diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml
index 2644e6ed3..f6edeac6c 100644
--- a/.github/workflows/docs.yaml
+++ b/.github/workflows/docs.yaml
@@ -28,19 +28,22 @@ jobs:
uses: mamba-org/setup-micromamba@v1
with:
environment-file: environment.yml
- create-args: python=3.10
+ create-args: python=3.12
init-shell: bash
cache-downloads: true
cache-environment: true
post-cleanup: all
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
+ with:
+ enable-cache: true
+ - name: Install plinder
+ shell: bash -el {0}
+ run: UV_PROJECT_ENVIRONMENT="$CONDA_PREFIX" uv sync --inexact --extra docs
- name: Build docs
shell: bash -el {0}
id: build
- run: |
- which python
- python -m pip install six
- python -m pip install '.[docs,loader]'
- sphinx-build docs build/docs
+ run: sphinx-build docs build/docs
- name: Upload build artifact
uses: actions/upload-pages-artifact@v3
with:
diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml
index 86aa1462e..9ef3df7b9 100644
--- a/.github/workflows/main.yaml
+++ b/.github/workflows/main.yaml
@@ -2,7 +2,6 @@ name: Package
permissions:
contents: write
id-token: write
- packages: write
on:
push:
branches:
@@ -14,51 +13,48 @@ jobs:
name: Package
if: ${{ ! contains(toJSON(github.event.commits.*.message), '[skip ci]') }}
runs-on: ubuntu-latest
+ defaults:
+ run:
+ shell: bash -l {0}
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- - name: Setup python
- uses: actions/setup-python@v5
+ - name: Setup micromamba
+ uses: mamba-org/setup-micromamba@v1
with:
- python-version: "3.10"
- - name: Configure docker
- run: echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
- - name: Install build and tag requirements
- run: python -m pip install build semver
+ environment-file: environment.yml
+ create-args: python=3.12
+ init-shell: bash
+ cache-downloads: true
+ cache-environment: true
+ post-cleanup: all
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
+ with:
+ enable-cache: true
+ - name: Install plinder
+ run: UV_PROJECT_ENVIRONMENT="$CONDA_PREFIX" uv sync --inexact
- name: Get version bump
id: get-tag
- run: echo "bump=$(python flows/docker.py bump)" >> $GITHUB_OUTPUT
- - name: Pull, build, tag, bump base image
- if: steps.get-tag.outputs.bump != ''
- run: python flows/docker.py pull --build --promote
- - name: Build image
+ run: echo "bump=$(python version.py)" >> $GITHUB_OUTPUT
+ - name: Run tests
if: steps.get-tag.outputs.bump != ''
- run: python flows/docker.py build
- - name: Run tests against new image and save images
+ env:
+ PLINDER_OFFLINE: "true"
+ run: python -m pytest -n auto -v
+ - name: Tag release
if: steps.get-tag.outputs.bump != ''
- run: |
- python flows/docker.py test --push
- if ! test -f reports/.coverage; then
- echo "Missing test coverage reports (reports/.coverage). Not all tests have passed?"
- exit 1
- else
- echo "Test coverage report found!"
- fi
+ run: git tag ${{ steps.get-tag.outputs.bump }}
- name: Build distribution
- run: python -m build
+ run: uv build
- name: Publish package distributions to PyPI
if: steps.get-tag.outputs.bump != ''
uses: pypa/gh-action-pypi-publish@release/v1
- name: Save git tag
if: steps.get-tag.outputs.bump != ''
run: git push origin ${{ steps.get-tag.outputs.bump }}
- - name: Copy and surgery coverage
- if: steps.get-tag.outputs.bump != ''
- run: |
- cp reports/.coverage .
- sqlite3 .coverage "update file set path='src/' || substr(path, 40);"
- name: Post coverage comment
if: steps.get-tag.outputs.bump != ''
uses: py-cov-action/python-coverage-comment-action@v3
diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml
index 9bb518752..7657eeb09 100644
--- a/.github/workflows/pr.yaml
+++ b/.github/workflows/pr.yaml
@@ -3,7 +3,6 @@ name: CI Workflow
permissions:
contents: write
id-token: write
- packages: read
pull-requests: write
concurrency:
@@ -23,67 +22,51 @@ jobs:
- name: Setup python
uses: actions/setup-python@v5
with:
- python-version: "3.10"
+ python-version: "3.12"
- name: Install tox
run: pip install tox
- name: Run quality checks
- run: tox -e py310-lint,py310-type
+ run: tox -e py312-lint,py312-type
- name: Directory Cache
uses: actions/cache@v4
with:
path: .tox
- key: tox-${{ runner.os }}-3.10-${{ hashFiles('tox.ini') }}
+ key: tox-${{ runner.os }}-3.12-${{ hashFiles('tox.ini') }}
restore-keys: |
- tox-${{ runner.os }}-3.10-
+ tox-${{ runner.os }}-3.12-
test:
- name: Build and test docker image
+ name: Test
runs-on: ubuntu-latest
+ defaults:
+ run:
+ shell: bash -l {0}
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- - name: Configure docker
- run: echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
- - name: Get changed source files
- id: changed-src
- uses: tj-actions/changed-files@v41
+ - name: Setup micromamba
+ uses: mamba-org/setup-micromamba@v1
with:
- files: src/**
- - name: Get changed base image files
- if: steps.changed-src.outputs.any_changed == 'true'
- id: changed-base
- uses: tj-actions/changed-files@v41
+ environment-file: environment.yml
+ create-args: python=3.12
+ init-shell: bash
+ cache-downloads: true
+ cache-environment: true
+ post-cleanup: all
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
with:
- files: dockerfiles/base/*
- - name: Pull base image and build
- if: steps.changed-src.outputs.any_changed == 'true' && steps.changed-base.outputs.any_changed == 'true'
- run: python flows/docker.py pull --build
- - name: Pull base image
- if: steps.changed-src.outputs.any_changed == 'true' && steps.changed-base.outputs.any_changed != 'true'
- run: python flows/docker.py pull
- - name: Build image
- if: steps.changed-base.outputs.any_changed == 'true' || steps.changed-src.outputs.any_changed == 'true'
- run: python flows/docker.py build
- - name: Run test image
- if: steps.changed-base.outputs.any_changed == 'true' || steps.changed-src.outputs.any_changed == 'true'
- run: |
- python flows/docker.py test
- if ! test -f reports/.coverage; then
- echo "Missing test coverage reports (reports/.coverage). Not all tests have passed?"
- exit 1
- else
- echo "Test coverage report found!"
- fi
- - name: Copy and surgery coverage
- if: steps.changed-base.outputs.any_changed == 'true' || steps.changed-src.outputs.any_changed == 'true'
- run: |
- cp reports/.coverage .
- sqlite3 .coverage "update file set path='src/' || substr(path, 40);"
+ enable-cache: true
+ - name: Install plinder
+ run: UV_PROJECT_ENVIRONMENT="$CONDA_PREFIX" uv sync --inexact
+ - name: Run tests
+ env:
+ PLINDER_OFFLINE: "true"
+ run: python -m pytest -n auto -v
- name: Post coverage comment
- if: steps.changed-src.outputs.any_changed == 'true'
uses: py-cov-action/python-coverage-comment-action@v3
with:
GITHUB_TOKEN: ${{ github.token }}
@@ -101,12 +84,19 @@ jobs:
uses: mamba-org/setup-micromamba@v1
with:
environment-file: environment.yml
- create-args: python=3.10
+ create-args: python=3.12
init-shell: bash
cache-downloads: true
cache-environment: true
post-cleanup: all
- - name: Install Python requirements
- run: pip install six ".[docs,loader]"
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
+ with:
+ enable-cache: true
+ - name: Install plinder
+ run: UV_PROJECT_ENVIRONMENT="$CONDA_PREFIX" uv sync --inexact --extra docs
- name: Build the documentation
run: sphinx-build --fail-on-warning docs build/docs
+ - name: Show notebook errors
+ if: failure()
+ run: cat build/docs/reports/examples/*.err.log 2>/dev/null || true
diff --git a/.gitignore b/.gitignore
index e3c6c66b7..0e6b93586 100644
--- a/.gitignore
+++ b/.gitignore
@@ -149,6 +149,7 @@ venv/
ENV/
env.bak/
venv.bak/
+.claude
# Spyder project settings
.spyderproject
@@ -173,7 +174,6 @@ dmypy.json
# Cython debug symbols
cython_debug/
-.metaflow/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
@@ -186,9 +186,14 @@ cython_debug/
*/*/DS_Store
src/plinder-data/plinder/data/artifacts
-#src/plinder-core
*.bak*
*.1.*
tests/xx
tests/test_data/plinder/mount/systems/*/
+tmp_foldseek
+tmp_mmseqs
artifacts
+logs/
+
+# uv lockfile: not committed; CI resolves the latest versions allowed by pyproject.toml
+uv.lock
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 3e035bc67..f95b9e6b8 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -4,7 +4,6 @@ exclude: |
(?x)^(
docs/.*png|
tests/test_data/.*|
- src/plinder/data/utils/annotations/static_files/dates.csv|
private/.*ipynb
)$
repos:
@@ -15,15 +14,12 @@ repos:
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
-- repo: local
+# pinned ruff, so the hook does not depend on whichever ruff is first on PATH
+- repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.9.4
hooks:
- - id: ruff-format
- name: ruff-format
- entry: bash -c 'ruff format --force-exclude --preview src tests'
- language: system
- types: [python]
- - id: ruff-linter
- name: ruff-linter
- entry: bash -c 'ruff check --fix src tests'
- language: system
- types: [python]
+ - id: ruff-format
+ files: ^(src|tests)/
+ - id: ruff
+ args: [--fix]
+ files: ^(src|tests)/
diff --git a/.python-version b/.python-version
new file mode 100644
index 000000000..e4fba2183
--- /dev/null
+++ b/.python-version
@@ -0,0 +1 @@
+3.12
diff --git a/LICENSE.txt b/LICENSE.txt
index 64c76f9dd..10cf0a2ea 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,280 +1,191 @@
-GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-โ
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-โ
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-โ
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-โ
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to the Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by the Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding any notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ Copyright 2024, Plinder Development Team
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/NOTICE b/NOTICE
index b73515ca8..720782ee4 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,4 +1,4 @@
-PLINDER - The Protein Ligand INteractions Dataset and Evaluation Resource
+PLINDER - Protein & Ligand INteraction Dataset and Evaluation Resource
Copyright (c) 2024, Plinder Development Team
The PLINDER project is a collaboration between the
diff --git a/README.md b/README.md
index 21f576688..b3f0534e5 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,13 @@

-
The Protein Ligand INteractions Dataset and Evaluation Resource
+
Protein & Ligand INteraction Dataset and Evaluation Resource
---
[](https://github.com/plinder-org/plinder/blob/master/LICENSE.txt)
-[](https://github.com/plinder-org/plinder/pkgs/container/plinder)
+[](https://pypi.org/project/plinder/)
[](https://www.plinder.sh/)
[](https://www.biorxiv.org/content/10.1101/2024.07.17.603955)
[](https://plinder-org.github.io/plinder/)
@@ -17,17 +17,16 @@
# ๐ About
-**PLINDER**, short for **p**rotein **l**igand **in**teractions **d**ataset and
-**e**valuation **r**esource, is a comprehensive, annotated, high quality dataset and
-resource for training and evaluation of protein-ligand docking algorithms:
+**PLINDER** is the **Protein & Ligand INteraction Dataset and Evaluation
+Resource**: a comprehensive, annotated, high-quality resource for training and
+evaluating protein-ligand and protein-protein structure models.
- \> 400k PLI systems across > 11k SCOP domains and > 50k unique small molecules
-- 750+ annotations for each system, including protein and ligand properties, quality,
- matched molecular series and more
+- Ligand-level annotations plus compact entry, chain, interface, and representative tables
- Automated curation pipeline to keep up with the PDB
-- 14 PLI metrics and over 20 billion similarity scores
-- Unbound \(_apo_\) and _predicted_ Alphafold2 structures linked to _holo_ systems
-- _train-val-test_ splits and ability to tune splitting based on the learning task
+- Reusable ligand, pocket, and protein-interface similarities and cluster assignments
+- Deposited apo protein chains linked to compatible _holo_ systems
+- Directed-cover assignments for choosing diverse training representatives
- Robust evaluation harness to simplify and standard performance comparison between
models.
@@ -35,9 +34,7 @@ The *PLINDER* project is a community effort, launched by the University of Basel
SIB Swiss Institute of Bioinformatics, Proxima (formerly VantAI), NVIDIA, MIT CSAIL,
and will be regularly updated.
-To accelerate community adoption, PLINDER will be used as the fieldโs new Protein-Ligand
-interaction dataset standard as part of an exciting competition at the upcoming 2024
-[Machine Learning in Structural Biology (MLSB)](https://mlsb.io#challenge) Workshop at NeurIPS, one of the field's premiere academic gatherings.
+PLINDER set a new standard for the Protein-Ligand interaction datasets. It was first introduced as part of the 2024 Machine Learning in Structural Biology (MLSB) [Workshop challenge](https://www.mlsb.io/index_2024.html#challenge) at NeurIPS, one of the field's premiere academic gatherings.
More details about the competition and other helpful practical tips can be found at our recent workshop repo:
[Moving Beyond Memorization](https://github.com/plinder-org/moving_beyond_memorisation).
@@ -46,10 +43,9 @@ More details about the competition and other helpful practical tips can be found
## ๐ข Plinder versions
-We version the `plinder` dataset with two controls:
-
-- `PLINDER_RELEASE`: the month stamp of the last RCSB sync
-- `PLINDER_ITERATION`: value that enables iterative development within a release
+We version the `plinder` dataset by the month stamp (`YYYY-MM`) of the RCSB
+sync it was built from, set with `PLINDER_RELEASE`. The current release,
+`2026-09`, is the default.
We version the `plinder` application using an automated semantic
versioning scheme based on the `git` commit history.
@@ -57,24 +53,27 @@ The `plinder.data` package is responsible for generating a dataset
release and the `plinder.core` package makes it easy to interact
with the dataset.
-#### ๐๐๐ Known bugs:
-- Source dataset contains incorrect `entry_release_date` dates, please, use `query_index` to get correct dates patched.
-- Complexes containing nucleic acid receptors may [not be saved corectly](https://github.com/plinder-org/plinder/issues/61).
-- `ligand_binding_affinity` queries have been disabled due to a [bug found parsing BindingDB](https://github.com/plinder-org/plinder/issues/94)
-
#### Changelog:
-Unreleased:
-- Public downloads for `2024-06/v2` now use `https://plinderdata.org` (Cloudflare R2).
- The consumer no longer supports GCS or downloading older releases.
-- Downloads stream to disk and verify size and MD5 before atomic replacement.
- Interrupted transfers retry from the start. Cached files with the expected size
- are reused; offline access retains the existing cache layout. Use a forced
- refresh to repair same-size local corruption.
-- Google storage dependencies are now optional: install `plinder[data]` for the
- GCS data-generation utilities.
-
-- 2024-06/v2 (Current):
+- WIP (Current โ unreleased):
+ - **Public downloads from Cameo**: releases download directly from `https://cameo3d.org/plinder/PLINDER-/` (currently `2026-09`); `PLINDER_MIRROR_URL` selects another HTTP file server with the same directory layout. Downloads stream to disk, validate HTTP Content-Length, and replace cached files atomically. Interrupted transfers retry from the start. Cached files are reused when their size and Last-Modified time match the server, so data hotfixes are fetched on the next access. Google storage dependencies are optional: install `plinder[data]` for the GCS data-generation utilities.
+ - **Major backend refactor**: replaced OST, gemmi, plip, openbabel with biotite + peppr for data generation; removed 6 dependencies from ingest pipeline
+ - **Nucleic acid support**: DNA/RNA chains now correctly included as receptor neighbors, mainchain/sidechain detection works for both protein and nucleic acids ([#61](https://github.com/plinder-org/plinder/issues/61))
+ - **Custom CIF support**: new `Entry.from_custom_cif_file` for structure-prediction outputs (Boltz, AlphaFold3, Chai-1) that ship CIFs without `_chem_comp_bond` ([#117](https://github.com/plinder-org/plinder/issues/117)). Bond orders come from `ligand_smiles_dict` via positional atom-order match (the convention these tools follow); element/count mismatches raise with the offending position, `force_substructure_match=True` opts into substructure matching when atom order isn't preserved. User SMILES win over CCD for both `smiles` and `resolved_stereo_matches_template` โ closes a silent gap where biotite's `LIG` placeholder would pass any 3D conformer. Input CIFs are never mutated; optional `save_fixed_cif` persists the enriched copy.
+ - **Stricter CIF ingest**: H/D filtered consistently (biotite's `filter_heavy`); multi-model CIFs warn and use model 1; multi-instance custom comp_ids must share heavy-atom naming (since `_chem_comp_bond` is comp_id-keyed); silent `connect_via_residue_names` and half-sanitized substructure fallbacks replaced with `ValueError` so corrupt inputs fail loudly.
+ - **Stereochemistry**: CCD ideal 3D coordinates used as stereo ground truth; new `resolved_stereo_matches_template` flag validates resolved structure chirality against CCD template (handles partial resolution via MCS trimming)
+ - **Interactions**: water bridge and metal bridge detection via peppr; halogen bond sidechain flag now computed (was hardcoded)
+ - **Binding affinity**: fixed BindingDB matching โ target sequence now validated against PDB SEQRES with 100% core identity, terminal tags/truncations tolerated ([#94](https://github.com/plinder-org/plinder/issues/94)); updated code to get the latest BindingDB release
+ - **Optional eval**: `pip install plinder[eval]` adds PoseBusters ligand validation; OpenStructure-backed metrics use the Conda-only `openstructure` package; PoseBusters no longer runs during ingest
+ - **PlinderSystem API**: new `receptor_structure` and `ligand_structures` (Biotite AtomArray) plus `ligand_mols` (RDKit Mol) properties; OpenStructure is confined to the evaluation implementation
+ - **Chain type support**: `Chain.from_cif_data` now assigns proper one-letter codes and chem_types for nucleotides (`RNA Linking`, `DNA Linking`); new `Residue.is_modified` property covers both protein PTMs and modified nucleotide bases
+ - **Save utils**: receptor/ligand chain naming generalized (`PDB_RECEPTOR_CHAINS`); system saving works for protein, NA, and mixed complexes
+ - **System definition**: unified `min_polymer_size=12` replaces separate `min_polymer_size`/`max_non_small_mol_ligand_length` โ polymers โฅ 12 residues are receptor, shorter are ligands (threshold matches minimum MMseqs2/Foldseek search length); molecules with BIRD annotation are ligands irrespective of size; ligand chains no longer appear in both receptor and ligand parts of system IDs.
+ - **System grouping**: pocket-based grouping (โฅ 3 shared receptor residues on the same chain instance) for adjacent binding sites (e.g. orthosteric + allosteric, cofactor + substrate in same active site); artifacts attach only via 4 ร proximity
+ - **Dead code removal**: removed unused OST-based functions, PDB string roundtrips, duplicate SMILES derivation paths, v1 template matching (consolidated to Rascal MCES `get_matched_template`)
+ - **License**: changed from GPL-2.0 to Apache-2.0 (GPL was only required by PLIP, now removed)
+
+- 2024-06/v2:
- New systems added based on the 2024-06 RCSB sync
- Updated system definition to be more stable and depend only on ligand distance rather than PLIP
- Added annotations for crystal contacts
@@ -87,9 +86,9 @@ Unreleased:
- 2024-04/v1: Version described in the preprint, with updated redundancy removal by protein pocket and ligand similarity.
- 2024-04/v0: Version used to re-train DiffDock in the paper, with redundancy removal based on \\_\
-## ๐ Gold standard benchmark sets
+## ๐ Preprint benchmark sets
-As part of *PLINDER* resource we provide train, validation and test splits that are
+The historical `2024-04/v1` preprint release provides train, validation, and test splits that are
curated to minimize the information leakage based on protein-ligand interaction
similarity.
In addition, we have prioritized the systems that has a linked experimental `apo`
@@ -108,21 +107,26 @@ Moreover, as we enticipate this resource to be used for benchmarking a wide rang
The *PLINDER* dataset is provided in two ways:
- You can either use the files from the dataset directly using your preferred tooling
- by downloading the data from the public
- [bucket](https://cloud.google.com/storage/docs/buckets),
+ by downloading the data from the [Cameo file server](https://cameo3d.org/plinder/PLINDER-2026-09/),
- or you can utilize the dedicated `plinder` Python package for interfacing the data.
## Downloading the dataset
-Install the Python package below, then run `plinder_download` to download the
-published `2024-06/v2` release from Cloudflare R2. Dataset APIs also download
-required files lazily. No Google Cloud credentials or SDK are needed.
+After installing the package, download the index tables and cluster assignments
+for a release with:
-The default endpoint is `https://plinderdata.org`; `PLINDER_MIRROR_URL` can select
-another HTTP mirror. This release no longer falls back to GCS. Other release
-versions are unavailable through the public downloader. Existing cache paths and
-`PLINDER_OFFLINE` behavior are preserved.
+```console
+$ plinder_download --release 2026-09
+```
+
+The command offers the larger ligand, alignment, score, export, and search
+database groups separately, and dataset APIs also download required files
+lazily. No Google Cloud credentials or SDK are needed: releases download
+from `https://cameo3d.org/plinder/PLINDER-2026-09/`; `PLINDER_MIRROR_URL`
+can select another HTTP file-server root containing `PLINDER-/`
+directories. The legacy `2024-06/v2` layout requires an earlier `plinder` version.
+For details on the release paths, see [Documentation](https://plinder-org.github.io/plinder/tutorial/dataset.html).
## Installing the Python package
@@ -132,6 +136,18 @@ versions are unavailable through the public downloader. Existing cache paths and
pip install plinder
```
+For PoseBusters ligand validation:
+
+```
+pip install plinder[eval]
+```
+
+OpenStructure is not published on PyPI. Evaluation metrics backed by
+OpenStructure (including lDDT and RMSD) use its command-line actions and require
+OpenStructure 2.12.0 or newer; the repository's `environment.yml` installs it
+from Bioconda. See the [evaluation guide](docs/evaluation.md) for evaluating
+folders of ligand or protein-interface predictions.
+
## License
Data curated by PLINDER are made available under the Apache License 2.0.
All data curated by BindingDB staff are provided under the Creative Commons Attribution 4.0 License. Data imported from ChEMBL are provided under their Creative Commons Attribution-Share Alike 4.0 Unported License.
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index ccf44038d..000000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-services:
-
- base:
- image: ${IMAGE_REPO:-ghcr.io/plinder-org}/plinder-base:${BASE_TAG:-latest}
- build:
- context: ./dockerfiles/base
-
- plinder:
- image: ${IMAGE_REPO:-ghcr.io/plinder-org}/plinder:${BUILD_TAG:-latest}
- build:
- context: .
- dockerfile: ./dockerfiles/main/Dockerfile
- args:
- BASE_IMAGE: ${IMAGE_REPO:-ghcr.io/plinder-org}/plinder-base
- BASE_TAG: ${BASE_TAG:-latest}
- depends_on:
- - base
-
- test:
- image: ${IMAGE_REPO:-ghcr.io/plinder-org}/plinder:${BUILD_TAG:-latest}
- depends_on:
- - plinder
- volumes:
- - ./tests/:/app/tests/
- - ./pytest.ini:/app/pytest.ini
- - ./.coveragerc:/app/.coveragerc
- - ./reports/:/app/reports/
- - ./examples/:/app/examples/
- command: /bin/bash -c "python -m pytest -n auto -v && cp .coverage reports/.coverage"
diff --git a/dockerfiles/base/Dockerfile b/dockerfiles/base/Dockerfile
deleted file mode 100644
index 1b43378bf..000000000
--- a/dockerfiles/base/Dockerfile
+++ /dev/null
@@ -1,70 +0,0 @@
-FROM --platform=linux/amd64 mambaorg/micromamba:git-c160e88-jammy
-
-USER root
-ENV DEBIAN_FRONTEND=noninteractive
-
-# Install OS dependencies
-RUN apt-get --allow-releaseinfo-change update \
- && apt-get -y install --no-install-recommends \
- apt-utils \
- dialog 2>&1 \
- && apt-get install -y --no-install-recommends \
- git \
- gpg \
- wget \
- man-db \
- procps \
- tree \
- unzip \
- gcc \
- build-essential \
- lsb-release \
- curl \
- vim \
- exuberant-ctags \
- apt-transport-https \
- ca-certificates \
- gnupg \
- sudo \
- libgl1-mesa-glx \
- libxrender1 \
- rsync \
- libtiff-dev \
- && apt-get autoclean \
- && apt-get autoremove \
- && rm -rf /var/lib/apt/lists/*
-
-# Install rust toolchain
-RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
-ENV PATH=/root/.cargo/bin:${PATH}
-
-# Install conda env
-COPY env.yml /tmp/env.yml
-RUN micromamba install -y -f /tmp/env.yml && \
- micromamba clean --all --yes && \
- rm /tmp/env.yml
-
-# Install gsutil without full gcloud sdk
-RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | \
- tee -a /etc/apt/sources.list.d/google-cloud-sdk.list \
- && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | \
- apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - \
- && apt-get update -y \
- && apt-get install google-cloud-cli -y \
- && apt-get autoclean \
- && apt-get autoremove \
- && rm -rf /var/lib/apt/lists/*
-
-ENV BASH_ENV=/usr/local/bin/_activate_current_env.sh
-ENV LD_LIBRARY_PATH=/opt/conda/lib
-
-COPY requirements.txt /tmp/requirements.txt
-RUN --mount=type=secret,id=INDEX_URL \
- PIP_KEYRING_PROVIDER=subprocess python -m pip install \
- --extra-index-url "$(cat /run/secrets/INDEX_URL)" \
- --no-cache-dir -r /tmp/requirements.txt && \
- rm /tmp/requirements.txt
-
-ENTRYPOINT ["/usr/local/bin/_entrypoint.sh"]
-
-CMD ["/bin/bash"]
diff --git a/dockerfiles/base/env.yml b/dockerfiles/base/env.yml
deleted file mode 100644
index ea6a05e83..000000000
--- a/dockerfiles/base/env.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-name: base
-channels:
- - conda-forge
- - defaults
- - bioconda
-dependencies:
- - python=3.12.*
- - pyopenssl=23.2.0
- - requests=2.25.1
- - google-cloud-storage
- - gcsfs
- - reduce
- - openstructure
- - mmseqs2
- - foldseek
- - plip=2.3.0
- - pip:
- - keyrings.google-artifactregistry-auth==1.1.2
diff --git a/dockerfiles/base/requirements.txt b/dockerfiles/base/requirements.txt
deleted file mode 100644
index 5d3759305..000000000
--- a/dockerfiles/base/requirements.txt
+++ /dev/null
@@ -1,185 +0,0 @@
-#
-# This file is autogenerated by pip-compile with Python 3.9
-# by the following command:
-#
-# pip-compile --annotation-style=line --extra=test,pipeline,plots --output-file=/output/requirements.txt --strip-extras pyproject.toml
-#
-aiohappyeyeballs==2.4.0 # via aiohttp
-aiohttp==3.10.5 # via gcsfs
-aiosignal==1.3.1 # via aiohttp
-annotated-types==0.7.0 # via pydantic
-antlr4-python3-runtime==4.9.3 # via omegaconf
-anyio==4.4.0 # via httpx, jupyter-server
-argon2-cffi==23.1.0 # via jupyter-server
-argon2-cffi-bindings==21.2.0 # via argon2-cffi
-arrow==1.3.0 # via isoduration
-asttokens==2.4.1 # via stack-data
-async-lru==2.0.4 # via jupyterlab
-async-timeout==4.0.3 # via aiohttp
-attrs==24.2.0 # via aiohttp, jsonschema, pytest, referencing
-babel==2.16.0 # via jupyterlab-server
-beautifulsoup4==4.12.3 # via nbconvert
-biotite==1.0.1 # via plinder (pyproject.toml)
-bleach==6.1.0 # via nbconvert
-build==0.9.0 # via plinder (pyproject.toml)
-cachetools==5.5.0 # via google-auth, tox
-certifi==2024.8.30 # via httpcore, httpx, requests
-cffi==1.17.0 # via argon2-cffi-bindings
-chardet==5.2.0 # via tox
-charset-normalizer==3.3.2 # via requests
-cloudpathlib==0.19.0 # via plinder (pyproject.toml)
-colorama==0.4.6 # via tox
-comm==0.2.2 # via ipykernel, ipywidgets
-contourpy==1.3.0 # via matplotlib
-coverage==7.6.1 # via pytest-cov
-cycler==0.12.1 # via matplotlib
-debugpy==1.8.5 # via ipykernel
-decorator==5.1.1 # via gcsfs, ipython
-defusedxml==0.7.1 # via nbconvert
-distlib==0.3.8 # via virtualenv
-duckdb==1.0.0 # via plinder (pyproject.toml)
-eval-type-backport==0.2.0 # via plinder (pyproject.toml)
-exceptiongroup==1.2.2 # via anyio, ipython, pytest
-execnet==2.1.1 # via pytest-xdist
-executing==2.1.0 # via stack-data
-fastjsonschema==2.20.0 # via nbformat
-filelock==3.15.4 # via tox, virtualenv
-fonttools==4.53.1 # via matplotlib
-fqdn==1.5.1 # via jsonschema
-frozenlist==1.4.1 # via aiohttp, aiosignal
-fsspec==2024.6.1 # via gcsfs
-future==1.0.0 # via mmcif
-gcsfs==2024.6.1 # via plinder (pyproject.toml)
-gemmi==0.6.6 # via plinder (pyproject.toml)
-google-api-core==2.19.2 # via google-cloud-core, google-cloud-storage
-google-auth==2.34.0 # via gcsfs, google-api-core, google-auth-oauthlib, google-cloud-core, google-cloud-storage
-google-auth-oauthlib==1.2.1 # via gcsfs
-google-cloud-core==2.4.1 # via google-cloud-storage
-google-cloud-storage==2.18.2 # via gcsfs, plinder (pyproject.toml)
-google-crc32c==1.6.0 # via google-cloud-storage, google-resumable-media
-google-resumable-media==2.7.2 # via google-cloud-storage
-googleapis-common-protos==1.65.0 # via google-api-core
-h11==0.14.0 # via httpcore
-httpcore==1.0.5 # via httpx
-httpx==0.27.2 # via jupyterlab
-idna==3.8 # via anyio, httpx, jsonschema, requests, yarl
-importlib-metadata==8.4.0 # via jupyter-client, jupyter-lsp, jupyterlab, jupyterlab-server, nbconvert
-importlib-resources==6.4.4 # via matplotlib
-iniconfig==2.0.0 # via pytest
-ipykernel==6.29.5 # via jupyterlab
-ipython==8.18.1 # via ipykernel, ipywidgets
-ipython-genutils==0.2.0 # via ipywidgets
-ipywidgets==7.8.4 # via mols2grid
-isoduration==20.11.0 # via jsonschema
-jedi==0.19.1 # via ipython
-jinja2==3.1.4 # via jupyter-server, jupyterlab, jupyterlab-server, mols2grid, nbconvert
-json5==0.9.25 # via jupyterlab-server
-jsonpointer==3.0.0 # via jsonschema
-jsonschema==4.23.0 # via jupyter-events, jupyterlab-server, nbformat
-jsonschema-specifications==2023.12.1 # via jsonschema
-jupyter-client==8.6.2 # via ipykernel, jupyter-server, nbclient
-jupyter-core==5.7.2 # via ipykernel, jupyter-client, jupyter-server, jupyterlab, nbclient, nbconvert, nbformat
-jupyter-events==0.10.0 # via jupyter-server
-jupyter-lsp==2.2.5 # via jupyterlab
-jupyter-server==2.14.2 # via jupyter-lsp, jupyterlab, jupyterlab-server, notebook, notebook-shim
-jupyter-server-terminals==0.5.3 # via jupyter-server
-jupyterlab==4.2.5 # via notebook
-jupyterlab-pygments==0.3.0 # via nbconvert
-jupyterlab-server==2.27.3 # via jupyterlab, notebook
-jupyterlab-widgets==1.1.10 # via ipywidgets
-kiwisolver==1.4.5 # via matplotlib
-markupsafe==2.1.5 # via jinja2, nbconvert
-matplotlib==3.9.2 # via matplotlib-venn, plinder (pyproject.toml), seaborn
-matplotlib-inline==0.1.7 # via ipykernel, ipython
-matplotlib-venn==1.1.1 # via plinder (pyproject.toml)
-mistune==3.0.2 # via nbconvert
-mmcif==0.89.0 # via plinder (pyproject.toml)
-mols2grid==2.0.0 # via plinder (pyproject.toml)
-msgpack==1.0.8 # via biotite, mmcif
-multidict==6.0.5 # via aiohttp, yarl
-nbclient==0.10.0 # via nbconvert
-nbconvert==7.16.4 # via jupyter-server
-nbformat==5.10.4 # via jupyter-server, nbclient, nbconvert, plinder (pyproject.toml)
-nest-asyncio==1.6.0 # via ipykernel
-networkx==3.2.1 # via biotite
-notebook==7.2.2 # via widgetsnbextension
-notebook-shim==0.2.4 # via jupyterlab, notebook
-numpy==1.26.4 # via biotite, contourpy, matplotlib, matplotlib-venn, mols2grid, pandas, plinder (pyproject.toml), posebusters, pyarrow, rdkit, scipy, seaborn
-oauthlib==3.2.2 # via requests-oauthlib
-omegaconf==2.3.0 # via plinder (pyproject.toml)
-overrides==7.7.0 # via jupyter-server
-packaging==24.1 # via build, ipykernel, jupyter-server, jupyterlab, jupyterlab-server, matplotlib, nbconvert, plotly, pyproject-api, pytest, setuptools-scm, tox
-pandas==2.2.2 # via mols2grid, plinder (pyproject.toml), posebusters, seaborn
-pandocfilters==1.5.1 # via nbconvert
-parso==0.8.4 # via jedi
-pep517==0.13.1 # via build
-pexpect==4.9.0 # via ipython
-pillow==10.4.0 # via matplotlib, rdkit
-platformdirs==4.2.2 # via jupyter-core, tox, virtualenv
-plotly==5.24.0 # via plinder (pyproject.toml)
-pluggy==1.5.0 # via pytest, tox
-posebusters==0.3.1 # via plinder (pyproject.toml)
-prometheus-client==0.20.0 # via jupyter-server
-prompt-toolkit==3.0.47 # via ipython
-proto-plus==1.24.0 # via google-api-core
-protobuf==5.28.0 # via google-api-core, googleapis-common-protos, proto-plus
-psutil==6.0.0 # via ipykernel
-ptyprocess==0.7.0 # via pexpect, terminado
-pure-eval==0.2.3 # via stack-data
-pyarrow==17.0.0 # via plinder (pyproject.toml)
-pyasn1==0.6.0 # via pyasn1-modules, rsa
-pyasn1-modules==0.4.0 # via google-auth
-pycparser==2.22 # via cffi
-pydantic==2.8.2 # via plinder (pyproject.toml)
-pydantic-core==2.20.1 # via pydantic
-pygments==2.18.0 # via ipython, nbconvert
-pyparsing==3.1.4 # via matplotlib
-pyproject-api==1.7.1 # via tox
-pytest==7.2.0 # via plinder (pyproject.toml), pytest-cov, pytest-xdist
-pytest-cov==4.0.0 # via plinder (pyproject.toml)
-pytest-xdist==3.6.1 # via plinder (pyproject.toml)
-python-dateutil==2.9.0.post0 # via arrow, jupyter-client, matplotlib, pandas
-python-json-logger==2.0.7 # via jupyter-events
-pytz==2024.1 # via pandas
-pyyaml==6.0.2 # via jupyter-events, omegaconf, posebusters
-pyzmq==26.2.0 # via ipykernel, jupyter-client, jupyter-server
-rdkit>=2023.9.5 # via plinder (pyproject.toml), posebusters
-referencing==0.35.1 # via jsonschema, jsonschema-specifications, jupyter-events
-requests==2.32.3 # via biotite, gcsfs, google-api-core, google-cloud-storage, jupyterlab-server, mmcif, requests-oauthlib
-requests-oauthlib==2.0.0 # via google-auth-oauthlib
-rfc3339-validator==0.1.4 # via jsonschema, jupyter-events
-rfc3986-validator==0.1.1 # via jsonschema, jupyter-events
-rpds-py==0.20.0 # via jsonschema, referencing
-rsa==4.9 # via google-auth
-scipy==1.13.1 # via matplotlib-venn, plinder (pyproject.toml)
-seaborn==0.13.2 # via plinder (pyproject.toml)
-send2trash==1.8.3 # via jupyter-server
-setuptools-scm==7.0.5 # via plinder (pyproject.toml)
-six==1.16.0 # via asttokens, bleach, mmcif, plinder (pyproject.toml), python-dateutil, rfc3339-validator
-sniffio==1.3.1 # via anyio, httpx
-soupsieve==2.6 # via beautifulsoup4
-stack-data==0.6.3 # via ipython
-tenacity==9.0.0 # via plotly
-terminado==0.18.1 # via jupyter-server, jupyter-server-terminals
-tinycss2==1.3.0 # via nbconvert
-tomli==2.0.1 # via build, coverage, jupyterlab, pep517, pyproject-api, pytest, setuptools-scm, tox
-tornado==6.4.1 # via ipykernel, jupyter-client, jupyter-server, jupyterlab, notebook, terminado
-tox==4.18.0 # via plinder (pyproject.toml)
-tqdm==4.66.5 # via plinder (pyproject.toml)
-traitlets==5.14.3 # via comm, ipykernel, ipython, ipywidgets, jupyter-client, jupyter-core, jupyter-events, jupyter-server, jupyterlab, matplotlib-inline, nbclient, nbconvert, nbformat
-types-python-dateutil==2.9.0.20240821 # via arrow
-typing-extensions==4.12.2 # via anyio, async-lru, cloudpathlib, ipython, plinder (pyproject.toml), pydantic, pydantic-core, setuptools-scm
-tzdata==2024.1 # via pandas
-uri-template==1.3.0 # via jsonschema
-urllib3==2.2.2 # via requests
-virtualenv==20.26.3 # via tox
-wcwidth==0.2.13 # via prompt-toolkit
-webcolors==24.8.0 # via jsonschema
-webencodings==0.5.1 # via bleach, tinycss2
-websocket-client==1.8.0 # via jupyter-server
-widgetsnbextension==3.6.9 # via ipywidgets
-yarl==1.9.7 # via aiohttp
-zipp==3.20.1 # via importlib-metadata, importlib-resources
-
-# The following packages are considered to be unsafe in a requirements file:
-# setuptools
diff --git a/dockerfiles/main/Dockerfile b/dockerfiles/main/Dockerfile
deleted file mode 100644
index 0e1148050..000000000
--- a/dockerfiles/main/Dockerfile
+++ /dev/null
@@ -1,16 +0,0 @@
-ARG BASE_IMAGE
-ARG BASE_TAG
-FROM --platform=linux/amd64 ${BASE_IMAGE}:${BASE_TAG}
-ARG MAMBA_DOCKERFILE_ACTIVATE=1
-ARG DEPENDENCY_BLOCKS=test
-
-WORKDIR /app
-COPY requirements_data.txt requirements_data.txt
-RUN python -m pip install -r requirements_data.txt
-COPY src src
-COPY pyproject.toml pyproject.toml
-RUN --mount=source=.git,target=.git,type=bind \
- --mount=type=secret,id=INDEX_URL \
- PIP_KEYRING_PROVIDER=subprocess python -m pip install \
- --extra-index-url "$(cat /run/secrets/INDEX_URL)" \
- --no-cache-dir '.['"${DEPENDENCY_BLOCKS}"']'
diff --git a/dockerfiles/test/Dockerfile b/dockerfiles/test/Dockerfile
deleted file mode 100644
index 454518404..000000000
--- a/dockerfiles/test/Dockerfile
+++ /dev/null
@@ -1,8 +0,0 @@
-ARG BASE_IMAGE
-ARG BASE_TAG
-FROM --platform=linux/amd64 ${BASE_IMAGE}:${BASE_TAG}
-ARG MAMBA_DOCKERFILE_ACTIVATE=1
-COPY src src
-COPY pyproject.toml pyproject.toml
-RUN --mount=source=.git,target=.git,type=bind \
- python -m pip install --no-cache-dir .
diff --git a/docs/api/index.md b/docs/api/index.md
index c0c636dc5..ebef36d4b 100644
--- a/docs/api/index.md
+++ b/docs/api/index.md
@@ -4,15 +4,8 @@ sd_hide_title: true
# Python API
-## API reference
-
-The ``plinder.core`` package provides utilities for interacting with the PLINDER dataset.
-
-It contains an additional ``plinder.core.scores`` sub-package for querying parquet collections.
-
:::{toctree}
:maxdepth: 1
-:hidden:
:glob:
./*/index
diff --git a/docs/apidoc.py b/docs/apidoc.py
index 55e68416c..08dcf469e 100644
--- a/docs/apidoc.py
+++ b/docs/apidoc.py
@@ -1,244 +1,135 @@
-# The code in this file is based on the file with the same name in the Biotite project
-# licensed under BSD-3-clause license.
+# The code in this file is based on the file with the same name in the Biotite
+# project, licensed under the BSD-3-Clause license.
-import enum
+from __future__ import annotations
+
+import ast
import shutil
-import types
from importlib import import_module
from pathlib import Path
from textwrap import dedent
-from types import ModuleType
-from typing import Any
-
-from sphinx.application import Sphinx
-
-_INDENT = " " * 4
-def generate_api_reference(package_name: str, output_dir: Path) -> None:
- """
- Create the API reference for the given package and store it in the output directory.
-
- This creates `.rst` files containing `autodoc` directives.
+def generate_api_reference(
+ package_name: str,
+ output_dir: Path,
+ *,
+ excluded_modules: set[str] | None = None,
+) -> None:
+ """Create module reference pages for an installed PLINDER package.
Parameters
----------
package_name : str
- The name of the package to document.
+ Import name of the package to document.
output_dir : Path
- The directory to store the generated files in.
-
- Notes
- -----
- Use `.rst` files are `apidoc`and `numpydoc` produce reStructuredText formatted text.
+ Directory in which the generated ``.rst`` files are written.
+ excluded_modules : set of str, optional
+ Module names, or package prefixes, that require optional dependencies.
"""
- package = import_module(package_name)
- class_names = []
- function_names = []
- for attr_name in package.__all__:
- if _is_public_class(package, attr_name):
- class_names.append(attr_name)
- elif _is_public_function(package, attr_name):
- function_names.append(attr_name)
-
- # Remove existing rst files
+ modules = _discover_modules(package_name, excluded_modules or set())
+
if output_dir.exists():
shutil.rmtree(output_dir)
- # Create rst files
- output_dir.mkdir(parents=True, exist_ok=True)
- _create_package_page(
- output_dir / "index.rst", package_name, class_names, function_names
- )
- for class_name in class_names:
- _create_class_page(
- output_dir / f"{package_name}.{class_name}.rst", package_name, class_name
- )
- for function_name in function_names:
- _create_function_page(
- output_dir / f"{package_name}.{function_name}.rst",
- package_name,
- function_name,
- )
+ output_dir.mkdir(parents=True)
+ _write_package_index(output_dir / "index.rst", package_name, modules)
+ for module_name, source_path in modules:
+ _write_module_page(output_dir / f"{module_name}.rst", module_name, source_path)
-def _create_package_page(
- output_path: Path,
- package_name: str,
- classes: list[str],
- functions: list[str],
-):
- """
- Create the `.rst` file for the package overview.
- Parameters
- ----------
- output_path : Path
- The path to the output file.
- package_name : str
- The name of the package as it would be imported.
- classes, functions : list of str
- The names of the classes and functions to be documented, that are attributes of
- the package, respectively.
- """
- attributes = classes + functions
- # Enumerate classes and functions
- summary_string = dedent(
- """
+def clear_api_reference(output_dir: Path) -> None:
+ """Remove generated API directories while retaining hand-written pages."""
+ if not output_dir.exists():
+ return
+ for path in output_dir.iterdir():
+ if path.is_dir():
+ shutil.rmtree(path)
- .. autosummary::
- :nosignatures:
- :toctree:
- """
+def _discover_modules(
+ package_name: str,
+ excluded_modules: set[str],
+) -> list[tuple[str, Path]]:
+ """Return source modules below *package_name* in import-name order."""
+ package = import_module(package_name)
+ package_root = Path(package.__file__).parent
+ modules: list[tuple[str, Path]] = []
+
+ for source_path in package_root.rglob("*.py"):
+ relative_path = source_path.relative_to(package_root)
+ if source_path.name == "__init__.py":
+ continue
+ suffix = relative_path.with_suffix("").parts
+ if any(part.startswith("_") for part in suffix):
+ continue
+ module_name = ".".join((package_name, *suffix))
+ if not _is_excluded(module_name, excluded_modules):
+ modules.append((module_name, source_path))
+
+ return sorted(set(modules))
+
+
+def _is_excluded(module_name: str, excluded_modules: set[str]) -> bool:
+ return any(
+ module_name == excluded or module_name.startswith(f"{excluded}.")
+ for excluded in excluded_modules
)
- summary_string += "\n".join([_INDENT + attr for attr in attributes])
- # Assemble page
- file_content = (
- dedent(
- f"""
- ``{package_name}``
- {"=" * (len(package_name) + 4)}
- .. currentmodule:: {package_name}
-
- .. automodule:: {package_name}
-
- .. currentmodule:: {package_name}
-
- """
+def _write_package_index(
+ output_path: Path,
+ package_name: str,
+ modules: list[tuple[str, Path]],
+) -> None:
+ title = f"``{package_name}``\n" f'{"=" * (len(package_name) + 4)}\n'
+ if modules:
+ entries = "\n".join(f" {module_name}" for module_name, _ in modules)
+ output_path.write_text(
+ title + "\n.. toctree::\n" + " :maxdepth: 1\n\n" + f"{entries}\n"
)
- + summary_string
- )
- with open(output_path, "w") as f:
- f.write(file_content)
+ else:
+ output_path.write_text(title)
-def _create_class_page(output_path, package_name, class_name):
- """
- Create the `.rst` file for the given class.
-
- Parameters
- ----------
- output_path : Path
- The path to the output file.
- package_name : str
- The name of the package as it would be imported.
- class_name : str
- The name of the class to document, that is part of the package.
- """
- file_content = dedent(
- f"""
- :sd_hide_title: true
-
- ``{class_name}``
- {"=" * (len(class_name) + 4)}
- .. autoclass:: {package_name}.{class_name}
- :show-inheritance:
- :members:
- :member-order: bysource
- :undoc-members:
- :inherited-members:
- """
+def _write_module_page(
+ output_path: Path,
+ module_name: str,
+ source_path: Path,
+) -> None:
+ imported_names = _imported_names(source_path)
+ excluded_members = ""
+ if imported_names:
+ excluded_members = f" :exclude-members: {', '.join(imported_names)}\n"
+ output_path.write_text(
+ dedent(
+ f"""
+ :sd_hide_title: true
+
+ ``{module_name}``
+ {"=" * (len(module_name) + 4)}
+
+ .. automodule:: {module_name}
+ :members:
+ :undoc-members:
+ :show-inheritance:
+ :member-order: bysource
+ """
+ ).rstrip()
+ + "\n"
+ + excluded_members
)
- with open(output_path, "w") as f:
- f.write(file_content)
-
-
-def _create_function_page(output_path, package_name, function_name):
- """
- Create the `.rst` file for the given function.
-
- Parameters
- ----------
- output_path : Path
- The path to the output file.
- package_name : str
- The name of the package as it would be imported.
- function_name : str
- The name of the function to document, that is part of the package.
- """
- file_content = dedent(
- f"""
- :sd_hide_title: true
-
- ``{function_name}``
- {"=" * (len(function_name) + 4)}
- .. autofunction:: {package_name}.{function_name}
- """
- ).strip()
- with open(output_path, "w") as f:
- f.write(file_content)
-
-
-def _is_public_class(module: ModuleType, attr_name: str) -> bool:
- """
- Check if the attribute is a public class.
- """
- return _is_public(attr_name) and isinstance(getattr(module, attr_name), type)
-def _is_public_function(module: ModuleType, attr_name: str) -> bool:
- """
- Check if the attribute is a public function.
- """
- return _is_public(attr_name) and callable(getattr(module, attr_name))
-
-
-def _is_public(attr_name: str) -> bool:
- """
- Check if the attribute is public.
- """
- return not attr_name.startswith("_")
-
-
-def skip_nonrelevant(
- app: Sphinx, what: str, name: str, obj: Any, skip: bool, options: dict
-) -> bool:
- """
- Skip all class members, that are not methods, enum values or inner
- classes, since other attributes are already documented in the class
- docstring.
-
- Furthermore, skip all class members, that are inherited from
- non-PLINDER base classes.
-
- See
- https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#event-autodoc-skip-member
- for more information.
- """
- if skip:
- return True
- if not _is_relevant_type(obj):
- return True
- if obj.__module__ is None:
- # Some built-in functions have '__module__' set to None
- return True
- package_name = obj.__module__.split(".")[0]
- if package_name != "plinder":
- return True
- return False
-
-
-def _is_relevant_type(obj: Any) -> bool:
- """
- Check if the given object is an attribute that is worth documenting.
- """
- if type(obj).__name__ == "method_descriptor":
- # These are some special built-in Python methods
- return False
- return (
- (
- # Functions
- type(obj)
- in [types.FunctionType, types.BuiltinFunctionType, types.MethodType]
- )
- | (
- # Enum instance
- isinstance(obj, enum.Enum)
- )
- | (
- # Inner class
- isinstance(obj, type)
- )
- )
+def _imported_names(source_path: Path) -> list[str]:
+ """Return names bound by top-level imports in a Python source file."""
+ tree = ast.parse(source_path.read_text())
+ names: set[str] = set()
+ for node in tree.body:
+ if isinstance(node, ast.Import):
+ names.update(
+ alias.asname or alias.name.split(".")[0] for alias in node.names
+ )
+ elif isinstance(node, ast.ImportFrom):
+ names.update(alias.asname or alias.name for alias in node.names)
+ return sorted(name for name in names if not name.startswith("_"))
diff --git a/docs/conf.py b/docs/conf.py
index aec33ab7f..c425beb25 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -5,7 +5,9 @@
import plinder
DOC_PATH = Path(__file__).parent
-COLUMN_REFERENCE_PATH = DOC_PATH.parent / "src" / "plinder" / "data" / "column_descriptions"
+COLUMN_REFERENCE_PATH = (
+ DOC_PATH.parent / "src" / "plinder" / "data" / "column_descriptions"
+)
# Avoid verbose logs in rendered notebooks
os.environ["PLINDER_LOG_LEVEL"] = "0"
@@ -17,9 +19,26 @@
import tablegen
import viewcode
-# Pregeneration of files
-for package in ["plinder.core", "plinder.core.scores", "plinder.core.loader"]:
- apidoc.generate_api_reference(package, DOC_PATH / "api" / package.split(".")[-1])
+# Modules that require dependencies outside the standard ``pip install plinder``.
+API_EXCLUDED_MODULES = {
+ "plinder.core.loader",
+ "plinder.data.annotations.aggregate_annotations",
+ "plinder.data.annotations.get_ligand_validation",
+ "plinder.data.annotations.ligand_utils",
+ "plinder.data.annotations.protein_utils",
+ "plinder.data.clusters",
+ "plinder.data.get_system_annotations",
+ "plinder.data.pipeline",
+}
+
+# Generate one reference page per module included in the standard installation.
+apidoc.clear_api_reference(DOC_PATH / "api")
+for package in ["plinder.core", "plinder.data", "plinder.eval"]:
+ apidoc.generate_api_reference(
+ package,
+ DOC_PATH / "api" / package.split(".")[-1],
+ excluded_modules=API_EXCLUDED_MODULES,
+ )
tablegen.generate_table(COLUMN_REFERENCE_PATH, DOC_PATH / "table.html")
#### Source code link ###
@@ -70,6 +89,11 @@
linkcode_resolve = viewcode.linkcode_resolve
templates_path = ["templates"]
+exclude_patterns = [
+ "_build",
+ # Deferred until the loader API is revisited in a focused PR.
+ "examples/5_dataset_and_loader.ipynb",
+]
source_suffix = {
".rst": "restructuredtext",
".ipynb": "myst-nb",
@@ -125,6 +149,7 @@
}
html_sidebars = {
# No primary sidebar for these pages
+ "tutorial/**": [],
"dataset": [],
"evaluation": [],
"citation": [],
@@ -136,10 +161,3 @@
"doc_path": "doc",
}
html_scaled_image_link = False
-
-
-#### App setup ####
-
-
-def setup(app):
- app.connect("autodoc-skip-member", apidoc.skip_nonrelevant)
diff --git a/docs/contribution/development.md b/docs/contribution/development.md
index e879ec724..826400c0c 100644
--- a/docs/contribution/development.md
+++ b/docs/contribution/development.md
@@ -16,67 +16,64 @@ $ git clone https://github.com/plinder-org/plinder.git
### Creating the Conda environment
-The `plinder` subpackages beside `plinder.core` require dependencies that are not
-installable via `pip`.
-The most convenient way to install the aforementioned extra dependencies is a _Conda_
-environment.
+The data generation pipeline (`plinder.data`) and evaluation require a few tools
+that are only available via _Conda_ (mmseqs2, foldseek, OpenStructure).
If you have not _Conda_ installed yet, we recommend its installation via
[miniforge](https://github.com/conda-forge/miniforge).
-Afterwards the environment can be created from the `environment.yml` in the local
-repository clone.
-
-:::{note}
-Currently only a Linux environment is fully supported, although the base
-environment also installs to MacOS.
-`plinder.data` uses a number of dependencies which are not simply pip-installable.
-Several dependencies which are referenced by a GitHub link directly, make
-a pip-installable package problematic.
-This includes Linux pytorch, which will not work in MacOS.
-These additional dependencies can be installed by running:
```console
-$ pip install -r requirements_data.txt
+$ mamba env create -f environment.yml
+$ mamba activate plinder
```
-`plinder.eval` also relies on `openstructure` for metrics
-calculations. For Windows and MacOS users, please see the relevant
-[_Docker_](#docker-target) resources.
-:::
+### Installing `plinder`
+
+All Python dependencies are declared in `pyproject.toml`.
+With [uv](https://docs.astral.sh/uv/), install `plinder` in editable mode with the
+complete `dev` dependency group (all extras used in CI, including CPU-only pytorch
+on Linux and the git-only pipeline packages) into the active Conda environment:
```console
-$ mamba env create -f environment.yml
-$ mamba activate plinder
+$ UV_PROJECT_ENVIRONMENT="$CONDA_PREFIX" uv sync --inexact
```
-### Installing `plinder`
+CI runs the same command. Without the Conda environment, a plain `uv sync`
+installs into `.venv`; tests that need the Conda-only tools will then fail.
-Now `plinder` can be installed into the created environment:
+With pip, the base install covers data generation and the core library:
```console
$ pip install -e ".[dev]"
```
-### Enabling Pre-commit hooks
+### Evaluation scoring (optional)
-Please install pre-commit hooks, that will run the same code quality checks as the CI:
+`plinder.eval` runs the [OpenStructure](https://openstructure.org/) command-line
+actions for ligand and protein-interface evaluation. OpenStructure 2.12.0 or
+newer is installed from Bioconda by the repository's `environment.yml`; it is
+not a PyPI dependency. Install the optional evaluation dependencies with:
```console
-$ pre-commit install
+$ pip install -e ".[eval]"
```
-(docker-target)=
-### Alternative: Using a Docker container
+:::{note}
+The `eval` extra installs PoseBusters. OpenStructure is Conda-only and
+is installed by `mamba env create -f environment.yml` above.
+Data generation (`plinder.data`) does **not** require OpenStructure and
+works with numpy 2.
+
+The full data pipeline also needs the git-only packages in the `dev`
+dependency group, which only `uv sync` installs.
+:::
-We also publish the `plinder` project as a
-[docker container](https://github.com/plinder-org/plinder/pkgs/container/plinder)
-as alternative to the _Conda_-based installation, to ensure the highest level of
-compatibility with non-Linux platforms.
-See the relevant docker resources here for more details:
+### Enabling Pre-commit hooks
-- `docker-compose.yml`: defines a `base` image, the `plinder` "app" and a `test`
- container
-- `dockerfiles/base/`: contains the files for the `base` image
-- `dockerfiles/main/`: contains the files for the `plinder` "app" image
+Please install pre-commit hooks, that will run the same code quality checks as the CI:
+
+```console
+$ pre-commit install
+```
## Testing and linting
diff --git a/docs/contribution/documentation.md b/docs/contribution/documentation.md
index a44a03024..d6673f388 100644
--- a/docs/contribution/documentation.md
+++ b/docs/contribution/documentation.md
@@ -2,8 +2,8 @@
The *PLINDER* documentation resides in the `docs` directory.
The documents are written in *Markdown* files rendered with [*Sphinx*](https://www.sphinx-doc.org) and [*MyST*](https://myst-parser.readthedocs.io).
-The [Python API Tutorial](/tutorial/api) uses a [*Jupyter*](https://jupyter.org/)
-notebook rendered with [*MyST-NB*](https://myst-nb.readthedocs.io)
+The examples use [*Jupyter*](https://jupyter.org/) notebooks rendered with
+[*MyST-NB*](https://myst-nb.readthedocs.io).
## Building
diff --git a/docs/contribution/index.md b/docs/contribution/index.md
index b4b0f62ad..a4a38b6d0 100644
--- a/docs/contribution/index.md
+++ b/docs/contribution/index.md
@@ -5,23 +5,20 @@ SIB Swiss Institute of Bioinformatics, Proxima (formerly VantAI), NVIDIA, MIT CS
and will be regularly updated.
We highly welcome contributions!
-This guide gives an introduction about how to maintain and improve `plinder` as
-developer
+This guide introduces how to maintain and improve `plinder` as a developer.
-# Code organization
+## Code organization
-This code is split into 4 sub-packages
+The code is split into three subpackages:
- `plinder.core`: Provides core data structures for interacting with
and loading the dataset.
- Parts of it are exposed as the [public API](/api/index).
- `plinder.data`: Contains core code for generating the PLINDER dataset.
-- `plinder.eval`: Offers evaluation harness for the dataset that takes as an input
- predicted and ground truth structures in a pre-determined folder structure an
- returns a leaderboard-ready set of entries.
- Parts of it are user-faced via [CLI scripts](/evaluation).
-- `plinder.methods`: Implements methods in the leaderboard that leverage
- PLINDER primitives for training and running.
+- `plinder.eval`: Provides an evaluation harness that compares predicted and
+ ground-truth structures and produces leaderboard-ready results.
+
+The modules included in a standard installation are listed in the
+[Python API reference](/api/index).
:::{toctree}
:maxdepth: 1
diff --git a/docs/contribution/pipeline.md b/docs/contribution/pipeline.md
index af0e3e30c..f456f802c 100644
--- a/docs/contribution/pipeline.md
+++ b/docs/contribution/pipeline.md
@@ -1,9 +1,9 @@
# Pipeline
-We outline conceptually the steps of the end-to-end pipeline in the following sections.
-We briefly describe some of the abstractions that are used to orchestrate the entire
-pipeline, but they are to be considered an implementation detail because they rely
-on our choice of orchestration framework for job execution.
+The data pipeline runs as Slurm jobs using the scripts in
+[`scripts/slurm`](https://github.com/plinder-org/plinder/tree/main/scripts/slurm).
+The Slurm runbook describes job submission, array sizing, dependencies, and
+final release assembly. The following sections describe the individual stages.

@@ -21,21 +21,120 @@ end-to-end pipeline through task wrappers in `plinder.data.pipeline.tasks`.
- `ingest/{two_char_code}/{full_pdb_id}/{full_pdb_id}-enrich.cif.gz`
- `reports/{two_char_code}/{pdb_id}/{pdb_id}_validation.xml.gz`
-- `tasks.download_alternative_datasets`: download all the alternative datasets used to enrich `plinder`
+- `tasks.download_alternative_datasets`: download the approved datasets used to enrich `plinder`
- This is a task that is called once but reaches out to numerous external REST APIs
- - This could be threaded and arguably the alphafold sync could be its own task
- Side effects include writing the following files:
- - `dbs/alphafold/AF-{uniprod_id}-F1-model_v4.cif`
- `dbs/cofactors/cofactors.json`
- `dbs/components/components.parquet`
- - `dbs/ecod/ecod.parquet`
- - `dbs/kinase/kinase_information.parquet`
- - `dbs/kinase/kinase_ligand_ccd_codes.parquet`
- - `dbs/kinase/kinase_uniprotac.parquet`
- - `dbs/kinase/kinase_structures.parquet`
- - `dbs/panther/panther_{i}.parquet`
+ - `dbs/affinity/measurements.parquet`
+ - `dbs/affinity/candidates.parquet`
- `dbs/seqres/pdb_seqres.txt.gz`
+## Planning weekly updates
+
+Compare a release with a local PDB snapshot before changing its files:
+
+```bash
+python -m plinder.data.pipeline.updates /path/to/release /path/to/update-plan \
+ --nextgen-root /scicore/data/managed/PDB_NEXTGEN/latest/pdb_nextgen \
+ --obsolete /scicore/data/managed/PDB/latest/data/status/obsolete.dat \
+ --threads 8
+```
+
+On sciCORE, run this command in a Slurm job. The output directory must be new
+and outside the existing release. The command writes `entries.tsv` and
+`entries.parquet` with added, revised, obsolete, unchanged, or blocked entries,
+plus `plan.json` describing the downstream work. A ready plan also contains
+PDB-ID lists for entry processing, removals, and score replacement.
+
+Revisions are compared with `index/entry_sources.parquet`. The first run reads
+the current CIFs; subsequent runs can use
+`--previous-snapshot /path/to/earlier-plan/snapshot.parquet` to reuse revision
+reads when the holdings timestamps match. This inventory is a read cache, not
+a record of applied updates. Use `--pdb-manifest` with a newline-delimited list
+of PDB IDs for a small trial.
+
+Only `obsolete.dat` authorizes a removal. Missing sources, conflicting current
+and obsolete records, and revisions older than the release block the plan;
+blocked plans contain reports but no executable PDB-ID lists. Successor IDs
+are recorded separately because a replacement can have different chains and
+ligands.
+
+Apply a ready plan to a new release workspace with the original release's
+pipeline configuration:
+
+```bash
+python -m plinder.data.pipeline.update_release /path/to/update-plan /path/to/update-workspace \
+ --validation-root /scicore/data/managed/PDB/latest/validation_reports \
+ --config /path/to/original-ingest-config.yaml \
+ --scratch-dir /path/to/scratch \
+ --threads 8 --memory-limit 32GB
+```
+
+This updates entry tables and ligand archives, protein search databases and
+clusters, similarities in both directions, ligand chemistry, representative
+covers, and the final release tables. Alignment and score work follows the
+search databases enabled in the original configuration; linked apo chains are
+updated when `apo` is enabled. Unchanged files are hard linked on the same
+filesystem and copied otherwise. The existing release stays unchanged. Each
+completed stage is recorded in `weekly_update.json`; rerunning the same command
+resumes after the last completed stage. A completed update has `status:
+complete` in both `weekly_update.json` and `index/collation.json`.
+
+The lower-level commands below are useful when inspecting individual stages.
+Prepare only the changed entry tables with:
+
+```bash
+python -m plinder.data.pipeline.update_entries /path/to/update-plan /path/to/update-workspace \
+ --validation-root /scicore/data/managed/PDB/latest/validation_reports \
+ --config /path/to/original-ingest-config.yaml \
+ --threads 4 --memory-limit 8GB
+```
+
+This processes added and revised entries, removes obsolete entries from the
+seven entry tables, and retains unaffected rows from the existing release.
+The updated tables are under `update-workspace/index/`; new per-entry data and
+ligand SDFs are under `update-workspace/.incoming/`. The existing release stays
+unchanged. Rerun the same command to resume failed entry processing or reuse
+completed tables. Use a new workspace if the plan, source release, or annotation
+settings change. Entry processing uses the sequential batch runner; `--threads`
+controls table processing.
+
+Update the canonical ligand archives after preparing the entry tables:
+
+```bash
+python -m plinder.data.pipeline.update_archives /path/to/update-workspace \
+ --threads 4 --memory-limit 8GB
+```
+
+This replaces poses for revised entries, adds new poses, and removes obsolete
+entries. Only affected shards are rewritten. Unchanged shards use hard links
+on the same filesystem and copies otherwise; treat release files as immutable
+and replace them rather than editing them in place. The complete archive set
+is checked against the updated annotation table before installation. The same
+command can be rerun after a failure.
+
+Prepare the scoring-input tables from the updated index:
+
+```bash
+python -m plinder.data.pipeline.score prepare-scoring-inputs /path/to/update-workspace \
+ --threads 4 --memory-limit 8GB
+```
+
+This builds ligand-pocket representatives, pocket residue mappings, interface
+representatives, their membership tables, and the alignment chain lookup. It
+reads the updated entry tables without loading coordinates or running searches.
+Completed tables are reused when their inputs are unchanged; `--force` rebuilds
+them. An optional `--scratch-dir` sets the location of temporary files.
+
+These lower-level commands leave the workspace marked
+`requires_downstream_repair`; finish it with the all-stage command above. Search
+changes cover both query and target directions. A small reverse search identifies
+existing queries that hit changed targets, and those queries are rerun against
+the complete current database so hit limits remain correct. Independent changes
+to validation reports, NextGen enrichment, CCD data, or annotation settings need
+a separate refresh; the planner compares PDB coordinate revisions.
+
## Database creation
Once the raw data is downloaded, we need to create the `foldseek` and `mmseqs`
@@ -55,143 +154,167 @@ is already heavily distributed and it would add complexity to the DAG.
- `tasks.make_entries`: creates the `raw_entries` data
- This is a distributed task that is called in parallel for chunks of PDB IDs
- It uses the `cif.gz` and `xml.gz` data in `Entry.from_cif_file`
- - It additionally uses the following alternative datasets:
- - `ECOD`
- - `Panther`
- - `Kinase`
+ - It additionally uses the following approved annotation datasets:
- `Cofactors`
- `Components`
+ - `BindingDB`
- Side effects include writing the following files:
- - `raw_entries/{two_char_code}/{pdb_id}.json`
- - `raw_entries/{two_char_code}/{system_id}/**`
-
-## Structure quality checks
-
-After raw annotation generation, we run a series of quality checks
-on the generated data and do some consolidation and organization
-of the generated data.
-
-- `tasks.structure_qc`: runs the structure quality checks
- - This is a distributed task that is called in parallel for chunks of two character codes
- - It reads in the JSON files in `raw_entries`
+ - `raw_entries/{two_char_code}/{pdb_id}.parquet`
+ - `raw_entries/{two_char_code}/{pdb_id}/interfaces.parquet`
+ - `raw_entries/{two_char_code}/{pdb_id}/entry_metadata.parquet`
+ - `raw_entries/{two_char_code}/{pdb_id}/entry_biounit_chains.parquet`
+ - `raw_entries/{two_char_code}/{pdb_id}/entry_chains.parquet`
+ - `raw_entries/{two_char_code}/{pdb_id}/entry_source.parquet`
+ - `raw_entries/{two_char_code}/{pdb_id}/ligand_files/{asym_id}.sdf`
+
+- `tasks.collate_entries`: validates and joins the per-entry files
+ - The annotation table contains one row per retained ligand
+ - Entry, chain, biological-assembly membership, interface, and source data are
+ written to separate tables instead of being repeated on every ligand row
+ - `query_table()` joins these tables when columns from more than one table are requested
- Side effects include writing the following files:
- - `qc/index/{two_char_code}.parquet` - consolidated annotations
- - `qc/logs/{two_char_code}_qc_fails.csv` - list of entries that failed QC
- - `entries/{two_char_code}.zip` - zipped JSON entries
+ - `index/annotation_table.parquet`
+ - `index/interface_annotation_table.parquet`
+ - `index/entry_metadata.parquet`
+ - `index/entry_chains.parquet`
+ - `index/entry_biounit_chains.parquet`
+ - `index/entry_sources.parquet`
-## Structure archives
+## Canonical ligand archives
-The amount of structural data generated in `make_entries` is large and consolidated
-separately in its own task.
+Canonical asymmetric-unit ligand SDFs are consolidated separately.
-- `tasks.make_system_archives`: creates the structure archives
+- `tasks.make_canonical_ligand_archives`: creates the ligand archives
- This is a distributed task that is called in parallel for chunks of two character codes
- - It consolidates the structure files into zip archives in the same layout as for `entries`
- - The inner structure of each structure zip is grouped by system ID
+ - It stores one canonical asymmetric-unit SDF per PDB ligand asym ID
- Side effects include writing the following files:
- - `archives/{two_char_code}.zip` - zipped structure files
+ - `ligand_archives/{two_char_code}.parquet`
+
+- `tasks.finalize_ligand_archives`: validates that every populated entry shard has
+ an archive before publishing the archive manifest
## Ligand Similarity
Once the `plinder` systems have been generated by `make_entries`, we can enumerate
the small molecule ligands in the dataset.
-- `tasks.make_ligands`: creates the `ligands` data
- - This is a distributed task that is called in parallel for chunks of PDB IDs
- - It filters out ligands that are acceptable for use in ligand similarity
- - It uses the JSON files from `raw_entries`
- - Side effects include writing the following files:
- - `ligands/{chunk_hash}.parquet`
-- `tasks.compute_ligand_fingerprints`: computes the ligand fingerprints
+- `tasks.compute_ligand_fingerprints`: computes fixed ECFP4 fingerprints (Morgan radius 2, 1024 bits, no chirality) and records that definition in Parquet metadata
- This is a task that is called once
- - It uses the `ligands` data
+ - It uses unique canonical SMILES from the annotation table
- Side effects include writing the following files:
- - `fingerprints/ligands_per_inchikey.parquet`
- - `fingerprints/ligands_per_inchikey_ecfp4.npy`
- - `fingerprints/ligands_per_system.parquet`
+ - `fingerprints/ligands_per_smiles.parquet`
- `tasks.make_ligand_scores`: creates the `ligand_scores` data
- This is a distributed task that is called in parallel for chunks of ligand IDs
- - It uses the `fingerprints` data
+ - It uses RDKit `BulkTanimotoSimilarity` on the unique canonical-SMILES fingerprints and retains every edge above the configured minimum
- Side effects include writing the following files:
- `ligand_scores/{fragment}.parquet`
+- `tasks.annotate_ligand_similarity`: writes chemical identifiers and cofactor-like
+ annotations to `fingerprints/ligand_similarity_annotations.parquet`
+ - It checks that the ligand-score shards contain every expected fingerprint query
## Sub-databases
Once the `plinder` systems have been generated, we are able to split the `foldseek`
-and `mmseqs` databases into sub-databases containing `holo` and `apo` systems. We additionally use the alphafold linked_structures
-to create the `pred` sub-database.
+and `mmseqs` databases into sub-databases containing `holo` and `apo` chains.
- `tasks.make_sub_dbs`: creates the `holo` and `apo` sub-databases
- This is a task that is called once
- It uses the `foldseek` and `mmseqs` databases
+ - Holo contains protein chains used by a ligand receptor or protein interface
+ - Apo contains deposited protein-chain candidates for ligand and interface
+ apo selection
- Side effects include writing the following files:
- `dbs/subdbs/holo_foldseek/**`
- `dbs/subdbs/apo_foldseek/**`
- - `dbs/subdbs/pred_foldseek/**`
- `dbs/subdbs/holo_mmseqs/**`
- `dbs/subdbs/apo_mmseqs/**`
- - `dbs/subdbs/pred_mmseqs/**`
## Protein similarity
-With the `holo` and `apo` sub-databases created, we can run
-protein similarity scoring for all `plinder` systems.
+With the `holo` and `apo` sub-databases created, we can run the searches used to
+calculate pocket, interface, ligand 3D, and linked-apo scores.
+Whole-protein identity, coverage, and lDDT scores are calculated from complete-chain
+MMseqs and Foldseek alignments, whereas pocket and interface scores apply those
+alignments only to the annotated residue sets and ligand 3D scores compare the
+canonical ligand structures.
- `tasks.run_batch_searches`: runs the `foldseek` and `mmseqs` searches for large batches
- This is a distributed task that is called in parallel for large chunks of PDB IDs
- - It uses the JSON files from `raw_entries` and the `holo` and `apo` sub-databases
+ - It uses the release index and the `holo` and `apo` sub-databases
- Side effects include writing the following files:
- `foldseek` and `mmseqs` search results
-- `tasks.make_batch_scores`: creates the protein similarity scores
- - This is a distributed task that is called in parallel for smaller chunks of PDB IDs
- - It uses the JSON files from `raw_entries` and the `foldseek` and `mmseqs` search results
+- `tasks.map_batch_alignments`: maps search coordinates to release chain and residue identifiers
+
+- `tasks.collate_alignments`: creates the distributable mapped-search dataset
+ - This is a distributed task over deterministic PDB two-character shards
+ - It combines and sorts the per-query Foldseek and MMseqs results
- Side effects include writing the following files:
- - `scores/search_db=holo/*`
- - `scores/search_db=apo/*`
- - `scores/search_db=pred/*`
+ - `alignments/search_db={holo,apo}/alignment_type={foldseek,mmseqs}/shard={two_char_code}.parquet`
-## MMP and MMS
+- `tasks.make_interface_scores`: creates whole-interface similarity scores
-- `tasks.make_mmp_index`: creates the `mmp` dataset
- - This is a task that is called once
- - It additionally consolidates the `index` dataset created in `structure_qc` into a single parquet file
- - Side effects include writing the following files:
- - `mmp/plinder_mmp_series.parquet`
- - `mmp/plinder_mms.csv.gz`
+- `tasks.make_batch_scores`: creates ligand-level pocket and interaction scores
+ - Holo shards omit whole-protein metrics because those values belong to chains,
+ not individual ligands
+ - Apo shards retain the whole-protein metrics used for linked-apo selection
-## Clustering
+- `tasks.make_ligand_3d_scores`: computes ligand shape and color scores for pairs
+ with positive pocket coverage
-Once the protein similarity scores are generated, we run
-component and community clustering.
+- `tasks.finalize_scores`: validates and publishes the score shards
-- `tasks.make_components_and_communities`: creates the `components` and `communities` clusters for given metrics at given thresholds
- - This is a distributed task that is called in parallel for individual tuples of metric and threshold
- - It uses the protein similarity scores and the annotation index
- - Side effects include writing the following files:
- - `clusters/**`
+- `tasks.make_linked_apo_structures`: ranks matching deposited apo chains for
+ each holo ligand system and each side of a protein interface
+ - It prefers candidates with fewer nearby ligands before using structure quality
+ and similarity
+ - Side effects include writing the following file:
+ - `index/linked_apo_structures.parquet`
+ - `index/interface_apo_structures.parquet`
-## Splits
+## MMP
-Armed with the clusters from the previous step, we can now split the `plinder` systems into `train`, `test` and `val`.
+- `tasks.make_ligand_mmp_pairs`: creates the matched molecular pair table
+ - It uses the unique canonical SMILES and writes shared cores and transformations
+ - Side effects include writing the following file:
+ - `index/ligand_mmp_pairs.parquet`
-## Leakage
+## Clustering
-With splits in hand, we perform an exhaustive evaluation of the generated splits
-to quantify the quality of the splits through leakage metrics.
+Once the ligand, interface, and chemical similarity scores are generated, we
+select representative covers.
+
+- `tasks.make_component_reductions`: creates resumable, sharded connectivity
+ work units used by the set-cover stages
+ - Components are an internal optimization and are not published as cluster columns
+- `tasks.make_set_covers`: selects representatives using regular greedy set cover
+ for reciprocal Tanimoto similarity
+- `tasks.make_directed_set_covers`: selects representatives using greedy directed
+ set cover for pocket, interaction, ligand 3D, and interface scores
+ - At each step it selects the candidate covering the most uncovered nodes
+ - Covers above 50 first use the requested threshold, then use 50-percent edges
+ for regions left uncovered before assigning singletons
+- `tasks.summarize_clusters`: validates node coverage, labels, and output completeness
+
+- `tasks.finalize_index`: merges cover labels into the ligand and interface indexes
+ - Long-form assignments, representative IDs, and assignment scores remain in
+ `ligand_sampling/` and `interface_sampling/`
+ - The release does not publish community or component cluster columns
# Technical details
## Schemas
-The `scores` protein similarity dataset is a collection of
+The `scores` similarity dataset is a collection of
parquet files with the following schema:
- >>> from plinder.data.schemas import PROTEIN_SIMILARITY_SCHEMA
+ >>> from plinder.core.utils.schemas import PROTEIN_SIMILARITY_SCHEMA
>>> PROTEIN_SIMILARITY_SCHEMA
query_system: string
+ query_ligand_id: string
target_system: string
+ target_ligand_id: string
protein_mapping: string
mapping: string
protein_mapper: dictionary
@@ -199,45 +322,60 @@ parquet files with the following schema:
metric: dictionary
similarity: int8
-The `ligand_scores` ligand similarity dataset is a collection of
+The `ligand_scores` dataset is a collection of
parquet files with the following schema:
- >>> from plinder.data.schemas import TANIMOTO_SCORE_SCHEMA
+ >>> from plinder.core.utils.schemas import TANIMOTO_SCORE_SCHEMA
>>> TANIMOTO_SCORE_SCHEMA
query_ligand_id: int32
target_ligand_id: int32
- tanimoto_similarity_max: int8
-
-The `clusters` clustering dataset is a collection of
-parquet files with the following schema:
-
- >>> from plinder.data.schemas import CLUSTER_DATASET_SCHEMA
- >>> CLUSTER_DATASET_SCHEMA
- metric: string
- directed: bool
- threshold: int8
- system_id: string
- component: string
+ tanimoto_similarity_ecfp4_1024: float
-The `splits` split datasets are independent
-parquet files with the following schema:
+The `linked_apo_structures` table has the following schema:
- >>> from plinder.data.schemas import SPLIT_DATASET_SCHEMA
- >>> SPLIT_DATASET_SCHEMA
- system_id: string
- split: string
- cluster: string
- cluster_for_val_split: string
-
-The `linked_structures` datasets are independent
-parquet files with the following schema:
-
- >>> from plinder.data.schemas import STRUCTURE_LINK_SCHEMA
+ >>> from plinder.core.utils.schemas import STRUCTURE_LINK_SCHEMA
>>> STRUCTURE_LINK_SCHEMA
- query_system: string
- target_system: string
- protein_qcov_weighted_sum: float
- protein_fident_weighted_sum: float
- pocket_fident: float
- target_id: string
- sort_score: float
+ reference_system_id: string
+ linked_structure_id: string
+ source_entry_id: string
+ source_chain_asym_id: string
+ source_chain_auth_id: string
+ source_biounit_id: string
+ source_chain_instance: string
+ source_num_contacting_ions: int16
+ source_num_contacting_artifacts: int16
+ source_num_contacting_other_ligands: int16
+ source_resolution: float
+ rank: int16
+ num_ligand_pockets: int16
+ min_pocket_fident: int8
+ mean_pocket_fident: float
+ min_protein_fident_weighted_sum: int8
+ min_protein_fident_qcov_weighted_sum: int8
+ min_protein_lddt_weighted_sum: int8
+
+The `interface_apo_structures` table has one ranked list for each interface
+side:
+
+ >>> from plinder.core.utils.schemas import INTERFACE_APO_LINK_SCHEMA
+ >>> INTERFACE_APO_LINK_SCHEMA
+ reference_system_id: string
+ reference_side: int8
+ reference_chain_instance: string
+ reference_chain_asym_id: string
+ linked_structure_id: string
+ source_entry_id: string
+ source_chain_asym_id: string
+ source_chain_auth_id: string
+ source_biounit_id: string
+ source_chain_instance: string
+ source_num_contacting_proteins: int16
+ source_num_contacting_ions: int16
+ source_num_contacting_artifacts: int16
+ source_num_contacting_other_ligands: int16
+ source_resolution: float
+ rank: int16
+ mmseqs_fident: float
+ mmseqs_query_coverage: float
+ mmseqs_target_coverage: float
+ foldseek_lddt: float
diff --git a/docs/contribution/release.md b/docs/contribution/release.md
index b059375cf..37065b21e 100644
--- a/docs/contribution/release.md
+++ b/docs/contribution/release.md
@@ -19,6 +19,4 @@ The CI workflow will use the **most recent** match in the commit history to make
Each new version release automatically triggers the following platforms:
- A new *PyPI* release is created.
-- A new *Docker* image is pushed to the
- [registry](https://github.com/plinder-org/plinder/pkgs/container/plinder).
- This documentation website is updated.
diff --git a/docs/dataset.md b/docs/dataset.md
index b0af6e2da..d38441e44 100644
--- a/docs/dataset.md
+++ b/docs/dataset.md
@@ -4,568 +4,343 @@ sd_hide_title: true
# Dataset
-## Dataset reference
-
-### Directory structure
-
-```bash
-2024-06/
-|-- v2
- |-- index # Consolidated tabular annotations
- | |-- annotation_table.parquet
- | |-- annotation_table_nonredundant.parquet
- |-- systems # Structure files for all systems (split by `two_char_code` and zipped)
- | |-- {two_char_code}.zip
- |-- clusters # Pre-calculated cluster labels derived from the protein similarity dataset
- | |-- cluster=communities
- | |-- ...
- | |-- cluster=components
- | |-- ...
- |-- splits # Split files and the configs used to generate them (if available)
- | |-- split.parquet
- | |-- split.yaml
- |-- linked_structures # Apo and predicted structures linked to their holo systems
- | |-- {two_char_code}.zip
- |-- links # Apo and predicted structures similarity to their holo structures
- | |-- apo_links.parquet
- | |-- pred_links.parquet
- |
---------------------------------------------------------------------------------
- miscellaneous data below
---------------------------------------------------------------------------------
- |
- |-- dbs # TSVs containing the raw files and IDs in the foldseek and mmseqs sub-databases
- | |-- subdbs
- | |-- apo.csv
- | |-- holo.csv
- | |-- pred.csv
- |-- entries # Raw annotations prior to consolidation (split by `two_char_code` and zipped)
- | |-- {two_char_code}.zip
- |-- fingerprints # Index mapping files for the ligand similarity dataset
- | |-- ligands_per_inchikey.parquet
- | |-- ligands_per_inchikey_ecfp4.npy
- | |-- ligands_per_system.parquet
- |-- ligand_scores # Ligand similarity parquet dataset
- | |-- {hashid}.parquet
- |-- ligands # Ligand data expanded from entries for computing similarity
- | |-- {hashid}.parquet
- |-- mmp # Ligand matched molecular pairs (MMP) and series (MMS) data
- | |-- plinder_mmp_series.parquet
- | |-- plinder_mms.csv.gz
- |-- scores # Protein similarity parquet dataset
- | |-- search_db=apo
- | |-- apo.parquet
- | |-- search_db=holo
- | |-- {chunck_id}.parquet
- | |-- search_db=pred
- | |-- pred.parquet
-```
-
-We will describe the content of the `index`, `systems`, `clusters`, `splits`, `links` and `linked_structures` directories in detail below, the rest are described in the [miscellaneous section](#miscellaneous-target).
-
-(annotation-table-target)=
+PLINDER, the **Protein & Ligand INteraction Dataset and Evaluation Resource**,
+extracts protein-ligand systems and protein-protein interfaces from the PDB.
-### Annotation tables (`index/`)
+## Release layout
-Tables that lists all systems along with their annotations.
+PLINDER releases are identified by the month of their PDB snapshot
+(`YYYY-MM`; the current release is `2026-09`) and served from
+`https://cameo3d.org/plinder/PLINDER-/`. The file layout is:
-- `annotation_table.parquet`: Lists all systems and their annotations.
-- `annotation_table_nonredundant.parquet`: Subset of systems without redundant systems.
-
-:::{include} table.html
+:::{note}
+Historical releases remain available at `gs://plinder/2024-04/v0`,
+`gs://plinder/2024-04/v1`, and `gs://plinder/2024-06/v2`. Their layout and APIs
+differ from the current release.
:::
-`Mandatory`: The column has a non-empty, non-NaN value in for all PLINDER systems.
-`Example`: An example non-empty, non-NaN value for the given column in a PLINDER system.
-
-### Systems (`systems/`)
-
-This directory contains all the systems used in the dataset. The systems are grouped into zipped subdirectories by using two penultimate characters of PDB code (`two_char_code`). The purpose of this grouping is to make loading and querying speed palatable.
-
-Each unzipped subdirectory, contains folders named by `system_id` that contain the structure files.
-
-```bash
-|-- {two_char_code}
- |-- {system_id}
- |-- chain_mapping.json # Mapping between the chains in the receptor and the chains in the system
- |-- ligand_files # Mapping between the ligand in the receptor and the ligands in the system
- |-- receptor.cif # Receptor mmcif file
- |-- receptor.pdb # Receptor pdb file
- |-- sequences.fasta # Receptor sequence fasta
- |-- system.cif # System mmcif file
- |-- water_mapping.json # Receptor binding site water map json file
+```text
+PLINDER-/
+โโโ index/
+โ โโโ annotation_table.parquet
+โ โโโ system_validation.parquet
+โ โโโ entry_chains.parquet
+โ โโโ entry_biounit_chains.parquet
+โ โโโ entry_metadata.parquet
+โ โโโ entry_sources.parquet
+โ โโโ interface_annotation_table.parquet
+โ โโโ alignment_chain_lookup.parquet
+โ โโโ linked_apo_structures.parquet
+โ โโโ interface_apo_structures.parquet
+โ โโโ ligand_pocket_membership.parquet
+โ โโโ ligand_pocket_residues.parquet
+โ โโโ ligand_pocket_representatives.parquet
+โ โโโ ligand_clusters.parquet
+โ โโโ ligand_affinity.parquet
+โ โโโ bindingdb_measurements.parquet
+โ โโโ ligand_mmp_pairs.parquet
+โ โโโ interface_half_representatives.parquet
+โ โโโ interface_membership.parquet
+โ โโโ interface_representatives.parquet
+โ โโโ interface_clusters.parquet
+โโโ protein_clusters/
+โ โโโ sequence.parquet
+โ โโโ structure.parquet
+โโโ ligand_archives/
+โ โโโ {two_char_code}.parquet
+โโโ alignment_cigars/
+โ โโโ search_db={holo,apo,interface_apo}/
+โ โโโ alignment_type={foldseek,mmseqs}/
+โ โโโ shard={two_char_code}.parquet
+โโโ ligand_scores/
+โ โโโ retained.parquet
+โโโ ligand_sampling/
+โ โโโ set_cover/metric={metric}/threshold={threshold}.parquet
+โ โโโ directed_set_cover/metric={metric}/threshold={threshold}.parquet
+โโโ interface_sampling/
+โ โโโ directed_set_cover/metric={interface_qcov,interface_side_qcov}/threshold={threshold}.parquet
+โโโ search_databases/
+โ โโโ holo_foldseek/
+โ โโโ holo_mmseqs/
+โ โโโ monomer_foldseek/
+โ โโโ monomer_mmseqs/
+โโโ exports/
+ โโโ ligand_similarity_scores.parquet
+ โโโ interface_similarity_scores.parquet
+ โโโ interface_half_similarity_scores.parquet
+ โโโ protein_similarity_scores/
+ โ โโโ alignment_type={foldseek,mmseqs}/
+ โ โโโ shard={two_char_code}.parquet
+ โโโ monomer_similarity_scores/
+ โโโ alignment_type={foldseek,mmseqs}/
+ โโโ monomer_{holo,monomer}_{batch}.parquet
```
-### Clusters (`clusters/`)
-
-This directory contains pre-calculated cluster labels derived from the protein and pocket similarity dataset.
-The nested structure is as follows:
-
-```bash
-|-- cluster=communities
- |-- directed=False
- |-- metric={metric}
- |-- threshold={threshold}.parquet
-|-- cluster=components
- |-- directed=False
- |-- metric={metric}
- |-- threshold={threshold}.parquet
- |-- directed=True
- |-- metric={metric}
- |-- threshold={threshold}.parquet
-```
+`plinder_download` downloads the index and representative-cover tables by
+default. It asks before downloading ligand archives, alignments, score files,
+complete similarity tables, and search databases; `--yes` downloads every
+group. APIs fetch missing optional files when they need them unless offline
+mode is enabled. Source PDB mmCIFs are separate: they are fetched per PDB entry
+during reconstruction and are not part of the bulk download.
-- `cluster`: the cluster algorithm used
- - `communities`: clusters derived from community detection algorithm
- - `components`: clusters derived from disconnected component of similarity graph
-- `directed`: type of graph used for cluster input
- - `False`: undirected
- - `True`: directed
-- `metric`: the similarity metrics used for generating the clusters
- - `pli_qcov`: Protein-ligand interaction similarity between aligned ligand-binding region (pocket) residues of two systems.
- - `pli_unique_qcov`: Protein-ligand interaction similarity between aligned pocket residues of two systems, taking only unique interaction type into consideration.
- - `pocket_fident`: Pocket region sequence identity of the ligand-binding (pocket) region of a system to a (possibly non-pocket) region of another system.
- - `pocket_fident_qcov`: Sequence identity between ligand binding region (pocket) of two systems.
- - `pocket_lddt`: Structural similarity between ligand-binding region (pocket) of a system to any region (possibly non-pocket) of another system.
- - `pocket_lddt_qcov`: Structural similarity between ligand-binding region (pocket) two systems.
- - `pocket_qcov`: Query coverage between ligand-binding region of two systems.
- - `protein_fident_max`: Local sequence identity between components of two systems, aggregated by max score across all pairs of protein chains or ligand chains.
- - `protein_fident_qcov_max`: Global protein sequence identity between components of two systems multiplied by query system coverage, aggregated by max score across all pairs of protein chains or ligand chains.
- - `protein_fident_qcov_weighted_max`: Global protein sequence identity between components of two systems, aggregated by length-weighted sum of scores across mapped protein or ligand chains.
- - `protein_fident_qcov_weighted_sum`: Global protein sequence identity between components of two systems, aggregated by length-weighted max score across all pairs of protein chains or ligand chains.
- - `protein_fident_weighted_max`: Local sequence identity between components of two systems, aggregated by length-weighted max score across all pairs of protein chains or ligand chains.
- - `protein_fident_weighted_sum`: Local sequence identity between components of two systems, aggregated by length-weighted sum of scores across mapped protein or ligand chains.
- - `protein_lddt_max`: Local structural similarity between chains of two systems, aggregated by max score across all pairs of protein chains or ligand chains.
- - `protein_lddt_qcov_max`: Global protein structural similarity multiplied by query system coverage, aggregated by max score across all pairs of protein chains or ligand chains.
- - `protein_lddt_qcov_weighted_max`: Global protein structural similarity multiplied by query system coverage, aggregated by length-weighted max score across all pairs of protein chains or ligand chains.
- - `protein_lddt_qcov_weighted_sum`: Global protein structural similarity multiplied by query system coverage, aggregated by length-weighted sum of scores across mapped protein or ligand chains.
- - `protein_lddt_weighted_max`: Local structural similarity between chains of two systems, aggregated by length-weighted max score across all pairs of protein chains or ligand chains.
- - `protein_lddt_weighted_sum`: Local structural similarity between chains of two systems, aggregated by length-weighted sum of scores across mapped protein or ligand chains.
- - `protein_qcov_weighted_sum`: Global protein query coverage, aggregated by length-weighted sum of scores across mapped protein or ligand chains.
- - `protein_seqsim_max`: Global protein sequence similarity between components of two systems, aggregated by max score across all pairs of protein chains or ligand chains.
- - `protein_seqsim_qcov_max`: Global protein sequence similarity between components of two systems multiplied by query system coverage, aggregated by max score across all pairs of protein chains or ligand chains.
- - `protein_seqsim_qcov_weighted_max`: Global protein sequence similarity between components of two systems multiplied by query system coverage, aggregated by length-weighted max score across all pairs of protein chains or ligand chains.
- - `protein_seqsim_qcov_weighted_sum`: Global protein sequence similarity between components of two systems multiplied by query system coverage, aggregated by length-weighted sum of scores across mapped protein or ligand chains.
- - `protein_seqsim_weighted_max`: Global protein sequence similarity between components of two systems, aggregated by length-weighted max score across all pairs of protein chains or ligand chains.
- - `protein_seqsim_weighted_sum`: Global protein sequence similarity between components of two systems, aggregated by length-weighted sum of scores across mapped protein or ligand chains.
-- `threshold`: similarity threshold in percent.
- - ...
- - `50`
- - `70`
- - `95`
- - `100`
-
-### Splits (`splits/`)
-
-This directory contains split files and the configs used to generate them.
-
-- `split.parquet`: listing the split category for each system
-- `split.yaml`: the config used to generate the split
-
-:::{list-table} `split.parquet`
-:widths: 10 5 30
-:header-rows: 1
-
-- - Name
- - Type
- - Description
-- - system_id
- - str
- - The PLINDER system ID
-- - split
- - str
- - Split category: either `train` (training set), `test` (test set),`val` (training set) or `removed` (removed for de-leaking purposes)
-- - cluster
- - str
- - Cluster label used in sampling test set
-- - cluster_for_val_split
- - str
- - Cluster label used in sampling validation set.
-- - uniqueness
- - str
- - system label used to remove redundant systems from the split
-- - system_pass_validation_criteria
- - bool
- - does as system pass the crystal quality for test?
-- - system_pass_statistics_criteria
- - bool
- - does a system fit the statistics criteria for test?
-- - system_proper_num_ligand_chains
- - int
- - number of ligand entries in a system that are not classified as ion or artifact (i.e "proper" ligands)
-- - system_proper_pocket_num_residues
- - int
- - total number of pocket residues that are within 6 ร distance to a "proper" ligand(s) in a system
-- - system_proper_num_interactions
- - int
- - total number of PLI interactions to a "proper" ligand(s) in a system
-- - system_proper_ligand_max_molecular_weight
- - float
- - maximum molecular weight of the "proper" ligand(s) in a system
-- - system_has_binding_affinity
- - bool
- - does the system have a ligand with an annotated binding affinity?
-- - system_has_apo_or_pred
- - bool
- - does the system have either `apo` or `pred` structure linked?
-:::
-
-The content of `split.yaml` is described below:
-
-```bash
-split:
- graph_configs: # Similarity graph configuration
- - metric: pli_unique_qcov # Metric used to generate the base graph from which all partitioning is done.
- threshold: 30 # Threshold used to generate the base graph from which all partitioning is done.
- depth: 1 # Depth at which the neighbors are defined.
- - metric: protein_seqsim_weighted_sum # Same as above
- threshold: 30 # Same as above
- depth: 1 # Same as above
- mms_unique_quality_count: 3 # How many unique congeneric IDs passing quality to consider as MMS
- ligand_cluster_metric: Tanimoto_similarity_max # which metric to use for ligand clusters (these are added to test from removed if they are different from train/val and corresponding leaked systems are removed from train/val)
- ligand_cluster_threshold: 50 # Which threshold to use for ligand clusters
-
- ligand_cluster_cluster: components # Which cluster to use for ligand clusters
- test_cluster_cluster: communities # What kind of cluster to use for sampling test
- test_cluster_metric: pli_unique_qcov # Metric to use for sampling representatives from each test cluster
- test_cluster_threshold: 50 # Threshold to use for sampling representatives from each test cluster
- test_cluster_directed: false # Directed to use for sampling representatives from each test cluster
- num_test_representatives: 2 # Max number of representatives from each test cluster
- num_per_entry_pdb_id_and_unique_ccd_codes: 1 # Max number of systems to choose per entry pdb id and unique ccd codes
- min_test_cluster_size: 5 # Test should not be singletons
- min_test_leakage_count: 30 # Test should not be too unique
- max_test_leakage_count: 1000 # Test should not be in too big communities or cause too many train cases to be removed
- max_removed_fraction: 0.2 # Maximum fraction of systems that can be removed due to test set selection
- num_test: 1000 # test set size
- val_cluster_cluster: components # What kind of cluster to use for sampling val
- val_cluster_metric: pocket_qcov # Metric to use for splitting train and val
- val_cluster_threshold: 50 # Threshold to use for splitting train and val
- val_cluster_directed: false # Directed to use for splitting train and val
- num_val_representatives: 3 # Max number of representatives from each val cluster
- min_val_cluster_size: 30 # Val should not be singletons
- num_val: 1000 # Val set size
- min_max_pli: # Test/val should not have too few or too many interactions
- - 3
- - 50
- min_max_pocket: # Test/val should not have too few or too many pocket residues
- - 5
- - 100
- min_max_ligand: # Test/val should not have too small or too large ligands
- - 200
- - 800
- test_additional_criteria: # Priority columns to use for scoring systems with a weight attached to each column
- - - system_pass_validation_criteria # Indicator of whether a system is passing validation criteria
- - ==
- - 'True'
- - - system_pass_statistics_criteria # Indicator of whether a system is passing statistic criteria
- - ==
- - 'True'
- - - biounit_num_ligands # Number of ligands in the biounit.
- - <=
- - 20
- priority_columns:
- system_ligand_has_cofactor: -40.0
- leakage_count: -1.0
-```
+(annotation-table-target)=
+(annotation-tables-index)=
+
+## Release tables
+
+The following are all registered release tables available through
+`query_table()`. The main tables of interest are `annotation`, which has one
+row per ligand, and `interface_annotations`, which has one row per
+protein-protein interface. The remaining tables separate entry,
+chain, validation, cluster, and representative data so clients only load it
+when needed. `query_table()` can request columns across related tables in a
+single query and selects the required relationships from those columns.
+
+- `annotation`: ligand annotations and reconstructable system IDs;
+- `system_validation`: ligand and pocket validation summaries for each
+ system;
+- `entry_chains`: one polymer chain in a PDB entry;
+- `entry_biounit_chains`: one chain instance in a biological assembly;
+- `entry_metadata`: experimental and entry-validation metadata;
+- `entry_sources`: the source mmCIF revision used for the release;
+- `interface_annotations`: one protein-chain interface;
+- `alignment_chain_lookup`: protein-chain search identifiers and
+ residue mappings;
+- `linked_apo_structures`: ranked apo chains linked to holo ligands;
+- `interface_apo_structures`: ranked apo chains linked to each side of a
+ protein interface;
+- `ligand_pocket_membership`: ligand-to-pocket-representative
+ assignments;
+- `ligand_pocket_representatives`: the receptor chains, pocket
+ residues, and protein-ligand interactions for each selected representative;
+- `ligand_clusters`: ligand cover labels, representative
+ indicators, and coverage statistics;
+- `ligand_affinity`: sequence-checked pKi or pKd and the endpoint for each
+ ligand; ambiguous values are empty;
+- `bindingdb_measurements`: individual Ki and Kd records, including target
+ sequences and inequality signs;
+- `ligand_mmp_pairs`: matched molecular pairs over unique ligand SMILES;
+- `interface_membership`: interface-to-representative assignments;
+- `interface_representatives`: representative full interfaces;
+- `interface_half_representatives`: representative interface sides;
+- `interface_clusters`: protein-interface cover labels.
+
+The checked-in column reference below is generated from these release tables.
+
+BindingDB's PDB/ligand cross-references can include similar, rather than exact,
+targets. `ligand_affinity` therefore requires a matching receptor sequence and
+one uncensored Ki or Kd endpoint before reporting a value. The individual
+records remain available in `bindingdb_measurements`.
+The table keeps BindingDB's curation source and DOIs so records imported from
+ChEMBL can be identified. BindingDB describes different reuse terms for its
+own curation and ChEMBL imports in its
+[data-availability statement](https://www.bindingdb.org/rwd/bind/gkae1075.pdf).
-### Linked structures (`linked_structures/`)
-
-This directory contains the linked apo and predicted structures for PLINDER systems. These structures are intended to be used for augmenting the PLINDER dataset, eg. for flexible docking or pocket prediction purposes.
-The files are grouped into zipped subdirectories by using `two_char_code` of the system.
-Each unzipped subdirectory contains `pred` and `apo` subfolders that in turn contain folders named by `system_id`.
-Inside each `apo/{system_id}` and `pred/{system_id}` folder is another directory containing a superposed system: `{source_id}_{chain_id}/superposed.cif`, where `{source_id}` and `{chain_id}` for apo systems is `pdb_id` with a source chain identifier, and for predicted structures, `{source_id}` is `uniprot_id` used in AF2DB with a chain identifier set to `A`.
-
-### Linked systems (`links/`)
-
-This directory contains parquet files linking PLINDER systems to their apo and predicted structures in `linked_structures/`.
-
-:::{list-table} `{apo|pred}_links.parquet`
-:widths: 10 5 30
-:header-rows: 1
-
-- - Name
- - Type
- - Description
-- - reference_system_id
- - str
- - The PLINDER system ID
-- - id
- - str
- - The PDB or AF2DB (for `apo` and `pred`, respectively) `{source_id}_{chain_id}` tag
-- - pocket_fident
- - float
- - sequence identity for pocket residues
-- - pocket_lddt
- - float
- - Local Distance Difference Test (lDDT) score for the pocket residue alpha carbons as returned by Foldseek.
-- - protein_fident_qcov_weighted_sum
- - float
- - Sum of fident \* qcov for all templates, weighted by the number of residues in the template
-- - protein_fident_weighted_sum
- - float
- - Sum of fident for all templates, weighted by the number of residues in the template
-- - protein_lddt_weighted_sum
- - float
- - Sum of lDDT for all residues, weighted by the number of residues in the template
-- - target_id
- - str
- - apo or pred stucture `{source_id}` tag
-- - sort_score
- - float
- - Score used to sort linked structures. This is resolution for apos and plddt for preds.
-- - receptor_file
- - str
- - intermediate aligned linked receptor file path
-- - ligand_files
- - str
- - intermediate file path for ligands used in calculations
-- - num_reference_ligands
- - int
- - number of ligands in reference structure
-- - num_model_ligands
- - int
- - number of ligands in model structure
-- - num_reference_proteins
- - int
- - number of protein chains in reference structure
-- - num_model_proteins
- - int
- - number of protein chains in model structure
-- - fraction_reference_ligands_mapped
- - float
- - Fraction of reference ligands that were successfully mapped to model ligands
-- - fraction_model_ligands_mapped
- - float
- - Fraction of model ligands that were successfully mapped to reference ligands
-- - lddt_pli_ave
- - float
- - Average lDDT score for protein-ligand interactions
-- - lddt_pli_wave
- - float
- - Weighted average lDDT score for protein-ligand interactions
-- - bisy_rmsd_ave
- - float
- - Average binding-site superposed symmetry-corrected RMSD between reference and model ligands
-- - bisy_rmsd_wave
- - float
- - Weighted average binding-site superposed symmetry-corrected RMSD between reference and model ligands
-- - lddt_lp_ave
- - float
- - Average lDDT score for ligand poses
-- - lddt_lp_wave
- - float
- - Weighted average lDDT score for ligand poses
-- - posebusters_mol_pred_loaded
- - bool
- - PoseBusters metric: boolean indicator of whether the predicted ligand could be loaded
-- - posebusters_mol_cond_loaded
- - bool
- - PoseBusters metric: boolean indicator of whether the conditional ligand could be loaded
-- - posebusters_sanitization
- - bool
- - PoseBusters metric: boolean indicator of whether the ligand could be sanitized
-- - posebusters_all_atoms_connected
- - bool
- - PoseBusters metric: boolean indicator of whether all atoms in the ligand are connected
-- - posebusters_bond_lengths
- - bool
- - PoseBusters metric: boolean indicator of whether all bond lengths in the ligand are within 4 standard deviations of the mean
-- - posebusters_bond_angles
- - bool
- - PoseBusters metric: boolean indicator of whether all bond angles in the ligand are within 4 standard deviations of the mean
-- - posebusters_internal_steric_clash
- - bool
- - PoseBusters metric: boolean indicator of whether there are no internal steric clashes in the ligand
-- - posebusters_aromatic_ring_flatness
- - bool
- - PoseBusters metric: boolean indicator of whether all aromatic rings in the ligand are flat
-- - posebusters_double_bond_flatness
- - bool
- - PoseBusters metric: boolean indicator of whether all double bonds in the ligand are flat
-- - posebusters_internal_energy
- - bool
- - PoseBusters metric: boolean indicator of whether the internal energy of the ligand is below 0 kcal/mol
-- - posebusters_protein-ligand_maximum_distance
- - bool
- - PoseBusters metric: boolean indicator of whether the maximum distance between the ligand and the protein is less than 5 Angstrom
-- - posebusters_minimum_distance_to_protein
- - bool
- - PoseBusters metric: boolean indicator of whether the minimum distance between the ligand and the protein is greater than 1.5 Angstrom
-- - posebusters_minimum_distance_to_organic_cofactors
- - float
- - PoseBusters metric: Minimum distance between the ligand and any organic cofactor
-- - posebusters_minimum_distance_to_inorganic_cofactors
- - bool
- - PoseBusters metric: Minimum distance between the ligand and any inorganic cofactor
-- - posebusters_minimum_distance_to_waters
- - float
- - PoseBusters metric: Minimum distance between the ligand and any water molecule
-- - posebusters_volume_overlap_with_protein
- - float
- - PoseBusters metric: Fraction of ligand volume that overlaps with the protein
-- - posebusters_volume_overlap_with_organic_cofactors
- - bool
- - PoseBusters metric: boolean indicator of whether the share of ligand volume that intersects with the organic cofactor is less than 7.5%. The volumes are defined by the van der Waals radii around the heavy atoms scaled by 0.8.
-- - posebusters_volume_overlap_with_inorganic_cofactors
- - bool
- - PoseBusters metric: boolean indicator of whether the share of ligand volume that intersects with the inorganic cofactor is less than 7.5%. The volumes are defined by the van der Waals radii around the heavy atoms scaled by 0.8.
-- - posebusters_volume_overlap_with_waters
- - bool
- - PoseBusters metric: boolean indicator of whether the share of ligand volume that intersects with the linked system waters is less than 7.5%. The volumes are defined by the van der Waals radii around the heavy atoms scaled by 0.8.
-- - fraction_reference_proteins_mapped
- - float
- - Fraction of reference protein chains with corresponding model chains
-- - fraction_model_proteins_mapped
- - float
- - Fraction of model protein chains mapped to corresponding reference chains
-- - lddt
- - float
- - Global lDDT score calculated over all atoms in the structure
-- - bb_lddt
- - float
- - Global lDDT score calculated over backbone atoms (N, CA, C, O) in the structure
-- - per_chain_lddt_ave
- - float
- - Average per-chain lDDT score calculated over all atoms
-- - per_chain_bb_lddt_ave
- - float
- - Average per-chain lDDT score calculated over backbone atoms (N, CA, C, O)
+:::{include} table.html
:::
-(miscellaneous-target)=
-
-### Miscellaneous
-
-Here we briefly describe subdirectories and their files that are not part of the main dataset but are used in the dataset processing pipeline.
-These files should be considered intermediate products and are not intended to be used directly, only for development purposes.
-
-#### Database processed files (`dbs/`)
-
-This directory contains the intermediate files of PDB structures that were successfully processed and scored by Foldseek and MMseqs2 pipeline.
-It is used in splitting to make sure that only successfully computed systems are used for splitting.
-
-```bash
-|-- subdbs
-| |-- apo.csv
-| |-- holo.csv
-| |-- pred.csv
-```
-
-Each file is a CSV with a single column: `pdb_id`.
-
-#### Raw annotations (`entries/`)
-
-This directory contains intermediate raw annotation files prior to consolidation. The files are grouped into zipped subdirectories by using `two_char_code`.
-Each subdirectory, contains `{pdb_id}.json` files with raw annotations for every system found in given `pdb_id`.
-
-#### Small molecule fingerprints (`fingerprints/`)
-
-Tables that contains all the ligand fingerprints used in calculating ligand similarity stored in `ligand_scores`.
-
-- `ligands_per_inchikey_ecfp4.npy`: `numpy` array of all-vs-all ECFP4 similarity.
-- `ligands_per_system.parquet`: table linking PLINDER systems to their ligands, including ligand ID, SMILES, InChIKey, etc.
-- `ligands_per_inchikey.parquet`: subset of `ligands_per_system.parquet` with reduced number of columns.
-
-#### Small molecule data (`ligands/`)
-
-Ligand data expanded from entries for computing similarity, saved in distributed files `{hashid}.parquet`.
-
-Eg.
-
-```
- pdb_id system_id ligand_rdkit_canonical_smiles ligand_ccd_code ligand_id inchikeys
-0 7o00 7o00__1__1.A_1.B__1.D CC(=O)N[C@H]1CO[C@H](CO)[C@@H](OC2O[C@H](CO)[C... HSR-HSR 7o00__1__1.A_1.B__1.D__1.D JHPFQHGUNGJQIZ-BQBDUENHSA-N
-1 7o00 7o00__1__1.A_1.B__1.E CC(=O)N[C@@H]1[C@@H](O)[C@H](O)[C@@H](CO)O[C@H]1O HSR 7o00__1__1.A_1.B__1.E__1.E OVRNDRQMDRJTHS-FMDGEEDCSA-N
-2 7o04 7o04__1__1.A__1.G CNCc1cc([N+](=O)[O-])ccc1Cl 4AV 7o04__1__1.A__1.G__1.G YRTNCUPHKWUHMQ-UHFFFAOYSA-N
-3 7o08 7o08__1__1.A__1.C CC1(C)CCN(Cc2ccc(NCC3(O)CCN(c4cc(NCc5ccccc5)nc... UXE 7o08__1__1.A__1.C__1.C GTLDMCHZRAFXCB-UHFFFAOYSA-N
-4 7o09 7o09__1__1.A__1.C CC1(C)CCN(Cc2ccc(N3CCOC4(CCN(c5cc(NCc6ccccc6)n... UXK 7o09__1__1.A__1.C__1.C RJEWLHZZXYDBNT-UHFFFAOYSA-N
-```
-
-#### Small molecule similarity scores (`ligand_scores/`)
-
-Tables that contains all the ligand similarity scores used in calculating the similarity between two ligands, saved in distributed files `{hashid}.parquet`.
-
-Eg.
-
-```
- query_ligand_id target_ligand_id tanimoto_similarity_max
-0 35300 6943 100
-1 35300 35300 100
-2 35300 13911 94
-3 35300 44243 90
-4 35300 24003 90
-```
-
-#### Small molecule matched molecular pairs (`mmp/`)
-
-Files that contains all the ligand matched molecular pairs (MMP) and matched molecular series (MMS).
-
-- `plinder_mmp_series.parquet`: matched molecular series (MMS) linked to PLINDER systems,
-- `plinder_mms.csv.gz`: compressed [mmpdb](https://github.com/rdkit/mmpdb) index file containing the matched molecular pairs (MMP) of all ligands in PLINDER annotation table.
-
-#### Protein similarity dataset (`scores/`)
-
-Tables that contains all the protein or pocket similarity scores used in calculating the similarity between two systems.
-
-```bash
-|-- search_db=apo
-| |-- apo.parquet
-|-- search_db=holo
-| |-- {chunck_id}.parquet
-|-- search_db=pred
-| |-- pred.parquet
-```
-
-All the parquet files have the save columns in the header.
-E.g
-
-```
- query_system target_system protein_mapping protein_mapper ... source metric mapping search_db
-1070886 1b5d__1__1.A_1.B__1.D 1b49_A 1.A:0.A foldseek ... mmseqs protein_qcov_weighted_max 1.A:0.A apo
-1070887 1b5d__1__1.A_1.B__1.D 1b49_A 1.A:0.A foldseek ... mmseqs protein_qcov_max 1.A:0.A apo
-1070888 1b5d__1__1.A_1.B__1.D 1b49_A 1.A:0.A foldseek ... both protein_fident_weighted_max 1.A:0.A apo
-1070889 1b5d__1__1.A_1.B__1.D 1b49_A 1.A:0.A foldseek ... both protein_fident_max 1.A:0.A apo
-1070890 1b5d__1__1.A_1.B__1.D 1b49_A 1.A:0.A foldseek ... mmseqs protein_fident_qcov_weighted_max 1.A:0.A apo
-... ... ... ... ... ... ... ... ... ...
-213471528 7eek__1__1.A__1.I 1uor_A 1.A:0.A foldseek ... foldseek protein_lddt_qcov_weighted_max 1.A:0.A apo
-213471529 7eek__1__1.A__1.I 1uor_A 1.A:0.A foldseek ... foldseek protein_lddt_qcov_max 1.A:0.A apo
-213471536 7eek__1__1.A__1.I 1uor_A 1.A:0.A foldseek ... foldseek pocket_lddt None apo
-213471540 7eek__1__1.A__1.I 6zl1_A 1.A:0.A foldseek ... foldseek pocket_lddt None apo
-213471541 7eek__1__1.A__1.I 6zl1_B 1.A:0.B foldseek ... foldseek pocket_lddt None apo
-```
-
-:::{list-table} `apo.parquet` columns
-:widths: 10 5 30
-:header-rows: 1
-
-- - Name
- - Type
- - Description
-- - query_system
- - str
- - The PLINDER system ID of query system
-- - target_system
- - str
- - The PLINDER system ID of target system
-- - protein_mapping
- - str
- - Chain mapping between query system and target system
-- - protein_mapper
- - str
- - Alignment method used for mapping.
-- - similarity
- - int
- - Similarity metric of interest
-- - source
- - str
- - Source of similarity metric. It could either be `foldseek`, `mmseqs` or `both`
-- - metric
- - str
- - Similarity metric of interest
-- - mapping
- - str
- - Local region mapping between query system and target system
-- - search_db
- - str
- - Search database type. Could be `apo`, `holo` or `pred`
-:::
+### Table relationships
+
+The tables can be read directly with any Parquet reader. The identifiers used
+to combine them are:
+
+- `entry_pdb_id` for entry metadata and source revisions;
+- the pair (`entry_pdb_id`, `chain_asym_id`) between `entry_biounit_chains`
+ and `entry_chains`;
+- `system_id` for ligand systems, system validation, protein interfaces, and
+ interface clusters;
+- `ligand_id` for ligand annotations, pocket-representative membership, and
+ ligand clusters;
+- `representative_ligand_id` and `representative_system_id` for the compact
+ representative tables.
+
+All registered relationships point from a table to rows that are unique on the
+join columns. Adding entry metadata, system validation, or representative
+membership therefore does not multiply the rows of the starting table. See
+{doc}`/examples/2_query_filter_index` for examples that select the required
+tables automatically.
+
+(protein-interface-reference)=
+
+## Protein interfaces
+
+`interface_annotations` has one row for an unordered pair of
+protein-chain instances in a biological assembly. Its `system_id` has the form
+`____--`.
+Assembly-chain IDs such as `1.A` and `2.A` distinguish repeated copies of the
+same asymmetric-unit chain.
+
+The table records both chain-instance IDs, resolved residue numbers and indices
+for each side, the number of contacting residue pairs, and PRODIGY-cryst
+features. Full deposited sequences and source taxonomies are in the chain and
+entry tables.
+
+`interface_representatives` stores the full-interface representatives,
+while `interface_half_representatives` stores individual interface
+sides. The latter is useful when one wants diverse protein surfaces without
+requiring both sides of the same complex. `interface_clusters` provides
+cover columns for `query_table()`, while detailed assignments are under
+`interface_sampling/`.
+
+(structure-asset-reference)=
+
+## Structures and reconstruction
+
+PLINDER stores one asymmetric-unit SDF for each ligand chain in
+`ligand_archives/{two_char_code}.parquet`. Assembly copies are not stored because
+they have the same conformation under a rigid-body transform. The archive stores
+the SDF together with the PDB entry ID and asymmetric-unit ligand ID.
+
+`PlinderSystem.reconstruct()` rebuilds selected system structures from the
+deposited PDB mmCIF, the ligand rows, and `entry_biounit_chains.parquet`.
+Accessing `PlinderSystem.system_cif` or `PlinderSystem.receptor_cif` performs
+reconstruction when the complete system or ligand-free receptor mmCIF is not
+already cached. Reconstruction options can include additional chains from the
+same PDB entry.
+
+`PlinderInterface.reconstruct()` similarly rebuilds a protein-protein interface,
+and `PlinderInterface.interface_cif` returns its standard mmCIF path. The source
+revision recorded in `entry_sources.parquet` is fetched from the
+[wwPDB versioned archive](https://www.wwpdb.org/ftp/pdb-versioned-ftp-site) and
+cached separately from the bulk release. Source PDB mmCIFs are therefore not
+included by `plinder_download`; `download_pdb_mmcifs()` can prefetch selected
+source revisions for offline reconstruction.
+
+The reconstructed mmCIFs contain the atom, sequence, component, assembly, and
+bond information needed to read them as self-contained PDBx/mmCIF files.
+Asymmetric ligand SDFs preserve the curated bond orders. Assembly-coordinate
+SDFs use the same chemistry with the recorded rigid-body transforms applied.
+
+### Linked apo chains
+
+`linked_apo_structures` associates a holo ligand system with ranked
+deposited apo protein chains. A candidate must pass the configured pocket and
+whole-chain similarity requirements for every proper ligand pocket in the holo
+system. Candidates from the same PDB entry are excluded.
+
+Ranking prefers chains with no nearby ligand-like components, then ion-only,
+artifact, and other-ligand contacts. Resolution and similarity break later
+ties. The release stores the assembly chain instance that was scored;
+`PlinderSystem.reconstruct_linked_apo()` rebuilds its coordinates from the
+recorded source entry and assembly membership.
+
+`interface_apo_structures` applies the same idea to each side of a
+protein-protein interface. Here an apo candidate is a highly similar protein
+chain in a biological assembly where that chain contacts no other protein.
+MMseqs alignments must cover at least 80% of both chains. The table retains
+sequence identity, both coverage values, Foldseek lDDT when available, and the
+exact assembly-chain instance selected for reconstruction.
+
+(similarity-score-reference)=
+
+## Similarity scores
+
+### Protein alignments
+
+`exports/protein_similarity_scores/` contains the Foldseek and MMseqs
+chain-pair scores, including query and target coverage, sequence identity,
+sequence similarity, and Foldseek lDDT. Percentage values are stored as
+integers from 0 to 100.
+`exports/monomer_similarity_scores/` adds query chains outside ligand pockets
+and protein interfaces. Pass `include_monomers=True` to
+`query_protein_similarity()` to read both sets of chain pairs.
+
+For a custom structure or FASTA search, `search()` returns
+`result.chain_similarity_scores`, a Parquet file of direct chain-level hits
+with the same score fields. FASTA results retain the original sequence IDs.
+By default, chain hits also include protein chains outside ligand pockets
+and protein interfaces. Pocket and interface scores use their own targets.
+
+The optional `alignment_cigars/` files contain full-chain CIGARs, alignment
+starts, and bit-packed residue identity flags. Holo chain-pair statistics are
+read from `exports/protein_similarity_scores/`.
+Pocket, protein-ligand interaction, and protein-interface residue mappings
+are recovered from these CIGARs and `alignment_chain_lookup` when needed.
+
+`plinder.core.scores.query_chain_overlap()` reports the overlapping and total
+residue counts for either ligand pockets or protein interfaces on a requested
+pair of chains. It also reports the overlap fractions and the number of
+identical residues for each available alignment backend.
+
+`plinder.core.scores.map_chain_alignment()` reads one chain pair and
+expands its CIGARs into residue positions. MMseqs rows use one-based SEQRES
+positions, while Foldseek rows use zero-based indices over the resolved
+coordinate residues. Gap rows can be retained or omitted.
+
+### Ligand similarities
+
+`exports/ligand_similarity_scores.parquet` stores the complete directed
+ligand-pair table derived from the corresponding protein alignments and ligand
+comparisons. Each row contains `pocket_qcov`, `pocket_fident_qcov`, `pli_qcov`,
+and `sucos_shape`. Swapping query and target can change the values. Symmetric
+Tanimoto similarities calculated from 1,024-bit Morgan fingerprints with
+radius 2 (ECFP4) over unique canonical SMILES remain in `ligand_scores/`, which
+is used to build the reciprocal chemical covers.
+
+The Tanimoto rows contain `query_ligand_id`, `target_ligand_id`, and
+`tanimoto_similarity_ecfp4_1024`; both ID columns refer to `ligand_smiles_id`
+values in `annotation`.
+
+### Protein-interface similarities
+
+`exports/interface_similarity_scores.parquet` contains the complete directed
+interface table with `iface1_qcov`, `iface2_qcov`, and their combined
+`similarity` value. Swapping query and target can change the coverage.
+`exports/interface_half_similarity_scores.parquet` contains directed coverage
+scores of at least 30 between individual interface sides, identified by IDs ending
+in `::side=1` or `::side=2`. Use `query_interface_similarity()` or
+`query_half_interface_similarity()` to filter these tables from Python.
+
+(representative-cover-reference)=
+
+## Representative covers
+
+- `ligand_sampling/set_cover/` contains undirected set covers for reciprocal
+ Tanimoto (ECFP4) and Jaccard (MHFP6) similarity;
+- `ligand_sampling/directed_set_cover/` contains directed covers for pocket,
+ interaction, and pocket-weighted ligand 3D metrics;
+- `interface_sampling/directed_set_cover/` contains directed covers for whole
+ protein interfaces (`interface_qcov`) and interface sides
+ (`interface_side_qcov`).
+
+Each metric has files named `metric={metric}/threshold={threshold}.parquet`.
+The release also includes one row per ligand in
+`index/ligand_clusters.parquet` and one row per interface to
+`index/interface_clusters.parquet`. `query_table()` joins these columns to the
+corresponding annotation table when requested. Tanimoto columns end in
+`__ligand__set_cover`; directional ligand columns end in
+`__ligand__directed_set_cover`.
+
+The Tanimoto cover uses only reciprocal edges meeting the requested threshold.
+For a directional cover, representative selection first maximizes residual gain
+at the requested threshold. If uncovered nodes remain above a threshold of 50,
+the algorithm uses 50-percent edges before assigning remaining singletons. The
+detailed file records `representative_selection_threshold` and
+`assignment_threshold`, so downstream selection can distinguish strict and
+fallback assignments. It also records selection order, marginal gain, and each
+node's potential coverage count and fraction.
+
+Between full clustering runs, weekly updates keep existing representatives and
+cluster IDs. Changed chains, ligands, and interfaces are compared with those
+representatives; a qualifying match joins an existing cluster, while an
+unmatched item starts a new one. The detailed cover files describe the last
+full clustering run; the index cluster tables include weekly assignments.
+
+The cluster tables also contain `__reciprocal_component` IDs. Two items share
+one ID when a path of similarities meeting the threshold in both directions
+connects them; they need not be directly similar. Weekly additions receive
+cover assignments immediately, while their component IDs await the next full
+clustering run.
+
+## Custom-scoring databases
+
+`search_databases/` contains Foldseek structure and MMseqs sequence databases
+for PLINDER receptor and interface chains, together with the chain mappings
+used by custom scoring.
+
+## Matched molecular pairs
+
+`ligand_mmp_pairs` contains compact mmpdb transformations over
+unique canonical ligand SMILES. Rows identify the two `ligand_smiles_id` values,
+both SMILES, the transformation and shared core, cut count, heavy-atom counts,
+and the fraction of each ligand contained in the shared core.
diff --git a/docs/evaluation.md b/docs/evaluation.md
index c0f83199f..35fbff5c4 100644
--- a/docs/evaluation.md
+++ b/docs/evaluation.md
@@ -2,145 +2,194 @@
sd_hide_title: true
---
-# Evaluation tools
+# Evaluation
-## Evaluating docking poses across a stratified test set
+Compare predicted ligand poses and protein interfaces with PLINDER references
+using OpenStructure. PoseBusters checks the chemical and physical plausibility
+of predicted ligands.
-The `plinder.eval` subpackage allows (1) assessing protein-ligand complex predictions against reference `plinder` systems, and
-(2) correlating the performance of these predictions against the level of similarity of each test system to the corresponding training set.
+For a runnable walkthrough, see {doc}`examples/evaluation`.
-The output file from running the scripts `src/plinder/eval/docking/write_scores.py` and `src/plinder/eval/docking/stratify_test_set.py` generates the same evaluation metrics as the ones we have on the public leaderboard.
+## Installation
-The `plinder-eval` package allows
+Install OpenStructure 2.12.0 or newer from Bioconda and the Python evaluation extra:
-1. assessing protein-ligand complex predictions against reference `plinder` systems, and
-2. correlating the performance of these predictions against the level of similarity of
-each test system to the corresponding training set.
-
-The output files from running `plinder-eval` will be used to populate the [MLSB leaderboard](https://www.mlsb.io/#challenge).
-
-### Input
+```bash
+conda install -c conda-forge -c bioconda 'openstructure>=2.12.0'
+pip install 'plinder[eval]'
+```
-`predictions.csv` with each row representating a protein-ligand pose, and the following columns:
+The `ost` executable must be on your `PATH`. PLINDER calls its
+`compare-ligand-structures` and `compare-structures` actions directly.
+The evaluation tests use OpenStructure 2.12.0 and PoseBusters 0.6.5.
+
+(arrange-your-predictions)=
+## Arrange your predictions
+
+Search and evaluation accept the same CSV, TSV, Parquet or pandas input table:
+
+| input_id | structure_path | ligand_path | reference_id |
+| --- | --- | --- | --- |
+| model_1 | models/receptor.pdb | models/pose.sdf | 8c3u__1__1.A__1.C |
+| model_2 | models/complex.cif | | 8c3u__1__1.A__1.C |
+| model_3 | models/interface.pdb | | 2e31__1__1.A--1.B |
+
+`input_id` identifies a prediction. For multiple ligand SDFs, repeat its row
+with a different `ligand_path`, or point `ligand_path` to a folder of SDFs.
+An empty ligand field selects a complete structure; an empty ligand folder
+represents zero predicted poses. Paths are relative to the table's directory;
+DataFrames use the working directory. Evaluation requires `reference_id`,
+which can be a PLINDER system/interface ID or a PDB ID. Search uses the remaining
+columns to find matches across PLINDER.
+
+Pass the table to `evaluate_predictions("inputs.tsv", output_dir="evaluation")`
+or `plinder_eval inputs.tsv --output-dir evaluation`. The search equivalent is
+`plinder.core.scores.search("inputs.tsv", output_dir="search_results")`;
+see {doc}`examples/custom_scoring` for a walkthrough.
+
+### Folder input
+
+Put each prediction in a subdirectory named after its reference:
+
+```text
+predictions/
+โโโ 8c3u__1__1.A__1.C/
+โ โโโ model_1.pdb
+โ โโโ model_1.sdf
+โ โโโ model_2.cif
+โ โโโ model_2.ligands/
+โ โโโ ligand_A.sdf
+โ โโโ ligand_B.sdf
+โโโ 8c3u/
+ โโโ model_1.cif
+```
-- `id`: An identifier for the prediction (same across different ranked poses of the same prediction)
-- `reference_system_id`: `plinder` system ID to use as reference
-- `receptor_file`: Path to protein CIF file. Leave blank if rigid docking, the system's receptor file will be used.
-- `rank`: The rank of the pose (1-indexed)
-- `confidence`: Optional score associated with the pose
-- `ligand_file`: Path to the pose SDF file or directory of SDF files for multi ligand poses
+Use a ligand-system ID or protein-interface ID for a specific reference.
+A four-character PDB ID compares each prediction with all matching systems
+or interfaces from that entry. Each file is a separate prediction.
+Both `.cif` and `.mmcif` files are accepted, including gzip-compressed files;
+the first coordinate model in each file is used.
+For protein interfaces, `.pdb` and `.pdb.gz` predictions can also be used directly.
-`split.parquet` with, at a minimum, `system_id` and `split` columns mapping PLINDER systems to `train`, or `test`.
+For ligand evaluation, supply a predicted receptor PDB/mmCIF with a matching
+`model_1.sdf`, or a `model_1.ligands/` folder containing one SDF per ligand.
+The receptor and ligand coordinates must describe the same predicted complex.
+Each SDF supplies its ligand's chemistry and coordinates. An empty
+`model_1.ligands/` folder represents a prediction with zero ligand poses.
+Choose either the single SDF or the ligand folder for each receptor.
-### Commands
+A complete predicted mmCIF can also be used on its own; PLINDER extracts its
+receptor and ligands for evaluation.
-#### Write scores
+## Run evaluation
```bash
-plinder_eval --prediction_file tests/test_data/eval/predictions.csv --output_dir test_eval/ --num_processes 8
+plinder_eval predictions --output-dir evaluation --mode both --num-workers 8
```
-This calculates accuracy metrics for all predicted poses compared to the reference. JSON files of each pose are stored in `test_eval/scores` and the summary file across all poses is stored in `test_eval/scores.parquet`.
-
-The predicted pose is compared to the reference system and the following ligand scores are calculated per each ligand:
-- `lddt_pli`: lDDT-PLI for the matched ligand
-- `bisy_rmsd`: binding-site superposed symmetry-corrected RMSD for the matched ligand
-- `lddt_lp`: lDDT score for the residues in the matched ligand pocket
-- `best_rmsd_matched_reference_chain`: chain tag of the best `bisy_rmsd` matched ligand chain in reference (useful for mutli ligand systems)
-- `best_pli_matched_reference_chain`: chain tag of the best `lddt_pli` matched ligand chain in reference (useful for mutli ligand systems)
-
-and in aggregate per system:
-- `fraction_reference_ligands_mapped`: Fraction of reference ligand chains with corresponding model chains
-- `fraction_model_ligands_mapped`: Fraction of model ligand chains mapped to corresponding reference chains
-- `lddt_pli_ave`: average lDDT-PLI across mapped ligands
-- `lddt_pli_wave`: average lDDT-PLI across mapped ligands weighted by number of atoms
-- `lddt_lp_ave`: average lDDT-LP score for the residues in the matched ligand pocket
-- `lddt_lp_wave`: average lDDT-LP across mapped ligands weighted by number of atoms
-- `bisy_rmsd_ave`: average binding-site superposed symmetry-corrected RMSD across mapped ligands
-- `bisy_rmsd_wave`: average binding-site superposed symmetry-corrected RMSD across mapped ligands weighted by number of atoms
-
-If `--score_receptor` flag is used, then protein in `receptor_file` is compared to the `reference` system receptor file and the following scores are calculated:
-
-- `fraction_reference_proteins_mapped`: Fraction of reference protein chains with corresponding model chains
-- `fraction_model_proteins_mapped`: Fraction of model protein chains mapped to corresponding reference chains
-- `lddt`: all atom lDDT
-- `bb_lddt`: CA lDDT
-- `per_chain_lddt_ave`: average all atom lDDT across all mapped chains
-- `per_chain_lddt_wave`: average all atom lDDT across all mapped chains weighted by chain length
-- `per_chain_bb_lddt_ave`: average CA lDDT across all mapped chains
-- `per_chain_bb_lddt_wave`: average CA lDDT across all mapped chains weighted by chain length
-
-For oligomeric complexes:
-
-- `qs_global` - Global QS score
-- `qs_best` - Global QS-score - only computed on aligned residues
-- `dockq_ave` - Average of DockQ scores
-- `dockq_wave` - Same as dockq_ave, weighted by native contacts
-
-If `score_posebusters` is True, all posebusters checks are saved.
-
-You can inspect the results at `test_eval/scores.parquet`
-
-```python
->>> import pandas as pd
->>> df = pd.read_parquet("test_eval/scores.parquet")
->>> df.T
- 0 1
-model 1a3b__1__1.B__1.D 1ai5__1__1.A_1.B__1.D
-reference 1a3b__1__1.B__1.D 1ai5__1__1.A_1.B__1.D
-num_reference_ligands 1 1
-num_model_ligands 1 1
-num_reference_proteins 1 2
-num_model_proteins 1 2
-fraction_reference_ligands_mapped 1.0 1.0
-fraction_model_ligands_mapped 1.0 1.0
-lddt_pli_ave 0.85815 0.510695
-lddt_pli_wave 0.85815 0.510695
-bisy_rmsd_ave 1.617184 3.665143
-bisy_rmsd_wave 1.617184 3.665143
-rank 1 1
-```
+Use `--mode ligands` or `--mode interfaces` to evaluate only one type.
+References come from your configured PLINDER release. To use a local release,
+add `--data-dir /path/to/release`. Reference coordinates are reconstructed
+from the release's recorded source structures as needed.
-#### Write test stratification data
+The equivalent Python function is
+`plinder.eval.evaluate_predictions(predictions, output_dir=..., mode="both", num_workers=8)`.
+It returns a dictionary of DataFrames as well as saving them to the output folder.
+In a standalone Python script, put the call inside
+`if __name__ == "__main__":`.
-(This command will not need to be run by a user, the `test_set.parquet` and `val_set.parquet` file will be provided with the split release)
+`num_workers` limits concurrent prediction processes. Each worker runs its
+comparisons and PoseBusters checks in sequence.
+
+## Ligand selection and bonds
+
+Ligand evaluation uses **proper reference ligands** by default: those marked
+`ligand_is_proper` in the annotation table. Add `--include-all-ligands` to
+also evaluate reference ions and artifacts. OST assigns predicted ligands to
+the selected references, including predicted ligands far from the receptor.
+
+For receptor + SDF inputs, chemistry comes from each prediction's own SDF files.
+Use this layout when different predictions use `LIG` for different molecules.
+Results identify these ligands by their original SDF filenames.
+
+For complete-mmCIF inputs, PLINDER prepares ligand SDFs from the prediction.
+Existing bonds and CCD chemistry are used where available. For an unfamiliar
+component name such as `LIG`, supply its CCD code or SMILES:
```bash
-plinder_stratify --split_file split.csv --output_dir test_data
+plinder_eval predictions --output-dir evaluation --mode ligands \
+ --ligand-ccd-codes '{"LIG": "ATP"}'
```
-Makes `test_data/test_set.parquet` which
-
-- Labels the maximum similarity of each test system to the training set across all the similarity metrics
-- Stratifies the test set based on training set similarity into `novel_pocket_pli`, `novel_ligand_pli`, `novel_protein`, `novel_ligand`, `novel_all` and `not_novel`
-- Labels test systems with high quality.
-
-To inspect the result of the run, do:
-```python
->>> import pandas as pd
->>> df = pd.read_parquet("test_eval/test_set.parquet")
->>> df.T
- 0 1
-system_id 1a3b__1__1.B__1.D 1ai5__1__1.A_1.B__1.D
-pli_qcov 0.0 0.0
-protein_seqsim_qcov_weighted_sum 0.0 0.0
-protein_seqsim_weighted_sum 0.0 0.0
-protein_fident_qcov_weighted_sum 0.0 0.0
-protein_fident_weighted_sum 0.0 0.0
-protein_lddt_qcov_weighted_sum 0.0 0.0
-protein_lddt_weighted_sum 0.0 0.0
-protein_qcov_weighted_sum 0.0 0.0
-pocket_fident_qcov 0.0 0.0
-pocket_fident 0.0 0.0
-pocket_lddt_qcov 0.0 0.0
-pocket_lddt 0.0 0.0
-pocket_qcov 0.0 0.0
-tanimoto_similarity_max 0.0 0.0
-passes_quality False False
-novel_pocket_pli True True
-novel_ligand True True
-novel_protein True True
-novel_all True True
-not_novel False False
->>>
-```
+Alternatively use `--ligand-smiles '{"LIG": "CCO"}'`.
+For SMILES, the heavy-atom order must match the CIF atom order. CCD templates
+use atom names or graph matching. These mappings apply to every prediction
+in the run that uses complete-mmCIF extraction. Use a shared mapping only when
+the component name refers to the same molecule across those predictions.
+Supply only one chemistry source per component.
+
+Protein and DNA/RNA polymers are treated as receptors. For a predicted peptide
+ligand, use `--ligand-chain B`, where `B` is its label asym ID; repeat the
+option for additional polymer ligand chains. DNA/RNA inputs need their mmCIF
+polymer sequence metadata. Covalently connected ligand chains stay together;
+ligands connected only by metal coordination are treated as separate molecules.
+
+PoseBusters is enabled for ligand evaluation. Use `--no-posebusters` to skip it.
+It checks each ligand against its paired predicted receptor, or the receptor
+extracted from the same complete mmCIF.
+The receptor's residue information is preserved in an RDKit molecule.
+
+Covalently bound ligands need care when interpreting these checks: separating
+the ligand and receptor can make their covalent attachment appear as a
+nonbonded clash. Such checks remain `False` in the results; inspect the attachment
+before interpreting it as a bad pose.
+
+## Results
+
+| File | Contents |
+| --- | --- |
+| `ligands.parquet` | One row per selected reference ligand and prediction |
+| `interfaces.parquet` | One row per reference interface and prediction |
+| `posebusters.parquet` | Plausibility checks per candidate predicted ligand |
+| `failures.tsv` | Reference-loading, preparation, or tool errors |
+| `details/` | Native OST results, PoseBusters CSVs, logs, and prepared structures |
+
+The Python return keys are `ligands`, `interfaces`, `posebusters`, and `failures`.
+`prediction` is the input path relative to the predictions folder;
+`system_id` and `ligand_id` identify the reference.
+
+Ligand metrics include `rmsd` (binding-site-superposed, symmetry-corrected RMSD),
+`bb_rmsd`, `lddt_lp`, `lddt_pli`, and the corresponding ligand coverage values.
+OST can choose different assignments for RMSD and lDDT-PLI. Their predicted
+ligand IDs are therefore stored separately as `rmsd_model_ligand` and
+`lddt_pli_model_ligand`.
+
+PoseBusters includes all candidate predicted ligands, including unmatched ones.
+To attach its checks to a reference-ligand result, join on `prediction` and
+the model-ligand ID for the metric you are analysing. The predicted IDs are
+SDF filenames for supplied poses, or label asym IDs for complete-mmCIF inputs;
+a covalent multi-chain group uses its lexically first asym ID.
+
+Interface metrics include `lddt`, `ilddt`, `qs_global`, `qs_best`,
+`dockq`, `dockq_ave_full`, and `dockq_wave_full`. The full DockQ aggregates
+include zero penalties for unmapped reference interfaces.
+
+Unmatched reference ligands have empty scores and a reason for each
+unassigned metric. `status="unassigned"` means both ligand metrics are unassigned.
+Include these rows as failures when calculating a pose-success fraction.
+`status="error"` indicates an execution problem; inspect `failures.tsv`
+and resolve it before interpreting results.
+`status="success"` means the comparison completed.
+
+OpenStructure 2.12 can reject modified receptor residues when its residue code
+disagrees with the sequence in the mmCIF, for example `CSK` in PDB entry `4agi`.
+This appears as a sequence-mismatch error in `failures.tsv`.
+Keep track of these cases when reporting how many predictions were evaluated.
+
+The command returns exit code 0 when comparisons complete, including those with
+unassigned ligands, and a nonzero code for execution errors. Each run recalculates
+results and replaces the summary tables.
+
+For additional OST settings, pass a quoted argument string with
+`--ligand-options='--flag value'` or `--interface-options='--flag value'`.
+The Python function accepts the corresponding lists of arguments.
diff --git a/docs/examples/1_download.ipynb b/docs/examples/1_download.ipynb
index bf7e912c7..6c6283b33 100644
--- a/docs/examples/1_download.ipynb
+++ b/docs/examples/1_download.ipynb
@@ -4,49 +4,39 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# Downloading the dataset\n",
+ "# Download the full dataset\n",
"\n",
- "The default location for the dataset is `~/.local/share/plinder//` where:\n",
- "- `` is the date of the PDB sync used to generate the dataset (e.g 2024-06)\n",
- "- `` is the iteration of the source code that generated the dataset (e.g. `v2`)\n",
- "\n",
- "If you want to use a different location, you can do so by setting the `PLINDER_MOUNT` environment variable."
+ "Use `plinder_download` when you need a local copy, for example on a compute node without internet access."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
+ "## Choose a local directory\n",
"\n",
- "## Use `plinder_download` to download the complete dataset\n",
- "\n",
- "```bash\n",
- "plinder_download --help\n",
- "usage:\n",
- " Download the full plinder dataset for the current configuration.\n",
- " Note that even though this is wrapped in a progress bar, the estimated\n",
- " completion time can vary wildly as it iterates over larger files vs.\n",
- " smaller ones.\n",
- " \n",
- "\n",
- "optional arguments:\n",
- " -h, --help show this help message and exit\n",
- " --release RELEASE plinder release\n",
- " --iteration ITERATION\n",
- " plinder iteration\n",
- " -y, --yes skip confirmation\n",
- "```\n",
+ "Files are cached in `~/.local/share/plinder/` by default. Set `PLINDER_MOUNT` before importing PLINDER to choose another location. Inspect the configured directory with:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from plinder.core import get_config\n",
"\n",
- ":::{note} The public `2024-06/v2` release is served from Cloudflare R2 and contains about 220 GB of downloadable files. Allow additional space for extracted archives; download time depends on your connection. Completed files are reused on subsequent runs. Set `PLINDER_OFFLINE=true` to use the cache without network requests. :::"
+ "cfg = get_config()\n",
+ "print(cfg.data.plinder_dir)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "## Use the `plinder` Python package to lazily access the dataset\n",
+ "## Download release files\n",
"\n",
- "Alternatively, if the `PLINDER_OFFLINE` environment variable **unset** (which is the default empty), the dataset will be downloaded on lazily and on the fly as you access the data. This is preferred for exploration and prototyping as you don't need to download the entire dataset at once and can just work with the assets you need for your use-case."
+ "`plinder_download` downloads the index and representative-cover tables, then asks which larger groups to include. The [dataset reference](../dataset.md) lists these groups."
]
},
{
@@ -55,11 +45,28 @@
"metadata": {},
"outputs": [],
"source": [
- "import plinder.core.utils.config\n",
+ "!plinder_download --help"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Run this in a terminal to include every group without confirmation:\n",
"\n",
- "cfg = plinder.core.get_config()\n",
- "print(f\"local directory: {cfg.data.plinder_dir}\")\n",
- "print(f\"remote data directory: {cfg.data.plinder_remote}\")"
+ "```bash\n",
+ "plinder_download --yes\n",
+ "```\n",
+ "\n",
+ "Rerun the same command after an interruption; completed files are reused. Source PDB mmCIFs are fetched separately when reconstructing structures. For offline reconstruction, first cache the entries you need with `download_pdb_mmcifs()`, described in the {ref}`structure reference `.\n",
+ "\n",
+ "## Work offline\n",
+ "\n",
+ "After the files you need are available locally, set this before starting Python:\n",
+ "\n",
+ "```bash\n",
+ "export PLINDER_OFFLINE=true\n",
+ "```"
]
}
],
@@ -70,18 +77,10 @@
"name": "python3"
},
"language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
"name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
+ "version": "3.12"
}
},
"nbformat": 4,
- "nbformat_minor": 2
+ "nbformat_minor": 4
}
diff --git a/docs/examples/2_query_filter_index.ipynb b/docs/examples/2_query_filter_index.ipynb
index 571660436..4316f9ff2 100644
--- a/docs/examples/2_query_filter_index.ipynb
+++ b/docs/examples/2_query_filter_index.ipynb
@@ -2,1072 +2,179 @@
"cells": [
{
"cell_type": "markdown",
+ "id": "query-release-tables",
"metadata": {},
"source": [
- "# The PLINDEX\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import matplotlib.pyplot as plt\n",
- "import mols2grid\n",
- "import numpy as np"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Querying and filtering the index\n",
- "\n",
- "Your main entry point to the dataset is the annotations table or the **index**, which is a Parquet file containing all the annotations for each system in the dataset.\n",
- "\n",
- ":::{note} The entire file has 745 columns, >1.3M rows, and takes 24G of RAM to load into memory :::\n",
- "\n",
- "We provide a `query_index` function to access the index and filter it based on the columns and criteria you need."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from plinder.core.scores import query_index"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The core of the PLINDER dataset is a collection of Protein-Ligand Interaction (PLI) systems extracted from the Protein Data Bank (PDB). The curation process in a nutshell is as follows:\n",
- "\n",
- "1. For every PDB entry, we generate all available biological assemblies (biounits).\n",
- "2. For each biounit, we identify all ligands and all protein chains within 6 ร of any ligand.\n",
- "3. Ligands within 4 ร of each other are merged into a single PLI system.\n",
- "4. For each system, we provide a range of detailed annotations and files to facilitate in-depth analysis and to enable a variety of use-cases.\n",
- "\n",
- "Thus, a PLI **_system_** is defined as a collection of **_protein_** and **_ligand_** chains that are in close proximity to each other within a given **_biounit_** of a given PDB **_entry_**. The **_pocket_** of a system is defined as the set of protein residues within 6 ร of the ligands in the system.\n",
- "\n",
- "Let's look at all the columns that define a `system`:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex = query_index(\n",
- " columns=[\n",
- " \"system_id\",\n",
- " \"entry_pdb_id\",\n",
- " \"system_biounit_id\",\n",
- " \"system_protein_chains_asym_id\",\n",
- " \"system_ligand_chains_asym_id\",\n",
- " \"ligand_instance_chain\",\n",
- " ]\n",
- ")\n",
- "plindex.head(20)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Thus, a system is uniquely qualified by its `system_id` which is a combination of\n",
- "- `entry_pdb_id` - the PDB identifier\n",
- "- `system_biounit_id` - the biological assembly identifier\n",
- "- `system_protein_chains_asym_id` - The list of protein chains in the system defined by their `.`\n",
- "- `system_ligand_chains_asym_id` - The list of ligand chains in the system defined by their `.`\n",
- "\n",
- "Systems containing multiple ligands (e.g `4grc__1__1.A__1.C_1.D`) span multiple rows, where each row represents a different ligand in the system (as seen in the `ligand_instance_chain` column)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "print(f\"Number of ligand chains: {plindex.shape[0]}\")\n",
- "print(f\"Number of systems: {plindex.system_id.nunique()}\")\n",
- "print(\n",
- " f\"Number of biounits: {plindex[['entry_pdb_id', 'system_biounit_id']].drop_duplicates().shape[0]}\"\n",
- ")\n",
- "print(f\"Number of PDB IDs: {plindex.entry_pdb_id.nunique()}\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "While `query_index` by default loads all the systems in the `train` and `val` splits, not every returned system may be useful for training your model."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Single-ligand single-protein predictors\n",
- "\n",
- "As an example, we consider the case of training single-ligand single-protein models. One way to filter training data is as follows:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex_single = query_index(\n",
- " filters=[\n",
- " (\"system_num_ligand_chains\", \"==\", 1),\n",
- " (\"system_num_protein_chains\", \"==\", 1),\n",
- " ],\n",
- " splits=[\"train\"],\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex_single.system_id.nunique()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "However, as PLINDER also considers ions and crystallization artifacts as ligands if they are within 4 ร of a non-ion non-artifact ligand, there are also systems in PLINDER which only have one \"proper\" ligand. So, another strategy would be to only train on the proper ligands and ignore the ions and artifacts in the system."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex_single_proper = query_index(\n",
- " filters=[\n",
- " (\"system_proper_num_ligand_chains\", \"==\", 1),\n",
- " (\"system_num_protein_chains\", \"==\", 1),\n",
- " (\"ligand_is_proper\", \"==\", True), # filters out all other ligands in the system\n",
- " ],\n",
- " splits=[\"train\"],\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex_single_proper.system_id.nunique()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This can provide up to 20% more data for training, however, the caveat is that some of the interactions made by artifacts or ions may influence the binding pose of the \"proper\" ligand.\n",
- "\n",
- "One could also choose to include multi-ligand systems but only train with one ligand at a time, and the same for multi-protein. These choices are up to the user and we provide the annotations to enable such choices."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Annotations"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "There are 745 columns in the full index. Of course, not every one will be useful for your use-case so we'll go through some common categories of them and some use-cases requiring different annotations. You can get the full list of columns with descriptions in the [index docs](https://plinder-org.github.io/plinder/dataset.html#annotation-tables-index)."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Structure quality\n",
- "\n",
- "A core principle of PLINDER is to be able to annotate which systems are of high enough experimental structure quality to be reliably used as the _ground truth_ for measuring model performance. As the quality of experimentally resolved structures [can vary significantly](https://doi.org/10.1107/S2059798322011901) and many crystal structures with ligands contain missing atoms or missing residues in the binding site, comparing prediction results to lower quality structures can incorrectly skew the perception of their performance.\n",
- "\n",
- "\n",
- "\n",
- "\n",
- "You can access all the crystal structure validation information extracted from PDB validation reports as well as crystal contact annotations by looking for columns starting with \"entry_validation\", \"system_pocket_validation\", \"system_ligand_validation\" etc."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "For simplicity, we have \"system_pass_validation_criteria\" as a column that can be used to filter systems which pass our quality definitions:\n",
- "\n",
- "```python\n",
- "class QualityCriteria:\n",
- " max_entry_resolution: float = 3.5\n",
- " max_entry_r: float = 0.4\n",
- " max_entry_rfree: float = 0.45\n",
- " max_entry_r_minus_rfree: float = 0.05\n",
- " ligand_max_num_unresolved_heavy_atoms: int = 0 # except for covalent\n",
- " ligand_max_alt_count: int = 1 # misnomer: this counts number of total configurations\n",
- " ligand_min_average_occupancy: float = 0.8\n",
- " ligand_min_average_rscc: float = 0.8\n",
- " ligand_max_average_rsr: float = 0.3\n",
- " ligand_max_percent_outliers_clashes: float = 0\n",
- " ligand_max_fraction_atoms_with_crystal_contacts: float = 0\n",
- " pocket_max_num_unresolved_heavy_atoms: int = 0\n",
- " pocket_max_alt_count: int = 1 # same as above\n",
- " pocket_min_average_occupancy: float = 0.8\n",
- " pocket_min_average_rscc: float = 0.8\n",
- " pocket_max_average_rsr: float = 0.3\n",
- " pocket_max_percent_outliers_clashes: int = 100\n",
- "```"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex = query_index(\n",
- " columns=[\"system_id\", \"system_pass_validation_criteria\"],\n",
- " splits=[\"train\", \"val\", \"test\"],\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "data = (\n",
- " plindex.drop_duplicates(\"system_id\")\n",
- " .sort_values(by=\"system_pass_validation_criteria\")\n",
- " .groupby([\"split\", \"system_pass_validation_criteria\"])\n",
- " .system_id.count()\n",
- " .unstack()\n",
- ")\n",
- "data_percentage = data.div(data.sum(axis=1), axis=0) * 100\n",
- "ax = data_percentage.plot(\n",
- " kind=\"bar\", stacked=True, figsize=(5, 3), color=[\"firebrick\", \"darkseagreen\"]\n",
- ")\n",
- "ax.set_xticklabels(\n",
- " [label.get_text().upper() for label in ax.get_xticklabels()], rotation=0\n",
- ")\n",
- "ax.set_xlabel(\"\")\n",
- "ax.set_ylabel(\"% passing criteria\")\n",
- "ax.get_legend().remove()\n",
- "for container, count_data in zip(ax.containers, data.values.T):\n",
- " ax.bar_label(container, labels=count_data, label_type=\"edge\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Structure completeness\n",
- "\n",
- "Related to structure quality, one aspect that is important to consider when using these structures in your training is **completeness**. While the inputs for prediction may be a protein sequence and a SMILES string, the protein-ligand complex structure that you get from the PDB may not have all the residues in the protein or all the atoms in the ligand resolved."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex = query_index(\n",
- " columns=[\n",
- " \"system_id\",\n",
- " \"ligand_num_unresolved_heavy_atoms\",\n",
- " \"ligand_num_heavy_atoms\",\n",
- " \"system_protein_chains_num_unresolved_residues\",\n",
- " \"system_pocket_validation_num_unresolved_heavy_atoms\",\n",
- " \"system_protein_chains_total_length\",\n",
- " ],\n",
- " splits=[\"train\", \"val\", \"test\"],\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Here we calculate the fraction of unresolved residues in the protein chains and the fraction of unresolved heavy atoms in the ligand, to see their distributions across the splits."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex[\n",
- " \"system_protein_chains_total_num_unresolved_residues\"\n",
- "] = plindex.system_protein_chains_num_unresolved_residues.map(sum)\n",
- "plindex[\"system_protein_chains_fraction_unresolved_residues\"] = (\n",
- " plindex.system_protein_chains_total_num_unresolved_residues\n",
- " / plindex.system_protein_chains_total_length\n",
- ")\n",
- "plindex[\"ligand_fraction_unresolved_heavy_atoms\"] = (\n",
- " plindex.ligand_num_unresolved_heavy_atoms / plindex.ligand_num_heavy_atoms\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "fig, axes = plt.subplots(1, 3, figsize=(10, 3), sharex=True, sharey=True)\n",
- "grouped_data = plindex.drop_duplicates(\"system_id\").groupby(\"split\")\n",
- "split_colors = {\n",
- " \"train\": \"#ff9999\",\n",
- " \"test\": \"#66b3ff\",\n",
- " \"val\": \"#7cc27c\",\n",
- "}\n",
- "for i, (split, data) in enumerate(grouped_data):\n",
- " data.system_protein_chains_fraction_unresolved_residues.hist(\n",
- " ax=axes[i], density=True, color=split_colors[split]\n",
- " )\n",
- " axes[i].set_title(split.upper())\n",
- " if i == 0:\n",
- " axes[i].set_ylabel(\"Density\")\n",
- "fig.suptitle(\n",
- " \"Fraction of Unresolved Protein Residues (SEQRES length - no. resolved residues)\"\n",
- ")\n",
- "plt.tight_layout()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "print(\"Percentage of ligands with no unresolved heavy atoms:\")\n",
- "for split in [\"train\", \"val\", \"test\"]:\n",
- " print(\n",
- " f'{split.capitalize()}: {100 * (plindex[plindex[\"split\"] == split].ligand_fraction_unresolved_heavy_atoms == 0).sum() / plindex[plindex[\"split\"] == split].shape[0]:.2f}%'\n",
- " )"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Pocket domains\n",
- "\n",
- "We annotated domains from different databases onto the protein chains of each system and then picked the one spanning the pocket residues of the system as the domain of the system pocket."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex = query_index(\n",
- " columns=[\"system_id\", \"system_pocket_ECOD_t_name\", \"system_pocket_kinase_name\"],\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex.drop_duplicates(\"system_id\").system_pocket_ECOD_t_name.value_counts().head(10)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex.drop_duplicates(\"system_id\").system_pocket_kinase_name.value_counts().head(10)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Ligand properties\n",
- "\n",
- "Molecular properties and annotations are calculated from the ligand SMILES strings"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "properties = [\n",
- " \"ligand_molecular_weight\",\n",
- " \"ligand_num_rot_bonds\",\n",
- " \"ligand_num_rings\",\n",
- " \"ligand_num_hbd\",\n",
- " \"ligand_num_hba\",\n",
- " \"ligand_num_heavy_atoms\",\n",
- " \"ligand_crippen_clogp\",\n",
- " \"ligand_qed\",\n",
- " \"ligand_tpsa\",\n",
- " \"ligand_is_kinase_inhibitor\",\n",
- "]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex = query_index(\n",
- " columns=[\"system_id\", \"ligand_instance_chain\", \"ligand_unique_ccd_code\"]\n",
- " + properties,\n",
- " splits=[\"train\", \"val\", \"test\"],\n",
- " filters=[\n",
- " (\"ligand_is_proper\", \"==\", True) # focusing on non-ion, non-artifact ligands\n",
- " ],\n",
- ")\n",
- "plindex.head(20)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "binwidths = {\n",
- " \"ligand_molecular_weight\": (\"Molecular weight\", 50),\n",
- " \"ligand_num_heavy_atoms\": (\"Number of heavy atoms\", 5),\n",
- " \"ligand_num_rot_bonds\": (\"Number of rotatable bonds\", 2),\n",
- " \"ligand_num_rings\": (\"Number of rings\", 1),\n",
- " \"ligand_tpsa\": (\"Topological polar surface area\", 10),\n",
- " \"ligand_crippen_clogp\": (\"Crippen logP\", 1),\n",
- "}\n",
- "fig, axes = plt.subplots(3, 2, figsize=(10, 7))\n",
- "axes = axes.flatten()\n",
- "for i, prop in enumerate(binwidths):\n",
- " ax = axes[i]\n",
- " plindex.groupby(\"split\")[prop].plot(\n",
- " kind=\"hist\",\n",
- " density=True,\n",
- " alpha=0.5,\n",
- " histtype=\"stepfilled\",\n",
- " legend=True,\n",
- " ax=ax,\n",
- " color=split_colors,\n",
- " bins=np.arange(\n",
- " min(plindex[prop]),\n",
- " max(plindex[prop]) + binwidths[prop][1],\n",
- " binwidths[prop][1],\n",
- " ),\n",
- " )\n",
- " ax.set_xlabel(binwidths[prop][0])\n",
- " ax.set_ylabel(\"Density\")\n",
- "plt.tight_layout()\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "These properties were further used to categorize the ligands into different types."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "ligand_types = [\n",
- " f\"ligand_is_{x}\"\n",
- " for x in [\n",
- " \"lipinski\",\n",
- " \"covalent\",\n",
- " \"cofactor\",\n",
- " \"oligo\",\n",
- " \"ion\",\n",
- " \"fragment\",\n",
- " \"artifact\",\n",
- " ]\n",
- "]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "These categories were also aggregated to the system level for easier filtering, with `system_has_` as a column indicating whether any ligand in the system is of that category."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex = query_index(\n",
- " columns=[\"system_id\", \"ligand_unique_ccd_code\"] + ligand_types,\n",
- " splits=[\"train\", \"val\", \"test\"],\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "labels = [c.replace(\"ligand_is_\", \"\").capitalize() for c in ligand_types]\n",
- "bar_colors = plt.cm.Pastel2.colors\n",
- "split_names = [\"train\", \"val\", \"test\"]\n",
- "fig, axes = plt.subplots(1, 3, figsize=(10, 3))\n",
- "for i, split in enumerate(split_names):\n",
- " ax = axes[i]\n",
- " split_data = plindex[plindex[\"split\"] == split]\n",
- " bars = ax.bar(\n",
- " labels,\n",
- " split_data[ligand_types].mean().mul(100).to_list(),\n",
- " width=1,\n",
- " color=bar_colors,\n",
- " edgecolor=\"black\",\n",
- " label=split,\n",
- " linewidth=1,\n",
- " )\n",
- " ax.set_xticks(np.arange(len(labels)), labels, rotation=70)\n",
- " ax.set_ylim(0, 100)\n",
- " ax.set_title(split.upper())\n",
- " counts = split_data[ligand_types].sum().to_list()\n",
- " for bar, count in zip(bars, counts):\n",
- " ax.text(\n",
- " bar.get_x() + bar.get_width() / 2.0,\n",
- " bar.get_height() + 2,\n",
- " f\"{count}\",\n",
- " ha=\"center\",\n",
- " va=\"bottom\",\n",
- " rotation=70,\n",
- " fontsize=10,\n",
- " )"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### PLI-specific properties\n",
+ "# Query the release tables\n",
"\n",
- "There are also some ligand properties that are specific to the interaction with the particular protein pocket present in the system. These include things like:\n",
- "- The kinds of interactions the ligand may have with the protein, calculated using PLIP\n",
- "- Experimental binding affinity, pulled from BindingDB when available (see [bug](https://github.com/plinder-org/plinder/issues/94))\n",
- "- Potential ligand-protein crystal contacts, defined as ligand-protein contacts below 5 ร which are not in the same asymmetric unit (symmetry mates) and not in the system biounit"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "pli_specific = [\n",
- " \"system_fraction_atoms_with_crystal_contacts\",\n",
- " \"system_num_crystal_contacted_residues\",\n",
- " # \"ligand_binding_affinity\",\n",
- " # \"system_has_binding_affinity\",\n",
- " \"ligand_interactions\",\n",
- " \"system_num_interactions\",\n",
- "]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex = query_index(\n",
- " columns=[\"system_id\"] + pli_specific,\n",
- " splits=[\"train\", \"val\", \"test\"],\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "You could filter out systems with crystal contacts:"
+ "Use {func}`plinder.core.query_table` to select and filter release records. The [dataset reference](../dataset.md) defines every table, key, relationship, and column."
]
},
{
"cell_type": "code",
"execution_count": null,
+ "id": "imports",
"metadata": {},
"outputs": [],
"source": [
- "(\n",
- " plindex.drop_duplicates(\"system_id\").system_fraction_atoms_with_crystal_contacts > 0\n",
- ").sum()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
+ "import pandas as pd\n",
"\n",
- " If your model has an additional component for predicting binding affinity, you could see how much data is available for training and evaluation: "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# plindex.drop_duplicates(\"system_id\").groupby(\n",
- "# \"split\"\n",
- "# ).system_has_binding_affinity.value_counts()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# plindex[\"ligand_binding_affinity\"].hist()\n",
- "# plt.xlabel(r\"$pK_i$ or $pK_D$\")\n",
- "# plt.ylabel(\"No. of system ligands\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "You could even look deeper into the kinds of protein-ligand interactions present in your training data:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex.groupby(\"split\").system_num_interactions.describe()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex[\"ligand_interactions\"].values[0]"
+ "from plinder.core import PlinderRelease, RELEASE_TABLES, query_table"
]
},
{
"cell_type": "markdown",
+ "id": "inspect-tables",
"metadata": {},
"source": [
- "## Beyond the split\n",
+ "## Inspect the available tables\n",
"\n",
- "Here we mainly focused on systems in the train/val/test splits as the train and val splits are the ones that can be used for training models to either participate in the PLINDER leaderboard or compare your models' performance to methods in the leaderboard.\n",
- "\n",
- "However, PLINDER itself contains all PLI systems in the PDB (except those containing only crystallization artifacts), and you may be interested in this dataset as a whole. This can be queried with the `splits=[\"*\"]` option."
+ "Each registered release table declares what one row represents and its primary key."
]
},
{
"cell_type": "code",
"execution_count": null,
+ "id": "table-summary",
"metadata": {},
"outputs": [],
"source": [
- "plindex = query_index(\n",
- " columns=[\n",
- " \"system_id\",\n",
- " \"entry_pdb_id\",\n",
- " \"system_num_protein_chains\",\n",
- " \"system_num_ligand_chains\",\n",
+ "release = PlinderRelease()\n",
+ "pd.DataFrame(\n",
+ " [\n",
+ " {\"table\": name, **release.table(name)}\n",
+ " for name in RELEASE_TABLES\n",
" ]\n",
- " + ligand_types,\n",
- " splits=[\"*\"],\n",
- ")\n",
- "print(\"No. ligands:\", len(plindex))\n",
- "print(\"No. systems:\", plindex.system_id.nunique())\n",
- "print(\"No. PDB entries:\", plindex.entry_pdb_id.nunique())"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "fig, ax = plt.subplots(figsize=(5, 3))\n",
- "bars = ax.bar(\n",
- " labels,\n",
- " plindex[ligand_types].mean().mul(100).to_list(),\n",
- " width=1,\n",
- " color=bar_colors,\n",
- " edgecolor=\"black\",\n",
- " label=split,\n",
- " linewidth=1,\n",
- ")\n",
- "ax.set_xticks(np.arange(len(labels)), labels, rotation=70)\n",
- "ax.set_ylim(0, 100)\n",
- "ax.set_title(f\"No. PLINDER ligands: {len(plindex)}\")\n",
- "counts = plindex[ligand_types].sum().to_list()\n",
- "for bar, count in zip(bars, counts):\n",
- " ax.text(\n",
- " bar.get_x() + bar.get_width() / 2.0,\n",
- " bar.get_height() + 2,\n",
- " f\"{count}\",\n",
- " ha=\"center\",\n",
- " va=\"bottom\",\n",
- " rotation=70,\n",
- " fontsize=10,\n",
- " )\n",
- "\n",
- "print(plindex.system_num_protein_chains.value_counts())\n",
- "print(plindex.system_num_ligand_chains.value_counts())"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "When looking at distributions across the entire dataset, you'll notice that there are quite a lot of ion systems, as well as systems with more than 5 protein or ligand chains.\n",
- "\n",
- ":::{note} While we provide annotations for all systems, those which are not in the train and val splits may not be used for training models to participate in the MLSB PLINDER leaderboard. :::"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Similarity clusters\n",
- "\n",
- "Similarity between two protein-ligand complexes can occur at various levels, including protein sequence, structural features, binding pocket characteristics, or ligand and interaction properties. We calculated a comprehensive set of similarity metrics to cover every combination of these dimensions โ from identical systems, where the protein, pocket, interactions and ligand are the same, to systems that differ across all levels.\n",
- "\n",
- "The entire set of similarity metrics is described [here](https://plinder-org.github.io/plinder/dataset.html#clusters-clusters), and they were calculated across all pairs of systems having a Foldseek or MMseqs alignment. We then used graph clustering to group systems into clusters based on their similarity with a specific **_metric_** and **_threshold_**. There are three types of clusters available: strongly connected graph components (**_strong component_**), weakly connected graph components (**_weak component_**), and communities detected using asynchronous label propagation (**_community_**).\n",
- "\n",
- "We can load the similarity clusters assigned to each system for different metrics, thresholds, and clustering types."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "These cluster labels can be used in many ways with the annotations."
+ ").set_index(\"table\")"
]
},
{
"cell_type": "markdown",
+ "id": "query-ligands",
"metadata": {},
"source": [
- "### Example: ATP-binding pockets\n",
+ "## Query ligand annotations\n",
"\n",
- "For example, maybe you are interested in seeing how many different kinds of ATP-binding pockets we have. First, let's find all the analogs of ATP. We can do this by finding the 95% ECFP4 tanimoto similarity component of ATP and then getting the CCD codes of all the ligands in the same cluster:"
+ "Select only the columns needed for the analysis. Columns such as resolution and taxonomy are found in related tables automatically. Conditions in the outer filter list are combined with AND."
]
},
{
"cell_type": "code",
"execution_count": null,
+ "id": "ligand-query",
"metadata": {},
"outputs": [],
"source": [
- "ligand_cluster_column = \"tanimoto_similarity_max__95__strong__component\"\n",
- "atp_ligand_cluster = query_index(\n",
- " columns=[\n",
- " ligand_cluster_column,\n",
- " ],\n",
- " filters=[\n",
- " (\"ligand_unique_ccd_code\", \"==\", \"ATP\"),\n",
- " (\"system_num_ligand_chains\", \"==\", 1),\n",
- " ],\n",
- ")[ligand_cluster_column].values[0]\n",
- "\n",
- "atp_analogs = query_index(\n",
+ "ligands = query_table(\n",
+ " \"annotation\",\n",
" columns=[\n",
" \"system_id\",\n",
" \"entry_pdb_id\",\n",
+ " \"ligand_id\",\n",
" \"ligand_unique_ccd_code\",\n",
- " \"ligand_rdkit_canonical_smiles\",\n",
+ " \"ligand_molecular_weight\",\n",
+ " \"system_num_protein_chains\",\n",
+ " \"system_pass_validation_criteria\",\n",
+ " \"entry_resolution\",\n",
+ " \"entry_source_taxonomy_ids\",\n",
" ],\n",
" filters=[\n",
- " (ligand_cluster_column, \"==\", atp_ligand_cluster),\n",
- " (\"system_num_ligand_chains\", \"==\", 1),\n",
+ " (\"entry_pdb_id\", \"in\", [\"4agi\", \"7eek\"]),\n",
+ " (\"ligand_is_proper\", \"==\", True),\n",
+ " (\"ligand_molecular_weight\", \"<=\", 500),\n",
+ " (\"system_num_protein_chains\", \"==\", 1),\n",
" ],\n",
- ").drop_duplicates(\"ligand_unique_ccd_code\")\n",
- "atp_analogs_code_set = set(atp_analogs.ligand_unique_ccd_code.unique())\n",
- "atp_analogs_code_set"
+ ")\n",
+ "ligands.head()"
]
},
{
"cell_type": "markdown",
+ "id": "ligand-rows",
"metadata": {},
"source": [
- "Let's see how they look"
+ "A system containing several ligands spans several rows. Count unique `system_id` values when the intended unit is a system."
]
},
{
"cell_type": "code",
"execution_count": null,
+ "id": "count-ligands-systems",
"metadata": {},
"outputs": [],
"source": [
- "grid = mols2grid.MolGrid(atp_analogs, smiles_col=\"ligand_rdkit_canonical_smiles\")\n",
- "grid.display(subset=[\"ligand_unique_ccd_code\", \"img\"])"
+ "print(f\"Ligand rows: {len(ligands):,}\")\n",
+ "print(f\"Systems: {ligands['system_id'].nunique():,}\")"
]
},
{
"cell_type": "markdown",
+ "id": "query-interfaces",
"metadata": {},
"source": [
- "Now we can get the pocket clusters of all systems containing ATP analogs. Here we're using `pocket_qcov__50__weak__component`, meaning a system within a cluster has some other system in that cluster with which it shares at least 50% of pocket residues when aligned."
+ "## Query protein interfaces\n",
+ "\n",
+ "Start from `interface_annotations` when selecting protein-chain pairs. Resolution and taxonomy are added from the entry table automatically."
]
},
{
"cell_type": "code",
"execution_count": null,
+ "id": "interface-query",
"metadata": {},
"outputs": [],
"source": [
- "pocket_cluster_column = \"pocket_qcov__50__weak__component\"\n",
- "plindex = query_index(\n",
+ "interfaces = query_table(\n",
+ " \"interface_annotations\",\n",
" columns=[\n",
" \"system_id\",\n",
- " \"entry_pdb_id\",\n",
- " \"entry_release_date\",\n",
- " pocket_cluster_column,\n",
- " \"system_pocket_ECOD_t_name\",\n",
+ " \"interface_chain_1\",\n",
+ " \"interface_chain_2\",\n",
+ " \"interface_num_contact_residue_pairs\",\n",
+ " \"prodigy_probability_bio\",\n",
+ " \"entry_resolution\",\n",
+ " \"entry_source_taxonomy_ids\",\n",
" ],\n",
" filters=[\n",
- " (\n",
- " \"ligand_unique_ccd_code\",\n",
- " \"in\",\n",
- " atp_analogs_code_set,\n",
- " ), # only ATP-binding systems\n",
- " (\"ligand_num_interactions\", \">\", 2), # with >2 interactions with ATP\n",
- " (\"system_num_ligand_chains\", \"==\", 1), # and ATP is the only ligand\n",
+ " (\"entry_pdb_id\", \"==\", \"7cm8\"),\n",
+ " (\"interface_num_contact_residue_pairs\", \">=\", 10),\n",
" ],\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "(\n",
- " \"No. systems:\",\n",
- " plindex.system_id.nunique(),\n",
- " \"No. PDB entries:\",\n",
- " plindex.entry_pdb_id.nunique(),\n",
- " \"No. clusters:\",\n",
- " plindex[pocket_cluster_column].nunique(),\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex[pocket_cluster_column].value_counts().head(10)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "When we look at the ECOD topology names of the cluster \"c11\" for example, we see that these systems are GroEL equatorial domain-like domains. Interestingly, 7 systems from 2 different PDB entries don't have ECOD annotations yet as they were recently released, but are indeed [the same domain](https://doi.org/10.1038/s41467-024-45242-x)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex[plindex[pocket_cluster_column] == \"c11\"].system_pocket_ECOD_t_name.value_counts(\n",
- " dropna=False\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex[\n",
- " (plindex[pocket_cluster_column] == \"c11\")\n",
- " & (plindex[\"system_pocket_ECOD_t_name\"].isna())\n",
- "].drop_duplicates(\"entry_pdb_id\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plindex[plindex[\"system_pocket_ECOD_t_name\"].isna()][\"entry_pdb_id\"].nunique()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Example: Diversity sampling"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The `pli_unique_qcov__50__community` column clusters systems such that the protein and ligand make similar interactions with the pocket. This clustering combines protein sequence and structural similarity (needed to obtain the pocket alignment), as well as the ligand-pocket interactions, making it a good proxy for unique kinds of binding present in the dataset.\n",
- "\n",
- "Here's an example of how one might use `torch.utils.data.WeightedRandomSampler` to sample training systems based on their PLI community cluster."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from torch.utils.data import WeightedRandomSampler\n",
- "\n",
- "cluster_column = \"pli_unique_qcov__50__community\"\n",
- "\n",
- "# Get train systems and their cluster labels\n",
- "plindex = query_index(\n",
- " columns=[\"system_id\", \"entry_pdb_id\", cluster_column], splits=[\"train\"]\n",
- ").drop_duplicates(\"system_id\")\n",
- "\n",
- "# Add the number of systems in each cluster to the dataframe\n",
- "plindex = plindex.merge(\n",
- " plindex[cluster_column].value_counts().rename(\"cluster_num_systems\"),\n",
- " left_on=cluster_column,\n",
- " right_index=True,\n",
- ").reset_index(drop=True)\n",
- "\n",
- "# Add the number of PDB entries in each cluster to the dataframe\n",
- "plindex = plindex.merge(\n",
- " plindex.drop_duplicates(\"entry_pdb_id\")[cluster_column]\n",
- " .value_counts()\n",
- " .rename(\"cluster_num_entries\"),\n",
- " left_on=cluster_column,\n",
- " right_index=True,\n",
- ").reset_index(drop=True)\n",
- "\n",
- "# Ignore clusters with only one PDB entry\n",
- "sample_from = plindex[plindex[\"cluster_num_entries\"] > 1].reset_index(drop=True)\n",
- "\n",
- "# Calculate the weight for each cluster\n",
- "cluster_weights = 1.0 / sample_from.cluster_num_systems.values\n",
- "\n",
- "# Create a WeightedRandomSampler and sample systems from the train set\n",
- "sampler = WeightedRandomSampler(\n",
- " weights=cluster_weights, num_samples=len(cluster_weights)\n",
")\n",
- "sampled_indices = list(sampler)\n",
- "sampled_plindex = (\n",
- " sample_from.iloc[sampled_indices]\n",
- " .reset_index(drop=True)\n",
- " .drop(columns=[\"cluster_num_systems\", \"cluster_num_entries\"])\n",
- ")\n",
- "\n",
- "# Add the number of sampled systems in each cluster to the sampled dataframe\n",
- "sampled_plindex = sampled_plindex.merge(\n",
- " sampled_plindex[cluster_column].value_counts().rename(\"cluster_num_systems\"),\n",
- " left_on=cluster_column,\n",
- " right_index=True,\n",
- ").reset_index(drop=True)\n",
- "\n",
- "# Add the number of sampled PDB entries in each cluster to the sampled dataframe\n",
- "sampled_plindex = sampled_plindex.merge(\n",
- " sampled_plindex.drop_duplicates(\"entry_pdb_id\")[cluster_column]\n",
- " .value_counts()\n",
- " .rename(\"cluster_num_entries\"),\n",
- " left_on=cluster_column,\n",
- " right_index=True,\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "print(\"No. of original systems: \", sample_from.system_id.nunique())\n",
- "print(\"No. of nonredundant sampled systems: \", sampled_plindex.system_id.nunique())\n",
- "print(\"No. of original clusters: \", sample_from[cluster_column].nunique())\n",
- "print(\"No. of sampled clusters: \", sampled_plindex[cluster_column].nunique())"
+ "interfaces"
]
},
{
"cell_type": "markdown",
+ "id": "query-chains",
"metadata": {},
"source": [
- "Let's see how the sampling process has affected the distribution of cluster sizes."
+ "## Query chains directly\n",
+ "\n",
+ "Use `entry_chains` when the analysis unit is a polymer chain. This avoids deduplicating chain information from ligand rows."
]
},
{
"cell_type": "code",
"execution_count": null,
+ "id": "chain-query",
"metadata": {},
"outputs": [],
"source": [
- "fig, ax = plt.subplots(1, 2, figsize=(10, 3))\n",
- "\n",
- "cluster_sizes = (\n",
- " sample_from.drop_duplicates(cluster_column)\n",
- " .cluster_num_systems.value_counts()\n",
- " .sort_index()\n",
- ")\n",
- "ax[0].hist(cluster_sizes.index, weights=cluster_sizes.values, bins=20, log=True)\n",
- "ax[0].set_xlabel(\"Cluster Size\")\n",
- "ax[0].set_ylabel(\"# Clusters (log scale)\")\n",
- "ax[0].grid(True, which=\"both\", ls=\"-\", alpha=0.2)\n",
- "\n",
- "cluster_sizes = (\n",
- " sampled_plindex.drop_duplicates(cluster_column)\n",
- " .cluster_num_systems.value_counts()\n",
- " .sort_index()\n",
+ "chains = query_table(\n",
+ " \"entry_chains\",\n",
+ " columns=[\n",
+ " \"entry_pdb_id\",\n",
+ " \"chain_asym_id\",\n",
+ " \"chain_auth_id\",\n",
+ " \"chain_sequence\",\n",
+ " \"chain_is_holo\",\n",
+ " ],\n",
+ " filters=[\n",
+ " (\"entry_pdb_id\", \"in\", [\"4agi\", \"7eek\"]),\n",
+ " (\"chain_receptor_type\", \"==\", \"protein\"),\n",
+ " ],\n",
")\n",
- "ax[1].hist(cluster_sizes.index, weights=cluster_sizes.values, bins=20, log=False)\n",
- "ax[1].set_xlabel(\"Cluster Size\")\n",
- "ax[1].set_ylabel(\"# Clusters\")"
+ "chains"
]
}
],
@@ -1087,9 +194,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.10.14"
+ "version": "3.12"
}
},
"nbformat": 4,
- "nbformat_minor": 2
+ "nbformat_minor": 5
}
diff --git a/docs/examples/3_access_system_files.ipynb b/docs/examples/3_access_system_files.ipynb
index 227d0a02e..b9237ec36 100644
--- a/docs/examples/3_access_system_files.ipynb
+++ b/docs/examples/3_access_system_files.ipynb
@@ -11,7 +11,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "We provide files for all holo PLINDER systems with <6 protein and <6 ligand chains. These can be accessed with the `PlinderSystem` object which also does the work of downloading and extracting only the relevant files if they haven't been downloaded yet. All system files will be extracted into `~/.local/share/plinder/${PLINDER_RELEASE}/${PLINDER_ITERATION}/systems`. The current default is `PLINDER_RELEASE=2024-06` and `PLINDER_ITERATION=v2`."
+ "`PlinderSystem` provides the files and coordinate views for one ligand system. See {ref}`Structures and reconstruction ` for their provenance and storage."
]
},
{
@@ -31,7 +31,7 @@
"source": [
"## Ligand\n",
"\n",
- "The ligands are provided in SDF format in `ligand_sdfs`.\n"
+ "`canonical_ligand_sdfs` contains the asymmetric-unit SDF for each ligand. `ligand_sdfs` writes copies in the reconstructed biological-assembly coordinates.\n"
]
},
{
@@ -40,14 +40,14 @@
"metadata": {},
"outputs": [],
"source": [
- "plinder_system.ligand_sdfs"
+ "plinder_system.canonical_ligand_sdfs, plinder_system.ligand_sdfs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "And the corresponding SMILES strings in `smiles`."
+ "Use `smiles` for the corresponding SMILES strings."
]
},
{
@@ -70,7 +70,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "The CIF/PDB files of the receptor are stored in `receptor_cif` and `receptor_pdb` and only contain the protein chains of the system."
+ "`receptor_cif` returns the path to an mmCIF containing the system's receptor chains."
]
},
{
@@ -79,14 +79,14 @@
"metadata": {},
"outputs": [],
"source": [
- "plinder_system.receptor_pdb, plinder_system.receptor_cif"
+ "plinder_system.receptor_cif"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "We recommend using the CIF file as PDB is an obsoleted format. However, if you must use the PDB file, an additional consideration is that the chains are renamed to single letters, which you can access with the `chain_mapping` attribute.\n"
+ "`system_cif` includes the selected receptor and ligand chains. Both structure views are written as self-contained PDBx/mmCIF files.\n"
]
},
{
@@ -95,14 +95,14 @@
"metadata": {},
"outputs": [],
"source": [
- "plinder_system.chain_mapping"
+ "plinder_system.system_cif"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "The FASTA file and sequences of the receptor are stored in `sequences_fasta` and `sequences` respectively. These are the canonical sequences of all protein chains in the system.\n"
+ "`sequences_fasta` returns the receptor FASTA path, while `sequences` returns the protein sequences by chain.\n"
]
},
{
@@ -118,11 +118,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "## Linked structures\n",
+ "## Linked apo chains\n",
"\n",
- "Where possible, we've linked plinder systems to associated apo structures from the PDB and predicted structures from AFDB. This was done using the same kind of similarity searches used for system clustering except with strict restrictions on the sequence identity and coverage of linked structures.\n",
- "\n",
- "The `linked_structures` attribute is a pandas DataFrame with information on the links for a system which were both found and additionally scored for conformational difficulty. This additional scoring consists of superposing the found apo or predicted chain to the receptor of the system with global sequence-based alignment, transplanting the ligand to the found structure, and evaluating the resulting protein-ligand complex as though it were a predicted structure for the given system. So, the `linked_structures` DataFrame contains the similarity scores from the alignments as well as the metrics from the evaluation."
+ "`linked_apo_structures` returns the ranked apo links for a holo ligand system."
]
},
{
@@ -131,7 +129,8 @@
"metadata": {},
"outputs": [],
"source": [
- "link_info = plinder_system.linked_structures"
+ "linked_system = PlinderSystem(system_id=\"10be__1__1.C__1.A_1.B\")\n",
+ "link_info = linked_system.linked_apo_structures"
]
},
{
@@ -142,15 +141,13 @@
"source": [
"link_info[\n",
" [\n",
- " \"id\",\n",
- " \"pocket_fident\",\n",
- " \"lddt\",\n",
- " \"bb_lddt\",\n",
- " \"lddt_lp_ave\",\n",
- " \"lddt_pli_ave\",\n",
- " \"bisy_rmsd_ave\",\n",
- " \"sort_score\",\n",
- " \"kind\",\n",
+ " \"linked_structure_id\",\n",
+ " \"source_entry_id\",\n",
+ " \"source_chain_instance\",\n",
+ " \"rank\",\n",
+ " \"source_resolution\",\n",
+ " \"min_pocket_fident\",\n",
+ " \"min_protein_fident_qcov_weighted_sum\",\n",
" ]\n",
"]"
]
@@ -159,22 +156,24 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "For example, here we can see that \"4uou_B\"\n",
- "- has 100% identical residues corresponding to the pocket of the system\n",
- "- has a very high lDDT and backbone lDDT scores, indicating that the structure is very similar to the receptor.\n",
- "- has a `sort_score` of 2.4, which is the resolution for an apo structure and the plDDT score for a predicted structure.\n",
- "\n",
- "Indeed the superposition + transplant results show the same story\n",
- "- a global superposition puts the ligand in the right place (seen by the `bisy_rmsd` of the ligand pose),\n",
- "- the distances between the pocket atoms are similar (seen by the `lddt_lp_ave` metric),\n",
- "- and the distances between the ligand and protein atoms are similar (seen by the `lddt_pli_ave` metric).\n",
- "\n",
- "`get_linked_structure` then gives the file path to the found structure\n",
- "\n",
- "```python\n",
- "plinder_system.get_linked_structure(\"apo\", \"4uou_B\")\n",
- "```\n",
- "\n"
+ "`reconstruct_linked_apo()` selects rank 1 by default or accepts a `linked_structure_id`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if link_info.empty:\n",
+ " print(\"No linked apo chain is available for this system.\")\n",
+ "else:\n",
+ " apo_cif = linked_system.reconstruct_linked_apo(overwrite=True)\n",
+ " selected_cif = linked_system.reconstruct_linked_apo(\n",
+ " linked_structure_id=link_info.iloc[0][\"linked_structure_id\"],\n",
+ " overwrite=True,\n",
+ " )\n",
+ " print(apo_cif, selected_cif)"
]
}
],
diff --git a/docs/examples/4_align_mask_crop.ipynb b/docs/examples/4_align_mask_crop.ipynb
index bba9fc43f..a6cee989b 100644
--- a/docs/examples/4_align_mask_crop.ipynb
+++ b/docs/examples/4_align_mask_crop.ipynb
@@ -4,7 +4,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# Structure abstraction"
+ "# Atom arrays and ligand mappings\n",
+ "\n",
+ "This advanced guide starts from a reconstructed ligand system and shows the in-memory coordinate views used for featurization and structural comparison. For file access and linked apo reconstruction, begin with [Access system files with PlinderSystem](3_access_system_files.ipynb)."
]
},
{
@@ -13,63 +15,22 @@
"metadata": {},
"outputs": [],
"source": [
+ "import pandas as pd\n",
"from rdkit.Chem.Draw import IPythonConsole\n",
"\n",
- "IPythonConsole.drawOptions.addAtomIndices = True"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "To enable using systems and linked structure files in training deep learning models, we've implemented a number of useful functions to align, mask, and featurize proteins and ligands.\n",
- "\n",
- "For this, we convert our `PlinderSystem` to a `Structure` object."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
"from plinder.core import PlinderSystem\n",
"\n",
- "plinder_system = PlinderSystem(system_id=\"4agi__1__1.C__1.W\")\n",
- "\n",
- "system_structure = plinder_system.holo_structure"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure"
+ "IPythonConsole.drawOptions.addAtomIndices = True\n",
+ "system = PlinderSystem(system_id=\"4agi__1__1.C__1.W\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "- We list all fields and their `FieldInfo` to show which ones are required. `id`, `protein_path` and `protein_sequence` are required. Everything else is optionally. Particularly worth mentioning is the decision to make `list_ligand_sdf_and_input_smiles` optional; this is because ligand will not be availbale in apo and predicted structures.\n",
- "- Out of these field `ligand_mols` and `protein_atom_array` is computed within the object if set to default. \n",
- "- `ligand_mols` returns a chain-mapped dictionary of of the form:\n",
- " ```\n",
- " {\n",
- " \".\": (\n",
- " RDKit 2D mol from template SMILES of type `Chem.Mol`,\n",
- " RDKit mol from template SMILES with random 3D conformer of type `Chem.Mol`,\n",
- " RDKit mol of solved (holo) ligand structure of type `Chem.Mol`,\n",
- " paired stacked arrays (template vs holo) mapping atom order by index of type `tuple[NDArray.int_, NDArray.int_]`\n",
- " )\n",
+ "## Coordinate views\n",
"\n",
- " }\n",
- " ```\n",
- "- While `protein_atom_array` returns [biotite AtomArray](https://www.biotite-python.org/latest/apidoc/biotite.structure.AtomArray.html) of the receptor protein structure.\n",
- "- `add_ligand_hydrogens` specifies whether to adds hydrogens to ligand\n",
- "- `structure_type`: could be `\"holo\"`, `\"apo\"` or `\"pred\"`"
+ "`PlinderSystem` exposes the receptor and each assembly ligand as Biotite atom arrays. RDKit molecules retain the curated ligand bonds and bond orders."
]
},
{
@@ -78,75 +39,14 @@
"metadata": {},
"outputs": [],
"source": [
- "system_structure.model_fields"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Ligand"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "for name in system_structure.get_properties():\n",
- " if \"ligand\" in name:\n",
- " print(name)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The ligands are provided using dictionaries.\n",
- "\n",
- "These dictionaries contain information for each ligand:\n",
- "- `input_ligand_templates`: 2D RDKit mols generated from the RDKit canonical SMILES\n",
- "- `input_ligand_conformers`: 3D (random) conformers generated for each input mol\n",
- "- `input_ligand_conformers_coords`: positional coordintates for 3D conformers\n",
- "- `resolved_ligand_mols`: RDKit mols of solved (holo) ligand structures\n",
- "- `resolved_ligand_mols_coords`: positional coordintates for holo ligand structures\n",
- "- `ligand_template2resolved_atom_order_stacks`: paired stacked arrays (template vs holo) mapping atom order by index\n",
- "- `ligand_chain_ordered`: ordered list of all ligands by their keys"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Ligand atom id mapping mapping\n",
- "\n",
- "Unlike the protein sequence - there is no canonical order to ligand atoms in the molecule.\n",
- "It can be further complicated by automorphisms present in the structure due to symmetry, i.e. there is more than one match that is possible between the structures.\n",
- "\n",
- "This is important when calculating ligand structure loss, as the most optimal atom order can change between the different inference results. Typically, it is accepted to take the atom ordering resulting in the best objective score and use that for the loss calculation.\n",
- "\n",
- "Occasionally futher ambiguity arises to to part of the ligand structure being unresolved in the holo structure - this can lead to multiple available matches. We use RascalMCES algorithm from RDKit to provide all the possible matches between the atom order in the input structure (from SMILES) to the resolved holo structure.\n",
- "\n",
- "This is provided as stacks of atom order arrays that reorder the template and holo indices to provide matches. Each stack is a unique order transformation and should be iterated."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure.input_ligand_templates[system_structure.ligand_chain_ordered[0]]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure.input_ligand_conformers[system_structure.ligand_chain_ordered[0]]"
+ "pd.Series(\n",
+ " {\n",
+ " \"receptor_atoms\": len(system.receptor_structure),\n",
+ " \"ligand_count\": system.num_ligands,\n",
+ " \"protein_chain_count\": system.num_proteins,\n",
+ " \"ligand_atoms\": sum(len(atoms) for atoms in system.ligand_structures.values()),\n",
+ " }\n",
+ ")"
]
},
{
@@ -155,17 +55,17 @@
"metadata": {},
"outputs": [],
"source": [
- "system_structure.resolved_ligand_mols[system_structure.ligand_chain_ordered[0]]"
+ "ligand_chain = next(iter(system.ligand_mols))\n",
+ "system.ligand_mols[ligand_chain]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "### Ligand conformer coordinates\n",
+ "## Protein masks and sequences\n",
"\n",
- "As you can tell, the input 2D and 3D conformer indices match, but the resolved ligand is different.\n",
- "Thus to perform a correct comparison for their coordinates one should use atom order stacks.\n"
+ "`holo_structure` combines the receptor and ligand views and provides common masks and sequence-derived properties."
]
},
{
@@ -174,135 +74,15 @@
"metadata": {},
"outputs": [],
"source": [
- "(\n",
- " input_atom_order_stack,\n",
- " holo_atom_order_stack,\n",
- ") = system_structure.ligand_template2resolved_atom_order_stacks[\n",
- " system_structure.ligand_chain_ordered[0]\n",
- "]\n",
- "input_atom_order_stack, holo_atom_order_stack"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure.input_ligand_conformers_coords[\n",
- " system_structure.ligand_chain_ordered[0]\n",
- "][input_atom_order_stack]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure.resolved_ligand_mols_coords[system_structure.ligand_chain_ordered[0]][\n",
- " holo_atom_order_stack\n",
- "]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### More complicated examples"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Symmetry in ligand (automorphism) - two ways of pairwise mapping the atom order"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "structure_with_symmetry_in_ligand = PlinderSystem(\n",
- " system_id=\"4v2y__1__1.A__1.E\"\n",
- ").holo_structure\n",
- "structure_with_symmetry_in_ligand.input_ligand_templates[\n",
- " structure_with_symmetry_in_ligand.ligand_chain_ordered[0]\n",
- "]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "structure_with_symmetry_in_ligand.resolved_ligand_mols[\n",
- " structure_with_symmetry_in_ligand.ligand_chain_ordered[0]\n",
- "]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "structure_with_symmetry_in_ligand.ligand_template2resolved_atom_order_stacks[\n",
- " structure_with_symmetry_in_ligand.ligand_chain_ordered[0]\n",
- "]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Symmetry arises due to ligand being partially resolved - there are three template pieces that can be mapped to the resolved ground truth."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "structure_with_partly_resolved_ligand = PlinderSystem(\n",
- " system_id=\"1ngx__1__1.A_1.B__1.E\"\n",
- ").holo_structure\n",
- "structure_with_partly_resolved_ligand.input_ligand_templates[\n",
- " structure_with_partly_resolved_ligand.ligand_chain_ordered[0]\n",
- "]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "structure_with_partly_resolved_ligand.resolved_ligand_mols[\n",
- " structure_with_partly_resolved_ligand.ligand_chain_ordered[0]\n",
- "]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "structure_with_partly_resolved_ligand.ligand_template2resolved_atom_order_stacks[\n",
- " structure_with_partly_resolved_ligand.ligand_chain_ordered[0]\n",
- "]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Protein"
+ "structure = system.holo_structure\n",
+ "pd.Series(\n",
+ " {\n",
+ " \"protein_atoms\": len(structure.protein_atom_array),\n",
+ " \"backbone_atoms\": int(structure.protein_backbone_mask.sum()),\n",
+ " \"calpha_atoms\": int(structure.protein_calpha_mask.sum()),\n",
+ " \"protein_chains\": len(structure.protein_chain_ordered),\n",
+ " }\n",
+ ")"
]
},
{
@@ -311,28 +91,24 @@
"metadata": {},
"outputs": [],
"source": [
- "for name in system_structure.get_properties():\n",
- " if \"protein\" in name:\n",
- " print(name)"
+ "calpha = structure.protein_atom_array[structure.protein_calpha_mask]\n",
+ "calpha.coord.shape, structure.protein_sequence"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "### Others properties\n",
- "This includes:\n",
- "- `num_ligands`: Number of ligand chains\n",
- "- `smiles`: Ligand smiles dictionary\n",
- "- `num_proteins`: Number of protein chains\n"
+ "`protein_sequence` is the full deposited polymer sequence. `protein_sequence_from_structure` is derived from resolved coordinates, so the two can differ when residues are unresolved."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "### Masking\n",
- "The properties `protein_backbone_mask` and `protein_calpha_mask` are boolean masks that can be used to select backbone or calpha atoms from biotite `AtomArray`. The indices of `True` corresponds to backbone or calpha indices."
+ "## Map canonical ligand atoms to resolved coordinates\n",
+ "\n",
+ "A canonical SDF can contain atoms that were not resolved, and molecular symmetry can permit several valid atom correspondences. PLINDER therefore exposes stacks of valid template-to-resolved atom orders rather than assuming a single positional zip."
]
},
{
@@ -341,15 +117,12 @@
"metadata": {},
"outputs": [],
"source": [
- "print(\n",
- " \"Total number of atoms:\",\n",
- " len(system_structure.protein_atom_array),\n",
+ "template = structure.input_ligand_templates[ligand_chain]\n",
+ "resolved = structure.resolved_ligand_mols[ligand_chain]\n",
+ "template_order, resolved_order = (\n",
+ " structure.ligand_template2resolved_atom_order_stacks[ligand_chain]\n",
")\n",
- "print(\"Number of backbone atoms:\", system_structure.protein_backbone_mask.sum())\n",
- "print(\n",
- " \"Number of calpha atoms:\",\n",
- " system_structure.protein_calpha_mask.sum(),\n",
- ")"
+ "template"
]
},
{
@@ -358,17 +131,7 @@
"metadata": {},
"outputs": [],
"source": [
- "calpha_atom_array = system_structure.protein_atom_array[\n",
- " system_structure.protein_calpha_mask\n",
- "]\n",
- "calpha_atom_array.coord.shape"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "You can also filter by arbitrary properties of the `AtomArray` using the `filter` method. This returns a new `Structure` object."
+ "resolved"
]
},
{
@@ -377,9 +140,13 @@
"metadata": {},
"outputs": [],
"source": [
- "calpha_structure = system_structure.filter(\n",
- " property=\"atom_name\",\n",
- " mask=\"CA\",\n",
+ "pd.Series(\n",
+ " {\n",
+ " \"valid_mappings\": len(template_order),\n",
+ " \"mapped_atoms_per_mapping\": template_order.shape[1],\n",
+ " \"template_atoms\": template.GetNumAtoms(),\n",
+ " \"resolved_atoms\": resolved.GetNumAtoms(),\n",
+ " }\n",
")"
]
},
@@ -389,213 +156,21 @@
"metadata": {},
"outputs": [],
"source": [
- "calpha_structure.protein_atom_array.coord.shape"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Get protein chain ordered\n",
- "This gives a list of protein chains ordered by how they are in the structure"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure.protein_chain_ordered"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Get protein chains for all atoms\n",
- "The list of chain IDs in the structure. Order of how they appear not kept."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure.protein_chains"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Get protein coordinates\n",
- "This property gets the 3D positions of each of the atoms in protein molecules"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure.protein_coords"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Get number of atoms of protein molecule"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure.protein_n_atoms"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Get protein structure atom names\n",
- "Returns all atoms names the same way they appear in the structure"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure.protein_unique_atom_names"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Get protein residue names"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure.protein_unique_residue_names"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Get protein residues number\n",
- "Residue number as they appear in structure"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure.protein_unique_residue_ids"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Get sequence from protein structure\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure.protein_sequence_from_structure"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Note that this is different from the canonical SEQRES sequence due to unresolved terminal residues:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure.protein_sequence"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Get tokenized sequence\n",
- "Get tensor of sequence converted to integer-based amino acid tokens"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_structure.protein_structure_tokenized_sequence"
+ "mapping_index = 0\n",
+ "template_coords = structure.input_ligand_conformers_coords[ligand_chain][\n",
+ " template_order[mapping_index]\n",
+ "]\n",
+ "resolved_coords = structure.resolved_ligand_mols_coords[ligand_chain][\n",
+ " resolved_order[mapping_index]\n",
+ "]\n",
+ "template_coords.shape, resolved_coords.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "## Linked protein input structures\n",
- "\n",
- "\n",
- "For realistic inference scenarios we need to initialize our protein structures using a linked structure (introduced above). In most cases, these will not be a perfect match to the _holo_ structure - the number of residues, residue numbering, and sometime the sequnce can be different. It's important to be able to match these structures to ensure that we can map between them. \n",
- "\n",
- "In the example below, we will take a _holo_ structure and it's linked predicted (_pred_) form with different number of residues and match and crop the resulting structures to figure out the correspondence between their residues. For this we use the `align_common_sequence` function of the holo `Structure` object, which aligns two structures based on their shared sequences. It has the following parameters:\n",
- "\n",
- "```\n",
- "other: Structure\n",
- " The other structure to align to\n",
- "copy: bool\n",
- " Whether to make a copy or edit in-place\n",
- "remove_differing_atoms: bool\n",
- " Whether to remove differing atoms between the two structure\n",
- "renumber_residues: bool [False]\n",
- " If True, renumber residues in the two structures to match and starting from 1.\n",
- " If False, sets the resulting residue indices to the one from the aligned sequence\n",
- "remove_differing_annotations: bool [False]\n",
- " Whether to remove differing annotations, like b-factor, etc\n",
- "```\n",
- "In this example, we will match, make copies and crop the structures.\n",
- "\n",
- ":::{note} To use this function the proteins to be aligned must have the same chain ids. So, we first set the chain id of the predicted structure to that of the holo structure. :::\n",
- "\n",
- "```python\n",
- "plinder_system = PlinderSystem(system_id=\"4cj6__1__1.A__1.B\")\n",
- "holo = plinder_system.holo_structure\n",
- "predicted = plinder_system.alternate_structures[\"P12271_A\"]\n",
- "predicted.set_chain(holo.protein_chain_ordered[0])\n",
- "holo_cropped, predicted_cropped = holo.align_common_sequence(predicted)\n",
- "predicted_cropped_superposed, raw_rmsd, refined_rmsd = predicted_cropped.superimpose(\n",
- " holo_cropped\n",
- ")\n",
- "```"
+ "Evaluate every valid row when a metric should be invariant to ligand automorphisms. The mapped coordinate arrays have the same shape even when the canonical and resolved molecules have different total atom counts."
]
}
],
@@ -606,18 +181,10 @@
"name": "python3"
},
"language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
"name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
+ "version": "3.12"
}
},
"nbformat": 4,
- "nbformat_minor": 2
+ "nbformat_minor": 4
}
diff --git a/docs/examples/5_dataset_and_loader.ipynb b/docs/examples/5_dataset_and_loader.ipynb
index 4575e55c1..0d88e6864 100644
--- a/docs/examples/5_dataset_and_loader.ipynb
+++ b/docs/examples/5_dataset_and_loader.ipynb
@@ -1,134 +1,5 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Datasets and Dataloaders"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from plinder.core.loader.dataset import PlinderDataset, get_torch_loader"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- "`PlinderDataset` provides an interface to interact with _PLINDER_ data as a dataset. It is a subclass of `torch.utils.data.Dataset`, as such subclassing it and extending should be familiar to most users. Flexibility and general applicability is our top concern when designing this interface and `PlinderDataset` allows users to not only define their own split but to also bring their own featurizer.\n",
- "It can be initialized with the following parameters\n",
- "```\n",
- "Parameters\n",
- " ----------\n",
- " df : pd.DataFrame | None\n",
- " the split to use\n",
- " split : str\n",
- " the split to sample from\n",
- " split_parquet_path : str | Path, default=None\n",
- " split parquet file\n",
- " input_structure_priority : str, default=\"apo\"\n",
- " Which alternate structure to proritize\n",
- " featurizer: Callable[\n",
- " [Structure, int], dict[str, torch.Tensor]\n",
- " ] = structure_featurizer,\n",
- " Transformation to turn structure to input tensors\n",
- " padding_value : int\n",
- " Value for padding uneven array\n",
- " **kwargs : Any\n",
- " Any other keyword args\n",
- "```\n",
- "\n",
- "For an example of how to write your own featurizer see [Featurizer Example](https://github.com/plinder-org/plinder/blob/c36eef9b02823ce572de905c094f6c85c03800ca/src/plinder/core/loader/featurizer.py#L16). The signature is shown below:\n",
- "```\n",
- "def structure_featurizer(\n",
- " structure: Structure, pad_value: int = -100\n",
- " ) -> dict[str, Any]:\n",
- "```\n",
- "The input is a `Structure` object and it returns dictionary of padded tensor features.\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- ":::{note}\n",
- "This is where you may want to load a `train` dataset, but for the purposes of demonstration - we will start with `val` due to smaller memory footprint, and load only a small subset of systems containing `ATP` as ligand. We also set `use_alternate_structures=False` to prevent downloading and loading alternate structures for the docs.\n",
- ":::"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "val_dataset = PlinderDataset(\n",
- " split=\"val\",\n",
- " filters=[\n",
- " (\"system_num_protein_chains\", \"==\", 1),\n",
- " (\"ligand_unique_ccd_code\", \"in\", {\"ATP\"}),\n",
- " ],\n",
- " use_alternate_structures=False,\n",
- ")\n",
- "len(val_dataset)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "val_data = val_dataset[1]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "val_loader = get_torch_loader(val_dataset)\n",
- "for data in val_loader:\n",
- " test_torch = data\n",
- " break"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "test_torch.keys()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "test_torch[\"system_ids\"]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "for k, v in test_torch[\"features_and_coords\"].items():\n",
- " print(k, v.shape)"
- ]
- }
- ],
+ "cells": [],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
@@ -136,18 +7,10 @@
"name": "python3"
},
"language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
"name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
+ "version": "3.12"
}
},
"nbformat": 4,
- "nbformat_minor": 2
+ "nbformat_minor": 4
}
diff --git a/docs/examples/6_custom_split.ipynb b/docs/examples/6_custom_split.ipynb
deleted file mode 100644
index d5e8e8ea1..000000000
--- a/docs/examples/6_custom_split.ipynb
+++ /dev/null
@@ -1,652 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Custom Split Example\n",
- "\n",
- "Contributed by [Franz Gรถrlich](https://github.com/frgoe003).\n",
- "\n",
- "Import core libraries:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from pathlib import Path\n",
- "import plinder \n",
- "\n",
- "from plinder.data.splits import (\n",
- " split,\n",
- " get_default_config,\n",
- ")\n",
- "from plinder.core.scores import query_index\n",
- "\n",
- "plinder_cfg = plinder.core.get_config()\n",
- "plinder_local_storage = plinder_cfg.data.plinder_dir"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Split Config"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "First, let's modify the split config. We will first get the default config using `get_default_config()` and then change some of the parameters."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Validation set size: 1000\n",
- "Test set size: 1000\n",
- "Minimum size of each cluster in the validation set: 30\n"
- ]
- }
- ],
- "source": [
- "cfg = get_default_config() \n",
- "print(f'Validation set size: {cfg.split.num_val}')\n",
- "print(f'Test set size: {cfg.split.num_test}')\n",
- "print(f'Minimum size of each cluster in the validation set: {cfg.split.min_val_cluster_size}')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Since we reduced the total number of samples, let's also reduce the minimum validation set cluster size, so we avoid removing to many systems. All configs can be found [here](https://plinder-org.github.io/plinder/dataset.html#splits-splits)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 27,
- "metadata": {},
- "outputs": [],
- "source": [
- "cfg.split.num_test = 500 # Reduce the max size of the test set\n",
- "cfg.split.num_val = 500 # Reduce the max size of the validation set\n",
- "cfg.split.min_val_cluster_size = 5 # Reduce the minimum required size of each cluster in the validation set"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Custom Dataset"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's generate a custom dataset that we want to resplit. First, let's load the plindex and then create a custom dataset."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 28,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2024-10-25 11:14:50,015 | plinder.core.utils.cpl.download_paths:24 | INFO : runtime succeeded: 0.53s\n",
- "2024-10-25 11:14:51,601 | plinder.core.utils.cpl.download_paths:24 | INFO : runtime succeeded: 0.55s\n"
- ]
- }
- ],
- "source": [
- "cols_of_interest = [\n",
- " \"system_id\",\n",
- " \"entry_pdb_id\",\n",
- " \"ligand_ccd_code\",\n",
- " \"ligand_binding_affinity\",\n",
- " \"ligand_is_proper\",\n",
- " \"ligand_molecular_weight\",\n",
- " \"system_has_binding_affinity\",\n",
- "]\n",
- "custom_df = query_index(\n",
- " columns=cols_of_interest, splits=[\"train\", \"val\", \"test\", \"removed\"] \n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 29,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "(567394, 8)"
- ]
- },
- "execution_count": 29,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "custom_df.shape"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's filter every system out that doesn't have a binding affinity `system_has_binding_affinity`, ions and artifacts `ligand_is_proper` and ligands with a molecular weight of less than 400 g/mol `ligand_molecular_weight`."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 30,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "
"
- ],
- "text/plain": [
- " system_id uniqueness split cluster \\\n",
- "0 10gs__1__1.A_1.B__1.C 10gs__A_B__C_c101993 train c62 \n",
- "1 10gs__1__1.A_1.B__1.E 10gs__A_B__E_c101949 train c62 \n",
- "2 19gs__1__1.A_1.B__1.C_1.D 19gs__A_B__C_D_c147080 train c62 \n",
- "3 19gs__1__1.A_1.B__1.F_1.G 19gs__A_B__F_G_c101954 train c62 \n",
- "\n",
- " cluster_for_val_split system_pass_validation_criteria \\\n",
- "0 c0 True \n",
- "1 c0 True \n",
- "2 c0 False \n",
- "3 c0 False \n",
- "\n",
- " system_pass_statistics_criteria system_proper_num_ligand_chains \\\n",
- "0 True 1 \n",
- "1 True 1 \n",
- "2 True 2 \n",
- "3 True 2 \n",
- "\n",
- " system_proper_num_pocket_residues system_proper_num_interactions \\\n",
- "0 24 15 \n",
- "1 24 13 \n",
- "2 30 12 \n",
- "3 30 14 \n",
- "\n",
- " system_proper_ligand_max_molecular_weight system_has_binding_affinity \\\n",
- "0 473.162057 True \n",
- "1 473.162057 True \n",
- "2 787.630334 True \n",
- "3 787.630334 True \n",
- "\n",
- " system_has_apo_or_pred \n",
- "0 False \n",
- "1 False \n",
- "2 False \n",
- "3 False "
- ]
- },
- "execution_count": 34,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "new_split_df.head(4)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Visualizing the new Split"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Now that we have our first custom split, let's use the `SplitPropertiesPlotter` to visualize the new split."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from plinder.core.split.plot import SplitPropertiesPlotter"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plotter = SplitPropertiesPlotter.from_files(\n",
- " data_dir = Path(plinder_local_storage),\n",
- " split_file = Path(f'{plinder_local_storage}/splits/split_{split_name}.parquet'),\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This will create a folder `split_plots` in the current working directory with the following plots:"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "`split_plots/split_proportions.png`\n",
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "`split_plots/chain_composition.png`\n",
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "`split_plots/domain_classifications.png`\n",
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "`split_plots/ligand_types.png`\n",
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "`split_plots/molecular_descriptors.png`\n",
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "`split_plots/priorities.png`\n",
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "`split_plots/plinder_clusters.png`\n",
- ""
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "MPT_env",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.12.3"
- },
- "mystnb": {
- "execution_mode": "off"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/docs/examples/custom_scoring.ipynb b/docs/examples/custom_scoring.ipynb
new file mode 100644
index 000000000..ffde8f4b0
--- /dev/null
+++ b/docs/examples/custom_scoring.ipynb
@@ -0,0 +1,238 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Search PLINDER with your structures and sequences\n",
+ "\n",
+ "`search()` finds similar proteins, ligand pockets and protein interfaces in PLINDER. Supply an input table for ligand-containing structures, or a FASTA file or structure folder for ligand-free queries."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Input requirements\n",
+ "\n",
+ "Search and evaluation share a table with `input_id`, `structure_path`, and optional `ligand_path` columns. Evaluation adds `reference_id`. See the {ref}`input table reference ` for details.\n",
+ "\n",
+ "Use an assembled PDB/mmCIF receptor with one or more ligand SDFs, or a complete mmCIF containing the ligand coordinates and chemistry. The SDFs must use the receptor's coordinate frame.\n",
+ "\n",
+ "For ligand-free queries, pass a FASTA file, a structure file, or a folder of PDB/mmCIF structures directly."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from pathlib import Path\n",
+ "\n",
+ "import pandas as pd\n",
+ "\n",
+ "from plinder.core import PlinderSystem, PlinderRelease\n",
+ "from plinder.core.scores import (\n",
+ " CustomProteinSearchConfig,\n",
+ " search,\n",
+ ")\n",
+ "\n",
+ "release_path = os.environ.get(\"PLINDER_DATA_DIR\")\n",
+ "release_path = Path(release_path) if release_path else None\n",
+ "input_cif = (\n",
+ " Path(os.environ[\"PLINDER_CUSTOM_CIF\"])\n",
+ " if \"PLINDER_CUSTOM_CIF\" in os.environ\n",
+ " else PlinderSystem(\n",
+ " system_id=\"4agi__1__1.C__1.W\",\n",
+ " release=PlinderRelease(data_dir=release_path),\n",
+ " ).receptor_cif\n",
+ ")\n",
+ "work_dir = Path(\n",
+ " os.environ.get(\"PLINDER_CUSTOM_WORK_DIR\", \"custom_scoring_example\")\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Run a small receptor-only example\n",
+ "\n",
+ "The example rebuilds a PLINDER receptor mmCIF when `PLINDER_CUSTOM_CIF` is not set. `plinder_entry_ids` limits the comparison to receptor and interface proteins from the selected entries; omit it to search all PLINDER proteins.\n",
+ "\n",
+ "`mode=\"pockets\"` searches protein and pocket features. Use `mode=\"interfaces\"` for protein interfaces, `mode=\"ligands\"` for ligand comparisons, or `mode=\"both\"` for both. The default `mode=\"auto\"` selects applicable features."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%%capture\n",
+ "result = search(\n",
+ " input_cif,\n",
+ " output_dir=work_dir,\n",
+ " release=PlinderRelease(data_dir=release_path),\n",
+ " mode=\"pockets\",\n",
+ " backends=(\"mmseqs\",),\n",
+ " plinder_entry_ids=[\"4agi\"],\n",
+ " search_config=CustomProteinSearchConfig(max_seqs=25),\n",
+ " threads=2,\n",
+ " store_aligned_pocket_residues=True,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "protein_scores = pd.read_parquet(result.protein_scores)\n",
+ "residue_pairs = pd.read_parquet(result.aligned_pocket_residues)\n",
+ "{\n",
+ " \"protein_score_rows\": len(protein_scores),\n",
+ " \"aligned_pocket_residue_rows\": len(residue_pairs),\n",
+ " \"ligand_scores_written\": result.ligand_scores is not None,\n",
+ " \"interface_scores_written\": result.interface_scores is not None,\n",
+ "}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Protein scoring is oriented from each PLINDER receptor and ligand pocket to a custom protein chain. `pocket_fident` is therefore the percentage of PLINDER pocket residues that align to identical residues in the custom chain."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "pocket_scores = protein_scores.loc[\n",
+ " protein_scores[\"metric\"].astype(str).eq(\"pocket_fident\"),\n",
+ " [\n",
+ " \"query_system\",\n",
+ " \"query_ligand_id\",\n",
+ " \"target_system\",\n",
+ " \"protein_mapping\",\n",
+ " \"source\",\n",
+ " \"similarity\",\n",
+ " ],\n",
+ "].head()\n",
+ "pocket_scores"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "When aligned pocket residues are requested, each row records a PLINDER pocket residue and the custom residue selected by the chain mapping and search source used for the reported score."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "residue_pairs[[\n",
+ " \"plinder_system_id\",\n",
+ " \"plinder_chain_instance\",\n",
+ " \"plinder_residue_number\",\n",
+ " \"custom_structure_id\",\n",
+ " \"custom_chain_asym_id\",\n",
+ " \"custom_residue_number\",\n",
+ " \"residue_identical\",\n",
+ "]].head()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Search ligand poses\n",
+ "\n",
+ "Each SDF supplies its own ligand chemistry and coordinates. Put the receptor path and ligand path in the same input row, and repeat the input ID for additional ligands."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def search_ligand_model(receptor_path, ligand_path):\n",
+ " inputs = pd.DataFrame([{\n",
+ " \"input_id\": \"model_1\",\n",
+ " \"structure_path\": str(receptor_path),\n",
+ " \"ligand_path\": str(ligand_path),\n",
+ " }])\n",
+ " return search(\n",
+ " inputs, output_dir=\"ligand_search\", mode=\"ligands\",\n",
+ " )\n",
+ "\n",
+ "\n",
+ "# Examples:\n",
+ "# search_ligand_model(\"receptor.pdb\", \"pose.sdf\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Compare protein sequences\n",
+ "\n",
+ "Protein sequences can be searched without coordinates. This MMseqs route writes protein scores, ligand-pocket links, the best link per input sequence, and optionally the aligned pocket residues."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def search_sequences(fasta_path):\n",
+ " return search(\n",
+ " Path(fasta_path),\n",
+ " output_dir=Path(fasta_path).with_suffix(\"\") / \"plinder_search\",\n",
+ " threads=8,\n",
+ " store_aligned_pocket_residues=True,\n",
+ " )"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "For several ligand-free coordinate files, use `search(\"models/\", output_dir=\"search_results\")`. Search uses the first coordinate model as the supplied assembly."
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.12.13"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/docs/examples/evaluation.ipynb b/docs/examples/evaluation.ipynb
new file mode 100644
index 000000000..1785a3c92
--- /dev/null
+++ b/docs/examples/evaluation.ipynb
@@ -0,0 +1,306 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "evaluation-00",
+ "metadata": {},
+ "source": [
+ "# Evaluate ligand poses and protein interfaces\n",
+ "\n",
+ "Compare predictions with PLINDER references using OpenStructure, and check ligand plausibility with PoseBusters.\n",
+ "\n",
+ "Evaluate two Boltz predictions for the 8c3u proteinโligand complex from [Runs N' Poses](https://github.com/plinder-org/runs-n-poses) and a GeoDock prediction for the 2e31 protein interface from [PINDER's evaluation tutorial](https://github.com/pinder-org/pinder/blob/main/examples/pinder-eval.ipynb)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "evaluation-01",
+ "metadata": {},
+ "source": [
+ "## Set up\n",
+ "\n",
+ "Install OpenStructure 2.12.0 or newer and the evaluation extra in your notebook environment:\n",
+ "\n",
+ "```bash\n",
+ "conda install -c conda-forge -c bioconda 'openstructure>=2.12.0'\n",
+ "pip install 'plinder[eval]'\n",
+ "```\n",
+ "\n",
+ "The `ost` command must be on your `PATH`. Set `PLINDER_DATA_DIR` to use a local release; otherwise PLINDER uses the configured release. The [evaluation reference](../evaluation.md) describes the options and output files."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "evaluation-02",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import tempfile\n",
+ "from pathlib import Path\n",
+ "from urllib.request import urlretrieve\n",
+ "\n",
+ "import yaml\n",
+ "import pandas as pd\n",
+ "\n",
+ "from plinder.core import PlinderRelease\n",
+ "from plinder.eval import evaluate_predictions\n",
+ "\n",
+ "data_dir = os.environ.get(\"PLINDER_DATA_DIR\")\n",
+ "release = PlinderRelease(data_dir=Path(data_dir)) if data_dir else PlinderRelease()\n",
+ "work_dir = Path(\n",
+ " os.environ.get(\"PLINDER_EVAL_WORK_DIR\")\n",
+ " or tempfile.mkdtemp(prefix=\"plinder-evaluation-\")\n",
+ ").resolve()\n",
+ "predictions = work_dir / \"predictions\"\n",
+ "work_dir"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "evaluation-03",
+ "metadata": {},
+ "source": [
+ "## Choose prediction files\n",
+ "\n",
+ "Search and evaluation share an input table with `input_id`, `structure_path`, and optional `ligand_path`. Evaluation adds a `reference_id`: a ligand-system ID, an interface ID, or a PDB ID. The {ref}`evaluation reference ` describes the columns and folder alternative.\n",
+ "\n",
+ "```text\n",
+ "predictions/\n",
+ "โโโ /\n",
+ "โ โโโ boltz_seed_1372115236.cif\n",
+ "โ โโโ boltz_seed_555476360.cif\n",
+ "โโโ /\n",
+ " โโโ geodock_model_1.pdb\n",
+ "```\n",
+ "\n",
+ "For your own models, use the same folder layout and skip this example-data setup. Interface evaluation accepts PDB or mmCIF files. For ligand evaluation, pair a receptor `model.pdb` or `model.cif` with `model.sdf`, or a `model.ligands/` folder containing one SDF per ligand. Each prediction then carries its own ligand chemistry and coordinates.\n",
+ "\n",
+ "Complete-mmCIF predictions are also supported, as shown with the two Boltz models below. Their input YAML provides the ligand SMILES."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "evaluation-04",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "system_id = \"8c3u__1__1.A__1.C\"\n",
+ "revision = \"78bfe19e15b086e39de4e03f30142e0dcb38beb0\"\n",
+ "example_url = f\"https://raw.githubusercontent.com/plinder-org/runs-n-poses/{revision}/examples\"\n",
+ "ligand_folder = predictions / system_id\n",
+ "ligand_folder.mkdir(parents=True, exist_ok=True)\n",
+ "\n",
+ "for seed in (1372115236, 555476360):\n",
+ " model = ligand_folder / f\"boltz_seed_{seed}.cif\"\n",
+ " if not model.is_file():\n",
+ " urlretrieve(\n",
+ " f\"{example_url}/outputs/boltz/{system_id}/{seed}/\"\n",
+ " \"boltz_results_input/predictions/input/input_model_0.cif\",\n",
+ " model,\n",
+ " )\n",
+ "\n",
+ "input_yaml = work_dir / \"boltz_input.yaml\"\n",
+ "if not input_yaml.is_file():\n",
+ " urlretrieve(f\"{example_url}/inputs/boltz/{system_id}/input.yaml\", input_yaml)\n",
+ "boltz_input = yaml.safe_load(input_yaml.read_text())\n",
+ "ligand_smiles = next(\n",
+ " item[\"ligand\"][\"smiles\"] for item in boltz_input[\"sequences\"] if \"ligand\" in item\n",
+ ")\n",
+ "\n",
+ "interface_id = \"2e31__1__1.A--1.B\"\n",
+ "interface_folder = predictions / interface_id\n",
+ "interface_folder.mkdir(parents=True, exist_ok=True)\n",
+ "\n",
+ "pinder_revision = \"20487ac403516f453d8be1b0bdc07a9f7a77d9df\"\n",
+ "pinder_id = \"2e31__A1_Q80UW2--2e31__B1_P63208\"\n",
+ "geodock_pdb = interface_folder / \"geodock_model_1.pdb\"\n",
+ "if not geodock_pdb.is_file():\n",
+ " urlretrieve(\n",
+ " f\"https://raw.githubusercontent.com/pinder-org/pinder/{pinder_revision}/\"\n",
+ " f\"tests/test_data/method_eval/geodock/{pinder_id}/holo_decoys/model_1.pdb\",\n",
+ " geodock_pdb,\n",
+ " )\n",
+ "\n",
+ "input_table = pd.DataFrame([\n",
+ " {\n",
+ " \"input_id\": path.stem,\n",
+ " \"structure_path\": str(path.resolve()),\n",
+ " \"reference_id\": path.parent.name,\n",
+ " }\n",
+ " for path in sorted(predictions.glob(\"*/*\")) if path.is_file()\n",
+ "])\n",
+ "input_table"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "evaluation-05",
+ "metadata": {},
+ "source": [
+ "## Evaluate the predictions\n",
+ "\n",
+ "One call evaluates both kinds of prediction. Choose `mode=\"ligands\"` or `mode=\"interfaces\"` for just one kind. `num_workers` limits the number of predictions processed at once.\n",
+ "\n",
+ "By default, ligand results cover proper **reference** ligands. Set `include_all_ligands=True` to include reference ions and artifacts too.\n",
+ "\n",
+ "The two Boltz predictions share the same ligand, so pass its SMILES as `ligand_smiles={\"LIG\": ligand_smiles}`. A SMILES must follow the CIF heavy-atom order. With complete-mmCIF inputs, `ligand_ccd_codes` supplies CCD templates and `ligand_chains=[\"B\"]` selects a peptide ligand by its label asym ID. For receptor + SDF inputs, the SDF files supply the chemistry."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "evaluation-06",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "results = evaluate_predictions(\n",
+ " input_table,\n",
+ " output_dir=work_dir / \"results\",\n",
+ " release=release,\n",
+ " mode=\"both\",\n",
+ " num_workers=2,\n",
+ " ligand_smiles={\"LIG\": ligand_smiles},\n",
+ ")\n",
+ "\n",
+ "display(results[\"failures\"])\n",
+ "assert results[\"failures\"].empty, \"Inspect the errors and tool logs before interpreting results.\""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "evaluation-07",
+ "metadata": {},
+ "source": [
+ "## Read ligand results\n",
+ "\n",
+ "Each row represents one reference ligand and one prediction. `rmsd` is the binding-site-superposed, symmetry-corrected ligand RMSD; `bb_rmsd` describes the backbone fit, `lddt_lp` the local binding-site structure, and `lddt_pli` the proteinโligand contacts. Lower RMSD is better; lDDT values range from zero to one.\n",
+ "\n",
+ "`status=\"success\"` means the comparison completed. Both Boltz examples here have a large ligand RMSD. A missing or unassigned reference ligand has a row with unavailable metrics and an unassigned reason."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "evaluation-08",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ligands = results[\"ligands\"]\n",
+ "ligands[\n",
+ " [\n",
+ " \"prediction\", \"ligand_id\", \"status\",\n",
+ " \"rmsd\", \"bb_rmsd\", \"lddt_lp\", \"lddt_pli\",\n",
+ " \"rmsd_unassigned\", \"lddt_pli_unassigned\",\n",
+ " ]\n",
+ "]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "evaluation-09",
+ "metadata": {},
+ "source": [
+ "## Attach PoseBusters checks\n",
+ "\n",
+ "PoseBusters checks all candidate predicted ligands. To attach those checks to a reference-ligand result, use the predicted ligand selected by the metric you are analysing. RMSD and lDDT-PLI can choose different assignments.\n",
+ "\n",
+ "Below, the join follows `rmsd_model_ligand`. For lDDT-PLI, use `lddt_pli_model_ligand` instead. PoseBusters uses each prediction's own receptor coordinates. Failed checks appear as `False`; PoseBusters fields for missing ligands are empty."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "evaluation-10",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "checks = results[\"posebusters\"][\n",
+ " [\n",
+ " \"prediction\", \"model_ligand\", \"sanitization\",\n",
+ " \"internal_steric_clash\", \"minimum_distance_to_protein\",\n",
+ " ]\n",
+ "]\n",
+ "ligands_with_checks = ligands.merge(\n",
+ " checks,\n",
+ " left_on=[\"prediction\", \"rmsd_model_ligand\"],\n",
+ " right_on=[\"prediction\", \"model_ligand\"],\n",
+ " how=\"left\",\n",
+ " validate=\"many_to_one\",\n",
+ ")\n",
+ "ligands_with_checks[\n",
+ " [\n",
+ " \"prediction\", \"ligand_id\", \"rmsd_model_ligand\", \"rmsd\",\n",
+ " \"sanitization\", \"internal_steric_clash\", \"minimum_distance_to_protein\",\n",
+ " ]\n",
+ "]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "evaluation-11",
+ "metadata": {},
+ "source": [
+ "## Read interface results\n",
+ "\n",
+ "OST maps the GeoDock model's chains `R` and `L` to reference chains `1.A` and `1.B`.\n",
+ "\n",
+ "`ilddt` describes local agreement at the interface; QS-score describes assembly agreement. Use `dockq_ave_full` or `dockq_wave_full` when comparing predictions that may have missing chains: these include the penalty for unmapped reference interfaces."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "evaluation-12",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "results[\"interfaces\"][\n",
+ " [\n",
+ " \"prediction\", \"system_id\", \"status\", \"lddt\", \"ilddt\",\n",
+ " \"qs_global\", \"qs_best\", \"dockq_ave_full\", \"dockq_wave_full\",\n",
+ " ]\n",
+ "]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "evaluation-13",
+ "metadata": {},
+ "source": [
+ "Access reference-ligand assignments in `results[\"ligands\"]` using `rmsd_model_ligand` and `lddt_pli_model_ligand`, with reasons for unmatched ligands in `rmsd_unassigned` and `lddt_pli_unassigned`."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "evaluation-15",
+ "metadata": {},
+ "source": [
+ "Reload saved tables with pandas, for example `pd.read_parquet(work_dir / \"results\" / \"ligands.parquet\")`."
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.12.13"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/examples/index.md b/docs/examples/index.md
index e77931f06..9555b3e2b 100644
--- a/docs/examples/index.md
+++ b/docs/examples/index.md
@@ -1,12 +1,59 @@
-# Examples
+# Guides
-The following examples show advanced applications of *PLINDER* to real world problems.
-Although they address a specific question, they can be easily adapted to use them for
-your own purposes.
+The notebooks are arranged by task so that release discovery, structure work,
+and similarity analysis can be learned independently.
-:::{toctree}
+## Data access
+
+Start here when working directly with the release tables and files.
+
+```{toctree}
+:maxdepth: 1
+
+2_query_filter_index
+```
+
+## Structures
+
+Reconstruct ligand systems and linked apo chains, then work with atom arrays,
+masks, sequences, and ligand atom mappings.
+
+```{toctree}
+:maxdepth: 1
+
+3_access_system_files
+protein_interfaces
+4_align_mask_crop
+```
+
+## Similarity and search
+
+Inspect similarity scores and representative covers, or compare
+custom structures and protein sequences with PLINDER.
+
+```{toctree}
+:maxdepth: 1
+
+similarity_and_representatives
+custom_scoring
+```
+
+## Evaluation
+
+Compare predicted ligand poses and protein interfaces with known references.
+
+```{toctree}
+:maxdepth: 1
+
+evaluation
+```
+
+## Offline access
+
+Download a local copy when you need to work without internet access.
+
+```{toctree}
:maxdepth: 1
-:glob:
-./*
-:::
+1_download
+```
diff --git a/docs/examples/protein_interfaces.ipynb b/docs/examples/protein_interfaces.ipynb
new file mode 100644
index 000000000..efaf6c37e
--- /dev/null
+++ b/docs/examples/protein_interfaces.ipynb
@@ -0,0 +1,129 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Work with protein interfaces\n",
+ "\n",
+ "Start from a selected interface ID and rebuild its two-chain coordinate view. Use [Query the release tables](2_query_filter_index.ipynb) to select interfaces and {ref}`Protein interfaces ` for the column definitions."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import biotite.structure as struc\n",
+ "import pandas as pd\n",
+ "\n",
+ "from plinder.core import PlinderInterface"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Rebuild one interface\n",
+ "\n",
+ "`PlinderInterface` expands the two selected assembly-chain instances from the source mmCIF revision recorded by the release."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "interface = PlinderInterface(system_id=\"7cm8__1__1.A--2.A\")\n",
+ "interface"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "pd.DataFrame(\n",
+ " {\n",
+ " \"chain\": interface.chains,\n",
+ " \"full_sequence_length\": [\n",
+ " len(interface.sequences[chain]) for chain in interface.chains\n",
+ " ],\n",
+ " \"resolved_atom_count\": [\n",
+ " len(interface.chain_structures[chain]) for chain in interface.chains\n",
+ " ],\n",
+ " }\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "`sequences` contains the full deposited polymer sequences; coordinate arrays contain only resolved atoms."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Interface residues and coordinate views\n",
+ "\n",
+ "The residue masks are defined over the complete two-chain `atom_array`. Their keys match the assembly-chain IDs in `interface_annotations`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "summary = []\n",
+ "for chain, mask in interface.interface_residue_masks.items():\n",
+ " atoms = interface.atom_array[mask]\n",
+ " summary.append(\n",
+ " {\n",
+ " \"chain\": chain,\n",
+ " \"interface_residues\": struc.get_residue_count(atoms),\n",
+ " \"interface_atoms\": len(atoms),\n",
+ " }\n",
+ " )\n",
+ "pd.DataFrame(summary)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(f\"Two-chain atoms: {len(interface.atom_array):,}\")\n",
+ "print(f\"Interface atoms: {len(interface.interface_structure):,}\")\n",
+ "print(f\"Reconstructed mmCIF: {interface.interface_cif}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "`interface_cif` is a `pathlib.Path`; `atom_array`, the values of `chain_structures`, and `interface_structure` are Biotite `AtomArray` objects. The written mmCIF is self-contained and contains only the selected interface chains."
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "name": "python",
+ "version": "3.12"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/docs/examples/similarity_and_representatives.ipynb b/docs/examples/similarity_and_representatives.ipynb
new file mode 100644
index 000000000..b52decf4c
--- /dev/null
+++ b/docs/examples/similarity_and_representatives.ipynb
@@ -0,0 +1,207 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Similarity scores and representative covers\n",
+ "\n",
+ "Compare ligands and protein interfaces, explore similarity scores, and find representative clusters. {ref}`Similarity scores ` defines the metrics and files."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "\n",
+ "from plinder.core import PlinderRelease, query_table\n",
+ "from plinder.core.scores import (\n",
+ " reconstruct_interface_similarity_scores,\n",
+ " reconstruct_similarity_scores,\n",
+ ")\n",
+ "\n",
+ "release = PlinderRelease()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ligand_system_id = \"4agi__1__1.C__1.R\"\n",
+ "ligand_id = \"4agi__1__1.R\"\n",
+ "interface_id = \"7cm8__1__1.A--2.A\""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Compare ligand similarities\n",
+ "\n",
+ "`reconstruct_similarity_scores()` reads the files needed for the requested query and target IDs. This example uses a one-pair self-comparison to keep execution small."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ligand_scores = reconstruct_similarity_scores(\n",
+ " query_system_ids=[ligand_system_id],\n",
+ " target_system_ids=[ligand_system_id],\n",
+ " query_ligand_ids=[ligand_id],\n",
+ " target_ligand_ids=[ligand_id],\n",
+ ")\n",
+ "ligand_scores"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "For larger neighborhoods, read selected columns and rows from the complete ligand score table."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def read_ligand_neighborhood(system_id, ligand_id):\n",
+ " return pd.read_parquet(\n",
+ " release.fetch(\"ligand_similarity_scores\"),\n",
+ " columns=[\n",
+ " \"query_system\",\n",
+ " \"query_ligand_id\",\n",
+ " \"target_system\",\n",
+ " \"target_ligand_id\",\n",
+ " \"pocket_qcov\",\n",
+ " \"pocket_fident_qcov\",\n",
+ " \"pli_qcov\",\n",
+ " \"sucos_shape\",\n",
+ " ],\n",
+ " filters=[\n",
+ " (\"query_system\", \"==\", system_id),\n",
+ " (\"query_ligand_id\", \"==\", ligand_id),\n",
+ " ],\n",
+ " )"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Compare protein-interface similarities\n",
+ "\n",
+ "The interface API likewise accepts selected query and target IDs."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "interface_scores = reconstruct_interface_similarity_scores(\n",
+ " query_interface_ids=[interface_id],\n",
+ " target_interface_ids=[interface_id],\n",
+ ")\n",
+ "interface_scores"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Representative covers\n",
+ "\n",
+ "Request cover columns through `query_table()` just like annotation columns. {ref}`Representative covers ` describes their construction and long-form files."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "pocket_cover = \"pocket_qcov__70__ligand__directed_set_cover\"\n",
+ "ligand_cover = query_table(\n",
+ " columns=[\n",
+ " \"system_id\",\n",
+ " \"ligand_id\",\n",
+ " pocket_cover,\n",
+ " f\"{pocket_cover}__is_centroid\",\n",
+ " ],\n",
+ " filters=[(\"ligand_id\", \"==\", ligand_id)],\n",
+ ")\n",
+ "ligand_cover.T"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "interface_cover = query_table(\n",
+ " \"interface_annotations\",\n",
+ " columns=[\n",
+ " \"system_id\",\n",
+ " \"interface_qcov__70__directed_set_cover\",\n",
+ " ],\n",
+ " filters=[(\"system_id\", \"==\", interface_id)],\n",
+ ")\n",
+ "interface_cover.T"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Matched molecular pairs\n",
+ "\n",
+ "Use `ligand_mmp_pairs` to look up transformations involving the selected ligand chemistry."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "smiles_id = query_table(\n",
+ " columns=[\"ligand_smiles_id\"],\n",
+ " filters=[(\"ligand_id\", \"==\", ligand_id)],\n",
+ ").iloc[0, 0]\n",
+ "mmp_neighbors = query_table(\n",
+ " \"ligand_mmp_pairs\",\n",
+ " filters=[[\n",
+ " (\"ligand_smiles_id_1\", \"==\", smiles_id),\n",
+ " (\"ligand_smiles_id_2\", \"==\", smiles_id),\n",
+ " ]],\n",
+ ")\n",
+ "mmp_neighbors.head()"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "name": "python",
+ "version": "3.12"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/docs/index.md b/docs/index.md
index 18df30dce..ee8714b43 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -5,82 +5,86 @@ html_theme.sidebar_secondary.remove: true
# PLINDER documentation
-
{w=40em align=center}
-**PLINDER**, short for **p**rotein **l**igand **in**teractions **d**ataset and
-**e**valuation **r**esource, is a comprehensive, annotated, high quality dataset and
-resource for training and evaluation of protein-ligand docking algorithms:
+**PLINDER** is the **Protein & Ligand INteraction Dataset and Evaluation
+Resource**: a comprehensive, annotated, high-quality resource for training and
+evaluating protein-ligand and protein-protein structure models.
-- \> 400k PLI systems across > 11k SCOP domains and > 50k unique small molecules
-- 500+ annotations for each system, including protein and ligand properties, quality,
- matched molecular series and more
+- 611,930 proteinโligand systems, 803,190 proper ligands, and 3,811,623 proteinโprotein interfaces
+- Ligand and protein-interface annotations plus compact entry, chain, and representative tables
- Automated curation pipeline to keep up with the PDB
-- 14 PLI metrics and over 20 billion similarity scores
-- Unbound \(_apo_\) and _predicted_ Alphafold2 structures linked to _holo_ systems
-- _train-val-test_ splits and ability to tune splitting based on the learning task
-- Robust evaluation harness to simplify and standard performance comparison between models.
-
+- Reusable ligand, pocket, and protein-interface similarities and representative assignments
+- Ranked deposited apo protein chains linked to holo ligands and protein-interface sides
+- Python APIs for release queries, coordinate reconstruction, and custom scoring
-::::::{grid} 1 1 2 2
+::::::{grid} 1 2 3 3
-:::::{grid-item-card}
+:::::{grid-item-card} Getting started
:link: tutorial/dataset
:link-type: doc
+:class-card: home-card
-::::{grid} 2
+
-:::{grid-item}
-:columns: 3
-:class: main-button
-
-:::
+Install PLINDER, select a release, and continue to the runnable guides.
+:::::
-:::{grid-item}
-:columns: 9
-**Dataset access**
+:::::{grid-item-card} Data access
+:link: examples/2_query_filter_index
+:link-type: doc
+:class-card: home-card
-Access the PLI systems and their annotations directly via the files
-:::
-::::
+
+
+Query columns across the ligand, interface,
+entry, chain, and representative tables.
:::::
+:::::{grid-item-card} Structures
+:link: examples/3_access_system_files
+:link-type: doc
+:class-card: home-card
+
+
+
+Work with ligand systems, linked apo chains, protein interfaces, atom masks,
+and self-contained mmCIF files.
+:::::
-:::::{grid-item-card}
-:link: tutorial/api
+:::::{grid-item-card} Similarity and scoring
+:link: examples/index
:link-type: doc
+:class-card: home-card
-::::{grid} 2
+
-:::{grid-item}
-:columns: 3
-:class: main-button
-
-:::
+Use pairwise scores and representative covers, or compare custom
+mmCIF and FASTA inputs with PLINDER.
+:::::
-:::{grid-item}
-:columns: 9
-**Python API**
+:::::{grid-item-card} Data reference
+:link: dataset
+:link-type: doc
+:class-card: home-card
-Use the dedicated Python package to explore the data
-:::
-::::
+
+
+Inspect release files, table relationships, column definitions, and
+coordinate provenance.
:::::
::::::
-% TODO: re-add `contribution/index`
-
:::{toctree}
:maxdepth: 1
:hidden:
tutorial/index
+examples/index
dataset
-api/index
evaluation
-examples/index
+api/index
contribution/index
-migration/r2
citation
:::
diff --git a/docs/migration/r2.md b/docs/migration/r2.md
deleted file mode 100644
index bcfad88de..000000000
--- a/docs/migration/r2.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# Static release downloads from R2
-
-Public dataset reads for `2024-06/v2` use `https://plinderdata.org`. No S3 keys
-or Google credentials are required. Other online release/bucket combinations
-are rejected. `PLINDER_MIRROR_URL` may select another HTTP(S) bucket root with
-the same release layout and manifest. The local cache layout is unchanged.
-
-## Download and cache behavior
-
-The consumer uses cloudpathlib HTTP paths. A release-relative `manifest.jsonl.gz`
-provides listing, sizes and base64 MD5 checksums. Directory traversal and file
-transfers use cloudpathlib; the manifest is cached in-process.
-
-Transfers stream into temporary files, verify size and MD5, and atomically
-replace the destination. Interrupted transfers retry from the start, with up to
-three attempts. They do not resume at a byte offset. Failed validation preserves
-an existing destination. Parallel batches use eight workers and propagate errors.
-
-Cached files with the expected size are reused without rehashing. Missing and
-size-mismatched files are fetched again. Same-size local corruption requires a
-forced refresh (`data.force_update=true`) or deletion of the affected file.
-Refreshing a ZIP clears its extraction marker. `PLINDER_OFFLINE` bypasses all
-network access when set to any nonempty value; unset it to return online.
-
-Google libraries are optional for consumers and available through `plinder[data]`.
-The docs extra still declares Google storage because `docs/tablegen.py` uses it
-for annotation-table generation. That docs download has not yet moved to R2.
-Ingestion and generation compatibility are outside this static-release change.
-
-## Building the static manifest
-
-```bash
-python scripts/build_r2_manifest.py INVENTORY_DIR OUTPUT.jsonl.gz
-```
-
-`INVENTORY_DIR/manifest-files.json` lists shard paths and SHA256 values. Each
-compressed JSONL shard contains source rows with `name`, `size` and `md5Hash`.
-The builder verifies shard checksums, rejects duplicate/invalid keys and writes
-sorted release-relative records for `2024-06/v2`. It performs no cloud I/O.
-
-The existing public manifest lists 5,891 objects totaling 219,677,619,278 bytes.
-Its 207,150 published bytes were checked on 2026-09-14 against SHA256
-`9b520375910b2e9bc7d258b0186e21488dc2236991976683a4bfa0ccbaa04e1b`.
-The full download validation below also checked every object's size and MD5.
-
-## Validation
-
-```bash
-python -m pytest --noconftest tests/core/test_r2.py tests/core/test_core_config.py tests/core/test_atoms.py::test_default_sequence_alignment -q -o addopts=''
-```
-
-30 focused tests passed with Python 3.12.13, cloudpathlib 0.25.0 and NumPy 2.5.3.
-They cover directory/archive access, checksums, atomic replacement, cache reuse,
-forced refresh, path containment, offline behavior, interrupted-transfer retry
-and integer gap penalties required by Biotite's sequence alignment API.
-`--noconftest` excludes repository-wide OpenStructure-dependent fixtures. These
-results do not represent full project CI or evaluation coverage.
-
-On 2026-09-14, the revised implementation downloaded the complete release with
-`plinder_download --release 2024-06 --iteration v2 --yes`: all 5,891 objects
-(219,677,619,278 bytes) passed size and MD5 checks. All 1,060 system archives and
-both linked-structure archives extracted successfully. Their contents total
-567,902,199,349 bytes, so allow roughly 788 GB plus filesystem overhead for the
-downloaded files and extracted contents together.
-
-A deliberate process interruption preserved 1,011 completed files; restarting
-the CLI reused them without changing their timestamps. A final fully cached CLI
-run exited successfully in 6.44 seconds, downloaded no dataset files and left all
-5,891 files unchanged. No unplanned transfer errors or retries occurred during
-the full download; interrupted-transfer retry was exercised by the HTTP test
-server. A separate offline reuse check passed with networking blocked.
-
-The API tutorial, index-query notebook and system-access notebook executed all
-63 code cells against the local release. A `PlinderSystem` structure smoke test
-loaded the receptor and ligand for `4agi__1__1.C__1.W` successfully.
-
-Repository-wide Ruff checks, strict typing of all 91 source files and the full
-Sphinx documentation build with warnings treated as errors passed locally.
-The manifest builder was checked with synthetic inventories for sorting,
-checksum/duplicate rejection and preservation of an existing output on those
-validation failures. These checks do not represent full evaluation coverage.
-
-No dataset copy, permission change or public GCS retirement is part of these
-commits. Existing installed clients still use GCS until upgraded.
diff --git a/docs/static/plinder.css b/docs/static/plinder.css
index a72cf5219..4a4bce988 100644
--- a/docs/static/plinder.css
+++ b/docs/static/plinder.css
@@ -34,15 +34,34 @@ html[data-theme="dark"] {
padding-bottom: 30px;
}
-/* The tutorial buttons on the home page */
-.main-button {
- padding-right: 20px;
- align-self: center;
+/* Task cards on the home page */
+.home-card {
+ position: relative;
+ border-top: 3px solid transparent;
+ transition: transform 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
}
-/* The tutorial button icons on the home page */
-svg.main-button-icon path {
- fill: var(--pst-color-primary);
+.home-card:hover {
+ border-top-color: var(--pst-color-primary);
+ box-shadow: 0 0.5rem 1.2rem rgb(0 0 0 / 12%);
+ transform: translateY(-2px);
+}
+
+.home-card .sd-card-title {
+ padding-right: 2.75rem;
+}
+
+.home-card-icon {
+ color: var(--pst-color-primary);
+ pointer-events: none;
+ position: absolute;
+ right: 1rem;
+ top: 1rem;
+ width: 2rem;
+}
+
+.home-card-icon i {
+ font-size: 1.8rem;
}
/* The cross/check marks in the annotation table*/
diff --git a/docs/tablegen.py b/docs/tablegen.py
index 33dad0144..4387ac1b6 100644
--- a/docs/tablegen.py
+++ b/docs/tablegen.py
@@ -1,106 +1,20 @@
from __future__ import annotations
-from glob import glob
+from html import escape
from pathlib import Path
-import duckdb
-import numpy as np
import pandas as pd
-from google.cloud import storage
from itables import to_html_datatable
-from sphinx.util import logging
ROWS_PER_PAGE = 10
-# The columns that should be displayed first in the table
-PRIMARY_COLUMNS = [
- "system_id",
-]
-CACHE_FILE = "index.parquet"
+DESCRIPTION_COLUMNS = ["Name", "Type", "Description"]
-CHECKMARK = ''
-CROSSMARK = ''
-
-logger = logging.getLogger(__name__)
-
-
-def generate_table(description_dir: Path, output_html_path: Path) -> None:
- """
- Generate a HTML table containing the column descriptions for
- `annotation_table.parquet`.
-
- The table is generated from TSV files.
-
- Parameters
- ----------
- description_dir : Path
- Directory containing the TSV files with the column descriptions.
- output_html_path : Path
- Path to the output HTML file.
- If the file already exists, it this function does nothing.
-
- Notes
- -----
- The functions caches the output file:
- If the file already exists, it does nothing.
- This skips the time consuming part of downloading and reading the annotation table.
- """
- column_descriptions = []
- for description_file in glob(str(description_dir / "*.tsv")):
- with open(description_file, "r") as f:
- column_descriptions_in_file = pd.read_csv(f, sep="\t")
- column_descriptions.append(column_descriptions_in_file)
- column_descriptions = pd.concat(column_descriptions, ignore_index=True)
-# # TODO: Remove as soon as wrong column names are fixed
-# column_descriptions = column_descriptions[
-# ~column_descriptions["Name"].str.contains("Kinase")
-# ]
-
- annotation_table = _get_annotation_table("2024-06", "v2", Path(CACHE_FILE))
-
- is_mandatory = np.zeros(column_descriptions.shape[0], dtype=bool)
- examples = [None] * column_descriptions.shape[0]
- for i, (column_name, data_type) in enumerate(
- zip(column_descriptions["Name"], column_descriptions["Type"])
- ):
- try:
- column = annotation_table[column_name]
- except KeyError:
- logger.warning(
- f"Column '{column_name}' is in column descriptions, "
- "but not found in annotation table."
- )
- continue
- is_value = _is_value(column, data_type)
- # Columns are considered mandatory if they contain a value in all rows
- is_mandatory[i] = is_value.all()
- # Get the first non-empty value as an example
- # whitelist ligand_rdkit_validation because we're only sampling the first 1000 rows
- if not is_value.any():
- if column_name in ["ligand_rdkit_validation"]:
- examples[i] = repr(None)
- else:
- logger.warning(f"Column '{column_name}' has no values.")
- examples[i] = repr(None)
- else:
- examples[i] = repr(column[is_value].iloc[0])
- column_descriptions["Mandatory"] = is_mandatory
- column_descriptions["Example"] = examples
-
- # Put important columns first
- column_descriptions = _prepend(column_descriptions, PRIMARY_COLUMNS)
-
- column_descriptions["Name"] = _to_monospace(column_descriptions["Name"])
- column_descriptions["Type"] = _to_monospace(column_descriptions["Type"])
- column_descriptions["Mandatory"] = _to_marks(column_descriptions["Mandatory"])
- column_descriptions["Example"] = _to_example(_to_monospace(
- column_descriptions["Example"])
- ) # fmt: skip
-
- html = to_html_datatable(
- column_descriptions,
+def _render_description_table(frame: pd.DataFrame) -> str:
+ """Render one release table's column descriptions."""
+ return to_html_datatable(
+ frame,
display_logo_when_loading=False,
- # Only one value, as the user can't change the number of rows
lengthMenu=[ROWS_PER_PAGE],
layout={
"topStart": "search",
@@ -108,170 +22,43 @@ def generate_table(description_dir: Path, output_html_path: Path) -> None:
"bottomStart": None,
"bottomEnd": None,
},
- # Use 'table' class from pydata theme to inherit the style of the usual tables
classes="table display compact",
- # Without setting width to 100%,
- # the table would get a small horizontal scrollbar
style="width:100%;overflow-wrap:break-word",
autoWidth=False,
)
- with open(output_html_path, "w") as f:
- # Inline HTML in Markdown does not allow empty lines
- f.write(_remove_empty_lines(html))
-
-
-def _remove_empty_lines(string: str) -> str:
- """
- Remove empty lines from a multiline string.
-
- Parameters
- ----------
- html : str
- HTML string.
-
- Returns
- -------
- str
- HTML string without empty lines.
- """
- return "\n".join(line for line in string.splitlines() if len(line.strip()) != 0)
-
-
-def _to_monospace(values: pd.Series) -> pd.Series:
- """
- Convert a series of strings to monospace.
-
- Parameters
- ----------
- values : pd.Series
- Series of strings.
-
- Returns
- -------
- pd.Series
- Series of strings in monospace.
- """
- return values.map(lambda x: f"{x}")
-def _to_marks(values: pd.Series) -> pd.Series:
- """
- Convert a series of booleans to check/cross marks.
-
- Parameters
- ----------
- values : pd.Series
- Series of booleans.
-
- Returns
- -------
- pd.Series
- Series of check/cross marks.
- """
- return values.map(lambda x: CHECKMARK if x else CROSSMARK)
-
-
-def _to_example(values: pd.Series) -> pd.Series:
- """
- Put the given series of text into a `div` with the `.example` class.
-
- Parameters
- ----------
- values : pd.Series
- Series of strings.
-
- Returns
- -------
- pd.Series
- Series of strings in a `div` with the `.example` class.
- """
- return values.map(lambda x: f'
{x}
')
-
-
-def _get_annotation_table(
- release: str, iteration: str, cache_path: Path
-) -> pd.DataFrame:
- """
- Read the annotation table from the Parquet file.
-
- Parameters
- ----------
- release : str
- Time stamp of the last RCSB sync.
- iteration : str
- Iterative development within a release, i.e. the version
- cache_path : str
-
- Returns
- -------
- pd.DataFrame
- Annotation table.
- """
- if not cache_path.exists():
- storage.Client.create_anonymous_client().get_bucket("plinder").blob(
- blob_name=f"{release}/{iteration}/index/annotation_table.parquet"
- ).download_to_filename(cache_path)
- # only load the first 1000 rows to avoid memory issues
- df = duckdb.sql(f"select * from read_parquet('{cache_path.as_posix()}') limit 1000;").to_df()
- return df
-
-
-def _is_value(column: pd.Series, data_type) -> pd.Series:
- """
- Get a mask for non-empty, non-NaN values.
-
- Parameters
- ----------
- column : pd.Series
- Column of the annotation table to check.
- data_type : str
- Data type of the column.
- This is not the `Series.dtype`, but the data type as a string to
- distinguish between different types of `object` columns.
-
- Returns
- -------
- mask : pd.Series
- Whether the elements in the series are actually values.
- """
- if data_type in ("str", "list[str]", "list[list[str]]"):
- # For strings and lists check if they are non-empty
- return ~pd.Series([obj is None or pd.isna(obj).all() if isinstance(obj, np.ndarray) else pd.isna(obj) or len(obj) == 0 for obj in column])
- return column.notna()
-
-
-def _prepend(
- column_descriptions: pd.DataFrame, column_names: list[str]
-) -> pd.DataFrame:
- """
- Put the specified column descriptions first in the DataFrame.
-
- Parameters
- ----------
- df : pd.DataFrame
- DataFrame to reorder.
- columns : list[str]
- Columns that should be displayed first.
-
- Returns
- -------
- pd.DataFrame
- DataFrame with the specified column descriptions first.
- """
- primary_indices = []
- for column_name in column_names:
- indices = np.where(column_descriptions["Name"] == column_name)[0]
- if len(indices) == 0:
- logger.warning(
- f"Primary column '{column_name}' not found in column descriptions."
+def generate_table(description_dir: Path, output_html_path: Path) -> None:
+ """Render one searchable HTML table per checked-in release table."""
+ sections: list[str] = []
+ for description_file in sorted((description_dir / "tables").glob("*.tsv")):
+ frame = pd.read_csv(description_file, sep="\t")
+ if frame.columns.tolist() != DESCRIPTION_COLUMNS:
+ raise ValueError(
+ f"{description_file} must contain columns {DESCRIPTION_COLUMNS}"
)
- continue
- primary_indices.append(indices[0])
- # Remove the primary columns from the original order...
- indices = np.arange(column_descriptions.shape[0])
- indices = indices[~np.isin(indices, primary_indices)]
- # ...and insert them at the beginning
- indices = np.concatenate([primary_indices, indices])
- column_descriptions = column_descriptions.iloc[indices]
- column_descriptions.reset_index(drop=True, inplace=True)
- return column_descriptions
+ if frame["Name"].duplicated().any():
+ raise ValueError(f"{description_file} contains duplicate column names")
+ frame = frame.apply(
+ lambda column: column.map(lambda value: escape(str(value), quote=True))
+ )
+ table_name = escape(description_file.stem, quote=True)
+ table_id = description_file.stem.replace("_", "-")
+ table_html = _render_description_table(frame)
+ sections.extend(
+ [
+ f'',
+ f"
{table_name}
",
+ *(line for line in table_html.splitlines() if line.strip()),
+ "",
+ ]
+ )
+ if not sections:
+ raise FileNotFoundError(
+ f"no release-table descriptions found below {description_dir / 'tables'}"
+ )
+
+ output_html_path.write_text(
+ "\n".join(line for line in sections if line.strip()),
+ encoding="utf-8",
+ )
diff --git a/docs/tutorial/api.ipynb b/docs/tutorial/api.ipynb
deleted file mode 100644
index 81754f411..000000000
--- a/docs/tutorial/api.ipynb
+++ /dev/null
@@ -1,401 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Python API tutorial\n",
- "\n",
- "## Setup\n",
- "\n",
- "### Installation\n",
- "\n",
- "`plinder` is available on *PyPI*.\n",
- "\n",
- "```\n",
- "pip install plinder\n",
- "```\n",
- "\n",
- "### Environment variable configuration\n",
- "\n",
- "We need to set environment variables to point to the release and iteration of choice.\n",
- "The R2 downloader uses the current release; the old small tutorial dataset is not mirrored.\n",
- "Use `PLINDER_RELEASE=2024-06` and `PLINDER_ITERATION=v2`. Broad queries may download large datasets.\n",
- "\n",
- ":::{note}\n",
- "The version used for the preprint is `PLINDER_RELEASE=2024-04` and\n",
- "`PLINDER_ITERATION=v1` (not mirrored on R2), while the current version to be used\n",
- "for the MLSB challenge is`PLINDER_RELEASE=2024-06` and `PLINDER_ITERATION=v2`.\n",
- ":::"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "%env PLINDER_LOG_LEVEL=0\n",
- "%env PLINDER_ITERATION=v2"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "As alternative these variables could also be set from terminal via `export` (*UNIX*) or\n",
- "`set` (*Windows*)."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Overview\n",
- "\n",
- "The user-facing subpackage of `plinder` is {mod}`plinder.core`.\n",
- "This provides access to the underlying utility functions for accessing the dataset,\n",
- "split and annotations.\n",
- "It provides access to five top-level functions:\n",
- "\n",
- ":::{currentmodule} plinder.core\n",
- ":::\n",
- "\n",
- "- {func}`get_config()`: access *PLINDER* global configuration\n",
- "- {func}`query_index()`: access and query annotation table\n",
- "\n",
- ":::{currentmodule} plinder\n",
- ":::\n",
- "\n",
- "In addition, it provides access to the data class {class}`PlinderSystem` for\n",
- "reconstituting a *PLINDER* system from its `system_id`.\n",
- "\n",
- "To supplement these data, {mod}`plinder.core.scores` provides functionality for\n",
- "querying metrics, such as protein/ligand similarity and cluster identity."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Getting the configuration\n",
- "\n",
- "At first we get the configuration to check that all parameters are correctly set. \n",
- "In the snippet below, we will check, if the local and remote *PLINDER* paths point to\n",
- "the expected location."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import plinder.core.utils.config\n",
- "\n",
- "cfg = plinder.core.get_config()\n",
- "print(f\"local cache directory: {cfg.data.plinder_dir}\")\n",
- "print(f\"remote data directory: {cfg.data.plinder_remote}\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Query annotations"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Query specific columns \n",
- "\n",
- ":::{currentmodule} plinder.core.scores\n",
- ":::\n",
- "\n",
- "To query the annotations table for specific columns or filter by specific criteria, use\n",
- "{func}`query_index()`.\n",
- "The function could be called without any argument to yield a [`pandas`](https://pandas.pydata.org) dataframe of `system_id`,\n",
- "`entry_pdb_id`, and `split`, and by default only loads systems present in the `train` and `val` splits."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from plinder.core.scores import query_index\n",
- "\n",
- "# Get system_id, entry_pdb_id, and split columns of train and val splits\n",
- "query_index()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The function can be called by passing `columns` argument, which is a list of\n",
- "[column names](#annotation-table-target). "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Get specific columns from the annotation table\n",
- "cols_of_interest = [\"system_id\", \"entry_pdb_id\", \"entry_release_date\", \"entry_oligomeric_state\", \"entry_validation_clashscore\", \"entry_resolution\"]\n",
- "query_index(columns=cols_of_interest)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Query annotations with specific filters\n",
- "\n",
- "We could also pass additional `filters`, where each filter is a logical comparison\n",
- "of a column name with some given value.\n",
- "Only those rows, that fulfill all conditions, are returned.\n",
- "See the description of\n",
- "[`pandas.read_parquet()`](https://pandas.pydata.org/docs/reference/api/pandas.read_parquet.html)\n",
- "for more information on the filter syntax."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Query for single-ligand systems\n",
- "filters = [(\"system_num_ligand_chains\", \"==\", 1)]\n",
- "query_index(columns=cols_of_interest, filters=filters)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Query systems in test, removed, or unassigned splits\n",
- "\n",
- "The `splits` parameter is set to [\"train\", \"val\"] by default but can take one or more of [\"train\", \"val\", \"test\", \"removed\", \"all\"]. By querying with [\"*\"], we get all 1.3 million rows, including those from the test and removed splits as well ion systems and systems with >5 protein and/or ligand chains (labelled \"unassigned\"):"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "df = query_index(columns=cols_of_interest, splits=[\"*\"])\n",
- "df.drop_duplicates(\"system_id\")[\"split\"].value_counts()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- ":::{note}\n",
- ":::{currentmodule} plinder.core\n",
- ":::\n",
- "To load all the columns, users can use the function {func}`get_plindex()` which returns all the columns in the dataframe. However, since this table has over 1.3 million rows and over 700 columns, it has a significant memory footprint (~24G RAM) and users are advised to query only columns they need.\n",
- ":::"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Query protein similarity\n",
- "The are three kinds of similarity datasets we provide:\n",
- "- Similarity between ligand bound structures (`holo`)\n",
- "- Similarity between ligand bound and unbound protein structures (`apo`)\n",
- "- Similarity between ligand bound and Alphafold predicted structures (`pred`)\n",
- "Any of these could be specified with {func}`query_protein_similarity()`"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- ":::{note} With the full dataset, some similarity queries might require a large amount of memory. For example, `query_protein_similarity(search_db=\"holo\", filters=[(\"similarity\", \">\", \"50\")]) will use up >500G RAM.:::"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Here, we query protein sequence similarity between a ligand-bound system and an unbound protein structure.\n",
- "This example downloads the approximately 439 MB `apo` score dataset. The `holo` score dataset is about 72.5 GB;\n",
- "filters limit query results but do not reduce the score files downloaded for the selected database."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from plinder.core.scores import query_protein_similarity\n",
- "\n",
- "query_protein_similarity(\n",
- " search_db=\"apo\",\n",
- " columns=[\"query_system\", \"target_system\", \"similarity\"],\n",
- " filters=[\n",
- " (\"query_system\", \"==\", \"101m__1__1.A__1.C_1.D\"),\n",
- " (\"target_system\", \"==\", \"1ufp_A\"),\n",
- " (\"metric\", \"==\", \"protein_fident_qcov_weighted_sum\"),\n",
- " (\"similarity\", \">=\", 90),\n",
- " ],\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Working with a PLINDER system\n",
- "\n",
- "A {class}`PlinderSystem` is the representation of a single System.\n",
- "This object provides access to all PDB entry and system level annotations, as well as\n",
- "the structures of the system components."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Load systems from IDs\n",
- "\n",
- "To reconstitute PLINDER systems directly from a set of IDs use class {class}`PlinderSystem`.\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {},
- "outputs": [],
- "source": [
- "from plinder.core import PlinderSystem\n",
- "\n",
- "plinder_system = PlinderSystem(system_id=\"4agi__1__1.C__1.W\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Users can choose the granularity level of input:\n",
- "In the cases above the systems were specified by their system ID, but as alternative\n",
- "passing PDB IDs (or their two middle characters) is also possible, which gives you all\n",
- "systems corresponding to the given PDB IDs."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Accessing annotations\n",
- "\n",
- "The `PlinderSystem.entry` property provides PDB entry-level annotations for that system.\n",
- "Here, we will list the accessible categories of entry annotations and access the\n",
- "oligomeric state of a given system."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "entry_annotations = plinder_system.entry\n",
- "print(list(entry_annotations.keys()))\n",
- "print(entry_annotations[\"oligomeric_state\"])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Instead, `PlinderSystem.system` returns annotations on the system level.\n",
- "Here, we will extract the SMILES string of the first ligand of a given system."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "system_annotations = plinder_system.system\n",
- "print(list(system_annotations.keys()))\n",
- "# Show ligand smiles of the first ligand of a given system\n",
- "print(system_annotations[\"ligands\"][0][\"rdkit_canonical_smiles\"])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Getting structure file paths\n",
- "\n",
- "The `PlinderSystem` also provides access to the structure files the system is based on.\n",
- "This could be helpful for loading the structures for training a model or performing\n",
- "other calculations that require structural information."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "print(plinder_system.ligand_sdfs)\n",
- "print(plinder_system.smiles)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The same can be done for the receptor protein."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "print(plinder_system.receptor_pdb)\n",
- "print(plinder_system.receptor_cif)\n",
- "print(plinder_system.sequences)"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.15"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/tutorial/dataset.md b/docs/tutorial/dataset.md
index 4f89bf252..514a4407a 100644
--- a/docs/tutorial/dataset.md
+++ b/docs/tutorial/dataset.md
@@ -1,246 +1,31 @@
-# Dataset tutorial
+# Getting started
-## Getting the data
+The `plinder` Python package is the main entry point for downloading release
+files, querying annotations, and reconstructing structures.
-The published `2024-06/v2` dataset is served from Cloudflare R2 at
-`https://plinderdata.org/2024-06/v2/`. Install `plinder` to download files with
-checksum verification and automatic retries; no Google Cloud SDK is required.
+PLINDER downloads the files needed by each API call automatically and reuses
+them on subsequent calls. You can start exploring straight away.
-The dataset is versioned by `PLINDER_RELEASE` (RCSB sync) and
-`PLINDER_ITERATION` (development within a release). The public R2 downloader
-currently supports only `PLINDER_RELEASE=2024-06` and `PLINDER_ITERATION=v2`.
-The old `tutorial` iteration is not mirrored.
-
-Downloaded files are checked against the release manifest's size and MD5 before
-replacing a local file. Cached files with the expected size are reused without
-rehashing. Missing or truncated files are downloaded again; same-size local
-corruption requires deleting the affected file or setting `data.force_update`.
-Interrupted downloads retry from the beginning, up to three attempts.
-
-Set `PLINDER_OFFLINE=1` to use local files without network requests. Unset it to
-return online: any nonempty value enables offline mode. `PLINDER_MIRROR_URL`
-can select an alternate HTTP(S) bucket root serving the same static release
-and its manifest.
-
-For selective access, the API downloads only the required files and archive
-shards:
-
-```python
-from plinder.core import PlinderSystem
-
-system = PlinderSystem(system_id="1avd__1__1.A__1.C")
-print(system.receptor_cif)
-```
-
-To download the full dataset instead:
-
-```bash
-# Adding --yes skips confirmation prompts. Allow hundreds of GB for the data
-# and additional space for extracted archives.
-plinder_download --release 2024-06 --iteration v2
-```
-
-:::{note}
-The historical preprint releases `2024-04/v1` and `2024-04/v0` are not available
-through this downloader. The current release is `2024-06/v2`; existing local
-historical data can still be used with `PLINDER_OFFLINE=1`.
-:::
-
-## Understanding the directory structure
-
-The directory downloaded from the bucket has the following structure:
+## Install PLINDER
```bash
-2024-06/ # The PLINDER release
-|-- v2 # The PLINDER iteration
-| |-- clusters # Pre-calculated cluster labels derived from the protein similarity dataset
-| |-- dbs # TSVs containing the raw files and IDs in the foldseek and mmseqs sub-databases
-| |-- entries # Raw annotations prior to consolidation (split by `two_char_code` and zipped)
-| |-- fingerprints # Index mapping files for the ligand similarity dataset
-| |-- index # Consolidated tabular annotations
-| |-- ligand_scores # Ligand similarity parquet dataset
-| |-- ligands # Ligand data expanded from entries for computing similarity
-| |-- linked_structures # Apo and predicted structures linked to their holo systems
-| |-- links # Apo and predicted structures similarity to their holo structures
-| |-- mmp # Ligand matched molecular pairs (MMP) and series (MMS) data
-| |-- scores # Protein similarity parquet dataset
-| |-- splits # Split files and the configs used to generate them (if available)
-| |-- systems # Structure files for all systems (split by `two_char_code` and zipped)
+pip install plinder
```
-The `systems`, `index`, `clusters` and `splits` directories are most the
-important ones for PLINDER utilization and will be covered in the tutorial, while the
-rest are for more curious users.
-
-To download specific directories of interest, for example `splits`, run:
-
-```python
-from plinder.core.utils.cpl import get_plinder_path
-
-splits = get_plinder_path(rel="splits")
-```
-
-## Unpacking the structure files
-
-If you used the `plinder_download` command, you can skip this section.
-
-Similar to the
-[PDB NextGen Archive](https://www.wwpdb.org/ftp/pdb-nextgen-archive-site), we split the
-structures into subdirectories of chunks (using two penultimate characters of PDB code) to make loading and querying speed palatable.
-
-The structure files can be found in the subfolder
-`~/.local/share/plinder/${PLINDER_RELEASE}/${PLINDER_ITERATION}/systems`.
-To unpack the structures run
+A release is identified by the month of its PDB snapshot. The current release
+(`2026-09`) is the default; select another with:
```bash
-cd ~/.local/share/plinder/${PLINDER_RELEASE}/${PLINDER_ITERATION}/systems; for i in `ls *zip`; do unzip $i; touch ${i//.zip/}_done; done
-```
-
-This will yield directories such as `7eek__1__1.A__1.I`, which is what we call a PLINDER
-system ID in the form
-`______`.
-Each system represent a complex between one or multiple proteins and a small molecules,
-derived from a biological assembly in the PDB.
-The directory contains _mmCIF_, _PDB_ and _SDF_ file formats as well as some additional
-metadata files, for e.g. chain mapping and sequences.
-
-## Exploring the annotation table
-
-All systems are listed and annotated in the table contained in the
-`index/annotation_table.parquet` file.
-The [_Parquet_ format](https://parquet.apache.org/) is an efficient binary data format
-for storing table data.
-There is a multitude of tools that support reading `.parquet` files.
-Here we will use the Python package [`pandas`](https://pandas.pydata.org) to inspect `annotation_table.parquet`.
-
-```python
->>> df = pd.read_parquet("index/annotation_table.parquet")
->>> df.columns
-Index(['entry_pdb_id', 'entry_release_date', 'entry_oligomeric_state',
- 'entry_determination_method', 'entry_keywords', 'entry_pH',
- 'entry_resolution', 'entry_rfree', 'entry_r', 'entry_clashscore',
- ...
- 'ligand_interacting_ligand_chains_UniProt',
- 'system_ligand_chains_PANTHER', 'ligand_interacting_ligand_chains_Pfam',
- 'ligand_neighboring_ligand_chains_Pfam',
- 'ligand_interacting_ligand_chains_PANTHER',
- 'ligand_neighboring_ligand_chains_PANTHER',
- 'system_ligand_chains_SCOP2', 'system_ligand_chains_SCOP2B',
- 'pli_qcov__100__strong__component',
- 'protein_lddt_qcov_weighted_sum__100__strong__component'],
- dtype='object', length=500)
-```
-
-We see that the table contains hundreds of columns.
-Each one is described in more detail in the
-[Dataset Reference](#annotation-table-target).
-The most important column is the `system_id`, which references the PLINDER systems
-in the `systems` directory, we have already seen, but also in the other directories, we
-are going to explore.
-
-While `index/annotation_table.parquet` contains annotation for all PLINDER systems,
-`index/annotation_table_nonredundant.parquet` contains a smaller set after
-ligand-protein redundancy removal.
-
-(cluster-target)=
-
-## Inspecting the clusters
-
-This directory is organized by the similarity metrics used for generating the clusters
-and further nested by whether clustering is done with directed or undirected graph and
-by the threshold for clustering.
-
-Show nested structure
-
-```console
-$ tree clusters
-
-clusters/
-โโโ cluster=communities
-โย ย โโโ directed=False
-โย ย โโโ metric=pli_qcov
-โย ย โย ย โโโ threshold=100
-โย ย โย ย โย ย โโโ data.parquet
-โย ย โย ย โโโ threshold=50
-โย ย โย ย โย ย โโโ data.parquet
-โย ย โย ย โโโ threshold=70
-โย ย โย ย โย ย โโโ data.parquet
-โย ย โย ย โโโ threshold=95
-โย ย โย ย โโโ data.parquet
-โย ย โโโ metric=pli_unique_qcov
-โย ย โย ย โโโ threshold=100
-โย ย โย ย โย ย โโโ data.parquet
-โย ย โย ย โโโ threshold=50
-โย ย โย ย โย ย โโโ data.parquet
-โย ย โย ย โโโ threshold=70
-โย ย โย ย โย ย โโโ data.parquet
-โย ย โย ย โโโ threshold=95
-โย ย โย ย โโโ data.parquet
+export PLINDER_RELEASE=2026-09
```
-As example, we will load the clusters based on pocket sequence similarity from an
-undirected graph at a similarity threshold of 70 %.
-
-```python
->>> import pandas as pd
-
->>> clus_file = "clusters/cluster=communities/directed=False/metric=pli_qcov/threshold=70/data.parquet"
->>> df = pd.read_parquet(clus_file)
->>> df
- system_id label metric cluster directed threshold
-0 3mj2__1__1.A__1.B c0 pli_qcov communities False 70
-1 4dh8__1__1.A_1.B__1.C_1.D_1.E c0 pli_qcov communities False 70
-2 7akb__1__1.A__1.C c0 pli_qcov communities False 70
-3 7mgj__2__1.B__1.F c0 pli_qcov communities False 70
-4 4fr4__6__1.F__1.S c0 pli_qcov communities False 70
-... ... ... ... ... ... ...
-479806 7xpv__1__2.A__2.C_2.D c77190 pli_qcov communities False 70
-479807 4ret__1__1.A__1.I c77191 pli_qcov communities False 70
-479808 7ks9__1__1.C__1.R c77192 pli_qcov communities False 70
-479809 7s6n__1__1.A__1.H c77193 pli_qcov communities False 70
-479810 7sc5__1__1.A__1.H c77194 pli_qcov communities False 70
-
-[479811 rows x 6 columns]
-```
+## Continue with a runnable guide
-The table assigns a cluster to each system, depicted by the cluster ID in the
-`component` column.
-This means, all systems with the same cluster ID belong to the same cluster.
-
-## Accessing the splits
-
-The `splits` directory contains an index for _training-validation-test_ splits contained
-in a single parquet file.
-The _PL50_ split described in the [article](https://doi.org/10.1101/2024.07.17.603955)
-belongs to the historical `2024-04/v1` release, which is not mirrored on R2.
-The current split is `2024-06/v2/splits/split.parquet`.
-
-```python
->>> import pandas as pd
->>> df = pd.read_parquet("splits/split.parquet")
->>> df.head()
- system_id uniqueness split cluster ... system_proper_num_interactions system_proper_ligand_max_molecular_weight system_has_binding_affinity system_has_apo_or_pred
-0 101m__1__1.A__1.C_1.D 101m__A__C_D_c188899 train c14 ... 20 616.177293 False False
-1 102m__1__1.A__1.C 102m__A__C_c237197 train c14 ... 20 616.177293 False True
-2 103m__1__1.A__1.C_1.D 103m__A__C_D_c252759 train c14 ... 16 616.177293 False False
-3 104m__1__1.A__1.C_1.D 104m__A__C_D_c274687 train c14 ... 21 616.177293 False False
-4 105m__1__1.A__1.C_1.D 105m__A__C_D_c221688 train c14 ... 20 616.177293 False False
-
-[5 rows x 13 columns]
-```
+Start with {doc}`/examples/2_query_filter_index` to select ligand or protein-interface
+records. The remaining {doc}`/examples/index` guides cover coordinate access,
+similarity analysis, and custom scoring.
-The columns are:
+For a local copy to use offline, see {doc}`/examples/1_download`.
-- `system_id`: The PLINDER system ID
-- `uniqueness`: An id tag that captures system redundancy based on ligand and pocket similarity
-- `split`: Split category, either `train` (training set), `test` (test set)
-- `cluster`: Cluster metric used in sampling test dataset.
-- `cluster_for_val_split`: Cluster metric used in sampling validation set from training set.
-- `system_pass_validation_criteria`: Boolean indicating whether a system pass all the quality criteria
-- `system_pass_statistics_criteria`: Boolean indicating whether a system pass the desired statistics criteria
-- `system_proper_num_ligand_chains`: Number of chains ligands that are not ions or artifacts
-- `system_proper_pocket_num_residues`: Number of pocket residues around ligands that are not ions or artifacts
-- `system_proper_num_interactions`: Number of interactions based on ligands that are not ions or artifacts
-- `system_proper_ligand_max_molecular_weight`: Maximum molecular weight of ligands that are not ions or artifacts
-- `system_has_binding_affinity`: Boolean indicator of whether a system has binding affinity or not
-- `system_has_apo_or_pred`: Boolean indicator of whether a system apo or predicted structures linked
+Use the {doc}`/dataset` page as the release and table reference, and
+{doc}`/api/index` for individual Python signatures.
diff --git a/docs/tutorial/index.md b/docs/tutorial/index.md
index 8b483697b..5981376cc 100644
--- a/docs/tutorial/index.md
+++ b/docs/tutorial/index.md
@@ -1,13 +1,10 @@
-# Tutorial
+# Getting started
-The following tutorials represent the two approaches to using PLINDER:
-The files from the dataset can be accessed directly using your preferred tooling.
-On the other side, the dedicated `plinder` Python package provides a simplified
-efficient way for working with the data.
+Start with the short guide below to install PLINDER and select a release, then
+continue with the runnable {doc}`/examples/index` guides.
```{toctree}
:maxdepth: 1
dataset
-api
```
diff --git a/environment.yml b/environment.yml
index 01df3379d..51a580b61 100644
--- a/environment.yml
+++ b/environment.yml
@@ -1,17 +1,20 @@
#
# Conda environment definition with dependencies
#
+# For data generation and OpenStructure-backed eval/scoring:
+# conda env create -f environment.yml
+# pip install -e .
+#
+# For PoseBusters ligand validation:
+# pip install -e ".[eval]"
+#
name: plinder
channels:
- conda-forge
- defaults
- bioconda
dependencies:
- - python=3.10.*
- - reduce
- - openstructure
+ - python=3.12.*
- mmseqs2
- foldseek
- - plip=2.3.0
- - pip:
- - keyrings.google-artifactregistry-auth==1.1.2
+ - bioconda::openstructure>=2.12.0
diff --git a/flows/configs/split_configs/batch_0/1.yaml b/flows/configs/split_configs/batch_0/1.yaml
deleted file mode 100644
index d48e26370..000000000
--- a/flows/configs/split_configs/batch_0/1.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-split:
- graph_configs:
- - metric: pli_qcov
- threshold: 30
- depth: 2
- - metric: pocket_qcov
- threshold: 50
- depth: 2
- - metric: protein_lddt_weighted_sum
- threshold: 70
- depth: 1
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_community_size: 2
- max_leakage_count: 200
- mms_unique_quality_count: 2
diff --git a/flows/configs/split_configs/batch_0/2.yaml b/flows/configs/split_configs/batch_0/2.yaml
deleted file mode 100644
index 382e750a9..000000000
--- a/flows/configs/split_configs/batch_0/2.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_qcov
- threshold: 20
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_community_size: 2
- max_leakage_count: 200
- mms_unique_quality_count: 2
diff --git a/flows/configs/split_configs/batch_0/3.yaml b/flows/configs/split_configs/batch_0/3.yaml
deleted file mode 100644
index f3d302a52..000000000
--- a/flows/configs/split_configs/batch_0/3.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: protein_seqsim_weighted_max
- threshold: 30
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_community_size: 2
- max_leakage_count: 200
- mms_unique_quality_count: 2
diff --git a/flows/configs/split_configs/batch_0/4.yaml b/flows/configs/split_configs/batch_0/4.yaml
deleted file mode 100644
index f3d302a52..000000000
--- a/flows/configs/split_configs/batch_0/4.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: protein_seqsim_weighted_max
- threshold: 30
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_community_size: 2
- max_leakage_count: 200
- mms_unique_quality_count: 2
diff --git a/flows/configs/split_configs/batch_0/5.yaml b/flows/configs/split_configs/batch_0/5.yaml
deleted file mode 100644
index cda675f1a..000000000
--- a/flows/configs/split_configs/batch_0/5.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-split:
- graph_configs:
- - metric: pli_qcov
- threshold: 30
- depth: 2
- - metric: protein_lddt_weighted_sum
- threshold: 55
- depth: 1
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_community_size: 2
- max_leakage_count: 200
- mms_unique_quality_count: 2
diff --git a/flows/configs/split_configs/batch_0/6.yaml b/flows/configs/split_configs/batch_0/6.yaml
deleted file mode 100644
index 1d4905342..000000000
--- a/flows/configs/split_configs/batch_0/6.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_lddt
- threshold: 50
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_community_size: 2
- max_leakage_count: 200
- mms_unique_quality_count: 2
diff --git a/flows/configs/split_configs/batch_1/1.yaml b/flows/configs/split_configs/batch_1/1.yaml
deleted file mode 100644
index 02fbd1f24..000000000
--- a/flows/configs/split_configs/batch_1/1.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-split:
- graph_configs:
- - metric: pli_qcov
- threshold: 30
- depth: 2
- - metric: pocket_qcov
- threshold: 50
- depth: 2
- - metric: protein_lddt_weighted_sum
- threshold: 70
- depth: 1
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_community_size: 2
- max_leakage_count: 300
- mms_unique_quality_count: 2
diff --git a/flows/configs/split_configs/batch_1/2.yaml b/flows/configs/split_configs/batch_1/2.yaml
deleted file mode 100644
index d52e3542a..000000000
--- a/flows/configs/split_configs/batch_1/2.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_qcov
- threshold: 20
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_community_size: 2
- max_leakage_count: 300
- mms_unique_quality_count: 2
diff --git a/flows/configs/split_configs/batch_1/3.yaml b/flows/configs/split_configs/batch_1/3.yaml
deleted file mode 100644
index f24d66e3d..000000000
--- a/flows/configs/split_configs/batch_1/3.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: protein_seqsim_weighted_max
- threshold: 30
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_community_size: 2
- max_leakage_count: 300
- mms_unique_quality_count: 2
diff --git a/flows/configs/split_configs/batch_1/4.yaml b/flows/configs/split_configs/batch_1/4.yaml
deleted file mode 100644
index f24d66e3d..000000000
--- a/flows/configs/split_configs/batch_1/4.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: protein_seqsim_weighted_max
- threshold: 30
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_community_size: 2
- max_leakage_count: 300
- mms_unique_quality_count: 2
diff --git a/flows/configs/split_configs/batch_1/5.yaml b/flows/configs/split_configs/batch_1/5.yaml
deleted file mode 100644
index 95105b8cb..000000000
--- a/flows/configs/split_configs/batch_1/5.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-split:
- graph_configs:
- - metric: pli_qcov
- threshold: 30
- depth: 2
- - metric: protein_lddt_weighted_sum
- threshold: 55
- depth: 1
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_community_size: 2
- max_leakage_count: 300
- mms_unique_quality_count: 2
diff --git a/flows/configs/split_configs/batch_1/6.yaml b/flows/configs/split_configs/batch_1/6.yaml
deleted file mode 100644
index 33640fa9b..000000000
--- a/flows/configs/split_configs/batch_1/6.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_lddt
- threshold: 50
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_community_size: 2
- max_leakage_count: 300
- mms_unique_quality_count: 2
diff --git a/flows/configs/split_configs/batch_2/0_5.yaml b/flows/configs/split_configs/batch_2/0_5.yaml
deleted file mode 100644
index cda675f1a..000000000
--- a/flows/configs/split_configs/batch_2/0_5.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-split:
- graph_configs:
- - metric: pli_qcov
- threshold: 30
- depth: 2
- - metric: protein_lddt_weighted_sum
- threshold: 55
- depth: 1
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_community_size: 2
- max_leakage_count: 200
- mms_unique_quality_count: 2
diff --git a/flows/configs/split_configs/batch_2/1_5.yaml b/flows/configs/split_configs/batch_2/1_5.yaml
deleted file mode 100644
index 95105b8cb..000000000
--- a/flows/configs/split_configs/batch_2/1_5.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-split:
- graph_configs:
- - metric: pli_qcov
- threshold: 30
- depth: 2
- - metric: protein_lddt_weighted_sum
- threshold: 55
- depth: 1
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_community_size: 2
- max_leakage_count: 300
- mms_unique_quality_count: 2
diff --git a/flows/configs/split_configs/batch_3/1.yaml b/flows/configs/split_configs/batch_3/1.yaml
deleted file mode 100644
index 90dd0888f..000000000
--- a/flows/configs/split_configs/batch_3/1.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-split:
- graph_configs:
- - metric: pli_qcov
- threshold: 30
- depth: 2
- - metric: pocket_qcov
- threshold: 50
- depth: 2
- - metric: protein_lddt_weighted_sum
- threshold: 70
- depth: 1
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_3/10.yaml b/flows/configs/split_configs/batch_3/10.yaml
deleted file mode 100644
index 93531f336..000000000
--- a/flows/configs/split_configs/batch_3/10.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-split:
- graph_configs:
- - metric: pli_qcov
- threshold: 30
- depth: 2
- - metric: pocket_qcov
- threshold: 50
- depth: 2
- - metric: protein_lddt_weighted_sum
- threshold: 70
- depth: 1
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 10
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_3/11.yaml b/flows/configs/split_configs/batch_3/11.yaml
deleted file mode 100644
index 4779577f2..000000000
--- a/flows/configs/split_configs/batch_3/11.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_qcov
- threshold: 20
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_lddt
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_3/12.yaml b/flows/configs/split_configs/batch_3/12.yaml
deleted file mode 100644
index afaac4589..000000000
--- a/flows/configs/split_configs/batch_3/12.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_qcov
- threshold: 20
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_lddt
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 10
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_3/13.yaml b/flows/configs/split_configs/batch_3/13.yaml
deleted file mode 100644
index 6fd6e95ed..000000000
--- a/flows/configs/split_configs/batch_3/13.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_qcov
- threshold: 20
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_sample_cluster_size: 2
- max_leakage_count: 300
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_3/14.yaml b/flows/configs/split_configs/batch_3/14.yaml
deleted file mode 100644
index f597bfa76..000000000
--- a/flows/configs/split_configs/batch_3/14.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_qcov
- threshold: 20
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_sample_cluster_size: 2
- max_leakage_count: 500
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_3/2.yaml b/flows/configs/split_configs/batch_3/2.yaml
deleted file mode 100644
index c774869ec..000000000
--- a/flows/configs/split_configs/batch_3/2.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_qcov
- threshold: 20
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_3/3.yaml b/flows/configs/split_configs/batch_3/3.yaml
deleted file mode 100644
index 1b82527f7..000000000
--- a/flows/configs/split_configs/batch_3/3.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: protein_seqsim_weighted_max
- threshold: 30
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_3/5.yaml b/flows/configs/split_configs/batch_3/5.yaml
deleted file mode 100644
index 0c4abcab6..000000000
--- a/flows/configs/split_configs/batch_3/5.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_lddt
- threshold: 50
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_3/6.yaml b/flows/configs/split_configs/batch_3/6.yaml
deleted file mode 100644
index ebe4520a1..000000000
--- a/flows/configs/split_configs/batch_3/6.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_qcov
- threshold: 20
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 10
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_3/7.yaml b/flows/configs/split_configs/batch_3/7.yaml
deleted file mode 100644
index 8dc2fddb7..000000000
--- a/flows/configs/split_configs/batch_3/7.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: protein_seqsim_weighted_max
- threshold: 30
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 10
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_3/9.yaml b/flows/configs/split_configs/batch_3/9.yaml
deleted file mode 100644
index b2dc313b3..000000000
--- a/flows/configs/split_configs/batch_3/9.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_lddt
- threshold: 50
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 10
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_4/4.yaml b/flows/configs/split_configs/batch_4/4.yaml
deleted file mode 100644
index d11ec9b41..000000000
--- a/flows/configs/split_configs/batch_4/4.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-split:
- graph_configs:
- - metric: pli_qcov
- threshold: 30
- depth: 2
- - metric: protein_lddt_weighted_sum
- threshold: 55
- depth: 1
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_4/8.yaml b/flows/configs/split_configs/batch_4/8.yaml
deleted file mode 100644
index 54cf55f03..000000000
--- a/flows/configs/split_configs/batch_4/8.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-split:
- graph_configs:
- - metric: pli_qcov
- threshold: 30
- depth: 2
- - metric: protein_lddt_weighted_sum
- threshold: 55
- depth: 1
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 10
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_5/10.yaml b/flows/configs/split_configs/batch_5/10.yaml
deleted file mode 100644
index af2cfed6c..000000000
--- a/flows/configs/split_configs/batch_5/10.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_lddt
- threshold: 50
- depth: 1
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 10
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_5/9.yaml b/flows/configs/split_configs/batch_5/9.yaml
deleted file mode 100644
index b2dc313b3..000000000
--- a/flows/configs/split_configs/batch_5/9.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_lddt
- threshold: 50
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 10
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_5/batch_11.yaml b/flows/configs/split_configs/batch_5/batch_11.yaml
deleted file mode 100644
index 8cd38dfaf..000000000
--- a/flows/configs/split_configs/batch_5/batch_11.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_lddt
- threshold: 50
- depth: 1
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pli_qcov
- val_cluster_threshold: 70
- val_cluster_directed: true
- num_representatives: 10
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_5/batch_12.yaml b/flows/configs/split_configs/batch_5/batch_12.yaml
deleted file mode 100644
index e10c5ac87..000000000
--- a/flows/configs/split_configs/batch_5/batch_12.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_lddt
- threshold: 50
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pli_qcov
- val_cluster_threshold: 70
- val_cluster_directed: true
- num_representatives: 10
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_6/10.yaml b/flows/configs/split_configs/batch_6/10.yaml
deleted file mode 100644
index c1aa6046e..000000000
--- a/flows/configs/split_configs/batch_6/10.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-split:
- graph_configs:
- - metric: pli_qcov
- threshold: 20
- depth: 2
- - metric: pocket_qcov
- threshold: 50
- depth: 2
- - metric: protein_lddt_weighted_sum
- threshold: 70
- depth: 1
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_6/2.yaml b/flows/configs/split_configs/batch_6/2.yaml
deleted file mode 100644
index c774869ec..000000000
--- a/flows/configs/split_configs/batch_6/2.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_qcov
- threshold: 20
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_6/7.yaml b/flows/configs/split_configs/batch_6/7.yaml
deleted file mode 100644
index 1b82527f7..000000000
--- a/flows/configs/split_configs/batch_6/7.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: protein_seqsim_weighted_max
- threshold: 30
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/split_configs/batch_6/9.yaml b/flows/configs/split_configs/batch_6/9.yaml
deleted file mode 100644
index 0c4abcab6..000000000
--- a/flows/configs/split_configs/batch_6/9.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_lddt
- threshold: 50
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 5
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/v2/download_and_make_dbs.yaml b/flows/configs/v2/download_and_make_dbs.yaml
deleted file mode 100644
index 1a32c6632..000000000
--- a/flows/configs/v2/download_and_make_dbs.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-ingest:
- run_specific_stages: download_rcsb_files,download_alternative_datasets,make_dbs
- plinder_mount: /plinder
- plinder_release: 2024-06
- force_update: true
-scatter:
- two_char_batch_size: 4
diff --git a/flows/configs/v2/make_batch_scores_only.yaml b/flows/configs/v2/make_batch_scores_only.yaml
deleted file mode 100644
index 91f21713e..000000000
--- a/flows/configs/v2/make_batch_scores_only.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-ingest:
- run_specific_stages: make_batch_scores
- plinder_mount: /plinder
- plinder_release: 2024-06
-scorer:
- sub_databases: holo,apo,pred
-scatter:
- run_batch_searches_batch_size: 10050
- make_batch_scores_batch_size: 90
diff --git a/flows/configs/v2/make_components.yaml b/flows/configs/v2/make_components.yaml
deleted file mode 100644
index e6d201f7f..000000000
--- a/flows/configs/v2/make_components.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-ingest:
- run_specific_stages: make_components_and_communities,make_mmp_index
- plinder_mount: /plinder
- plinder_release: 2024-06
-scatter:
- skip_existing_clusters: False
diff --git a/flows/configs/v2/make_entries_ligands.yaml b/flows/configs/v2/make_entries_ligands.yaml
deleted file mode 100644
index 9183d0c31..000000000
--- a/flows/configs/v2/make_entries_ligands.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-ingest:
- run_specific_stages: make_entries,structure_qc,make_system_archives,make_ligands,compute_ligand_fingerprints,make_ligand_scores
- plinder_mount: /plinder
- plinder_release: 2024-06
-scatter:
- two_char_batch_size: 1
- annotation_batch_size: 120
- make_ligands_batch_size: 220
- skip_existing_entries: true
- skip_missing_annotations: true
diff --git a/flows/configs/v2/make_leakage.yaml b/flows/configs/v2/make_leakage.yaml
deleted file mode 100644
index 6b09bc2ed..000000000
--- a/flows/configs/v2/make_leakage.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-ingest:
- run_specific_stages: make_leakage
- plinder_mount: /plinder
- plinder_release: 2024-06
diff --git a/flows/configs/v2/make_protein_scores.yaml b/flows/configs/v2/make_protein_scores.yaml
deleted file mode 100644
index 499dc8a6d..000000000
--- a/flows/configs/v2/make_protein_scores.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-ingest:
- run_specific_stages: make_sub_dbs,run_batch_searches,make_batch_scores
- plinder_mount: /plinder
- plinder_release: 2024-06
-scorer:
- sub_databases: holo,apo,pred
-scatter:
- run_batch_searches_batch_size: 10050
- make_batch_scores_batch_size: 111
diff --git a/flows/configs/v2/make_splits.yaml b/flows/configs/v2/make_splits.yaml
deleted file mode 100644
index 45e921f2c..000000000
--- a/flows/configs/v2/make_splits.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-ingest:
- run_specific_stages: make_splits
- plinder_mount: /plinder
- plinder_release: 2024-06
-scatter:
- split_config_dir: gs://plinder-collab-bucket/metaflow/config/split/v2/
diff --git a/flows/configs/v2/split_multi_graph.yaml b/flows/configs/v2/split_multi_graph.yaml
deleted file mode 100644
index 06ec2e46f..000000000
--- a/flows/configs/v2/split_multi_graph.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-split:
- graph_configs:
- - metric: pli_qcov
- threshold: 20
- depth: 2
- - metric: pocket_qcov
- threshold: 50
- depth: 2
- - metric: protein_lddt_weighted_sum
- threshold: 70
- depth: 1
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 10
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/configs/v2/split_single_graph.yaml b/flows/configs/v2/split_single_graph.yaml
deleted file mode 100644
index b2dc313b3..000000000
--- a/flows/configs/v2/split_single_graph.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-split:
- graph_configs:
- - metric: pocket_lddt
- threshold: 50
- depth: 2
- sampling_cluster_metric: pli_qcov
- sampling_cluster_threshold: 70
- sampling_cluster_directed: true
- val_cluster_metric: pocket_qcov
- val_cluster_threshold: 50
- val_cluster_directed: false
- num_representatives: 10
- min_sample_cluster_size: 2
- max_leakage_count: 400
- mms_unique_quality_count: 3
diff --git a/flows/data_ingest.py b/flows/data_ingest.py
deleted file mode 100644
index 596836e54..000000000
--- a/flows/data_ingest.py
+++ /dev/null
@@ -1,474 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-"""
-The filestore instance name is: plinder-data-gen.
-
-"""
-from __future__ import annotations
-
-from metaflow import FlowSpec, Parameter, kubernetes, environment, step, retry
-
-
-MOUNT = "/plinder"
-K8S = dict(
- cpu=1,
- image="us-east1-docker.pkg.dev/vantai-analysis/metaflow/plinder:v0.2.2-63-g71bd2d22",
- node_selector={
- "topology.kubernetes.io/zone": "us-east1-b",
- },
- persistent_volume_claims={
- "plinder-data-gen-pvc": MOUNT,
- },
-)
-ENV = dict(
- vars=dict(
- PLINDER_MOUNT=MOUNT,
- PLINDER_RELEASE="2024-06",
- PLINDER_ITERATION="",
- )
-)
-DATABASES = dict(cpu=90, memory=82000)
-WORKSTATION = dict(cpu=14, memory=14000)
-WORKSTATION_MEM = dict(cpu=5, memory=48000)
-LARGE_MEM = dict(
- cpu=7,
- memory=380000,
- tolerations=[
- dict(
- effect="NoSchedule",
- key="machine_type",
- value="n1-custom-380",
- )
- ]
-)
-
-
-class PlinderDataIngestFlow(FlowSpec):
- config_file = Parameter("config_file", required=True)
-
- @kubernetes(**K8S)
- @environment(**ENV)
- @retry
- @step
- def start(self):
- from plinder.core.utils import gcs
- from plinder.data.pipeline.config import get_config
- from plinder.data.pipeline.pipeline import IngestPipeline
-
- assert isinstance(self.config_file, str)
- if not self.config_file.startswith("gs:"):
- raise ValueError("--config_file must be a gs:// path")
- print(f"started data ingest run with config: {self.config_file}")
- contents = gcs.download_as_str(gcs_path=self.config_file, bucket_name="plinder-collab-bucket")
- self.pipeline = IngestPipeline(conf=get_config(config_contents=contents))
- # self.next(self.scatter_download_rcsb_files)
- # self.next(self.scatter_make_entries)
- self.next(self.scatter_structure_qc)
- # self.next(self.scatter_collate_partitions)
- # self.next(self.scatter_make_components_and_communities)
- # self.next(self.scatter_make_links)
-
- # @kubernetes(**{**K8S, **LARGE_MEM, **{"cpu": 3.5, "memory": 175000}})
- # @environment(**ENV)
- # @retry
- # @step
- # def scatter_collate_partitions(self):
- # self.chunks = self.pipeline.scatter_collate_partitions()
- # self.next(self.collate_partitions, foreach="chunks")
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def collate_partitions(self):
- # self.pipeline.collate_partitions(self.input)
- # self.next(self.join_collate_partitions)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def join_collate_partitions(self, inputs):
- # self.pipeline = inputs[0].pipeline
- # self.merge_artifacts(inputs, exclude=["chunks"])
- # self.next(self.make_mmp_index)
-
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def scatter_download_rcsb_files(self):
- # self.chunks = self.pipeline.scatter_download_rcsb_files()
- # self.next(self.download_rcsb_files, foreach="chunks")
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def download_rcsb_files(self):
- # self.pipeline.download_rcsb_files(self.input)
- # self.next(self.join_download_rcsb_files)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def join_download_rcsb_files(self, inputs):
- # self.pipeline = inputs[0].pipeline
- # self.merge_artifacts(inputs, exclude=["chunks"])
- # self.next(self.download_alternative_datasets)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def download_alternative_datasets(self):
- # self.pipeline.download_alternative_datasets()
- # self.next(self.make_dbs)
- #
- # @kubernetes(**{**K8S, **DATABASES})
- # @environment(**ENV)
- # @retry
- # @step
- # def make_dbs(self):
- # self.pipeline.make_dbs()
- # self.next(self.scatter_make_entries)
-
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def scatter_make_entries(self):
- # self.chunks = self.pipeline.scatter_make_entries()
- # self.next(self.make_entries, foreach="chunks")
- #
- # @kubernetes(**{**K8S, **WORKSTATION})
- # @environment(**ENV)
- # @retry
- # @step
- # def make_entries(self):
- # self.pipeline.cfg.flow.make_entries_cpu = WORKSTATION["cpu"]
- # self.reruns = self.pipeline.make_entries(self.input)
- # self.next(self.join_make_entries)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def join_make_entries(self, inputs):
- # self.pipeline = inputs[0].pipeline
- # self.merge_artifacts(inputs, exclude=["chunks", "reruns"])
- # self.rerun = self.pipeline.join_make_entries([inp.reruns for inp in inputs])
- # self.next(self.scatter_make_entries_second_try)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def scatter_make_entries_second_try(self):
- # self.original_pdb_ids = self.pipeline.cfg.context.pdb_ids
- # self.pipeline.cfg.context.pdb_ids = self.rerun
- # self.chunks = self.pipeline.scatter_make_entries()
- # self.next(self.make_entries_second_try, foreach="chunks")
- #
- # @kubernetes(**{**K8S, **WORKSTATION_MEM})
- # @environment(**ENV)
- # @retry
- # @step
- # def make_entries_second_try(self):
- # self.pipeline.cfg.flow.make_entries_cpu = WORKSTATION_MEM["cpu"]
- # self.pipeline.make_entries(self.input)
- # self.next(self.join_make_entries_second_try)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def join_make_entries_second_try(self, inputs):
- # self.pipeline = inputs[0].pipeline
- # self.merge_artifacts(inputs, exclude=["chunks", "reruns"])
- # self.pipeline.cfg.context.pdb_ids = self.original_pdb_ids
- # self.next(self.scatter_structure_qc)
- #
- @kubernetes(**K8S)
- @environment(**ENV)
- @retry
- @step
- def scatter_structure_qc(self):
- self.chunks = self.pipeline.scatter_structure_qc()
- self.next(self.structure_qc, foreach="chunks")
-
- @kubernetes(**{**K8S, **{"memory": 4000}})
- @environment(**ENV)
- @retry
- @step
- def structure_qc(self):
- self.pipeline.structure_qc(self.input)
- self.next(self.join_structure_qc)
-
- @kubernetes(**K8S)
- @environment(**ENV)
- @retry
- @step
- def join_structure_qc(self, inputs):
- self.pipeline = inputs[0].pipeline
- self.merge_artifacts(inputs, exclude=["chunks"])
- self.pipeline.join_structure_qc([])
- self.next(self.scatter_score_linked_structures)
-
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def scatter_make_system_archives(self):
- # self.chunks = self.pipeline.scatter_make_system_archives()
- # self.next(self.make_system_archives, foreach="chunks")
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def make_system_archives(self):
- # self.pipeline.make_system_archives(self.input)
- # self.next(self.join_make_system_archives)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def join_make_system_archives(self, inputs):
- # self.pipeline = inputs[0].pipeline
- # self.merge_artifacts(inputs, exclude=["chunks"])
- # self.next(self.scatter_make_ligands)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def scatter_make_ligands(self):
- # self.chunks = self.pipeline.scatter_make_ligands()
- # self.next(self.make_ligands, foreach="chunks")
- #
- # @kubernetes(**{**K8S, **WORKSTATION_MEM})
- # @environment(**ENV)
- # @retry
- # @step
- # def make_ligands(self):
- # self.pipeline.make_ligands(self.input)
- # self.next(self.join_make_ligands)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def join_make_ligands(self, inputs):
- # self.pipeline = inputs[0].pipeline
- # self.merge_artifacts(inputs, exclude=["chunks"])
- # self.next(self.compute_ligand_fingerprints)
- #
- # @kubernetes(**{**K8S, **DATABASES})
- # @environment(**ENV)
- # @retry
- # @step
- # def compute_ligand_fingerprints(self):
- # self.pipeline.compute_ligand_fingerprints()
- # self.next(self.scatter_make_ligand_scores)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def scatter_make_ligand_scores(self):
- # self.chunks = self.pipeline.scatter_make_ligand_scores()
- # self.next(self.make_ligand_scores, foreach="chunks")
- #
- # @kubernetes(**{**K8S, **WORKSTATION_MEM})
- # @environment(**ENV)
- # @retry
- # @step
- # def make_ligand_scores(self):
- # self.pipeline.make_ligand_scores(self.input)
- # self.reruns = self.pipeline.make_ligand_scores(self.input)
- # self.next(self.join_make_ligand_scores)
- #
- # @kubernetes(**K8S)
- # @retry
- # @step
- # def join_make_ligand_scores(self, inputs):
- # self.pipeline = inputs[0].pipeline
- # self.merge_artifacts(inputs, exclude=["chunks"])
- # self.next(self.make_sub_dbs)
- #
- # @kubernetes(**{**K8S, **DATABASES})
- # @environment(**ENV)
- # @retry
- # @step
- # def make_sub_dbs(self):
- # self.pipeline.make_sub_dbs()
- # self.next(self.scatter_run_batch_searches)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def scatter_run_batch_searches(self):
- # self.chunks = self.pipeline.scatter_run_batch_searches()
- # self.next(self.run_batch_searches, foreach="chunks")
- #
- # @kubernetes(**{**K8S, **DATABASES})
- # @environment(**ENV)
- # @retry
- # @step
- # def run_batch_searches(self):
- # self.pipeline.run_batch_searches(self.input)
- # self.next(self.join_run_batch_searches)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def join_run_batch_searches(self, inputs):
- # self.pipeline = inputs[0].pipeline
- # self.merge_artifacts(inputs, exclude=["chunks"])
- # self.next(self.scatter_make_batch_scores)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def scatter_make_batch_scores(self):
- # self.chunks = self.pipeline.scatter_make_batch_scores()
- # self.next(self.make_batch_scores, foreach="chunks")
- #
- # @kubernetes(**{**K8S, **{"memory": 10000}})
- # @environment(**ENV)
- # @retry
- # @step
- # def make_batch_scores(self):
- # self.chunks = self.pipeline.make_batch_scores(self.input)
- # self.next(self.join_make_batch_scores)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def join_make_batch_scores(self, inputs):
- # self.pipeline = inputs[0].pipeline
- # self.merge_artifacts(inputs, exclude=["chunks"])
- # # self.next(self.scatter_make_components_and_communities)
- # self.next(self.make_mmp_index) # scatter_make_components_and_communities)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def scatter_make_components_and_communities(self):
- # self.chunks = self.pipeline.scatter_make_components_and_communities()
- # self.next(self.make_components_and_communities, foreach="chunks")
- #
- # @kubernetes(**{**K8S, **LARGE_MEM})
- # @environment(**ENV)
- # @retry
- # @step
- # def make_components_and_communities(self):
- # self.pipeline.make_components_and_communities(self.input)
- # self.next(self.join_make_components_and_communities)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def join_make_components_and_communities(self, inputs):
- # self.pipeline = inputs[0].pipeline
- # self.merge_artifacts(inputs, exclude=["chunks"])
- # self.next(self.make_mmp_index)
- #
- # @kubernetes(**{**K8S, **WORKSTATION})
- # @environment(**ENV)
- # @retry
- # @step
- # def make_mmp_index(self):
- # self.pipeline.make_mmp_index()
- # self.next(self.assign_apo_pred_systems)
- #
- # @kubernetes(**{**K8S, **DATABASES})
- # @environment(**ENV)
- # @retry
- # @step
- # def assign_apo_pred_systems(self):
- # self.pipeline.cfg.flow.assign_apo_pred_systems_cpus = DATABASES["cpu"]
- # self.pipeline.assign_apo_pred_systems()
- # self.next(self.end)
-
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def scatter_make_links(self):
- # self.chunks = self.pipeline.scatter_make_links()
- # self.next(self.make_links, foreach="chunks")
- #
- # @kubernetes(**{**K8S, **DATABASES})
- # @environment(**ENV)
- # @retry
- # @step
- # def make_links(self):
- # self.pipeline.cfg.flow.make_links_cpu = DATABASES["cpu"] - 1
- # self.pipeline.make_links(self.input)
- # self.next(self.join_make_links)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def join_make_links(self, inputs):
- # self.pipeline = inputs[0].pipeline
- # self.merge_artifacts(inputs, exclude=["chunks"])
- # self.next(self.scatter_make_linked_structures)
- #
- # @kubernetes(**{**K8S, **{"cpu": 28, "memory": 24000}})
- # @environment(**ENV)
- # @retry
- # @step
- # def make_linked_structures(self):
- # self.pipeline.cfg.flow.make_linked_structures_cpu = 26
- # self.pipeline.make_linked_structures()
- # self.next(self.end)
- #
- @kubernetes(**{**K8S, **{"memory": 6000}})
- @environment(**ENV)
- @retry
- @step
- def scatter_score_linked_structures(self):
- self.chunks = self.pipeline.scatter_score_linked_structures()
- self.next(self.score_linked_structures, foreach="chunks")
-
- @kubernetes(**{**K8S, **WORKSTATION, **{"memory": 28000}})
- @environment(**ENV)
- @retry
- @step
- def score_linked_structures(self):
- self.pipeline.cfg.flow.score_linked_structures_cpu = WORKSTATION["cpu"] - 1
- self.pipeline.score_linked_structures(self.input)
- self.next(self.join_score_linked_structures)
-
- @kubernetes(**K8S)
- @environment(**ENV)
- @retry
- @step
- def join_score_linked_structures(self, inputs):
- self.pipeline = inputs[0].pipeline
- self.pipeline.join_score_linked_structures(inputs)
- self.merge_artifacts(inputs, exclude=["chunks"])
- self.next(self.end)
-
- @kubernetes(**K8S)
- @environment(**ENV)
- @retry
- @step
- def end(self):
- print(f"finished data ingest run with config: {self.config_file}")
-
-
-if __name__ == "__main__":
- PlinderDataIngestFlow()
diff --git a/flows/data_ingest_report.py b/flows/data_ingest_report.py
deleted file mode 100644
index 423d4be49..000000000
--- a/flows/data_ingest_report.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-"""
-The filestore instance name is: plinder-data-gen.
-"""
-
-from metaflow import FlowSpec, kubernetes, environment, step, retry
-
-import report
-
-MOUNT = "/plinder"
-
-K8S = dict(
- cpu=1,
- image="ghcr.io/plinder-org/plinder:v0.1.1",
- persistent_volume_claims={
- "plinder-data-gen-pvc": MOUNT,
- },
-)
-ENV = dict(
- vars=dict(
- PLINDER_MOUNT=MOUNT,
- PLINDER_RELEASE="2024-04",
- )
-)
-
-
-class PlinderDataIngestReportFlow(FlowSpec):
-
- @kubernetes(**K8S)
- @environment(**ENV)
- @retry
- @step
- def start(self):
- self.dfs = report.main(upload=True)
- self.next(self.end)
-
- @step
- def end(self):
- for name, df in self.dfs.items():
- df.to_csv(f"reports/{name}.csv", index=False)
-
-
-
-if __name__ == '__main__':
- PlinderDataIngestReportFlow()
diff --git a/flows/docker.py b/flows/docker.py
deleted file mode 100644
index 582600ed2..000000000
--- a/flows/docker.py
+++ /dev/null
@@ -1,419 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-import logging
-from argparse import ArgumentParser
-from os import environ
-from pathlib import Path
-from shlex import split
-from shutil import which
-from subprocess import PIPE, check_output
-from sys import argv as sys_argv
-from typing import List, Optional
-
-from proc import Proc
-
-logging.basicConfig(level=logging.INFO)
-LOG = logging.getLogger("doc")
-DEPENDENCY_BLOCKS = "test,pipeline,plots"
-
-
-def get_dev_tag() -> str:
- """
- Get the current git describe which includes base image tag
- and whether or not the repository is in a dirty (uncommitted)
- state.
-
- Returns
- -------
- tag : str
- current git describe
- """
- return check_output(
- [
- "git",
- "describe",
- "--tags",
- "--always",
- "--dirty",
- "--abbrev=8",
- ],
- text=True,
- ).strip()
-
-
-def get_version_bump(base_tag: str | None = None) -> str:
- """
- Inspect the git history for "bumpversion {phrase}"
- and return the new version.
- """
- if base_tag is None:
- current = get_dev_tag()
- base_tag = current.split("-")[0]
- bump = "patch"
- tokens = [
- "bumpversion major",
- "bumpversion minor",
- "bumpversion skip",
- ]
- for token in tokens:
- log = check_output(
- split(
- " ".join(
- [
- "git",
- "log",
- f"{base_tag}..HEAD",
- "--oneline",
- "--grep",
- f"'{token}'",
- "--format=%s",
- ]
- )
- ),
- text=True,
- ).strip()
- # origin/main hack was to get around docs branch but isn'try:
- # present before pushing the tag back to main so just search for PR number
- if log and "(#" in log:
- bump = token.split()[1]
- break
- if bump == "skip":
- return ""
- try:
- import semver
-
- new_version = getattr(semver, f"bump_{bump}")(base_tag.lstrip("v"))
- new_version = f"v{new_version}"
- print(new_version)
- return new_version
- except ImportError:
- LOG.error("could not import semver")
- return ""
-
-
-def get_image() -> str:
- """
- Minimize the diff if any of this changes
- """
- url = "ghcr.io"
- organization = "plinder-org"
- image_name = "plinder"
- return f"{url}/{organization}/{image_name}"
-
-
-def get_docker() -> str:
- """
- Sanity check for docker in environment
- """
- docker = which("docker")
- if docker is None:
- raise ValueError("could not find docker executable!")
- if not (Path.cwd() / "docker-compose.yml").is_file():
- raise ValueError("could not find docker-compose.yml, are you in repo root?")
- return docker
-
-
-def get_env(tag: str | None = None) -> dict[str, str]:
- """
- Get the build env that simulates docker compose
-
- Parameters
- ----------
- tag : str, default=None
- the tag to use instead of the current dev tag
-
- Returns
- -------
- env : dict[str, str]
- the build environment
- """
- image_repo = "/".join(get_image().split("/")[:-1])
- dev_tag = get_dev_tag()
- base_tag = dev_tag.split("-")[0]
- build_tag = tag or dev_tag
- LOG.info(f"get_env: base_tag={base_tag} build_tag={build_tag}")
- return {
- **environ,
- **{
- "BASE_TAG": base_tag,
- "IMAGE_REPO": image_repo,
- "BUILD_TAG": build_tag,
- "INDEX_URL": "https://pypi.org/simple",
- },
- }
-
-
-def pull_base_image(build: bool = False, promote: bool = False) -> None:
- """
- Make sure the base image is up to date. Optionally
- promote the image tag using semver by inspecting the
- git history for "bumpverson {phrase}".
-
- Parameters
- ----------
- promote : bool, default=False
- if True, promote the image tag using semver
- """
- docker = get_docker()
- env = get_env()
- cmd = [docker, "compose", "pull", "base", "--quiet"]
- Proc(cmd, env=env).execute()
- if build:
- cmd = [
- docker,
- "build",
- "-f",
- "dockerfiles/base/Dockerfile",
- "-t",
- f"{env['IMAGE_REPO']}/plinder-base:{env['BASE_TAG']}",
- "--secret",
- "id=INDEX_URL",
- "--build-arg",
- f"BASE_TAG={env['BASE_TAG']}",
- "--build-arg",
- f"DEPENDENCY_BLOCKS={DEPENDENCY_BLOCKS}",
- (Path.cwd() / "dockerfiles/base").as_posix(),
- ]
- Proc(cmd, env=env).execute()
- if promote:
- promote_base_image(env)
-
-
-def promote_base_image(env: dict[str, str]) -> None:
- """
- Promote the base image
- """
- base_tag = env["BASE_TAG"]
- new_tag = get_version_bump(base_tag)
- if not new_tag:
- LOG.info("skipping base image promotion")
- return
- image = f"{env['IMAGE_REPO']}/plinder-base"
- orig_image = f"{image}:{base_tag}"
- new_image = f"{image}:{new_tag}"
- LOG.info(f"promoting base image to {new_tag}")
- docker = get_docker()
- Proc([docker, "tag", orig_image, new_image], env=env).execute()
- check_output(["git", "tag", new_tag])
-
-
-def build_image(tag: str | None = None, push: bool = False) -> str:
- """
- Build the image
-
- Parameters
- ----------
- tag : str, default=None
- the tag to use instead of the current dev tag
- push : bool, default=False
- push the image to the artifact registry
-
- Returns
- -------
- image : str
- the full image including tag
- """
- check_output(["git", "fetch", "--tags"])
- docker = get_docker()
- env = get_env(tag)
- image = f"{env['IMAGE_REPO']}/plinder"
- build_tag = env["BUILD_TAG"]
- registry = environ.get("PLINDER_REGISTRY", "/".join(get_image().split("/")[:-1]))
- cmd = [
- docker,
- "build",
- "-f",
- "dockerfiles/main/Dockerfile",
- "-t",
- f"{env['IMAGE_REPO']}/plinder:{build_tag}",
- "-t",
- f"{registry}/plinder:{build_tag}",
- "--secret",
- "id=INDEX_URL",
- "--build-arg",
- f"BASE_IMAGE={env['IMAGE_REPO']}/plinder-base",
- "--build-arg",
- f"BASE_TAG={env['BASE_TAG']}",
- "--build-arg",
- f"DEPENDENCY_BLOCKS={DEPENDENCY_BLOCKS}",
- Path.cwd().as_posix(),
- ]
- Proc(cmd, env=env).execute()
- if push:
- cmd = [docker, "push", f"{registry}/plinder:{build_tag}"]
- Proc(cmd, env=env).execute()
- return f"{image}:{build_tag}"
-
-
-def test_image(
- tag: str,
- push: bool = False,
- args: Optional[List[str]] = None,
- dirty: bool = False,
-) -> None:
- """
- Run the test service from docker compose. Optionally
- push both the base and plinder images to the artifact
- registry.
-
- Parameters
- ----------
- tag : str
- the tag to use instead of the current dev tag
- push : bool, default=False
- if True, push images to the artifact registry
- args : List[str], default=None
- the arguments to pass to the image
- dirty : bool, default=False
- if True, mount the current working tree
- """
- env = get_env(tag)
- docker = get_docker()
- cmd = [docker, "compose", "run", "-e", "PLINDER_OFFLINE=true"]
- if dirty:
- cmd.extend(["-v", f"{Path.cwd()}/src/plinder:/opt/conda/lib/python3.9/site-packages/plinder"])
- cmd.append("test")
- if args is not None and len(args):
- cmd.extend(
- split(f'''/bin/bash -c "python -m pytest -n auto -v {' '.join(args)} && cp .coverage reports/.coverage"''')
- )
- Proc(cmd, env=env).execute()
- if push:
- cmd = [docker, "compose", "push", "base", "plinder", "--quiet"]
- Proc(cmd, env=env).execute()
-
-
-def run_image(
- args: Optional[List[str]] = None,
- build: bool = False,
- tag: str | None = None,
- dirty: bool = False,
- it: bool = False,
- script: str | None = None,
-) -> None:
- """
- Run the image mounting the current working tree. This can be
- convenient for debugging during development.
-
- Parameters
- ----------
- image : str
- the image to run
- args : List[str], default=None
- the arguments to pass to the image
- """
- tag = tag or "latest"
- image = build_image(tag=tag) if build else get_image() + ":" + tag
- docker = which("docker")
- if docker is None:
- raise ValueError("could not find docker executable!")
- home = Path.home()
- host = Path.cwd() / "src"
- guest = "/opt/conda/lib/python3.10/site-packages/plinder"
- app = "/app/src"
- if not host.is_dir():
- raise RuntimeError(f"could not find {host}, please run from repo root")
- cmd = [
- docker,
- "run",
- "--platform",
- "linux/amd64",
- "-e",
- "PLINDER_TEST_BASE_DIR=/app",
- "-v",
- f"{host.parent}/tests:/app/tests/",
- "-v",
- f"{host.parent}/column_descriptions:/app/column_descriptions/",
- "-e",
- "PLINDER_MOUNT=/plinder",
- "-e",
- "PLINDER_LOG_LEVEL=10",
- "-v",
- f"{home}/.local/share/plinder:/plinder",
- "-v",
- f"{host}/plinder:{guest}",
- "-v",
- f"{host}:{app}",
- ]
- if script:
- cmd.extend(["-v", f"{host.parent}/{script}:{Path(app).parent}/{script}"])
- if it:
- import pty
-
- pty.spawn(cmd + ["-it", image, "/bin/bash"])
- return
- cmd.append(image)
- if args is not None:
- cmd.extend(args)
- Proc(cmd).execute()
-
-
-def main(argv: Optional[List[str]] = None):
- """
- The main entrypoint for the docker helper
-
- Parameters
- ----------
- argv : List[str], default=None
- the command line arguments
- """
- if argv is None:
- argv = sys_argv[1:]
- parser = ArgumentParser(prog="plinder docker helper")
- subs = parser.add_subparsers(help="subcommand", dest="command")
- subs.add_parser("bump", help="Get version bump")
- pull = subs.add_parser("pull", help="Pull the base image")
- pull.add_argument(
- "--promote",
- default=False,
- action="store_true",
- help="Promote the image tag using semver",
- )
- build = subs.add_parser("build", help="Build the app image")
- test = subs.add_parser("test", help="Test the app image")
- test.add_argument("--dirty", default=False, action="store_true", help="Mount current working tree")
- run = subs.add_parser("run", help="Run the app image")
- run.add_argument("--it", default=False, action="store_true", help="Run in interactive mode")
- run.add_argument("--script", default="", help="Script to run")
- run.add_argument("--dirty", default=False, action="store_true", help="Mount current working tree")
- for sub in [build, test, run]:
- sub.add_argument(
- "--tag", default=None, help="The image tag to pass to build_image",
- )
- for sub in [build, test]:
- sub.add_argument(
- "--push",
- default=False,
- action="store_true",
- help="Push the image to the artifact registry",
- )
- for sub in [pull, run]:
- sub.add_argument(
- "--build",
- default=False,
- action="store_true",
- help="Build the image before running",
- )
- ns, args = parser.parse_known_args()
- nsargs = vars(ns)
- if len(args):
- nsargs["args"] = args
- command = nsargs.pop("command")
- func = {
- "bump": get_version_bump,
- "pull": pull_base_image,
- "build": build_image,
- "test": test_image,
- "run": run_image,
- }
- kwargs = {} if command == "bump" else nsargs
- if command is None:
- parser.print_help()
- exit()
- func[command](**kwargs)
-
-
-if __name__ == "__main__":
- main()
diff --git a/flows/proc.py b/flows/proc.py
deleted file mode 100644
index 1c4b74594..000000000
--- a/flows/proc.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-import io
-import logging
-from subprocess import PIPE, STDOUT, Popen
-from typing import Any, Dict, List, Optional, Union
-
-logging.basicConfig(level=logging.INFO)
-LOG = logging.getLogger("proc")
-
-
-class Proc(Popen):
- """
- An opinionated Popen with an execute method
- to mirror communicate that handles input as strings,
- supports early return, and logs as the process runs.
- Also retain stdout and stderr as a list of strings
- for downstream access.
- """
-
- def __init__(
- self,
- *args,
- stdin=PIPE,
- stdout=PIPE,
- stderr=STDOUT,
- text=True,
- **kwargs,
- ):
- super().__init__(
- *args,
- stdin=stdin,
- stdout=stdout,
- stderr=stderr,
- text=text,
- **kwargs,
- )
- self._stderr = stderr
- # squelch the static type checkers that
- # see these pipes as None since we're using
- # PIPEs for everything
- self.stdin: io.TextIOWrapper
- self.stdout: io.TextIOWrapper
- self.stderr: io.TextIOWrapper
-
- def execute(
- self,
- *,
- inputs: Optional[str] = None,
- ) -> None:
- """
- Like Popen.communicate but tail output
-
- Parameters
- ----------
- inputs : str
- a command to pass to the subprocess
-
- """
- if isinstance(self.args, list):
- LOG.info(" ".join(map(str, self.args)))
- else:
- LOG.info(self.args)
-
- streams = [("stdout", "stdout"), ("stderr", "stderr")]
- if self._stderr == STDOUT:
- streams = [("stdout", "stream")]
- with self:
- try:
- if inputs is not None:
- self.stdin.write(inputs)
- self.stdin.close()
- for attr, stream in streams:
- for line in getattr(self, attr):
- LOG.info(f"{stream}: {line.rstrip()}")
- except Exception:
- self.kill()
diff --git a/flows/report.py b/flows/report.py
deleted file mode 100644
index 3b426f18f..000000000
--- a/flows/report.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-import os
-import json
-from dataclasses import dataclass, asdict
-from pathlib import Path
-
-
-@dataclass
-class PDB:
- two_char_code: str
- pdb_id: str
- ingest: int
- report: int
- entry: int
- num_holo: int
- num_apo: int
- num_system: int
-
-
-def get_pdb_data(base: str, pdb_dir: str) -> PDB:
- two_char_code = pdb_dir[-3:-1]
- pdb_id = pdb_dir[-4:]
- entry_dir = f"{base}/entries/{two_char_code}"
- num_holo = 0
- num_apo = 0
- num_system = 0
- entry = int(os.path.exists(f"{entry_dir}/{pdb_id}.json"))
- if entry:
- with open(f"{entry_dir}/{pdb_id}.json") as f:
- contents = json.load(f)
- num_system = len(contents["systems"])
- for chain in contents.get("chains", {}).values():
- if chain.get("holo"):
- num_holo += 1
- else:
- num_apo += 1
- return PDB(
- two_char_code=two_char_code,
- pdb_id=pdb_id,
- ingest=1,
- report=int(os.path.exists(f"{base}/reports/{two_char_code}/{pdb_id}/{pdb_id}_validation.xml.gz")),
- entry=entry,
- num_holo=num_holo,
- num_apo=num_apo,
- num_system=num_system,
- )
-
-
-def main(upload: bool = False):
- import pandas as pd
-
- plinder_mount = os.getenv("PLINDER_MOUNT")
- plinder_release = os.getenv("PLINDER_RELEASE")
- base = f"{plinder_mount}/{plinder_release}"
- total_cifs = 0
- total_reports = 0
- Path("reports").mkdir(exist_ok=True)
- pdbs = []
- fails = []
- for i, two_char_code in enumerate(sorted(os.listdir(f"{base}/ingest"))):
- if not i % 25:
- print(i, end=" ", flush=True)
- pdbs.extend([
- get_pdb_data(base, pdb_dir) for pdb_dir in
- os.listdir(f"{base}/ingest/{two_char_code}")
- ])
- fail_log = f"{base}/entries/{two_char_code}/failures.csv"
- if os.path.exists(fail_log):
- fails.append(pd.read_csv(fail_log))
- pdbs = pd.DataFrame([asdict(pdb) for pdb in pdbs])
- failures = pd.concat(fails).drop_duplicates(subset="pdb_id", keep="last").reset_index(drop=True)
- pdbs.to_csv("reports/pdbs.csv", index=False)
- failures.to_csv("reports/failures.csv", index=False)
- if upload:
- import gcs
-
- gcs.upload_report_from_file("reports/pdbs.csv")
- gcs.upload_report_from_file("reports/failures.csv")
-
- # print
- total_cifs = len(pdbs.index)
- total_reports = pdbs["report"].sum()
- total_entries = pdbs["entry"].sum()
- total_systems = pdbs["num_system"].sum()
- total_holo = pdbs["num_holo"].sum()
- total_apo = pdbs["num_apo"].sum()
- missing_entries = total_cifs - total_entries
- failed_entries = len(failures.index)
- msg_counts = failures["error"].value_counts()
- print(f"""\
-total mmcifs : {total_cifs}
-total reports : {total_reports}
-total entries : {total_entries}
-total systems : {total_systems}
-total holo chains : {total_holo}
-total apo chains : {total_apo}
-missing entries : {missing_entries}
-failed entries : {failed_entries}
-most common failure : {msg_counts.iloc[0]}
-
-CSVs saved to reports/ directory for further analysis
-""")
- return {
- "pdbs": pdbs,
- "failures": failures,
- }
-
-
-if __name__ == "__main__":
- main()
diff --git a/flows/split_eval.py b/flows/split_eval.py
deleted file mode 100644
index 7988f6981..000000000
--- a/flows/split_eval.py
+++ /dev/null
@@ -1,163 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-
-from __future__ import annotations
-
-from metaflow import FlowSpec, Parameter, kubernetes, environment, step, retry
-
-
-MOUNT = "/plinder"
-K8S = dict(
- cpu=1,
- image="us-east1-docker.pkg.dev/vantai-analysis/metaflow/plinder:v0.1.3-41-gd139d52b-dirty",
- node_selector={
- "topology.kubernetes.io/zone": "us-east1-b",
- },
- persistent_volume_claims={
- "plinder-data-gen-pvc": MOUNT,
- },
-)
-ENV = dict(
- vars=dict(
- PLINDER_MOUNT=MOUNT,
- PLINDER_RELEASE="2024-06",
- PLINDER_ITERATION="",
- )
-)
-LARGE_MEM = dict(
- cpu=7,
- memory=360000,
- tolerations=[
- dict(
- effect="NoSchedule",
- key="machine_type",
- value="n1-custom-380",
- )
- ]
-)
-WORKSTATION = dict(cpu=14, memory=14000)
-PROTEIN_LEAKAGE = dict(
- cpu=10,
- memory=40000,
-)
-LIGAND_LEAKAGE = dict(
- cpu=4,
- memory=10000,
-)
-
-
-class PlinderSplitEvalFlow(FlowSpec):
- config_file = Parameter("config_file", required=True)
-
- @kubernetes(**K8S)
- @environment(**ENV)
- @retry
- @step
- def start(self):
- from plinder.core.utils import gcs
- from plinder.data.pipeline.config import get_config
- from plinder.data.pipeline.pipeline import IngestPipeline
-
- assert isinstance(self.config_file, str)
- if not self.config_file.startswith("gs:"):
- raise ValueError("--config_file must be a gs:// path")
- print(f"started split eval run with config: {self.config_file}")
- contents = gcs.download_as_str(gcs_path=self.config_file, bucket_name="plinder-collab-bucket")
- self.pipeline = IngestPipeline(conf=get_config(config_contents=contents))
- self.next(self.make_mmp_index)
-
- @kubernetes(**{**K8S, **WORKSTATION})
- @environment(**ENV)
- @retry
- @step
- def make_mmp_index(self):
- self.pipeline.make_mmp_index()
- self.next(self.scatter_make_splits)
-
- @kubernetes(**K8S)
- @environment(**ENV)
- @retry
- @step
- def scatter_make_splits(self):
- self.chunks = self.pipeline.scatter_make_splits()
- self.next(self.make_splits, foreach="chunks")
-
- @kubernetes(**{**K8S, **LARGE_MEM})
- @environment(**ENV)
- @retry
- @step
- def make_splits(self):
- self.pipeline.make_splits(self.input)
- self.next(self.join_make_splits)
-
- @kubernetes(**K8S)
- @environment(**ENV)
- @retry
- @step
- def join_make_splits(self, inputs):
- self.pipeline = inputs[0].pipeline
- self.merge_artifacts(inputs, exclude=["chunks"])
- self.next(self.end)
-
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def scatter_compute_ligand_leakage(self):
- # self.chunks = self.pipeline.scatter_compute_ligand_leakage()
- # self.next(self.compute_ligand_leakage, foreach="chunks")
- #
- # @kubernetes(**{**K8S, **LIGAND_LEAKAGE})
- # @environment(**ENV)
- # @retry
- # @step
- # def compute_ligand_leakage(self):
- # self.pipeline.compute_ligand_leakage(self.input)
- # self.next(self.join_compute_ligand_leakage)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def join_compute_ligand_leakage(self, inputs):
- # self.pipeline = inputs[0].pipeline
- # self.merge_artifacts(inputs, exclude=["chunks"])
- # self.next(self.scatter_compute_protein_leakage)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def scatter_compute_protein_leakage(self):
- # self.chunks = self.pipeline.scatter_compute_protein_leakage()
- # self.next(self.compute_protein_leakage, foreach="chunks")
- #
- # @kubernetes(**{**K8S, **PROTEIN_LEAKAGE})
- # @environment(**ENV)
- # @retry
- # @step
- # def compute_protein_leakage(self):
- # self.pipeline.compute_protein_leakage(self.input)
- # self.next(self.join_compute_protein_leakage)
- #
- # @kubernetes(**K8S)
- # @environment(**ENV)
- # @retry
- # @step
- # def join_compute_protein_leakage(self, inputs):
- # self.pipeline = inputs[0].pipeline
- # self.merge_artifacts(inputs, exclude=["chunks", "run_leakage"])
- # self.next(self.end)
-
- @kubernetes(**K8S)
- @environment(**ENV)
- @retry
- @step
- def end(self):
- print("finished split eval run with:")
- print(f"pipeline config: {self.config_file}")
- print(f"split config dir: {self.pipeline.cfg.scatter.split_config_dir}")
-
-
-if __name__ == "__main__":
- PlinderSplitEvalFlow()
diff --git a/mypy.ini b/mypy.ini
deleted file mode 100644
index 006ff07a6..000000000
--- a/mypy.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[mypy]
-strict = True
-ignore_missing_imports = True
-disallow_untyped_decorators = False
-
-[mypy-plinder._version]
-ignore_errors = True
diff --git a/notebooks/archive/custom_temporal_split.ipynb b/notebooks/archive/custom_temporal_split.ipynb
new file mode 100644
index 000000000..93f37a67e
--- /dev/null
+++ b/notebooks/archive/custom_temporal_split.ipynb
@@ -0,0 +1,193 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Archived custom temporal split\n",
+ "\n",
+ "PLINDER publishes annotations and representative-cover assignments rather than one mandatory train/test split. This example builds a small, reproducible split table with a release-date cutoff and a ligand-family separation rule."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "\n",
+ "os.environ.setdefault(\"PLINDER_RELEASE\", \"2026-07\")\n",
+ "os.environ.setdefault(\"PLINDER_RELEASE_NUMBER\", \"1\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "\n",
+ "from plinder.core import query_table"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Select the candidate systems\n",
+ "\n",
+ "The annotation table has one row per ligand. Restricting this example to systems with one proper ligand gives one row per system. Entry release dates are stored once in `entry_metadata`; requesting the date selects that table automatically. The pocket-residue and interaction bounds are example statistical criteria; choose bounds suited to the intended evaluation."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "cluster_col = (\n",
+ " \"tanimoto_similarity_ecfp4_1024__70__ligand__set_cover\"\n",
+ ")\n",
+ "columns = [\n",
+ " \"system_id\",\n",
+ " \"entry_pdb_id\",\n",
+ " \"ligand_id\",\n",
+ " \"ligand_unique_ccd_code\",\n",
+ " \"system_pass_validation_criteria\",\n",
+ " \"system_proper_num_pocket_residues\",\n",
+ " \"system_proper_num_interactions\",\n",
+ " \"entry_release_date\",\n",
+ " cluster_col,\n",
+ "]\n",
+ "systems = query_table(\n",
+ " \"annotation\",\n",
+ " columns=columns,\n",
+ " filters=[\n",
+ " (\"ligand_is_proper\", \"==\", True),\n",
+ " (\"system_proper_num_ligand_chains\", \"==\", 1),\n",
+ " (\"system_proper_num_pocket_residues\", \">=\", 5),\n",
+ " (\"system_proper_num_pocket_residues\", \"<=\", 100),\n",
+ " (\"system_proper_num_interactions\", \">=\", 3),\n",
+ " ],\n",
+ ")\n",
+ "systems[\"entry_release_date\"] = pd.to_datetime(\n",
+ " systems[\"entry_release_date\"]\n",
+ ")\n",
+ "assert not systems[\"system_id\"].duplicated().any()\n",
+ "systems.shape"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Keep only ligand families that are entirely post-cutoff\n",
+ "\n",
+ "A system is eligible for the test set only when it was released after the cutoff and no pre-cutoff candidate has the same 70% Tanimoto set-cover label. Post-cutoff systems in mixed families, and systems without a cover label, are marked `removed`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "cutoff = pd.Timestamp(\"2021-09-30\")\n",
+ "is_post_cutoff = systems[\"entry_release_date\"] > cutoff\n",
+ "is_train_period = systems[\"entry_release_date\"].le(cutoff)\n",
+ "cluster_has_pre_cutoff = (\n",
+ " is_train_period\n",
+ " .groupby(systems[cluster_col], dropna=False)\n",
+ " .transform(\"any\")\n",
+ ")\n",
+ "is_pure_post_cutoff = (\n",
+ " is_post_cutoff\n",
+ " & systems[cluster_col].notna()\n",
+ " & ~cluster_has_pre_cutoff\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "systems[\"split\"] = \"removed\"\n",
+ "systems.loc[is_train_period, \"split\"] = \"train\"\n",
+ "systems.loc[is_pure_post_cutoff, \"split\"] = \"test\"\n",
+ "systems[\"split\"].value_counts()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Check the two conditions directly: test systems are post-cutoff, and their published ligand-family labels do not occur in training."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "test_rows = systems[systems[\"split\"] == \"test\"]\n",
+ "train_clusters = set(\n",
+ " systems.loc[systems[\"split\"] == \"train\", cluster_col].dropna()\n",
+ ")\n",
+ "test_clusters = set(test_rows[cluster_col].dropna())\n",
+ "assert (test_rows[\"entry_release_date\"] > cutoff).all()\n",
+ "assert systems.loc[systems[\"split\"] == \"train\", \"entry_release_date\"].le(cutoff).all()\n",
+ "assert train_clusters.isdisjoint(test_clusters)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Create the compact table expected by downstream code. Additional columns can be retained for auditing."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "split_table = systems[[\"system_id\", \"split\"]].copy()\n",
+ "split_table.head()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "A set-cover label groups each member with a chosen representative; it is not a transitive similarity component. This recipe prevents shared published labels across train and test, but does not prove that every cross-split ligand pair is below 70% Tanimoto. Use the all-vs-all ligand scores when that stricter pairwise guarantee is required. The same pattern can combine ligand, pocket, and interface cover labels depending on the leakage definition."
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.12"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/examples/mlsb_challenge.md b/notebooks/archive/mlsb_challenge_2024.md
similarity index 99%
rename from docs/examples/mlsb_challenge.md
rename to notebooks/archive/mlsb_challenge_2024.md
index 160d05388..9530004ae 100644
--- a/docs/examples/mlsb_challenge.md
+++ b/notebooks/archive/mlsb_challenge_2024.md
@@ -1,4 +1,4 @@
-# MLSB/P(L)INDER Challenge: Overview and details
+# Archived MLSB/P(L)INDER Challenge: Overview and details
## Objectives
diff --git a/pyproject.toml b/pyproject.toml
index 2d415714e..bfef683e5 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -2,29 +2,23 @@
name = "plinder"
dynamic = ["version"]
dependencies = [
- "biotite >= 1.0",
+ "biotite >= 1.2",
"numpy",
+ "threadpoolctl>=3.6",
"pandas",
- "typing_extensions",
"pydantic",
"tqdm",
- "plotly",
- "nbformat",
- "gemmi",
- "rdkit>=2024.03.6",
+ "peppr>=0.13",
+ "voronotalt>=1.1",
+ "rdkit>=2025.09.1",
"pyarrow",
"omegaconf",
- "mmcif",
- "eval_type_backport",
- "posebusters",
- "duckdb",
+ "duckdb>=1.5",
"cloudpathlib>=0.25,<0.26",
- "mols2grid",
- "six",
]
-description = "PLINDER: The Protein-Ligand INteraction Dataset and Evaluation Resource"
+description = "PLINDER: Protein & Ligand INteraction Dataset and Evaluation Resource"
readme = "README.md"
-requires-python = ">=3.10"
+requires-python = ">=3.12"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: Apache Software License",
@@ -37,14 +31,13 @@ Issues = "https://github.com/plinder-org/plinder/issues"
[project.scripts]
plinder_download = "plinder.core.index.utils:download_plinder_cmd"
-plinder_eval = "plinder.eval.docking.write_scores:evaluate_cmd"
-plinder_stratify = "plinder.eval.docking.stratify_test_set:stratify_cmd"
-plinder_plot = "plinder.eval.docking.make_plots:plot_cmd"
+plinder_eval = "plinder.eval.cli:main"
+plinder_prepare_release = "plinder.data.pipeline.public_release:main"
[project.optional-dependencies]
-data = ["google-cloud-storage", "gcsfs"]
+data = ["google-cloud-storage", "gcsfs", "numba"]
lint = [
- "ruff == 0.1.2",
+ "ruff == 0.9.4",
"pre-commit == 2.21.0",
]
test = [
@@ -52,11 +45,12 @@ test = [
"pytest == 7.2.0",
"pytest-cov == 4.0.0",
"pytest-xdist == 3.6.1",
+ "tomli>=2",
"build",
"setuptools_scm[toml]",
]
type = [
- "mypy==1.2.0",
+ "mypy==1.18.2",
"cloudpathlib>=0.25,<0.26",
"types-PyYAML",
"types-requests",
@@ -67,6 +61,9 @@ dev = [
loader = [
"torch",
]
+eval = [
+ "posebusters>=0.6.5",
+]
plots = [
"matplotlib",
"seaborn",
@@ -75,7 +72,6 @@ plots = [
"scipy",
]
docs = [
- "google-cloud-storage",
"itables",
"jupyter-sphinx",
"jupyterlab_myst",
@@ -92,6 +88,32 @@ docs = [
"matplotlib",
]
+# Not published to PyPI (includes git-only packages); installed by default with
+# `uv sync`. This is the complete development and CI environment.
+[dependency-groups]
+dev = [
+ "plinder[dev,eval,loader,plots]",
+ "networkit>11.0",
+ "tabulate",
+ "pdb-validation",
+ "mmpdb",
+ "semver",
+]
+
+[tool.uv.sources]
+pdb-validation = { git = "https://git.scicore.unibas.ch/schwede/ligand-validation.git" }
+mmpdb = { git = "https://github.com/rdkit/mmpdb.git" }
+torch = [{ index = "pytorch-cpu", marker = "sys_platform == 'linux'" }]
+
+[tool.uv]
+# networkit source builds need CMake; require a published wheel.
+no-build-package = ["networkit"]
+
+[[tool.uv.index]]
+name = "pytorch-cpu"
+url = "https://download.pytorch.org/whl/cpu"
+explicit = true
+
[build-system]
build-backend = "setuptools.build_meta"
requires = [
@@ -112,11 +134,14 @@ namespaces = false
plinder = [
"**.yaml",
"**.tsv",
- "plinder/data/utils/annotations/static_files/artifacts_badlist.csv",
+ "plinder/data/annotations/static_files/*",
]
[tool.ruff]
line-length = 88
+preview = false
+
+[tool.ruff.lint]
select = [
"F",
"I",
@@ -125,15 +150,29 @@ ignore = [
"E",
"W",
]
-preview = true
-[tool.ruff.flake8-tidy-imports]
+[tool.ruff.lint.flake8-tidy-imports]
ban-relative-imports = "all"
[tool.mypy]
ignore_missing_imports = true
strict = true
disallow_untyped_decorators = false
+untyped_calls_exclude = ["pyarrow"]
+follow_imports_for_stubs = true
+
+[[tool.mypy.overrides]]
+module = ["rdkit", "rdkit.*"]
+follow_imports = "skip"
+
+[[tool.mypy.overrides]]
+module = ["pyarrow", "pyarrow.*"]
+follow_imports = "skip"
+
+[[tool.mypy.overrides]]
+module = "plinder.core.loader.dataset"
+# Torch is an optional dependency and is absent from the lightweight type-check job.
+disallow_subclassing_any = false
[[tool.mypy.overrides]]
module = "plinder._version"
diff --git a/requirements_data.txt b/requirements_data.txt
deleted file mode 100644
index ef7f6244d..000000000
--- a/requirements_data.txt
+++ /dev/null
@@ -1,6 +0,0 @@
---only-binary=networkit
- networkit > 11.0
- tabulate
- pdb-validation @ git+https://git.scicore.unibas.ch/schwede/ligand-validation.git
- mmpdb @ git+https://github.com/rdkit/mmpdb.git
- https://download.pytorch.org/whl/cpu/torch-2.5.1%2Bcpu-cp312-cp312-linux_x86_64.whl#sha256=4856f9d6925121d13c2df07aa7580b767f449dfe71ae5acde9c27535d5da4840
diff --git a/scripts/build_r2_manifest.py b/scripts/build_r2_manifest.py
deleted file mode 100644
index 6627a57cc..000000000
--- a/scripts/build_r2_manifest.py
+++ /dev/null
@@ -1,51 +0,0 @@
-"""Build the release's HTTP listing from audited GCS metadata, without cloud I/O."""
-
-import argparse
-import base64
-import gzip
-import hashlib
-import json
-from pathlib import Path
-
-
-def build(inventory: Path, destination: Path) -> int:
- shards = json.loads((inventory / "manifest-files.json").read_text())
- records = {}
- for shard in shards:
- path = (inventory / shard["path"]).resolve()
- if not path.is_relative_to(inventory.resolve()):
- raise ValueError("Invalid inventory path")
- if hashlib.sha256(path.read_bytes()).hexdigest() != shard["sha256"]:
- raise ValueError("Inventory checksum mismatch")
- with gzip.open(path, "rt") as stream:
- for line in stream:
- r = json.loads(line)
- if not r["name"].startswith("2024-06/v2/"):
- raise ValueError("Unexpected release")
- key = r["name"][len("2024-06/v2/") :]
- if key.endswith("/"):
- continue
- if (
- not key
- or "\\" in key
- or any(p in {"", ".", ".."} for p in key.split("/"))
- or key in records
- ):
- raise ValueError("Invalid or duplicate object key")
- size = int(r["size"])
- if size < 0 or len(base64.b64decode(r["md5Hash"], validate=True)) != 16:
- raise ValueError("Invalid object metadata")
- records[key] = {"key": key, "size": size, "md5": r["md5Hash"]}
- destination.parent.mkdir(parents=True, exist_ok=True)
- with gzip.open(destination, "wt") as stream:
- for key in sorted(records):
- stream.write(json.dumps(records[key], separators=(",", ":")) + "\n")
- return len(records)
-
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description=__doc__)
- parser.add_argument("inventory", type=Path)
- parser.add_argument("destination", type=Path)
- args = parser.parse_args()
- print(build(args.inventory, args.destination))
diff --git a/scripts/prepare_ingest_reference_data.py b/scripts/prepare_ingest_reference_data.py
new file mode 100644
index 000000000..99c5b5fb4
--- /dev/null
+++ b/scripts/prepare_ingest_reference_data.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Prepare shared ingest reference data on a machine with internet access."""
+
+from __future__ import annotations
+
+import argparse
+import os
+import time
+from pathlib import Path
+
+from plinder.data.pipeline.tasks import download_alternative_datasets
+
+
+def _is_truthy(value: str | None) -> bool:
+ return value is not None and value.lower() in {"1", "true", "yes", "on"}
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument("output_root", type=Path)
+ parser.add_argument("--threads", type=int, default=4)
+ parser.add_argument("--force", action="store_true")
+ args = parser.parse_args()
+
+ if _is_truthy(os.environ.get("PLINDER_OFFLINE")) or _is_truthy(
+ os.environ.get("PLINDER_OFFLINE_MODE")
+ ):
+ raise RuntimeError(
+ "reference preparation requires internet access; unset "
+ "PLINDER_OFFLINE and PLINDER_OFFLINE_MODE"
+ )
+
+ started = time.perf_counter()
+ download_alternative_datasets(
+ data_dir=args.output_root.resolve(),
+ threads=args.threads,
+ force_update=args.force,
+ )
+ print(
+ f"prepared reference data in {time.perf_counter() - started:.1f}s "
+ f"under {args.output_root.resolve() / 'dbs'}"
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/slurm/README.md b/scripts/slurm/README.md
new file mode 100644
index 000000000..545b0acbc
--- /dev/null
+++ b/scripts/slurm/README.md
@@ -0,0 +1,645 @@
+# Batched PDB ingest on Slurm
+
+The entry jobs read the managed NextGen mmCIF and validation archives directly.
+They do not stage inputs or create symlinks.
+
+Example ingest configurations are in [`configs/ingest`](configs/ingest).
+
+Set site-specific locations in the submission environment:
+
+```bash
+export PLINDER_ENV_ROOT=/path/to/plinder/environment
+export PLINDER_PDB_NEXTGEN_ROOT=/path/to/pdb_nextgen/data/entries/divided
+export PLINDER_VALIDATION_ROOT=/path/to/validation_reports
+export OUTPUT_ROOT=/path/to/ingest-output
+```
+
+Prepare shared reference data once on a node with internet access:
+
+```bash
+python scripts/prepare_ingest_reference_data.py "${OUTPUT_ROOT}" --threads 4
+```
+
+If the BindingDB TSV was downloaded but its measurement and candidate Parquet
+files still need to be built, it can be transformed on an offline Slurm node:
+
+```bash
+sbatch \
+ --output="${OUTPUT_ROOT}/logs/transform-bindingdb-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT \
+ scripts/slurm/transform_bindingdb.sbatch "${OUTPUT_ROOT}"
+```
+
+For a full release, first create a size-balanced manifest. This scans only local
+metadata and does not download structure or validation files:
+
+```bash
+python -m plinder.data.pipeline.ingest manifest \
+ "${PLINDER_PDB_NEXTGEN_ROOT}" \
+ "${PLINDER_VALIDATION_ROOT}" \
+ "${OUTPUT_ROOT}/manifests/pdb-nextgen-all.txt" \
+ --batch-size 100 --threads 8
+```
+
+The neighboring `.txt.json` report contains the exact entry and batch counts,
+compressed-CIF size distribution, and largest inputs; `.txt.entries.tsv` retains
+the full size inventory for sampling and runtime analysis. Add `--check-validation`
+only when an up-front XML availability audit is worth the extra metadata I/O.
+Ordinary ingest records exact XML availability per entry. Each contiguous 100-line
+slice is balanced by compressed CIF bytes. Entries within each slice run smallest
+first, so a 30-minute timeout leaves the expensive tail for the retry rather than
+discarding time before many small entries are completed.
+
+Submit the complete one-CPU array, replacing `LAST_BATCH_INDEX` with
+`batch_count - 1` from the report. No array throttle is imposed here; Slurm can
+use all concurrency allowed by available capacity and fair-share:
+
+```bash
+sbatch \
+ --array=0-LAST_BATCH_INDEX \
+ --output="${OUTPUT_ROOT}/logs/ingest-batch-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_PDB_NEXTGEN_ROOT,PLINDER_VALIDATION_ROOT \
+ scripts/slurm/ingest_pdb_batch.sbatch \
+ "${OUTPUT_ROOT}/manifests/pdb-nextgen-all.txt" "${OUTPUT_ROOT}" 100
+```
+
+The batch runner records progress atomically after every PDB ID. Resubmitting the
+same array skips entries whose per-entry metrics and outputs are complete. This
+makes it safe to retry the full array under the longer QoS; normally only timed-out
+or failed entries do work:
+
+```bash
+sbatch \
+ --qos=6hours \
+ --mem=64G \
+ --array=0-LAST_BATCH_INDEX \
+ --output="${OUTPUT_ROOT}/logs/ingest-batch-retry-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_PDB_NEXTGEN_ROOT,PLINDER_VALIDATION_ROOT \
+ scripts/slurm/ingest_pdb_batch.sbatch \
+ "${OUTPUT_ROOT}/manifests/pdb-nextgen-all.txt" "${OUTPUT_ROOT}" 100
+```
+
+Both array passes force both Plinder offline-mode variables. A missing source CIF
+or required shared reference fails the affected entry without a network request.
+Per-entry timings are written to sharded `metrics/ingest-one-.json` files;
+whole-process resource use is written once per array task to
+`metrics/ingest-batch--.time-v.txt`.
+
+## Collate the V3 annotation index
+
+After entry ingest is complete, freeze the two-character code list, inventory
+the exact per-entry outputs in parallel, and atomically merge the inventories.
+The plan fails if any materialized entry is missing an annotation, chain,
+biological-assembly-chain, source, or ligand Parquet:
+
+```bash
+sbatch \
+ --output="${OUTPUT_ROOT}/logs/collate-plan-start-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/collate_v3_shards.sbatch plan-start "${OUTPUT_ROOT}"
+
+# Read code_count from index/.staging/collation/plan-build.json. With a
+# batch size of four, LAST_PLAN_BATCH_INDEX is ceil(code_count / 4) - 1.
+sbatch \
+ --array=0-LAST_PLAN_BATCH_INDEX --cpus-per-task=4 --mem=8G \
+ --output="${OUTPUT_ROOT}/logs/collate-plan-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/collate_v3_shards.sbatch plan-shard "${OUTPUT_ROOT}" 4
+
+sbatch \
+ --dependency=afterok:PLAN_ARRAY_JOB_ID \
+ --output="${OUTPUT_ROOT}/logs/collate-plan-finish-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/collate_v3_shards.sbatch plan-finish "${OUTPUT_ROOT}"
+```
+
+When augmenting an existing ligand release with interface-only ingest, set
+`PLINDER_COLLATE_INTERFACES_ONLY=true` on `plan-start`. This preserves the
+installed `index/annotation_table.parquet` byte-for-byte and collates only the
+shared chain, entry, source, and interface tables. The setting is frozen in the
+plan, so later stages do not need the environment variable.
+
+Read `index/.staging/collation/plan.json` after that job succeeds. With a
+batch size of four, set `LAST_CODE_BATCH_INDEX` to
+`ceil(code_count / 4) - 1`, then submit the unthrottled shard array:
+
+```bash
+sbatch \
+ --array=0-LAST_CODE_BATCH_INDEX \
+ --output="${OUTPUT_ROOT}/logs/collate-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/collate_v3_shards.sbatch shard "${OUTPUT_ROOT}" 4
+```
+
+Each shard is atomic and resumable. Once the array succeeds, merge and validate
+the planned shards with a larger single task:
+
+```bash
+sbatch \
+ --qos=6hours \
+ --cpus-per-task=4 --mem=48G \
+ --output="${OUTPUT_ROOT}/logs/collate-finalize-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT,PLINDER_COLLATE_MEMORY_LIMIT=40GB \
+ scripts/slurm/collate_v3_shards.sbatch finalize "${OUTPUT_ROOT}"
+```
+
+Finalization writes the local `index/*.parquet` files only after validating row
+counts, keys, cross-table references, and ligand scoreability. Each shard
+verifies its raw inputs before producing a frozen output; finalization validates
+and merges those outputs without rescanning every per-entry source file. It
+performs no upload or external release operation.
+
+## Build publishable protein-search shards
+
+Protein scoring uses the union of protein chains that are holo ligand receptors
+or members of `index/interface_annotation_table.parquet`; unrelated chains
+retained only for biological-unit context are not searched. Freeze that query
+universe before starting any arrays:
+
+```bash
+python -m plinder.data.pipeline.score plan "${OUTPUT_ROOT}" --max-seqs 10000
+```
+
+The resulting `manifests/protein_scoring_plan.json` gives `query_count` and
+`shard_count`. Both Foldseek and MMseqs searches are filtered by E-value and
+coverage, with the minimum sequence identity explicitly set to zero.
+
+Cache `pdb_seqres.txt.gz` on an online node and set `PLINDER_SEQRES_PATH` to it.
+Run `createdb` on a host with enough memory and fast access to the managed PDB
+tree; this reads the original NextGen divided mmCIF archive directly. The
+command derives a TSV of only the protein-containing PDB entries in the frozen
+plan, avoiding a recursive walk over the full archive:
+
+```bash
+python -m plinder.data.pipeline.score create-dbs "${OUTPUT_ROOT}" \
+ --cif-root "${PLINDER_PDB_NEXTGEN_ROOT}" \
+ --seqres-path "${PLINDER_SEQRES_PATH}" \
+ --threads 4
+```
+
+If the login host is memory-limited, run the same resumable operation on Slurm.
+Each backend is built and validated under node-local `/scratch`, then staged and
+swapped into shared storage. A retry reuses either backend whose installed
+`createdb` output already completed:
+
+```bash
+sbatch \
+ --qos=6hours --cpus-per-task=4 --mem=32G \
+ --output="${OUTPUT_ROOT}/logs/protein-create-dbs-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT,PLINDER_PDB_NEXTGEN_ROOT,PLINDER_SEQRES_PATH \
+ scripts/slurm/score_v3.sbatch create-dbs "${OUTPUT_ROOT}"
+```
+
+On Slurm, select the V3 protein chains, cluster the Foldseek and MMseqs targets
+at exactly 100% identity and 100% bidirectional coverage, and index the
+representative targets. This job is offline and uses node-local `/scratch` for
+all clustering and index working files:
+
+```bash
+sbatch \
+ --qos=6hours --cpus-per-task=16 --mem=128G \
+ --output="${OUTPUT_ROOT}/logs/protein-make-sub-dbs-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch make-sub-dbs "${OUTPUT_ROOT}"
+```
+
+The 10,000-hit search cap therefore applies to unique representatives rather
+than being consumed by identical chains. Foldseek's cluster search and the
+MMseqs expansion workflow both realign expanded members before conversion, so
+the resulting Parquets still contain chain-level scores and identifiers.
+
+Foldseek and MMseqs use separate arrays so their query-batch sizes can be tuned
+independently. Pilot before submitting the complete arrays. For a Foldseek
+batch size of 5,000, `LAST_FOLDSEEK_INDEX` is
+`ceil(query_count / 5000) - 1`:
+
+```bash
+sbatch \
+ --qos=6hours --array=0-LAST_FOLDSEEK_INDEX \
+ --cpus-per-task=128 --mem=128G \
+ --output="${OUTPUT_ROOT}/logs/protein-foldseek-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch search-foldseek "${OUTPUT_ROOT}" 5000
+
+sbatch \
+ --qos=30min --array=0-LAST_MMSEQS_INDEX \
+ --cpus-per-task=128 --mem=128G \
+ --output="${OUTPUT_ROOT}/logs/protein-mmseqs-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch search-mmseqs "${OUTPUT_ROOT}" 5000
+```
+
+Foldseek uses the longer QoS up front because its expanded hit sets and raw
+checkpoints are larger. For MMseqs, resubmit only incomplete batches with
+`--qos=6hours`; per-query raw checkpoints make those retries skip outputs
+already installed by the first pass.
+
+The Foldseek release output stores one scalar LDDT value per hit, not
+per-residue `lddtfull`. Full aligned strings remain generation intermediates;
+release shards retain only scalar search fields and compact pocket-relevant
+residue-number/identity mappings needed to reconstruct system and ligand scores.
+
+Mapping is separate from derived scoring so completed searches remain usable
+when downstream score generation needs retries. Each task owns one PDB
+two-character query shard, writes temporary per-query mappings only on
+node-local scratch, and atomically publishes one Parquet per available backend.
+With one shard per task, `LAST_SHARD_INDEX` is `shard_count - 1`:
+
+```bash
+sbatch \
+ --qos=30min --array=0-LAST_SHARD_INDEX --cpus-per-task=2 --mem=32G \
+ --output="${OUTPUT_ROOT}/logs/protein-map-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch map "${OUTPUT_ROOT}" 1
+
+# Pack each canonical ASU ligand once for bulk scoring and distribution.
+sbatch \
+ --qos=30min --array=0-LAST_LIGAND_PACK_INDEX --cpus-per-task=4 --mem=32G \
+ --output="${OUTPUT_ROOT}/logs/ligand-pack-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch pack-ligands "${OUTPUT_ROOT}" 50
+
+sbatch \
+ --output="${OUTPUT_ROOT}/logs/ligand-finalize-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch finalize-ligands "${OUTPUT_ROOT}"
+
+sbatch \
+ --output="${OUTPUT_ROOT}/logs/protein-finalize-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch finalize-alignments "${OUTPUT_ROOT}"
+```
+
+The same mapped protein alignments also drive protein-interface scoring. Plan
+one two-character query shard per array task, run the shards independently,
+and then publish the compact all-vs-all table:
+
+```bash
+sbatch \
+ --qos=30min --cpus-per-task=1 --mem=8G \
+ --output="${OUTPUT_ROOT}/logs/interface-score-plan-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch plan-interface-scores "${OUTPUT_ROOT}" 1
+
+# Read batch_count from manifests/interface_scoring_plan.json, then:
+sbatch \
+ --qos=30min --array=0-LAST_INTERFACE_INDEX --cpus-per-task=4 --mem=32G \
+ --output="${OUTPUT_ROOT}/logs/interface-score-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch score-interface-shards "${OUTPUT_ROOT}" 1
+
+sbatch \
+ --qos=6hours --cpus-per-task=8 --mem=64G \
+ --output="${OUTPUT_ROOT}/logs/interface-finalize-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT,PLINDER_DUCKDB_MEMORY_LIMIT=56GB \
+ scripts/slurm/score_v3.sbatch finalize-interface-scores "${OUTPUT_ROOT}"
+```
+
+Each winning direct or swapped chain assignment retains `iface1_qcov` and
+`iface2_qcov` before multiplication. They are the coverages of the query
+interface's canonical first and second chain, respectively, under that winning
+assignment. The release file
+`exports/interface_similarity_scores.parquet` contains the query and target interface
+IDs, both side coverages, and the final directional 0--100 similarity. Positive
+scores below the lowest clustering threshold are retained. Interface clustering
+uses the whole-interface `interface_qcov` product; the two side coverages remain
+available as score diagnostics but are not clustered separately.
+
+Derived per-ligand system scores are generation intermediates used for graph
+clustering, not release artifacts. Before scattering them, estimate work from
+the compact alignment hits and greedily spread expensive queries across fixed
+50-query batches within each two-character alignment shard:
+
+```bash
+sbatch \
+ --qos=6hours --cpus-per-task=4 --mem=32G \
+ --output="${OUTPUT_ROOT}/logs/protein-score-plan-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch plan-score-batches "${OUTPUT_ROOT}" 50
+
+# Read score_batch_count from manifests/protein_scoring_plan.json, then:
+sbatch \
+ --qos=30min --array=0-LAST_SCORE_INDEX --cpus-per-task=4 --mem=32G \
+ --output="${OUTPUT_ROOT}/logs/protein-score-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch score "${OUTPUT_ROOT}" 50
+```
+
+Query-system safety caps default to 30 protein receptor chains and 30 proper
+ligand chains. Larger holo systems remain available as targets. Override the
+query caps with `PLINDER_MAX_QUERY_PROTEIN_CHAINS` and
+`PLINDER_MAX_QUERY_PROPER_LIGAND_CHAINS` when planning.
+
+This first pass calculates only protein and pocket scores. For every proper,
+3D-scoreable ligand pair with positive pocket query coverage it also records a
+full-precision candidate row; it does not load an SDF or run shape alignment.
+Retry only any batches that exceed the 30-minute QoS with `--qos=6hours`.
+If a batch exceeds memory, freeze its still-missing PDB IDs into a Parquet with
+a unique `pdb_id` column and retry them independently:
+
+```bash
+export PLINDER_SCORE_PDB_MANIFEST="${OUTPUT_ROOT}/manifests/protein_scoring_retry.parquet"
+sbatch \
+ --qos=6hours --array=0-LAST_RETRY_INDEX --cpus-per-task=4 --mem=128G \
+ --output="${OUTPUT_ROOT}/logs/protein-score-pdb-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT,PLINDER_SCORE_PDB_MANIFEST \
+ scripts/slurm/score_v3.sbatch score-pdbs "${OUTPUT_ROOT}" 1
+```
+
+Each array task then owns one PDB and still reuses completed score checkpoints.
+
+After every protein-score batch has completed, first consolidate the per-PDB
+candidate checkpoints into two-character query shards. With a collation batch
+size of four, use `ceil(shard_count / 4) - 1` as
+`LAST_CANDIDATE_SHARD_INDEX`. This prevents the global planner from opening one
+small Parquet for every PDB entry:
+
+```bash
+sbatch \
+ --qos=30min --array=0-LAST_CANDIDATE_SHARD_INDEX --cpus-per-task=4 --mem=32G \
+ --output="${OUTPUT_ROOT}/logs/ligand-3d-candidates-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch collate-ligand-3d-candidates "${OUTPUT_ROOT}" 4
+```
+
+Then deduplicate the sharded candidate rows into canonical ASU ligand pairs,
+retain every pair with positive pocket coverage, and stream deterministic
+query-local batches ordered by ligand size:
+
+```bash
+sbatch \
+ --qos=6hours --cpus-per-task=4 --mem=32G \
+ --output="${OUTPUT_ROOT}/logs/ligand-3d-plan-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch plan-ligand-3d "${OUTPUT_ROOT}" 30000
+
+# Read ligand_3d_batch_count from protein_scoring_plan.json, then:
+sbatch \
+ --qos=30min --array=0-LAST_LIGAND_3D_INDEX --cpus-per-task=1 --mem=16G \
+ --output="${OUTPUT_ROOT}/logs/ligand-3d-score-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch score-ligand-3d "${OUTPUT_ROOT}" 30000
+```
+
+The pair scorer bulk-loads only the required canonical SDF records from the
+packed Parquets and calculates shape, color, and SuCOS once per unique directed
+ASU ligand pair. If any coarse batches fail, split only those batches into
+smaller, resumable retry units and require every retry before continuing:
+
+```bash
+sbatch \
+ --output="${OUTPUT_ROOT}/logs/ligand-3d-retry-plan-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch plan-ligand-3d-retries "${OUTPUT_ROOT}" 500
+
+# Read ligand_3d_retry_batch_count from protein_scoring_plan.json, then:
+sbatch \
+ --qos=6hours --array=0-LAST_LIGAND_3D_RETRY_INDEX \
+ --cpus-per-task=1 --mem=32G \
+ --output="${OUTPUT_ROOT}/logs/ligand-3d-retry-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch score-ligand-3d-retry "${OUTPUT_ROOT}" 500
+
+sbatch \
+ --output="${OUTPUT_ROOT}/logs/ligand-3d-retry-finalize-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch finalize-ligand-3d-retries "${OUTPUT_ROOT}"
+```
+
+Repartition the complete balanced outputs by query PDB shard before
+expanding them back to system-level rows. With a collation batch size of four,
+`LAST_LIGAND_3D_SHARD_INDEX` is
+`ceil(ligand_3d_query_shard_count / 4) - 1`:
+
+```bash
+sbatch \
+ --qos=30min --array=0-LAST_LIGAND_3D_SHARD_INDEX --cpus-per-task=4 --mem=32G \
+ --output="${OUTPUT_ROOT}/logs/ligand-3d-collate-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch collate-ligand-3d "${OUTPUT_ROOT}" 4
+
+sbatch \
+ --qos=30min --array=0-LAST_LIGAND_MERGE_INDEX --cpus-per-task=4 --mem=32G \
+ --output="${OUTPUT_ROOT}/logs/ligand-3d-merge-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch merge-ligand-3d "${OUTPUT_ROOT}" 50
+
+sbatch \
+ --qos=6hours --cpus-per-task=4 --mem=32G \
+ --output="${OUTPUT_ROOT}/logs/protein-score-finalize-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch finalize-scores "${OUTPUT_ROOT}"
+```
+
+The merge computes `sucos_shape_pocket_qcov` from full-precision pocket
+coverage before converting retained similarities to the 0โ100 integer schema.
+
+The complete ligand-pair score table is a release artifact. It retains
+`pocket_qcov`, `pocket_fident_qcov`, `pli_qcov`, and `sucos_shape` separately,
+including positive scores below the 30% clustering threshold. The combined
+SuCOS-pocket score can be derived by multiplying `sucos_shape` and
+`pocket_qcov`. Use the same query-shard array bound as ligand-3D collation,
+then validate and concatenate the shards:
+
+```bash
+sbatch \
+ --qos=30min --array=0-LAST_LIGAND_3D_SHARD_INDEX \
+ --cpus-per-task=4 --mem=32G \
+ --output="${OUTPUT_ROOT}/logs/ligand-similarity-export-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch export-ligand-similarity-shards "${OUTPUT_ROOT}" 4
+
+sbatch \
+ --qos=6hours --cpus-per-task=8 --mem=64G \
+ --output="${OUTPUT_ROOT}/logs/ligand-similarity-finalize-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch finalize-ligand-similarity-scores "${OUTPUT_ROOT}"
+```
+
+The default final path is `exports/ligand_similarity_scores.parquet`; set
+`PLINDER_LIGAND_SIMILARITY_DIR` and `PLINDER_LIGAND_SIMILARITY_OUTPUT` to
+override the temporary shard directory or final release location.
+
+Targeted collation repairs deliberately leave `index/collation.json` in
+`requires_downstream_repair` state. After repairing fingerprints and affected
+score shards, rerun the clustering and final-index sequence below. Finalization
+rejects cluster artifacts that do not exactly cover the current eligible ligand
+universe and marks the repair complete after assembling the final index tables.
+
+Build internal connectivity partitions and representative set covers only after
+score finalization.
+The planning job reports exact array counts for the default metrics and the
+30, 50, 70, 90, and 100 thresholds:
+
+```bash
+sbatch \
+ --qos=30min --cpus-per-task=1 --mem=8G \
+ --output="${OUTPUT_ROOT}/logs/cluster-plan-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch plan-clusters "${OUTPUT_ROOT}" 20
+```
+
+First read `symmetric_fragment_batch_count` from that log. Each task copies 20
+regular score shards to node-local scratch and hash-partitions canonical ligand
+pairs while retaining both directional maxima:
+
+```bash
+sbatch \
+ --qos=6hours --array=0-LAST_SYMMETRIC_FRAGMENT_INDEX \
+ --cpus-per-task=4 --mem=64G \
+ --output="${OUTPUT_ROOT}/logs/symmetric-fragment-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch symmetric-edge-fragments "${OUTPUT_ROOT}" 1
+
+sbatch \
+ --qos=6hours --array=0-LAST_SYMMETRIC_EDGE_INDEX \
+ --cpus-per-task=4 --mem=64G \
+ --output="${OUTPUT_ROOT}/logs/symmetric-edge-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch symmetric-edge-shards "${OUTPUT_ROOT}" 1
+```
+
+The second array takes the minimum of the two directional maxima. Pairs with
+only one stored direction retain that direction but have a null reciprocal
+score: public reciprocal-minimum clustering ignores them, while the optional
+directed cover can still use them. Then read
+`component_reduction_batch_count` from the plan and reduce one compact edge
+shard per task:
+
+```bash
+sbatch \
+ --qos=6hours --array=0-LAST_COMPONENT_REDUCTION_INDEX \
+ --cpus-per-task=4 --mem=64G \
+ --output="${OUTPUT_ROOT}/logs/component-reduction-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch component-reductions "${OUTPUT_ROOT}" 1
+
+sbatch \
+ --qos=6hours --cpus-per-task=8 --mem=128G \
+ --output="${OUTPUT_ROOT}/logs/component-merge-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch merge-components "${OUTPUT_ROOT}"
+```
+
+The merge publishes exact connected components of the reciprocal-minimum graph
+without retaining a full in-memory 30%-threshold graph. It also creates
+any-direction connectivity partitions used by the optional directed sampling
+cover. Finally, read `set_cover_batch_count` from the plan log and scatter one
+chemical metric/threshold per task. Skip this array when the count is zero,
+including for protein-interface clustering:
+
+```bash
+SET_COVER_JOB=$(sbatch --parsable \
+ --qos=6hours --array=0-LAST_SET_COVER_INDEX \
+ --cpus-per-task=8 --mem=128G \
+ --output="${OUTPUT_ROOT}/logs/set-cover-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch set-covers "${OUTPUT_ROOT}" 1)
+```
+
+Chemical set covers use deterministic greedy representative selection on
+reciprocal-minimum edges. Every member meets the threshold to its representative;
+two non-representative members need not meet it directly. Chemical similarity
+scores are symmetric.
+
+Run `directed-covers` with the
+`directed_cover_batch_count` from the plan. A centroid covers query ligand `Q`
+when `score(Q -> centroid)` meets the threshold. These labels are required by
+final index enrichment and the detailed assignments also support training-set
+sampling:
+
+```bash
+DIRECTED_COVER_JOB=$(sbatch --parsable \
+ --qos=6hours --array=0-LAST_DIRECTED_COVER_INDEX \
+ --cpus-per-task=8 --mem=128G \
+ --output="${OUTPUT_ROOT}/logs/directed-cover-%A-%a.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch directed-covers "${OUTPUT_ROOT}" 1)
+```
+Set comma-delimited `PLINDER_CLUSTER_METRICS` or
+`PLINDER_CLUSTER_THRESHOLDS` consistently on every clustering command to run a
+subset. Because Slurm itself treats commas inside `--export` as separators,
+define comma-delimited values in the submitting shell and export their names:
+
+```bash
+export PLINDER_CLUSTER_METRICS='pocket_qcov,pli_qcov'
+export PLINDER_CLUSTER_THRESHOLDS='100,90,70,50,30'
+sbatch \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT,PLINDER_CLUSTER_METRICS,PLINDER_CLUSTER_THRESHOLDS \
+ scripts/slurm/score_v3.sbatch plan-clusters "${OUTPUT_ROOT}" 1
+```
+
+Protein-interface clustering uses the same commands and thresholds in a
+separate namespace. Set these variables for every command in the sequence:
+
+```bash
+export PLINDER_CLUSTER_ENTITY_TYPE=interface
+export PLINDER_CLUSTER_METRICS='interface_qcov'
+export PLINDER_CLUSTER_THRESHOLDS='100,90,70,50,30'
+```
+
+The interface plan reads `interface_scores/shard=*.parquet`. Internal
+connectivity partitions are written below `interface_clusters/`; the
+directional centroid cover is written below `interface_sampling/`. Final index
+enrichment adds `interface_qcov__THRESHOLD__directed_set_cover` columns for
+whole-interface product scores. Component labels remain internal.
+The ligand and interface plans and artifacts never share cache paths.
+Run both entity sequences before `finalize-index`; finalization rejects a
+non-empty interface annotation table when its interface clusters are absent.
+
+After connectivity, set-cover, and directed-cover branches complete, validate every
+published artifact and write `ligand_clusters/stats.parquet` (or
+`interface_clusters/stats.parquet`) plus `stats.json`.
+This gate checks artifact coverage, duplicate and null labels, consistent ligand
+counts, and monotonic internal component counts across thresholds. Cover counts
+are reported but are not required to be monotonic. When the set-cover array was
+skipped, leave `SET_COVER_JOB` unset or empty:
+
+```bash
+STATS_JOB=$(sbatch --parsable \
+ --dependency="afterok:${SET_COVER_JOB:+${SET_COVER_JOB}:}${DIRECTED_COVER_JOB}" \
+ --qos=6hours --cpus-per-task=8 --mem=128G \
+ --output="${OUTPUT_ROOT}/logs/cluster-stats-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch cluster-stats "${OUTPUT_ROOT}")
+```
+
+Only after that audit succeeds, merge the ligand-level annotations and cluster
+IDs into the index. Cluster files are loaded incrementally and progress with an
+ETA is logged, avoiding a giant concatenated long-form table:
+
+```bash
+sbatch \
+ --dependency="afterok:${STATS_JOB}" \
+ --qos=6hours --cpus-per-task=8 --mem=128G \
+ --output="${OUTPUT_ROOT}/logs/finalize-index-%j.out" \
+ --export=ALL,PLINDER_ENV_ROOT,PLINDER_REPO_ROOT \
+ scripts/slurm/score_v3.sbatch finalize-index "${OUTPUT_ROOT}"
+```
+
+The release scoring artifacts are the two similarity tables in `exports/` and
+the validated alignment shards under
+`alignment_cigars/search_db=holo/alignment_type=*/shard=*.parquet`. Per-PDB raw
+search files and the other derived score datasets are generation intermediates;
+mapped per-PDB files exist only transiently on node-local scratch.
+
+## Separate the public release from working data
+
+Keep the completed ingest as the working directory. Build a sibling directory
+containing only the files used by the release API:
+
+```bash
+python -m plinder.data.pipeline.public_release \
+ /path/to/ingest_2026-09 /path/to/PLINDER-2026-09
+```
+
+The public directory includes the index tables, similarity tables, cover tables,
+ligand archives and scores, alignment CIGARs, and MMseqs/Foldseek search databases.
+It excludes raw alignments, score caches, scratch files, STEAM databases, and JSON
+files containing local paths. By default the files are hard-linked, so this adds
+almost no data storage but is not an independent copy: do not edit either tree's
+files in place. Pass `--copy` for an independent copy. After a working-release
+repair, rerun with `--replace` to refresh the public tree.
+
+Upload the public directory, not the working ingest. The Foldseek databases
+contain internal symlinks, so use `--no-ignore-symlinks` when syncing to GCS.
diff --git a/scripts/slurm/collate_v3_shards.sbatch b/scripts/slurm/collate_v3_shards.sbatch
new file mode 100755
index 000000000..29535eb03
--- /dev/null
+++ b/scripts/slurm/collate_v3_shards.sbatch
@@ -0,0 +1,103 @@
+#!/usr/bin/env bash
+#SBATCH --job-name=plinder-collate
+#SBATCH --partition=scicore,bigmem
+#SBATCH --qos=30min
+#SBATCH --cpus-per-task=2
+#SBATCH --mem=8G
+
+set -euo pipefail
+umask 002
+
+MODE=${1:-shard}
+case "${MODE}" in
+ plan|plan-start|plan-finish|finalize|repair)
+ DATA_DIR=${2:?'usage: sbatch collate_v3_shards.sbatch MODE DATA_DIR'}
+ BATCH_SIZE=0
+ ;;
+ plan-shard|shard)
+ DATA_DIR=${2:?'usage: sbatch collate_v3_shards.sbatch MODE DATA_DIR BATCH_SIZE'}
+ BATCH_SIZE=${3:?'usage: sbatch collate_v3_shards.sbatch shard DATA_DIR BATCH_SIZE'}
+ ;;
+ *)
+ # Preserve the original DATA_DIR BATCH_SIZE interface.
+ DATA_DIR=${1:?'usage: sbatch collate_v3_shards.sbatch DATA_DIR BATCH_SIZE'}
+ BATCH_SIZE=${2:?'usage: sbatch collate_v3_shards.sbatch DATA_DIR BATCH_SIZE'}
+ MODE=shard
+ ;;
+esac
+BATCH_INDEX=${SLURM_ARRAY_TASK_ID:-0}
+JOB_ID=${SLURM_ARRAY_JOB_ID:-${SLURM_JOB_ID:-local}}
+ENV_ROOT=${PLINDER_ENV_ROOT:?'set PLINDER_ENV_ROOT to the ingest Conda environment'}
+REPO_ROOT=${PLINDER_REPO_ROOT:-${SLURM_SUBMIT_DIR:-}}
+SCRATCH_ROOT=${PLINDER_COLLATE_SCRATCH:-${SLURM_TMPDIR:-/scratch/${USER}/plinder-collate-${SLURM_JOB_ID:-local}}}
+
+export PATH="${ENV_ROOT}/bin:${PATH}"
+export LD_LIBRARY_PATH="${ENV_ROOT}/lib:${LD_LIBRARY_PATH:-}"
+if [[ -n "${REPO_ROOT}" && -d "${REPO_ROOT}/src/plinder" ]]; then
+ export PYTHONPATH="${REPO_ROOT}/src:${PYTHONPATH:-}"
+fi
+export PLINDER_OFFLINE=true
+export PLINDER_OFFLINE_MODE=true
+export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+export MKL_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+export OPENBLAS_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+export NUMEXPR_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+
+mkdir -p "${DATA_DIR}/metrics" "${SCRATCH_ROOT}/${JOB_ID}-${BATCH_INDEX}"
+echo "host=$(hostname) job_id=${JOB_ID} mode=${MODE} batch_index=${BATCH_INDEX} batch_size=${BATCH_SIZE}"
+
+TIME_OUTPUT="${DATA_DIR}/metrics/collate-${MODE}-${JOB_ID}-${BATCH_INDEX}.time-v.txt"
+MEMORY_LIMIT=${PLINDER_COLLATE_MEMORY_LIMIT:-7GB}
+if [[ "${MODE}" == "plan" ]]; then
+ /usr/bin/time -v -o "${TIME_OUTPUT}" \
+ python -m plinder.data.pipeline.collate plan "${DATA_DIR}" \
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+elif [[ "${MODE}" == "plan-start" ]]; then
+ PLAN_ARGS=()
+ if [[ "${PLINDER_COLLATE_INTERFACES_ONLY:-false}" == "true" ]]; then
+ PLAN_ARGS+=(--interfaces-only)
+ fi
+ /usr/bin/time -v -o "${TIME_OUTPUT}" \
+ python -m plinder.data.pipeline.collate plan-start "${DATA_DIR}" \
+ "${PLAN_ARGS[@]}"
+elif [[ "${MODE}" == "plan-shard" ]]; then
+ /usr/bin/time -v -o "${TIME_OUTPUT}" \
+ python -m plinder.data.pipeline.collate plan-shard "${DATA_DIR}" \
+ --batch-index "${BATCH_INDEX}" \
+ --batch-size "${BATCH_SIZE}" \
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+elif [[ "${MODE}" == "plan-finish" ]]; then
+ /usr/bin/time -v -o "${TIME_OUTPUT}" \
+ python -m plinder.data.pipeline.collate plan-finish "${DATA_DIR}"
+elif [[ "${MODE}" == "finalize" ]]; then
+ /usr/bin/time -v -o "${TIME_OUTPUT}" \
+ python -m plinder.data.pipeline.collate finalize "${DATA_DIR}" \
+ --threads "${SLURM_CPUS_PER_TASK:-1}" \
+ --memory-limit "${MEMORY_LIMIT}" \
+ --scratch-dir "${SCRATCH_ROOT}/${JOB_ID}-${BATCH_INDEX}"
+elif [[ "${MODE}" == "repair" ]]; then
+ : "${PLINDER_COLLATE_PDB_MANIFEST:?set PLINDER_COLLATE_PDB_MANIFEST for repair}"
+ /usr/bin/time -v -o "${TIME_OUTPUT}" \
+ python -m plinder.data.pipeline.collate repair "${DATA_DIR}" \
+ --pdb-manifest "${PLINDER_COLLATE_PDB_MANIFEST}" \
+ --threads "${SLURM_CPUS_PER_TASK:-1}" \
+ --memory-limit "${MEMORY_LIMIT}" \
+ --scratch-dir "${SCRATCH_ROOT}/${JOB_ID}-${BATCH_INDEX}"
+else
+ SHARD_ARGS=(
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+ --memory-limit "${MEMORY_LIMIT}"
+ --scratch-dir "${SCRATCH_ROOT}/${JOB_ID}-${BATCH_INDEX}"
+ )
+ if [[ -n "${PLINDER_COLLATE_PDB_MANIFEST:-}" ]]; then
+ SHARD_ARGS+=(
+ --pdb-manifest "${PLINDER_COLLATE_PDB_MANIFEST}"
+ --batch-index "${BATCH_INDEX}"
+ --batch-size "${BATCH_SIZE}"
+ )
+ else
+ SHARD_ARGS+=(--batch-index "${BATCH_INDEX}" --batch-size "${BATCH_SIZE}")
+ fi
+ /usr/bin/time -v -o "${TIME_OUTPUT}" \
+ python -m plinder.data.pipeline.collate shard "${DATA_DIR}" "${SHARD_ARGS[@]}"
+fi
diff --git a/scripts/slurm/configs/ingest/make_components.yaml b/scripts/slurm/configs/ingest/make_components.yaml
new file mode 100644
index 000000000..36a16a2f8
--- /dev/null
+++ b/scripts/slurm/configs/ingest/make_components.yaml
@@ -0,0 +1,7 @@
+flow:
+ run_specific_stages: collate_partitions,make_linked_apo_structures,plan_clusters,make_symmetric_edge_fragments,make_symmetric_edge_shards,make_component_reductions,merge_component_reductions,make_set_covers,make_directed_set_covers,summarize_clusters,finalize_index
+ make_components_force_update: true
+data:
+ plinder_mount: /plinder
+ plinder_release: 2026-07
+ plinder_release_number: "1"
diff --git a/scripts/slurm/configs/ingest/make_entries_ligands.yaml b/scripts/slurm/configs/ingest/make_entries_ligands.yaml
new file mode 100644
index 000000000..5046a9119
--- /dev/null
+++ b/scripts/slurm/configs/ingest/make_entries_ligands.yaml
@@ -0,0 +1,9 @@
+flow:
+ run_specific_stages: make_entries,collate_entries,make_canonical_ligand_archives,finalize_ligand_archives,compute_ligand_fingerprints,make_ligand_scores,make_mhfp6_scores,annotate_ligand_similarity,make_ligand_mmp_pairs,make_ccd_ligand_dbs
+ download_rcsb_files_batch_size: 1
+ make_entries_batch_size: 120
+ make_ligands_batch_size: 220
+data:
+ plinder_mount: /plinder
+ plinder_release: 2026-07
+ plinder_release_number: "1"
diff --git a/scripts/slurm/configs/ingest/make_protein_scores.yaml b/scripts/slurm/configs/ingest/make_protein_scores.yaml
new file mode 100644
index 000000000..ed6945d03
--- /dev/null
+++ b/scripts/slurm/configs/ingest/make_protein_scores.yaml
@@ -0,0 +1,30 @@
+flow:
+ run_specific_stages: make_protein_sequence_clusters,make_dbs,make_protein_structure_clusters,make_sub_dbs,run_batch_searches,map_batch_alignments,collate_alignments,finalize_alignments,plan_score_batches,plan_interface_scores,make_interface_scores,finalize_interface_scores,make_batch_scores,collate_ligand_3d_candidates,plan_ligand_3d_scores,make_ligand_3d_scores,collate_ligand_3d_scores,merge_ligand_3d_scores,finalize_scores,export_ligand_similarity_scores,finalize_ligand_similarity_scores
+ make_dbs_cpu: 32
+ make_sub_dbs_cpu: 32
+ make_scorers_cpu: 32
+ protein_clustering_cpu: 32
+ run_batch_searches_batch_size: 5000
+ map_batch_alignments_batch_size: 1
+ make_interface_scores_batch_size: 1
+ make_interface_scores_cpu: 4
+ make_interface_scores_memory_limit: 32GB
+ make_batch_scores_batch_size: 50
+ make_batch_scores_cpu: 4
+ make_ligand_3d_scores_batch_size: 30000
+ make_ligand_3d_scores_cpu: 1
+ collate_ligand_3d_candidates_batch_size: 4
+ collate_ligand_3d_scores_batch_size: 4
+ merge_ligand_3d_scores_batch_size: 4
+data:
+ plinder_mount: /plinder
+ plinder_release: 2026-07
+ plinder_release_number: "1"
+scorer:
+ sub_databases: holo,apo
+ minimum_thresholds:
+ protein_lddt_weighted_sum: 0.2
+foldseek:
+ min_seq_id: 0.0
+mmseqs:
+ min_seq_id: 0.0
diff --git a/scripts/slurm/ingest_pdb_batch.sbatch b/scripts/slurm/ingest_pdb_batch.sbatch
new file mode 100644
index 000000000..ee4600f5e
--- /dev/null
+++ b/scripts/slurm/ingest_pdb_batch.sbatch
@@ -0,0 +1,57 @@
+#!/usr/bin/env bash
+#SBATCH --job-name=plinder-batch
+#SBATCH --partition=scicore-fast,scicore,bigmem
+#SBATCH --qos=fast,30min
+#SBATCH --cpus-per-task=1
+#SBATCH --mem=16G
+
+set -euo pipefail
+umask 002
+
+MANIFEST=${1:?"usage: sbatch ingest_pdb_batch.sbatch MANIFEST OUTPUT_ROOT BATCH_SIZE"}
+OUTPUT_ROOT=${2:?"usage: sbatch ingest_pdb_batch.sbatch MANIFEST OUTPUT_ROOT BATCH_SIZE"}
+BATCH_SIZE=${3:?"usage: sbatch ingest_pdb_batch.sbatch MANIFEST OUTPUT_ROOT BATCH_SIZE"}
+BATCH_INDEX=${SLURM_ARRAY_TASK_ID:-0}
+JOB_ID=${SLURM_ARRAY_JOB_ID:-${SLURM_JOB_ID:-local}}
+ENV_ROOT=${PLINDER_ENV_ROOT:?"set PLINDER_ENV_ROOT to the ingest Conda environment"}
+: "${PLINDER_PDB_NEXTGEN_ROOT:?set PLINDER_PDB_NEXTGEN_ROOT}"
+: "${PLINDER_VALIDATION_ROOT:?set PLINDER_VALIDATION_ROOT}"
+REPO_ROOT=${PLINDER_REPO_ROOT:-${SLURM_SUBMIT_DIR:-}}
+
+export PATH="${ENV_ROOT}/bin:${PATH}"
+export LD_LIBRARY_PATH="${ENV_ROOT}/lib:${LD_LIBRARY_PATH:-}"
+if [[ -n "${REPO_ROOT}" && -d "${REPO_ROOT}/src/plinder" ]]; then
+ export PYTHONPATH="${REPO_ROOT}/src:${PYTHONPATH:-}"
+fi
+export PLINDER_OFFLINE=true
+export PLINDER_OFFLINE_MODE=true
+export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+export MKL_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+export OPENBLAS_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+export NUMEXPR_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+
+mkdir -p "${OUTPUT_ROOT}/metrics"
+echo "host=$(hostname) job_id=${JOB_ID} batch_index=${BATCH_INDEX} batch_size=${BATCH_SIZE}"
+echo "PLINDER offline mode is enabled; source CIFs and reference data must exist"
+
+ARGS=(
+ "${MANIFEST}"
+ "${OUTPUT_ROOT}"
+ --batch-size "${BATCH_SIZE}"
+ --batch-index "${BATCH_INDEX}"
+)
+if [[ "${FORCE:-0}" == "1" ]]; then
+ ARGS+=(--force)
+fi
+INGEST_MODE=${INGEST_MODE:-all}
+ARGS+=(--mode "${INGEST_MODE}")
+case "${INGEST_MODE}" in
+ all) METRICS_PREFIX=ingest-batch ;;
+ ligands) METRICS_PREFIX=ligand-ingest-batch ;;
+ interfaces) METRICS_PREFIX=interface-ingest-batch ;;
+ *) echo "INGEST_MODE must be all, ligands, or interfaces" >&2; exit 2 ;;
+esac
+
+/usr/bin/time -v \
+ -o "${OUTPUT_ROOT}/metrics/${METRICS_PREFIX}-${JOB_ID}-${BATCH_INDEX}.time-v.txt" \
+ python -m plinder.data.pipeline.ingest batch "${ARGS[@]}"
diff --git a/scripts/slurm/score_v3.sbatch b/scripts/slurm/score_v3.sbatch
new file mode 100644
index 000000000..e79a206b6
--- /dev/null
+++ b/scripts/slurm/score_v3.sbatch
@@ -0,0 +1,327 @@
+#!/usr/bin/env bash
+#SBATCH --job-name=plinder-score
+#SBATCH --partition=scicore,bigmem
+#SBATCH --qos=30min
+#SBATCH --cpus-per-task=4
+#SBATCH --mem=32G
+
+set -euo pipefail
+umask 002
+
+MODE=${1:?"usage: sbatch score_v3.sbatch MODE DATA_DIR [BATCH_SIZE]"}
+DATA_DIR=${2:?"usage: sbatch score_v3.sbatch MODE DATA_DIR [BATCH_SIZE]"}
+BATCH_SIZE=${3:-1}
+BATCH_INDEX=${SLURM_ARRAY_TASK_ID:-0}
+JOB_ID=${SLURM_ARRAY_JOB_ID:-${SLURM_JOB_ID:-local}}
+SEARCH_DB=${PLINDER_SEARCH_DB:-holo}
+ENV_ROOT=${PLINDER_ENV_ROOT:?"set PLINDER_ENV_ROOT to the ingest Conda environment"}
+REPO_ROOT=${PLINDER_REPO_ROOT:-${SLURM_SUBMIT_DIR:-}}
+LOCAL_SCRATCH=${PLINDER_SCORE_SCRATCH:-${SLURM_TMPDIR:-${TMPDIR:-/scratch/${USER}/plinder-score-${SLURM_JOB_ID:-local}}}}
+TASK_SCRATCH=${LOCAL_SCRATCH}/${MODE}-${BATCH_INDEX}
+SCRATCH_MONITOR_PID=
+
+cleanup_task_scratch() {
+ if [[ -n "${SCRATCH_MONITOR_PID}" ]]; then
+ kill "${SCRATCH_MONITOR_PID}" 2>/dev/null || true
+ wait "${SCRATCH_MONITOR_PID}" 2>/dev/null || true
+ fi
+ if [[ -n "${TASK_SCRATCH}" && "${TASK_SCRATCH}" == "${LOCAL_SCRATCH}"/* ]]; then
+ rm -rf -- "${TASK_SCRATCH}"
+ fi
+}
+trap cleanup_task_scratch EXIT
+
+export PATH="${ENV_ROOT}/bin:${PATH}"
+export LD_LIBRARY_PATH="${ENV_ROOT}/lib:${LD_LIBRARY_PATH:-}"
+if [[ -n "${REPO_ROOT}" && -d "${REPO_ROOT}/src/plinder" ]]; then
+ export PYTHONPATH="${REPO_ROOT}/src:${PYTHONPATH:-}"
+fi
+export PLINDER_OFFLINE=true
+export PLINDER_OFFLINE_MODE=true
+export TMPDIR="${TASK_SCRATCH}"
+export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+export MKL_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+export OPENBLAS_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+export NUMEXPR_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+
+mkdir -p "${DATA_DIR}/metrics" "${TASK_SCRATCH}"
+echo "host=$(hostname) job_id=${JOB_ID} mode=${MODE} search_db=${SEARCH_DB} batch_index=${BATCH_INDEX} batch_size=${BATCH_SIZE} scratch=${TASK_SCRATCH}"
+echo "PLINDER offline mode is enabled; all sources and reference data must exist"
+
+monitor_scratch_usage() {
+ local output=${DATA_DIR}/metrics/protein-${MODE}-${JOB_ID}-${BATCH_INDEX}.scratch.tsv
+ local interval=${PLINDER_SCRATCH_MONITOR_INTERVAL_SECONDS:-5}
+ local scratch_kib
+ printf 'unix_seconds\tscratch_kib\n' > "${output}"
+ while [[ -d "${TASK_SCRATCH}" ]]; do
+ scratch_kib=$(du -sk "${TASK_SCRATCH}" 2>/dev/null | cut -f1) || scratch_kib=0
+ printf '%(%s)T\t%s\n' -1 "${scratch_kib:-0}" >> "${output}"
+ sleep "${interval}"
+ done
+}
+
+if [[ "${PLINDER_MONITOR_SCRATCH:-0}" == "1" ]]; then
+ monitor_scratch_usage &
+ SCRATCH_MONITOR_PID=$!
+fi
+
+CLI_MODE=${MODE}
+if [[ "${MODE}" == "search-foldseek" || "${MODE}" == "search-mmseqs" ]]; then
+ CLI_MODE=search
+fi
+ARGS=("${CLI_MODE}" "${DATA_DIR}")
+case "${MODE}" in
+ plan)
+ ARGS+=(--max-seqs "${PLINDER_MAX_SEQS:-10000}")
+ ;;
+ create-dbs)
+ : "${PLINDER_PDB_NEXTGEN_ROOT:?set PLINDER_PDB_NEXTGEN_ROOT}"
+ : "${PLINDER_SEQRES_PATH:?set PLINDER_SEQRES_PATH}"
+ ARGS+=(
+ --cif-root "${PLINDER_PDB_NEXTGEN_ROOT}"
+ --seqres-path "${PLINDER_SEQRES_PATH}"
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+ --scratch-dir "${TASK_SCRATCH}/createdb"
+ )
+ if [[ "${FORCE:-0}" == "1" ]]; then
+ ARGS+=(--force)
+ fi
+ ;;
+ make-sub-dbs)
+ ARGS+=(
+ --search-db "${SEARCH_DB}"
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+ --scratch-dir "${TASK_SCRATCH}"
+ )
+ ;;
+ refresh-alignment-lookup)
+ ARGS+=(
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+ --scratch-dir "${TASK_SCRATCH}"
+ )
+ ;;
+ plan-score-batches)
+ ARGS+=(
+ --batch-size "${BATCH_SIZE}"
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+ --scratch-dir "${TASK_SCRATCH}"
+ --max-query-protein-chains "${PLINDER_MAX_QUERY_PROTEIN_CHAINS:-30}"
+ --max-query-proper-ligand-chains "${PLINDER_MAX_QUERY_PROPER_LIGAND_CHAINS:-30}"
+ )
+ if [[ "${PLINDER_REUSE_MAPPED_ALIGNMENTS:-0}" == "1" ]]; then
+ ARGS+=(--reuse-mapped-alignments)
+ fi
+ ;;
+ plan-ligand-3d)
+ ARGS+=(
+ --batch-size "${BATCH_SIZE}"
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+ --scratch-dir "${TASK_SCRATCH}"
+ --memory-limit "${PLINDER_DUCKDB_MEMORY_LIMIT:-8GB}"
+ )
+ ;;
+ plan-ligand-3d-retries)
+ ARGS+=(--batch-size "${BATCH_SIZE}")
+ ;;
+ plan-interface-scores)
+ ARGS+=(--batch-size "${BATCH_SIZE}")
+ ;;
+ plan-interface-score-repair)
+ ARGS+=(--batch-size "${BATCH_SIZE}")
+ if [[ -n "${PLINDER_INTERFACE_REPAIR_QUERY_MANIFEST:-}" ]]; then
+ ARGS+=(
+ --query-manifest
+ "${PLINDER_INTERFACE_REPAIR_QUERY_MANIFEST}"
+ )
+ fi
+ ;;
+ plan-ligand-pocket-scores)
+ ARGS+=(
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+ --scratch-dir "${TASK_SCRATCH}"
+ --memory-limit "${PLINDER_DUCKDB_MEMORY_LIMIT:-32GB}"
+ --max-query-protein-chains "${PLINDER_MAX_QUERY_PROTEIN_CHAINS:-30}"
+ --max-query-proper-ligand-chains "${PLINDER_MAX_QUERY_PROPER_LIGAND_CHAINS:-30}"
+ )
+ ;;
+ plan-score-repair)
+ : "${PLINDER_AFFECTED_PDB_MANIFEST:?set PLINDER_AFFECTED_PDB_MANIFEST}"
+ ARGS+=(
+ --affected-manifest "${PLINDER_AFFECTED_PDB_MANIFEST}"
+ --batch-size "${BATCH_SIZE}"
+ --target-batch-size "${PLINDER_TARGET_REPAIR_BATCH_SIZE:-100}"
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+ --scratch-dir "${TASK_SCRATCH}"
+ --memory-limit "${PLINDER_DUCKDB_MEMORY_LIMIT:-32GB}"
+ )
+ if [[ -n "${PLINDER_ADDITIONAL_FULL_QUERY_MANIFEST:-}" ]]; then
+ ARGS+=(
+ --additional-full-query-manifest
+ "${PLINDER_ADDITIONAL_FULL_QUERY_MANIFEST}"
+ )
+ fi
+ if [[ -n "${PLINDER_SCORE_REPAIR_MANIFEST:-}" ]]; then
+ ARGS+=(--output "${PLINDER_SCORE_REPAIR_MANIFEST}")
+ fi
+ ;;
+ plan-bounded-score-repair)
+ : "${PLINDER_BOUNDED_QUERY_MANIFEST:?set PLINDER_BOUNDED_QUERY_MANIFEST}"
+ ARGS+=(
+ --pdb-manifest "${PLINDER_BOUNDED_QUERY_MANIFEST}"
+ --batch-size "${BATCH_SIZE}"
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+ --scratch-dir "${TASK_SCRATCH}"
+ --memory-limit "${PLINDER_DUCKDB_MEMORY_LIMIT:-32GB}"
+ )
+ ;;
+ plan-score-repair-ligand-3d)
+ : "${PLINDER_SCORE_REPAIR_MANIFEST:?set PLINDER_SCORE_REPAIR_MANIFEST}"
+ ARGS+=(
+ --repair-manifest "${PLINDER_SCORE_REPAIR_MANIFEST}"
+ --batch-size "${BATCH_SIZE}"
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+ --scratch-dir "${TASK_SCRATCH}"
+ --memory-limit "${PLINDER_DUCKDB_MEMORY_LIMIT:-8GB}"
+ )
+ ;;
+ finalize-score-repair-queries)
+ : "${PLINDER_SCORE_REPAIR_MANIFEST:?set PLINDER_SCORE_REPAIR_MANIFEST}"
+ ARGS+=(
+ --repair-manifest "${PLINDER_SCORE_REPAIR_MANIFEST}"
+ --max-new-drops "${PLINDER_MAX_NEW_REPAIR_DROPS:-2000}"
+ )
+ ;;
+ validate-score-repair)
+ : "${PLINDER_SCORE_REPAIR_MANIFEST:?set PLINDER_SCORE_REPAIR_MANIFEST}"
+ ARGS+=(--repair-manifest "${PLINDER_SCORE_REPAIR_MANIFEST}")
+ ;;
+ plan-clusters)
+ ARGS+=(
+ --source-batch-size "${BATCH_SIZE}"
+ --cover-batch-size "${PLINDER_COVER_BATCH_SIZE:-1}"
+ --symmetric-bucket-count "${PLINDER_SYMMETRIC_EDGE_BUCKET_COUNT:-64}"
+ )
+ ;;
+ drop-score-queries)
+ : "${PLINDER_DROPPED_QUERY_MANIFEST:?set PLINDER_DROPPED_QUERY_MANIFEST}"
+ ARGS+=(--pdb-manifest "${PLINDER_DROPPED_QUERY_MANIFEST}")
+ ;;
+ finalize-ligand-similarity-scores)
+ ARGS+=(
+ --source-dir "${PLINDER_LIGAND_SIMILARITY_DIR:-${DATA_DIR}/exports/ligand_similarity_scores}"
+ --output "${PLINDER_LIGAND_SIMILARITY_OUTPUT:-${DATA_DIR}/exports/ligand_similarity_scores.parquet}"
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+ --scratch-dir "${TASK_SCRATCH}"
+ --memory-limit "${PLINDER_DUCKDB_MEMORY_LIMIT:-32GB}"
+ )
+ ;;
+ finalize-interface-scores)
+ ARGS+=(
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+ --scratch-dir "${TASK_SCRATCH}"
+ --memory-limit "${PLINDER_DUCKDB_MEMORY_LIMIT:-32GB}"
+ )
+ if [[ -n "${PLINDER_INTERFACE_SCORE_OUTPUT:-}" ]]; then
+ ARGS+=(--output "${PLINDER_INTERFACE_SCORE_OUTPUT}")
+ fi
+ ;;
+ finalize-interface-score-repair)
+ ARGS+=(
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+ --scratch-dir "${TASK_SCRATCH}"
+ --memory-limit "${PLINDER_DUCKDB_MEMORY_LIMIT:-32GB}"
+ )
+ ;;
+ finalize-alignments|finalize-ligands|finalize-scores|finalize-ligand-3d-retries|finalize-index|merge-components|cluster-stats)
+ ;;
+ search-foldseek|search-mmseqs|map|pack-ligands|score|score-pdbs|repair-score-pdbs|repair-score-target-remainders|repair-pack-ligands|repair-candidates|repair-ligand-3d|repair-merge-ligand-3d|repair-score-shards|repair-ligand-similarity-shards|collate-ligand-3d-candidates|score-ligand-3d|score-ligand-3d-retry|collate-ligand-3d|merge-ligand-3d|export-ligand-similarity-shards|score-ligand-pocket-shards|materialize-ligand-3d-candidates|score-interface-shards|score-interface-repair-batches|collate-alignments|collate-score-partitions|symmetric-edge-fragments|symmetric-edge-shards|component-reductions|set-covers|directed-covers)
+ ARGS+=(
+ --batch-index "${BATCH_INDEX}"
+ --batch-size "${BATCH_SIZE}"
+ --threads "${SLURM_CPUS_PER_TASK:-1}"
+ --scratch-dir "${TASK_SCRATCH}"
+ )
+ if [[ "${FORCE:-0}" == "1" ]]; then
+ ARGS+=(--force)
+ fi
+ if [[ "${MODE}" == "search-foldseek" || "${MODE}" == "search-mmseqs" ]]; then
+ ARGS+=(--alignment-type "${MODE#search-}")
+ fi
+ if [[ "${MODE}" == "search-foldseek" || "${MODE}" == "search-mmseqs" || "${MODE}" == "map" || "${MODE}" == "score" || "${MODE}" == "score-pdbs" ]]; then
+ ARGS+=(--search-db "${SEARCH_DB}")
+ fi
+ if [[ "${MODE}" == "score-pdbs" ]]; then
+ : "${PLINDER_SCORE_PDB_MANIFEST:?set PLINDER_SCORE_PDB_MANIFEST}"
+ ARGS+=(--pdb-manifest "${PLINDER_SCORE_PDB_MANIFEST}")
+ fi
+ if [[ "${MODE}" == repair-* ]]; then
+ : "${PLINDER_SCORE_REPAIR_MANIFEST:?set PLINDER_SCORE_REPAIR_MANIFEST}"
+ ARGS+=(--repair-manifest "${PLINDER_SCORE_REPAIR_MANIFEST}")
+ fi
+ if [[ "${MODE}" == "export-ligand-similarity-shards" || "${MODE}" == "repair-ligand-similarity-shards" ]]; then
+ ARGS+=(
+ --output-dir "${PLINDER_LIGAND_SIMILARITY_DIR:-${DATA_DIR}/exports/ligand_similarity_scores}"
+ --memory-limit "${PLINDER_DUCKDB_MEMORY_LIMIT:-16GB}"
+ )
+ fi
+ if [[ "${MODE}" == "score-interface-shards" || "${MODE}" == "score-interface-repair-batches" || "${MODE}" == "score-ligand-pocket-shards" || "${MODE}" == "materialize-ligand-3d-candidates" ]]; then
+ ARGS+=(--memory-limit "${PLINDER_DUCKDB_MEMORY_LIMIT:-32GB}")
+ fi
+ if [[ "${MODE}" == "score-interface-shards" || "${MODE}" == "score-interface-repair-batches" ]]; then
+ ARGS+=(--side-coverage-buckets "${PLINDER_INTERFACE_SIDE_COVERAGE_BUCKETS:-32}")
+ ARGS+=(--assignment-target-buckets "${PLINDER_INTERFACE_TARGET_BUCKETS:-1}")
+ fi
+ if [[ "${MODE}" == "score-interface-repair-batches" ]]; then
+ ARGS+=(
+ --repair-batches-per-task
+ "${PLINDER_INTERFACE_REPAIR_BATCHES_PER_TASK:-1}"
+ )
+ if [[ "${FORCE:-0}" == "1" ]]; then
+ ARGS+=(--force)
+ fi
+ fi
+ if [[ "${MODE}" == "score-ligand-pocket-shards" && -n "${PLINDER_SCORE_SHARDS:-}" ]]; then
+ IFS=',' read -r -a SCORE_SHARDS <<< "${PLINDER_SCORE_SHARDS}"
+ for SHARD in "${SCORE_SHARDS[@]}"; do
+ ARGS+=(--shard "${SHARD}")
+ done
+ fi
+ ;;
+ *)
+ echo "unsupported mode: ${MODE}" >&2
+ exit 2
+ ;;
+esac
+
+if [[ "${MODE}" == "plan-clusters" || "${MODE}" == "symmetric-edge-fragments" || "${MODE}" == "symmetric-edge-shards" || "${MODE}" == "component-reductions" || "${MODE}" == "merge-components" || "${MODE}" == "set-covers" || "${MODE}" == "directed-covers" || "${MODE}" == "cluster-stats" ]]; then
+ ARGS+=(--entity-type "${PLINDER_CLUSTER_ENTITY_TYPE:-ligand}")
+fi
+
+if [[ "${MODE}" == "plan-clusters" || "${MODE}" == "component-reductions" || "${MODE}" == "merge-components" || "${MODE}" == "set-covers" || "${MODE}" == "directed-covers" || "${MODE}" == "cluster-stats" ]]; then
+ if [[ -n "${PLINDER_CLUSTER_METRICS:-}" ]]; then
+ IFS=',' read -r -a CLUSTER_METRICS <<< "${PLINDER_CLUSTER_METRICS}"
+ for METRIC in "${CLUSTER_METRICS[@]}"; do
+ ARGS+=(--metric "${METRIC}")
+ done
+ fi
+ if [[ -n "${PLINDER_CLUSTER_THRESHOLDS:-}" ]]; then
+ IFS=',' read -r -a CLUSTER_THRESHOLDS <<< "${PLINDER_CLUSTER_THRESHOLDS}"
+ for THRESHOLD in "${CLUSTER_THRESHOLDS[@]}"; do
+ ARGS+=(--threshold "${THRESHOLD}")
+ done
+ fi
+fi
+
+set +e
+/usr/bin/time -v \
+ -o "${DATA_DIR}/metrics/protein-${MODE}-${JOB_ID}-${BATCH_INDEX}.time-v.txt" \
+ python -m plinder.data.pipeline.score "${ARGS[@]}"
+COMMAND_STATUS=$?
+set -e
+
+if [[ -n "${SCRATCH_MONITOR_PID}" ]]; then
+ kill "${SCRATCH_MONITOR_PID}" 2>/dev/null || true
+ wait "${SCRATCH_MONITOR_PID}" 2>/dev/null || true
+ SCRATCH_MONITOR_PID=
+fi
+exit "${COMMAND_STATUS}"
diff --git a/scripts/slurm/transform_bindingdb.sbatch b/scripts/slurm/transform_bindingdb.sbatch
new file mode 100644
index 000000000..608d7e702
--- /dev/null
+++ b/scripts/slurm/transform_bindingdb.sbatch
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+#SBATCH --job-name=plinder-bindingdb
+#SBATCH --partition=scicore-fast,scicore,bigmem
+#SBATCH --qos=fast
+#SBATCH --cpus-per-task=1
+#SBATCH --mem=32G
+
+set -euo pipefail
+umask 002
+
+OUTPUT_ROOT=${1:?"usage: sbatch transform_bindingdb.sbatch OUTPUT_ROOT"}
+ENV_ROOT=${PLINDER_ENV_ROOT:?"set PLINDER_ENV_ROOT to the ingest Conda environment"}
+REPO_ROOT=${PLINDER_REPO_ROOT:-${SLURM_SUBMIT_DIR:-}}
+RAW_BINDINGDB="${OUTPUT_ROOT}/dbs/affinity/BindingDB_All.tsv"
+
+if [[ ! -s "${RAW_BINDINGDB}" ]]; then
+ echo "missing pre-downloaded BindingDB TSV: ${RAW_BINDINGDB}" >&2
+ exit 1
+fi
+
+export PATH="${ENV_ROOT}/bin:${PATH}"
+export LD_LIBRARY_PATH="${ENV_ROOT}/lib:${LD_LIBRARY_PATH:-}"
+if [[ -n "${REPO_ROOT}" && -d "${REPO_ROOT}/src/plinder" ]]; then
+ export PYTHONPATH="${REPO_ROOT}/src:${PYTHONPATH:-}"
+fi
+export PLINDER_OFFLINE=true
+export PLINDER_OFFLINE_MODE=true
+export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+export MKL_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+export OPENBLAS_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+export NUMEXPR_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
+
+mkdir -p "${OUTPUT_ROOT}/metrics"
+echo "host=$(hostname) job_id=${SLURM_JOB_ID:-none} output_root=${OUTPUT_ROOT}"
+echo "PLINDER offline mode is enabled; transforming the existing BindingDB TSV"
+
+/usr/bin/time -v \
+ -o "${OUTPUT_ROOT}/metrics/transform-bindingdb.time-v.txt" \
+ python -c \
+ 'from pathlib import Path; from plinder.data.pipeline.io import download_affinity_data; download_affinity_data(data_dir=Path(__import__("sys").argv[1]), force_update=False)' \
+ "${OUTPUT_ROOT}"
+
+ls -lh \
+ "${OUTPUT_ROOT}/dbs/affinity/candidates.parquet" \
+ "${OUTPUT_ROOT}/dbs/affinity/measurements.parquet"
diff --git a/src/plinder/__init__.py b/src/plinder/__init__.py
index 761ecc5d4..a3b640f08 100644
--- a/src/plinder/__init__.py
+++ b/src/plinder/__init__.py
@@ -1,6 +1,7 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
"""plinder"""
+
from pathlib import Path
from ._version import _get_version
diff --git a/src/plinder/core/__init__.py b/src/plinder/core/__init__.py
index e60b4112b..f38fbe9ad 100644
--- a/src/plinder/core/__init__.py
+++ b/src/plinder/core/__init__.py
@@ -4,25 +4,37 @@
The plinder.core package collects useful functions and classes for interacting
with the PLINDER dataset. It manages app configuration and will automatically
download (and / or sync) the dataset to a local cache in a lazy manner, when
-particular assets are requested. Downloads are checked against the release
-manifest for size and MD5 before replacing a local file. Cached files with the
-expected size are reused without rehashing; force a refresh to repair same-size
-local corruption.
+particular assets are requested. Downloads come directly from the Cameo file
+server and are checked against HTTP Content-Length before replacing a local
+file. Cached files with matching size and Last-Modified time are reused; server
+hotfixes are fetched on the next access. Force a refresh to repair local
+corruption that preserves both size and modification time.
Note
----
Set the environment variable `PLINDER_OFFLINE=true` to use local files without
network access.
"""
+
+from plinder.core.index.interface import PlinderInterface
+from plinder.core.index.query import query_table
from plinder.core.index.system import PlinderSystem
-from plinder.core.index.utils import get_manifest, get_plindex
-from plinder.core.split.utils import get_split
+from plinder.core.release import (
+ RELEASE_PATHS,
+ RELEASE_TABLES,
+ PlinderRelease,
+)
from plinder.core.utils.config import get_config
+from plinder.core.utils.io import download_pdb_mmcifs, get_pdb_mmcif
__all__ = [
"get_config",
- "get_plindex",
- "get_manifest",
- "get_split",
+ "get_pdb_mmcif",
+ "download_pdb_mmcifs",
+ "PlinderInterface",
"PlinderSystem",
+ "query_table",
+ "PlinderRelease",
+ "RELEASE_PATHS",
+ "RELEASE_TABLES",
]
diff --git a/src/plinder/core/index/__init__.py b/src/plinder/core/index/__init__.py
index 274995158..2daa0b154 100644
--- a/src/plinder/core/index/__init__.py
+++ b/src/plinder/core/index/__init__.py
@@ -1,6 +1,8 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
+from plinder.core.index.interface import PlinderInterface
+from plinder.core.index.query import query_table
from plinder.core.index.system import PlinderSystem
-__all__ = ["PlinderSystem"]
+__all__ = ["PlinderInterface", "PlinderSystem", "query_table"]
diff --git a/src/plinder/core/index/interface.py b/src/plinder/core/index/interface.py
new file mode 100644
index 000000000..3502e6ea2
--- /dev/null
+++ b/src/plinder/core/index/interface.py
@@ -0,0 +1,238 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Public access to one protein interface in a PLINDER release."""
+
+from __future__ import annotations
+
+from functools import cached_property
+from pathlib import Path
+from typing import TYPE_CHECKING
+
+import biotite.structure as struc
+import numpy as np
+import pandas as pd
+
+from plinder.core.index.query import query_table
+from plinder.core.release import PlinderRelease
+from plinder.core.utils.config import get_config
+from plinder.core.utils.io import get_pdb_mmcif
+from plinder.data.annotations.save_utils import (
+ reconstruct_interface,
+ save_reconstructed_interface,
+)
+
+if TYPE_CHECKING:
+ from numpy.typing import NDArray
+
+
+class PlinderInterface:
+ """One annotated protein-chain interface in a biological assembly."""
+
+ def __init__(
+ self,
+ *,
+ system_id: str,
+ release: PlinderRelease | None = None,
+ source_mmcif: Path | str | None = None,
+ reconstruction_dir: Path | str | None = None,
+ ) -> None:
+ self.system_id = system_id
+ self.release = release or PlinderRelease()
+ self.source_mmcif = Path(source_mmcif) if source_mmcif is not None else None
+ default_reconstruction_root = (
+ Path(self.release.data_dir)
+ if self.release.data_dir is not None
+ else Path(get_config().data.plinder_dir)
+ )
+ self.reconstruction_dir = (
+ Path(reconstruction_dir)
+ if reconstruction_dir is not None
+ else default_reconstruction_root / "reconstructed_interfaces" / system_id
+ )
+ self._annotation: pd.Series | None = None
+
+ def __repr__(self) -> str:
+ return f"PlinderInterface(system_id={self.system_id!r})"
+
+ @property
+ def annotation(self) -> pd.Series:
+ """Return the unique published annotation row for this interface."""
+ if self._annotation is None:
+ rows = query_table(
+ "interface_annotations",
+ filters=[("system_id", "==", self.system_id)],
+ release=self.release,
+ )
+ if rows.empty:
+ raise ValueError(f"interface {self.system_id!r} is not in the release")
+ if len(rows) != 1:
+ raise ValueError(
+ f"interface {self.system_id!r} has {len(rows)} annotation rows"
+ )
+ self._annotation = rows.iloc[0]
+ return self._annotation
+
+ @property
+ def entry_pdb_id(self) -> str:
+ """Return the source PDB entry ID."""
+ return str(self.annotation["entry_pdb_id"])
+
+ @property
+ def biounit_id(self) -> str:
+ """Return the deposited biological-assembly ID."""
+ return str(self.annotation["system_biounit_id"])
+
+ @property
+ def chains(self) -> tuple[str, str]:
+ """Return the two canonical assembly-chain instance IDs."""
+ return (
+ str(self.annotation["interface_chain_1"]),
+ str(self.annotation["interface_chain_2"]),
+ )
+
+ @property
+ def source_mmcif_path(self) -> Path:
+ """Return the explicit or release-cached deposited PDB mmCIF."""
+ if self.source_mmcif is None:
+ manifest = self.release.fetch("entry_sources")
+ cache_dir = (
+ Path(self.release.data_dir) / get_config().data.source_mmcifs
+ if self.release.data_dir is not None
+ else None
+ )
+ self.source_mmcif = get_pdb_mmcif(
+ self.entry_pdb_id,
+ cache_dir=cache_dir,
+ manifest_path=manifest,
+ )
+ if not self.source_mmcif.is_file():
+ raise FileNotFoundError(self.source_mmcif)
+ return self.source_mmcif
+
+ @cached_property
+ def atom_array(self) -> struc.AtomArray:
+ """Return the exact biological-assembly chain pair in memory."""
+ return reconstruct_interface(self.source_mmcif_path, self.annotation)
+
+ @cached_property
+ def chain_structures(self) -> dict[str, struc.AtomArray]:
+ """Return the two interface sides keyed by assembly-chain instance."""
+ return {
+ chain_id: self.atom_array[self.atom_array.chain_id.astype(str) == chain_id]
+ for chain_id in self.chains
+ }
+
+ @cached_property
+ def sequences(self) -> dict[str, str]:
+ """Return full polymer sequences keyed by assembly-chain instance."""
+ asym_ids = {chain_id.split(".", maxsplit=1)[-1] for chain_id in self.chains}
+ rows = query_table(
+ "entry_chains",
+ columns=["chain_asym_id", "chain_sequence"],
+ filters=[
+ ("entry_pdb_id", "==", self.entry_pdb_id),
+ ("chain_asym_id", "in", sorted(asym_ids)),
+ ],
+ release=self.release,
+ )
+ asym_to_sequence = dict(
+ zip(rows["chain_asym_id"].astype(str), rows["chain_sequence"].astype(str))
+ )
+ missing = sorted(asym_ids.difference(asym_to_sequence))
+ if missing:
+ raise ValueError(
+ f"interface {self.system_id!r} has no sequences for chains {missing}"
+ )
+ return {
+ chain_id: asym_to_sequence[chain_id.split(".", maxsplit=1)[-1]]
+ for chain_id in self.chains
+ }
+
+ @cached_property
+ def interface_residue_masks(self) -> dict[str, "NDArray[np.bool_]"]:
+ """Return atom masks for the annotated interface residues on each side."""
+ masks: dict[str, NDArray[np.bool_]] = {}
+ for side, chain_id in enumerate(self.chains, start=1):
+ residue_indices = np.asarray(
+ self.annotation[f"interface_chain_{side}_residue_indices"],
+ dtype=int,
+ )
+ residue_numbers = np.asarray(
+ self.annotation[f"interface_chain_{side}_residue_numbers"],
+ dtype=int,
+ )
+ if len(residue_indices) != len(residue_numbers):
+ raise ValueError(
+ f"interface residue indices and numbers for {chain_id} have "
+ f"different lengths: {len(residue_indices)} and "
+ f"{len(residue_numbers)}"
+ )
+ chain_atom_indices = np.flatnonzero(
+ self.atom_array.chain_id.astype(str) == chain_id
+ )
+ chain = self.atom_array[chain_atom_indices]
+ starts = struc.get_residue_starts(chain, add_exclusive_stop=True)
+ residue_count = len(starts) - 1
+ if np.any(residue_indices < 0) or np.any(residue_indices >= residue_count):
+ raise ValueError(
+ f"interface residue indices for {chain_id} fall outside its "
+ f"{residue_count} resolved residues"
+ )
+ observed_numbers = chain.res_id[starts[:-1]][residue_indices].astype(int)
+ if not np.array_equal(observed_numbers, residue_numbers):
+ mismatches = [
+ f"index {residue_index}: expected {expected}, found {observed}"
+ for residue_index, expected, observed in zip(
+ residue_indices,
+ residue_numbers,
+ observed_numbers,
+ )
+ if expected != observed
+ ]
+ raise ValueError(
+ f"source mmCIF residues do not match the release annotation "
+ f"for {chain_id}: {'; '.join(mismatches)}"
+ )
+ mask = np.zeros(self.atom_array.array_length(), dtype=bool)
+ for residue_index in residue_indices:
+ start = starts[residue_index]
+ stop = starts[residue_index + 1]
+ mask[chain_atom_indices[start:stop]] = True
+ masks[chain_id] = mask
+ return masks
+
+ @cached_property
+ def interface_structure(self) -> struc.AtomArray:
+ """Return atoms belonging to annotated interface residues."""
+ mask = np.zeros(self.atom_array.array_length(), dtype=bool)
+ for side_mask in self.interface_residue_masks.values():
+ mask |= side_mask
+ return self.atom_array[mask]
+
+ def reconstruct(
+ self,
+ *,
+ output_cif: Path | str | None = None,
+ overwrite: bool = False,
+ ) -> Path:
+ """Write the two-chain biological-assembly interface as an mmCIF."""
+ if output_cif is None:
+ output_cif = self.reconstruction_dir / "interface.cif"
+ return save_reconstructed_interface(
+ self.source_mmcif_path,
+ self.annotation,
+ output_cif=output_cif,
+ overwrite=overwrite,
+ reconstructed=self.atom_array,
+ )
+
+ @property
+ def interface_cif(self) -> Path:
+ """Return the standard reconstructed interface mmCIF path."""
+ path = self.reconstruction_dir / "interface.cif"
+ if not path.is_file():
+ self.reconstruct(output_cif=path)
+ return path
+
+
+__all__ = ["PlinderInterface"]
diff --git a/src/plinder/core/index/query.py b/src/plinder/core/index/query.py
new file mode 100644
index 000000000..af779daa6
--- /dev/null
+++ b/src/plinder/core/index/query.py
@@ -0,0 +1,454 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Query published PLINDER tables, joining related tables when needed."""
+
+from __future__ import annotations
+
+from collections.abc import Iterable
+from pathlib import Path
+from typing import Any, TypeAlias
+
+import duckdb
+import numpy as np
+import pandas as pd
+import pyarrow.dataset as ds
+
+from plinder.core.release import RELEASE_TABLES, PlinderRelease
+
+Filter: TypeAlias = tuple[str, str, Any]
+Filters: TypeAlias = list[Filter | list[Filter]] | None
+JoinKeys: TypeAlias = tuple[tuple[str, str], ...]
+
+
+def _is_repeated_entry_column(column: str) -> bool:
+ return column.startswith("entry_") and column != "entry_pdb_id"
+
+
+# Every relationship points from a base table to a table whose join columns are
+# unique. These joins therefore preserve the rows of the base table.
+TABLE_JOINS: dict[str, dict[str, JoinKeys]] = {
+ "annotation": {
+ "system_validation": (("system_id", "system_id"),),
+ "entry_metadata": (("entry_pdb_id", "entry_pdb_id"),),
+ "entry_sources": (("entry_pdb_id", "entry_pdb_id"),),
+ "ligand_pocket_membership": (("ligand_id", "ligand_id"),),
+ "ligand_clusters": (("ligand_id", "ligand_id"),),
+ "ligand_affinity": (("ligand_id", "ligand_id"),),
+ },
+ "entry_chains": {
+ "alignment_chain_lookup": (
+ ("entry_pdb_id", "entry_pdb_id"),
+ ("chain_asym_id", "chain_asym_id"),
+ ),
+ "entry_metadata": (("entry_pdb_id", "entry_pdb_id"),),
+ "entry_sources": (("entry_pdb_id", "entry_pdb_id"),),
+ },
+ "entry_biounit_chains": {
+ "entry_chains": (
+ ("entry_pdb_id", "entry_pdb_id"),
+ ("chain_asym_id", "chain_asym_id"),
+ ),
+ "entry_metadata": (("entry_pdb_id", "entry_pdb_id"),),
+ "entry_sources": (("entry_pdb_id", "entry_pdb_id"),),
+ },
+ "entry_metadata": {
+ "entry_sources": (("entry_pdb_id", "entry_pdb_id"),),
+ },
+ "interface_annotations": {
+ "entry_metadata": (("entry_pdb_id", "entry_pdb_id"),),
+ "entry_sources": (("entry_pdb_id", "entry_pdb_id"),),
+ "interface_membership": (("system_id", "system_id"),),
+ "interface_clusters": (("system_id", "system_id"),),
+ },
+ "alignment_chain_lookup": {
+ "entry_chains": (
+ ("entry_pdb_id", "entry_pdb_id"),
+ ("chain_asym_id", "chain_asym_id"),
+ ),
+ },
+ "ligand_pocket_membership": {
+ "annotation": (("ligand_id", "ligand_id"),),
+ "system_validation": (("system_id", "system_id"),),
+ "ligand_clusters": (("ligand_id", "ligand_id"),),
+ "ligand_affinity": (("ligand_id", "ligand_id"),),
+ },
+ "ligand_pocket_residues": {
+ "annotation": (("ligand_id", "ligand_id"),),
+ "system_validation": (("system_id", "system_id"),),
+ "entry_chains": (
+ ("entry_pdb_id", "entry_pdb_id"),
+ ("chain_asym_id", "chain_asym_id"),
+ ),
+ "entry_metadata": (("entry_pdb_id", "entry_pdb_id"),),
+ "entry_sources": (("entry_pdb_id", "entry_pdb_id"),),
+ "ligand_pocket_membership": (("ligand_id", "ligand_id"),),
+ "ligand_clusters": (("ligand_id", "ligand_id"),),
+ "ligand_affinity": (("ligand_id", "ligand_id"),),
+ },
+ "ligand_clusters": {
+ "annotation": (("ligand_id", "ligand_id"),),
+ "ligand_affinity": (("ligand_id", "ligand_id"),),
+ },
+ "ligand_affinity": {
+ "annotation": (("ligand_id", "ligand_id"),),
+ },
+ "interface_membership": {
+ "interface_annotations": (("system_id", "system_id"),),
+ "interface_clusters": (("system_id", "system_id"),),
+ },
+ "interface_clusters": {
+ "interface_annotations": (("system_id", "system_id"),),
+ },
+ "linked_apo_structures": {
+ "entry_metadata": (("source_entry_id", "entry_pdb_id"),),
+ "entry_sources": (("source_entry_id", "entry_pdb_id"),),
+ },
+ "interface_apo_structures": {
+ "entry_chains": (
+ ("source_entry_id", "entry_pdb_id"),
+ ("source_chain_asym_id", "chain_asym_id"),
+ ),
+ "entry_metadata": (("source_entry_id", "entry_pdb_id"),),
+ "entry_sources": (("source_entry_id", "entry_pdb_id"),),
+ },
+}
+
+
+for cluster_table in ("protein_sequence_clusters", "protein_structure_clusters"):
+ chain_keys = (
+ ("entry_pdb_id", "entry_pdb_id"),
+ ("chain_asym_id", "chain_asym_id"),
+ )
+ TABLE_JOINS[cluster_table] = {
+ "entry_chains": chain_keys,
+ "entry_metadata": (("entry_pdb_id", "entry_pdb_id"),),
+ "entry_sources": (("entry_pdb_id", "entry_pdb_id"),),
+ }
+ for chain_table in (
+ "entry_chains",
+ "entry_biounit_chains",
+ "alignment_chain_lookup",
+ "ligand_pocket_residues",
+ ):
+ TABLE_JOINS[chain_table][cluster_table] = chain_keys
+
+
+def _quote_identifier(value: str) -> str:
+ return f'"{value.replace(chr(34), chr(34) * 2)}"'
+
+
+def _parquet_sql(path: Path) -> str:
+ source = path.resolve()
+ if source.is_dir():
+ source = source / "**" / "*.parquet"
+ escaped = source.as_posix().replace("'", "''")
+ return f"read_parquet('{escaped}', union_by_name = true)"
+
+
+def _schema_names(path: Path) -> list[str]:
+ if path.is_dir():
+ dataset = ds.dataset(
+ path,
+ format="parquet",
+ partitioning="hive",
+ exclude_invalid_files=True,
+ )
+ else:
+ dataset = ds.dataset(path, format="parquet", exclude_invalid_files=True)
+ return list(dataset.schema.names)
+
+
+def _condition_sql(
+ condition: Filter,
+ *,
+ columns: dict[str, str],
+ parameters: list[Any],
+) -> str:
+ if len(condition) != 3:
+ raise ValueError(
+ f"filters must be (column, operator, value): got {condition!r}"
+ )
+ column, operator, value = condition
+ if column not in columns:
+ raise ValueError(
+ f"filter column {column!r} is unavailable; choose from: "
+ f"{', '.join(columns)}"
+ )
+ field = columns[column]
+ operator = operator.casefold().strip()
+ operator = {"==": "=", "not in": "not in"}.get(operator, operator)
+ if isinstance(value, np.generic):
+ value = value.item()
+ if value is None:
+ if operator in {"=", "is"}:
+ return f"{field} IS NULL"
+ if operator in {"!=", "<>", "is not"}:
+ return f"{field} IS NOT NULL"
+ raise ValueError(f"operator {operator!r} cannot compare with None")
+ if operator in {"in", "not in"}:
+ if isinstance(value, (str, bytes)) or not isinstance(value, Iterable):
+ raise TypeError(f"operator {operator!r} requires a non-string iterable")
+ values = [
+ item.item() if isinstance(item, np.generic) else item for item in value
+ ]
+ if not values:
+ return "FALSE" if operator == "in" else "TRUE"
+ parameters.extend(values)
+ placeholders = ", ".join("?" for _ in values)
+ return f"{field} {operator.upper()} ({placeholders})"
+ allowed = {"=", "!=", "<>", "<", "<=", ">", ">="}
+ if operator not in allowed:
+ raise ValueError(
+ f"unsupported filter operator {operator!r}; choose from: "
+ f"{', '.join(sorted(allowed | {'==', 'in', 'not in'}))}"
+ )
+ parameters.append(value)
+ return f"{field} {operator} ?"
+
+
+def _filters_sql(
+ filters: Filters,
+ *,
+ columns: dict[str, str],
+) -> tuple[str, list[Any]]:
+ parameters: list[Any] = []
+ clauses: list[str] = []
+ for item in filters or []:
+ if isinstance(item, list):
+ if not item:
+ raise ValueError("OR filter groups must not be empty")
+ group = [
+ _condition_sql(
+ condition,
+ columns=columns,
+ parameters=parameters,
+ )
+ for condition in item
+ ]
+ clauses.append(f"({' OR '.join(group)})")
+ else:
+ clauses.append(_condition_sql(item, columns=columns, parameters=parameters))
+ if not clauses:
+ return "", parameters
+ return f"\nWHERE {' AND '.join(clauses)}", parameters
+
+
+def _filter_columns(filters: Filters) -> set[str]:
+ """Return every column referenced by a filter expression."""
+ return {
+ condition[0]
+ for item in filters or []
+ for condition in (item if isinstance(item, list) else [item])
+ if len(condition) == 3
+ }
+
+
+def _column_sql(alias: str, column: str) -> str:
+ return f"{_quote_identifier(alias)}.{_quote_identifier(column)}"
+
+
+def _visible_schema_columns(
+ table_name: str,
+ schema: Iterable[str],
+ *,
+ side_key_columns: set[str] | None = None,
+) -> list[str]:
+ """Return columns exposed by a base table or joined side table."""
+ keys = side_key_columns or set()
+ return [
+ name
+ for name in schema
+ if name not in keys
+ and (table_name != "annotation" or not _is_repeated_entry_column(name))
+ ]
+
+
+def query_table(
+ table_name: str = "annotation",
+ *,
+ columns: list[str] | None = None,
+ filters: Filters = None,
+ joins: list[str] | None = None,
+ release: PlinderRelease | None = None,
+) -> pd.DataFrame:
+ """Query one release table and add related tables when columns require them.
+
+ Requested output and filter columns select registered related tables
+ automatically. Their join columns are unique, so joining never creates
+ extra base rows. If a related table repeats a non-key column from the base
+ table, its non-null values take precedence and unmatched base values are
+ retained.
+
+ Parameters
+ ----------
+ table_name : str
+ Name in :data:`plinder.core.RELEASE_TABLES`.
+ columns : list[str] | None
+ Output columns. ``None`` returns every available column.
+ filters : list | None
+ Conditions combined with AND. A nested list is an OR group.
+ joins : list[str] | None
+ Additional registered tables to left-join. Usually unnecessary; use it
+ to choose a source when the same requested column exists in more than
+ one related table.
+ release : PlinderRelease | None
+ Explicit local release, or the configured release when omitted.
+
+ Protein clusters are available as ``protein_sequence_clusters`` (MMseqs)
+ and ``protein_structure_clusters`` (Foldseek). Query either table with
+ ``chain_sequence`` to include sequences automatically. When starting from
+ ``entry_chains``, choose the cluster table with ``joins=[...]``; both
+ cluster tables use the same representative column names.
+ """
+ if table_name not in RELEASE_TABLES:
+ choices = ", ".join(sorted(RELEASE_TABLES))
+ raise KeyError(f"unknown release table {table_name!r}; choose from: {choices}")
+ release = release or PlinderRelease()
+ selected_joins = list(dict.fromkeys(joins or []))
+ allowed_joins = TABLE_JOINS.get(table_name, {})
+ invalid_joins = [name for name in selected_joins if name not in allowed_joins]
+ if invalid_joins:
+ choices = ", ".join(sorted(allowed_joins)) or "none"
+ raise ValueError(
+ f"table {table_name!r} cannot join {invalid_joins}; "
+ f"available related tables: {choices}"
+ )
+
+ requested_filter_columns = _filter_columns(filters)
+ requested_columns = set(columns or [])
+ requested_columns.discard("*")
+ paths = {table_name: release.fetch(str(RELEASE_TABLES[table_name]["artifact"]))}
+ schemas = {table_name: _schema_names(paths[table_name])}
+ output_order = _visible_schema_columns(table_name, schemas[table_name])
+
+ requested_names = requested_columns | requested_filter_columns
+ unresolved = requested_names.difference(output_order)
+ if unresolved:
+ candidate_owners: dict[str, list[str]] = {name: [] for name in unresolved}
+ for join_name, keys in allowed_joins.items():
+ if join_name not in paths:
+ try:
+ paths[join_name] = release.fetch(
+ str(RELEASE_TABLES[join_name]["artifact"])
+ )
+ except FileNotFoundError:
+ continue
+ schemas[join_name] = _schema_names(paths[join_name])
+ visible = set(
+ _visible_schema_columns(
+ join_name,
+ schemas[join_name],
+ side_key_columns={side for _, side in keys},
+ )
+ )
+ for name in unresolved.intersection(visible):
+ candidate_owners[name].append(join_name)
+
+ uniquely_required = sorted(
+ {owners[0] for owners in candidate_owners.values() if len(owners) == 1}
+ )
+ selected_joins.extend(uniquely_required)
+ selected_joins = list(dict.fromkeys(selected_joins))
+ for name in sorted(candidate_owners):
+ owners = candidate_owners[name]
+ selected_owners = [owner for owner in owners if owner in selected_joins]
+ if len(selected_owners) == 1:
+ continue
+ if len(selected_owners) > 1:
+ raise ValueError(
+ f"column {name!r} is provided by selected related tables "
+ f"{selected_owners}; select only one"
+ )
+ if len(owners) > 1:
+ raise ValueError(
+ f"column {name!r} is available from multiple related "
+ f"tables {owners}; choose one with joins=[...]"
+ )
+
+ selected_joins = list(dict.fromkeys(selected_joins))
+ table_names = [table_name, *selected_joins]
+ aliases = {name: f"t{index}" for index, name in enumerate(table_names)}
+ for name in selected_joins:
+ if name not in paths:
+ paths[name] = release.fetch(str(RELEASE_TABLES[name]["artifact"]))
+ schemas[name] = _schema_names(paths[name])
+
+ output_columns = {
+ name: _column_sql(aliases[table_name], name) for name in output_order
+ }
+ joined_column_owner: dict[str, str] = {}
+ join_sql: list[str] = []
+ for join_name in selected_joins:
+ keys = allowed_joins[join_name]
+ base_missing = [
+ column for column, _ in keys if column not in schemas[table_name]
+ ]
+ join_missing = [
+ column for _, column in keys if column not in schemas[join_name]
+ ]
+ if base_missing or join_missing:
+ raise ValueError(
+ f"join {table_name!r} -> {join_name!r} is unavailable; "
+ f"missing base columns {base_missing}, sidecar columns {join_missing}"
+ )
+ side_key_columns = {side_column for _, side_column in keys}
+ visible_columns = _visible_schema_columns(join_name, schemas[join_name])
+ for name in visible_columns:
+ if name in side_key_columns:
+ continue
+ # Related tables can repeat base identifiers such as system_id.
+ # Columns supplied only by multiple side tables remain ambiguous.
+ if name in joined_column_owner and name not in schemas[table_name]:
+ previous = joined_column_owner[name]
+ raise ValueError(
+ f"joined column {name!r} is provided by both {previous!r} "
+ f"and {join_name!r}"
+ )
+ joined_column_owner[name] = join_name
+ if name not in output_columns:
+ output_order.append(name)
+ output_columns[name] = _column_sql(aliases[join_name], name)
+ else:
+ output_columns[name] = (
+ f"COALESCE({_column_sql(aliases[join_name], name)}, "
+ f"{output_columns[name]})"
+ )
+ conditions = " AND ".join(
+ f"{_quote_identifier(aliases[table_name])}.{_quote_identifier(base)} = "
+ f"{_quote_identifier(aliases[join_name])}.{_quote_identifier(side)}"
+ for base, side in keys
+ )
+ join_sql.append(
+ f"LEFT JOIN {_parquet_sql(paths[join_name])} "
+ f"AS {_quote_identifier(aliases[join_name])} ON {conditions}"
+ )
+
+ requested = output_order if columns is None or columns == ["*"] else columns
+ if not requested:
+ raise ValueError("columns must not be empty")
+ duplicates = sorted({name for name in requested if requested.count(name) > 1})
+ if duplicates:
+ raise ValueError(f"duplicate output columns: {duplicates}")
+ missing = [name for name in requested if name not in output_columns]
+ if missing:
+ raise ValueError(
+ f"columns {missing} are unavailable; choose from: {', '.join(output_order)}"
+ )
+ select_sql = ", ".join(
+ f"{output_columns[name]} AS {_quote_identifier(name)}" for name in requested
+ )
+ where_sql, parameters = _filters_sql(filters, columns=output_columns)
+ query = (
+ f"SELECT {select_sql}\n"
+ f"FROM {_parquet_sql(paths[table_name])} "
+ f"AS {_quote_identifier(aliases[table_name])}\n"
+ f"{' '.join(join_sql)}{where_sql}"
+ )
+ connection = duckdb.connect()
+ try:
+ return connection.execute(query, parameters).fetch_df()
+ finally:
+ connection.close()
+
+
+__all__ = ["TABLE_JOINS", "query_table"]
diff --git a/src/plinder/core/index/system.py b/src/plinder/core/index/system.py
index 1662f9926..e3f7a586b 100644
--- a/src/plinder/core/index/system.py
+++ b/src/plinder/core/index/system.py
@@ -2,38 +2,89 @@
# Distributed under the terms of the Apache License 2.0
from __future__ import annotations
-import json
from functools import cached_property
from pathlib import Path
-from typing import TYPE_CHECKING, Any
+from typing import TYPE_CHECKING
+from uuid import uuid4
import pandas as pd
if TYPE_CHECKING:
- from ost import mol
+ import biotite.structure as struc
+ from rdkit import Chem
from biotite.sequence.io.fasta import FastaFile
-from plinder.core.index import utils
-from plinder.core.scores.links import query_links
+from plinder.core.index.query import query_table
+from plinder.core.release import PlinderRelease
from plinder.core.structure.structure import Structure
-from plinder.core.utils.cpl import get_plinder_path
-from plinder.core.utils.io import (
- download_alphafold_cif_file,
- download_pdb_chain_cif_file,
+from plinder.core.utils.config import get_config
+from plinder.core.utils.io import get_pdb_mmcif
+from plinder.data.annotations.save_utils import (
+ ReconstructedSystem,
+ SystemReconstructionOptions,
+ SystemReconstructionOutputs,
+ reconstruct_system,
+ save_ligands,
+ save_reconstructed_chain,
+ save_reconstructed_system,
)
-from plinder.core.utils.log import setup_logger
-from plinder.core.utils.unpack import get_zips_to_unpack
-LOG = setup_logger(__name__)
+
+def _ligand_sdf_groups(system_df: pd.DataFrame) -> dict[str, list[str]]:
+ """Map each ligand's primary instance-chain to all its member instance-chains.
+
+ A multi-chain covalent ligand spans several chains; its reconstructed SDF must
+ contain all of them (matching the ingest writer and the stored SMILES), so we
+ read the serialized ``ligand_instance_chains``.
+ """
+ groups: dict[str, list[str]] = {}
+ for _, row in system_df.iterrows():
+ primary = str(row["ligand_instance_chain"])
+ groups[primary] = sorted(str(chain) for chain in row["ligand_instance_chains"])
+ return groups
+
+
+def _extract_packed_ligand_sdfs(
+ *, archive: Path, pdb_id: str, asym_ids: set[str]
+) -> Path:
+ """Extract only one system's canonical SDFs from its shard parquet."""
+ folder = archive.parent / pdb_id / "ligand_files"
+ missing = {
+ asym_id for asym_id in asym_ids if not (folder / f"{asym_id}.sdf").is_file()
+ }
+ if not missing:
+ return folder
+ packed = pd.read_parquet(
+ archive,
+ columns=["ligand_asym_id", "sdf"],
+ filters=[("pdb_id", "==", pdb_id), ("ligand_asym_id", "in", sorted(missing))],
+ )
+ observed = set(packed["ligand_asym_id"].astype(str))
+ absent = sorted(missing.difference(observed))
+ if absent:
+ raise ValueError(f"canonical ligand SDFs are missing for {pdb_id}: {absent}")
+ folder.mkdir(exist_ok=True, parents=True)
+ for row in packed.itertuples(index=False):
+ target = folder / f"{row.ligand_asym_id}.sdf"
+ temporary = target.with_name(f".{target.name}.{uuid4().hex}.tmp")
+ try:
+ temporary.write_bytes(row.sdf)
+ temporary.replace(target)
+ finally:
+ temporary.unlink(missing_ok=True)
+ return folder
class PlinderSystem:
"""
Core class for interacting with a single system and its assets.
- Relies on the entry data to populate the system, system zips
- to obtain structure files, and the linked_structures archive
- for linked structures.
+ Annotation data is queried lazily for one entry or system. Release structure
+ views are reconstructed from a deposited PDB mmCIF cached under the
+ configured PLINDER directory; canonical ASU ligand SDFs are loaded from the
+ ligand archive independently. An explicit source mmCIF can override the
+ managed cache.
+
"""
def __repr__(self) -> str:
@@ -43,74 +94,244 @@ def __init__(
self,
*,
system_id: str,
+ release: PlinderRelease | None = None,
prune: bool = True,
skip_3d_confgen: bool = False,
+ complete_missing_atoms: bool = False,
+ source_mmcif: Path | str | None = None,
+ reconstruction_dir: Path | str | None = None,
+ canonical_ligand_dir: Path | str | None = None,
+ biounit_chains: pd.DataFrame | None = None,
+ reconstruction_options: SystemReconstructionOptions = (
+ SystemReconstructionOptions()
+ ),
) -> None:
self.system_id: str = system_id
+ self.release = release or PlinderRelease()
self.prune: bool = prune
self.skip_3d_confgen: bool = skip_3d_confgen
- self._entry: dict[str, Any] | None = None
- self._system: dict[str, Any] | None = None
- self._archive: Path | None = None
- self._chain_mapping: dict[str, Any] | None = None
- self._water_mapping: dict[str, Any] | None = None
- self._linked_structures: pd.DataFrame | None = None
- self._linked_archive: Path | None = None
+ self.complete_missing_atoms: bool = complete_missing_atoms
+ self.source_mmcif = Path(source_mmcif) if source_mmcif is not None else None
+ default_reconstruction_root = (
+ Path(self.release.data_dir)
+ if self.release.data_dir is not None
+ else Path(get_config().data.plinder_dir)
+ )
+ self.reconstruction_dir = (
+ Path(reconstruction_dir)
+ if reconstruction_dir is not None
+ else default_reconstruction_root / "reconstructed_systems" / system_id
+ )
+ self.canonical_ligand_dir = (
+ Path(canonical_ligand_dir) if canonical_ligand_dir is not None else None
+ )
+ self.reconstruction_options = reconstruction_options
+ self._entry: pd.DataFrame | None = None
+ self._system: pd.DataFrame | None = None
+ self._entry_chains: pd.DataFrame | None = None
+ self._linked_apo_structures: pd.DataFrame | None = None
+ self._biounit_chains = (
+ biounit_chains.copy() if biounit_chains is not None else None
+ )
+ self._reconstructed: ReconstructedSystem | None = None
+ self._canonical_ligand_folder: Path | None = None
@property
- def entry(self) -> dict[str, Any] | None:
+ def entry(self) -> pd.DataFrame:
"""
- Store a reference to the entry JSON for this system
+ Store the annotation rows for this PDB entry.
Returns
-------
- dict[str, Any] | None
- entry JSON
+ pd.DataFrame
+ Ligand-level annotation rows for the entry.
"""
if self._entry is None:
entry_pdb_id = self.system_id.split("__")[0]
- try:
- entry = utils.load_entries(pdb_ids=[entry_pdb_id], prune=self.prune)
- self._entry = entry[entry_pdb_id]
- except KeyError:
- raise ValueError(f"pdb_id={entry_pdb_id} not found in entries")
+ self._entry = query_table(
+ "annotation",
+ columns=["*"],
+ filters=[("entry_pdb_id", "==", entry_pdb_id)],
+ joins=["entry_metadata"],
+ release=self.release,
+ )
+ if self._entry.empty:
+ raise ValueError(
+ f"pdb_id={entry_pdb_id} not found in the annotation index"
+ )
return self._entry
@property
- def system(self) -> dict[str, Any] | None:
+ def system(self) -> pd.DataFrame:
"""
- Return the system metadata from the original entry JSON
+ Return ligand-level annotation rows for this system.
Returns
-------
- dict[str, Any] | None
- system metadata
+ pd.DataFrame
+ Annotation rows for the system.
"""
if self._system is None:
- try:
- assert self.entry is not None
- self._system = self.entry["systems"][self.system_id]
- except KeyError:
- raise ValueError(f"system_id={self.system_id} not found in entry")
+ self._system = query_table(
+ "annotation",
+ columns=["*"],
+ filters=[("system_id", "==", self.system_id)],
+ joins=["entry_metadata"],
+ release=self.release,
+ )
+ if self._system.empty:
+ raise ValueError(f"system_id={self.system_id} not found in the index")
return self._system
@property
- def archive(self) -> Path | None:
+ def receptor_type(self) -> str:
+ """Return the receptor polymer composition recorded during ingestion."""
+ column = "system_receptor_type"
+ if column not in self.system.columns:
+ raise ValueError(
+ f"{column} is unavailable for {self.system_id}; "
+ "this release predates receptor-type annotation"
+ )
+ values = self.system[column].dropna().astype(str).unique()
+ if len(values) != 1 or not values[0]:
+ raise ValueError(
+ f"Expected one receptor type for {self.system_id}, "
+ f"got {values.tolist()}"
+ )
+ return str(values[0])
+
+ @property
+ def receptor_chain_types(self) -> dict[str, str]:
+ """Map each system receptor instance chain to its polymer type."""
+ if self._entry_chains is None:
+ path = self.release.fetch("entry_chains")
+ pdb_id = self.system_id.split("__", maxsplit=1)[0]
+ self._entry_chains = pd.read_parquet(
+ path,
+ filters=[("entry_pdb_id", "==", pdb_id)],
+ )
+ required = {"chain_asym_id", "chain_receptor_type"}
+ missing_columns = required.difference(self._entry_chains.columns)
+ if missing_columns:
+ raise ValueError(
+ "Entry-chain receptor types are unavailable; missing columns "
+ f"{sorted(missing_columns)}"
+ )
+ asym_to_type = dict(
+ zip(
+ self._entry_chains["chain_asym_id"].astype(str),
+ self._entry_chains["chain_receptor_type"].astype(str),
+ )
+ )
+ instance_chains = list(self.system.iloc[0]["system_protein_chains_asym_id"])
+ result = {}
+ for instance_chain in instance_chains:
+ asym_id = str(instance_chain).split(".", maxsplit=1)[-1]
+ if asym_id not in asym_to_type:
+ raise ValueError(
+ f"No receptor-chain type found for {instance_chain} in "
+ f"{self.system_id}"
+ )
+ result[str(instance_chain)] = asym_to_type[asym_id]
+ return result
+
+ @property
+ def biounit_chains(self) -> pd.DataFrame:
+ """Return ingested chain membership for this biological assembly."""
+ if self._biounit_chains is None:
+ path = self.release.fetch("entry_biounit_chains")
+ row = self.system.iloc[0]
+ self._biounit_chains = pd.read_parquet(
+ path,
+ filters=[
+ ("entry_pdb_id", "==", str(row["entry_pdb_id"])),
+ ("biounit_id", "==", str(row["system_biounit_id"])),
+ ],
+ )
+ if self._biounit_chains.empty:
+ raise ValueError(
+ f"No biological-assembly chain metadata for {self.system_id}"
+ )
+ return self._biounit_chains
+
+ @property
+ def source_mmcif_path(self) -> Path:
+ """Return the explicit or release-cached deposited PDB mmCIF."""
+ if self.source_mmcif is None:
+ manifest = self.release.fetch("entry_sources")
+ cache_dir = (
+ Path(self.release.data_dir) / get_config().data.source_mmcifs
+ if self.release.data_dir is not None
+ else None
+ )
+ self.source_mmcif = get_pdb_mmcif(
+ self.system_id,
+ cache_dir=cache_dir,
+ manifest_path=manifest,
+ )
+ if not self.source_mmcif.is_file():
+ raise FileNotFoundError(self.source_mmcif)
+ return self.source_mmcif
+
+ @property
+ def reconstructed(self) -> ReconstructedSystem:
+ """In-memory biological-assembly views reconstructed from source mmCIF."""
+ if self._reconstructed is None:
+ self._reconstructed = reconstruct_system(
+ self.source_mmcif_path,
+ self.system.iloc[0],
+ biounit_chains=self.biounit_chains,
+ options=self.reconstruction_options,
+ )
+ return self._reconstructed
+
+ def reconstruct(
+ self,
+ *,
+ outputs: SystemReconstructionOutputs,
+ options: SystemReconstructionOptions | None = None,
+ overwrite: bool = False,
+ ) -> dict[str, Path]:
+ """Write exactly the requested reconstructed assets."""
+ selected_options = options or self.reconstruction_options
+ cached = (
+ self.reconstructed
+ if selected_options == self.reconstruction_options
+ else None
+ )
+ return save_reconstructed_system(
+ self.source_mmcif_path,
+ self.system.iloc[0],
+ outputs=outputs,
+ biounit_chains=self.biounit_chains,
+ options=selected_options,
+ overwrite=overwrite,
+ reconstructed=cached,
+ )
+
+ def _ensure_standard_output(self, name: str) -> Path:
+ path = self.reconstruction_dir / name
+ if not path.is_file():
+ output_name = {
+ "system.cif": "system_cif",
+ "receptor.cif": "receptor_cif",
+ "sequences.fasta": "sequences_fasta",
+ }[name]
+ self.reconstruct(outputs=SystemReconstructionOutputs(**{output_name: path}))
+ return path
+
+ @property
+ def archive(self) -> Path:
"""
Return the path to the directory containing the plinder system
Returns
-------
- Path | None
+ Path
directory containing the plinder system
"""
- if self._archive is None:
- zips = get_zips_to_unpack(kind="systems", system_ids=[self.system_id])
- [archive] = list(zips.keys())
- self._archive = archive.parent / self.system_id
- if not self._archive.is_dir():
- raise ValueError(f"system_id={self.system_id} not found in systems")
- return self._archive
+ self.reconstruction_dir.mkdir(parents=True, exist_ok=True)
+ return self.reconstruction_dir
@property
def system_cif(self) -> str:
@@ -122,8 +343,7 @@ def system_cif(self) -> str:
str
path
"""
- assert self.archive is not None
- return (self.archive / "system.cif").as_posix()
+ return self._ensure_standard_output("system.cif").as_posix()
@property
def receptor_cif(self) -> str:
@@ -135,21 +355,7 @@ def receptor_cif(self) -> str:
str
path
"""
- assert self.archive is not None
- return (self.archive / "receptor.cif").as_posix()
-
- @property
- def receptor_pdb(self) -> str:
- """
- Path to the receptor.pdb file
-
- Returns
- -------
- str
- path
- """
- assert self.archive is not None
- return (self.archive / "receptor.pdb").as_posix()
+ return self._ensure_standard_output("receptor.cif").as_posix()
@property
def sequences_fasta(self) -> str:
@@ -161,56 +367,57 @@ def sequences_fasta(self) -> str:
str
path
"""
- assert self.archive is not None
- return (self.archive / "sequences.fasta").as_posix()
+ return self._ensure_standard_output("sequences.fasta").as_posix()
@cached_property
def sequences(self) -> dict[str, str]:
"""
- Path to the sequences.fasta file
+ Parsed FASTA contents from ``sequences.fasta``.
Returns
-------
- str
- path
+ dict[str, str]
+ Mapping from chain ID to sequence.
"""
- assert self.archive is not None
return {k: v for k, v in FastaFile.read_iter(self.sequences_fasta)}
@property
- def chain_mapping(self) -> dict[str, Any] | None:
- """
- Chain mapping metadata
-
- Returns
- -------
- dict[str, Any] | None
- chain mapping
- """
- if self._chain_mapping is None:
- assert self.archive is not None
- with (self.archive / "chain_mapping.json").open() as f:
- self._chain_mapping = json.load(f)
- return self._chain_mapping
-
- @property
- def water_mapping(self) -> dict[str, Any] | None:
- """
- Water mapping metadata
+ def canonical_ligand_sdfs(self) -> dict[str, str]:
+ """Map system ligand instances to the single canonical ASU SDF copy."""
+ if self._canonical_ligand_folder is None:
+ if self.canonical_ligand_dir is not None:
+ folder = self.canonical_ligand_dir
+ else:
+ pdb_id = self.system_id.split("__", maxsplit=1)[0]
+ asym_ids = set(self.system["ligand_asym_id"].astype(str))
+ code = pdb_id[1:3]
+ archive = self.release.fetch(
+ "ligand_archive",
+ shard=code,
+ )
+ folder = _extract_packed_ligand_sdfs(
+ archive=archive,
+ pdb_id=pdb_id,
+ asym_ids=asym_ids,
+ )
+ if not folder.is_dir():
+ raise ValueError(f"canonical ligand directory does not exist: {folder}")
+ self._canonical_ligand_folder = folder
- Returns
- -------
- dict[str, Any] | None
- water mapping
- """
- if self._water_mapping is None:
- assert self.archive is not None
- try:
- with (self.archive / "water_mapping.json").open() as f:
- self._water_mapping = json.load(f)
- except FileNotFoundError:
- return None
- return self._water_mapping
+ ligands = {}
+ for _, ligand in self.system.iterrows():
+ instance_chain = ligand.get("ligand_instance_chain")
+ if not isinstance(instance_chain, str) or not instance_chain:
+ instance_chain = (
+ f"{ligand['ligand_instance']}.{ligand['ligand_asym_id']}"
+ )
+ ligand_file = self._canonical_ligand_folder / (
+ f"{ligand['ligand_asym_id']}.sdf"
+ )
+ if not ligand_file.is_file():
+ raise ValueError(f"canonical ligand SDF does not exist: {ligand_file}")
+ ligands[instance_chain] = ligand_file.as_posix()
+ return ligands
@property
def ligand_sdfs(self) -> dict[str, str]:
@@ -222,10 +429,28 @@ def ligand_sdfs(self) -> dict[str, str]:
dict[str, str]
dictionary of ligand names to paths to ligand sdf files
"""
- assert self.archive is not None
- ligands = {}
- for ligand in (self.archive / "ligand_files/").glob("*.sdf"):
- ligands[ligand.stem] = ligand.as_posix()
+ ligand_dir = self.reconstruction_dir / "ligand_files"
+ instance_chains = list(self.canonical_ligand_sdfs)
+ missing = [
+ chain
+ for chain in instance_chains
+ if not (ligand_dir / f"{chain}.sdf").is_file()
+ ]
+ if missing:
+ # Pass the member-spanning groups (not a bare chain list) so a
+ # multi-chain covalent ligand is written as one whole molecule.
+ groups = _ligand_sdf_groups(self.system)
+ save_ligands(
+ self.reconstructed.biounit,
+ {chain: groups.get(chain, [chain]) for chain in missing},
+ ligand_dir,
+ )
+ ligands = {
+ chain: (ligand_dir / f"{chain}.sdf").as_posix() for chain in instance_chains
+ }
+ absent = [path for path in ligands.values() if not Path(path).is_file()]
+ if absent:
+ raise ValueError(f"failed to reconstruct ligand SDFs: {absent}")
return ligands
@property
@@ -238,126 +463,191 @@ def structures(self) -> list[str]:
list[str]
list of paths to structures
"""
- assert self.archive is not None
return [path.as_posix() for path in self.archive.rglob("*") if path.is_file()]
@property
- def linked_structures(self) -> pd.DataFrame | None:
- """
- Return a dataframe of linked structures for this system. Note
- that the dataframe will include all of the scores for the linked
- structures as well, so that particular alternatives can be chosen
- accordingly.
+ def linked_apo_structures(self) -> pd.DataFrame:
+ """Return ranked deposited apo chains linked to this holo system."""
+ if self._linked_apo_structures is None:
+ path = self.release.fetch("linked_apo_structures")
+ self._linked_apo_structures = pd.read_parquet(
+ path,
+ filters=[("reference_system_id", "==", self.system_id)],
+ ).sort_values("rank", ignore_index=True)
+ return self._linked_apo_structures
+
+ def _linked_apo_row(self, linked_structure_id: str | None = None) -> pd.Series:
+ links = self.linked_apo_structures
+ if linked_structure_id is None:
+ selected = links.head(1)
+ else:
+ selected = links.loc[
+ links["linked_structure_id"].astype(str).eq(linked_structure_id)
+ ]
+ if selected.empty:
+ requested = linked_structure_id or "rank 1"
+ raise ValueError(
+ f"No linked apo structure {requested!r} for {self.system_id}"
+ )
+ if len(selected) != 1:
+ raise ValueError(
+ f"Linked apo ID {linked_structure_id!r} is not unique for "
+ f"{self.system_id}"
+ )
+ return selected.iloc[0]
+
+ def _linked_apo_source_mmcif(
+ self, row: pd.Series, source_mmcif: Path | str | None
+ ) -> Path | str:
+ if source_mmcif is not None:
+ return source_mmcif
+ manifest = self.release.fetch("entry_sources")
+ cache_dir = (
+ Path(self.release.data_dir) / get_config().data.source_mmcifs
+ if self.release.data_dir is not None
+ else None
+ )
+ return get_pdb_mmcif(
+ str(row["source_entry_id"]),
+ cache_dir=cache_dir,
+ manifest_path=manifest,
+ )
- Returns
- -------
- pd.DataFrame | None
- dataframe of linked structures if present in plinder
- """
- if self._linked_structures is None:
- links = query_links(filters=[("reference_system_id", "==", self.system_id)])
- self._linked_structures = links
- return self._linked_structures
+ def reconstruct_linked_apo(
+ self,
+ linked_structure_id: str | None = None,
+ *,
+ output_cif: Path | str | None = None,
+ source_mmcif: Path | str | None = None,
+ overwrite: bool = False,
+ ) -> Path:
+ """Reconstruct one linked apo chain from its deposited source mmCIF.
+
+ When ``linked_structure_id`` is omitted, the highest-ranked link is
+ selected. The result contains the exact biological-assembly chain that
+ was scored, with source sequence and chemical-component metadata.
+ """
+ row = self._linked_apo_row(linked_structure_id)
+ link_id = str(row["linked_structure_id"])
+ if output_cif is None:
+ output_cif = self.reconstruction_dir / "linked_apo" / f"{link_id}.cif"
+ return save_reconstructed_chain(
+ self._linked_apo_source_mmcif(row, source_mmcif),
+ assembly_id=str(row["source_biounit_id"]),
+ chain_instance=str(row["source_chain_instance"]),
+ source_asym_id=str(row["source_chain_asym_id"]),
+ output_cif=output_cif,
+ structure_id=link_id,
+ overwrite=overwrite,
+ )
- @property
- def linked_archive(self) -> Path | None:
- """
- Path to linked structures archive if it exists
+ def superpose_linked_apo(
+ self,
+ linked_structure_id: str | None = None,
+ *,
+ reference_chain: str | None = None,
+ output_cif: Path | str | None = None,
+ source_mmcif: Path | str | None = None,
+ overwrite: bool = False,
+ ) -> Path:
+ """Reconstruct and fit one linked apo chain to a holo receptor chain.
+
+ The reference chain is inferred when the holo receptor contains one
+ protein chain. Multichain receptors require ``reference_chain`` so the
+ fit is never chosen arbitrarily.
+ """
+ import biotite.structure as struc
+
+ receptor = self.receptor_structure
+ ca_mask = struc.filter_amino_acids(receptor) & (
+ receptor.atom_name.astype(str) == "CA"
+ )
+ protein_chains = sorted(set(receptor.chain_id[ca_mask].astype(str)))
+ if reference_chain is None:
+ if len(protein_chains) != 1:
+ raise ValueError(
+ "reference_chain is required when the holo receptor has "
+ f"{len(protein_chains)} protein chains: {protein_chains}"
+ )
+ reference_chain = protein_chains[0]
+ if reference_chain not in protein_chains:
+ raise ValueError(
+ f"Reference chain {reference_chain!r} is not a protein chain in "
+ f"{self.system_id}; available chains are {protein_chains}"
+ )
+ reference_atoms = receptor[
+ receptor.chain_id.astype(str) == str(reference_chain)
+ ]
+
+ row = self._linked_apo_row(linked_structure_id)
+ link_id = str(row["linked_structure_id"])
+ if output_cif is None:
+ output_cif = (
+ self.reconstruction_dir / "linked_apo" / f"{link_id}_superposed.cif"
+ )
+ return save_reconstructed_chain(
+ self._linked_apo_source_mmcif(row, source_mmcif),
+ assembly_id=str(row["source_biounit_id"]),
+ chain_instance=str(row["source_chain_instance"]),
+ source_asym_id=str(row["source_chain_asym_id"]),
+ output_cif=output_cif,
+ structure_id=link_id,
+ superpose_to=reference_atoms,
+ overwrite=overwrite,
+ )
- Returns
- -------
- Path | None
- path to linked structures archive
+ @cached_property
+ def receptor_structure(self) -> "struc.AtomArray":
"""
- if self._linked_archive is None:
- zips = get_zips_to_unpack(kind="linked_structures")
- if not len(zips):
- LOG.info("no linked_structures found, downloading now, stand by")
- get_plinder_path(rel="linked_structures")
- zips = get_zips_to_unpack(kind="linked_structures")
- archive = list(zips.keys())[0]
- self._linked_archive = archive.parent
-
- return self._linked_archive
-
- def get_linked_structure(self, link_kind: str, link_id: str) -> str:
+ Return the receptor structure as biotite AtomArray.
"""
- Get the path to the requested linked structure
+ import biotite.structure.io.pdbx as pdbx
+ from biotite.structure import filter_heavy
- Parameters
- ----------
- link_kind : str
- kind of linked structure ('apo', 'pred', 'holo')
- link_id : str
- id of linked structure
+ from plinder.data.annotations.cif_utils import read_mmcif_file
- Returns
- -------
- str
- path to linked structure
- """
- if self.linked_archive is None:
- raise ValueError("linked_archive is None!")
- allowed = ["apo", "pred", "holo"]
- assert link_kind in allowed, f"link_kind={link_kind} not in {allowed}"
- structure = self.linked_archive / f"{link_id}.cif"
- if not structure.is_file():
- if link_kind == "apo":
- pdb_id, chain_id = link_id.split("_")
- try:
- download_pdb_chain_cif_file(pdb_id, chain_id, structure)
- except Exception as e:
- raise ValueError(f"Unable to download {link_id}! {str(e)}")
- elif link_kind == "pred":
- uniprot_id = link_id.split("_")[0]
- cif_file_path = download_alphafold_cif_file(
- uniprot_id, self.linked_archive
- )
- if cif_file_path is None:
- raise ValueError(f"Unable to download {link_id}")
- cif_file_path.rename(structure)
- elif link_kind == "holo":
- structure = Path(PlinderSystem(system_id=link_id).receptor_cif)
- if structure is None or not structure.is_file():
- raise ValueError(f"structure={structure} does not exist!")
- return structure.as_posix()
+ cif_file = read_mmcif_file(self.receptor_cif)
+ atoms = pdbx.get_structure(
+ cif_file, model=1, use_author_fields=False, include_bonds=True
+ )
+ return atoms[filter_heavy(atoms)]
@cached_property
- def receptor_entity(self) -> "mol.EntityHandle":
- """
- Return the receptor entity handle
+ def ligand_structures(self) -> dict[str, "struc.AtomArray"]:
+ """Return heavy-atom ligand structures as Biotite atom arrays."""
+ from biotite.structure import filter_heavy
+ from biotite.structure.io.mol import SDFile
- Returns
- -------
- mol.EntityHandle
- receptor entity handle
- """
- try:
- from ost import io
- except ImportError:
- raise ImportError("Please install openstructure to use this property")
- return io.LoadMMCIF(self.receptor_cif)
+ structures = {}
+ for chain, ligand_sdf in self.ligand_sdfs.items():
+ atoms = SDFile.read(ligand_sdf).record.get_structure()
+ structures[chain] = atoms[filter_heavy(atoms)]
+ return structures
@cached_property
- def ligand_views(self) -> dict[str, "mol.ResidueView"]:
+ def ligand_mols(self) -> dict[str, "Chem.Mol"]:
"""
- Return the ligand views
-
- Returns
- -------
- dict[str, mol.ResidueView]
+ Return the ligand molecules as RDKit Mol objects.
"""
- try:
- from ost import io
- except ImportError:
- raise ImportError("Please install openstructure to use this property")
+ # TODO(peppr): temporary local sanitize carrying boron/main-group
+ # over-valence fixes not yet in a released peppr. Revert to
+ # `from peppr import sanitize as peppr_sanitize` once upstream.
+ # See plinder.core.utils.sanitize.
+ from rdkit import Chem
+
+ from plinder.core.utils.sanitize import sanitize as peppr_sanitize
- ligand_views = {}
+ mols = {}
for chain in self.ligand_sdfs:
- ligand_views[chain] = io.LoadEntity(
- self.ligand_sdfs[chain], format="sdf"
- ).Select("ele != H")
- return ligand_views
+ supplier = Chem.SDMolSupplier(self.ligand_sdfs[chain], sanitize=False)
+ mol = next(supplier, None)
+ if mol is not None:
+ peppr_sanitize(mol)
+ # ring info survives the removal here; a second sanitize is not
+ # free, it re-perceives stereo (drops centres on 1fbh ligands)
+ mol = Chem.RemoveAllHs(mol, sanitize=False)
+ mols[chain] = mol
+ return mols
@property
def num_ligands(self) -> int:
@@ -381,29 +671,6 @@ def num_proteins(self) -> int:
"""
return len(self.system_id.split("__")[2].split("_"))
- @property
- def alternate_structures(self) -> dict[str, Structure]:
- """
- load all alternate structures
- """
- # TODO: do we want to keep this as assertion?
- # better if then raise?
- assert self.linked_structures is not None
-
- structures = {}
- for id, kind in self.linked_structures[["id", "kind"]].values:
- protein_path = self.get_linked_structure(
- kind,
- id,
- )
- structures[id] = Structure(
- id=id,
- protein_path=Path(protein_path),
- protein_sequence=self.sequences,
- structure_type=kind,
- )
- return structures
-
@property
def holo_structure(self) -> Structure:
"""
@@ -417,21 +684,25 @@ def holo_structure(self) -> Structure:
ligand_smiles=self.smiles,
skip_3d_confgen=self.skip_3d_confgen,
structure_type="holo",
+ complete_missing_atoms=self.complete_missing_atoms,
)
@cached_property
def smiles(self) -> dict[str, str] | None:
- if self.system is None:
- return None
smiles_dict = {}
- try_smiles = ["rdkit_canonical_smiles", "smiles", "resolved_smiles"]
- for ligand in self.system["ligands"]:
+ try_smiles = [
+ "ligand_smiles",
+ "ligand_resolved_smiles",
+ ]
+ for _, ligand in self.system.iterrows():
+ ligand_key = f"{ligand['ligand_instance']}.{ligand['ligand_asym_id']}"
found = False
for s in try_smiles:
- if s in ligand and ligand[s] is not None and len(ligand[s]):
- smiles_dict[f"{ligand['instance']}.{ligand['asym_id']}"] = ligand[s]
+ value = ligand.get(s)
+ if value is not None and isinstance(value, str) and value:
+ smiles_dict[ligand_key] = value
found = True
break
if not found:
- smiles_dict[f"{ligand['instance']}.{ligand['asym_id']}"] = ""
+ smiles_dict[ligand_key] = ""
return smiles_dict
diff --git a/src/plinder/core/index/utils.py b/src/plinder/core/index/utils.py
index 9985f10b5..f5a1aed02 100644
--- a/src/plinder/core/index/utils.py
+++ b/src/plinder/core/index/utils.py
@@ -3,209 +3,80 @@
from __future__ import annotations
from argparse import ArgumentParser
-from json import load
-from pathlib import Path
-from shutil import rmtree
from textwrap import dedent
from time import time
-from typing import Any, Optional
-from zipfile import ZipFile
-import pandas as pd
-from omegaconf import DictConfig
-
-from plinder.core.utils import cpl, unpack
+from plinder.core.release import RELEASE_PATHS, RELEASE_TABLES
+from plinder.core.utils import cpl
from plinder.core.utils.config import get_config
-from plinder.core.utils.dec import timeit
from plinder.core.utils.log import setup_logger
-from plinder.core.utils.unpack import get_zips_to_unpack
LOG = setup_logger(__name__)
-_PLINDEX = None
-_MANIFEST = None
-
-
-@timeit
-def get_plindex() -> pd.DataFrame:
- """
- Fetch the plindex and cache it
-
- Parameters
- ----------
- cfg : DictConfig, default=None
- the plinder-core config
-
- Returns
- -------
- pd.DataFrame
- the plindex
- """
- from plinder.core.scores import query_index
-
- global _PLINDEX
-
- if _PLINDEX is not None:
- return _PLINDEX
- _PLINDEX = query_index(columns=["*"], splits=["*"])
- return _PLINDEX
-
-
-def get_manifest() -> pd.DataFrame:
- """
- Fetch the manifest and cache it
-
- Parameters
- ----------
- cfg : DictConfig, default=None
- the plinder-core config
- plindex : pd.DataFrame, default=None
- the plindex
-
- Returns
- -------
- pd.DataFrame
- the manifest
- """
- from plinder.core.scores import query_index
-
- global _MANIFEST
-
- if _MANIFEST is not None:
- return _MANIFEST
- _MANIFEST = query_index(columns=["system_id", "entry_pdb_id"], splits=["*"])
- return _MANIFEST
-
-
-def _prune_entry(entry: dict[str, Any]) -> dict[str, Any]:
- """
- Prune the entry as in Entry.prune
-
- Parameters
- ----------
- entry : dict[str, Any]
- the entry
-
- Returns
- -------
- dict[str, Any]
- the pruned entry
- """
- entry["systems"] = {
- id_: s
- for id_, s in entry["systems"].items()
- if any(not l["is_ion"] and not l["is_artifact"] for l in s["ligands"])
- and len(
- set(
- chain
- for ligand in s["ligands"]
- for chain in sorted(ligand["interacting_residues"].keys())
- )
- )
- <= 5
- and len(s["ligands"]) <= 5
- }
- return entry
+_DOWNLOAD_GROUPS = (
+ (
+ "index tables",
+ tuple(
+ dict.fromkeys(str(table["artifact"]) for table in RELEASE_TABLES.values())
+ ),
+ False,
+ ),
+ (
+ "representative-cover tables",
+ ("ligand_sampling", "interface_sampling"),
+ False,
+ ),
+ (
+ "complete similarity exports",
+ (
+ "protein_similarity_scores",
+ "monomer_similarity_scores",
+ "ligand_similarity_scores",
+ "interface_similarity_scores",
+ "interface_half_similarity_scores",
+ ),
+ True,
+ ),
+ ("canonical ligand archives", ("ligand_archives",), True),
+ ("ligand similarities", ("ligand_scores",), True),
+ ("protein alignment CIGARs", ("alignment_cigars",), True),
+ ("custom-scoring search databases", ("search_databases",), True),
+)
-@timeit
-def load_entries(
- *,
- cfg: Optional[DictConfig] = None,
- two_char_codes: list[str] | None = None,
- pdb_ids: list[str] | None = None,
- prune: bool = True,
-) -> dict[str, Any]:
- """
- Load the entries from a list of pdb IDs or two character codes.
- If no filters are provided, all entries are loaded.
-
- Parameters
- ----------
- cfg : DictConfig
- the plinder-core config
- two_char_codes : list[str] | None, default=None
- only consider particular two character codes
- pdb_ids : list[str] | None, default=None
- only consider particular pdb IDs
- Returns
- -------
- dict[str, Any]
- the entries
+def download_plinder_cmd(args: list[str] | None = None) -> None:
"""
- cfg = cfg or get_config()
- entry_dir = Path(cfg.data.plinder_dir) / cfg.data.entries
- entry_dir.mkdir(exist_ok=True, parents=True)
-
- zips = unpack.get_zips_to_unpack(
- kind=cfg.data.entries,
- cfg=cfg,
- two_char_codes=two_char_codes,
- pdb_ids=pdb_ids,
- )
- reduced: dict[str, Any] = {}
- LOG.info(f"loading entries from {len(zips)} zips")
- for zip_path, pdb_ids in zips.items():
- with ZipFile(zip_path) as archive:
- if len(pdb_ids):
- names = [f"{pdb_id}.json" for pdb_id in pdb_ids]
- else:
- names = archive.namelist()
- for name in names:
- with archive.open(name) as obj:
- pdb_id = name.replace(".json", "")
- # TODO: port Entry to plinder.core for model validation
- if prune:
- reduced[pdb_id] = _prune_entry(load(obj))
- else:
- reduced[pdb_id] = load(obj)
- LOG.info(f"loaded {len(reduced)} entries")
- return reduced
-
-
-def _remove_old_linked_structures(data_dir: Path) -> None:
- zips = (data_dir / "linked_structures").glob("*zip")
- for zip in zips:
- if zip.stem in ["apo", "pred"]:
- continue
- zip.unlink()
- done = zip.parent / (zip.stem + "_done")
- if done.is_file():
- done.unlink()
- if (data_dir / "linked_structures" / "apo").is_dir():
- LOG.info("found old apo linked structures, removing")
- rmtree(data_dir / "linked_structures" / "apo")
- if (data_dir / "linked_structures" / "pred").is_dir():
- LOG.info("found old pred linked structures, removing")
- rmtree(data_dir / "linked_structures" / "pred")
+ Download published PLINDER release artifacts for the current configuration.
+ Source PDB mmCIFs are not included. They are fetched and cached per PDB
+ entry when reconstruction needs them.
-def download_plinder_cmd(args: list[str] | None = None) -> None:
- """
- Download the full plinder dataset for the current configuration.
Note that even though this is wrapped in a progress bar, the estimated
completion time can vary wildly as it iterates over larger files vs.
smaller ones.
"""
t0 = time()
parser = ArgumentParser(usage=download_plinder_cmd.__doc__)
- parser.add_argument("--release", default=None, help="plinder release")
- parser.add_argument("--iteration", default=None, help="plinder iteration")
+ parser.add_argument(
+ "--release",
+ default=None,
+ help="ingest month for the PLINDER release (YYYY-MM)",
+ )
+ parser.add_argument(
+ "--release-number",
+ default=None,
+ help="numbered release within the ingest month",
+ )
parser.add_argument("-y", "--yes", action="store_true", help="skip confirmation")
- ns, args = parser.parse_known_args(args=args)
+ ns = parser.parse_args(args=args)
autodo = ns.yes
- if len(args):
- LOG.warning(f"ignoring arguments {args}")
- kwargs = None
+ release_config = {}
if ns.release is not None:
- kwargs = dict(data=dict(plinder_release=ns.release))
- if ns.iteration is not None:
- if kwargs is None:
- kwargs = dict(data=dict(plinder_iteration=ns.iteration))
- else:
- kwargs["data"]["plinder_iteration"] = ns.iteration
- cfg = get_config(config=kwargs)
+ release_config["plinder_release"] = ns.release
+ if ns.release_number is not None:
+ release_config["plinder_release_number"] = ns.release_number
+ cfg = get_config(config={"data": release_config} if release_config else None)
LOG.info(
dedent(
f"""
@@ -217,94 +88,44 @@ def download_plinder_cmd(args: list[str] | None = None) -> None:
"""
)
)
- LOG.debug("cleaning up old linked structures")
- _remove_old_linked_structures(Path(cfg.data.plinder_dir))
- for attr in cfg.data:
- if (
- attr.startswith("plinder_")
- or attr.endswith("_file")
- or attr in ["ingest", "validation", "force_update"]
- ):
+ for label, artifact_names, large_download in _DOWNLOAD_GROUPS:
+ do_download = autodo or not large_download
+ if large_download and not autodo:
+ answer = input(f"Download {label}? [Y/n] ").strip().lower()
+ do_download = answer in {"", "y", "yes"}
+ if not do_download:
+ LOG.info(f"skipping {label}; its files are fetched when requested")
continue
- path = None
- if attr == "scores":
- do = (
- input("Download the full scores dataset? [Y/n] ").lower()
- in ["", "y", "yes"]
- if not autodo
- else True
- )
- if do:
- for subdb in ["apo", "pred", "holo"]:
- msg = f"Syncing {getattr(cfg.data, attr)}/search_db={subdb}"
- if subdb == "holo":
- msg += ", this may take a while!"
- LOG.info(msg)
- if subdb == "holo":
- LOG.info(
- "Note that the tqdm progress bar for holo is not very useful, please be patient!"
- )
- cpl.get_plinder_path(
- rel=f"{getattr(cfg.data, attr)}/search_db={subdb}",
- force_progress=True,
- )
- else:
- LOG.info(
- "skipping scores download, plinder.core.scores will download it lazily on request!"
- )
- else:
- msg = f"Syncing {getattr(cfg.data, attr)}"
- do = True
- if attr in ["linked_structures", "systems"]:
- if not autodo:
- do = input(f"Download the {attr} dataset? [Y/n] ").lower() in [
- "",
- "y",
- "yes",
- ]
- else:
- do = True
- msg += ", this may take a while!"
- if do:
- LOG.info(msg)
- path = cpl.get_plinder_path(
- rel=getattr(cfg.data, attr),
- force_progress=True,
+ LOG.info(f"syncing {label}")
+ for artifact_name in artifact_names:
+ artifact_path = RELEASE_PATHS[artifact_name]
+ if "{" in artifact_path:
+ raise RuntimeError(
+ f"bulk download cannot resolve parameterized artifact "
+ f"{artifact_name}"
)
- else:
- LOG.info(
- f"skipping {attr} download, plinder.core.PlinderSystem will download lazily as needed on request!"
- )
- if path is not None and attr in ["linked_structures", "systems"]:
- LOG.info(
- f"extracting {getattr(cfg.data, attr)} archives, you may want to stretch your legs."
+ cpl.get_plinder_path(
+ rel=artifact_path,
+ force_progress=large_download,
)
- codes: list[str] | None = [p.stem for p in path.glob("*zip")]
- if attr == "linked_structures":
- codes = None
- get_zips_to_unpack(kind=attr, two_char_codes=codes)
t1 = time()
total = t1 - t0
timing = f"{total:.2f}s"
- if total > 60:
- timing = f"{total / 60:.2f}m"
- elif total > 3600:
+ if total > 3600:
timing = f"{total / 3600:.2f}h"
+ elif total > 60:
+ timing = f"{total / 60:.2f}m"
LOG.info(
dedent(
f"""
Sync complete in {timing}!
- If you downloaded all of the data, you can run:
-
- export PLINDER_OFFLINE=true
-
- This will avoid checking that files are still in sync when using plinder.core.
- If you didn't download all of the data, plinder.core will download it lazily when
- it's needed. By default, plinder.core will check that files are still in sync
- in case any of the files for an existing release need to be patched.
+ If you skipped large groups, plinder.core fetches their files when
+ requested unless offline mode is enabled. Use
+ plinder.core.download_pdb_mmcifs(...) if offline system reconstruction
+ is needed.
"""
)
)
diff --git a/src/plinder/core/loader/dataset.py b/src/plinder/core/loader/dataset.py
index 7e1bfc129..596676949 100644
--- a/src/plinder/core/loader/dataset.py
+++ b/src/plinder/core/loader/dataset.py
@@ -4,33 +4,29 @@
from typing import Any, Callable
-import pandas as pd
import torch
from torch.utils.data import DataLoader, Dataset
+from plinder.core.index.query import Filters, query_table
from plinder.core.index.system import PlinderSystem
from plinder.core.loader.featurizer import structure_featurizer
from plinder.core.loader.utils import collate_batch
-from plinder.core.scores import query_index
-from plinder.core.scores.query import FILTERS
from plinder.core.structure.structure import Structure
from plinder.core.utils.log import setup_logger
LOG = setup_logger(__name__)
-class PlinderDataset(Dataset): # type: ignore
+class PlinderDataset(Dataset[dict[str, Any]]):
"""
Creates a dataset from plinder systems
Parameters
----------
- split : str
- the split to sample from
- filters: FILTERS, default=None
+ filters: Filters, default=None
Index filter to select specific system ids
- use_alternate_structures: bool, default=True
- Whether to load alternate structures
+ system_factory: Callable[[str], PlinderSystem] | None, default=None
+ Optional function that creates a system from its system ID
featurizer: Callable[
[Structure, int], dict[str, torch.Tensor]
] = structure_featurizer,
@@ -39,31 +35,32 @@ class PlinderDataset(Dataset): # type: ignore
def __init__(
self,
- split: str,
- filters: FILTERS = None,
- use_alternate_structures: bool = True,
+ filters: Filters = None,
featurizer: Callable[
[Structure], torch.Tensor | dict[str, torch.Tensor]
] = structure_featurizer,
- **kwargs: Any,
+ system_factory: Callable[[str], PlinderSystem] | None = None,
):
- index = query_index(splits=[split], filters=filters)
+ index = query_table("annotation", columns=["system_id"], filters=filters)
LOG.info(f"Loading {index.system_id.nunique()} systems")
- self._system_ids = list(set(index["system_id"]))
+ self._system_ids = index["system_id"].drop_duplicates().tolist()
self._num_examples = len(self._system_ids)
self._featurizer = featurizer
- self._use_alternate_structures = use_alternate_structures
+ self._system_factory = system_factory
def __len__(self) -> int:
return self._num_examples
- def __getitem__(
- self, index: int
- ) -> dict[str, int | str | pd.DataFrame | dict[str, str | pd.DataFrame]]:
+ def __getitem__(self, index: int) -> dict[str, Any]:
if not 0 <= index < self._num_examples:
raise IndexError(index)
- s = PlinderSystem(system_id=self._system_ids[index])
+ system_id = self._system_ids[index]
+ s = (
+ PlinderSystem(system_id=system_id)
+ if self._system_factory is None
+ else self._system_factory(system_id)
+ )
holo_structure = s.holo_structure
features_and_coords = None
@@ -73,9 +70,6 @@ def __getitem__(
item: dict[str, Any] = {
"system_id": holo_structure.id,
"holo_structure": holo_structure,
- "alternate_structures": s.alternate_structures
- if self._use_alternate_structures
- else {},
"features_and_coords": features_and_coords,
"path": s.system_cif,
}
@@ -90,7 +84,7 @@ def get_torch_loader(
num_workers: int = 1,
collate_fn: Callable[[list[dict[str, Any]]], dict[str, Any]] = collate_batch,
**kwargs: Any,
-) -> DataLoader[PlinderDataset]:
+) -> DataLoader[dict[str, Any]]:
return DataLoader(
dataset,
batch_size=batch_size,
diff --git a/src/plinder/core/loader/featurizer.py b/src/plinder/core/loader/featurizer.py
index aedb337c8..7945f7fe9 100644
--- a/src/plinder/core/loader/featurizer.py
+++ b/src/plinder/core/loader/featurizer.py
@@ -1,4 +1,4 @@
-from typing import Any
+from typing import Any, cast
import torch
@@ -8,7 +8,7 @@
_stack_atom_array_features,
_stack_ligand_feat,
)
-from plinder.core.structure.diffdock_utils import lig_atom_featurizer
+from plinder.core.structure.smallmols_utils import ligand_atom_features
from plinder.core.structure.structure import Structure
from plinder.core.utils import constants as pc
@@ -36,7 +36,10 @@ def structure_featurizer(structure: Structure, pad_value: int = -100) -> dict[st
# Featurize and sort in input structure order
input_sequence_full_atom_feat_stack = _one_hot_encode_stack(
- [input_sequence_full_atom_feat[ch] for ch in protein_chain_order],
+ # _one_hot_encode_stack accepts per-chain element-name lists at runtime;
+ # its stack param is annotated narrower (list[NDArray]); cast keeps both
+ # the full-dep and the minimal-dep CI type env happy.
+ cast(Any, [input_sequence_full_atom_feat[ch] for ch in protein_chain_order]),
pc.ELE2NUM,
"other",
)
@@ -51,11 +54,10 @@ def structure_featurizer(structure: Structure, pad_value: int = -100) -> dict[st
protein_structure_residue_type_arr, pc.AA_TO_INDEX, "UNK"
)
]
- # TODO: Fix issues with ligands conformer generation
- # Featurize and stack ligand chains
- # VO: try passing the 2D - does not need a conformer!
+ # Ligand atom features come from the 2D SMILES templates: they only use
+ # graph properties, so no conformer is needed.
input_conformer_ligand_feat = {
- ch: lig_atom_featurizer(ligand_mol)
+ ch: ligand_atom_features(ligand_mol)
for ch, ligand_mol in input_ligand_templates.items()
}
# Stack in ligand_chain_order order
@@ -76,10 +78,11 @@ def structure_featurizer(structure: Structure, pad_value: int = -100) -> dict[st
coord
for coord in _stack_ligand_feat(resolved_ligand_mols_coords, ligand_chain_order)
]
- features = {
+ features: dict[str, Any] = {
"sequence_atom_mask_feature": sequence_atom_mask_stacked,
"input_sequence_residue_mask_feature": input_sequence_residue_mask_stacked,
"protein_coordinates": protein_coordinates_stacked,
+ "protein_atom_unresolved_mask": structure.protein_unresolved_atom_mask,
"protein_calpha_coordinates": protein_calpha_coordinates_stacked,
"input_sequence_full_atom_feature": input_sequence_full_atom_feat_stack,
"protein_structure_residue_feature": protein_structure_residue_type_stack,
diff --git a/src/plinder/core/loader/utils.py b/src/plinder/core/loader/utils.py
index 10dbd9311..d19794ef2 100644
--- a/src/plinder/core/loader/utils.py
+++ b/src/plinder/core/loader/utils.py
@@ -1,7 +1,6 @@
from __future__ import annotations
-from pathlib import Path
-from typing import Sequence
+from typing import Any, Sequence
import torch
from torch import Tensor
@@ -90,9 +89,9 @@ def pad_and_stack(
output: (2, 7, 7, 3)
"""
- assert (
- len({t.ndim for t in tensors}) == 1
- ), "All `tensors` must have the same number of dimensions."
+ assert len({t.ndim for t in tensors}) == 1, (
+ "All `tensors` must have the same number of dimensions."
+ )
# Pad all dims if none are specified
if dims_to_pad is None:
@@ -113,98 +112,49 @@ def collate_complex(
batch_features: list[dict[str, Tensor]],
pad_value: int = PAD_VALUE,
) -> dict[str, Tensor]:
- collated_and_padded_properties = {}
- batch_size = len(batch_features)
-
- feature_names = batch_features[0].keys()
- for feat_name in feature_names:
- collated_properties = []
- for idx in range(batch_size):
- feat = batch_features[idx][feat_name]
- collated_properties.append(feat)
- collated_and_padded_properties[feat_name] = pad_and_stack(
- collated_properties, dim=0, value=pad_value
+ return {
+ name: pad_and_stack(
+ [features[name] for features in batch_features], dim=0, value=pad_value
)
- return collated_and_padded_properties
-
-
-def collate_batch(
- batch: list[
- dict[
- str,
- list[str]
- | list[Structure]
- | list[dict[str, dict[str, Structure]]]
- | list[Path]
- | list[dict[str, Tensor]],
- ]
- ],
-) -> dict[
- str,
- list[str]
- | list[Structure]
- | list[dict[str, dict[str, Structure]]]
- | list[Path]
- | list[dict[str, Tensor]],
-]:
+ for name in batch_features[0]
+ }
+
+
+def collate_batch(batch: list[dict[str, Any]]) -> dict[str, Any]:
"""Collate a batch of PlinderDataset items into a merged mini-batch of Tensors.
Used as the default collate_fn for the torch DataLoader consuming PlinderDataset.
- Parameters:
- batch list[
- dict[
- str,
- list[str]
- | list[Structure]
- | list[dict[str, dict[str, Structure]]]
- | list[Path]
- | list[dict[str, Tensor]],
- ]
- ]: A list of dictionaries
- containing the data for each item in the batch.
+ Parameters
+ ----------
+ batch : list[dict[str, Any]]
+ Dataset items to combine.
- Returns:
- dict[
- str,
- list[str]
- | list[Structure]
- | list[dict[str, dict[str, Structure]]]
- | list[Path]
- | list[dict[str, Tensor]]
- A dictionary containing the merged items in the batch.
+ Returns
+ -------
+ dict[str, Any]
+ The combined batch.
"""
system_ids: list[str] = []
holo_structures: list[Structure] = []
- alternate_structures: list[dict[str, dict[str, Structure]]] = []
feature_and_coords: list[dict[str, Tensor]] = []
- paths: list[Path] = []
+ paths: list[str] = []
for x in batch:
assert isinstance(x["system_id"], str)
assert isinstance(x["holo_structure"], Structure)
- assert isinstance(x["alternate_structures"], dict)
assert isinstance(x["features_and_coords"], dict)
assert isinstance(x["path"], str)
system_ids.append(x["system_id"])
holo_structures.append(x["holo_structure"])
- alternate_structures.append(x["alternate_structures"])
feature_and_coords.append(x["features_and_coords"])
paths.append(x["path"])
- collated_batch: dict[
- str,
- list[str]
- | list[Structure]
- | list[dict[str, dict[str, Structure]]]
- | list[Path]
- | list[dict[str, Tensor]],
- ] = {
+ collated_batch: dict[str, Any] = {
"system_ids": system_ids,
"holo_structures": holo_structures,
- "alternate_structures": alternate_structures,
"paths": paths,
- "features_and_coords": collate_complex(feature_and_coords), # type: ignore
+ "features_and_coords": collate_complex(feature_and_coords),
}
return collated_batch
diff --git a/src/plinder/core/release.py b/src/plinder/core/release.py
new file mode 100644
index 000000000..648385cf1
--- /dev/null
+++ b/src/plinder/core/release.py
@@ -0,0 +1,279 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Paths and table keys for a published PLINDER release."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+from pathlib import Path
+from typing import Any
+
+from plinder.core.utils import cpl
+from plinder.core.utils.config import get_config
+
+
+def _require_file(path: Path, *, description: str) -> Path:
+ if path.is_file():
+ return path
+ mode = "offline cache" if cpl.is_offline() else "release cache"
+ raise FileNotFoundError(f"missing {description} in {mode}: {path}")
+
+
+def _release_file(
+ name: str,
+ *,
+ data_dir: Path | None,
+ description: str,
+ **parameters: str,
+) -> Path:
+ """Resolve a scoring file, preserving context in missing-file errors."""
+ release = PlinderRelease(data_dir)
+ if data_dir is not None:
+ return _require_file(release.path(name, **parameters), description=description)
+ try:
+ return release.fetch(name, **parameters)
+ except FileNotFoundError as exc:
+ mode = "offline cache" if cpl.is_offline() else "release cache"
+ raise FileNotFoundError(
+ f"missing {description} in {mode}: {release.path(name, **parameters)}"
+ ) from exc
+
+
+RELEASE_PATHS = {
+ "annotation_table": "index/annotation_table.parquet",
+ "system_validation": "index/system_validation.parquet",
+ "entry_chains": "index/entry_chains.parquet",
+ "entry_biounit_chains": "index/entry_biounit_chains.parquet",
+ "entry_metadata": "index/entry_metadata.parquet",
+ "entry_sources": "index/entry_sources.parquet",
+ "linked_apo_structures": "index/linked_apo_structures.parquet",
+ "interface_apo_structures": "index/interface_apo_structures.parquet",
+ "interface_annotations": "index/interface_annotation_table.parquet",
+ "alignment_chain_lookup": "index/alignment_chain_lookup.parquet",
+ "ligand_pocket_membership": "index/ligand_pocket_membership.parquet",
+ "ligand_pocket_residues": "index/ligand_pocket_residues.parquet",
+ "ligand_pocket_representatives": ("index/ligand_pocket_representatives.parquet"),
+ "ligand_clusters": "index/ligand_clusters.parquet",
+ "ligand_affinity": "index/ligand_affinity.parquet",
+ "bindingdb_measurements": "index/bindingdb_measurements.parquet",
+ "ligand_mmp_pairs": "index/ligand_mmp_pairs.parquet",
+ "interface_half_representatives": ("index/interface_half_representatives.parquet"),
+ "interface_membership": "index/interface_membership.parquet",
+ "interface_representatives": "index/interface_representatives.parquet",
+ "interface_clusters": "index/interface_clusters.parquet",
+ "protein_sequence_clusters": "protein_clusters/sequence.parquet",
+ "protein_structure_clusters": "protein_clusters/structure.parquet",
+ "alignment_cigars": "alignment_cigars",
+ "alignment_cigar_shard": (
+ "alignment_cigars/search_db={search_db}/alignment_type={alignment_type}/"
+ "shard={shard}.parquet"
+ ),
+ "ligand_archives": "ligand_archives",
+ "ligand_archive": "ligand_archives/{shard}.parquet",
+ "ligand_scores": "ligand_scores",
+ "ligand_sampling": "ligand_sampling",
+ "interface_sampling": "interface_sampling",
+ "search_databases": "search_databases",
+ "search_database": "search_databases/holo_{backend}",
+ "search_database_overlay": "search_databases/weekly_delta/holo_{backend}",
+ "monomer_search_database": "search_databases/monomer_{backend}",
+ "monomer_search_database_overlay": (
+ "search_databases/weekly_delta/monomer_{backend}"
+ ),
+ "search_database_shadowed_entries": "search_databases/shadowed_entries.parquet",
+ "protein_similarity_scores": "exports/protein_similarity_scores",
+ "protein_similarity_score_shard": (
+ "exports/protein_similarity_scores/alignment_type={alignment_type}/"
+ "shard={shard}.parquet"
+ ),
+ "monomer_similarity_scores": "exports/monomer_similarity_scores",
+ "ligand_similarity_scores": "exports/ligand_similarity_scores.parquet",
+ "interface_similarity_scores": "exports/interface_similarity_scores.parquet",
+ "interface_half_similarity_scores": (
+ "exports/interface_half_similarity_scores.parquet"
+ ),
+}
+
+
+RELEASE_TABLES: dict[str, dict[str, Any]] = {
+ "annotation": {
+ "artifact": "annotation_table",
+ "row_description": "ligand",
+ "primary_key": ("ligand_id",),
+ },
+ "system_validation": {
+ "artifact": "system_validation",
+ "row_description": "ligand-binding system validation summary",
+ "primary_key": ("system_id",),
+ },
+ "entry_chains": {
+ "artifact": "entry_chains",
+ "row_description": "polymer chain in a PDB entry",
+ "primary_key": ("entry_pdb_id", "chain_asym_id"),
+ },
+ "entry_biounit_chains": {
+ "artifact": "entry_biounit_chains",
+ "row_description": "chain instance in a biological assembly",
+ "primary_key": ("entry_pdb_id", "biounit_id", "chain_instance"),
+ },
+ "entry_metadata": {
+ "artifact": "entry_metadata",
+ "row_description": "PDB entry",
+ "primary_key": ("entry_pdb_id",),
+ },
+ "entry_sources": {
+ "artifact": "entry_sources",
+ "row_description": "PDB entry",
+ "primary_key": ("entry_pdb_id",),
+ },
+ "linked_apo_structures": {
+ "artifact": "linked_apo_structures",
+ "row_description": "ranked apo chain linked to a holo ligand",
+ "primary_key": ("reference_system_id", "rank"),
+ },
+ "interface_apo_structures": {
+ "artifact": "interface_apo_structures",
+ "row_description": "ranked apo chain linked to one protein-interface side",
+ "primary_key": ("reference_system_id", "reference_side", "rank"),
+ },
+ "interface_annotations": {
+ "artifact": "interface_annotations",
+ "row_description": "protein-chain interface in a biological assembly",
+ "primary_key": ("system_id",),
+ },
+ "alignment_chain_lookup": {
+ "artifact": "alignment_chain_lookup",
+ "row_description": "protein chain in the release search databases",
+ "primary_key": ("entry_pdb_id", "chain_asym_id"),
+ },
+ "ligand_pocket_membership": {
+ "artifact": "ligand_pocket_membership",
+ "row_description": "ligand directed-set-cover assignment",
+ "primary_key": ("ligand_id",),
+ },
+ "ligand_pocket_residues": {
+ "artifact": "ligand_pocket_residues",
+ "row_description": "receptor residue neighboring a proper ligand",
+ "primary_key": (
+ "ligand_id",
+ "chain_instance",
+ "residue_label_seq_id",
+ ),
+ },
+ "ligand_pocket_representatives": {
+ "artifact": "ligand_pocket_representatives",
+ "row_description": "ligand-pocket representative",
+ "primary_key": ("representative_ligand_id",),
+ },
+ "ligand_clusters": {
+ "artifact": "ligand_clusters",
+ "row_description": "ligand cluster assignments",
+ "primary_key": ("ligand_id",),
+ },
+ "ligand_affinity": {
+ "artifact": "ligand_affinity",
+ "row_description": "ligand with sequence-checked BindingDB affinity",
+ "primary_key": ("ligand_id",),
+ },
+ "bindingdb_measurements": {
+ "artifact": "bindingdb_measurements",
+ "row_description": "BindingDB Ki or Kd measurement with a PDB ligand cross-reference",
+ "primary_key": ("source_row", "pdb_id", "ligand_het_id", "endpoint"),
+ },
+ "ligand_mmp_pairs": {
+ "artifact": "ligand_mmp_pairs",
+ "row_description": "matched molecular pair and shared core",
+ "primary_key": (
+ "ligand_smiles_id_1",
+ "ligand_smiles_id_2",
+ "transformation",
+ "shared_core_smiles",
+ ),
+ },
+ "interface_half_representatives": {
+ "artifact": "interface_half_representatives",
+ "row_description": "representative half-interface",
+ "primary_key": ("half_interface_id",),
+ },
+ "interface_membership": {
+ "artifact": "interface_membership",
+ "row_description": "protein-interface representative assignment",
+ "primary_key": ("system_id",),
+ },
+ "interface_representatives": {
+ "artifact": "interface_representatives",
+ "row_description": "protein-interface representative",
+ "primary_key": ("representative_system_id",),
+ },
+ "interface_clusters": {
+ "artifact": "interface_clusters",
+ "row_description": "protein-interface cluster assignments",
+ "primary_key": ("system_id",),
+ },
+ "protein_sequence_clusters": {
+ "artifact": "protein_sequence_clusters",
+ "row_description": "protein-chain sequence cluster assignment from MMseqs",
+ "primary_key": ("entry_pdb_id", "chain_asym_id"),
+ },
+ "protein_structure_clusters": {
+ "artifact": "protein_structure_clusters",
+ "row_description": "protein-chain structure cluster assignment from Foldseek",
+ "primary_key": ("entry_pdb_id", "chain_asym_id"),
+ },
+}
+
+
+@dataclass(frozen=True)
+class PlinderRelease:
+ """Resolve named paths within a local or configured PLINDER release."""
+
+ data_dir: Path | None = None
+
+ def _relative_path(self, name: str, **parameters: str) -> Path:
+ try:
+ template = RELEASE_PATHS[name]
+ except KeyError as exc:
+ choices = ", ".join(sorted(RELEASE_PATHS))
+ raise KeyError(
+ f"unknown release artifact {name!r}; choose from: {choices}"
+ ) from exc
+
+ for parameter, value in parameters.items():
+ value = str(value)
+ if not value or value in {".", ".."} or Path(value).name != value:
+ raise ValueError(
+ f"artifact parameter {parameter!r} must be one path component"
+ )
+ try:
+ return Path(template.format(**parameters))
+ except KeyError as exc:
+ raise ValueError(f"missing artifact parameter {exc.args[0]!r}") from exc
+
+ def path(self, name: str, **parameters: str) -> Path:
+ """Return the expected local path without fetching it."""
+ root = self.data_dir or Path(get_config().data.plinder_dir)
+ return Path(root) / self._relative_path(name, **parameters)
+
+ def fetch(self, name: str, **parameters: str) -> Path:
+ """Fetch a configured artifact or check an explicit local release."""
+ relative = self._relative_path(name, **parameters)
+ path = (
+ Path(self.data_dir) / relative
+ if self.data_dir is not None
+ else cpl.get_plinder_path(rel=relative.as_posix())
+ )
+ if not path.exists():
+ raise FileNotFoundError(
+ f"PLINDER release artifact {name!r} is unavailable at {path}"
+ )
+ return path
+
+ def table(self, name: str) -> dict[str, Any]:
+ """Return the path name, row description, and key for a release table."""
+ try:
+ return RELEASE_TABLES[name]
+ except KeyError as exc:
+ choices = ", ".join(sorted(RELEASE_TABLES))
+ raise KeyError(
+ f"unknown release table {name!r}; choose from: {choices}"
+ ) from exc
diff --git a/src/plinder/core/scores/__init__.py b/src/plinder/core/scores/__init__.py
index 536188103..f1cef98a8 100644
--- a/src/plinder/core/scores/__init__.py
+++ b/src/plinder/core/scores/__init__.py
@@ -8,24 +8,48 @@
the same pyarrow query filters used in pd.read_parquet into raw SQL for
duckdb to execute.
"""
-from .clusters import query_clusters
-from .index import query_index
-from .ligand import cross_similarity as cross_ligand_similarity
-from .ligand import query_ligand_similarity
-from .links import query_links
-from .protein import (
- cross_similarity as cross_protein_similarity,
+
+from .alignment import expand_alignment_cigar, map_chain_alignment
+from .custom import (
+ CustomProteinSearchConfig,
+ CustomScoringResult,
+ CustomSequenceScoringResult,
+ resolve_custom_scoring_assets,
+ score_custom_cif_files,
+ score_custom_sequence_file,
+)
+from .interface import query_half_interface_similarity, query_interface_similarity
+from .ligand import (
+ cross_ligand_chemical_similarity,
+ query_ligand_chemical_similarity,
+ query_ligand_similarity,
)
-from .protein import (
- query_protein_similarity,
+from .protein import query_chain_overlap, query_protein_similarity
+from .reconstruct import (
+ prefetch_similarity_alignments,
+ reconstruct_interface_similarity_scores,
+ reconstruct_similarity_scores,
)
+from .search import search
__all__ = [
+ "search",
+ "expand_alignment_cigar",
+ "map_chain_alignment",
"query_ligand_similarity",
- "cross_ligand_similarity",
+ "query_ligand_chemical_similarity",
+ "cross_ligand_chemical_similarity",
+ "query_interface_similarity",
+ "query_half_interface_similarity",
+ "query_chain_overlap",
"query_protein_similarity",
- "cross_protein_similarity",
- "query_clusters",
- "query_links",
- "query_index",
+ "CustomProteinSearchConfig",
+ "CustomScoringResult",
+ "CustomSequenceScoringResult",
+ "resolve_custom_scoring_assets",
+ "score_custom_cif_files",
+ "score_custom_sequence_file",
+ "prefetch_similarity_alignments",
+ "reconstruct_interface_similarity_scores",
+ "reconstruct_similarity_scores",
]
diff --git a/src/plinder/core/scores/alignment.py b/src/plinder/core/scores/alignment.py
new file mode 100644
index 000000000..4645a9212
--- /dev/null
+++ b/src/plinder/core/scores/alignment.py
@@ -0,0 +1,141 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Load full chain alignments from optional CIGAR shards."""
+
+from __future__ import annotations
+
+import re
+from typing import Literal
+
+import pandas as pd
+
+from plinder.core.release import PlinderRelease
+from plinder.core.utils.dec import timeit
+
+POSITION_COLUMNS = [
+ "alignment_index",
+ "alignment_column",
+ "operation",
+ "query_seqres_position",
+ "target_seqres_position",
+ "query_coordinate_index",
+ "target_coordinate_index",
+]
+_CIGAR_RUN = re.compile(r"([1-9][0-9]*)([MID=X])")
+
+
+def expand_alignment_cigar(
+ cigar: str,
+ *,
+ query_start: int,
+ target_start: int,
+ source: Literal["foldseek", "mmseqs"],
+ include_gaps: bool = True,
+ alignment_index: int = 0,
+) -> pd.DataFrame:
+ """Expand one CIGAR into backend-native residue positions.
+
+ MMseqs positions are one-based SEQRES positions. Foldseek positions are
+ zero-based indices over resolved coordinate residues.
+ """
+ if source not in {"foldseek", "mmseqs"}:
+ raise ValueError("source must be 'foldseek' or 'mmseqs'")
+ if query_start < 1 or target_start < 1:
+ raise ValueError("query_start and target_start must be positive")
+ runs = _CIGAR_RUN.findall(cigar)
+ if (
+ not runs
+ or "".join(f"{length}{operation}" for length, operation in runs) != cigar
+ ):
+ raise ValueError(f"invalid alignment CIGAR: {cigar!r}")
+
+ query_position = query_start
+ target_position = target_start
+ records: list[dict[str, object]] = []
+ alignment_column = 0
+ for length_text, operation in runs:
+ query_consumed = operation in {"M", "I", "=", "X"}
+ target_consumed = operation in {"M", "D", "=", "X"}
+ for _ in range(int(length_text)):
+ query_value = query_position if query_consumed else None
+ target_value = target_position if target_consumed else None
+ if include_gaps or (query_value is not None and target_value is not None):
+ records.append(
+ {
+ "alignment_index": alignment_index,
+ "alignment_column": alignment_column,
+ "operation": operation,
+ "query_seqres_position": (
+ query_value if source == "mmseqs" else None
+ ),
+ "target_seqres_position": (
+ target_value if source == "mmseqs" else None
+ ),
+ "query_coordinate_index": (
+ query_value - 1
+ if source == "foldseek" and query_value is not None
+ else None
+ ),
+ "target_coordinate_index": (
+ target_value - 1
+ if source == "foldseek" and target_value is not None
+ else None
+ ),
+ }
+ )
+ query_position += int(query_consumed)
+ target_position += int(target_consumed)
+ alignment_column += 1
+ result = pd.DataFrame.from_records(records, columns=POSITION_COLUMNS)
+ for column in POSITION_COLUMNS[3:]:
+ result[column] = result[column].astype("Int64")
+ return result
+
+
+@timeit
+def map_chain_alignment(
+ query_entry: str,
+ query_chain: str,
+ target_entry: str,
+ target_chain: str,
+ *,
+ source: Literal["foldseek", "mmseqs"],
+ search_db: str = "holo",
+ include_gaps: bool = True,
+ release: PlinderRelease | None = None,
+) -> pd.DataFrame:
+ """Load and expand full alignments for a pair of label-asym chains."""
+ selected_release = release or PlinderRelease()
+ shard = selected_release.fetch(
+ "alignment_cigar_shard",
+ search_db=search_db,
+ alignment_type=source,
+ shard=query_entry[-3:-1],
+ )
+ alignments = pd.read_parquet(
+ shard,
+ columns=["query_start", "target_start", "cigar"],
+ filters=[
+ ("query_entry", "==", query_entry),
+ ("query_chain_mapped", "==", query_chain),
+ ("target_entry", "==", target_entry),
+ ("target_chain_mapped", "==", target_chain),
+ ],
+ )
+ frames = [
+ expand_alignment_cigar(
+ str(row.cigar),
+ query_start=int(row.query_start),
+ target_start=int(row.target_start),
+ source=source,
+ include_gaps=include_gaps,
+ alignment_index=index,
+ )
+ for index, row in enumerate(alignments.itertuples(index=False))
+ ]
+ if not frames:
+ return pd.DataFrame(columns=POSITION_COLUMNS)
+ return pd.concat(frames, ignore_index=True)
+
+
+__all__ = ["expand_alignment_cigar", "map_chain_alignment"]
diff --git a/src/plinder/core/scores/clusters.py b/src/plinder/core/scores/clusters.py
deleted file mode 100644
index 01f1ea3a5..000000000
--- a/src/plinder/core/scores/clusters.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-import pandas as pd
-from duckdb import sql
-
-from plinder.core.scores.query import FILTERS, make_query
-from plinder.core.utils import cpl
-from plinder.core.utils.config import get_config
-from plinder.core.utils.dec import timeit
-from plinder.core.utils.log import setup_logger
-from plinder.core.utils.schemas import CLUSTER_SCHEMA
-
-LOG = setup_logger(__name__)
-
-
-@timeit
-def query_clusters(
- *,
- columns: list[str] | None = None,
- filters: FILTERS = None,
-) -> pd.DataFrame | None:
- """
- Query the cluster database.
-
- Parameters
- ----------
- columns : list[str], default=None
- the columns to return
- filters : list[tuple[str, str, str]]
- the filters to apply
-
- Returns
- -------
- df : pd.DataFrame | None
- the cluster results
- """
-
- cfg = get_config()
- dataset = cpl.get_plinder_path(rel=cfg.data.clusters)
- query = make_query(
- schema=CLUSTER_SCHEMA,
- dataset=dataset,
- filters=filters,
- columns=columns,
- nested=True,
- allow_no_filters=True,
- )
- if query is None:
- LOG.warning("try minimally passing filters=[('metric', '==', 'pli_qcov')]")
- return None
- return sql(query).to_df()
diff --git a/src/plinder/core/scores/custom.py b/src/plinder/core/scores/custom.py
new file mode 100644
index 000000000..7492e8eea
--- /dev/null
+++ b/src/plinder/core/scores/custom.py
@@ -0,0 +1,3270 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Annotate and score custom mmCIF structures against PLINDER."""
+
+from __future__ import annotations
+
+import logging
+import re
+import shutil
+import subprocess
+from bisect import bisect_left
+from collections import Counter
+from collections.abc import Iterable as IterableABC
+from collections.abc import Iterator
+from dataclasses import dataclass, field, replace
+from gzip import open as gzip_open
+from pathlib import Path
+from threading import Lock
+from typing import Any, Iterable, Literal, Mapping
+
+import numpy as np
+import pandas as pd
+
+from plinder.core.release import PlinderRelease, _release_file, _require_file
+from plinder.core.scores.mapping import (
+ pack_residue_identities,
+ unpack_residue_identities,
+)
+
+LOG = logging.getLogger(__name__)
+CIF_SEARCH_BACKENDS = ("foldseek", "mmseqs")
+SEQUENCE_SEARCH_BACKENDS = ("mmseqs",)
+SEARCH_BACKENDS = CIF_SEARCH_BACKENDS
+
+
+@dataclass(frozen=True)
+class SearchDatabaseBundle:
+ """Portable exact-clustered target database for one search backend."""
+
+ backend: str
+ root: Path
+ search_target: Path
+ conversion_target: Path
+ cluster_alignments: Path | None
+ manifest: Mapping[str, object]
+
+
+@dataclass(frozen=True)
+class CustomScoringAssets:
+ """Release files required by custom-structure scoring."""
+
+ annotation_table: Path
+ entry_chains: Path
+ interface_annotations: Path
+ alignment_chain_lookup: Path
+ search_databases: Mapping[str, SearchDatabaseBundle]
+ ligand_archives: Mapping[str, Path]
+ monomer_search_databases: Mapping[str, SearchDatabaseBundle] = field(
+ default_factory=dict
+ )
+ overlay_search_databases: Mapping[str, SearchDatabaseBundle] = field(
+ default_factory=dict
+ )
+ overlay_monomer_search_databases: Mapping[str, SearchDatabaseBundle] = field(
+ default_factory=dict
+ )
+ shadowed_entries: frozenset[str] = frozenset()
+
+
+@dataclass(frozen=True)
+class CustomQueryInputs:
+ """Written per-chain coordinates, sequences, and stable metadata."""
+
+ root: Path
+ chain_cif_dir: Path
+ sequence_fasta: Path
+ chain_manifest: Path
+
+
+@dataclass(frozen=True)
+class CustomQueryDatabases:
+ """Foldseek/MMseqs query DBs and their backend identifier mapping."""
+
+ root: Path
+ inputs: CustomQueryInputs
+ databases: Mapping[str, Path]
+ identifier_map: Path
+
+
+@dataclass(frozen=True)
+class CustomProteinSearchConfig:
+ """Custom search filters, with optional E-value overrides per backend.
+
+ ``evalue`` sets all backends to the same threshold (default 0.01).
+ ``foldseek_evalue``, ``mmseqs_evalue`` and ``steam_evalue`` take precedence
+ for their respective backends when supplied.
+ """
+
+ evalue: float = 0.01
+ foldseek_evalue: float | None = None
+ mmseqs_evalue: float | None = None
+ steam_evalue: float | None = None
+ sensitivity: float = 11.0
+ max_seqs: int = 10_000
+ coverage: float = 0.0
+ min_seq_id: float = 0.0
+
+ def __post_init__(self) -> None:
+ for value in (
+ self.evalue,
+ self.foldseek_evalue,
+ self.mmseqs_evalue,
+ self.steam_evalue,
+ ):
+ if value is not None and not value >= 0:
+ raise ValueError("E-values must be nonnegative")
+ if self.max_seqs < 1:
+ raise ValueError("max_seqs must be positive")
+ if not 0 <= self.coverage <= 1:
+ raise ValueError("coverage must be in [0, 1]")
+ if not 0 <= self.min_seq_id <= 1:
+ raise ValueError("min_seq_id must be in [0, 1]")
+
+ def evalue_for(self, backend: str) -> float:
+ """Use the backend override, or the shared E-value (default 0.01)."""
+ overrides = {
+ "foldseek": self.foldseek_evalue,
+ "mmseqs": self.mmseqs_evalue,
+ "steam": self.steam_evalue,
+ }
+ value = overrides[backend]
+ return self.evalue if value is None else value
+
+
+@dataclass(frozen=True)
+class CustomStructureAnnotations:
+ """Custom ligand/interface annotations and their generated ligand SDFs."""
+
+ root: Path
+ ligand_sdf_root: Path
+ annotation_table: Path
+ entry_chains: Path
+ interface_annotations: Path
+ entries_by_structure: Mapping[str, Any]
+
+
+@dataclass(frozen=True)
+class CustomScoringResult:
+ """Files produced by the complete custom-CIF scoring workflow."""
+
+ annotations: CustomStructureAnnotations
+ query_inputs: CustomQueryInputs
+ query_databases: CustomQueryDatabases
+ protein_hits: Mapping[str, Path]
+ chain_similarity_scores: Path
+ score_alignments: Mapping[str, Path]
+ protein_score_alignments: Mapping[str, Path]
+ protein_scores: Path
+ aligned_pocket_residues: Path | None
+ ligand_scores: Path | None
+ interface_scores: Path | None
+
+
+@dataclass(frozen=True)
+class CustomSequenceScoringResult:
+ """Files produced by protein-sequence scoring against PLINDER pockets."""
+
+ query_inputs: CustomQueryInputs
+ query_databases: CustomQueryDatabases
+ protein_hits: Mapping[str, Path]
+ chain_similarity_scores: Path
+ protein_score_alignments: Mapping[str, Path]
+ protein_scores: Path
+ aligned_pocket_residues: Path | None
+ sequence_links: Path
+ best_sequence_links: Path
+
+
+@dataclass(frozen=True)
+class _SequenceEntry:
+ """Small entry stand-in needed while reversing custom alignments."""
+
+ pdb_id: str
+
+
+def _require_database_prefix(
+ prefix: Path,
+ *,
+ description: str,
+ indexed: bool = False,
+) -> None:
+ _require_file(prefix.with_suffix(".dbtype"), description=description)
+ if indexed:
+ _require_file(
+ Path(f"{prefix}.idx.dbtype"), description=f"indexed {description}"
+ )
+
+
+def _validate_portable_links(root: Path) -> None:
+ """Reject database links that would break after moving the bundle."""
+ resolved_root = root.resolve()
+ for path in root.rglob("*"):
+ if not path.is_symlink():
+ continue
+ link = path.readlink()
+ try:
+ target = path.resolve(strict=True)
+ except FileNotFoundError as exc:
+ raise ValueError(f"broken database link: {path} -> {link}") from exc
+ if link.is_absolute() or not target.is_relative_to(resolved_root):
+ raise ValueError(f"non-portable database link: {path} -> {path.readlink()}")
+
+
+def _local_search_database_root(
+ data_dir: Path, backend: str, *, monomer: bool = False
+) -> Path:
+ """Resolve either a published bundle or an unmodified ingest output."""
+ artifact = "monomer_search_database" if monomer else "search_database"
+ prefix = "monomer" if monomer else "holo"
+ published = PlinderRelease(data_dir).path(artifact, backend=backend)
+ if published.is_dir():
+ return published
+ ingest = data_dir / "dbs" / "subdbs" / f"{prefix}_{backend}"
+ return ingest if ingest.is_dir() else published
+
+
+def resolve_search_database(
+ backend: str,
+ *,
+ data_dir: Path | None = None,
+ monomer: bool = False,
+) -> SearchDatabaseBundle:
+ """Download or validate one portable PLINDER search database bundle."""
+ if backend not in SEARCH_BACKENDS:
+ raise ValueError(
+ f"unsupported search backend {backend!r}; expected one of {SEARCH_BACKENDS}"
+ )
+ artifact = "monomer_search_database" if monomer else "search_database"
+ if data_dir is None:
+ root = _release_file(
+ artifact,
+ data_dir=None,
+ description=f"{backend} search database",
+ backend=backend,
+ )
+ else:
+ root = _local_search_database_root(Path(data_dir), backend, monomer=monomer)
+ return _validate_search_database(backend, Path(root))
+
+
+def _validate_search_database(backend: str, root: Path) -> SearchDatabaseBundle:
+ root = Path(root)
+ if backend == "foldseek":
+ search_target = conversion_target = root / "clustered"
+ cluster_alignments = None
+ else:
+ search_target = root / "representatives"
+ conversion_target = root / root.name
+ cluster_alignments = root / "cluster_alignments"
+
+ _require_database_prefix(
+ search_target,
+ description=f"{backend} representative search target",
+ indexed=True,
+ )
+ _require_database_prefix(
+ conversion_target,
+ description=f"{backend} conversion target",
+ )
+ if cluster_alignments is not None:
+ _require_database_prefix(
+ cluster_alignments,
+ description="MMseqs exact-cluster expansion database",
+ )
+ _validate_portable_links(root)
+ return SearchDatabaseBundle(
+ backend=backend,
+ root=root,
+ search_target=search_target,
+ conversion_target=conversion_target,
+ cluster_alignments=cluster_alignments,
+ manifest={},
+ )
+
+
+def _pdb_shard(identifier: str) -> str:
+ pdb_id = str(identifier).split("__", maxsplit=1)[0].strip().lower()
+ if len(pdb_id) < 4 or not pdb_id.replace("_", "").isalnum():
+ raise ValueError(f"invalid PDB or system identifier: {identifier!r}")
+ return pdb_id[-3:-1]
+
+
+def resolve_ligand_archives(
+ pdb_or_system_ids: Iterable[str],
+ *,
+ data_dir: Path | None = None,
+) -> dict[str, Path]:
+ """Download or validate only ligand-coordinate shards needed by targets."""
+ codes = sorted({_pdb_shard(value) for value in pdb_or_system_ids})
+ archives: dict[str, Path] = {}
+ for code in codes:
+ archives[code] = _release_file(
+ "ligand_archive",
+ data_dir=data_dir,
+ description=f"canonical ligand archive for shard {code}",
+ shard=code,
+ )
+ return archives
+
+
+def resolve_custom_scoring_assets(
+ *,
+ data_dir: Path | None = None,
+ backends: Iterable[str] = CIF_SEARCH_BACKENDS,
+ ligand_pdb_ids: Iterable[str] = (),
+ include_monomers: bool = False,
+) -> CustomScoringAssets:
+ """Download or validate the bounded asset set for custom scoring.
+
+ Ligand archives are intentionally omitted unless ``ligand_pdb_ids`` are
+ supplied. A caller can therefore run protein search first and fetch only
+ the coordinate shards containing target ligands with positive pocket
+ coverage.
+ """
+ index_files = (
+ "annotation_table",
+ "entry_chains",
+ "interface_annotations",
+ "alignment_chain_lookup",
+ )
+ resolved_index: dict[str, Path] = {}
+ for name in index_files:
+ resolved_index[name] = _release_file(
+ name,
+ data_dir=data_dir,
+ description=name.replace("_", " "),
+ )
+
+ selected_backends = tuple(dict.fromkeys(backends))
+ databases = {
+ backend: resolve_search_database(backend, data_dir=data_dir)
+ for backend in selected_backends
+ }
+ monomer_databases = {}
+ for backend in selected_backends if include_monomers else ():
+ try:
+ monomer_databases[backend] = resolve_search_database(
+ backend, data_dir=data_dir, monomer=True
+ )
+ except FileNotFoundError as exc:
+ # A release or ingest may have no monomer universe for a backend.
+ LOG.warning(f"no {backend} monomer search database; skipping: {exc}")
+ release = PlinderRelease(data_dir)
+ overlay_databases = {}
+ overlay_monomer_databases = {}
+ for backend in selected_backends:
+ try:
+ overlay = release.fetch("search_database_overlay", backend=backend)
+ except FileNotFoundError:
+ pass
+ else:
+ overlay_databases[backend] = _validate_search_database(backend, overlay)
+ if include_monomers:
+ try:
+ monomer_overlay = release.fetch(
+ "monomer_search_database_overlay", backend=backend
+ )
+ except FileNotFoundError:
+ pass
+ else:
+ overlay_monomer_databases[backend] = _validate_search_database(
+ backend, monomer_overlay
+ )
+ shadowed_entries: frozenset[str] = frozenset()
+ try:
+ shadowed_path = release.fetch("search_database_shadowed_entries")
+ except FileNotFoundError:
+ if overlay_databases or overlay_monomer_databases:
+ raise ValueError(
+ "search database overlay is missing shadowed entries"
+ ) from None
+ else:
+ shadowed_entries = frozenset(
+ pd.read_parquet(shadowed_path, columns=["pdb_id"])["pdb_id"].astype(str)
+ )
+ ligand_archives = resolve_ligand_archives(
+ ligand_pdb_ids,
+ data_dir=data_dir,
+ )
+ return CustomScoringAssets(
+ annotation_table=resolved_index["annotation_table"],
+ entry_chains=resolved_index["entry_chains"],
+ interface_annotations=resolved_index["interface_annotations"],
+ alignment_chain_lookup=resolved_index["alignment_chain_lookup"],
+ search_databases=databases,
+ ligand_archives=ligand_archives,
+ monomer_search_databases=monomer_databases,
+ overlay_search_databases=overlay_databases,
+ overlay_monomer_search_databases=overlay_monomer_databases,
+ shadowed_entries=shadowed_entries,
+ )
+
+
+def _mmcif_stem(path: Path) -> str:
+ """Return a stable structure ID while accepting only mmCIF suffixes."""
+ name = path.name
+ lowered = name.lower()
+ for suffix in (".mmcif.gz", ".cif.gz", ".mmcif", ".cif"):
+ if lowered.endswith(suffix):
+ structure_id = name[: -len(suffix)]
+ if not structure_id:
+ break
+ return structure_id
+ raise ValueError(f"custom structure must be an mmCIF file: {path}")
+
+
+def _clean_protein_sequence(sequence: str, *, context: str) -> str:
+ cleaned = "".join(str(sequence).replace(";", "").split()).upper()
+ cleaned = cleaned.replace("?", "X")
+ if not cleaned or re.fullmatch(r"[A-Z]+", cleaned) is None:
+ raise ValueError(f"invalid protein sequence for {context}: {sequence!r}")
+ return cleaned
+
+
+def _fasta_records(path: Path) -> Iterator[tuple[str, str]]:
+ """Yield identifier and sequence pairs from a plain or gzipped FASTA."""
+ source = Path(path)
+ if not source.is_file():
+ raise FileNotFoundError(f"missing protein FASTA: {source}")
+ handle = (
+ gzip_open(source, mode="rt")
+ if source.name.lower().endswith(".gz")
+ else source.open()
+ )
+ with handle:
+ identifier: str | None = None
+ parts: list[str] = []
+ for line_number, line in enumerate(handle, start=1):
+ text = line.strip()
+ if not text:
+ continue
+ if text.startswith(">"):
+ if identifier is not None:
+ yield identifier, "".join(parts)
+ header = text[1:].strip()
+ if not header:
+ raise ValueError(
+ f"empty FASTA header in {source} at line {line_number}"
+ )
+ identifier = header.split(maxsplit=1)[0]
+ parts = []
+ else:
+ if identifier is None:
+ raise ValueError(
+ f"sequence precedes the first FASTA header in {source} "
+ f"at line {line_number}"
+ )
+ parts.append(text)
+ if identifier is not None:
+ yield identifier, "".join(parts)
+
+
+def write_custom_sequence_query_files(
+ sequence_fasta: Path,
+ *,
+ work_dir: Path,
+ min_chain_length: int = 12,
+) -> CustomQueryInputs:
+ """Write stable internal query IDs for a protein FASTA.
+
+ Each FASTA record represents one ligand-free protein chain. Original
+ identifiers remain in the manifest and generated result tables; internal
+ IDs keep search-database identifiers unambiguous.
+ """
+ if min_chain_length < 1:
+ raise ValueError("min_chain_length must be positive")
+ source = Path(sequence_fasta)
+ root = Path(work_dir) / "query_inputs"
+ if source.resolve().is_relative_to(root.resolve()):
+ raise ValueError("the protein FASTA must be outside the generated work tree")
+ records = list(_fasta_records(source))
+ if not records:
+ raise ValueError(f"protein FASTA contains no records: {source}")
+ identifiers = [identifier for identifier, _ in records]
+ duplicates = sorted(
+ identifier for identifier, count in Counter(identifiers).items() if count > 1
+ )
+ if duplicates:
+ raise ValueError(f"protein FASTA repeats identifiers: {duplicates[:10]}")
+
+ if root.exists():
+ shutil.rmtree(root)
+ chain_cif_dir = root / "chains"
+ chain_cif_dir.mkdir(parents=True)
+ written_fasta = root / "query_sequences.fasta"
+ chain_manifest = root / "query_chains.parquet"
+ rows: list[dict[str, Any]] = []
+ fasta_rows: list[str] = []
+ skipped: dict[str, str] = {}
+ for sequence_id, raw_sequence in records:
+ sequence = _clean_protein_sequence(
+ raw_sequence,
+ context=f"FASTA record {sequence_id}",
+ )
+ if len(sequence) < min_chain_length:
+ skipped[sequence_id] = (
+ f"protein length {len(sequence)} is below {min_chain_length}"
+ )
+ continue
+ query_id = f"cq{len(rows):08d}"
+ rows.append(
+ {
+ "query_id": query_id,
+ "query_chain_id": f"{query_id}__A",
+ "structure_id": query_id,
+ "sequence_id": sequence_id,
+ "source_fasta": str(source.resolve()),
+ "chain_asym_id": "A",
+ "sequence": sequence,
+ "sequence_length": len(sequence),
+ "sequence_source": "polymer",
+ "resolved_residue_numbers": [],
+ }
+ )
+ fasta_rows.append(f">{query_id}\n{sequence}\n")
+ if not rows:
+ raise ValueError(
+ f"no protein sequences of at least {min_chain_length} residues were "
+ f"found; record diagnostics={skipped}"
+ )
+ written_fasta.write_text("".join(fasta_rows))
+ pd.DataFrame(rows).to_parquet(chain_manifest, index=False)
+ return CustomQueryInputs(
+ root=root,
+ chain_cif_dir=chain_cif_dir,
+ sequence_fasta=written_fasta,
+ chain_manifest=chain_manifest,
+ )
+
+
+def _protein_asym_sequences(block: Any) -> dict[str, str]:
+ """Map label asym IDs to canonical sequences for protein entities only."""
+ from plinder.data.annotations.cif_utils import get_label_asym_sequences
+
+ if "struct_asym" not in block or "entity_poly" not in block:
+ return {}
+ struct_asym = block["struct_asym"]
+ entity_poly = block["entity_poly"]
+ if not {"id", "entity_id"}.issubset(struct_asym):
+ return {}
+ if not {"entity_id", "type"}.issubset(entity_poly):
+ return {}
+ protein_entities = {
+ str(entity_id)
+ for entity_id, polymer_type in zip(
+ entity_poly["entity_id"].as_array(),
+ entity_poly["type"].as_array(),
+ )
+ if "polypeptide" in str(polymer_type).lower()
+ }
+ sequences = get_label_asym_sequences(block)
+ return {
+ str(asym_id): _clean_protein_sequence(
+ sequences[str(asym_id)], context=f"chain {asym_id}"
+ )
+ for asym_id, entity_id in zip(
+ struct_asym["id"].as_array(),
+ struct_asym["entity_id"].as_array(),
+ )
+ if str(entity_id) in protein_entities and str(asym_id) in sequences
+ }
+
+
+def _query_chain_atoms(
+ cif_file: Any,
+ *,
+ structure_mode: str,
+ assembly_ids: Iterable[str] | None,
+) -> dict[str, Any]:
+ """Return one coordinate representative per label asym protein chain."""
+ import biotite.structure as struc
+ from biotite.structure import filter_heavy
+
+ from plinder.data.annotations.cif_utils import (
+ build_biounit,
+ get_structure_with_altloc,
+ select_assembly_ids,
+ )
+
+ if structure_mode == "as_is":
+ if assembly_ids is not None:
+ raise ValueError("assembly_ids are only valid in pdb mode")
+ atoms = get_structure_with_altloc(
+ cif_file,
+ model=1,
+ use_author_fields=False,
+ include_bonds=False,
+ )
+ atoms = atoms[filter_heavy(atoms)]
+ return {
+ str(chain_id): atoms[atoms.chain_id == chain_id]
+ for chain_id in np.unique(atoms.chain_id)
+ }
+ if structure_mode != "pdb":
+ raise ValueError("structure_mode must be 'as_is' or 'pdb'")
+
+ block = list(cif_file.values())[0]
+ available_assemblies = block["pdbx_struct_assembly_gen"]["assembly_id"].as_array(
+ str
+ )
+ selected = select_assembly_ids(available_assemblies, assembly_ids)
+ if not selected:
+ raise ValueError("pdb mode requires at least one deposited assembly")
+ representatives: dict[str, Any] = {}
+ for assembly_id in selected:
+ assembly = build_biounit(cif_file, assembly_id)
+ for instance_chain in np.unique(assembly.chain_id):
+ chain = str(instance_chain)
+ if "." not in chain:
+ continue
+ asym_id = chain.split(".", maxsplit=1)[1]
+ representatives.setdefault(
+ asym_id,
+ assembly[assembly.chain_id == instance_chain],
+ )
+ # Ensure every representative contains at least one residue. This also
+ # narrows the otherwise broad Any returned by Biotite's dynamic CIF API.
+ return {
+ asym_id: atoms
+ for asym_id, atoms in representatives.items()
+ if struc.get_residue_count(atoms) > 0
+ }
+
+
+def _resolved_protein_sequence(atoms: Any, *, context: str) -> str | None:
+ """Derive a sequence for coordinate-only mmCIFs without entity tables."""
+ import biotite.structure as struc
+ from biotite.sequence import ProteinSequence
+
+ try:
+ sequences, _ = struc.to_sequence(atoms, allow_hetero=True)
+ except (IndexError, TypeError, ValueError, struc.BadStructureError):
+ return None
+ if len(sequences) != 1:
+ return None
+ sequence = sequences[0]
+ if not isinstance(sequence, ProteinSequence):
+ return None
+ return _clean_protein_sequence(str(sequence), context=context)
+
+
+def write_custom_query_files(
+ cif_files: Iterable[Path],
+ *,
+ work_dir: Path,
+ structure_mode: str = "as_is",
+ assembly_ids: Iterable[str] | None = None,
+ min_chain_length: int = 12,
+) -> CustomQueryInputs:
+ """Write one Foldseek-ready CIF and one FASTA record per protein chain.
+
+ ``as_is`` treats each supplied coordinate file as an already assembled
+ structure. ``pdb`` applies the selected deposited assembly definitions,
+ but searches only one rigid-transform-equivalent copy per label asym ID.
+ Nucleic-acid entities and protein chains shorter than ``min_chain_length``
+ are excluded from both search backends.
+ """
+ import biotite.structure as struc
+ from biotite.file import DeserializationError, InvalidFileError
+
+ from plinder.data.annotations.cif_utils import (
+ check_custom_mmcif_fields,
+ read_mmcif_file,
+ )
+ from plinder.data.annotations.save_utils import save_cif_file
+
+ if min_chain_length < 1:
+ raise ValueError("min_chain_length must be positive")
+ sources = tuple(sorted((Path(path) for path in cif_files), key=str))
+ if not sources:
+ raise ValueError("at least one custom mmCIF is required")
+ requested_assemblies = (
+ tuple(str(value) for value in assembly_ids)
+ if assembly_ids is not None and not isinstance(assembly_ids, str)
+ else assembly_ids
+ )
+ root = Path(work_dir) / "query_inputs"
+ resolved_root = root.resolve()
+ for source in sources:
+ _mmcif_stem(source)
+ if not source.is_file():
+ raise FileNotFoundError(f"missing custom mmCIF: {source}")
+ if source.resolve().is_relative_to(resolved_root):
+ raise ValueError(
+ "custom input files must be outside the generated work tree"
+ )
+ if root.exists():
+ shutil.rmtree(root)
+ chain_cif_dir = root / "chains"
+ chain_cif_dir.mkdir(parents=True)
+ sequence_fasta = root / "query_sequences.fasta"
+ chain_manifest = root / "query_chains.parquet"
+
+ structure_ids: set[str] = set()
+ rows: list[dict[str, Any]] = []
+ fasta_records: list[str] = []
+ skipped_chains: dict[str, str] = {}
+ for source in sources:
+ structure_id = _mmcif_stem(source)
+ if structure_id in structure_ids:
+ raise ValueError(f"duplicate custom structure ID: {structure_id}")
+ structure_ids.add(structure_id)
+ try:
+ cif_file = read_mmcif_file(source)
+ block = list(cif_file.values())[0]
+ except (DeserializationError, IndexError, InvalidFileError, OSError) as exc:
+ raise ValueError(f"cannot parse custom mmCIF {source}: {exc}") from exc
+ check_custom_mmcif_fields(
+ block,
+ source=source,
+ structure_mode=structure_mode,
+ )
+ sequences = _protein_asym_sequences(block)
+ try:
+ atoms_by_asym = _query_chain_atoms(
+ cif_file,
+ structure_mode=structure_mode,
+ assembly_ids=requested_assemblies,
+ )
+ except (
+ IndexError,
+ InvalidFileError,
+ KeyError,
+ TypeError,
+ ValueError,
+ ) as exc:
+ raise ValueError(
+ f"failed to read {structure_mode} coordinates from custom "
+ f"mmCIF {source}: {exc}"
+ ) from exc
+ for asym_id in sorted(atoms_by_asym):
+ sequence = sequences.get(asym_id)
+ sequence_source = "polymer"
+ if sequence is None:
+ sequence = _resolved_protein_sequence(
+ atoms_by_asym[asym_id],
+ context=f"{structure_id} chain {asym_id}",
+ )
+ sequence_source = "coordinates"
+ if sequence is None:
+ skipped_chains[f"{structure_id}__{asym_id}"] = (
+ "not identifiable as a protein"
+ )
+ continue
+ if len(sequence) < min_chain_length:
+ skipped_chains[f"{structure_id}__{asym_id}"] = (
+ f"protein length {len(sequence)} is below {min_chain_length}"
+ )
+ continue
+ atoms = atoms_by_asym[asym_id].copy()
+ residue_starts = struc.get_residue_starts(atoms, add_exclusive_stop=False)
+ if len(residue_starts) < 1:
+ continue
+ query_id = f"cq{len(rows):08d}"
+ query_chain_id = f"{structure_id}__{asym_id}"
+ resolved_residue_numbers = [
+ int(atoms.res_id[index]) for index in residue_starts
+ ]
+ if sequence_source == "coordinates":
+ if len(resolved_residue_numbers) != len(sequence):
+ raise ValueError(
+ "resolved residue count does not match the emitted FASTA "
+ f"sequence for {structure_id} chain {asym_id}"
+ )
+ if len(set(resolved_residue_numbers)) != len(resolved_residue_numbers):
+ raise ValueError(
+ f"resolved residue numbers are ambiguous for {structure_id} "
+ f"chain {asym_id}; coordinate-derived FASTA positions cannot "
+ "be mapped uniquely"
+ )
+ atoms.chain_id = np.full(len(atoms), "A")
+ chain_path = chain_cif_dir / f"{query_id}.cif"
+ save_cif_file(
+ atoms,
+ query_id,
+ chain_path,
+ source_block=block,
+ source_asym_ids={"A": asym_id},
+ protein_sequences={"A": sequence},
+ )
+ rows.append(
+ {
+ "query_id": query_id,
+ "query_chain_id": query_chain_id,
+ "structure_id": structure_id,
+ "source_mmcif": str(source.resolve()),
+ "chain_asym_id": asym_id,
+ "sequence": sequence,
+ "sequence_length": len(sequence),
+ "sequence_source": sequence_source,
+ "resolved_residue_numbers": resolved_residue_numbers,
+ }
+ )
+ fasta_records.append(f">{query_id}\n{sequence}\n")
+ if not rows:
+ raise ValueError(
+ f"no protein chains of at least {min_chain_length} residues were found; "
+ f"chain diagnostics={skipped_chains}"
+ )
+ sequence_fasta.write_text("".join(fasta_records))
+ pd.DataFrame(rows).to_parquet(chain_manifest, index=False)
+ return CustomQueryInputs(
+ root=root,
+ chain_cif_dir=chain_cif_dir,
+ sequence_fasta=sequence_fasta,
+ chain_manifest=chain_manifest,
+ )
+
+
+def annotate_custom_cif_files(
+ cif_files: Iterable[Path],
+ *,
+ work_dir: Path,
+ structure_mode: Literal["as_is", "pdb"] = "as_is",
+ assembly_ids: Iterable[str] | None = None,
+ ligand_smiles_dict: Mapping[str, str] | None = None,
+ ligand_ccd_code_dict: Mapping[str, str] | None = None,
+ include_ligands: bool = True,
+ include_interfaces: bool = True,
+ interface_annotate_prodigy: bool = True,
+ data_dir: Path | None = None,
+) -> CustomStructureAnnotations:
+ """Annotate custom structures and write the scorer's three index tables.
+
+ Ligand chemistry overrides are passed directly to
+ :meth:`Entry.from_custom_cif_file`. The same component mapping is applied
+ to every input file; callers with different meanings for a repeated
+ component name such as ``LIG`` should score those files in separate calls.
+ Generated SDFs live under ``ligand_sdf_root//ligand_files`` and
+ contain the bond orders assigned during custom-CIF ingest.
+ """
+ from plinder.core.scores.entries import entry_views_from_df
+ from plinder.data.annotations.aggregate_annotations import Entry
+
+ sources = tuple(sorted((Path(path) for path in cif_files), key=str))
+ if not sources:
+ raise ValueError("at least one custom mmCIF is required")
+ structure_ids = [_mmcif_stem(source) for source in sources]
+ duplicates = sorted(
+ structure_id
+ for structure_id in set(structure_ids)
+ if structure_ids.count(structure_id) > 1
+ )
+ if duplicates:
+ raise ValueError(f"duplicate custom structure IDs: {duplicates}")
+
+ root = Path(work_dir) / "custom_annotations"
+ root.mkdir(exist_ok=True, parents=True)
+ ligand_sdf_root = root / "ligands"
+ ligand_sdf_root.mkdir(exist_ok=True, parents=True)
+ requested_assemblies = (
+ tuple(str(value) for value in assembly_ids)
+ if assembly_ids is not None and not isinstance(assembly_ids, str)
+ else assembly_ids
+ )
+
+ annotated: dict[str, Any] = {}
+ entry_ids: set[str] = set()
+ for structure_id, source in zip(structure_ids, sources, strict=True):
+ entry = Entry.from_custom_cif_file(
+ None if structure_mode == "pdb" else structure_id,
+ source,
+ ligand_smiles_dict=(
+ dict(ligand_smiles_dict) if ligand_smiles_dict is not None else None
+ ),
+ ligand_ccd_code_dict=(
+ dict(ligand_ccd_code_dict) if ligand_ccd_code_dict is not None else None
+ ),
+ save_folder=ligand_sdf_root if include_ligands else None,
+ structure_mode=structure_mode,
+ assembly_ids=requested_assemblies,
+ include_ligands=include_ligands,
+ include_interfaces=include_interfaces,
+ interface_annotate_prodigy=interface_annotate_prodigy,
+ data_dir=data_dir,
+ )
+ entry_id = str(entry.pdb_id)
+ if entry_id in entry_ids:
+ raise ValueError(
+ f"custom inputs produce duplicate entry ID {entry_id!r}; "
+ "score them in separate calls"
+ )
+ entry_ids.add(entry_id)
+ protein_chains = [
+ chain
+ for chain in entry.chains.values()
+ if "polypeptide" in str(chain.chain_type_str).lower()
+ ]
+ if not protein_chains:
+ raise ValueError(
+ f"custom mmCIF {source} produced no protein chains to score"
+ )
+ annotated[structure_id] = entry
+
+ ligand_frames = [entry.to_df() for entry in annotated.values()]
+ ligand_frames = [frame for frame in ligand_frames if not frame.empty]
+ annotation = (
+ pd.concat(ligand_frames, ignore_index=True)
+ if ligand_frames
+ else pd.DataFrame(
+ {
+ "entry_pdb_id": pd.Series(dtype="string"),
+ "system_id": pd.Series(dtype="string"),
+ }
+ )
+ )
+ entry_chains = pd.concat(
+ [entry.chains_to_df() for entry in annotated.values()],
+ ignore_index=True,
+ )
+ interface_rows = [
+ interface.to_row()
+ for entry in annotated.values()
+ for interface in entry.interfaces
+ ]
+ interface_annotations = pd.DataFrame.from_records(interface_rows)
+ if interface_annotations.empty:
+ interface_annotations = pd.DataFrame(
+ {"entry_pdb_id": pd.Series(dtype="string")}
+ )
+
+ annotation_table = root / "annotation_table.parquet"
+ entry_chain_table = root / "entry_chains.parquet"
+ interface_table = root / "interface_annotation_table.parquet"
+ annotation.to_parquet(annotation_table, index=False)
+ entry_chains.to_parquet(entry_chain_table, index=False)
+ interface_annotations.to_parquet(interface_table, index=False)
+ entry_views = entry_views_from_df(
+ annotation,
+ entry_chains=entry_chains,
+ interface_annotations=interface_annotations,
+ )
+ entries_by_structure = {
+ structure_id: entry_views[str(entry.pdb_id)]
+ for structure_id, entry in annotated.items()
+ }
+ return CustomStructureAnnotations(
+ root=root,
+ ligand_sdf_root=ligand_sdf_root,
+ annotation_table=annotation_table,
+ entry_chains=entry_chain_table,
+ interface_annotations=interface_table,
+ entries_by_structure=entries_by_structure,
+ )
+
+
+def _run_command(command: list[str]) -> None:
+ LOG.info("running custom search command: %s", " ".join(command))
+ subprocess.check_call(command)
+
+
+def _database_lookup_identifiers(database: Path) -> list[str]:
+ lookup = database.with_suffix(".lookup")
+ if not lookup.is_file():
+ raise FileNotFoundError(f"search query database has no lookup: {lookup}")
+ identifiers: list[str] = []
+ for line in lookup.read_text().splitlines():
+ fields = line.split()
+ if len(fields) >= 2:
+ identifiers.append(fields[1])
+ return identifiers
+
+
+def _map_backend_query_identifiers(
+ identifiers: Iterable[str], query_ids: Iterable[str], *, backend: str
+) -> dict[str, str]:
+ expected = tuple(query_ids)
+ output: dict[str, str] = {}
+ matched: dict[str, list[str]] = {query_id: [] for query_id in expected}
+ for identifier in identifiers:
+ candidates = [
+ query_id
+ for query_id in expected
+ if identifier == query_id
+ or identifier.startswith(f"{query_id}_")
+ or re.search(rf"(?:^|/){re.escape(query_id)}(?:[_.]|$)", identifier)
+ ]
+ if len(candidates) != 1:
+ raise ValueError(
+ f"cannot map {backend} query identifier {identifier!r}: {candidates}"
+ )
+ query_id = candidates[0]
+ output[identifier] = query_id
+ matched[query_id].append(identifier)
+ invalid = {
+ query_id: values for query_id, values in matched.items() if len(values) != 1
+ }
+ if invalid:
+ raise ValueError(
+ f"{backend} query database must contain one record per chain: {invalid}"
+ )
+ return output
+
+
+def create_custom_query_databases(
+ inputs: CustomQueryInputs,
+ *,
+ work_dir: Path,
+ backends: Iterable[str] = CIF_SEARCH_BACKENDS,
+ threads: int = 1,
+) -> CustomQueryDatabases:
+ """Create unindexed, scratch-local query DBs for selected search backends."""
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ selected = tuple(dict.fromkeys(backends))
+ if not selected:
+ raise ValueError("at least one custom search backend is required")
+ unsupported = sorted(set(selected).difference(SEARCH_BACKENDS))
+ if unsupported:
+ raise ValueError(f"unsupported search backends: {unsupported}")
+ for backend in selected:
+ if shutil.which(backend) is None:
+ raise FileNotFoundError(
+ f"{backend} executable is required for custom protein searches"
+ )
+ root = Path(work_dir) / "query_databases"
+ if root.exists():
+ shutil.rmtree(root)
+ root.mkdir(parents=True)
+ databases = {backend: root / backend for backend in selected}
+ if "foldseek" in selected:
+ _run_command(
+ [
+ "foldseek",
+ "createdb",
+ str(inputs.chain_cif_dir),
+ str(databases["foldseek"]),
+ "--threads",
+ str(threads),
+ "--chain-name-mode",
+ "1",
+ "--coord-store-mode",
+ "2",
+ ]
+ )
+ if "mmseqs" in selected:
+ _run_command(
+ [
+ "mmseqs",
+ "createdb",
+ str(inputs.sequence_fasta),
+ str(databases["mmseqs"]),
+ "--threads",
+ str(threads),
+ ]
+ )
+ manifest = pd.read_parquet(inputs.chain_manifest)
+ query_ids = manifest["query_id"].astype(str).tolist()
+ mapping_rows: list[dict[str, str]] = []
+ for backend, database in databases.items():
+ mapping = _map_backend_query_identifiers(
+ _database_lookup_identifiers(database),
+ query_ids,
+ backend=backend,
+ )
+ mapping_rows.extend(
+ {
+ "backend": backend,
+ "backend_query_id": identifier,
+ "query_id": query_id,
+ }
+ for identifier, query_id in mapping.items()
+ )
+ identifier_map = root / "query_identifier_map.parquet"
+ pd.DataFrame(mapping_rows).sort_values(["backend", "query_id"]).to_parquet(
+ identifier_map, index=False
+ )
+ return CustomQueryDatabases(
+ root=root,
+ inputs=inputs,
+ databases=databases,
+ identifier_map=identifier_map,
+ )
+
+
+def _plinder_entry_subset(values: Iterable[str] | None) -> tuple[str, ...] | None:
+ if values is None:
+ return None
+ if isinstance(values, str):
+ values = (values,)
+ selected = tuple(
+ dict.fromkeys(
+ str(value).strip().lower() for value in values if str(value).strip()
+ )
+ )
+ if not selected:
+ raise ValueError("plinder_entry_ids must contain at least one PDB ID")
+ invalid = [
+ value for value in selected if re.fullmatch(r"[a-z0-9]{4}", value) is None
+ ]
+ if invalid:
+ raise ValueError(f"invalid PLINDER PDB IDs: {invalid[:10]}")
+ return selected
+
+
+def _build_mmseqs_target_subset(
+ entry_chains: Path,
+ interface_annotations: Path,
+ *,
+ entry_ids: Iterable[str],
+ output_dir: Path,
+ threads: int = 1,
+ monomer_only: bool = False,
+) -> SearchDatabaseBundle | None:
+ """Build a bounded MMseqs target from selected release chains."""
+ selected = _plinder_entry_subset(entry_ids)
+ assert selected is not None
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ if shutil.which("mmseqs") is None:
+ raise FileNotFoundError("mmseqs executable is required for custom searches")
+
+ chains = pd.read_parquet(
+ entry_chains,
+ columns=[
+ "entry_pdb_id",
+ "chain_asym_id",
+ "chain_auth_id",
+ "chain_receptor_type",
+ "chain_is_holo",
+ "chain_sequence",
+ *(["chain_is_ligand_like"] if monomer_only else []),
+ ],
+ filters=[("entry_pdb_id", "in", list(selected))],
+ )
+ interfaces = pd.read_parquet(
+ interface_annotations,
+ columns=["entry_pdb_id", "interface_chain_1", "interface_chain_2"],
+ filters=[("entry_pdb_id", "in", list(selected))],
+ )
+ interface_keys = pd.concat(
+ [
+ interfaces[["entry_pdb_id", column]].rename(
+ columns={column: "chain_instance"}
+ )
+ for column in ["interface_chain_1", "interface_chain_2"]
+ ],
+ ignore_index=True,
+ )
+ interface_keys["chain_asym_id"] = (
+ interface_keys.pop("chain_instance").astype(str).str.split(".", n=1).str[-1]
+ )
+ interface_keys = interface_keys.drop_duplicates()
+ interface_keys["chain_is_interface"] = True
+ chains = chains.merge(
+ interface_keys,
+ on=["entry_pdb_id", "chain_asym_id"],
+ how="left",
+ validate="one_to_one",
+ )
+ scoreable = chains["chain_is_holo"].fillna(False).astype(bool) | chains[
+ "chain_is_interface"
+ ].eq(True)
+ selected_chains = (
+ ~scoreable & ~chains["chain_is_ligand_like"].fillna(False).astype(bool)
+ if monomer_only
+ else scoreable
+ )
+ chains = chains.loc[
+ chains["chain_receptor_type"].fillna("").astype(str).eq("protein")
+ & selected_chains
+ & chains["chain_auth_id"].notna()
+ & chains["chain_sequence"].notna()
+ ].copy()
+ if monomer_only and chains.empty:
+ return None
+ found = set(chains["entry_pdb_id"].astype(str))
+ missing = sorted(set(selected).difference(found))
+ if missing and not monomer_only:
+ raise ValueError(
+ "selected PLINDER entries have no scoreable receptor or interface "
+ f"chains: {missing[:10]}"
+ )
+
+ chains["target_id"] = (
+ chains["entry_pdb_id"].astype(str) + "_" + chains["chain_auth_id"].astype(str)
+ )
+ duplicate_ids = chains.loc[
+ chains["target_id"].duplicated(keep=False), "target_id"
+ ].drop_duplicates()
+ if not duplicate_ids.empty:
+ raise ValueError(
+ "selected PLINDER chains have ambiguous author IDs: "
+ f"{duplicate_ids.tolist()[:10]}"
+ )
+
+ records: list[str] = []
+ for row in chains.sort_values("target_id").itertuples(index=False):
+ if any(character.isspace() for character in str(row.target_id)):
+ raise ValueError(f"invalid PLINDER target identifier: {row.target_id!r}")
+ sequence = _clean_protein_sequence(
+ str(row.chain_sequence),
+ context=f"{row.entry_pdb_id} chain {row.chain_auth_id}",
+ )
+ records.append(f">{row.target_id}\n{sequence}\n")
+
+ root = Path(output_dir) / "mmseqs"
+ if root.exists():
+ shutil.rmtree(root)
+ root.mkdir(exist_ok=True, parents=True)
+ fasta = root / "targets.fasta"
+ fasta.write_text("".join(records))
+ database = root / "targets"
+ _run_command(
+ [
+ "mmseqs",
+ "createdb",
+ str(fasta),
+ str(database),
+ "--threads",
+ str(threads),
+ ]
+ )
+ return SearchDatabaseBundle(
+ backend="mmseqs",
+ root=root,
+ search_target=database,
+ conversion_target=database,
+ cluster_alignments=None,
+ manifest={"plinder_entry_ids": list(selected)},
+ )
+
+
+def _resolve_workflow_assets(
+ *,
+ data_dir: Path | None,
+ backends: tuple[str, ...],
+ plinder_entry_ids: tuple[str, ...] | None,
+ work_dir: Path,
+ threads: int,
+ include_monomers: bool = False,
+) -> CustomScoringAssets:
+ if plinder_entry_ids is not None and backends != ("mmseqs",):
+ raise ValueError("plinder_entry_ids currently requires backends=('mmseqs',)")
+ assets = resolve_custom_scoring_assets(
+ data_dir=data_dir,
+ backends=() if plinder_entry_ids is not None else backends,
+ include_monomers=include_monomers and plinder_entry_ids is None,
+ )
+ if plinder_entry_ids is None:
+ return assets
+ subset = _build_mmseqs_target_subset(
+ assets.entry_chains,
+ assets.interface_annotations,
+ entry_ids=plinder_entry_ids,
+ output_dir=work_dir / "plinder_target_subset",
+ threads=threads,
+ )
+ assert subset is not None
+ monomer_subset = (
+ _build_mmseqs_target_subset(
+ assets.entry_chains,
+ assets.interface_annotations,
+ entry_ids=plinder_entry_ids,
+ output_dir=work_dir / "plinder_monomer_subset",
+ threads=threads,
+ monomer_only=True,
+ )
+ if include_monomers
+ else None
+ )
+ return replace(
+ assets,
+ search_databases={"mmseqs": subset},
+ monomer_search_databases=(
+ {"mmseqs": monomer_subset} if monomer_subset is not None else {}
+ ),
+ shadowed_entries=frozenset(),
+ )
+
+
+def _parse_plinder_target_identifier(
+ identifier: str, *, backend: str
+) -> tuple[str, str]:
+ cleaned = str(identifier)
+ for value in (
+ "_xyz-enrich.cif.gz",
+ "_xyz-enrich.cif",
+ "_xyz-enrich",
+ "pdb_0000",
+ ".cif.gz",
+ ".cif",
+ ):
+ cleaned = cleaned.replace(value, "")
+ entry_id, separator, author_chain = cleaned.partition("_")
+ if not separator or not entry_id or not author_chain:
+ raise ValueError(f"invalid {backend} target identifier: {identifier!r}")
+ if backend == "foldseek":
+ author_chain = re.sub(r"^MODEL_\d+_", "", author_chain)
+ return entry_id.lower(), author_chain
+
+
+def _load_target_chain_mapping(
+ lookup_path: Path, target_identifiers: Iterable[str], *, backend: str
+) -> pd.DataFrame:
+ parsed = pd.DataFrame(
+ [
+ {
+ "target_backend_id": identifier,
+ "target_entry": entry_id,
+ "target_chain_auth_id": auth_id,
+ }
+ for identifier in sorted(set(target_identifiers))
+ for entry_id, auth_id in [
+ _parse_plinder_target_identifier(identifier, backend=backend)
+ ]
+ ]
+ )
+ if parsed.empty:
+ return parsed.assign(
+ target_chain_asym_id=pd.Series(dtype="string"),
+ target_selected_residue_numbers=pd.Series(dtype="object"),
+ target_selected_residue_indices=pd.Series(dtype="object"),
+ )
+ entry_ids = sorted(set(parsed["target_entry"]))
+ lookup = pd.read_parquet(
+ lookup_path,
+ columns=[
+ "entry_pdb_id",
+ "chain_asym_id",
+ "chain_auth_id",
+ "selected_residue_numbers",
+ "selected_residue_indices",
+ ],
+ filters=[("entry_pdb_id", "in", entry_ids)],
+ ).rename(
+ columns={
+ "entry_pdb_id": "target_entry",
+ "chain_asym_id": "target_chain_asym_id",
+ "chain_auth_id": "target_chain_auth_id",
+ "selected_residue_numbers": "target_selected_residue_numbers",
+ "selected_residue_indices": "target_selected_residue_indices",
+ }
+ )
+ key_columns = ["target_entry", "target_chain_auth_id"]
+ ambiguous = (
+ lookup.groupby(key_columns, dropna=False)["target_chain_asym_id"]
+ .nunique()
+ .loc[lambda values: values > 1]
+ )
+ if not ambiguous.empty:
+ raise ValueError(
+ "alignment chain lookup has ambiguous author-chain mappings: "
+ f"{list(ambiguous.index[:10])}"
+ )
+ lookup = lookup.drop_duplicates(key_columns)
+ mapped = parsed.merge(lookup, on=key_columns, how="left", validate="many_to_one")
+ missing = mapped.loc[
+ mapped["target_chain_asym_id"].isna(), "target_backend_id"
+ ].tolist()
+ if missing:
+ raise ValueError(
+ f"PLINDER alignment lookup cannot map target chains: {missing[:10]}"
+ )
+ return mapped
+
+
+def map_custom_alignment_hits(
+ *,
+ raw_alignment: Path,
+ backend: str,
+ query_databases: CustomQueryDatabases,
+ alignment_chain_lookup: Path,
+ output_path: Path,
+ exclude_target_entries: Iterable[str] = (),
+) -> Path:
+ """Replace backend identifiers with custom and PLINDER label-asym IDs."""
+ if backend not in SEARCH_BACKENDS:
+ raise ValueError(f"unsupported search backend: {backend}")
+ raw = pd.read_parquet(raw_alignment)
+ excluded = {str(entry).lower() for entry in exclude_target_entries}
+ if excluded and not raw.empty:
+ target_entries = {
+ target: _parse_plinder_target_identifier(str(target), backend=backend)[0]
+ for target in raw["target"].unique()
+ }
+ raw = raw.loc[~raw["target"].map(target_entries).isin(excluded)].copy()
+ identifier_map = pd.read_parquet(
+ query_databases.identifier_map,
+ filters=[("backend", "=", backend)],
+ )
+ chains = pd.read_parquet(query_databases.inputs.chain_manifest)
+ query_mapping = identifier_map.merge(
+ chains,
+ on="query_id",
+ how="left",
+ validate="many_to_one",
+ )
+ output_path.parent.mkdir(exist_ok=True, parents=True)
+ if raw.empty:
+ columns = [
+ "query_id",
+ "query_chain_id",
+ "structure_id",
+ "query_chain_asym_id",
+ "target_entry",
+ "target_chain_asym_id",
+ "source",
+ ]
+ pd.DataFrame(
+ {column: pd.Series(dtype="string") for column in columns}
+ ).to_parquet(output_path, index=False)
+ return output_path
+ query_columns = query_mapping[
+ [
+ "backend_query_id",
+ "query_id",
+ "query_chain_id",
+ "structure_id",
+ "chain_asym_id",
+ "sequence_source",
+ "resolved_residue_numbers",
+ ]
+ ].rename(
+ columns={
+ "backend_query_id": "query_backend_id",
+ "chain_asym_id": "query_chain_asym_id",
+ "sequence_source": "query_sequence_source",
+ "resolved_residue_numbers": "query_resolved_residue_numbers",
+ }
+ )
+ raw = raw.rename(
+ columns={"query": "query_backend_id", "target": "target_backend_id"}
+ )
+ mapped = raw.merge(
+ query_columns,
+ on="query_backend_id",
+ how="left",
+ validate="many_to_one",
+ )
+ missing_queries = mapped.loc[
+ mapped["query_id"].isna(), "query_backend_id"
+ ].drop_duplicates()
+ if not missing_queries.empty:
+ raise ValueError(
+ f"cannot map {backend} query chains: {missing_queries.tolist()[:10]}"
+ )
+ targets = _load_target_chain_mapping(
+ alignment_chain_lookup,
+ mapped["target_backend_id"],
+ backend=backend,
+ )
+ mapped = mapped.merge(
+ targets,
+ on="target_backend_id",
+ how="left",
+ validate="many_to_one",
+ )
+ mapped["source"] = backend
+ mapped = mapped.drop(columns=["query_pdb_id", "target_pdb_id"], errors="ignore")
+ leading = [
+ "query_id",
+ "query_chain_id",
+ "structure_id",
+ "query_chain_asym_id",
+ "target_entry",
+ "target_chain_asym_id",
+ "source",
+ ]
+ remainder = [column for column in mapped.columns if column not in leading]
+ mapped = mapped[leading + remainder].sort_values(
+ ["query_id", "target_entry", "target_chain_asym_id"],
+ ignore_index=True,
+ )
+ mapped.to_parquet(output_path, index=False, compression="zstd")
+ return output_path
+
+
+def _int_values(value: object, *, column: str) -> list[int]:
+ if value is None or isinstance(value, (str, bytes)):
+ return []
+ if not isinstance(value, IterableABC):
+ if pd.isna(value):
+ return []
+ raise ValueError(f"custom alignment column {column} is not a list")
+ return [int(item) for item in value]
+
+
+def _selected_positions_for_custom_hit(
+ row: Any,
+ *,
+ backend: str,
+ query_entry: Any,
+) -> tuple[list[int], list[int], bytes]:
+ """Map selected custom residues through one raw pairwise alignment."""
+ qaln = str(row.qaln).upper()
+ taln = str(row.taln).upper()
+ alignment_length = min(len(qaln), len(taln))
+ qaln = qaln[:alignment_length]
+ taln = taln[:alignment_length]
+ query_chain = str(row.query_chain_asym_id)
+ query_index_to_number = query_entry.selected_index_to_number_per_chain.get(
+ query_chain, {}
+ )
+ if not query_index_to_number or alignment_length == 0:
+ return [], [], b""
+
+ target_numbers = _int_values(
+ row.target_selected_residue_numbers,
+ column="target_selected_residue_numbers",
+ )
+ target_indices = _int_values(
+ row.target_selected_residue_indices,
+ column="target_selected_residue_indices",
+ )
+ if len(target_numbers) != len(target_indices):
+ raise ValueError(
+ "target selected-residue numbers and indices have different lengths "
+ f"for {row.target_entry} chain {row.target_chain_asym_id}"
+ )
+ target_index_to_number = dict(zip(target_indices, target_numbers, strict=True))
+
+ query_start = int(row.qstart) - 1
+ target_start = int(row.tstart) - 1
+ query_alignment_positions = [
+ position for position, residue in enumerate(qaln) if residue != "-"
+ ]
+ target_alignment_positions = [
+ position for position, residue in enumerate(taln) if residue != "-"
+ ]
+ if backend in SEQUENCE_SEARCH_BACKENDS:
+ query_numbers = set(query_index_to_number.values())
+ if str(row.query_sequence_source) == "coordinates":
+ resolved_numbers = _int_values(
+ row.query_resolved_residue_numbers,
+ column="query_resolved_residue_numbers",
+ )
+ if len(resolved_numbers) != len(set(resolved_numbers)):
+ raise ValueError(
+ "coordinate-derived FASTA has ambiguous residue numbers for "
+ f"{row.structure_id} chain {query_chain}"
+ )
+ residue_number_to_fasta_position = {
+ number: position
+ for position, number in enumerate(resolved_numbers, start=1)
+ }
+ missing_numbers = sorted(
+ query_numbers.difference(residue_number_to_fasta_position)
+ )
+ if missing_numbers:
+ raise ValueError(
+ "coordinate-derived FASTA is missing selected residues for "
+ f"{row.structure_id} chain {query_chain}: {missing_numbers}"
+ )
+ query_candidates = [
+ (
+ residue_number_to_fasta_position[number] - (query_start + 1),
+ number,
+ )
+ for number in query_numbers
+ ]
+ elif str(row.query_sequence_source) == "polymer":
+ query_candidates = [
+ (number - (query_start + 1), number) for number in query_numbers
+ ]
+ else:
+ raise ValueError(
+ "unknown query FASTA sequence source for "
+ f"{row.structure_id} chain {query_chain}: "
+ f"{row.query_sequence_source!r}"
+ )
+ target_selected_numbers = set(target_index_to_number.values())
+ else:
+ query_candidates = [
+ (index - query_start, number)
+ for index, number in query_index_to_number.items()
+ ]
+ target_selected_numbers = set()
+
+ aligned_query_numbers: list[int] = []
+ aligned_target_numbers: list[int] = []
+ residue_identity: list[bool] = []
+ for query_offset, query_number in sorted(query_candidates):
+ if not 0 <= query_offset < len(query_alignment_positions):
+ continue
+ alignment_position = query_alignment_positions[query_offset]
+ if taln[alignment_position] == "-":
+ continue
+ target_index = target_start + bisect_left(
+ target_alignment_positions, alignment_position
+ )
+ if backend in SEQUENCE_SEARCH_BACKENDS:
+ target_number = (
+ target_index + 1
+ if target_index + 1 in target_selected_numbers
+ else None
+ )
+ else:
+ target_number = target_index_to_number.get(target_index)
+ aligned_query_numbers.append(int(query_number))
+ aligned_target_numbers.append(
+ int(target_number) if target_number is not None else -1
+ )
+ residue_identity.append(qaln[alignment_position] == taln[alignment_position])
+ return (
+ aligned_query_numbers,
+ aligned_target_numbers,
+ pack_residue_identities(residue_identity),
+ )
+
+
+def prepare_custom_score_alignments(
+ protein_hits: Mapping[str, Path],
+ *,
+ entries_by_structure: Mapping[str, Any],
+ output_dir: Path,
+) -> dict[str, Path]:
+ """Write hit tables in the compact alignment format used by PLINDER scores."""
+ from plinder.data.annotations.get_similarity_scores import (
+ get_sequence_similarity_helper,
+ )
+
+ unsupported = sorted(set(protein_hits).difference(SEARCH_BACKENDS))
+ if unsupported:
+ raise ValueError(f"unsupported search backends: {unsupported}")
+ query_entry_ids = [str(entry.pdb_id) for entry in entries_by_structure.values()]
+ if len(query_entry_ids) != len(set(query_entry_ids)):
+ raise ValueError("custom scoring entries must have distinct entry IDs")
+ output_dir = Path(output_dir)
+ output_dir.mkdir(exist_ok=True, parents=True)
+ outputs: dict[str, Path] = {}
+ required = {
+ "structure_id",
+ "query_chain_asym_id",
+ "target_entry",
+ "target_chain_asym_id",
+ "target_selected_residue_numbers",
+ "target_selected_residue_indices",
+ "qstart",
+ "tstart",
+ "qcov",
+ "fident",
+ "qaln",
+ "taln",
+ }
+ for backend, hit_path in protein_hits.items():
+ hits = pd.read_parquet(hit_path)
+ output = output_dir / f"{backend}.parquet"
+ if hits.empty:
+ pd.DataFrame(
+ {
+ column: pd.Series(dtype="string")
+ for column in (
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ "source",
+ )
+ }
+ ).to_parquet(output, index=False)
+ outputs[backend] = output
+ continue
+ backend_required = required | (
+ {"query_sequence_source", "query_resolved_residue_numbers"}
+ if backend in SEQUENCE_SEARCH_BACKENDS
+ else set()
+ )
+ missing = sorted(backend_required.difference(hits.columns))
+ if missing:
+ raise ValueError(f"{backend} custom hit table is missing columns {missing}")
+ unknown_structures = sorted(
+ set(hits["structure_id"].astype(str)).difference(entries_by_structure)
+ )
+ if unknown_structures:
+ raise ValueError(
+ f"{backend} hits reference unknown custom structures: "
+ f"{unknown_structures}"
+ )
+ hits = hits.loc[~hits["target_entry"].astype(str).isin(query_entry_ids)].copy()
+ if hits.empty:
+ pd.DataFrame(
+ {
+ column: pd.Series(dtype="string")
+ for column in (
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ "source",
+ )
+ }
+ ).to_parquet(output, index=False)
+ outputs[backend] = output
+ continue
+ selected = [
+ _selected_positions_for_custom_hit(
+ row,
+ backend=backend,
+ query_entry=entries_by_structure[str(row.structure_id)],
+ )
+ for row in hits.itertuples(index=False)
+ ]
+ hits["query_selected_residue_numbers"] = [value[0] for value in selected]
+ hits["target_selected_residue_numbers"] = [value[1] for value in selected]
+ hits["selected_residue_identity_bits"] = [value[2] for value in selected]
+ hits["query_entry"] = [
+ str(entries_by_structure[str(value)].pdb_id)
+ for value in hits["structure_id"]
+ ]
+ hits["query_chain_mapped"] = hits["query_chain_asym_id"].astype(str)
+ hits["target_chain_mapped"] = hits["target_chain_asym_id"].astype(str)
+ hits["source"] = backend
+ hits["seqsim"] = [
+ get_sequence_similarity_helper(str(qaln).upper(), str(taln).upper())
+ for qaln, taln in zip(hits["qaln"], hits["taln"], strict=True)
+ ]
+ hits["fident_qcov"] = hits["fident"] * hits["qcov"]
+ hits["seqsim_qcov"] = hits["seqsim"] * hits["qcov"]
+ if backend == "foldseek":
+ if "lddt" not in hits:
+ raise ValueError("foldseek custom hit table is missing column lddt")
+ hits["lddt_qcov"] = hits["lddt"] * hits["qcov"]
+ hits = hits.drop(
+ columns=[
+ "qaln",
+ "taln",
+ "target_selected_residue_indices",
+ ],
+ errors="ignore",
+ )
+ leading = [
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ "source",
+ ]
+ hits = hits[leading + [column for column in hits if column not in leading]]
+ hits = hits.sort_values(
+ [
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ ],
+ ignore_index=True,
+ )
+ hits.to_parquet(output, index=False, compression="zstd")
+ outputs[backend] = output
+ return outputs
+
+
+def _release_positions_for_custom_hit(
+ row: Any,
+ *,
+ backend: str,
+) -> tuple[list[int], list[int], bytes]:
+ """Project PLINDER selected residues through a custom-chain alignment."""
+ qaln = str(row.qaln).upper()
+ taln = str(row.taln).upper()
+ alignment_length = min(len(qaln), len(taln))
+ qaln = qaln[:alignment_length]
+ taln = taln[:alignment_length]
+ if alignment_length == 0:
+ return [], [], b""
+
+ selected_numbers = _int_values(
+ row.target_selected_residue_numbers,
+ column="target_selected_residue_numbers",
+ )
+ selected_indices = _int_values(
+ row.target_selected_residue_indices,
+ column="target_selected_residue_indices",
+ )
+ if len(selected_numbers) != len(selected_indices):
+ raise ValueError(
+ "target selected-residue numbers and indices have different lengths "
+ f"for {row.target_entry} chain {row.target_chain_asym_id}"
+ )
+ if not selected_numbers:
+ return [], [], b""
+
+ target_start = int(row.tstart) - 1
+ query_start = int(row.qstart) - 1
+ query_alignment_positions = [
+ position for position, residue in enumerate(qaln) if residue != "-"
+ ]
+ resolved_numbers = _int_values(
+ row.query_resolved_residue_numbers,
+ column="query_resolved_residue_numbers",
+ )
+ target_alignment_positions = [
+ position for position, residue in enumerate(taln) if residue != "-"
+ ]
+ if backend in SEQUENCE_SEARCH_BACKENDS:
+ selected = [
+ (number - (target_start + 1), number) for number in selected_numbers
+ ]
+ else:
+ selected = [
+ (index - target_start, number)
+ for index, number in zip(
+ selected_indices,
+ selected_numbers,
+ strict=True,
+ )
+ ]
+
+ query_numbers: list[int] = []
+ custom_numbers: list[int] = []
+ residue_identity: list[bool] = []
+ for target_offset, target_number in sorted(selected):
+ if not 0 <= target_offset < len(target_alignment_positions):
+ continue
+ alignment_position = target_alignment_positions[target_offset]
+ if qaln[alignment_position] == "-":
+ continue
+ query_index = query_start + bisect_left(
+ query_alignment_positions, alignment_position
+ )
+ if backend == "foldseek" or str(row.query_sequence_source) == "coordinates":
+ custom_number = (
+ resolved_numbers[query_index]
+ if 0 <= query_index < len(resolved_numbers)
+ else None
+ )
+ elif str(row.query_sequence_source) == "polymer":
+ custom_number = query_index + 1
+ else:
+ raise ValueError(
+ "unknown query sequence source for "
+ f"{row.structure_id} chain {row.query_chain_asym_id}: "
+ f"{row.query_sequence_source!r}"
+ )
+ query_numbers.append(int(target_number))
+ custom_numbers.append(int(custom_number) if custom_number is not None else -1)
+ residue_identity.append(qaln[alignment_position] == taln[alignment_position])
+ return query_numbers, custom_numbers, pack_residue_identities(residue_identity)
+
+
+def prepare_custom_protein_score_alignments(
+ protein_hits: Mapping[str, Path],
+ *,
+ entries_by_structure: Mapping[str, Any],
+ output_dir: Path,
+) -> dict[str, Path]:
+ """Write reverse compact alignments for PLINDER-to-custom protein scores."""
+ from plinder.data.annotations.get_similarity_scores import (
+ get_sequence_similarity_helper,
+ )
+
+ unsupported = sorted(set(protein_hits).difference(SEARCH_BACKENDS))
+ if unsupported:
+ raise ValueError(f"unsupported search backends: {unsupported}")
+ entry_id_by_structure = {
+ str(structure_id): str(entry.pdb_id)
+ for structure_id, entry in entries_by_structure.items()
+ }
+ if len(entry_id_by_structure) != len(set(entry_id_by_structure.values())):
+ raise ValueError("custom scoring entries must have distinct entry IDs")
+ output_dir = Path(output_dir)
+ output_dir.mkdir(exist_ok=True, parents=True)
+ outputs: dict[str, Path] = {}
+ required = {
+ "structure_id",
+ "query_chain_asym_id",
+ "query_sequence_source",
+ "query_resolved_residue_numbers",
+ "target_entry",
+ "target_chain_asym_id",
+ "target_selected_residue_numbers",
+ "target_selected_residue_indices",
+ "qstart",
+ "tstart",
+ "qcov",
+ "tcov",
+ "fident",
+ "qaln",
+ "taln",
+ }
+ empty_columns = (
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ "source",
+ )
+ for backend, hit_path in protein_hits.items():
+ hits = pd.read_parquet(hit_path)
+ output = output_dir / f"{backend}.parquet"
+ if hits.empty:
+ pd.DataFrame(
+ {column: pd.Series(dtype="string") for column in empty_columns}
+ ).to_parquet(output, index=False)
+ outputs[backend] = output
+ continue
+ missing = sorted(required.difference(hits.columns))
+ if missing:
+ raise ValueError(f"{backend} custom hit table is missing columns {missing}")
+ unknown_structures = sorted(
+ set(hits["structure_id"].astype(str)).difference(entry_id_by_structure)
+ )
+ if unknown_structures:
+ raise ValueError(
+ f"{backend} hits reference unknown custom structures: "
+ f"{unknown_structures}"
+ )
+ custom_entry_ids = hits["structure_id"].astype(str).map(entry_id_by_structure)
+ hits = hits.loc[
+ hits["target_entry"].astype(str).to_numpy() != custom_entry_ids.to_numpy()
+ ].copy()
+ if hits.empty:
+ pd.DataFrame(
+ {column: pd.Series(dtype="string") for column in empty_columns}
+ ).to_parquet(output, index=False)
+ outputs[backend] = output
+ continue
+
+ selected = [
+ _release_positions_for_custom_hit(row, backend=backend)
+ for row in hits.itertuples(index=False)
+ ]
+ custom_entries = hits["structure_id"].astype(str).map(entry_id_by_structure)
+ release_entries = hits["target_entry"].astype(str).copy()
+ custom_chains = hits["query_chain_asym_id"].astype(str).copy()
+ release_chains = hits["target_chain_asym_id"].astype(str).copy()
+ custom_coverage = hits["qcov"].copy()
+ hits["query_entry"] = release_entries
+ hits["target_entry"] = custom_entries
+ hits["query_chain_mapped"] = release_chains
+ hits["target_chain_mapped"] = custom_chains
+ hits["source"] = backend
+ hits["qcov"] = hits["tcov"]
+ hits["tcov"] = custom_coverage
+ hits["query_selected_residue_numbers"] = [value[0] for value in selected]
+ hits["target_selected_residue_numbers"] = [value[1] for value in selected]
+ hits["selected_residue_identity_bits"] = [value[2] for value in selected]
+ hits["seqsim"] = [
+ get_sequence_similarity_helper(str(qaln).upper(), str(taln).upper())
+ for qaln, taln in zip(hits["qaln"], hits["taln"], strict=True)
+ ]
+ hits["fident_qcov"] = hits["fident"] * hits["qcov"]
+ hits["seqsim_qcov"] = hits["seqsim"] * hits["qcov"]
+ if backend == "foldseek":
+ if "lddt" not in hits:
+ raise ValueError("foldseek custom hit table is missing column lddt")
+ hits["lddt_qcov"] = hits["lddt"] * hits["qcov"]
+ hits = hits.drop(
+ columns=[
+ "qaln",
+ "taln",
+ "cigar",
+ "target_selected_residue_indices",
+ ],
+ errors="ignore",
+ )
+ leading = list(empty_columns)
+ hits = hits[leading + [column for column in hits if column not in leading]]
+ hits = hits.sort_values(
+ [
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ ],
+ ignore_index=True,
+ )
+ hits.to_parquet(output, index=False, compression="zstd")
+ outputs[backend] = output
+ return outputs
+
+
+def run_custom_protein_searches(
+ *,
+ query_databases: CustomQueryDatabases,
+ assets: CustomScoringAssets,
+ output_dir: Path,
+ scratch_dir: Path,
+ config: CustomProteinSearchConfig | None = None,
+ backends: Iterable[str] = CIF_SEARCH_BACKENDS,
+ threads: int = 1,
+) -> dict[str, Path]:
+ """Search custom protein chains and write backend-independent hit tables."""
+ from plinder.data.annotations.get_similarity_scores import run_alignment
+ from plinder.data.pipeline.config import FoldseekConfig, MMSeqsConfig
+
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ config = config or CustomProteinSearchConfig()
+ selected = tuple(dict.fromkeys(backends))
+ unsupported = sorted(set(selected).difference(SEARCH_BACKENDS))
+ if unsupported:
+ raise ValueError(f"unsupported search backends: {unsupported}")
+ output_dir = Path(output_dir)
+ scratch_dir = Path(scratch_dir)
+ raw_root = output_dir / "raw"
+ raw_root.mkdir(exist_ok=True, parents=True)
+ outputs: dict[str, Path] = {}
+ for backend in selected:
+ if backend not in assets.search_databases:
+ raise ValueError(f"custom scoring assets omit {backend}")
+ bundle = assets.search_databases[backend]
+ backend_scratch = scratch_dir / backend
+ backend_scratch.mkdir(exist_ok=True, parents=True)
+ alignment_config: FoldseekConfig | MMSeqsConfig
+ if backend == "foldseek":
+ alignment_config = FoldseekConfig(
+ evalue=config.evalue_for(backend),
+ sensitivity=config.sensitivity,
+ max_seqs=config.max_seqs,
+ coverage=config.coverage,
+ min_seq_id=config.min_seq_id,
+ )
+ else:
+ alignment_config = MMSeqsConfig(
+ evalue=config.evalue_for(backend),
+ sensitivity=config.sensitivity,
+ max_seqs=config.max_seqs,
+ coverage=config.coverage,
+ min_seq_id=config.min_seq_id,
+ )
+ output = output_dir / f"{backend}.parquet"
+ target_bundles = [("base", bundle)]
+ if backend in assets.overlay_search_databases:
+ target_bundles.append(("overlay", assets.overlay_search_databases[backend]))
+ combine = len(target_bundles) > 1 or bool(assets.shadowed_entries)
+ frames: list[pd.DataFrame] = []
+ for label, target_bundle in target_bundles:
+ raw_prefix = raw_root / (
+ backend if label == "base" else f"{backend}_{label}"
+ )
+ search_config = alignment_config
+ if label == "base" and assets.shadowed_entries:
+ lookup = Path(f"{bundle.search_target}.lookup")
+ with lookup.open() as handle:
+ replaced = sum(
+ (
+ line.split("\t", 2)[1].removeprefix("pdb_0000")[:4]
+ if backend == "foldseek"
+ else line.split("\t", 2)[1].split("_", 1)[0]
+ )
+ in assets.shadowed_entries
+ for line in handle
+ )
+ search_config = replace(
+ alignment_config, max_seqs=alignment_config.max_seqs + replaced
+ )
+ run_alignment(
+ aln_type=backend,
+ query_db=query_databases.databases[backend],
+ target_db=target_bundle.conversion_target,
+ search_target_db=target_bundle.search_target,
+ cluster_alignment_db=target_bundle.cluster_alignments,
+ search_db=backend_scratch / f"result_{label}",
+ aln_file=raw_prefix,
+ alignment_config=search_config,
+ tmp_dir=backend_scratch / f"tmp_{label}",
+ remove_tmp=True,
+ threads=threads,
+ )
+ mapped = output_dir / f"{backend}_{label}.parquet" if combine else output
+ map_custom_alignment_hits(
+ raw_alignment=raw_prefix.with_suffix(".parquet"),
+ backend=backend,
+ query_databases=query_databases,
+ alignment_chain_lookup=assets.alignment_chain_lookup,
+ output_path=mapped,
+ exclude_target_entries=(
+ assets.shadowed_entries if label == "base" else ()
+ ),
+ )
+ if combine:
+ frame = pd.read_parquet(mapped)
+ frames.append(frame)
+ mapped.unlink()
+ if combine:
+ pd.concat(frames, ignore_index=True).to_parquet(output, index=False)
+ outputs[backend] = output
+ return outputs
+
+
+def run_custom_monomer_searches(
+ *,
+ query_databases: CustomQueryDatabases,
+ assets: CustomScoringAssets,
+ output_dir: Path,
+ scratch_dir: Path,
+ config: CustomProteinSearchConfig | None,
+ backends: Iterable[str],
+ threads: int,
+) -> dict[str, Path]:
+ """Search protein chains absent from pocket/interface targets."""
+ if not assets.monomer_search_databases:
+ return {}
+ monomer_assets = replace(
+ assets,
+ search_databases=assets.monomer_search_databases,
+ overlay_search_databases=assets.overlay_monomer_search_databases,
+ )
+ return run_custom_protein_searches(
+ query_databases=query_databases,
+ assets=monomer_assets,
+ output_dir=output_dir,
+ scratch_dir=scratch_dir,
+ config=config,
+ backends=(
+ backend
+ for backend in backends
+ if backend in assets.monomer_search_databases
+ ),
+ threads=threads,
+ )
+
+
+def write_custom_chain_similarity_scores(
+ protein_hits: Mapping[str, Path],
+ *,
+ output_path: Path,
+ chain_manifest: Path | None = None,
+ monomer_hits: Mapping[str, Path] | None = None,
+) -> Path:
+ """Write direct custom-to-PLINDER protein-chain alignment scores.
+
+ Coverage and similarity values use integer percentages, as in the release
+ protein similarity table. Each alignment remains a separate row.
+ """
+ from plinder.data.annotations.get_similarity_scores import (
+ get_sequence_similarity_helper,
+ )
+
+ columns = [
+ "sequence_id",
+ "query_id",
+ "query_chain_id",
+ "structure_id",
+ "query_chain_asym_id",
+ "target_entry",
+ "target_chain_asym_id",
+ "source",
+ "qcov",
+ "tcov",
+ "fident",
+ "seqsim",
+ "lddt",
+ ]
+ frames = []
+ for backend, path in [*protein_hits.items(), *(monomer_hits or {}).items()]:
+ hits = pd.read_parquet(path)
+ if hits.empty:
+ continue
+ required = set(columns).difference({"sequence_id", "seqsim", "lddt"}) | {
+ "qaln",
+ "taln",
+ }
+ if backend == "foldseek":
+ required.add("lddt")
+ missing = sorted(required.difference(hits.columns))
+ if missing:
+ raise ValueError(f"{backend} custom hit table is missing columns {missing}")
+ scores = hits[[column for column in columns if column in hits]].copy()
+ scores["seqsim"] = [
+ get_sequence_similarity_helper(str(query).upper(), str(target).upper())
+ for query, target in zip(hits["qaln"], hits["taln"], strict=True)
+ ]
+ if "lddt" not in scores:
+ scores["lddt"] = pd.NA
+ for column in ("qcov", "tcov", "fident", "seqsim", "lddt"):
+ scores[column] = (
+ np.floor(pd.to_numeric(scores[column], errors="coerce") * 100 + 0.5)
+ .clip(0, 100)
+ .astype("UInt8")
+ )
+ frames.append(scores)
+ result = (
+ pd.concat(frames, ignore_index=True)
+ if frames
+ else pd.DataFrame(columns=columns)
+ )
+ if chain_manifest is not None:
+ manifest = pd.read_parquet(chain_manifest, columns=["query_id", "sequence_id"])
+ if manifest["query_id"].duplicated().any():
+ raise ValueError("query chain manifest contains duplicate query IDs")
+ result = result.drop(columns="sequence_id", errors="ignore")
+ result = result.merge(
+ manifest, on="query_id", how="left", validate="many_to_one"
+ )
+ if result["sequence_id"].isna().any():
+ raise ValueError("custom chain scores contain unknown query IDs")
+ else:
+ result["sequence_id"] = pd.NA
+ result = result[columns]
+ output_path = Path(output_path)
+ output_path.parent.mkdir(parents=True, exist_ok=True)
+ result.to_parquet(output_path, index=False, compression="zstd")
+ return output_path
+
+
+def _target_entry_ids(score_alignments: Mapping[str, Path]) -> set[str]:
+ target_ids: set[str] = set()
+ for path in score_alignments.values():
+ frame = pd.read_parquet(path, columns=["target_entry"])
+ target_ids.update(frame["target_entry"].dropna().astype(str))
+ return target_ids
+
+
+def _query_entry_ids(score_alignments: Mapping[str, Path]) -> set[str]:
+ query_ids: set[str] = set()
+ for path in score_alignments.values():
+ frame = pd.read_parquet(path, columns=["query_entry"])
+ query_ids.update(frame["query_entry"].dropna().astype(str))
+ return query_ids
+
+
+def _load_release_entry_views(
+ assets: CustomScoringAssets,
+ *,
+ pdb_ids: Iterable[str],
+) -> dict[str, Any]:
+ from plinder.core.scores.entries import entry_views_from_df
+
+ selected = sorted(set(map(str, pdb_ids)))
+ if not selected:
+ return {}
+ annotation = pd.read_parquet(
+ assets.annotation_table,
+ filters=[("entry_pdb_id", "in", selected)],
+ )
+ entry_chains = pd.read_parquet(
+ assets.entry_chains,
+ filters=[("entry_pdb_id", "in", selected)],
+ )
+ interfaces = pd.read_parquet(
+ assets.interface_annotations,
+ filters=[("entry_pdb_id", "in", selected)],
+ )
+ return entry_views_from_df(
+ annotation,
+ entry_chains=entry_chains,
+ interface_annotations=interfaces,
+ )
+
+
+def _custom_ligand_sdf_resolver(
+ *,
+ query_entry_ids: set[str],
+ query_ligand_root: Path,
+ assets: CustomScoringAssets,
+ extracted_target_root: Path,
+ data_dir: Path | None,
+) -> Any:
+ """Return an SDF resolver that opens target archives only when called."""
+ archive_cache = dict(assets.ligand_archives)
+ packed_sdf_cache: dict[str, dict[tuple[str, str], bytes]] = {}
+ cache_lock = Lock()
+
+ def resolve(ligand: Any) -> Path | None:
+ pdb_id = str(ligand.pdb_id)
+ asym_id = str(ligand.asym_id)
+ if pdb_id in query_entry_ids:
+ custom_path = query_ligand_root / pdb_id / "ligand_files" / f"{asym_id}.sdf"
+ return custom_path if custom_path.is_file() else None
+
+ if data_dir is not None:
+ raw_path = (
+ Path(data_dir)
+ / "raw_entries"
+ / _pdb_shard(pdb_id)
+ / pdb_id
+ / "ligand_files"
+ / f"{asym_id}.sdf"
+ )
+ if raw_path.is_file():
+ return raw_path
+ extracted = extracted_target_root / pdb_id / "ligand_files" / f"{asym_id}.sdf"
+ if extracted.is_file():
+ return extracted
+
+ shard = _pdb_shard(pdb_id)
+ with cache_lock:
+ if extracted.is_file():
+ return extracted
+ if shard not in packed_sdf_cache:
+ archive = archive_cache.get(shard)
+ if archive is None:
+ archive = _release_file(
+ "ligand_archive",
+ data_dir=data_dir,
+ description=f"canonical ligand archive for shard {shard}",
+ shard=shard,
+ )
+ archive_cache[shard] = archive
+ packed = pd.read_parquet(
+ archive,
+ columns=["pdb_id", "ligand_asym_id", "sdf"],
+ )
+ packed_sdf_cache[shard] = {
+ (str(row.pdb_id), str(row.ligand_asym_id)): bytes(row.sdf)
+ for row in packed.itertuples(index=False)
+ }
+ sdf = packed_sdf_cache[shard].get((pdb_id, asym_id))
+ if sdf is None:
+ LOG.warning(
+ "canonical ligand archive has no row for %s/%s",
+ pdb_id,
+ asym_id,
+ )
+ return None
+ extracted.parent.mkdir(exist_ok=True, parents=True)
+ temporary = extracted.with_suffix(".tmp.sdf")
+ temporary.write_bytes(sdf)
+ temporary.replace(extracted)
+ return extracted
+
+ return resolve
+
+
+def calculate_custom_protein_similarity_scores(
+ protein_score_alignments: Mapping[str, Path],
+ *,
+ assets: CustomScoringAssets,
+ work_dir: Path,
+ plinder_system_ids: Iterable[str] | None = None,
+ custom_chain_ids: Iterable[str] | None = None,
+ output_path: Path | None = None,
+) -> pd.DataFrame:
+ """Score PLINDER receptors and ligand pockets against custom protein chains."""
+ from plinder.core.utils.schemas import PROTEIN_SIMILARITY_SCHEMA
+ from plinder.data.annotations.get_similarity_scores import Scorer
+
+ entries = _load_release_entry_views(
+ assets,
+ pdb_ids=_query_entry_ids(protein_score_alignments),
+ )
+ work_dir = Path(work_dir)
+ work_dir.mkdir(exist_ok=True, parents=True)
+ scorer = Scorer(
+ entries=entries,
+ source_to_full_db_file={},
+ db_dir=work_dir,
+ scores_dir=work_dir,
+ include_pli_fident=True,
+ )
+ selected_plinder_systems = (
+ set(map(str, plinder_system_ids)) if plinder_system_ids is not None else None
+ )
+ selected_custom_chains = (
+ set(map(str, custom_chain_ids)) if custom_chain_ids is not None else None
+ )
+ source_to_alignment = {
+ f"apo_{backend}": path for backend, path in protein_score_alignments.items()
+ }
+ alignments = scorer.load_alignments(
+ source_to_aln_file=source_to_alignment,
+ search_db="apo",
+ )
+ alignments_by_query_entry = (
+ {
+ str(entry_id): group.droplevel("query_entry")
+ for entry_id, group in alignments.groupby(level="query_entry", sort=False)
+ }
+ if not alignments.empty
+ else {}
+ )
+ frames: list[pd.DataFrame] = []
+ for entry_id in sorted(entries):
+ query_entry_alignments = alignments_by_query_entry.get(entry_id)
+ if query_entry_alignments is None:
+ continue
+ frame = scorer.aggregate_scores(
+ entry_id,
+ search_db="apo",
+ source_to_aln_file=source_to_alignment,
+ query_entry_alignments=query_entry_alignments,
+ query_system_ids=selected_plinder_systems,
+ target_system_ids=selected_custom_chains,
+ )
+ if frame is not None and not frame.empty:
+ frames.append(frame)
+ result = (
+ pd.concat(frames, ignore_index=True)
+ if frames
+ else pd.DataFrame(columns=PROTEIN_SIMILARITY_SCHEMA.names)
+ )
+ if not result.empty:
+ result = result.sort_values(
+ [
+ "similarity",
+ "query_system",
+ "query_ligand_id",
+ "target_system",
+ ],
+ ascending=[False, True, True, True],
+ ignore_index=True,
+ )
+ if output_path is not None:
+ output_path = Path(output_path)
+ output_path.parent.mkdir(exist_ok=True, parents=True)
+ result.to_parquet(output_path, index=False, compression="zstd")
+ return result
+
+
+def write_custom_aligned_pocket_residues(
+ protein_score_alignments: Mapping[str, Path],
+ *,
+ protein_scores: Path,
+ assets: CustomScoringAssets,
+ output_path: Path,
+) -> Path:
+ """Write residue pairs supporting custom-chain pocket identity scores."""
+ columns = [
+ "plinder_system_id",
+ "plinder_ligand_id",
+ "plinder_entry_id",
+ "plinder_chain_instance",
+ "plinder_chain_asym_id",
+ "plinder_residue_number",
+ "custom_structure_id",
+ "custom_chain_asym_id",
+ "custom_residue_number",
+ "residue_identical",
+ "source",
+ ]
+ scores = pd.read_parquet(
+ protein_scores,
+ columns=[
+ "query_system",
+ "query_ligand_id",
+ "target_system",
+ "protein_mapping",
+ "source",
+ "metric",
+ ],
+ )
+ pocket_scores = scores.loc[
+ scores["metric"].astype(str).eq("pocket_fident"),
+ [
+ "query_system",
+ "query_ligand_id",
+ "target_system",
+ "protein_mapping",
+ "source",
+ ],
+ ].drop_duplicates()
+ accepted: set[tuple[str, str, str, str, str, str]] = set()
+ for score in pocket_scores.itertuples(index=False):
+ if not isinstance(score.protein_mapping, str):
+ continue
+ score_sources = (
+ tuple(protein_score_alignments)
+ if str(score.source) == "both"
+ else (str(score.source),)
+ )
+ for pair in score.protein_mapping.split(";"):
+ if ":" not in pair:
+ continue
+ release_instance, custom_instance = pair.split(":", maxsplit=1)
+ release_chain = release_instance.split(".", maxsplit=1)[-1]
+ custom_chain = custom_instance.split(".", maxsplit=1)[-1]
+ for source in score_sources:
+ accepted.add(
+ (
+ str(score.query_system),
+ str(score.query_ligand_id),
+ str(score.target_system),
+ source,
+ release_chain,
+ custom_chain,
+ )
+ )
+ if not accepted:
+ result = pd.DataFrame(columns=columns)
+ else:
+ entries = _load_release_entry_views(
+ assets,
+ pdb_ids=_query_entry_ids(protein_score_alignments),
+ )
+ pocket_membership: dict[tuple[str, str, int], list[tuple[str, str, str]]] = {}
+ for entry_id, entry in entries.items():
+ for system in entry.systems.values():
+ for ligand in system.ligands.values():
+ if not ligand.is_proper:
+ continue
+ for (
+ instance_chain,
+ number_to_index,
+ ) in ligand.pocket_residue_number_to_index.items():
+ asym_id = instance_chain.split(".", maxsplit=1)[-1]
+ for residue_number in number_to_index:
+ pocket_membership.setdefault(
+ (str(entry_id), asym_id, int(residue_number)), []
+ ).append(
+ (
+ str(system.id),
+ str(ligand.id),
+ str(instance_chain),
+ )
+ )
+
+ rows: list[dict[str, Any]] = []
+ for backend, alignment_path in protein_score_alignments.items():
+ alignments = pd.read_parquet(alignment_path)
+ for row in alignments.itertuples(index=False):
+ release_entry = str(row.query_entry)
+ release_chain = str(row.query_chain_mapped)
+ custom_entry = str(row.target_entry)
+ custom_chain = str(row.target_chain_mapped)
+ target_system = f"{custom_entry}_{custom_chain}"
+ release_numbers = _int_values(
+ row.query_selected_residue_numbers,
+ column="query_selected_residue_numbers",
+ )
+ custom_numbers = _int_values(
+ row.target_selected_residue_numbers,
+ column="target_selected_residue_numbers",
+ )
+ if len(release_numbers) != len(custom_numbers):
+ raise ValueError(
+ "custom pocket residue alignment columns have different "
+ f"lengths for {release_entry} chain {release_chain}"
+ )
+ identities = unpack_residue_identities(
+ row.selected_residue_identity_bits, len(release_numbers)
+ )
+ for release_number, custom_number, identical in zip(
+ release_numbers,
+ custom_numbers,
+ identities,
+ strict=True,
+ ):
+ for system_id, ligand_id, instance_chain in pocket_membership.get(
+ (release_entry, release_chain, release_number), []
+ ):
+ if (
+ system_id,
+ ligand_id,
+ target_system,
+ backend,
+ release_chain,
+ custom_chain,
+ ) not in accepted:
+ continue
+ rows.append(
+ {
+ "plinder_system_id": system_id,
+ "plinder_ligand_id": ligand_id,
+ "plinder_entry_id": release_entry,
+ "plinder_chain_instance": instance_chain,
+ "plinder_chain_asym_id": release_chain,
+ "plinder_residue_number": release_number,
+ "custom_structure_id": custom_entry,
+ "custom_chain_asym_id": custom_chain,
+ "custom_residue_number": (
+ custom_number if custom_number >= 0 else pd.NA
+ ),
+ "residue_identical": bool(identical),
+ "source": backend,
+ }
+ )
+ result = pd.DataFrame.from_records(rows, columns=columns)
+ if not result.empty:
+ result = result.drop_duplicates().sort_values(
+ [
+ "custom_structure_id",
+ "custom_chain_asym_id",
+ "plinder_system_id",
+ "plinder_ligand_id",
+ "source",
+ "plinder_chain_instance",
+ "plinder_residue_number",
+ ],
+ ignore_index=True,
+ )
+ result["plinder_residue_number"] = result["plinder_residue_number"].astype("Int64")
+ result["custom_residue_number"] = result["custom_residue_number"].astype("Int64")
+ result["residue_identical"] = result["residue_identical"].astype("boolean")
+ output_path = Path(output_path)
+ output_path.parent.mkdir(exist_ok=True, parents=True)
+ result.to_parquet(output_path, index=False, compression="zstd")
+ return output_path
+
+
+def write_custom_sequence_link_tables(
+ *,
+ protein_scores: Path,
+ chain_manifest: Path,
+ annotation_table: Path,
+ output_path: Path,
+ best_output_path: Path,
+) -> tuple[Path, Path]:
+ """Attach sequence IDs and ligand chemistry to pocket-identity scores."""
+ manifest = pd.read_parquet(
+ chain_manifest,
+ columns=[
+ "structure_id",
+ "chain_asym_id",
+ "sequence_id",
+ "sequence_length",
+ ],
+ )
+ manifest["target_system"] = (
+ manifest["structure_id"].astype(str)
+ + "_"
+ + manifest["chain_asym_id"].astype(str)
+ )
+ target_map = manifest[
+ ["target_system", "sequence_id", "sequence_length"]
+ ].drop_duplicates()
+ if target_map.duplicated("target_system").any():
+ raise ValueError("sequence manifest has ambiguous target-system IDs")
+
+ scores = pd.read_parquet(protein_scores)
+ score_identity_columns = [
+ "query_system",
+ "query_ligand_id",
+ "target_system",
+ "protein_mapping",
+ "protein_mapper",
+ "source",
+ ]
+ score_pair_columns = [
+ "query_system",
+ "query_ligand_id",
+ "target_system",
+ ]
+ pocket = scores.loc[
+ scores["metric"].astype(str).eq("pocket_fident"),
+ [
+ *score_identity_columns,
+ "similarity",
+ ],
+ ].copy()
+ pli = scores.loc[
+ scores["metric"].astype(str).eq("pli_fident"),
+ [*score_pair_columns, "similarity"],
+ ].rename(columns={"similarity": "pli_fident"})
+ if pli.duplicated(score_pair_columns).any():
+ raise ValueError("protein scores contain duplicate PLI identity rows")
+ pocket = pocket.merge(
+ pli,
+ on=score_pair_columns,
+ how="left",
+ validate="one_to_one",
+ )
+ pocket = pocket.merge(
+ target_map,
+ on="target_system",
+ how="left",
+ validate="many_to_one",
+ )
+ if pocket["sequence_id"].isna().any():
+ missing = pocket.loc[pocket["sequence_id"].isna(), "target_system"].unique()
+ raise ValueError(f"protein scores reference unknown sequences: {missing[:10]}")
+
+ chemistry_columns = [
+ "system_id",
+ "ligand_id",
+ "ligand_ccd_code",
+ "ligand_unique_ccd_code",
+ "ligand_smiles",
+ ]
+ scored_pairs = (
+ pocket[["query_system", "query_ligand_id"]]
+ .drop_duplicates()
+ .rename(
+ columns={
+ "query_system": "system_id",
+ "query_ligand_id": "ligand_id",
+ }
+ )
+ )
+ scored_system_ids = scored_pairs["system_id"].astype(str).drop_duplicates().tolist()
+ chemistry = (
+ pd.read_parquet(
+ annotation_table,
+ columns=chemistry_columns,
+ filters=[("system_id", "in", scored_system_ids)],
+ ).drop_duplicates()
+ if scored_system_ids
+ else pd.DataFrame(columns=chemistry_columns)
+ )
+ chemistry = chemistry.merge(
+ scored_pairs,
+ on=["system_id", "ligand_id"],
+ how="inner",
+ validate="many_to_one",
+ )
+ if chemistry.duplicated(["system_id", "ligand_id"]).any():
+ raise ValueError("release annotation has conflicting ligand chemistry rows")
+ pocket = pocket.merge(
+ chemistry,
+ left_on=["query_system", "query_ligand_id"],
+ right_on=["system_id", "ligand_id"],
+ how="left",
+ validate="many_to_one",
+ indicator="_chemistry_merge",
+ )
+ missing_chemistry = pocket["_chemistry_merge"].ne("both")
+ if missing_chemistry.any():
+ missing = pocket.loc[
+ missing_chemistry, ["query_system", "query_ligand_id"]
+ ].drop_duplicates()
+ raise ValueError(
+ "release annotation has no row for scored PLINDER ligands: "
+ f"{missing.head(10).to_dict('records')}"
+ )
+ pocket["plinder_pdb_id"] = (
+ pocket["query_system"].astype(str).str.split("__", n=1).str[0]
+ )
+ pocket = pocket.rename(
+ columns={
+ "query_system": "plinder_system_id",
+ "query_ligand_id": "plinder_ligand_id",
+ "similarity": "pocket_fident",
+ "ligand_ccd_code": "plinder_ligand_ccd_code",
+ "ligand_unique_ccd_code": "plinder_ligand_unique_ccd_code",
+ "ligand_smiles": "plinder_ligand_smiles",
+ }
+ ).drop(columns=["system_id", "ligand_id", "target_system", "_chemistry_merge"])
+ link_columns = [
+ "sequence_id",
+ "sequence_length",
+ "plinder_pdb_id",
+ "plinder_system_id",
+ "plinder_ligand_id",
+ "pocket_fident",
+ "pli_fident",
+ "protein_mapping",
+ "protein_mapper",
+ "source",
+ "plinder_ligand_ccd_code",
+ "plinder_ligand_unique_ccd_code",
+ "plinder_ligand_smiles",
+ ]
+ pocket = pocket[link_columns].sort_values(
+ ["sequence_id", "pocket_fident", "plinder_pdb_id", "plinder_ligand_id"],
+ ascending=[True, False, True, True],
+ ignore_index=True,
+ )
+ output_path = Path(output_path)
+ best_output_path = Path(best_output_path)
+ output_path.parent.mkdir(exist_ok=True, parents=True)
+ pocket.to_parquet(output_path, index=False, compression="zstd")
+
+ best_hits = pocket.drop_duplicates("sequence_id", keep="first")
+ best = manifest[["sequence_id", "sequence_length"]].merge(
+ best_hits.drop(columns="sequence_length"),
+ on="sequence_id",
+ how="left",
+ validate="one_to_one",
+ )
+ best = best[link_columns]
+ best.to_parquet(best_output_path, index=False, compression="zstd")
+ return output_path, best_output_path
+
+
+def add_sequence_ids_to_aligned_pocket_residues(
+ aligned_pocket_residues: Path,
+ *,
+ chain_manifest: Path,
+) -> Path:
+ """Add original FASTA identifiers to sequence-query residue mappings."""
+ path = Path(aligned_pocket_residues)
+ residues = pd.read_parquet(path)
+ identifiers = pd.read_parquet(
+ chain_manifest,
+ columns=["structure_id", "sequence_id"],
+ ).drop_duplicates()
+ if identifiers.duplicated("structure_id").any():
+ raise ValueError("sequence manifest has ambiguous structure IDs")
+ residues = residues.merge(
+ identifiers,
+ left_on="custom_structure_id",
+ right_on="structure_id",
+ how="left",
+ validate="many_to_one",
+ ).drop(columns="structure_id")
+ if not residues.empty and residues["sequence_id"].isna().any():
+ missing = residues.loc[
+ residues["sequence_id"].isna(), "custom_structure_id"
+ ].unique()
+ raise ValueError(
+ f"residue mappings reference unknown sequences: {missing[:10]}"
+ )
+ leading = ["sequence_id"]
+ residues = residues[
+ leading + [column for column in residues if column not in leading]
+ ]
+ temporary = path.with_suffix(".tmp.parquet")
+ residues.to_parquet(temporary, index=False, compression="zstd")
+ temporary.replace(path)
+ return path
+
+
+def score_custom_sequence_file(
+ sequence_fasta: Path,
+ *,
+ work_dir: Path,
+ scratch_dir: Path | None = None,
+ data_dir: Path | None = None,
+ search_config: CustomProteinSearchConfig | None = None,
+ backends: Iterable[str] = SEQUENCE_SEARCH_BACKENDS,
+ plinder_entry_ids: Iterable[str] | None = None,
+ threads: int = 1,
+ store_aligned_pocket_residues: bool = False,
+ include_monomers: bool = False,
+) -> CustomSequenceScoringResult:
+ """Search protein sequences and score PLINDER ligand-pocket identity.
+
+ ``plinder_entry_ids`` builds a small MMseqs target from the scoreable
+ receptor and interface chains in the selected release entries instead of
+ fetching the complete search database. This bounded mode currently requires
+ ``backends=("mmseqs",)``.
+ """
+ selected_backends = tuple(dict.fromkeys(backends))
+ if not selected_backends:
+ raise ValueError("at least one sequence search backend is required")
+ unsupported = sorted(set(selected_backends).difference(SEQUENCE_SEARCH_BACKENDS))
+ if unsupported:
+ raise ValueError(
+ f"unsupported sequence search backends: {unsupported}; "
+ f"expected a subset of {SEQUENCE_SEARCH_BACKENDS}"
+ )
+ work_dir = Path(work_dir)
+ work_dir.mkdir(exist_ok=True, parents=True)
+ selected_plinder_entries = _plinder_entry_subset(plinder_entry_ids)
+ query_inputs = write_custom_sequence_query_files(
+ Path(sequence_fasta),
+ work_dir=work_dir,
+ )
+ query_databases = create_custom_query_databases(
+ query_inputs,
+ work_dir=work_dir,
+ backends=selected_backends,
+ threads=threads,
+ )
+ assets = _resolve_workflow_assets(
+ data_dir=data_dir,
+ backends=selected_backends,
+ plinder_entry_ids=selected_plinder_entries,
+ work_dir=work_dir,
+ threads=threads,
+ include_monomers=include_monomers,
+ )
+ protein_hits = run_custom_protein_searches(
+ query_databases=query_databases,
+ assets=assets,
+ output_dir=work_dir / "protein_hits",
+ scratch_dir=(
+ Path(scratch_dir) if scratch_dir is not None else work_dir / "scratch"
+ ),
+ config=search_config,
+ backends=selected_backends,
+ threads=threads,
+ )
+ monomer_hits = run_custom_monomer_searches(
+ query_databases=query_databases,
+ assets=assets,
+ output_dir=work_dir / "monomer_hits",
+ scratch_dir=(
+ Path(scratch_dir) if scratch_dir is not None else work_dir / "scratch"
+ )
+ / "monomer",
+ config=search_config,
+ backends=selected_backends,
+ threads=threads,
+ )
+ chain_similarity_scores = write_custom_chain_similarity_scores(
+ protein_hits,
+ output_path=work_dir / "chain_similarity_scores.parquet",
+ chain_manifest=query_inputs.chain_manifest,
+ monomer_hits=monomer_hits,
+ )
+ manifest = pd.read_parquet(query_inputs.chain_manifest)
+ entries_by_structure = {
+ str(structure_id): _SequenceEntry(pdb_id=str(structure_id))
+ for structure_id in manifest["structure_id"]
+ }
+ protein_score_alignments = prepare_custom_protein_score_alignments(
+ protein_hits,
+ entries_by_structure=entries_by_structure,
+ output_dir=work_dir / "protein_score_alignments",
+ )
+ protein_score_path = work_dir / "protein_scores.parquet"
+ calculate_custom_protein_similarity_scores(
+ protein_score_alignments,
+ assets=assets,
+ work_dir=work_dir / "protein_score_work",
+ output_path=protein_score_path,
+ )
+ aligned_pocket_residue_path = (
+ work_dir / "aligned_pocket_residues.parquet"
+ if store_aligned_pocket_residues
+ else None
+ )
+ if aligned_pocket_residue_path is not None:
+ write_custom_aligned_pocket_residues(
+ protein_score_alignments,
+ protein_scores=protein_score_path,
+ assets=assets,
+ output_path=aligned_pocket_residue_path,
+ )
+ add_sequence_ids_to_aligned_pocket_residues(
+ aligned_pocket_residue_path,
+ chain_manifest=query_inputs.chain_manifest,
+ )
+ sequence_links, best_sequence_links = write_custom_sequence_link_tables(
+ protein_scores=protein_score_path,
+ chain_manifest=query_inputs.chain_manifest,
+ annotation_table=assets.annotation_table,
+ output_path=work_dir / "sequence_links.parquet",
+ best_output_path=work_dir / "best_sequence_links.parquet",
+ )
+ return CustomSequenceScoringResult(
+ query_inputs=query_inputs,
+ query_databases=query_databases,
+ protein_hits=protein_hits,
+ chain_similarity_scores=chain_similarity_scores,
+ protein_score_alignments=protein_score_alignments,
+ protein_scores=protein_score_path,
+ aligned_pocket_residues=aligned_pocket_residue_path,
+ sequence_links=sequence_links,
+ best_sequence_links=best_sequence_links,
+ )
+
+
+def calculate_custom_similarity_scores(
+ score_alignments: Mapping[str, Path],
+ *,
+ annotations: CustomStructureAnnotations,
+ assets: CustomScoringAssets,
+ work_dir: Path,
+ include_shape: bool = True,
+ shape_score_threads: int = 1,
+ target_system_ids: Iterable[str] | None = None,
+ target_ligand_ids: Iterable[str] | None = None,
+ data_dir: Path | None = None,
+ output_path: Path | None = None,
+) -> pd.DataFrame:
+ """Calculate directed ligand-pocket scores from custom structures."""
+ from plinder.core.utils.schemas import PROTEIN_SIMILARITY_SCHEMA
+ from plinder.data.annotations.get_similarity_scores import Scorer
+
+ query_entries = {
+ str(entry.pdb_id): entry for entry in annotations.entries_by_structure.values()
+ }
+ target_entries = _load_release_entry_views(
+ assets,
+ pdb_ids=_target_entry_ids(score_alignments).difference(query_entries),
+ )
+ entries = {**target_entries, **query_entries}
+ work_dir = Path(work_dir)
+ work_dir.mkdir(exist_ok=True, parents=True)
+ scorer = Scorer(
+ entries=entries,
+ source_to_full_db_file={},
+ db_dir=work_dir,
+ scores_dir=work_dir,
+ ligand_sdf_resolver=_custom_ligand_sdf_resolver(
+ query_entry_ids=set(query_entries),
+ query_ligand_root=annotations.ligand_sdf_root,
+ assets=assets,
+ extracted_target_root=work_dir / "target_ligands",
+ data_dir=data_dir,
+ ),
+ shape_score_threads=shape_score_threads,
+ include_pli_fident=True,
+ )
+ selected_systems = (
+ set(map(str, target_system_ids)) if target_system_ids is not None else None
+ )
+ selected_ligands = (
+ set(map(str, target_ligand_ids)) if target_ligand_ids is not None else None
+ )
+ source_to_alignment = {
+ f"holo_{backend}": path for backend, path in score_alignments.items()
+ }
+ frames: list[pd.DataFrame] = []
+ for query_entry_id, query_entry in query_entries.items():
+ if not query_entry.systems:
+ continue
+ frame = scorer.aggregate_scores(
+ query_entry_id,
+ search_db="holo",
+ data_dir=work_dir if include_shape else None,
+ source_to_aln_file=source_to_alignment,
+ target_system_ids=selected_systems,
+ target_ligand_ids=selected_ligands,
+ include_holo_protein_scores=True,
+ )
+ if frame is not None and not frame.empty:
+ frames.append(frame)
+ result = (
+ pd.concat(frames, ignore_index=True)
+ if frames
+ else pd.DataFrame(columns=PROTEIN_SIMILARITY_SCHEMA.names)
+ )
+ if not result.empty:
+ result = result.sort_values(
+ [
+ "similarity",
+ "query_system",
+ "query_ligand_id",
+ "target_system",
+ "target_ligand_id",
+ ],
+ ascending=[False, True, True, True, True],
+ ignore_index=True,
+ )
+ if output_path is not None:
+ output_path = Path(output_path)
+ output_path.parent.mkdir(exist_ok=True, parents=True)
+ result.to_parquet(output_path, index=False, compression="zstd")
+ return result
+
+
+def calculate_custom_interface_similarity_scores(
+ score_alignments: Mapping[str, Path],
+ *,
+ annotations: CustomStructureAnnotations,
+ assets: CustomScoringAssets,
+ target_interface_ids: Iterable[str] | None = None,
+ output_path: Path | None = None,
+) -> pd.DataFrame:
+ """Calculate directed protein-interface coverage from custom structures."""
+ from plinder.core.scores.reconstruct import (
+ calculate_interface_similarity_scores,
+ )
+
+ query_entry_ids = {
+ str(entry.pdb_id) for entry in annotations.entries_by_structure.values()
+ }
+ target_entries = _load_release_entry_views(
+ assets,
+ pdb_ids=_target_entry_ids(score_alignments).difference(query_entry_ids),
+ )
+ query_interfaces = {
+ interface_id: interface
+ for entry in annotations.entries_by_structure.values()
+ for interface_id, interface in entry.interfaces.items()
+ }
+ target_interfaces = {
+ interface_id: interface
+ for entry in target_entries.values()
+ for interface_id, interface in entry.interfaces.items()
+ }
+ if target_interface_ids is not None:
+ selected = set(map(str, target_interface_ids))
+ missing = selected.difference(target_interfaces)
+ if missing:
+ raise KeyError(f"unknown target interface system IDs: {sorted(missing)}")
+ target_interfaces = {
+ interface_id: target_interfaces[interface_id] for interface_id in selected
+ }
+ alignment_frames = [pd.read_parquet(path) for path in score_alignments.values()]
+ alignments = (
+ pd.concat(alignment_frames, ignore_index=True)
+ if alignment_frames
+ else pd.DataFrame()
+ )
+ result = calculate_interface_similarity_scores(
+ alignments,
+ query_interfaces=query_interfaces,
+ target_interfaces=target_interfaces,
+ )
+ if output_path is not None:
+ output_path = Path(output_path)
+ output_path.parent.mkdir(exist_ok=True, parents=True)
+ result.to_parquet(output_path, index=False, compression="zstd")
+ return result
+
+
+def score_custom_cif_files(
+ cif_files: Iterable[Path],
+ *,
+ work_dir: Path,
+ scratch_dir: Path | None = None,
+ data_dir: Path | None = None,
+ structure_mode: Literal["as_is", "pdb"] = "as_is",
+ assembly_ids: Iterable[str] | None = None,
+ ligand_smiles_dict: Mapping[str, str] | None = None,
+ ligand_ccd_code_dict: Mapping[str, str] | None = None,
+ include_ligands: bool | None = True,
+ include_interfaces: bool | None = True,
+ include_shape: bool = True,
+ interface_annotate_prodigy: bool = True,
+ search_config: CustomProteinSearchConfig | None = None,
+ backends: Iterable[str] = CIF_SEARCH_BACKENDS,
+ plinder_entry_ids: Iterable[str] | None = None,
+ threads: int = 1,
+ shape_score_threads: int = 1,
+ store_aligned_pocket_residues: bool = False,
+ include_monomers: bool = False,
+) -> CustomScoringResult:
+ """Run custom-CIF annotation, protein search, and PLINDER scoring.
+
+ Unknown component IDs such as ``LIG`` can be assigned chemistry with
+ either ``ligand_smiles_dict`` or ``ligand_ccd_code_dict``. The resulting
+ bond-aware SDFs are used as the query conformers for shape, color, and
+ SuCOS scores. Target ligand archives are first opened after a positive
+ pocket match, and each required archive shard is read at most once.
+
+ The returned object points to the written custom annotation tables,
+ backend hit tables, compact score alignments, and the final protein,
+ ligand, and/or interface score parquet files under ``work_dir``. Protein
+ scores use each PLINDER ligand pocket as the directed query and each
+ custom protein chain as a ligand-free target, so ``include_ligands=False``
+ still yields protein metrics and ``pocket_fident``. Passing ``None`` for
+ ligand or interface inclusion annotates that feature and emits its score
+ table only when the custom structures contain a proper ligand or protein
+ interface, respectively. ``plinder_entry_ids`` builds a small MMseqs target
+ from scoreable receptor and interface chains in selected release entries
+ rather than fetching the complete search database; this bounded mode
+ currently requires ``backends=("mmseqs",)``.
+ """
+ sources = tuple(Path(path) for path in cif_files)
+ if not sources:
+ raise ValueError("at least one custom mmCIF is required")
+ work_dir = Path(work_dir)
+ work_dir.mkdir(exist_ok=True, parents=True)
+ selected_plinder_entries = _plinder_entry_subset(plinder_entry_ids)
+ selected_backends = tuple(dict.fromkeys(backends))
+ if not selected_backends:
+ raise ValueError("at least one custom search backend is required")
+ requested_assemblies = (
+ tuple(str(value) for value in assembly_ids)
+ if assembly_ids is not None and not isinstance(assembly_ids, str)
+ else assembly_ids
+ )
+ annotate_ligands = include_ligands is not False
+ annotate_interfaces = include_interfaces is not False
+ annotations = annotate_custom_cif_files(
+ sources,
+ work_dir=work_dir,
+ structure_mode=structure_mode,
+ assembly_ids=requested_assemblies,
+ ligand_smiles_dict=ligand_smiles_dict,
+ ligand_ccd_code_dict=ligand_ccd_code_dict,
+ include_ligands=annotate_ligands,
+ include_interfaces=annotate_interfaces,
+ interface_annotate_prodigy=interface_annotate_prodigy,
+ data_dir=data_dir,
+ )
+ query_inputs = write_custom_query_files(
+ sources,
+ work_dir=work_dir,
+ structure_mode=structure_mode,
+ assembly_ids=requested_assemblies,
+ )
+ query_databases = create_custom_query_databases(
+ query_inputs,
+ work_dir=work_dir,
+ backends=selected_backends,
+ threads=threads,
+ )
+ assets = _resolve_workflow_assets(
+ data_dir=data_dir,
+ backends=selected_backends,
+ plinder_entry_ids=selected_plinder_entries,
+ work_dir=work_dir,
+ threads=threads,
+ include_monomers=include_monomers,
+ )
+ protein_hits = run_custom_protein_searches(
+ query_databases=query_databases,
+ assets=assets,
+ output_dir=work_dir / "protein_hits",
+ scratch_dir=(
+ Path(scratch_dir) if scratch_dir is not None else work_dir / "scratch"
+ ),
+ config=search_config,
+ backends=selected_backends,
+ threads=threads,
+ )
+ monomer_hits = run_custom_monomer_searches(
+ query_databases=query_databases,
+ assets=assets,
+ output_dir=work_dir / "monomer_hits",
+ scratch_dir=(
+ Path(scratch_dir) if scratch_dir is not None else work_dir / "scratch"
+ )
+ / "monomer",
+ config=search_config,
+ backends=selected_backends,
+ threads=threads,
+ )
+ chain_similarity_scores = write_custom_chain_similarity_scores(
+ protein_hits,
+ output_path=work_dir / "chain_similarity_scores.parquet",
+ monomer_hits=monomer_hits,
+ )
+ score_alignments = prepare_custom_score_alignments(
+ protein_hits,
+ entries_by_structure=annotations.entries_by_structure,
+ output_dir=work_dir / "score_alignments",
+ )
+ protein_score_alignments = prepare_custom_protein_score_alignments(
+ protein_hits,
+ entries_by_structure=annotations.entries_by_structure,
+ output_dir=work_dir / "protein_score_alignments",
+ )
+ protein_score_path = work_dir / "protein_scores.parquet"
+ calculate_custom_protein_similarity_scores(
+ protein_score_alignments,
+ assets=assets,
+ work_dir=work_dir / "protein_score_work",
+ output_path=protein_score_path,
+ )
+ aligned_pocket_residue_path = (
+ work_dir / "aligned_pocket_residues.parquet"
+ if store_aligned_pocket_residues
+ else None
+ )
+ if aligned_pocket_residue_path is not None:
+ write_custom_aligned_pocket_residues(
+ protein_score_alignments,
+ protein_scores=protein_score_path,
+ assets=assets,
+ output_path=aligned_pocket_residue_path,
+ )
+ has_proper_ligands = any(
+ ligand.is_proper
+ for entry in annotations.entries_by_structure.values()
+ for system in entry.systems.values()
+ for ligand in system.ligands.values()
+ )
+ score_ligands = include_ligands is True or (
+ include_ligands is None and has_proper_ligands
+ )
+ ligand_score_path = work_dir / "ligand_scores.parquet" if score_ligands else None
+ if ligand_score_path is not None:
+ calculate_custom_similarity_scores(
+ score_alignments,
+ annotations=annotations,
+ assets=assets,
+ work_dir=work_dir / "score_work",
+ include_shape=include_shape,
+ shape_score_threads=shape_score_threads,
+ data_dir=data_dir,
+ output_path=ligand_score_path,
+ )
+ has_interfaces = any(
+ entry.interfaces for entry in annotations.entries_by_structure.values()
+ )
+ score_interfaces = include_interfaces is True or (
+ include_interfaces is None and has_interfaces
+ )
+ interface_score_path = (
+ work_dir / "interface_scores.parquet" if score_interfaces else None
+ )
+ if interface_score_path is not None:
+ calculate_custom_interface_similarity_scores(
+ score_alignments,
+ annotations=annotations,
+ assets=assets,
+ output_path=interface_score_path,
+ )
+ return CustomScoringResult(
+ annotations=annotations,
+ query_inputs=query_inputs,
+ query_databases=query_databases,
+ protein_hits=protein_hits,
+ chain_similarity_scores=chain_similarity_scores,
+ score_alignments=score_alignments,
+ protein_score_alignments=protein_score_alignments,
+ protein_scores=protein_score_path,
+ aligned_pocket_residues=aligned_pocket_residue_path,
+ ligand_scores=ligand_score_path,
+ interface_scores=interface_score_path,
+ )
diff --git a/src/plinder/core/scores/entries.py b/src/plinder/core/scores/entries.py
new file mode 100644
index 000000000..c1a135792
--- /dev/null
+++ b/src/plinder/core/scores/entries.py
@@ -0,0 +1,730 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Lightweight entry/system/chain views loaded from the index parquet.
+
+Consumed by similarity scoring.
+"""
+
+from __future__ import annotations
+
+from collections import Counter, defaultdict
+from collections.abc import Iterable as IterableABC
+from dataclasses import dataclass, field
+from functools import cached_property
+from pathlib import Path
+from typing import Any, Iterable
+
+import pandas as pd
+import pyarrow.parquet as pq
+
+from plinder.core.index.query import query_table
+from plinder.core.utils.log import setup_logger
+
+LOG = setup_logger(__name__)
+
+
+@dataclass(frozen=True)
+class ChainView:
+ asym_id: str # label_asym_id (e.g. "A")
+ auth_id: str # auth_asym_id (e.g. "A")
+ length: int # SEQRES length
+ entity_id: str = ""
+ chain_type: str = "polypeptide(L)"
+ holo: bool = True
+ uniprot_ids: tuple[str, ...] = ()
+
+ @property
+ def is_polypeptide(self) -> bool:
+ return "polypeptide" in self.chain_type.lower()
+
+ @property
+ def receptor_type(self) -> str:
+ """Receptor polymer category derived from the CIF chain type."""
+ chain_type = self.chain_type.lower()
+ components = []
+ if "polypeptide" in chain_type:
+ components.append("protein")
+ if "polydeoxyribonucleotide" in chain_type:
+ components.append("dna")
+ if "polyribonucleotide" in chain_type:
+ components.append("rna")
+ return "+".join(components) or "other"
+
+
+@dataclass
+class LigandView:
+ """Ligand-level annotations needed by pairwise similarity scoring."""
+
+ id: str
+ pdb_id: str
+ system_id: str
+ instance_chain: str
+ asym_id: str
+ is_proper: bool
+ protein_chains_asym_id: list[str] # protein-only receptor instance chains
+ num_pocket_residues: int
+ num_interactions: int
+ num_unique_interactions: int
+ is_shape_comparable: bool | None = None
+ # receptor instance_chain -> {residue_number: residue_index}
+ pocket_residue_number_to_index: dict[str, dict[int, int]] = field(
+ default_factory=dict
+ )
+ # receptor instance_chain -> {residue_number: Counter[interaction_type]}
+ interactions_counter: dict[str, dict[int, Counter[str]]] = field(
+ default_factory=dict
+ )
+
+
+@dataclass
+class SystemView:
+ id: str
+ pdb_id: str
+ system_type: str
+ protein_chains_asym_id: list[str] # protein-only, e.g. ["1.A", "1.B"]
+ proper_num_pocket_residues: int
+ proper_num_interactions: int
+ proper_num_unique_interactions: int
+ receptor_type: str = "protein"
+ # instance_chain -> {residue_number: residue_index}
+ pocket_residue_number_to_index: dict[str, dict[int, int]] = field(
+ default_factory=dict
+ )
+ # instance_chain -> {residue_number: Counter[interaction_type]}
+ interactions_counter: dict[str, dict[int, Counter[str]]] = field(
+ default_factory=dict
+ )
+ ligands: dict[str, LigandView] = field(default_factory=dict)
+
+ @cached_property
+ def pocket_residue_index_to_number(self) -> dict[str, dict[int, int]]:
+ return {
+ chain: {idx: num for num, idx in mapping.items()}
+ for chain, mapping in self.pocket_residue_number_to_index.items()
+ }
+
+
+@dataclass(frozen=True)
+class InterfaceView:
+ """One unordered protein-chain interface in a biological assembly."""
+
+ id: str
+ pdb_id: str
+ biounit_id: str
+ chain_1: str
+ chain_2: str
+ chain_1_residue_number_to_index: dict[int, int]
+ chain_2_residue_number_to_index: dict[int, int]
+ num_contact_residue_pairs: int
+
+ @property
+ def chains(self) -> tuple[str, str]:
+ return self.chain_1, self.chain_2
+
+ @property
+ def residue_number_to_index(self) -> dict[str, dict[int, int]]:
+ return {
+ self.chain_1: self.chain_1_residue_number_to_index,
+ self.chain_2: self.chain_2_residue_number_to_index,
+ }
+
+
+@dataclass
+class EntryView:
+ pdb_id: str
+ chains: dict[str, ChainView] # by asym_id
+ systems: dict[str, SystemView] # by system_id
+ author_to_asym: dict[str, str]
+ interfaces: dict[str, InterfaceView] = field(default_factory=dict)
+
+ @cached_property
+ def pocket_index_to_number_per_chain(self) -> dict[str, dict[int, int]]:
+ """Union of pocket (residue_index โ residue_number) maps across every
+ system / instance that touches each chain. Used by Scorer's map_row
+ to translate foldseek's 0-based residue indices into PDB residue
+ numbers so downstream scoring is source-agnostic."""
+ result: dict[str, dict[int, int]] = {}
+ for system in self.systems.values():
+ for instance_chain, n2i in system.pocket_residue_number_to_index.items():
+ asym = instance_chain.split(".", 1)[1]
+ bucket = result.setdefault(asym, {})
+ for num, idx in n2i.items():
+ bucket[idx] = num
+ return result
+
+ @cached_property
+ def selected_index_to_number_per_chain(self) -> dict[str, dict[int, int]]:
+ """Union of ligand-pocket and protein-interface residue mappings.
+
+ Compact mapped alignments retain only these selected query positions.
+ This union supports exact ligand pocket and interface reconstruction
+ from one release artifact without storing full residue alignments.
+ """
+ result = {
+ asym_id: dict(index_to_number)
+ for asym_id, index_to_number in self.pocket_index_to_number_per_chain.items()
+ }
+ for interface in self.interfaces.values():
+ for (
+ instance_chain,
+ number_to_index,
+ ) in interface.residue_number_to_index.items():
+ asym_id = instance_chain.split(".", maxsplit=1)[-1]
+ bucket = result.setdefault(asym_id, {})
+ for number, index in number_to_index.items():
+ previous = bucket.setdefault(index, number)
+ if previous != number:
+ raise ValueError(
+ f"conflicting residue number for {self.pdb_id} "
+ f"chain {asym_id} index {index}: {previous} != {number}"
+ )
+ return result
+
+ def chains_for_alignment(self, chain_type: str, aln_type: str) -> list[str]:
+ if chain_type not in {"apo", "holo", "pred"}:
+ raise ValueError(f"unknown chain_type={chain_type!r}")
+ if aln_type not in {"foldseek", "mmseqs"}:
+ raise ValueError(f"unknown aln_type={aln_type!r}")
+
+ if chain_type == "holo":
+ receptor_asym_ids = {
+ instance_chain.split(".", 1)[1]
+ for system in self.systems.values()
+ if system.system_type == "holo"
+ for instance_chain in system.protein_chains_asym_id
+ }
+ receptor_asym_ids.update(
+ instance_chain.split(".", maxsplit=1)[-1]
+ for interface in self.interfaces.values()
+ for instance_chain in interface.chains
+ )
+ chains = sorted(
+ self.chains[asym].auth_id
+ for asym in receptor_asym_ids
+ if asym in self.chains and self.chains[asym].is_polypeptide
+ )
+ elif chain_type == "apo":
+ holo_entities = {
+ chain.entity_id for chain in self.chains.values() if chain.holo
+ }
+ chains = sorted(
+ chain.auth_id
+ for chain in self.chains.values()
+ if not chain.holo
+ and chain.entity_id not in holo_entities
+ and chain.is_polypeptide
+ )
+ else:
+ uniprot_ids = sorted(
+ {
+ uniprot_id
+ for chain in self.chains.values()
+ if chain.holo and chain.is_polypeptide
+ for uniprot_id in chain.uniprot_ids
+ }
+ )
+ if aln_type == "foldseek":
+ return [f"AF-{uniprot_id}-F1-model_v4_A" for uniprot_id in uniprot_ids]
+ return uniprot_ids
+
+ if aln_type == "foldseek":
+ return [f"pdb_0000{self.pdb_id}_xyz-enrich_{c}" for c in chains]
+ return [f"{self.pdb_id}_{c}" for c in chains]
+
+
+def _parse_neighboring_residue(s: str) -> tuple[str, int, int]:
+ """Parse the label-asym residue coordinates from an encoded pocket row."""
+ parts = s.split("_")
+ # instance_chain has a dot ("1.A") so it doesn't collide with the _ separator
+ return parts[0], int(parts[1]), int(parts[2])
+
+
+def _parse_interaction(s: str) -> tuple[str, int, str]:
+ """Parse ``{instance_chain}_{res_number}_{interaction_type}`` strings.
+
+ interaction_type contains underscores (e.g. ``type:hydrogen_bonds__...``),
+ so use maxsplit=2.
+ """
+ inst, rnum, itype = s.split("_", 2)
+ return inst, int(rnum), itype
+
+
+def _as_list(value: Any) -> list[Any]:
+ """Convert an array-valued cell (numpy array / None / NaN) to a list."""
+ if value is None:
+ return []
+ if isinstance(value, str):
+ return [value]
+ if isinstance(value, IterableABC):
+ return list(value)
+ return []
+
+
+def _entry_chains_from_rows(
+ entry_rows: pd.DataFrame,
+ chain_rows: pd.DataFrame | None = None,
+) -> tuple[dict[str, ChainView], dict[str, str]]:
+ """Build chain views from the chain table or holo fallback."""
+ chains: dict[str, ChainView] = {}
+ author_to_asym: dict[str, str] = {}
+ if chain_rows is not None:
+ for row in chain_rows.itertuples(index=False):
+ chain = ChainView(
+ asym_id=str(row.chain_asym_id),
+ auth_id=str(row.chain_auth_id),
+ entity_id=str(row.chain_entity_id),
+ chain_type=str(row.chain_type),
+ length=int(row.chain_length),
+ holo=bool(row.chain_is_holo),
+ uniprot_ids=tuple(
+ str(value) for value in _as_list(row.chain_uniprot_ids)
+ ),
+ )
+ chains[chain.asym_id] = chain
+ if chain.is_polypeptide:
+ author_to_asym[chain.auth_id] = chain.asym_id
+ return chains, author_to_asym
+
+ # Compatibility for in-memory test/custom dataframes that only contain
+ # system receptor columns. Such rows can reproduce holo selection but do
+ # not contain enough information to identify apo or predicted chains.
+ for _, row in entry_rows.iterrows():
+ asyms = _as_list(row["system_protein_chains_asym_id"])
+ auths = _as_list(row["system_protein_chains_auth_id"])
+ lengths = _as_list(row["system_protein_chains_length"])
+ for inst_chain, auth, length in zip(asyms, auths, lengths):
+ asym = str(inst_chain).split(".", 1)[1]
+ if asym not in chains:
+ chains[asym] = ChainView(
+ asym_id=asym,
+ auth_id=str(auth),
+ length=int(length),
+ )
+ author_to_asym[str(auth)] = asym
+ return chains, author_to_asym
+
+
+def _protein_instance_chains(
+ instance_chains: Iterable[str], chains: dict[str, ChainView]
+) -> list[str]:
+ """Filter receptor instance chains to polypeptides known by the chain index."""
+ result = []
+ for instance_chain in instance_chains:
+ value = str(instance_chain)
+ asym_id = value.split(".", maxsplit=1)[-1]
+ chain = chains.get(asym_id)
+ if chain is not None and chain.is_polypeptide:
+ result.append(value)
+ return sorted(set(result))
+
+
+def _make_ligand_view(
+ row: pd.Series,
+ *,
+ pdb_id: str,
+ system_id: str,
+ chains: dict[str, ChainView],
+) -> LigandView:
+ """Build a ligand view from one published-index row."""
+ instance_chain = str(row["ligand_instance_chain"])
+ asym_id = str(row["ligand_asym_id"])
+ ligand_id = str(row["ligand_id"])
+ pocket_n2i: dict[str, dict[int, int]] = defaultdict(dict)
+ interactions: dict[str, dict[int, Counter[str]]] = defaultdict(
+ lambda: defaultdict(Counter)
+ )
+ protein_chains = _protein_instance_chains(
+ _as_list(row["ligand_protein_chains_asym_id"]), chains
+ )
+ protein_chain_set = set(protein_chains)
+ for value in _as_list(row["ligand_neighboring_residues"]):
+ inst, rnum, ridx = _parse_neighboring_residue(value)
+ if inst in protein_chain_set:
+ pocket_n2i[inst][rnum] = ridx
+ for value in _as_list(row["ligand_interactions"]):
+ inst, rnum, itype = _parse_interaction(value)
+ if inst in protein_chain_set:
+ interactions[inst][rnum][itype] += 1
+ num_pocket_residues = sum(len(residues) for residues in pocket_n2i.values())
+ num_interactions = sum(
+ sum(counter.values())
+ for residues in interactions.values()
+ for counter in residues.values()
+ )
+ num_unique_interactions = sum(
+ len(counter)
+ for residues in interactions.values()
+ for counter in residues.values()
+ )
+ comparability = row.get("ligand_is_shape_comparable")
+ is_shape_comparable = None if pd.isna(comparability) else bool(comparability)
+ return LigandView(
+ id=ligand_id,
+ pdb_id=pdb_id,
+ system_id=system_id,
+ instance_chain=instance_chain,
+ asym_id=asym_id,
+ is_proper=bool(row["ligand_is_proper"]),
+ protein_chains_asym_id=protein_chains,
+ num_pocket_residues=num_pocket_residues,
+ num_interactions=num_interactions,
+ num_unique_interactions=num_unique_interactions,
+ is_shape_comparable=is_shape_comparable,
+ pocket_residue_number_to_index={k: dict(v) for k, v in pocket_n2i.items()},
+ interactions_counter={
+ k: {r: Counter(c) for r, c in v.items()} for k, v in interactions.items()
+ },
+ )
+
+
+def _make_interface_view(row: pd.Series, *, pdb_id: str) -> InterfaceView:
+ """Build a protein-interface view from one annotation row."""
+ chain_1_numbers = [
+ int(value) for value in _as_list(row["interface_chain_1_residue_numbers"])
+ ]
+ chain_1_indices = [
+ int(value) for value in _as_list(row["interface_chain_1_residue_indices"])
+ ]
+ chain_2_numbers = [
+ int(value) for value in _as_list(row["interface_chain_2_residue_numbers"])
+ ]
+ chain_2_indices = [
+ int(value) for value in _as_list(row["interface_chain_2_residue_indices"])
+ ]
+ if len(chain_1_numbers) != len(chain_1_indices) or len(chain_2_numbers) != len(
+ chain_2_indices
+ ):
+ raise ValueError(
+ f"interface residue mapping lengths differ for {row['system_id']}"
+ )
+ return InterfaceView(
+ id=str(row["system_id"]),
+ pdb_id=pdb_id,
+ biounit_id=str(row["system_biounit_id"]),
+ chain_1=str(row["interface_chain_1"]),
+ chain_2=str(row["interface_chain_2"]),
+ chain_1_residue_number_to_index=dict(zip(chain_1_numbers, chain_1_indices)),
+ chain_2_residue_number_to_index=dict(zip(chain_2_numbers, chain_2_indices)),
+ num_contact_residue_pairs=int(row["interface_num_contact_residue_pairs"]),
+ )
+
+
+def entry_views_from_df(
+ df: pd.DataFrame,
+ *,
+ entry_chains: pd.DataFrame | None = None,
+ interface_annotations: pd.DataFrame | None = None,
+) -> dict[str, EntryView]:
+ """Build :class:`EntryView` objects from any DataFrame shaped like the
+ published annotation parquet โ i.e. one row per
+ ``(entry, system, ligand)`` triple. ``interface_annotations`` supplies the
+ parallel one-row-per-protein-interface table and permits interface-only
+ entries. Pass the one-row-per-chain table to retain receptor
+ types and apo/predicted alignment metadata.
+ Without it, only protein-only holo chains present on system rows can be
+ reconstructed. Annotation-only mixed or nucleic-acid receptors cannot be
+ reconstructed because the system-level receptor type cannot be assigned
+ to individual chains unambiguously.
+
+ Source-agnostic: works equally on the published parquet read via
+ :func:`load_entry_views`, a locally-built parquet, or a freshly
+ constructed DataFrame from in-memory ``Entry`` objects
+ (``pd.concat([e.to_df() for e in entries.values()])``).
+ """
+ interface_annotations = (
+ interface_annotations
+ if interface_annotations is not None
+ else pd.DataFrame(columns=["entry_pdb_id"])
+ )
+ pdb_ids = list(
+ dict.fromkeys(
+ [str(value) for value in df.get("entry_pdb_id", [])]
+ + [str(value) for value in interface_annotations.get("entry_pdb_id", [])]
+ + (
+ [str(value) for value in entry_chains.get("entry_pdb_id", [])]
+ if entry_chains is not None
+ else []
+ )
+ )
+ )
+ entry_groups = {
+ str(pdb_id): rows
+ for pdb_id, rows in df.groupby(df["entry_pdb_id"].astype(str), sort=False)
+ }
+ interface_groups = {
+ str(pdb_id): rows
+ for pdb_id, rows in interface_annotations.groupby(
+ interface_annotations["entry_pdb_id"].astype(str), sort=False
+ )
+ }
+ chain_groups = (
+ {
+ str(pdb_id): rows
+ for pdb_id, rows in entry_chains.groupby(
+ entry_chains["entry_pdb_id"].astype(str), sort=False
+ )
+ }
+ if entry_chains is not None
+ else {}
+ )
+ views: dict[str, EntryView] = {}
+ for pdb_id in pdb_ids:
+ entry_rows = entry_groups.get(pdb_id, df.iloc[:0])
+ interface_rows = interface_groups.get(pdb_id, interface_annotations.iloc[:0])
+ chain_rows = None
+ if entry_chains is not None:
+ chain_rows = chain_groups.get(pdb_id, entry_chains.iloc[:0])
+ if chain_rows.empty:
+ receptor_types = {
+ str(value)
+ for value in entry_rows.get(
+ "system_receptor_type", pd.Series(dtype=str)
+ )
+ }
+ if (
+ not interface_rows.empty
+ or not receptor_types
+ or any(
+ "protein" in receptor_type.split("+")
+ for receptor_type in receptor_types
+ )
+ ):
+ raise ValueError(f"No protein chain metadata found for {pdb_id}")
+ else:
+ receptor_types = {
+ str(value)
+ for value in entry_rows.get(
+ "system_receptor_type", pd.Series(dtype=str)
+ )
+ if pd.notna(value)
+ }
+ unsupported_types = sorted(
+ receptor_type
+ for receptor_type in receptor_types
+ if receptor_type != "protein"
+ )
+ if unsupported_types:
+ raise ValueError(
+ f"entry_chains is required for {pdb_id}: annotation-only "
+ "annotations cannot assign receptor chain types for "
+ f"{unsupported_types}"
+ )
+ if "system_id" not in entry_rows.columns:
+ entry_rows = entry_rows.assign(system_id=pd.Series(dtype="string"))
+ chains, author_to_asym = _entry_chains_from_rows(entry_rows, chain_rows)
+
+ systems: dict[str, SystemView] = {}
+ for system_id, sys_rows in entry_rows.groupby("system_id", sort=False):
+ first = sys_rows.iloc[0]
+ ligands: dict[str, LigandView] = {}
+ for _, row in sys_rows.iterrows():
+ ligand = _make_ligand_view(
+ row,
+ pdb_id=str(pdb_id),
+ system_id=str(system_id),
+ chains=chains,
+ )
+ ligands[ligand.instance_chain] = ligand
+ pocket_n2i: dict[str, dict[int, int]] = defaultdict(dict)
+ interactions: dict[str, dict[int, Counter[str]]] = defaultdict(
+ lambda: defaultdict(Counter)
+ )
+ proper_ligands = [ligand for ligand in ligands.values() if ligand.is_proper]
+ for ligand in proper_ligands:
+ for (
+ instance_chain,
+ pocket_residues,
+ ) in ligand.pocket_residue_number_to_index.items():
+ pocket_n2i[instance_chain].update(pocket_residues)
+ for (
+ instance_chain,
+ interaction_residues,
+ ) in ligand.interactions_counter.items():
+ for residue_number, counter in interaction_residues.items():
+ interactions[instance_chain][residue_number].update(counter)
+ systems[system_id] = SystemView(
+ id=system_id,
+ pdb_id=str(pdb_id),
+ system_type=first["system_type"],
+ protein_chains_asym_id=_protein_instance_chains(
+ _as_list(first["system_protein_chains_asym_id"]), chains
+ ),
+ proper_num_pocket_residues=sum(
+ len(residues) for residues in pocket_n2i.values()
+ ),
+ proper_num_interactions=sum(
+ ligand.num_interactions for ligand in proper_ligands
+ ),
+ proper_num_unique_interactions=sum(
+ ligand.num_unique_interactions for ligand in proper_ligands
+ ),
+ receptor_type=str(first.get("system_receptor_type", "protein")),
+ pocket_residue_number_to_index={
+ k: dict(v) for k, v in pocket_n2i.items()
+ },
+ interactions_counter={
+ k: {r: Counter(c) for r, c in v.items()}
+ for k, v in interactions.items()
+ },
+ ligands=ligands,
+ )
+ interfaces: dict[str, InterfaceView] = {}
+ for _, row in interface_rows.iterrows():
+ interface = _make_interface_view(row, pdb_id=pdb_id)
+ interfaces[interface.id] = interface
+ for interface in interfaces.values():
+ missing_chains = {
+ chain.split(".", maxsplit=1)[-1]
+ for chain in interface.chains
+ if chain.split(".", maxsplit=1)[-1] not in chains
+ }
+ if missing_chains:
+ raise ValueError(
+ f"interface {interface.id} references missing chains: "
+ f"{sorted(missing_chains)}"
+ )
+ views[pdb_id] = EntryView(
+ pdb_id=pdb_id,
+ chains=chains,
+ systems=systems,
+ author_to_asym=author_to_asym,
+ interfaces=interfaces,
+ )
+ return views
+
+
+def load_entry_views(
+ *,
+ pdb_ids: Iterable[str],
+ data_dir: Path | None = None,
+ include_interfaces: bool = True,
+) -> dict[str, EntryView]:
+ """Load annotation and chain rows for the requested entries.
+
+ ``data_dir`` selects a local ingest/release root. If omitted, the ligand,
+ interface, and chain tables are resolved from the configured PLINDER
+ release cache. Production callers should use this loader so all rows come
+ from the same release. Direct/custom DataFrames can use
+ :func:`entry_views_from_df` instead.
+ """
+ pdb_ids = sorted(set(pdb_ids))
+ if not pdb_ids:
+ return {}
+
+ from plinder.core.release import PlinderRelease
+
+ release = PlinderRelease(data_dir)
+ annotation_columns = [
+ "entry_pdb_id",
+ "system_id",
+ "system_type",
+ "system_receptor_type",
+ "system_protein_chains_asym_id",
+ "ligand_id",
+ "ligand_instance_chain",
+ "ligand_asym_id",
+ "ligand_is_proper",
+ "ligand_protein_chains_asym_id",
+ "ligand_neighboring_residues",
+ "ligand_interactions",
+ ]
+ if data_dir is None:
+ df = query_table(
+ "annotation",
+ columns=[*annotation_columns, "ligand_is_shape_comparable"],
+ filters=[("entry_pdb_id", "in", pdb_ids)],
+ release=release,
+ )
+ chain_path = release.fetch("entry_chains")
+ interface_path = (
+ release.fetch("interface_annotations") if include_interfaces else None
+ )
+ else:
+ annotation_path = release.path("annotation_table")
+ if not annotation_path.is_file():
+ raise FileNotFoundError(f"missing annotation index: {annotation_path}")
+ if "ligand_is_shape_comparable" in pq.read_schema(annotation_path).names:
+ annotation_columns.append("ligand_is_shape_comparable")
+ df = pd.read_parquet(
+ annotation_path,
+ columns=annotation_columns,
+ filters=[("entry_pdb_id", "in", pdb_ids)],
+ )
+ chain_path = release.path("entry_chains")
+ interface_path = (
+ release.path("interface_annotations") if include_interfaces else None
+ )
+
+ if not chain_path.is_file():
+ raise FileNotFoundError(f"missing entry chain index: {chain_path}")
+ if interface_path is not None and not interface_path.is_file():
+ raise FileNotFoundError(f"missing interface annotation index: {interface_path}")
+ entry_chains = pd.read_parquet(
+ chain_path,
+ filters=[("entry_pdb_id", "in", pdb_ids)],
+ )
+ interfaces = (
+ pd.read_parquet(
+ interface_path,
+ filters=[("entry_pdb_id", "in", pdb_ids)],
+ )
+ if interface_path is not None
+ else pd.DataFrame(columns=["entry_pdb_id"])
+ )
+ LOG.info(
+ "load_entry_views: %s ligand rows and %s interface rows for %s pdb_ids",
+ len(df),
+ len(interfaces),
+ len(pdb_ids),
+ )
+ return entry_views_from_df(
+ df,
+ entry_chains=entry_chains,
+ interface_annotations=interfaces,
+ )
+
+
+def load_alignment_entry_views(
+ *, lookup_path: Path, pdb_ids: Iterable[str]
+) -> dict[str, EntryView]:
+ """Load compact chain and selected-residue maps for alignment mapping."""
+ selected = sorted(set(pdb_ids))
+ if not selected:
+ return {}
+ frame = pd.read_parquet(
+ lookup_path,
+ filters=[("entry_pdb_id", "in", selected)],
+ )
+ views: dict[str, EntryView] = {}
+ for pdb_id, rows in frame.groupby("entry_pdb_id", sort=False):
+ author_to_asym: dict[str, str] = {}
+ pocket_n2i: dict[str, dict[int, int]] = {}
+ for row in rows.itertuples(index=False):
+ asym_id = str(row.chain_asym_id)
+ author_to_asym[str(row.chain_auth_id)] = asym_id
+ numbers = [int(value) for value in _as_list(row.selected_residue_numbers)]
+ indices = [int(value) for value in _as_list(row.selected_residue_indices)]
+ if numbers:
+ pocket_n2i[f"1.{asym_id}"] = dict(zip(numbers, indices))
+ systems = {}
+ if pocket_n2i:
+ systems["alignment"] = SystemView(
+ id="alignment",
+ pdb_id=str(pdb_id),
+ system_type="holo",
+ protein_chains_asym_id=sorted(pocket_n2i),
+ proper_num_pocket_residues=sum(map(len, pocket_n2i.values())),
+ proper_num_interactions=0,
+ proper_num_unique_interactions=0,
+ pocket_residue_number_to_index=pocket_n2i,
+ )
+ views[str(pdb_id)] = EntryView(
+ pdb_id=str(pdb_id),
+ chains={},
+ systems=systems,
+ author_to_asym=author_to_asym,
+ )
+ LOG.info(
+ f"load_alignment_entry_views: {len(frame)} chains for {len(views)} pdb_ids"
+ )
+ return views
diff --git a/src/plinder/core/scores/index.py b/src/plinder/core/scores/index.py
deleted file mode 100644
index 2206bba39..000000000
--- a/src/plinder/core/scores/index.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-import pandas as pd
-from duckdb import sql
-
-from plinder.core.scores.query import FILTERS, make_query
-from plinder.core.utils import cpl
-from plinder.core.utils.config import get_config
-from plinder.core.utils.log import setup_logger
-
-LOG = setup_logger(__name__)
-
-
-def query_index(
- *,
- columns: list[str] | None = None,
- splits: list[str] | None = None,
- filters: FILTERS = None,
-) -> pd.DataFrame:
- """
- Query the index database.
-
- Parameters
- ----------
- columns : list[str], default=None
- the columns to return
- filters : list[tuple[str, str, str]]
- the filters to apply
-
- Returns
- -------
- df : pd.DataFrame | None
- the index results
- """
- cfg = get_config()
- dataset = cpl.get_plinder_path(rel=f"{cfg.data.index}/{cfg.data.index_file}")
- if columns is None:
- columns = ["system_id", "entry_pdb_id"]
- if "system_id" not in columns and "*" not in columns:
- columns = ["system_id"] + columns
- # START patch-1
- # TODO-1: remove this patch after binding_affinity is fixed
- if "system_has_binding_affinity" in columns or "ligand_binding_affinity" in columns:
- raise ValueError(
- "columns containing binding_affinity have been removed until bugfix"
- "see: https://github.com/plinder-org/plinder/issues/94"
- )
- # END patch-1
- query = make_query(
- dataset=dataset,
- columns=columns,
- filters=filters,
- allow_no_filters=True,
- )
- assert query is not None
- df = sql(query).to_df()
- # START patch-2
- # TODO-2: remove this patch after entry_release_date is fixed
- if "entry_release_date" in df.columns:
- from importlib import resources
-
- df_fixed_time = pd.read_csv(
- resources.files("plinder") / "data/utils/annotations/static_files/dates.csv"
- )[["entry_release_date", "entry_pdb_id"]]
- if "entry_pdb_id" not in df.columns:
- # hacky fix - assuming standard pdb names - to be removed
- df["entry_pdb_id"] = df.system_id.apply(lambda x: x[:4])
- df = df.drop("entry_release_date", axis=1).merge(
- df_fixed_time, on="entry_pdb_id"
- )
- # END patch-2
- if splits is None:
- splits = ["train", "val"]
- split = cpl.get_plinder_path(rel=f"{cfg.data.splits}/{cfg.data.split_file}")
- split_df = pd.read_parquet(split)
- split_dict = dict(zip(split_df["system_id"], split_df["split"]))
- df["split"] = df["system_id"].map(lambda x: split_dict.get(x, "unassigned"))
- if "*" not in splits:
- df = df[df["split"].isin(splits)].reset_index(drop=True)
- return df
diff --git a/src/plinder/core/scores/interface.py b/src/plinder/core/scores/interface.py
new file mode 100644
index 000000000..b0174ace5
--- /dev/null
+++ b/src/plinder/core/scores/interface.py
@@ -0,0 +1,38 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Query complete protein-interface similarities."""
+
+from __future__ import annotations
+
+import pandas as pd
+
+from plinder.core.release import PlinderRelease
+from plinder.core.scores.query import Filters, read_score_table
+from plinder.core.utils.dec import timeit
+
+
+@timeit
+def query_interface_similarity(
+ *,
+ columns: list[str] | None = None,
+ filters: Filters = None,
+ release: PlinderRelease | None = None,
+) -> pd.DataFrame:
+ """Query complete directed protein-interface similarities."""
+ dataset = (release or PlinderRelease()).fetch("interface_similarity_scores")
+ return read_score_table(dataset, columns=columns, filters=filters)
+
+
+@timeit
+def query_half_interface_similarity(
+ *,
+ columns: list[str] | None = None,
+ filters: Filters = None,
+ release: PlinderRelease | None = None,
+) -> pd.DataFrame:
+ """Query directed coverage between individual interface sides."""
+ dataset = (release or PlinderRelease()).fetch("interface_half_similarity_scores")
+ return read_score_table(dataset, columns=columns, filters=filters)
+
+
+__all__ = ["query_interface_similarity", "query_half_interface_similarity"]
diff --git a/src/plinder/core/scores/ligand.py b/src/plinder/core/scores/ligand.py
index 26dc89a73..75decfdb2 100644
--- a/src/plinder/core/scores/ligand.py
+++ b/src/plinder/core/scores/ligand.py
@@ -2,28 +2,33 @@
# Distributed under the terms of the Apache License 2.0
from __future__ import annotations
+from collections.abc import Iterable
+
import pandas as pd
-from duckdb import sql
-from plinder.core.scores.query import FILTER, FILTERS, make_query
-from plinder.core.utils import cpl
-from plinder.core.utils.config import get_config
+from plinder.core.index.query import query_table
+from plinder.core.release import PlinderRelease
+from plinder.core.scores.query import Filter, Filters, read_score_table
from plinder.core.utils.dec import timeit
-from plinder.core.utils.log import setup_logger
-from plinder.core.utils.schemas import TANIMOTO_SCORE_SCHEMA
-LOG = setup_logger(__name__)
+
+def _ligand_ids(values: Iterable[int | str]) -> set[int]:
+ if isinstance(values, (str, bytes)):
+ raise TypeError("ligand IDs must be provided as a collection")
+ try:
+ return {int(value) for value in values}
+ except (TypeError, ValueError) as exc:
+ raise ValueError("ligand IDs must be integers") from exc
@timeit
def query_ligand_similarity(
*,
columns: list[str] | None = None,
- filters: FILTERS = None,
-) -> pd.DataFrame | None:
- """
- Query the ligand similarity database
- and return the results.
+ filters: Filters = None,
+ release: PlinderRelease | None = None,
+) -> pd.DataFrame:
+ """Query complete directed ligand-pair similarities.
Parameters
----------
@@ -31,50 +36,65 @@ def query_ligand_similarity(
the columns to return
filters : list[tuple[str, str, str | set[str]]]
the filters to apply
+ release : PlinderRelease | None
+ Explicit local release, or the configured release when omitted.
Returns
-------
- df : pd.DataFrame | None
- the protein similarity results
+ df : pd.DataFrame
+ The ligand similarity results.
"""
- cfg = get_config()
- dataset = cpl.get_plinder_path(rel=cfg.data.ligand_scores)
- query = make_query(
- schema=TANIMOTO_SCORE_SCHEMA,
- dataset=dataset,
- filters=filters,
+ dataset = (release or PlinderRelease()).fetch("ligand_similarity_scores")
+ return read_score_table(
+ dataset,
columns=columns,
+ filters=filters,
)
- if query is None:
- LOG.warning(
- "try minimally passing filters=[('tanimoto_similarity_max', '>', 0.5)]"
- )
- return None
- return sql(query).to_df()
+
+@timeit
+def query_ligand_chemical_similarity(
+ *,
+ columns: list[str] | None = None,
+ filters: Filters = None,
+ release: PlinderRelease | None = None,
+) -> pd.DataFrame:
+ """Query ECFP4 Tanimoto similarities between canonical ligand SMILES."""
+ dataset = (release or PlinderRelease()).fetch("ligand_scores")
+ return read_score_table(dataset, columns=columns, filters=filters)
@timeit
-def map_cross_similarity(
- df: pd.DataFrame, target_ligands: set[str], metric: str
+def _map_cross_chemical_similarity(
+ df: pd.DataFrame,
+ target_ligands: set[int],
+ metric: str,
+ release: PlinderRelease | None,
) -> pd.DataFrame:
- updated_query_ligands = []
- for q, t in zip(df["query_ligand_id"], df["target_ligand_id"]):
- if t in target_ligands:
- updated_query_ligands.append(t)
- else:
- updated_query_ligands.append(q)
- df["updated_query_ligand_id"] = updated_query_ligands
- idx = df.groupby("updated_query_ligand_id")["tanimoto_similarity_max"].idxmax()
+ if df.empty:
+ return pd.DataFrame(
+ {
+ "system_id": pd.Series(dtype="object"),
+ metric: pd.Series(dtype="float64"),
+ }
+ )
+ target_is_requested = df["target_ligand_id"].isin(target_ligands)
+ df["updated_query_ligand_id"] = df["target_ligand_id"].where(
+ target_is_requested, df["query_ligand_id"]
+ )
+ idx = df.groupby("updated_query_ligand_id")[metric].idxmax()
df = df.loc[idx]
- cfg = get_config()
- dataset = cpl.get_plinder_path(
- rel=f"{cfg.data.fingerprints}/{cfg.data.fingerprint_file}"
+ ligand_ids = set(df["query_ligand_id"].astype(int))
+ ligand_occurrences = query_table(
+ "annotation",
+ columns=["system_id", "ligand_smiles_id"],
+ filters=[("ligand_smiles_id", "in", ligand_ids)],
+ release=release,
)
- ligands_per_system = pd.read_parquet(dataset)
+ id_column = "ligand_smiles_id"
ligand_to_system: dict[int, set[str]] = {}
- for ligand_id, group in ligands_per_system.groupby("number_id_by_inchikeys"):
+ for ligand_id, group in ligand_occurrences.groupby(id_column):
ligand_to_system[int(ligand_id)] = set(group["system_id"])
df["query_system"] = df["query_ligand_id"].map(ligand_to_system)
return (
@@ -90,11 +110,12 @@ def map_cross_similarity(
@timeit
-def cross_similarity(
+def cross_ligand_chemical_similarity(
*,
- query_ligands: set[str],
- target_ligands: set[str],
- metric: str = "tanimoto_similarity_max",
+ query_ligands: Iterable[int | str],
+ target_ligands: Iterable[int | str],
+ metric: str | None = None,
+ release: PlinderRelease | None = None,
) -> pd.DataFrame:
"""
Query the ligand similarity database for
@@ -103,34 +124,40 @@ def cross_similarity(
Parameters
----------
- query_ligands : set[str]
- the set of query ligands
- target_ligands : set[str]
- the set of target ligands
+ query_ligands : Iterable[int | str]
+ The query ligand IDs.
+ target_ligands : Iterable[int | str]
+ The target ligand IDs.
Returns
-------
df : pd.DataFrame
the cross similarity results
"""
- cfg = get_config()
- dataset = cpl.get_plinder_path(rel=cfg.data.ligand_scores)
- filters = [
+ query_ids = _ligand_ids(query_ligands)
+ target_ids = _ligand_ids(target_ligands)
+ dataset = (release or PlinderRelease()).fetch("ligand_scores")
+ if metric is None:
+ metric = "tanimoto_similarity_ecfp4_1024"
+ filters: list[list[Filter]] = [
[
- FILTER(("query_ligand_id", "in", query_ligands)),
- FILTER(("target_ligand_id", "in", target_ligands)),
+ ("query_ligand_id", "in", query_ids),
+ ("target_ligand_id", "in", target_ids),
],
[
- FILTER(("query_ligand_id", "in", target_ligands)),
- FILTER(("target_ligand_id", "in", query_ligands)),
+ ("query_ligand_id", "in", target_ids),
+ ("target_ligand_id", "in", query_ids),
],
]
- columns = ["query_ligand_id", "target_ligand_id", "tanimoto_similarity_max"]
- query = make_query(
- schema=TANIMOTO_SCORE_SCHEMA,
- dataset=dataset,
+ columns = ["query_ligand_id", "target_ligand_id", metric]
+ similarities = read_score_table(
+ dataset,
columns=columns,
filters=filters,
)
- assert query is not None
- return map_cross_similarity(sql(query).to_df(), target_ligands, metric)
+ return _map_cross_chemical_similarity(
+ similarities,
+ target_ids,
+ metric,
+ release,
+ )
diff --git a/src/plinder/core/scores/links.py b/src/plinder/core/scores/links.py
deleted file mode 100644
index 99adfd798..000000000
--- a/src/plinder/core/scores/links.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-from pathlib import Path
-
-import pandas as pd
-from duckdb import sql
-
-from plinder.core.scores.query import FILTERS, make_query
-from plinder.core.utils import cpl
-from plinder.core.utils.config import get_config
-from plinder.core.utils.dec import timeit
-from plinder.core.utils.log import setup_logger
-
-LOG = setup_logger(__name__)
-
-
-@timeit
-def query_links(
- *,
- columns: list[str] | None = None,
- filters: FILTERS = None,
-) -> pd.DataFrame:
- """
- Query the linked systems dataset
-
- Parameters
- ----------
- columns : list[str], default=None
- the columns to return
- filters : list[tuple[str, str, str]]
- the filters to apply
-
- Returns
- -------
- df : pd.DataFrame
- the linked systems results
- """
- cfg = get_config()
- dataset = cpl.get_plinder_path(rel=cfg.data.links)
- new = any((path.parent.stem == "kind=apo" for path in dataset.rglob("*.parquet")))
- if (dataset / "apo_links.parquet").is_file():
- LOG.warning("found old apo links, removing")
- (dataset / "apo_links.parquet").unlink()
- if (dataset / "pred_links.parquet").is_file():
- LOG.warning("found old pred links, removing")
- (dataset / "pred_links.parquet").unlink()
- if not new and columns and "filename" not in columns:
- # bugfix: necessary for determining the "kind" below
- columns.append("filename")
- elif columns and "kind" not in columns:
- columns.append("kind")
- query = make_query(
- dataset=dataset,
- filters=filters,
- nested=new,
- columns=columns or ["*"],
- allow_no_filters=True,
- include_filename=not new,
- )
- assert query is not None
- df = sql(query).to_df()
- if not new:
- df["kind"] = df["filename"].apply(lambda x: Path(x).stem.split("_links")[0])
- df.drop(columns=["filename"], inplace=True)
- return df
diff --git a/src/plinder/core/scores/mapping.py b/src/plinder/core/scores/mapping.py
new file mode 100644
index 000000000..dcccb2abb
--- /dev/null
+++ b/src/plinder/core/scores/mapping.py
@@ -0,0 +1,202 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Compact residue mappings shared by search and score reconstruction."""
+
+from __future__ import annotations
+
+import re
+from bisect import bisect_left
+from collections.abc import Iterable
+from pathlib import Path
+
+import pandas as pd
+
+
+def cigar_alignment_sql(path: Path, chain_lookup: Path) -> str:
+ """DuckDB relation recovering sparse residue positions without a Python UDF."""
+ source = str(path).replace("'", "''")
+ lookup = str(chain_lookup).replace("'", "''")
+ return f"""WITH native AS (
+ SELECT a AS original,
+ CASE WHEN a.source='mmseqs' THEN q.selected_residue_numbers
+ ELSE list_transform(q.selected_residue_indices, i -> i+1) END AS qnative,
+ coalesce(CASE WHEN a.source='mmseqs' THEN t.selected_residue_numbers
+ ELSE list_transform(t.selected_residue_indices, i -> i+1) END, []) AS tnative,
+ regexp_extract_all(a.cigar, '([0-9]+)([MID=X])', 1)::BIGINT[] AS lengths,
+ regexp_extract_all(a.cigar, '([0-9]+)([MID=X])', 2) AS operations
+ FROM read_parquet('{source}') a
+ JOIN read_parquet('{lookup}') q
+ ON a.query_entry=q.entry_pdb_id AND a.query_chain_mapped=q.chain_asym_id
+ LEFT JOIN read_parquet('{lookup}') t
+ ON a.target_entry=t.entry_pdb_id AND a.target_chain_mapped=t.chain_asym_id
+ ), consumed AS (
+ SELECT *,
+ list_transform(list_zip(lengths, operations), r -> CASE WHEN r[2]='D' THEN 0 ELSE r[1] END) AS qlengths,
+ list_transform(list_zip(lengths, operations), r -> CASE WHEN r[2]='I' THEN 0 ELSE r[1] END) AS tlengths
+ FROM native
+ ), starts AS (
+ SELECT *,
+ list_transform(range(1, len(lengths)+1), i -> original.query_start + coalesce(list_sum(list_slice(qlengths, 1, i-1)), 0)) AS qstarts,
+ list_transform(range(1, len(lengths)+1), i -> original.target_start + coalesce(list_sum(list_slice(tlengths, 1, i-1)), 0)) AS tstarts
+ FROM consumed
+ ), matched AS (
+ SELECT *, list_transform(qnative, n -> list_position(
+ list_transform(range(1, len(lengths)+1), j ->
+ n >= qstarts[j] AND n < qstarts[j]+qlengths[j]
+ AND operations[j] IN ('M', '=', 'X')), true)) AS matching_runs
+ FROM starts
+ ), selected AS (
+ SELECT *, list_filter(list_grade_up(qnative), i -> matching_runs[i] IS NOT NULL) AS qpositions
+ FROM matched
+ ) SELECT original.*,
+ qpositions AS query_selected_residue_positions,
+ list_transform(qpositions, i -> coalesce(list_position(tnative,
+ tstarts[matching_runs[i]] + qnative[i] - qstarts[matching_runs[i]]), 0)) AS target_selected_residue_positions
+ FROM selected"""
+
+
+def decode_cigar_residue_positions(
+ alignments: pd.DataFrame, *, chain_lookup: Path
+) -> pd.DataFrame:
+ """Recover selected residue pairs from CIGARs and the chain lookup.
+
+ Only selected query residues are visited; target position zero denotes a
+ residue outside the target's selected pocket/interface residues.
+ """
+ entries = sorted(set(alignments.query_entry) | set(alignments.target_entry))
+ lookup = (
+ pd.read_parquet(
+ chain_lookup,
+ columns=[
+ "entry_pdb_id",
+ "chain_asym_id",
+ "selected_residue_numbers",
+ "selected_residue_indices",
+ ],
+ filters=[("entry_pdb_id", "in", entries)],
+ )
+ if entries
+ else pd.DataFrame()
+ )
+ maps: dict[tuple[str, str, str], tuple[list[int], dict[int, int]]] = {}
+ for row in lookup.itertuples(index=False):
+ for backend, numbers in (
+ ("mmseqs", [int(n) for n in row.selected_residue_numbers]),
+ ("foldseek", [int(i) + 1 for i in row.selected_residue_indices]),
+ ):
+ maps[(row.entry_pdb_id, row.chain_asym_id, backend)] = (
+ sorted(numbers),
+ {n: i for i, n in enumerate(numbers, start=1)},
+ )
+ queries, targets = [], []
+ for row in alignments.itertuples(index=False):
+ selected, qmap = maps[(row.query_entry, row.query_chain_mapped, row.source)]
+ _, tmap = maps.get(
+ (row.target_entry, row.target_chain_mapped, row.source), ([], {})
+ )
+ q, t = int(row.query_start), int(row.target_start)
+ query, target = [], []
+ for length_text, operation in re.findall(r"(\d+)([MID=X])", row.cigar):
+ length = int(length_text)
+ if operation in {"M", "=", "X"}:
+ lo, hi = bisect_left(selected, q), bisect_left(selected, q + length)
+ for number in selected[lo:hi]:
+ query.append(qmap[number])
+ target.append(tmap.get(t + number - q, 0))
+ if operation in {"M", "I", "=", "X"}:
+ q += length
+ if operation in {"M", "D", "=", "X"}:
+ t += length
+ queries.append(query)
+ targets.append(target)
+ result = alignments.copy()
+ result["query_selected_residue_positions"] = queries
+ result["target_selected_residue_positions"] = targets
+ return result
+
+
+def pack_residue_identities(values: Iterable[bool]) -> bytes:
+ """Pack residue identity flags least-significant bit first."""
+ result = bytearray()
+ for index, value in enumerate(values):
+ byte_index = index // 8
+ if byte_index == len(result):
+ result.append(0)
+ if value:
+ result[byte_index] |= 1 << (index % 8)
+ return bytes(result)
+
+
+def unpack_residue_identities(value: object, count: int) -> list[bool]:
+ """Expand ``count`` flags from a packed identity bitset."""
+ if not isinstance(value, (bytes, bytearray, memoryview)):
+ raise TypeError("residue identity bitset must be bytes-like")
+ packed = bytes(value)
+ if len(packed) * 8 < count:
+ raise ValueError(
+ f"residue identity bitset has {len(packed) * 8} bits for {count} residues"
+ )
+ return [bool(packed[index // 8] & (1 << (index % 8))) for index in range(count)]
+
+
+def expand_residue_positions(
+ alignments: pd.DataFrame,
+ *,
+ chain_lookup: Path,
+) -> pd.DataFrame:
+ """Expand compact chain-relative positions to label-sequence numbers."""
+ if alignments.empty:
+ result = alignments.copy()
+ result["query_selected_residue_numbers"] = pd.Series(dtype="object")
+ result["target_selected_residue_numbers"] = pd.Series(dtype="object")
+ return result.drop(
+ columns=[
+ "query_selected_residue_positions",
+ "target_selected_residue_positions",
+ ],
+ errors="ignore",
+ )
+
+ entry_ids = sorted(
+ set(alignments["query_entry"].astype(str))
+ | set(alignments["target_entry"].astype(str))
+ )
+ lookup = pd.read_parquet(
+ chain_lookup,
+ columns=["entry_pdb_id", "chain_asym_id", "selected_residue_numbers"],
+ filters=[("entry_pdb_id", "in", entry_ids)],
+ )
+ numbers = {
+ (str(row.entry_pdb_id), str(row.chain_asym_id)): [
+ int(value) for value in row.selected_residue_numbers
+ ]
+ for row in lookup.itertuples(index=False)
+ }
+
+ query_numbers: list[list[int]] = []
+ target_numbers: list[list[int]] = []
+ for row in alignments.itertuples(index=False):
+ query = numbers[(str(row.query_entry), str(row.query_chain_mapped))]
+ target = numbers.get((str(row.target_entry), str(row.target_chain_mapped)), [])
+ query_numbers.append(
+ [
+ query[int(position) - 1]
+ for position in row.query_selected_residue_positions
+ ]
+ )
+ target_numbers.append(
+ [
+ -1 if int(position) == 0 else target[int(position) - 1]
+ for position in row.target_selected_residue_positions
+ ]
+ )
+
+ result = alignments.copy()
+ result["query_selected_residue_numbers"] = query_numbers
+ result["target_selected_residue_numbers"] = target_numbers
+ return result.drop(
+ columns=[
+ "query_selected_residue_positions",
+ "target_selected_residue_positions",
+ ]
+ )
diff --git a/src/plinder/core/scores/metrics.py b/src/plinder/core/scores/metrics.py
new file mode 100644
index 000000000..d761e93ac
--- /dev/null
+++ b/src/plinder/core/scores/metrics.py
@@ -0,0 +1,210 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Similarity metric definitions shared by scoring and clustering."""
+
+from __future__ import annotations
+
+import math
+from collections.abc import Iterable, Mapping
+
+PROTEIN_SCORE_NAMES = (
+ "protein_lddt",
+ "protein_lddt_qcov",
+ "protein_qcov",
+ "protein_fident",
+ "protein_fident_qcov",
+ "protein_seqsim",
+ "protein_seqsim_qcov",
+)
+
+LIGAND_SCORE_NAMES = (
+ "pocket_qcov",
+ "pocket_fident",
+ "pocket_fident_qcov",
+ "pli_fident",
+ "pli_qcov",
+ "shape",
+ "color",
+ "sucos_shape",
+ "sucos_shape_pocket_qcov",
+)
+
+SCORE_NAMES = PROTEIN_SCORE_NAMES + LIGAND_SCORE_NAMES
+
+GATED_LIGAND_DIAGNOSTIC_METRICS = frozenset({"shape", "color", "sucos_shape"})
+NON_CLUSTERING_LIGAND_METRICS = GATED_LIGAND_DIAGNOSTIC_METRICS | {
+ "pocket_fident",
+ "pocket_fident_qcov",
+ "pli_fident",
+}
+
+FOLDSEEK_ONLY_PROTEIN_SCORE_NAMES = frozenset({"protein_lddt", "protein_lddt_qcov"})
+
+PROTEIN_CLUSTER_METRICS = tuple(
+ f"{score_name}{suffix}"
+ for score_name in PROTEIN_SCORE_NAMES
+ if score_name not in FOLDSEEK_ONLY_PROTEIN_SCORE_NAMES
+ for suffix in ("_max", "_weighted_max", "_weighted_sum")
+)
+
+# Shape, color, raw SuCOS, and pocket fident remain queryable scores but are not
+# release clustering metrics. The 3D diagnostics are evaluated only after the
+# positive-pocket gate.
+LIGAND_CLUSTER_METRICS = tuple(
+ metric
+ for metric in LIGAND_SCORE_NAMES
+ if metric not in NON_CLUSTERING_LIGAND_METRICS
+)
+
+# Fingerprint-derived ligand-similarity metrics. Each is computed on the shared
+# unique-SMILES node universe (``ligand_smiles_id``) but from its own fingerprint
+# and similarity measure: ECFP4/1024 Tanimoto and MHFP6/2048 estimated Jaccard.
+CHEMICAL_CLUSTER_METRICS = (
+ "tanimoto_similarity_ecfp4_1024",
+ "jaccard_similarity_mhfp6_2048",
+)
+
+# Each chemical metric also publishes one convenience cluster column from its
+# 90-percent reciprocal set cover, plus the distinct-PDB count of that cluster
+# under ``_num_pdb_ids``.
+CHEMICAL_CLUSTER_SUMMARY_THRESHOLD = 90
+CHEMICAL_CLUSTER_SUMMARY_COLUMNS = {
+ "tanimoto_similarity_ecfp4_1024": "ligand_tanimoto_ecfp4_1024_90_cluster",
+ "jaccard_similarity_mhfp6_2048": "ligand_jaccard_mhfp6_2048_90_cluster",
+}
+
+DEFAULT_CLUSTER_METRICS = LIGAND_CLUSTER_METRICS + CHEMICAL_CLUSTER_METRICS
+
+
+def maximum_weight_bipartite_assignment(
+ query_nodes: Iterable[str],
+ target_nodes: Iterable[str],
+ primary_weights: Mapping[tuple[str, str], float],
+ *,
+ secondary_weights: Mapping[tuple[str, str], float] | None = None,
+) -> list[tuple[str, str]]:
+ """Maximize integer-stepped primary weights, then secondary weights.
+
+ Zero-weight dummy nodes allow either side to remain unmatched. Secondary
+ weights are normalized so that their complete assignment can never
+ outweigh one primary-weight unit. Returned pairs are deterministic and
+ ordered by their contribution to the objective.
+ """
+ query = sorted(set(map(str, query_nodes)))
+ target = sorted(set(map(str, target_nodes)))
+ size = max(len(query), len(target))
+ if size == 0:
+ return []
+
+ secondary_weights = secondary_weights or {}
+ finite_secondary = [
+ float(value)
+ for value in secondary_weights.values()
+ if math.isfinite(float(value)) and float(value) > 0
+ ]
+ secondary_scale = max([1.0, *finite_secondary])
+ primary_multiplier = float(size + 1)
+ weights = [[0.0] * size for _ in range(size)]
+ components: dict[tuple[int, int], tuple[float, float]] = {}
+ maximum = 0.0
+ for query_index, query_node in enumerate(query):
+ for target_index, target_node in enumerate(target):
+ pair = (query_node, target_node)
+ primary = float(primary_weights.get(pair, 0.0))
+ secondary = float(secondary_weights.get(pair, 0.0))
+ if not math.isfinite(primary) or primary < 0:
+ primary = 0.0
+ if not math.isfinite(secondary) or secondary < 0:
+ secondary = 0.0
+ secondary /= secondary_scale
+ weight = primary * primary_multiplier + secondary
+ weights[query_index][target_index] = weight
+ components[(query_index, target_index)] = (primary, secondary)
+ maximum = max(maximum, weight)
+ if maximum == 0:
+ return []
+
+ # Shortest-augmenting-path Hungarian algorithm for a square minimum-cost
+ # problem. Converting max weights to costs preserves the optimum.
+ costs = [[maximum - weight for weight in row] for row in weights]
+ row_potential = [0.0] * (size + 1)
+ column_potential = [0.0] * (size + 1)
+ column_match = [0] * (size + 1)
+ predecessor = [0] * (size + 1)
+ for row in range(1, size + 1):
+ column_match[0] = row
+ minimum = [math.inf] * (size + 1)
+ used = [False] * (size + 1)
+ column = 0
+ while True:
+ used[column] = True
+ matched_row = column_match[column]
+ delta = math.inf
+ next_column = 0
+ for candidate in range(1, size + 1):
+ if used[candidate]:
+ continue
+ reduced_cost = (
+ costs[matched_row - 1][candidate - 1]
+ - row_potential[matched_row]
+ - column_potential[candidate]
+ )
+ if reduced_cost < minimum[candidate]:
+ minimum[candidate] = reduced_cost
+ predecessor[candidate] = column
+ if minimum[candidate] < delta:
+ delta = minimum[candidate]
+ next_column = candidate
+ for candidate in range(size + 1):
+ if used[candidate]:
+ row_potential[column_match[candidate]] += delta
+ column_potential[candidate] -= delta
+ else:
+ minimum[candidate] -= delta
+ column = next_column
+ if column_match[column] == 0:
+ break
+ while True:
+ previous = predecessor[column]
+ column_match[column] = column_match[previous]
+ column = previous
+ if column == 0:
+ break
+
+ row_to_column = [-1] * size
+ for column in range(1, size + 1):
+ if column_match[column] > 0:
+ row_to_column[column_match[column] - 1] = column - 1
+ weighted_pairs = [
+ (
+ *components[(row, column)],
+ query[row],
+ target[column],
+ )
+ for row, column in enumerate(row_to_column[: len(query)])
+ if 0 <= column < len(target) and weights[row][column] > 0
+ ]
+ weighted_pairs.sort(key=lambda pair: (-pair[0], -pair[1], pair[2], pair[3]))
+ return [
+ (query_node, target_node) for _, _, query_node, target_node in weighted_pairs
+ ]
+
+
+def is_chemical_cluster_metric(metric: str) -> bool:
+ """Return whether a metric is a fingerprint-derived ligand-similarity metric.
+
+ Chemical metrics cluster the unique-SMILES node universe and are symmetric,
+ which sets them apart from the pocket/protein score metrics throughout the
+ clustering pipeline.
+ """
+ return metric in CHEMICAL_CLUSTER_METRICS
+
+
+def is_ligand_level_metric(metric: str) -> bool:
+ """Return whether graph nodes for this score are individual ligands."""
+ return (
+ metric in LIGAND_SCORE_NAMES
+ or metric in PROTEIN_CLUSTER_METRICS
+ or metric in CHEMICAL_CLUSTER_METRICS
+ or metric.startswith(("pocket_", "pli_"))
+ )
diff --git a/src/plinder/core/scores/protein.py b/src/plinder/core/scores/protein.py
index d839e876a..e10796542 100644
--- a/src/plinder/core/scores/protein.py
+++ b/src/plinder/core/scores/protein.py
@@ -1,203 +1,260 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
+"""Query compact chain-level protein similarities."""
+
from __future__ import annotations
+from pathlib import Path
+from typing import Literal
+
import pandas as pd
-from duckdb import sql
-from plinder.core.scores.index import query_index
-from plinder.core.scores.query import FILTER, FILTERS, make_query
-from plinder.core.utils import cpl
-from plinder.core.utils.config import get_config
+from plinder.core.release import PlinderRelease
+from plinder.core.scores.mapping import (
+ decode_cigar_residue_positions,
+ unpack_residue_identities,
+)
+from plinder.core.scores.query import Filters, read_score_table
from plinder.core.utils.dec import timeit
-from plinder.core.utils.log import setup_logger
-from plinder.core.utils.schemas import PROTEIN_SIMILARITY_SCHEMA
-LOG = setup_logger(__name__)
+OVERLAP_COLUMNS = [
+ "query_entry",
+ "query_chain",
+ "target_entry",
+ "target_chain",
+ "source",
+ "kind",
+ "overlapping_residues",
+ "identical_overlapping_residues",
+ "query_total_residues",
+ "target_total_residues",
+ "query_overlap_fraction",
+ "target_overlap_fraction",
+]
@timeit
def query_protein_similarity(
*,
- search_db: str,
columns: list[str] | None = None,
- filters: FILTERS = None,
-) -> pd.DataFrame | None:
- """
- Query the protein similarity database for
- a given search_db and return the results.
-
- Parameters
- ----------
- search_db : str
- the name of the search database
- columns : list[str], default=None
- the columns to return
- filters : list[tuple[str, str, str | set[str]]]
- the filters to apply
-
- Returns
- -------
- df : pd.DataFrame | None
- the protein similarity results
+ filters: Filters = None,
+ release: PlinderRelease | None = None,
+ include_monomers: bool = False,
+) -> pd.DataFrame:
+ """Query chain-level Foldseek and MMseqs similarities in integer percent.
+
+ Set ``include_monomers`` to include queries from protein chains outside
+ ligand pockets and protein interfaces.
"""
- if search_db not in ["apo", "holo", "pred"]:
- raise ValueError(f"search_db={search_db} not in ['apo', 'holo', 'pred']")
- cfg = get_config()
- if isinstance(filters, list):
- if len(filters) and not isinstance(filters[0], list):
- for i, (col, _, _) in enumerate(filters):
- if col == "search_db":
- filters.pop(i)
- break
- dataset = cpl.get_plinder_path(rel=f"{cfg.data.scores}/search_db={search_db}")
- query = make_query(
- schema=PROTEIN_SIMILARITY_SCHEMA,
- dataset=dataset,
- filters=filters,
- columns=columns,
+ selected_release = release or PlinderRelease()
+ paths = [selected_release.fetch("protein_similarity_scores")]
+ if include_monomers:
+ paths.append(selected_release.fetch("monomer_similarity_scores"))
+ return pd.concat(
+ [read_score_table(path, columns=columns, filters=filters) for path in paths],
+ ignore_index=True,
)
- if query is None:
- LOG.warning("try minimally passing filters=[('similarity', '>', 90)]")
- return None
- return sql(query).to_df()
-@timeit
-def map_cross_similarity(
- df: pd.DataFrame, target_systems: set[str], metric: str
-) -> pd.DataFrame:
- updated_query_systems = []
- updated_target_systems = []
- for q, t in zip(df["query_system"], df["target_system"]):
- if t in target_systems:
- updated_query_systems.append(t)
- updated_target_systems.append(q)
- else:
- updated_query_systems.append(q)
- updated_target_systems.append(t)
- df["updated_query_system"] = updated_query_systems
- df["updated_target_system"] = updated_target_systems
- idx = df.groupby("updated_query_system")["similarity"].idxmax()
- return df.loc[idx][
- ["updated_query_system", "updated_target_system", "similarity"]
- ].rename(
- columns={
- "updated_query_system": "query_system",
- "updated_target_system": "target_system",
- "similarity": metric,
- }
+def _selected_residue_positions(
+ lookup: Path,
+ *,
+ entry: str,
+ chain: str,
+) -> dict[int, int]:
+ rows = pd.read_parquet(
+ lookup,
+ columns=["selected_residue_numbers"],
+ filters=[("entry_pdb_id", "==", entry), ("chain_asym_id", "==", chain)],
)
+ if len(rows) != 1:
+ raise KeyError(f"unknown protein chain {entry}_{chain}")
+ return {
+ int(number): position
+ for position, number in enumerate(
+ rows.iloc[0]["selected_residue_numbers"], start=1
+ )
+ }
-@timeit
-def cross_similarity(
+def _pocket_residue_numbers(
+ release: PlinderRelease,
*,
- query_systems: set[str],
- target_systems: set[str],
- metric: str,
-) -> pd.DataFrame:
- cfg = get_config()
- dataset = cpl.get_plinder_path(rel=f"{cfg.data.scores}/search_db=holo")
- filters: list[list[FILTER]] = [
- [
- FILTER(("metric", "==", metric)),
- FILTER(("query_system", "in", query_systems)),
- FILTER(("target_system", "in", target_systems)),
- ],
- [
- FILTER(("metric", "==", metric)),
- FILTER(("query_system", "in", target_systems)),
- FILTER(("target_system", "in", query_systems)),
+ entry: str,
+ chain: str,
+) -> set[int]:
+ rows = pd.read_parquet(
+ release.fetch("ligand_pocket_residues"),
+ columns=["residue_label_seq_id"],
+ filters=[("entry_pdb_id", "==", entry), ("chain_asym_id", "==", chain)],
+ )
+ return set(rows["residue_label_seq_id"].astype(int))
+
+
+def _interface_residue_numbers(
+ release: PlinderRelease,
+ *,
+ entry: str,
+ chain: str,
+) -> set[int]:
+ rows = pd.read_parquet(
+ release.fetch("interface_annotations"),
+ columns=[
+ "interface_chain_1",
+ "interface_chain_1_residue_numbers",
+ "interface_chain_2",
+ "interface_chain_2_residue_numbers",
],
- ]
- columns = ["query_system", "target_system", "similarity"]
- query = make_query(
- schema=PROTEIN_SIMILARITY_SCHEMA,
- dataset=dataset,
- columns=columns,
- filters=filters,
+ filters=[("entry_pdb_id", "==", entry)],
)
- assert query is not None
- return map_cross_similarity(sql(query).to_df(), target_systems, metric)
+ numbers: set[int] = set()
+ for row in rows.itertuples(index=False):
+ for instance_chain, residues in (
+ (row.interface_chain_1, row.interface_chain_1_residue_numbers),
+ (row.interface_chain_2, row.interface_chain_2_residue_numbers),
+ ):
+ if str(instance_chain).split(".", maxsplit=1)[-1] == chain:
+ numbers.update(int(number) for number in residues)
+ return numbers
+
+
+def _residue_positions(
+ release: PlinderRelease,
+ lookup: Path,
+ *,
+ entry: str,
+ chain: str,
+ kind: Literal["pocket", "interface"],
+) -> set[int]:
+ selected = _selected_residue_positions(lookup, entry=entry, chain=chain)
+ if kind == "pocket":
+ numbers = _pocket_residue_numbers(release, entry=entry, chain=chain)
+ else:
+ numbers = _interface_residue_numbers(release, entry=entry, chain=chain)
+ return {selected[number] for number in numbers}
+
+
+def _overlap_fraction(overlap: int, total: int) -> float:
+ return overlap / total if total else 0.0
@timeit
-def multi_query_protein_similarity(
+def query_chain_overlap(
+ query_entry: str,
+ query_chain: str,
+ target_entry: str,
+ target_chain: str,
*,
- system_id: str,
- search_db: str,
- filter_criteria: dict[str, int],
- splits: list[str] | None = None,
+ kind: Literal["pocket", "interface"],
+ source: Literal["foldseek", "mmseqs"] | None = None,
+ search_db: str = "holo",
+ release: PlinderRelease | None = None,
) -> pd.DataFrame:
+ """Count aligned pocket or interface residues between two protein chains.
+
+ Chain IDs are label asym IDs. Residues are collected across all ligand
+ pockets or all protein interfaces involving each chain. One row is returned
+ per available search backend.
"""
- Searches the protein similarity database for systems satisfying ALL filter criteria
-
- Parameters
- ----------
- system_id : str
- the system_id to search for
- search_db : str
- the search database to search in
- filter_criteria : dict[str, int]
- metric and threshold pairs
- e.g {
- "pocket_fident": 100,
- "protein_fident_weighted_sum": 95,
- "protein_fident_qcov_weighted_sum": 80,
- "pocket_lddt": 20,
- "protein_lddt_weighted_sum": 20,
- }
- splits : list[str] | None, default=None
- the splits to search in (only used if search_db="holo")
-
- Returns
- -------
- df : pd.DataFrame
- the protein similarity results across all metrics in filter_criteria
- """
- if splits is None:
- splits = ["train"]
- empty_df = pd.DataFrame(
- columns=["query_system", "target_system"] + list(filter_criteria.keys())
+ if kind not in {"pocket", "interface"}:
+ raise ValueError("kind must be 'pocket' or 'interface'")
+ selected_release = release or PlinderRelease()
+ lookup = selected_release.fetch("alignment_chain_lookup")
+ query_positions = _residue_positions(
+ selected_release,
+ lookup,
+ entry=query_entry,
+ chain=query_chain,
+ kind=kind,
)
- if search_db == "holo":
- target_systems_df = query_index(
- columns=["system_id"],
- splits=splits,
- )
- if target_systems_df is None:
- return empty_df
- target_systems = set(target_systems_df["system_id"])
- if len(target_systems) == 0:
- return empty_df
- filters = []
- for metric, threshold in filter_criteria.items():
- filter = [
- ("metric", "==", metric),
- ("similarity", ">=", threshold),
- ("query_system", "==", system_id),
- ]
- if search_db == "holo":
- filter.append(("target_system", "in", target_systems))
- filters.append(filter)
- links = query_protein_similarity(
- search_db=search_db,
- columns=["query_system", "target_system", "metric", "similarity"],
- filters=filters,
+ target_positions = _residue_positions(
+ selected_release,
+ lookup,
+ entry=target_entry,
+ chain=target_chain,
+ kind=kind,
)
- if links is None or len(links) == 0:
- return empty_df
- links = links.iloc[
- links.groupby(["query_system", "target_system", "metric"], observed=True)[
- "similarity"
- ].idxmax()
- ]
- links = links.pivot(
- index=["query_system", "target_system"],
- columns="metric",
- values="similarity",
- ).reset_index()
- found_metrics = set(links.columns).intersection(filter_criteria.keys())
- query = " and ".join([f"{m} >= {filter_criteria[m]}" for m in found_metrics])
- return links.query(query)
+ query_total = len(query_positions)
+ target_total = len(target_positions)
+
+ sources = (source,) if source is not None else ("foldseek", "mmseqs")
+ records: list[dict[str, object]] = []
+ for alignment_type in sources:
+ try:
+ shard = selected_release.fetch(
+ "alignment_cigar_shard",
+ search_db=search_db,
+ alignment_type=alignment_type,
+ shard=query_entry[-3:-1],
+ )
+ except FileNotFoundError:
+ if source is not None:
+ raise
+ continue
+ alignments = pd.read_parquet(
+ shard,
+ columns=[
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ "source",
+ "query_start",
+ "target_start",
+ "cigar",
+ "selected_residue_identity_bits",
+ ],
+ filters=[
+ ("query_entry", "==", query_entry),
+ ("query_chain_mapped", "==", query_chain),
+ ("target_entry", "==", target_entry),
+ ("target_chain_mapped", "==", target_chain),
+ ],
+ )
+ alignments = decode_cigar_residue_positions(alignments, chain_lookup=lookup)
+ for row in alignments.itertuples(index=False):
+ aligned_query_positions = [
+ int(position) for position in row.query_selected_residue_positions
+ ]
+ aligned_target_positions = [
+ int(position) for position in row.target_selected_residue_positions
+ ]
+ identities = unpack_residue_identities(
+ row.selected_residue_identity_bits,
+ len(aligned_target_positions),
+ )
+ overlap_mask = [
+ query_position in query_positions
+ and target_position in target_positions
+ for query_position, target_position in zip(
+ aligned_query_positions,
+ aligned_target_positions,
+ strict=True,
+ )
+ ]
+ overlap = sum(overlap_mask)
+ records.append(
+ {
+ "query_entry": query_entry,
+ "query_chain": query_chain,
+ "target_entry": target_entry,
+ "target_chain": target_chain,
+ "source": alignment_type,
+ "kind": kind,
+ "overlapping_residues": overlap,
+ "identical_overlapping_residues": sum(
+ identity and overlaps
+ for identity, overlaps in zip(
+ identities, overlap_mask, strict=True
+ )
+ ),
+ "query_total_residues": query_total,
+ "target_total_residues": target_total,
+ "query_overlap_fraction": _overlap_fraction(overlap, query_total),
+ "target_overlap_fraction": _overlap_fraction(overlap, target_total),
+ }
+ )
+ return pd.DataFrame.from_records(records, columns=OVERLAP_COLUMNS)
+
+
+__all__ = ["query_chain_overlap", "query_protein_similarity"]
diff --git a/src/plinder/core/scores/query.py b/src/plinder/core/scores/query.py
index 04ff8ef24..bcae68f7d 100644
--- a/src/plinder/core/scores/query.py
+++ b/src/plinder/core/scores/query.py
@@ -1,311 +1,28 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
+"""Read filtered similarity-score Parquet datasets."""
+
from __future__ import annotations
from pathlib import Path
-from typing import List, NewType, Set, Tuple, Union
-
-import numpy as np
-import pyarrow as pa
-
-from plinder.core.utils.log import setup_logger
-
-LOG = setup_logger(__name__)
-SQL_OP_MAP = {"==": "="}
-FILTER = NewType("FILTER", Tuple[str, str, Union[str, Set[str]]])
-FILTERS = Union[List[List[FILTER]], List[FILTER], None]
-
-
-def _handle_condition_by_schema(
- schema: pa.Schema, col: str, val: str | set[str]
-) -> str:
- """
- Deal with quoting hell for the varied conditions
- and types in the schema.
-
- Parameters
- ----------
- schema : pa.Schema
- the schema to use
- col : str
- the field name to get the type
- val : str
- the value provided in the filter
-
- Returns
- -------
- val : str
- the value to use in the query
- """
- try:
- dt = schema.types[schema.names.index(col)].to_pandas_dtype()
- if np.issubdtype(dt, np.number):
- val = val
- else:
- val = f"'{val}'"
- except NotImplementedError:
- val = f"'{val}'"
- if isinstance(val, (set, list, tuple)):
- val = f"({str(val)[1:-1]})"
- return val
-
-
-def _handle_condition_by_type(val: str | set[str]) -> str:
- """
- Deal with quoting hell for the varied types passed
- in the filters.
-
- Parameters
- ----------
- val : str
- the value provided in the filter
-
- Returns
- -------
- val : str
- the value to use in the query
- """
- if isinstance(val, str):
- val = f"'{val}'"
- elif isinstance(val, (list, set)):
- val = f"({str(val)[1:-1]})"
- else:
- LOG.debug(f"_handle_condition_by_type: type(val)={type(val)} not mutated")
- return val
-
-
-def _handle_inner_filter(
- filter: FILTER,
- schema: pa.Schema | None,
-) -> str:
- """
- Convert the tuple format of a filter into a valid SQL substring
-
- Parameters
- ----------
- filter : tuple[str, str, str | set[str]]
- the filter to apply
- schema : pa.Schema | None
- the schema to use
-
- Returns
- -------
- str
- the formatted SQL filter
- """
- if len(filter) != 3:
- raise ValueError(f"filters must be (column, operator, value): got {filter}")
- col, op, val = filter
- if op == "in":
- val = _handle_condition_by_type(val)
- else:
- if schema is not None:
- if col not in schema.names:
- raise ValueError(f"column={col} not in schema={schema.names}")
- val = _handle_condition_by_schema(schema, col, val)
- else:
- val = _handle_condition_by_type(val)
- return f"{col} {SQL_OP_MAP.get(op, op)} {val}"
-
-
-def _handle_filters(
- filters: FILTERS,
- allow_no_filters: bool,
- schema: pa.Schema | None,
-) -> list[str | list[str]]:
- """
- Format the filters for the query
-
- Parameters
- ----------
- filters : list[tuple[str, str, str | set[str]]], default=None
- the filters to apply
- allow_no_filters : bool
- if True, allow no filters
- schema : pa.Schema, default=None
- the schema to validate the filters against
-
- Returns
- -------
- filters : list[tuple[str, str, str | set[str]]]
- the formatted filters
- """
- missing = False
- if filters is None:
- missing = True
- elif not len(filters):
- missing = True
- if missing and not allow_no_filters:
- raise ValueError("no filters provided, aborting query generation!")
- wheres: list[str | list[str]] = []
- if filters is not None:
- for filter in filters:
- if isinstance(filter, list):
- inner_wheres: list[str] = []
- for inner_filter in filter:
- inner_wheres.append(_handle_inner_filter(inner_filter, schema))
- wheres.append(inner_wheres)
- else:
- wheres.append(_handle_inner_filter(filter, schema))
- return wheres
-
-
-def _handle_columns(
- columns: list[str] | None,
- include_filename: bool,
- schema: pa.Schema | None,
-) -> list[str]:
- """
- Format the columns for the query
-
- Parameters
- ----------
- columns : list[str], default=None
- the columns to select
- include_filename : bool
- if True, include the filename in the columns
- schema : pa.Schema, default=None
- the schema to validate the columns against
- """
- cols: list[str]
- if schema is not None:
- cols = schema.names if columns is None or not len(columns) else columns
- if cols != ["*"]:
- for col in cols:
- if col not in schema.names:
- if include_filename and col == "filename":
- continue
- raise ValueError(f"column={col} not in schema={schema.names}")
- else:
- cols = columns if columns is not None else ["*"]
- return cols
-
-
-def _handle_source(
- dataset: Path,
- nested: bool,
- include_filename: bool,
- filename: str | None,
-) -> str:
- """
- Format the source of data for the query
-
- Parameters
- ----------
- dataset : Path
- the dataset to query
- nested : bool
- if True, select all parquet files in the dataset
- include_filename : bool
- if True, include the filename in the result
- filename : str, default=None
- a specific filename to read from if present
-
- Returns
- -------
- content : str
- the formatted source
- """
- if dataset.is_file():
- content = f"'{dataset.as_posix()}'"
- else:
- content = f"'{dataset}/*.parquet'"
- if nested:
- content = f"'{dataset}/**/*.parquet'"
- if filename is not None:
- content = f"'{dataset}/{filename}'"
- if include_filename:
- content = f"read_parquet({content}, filename = true)"
- return content
-
-
-def _format_query(
- columns: list[str],
- filters: list[str | list[str]],
- source: str,
-) -> str:
- """
- Pretty format the SQL query for readability of the SQL
- syntax when debugging.
+from typing import Any, TypeAlias
- Parameters
- ----------
- columns : list[str]
- the columns to select
- filters : list[list[str]] | list[str]
- the filters to apply
- source : str
- the source of the data
+import pandas as pd
- Returns
- -------
- qry : str
- the formatted SQL query
- """
- margin = "\n "
- select = margin.join(["", f",{margin}".join(columns)])
- ands = []
- union = "AND"
- for ors in filters:
- if isinstance(ors, list):
- inner = f"{margin} "
- union = "OR"
- ands.append("".join([f"({inner}", f"{inner}AND ".join(ors), f"{margin})"]))
- else:
- ands.append(f"{ors}")
- where = margin.join(["", f"{margin}{union} {margin}".join(ands)])
- qry = f"""\
-SELECT {select}
-FROM
- {source}"""
- if len(filters):
- qry += f"\nWHERE {where}"
- if ";" in qry:
- raise ValueError(f"query={qry} contains a semicolon!")
- LOG.debug("\n" + qry + ";")
- return qry
+Filter: TypeAlias = tuple[str, str, Any]
+Filters: TypeAlias = list[Filter] | list[list[Filter]] | None
-def make_query(
+def read_score_table(
dataset: Path,
- schema: pa.Schema | None = None,
+ *,
columns: list[str] | None = None,
- filters: FILTERS = None,
- nested: bool = False,
- allow_no_filters: bool = False,
- include_filename: bool = False,
- filename: str | None = None,
-) -> str | None:
- """
- Convert the kwargs commonly passed to pd.read_parquet
- into a duckdb SQL query string. Fill in the blanks and
- raise an error if no filters are provided.
+ filters: Filters = None,
+) -> pd.DataFrame:
+ """Read selected score rows without allowing an unbounded scan."""
+ if not filters:
+ raise ValueError("at least one score filter is required")
+ return pd.read_parquet(dataset, columns=columns, filters=filters)
- Parameters
- ----------
- schema : pa.Schema
- the pyarrow schema of the dataset
- dataset : Path
- the path to the dataset
- columns : list[str], default=None
- the columns to select
- filters : list[tuple[str, str, str]], default=None
- the filters to apply
- nested : bool, default=False
- if True, select all parquet files in the dataset
- allow_no_filters : bool, default=False
- if True, allow no filters
- include_filename : bool, default=False
- if True, include the filename in the result
- filename : str, default=None
- a specific filename to read from if present
- Returns
- -------
- query : str | None
- the duckdb SQL query string
- """
- wheres = _handle_filters(filters, allow_no_filters, schema)
- cols = _handle_columns(columns, include_filename, schema)
- content = _handle_source(dataset, nested, include_filename, filename)
- return f"{_format_query(cols, wheres, content)};"
+__all__ = ["Filter", "Filters", "read_score_table"]
diff --git a/src/plinder/core/scores/reconstruct.py b/src/plinder/core/scores/reconstruct.py
new file mode 100644
index 000000000..4068f73d2
--- /dev/null
+++ b/src/plinder/core/scores/reconstruct.py
@@ -0,0 +1,597 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Reconstruct bounded similarity subsets from mapped search alignments."""
+
+from __future__ import annotations
+
+from collections import defaultdict
+from collections.abc import Callable, Iterable, Mapping
+from pathlib import Path
+
+import pandas as pd
+
+from plinder.core.release import _release_file
+from plinder.core.scores.entries import (
+ EntryView,
+ InterfaceView,
+ LigandView,
+ load_entry_views,
+)
+from plinder.core.scores.mapping import (
+ decode_cigar_residue_positions,
+ expand_residue_positions,
+)
+from plinder.core.utils.log import setup_logger
+from plinder.core.utils.schemas import (
+ INTERFACE_SIMILARITY_SCHEMA,
+ PROTEIN_SIMILARITY_SCHEMA,
+)
+
+ALIGNMENT_TYPES = ("foldseek", "mmseqs")
+LOG = setup_logger(__name__)
+
+
+def _pdb_id(identifier: str) -> str:
+ return identifier.split("__", maxsplit=1)[0]
+
+
+def _pdb_shard(pdb_id: str) -> str:
+ return pdb_id[-3:-1]
+
+
+def prefetch_similarity_alignments(
+ query_system_ids: Iterable[str],
+ *,
+ search_db: str = "holo",
+ data_dir: Path | None = None,
+ include_protein_scores: bool = False,
+) -> dict[str, dict[str, Path]]:
+ """Download or verify only the mapped alignments needed by query systems.
+
+ Calling this on an online node populates the normal PLINDER cache. Calling
+ it later with offline mode enabled only checks those same local files.
+ With ``include_protein_scores``, each backend also needs its matching
+ protein-similarity export shard, which supplies the alignment scores that
+ the CIGAR shards omit (needed for ligand similarity reconstruction).
+ """
+ if search_db != "holo":
+ raise NotImplementedError(
+ "subset reconstruction currently supports search_db='holo' only"
+ )
+ query_pdb_ids = sorted({_pdb_id(value) for value in query_system_ids})
+ if not query_pdb_ids:
+ raise ValueError("query_system_ids must not be empty")
+
+ paths: dict[str, dict[str, Path]] = {}
+ resolved: dict[tuple[str, str], Path | None] = {}
+ resolution_errors: dict[tuple[str, str], FileNotFoundError] = {}
+ for pdb_id in query_pdb_ids:
+ paths[pdb_id] = {}
+ shard = _pdb_shard(pdb_id)
+ for alignment_type in ALIGNMENT_TYPES:
+ key = (alignment_type, shard)
+ if key not in resolved:
+ try:
+ resolved[key] = _release_file(
+ "alignment_cigar_shard",
+ data_dir=data_dir,
+ description=(
+ f"{search_db} {alignment_type} mapped alignment "
+ f"shard {shard}"
+ ),
+ search_db=search_db,
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ if include_protein_scores:
+ _release_file(
+ "protein_similarity_score_shard",
+ data_dir=data_dir,
+ description=(
+ f"{alignment_type} protein similarity score "
+ f"shard {shard}"
+ ),
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ except FileNotFoundError as exc:
+ resolved[key] = None
+ resolution_errors[key] = exc
+ resolved_path = resolved[key]
+ if resolved_path is not None:
+ paths[pdb_id][alignment_type] = resolved_path
+
+ if not paths[pdb_id]:
+ failures = []
+ for alignment_type in ALIGNMENT_TYPES:
+ key = (alignment_type, shard)
+ if key in resolution_errors:
+ failures.append(str(resolution_errors[key]))
+ raise FileNotFoundError(
+ f"no mapped alignment backend is available for {pdb_id}: "
+ + "; ".join(failures)
+ )
+ if len(paths[pdb_id]) != len(ALIGNMENT_TYPES):
+ missing = sorted(set(ALIGNMENT_TYPES) - paths[pdb_id].keys())
+ LOG.warning(
+ f"reconstructing {pdb_id} without unavailable alignment "
+ f"backend(s): {', '.join(missing)}"
+ )
+ return paths
+
+
+def _load_entry_subset(
+ *, pdb_ids: set[str], data_dir: Path | None
+) -> tuple[dict[str, EntryView], Path]:
+ index_path = _release_file(
+ "annotation_table",
+ data_dir=data_dir,
+ description="annotation index",
+ )
+ entries = load_entry_views(pdb_ids=pdb_ids, data_dir=data_dir)
+ if not entries:
+ raise KeyError(f"no annotation rows found for PDB IDs {sorted(pdb_ids)}")
+ return entries, index_path.parent.parent
+
+
+def _selected_ligand_ids(
+ entries: dict[str, EntryView], system_ids: set[str]
+) -> set[str]:
+ ligand_ids: set[str] = set()
+ for entry in entries.values():
+ for system_id, system in entry.systems.items():
+ if system_id in system_ids:
+ ligand_ids.update(ligand.id for ligand in system.ligands.values())
+ return ligand_ids
+
+
+def _selected_interfaces(
+ entries: Mapping[str, EntryView], interface_ids: set[str]
+) -> dict[str, InterfaceView]:
+ available = {
+ interface_id: interface
+ for entry in entries.values()
+ for interface_id, interface in entry.interfaces.items()
+ }
+ missing = interface_ids - available.keys()
+ if missing:
+ raise KeyError(f"unknown interface system IDs: {sorted(missing)}")
+ return {interface_id: available[interface_id] for interface_id in interface_ids}
+
+
+def _load_interface_alignments(
+ alignment_paths: Mapping[str, Mapping[str, Path]],
+ *,
+ target_pdb_ids: set[str],
+ chain_lookup: Path,
+) -> pd.DataFrame:
+ """Load only compact residue maps needed by an interface subset."""
+ columns = [
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ "source",
+ "query_start",
+ "target_start",
+ "cigar",
+ ]
+ frames: list[pd.DataFrame] = []
+ targets = sorted(target_pdb_ids)
+ for query_pdb_id, paths in alignment_paths.items():
+ for alignment_type, path in paths.items():
+ frame = pd.read_parquet(
+ path,
+ columns=columns,
+ filters=[
+ ("query_entry", "==", query_pdb_id),
+ ("target_entry", "in", targets),
+ ],
+ )
+ if frame.empty:
+ continue
+ frame["source"] = alignment_type
+ frames.append(
+ expand_residue_positions(
+ decode_cigar_residue_positions(frame, chain_lookup=chain_lookup),
+ chain_lookup=chain_lookup,
+ )
+ )
+ if not frames:
+ return pd.DataFrame(
+ columns=[
+ *columns[:5],
+ "query_selected_residue_numbers",
+ "target_selected_residue_numbers",
+ ]
+ )
+ return pd.concat(frames, ignore_index=True)
+
+
+def _interface_side_index(
+ interfaces: Mapping[str, InterfaceView],
+) -> dict[tuple[str, str], list[tuple[str, int, frozenset[int]]]]:
+ sides: dict[tuple[str, str], list[tuple[str, int, frozenset[int]]]] = defaultdict(
+ list
+ )
+ for interface in interfaces.values():
+ for side, (chain, residues) in enumerate(
+ (
+ (interface.chain_1, interface.chain_1_residue_number_to_index),
+ (interface.chain_2, interface.chain_2_residue_number_to_index),
+ ),
+ start=1,
+ ):
+ asym_id = chain.split(".", maxsplit=1)[-1]
+ sides[(interface.pdb_id, asym_id)].append(
+ (
+ interface.id,
+ side,
+ frozenset(residues),
+ )
+ )
+ return sides
+
+
+def _as_int_list(value: object) -> list[int]:
+ if (
+ value is None
+ or isinstance(value, (str, bytes))
+ or not isinstance(value, Iterable)
+ ):
+ return []
+ return [int(item) for item in value]
+
+
+def calculate_interface_similarity_scores(
+ alignments: pd.DataFrame,
+ *,
+ query_interfaces: Mapping[str, InterfaceView],
+ target_interfaces: Mapping[str, InterfaceView],
+) -> pd.DataFrame:
+ """Calculate directional two-chain interface coverage from compact maps.
+
+ For each backend, the direct and swapped chain assignments are evaluated
+ as the product of the two directed residue coverages. The better complete
+ assignment is retained, followed by the better Foldseek/MMseqs backend.
+ """
+ query_sides = _interface_side_index(query_interfaces)
+ target_sides = _interface_side_index(target_interfaces)
+ coverage: dict[tuple[str, str, str, int, int], float] = {}
+ for row in alignments.itertuples(index=False):
+ source = str(row.source)
+ query_key = (str(row.query_entry), str(row.query_chain_mapped))
+ target_key = (str(row.target_entry), str(row.target_chain_mapped))
+ matching_query_sides = query_sides.get(query_key, [])
+ matching_target_sides = target_sides.get(target_key, [])
+ if not matching_query_sides or not matching_target_sides:
+ continue
+ residue_pairs = list(
+ zip(
+ _as_int_list(row.query_selected_residue_numbers),
+ _as_int_list(row.target_selected_residue_numbers),
+ )
+ )
+ if not residue_pairs:
+ continue
+ for query_id, query_side, query_residues in matching_query_sides:
+ if not query_residues:
+ continue
+ for target_id, target_side, target_residues in matching_target_sides:
+ matched_query_residues = {
+ query_number
+ for query_number, target_number in residue_pairs
+ if query_number in query_residues
+ and target_number in target_residues
+ }
+ if not matched_query_residues:
+ continue
+ value = len(matched_query_residues) / len(query_residues)
+ key = (source, query_id, target_id, query_side, target_side)
+ coverage[key] = max(coverage.get(key, 0.0), value)
+
+ def assignment(
+ source: str,
+ query: InterfaceView,
+ target: InterfaceView,
+ *,
+ swapped: bool,
+ ) -> tuple[float, float, float, str] | None:
+ target_sides_order = (2, 1) if swapped else (1, 2)
+ values = [
+ coverage.get((source, query.id, target.id, query_side, target_side))
+ for query_side, target_side in zip((1, 2), target_sides_order)
+ ]
+ first, second = values
+ if first is None or second is None:
+ return None
+ target_chains = (target.chain_2, target.chain_1) if swapped else target.chains
+ mapping = ";".join(
+ f"{query_chain}:{target_chain}"
+ for query_chain, target_chain in zip(query.chains, target_chains)
+ )
+ return first * second, first, second, mapping
+
+ records: list[dict[str, object]] = []
+ for query in query_interfaces.values():
+ for target in target_interfaces.values():
+ if query.id == target.id:
+ continue
+ backend_scores: dict[str, tuple[float, float, float, str]] = {}
+ for source in ALIGNMENT_TYPES:
+ candidates = [
+ result
+ for swapped in (False, True)
+ if (result := assignment(source, query, target, swapped=swapped))
+ is not None
+ ]
+ if candidates:
+ backend_scores[source] = max(
+ candidates,
+ key=lambda result: result[0],
+ )
+ if not backend_scores:
+ continue
+ best_score = max(value[0] for value in backend_scores.values())
+ best_sources = [
+ source
+ for source, value in backend_scores.items()
+ if abs(value[0] - best_score) < 1e-12
+ ]
+ source = (
+ "both" if len(best_sources) == len(ALIGNMENT_TYPES) else best_sources[0]
+ )
+ mapping_source = (
+ "foldseek" if "foldseek" in best_sources else best_sources[0]
+ )
+ records.append(
+ {
+ "query_system": query.id,
+ "target_system": target.id,
+ "mapping": backend_scores[mapping_source][3],
+ "source": source,
+ "metric": "interface_qcov",
+ "iface1_qcov": backend_scores[mapping_source][1],
+ "iface2_qcov": backend_scores[mapping_source][2],
+ "similarity": max(0, min(100, round(best_score * 100))),
+ }
+ )
+ if not records:
+ return pd.DataFrame(columns=INTERFACE_SIMILARITY_SCHEMA.names)
+ return (
+ pd.DataFrame.from_records(records, columns=INTERFACE_SIMILARITY_SCHEMA.names)
+ .sort_values(
+ ["similarity", "query_system", "target_system"],
+ ascending=[False, True, True],
+ )
+ .reset_index(drop=True)
+ )
+
+
+def _validate_selection(
+ *,
+ entries: dict[str, EntryView],
+ query_system_ids: set[str],
+ target_system_ids: set[str],
+ query_ligand_ids: set[str] | None,
+ target_ligand_ids: set[str] | None,
+) -> None:
+ available_system_ids = {
+ system_id for entry in entries.values() for system_id in entry.systems
+ }
+ missing_system_ids = (query_system_ids | target_system_ids) - available_system_ids
+ if missing_system_ids:
+ raise KeyError(f"unknown system IDs: {sorted(missing_system_ids)}")
+
+ for name, selected, systems in [
+ ("query_ligand_ids", query_ligand_ids, query_system_ids),
+ ("target_ligand_ids", target_ligand_ids, target_system_ids),
+ ]:
+ if selected is None:
+ continue
+ missing = selected - _selected_ligand_ids(entries, systems)
+ if missing:
+ raise KeyError(
+ f"{name} do not belong to selected systems: {sorted(missing)}"
+ )
+
+
+def _canonical_ligand_resolver(
+ *, release_root: Path, data_dir: Path | None
+) -> Callable[[LigandView], Path | None]:
+ def resolve(ligand: LigandView) -> Path | None:
+ candidates = [
+ release_root
+ / "raw_entries"
+ / ligand.pdb_id[-3:-1]
+ / ligand.pdb_id
+ / "ligand_files"
+ / f"{ligand.asym_id}.sdf",
+ release_root
+ / "ligand_archives"
+ / ligand.pdb_id
+ / "ligand_files"
+ / f"{ligand.asym_id}.sdf",
+ ]
+ existing = next((path for path in candidates if path.is_file()), None)
+ if existing is not None:
+ return existing
+
+ code = ligand.pdb_id[-3:-1]
+ archive = _release_file(
+ "ligand_archive",
+ data_dir=data_dir,
+ description=f"canonical ligand archive for {code}",
+ shard=code,
+ )
+ packed = pd.read_parquet(
+ archive,
+ columns=["sdf"],
+ filters=[
+ ("pdb_id", "==", ligand.pdb_id),
+ ("ligand_asym_id", "==", ligand.asym_id),
+ ],
+ )
+ if len(packed) != 1:
+ return None
+ extracted = (
+ archive.parent / ligand.pdb_id / "ligand_files" / f"{ligand.asym_id}.sdf"
+ )
+ extracted.parent.mkdir(exist_ok=True, parents=True)
+ temporary = extracted.with_suffix(".tmp.sdf")
+ temporary.write_bytes(packed.iloc[0]["sdf"])
+ temporary.replace(extracted)
+ return extracted if extracted.is_file() else None
+
+ return resolve
+
+
+def reconstruct_similarity_scores(
+ query_system_ids: Iterable[str],
+ target_system_ids: Iterable[str],
+ *,
+ query_ligand_ids: Iterable[str] | None = None,
+ target_ligand_ids: Iterable[str] | None = None,
+ search_db: str = "holo",
+ include_shape: bool = True,
+ data_dir: Path | None = None,
+) -> pd.DataFrame:
+ """Reconstruct directed ligand-level scores for a bounded system subset.
+
+ Only mapped Foldseek/MMseqs shards and annotation rows for the requested
+ systems are loaded. Canonical ligand SDF archives are accessed lazily, and
+ only after a ligand pair has positive pocket coverage.
+ """
+ query_systems = set(query_system_ids)
+ target_systems = set(target_system_ids)
+ if not query_systems or not target_systems:
+ raise ValueError("query_system_ids and target_system_ids must not be empty")
+ query_ligands = set(query_ligand_ids) if query_ligand_ids is not None else None
+ target_ligands = set(target_ligand_ids) if target_ligand_ids is not None else None
+
+ alignment_paths = prefetch_similarity_alignments(
+ query_systems,
+ search_db=search_db,
+ data_dir=data_dir,
+ include_protein_scores=True,
+ )
+ selected_pdb_ids = {
+ _pdb_id(system_id) for system_id in query_systems | target_systems
+ }
+ entries, release_root = _load_entry_subset(
+ pdb_ids=selected_pdb_ids,
+ data_dir=data_dir,
+ )
+ _validate_selection(
+ entries=entries,
+ query_system_ids=query_systems,
+ target_system_ids=target_systems,
+ query_ligand_ids=query_ligands,
+ target_ligand_ids=target_ligands,
+ )
+ alignment_chain_lookup = _release_file(
+ "alignment_chain_lookup",
+ data_dir=data_dir,
+ description="alignment chain lookup",
+ )
+
+ # Imported lazily so ordinary score parquet queries do not import ingest
+ # machinery or RDKit shape-alignment code.
+ from plinder.data.annotations.get_similarity_scores import Scorer
+
+ scorer = Scorer(
+ entries=entries,
+ source_to_full_db_file={},
+ db_dir=release_root,
+ scores_dir=release_root,
+ alignment_chain_lookup=alignment_chain_lookup,
+ ligand_sdf_resolver=_canonical_ligand_resolver(
+ release_root=release_root,
+ data_dir=data_dir,
+ ),
+ )
+ frames: list[pd.DataFrame] = []
+ for pdb_id, paths in alignment_paths.items():
+ query_ids = {
+ system_id for system_id in query_systems if _pdb_id(system_id) == pdb_id
+ }
+ frame = scorer.aggregate_scores(
+ pdb_id,
+ search_db=search_db,
+ data_dir=release_root if include_shape else None,
+ source_to_aln_file={
+ f"{search_db}_{alignment_type}": path
+ for alignment_type, path in paths.items()
+ },
+ query_system_ids=query_ids,
+ query_ligand_ids=query_ligands,
+ target_system_ids=target_systems,
+ target_ligand_ids=target_ligands,
+ )
+ if frame is not None and not frame.empty:
+ frames.append(frame)
+
+ if not frames:
+ return pd.DataFrame(columns=PROTEIN_SIMILARITY_SCHEMA.names)
+ return (
+ pd.concat(frames, ignore_index=True)
+ .sort_values(
+ [
+ "similarity",
+ "query_system",
+ "query_ligand_id",
+ "target_system",
+ "target_ligand_id",
+ ],
+ ascending=[False, True, True, True, True],
+ )
+ .reset_index(drop=True)
+ )
+
+
+def reconstruct_interface_similarity_scores(
+ query_interface_ids: Iterable[str],
+ target_interface_ids: Iterable[str],
+ *,
+ search_db: str = "holo",
+ data_dir: Path | None = None,
+) -> pd.DataFrame:
+ """Reconstruct directed interface coverage for a bounded interface subset.
+
+ Only the mapped alignment shards for the requested query PDB entries and
+ chain and interface rows are loaded. The result is therefore
+ reconstructable from the compact public artifacts without the private
+ all-vs-all score table used for release clustering.
+ """
+ query_ids = set(query_interface_ids)
+ target_ids = set(target_interface_ids)
+ if not query_ids or not target_ids:
+ raise ValueError(
+ "query_interface_ids and target_interface_ids must not be empty"
+ )
+ alignment_paths = prefetch_similarity_alignments(
+ query_ids,
+ search_db=search_db,
+ data_dir=data_dir,
+ )
+ selected_pdb_ids = {_pdb_id(value) for value in query_ids | target_ids}
+ entries, _ = _load_entry_subset(
+ pdb_ids=selected_pdb_ids,
+ data_dir=data_dir,
+ )
+ query_interfaces = _selected_interfaces(entries, query_ids)
+ target_interfaces = _selected_interfaces(entries, target_ids)
+ alignments = _load_interface_alignments(
+ alignment_paths,
+ target_pdb_ids={interface.pdb_id for interface in target_interfaces.values()},
+ chain_lookup=_release_file(
+ "alignment_chain_lookup",
+ data_dir=data_dir,
+ description="alignment chain lookup",
+ ),
+ )
+ return calculate_interface_similarity_scores(
+ alignments,
+ query_interfaces=query_interfaces,
+ target_interfaces=target_interfaces,
+ )
diff --git a/src/plinder/core/scores/search.py b/src/plinder/core/scores/search.py
new file mode 100644
index 000000000..9e845e18a
--- /dev/null
+++ b/src/plinder/core/scores/search.py
@@ -0,0 +1,136 @@
+"""Search PLINDER using an input table, protein structures, or sequences."""
+
+from __future__ import annotations
+
+import shutil
+from collections.abc import Iterable
+from pathlib import Path
+from typing import Any, Literal
+
+import pandas as pd
+
+from plinder.core.release import PlinderRelease
+from plinder.core.scores.custom import (
+ CIF_SEARCH_BACKENDS,
+ CustomProteinSearchConfig,
+ CustomScoringResult,
+ CustomSequenceScoringResult,
+ score_custom_cif_files,
+ score_custom_sequence_file,
+)
+from plinder.core.structure.inputs import (
+ find_structure_files,
+ read_structure_table,
+ write_search_structure,
+)
+
+
+def search(
+ inputs: str | Path | pd.DataFrame,
+ *,
+ output_dir: str | Path,
+ release: PlinderRelease | None = None,
+ mode: Literal["auto", "pockets", "ligands", "interfaces", "both"] = "auto",
+ backends: Iterable[str] | None = None,
+ threads: int = 1,
+ search_config: CustomProteinSearchConfig | None = None,
+ plinder_entry_ids: Iterable[str] | None = None,
+ store_aligned_pocket_residues: bool = False,
+ include_monomers: bool = True,
+) -> CustomScoringResult | CustomSequenceScoringResult:
+ """Search with the same structure table accepted by evaluation.
+
+ Tables contain ``input_id``, ``structure_path`` and optional ``ligand_path``.
+ A receptor and its SDFs share an input ID; paths are relative to the table.
+ Complete mmCIFs use an empty ligand_path. ``reference_id`` is ignored here.
+
+ For ligand-free queries, pass a FASTA, one PDB/mmCIF, or a folder of those
+ structures. FASTA searches use MMseqs; structure searches use Foldseek and
+ MMseqs by default. ``mode='pockets'`` compares protein/pocket features,
+ ``'ligands'`` includes ligand similarities, and ``'interfaces'`` includes
+ protein interfaces. ``'both'`` includes both; ``'auto'`` uses applicable
+ features (ligand comparisons require a table).
+
+ PDB receptors contribute amino-acid residues, including modified amino acids;
+ other PDB components are omitted. Supply ligand poses through ``ligand_path``.
+
+ The returned result contains paths to score tables and alignment files.
+ ``chain_similarity_scores`` gives direct protein-chain hits, with query and
+ target coverage, identity, sequence similarity, and Foldseek lDDT as
+ integer percentages. FASTA results include the original ``sequence_id``.
+ With ``include_monomers=True``, chain hits also cover proteins outside
+ ligand pockets and protein interfaces. Pocket and interface scores still
+ use their own targets.
+ ``search_config`` controls search filters. Its shared ``evalue`` defaults to
+ 0.01; ``foldseek_evalue``, ``mmseqs_evalue`` and ``steam_evalue`` override it
+ independently for their respective backends.
+ Input IDs become custom structure IDs in these outputs. Generated ligand
+ chain IDs map to the original SDF paths in ``inputs/.ligands.tsv``.
+ """
+ if mode not in {"auto", "pockets", "ligands", "interfaces", "both"}:
+ raise ValueError("mode must be auto, pockets, ligands, interfaces or both")
+ output_dir = Path(output_dir).resolve()
+ common: dict[str, Any] = dict(
+ work_dir=output_dir,
+ data_dir=release.data_dir if release is not None else None,
+ threads=threads,
+ search_config=search_config,
+ plinder_entry_ids=plinder_entry_ids,
+ store_aligned_pocket_residues=store_aligned_pocket_residues,
+ include_monomers=include_monomers,
+ )
+ path = None if isinstance(inputs, pd.DataFrame) else Path(inputs).resolve()
+ if path is not None and path.name.lower().endswith(
+ (".fasta", ".fa", ".faa", ".fasta.gz", ".fa.gz", ".faa.gz")
+ ):
+ if mode not in {"auto", "pockets"}:
+ raise ValueError(
+ "FASTA inputs support pocket search; use structures for ligand/interface comparisons"
+ )
+ return score_custom_sequence_file(
+ path,
+ backends=tuple(backends) if backends is not None else ("mmseqs",),
+ **common,
+ )
+ is_table = path is None or path.suffix.lower() in {".csv", ".tsv", ".parquet"}
+ if is_table:
+ structures = read_structure_table(inputs)
+ else:
+ if mode in {"ligands", "both"}:
+ raise ValueError("Use an input table for ligand searches")
+ assert path is not None
+ rows = []
+ for file in find_structure_files(path):
+ name = file.stem if file.suffix.lower() == ".gz" else file.name
+ rows.append({"input_id": Path(name).stem, "structure_path": str(file)})
+ if not rows:
+ raise ValueError(f"No PDB/mmCIF structures found in {path}")
+ if len({row["input_id"] for row in rows}) != len(rows):
+ raise ValueError("Structure filenames must have unique basenames")
+ structures = read_structure_table(pd.DataFrame(rows))
+ include_ligands = is_table and mode in {"auto", "ligands", "both"}
+ sources = []
+ for input_id, structure in structures.items():
+ original = Path(structure.coordinates)
+ destination = output_dir / "inputs" / f"{input_id}.cif"
+ if structure.ligand_sdfs is None and original.suffix.lower() in {
+ ".cif",
+ ".mmcif",
+ }:
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ if original.resolve() != destination.resolve():
+ shutil.copyfile(original, destination)
+ else:
+ write_search_structure(
+ structure, destination, include_ligands=include_ligands
+ )
+ sources.append(destination)
+ return score_custom_cif_files(
+ sources,
+ backends=tuple(backends)
+ if backends is not None
+ else (("mmseqs",) if plinder_entry_ids is not None else CIF_SEARCH_BACKENDS),
+ include_ligands=None if mode == "auto" and include_ligands else include_ligands,
+ include_interfaces=None if mode == "auto" else mode in {"interfaces", "both"},
+ **common,
+ )
diff --git a/src/plinder/core/split/__init__.py b/src/plinder/core/split/__init__.py
deleted file mode 100644
index 7c8968d91..000000000
--- a/src/plinder/core/split/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from .utils import get_split
-
-__all__ = ["get_split"]
diff --git a/src/plinder/core/split/plot.py b/src/plinder/core/split/plot.py
deleted file mode 100644
index ebe774d80..000000000
--- a/src/plinder/core/split/plot.py
+++ /dev/null
@@ -1,832 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-from dataclasses import dataclass, field
-from pathlib import Path
-
-import numpy as np
-import pandas as pd
-
-from plinder.core.index.utils import get_plindex
-
-try:
- import matplotlib.pyplot as plt
- import mols2grid
- import seaborn as sns
- from matplotlib_venn import venn3
- from scipy.stats import ks_2samp
-except ImportError:
- raise ImportError("Please run: pip install plinder[plots] to use this module")
-
-
-from plinder.core.utils.log import setup_logger
-
-LOG = setup_logger(__name__)
-
-
-def get_ks_test(
- df1: pd.DataFrame, df2: pd.DataFrame, metric: str
-) -> tuple[float, float]:
- res = ks_2samp(
- df1[metric],
- df2[metric],
- method="auto",
- axis=0,
- nan_policy="omit",
- keepdims=False,
- )
- return res.statistic, res.pvalue
-
-
-def label_has_mms_within_subset(
- mms_df: pd.DataFrame, subset: set[str], minimum_count: int
-) -> tuple[pd.DataFrame, set[str]]:
- mms_df = mms_df[mms_df["system_id"].isin(subset)].reset_index(drop=True)
- LOG.info(
- f"mmp series after subset {len(mms_df.index)} records for {mms_df['system_id'].nunique()} systems"
- )
- # count number of unique ligands (not counting repeats)
- mms_count = mms_df.groupby("congeneric_id")["congeneric_ligand_ccd_code"].agg(
- "nunique"
- )
- mms_df["mms_unique_count"] = mms_df["congeneric_id"].map(mms_count)
- good_mms_systems = set(
- mms_df[mms_df["mms_unique_count"] >= minimum_count]["system_id"]
- )
- return mms_df, good_mms_systems
-
-
-@dataclass
-class SplitPropertiesPlotter:
- data_dir: Path
- split_file: Path
- output_dir: Path
- stratified_files: dict[str, Path] = field(default_factory=dict)
- plindex: pd.DataFrame = field(init=False)
- system_plindex: pd.DataFrame = field(init=False)
- mms_count: int = field(default=3)
- colors: dict[str, str] = field(
- default_factory=lambda: {
- "train": "#ff9999", # Light red
- "test": "#66b3ff", # Light blue
- "val": "#99ff99", # Light green
- "removed": "#d3d3d3", # Light grey
- "train_text": "red",
- "test_text": "blue",
- "val_text": "green",
- "False": "#D3D3D3",
- "True": "#99ff99",
- }
- )
- system_descriptors: dict[str, int | None] = field(
- default_factory=lambda: {
- # ligand
- "ligand_molecular_weight": 50,
- "ligand_tpsa": 10,
- "ligand_num_heavy_atoms": 5,
- "ligand_num_rot_bonds": 2,
- "ligand_num_rings": 1,
- "ligand_crippen_clogp": 1,
- # pocket
- "system_proper_num_pocket_residues": 5,
- # protein
- "system_protein_chains_total_length": None,
- }
- )
- priority_columns: list[str] = field(
- default_factory=lambda: [
- "system_has_binding_affinity",
- "system_has_mms",
- "system_has_apo_or_pred",
- "system_ligand_has_lipinski",
- "system_pass_validation_criteria",
- "system_pass_statistics_criteria",
- ]
- )
- domain_columns: list[str] = field(
- default_factory=lambda: [
- "system_pocket_ECOD_t_name",
- "system_pocket_CATH",
- "system_pocket_SCOP2B",
- "system_pocket_Pfam",
- ]
- )
- ligand_types: list[str] = field(
- default_factory=lambda: [
- f"system_ligand_has_{x}"
- for x in [
- "lipinski",
- "covalent",
- "cofactor",
- "oligo",
- "ion",
- "fragment",
- "artifact",
- "other",
- ]
- ]
- )
- diversity_columns: dict[str, str] = field(
- default_factory=lambda: {
- "system_id": "Systems",
- "entry_pdb_id": "PDB IDs",
- "system_proper_unique_ccd_codes": "Ligand CCD codes",
- "pli_unique_qcov__50__community": "PLI community",
- "pocket_qcov__50__community": "Pocket community",
- "tanimoto_similarity_max__50__community": "Ligand community",
- }
- )
-
- @classmethod
- def from_files(
- cls,
- data_dir: Path,
- split_file: Path,
- output_dir: Path = Path("split_plots"),
- plindex_file: Path | None = None,
- stratified_train_test_file: Path | None = None,
- stratified_train_val_file: Path | None = None,
- stratified_val_test_file: Path | None = None,
- mms_count: int = 3,
- make_plots: bool = True,
- ) -> "SplitPropertiesPlotter":
- stratified_files = {}
- if stratified_train_test_file is not None:
- stratified_files["train_vs_test"] = stratified_train_test_file
- if stratified_train_val_file is not None:
- stratified_files["train_vs_val"] = stratified_train_val_file
- if stratified_val_test_file is not None:
- stratified_files["val_vs_test"] = stratified_val_test_file
- plotter = cls(
- data_dir=data_dir,
- split_file=split_file,
- stratified_files=stratified_files,
- output_dir=output_dir,
- mms_count=mms_count,
- )
- if plindex_file is None:
- plindex = get_plindex().drop(columns=["split"])
- else:
- plindex = pd.read_parquet(plindex_file)
- plotter.plindex = plotter.merge_splits_and_plindex(plindex)
- plotter.system_plindex = plotter.plindex.drop_duplicates("system_id")
- plotter.merge_stratification()
- if make_plots:
- plotter.plot_all()
- return plotter
-
- def __post_init__(self) -> None:
- self.output_dir.mkdir(parents=True, exist_ok=True)
-
- def save_ligand_report_html(
- self,
- split_name: str,
- smiles_col: str = "ligand_rdkit_canonical_smiles",
- bg_color_col: str = "system_has_mms",
- sort_col: str = "system_id",
- ) -> None:
- color_col = f"tanimoto_similarity_max__train_vs_{split_name}"
- df = self.plindex[
- (self.plindex["split"] == split_name)
- & (~self.plindex["ligand_is_ion"])
- & (~self.plindex["ligand_is_artifact"])
- ]
- system_df = df.drop_duplicates("system_id")
- grouped_smiles_df = (
- df.groupby("system_id")[smiles_col].agg(list).apply(".".join).reset_index()
- )
- df = system_df.merge(grouped_smiles_df, on="system_id", suffixes=["_", ""])
-
- grid = mols2grid.MolGrid(
- df,
- smiles_col=smiles_col,
- )
- grid.save(
- self.output_dir / f"{split_name}.html",
- # rename columns for easier interpretation and formatting
- rename={
- "pli_unique_qcov__50__community": "PLI community ID",
- "tanimoto_similarity_max__50__community": "Ligand community ID",
- "tanimoto_similarity_max__30__community": "Ligand community ID",
- "system_num_protein_chains": "Receptor chain count",
- "system_proper_num_ligand_chains": "Ligand count",
- },
- # set what's displayed on the grid
- subset=[
- "system_id",
- "img",
- "Ligand community ID",
- "PLI community ID",
- color_col,
- ],
- # set what's displayed on the hover tooltip
- tooltip=[
- "Receptor chain count",
- "Ligand count",
- "system_has_binding_affinity",
- "system_has_mms",
- "system_has_apo_or_pred",
- "system_ligand_has_lipinski",
- "system_ligand_has_cofactor",
- ],
- n_items_per_page=48,
- # style for the grid labels and tooltips
- style={
- color_col: lambda x: "color: red; font-weight: bold;" if x > 30 else "",
- "__all__": lambda x: "background-color: azure;"
- if x[bg_color_col]
- else "",
- },
- transform={color_col: lambda x: round(x, 0)},
- # sort the grid in a different order by default
- sort_by=sort_col,
- )
-
- def merge_splits_and_plindex(self, plindex: pd.DataFrame) -> pd.DataFrame:
- split = pd.read_parquet(self.split_file)
- plindex = plindex[plindex["system_id"].isin(split["system_id"])].reset_index(
- drop=True
- )
- plindex = pd.merge(plindex, split, on="system_id", suffixes=("", "_y"))
- mms_df = pd.read_parquet(self.data_dir / "mmp/plinder_mmp_series.parquet")
- split_subdf = plindex[
- plindex["system_pass_validation_criteria"].fillna(False)
- ].drop_duplicates("system_id")
- good_mms_systems = set()
- for split in plindex["split"].unique():
- split_systems = set(
- split_subdf[split_subdf["split"] == split]["system_id"].unique()
- )
- good_mms_systems |= label_has_mms_within_subset(
- mms_df,
- split_systems,
- self.mms_count,
- )[1]
- plindex["system_has_mms"] = plindex["system_id"].isin(good_mms_systems)
-
- return plindex
-
- def merge_stratification(self) -> None:
- self.stratified = {
- split: pd.read_parquet(self.stratified_files[split])
- .drop_duplicates("system_id")
- .rename(
- mapper=lambda x: f"{x}__{split}"
- if x != "system_id" and "novel" not in x
- else x,
- axis=1,
- )
- for split in self.stratified_files
- }
- for split in self.stratified:
- self.system_plindex = self.system_plindex.merge(
- self.stratified[split],
- on="system_id",
- how="left",
- )
- self.plindex = self.plindex.merge(
- self.stratified[split],
- on="system_id",
- how="left",
- )
-
- def plot_ligands(self, split_names: list[str] = ["test", "val"]) -> None:
- plindex = self.plindex[
- self.plindex["ligand_is_proper"] & self.plindex["split"].isin(split_names)
- ]
- for split in split_names:
- ligand_df = plindex[plindex["split"] == split][
- ["system_id", "ligand_rdkit_canonical_smiles"]
- ].reset_index(drop=True)
- if split in self.stratified_files:
- stratified = pd.read_parquet(self.stratified_files[split])
- stratified["novel_ligand"] = stratified["tanimoto_similarity_max"] < 30
- ligand_df = ligand_df.merge(
- stratified[
- ["system_id", "tanimoto_similarity_max", "novel_ligand"]
- ],
- on="system_id",
- how="left",
- )
-
- print(f"{split}: {len(ligand_df)}")
-
- def plot_split_proportions(self) -> None:
- fig, ax = plt.subplots()
- counts = self.system_plindex["split"].value_counts()
- ax.pie(
- counts,
- labels=counts.index,
- autopct="%1.1f%%",
- colors=[self.colors[x] for x in counts.index],
- )
- ax.set_title("Split proportions")
- plt.savefig(self.output_dir / "split_proportions.png")
-
- def print_stratification_table(self) -> None:
- if len(self.stratified) == 0:
- LOG.info("No stratified data found, skipping stratification table")
- return
- stratified_dfs = {
- split: self.stratified[split][
- [c for c in self.stratified[split].columns if "novel" in c]
- ]
- .apply(lambda x: x.value_counts())
- .fillna(0)
- .astype(int)
- for split in self.stratified
- }
- df_combined = pd.concat(stratified_dfs.values(), keys=stratified_dfs.keys())
- df_combined = df_combined.reset_index().rename(columns={"level_0": "split"})
- df_combined = (
- df_combined[df_combined["level_1"]]
- .drop(columns=["level_1"])
- .reset_index(drop=True)
- )
- df_combined["total"] = df_combined["split"].apply(
- lambda x: self.system_plindex[
- self.system_plindex["split"] == x.split("_")[-1]
- ].shape[0]
- )
- df_combined["split"] = df_combined["split"].apply(
- lambda x: x.replace("_", " ").upper()
- )
- df_combined.to_csv(self.output_dir / "stratification_table.csv", index=False)
-
- def print_overall_diversity(self) -> None:
- cluster_df = pd.DataFrame(
- {
- col: self.system_plindex.groupby("split")[col].nunique()
- for col in self.diversity_columns
- }
- ).rename(columns=self.diversity_columns)
- cluster_df.to_csv(self.output_dir / "overall_diversity.csv", index=True)
-
- def plot_molecular_descriptors(
- self, val_label: str = "val", test_label: str = "test"
- ) -> None:
- fig, axes = self.get_axes(len(self.system_descriptors))
- plindex_to_use = self.plindex[self.plindex["ligand_is_proper"]].reset_index(
- drop=True
- )
- for i, prop in enumerate(self.system_descriptors):
- stat, pval = get_ks_test(
- plindex_to_use[plindex_to_use.split == val_label][[prop]],
- plindex_to_use[plindex_to_use.split == test_label][[prop]],
- metric=prop,
- )
- self.plot_hist_plot(
- plindex_to_use,
- prop,
- axes[i],
- )
- ks_info = f"KS test ({val_label}/{test_label}):\nstatistic = {stat:.3f}\np-value = {pval:.3e}"
- axes[i].text(
- 0.95,
- 0.05,
- ks_info,
- transform=axes[i].transAxes,
- verticalalignment="bottom",
- horizontalalignment="right",
- bbox=dict(boxstyle="round", facecolor="white", alpha=0.8),
- fontsize=8,
- )
- self.clear_unused_axes(axes, len(self.system_descriptors))
- plt.tight_layout()
- plt.savefig(self.output_dir / "molecular_descriptors.png")
-
- def plot_hist_plot(self, df: pd.DataFrame, plot_metric: str, ax: plt.Axes) -> None:
- if plot_metric.startswith("system"):
- df = df.drop(columns=["system_id"])
- sns.histplot(
- df,
- x=plot_metric,
- hue="split",
- hue_order=["train", "val", "test"],
- element="step",
- stat="density",
- common_norm=False,
- binwidth=self.system_descriptors[plot_metric],
- bins=None
- if self.system_descriptors[plot_metric]
- else np.linspace(0, 4, 50),
- log_scale=plot_metric.startswith("system_protein_chains_total_length"),
- ax=ax,
- palette=self.colors,
- )
- ax.set_xlabel("")
- name = (
- plot_metric.replace("system_", "")
- .replace("proper", "")
- .replace("ligand_", "")
- .replace("protein_chains_asym_id", "protein")
- .replace("protein_chains_", "")
- .replace("_", " ")
- .upper()
- )
- ax.set_title(name)
-
- def plot_priorities(self) -> None:
- fig, axes = self.get_axes(len(self.priority_columns))
-
- for idx, column in enumerate(self.priority_columns):
- column_data = self.system_plindex[["split", column]].astype(str)
- data = column_data.groupby("split")[column].value_counts()
- percentages = column_data.groupby("split")[column].value_counts(
- normalize=True
- )
- split_order = ["train", "val", "test", "removed"]
- percentages = percentages.reindex(split_order, level=0)
- unstacked = percentages.unstack().loc[split_order].fillna(0) * 100
- unstacked = unstacked[list(unstacked.columns)]
-
- unstacked.plot(
- kind="bar",
- stacked=True,
- ax=axes[idx],
- color=[self.colors[x] for x in unstacked.columns],
- rot=0,
- legend=False,
- )
-
- axes[idx].set_title(column.replace("system_", "").replace("_", " ").title())
- axes[idx].set_ylabel("Systems (%)")
- axes[idx].set_ylim(0, 100)
- axes[idx].set_xlabel("")
-
- names = percentages.index.get_level_values(0).unique()
- for c in axes[idx].containers:
- labels = []
- for v in names:
- key = (v, c.get_label())
- if key in data.index:
- labels.append(int(data[key]))
- else:
- labels.append(0)
- axes[idx].bar_label(c, labels=labels, label_type="center", fontsize=12)
- self.clear_unused_axes(axes, len(self.priority_columns))
- fig.suptitle("Priorities across splits", fontsize=16)
- handles, labels = axes[0].get_legend_handles_labels()
- fig.legend(handles, labels, loc="upper left", ncol=2)
- plt.tight_layout()
- plt.savefig(self.output_dir / "priorities.png")
-
- def plot_venn(self, column: str, ax: plt.Axes, label: str) -> None:
- per_split = {
- split: self.system_plindex[
- self.system_plindex[column].notna()
- & (self.system_plindex["split"] == split)
- ][["system_id", column]]
- for split in ["train", "val", "test"]
- }
-
- per_split_groups = {split: set(per_split[split][column]) for split in per_split}
-
- v = venn3(
- (
- per_split_groups["train"],
- per_split_groups["val"],
- per_split_groups["test"],
- ),
- set_labels=None,
- ax=ax,
- alpha=0.6,
- set_colors=(
- self.colors["train"],
- self.colors["val"],
- self.colors["test"],
- ),
- )
-
- for idx in ["100", "010", "001", "110", "101", "011", "111"]:
- if v.get_patch_by_id(idx):
- if idx == "100":
- groups = per_split_groups["train"] - (
- per_split_groups["val"] | per_split_groups["test"]
- )
- systems = {
- "train": per_split["train"][
- per_split["train"][column].isin(groups)
- ]
- }
- elif idx == "010":
- groups = per_split_groups["val"] - (
- per_split_groups["train"] | per_split_groups["test"]
- )
- systems = {
- "val": per_split["val"][per_split["val"][column].isin(groups)]
- }
- elif idx == "001":
- groups = per_split_groups["test"] - (
- per_split_groups["train"] | per_split_groups["val"]
- )
- systems = {
- "test": per_split["test"][
- per_split["test"][column].isin(groups)
- ]
- }
- elif idx == "110":
- groups = (
- per_split_groups["train"]
- & per_split_groups["val"] - per_split_groups["test"]
- )
- systems = {
- "train": per_split["train"][
- per_split["train"][column].isin(groups)
- ],
- "val": per_split["val"][per_split["val"][column].isin(groups)],
- }
- elif idx == "101":
- groups = (
- per_split_groups["train"]
- & per_split_groups["test"] - per_split_groups["val"]
- )
- systems = {
- "train": per_split["train"][
- per_split["train"][column].isin(groups)
- ],
- "test": per_split["test"][
- per_split["test"][column].isin(groups)
- ],
- }
- elif idx == "011":
- groups = (
- per_split_groups["val"]
- & per_split_groups["test"] - per_split_groups["train"]
- )
- systems = {
- "val": per_split["val"][per_split["val"][column].isin(groups)],
- "test": per_split["test"][
- per_split["test"][column].isin(groups)
- ],
- }
- elif idx == "111":
- groups = (
- per_split_groups["train"]
- & per_split_groups["val"]
- & per_split_groups["test"]
- )
- systems = {
- "train": per_split["train"][
- per_split["train"][column].isin(groups)
- ],
- "val": per_split["val"][per_split["val"][column].isin(groups)],
- "test": per_split["test"][
- per_split["test"][column].isin(groups)
- ],
- }
-
- n = len(groups)
- if n == 0:
- v.get_label_by_id(idx).set_text("")
- continue
- v.get_label_by_id(idx).set_text(str(n))
-
- x, y = v.get_label_by_id(idx).get_position()
- y += 0.06
- v.get_label_by_id(idx).set_position((x, y))
- for split in systems:
- n = len(systems[split])
- if n == 0:
- continue
- y -= 0.04
- ax.text(
- x,
- y,
- str(n),
- color=self.colors[f"{split}_text"],
- ha="center",
- va="center",
- )
-
- ax.set_title(label, fontsize=15)
-
- def plot_domain_classifications(self) -> None:
- fig, axes = self.get_axes(len(self.domain_columns))
- for i, c in enumerate(self.domain_columns):
- self.plot_venn(
- c, axes[i], c.replace("system_pocket_", "").replace("_", " ").upper()
- )
- self.clear_unused_axes(axes, len(self.domain_columns))
- fig.suptitle("Domain Classifications")
- plt.tight_layout()
- plt.savefig(self.output_dir / "domain_classifications.png")
-
- def get_axes(self, num_plots: int) -> tuple[plt.Figure, np.ndarray]:
- num_cols = int(np.ceil(np.sqrt(num_plots)))
- num_rows = int(np.ceil(num_plots / num_cols))
- fig, axes = plt.subplots(
- num_rows, num_cols, figsize=(5 * num_cols, 5 * num_rows)
- )
- return fig, axes.flatten()
-
- def clear_unused_axes(self, axes: np.ndarray, num_plots: int) -> None:
- for j in range(num_plots, len(axes)):
- axes[j].axis("off")
-
- def plot_clusters(self, cluster: str = "community", threshold: int = 50) -> None:
- cluster_names = [
- c
- for c in self.system_plindex.columns
- if c.endswith(f"__{threshold}__{cluster}")
- and "weighted_max" not in c
- and ("tanimoto" in c or "max" not in c)
- ]
-
- fig, axes = self.get_axes(len(cluster_names))
-
- for i, c in enumerate(cluster_names):
- name = (
- c.replace(f"__{threshold}__{cluster}", "")
- .replace("weighted_sum", "")
- .replace("max", "")
- )
- if name.startswith("protein"):
- name = name.replace("qcov", "global")
- else:
- name = name.replace("qcov", "shared")
- name = name.replace("_", " ").upper()
- self.plot_venn(
- c,
- axes[i],
- name,
- )
-
- self.clear_unused_axes(axes, len(cluster_names))
-
- fig.suptitle(f"Clusters ({cluster.capitalize()}, {threshold}%)", fontsize=16)
- plt.tight_layout()
- plt.savefig(self.output_dir / "plinder_clusters.png")
-
- def plot_ligand_types(self) -> None:
- counts_per_split = (
- self.system_plindex.groupby("split")[self.ligand_types]
- .mean()
- .mul(100)
- .to_dict()
- )
- labels = [
- c.replace("system_ligand_has_", "").capitalize() for c in self.ligand_types
- ]
- split_names = ["train", "val", "test", "removed"]
- fig, axes = self.get_axes(len(split_names))
-
- bar_colors = plt.cm.Pastel2.colors
- for i, split in enumerate(split_names):
- split_data = self.system_plindex[self.system_plindex["split"] == split]
- total_systems = len(split_data)
- percentages = [counts_per_split[c][split] for c in self.ligand_types]
- counts = [int(p / 100 * total_systems) for p in percentages]
-
- bars = axes[i].bar(
- np.arange(len(labels)),
- percentages,
- width=1,
- color=bar_colors,
- edgecolor="black",
- label=split,
- linewidth=1,
- )
- axes[i].set_xticks(np.arange(len(labels)))
- axes[i].set_xticklabels(labels, rotation=70)
- axes[i].set_ylim(0, 100)
- axes[i].set_title(f"{split.capitalize()} (Total: {total_systems})")
-
- # Add count labels to bars
- for bar, count in zip(bars, counts):
- axes[i].text(
- bar.get_x() + bar.get_width() / 2.0,
- bar.get_height() + 2,
- f"{count}",
- ha="center",
- va="bottom",
- rotation=70,
- fontsize=10,
- )
- fig.suptitle("Distribution of Ligand Types Contained in Systems")
- self.clear_unused_axes(axes, len(split_names))
- plt.tight_layout()
- plt.savefig(self.output_dir / "ligand_types.png")
-
- def plot_chain_composition(self) -> None:
- split_names = ["train", "val", "test", "removed"]
- fig, axes = self.get_axes(len(split_names))
-
- for i, split in enumerate(split_names):
- split_stats = self.system_plindex[self.system_plindex["split"] == split][
- [
- "system_num_protein_chains",
- "system_proper_num_ligand_chains",
- ]
- ]
- counts = {
- "Single Protein & Single Ligand": split_stats[
- (split_stats["system_num_protein_chains"] == 1)
- & (split_stats["system_proper_num_ligand_chains"] == 1)
- ].shape[0],
- "Single Protein & Multiple Ligands": split_stats[
- (split_stats["system_num_protein_chains"] == 1)
- & (split_stats["system_proper_num_ligand_chains"] > 1)
- ].shape[0],
- "Multiple Proteins & Single Ligand": split_stats[
- (split_stats["system_proper_num_ligand_chains"] == 1)
- & (split_stats["system_num_protein_chains"] > 1)
- ].shape[0],
- "Multiple Proteins & Multiple Ligands": split_stats[
- (split_stats["system_proper_num_ligand_chains"] > 1)
- & (split_stats["system_num_protein_chains"] > 1)
- ].shape[0],
- }
-
- wedges, texts, autotexts = axes[i].pie(
- list(counts.values()),
- colors=plt.cm.Pastel2.colors,
- autopct=lambda pct: f"{pct:.1f}%\n{int(pct/100.*sum(counts.values())):d}",
- textprops={"fontsize": 8},
- wedgeprops={"linewidth": 0.5, "edgecolor": "black"},
- )
- axes[i].set_title(f"{split.capitalize()} ({sum(counts.values())})")
-
- self.clear_unused_axes(axes, len(split_names))
- fig.suptitle("System Chain Composition")
- fig.legend(wedges, list(counts.keys()), loc="lower center", ncol=2)
- plt.tight_layout()
- plt.savefig(self.output_dir / "chain_composition.png")
-
- def plot_all(self) -> None:
- self.plot_split_proportions()
- self.print_stratification_table()
- try:
- if "train_vs_test" in self.stratified.keys():
- self.save_ligand_report_html("test")
- if "train_vs_val" in self.stratified.keys():
- self.save_ligand_report_html("val")
- except Exception as e:
- LOG.error(f"error saving ligand report: {e}")
- self.print_overall_diversity()
- self.plot_molecular_descriptors()
- self.plot_priorities()
- self.plot_domain_classifications()
- self.plot_clusters()
- self.plot_ligand_types()
- self.plot_chain_composition()
-
-
-def main() -> None:
- import argparse
-
- parser = argparse.ArgumentParser(description="Compare split properties")
- parser.add_argument(
- "--split_file",
- type=Path,
- help="Path to split file",
- )
- parser.add_argument(
- "--data_dir",
- type=Path,
- help="Path to plinder data",
- )
- parser.add_argument(
- "--stratified_train_test_file",
- type=Path,
- help="Path to stratified train vs test file",
- )
- parser.add_argument(
- "--stratified_train_val_file",
- type=Path,
- help="Path to stratified train vs val file",
- )
- parser.add_argument(
- "--stratified_val_test_file",
- type=Path,
- help="Path to stratified val vs test file",
- )
- parser.add_argument(
- "--output_dir",
- type=Path,
- help="Path to output directory",
- default=Path("split_plots"),
- )
- parser.add_argument(
- "--mms_count",
- type=int,
- help="Number of systems to consider as an MMS",
- default=3,
- )
-
- args = parser.parse_args()
-
- SplitPropertiesPlotter.from_files(
- split_file=args.split_file,
- data_dir=args.data_dir,
- stratified_train_test_file=args.stratified_train_test_file,
- stratified_train_val_file=args.stratified_train_val_file,
- stratified_val_test_file=args.stratified_val_test_file,
- mms_count=args.mms_count,
- output_dir=args.output_dir,
- )
-
-
-if __name__ == "__main__":
- main()
diff --git a/src/plinder/core/split/utils.py b/src/plinder/core/split/utils.py
deleted file mode 100644
index 34411e678..000000000
--- a/src/plinder/core/split/utils.py
+++ /dev/null
@@ -1,42 +0,0 @@
-from typing import Optional
-
-import pandas as pd
-from omegaconf import DictConfig
-
-from plinder.core.utils import cpl
-from plinder.core.utils.config import get_config
-from plinder.core.utils.dec import timeit
-from plinder.core.utils.log import setup_logger
-
-LOG = setup_logger(__name__)
-
-_SPLIT = None
-
-
-@timeit
-def get_split(
- *,
- cfg: Optional[DictConfig] = None,
-) -> pd.DataFrame:
- """
- Fetch the plinder split and cache it
-
- Parameters
- ----------
- cfg : DictConfig, default=None
- the plinder-core config
-
- Returns
- -------
- pd.DataFrame
- the plinder split
- """
- global _SPLIT
- if _SPLIT is not None:
- return _SPLIT
- cfg = cfg or get_config()
- suffix = f"{cfg.data.splits}/{cfg.data.split_file}"
- split = cpl.get_plinder_path(rel=suffix)
- LOG.info(f"reading {split}")
- _SPLIT = pd.read_parquet(split)
- return _SPLIT
diff --git a/src/plinder/core/structure/atoms.py b/src/plinder/core/structure/atoms.py
index f0793d7af..b9db31480 100644
--- a/src/plinder/core/structure/atoms.py
+++ b/src/plinder/core/structure/atoms.py
@@ -3,23 +3,19 @@
from __future__ import annotations
import gzip
+from collections.abc import Iterable, Sequence
from pathlib import Path
from typing import Any, Union
+import biotite.sequence as seq
+import biotite.sequence.align as align
import numpy as np
from biotite import TextFile
from biotite.structure import get_residues
from biotite.structure.atoms import AtomArray, AtomArrayStack
-from biotite.structure.io.pdbx import get_structure
+from biotite.structure.io.pdbx import CIFFile, get_structure, set_structure
from numpy.typing import NDArray
-from rdkit.Chem import Mol
-
-from plinder.core.structure.vendored import (
- _convert_resn_to_sequence_and_numbering,
- _get_structure_and_res_info,
- align_sequences,
- apply_mask,
-)
+
from plinder.core.utils import constants as pc
from plinder.core.utils.log import setup_logger
@@ -99,57 +95,111 @@ def atom_array_from_cif_file(
return structure
+def write_cif(arr: AtomArray, filepath: Path) -> None:
+ """Write an AtomArray to an mmCIF file whose data block is the file stem."""
+ filepath = Path(filepath)
+ if filepath.suffix != ".cif":
+ raise ValueError(f"mmCIF output must end in .cif, got {filepath}")
+ filepath.parent.mkdir(exist_ok=True, parents=True)
+ cif_file = CIFFile()
+ set_structure(cif_file, arr, data_block=filepath.stem)
+ cif_file.write(str(filepath))
+
+
+def apply_mask(atoms: _AtomArrayOrStack, mask: NDArray[np.bool_]) -> _AtomArrayOrStack:
+ """Filter the atoms of an AtomArray or AtomArrayStack with a boolean mask."""
+ if isinstance(atoms, AtomArray):
+ return atoms[mask]
+ if isinstance(atoms, AtomArrayStack):
+ return atoms[..., mask]
+ raise TypeError("atoms must be an AtomArray or AtomArrayStack")
+
+
+def resn2seq(resn: Iterable[str]) -> str:
+ """Convert residue names to one-letter code, with ``X`` for unknown names.
+
+ Selenocysteine and pyrrolysine become cysteine and lysine because
+ biotite's protein alphabet has no ``U`` or ``O``.
+ """
+ three_to_one = pc.three_to_one_noncanonical_mapping
+ substitutions = {"U": "C", "O": "K"}
+ return "".join(
+ substitutions.get(one, one)
+ for one in (three_to_one.get(three, "X") for three in resn)
+ )
+
+
+def align_sequences(
+ ref_seq: str,
+ subject_seq: str,
+ ref_numbering: Sequence[int] | None = None,
+ subject_numbering: Sequence[int] | None = None,
+) -> tuple[str, str, list[int], list[int]]:
+ """Globally align two sequences and return their matched residues.
+
+ The alignment uses BLOSUM62 with affine gap penalties and no terminal
+ penalty. Only positions where both sequences carry a known residue are
+ kept, and returned as the two mapped sequences plus their residue
+ numbering (1-based unless numbering is given).
+ """
+ alignment = align.align_optimal(
+ seq.ProteinSequence(subject_seq),
+ seq.ProteinSequence(ref_seq),
+ align.SubstitutionMatrix.std_protein_matrix(),
+ gap_penalty=(-10, -1),
+ terminal_penalty=False,
+ local=False,
+ max_number=1,
+ )[0]
+ subject_symbols, ref_symbols = align.get_symbols(alignment)
+ if ref_numbering is None:
+ ref_numbering = list(range(1, len(ref_seq) + 1))
+ if subject_numbering is None:
+ subject_numbering = list(range(1, len(subject_seq) + 1))
+ ref_mapped = ""
+ subject_mapped = ""
+ ref_numbering_mapped: list[int] = []
+ subject_numbering_mapped: list[int] = []
+ ref_index = -1
+ subject_index = -1
+ for subject_symbol, ref_symbol in zip(subject_symbols, ref_symbols):
+ if ref_symbol:
+ ref_index += 1
+ if subject_symbol:
+ subject_index += 1
+ if ref_symbol and subject_symbol and "X" not in (ref_symbol, subject_symbol):
+ ref_numbering_mapped.append(int(ref_numbering[ref_index]))
+ subject_numbering_mapped.append(int(subject_numbering[subject_index]))
+ ref_mapped += ref_symbol
+ subject_mapped += subject_symbol
+ return ref_mapped, subject_mapped, ref_numbering_mapped, subject_numbering_mapped
+
+
def get_residue_index_mapping_mask(
ref_seqs: dict[str, str], subject_arr: _AtomArrayOrStack
-) -> dict[str, list[int]]:
+) -> dict[str, NDArray[np.float64]]:
+ """Mark which reference-sequence positions are resolved in each chain."""
mask_map = {}
- for reference_chain, ref_seq in ref_seqs.items():
- # refernece and subject chain are the same
- subject_chain = reference_chain
- subject_mask = subject_arr.chain_id == subject_chain
- subject_ch_arr = apply_mask(subject_arr, subject_mask)
-
- subj_info = _get_structure_and_res_info(subject_ch_arr)
- subj_seq, subj_numbering = _convert_resn_to_sequence_and_numbering(subj_info)
- alignments = align_sequences(
- ref_seq, subj_seq, ref_numbering=None, subject_numbering=subj_numbering
+ for chain, ref_seq in ref_seqs.items():
+ # The reference and subject chain IDs are the same.
+ subject_ch_arr = apply_mask(subject_arr, subject_arr.chain_id == chain)
+ subj_numbering, subj_resn = get_residues(subject_ch_arr)
+ _, _, ref_numbering_mapped, _ = align_sequences(
+ ref_seq,
+ resn2seq(subj_resn),
+ subject_numbering=subj_numbering.tolist(),
)
- (
- _,
- _,
- ref_numbering_mapped,
- _,
- ) = alignments
+ resolved = set(ref_numbering_mapped)
mask = np.zeros(len(ref_seq))
for i in range(len(mask)):
- if (i + 1) in ref_numbering_mapped:
+ if (i + 1) in resolved:
mask[i] = 1
- mask_map[reference_chain] = mask
+ mask_map[chain] = mask
return mask_map
-def get_ligand_atom_index_mapping_mask(
- ref_mol: Mol, matching_indices: tuple[int, ...]
-) -> NDArray[np._int]:
- mask = np.zeros(len(ref_mol.GetAtoms()))
- for atm_idx in range(len(mask)):
- if atm_idx in matching_indices:
- mask[atm_idx] = 1
- return mask
-
-
-def make_one_hot_atom_features(atom_name: list[str]) -> list[int]:
- allowed_atom_names = ["C", "N", "O", "S", "P"]
- striped_atom_name = "".join(filter(lambda x: not x.isdigit(), atom_name))[0]
- return [1 if striped_atom_name == atm else 0 for atm in allowed_atom_names]
-
-
-def _convert_pdb_atom_name_to_elem_symbol(atom_name: str) -> str:
- return "".join(filter(lambda x: not x.isdigit(), atom_name))[0]
-
-
def get_per_residue_mask(
- residue_reference_atom_list: list[str], atom_list: list[str]
+ residue_reference_atom_list: Sequence[str], atom_list: Sequence[str]
) -> list[int]:
res_mask = [1 if i in atom_list else 0 for i in residue_reference_atom_list]
return res_mask
@@ -158,13 +208,16 @@ def get_per_residue_mask(
def get_per_residue_atoms(
atom_array: _AtomArrayOrStack, resi: int, resn: str
) -> NDArray[np.str_]:
- return atom_array[
- (atom_array.res_id == resi) & (atom_array.res_name == resn)
- ].atom_name
+ return np.asarray(
+ atom_array[
+ (atom_array.res_id == resi) & (atom_array.res_name == resn)
+ ].atom_name,
+ dtype=np.str_,
+ )
def make_atom_mask(
- atom_array: _AtomArrayOrStack, seq_res: str, seq_mask: list[int]
+ atom_array: _AtomArrayOrStack, seq_res: str, seq_mask: Sequence[int | float]
) -> list[int]:
seq_res_three_aa = [pc.ONE_TO_THREE[aa] for aa in seq_res]
resi, resn = get_residues(atom_array)
@@ -180,7 +233,7 @@ def make_atom_mask(
atom_mask.append(
get_per_residue_mask(
pc.ORDERED_AA_FULL_ATOM[resn],
- get_per_residue_atoms(atom_array, resi, resn),
+ get_per_residue_atoms(atom_array, resi, resn).tolist(),
)
)
return [atm for res in atom_mask for atm in res]
@@ -190,7 +243,7 @@ def _stack_atom_array_features(
atom_arr: _AtomArrayOrStack,
atom_arr_feat: str,
chain_order_list: list[str] | None,
-) -> list[NDArray[np.int_ | np.str_ | np.float_]]:
+) -> list[NDArray[Any]]:
assert chain_order_list is not None
return [
getattr(atom_arr[atom_arr.chain_id == chain], atom_arr_feat)
@@ -206,15 +259,19 @@ def _stack_ligand_feat(
def _one_hot_encode_stack(
- stack: list[NDArray],
+ stack: list[NDArray[Any]],
feature_dict: dict[str, int],
unknown_name_filler: str,
-) -> list[NDArray]:
+) -> list[NDArray[np.float64]]:
feat_array = []
unknown_name_filler_value = feature_dict[unknown_name_filler]
for per_chain_feat in stack:
feat_array_by_chain = np.zeros(
- (len(per_chain_feat), len(set(list(feature_dict.values()))))
+ (
+ len(per_chain_feat),
+ len(set(list(feature_dict.values()))),
+ ),
+ dtype=np.float64,
)
for index, value in enumerate(per_chain_feat):
feat_array_by_chain[
@@ -222,17 +279,3 @@ def _one_hot_encode_stack(
] = 1.0
feat_array.append(feat_array_by_chain)
return feat_array
-
-
-def _sequence_full_atom_type_array(
- input_sequences: dict[str, str]
-) -> dict[str, NDArray]:
- """Resolved sequence full atom features."""
- seq_atom_dict = {}
- for chain, sequence in input_sequences.items():
- feat = []
- for res in sequence:
- for atom in pc.ORDERED_AA_FULL_ATOM[pc.ONE_TO_THREE[res]]:
- feat.append(_convert_pdb_atom_name_to_elem_symbol(atom))
- seq_atom_dict[chain] = np.array(feat)
- return seq_atom_dict
diff --git a/src/plinder/core/structure/ccd_template.py b/src/plinder/core/structure/ccd_template.py
new file mode 100644
index 000000000..c3bb8f689
--- /dev/null
+++ b/src/plinder/core/structure/ccd_template.py
@@ -0,0 +1,277 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""CCD component templates: missing-atom detection and opt-in completion."""
+
+from __future__ import annotations
+
+from collections.abc import Collection, Iterable
+from functools import cache
+from typing import NamedTuple
+
+import biotite.structure as struc
+import numpy as np
+from biotite.structure.atoms import AtomArray
+
+from plinder.core.utils.log import setup_logger
+
+LOG = setup_logger(__name__)
+
+UNRESOLVED_ANNOTATION = "is_unresolved"
+
+
+class ComponentTemplate(NamedTuple):
+ heavy: tuple[str, ...] # heavy atom names in CCD order
+ elements: dict[str, str]
+ leaving: frozenset[str]
+ bonds: tuple[tuple[str, str, int], ...] # heavy-heavy bonds by atom name
+
+
+@cache
+def ccd_component_template(comp_id: str) -> ComponentTemplate | None:
+ """Heavy atoms, elements, leaving atoms and bonds of a CCD component."""
+ from biotite.structure.info import ccd as bundled_ccd
+
+ from plinder.data.annotations.cif_utils import _get_ccd_atomarray
+
+ template = _get_ccd_atomarray(comp_id) # the one CCD accessor; warns on failure
+ if template is None:
+ return None
+ chem_comp_atom = bundled_ccd.get_ccd()["chem_comp_atom"]
+ heavy_mask = struc.filter_heavy(template)
+ heavy = tuple(str(name) for name in template.atom_name[heavy_mask])
+ elements = {
+ str(name): str(element)
+ for name, element in zip(template.atom_name, template.element)
+ }
+ rows = chem_comp_atom["comp_id"].as_array(str) == comp_id
+ leaving = frozenset(
+ chem_comp_atom["atom_id"].as_array(str)[rows][
+ chem_comp_atom["pdbx_leaving_atom_flag"].as_array(str)[rows] == "Y"
+ ]
+ )
+ bonds: list[tuple[str, str, int]] = []
+ if template.bonds is not None:
+ heavy_set = set(heavy)
+ for index_a, index_b, order in template.bonds.as_array():
+ name_a, name_b = (
+ str(template.atom_name[index_a]),
+ str(template.atom_name[index_b]),
+ )
+ if name_a in heavy_set and name_b in heavy_set:
+ bonds.append((name_a, name_b, int(order)))
+ return ComponentTemplate(heavy, elements, leaving, tuple(bonds))
+
+
+def ccd_heavy_atom_names(comp_id: str) -> tuple[frozenset[str], frozenset[str]] | None:
+ """Heavy atom names and leaving-group atom names of a CCD component."""
+ template = ccd_component_template(comp_id)
+ if template is None:
+ return None
+ return frozenset(template.heavy), template.leaving
+
+
+def departed_leaving_atoms(
+ template: ComponentTemplate, linked_atom_names: Collection[str]
+) -> frozenset[str]:
+ """Leaving atoms whose anchor atom is bonded outside the residue, i.e. gone on linkage."""
+ return frozenset(
+ leaving
+ for name_a, name_b, _ in template.bonds
+ for leaving, anchor in ((name_a, name_b), (name_b, name_a))
+ if leaving in template.leaving and anchor in linked_atom_names
+ )
+
+
+def linked_atoms_by_residue(
+ atoms: AtomArray, starts: np.ndarray
+) -> dict[int, set[str]]:
+ """Residue start index -> names of its atoms bonded to another residue.
+
+ ``starts`` are residue starts with the exclusive stop appended.
+ """
+ linked: dict[int, set[str]] = {}
+ if atoms.bonds is None:
+ return linked
+ bonds = atoms.bonds.as_array()[:, :2]
+ residue_of = np.searchsorted(starts[:-1], bonds, side="right") - 1
+ crossing = residue_of[:, 0] != residue_of[:, 1]
+ for column in (0, 1):
+ for index, residue in zip(
+ bonds[crossing, column], residue_of[crossing, column]
+ ):
+ linked.setdefault(int(starts[residue]), set()).add(
+ str(atoms.atom_name[index])
+ )
+ return linked
+
+
+def unresolved_atoms_from_template(
+ comp_id: str,
+ resolved_atom_names: Iterable[str],
+ linked_atom_names: Collection[str] | None = None,
+) -> list[str] | None:
+ """CCD heavy atoms absent from ``resolved_atom_names``.
+
+ Leaving atoms whose anchor is in ``linked_atom_names`` (atoms bonded outside
+ the residue) departed on linkage and are not missing; with
+ ``linked_atom_names=None`` every leaving atom is excluded. ``None`` when
+ ``comp_id`` is not in the CCD.
+ """
+ template = ccd_component_template(comp_id)
+ if template is None:
+ return None
+ excluded = (
+ template.leaving
+ if linked_atom_names is None
+ else departed_leaving_atoms(template, linked_atom_names)
+ )
+ resolved = set(resolved_atom_names)
+ return [
+ name for name in template.heavy if name not in excluded and name not in resolved
+ ]
+
+
+def add_missing_atoms(
+ atoms: AtomArray, *, mask_annotation: str = UNRESOLVED_ANNOTATION
+) -> AtomArray:
+ """Append CCD heavy atoms missing from each residue, with NaN coordinates.
+
+ A residue is completed only when its CCD template is known and every
+ resolved heavy atom name is a template name; hydrogens are never added,
+ leaving atoms only for a non-polymer residue not bonded through their anchor
+ (never when ``atoms`` has no bonds), and fully unresolved residues are not
+ created. Added atoms copy
+ their residue's annotations, take ``element`` from the CCD, get
+ ``occupancy``/``b_factor``/``charge`` 0 where present, and ``mask_annotation``
+ True (deposited atoms get False). Existing bonds are kept and the template
+ bonds of added atoms appended. The input is not modified.
+ """
+ count = atoms.array_length()
+ starts = struc.get_residue_starts(atoms, add_exclusive_stop=True)
+ solvent = struc.filter_solvent(atoms)
+ hydrogen = ~struc.filter_heavy(atoms)
+ linked = linked_atoms_by_residue(atoms, starts) if atoms.bonds is not None else None
+ polymer = struc.filter_amino_acids(atoms) | struc.filter_nucleotides(atoms)
+ completed: list[tuple[int, int, list[str], ComponentTemplate]] = []
+ mismatched = 0
+ for start, stop in zip(starts[:-1], starts[1:]):
+ if solvent[start]:
+ continue
+ template = ccd_component_template(str(atoms.res_name[start]))
+ if template is None:
+ continue
+ resolved = {
+ str(name)
+ for name, is_h in zip(atoms.atom_name[start:stop], hydrogen[start:stop])
+ if not is_h
+ }
+ if not resolved <= set(template.heavy):
+ mismatched += 1
+ continue
+ excluded = (
+ template.leaving
+ if linked is None or polymer[start]
+ else departed_leaving_atoms(template, linked.get(int(start), set()))
+ )
+ missing = [
+ name
+ for name in template.heavy
+ if name not in excluded and name not in resolved
+ ]
+ if missing:
+ completed.append((int(start), int(stop), missing, template))
+
+ categories = atoms.get_annotation_categories()
+ existing_mask = (
+ atoms.get_annotation(mask_annotation).astype(bool)
+ if mask_annotation in categories
+ else np.zeros(count, dtype=bool)
+ )
+ if not completed:
+ result = atoms.copy()
+ result.set_annotation(mask_annotation, existing_mask)
+ if mismatched:
+ LOG.info(
+ "add_missing_atoms: %d residues skipped, names off-template", mismatched
+ )
+ return result
+
+ positions = np.concatenate(
+ [np.full(len(missing), stop) for _, stop, missing, _ in completed]
+ )
+ sources = np.concatenate(
+ [np.full(len(missing), start) for start, _, missing, _ in completed]
+ )
+ new_names = np.array(
+ [name for _, _, missing, _ in completed for name in missing], dtype=str
+ )
+ new_elements = np.array(
+ [
+ template.elements[name]
+ for _, _, missing, template in completed
+ for name in missing
+ ],
+ dtype=str,
+ )
+ added = len(positions)
+ result = struc.AtomArray(count + added)
+ result.coord = np.insert(
+ atoms.coord,
+ positions,
+ np.full((added, 3), np.nan, dtype=atoms.coord.dtype),
+ axis=0,
+ )
+ for category in categories:
+ values = atoms.get_annotation(category)
+ if category == "atom_name":
+ fill = new_names
+ elif category == "element":
+ fill = new_elements
+ elif category in {"occupancy", "b_factor", "charge"}:
+ fill = np.zeros(added, dtype=values.dtype)
+ elif category == mask_annotation:
+ continue
+ else:
+ fill = values[sources]
+ result.set_annotation(category, np.insert(values, positions, fill))
+ result.set_annotation(
+ mask_annotation, np.insert(existing_mask, positions, np.ones(added, dtype=bool))
+ )
+
+ if atoms.bonds is not None:
+ new_index = np.arange(count) + np.searchsorted(
+ positions, np.arange(count), "right"
+ )
+ bonds = atoms.bonds.as_array()
+ remapped = bonds.copy()
+ remapped[:, 0] = new_index[bonds[:, 0]]
+ remapped[:, 1] = new_index[bonds[:, 1]]
+ extra: list[list[int]] = []
+ for start, stop, missing, template in completed:
+ index_by_name = {
+ str(name): int(new_index[i])
+ for i, name in zip(range(start, stop), atoms.atom_name[start:stop])
+ }
+ first_new = int(new_index[stop - 1]) + 1
+ index_by_name.update(
+ {name: first_new + k for k, name in enumerate(missing)}
+ )
+ for name_a, name_b, order in template.bonds:
+ if (
+ (name_a in missing or name_b in missing)
+ and name_a in index_by_name
+ and name_b in index_by_name
+ ):
+ extra.append([index_by_name[name_a], index_by_name[name_b], order])
+ all_bonds = (
+ np.vstack([remapped, np.array(extra, dtype=int)]) if extra else remapped
+ )
+ result.bonds = struc.BondList(count + added, all_bonds)
+
+ LOG.info(
+ "add_missing_atoms: added %d atoms to %d residues; %d residues skipped, names off-template",
+ added,
+ len(completed),
+ mismatched,
+ )
+ return result
diff --git a/src/plinder/core/structure/contacts.py b/src/plinder/core/structure/contacts.py
deleted file mode 100644
index 82cce0bfc..000000000
--- a/src/plinder/core/structure/contacts.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-from itertools import combinations
-from typing import Any, List, NamedTuple, Set, Tuple, Union
-
-import biotite.structure as struc
-import numpy as np
-import pandas as pd
-from biotite.structure.atoms import AtomArray
-from numpy.typing import NDArray
-
-from plinder.core.utils.log import setup_logger
-
-_Contacts = Set[Tuple[str, str, int, int]]
-_StackContacts = List[_Contacts]
-_AtomResContacts = Union[Tuple[_Contacts, _Contacts], _Contacts]
-_StackAtomResContacts = Union[Tuple[_StackContacts, _StackContacts], _StackContacts]
-
-
-class ContactPairs(NamedTuple):
- residue_contacts: _Contacts
- atom_contacts: _Contacts
-
-
-log = setup_logger(__name__)
-
-
-def get_atoms_within_coordinate(
- atom_array: AtomArray | NDArray[np.double],
- coords: NDArray[np.double],
- radius: float,
- cell_size: float | None = None,
- as_mask: bool = False,
-) -> NDArray[np.int_]:
- """
- Find atom indices (contact matrix) within distance of coords.
-
- Parameters
- ----------
- atom_array : AtomArray | NDArray[np.double]
- The array of atoms representing the protein structure.
- coords : NDArray[np.double]
- The coordinates to find atoms within.
- radius : float
- The radius within which to consider atoms as being in contact.
- cell_size : float
- The size of the cell for the cell list.
- as_mask : bool, optional
- Whether to return the contacts as a mask, by default False.
-
- Returns
- -------
- NDArray[np.int_]
- The contact indices.
- """
- cell_list = struc.CellList(atom_array, cell_size=cell_size)
- contacts: NDArray[np.int_] = cell_list.get_atoms(
- coords.reshape(-1, coords.shape[-1]), radius=radius, as_mask=False
- )
- return contacts
-
-
-def get_atom_neighbors(
- atom_array: AtomArray,
- query_array: AtomArray,
- radius: float,
- cell_size: float | None = None,
- as_mask: bool = False,
-) -> AtomArray:
- """
- Find atoms within a specified distance of coordinates.
-
- Parameters
- ----------
- atom_array : AtomArray
- The array of atoms.
- query_array : AtomArray
- The array of query atoms.
- radius : float
- The radius within which to find neighboring atoms.
- cell_size : float or None, optional
- The cell size for the cell list, by default None. If None, the radius is used as the cell size.
- as_mask : bool, optional
- Whether to return the contacts as a mask, by default False.
-
- Returns
- -------
- AtomArray
- The array of neighboring atoms.
- """
- if not cell_size:
- cell_size = radius
- contacts = get_atoms_within_coordinate(
- atom_array=query_array,
- coords=atom_array.coord,
- radius=radius,
- cell_size=cell_size,
- as_mask=as_mask,
- )
- neighbor_atoms = set()
- for at_idx, j in np.argwhere(contacts >= 0.0):
- neighbor_atoms.add(at_idx)
-
- return atom_array[list(neighbor_atoms)]
-
-
-def get_binder_residues_atom_array(
- structure: AtomArray, binder_chains_resids: list[tuple[str, int]]
-) -> AtomArray:
- struc_info = [(atm.chain_id, atm.res_id) for atm in structure]
- return structure[
- np.array([(sinfo in binder_chains_resids) for sinfo in struc_info])
- ]
-
-
-def get_contact_df(
- prot_arr: AtomArray,
- ch_combos: List[Tuple[Tuple[Any, Any], Any]],
- lig_arr: AtomArray | None = None,
- radius: float = 4.5,
- cell_size: float | None = None,
-) -> pd.DataFrame:
- all_contacts = []
-
- # Chain1 is set to ligand
- for ch1, ch2 in ch_combos:
- if lig_arr is not None:
- arr1 = lig_arr[(lig_arr.chain_id == ch1[0]) & (lig_arr.res_id == ch1[1])]
- else:
- arr1 = prot_arr[prot_arr.chain_id == ch1[0]]
- arr2 = prot_arr[prot_arr.chain_id == ch2[0]]
- contacts = get_atoms_within_coordinate(
- atom_array=arr1,
- coords=arr2.coord,
- radius=radius,
- cell_size=cell_size,
- as_mask=False,
- )
- contact_pairs = set()
- for a2_idx, a1_idx in np.argwhere(contacts != -1):
- # Chain1 residue
- a1_at = arr1.res_id[contacts[a2_idx, a1_idx]]
- # Chain2 residue
- a2_at = arr2.res_id[a2_idx]
- # Residue IDs in contact
- contact_pairs.add((a1_at, a2_at))
- if len(contact_pairs):
- # Note: Chain1 is always ligand
- all_contacts.append(
- {
- "chain1": ch1[0],
- "resid1": ch1[1],
- "chain2": ch2[0],
- "resid2": ch2[1],
- "contacts": contact_pairs,
- }
- )
- if all_contacts:
- return pd.DataFrame(all_contacts)
- return pd.DataFrame()
-
-
-def pairwise_chain_contacts(
- atom_array: AtomArray, radius: float = 4.5, cell_size: float | None = None
-) -> pd.DataFrame:
- """
- Calculate pairwise contacts between chains in a protein structure.
-
- Parameters
- ----------
- atom_array : AtomArray
- The array of atoms representing the protein structure.
- radius : float, optional
- The radius within which to consider atoms as being in contact, by default 4.5.
- cell_size : float | None, optional
- The size of the cell used for the contact calculation. If None, it is set to the value of radius.
-
- Returns
- -------
- pd.DataFrame | None
- A DataFrame containing the chain pairs and their contacts, or None if no contacts are found.
-
- Examples
- --------
- >>> from plinder.core.structure.atoms import atom_array_from_pdb_file
- >>> atom_array = atom_array_from_pdb_file('1abc.pdb') # doctest: +SKIP
- >>> pairwise_chain_contacts(atom_array) # doctest: +SKIP
- """
- if not cell_size:
- cell_size = radius
-
- # Prot array
- prot_arr = atom_array[struc.filter_amino_acids(atom_array)]
- prot_chains_resids = sorted(set(prot_arr.chain_id))
- # Add dummy res_id for protein
- prot_chains_resids_set = {(i, None) for i in prot_chains_resids}
-
- lig_arr = atom_array[~struc.filter_amino_acids(atom_array) & (atom_array.hetero)]
- lig_chains_resids = sorted(set(zip(lig_arr.chain_id, lig_arr.res_id)))
-
- pli_combos = [(l, p) for l in lig_chains_resids for p in prot_chains_resids_set]
- ppi_combos = list(combinations(prot_chains_resids_set, 2))
-
- if len(lig_arr) == 0:
- pli_contacts = pd.DataFrame()
- else:
- pli_contacts = get_contact_df(
- prot_arr, pli_combos, lig_arr, radius=radius, cell_size=cell_size
- )
- ppi_contacts = get_contact_df(
- prot_arr, ppi_combos, radius=radius, cell_size=cell_size
- )
-
- if isinstance(ppi_contacts, pd.DataFrame) | isinstance(pli_contacts, pd.DataFrame):
- ppi_contacts = pd.DataFrame(ppi_contacts)
- return ppi_contacts, pli_contacts
-
- return pd.DataFrame(), pd.DataFrame()
-
-
-def get_ligand_filter(
- complex_array: AtomArray, binder_chain_ids_resids: List[Tuple[str, int]]
-) -> np.ndarray[bool, Any]:
- filter = np.array(
- [
- ((atm.chain_id, atm.res_id) in binder_chain_ids_resids)
- for atm in complex_array
- ]
- )
- return filter
-
-
-def label_structure_gaps(atom_array: AtomArray) -> pd.DataFrame | None:
- """
- Find gaps in residue numbering between C-alpha atoms.
-
- Parameters
- ----------
- atom_array : AtomArray
- The array of atoms for which to find gaps.
-
- Returns
- -------
- chains : list
- A sorted list of unique chain IDs from the atom array.
- """
- chains = sorted(set(atom_array.chain_id))
- gaps = []
- for ch in chains:
- prot = atom_array[atom_array.chain_id == ch]
- prot_ca = prot[prot.atom_name == "CA"]
- prot_ca = prot_ca[prot_ca.element != "CA"]
- for i in range(prot_ca.shape[0] - 1):
- if prot_ca[i + 1].res_id != (prot_ca[i].res_id + 1):
- if prot_ca[i + 1].res_id == (prot_ca[i].res_id):
- log.warning(
- f"found two Calpha atoms for residue {prot_ca[i].res_id}"
- )
- continue
- gaps.append(
- {
- "chain": ch,
- "gap_start": prot_ca[i].res_id,
- "gap_end": prot_ca[i + 1].res_id,
- }
- )
- if gaps:
- gaps = pd.DataFrame(gaps)
- return gaps
- return None
diff --git a/src/plinder/core/structure/diffdock_utils.py b/src/plinder/core/structure/diffdock_utils.py
deleted file mode 100644
index d294d219a..000000000
--- a/src/plinder/core/structure/diffdock_utils.py
+++ /dev/null
@@ -1,520 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-# mypy: disable-error-code="no-untyped-def, no-untyped-call, attr-defined, assignment, arg-type, var-annotated"
-# ruff: noqa
-
-import copy
-
-import networkx as nx
-import numpy as np
-from rdkit import Chem, RDLogger
-from rdkit.Chem import AllChem, GetPeriodicTable, rdMolTransforms
-from rdkit.Chem.rdchem import BondType as BT
-from scipy.optimize import differential_evolution
-
-from plinder.core.utils.log import setup_logger
-
-RDLogger.DisableLog("rdApp.*")
-LOG = setup_logger(__name__)
-
-"""
- Preprocessing functions taken or adapted from https://github.com/gcorso/DiffDock
-"""
-
-
-def GetDihedral(conf, atom_idx):
- return rdMolTransforms.GetDihedralRad(
- conf, atom_idx[0], atom_idx[1], atom_idx[2], atom_idx[3]
- )
-
-
-def SetDihedral(conf, atom_idx, new_vale):
- rdMolTransforms.SetDihedralRad(
- conf, atom_idx[0], atom_idx[1], atom_idx[2], atom_idx[3], new_vale
- )
-
-
-def apply_changes(mol, values, rotatable_bonds, conf_id):
- opt_mol = copy.copy(mol)
- [
- SetDihedral(opt_mol.GetConformer(conf_id), rotatable_bonds[r], values[r])
- for r in range(len(rotatable_bonds))
- ]
- return opt_mol
-
-
-def optimize_rotatable_bonds(
- mol,
- true_mol,
- rotatable_bonds,
- probe_id=-1,
- ref_id=-1,
- seed=0,
- popsize=15,
- maxiter=500,
- mutation=(0.5, 1),
- recombination=0.8,
-):
- opt = OptimizeConformer(
- mol, true_mol, rotatable_bonds, seed=seed, probe_id=probe_id, ref_id=ref_id
- )
- max_bound = [np.pi] * len(opt.rotatable_bonds)
- min_bound = [-np.pi] * len(opt.rotatable_bonds)
- bounds = (min_bound, max_bound)
- bounds = list(zip(bounds[0], bounds[1]))
-
- # Optimize conformations
- result = differential_evolution(
- opt.score_conformation,
- bounds,
- maxiter=maxiter,
- popsize=popsize,
- mutation=mutation,
- recombination=recombination,
- disp=False,
- seed=seed,
- )
- opt_mol = apply_changes(opt.mol, result["x"], opt.rotatable_bonds, conf_id=probe_id)
-
- return opt_mol
-
-
-class OptimizeConformer:
- def __init__(
- self, mol, true_mol, rotatable_bonds, probe_id=-1, ref_id=-1, seed=None
- ):
- super(OptimizeConformer, self).__init__()
- if seed:
- np.random.seed(seed)
- self.rotatable_bonds = rotatable_bonds
- self.mol = mol
- self.true_mol = true_mol
- self.probe_id = probe_id
- self.ref_id = ref_id
-
- def score_conformation(self, values):
- for i, r in enumerate(self.rotatable_bonds):
- SetDihedral(self.mol.GetConformer(self.probe_id), r, values[i])
- return AllChem.AlignMol(self.mol, self.true_mol, self.probe_id, self.ref_id)
-
-
-def get_torsion_angles(mol):
- torsions_list = []
- G = nx.Graph()
- for i, atom in enumerate(mol.GetAtoms()):
- G.add_node(i)
- nodes = set(G.nodes())
- for bond in mol.GetBonds():
- start, end = bond.GetBeginAtomIdx(), bond.GetEndAtomIdx()
- G.add_edge(start, end)
- for e in G.edges():
- G2 = copy.deepcopy(G)
- G2.remove_edge(*e)
- if nx.is_connected(G2):
- continue
- l = list(sorted(nx.connected_components(G2), key=len)[0])
- if len(l) < 2:
- continue
- n0 = list(G2.neighbors(e[0]))
- n1 = list(G2.neighbors(e[1]))
- torsions_list.append((n0[0], e[0], e[1], n1[0]))
- return torsions_list
-
-
-def read_molecule(
- molecule_file, sanitize=False, calc_charges=False, remove_hs=False
-) -> Chem.rdchem.Mol:
- if molecule_file.endswith(".mol2"):
- mol = Chem.MolFromMol2File(molecule_file, sanitize=False, removeHs=False)
- elif molecule_file.endswith(".sdf"):
- supplier = Chem.SDMolSupplier(molecule_file, sanitize=False, removeHs=False)
- mol = supplier[0]
- elif molecule_file.endswith(".pdbqt"):
- with open(molecule_file) as file:
- pdbqt_data = file.readlines()
- pdb_block = ""
- for line in pdbqt_data:
- pdb_block += "{}\n".format(line[:66])
- mol = Chem.MolFromPDBBlock(pdb_block, sanitize=False, removeHs=False)
- elif molecule_file.endswith(".pdb"):
- mol = Chem.MolFromPDBFile(molecule_file, sanitize=False, removeHs=False)
- else:
- raise ValueError(
- "Expect the format of the molecule_file to be "
- "one of .mol2, .sdf, .pdbqt and .pdb, got {}".format(molecule_file)
- )
-
- try:
- if sanitize or calc_charges:
- Chem.SanitizeMol(mol)
-
- if calc_charges:
- # Compute Gasteiger charges on the molecule.
- try:
- AllChem.ComputeGasteigerCharges(mol)
- except:
- LOG.warning("Unable to compute charges for the molecule.")
-
- if remove_hs:
- mol = Chem.RemoveHs(mol, sanitize=sanitize)
-
- except Exception:
- # Print stacktrace
- import traceback
-
- msg = traceback.format_exc()
- LOG.warning(f"Failed to process molecule: {molecule_file}\n{msg}")
- return None
-
- return mol
-
-
-def generate_conformer(mol):
- ps = AllChem.ETKDGv2()
- failures, id = 0, -1
- while failures < 3 and id == -1:
- if failures > 0:
- LOG.debug(f"rdkit coords could not be generated. trying again {failures}.")
- id = AllChem.EmbedMolecule(mol, ps)
- failures += 1
- if id == -1:
- LOG.info(
- "rdkit coords could not be generated without using random coords. using random coords now."
- )
- ps.useRandomCoords = True
- AllChem.EmbedMolecule(mol, ps)
- AllChem.MMFFOptimizeMolecule(mol, confId=0)
- return True
- return False
-
-
-periodic_table = GetPeriodicTable()
-allowable_features = {
- "possible_atomic_num_list": list(range(1, 119)) + ["misc"],
- "possible_chirality_list": [
- "CHI_UNSPECIFIED",
- "CHI_TETRAHEDRAL_CW",
- "CHI_TETRAHEDRAL_CCW",
- "CHI_OTHER",
- ],
- "possible_degree_list": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, "misc"],
- "possible_numring_list": [0, 1, 2, 3, 4, 5, 6, "misc"],
- "possible_implicit_valence_list": [0, 1, 2, 3, 4, 5, 6, "misc"],
- "possible_formal_charge_list": [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, "misc"],
- "possible_numH_list": [0, 1, 2, 3, 4, 5, 6, 7, 8, "misc"],
- "possible_number_radical_e_list": [0, 1, 2, 3, 4, "misc"],
- "possible_hybridization_list": ["SP", "SP2", "SP3", "SP3D", "SP3D2", "misc"],
- "possible_is_aromatic_list": [False, True],
- "possible_is_in_ring3_list": [False, True],
- "possible_is_in_ring4_list": [False, True],
- "possible_is_in_ring5_list": [False, True],
- "possible_is_in_ring6_list": [False, True],
- "possible_is_in_ring7_list": [False, True],
- "possible_is_in_ring8_list": [False, True],
- "possible_amino_acids": [
- "ALA",
- "ARG",
- "ASN",
- "ASP",
- "CYS",
- "GLN",
- "GLU",
- "GLY",
- "HIS",
- "ILE",
- "LEU",
- "LYS",
- "MET",
- "PHE",
- "PRO",
- "SER",
- "THR",
- "TRP",
- "TYR",
- "VAL",
- "HIP",
- "HIE",
- "TPO",
- "HID",
- "LEV",
- "MEU",
- "PTR",
- "GLV",
- "CYT",
- "SEP",
- "HIZ",
- "CYM",
- "GLM",
- "ASQ",
- "TYS",
- "CYX",
- "GLZ",
- "misc",
- ],
- "possible_atom_type_2": [
- "C*",
- "CA",
- "CB",
- "CD",
- "CE",
- "CG",
- "CH",
- "CZ",
- "N*",
- "ND",
- "NE",
- "NH",
- "NZ",
- "O*",
- "OD",
- "OE",
- "OG",
- "OH",
- "OX",
- "S*",
- "SD",
- "SG",
- "misc",
- ],
- "possible_atom_type_3": [
- "C",
- "CA",
- "CB",
- "CD",
- "CD1",
- "CD2",
- "CE",
- "CE1",
- "CE2",
- "CE3",
- "CG",
- "CG1",
- "CG2",
- "CH2",
- "CZ",
- "CZ2",
- "CZ3",
- "N",
- "ND1",
- "ND2",
- "NE",
- "NE1",
- "NE2",
- "NH1",
- "NH2",
- "NZ",
- "O",
- "OD1",
- "OD2",
- "OE1",
- "OE2",
- "OG",
- "OG1",
- "OH",
- "OXT",
- "SD",
- "SG",
- "misc",
- ],
-}
-bonds = {BT.SINGLE: 0, BT.DOUBLE: 1, BT.TRIPLE: 2, BT.AROMATIC: 3}
-
-lig_feature_dims = (
- list(
- map(
- len,
- [
- allowable_features["possible_atomic_num_list"],
- allowable_features["possible_chirality_list"],
- allowable_features["possible_degree_list"],
- allowable_features["possible_formal_charge_list"],
- allowable_features["possible_implicit_valence_list"],
- allowable_features["possible_numH_list"],
- allowable_features["possible_number_radical_e_list"],
- allowable_features["possible_hybridization_list"],
- allowable_features["possible_is_aromatic_list"],
- allowable_features["possible_numring_list"],
- allowable_features["possible_is_in_ring3_list"],
- allowable_features["possible_is_in_ring4_list"],
- allowable_features["possible_is_in_ring5_list"],
- allowable_features["possible_is_in_ring6_list"],
- allowable_features["possible_is_in_ring7_list"],
- allowable_features["possible_is_in_ring8_list"],
- ],
- )
- ),
- 0,
-) # number of scalar features
-
-rec_atom_feature_dims = (
- list(
- map(
- len,
- [
- allowable_features["possible_amino_acids"],
- allowable_features["possible_atomic_num_list"],
- allowable_features["possible_atom_type_2"],
- allowable_features["possible_atom_type_3"],
- ],
- )
- ),
- 0,
-)
-
-rec_residue_feature_dims = (
- list(map(len, [allowable_features["possible_amino_acids"]])),
- 0,
-)
-
-
-def safe_index(l, e):
- """Return index of element e in list l. If e is not present, return the last index"""
- try:
- return l.index(e)
- except:
- return len(l) - 1
-
-
-def lig_atom_featurizer(mol: Chem.rdchem.Mol) -> list[list[int]]:
- ringinfo = mol.GetRingInfo()
- atom_features_list = []
- for idx, atom in enumerate(mol.GetAtoms()):
- chiral_tag = str(atom.GetChiralTag())
- if chiral_tag in [
- "CHI_SQUAREPLANAR",
- "CHI_TRIGONALBIPYRAMIDAL",
- "CHI_OCTAHEDRAL",
- ]:
- chiral_tag = "CHI_OTHER"
-
- atom_features_list.append(
- [
- safe_index(
- allowable_features["possible_atomic_num_list"], atom.GetAtomicNum()
- ),
- allowable_features["possible_chirality_list"].index(str(chiral_tag)),
- safe_index(
- allowable_features["possible_degree_list"], atom.GetTotalDegree()
- ),
- safe_index(
- allowable_features["possible_formal_charge_list"],
- atom.GetFormalCharge(),
- ),
- safe_index(
- allowable_features["possible_implicit_valence_list"],
- atom.GetImplicitValence(),
- ),
- safe_index(
- allowable_features["possible_numH_list"], atom.GetTotalNumHs()
- ),
- safe_index(
- allowable_features["possible_number_radical_e_list"],
- atom.GetNumRadicalElectrons(),
- ),
- safe_index(
- allowable_features["possible_hybridization_list"],
- str(atom.GetHybridization()),
- ),
- allowable_features["possible_is_aromatic_list"].index(
- atom.GetIsAromatic()
- ),
- safe_index(
- allowable_features["possible_numring_list"],
- ringinfo.NumAtomRings(idx),
- ),
- allowable_features["possible_is_in_ring3_list"].index(
- ringinfo.IsAtomInRingOfSize(idx, 3)
- ),
- allowable_features["possible_is_in_ring4_list"].index(
- ringinfo.IsAtomInRingOfSize(idx, 4)
- ),
- allowable_features["possible_is_in_ring5_list"].index(
- ringinfo.IsAtomInRingOfSize(idx, 5)
- ),
- allowable_features["possible_is_in_ring6_list"].index(
- ringinfo.IsAtomInRingOfSize(idx, 6)
- ),
- allowable_features["possible_is_in_ring7_list"].index(
- ringinfo.IsAtomInRingOfSize(idx, 7)
- ),
- allowable_features["possible_is_in_ring8_list"].index(
- ringinfo.IsAtomInRingOfSize(idx, 8)
- ),
- # g_charge if not np.isnan(g_charge) and not np.isinf(g_charge) else 0.
- ]
- )
- return atom_features_list
-
-
-def get_lig_graph(mol):
- atom_feats = lig_atom_featurizer(mol)
-
- row, col, edge_type = [], [], []
- for bond in mol.GetBonds():
- start, end = bond.GetBeginAtomIdx(), bond.GetEndAtomIdx()
- row += [start, end]
- col += [end, start]
- edge_type += (
- 2 * [bonds[bond.GetBondType()]]
- if bond.GetBondType() != BT.UNSPECIFIED
- else [0, 0]
- )
- if mol.GetNumConformers() > 0:
- lig_coords = mol.GetConformer().GetPositions()
- return
-
-
-def get_lig_graph_with_matching(
- mol_,
- popsize=15,
- maxiter=15,
- num_conformers=1,
- remove_hs=False,
- tries=10,
- skip_matching=False,
-) -> None:
- mol_maybe_noh = copy.deepcopy(mol_)
- if remove_hs:
- mol_maybe_noh = Chem.RemoveHs(mol_maybe_noh, sanitize=True)
- mol_maybe_noh = AllChem.RemoveAllHs(mol_maybe_noh)
-
- _tmp = copy.deepcopy(mol_)
- if remove_hs:
- _tmp = Chem.RemoveHs(_tmp, sanitize=True)
- _tmp = AllChem.RemoveAllHs(_tmp)
- rotatable_bonds = get_torsion_angles(_tmp)
-
- for i in range(num_conformers):
- mols, rmsds = [], []
- for _ in range(tries):
- mol_rdkit = copy.deepcopy(mol_)
-
- mol_rdkit.RemoveAllConformers()
- mol_rdkit = AllChem.AddHs(mol_rdkit)
- generate_conformer(mol_rdkit)
- if remove_hs:
- mol_rdkit = Chem.RemoveHs(mol_rdkit, sanitize=True)
- mol_rdkit = AllChem.RemoveAllHs(mol_rdkit)
- mol = AllChem.RemoveAllHs(copy.deepcopy(mol_maybe_noh))
- if rotatable_bonds and not skip_matching:
- optimize_rotatable_bonds(
- mol_rdkit,
- mol,
- rotatable_bonds,
- popsize=popsize,
- maxiter=maxiter,
- )
- mol.AddConformer(mol_rdkit.GetConformer())
- rms_list = []
- AllChem.AlignMolConformers(mol, RMSlist=rms_list)
- mol_rdkit.RemoveAllConformers()
- mol_rdkit.AddConformer(mol.GetConformers()[1])
- mols.append(mol_rdkit)
- rmsds.append(rms_list[0])
- mol_rdkit = mols[np.argmin(rmsds)]
- if i == 0:
- rmsd_matching = min(rmsds)
- get_lig_graph(mol_rdkit)
- else:
- pos = mol_rdkit.GetConformer().GetPositions()
- return
diff --git a/src/plinder/core/structure/inputs.py b/src/plinder/core/structure/inputs.py
new file mode 100644
index 000000000..a258d2da2
--- /dev/null
+++ b/src/plinder/core/structure/inputs.py
@@ -0,0 +1,284 @@
+"""Structure input files for search and evaluation workflows."""
+
+from __future__ import annotations
+
+import gzip
+import re
+from collections.abc import Sequence
+from dataclasses import dataclass
+from pathlib import Path
+from typing import TYPE_CHECKING
+
+import pandas as pd
+
+if TYPE_CHECKING:
+ import biotite.structure as struc
+ from biotite.structure.io import pdbx
+ from rdkit.Chem import Mol
+
+STRUCTURE_SUFFIXES = (".pdb", ".pdb.gz", ".cif", ".cif.gz", ".mmcif", ".mmcif.gz")
+
+
+def find_structure_files(path: Path) -> list[Path]:
+ """List PDB/mmCIF files in a folder, or select a single coordinate file."""
+ candidates = sorted(path.iterdir()) if path.is_dir() else [path]
+ return [
+ candidate
+ for candidate in candidates
+ if candidate.is_file() and candidate.name.lower().endswith(STRUCTURE_SUFFIXES)
+ ]
+
+
+@dataclass(frozen=True)
+class StructureInput:
+ """A complete structure, or a receptor with separate ligand poses.
+
+ ``coordinates`` is a PDB or mmCIF file, optionally gzip-compressed.
+ ``ligand_sdfs=None`` identifies a complete structure. A supplied sequence
+ identifies separate ligand poses, one molecule per SDF, in the receptor's
+ coordinate frame. An empty sequence represents zero predicted ligand poses.
+
+ Examples
+ --------
+ ``StructureInput("complex.cif")``
+ ``StructureInput("receptor.pdb", ligand_sdfs=["pose.sdf"])``
+ """
+
+ coordinates: str | Path
+ ligand_sdfs: Sequence[str | Path] | None = None
+ reference_id: str | None = None
+
+ def __post_init__(self) -> None:
+ object.__setattr__(self, "coordinates", Path(self.coordinates))
+ if self.ligand_sdfs is not None:
+ if isinstance(self.ligand_sdfs, (str, Path)):
+ raise TypeError("ligand_sdfs must be a sequence of SDF paths")
+ object.__setattr__(
+ self, "ligand_sdfs", tuple(Path(path) for path in self.ligand_sdfs)
+ )
+
+ @classmethod
+ def from_path(cls, coordinates: str | Path) -> StructureInput:
+ """Pair coordinates with ``model.sdf`` or ``model.ligands/*.sdf``.
+
+ With no matching SDF or ligand folder, use the complete-structure form.
+ Matching uses the coordinate basename, including for compressed files.
+ """
+ model = Path(coordinates)
+ name = model.stem if model.suffix.lower() == ".gz" else model.name
+ stem = Path(name).stem
+ folder = model.parent / f"{stem}.ligands"
+ singles = sorted(
+ path
+ for path in model.parent.iterdir()
+ if path.is_file() and path.stem == stem and path.suffix.lower() == ".sdf"
+ )
+ if len(singles) > 1 or (singles and folder.exists()):
+ raise ValueError(f"Use either {stem}.sdf or {stem}.ligands/ for {model}")
+ if folder.exists():
+ if not folder.is_dir():
+ raise NotADirectoryError(folder)
+ return cls(
+ model,
+ ligand_sdfs=sorted(
+ path
+ for path in folder.iterdir()
+ if path.is_file() and path.suffix.lower() == ".sdf"
+ ),
+ )
+ return cls(model, ligand_sdfs=singles or None)
+
+
+def read_structure_table(
+ source: str | Path | pd.DataFrame, *, require_reference: bool = False
+) -> dict[str, StructureInput]:
+ """Read CSV/TSV/Parquet inputs, grouped by ``input_id``.
+
+ Required columns are ``input_id`` and ``structure_path``. ``ligand_path``
+ holds one SDF or a folder of SDFs; repeat the input row for multiple ligands.
+ Evaluation also requires ``reference_id``. Relative file paths are resolved
+ from the table's directory (the working directory for a DataFrame).
+ """
+ if isinstance(source, pd.DataFrame):
+ frame, base = source.copy(), Path.cwd()
+ else:
+ path = Path(source).resolve()
+ base = path.parent
+ if path.suffix.lower() == ".parquet":
+ frame = pd.read_parquet(path)
+ elif path.suffix.lower() in {".csv", ".tsv"}:
+ frame = pd.read_csv(
+ path,
+ sep="\t" if path.suffix.lower() == ".tsv" else ",",
+ dtype=str,
+ keep_default_na=False,
+ )
+ else:
+ raise ValueError("Input tables must be CSV, TSV or Parquet")
+ required = {"input_id", "structure_path"}
+ if require_reference:
+ required.add("reference_id")
+ if missing := required - set(frame.columns):
+ raise ValueError(f"Missing input table columns: {sorted(missing)}")
+ if frame.empty:
+ raise ValueError("Input table is empty")
+ for column in required | {"ligand_path", "reference_id"}:
+ if column not in frame:
+ frame[column] = ""
+ frame[column] = frame[column].fillna("").astype(str).str.strip()
+ if column in required and frame[column].eq("").any():
+ raise ValueError(f"Input table has empty {column} values")
+ inputs = {}
+ for input_id, rows in frame.groupby("input_id", sort=False):
+ if not re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9_.-]*", input_id):
+ raise ValueError(
+ f"Invalid input_id: {input_id!r}; use letters, digits, _, . or -"
+ )
+ for column in ("structure_path", "reference_id"):
+ if rows[column].nunique() != 1:
+ raise ValueError(f"Conflicting {column} values for {input_id}")
+ ligands: list[Path] = []
+ supplied = rows.loc[rows["ligand_path"].ne(""), "ligand_path"]
+ for name in supplied:
+ path = (base / name).resolve()
+ ligands.extend(
+ sorted(
+ p
+ for p in path.iterdir()
+ if p.is_file() and p.suffix.lower() == ".sdf"
+ )
+ if path.is_dir()
+ else [path]
+ )
+ if len(set(ligands)) != len(ligands):
+ raise ValueError(f"Repeated ligand files for {input_id}")
+ inputs[input_id] = StructureInput(
+ (base / rows["structure_path"].iloc[0]).resolve(),
+ ligand_sdfs=ligands if len(supplied) else None,
+ reference_id=rows["reference_id"].iloc[0] or None,
+ )
+ return inputs
+
+
+def read_ligand_sdf(path: str | Path) -> Mol:
+ """Read one supplied pose, preserving its coordinates and bond information."""
+ import numpy as np
+ from rdkit.Chem import SDMolSupplier
+
+ path = Path(path)
+ if path.suffix.lower() != ".sdf":
+ raise ValueError(f"Expected a ligand SDF: {path}")
+ supplier = SDMolSupplier(str(path), sanitize=False, removeHs=False)
+ if len(supplier) != 1 or (molecule := supplier[0]) is None:
+ raise ValueError(f"Expected one readable ligand per SDF: {path}")
+ if (
+ molecule.GetNumAtoms() == 0
+ or molecule.GetNumConformers() == 0
+ or not np.isfinite(molecule.GetConformer().GetPositions()).all()
+ ):
+ raise ValueError(f"Ligand SDF needs atomic coordinates: {path}")
+ return molecule
+
+
+def read_input_structure(
+ path: str | Path,
+) -> tuple[struc.AtomArray, pdbx.CIFBlock | None]:
+ """Read the first coordinate model and its mmCIF metadata where available."""
+ from biotite.structure.io import pdb
+
+ from plinder.data.annotations.cif_utils import (
+ get_structure_with_altloc,
+ read_mmcif_file,
+ )
+
+ path = Path(path)
+ if path.name.lower().endswith((".pdb", ".pdb.gz")):
+ with (
+ gzip.open(path, "rt") if path.suffix.lower() == ".gz" else path.open("r")
+ ) as stream:
+ return pdb.PDBFile.read(stream).get_structure(
+ model=1, include_bonds=True, extra_fields=["charge"]
+ ), None
+ if not path.name.lower().endswith((".cif", ".cif.gz", ".mmcif", ".mmcif.gz")):
+ raise ValueError(f"Expected PDB or mmCIF coordinates: {path}")
+ cif = read_mmcif_file(path)
+ return get_structure_with_altloc(cif, include_bonds=True), cif.block
+
+
+def write_search_structure(
+ structure: StructureInput, destination: Path, *, include_ligands: bool
+) -> Path:
+ """Write a search mmCIF with the supplied SDF chemistry and pose coordinates.
+
+ PDB receptors contribute amino-acid residues, including modified amino acids.
+ Other PDB components are omitted; ligand poses can be supplied as SDFs.
+ """
+ import biotite.structure as struc
+ import numpy as np
+ from biotite.interface.rdkit import from_mol
+ from biotite.structure.io import pdbx
+
+ from plinder.core.utils.sanitize import sanitize as peppr_sanitize
+ from plinder.data.annotations.save_utils import save_cif_file
+
+ atoms, block = read_input_structure(structure.coordinates)
+ if block is None:
+ if struc.filter_nucleotides(atoms).any():
+ raise ValueError(
+ "Use mmCIF with polymer sequence metadata for DNA/RNA search inputs"
+ )
+ # PDB author chains may mix protein, water and other components. Only
+ # protein residues belong in the sequence of the generated polymer entity.
+ # CCD-based selection retains modified amino acids recorded as HETATM.
+ atoms = atoms[struc.filter_amino_acids(atoms)]
+ if len(atoms) == 0:
+ raise ValueError(
+ f"No protein residues found in PDB receptor: {structure.coordinates}"
+ )
+ author_numbers = atoms.res_id.copy()
+ if block is None:
+ atoms.res_id = struc.create_continuous_res_ids(atoms, restart_each_chain=True)
+ if "charge" not in atoms.get_annotation_categories():
+ atoms.set_annotation("charge", np.zeros(len(atoms), dtype=int))
+ mapping = {}
+ used_chains, used_components = set(atoms.chain_id), set(atoms.res_name)
+ if include_ligands and structure.ligand_sdfs is not None:
+ for index, ligand_path in enumerate(structure.ligand_sdfs, start=1):
+ molecule = read_ligand_sdf(ligand_path)
+ peppr_sanitize(molecule)
+ ligand = from_mol(molecule, conformer_id=0, add_hydrogen=False)
+ counter = index
+ while f"L{counter:04d}" in used_chains | used_components:
+ counter += 1
+ name = f"L{counter:04d}"
+ used_chains.add(name)
+ used_components.add(name)
+ ligand.chain_id = np.full(len(ligand), name)
+ ligand.res_name = np.full(len(ligand), name)
+ ligand.res_id[:] = 1
+ ligand.ins_code[:] = ""
+ ligand.hetero[:] = True
+ ligand.atom_name = struc.create_atom_names(ligand)
+ author_numbers = np.concatenate((author_numbers, ligand.res_id))
+ atoms += ligand
+ mapping[name] = str(Path(ligand_path).resolve())
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ save_cif_file(
+ atoms,
+ destination.stem,
+ destination,
+ source_block=block,
+ source_asym_ids={chain: chain for chain in used_chains},
+ )
+ if block is None:
+ cif = pdbx.CIFFile.read(destination)
+ cif.block["atom_site"]["auth_seq_id"] = author_numbers
+ cif.write(destination)
+ if mapping:
+ pd.DataFrame(
+ [
+ {"chain_id": chain, "ligand_path": value}
+ for chain, value in mapping.items()
+ ]
+ ).to_csv(destination.with_suffix(".ligands.tsv"), sep="\t", index=False)
+ return destination
diff --git a/src/plinder/core/structure/models.py b/src/plinder/core/structure/models.py
deleted file mode 100644
index ef457bcfb..000000000
--- a/src/plinder/core/structure/models.py
+++ /dev/null
@@ -1,29 +0,0 @@
-from enum import Enum
-
-from pydantic import BaseModel, ConfigDict
-
-
-class Base(BaseModel):
- model_config = ConfigDict(
- extra="forbid", validate_assignment=True, use_enum_values=True
- )
-
-
-class ChainConfig(Base):
- """Preparation configuration settings.
-
- Default configuration for preparation of normalized monomers,
- ready for use in PPI generation tasks.
- """
-
- decoy_receptor: list[str] = ["R"]
- decoy_ligand: list[str] = ["L"]
- native_receptor: list[str] = ["R"]
- native_ligand: list[str] = ["L"]
-
-
-class BackboneDefinition(str, Enum):
- # Biotite (standard) C, CA, N
- biotite = "biotite"
- # DockQ definition: C, CA, N, O
- dockq = "dockq"
diff --git a/src/plinder/core/structure/smallmols_similarity.py b/src/plinder/core/structure/smallmols_similarity.py
index 7bf451ff5..256437f50 100644
--- a/src/plinder/core/structure/smallmols_similarity.py
+++ b/src/plinder/core/structure/smallmols_similarity.py
@@ -1,332 +1,320 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
-from pathlib import Path
-from typing import TYPE_CHECKING, Any, Optional
+from functools import cache
+from typing import NamedTuple
import numpy as np
-import pandas as pd
-import pyarrow as pa
-import pyarrow.parquet as pq
+from numpy.typing import NDArray
from rdkit import Chem, DataStructs
-from rdkit.Chem import AllChem, rdFingerprintGenerator, rdRascalMCES
+from rdkit.Chem import (
+ rdFingerprintGenerator,
+ rdMHFPFingerprint,
+ rdRascalMCES,
+)
from rdkit.Chem.rdchem import Mol
from rdkit.rdBase import BlockLogs
-from scipy.spatial.distance import cdist
-from plinder.core.structure.smallmols_utils import uncharge_mol
-from plinder.core.utils import schemas
-from plinder.core.utils.log import setup_logger
+from plinder.core.utils.sanitize import mol_from_smiles
-if TYPE_CHECKING:
- from plinder.data.utils.annotations.aggregate_annotations import Entry
+# MHFP6 = MinHashed FingerPrint at radius 3 (ECFP diameter 6 equivalent).
+# Probst, D. & Reymond, J-L. "A probabilistic molecular fingerprint for big
+# data settings." J. Cheminform. 10, 8 (2018).
+# https://doi.org/10.1186/s13321-018-0321-8
+MHFP6_RADIUS = 3
+MHFP6_N_PERMUTATIONS = 2048
+# A fixed permutation seed makes the MinHash vectors reproducible across runs
+# and machines; changing it invalidates every stored MHFP6 fingerprint.
+MHFP6_SEED = 42
-LOG = setup_logger(__name__)
+def smiles2nonstereo(smiles: str) -> str:
+ """Return a stereo-stripped RDKit canonical SMILES โ the ligand identity key.
-def smiles2inchikey(smiles: str, remove_stereo: bool = False) -> str:
- """
- Gets inchikey. In case it fails, returns standardized smiles instead of as a unique specifier string.
- Optional to remove stereo (default: False)
+ RDKit always yields a canonical SMILES from a parsed molecule, whereas InChIKey
+ generation fails for many CCD molecules (organometallics, exotic valences), so
+ canonical SMILES is the robust, uniform identifier. Stereochemistry is removed
+ (identity is stereo-insensitive โ used for split stratification and MMP
+ grouping) and no charge normalization is applied: the CCD representation is
+ taken as-is, consistent with the exact-SMILES cofactor/artifact matching.
+
+ Parsing uses the tolerant :func:`mol_from_smiles` so over-valent ligands
+ (boron cages, hypervalent metals) still yield a canonical 2D graph key
+ instead of falling back to their raw, non-canonical SMILES.
"""
- mol = Chem.MolFromSmiles(smiles)
+ mol = mol_from_smiles(smiles)
+ if mol is None:
+ return smiles
with BlockLogs():
- # TODO: this might be unnecesarry if done before
- mol = uncharge_mol(mol)
- if remove_stereo:
- Chem.RemoveStereochemistry(mol)
- inchikey = Chem.MolToInchiKey(mol)
- if not inchikey:
- inchikey = Chem.CanonSmiles(Chem.MolToSmiles(mol), useChiral=not remove_stereo)
- return str(inchikey)
-
-
-def get_ecfp_fingerprint(
- smiles: str, radius: int, nbits: int
-) -> Optional[np.ndarray[int, Any]]:
- try:
- mol = Chem.MolFromSmiles(smiles)
- fp = AllChem.GetMorganFingerprintAsBitVect(mol, radius, nBits=nbits)
- return np.array(fp)
- except:
- return None
+ Chem.RemoveStereochemistry(mol)
+ return str(Chem.MolToSmiles(mol))
def mol2morgan_fp(
mol: Mol | str, radius: int = 2, nbits: int = 2048
) -> DataStructs.ExplicitBitVect:
- """Convert an RDKit molecule to a Morgan fingerprint
- :param mol: RDKit molecule or SMILES str
- :param radius: fingerprint radius
- :param nbits: number of fingerprint bits
- :return: RDKit Morgan fingerprint
+ """Convert an RDKit molecule or SMILES string to a Morgan fingerprint."""
+ if isinstance(mol, str):
+ mol = mol_from_smiles(mol)
+ if mol is None:
+ raise ValueError("cannot fingerprint an invalid molecule")
+ generator = rdFingerprintGenerator.GetMorganGenerator(radius=radius, fpSize=nbits)
+ return generator.GetFingerprint(mol)
+
+
+@cache
+def _mhfp6_encoder() -> rdMHFPFingerprint.MHFPEncoder:
+ """Return the shared, seeded MHFP6 encoder (permutations are seed-derived)."""
+ return rdMHFPFingerprint.MHFPEncoder(MHFP6_N_PERMUTATIONS, MHFP6_SEED)
+
+
+def mol2mhfp6(mol: Mol | str) -> NDArray[np.uint32]:
+ """Return the MHFP6 MinHash fingerprint of a molecule or SMILES string.
+
+ MHFP6 hashes the set of circular SMILES shingles (radii 1..3) and keeps the
+ per-permutation minima, so the fraction of matching positions between two
+ fingerprints estimates the Jaccard similarity of their shingle sets
+ (Probst & Reymond, J. Cheminform. 2018). Unlike a folded Morgan bit-vector,
+ the result is a dense vector of ``MHFP6_N_PERMUTATIONS`` uint32 hashes.
"""
- if type(mol) == str:
- mol = Chem.MolFromSmiles(mol)
- mfpgen = rdFingerprintGenerator.GetMorganGenerator(radius=radius, fpSize=nbits)
- fp = mfpgen.GetFingerprint(mol)
- return fp
-
-
-def tanimoto_maxsim_and_argmax(
- long_list: list[Any], test_list: list[Any]
-) -> tuple[np.ndarray[float], np.ndarray[int]]:
- """Calculate maximum similarity for the fingerprint second list to the first fingerprint lists"""
- similarity_matrix = [
- DataStructs.BulkTanimotoSimilarity(fp, long_list) for fp in test_list
- ]
- return np.max(similarity_matrix, axis=1) * 100, np.argmax(similarity_matrix, axis=1)
-
-
-def get_mmp_similarity_dict(
- mmp_path: Path, min_constant_size: int = 5
-) -> dict[str, dict[str, float]]:
- mmp_df = pd.read_csv(
- mmp_path,
- sep="\t",
- compression="gzip",
- names=["SMILES1", "SMILES2", "id1", "id2", "V1>>V2", "CONSTANT"],
- )
+ if isinstance(mol, str):
+ mol = mol_from_smiles(mol)
+ if mol is None:
+ raise ValueError("cannot fingerprint an invalid molecule")
+ try:
+ encoded = _mhfp6_encoder().EncodeMol(mol, radius=MHFP6_RADIUS)
+ except RuntimeError as exc:
+ if "bad bond stereo" not in str(exc):
+ raise
+ # RDKit can fail while creating fragments of a conjugated alkene even
+ # with isomeric=False. Clear only double-bond stereo; keep atom chirality.
+ mol = Chem.Mol(mol)
+ for bond in mol.GetBonds():
+ if bond.GetBondType() == Chem.BondType.DOUBLE:
+ bond.SetStereo(Chem.BondStereo.STEREONONE)
+ elif bond.GetBondDir() != Chem.BondDir.NONE:
+ bond.SetBondDir(Chem.BondDir.NONE)
+ encoded = _mhfp6_encoder().EncodeMol(mol, radius=MHFP6_RADIUS)
+ return np.asarray(encoded, dtype=np.uint32)
+
+
+def mhfp6_bulk_jaccard(
+ query: NDArray[np.uint32], reference_matrix: NDArray[np.uint32]
+) -> NDArray[np.float64]:
+ """Estimate one MHFP6 vector's Jaccard similarity to every reference row.
+
+ Each reference row is a MinHash vector; the estimated Jaccard similarity is
+ the fraction of permutations at which the two vectors share the same minimum
+ hash -- the MinHash counterpart of ``BulkTanimotoSimilarity`` for bit-vectors.
+ """
+ if reference_matrix.ndim != 2 or reference_matrix.shape[1] != query.shape[0]:
+ raise ValueError("query and reference MinHash widths do not match")
+ matches = np.count_nonzero(reference_matrix == query, axis=1)
+ return np.asarray(matches / reference_matrix.shape[1], dtype=np.float64)
- const_size_map = {
- smarts: Chem.MolFromSmarts(smarts).GetNumHeavyAtoms()
- for smarts in mmp_df.CONSTANT.drop_duplicates()
- }
- mmp_df["const_size"] = mmp_df.CONSTANT.map(const_size_map)
- mmp_df = mmp_df[mmp_df["const_size"] >= min_constant_size]
- # remove stereo as we only care for the graph here - proxy for common edge subgraphs
- smiles_inchikey_map = {
- smi: smiles2inchikey(smi, remove_stereo=True)
- for smi in set(mmp_df.SMILES1.to_list() + mmp_df.SMILES2.to_list())
- }
- mmp_df["inchikey1"] = mmp_df.SMILES1.map(smiles_inchikey_map)
- mmp_df["inchikey2"] = mmp_df.SMILES2.map(smiles_inchikey_map)
+Centres = dict[int, tuple[Chem.StereoDescriptor, list[int]]]
+
- smiles_size_map = {
- smi: Chem.MolFromSmiles(smi).GetNumHeavyAtoms()
- for smi in set(mmp_df.SMILES1.to_list() + mmp_df.SMILES2.to_list())
+def _stereo_centres(mol: Mol) -> Centres:
+ """Specified tetrahedral centres: descriptor and neighbours, padded to four."""
+ return {
+ si.centeredOn: (si.descriptor, (list(si.controllingAtoms) + [-1])[:4])
+ for si in Chem.FindPotentialStereo(mol)
+ if si.type == Chem.StereoType.Atom_Tetrahedral
+ and si.specified == Chem.StereoSpecified.Specified
}
- mmp_df["SMILES1_size"] = mmp_df.SMILES1.map(smiles_size_map)
- mmp_df["SMILES2_size"] = mmp_df.SMILES2.map(smiles_size_map)
-
- # calculate similarities
- mmp_df["sim_1_to_2"] = mmp_df["const_size"] / mmp_df["SMILES1_size"]
- mmp_df["sim_2_to_1"] = mmp_df["const_size"] / mmp_df["SMILES2_size"]
-
- mmp_sim_dict: dict[str, dict[str, float]] = {}
- for inchik1, inchik2, sim12, sim21 in mmp_df[
- ["inchikey1", "inchikey2", "sim_1_to_2", "sim_2_to_1"]
- ].values:
- if inchik1 not in mmp_sim_dict.keys():
- mmp_sim_dict[inchik1] = {}
- if inchik2 not in mmp_sim_dict.keys():
- mmp_sim_dict[inchik2] = {}
- mmp_sim_dict[inchik1][inchik2] = sim12 * 100
- mmp_sim_dict[inchik2][inchik1] = sim21 * 100
- return mmp_sim_dict
-
-
-def rdRascalMCES_similarity(mol1: Mol, mol2: Mol, sim_threshold: float = 0.4) -> float:
- rascal_opts = rdRascalMCES.RascalOptions()
- rascal_opts.allBestMCESs = False
- rascal_opts.returnEmptyMCES = True
- rascal_opts.completeAromaticRings = False
- rascal_opts.ringMatchesRingOnly = False
- rascal_opts.maxBondMatchPairs = 1000
- rascal_opts.timeout = 2
- rascal_opts.similarityThreshold = sim_threshold
- res = rdRascalMCES.FindMCES(mol1, mol2, rascal_opts)
- return float(res[0].tier2Sim if res else 0)
-
-
-def load_ligands_from_entry(
- *,
- entry: "Entry",
- ccd_col: str = "unique_ccd_code",
- smiles_col: str = "rdkit_canonical_smiles",
-) -> Optional[pd.DataFrame]:
- """
- Load ligands from entries for tanimoto similarity calculations
- Parameters
- ----------
- entry : Entry
- annotation entry
- ccd_col : str
- entry attribute where ccd code is fetched
- smiles_col : str
- entry attribute where smiles is fetched
+
+def _opposed_centres(
+ first: Centres, second: Centres, partner: dict[int, int], atoms: set[int]
+) -> int:
+ """Count matched tetrahedral centres of opposite handedness under the mapping.
+
+ Tet_CW/Tet_CCW is relative to each molecule's own neighbour order, so the
+ mapping between the two orders is a permutation and the descriptors are
+ equal only up to its parity. A centre needs three mapped neighbours; the
+ leftover slot on each side (fourth neighbour or implicit H, which RDKit
+ orders last) is taken as corresponding.
"""
- ligands = []
- for system_id, system in entry.systems.items():
- if system.system_type != "holo":
- LOG.info(f"skipping {system_id} as it's not a holo system")
+ opposed = 0
+ for i in atoms & first.keys():
+ j = partner.get(i)
+ if j not in second:
+ continue
+ (descriptor, neighbours), (other_descriptor, other) = first[i], second[j]
+ # i's neighbour order translated into mol2 indices, next to j's own order
+ mapped = [partner.get(a, -1) for a in neighbours]
+ common = set(mapped) & set(other) - {-1}
+ if len(common) < 3:
continue
- for ligand in system.ligands:
- smiles = getattr(ligand, smiles_col)
- ccd_code = getattr(ligand, ccd_col)
- if not smiles:
- continue
- ligand_id = f"{system_id}__{ligand.biounit_id}.{ligand.asym_id}"
- ligands.append(
- (
- entry.pdb_id,
- system_id,
- smiles,
- ccd_code,
- ligand_id,
- )
- )
- LOG.info(f"{entry.pdb_id} loaded {len(ligands)} ligands")
- if not len(ligands):
- return None
- df = (
- pd.DataFrame(
- ligands,
- columns=[
- "pdb_id",
- "system_id",
- "ligand_rdkit_canonical_smiles",
- "ligand_ccd_code",
- "ligand_id",
- ],
+ mapped, other = (
+ [a if a in common else -1 for a in ns] for ns in (mapped, other)
+ )
+ order = [other.index(a) for a in mapped]
+ odd = sum(order[x] > order[y] for x in range(4) for y in range(x + 1, 4)) % 2
+ opposed += (descriptor == other_descriptor) == bool(odd)
+ return opposed
+
+
+class RascalParityMatch(NamedTuple):
+ """One Rascal MCES reduced to what the PARITY-like score needs."""
+
+ atoms: dict[int, int] # largest connected fragment, mol1 -> mol2 atom index
+ bonds: int # matched bonds over all fragments
+ opposed: int # fragment centres of opposite handedness under the mapping
+ alternatives: tuple[dict[int, int], ...] = () # fragments of the other best MCESs
+
+ def score(self, mol1: Mol, mol2: Mol, *, stereo: bool = True) -> float:
+ """PARITY-like similarity in [0, 1]; an opposed centre counts half an atom."""
+ atoms = len(self.atoms) - (0.5 * self.opposed if stereo else 0.0)
+ return parity_similarity(
+ atoms,
+ self.bonds,
+ mol1.GetNumAtoms() + mol2.GetNumAtoms(),
+ mol1.GetNumBonds() + mol2.GetNumBonds(),
)
- .dropna(subset="ligand_id")
- .drop_duplicates(subset=["ligand_id"])
- .reset_index(drop=True)
- .sort_values(by="ligand_id")
- )
- LOG.info(f"after deduplication {len(df.index)} entries")
- # aggregate multiple ligands into one:
- df["inchikeys"] = df["ligand_rdkit_canonical_smiles"].apply(smiles2inchikey)
- return df
+ def coverage(
+ self, mol1: Mol, mol2: Mol, *, stereo: bool = True
+ ) -> tuple[float, float]:
+ """Fraction of each molecule matched, ``(mol1, mol2)``, in [0, 1].
-def compute_ligand_fingerprints(
- *, data_dir: Path, split_char: str = "__", radius: int = 2, nbits: int = 1024
-) -> None:
- ligands = (
- pd.read_parquet(data_dir / "ligands").drop_duplicates().reset_index(drop=True)
- )
- for col in ligands.columns:
- nunique = ligands[col].nunique()
- LOG.info(f"compute_ligand_fingerprints: unique {col}={nunique}")
-
- ligands_unique = (
- ligands[ligands["inchikeys"] != ""][
- ["inchikeys", "ligand_rdkit_canonical_smiles"]
- ]
- .drop_duplicates(subset="inchikeys")
- .sort_values(by="inchikeys")
- .reset_index(drop=True)
- .sort_values(by=["inchikeys"])
- )
- ids, _ = pd.factorize(ligands_unique["inchikeys"])
- ids_str = [f"l{int(i)}" for i in ids]
- ligands_unique["number_id_by_inchikeys"] = ids
- ligands_unique["number_id_by_inchikeys_withl"] = ids_str
- missing_inchi = ligands_unique[ligands_unique["number_id_by_inchikeys"] <= -1]
- LOG.info(f"ligands missing inchikeys: {len(missing_inchi.index)}")
- ligands_unique = ligands_unique[ligands_unique["number_id_by_inchikeys"] > -1]
- output_dir = data_dir / "fingerprints"
- output_dir.mkdir(exist_ok=True, parents=True)
- ligands_unique.to_parquet(output_dir / "ligands_per_inchikey.parquet", index=False)
-
- LOG.info(f"computing ECFP fingerprints with radius={radius} nbits={nbits}")
- ligands_unique["ECFP4"] = ligands_unique["ligand_rdkit_canonical_smiles"].apply(
- get_ecfp_fingerprint,
- radius=radius,
- nbits=nbits,
- )
- if ligands_unique["ECFP4"].isnull().any():
- raise ValueError(f"found {ligands_unique['ECFP4'].isnull().sum()}")
+ Directional counterpart of :meth:`score`: the same atom and bond terms
+ (an opposed centre still counts half an atom), each averaged over one
+ molecule's own atom and bond counts instead of the union.
+ """
+ if self.bonds <= 0:
+ return 0.0, 0.0
+ atoms = len(self.atoms) - (0.5 * self.opposed if stereo else 0.0)
+
+ def fraction(mol: Mol) -> float:
+ return float(atoms / mol.GetNumAtoms() + self.bonds / mol.GetNumBonds()) / 2
- ecfp = (
- np.concatenate(ligands_unique.ECFP4.values).reshape(-1, nbits).astype(np.int8)
+ return fraction(mol1), fraction(mol2)
+
+
+def parity_similarity(
+ atoms: float, bonds: float, atom_total: int, bond_total: int
+) -> float:
+ """Mean of the atom and bond Tanimotos; totals are both molecules' counts summed."""
+ if bonds <= 0:
+ return 0.0
+ return (atoms / (atom_total - atoms) + bonds / (bond_total - bonds)) / 2
+
+
+def rascal_parity_match(
+ mol1: Mol,
+ mol2: Mol,
+ *,
+ target: float = 0.3,
+ timeout: int = 2,
+ all_best: bool = False,
+) -> RascalParityMatch:
+ """Element-exact Rascal MCES with fragments allowed, pruned to a target bond similarity.
+
+ Pairs whose bond Tanimoto cannot reach ``target`` are pruned before the
+ clique search and come back empty. Rascal maximises matched bonds, and the
+ MCESs of that size differ in their largest fragment, so the bonds come from
+ one MCES and the fragment from a second run that keeps only the largest
+ fragment over all of them (``singleLargestFrag``). With ``all_best`` every
+ fragment is enumerated instead (a further 1.5x) and the one scoring best is
+ taken; the rest follow, best first and then in a fixed order.
+ """
+ options = rdRascalMCES.RascalOptions()
+ # tier screens use Johnson similarity; below (2t/(1+t))^2 no pair reaches bond Tanimoto t
+ options.similarityThreshold = (2 * target / (1 + target)) ** 2
+ # fewest matched bonds giving bond Tanimoto >= target; Rascal's bound is exclusive
+ options.minCliqueSize = max(
+ int(np.ceil(target * (mol1.GetNumBonds() + mol2.GetNumBonds()) / (1 + target)))
+ - 1,
+ 0,
)
- LOG.info(f"writing {output_dir}/ligands_per_inchikey_ecfp4.npy")
- np.save(output_dir / "ligands_per_inchikey_ecfp4.npy", ecfp)
-
- ligs = pd.merge(
- ligands,
- ligands_unique[
- ["inchikeys", "number_id_by_inchikeys", "number_id_by_inchikeys_withl"]
- ],
- on="inchikeys",
+ options.returnEmptyMCES = True
+ options.completeAromaticRings = False
+ options.ringMatchesRingOnly = False
+ options.maxBondMatchPairs = 5000
+ options.timeout = timeout
+ options.allBestMCESs = all_best
+ matches: dict[tuple[tuple[int, int], ...], dict[int, int]] = {}
+ bonds = 0
+ for result in rdRascalMCES.FindMCES(mol1, mol2, options):
+ matched = result.bondMatches()
+ if not matched:
+ continue
+ # largest connected fragment of the matched bonds, in mol1 atom indices
+ atom_map: dict[int, int] = {}
+ core = Chem.PathToSubmol(mol1, [i for i, _ in matched], atomMap=atom_map)
+ original = {new: old for old, new in atom_map.items()}
+ partner = dict(result.atomMatches())
+ fragment = {
+ original[i]: partner[original[i]]
+ for i in max(Chem.GetMolFrags(core), key=len)
+ }
+ matches.setdefault(tuple(sorted(fragment.items())), partner)
+ bonds = len(matched)
+ if not matches:
+ return RascalParityMatch({}, 0, 0)
+ if not all_best:
+ options.singleLargestFrag = True
+ best = rdRascalMCES.FindMCES(mol1, mol2, options)
+ if best and best[0].bondMatches():
+ fragment = dict(best[0].atomMatches())
+ matches = {tuple(sorted(fragment.items())): fragment}
+ centres_1, centres_2 = _stereo_centres(mol1), _stereo_centres(mol2)
+ opposed = {
+ key: _opposed_centres(centres_1, centres_2, partner, {i for i, _ in key})
+ for key, partner in matches.items()
+ }
+ ordered = sorted(matches, key=lambda key: (0.5 * opposed[key] - len(key), key))
+ return RascalParityMatch(
+ dict(ordered[0]),
+ bonds,
+ opposed[ordered[0]],
+ tuple(dict(key) for key in ordered[1:]),
)
- # free up memory
- ligands_unique = None
- ecfp = None
- # remove nan inchikeys entries
- ligs = ligs[ligs["number_id_by_inchikeys"].notna()]
- ligs["multi_number_id_by_inchikeys"] = ligs["number_id_by_inchikeys"]
- ligs["multi_number_id_by_inchikeys_withl"] = ligs["number_id_by_inchikeys_withl"]
- for aggcol in [
- "multi_number_id_by_inchikeys",
- "multi_number_id_by_inchikeys_withl",
- ]:
- ligs[aggcol] = ligs[aggcol].astype(str)
- agg_df = ligs.groupby("system_id")[aggcol].agg(split_char.join).reset_index()
- del ligs[aggcol]
- ligs = pd.merge(ligs, agg_df, on="system_id", how="left")
+def rascal_parity_score(
+ mol1: Mol, mol2: Mol, *, target: float = 0.3, stereo: bool = True, timeout: int = 2
+) -> float:
+ """PARITY-like similarity from one Rascal MCES, in [0, 1].
- LOG.info(f"writing {output_dir}/ligands_per_system.parquet")
- ligs.to_parquet(output_dir / "ligands_per_system.parquet", index=False)
+ Element-exact MCES with fragments allowed, scored as the mean of two
+ Tanimoto terms: atoms of the largest connected fragment over the atom union,
+ and all matched bonds over the bond union. The largest fragment carries
+ residue order (a shuffled peptide splits into one fragment per residue, a
+ substitution does not); the bonds keep credit for matches beyond a
+ substituted connecting atom. With ``stereo`` a matched tetrahedral centre of
+ opposite handedness counts half an atom.
+ """
+ match = rascal_parity_match(mol1, mol2, target=target, timeout=timeout)
+ return match.score(mol1, mol2, stereo=stereo)
-def ligand_scores(
- *,
- ligand_ids: list[int],
- data_dir: Path,
- output_path: Path,
- number_id_col: str = "number_id_by_inchikeys",
- # TODO: always save all ligands!!
- save_top_k_similar_ligands: int = 5000,
- multiply_by: int = 100,
-) -> None:
- fp_dir = data_dir / "fingerprints"
- all_ligs_ids = pd.read_parquet(fp_dir / "ligands_per_inchikey.parquet")
- LOG.info(f"ligand_scores: loaded {len(all_ligs_ids.index)} ligands")
- fingerprints = np.load(fp_dir / "ligands_per_inchikey_ecfp4.npy")
- LOG.info(f"ligand_scores: loaded {fingerprints.shape[0]} fingerprints")
-
- # make sure the shape match and the index is in order
- if fingerprints.shape[0] != len(all_ligs_ids.index):
- raise ValueError("ligands don't match fingerprints!")
- if all_ligs_ids[number_id_col].min() != 0:
- raise ValueError("inconsistency in ligand ids, no index=zero found!")
- if all_ligs_ids[number_id_col].max() != all_ligs_ids.shape[0] - 1:
- raise ValueError("inconsistency in ligand ids, max index != ids shape!")
-
- query_ecfp = fingerprints[ligand_ids]
- # target_list = fingerprints
- ecfp_distances = cdist(query_ecfp, fingerprints, metric="jaccard")
- # change to similarity score
- ecfp_distances = np.array(1 - ecfp_distances)
-
- # For each i and j, the metric dist(u=XA[i], v=XB[j]) is computed
- # and stored in the ith, jth entry of ecfp_distances = cdist
- top_k_indices = np.argsort(ecfp_distances, axis=1)[:, -save_top_k_similar_ligands:][
- ..., ::-1
- ]
-
- table = []
- for row, cols in enumerate(top_k_indices):
- LOG.info(f"row {ligand_ids[row]}")
- query_list = [ligand_ids[row]] * len(cols)
- target_list = cols
- tani_topk = (np.round(ecfp_distances[row, cols], 2) * multiply_by).astype(int)
- single_table = pa.table(
- [
- pa.array(query_list),
- pa.array(target_list),
- pa.array(tani_topk),
- ],
- schema=schemas.TANIMOTO_SCORE_SCHEMA,
- )
- table.append(single_table)
- table = pa.concat_tables(table)
- LOG.info(f"writing {output_path}")
- pq.write_table(table, output_path)
+def rascal_parity_coverage(
+ mol1: Mol, mol2: Mol, *, target: float = 0.3, stereo: bool = True, timeout: int = 2
+) -> tuple[float, float]:
+ """Directional PARITY-like coverage from one Rascal MCES.
+
+ Parameters
+ ----------
+ mol1, mol2 : Mol
+ The molecules to compare.
+ target : float, default=0.3
+ Bond Tanimoto below which a pair is pruned and scores zero. It is
+ symmetric, so a small molecule inside a much larger one is pruned
+ unless ``target`` is lowered.
+ stereo : bool, default=True
+ Count a matched centre of opposite handedness as half an atom.
+ timeout : int, default=2
+ Rascal timeout in seconds.
+
+ Returns
+ -------
+ tuple[float, float]
+ The fraction of ``mol1`` and of ``mol2`` covered by the match. A
+ fragment fully contained in a larger molecule gives ``(1.0, x)`` with
+ ``x < 1``, which the symmetric :func:`rascal_parity_score` cannot show.
+ """
+ match = rascal_parity_match(mol1, mol2, target=target, timeout=timeout)
+ return match.coverage(mol1, mol2, stereo=stereo)
diff --git a/src/plinder/core/structure/smallmols_utils.py b/src/plinder/core/structure/smallmols_utils.py
index 9b0925b54..536e53b87 100644
--- a/src/plinder/core/structure/smallmols_utils.py
+++ b/src/plinder/core/structure/smallmols_utils.py
@@ -5,219 +5,27 @@
import copy
from pathlib import Path
+import biotite.structure as struc
import numpy as np
from numpy.typing import NDArray
from rdkit import Chem
-from rdkit.Chem import AllChem, Mol, rdDepictor, rdMolDescriptors, rdRascalMCES
-from rdkit.Chem.MolStandardize import rdMolStandardize
-from rdkit.Chem.rdFMCS import FindMCS
+from rdkit.Chem import (
+ AllChem,
+ Mol,
+ rdDepictor,
+ rdDistGeom,
+ rdMolDescriptors,
+ rdRascalMCES,
+)
from plinder.core.utils.log import setup_logger
-log = setup_logger(__name__)
-
-
-def make_rdkit_compatible_mol(mol: Mol) -> Mol | None:
- """Process RDKit molecule from input to sanitization
-
- Parameters
- ----------
- mol : Chem.rdchem.Mol
-
- Returns
- -------
- Chem.rdchem.Mol | None
- Mol of relevant molecule
- """
- try:
- sanitize_mol(mol)
- except:
- try:
- # fix N, O, C, H valency issues and then sanitize
- mol = fix_valency_issues(mol)
- except Exception:
- mol = None
- return mol
-
-
-def sanitize_mol(mol: Mol) -> None:
- """Santitize while keeping hydrogen as is.
-
- Parameters
- ----------
- mol : Chem.rdchem.Mol
-
- Returns
- -------
- None
- Sanitizes molecule in place
- """
- try:
- Chem.SanitizeMol(mol)
- except Exception:
- Chem.SanitizeMol(
- mol,
- # sanitize all but keep hydrogens as is
- sanitizeOps=Chem.SanitizeFlags.SANITIZE_ALL
- ^ Chem.SanitizeFlags.SANITIZE_ADJUSTHS,
- )
-
-
-def params_removeHs(mol: Chem.Mol) -> Chem.Mol:
- params = Chem.rdmolops.RemoveHsParameters()
- params.removeIsotopes = True
- params.removeDegreeZero = True
- params.removeHigherDegrees = True
- params.removeOnlyHNeighbors = True
- params.removeDummyNeighbors = True
- params.removeNontetrahedralNeighbors = True
- params.removeDefiningBondStereo = True
- params.removeWithWedgedBond = True
- params.showWarnings = True
- return Chem.rdmolops.RemoveHs(mol, params, sanitize=False)
-
-
-def explicit_H_remover(mol: Mol, remove_hydrogens: list[int]) -> Mol:
- """removes all H atoms in the list and all bonds to those hydrogens"""
- res = Chem.RWMol(mol)
- res.BeginBatchEdit()
- for aid in remove_hydrogens:
- neighbors = res.GetAtomWithIdx(aid).GetNeighbors()
- for neighbor in neighbors:
- res.RemoveBond(aid, neighbor.GetIdx())
- res.RemoveAtom(aid)
- res.CommitBatchEdit()
- return res
-
+# TODO(peppr): peppr_sanitize is the vendored local copy of peppr.sanitize
+# (see plinder.core.utils.sanitize); revert to `from peppr import sanitize`
+# once the over-valence fixes land in a released peppr.
+from plinder.core.utils.sanitize import sanitize as peppr_sanitize
-def uncharge_mol(mol: Mol) -> Mol:
- # check if any atoms have a formal charge
- if sum([at.GetFormalCharge() != 0 for at in mol.GetAtoms()]):
- # adjust protonation to neutralize, when possible
- uncharger = rdMolStandardize.Uncharger(
- canonicalOrder=True, force=False
- ) # , protonationOnly=True)
- res = uncharger.uncharge(mol)
- res.UpdatePropertyCache(strict=False)
- return res
- else:
- # return unchanged
- return mol
-
-
-def fix_valency_issues(mol: Mol) -> Mol:
- """Fix valency issues with rdkit mol and return sanitized.
- Deals with cases like:
- Removed hydrogens if there is an issue with their valence!
- Explicit valence for atom # X N, 4, is greater than permitted
- Explicit valence for atom # X O, 3, is greater than permitted
- # NOT: Explicit valence for atom # X C, 5, is greater than permitted
- # skipped C - as we don't like Texas carbons :)
-
- Parameters
- ----------
- mol : Chem.rdchem.Mol
-
- Returns
- -------
- Chem.rdchem.Mol
- Sanitized Mol with valency issues fixed
- """
- max_explicit_valency_per_element = {
- # 6: 4,
- 7: 3,
- 8: 2,
- # 1: 1,
- }
- mol.UpdatePropertyCache(strict=False)
- ps = Chem.DetectChemistryProblems(mol)
- if not ps:
- # if no problems - just sanitize and return
- sanitize_mol(mol)
- return mol
-
- # quick scan if the issue with hydrogens - see if needed to remove
- delete_hydrogens = set()
- ps = Chem.DetectChemistryProblems(mol)
- for p in ps:
- if p.GetType() == "AtomValenceException":
- at = mol.GetAtomWithIdx(p.GetAtomIdx())
- atm_no = at.GetAtomicNum()
- if atm_no == 1:
- delete_hydrogens.add(p.GetAtomIdx())
- elif atm_no == 6:
- delete_hydrogens |= {
- nat.GetIdx() for nat in at.GetNeighbors() if nat.GetAtomicNum() == 1
- }
- # remove explicit hydrogents when some are causing issues
- if delete_hydrogens:
- log.warning(
- f"fix_valency_issues: found issues with H atoms {delete_hydrogens} - will try removing these atoms explicitly!"
- )
- mol = explicit_H_remover(mol, list(delete_hydrogens))
- # scan again for remaining problems
- ps = Chem.DetectChemistryProblems(mol)
-
- # deal with remainng issues, if any
- for p in ps:
- if p.GetType() == "AtomValenceException":
- at = mol.GetAtomWithIdx(p.GetAtomIdx())
- atm_no = at.GetAtomicNum()
- formal_charge = at.GetFormalCharge()
- valency = at.GetExplicitValence()
- elem_max_explicit_valency = max_explicit_valency_per_element[atm_no]
- expected_charge = valency - elem_max_explicit_valency
- if expected_charge > formal_charge:
- # Fix Explicit valence issue
- at.SetFormalCharge(expected_charge)
- if p.GetType() == "KekulizeException":
- # hack: only works for nitrogens with missing explicit Hs
- for atidx in p.GetAtomIndices():
- at = mol.GetAtomWithIdx(atidx)
- # set one of the nitrogens with two bonds in a ring system as "[nH]"
- if at.GetAtomicNum() == 7 and at.GetDegree() == 2:
- at.SetNumExplicitHs(1)
- break
- sanitize_mol(mol)
- return mol
-
-
-def assign_bond_from_smiles(smiles: str, mol: Mol) -> Mol:
- """Assign bonds from a list smiles.
-
- The goal of this bond assigner is to capture all
- ligands, including the ones with subunits.
-
- Parameters
- ----------
- smiles : str
- smiles string of template for bond assignment
- mol : Chem.rdchem.Mol
- Mol that needs bond assignment
-
- Returns
- -------
- Chem.rdchem.Mol
- Mol bonds assigned
- """
- try:
- # Iterative assign bonds to subunits; this captures multisubunit ligands
- template = AllChem.MolFromSmiles(smiles)
- return AllChem.AssignBondOrdersFromTemplate(template, mol)
-
- except ValueError:
- return None
-
-
-def get_element_count(mol: Mol) -> dict[int, int]:
- atomic_count: dict[int, int] = {}
- for atom in mol.GetAtoms():
- elem = atom.GetAtomicNum()
- if elem == 1:
- continue
- atomic_count.setdefault(elem, 0)
- atomic_count[elem] += 1
- return atomic_count
+log = setup_logger(__name__)
def generate_input_conformer(
@@ -229,19 +37,33 @@ def generate_input_conformer(
_mol = copy.deepcopy(template_mol)
# need to add Hs to generate sensible conformers
_mol = Chem.AddHs(_mol)
+ # peppr_sanitize resolves valences, rings and hybridization โ including
+ # over-valent centres (boron cages, metals) via dative bonds โ so the
+ # embedder has the chemistry it needs. Paired with
+ # ``embedFragmentsSeparately=False`` below, this is the rdkit#8653 work-around
+ # that lets EmbedMolecule skip its internal strict-valence sanitize, which
+ # would otherwise reject those molecules with an AtomValenceException.
+ try:
+ peppr_sanitize(_mol)
+ except Exception as exc: # embed anyway; RDKit may still cope
+ log.warning(f"generate_input_conformer: peppr_sanitize failed ({exc})")
+
+ def _embed(use_basic_knowledge: bool) -> int:
+ params = rdDistGeom.ETKDGv3()
+ params.useRandomCoords = True
+ params.useBasicKnowledge = use_basic_knowledge
+ params.randomSeed = 42
+ params.maxIterations = 100
+ # skip RDKit's internal (strict) sanitize during embedding; the
+ # chemistry it needs was supplied by peppr_sanitize above (rdkit#8653).
+ params.embedFragmentsSeparately = False
+ return int(rdDistGeom.EmbedMolecule(_mol, params))
if skip_3d_confgen:
confid = -1
else:
- # try embedding molecule using ETKDGv2 (default)
- confid = AllChem.EmbedMolecule(
- _mol,
- # ps,
- useRandomCoords=True,
- useBasicKnowledge=True,
- maxAttempts=100,
- randomSeed=42,
- )
+ # try embedding molecule using ETKDGv3
+ confid = _embed(use_basic_knowledge=True)
if confid != -1:
if minimize_maxIters > 0:
# molecule successfully embedded - minimize
@@ -265,13 +87,7 @@ def generate_input_conformer(
"generate_conformer: default EmbedMolecule - failed, trying using useBasicKnowledge=False"
)
# try less optimal approach
- confid = AllChem.EmbedMolecule(
- _mol,
- useRandomCoords=True,
- useBasicKnowledge=False,
- maxAttempts=100,
- randomSeed=42,
- )
+ confid = _embed(use_basic_knowledge=False)
if confid == -1:
# if 3D confgen fails or skipped
@@ -286,7 +102,9 @@ def generate_input_conformer(
if not addHs:
# remove Hs if they should not be kept
- _mol = params_removeHs(_mol)
+ _mol = Chem.RemoveAllHs(_mol, sanitize=False)
+ # resanitize after RemoveAllHs
+ peppr_sanitize(_mol)
return _mol
@@ -294,16 +112,24 @@ def generate_input_conformer(
def match_ligands(
input_smiles: str,
resolved_sdf: str | Path,
-) -> tuple[Chem.Mol, Chem.Mol, tuple[NDArray, NDArray]]:
- template_mol = Chem.MolFromSmiles(input_smiles)
- resolved_mol = Chem.MolFromMolFile(resolved_sdf.__str__())
+) -> tuple[Chem.Mol, Chem.Mol, tuple[NDArray[np.int_], NDArray[np.int_]]]:
+ template_mol = Chem.MolFromSmiles(input_smiles, sanitize=False)
+ try:
+ peppr_sanitize(template_mol)
+ except Exception as exc: # embed anyway; RDKit may still cope
+ log.warning(f"template_mol: peppr_sanitize failed ({exc})")
+ resolved_mol = Chem.MolFromMolFile(resolved_sdf.__str__(), sanitize=False)
+ try:
+ peppr_sanitize(resolved_mol)
+ except Exception as exc: # embed anyway; RDKit may still cope
+ log.warning(f"resolved_mol: peppr_sanitize failed ({exc})")
atom_order_stacks = get_template_to_mol_matches(template_mol, resolved_mol)
return template_mol, resolved_mol, atom_order_stacks
def get_template_to_mol_matches(
template: Chem.Mol, mol: Chem.Mol
-) -> tuple[NDArray, NDArray]:
+) -> tuple[NDArray[np.int_], NDArray[np.int_]]:
"""
Function that works a lot like get_matched_template but can better deal with fragmented molecules
"""
@@ -366,14 +192,103 @@ def get_template_to_mol_matches(
return template_atom_order_stack1, mol_atom_order_stack2
+def compare_stereo_to_template(
+ resolved_mol: Mol,
+ template_mol: Mol,
+) -> bool | None:
+ """Check resolved 3D stereo against a template โ tetrahedral R/S and E/Z.
+
+ Atoms are matched by PDB name. Template stereo is read from its tags via
+ :func:`Chem.FindPotentialStereo`; a template that ships ideal coordinates (CCD)
+ first has its atom + bond stereo perceived from them via
+ :func:`Chem.AssignStereochemistryFrom3D`, while SMILES templates already carry
+ tags โ no conformer is generated either way. Each tetrahedral center's descriptor
+ (Tet_CW/Tet_CCW) fixes the sign of the signed volume of its ``controllingAtoms``;
+ each double bond's descriptor (Bond_Cis/Bond_Trans) fixes the dihedral of its
+ reference substituents. Both are checked against the resolved coordinates only โ
+ no CIP priority, no conformer generation and no empty filled coordinates.
+
+ Returns True if every fully-resolved stereo element matches (or the template has
+ none), False on any mismatch, None if nothing could be matched. Elements with
+ unresolved atoms or degenerate geometry are skipped.
+ """
+
+ def _name(atom: Chem.Atom) -> str | None:
+ info = atom.GetPDBResidueInfo()
+ return info.GetName().strip() if info is not None else None
+
+ # perceive full stereo (atom + bond) from a template's ideal coordinates (CCD) so
+ # double-bond E/Z is available; SMILES templates already carry their stereo tags
+ if template_mol.GetNumConformers() > 0:
+ template_mol = Chem.Mol(template_mol)
+ Chem.AssignStereochemistryFrom3D(template_mol)
+
+ conf = resolved_mol.GetConformer()
+ resolved_pos: dict[str, NDArray[np.float64]] = {
+ n: np.asarray(conf.GetAtomPosition(a.GetIdx()), dtype=np.float64)
+ for a in resolved_mol.GetAtoms()
+ if (n := _name(a)) is not None
+ }
+ template_names = {n for a in template_mol.GetAtoms() if (n := _name(a)) is not None}
+ if not resolved_pos.keys() & template_names:
+ return None # nothing maps onto the template
+
+ for si in Chem.FindPotentialStereo(template_mol):
+ if si.specified != Chem.StereoSpecified.Specified:
+ continue
+
+ if si.type == Chem.StereoType.Atom_Tetrahedral:
+ center = _name(template_mol.GetAtomWithIdx(si.centeredOn))
+ names = [
+ _name(template_mol.GetAtomWithIdx(i))
+ for i in list(si.controllingAtoms)[:3]
+ ]
+ if center is None or center not in resolved_pos or len(names) < 3:
+ continue
+ if any(n is None or n not in resolved_pos for n in names):
+ continue # center or reference neighbours not resolved -> undefined
+ order = [n for n in names if n is not None] # resolved; list[str] for mypy
+ # Tet_CW -> -1, Tet_CCW -> +1 signed volume of controllingAtoms (see tests)
+ ref = -1.0 if si.descriptor == Chem.StereoDescriptor.Tet_CW else 1.0
+ u, v, w = (resolved_pos[n] - resolved_pos[center] for n in order)
+ res = float(np.sign(np.dot(u, np.cross(v, w))))
+ if res != 0 and res != ref: # resolved handedness opposes the template
+ return False
+
+ elif si.type == Chem.StereoType.Bond_Double:
+ ctrl = list(si.controllingAtoms)
+ if len(ctrl) < 3:
+ continue
+ bond = template_mol.GetBondWithIdx(si.centeredOn)
+ # controllingAtoms = [begin_ref, begin_ref, end_ref, end_ref]; the dihedral
+ # of one reference per end (ref_a1 - a1 - a2 - ref_a2) fixes cis/trans
+ quad = [
+ _name(template_mol.GetAtomWithIdx(i))
+ for i in (
+ ctrl[0],
+ bond.GetBeginAtomIdx(),
+ bond.GetEndAtomIdx(),
+ ctrl[2],
+ )
+ ]
+ if any(n is None or n not in resolved_pos for n in quad):
+ continue # a reference or bond atom not resolved -> undefined
+ p = [resolved_pos[n] for n in quad if n is not None] # 4 pts; list for mypy
+ dih = struc.dihedral(p[0], p[1], p[2], p[3]) # radians; nan if degenerate
+ if np.isnan(dih):
+ continue
+ # Bond_Cis -> ~0, Bond_Trans -> ~180 (biotite dihedral convention; see tests)
+ expected_cis = si.descriptor == Chem.StereoDescriptor.Bond_Cis
+ if (abs(dih) < np.pi / 2) != expected_cis: # resolved E/Z opposes template
+ return False
+ return True
+
+
# below functions used for data ingest
def mol_assigned_bond_orders_by_template(template_mol: Mol, mol: Mol) -> Mol:
try:
- # Assign bonds according to template smiles!
fixed_mol = AllChem.AssignBondOrdersFromTemplate(template_mol, mol)
except Exception as e:
- # raise AssertionError(f"mol_assigned_bond_orders_by_template: {e}")
- # update template in case fully resovled mol but bonding is an issue
log.warning(
f"mol_assigned_bond_orders_by_template: {e} - try get_matched_template"
)
@@ -382,72 +297,10 @@ def mol_assigned_bond_orders_by_template(template_mol: Mol, mol: Mol) -> Mol:
return fixed_mol
-def get_matched_template(template: Chem.Mol, mol: Chem.Mol) -> Chem.Mol:
- """
- Perform MCS matching between a (subject) mol and a template; and return the matched template with
- the bond orders of the template. Used to assign bond orders in
- `safe_mol_from_pdb_assign_bond_orders`. Known limitation: if the template has
- double/triple bonds and the mol doesn't (because it's read from PDB), this leads to
- removing all atoms that don't match, incl. the ones bound via e.g., a double bond. This is
- only a problem if we need to use this fallback option because previous attempts in
- `safe_mol_from_pdb_assign_bond_orders` have failed.
- Returns
- -------
- Chem.Mol
- the matching template with bond orders from template
- """
- # set all bonds to unspecified to help with the match
- match_mol = copy.deepcopy(mol)
- [b.SetBondType(Chem.BondType.UNSPECIFIED) for b in match_mol.GetBonds()]
-
- mcs = FindMCS(
- [match_mol, template],
- completeRingsOnly=False,
- ringMatchesRingOnly=False,
- timeout=10,
- )
- patt = Chem.MolFromSmarts(mcs.smartsString)
- atom_map_template = np.array(template.GetSubstructMatch(patt))
- # remove all atoms from the ref that are not in the MCS --> use this as template for
- # bond orders
- matched_template_mol = remove_unmatched_atoms(template, atom_map_template)
- return matched_template_mol
-
-
-def remove_unmatched_atoms(mol: Chem.Mol, match: NDArray) -> Chem.Mol:
- """Remove atoms in mol whose indices are not in match.
- Parameters
- ----------
- mol : Chem.Mol
- the mol to be modified
- match : NDArray
- indices that are matches and should not be removed
- Returns
- -------
- Chem.Mol
- the mol with unmatched atoms removed
- """
- res = Chem.RWMol(mol)
- atoms_to_remove = [a.GetIdx() for a in mol.GetAtoms() if a.GetIdx() not in match]
- res.BeginBatchEdit()
- for atom_idx in atoms_to_remove:
- neighbors = res.GetAtomWithIdx(atom_idx).GetNeighbors()
- for neighbor in neighbors:
- res.RemoveBond(atom_idx, neighbor.GetIdx())
- res.RemoveAtom(atom_idx)
- res.CommitBatchEdit()
- res = Chem.Mol(res)
- try:
- Chem.SanitizeMol(res)
- except:
- pass
- [a.SetNumRadicalElectrons(0) for a in res.GetAtoms()]
- return res
-
-
-# Version 2 of above functions
-def remove_unmatched_atoms_and_bonds(
- mol: Chem.Mol, matched_atoms: NDArray, matched_bonds: NDArray
+def _remove_unmatched(
+ mol: Chem.Mol,
+ matched_atoms: NDArray[np.int_],
+ matched_bonds: NDArray[np.int_],
) -> Chem.Mol:
"""Remove atoms and bonds in mol whose indices are not in match.
Parameters
@@ -492,15 +345,16 @@ def remove_unmatched_atoms_and_bonds(
res = Chem.Mol(res)
try:
Chem.SanitizeMol(res)
- except:
+ except Exception:
pass
[a.SetNumRadicalElectrons(0) for a in res.GetAtoms()]
return res
-def get_matched_template_v2(template: Chem.Mol, mol: Chem.Mol) -> Chem.Mol:
- """
- Function that works a lot like get_matched_template but can better deal with fragmented molecules
+def get_matched_template(template: Chem.Mol, mol: Chem.Mol) -> Chem.Mol:
+ """Trim template to the MCS with mol using Rascal MCES.
+
+ Handles fragmented molecules and unmatched bonds correctly.
"""
rascal_opts = rdRascalMCES.RascalOptions()
rascal_opts.similarityThreshold = 0.1
@@ -524,7 +378,7 @@ def get_matched_template_v2(template: Chem.Mol, mol: Chem.Mol) -> Chem.Mol:
ref_mol = copy.deepcopy(template)
log.warning(
- "get_matched_template_v2: could not match template fully - retry with unmatched bonds set as UNSPECIFIED"
+ "get_matched_template: could not match template fully - retry with unmatched bonds set as UNSPECIFIED"
)
# set all unmatched bonds to UNSPECIFIED to help with the match
if len(bond_matches):
@@ -554,10 +408,102 @@ def get_matched_template_v2(template: Chem.Mol, mol: Chem.Mol) -> Chem.Mol:
atom_map_template = np.array([j for i, j in result.atomMatches()])
bond_map_template = np.array([j for i, j in result.bondMatches()])
if len(atom_map_template) == 0:
- raise ValueError("get_matched_template_v2: cannot match mol to template")
+ raise ValueError("get_matched_template: cannot match mol to template")
# Removes unmatched atoms and bonds from the template
- matched_template_mol = remove_unmatched_atoms_and_bonds(
+ matched_template_mol = _remove_unmatched(
template, atom_map_template, bond_map_template
)
return matched_template_mol
+
+
+# Categorical ligand-atom descriptors, one vocabulary per column. A value
+# outside its vocabulary maps to a trailing "other" bucket (index
+# ``len(vocabulary)``), so the encoding is stable across RDKit versions and
+# exotic chemistry.
+LIGAND_ATOM_FEATURE_NAMES = (
+ "atomic_number",
+ "chiral_tag",
+ "total_degree",
+ "formal_charge",
+ "implicit_valence",
+ "total_hydrogens",
+ "radical_electrons",
+ "hybridization",
+ "is_aromatic",
+ "ring_count",
+ "in_ring_3",
+ "in_ring_4",
+ "in_ring_5",
+ "in_ring_6",
+ "in_ring_7",
+ "in_ring_8",
+)
+_ATOMIC_NUMBERS = tuple(range(1, 119))
+_CHIRAL_TAGS = (
+ "CHI_UNSPECIFIED",
+ "CHI_TETRAHEDRAL_CW",
+ "CHI_TETRAHEDRAL_CCW",
+ "CHI_OTHER",
+)
+_TOTAL_DEGREES = tuple(range(11))
+_FORMAL_CHARGES = tuple(range(-5, 6))
+_IMPLICIT_VALENCES = tuple(range(7))
+_HYDROGEN_COUNTS = tuple(range(9))
+_RADICAL_ELECTRONS = tuple(range(5))
+_HYBRIDIZATIONS = ("SP", "SP2", "SP3", "SP3D", "SP3D2")
+_RING_COUNTS = tuple(range(7))
+_RING_SIZES = (3, 4, 5, 6, 7, 8)
+
+
+def _bucket(vocabulary: tuple[int, ...] | tuple[str, ...], value: int | str) -> int:
+ """Return the index of ``value`` in ``vocabulary`` or the "other" bucket."""
+ try:
+ return vocabulary.index(value)
+ except ValueError:
+ return len(vocabulary)
+
+
+def ligand_atom_features(mol: Chem.Mol) -> NDArray[np.int64]:
+ """Encode every atom of ``mol`` as categorical vocabulary indices.
+
+ Columns follow :data:`LIGAND_ATOM_FEATURE_NAMES`: atomic number, chiral
+ tag, total degree, formal charge, implicit valence, total hydrogen count,
+ radical electrons, hybridization, aromaticity, number of rings the atom
+ belongs to, and membership in rings of size 3 to 8. Chiral tags other
+ than the two tetrahedral ones collapse onto ``CHI_OTHER``. Only graph
+ properties are used, so a 2D template without a conformer is sufficient.
+
+ Parameters
+ ----------
+ mol : Chem.Mol
+ Ligand with explicit atoms in the order the features should follow.
+
+ Returns
+ -------
+ NDArray[np.int64]
+ Array of shape ``(n_atoms, len(LIGAND_ATOM_FEATURE_NAMES))``.
+ """
+ ring_info = mol.GetRingInfo()
+ features = np.empty(
+ (mol.GetNumAtoms(), len(LIGAND_ATOM_FEATURE_NAMES)), dtype=np.int64
+ )
+ for row, atom in zip(features, mol.GetAtoms()):
+ index = atom.GetIdx()
+ chiral_tag = str(atom.GetChiralTag())
+ if chiral_tag not in _CHIRAL_TAGS:
+ chiral_tag = "CHI_OTHER"
+ row[:] = (
+ _bucket(_ATOMIC_NUMBERS, atom.GetAtomicNum()),
+ _CHIRAL_TAGS.index(chiral_tag),
+ _bucket(_TOTAL_DEGREES, atom.GetTotalDegree()),
+ _bucket(_FORMAL_CHARGES, atom.GetFormalCharge()),
+ _bucket(_IMPLICIT_VALENCES, atom.GetImplicitValence()),
+ _bucket(_HYDROGEN_COUNTS, atom.GetTotalNumHs()),
+ _bucket(_RADICAL_ELECTRONS, atom.GetNumRadicalElectrons()),
+ _bucket(_HYBRIDIZATIONS, str(atom.GetHybridization())),
+ int(atom.GetIsAromatic()),
+ _bucket(_RING_COUNTS, ring_info.NumAtomRings(index)),
+ *(int(ring_info.IsAtomInRingOfSize(index, size)) for size in _RING_SIZES),
+ )
+ return features
diff --git a/src/plinder/core/structure/structure.py b/src/plinder/core/structure/structure.py
index c8eee498f..d9c4d945e 100644
--- a/src/plinder/core/structure/structure.py
+++ b/src/plinder/core/structure/structure.py
@@ -2,7 +2,7 @@
import tempfile
from pathlib import Path
-from typing import TYPE_CHECKING, Iterable
+from typing import TYPE_CHECKING, Iterable, cast
import biotite.structure as struc
import numpy as np
@@ -12,25 +12,23 @@
from pydantic import BaseModel, model_validator
from rdkit import Chem
-from plinder.core.structure import surgery
from plinder.core.structure.atoms import (
_stack_atom_array_features,
atom_array_from_cif_file,
get_residue_index_mapping_mask,
make_atom_mask,
+ resn2seq,
+ write_cif,
+)
+from plinder.core.structure.ccd_template import (
+ UNRESOLVED_ANNOTATION,
+ add_missing_atoms,
)
from plinder.core.structure.smallmols_utils import (
generate_input_conformer,
match_ligands,
)
from plinder.core.structure.superimpose import superimpose_chain
-from plinder.core.structure.vendored import (
- get_per_chain_seq_alignments,
- get_seq_aligned_structures,
- invert_chain_seq_map,
- resn2seq,
- write_pdb,
-)
from plinder.core.utils import constants as pc
from plinder.core.utils.dataclass import stringify_dataclass
from plinder.core.utils.log import setup_logger
@@ -80,17 +78,6 @@ def _superimpose_common_atoms(
)
-def reverse_dict(mapping: dict[int, int]) -> dict[int, int]:
- return {v: k for k, v in mapping.items()}
-
-
-def get_rdkit_mol(ligand: Path | str) -> Chem.rdchem.Mol:
- if isinstance(ligand, Path):
- return Chem.MolFromSmiles(ligand)
- elif isinstance(ligand, Path):
- return next(Chem.SDMolSupplier(ligand))
-
-
class Structure(BaseModel):
id: str
protein_path: Path
@@ -107,7 +94,7 @@ class Structure(BaseModel):
# tuple[NDArray, NDArray],
Chem.Mol,
# tuple[NDArray, NDArray],
- tuple[NDArray, NDArray],
+ tuple[NDArray[np.int_], NDArray[np.int_]],
],
]
| None
@@ -115,6 +102,7 @@ class Structure(BaseModel):
add_ligand_hydrogens: bool = False
skip_3d_confgen: bool = False
structure_type: str = "holo"
+ complete_missing_atoms: bool = False
"""Initialize structure.
This dataclass provides abstraction over plinder systems holo, apo and predicted structures.
@@ -137,23 +125,21 @@ class Structure(BaseModel):
Dictionary of ligand smiles with chain id as key and smiles as value
protein_atom_array : AtomArray | None = None
Protein Biotite atom array
- ligand_mols : ligand_mols: Optional[
- dict[
- str,
- tuple[Chem.Mol, Chem.Mol, Chem.Mol, tuple[NDArray, NDArray]]
- ]
- ]
- Dictionary of ligand molecule id to
- molecule loaded from smiles (2D),
- template (random) conformer generated from 2D,
- resolved (holo) mol conformer,
- paired stacked arrays (template vs holo) mapping atom order by index
+ ligand_mols : dict, optional
+ Ligand molecules keyed by ligand ID. Each value contains the molecule
+ loaded from SMILES, a generated template conformer, the resolved
+ conformer, and paired atom-index arrays for the template and resolved
+ structures.
add_ligand_hydrogens : bool = False
Whether to add hydrogen to ligand or not
skip_3d_confgen : bool = False
Use 2D coords instead of (default) 3D conformer generation
structure_type : str = "holo"
Structure type, "holo", "apo" or "pred"
+ complete_missing_atoms : bool = False
+ Append CCD-template heavy atoms missing from receptor residues with NaN
+ coordinates and an ``is_unresolved`` annotation (see
+ :func:`plinder.core.structure.ccd_template.add_missing_atoms`)
"""
class Config:
@@ -163,6 +149,8 @@ class Config:
def initialize(self) -> Structure:
if self.protein_atom_array is None:
self.load_protein()
+ if self.complete_missing_atoms and self.protein_atom_array is not None:
+ self.protein_atom_array = add_missing_atoms(self.protein_atom_array)
if self.protein_sequence is None:
self.load_sequence()
if self.ligand_sdfs is not None or self.ligand_smiles is not None:
@@ -270,12 +258,12 @@ def __add__(self, other: Structure) -> Structure | None:
return None
def save_to_disk(self, filepath: Path | None = None) -> None:
- """Write Structure Atomarray to a PDB file.
+ """Write the structure AtomArray to an mmCIF file.
Parameters
----------
filepath : Path | None
- Filepath to output PDB.
+ Filepath to output mmCIF.
If not provided, will write to self.protein_path,
potentially overwriting if the file already exists!
@@ -286,7 +274,7 @@ def save_to_disk(self, filepath: Path | None = None) -> None:
"""
if not filepath:
filepath = self.protein_path
- write_pdb(self.protein_atom_array, filepath)
+ write_cif(self.protein_atom_array, filepath)
def filter(
self,
@@ -318,88 +306,6 @@ def filter(
self.protein_atom_array = self.protein_atom_array[atom_mask]
return None
- def get_per_chain_seq_alignments(
- self,
- other: Structure,
- ) -> dict[str, dict[int, int]]:
- self2other_seq: dict[str, dict[int, int]] = get_per_chain_seq_alignments(
- other.protein_atom_array, self.protein_atom_array
- )
- return self2other_seq
-
- def align_common_sequence(
- self,
- other: Structure,
- copy: bool = True,
- remove_differing_atoms: bool = True,
- renumber_residues: bool = False,
- remove_differing_annotations: bool = False,
- ) -> tuple[Structure, Structure]:
- assert (other.protein_atom_array is not None) and (
- self.protein_atom_array is not None
- )
- ref_at = other.protein_atom_array.copy()
- target_at = self.protein_atom_array.copy()
- target2ref_seq = get_per_chain_seq_alignments(ref_at, target_at)
- ref2target_seq = invert_chain_seq_map(target2ref_seq)
- ref_at, target_at = get_seq_aligned_structures(ref_at, target_at)
-
- if remove_differing_atoms:
- # Even if atom counts are identical, annotation categories must be the same
- # First modify annotation arrays to use struc.filter_intersection,
- # then filter original structure with annotations to match res_id, res_name, atom_name
- # of intersecting structure
- ref_at_mod = ref_at.copy()
- target_at_mod = target_at.copy()
- ref_at_mod, target_at_mod = surgery.fix_annotation_mismatch(
- ref_at_mod, target_at_mod, ["element", "ins_code", "b_factor"]
- )
- ref_target_mask = struc.filter_intersection(ref_at_mod, target_at_mod)
- target_ref_mask = struc.filter_intersection(target_at_mod, ref_at_mod)
- if remove_differing_annotations:
- ref_at = ref_at_mod[ref_target_mask].copy()
- target_at = target_at_mod[target_ref_mask].copy()
- else:
- ref_at = ref_at[ref_target_mask].copy()
- target_at = target_at[target_ref_mask].copy()
-
- if not renumber_residues:
- target_at.res_id = np.array(
- [ref2target_seq[at.chain_id][at.res_id] for at in target_at]
- )
-
- if copy:
- self_struct = Structure(
- id=self.id,
- protein_path=self.protein_path,
- protein_sequence=self.protein_sequence,
- ligand_sdfs=self.ligand_sdfs,
- ligand_smiles=self.ligand_smiles,
- protein_atom_array=target_at,
- ligand_mols=self.ligand_mols,
- add_ligand_hydrogens=self.add_ligand_hydrogens,
- skip_3d_confgen=self.skip_3d_confgen,
- structure_type=self.structure_type,
- )
-
- other_struct = Structure(
- id=other.id,
- protein_path=other.protein_path,
- protein_sequence=self.protein_sequence,
- ligand_sdfs=other.ligand_sdfs,
- ligand_smiles=other.ligand_smiles,
- protein_atom_array=ref_at,
- ligand_mols=other.ligand_mols,
- add_ligand_hydrogens=other.add_ligand_hydrogens,
- skip_3d_confgen=other.skip_3d_confgen,
- structure_type=other.structure_type,
- )
-
- return self_struct, other_struct
- other.protein_atom_array = ref_at
- self.protein_atom_array = target_at
- return self, other
-
def set_chain(self, chain_id: str) -> None:
if self.protein_atom_array is not None:
self.protein_atom_array.chain_id = np.repeat(
@@ -454,7 +360,7 @@ def superimpose(
)
@property
- def input_sequence_residue_mask_stacked(self) -> list[list[int]]:
+ def input_sequence_residue_mask_stacked(self) -> list[NDArray[np.float64]]:
"""Input sequence stacked by chain"""
# TODO: do we want to keep this as assertion?
# better if then raise?
@@ -517,7 +423,7 @@ def sequence_atom_mask(self) -> list[list[int]]:
make_atom_mask(
self.protein_atom_array[self.protein_atom_array.chain_id == ch],
self.protein_sequence[ch],
- seqres_masks[ch],
+ seqres_masks[ch].tolist(),
)
for ch in self.protein_chain_ordered
]
@@ -531,12 +437,12 @@ def ligand_chain_ordered(self) -> list[str]:
return []
@property
- def protein_coords(self) -> list[NDArray]:
+ def protein_coords(self) -> list[NDArray[np.float32]]:
"""list[NDArray]: The coordinates of the protein atoms in the structure."""
assert self.protein_atom_array is not None
- protein_coords: list[NDArray] = [
- coord
+ protein_coords = [
+ cast(NDArray[np.float32], coord)
for coord in _stack_atom_array_features(
self.protein_atom_array, "coord", self.protein_chain_ordered
)
@@ -571,11 +477,23 @@ def input_ligand_templates(self) -> dict[str, Chem.Mol]:
return {tag: mol_tuple[0] for tag, mol_tuple in self.ligand_mols.items()}
@property
- def protein_calpha_coords(self) -> NDArray[np.double]:
+ def protein_unresolved_atom_mask(self) -> list[NDArray[np.int_]]:
+ """Per chain, 1 for CCD-template atoms with NaN coordinates, 0 for deposited atoms."""
+ assert self.protein_atom_array is not None
+ atoms = self.protein_atom_array
+ mask = (
+ atoms.get_annotation(UNRESOLVED_ANNOTATION).astype(np.int64)
+ if UNRESOLVED_ANNOTATION in atoms.get_annotation_categories()
+ else np.zeros(atoms.array_length(), dtype=np.int64)
+ )
+ return [mask[atoms.chain_id == chain] for chain in self.protein_chain_ordered]
+
+ @property
+ def protein_calpha_coords(self) -> list[NDArray[np.float32]]:
+ """list[NDArray]: Per-chain coordinates of the protein C-alpha atoms."""
assert self.protein_atom_array is not None
- """list[NDArray]: The coordinates of the protein clapha atoms in the structure."""
- protein_calpha_coords: list[NDArray] = [
- coord
+ protein_calpha_coords = [
+ cast(NDArray[np.float32], coord)
for coord in _stack_atom_array_features(
self.protein_atom_array[self.protein_atom_array.atom_name == "CA"],
"coord",
@@ -610,7 +528,7 @@ def resolved_ligand_mols(self) -> dict[str, Chem.Mol]:
@property
def ligand_template2resolved_atom_order_stacks(
self,
- ) -> dict[str, tuple[NDArray, NDArray]]:
+ ) -> dict[str, tuple[NDArray[np.int_], NDArray[np.int_]]]:
"""for every ligand this gets a pair of atom order array stacks providing index sort to match template atoms to holo conformer atoms"""
return (
{tag: mol_tuple[3] for tag, mol_tuple in self.ligand_mols.items()}
@@ -631,14 +549,14 @@ def resolved_ligand_mols_coords(self) -> dict[str, NDArray[np.double]]:
@property
def protein_backbone_mask(self) -> NDArray[np.bool_]:
- """ndarray[np.bool\_]: a logical mask for backbone atoms."""
+ r"""ndarray[np.bool\_]: a logical mask for backbone atoms."""
assert self.protein_atom_array is not None
mask: NDArray[np.bool_] = struc.filter_peptide_backbone(self.protein_atom_array)
return mask
@property
def protein_calpha_mask(self) -> NDArray[np.bool_]:
- """ndarray[np.bool\_]: a logical mask for alpha carbon atoms."""
+ r"""ndarray[np.bool\_]: a logical mask for alpha carbon atoms."""
assert self.protein_atom_array is not None
mask: NDArray[np.bool_] = self.protein_atom_array.atom_name == "CA"
return mask
diff --git a/src/plinder/core/structure/superimpose.py b/src/plinder/core/structure/superimpose.py
index 31ea4a5db..75f8e04c2 100644
--- a/src/plinder/core/structure/superimpose.py
+++ b/src/plinder/core/structure/superimpose.py
@@ -8,7 +8,7 @@
import numpy as np
from numpy.typing import NDArray
-from plinder.core.structure.vendored import resn2seq
+from plinder.core.structure.atoms import resn2seq
__all__ = ["superimpose_chain"]
@@ -146,7 +146,10 @@ def superimpose_chain(
def _get_ca_indices(atoms: Atoms) -> NDArray[np.int_]:
- return np.where((struc.filter_amino_acids(atoms)) & (atoms.atom_name == "CA"))[0]
+ return np.asarray(
+ np.flatnonzero(struc.filter_amino_acids(atoms) & (atoms.atom_name == "CA")),
+ dtype=np.int_,
+ )
def _find_matching_anchors(
diff --git a/src/plinder/core/structure/surgery.py b/src/plinder/core/structure/surgery.py
deleted file mode 100644
index 910ee8273..000000000
--- a/src/plinder/core/structure/surgery.py
+++ /dev/null
@@ -1,129 +0,0 @@
-from __future__ import annotations
-
-import biotite.structure as struc
-import numpy as np
-from biotite.structure.atoms import AtomArray, AtomArrayStack
-from numpy.typing import NDArray
-
-from plinder.core.structure.models import ChainConfig
-from plinder.core.structure.vendored import apply_mask, get_seq_aligned_structures
-from plinder.core.utils.log import setup_logger
-
-log = setup_logger(__name__)
-
-
-def remove_annotations(
- structure: AtomArray | AtomArrayStack,
- categories: list[str] = ["element", "ins_code"],
-) -> AtomArray | AtomArrayStack:
- if isinstance(structure, AtomArrayStack):
- shape_idx = 1
- else:
- shape_idx = 0
-
- for annotation in categories:
- val: float | str = 0.0 if annotation == "b_factor" else ""
- annotation_arr: NDArray[np.double | np.str_] = np.repeat(
- val, structure.shape[shape_idx]
- )
- structure.set_annotation(annotation, annotation_arr)
- return structure
-
-
-def fix_annotation_mismatch(
- ref: AtomArray,
- decoys: AtomArrayStack,
- categories: list[str] = ["element", "ins_code"],
-) -> tuple[AtomArray, AtomArrayStack]:
- for annot in ref.get_annotation_categories():
- ref_annot = ref.get_annotation(annot)
- decoy_annot = decoys.get_annotation(annot)
- if not np.array_equal(ref_annot, decoy_annot):
- log.debug(f"Decoy and ref have differing {annot} categories!")
- if annot not in categories:
- continue
-
- decoys = remove_annotations(decoys, categories=[annot])
- ref = remove_annotations(ref, categories=[annot])
- return ref, decoys
-
-
-def fix_mismatched_atoms(
- native: AtomArray, decoy_stack: AtomArrayStack, max_atom_delta: int
-) -> tuple[AtomArray, AtomArrayStack]:
- identical = np.array_equal(decoy_stack.res_id, native.res_id)
- if identical:
- # Both shape and res_id elements are identical
- return native, decoy_stack
-
- log.debug("Detected mismatch between native and decoy stack!")
- # Sequence based structural alignment
- # Make the decoy_stack match numbering of native
- log.debug("Attempting sequence-based structural alignment")
- native, decoy_stack = get_seq_aligned_structures(native, decoy_stack)
- native_intersect = native[struc.filter_intersection(native, decoy_stack)]
- in_common = native_intersect.shape[0]
- native_atoms = native.shape[0]
- mismatch = native_atoms - in_common
- if mismatch > max_atom_delta:
- log.debug(
- f"Large atom mismatch detected between native and models: {mismatch} atoms."
- )
- log.debug("Attempting to fix mismatch")
-
- # In test case there are missing element annotations
- native = remove_annotations(native)
- decoy_stack = remove_annotations(decoy_stack)
- native_intersect = native[struc.filter_intersection(native, decoy_stack)]
- in_common = native_intersect.shape[0]
- log.warning(
- "Caution: results will only represent the atoms in common! "
- f"keeping {in_common} / {native_atoms} atoms in common"
- )
-
- native = native_intersect.copy()
- decoy_stack = decoy_stack[..., struc.filter_intersection(decoy_stack, native)]
- return native, decoy_stack
-
-
-def set_canonical_chain_order(
- structure: AtomArray | AtomArrayStack | list[AtomArray],
- chains: "ChainConfig",
- subject: str,
-) -> AtomArray | AtomArrayStack | list[AtomArray]:
- # Create set of residues in interface split into receptor and ligand
- # Conflict between residue numbers in different chains is handled by
- # logical mask on array.chain_id and array.res_id
- raise NotImplementedError
- lig_chains = getattr(chains, f"{subject}_ligand")
- rec_chains = getattr(chains, f"{subject}_receptor")
-
- if isinstance(structure, list):
- for i, arr in enumerate(structure):
- R_mask = np.isin(arr.chain_id, rec_chains)
- L_mask = np.isin(arr.chain_id, lig_chains)
- R = arr[R_mask].copy()
- L = arr[L_mask].copy()
- structure[i] = R + L
- return structure
- else:
- R_mask = np.isin(structure.chain_id, rec_chains)
- L_mask = np.isin(structure.chain_id, lig_chains)
- R = apply_mask(structure, R_mask)
- L = apply_mask(structure, L_mask)
- return R + L
-
-
-def remove_duplicate_calpha(atoms: AtomArray) -> AtomArray:
- unique_mask = []
- unique = set()
- for at in atoms:
- at_id = f"{at.chain_id}-{at.res_id}"
- mask = not (at_id in unique)
- if mask:
- unique.add(at_id)
- else:
- log.warning(f"{at_id} is duplicated!")
- unique_mask.append(mask)
- atoms = atoms[np.array(unique_mask)].copy()
- return atoms
diff --git a/src/plinder/core/structure/vendored.py b/src/plinder/core/structure/vendored.py
deleted file mode 100644
index d47b84ff0..000000000
--- a/src/plinder/core/structure/vendored.py
+++ /dev/null
@@ -1,903 +0,0 @@
-from __future__ import annotations
-
-from functools import lru_cache
-from pathlib import Path
-from typing import Union
-
-import biotite.sequence as seq
-import biotite.sequence.align as align
-import biotite.structure as struc
-import biotite.structure.io as strucio
-import numpy as np
-from biotite import TextFile
-from biotite.sequence.align import Alignment
-from biotite.structure.atoms import Atom, AtomArray, AtomArrayStack, stack
-from numpy.typing import NDArray
-
-import plinder.core.utils.constants as pc
-from plinder.core.structure.models import BackboneDefinition
-from plinder.core.utils.log import setup_logger
-
-log = setup_logger(__name__)
-
-DOCKQ_BACKBONE_ATOMS = ["C", "CA", "N", "O"]
-
-
-_AtomArrayOrStack = Union[AtomArray, AtomArrayStack]
-
-
-def biotite_pdbxfile() -> TextFile:
- from biotite.structure.io.pdbx import CIFFile
-
- return CIFFile
-
-
-def biotite_pdbfile() -> TextFile:
- from biotite.structure.io.pdb import PDBFile
-
- return PDBFile
-
-
-@lru_cache(maxsize=None)
-def rust_pdbfile() -> TextFile:
- # TODO: is this used anywhere?
- try:
- import fastpdb
-
- return fastpdb.PDBFile
- except ImportError:
- log.warning(
- "Requested fastpdb engine, but its not installed. "
- "Falling back to biotite"
- )
- return biotite_pdbfile()
-
-
-def atom_array_from_pdb_file(
- structure: Path | AtomArray,
- extra_fields: list[str] | None = None,
-) -> _AtomArrayOrStack:
- if isinstance(structure, str):
- structure = Path(structure)
-
- if isinstance(structure, Path):
- try:
- arr = strucio.load_structure(
- structure.as_posix(), extra_fields=extra_fields
- )
- assert isinstance(arr, (AtomArray, AtomArrayStack))
- return arr
- except Exception as e:
- log.error(f"Unable to parse {structure}! {str(e)}")
- raise
- return structure
-
-
-def atom_vdw_radius(at: Atom) -> float:
- try:
- if at.hetero:
- rad = struc.info.vdw_radius_single(at.element)
- else:
- rad = struc.info.vdw_radius_protor(at.res_name, at.atom_name)
- if rad is None:
- rad = struc.info.vdw_radius_single(at.element)
- except Exception:
- rad = struc.info.vdw_radius_single("N")
- assert isinstance(rad, float)
- return rad
-
-
-def backbone_mask(
- atoms: _AtomArrayOrStack, backbone_definition: str | BackboneDefinition
-) -> NDArray[np.bool_]:
- if backbone_definition == "dockq":
- mask = np.isin(atoms.atom_name, DOCKQ_BACKBONE_ATOMS)
- else:
- mask = struc.filter_peptide_backbone(atoms)
- return mask
-
-
-def mask_from_res_list(
- atoms: _AtomArrayOrStack, res_list: list[int]
-) -> NDArray[np.bool_]:
- mask = np.isin(atoms.res_id, res_list)
- return mask
-
-
-def apply_mask(atoms: _AtomArrayOrStack, mask: NDArray[np.bool_]) -> _AtomArrayOrStack:
- """Apply a boolean mask to an AtomArray or AtomArrayStack to filter atoms.
-
- Parameters
- ----------
- atoms : (AtomArray | AtomArrayStack)
- The atoms to be filtered.
- mask : NDArray[np.bool\_]
- The boolean mask that specifies which atoms to keep.
-
- Returns
- -------
- AtomArray | AtomArrayStack:
- The filtered atoms.
- """
- if isinstance(atoms, AtomArray):
- return atoms[mask]
- elif isinstance(atoms, AtomArrayStack):
- return atoms[..., mask]
- else:
- raise TypeError("atoms must be an AtomArray or AtomArrayStack")
-
-
-def filter_atoms(
- atoms: _AtomArrayOrStack,
- calpha_only: bool = False,
- backbone_only: bool = False,
- heavy_only: bool = True,
- backbone_definition: str | BackboneDefinition = "dockq",
-) -> _AtomArrayOrStack:
- if calpha_only:
- atoms = apply_mask(atoms, atoms.atom_name == "CA")
- if backbone_only:
- atoms = apply_mask(atoms, backbone_mask(atoms, backbone_definition))
- if heavy_only:
- atoms = apply_mask(atoms, atoms.element != "H")
- return atoms
-
-
-def get_backbone_atom_masks(
- native: AtomArray,
- decoy_stack: AtomArrayStack,
- backbone_only: bool,
- calpha_only: bool,
- backbone_definition: str | BackboneDefinition = "dockq",
-) -> tuple[NDArray[np.bool_], NDArray[np.bool_]]:
- # superimpose
- if backbone_only:
- model_mask = backbone_mask(decoy_stack, backbone_definition)
- native_mask = backbone_mask(native, backbone_definition)
- elif calpha_only:
- model_mask = decoy_stack.atom_name == "CA"
- native_mask = native.atom_name == "CA"
- else:
- model_mask = np.repeat(True, decoy_stack.shape[1])
- native_mask = np.repeat(True, native.shape[0])
- return native_mask, model_mask
-
-
-def renumber_res_ids(arr: _AtomArrayOrStack) -> _AtomArrayOrStack:
- try:
- # biotite for py39 and below does not have this method
- arr.res_id = struc.create_continuous_res_ids(arr)
- except AttributeError:
- # Deprecated in biotite 0.41.0, and py39 no longer supported
- arr = struc.renumber_res_ids(arr, start=1)
- return arr
-
-
-def standardize_atom_array(
- arr: _AtomArrayOrStack, standardize: bool = True
-) -> _AtomArrayOrStack:
- if not standardize:
- return arr
- std_order = struc.info.standardize_order(arr)
- arr = apply_mask(arr, std_order).copy()
- arr = renumber_res_ids(arr)
- return arr
-
-
-def stack_filter_intersect(
- arr_list: list[AtomArray],
- remove_elements: bool = False,
- standardize_order: bool = False,
-) -> tuple[AtomArrayStack, bool]:
- # Ensure only matching atoms and annotations persisted
- # This way we can construct an AtomArrayStack
- common_decoys: list[AtomArray] = []
- largest_decoy = max(arr.shape[0] for arr in arr_list)
-
- idx = 0
- while len(common_decoys) < len(arr_list):
- decoy = arr_list[idx].copy()
- if hasattr(decoy, "atom_id"):
- # All annotation categories must be equal. If there are differing
- # atom counts in the decoys, the filter_intersection will return
- # a seemingly invalid, smaller number of intersecting atoms if the
- # atom_id (an atom index) is not equal.
- decoy.set_annotation("atom_id", np.repeat(0, decoy.shape[0]))
- if len(arr_list) == 1:
- # Nothing to filter intersect on, only one decoy
- common_decoys.append(standardize_atom_array(decoy, standardize_order))
- break
-
- decoy2 = arr_list[idx + 1].copy()
- if hasattr(decoy2, "atom_id"):
- decoy2.set_annotation("atom_id", np.repeat(0, decoy2.shape[0]))
-
- if remove_elements:
- decoy.set_annotation("element", np.repeat("", decoy.shape[0]))
- decoy2.set_annotation("element", np.repeat("", decoy2.shape[0]))
- decoy_intersect = decoy[struc.filter_intersection(decoy, decoy2)]
- if len(common_decoys):
- decoy_prev = common_decoys[-1].copy()
- decoy_intersect = decoy_intersect[
- struc.filter_intersection(decoy_intersect, decoy_prev)
- ]
- common_decoys.append(standardize_atom_array(decoy_intersect, standardize_order))
- idx += 1
- # We need the final element in the list
- if (idx + 1) == len(arr_list):
- decoy2 = decoy2[struc.filter_intersection(decoy2, decoy_intersect)]
- common_decoys.append(standardize_atom_array(decoy2, standardize_order))
-
- in_common = min(common.shape[0] for common in common_decoys)
- max_in_common = max(common.shape[0] for common in common_decoys)
- smallest_decoy = sorted(common_decoys, key=lambda x: x.shape[0])[0] # type: ignore
- mismatch = largest_decoy - in_common
- if in_common < max_in_common:
- # Make sure all of the common atoms that exceed smallest are filtered out
- for i, decoy in enumerate(common_decoys):
- if decoy.shape[0] > in_common:
- decoy_intersect = decoy[
- struc.filter_intersection(decoy, smallest_decoy)
- ]
- common_decoys[i] = decoy_intersect.copy()
-
- in_common = min(common.shape[0] for common in common_decoys)
- mismatch = largest_decoy - in_common
- if mismatch > 0:
- log.warning(f"Large atom mismatch detected between decoys: {mismatch} atoms.")
- lost_chains = any(len(set(arr.chain_id)) < 2 for arr in common_decoys)
- if lost_chains and not remove_elements:
- log.warning("Attempting to remove element annotations")
- return stack_filter_intersect(
- arr_list,
- standardize_order=False,
- remove_elements=True,
- )
-
- try:
- return stack(common_decoys), standardize_order
- except Exception:
- if standardize_order and remove_elements:
- # log.warning(
- # "Caution: results will only represent the atoms in common! "
- # f"keeping {in_common} / {largest_decoy} atoms in common"
- # )
- # Escape hatch to prevent infinite recursion
- raise ValueError("Unable to create valid decoy stack! Mismatched!")
- # First see if stack can be made by removing element annotations
- if not remove_elements:
- log.warning("Attempting to remove element annotations")
- return stack_filter_intersect(
- arr_list,
- standardize_order=False,
- remove_elements=True,
- )
- # Finally, see if renumbering + standardizing can fix
- if not standardize_order:
- log.warning("Attempting to renumber and standardize order!")
- return stack_filter_intersect(
- arr_list,
- standardize_order=True,
- remove_elements=True,
- )
- # Escape hatch to prevent infinite recursion
- raise ValueError("Unable to create valid decoy stack! Mismatched!")
-
-
-def get_seq_alignments(
- ref_seq: str,
- subject_seq: str,
- gap_penalty: tuple[int, int] = (-10, -1),
-) -> list[Alignment]:
- """Generate optimal global alignments between two sequences using BLOSUM62 matrix.
-
- Parameters
- ----------
- ref_seq : (str)
- The reference sequence.
- subject_seq : (str)
- The subject sequence.
- gap_penalty : (tuple[int, int], optional)
- A tuple consisting of the gap open penalty and the gap extension penalty.
-
- Returns
- -------
- list[Alignment]:
- A list of `Alignment` objects that represent the optimal global alignment(s).
-
- Note:
- The function uses the BLOSUM62 matrix by default for alignment scoring.
- """
- ref_protein_seq = seq.ProteinSequence(ref_seq)
- subject_protein_seq = seq.ProteinSequence(subject_seq)
-
- matrix = align.SubstitutionMatrix.std_protein_matrix() # BLOSUM62 matrix
- # matrix = seq.align.SubstitutionMatrix(alph, alph, "IDENTITY")
- # alph = seq.ProteinSequence.alphabet
- alignments = align.align_optimal(
- subject_protein_seq,
- ref_protein_seq,
- matrix,
- gap_penalty=gap_penalty,
- terminal_penalty=False,
- local=False,
- max_number=1,
- )
- assert isinstance(alignments, list)
- return alignments
-
-
-def get_seq_identity(
- ref_seq: str | None = None,
- subject_seq: str | None = None,
- alignments: list[Alignment] | None = None,
- gap_penalty: tuple[int, int] = (-10, -1),
-) -> float:
- """Align an arbitrary sequence with the reference sequence
- Return sequence identity between the two.
- """
-
- all_none = all(arg is None for arg in [ref_seq, subject_seq, alignments])
- if all_none:
- raise ValueError("Must provide one of ref_seq and subject_seq or alignments!")
-
- if not alignments:
- assert isinstance(ref_seq, str)
- assert isinstance(subject_seq, str)
- alignments = get_seq_alignments(ref_seq, subject_seq, gap_penalty)
-
- aln = alignments[0]
- identity: float = align.get_sequence_identity(aln, "shortest")
- if identity < 0.90:
- log.debug(f"Alignment issue detected with identity of {identity}")
- return identity
-
-
-def calc_num_mismatches(alignments: list[Alignment]) -> tuple[int, int]:
- """Calculate number of mismatches in sequence alignment
-
- Parameters
- ----------
- alignments : list[Alignment]
- sequence alignment(s)
-
- Returns
- -------
- tuple[int, int]:
- A tuple containing number of mismatches and matches in sequence alignment, respectively.
- """
- n_matches = 0
- n_mismatches = 0
- for alignment in alignments:
- s = align.alignment.get_symbols(alignment)
- # p = subject protein sequence, u = ref sequence
- ui = -1
- pj = -1
- for p, u in zip(s[0], s[1]):
- if u:
- ui += 1
- if p:
- pj += 1
- if u and p and u != "X" and p != "X":
- n_matches += 1
- else:
- n_mismatches += 1
- return n_mismatches, n_matches
-
-
-def align_sequences(
- ref_seq: str,
- subject_seq: str,
- ref_numbering: list[int] | None = None,
- subject_numbering: list[int] | None = None,
-) -> tuple[str, str, list[int], list[int]]:
- """Aligns two sequences and returns a tuple containing the aligned sequences
- and their respective numbering.
-
- Parameters
- ----------
- ref_seq : (str)
- The reference sequence to align to.
- subject_seq : (str)
- The subject sequence to be aligned.
- ref_numbering : (list[int], optional)
- List of residue numbers for the reference sequence.
- subject_numbering : (list[int], optional)
- List of residue numbers for the subject sequence.
-
- Returns:
- tuple: A tuple containing:
- - Aligned reference sequence (str)
- - Aligned subject sequence (str)
- - Numbering of the aligned reference sequence (list[int])
- - Numbering of the aligned subject sequence (list[int])
-
- Raises
- ------
- ValueError if the sequences cannot be aligned.
- """
- alignments = get_seq_alignments(ref_seq, subject_seq)
- get_seq_identity(alignments=alignments)
- aln = alignments[0]
- s = align.alignment.get_symbols(aln)
-
- if ref_numbering is None:
- ref_numbering = list(range(1, len(ref_seq) + 1))
-
- if subject_numbering is None:
- subject_numbering = list(range(1, len(subject_seq) + 1))
-
- # assigning reference numbering to all residues in a given sequence
- # (e.g. PDB chain)
- # p = subject protein sequence, u = ref sequence
- ref_numbering_mapped = []
- subject_numbering_mapped = []
- subject_sequence_mapped = ""
- ref_sequence_mapped = ""
- ui = -1
- pj = -1
- for p, u in zip(s[0], s[1]):
- if u:
- ui += 1
- if p:
- pj += 1
- if u and p and u != "X" and p != "X":
- # ref_numbering_mapped.append(ui + 1) # 1-based
- ref_numbering_mapped.append(ref_numbering[ui])
- subject_numbering_mapped.append(subject_numbering[pj])
- ref_sequence_mapped += u
- subject_sequence_mapped += p
- return (
- ref_sequence_mapped,
- subject_sequence_mapped,
- ref_numbering_mapped,
- subject_numbering_mapped,
- )
-
-
-def _get_structure_and_res_info(
- structure: Path | _AtomArrayOrStack,
-) -> tuple[_AtomArrayOrStack, list[int], list[str]]:
- structure = atom_array_from_pdb_file(structure)
- numbering, resn = struc.get_residues(structure)
- return structure, numbering, resn
-
-
-def _convert_resn_to_sequence_and_numbering(
- structure_info: tuple[_AtomArrayOrStack, list[int], list[str]],
-) -> tuple[str, list[int]]:
- """Converts residue names to a sequence and extracts numbering."""
- _, numbering, resn = structure_info
- seq = resn2seq(resn)
- return seq, numbering
-
-
-def _align_and_map_sequences(
- ref_info: tuple[_AtomArrayOrStack, list[int], list[str]],
- subj_info: tuple[_AtomArrayOrStack, list[int], list[str]],
-) -> tuple[dict[int, int], tuple[str, str, list[int], list[int]]]:
- """Aligns two sequences and maps the numbering from the reference to the subject.
-
- This method only safely works on a single chain.
- """
- ref_seq, ref_numbering = _convert_resn_to_sequence_and_numbering(ref_info)
- subj_seq, subj_numbering = _convert_resn_to_sequence_and_numbering(subj_info)
-
- alignments = align_sequences(ref_seq, subj_seq, ref_numbering, subj_numbering)
- (
- ref_seq_mapped,
- subj_seq_mapped,
- ref_numbering_mapped,
- subj_numbering_mapped,
- ) = alignments
-
- subject_common = f"{len(subj_seq_mapped)}/{len(subj_seq)}"
- ref_common = f"{len(ref_seq_mapped)}/{len(ref_seq)}"
- log.debug(
- f"{subject_common} residues in subject matched to "
- f"{ref_common} residues in ref"
- )
-
- # Renumber subject residues to match aligned reference
- subj_resid_map = dict(zip(subj_numbering_mapped, ref_numbering_mapped))
- return subj_resid_map, alignments
-
-
-def resn2seq(resn: list[str]) -> str:
- three_to_one = pc.three_to_one_noncanonical_mapping
- seq_list = [three_to_one.get(three, "X") for three in resn]
- # Make sure we convert selenocysteine to cysteine
- # https://github.com/biotite-dev/biotite/blob/master/src/biotite/sequence/seqtypes.py#L364-L369
- # It appears that pyrrolysine (PYL->O) is also not supported - convert to lysine.
- seq_str = ""
- for s in seq_list:
- if s == "U":
- seq_str += "C"
- elif s == "O":
- seq_str += "K"
- else:
- seq_str += s
- return seq_str
-
-
-def _get_seq_aligned_structures(
- ref: Path | _AtomArrayOrStack,
- subject: Path | _AtomArrayOrStack,
-) -> tuple[_AtomArrayOrStack, _AtomArrayOrStack]:
- """Find common sequence and set identical residue numbering for common seq.
- This method only safely works on a single chain.
- """
-
- ref_info = _get_structure_and_res_info(ref)
- subj_info = _get_structure_and_res_info(subject)
-
- subj_resid_map, alns = _align_and_map_sequences(ref_info, subj_info)
-
- # Need to remove ref residues in order to match subject
- ref_structure, _, _ = ref_info
- subj_structure, _, _ = subj_info
-
- assert isinstance(ref_structure, (AtomArray, AtomArrayStack))
- assert isinstance(subj_structure, (AtomArray, AtomArrayStack))
-
- ref_mask = mask_from_res_list(ref_structure, list(subj_resid_map.values()))
- subj_mask = mask_from_res_list(subj_structure, list(subj_resid_map.keys()))
-
- ref_aligned = apply_mask(ref_structure, ref_mask)
- subject_aligned = apply_mask(subj_structure, subj_mask)
- subject_aligned.res_id = np.array(
- [subj_resid_map[ri] for ri in subject_aligned.res_id]
- )
- return ref_aligned, subject_aligned
-
-
-def _get_paired_structures_and_chains(
- ref: Path | _AtomArrayOrStack,
- subject: Path | _AtomArrayOrStack,
-) -> tuple[_AtomArrayOrStack, _AtomArrayOrStack, NDArray[np.str_], NDArray[np.str_]]:
- ref_arr: _AtomArrayOrStack = atom_array_from_pdb_file(ref)
- subject_arr: _AtomArrayOrStack = atom_array_from_pdb_file(subject)
- ref_chains = struc.get_chains(ref_arr)
- subject_chains = struc.get_chains(subject_arr)
-
- # Sometimes returns repeated chains
- _, sub_idx = np.unique(subject_chains, return_index=True)
- subject_chains = subject_chains[np.sort(sub_idx)]
-
- _, ref_idx = np.unique(ref_chains, return_index=True)
- ref_chains = ref_chains[np.sort(ref_idx)]
- if len(ref_chains) != len(subject_chains):
- raise ValueError("Ref and subject must have same number of chains!")
-
- if (ref_chains != subject_chains).any():
- log.error("Ref and subject have different chains!")
- log.warning(
- "Sequence alignment will assume this order: "
- f"{ref_chains}, {subject_chains} "
- )
- return ref_arr, subject_arr, ref_chains, subject_chains
-
-
-def get_seq_aligned_structures(
- ref: Path | _AtomArrayOrStack,
- subject: Path | _AtomArrayOrStack,
-) -> tuple[_AtomArrayOrStack, _AtomArrayOrStack]:
- """Computes per-chain sequence alignments between reference and subject
- structures, and creates a new set of structures where the residue numbers
- in the subject structure are renumbered to match those in the reference
- structure for the aligned sequence segments for each chain.
-
- This function processes each chain separately, aligns their sequences,
- and then constructs the multi-chain structure using the chain-aligned
- sequences.
-
- Parameters
- ----------
- ref : Path | _AtomArrayOrStack
- The file path or structure array of the reference structure.
- subject : Path | _AtomArrayOrStack
- The file path or structure array of the subject structure to align with the reference.
-
- Returns
- -------
- tuple
- A tuple containing:
- - Reference structure with aligned sequence and residue numbering (_AtomArrayOrStack).
- - Subject structure with aligned sequence and residue numbering (_AtomArrayOrStack).
-
- Raises
- ------
- ValueError
- If the reference and subject structures do not have the same number of chains or if the chains cannot be matched properly.
- """
- (
- ref_arr,
- subject_arr,
- ref_chains,
- subject_chains,
- ) = _get_paired_structures_and_chains(ref, subject)
- ref_arrays = []
- subject_arrays = []
- for ref_ch, subject_ch in zip(ref_chains, subject_chains):
- ref_mask = ref_arr.chain_id == ref_ch
- subject_mask = subject_arr.chain_id == subject_ch
- ref_ch_arr = apply_mask(ref_arr, ref_mask)
- subject_ch_arr = apply_mask(subject_arr, subject_mask)
- ref_aligned, subject_aligned = _get_seq_aligned_structures(
- ref_ch_arr, subject_ch_arr
- )
- ref_arrays.append(ref_aligned)
- subject_arrays.append(subject_aligned)
-
- # construct multi-chain objects again
- ref_aligned = ref_arrays.pop(0)
- subject_aligned = subject_arrays.pop(0)
- for ref_arr, sub_arr in zip(ref_arrays, subject_arrays):
- ref_aligned += ref_arr
- subject_aligned += sub_arr
- return ref_aligned, subject_aligned
-
-
-def get_per_chain_seq_alignments(
- ref: Path | _AtomArrayOrStack,
- subject: Path | _AtomArrayOrStack,
-) -> dict[str, dict[int, int]]:
- """Computes per-chain sequence alignments between reference and subject
- structures, and provides a mapping of residue numbers from the subject
- to the reference for each chain.
-
- This function processes each chain separately, aligns their sequences,
- and creates a mapping of residue numbering from the subject structure
- to the reference structure based on sequence alignment. It is designed
- to work with multi-chain structures, aligning each chain independently.
-
- Parameters
- ----------
- ref : Path | _AtomArrayOrStack
- The file path or structure array of the reference structure.
- subject : Path | _AtomArrayOrStack
- The file path or structure array of the subject structure to align with the reference.
-
- Returns
- -------
- dict[str, dict[int, int]]
- A dictionary where keys are chain identifiers from the subject structure and values are dictionaries mapping residue numbers in the subject structure to those in the reference structure for the aligned sequence segments.
-
- Raises
- ------
- ValueError
- If the reference and subject structures do not have the same number of chains or if the chains cannot be matched properly.
- """
- (
- ref_arr,
- subject_arr,
- ref_chains,
- subject_chains,
- ) = _get_paired_structures_and_chains(ref, subject)
- ch_res_maps: dict[str, dict[int, int]] = {}
- for ref_ch, subject_ch in zip(ref_chains, subject_chains):
- ref_mask = ref_arr.chain_id == ref_ch
- subject_mask = subject_arr.chain_id == subject_ch
- ref_ch_arr = apply_mask(ref_arr, ref_mask)
- subject_ch_arr = apply_mask(subject_arr, subject_mask)
-
- ref_info = _get_structure_and_res_info(ref_ch_arr)
- subj_info = _get_structure_and_res_info(subject_ch_arr)
- existing2new, alns = _align_and_map_sequences(ref_info, subj_info)
- ch_res_maps[subject_ch] = existing2new
- return ch_res_maps
-
-
-def invert_chain_seq_map(
- seq_map: dict[str, dict[int, int]] | list[dict[str, dict[int, int]]],
-) -> dict[str, dict[int, int]] | list[dict[str, dict[int, int]]]:
- def _invert(seq_map: dict[str, dict[int, int]]) -> dict[str, dict[int, int]]:
- rev_map: dict[str, dict[int, int]] = {ch: {} for ch in seq_map}
- for ch, rmap in seq_map.items():
- rev_map[ch] = {v: k for k, v in rmap.items()}
- return rev_map
-
- inverted: dict[str, dict[int, int]] | list[dict[str, dict[int, int]]]
- if isinstance(seq_map, list):
- inverted = []
- for sm in seq_map:
- inverted.append(_invert(sm))
- else:
- inverted = _invert(seq_map)
- return inverted
-
-
-def get_buried_sasa(
- a: struc.AtomArray,
- b: struc.AtomArray,
- point_number: int = 200,
- ignore_ions: bool = True,
-) -> int:
- """Calculate the rounded dSASA value for a pair of interacting substructures (chains).
-
- Parameters
- ----------
- a : struc.AtomArray
- The first substructure (chain).
- b : struc.AtomArray
- The second substructure (chain).
- point_number : int, optional
- The number of points per atom, by default 200.
- This parameter affects the speed and the accuracy of the calculation.
-
- Returns
- -------
- int
- The rounded dSASA value.
-
- Examples
- --------
- >>> atom1a = struc.atoms.Atom([0,0,0], chain_id="A")
- >>> atom2a = struc.atoms.Atom([1,1,1], chain_id="A")
- >>> atom1b = struc.atoms.Atom([2,2,2], chain_id="B")
- >>> atom2b = struc.atoms.Atom([3,3,3], chain_id="B")
- >>> a = struc.atoms.array([atom1a, atom2a])
- >>> b = struc.atoms.array([atom1b, atom2b])
- >>> get_buried_sasa(a, b, ignore_ions=False)
- 0
- """
- dsasa: int = 0
- try:
- sasa_ab = np.sum(
- np.nan_to_num(
- struc.sasa(a + b, point_number=point_number, ignore_ions=ignore_ions)
- )
- )
- sasa_a = np.sum(
- np.nan_to_num(
- struc.sasa(a, point_number=point_number, ignore_ions=ignore_ions)
- )
- )
- sasa_b = np.sum(
- np.nan_to_num(
- struc.sasa(b, point_number=point_number, ignore_ions=ignore_ions)
- )
- )
- dsasa = sasa_a + sasa_b - sasa_ab
- dsasa = int(np.round(dsasa))
- except (KeyError, ValueError) as e:
- log.error(f"Failed to calculate buried sasa using ProtOr vdw radius: {e}")
- sasa_ab = np.sum(
- np.nan_to_num(
- struc.sasa(
- a + b,
- point_number=point_number,
- ignore_ions=ignore_ions,
- vdw_radii="Single",
- )
- )
- )
- sasa_a = np.sum(
- np.nan_to_num(
- struc.sasa(
- a,
- point_number=point_number,
- ignore_ions=ignore_ions,
- vdw_radii="Single",
- )
- )
- )
- sasa_b = np.sum(
- np.nan_to_num(
- struc.sasa(
- b,
- point_number=point_number,
- ignore_ions=ignore_ions,
- vdw_radii="Single",
- )
- )
- )
- dsasa = sasa_a + sasa_b - sasa_ab
- dsasa = int(np.round(dsasa))
- except Exception as e:
- log.error(
- f"Failed to calculate buried sasa even with vdw_radii=Single, returning 0! {e}"
- )
- return dsasa
-
-
-def get_resolved_resi_from_atom_array(model: _AtomArrayOrStack) -> dict[str, list[int]]:
- """Returns a list of resolved resi (only checking the CA atom) in the PDB file.
-
- Parameters
- ----------
- model : _AtomArrayOrStack
- AtomArray or Stack
-
- Returns
- -------
- List[int]
- A list of resolved resi in the PDB file.
- """
- model_ch: set[str] = set(model.chain_id)
- per_chain_resolved: dict[str, list[int]] = {}
- for ch in model_ch:
- per_chain_resolved[ch] = [
- int(res_id)
- for res_id in model.res_id[
- (model.atom_name == "CA") & (model.chain_id == ch)
- ].tolist()
- ]
- return per_chain_resolved
-
-
-def get_resolved_resi(pdb_path: str) -> dict[str, list[int]]:
- """Returns a list of resolved resi (only checking the CA atom) in the PDB file.
-
- Parameters
- ----------
- pdb_path : str
- The path to the PDB file.
-
- Returns
- -------
- List[int]
- A list of resolved resi in the PDB file.
- """
- model: _AtomArrayOrStack = atom_array_from_pdb_file(Path(pdb_path))
- resolved_resi = get_resolved_resi_from_atom_array(model)
- return resolved_resi
-
-
-def write_pdb(arr: AtomArray, filepath: Path) -> None:
- """Write AtomArray to a PDB file.
-
- Parameters
- ----------
- arr : AtomArray
- AtomArray to save to PDB file.
- filepath : Path
- Path to outut PDB file.
-
- Returns
- -------
- None
-
- """
- if not filepath.parent.is_dir():
- filepath.parent.mkdir(exist_ok=True, parents=True)
-
- strucio.save_structure(filepath, arr)
-
-
-def cif_to_pdb(
- cif_path: str, pdb_path: str, chains: dict[str, str] | None = None
-) -> None:
- """Convert CIF file to PDB file
-
- Parameters
- ----------
- cif_path : str
- The path to the CIF file to be converted.
- pdb_path : str
- The path where the converted PDB file will be saved.
- chains : Optional[dict], default is None
- If provided, only the chains specified in the dictionary will be kept
- and they will be renamed according to the dictionary.
- Note: The new chain names must be single characters to be PDB compatible.
- """
- # temp workaround for biotite API
- from biotite.structure.io import pdbx
-
- f = biotite_pdbxfile()
- pdbx_file = f.read(cif_path)
- model = pdbx.get_structure(
- pdbx_file, model=1, use_author_fields=False, extra_fields=["b_factor", "charge"]
- )
- # print(f"DEBUG: {cif_path} has {sorted(np.unique(model.chain_id))} chains")
- if chains is not None:
- mask = np.isin(model.chain_id, list(chains.keys()))
- if np.sum(mask) == 0:
- print(f"WARNING: chains {list(chains.keys())} not found in {cif_path}")
- return
- model = model[mask]
- model_orig = model.copy()
- for old_chain_id, new_chain_id in chains.items():
- mask = model_orig.chain_id == old_chain_id
- model.chain_id[mask] = new_chain_id
- write_pdb(model, Path(pdb_path))
diff --git a/src/plinder/core/utils/config.py b/src/plinder/core/utils/config.py
index 5006dc800..9afc36f13 100644
--- a/src/plinder/core/utils/config.py
+++ b/src/plinder/core/utils/config.py
@@ -15,6 +15,9 @@
LOG = setup_logger(__name__)
+# Default public release: a YYYY-MM PDB snapshot stamp on the Cameo file server.
+DEFAULT_RELEASE = "2026-09"
+
def _validate_cfg(*, cfg: DictConfig, schema: dict[str, Any]) -> DictConfig:
"""
@@ -35,10 +38,14 @@ def _validate_cfg(*, cfg: DictConfig, schema: dict[str, Any]) -> DictConfig:
the validated config with post-init validation logic
"""
keys = set(cfg.keys()).union(set(schema.keys()))
- cfg = OmegaConf.to_container(cfg)
- cfg.get("data", {}).pop("plinder_dir", None)
- cfg.get("data", {}).pop("plinder_remote", None)
- return DictConfig({str(k): schema[str(k)](**cfg.get(k, {})) for k in keys})
+ container = OmegaConf.to_container(cfg)
+ if not isinstance(container, dict):
+ raise TypeError("configuration root must be a mapping")
+ data = container.get("data")
+ if isinstance(data, dict):
+ data.pop("plinder_dir", None)
+ data.pop("plinder_remote", None)
+ return DictConfig({str(k): schema[str(k)](**container.get(k, {})) for k in keys})
def _clean_sort_config(*, cfg: Any) -> Any:
@@ -148,7 +155,7 @@ def __call__(
args.append(DictConfig(OmegaConf.load(StringIO(config_contents))))
try:
# catchall for non-standard execution models
- # e.g. in metaflow or jupyter
+ # e.g. in job runners or Jupyter
cli = OmegaConf.from_cli(config_args)
# omegaconf casts single int-like two_char_codes to int
if cli.get("scatter", {}).get("two_char_codes") is not None:
@@ -205,24 +212,26 @@ class DataConfig:
Attributes
----------
plinder_release : str
- the plinder dataset version
- plinder_iteration : str
- the plinder dataset iteration
+ the ingest month for the PLINDER release, formatted as ``YYYY-MM``
+ plinder_release_number : str
+ the numbered release for that ingest month
plinder_mount : str, default="~/.local/share/plinder"
the resting place for the plinder dataset
plinder_bucket : str, default="plinder"
- the plinder bucket
+ the local cache subdirectory name
plinder_dir : str
set automatically
plinder_remote : str
- set automatically
+ set automatically; the release root under ``PLINDER_MIRROR_URL``
+ (default ``https://cameo3d.org/plinder``), in ``PLINDER-YYYY-MM``
+ directories
"""
plinder_release: str = field(
- default_factory=partial(_getenv_default, "PLINDER_RELEASE", "2024-06")
+ default_factory=partial(_getenv_default, "PLINDER_RELEASE", DEFAULT_RELEASE)
)
- plinder_iteration: str = field(
- default_factory=partial(_getenv_default, "PLINDER_ITERATION", "v2")
+ plinder_release_number: str = field(
+ default_factory=partial(_getenv_default, "PLINDER_RELEASE_NUMBER", "")
)
plinder_mount: str = field(
default_factory=partial(
@@ -235,36 +244,22 @@ class DataConfig:
plinder_dir: str = field(init=False)
plinder_remote: str = field(init=False)
- ingest: str = "ingest"
- validation: str = "validation"
- dbs: str = "dbs"
- clusters: str = "clusters"
- entries: str = "entries"
- fingerprints: str = "fingerprints"
- fingerprint_file: str = "ligands_per_system.parquet"
- index: str = "index"
- ligand_scores: str = "ligand_scores"
- ligands: str = "ligands"
- links: str = "links"
- linked_structures: str = "linked_structures"
- mmp: str = "mmp"
scores: str = "scores"
- splits: str = "splits"
- split_file: str = "split.parquet"
- systems: str = "systems"
- index_file: str = "annotation_table.parquet"
+ source_mmcifs: str = "source_mmcifs"
force_update: bool = False
def __post_init__(self) -> None:
- suffix = self.plinder_release
- if self.plinder_iteration:
- suffix = f"{self.plinder_release}/{self.plinder_iteration}"
+ suffix = self.plinder_release.strip("/")
+ release_number = str(self.plinder_release_number).strip("/")
+ if suffix and release_number:
+ suffix = f"{suffix}/{release_number}"
if self.plinder_mount in ["/plinder", "/", ""]:
- self.plinder_dir = f"{self.plinder_mount}/{suffix}"
+ root = Path(self.plinder_mount or "/")
else:
- self.plinder_dir = f"{self.plinder_mount}/{self.plinder_bucket}/{suffix}"
- base = getenv("PLINDER_MIRROR_URL", "https://plinderdata.org").rstrip("/")
- self.plinder_remote = f"{base}/{suffix}"
+ root = Path(self.plinder_mount) / self.plinder_bucket
+ self.plinder_dir = (root / suffix).as_posix() if suffix else root.as_posix()
+ base = getenv("PLINDER_MIRROR_URL", "https://cameo3d.org/plinder").rstrip("/")
+ self.plinder_remote = f"{base}/PLINDER-{suffix}" if suffix else base
@dataclass
diff --git a/src/plinder/core/utils/cpl.py b/src/plinder/core/utils/cpl.py
index 68f539247..1b29a507a 100644
--- a/src/plinder/core/utils/cpl.py
+++ b/src/plinder/core/utils/cpl.py
@@ -1,6 +1,7 @@
-"""Public dataset access with cloudpathlib and a local immutable-release cache."""
+"""Public dataset access with cloudpathlib and a local release cache."""
import os
+import re
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
from typing import Callable, Iterable, TypeVar
@@ -9,11 +10,29 @@
from tqdm import tqdm
from plinder.core.utils.config import get_config
-from plinder.core.utils.r2 import ReleaseClient, checked_key, manifest
+from plinder.core.utils.http import ReleaseClient, checked_key
T = TypeVar("T")
+def is_offline() -> bool:
+ """Return whether remote access is disabled.
+
+ ``PLINDER_OFFLINE`` remains the canonical setting. The
+ ``PLINDER_OFFLINE_MODE`` alias is accepted for compatibility with cluster
+ launch environments that use the longer name.
+ """
+ values = (
+ os.getenv("PLINDER_OFFLINE"),
+ os.getenv("PLINDER_OFFLINE_MODE"),
+ )
+ return any(
+ value is not None
+ and value.strip().lower() not in {"", "0", "false", "no", "off"}
+ for value in values
+ )
+
+
def thread_pool(func: Callable[[T], None], items: Iterable[T]) -> None:
with ThreadPoolExecutor(max_workers=8) as pool:
list(pool.map(func, items))
@@ -21,12 +40,12 @@ def thread_pool(func: Callable[[T], None], items: Iterable[T]) -> None:
def _get_client() -> ReleaseClient:
cfg = get_config().data
- if (cfg.plinder_bucket, cfg.plinder_release, cfg.plinder_iteration) != (
- "plinder",
- "2024-06",
- "v2",
+ if cfg.plinder_release_number or not re.fullmatch(
+ r"\d{4}-(0[1-9]|1[0-2])", cfg.plinder_release
):
- raise ValueError("R2 downloads support only plinder/2024-06/v2")
+ raise ValueError(
+ "HTTP downloads support only YYYY-MM releases without a release number"
+ )
remote = str(cfg.plinder_remote).rstrip("/")
url = urlsplit(remote)
if (
@@ -37,9 +56,7 @@ def _get_client() -> ReleaseClient:
or url.username
or url.password
):
- raise ValueError("PLINDER_MIRROR_URL must be an HTTP(S) bucket URL")
- if cfg.force_update:
- manifest.cache_clear()
+ raise ValueError("PLINDER_MIRROR_URL must be an HTTP(S) file-server URL")
return ReleaseClient(remote)
@@ -49,14 +66,18 @@ def _download(client: ReleaseClient, paths: list[Path], force_progress: bool) ->
def fetch(path: Path) -> None:
key = checked_key(path.resolve().relative_to(root).as_posix())
- if key not in client.records:
- raise FileNotFoundError(f"File absent from release manifest: {key}")
+ remote = client.path(key)
+ if not remote.exists():
+ raise FileNotFoundError(f"File absent from release: {key}")
+ metadata = client.metadata(remote)
if (
cfg.force_update
or not path.is_file()
- or path.stat().st_size != client.records[key]["size"]
+ or path.stat().st_size != metadata.size
+ or metadata.modified is None
+ or path.stat().st_mtime != metadata.modified
):
- client.path(key).download_to(path)
+ remote.download_to(path)
if path.suffix == ".zip":
path.with_name(path.stem + "_done").unlink(missing_ok=True)
@@ -71,37 +92,74 @@ def fetch(path: Path) -> None:
def download_paths(*, paths: list[Path], force_progress: bool = False) -> None:
- if paths and not os.getenv("PLINDER_OFFLINE"):
+ """
+ Download pre-determined paths from the release mirror concurrently. This
+ is useful when we want to process a pre-determined subset of the data
+ rather than all of the contents of the dataset.
+
+ Parameters
+ ----------
+ paths : list[Path]
+ the local paths to download, resolved against the release cache root
+ force_progress : bool, default=False
+ if True, always display a progress bar
+ """
+ if paths and not is_offline():
_download(_get_client(), paths, force_progress)
+def _prune_unpublished(directory: Path, published: set[str]) -> None:
+ """Remove cached Parquet files that the release no longer lists.
+
+ Directory artifacts are read as whole Parquet datasets, so a file dropped
+ from an updated release would otherwise be read alongside its replacement.
+ """
+ root = Path(get_config().data.plinder_dir)
+ for path in directory.rglob("*.parquet"):
+ if path.is_symlink() or not path.is_file():
+ continue
+ if path.relative_to(root).as_posix() not in published:
+ path.unlink()
+
+
def get_plinder_path(
*, rel: str = "", download: bool = True, force_progress: bool = False
) -> Path:
+ """
+ Get the local cache path for a file or directory in the plinder release,
+ downloading it first if requested. This provides a convenient way to
+ manage local file caching since it is automatically synced from the
+ release mirror on access in case remote files change.
+
+ Parameters
+ ----------
+ rel : str
+ Relative path to the file or directory.
+ download : bool, default=True
+ if True, download the files
+ force_progress : bool, default=False
+ if True, force progress bar even if < 10 files
+
+ Returns
+ -------
+ Path
+ The local cache path.
+ """
root = Path(get_config().data.plinder_dir)
local = root / checked_key(rel)
- if os.getenv("PLINDER_OFFLINE") or not download:
+ if is_offline() or not download:
return local
+ local.resolve().relative_to(root.resolve())
client = _get_client()
remote = client.path(rel)
if not remote.exists():
- raise FileNotFoundError(f"Path absent from release manifest: {rel}")
+ raise FileNotFoundError(f"Path absent from release: {rel}")
files = (
[remote] if remote.is_file() else [p for p in remote.rglob("*") if p.is_file()]
)
- _download(client, [root / client.key(p) for p in files], force_progress)
+ keys = {client.key(p) for p in files}
+ _download(client, [root / key for key in sorted(keys)], force_progress)
+ if not remote.is_file():
+ local.mkdir(parents=True, exist_ok=True)
+ _prune_unpublished(local, keys)
return local
-
-
-def list_zip_paths(rel: str) -> list[Path]:
- root = Path(get_config().data.plinder_dir)
- rel = checked_key(rel)
- if os.getenv("PLINDER_OFFLINE"):
- return sorted((root / rel).glob("*.zip"))
- client = _get_client()
- return [root / client.key(p) for p in client.path(rel).glob("*.zip")]
-
-
-def get_plinder_paths(*, paths: list[Path]) -> list[Path]:
- download_paths(paths=paths)
- return paths
diff --git a/src/plinder/core/utils/files.py b/src/plinder/core/utils/files.py
new file mode 100644
index 000000000..81ad574cb
--- /dev/null
+++ b/src/plinder/core/utils/files.py
@@ -0,0 +1,54 @@
+"""Small file helpers shared by release builders and readers."""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import os
+import shutil
+from errno import EACCES, EPERM, EXDEV
+from pathlib import Path
+from typing import Any
+from uuid import uuid4
+
+
+def link_or_copy_file(source: Path, destination: Path) -> None:
+ """Reuse immutable files on one filesystem, copying across filesystems."""
+ if source.is_symlink():
+ destination.symlink_to(source.readlink())
+ return
+ try:
+ os.link(source, destination)
+ except OSError as exc:
+ if exc.errno not in {EACCES, EPERM, EXDEV}:
+ raise
+ shutil.copy2(source, destination)
+
+
+def file_sha256(path: Path) -> str:
+ """Hash a file without loading it into memory."""
+ digest = hashlib.sha256()
+ with path.open("rb") as handle:
+ while chunk := handle.read(1024 * 1024):
+ digest.update(chunk)
+ return digest.hexdigest()
+
+
+def read_json_cache(path: Path) -> dict[str, Any] | None:
+ """Read an optional cache marker; missing or malformed markers are cache misses."""
+ try:
+ payload = json.loads(path.read_text())
+ except (OSError, ValueError, TypeError):
+ return None
+ return payload if isinstance(payload, dict) else None
+
+
+def write_json_atomic(path: Path, payload: dict[str, Any]) -> None:
+ """Replace a JSON file only after writing its complete contents."""
+ path.parent.mkdir(parents=True, exist_ok=True)
+ temporary = path.with_name(f".{path.name}.{uuid4().hex}.tmp")
+ try:
+ temporary.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n")
+ temporary.replace(path)
+ finally:
+ temporary.unlink(missing_ok=True)
diff --git a/src/plinder/core/utils/gcs.py b/src/plinder/core/utils/gcs.py
deleted file mode 100644
index 4de4a27f1..000000000
--- a/src/plinder/core/utils/gcs.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from concurrent.futures import ThreadPoolExecutor
-from functools import wraps
-from pathlib import Path
-from time import sleep
-from typing import Any, Callable, Optional, TypeVar
-
-from google.cloud.storage.bucket import Bucket
-from google.cloud.storage.client import Client
-from omegaconf import DictConfig
-from tqdm import tqdm
-
-from plinder.core.utils.dec import timeit
-from plinder.core.utils.log import setup_logger
-
-BUCKET = "plinder"
-BUCKETS: dict[str, Bucket] = {}
-LOG = setup_logger(__name__)
-T = TypeVar("T")
-
-
-def retry(f: Optional[Callable[..., T]] = None, retries: int = 5) -> Callable[..., T]:
- def decorator(func: Callable[..., T]) -> Callable[..., T]:
- @wraps(func)
- def inner(**kwargs: Any) -> T:
- bucket = kwargs.get("bucket", None)
- if bucket is None:
- cfg = kwargs.get("cfg", None)
- if cfg is None:
- name = kwargs.get("bucket_name")
- if name is not None:
- client = Client()
- bucket = client.bucket(name)
- BUCKETS[name] = bucket
- else:
- client = Client.create_anonymous_client()
- bucket = client.bucket(BUCKET)
- BUCKETS[BUCKET] = bucket
- else:
- if cfg.data.plinder_bucket in BUCKETS:
- bucket = BUCKETS[cfg.data.plinder_bucket]
- else:
- if cfg.data.plinder_bucket == BUCKET:
- client = Client.create_anonymous_client()
- else:
- client = Client()
- bucket = client.bucket(cfg.data.plinder_bucket)
- BUCKETS[cfg.data.plinder_bucket] = bucket
- exc = None
- for i in range(1, retries + 1):
- try:
- return func(bucket=bucket, **kwargs)
- except Exception as e:
- LOG.error(f"retry: {e}")
- exc = e
- sleep(2**i)
- raise Exception(f"Timeout error {exc}")
-
- return inner
-
- return decorator(f) if f else decorator # type: ignore
-
-
-@retry
-def download_as_str(
- *,
- gcs_path: str,
- cfg: Optional[DictConfig] = None,
- bucket_name: Optional[str] = None,
- bucket: Optional["Bucket"] = None,
-) -> str:
- assert bucket is not None
- blob = bucket.blob("/".join(Path(gcs_path).parts[2:]))
- return str(blob.download_as_bytes().decode("utf8"))
-
-
-@retry
-def download_to_file(
- *,
- gcs_path: str,
- local_path: str,
- cfg: Optional[DictConfig] = None,
- bucket_name: Optional[str] = None,
- bucket: Optional["Bucket"] = None,
-) -> None:
- assert bucket is not None
- blob = bucket.blob("/".join(Path(gcs_path).parts[2:]))
- blob.download_to_filename(local_path)
-
-
-@retry
-def list_dir(
- *,
- gcs_path: str,
- cfg: Optional[DictConfig] = None,
- bucket_name: Optional[str] = None,
- bucket: Optional["Bucket"] = None,
-) -> list[str]:
- assert bucket is not None
- prefix = "/".join(Path(gcs_path.rstrip("/")).parts[2:])
- return [
- f"gs://{bucket.name}/{blob.name}"
- for blob in bucket.list_blobs(prefix=f"{prefix}/")
- ]
-
-
-@retry
-def upload_from_file(
- *,
- local_path: str,
- gcs_path: str,
- cfg: Optional[DictConfig] = None,
- bucket_name: Optional[str] = None,
- bucket: Optional["Bucket"] = None,
-) -> None:
- assert bucket is not None
- blob = bucket.blob("/".join(Path(gcs_path).parts[2:]))
- with open(local_path, "rb") as f:
- blob.upload_from_file(f)
-
-
-@timeit
-def download_many(
- *,
- gcs_paths: list[str],
- local_paths: list[str],
- cfg: Optional[DictConfig] = None,
- bucket_name: Optional[str] = None,
-) -> None:
- if not len(gcs_paths):
- LOG.info("No files to download")
- return
- if not len(gcs_paths) == len(local_paths):
- raise ValueError("gcs_paths and local_paths must have the same length")
-
- def ordered(gcs_path: str, local_path: str) -> None:
- download_to_file(
- gcs_path=gcs_path, local_path=local_path, cfg=cfg, bucket_name=bucket_name
- )
-
- with ThreadPoolExecutor() as executor:
- res = executor.map(ordered, gcs_paths, local_paths)
- if len(gcs_paths) > 20:
- list(tqdm(res, total=len(gcs_paths)))
- else:
- LOG.info(f"downloading {len(gcs_paths)} files")
-
-
-def download_if_not_exists(
- *,
- local_paths: list[Path],
- remote_root: Path,
- cfg: Optional[DictConfig] = None,
- bucket_name: Optional[str] = None,
-) -> None:
- gcs_paths = []
- need_download = []
- for local_path in local_paths:
- if not local_path.is_file():
- need_download.append(local_path.as_posix())
- gcs_paths.append((remote_root / local_path.name).as_posix())
- if len(need_download):
- download_many(
- gcs_paths=gcs_paths,
- local_paths=need_download,
- cfg=cfg,
- )
diff --git a/src/plinder/core/utils/http.py b/src/plinder/core/utils/http.py
new file mode 100644
index 000000000..4d3fa90a4
--- /dev/null
+++ b/src/plinder/core/utils/http.py
@@ -0,0 +1,232 @@
+"""Directory listing and atomic downloads from the public PLINDER file server."""
+
+import os
+import shutil
+from dataclasses import dataclass
+from email.utils import parsedate_to_datetime
+from html.parser import HTMLParser
+from http.client import HTTPException
+from os import PathLike
+from pathlib import Path
+from tempfile import TemporaryDirectory
+from time import sleep
+from typing import Callable, Iterator, TypeVar, cast
+from urllib.error import HTTPError
+from urllib.parse import quote, unquote, urlsplit
+from urllib.request import BaseHandler, Request
+
+from cloudpathlib import CloudPath as BaseCloudPath
+from cloudpathlib import HttpPath, HttpsClient, HttpsPath
+
+CloudPathT = TypeVar("CloudPathT", bound=BaseCloudPath)
+T = TypeVar("T")
+
+
+def checked_key(key: str) -> str:
+ if key and ("\\" in key or any(p in {"", ".", ".."} for p in key.split("/"))):
+ raise ValueError(f"Invalid dataset path: {key!r}")
+ return key
+
+
+class _TimeoutHandler(BaseHandler):
+ def http_request(self, request: Request) -> Request:
+ # Bound connection/read inactivity without limiting total transfer time.
+ request.timeout = 60
+ return request
+
+ https_request = http_request
+
+
+def _retry(operation: Callable[[], T]) -> T:
+ for attempt in range(3):
+ try:
+ return operation()
+ except (OSError, HTTPException) as exc:
+ if isinstance(exc, HTTPError) and exc.code not in {
+ 408,
+ 429,
+ 500,
+ 502,
+ 503,
+ 504,
+ }:
+ raise
+ if attempt == 2:
+ raise
+ sleep(2**attempt)
+ raise AssertionError("unreachable")
+
+
+class _DirectoryIndex(HTMLParser):
+ def __init__(self) -> None:
+ super().__init__()
+ self.links: list[str] = []
+ self.title = ""
+ self.in_title = False
+
+ def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
+ if tag == "title":
+ self.in_title = True
+ if tag == "a":
+ self.links.extend(
+ value for name, value in attrs if name == "href" and value
+ )
+
+ def handle_endtag(self, tag: str) -> None:
+ if tag == "title":
+ self.in_title = False
+
+ def handle_data(self, data: str) -> None:
+ if self.in_title:
+ self.title += data
+
+
+@dataclass(frozen=True)
+class FileMetadata:
+ size: int
+ modified: float | None
+ is_dir: bool
+
+
+class ReleaseClient(HttpsClient):
+ """Read a fresh directory index and HTTP metadata for each cache access."""
+
+ def __init__(self, remote: str):
+ super().__init__(auth=_TimeoutHandler())
+ self.remote = remote.rstrip("/")
+ # These caches live only for one get_plinder_path/download_paths call.
+ self._metadata: dict[str, FileMetadata] = {}
+ self._listed: dict[str, bool] = {}
+ self.dir_matcher = self._is_directory
+
+ def CloudPath(self, path: str | CloudPathT, *parts: str) -> CloudPathT:
+ cls = HttpsPath if self.remote.startswith("https:") else HttpPath
+ return cast(CloudPathT, cls(str(path), *parts, client=self))
+
+ def path(self, key: str = "") -> HttpPath:
+ return cast(
+ HttpPath,
+ self.CloudPath(
+ self.remote + ("/" + quote(checked_key(key), safe="/") if key else "")
+ ),
+ )
+
+ def key(self, path: str | BaseCloudPath) -> str:
+ url = str(path).removesuffix("/")
+ if url == self.remote:
+ return ""
+ if not url.startswith(self.remote + "/"):
+ raise ValueError("Path is outside the release")
+ return checked_key(unquote(url[len(self.remote) + 1 :]))
+
+ def metadata(self, path: HttpPath) -> FileMetadata:
+ key = self.key(path)
+ if key not in self._metadata:
+
+ def read() -> FileMetadata:
+ request = Request(
+ str(path), method="HEAD", headers={"Cache-Control": "no-cache"}
+ )
+ with self.opener.open(request) as response:
+ if self.key(response.geturl()) != key:
+ raise ValueError(
+ "File server redirected outside the requested path"
+ )
+ is_dir = response.geturl().endswith("/")
+ size = response.headers.get("Content-Length")
+ if not is_dir and size is None:
+ raise ValueError("File server must supply Content-Length")
+ modified = response.headers.get("Last-Modified")
+ return FileMetadata(
+ int(size or 0),
+ parsedate_to_datetime(modified).timestamp()
+ if modified
+ else None,
+ is_dir,
+ )
+
+ self._metadata[key] = _retry(read)
+ return self._metadata[key]
+
+ def _is_directory(self, url: str) -> bool:
+ key = self.key(url)
+ if key in self._listed:
+ return self._listed[key]
+ return self.metadata(self.path(key)).is_dir
+
+ def _exists(self, path: HttpPath) -> bool:
+ if self.key(path) in self._listed:
+ return True
+ try:
+ self.metadata(path)
+ except HTTPError as exc:
+ if exc.code == 404:
+ return False
+ raise
+ return True
+
+ def _list_dir(
+ self, path: HttpPath, recursive: bool
+ ) -> Iterator[tuple[HttpPath, bool]]:
+ key = self.key(path)
+ url = str(self.path(key)) + "/"
+
+ def read() -> str:
+ request = Request(url, headers={"Cache-Control": "no-cache"})
+ with self.opener.open(request) as response:
+ if self.key(response.geturl()) != key:
+ raise ValueError(
+ "File server redirected outside the requested directory"
+ )
+ return cast(bytes, response.read()).decode("utf-8")
+
+ index = _DirectoryIndex()
+ index.feed(_retry(read))
+ if not index.title.startswith(("Index of ", "Directory listing for ")):
+ raise ValueError("Expected an HTTP directory index")
+ children: dict[str, bool] = {}
+ for href in index.links:
+ link = urlsplit(href)
+ if link.scheme or link.netloc or link.query or link.fragment:
+ continue
+ name = unquote(link.path.removesuffix("/"))
+ # Only immediate relative children: ignore parent/sort/navigation links.
+ if not name or name in {".", ".."} or "/" in name or "\\" in name:
+ continue
+ child = checked_key(f"{key}/{name}" if key else name)
+ children[child] = link.path.endswith("/")
+ self._listed.update(children)
+ for child, is_dir in sorted(children.items()):
+ child_path = self.path(child)
+ yield child_path, is_dir
+ if recursive and is_dir:
+ yield from self._list_dir(child_path, recursive=True)
+
+ def _download_file(self, path: HttpPath, local_path: str | PathLike[str]) -> Path:
+ destination = Path(local_path)
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ with TemporaryDirectory(dir=destination.parent) as tmp:
+ temporary = Path(tmp) / "download"
+
+ def download() -> None:
+ request = Request(str(path), headers={"Cache-Control": "no-cache"})
+ with self.opener.open(request) as response:
+ if self.key(response.geturl()) != self.key(path):
+ raise ValueError(
+ "File server redirected outside the requested path"
+ )
+ size = response.headers.get("Content-Length")
+ if size is None:
+ raise ValueError("File server must supply Content-Length")
+ with temporary.open("wb") as stream:
+ shutil.copyfileobj(response, stream)
+ if temporary.stat().st_size != int(size):
+ raise OSError("Incomplete dataset download")
+ modified = response.headers.get("Last-Modified")
+ if modified:
+ timestamp = parsedate_to_datetime(modified).timestamp()
+ os.utime(temporary, (timestamp, timestamp))
+
+ _retry(download)
+ temporary.replace(destination)
+ return destination
diff --git a/src/plinder/core/utils/io.py b/src/plinder/core/utils/io.py
index 1c591757b..2c7c8b88e 100644
--- a/src/plinder/core/utils/io.py
+++ b/src/plinder/core/utils/io.py
@@ -7,19 +7,348 @@
the network.
"""
+import gzip
+import re
+from collections.abc import Iterable
+from concurrent.futures import ThreadPoolExecutor
from functools import wraps
from pathlib import Path
+from tempfile import NamedTemporaryFile
from time import sleep
from typing import Any, Callable, Optional, TypeVar
+import pandas as pd
import requests
-from biotite.database.rcsb import fetch
-from biotite.structure.io.pdbx import CIFFile, get_structure, set_structure
+from biotite.file import DeserializationError, InvalidFileError
+from biotite.structure.io.pdbx import CIFFile
+from plinder.core.release import PlinderRelease
+from plinder.core.utils.config import get_config
+from plinder.core.utils.cpl import is_offline
from plinder.core.utils.log import setup_logger
LOG = setup_logger(__name__)
T = TypeVar("T")
+WWPDB_VERSIONED_MMCIF_URL = (
+ "https://files-versioned.wwpdb.org/pdb_versioned/data/entries"
+)
+PDBRevision = tuple[int, int]
+SOURCE_MMCIF_DOWNLOAD_ATTEMPTS = 3
+TRANSIENT_HTTP_STATUSES = frozenset({429, *range(500, 600)})
+
+
+def _normalize_pdb_id(pdb_or_system_id: str) -> str:
+ """Return a safe lowercase PDB identifier from a PDB or system ID."""
+ pdb_id = str(pdb_or_system_id).split("__", maxsplit=1)[0].strip().lower()
+ if not re.fullmatch(r"(?:[0-9][a-z0-9]{3}|pdb_[a-z0-9]{8})", pdb_id):
+ raise ValueError(f"invalid PDB ID: {pdb_or_system_id!r}")
+ # The extended representation of a legacy four-character accession is
+ # equivalent to its short form. Canonicalizing it avoids duplicate cache
+ # entries and manifest lookups.
+ if pdb_id.startswith("pdb_0000"):
+ return pdb_id[-4:]
+ return pdb_id
+
+
+def _entry_source_manifest_path(manifest_path: Path | str | None) -> Path:
+ if manifest_path is not None:
+ return Path(manifest_path)
+ return PlinderRelease().fetch("entry_sources")
+
+
+def _get_pdb_revisions(
+ pdb_ids: Iterable[str],
+ *,
+ manifest_path: Path | str | None = None,
+) -> dict[str, PDBRevision]:
+ """Read exact source revisions for a subset from the release manifest."""
+ normalized = list(dict.fromkeys(_normalize_pdb_id(value) for value in pdb_ids))
+ if not normalized:
+ return {}
+ path = _entry_source_manifest_path(manifest_path)
+ if not path.is_file():
+ raise FileNotFoundError(
+ f"source mmCIF revision manifest is not available at {path}; "
+ "download the release index before entering offline mode"
+ )
+ columns = [
+ "entry_pdb_id",
+ "source_mmcif_major_revision",
+ "source_mmcif_minor_revision",
+ ]
+ predicate: Any = (
+ [("entry_pdb_id", "==", normalized[0])]
+ if len(normalized) == 1
+ else [("entry_pdb_id", "in", normalized)]
+ )
+ rows = pd.read_parquet(path, columns=columns, filters=predicate)
+ if rows["entry_pdb_id"].duplicated().any():
+ duplicates = sorted(
+ rows.loc[rows["entry_pdb_id"].duplicated(), "entry_pdb_id"].unique()
+ )
+ raise ValueError(f"duplicate source revisions in {path}: {duplicates}")
+ revisions = {
+ str(row.entry_pdb_id): (
+ int(row.source_mmcif_major_revision),
+ int(row.source_mmcif_minor_revision),
+ )
+ for row in rows.itertuples(index=False)
+ }
+ missing = sorted(set(normalized).difference(revisions))
+ if missing:
+ raise KeyError(f"source mmCIF revisions missing from {path}: {missing}")
+ return revisions
+
+
+def get_pdb_revision(
+ pdb_or_system_id: str,
+ *,
+ manifest_path: Path | str | None = None,
+) -> PDBRevision:
+ """Return the exact source mmCIF revision pinned by this release."""
+ pdb_id = _normalize_pdb_id(pdb_or_system_id)
+ return _get_pdb_revisions([pdb_id], manifest_path=manifest_path)[pdb_id]
+
+
+def _extended_pdb_id(pdb_id: str) -> str:
+ """Return the wwPDB extended accession used by the versioned archive."""
+ return pdb_id if pdb_id.startswith("pdb_") else f"pdb_0000{pdb_id}"
+
+
+def pdb_mmcif_cache_path(
+ pdb_or_system_id: str,
+ *,
+ cache_dir: Path | str | None = None,
+ revision: PDBRevision | None = None,
+ manifest_path: Path | str | None = None,
+) -> Path:
+ """Return the deterministic local path for a version-pinned PDB mmCIF."""
+ pdb_id = _normalize_pdb_id(pdb_or_system_id)
+ if revision is None:
+ revision = get_pdb_revision(pdb_id, manifest_path=manifest_path)
+ if cache_dir is None:
+ cfg = get_config()
+ cache_dir = Path(cfg.data.plinder_dir) / cfg.data.source_mmcifs
+ major, minor = revision
+ return Path(cache_dir) / pdb_id[-3:-1] / f"{pdb_id}_v{major}-{minor}.cif.gz"
+
+
+def _mmcif_revision(path: Path) -> PDBRevision:
+ """Read the latest structure-model revision from a compressed mmCIF."""
+ try:
+ with gzip.open(path, "rt", encoding="utf-8") as handle:
+ cif_file = CIFFile.read(handle)
+ except (
+ OSError,
+ EOFError,
+ UnicodeDecodeError,
+ DeserializationError,
+ InvalidFileError,
+ ) as exc:
+ raise ValueError(f"invalid gzip-compressed mmCIF: {path}") from exc
+ if not cif_file:
+ raise ValueError(f"downloaded mmCIF contains no data block: {path}")
+ block = next(iter(cif_file.values()))
+ category_name = "pdbx_audit_revision_history"
+ if category_name not in block:
+ raise ValueError(f"mmCIF has no {category_name} category: {path}")
+ category = block[category_name]
+ if not {"major_revision", "minor_revision"}.issubset(category):
+ raise ValueError(f"mmCIF has no revision columns: {path}")
+ major = category["major_revision"].as_array()
+ minor = category["minor_revision"].as_array()
+ indices: Iterable[int] = range(len(major))
+ if "data_content_type" in category:
+ content_type = category["data_content_type"].as_array()
+ indices = [
+ index
+ for index, value in enumerate(content_type)
+ if str(value).lower() == "structure model"
+ ]
+ revisions = [(int(major[index]), int(minor[index])) for index in indices]
+ if not revisions:
+ raise ValueError(f"mmCIF contains no structure-model revision: {path}")
+ return max(revisions)
+
+
+def _validate_gzipped_mmcif(
+ path: Path,
+ *,
+ expected_revision: PDBRevision | None = None,
+) -> None:
+ """Reject corrupt/non-mmCIF data and revision mismatches."""
+ try:
+ with gzip.open(path, "rb") as handle:
+ prefix = handle.read(4096).lstrip()
+ except (OSError, EOFError) as exc:
+ raise ValueError(f"invalid gzip-compressed mmCIF: {path}") from exc
+ if not prefix.startswith(b"data_"):
+ raise ValueError(f"downloaded file is not an mmCIF: {path}")
+ if expected_revision is not None:
+ actual_revision = _mmcif_revision(path)
+ if actual_revision != expected_revision:
+ raise ValueError(
+ f"source mmCIF revision mismatch for {path}: expected "
+ f"{expected_revision[0]}.{expected_revision[1]}, found "
+ f"{actual_revision[0]}.{actual_revision[1]}"
+ )
+
+
+def _download_versioned_mmcif(
+ *,
+ url: str,
+ destination: Path,
+ pdb_id: str,
+ revision: PDBRevision,
+) -> None:
+ """Download one mmCIF atomically, retrying only transient failures."""
+ major, minor = revision
+ transient_errors = (
+ requests.exceptions.Timeout,
+ requests.exceptions.ConnectionError,
+ requests.exceptions.ChunkedEncodingError,
+ requests.exceptions.ContentDecodingError,
+ )
+ for attempt in range(1, SOURCE_MMCIF_DOWNLOAD_ATTEMPTS + 1):
+ temporary: Path | None = None
+ retry_reason: str | None = None
+ try:
+ response = requests.get(url, stream=True, timeout=(10, 120))
+ if response.status_code == 404:
+ raise FileNotFoundError(
+ f"wwPDB versioned archive has no source mmCIF for {pdb_id} "
+ f"revision {major}.{minor}: {url}"
+ )
+ if response.status_code in TRANSIENT_HTTP_STATUSES:
+ if attempt == SOURCE_MMCIF_DOWNLOAD_ATTEMPTS:
+ response.raise_for_status()
+ raise RuntimeError(
+ f"HTTP {response.status_code} while downloading {url}"
+ )
+ retry_reason = f"HTTP {response.status_code}"
+ else:
+ response.raise_for_status()
+ with NamedTemporaryFile(
+ dir=destination.parent,
+ prefix=f".{destination.name}.",
+ suffix=".tmp",
+ delete=False,
+ ) as handle:
+ temporary = Path(handle.name)
+ for chunk in response.iter_content(chunk_size=1024 * 1024):
+ if chunk:
+ handle.write(chunk)
+ _validate_gzipped_mmcif(
+ temporary,
+ expected_revision=revision,
+ )
+ temporary.replace(destination)
+ return
+ except transient_errors as exc:
+ if attempt == SOURCE_MMCIF_DOWNLOAD_ATTEMPTS:
+ raise
+ retry_reason = repr(exc)
+ finally:
+ if temporary is not None and temporary.exists():
+ temporary.unlink()
+
+ wait_seconds = 2 ** (attempt - 1)
+ LOG.warning(
+ f"transient source mmCIF download failure for {pdb_id} "
+ f"({retry_reason}); retrying in {wait_seconds}s "
+ f"[{attempt}/{SOURCE_MMCIF_DOWNLOAD_ATTEMPTS}]"
+ )
+ sleep(wait_seconds)
+
+ raise RuntimeError(f"failed to download source mmCIF from {url}")
+
+
+def get_pdb_mmcif(
+ pdb_or_system_id: str,
+ *,
+ cache_dir: Path | str | None = None,
+ force_update: bool = False,
+ revision: PDBRevision | None = None,
+ manifest_path: Path | str | None = None,
+ base_url: str = WWPDB_VERSIONED_MMCIF_URL,
+) -> Path:
+ """Return the release-pinned source mmCIF, downloading it when allowed.
+
+ Online calls populate the release-local cache atomically. In offline mode
+ the function performs no network or filesystem writes: a valid cached file
+ is returned and a missing or corrupt file raises ``FileNotFoundError``.
+ """
+ pdb_id = _normalize_pdb_id(pdb_or_system_id)
+ if revision is None:
+ revision = get_pdb_revision(pdb_id, manifest_path=manifest_path)
+ destination = pdb_mmcif_cache_path(
+ pdb_id,
+ cache_dir=cache_dir,
+ revision=revision,
+ )
+ cached = False
+ if destination.is_file():
+ try:
+ _validate_gzipped_mmcif(
+ destination,
+ expected_revision=revision,
+ )
+ cached = True
+ except ValueError:
+ cached = False
+ if cached and (not force_update or is_offline()):
+ return destination
+ if is_offline():
+ raise FileNotFoundError(
+ f"No valid cached source mmCIF for {pdb_id} at {destination}. "
+ "Disable PLINDER_OFFLINE/PLINDER_OFFLINE_MODE and call "
+ "get_pdb_mmcif() or download_pdb_mmcifs() on an online node first."
+ )
+
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ major, minor = revision
+ extended_id = _extended_pdb_id(pdb_id)
+ filename = f"{extended_id}_xyz_v{major}-{minor}.cif.gz"
+ url = f"{base_url.rstrip('/')}/{pdb_id[-3:-1]}/{extended_id}/{filename}"
+ _download_versioned_mmcif(
+ url=url,
+ destination=destination,
+ pdb_id=pdb_id,
+ revision=revision,
+ )
+ LOG.info(
+ f"cached wwPDB source mmCIF {pdb_id} revision {major}.{minor} at {destination}"
+ )
+ return destination
+
+
+def download_pdb_mmcifs(
+ pdb_or_system_ids: Iterable[str],
+ *,
+ cache_dir: Path | str | None = None,
+ force_update: bool = False,
+ max_workers: int = 8,
+ manifest_path: Path | str | None = None,
+) -> dict[str, Path]:
+ """Prefetch a release-pinned subset of PDB mmCIFs for offline use."""
+ if max_workers < 1:
+ raise ValueError("max_workers must be at least 1")
+ pdb_ids = list(
+ dict.fromkeys(_normalize_pdb_id(value) for value in pdb_or_system_ids)
+ )
+ revisions = _get_pdb_revisions(pdb_ids, manifest_path=manifest_path)
+
+ def download(pdb_id: str) -> Path:
+ return get_pdb_mmcif(
+ pdb_id,
+ cache_dir=cache_dir,
+ force_update=force_update,
+ revision=revisions[pdb_id],
+ )
+
+ with ThreadPoolExecutor(max_workers=min(max_workers, len(pdb_ids) or 1)) as pool:
+ downloaded = pool.map(download, pdb_ids)
+ return dict(zip(pdb_ids, downloaded))
def retry(func: Callable[..., T]) -> Callable[..., T]:
@@ -60,22 +389,3 @@ def download_alphafold_cif_file(
with open(cif_file_path, "w") as f:
f.write(resp.text)
return cif_file_path
-
-
-@retry
-def download_pdb_chain_cif_file(pdb_id: str, chain_id: str, filename: Path) -> Path:
- structure = get_structure(
- CIFFile.read(
- fetch(
- pdb_ids=pdb_id,
- format="cif",
- overwrite=False,
- )
- ),
- model=1,
- use_author_fields=False,
- )
- write_file = CIFFile()
- set_structure(write_file, structure[structure.chain_id == chain_id])
- write_file.write(filename.as_posix())
- return filename
diff --git a/src/plinder/core/utils/load_systems.py b/src/plinder/core/utils/load_systems.py
deleted file mode 100644
index 42396026b..000000000
--- a/src/plinder/core/utils/load_systems.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# type: ignore
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from typing import Any, Optional, Union
-
-from omegaconf import DictConfig
-
-from plinder.core.index.system import PlinderSystem
-from plinder.core.index.utils import get_manifest
-from plinder.core.utils.unpack import expand_config_context
-
-
-# TODO: not used currently
-def load_systems(
- *,
- system_ids: Optional[Union[str, list[str]]] = None,
- pdb_ids: Optional[Union[str, list[str]]] = None,
- two_char_codes: Optional[Union[str, list[str]]] = None,
- cfg: Optional[DictConfig] = None,
-) -> dict[str, Any]:
- kind, items = expand_config_context(
- system_ids=system_ids, pdb_ids=pdb_ids, two_char_codes=two_char_codes, cfg=cfg
- )
- if kind == "system_ids":
- return {system_id: PlinderSystem(system_id=system_id) for system_id in items}
- manifest = get_manifest()
- systems = {}
- if kind == "pdb_ids":
- for pdb_id in items:
- ids = manifest[manifest["pdb_id"] == pdb_id]["system_id"].to_list()
- for system_id in ids:
- systems[system_id] = PlinderSystem(system_id=system_id)
- return systems
- manifest["two_char_code"] = manifest["entry_pdb_id"].str[1:3]
- for two_char_code in items:
- ids = manifest[manifest["two_char_code"] == two_char_code][
- "system_id"
- ].to_list()
- for system_id in ids:
- systems[system_id] = PlinderSystem(system_id=system_id)
- return systems
diff --git a/src/plinder/core/utils/log.py b/src/plinder/core/utils/log.py
index 4a458bebf..7fdf7e022 100644
--- a/src/plinder/core/utils/log.py
+++ b/src/plinder/core/utils/log.py
@@ -13,10 +13,6 @@
DEFAULT_LOGGING_LEVEL = logging.INFO
-class PlinderLoggingError(Exception):
- pass
-
-
def setup_logger(
logger_name: str | None = None,
log_level: int = DEFAULT_LOGGING_LEVEL,
@@ -29,8 +25,8 @@ def setup_logger(
Parameters
----------
- logger_name : str
- Name of the logger
+ logger_name : str | None
+ Name of the logger; if None, derived from the calling module's filename.
log_level : int
Log level
log_file: str | None
@@ -43,6 +39,13 @@ def setup_logger(
logging.Logger:
logger object
+ Notes
+ -----
+ When ``propagate=False`` (the default), pytest's ``caplog`` fixture
+ cannot observe records from this logger because caplog hooks the root logger.
+ Tests asserting on warnings/errors should either pass ``propagate=True`` here
+ or capture via ``monkeypatch.setattr(LOG, "warning", ...)``.
+
Examples
--------
>>> logger = setup_logger("some_logger_name")
diff --git a/src/plinder/core/utils/r2.py b/src/plinder/core/utils/r2.py
deleted file mode 100644
index 57c4be58a..000000000
--- a/src/plinder/core/utils/r2.py
+++ /dev/null
@@ -1,166 +0,0 @@
-"""Manifest-backed listing and verified cloudpathlib downloads for public R2."""
-
-import base64
-import gzip
-import hashlib
-import json
-from functools import lru_cache
-from http.client import HTTPException
-from os import PathLike
-from pathlib import Path
-from tempfile import TemporaryDirectory
-from time import sleep
-from typing import Iterator, TypedDict, TypeVar, cast
-from urllib.error import HTTPError
-from urllib.parse import quote, unquote
-from urllib.request import BaseHandler, Request
-
-from cloudpathlib import CloudPath as BaseCloudPath
-from cloudpathlib import HttpPath, HttpsClient, HttpsPath
-
-CloudPathT = TypeVar("CloudPathT", bound=BaseCloudPath)
-
-
-class ManifestRecord(TypedDict):
- key: str
- size: int
- md5: str
-
-
-def checked_key(key: str) -> str:
- if key and ("\\" in key or any(p in {"", ".", ".."} for p in key.split("/"))):
- raise ValueError(f"Invalid dataset path: {key!r}")
- return key
-
-
-class _TimeoutHandler(BaseHandler):
- def http_request(self, request: Request) -> Request:
- # Bound connection/read inactivity without limiting total transfer time.
- request.timeout = 60
- return request
-
- https_request = http_request
-
-
-class _DownloadClient(HttpsClient):
- def __init__(self) -> None:
- super().__init__(auth=_TimeoutHandler())
-
- def _download(
- self,
- path: HttpPath,
- local_path: str | PathLike[str],
- expected_size: int | None = None,
- ) -> Path:
- destination = Path(local_path)
- for attempt in range(3):
- try:
- super()._download_file(path, destination)
- if (
- expected_size is not None
- and destination.stat().st_size != expected_size
- ):
- raise OSError("Incomplete dataset download")
- break
- except (OSError, HTTPException) as exc:
- if isinstance(exc, HTTPError) and exc.code not in {
- 408,
- 429,
- 500,
- 502,
- 503,
- 504,
- }:
- raise
- if attempt == 2:
- raise
- sleep(2**attempt)
- return destination
-
-
-@lru_cache(maxsize=4)
-def manifest(remote: str) -> dict[str, ManifestRecord]:
- with TemporaryDirectory() as tmp:
- path = Path(tmp) / "manifest.jsonl.gz"
- path_class = HttpsPath if remote.startswith("https:") else HttpPath
- client = _DownloadClient()
- source = path_class(remote + "/manifest.jsonl.gz", client=client)
- # A direct GET preserves transient errors hidden by cloudpathlib's HEAD check.
- client._download(source, path)
- data = path.read_bytes()
- records: dict[str, ManifestRecord] = {}
- for line in gzip.decompress(data).splitlines():
- row = json.loads(line)
- key = checked_key(row["key"])
- if not key or key in records or type(row["size"]) is not int or row["size"] < 0:
- raise ValueError("Invalid or duplicate manifest record")
- if len(base64.b64decode(row["md5"], validate=True)) != 16:
- raise ValueError("Invalid manifest MD5")
- records[key] = row
- return records
-
-
-class ReleaseClient(_DownloadClient):
- """Use the manifest where public HTTP lacks object listing; delegate transfers."""
-
- def __init__(self, remote: str):
- super().__init__()
- self.remote = remote
- self.records = manifest(remote)
- self.dir_matcher = lambda url: self.key(url) not in self.records
-
- def CloudPath(self, path: str | CloudPathT, *parts: str) -> CloudPathT:
- cls = HttpsPath if self.remote.startswith("https:") else HttpPath
- return cast(CloudPathT, cls(str(path), *parts, client=self))
-
- def path(self, key: str = "") -> HttpPath:
- return cast(
- HttpPath,
- self.CloudPath(
- self.remote + ("/" + quote(checked_key(key), safe="/") if key else "")
- ),
- )
-
- def key(self, path: str | BaseCloudPath) -> str:
- url = str(path)
- if url == self.remote:
- return ""
- if not url.startswith(self.remote + "/"):
- raise ValueError("Path is outside the release")
- return checked_key(unquote(url[len(self.remote) + 1 :]))
-
- def _exists(self, path: HttpPath) -> bool:
- key = self.key(path)
- return key in self.records or any(
- not key or k.startswith(key + "/") for k in self.records
- )
-
- def _list_dir(
- self, path: HttpPath, recursive: bool
- ) -> Iterator[tuple[HttpPath, bool]]:
- key = self.key(path)
- prefix = key + "/" if key else ""
- children = {}
- for name in self.records:
- if name.startswith(prefix):
- parts = name[len(prefix) :].split("/")
- for i in range(1, len(parts) + 1 if recursive else 2):
- children[prefix + "/".join(parts[:i])] = i < len(parts)
- for name, is_dir in sorted(children.items()):
- yield self.path(name), is_dir
-
- def _download_file(self, path: HttpPath, local_path: str | PathLike[str]) -> Path:
- destination = Path(local_path)
- destination.parent.mkdir(parents=True, exist_ok=True)
- record = self.records[self.key(path)]
- with TemporaryDirectory(dir=destination.parent) as tmp:
- temporary = Path(tmp) / "download"
- self._download(path, temporary, expected_size=record["size"])
- digest = hashlib.md5()
- with temporary.open("rb") as stream:
- for chunk in iter(lambda: stream.read(1024 * 1024), b""):
- digest.update(chunk)
- if base64.b64encode(digest.digest()).decode() != record["md5"]:
- raise ValueError("Dataset checksum mismatch")
- temporary.replace(destination)
- return destination
diff --git a/src/plinder/core/utils/sanitize.py b/src/plinder/core/utils/sanitize.py
new file mode 100644
index 000000000..c371dae1d
--- /dev/null
+++ b/src/plinder/core/utils/sanitize.py
@@ -0,0 +1,755 @@
+# mypy: disable-error-code="attr-defined"
+
+"""Vendored copy of peppr's ``sanitize`` with local over-valence fixes.
+
+.. warning::
+
+ TEMPORARY. This is a local, hand-maintained copy of the modified
+ ``sanitize`` from unreleased peppr version. It carries boron-cage / main-group
+ over-valence tolerance and related valence/kekulization fixes that are
+ **not yet in a released** ``peppr`` and are not pip-installable from the
+ internal repo.
+
+ TODO(peppr): once these changes land in a published ``peppr`` release,
+ DELETE this module and revert every import of the form
+ ``from plinder.core.utils.sanitize import sanitize as peppr_sanitize``
+ back to ``from peppr import sanitize as peppr_sanitize``
+ (grep the tree for ``peppr_sanitize`` to find all call sites). Note that
+ :func:`mol_from_smiles` is a plinder wrapper, not part of upstream peppr โ
+ RELOCATE it (e.g. to a core utils module) rather than deleting it.
+
+ Deliberate local deltas from the upstream peppr body: this warning docstring; the
+ ``bool(...)`` wraps on the predicate returns (plinder's minimal mypy env has no rdkit
+ stubs, so ``Chem`` is ``Any`` and ``strict``'s ``warn_return_any`` would flag them);
+ and a trimmed ``_ORGANOMETALLIC_OMITTED_ELEMENTS`` comment (correctness, pending upstream).
+"""
+
+__all__ = ["mol_from_smiles", "sanitize"]
+
+import logging
+from collections.abc import Callable
+from itertools import combinations, product
+
+import rdkit
+import rdkit.Chem.AllChem as Chem
+from rdkit.Chem.rdmolops import SanitizeFlags
+
+LOG = logging.getLogger(__name__)
+
+# Main-group metals/metalloids RDKit's SANITIZE_CLEANUP_ORGANOMETALLICS step leaves alone
+# (it dativises only transition metals). An over-valent centre of one is tolerated neutral
+# (:func:`_is_tolerated_over_valence`) and one counts as a coordinating metal when kekulizing
+# (:func:`_is_metal`). Built from symbols for legibility, stored/compared as atomic numbers.
+_ORGANOMETALLIC_OMITTED_ELEMENTS = frozenset(
+ Chem.GetPeriodicTable().GetAtomicNumber(symbol)
+ for symbol in (
+ "B",
+ "Li",
+ "Be",
+ "Na",
+ "Mg",
+ "Al",
+ "K",
+ "Ca",
+ "Ga",
+ "Ge",
+ "As",
+ "Rb",
+ "Sr",
+ "In",
+ "Sn",
+ "Sb",
+ "Cs",
+ "Ba",
+ "Tl",
+ "Pb",
+ "Bi",
+ "Po",
+ "Fr",
+ "Ra",
+ )
+)
+
+# Terminal ligands that take the -1 when their bond to an over-valent centre is
+# reduced, most electronegative first (they most naturally become the anion).
+_TERMINAL_ANION_ELEMENTS = ("F", "O", "Cl", "N", "Br", "I", "S")
+
+# One step down in bond order, relieving over-valence while keeping the atoms bonded.
+# A single drops to UNSPECIFIED: a zero-valence bond (contributes 0, like ZERO) - the
+# "zero-order" shed elsewhere in this module. UNSPECIFIED rather than ZERO because only it
+# survives the biotite round-trip (ZERO has no biotite equivalent -> ANY + a per-bond
+# warning; peppr.charge round-trips a sanitized mol via rdkit_interface.from_mol).
+_REDUCED_BOND_ORDER = {
+ Chem.BondType.TRIPLE: Chem.BondType.DOUBLE,
+ Chem.BondType.DOUBLE: Chem.BondType.SINGLE,
+ Chem.BondType.SINGLE: Chem.BondType.UNSPECIFIED,
+}
+
+
+def sanitize(mol: Chem.Mol, max_fix_iterations: int = 100) -> None:
+ """
+ Sanitize a molecule, repairing the problems that make RDKit's :func:`SanitizeMol`
+ fail on otherwise-valid heavy-atom input.
+
+ Parameters
+ ----------
+ mol : Chem.rdchem.Mol
+ The molecule to sanitize, modified in place.
+ max_fix_iterations : int, optional
+ The maximum number of fix passes per stage.
+
+ Notes
+ -----
+ Runs in stages, in the order RDKit resolves them - valence, then kekulization, then
+ the rest - fixing and re-checking each before moving on:
+
+ - ``AtomValenceException``: relieve over-valence via a zero-order bond (into a
+ valence-unlimited metal or an over-valent partner), an "onium" charge (N/O), a
+ terminal-ligand charge (hypervalent P/S), or a borate charge (B); metal centres and
+ carborane cages are tolerated. See :func:`_fix_valence`.
+ - ``KekulizeException``: kekulize a ring heteroatom (N/O/S) neutral-first - reduce its
+ bond to a coordinated metal, or add a ring-N ``[nH]`` - and only as a last resort
+ invent an onium ``+1`` (pyridinium/pyrylium/thiopyrylium). See :func:`_fix_kekule`.
+ """
+ # Avoid getting RDKit logs during checks for chemistry problems
+ # If problems remain we rather want to receive them via an exception
+ # from the final `SanitizeMol()` call
+ with rdkit.rdBase.BlockLogs():
+ # baseline clean-up first (standardises e.g. nitro groups and
+ # organometallics); no corrections of ours are applied yet
+ Chem.SanitizeMol(
+ mol,
+ sanitizeOps=SanitizeFlags.SANITIZE_CLEANUP
+ | SanitizeFlags.SANITIZE_CLEANUP_ORGANOMETALLICS,
+ )
+ mol.UpdatePropertyCache(strict=False)
+
+ # 1) valence problems must be resolved before anything else.
+ _iteratively_fix(
+ mol, SanitizeFlags.SANITIZE_PROPERTIES, _fix_valence, max_fix_iterations
+ )
+ try:
+ Chem.SanitizeMol(mol, sanitizeOps=SanitizeFlags.SANITIZE_PROPERTIES)
+ except Exception as exc:
+ # tolerate over-valence RDKit still flags but no 2-centre-bond model can
+ # fix - main-group metal centres and carborane cages, kept neutral (see
+ # _is_tolerated_over_valence); anything else is a genuine over-valence
+ # _fix_valence could not repair -> re-raise, noting which atoms
+ offenders = [
+ p.GetAtomIdx()
+ for p in Chem.DetectChemistryProblems(
+ mol, sanitizeOps=SanitizeFlags.SANITIZE_PROPERTIES
+ )
+ if not _is_tolerated_over_valence(mol.GetAtomWithIdx(p.GetAtomIdx()))
+ ]
+ if offenders:
+ exc.add_note(
+ f"peppr.sanitize could not fix over-valent atom(s) {offenders}"
+ )
+ raise
+
+ # ring perception is required before kekulization can be attempted
+ Chem.SanitizeMol(mol, sanitizeOps=SanitizeFlags.SANITIZE_SYMMRINGS)
+
+ # 2) kekulization problems
+ _iteratively_fix(
+ mol, SanitizeFlags.SANITIZE_KEKULIZE, _fix_kekule, max_fix_iterations
+ )
+ # surface any remaining kekulization error here
+ Chem.SanitizeMol(mol, sanitizeOps=SanitizeFlags.SANITIZE_KEKULIZE)
+
+ # everything else (aromaticity, radicals, hybridisation, ...);
+ # any issue that remains will be raised here
+ Chem.SanitizeMol(
+ mol,
+ sanitizeOps=SanitizeFlags.SANITIZE_ALL ^ SanitizeFlags.SANITIZE_PROPERTIES,
+ )
+
+
+def mol_from_smiles(smiles: str | None) -> "Chem.Mol | None":
+ """Parse a SMILES into a sanitized RDKit mol via the tolerant peppr sanitizer.
+
+ This is the canonical way to re-parse a *stored* ligand SMILES anywhere in
+ plinder. Plain ``Chem.MolFromSmiles`` applies strict valence sanitization and
+ returns ``None`` for the over-valent main-group centres (boron cages,
+ hypervalent metals) that the mol-building path accepts, so descriptors,
+ classification, fingerprints and identity keys must reparse the same way or
+ they silently drop those ligands. Here we parse without sanitizing and then
+ run :func:`sanitize`, which accepts exactly what the build path accepts.
+
+ For a valid organic molecule the result is chemically identical to
+ ``Chem.MolFromSmiles`` (``sanitize`` finishes with a full ``SANITIZE_ALL``
+ pass), so fingerprints/canonical SMILES do not drift. It is a faithful
+ tolerant drop-in: parsing with ``sanitize=False`` skips the parser's
+ ``assignStereochemistry`` finalisation that strict ``MolFromSmiles`` runs, so
+ we re-run it here โ otherwise double-bond E/Z (parsed as bond directions but
+ never translated into bond stereo) would be left unperceived while atom
+ ``@``/``@@`` parity survived. Returns ``None`` for an empty/``None`` input or
+ a SMILES that cannot be parsed or repaired.
+ """
+ if not smiles:
+ return None
+ mol = Chem.MolFromSmiles(smiles, sanitize=False)
+ if mol is None:
+ return None
+ try:
+ sanitize(mol)
+ except Exception as exc:
+ LOG.warning("mol_from_smiles: peppr sanitize failed for %r (%s)", smiles, exc)
+ return None
+ # Perceive stereo (esp. double-bond E/Z from bond directions) to match
+ # Chem.MolFromSmiles. Best-effort: a valid mol without perceived stereo is
+ # still usable for descriptors/fingerprints, so keep it if this rare step fails.
+ try:
+ Chem.AssignStereochemistry(mol, cleanIt=True, force=True)
+ except Exception as exc:
+ LOG.warning(
+ "mol_from_smiles: stereo perception failed for %r (%s)", smiles, exc
+ )
+ return mol
+
+
+def _fix_valence(mol: Chem.Mol, problem: Exception) -> None:
+ """
+ Fix a single over-valence problem in place, applying the first repair that is
+ legitimate for the atom.
+
+ Parameters
+ ----------
+ mol : Chem.rdchem.Mol
+ The molecule to fix.
+ problem : Exception
+ The problem to fix.
+
+ Notes
+ -----
+ Strategies are attempted in order; the first that relieves the atom wins:
+
+ 0. Neutralise a spurious formal charge so the bond-based fixes see the real valence.
+ 1. A zero-order bond (:func:`_fix_valence_by_reduced_bond_order`) into a clean sink -
+ a valence-unlimited metal (the FeMo-cofactor carbide bonded to 6 Fe) or an
+ over-valent cage partner.
+ 2. Element-specific: N/O take an "onium" ``+1``; hypervalent P/S push a ``-1`` onto a
+ terminal ligand; a non-cage tetravalent B becomes borate ``[B-]``; a carborane cage
+ or main-group metal centre is tolerated neutral.
+
+ An atom no fix relieves is a genuinely impossible valence (a divalent F, a pentavalent
+ C), left flagged so :func:`sanitize` raises rather than papering over broken chemistry.
+ """
+ if problem.GetType() != "AtomValenceException":
+ return
+ at = mol.GetAtomWithIdx(problem.GetAtomIdx())
+
+ # 0) drop a spurious formal charge first: biotite emits charged atoms illegal for
+ # their charge state (e.g. [C+2] carborane carbons, coordinated [Cl-]). Neutralise
+ # so the bond-based fixes below see the real valence; the element branches re-apply
+ # any legitimate charge (borate [B-], N/O onium, ...).
+ if at.GetFormalCharge() != 0:
+ at.SetFormalCharge(0)
+ mol.UpdatePropertyCache(strict=False)
+
+ # 1) decouple an over-valent bond as zero-order into a clean sink - a
+ # valence-unlimited metal (the FeMo-cofactor carbide bonded to 6 Fe) or a
+ # partner that is itself over-valent, e.g. a borane-cage neighbour (relieves
+ # both). No phantom H; direction-agnostic (no RWMol bond-flip).
+ if _fix_valence_by_reduced_bond_order(mol, at):
+ return
+
+ # 2) element-specific charge, or tolerate an over-valence no 2-centre-bond model can
+ # express (a carborane cage or main-group metal centre - kept neutral, flagged,
+ # swallowed in `sanitize`). Each branch gates on the exact valence one over the
+ # element default, where an onium/borate charge is valid. Anything matching no branch
+ # is a genuinely impossible valence (divalent F, pentavalent C), left flagged so
+ # `sanitize` raises rather than papering it over with a phantom H.
+ elem = at.GetSymbol()
+ if elem == "O" and at.GetTotalValence() == 3:
+ # oxonium: an over-coordinated O (one past its default valence 2) shares a lone
+ # pair, relieved by a +1
+ at.SetFormalCharge(1)
+ elif elem == "N" and at.GetTotalValence() == 4:
+ # ammonium/iminium: N one past its default valence 3, relieved by a +1
+ at.SetFormalCharge(1)
+ # a cumulated 1,3-dipole (azide/diazo) needs the compensating -1 on its terminal
+ # N: CN=N=N -> CN=[N+]=[N-], not CN=[N+]=N
+ _balance_dipole_terminal(at)
+ elif elem in ("P", "S") and _fix_valence_by_ligand_charge(mol, at):
+ # hypervalent P/S relieved by moving a -1 onto a terminal ligand: =O -> -O(-)
+ # (phosphate, sulfonate/hypervalent sulfur), P-F -> P~[F-] (PF6). Nitro is
+ # already handled by SANITIZE_CLEANUP. If no terminal ligand can take the charge,
+ # this is False and the atom is left flagged to raise.
+ pass
+ elif elem == "B" and not _is_borane_cage_atom(at) and at.GetTotalValence() == 4:
+ # a non-cage tetravalent boron is a borate anion [B-] (BF4-, B(OH)4-, R4B-) - the
+ # N/O onium charge with the opposite sign.
+ at.SetFormalCharge(-1)
+ elif _is_tolerated_over_valence(at):
+ # a carborane/borane cage vertex or a main-group metal centre (In, Be, ...): no
+ # 2-centre-bond model expresses the hyper-coordination, so tolerate it neutral
+ # (already neutralised in step 0, then flagged and swallowed in `sanitize` by the
+ # same predicate).
+ pass
+
+
+def _fix_valence_by_reduced_bond_order(mol: Chem.Mol, atom: Chem.Atom) -> bool:
+ """
+ Relieve an over-valent atom by lowering a bond one order at a time into a sink that
+ absorbs it (:data:`_REDUCED_BOND_ORDER`), one unit of excess per step. Return True if
+ the atom ends up within valence.
+
+ Notes
+ -----
+ A reduction debits *both* endpoints, so it is lossless only into a valence-unlimited
+ metal (the FeMo carbide bonded to 6 Fe) or an over-valent cage partner (their shared
+ bond's reduction relieves both). With no such sink the atom is left over-valent to
+ raise later, deliberately avoiding a phantom H. Aromatic bonds are never touched.
+ """
+ if _has_no_valence_limit(atom.GetAtomicNum()):
+ return False # unenforced valence -> never flagged, nothing to relieve
+ max_valence = max(Chem.GetPeriodicTable().GetValenceList(atom.GetAtomicNum()))
+ excess = atom.GetTotalValence() - max_valence # how far over its highest valence
+ if excess <= 0:
+ return False
+
+ # spend the least-damaging bond first: a valence-unlimited metal (free sink), then an
+ # over-valent cage partner, then an omitted main-group metal bond, then a covalent one.
+ def _sink_rank(bond: Chem.Bond) -> int:
+ partner = bond.GetOtherAtom(atom)
+ neighbour = partner.GetAtomicNum()
+ if _has_no_valence_limit(neighbour):
+ return 0
+ if (
+ _is_over_valent(partner)
+ and neighbour not in _ORGANOMETALLIC_OMITTED_ELEMENTS
+ ):
+ return 1
+ if neighbour in _ORGANOMETALLIC_OMITTED_ELEMENTS:
+ return 2
+ return 3
+
+ for bond in sorted(atom.GetBonds(), key=_sink_rank):
+ if excess <= 0:
+ break
+ if bond.GetBondType() not in _REDUCED_BOND_ORDER:
+ continue # aromatic, already zero-order, dative, or otherwise not reducible
+ # only reduce into a clean sink (absorbs it without a phantom H): a valence-
+ # unlimited metal, or an over-valent partner in a cage cluster. The cage gate is
+ # deliberate - an ordinary over-valent adjacency (pentavalent C next to over-valent
+ # O) is broken input, left to raise, not silently zero-ordered like a cluster.
+ partner = bond.GetOtherAtom(atom)
+ clean_sink = _has_no_valence_limit(partner.GetAtomicNum()) or (
+ _is_over_valent(partner)
+ and (_is_borane_cage_atom(atom) or _is_borane_cage_atom(partner))
+ )
+ if not clean_sink:
+ continue
+ # drop one order (e.g. single -> zero), shedding exactly one valence unit per end
+ bond.SetBondType(_REDUCED_BOND_ORDER[bond.GetBondType()])
+ excess -= 1
+ # refresh so a shared partner is not reduced past its own excess (no over-shedding)
+ mol.UpdatePropertyCache(strict=False)
+
+ mol.UpdatePropertyCache(strict=False)
+ return bool(atom.GetTotalValence() <= max_valence)
+
+
+def _fix_valence_by_ligand_charge(mol: Chem.Mol, atom: Chem.Atom) -> bool:
+ """
+ Relieve an over-valent centre by moving a ``-1`` onto its terminal ligands, keeping
+ the centre itself neutral. Return True if resolved.
+
+ Notes
+ -----
+ Per unit of excess, the bond to the most electronegative terminal (degree-1, neutral,
+ H-free) ligand is lowered one order and that ligand takes the ``-1``: ``=O -> -O(-)``
+ (phosphate) and ``P-F -> P~[F-]`` (PF6). Ligands are spent in electronegativity order
+ (F > O > Cl > N > ...).
+ """
+ if _has_no_valence_limit(atom.GetAtomicNum()):
+ return False
+ max_valence = max(Chem.GetPeriodicTable().GetValenceList(atom.GetAtomicNum()))
+ # amount by which the atom's valence exceeds its highest standard valence
+ excess = atom.GetTotalValence() - max_valence
+ if excess <= 0:
+ return False
+
+ rank = {sym: i for i, sym in enumerate(_TERMINAL_ANION_ELEMENTS)}
+ # terminal, neutral, H-free ligands whose bond order can be reduced, most
+ # electronegative first (they most naturally carry the -1)
+ ligand_bonds = sorted(
+ (
+ bond
+ for bond in atom.GetBonds()
+ if bond.GetBondType() in _REDUCED_BOND_ORDER
+ and bond.GetOtherAtom(atom).GetSymbol() in rank
+ and bond.GetOtherAtom(atom).GetDegree() == 1
+ and bond.GetOtherAtom(atom).GetFormalCharge() == 0
+ and bond.GetOtherAtom(atom).GetTotalNumHs() == 0
+ ),
+ key=lambda bond: rank[bond.GetOtherAtom(atom).GetSymbol()],
+ )
+ for bond in ligand_bonds:
+ if excess <= 0:
+ break
+ # lower the bond order by one and move the -1 onto the ligand
+ terminal = bond.GetOtherAtom(atom)
+ bond.SetBondType(_REDUCED_BOND_ORDER[bond.GetBondType()])
+ excess -= 1
+ terminal.SetFormalCharge(-1)
+
+ mol.UpdatePropertyCache(strict=False)
+ return bool(atom.GetTotalValence() <= max_valence)
+
+
+def _balance_dipole_terminal(center: Chem.Atom) -> None:
+ """
+ Move the compensating ``-1`` onto the terminal N of a just-``+1``-charged cumulated
+ 1,3-dipole (azide/diazo): ``CN=N=N -> CN=[N+]=[N-]``.
+
+ Notes
+ -----
+ Only a terminal (degree-1), neutral N double-bonded to ``center`` is charged, leaving
+ ammonium/iminium centres untouched (RDKit would otherwise neutral-fill the divalent
+ terminal N with an implicit H, giving ``CN=[N+]=N``).
+ """
+ for bond in center.GetBonds():
+ if bond.GetBondType() != Chem.BondType.DOUBLE:
+ continue
+ terminal = bond.GetOtherAtom(center)
+ if (
+ terminal.GetSymbol() == "N"
+ and terminal.GetDegree() == 1
+ and terminal.GetFormalCharge() == 0
+ ):
+ terminal.SetFormalCharge(-1)
+ return
+
+
+def _has_no_valence_limit(atomic_num: int) -> bool:
+ """
+ True for elements whose valence RDKit does not enforce (transition and
+ inner-transition metals). RDKit signals this with a ``[-1]`` sentinel in the
+ valence list (not an empty list), so test for that sentinel explicitly.
+ """
+ valences = Chem.GetPeriodicTable().GetValenceList(atomic_num)
+ return not valences or max(valences) < 0
+
+
+def _is_over_valent(atom: Chem.Atom) -> bool:
+ """
+ True if the atom exceeds the larger of its neutral valence and its formally-charged
+ (isoelectronic) valence - i.e. more bonds than any legitimate reading allows.
+
+ Notes
+ -----
+ Taking the max reads a charge in whichever direction is legitimate:
+
+ - a charge that *raises* the ceiling is honoured, so a ``[N+]`` (isoelectronic with C)
+ or a ``[B-]`` (borate) may reach valence 4 without being over-valent (e.g. a BODIPY
+ ``[N+]...[B-]``);
+ - a spurious charge that would *lower* it is ignored, so biotite's ``[C+2]`` on a
+ carborane carbon (isoelectronic with Be) is still judged by neutral carbon's 4 - it
+ is dropped later anyway (step 0 of :func:`_fix_valence`).
+
+ Valence-unlimited metals are never over-valent. Requires an up-to-date property cache.
+ """
+ if _has_no_valence_limit(atom.GetAtomicNum()):
+ return False
+ periodic_table = Chem.GetPeriodicTable()
+ neutral_valence = max(periodic_table.GetValenceList(atom.GetAtomicNum()))
+ # isoelectronic neutral element (same electron count): subtracting the charge shifts
+ # the atomic number - left for a cation ([N+]->C), right for an anion ([B-]->C)
+ isoelectronic = atom.GetAtomicNum() - atom.GetFormalCharge()
+ charged_valence = (
+ max(periodic_table.GetValenceList(isoelectronic)) if isoelectronic >= 1 else 0
+ )
+ return bool(atom.GetExplicitValence() > max(neutral_valence, charged_valence))
+
+
+def _is_borane_cage_atom(atom: Chem.Atom) -> bool:
+ """
+ True if the atom is a borane / carborane cage vertex (bonded to >=3 borons).
+
+ Notes
+ -----
+ Cage 3-centre-2-electron bonding is not expressible with 2-centre bonds: a cage carbon
+ is dropped to a legal valence by the zero-order shed, while a cage boron has no clean
+ fix and is tolerated neutral. A lone borate boron (bonded to F/O/C, no boron
+ neighbours) is not a cage vertex and is charged ``[B-]`` instead. Boron-specific: the
+ only element forming such cages in the PDB CCD.
+ """
+ return bool(
+ sum(neighbour.GetSymbol() == "B" for neighbour in atom.GetNeighbors()) >= 3
+ )
+
+
+def _is_tolerated_over_valence(atom: Chem.Atom) -> bool:
+ """
+ True for over-valence peppr accepts as flagged-but-faithful: an omitted main-group
+ metal centre (kept neutral) or a borane / carborane cage vertex
+ (:func:`_is_borane_cage_atom`).
+
+ Notes
+ -----
+ Both are hyper-coordinations no 2-centre-bond model can express. Everything else still
+ over-valent after the fixes is a genuine, unrepairable error.
+ """
+ return (
+ atom.GetAtomicNum() in _ORGANOMETALLIC_OMITTED_ELEMENTS
+ or _is_borane_cage_atom(atom)
+ )
+
+
+def _fix_kekule(mol: Chem.Mol, problem: Exception) -> None:
+ """
+ Fix a single kekulization problem in place by pinning down the ambiguous protonation,
+ charge, or metal-coordination state of a ring heteroatom (N/O/S).
+
+ Parameters
+ ----------
+ mol : Chem.rdchem.Mol
+ The molecule to fix.
+ problem : Exception
+ The problem to fix.
+
+ Notes
+ -----
+ Ring perception (``SANITIZE_SYMMRINGS``) must have run first. The fixes are tried
+ *neutral-first*, so a cation is only ever invented as a last resort:
+
+ 1. a heteroatom *coordinating a metal* (a pyridine/furan/thiophene donor) has an extra
+ bond to the metal blocking kekulization; reduce that bond to zero-order, freeing the
+ ring with the atom left neutral (and no directional dative bond, which ``sanitize``
+ cannot orient editing in place);
+ 2. a two-neighbour ring N given an *explicit* H is read as a charge (``[nH]`` -> a
+ charged ``[nH+]``), honouring an over-protonated input; heavy-atom input has only
+ implicit H, so this never fires there;
+ 3. otherwise a two-neighbour ring N may just need an added implicit H - the pyrrole
+ ``[nH]`` tautomer; nearly every unkekulizable heavy-atom ring (thiophenes, lactams,
+ ...) is neutral and resolves here;
+ 4. only a saturated heteroatom that *no* neutral kekule can satisfy is a genuine onium,
+ forced to carry a ring double bond, and takes a ``+1``: pyridinium (N, 3 neighbours),
+ pyrylium (O, 2), or thiopyrylium (S, 2).
+ """
+
+ def _kekulized() -> bool:
+ remaining = Chem.DetectChemistryProblems(
+ mol, sanitizeOps=SanitizeFlags.SANITIZE_KEKULIZE
+ )
+ return not [p for p in remaining if _is_same_problem(p, problem)]
+
+ if problem.GetType() != "KekulizeException":
+ # unclear if it can be fixed
+ return
+ # gather the whole ring system around the flagged atoms
+ problem_indices = set(problem.GetAtomIndices())
+ ring_info = mol.GetRingInfo()
+ for ring_indices in ring_info.AtomRings():
+ if problem_indices.intersection(ring_indices):
+ problem_indices |= set(ring_indices)
+
+ # heavy-neighbour count at which a neutral aromatic heteroatom is saturated (lone pair
+ # donated to the ring); past that it kekulizes only as an onium via a +1. N takes one
+ # bond more than O/S.
+ onium_saturation = {"N": 3, "O": 2, "S": 2}
+
+ # candidate ring heteroatoms (N/O/S), grouped by the degree of freedom each carries
+ two_neighbour_ns = []
+ original_nH_state = []
+ original_charge_state = []
+ onium_atoms = []
+ metal_coordinating_atoms = []
+ for atidx in problem_indices:
+ at = mol.GetAtomWithIdx(atidx)
+ sym = at.GetSymbol()
+ if sym not in onium_saturation: # only ring N/O/S carry a kekulization DOF
+ continue
+ # aromatic heteroatom bonded to a metal: a neutral dative donor (coordinating
+ # pyridine/furan/thiophene), relieved by reducing that bond, not by a charge
+ if at.GetIsAromatic() and any(
+ _is_metal(nbr.GetAtomicNum()) for nbr in at.GetNeighbors()
+ ):
+ metal_coordinating_atoms.append(at)
+ continue
+ num_heavy_neighbors = at.GetTotalDegree() - at.GetTotalNumHs()
+ # a two-neighbour ring N is protonation-ambiguous (pyrrole [nH] vs pyridine [n])
+ if sym == "N" and num_heavy_neighbors == 2:
+ two_neighbour_ns.append(at)
+ original_nH_state.append(at.GetNumExplicitHs())
+ original_charge_state.append(at.GetFormalCharge())
+ # a saturated neutral aromatic heteroatom is an onium (pyridinium/pyrylium/
+ # thiopyrylium), needing a +1
+ elif (
+ at.GetIsAromatic()
+ and at.GetTotalNumHs() == 0
+ and at.GetFormalCharge() == 0
+ and num_heavy_neighbors == onium_saturation[sym]
+ ):
+ onium_atoms.append(at)
+
+ if not two_neighbour_ns and not onium_atoms and not metal_coordinating_atoms:
+ # no candidate heteroatoms to fix the problem
+ return
+
+ # 1) metal-coordinating heteroatom: drop its bond to the metal to zero-order (the valence
+ # fix's relief into a metal sink, :data:`_REDUCED_BOND_ORDER`). That extra bond, not a
+ # missing charge/H, blocks kekulization; reducing it frees the ring, atom left neutral.
+ reduced_metal_bonds = [] # (bond, original type) - restored if nothing resolves below
+ for at in metal_coordinating_atoms:
+ for nbr in at.GetNeighbors():
+ if not _is_metal(nbr.GetAtomicNum()):
+ continue
+ bond = mol.GetBondBetweenAtoms(at.GetIdx(), nbr.GetIdx())
+ if bond.GetBondType() in _REDUCED_BOND_ORDER:
+ reduced_metal_bonds.append((bond, bond.GetBondType()))
+ bond.SetBondType(_REDUCED_BOND_ORDER[bond.GetBondType()])
+ if reduced_metal_bonds:
+ mol.UpdatePropertyCache(strict=False)
+ if _kekulized():
+ return
+
+ # 2) two-neighbour N given an *explicit* H: read that H as a charge ([nH] -> [nH+]),
+ # honouring an over-protonated input (an uncharged [nH]...[nH] imidazole is really the
+ # imidazolium) rather than stripping it. Only fires when the input supplied an explicit
+ # H, so the heavy-atom CCD path (implicit H) never reaches it - no CCD over-charging.
+ for ni, nH, charge in zip(
+ two_neighbour_ns, original_nH_state, original_charge_state
+ ):
+ if nH > 0 and charge == 0:
+ ni.SetFormalCharge(nH)
+ if _kekulized():
+ return
+ ni.SetFormalCharge(0) # not resolved - try other candidates
+ mol.UpdatePropertyCache(strict=False)
+
+ # 3) two-neighbour N: search [nH] on/off - the *neutral* resolution (pyrrole [nH] donates
+ # its lone pair vs pyridine [n]). Tried before any charge: a ring that kekulizes with an
+ # added H needs no invented cation, so this must precede the onium (step 4). Nearly all
+ # unkekulizable heavy-atom rings (thiophenes, lactams, ...) resolve neutrally here.
+ for combo in product([0, 1], repeat=len(two_neighbour_ns)):
+ for ni, nH_explicit in zip(two_neighbour_ns, combo):
+ ni.SetNumExplicitHs(nH_explicit)
+ if _kekulized():
+ return
+ for ni, nH_explicit in zip(two_neighbour_ns, original_nH_state):
+ ni.SetNumExplicitHs(nH_explicit) # restore before the charge route
+ mol.UpdatePropertyCache(strict=False)
+
+ # 4) onium (last resort): only a genuine aromatic cation reaches here - a saturated ring
+ # heteroatom that no neutral kekule can satisfy, so it is forced to carry a ring double
+ # bond (pyridinium/pyrylium/thiazolium). Charge the fewest atoms, N before O/S so a
+ # mixed ring charges the right one (a thiazolium is an N-ylide, not an S+).
+ onium_atoms.sort(key=lambda at: 0 if at.GetSymbol() == "N" else 1)
+ for size in range(1, len(onium_atoms) + 1):
+ for subset in combinations(onium_atoms, size):
+ for at in subset:
+ at.SetFormalCharge(1)
+ if _kekulized():
+ return
+ for at in subset:
+ at.SetFormalCharge(0)
+
+ # nothing resolved it - roll back the metal reductions (the [nH] search already restored
+ # its Hs above) so a failed attempt leaves the caller's in-place molecule untouched.
+ for bond, original_type in reduced_metal_bonds:
+ bond.SetBondType(original_type)
+ mol.UpdatePropertyCache(strict=False)
+
+
+def _is_metal(atomic_num: int) -> bool:
+ """
+ True for a metal peppr treats as a coordination centre: a transition / inner-transition
+ metal (valence unenforced, :func:`_has_no_valence_limit`) or an omitted main-group metal
+ (:data:`_ORGANOMETALLIC_OMITTED_ELEMENTS`). A ring heteroatom bonded to one is a neutral
+ dative donor, not an onium.
+ """
+ return (
+ _has_no_valence_limit(atomic_num)
+ or atomic_num in _ORGANOMETALLIC_OMITTED_ELEMENTS
+ )
+
+
+def _iteratively_fix(
+ mol: Chem.Mol,
+ sanitize_op: SanitizeFlags,
+ fix: Callable[[Chem.Mol, Exception], None],
+ max_fix_iterations: int,
+) -> None:
+ """
+ Repeatedly detect and fix the problems of a single sanitation stage, until every
+ problem is either fixed or known to be unfixable here.
+
+ Parameters
+ ----------
+ mol : Chem.rdchem.Mol
+ The molecule to fix, modified in place.
+ sanitize_op : SanitizeFlags
+ The sanitation operation whose problems are detected and fixed.
+ fix : Callable[[Chem.Mol, Exception], None]
+ Function applying a fix for a single detected problem.
+ max_fix_iterations : int
+ The maximum number of iterations to fix problems.
+
+ Notes
+ -----
+ RDKit surfaces problems iteratively - fixing one may resolve or shift others. Each pass
+ re-detects, marks any problem still present after its fix was attempted as *stuck*
+ (unfixable here, e.g. a tolerated metal centre), and acts only on the rest. Skipping
+ stuck ones - rather than aborting the stage on the first recurrence - lets the rest of
+ a cluster resolve completely.
+ """
+ stuck: list[Exception] = []
+ attempted: list[Exception] = []
+ for _ in range(max_fix_iterations):
+ problems = Chem.DetectChemistryProblems(mol, sanitizeOps=sanitize_op)
+ # a problem still present after its fix was attempted last pass cannot be
+ # fixed here - record it so it is not retried and does not stall the stage
+ for problem in problems:
+ if any(_is_same_problem(problem, a) for a in attempted) and not any(
+ _is_same_problem(problem, s) for s in stuck
+ ):
+ stuck.append(problem)
+ # act only on problems not yet addressed (and not given up on)
+ pending = [
+ problem
+ for problem in problems
+ if not any(_is_same_problem(problem, s) for s in stuck)
+ ]
+ if not pending:
+ # everything is either fixed or known to be unfixable here
+ break
+ for problem in pending:
+ fix(mol, problem)
+ attempted = pending
+
+
+def _is_same_problem(problem1: Exception, problem2: Exception) -> bool:
+ """
+ Check if two exceptions related to chemistry problems are the same.
+
+ Parameters
+ ----------
+ problem1, problem2 : Exception
+ The problems to compare.
+
+ Returns
+ -------
+ same : bool
+ True if the two problems are the same.
+ """
+ problem_type = problem1.GetType()
+ if problem_type != problem2.GetType():
+ return False
+ elif problem_type == "AtomValenceException":
+ if problem1.GetAtomIdx() != problem2.GetAtomIdx():
+ return False
+ elif problem_type == "KekulizeException":
+ if (
+ len(
+ set(problem1.GetAtomIndices()).intersection(
+ set(problem2.GetAtomIndices())
+ )
+ )
+ == 0
+ ):
+ return False
+ return True
diff --git a/src/plinder/core/utils/schemas.py b/src/plinder/core/utils/schemas.py
index cedf94663..958f328a9 100644
--- a/src/plinder/core/utils/schemas.py
+++ b/src/plinder/core/utils/schemas.py
@@ -2,10 +2,150 @@
# Distributed under the terms of the Apache License 2.0
import pyarrow as pa
+MAPPED_ALIGNMENT_REQUIRED_COLUMNS = frozenset(
+ {
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ "source",
+ "qcov",
+ "tcov",
+ "fident",
+ "seqsim",
+ "query_selected_residue_numbers",
+ "target_selected_residue_numbers",
+ "query_selected_residue_positions",
+ "target_selected_residue_positions",
+ "selected_residue_identity_bits",
+ }
+)
+
+RELEASE_ALIGNMENT_MAPPING_REQUIRED_COLUMNS = frozenset(
+ {
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ "source",
+ "query_start",
+ "target_start",
+ "cigar",
+ "selected_residue_identity_bits",
+ }
+)
+
+
+def mapped_alignment_schema(*, alignment_type: str) -> pa.Schema:
+ """Return the per-query mapped-alignment schema."""
+ fields = [
+ pa.field("query_entry", pa.string()),
+ pa.field("target_entry", pa.string()),
+ pa.field("query_chain_mapped", pa.string()),
+ pa.field("target_chain_mapped", pa.string()),
+ pa.field("source", pa.string()),
+ pa.field("qcov", pa.float64()),
+ pa.field("tcov", pa.float64()),
+ pa.field("fident", pa.float64()),
+ pa.field("seqsim", pa.float64()),
+ pa.field("query_selected_residue_numbers", pa.list_(pa.int32())),
+ pa.field("target_selected_residue_numbers", pa.list_(pa.int32())),
+ pa.field("query_selected_residue_positions", pa.list_(pa.uint16())),
+ pa.field("target_selected_residue_positions", pa.list_(pa.uint16())),
+ pa.field("selected_residue_identity_bits", pa.binary()),
+ ]
+ if alignment_type == "foldseek":
+ fields.append(pa.field("lddt", pa.float64()))
+ elif alignment_type != "mmseqs":
+ raise ValueError(f"unknown alignment type: {alignment_type}")
+ return pa.schema(fields)
+
+
+def mapped_alignment_schema_is_current(
+ columns: set[str], *, alignment_type: str
+) -> bool:
+ """Return whether a mapped alignment has the current compact schema."""
+ required = MAPPED_ALIGNMENT_REQUIRED_COLUMNS
+ if alignment_type == "foldseek":
+ required = required | {"lddt"}
+ elif alignment_type != "mmseqs":
+ raise ValueError(f"unknown alignment type: {alignment_type}")
+ return required.issubset(columns)
+
+
+def release_alignment_mapping_schema(
+ *, alignment_type: str, include_scores: bool = True
+) -> pa.Schema:
+ """Return the CIGAR-based release alignment schema."""
+ if alignment_type not in {"foldseek", "mmseqs"}:
+ raise ValueError(f"unknown alignment type: {alignment_type}")
+ return ALIGNMENT_CIGAR_SCHEMA if include_scores else ALIGNMENT_CIGAR_ONLY_SCHEMA
+
+
+def release_alignment_mapping_schema_is_current(
+ columns: set[str], *, alignment_type: str, include_scores: bool = True
+) -> bool:
+ """Check residue-mapping columns and, when requested, chain scores."""
+ required = RELEASE_ALIGNMENT_MAPPING_REQUIRED_COLUMNS
+ if include_scores:
+ required = required | {"qcov", "tcov", "fident", "seqsim"}
+ if alignment_type == "foldseek":
+ required = required | {"lddt"}
+ if alignment_type not in {"foldseek", "mmseqs"}:
+ raise ValueError(f"unknown alignment type: {alignment_type}")
+ return required.issubset(columns)
+
+
+PROTEIN_SIMILARITY_EXPORT_SCHEMA = pa.schema(
+ [
+ ("query_entry", pa.string()),
+ ("target_entry", pa.string()),
+ ("query_chain_mapped", pa.string()),
+ ("target_chain_mapped", pa.string()),
+ ("source", pa.string()),
+ ("qcov", pa.uint8()),
+ ("tcov", pa.uint8()),
+ ("fident", pa.uint8()),
+ ("seqsim", pa.uint8()),
+ ("lddt", pa.uint8()),
+ ]
+)
+
+
+ALIGNMENT_CIGAR_SCHEMA = pa.schema(
+ [
+ ("query_entry", pa.string()),
+ ("target_entry", pa.string()),
+ ("query_chain_mapped", pa.string()),
+ ("target_chain_mapped", pa.string()),
+ ("source", pa.string()),
+ ("query_start", pa.uint32()),
+ ("target_start", pa.uint32()),
+ ("cigar", pa.string()),
+ ("qcov", pa.float64()),
+ ("tcov", pa.float64()),
+ ("fident", pa.float64()),
+ ("seqsim", pa.float64()),
+ ("lddt", pa.float64()),
+ ("selected_residue_identity_bits", pa.binary()),
+ ]
+)
+
+ALIGNMENT_CIGAR_ONLY_SCHEMA = pa.schema(
+ [
+ field
+ for field in ALIGNMENT_CIGAR_SCHEMA
+ if field.name not in {"qcov", "tcov", "fident", "seqsim", "lddt"}
+ ]
+)
+
+
PROTEIN_SIMILARITY_SCHEMA = pa.schema(
[
("query_system", pa.string()),
+ ("query_ligand_id", pa.string()),
("target_system", pa.string()),
+ ("target_ligand_id", pa.string()),
("protein_mapping", pa.string()),
("mapping", pa.string()),
("protein_mapper", pa.dictionary(pa.int8(), pa.string())),
@@ -15,35 +155,208 @@
]
)
+INTERFACE_SIMILARITY_SCHEMA = pa.schema(
+ [
+ ("query_system", pa.string()),
+ ("target_system", pa.string()),
+ ("mapping", pa.string()),
+ ("source", pa.dictionary(pa.int8(), pa.string(), ordered=True)),
+ ("metric", pa.dictionary(pa.int8(), pa.string(), ordered=True)),
+ ("iface1_qcov", pa.float32()),
+ ("iface2_qcov", pa.float32()),
+ ("similarity", pa.int8()),
+ ]
+)
+
+INTERFACE_SCORE_SHARD_SCHEMA = pa.schema(
+ [
+ ("query_system", pa.string()),
+ ("target_system", pa.string()),
+ ("mapping", pa.string()),
+ ("source", pa.string()),
+ ("metric", pa.string()),
+ ("iface1_qcov", pa.float32()),
+ ("iface2_qcov", pa.float32()),
+ ("similarity", pa.int8()),
+ ]
+)
+
+INTERFACE_SIMILARITY_EXPORT_SCHEMA = pa.schema(
+ [
+ ("query_system", pa.string()),
+ ("target_system", pa.string()),
+ ("iface1_qcov", pa.float32()),
+ ("iface2_qcov", pa.float32()),
+ ("similarity", pa.int8()),
+ ]
+)
+
+INTERFACE_HALF_SIMILARITY_EXPORT_SCHEMA = pa.schema(
+ [
+ ("query_half_interface_id", pa.string()),
+ ("target_half_interface_id", pa.string()),
+ ("similarity", pa.int8()),
+ ]
+)
-NETWORKX_CLUSTER_SCHEMA = pa.schema(
+INTERFACE_HALF_REPRESENTATIVE_SCHEMA = pa.schema(
[
- ("system_id", pa.dictionary(pa.int32(), pa.string())),
- ("component", pa.dictionary(pa.int32(), pa.string())),
- ("community", pa.dictionary(pa.int32(), pa.string())),
+ ("half_interface_id", pa.string()),
+ ("entry_pdb_id", pa.string()),
+ ("instance_chain_id", pa.string()),
+ ("chain_asym_id", pa.string()),
+ ("residue_numbers", pa.list_(pa.int32())),
+ ("residue_indices", pa.list_(pa.int32())),
]
)
+INTERFACE_REPRESENTATIVE_SCHEMA = pa.schema(
+ [
+ ("representative_system_id", pa.string()),
+ ("entry_pdb_id", pa.string()),
+ ("half_interface_1_id", pa.string()),
+ ("half_interface_2_id", pa.string()),
+ ]
+)
-GRAPHTOOL_CLUSTER_SCHEMA = pa.schema(
+INTERFACE_MEMBERSHIP_SCHEMA = pa.schema(
[
("system_id", pa.string()),
- ("component", pa.dictionary(pa.int32(), pa.string())),
- ("metric", pa.dictionary(pa.int32(), pa.string())),
- ("directed", pa.dictionary(pa.int32(), pa.string())),
- ("threshold", pa.int8()),
+ ("representative_system_id", pa.string()),
+ ("side_1_half_interface_id", pa.string()),
+ ("side_2_half_interface_id", pa.string()),
]
)
+LIGAND_POCKET_REPRESENTATIVE_SCHEMA = pa.schema(
+ [
+ ("representative_ligand_id", pa.string()),
+ ("representative_system_id", pa.string()),
+ ("entry_pdb_id", pa.string()),
+ ("ligand_asym_id", pa.string()),
+ ("ligand_is_shape_comparable", pa.bool_()),
+ ("receptor_set_id", pa.string()),
+ ("receptor_chain_asym_ids", pa.list_(pa.string())),
+ ("pocket_residues", pa.list_(pa.string())),
+ ("interactions", pa.list_(pa.string())),
+ ]
+)
-CLUSTER_SCHEMA = pa.schema(
+LIGAND_POCKET_MEMBERSHIP_SCHEMA = pa.schema(
[
("system_id", pa.string()),
- ("label", pa.string()),
- ("metric", pa.string()),
- ("cluster", pa.string()),
- ("directed", pa.bool_()),
- ("threshold", pa.int8()),
+ ("ligand_id", pa.string()),
+ ("representative_system_id", pa.string()),
+ ("representative_ligand_id", pa.string()),
+ ]
+)
+
+LIGAND_POCKET_RESIDUE_SCHEMA = pa.schema(
+ [
+ ("entry_pdb_id", pa.string()),
+ ("system_id", pa.string()),
+ ("ligand_id", pa.string()),
+ ("chain_instance", pa.string()),
+ ("chain_asym_id", pa.string()),
+ ("chain_auth_id", pa.string()),
+ ("residue_label_seq_id", pa.int32()),
+ ("residue_index", pa.int32()),
+ ("residue_auth_seq_id", pa.string()),
+ ("residue_insertion_code", pa.string()),
+ ("is_pli", pa.bool_()),
+ ]
+)
+
+LIGAND_POCKET_SCORE_QUERY_SCHEMA = pa.schema(
+ [
+ ("entry_pdb_id", pa.string()),
+ ("system_id", pa.string()),
+ ("ligand_id", pa.string()),
+ ("representative_system_id", pa.string()),
+ ("representative_ligand_id", pa.string()),
+ ("shard", pa.string()),
+ ]
+)
+
+LIGAND_POCKET_QCOV_REPRESENTATIVE_SCHEMA = pa.schema(
+ [
+ ("query_system", pa.string()),
+ ("query_ligand_id", pa.string()),
+ ("target_system", pa.string()),
+ ("target_ligand_id", pa.string()),
+ ("protein_mapping", pa.string()),
+ ("protein_mapper", pa.string()),
+ ("source", pa.string()),
+ ("pocket_qcov", pa.float64()),
+ ]
+)
+
+LIGAND_3D_CANDIDATE_SCHEMA = pa.schema(
+ [
+ ("query_system", pa.string()),
+ ("query_ligand_id", pa.string()),
+ ("query_entry", pa.string()),
+ ("query_ligand_asym_id", pa.string()),
+ ("target_system", pa.string()),
+ ("target_ligand_id", pa.string()),
+ ("target_entry", pa.string()),
+ ("target_ligand_asym_id", pa.string()),
+ ("protein_mapping", pa.string()),
+ ("protein_mapper", pa.string()),
+ ("pocket_qcov", pa.float64()),
+ ]
+)
+
+LIGAND_PAIR_SCORE_SCHEMA = pa.schema(
+ [
+ ("query_system", pa.string()),
+ ("query_ligand_id", pa.string()),
+ ("query_entry", pa.string()),
+ ("query_ligand_asym_id", pa.string()),
+ ("target_system", pa.string()),
+ ("target_ligand_id", pa.string()),
+ ("target_entry", pa.string()),
+ ("target_ligand_asym_id", pa.string()),
+ ("pocket_qcov", pa.int8()),
+ ("pocket_fident_qcov", pa.int8()),
+ ("pli_qcov", pa.int8()),
+ ]
+)
+
+LIGAND_SIMILARITY_EXPORT_SCHEMA = pa.schema(
+ [
+ ("query_system", pa.string()),
+ ("query_ligand_id", pa.string()),
+ ("target_system", pa.string()),
+ ("target_ligand_id", pa.string()),
+ ("pocket_qcov", pa.int8()),
+ ("pocket_fident_qcov", pa.int8()),
+ ("pli_qcov", pa.int8()),
+ ("shape", pa.int8()),
+ ("color", pa.int8()),
+ ("sucos_shape", pa.int8()),
+ ]
+)
+
+LIGAND_3D_PAIR_CANDIDATE_SCHEMA = pa.schema(
+ [
+ ("query_entry", pa.string()),
+ ("query_ligand_asym_id", pa.string()),
+ ("target_entry", pa.string()),
+ ("target_ligand_asym_id", pa.string()),
+ ("pocket_qcov", pa.float64()),
+ ]
+)
+
+LIGAND_3D_SCORE_SCHEMA = pa.schema(
+ [
+ ("query_entry", pa.string()),
+ ("query_ligand_asym_id", pa.string()),
+ ("target_entry", pa.string()),
+ ("target_ligand_asym_id", pa.string()),
+ ("shape", pa.float64()),
+ ("color", pa.float64()),
+ ("sucos_shape", pa.float64()),
]
)
@@ -52,11 +365,38 @@
[
pa.field("query_ligand_id", pa.int32()),
pa.field("target_ligand_id", pa.int32()),
- pa.field("tanimoto_similarity_max", pa.int8()),
+ pa.field("tanimoto_similarity_ecfp4_1024", pa.float32()),
]
)
+LIGAND_MMP_PAIR_SCHEMA = pa.schema(
+ [
+ ("ligand_smiles_id_1", pa.int32()),
+ ("ligand_smiles_id_2", pa.int32()),
+ ("ligand_smiles_1", pa.string()),
+ ("ligand_smiles_2", pa.string()),
+ ("transformation", pa.string()),
+ ("shared_core_smiles", pa.string()),
+ ("num_cuts", pa.int8()),
+ ("shared_core_num_heavy_atoms", pa.int16()),
+ ("ligand_1_num_heavy_atoms", pa.int16()),
+ ("ligand_2_num_heavy_atoms", pa.int16()),
+ ("ligand_1_shared_core_fraction", pa.float32()),
+ ("ligand_2_shared_core_fraction", pa.float32()),
+ ]
+)
+
+# MHFP6 MinHash edges: the third field carries the estimated Jaccard similarity
+# (percent) of the two ligands' circular-SMILES shingle sets.
+MHFP6_SCORE_SCHEMA = pa.schema(
+ [
+ pa.field("query_ligand_id", pa.int32()),
+ pa.field("target_ligand_id", pa.int32()),
+ pa.field("jaccard_similarity_mhfp6_2048", pa.float32()),
+ ]
+)
+
CLUSTER_DATASET_SCHEMA = pa.schema(
[
("metric", pa.string()),
@@ -78,17 +418,50 @@
)
-# subject to criteria used in save_linked_structures.py
-# TODO: this schema is now out of date since addition of
-# scores.json contents but it now contains >50 columns
STRUCTURE_LINK_SCHEMA = pa.schema(
[
- ("query_system", pa.string()),
- ("target_system", pa.string()),
- ("protein_qcov_weighted_sum", pa.float32()),
- ("protein_fident_weighted_sum", pa.float32()),
- ("pocket_fident", pa.float32()),
- ("target_id", pa.string()),
- ("sort_score", pa.float32()),
+ ("reference_system_id", pa.string()),
+ ("linked_structure_id", pa.string()),
+ ("source_entry_id", pa.string()),
+ ("source_chain_asym_id", pa.string()),
+ ("source_chain_auth_id", pa.string()),
+ ("source_biounit_id", pa.string()),
+ ("source_chain_instance", pa.string()),
+ ("source_num_contacting_ions", pa.int16()),
+ ("source_num_contacting_artifacts", pa.int16()),
+ ("source_num_contacting_other_ligands", pa.int16()),
+ ("source_resolution", pa.float32()),
+ ("rank", pa.int16()),
+ ("num_ligand_pockets", pa.int16()),
+ ("min_pocket_fident", pa.int8()),
+ ("mean_pocket_fident", pa.float32()),
+ ("min_protein_fident_weighted_sum", pa.int8()),
+ ("min_protein_fident_qcov_weighted_sum", pa.int8()),
+ ("min_protein_lddt_weighted_sum", pa.int8()),
+ ]
+)
+
+INTERFACE_APO_LINK_SCHEMA = pa.schema(
+ [
+ ("reference_system_id", pa.string()),
+ ("reference_side", pa.int8()),
+ ("reference_chain_instance", pa.string()),
+ ("reference_chain_asym_id", pa.string()),
+ ("linked_structure_id", pa.string()),
+ ("source_entry_id", pa.string()),
+ ("source_chain_asym_id", pa.string()),
+ ("source_chain_auth_id", pa.string()),
+ ("source_biounit_id", pa.string()),
+ ("source_chain_instance", pa.string()),
+ ("source_num_contacting_proteins", pa.int16()),
+ ("source_num_contacting_ions", pa.int16()),
+ ("source_num_contacting_artifacts", pa.int16()),
+ ("source_num_contacting_other_ligands", pa.int16()),
+ ("source_resolution", pa.float32()),
+ ("rank", pa.int16()),
+ ("mmseqs_fident", pa.float32()),
+ ("mmseqs_query_coverage", pa.float32()),
+ ("mmseqs_target_coverage", pa.float32()),
+ ("foldseek_lddt", pa.float32()),
]
)
diff --git a/src/plinder/core/utils/unpack.py b/src/plinder/core/utils/unpack.py
deleted file mode 100644
index d2ac5a891..000000000
--- a/src/plinder/core/utils/unpack.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-from pathlib import Path
-from time import time
-from typing import Literal, Optional
-from zipfile import BadZipFile, ZipFile
-
-from omegaconf import DictConfig
-from tqdm.contrib.concurrent import thread_map
-
-from plinder.core.utils import cpl
-from plinder.core.utils.config import get_config
-from plinder.core.utils.log import setup_logger
-
-LOG = setup_logger(__name__)
-ZIP_KINDS = Literal["entries", "linked_structures", "systems"]
-ID_KINDS = Literal["system_ids", "pdb_ids", "two_char_code"]
-
-
-def expand_config_context(
- *,
- system_ids: Optional[str | list[str]] = None,
- pdb_ids: Optional[str | list[str]] = None,
- two_char_codes: Optional[str | list[str]] = None,
- cfg: Optional[DictConfig] = None,
-) -> tuple[str, list[str]]:
- conf = cfg or get_config()
- if system_ids is None:
- systems = conf.context.system_ids
- elif isinstance(system_ids, str):
- systems = [system_ids]
- else:
- systems = system_ids
- if pdb_ids is None:
- pdbs = conf.context.pdb_ids
- elif isinstance(pdb_ids, str):
- pdbs = [pdb_ids]
- else:
- pdbs = pdb_ids
- if two_char_codes is None:
- two_chars = conf.context.two_char_codes
- elif isinstance(two_char_codes, str):
- two_chars = [two_char_codes]
- else:
- two_chars = two_char_codes
- if systems:
- return "system_ids", systems
- if pdbs:
- return "pdb_ids", pdbs
- return "two_char_codes", two_chars
-
-
-def _unpack_zip(path: Path) -> None:
- t0 = time()
- done = path.parent / (path.stem + "_done")
- if done.is_file():
- LOG.debug(f"skipping {path} as it was already extracted")
- return
- with ZipFile(path) as arch:
- arch.extractall(path=path.parent)
- done.touch()
- LOG.debug(f"validating and extracting {path} took {time() - t0:.2f}s")
- return
-
-
-def get_zips_to_unpack(
- *,
- kind: ZIP_KINDS,
- system_ids: Optional[str | list[str]] = None,
- pdb_ids: Optional[str | list[str]] = None,
- two_char_codes: Optional[str | list[str]] = None,
- cfg: Optional[DictConfig] = None,
-) -> dict[Path, list[str]]:
- """
- Get the zips to unpack (and unpack them if necessary) for
- the context provided (or configured).
-
- Parameters
- ----------
- kind : ZIP_KINDS
- the kind of zips to unpack
- system_ids : Optional[str | list[str]], default=None
- the system IDs to unpack
- pdb_ids : Optional[str | list[str]], default=None
- the PDB IDs to unpack
- two_char_codes : Optional[str | list[str]], default=None
- the two character codes to unpack
- cfg : Optional[DictConfig], default=None
- the plinder.core config
-
- Returns
- -------
- dict[Path, list[str]]
- the zips to unpack and the list of IDs (based on kind) in each zip
- """
- conf = cfg or get_config()
- if kind == "linked_structures":
- id_kind = None
- ids: list[str] = []
- else:
- id_kind, ids = expand_config_context(
- system_ids=system_ids,
- pdb_ids=pdb_ids,
- two_char_codes=two_char_codes,
- cfg=cfg,
- )
-
- root = cpl.get_plinder_path(rel=getattr(conf.data, kind), download=False)
- zips: dict[Path, list[str]] = {}
- if id_kind is None:
- for zip in cpl.list_zip_paths(getattr(conf.data, kind)):
- zips.setdefault(zip, [])
- elif id_kind == "system_ids":
- for system_id in ids:
- two_char_code = system_id[1:3]
- key = root / f"{two_char_code}.zip"
- zips.setdefault(key, [])
- zips[key].append(system_id)
- elif id_kind == "pdb_ids":
- for pdb_id in ids:
- code = pdb_id[-3:-1]
- key = root / f"{code}.zip"
- zips.setdefault(key, [])
- zips[key].append(pdb_id)
- elif id_kind == "two_char_codes":
- for two_char_code in ids:
- key = root / f"{two_char_code}.zip"
- zips.setdefault(key, [])
-
- paths = list(zips.keys())
- for path in paths:
- if path.is_file():
- try:
- with ZipFile(path):
- pass
- except BadZipFile:
- LOG.error(f"removing malformed zip {path}")
- path.unlink()
-
- cpl.download_paths(paths=paths)
-
- if kind in ["systems", "linked_structures"]:
- if len(paths) > 10:
- thread_map(_unpack_zip, paths)
- else:
- cpl.thread_pool(_unpack_zip, paths)
-
- return zips
diff --git a/src/plinder/data/__init__.py b/src/plinder/data/__init__.py
index f7f279c05..bbf917140 100644
--- a/src/plinder/data/__init__.py
+++ b/src/plinder/data/__init__.py
@@ -1,19 +1,8 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
-from textwrap import dedent
+"""PLINDER ingest and dataset-generation modules.
-try:
- import ost # noqa
- import networkit # noqa
-except (ImportError, ModuleNotFoundError):
- raise ImportError(
- dedent(
- """\
- plinder.data requires the OpenStructureToolkit >= 2.8.0 (ost) and networkit == 11.0.0 to be installed.
- Please refer to the documentation for installation instructions and current limitations.
- See details here:
-
- https://plinder-org.github.io/plinder/contribution/development.html#creating-the-conda-environment
- """
- )
- )
+Optional dependencies are imported by the modules that use them. Keeping the
+package initializer dependency-free also lets :mod:`plinder.core` reuse the
+mmCIF reconstruction utilities in a standard pip installation.
+"""
diff --git a/src/plinder/data/_cover.py b/src/plinder/data/_cover.py
new file mode 100644
index 000000000..73014af59
--- /dev/null
+++ b/src/plinder/data/_cover.py
@@ -0,0 +1,56 @@
+"""Compiled linear-time operations for disk-backed directed covers."""
+
+import numpy as np
+from numba import njit
+from numpy.typing import NDArray
+
+
+@njit(nogil=True)
+def outgoing_counts(queries: NDArray[np.uint32], node_count: int) -> NDArray[np.int64]:
+ counts = np.zeros(node_count, dtype=np.int64)
+ for query in queries:
+ counts[query] += 1
+ return counts
+
+
+@njit(nogil=True)
+def transpose_edges(
+ offsets: NDArray[np.int64],
+ queries: NDArray[np.uint32],
+ scores: NDArray[np.uint8],
+ outgoing_offsets: NDArray[np.int64],
+ targets: NDArray[np.uint32],
+ outgoing_scores: NDArray[np.uint8],
+) -> None:
+ positions = outgoing_offsets[:-1].copy()
+ for target in range(len(offsets) - 1):
+ for edge in range(offsets[target], offsets[target + 1]):
+ query = queries[edge]
+ position = positions[query]
+ targets[position] = target
+ outgoing_scores[position] = scores[edge]
+ positions[query] += 1
+
+
+@njit(nogil=True)
+def decrement_gains(
+ covered: NDArray[np.int64],
+ offsets: NDArray[np.int64],
+ targets: NDArray[np.uint32],
+ scores: NDArray[np.uint8],
+ primary: int,
+ fallback: int,
+ primary_gains: NDArray[np.int64],
+ fallback_gains: NDArray[np.int64],
+) -> None:
+ for query in covered:
+ primary_gains[query] -= 1
+ fallback_gains[query] -= 1
+ for edge in range(offsets[query], offsets[query + 1]):
+ target = targets[edge]
+ if target != query:
+ score = scores[edge]
+ if score >= primary:
+ primary_gains[target] -= 1
+ if score >= fallback:
+ fallback_gains[target] -= 1
diff --git a/src/plinder/data/_version.py b/src/plinder/data/_version.py
deleted file mode 100644
index 2905a77d4..000000000
--- a/src/plinder/data/_version.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-"""
-Module for supplying version information.
-
-This module provides the function `_get_version()`, which gets the version if
-either setuptools_scm or our package is installed, and returns "unknown"
-otherwise. Getting the version from setuptools_scm is primarily useful for
-Docker image building (where it doesn't make sense to make the host install our
-package just to obtain the version information to pass to the image build
-process) and for editable installs (where having setuptools_scm installed is
-the only way to get accurate version information).
-
-When our package is installed, its version (the result of `get_version()`) can
-be accessed as `plinder.__version__`.
-"""
-
-import warnings
-
-
-def _get_version() -> str:
- try:
- # Our first choice would be to get the version from setuptools_scm if it
- # is installed (only way that works with editable installs)
- from setuptools_scm import get_version as scm_get_version
-
- version: str = scm_get_version(root="../..", relative_to=__file__)
- except (ImportError, LookupError):
- from importlib.metadata import PackageNotFoundError
- from importlib.metadata import version as importlib_version
-
- try:
- # Our second choice is to try to get the version from importlib
- version = importlib_version("plinder")
- except PackageNotFoundError:
- # We will land here if our package isn't actually installed
- warnings.warn("Neither our package nor setuptools_scm are installed")
- version = "unknown"
- version = "unknown"
- return version
diff --git a/src/plinder/data/common/__init__.py b/src/plinder/data/annotations/__init__.py
similarity index 100%
rename from src/plinder/data/common/__init__.py
rename to src/plinder/data/annotations/__init__.py
diff --git a/src/plinder/data/annotations/affinity.py b/src/plinder/data/annotations/affinity.py
new file mode 100644
index 000000000..3827d02a3
--- /dev/null
+++ b/src/plinder/data/annotations/affinity.py
@@ -0,0 +1,195 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Select an unambiguous BindingDB measurement for a receptor."""
+
+from collections.abc import Collection, Mapping, Sequence
+from pathlib import Path
+from shutil import copyfile
+from typing import Any
+
+import numpy as np
+import pandas as pd
+
+from plinder.data.annotations.protein_utils import sequences_match_core
+
+
+def candidate_map(candidates: pd.DataFrame) -> dict[str, list[dict[str, Any]]]:
+ """Index strict BindingDB candidates by reported PDB/ligand code."""
+ by_key: dict[str, list[dict[str, Any]]] = {}
+ for key, target_sequence, endpoint, pchembl, count in candidates[
+ ["pdbid_ligid", "target_sequence", "endpoint", "pchembl", "count"]
+ ].itertuples(index=False, name=None):
+ by_key.setdefault(key, []).append(
+ {
+ "target_sequence": target_sequence,
+ "endpoint": endpoint,
+ "pchembl": pchembl,
+ "count": count,
+ }
+ )
+ return by_key
+
+
+def matched_affinity(
+ candidates: Sequence[Mapping[str, Any]], receptor_seqres: Mapping[str, str]
+) -> tuple[float, str, int] | None:
+ """Return pKi/pKd, endpoint, and measurement count for one target match.
+
+ Candidates have already passed the within-target assay/qualifier checks.
+ A missing receptor sequence or multiple matching target sequences is
+ ambiguous, so neither produces a scalar affinity.
+ """
+ if not receptor_seqres:
+ return None
+ matching = [
+ candidate
+ for candidate in candidates
+ if candidate.get("target_sequence")
+ and any(
+ sequences_match_core(candidate["target_sequence"], sequence)
+ for sequence in receptor_seqres.values()
+ )
+ ]
+ if len(matching) != 1:
+ return None
+ candidate = matching[0]
+ return (
+ float(candidate["pchembl"]),
+ str(candidate["endpoint"]),
+ int(candidate["count"]),
+ )
+
+
+def build_ligand_affinity_table(
+ annotation_path: Path,
+ entry_chains_path: Path,
+ candidates_path: Path,
+ *,
+ pdb_ids: Collection[str] | None = None,
+) -> pd.DataFrame:
+ """Assign BindingDB candidates to ligands using their receptor chains.
+
+ A BindingDB PDB/CCD cross-reference alone is not sufficient evidence for
+ the scalar value. Unmatched or ambiguous ligands retain null values here.
+ """
+ filters = [("entry_pdb_id", "in", sorted(pdb_ids))] if pdb_ids is not None else None
+ annotations = pd.read_parquet(
+ annotation_path,
+ columns=[
+ "ligand_id",
+ "system_id",
+ "entry_pdb_id",
+ "ligand_ccd_code",
+ "ligand_protein_chains_asym_id",
+ ],
+ filters=filters,
+ )
+ chains = pd.read_parquet(
+ entry_chains_path,
+ columns=["entry_pdb_id", "chain_asym_id", "chain_sequence"],
+ filters=filters,
+ )
+ sequence_by_chain = {
+ (pdb_id, asym_id): sequence
+ for pdb_id, asym_id, sequence in chains.itertuples(index=False, name=None)
+ if isinstance(sequence, str) and sequence
+ }
+ candidates_by_key = candidate_map(pd.read_parquet(candidates_path))
+
+ values: list[tuple[float | None, str | None, int | None]] = []
+ for _, _, pdb_id, ccd_code, receptor_chains in annotations.itertuples(
+ index=False, name=None
+ ):
+ key = f"{pdb_id}_{ccd_code}".upper()
+ receptor_seqres = {}
+ if isinstance(receptor_chains, (list, tuple, np.ndarray)):
+ for chain in receptor_chains:
+ sequence = sequence_by_chain.get(
+ (pdb_id, chain.split(".", maxsplit=1)[-1])
+ )
+ if sequence:
+ receptor_seqres[chain] = sequence
+ values.append(
+ matched_affinity(candidates_by_key.get(key, []), receptor_seqres)
+ or (None, None, None)
+ )
+ result = annotations[["ligand_id", "system_id"]].copy()
+ affinity_columns = [
+ "ligand_binding_affinity",
+ "ligand_binding_affinity_endpoint",
+ "ligand_binding_affinity_measurement_count",
+ ]
+ result[affinity_columns] = pd.DataFrame(
+ values, index=result.index, columns=affinity_columns
+ )
+ result["ligand_binding_affinity"] = result["ligand_binding_affinity"].astype(float)
+ result["ligand_binding_affinity_endpoint"] = result[
+ "ligand_binding_affinity_endpoint"
+ ].astype("string")
+ result["ligand_binding_affinity_measurement_count"] = result[
+ "ligand_binding_affinity_measurement_count"
+ ].astype("Int64")
+ result["system_has_binding_affinity"] = (
+ result.groupby("system_id")["ligand_binding_affinity"].transform("count").gt(0)
+ )
+ return result.drop(columns="system_id")
+
+
+def publish_affinity_tables(
+ data_dir: Path,
+ *,
+ affinity_dir: Path | None = None,
+ base_dir: Path | None = None,
+ changed_pdb_ids: Collection[str] = (),
+ removed_pdb_ids: Collection[str] = (),
+) -> None:
+ """Write corrected ligand values and source measurements beside the index."""
+ affinity_dir = affinity_dir or data_dir / "dbs" / "affinity"
+ index_dir = data_dir / "index"
+ index_dir.mkdir(parents=True, exist_ok=True)
+ ligand_path = index_dir / "ligand_affinity.parquet"
+ records_path = index_dir / "bindingdb_measurements.parquet"
+ ligand_tmp = ligand_path.with_suffix(".parquet.tmp")
+ records_tmp = records_path.with_suffix(".parquet.tmp")
+ try:
+ if base_dir is None:
+ values = build_ligand_affinity_table(
+ index_dir / "annotation_table.parquet",
+ index_dir / "entry_chains.parquet",
+ affinity_dir / "candidates.parquet",
+ )
+ else:
+ old = pd.read_parquet(base_dir / "index/ligand_affinity.parquet")
+ if removed_pdb_ids:
+ removed_ligands = pd.read_parquet(
+ base_dir / "index/annotation_table.parquet",
+ columns=["ligand_id"],
+ filters=[("entry_pdb_id", "in", sorted(removed_pdb_ids))],
+ )["ligand_id"]
+ old = old.loc[~old["ligand_id"].isin(removed_ligands)]
+ new = (
+ build_ligand_affinity_table(
+ index_dir / "annotation_table.parquet",
+ index_dir / "entry_chains.parquet",
+ affinity_dir / "candidates.parquet",
+ pdb_ids=changed_pdb_ids,
+ )
+ if changed_pdb_ids
+ else old.iloc[:0]
+ )
+ ligand_ids = pd.read_parquet(
+ index_dir / "annotation_table.parquet", columns=["ligand_id"]
+ )["ligand_id"]
+ values = (
+ pd.concat([old, new], ignore_index=True)
+ .set_index("ligand_id", verify_integrity=True)
+ .loc[ligand_ids]
+ .reset_index()
+ )
+ values.to_parquet(ligand_tmp, index=False)
+ copyfile(affinity_dir / "measurements.parquet", records_tmp)
+ ligand_tmp.replace(ligand_path)
+ records_tmp.replace(records_path)
+ finally:
+ ligand_tmp.unlink(missing_ok=True)
+ records_tmp.unlink(missing_ok=True)
diff --git a/src/plinder/data/annotations/aggregate_annotations.py b/src/plinder/data/annotations/aggregate_annotations.py
new file mode 100644
index 000000000..5ff69edae
--- /dev/null
+++ b/src/plinder/data/annotations/aggregate_annotations.py
@@ -0,0 +1,3100 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from __future__ import annotations
+
+import gzip
+import re
+import shutil
+import typing as ty
+from collections import Counter, defaultdict
+from dataclasses import dataclass, replace
+from functools import cached_property
+from itertools import combinations
+from pathlib import Path
+
+import biotite.structure as struc
+import biotite.structure.io.pdbx as pdbx
+import numpy as np
+import pandas as pd
+from biotite.file import DeserializationError, InvalidFileError
+from biotite.structure import filter_heavy
+from pydantic import BeforeValidator, Field, PrivateAttr
+from rdkit import RDLogger
+
+from plinder.core.utils.log import setup_logger
+from plinder.data.annotations.cif_utils import (
+ build_biounit,
+ get_chain_external_mappings,
+ get_entry_info,
+ get_entry_ph_range,
+ get_entry_taxonomy,
+ get_label_asym_sequences,
+ get_ligand_of_interest,
+ get_model_count,
+ get_structure_with_altloc,
+ remove_nonphysical_bonds,
+)
+from plinder.data.annotations.cif_utils import (
+ select_assembly_ids as _selected_assembly_ids,
+)
+from plinder.data.annotations.contact_areas import (
+ chain_pair_contact_areas,
+ tessellation_atom_mask,
+)
+from plinder.data.annotations.get_ligand_validation import (
+ EntryValidation,
+ ResidueListValidation,
+ ResidueValidationThresholds,
+)
+from plinder.data.annotations.interaction_utils import (
+ get_covalent_connections,
+ get_symmetry_mate_contacts,
+)
+from plinder.data.annotations.interface_utils import (
+ DEFAULT_MIN_INTERFACE_RESIDUES,
+ ProteinChainContacts,
+ ProteinInterface,
+ detect_protein_interfaces,
+ find_protein_chain_contacts,
+)
+from plinder.data.annotations.ligand_utils import (
+ BiounitSpatialIndex,
+ Ligand,
+ get_artifact_codes,
+ get_water_chain_ids,
+ is_known_artifact_ligand,
+ validate_chain_residue,
+)
+from plinder.data.annotations.protein_utils import (
+ Chain,
+ UnobservedAtom,
+ _is_polynucleotide,
+ _is_polypeptide,
+ detect_ligand_chains,
+ detect_ligand_chains_from_cif,
+ get_atom_site_author_ids,
+ get_modified_residues,
+ get_receptor_type,
+ get_unobserved_atoms,
+)
+from plinder.data.annotations.save_utils import save_ligands
+from plinder.data.annotations.utils import (
+ DocBaseModel,
+ description_excluded_from_flat_export,
+)
+
+LOG = setup_logger(__name__)
+RDLogger.DisableLog("rdApp.*")
+SymmetryMateContacts = ty.Annotated[
+ dict[tuple[str, int], dict[tuple[str, int], dict[int, set[int]]]],
+ BeforeValidator(validate_chain_residue),
+ Field(default_factory=dict),
+]
+CUSTOM_STRUCTURE_MODES = ("as_is", "pdb")
+ENTRY_VALIDATION_COLUMNS = (
+ *(f"entry_validation_{name}" for name in EntryValidation.model_fields),
+ "entry_validation_r_minus_rfree",
+ "entry_pass_validation_criteria",
+)
+
+
+def _require_mmcif_path(path: Path) -> Path:
+ """Reject legacy PDB files and unrelated structure formats."""
+ path = Path(path)
+ name = path.name.lower()
+ if not name.endswith((".cif", ".cif.gz", ".mmcif", ".mmcif.gz")):
+ raise ValueError(
+ f"custom structures must be mmCIF files (.cif/.mmcif, optionally "
+ f"gzip-compressed), not {path.name!r}"
+ )
+ return path
+
+
+def _chain_type_from_coordinates(atoms: struc.AtomArray) -> str:
+ """Identify standard polymer chains when entity metadata is absent."""
+ if np.all(struc.filter_solvent(atoms)):
+ return "water"
+ residue_starts = struc.get_residue_starts(atoms, add_exclusive_stop=True)
+ if len(residue_starts) < 2:
+ return "non-polymer"
+ protein_residues = 0
+ nucleotide_residues = 0
+ dna_residues = 0
+ rna_residues = 0
+ ambiguous_nucleotide_residues = 0
+ for start, stop in zip(residue_starts[:-1], residue_starts[1:]):
+ residue = atoms[start:stop]
+ atom_names = set(residue.atom_name.astype(str))
+ if np.any(struc.filter_amino_acids(residue)) or {
+ "N",
+ "CA",
+ "C",
+ }.issubset(atom_names):
+ protein_residues += 1
+ if np.any(struc.filter_nucleotides(residue)):
+ nucleotide_residues += 1
+ residue_name = str(residue.res_name[0]).upper()
+ if residue_name in {"DA", "DC", "DG", "DT", "DU", "DI"}:
+ dna_residues += 1
+ elif residue_name in {"A", "C", "G", "U", "I"} or atom_names.intersection(
+ {
+ "O2'",
+ "O2*",
+ }
+ ):
+ rna_residues += 1
+ else:
+ ambiguous_nucleotide_residues += 1
+ residue_count = len(residue_starts) - 1
+ if protein_residues == residue_count:
+ return "polypeptide(L)"
+ if nucleotide_residues == residue_count:
+ if dna_residues and not rna_residues and not ambiguous_nucleotide_residues:
+ return "polydeoxyribonucleotide"
+ if rna_residues and not dna_residues and not ambiguous_nucleotide_residues:
+ return "polyribonucleotide"
+ # Mixed or modified nucleotides without a decisive sugar marker must
+ # not be mislabeled as pure RNA. The hybrid type keeps both receptor
+ # classes visible downstream.
+ return "polydeoxyribonucleotide/polyribonucleotide hybrid"
+ return "non-polymer"
+
+
+def _sequence_from_coordinates(atoms: struc.AtomArray) -> str:
+ """Return the resolved polymer sequence, or an empty string on ambiguity."""
+ try:
+ sequences, _ = struc.to_sequence(atoms, allow_hetero=True)
+ except (IndexError, TypeError, ValueError, struc.BadStructureError):
+ return ""
+ return str(sequences[0]) if len(sequences) == 1 else ""
+
+
+class _LigandChainClasses(ty.NamedTuple):
+ """Ligand-like asym IDs split by how ingest treats them.
+
+ Monoatomic ions and known artifacts are deferred: they only become
+ ligands when they connect to a proper primary ligand's pocket.
+ """
+
+ monoatomic_ion_asym_ids: set[str]
+ known_artifact_asym_ids: set[str]
+ primary_asym_ids: set[str]
+
+
+def remove_alphabets(x: str) -> int:
+ """Turn alphanumeric to integer
+
+ Parameters
+ ----------
+ x : str
+ Alphanumeric string
+
+ Returns
+ -------
+ int
+ """
+
+ return int(re.sub("[^0-9]", "", str(x)))
+
+
+@dataclass
+class QualityCriteria:
+ max_entry_resolution: float = 3.5
+ max_entry_r: float = 0.4
+ max_entry_rfree: float = 0.45
+ max_entry_r_minus_rfree: float = 0.05
+ ligand_max_num_unresolved_heavy_atoms: int = 0
+ ligand_max_alt_count: int = 1
+ ligand_min_average_occupancy: float = 0.8
+ ligand_min_average_rscc: float = 0.8
+ ligand_max_average_rsr: float = 0.3
+ ligand_max_percent_outliers_clashes: float = 0
+ ligand_max_fraction_atoms_with_crystal_contacts: float = 0
+ pocket_max_num_unresolved_heavy_atoms: int = 0
+ pocket_max_alt_count: int = 1
+ pocket_min_average_occupancy: float = 0.8
+ pocket_min_average_rscc: float = 0.8
+ pocket_max_average_rsr: float = 0.3
+ pocket_max_percent_outliers_clashes: int = 100
+
+
+class System(DocBaseModel):
+ pdb_id: str = Field(description="[EXCLUDE] PDB ID")
+ biounit_id: str = Field(description="Biounit ID")
+ id_legacy: str = Field(
+ default="",
+ description="Historical system ID using global assembly-operation chain instances",
+ )
+ ligands: list[Ligand] = Field(description="[EXCLUDE] List of Ligands in a systems")
+ receptor_type: str = Field(
+ description=(
+ "Receptor polymer composition: protein, DNA, RNA, other, or a "
+ "+-joined combination"
+ )
+ )
+ ligand_validation: ResidueListValidation | None = Field(
+ default=None,
+ description="[EXCLUDE] Validation object for the ligand residues in the system",
+ )
+ pocket_validation: ResidueListValidation | None = Field(
+ default=None,
+ description="[EXCLUDE] Validation object for the system's pocket residues",
+ )
+ pass_criteria: bool | None = Field(
+ default=None, description="Whether the system passes validation criteria"
+ ) # TODO: remove as attribute and have as function
+
+ """
+ This class defines a system which includes a protein-ligand complex
+ and its neighboring ligands and receptor residues
+
+ """
+
+ @classmethod
+ def document_properties(
+ cls, prefix: str
+ ) -> ty.Generator[tuple[str, str | None, str], ty.Any, ty.Any]:
+ """Describe model fields plus the flat columns emitted by ``format()``."""
+ yield from super().document_properties(prefix)
+ yield (
+ f"{prefix}_water_residues",
+ "list[str]",
+ "Interacting water residues encoded as ._",
+ )
+ for mapping_name in ("CATH", "Pfam", "SCOP2", "SCOP2B", "UniProt"):
+ yield (
+ f"{prefix}_pocket_{mapping_name}",
+ "str",
+ f"Most frequent {mapping_name} mapping among pocket residues",
+ )
+
+ def proper_ligands(self) -> list[Ligand]:
+ return [ligand for ligand in self.ligands if ligand.is_proper]
+
+ @cached_property
+ def protein_chains_asym_id(self) -> list[str]:
+ """
+ Interacting receptor chains (protein or nucleic acid) of the system.
+
+ The historical property name is retained in the annotation schema.
+ """
+ return sorted(
+ set(
+ chain
+ for ligand in self.ligands
+ for chain in ligand.protein_chains_asym_id
+ )
+ )
+
+ @cached_property
+ def id_no_biounit(self) -> str:
+ """
+ ID of the system without the biounit
+ """
+ return "__".join(
+ [
+ self.pdb_id,
+ "_".join(
+ x.split(".", maxsplit=1)[1] for x in self.protein_chains_asym_id
+ ),
+ "_".join(x.split(".", maxsplit=1)[1] for x in self.ligand_chains),
+ ]
+ )
+
+ @cached_property
+ def ligand_chains(self) -> list[str]:
+ """
+ Ligand chains of the system
+ """
+ return [f"{ligand.instance}.{ligand.asym_id}" for ligand in self.ligands]
+
+ @cached_property
+ def num_pocket_residues(self) -> int:
+ """
+ Number of pocket residues of the system
+ """
+ pocket_residues = set()
+ for ligand in self.ligands:
+ ligand_pocket_residues = ligand.pocket_residues
+ for chain in ligand_pocket_residues:
+ pocket_residues |= set(
+ (chain, residue) for residue in ligand_pocket_residues[chain]
+ )
+ return len(pocket_residues)
+
+ @cached_property
+ def proper_num_pocket_residues(self) -> int:
+ """
+ Number of pocket residues of the system excluding ions and artifacts
+ """
+ pocket_residues = set()
+ for chain in self.pocket_residues:
+ for residue in self.pocket_residues[chain]:
+ pocket_residues.add((chain, residue))
+ return len(pocket_residues)
+
+ @cached_property
+ def num_interactions(self) -> int:
+ """
+ Number of interactions of the system
+ """
+ return sum(l.num_interactions for l in self.ligands)
+
+ @cached_property
+ def proper_num_interactions(self) -> int:
+ """
+ Number of interactions of the system excluding ions and artifacts
+ """
+ return sum(l.num_interactions for l in self.proper_ligands())
+
+ @cached_property
+ def num_unique_interactions(self) -> int:
+ """
+ Number of unique interactions of the system
+ """
+ return sum(l.num_unique_interactions for l in self.ligands)
+
+ @cached_property
+ def proper_num_unique_interactions(self) -> int:
+ """
+ Number of unique interactions of the system excluding ions and artifacts
+ """
+ return sum(l.num_unique_interactions for l in self.proper_ligands())
+
+ @cached_property
+ def num_covalent_ligands(self) -> int:
+ """
+ Number of covalent ligands of the system
+ """
+ return sum(ligand.is_covalent for ligand in self.ligands)
+
+ @cached_property
+ def proper_num_covalent_ligands(self) -> int:
+ """
+ Number of covalent ligands of the system excluding ions and artifacts
+ """
+ return sum(ligand.is_covalent for ligand in self.proper_ligands())
+
+ @cached_property
+ def id(self) -> str:
+ """
+ ID of the system
+ """
+ return "__".join(
+ [
+ self.pdb_id,
+ self.biounit_id,
+ "_".join(self.protein_chains_asym_id),
+ "_".join(self.ligand_chains),
+ ]
+ )
+
+ @cached_property
+ def system_type(self) -> str:
+ """
+ Type of the system (one of: holo, ion, artifact)
+ """
+ if any(not l.is_ion and not l.is_artifact for l in self.ligands):
+ return "holo"
+ elif any(l.is_ion for l in self.ligands):
+ return "ion"
+ else:
+ return "artifact"
+
+ @cached_property
+ def has_binding_affinity(self) -> bool:
+ """
+ Whether any ligand in the system has a binding affinity from BindingDB
+ """
+ return any(l.binding_affinity is not None for l in self.ligands)
+
+ @cached_property
+ def pocket_residues(self) -> dict[str, dict[int, str]]:
+ """[EXCLUDE] Pockets residues of the system"""
+ all_residues: dict[str, dict[int, str]] = defaultdict(dict)
+ for ligand in self.ligands:
+ if not ligand.is_proper:
+ continue
+ ligand_pocket_residues = ligand.pocket_residues
+ for chain in ligand_pocket_residues:
+ all_residues[chain].update(ligand_pocket_residues[chain])
+ return all_residues
+
+ @cached_property
+ def interactions(self) -> dict[str, dict[int, list[str]]]:
+ """[EXCLUDE] Interactions of the system"""
+ all_interactions: dict[str, dict[int, list[str]]] = defaultdict(
+ lambda: defaultdict(list)
+ )
+ for ligand in self.ligands:
+ if not ligand.is_proper:
+ continue
+ for chain in ligand.interactions:
+ for residue in ligand.interactions[chain]:
+ all_interactions[chain][residue].extend(
+ ligand.interactions[chain][residue]
+ )
+ return all_interactions
+
+ @cached_property
+ def interactions_counter(self) -> dict[str, dict[int, ty.Counter[str]]]:
+ """[EXCLUDE] Counter of interactions of the system"""
+ interactions_counter: dict[str, dict[int, ty.Counter[str]]] = {}
+ for chain in self.interactions:
+ interactions_counter[chain] = {}
+ for residue in self.interactions[chain]:
+ interactions_counter[chain][residue] = Counter(
+ self.interactions[chain][residue]
+ )
+ return interactions_counter
+
+ def format_chains(
+ self,
+ chain_type: str,
+ chains: dict[str, Chain],
+ sub_chains: list[str] | None = None,
+ ) -> dict[str, ty.Any]:
+ if sub_chains is None:
+ if chain_type == "protein":
+ sub_chains = self.protein_chains_asym_id
+ elif chain_type == "ligand":
+ sub_chains = self.ligand_chains
+ else:
+ raise ValueError(f"chain_type={chain_type} requires sub_chains")
+ sub_chain_list = [ch.split(".", maxsplit=1) for ch in sub_chains]
+
+ sub_chains_data = [
+ chains[c].format(int(instance)) for instance, c in sub_chain_list
+ ]
+ if chain_type == "other":
+ for sub_chain, (_, asym_id) in zip(sub_chains_data, sub_chain_list):
+ sub_chain["chain_type"] = chains[asym_id].chain_type_str
+
+ if len(sub_chains_data) == 0:
+ return {}
+ data: dict[str, list[ty.Any]] = defaultdict(list)
+ for sub_chain in sub_chains_data:
+ for key in sub_chain:
+ data[f"system_{chain_type}_chains_{key}"].append(sub_chain[key])
+ return data
+
+ @cached_property
+ def num_protein_chains(self) -> int:
+ """
+ Number of interacting receptor chains of the system.
+ """
+ return len(self.protein_chains_asym_id)
+
+ @cached_property
+ def proper_num_protein_chains(self) -> int:
+ """
+ Number of interacting receptor chains excluding ions and artifacts.
+ """
+ return len(
+ set(
+ chain
+ for ligand in self.proper_ligands()
+ for chain in ligand.protein_chains_asym_id
+ )
+ )
+
+ @cached_property
+ def num_ligand_chains(self) -> int:
+ """
+ Number of ligand chains of the system
+ """
+ return len(self.ligands)
+
+ @cached_property
+ def proper_num_ligand_chains(self) -> int:
+ """
+ Number of ligand chains of the system excluding ions and artifacts
+ """
+ return len(self.proper_ligands())
+
+ def format_validation(
+ self, entry_pass_criteria: bool | None, criteria: QualityCriteria
+ ) -> dict[str, ty.Any]:
+ data = {}
+ if self.ligand_validation:
+ ligand_validation = self.ligand_validation.format()
+ data.update({f"system_ligand_{k}": v for k, v in ligand_validation.items()})
+ if self.pocket_validation:
+ pocket_validation = self.pocket_validation.format()
+ data.update({f"system_pocket_{k}": v for k, v in pocket_validation.items()})
+ if (
+ self.pocket_validation is None
+ or self.ligand_validation is None
+ or entry_pass_criteria is None
+ or not entry_pass_criteria
+ or data["system_ligand_validation_max_alt_count"] is None
+ or data["system_ligand_validation_average_occupancy"] is None
+ or data["system_ligand_validation_average_rscc"] is None
+ or data["system_ligand_validation_average_rsr"] is None
+ or data["system_ligand_validation_percent_outliers_clashes"] is None
+ or data["system_pocket_validation_num_unresolved_heavy_atoms"] is None
+ or data["system_pocket_validation_max_alt_count"] is None
+ or data["system_pocket_validation_average_occupancy"] is None
+ or data["system_pocket_validation_average_rscc"] is None
+ or data["system_pocket_validation_average_rsr"] is None
+ or data["system_pocket_validation_percent_outliers_clashes"] is None
+ ):
+ self.pass_criteria = False
+ else:
+ """
+ Quality criteria for the system
+ """
+ quality = [
+ # LIGAND
+ self.num_unresolved_heavy_atoms is not None
+ and self.num_unresolved_heavy_atoms
+ <= self.num_covalent_ligands
+ + criteria.ligand_max_num_unresolved_heavy_atoms,
+ data["system_ligand_validation_max_alt_count"]
+ <= criteria.ligand_max_alt_count,
+ data["system_ligand_validation_average_occupancy"]
+ >= criteria.ligand_min_average_occupancy,
+ data["system_ligand_validation_average_rscc"]
+ >= criteria.ligand_min_average_rscc,
+ data["system_ligand_validation_average_rsr"]
+ <= criteria.ligand_max_average_rsr,
+ data["system_ligand_validation_percent_outliers_clashes"]
+ <= criteria.ligand_max_percent_outliers_clashes,
+ self.fraction_atoms_with_crystal_contacts is not None
+ and self.fraction_atoms_with_crystal_contacts
+ <= criteria.ligand_max_fraction_atoms_with_crystal_contacts,
+ # POCKET
+ data["system_pocket_validation_num_unresolved_heavy_atoms"]
+ <= criteria.pocket_max_num_unresolved_heavy_atoms,
+ data["system_pocket_validation_max_alt_count"]
+ <= criteria.pocket_max_alt_count,
+ data["system_pocket_validation_average_occupancy"]
+ >= criteria.pocket_min_average_occupancy,
+ data["system_pocket_validation_average_rscc"]
+ >= criteria.pocket_min_average_rscc,
+ data["system_pocket_validation_average_rsr"]
+ <= criteria.pocket_max_average_rsr,
+ data["system_pocket_validation_percent_outliers_clashes"]
+ <= criteria.pocket_max_percent_outliers_clashes,
+ ]
+ self.pass_criteria = all(quality)
+ data["system_pass_validation_criteria"] = self.pass_criteria
+ return data
+
+ def format(
+ self,
+ chains: dict[str, Chain],
+ entry_pass_criteria: bool | None,
+ criteria: QualityCriteria = QualityCriteria(),
+ ) -> dict[str, ty.Any]:
+ data: dict[str, ty.Any] = defaultdict(str)
+ for field, (description, _) in self.get_descriptions_and_types().items():
+ if description_excluded_from_flat_export(description):
+ continue
+ if not field.startswith("system_"):
+ name = f"system_{field}"
+ else:
+ name = field
+ data[name] = getattr(self, field)
+
+ pocket_mapping = self.get_pocket_domains(chains)
+ for mapping in pocket_mapping:
+ data[f"system_pocket_{mapping}"] = pocket_mapping[mapping]
+ data.update(self.format_validation(entry_pass_criteria, criteria))
+ for chain_type in ["protein", "ligand"]:
+ data.update(self.format_chains(chain_type, chains))
+ data["system_water_residues"] = sorted(
+ f"{chain_id}_{residue_number}"
+ for chain_id, residue_numbers in self.waters.items()
+ for residue_number in set(residue_numbers)
+ )
+ return data
+
+ @cached_property
+ def waters(self) -> dict[str, list[int]]:
+ """[EXCLUDE] Waters interacting with any of the ligands in the system"""
+ waters: dict[str, list[int]] = defaultdict(list)
+ for ligand in self.ligands:
+ for chain in ligand.waters:
+ waters[chain] += ligand.waters[chain]
+ return waters
+
+ def select_waters(self) -> str:
+ query = []
+ for chain in self.waters:
+ chain_query = " or ".join(f"rnum={resnum}" for resnum in self.waters[chain])
+ query.append(f"(chain='{chain}' and ({chain_query}))")
+ return " or ".join(query)
+
+ @cached_property
+ def num_crystal_contacted_residues(self) -> int:
+ """
+ Number of residues from other symmetry mates which are in contact with any ligand in the system.
+ """
+ residues = set()
+ for ligand in self.ligands:
+ residues |= set(ligand.crystal_contacts.keys())
+ return len(residues)
+
+ @cached_property
+ def num_atoms_with_crystal_contacts(self) -> int:
+ """
+ Number of atoms in the system ligands which are in contact with residues from other symmetry mates.
+ """
+ return sum(ligand.num_atoms_with_crystal_contacts for ligand in self.ligands)
+
+ @cached_property
+ def num_heavy_atoms(self) -> int | None:
+ """
+ Number of heavy atoms in the system ligands
+ """
+ if any(ligand.num_heavy_atoms is None for ligand in self.ligands):
+ return None
+ return sum(
+ ligand.num_heavy_atoms
+ for ligand in self.ligands
+ if ligand.num_heavy_atoms is not None
+ )
+
+ @cached_property
+ def num_resolved_heavy_atoms(self) -> int | None:
+ """
+ Number of resolved heavy atoms in the system ligands
+ """
+ if any(ligand.num_resolved_heavy_atoms is None for ligand in self.ligands):
+ return None
+ return sum(
+ ligand.num_resolved_heavy_atoms
+ for ligand in self.ligands
+ if ligand.num_resolved_heavy_atoms is not None
+ )
+
+ @cached_property
+ def ligand_max_qed(self) -> float:
+ """
+ Maximum QED of the system ligands
+ """
+ return max(
+ ligand.qed if ligand.qed is not None else -1.0 for ligand in self.ligands
+ )
+
+ @cached_property
+ def ligand_max_molecular_weight(self) -> float:
+ """
+ Maximum molecular weight of the system ligands
+ """
+ max_vals = [
+ ligand.molecular_weight if ligand.molecular_weight is not None else -1.0
+ for ligand in self.ligands
+ if ligand.molecular_weight is not None
+ ]
+ if len(max_vals):
+ return max(max_vals)
+ else:
+ return 1
+
+ @cached_property
+ def proper_ligand_max_molecular_weight(self) -> float:
+ """
+ Maximum molecular weight of the system ligands excluding ions and artifacts
+ """
+ ligands = self.proper_ligands()
+ if len(ligands) == 0:
+ return -1.0
+ weights = [
+ ligand.molecular_weight if ligand.molecular_weight is not None else -1.0
+ for ligand in ligands
+ ]
+ return max(weights)
+
+ @cached_property
+ def num_unresolved_heavy_atoms(self) -> int | None:
+ """
+ Number of unresolved heavy atoms in the system ligands
+ """
+ if any(ligand.num_unresolved_heavy_atoms is None for ligand in self.ligands):
+ return None
+ return sum(
+ ligand.num_unresolved_heavy_atoms
+ for ligand in self.ligands
+ if ligand.num_unresolved_heavy_atoms is not None
+ )
+
+ @cached_property
+ def fraction_atoms_with_crystal_contacts(self) -> float | None:
+ """
+ Fraction of atoms in the system ligands which are in contact with residues from other symmetry mates.
+ """
+ if not self.num_heavy_atoms:
+ return None
+ return self.num_atoms_with_crystal_contacts / self.num_heavy_atoms
+
+ def selection(self, include_waters: bool = True) -> str:
+ ligand_selection = " or ".join(
+ f"({ligand.selection})" for ligand in self.ligands
+ )
+ protein_selection = " or ".join(
+ f"(cname='{chain}')" for chain in self.protein_chains_asym_id
+ )
+ selection = f"({ligand_selection}) or ({protein_selection})"
+ if include_waters and len(self.waters):
+ selection += f" or {self.select_waters()}"
+ return selection
+
+ def set_validation(
+ self,
+ chains: dict[str, Chain],
+ thresholds: ResidueValidationThresholds = ResidueValidationThresholds(),
+ ) -> None:
+ self.ligand_validation = ResidueListValidation.from_residues(
+ [
+ chains[c.split(".", maxsplit=1)[1]].residues[r].validation
+ for c in self.ligand_chains
+ for r in chains[c.split(".", maxsplit=1)[1]].residues
+ ],
+ thresholds,
+ )
+ self.pocket_validation = ResidueListValidation.from_residues(
+ [
+ chains[c.split(".", maxsplit=1)[1]].residues[r].validation
+ for c in self.pocket_residues
+ for r in self.pocket_residues[c]
+ ],
+ thresholds,
+ )
+
+ def get_pocket_domains(self, chains_dict: dict[str, Chain]) -> dict[str, str]:
+ pocket_mapping: dict[str, dict[str, int]] = defaultdict(
+ lambda: defaultdict(int)
+ )
+ for (
+ neighboring_chain,
+ neighboring_residues_list,
+ ) in self.pocket_residues.items():
+ neighboring_chain = neighboring_chain.split(".", maxsplit=1)[-1]
+ neighboring_residues_set = {int(i) for i in neighboring_residues_list}
+ for mapping_name in chains_dict[neighboring_chain].mappings:
+ if mapping_name == "BIRD":
+ continue
+ for domain in chains_dict[neighboring_chain].mappings[mapping_name]:
+ unrolled_v = {
+ tuple(range(*[remove_alphabets(j) for j in i]))
+ for i in chains_dict[neighboring_chain].mappings[mapping_name][
+ domain
+ ]
+ if i is not None
+ }
+ unrolled_v_2 = {j for i in unrolled_v for j in i}
+ intersection = neighboring_residues_set.intersection(unrolled_v_2)
+ if len(intersection) > 0:
+ pocket_mapping[mapping_name][domain] += len(intersection)
+ result = {}
+ for k, values in pocket_mapping.items():
+ result[k] = sorted(values.items(), key=lambda x: x[1], reverse=True)[0][0]
+ return result
+
+
+class Entry(DocBaseModel):
+ _ligand_contacts_requested: bool = PrivateAttr(default=False)
+ _protein_contacts_requested: bool = PrivateAttr(default=False)
+ # SUBJECT OF INVESTIGATION comp_ids; None when the category is absent
+ _subject_of_investigation_comp_ids: frozenset[str] | None = PrivateAttr(
+ default=None
+ )
+ # asym -> pdbx_unobs_or_zero_occ_atoms rows; None when the category is absent
+ _unobserved_atom_records: dict[str, list[UnobservedAtom]] | None = PrivateAttr(
+ default=None
+ )
+
+ pdb_id: str = Field(
+ default_factory=str,
+ description="RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html",
+ )
+ release_date: str = Field(
+ default_factory=str,
+ description="RCSB structure release date. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_database_PDB_rev.date_original.html",
+ )
+ oligomeric_state: str | None = Field(
+ default_factory=str,
+ description="Author's provided description of quaternary structure in RCSB. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_pdbx_struct_assembly.oligomeric_details.html",
+ )
+ determination_method: str | None = Field(
+ default_factory=str,
+ description="RCSB method of structure determination. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_exptl.method.html",
+ )
+ keywords: str | None = Field(
+ default_factory=str,
+ description="RCSB keywords describing the structure. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_struct_keywords.pdbx_keywords.html",
+ )
+ pH: str | None = Field(
+ default_factory=str,
+ description="pH at which structure is solved. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_exptl_crystal_grow.pH.html",
+ )
+ pH_min: float | None = Field(
+ default=None,
+ description="Lowest crystallization pH parsed from _exptl_crystal_grow (pH, pdbx_pH_range, or pdbx_details); null when none parses",
+ )
+ pH_max: float | None = Field(
+ default=None,
+ description="Highest crystallization pH parsed from _exptl_crystal_grow (pH, pdbx_pH_range, or pdbx_details); null when none parses",
+ )
+ resolution: float | None = Field(
+ default_factory=float,
+ description="RCSB structure resolution. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_refine.ls_d_res_high.html",
+ )
+ has_ligand_of_interest: bool | None = Field(
+ default=None,
+ description="Depositor flag _pdbx_entry_details.has_ligand_of_interest (Y true, N false); null when absent, i.e. for most entries deposited before ~2019",
+ )
+ source_taxonomy_ids: list[int] = Field(
+ default_factory=list,
+ description="Distinct NCBI taxonomy IDs of the deposited entities' source organisms",
+ )
+ source_organism_names: list[str] = Field(
+ default_factory=list,
+ description="Distinct scientific names of the deposited entities' source organisms",
+ )
+ host_taxonomy_ids: list[int] = Field(
+ default_factory=list,
+ description="Distinct NCBI taxonomy IDs of recombinant expression hosts",
+ )
+ host_organism_names: list[str] = Field(
+ default_factory=list,
+ description="Distinct scientific names of recombinant expression hosts",
+ )
+ chains: dict[str, Chain] = Field(
+ default_factory=dict,
+ description="[EXCLUDE] Chains dictionary with chain name mapped to chain object",
+ )
+ ligand_like_chains: dict[str, str] = Field(
+ default_factory=dict,
+ description="[EXCLUDE] Chain: chain type for other ligand-like chains in the entry",
+ )
+ systems: dict[str, System] = Field(
+ default_factory=dict,
+ description="[EXCLUDE] System dictionary with system id mapped to system object",
+ )
+ interfaces: list[ProteinInterface] = Field(
+ default_factory=list,
+ description="[EXCLUDE] Protein-chain interfaces across deposited assemblies",
+ )
+ covalent_bonds: dict[str, list[tuple[str, str]]] = Field(
+ default_factory=dict,
+ description="[EXCLUDE] All covalent interactions in the entry as defined by mmcif annotations. They types are separated by dictionary key and they include: "
+ + "covale: actual covalent linkage, metalc: other dative bond interactions like metal-ligand dative bond, "
+ + "hydrog: strong hydrogen bonding of nucleic acid. For the purpose of covalent annotations, we use only covale for downstream processing.",
+ )
+ chain_to_seqres_noncanonical: dict[str, str] = Field(
+ default_factory=dict,
+ description="[EXCLUDE] entity_poly.pdbx_seq_one_letter_code per asym; modified residues as (CCD)",
+ )
+ chain_to_seqres: dict[str, str] = Field(
+ default_factory=dict,
+ description="[EXCLUDE] Chain to sequence mapping",
+ )
+ validation: EntryValidation | None = Field(
+ default=None, description="[EXCLUDE] Entry validation"
+ )
+ pass_criteria: bool | None = Field(
+ default=None, description="Whether the entry passes validation criteria"
+ )
+ water_chains: list[str] = Field(
+ default_factory=list, description="[EXCLUDE] Water chains in the entry"
+ )
+ biounit_chain_ids: dict[str, list[str]] = Field(
+ default_factory=dict,
+ description="[EXCLUDE] Resolved biological-assembly chain instances by assembly ID",
+ )
+ biounit_legacy_chain_ids: dict[str, dict[str, str]] = Field(
+ default_factory=dict,
+ description="[EXCLUDE] Canonical-to-historical chain instance IDs by assembly ID",
+ )
+ biounit_ligand_contact_counts: dict[str, dict[str, dict[str, int]]] = Field(
+ default_factory=dict,
+ description=(
+ "[EXCLUDE] Counts of ion, artifact, and other ligand chains near "
+ "each biological-assembly receptor chain instance"
+ ),
+ )
+ biounit_protein_contact_counts: dict[str, dict[str, int]] = Field(
+ default_factory=dict,
+ description=(
+ "[EXCLUDE] Number of other polypeptide chain instances contacting "
+ "each chain in a biological assembly"
+ ),
+ )
+ failed_assembly_ids: list[str] = Field(
+ default_factory=list,
+ description="Biological-assembly IDs that could not be built; their "
+ "systems and interfaces are absent from this entry",
+ )
+ failed_contact_area_biounit_ids: list[str] = Field(
+ default_factory=list,
+ description="[EXCLUDE] Biological-assembly IDs whose Voronota-LT tessellation "
+ "was skipped (too many atoms) or failed; their ligand and interface contact "
+ "areas are null.",
+ )
+ symmetry_mate_contacts: SymmetryMateContacts = Field(
+ default_factory=dict,
+ description="[EXCLUDE] Symmetry mate contacts in the entry",
+ )
+
+ def prune(
+ self,
+ *,
+ clear_non_pocket_residues: bool = True,
+ load_for_scoring: bool = True,
+ max_protein_chains: int = 5,
+ max_ligand_chains: int = 5,
+ ) -> Entry:
+ """
+ Update an entry in place to reduce memory footprint and discard
+ unuseful systems for downstream processing.
+
+ Parameters
+ ----------
+ clear_non_pocket_residues : bool, default=True
+ remove residues not present in pockets
+ load_for_scoring : bool, default=True
+ remove systems that are not holo or have too many protein/ligand chains
+ max_protein_chains : int, default=5
+ only keep systems with leq max_protein_chains
+ max_ligand_chains : int, default=5
+ only keep systems with leq max_ligand_chains
+
+ Returns
+ -------
+ self : Entry
+ the updated entry
+ """
+ if clear_non_pocket_residues:
+ self.clear_non_pocket_residues()
+ if load_for_scoring:
+ n_before = len(self.systems)
+ self.systems = {
+ s.id: s
+ for s in self.systems.values()
+ if s.system_type == "holo"
+ and len(s.protein_chains_asym_id) <= max_protein_chains
+ and len(s.ligand_chains) <= max_ligand_chains
+ }
+ n_dropped = n_before - len(self.systems)
+ if n_dropped:
+ LOG.info(
+ f"{self.pdb_id}: prune(load_for_scoring) dropped {n_dropped} "
+ f"of {n_before} systems (non-holo or exceeding "
+ f"{max_protein_chains} protein / {max_ligand_chains} ligand "
+ "chains)"
+ )
+ return self
+
+ def _populate_chains(
+ self,
+ atoms: struc.AtomArray,
+ block: pdbx.CIFBlock,
+ ) -> None:
+ """Set entry.chains and entry.water_chains from biotite data."""
+ chain_starts = struc.get_chain_starts(atoms, add_exclusive_stop=True)
+ chain_segments: dict[str, list[tuple[int, int]]] = defaultdict(list)
+ for start, stop in zip(chain_starts[:-1], chain_starts[1:]):
+ chain_segments[str(atoms.chain_id[start])].append((int(start), int(stop)))
+ solvent_mask = struc.filter_solvent(atoms)
+ water_chains = {
+ chain_id
+ for chain_id, segments in chain_segments.items()
+ if all(bool(solvent_mask[start:stop].all()) for start, stop in segments)
+ }
+ entity_by_asym: dict[str, str] = {}
+ if "struct_asym" in block:
+ struct_asym = block["struct_asym"]
+ entity_by_asym = {
+ str(asym_id): str(entity_id)
+ for asym_id, entity_id in zip(
+ struct_asym["id"].as_array(),
+ struct_asym["entity_id"].as_array(),
+ )
+ }
+ type_by_entity: dict[str, str] = {}
+ if "entity" in block:
+ entity = block["entity"]
+ type_by_entity.update(
+ {
+ str(entity_id): str(entity_type)
+ for entity_id, entity_type in zip(
+ entity["id"].as_array(), entity["type"].as_array()
+ )
+ }
+ )
+ if "entity_poly" in block:
+ entity_poly = block["entity_poly"]
+ type_by_entity.update(
+ {
+ str(entity_id): str(entity_type)
+ for entity_id, entity_type in zip(
+ entity_poly["entity_id"].as_array(),
+ entity_poly["type"].as_array(),
+ )
+ }
+ )
+ auth_id_by_asym, residue_author_ids_by_asym = get_atom_site_author_ids(block)
+ modified_residues_by_asym = get_modified_residues(
+ block, residue_author_ids_by_asym
+ )
+ unobserved = get_unobserved_atoms(block)
+ self._unobserved_atom_records = None if unobserved is None else unobserved[1]
+ self.chains = {}
+ # Chain metadata does not use bonds. Temporarily detaching the global
+ # BondList prevents every small chain slice from scanning and
+ # reindexing the full entry bond graph.
+ bonds = atoms.bonds
+ atoms.bonds = None
+ try:
+ for chain_id in sorted(set(chain_segments) - water_chains):
+ segments = chain_segments[chain_id]
+ if len(segments) == 1:
+ start, stop = segments[0]
+ chain_atoms = atoms[start:stop]
+ else:
+ chain_atoms = struc.concatenate(
+ [atoms[start:stop] for start, stop in segments]
+ )
+ entity_id = entity_by_asym.get(chain_id, "")
+ chain_type = type_by_entity.get(entity_id, "unknown")
+ if chain_type == "unknown":
+ chain_type = _chain_type_from_coordinates(chain_atoms)
+ if chain_id not in self.chain_to_seqres and (
+ _is_polypeptide(chain_type) or _is_polynucleotide(chain_type)
+ ):
+ sequence = _sequence_from_coordinates(chain_atoms)
+ if sequence:
+ self.chain_to_seqres[chain_id] = sequence
+ self.chains[chain_id] = Chain.from_cif_data(
+ chain_id,
+ block,
+ chain_atoms,
+ len(self.chain_to_seqres.get(chain_id, "")),
+ entity_id=entity_id,
+ auth_id=auth_id_by_asym.get(chain_id),
+ chain_type_str=chain_type,
+ residue_author_ids=residue_author_ids_by_asym.get(chain_id, {}),
+ modified_residues=modified_residues_by_asym.get(chain_id),
+ unresolved_atoms=(
+ None if unobserved is None else unobserved[0].get(chain_id, {})
+ ),
+ )
+ finally:
+ atoms.bonds = bonds
+
+ self.water_chains = sorted(water_chains)
+
+ @staticmethod
+ def _clear_ligand_files(save_folder: Path | None, pdb_id: str) -> None:
+ """Remove ligand SDFs left by a prior annotation of this entry.
+
+ Re-ingest must never merge newly retained ligands with SDFs left in
+ ``//ligand_files`` by an earlier run; clear the
+ directory up front so even an early no-system return leaves it empty.
+ """
+ if save_folder is None:
+ return
+ ligand_dir = Path(save_folder) / pdb_id / "ligand_files"
+ if ligand_dir.exists():
+ shutil.rmtree(ligand_dir)
+
+ @staticmethod
+ def _load_clean_atoms(
+ cif_file_obj: pdbx.CIFFile,
+ *,
+ source: str,
+ no_bonds_error: str,
+ multimodel_note: str = "",
+ require_bonds: bool = True,
+ ) -> struc.AtomArray:
+ """Parse model 1 as a bond-clean, heavy-atom ``AtomArray``.
+
+ Shared by both ingest paths so their structure loading and bond
+ handling cannot drift apart. Loads model 1 with altlocs and
+ ``include_bonds=True``, drops hydrogens, and prunes non-physical
+ bonds.
+
+ Parameters
+ ----------
+ cif_file_obj : pdbx.CIFFile
+ Parsed CIF (already bond-enriched for custom structures).
+ source : str
+ Structure label for the multi-model warning, e.g.
+ ``"PDB '1abc'"`` or ``"Custom CIF"``.
+ no_bonds_error : str
+ Message for the ``ValueError`` raised when biotite derives no
+ bonds despite ``include_bonds=True``.
+ multimodel_note : str, optional
+ Extra guidance appended to the multi-model warning.
+ require_bonds : bool, optional
+ Raise when biotite derives no bonds. Ligand ingest needs the bond
+ graph; interface-only and protein-only ingest tolerate its absence.
+
+ Returns
+ -------
+ struc.AtomArray
+ Heavy atoms of model 1 with a physical bond graph.
+
+ Raises
+ ------
+ ValueError
+ If ``require_bonds`` and biotite returns no bonds (``atoms.bonds is None``).
+
+ Notes
+ -----
+ ``use_author_fields=False`` keeps ligand-chain detection keyed on
+ label_seq_id, while ``auth_seq_id`` is loaded separately so author
+ residue numbers survive into :meth:`Chain.from_cif_data`. Only
+ model 1 is used; NMR ensembles and multi-sample predictions must be
+ processed one model at a time.
+ """
+ n_models = get_model_count(cif_file_obj)
+ if n_models > 1:
+ LOG.warning(
+ f"{source} has {n_models} models โ using model 1 only.{multimodel_note}"
+ )
+ atoms = get_structure_with_altloc(
+ cif_file_obj,
+ model=1,
+ use_author_fields=False,
+ include_bonds=True,
+ extra_fields=["auth_seq_id"],
+ )
+ atoms = atoms[filter_heavy(atoms)]
+ if atoms.bonds is None and require_bonds:
+ raise ValueError(no_bonds_error)
+ remove_nonphysical_bonds(atoms)
+ return atoms
+
+ def _finalize(
+ self,
+ ligands: dict[str, Ligand],
+ atoms: struc.AtomArray,
+ *,
+ save_folder: Path | None = None,
+ min_shared_pocket_members: int = 3,
+ cif_file_obj: pdbx.CIFFile | None = None,
+ symmetry_mate_contact_threshold: float = 5.0,
+ include_ligands: bool = True,
+ ) -> None:
+ """Set systems, label crystal contacts and chains, and save ligand SDFs.
+
+ The shared tail of both ingest paths.
+
+ Parameters
+ ----------
+ ligands : dict[str, Ligand]
+ Candidate ligands collected across all biounits.
+ atoms : struc.AtomArray
+ Heavy-atom model used to write the ligand SDFs.
+ save_folder : Path | None, optional
+ Root for canonical ASU ligand SDFs; ``None`` skips saving.
+ cif_file_obj : pdbx.CIFFile | None, optional
+ Parsed CIF used for crystal-contact detection; ``None`` skips it.
+ symmetry_mate_contact_threshold : float, optional
+ Distance (ร ) for symmetry-mate contacts.
+ include_ligands : bool, optional
+ Build ligand systems and write their SDFs. Interface-only and
+ protein-only ingest skip both but still label the chains.
+
+ Notes
+ -----
+ Crystal contacts are computed only when ``cif_file_obj`` is given
+ (deposited structures with crystallographic symmetry) and only for
+ ligands that ended up in a system; custom/predicted CIFs pass
+ ``None`` to skip that step. One SDF is written per retained ligand,
+ keyed by its primary asym and spanning every member chain, so
+ covalently-linked ligand chains are saved as a single molecule.
+ """
+ if include_ligands:
+ self.set_systems(
+ ligands, min_shared_pocket_members=min_shared_pocket_members
+ )
+ if self.systems and cif_file_obj is not None:
+ self.symmetry_mate_contacts = get_symmetry_mate_contacts(
+ cif_file_obj,
+ symmetry_mate_contact_threshold,
+ )
+ if self.symmetry_mate_contacts:
+ for system in self.systems.values():
+ for ligand in system.ligands:
+ ligand.label_crystal_contacts(self.symmetry_mate_contacts)
+ self.label_chains()
+ retained_ligand_chain_groups = {
+ ligand.asym_id: ligand.member_asym_ids
+ for system in self.systems.values()
+ for ligand in system.ligands
+ }
+ if include_ligands and save_folder is not None and retained_ligand_chain_groups:
+ save_ligands(
+ atoms,
+ retained_ligand_chain_groups,
+ save_folder / self.pdb_id / "ligand_files",
+ )
+
+ def _collect_ligands_from_biounit(
+ self,
+ biounit: struc.AtomArray,
+ biounit_id: str,
+ interaction_search_threshold: float,
+ neighboring_residue_threshold: float,
+ neighboring_ligand_threshold: float,
+ data_dir: Path | None,
+ ligand_smiles_dict: dict[str, str] | None = None,
+ ligand_ccd_code_dict: dict[str, str] | None = None,
+ ligand_asym_ids: set[str] | None = None,
+ ligand_instance_chains: set[str] | None = None,
+ water_chains: set[str] | None = None,
+ spatial_index: BiounitSpatialIndex | None = None,
+ chain_pair_contact_areas: ty.Mapping[tuple[str, str], float] | None = None,
+ ) -> dict[str, "Ligand"]:
+ """Create Ligand objects for every ligand chain in a single biounit.
+
+ ``ligand_smiles_dict`` is passed through to :meth:`Ligand.from_pli`
+ and is only set by :meth:`Entry.from_custom_cif_file` โ it lets
+ user-supplied SMILES act as the CCD fallback for stereo
+ validation and SMILES assignment on custom residues.
+
+ ``ligand_ccd_code_dict`` records explicit custom-component to CCD
+ references so the output ligand annotation reports the supplied code.
+
+ ``ligand_asym_ids`` optionally limits work to selected ligand chains.
+ PDB ingest uses this to probe non-ion ligands before calculating
+ contacts for potentially thousands of monoatomic ions.
+
+ ``ligand_instance_chains`` optionally selects exact biological-
+ assembly copies, rather than every copy of an asymmetric-unit chain.
+
+ ``water_chains`` may be precomputed once per biological assembly and
+ shared across calls that process different ligand subsets.
+
+ ``spatial_index`` shares the assembly CellList and atom hierarchy
+ across every ligand and across the non-ion/ion passes.
+
+ ``chain_pair_contact_areas`` are the assembly-wide Voronota-LT chain
+ pair areas; ``None`` leaves every ligand's contact area unset.
+ """
+ ligands: dict[str, Ligand] = {}
+ if spatial_index is None:
+ spatial_index = BiounitSpatialIndex.from_atoms(
+ biounit,
+ max(
+ interaction_search_threshold,
+ neighboring_residue_threshold,
+ neighboring_ligand_threshold,
+ ),
+ )
+ # Find ligand chains: chain_id format is "{instance}.{asym_id}"
+ biounit_ligand_chains = [
+ c
+ for c in spatial_index.chain_ids
+ if "." in c
+ and c.split(".", maxsplit=1)[1] in self.ligand_like_chains
+ and (
+ ligand_asym_ids is None
+ or c.split(".", maxsplit=1)[1] in ligand_asym_ids
+ )
+ and (ligand_instance_chains is None or c in ligand_instance_chains)
+ ]
+ if not biounit_ligand_chains:
+ return ligands
+ if water_chains is None:
+ water_chains = get_water_chain_ids(biounit)
+ # Covalently-linked ligand chains are one molecule (e.g. a macrocycle
+ # whose non-polymer parts are deposited as separate chains) and are
+ # built as a single ligand spanning all member chains.
+ ligand_groups = self._covalent_ligand_groups(biounit_ligand_chains)
+ group_count = len(ligand_groups)
+ if group_count >= 100:
+ LOG.info(
+ "PDB %s assembly %s: processing %d ligand groups",
+ self.pdb_id,
+ biounit_id,
+ group_count,
+ )
+ for ligand_index, group in enumerate(ligand_groups, start=1):
+ if group_count >= 100 and ligand_index % 100 == 0:
+ LOG.info(
+ "PDB %s assembly %s: processed %d/%d ligand groups",
+ self.pdb_id,
+ biounit_id,
+ ligand_index,
+ group_count,
+ )
+ # Residue numbers per member instance-chain in the group.
+ member_residue_numbers: dict[str, list[int]] = {}
+ for member_chain in sorted(group):
+ member_atoms = spatial_index.take_atoms(
+ biounit,
+ spatial_index.atom_indices_for_chain(member_chain),
+ include_bonds=False,
+ )
+ member_residue_numbers[member_chain] = list(
+ dict.fromkeys(int(r) for r in member_atoms.res_id)
+ )
+ # Primary chain (deterministic): the first sorted member. The
+ # ligand is keyed on it, but its atoms span every member chain.
+ primary_chain = sorted(group)[0]
+ primary_instance, primary_asym_id = primary_chain.split(".", maxsplit=1)
+ ligand = Ligand.from_pli(
+ pdb_id=self.pdb_id,
+ biounit_id=biounit_id,
+ biounit=biounit,
+ ligand_instance=int(primary_instance),
+ ligand_chain=self.chains[primary_asym_id],
+ residue_numbers=member_residue_numbers[primary_chain],
+ ligand_like_chains=self.ligand_like_chains,
+ all_covalent_dict=self.covalent_bonds,
+ interaction_search_threshold=interaction_search_threshold,
+ neighboring_residue_threshold=neighboring_residue_threshold,
+ neighboring_ligand_threshold=neighboring_ligand_threshold,
+ data_dir=data_dir,
+ chain_to_seqres=self.chain_to_seqres,
+ ligand_smiles_dict=ligand_smiles_dict,
+ ligand_ccd_code_dict=ligand_ccd_code_dict,
+ water_chains=water_chains,
+ spatial_index=spatial_index,
+ member_residue_numbers=member_residue_numbers,
+ chain_pair_contact_areas=chain_pair_contact_areas,
+ subject_of_investigation_comp_ids=(
+ self._subject_of_investigation_comp_ids
+ ),
+ unobserved_atoms=self._unobserved_atom_records,
+ )
+ if ligand is not None:
+ ligands[ligand.id] = ligand
+ return ligands
+
+ def _covalent_ligand_groups(
+ self, biounit_ligand_chains: list[str]
+ ) -> list[set[str]]:
+ """Group ligand instance-chains linked by covalent bonds.
+
+ Two ligand chains join the same group when a ``covale`` bond in
+ ``self.covalent_bonds`` connects their asym ids within the same
+ biounit instance. Covalently-linked ligand chains are the same
+ physical molecule and must be reported as one ligand rather than
+ several. Chains with no ligand-ligand covalent partner form
+ singleton groups (the previous one-ligand-per-chain behaviour).
+ """
+ covale_edges: set[frozenset[str]] = set()
+ for link1, link2 in self.covalent_bonds.get("covale", []):
+ asym1, asym2 = link1.split(":")[2], link2.split(":")[2]
+ if asym1 != asym2:
+ covale_edges.add(frozenset((asym1, asym2)))
+
+ parent = {chain: chain for chain in biounit_ligand_chains}
+
+ def find(node: str) -> str:
+ while parent[node] != node:
+ parent[node] = parent[parent[node]]
+ node = parent[node]
+ return node
+
+ def union(a: str, b: str) -> None:
+ parent[find(a)] = find(b)
+
+ # Only union chains that share an instance: biological-assembly
+ # copies reuse asym labels but are physically independent.
+ by_instance: dict[str, dict[str, str]] = defaultdict(dict)
+ for chain in biounit_ligand_chains:
+ instance, asym = chain.split(".", maxsplit=1)
+ by_instance[instance][asym] = chain
+ for asym_to_chain in by_instance.values():
+ for edge in covale_edges:
+ asym1, asym2 = tuple(edge)
+ if asym1 in asym_to_chain and asym2 in asym_to_chain:
+ union(asym_to_chain[asym1], asym_to_chain[asym2])
+
+ groups: dict[str, set[str]] = defaultdict(set)
+ for chain in biounit_ligand_chains:
+ groups[find(chain)].add(chain)
+ return sorted(groups.values(), key=lambda g: sorted(g))
+
+ @staticmethod
+ def _ligand_pocket_members(ligand: Ligand) -> set[str]:
+ """Return the exact members used to connect a non-artifact ligand."""
+ members = {
+ f"res:{chain}:{residue}"
+ for chain, residues in ligand.neighboring_residues.items()
+ for residue in residues
+ }
+ members.update(
+ f"lig:{chain}"
+ for chain in ligand.neighboring_ligands + ligand.interacting_ligands
+ )
+ return members
+
+ def _upper_pocket_members(
+ self,
+ biounit: struc.AtomArray,
+ spatial_index: BiounitSpatialIndex,
+ instance_chain: str,
+ *,
+ neighboring_residue_threshold: float,
+ interaction_search_threshold: float,
+ ) -> set[str]:
+ """Cheap superset of the pocket members for one deferred ligand.
+
+ Every actual receptor neighbor is included at the normal pocket
+ radius. Every ligand-like chain within the interaction search radius
+ is included as a possible ligand interaction. The result may retain
+ extra deferred ligands, but cannot discard an edge later created by
+ :meth:`set_systems`.
+ """
+ chain_indices = spatial_index.atom_indices_for_chain(instance_chain)
+ if chain_indices.size == 0:
+ return set()
+ coordinates = biounit.coord[chain_indices]
+ receptor_asym_ids = {
+ asym_id
+ for asym_id, chain in self.chains.items()
+ if asym_id not in self.ligand_like_chains
+ and (
+ _is_polypeptide(chain.chain_type_str)
+ or _is_polynucleotide(chain.chain_type_str)
+ )
+ }
+ members: set[str] = set()
+ neighbor_indices = spatial_index.atom_indices_near(
+ coordinates, neighboring_residue_threshold
+ )
+ for index in neighbor_indices:
+ chain = str(biounit.chain_id[index])
+ asym_id = chain.split(".", maxsplit=1)[-1]
+ if asym_id in receptor_asym_ids:
+ members.add(f"res:{chain}:{int(biounit.res_id[index])}")
+
+ possible_interactions = spatial_index.atom_indices_near(
+ coordinates, interaction_search_threshold
+ )
+ for chain in np.unique(biounit.chain_id[possible_interactions]):
+ chain = str(chain)
+ if chain == instance_chain or "." not in chain:
+ continue
+ if chain.split(".", maxsplit=1)[1] in self.ligand_like_chains:
+ members.add(f"lig:{chain}")
+ return members
+
+ def _connected_deferred_ligand_chains(
+ self,
+ biounit: struc.AtomArray,
+ spatial_index: BiounitSpatialIndex,
+ primary_ligands: ty.Iterable[Ligand],
+ deferred_instance_chains: set[str],
+ *,
+ min_shared_pocket_members: int,
+ neighboring_residue_threshold: float,
+ interaction_search_threshold: float,
+ ) -> set[str]:
+ """Keep deferred non-artifacts that may connect to a primary ligand."""
+ import networkit as nk
+
+ if not deferred_instance_chains:
+ return set()
+ if min_shared_pocket_members <= 0:
+ return deferred_instance_chains
+
+ primary_members = {
+ ligand.instance_chain: self._ligand_pocket_members(ligand)
+ for ligand in primary_ligands
+ if not ligand.is_artifact
+ }
+ if not primary_members:
+ return set()
+ pocket_members = dict(primary_members)
+ for chain in deferred_instance_chains:
+ pocket_members[chain] = self._upper_pocket_members(
+ biounit,
+ spatial_index,
+ chain,
+ neighboring_residue_threshold=neighboring_residue_threshold,
+ interaction_search_threshold=interaction_search_threshold,
+ )
+
+ chain_ids = list(pocket_members)
+ graph = nk.Graph(len(chain_ids))
+ member_chains: dict[str, list[int]] = defaultdict(list)
+ for chain_index, members in enumerate(pocket_members.values()):
+ for member in members:
+ member_chains[member].append(chain_index)
+ shared_counts: dict[tuple[int, int], int] = defaultdict(int)
+ for member_indices in member_chains.values():
+ for left, right in combinations(member_indices, 2):
+ pair = (min(left, right), max(left, right))
+ shared_counts[pair] += 1
+ if shared_counts[pair] == min_shared_pocket_members:
+ graph.addEdge(*pair)
+
+ primary_chains = set(primary_members)
+ retained: set[str] = set()
+ components = nk.components.ConnectedComponents(graph).run().getComponents()
+ for component in components:
+ component_chains = {chain_ids[index] for index in component}
+ if component_chains & primary_chains:
+ retained.update(component_chains & deferred_instance_chains)
+ return retained
+
+ def _record_biounit_ligand_contact_counts(
+ self,
+ biounit: struc.AtomArray,
+ biounit_id: str,
+ spatial_index: BiounitSpatialIndex,
+ *,
+ monoatomic_ion_asym_ids: set[str],
+ known_artifact_asym_ids: set[str],
+ contact_threshold: float,
+ ) -> None:
+ """Count every ligand-like chain contacting each receptor instance."""
+ self._ligand_contacts_requested = True
+ receptor_asym_ids = {
+ asym_id
+ for asym_id, chain in self.chains.items()
+ if asym_id not in self.ligand_like_chains
+ and (
+ _is_polypeptide(chain.chain_type_str)
+ or _is_polynucleotide(chain.chain_type_str)
+ )
+ }
+ counts: dict[str, Counter[str]] = defaultdict(Counter)
+ for ligand_instance in spatial_index.chain_ids:
+ if "." not in ligand_instance:
+ continue
+ ligand_asym_id = ligand_instance.split(".", maxsplit=1)[1]
+ if ligand_asym_id not in self.ligand_like_chains:
+ continue
+ ligand_indices = spatial_index.atom_indices_for_chain(ligand_instance)
+ if ligand_indices.size == 0:
+ continue
+ nearby = spatial_index.atom_indices_near(
+ biounit.coord[ligand_indices], contact_threshold
+ )
+ receptor_instances = {
+ str(chain_instance)
+ for chain_instance in np.unique(biounit.chain_id[nearby])
+ if "." in str(chain_instance)
+ and str(chain_instance).split(".", maxsplit=1)[1] in receptor_asym_ids
+ }
+ if ligand_asym_id in monoatomic_ion_asym_ids:
+ contact_type = "ions"
+ elif ligand_asym_id in known_artifact_asym_ids:
+ contact_type = "artifacts"
+ else:
+ contact_type = "other_ligands"
+ for receptor_instance in receptor_instances:
+ counts[receptor_instance][contact_type] += 1
+ self.biounit_ligand_contact_counts[str(biounit_id)] = {
+ chain_instance: {
+ "ions": int(chain_counts["ions"]),
+ "artifacts": int(chain_counts["artifacts"]),
+ "other_ligands": int(chain_counts["other_ligands"]),
+ }
+ for chain_instance, chain_counts in counts.items()
+ }
+
+ def _record_biounit_protein_contact_counts(
+ self,
+ biounit_id: str,
+ contacts: ProteinChainContacts,
+ ) -> None:
+ """Count distinct polypeptide partners for each assembly-chain instance."""
+ self._protein_contacts_requested = True
+ counts: Counter[str] = Counter()
+ for chain_1, chain_2 in contacts:
+ counts[chain_1] += 1
+ counts[chain_2] += 1
+ self.biounit_protein_contact_counts[str(biounit_id)] = dict(counts)
+
+ @classmethod
+ def _from_cif_block(cls, cif_data: pdbx.CIFBlock, *, pdb_id: str) -> Entry:
+ """Create an entry carrying the block's deposition metadata.
+
+ Every extractor tolerates absent categories, so predicted or otherwise
+ minimal custom mmCIFs simply leave the corresponding fields unset.
+ """
+ from plinder.data.annotations.cif_utils import _cif_scalar
+
+ entry_info = get_entry_info(cif_data)
+ entry_taxonomy = get_entry_taxonomy(cif_data)
+ release_date = _cif_scalar(
+ cif_data, "pdbx_audit_revision_history", "revision_date"
+ )
+ resolution = entry_info.get("entry_resolution")
+ r = None
+ if resolution is not None:
+ try:
+ r = float(resolution)
+ except ValueError:
+ r = None
+
+ entry = cls(
+ pdb_id=pdb_id,
+ release_date=release_date or "",
+ oligomeric_state=str(entry_info.get("entry_oligomeric_state"))
+ if entry_info.get("entry_oligomeric_state") is not None
+ else None,
+ determination_method=str(entry_info.get("entry_determination_method"))
+ if entry_info.get("entry_determination_method") is not None
+ else None,
+ keywords=str(entry_info.get("entry_keywords"))
+ if entry_info.get("entry_keywords", None) is not None
+ else None,
+ pH=str(entry_info.get("entry_pH"))
+ if entry_info.get("entry_pH") is not None
+ else None,
+ resolution=r,
+ **entry_taxonomy,
+ )
+ entry.pH_min, entry.pH_max = get_entry_ph_range(cif_data)
+ has_ligand_of_interest, subject_comp_ids = get_ligand_of_interest(cif_data)
+ entry.has_ligand_of_interest = has_ligand_of_interest
+ entry._subject_of_investigation_comp_ids = subject_comp_ids
+ entry.covalent_bonds = get_covalent_connections(cif_data)
+ entry.chain_to_seqres = get_label_asym_sequences(cif_data)
+ entry.chain_to_seqres_noncanonical = get_label_asym_sequences(
+ cif_data, column="pdbx_seq_one_letter_code"
+ )
+ return entry
+
+ def _attach_chains(
+ self,
+ atoms: struc.AtomArray,
+ cif_data: pdbx.CIFBlock,
+ *,
+ min_polymer_size: int,
+ data_dir: Path | None,
+ include_ligands: bool,
+ include_interfaces: bool,
+ ) -> _LigandChainClasses:
+ """Populate chains and mappings, then classify the ligand-like chains.
+
+ Returns the ion / known-artifact / primary split that every biounit
+ pass uses to defer cheap-to-miss ligands until a proper primary ligand
+ connects to them. Artifact detection needs ``data_dir``; without it
+ no chain is treated as a known artifact.
+ """
+ self._populate_chains(atoms, cif_data)
+ per_chain = get_chain_external_mappings(cif_data)
+ for chain in per_chain:
+ # External databases may annotate an asym ID that is absent from
+ # the parsed model (for example, a chain omitted from model 1).
+ # Such mappings cannot be attached to an Entry chain.
+ if chain in self.chains:
+ self.chains[chain].mappings = per_chain[chain]
+ self.ligand_like_chains = detect_ligand_chains(self, min_polymer_size)
+ if not include_ligands or not self.ligand_like_chains:
+ return _LigandChainClasses(set(), set(), set())
+ monoatomic_ion_mask = struc.filter_monoatomic_ions(atoms)
+ ion_only_chains = set(
+ str(chain) for chain in atoms.chain_id[monoatomic_ion_mask]
+ )
+ ion_only_chains.difference_update(
+ str(chain) for chain in atoms.chain_id[~monoatomic_ion_mask]
+ )
+ monoatomic_ion_asym_ids = set(self.ligand_like_chains) & ion_only_chains
+ known_artifact_asym_ids: set[str] = set()
+ if data_dir is not None:
+ artifact_codes = get_artifact_codes(data_dir)
+ known_artifact_asym_ids = {
+ asym_id
+ for asym_id in self.ligand_like_chains
+ if asym_id not in monoatomic_ion_asym_ids
+ and is_known_artifact_ligand(
+ (
+ residue.name
+ for residue in self.chains[asym_id].residues.values()
+ ),
+ artifact_codes,
+ )
+ }
+ primary_asym_ids = (
+ set(self.ligand_like_chains)
+ - monoatomic_ion_asym_ids
+ - known_artifact_asym_ids
+ )
+ if not primary_asym_ids and include_interfaces:
+ LOG.info(
+ "PDB %r has no primary ligand chains; processing only "
+ "protein interfaces",
+ self.pdb_id,
+ )
+ elif not primary_asym_ids:
+ LOG.info("PDB %r has no primary ligand chains", self.pdb_id)
+ if monoatomic_ion_asym_ids or known_artifact_asym_ids:
+ LOG.info(
+ "PDB %s: deferring %d ion and %d known-artifact ASU ligand chains",
+ self.pdb_id,
+ len(monoatomic_ion_asym_ids),
+ len(known_artifact_asym_ids),
+ )
+ return _LigandChainClasses(
+ monoatomic_ion_asym_ids, known_artifact_asym_ids, primary_asym_ids
+ )
+
+ def _biounit_chain_pair_contact_areas(
+ self,
+ biounit: struc.AtomArray,
+ biounit_id: str,
+ *,
+ atom_limit: int,
+ ) -> dict[tuple[str, str], float] | None:
+ """Tessellate one assembly once; ``None`` records a skipped or failed run."""
+ atom_count = int(np.count_nonzero(tessellation_atom_mask(biounit)))
+ if atom_count > atom_limit:
+ LOG.warning(
+ "PDB %s assembly %s: skipping Voronota-LT tessellation, %d heavy "
+ "non-water atoms exceed tessellation_atom_limit=%d",
+ self.pdb_id,
+ biounit_id,
+ atom_count,
+ atom_limit,
+ )
+ self.failed_contact_area_biounit_ids.append(biounit_id)
+ return None
+ try:
+ return chain_pair_contact_areas(biounit)
+ except Exception as exc:
+ LOG.error(
+ "PDB %s assembly %s: Voronota-LT tessellation failed: %s",
+ self.pdb_id,
+ biounit_id,
+ exc,
+ )
+ self.failed_contact_area_biounit_ids.append(biounit_id)
+ return None
+
+ def _annotate_biounit(
+ self,
+ biounit: struc.AtomArray,
+ biounit_id: str,
+ *,
+ ligand_classes: _LigandChainClasses,
+ include_ligands: bool,
+ include_interfaces: bool,
+ data_dir: Path | None,
+ interaction_search_threshold: float,
+ neighboring_residue_threshold: float,
+ neighboring_ligand_threshold: float,
+ min_shared_pocket_members: int,
+ interface_contact_radius: float,
+ interface_min_chain_length: int,
+ interface_min_residues: int,
+ interface_annotate_prodigy: bool,
+ tessellation_atom_limit: int,
+ ligand_smiles_dict: dict[str, str] | None = None,
+ ligand_ccd_code_dict: dict[str, str] | None = None,
+ ) -> dict[str, Ligand]:
+ """Annotate one biological assembly and return its candidate ligands.
+
+ The shared body of both ingest paths: PDB ingest calls it once per
+ deposited assembly, custom ``as_is`` ingest once for the supplied
+ coordinates. It records the instance chain IDs, the per-receptor
+ ligand contact counts, and the protein interfaces, then collects the
+ primary ligands first and only those deferred ions and known artifacts
+ that connect to a proper primary ligand. The biounit must carry a
+ ``legacy_chain_id`` annotation.
+
+ Assemblies with a retained interface or a neighboring-residue ligand
+ pocket are tessellated once with Voronota-LT. Assemblies above
+ ``tessellation_atom_limit`` heavy, non-water atoms skip it and are recorded in
+ ``failed_contact_area_biounit_ids``.
+ """
+ self.biounit_chain_ids[biounit_id] = sorted(
+ str(chain_id) for chain_id in np.unique(biounit.chain_id)
+ )
+ self.biounit_legacy_chain_ids[biounit_id] = {
+ str(chain_id): str(legacy_chain_id)
+ for chain_id, legacy_chain_id in zip(
+ biounit.chain_id, biounit.legacy_chain_id
+ )
+ }
+ if include_ligands and not self.ligand_like_chains:
+ # The contacts are known to be zero; no spatial search is needed.
+ self._ligand_contacts_requested = True
+ self.biounit_ligand_contact_counts[str(biounit_id)] = {}
+ include_ligands = False
+ spatial_radii: list[float] = []
+ if include_ligands:
+ spatial_radii.extend(
+ [
+ interaction_search_threshold,
+ neighboring_residue_threshold,
+ neighboring_ligand_threshold,
+ ]
+ )
+ if include_interfaces:
+ spatial_radii.append(interface_contact_radius)
+ spatial_index = (
+ BiounitSpatialIndex.from_atoms(biounit, max(spatial_radii))
+ if spatial_radii
+ else None
+ )
+ if include_ligands:
+ assert spatial_index is not None
+ self._record_biounit_ligand_contact_counts(
+ biounit,
+ biounit_id,
+ spatial_index,
+ monoatomic_ion_asym_ids=ligand_classes.monoatomic_ion_asym_ids,
+ known_artifact_asym_ids=ligand_classes.known_artifact_asym_ids,
+ contact_threshold=neighboring_residue_threshold,
+ )
+ interfaces: list[ProteinInterface] = []
+ if include_interfaces:
+ assert spatial_index is not None
+ protein_contacts = find_protein_chain_contacts(
+ biounit,
+ chains=self.chains,
+ contact_radius=interface_contact_radius,
+ spatial_index=spatial_index,
+ )
+ self._record_biounit_protein_contact_counts(
+ biounit_id,
+ protein_contacts,
+ )
+ interfaces = detect_protein_interfaces(
+ biounit,
+ pdb_id=self.pdb_id,
+ biounit_id=biounit_id,
+ chains=self.chains,
+ contact_radius=interface_contact_radius,
+ min_chain_length=interface_min_chain_length,
+ min_interface_residues=interface_min_residues,
+ annotate_prodigy=interface_annotate_prodigy,
+ spatial_index=spatial_index,
+ chain_contacts=protein_contacts,
+ )
+ ligands: dict[str, Ligand] = {}
+ if include_ligands and ligand_classes.primary_asym_ids:
+ assert spatial_index is not None
+ water_chains = get_water_chain_ids(biounit)
+
+ def collect(
+ *,
+ ligand_asym_ids: set[str] | None = None,
+ ligand_instance_chains: set[str] | None = None,
+ ) -> dict[str, Ligand]:
+ return self._collect_ligands_from_biounit(
+ biounit,
+ biounit_id,
+ interaction_search_threshold,
+ neighboring_residue_threshold,
+ neighboring_ligand_threshold,
+ data_dir,
+ ligand_smiles_dict=ligand_smiles_dict,
+ ligand_ccd_code_dict=ligand_ccd_code_dict,
+ water_chains=water_chains,
+ spatial_index=spatial_index,
+ ligand_asym_ids=ligand_asym_ids,
+ ligand_instance_chains=ligand_instance_chains,
+ )
+
+ primary_ligands = collect(ligand_asym_ids=ligand_classes.primary_asym_ids)
+ ligands = primary_ligands
+ proper_primary_ligands = [
+ ligand for ligand in primary_ligands.values() if ligand.is_proper
+ ]
+ if proper_primary_ligands:
+ monoatomic_ion_asym_ids = ligand_classes.monoatomic_ion_asym_ids
+ known_artifact_asym_ids = ligand_classes.known_artifact_asym_ids
+ ion_instance_chains = {
+ chain
+ for chain in spatial_index.chain_ids
+ if "." in chain
+ and chain.split(".", maxsplit=1)[1] in monoatomic_ion_asym_ids
+ }
+ retained_ion_chains = self._connected_deferred_ligand_chains(
+ biounit,
+ spatial_index,
+ proper_primary_ligands,
+ ion_instance_chains,
+ min_shared_pocket_members=min_shared_pocket_members,
+ neighboring_residue_threshold=neighboring_residue_threshold,
+ interaction_search_threshold=interaction_search_threshold,
+ )
+ ion_ligands = collect(ligand_instance_chains=retained_ion_chains)
+ non_artifact_ligands = [
+ ligand
+ for ligand in (*primary_ligands.values(), *ion_ligands.values())
+ if not ligand.is_artifact
+ ]
+ referenced_artifact_chains = {
+ chain
+ for ligand in non_artifact_ligands
+ for chain in (
+ ligand.neighboring_ligands + ligand.interacting_ligands
+ )
+ if "." in chain
+ and chain.split(".", maxsplit=1)[1] in known_artifact_asym_ids
+ }
+ # Ligand interaction detection is not guaranteed to be symmetric
+ # for short polymer ligands. Include every known artifact inside
+ # the interaction search radius; set_systems() drops false positives.
+ for ligand in non_artifact_ligands:
+ ligand_indices = spatial_index.atom_indices_for_chain(
+ ligand.instance_chain
+ )
+ nearby_indices = spatial_index.atom_indices_near(
+ biounit.coord[ligand_indices], interaction_search_threshold
+ )
+ referenced_artifact_chains.update(
+ str(chain)
+ for chain in np.unique(biounit.chain_id[nearby_indices])
+ if "." in str(chain)
+ and str(chain).split(".", maxsplit=1)[1]
+ in known_artifact_asym_ids
+ )
+ artifact_ligands = collect(
+ ligand_instance_chains=referenced_artifact_chains
+ )
+ ligands = {**primary_ligands, **ion_ligands, **artifact_ligands}
+
+ if interfaces or any(
+ ligand.neighboring_residues for ligand in ligands.values()
+ ):
+ chain_pair_areas = self._biounit_chain_pair_contact_areas(
+ biounit, biounit_id, atom_limit=tessellation_atom_limit
+ )
+ if chain_pair_areas is not None:
+ for ligand in ligands.values():
+ ligand.set_contact_areas(chain_pair_areas, self.ligand_like_chains)
+ interfaces = [
+ replace(
+ interface,
+ contact_area=float(
+ chain_pair_areas.get(
+ (interface.chain_1, interface.chain_2), 0.0
+ )
+ ),
+ )
+ for interface in interfaces
+ ]
+ self.interfaces.extend(interfaces)
+ return ligands
+
+ @classmethod
+ def from_cif_file(
+ cls,
+ cif_file: Path,
+ neighboring_residue_threshold: float = 6.0,
+ neighboring_ligand_threshold: float = 4.0,
+ min_polymer_size: int = 12,
+ data_dir: Path | None = None,
+ save_folder: Path | None = None,
+ interaction_search_threshold: float = 10.0,
+ symmetry_mate_contact_threshold: float = 5.0,
+ min_shared_pocket_members: int = 3,
+ interface_contact_radius: float = 10.0,
+ interface_min_chain_length: int = 12,
+ interface_min_residues: int = DEFAULT_MIN_INTERFACE_RESIDUES,
+ interface_annotate_prodigy: bool = True,
+ include_ligands: bool = True,
+ include_interfaces: bool = True,
+ assembly_ids: ty.Iterable[str] | None = None,
+ protein_only: bool = False,
+ tessellation_atom_limit: int = 2_000_000,
+ ) -> Entry:
+ """
+ Load an entry object from mmCIF files in the pipeline
+
+ Parameters
+ ----------
+ cif_file : Path
+ mmCIF file of interest
+ neighboring_residue_threshold : float
+ Distance from ligand for protein residues to be considered a ligand
+ neighboring_ligand_threshold : float
+ Distance from ligand for other ligands to be considered a ligand
+ min_polymer_size : int = 12
+ Minimum residue count for a polymer chain to be receptor.
+ Shorter polymers are classified as ligands. Set to 12 as
+ the minimum length for meaningful MMseqs2/Foldseek searches.
+ data_dir : Path | None
+ Optional PLINDER data root used only for reference datasets such
+ as CCD synonyms, cofactors, artifacts, and binding affinities.
+ This is independent of ``save_folder``.
+ save_folder : Path
+ Root directory for one canonical ASU ligand SDF per chain.
+ Files are written to ``//ligand_files``.
+ interaction_search_threshold : float
+ Receptor residues within this distance (ร ) of a ligand form the
+ complex handed to peppr for interaction detection. Keep it at or
+ above peppr's 8 ร contact cutoff, which plinder leaves at its
+ default; a smaller value silently truncates the contact search.
+ min_shared_pocket_members : int
+ Minimum shared pocket residues to group non-artifact ligands.
+ interface_contact_radius : float
+ Maximum backbone-atom distance defining a protein interface.
+ interface_min_chain_length : int
+ Minimum SEQRES length for an interface chain.
+ interface_min_residues : int
+ Minimum number of contacting residues required on each side.
+ interface_annotate_prodigy : bool
+ Whether to add PRODIGY-cryst contact and BIO/XTAL annotations.
+ include_ligands : bool
+ Whether to derive ligand systems and canonical ligand SDFs.
+ include_interfaces : bool
+ Whether to derive protein-protein interfaces and PRODIGY annotations.
+ assembly_ids : Iterable[str] | None
+ Optional subset of deposited biological assemblies. By default all
+ assemblies listed by the mmCIF are processed.
+ protein_only : bool
+ Permit chain and assembly extraction without ligand or interface
+ annotation. Used by receptor-only custom scoring.
+ tessellation_atom_limit : int
+ Number of heavy, non-water atoms above which an assembly skips the
+ Voronota-LT contact-area tessellation; its ligand and interface
+ contact areas are null and the assembly ID is recorded in
+ ``failed_contact_area_biounit_ids``. The limit protects memory:
+ the tessellation needs about 2.2 KB and 9 ยตs per atom, so the
+ default of 2 million atoms costs roughly 4.5 GB and 20 s.
+
+ Returns
+ -------
+ Entry
+ Entry object for the given pdbid
+ """
+ if not include_ligands and not include_interfaces and not protein_only:
+ raise ValueError("entry ingest must include ligands, interfaces, or both")
+
+ cif_file = Path(cif_file)
+ data_dir = Path(data_dir) if data_dir is not None else None
+ save_folder = Path(save_folder) if save_folder is not None else None
+
+ from plinder.data.annotations.cif_utils import (
+ _cif_scalar,
+ read_mmcif_file,
+ )
+
+ cif_file_obj = read_mmcif_file(cif_file)
+ cif_data = list(cif_file_obj.values())[0]
+ # Extract metadata from CIF block
+ pdb_id = (_cif_scalar(cif_data, "entry", "id") or "").lower()
+ if include_ligands:
+ cls._clear_ligand_files(save_folder, pdb_id)
+ entry = cls._from_cif_block(cif_data, pdb_id=pdb_id)
+ entry._ligand_contacts_requested = include_ligands
+ entry._protein_contacts_requested = include_interfaces
+ # Unliganded entries still supply apo chains and assembly membership.
+ # They do not require a ligand bond graph (e.g. CA-only proteins).
+ require_ligand_bonds = (
+ include_ligands
+ and detect_ligand_chains_from_cif(cif_data, min_polymer_size) != {}
+ )
+ atoms = cls._load_clean_atoms(
+ cif_file_obj,
+ source=f"PDB {pdb_id!r}",
+ no_bonds_error=(
+ f"{pdb_id}: biotite returned no bonds despite include_bonds=True"
+ ),
+ require_bonds=require_ligand_bonds,
+ )
+ ligand_classes = entry._attach_chains(
+ atoms,
+ cif_data,
+ min_polymer_size=min_polymer_size,
+ data_dir=data_dir,
+ include_ligands=include_ligands,
+ include_interfaces=include_interfaces,
+ )
+ ligands: dict[str, Ligand] = {}
+ selected_assemblies = _selected_assembly_ids(
+ pdbx.list_assemblies(cif_file_obj), assembly_ids
+ )
+ for assembly_id in selected_assemblies:
+ try:
+ biounit = build_biounit(cif_file_obj, assembly_id)
+ except Exception as e:
+ # Skip this assembly but record it: its systems are silently
+ # missing from the entry otherwise. Other assemblies proceed.
+ LOG.error(
+ f"Could not build assembly {assembly_id} for {entry.pdb_id!r}: {e}"
+ )
+ entry.failed_assembly_ids.append(assembly_id)
+ continue
+ ligands.update(
+ entry._annotate_biounit(
+ biounit,
+ str(assembly_id),
+ ligand_classes=ligand_classes,
+ include_ligands=include_ligands,
+ include_interfaces=include_interfaces,
+ data_dir=data_dir,
+ interaction_search_threshold=interaction_search_threshold,
+ neighboring_residue_threshold=neighboring_residue_threshold,
+ neighboring_ligand_threshold=neighboring_ligand_threshold,
+ min_shared_pocket_members=min_shared_pocket_members,
+ interface_contact_radius=interface_contact_radius,
+ interface_min_chain_length=interface_min_chain_length,
+ interface_min_residues=interface_min_residues,
+ interface_annotate_prodigy=interface_annotate_prodigy,
+ tessellation_atom_limit=tessellation_atom_limit,
+ )
+ )
+ entry._finalize(
+ ligands,
+ atoms,
+ save_folder=save_folder,
+ min_shared_pocket_members=min_shared_pocket_members,
+ cif_file_obj=cif_file_obj,
+ symmetry_mate_contact_threshold=symmetry_mate_contact_threshold,
+ include_ligands=include_ligands,
+ )
+ return entry
+
+ @classmethod
+ def from_custom_cif_file(
+ cls,
+ pdb_id: str | None,
+ cif_file: Path,
+ ligand_smiles_dict: dict[str, str] | None = None,
+ neighboring_residue_threshold: float = 6.0,
+ neighboring_ligand_threshold: float = 4.0,
+ min_polymer_size: int = 12,
+ interaction_search_threshold: float = 10.0,
+ save_folder: Path | None = None,
+ min_shared_pocket_members: int = 3,
+ save_fixed_cif: Path | None = None,
+ structure_mode: ty.Literal["as_is", "pdb"] = "as_is",
+ assembly_ids: ty.Iterable[str] | None = None,
+ symmetry_mate_contact_threshold: float = 5.0,
+ interface_contact_radius: float = 10.0,
+ interface_min_chain_length: int = 12,
+ interface_min_residues: int = DEFAULT_MIN_INTERFACE_RESIDUES,
+ interface_annotate_prodigy: bool = True,
+ include_ligands: bool = True,
+ include_interfaces: bool = True,
+ data_dir: Path | None = None,
+ ligand_ccd_code_dict: dict[str, str] | None = None,
+ tessellation_atom_limit: int = 2_000_000,
+ ) -> Entry:
+ """
+ Create an entry from an already assembled or deposited PDB mmCIF.
+
+ Parameters
+ ----------
+ pdb_id : str | None
+ Identifier used for an ``as_is`` structure. Must be ``None`` in
+ ``pdb`` mode, where the deposited ``_entry.id`` is authoritative.
+ cif_file : Path
+ mmcif files of interest
+ ligand_smiles_dict : dict[str, str] | None, optional
+ Mapping of component ID (e.g. ``LIG``) to SMILES.
+ Required for unknown ligands without ``_chem_comp_bond``
+ (typical of cofolding outputs). Known CCD compounds
+ are handled automatically.
+ ligand_ccd_code_dict : dict[str, str] | None, optional
+ Mapping of a custom component ID to the CCD component whose atom
+ names, bonds, and canonical SMILES should be used, for example
+ ``{"LIG": "ATP"}``. A component may be present in either this
+ mapping or ``ligand_smiles_dict``, but not both.
+ neighboring_residue_threshold : float, optional
+ Max distance (ร ) for neighboring receptor residues, by default 6.0
+ neighboring_ligand_threshold : float, optional
+ Max distance (ร ) for neighboring ligands, by default 4.0
+ min_polymer_size : int, optional
+ Minimum residue count for a chain to be polymer (not ligand), by default 10
+ save_folder : Path | None, optional
+ Root directory for canonical ASU ligand SDFs, by default None.
+ This path is never interpreted as a PLINDER data root.
+ data_dir : Path | None, optional
+ Optional PLINDER data root used for reference annotations. This is
+ independent of ``save_folder`` and is not inferred from it.
+ save_fixed_cif : Path | None, optional
+ If provided and the CIF needed bond-order enrichment, write
+ the enriched copy to this path. The input CIF at ``cif_file``
+ is never mutated. Raises ``FileExistsError`` if the target
+ already exists and ``ValueError`` if it resolves to the same
+ path as ``cif_file``. By default (``None``) no file is written.
+ structure_mode : {"as_is", "pdb"}
+ ``as_is`` treats model 1 as one already assembled structure without
+ symmetry expansion. ``pdb`` uses deposited biological-assembly
+ operators through the production PDB ingest path.
+ assembly_ids : Iterable[str] | None
+ Biological assemblies selected in ``pdb`` mode. By default all are
+ processed. Assembly selection is invalid in ``as_is`` mode.
+ include_ligands : bool
+ Whether to derive ligand systems and canonical ligand SDFs.
+ include_interfaces : bool
+ Whether to derive protein-protein interfaces.
+ tessellation_atom_limit : int
+ Skip the Voronota-LT tessellation above this many heavy, non-water
+ atoms (see :meth:`from_cif_file`).
+
+ Returns
+ -------
+ Entry
+ Entry object for the given pdbid
+
+ Notes
+ -----
+ ``as_is`` mode runs the same entry, chain, and per-assembly annotation
+ as :meth:`from_cif_file`, with the supplied coordinates standing in for
+ the single biological assembly ``1``: deposition metadata, covalent
+ links, external chain mappings, ion and known-artifact deferral (the
+ latter needs ``data_dir``), ligand contact counts, interfaces, and
+ ligand collection are identical. The crystal-contact labelling of
+ deposited entries is skipped.
+
+ Raises
+ ------
+ MissingBondOrderError
+ If the CIF contains unknown ligands and neither a SMILES nor CCD
+ code is provided for them.
+ FileExistsError
+ If ``save_fixed_cif`` already exists.
+ ValueError
+ If ``save_fixed_cif`` points at the input ``cif_file``;
+ if biotite returns no bonds at all (corrupted / missing
+ bond information CIF); or any error propagated from
+ :func:`~plinder.data.annotations.cif_utils.enrich_cif_with_smiles_bonds`
+ (invalid SMILES, atom-count / element-order mismatch in the
+ positional path, sanitize / template-match failure in the
+ opt-in substructure path, or multi-instance comp_id
+ divergence).
+ """
+ from plinder.data.annotations.cif_utils import (
+ MissingBondOrderError,
+ check_cif_bond_orders,
+ check_custom_mmcif_fields,
+ enrich_cif_with_ccd_bonds,
+ enrich_cif_with_smiles_bonds,
+ get_unknown_ligand_ids,
+ read_mmcif_file,
+ )
+
+ cif_file = _require_mmcif_path(cif_file)
+ data_dir = Path(data_dir) if data_dir is not None else None
+ save_folder = Path(save_folder) if save_folder is not None else None
+ ligand_ccd_code_dict = (
+ {
+ str(component_id).strip(): str(ccd_code).strip().upper()
+ for component_id, ccd_code in ligand_ccd_code_dict.items()
+ }
+ if ligand_ccd_code_dict is not None
+ else None
+ )
+ if structure_mode not in CUSTOM_STRUCTURE_MODES:
+ raise ValueError(
+ f"invalid structure_mode {structure_mode!r}; "
+ f"expected one of {CUSTOM_STRUCTURE_MODES}"
+ )
+ if not include_ligands and (
+ ligand_smiles_dict is not None or ligand_ccd_code_dict is not None
+ ):
+ raise ValueError("ligand chemistry overrides require include_ligands=True")
+ overlapping_chemistry = set(ligand_smiles_dict or {}).intersection(
+ ligand_ccd_code_dict or {}
+ )
+ if overlapping_chemistry:
+ raise ValueError(
+ "provide either SMILES or a CCD code for each ligand component, "
+ f"not both: {sorted(overlapping_chemistry)}"
+ )
+ try:
+ cif_file_obj = read_mmcif_file(cif_file)
+ cif_data = list(cif_file_obj.values())[0]
+ except (DeserializationError, IndexError, InvalidFileError, OSError) as exc:
+ raise ValueError(f"cannot parse custom mmCIF {cif_file}: {exc}") from exc
+ if structure_mode == "pdb" and pdb_id is not None:
+ raise ValueError(
+ "pdb_id must be None in pdb mode; the deposited _entry.id "
+ "is authoritative"
+ )
+ check_custom_mmcif_fields(
+ cif_data,
+ source=cif_file,
+ structure_mode=structure_mode,
+ require_label_ids=True,
+ )
+ if structure_mode == "pdb":
+ if (
+ "entry" not in cif_data
+ or "id" not in cif_data["entry"]
+ or cif_data["entry"].row_count == 0
+ ):
+ raise ValueError(f"custom mmCIF {cif_file} needs _entry.id in pdb mode")
+ if (
+ ligand_smiles_dict is not None
+ or ligand_ccd_code_dict is not None
+ or save_fixed_cif is not None
+ ):
+ raise ValueError(
+ "pdb mode uses deposited PDB chemistry and does not accept "
+ "ligand chemistry overrides or save_fixed_cif"
+ )
+ requested_assemblies = (
+ tuple(str(value) for value in assembly_ids)
+ if assembly_ids is not None and not isinstance(assembly_ids, str)
+ else assembly_ids
+ )
+ entry = cls.from_cif_file(
+ cif_file,
+ neighboring_residue_threshold=neighboring_residue_threshold,
+ neighboring_ligand_threshold=neighboring_ligand_threshold,
+ min_polymer_size=min_polymer_size,
+ data_dir=data_dir,
+ save_folder=save_folder,
+ interaction_search_threshold=interaction_search_threshold,
+ symmetry_mate_contact_threshold=symmetry_mate_contact_threshold,
+ min_shared_pocket_members=min_shared_pocket_members,
+ interface_contact_radius=interface_contact_radius,
+ interface_min_chain_length=interface_min_chain_length,
+ interface_min_residues=interface_min_residues,
+ interface_annotate_prodigy=interface_annotate_prodigy,
+ include_ligands=include_ligands,
+ include_interfaces=include_interfaces,
+ assembly_ids=requested_assemblies,
+ protein_only=not include_ligands and not include_interfaces,
+ tessellation_atom_limit=tessellation_atom_limit,
+ )
+ if not entry.biounit_chain_ids:
+ raise ValueError(
+ f"pdb mode requires deposited biological assemblies: {cif_file}"
+ )
+ if requested_assemblies is not None:
+ requested = (
+ {requested_assemblies}
+ if isinstance(requested_assemblies, str)
+ else set(requested_assemblies)
+ )
+ missing = sorted(requested.difference(entry.biounit_chain_ids))
+ if missing:
+ raise ValueError(
+ f"failed to construct requested biological assemblies: {missing}"
+ )
+ return entry
+ if pdb_id is None or not str(pdb_id).strip():
+ raise ValueError("pdb_id is required in as_is mode")
+ if assembly_ids is not None:
+ raise ValueError("assembly_ids are only valid in pdb mode")
+ pdb_id = str(pdb_id).strip().lower()
+
+ if include_ligands:
+ cls._clear_ligand_files(save_folder, pdb_id)
+
+ # Resolve explicit CCD references before checking which components still
+ # need a user-provided SMILES. Both paths write _chem_comp_bond into the
+ # in-memory copy without touching the caller's file.
+ effective_smiles = dict(ligand_smiles_dict or {})
+ enrichment_applied = False
+ if include_ligands and ligand_ccd_code_dict:
+ enrich_cif_with_ccd_bonds(
+ cif_file_obj,
+ ligand_ccd_codes=ligand_ccd_code_dict,
+ )
+ enrichment_applied = True
+
+ unknown_ids = get_unknown_ligand_ids(cif_file_obj) if include_ligands else []
+ if unknown_ids:
+ missing_chemistry = set(unknown_ids).difference(effective_smiles)
+ if missing_chemistry:
+ raise MissingBondOrderError(
+ f"CIF contains unknown ligands {sorted(missing_chemistry)} with no "
+ "_chem_comp_bond and no CCD match. "
+ "Provide a SMILES in ligand_smiles_dict or a CCD code in "
+ "ligand_ccd_code_dict to assign bond orders."
+ )
+ enrich_cif_with_smiles_bonds(
+ cif_file_obj,
+ ligand_smiles={
+ comp_id: effective_smiles[comp_id] for comp_id in unknown_ids
+ },
+ )
+ # Postcondition: enrichment must have resolved every flagged ligand.
+ # Fail early/clearly if any unknown-without-bonds remain, rather than
+ # feeding a partially-bonded CIF into structure parsing.
+ check_cif_bond_orders(cif_file_obj)
+ enrichment_applied = True
+ ligand_smiles_dict = effective_smiles or None
+
+ # Optionally persist the enriched CIF. Guard against overwriting
+ # the caller's input or an existing file.
+ if save_fixed_cif is not None and enrichment_applied:
+ save_fixed_cif = Path(save_fixed_cif)
+ if save_fixed_cif.resolve() == Path(cif_file).resolve():
+ raise ValueError(
+ "save_fixed_cif must not point at the input cif_file โ "
+ "the input file is never overwritten."
+ )
+ if save_fixed_cif.exists():
+ raise FileExistsError(
+ f"save_fixed_cif target already exists: {save_fixed_cif}"
+ )
+ cif_file_obj.write(str(save_fixed_cif))
+
+ atoms = cls._load_clean_atoms(
+ cif_file_obj,
+ source=f"Custom CIF {cif_file}",
+ no_bonds_error=(
+ f"Custom CIF {cif_file}: biotite returned no bonds at all "
+ "after enrichment โ the CIF is corrupted or missing all "
+ "bond information (_chem_comp_bond, _struct_conn, and CCD "
+ "coverage are all absent)."
+ ),
+ multimodel_note=(
+ " Call from_custom_cif_file once per model for ensemble analysis."
+ ),
+ require_bonds=include_ligands,
+ )
+ entry = cls._from_cif_block(cif_data, pdb_id=pdb_id)
+ entry._ligand_contacts_requested = include_ligands
+ entry._protein_contacts_requested = include_interfaces
+ ligand_classes = entry._attach_chains(
+ atoms,
+ cif_data,
+ min_polymer_size=min_polymer_size,
+ data_dir=data_dir,
+ include_ligands=include_ligands,
+ include_interfaces=include_interfaces,
+ )
+ # Treat model 1 as one already assembled structure: a single biological
+ # assembly "1" without symmetry expansion that keeps the supplied chain
+ # IDs, then annotate it exactly like a deposited assembly.
+ biounit = atoms.copy()
+ biounit.chain_id = np.array([f"1.{c}" for c in biounit.chain_id])
+ biounit.set_annotation("legacy_chain_id", biounit.chain_id.copy())
+ ligands = entry._annotate_biounit(
+ biounit,
+ "1",
+ ligand_classes=ligand_classes,
+ include_ligands=include_ligands,
+ include_interfaces=include_interfaces,
+ data_dir=data_dir,
+ interaction_search_threshold=interaction_search_threshold,
+ neighboring_residue_threshold=neighboring_residue_threshold,
+ neighboring_ligand_threshold=neighboring_ligand_threshold,
+ min_shared_pocket_members=min_shared_pocket_members,
+ interface_contact_radius=interface_contact_radius,
+ interface_min_chain_length=interface_min_chain_length,
+ interface_min_residues=interface_min_residues,
+ interface_annotate_prodigy=interface_annotate_prodigy,
+ tessellation_atom_limit=tessellation_atom_limit,
+ ligand_smiles_dict=ligand_smiles_dict,
+ ligand_ccd_code_dict=ligand_ccd_code_dict,
+ )
+ # Crystal contacts are skipped: as_is coordinates carry no
+ # crystallographic symmetry to expand.
+ entry._finalize(
+ ligands,
+ atoms,
+ save_folder=save_folder,
+ min_shared_pocket_members=min_shared_pocket_members,
+ include_ligands=include_ligands,
+ )
+ return entry
+
+ def set_systems(
+ self,
+ ligands: dict[str, Ligand],
+ min_shared_pocket_members: int = 3,
+ ) -> None:
+ """Group ligands into systems by shared pocket and proximity.
+
+ Non-artifact ligands (drug-like, cofactors, ions) are grouped
+ if they share at least *min_shared_pocket_members* pocket
+ members (receptor residues + neighboring ligand chains).
+ Pocket members use chain instance IDs (e.g. ``1.A``) so
+ ligands in different subunits only merge when they genuinely
+ share residues on the same chain copy. Biological assemblies
+ are always independent: their instance-chain labels share a
+ namespace but do not describe the same physical chains.
+
+ Artifacts (GOL, PEG, etc.) are only attached to a system if
+ they are within 4 ร of a non-artifact ligand.
+
+ Parameters
+ ----------
+ ligands : dict[str, Ligand]
+ All ligands in the entry keyed by ligand ID.
+ min_shared_pocket_members : int
+ Minimum shared pocket members to group non-artifact ligands.
+ """
+ import networkit as nk
+
+ ligand_ids = list(ligands.keys())
+ G = nk.Graph(len(ligand_ids))
+
+ # Step 1: group non-artifact ligands by shared pocket residues
+ pocket_members: dict[int, set[str]] = {}
+ for i, lid in enumerate(ligand_ids):
+ lig = ligands[lid]
+ if lig.is_artifact:
+ continue
+ members: set[str] = set()
+ for chain, resnums in lig.neighboring_residues.items():
+ for rn in resnums:
+ members.add(f"res:{chain}:{rn}")
+ for lc in lig.neighboring_ligands + lig.interacting_ligands:
+ members.add(f"lig:{lc}")
+ pocket_members[i] = members
+
+ groupable = list(pocket_members)
+ if min_shared_pocket_members <= 0:
+ for i, j in combinations(groupable, 2):
+ if (
+ ligands[ligand_ids[i]].biounit_id
+ == ligands[ligand_ids[j]].biounit_id
+ ):
+ G.addEdge(i, j)
+ else:
+ member_ligands: dict[str, list[int]] = defaultdict(list)
+ for ligand_index, members in pocket_members.items():
+ biounit_id = ligands[ligand_ids[ligand_index]].biounit_id
+ for member in members:
+ member_ligands[f"{biounit_id}:{member}"].append(ligand_index)
+ shared_member_counts: dict[tuple[int, int], int] = defaultdict(int)
+ for member_indices in member_ligands.values():
+ for i, j in combinations(member_indices, 2):
+ pair = (min(i, j), max(i, j))
+ shared_member_counts[pair] += 1
+ if shared_member_counts[pair] == min_shared_pocket_members:
+ G.addEdge(*pair)
+
+ # Step 2: attach artifacts within 4A of a non-artifact ligand
+ ligand_id_to_index = {ligand_id: i for i, ligand_id in enumerate(ligand_ids)}
+ for i, lid in enumerate(ligand_ids):
+ lig = ligands[lid]
+ if not lig.is_artifact:
+ continue
+ for neighbor_chain in lig.neighboring_ligands + lig.interacting_ligands:
+ neighbor_id = "__".join([self.pdb_id, lig.biounit_id, neighbor_chain])
+ j_idx = ligand_id_to_index.get(neighbor_id)
+ if j_idx is not None and not ligands[ligand_ids[j_idx]].is_artifact:
+ G.addEdge(i, j_idx)
+ cc = nk.components.ConnectedComponents(G)
+ cc.run()
+ components = cc.getComponents()
+ system_ligands: dict[int, list[Ligand]] = {}
+ for idx, component in enumerate(sorted(components, key=len, reverse=True)):
+ system_ligands[idx + 1] = []
+ for node_idx in component:
+ system_ligands[idx + 1].append(ligands[ligand_ids[node_idx]])
+ self.systems: dict[str, System] = {}
+ for ligs in system_ligands.values():
+ if not ligs:
+ continue
+ biounit_ids = {ligand.biounit_id for ligand in ligs}
+ if len(biounit_ids) != 1:
+ raise RuntimeError(
+ f"system ligands span biological assemblies: {sorted(biounit_ids)}"
+ )
+ instance_chains = [ligand.instance_chain for ligand in ligs]
+ if len(instance_chains) != len(set(instance_chains)):
+ raise RuntimeError(
+ "system contains repeated ligand instance chains: "
+ f"{instance_chains}"
+ )
+ receptor_asym_ids = sorted(
+ {
+ instance_chain.split(".", maxsplit=1)[1]
+ for ligand in ligs
+ for instance_chain in ligand.protein_chains_asym_id
+ }
+ )
+ system = System(
+ pdb_id=self.pdb_id,
+ biounit_id=next(iter(biounit_ids)),
+ ligands=sorted(ligs, key=lambda x: x.id),
+ receptor_type=get_receptor_type(
+ self.chains[asym_id].chain_type_str for asym_id in receptor_asym_ids
+ ),
+ )
+ if system.proper_ligands() and len(system.protein_chains_asym_id):
+ self.systems[system.id] = system
+
+ @cached_property
+ def author_to_asym(self) -> dict[str, str]:
+ """[EXCLUDE] Map author chain id to asym id"""
+ return {
+ c.auth_id: c.asym_id
+ for c in self.chains.values()
+ if "polypeptide" in c.chain_type_str.lower()
+ }
+
+ def chains_for_alignment(self, chain_type: str, aln_type: str) -> list[str]:
+ """
+ Get chains for foldseek/mmseqs alignment
+ Parameters
+ ----------
+ self : Entry
+ Entry object
+ chain_type : str
+ Chain type (apo/holo)
+ aln_type : str
+ Alignment type (folseek, mmses, etc)
+ Returns
+ -------
+ list[str]
+ """
+ assert chain_type in (
+ "apo",
+ "holo",
+ "pred",
+ ), "chain_type must be 'apo', 'holo', or 'pred'"
+ if chain_type == "holo":
+ receptor_asym_ids = {
+ i_c.split(".", maxsplit=1)[1]
+ for system in self.systems.values()
+ if system.system_type == "holo"
+ for i_c in system.protein_chains_asym_id
+ }
+ na_chains = sorted(
+ asym
+ for asym in receptor_asym_ids
+ if _is_polynucleotide(self.chains[asym].chain_type_str)
+ )
+ if na_chains:
+ LOG.warning(
+ f"PDB {self.pdb_id!r}: nucleic acid receptor chains "
+ f"{na_chains} are excluded from {aln_type} alignment "
+ "because similarity databases and scores are protein-only."
+ )
+ chains = {
+ self.chains[asym].auth_id
+ for asym in receptor_asym_ids
+ if _is_polypeptide(self.chains[asym].chain_type_str)
+ }
+ elif chain_type == "apo":
+ holo_entities = set(
+ self.chains[c].entity_id for c in self.chains if self.chains[c].holo
+ )
+ chains = set(
+ self.chains[c].auth_id
+ for c in self.chains
+ if not self.chains[c].holo
+ and self.chains[c].entity_id not in holo_entities
+ and _is_polypeptide(self.chains[c].chain_type_str)
+ )
+ elif chain_type == "pred":
+ chains = set()
+ for c in self.chains:
+ if self.chains[c].holo and _is_polypeptide(
+ self.chains[c].chain_type_str
+ ):
+ chains |= set(self.chains[c].mappings.get("UniProt", {}))
+ if aln_type == "foldseek":
+ if chain_type == "pred":
+ return [f"AF-{c}-F1-model_v4_A" for c in chains]
+ else:
+ return [f"pdb_0000{self.pdb_id}_xyz-enrich_{c}" for c in chains]
+ elif aln_type == "mmseqs":
+ if chain_type == "pred":
+ return list(chains)
+ else:
+ return [f"{self.pdb_id}_{c}" for c in chains]
+ return []
+
+ def label_chains(self) -> None:
+ """
+ Label chains as apo/holo/ligand
+ Parameters
+ ----------
+ self : Entry
+ Entry object
+
+ Returns
+ -------
+ None
+ """
+ holo_chains = set()
+ for system in self.systems.values():
+ if system.system_type == "holo":
+ holo_chains.update(
+ [c.split(".", maxsplit=1)[1] for c in system.protein_chains_asym_id]
+ )
+ for interface in self.interfaces:
+ holo_chains.update(
+ {
+ interface.chain_1.split(".", maxsplit=1)[-1],
+ interface.chain_2.split(".", maxsplit=1)[-1],
+ }
+ )
+ for chain in self.chains:
+ self.chains[chain].holo = chain in holo_chains
+
+ def format_validation(
+ self, criteria: QualityCriteria = QualityCriteria()
+ ) -> dict[str, ty.Any]:
+ assert self.validation is not None
+ data = self.validation.format()
+ data = {f"entry_{k}": v for k, v in data.items()}
+ if data["entry_validation_r"] is None:
+ self.pass_criteria = False
+ else:
+ quality = [
+ # ENTRY
+ data["entry_validation_resolution"] is not None
+ and data["entry_validation_resolution"]
+ <= criteria.max_entry_resolution,
+ data["entry_validation_r"] is not None
+ and data["entry_validation_r"] <= criteria.max_entry_r,
+ data["entry_validation_rfree"] is not None
+ and data["entry_validation_rfree"] <= criteria.max_entry_rfree,
+ data["entry_validation_r_minus_rfree"] is not None
+ and data["entry_validation_r_minus_rfree"]
+ <= criteria.max_entry_r_minus_rfree,
+ ]
+ self.pass_criteria = all(quality)
+ data["entry_pass_validation_criteria"] = self.pass_criteria
+ return data
+
+ def format(
+ self, criteria: QualityCriteria = QualityCriteria()
+ ) -> dict[str, ty.Any]:
+ """
+ Format label for entry-level annotations by prepending label with "entry_"
+
+ Parameters
+ ----------
+ self : Entry
+ Entry object
+
+ Returns
+ -------
+ dict[str, ty.Any]
+ """
+ data: dict[str, ty.Any] = defaultdict(str)
+ columns = [
+ "pdb_id",
+ "release_date",
+ "oligomeric_state",
+ "determination_method",
+ "keywords",
+ "pH",
+ "pH_min",
+ "pH_max",
+ "resolution",
+ "has_ligand_of_interest",
+ "source_taxonomy_ids",
+ "source_organism_names",
+ "host_taxonomy_ids",
+ "host_organism_names",
+ "failed_assembly_ids",
+ ]
+ for field in columns:
+ name = f"entry_{field}"
+ data[name] = getattr(self, field)
+
+ data.update(dict.fromkeys(ENTRY_VALIDATION_COLUMNS))
+ if self.validation:
+ data.update(self.format_validation(criteria))
+ return data
+
+ def chains_to_df(self) -> pd.DataFrame:
+ """Return one metadata row for each receptor polymer chain."""
+ columns = [
+ "entry_pdb_id",
+ "chain_asym_id",
+ "chain_auth_id",
+ "chain_entity_id",
+ "chain_type",
+ "chain_receptor_type",
+ "chain_sequence",
+ "chain_sequence_noncanonical",
+ "chain_modified_residues",
+ "chain_length",
+ "chain_num_unresolved_residues",
+ "chain_is_holo",
+ "chain_is_ligand_like",
+ "chain_uniprot_ids",
+ ]
+ rows = []
+ for chain_id in sorted(self.chains):
+ chain = self.chains[chain_id]
+ if not (
+ _is_polypeptide(chain.chain_type_str)
+ or _is_polynucleotide(chain.chain_type_str)
+ ):
+ continue
+ rows.append(
+ {
+ "entry_pdb_id": self.pdb_id,
+ "chain_asym_id": chain.asym_id,
+ "chain_auth_id": chain.auth_id,
+ "chain_entity_id": chain.entity_id,
+ "chain_type": chain.chain_type_str,
+ "chain_receptor_type": get_receptor_type([chain.chain_type_str]),
+ "chain_sequence": self.chain_to_seqres.get(chain.asym_id, ""),
+ "chain_sequence_noncanonical": (
+ self.chain_to_seqres_noncanonical.get(chain.asym_id, "")
+ ),
+ "chain_modified_residues": list(chain.modified_residues),
+ "chain_length": chain.length,
+ "chain_num_unresolved_residues": chain.num_unresolved_residues,
+ "chain_is_holo": chain.holo,
+ "chain_is_ligand_like": chain_id in self.ligand_like_chains,
+ "chain_uniprot_ids": sorted(chain.mappings.get("UniProt", {})),
+ }
+ )
+ return pd.DataFrame(rows, columns=columns)
+
+ def metadata_to_df(self) -> pd.DataFrame:
+ """Return one row of entry-level annotations."""
+ return pd.DataFrame([self.format()])
+
+ def biounit_chains_to_df(self) -> pd.DataFrame:
+ """Return biological-assembly membership once per chain instance."""
+ columns = [
+ "entry_pdb_id",
+ "biounit_id",
+ "chain_instance",
+ "chain_asym_id",
+ "chain_role",
+ ]
+ contact_columns = [
+ "chain_num_contacting_ions",
+ "chain_num_contacting_artifacts",
+ "chain_num_contacting_other_ligands",
+ ]
+ protein_contact_column = "chain_num_contacting_proteins"
+ contacts_computed = self._ligand_contacts_requested or bool(
+ self.biounit_ligand_contact_counts
+ )
+ if contacts_computed:
+ columns.extend(contact_columns)
+ protein_contacts_computed = self._protein_contacts_requested or bool(
+ self.biounit_protein_contact_counts
+ )
+ if protein_contacts_computed:
+ columns.append(protein_contact_column)
+ rows = []
+ water_chains = set(self.water_chains)
+ ligand_chains = set(self.ligand_like_chains)
+ for biounit_id, chain_instances in sorted(self.biounit_chain_ids.items()):
+ contact_counts = self.biounit_ligand_contact_counts.get(str(biounit_id), {})
+ protein_contact_counts = self.biounit_protein_contact_counts.get(
+ str(biounit_id), {}
+ )
+ for chain_instance in sorted(set(chain_instances)):
+ asym_id = chain_instance.split(".", maxsplit=1)[-1]
+ if asym_id in water_chains:
+ role = "water"
+ elif asym_id in ligand_chains:
+ role = "ligand"
+ else:
+ role = "receptor"
+ chain_counts = contact_counts.get(chain_instance, {})
+ row: dict[str, object] = {
+ "entry_pdb_id": self.pdb_id,
+ "biounit_id": str(biounit_id),
+ "chain_instance": chain_instance,
+ "chain_asym_id": asym_id,
+ "chain_role": role,
+ }
+ if contacts_computed:
+ row.update(
+ {
+ "chain_num_contacting_ions": int(
+ chain_counts.get("ions", 0)
+ ),
+ "chain_num_contacting_artifacts": int(
+ chain_counts.get("artifacts", 0)
+ ),
+ "chain_num_contacting_other_ligands": int(
+ chain_counts.get("other_ligands", 0)
+ ),
+ }
+ )
+ if protein_contacts_computed:
+ row[protein_contact_column] = int(
+ protein_contact_counts.get(chain_instance, 0)
+ )
+ rows.append(row)
+ return pd.DataFrame(rows, columns=columns)
+
+ def to_df(self) -> pd.DataFrame:
+ """
+ Convert entry data object to pd.DataFrame
+ Parameters
+ ----------
+ self : Entry
+ Entry object
+
+ Returns
+ -------
+ pd.DataFrame
+ """
+ if self.validation is not None:
+ self.format_validation()
+ rows = []
+ entry_data = {"entry_pdb_id": self.pdb_id}
+ for system in self.systems:
+ annotation = self.systems[system]
+ legacy_mapping = self.biounit_legacy_chain_ids.get(
+ annotation.biounit_id, {}
+ )
+ legacy_protein_chains = sorted(
+ legacy_mapping.get(chain_id, chain_id)
+ for chain_id in annotation.protein_chains_asym_id
+ )
+ legacy_ligand_chains = sorted(
+ legacy_mapping.get(chain_id, chain_id)
+ for chain_id in annotation.ligand_chains
+ )
+ annotation.id_legacy = "__".join(
+ [
+ annotation.pdb_id,
+ annotation.biounit_id,
+ "_".join(legacy_protein_chains),
+ "_".join(legacy_ligand_chains),
+ ]
+ )
+ system_data = annotation.format(
+ self.chains,
+ self.pass_criteria,
+ )
+ for ligand in self.systems[system].ligands:
+ legacy_instance_chain = legacy_mapping.get(
+ ligand.instance_chain, ligand.instance_chain
+ )
+ ligand.id_legacy = "__".join(
+ [
+ ligand.pdb_id,
+ ligand.biounit_id,
+ legacy_instance_chain,
+ ]
+ )
+ ligand_data = ligand.format(self.chains)
+ rows.append({**entry_data, **system_data, **ligand_data})
+ return pd.DataFrame(rows)
+
+ def clear_non_pocket_residues(self) -> None:
+ """
+ Remove non-pocket residues from chains
+ """
+ all_pocket_residues: dict[str, set[int]] = defaultdict(set)
+ for system in self.systems.values():
+ for ligand in system.ligands:
+ for chain in ligand.pocket_residues:
+ all_pocket_residues[chain.split(".", maxsplit=1)[1]].update(
+ ligand.pocket_residues[chain].keys()
+ )
+ n_before = sum(len(c.residues) for c in self.chains.values())
+ for chain in self.chains:
+ if chain in all_pocket_residues:
+ self.chains[chain].residues = {
+ r: self.chains[chain].residues[r]
+ for r in all_pocket_residues[chain]
+ }
+ else:
+ self.chains[chain].residues = {}
+ n_dropped = n_before - sum(len(c.residues) for c in self.chains.values())
+ if n_dropped:
+ LOG.info(
+ f"{self.pdb_id}: clear_non_pocket_residues dropped {n_dropped} of "
+ f"{n_before} chain residues (kept pocket residues only)"
+ )
+
+ def set_validation(
+ self,
+ validation_file: Path,
+ cif_file: Path,
+ thresholds: ResidueValidationThresholds = ResidueValidationThresholds(),
+ ) -> None:
+ from PDBValidation.ValidationFactory import ValidationFactory
+
+ if self.determination_method != "X-RAY DIFFRACTION":
+ LOG.warning(
+ f"set_validation: Skipping validation for {self.pdb_id} as method is not X-RAY DIFFRACTION"
+ )
+ return
+ if not validation_file.exists():
+ LOG.error(f"set_validation: Validation file not found {validation_file}")
+ return
+ try:
+ # libxml2 no longer decompresses gzip input by default.
+ with (
+ gzip.open(validation_file, "rb")
+ if validation_file.suffix == ".gz"
+ else validation_file.open("rb")
+ ) as validation_xml:
+ doc = ValidationFactory(
+ validation_xml, mmcif_path=str(cif_file)
+ ).getValidation()
+ self.validation = EntryValidation.from_entry(doc)
+ except Exception as e:
+ LOG.error(
+ f"set_validation: Error setting validation for {self.pdb_id}: {e}"
+ )
+ return
+ if self.validation is None or self.validation.r is None:
+ return
+
+ system_chain_ids = {
+ system_id: {
+ instance_chain.split(".", maxsplit=1)[-1]
+ for instance_chain in system.protein_chains_asym_id
+ }
+ | {ligand.asym_id for ligand in system.ligands}
+ for system_id, system in self.systems.items()
+ }
+ failed_chains = set()
+ for chain_id in sorted(
+ {chain for chains in system_chain_ids.values() for chain in chains}
+ ):
+ try:
+ self.chains[chain_id].set_validation(doc, thresholds)
+ except Exception as e:
+ failed_chains.add(chain_id)
+ if chain_id in self.chains:
+ chain = self.chains[chain_id]
+ chain.validation = None
+ for residue in chain.residues.values():
+ residue.validation = None
+ LOG.error(
+ f"set_validation: Error setting validation for "
+ f"{self.pdb_id} chain {chain_id}: {e}"
+ )
+
+ for system_id, system in self.systems.items():
+ system.ligand_validation = None
+ system.pocket_validation = None
+ system.pass_criteria = None
+ if failed := system_chain_ids[system_id] & failed_chains:
+ LOG.warning(
+ f"set_validation: Skipping validation for {system_id}: "
+ f"failed chains {sorted(failed)}"
+ )
+ continue
+ try:
+ system.set_validation(self.chains, thresholds)
+ except Exception as e:
+ system.ligand_validation = None
+ system.pocket_validation = None
+ LOG.error(
+ f"set_validation: Error setting validation for {system_id}: {e}"
+ )
+
+
+def document(output_dir: Path) -> None:
+ """
+ Document the columns in the annotation files
+ """
+ output_dir.mkdir(parents=True, exist_ok=True)
+ Entry.document_properties_to_tsv(prefix="entry", filename=output_dir / "entry.tsv")
+ EntryValidation.document_properties_to_tsv(
+ prefix="entry_validation", filename=output_dir / "entry_validation.tsv"
+ )
+ System.document_properties_to_tsv(
+ prefix="system", filename=output_dir / "system.tsv"
+ )
+ ResidueListValidation.document_properties_to_tsv(
+ prefix="system_pocket", filename=output_dir / "system_pocket_validation.tsv"
+ )
+ ResidueListValidation.document_properties_to_tsv(
+ prefix="system_ligand", filename=output_dir / "system_ligand_validation.tsv"
+ )
+ Chain.document_properties_to_tsv(
+ prefix="system_protein_chains",
+ filename=output_dir / "system_protein_chains.tsv",
+ )
+ Chain.document_properties_to_tsv(
+ prefix="system_ligand_chains", filename=output_dir / "system_ligand_chains.tsv"
+ )
+ Ligand.document_properties_to_tsv(
+ prefix="ligand", filename=output_dir / "ligands.tsv"
+ )
diff --git a/src/plinder/data/annotations/ccd_ligand_dbs.py b/src/plinder/data/annotations/ccd_ligand_dbs.py
new file mode 100644
index 000000000..8f2f98026
--- /dev/null
+++ b/src/plinder/data/annotations/ccd_ligand_dbs.py
@@ -0,0 +1,2350 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""CCD-anchored ligand relationship databases (MMP + ECFP4/Tanimoto).
+
+Builds the ligand relationship databases over the fixed Chemical Component
+Dictionary universe rather than one ingest run's ligands, so the artifacts are
+stable across releases and dataset ligands join by CCD identity first and fall
+back to chemistry only when they have no CCD identity.
+
+See ``make_ligand_dbs.md`` for the design and the wire-in checklist.
+
+Notes
+-----
+The component table deliberately reuses the column names of the existing
+unique-SMILES table (``ligand_smiles_id`` / ``ligand_rdkit_canonical_smiles``)
+so :mod:`plinder.data.annotations.mmpdb_utils` and the ECFP4 writer in
+:mod:`plinder.data.annotations.get_similarity_scores` can be reused verbatim on
+this universe.
+"""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import shutil
+import sqlite3
+from collections import Counter, deque
+from collections.abc import Collection, Iterable, Mapping, Sequence
+from difflib import SequenceMatcher
+from functools import cache, lru_cache
+from pathlib import Path
+from typing import TYPE_CHECKING, Any, NamedTuple, TypedDict, cast
+
+import numpy as np
+import pyarrow as pa
+import pyarrow.parquet as pq
+
+if TYPE_CHECKING:
+ from collections.abc import Callable
+
+ import biotite.structure as struc
+ from rdkit.Chem.rdchem import Mol
+
+import pandas as pd
+
+from plinder.core.structure.smallmols_similarity import parity_similarity
+from plinder.core.utils.log import setup_logger
+
+LOG = setup_logger(__name__)
+
+FRAGMENT_OPTIONS_METADATA = b"mmpdb_fragment_options"
+FRAGMENT_COLUMNS = [
+ "ligand_smiles_id",
+ "normalized_smiles",
+ "num_cuts",
+ "enumeration_label",
+ "variable_num_heavies",
+ "variable_symmetry_class",
+ "variable_smiles",
+ "attachment_order",
+ "constant_num_heavies",
+ "constant_symmetry_class",
+ "constant_smiles",
+ "constant_with_H_smiles",
+]
+HYDROGEN = ("[*][H]", "1", "0", "N", 0) # mmpdb's hydrogen variable fragment
+
+
+# TODO: three ad-hoc bundled-CCD readers now exist - this one,
+# ``protein_utils._ccd_parent_components`` and ``ccd_template``'s leaving-atom
+# lookup.
+# Hoist a shared accessor into ``cif_utils`` rather than adding a fourth.
+@lru_cache(maxsize=1)
+def _ccd_chem_comp_table() -> pd.DataFrame:
+ """Return biotite's bundled CCD ``chem_comp`` category as a DataFrame.
+
+ Only the columns this module consumes, all as strings: the CCD stores
+ everything as text and nothing here does arithmetic on it.
+ """
+ from biotite.structure.info.ccd import get_ccd
+
+ category = get_ccd()["chem_comp"]
+ wanted = ["id", "type", "pdbx_release_status"]
+ columns = {
+ name: category[name].as_array(str) for name in wanted if name in category
+ }
+ return pd.DataFrame(columns)
+
+
+def _ccd_smiles(comp_id: str) -> str | None:
+ """Canonical SMILES for one CCD component, or None when underivable."""
+ from plinder.data.annotations.ligand_utils import _get_ccd_smiles
+
+ try:
+ return _get_ccd_smiles(comp_id)
+ except Exception as exc: # noqa: BLE001 - one bad component must not abort
+ LOG.warning(f"CCD SMILES failed for {comp_id}: {exc}")
+ return None
+
+
+def ccd_component_table(
+ *,
+ exclude_non_druglike: bool = True,
+ exclude_polymer_linking: bool = False,
+ limit: int | None = None,
+) -> pd.DataFrame:
+ """Build the active-CCD node universe with canonical SMILES.
+
+ Parameters
+ ----------
+ exclude_non_druglike : bool, default=True
+ Apply plinder's own :func:`~plinder.data.annotations.ligand_utils.is_excluded_mol`
+ filter, the same rule that marks a dataset ligand an artifact. Keeps the
+ CCD universe consistent with native ligand treatment rather than
+ inventing a second notion of "real ligand". Of the dataset's four
+ exclusion sources (these chemistry rules, the artifact bad-list, the
+ cofactor list and the dummy codes) only this one applies here: listed
+ artifacts and cofactors stay nodes, since a ligand may still be related
+ to them; dummies and ions drop out for lacking a molecule.
+ exclude_polymer_linking : bool, default=False
+ Drop ``*-linking`` components (amino acids, nucleotides, saccharides).
+ plinder treats these as polymer/receptor rather than ligand, so enable
+ this for a ligand-only universe; the default keeps the broad chemical
+ reference set.
+ limit : int or None
+ Process only the first *limit* released components (testing aid).
+
+ Returns
+ -------
+ pd.DataFrame
+ Columns ``ccd_id``, ``ligand_rdkit_canonical_smiles`` (stereo included,
+ the key the dataset deduplicates ligands on and the one chemistry
+ matching uses), ``ligand_smiles_id``, ``num_heavy_atoms`` and
+ ``ccd_type``. The
+ ``ligand_*`` names intentionally match the unique-SMILES table so the
+ MMP and ECFP4 builders can be reused.
+
+ Notes
+ -----
+ Only ``pdbx_release_status == "REL"`` components are kept, so obsolete
+ entries never enter the databases. Placeholder codes are dropped via
+ plinder's own :func:`~plinder.data.annotations.ligand_utils.lig_has_dummies`.
+ """
+ from rdkit import Chem
+
+ from plinder.data.annotations.ligand_utils import is_excluded_mol, lig_has_dummies
+
+ table = _ccd_chem_comp_table()
+ released = table[table["pdbx_release_status"] == "REL"]
+ # plinder's own dummy/unknown list, not a local copy: it covers UNK, UPL,
+ # DN and N, which carry real SMILES and would otherwise enter the universe
+ # as if they were genuine chemistry.
+ comp_ids = [
+ comp_id for comp_id in released["id"].tolist() if not lig_has_dummies(comp_id)
+ ]
+ if limit is not None:
+ comp_ids = comp_ids[:limit]
+ LOG.info(f"ccd_component_table: deriving SMILES for {len(comp_ids)} components")
+
+ type_by_id = (
+ dict(zip(released["id"], released["type"])) if "type" in released else {}
+ )
+
+ rows: list[dict[str, object]] = []
+ skipped_no_smiles = 0
+ skipped_non_druglike = 0
+ skipped_polymer = 0
+ for comp_id in comp_ids:
+ ccd_type = str(type_by_id.get(comp_id, "")).lower()
+ if exclude_polymer_linking and "linking" in ccd_type:
+ skipped_polymer += 1
+ continue
+ smiles = _ccd_smiles(comp_id)
+ if not smiles:
+ skipped_no_smiles += 1
+ continue
+ mol = Chem.MolFromSmiles(smiles, sanitize=False)
+ if mol is None:
+ skipped_no_smiles += 1
+ continue
+ num_heavy = mol.GetNumHeavyAtoms()
+ # Same rule plinder uses to call a dataset ligand an artifact, so the
+ # reference universe and the annotation path agree on "real ligand".
+ if exclude_non_druglike and is_excluded_mol(smiles):
+ skipped_non_druglike += 1
+ continue
+ rows.append(
+ {
+ "ccd_id": comp_id,
+ "ligand_rdkit_canonical_smiles": smiles,
+ "num_heavy_atoms": int(num_heavy),
+ # CCD ``type`` is mixed case in the bundle ("NON-POLYMER" vs
+ # "non-polymer"); normalise so consumers can group on it.
+ "ccd_type": ccd_type,
+ }
+ )
+ LOG.info(
+ f"ccd_component_table: kept {len(rows)}; skipped {skipped_no_smiles} "
+ f"without SMILES, {skipped_non_druglike} non-druglike, "
+ f"{skipped_polymer} polymer-linking"
+ )
+ components = pd.DataFrame(rows).sort_values("ccd_id", ignore_index=True)
+ # Stable integer node id: assigned over the sorted CCD ids so the universe
+ # is reproducible for a given CCD bundle. Must be 0-based and contiguous -
+ # ``get_similarity_scores.ligand_scores`` indexes the fingerprint list
+ # directly by node id and rejects any other numbering.
+ components["ligand_smiles_id"] = range(len(components))
+ return components
+
+
+def ccd_universe_signature(components: pd.DataFrame) -> str:
+ """Digest of the component universe, for the build manifest."""
+ digest = hashlib.sha256()
+ for ccd_id, smiles in components[
+ ["ccd_id", "ligand_rdkit_canonical_smiles"]
+ ].itertuples(index=False, name=None):
+ digest.update(str(ccd_id).encode())
+ digest.update(b"\0")
+ digest.update(str(smiles).encode())
+ digest.update(b"\n")
+ return digest.hexdigest()
+
+
+def ccd_dbs_dir(data_dir: Path) -> Path:
+ """Directory holding the CCD-anchored database artifacts."""
+ return Path(data_dir) / "ccd_dbs"
+
+
+def ccd_fingerprint_path(data_dir: Path) -> Path:
+ """Path of the CCD ECFP4 table, in the layout the Tanimoto scorer expects.
+
+ :func:`plinder.data.annotations.get_similarity_scores.ligand_scores`
+ resolves ``/fingerprints/ligands_per_smiles.parquet`` internally,
+ so mirroring that layout under ``ccd_dbs`` lets the existing scorer run on
+ the CCD universe unchanged - no new parameter, no edit to a shared file.
+ """
+ return ccd_dbs_dir(data_dir) / "fingerprints" / "ligands_per_smiles.parquet"
+
+
+def build_ccd_tanimoto_scores(
+ components: pd.DataFrame,
+ data_dir: Path,
+ *,
+ minimum_similarity: float = 30.0,
+ batch_size: int = 5_000,
+) -> Path:
+ """Compute ECFP4 Tanimoto edges over the CCD universe.
+
+ Parameters
+ ----------
+ components : pd.DataFrame
+ Output of :func:`ccd_component_table`; supplies the node ids.
+ data_dir : Path
+ Release directory; scores land in ``/ccd_dbs/ligand_scores``.
+ minimum_similarity : float
+ Percentage cutoff below which edges are dropped.
+ batch_size : int
+ Node ids scored per output shard, mirroring the ingest scatter so a
+ 50k-node universe never materialises an all-pairs matrix at once.
+
+ Returns
+ -------
+ Path
+ Directory holding the per-batch score shards.
+
+ Notes
+ -----
+ Delegates to the same ``ligand_scores`` routine the ingest pipeline uses,
+ pointed at the CCD ``fingerprints`` layout, so the edge semantics and the
+ ECFP4 metadata check are identical to the dataset-level scores.
+ """
+ from plinder.data.annotations import get_similarity_scores
+
+ ccd_dir = ccd_dbs_dir(data_dir)
+ scores_dir = ccd_dir / "ligand_scores"
+ scores_dir.mkdir(parents=True, exist_ok=True)
+ # Shards are numbered per batch, so a rebuild over a smaller universe would
+ # otherwise leave higher-numbered shards behind and any consumer globbing
+ # this directory would read them as live edges referencing dead node ids.
+ for stale in scores_dir.glob("ccd_scores_*.parquet"):
+ stale.unlink()
+ node_ids = [int(value) for value in components["ligand_smiles_id"]]
+ for start in range(0, len(node_ids), batch_size):
+ batch = node_ids[start : start + batch_size]
+ output_path = scores_dir / f"ccd_scores_{start // batch_size:04d}.parquet"
+ get_similarity_scores.ligand_scores(
+ ligand_ids=batch,
+ data_dir=ccd_dir,
+ output_path=output_path,
+ minimum_similarity=minimum_similarity,
+ )
+ LOG.info(
+ f"build_ccd_tanimoto_scores: scored {len(node_ids)} nodes into {scores_dir}"
+ )
+ return scores_dir
+
+
+def build_ccd_ecfp_db(components: pd.DataFrame, output_path: Path) -> Path:
+ """Write the ECFP4/1024 fingerprint table over the CCD universe.
+
+ Mirrors ``fingerprints/ligands_per_smiles.parquet`` (same columns, same
+ parquet metadata) so the existing similarity/clustering machinery can run
+ against this node universe unchanged.
+ """
+ from rdkit import DataStructs
+
+ from plinder.core.structure.smallmols_similarity import mol2morgan_fp
+ from plinder.data.annotations.get_similarity_scores import (
+ ECFP4_NBITS,
+ ECFP4_RADIUS,
+ write_ecfp4_fingerprint_table,
+ )
+
+ table = components.copy()
+ binary_fingerprints: list[bytes] = []
+ for smiles in table["ligand_rdkit_canonical_smiles"]:
+ fingerprint = mol2morgan_fp(smiles, radius=ECFP4_RADIUS, nbits=ECFP4_NBITS)
+ binary_fingerprints.append(DataStructs.BitVectToBinaryText(fingerprint))
+ table["fingerprint"] = binary_fingerprints
+
+ output_path.parent.mkdir(parents=True, exist_ok=True)
+ temporary_path = output_path.with_suffix(".parquet.tmp")
+ temporary_path.unlink(missing_ok=True)
+ write_ecfp4_fingerprint_table(table, temporary_path)
+ temporary_path.replace(output_path)
+ LOG.info(f"build_ccd_ecfp_db: wrote {len(table)} fingerprints to {output_path}")
+ return output_path
+
+
+def build_ccd_mmp_db(
+ components: pd.DataFrame,
+ output_path: Path,
+ *,
+ scratch_dir: Path,
+ threads: int = 4,
+ fragments_path: Path | None = None,
+ exclusions_path: Path | None = None,
+) -> Path:
+ """Write matched molecular pairs over the CCD universe.
+
+ Reuses the existing mmpdb flow (``smi_split -> fragment ->
+ fragdb_partition -> index``) unchanged; only the input universe differs.
+
+ Parameters
+ ----------
+ fragments_path : Path or None
+ When given, persist every fragmentation of the universe there, keyed by
+ constant part; :func:`query_ccd_mmp_pairs` pairs molecules outside the
+ universe against it without a rebuild.
+
+ Notes
+ -----
+ The universe is CCD components only; composite ligands are deliberately not
+ added. Pairing joins fragmentations on their shared constant part, and
+ residues of one class leave the same constant when their side chain is cut -
+ every amino acid leaves the backbone - so composites of that class all pair
+ with one another: recall without precision. Fragmentation also enumerates
+ cuts over acyclic single bonds, of which a composite has one per linkage
+ plus its side chains, so cost grows combinatorially with residue count while
+ those shared constants make the pair count quadratic in the number of
+ composites. Relate composites by their residue graph instead
+ (:func:`composite_similarity`), and use this database only to describe a
+ residue substitution, never to decide whether two composites are related.
+ """
+ from tempfile import TemporaryDirectory
+
+ from plinder.data.annotations.mmpdb_utils import (
+ _generate_pair_files,
+ _write_pair_parquet,
+ )
+
+ executable = shutil.which("mmpdb")
+ if executable is None:
+ raise RuntimeError(
+ "mmpdb is required to build the CCD MMP database; install the "
+ "PLINDER data dependencies"
+ )
+ output_path.parent.mkdir(parents=True, exist_ok=True)
+ mmp_components, exclusions = _ccd_mmp_inputs(components)
+ if exclusions_path is not None:
+ exclusions_path.parent.mkdir(parents=True, exist_ok=True)
+ exclusions.to_csv(exclusions_path, sep="\t", index=False)
+ LOG.info(
+ "build_ccd_mmp_db: excluding %d of %d CCD components from mmpdb",
+ len(exclusions),
+ len(components),
+ )
+ scratch_dir = Path(scratch_dir)
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ temporary_path = output_path.with_suffix(".parquet.tmp")
+ temporary_path.unlink(missing_ok=True)
+ with TemporaryDirectory(prefix="plinder-ccd-mmp-", dir=scratch_dir) as work:
+ work_dir = Path(work)
+ pair_files = _generate_pair_files(
+ ligands=mmp_components,
+ work_dir=work_dir,
+ threads=threads,
+ executable=executable,
+ )
+ _write_pair_parquet(
+ pair_files=pair_files,
+ ligands=mmp_components,
+ output_path=temporary_path,
+ )
+ if fragments_path is not None:
+ _export_fragmentations(work_dir, Path(fragments_path))
+ temporary_path.replace(output_path)
+ LOG.info(f"build_ccd_mmp_db: wrote matched pairs to {output_path}")
+ return output_path
+
+
+def _ccd_mmp_inputs(components: pd.DataFrame) -> tuple[pd.DataFrame, pd.DataFrame]:
+ """Keep CCD chemistry mmpdb can fragment; retain every CCD in other scores."""
+ from rdkit import Chem
+ from rdkit.rdBase import BlockLogs
+
+ included = []
+ exclusions = []
+ with BlockLogs():
+ for row in components.itertuples(index=False):
+ smiles = row.ligand_rdkit_canonical_smiles
+ molecule = Chem.MolFromSmiles(smiles)
+ if molecule is None:
+ reason = "unsupported_by_mmpdb_smiles_parser"
+ elif any(
+ str(bond.GetBondType()).startswith("DATIVE")
+ for bond in molecule.GetBonds()
+ ):
+ reason = "metal_dative_bonds"
+ elif len(Chem.GetMolFrags(molecule)) != 1:
+ reason = "disconnected_components"
+ else:
+ included.append(row.ligand_smiles_id)
+ continue
+ exclusions.append((row.ccd_id, row.ligand_smiles_id, smiles, reason))
+ filtered = components[components["ligand_smiles_id"].isin(included)]
+ excluded = pd.DataFrame(
+ exclusions, columns=["ccd_id", "ligand_smiles_id", "smiles", "reason"]
+ )
+ return filtered, excluded
+
+
+def _export_fragmentations(work_dir: Path, fragments_path: Path) -> Path:
+ """Persist the universe's fragmentations as the constant-keyed pair dictionary.
+
+ ``mmpdb index`` forms pairs by joining fragmentations on their constant part;
+ the ``ligands.NNNN.fragdb`` shards hold exactly those rows. Sorted by
+ constant so parquet row-group statistics let a lookup skip most of the file,
+ with the fragment options in the parquet metadata so queries fragment the
+ same way.
+ """
+ frames: list[pd.DataFrame] = []
+ options: dict[str, Any] | None = None
+ record_columns = {
+ "ligand_smiles_id": "r.title AS ligand_smiles_id",
+ "normalized_smiles": "r.normalized_smiles",
+ }
+ select = ", ".join(
+ record_columns.get(name, f"f.{name}") for name in FRAGMENT_COLUMNS
+ )
+ for database in sorted(work_dir.glob("ligands.[0-9][0-9][0-9][0-9].fragdb")):
+ connection = sqlite3.connect(database)
+ try:
+ frames.append(
+ pd.read_sql_query(
+ f"SELECT {select} FROM fragmentation f "
+ "JOIN record r ON r.id = f.record_id",
+ connection,
+ )
+ )
+ names = [row[1] for row in connection.execute("PRAGMA table_info(options)")]
+ values = connection.execute("SELECT * FROM options").fetchone()
+ finally:
+ connection.close()
+ options = {
+ name: value
+ for name, value in zip(names, values)
+ if name not in {"id", "version"}
+ }
+ if options is None:
+ raise RuntimeError("mmpdb fragmentation left no fragment databases behind")
+ fragments = (
+ pd.concat(frames, ignore_index=True)
+ if frames
+ else pd.DataFrame(columns=FRAGMENT_COLUMNS)
+ )
+ fragments["ligand_smiles_id"] = fragments["ligand_smiles_id"].astype(int)
+ fragments = fragments.sort_values(
+ ["constant_smiles", "num_cuts"], ignore_index=True
+ )
+ table = pa.Table.from_pandas(
+ fragments, preserve_index=False
+ ).replace_schema_metadata({FRAGMENT_OPTIONS_METADATA: json.dumps(options).encode()})
+ fragments_path.parent.mkdir(parents=True, exist_ok=True)
+ temporary_path = fragments_path.with_suffix(".parquet.tmp")
+ pq.write_table(table, temporary_path, compression="zstd", row_group_size=50_000)
+ temporary_path.replace(fragments_path)
+ LOG.info(f"_export_fragmentations: wrote {len(fragments)} rows to {fragments_path}")
+ return fragments_path
+
+
+def _fragment_dictionary(
+ fragments_path: Path, *, constants: Collection[str], molecules: Collection[str]
+) -> tuple[pd.DataFrame, dict[str, list[int]]]:
+ """Fragmentation rows a query can pair with, and the universe's molecule map.
+
+ Rows share a constant with a query fragmentation, or are one-cut rows whose
+ constant plus hydrogen is a query molecule. The map (normalised SMILES ->
+ node ids) serves the opposite hydrogen case.
+ """
+ frames = []
+ if constants:
+ frames.append(
+ pq.read_table(
+ fragments_path,
+ filters=[("constant_smiles", "in", sorted(set(constants)))],
+ ).to_pandas()
+ )
+ if molecules:
+ frames.append(
+ pq.read_table(
+ fragments_path,
+ filters=[
+ ("num_cuts", "==", 1),
+ ("constant_with_H_smiles", "in", sorted(set(molecules))),
+ ],
+ ).to_pandas()
+ )
+ rows = (
+ pd.concat(frames, ignore_index=True).drop_duplicates()
+ if frames
+ else pq.read_schema(fragments_path).empty_table().to_pandas()
+ )
+ nodes = (
+ pq.read_table(fragments_path, columns=["ligand_smiles_id", "normalized_smiles"])
+ .to_pandas()
+ .drop_duplicates()
+ )
+ molecule_ids = {
+ smiles: [int(value) for value in group]
+ for smiles, group in nodes.groupby("normalized_smiles")["ligand_smiles_id"]
+ }
+ return rows, molecule_ids
+
+
+def query_ccd_mmp_pairs(
+ queries: Mapping[str, str],
+ data_dir: Path,
+ *,
+ max_variable_heavies: int | None = 10,
+ max_heavies_transf: int | None = None,
+) -> pd.DataFrame:
+ """Matched molecular pairs between molecules outside the universe and the CCD.
+
+ Runs mmpdb's pairing rule against the persisted fragmentation dictionary: a
+ query and a component are a pair when a fragmentation of each leaves the
+ same constant part (cut count and symmetry class included) with different
+ variable parts; a one-cut constant whose hydrogen-capped form is itself a
+ molecule of the other side pairs against the hydrogen fragment, as in
+ ``mmpdb index``; two enumerated-chirality constants never pair. SMIRKS come
+ from ``mmpdblib.index_algorithm.cansmirks``, so transformations are written
+ exactly as in ``ccd_mmp_pairs.parquet``. Defaults are mmpdb's index defaults
+ (``--max-variable-heavies 10``).
+
+ Parameters
+ ----------
+ queries : mapping
+ ``{query_id: smiles}`` for the molecules to place (novel or external).
+ data_dir : Path
+ Release directory holding ``ccd_dbs``.
+ max_variable_heavies, max_heavies_transf : int or None
+ mmpdb index filters on the variable part and on the change in its size.
+
+ Returns
+ -------
+ pd.DataFrame
+ One row per (query, component, shared core, transformation) with
+ ``query_id``, ``query_smiles``, ``ligand_smiles_id``, ``ccd_id``,
+ ``ligand_smiles``, ``transformation`` (query >> component),
+ ``shared_core_smiles``, ``num_cuts``, ``shared_core_num_heavy_atoms``.
+
+ Notes
+ -----
+ Components with no fragmentation of their own (very small molecules) cannot
+ be hydrogen partners, since the molecule map is read from the dictionary.
+
+ TODO (discuss): the pair relation is symmetric; the directed quantity plinder
+ uses is core coverage per side (``shared_core_fraction`` in
+ ``ccd_mmp_pairs.parquet``), which this output lacks. Also whether mmpdb's
+ index defaults (10-atom variable cap, no coverage floor) and the downstream
+ 5-atom core floor are the cutoffs wanted for the CCD reference.
+ """
+ from mmpdblib import (
+ fragment_algorithm,
+ fragment_records,
+ fragment_types,
+ index_algorithm,
+ )
+
+ fragments_path = ccd_dbs_dir(data_dir) / "ccd_mmp_fragments.parquet"
+ if not fragments_path.is_file():
+ raise FileNotFoundError(f"missing CCD fragmentation table: {fragments_path}")
+ options = json.loads(
+ pq.read_schema(fragments_path).metadata[FRAGMENT_OPTIONS_METADATA]
+ )
+ fragment_filter = fragment_types.get_fragment_filter(
+ fragment_types.FragmentOptions(**options)
+ )
+ records = {}
+ for query_id, smiles in queries.items():
+ record = fragment_records.make_fragment_record_from_smiles(
+ smiles, fragment_filter
+ )
+ if getattr(record, "errmsg", None):
+ LOG.warning(
+ f"query_ccd_mmp_pairs: cannot fragment {query_id}: {record.errmsg}"
+ )
+ continue
+ records[query_id] = record
+ constants = {
+ fragmentation.constant_smiles
+ for record in records.values()
+ for fragmentation in record.fragmentations
+ }
+ molecules = {record.normalized_smiles for record in records.values()}
+ dictionary, molecule_ids = _fragment_dictionary(
+ fragments_path, constants=constants, molecules=molecules
+ )
+ groups = {
+ key: group
+ for key, group in dictionary.groupby(
+ ["num_cuts", "constant_smiles", "constant_symmetry_class"], sort=False
+ )
+ }
+ capped = dictionary[dictionary["num_cuts"] == 1].groupby("constant_with_H_smiles")
+ relabel_cache = index_algorithm.RelabelCache()
+ no_enumeration = fragment_algorithm.EnumerationLabel.NO_ENUMERATION
+ rows: list[dict[str, object]] = []
+
+ def pair(
+ query_id: str,
+ query_smiles: str,
+ query_molecule: str,
+ constant: tuple[int, str, str, int],
+ query_side: tuple[str, str, str, str, int],
+ target_id: int,
+ target_molecule: str,
+ target_side: tuple[str, str, str, str, int],
+ ) -> None:
+ """Append one pair if mmpdb's index filters admit it."""
+ num_cuts, constant_smiles, constant_symmetry_class, constant_heavies = constant
+ (
+ query_smiles_,
+ query_symmetry,
+ query_order,
+ query_label,
+ query_heavies,
+ ) = query_side
+ (
+ target_smiles,
+ target_symmetry,
+ target_order,
+ target_label,
+ target_heavies,
+ ) = target_side
+ if max_variable_heavies is not None and (
+ query_heavies > max_variable_heavies
+ or target_heavies > max_variable_heavies
+ ):
+ return
+ if target_smiles == query_smiles_ and target_order == query_order:
+ return
+ if target_molecule == query_molecule: # the query is that component
+ return
+ if query_label != no_enumeration and target_label != no_enumeration:
+ return
+ if (
+ max_heavies_transf is not None
+ and abs(target_heavies - query_heavies) > max_heavies_transf
+ ):
+ return
+ smirks, shared_core = index_algorithm.cansmirks(
+ num_cuts,
+ query_smiles_,
+ query_symmetry,
+ query_order,
+ constant_smiles,
+ constant_symmetry_class,
+ target_smiles,
+ target_symmetry,
+ target_order,
+ relabel_cache,
+ )
+ rows.append(
+ {
+ "query_id": query_id,
+ "query_smiles": query_smiles,
+ "ligand_smiles_id": int(target_id),
+ "transformation": smirks,
+ "shared_core_smiles": shared_core,
+ "num_cuts": int(num_cuts),
+ "shared_core_num_heavy_atoms": int(constant_heavies),
+ }
+ )
+
+ for query_id, record in records.items():
+ for query in record.fragmentations:
+ constant = (
+ query.num_cuts,
+ query.constant_smiles,
+ query.constant_symmetry_class,
+ query.constant_num_heavies,
+ )
+ query_side = (
+ query.variable_smiles,
+ query.variable_symmetry_class,
+ query.attachment_order,
+ query.enumeration_label,
+ query.variable_num_heavies,
+ )
+ group = groups.get(constant[:3])
+ if group is not None:
+ for target in group.itertuples(index=False):
+ pair(
+ query_id,
+ record.input_smiles,
+ record.normalized_smiles,
+ constant,
+ query_side,
+ target.ligand_smiles_id,
+ target.normalized_smiles,
+ (
+ target.variable_smiles,
+ target.variable_symmetry_class,
+ target.attachment_order,
+ target.enumeration_label,
+ target.variable_num_heavies,
+ ),
+ )
+ if query.num_cuts == 1:
+ # the query minus this substituent is itself a component
+ for target_id in molecule_ids.get(query.constant_with_H_smiles, []):
+ pair(
+ query_id,
+ record.input_smiles,
+ record.normalized_smiles,
+ constant,
+ query_side,
+ target_id,
+ query.constant_with_H_smiles,
+ HYDROGEN,
+ )
+ if record.normalized_smiles in capped.groups:
+ # the query is a component minus one substituent
+ for target in capped.get_group(record.normalized_smiles).itertuples(
+ index=False
+ ):
+ pair(
+ query_id,
+ record.input_smiles,
+ record.normalized_smiles,
+ (
+ 1,
+ target.constant_smiles,
+ target.constant_symmetry_class,
+ target.constant_num_heavies,
+ ),
+ HYDROGEN,
+ target.ligand_smiles_id,
+ target.normalized_smiles,
+ (
+ target.variable_smiles,
+ target.variable_symmetry_class,
+ target.attachment_order,
+ target.enumeration_label,
+ target.variable_num_heavies,
+ ),
+ )
+ pairs = pd.DataFrame(
+ rows,
+ columns=[
+ "query_id",
+ "query_smiles",
+ "ligand_smiles_id",
+ "transformation",
+ "shared_core_smiles",
+ "num_cuts",
+ "shared_core_num_heavy_atoms",
+ ],
+ ).drop_duplicates()
+ components = load_ccd_components(data_dir)[
+ ["ligand_smiles_id", "ccd_id", "ligand_rdkit_canonical_smiles"]
+ ].rename(columns={"ligand_rdkit_canonical_smiles": "ligand_smiles"})
+ return pairs.merge(components, on="ligand_smiles_id", how="left").sort_values(
+ ["query_id", "ligand_smiles_id", "shared_core_smiles", "transformation"],
+ ignore_index=True,
+ )
+
+
+class CcdMatch(TypedDict):
+ """One ligand resolved against the CCD universe."""
+
+ match_kind: str
+ matched_ccd_ids: list[str]
+ component_ccd_ids: list[str]
+
+
+class CcdIndex(NamedTuple):
+ """Lookups over the universe that :func:`match_ligand_to_ccd` needs."""
+
+ ccd_ids: frozenset[str]
+ smiles_to_ccd_ids: dict[
+ str, list[str]
+ ] # canonical SMILES, stereo included -> codes
+ released_ids: frozenset[str]
+
+
+def ccd_index(components: pd.DataFrame) -> CcdIndex:
+ """Build the matcher's lookups from :func:`ccd_component_table` output."""
+ # both sides through canonical_smiles: re-canonicalising is not idempotent
+ # for a few dative/cage SMILES, so the stored string alone would not match
+ by_smiles: dict[str, list[str]] = {}
+ for ccd_id, smiles in zip(
+ components["ccd_id"].astype(str),
+ components["ligand_rdkit_canonical_smiles"].astype(str),
+ ):
+ by_smiles.setdefault(canonical_smiles(smiles) or smiles, []).append(ccd_id)
+ released = _ccd_chem_comp_table().query("pdbx_release_status == 'REL'")["id"]
+ return CcdIndex(
+ frozenset(components["ccd_id"].astype(str)),
+ by_smiles,
+ frozenset(released.astype(str)),
+ )
+
+
+def canonical_smiles(smiles: str | None) -> str | None:
+ """RDKit canonical SMILES with stereo, the form the CCD table stores."""
+ from rdkit import Chem
+
+ from plinder.core.utils.sanitize import mol_from_smiles
+
+ if not smiles:
+ return None
+ mol = mol_from_smiles(smiles)
+ return None if mol is None else str(Chem.MolToSmiles(mol))
+
+
+def match_ligand_to_ccd(
+ ccd_code: str, ligand_smiles: str | None, index: CcdIndex
+) -> CcdMatch:
+ """Resolve one ligand against the CCD universe by code, then by chemistry.
+
+ ``ligand_smiles`` must come through :func:`canonical_smiles`, as the index
+ keys do. ``match_kind`` is one of
+
+ ``exact``
+ The ligand is a universe component: its single code is one, or its
+ whole-molecule canonical SMILES equals a component's. The second test
+ is what lets one molecule match however it was deposited, e.g. lactose
+ as ``LAT`` or as the linked sugars ``GAL-BGC``. Stereo is part of the
+ identity, as in the dataset's own ligand key: the ligand's SMILES
+ carries the stereo perceived from its coordinates, the component's the
+ stereo of its ideal coordinates, so cellobiose and maltose never match
+ lactose.
+ ``excluded``
+ A single code that is a released CCD component the universe filters
+ out (ions, artifacts, placeholders): known, not novel.
+ ``novel``
+ No component is this molecule. Relating it to the universe is the
+ fingerprint's job (:func:`query_ccd_tanimoto`, :func:`query_ccd_mmp_pairs`).
+
+ ``component_ccd_ids`` lists a composite's codes that are universe
+ components, as annotation only: a missing component says nothing about
+ what the whole molecule is.
+ """
+ codes = [code for code in str(ccd_code or "").split("-") if code]
+ matched: list[str] = []
+ if len(codes) == 1 and codes[0] in index.ccd_ids:
+ matched = [codes[0]]
+ elif ligand_smiles:
+ matched = sorted(index.smiles_to_ccd_ids.get(ligand_smiles, []))
+ if matched:
+ kind = "exact"
+ elif len(codes) == 1 and codes[0] in index.released_ids:
+ kind = "excluded"
+ else:
+ kind = "novel"
+ return {
+ "match_kind": kind,
+ "matched_ccd_ids": matched,
+ "component_ccd_ids": [code for code in codes if code in index.ccd_ids],
+ }
+
+
+def load_ccd_components(data_dir: Path) -> pd.DataFrame:
+ """Load the persisted component universe the artifacts were built from.
+
+ Always prefer this over rebuilding with :func:`ccd_component_table` when
+ joining against existing artifacts: node ids are positions in *this* table,
+ so a table built with different filters would silently mis-map every id.
+ """
+ path = ccd_dbs_dir(data_dir) / "ccd_components.parquet"
+ if not path.is_file():
+ raise FileNotFoundError(f"missing CCD component table: {path}")
+ return pd.read_parquet(path)
+
+
+def build_ligand_ccd_match(
+ ligands: pd.DataFrame,
+ components: pd.DataFrame,
+ output_path: Path | None = None,
+) -> pd.DataFrame:
+ """Map dataset ligands onto the CCD universe.
+
+ Parameters
+ ----------
+ ligands : pd.DataFrame
+ ``ligand_id``, ``ligand_ccd_code`` and ``ligand_smiles`` (the
+ whole-molecule SMILES; composites are one connected molecule), plus
+ components : pd.DataFrame
+ Output of :func:`ccd_component_table`.
+ output_path : Path or None
+ When given, write the join table as parquet.
+
+ Returns
+ -------
+ pd.DataFrame
+ ``ligand_id``, ``ligand_ccd_code``, ``match_kind``, ``matched_ccd_ids``,
+ ``ccd_node_ids`` (nodes of the matched components), ``component_ccd_ids``.
+
+ Notes
+ -----
+ Emitted as a sidecar join table rather than annotation columns, so building
+ these databases never contends with the index schema.
+ """
+ index = ccd_index(components)
+ node_by_ccd = dict(
+ zip(components["ccd_id"].astype(str), components["ligand_smiles_id"])
+ )
+ canonical_of = {
+ smiles: canonical_smiles(smiles)
+ for smiles in ligands["ligand_smiles"].dropna().unique()
+ }
+ rows: list[dict[str, object]] = []
+ for ligand_id, ccd_code, smiles in zip(
+ ligands["ligand_id"], ligands["ligand_ccd_code"], ligands["ligand_smiles"]
+ ):
+ match = match_ligand_to_ccd(str(ccd_code), canonical_of.get(smiles), index)
+ rows.append(
+ {
+ "ligand_id": ligand_id,
+ "ligand_ccd_code": ccd_code,
+ "match_kind": match["match_kind"],
+ "matched_ccd_ids": match["matched_ccd_ids"],
+ "ccd_node_ids": [int(node_by_ccd[c]) for c in match["matched_ccd_ids"]],
+ "component_ccd_ids": match["component_ccd_ids"],
+ }
+ )
+ matches = pd.DataFrame(rows)
+ if output_path is not None:
+ output_path.parent.mkdir(parents=True, exist_ok=True)
+ temporary_path = output_path.with_suffix(".parquet.tmp")
+ temporary_path.unlink(missing_ok=True)
+ matches.to_parquet(temporary_path, index=False)
+ temporary_path.replace(output_path)
+ return matches
+
+
+def make_ligand_ccd_match(*, data_dir: Path) -> Path:
+ """Write ``ccd_dbs/ligand_ccd_match.parquet`` for the collated annotation table."""
+ annotation_path = data_dir / "index" / "annotation_table.parquet"
+ if not annotation_path.is_file():
+ raise FileNotFoundError(
+ f"collate the annotation table first: {annotation_path}"
+ )
+ columns = [
+ "ligand_id",
+ "ligand_ccd_code",
+ "ligand_smiles",
+ ]
+ available = set(pq.read_schema(annotation_path).names)
+ ligands = pd.read_parquet(
+ annotation_path, columns=[c for c in columns if c in available]
+ ).drop_duplicates()
+ output_path = ccd_dbs_dir(data_dir) / "ligand_ccd_match.parquet"
+ build_ligand_ccd_match(
+ ligands, load_ccd_components(data_dir), output_path=output_path
+ )
+ return output_path
+
+
+def query_ccd_tanimoto(
+ queries: Mapping[str, str], data_dir: Path, *, minimum_similarity: float = 30.0
+) -> pd.DataFrame:
+ """ECFP4/1024 Tanimoto neighbours of molecules outside the universe.
+
+ The same fingerprint, table and percentage cutoff as
+ :func:`~plinder.data.annotations.get_similarity_scores.ligand_scores`, so a
+ novel or external ligand (a composite included, through its whole-molecule
+ SMILES) is related to the CCD exactly as dataset ligands are to each other.
+
+ Returns
+ -------
+ pd.DataFrame
+ ``query_id``, ``query_smiles``, ``ligand_smiles_id``,
+ ``tanimoto_similarity_ecfp4_1024`` (percent), ``ccd_id``; best hit first.
+ """
+ from rdkit import DataStructs
+
+ from plinder.core.structure.smallmols_similarity import mol2morgan_fp
+ from plinder.data.annotations.get_similarity_scores import (
+ ECFP4_NBITS,
+ ECFP4_PARQUET_METADATA,
+ ECFP4_RADIUS,
+ )
+
+ fingerprint_path = ccd_fingerprint_path(data_dir)
+ metadata = pq.read_schema(fingerprint_path).metadata or {}
+ if any(metadata.get(key) != value for key, value in ECFP4_PARQUET_METADATA.items()):
+ raise ValueError("CCD fingerprint metadata is not ECFP4/1024")
+ table = pd.read_parquet(
+ fingerprint_path, columns=["ligand_smiles_id", "fingerprint"]
+ )
+ fingerprints = [DataStructs.CreateFromBinaryText(v) for v in table["fingerprint"]]
+ node_ids = table["ligand_smiles_id"].astype(int).tolist()
+ minimum_fraction = minimum_similarity / 100.0
+ rows: list[dict[str, object]] = []
+ for query_id, smiles in queries.items():
+ try:
+ fingerprint = mol2morgan_fp(smiles, radius=ECFP4_RADIUS, nbits=ECFP4_NBITS)
+ except Exception as exc: # noqa: BLE001 - one bad query must not abort
+ LOG.warning(f"query_ccd_tanimoto: cannot fingerprint {query_id}: {exc}")
+ continue
+ similarities = DataStructs.BulkTanimotoSimilarity(fingerprint, fingerprints)
+ rows.extend(
+ {
+ "query_id": query_id,
+ "query_smiles": smiles,
+ "ligand_smiles_id": node_id,
+ "tanimoto_similarity_ecfp4_1024": similarity * 100.0,
+ }
+ for node_id, similarity in zip(node_ids, similarities)
+ if similarity >= minimum_fraction
+ )
+ hits = pd.DataFrame(
+ rows,
+ columns=[
+ "query_id",
+ "query_smiles",
+ "ligand_smiles_id",
+ "tanimoto_similarity_ecfp4_1024",
+ ],
+ )
+ components = load_ccd_components(data_dir)[["ligand_smiles_id", "ccd_id"]]
+ return hits.merge(components, on="ligand_smiles_id", how="left").sort_values(
+ ["query_id", "tanimoto_similarity_ecfp4_1024", "ligand_smiles_id"],
+ ascending=[True, False, True],
+ ignore_index=True,
+ )
+
+
+def ccd_parity_path(data_dir: Path) -> Path:
+ """Path of the CCD-vs-CCD PARITY-like score table."""
+ return ccd_dbs_dir(data_dir) / "ccd_parity_scores.parquet"
+
+
+@cache
+def _ccd_named_mol(ccd_id: str) -> Mol | None:
+ """RDKit molecule of a CCD component carrying its atom names, or None."""
+ from plinder.data.annotations.ligand_utils import _get_ccd_mol
+
+ return _get_ccd_mol(ccd_id)
+
+
+def _ccd_heavy_atoms(ccd_id: str) -> tuple[tuple[str, ...], frozenset[frozenset[str]]]:
+ """Heavy-atom names of a CCD component and its bonds as name pairs."""
+ from plinder.core.structure.ccd_template import ccd_component_template
+
+ template = ccd_component_template(ccd_id)
+ if template is None:
+ return (), frozenset()
+ return template.heavy, frozenset(frozenset((a, b)) for a, b, _ in template.bonds)
+
+
+def _atom_names(mol: Mol) -> list[str]:
+ """PDB atom names when the molecule carries them, else atom indices."""
+ names = []
+ for index in range(mol.GetNumAtoms()):
+ info = mol.GetAtomWithIdx(index).GetPDBResidueInfo()
+ names.append(info.GetName().strip() if info else str(index))
+ return names
+
+
+def _parity_rows(
+ pairs: Sequence[tuple[Mol | None, Mol | None, bool]], *, threads: int
+) -> pd.DataFrame:
+ """PARITY-like score, per-side coverage and fragment atom names per molecule pair.
+
+ Each pair is ``(first, second, keep_alternatives)``; the scored fragment is
+ always the best of every equally good MCES, and with ``keep_alternatives``
+ the others are stored after it. Score and coverages are percent.
+ """
+ from concurrent.futures import ThreadPoolExecutor
+
+ from rdkit import Chem
+
+ from plinder.core.structure.smallmols_similarity import rascal_parity_match
+
+ def row(
+ pair: tuple[Mol | None, Mol | None, bool],
+ ) -> tuple[float, float, float, list[list[str]], list[list[str]]]:
+ first, second, keep_alternatives = pair
+ if first is None or second is None:
+ return float("nan"), float("nan"), float("nan"), [], []
+ first, second = Chem.Mol(first), Chem.Mol(second)
+ first.RemoveAllConformers()
+ second.RemoveAllConformers()
+ match = rascal_parity_match(first, second, all_best=keep_alternatives)
+ names_1, names_2 = _atom_names(first), _atom_names(second)
+ fragments = (match.atoms, *(match.alternatives if keep_alternatives else ()))
+ coverage_1, coverage_2 = match.coverage(first, second)
+ return (
+ match.score(first, second) * 100.0,
+ coverage_1 * 100.0,
+ coverage_2 * 100.0,
+ [[names_1[i] for i in fragment] for fragment in fragments],
+ [[names_2[j] for j in fragment.values()] for fragment in fragments],
+ )
+
+ # Clone only active worker inputs; cached CCD molecules remain shared read-only.
+ with ThreadPoolExecutor(threads) as pool:
+ rows = list(pool.map(row, pairs))
+ return pd.DataFrame(
+ rows,
+ columns=[
+ "parity_similarity",
+ "parity_coverage_1",
+ "parity_coverage_2",
+ "fragment_atoms_1",
+ "fragment_atoms_2",
+ ],
+ )
+
+
+class CcdParityTable:
+ """Mono-to-mono PARITY-like matches keyed by CCD code pair, for composite scoring.
+
+ Rows carry ``ccd_id_1``, ``ccd_id_2``, ``parity_similarity`` (percent), the
+ directional ``parity_coverage_1`` and ``parity_coverage_2`` (percent) and
+ the largest-fragment atom names ``fragment_atoms_1`` -> ``fragment_atoms_2``,
+ one list per equally good fragment, the scored one first.
+
+ Notes
+ -----
+ Each unordered pair is stored once, so the symmetric score and the fragment
+ mapping are not duplicated. The direction is resolved on access: ``1 -> 2``
+ and ``2 -> 1`` read the same row, with the mapping inverted and the two
+ coverage columns swapped (:meth:`mapping`, :meth:`mappings`,
+ :meth:`coverage`). :meth:`directed` expands the table to one row per
+ direction in memory for joins on query and target.
+
+ The class API works in fractions in [0, 1]; the parquet stores percent.
+ Coverage is the mean of the atom and bond fractions of one molecule matched,
+ see :meth:`RascalParityMatch.coverage`. A table built before the coverage
+ columns existed still loads, but :meth:`coverage` and :meth:`directed` raise
+ until it is rebuilt with :func:`build_ccd_parity_scores`.
+ """
+
+ def __init__(self, rows: pd.DataFrame) -> None:
+ self._rows: dict[tuple[str, str], tuple[float, list[dict[str, str]]]] = {
+ (first, second): (
+ score / 100.0,
+ [dict(zip(one, other)) for one, other in zip(names_1, names_2)],
+ )
+ for first, second, score, names_1, names_2 in rows[
+ [
+ "ccd_id_1",
+ "ccd_id_2",
+ "parity_similarity",
+ "fragment_atoms_1",
+ "fragment_atoms_2",
+ ]
+ ].itertuples(index=False, name=None)
+ if score == score
+ }
+ self._coverage: dict[tuple[str, str], tuple[float, float]] | None = (
+ {
+ (first, second): (one / 100.0, other / 100.0)
+ for first, second, score, one, other in rows[
+ [
+ "ccd_id_1",
+ "ccd_id_2",
+ "parity_similarity",
+ "parity_coverage_1",
+ "parity_coverage_2",
+ ]
+ ].itertuples(index=False, name=None)
+ if score == score
+ }
+ if {"parity_coverage_1", "parity_coverage_2"} <= set(rows.columns)
+ else None
+ )
+
+ @classmethod
+ def load(cls, data_dir: Path) -> CcdParityTable:
+ """The precompiled table of :func:`build_ccd_parity_scores`."""
+ codes = load_ccd_components(data_dir).set_index("ligand_smiles_id")["ccd_id"]
+ table = pd.read_parquet(ccd_parity_path(data_dir))
+ table["ccd_id_1"] = table["ligand_smiles_id_1"].map(codes)
+ table["ccd_id_2"] = table["ligand_smiles_id_2"].map(codes)
+ return cls(table)
+
+ @classmethod
+ def compute(cls, codes: Iterable[str], *, threads: int = 1) -> CcdParityTable:
+ """Match every pair of *codes* now, for small residue sets and tests."""
+ unique = sorted(set(codes))
+ mols = {code: _ccd_named_mol(code) for code in unique}
+ pairs = [(a, b) for k, a in enumerate(unique) for b in unique[k + 1 :]]
+ rows = _parity_rows(
+ [(mols[a], mols[b], True) for a, b in pairs], threads=threads
+ )
+ rows.insert(0, "ccd_id_2", [b for _, b in pairs])
+ rows.insert(0, "ccd_id_1", [a for a, _ in pairs])
+ return cls(rows)
+
+ def _lookup(self, first: str, second: str) -> tuple[float, list[dict[str, str]]]:
+ if (first, second) in self._rows:
+ return self._rows[(first, second)]
+ score, mappings = self._rows.get((second, first), (0.0, []))
+ return score, [{q: p for p, q in mapping.items()} for mapping in mappings]
+
+ def similarity(self, first: str, second: str) -> float:
+ """Node kernel: 1 for identical codes, the table score, 0 when absent."""
+ return 1.0 if first == second else self._lookup(first, second)[0]
+
+ def _coverages(self) -> dict[tuple[str, str], tuple[float, float]]:
+ if self._coverage is None:
+ raise ValueError(
+ "the parity table has no coverage columns; rebuild it with "
+ "build_ccd_parity_scores"
+ )
+ return self._coverage
+
+ def coverage(self, first: str, second: str) -> float:
+ """Fraction of *first* matched by *second*: 1 for identical codes, 0 when absent.
+
+ Directional, unlike :meth:`similarity`: a small molecule inside a larger
+ one is fully covered as *first* and only partly as *second*.
+ """
+ if first == second:
+ return 1.0
+ coverages = self._coverages()
+ if (first, second) in coverages:
+ return coverages[(first, second)][0]
+ return coverages.get((second, first), (0.0, 0.0))[1]
+
+ def directed(self) -> pd.DataFrame:
+ """One row per direction: ``query_ccd_id``, ``target_ccd_id``,
+ ``parity_similarity`` and the ``parity_coverage`` of the query, in [0, 1].
+ """
+ rows = []
+ for (first, second), (one, other) in self._coverages().items():
+ score = self._rows[(first, second)][0]
+ rows += [(first, second, score, one), (second, first, score, other)]
+ return pd.DataFrame(
+ rows,
+ columns=[
+ "query_ccd_id",
+ "target_ccd_id",
+ "parity_similarity",
+ "parity_coverage",
+ ],
+ )
+
+ def mappings(self, first: str, second: str) -> list[dict[str, str]]:
+ """Equally good largest fragments of *first* onto *second*, scored one first."""
+ if first == second:
+ return [{name: name for name in _ccd_heavy_atoms(first)[0]}]
+ return self._lookup(first, second)[1]
+
+ def mapping(self, first: str, second: str) -> dict[str, str]:
+ """The scored fragment of *first* onto *second*; empty when absent."""
+ return next(iter(self.mappings(first, second)), {})
+
+
+def build_ccd_parity_scores(
+ components: pd.DataFrame,
+ data_dir: Path,
+ *,
+ threads: int = 4,
+ batch_size: int = 5000,
+) -> Path:
+ """Score every ECFP4 edge of the CCD universe with :func:`rascal_parity_score`.
+
+ The Tanimoto shards written by :func:`build_ccd_tanimoto_scores` are the
+ prefilter: each unordered pair above the ECFP4 cutoff is scored once, so the
+ graph-based score never runs over the all-pairs matrix. Molecules are built
+ from the CCD atoms so the stored fragment carries CCD atom names, which is
+ what :func:`composite_parity` joins on. A pair with an unbuildable molecule
+ scores NaN rather than being dropped.
+
+ Returns
+ -------
+ Path
+ Parquet with ``ligand_smiles_id_1 < ligand_smiles_id_2``,
+ ``tanimoto_similarity_ecfp4_1024``, ``parity_similarity`` (percent),
+ the directional ``parity_coverage_1`` and ``parity_coverage_2`` (percent
+ of each molecule matched, see :meth:`RascalParityMatch.coverage`) and
+ the largest-fragment atom names ``fragment_atoms_1`` -> ``fragment_atoms_2``.
+ """
+ scores_dir = ccd_dbs_dir(data_dir) / "ligand_scores"
+ edges = pd.concat(
+ [
+ pd.read_parquet(shard)
+ for shard in sorted(scores_dir.glob("ccd_scores_*.parquet"))
+ ],
+ ignore_index=True,
+ )
+ edges = edges[edges["query_ligand_id"] < edges["target_ligand_id"]].rename(
+ columns={
+ "query_ligand_id": "ligand_smiles_id_1",
+ "target_ligand_id": "ligand_smiles_id_2",
+ }
+ )
+ codes = components.set_index("ligand_smiles_id")["ccd_id"]
+ # only residues carry linkages, so only their pairs need alternative fragments
+ linking = components.set_index("ligand_smiles_id")["ccd_type"].str.contains(
+ "LINKING", case=False
+ )
+ edges = edges.sort_values(
+ ["ligand_smiles_id_1", "ligand_smiles_id_2"], ignore_index=True
+ )
+ output_path = ccd_parity_path(data_dir)
+ temporary_path = output_path.with_suffix(".parquet.tmp")
+ temporary_path.unlink(missing_ok=True)
+ schema = pa.schema(
+ [
+ ("ligand_smiles_id_1", pa.int32()),
+ ("ligand_smiles_id_2", pa.int32()),
+ ("tanimoto_similarity_ecfp4_1024", pa.float32()),
+ ("parity_similarity", pa.float64()),
+ ("parity_coverage_1", pa.float64()),
+ ("parity_coverage_2", pa.float64()),
+ ("fragment_atoms_1", pa.list_(pa.list_(pa.string()))),
+ ("fragment_atoms_2", pa.list_(pa.list_(pa.string()))),
+ ]
+ )
+ try:
+ with pq.ParquetWriter(temporary_path, schema) as writer:
+ for start in range(0, len(edges), batch_size):
+ batch = edges.iloc[start : start + batch_size].reset_index(drop=True)
+ pairs = [
+ (
+ _ccd_named_mol(codes[i]),
+ _ccd_named_mol(codes[j]),
+ bool(linking[i] and linking[j]),
+ )
+ for i, j in batch[
+ ["ligand_smiles_id_1", "ligand_smiles_id_2"]
+ ].itertuples(index=False, name=None)
+ ]
+ scored = pd.concat(
+ [batch, _parity_rows(pairs, threads=threads)], axis=1
+ )
+ writer.write_table(
+ pa.Table.from_pandas(scored, schema=schema, preserve_index=False)
+ )
+ if (start // batch_size + 1) % 20 == 0:
+ LOG.info(
+ "build_ccd_parity_scores: scored %s/%s edges",
+ min(start + batch_size, len(edges)),
+ len(edges),
+ )
+ except Exception:
+ temporary_path.unlink(missing_ok=True)
+ raise
+ temporary_path.replace(output_path)
+ LOG.info(f"build_ccd_parity_scores: scored {len(edges)} edges into {output_path}")
+ return output_path
+
+
+def query_ccd_parity(
+ queries: Mapping[str, str],
+ data_dir: Path,
+ *,
+ minimum_similarity: float = 30.0,
+ threads: int = 4,
+) -> pd.DataFrame:
+ """PARITY-like scores of molecules outside the universe against their ECFP4 neighbours.
+
+ Extends the precompiled CCD-vs-CCD table to ligands that only exist at
+ dataset build time (novel molecules, composites through their whole-molecule
+ SMILES): the same Tanimoto prefilter as :func:`query_ccd_tanimoto`, then the
+ same score as :func:`build_ccd_parity_scores` on each hit.
+
+ Returns
+ -------
+ pd.DataFrame
+ :func:`query_ccd_tanimoto` columns plus ``parity_similarity`` and the
+ directional ``parity_coverage_1`` (query) and ``parity_coverage_2``
+ (universe molecule), all percent; best PARITY-like hit first.
+ """
+ hits = query_ccd_tanimoto(queries, data_dir, minimum_similarity=minimum_similarity)
+ from plinder.core.utils.sanitize import mol_from_smiles
+
+ smiles = load_ccd_components(data_dir).set_index("ligand_smiles_id")[
+ "ligand_rdkit_canonical_smiles"
+ ]
+ mols = {value: mol_from_smiles(value) for value in set(hits["query_smiles"])}
+ pairs = [
+ (mols[query], mol_from_smiles(smiles[node]), False)
+ for query, node in hits[["query_smiles", "ligand_smiles_id"]].itertuples(
+ index=False, name=None
+ )
+ ]
+ scored = _parity_rows(pairs, threads=threads)
+ for column in ("parity_similarity", "parity_coverage_1", "parity_coverage_2"):
+ hits[column] = scored[column]
+ return hits.sort_values(
+ ["query_id", "parity_similarity", "ligand_smiles_id"],
+ ascending=[True, False, True],
+ ignore_index=True,
+ )
+
+
+def make_ccd_ligand_dbs(
+ *,
+ data_dir: Path,
+ scratch_dir: Path,
+ threads: int = 4,
+ force_update: bool = False,
+ limit: int | None = None,
+ build_tanimoto_scores: bool = True,
+ build_parity_scores: bool = False,
+ minimum_similarity: float = 30.0,
+) -> Path:
+ """Build CCD-anchored MMP and ECFP4 databases, optionally scoring PARITY.
+
+ Parameters
+ ----------
+ data_dir : Path
+ Release directory; artifacts land in ``/ccd_dbs``.
+ scratch_dir : Path
+ Working area for the mmpdb fragment/index run.
+ threads : int
+ Parallelism for the mmpdb fragmentation and indexing steps.
+ force_update : bool
+ Rebuild even when the manifest matches.
+ limit : int or None
+ Restrict to the first *limit* released components (testing aid).
+ build_tanimoto_scores : bool
+ Build the Tanimoto edges.
+ build_parity_scores : bool
+ Also score every retained CCD pair with PARITY. This is an expensive
+ optional step; targeted PARITY queries remain available separately.
+ minimum_similarity : float
+ ECFP4 Tanimoto percentage cutoff for retained pairs.
+
+ Returns
+ -------
+ Path
+ The ``ccd_dbs`` directory.
+
+ Notes
+ -----
+ The manifest records the component universe, mmpdb version, and score
+ settings. Matching builds reuse their files; changed settings rebuild them.
+ """
+ import json
+
+ from plinder.data.annotations.mmpdb_utils import _mmpdb_version
+
+ output_dir = ccd_dbs_dir(data_dir)
+ output_dir.mkdir(parents=True, exist_ok=True)
+ components_path = output_dir / "ccd_components.parquet"
+ # Written into a ``fingerprints/`` subdirectory so the existing Tanimoto
+ # scorer (which resolves ``/fingerprints/ligands_per_smiles.parquet``
+ # internally) runs against this universe with ``data_dir=ccd_dbs`` and no
+ # change to its signature.
+ ecfp_path = ccd_fingerprint_path(data_dir)
+ mmp_path = output_dir / "ccd_mmp_pairs.parquet"
+ fragments_path = output_dir / "ccd_mmp_fragments.parquet"
+ exclusions_path = output_dir / "ccd_mmp_exclusions.tsv"
+ manifest_path = output_dir / "ccd_dbs.manifest.json"
+
+ components = ccd_component_table(limit=limit)
+ if components.empty:
+ raise ValueError("the CCD component universe is empty")
+ if build_parity_scores and not build_tanimoto_scores:
+ raise ValueError("PARITY scoring requires Tanimoto score shards")
+ manifest = {
+ "ccd_universe_signature": ccd_universe_signature(components),
+ "num_components": int(len(components)),
+ "mmpdb_version": _mmpdb_version(),
+ "minimum_similarity": minimum_similarity,
+ "build_tanimoto_scores": build_tanimoto_scores,
+ "build_parity_scores": build_parity_scores,
+ }
+
+ artifacts: tuple[Path, ...] = (
+ components_path,
+ ecfp_path,
+ mmp_path,
+ fragments_path,
+ exclusions_path,
+ manifest_path,
+ )
+ if build_tanimoto_scores:
+ artifacts += tuple(
+ output_dir / "ligand_scores" / f"ccd_scores_{i:04d}.parquet"
+ for i in range((len(components) + 4_999) // 5_000)
+ )
+ if build_parity_scores:
+ artifacts += (ccd_parity_path(data_dir),)
+ if not force_update and all(path.is_file() for path in artifacts):
+ try:
+ cached = json.loads(manifest_path.read_text())
+ except (OSError, ValueError):
+ cached = None
+ if cached == manifest:
+ LOG.info("make_ccd_ligand_dbs: artifacts already match the build settings")
+ return output_dir
+
+ temporary_components = components_path.with_suffix(".parquet.tmp")
+ temporary_components.unlink(missing_ok=True)
+ components.to_parquet(temporary_components, index=False)
+ temporary_components.replace(components_path)
+
+ build_ccd_ecfp_db(components, ecfp_path)
+ build_ccd_mmp_db(
+ components,
+ mmp_path,
+ scratch_dir=Path(scratch_dir),
+ threads=threads,
+ fragments_path=fragments_path,
+ exclusions_path=exclusions_path,
+ )
+ if build_tanimoto_scores:
+ build_ccd_tanimoto_scores(
+ components,
+ data_dir,
+ minimum_similarity=minimum_similarity,
+ )
+ if build_parity_scores:
+ build_ccd_parity_scores(components, data_dir, threads=threads)
+ manifest_path.write_text(json.dumps(manifest, indent=2, sort_keys=True))
+ LOG.info(f"make_ccd_ligand_dbs: built {len(components)} components -> {output_dir}")
+ return output_dir
+
+
+def ccd_code_sequence(ccd_code: str) -> list[str]:
+ """Ordered component codes of a (possibly composite) ligand code.
+
+ No CCD id contains ``-`` (ids are at most five characters), so splitting on
+ the hyphen recovers the components unambiguously.
+ """
+ return [code for code in str(ccd_code).split("-") if code]
+
+
+# Linear sequence identity is the weak point of composite comparison. It is
+# correct for genuinely linear composites (peptides, oligonucleotides) but wrong
+# in two ways for branched ones, chiefly glycans:
+# 1. A glycan is a tree, not a chain, so linear identity cannot express branch
+# topology - two different topologies over the same residues score 1.0.
+# 2. ``ccd_code`` is the chain's residue order, i.e. one arbitrary traversal.
+# The same glycan deposited with a different residue order linearises
+# differently and scores < 1.0 against itself.
+# Prefer :func:`composite_similarity`, which follows the bond graph instead: a
+# branched composite and the linear reading of its own code string are identical
+# to this function and distinct to that one. This one stays for records that
+# carry only a code string and no structure.
+#
+# TODO: neither comparison is chirality-aware, so stereoisomeric residues are
+# interchangeable here (GLC/GAL/MAN all score 1.0 against each other). That is
+# consistent with the rest of the stack - plinder's ECFP4 fingerprints set
+# ``include_chirality: false`` and MMP fragmentation is likewise achiral - so
+# making this one component stereo-aware would introduce an inconsistency rather
+# than remove one. Revisit only as a stack-wide change: chirality-aware ECFP4
+# does separate stereoisomeric hexoses, which the achiral form scores identical,
+# so the signal is available if the whole similarity stack moves together. Note that MCES (RascalMCES) and distance-geometry bounds matrices
+# were both measured stereo-blind, so neither is a shortcut to it.
+def component_sequence_identity(query: Sequence[str], target: Sequence[str]) -> float:
+ """Fractional identity between two component-code sequences.
+
+ Parameters
+ ----------
+ query, target : sequence of str
+ Ordered CCD component codes, e.g. ``["SER", "TPO", "GLY"]`` for a
+ peptide, ``["DA", "DT", "DG"]`` for DNA, ``["NAG", "BMA"]`` for a glycan.
+
+ Returns
+ -------
+ float
+ Identity in ``[0, 1]``: matched positions over the longer sequence.
+
+ Notes
+ -----
+ Applies to **any covalently-linked biopolymer composite** - peptide, RNA/DNA
+ or oligosaccharide - because in every case the discriminating signal is the
+ component sequence, not the chemistry:
+
+ - mmpdb cuts rotatable single bonds. The peptide backbone amide and the
+ nucleic-acid phosphodiester are both such bonds, so every peptide and
+ every oligonucleotide shatters into the same repeating residue fragments.
+ - ECFP4's radius-2 window is dominated by the repeating backbone motif
+ (``-NH-CO-CH-`` or sugar-phosphate). Nucleic acids are *worse* than
+ peptides here: with only four canonical nucleotides the fingerprint space
+ is far more degenerate than with twenty amino acids.
+ - Worst of all for sugars: plinder builds ECFP4 with
+ ``include_chirality=false``, so hexose stereoisomers (glucose / galactose
+ / mannose) have **identical connectivity and therefore identical
+ fingerprints**. Nothing but the component code separates them.
+
+ Alignment uses :class:`difflib.SequenceMatcher` over tokens, since residue
+ codes are multi-character and the protein-sequence aligners do not apply.
+
+ Caveat: this models a **linear** sequence. Branched glycans are trees
+ flattened into residue order, so identity here is a weak proxy for them -
+ exact-set or topology-aware comparison is more appropriate for branched
+ composites.
+ """
+ query = list(query)
+ target = list(target)
+ if not query or not target:
+ return 0.0
+ matcher = SequenceMatcher(a=query, b=target, autojunk=False)
+ matched = sum(block.size for block in matcher.get_matching_blocks())
+ return matched / max(len(query), len(target))
+
+
+def match_composite_by_sequence(
+ ccd_code: str,
+ reference_codes: Mapping[str, str],
+ *,
+ min_identity: float = 0.8,
+) -> list[tuple[str, float]]:
+ """Rank reference ligands whose component-code sequence matches the query.
+
+ Works for any biopolymer composite (peptide, RNA/DNA, oligosaccharide); see
+ :func:`component_sequence_identity` for why sequence beats chemistry here.
+
+ Parameters
+ ----------
+ ccd_code : str
+ Query ligand code (composite, hyphen-joined).
+ reference_codes : mapping
+ ``{reference_id: ccd_code}`` to compare against.
+ min_identity : float
+ Minimum fractional identity to report.
+
+ Returns
+ -------
+ list of (reference_id, identity)
+ Sorted by descending identity; empty when nothing clears the threshold.
+
+ Notes
+ -----
+ The sequence arm of the matching strategy: name first, chemistry never. Use
+ it instead of fingerprint or MMP similarity for any linked-residue
+ composite.
+ """
+ query_sequence = ccd_code_sequence(ccd_code)
+ if not query_sequence:
+ return []
+ matches: list[tuple[str, float]] = []
+ for reference_id, reference_code in reference_codes.items():
+ identity = component_sequence_identity(
+ query_sequence, ccd_code_sequence(reference_code)
+ )
+ if identity >= min_identity:
+ matches.append((reference_id, identity))
+ matches.sort(key=lambda item: (-item[1], item[0]))
+ return matches
+
+
+class ResidueGraph(NamedTuple):
+ """Rooted residue-level graph of a composite ligand.
+
+ ``labels[i]`` is residue *i*'s CCD code, ``adjacency[i]`` the residues it is
+ covalently bonded to, and ``roots`` the residues that only accept linkages.
+ This is the connectivity ``ccd_code`` cannot express: the code string is one
+ arbitrary traversal, so any comparison built on it is order-dependent and
+ blind to branching.
+
+ The rooting matters as much as the edges. Undirected, a linear and a
+ branched trisaccharide are the same three-node path, so a comparison free to
+ pick its own roots scores them identical. ``roots`` fixes the traversal
+ chemically instead - see :func:`residue_graph_from_atoms`.
+
+ ``donors[i]`` holds the residues donating a linkage into residue *i*, i.e.
+ the edges directed by chemistry. It orients traversal of a macrocycle, which
+ has no terminus to root at, and may be left empty for a graph built without
+ structural information.
+
+ ``atoms[i]`` is the heavy-atom names present in residue *i* and ``links``
+ each inter-residue bond as ``(i, j, atom_in_i, atom_in_j)``; both empty for
+ a graph built without structural information.
+ """
+
+ labels: tuple[str, ...]
+ adjacency: tuple[frozenset[int], ...]
+ roots: tuple[int, ...]
+ donors: tuple[frozenset[int], ...] = ()
+ atoms: tuple[frozenset[str], ...] = ()
+ links: tuple[tuple[int, int, str, str], ...] = ()
+
+ def donors_of(self, residue: int) -> frozenset[int]:
+ """Residues donating a linkage into *residue*, empty when undirected."""
+ return self.donors[residue] if self.donors else frozenset()
+
+ @property
+ def is_connected(self) -> bool:
+ """Whether every residue is reachable from the first one."""
+ if not self.labels:
+ return True
+ seen = {0}
+ stack = [0]
+ while stack:
+ for neighbour in self.adjacency[stack.pop()]:
+ if neighbour not in seen:
+ seen.add(neighbour)
+ stack.append(neighbour)
+ return len(seen) == len(self.labels)
+
+ @property
+ def is_tree(self) -> bool:
+ edges = sum(len(neighbours) for neighbours in self.adjacency) // 2
+ return edges == len(self.labels) - 1 and self.is_connected
+
+
+def residue_graph_from_atoms(atoms: struc.AtomArray) -> ResidueGraph:
+ """Build the rooted residue graph of a ligand from its bond graph.
+
+ Parameters
+ ----------
+ atoms : struc.AtomArray
+ Ligand atoms carrying ``bonds``, as produced by ``build_biounit``.
+
+ Returns
+ -------
+ ResidueGraph
+ Residues as nodes, inter-residue covalent bonds as edges, rooted at the
+ residues that only accept linkages.
+
+ Raises
+ ------
+ ValueError
+ If the atoms carry no bond graph, which is the whole input here.
+
+ Notes
+ -----
+ Linkages are directed by the chemistry of the bond rather than by residue
+ numbering, which is not comparable across entries. In both families plinder
+ sees, one side donates a carbon and the other accepts through a heteroatom:
+ a glycosidic bond runs anomeric ``C1`` into the next ring's oxygen, a
+ peptide bond runs carbonyl ``C`` into the next residue's nitrogen. Directing
+ every linkage donor -> acceptor therefore roots the graph at the reducing
+ end of a glycan and the C-terminus of a peptide, both canonical and both
+ derived from the structure alone.
+
+ Cyclic residue graphs (cyclic peptides, macrocycles) have no such terminus;
+ every residue is then reported as a root, and comparison falls back to the
+ best alignment over root pairs.
+ """
+ import biotite.structure as structure
+
+ if atoms.bonds is None:
+ raise ValueError("residue_graph_from_atoms requires bonded atoms")
+
+ starts = structure.get_residue_starts(atoms, add_exclusive_stop=True)
+ residue_of_atom: dict[int, int] = {}
+ labels: list[str] = []
+ for index, (start, stop) in enumerate(zip(starts[:-1], starts[1:])):
+ labels.append(str(atoms.res_name[start]))
+ for atom_index in range(int(start), int(stop)):
+ residue_of_atom[atom_index] = index
+
+ elements = [str(value).upper() for value in atoms.element]
+ names = [str(value) for value in atoms.atom_name]
+ present: list[set[str]] = [set() for _ in labels]
+ for atom_index, residue in residue_of_atom.items():
+ if elements[atom_index] not in ("H", "D"):
+ present[residue].add(names[atom_index])
+ adjacency: list[set[int]] = [set() for _ in labels]
+ donors: list[set[int]] = [set() for _ in labels]
+ donates: set[int] = set()
+ links: list[tuple[int, int, str, str]] = []
+ for first, second, _ in atoms.bonds.as_array():
+ left = residue_of_atom.get(int(first))
+ right = residue_of_atom.get(int(second))
+ if left is None or right is None or left == right:
+ continue
+ adjacency[left].add(right)
+ adjacency[right].add(left)
+ links.append((left, right, names[int(first)], names[int(second)]))
+ left_element, right_element = elements[int(first)], elements[int(second)]
+ if left_element == "C" and right_element != "C":
+ donates.add(left)
+ donors[right].add(left)
+ elif right_element == "C" and left_element != "C":
+ donates.add(right)
+ donors[left].add(right)
+
+ roots = tuple(index for index in range(len(labels)) if index not in donates)
+ graph = ResidueGraph(
+ tuple(labels),
+ tuple(frozenset(entry) for entry in adjacency),
+ roots or tuple(range(len(labels))),
+ tuple(frozenset(entry) for entry in donors),
+ tuple(frozenset(entry) for entry in present),
+ tuple(links),
+ )
+ if len(labels) > 1 and not graph.is_connected:
+ # plinder builds ligands as connected components of the covalent graph,
+ # so a disconnected result means unrelated residues were passed in
+ # together and any similarity computed from it would be meaningless.
+ LOG.warning(
+ "residue graph is disconnected: %d residues (%s) with no single "
+ "covalent component; these are separate ligands, not a composite",
+ len(labels),
+ "-".join(labels),
+ )
+ return graph
+
+
+def ccd_code_residue_graph(ccd_code: str) -> ResidueGraph:
+ """Residue graph implied by a hyphenated ``ccd_code``, assuming linearity.
+
+ Fallback for records that carry only the code string. It reproduces the
+ linear assumption of :func:`component_sequence_identity`, so prefer
+ :func:`residue_graph_from_atoms` whenever the structure is available.
+ """
+ labels = ccd_code_sequence(ccd_code)
+ adjacency = [
+ frozenset(
+ neighbour
+ for neighbour in (index - 1, index + 1)
+ if 0 <= neighbour < len(labels)
+ )
+ for index in range(len(labels))
+ ]
+ return ResidueGraph(tuple(labels), tuple(adjacency), (0,) if labels else ())
+
+
+def _exact_label_similarity(first: str, second: str) -> float:
+ return 1.0 if first == second else 0.0
+
+
+def _rooted_children(graph: ResidueGraph, root: int) -> tuple[tuple[int, ...], ...]:
+ """Spanning tree from *root*, as a child list per residue.
+
+ Descends against the direction of donation, so from a residue the traversal
+ reaches the residues that donate into it and never the one it donates to.
+ On a tree this reproduces the graph exactly; on a macrocycle, where every
+ residue both donates and accepts, it unrolls the ring into a path whose
+ direction is set by the linkage chemistry rather than by residue numbering,
+ which is what makes the score invariant to rotating the residue order.
+ Edges whose direction is undetermined are traversed either way.
+ """
+ children: list[tuple[int, ...]] = [() for _ in graph.labels]
+ seen = {root}
+ queue = deque([root])
+ while queue:
+ node = queue.popleft()
+ descend = []
+ for neighbour in sorted(graph.adjacency[node]):
+ if neighbour in seen or node in graph.donors_of(neighbour):
+ continue
+ seen.add(neighbour)
+ descend.append(neighbour)
+ queue.append(neighbour)
+ children[node] = tuple(descend)
+ return tuple(children)
+
+
+def _align_rooted(
+ query: ResidueGraph,
+ target: ResidueGraph,
+ children_query: tuple[tuple[int, ...], ...],
+ children_target: tuple[tuple[int, ...], ...],
+ root_query: int,
+ root_target: int,
+ similarity: Callable[[str, str], float],
+) -> tuple[float, list[tuple[int, int]]]:
+ """Best alignment of two spanning trees: summed node score and aligned pairs.
+
+ Each residue match is weighted by how well the two residues' linkage counts
+ agree. The spanning tree necessarily drops any ring-closing edge, so without
+ this a macrocycle and the open chain of the same residues would align
+ perfectly; degree is where that edge survives.
+ """
+ from scipy.optimize import linear_sum_assignment
+
+ memo: dict[tuple[int, int], tuple[float, list[tuple[int, int]]]] = {}
+
+ def linkage_agreement(a: int, b: int) -> float:
+ # Smoothed, so a free residue (degree 0) is merely a poor match for a
+ # linked one rather than an impossible one. An unsmoothed ratio zeroes
+ # that pair outright, which would score every mono-residue ligand 0.0
+ # against every composite containing it - worse than the whole-molecule
+ # fingerprint this is meant to improve on.
+ degree_query = len(query.adjacency[a])
+ degree_target = len(target.adjacency[b])
+ return (1 + min(degree_query, degree_target)) / (
+ 1 + max(degree_query, degree_target)
+ )
+
+ def score(a: int, b: int) -> tuple[float, list[tuple[int, int]]]:
+ cached = memo.get((a, b))
+ if cached is not None:
+ return cached
+ total = similarity(query.labels[a], target.labels[b]) * linkage_agreement(a, b)
+ pairs = [(a, b)]
+ kids_query, kids_target = children_query[a], children_target[b]
+ if kids_query and kids_target:
+ scored = [[score(ca, cb) for cb in kids_target] for ca in kids_query]
+ matrix = np.array([[value for value, _ in row] for row in scored])
+ rows, columns = linear_sum_assignment(-matrix)
+ for row, column in zip(rows, columns):
+ total += float(matrix[row, column])
+ pairs += scored[row][column][1]
+ memo[(a, b)] = (total, pairs)
+ return total, pairs
+
+ return score(root_query, root_target)
+
+
+def _best_alignment(
+ query: ResidueGraph, target: ResidueGraph, similarity: Callable[[str, str], float]
+) -> tuple[float, list[tuple[int, int]]]:
+ """Best root pairing: summed node score and the one-to-one residue pairs.
+
+ A single residue has no topology to orient, so against a composite it is
+ tried at every residue rather than only at the roots.
+ """
+ if not query.labels or not target.labels:
+ return 0.0, []
+ roots_a = query.roots if len(target.labels) > 1 else range(len(query.labels))
+ roots_b = target.roots if len(query.labels) > 1 else range(len(target.labels))
+ return max(
+ (
+ _align_rooted(
+ query,
+ target,
+ _rooted_children(query, root_a),
+ _rooted_children(target, root_b),
+ root_a,
+ root_b,
+ similarity,
+ )
+ for root_a in roots_a
+ for root_b in roots_b
+ ),
+ key=lambda item: item[0],
+ )
+
+
+def composite_similarity(
+ query: ResidueGraph,
+ target: ResidueGraph,
+ *,
+ node_similarity: Callable[[str, str], float] | None = None,
+) -> float:
+ """Similarity of two composite ligands following their connectivity.
+
+ A rooted tree alignment: residues match residues by a node score and
+ subtrees are aligned recursively, each level resolved by an optimal (1:1)
+ assignment between the two child sets. Unlike sequence identity this follows
+ the actual bond graph, so branch topology is respected and the arbitrary
+ residue order in ``ccd_code`` is irrelevant.
+
+ This is *not* Feature Trees (Rarey & Dixon 1998), though it shares the
+ tree-alignment shape and, with a graded ``node_similarity``, the fuzzy node
+ comparison. FTrees' defining step is a split search in which one node may
+ match a contiguous *set* of nodes; matching here is strictly one residue to
+ one residue.
+
+ That 1:1 restriction is a real limitation, not a free simplification. The
+ CCD assigns single codes to molecules that are chemically composites
+ (``LAT`` for the same molecule as ``GAL-BGC``, ``SUC`` for ``GLC-FRU``,
+ ``GSH`` for a tripeptide), so the same chemistry does appear at two
+ granularities, and this function scores such pairs 0.0 - it can only see
+ residue labels, which share nothing across a regrouping.
+
+ This function therefore measures topology agreement *given* a decomposition,
+ and is only meaningful between ligands decomposed comparably. For a measure
+ that does not assume that, use :func:`ligand_features` with
+ :func:`ligand_similarity`, where molecular and residue descriptions share
+ one feature space and the decomposition is not privileged.
+
+ Parameters
+ ----------
+ query, target : ResidueGraph
+ Rooted residue graphs, e.g. from :func:`residue_graph_from_atoms`.
+ node_similarity : callable, optional
+ ``(code_a, code_b) -> [0, 1]``. Defaults to exact CCD-code identity;
+ pass :func:`ccd_node_similarity` to let chemically similar residues
+ match partially, so ``A-TYR-B`` and ``A-PHE-B`` score as near-misses
+ rather than as a plain mismatch. Note that a graded kernel also raises
+ the floor for unrelated composites - every amino acid shares backbone
+ chemistry - so thresholds tuned for exact matching are too permissive
+ under it.
+
+ Returns
+ -------
+ float
+ Score in ``[0, 1]``, normalised by the larger residue count, so a
+ subgraph match is penalised by the residues it leaves unmatched. Each
+ residue match is additionally weighted by how well the two residues'
+ linkage counts agree, which is what separates a macrocycle from the
+ open chain of the same residues.
+
+ Notes
+ -----
+ Only the roots recorded on each graph are tried, which is what keeps a
+ linear and a branched composite distinguishable; a single residue, having
+ no topology, is tried at every residue of the other graph. Residue graphs run to a
+ handful of nodes, so the assignment at each level is negligible.
+
+ Comparison runs over the spanning tree from each root (see
+ :func:`_rooted_children`), so a macrocycle is handled like any other graph
+ rather than recursing around its ring.
+ """
+ best, _ = _best_alignment(query, target, node_similarity or _exact_label_similarity)
+ return best / max(len(query.labels), len(target.labels))
+
+
+def _present_atoms(graph: ResidueGraph, residue: int) -> frozenset[str]:
+ """Heavy atoms of a residue: the structure's when recorded, else the component's."""
+ if graph.atoms:
+ return graph.atoms[residue]
+ return frozenset(_ccd_heavy_atoms(graph.labels[residue])[0])
+
+
+def _present_bonds(graph: ResidueGraph, residue: int) -> int:
+ """Component bonds whose both atoms are present in the residue."""
+ present = _present_atoms(graph, residue)
+ return sum(bond <= present for bond in _ccd_heavy_atoms(graph.labels[residue])[1])
+
+
+def ligand_parity(
+ query: ResidueGraph,
+ target: ResidueGraph,
+ table: CcdParityTable,
+ query_mol: Mol,
+ target_mol: Mol,
+) -> float:
+ """PARITY-like similarity of two ligands, assembled or whole-molecule as fits.
+
+ Two composites are assembled from the mono table by :func:`composite_parity`.
+ When either ligand is a single residue the whole molecules go through
+ :func:`rascal_parity_score`: a mono may span several residues of the other
+ side, which one-to-one residue alignment cannot express, and one molecule
+ of residue size keeps the engine in its fast range.
+ """
+ from plinder.core.structure.smallmols_similarity import rascal_parity_score
+
+ if min(len(query.labels), len(target.labels)) <= 1:
+ return rascal_parity_score(query_mol, target_mol, stereo=False)
+ return composite_parity(query, target, table)
+
+
+def _rewired(mapping: dict[str, str], atom: str, image: str) -> dict[str, str]:
+ """*mapping* with ``atom -> image``, the displaced images swapped to stay one-to-one."""
+ rewired = dict(mapping)
+ holder = next((p for p, q in mapping.items() if q == image), None)
+ if holder is not None:
+ if atom in mapping:
+ rewired[holder] = mapping[atom]
+ else:
+ del rewired[holder]
+ rewired[atom] = image
+ return rewired
+
+
+def _fragment_bonds(first: str, second: str, mapping: dict[str, str]) -> int:
+ """Bonds of *first* inside the fragment whose images are bonds of *second*."""
+ bonds_second = _ccd_heavy_atoms(second)[1]
+ return sum(
+ frozenset(mapping[p] for p in bond) in bonds_second
+ for bond in _ccd_heavy_atoms(first)[1]
+ if bond <= mapping.keys()
+ )
+
+
+def composite_parity(
+ query: ResidueGraph, target: ResidueGraph, table: CcdParityTable
+) -> float:
+ """PARITY-like similarity of two composites assembled from mono-to-mono matches.
+
+ Residues are aligned one-to-one with the table as node kernel; each aligned
+ pair contributes its largest matched fragment, restricted to the atoms the
+ structure actually holds (a linked residue has lost its leaving atom); a
+ linkage counts, and joins the two fragments, only when both mappings carry
+ its atoms onto the partner linkage. The assembled match is a common
+ subgraph of the two molecules, so the score sits at or just below the
+ whole-molecule :func:`rascal_parity_score`. No stereo term, as in PARITY.
+
+ Residues match one-to-one, so a single residue that spans several residues
+ of the other side (chitotriose against NAG-NAG-NAG) is credited for one of
+ them; :func:`ligand_parity` routes such pairs to the whole-molecule engine.
+
+ Where the table holds several equally good fragments for a residue pair,
+ the one carrying the most linkage atoms onto the partner's linkage is taken,
+ then the biggest, then the first in the table's fixed order, so the choice
+ is deterministic and no atom is used twice on either side. A fragment that
+ misses a linkage atom is also tried rewired onto it (a beta1-4 against a
+ beta1-6 chain keeps the chain connected at the cost of the two displaced
+ hydroxyl bonds, as the whole-molecule engine does).
+ """
+ _, pairs = _best_alignment(query, target, table.similarity)
+ partner = dict(pairs)
+ target_links = {(i, j): (p, q) for i, j, p, q in target.links}
+ target_links |= {(j, i): (q, p) for i, j, p, q in target.links}
+ # link atoms each residue should carry onto its partner's linkage
+ wanted: dict[int, dict[str, str]] = {a: {} for a, _ in pairs}
+ for i, j, p, q in query.links:
+ link = target_links.get((partner.get(i, -1), partner.get(j, -1)))
+ if link:
+ wanted[i][p], wanted[j][q] = link
+ fragments: dict[int, dict[str, str]] = {}
+ bonds = 0
+ for a, b in pairs:
+ present_a, present_b = _present_atoms(query, a), _present_atoms(target, b)
+ candidates = [
+ {p: q for p, q in mapping.items() if p in present_a and q in present_b}
+ for mapping in table.mappings(query.labels[a], target.labels[b])
+ ] or [{}]
+ candidates += [
+ _rewired(mapping, p, r)
+ for mapping in list(candidates)
+ for p, r in wanted[a].items()
+ if mapping.get(p) != r and p in present_a and r in present_b
+ ]
+ scored = [
+ (
+ sum(mapping.get(p) == r for p, r in wanted[a].items()),
+ len(mapping),
+ _fragment_bonds(query.labels[a], target.labels[b], mapping),
+ )
+ for mapping in candidates
+ ]
+ best = max(range(len(candidates)), key=lambda k: scored[k])
+ fragments[a] = candidates[best]
+ bonds += scored[best][2]
+ # a matched linkage adds its bond and merges the two fragments it joins
+ joined = {a: a for a in fragments}
+
+ def root(a: int) -> int:
+ while joined[a] != a:
+ a = joined[a]
+ return a
+
+ for i, j, p, q in query.links:
+ if i not in partner or j not in partner:
+ continue
+ link = target_links.get((partner[i], partner[j]))
+ if link and fragments[i].get(p) == link[0] and fragments[j].get(q) == link[1]:
+ bonds += 1
+ joined[root(i)] = root(j)
+ merged: Counter[int] = Counter()
+ for a, mapping in fragments.items():
+ merged[root(a)] += len(mapping)
+ graphs = (query, target)
+ atom_total = sum(
+ len(_present_atoms(g, i)) for g in graphs for i in range(len(g.labels))
+ )
+ bond_total = sum(_present_bonds(g, i) for g in graphs for i in range(len(g.labels)))
+ bond_total += len(query.links) + len(target.links)
+ return parity_similarity(
+ max(merged.values(), default=0), bonds, atom_total, bond_total
+ )
+
+
+@lru_cache(maxsize=8192)
+def _ccd_component_fingerprint(ccd_id: str) -> Any | None:
+ """ECFP4/1024 of one CCD component, cached; None when underivable.
+
+ Uses plinder's own ``mol2morgan_fp`` at the native ECFP4 radius and size, so
+ residue-level similarity here is the same measure the ligand similarity
+ stack uses elsewhere.
+ """
+ from plinder.core.structure.smallmols_similarity import mol2morgan_fp
+ from plinder.data.annotations.get_similarity_scores import (
+ ECFP4_NBITS,
+ ECFP4_RADIUS,
+ )
+
+ smiles = _ccd_smiles(ccd_id)
+ if not smiles:
+ return None
+ try:
+ fingerprint = mol2morgan_fp(smiles, radius=ECFP4_RADIUS, nbits=ECFP4_NBITS)
+ except Exception as exc: # noqa: BLE001 - one bad component must not abort
+ LOG.warning(f"CCD fingerprint failed for {ccd_id}: {exc}")
+ return None
+ return cast("object | None", fingerprint)
+
+
+def ccd_node_similarity(first: str, second: str) -> float:
+ """Graded similarity between two CCD components, for use as a node kernel.
+
+ Pass to :func:`composite_similarity` to let chemically similar residues
+ match partially instead of all-or-nothing, so ``A-TYR-B`` and ``A-PHE-B``
+ score as near-misses rather than as unrelated composites.
+
+ Parameters
+ ----------
+ first, second : str
+ CCD component codes.
+
+ Returns
+ -------
+ float
+ ``1.0`` for identical codes, otherwise the ECFP4/1024 Tanimoto of the
+ two components. ``0.0`` when either has no derivable chemistry, which
+ keeps an unresolvable residue from inventing similarity.
+
+ Notes
+ -----
+ Achiral, like the rest of plinder's fingerprint stack, so stereoisomeric
+ residues score 1.0 against each other - see the TODO above
+ :func:`component_sequence_identity`.
+ """
+ from rdkit import DataStructs
+
+ if first == second:
+ return 1.0
+ left, right = _ccd_component_fingerprint(first), _ccd_component_fingerprint(second)
+ if left is None or right is None:
+ return 0.0
+ return float(DataStructs.TanimotoSimilarity(left, right))
+
+
+def residue_graph_features(graph: ResidueGraph, *, iterations: int = 2) -> Counter[str]:
+ """Weisfeiler-Lehman features of a residue graph.
+
+ Each residue's label is refined by the labels of the residues donating into
+ it and those it donates to, repeatedly; every label seen at every round is a
+ feature. Features depend only on labels and linkage, never on residue
+ numbering, so relabelling a ring or reordering a ``ccd_code`` cannot change
+ them, while a different cyclic order or branch topology does.
+
+ Parameters
+ ----------
+ graph : ResidueGraph
+ Residue graph, from :func:`residue_graph_from_atoms`.
+ iterations : int
+ Refinement rounds. Two reaches each residue's neighbours-of-neighbours,
+ which is the residue-level analogue of ECFP4's radius 2.
+
+ Returns
+ -------
+ Counter of str
+ Feature strings, ``r:``-prefixed to share a space with molecular bits,
+ counted by how many residues carry each. Multiplicity is kept because
+ residue composition is exact and unhashed: a decapeptide genuinely has
+ two alanines where a pentapeptide has one, and a presence-only feature
+ set scores those two molecules identical.
+ """
+ labels = dict(enumerate(graph.labels))
+ features = Counter(f"r:{label}" for label in labels.values())
+ for _ in range(iterations):
+ refined: dict[int, str] = {}
+ for node, label in labels.items():
+ donors = sorted(labels[other] for other in graph.donors_of(node))
+ accepts = sorted(
+ labels[other]
+ for other in graph.adjacency[node]
+ if node in graph.donors_of(other)
+ )
+ undirected = sorted(
+ labels[other]
+ for other in graph.adjacency[node]
+ if other not in graph.donors_of(node)
+ and node not in graph.donors_of(other)
+ )
+ refined[node] = (
+ f"{label}<{','.join(donors)}>{','.join(accepts)}~{','.join(undirected)}"
+ )
+ labels = refined
+ features.update(f"r:{label}" for label in labels.values())
+ return features
+
+
+def ligand_features(smiles: str | None, graph: ResidueGraph | None) -> Counter[str]:
+ """The feature set describing one ligand: molecular bits plus residue graph.
+
+ Both descriptions live in one space, so similarity is a single Tanimoto over
+ whatever each ligand has. Nothing branches on how a ligand was decomposed:
+ the molecular bits are identical for the same chemistry however it was
+ carved into residues, and the residue features add the topology that
+ fingerprints cannot see.
+
+ Parameters
+ ----------
+ smiles : str or None
+ Whole-molecule SMILES (plinder's ``ligand_rdkit_canonical_smiles``).
+ graph : ResidueGraph or None
+ Residue graph, when the structure is available.
+
+ Returns
+ -------
+ Counter of str
+ ``m:``-prefixed molecular bits and ``r:``-prefixed residue features.
+
+ Notes
+ -----
+ Molecular bits are kept presence-only, matching plinder's ECFP4 tables and
+ :func:`~plinder.data.annotations.get_similarity_scores.ligand_scores`, so
+ this measure stays consistent with every other similarity in the codebase.
+ Counting them was measured and rejected: a larger molecule's multiplicities
+ inflate the denominator, sharpening the penalty on any size difference, and
+ since folded bits outnumber residue features it also dilutes the residue
+ signal that separates a resequenced macrocycle. Residue features are counted
+ instead, where multiplicity is exact rather than hashed.
+ """
+ from plinder.core.structure.smallmols_similarity import mol2morgan_fp
+ from plinder.data.annotations.get_similarity_scores import (
+ ECFP4_NBITS,
+ ECFP4_RADIUS,
+ )
+
+ features: Counter[str] = Counter()
+ if smiles:
+ try:
+ fingerprint = mol2morgan_fp(smiles, radius=ECFP4_RADIUS, nbits=ECFP4_NBITS)
+ features.update({f"m:{bit}": 1 for bit in fingerprint.GetOnBits()})
+ except Exception as exc: # noqa: BLE001 - a bad SMILES must not abort
+ LOG.warning(f"molecular features failed for {smiles!r}: {exc}")
+ if graph is not None and graph.labels:
+ features.update(residue_graph_features(graph))
+ return features
+
+
+def ligand_similarity(query: Counter[str], target: Counter[str]) -> float:
+ """Similarity between two :func:`ligand_features` sets.
+
+ ``sum(min) / sum(max)`` over the pooled features - the count-aware form of
+ Tanimoto, which it equals exactly when every count is 1. Counts only enter
+ through the residue features, so a molecule and a tandem repeat of it are no
+ longer identical, while any pair whose residue multiplicities already agree
+ scores exactly as it did presence-only.
+ """
+ if not query or not target:
+ return 0.0
+ shared = set(query) | set(target)
+ lower = sum(min(query.get(key, 0), target.get(key, 0)) for key in shared)
+ upper = sum(max(query.get(key, 0), target.get(key, 0)) for key in shared)
+ return lower / upper if upper else 0.0
diff --git a/src/plinder/data/annotations/cif_utils.py b/src/plinder/data/annotations/cif_utils.py
new file mode 100644
index 000000000..9730a8995
--- /dev/null
+++ b/src/plinder/data/annotations/cif_utils.py
@@ -0,0 +1,2228 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""mmCIF I/O utilities using biotite.
+
+Generic helpers for reading CIF blocks, extracting scalar values and
+category rows, plus ligand bond-order detection and assignment from
+SMILES templates.
+"""
+
+from __future__ import annotations
+
+import logging
+import re
+from collections import defaultdict
+from collections.abc import Iterable, Iterator
+from contextlib import contextmanager
+from functools import cache
+from math import prod
+from pathlib import Path
+from typing import TypedDict
+
+import biotite.structure as struc
+import biotite.structure.info as bt_info
+import biotite.structure.io.pdbx as pdbx
+import numpy as np
+from rdkit import Chem
+
+from plinder.core.structure.smallmols_utils import (
+ mol_assigned_bond_orders_by_template,
+)
+from plinder.core.utils.sanitize import mol_from_smiles
+
+LOG = logging.getLogger(__name__)
+
+
+class EntryTaxonomy(TypedDict):
+ """Taxonomy fields extracted from deposited entry metadata."""
+
+ source_taxonomy_ids: list[int]
+ source_organism_names: list[str]
+ host_taxonomy_ids: list[int]
+ host_organism_names: list[str]
+
+
+# biotite's heavy-atom filter (drops H and D) is the one definition used by
+# both ``plinder.core`` and ``plinder.data``.
+from biotite.structure import filter_heavy # noqa: E402
+
+# ---------------------------------------------------------------------------
+# Generic CIF I/O helpers
+# ---------------------------------------------------------------------------
+
+
+def select_assembly_ids(
+ available: Iterable[str], selected: Iterable[str] | None
+) -> list[str]:
+ """Return a validated assembly subset in caller-provided order."""
+ available_ids = list(dict.fromkeys(str(value) for value in available))
+ if selected is None:
+ return available_ids
+ selected_values = [selected] if isinstance(selected, str) else selected
+ selected_ids = list(dict.fromkeys(str(value) for value in selected_values))
+ if not selected_ids:
+ raise ValueError("assembly_ids must not be empty when provided")
+ missing = sorted(set(selected_ids).difference(available_ids))
+ if missing:
+ raise ValueError(
+ f"requested assembly IDs are absent from the mmCIF: {missing}; "
+ f"available={available_ids}"
+ )
+ return selected_ids
+
+
+def read_mmcif_file(mmcif_filename: Path | str) -> pdbx.CIFFile:
+ """Read an mmCIF file and add unambiguous optional atom-site defaults.
+
+ Handles ``.gz`` transparently.
+
+ Parameters
+ ----------
+ mmcif_filename : Path or str
+ Path to the mmCIF file (optionally gzip-compressed).
+
+ Returns
+ -------
+ pdbx.CIFFile
+ Parsed CIF file with the optional atom-site defaults filled in.
+ """
+ import gzip
+
+ path = str(mmcif_filename)
+ if path.endswith(".gz"):
+ with gzip.open(path, "rt", encoding="utf-8") as f:
+ cif_file = pdbx.CIFFile.read(f)
+ else:
+ cif_file = pdbx.CIFFile.read(path)
+ for block in cif_file.values():
+ if "atom_site" not in block:
+ continue
+ atom_site = block["atom_site"]
+ atom_count = atom_site.row_count
+ if "pdbx_PDB_model_num" not in atom_site:
+ atom_site["pdbx_PDB_model_num"] = np.ones(atom_count, dtype=np.int32)
+ if "pdbx_PDB_ins_code" not in atom_site:
+ atom_site["pdbx_PDB_ins_code"] = ["."] * atom_count
+ return cif_file
+
+
+def check_custom_mmcif_fields(
+ block: pdbx.CIFBlock,
+ *,
+ source: Path,
+ structure_mode: str,
+ require_label_ids: bool = False,
+) -> None:
+ """Check fields required to read custom coordinates and assemblies.
+
+ Model number and insertion code are optional for a single-model custom
+ structure and receive unambiguous defaults. Deposited-PDB mode additionally
+ requires the assembly operation tables. Other deposition metadata (authors,
+ citations, experimental details, and validation categories) is not required.
+ """
+ if "atom_site" not in block:
+ raise ValueError(f"custom mmCIF {source} has no _atom_site category")
+ atom_site = block["atom_site"]
+ required_columns = {
+ "group_PDB",
+ "type_symbol",
+ "Cartn_x",
+ "Cartn_y",
+ "Cartn_z",
+ }
+ missing = sorted(required_columns.difference(atom_site))
+ if require_label_ids:
+ label_columns = {
+ "label_atom_id",
+ "label_comp_id",
+ "label_asym_id",
+ "label_seq_id",
+ }
+ missing.extend(sorted(label_columns.difference(atom_site)))
+ missing_identifiers: list[str] = []
+ else:
+ identifier_pairs = {
+ "atom name": ("label_atom_id", "auth_atom_id"),
+ "residue name": ("label_comp_id", "auth_comp_id"),
+ "chain ID": ("label_asym_id", "auth_asym_id"),
+ "residue number": ("label_seq_id", "auth_seq_id"),
+ }
+ missing_identifiers = [
+ f"{description} ({first} or {second})"
+ for description, (first, second) in identifier_pairs.items()
+ if first not in atom_site and second not in atom_site
+ ]
+ if missing or missing_identifiers:
+ details = [f"_atom_site.{column}" for column in missing]
+ details.extend(missing_identifiers)
+ raise ValueError(
+ f"custom mmCIF {source} is missing required coordinate fields: "
+ + ", ".join(details)
+ )
+
+ atom_count = atom_site.row_count
+ if "pdbx_PDB_model_num" not in atom_site:
+ atom_site["pdbx_PDB_model_num"] = np.ones(atom_count, dtype=np.int32)
+ if "pdbx_PDB_ins_code" not in atom_site:
+ atom_site["pdbx_PDB_ins_code"] = ["."] * atom_count
+
+ if structure_mode != "pdb":
+ if structure_mode != "as_is":
+ raise ValueError("structure_mode must be 'as_is' or 'pdb'")
+ return
+ if "label_asym_id" not in atom_site:
+ raise ValueError(
+ f"custom mmCIF {source} needs _atom_site.label_asym_id in pdb mode "
+ "because assembly definitions reference label asym IDs"
+ )
+ assembly_fields = {
+ "pdbx_struct_assembly_gen": {
+ "assembly_id",
+ "oper_expression",
+ "asym_id_list",
+ },
+ "pdbx_struct_oper_list": {
+ "id",
+ "matrix[1][1]",
+ "matrix[1][2]",
+ "matrix[1][3]",
+ "matrix[2][1]",
+ "matrix[2][2]",
+ "matrix[2][3]",
+ "matrix[3][1]",
+ "matrix[3][2]",
+ "matrix[3][3]",
+ "vector[1]",
+ "vector[2]",
+ "vector[3]",
+ },
+ }
+ missing_assembly_fields: list[str] = []
+ for category_name, columns in assembly_fields.items():
+ if category_name not in block:
+ missing_assembly_fields.append(f"_{category_name}")
+ continue
+ missing_assembly_fields.extend(
+ f"_{category_name}.{column}"
+ for column in sorted(columns.difference(block[category_name]))
+ )
+ if missing_assembly_fields:
+ raise ValueError(
+ f"custom mmCIF {source} is missing fields required by pdb mode: "
+ + ", ".join(missing_assembly_fields)
+ + "; use structure_mode='as_is' for an already assembled model"
+ )
+
+
+def read_mmcif_container(mmcif_filename: Path) -> pdbx.CIFBlock:
+ """Parse an mmCIF file and return its first data block.
+
+ Parameters
+ ----------
+ mmcif_filename : Path
+ Path to the mmCIF file.
+
+ Returns
+ -------
+ pdbx.CIFBlock
+ The first data block.
+ """
+ cif_file = read_mmcif_file(mmcif_filename)
+ return list(cif_file.values())[0]
+
+
+def _alphabetic_id(index: int) -> str:
+ """Return a deterministic spreadsheet-style alphabetic identifier."""
+ value = index + 1
+ result = ""
+ while value:
+ value, remainder = divmod(value - 1, 26)
+ result = chr(ord("A") + remainder) + result
+ return result
+
+
+@contextmanager
+def _alphabetic_altloc_ids(
+ cif_file: pdbx.CIFFile | pdbx.CIFBlock,
+) -> Iterator[dict[str, str]]:
+ """Temporarily map non-alphabetic altloc IDs for Biotite filtering.
+
+ Restored on exit; a no-op when all altloc IDs are already alphabetic.
+ """
+ block = (
+ cif_file if isinstance(cif_file, pdbx.CIFBlock) else list(cif_file.values())[0]
+ )
+ specifications = [
+ ("atom_site", "label_alt_id"),
+ ("struct_conn", "pdbx_ptnr1_label_alt_id"),
+ ("struct_conn", "pdbx_ptnr2_label_alt_id"),
+ ]
+ columns: list[tuple[pdbx.CIFCategory, str, pdbx.CIFColumn]] = []
+ all_ids: set[str] = set()
+ for category_name, column_name in specifications:
+ if category_name not in block or column_name not in block[category_name]:
+ continue
+ category = block[category_name]
+ column = category[column_name]
+ columns.append((category, column_name, column))
+ all_ids.update(column.as_array(str))
+
+ no_altloc = {".", "?", " ", ""}
+ invalid_ids = sorted(
+ altloc_id
+ for altloc_id in all_ids
+ if altloc_id not in no_altloc and not altloc_id.isalpha()
+ )
+ if not invalid_ids:
+ yield {}
+ return
+
+ used_ids = {altloc_id for altloc_id in all_ids if altloc_id.isalpha()}
+ mapping: dict[str, str] = {}
+ candidate_index = 0
+ for invalid_id in invalid_ids:
+ while (candidate := _alphabetic_id(candidate_index)) in used_ids:
+ candidate_index += 1
+ mapping[invalid_id] = candidate
+ used_ids.add(candidate)
+ candidate_index += 1
+
+ try:
+ for category, column_name, original in columns:
+ values = original.as_array(str)
+ mapped = [mapping.get(value, value) for value in values]
+ category[column_name] = pdbx.CIFColumn(mapped, mask=original.mask)
+ yield mapping
+ finally:
+ for category, column_name, original in columns:
+ category[column_name] = original
+
+
+@contextmanager
+def _branched_residue_numbering(
+ cif_file: pdbx.CIFFile | pdbx.CIFBlock,
+) -> Iterator[None]:
+ """Temporarily number branched-entity residues from ``pdbx_branch_scheme``.
+
+ Restored on exit; a no-op when the CIF has no branched entities.
+
+ Notes
+ -----
+ Branched entities (glycans) leave ``atom_site.label_seq_id`` undefined
+ (``"."``), so biotite (``use_author_fields=False``) collapses all their
+ residues onto one ``res_id`` and cross-links the sugars. The deposited file
+ numbers them canonically in ``pdbx_branch_scheme.num``; we copy that into
+ ``label_seq_id`` so biotite builds distinct residues with correct bonds.
+
+ We restore ``label_seq_id`` on exit because ligand-chain detection keys on
+ the undefined value to tell polymers from branched ligands (see
+ ``protein_utils.detect_ligand_chains_from_cif``).
+ """
+ block = (
+ cif_file if isinstance(cif_file, pdbx.CIFBlock) else list(cif_file.values())[0]
+ )
+ if "pdbx_branch_scheme" not in block or "atom_site" not in block:
+ yield
+ return
+ branch = block["pdbx_branch_scheme"]
+ if not {"asym_id", "auth_seq_num", "num"}.issubset(branch):
+ yield
+ return
+
+ num_by_key = {
+ (asym_id, auth_seq_num): num
+ for asym_id, auth_seq_num, num in zip(
+ branch["asym_id"].as_array(str),
+ branch["auth_seq_num"].as_array(str),
+ branch["num"].as_array(str),
+ )
+ }
+ atom_site = block["atom_site"]
+ label_asym_ids = atom_site["label_asym_id"].as_array(str)
+ auth_seq_ids = atom_site["auth_seq_id"].as_array(str)
+ original = atom_site["label_seq_id"]
+ patched = original.as_array(str).copy()
+ changed = False
+ for index in range(len(label_asym_ids)):
+ num = num_by_key.get((label_asym_ids[index], auth_seq_ids[index]))
+ if num is not None:
+ patched[index] = num
+ changed = True
+ if not changed:
+ yield
+ return
+ try:
+ atom_site["label_seq_id"] = pdbx.CIFColumn(patched)
+ yield
+ finally:
+ atom_site["label_seq_id"] = original
+
+
+def get_structure_with_altloc(
+ cif_file: pdbx.CIFFile | pdbx.CIFBlock,
+ *,
+ model: int = 1,
+ use_author_fields: bool = False,
+ include_bonds: bool = False,
+ extra_fields: list[str] | None = None,
+) -> struc.AtomArray:
+ """Load one model using its deposited-first alternate conformers.
+
+ Parameters
+ ----------
+ cif_file : pdbx.CIFFile or pdbx.CIFBlock
+ Source mmCIF.
+ model : int, default=1
+ Model number to load.
+ use_author_fields : bool, default=False
+ Use author chain/residue numbering instead of the label fields.
+ include_bonds : bool, default=False
+ Read the bond graph (``_chem_comp_bond`` plus inferred inter-residue
+ bonds).
+ extra_fields : list[str] or None
+ Additional ``atom_site`` annotations to carry onto the array.
+
+ Returns
+ -------
+ struc.AtomArray
+ The single model, with a ``selected_altloc_id`` annotation.
+
+ Raises
+ ------
+ TypeError
+ If loading a single model does not return an ``AtomArray``.
+
+ Notes
+ -----
+ Biotite only recognizes alphabetic alternate-location IDs while filtering.
+ Non-alphabetic source IDs are therefore mapped temporarily, then restored
+ on the returned ``selected_altloc_id`` annotation so validation can select
+ the exact same deposited conformer.
+
+ TODO: discuss switching to highest-occupancy selection (``altloc="occupancy"``)
+ instead of deposited-first. Occupancy is the crystallographer's quantitative
+ statement of the dominant conformer, so it may be more principled โ but it is
+ a deliberate deposited-first choice today, and the switch would change
+ coordinates (hence bonds/interactions/validation) for altloc-heavy entries,
+ can stitch per-residue occupancy picks across correlated altloc states, and
+ biotite's ``altloc="occupancy"`` raises when a CIF has no occupancy column
+ (predicted/custom CIFs) so it must fall back to ``"first"`` there.
+ """
+ requested_extra_fields = list(extra_fields or [])
+ block = cif_file if isinstance(cif_file, pdbx.CIFBlock) else cif_file.block
+ if (
+ "pdbx_formal_charge" in block["atom_site"]
+ and "charge" not in requested_extra_fields
+ ):
+ requested_extra_fields.append("charge")
+ include_label_alt_id = "label_alt_id" in requested_extra_fields
+ if not include_label_alt_id:
+ requested_extra_fields.append("label_alt_id")
+ with (
+ _alphabetic_altloc_ids(cif_file) as mapping,
+ _branched_residue_numbering(cif_file),
+ ):
+ atoms = pdbx.get_structure(
+ cif_file,
+ model=model,
+ altloc="first",
+ use_author_fields=use_author_fields,
+ include_bonds=include_bonds,
+ extra_fields=requested_extra_fields,
+ )
+ if not isinstance(atoms, struc.AtomArray):
+ raise TypeError("loading one mmCIF model must return an AtomArray")
+ inverse_mapping = {mapped: source for source, mapped in mapping.items()}
+ source_altloc_ids = np.asarray(
+ [inverse_mapping.get(value, value) for value in atoms.label_alt_id]
+ )
+ # ``label_alt_id`` is atom-level: atoms shared by all conformers retain
+ # ``.``. Record the selected source conformer on every atom in the
+ # residue so the choice survives subsequent hydrogen removal and can be
+ # used to select the matching validation record.
+ selected_altloc_ids = np.full(len(atoms), ".", dtype=source_altloc_ids.dtype)
+ residue_starts = struc.get_residue_starts(atoms, add_exclusive_stop=True)
+ for start, stop in zip(residue_starts[:-1], residue_starts[1:]):
+ selected = next(
+ (
+ altloc_id
+ for altloc_id in source_altloc_ids[start:stop]
+ if altloc_id not in {".", "?", " ", ""}
+ ),
+ ".",
+ )
+ selected_altloc_ids[start:stop] = selected
+ atoms.set_annotation("selected_altloc_id", selected_altloc_ids)
+ if not include_label_alt_id:
+ atoms.del_annotation("label_alt_id")
+ return atoms
+
+
+def get_unit_cell_with_altloc(
+ cif_file: pdbx.CIFFile,
+ *,
+ model: int = 1,
+ use_author_fields: bool = False,
+) -> struc.AtomArray:
+ """Build a unit cell using normalized deposited-first altlocs.
+
+ Parameters
+ ----------
+ cif_file : pdbx.CIFFile
+ Source mmCIF.
+ model : int, default=1
+ Model number to expand.
+ use_author_fields : bool, default=False
+ Use author chain/residue numbering instead of the label fields.
+
+ Returns
+ -------
+ struc.AtomArray
+ The unit-cell atoms.
+
+ Raises
+ ------
+ TypeError
+ If loading the unit cell does not return an ``AtomArray``.
+ """
+ with _alphabetic_altloc_ids(cif_file), _branched_residue_numbering(cif_file):
+ atoms = pdbx.get_unit_cell(
+ cif_file,
+ model=model,
+ altloc="first",
+ use_author_fields=use_author_fields,
+ )
+ if not isinstance(atoms, struc.AtomArray):
+ raise TypeError("loading one mmCIF unit-cell model must return an AtomArray")
+ return atoms
+
+
+def get_label_asym_sequences(
+ block: pdbx.CIFBlock, column: str = "pdbx_seq_one_letter_code_can"
+) -> dict[str, str]:
+ """Extract polymer sequences keyed by label asym ID.
+
+ Parameters
+ ----------
+ block : pdbx.CIFBlock
+ Source mmCIF data block.
+ column : str
+ ``entity_poly`` sequence column; the default is the canonical one-letter
+ code, ``pdbx_seq_one_letter_code`` keeps modified residues as ``(CCD)``.
+
+ Returns
+ -------
+ dict[str, str]
+ Sequence keyed by ``label_asym_id`` (empty when the required categories
+ are absent).
+
+ Notes
+ -----
+ ``entity_poly.pdbx_strand_id`` contains author chain IDs and therefore
+ cannot be used for reconstructed biological assemblies, whose chain IDs
+ are ``.``. The stable mapping is
+ ``struct_asym.id -> struct_asym.entity_id -> entity_poly.entity_id``.
+ """
+ if "struct_asym" not in block or "entity_poly" not in block:
+ return {}
+ struct_asym = block["struct_asym"]
+ entity_poly = block["entity_poly"]
+ if not {"id", "entity_id"}.issubset(struct_asym):
+ return {}
+ if not {"entity_id", column}.issubset(entity_poly):
+ return {}
+
+ entity_sequences = {
+ str(entity_id): "".join(str(sequence).replace(";", "").split())
+ for entity_id, sequence in zip(
+ entity_poly["entity_id"].as_array(),
+ entity_poly[column].as_array(),
+ )
+ }
+ return {
+ str(asym_id): entity_sequences[str(entity_id)]
+ for asym_id, entity_id in zip(
+ struct_asym["id"].as_array(),
+ struct_asym["entity_id"].as_array(),
+ )
+ if str(entity_id) in entity_sequences
+ }
+
+
+def get_entry_taxonomy(
+ block: pdbx.CIFBlock,
+) -> EntryTaxonomy:
+ """Extract distinct source and expression-host organisms for an entry."""
+ source_taxonomy_ids: set[int] = set()
+ source_organism_names: set[str] = set()
+ host_taxonomy_ids: set[int] = set()
+ host_organism_names: set[str] = set()
+
+ def add_values(
+ category_name: str,
+ taxonomy_column: str,
+ organism_column: str,
+ taxonomy_ids: set[int],
+ organism_names: set[str],
+ ) -> None:
+ if category_name not in block:
+ return
+ category = block[category_name]
+ if taxonomy_column in category:
+ for value in category[taxonomy_column].as_array(str):
+ text = str(value).strip()
+ if text in {"", ".", "?"}:
+ continue
+ try:
+ taxonomy_ids.add(int(text))
+ except ValueError:
+ LOG.warning(
+ "ignoring non-integer %s.%s value %r",
+ category_name,
+ taxonomy_column,
+ text,
+ )
+ if organism_column in category:
+ organism_names.update(
+ text
+ for value in category[organism_column].as_array(str)
+ if (text := str(value).strip()) not in {"", ".", "?"}
+ )
+
+ add_values(
+ "entity_src_gen",
+ "pdbx_gene_src_ncbi_taxonomy_id",
+ "pdbx_gene_src_scientific_name",
+ source_taxonomy_ids,
+ source_organism_names,
+ )
+ add_values(
+ "entity_src_nat",
+ "pdbx_ncbi_taxonomy_id",
+ "pdbx_organism_scientific",
+ source_taxonomy_ids,
+ source_organism_names,
+ )
+ add_values(
+ "pdbx_entity_src_syn",
+ "ncbi_taxonomy_id",
+ "organism_scientific",
+ source_taxonomy_ids,
+ source_organism_names,
+ )
+ add_values(
+ "entity_src_gen",
+ "pdbx_host_org_ncbi_taxonomy_id",
+ "pdbx_host_org_scientific_name",
+ host_taxonomy_ids,
+ host_organism_names,
+ )
+ return {
+ "source_taxonomy_ids": sorted(source_taxonomy_ids),
+ "source_organism_names": sorted(source_organism_names),
+ "host_taxonomy_ids": sorted(host_taxonomy_ids),
+ "host_organism_names": sorted(host_organism_names),
+ }
+
+
+def get_mmcif_revision(block: pdbx.CIFBlock) -> tuple[int, int]:
+ """Return the latest structure-model major/minor revision in an mmCIF.
+
+ Parameters
+ ----------
+ block : pdbx.CIFBlock
+ Source mmCIF data block.
+
+ Returns
+ -------
+ tuple[int, int]
+ The ``(major, minor)`` revision of the latest structure-model entry.
+
+ Raises
+ ------
+ ValueError
+ If the revision-history category or its columns are missing, or it has
+ no structure-model revisions.
+ """
+ category_name = "pdbx_audit_revision_history"
+ if category_name not in block:
+ raise ValueError(f"mmCIF has no {category_name} category")
+ category = block[category_name]
+ required = {"major_revision", "minor_revision"}
+ if not required.issubset(category):
+ raise ValueError(f"mmCIF {category_name} has no revision columns")
+
+ major = category["major_revision"].as_array()
+ minor = category["minor_revision"].as_array()
+ rows = list(range(len(major)))
+ if "data_content_type" in category:
+ content_type = category["data_content_type"].as_array()
+ rows = [
+ index
+ for index, value in enumerate(content_type)
+ if str(value).lower() == "structure model"
+ ]
+ if not rows:
+ raise ValueError(f"mmCIF {category_name} has no structure-model revisions")
+ return max((int(major[index]), int(minor[index])) for index in rows)
+
+
+def get_model_count(cif_file: pdbx.CIFFile) -> int:
+ """Return the number of models in a CIF (1 if no model column present).
+
+ Parameters
+ ----------
+ cif_file : pdbx.CIFFile
+ Source mmCIF.
+
+ Returns
+ -------
+ int
+ Number of models (0 if there is no ``atom_site`` category).
+ """
+ block = list(cif_file.values())[0]
+ if "atom_site" not in block:
+ return 0
+ atom_site = block["atom_site"]
+ if "pdbx_PDB_model_num" not in atom_site:
+ return 1
+ return int(len(set(atom_site["pdbx_PDB_model_num"].as_array())))
+
+
+def _operation_expression_count(expression: str) -> int:
+ """Count transformations encoded by an assembly operation expression."""
+ groups = re.findall(r"\(([^()]*)\)", expression)
+ if not groups:
+ groups = [expression]
+ group_sizes = []
+ for group in groups:
+ size = 0
+ for token in group.split(","):
+ token = token.strip()
+ if not token:
+ continue
+ if "-" in token:
+ first, last = token.split("-", maxsplit=1)
+ size += int(last) - int(first) + 1
+ else:
+ size += 1
+ if size == 0:
+ raise ValueError(f"empty assembly operation group in {expression!r}")
+ group_sizes.append(size)
+ return prod(group_sizes)
+
+
+def get_legacy_chain_instance_mapping(
+ cif_file: pdbx.CIFFile | pdbx.CIFBlock,
+ assembly_id: str,
+) -> dict[str, str]:
+ """Map canonical per-asym instance IDs to historical global-copy IDs.
+
+ The canonical Biotite representation numbers transformed copies separately
+ for each label asym ID. Earlier Plinder releases used OpenStructure, which
+ numbered every generated transformation globally across assembly rows.
+ This mapping preserves those historical identifiers as lookup aliases.
+ """
+ block = (
+ cif_file if isinstance(cif_file, pdbx.CIFBlock) else list(cif_file.values())[0]
+ )
+ category_name = "pdbx_struct_assembly_gen"
+ if category_name not in block:
+ return {}
+ category = block[category_name]
+ required = {"assembly_id", "oper_expression", "asym_id_list"}
+ if not required.issubset(category):
+ return {}
+
+ mapping: dict[str, str] = {}
+ per_asym_offset: defaultdict[str, int] = defaultdict(int)
+ global_offset = 0
+ for row_assembly_id, expression, asym_id_list in zip(
+ category["assembly_id"].as_array(str),
+ category["oper_expression"].as_array(str),
+ category["asym_id_list"].as_array(str),
+ ):
+ if str(row_assembly_id) != str(assembly_id):
+ continue
+ operation_count = _operation_expression_count(str(expression))
+ asym_ids = [value.strip() for value in str(asym_id_list).split(",")]
+ for asym_id in asym_ids:
+ if not asym_id:
+ continue
+ local_offset = per_asym_offset[asym_id]
+ for operation_index in range(operation_count):
+ canonical = f"{local_offset + operation_index + 1}.{asym_id}"
+ legacy = f"{global_offset + operation_index + 1}.{asym_id}"
+ mapping[canonical] = legacy
+ per_asym_offset[asym_id] += operation_count
+ global_offset += operation_count
+ return mapping
+
+
+def drop_self_clashing_symmetry_copies(
+ assembly: struc.AtomArray,
+ *,
+ clash_distance: float = 1.0,
+ clash_ratio: float = 0.5,
+ context: str = "assembly",
+) -> struc.AtomArray:
+ """Drop coincident symmetry copies and severely overlapping protein chains.
+
+ Chains on a symmetry axis can expand into coincident copies of one
+ ``label_asym_id``. Copies are visited in ascending ``sym_id``; one is
+ dropped when more than ``clash_ratio`` of its atoms lie within
+ ``clash_distance`` of an already kept copy. Waters are untouched.
+ Protein chains from different source asym IDs are also compared by their
+ C-alpha atoms: a chain is removed if at least five and more than 10%, or
+ at least twenty regardless of chain length, lie within 2 ร of previously
+ retained protein chains. Such C-alpha distances are nonphysical for
+ separate chains. Requires the ``sym_id`` and ``label_asym_id`` annotations.
+ """
+ categories = set(assembly.get_annotation_categories())
+ if not {"sym_id", "label_asym_id"}.issubset(categories):
+ return assembly
+ candidates = ~struc.filter_solvent(assembly) & np.isfinite(assembly.coord).all(
+ axis=1
+ )
+ keep = np.ones(assembly.array_length(), dtype=bool)
+ for asym_id in np.unique(assembly.label_asym_id[candidates]):
+ indices = np.flatnonzero(candidates & (assembly.label_asym_id == asym_id))
+ copies = assembly[indices]
+ sym_ids = np.unique(copies.sym_id)
+ if len(sym_ids) < 2:
+ continue
+ cell_list = struc.CellList(copies, cell_size=max(clash_distance, 3.0))
+ kept: list[int] = []
+ dropped: list[tuple[int, float]] = []
+ for sym_id in sorted(int(value) for value in sym_ids):
+ copy_mask = copies.sym_id == sym_id
+ if kept:
+ neighbors = cell_list.get_atoms(
+ copies.coord[copy_mask], radius=clash_distance
+ )
+ neighbor_syms = np.where(
+ neighbors >= 0, copies.sym_id[np.clip(neighbors, 0, None)], -1
+ )
+ clashing = np.isin(neighbor_syms, kept).any(axis=1)
+ fraction = float(clashing.mean())
+ if fraction > clash_ratio:
+ keep[indices[copy_mask]] = False
+ dropped.append((sym_id, fraction))
+ continue
+ kept.append(sym_id)
+ if dropped:
+ LOG.info(
+ "%s: dropped %d self-clashing symmetry copies of chain %s "
+ "(sym_id, clash fraction): %s",
+ context,
+ len(dropped),
+ asym_id,
+ [(sym_id, round(fraction, 2)) for sym_id, fraction in dropped],
+ )
+ ca_indices = np.flatnonzero(
+ keep
+ & candidates
+ & (assembly.atom_name == "CA")
+ & struc.filter_amino_acids(assembly)
+ )
+ if len(ca_indices):
+ ca = assembly[ca_indices]
+ chain_names = np.array(
+ [
+ f"{int(sym_id)}.{asym_id}"
+ for sym_id, asym_id in zip(ca.sym_id, ca.label_asym_id, strict=True)
+ ]
+ )
+ unique_chains, chain_index = np.unique(chain_names, return_inverse=True)
+ chain_sizes = np.bincount(chain_index)
+ eligible = [index for index, size in enumerate(chain_sizes) if size >= 10]
+ if len(eligible) > 1:
+ cell_list = struc.CellList(ca, cell_size=3.0)
+ retained: list[int] = []
+ dropped_chains: list[tuple[str, int, float]] = []
+ for index in sorted(
+ eligible,
+ key=lambda value: (
+ int(unique_chains[value].split(".", 1)[0]),
+ unique_chains[value],
+ ),
+ ):
+ query_mask = chain_index == index
+ if retained:
+ neighbors = cell_list.get_atoms(ca.coord[query_mask], radius=2.0)
+ clashing = (
+ (neighbors >= 0)
+ & np.isin(chain_index[np.clip(neighbors, 0, None)], retained)
+ ).any(axis=1)
+ fraction = float(clashing.mean())
+ clash_count = int(clashing.sum())
+ if clash_count >= 20 or (clash_count >= 5 and fraction > 0.1):
+ sym_id, asym_id = unique_chains[index].split(".", 1)
+ keep &= ~(
+ (assembly.sym_id == int(sym_id))
+ & (assembly.label_asym_id == asym_id)
+ )
+ dropped_chains.append(
+ (str(unique_chains[index]), clash_count, fraction)
+ )
+ continue
+ retained.append(index)
+ if dropped_chains:
+ LOG.info(
+ "%s: dropped %d clashing protein chains (first 10 chain, "
+ "C-alpha clash count, fraction): %s",
+ context,
+ len(dropped_chains),
+ [
+ (chain, count, round(fraction, 2))
+ for chain, count, fraction in dropped_chains[:10]
+ ],
+ )
+ if keep.all():
+ return assembly
+ return assembly[keep]
+
+
+def build_biounit(
+ cif_file: pdbx.CIFFile,
+ assembly_id: str,
+) -> struc.AtomArray:
+ """Build a biological assembly with stable ``instance.asym`` chain IDs.
+
+ Parameters
+ ----------
+ cif_file : pdbx.CIFFile
+ Source mmCIF to build the assembly from.
+ assembly_id : str
+ Identifier of the biological assembly to construct.
+
+ Returns
+ -------
+ struc.AtomArray
+ Heavy-atom assembly with ``.`` chain IDs and an
+ intra/inter-residue bond graph.
+
+ Raises
+ ------
+ ValueError
+ If biotite returns no bonds despite ``include_bonds=True``.
+
+ Notes
+ -----
+ Biotite's ``sym_id`` enumerates transformed copies independently for each
+ source asym chain. Using it avoids assuming that an assembly consists of
+ complete, contiguous ASU-sized blocks, which is false when operators apply
+ to only a subset of chains.
+
+ Branched entities are renumbered (:func:`_branched_residue_numbering`) before
+ building so biotite gives their residues distinct ``res_id`` values, and any
+ non-physical bonds biotite's inference still emits are then dropped
+ (:func:`remove_nonphysical_bonds`). Copies generated on top of each other
+ by a symmetry axis are reduced to one
+ (:func:`drop_self_clashing_symmetry_copies`).
+ """
+ block = (
+ cif_file if isinstance(cif_file, pdbx.CIFBlock) else list(cif_file.values())[0]
+ )
+ extra_fields = ["label_asym_id"]
+ if "auth_seq_id" in block["atom_site"]:
+ extra_fields.append("auth_seq_id") # residue_address of unresolved atoms
+ with _alphabetic_altloc_ids(cif_file), _branched_residue_numbering(cif_file):
+ biounit = pdbx.get_assembly(
+ cif_file,
+ assembly_id=assembly_id,
+ model=1,
+ altloc="first",
+ use_author_fields=False,
+ include_bonds=True,
+ extra_fields=extra_fields,
+ )
+ biounit = biounit[filter_heavy(biounit)]
+ biounit = drop_self_clashing_symmetry_copies(
+ biounit, context=f"assembly {assembly_id}"
+ )
+ if biounit.bonds is None:
+ raise ValueError(
+ f"assembly {assembly_id}: biotite returned no bonds despite "
+ "include_bonds=True"
+ )
+ biounit.chain_id = np.asarray(
+ [
+ f"{int(sym_id) + 1}.{asym_id}"
+ for sym_id, asym_id in zip(biounit.sym_id, biounit.label_asym_id)
+ ]
+ )
+ legacy_mapping = get_legacy_chain_instance_mapping(cif_file, assembly_id)
+ biounit.set_annotation(
+ "legacy_chain_id",
+ np.asarray(
+ [
+ legacy_mapping.get(chain_id, chain_id)
+ for chain_id in biounit.chain_id
+ ]
+ ),
+ )
+ remove_nonphysical_bonds(biounit)
+ return biounit
+
+
+def _cif_scalar(block: pdbx.CIFBlock, category: str, column: str) -> str | None:
+ """Read a single scalar value from a CIF category, or None."""
+ if category not in block:
+ return None
+ cat = block[category]
+ if column not in cat:
+ return None
+ val = cat[column].as_array()[0]
+ if val in ("?", "."):
+ return None
+ return str(val)
+
+
+def _iter_category_rows(
+ block: pdbx.CIFBlock, category: str, columns: list[str]
+) -> list[dict[str, str]]:
+ """Iterate over rows of a CIF category as dicts."""
+ if category not in block:
+ return []
+ cat = block[category]
+ arrays = {}
+ for col in columns:
+ if col not in cat:
+ return []
+ arrays[col] = cat[col].as_array()
+ n = len(next(iter(arrays.values())))
+ return [{col: arrays[col][i] for col in columns} for i in range(n)]
+
+
+_PH_RANGE_SEPARATOR = re.compile(r"\s*(?:-|โ|โ|/|\bto\b|\band\b)\s*", re.IGNORECASE)
+_PH_PREFIX = re.compile(r"^p\s*h\s*(?:=|:|of|~)?\s*", re.IGNORECASE)
+_PH_MENTION = re.compile(
+ r"\bp\s*h\s*(?:range\s*)?(?:=|:|of|~)?\s*"
+ r"(\d{1,2}(?:\.\d+)?)(?:\s*(?:-|โ|โ|/|to)\s*(\d{1,2}(?:\.\d+)?))?",
+ re.IGNORECASE,
+)
+
+
+def _valid_ph(values: list[float]) -> tuple[float, float] | None:
+ in_range = [value for value in values if 0.0 <= value <= 14.0]
+ if not in_range:
+ return None
+ return (min(in_range), max(in_range))
+
+
+def parse_ph_range(text: str | None) -> tuple[float, float] | None:
+ """Parse ``"7.5"``, ``"7.0-8.0"``, ``"pH8.0"`` or ``"6.5 to 7.5"`` into
+ ``(low, high)``; ``None`` for ``?``/``.``, free text, or values outside 0-14."""
+ if text is None:
+ return None
+ value = _PH_PREFIX.sub("", text.strip())
+ if value in {"", ".", "?"}:
+ return None
+ numbers: list[float] = []
+ for part in _PH_RANGE_SEPARATOR.split(value):
+ try:
+ numbers.append(float(part))
+ except ValueError:
+ return None
+ return _valid_ph(numbers)
+
+
+def find_ph_mentions(text: str | None) -> tuple[float, float] | None:
+ """Return ``(low, high)`` over every ``pH [-]`` mention in text."""
+ values: list[float] = []
+ for match in _PH_MENTION.finditer(text or ""):
+ values.extend(float(group) for group in match.groups() if group is not None)
+ return _valid_ph(values)
+
+
+def get_entry_ph_range(block: pdbx.CIFBlock) -> tuple[float | None, float | None]:
+ """Crystallization pH range over ``exptl_crystal_grow`` rows.
+
+ Per row: ``pH``, else ``pdbx_pH_range``, else pH mentions in
+ ``pdbx_details``. Returns ``(None, None)`` when nothing parses.
+ """
+ if "exptl_crystal_grow" not in block:
+ return (None, None)
+ category = block["exptl_crystal_grow"]
+ row_count = category.row_count
+
+ def column(name: str) -> list[str | None]:
+ if name not in category:
+ return [None] * row_count
+ return [str(value) for value in category[name].as_array(str)]
+
+ lows: list[float] = []
+ highs: list[float] = []
+ for ph, ph_range, details in zip(
+ column("pH"), column("pdbx_pH_range"), column("pdbx_details")
+ ):
+ parsed = (
+ parse_ph_range(ph) or parse_ph_range(ph_range) or find_ph_mentions(details)
+ )
+ if parsed is not None:
+ lows.append(parsed[0])
+ highs.append(parsed[1])
+ if not lows:
+ return (None, None)
+ return (min(lows), max(highs))
+
+
+def get_ligand_of_interest(
+ block: pdbx.CIFBlock,
+) -> tuple[bool | None, frozenset[str] | None]:
+ """Return ``has_ligand_of_interest`` (Y/N -> bool, else None) and the
+ ``comp_id`` set flagged SUBJECT OF INVESTIGATION (None when absent)."""
+ flag = _cif_scalar(block, "pdbx_entry_details", "has_ligand_of_interest")
+ has_ligand_of_interest = {"Y": True, "N": False}.get(flag or "")
+ if "pdbx_entity_instance_feature" not in block:
+ return has_ligand_of_interest, None
+ subjects = frozenset(
+ row["comp_id"]
+ for row in _iter_category_rows(
+ block, "pdbx_entity_instance_feature", ["feature_type", "comp_id"]
+ )
+ if row["feature_type"] == "SUBJECT OF INVESTIGATION"
+ and row["comp_id"] not in {"?", "."}
+ )
+ return has_ligand_of_interest, subjects
+
+
+def get_entry_info(data: pdbx.CIFBlock) -> dict[str, str | None]:
+ """Get entry-level information from a CIF block.
+
+ Parameters
+ ----------
+ data : pdbx.CIFBlock
+ Source mmCIF data block.
+
+ Returns
+ -------
+ dict[str, str | None]
+ Entry-level metadata (oligomeric state, determination method, keywords,
+ pH, resolution); each value is ``None`` when absent. Resolution uses
+ refinement metadata first, then EM reconstruction metadata.
+ """
+ entry_info = {}
+ mappings = [
+ ("entry_oligomeric_state", "pdbx_struct_assembly", "oligomeric_details"),
+ ("entry_determination_method", "exptl", "method"),
+ ("entry_keywords", "struct_keywords", "pdbx_keywords"),
+ ("entry_pH", "exptl_crystal_grow", "pH"),
+ ]
+ for key, cat_name, col_name in mappings:
+ entry_info[key] = _cif_scalar(data, cat_name, col_name)
+ resolution_options = [
+ ("refine", "ls_d_res_high"),
+ ("em_3d_reconstruction", "resolution"),
+ ]
+ resolution = None
+ for cat_name, col_name in resolution_options:
+ r = _cif_scalar(data, cat_name, col_name)
+ if r is not None:
+ resolution = r
+ break
+ entry_info["entry_resolution"] = resolution
+ return entry_info
+
+
+def get_chain_external_mappings(
+ data: pdbx.CIFBlock,
+) -> dict[str, dict[str, dict[str, list[tuple[str, str] | None]]]]:
+ """Get additional metadata directory from nextgen mmcif.
+
+ Parameters
+ ----------
+ data : pdbx.CIFBlock
+ Source mmCIF data block.
+
+ Returns
+ -------
+ dict[str, dict[str, dict[str, list[tuple[str, str] | None]]]]
+ Per-chain SIFTS / UniProt / BIRD mappings keyed by ``asym_id``.
+ """
+ per_chain: dict[str, dict[str, dict[str, set[tuple[str, str] | None]]]] = {}
+
+ # SIFTS mapping
+ for row in _iter_category_rows(
+ data,
+ "pdbx_sifts_xref_db_segments",
+ ["asym_id", "xref_db", "xref_db_acc", "seq_id_start", "seq_id_end"],
+ ):
+ if row["asym_id"] not in per_chain:
+ per_chain[row["asym_id"]] = defaultdict(lambda: defaultdict(set))
+ per_chain[row["asym_id"]][row["xref_db"]][row["xref_db_acc"]].add(
+ (
+ row["seq_id_start"],
+ row["seq_id_end"],
+ )
+ )
+
+ # UniProt mapping
+ for row in _iter_category_rows(
+ data,
+ "pdbx_sifts_unp_segments",
+ ["asym_id", "unp_acc", "seq_id_start", "seq_id_end"],
+ ):
+ if row["asym_id"] not in per_chain:
+ per_chain[row["asym_id"]] = defaultdict(lambda: defaultdict(set))
+ per_chain[row["asym_id"]]["UniProt"][row["unp_acc"]].add(
+ (
+ row["seq_id_start"],
+ row["seq_id_end"],
+ )
+ )
+
+ # BIRD/PRD ligands: key each chain's BIRD mapping by its PRD code (from
+ # pdbx_molecule), giving a multi-residue ligand one canonical id instead of
+ # a hyphen-joined component-code string.
+ for row in _iter_category_rows(data, "pdbx_molecule", ["asym_id", "prd_id"]):
+ if row["asym_id"] not in per_chain:
+ per_chain[row["asym_id"]] = defaultdict(lambda: defaultdict(set))
+ per_chain[row["asym_id"]]["BIRD"][row["prd_id"]].add(None)
+
+ per_chain_list: dict[str, dict[str, dict[str, list[tuple[str, str] | None]]]] = {}
+ for chain in per_chain:
+ per_chain_list[chain] = {}
+ for mapping in per_chain[chain]:
+ per_chain_list[chain][mapping] = {
+ k: list(v) for k, v in per_chain[chain][mapping].items()
+ }
+ return per_chain_list
+
+
+# ---------------------------------------------------------------------------
+# CIF -> RDKit conversion
+# ---------------------------------------------------------------------------
+
+
+@cache
+def _get_ccd_atomarray(comp_id: str) -> "struc.AtomArray | None":
+ """Return the CCD component atoms from biotite's bundled CCD, or None.
+
+ Notes
+ -----
+ ``bt_info`` is the single CCD atom source. The pipeline keeps it current by
+ running biotite ``setup_ccd`` (see
+ :func:`plinder.data.pipeline.io.refresh_bundled_ccd`) during provisioning โ it
+ pulls the same wwPDB dictionary, so the bundle carries up-to-date
+ representations (correct nitro charges, the 5-char extended codes, โฆ). If that
+ sync has not run, the bundle is whatever biotite shipped, which may be stale.
+ """
+ try:
+ return bt_info.residue(comp_id, allow_missing_coord=True)
+ except Exception as bundled_error:
+ LOG.warning(f"CCD lookup failed for {comp_id}: {bundled_error}")
+ return None
+
+
+def _fill_missing_ccd_bonds(atoms: "struc.AtomArray") -> "struc.AtomArray":
+ """Fill intra-residue bonds from the bundled CCD for bond-less residues.
+
+ Notes
+ -----
+ A residue arrives without internal bonds when the structure's CIF omits its
+ ``_chem_comp_bond`` rows. We recover them from biotite's bundled CCD
+ (:func:`_get_ccd_atomarray`), matched by atom name. Existing bonds (including
+ inter-residue ``struct_conn`` links) and already-bonded residues are left
+ untouched โ a no-op for most ligands.
+ """
+ if atoms.array_length() < 2:
+ return atoms
+ if atoms.bonds is None:
+ atoms.bonds = struc.BondList(atoms.array_length())
+ existing = atoms.bonds.as_array()
+ residue_starts = struc.get_residue_starts(atoms, add_exclusive_stop=True)
+ for start, stop in zip(residue_starts[:-1], residue_starts[1:]):
+ if stop - start < 2:
+ continue
+ has_internal = bool(
+ np.any(
+ (existing[:, 0] >= start)
+ & (existing[:, 0] < stop)
+ & (existing[:, 1] >= start)
+ & (existing[:, 1] < stop)
+ )
+ )
+ if has_internal:
+ continue
+ ccd = _get_ccd_atomarray(str(atoms.res_name[start]))
+ if ccd is None or ccd.bonds is None:
+ continue
+ name_to_index = {
+ str(name): start + offset
+ for offset, name in enumerate(atoms.atom_name[start:stop])
+ }
+ ccd_names = ccd.atom_name
+ for ccd_i, ccd_j, order in ccd.bonds.as_array():
+ index_i = name_to_index.get(str(ccd_names[ccd_i]))
+ index_j = name_to_index.get(str(ccd_names[ccd_j]))
+ if index_i is not None and index_j is not None:
+ atoms.bonds.add_bond(index_i, index_j, int(order))
+ return atoms
+
+
+def atoms_to_rdkit_mol(
+ atoms: "struc.AtomArray",
+ assign_stereo: bool = True,
+) -> "Chem.Mol":
+ """Convert a biotite AtomArray to a sanitized RDKit Mol.
+
+ Parameters
+ ----------
+ atoms : AtomArray
+ Atoms with bonds (``include_bonds=True`` or caller-set). Bonds missing
+ from a residue are filled from the CCD; a multi-atom input still
+ bond-less after that raises ``ValueError``. Single atoms (ions) need none.
+ assign_stereo : bool
+ If True, perceive stereo from the coordinates via
+ ``AssignStereochemistryFrom3D`` (tetrahedral R/S and double-bond E/Z).
+
+ Returns
+ -------
+ Chem.Mol
+ Sanitized RDKit molecule with 3D coordinates and PDB atom info,
+ heavy atoms only.
+
+ Raises
+ ------
+ ValueError
+ If a multi-atom input has no bonds (even after CCD fill), or conversion fails.
+
+ Notes
+ -----
+ Missing intra-residue bonds are recovered from the bundled CCD first, then
+ stereo (atom R/S *and* double-bond E/Z) is optionally assigned from the 3D
+ coordinates. H and D are dropped by ``filter_heavy``
+ before conversion, so the sanitized molecule, ring info included, is
+ returned as is.
+ ``connect_via_residue_names`` is deliberately not used to derive bonds โ it
+ silently drops inter-residue bonds for non-standard residues.
+ """
+ from biotite.interface import rdkit as rdkit_interface
+ from biotite.structure import BondList
+
+ # TODO(peppr): local sanitize with boron/main-group over-valence fixes not yet
+ # in a released peppr; revert to `from peppr import sanitize` once upstream.
+ from plinder.core.utils.sanitize import sanitize as peppr_sanitize
+
+ heavy = atoms[filter_heavy(atoms)]
+ # Recover intra-residue bonds for residues that arrived bond-less (no-op when
+ # already bonded) so every caller shares one bond graph.
+ heavy = _fill_missing_ccd_bonds(heavy)
+
+ # Multi-atom inputs must carry bonds; single atoms (ions) don't.
+ if heavy.bonds is None or heavy.bonds.as_array().shape[0] == 0:
+ if heavy.array_length() == 1:
+ heavy.bonds = BondList(1)
+ else:
+ raise ValueError(
+ "atoms_to_rdkit_mol requires bonds on multi-atom inputs "
+ "(load the CIF with include_bonds=True or set atoms.bonds)."
+ )
+
+ # Keep explicit aromatic single/double orders for incomplete rings, but
+ # leave generic aromatic bonds for RDKit to resolve. Biotite's
+ # kekulize=True turns the latter into ANY, producing bond type 0 in SDFs.
+ generic_aromatic = heavy.bonds.as_array()[:, 2] == struc.BondType.AROMATIC
+ heavy.bonds.remove_aromaticity()
+ if generic_aromatic.any():
+ bonds = heavy.bonds.as_array()
+ bonds[generic_aromatic, 2] = struc.BondType.AROMATIC
+ heavy.bonds = BondList(len(heavy), bonds)
+ mol = rdkit_interface.to_mol(heavy, use_dative_bonds=True)
+ if mol is None:
+ raise ValueError("Failed to convert AtomArray to RDKit Mol")
+
+ peppr_sanitize(mol)
+ if assign_stereo:
+ # From3D (not atom-only AssignAtomChiralTagsFromStructure) so double-bond
+ # E/Z is perceived too, not just R/S; keeps all-carbon quaternary centres.
+ Chem.AssignStereochemistryFrom3D(mol)
+ return mol
+
+
+# ---------------------------------------------------------------------------
+# Structure bonds: struct_conn parsing and non-physical bond removal
+# ---------------------------------------------------------------------------
+
+
+def residue_address(
+ auth_seq: str,
+ comp_id: str,
+ asym_id: str,
+ label_seq: str | int,
+ atom_name: str | None = None,
+) -> str:
+ """``{auth_seq}:{comp_id}:{asym}:{label_seq}[:{atom}]`` in ``_struct_conn`` partner order.
+
+ ``auth_seq`` is ``auth_seq_id`` with insertion code (``?`` when unknown),
+ ``comp_id`` is ``label_comp_id`` (``entity_poly_seq.mon_id`` for polymers),
+ ``asym`` is ``label_asym_id``, ``label_seq`` is ``label_seq_id`` (``.`` for
+ non-polymer and branched residues) and ``atom`` is ``label_atom_id``. Shared
+ by covalent links, modified residues and unresolved atoms.
+ """
+ label = str(label_seq)
+ if label in {"", "?", "."}:
+ label = "."
+ parts = [str(auth_seq), str(comp_id), str(asym_id), label]
+ if atom_name is not None:
+ parts.append(str(atom_name))
+ return ":".join(parts)
+
+
+def parse_struct_conn(
+ block: pdbx.CIFBlock,
+) -> list[dict[str, str]]:
+ """Parse ``_struct_conn`` into a list of connection dicts.
+
+ Parameters
+ ----------
+ block : pdbx.CIFBlock
+ Source mmCIF data block.
+
+ Returns
+ -------
+ list[dict[str, str]]
+ One dict per connection (empty when ``_struct_conn`` or a required
+ column is absent).
+ """
+ if "struct_conn" not in block:
+ return []
+ conn = block["struct_conn"]
+ cols = {
+ "conn_type_id": "conn_type",
+ "ptnr1_label_asym_id": "chain1",
+ "ptnr1_label_seq_id": "seq1",
+ "ptnr1_label_atom_id": "atom1",
+ "ptnr1_label_comp_id": "comp1",
+ "ptnr2_label_asym_id": "chain2",
+ "ptnr2_label_seq_id": "seq2",
+ "ptnr2_label_atom_id": "atom2",
+ "ptnr2_label_comp_id": "comp2",
+ "ptnr1_auth_seq_id": "auth_seq1",
+ "ptnr2_auth_seq_id": "auth_seq2",
+ }
+ arrays = {}
+ for cif_col, key in cols.items():
+ if cif_col not in conn:
+ return []
+ arrays[key] = conn[cif_col].as_array()
+ n = len(arrays["conn_type"])
+ return [{k: arrays[k][i] for k in arrays} for i in range(n)]
+
+
+# Drop bonds longer than this fraction of the two atoms' van der Waals radii
+# sum: ~0.8x the vdW sum is the start of the non-bonded range, so a longer
+# "bond" is more likely a van der Waals contact than covalent.
+_NONPHYSICAL_BOND_VDW_FRACTION = 0.8
+# RDKit's table covers every element (incl. Hg, U), unlike biotite's, so exotic
+# elements still get assessed rather than skipped.
+_PERIODIC_TABLE = Chem.GetPeriodicTable()
+
+
+def _max_bond_length(element1: str, element2: str) -> float:
+ """Distance above which an element pair can't be bonded (0.8 x vdW sum, ร )."""
+ try:
+ # capitalize(): RDKit wants "Hg", biotite gives "HG".
+ radius1 = _PERIODIC_TABLE.GetRvdw(
+ _PERIODIC_TABLE.GetAtomicNumber(element1.capitalize())
+ )
+ radius2 = _PERIODIC_TABLE.GetRvdw(
+ _PERIODIC_TABLE.GetAtomicNumber(element2.capitalize())
+ )
+ except RuntimeError:
+ # Unrecognized element symbol (e.g. "X", "UNK"): can't assess, keep it.
+ return float("inf")
+ # float(): GetRvdw is untyped (Any), so cast at the boundary.
+ return _NONPHYSICAL_BOND_VDW_FRACTION * float(radius1 + radius2)
+
+
+def remove_nonphysical_bonds(atoms: "struc.AtomArray") -> None:
+ """Drop bonds too long to be covalent, in-place, logging each removal.
+
+ Parameters
+ ----------
+ atoms : struc.AtomArray
+ Bonded structure cleaned in-place; ``atoms.bonds`` is replaced with the
+ pruned graph. A no-op when there are no bonds.
+
+ Notes
+ -----
+ ``get_assembly``/``get_structure`` with ``include_bonds=True`` can emit
+ chemically impossible bonds:
+
+ - a **residue-ambiguity clash**, where a ``res_id`` collision makes biotite
+ cross-link atoms of two different residues. Branched sugars are the usual
+ cause (undefined ``label_seq_id``); :func:`_branched_residue_numbering`
+ prevents that upstream, so this stays a backstop for any other collision.
+ - **inter-residue inference**, where ``connect_via_residue_names`` bonds
+ consecutive-but-spatially-distant residues (peptide ``C-N`` / nucleic
+ ``O3'-P``) without checking the distance.
+
+ Both are far longer than any real bond, so we drop any bond exceeding the
+ element pair's distance threshold (:func:`_max_bond_length`). Real bonds
+ (<=~2.4 ร , disulfides and carborane cages included) are kept.
+ """
+ if atoms.bonds is None:
+ return
+ bond_array = atoms.bonds.as_array()
+ if bond_array.shape[0] == 0:
+ return
+
+ index1 = bond_array[:, 0].astype(int)
+ index2 = bond_array[:, 1].astype(int)
+ distances = np.linalg.norm(atoms.coord[index1] - atoms.coord[index2], axis=1)
+ thresholds = np.fromiter(
+ (
+ _max_bond_length(str(element1), str(element2))
+ for element1, element2 in zip(atoms.element[index1], atoms.element[index2])
+ ),
+ dtype=float,
+ count=bond_array.shape[0],
+ )
+ remove_mask = distances > thresholds
+ if not remove_mask.any():
+ return
+
+ for row in np.flatnonzero(remove_mask):
+ first, second = int(index1[row]), int(index2[row])
+ same_residue = (
+ atoms.chain_id[first] == atoms.chain_id[second]
+ and atoms.res_id[first] == atoms.res_id[second]
+ )
+ cause = (
+ "residue-ambiguity clash (get_assembly res_id collision)"
+ if same_residue
+ else "inter-residue inference (get_assembly)"
+ )
+ LOG.warning(
+ "removing non-physical bond "
+ f"{atoms.atom_name[first]}@{atoms.res_name[first]}"
+ f"{int(atoms.res_id[first])} <-> "
+ f"{atoms.atom_name[second]}@{atoms.res_name[second]}"
+ f"{int(atoms.res_id[second])} "
+ f"({distances[row]:.2f} A > {thresholds[row]:.2f} A); likely {cause}."
+ )
+
+ atoms.bonds = struc.BondList(atoms.array_length(), bond_array[~remove_mask])
+
+
+# ---------------------------------------------------------------------------
+# Ligand bond order detection and assignment
+# ---------------------------------------------------------------------------
+
+
+class MissingBondOrderError(ValueError):
+ """Raised when a CIF file has ligands with unresolvable bond orders."""
+
+ pass
+
+
+# Minimum fraction of a CCD entry's heavy atoms that must be matched by name
+# in the CIF for its bonds to be applied reliably.
+_MIN_CCD_ATOM_MATCH_FRACTION = 0.5
+
+
+def _get_cif_bond_comp_ids(block: pdbx.CIFBlock) -> set[str]:
+ """Return the set of comp_ids that already have _chem_comp_bond entries."""
+ if "chem_comp_bond" not in block:
+ return set()
+ return set(block["chem_comp_bond"]["comp_id"].as_array())
+
+
+def _is_known_compound(comp_id: str, atom_names: set[str] | None = None) -> bool:
+ """Return True if ``comp_id`` is in biotite's bundled CCD.
+
+ Notes
+ -----
+ When *atom_names* (the CIF's heavy-atom names) is given, also require that the
+ CIF names agree with the CCD entry: every CIF name must be a CCD name, and the
+ CIF must cover at least ``_MIN_CCD_ATOM_MATCH_FRACTION`` of the CCD's heavy
+ atoms. This rejects a comp_id that collides with a CCD code but is chemically
+ different (e.g. Boltz ``LIG`` =/= CCD ``LIG``), which would otherwise be
+ treated as known and get wrong bonds from the CCD by atom-name lookup.
+ """
+ try:
+ ref = _get_ccd_atomarray(comp_id)
+ if ref is None:
+ return False
+ if atom_names is not None:
+ ref_heavy = ref[filter_heavy(ref)]
+ ref_names = set(ref_heavy.atom_name)
+ if not ref_names or not atom_names:
+ return False
+ # All CIF atom names must exist in the CCD entry
+ unknown_names = atom_names - ref_names
+ if unknown_names:
+ return False
+ # Enough CCD atoms must be matched for reliable bond assignment
+ if len(atom_names & ref_names) < _MIN_CCD_ATOM_MATCH_FRACTION * len(
+ ref_names
+ ):
+ return False
+ return True
+ except Exception as e:
+ LOG.warning(f"CCD lookup failed for {comp_id}: {e}")
+ return False
+
+
+def get_unknown_ligand_ids(cif_input: pdbx.CIFFile | Path | str) -> set[str]:
+ """Return HETATM comp_ids not in CCD and missing ``_chem_comp_bond``.
+
+ Parameters
+ ----------
+ cif_input : CIFFile, Path, or str
+ Biotite CIFFile or path to an mmCIF file.
+
+ Returns
+ -------
+ set[str]
+ Component IDs requiring user-supplied SMILES.
+ """
+ if not isinstance(cif_input, pdbx.CIFFile):
+ cif_input = pdbx.CIFFile.read(str(cif_input))
+ block = list(cif_input.values())[0]
+ if "atom_site" not in block:
+ return set()
+ atom_site = block["atom_site"]
+
+ # Scan model 1 only โ the sole model built downstream. A later-model-only
+ # component would otherwise falsely drive enrichment (or raise a spurious
+ # MissingBondOrderError) for a model that is never used.
+ if "pdbx_PDB_model_num" in atom_site:
+ model_nums = atom_site["pdbx_PDB_model_num"].as_array()
+ n_models = len(set(model_nums))
+ model_mask = model_nums == model_nums[0]
+ else:
+ n_models = 1
+ model_mask = np.ones(atom_site.row_count, dtype=bool)
+ if n_models > 1:
+ LOG.warning(
+ f"CIF has {n_models} models โ scanning model 1 only for unknown "
+ "ligands; other models are not read."
+ )
+
+ group_pdb = atom_site["group_PDB"].as_array()[model_mask]
+ comp_ids = atom_site["label_comp_id"].as_array()[model_mask]
+ hetatm_ids = {
+ comp_ids[i] for i in range(len(group_pdb)) if group_pdb[i] == "HETATM"
+ }
+ if not hetatm_ids:
+ return set()
+
+ cif_bond_ids = _get_cif_bond_comp_ids(block)
+
+ # Collect heavy-atom names per comp_id for validation
+ a_names = atom_site["label_atom_id"].as_array()[model_mask]
+ elements = (
+ atom_site["type_symbol"].as_array()[model_mask]
+ if "type_symbol" in atom_site
+ else None
+ )
+ atom_names_per_comp: dict[str, set[str]] = {}
+ for comp_id in hetatm_ids:
+ if elements is not None:
+ mask = (comp_ids == comp_id) & (elements != "H") & (elements != "D")
+ else:
+ mask = comp_ids == comp_id
+ atom_names_per_comp[comp_id] = set(a_names[mask])
+
+ unknown = set()
+ for comp_id in hetatm_ids:
+ if comp_id in cif_bond_ids:
+ # if bonds defined in cif - consider chemistry as known
+ continue
+ if _is_known_compound(comp_id, atom_names=atom_names_per_comp.get(comp_id)):
+ continue
+ unknown.add(comp_id)
+ return unknown
+
+
+def _rdkit_bond_to_cif(bond: Chem.rdchem.Bond) -> tuple[str, str]:
+ """Map an RDKit bond to ``(value_order, pdbx_aromatic_flag)``.
+
+ Notes
+ -----
+ Biotite's ``_parse_intra_residue_bonds`` needs both columns; the
+ ``(order, flag)`` pair keys into
+ :data:`biotite.structure.io.pdbx.convert.COMP_BOND_ORDER_TO_TYPE`
+ โ without the aromatic flag biotite silently falls back to the
+ CCD library, which fails for custom residues.
+ """
+ aromatic_flag = "Y" if bond.GetIsAromatic() else "N"
+ order_map = {
+ Chem.rdchem.BondType.SINGLE: "sing",
+ Chem.rdchem.BondType.DOUBLE: "doub",
+ Chem.rdchem.BondType.TRIPLE: "trip",
+ Chem.rdchem.BondType.AROMATIC: "arom",
+ }
+ order = order_map.get(bond.GetBondType(), "sing")
+ return order, aromatic_flag
+
+
+def check_cif_bond_orders(cif_input: pdbx.CIFFile | Path | str) -> None:
+ """Raise if any ligand has unresolvable bond orders.
+
+ Parameters
+ ----------
+ cif_input : CIFFile, Path, or str
+ Biotite CIFFile or path to an mmCIF file.
+
+ Raises
+ ------
+ MissingBondOrderError
+ If any ligand is unknown to CCD and has no ``_chem_comp_bond``.
+ """
+ unknown = get_unknown_ligand_ids(cif_input)
+ if unknown:
+ raise MissingBondOrderError(
+ f"CIF file contains unknown ligands {unknown} with "
+ "no _chem_comp_bond category and no CCD library match. "
+ "Provide ligand SMILES to assign bond orders."
+ )
+
+
+def _bonds_by_position(
+ comp_id: str,
+ template_heavy: Chem.Mol,
+ lig_heavy: struc.AtomArray,
+) -> list[tuple[str, str, str, str]]:
+ """Assign bonds by trusting positional atom-order correspondence.
+
+ Returns
+ -------
+ list[tuple[str, str, str, str]]
+ ``(atom_name_1, atom_name_2, value_order, pdbx_aromatic_flag)`` tuples
+ ready to be written to ``_chem_comp_bond``.
+
+ Notes
+ -----
+ Assumes CIF heavy atoms appear in the same order as heavy atoms in the SMILES
+ template (the convention used by Boltz, AlphaFold3, Chai-1, etc.). Verifies by
+ comparing elements at each position and raises ``ValueError`` on any mismatch,
+ pointing at the offending position so the caller can diagnose it quickly.
+ """
+ n_template = template_heavy.GetNumAtoms()
+ n_cif = lig_heavy.array_length()
+ if n_template != n_cif:
+ raise ValueError(
+ f"Atom count mismatch for {comp_id}: CIF has {n_cif} heavy atoms, "
+ f"SMILES has {n_template}."
+ )
+
+ cif_elements = [str(e).upper() for e in lig_heavy.element]
+ for i, (cif_el, tmpl_atom) in enumerate(
+ zip(cif_elements, template_heavy.GetAtoms())
+ ):
+ tmpl_el = tmpl_atom.GetSymbol().upper()
+ if cif_el != tmpl_el:
+ raise ValueError(
+ f"Element mismatch for {comp_id} at position {i}: "
+ f"CIF has {cif_el}, SMILES has {tmpl_el}. Set "
+ "force_substructure_match=True if the CIF doesn't "
+ "preserve SMILES atom order."
+ )
+
+ atom_names = list(lig_heavy.atom_name)
+ out: list[tuple[str, str, str, str]] = []
+ for bond in template_heavy.GetBonds():
+ idx1 = bond.GetBeginAtomIdx()
+ idx2 = bond.GetEndAtomIdx()
+ order, aromatic_flag = _rdkit_bond_to_cif(bond)
+ out.append((atom_names[idx1], atom_names[idx2], order, aromatic_flag))
+ return out
+
+
+def _bonds_by_substructure_match(
+ comp_id: str,
+ template: Chem.Mol,
+ lig_heavy: struc.AtomArray,
+) -> list[tuple[str, str, str, str]]:
+ """Assign bonds via RDKit substructure matching.
+
+ Raises
+ ------
+ ValueError
+ If the ligand cannot be parsed as an RDKit mol, or if
+ :func:`peppr.sanitize` fails โ a half-sanitized mol has
+ undefined aromaticity perception, and feeding it to
+ ``AssignBondOrdersFromTemplate`` can silently match the wrong
+ substructure. Better to fail loudly than to emit chemically
+ wrong bond orders.
+
+ Notes
+ -----
+ Opt-in alternative to :func:`_bonds_by_position` for CIFs whose atom order
+ does not match SMILES parse order. Invoked only when
+ ``force_substructure_match=True`` is passed to
+ :func:`assign_bond_orders_from_smiles` โ there is no automatic fallback
+ between the two paths.
+
+ Substructure matching needs CIF connectivity (RDKit can't search a graph that
+ has no edges). If ``lig_heavy.bonds`` is empty, bonds are inferred from
+ interatomic distances (``connect_via_distances``); bond orders are then
+ reassigned from the SMILES template via ``AssignBondOrdersFromTemplate``. The
+ positional path doesn't need this fallback because it never reads the CIF's
+ bond list โ it copies bonds straight from the SMILES template using positional
+ atom-name lookup.
+ """
+ from biotite.interface import rdkit as rdkit_interface
+
+ # TODO(peppr): temporary local sanitize carrying boron/main-group
+ # over-valence fixes not yet in a released peppr. Revert to
+ # `from peppr import sanitize as peppr_sanitize` once upstream.
+ # See plinder.core.utils.sanitize.
+ from plinder.core.utils.sanitize import sanitize as peppr_sanitize
+
+ if lig_heavy.bonds is None or lig_heavy.bonds.as_array().shape[0] == 0:
+ # Unknown residue โ infer bonds from distances
+ lig_heavy.bonds = struc.connect_via_distances(lig_heavy)
+ # Ensure bond types are SINGLE (1), not ANY/UNSPECIFIED (0),
+ # so RDKit template matching can reassign proper orders
+ bond_arr = lig_heavy.bonds.as_array()
+ bond_arr[:, 2] = np.where(bond_arr[:, 2] == 0, 1, bond_arr[:, 2])
+ lig_heavy.bonds = struc.BondList(lig_heavy.array_length(), bond_arr)
+ rdkit_mol = rdkit_interface.to_mol(lig_heavy)
+ if rdkit_mol is None:
+ raise ValueError(f"Could not parse ligand {comp_id} as RDKit mol")
+ try:
+ peppr_sanitize(rdkit_mol)
+ except Exception as e:
+ raise ValueError(
+ f"peppr_sanitize failed for {comp_id}: {e}. "
+ "Proceeding to substructure matching with a half-sanitized "
+ "mol can silently produce wrong bond orders, so aborting."
+ ) from e
+ fixed_mol = mol_assigned_bond_orders_by_template(template, rdkit_mol)
+
+ atom_names = [
+ a.GetPDBResidueInfo().GetName().strip()
+ if a.GetPDBResidueInfo()
+ else lig_heavy.atom_name[a.GetIdx()]
+ for a in fixed_mol.GetAtoms()
+ ]
+
+ out: list[tuple[str, str, str, str]] = []
+ for bond in fixed_mol.GetBonds():
+ idx1 = bond.GetBeginAtomIdx()
+ idx2 = bond.GetEndAtomIdx()
+ if idx1 < len(atom_names) and idx2 < len(atom_names):
+ order, aromatic_flag = _rdkit_bond_to_cif(bond)
+ out.append((atom_names[idx1], atom_names[idx2], order, aromatic_flag))
+ return out
+
+
+def _component_reference_instance(
+ atoms: struc.AtomArray,
+ comp_id: str,
+) -> struc.AtomArray:
+ """Return one component instance after checking all copies agree."""
+ component_atoms = atoms[atoms.res_name == comp_id]
+ if component_atoms.array_length() == 0:
+ raise ValueError(f"No atoms found for component {comp_id} in CIF")
+
+ instance_keys = list(
+ dict.fromkeys(
+ (str(chain), int(res_id))
+ for chain, res_id in zip(component_atoms.chain_id, component_atoms.res_id)
+ )
+ )
+ instances = [
+ (
+ key,
+ component_atoms[
+ (component_atoms.chain_id == key[0])
+ & (component_atoms.res_id == key[1])
+ ],
+ )
+ for key in instance_keys
+ ]
+ ref_key, ref_atoms = instances[0]
+ ref_names = tuple(ref_atoms.atom_name)
+ ref_elements = tuple(ref_atoms.element)
+ for key, instance_atoms in instances[1:]:
+ names = tuple(instance_atoms.atom_name)
+ elements = tuple(instance_atoms.element)
+ if names != ref_names or elements != ref_elements:
+ raise ValueError(
+ f"{comp_id}: instances disagree on heavy-atom naming/order. "
+ f"Instance {ref_key} has {len(ref_names)} atoms starting with "
+ f"{ref_names[:5]}; instance {key} has {len(names)} atoms "
+ f"starting with {names[:5]}. mmCIF _chem_comp_bond is keyed "
+ "by component ID, so every copy must use the same chemistry "
+ "and atom names. Use distinct component IDs when copies differ."
+ )
+ if len(instances) > 1:
+ LOG.info(
+ "%s: %d instances share one atom naming scheme; writing one "
+ "_chem_comp_bond definition",
+ comp_id,
+ len(instances),
+ )
+ return ref_atoms
+
+
+def _existing_chem_comp_bonds(
+ block: pdbx.CIFBlock,
+ *,
+ replace_components: set[str] | None = None,
+) -> list[tuple[str, str, str, str, str]]:
+ """Read existing component bonds except explicitly replaced components."""
+ if "chem_comp_bond" not in block:
+ return []
+ replace_components = replace_components or set()
+ category = block["chem_comp_bond"]
+ required = {"comp_id", "atom_id_1", "atom_id_2", "value_order"}
+ missing = sorted(required.difference(category))
+ if missing:
+ raise ValueError(
+ "existing _chem_comp_bond is missing required fields: "
+ + ", ".join(f"_chem_comp_bond.{name}" for name in missing)
+ )
+ comp_ids = category["comp_id"].as_array(str)
+ atom_ids_1 = category["atom_id_1"].as_array(str)
+ atom_ids_2 = category["atom_id_2"].as_array(str)
+ orders = category["value_order"].as_array(str)
+ aromatic_flags = (
+ category["pdbx_aromatic_flag"].as_array(str)
+ if "pdbx_aromatic_flag" in category
+ else np.full(category.row_count, "N")
+ )
+ return [
+ (comp_id, atom_id_1, atom_id_2, order.lower(), aromatic_flag)
+ for comp_id, atom_id_1, atom_id_2, order, aromatic_flag in zip(
+ comp_ids,
+ atom_ids_1,
+ atom_ids_2,
+ orders,
+ aromatic_flags,
+ )
+ if comp_id not in replace_components
+ ]
+
+
+def _set_chem_comp_bonds(
+ block: pdbx.CIFBlock,
+ bonds: list[tuple[str, str, str, str, str]],
+) -> None:
+ """Write dictionary-valid component bond rows."""
+ block["chem_comp_bond"] = pdbx.CIFCategory(
+ {
+ "comp_id": [bond[0] for bond in bonds],
+ "atom_id_1": [bond[1] for bond in bonds],
+ "atom_id_2": [bond[2] for bond in bonds],
+ "value_order": [bond[3].lower() for bond in bonds],
+ "pdbx_aromatic_flag": [bond[4] for bond in bonds],
+ }
+ )
+
+
+def enrich_cif_with_ccd_bonds(
+ cif_file: pdbx.CIFFile,
+ ligand_ccd_codes: dict[str, str],
+) -> dict[str, str]:
+ """Assign custom component bonds from Chemical Component Dictionary entries.
+
+ The input mapping uses the custom component ID in ``_atom_site`` as its
+ key and a reference CCD code as its value, for example ``{"LIG": "ATP"}``.
+ Atom names are matched first. If they differ, provisional connectivity is
+ inferred from the supplied coordinates and graph-matched to the CCD
+ template. The function refuses partial or ambiguous mappings instead of
+ assigning bonds from element order alone.
+
+ Returns
+ -------
+ dict[str, str]
+ Canonical CCD SMILES keyed by the custom component ID.
+ """
+ from plinder.data.annotations.ligand_utils import (
+ _get_ccd_mol,
+ _get_ccd_smiles,
+ )
+
+ if not ligand_ccd_codes:
+ return {}
+ block = list(cif_file.values())[0]
+ atoms = pdbx.get_structure(
+ cif_file, model=1, use_author_fields=False, include_bonds=False
+ )
+ atoms = atoms[filter_heavy(atoms)]
+ bonds = _existing_chem_comp_bonds(
+ block,
+ replace_components=set(ligand_ccd_codes),
+ )
+ smiles_by_component: dict[str, str] = {}
+ bond_type_to_cif = {
+ struc.BondType.SINGLE: ("sing", "N"),
+ struc.BondType.DOUBLE: ("doub", "N"),
+ struc.BondType.TRIPLE: ("trip", "N"),
+ struc.BondType.QUADRUPLE: ("quad", "N"),
+ struc.BondType.AROMATIC_SINGLE: ("sing", "Y"),
+ struc.BondType.AROMATIC_DOUBLE: ("doub", "Y"),
+ struc.BondType.AROMATIC_TRIPLE: ("trip", "Y"),
+ struc.BondType.AROMATIC: ("arom", "Y"),
+ }
+ for custom_comp_id, reference_code in ligand_ccd_codes.items():
+ custom_comp_id = str(custom_comp_id).strip()
+ reference_code = str(reference_code).strip().upper()
+ if not custom_comp_id or not reference_code:
+ raise ValueError("ligand component IDs and CCD codes must not be empty")
+ custom_atoms = _component_reference_instance(atoms, custom_comp_id)
+ ccd_atoms = _get_ccd_atomarray(reference_code)
+ if ccd_atoms is None:
+ raise ValueError(
+ f"CCD code {reference_code!r} supplied for component "
+ f"{custom_comp_id!r} was not found in the Chemical Component "
+ "Dictionary"
+ )
+ ccd_atoms = ccd_atoms[filter_heavy(ccd_atoms)]
+ if ccd_atoms.bonds is None or len(ccd_atoms.bonds.as_array()) == 0:
+ raise ValueError(
+ f"CCD code {reference_code!r} has no heavy-atom bonds to assign "
+ f"to component {custom_comp_id!r}"
+ )
+ if custom_atoms.array_length() != ccd_atoms.array_length():
+ raise ValueError(
+ f"cannot map component {custom_comp_id!r} to CCD code "
+ f"{reference_code!r}: custom CIF has "
+ f"{custom_atoms.array_length()} heavy atoms but CCD has "
+ f"{ccd_atoms.array_length()}"
+ )
+
+ custom_names = [str(name) for name in custom_atoms.atom_name]
+ ccd_names = [str(name) for name in ccd_atoms.atom_name]
+ if len(set(custom_names)) != len(custom_names):
+ raise ValueError(
+ f"component {custom_comp_id!r} has duplicate heavy-atom names; "
+ "CCD bond assignment requires unique atom names"
+ )
+ bonds_to_emit: list[tuple[str, str, str, str]] | None = None
+ if set(custom_names) == set(ccd_names):
+ ccd_element_by_name = dict(zip(ccd_names, ccd_atoms.element))
+ element_mismatches = [
+ name
+ for name, element in zip(custom_names, custom_atoms.element)
+ if element != ccd_element_by_name[name]
+ ]
+ if element_mismatches:
+ raise ValueError(
+ f"cannot map component {custom_comp_id!r} to CCD code "
+ f"{reference_code!r}: atom names match but elements differ "
+ f"for {element_mismatches[:5]}"
+ )
+ ccd_index_to_custom_name = {
+ index: ccd_name for index, ccd_name in enumerate(ccd_names)
+ }
+ else:
+ ccd_template = _get_ccd_mol(reference_code)
+ if ccd_template is None:
+ raise ValueError(
+ f"CCD code {reference_code!r} could not provide an RDKit "
+ f"template for component {custom_comp_id!r}"
+ )
+ try:
+ bonds_to_emit = _bonds_by_substructure_match(
+ custom_comp_id,
+ ccd_template,
+ custom_atoms,
+ )
+ except ValueError as exc:
+ raise ValueError(
+ f"cannot safely map component {custom_comp_id!r} to CCD "
+ f"code {reference_code!r} from atom names or inferred "
+ f"connectivity: {exc}. Provide a SMILES whose parse order "
+ "matches the custom CIF if its geometry does not support "
+ "distance-based bond inference."
+ ) from exc
+
+ if bonds_to_emit is None:
+ bonds_to_emit = []
+ for atom_index_1, atom_index_2, bond_type in ccd_atoms.bonds.as_array():
+ bond_type = struc.BondType(bond_type)
+ if bond_type not in bond_type_to_cif:
+ raise ValueError(
+ f"CCD code {reference_code!r} contains unsupported bond "
+ f"type {bond_type.name} for component {custom_comp_id!r}"
+ )
+ order, aromatic_flag = bond_type_to_cif[bond_type]
+ bonds_to_emit.append(
+ (
+ ccd_index_to_custom_name[int(atom_index_1)],
+ ccd_index_to_custom_name[int(atom_index_2)],
+ order,
+ aromatic_flag,
+ )
+ )
+ bonds.extend(
+ (custom_comp_id, atom_1, atom_2, order, aromatic_flag)
+ for atom_1, atom_2, order, aromatic_flag in bonds_to_emit
+ )
+ smiles = _get_ccd_smiles(reference_code)
+ if smiles is None:
+ raise ValueError(
+ f"CCD code {reference_code!r} could not be converted to RDKit "
+ f"chemistry for component {custom_comp_id!r}"
+ )
+ smiles_by_component[custom_comp_id] = smiles
+
+ _set_chem_comp_bonds(block, bonds)
+ return smiles_by_component
+
+
+def enrich_cif_with_smiles_bonds(
+ cif_file: pdbx.CIFFile,
+ ligand_smiles: dict[str, str],
+ force_substructure_match: bool = False,
+) -> None:
+ """Add ``_chem_comp_bond`` rows to a CIFFile in-memory.
+
+ Parameters
+ ----------
+ cif_file : pdbx.CIFFile
+ CIF object to mutate in place.
+ ligand_smiles : dict[str, str]
+ Mapping of component ID (e.g. ``LIG``) to SMILES.
+ force_substructure_match : bool, default=False
+ If ``True``, skip the positional element check entirely and
+ assign bonds via RDKit substructure matching instead.
+
+ Raises
+ ------
+ MissingBondOrderError
+ If unknown ligands remain without SMILES.
+ ValueError
+ If SMILES is invalid, atom counts differ, element order does
+ not match (default path), sanitize / template matching fails
+ (substructure path โ this path fails loudly rather than risk
+ emitting chemically wrong bond orders), or multiple instances
+ of the same comp_id disagree on heavy-atom naming/order
+ (mmCIF ``_chem_comp_bond`` is keyed by comp_id so all
+ instances must share atom naming for biotite to apply the
+ single bond definition correctly).
+
+ Notes
+ -----
+ Mutates ``cif_file`` by appending bond entries for unknown ligands using the
+ provided SMILES templates. Known CCD compounds are skipped and existing
+ ``_chem_comp_bond`` rows are preserved. See
+ :func:`assign_bond_orders_from_smiles` for the atom-order assumption and the
+ ``force_substructure_match`` opt-in.
+ """
+ block = list(cif_file.values())[0]
+
+ unknown_ids = get_unknown_ligand_ids(cif_file)
+ if not unknown_ids:
+ LOG.info("All ligands are known or already have bond orders, nothing to do")
+ return
+
+ missing_smiles = unknown_ids - set(ligand_smiles.keys())
+ if missing_smiles:
+ raise MissingBondOrderError(
+ f"Unknown ligands {missing_smiles} need SMILES but none were provided"
+ )
+
+ to_process = {k: v for k, v in ligand_smiles.items() if k in unknown_ids}
+ skipped = set(ligand_smiles.keys()) - unknown_ids
+ if skipped:
+ LOG.info(f"Skipping known compounds: {skipped}")
+
+ atoms = pdbx.get_structure(
+ cif_file, model=1, use_author_fields=False, include_bonds=True
+ )
+ atoms = atoms[filter_heavy(atoms)]
+ bonds = _existing_chem_comp_bonds(block)
+
+ for comp_id, smiles in to_process.items():
+ # Tolerant parse (over-valent boron/main-group centres) to stay
+ # consistent with the rest of the ligand-SMILES pipeline; still raises
+ # if even that fails, since a bond-order template is mandatory here.
+ template = mol_from_smiles(smiles)
+ if template is None:
+ raise ValueError(f"Invalid SMILES for {comp_id}: {smiles}")
+ template_heavy = Chem.RemoveHs(template, sanitize=False)
+
+ lig_heavy = _component_reference_instance(atoms, comp_id)
+
+ if force_substructure_match:
+ bonds_to_emit = _bonds_by_substructure_match(comp_id, template, lig_heavy)
+ else:
+ bonds_to_emit = _bonds_by_position(comp_id, template_heavy, lig_heavy)
+
+ for atom_name_1, atom_name_2, value_order, aromatic_flag in bonds_to_emit:
+ bonds.append(
+ (
+ comp_id,
+ atom_name_1,
+ atom_name_2,
+ value_order,
+ aromatic_flag,
+ )
+ )
+
+ _set_chem_comp_bonds(block, bonds)
+
+
+def assign_bond_orders_from_smiles(
+ cif_path: Path,
+ ligand_smiles: dict[str, str],
+ output_path: Path | None = None,
+ force_substructure_match: bool = False,
+) -> Path:
+ """Disk-based wrapper around :func:`enrich_cif_with_smiles_bonds`.
+
+ Parameters
+ ----------
+ cif_path : Path
+ Input mmCIF file.
+ ligand_smiles : dict[str, str]
+ Mapping of component ID (e.g. ``LIG``) to SMILES.
+ output_path : Path | None
+ Output path. Defaults to overwriting *cif_path*.
+ force_substructure_match : bool, default=False
+ If ``True``, skip the positional element check entirely and
+ assign bonds via RDKit substructure matching instead. Use only
+ when CIF atom order is not guaranteed to match SMILES order.
+
+ Returns
+ -------
+ Path
+ Path to the written CIF file.
+
+ Raises
+ ------
+ MissingBondOrderError, ValueError
+ Propagated from :func:`enrich_cif_with_smiles_bonds`. See
+ that function's docstring for the full list of failure modes.
+
+ Notes
+ -----
+ Reads ``cif_path``, enriches the CIF in memory, and writes the result to
+ ``output_path`` (or overwrites ``cif_path`` when ``output_path`` is
+ ``None``). Callers that already hold a ``pdbx.CIFFile`` should use
+ :func:`enrich_cif_with_smiles_bonds` directly to avoid the read/write
+ round-trip.
+
+ **Atom-order assumption.** By default this assumes the CIF heavy-atom order
+ matches the SMILES heavy-atom parse order โ the convention produced by
+ structure-prediction tools (e.g. Boltz, AlphaFold3, Chai-1). Under it the CIF
+ atom -> SMILES atom mapping is the identity, so bond orders copy directly from
+ the template; the function verifies this by comparing the element at each
+ position and raises ``ValueError`` at the first mismatch.
+
+ Set ``force_substructure_match=True`` to fully replace the default path with
+ RDKit substructure matching. This does NOT fall back on failure โ it is the
+ only method used when the flag is set. Slower, can be ambiguous for symmetric
+ molecules, and should only be used for CIFs from tools that don't preserve
+ SMILES atom order.
+ """
+ if output_path is None:
+ output_path = cif_path
+ cif_file = pdbx.CIFFile.read(str(cif_path))
+ enrich_cif_with_smiles_bonds(
+ cif_file,
+ ligand_smiles=ligand_smiles,
+ force_substructure_match=force_substructure_match,
+ )
+ cif_file.write(str(output_path))
+ return output_path
diff --git a/src/plinder/data/annotations/contact_areas.py b/src/plinder/data/annotations/contact_areas.py
new file mode 100644
index 000000000..0f93571b1
--- /dev/null
+++ b/src/plinder/data/annotations/contact_areas.py
@@ -0,0 +1,143 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Chain-pair contact areas from a Voronota-LT radical tessellation.
+
+One tessellation of a biological assembly yields the exact contact area between
+every pair of chains in a single near-linear pass. Areas are Voronoi contact
+areas between van der Waals spheres expanded by a solvent probe, not buried
+SASA, so a pair of chains that never touch has no entry rather than zero.
+
+Cost, measured on the complete icosahedral assembly of 7kmx (1.44 million heavy
+non-water atoms, 840 chains): about 13 s and 3.2 GB of peak memory, i.e. roughly
+9 ยตs and 2.2 KB per atom, almost all of it inside the C++ tessellation. Callers
+that process arbitrary assemblies should cap the atom count (see
+``tessellation_atom_limit`` on :class:`plinder.data.annotations.aggregate_annotations.Entry`).
+"""
+
+from __future__ import annotations
+
+from collections.abc import Mapping
+
+import biotite.structure as struc
+import numpy as np
+from numpy.typing import NDArray
+
+from plinder.core.utils.log import setup_logger
+
+LOG = setup_logger(__name__)
+
+DEFAULT_PROBE_RADIUS = 1.4
+"""Solvent probe radius (ร ) added to every atom before tessellating."""
+
+ChainPairAreas = Mapping[tuple[str, str], float]
+
+
+def tessellation_atom_mask(atoms: struc.AtomArray) -> NDArray[np.bool_]:
+ """Select the atoms that take part in a tessellation: heavy, non-water."""
+ return np.asarray(
+ struc.filter_heavy(atoms) & ~struc.filter_solvent(atoms), dtype=np.bool_
+ )
+
+
+def chain_pair_contact_areas(
+ atoms: struc.AtomArray,
+ *,
+ probe: float = DEFAULT_PROBE_RADIUS,
+) -> dict[tuple[str, str], float]:
+ """Return the Voronota-LT contact area (ร ยฒ) between every pair of chains.
+
+ Hydrogens and waters are excluded before tessellating, so waters count as
+ solvent rather than as a chain. Radii follow Voronota-LT's molecular
+ assignment rules keyed on residue and atom names.
+
+ Parameters
+ ----------
+ atoms : struc.AtomArray
+ Atoms of one biological assembly (or any set of chains) carrying the
+ ``ins_code`` annotation biotite reads from mmCIF.
+ probe : float
+ Solvent probe radius in ร added to every atom.
+
+ Returns
+ -------
+ dict[tuple[str, str], float]
+ Contact area per unordered chain pair, keyed by the lexicographically
+ sorted ``(chain_a, chain_b)`` tuple. Pairs without contact are absent.
+ """
+ from voronotalt import voronotalt_python as vlt
+
+ selected = atoms[tessellation_atom_mask(atoms)]
+ if selected.array_length() == 0:
+ return {}
+ # biotite recreates a deleted ``ins_code`` category as an empty array when
+ # slicing, so check the length rather than the presence of the annotation.
+ insertion_codes = (
+ selected.ins_code
+ if "ins_code" in selected.get_annotation_categories()
+ else None
+ )
+ if insertion_codes is None or len(insertion_codes) != selected.array_length():
+ insertion_codes = np.full(selected.array_length(), "", dtype=str)
+ # Fill the C++ vector in place: a Python list of SWIG proxies would cost
+ # about 1 KB per atom on top of the tessellation itself.
+ balls = vlt.VectorMolecularAtomBall()
+ for chain_id, res_id, ins_code, res_name, atom_name, (x, y, z) in zip(
+ selected.chain_id,
+ selected.res_id,
+ insertion_codes,
+ selected.res_name,
+ selected.atom_name,
+ selected.coord,
+ ):
+ balls.push_back(
+ vlt.MolecularAtomBall(
+ str(chain_id),
+ int(res_id),
+ str(ins_code),
+ str(res_name),
+ str(atom_name),
+ float(x),
+ float(y),
+ float(z),
+ )
+ )
+ if balls.size() != selected.array_length():
+ raise ValueError(
+ "atom annotations have inconsistent lengths: built "
+ f"{balls.size()} balls for {selected.array_length()} atoms"
+ )
+ tessellation = vlt.MolecularRadicalTessellation.from_atoms(
+ balls,
+ probe=probe,
+ compute_only_inter_chain_contacts=True,
+ record_inter_chain_contact_summaries=True,
+ record_everything_possible=False,
+ )
+ areas: dict[tuple[str, str], float] = {}
+ for summary in tessellation.inter_chain_contact_summaries:
+ chain_a, chain_b = str(summary.ID1_chain), str(summary.ID2_chain)
+ if chain_a == chain_b:
+ continue
+ pair = (chain_a, chain_b) if chain_a < chain_b else (chain_b, chain_a)
+ areas[pair] = areas.get(pair, 0.0) + float(summary.area)
+ return areas
+
+
+def partner_contact_areas(
+ chain_pair_areas: ChainPairAreas,
+ member_chains: set[str],
+) -> dict[str, float]:
+ """Sum the contact area of one molecule's chains with every other chain.
+
+ ``member_chains`` are the instance chains forming one molecule (several for
+ a covalently linked multi-chain ligand); contacts between member chains are
+ internal and ignored. The result maps each partner chain to its total
+ contact area with the molecule, sorted by chain ID.
+ """
+ partners: dict[str, float] = {}
+ for (chain_a, chain_b), area in chain_pair_areas.items():
+ if chain_a in member_chains and chain_b not in member_chains:
+ partners[chain_b] = partners.get(chain_b, 0.0) + area
+ elif chain_b in member_chains and chain_a not in member_chains:
+ partners[chain_a] = partners.get(chain_a, 0.0) + area
+ return dict(sorted(partners.items()))
diff --git a/src/plinder/data/utils/annotations/get_ligand_validation.py b/src/plinder/data/annotations/get_ligand_validation.py
similarity index 75%
rename from src/plinder/data/utils/annotations/get_ligand_validation.py
rename to src/plinder/data/annotations/get_ligand_validation.py
index 80e389108..2adf7ee8a 100644
--- a/src/plinder/data/utils/annotations/get_ligand_validation.py
+++ b/src/plinder/data/annotations/get_ligand_validation.py
@@ -2,20 +2,21 @@
# Distributed under the terms of the Apache License 2.0
from __future__ import annotations
+import typing as ty
+from collections.abc import Collection, Sequence
from functools import cached_property
import numpy as np
-from PDBValidation.PDBXReader import ResidueNotFound
-from PDBValidation.Residue import Residue
-from PDBValidation.Validation import PDBValidation
-from PDBValidation.XML import ModelledSubgroupNotFound
from pydantic import ConfigDict, Field, computed_field
from plinder.core.utils.log import setup_logger
-from plinder.data.utils.annotations.utils import DocBaseModel
+from plinder.data.annotations.utils import DocBaseModel
LOG = setup_logger(__name__)
+if ty.TYPE_CHECKING:
+ from PDBValidation.Validation import PDBValidation
+
class ResidueValidationThresholds(DocBaseModel):
model_config = ConfigDict(ser_json_inf_nan="constants")
@@ -30,6 +31,22 @@ def nanmean_return_nan(arr: list[float]) -> float:
return float(np.nanmean(arr))
+def _select_altcode(
+ altcodes: Collection[str],
+ preferred_altcode: str | None = None,
+) -> str:
+ """Select the deposited conformer used by coordinate loading."""
+ if preferred_altcode in altcodes:
+ return str(preferred_altcode)
+ if "." in altcodes:
+ return "."
+ if not altcodes:
+ raise ValueError("residue has no alternative configurations")
+ # Validation exposes altcodes as a set, so retain a deterministic fallback
+ # for malformed/mismatched inputs where the selected source ID is absent.
+ return min(altcodes)
+
+
class ResidueValidation(DocBaseModel):
model_config = ConfigDict(ser_json_inf_nan="constants")
altcode: str = Field(description="Alternative conformation code")
@@ -43,12 +60,14 @@ class ResidueValidation(DocBaseModel):
atom_count: int = Field(description="Number of atoms")
unknown_atom_count: int = Field(description="Number of unknown atoms")
heavy_atom_count: int = Field(description="Number of heavy atoms")
- num_unresolved_heavy_atoms: int = Field(
- description="Number of unresolved heavy atoms"
+ num_unresolved_heavy_atoms: int | None = Field(
+ description="Number of unresolved heavy atoms; null when the reference "
+ "is unavailable or the atom counts are inconsistent"
)
is_outlier: dict[str, bool] = Field(description="Whether the residue is an outlier")
- is_atom_count_consistent: bool = Field(
- description="Whether the atom count is consistent"
+ is_atom_count_consistent: bool | None = Field(
+ description="Whether the atom count is consistent; null when the reference "
+ "is unavailable"
)
has_clashing_partial_occupancy_atoms: bool = Field(
description="Whether the residue has clashing partial occupancy atoms"
@@ -57,8 +76,19 @@ class ResidueValidation(DocBaseModel):
@classmethod
def from_residue(
- cls, chain: str, resnum: str | int, entity: str, doc: PDBValidation
+ cls,
+ chain: str,
+ resnum: str | int,
+ entity: str,
+ doc: PDBValidation,
+ *,
+ preferred_altcode: str | None = None,
) -> ResidueValidation | None:
+ from PDBValidation.PDBXReader import ResidueNotFound
+ from PDBValidation.Residue import Residue
+ from PDBValidation.Validation import PDBValidation
+ from PDBValidation.XML import ModelledSubgroupNotFound
+
try:
residue_with_alts = Residue.CreateFromMmCIFPosition(
chain, resnum, str(entity), doc
@@ -69,35 +99,19 @@ def from_residue(
)
return None
alts = residue_with_alts.listAlt()
- if "." in alts:
- alt = "."
- else:
- alt = list(alts)[0]
try:
+ alt = _select_altcode(alts, preferred_altcode)
residue = residue_with_alts.getAlt(alt)
heavy_atom_count = residue.countAtomsHeavyPDBX()
heavy_atom_count_conop = residue.countAtomsHeavyConop()
- if heavy_atom_count_conop is None:
- heavy_atom_count_conop = 0
- if (
- residue.isType("PolymerChainResidue")
- and np.abs(heavy_atom_count - heavy_atom_count_conop) <= 1
- ):
- heavy_atom_count_conop = heavy_atom_count
- num_unresolved_heavy_atoms = heavy_atom_count_conop - heavy_atom_count
-
- # TODO: uncomment for rerun
- # # set -1 as value for cases where no reference was found
- # num_unresolved_heavy_atoms = -1
- # else:
- # num_unresolved_heavy_atoms = heavy_atom_count_conop - heavy_atom_count
- # if (
- # residue.isType("PolymerChainResidue")
- # and num_unresolved_heavy_atoms >= 1
- # ):
- # # residues have one atom less when in polymer - adjust for it
- # num_unresolved_heavy_atoms -= 1
+ num_unresolved_heavy_atoms = None
+ if heavy_atom_count_conop is not None:
+ difference = heavy_atom_count_conop - heavy_atom_count
+ if residue.isType("PolymerChainResidue") and abs(difference) <= 1:
+ difference = 0
+ if difference >= 0:
+ num_unresolved_heavy_atoms = difference
return cls(
altcode=residue.getAltCode(),
@@ -117,7 +131,11 @@ def from_residue(
s: residue.isOutlier(s)
for s in ["geometry", "density", "chirality", "clashes"]
},
- is_atom_count_consistent=residue.isAtomCountConsistent(),
+ is_atom_count_consistent=(
+ residue.isAtomCountConsistent()
+ if heavy_atom_count_conop is not None
+ else None
+ ),
has_clashing_partial_occupancy_atoms=residue.hasClashingPartialOccupancyAtoms(),
)
except Exception as e:
@@ -169,24 +187,38 @@ class ResidueListValidation(DocBaseModel):
heavy_atom_count: int = Field(
description="Number of heavy atoms across all residues in the list"
)
- num_unresolved_heavy_atoms: int = Field(
- description="Number of unresolved heavy atoms across all residues in the list"
+ num_unresolved_heavy_atoms: int | None = Field(
+ description="Number of unresolved heavy atoms across all residues in the list; "
+ "null if any residue's count is unavailable or inconsistent"
)
max_alt_count: int = Field(
description="The highest number of configurations in a single residue in the list"
)
percent_outliers: dict[str, float] = Field(
- description="__Percentage of outliers for each type of outlier"
+ description="[EXCLUDE] Percentage of outliers for each type of outlier"
+ )
+ thresholds: ResidueValidationThresholds | None = Field(
+ default=None,
+ description="[EXCLUDE] Thresholds used to calculate residue validation percentages",
)
- # TODO: add thresholds in rerun
- # thresholds: ResidueValidationThresholds = Field(
- # description="Thresholds used to determine if a residue is valid"
- # )
+
+ @classmethod
+ def document_properties(
+ cls, prefix: str
+ ) -> ty.Generator[tuple[str, str | None, str], ty.Any, ty.Any]:
+ """Describe the flat validation columns emitted by ``format()``."""
+ yield from super().document_properties(prefix)
+ for outlier_type in ("chirality", "clashes", "density", "geometry"):
+ yield (
+ f"{prefix}_percent_outliers_{outlier_type}",
+ "float",
+ f"Percentage of residues with {outlier_type} outliers",
+ )
@classmethod
def from_residues(
cls,
- residues: list[ResidueValidation],
+ residues: Sequence[ResidueValidation | None],
residue_thresholds: ResidueValidationThresholds,
) -> ResidueListValidation | None:
total_residues = len(residues)
@@ -194,6 +226,10 @@ def from_residues(
num_processed = len(filtered)
if num_processed == 0:
return None
+ unresolved_counts = [residue.num_unresolved_heavy_atoms for residue in filtered]
+ known_counts = [
+ count for count in unresolved_counts if count is not None and count >= 0
+ ]
return cls(
num_residues=total_residues,
num_processed_residues=num_processed,
@@ -227,8 +263,8 @@ def from_residues(
),
atom_count=sum([residue.atom_count for residue in filtered]),
heavy_atom_count=sum([residue.heavy_atom_count for residue in filtered]),
- num_unresolved_heavy_atoms=sum(
- [residue.num_unresolved_heavy_atoms for residue in filtered]
+ num_unresolved_heavy_atoms=(
+ sum(known_counts) if len(known_counts) == total_residues else None
),
max_alt_count=max([residue.alt_count for residue in filtered]),
percent_outliers={
@@ -237,8 +273,7 @@ def from_residues(
/ total_residues
for s in ["geometry", "density", "chirality", "clashes"]
},
- # TODO: add thresholds in rerun
- # thresholds=residue_thresholds,
+ thresholds=residue_thresholds.model_copy(deep=True),
)
def format(self) -> dict[str, float | int | None]:
@@ -258,7 +293,7 @@ class EntryValidation(DocBaseModel):
r: float = Field(
description="The similarity between the observed structure-factor amplitudes and those calculated from the model. See https://www.wwpdb.org/validation/XrayValidationReportHelp"
)
- clashscore: float = Field(
+ clashscore: float | None = Field(
description="The Molprobity Clashscore is an approximation of the overall severity of the clashes in a structure, which is defined as the number of clashes per 1000 atoms (including hydrogens). See https://www.wwpdb.org/validation/XrayValidationReportHelp"
)
percent_rama_outliers: float | None = Field(
@@ -299,20 +334,35 @@ class EntryValidation(DocBaseModel):
def from_entry(cls, doc: PDBValidation) -> EntryValidation:
xml = doc.getValidationXML()
entry = xml.getEntry()
+ unavailable = {None, "?", ".", "NotAvailable"}
+ resolution = entry.get("PDB-resolution")
+ if resolution in unavailable:
+ resolution = np.nan
rfree = entry.get("PDB-Rfree")
- if rfree == "NotAvailable":
+ if rfree in unavailable:
rfree = np.nan
+ r = entry.get("PDB-R")
+ if r in unavailable:
+ r = np.nan
try:
reflns = doc.getReflectionsResolution()
except KeyError:
reflns = None
+ if reflns in unavailable:
+ reflns = None
+ try:
+ pdbx_resolution = doc.getResolution()
+ except KeyError:
+ pdbx_resolution = resolution
+ if pdbx_resolution in unavailable:
+ pdbx_resolution = np.nan
meanI_over_sigI_obs = doc.getMeanIOverSigIObs()
- if meanI_over_sigI_obs == "?":
+ if meanI_over_sigI_obs in unavailable:
meanI_over_sigI_obs = None
return cls(
- resolution=entry.get("PDB-resolution"),
+ resolution=resolution,
rfree=rfree,
- r=entry.get("PDB-R"),
+ r=r,
clashscore=entry.get("clashscore"),
percent_rama_outliers=entry.get("percent-rama-outliers"),
percent_rota_outliers=entry.get("percent-rota-outliers"),
@@ -322,7 +372,7 @@ def from_entry(cls, doc: PDBValidation) -> EntryValidation:
molprobity=doc.calcMolProbityOverallScore(),
mean_b_factor=doc.calcMeanStructureBFactor(),
median_b_factor=doc.calcMedianStructureBFactor(),
- pdbx_resolution=doc.getResolution(),
+ pdbx_resolution=pdbx_resolution,
pdbx_reflns_resolution=reflns,
meanI_over_sigI_obs=meanI_over_sigI_obs,
)
diff --git a/src/plinder/data/annotations/get_similarity_scores.py b/src/plinder/data/annotations/get_similarity_scores.py
new file mode 100644
index 000000000..e0487d8e5
--- /dev/null
+++ b/src/plinder/data/annotations/get_similarity_scores.py
@@ -0,0 +1,4650 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from __future__ import annotations
+
+import hashlib
+import json
+import pickle
+import shutil
+import subprocess
+from bisect import bisect_left
+from collections import Counter, OrderedDict, abc, defaultdict
+from concurrent.futures import ThreadPoolExecutor
+from dataclasses import dataclass, field, replace
+from functools import cache
+from pathlib import Path
+from time import perf_counter
+from typing import Any, Callable, Optional, Sequence, cast
+from uuid import uuid4
+
+import biotite.sequence.align as align
+import numpy as np
+import pandas as pd
+import pyarrow
+import pyarrow as pa
+import pyarrow.compute as pc
+import pyarrow.parquet as pq
+from numpy.typing import NDArray
+from pyarrow import csv
+from rdkit import Chem, DataStructs, Geometry, RDConfig, rdBase
+from rdkit.Chem import ChemicalFeatures, rdShapeAlign, rdShapeHelpers
+from rdkit.Chem.FeatMaps import FeatMaps
+from tqdm import tqdm
+
+from plinder.core.scores.entries import (
+ EntryView,
+ LigandView,
+ SystemView,
+ load_entry_views,
+)
+from plinder.core.scores.mapping import (
+ decode_cigar_residue_positions,
+ expand_residue_positions,
+ unpack_residue_identities,
+)
+from plinder.core.scores.metrics import (
+ SCORE_NAMES,
+ maximum_weight_bipartite_assignment,
+)
+from plinder.core.structure.smallmols_similarity import (
+ MHFP6_N_PERMUTATIONS,
+ mhfp6_bulk_jaccard,
+ mol2mhfp6,
+ mol2morgan_fp,
+)
+from plinder.core.utils import schemas
+from plinder.core.utils.files import write_json_atomic
+from plinder.core.utils.log import setup_logger
+from plinder.data import databases
+from plinder.data.pipeline.config import FoldseekConfig, MMSeqsConfig
+
+LOG = setup_logger(__name__)
+
+# Large entries have millions of distinct pocket pairs; retain only a working set.
+_POCKET_CACHE_MAX_ENTRIES = 100_000
+
+ECFP4_RADIUS = 2
+ECFP4_NBITS = 1024
+ECFP4_PARQUET_METADATA = {
+ b"plinder.fingerprint": b"ECFP4",
+ b"plinder.fingerprint.generator": b"RDKit Morgan",
+ b"plinder.fingerprint.radius": b"2",
+ b"plinder.fingerprint.nbits": b"1024",
+ b"plinder.fingerprint.include_chirality": b"false",
+}
+SCORE_THRESHOLDS_METADATA_KEY = b"plinder.scoring_thresholds"
+HOLO_PROTEIN_SCORES_METADATA_KEY = b"plinder.holo_protein_scores"
+SCORE_METRICS_METADATA_KEY = b"plinder.score_metrics"
+APO_SEARCH_COVERAGE = 0.8
+APO_SEARCH_MIN_SEQ_ID = 0.9
+
+# MHFP6 MinHash fingerprints live in a sibling file with the same
+# ``ligand_smiles_id`` node universe as the ECFP4 table, so the two chemical
+# clustering metrics share every downstream node/expansion path and differ only
+# in their stored fingerprint and similarity measure. See
+# ``plinder.core.structure.smallmols_similarity`` for the citation.
+MHFP6_METRIC = "jaccard_similarity_mhfp6_2048"
+MHFP6_FINGERPRINT_FILE = "ligands_per_smiles_mhfp6.parquet"
+MHFP6_SCORES_DIR = "mhfp6_scores"
+MHFP6_PARQUET_METADATA = {
+ b"plinder.fingerprint": b"MHFP6",
+ b"plinder.fingerprint.generator": b"RDKit rdMHFPFingerprint",
+ b"plinder.fingerprint.radius": b"3",
+ b"plinder.fingerprint.n_permutations": str(MHFP6_N_PERMUTATIONS).encode(),
+ b"plinder.fingerprint.seed": b"42",
+ b"plinder.fingerprint.similarity": b"minhash_jaccard",
+}
+LIGAND_SCORE_MANIFEST = "_manifest.json"
+
+_NON_CANONICAL_AA = str.maketrans({"J": "L", "U": "C", "O": "K"})
+
+
+def score_thresholds_metadata(
+ minimum_threshold: float,
+ minimum_thresholds: dict[str, float],
+) -> bytes:
+ """Encode score-filter thresholds for Parquet completion metadata."""
+ return json.dumps(
+ {
+ "default": float(minimum_threshold),
+ "metrics": {
+ str(metric): float(threshold)
+ for metric, threshold in sorted(minimum_thresholds.items())
+ },
+ },
+ sort_keys=True,
+ separators=(",", ":"),
+ ).encode()
+
+
+def score_metrics_metadata(metrics: abc.Collection[str] | None) -> bytes | None:
+ """Encode an optional retained-metric set for cache validation."""
+ if metrics is None:
+ return None
+ return json.dumps(sorted(set(metrics)), separators=(",", ":")).encode()
+
+
+def score_cache_is_current(
+ path: Path,
+ *,
+ ligand_3d_mode: bytes,
+ minimum_threshold: float,
+ minimum_thresholds: dict[str, float],
+ holo_protein_scores_mode: bytes | None = None,
+ score_metrics: abc.Collection[str] | None = None,
+) -> bool:
+ """Return whether a per-query score file matches the active filters."""
+ try:
+ schema = pq.read_schema(path)
+ pq.read_metadata(path)
+ except (OSError, ValueError):
+ return False
+ metadata = schema.metadata or {}
+ current = (
+ set(schemas.PROTEIN_SIMILARITY_SCHEMA.names).issubset(schema.names)
+ and metadata.get(b"plinder.ligand_3d") == ligand_3d_mode
+ and metadata.get(SCORE_THRESHOLDS_METADATA_KEY)
+ == score_thresholds_metadata(minimum_threshold, minimum_thresholds)
+ and metadata.get(SCORE_METRICS_METADATA_KEY)
+ == score_metrics_metadata(score_metrics)
+ )
+ if holo_protein_scores_mode is not None:
+ current = current and (
+ metadata.get(HOLO_PROTEIN_SCORES_METADATA_KEY) == holo_protein_scores_mode
+ )
+ return current
+
+
+def _atomic_copy_file(source: Path, target: Path) -> None:
+ """Install a file atomically without sharing a writer staging path."""
+ target.parent.mkdir(exist_ok=True, parents=True)
+ staging = target.with_name(f".{target.name}.{uuid4().hex}.tmp")
+ try:
+ shutil.copyfile(source, staging)
+ staging.replace(target)
+ finally:
+ staging.unlink(missing_ok=True)
+
+
+def _atomic_write_parquet(table: pa.Table, target: Path) -> None:
+ """Write a Parquet table atomically with a writer-private staging path."""
+ target.parent.mkdir(exist_ok=True, parents=True)
+ staging = target.with_name(f".{target.name}.{uuid4().hex}.tmp")
+ try:
+ pq.write_table(table, staging)
+ staging.replace(target)
+ finally:
+ staging.unlink(missing_ok=True)
+
+
+def _with_parquet_metadata(
+ table: pa.Table, metadata: abc.Mapping[bytes, bytes] | None
+) -> pa.Table:
+ if not metadata:
+ return table
+ return table.replace_schema_metadata({**(table.schema.metadata or {}), **metadata})
+
+
+def _finite_float_or_zero(value: Any) -> float:
+ """Return a finite alignment value, treating missing values as zero."""
+ try:
+ numeric = float(value)
+ except (TypeError, ValueError):
+ return 0.0
+ return numeric if np.isfinite(numeric) else 0.0
+
+
+def _protein_similarity_lookups() -> tuple[NDArray[np.bool_], NDArray[np.bool_]]:
+ """Build byte-indexed validity and BLOSUM similarity lookup tables."""
+ matrix = align.SubstitutionMatrix.std_protein_matrix()
+ alphabet = list(matrix.get_alphabet1())
+ scores = matrix.score_matrix()
+ valid = np.zeros(256, dtype=bool)
+ similar = np.zeros((256, 256), dtype=bool)
+ for i, aa_i in enumerate(alphabet):
+ code_i = ord(aa_i)
+ valid[code_i] = True
+ for j, aa_j in enumerate(alphabet):
+ pair_score = max(0, scores[i, j])
+ normalization = max(scores[i, i], scores[j, j])
+ similar[code_i, ord(aa_j)] = pair_score / normalization > 0.2
+ return valid, similar
+
+
+_VALID_PROTEIN_AA, _SIMILAR_PROTEIN_AA = _protein_similarity_lookups()
+
+
+def write_ecfp4_fingerprint_table(ligands: pd.DataFrame, output_path: Path) -> None:
+ """Write the fixed ECFP4/1024 fingerprint table with explicit metadata."""
+ table = pa.Table.from_pandas(ligands, preserve_index=False)
+ metadata = {**(table.schema.metadata or {}), **ECFP4_PARQUET_METADATA}
+ pq.write_table(table.replace_schema_metadata(metadata), output_path)
+
+
+def write_mhfp6_fingerprints(unique_ligands: pd.DataFrame, output_dir: Path) -> None:
+ """Write the MHFP6/2048 MinHash table over the shared ligand_smiles_id set.
+
+ ``unique_ligands`` is the already-deduplicated, ``ligand_smiles_id``-indexed
+ frame produced for ECFP4, so the two chemical metrics stay node-aligned. Each
+ MinHash vector is stored as a compact uint32 byte blob, mirroring the ECFP4
+ binary-text column.
+ """
+ smiles_column = "ligand_rdkit_canonical_smiles"
+ minhash_blobs: list[bytes] = []
+ total = len(unique_ligands)
+ started = perf_counter()
+ for index, smiles in enumerate(unique_ligands[smiles_column], start=1):
+ minhash_blobs.append(mol2mhfp6(smiles).tobytes())
+ if index % 5_000 == 0 or index == total:
+ elapsed = perf_counter() - started
+ rate = index / elapsed
+ LOG.info(
+ "MHFP6 fingerprint progress: "
+ f"processed={index}/{total} rate={rate:.1f}/s "
+ f"eta_seconds={(total - index) / rate:.1f}"
+ )
+ mhfp6_table = pd.DataFrame(
+ {
+ "ligand_smiles_id": unique_ligands["ligand_smiles_id"].to_numpy(),
+ smiles_column: unique_ligands[smiles_column].to_numpy(),
+ "mhfp6": minhash_blobs,
+ }
+ )
+ table = pa.Table.from_pandas(mhfp6_table, preserve_index=False)
+ metadata = {**(table.schema.metadata or {}), **MHFP6_PARQUET_METADATA}
+ temporary_path = (output_dir / MHFP6_FINGERPRINT_FILE).with_suffix(".parquet.tmp")
+ pq.write_table(table.replace_schema_metadata(metadata), temporary_path)
+ temporary_path.replace(output_dir / MHFP6_FINGERPRINT_FILE)
+
+
+SORT_ORDER = [
+ ("similarity", "descending"),
+ ("query_system", "ascending"),
+ ("query_ligand_id", "ascending"),
+ ("target_system", "ascending"),
+ ("target_ligand_id", "ascending"),
+]
+INFO_COLUMNS = (
+ "query_system",
+ "query_ligand_id",
+ "target_system",
+ "target_ligand_id",
+ "protein_mapping",
+ "protein_mapper",
+)
+_ChainInstanceMapping = str
+_ChainPairType = tuple[_ChainInstanceMapping, _ChainInstanceMapping]
+_SimilarityScoreDictType = dict[str, float]
+_Ligand3DCandidateType = dict[str, str | float | None]
+_LigandPairScoreType = dict[str, str | int]
+_PocketDataType = tuple[
+ dict[str, dict[int, int]],
+ dict[str, dict[int, Counter[str]]],
+ int,
+ int,
+]
+_PocketPatternInfoType = tuple[str, dict[str, str], bool]
+_PocketPairResultType = tuple[
+ _SimilarityScoreDictType,
+ _SimilarityScoreDictType,
+ dict[str, list[_ChainPairType]],
+]
+_PocketScoreCacheType = dict[tuple[str, str, str], _PocketPairResultType]
+_ProteinScoreResultType = tuple[
+ dict[str, list[_ChainPairType]],
+ _SimilarityScoreDictType,
+ dict[_ChainPairType, pd.DataFrame],
+ str,
+]
+
+
+def load_ligands_from_index(*, annotation: pd.DataFrame) -> pd.DataFrame:
+ """Extract post-ingest ligand-similarity inputs from annotation rows."""
+ columns = {
+ "entry_pdb_id": "pdb_id",
+ "system_id": "system_id",
+ "ligand_smiles": "ligand_rdkit_canonical_smiles",
+ "ligand_unique_ccd_code": "ligand_ccd_code",
+ "ligand_id": "ligand_id",
+ "ligand_asym_id": "ligand_asym_id",
+ }
+ if annotation.empty:
+ return pd.DataFrame(columns=list(columns.values()))
+ eligible = annotation["system_type"].eq("holo") & annotation[
+ "ligand_is_proper"
+ ].fillna(False)
+ ligands = annotation.loc[eligible, list(columns)].rename(columns=columns)
+ return (
+ ligands.dropna(subset=["ligand_id"])
+ .drop_duplicates(subset=["ligand_id"])
+ .reset_index(drop=True)
+ .sort_values("ligand_id")
+ )
+
+
+def load_ligands_from_annotation_table(*, data_dir: Path) -> pd.DataFrame:
+ """Load proper holo ligand instances from the collated annotation table."""
+ columns = [
+ "entry_pdb_id",
+ "system_id",
+ "system_type",
+ "ligand_is_proper",
+ "ligand_smiles",
+ "ligand_unique_ccd_code",
+ "ligand_id",
+ "ligand_asym_id",
+ ]
+ annotation = pd.read_parquet(
+ data_dir / "index" / "annotation_table.parquet",
+ columns=columns,
+ )
+ return load_ligands_from_index(annotation=annotation)
+
+
+def annotate_cofactor_similarity(
+ ligands: pd.DataFrame,
+ *,
+ cofactor_smiles: dict[str, str],
+ threshold: float = 90.0,
+ radius: int = 2,
+ nbits: int = 1024,
+) -> pd.DataFrame:
+ """Annotate unique ligand SMILES against CCD cofactor structures."""
+ cofactor_fingerprints: list[DataStructs.ExplicitBitVect] = []
+ cofactor_codes: list[str] = []
+ for code, smiles in sorted(cofactor_smiles.items()):
+ try:
+ cofactor_fingerprints.append(
+ mol2morgan_fp(smiles, radius=radius, nbits=nbits)
+ )
+ cofactor_codes.append(code)
+ except (TypeError, ValueError):
+ LOG.warning(f"skipping invalid cofactor SMILES for {code}")
+ if not cofactor_fingerprints:
+ raise ValueError("no valid CCD cofactor structures are available")
+
+ result = ligands.copy()
+ maximum_similarities: list[float] = []
+ closest_cofactors: list[str] = []
+ total = len(result)
+ started = perf_counter()
+ for index, binary_fingerprint in enumerate(result["fingerprint"], start=1):
+ fingerprint = DataStructs.CreateFromBinaryText(binary_fingerprint)
+ similarities = DataStructs.BulkTanimotoSimilarity(
+ fingerprint, cofactor_fingerprints
+ )
+ best_index = int(np.argmax(similarities))
+ maximum_similarities.append(float(similarities[best_index] * 100.0))
+ closest_cofactors.append(cofactor_codes[best_index])
+ if index % 5_000 == 0 or index == total:
+ elapsed = perf_counter() - started
+ rate = index / elapsed
+ LOG.info(
+ "cofactor similarity progress: "
+ f"processed={index}/{total} rate={rate:.1f}/s "
+ f"eta_seconds={(total - index) / rate:.1f}"
+ )
+ result["ligand_max_cofactor_similarity"] = np.asarray(
+ maximum_similarities, dtype=np.float32
+ )
+ result["ligand_most_similar_cofactor"] = closest_cofactors
+ result["ligand_is_cofactor_like"] = (
+ result["ligand_max_cofactor_similarity"] >= threshold
+ )
+ return result
+
+
+def compute_ligand_fingerprints(
+ *,
+ data_dir: Path,
+ cofactor_similarity_threshold: float = 90.0,
+ retain_score_shards: bool = False,
+) -> None:
+ """Fingerprint the unique canonical SMILES in a completed ligand ingest."""
+ ligands = load_ligands_from_annotation_table(data_dir=data_dir)
+ for column in ligands.columns:
+ LOG.info(
+ f"compute_ligand_fingerprints: unique {column}={ligands[column].nunique()}"
+ )
+
+ smiles_column = "ligand_rdkit_canonical_smiles"
+ ligands = ligands.dropna(subset=[smiles_column])
+ ligands = ligands[ligands[smiles_column].ne("")].copy()
+ ligands_unique = (
+ ligands[[smiles_column]]
+ .drop_duplicates()
+ .sort_values(smiles_column)
+ .reset_index(drop=True)
+ )
+ ligands_unique.insert(
+ 0,
+ "ligand_smiles_id",
+ np.arange(len(ligands_unique), dtype=np.int32),
+ )
+ total = len(ligands_unique)
+ started = perf_counter()
+ binary_fingerprints: list[bytes] = []
+ for index, smiles in enumerate(ligands_unique[smiles_column], start=1):
+ fingerprint = mol2morgan_fp(
+ smiles,
+ radius=ECFP4_RADIUS,
+ nbits=ECFP4_NBITS,
+ )
+ binary_fingerprints.append(DataStructs.BitVectToBinaryText(fingerprint))
+ if index % 5_000 == 0 or index == total:
+ elapsed = perf_counter() - started
+ rate = index / elapsed
+ LOG.info(
+ "ligand fingerprint progress: "
+ f"processed={index}/{total} rate={rate:.1f}/s "
+ f"eta_seconds={(total - index) / rate:.1f}"
+ )
+ ligands_unique["fingerprint"] = binary_fingerprints
+
+ from plinder.data.annotations.ligand_utils import _get_ccd_smiles, parse_cofactors
+
+ cofactor_codes = parse_cofactors(data_dir)
+ # RDKit SMILES from the CCD atoms (biotite's bundled bt_info), not the CCD
+ # ``pdbx_chem_comp_descriptor`` column: same canonicalization as the ligands'
+ # own ``rdkit_canonical_smiles``, and no ``components.parquet`` dependency.
+ cofactor_smiles = {}
+ for code in cofactor_codes:
+ smi = _get_ccd_smiles(code)
+ if smi:
+ cofactor_smiles[code] = smi
+ missing_cofactors = cofactor_codes.difference(cofactor_smiles)
+ if missing_cofactors:
+ LOG.warning(
+ f"{len(missing_cofactors)} cofactor codes have no CCD SMILES structure"
+ )
+ ligands_unique = annotate_cofactor_similarity(
+ ligands_unique,
+ cofactor_smiles=cofactor_smiles,
+ threshold=cofactor_similarity_threshold,
+ radius=ECFP4_RADIUS,
+ nbits=ECFP4_NBITS,
+ )
+
+ output_dir = data_dir / "fingerprints"
+ output_dir.mkdir(exist_ok=True, parents=True)
+ fingerprint_path = output_dir / "ligands_per_smiles.parquet"
+ score_basis_columns = [
+ "ligand_smiles_id",
+ smiles_column,
+ "fingerprint",
+ ]
+ score_basis_is_unchanged = False
+ if fingerprint_path.is_file():
+ try:
+ existing_metadata = pq.read_schema(fingerprint_path).metadata or {}
+ existing_basis = pd.read_parquet(
+ fingerprint_path,
+ columns=score_basis_columns,
+ )
+ score_basis_is_unchanged = all(
+ existing_metadata.get(key) == value
+ for key, value in ECFP4_PARQUET_METADATA.items()
+ ) and existing_basis.equals(ligands_unique[score_basis_columns])
+ except (OSError, ValueError):
+ score_basis_is_unchanged = False
+ temporary_path = fingerprint_path.with_suffix(".parquet.tmp")
+ write_ecfp4_fingerprint_table(
+ ligands_unique,
+ temporary_path,
+ )
+ temporary_path.replace(fingerprint_path)
+
+ # Occurrence counts and cofactor annotations are always derived anew.
+ (output_dir / "ligand_similarity_annotations.parquet").unlink(missing_ok=True)
+ if score_basis_is_unchanged:
+ LOG.info("ligand fingerprint score basis is unchanged; retaining score shards")
+ elif not retain_score_shards:
+ # Fingerprints define both IDs and the node universe, so old scores are
+ # usable only when the complete ordered score basis is identical.
+ LOG.info("ligand fingerprint score basis changed; removing score shards")
+ for path in (data_dir / "ligand_scores").glob("*.parquet"):
+ path.unlink()
+
+ # MHFP6 shares ECFP4's ligand_smiles_id node universe, so its scores survive
+ # exactly when that universe is unchanged AND the MinHash parameters (radius,
+ # permutations, seed) recorded in the sibling table's metadata still match.
+ mhfp6_path = output_dir / MHFP6_FINGERPRINT_FILE
+ mhfp6_metadata_unchanged = False
+ if mhfp6_path.is_file():
+ try:
+ existing_mhfp6_metadata = pq.read_schema(mhfp6_path).metadata or {}
+ mhfp6_metadata_unchanged = all(
+ existing_mhfp6_metadata.get(key) == value
+ for key, value in MHFP6_PARQUET_METADATA.items()
+ )
+ except (OSError, ValueError):
+ mhfp6_metadata_unchanged = False
+ write_mhfp6_fingerprints(ligands_unique, output_dir)
+ if score_basis_is_unchanged and mhfp6_metadata_unchanged:
+ LOG.info("MHFP6 fingerprint score basis is unchanged; retaining score shards")
+ elif not retain_score_shards:
+ LOG.info("MHFP6 fingerprint score basis changed; removing score shards")
+ for path in (data_dir / MHFP6_SCORES_DIR).glob("*.parquet"):
+ path.unlink()
+
+
+def ligand_scores(
+ *,
+ ligand_ids: list[int],
+ data_dir: Path,
+ output_path: Path,
+ number_id_col: str = "ligand_smiles_id",
+ minimum_similarity: float = 30.0,
+) -> None:
+ """Write all BulkTanimoto edges above ``minimum_similarity``."""
+ fingerprint_path = data_dir / "fingerprints" / "ligands_per_smiles.parquet"
+ fingerprint_metadata = pq.read_schema(fingerprint_path).metadata or {}
+ if any(
+ fingerprint_metadata.get(key) != value
+ for key, value in ECFP4_PARQUET_METADATA.items()
+ ):
+ raise ValueError("ligand fingerprint metadata is not ECFP4/1024")
+ all_ligands = pd.read_parquet(fingerprint_path)
+ fingerprints = [
+ DataStructs.CreateFromBinaryText(value) for value in all_ligands["fingerprint"]
+ ]
+ if len(fingerprints) != len(all_ligands):
+ raise ValueError("ligands don't match fingerprints")
+ node_ids = all_ligands[number_id_col].astype(int).tolist()
+ positions = {node_id: index for index, node_id in enumerate(node_ids)}
+ missing = sorted(set(ligand_ids).difference(positions))
+ if missing:
+ raise ValueError(f"unknown ligand IDs: {missing[:10]}")
+
+ minimum_fraction = minimum_similarity / 100.0
+ rows: list[dict[str, int | float]] = []
+ for ligand_id in ligand_ids:
+ similarities = DataStructs.BulkTanimotoSimilarity(
+ fingerprints[positions[ligand_id]], fingerprints
+ )
+ rows.extend(
+ {
+ "query_ligand_id": ligand_id,
+ "target_ligand_id": target_id,
+ "tanimoto_similarity_ecfp4_1024": similarity * 100.0,
+ }
+ for target_id, similarity in zip(node_ids, similarities, strict=True)
+ if similarity >= minimum_fraction
+ )
+ table = pa.Table.from_pylist(
+ rows,
+ schema=schemas.TANIMOTO_SCORE_SCHEMA.with_metadata(ECFP4_PARQUET_METADATA),
+ )
+ _atomic_write_parquet(table, output_path)
+
+
+def _load_mhfp6_matrix(
+ data_dir: Path, *, number_id_col: str
+) -> tuple[list[int], NDArray[np.uint32]]:
+ """Load ligand IDs and their ID-ordered MHFP6 MinHash matrix."""
+ fingerprint_path = data_dir / "fingerprints" / MHFP6_FINGERPRINT_FILE
+ fingerprint_metadata = pq.read_schema(fingerprint_path).metadata or {}
+ if any(
+ fingerprint_metadata.get(key) != value
+ for key, value in MHFP6_PARQUET_METADATA.items()
+ ):
+ raise ValueError("ligand fingerprint metadata is not MHFP6/2048")
+ all_ligands = pd.read_parquet(fingerprint_path)
+ node_ids = all_ligands[number_id_col].astype(int).tolist()
+ matrix = np.frombuffer(b"".join(all_ligands["mhfp6"]), dtype=np.uint32).reshape(
+ len(all_ligands), MHFP6_N_PERMUTATIONS
+ )
+ return node_ids, matrix
+
+
+def mhfp6_ligand_scores(
+ *,
+ ligand_ids: list[int],
+ data_dir: Path,
+ output_path: Path,
+ number_id_col: str = "ligand_smiles_id",
+ minimum_similarity: float = 30.0,
+) -> None:
+ """Write all MHFP6 MinHash-Jaccard edges above ``minimum_similarity``."""
+ node_ids, matrix = _load_mhfp6_matrix(data_dir, number_id_col=number_id_col)
+ positions = {node_id: index for index, node_id in enumerate(node_ids)}
+ missing = sorted(set(ligand_ids).difference(positions))
+ if missing:
+ raise ValueError(f"unknown ligand IDs: {missing[:10]}")
+ minimum_fraction = minimum_similarity / 100.0
+ rows: list[dict[str, int | float]] = []
+ for ligand_id in ligand_ids:
+ similarities = mhfp6_bulk_jaccard(matrix[positions[ligand_id]], matrix)
+ for target_id, similarity in zip(node_ids, similarities, strict=True):
+ if similarity >= minimum_fraction:
+ rows.append(
+ {
+ "query_ligand_id": ligand_id,
+ "target_ligand_id": target_id,
+ MHFP6_METRIC: float(similarity) * 100.0,
+ }
+ )
+ table = pa.Table.from_pylist(
+ rows,
+ schema=schemas.MHFP6_SCORE_SCHEMA.with_metadata(MHFP6_PARQUET_METADATA),
+ )
+ _atomic_write_parquet(table, output_path)
+
+
+def build_ligand_similarity_annotations(
+ *,
+ unique_ligands: pd.DataFrame,
+) -> pd.DataFrame:
+ """Return public unique-SMILES annotations without fingerprint bytes."""
+ return unique_ligands.drop(columns=["fingerprint"]).copy()
+
+
+def _check_self_score_coverage(
+ score_paths: list[Path],
+ *,
+ metric: str,
+ expected_query_ids: set[int],
+ label: str,
+) -> None:
+ """Require every fingerprint node to appear as a 100-percent self edge."""
+ observed_query_ids: set[int] = set()
+ for path in score_paths:
+ self_scores = pd.read_parquet(
+ path,
+ columns=["query_ligand_id"],
+ filters=[(metric, "==", 100.0)],
+ )
+ observed_query_ids.update(self_scores["query_ligand_id"].astype(int))
+ if observed_query_ids != expected_query_ids:
+ missing = sorted(expected_query_ids.difference(observed_query_ids))
+ extra = sorted(observed_query_ids.difference(expected_query_ids))
+ raise ValueError(
+ f"{label} score shards do not cover the fingerprint set: "
+ f"missing={missing[:10]}, extra={extra[:10]}"
+ )
+
+
+def fingerprint_basis_sha256(
+ path: Path,
+ *,
+ number_id_col: str,
+ fingerprint_col: str,
+) -> str:
+ """Hash the ID-ordered fingerprint vectors that define chemical scores."""
+ digest = hashlib.sha256()
+ digest.update(number_id_col.encode())
+ digest.update(b"\0")
+ digest.update(fingerprint_col.encode())
+ parquet = pq.ParquetFile(path)
+ for batch in parquet.iter_batches(columns=[number_id_col, fingerprint_col]):
+ ids = batch.column(0).to_pylist()
+ fingerprints = batch.column(1).to_pylist()
+ for ligand_id, fingerprint in zip(ids, fingerprints, strict=True):
+ value = bytes(fingerprint)
+ digest.update(int(ligand_id).to_bytes(8, "little", signed=True))
+ digest.update(len(value).to_bytes(8, "little"))
+ digest.update(value)
+ return digest.hexdigest()
+
+
+def ligand_score_manifest_payload(
+ *,
+ fingerprint_path: Path,
+ fingerprint_col: str,
+ metric: str,
+ minimum_similarity: float,
+ number_id_col: str,
+) -> dict[str, str | float]:
+ """Describe the exact fingerprint basis and cutoff behind score shards."""
+ return {
+ "metric": metric,
+ "minimum_similarity": float(minimum_similarity),
+ "number_id_column": number_id_col,
+ "fingerprint_column": fingerprint_col,
+ "fingerprint_basis_sha256": fingerprint_basis_sha256(
+ fingerprint_path,
+ number_id_col=number_id_col,
+ fingerprint_col=fingerprint_col,
+ ),
+ }
+
+
+def annotate_ligand_similarity(
+ *,
+ data_dir: Path,
+ minimum_similarity: float = 30.0,
+ number_id_col: str = "ligand_smiles_id",
+) -> Path:
+ """Write unique-SMILES identifiers and cofactor annotations for the index."""
+ fingerprint_dir = data_dir / "fingerprints"
+ unique_ligands = pd.read_parquet(fingerprint_dir / "ligands_per_smiles.parquet")
+ score_paths = sorted((data_dir / "ligand_scores").glob("*.parquet"))
+ if len(unique_ligands) and not score_paths:
+ raise FileNotFoundError("no BulkTanimoto score shards were generated")
+ expected_query_ids = set(unique_ligands["ligand_smiles_id"].astype(int))
+ _check_self_score_coverage(
+ score_paths,
+ metric="tanimoto_similarity_ecfp4_1024",
+ expected_query_ids=expected_query_ids,
+ label="BulkTanimoto",
+ )
+ write_json_atomic(
+ data_dir / "ligand_scores" / LIGAND_SCORE_MANIFEST,
+ ligand_score_manifest_payload(
+ fingerprint_path=fingerprint_dir / "ligands_per_smiles.parquet",
+ fingerprint_col="fingerprint",
+ metric="tanimoto_similarity_ecfp4_1024",
+ minimum_similarity=minimum_similarity,
+ number_id_col=number_id_col,
+ ),
+ )
+ # MHFP6 scoring is opt-in, but once shards exist they must cover the same
+ # unique-SMILES node universe as the ECFP4 shards.
+ mhfp6_paths = sorted((data_dir / MHFP6_SCORES_DIR).glob("*.parquet"))
+ if mhfp6_paths:
+ _check_self_score_coverage(
+ mhfp6_paths,
+ metric=MHFP6_METRIC,
+ expected_query_ids=expected_query_ids,
+ label="MHFP6",
+ )
+ write_json_atomic(
+ data_dir / MHFP6_SCORES_DIR / LIGAND_SCORE_MANIFEST,
+ ligand_score_manifest_payload(
+ fingerprint_path=fingerprint_dir / MHFP6_FINGERPRINT_FILE,
+ fingerprint_col="mhfp6",
+ metric=MHFP6_METRIC,
+ minimum_similarity=minimum_similarity,
+ number_id_col=number_id_col,
+ ),
+ )
+ annotations = build_ligand_similarity_annotations(
+ unique_ligands=unique_ligands,
+ )
+ output_path = fingerprint_dir / "ligand_similarity_annotations.parquet"
+ _atomic_write_parquet(
+ pa.Table.from_pandas(annotations, preserve_index=False), output_path
+ )
+ return output_path
+
+
+PHARMACOPHORE_FEATURES = frozenset(
+ {
+ "Donor",
+ "Acceptor",
+ "NegIonizable",
+ "PosIonizable",
+ "ZnBinder",
+ "Aromatic",
+ "Hydrophobe",
+ "LumpedHydrophobe",
+ }
+)
+_PharmacophoreFeatures = tuple[Any, ...]
+PHARMACOPHORE_FEATURE_TYPE = pa.list_(
+ pa.struct(
+ [
+ pa.field("family", pa.string()),
+ pa.field("type", pa.string()),
+ pa.field("atom_ids", pa.list_(pa.uint32())),
+ pa.field("weights", pa.list_(pa.float64())),
+ ]
+ )
+)
+# RDKit ShapeAlign supplies default radii for the usual organic elements but
+# raises for coordination metals such as HEM iron. Other elements receive a
+# custom periodic-table radius without changing the molecule or canonical SDF.
+SHAPE_DEFAULT_ATOMIC_NUMBERS = frozenset({1, 6, 7, 8, 9, 15, 16, 17, 35, 53})
+LIGAND_SHAPE_COMPARABILITY_CACHE_SIZE = 4096
+_LIGAND_SHAPE_COMPARABILITY_CACHE: OrderedDict[str, bool] = OrderedDict()
+
+
+@cache
+def _get_feature_scoring_context() -> tuple[Any, dict[str, FeatMaps.FeatMapParams]]:
+ """Load RDKit's pharmacophore definitions only when shape scoring is used."""
+ build_feature_factory = cast(Any, ChemicalFeatures).BuildFeatureFactory
+ factory = build_feature_factory(str(Path(RDConfig.RDDataDir) / "BaseFeatures.fdef"))
+ parameters = {
+ family: FeatMaps.FeatMapParams() for family in factory.GetFeatureFamilies()
+ }
+ return factory, parameters
+
+
+def align_molecules(
+ reference: Chem.Mol,
+ mobile: Chem.Mol,
+ max_preiters: int = 100,
+ max_postiters: int = 100,
+) -> tuple[float, float]:
+ """Shape-align ``mobile`` onto ``reference`` and return shape/color scores."""
+ reference_options = _shape_input_options(reference)
+ mobile_options = _shape_input_options(mobile)
+ shape, color = rdShapeAlign.AlignMol(
+ reference,
+ mobile,
+ reference_options,
+ mobile_options,
+ -1,
+ -1,
+ 1.0,
+ max_preiters,
+ max_postiters,
+ )
+ return float(shape), float(color)
+
+
+def _shape_input_options(molecule: Chem.Mol) -> Any:
+ """Supply VdW radii for atoms outside ShapeAlign's default organic set."""
+ options = rdShapeAlign.ShapeInputOptions()
+ periodic_table = Chem.GetPeriodicTable()
+ options.atomRadii = [
+ (atom.GetIdx(), float(periodic_table.GetRvdw(atom.GetAtomicNum())))
+ for atom in molecule.GetAtoms()
+ if atom.GetAtomicNum() not in SHAPE_DEFAULT_ATOMIC_NUMBERS
+ and atom.GetAtomicNum() > 0
+ ]
+ return options
+
+
+def get_feature_map_score(
+ mol_1: Chem.Mol,
+ mol_2: Chem.Mol,
+ score_mode: int = FeatMaps.FeatMapScoreMode.All,
+ features_1: Sequence[Any] | None = None,
+ features_2: Sequence[Any] | None = None,
+) -> float:
+ """Calculate the normalized pharmacophore feature overlap."""
+ factory, parameters = _get_feature_scoring_context()
+ molecules_and_features = ((mol_1, features_1), (mol_2, features_2))
+ feature_lists = [
+ list(features)
+ if features is not None
+ else [
+ feature
+ for feature in factory.GetFeaturesForMol(molecule)
+ if feature.GetFamily() in PHARMACOPHORE_FEATURES
+ ]
+ for molecule, features in molecules_and_features
+ ]
+ denominator = min(len(features) for features in feature_lists)
+ if denominator == 0:
+ return 0.0
+ feature_map_type = cast(Any, FeatMaps.FeatMap)
+ feature_map = feature_map_type(
+ feats=feature_lists[0],
+ weights=[1] * len(feature_lists[0]),
+ params=parameters,
+ )
+ feature_map.scoreMode = score_mode
+ return float(feature_map.ScoreFeats(feature_lists[1]) / denominator)
+
+
+def get_sucos_score(
+ mol_1: Chem.Mol,
+ mol_2: Chem.Mol,
+ score_mode: int = FeatMaps.FeatMapScoreMode.All,
+ features_1: Sequence[Any] | None = None,
+ features_2: Sequence[Any] | None = None,
+) -> float:
+ """Calculate SuCOS from feature overlap and shape protrusion distance."""
+ feature_map_score = float(
+ np.clip(
+ get_feature_map_score(
+ mol_1,
+ mol_2,
+ score_mode,
+ features_1,
+ features_2,
+ ),
+ 0,
+ 1,
+ )
+ )
+ protrude_distance = float(
+ np.clip(
+ rdShapeHelpers.ShapeProtrudeDist(mol_1, mol_2, allowReordering=False),
+ 0,
+ 1,
+ )
+ )
+ return 0.5 * feature_map_score + 0.5 * (1 - protrude_distance)
+
+
+def _pharmacophore_features(molecule: Chem.Mol) -> _PharmacophoreFeatures:
+ """Detect the pharmacophore features of an unmodified reference ligand."""
+ factory, _ = _get_feature_scoring_context()
+ return tuple(
+ feature
+ for feature in factory.GetFeaturesForMol(molecule)
+ if feature.GetFamily() in PHARMACOPHORE_FEATURES
+ )
+
+
+@cache
+def _pharmacophore_weights() -> dict[str, tuple[float, ...]]:
+ """Read the position weights used by the installed RDKit feature factory."""
+ result = {}
+ feature_type = ""
+ for line in (
+ (Path(RDConfig.RDDataDir) / "BaseFeatures.fdef").read_text().splitlines()
+ ):
+ fields = line.split()
+ if fields and fields[0] == "DefineFeature":
+ feature_type = fields[1]
+ elif fields and fields[0] == "Weights":
+ weights = [float(value) for value in fields[1].split(",")]
+ total = sum(weights)
+ result[feature_type] = tuple(weight / total for weight in weights)
+ return result
+
+
+def _pharmacophore_records(features: Sequence[Any]) -> list[dict[str, Any]]:
+ weights = _pharmacophore_weights()
+ return [
+ {
+ "family": f.GetFamily(),
+ "type": f.GetType(),
+ "atom_ids": list(f.GetAtomIds()),
+ "weights": list(weights[f.GetType()]),
+ }
+ for f in features
+ ]
+
+
+def ligand_pharmacophore_records(
+ sdf: bytes, *, label: str
+) -> list[dict[str, Any]] | None:
+ """Detect feature atom memberships and weights once per canonical SDF."""
+ molecule = load_sdf_molecule_block(sdf, label=label)
+ if molecule is None:
+ return None
+ molecule = prepare_ligand_for_3d_scoring(molecule)
+ try:
+ return _pharmacophore_records(_pharmacophore_features(molecule))
+ except Exception as exc:
+ LOG.warning("pharmacophore detection failed for %s: %s", label, exc)
+ return None
+
+
+def _aligned_pharmacophore_features(
+ aligned: Chem.Mol, records: Sequence[dict[str, Any]]
+) -> _PharmacophoreFeatures:
+ """Locate cached feature definitions directly on the aligned atom coordinates."""
+ coordinates = aligned.GetConformer().GetPositions()
+ return tuple(
+ ChemicalFeatures.FreeChemicalFeature(
+ record["family"],
+ record["type"],
+ Geometry.Point3D(
+ *(
+ coordinates[record["atom_ids"]]
+ * np.asarray(record["weights"])[:, None]
+ ).sum(axis=0)
+ ),
+ )
+ for record in records
+ )
+
+
+def _prepare_unsanitized_sdf_molecule(molecule: Chem.Mol, *, label: str) -> Chem.Mol:
+ """Prepare a permissively parsed molecule without rejecting bad valence."""
+ try:
+ molecule.UpdatePropertyCache(strict=False)
+ except Exception as exc:
+ LOG.debug("property-cache update failed for %s: %s", label, exc)
+ return molecule
+ sanitize_ops = (
+ Chem.SanitizeFlags.SANITIZE_ALL ^ Chem.SanitizeFlags.SANITIZE_PROPERTIES
+ )
+ try:
+ failed_operation = Chem.SanitizeMol(
+ molecule,
+ sanitizeOps=sanitize_ops,
+ catchErrors=True,
+ )
+ except Exception as exc:
+ LOG.debug("partial sanitization failed for %s: %s", label, exc)
+ else:
+ if failed_operation != Chem.SanitizeFlags.SANITIZE_NONE:
+ LOG.debug(
+ "partial sanitization stopped at operation %s for %s",
+ failed_operation,
+ label,
+ )
+ return molecule
+
+
+def load_sdf_molecule(sdf_file: Path) -> Chem.Mol | None:
+ """Load one SDF, falling back to permissive parsing for bad valence."""
+ try:
+ with rdBase.BlockLogs():
+ molecule = Chem.MolFromMolFile(str(sdf_file))
+ except Exception:
+ molecule = None
+ if molecule is None:
+ try:
+ with rdBase.BlockLogs():
+ molecule = Chem.MolFromMolFile(
+ str(sdf_file), sanitize=False, strictParsing=False
+ )
+ except Exception as exc:
+ LOG.warning("failed loading ligand SDF %s: %s", sdf_file, exc)
+ return None
+ if molecule is not None:
+ molecule = _prepare_unsanitized_sdf_molecule(molecule, label=str(sdf_file))
+ if molecule is None or molecule.GetNumConformers() == 0:
+ return None
+ return molecule
+
+
+def load_sdf_molecule_block(sdf: bytes, *, label: str) -> Chem.Mol | None:
+ """Load one packed SDF record, with a permissive bad-valence fallback."""
+ try:
+ block = sdf.decode("utf-8")
+ except (AttributeError, UnicodeDecodeError) as exc:
+ LOG.warning("failed decoding packed ligand SDF %s: %s", label, exc)
+ return None
+ try:
+ with rdBase.BlockLogs():
+ molecule = Chem.MolFromMolBlock(block)
+ except Exception:
+ molecule = None
+ if molecule is None:
+ try:
+ with rdBase.BlockLogs():
+ molecule = Chem.MolFromMolBlock(
+ block, sanitize=False, strictParsing=False
+ )
+ except Exception as exc:
+ LOG.warning("failed loading packed ligand SDF %s: %s", label, exc)
+ return None
+ if molecule is not None:
+ molecule = _prepare_unsanitized_sdf_molecule(molecule, label=label)
+ if molecule is None or molecule.GetNumConformers() == 0:
+ return None
+ return molecule
+
+
+def prepare_ligand_for_3d_scoring(molecule: Chem.Mol) -> Chem.Mol | None:
+ """Clone a ligand after checking that it contains an explicit heavy atom."""
+ if not any(atom.GetAtomicNum() > 1 for atom in molecule.GetAtoms()):
+ return None
+ return Chem.Mol(molecule)
+
+
+def canonical_ligand_sdf_path(data_dir: Path, *, pdb_id: str, asym_id: str) -> Path:
+ """Return the canonical ASU SDF path for one ligand occurrence."""
+ return (
+ data_dir
+ / "raw_entries"
+ / pdb_id[-3:-1]
+ / pdb_id
+ / "ligand_files"
+ / f"{asym_id}.sdf"
+ )
+
+
+def is_ligand_shape_comparable(sdf_file: Path) -> bool:
+ """Test whether one canonical SDF supports shape, color, and SuCOS scoring."""
+ molecule = load_sdf_molecule(sdf_file)
+ if molecule is None:
+ return False
+ prepared = prepare_ligand_for_3d_scoring(molecule)
+ if prepared is None:
+ return False
+ positions = prepared.GetConformer().GetPositions()
+ if not np.isfinite(positions).all():
+ LOG.warning(f"ligand SDF has non-finite coordinates ({sdf_file})")
+ return False
+
+ # Capability depends on the sanitized molecular graph, while each ASU copy
+ # differs only in its coordinates. Loading every SDF above still validates
+ # its conformer; reusing a successful graph-level probe avoids repeatedly
+ # self-aligning large repeated ligands (e.g. symmetry-related oligos).
+ try:
+ cache_key = Chem.MolToSmiles(
+ prepared,
+ canonical=True,
+ isomericSmiles=True,
+ )
+ except Exception:
+ cache_key = None
+ if cache_key is not None and cache_key in _LIGAND_SHAPE_COMPARABILITY_CACHE:
+ _LIGAND_SHAPE_COMPARABILITY_CACHE.move_to_end(cache_key)
+ return _LIGAND_SHAPE_COMPARABILITY_CACHE[cache_key]
+
+ reference = Chem.Mol(prepared)
+ mobile = Chem.Mol(prepared)
+ try:
+ shape, color = align_molecules(reference, mobile)
+ sucos = get_sucos_score(reference, mobile)
+ except Exception as exc:
+ LOG.warning(f"ligand SDF is not shape-comparable ({sdf_file}): {exc}")
+ return False
+ comparable = all(np.isfinite(value) for value in (shape, color, sucos))
+ if comparable and cache_key is not None:
+ _LIGAND_SHAPE_COMPARABILITY_CACHE[cache_key] = True
+ _LIGAND_SHAPE_COMPARABILITY_CACHE.move_to_end(cache_key)
+ while (
+ len(_LIGAND_SHAPE_COMPARABILITY_CACHE)
+ > LIGAND_SHAPE_COMPARABILITY_CACHE_SIZE
+ ):
+ _LIGAND_SHAPE_COMPARABILITY_CACHE.popitem(last=False)
+ return comparable
+
+
+def annotate_ligand_3d_score_ability(
+ ligands: pd.DataFrame, *, data_dir: Path
+) -> pd.DataFrame:
+ """Annotate each ligand occurrence using its canonical ASU conformation."""
+ required = {"pdb_id", "ligand_asym_id"}
+ missing = required.difference(ligands.columns)
+ if missing:
+ raise ValueError(f"missing ligand SDF identifiers: {sorted(missing)}")
+ result = ligands.copy()
+ comparability_by_sdf: dict[Path, bool] = {}
+ comparabilities = []
+ for pdb_id, asym_id in result[["pdb_id", "ligand_asym_id"]].itertuples(
+ index=False, name=None
+ ):
+ sdf_file = canonical_ligand_sdf_path(
+ data_dir,
+ pdb_id=str(pdb_id),
+ asym_id=str(asym_id),
+ )
+ if sdf_file not in comparability_by_sdf:
+ comparability_by_sdf[sdf_file] = is_ligand_shape_comparable(sdf_file)
+ comparabilities.append(comparability_by_sdf[sdf_file])
+ result["ligand_is_shape_comparable"] = pd.array(comparabilities, dtype="boolean")
+ return result
+
+
+def get_sequence_similarity(seq_str1: str, seq_str2: str) -> tuple[float, float]:
+ """
+ Calculate the protein similarity score of an alignment.
+
+ If the alignment contains more than two protein sequences,
+ all pairwise scores are counted.
+
+ Parameters
+ ----------
+ seq_str1 : str
+ First protein sequence
+ seq_str2 : str
+ Second protein sequence
+
+ Returns
+ -------
+ tuple[float, float]
+ Sequence identity and sequence similarity score.
+ """
+ # Keep the established scoring semantics: remove gaps independently before
+ # comparing positions, and map J/U/O to their ProteinSequence equivalents.
+ # A byte lookup avoids constructing Biotite sequence/alignment objects for
+ # every search hit, which dominates mapping time for dense query chains.
+ s1 = seq_str1.translate(_NON_CANONICAL_AA).replace("-", "").encode("ascii")
+ s2 = seq_str2.translate(_NON_CANONICAL_AA).replace("-", "").encode("ascii")
+ if not s1 or len(s1) != len(s2):
+ raise ValueError("aligned sequences must have equal non-zero lengths")
+ codes1 = np.frombuffer(s1, dtype=np.uint8)
+ codes2 = np.frombuffer(s2, dtype=np.uint8)
+ if not np.all(_VALID_PROTEIN_AA[codes1]) or not np.all(_VALID_PROTEIN_AA[codes2]):
+ raise ValueError("aligned sequence contains an unsupported residue")
+ identity = float(np.mean(codes1 == codes2))
+ similarity = float(np.mean(_SIMILAR_PROTEIN_AA[codes1, codes2]))
+ return identity, similarity
+
+
+def get_sequence_similarity_helper(seq_str1: str, seq_str2: str) -> float:
+ try:
+ return get_sequence_similarity(seq_str1, seq_str2)[1]
+ except Exception:
+ return 0
+
+
+def _alignment_search_command(
+ *,
+ aln_type: str,
+ query_db: Path,
+ target_db: Path,
+ search_db: Path,
+ tmp_dir: Path,
+ alignment_config: FoldseekConfig | MMSeqsConfig,
+ threads: int,
+ expand_exact_clusters: bool = False,
+) -> list[str]:
+ """Build a representative-target search from the configured filters."""
+ command = [
+ aln_type,
+ "search",
+ str(query_db),
+ str(target_db),
+ str(search_db),
+ str(tmp_dir),
+ "-a",
+ "-e",
+ f"{alignment_config.evalue}",
+ "-s",
+ f"{alignment_config.sensitivity}",
+ "--max-seqs",
+ f"{alignment_config.max_seqs}",
+ "-c",
+ f"{alignment_config.coverage}",
+ "--cov-mode",
+ "2",
+ "--min-seq-id",
+ f"{alignment_config.min_seq_id}",
+ ]
+ if aln_type == "mmseqs":
+ if not isinstance(alignment_config, MMSeqsConfig):
+ raise TypeError("mmseqs search requires MMSeqsConfig")
+ if expand_exact_clusters:
+ raise ValueError("MMseqs cluster expansion is a separate workflow")
+ elif aln_type == "foldseek":
+ if not isinstance(alignment_config, FoldseekConfig):
+ raise TypeError("foldseek search requires FoldseekConfig")
+ command.extend(["--sort-by-structure-bits", "0"])
+ if expand_exact_clusters:
+ command.extend(["--cluster-search", "1"])
+ else:
+ raise ValueError(f"unsupported alignment type: {aln_type}")
+ command.extend(["--threads", str(threads)])
+ return command
+
+
+def run_alignment(
+ aln_type: str,
+ query_db: Path,
+ target_db: Path,
+ search_target_db: Path,
+ search_db: Path,
+ aln_file: Path,
+ alignment_config: FoldseekConfig | MMSeqsConfig,
+ cluster_alignment_db: Path | None = None,
+ tmp_dir: Path = Path.cwd() / "tmp",
+ remove_tmp: bool = True,
+ threads: int = 1,
+ include_target_pdb_id: bool = True,
+ query_ids_only: bool = False,
+ id_column: str = "query",
+) -> set[str] | None:
+ if id_column not in {"query", "target"}:
+ raise ValueError(f"unsupported alignment ID column: {id_column}")
+
+ def remove_search_results() -> None:
+ for filename in search_db.parent.glob(f"{search_db.name}*"):
+ if filename.is_dir():
+ shutil.rmtree(filename)
+ elif filename.is_file():
+ filename.unlink()
+
+ # A failed search may leave a partial result DB. Always start this
+ # scratch-scoped operation from a clean prefix so Slurm retries work.
+ remove_search_results()
+
+ expand_mmseqs_clusters = aln_type == "mmseqs" and cluster_alignment_db is not None
+ representative_result = (
+ search_db.parent / f"{search_db.name}_representatives"
+ if expand_mmseqs_clusters
+ else search_db
+ )
+ search_commands = _alignment_search_command(
+ aln_type=aln_type,
+ query_db=query_db,
+ target_db=search_target_db,
+ search_db=representative_result,
+ tmp_dir=tmp_dir,
+ alignment_config=alignment_config,
+ threads=threads,
+ expand_exact_clusters=(
+ aln_type == "foldseek" and search_target_db != target_db
+ ),
+ )
+ format_output = (
+ id_column
+ if query_ids_only
+ else (
+ "query,target,qlen,fident,alnlen,qstart,qend,tstart,tend,evalue,bits,"
+ "qcov,tcov,cigar,qaln,taln"
+ )
+ )
+ if aln_type == "foldseek" and not query_ids_only:
+ format_output += ",lddt"
+ subprocess.check_call(search_commands, stdout=subprocess.DEVNULL)
+ if expand_mmseqs_clusters:
+ assert cluster_alignment_db is not None
+ expanded_result = search_db.parent / f"{search_db.name}_expanded"
+ subprocess.check_call(
+ [
+ "mmseqs",
+ "expandaln",
+ str(query_db),
+ str(target_db),
+ str(representative_result),
+ str(cluster_alignment_db),
+ str(expanded_result),
+ "--expansion-mode",
+ "0",
+ "--threads",
+ str(threads),
+ ],
+ stdout=subprocess.DEVNULL,
+ )
+ # Re-align expanded members so scores and E-values are calculated for
+ # the full target DB rather than copied from its representatives.
+ subprocess.check_call(
+ [
+ "mmseqs",
+ "align",
+ str(query_db),
+ str(target_db),
+ str(expanded_result),
+ str(search_db),
+ "-a",
+ "-e",
+ f"{alignment_config.evalue}",
+ "-c",
+ f"{alignment_config.coverage}",
+ "--cov-mode",
+ "2",
+ "--min-seq-id",
+ f"{alignment_config.min_seq_id}",
+ "--threads",
+ str(threads),
+ ],
+ stdout=subprocess.DEVNULL,
+ )
+
+ # Foldseek's cluster-search DB contains the expanded member records needed
+ # by convertalis, so a portable search bundle need not also ship full_db.
+ conversion_target_db = search_target_db if aln_type == "foldseek" else target_db
+ convert_commands = [
+ aln_type,
+ "convertalis",
+ str(query_db),
+ str(conversion_target_db),
+ str(search_db),
+ str(aln_file.with_suffix(".tsv")),
+ "--format-mode",
+ "4",
+ "--format-output",
+ format_output,
+ "--threads",
+ str(threads),
+ ]
+ subprocess.check_call(convert_commands, stdout=subprocess.DEVNULL)
+
+ query_ids = None
+ if query_ids_only:
+ with aln_file.with_suffix(".tsv").open() as handle:
+ query_ids = {line.strip() for line in handle if line.strip()}
+ query_ids.discard(id_column)
+ else:
+ _stream_alignment_tsv_to_dataset(
+ aln_file.with_suffix(".tsv"),
+ aln_file.with_suffix(".parquet"),
+ aln_type=aln_type,
+ include_target_pdb_id=include_target_pdb_id,
+ )
+
+ # Cleanup
+ if remove_tmp and tmp_dir.exists():
+ shutil.rmtree(tmp_dir)
+ aln_file.with_suffix(".tsv").unlink()
+ remove_search_results()
+ return query_ids
+
+
+def _pdb_ids_from_alignment_identifiers(identifiers: Any) -> Any:
+ """Extract four-character PDB IDs without a Python loop over Arrow rows."""
+ without_foldseek_prefix = pc.replace_substring(
+ identifiers,
+ pattern="pdb_0000",
+ replacement="",
+ )
+ return pc.utf8_slice_codeunits(without_foldseek_prefix, start=0, stop=4)
+
+
+def _raw_alignment_schema(aln_type: str) -> pa.Schema:
+ fields = [
+ pa.field("query", pa.string()),
+ pa.field("target", pa.string()),
+ pa.field("qlen", pa.int64()),
+ pa.field("fident", pa.float64()),
+ pa.field("alnlen", pa.int64()),
+ pa.field("qstart", pa.int64()),
+ pa.field("qend", pa.int64()),
+ pa.field("tstart", pa.int64()),
+ pa.field("tend", pa.int64()),
+ pa.field("evalue", pa.float64()),
+ pa.field("bits", pa.int64()),
+ pa.field("qcov", pa.float64()),
+ pa.field("tcov", pa.float64()),
+ pa.field("cigar", pa.string()),
+ pa.field("qaln", pa.string()),
+ pa.field("taln", pa.string()),
+ ]
+ if aln_type == "foldseek":
+ fields.append(pa.field("lddt", pa.float64()))
+ elif aln_type != "mmseqs":
+ raise ValueError(f"unknown alignment type: {aln_type}")
+ fields.append(pa.field("target_pdb_id", pa.string()))
+ return pa.schema(fields)
+
+
+def _stream_alignment_tsv_to_dataset(
+ tsv_path: Path,
+ dataset_path: Path,
+ *,
+ aln_type: str,
+ include_target_pdb_id: bool,
+) -> None:
+ """Convert an alignment TSV without holding the full search batch in memory."""
+ if dataset_path.exists():
+ shutil.rmtree(dataset_path)
+ reader = csv.open_csv(
+ tsv_path,
+ parse_options=csv.ParseOptions(delimiter="\t"),
+ read_options=csv.ReadOptions(block_size=16 * 1024 * 1024),
+ )
+ wrote_batch = False
+ for batch_index, batch in enumerate(reader):
+ wrote_batch = True
+ table = pyarrow.Table.from_batches([batch])
+ table = table.append_column(
+ "query_pdb_id",
+ _pdb_ids_from_alignment_identifiers(table["query"]),
+ )
+ if include_target_pdb_id:
+ table = table.append_column(
+ "target_pdb_id",
+ _pdb_ids_from_alignment_identifiers(table["target"]),
+ )
+ pq.write_to_dataset(
+ table,
+ dataset_path,
+ partition_cols=["query_pdb_id"],
+ basename_template=f"batch-{batch_index}-{{i}}.parquet",
+ )
+ if not wrote_batch:
+ schema = _raw_alignment_schema(aln_type)
+ if not include_target_pdb_id:
+ schema = pa.schema(
+ field for field in schema if field.name != "target_pdb_id"
+ )
+ dataset_path.mkdir(parents=True)
+ pq.write_table(
+ pa.Table.from_pylist([], schema=schema),
+ dataset_path / "empty.parquet",
+ )
+
+
+def combine_scores(
+ q_t_scores: _SimilarityScoreDictType,
+ q_t_mappings: dict[str, list[_ChainPairType]],
+ protein_chain_mapper: str = "",
+) -> dict[str, str | float]:
+ q_t_scores_combined: dict[str, str | float] = {}
+ for s in SCORE_NAMES:
+ for suffix in ["_max", "_weighted_max", "_weighted_sum", ""]:
+ if (
+ f"{s}_foldseek{suffix}" not in q_t_scores
+ and f"{s}_mmseqs{suffix}" not in q_t_scores
+ ):
+ continue
+ s1, s2 = (
+ float(q_t_scores.get(f"{s}_foldseek{suffix}", 0)),
+ float(q_t_scores.get(f"{s}_mmseqs{suffix}", 0)),
+ )
+ source = "foldseek"
+ if np.abs(s1 - s2) < 1e-6:
+ q_t_scores_combined[f"{s}{suffix}"] = s1
+ q_t_scores_combined[f"{s}{suffix}_source"] = "both"
+ else:
+ index = np.argmax([s1, s2])
+ q_t_scores_combined[f"{s}{suffix}"] = [s1, s2][index]
+ source = ["foldseek", "mmseqs"][index]
+ q_t_scores_combined[f"{s}{suffix}_source"] = source
+ source_name = "mmseqs" if source == "mmseqs" else "foldseek"
+ n = f"{s}_{source_name}{suffix}"
+ if n in q_t_mappings:
+ q_t_scores_combined[f"{s}{suffix}_mapping"] = _format_chain_mapping(
+ q_t_mappings[n]
+ )
+ if protein_chain_mapper != "":
+ q_t_scores_combined["protein_mapping"] = _format_chain_mapping(
+ q_t_mappings.get(f"{protein_chain_mapper}_weighted_sum", [])
+ )
+ q_t_scores_combined["protein_mapper"] = (
+ "foldseek" if "lddt" in protein_chain_mapper else "mmseqs"
+ )
+ return q_t_scores_combined
+
+
+def _format_chain_mapping(mapping: list[_ChainPairType]) -> str:
+ return ";".join(
+ f"{query}:{target}" if target else query for query, target in mapping
+ )
+
+
+@dataclass
+class Scorer:
+ entries: dict[str, EntryView]
+ source_to_full_db_file: dict[str, Path]
+ db_dir: Path
+ scores_dir: Path
+ alignment_chain_lookup: Path | None = None
+ ligand_sdf_resolver: Callable[[LigandView], Path | None] | None = field(
+ default=None, repr=False
+ )
+ foldseek_config: FoldseekConfig = field(default_factory=FoldseekConfig)
+ mmseqs_config: MMSeqsConfig = field(default_factory=MMSeqsConfig)
+ protein_chain_mappers: list[str] = field(
+ default_factory=lambda: [
+ "protein_lddt_qcov_foldseek",
+ "protein_fident_qcov_mmseqs",
+ ]
+ )
+ # default minimum threshold for every metric BEFORE scaling to 100
+ minimum_threshold: float = 0.0
+ # optional custom minimum threshold for each metric BEFORE scaling to 100
+ minimum_thresholds: dict[str, float] = field(default_factory=dict)
+ max_query_protein_chains: int = 30
+ max_query_proper_ligand_chains: int = 30
+ shape_score_threads: int = 1
+ include_pli_fident: bool = False
+ _ligand_mol_cache: dict[tuple[str, str], Chem.Mol | None] = field(
+ default_factory=dict, init=False, repr=False
+ )
+ _ligand_shape_score_cache: dict[
+ tuple[tuple[str, str], tuple[str, str]], _SimilarityScoreDictType
+ ] = field(default_factory=dict, init=False, repr=False)
+ _ligand_reference_feature_cache: dict[
+ tuple[str, str], _PharmacophoreFeatures | None
+ ] = field(default_factory=dict, init=False, repr=False)
+ _ligand_feature_records: dict[tuple[str, str], list[dict[str, Any]] | None] = field(
+ default_factory=dict, init=False, repr=False
+ )
+ _ligand_sdf_block_cache: dict[tuple[str, str], bytes] = field(
+ default_factory=dict, init=False, repr=False
+ )
+ _loaded_ligand_archive_entries: set[str] = field(
+ default_factory=set, init=False, repr=False
+ )
+ _ligand_pocket_data_cache: dict[str, _PocketDataType] = field(
+ default_factory=dict, init=False, repr=False
+ )
+ _pocket_pattern_info_cache: dict[str, _PocketPatternInfoType] = field(
+ default_factory=dict, init=False, repr=False
+ )
+ _pocket_alignment_row_cache: dict[
+ int,
+ tuple[pd.DataFrame, dict[tuple[str, str, str], list[dict[str, Any]]]],
+ ] = field(default_factory=dict, init=False, repr=False)
+ _pocket_alignment_inputs: dict[bytes, dict[str, Any]] = field(
+ default_factory=dict, init=False, repr=False
+ )
+ _aligned_query_pockets: dict[
+ tuple[bytes, tuple[int, ...]], tuple[tuple[int, int, bool], ...]
+ ] = field(default_factory=dict, init=False, repr=False)
+ _pocket_chain_matches: dict[
+ tuple[str, tuple[bytes, ...], tuple[int, ...], tuple[int, ...]],
+ tuple[tuple[float, float, float, float], dict[str, Any]] | None,
+ ] = field(default_factory=dict, init=False, repr=False)
+ _protein_score_cache: dict[
+ tuple[str, str, tuple[str, ...], tuple[str, ...]], _ProteinScoreResultType
+ ] = field(default_factory=dict, init=False, repr=False)
+
+ def __post_init__(self) -> None:
+ if self.shape_score_threads < 1:
+ raise ValueError("shape_score_threads must be positive")
+ if self.max_query_protein_chains < 1 or self.max_query_proper_ligand_chains < 1:
+ raise ValueError("scoring system chain limits must be positive")
+ self.db_dir.mkdir(exist_ok=True, parents=True)
+ self.scores_dir.mkdir(exist_ok=True, parents=True)
+
+ def system_is_query_scoreable(self, system: SystemView) -> bool:
+ """Return whether a holo system is small enough to score as a query."""
+ proper_ligand_count = sum(
+ ligand.is_proper for ligand in system.ligands.values()
+ )
+ return (
+ system.system_type == "holo"
+ and 0 < len(system.protein_chains_asym_id) <= self.max_query_protein_chains
+ and 0 < proper_ligand_count <= self.max_query_proper_ligand_chains
+ )
+
+ @staticmethod
+ def system_is_target_scoreable(system: SystemView) -> bool:
+ """Return whether a system may contribute scores as a target.
+
+ Query limits exist to bound the work initiated by an entry. Applying
+ them to targets as well would remove large systems from the score graph
+ entirely, so every protein-containing holo system remains available as
+ a target. Only proper ligands are emitted later by
+ :meth:`get_scores_holo`.
+ """
+ return system.system_type == "holo" and bool(system.protein_chains_asym_id)
+
+ def resolve_ligand_sdf(self, data_dir: Path, ligand: LigandView) -> Path | None:
+ """Resolve the canonical ASU ligand SDF for a ligand annotation."""
+ candidates = [
+ canonical_ligand_sdf_path(
+ data_dir,
+ pdb_id=ligand.pdb_id,
+ asym_id=ligand.asym_id,
+ ),
+ data_dir
+ / "ligand_archives"
+ / ligand.pdb_id
+ / "ligand_files"
+ / f"{ligand.asym_id}.sdf",
+ ]
+ return next((path for path in candidates if path.is_file()), None)
+
+ def _get_ligand_mol(self, data_dir: Path, ligand: LigandView) -> Chem.Mol | None:
+ cache_key = (ligand.pdb_id, ligand.asym_id)
+ if cache_key not in self._ligand_mol_cache:
+ packed = self._ligand_sdf_block_cache.pop(cache_key, None)
+ if packed is not None:
+ molecule = load_sdf_molecule_block(
+ packed, label=f"{ligand.pdb_id}/{ligand.asym_id}"
+ )
+ self._ligand_mol_cache[cache_key] = (
+ prepare_ligand_for_3d_scoring(molecule)
+ if molecule is not None
+ else None
+ )
+ return self._ligand_mol_cache[cache_key]
+ if self.ligand_sdf_resolver is None:
+ sdf_file = self.resolve_ligand_sdf(data_dir, ligand)
+ else:
+ sdf_file = self.ligand_sdf_resolver(ligand)
+ if sdf_file is None:
+ LOG.warning(
+ f"no ligand SDF found for {ligand.id} (canonical key={cache_key})"
+ )
+ self._ligand_mol_cache[cache_key] = None
+ else:
+ molecule = load_sdf_molecule(sdf_file)
+ self._ligand_mol_cache[cache_key] = (
+ prepare_ligand_for_3d_scoring(molecule)
+ if molecule is not None
+ else None
+ )
+ return self._ligand_mol_cache[cache_key]
+
+ def _preload_packed_ligand_sdfs(
+ self,
+ data_dir: Path,
+ ligands: Sequence[LigandView],
+ *,
+ requested_entries_only: bool = False,
+ ) -> None:
+ """Bulk-read packed canonical SDFs once per requested PDB entry."""
+ if self.ligand_sdf_resolver is not None:
+ return
+ requested_shards: set[str] = set()
+ for ligand in ligands:
+ cache_key = (ligand.pdb_id, ligand.asym_id)
+ if (
+ cache_key not in self._ligand_mol_cache
+ and ligand.pdb_id not in self._loaded_ligand_archive_entries
+ ):
+ requested_shards.add(ligand.pdb_id[1:3])
+
+ archive_root = data_dir / "ligand_archives"
+ for shard in sorted(requested_shards):
+ archive = archive_root / f"{shard}.parquet"
+ if not archive.is_file():
+ continue
+ requested_pdb_ids = sorted(
+ {
+ ligand.pdb_id
+ for ligand in ligands
+ if ligand.pdb_id[1:3] == shard
+ and ligand.pdb_id not in self._loaded_ligand_archive_entries
+ }
+ )
+ # A shard is deliberately small (roughly one hundred PDB entries)
+ # and normally one Parquet row group. Reading it once avoids
+ # repeating the same NFS page read for later queries in this job.
+ columns = ["pdb_id", "ligand_asym_id", "sdf"]
+ if "pharmacophore_features" in pq.read_schema(archive).names:
+ columns.append("pharmacophore_features")
+ table = pq.read_table(
+ archive,
+ columns=columns,
+ filters=(
+ [("pdb_id", "in", requested_pdb_ids)]
+ if requested_entries_only
+ else None
+ ),
+ use_threads=True,
+ )
+ for pdb_id, asym_id, sdf in zip(
+ table["pdb_id"].to_pylist(),
+ table["ligand_asym_id"].to_pylist(),
+ table["sdf"].to_pylist(),
+ ):
+ self._ligand_sdf_block_cache[(str(pdb_id), str(asym_id))] = sdf
+ if "pharmacophore_features" in table.column_names:
+ for row in table.select(
+ ["pdb_id", "ligand_asym_id", "pharmacophore_features"]
+ ).to_pylist():
+ records = row["pharmacophore_features"]
+ self._ligand_feature_records[
+ (row["pdb_id"], row["ligand_asym_id"])
+ ] = records
+ self._loaded_ligand_archive_entries.update(
+ str(pdb_id) for pdb_id in table["pdb_id"].to_pylist()
+ )
+
+ def _get_ligand_reference_features(
+ self, data_dir: Path, ligand: LigandView
+ ) -> _PharmacophoreFeatures | None:
+ """Cache pharmacophore features for an unmodified reference ligand."""
+ cache_key = (ligand.pdb_id, ligand.asym_id)
+ if cache_key not in self._ligand_reference_feature_cache:
+ molecule = self._get_ligand_mol(data_dir, ligand)
+ if cache_key in self._ligand_feature_records:
+ records = self._ligand_feature_records[cache_key]
+ features = (
+ _aligned_pharmacophore_features(molecule, records)
+ if molecule is not None and records is not None
+ else None
+ )
+ else:
+ features = (
+ _pharmacophore_features(molecule) if molecule is not None else None
+ )
+ self._ligand_feature_records[cache_key] = (
+ _pharmacophore_records(features) if features is not None else None
+ )
+ self._ligand_reference_feature_cache[cache_key] = features
+ return self._ligand_reference_feature_cache[cache_key]
+
+ def get_ligand_pair_shape_scores(
+ self,
+ data_dir: Path,
+ query_ligand: LigandView,
+ target_ligand: LigandView,
+ pocket_qcov: float,
+ ) -> _SimilarityScoreDictType:
+ """Shape-score one ligand pair after the pocket-coverage gate."""
+ if not np.isfinite(pocket_qcov) or pocket_qcov <= 0:
+ return {}
+ if (
+ query_ligand.is_shape_comparable is False
+ or target_ligand.is_shape_comparable is False
+ ):
+ return {}
+
+ query_key = (query_ligand.pdb_id, query_ligand.asym_id)
+ target_key = (target_ligand.pdb_id, target_ligand.asym_id)
+ cache_key = (query_key, target_key)
+ if cache_key not in self._ligand_shape_score_cache:
+ query_mol = self._get_ligand_mol(data_dir, query_ligand)
+ target_mol = self._get_ligand_mol(data_dir, target_ligand)
+ query_features = self._get_ligand_reference_features(data_dir, query_ligand)
+ target_features = self._get_ligand_reference_features(
+ data_dir, target_ligand
+ )
+ base_scores: _SimilarityScoreDictType = {}
+ if (
+ query_mol is not None
+ and target_mol is not None
+ and query_features is not None
+ and target_features is not None
+ ):
+ # ShapeAlign mutates the mobile conformer. Clone the cached
+ # canonical ASU molecules once for this directed ligand pair,
+ # then reuse its immutable scores across every system in which
+ # those ligand instances occur.
+ query_aligned = Chem.Mol(query_mol)
+ target_aligned = Chem.Mol(target_mol)
+ try:
+ shape, color = align_molecules(query_aligned, target_aligned)
+ except Exception as exc:
+ LOG.warning(
+ "shape alignment failed for "
+ f"{query_ligand.id} to {target_ligand.id}: {exc}"
+ )
+ else:
+ if all(np.isfinite(value) for value in (shape, color)):
+ base_scores.update(
+ {
+ "shape": float(np.clip(shape, 0, 1)),
+ "color": float(np.clip(color, 0, 1)),
+ }
+ )
+ try:
+ sucos_shape = get_sucos_score(
+ query_aligned,
+ target_aligned,
+ FeatMaps.FeatMapScoreMode.All,
+ query_features,
+ _aligned_pharmacophore_features(
+ target_aligned,
+ cast(
+ list[dict[str, Any]],
+ self._ligand_feature_records[target_key],
+ ),
+ ),
+ )
+ except Exception as exc:
+ LOG.warning(
+ "SuCOS calculation failed for "
+ f"{query_ligand.id} to {target_ligand.id}: {exc}"
+ )
+ else:
+ if np.isfinite(sucos_shape):
+ base_scores["sucos_shape"] = sucos_shape
+ else:
+ LOG.warning(
+ "SuCOS calculation returned a non-finite "
+ f"score for {query_ligand.id} to "
+ f"{target_ligand.id}"
+ )
+ else:
+ LOG.warning(
+ "shape alignment returned non-finite scores for "
+ f"{query_ligand.id} to {target_ligand.id}"
+ )
+ self._ligand_shape_score_cache[cache_key] = base_scores
+
+ scores = dict(self._ligand_shape_score_cache[cache_key])
+ if "sucos_shape" in scores:
+ scores["sucos_shape_pocket_qcov"] = scores["sucos_shape"] * pocket_qcov
+ return scores
+
+ def score_canonical_ligand_pairs(
+ self,
+ data_dir: Path,
+ pairs: pd.DataFrame,
+ ) -> pd.DataFrame:
+ """Calculate base 3D metrics once for each canonical directed pair."""
+ pair_columns = [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ if pairs.empty:
+ return pd.DataFrame(columns=schemas.LIGAND_3D_SCORE_SCHEMA.names)
+ missing = sorted(set(pair_columns).difference(pairs.columns))
+ if missing:
+ raise ValueError(f"ligand 3D pair table is missing columns {missing}")
+ pair_frame = pairs[pair_columns].drop_duplicates(ignore_index=True)
+ ligand_views: dict[tuple[str, str], LigandView] = {}
+
+ def ligand_view(pdb_id: str, asym_id: str) -> LigandView:
+ key = (pdb_id, asym_id)
+ if key not in ligand_views:
+ ligand_views[key] = LigandView(
+ id=f"{pdb_id}__canonical__{asym_id}",
+ pdb_id=pdb_id,
+ system_id="",
+ instance_chain=f"0.{asym_id}",
+ asym_id=asym_id,
+ is_proper=True,
+ is_shape_comparable=True,
+ protein_chains_asym_id=[],
+ num_pocket_residues=0,
+ num_interactions=0,
+ num_unique_interactions=0,
+ )
+ return ligand_views[key]
+
+ work: list[tuple[LigandView, LigandView]] = [
+ (
+ ligand_view(str(row.query_entry), str(row.query_ligand_asym_id)),
+ ligand_view(str(row.target_entry), str(row.target_ligand_asym_id)),
+ )
+ for row in pair_frame.itertuples(index=False)
+ ]
+ self._preload_packed_ligand_sdfs(
+ data_dir,
+ list(ligand_views.values()),
+ requested_entries_only=True,
+ )
+
+ def load_ligand(ligand: LigandView) -> Chem.Mol | None:
+ return self._get_ligand_mol(data_dir, ligand)
+
+ def score_pair(pair: tuple[LigandView, LigandView]) -> dict[str, float]:
+ return self.get_ligand_pair_shape_scores(
+ data_dir, pair[0], pair[1], pocket_qcov=1.0
+ )
+
+ with ThreadPoolExecutor(max_workers=self.shape_score_threads) as executor:
+ list(executor.map(load_ligand, ligand_views.values()))
+ for ligand in ligand_views.values():
+ self._get_ligand_reference_features(data_dir, ligand)
+ scores = list(executor.map(score_pair, work))
+ records = []
+ for pair, score in zip(pair_frame.itertuples(index=False), scores):
+ records.append(
+ {
+ **{column: getattr(pair, column) for column in pair_columns},
+ "shape": score.get("shape"),
+ "color": score.get("color"),
+ "sucos_shape": score.get("sucos_shape"),
+ }
+ )
+ return pd.DataFrame.from_records(
+ records, columns=schemas.LIGAND_3D_SCORE_SCHEMA.names
+ )
+
+ def make_dbs(self) -> None:
+ databases.make_sub_dbs(self.db_dir, self.source_to_full_db_file, self.entries)
+
+ def get_config(
+ self, search_db: str, aln_type: str
+ ) -> FoldseekConfig | MMSeqsConfig:
+ config: FoldseekConfig | MMSeqsConfig
+ if aln_type == "foldseek":
+ config = replace(self.foldseek_config)
+ else:
+ config = replace(self.mmseqs_config)
+ if search_db in {"apo", "interface_apo"}:
+ config.coverage = APO_SEARCH_COVERAGE
+ config.min_seq_id = APO_SEARCH_MIN_SEQ_ID
+ elif search_db == "pred":
+ config.coverage = 0.9
+ config.min_seq_id = 0.9
+ return config
+
+ def run_alignments(
+ self,
+ entry_ids: list[str],
+ search_db: str,
+ output_folder: Path,
+ overwrite: bool = False,
+ threads: int = 1,
+ alignment_types: Sequence[str] | None = None,
+ query_chain_auth_ids: abc.Mapping[str, abc.Collection[str]] | None = None,
+ output_metadata_by_entry: (
+ abc.Mapping[str, abc.Mapping[bytes, bytes]] | None
+ ) = None,
+ target_database_dir: Path | None = None,
+ query_database_dir: Path | None = None,
+ result_database_dir: Path | None = None,
+ write_empty_results: bool = True,
+ ) -> set[str]:
+ """Search selected entries and return those with at least one hit.
+
+ The optional database roots let update jobs search the current query
+ database against a small changed-target database without touching the
+ release's existing raw alignments.
+ """
+ output_folder.mkdir(exist_ok=True)
+ failures: list[str] = []
+ hit_entries: set[str] = set()
+ selected_alignment_types = list(alignment_types or ["mmseqs", "foldseek"])
+ unsupported = sorted(set(selected_alignment_types) - {"foldseek", "mmseqs"})
+ if unsupported:
+ raise ValueError(f"unsupported alignment types: {unsupported}")
+ for aln_type in selected_alignment_types:
+ sub_db = output_folder / search_db / aln_type
+ sub_db.mkdir(exist_ok=True, parents=True)
+ if query_chain_auth_ids is None:
+ db_ids = databases.get_db_ids(
+ self.entries, "holo", aln_type, entry_ids=entry_ids
+ )
+ elif aln_type == "foldseek":
+ db_ids = {
+ f"pdb_0000{entry_id}_xyz-enrich_{auth_id}"
+ for entry_id in entry_ids
+ for auth_id in query_chain_auth_ids.get(entry_id, ())
+ }
+ else:
+ db_ids = {
+ f"{entry_id}_{auth_id}"
+ for entry_id in entry_ids
+ for auth_id in query_chain_auth_ids.get(entry_id, ())
+ }
+ query_source = (
+ query_database_dir / aln_type / aln_type
+ if query_database_dir is not None
+ else self.source_to_full_db_file[f"holo_{aln_type}"]
+ )
+ if (
+ query_database_dir is not None
+ and not Path(f"{query_source}.lookup").is_file()
+ ):
+ db_ids = set()
+ missing_query_ids = []
+ else:
+ missing_query_ids = databases.make_sub_db(
+ db_ids, query_source, sub_db, aln_type
+ )
+ result_root = result_database_dir or self.db_dir
+ aln_dir = result_root / f"{search_db}_{aln_type}" / "aln"
+ aln_dir.mkdir(exist_ok=True, parents=True)
+ if not db_ids or len(missing_query_ids) == len(db_ids):
+ LOG.warning(
+ f"no {aln_type} query chains are available for "
+ f"{len(entry_ids)} entries"
+ )
+ if write_empty_results:
+ for pdb_id in entry_ids:
+ empty = pa.Table.from_pylist(
+ [], schema=_raw_alignment_schema(aln_type)
+ )
+ empty = _with_parquet_metadata(
+ empty,
+ output_metadata_by_entry.get(pdb_id)
+ if output_metadata_by_entry is not None
+ else None,
+ )
+ target = aln_dir / f"{pdb_id}.parquet"
+ _atomic_write_parquet(empty, target)
+ continue
+ tmp_dir = sub_db / f"tmp_{search_db}_{aln_type}"
+ tmp_dir.mkdir(exist_ok=True, parents=True)
+ shadowed: set[str] = set()
+ targets = [("base", target_database_dir or self.db_dir)]
+ if target_database_dir is None and search_db != "pred":
+ shadowed_path = (
+ self.db_dir.parent.parent
+ / "manifests/weekly_shadowed_entries.parquet"
+ )
+ if shadowed_path.is_file():
+ shadowed = set(
+ map(
+ str,
+ pq.read_table(shadowed_path, columns=["pdb_id"])[
+ "pdb_id"
+ ].to_pylist(),
+ )
+ )
+ overlay = self.db_dir.parent / "weekly_delta/subdbs"
+ if (overlay / f"{search_db}_{aln_type}/exact_cluster.json").is_file():
+ targets.append(("overlay", overlay))
+ alignment_files: list[tuple[str, Path]] = []
+ try:
+ for label, target_root in targets:
+ (
+ target_db,
+ search_target_db,
+ cluster_alignment_db,
+ ) = databases.exact_search_database_paths(
+ target_root, search_db, aln_type
+ )
+ aln_file = sub_db / f"aln_{search_db}_{label}.tsv"
+ alignment_config = self.get_config(search_db, aln_type)
+ if label == "base" and shadowed:
+ lookup = Path(f"{search_target_db}.lookup")
+ if not lookup.is_file():
+ raise FileNotFoundError(lookup)
+ with lookup.open() as handle:
+ replaced_representatives = sum(
+ (
+ line.split("\t", 2)[1].removeprefix("pdb_0000")[:4]
+ if aln_type == "foldseek"
+ else line.split("\t", 2)[1].split("_", 1)[0]
+ )
+ in shadowed
+ for line in handle
+ )
+ alignment_config.max_seqs += replaced_representatives
+ run_alignment(
+ aln_type=aln_type,
+ query_db=sub_db / sub_db.name,
+ target_db=target_db,
+ search_target_db=search_target_db,
+ cluster_alignment_db=cluster_alignment_db,
+ search_db=sub_db / f"search_{label}",
+ aln_file=aln_file,
+ tmp_dir=tmp_dir / f"{output_folder.stem}_{label}",
+ alignment_config=alignment_config,
+ threads=threads,
+ include_target_pdb_id=search_db != "pred",
+ )
+ alignment_files.append((label, aln_file))
+ except Exception as e:
+ scratch = (
+ output_folder / "scratch" / "scores" / "run_alignment_failures"
+ )
+ scratch.mkdir(exist_ok=True, parents=True)
+ (scratch / f"{search_db}_{aln_type}.txt").write_text(f"{repr(e)}: {e}")
+ LOG.error(f"scoring: Error for {search_db}_{aln_type}: {e}")
+ failures.append(f"{search_db}_{aln_type}: {e}")
+ continue
+ for pdb_id in tqdm(entry_ids):
+ target = aln_dir / f"{pdb_id}.parquet"
+ local_output = (
+ output_folder
+ / "completed"
+ / search_db
+ / aln_type
+ / f"{pdb_id}.parquet"
+ )
+ local_output.parent.mkdir(exist_ok=True, parents=True)
+ frames = []
+ for label, aln_file in alignment_files:
+ pdb_id_file = (
+ aln_file.with_suffix(".parquet") / f"query_pdb_id={pdb_id}"
+ )
+ if not pdb_id_file.exists():
+ continue
+ rows = pd.read_parquet(pdb_id_file)
+ if label == "base" and shadowed:
+ rows = rows.loc[
+ ~rows["target_pdb_id"].astype(str).isin(shadowed)
+ ]
+ if not rows.empty:
+ frames.append(rows)
+ if frames:
+ hit_entries.add(pdb_id)
+ table = pa.Table.from_pandas(
+ pd.concat(frames, ignore_index=True), preserve_index=False
+ )
+ elif write_empty_results:
+ # Short chains can legitimately have no hit after the
+ # E-value filter. A typed empty file is their durable
+ # searched/no-hit completion marker.
+ table = pa.Table.from_pylist(
+ [], schema=_raw_alignment_schema(aln_type)
+ )
+ else:
+ continue
+ table = _with_parquet_metadata(
+ table,
+ output_metadata_by_entry.get(pdb_id)
+ if output_metadata_by_entry is not None
+ else None,
+ )
+ pq.write_table(table, local_output)
+ _atomic_copy_file(local_output, target)
+ local_output.unlink(missing_ok=True)
+ if failures:
+ raise RuntimeError("alignment searches failed: " + "; ".join(failures))
+ return hit_entries
+
+ def map_alignment_files(
+ self,
+ data_dir: Path,
+ pdb_id: str,
+ search_db: str,
+ overwrite: bool = True,
+ scratch_dir: Path | None = None,
+ mapped_db_dir: Path | None = None,
+ ) -> list[Path]:
+ """Map raw backend alignments without calculating system scores."""
+ mapped_files: list[Path] = []
+ failures: list[str] = []
+ for aln_type in ["foldseek", "mmseqs"]:
+ raw_file = (
+ self.db_dir / f"{search_db}_{aln_type}" / "aln" / f"{pdb_id}.parquet"
+ )
+ if not raw_file.exists():
+ LOG.info(f"map_alignment_files: raw_file={raw_file} does not exist")
+ continue
+
+ entries_to_load = {pdb_id}
+ if search_db != "pred":
+ entries_to_load |= set(
+ pd.read_parquet(raw_file, columns=["target_pdb_id"])[
+ "target_pdb_id"
+ ]
+ )
+ entries_to_load = entries_to_load.difference(self.entries)
+ if entries_to_load:
+ LOG.info(
+ f"loading {len(entries_to_load)} entries to map {pdb_id} "
+ f"against {search_db} with {aln_type}"
+ )
+ self.entries.update(
+ load_entry_views(pdb_ids=entries_to_load, data_dir=data_dir)
+ )
+
+ mapped_file = (
+ (mapped_db_dir or self.db_dir)
+ / f"{search_db}_{aln_type}"
+ / "mapped_aln"
+ / f"{pdb_id}.parquet"
+ )
+ mapped_file.parent.mkdir(exist_ok=True, parents=True)
+ if not overwrite and mapped_file.exists():
+ try:
+ mapped_columns = set(pq.read_schema(mapped_file).names)
+ except (OSError, ValueError):
+ mapped_columns = set()
+ if mapped_columns and schemas.mapped_alignment_schema_is_current(
+ mapped_columns, alignment_type=aln_type
+ ):
+ mapped_files.append(mapped_file)
+ continue
+ LOG.info(
+ "map_alignment_files: replacing mapped file with stale schema: "
+ f"{mapped_file}"
+ )
+ failure_file = (
+ self.db_dir
+ / "scratch"
+ / "scores"
+ / "map_alignment_df_failures"
+ / f"{search_db}_{aln_type}_{pdb_id}.txt"
+ )
+ try:
+ LOG.info(f"mapping {pdb_id} against {search_db} with {aln_type}")
+ mapped = self.map_alignment_df(raw_file, aln_type, search_db)
+ temporary_root = scratch_dir or mapped_file.parent
+ temporary_root.mkdir(exist_ok=True, parents=True)
+ temporary = temporary_root / (
+ f"{search_db}-{aln_type}-{pdb_id}.mapped.parquet"
+ )
+ mapped.to_parquet(temporary, index=True)
+ _atomic_copy_file(temporary, mapped_file)
+ temporary.unlink(missing_ok=True)
+ mapped_files.append(mapped_file)
+ failure_file.unlink(missing_ok=True)
+ except Exception as exc:
+ failure_file.parent.mkdir(exist_ok=True, parents=True)
+ failure_file.write_text(f"{exc!r}: {exc}")
+ failures.append(f"{search_db}_{aln_type}_{pdb_id}: {exc}")
+ if failures:
+ raise RuntimeError("alignment mapping failed: " + "; ".join(failures))
+ return mapped_files
+
+ def get_score_df(
+ self,
+ data_dir: Path,
+ pdb_id: str,
+ search_db: str,
+ overwrite: bool = True,
+ map_alignments: bool = True,
+ scratch_dir: Path | None = None,
+ source_to_aln_file: dict[str, Path] | None = None,
+ defer_ligand_3d: bool = False,
+ query_entry_alignments: pd.DataFrame | None = None,
+ score_metrics: abc.Collection[str] | None = None,
+ ) -> Path:
+ """
+ Convert aligmnent results to mapped alignment results. Then
+ aggregate the mapped alignment results into the scores dataset.
+ """
+ if defer_ligand_3d and search_db != "holo":
+ raise ValueError("ligand 3D scoring can only be deferred for holo scores")
+ score_df_path = self.db_dir / f"search_db={search_db}" / f"{pdb_id}.parquet"
+ candidate_path = (
+ self.scores_dir
+ / "ligand_3d_candidates"
+ / f"search_db={search_db}"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet"
+ )
+ ligand_pair_score_path = (
+ self.scores_dir
+ / "ligand_pair_scores"
+ / f"search_db={search_db}"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet"
+ )
+ score_mode = b"deferred" if defer_ligand_3d else b"complete"
+ holo_protein_scores_mode = b"excluded" if search_db == "holo" else None
+ cached_score_is_current = False
+ if not overwrite and score_df_path.is_file():
+ try:
+ cached_score_is_current = score_cache_is_current(
+ score_df_path,
+ ligand_3d_mode=score_mode,
+ minimum_threshold=self.minimum_threshold,
+ minimum_thresholds=self.minimum_thresholds,
+ holo_protein_scores_mode=holo_protein_scores_mode,
+ score_metrics=score_metrics,
+ )
+ if defer_ligand_3d:
+ candidate_schema = pq.read_schema(candidate_path)
+ pq.read_metadata(candidate_path)
+ ligand_pair_schema = pq.read_schema(ligand_pair_score_path)
+ pq.read_metadata(ligand_pair_score_path)
+ cached_score_is_current = (
+ cached_score_is_current
+ and set(schemas.LIGAND_3D_CANDIDATE_SCHEMA.names).issubset(
+ candidate_schema.names
+ )
+ and ligand_pair_schema.equals(schemas.LIGAND_PAIR_SCORE_SCHEMA)
+ )
+ except (OSError, ValueError):
+ cached_score_is_current = False
+ if overwrite or not cached_score_is_current:
+ LOG.info(f"get_score_df: aggregating scores for {pdb_id} to {search_db}")
+ else:
+ LOG.info(f"get_score_df: skipping existing {score_df_path}")
+ return score_df_path
+ if map_alignments:
+ self.map_alignment_files(
+ data_dir,
+ pdb_id,
+ search_db,
+ overwrite=overwrite,
+ )
+ else:
+ entries_to_load = {pdb_id}
+ if search_db == "holo":
+ for aln_type in ["foldseek", "mmseqs"]:
+ source = f"{search_db}_{aln_type}"
+ mapped_file = (
+ source_to_aln_file[source]
+ if source_to_aln_file is not None
+ and source in source_to_aln_file
+ else self.db_dir / source / "mapped_aln" / f"{pdb_id}.parquet"
+ )
+ if mapped_file.is_file():
+ target_entries = pd.read_parquet(
+ mapped_file,
+ columns=["target_entry"],
+ filters=[("query_entry", "==", pdb_id)],
+ )
+ if "target_entry" in target_entries.columns:
+ target_values = target_entries["target_entry"]
+ else:
+ target_values = pd.Series(
+ target_entries.index.get_level_values("target_entry")
+ )
+ entries_to_load.update(target_values.dropna().astype(str))
+ entries_to_load.difference_update(self.entries)
+ if entries_to_load:
+ LOG.info(
+ f"loading {len(entries_to_load)} entries to score {pdb_id} "
+ f"against {search_db}"
+ )
+ self.entries.update(
+ load_entry_views(
+ pdb_ids=entries_to_load,
+ data_dir=data_dir,
+ include_interfaces=False,
+ )
+ )
+
+ try:
+ score_df_path.parent.mkdir(exist_ok=True, parents=True)
+ LOG.info(f"aggregating scores for {pdb_id} to {search_db}")
+ # A canonical pair cannot recur across different query entries.
+ # Bound this cache to one query while retaining the molecule cache
+ # across a batch, where target ligands are commonly reused.
+ self._ligand_shape_score_cache.clear()
+ self._protein_score_cache.clear()
+ ligand_3d_candidates: list[_Ligand3DCandidateType] | None = (
+ [] if defer_ligand_3d else None
+ )
+ ligand_pair_scores: list[_LigandPairScoreType] | None = (
+ [] if defer_ligand_3d else None
+ )
+ df = self.aggregate_scores(
+ pdb_id,
+ search_db=search_db,
+ data_dir=None if defer_ligand_3d else data_dir,
+ source_to_aln_file=source_to_aln_file,
+ query_entry_alignments=query_entry_alignments,
+ ligand_3d_candidates=ligand_3d_candidates,
+ ligand_pair_scores=ligand_pair_scores,
+ include_holo_protein_scores=search_db != "holo",
+ )
+ if df is not None and score_metrics is not None:
+ df = df[df["metric"].astype(str).isin(set(score_metrics))].copy()
+ if df is None or df.empty:
+ df = pd.DataFrame(
+ {
+ name: pd.Series(dtype="object")
+ for name in schemas.PROTEIN_SIMILARITY_SCHEMA.names
+ }
+ )
+ temporary_root = scratch_dir or score_df_path.parent
+ temporary_root.mkdir(exist_ok=True, parents=True)
+ temporary = temporary_root / f"{search_db}-{pdb_id}.scores.parquet"
+ score_metadata = {
+ b"plinder.ligand_3d": score_mode,
+ SCORE_THRESHOLDS_METADATA_KEY: score_thresholds_metadata(
+ self.minimum_threshold,
+ self.minimum_thresholds,
+ ),
+ }
+ if holo_protein_scores_mode is not None:
+ score_metadata[HOLO_PROTEIN_SCORES_METADATA_KEY] = (
+ holo_protein_scores_mode
+ )
+ retained_metrics = score_metrics_metadata(score_metrics)
+ if retained_metrics is not None:
+ score_metadata[SCORE_METRICS_METADATA_KEY] = retained_metrics
+ score_schema = schemas.PROTEIN_SIMILARITY_SCHEMA.with_metadata(
+ score_metadata
+ )
+ df.to_parquet(
+ temporary,
+ index=False,
+ schema=score_schema,
+ )
+ candidate_temporary = (
+ temporary_root / f"{search_db}-{pdb_id}.ligand-3d-candidates.parquet"
+ )
+ ligand_pair_temporary = (
+ temporary_root / f"{search_db}-{pdb_id}.ligand-pair-scores.parquet"
+ )
+ if ligand_3d_candidates is not None:
+ candidate_table = pa.Table.from_pylist(
+ ligand_3d_candidates,
+ schema=schemas.LIGAND_3D_CANDIDATE_SCHEMA,
+ )
+ pq.write_table(
+ candidate_table,
+ candidate_temporary,
+ compression="zstd",
+ )
+ candidate_path.parent.mkdir(exist_ok=True, parents=True)
+ _atomic_copy_file(candidate_temporary, candidate_path)
+ if ligand_pair_scores is not None:
+ ligand_pair_table = pa.Table.from_pylist(
+ ligand_pair_scores,
+ schema=schemas.LIGAND_PAIR_SCORE_SCHEMA,
+ )
+ pq.write_table(
+ ligand_pair_table,
+ ligand_pair_temporary,
+ compression="zstd",
+ )
+ ligand_pair_score_path.parent.mkdir(exist_ok=True, parents=True)
+ _atomic_copy_file(ligand_pair_temporary, ligand_pair_score_path)
+ _atomic_copy_file(temporary, score_df_path)
+ temporary.unlink(missing_ok=True)
+ candidate_temporary.unlink(missing_ok=True)
+ ligand_pair_temporary.unlink(missing_ok=True)
+ if ligand_3d_candidates is None:
+ candidate_path.unlink(missing_ok=True)
+ if ligand_pair_scores is None:
+ ligand_pair_score_path.unlink(missing_ok=True)
+ except Exception as e:
+ scratch = data_dir / "scratch" / "scores" / "aggregate_scores_failures"
+ scratch.mkdir(exist_ok=True, parents=True)
+ (scratch / f"{search_db}_{pdb_id}.txt").write_text(f"{repr(e)}: {e}")
+ LOG.error(
+ f"scoring: Error in aggregate_scores: {pdb_id} searching against {search_db}: {repr(e)}"
+ )
+ raise
+ return score_df_path
+
+ def repair_score_df_targets(
+ self,
+ data_dir: Path,
+ pdb_id: str,
+ *,
+ affected_target_entries: set[str],
+ search_db: str = "holo",
+ scratch_dir: Path | None = None,
+ allow_missing: bool = False,
+ query_system_ids: set[str] | None = None,
+ query_ligand_ids: set[str] | None = None,
+ target_system_ids: set[str] | None = None,
+ target_ligand_ids: set[str] | None = None,
+ ) -> Path:
+ """Replace target-entry rows, optionally creating a bounded query."""
+ if search_db != "holo":
+ raise ValueError(
+ "targeted score repair currently supports holo scores only"
+ )
+ if pdb_id in affected_target_entries:
+ raise ValueError("an affected query entry requires a complete rescore")
+ score_path = self.db_dir / f"search_db={search_db}" / f"{pdb_id}.parquet"
+ candidate_path = (
+ self.scores_dir
+ / "ligand_3d_candidates"
+ / f"search_db={search_db}"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet"
+ )
+ ligand_pair_score_path = (
+ self.scores_dir
+ / "ligand_pair_scores"
+ / f"search_db={search_db}"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet"
+ )
+ if not allow_missing and (
+ not score_path.is_file()
+ or not candidate_path.is_file()
+ or not ligand_pair_score_path.is_file()
+ ):
+ raise FileNotFoundError(
+ "targeted score repair requires existing score and pair files: "
+ f"score={score_path.is_file()} candidates={candidate_path.is_file()} "
+ f"ligand_pairs={ligand_pair_score_path.is_file()}"
+ )
+ existing_threshold_metadata = None
+ if score_path.is_file():
+ existing_threshold_metadata = (
+ pq.read_schema(score_path).metadata or {}
+ ).get(SCORE_THRESHOLDS_METADATA_KEY)
+
+ requested_entries = {pdb_id, *affected_target_entries}
+ requested_entries.difference_update(self.entries)
+ if requested_entries:
+ self.entries.update(
+ load_entry_views(pdb_ids=requested_entries, data_dir=data_dir)
+ )
+ if pdb_id not in self.entries:
+ raise KeyError(f"query entry is absent from the current index: {pdb_id}")
+ if target_system_ids is None:
+ target_system_ids = {
+ system_id
+ for target_pdb_id in affected_target_entries
+ for system_id in (
+ self.entries[target_pdb_id].systems
+ if target_pdb_id in self.entries
+ else {}
+ )
+ }
+ elif {
+ system_id.split("__", maxsplit=1)[0] for system_id in target_system_ids
+ }.difference(affected_target_entries):
+ raise ValueError("bounded target systems fall outside target entries")
+ source_to_aln_file = {
+ f"{search_db}_{alignment_type}": data_dir
+ / "alignment_cigars"
+ / f"search_db={search_db}"
+ / f"alignment_type={alignment_type}"
+ / f"shard={pdb_id[1:3]}.parquet"
+ for alignment_type in ["foldseek", "mmseqs"]
+ }
+ ligand_3d_candidates: list[_Ligand3DCandidateType] = []
+ ligand_pair_scores: list[_LigandPairScoreType] = []
+ repaired = (
+ self.aggregate_scores(
+ pdb_id,
+ search_db=search_db,
+ data_dir=None,
+ source_to_aln_file=source_to_aln_file,
+ query_system_ids=query_system_ids,
+ query_ligand_ids=query_ligand_ids,
+ target_system_ids=target_system_ids,
+ target_ligand_ids=target_ligand_ids,
+ ligand_3d_candidates=ligand_3d_candidates,
+ ligand_pair_scores=ligand_pair_scores,
+ include_holo_protein_scores=False,
+ )
+ if target_system_ids
+ else None
+ )
+
+ def unaffected_target(values: pd.Series) -> pd.Series:
+ return ~values.astype(str).str.split("__").str[0].isin(
+ affected_target_entries
+ )
+
+ scores = (
+ pd.read_parquet(score_path)
+ if score_path.is_file()
+ else pd.DataFrame(columns=schemas.PROTEIN_SIMILARITY_SCHEMA.names)
+ )
+ scores = scores[~scores["metric"].astype(str).str.startswith("protein_")]
+ scores = scores[unaffected_target(scores["target_system"])]
+ if repaired is not None and not repaired.empty:
+ scores = (
+ repaired.reset_index(drop=True)
+ if scores.empty
+ else pd.concat([scores, repaired], ignore_index=True)
+ )
+ score_keys = [
+ "query_system",
+ "query_ligand_id",
+ "target_system",
+ "target_ligand_id",
+ "metric",
+ ]
+ if scores.duplicated(score_keys).any():
+ raise ValueError(
+ f"targeted score repair produced duplicate rows for {pdb_id}"
+ )
+ scores = scores.sort_values(
+ [column for column, _ in SORT_ORDER],
+ ascending=[order == "ascending" for _, order in SORT_ORDER],
+ ignore_index=True,
+ )
+
+ candidates = (
+ pd.read_parquet(candidate_path)
+ if candidate_path.is_file()
+ else pd.DataFrame(columns=schemas.LIGAND_3D_CANDIDATE_SCHEMA.names)
+ )
+ candidates = candidates[
+ ~candidates["target_entry"].astype(str).isin(affected_target_entries)
+ ]
+ if ligand_3d_candidates:
+ repaired_candidates = pd.DataFrame(ligand_3d_candidates)
+ candidates = (
+ repaired_candidates.reset_index(drop=True)
+ if candidates.empty
+ else pd.concat([candidates, repaired_candidates], ignore_index=True)
+ )
+ candidate_keys = [
+ "query_system",
+ "query_ligand_id",
+ "target_system",
+ "target_ligand_id",
+ ]
+ if candidates.duplicated(candidate_keys).any():
+ raise ValueError(
+ f"targeted score repair produced duplicate candidates for {pdb_id}"
+ )
+
+ pair_scores = (
+ pd.read_parquet(ligand_pair_score_path)
+ if ligand_pair_score_path.is_file()
+ else pd.DataFrame(columns=schemas.LIGAND_PAIR_SCORE_SCHEMA.names)
+ )
+ pair_scores = pair_scores[
+ ~pair_scores["target_entry"].astype(str).isin(affected_target_entries)
+ ]
+ if ligand_pair_scores:
+ repaired_pair_scores = pd.DataFrame(ligand_pair_scores)
+ pair_scores = (
+ repaired_pair_scores.reset_index(drop=True)
+ if pair_scores.empty
+ else pd.concat([pair_scores, repaired_pair_scores], ignore_index=True)
+ )
+ if pair_scores.duplicated(candidate_keys).any():
+ raise ValueError(
+ f"targeted score repair produced duplicate ligand pairs for {pdb_id}"
+ )
+
+ temporary_root = scratch_dir or score_path.parent
+ temporary_root.mkdir(exist_ok=True, parents=True)
+ score_temporary = temporary_root / f"{pdb_id}.repair-scores.parquet"
+ candidate_temporary = temporary_root / f"{pdb_id}.repair-candidates.parquet"
+ ligand_pair_temporary = temporary_root / f"{pdb_id}.repair-ligand-pairs.parquet"
+ score_metadata = {
+ b"plinder.ligand_3d": b"deferred",
+ HOLO_PROTEIN_SCORES_METADATA_KEY: b"excluded",
+ }
+ current_threshold_metadata = score_thresholds_metadata(
+ self.minimum_threshold,
+ self.minimum_thresholds,
+ )
+ if existing_threshold_metadata == current_threshold_metadata:
+ score_metadata[SCORE_THRESHOLDS_METADATA_KEY] = current_threshold_metadata
+ score_schema = schemas.PROTEIN_SIMILARITY_SCHEMA.with_metadata(score_metadata)
+ scores.to_parquet(
+ score_temporary,
+ index=False,
+ schema=score_schema,
+ )
+ candidates.to_parquet(
+ candidate_temporary,
+ index=False,
+ schema=schemas.LIGAND_3D_CANDIDATE_SCHEMA,
+ )
+ pair_scores.to_parquet(
+ ligand_pair_temporary,
+ index=False,
+ schema=schemas.LIGAND_PAIR_SCORE_SCHEMA,
+ )
+ _atomic_copy_file(candidate_temporary, candidate_path)
+ _atomic_copy_file(ligand_pair_temporary, ligand_pair_score_path)
+ _atomic_copy_file(score_temporary, score_path)
+ score_temporary.unlink(missing_ok=True)
+ candidate_temporary.unlink(missing_ok=True)
+ ligand_pair_temporary.unlink(missing_ok=True)
+ return score_path
+
+ def load_alignments(
+ self,
+ source_to_aln_file: dict[str, Path],
+ search_db: str = "holo",
+ query_entry_ids: set[str] | None = None,
+ target_entry_ids: set[str] | None = None,
+ ) -> pd.DataFrame:
+ data = []
+ index_columns = [
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ "source",
+ ]
+ for source, aln_file in source_to_aln_file.items():
+ sdb, aln_type = source.split("_")
+ if sdb != search_db:
+ continue
+ if not aln_file.exists():
+ continue
+ filters = []
+ if query_entry_ids is not None:
+ filters.append(("query_entry", "in", query_entry_ids))
+ if target_entry_ids is not None:
+ filters.append(("target_entry", "in", target_entry_ids))
+ aln_df = pd.read_parquet(aln_file, filters=filters or None)
+ if aln_df.empty:
+ continue
+ if "cigar" in aln_df and "qcov" not in aln_df:
+ protein_scores = (
+ aln_file.parents[3]
+ / "exports"
+ / "protein_similarity_scores"
+ / f"alignment_type={aln_type}"
+ / aln_file.name
+ )
+ if not protein_scores.is_file():
+ raise FileNotFoundError(protein_scores)
+ score_columns = ["qcov", "tcov", "fident", "seqsim", "lddt"]
+ score_df = pd.read_parquet(
+ protein_scores,
+ columns=index_columns + score_columns,
+ filters=filters or None,
+ )
+ if len(aln_df) != len(score_df):
+ raise ValueError(
+ f"protein scores and CIGARs have different row counts in {aln_file}"
+ )
+ aln_df = aln_df.merge(
+ score_df,
+ on=index_columns,
+ how="left",
+ validate="one_to_one",
+ indicator=True,
+ )
+ if not aln_df["_merge"].eq("both").all():
+ raise ValueError(
+ f"protein scores do not cover CIGARs in {aln_file}"
+ )
+ aln_df = aln_df.drop(columns="_merge")
+ for column in score_columns:
+ aln_df[column] = aln_df[column].astype(float) / 100
+ # Custom-scoring alignments keep their CIGARs but are already
+ # mapped to residue numbers, so only undecoded release shards
+ # need the chain lookup.
+ if (
+ "cigar" in aln_df.columns
+ and "query_selected_residue_positions" not in aln_df.columns
+ and "query_selected_residue_numbers" not in aln_df.columns
+ ):
+ if self.alignment_chain_lookup is None:
+ raise ValueError("CIGAR alignments require a chain lookup")
+ aln_df = decode_cigar_residue_positions(
+ aln_df, chain_lookup=self.alignment_chain_lookup
+ )
+ if (
+ "query_selected_residue_positions" in aln_df.columns
+ and "query_selected_residue_numbers" not in aln_df.columns
+ ):
+ if self.alignment_chain_lookup is None:
+ raise ValueError(
+ "compact alignments require an alignment chain lookup"
+ )
+ aln_df = expand_residue_positions(
+ aln_df,
+ chain_lookup=self.alignment_chain_lookup,
+ )
+ # Per-entry mapped files written by pandas restore these fields as
+ # a MultiIndex. Release shards written by DuckDB expose the same
+ # fields as regular columns. Normalize both layouts here so shard
+ # reads can still use Parquet predicate pushdown.
+ if set(index_columns).issubset(aln_df.columns):
+ aln_df["source"] = aln_type
+ aln_df = aln_df.set_index(index_columns)
+ elif list(aln_df.index.names) != index_columns:
+ raise ValueError(
+ f"unexpected mapped alignment schema in {aln_file}: "
+ f"index={aln_df.index.names}, columns={list(aln_df.columns)}"
+ )
+ aln_df["fident_qcov"] = aln_df["fident"] * aln_df["qcov"]
+ aln_df["seqsim_qcov"] = aln_df["seqsim"] * aln_df["qcov"]
+ if aln_type == "foldseek":
+ aln_df["lddt_qcov"] = aln_df["lddt"] * aln_df["qcov"]
+ # Per-query mapped files use four position-keyed nested columns.
+ # Compact release shards expose aligned residue arrays and identity
+ # bytes, so they require no Python dictionary expansion.
+ if "qrnum" in aln_df.columns:
+ for column in ["qrnum", "trnum"]:
+ aln_df[column] = aln_df[column].apply(
+ lambda x: {int(i): int(r) for i, r in x}
+ )
+ for column in ["qaa", "taa"]:
+ aln_df[column] = [
+ {
+ position: str(residue)
+ for position, residue in zip(qrnum, residues)
+ }
+ for qrnum, residues in zip(aln_df["qrnum"], aln_df[column])
+ ]
+ data.append(aln_df)
+ if len(data):
+ df = pd.concat(data)
+ return df.sort_index()
+ else:
+ return pd.DataFrame()
+
+ def map_alignment_df(
+ self, df_file: Path, aln_type: str, search_db: str
+ ) -> pd.DataFrame:
+ df = pd.read_parquet(df_file)
+ if df.empty:
+ for column in [
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ ]:
+ df[column] = pd.Series(dtype="string")
+ for column in ["seqsim", "seqsim_qcov", "fident_qcov"]:
+ df[column] = pd.Series(dtype="float64")
+ if aln_type == "foldseek":
+ df["lddt_qcov"] = pd.Series(dtype="float64")
+ for column in [
+ "query_selected_residue_numbers",
+ "target_selected_residue_numbers",
+ "query_selected_residue_positions",
+ "target_selected_residue_positions",
+ "selected_residue_identity_bits",
+ ]:
+ df[column] = pd.Series(dtype="object")
+ df.drop(
+ columns=["qaln", "taln", "evalue", "bits"],
+ inplace=True,
+ errors="ignore",
+ )
+ df["source"] = pd.Series(dtype="string")
+ return df.set_index(
+ [
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ "source",
+ ]
+ )
+ if aln_type == "foldseek":
+ query_replacements = [
+ "_xyz-enrich.cif.gz",
+ "_xyz-enrich.cif",
+ "_xyz-enrich",
+ "pdb_0000",
+ ".cif.gz",
+ ".cif",
+ ]
+ for value in query_replacements:
+ df["query"] = df["query"].str.replace(value, "", regex=False)
+ if search_db == "pred":
+ for value in ["-F1-model_v4.cif", "-F1-model_v4", "AF-"]:
+ df["target"] = df["target"].str.replace(value, "", regex=False)
+ else:
+ for value in query_replacements:
+ df["target"] = df["target"].str.replace(value, "", regex=False)
+ query_parts = df["query"].str.split("_", n=1, expand=True)
+ if aln_type == "foldseek":
+ query_parts[1] = query_parts[1].str.replace(r"^MODEL_\d+_", "", regex=True)
+ df["query_entry"] = query_parts[0]
+ df["query_chain_mapped"] = [
+ self.entries[entry].author_to_asym.get(author)
+ for entry, author in zip(query_parts[0], query_parts[1])
+ ]
+ df = df.dropna(subset=["query_chain_mapped"]).reset_index(drop=True)
+ if search_db == "pred":
+ df["target_chain_mapped"] = "A"
+ df["target_entry"] = df["target"].str.split("_", n=1).str[0]
+ else:
+ target_parts = df["target"].str.split("_", n=1, expand=True)
+ if aln_type == "foldseek":
+ target_parts[1] = target_parts[1].str.replace(
+ r"^MODEL_\d+_", "", regex=True
+ )
+ df["target_entry"] = target_parts[0]
+ df["target_chain_mapped"] = [
+ (
+ self.entries[entry].author_to_asym.get(author)
+ if entry in self.entries
+ else None
+ )
+ for entry, author in zip(target_parts[0], target_parts[1])
+ ]
+ df = df.dropna(subset=["target_chain_mapped"]).reset_index(drop=True)
+ df["qaln"] = df["qaln"].str.upper()
+ df["taln"] = df["taln"].str.upper()
+ df["seqsim"] = [
+ get_sequence_similarity_helper(qaln, taln)
+ for qaln, taln in zip(df["qaln"], df["taln"])
+ ]
+ df["seqsim_qcov"] = df["seqsim"] * df["qcov"]
+ df["fident_qcov"] = df["fident"] * df["qcov"]
+ if aln_type == "foldseek":
+ df["lddt_qcov"] = df["lddt"] * df["qcov"]
+ selected_mappings = [
+ self._map_alignment_selected_positions(
+ query_entry=row.query_entry,
+ target_entry=row.target_entry,
+ query_chain=str(row.query_chain_mapped),
+ target_chain=str(row.target_chain_mapped),
+ qstart=int(row.qstart),
+ tstart=int(row.tstart),
+ qaln=str(row.qaln),
+ taln=str(row.taln),
+ aln_type=aln_type,
+ search_db=search_db,
+ )
+ for row in df.itertuples(index=False)
+ ]
+ for index, column in enumerate(
+ (
+ "query_selected_residue_numbers",
+ "target_selected_residue_numbers",
+ "query_selected_residue_positions",
+ "target_selected_residue_positions",
+ "selected_residue_identity_bits",
+ )
+ ):
+ df[column] = [mapping[index] for mapping in selected_mappings]
+ # Retain only selected ligand-pocket/interface residue numbers,
+ # chain-lookup positions, and identity bits. Complete alignments and
+ # amino-acid strings are not needed downstream.
+ df.drop(
+ columns=["qaln", "taln", "evalue", "bits"],
+ inplace=True,
+ errors="ignore",
+ )
+ df["source"] = aln_type
+ df.set_index(
+ [
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ "source",
+ ],
+ inplace=True,
+ )
+ return df
+
+ def _map_alignment_selected_positions(
+ self,
+ *,
+ query_entry: str,
+ target_entry: str,
+ query_chain: str,
+ target_chain: str,
+ qstart: int,
+ tstart: int,
+ qaln: str,
+ taln: str,
+ aln_type: str,
+ search_db: str,
+ ) -> tuple[list[int], list[int], list[int], list[int], bytes]:
+ """Map sparse selected query positions through one pairwise alignment."""
+ # mmseqs operates on the SEQRES FASTA, so 1-based position
+ # equals the residue NUMBER (label_seq_id = Chain.residues key);
+ # foldseek operates on the 3D structure, so position == 0-based
+ # resolved-residue INDEX;
+ query_numbers: list[int] = []
+ target_numbers: list[int] = []
+ query_positions: list[int] = []
+ target_positions: list[int] = []
+ residue_identity = bytearray()
+ q_i, t_i = qstart - 1, tstart - 1
+ q_entry = self.entries[query_entry]
+ q_i2n = q_entry.selected_index_to_number_per_chain.get(query_chain, {})
+ t_i2n: dict[int, int] = {}
+ if search_db != "pred":
+ t_entry = self.entries[target_entry]
+ t_i2n = t_entry.selected_index_to_number_per_chain.get(target_chain, {})
+ alignment_length = min(len(qaln), len(taln))
+ if not q_i2n or alignment_length == 0:
+ return (
+ query_numbers,
+ target_numbers,
+ query_positions,
+ target_positions,
+ bytes(residue_identity),
+ )
+
+ query_number_to_position = {
+ number: position
+ for position, (_, number) in enumerate(sorted(q_i2n.items()), start=1)
+ }
+ target_number_to_position = {
+ number: position
+ for position, (_, number) in enumerate(sorted(t_i2n.items()), start=1)
+ }
+
+ qaln = qaln[:alignment_length]
+ taln = taln[:alignment_length]
+ query_residue_positions = [
+ position for position, residue in enumerate(qaln) if residue != "-"
+ ]
+ target_residue_positions = [
+ position for position, residue in enumerate(taln) if residue != "-"
+ ]
+
+ # Locate only sparse selected query positions in the alignment instead of
+ # walking every aligned character in Python. Offsets are relative to
+ # the first aligned residue reported by the search backend.
+ if aln_type == "mmseqs":
+ query_candidates = [
+ (number - (q_i + 1), number) for number in set(q_i2n.values())
+ ]
+ target_selected_numbers = set(t_i2n.values())
+ else:
+ query_candidates = [
+ (index - q_i, number) for index, number in q_i2n.items()
+ ]
+ target_selected_numbers = set()
+
+ for query_offset, query_number in sorted(query_candidates):
+ if not 0 <= query_offset < len(query_residue_positions):
+ continue
+ alignment_position = query_residue_positions[query_offset]
+ if taln[alignment_position] == "-":
+ continue
+ target_index = t_i + bisect_left(
+ target_residue_positions, alignment_position
+ )
+ if aln_type == "mmseqs":
+ target_number = (
+ target_index + 1
+ if target_index + 1 in target_selected_numbers
+ else None
+ )
+ else:
+ target_number = t_i2n.get(target_index) if search_db != "pred" else None
+ query_numbers.append(query_number)
+ target_numbers.append(target_number if target_number is not None else -1)
+ query_positions.append(query_number_to_position[query_number])
+ target_positions.append(
+ target_number_to_position[target_number]
+ if target_number is not None
+ else 0
+ )
+ identity_position = len(query_numbers) - 1
+ if identity_position % 8 == 0:
+ residue_identity.append(0)
+ if qaln[alignment_position] == taln[alignment_position]:
+ residue_identity[-1] |= 1 << (identity_position % 8)
+ return (
+ query_numbers,
+ target_numbers,
+ query_positions,
+ target_positions,
+ bytes(residue_identity),
+ )
+
+ def map_row(self, parts: pd.Series, aln_type: str, search_db: str) -> pd.Series:
+ """Map selected positions for callers operating on one pandas row."""
+ mapped = self._map_alignment_selected_positions(
+ query_entry=str(parts["query_entry"]),
+ target_entry=str(parts["target_entry"]),
+ query_chain=str(parts["query_chain_mapped"]),
+ target_chain=str(parts["target_chain_mapped"]),
+ qstart=int(parts["qstart"]),
+ tstart=int(parts["tstart"]),
+ qaln=str(parts["qaln"]),
+ taln=str(parts["taln"]),
+ aln_type=aln_type,
+ search_db=search_db,
+ )
+ for column, values in zip(
+ (
+ "query_selected_residue_numbers",
+ "target_selected_residue_numbers",
+ "query_selected_residue_positions",
+ "target_selected_residue_positions",
+ "selected_residue_identity_bits",
+ ),
+ mapped,
+ ):
+ parts[column] = values
+ return parts
+
+ def get_protein_scores_pair(self, aln: pd.DataFrame) -> dict[str, float]:
+ scores = {}
+ for source in aln.index.unique():
+ source_rows = aln.loc[source]
+ if isinstance(source_rows, pd.DataFrame):
+ rank_column = "lddt_qcov" if source == "foldseek" else "fident_qcov"
+ data = source_rows.sort_values(
+ [rank_column, "qcov", "fident"],
+ ascending=False,
+ kind="stable",
+ ).iloc[0]
+ else:
+ data = source_rows
+ for score in ["qcov", "fident", "seqsim", "fident_qcov", "seqsim_qcov"]:
+ scores[f"protein_{score}_{source}"] = data[score]
+ if source == "foldseek":
+ for score in ["lddt", "lddt_qcov"]:
+ scores[f"protein_{score}_{source}"] = data[score]
+ return scores
+
+ def get_protein_scores(
+ self,
+ query_target_entry_alignments: pd.DataFrame,
+ query_system: SystemView,
+ target_protein_chains: list[str],
+ query_system_length: int,
+ query_protein_chains: list[str] | None = None,
+ ) -> tuple[
+ dict[str, list[_ChainPairType]],
+ _SimilarityScoreDictType,
+ dict[_ChainPairType, pd.DataFrame],
+ str,
+ ]:
+ scores: _SimilarityScoreDictType = defaultdict(float)
+ mappings: dict[str, list[_ChainPairType]] = defaultdict(list)
+ max_chain_lengths: dict[str, float] = defaultdict(float)
+ protein_chain_mapper = ""
+ if query_protein_chains is None:
+ query_protein_chains = query_system.protein_chains_asym_id
+ query_protein_chains = self.get_protein_receptor_chains(
+ query_system.pdb_id, query_protein_chains
+ )
+ query_system_length = self.get_protein_chain_length(
+ query_system.pdb_id, query_protein_chains
+ )
+ s_matrix = np.zeros(
+ (
+ len(query_protein_chains),
+ len(target_protein_chains),
+ )
+ )
+ for i, q_instance_chain in enumerate(query_protein_chains):
+ q_chain = q_instance_chain.split(".", maxsplit=1)[1]
+ q_chain_length = self.entries[query_system.pdb_id].chains[q_chain].length
+ for j, t_instance_chain in enumerate(target_protein_chains):
+ t_chain = t_instance_chain.split(".", maxsplit=1)[1]
+ try:
+ aln = query_target_entry_alignments.loc[(q_chain, t_chain)]
+ except KeyError:
+ LOG.debug("get_protein_scores indexing failed, aln is None")
+ aln = None
+ if aln is not None:
+ pair = (q_instance_chain, t_instance_chain)
+ pair_scores = self.get_protein_scores_pair(aln)
+ if protein_chain_mapper == "":
+ for chain_mapper in self.protein_chain_mappers:
+ if chain_mapper in pair_scores:
+ protein_chain_mapper = chain_mapper
+ break
+ s_matrix[i, j] = pair_scores.get(protein_chain_mapper, 0)
+ for score in pair_scores:
+ if (
+ pair_scores[score] * q_chain_length
+ > scores[f"{score}_weighted_max"]
+ ):
+ scores[f"{score}_weighted_max"] = (
+ pair_scores[score] * q_chain_length
+ )
+ max_chain_lengths[f"{score}_weighted_max"] = q_chain_length
+ mappings[f"{score}_weighted_max"] = [pair]
+ if pair_scores[score] > scores[f"{score}_max"]:
+ scores[f"{score}_max"] = pair_scores[score]
+ mappings[f"{score}_max"] = [pair]
+ for score in scores:
+ if score.endswith("_weighted_max") and max_chain_lengths[score] > 0:
+ scores[score] /= max_chain_lengths[score]
+
+ # do chain mapping
+ # Find the highest scores along with their indices in the matrix
+ alns = {}
+ while np.any(s_matrix):
+ # changed score -> score_tag conflicting variable name
+ score_val = float(np.amax(s_matrix))
+ if score_val == 0:
+ break
+ q_idx, t_idx = np.unravel_index(np.argmax(s_matrix), s_matrix.shape)
+ q_instance_chain, t_instance_chain = (
+ query_protein_chains[q_idx],
+ target_protein_chains[t_idx],
+ )
+ q_chain, t_chain = (
+ q_instance_chain.split(".", maxsplit=1)[1],
+ t_instance_chain.split(".", maxsplit=1)[1],
+ )
+ try:
+ aln = query_target_entry_alignments.loc[(q_chain, t_chain)]
+ except KeyError:
+ break
+ pair = (q_instance_chain, t_instance_chain)
+ pair_scores = self.get_protein_scores_pair(aln)
+ for score in pair_scores:
+ scores[f"{score}_weighted_sum"] += (
+ pair_scores[score]
+ * self.entries[query_system.pdb_id].chains[q_chain].length
+ )
+ alns[pair] = aln
+
+ mappings[f"{protein_chain_mapper}_weighted_sum"].append(pair)
+ # Zero out the entire row and column for the max element
+ s_matrix[q_idx, :] = 0
+ s_matrix[:, t_idx] = 0
+ for score in scores:
+ if score.endswith("_weighted_sum") and query_system_length > 0:
+ scores[score] /= query_system_length
+ return mappings, scores, alns, protein_chain_mapper
+
+ def get_pocket_pli_scores(
+ self,
+ alns: dict[_ChainPairType, pd.DataFrame],
+ query_system: SystemView,
+ target_system: SystemView | None = None,
+ ) -> tuple[
+ _SimilarityScoreDictType,
+ _SimilarityScoreDictType,
+ ]:
+ (
+ query_pocket,
+ query_interactions,
+ pocket_length,
+ pli_length,
+ ) = self._protein_only_pocket_data(
+ query_system.pdb_id,
+ query_system.protein_chains_asym_id,
+ query_system.pocket_residue_number_to_index,
+ query_system.interactions_counter,
+ )
+ target_pocket = None
+ target_interactions = None
+ if target_system is not None:
+ (
+ target_pocket,
+ target_interactions,
+ _,
+ _,
+ ) = self._protein_only_pocket_data(
+ target_system.pdb_id,
+ target_system.protein_chains_asym_id,
+ target_system.pocket_residue_number_to_index,
+ target_system.interactions_counter,
+ )
+ return self._get_pocket_pli_scores(
+ alns=alns,
+ query_pocket=query_pocket,
+ query_interactions=query_interactions,
+ pocket_length=pocket_length,
+ pli_length=pli_length,
+ target_pocket=target_pocket,
+ target_interactions=target_interactions,
+ )
+
+ def _protein_only_pocket_data(
+ self,
+ pdb_id: str,
+ receptor_chains: list[str],
+ pocket: dict[str, dict[int, int]],
+ interactions: dict[str, dict[int, Counter[str]]],
+ ) -> tuple[
+ dict[str, dict[int, int]],
+ dict[str, dict[int, Counter[str]]],
+ int,
+ int,
+ ]:
+ """Restrict pocket and interaction data to polypeptide receptors."""
+ allowed = set(self.get_protein_receptor_chains(pdb_id, receptor_chains))
+ protein_pocket = {
+ chain: residues for chain, residues in pocket.items() if chain in allowed
+ }
+ protein_interactions = {
+ chain: residues
+ for chain, residues in interactions.items()
+ if chain in allowed
+ }
+ pocket_length = sum(len(residues) for residues in protein_pocket.values())
+ interaction_length = sum(
+ sum(counter.values())
+ for residues in protein_interactions.values()
+ for counter in residues.values()
+ )
+ return (
+ protein_pocket,
+ protein_interactions,
+ pocket_length,
+ interaction_length,
+ )
+
+ def _get_pocket_pli_scores(
+ self,
+ *,
+ alns: abc.Mapping[
+ _ChainPairType, pd.DataFrame | list[tuple[str, dict[str, Any]]]
+ ],
+ query_pocket: dict[str, dict[int, int]],
+ query_interactions: dict[str, dict[int, Counter[str]]],
+ pocket_length: int,
+ pli_length: int,
+ target_pocket: dict[str, dict[int, int]] | None,
+ target_interactions: dict[str, dict[int, Counter[str]]] | None,
+ ) -> tuple[
+ _SimilarityScoreDictType,
+ _SimilarityScoreDictType,
+ ]:
+ pocket_scores: _SimilarityScoreDictType = defaultdict(float)
+ pli_scores: _SimilarityScoreDictType = defaultdict(float)
+ has_target = target_pocket is not None
+ target_pocket = target_pocket or {}
+ target_interactions = target_interactions or {}
+ pli_residue_length = sum(
+ len(residues) for residues in query_interactions.values()
+ )
+ # Compact maps contain only aligned selected query residue numbers,
+ # selected target residue numbers (or -1), and amino-acid identity
+ # flags. The scorer then filters that shared representation to this
+ # ligand pair's pocket residues.
+ for q_instance_chain, t_instance_chain in alns:
+ aln = alns[(q_instance_chain, t_instance_chain)]
+ q_chain_pocket = query_pocket.get(q_instance_chain, {})
+ q_chain_interactions = query_interactions.get(q_instance_chain, {})
+ t_chain_pocket = target_pocket.get(t_instance_chain, {})
+ t_chain_interactions = target_interactions.get(t_instance_chain, {})
+ rows = aln.iterrows() if isinstance(aln, pd.DataFrame) else aln
+ for source, aln_source in rows:
+ pocket_positions = self._aligned_query_pocket(
+ aln_source, q_chain_pocket
+ )
+ if pocket_positions is None:
+ continue
+ if self.include_pli_fident and pli_residue_length:
+ pli_scores.setdefault(f"pli_fident_{source}", 0.0)
+ for q_n, t_n, residues_are_identical in pocket_positions:
+ if residues_are_identical:
+ pocket_scores[f"pocket_fident_{source}"] += 1
+ if self.include_pli_fident and q_n in q_chain_interactions:
+ pli_scores[f"pli_fident_{source}"] += 1
+ if has_target and t_n >= 0 and t_n in t_chain_pocket:
+ pocket_scores[f"pocket_qcov_{source}"] += 1
+ if residues_are_identical:
+ pocket_scores[f"pocket_fident_qcov_{source}"] += 1
+ if q_n in q_chain_interactions and t_n in t_chain_interactions:
+ pli_scores[f"pli_qcov_{source}"] += sum(
+ (
+ q_chain_interactions[q_n]
+ & t_chain_interactions[t_n]
+ ).values()
+ )
+ if pocket_length:
+ for score in pocket_scores:
+ pocket_scores[score] /= pocket_length
+ else:
+ pocket_scores.clear()
+ for score in list(pli_scores):
+ if score.startswith("pli_fident_"):
+ denominator = pli_residue_length
+ else:
+ denominator = pli_length
+ if denominator:
+ pli_scores[score] /= denominator
+ else:
+ del pli_scores[score]
+ return pocket_scores, pli_scores
+
+ def _get_ligand_pair_pocket_pli_scores_for_mapping(
+ self,
+ alns: dict[_ChainPairType, pd.DataFrame],
+ query_ligand: LigandView,
+ target_ligand: LigandView,
+ ) -> tuple[
+ _SimilarityScoreDictType,
+ _SimilarityScoreDictType,
+ ]:
+ """Calculate directed pocket and PLI coverage for one ligand pair."""
+ (
+ query_pocket,
+ query_interactions,
+ pocket_length,
+ pli_length,
+ ) = self._ligand_protein_only_pocket_data(query_ligand)
+ (
+ target_pocket,
+ target_interactions,
+ _,
+ _,
+ ) = self._ligand_protein_only_pocket_data(target_ligand)
+ return self._get_pocket_pli_scores(
+ alns=alns,
+ query_pocket=query_pocket,
+ query_interactions=query_interactions,
+ pocket_length=pocket_length,
+ pli_length=pli_length,
+ target_pocket=target_pocket,
+ target_interactions=target_interactions,
+ )
+
+ @staticmethod
+ def _pocket_coverage_for_alignment_row(
+ alignment: pd.Series | dict[str, Any],
+ query_pocket: dict[int, int],
+ target_pocket: dict[int, int],
+ ) -> int:
+ """Count query-pocket residues aligned into one target-chain pocket."""
+ if "query_selected_residue_numbers" in alignment:
+ query_numbers = alignment["query_selected_residue_numbers"]
+ target_numbers = alignment["target_selected_residue_numbers"]
+ if not isinstance(query_numbers, abc.Iterable) or not isinstance(
+ target_numbers, abc.Iterable
+ ):
+ return 0
+ return sum(
+ query_number in query_pocket
+ and target_number >= 0
+ and target_number in target_pocket
+ for query_number, target_number in zip(
+ query_numbers, target_numbers, strict=True
+ )
+ )
+ return sum(
+ query_number in query_pocket
+ and alignment["trnum"].get(position, -1) in target_pocket
+ for position, query_number in alignment["qrnum"].items()
+ )
+
+ def _pocket_alignment_rows(
+ self,
+ alignments: pd.DataFrame,
+ query_chain: str,
+ target_chain: str,
+ source: str,
+ ) -> list[dict[str, Any]]:
+ """Reuse plain alignment rows for each chain pair and backend."""
+ frame_id = id(alignments)
+ if frame_id not in self._pocket_alignment_row_cache:
+ mapping_columns = (
+ (
+ "query_selected_residue_numbers",
+ "target_selected_residue_numbers",
+ "selected_residue_identity_bits",
+ )
+ if "query_selected_residue_numbers" in alignments.columns
+ else ("qrnum", "trnum", "qaa", "taa")
+ )
+ columns = [
+ column
+ for column in (
+ *mapping_columns,
+ "lddt_qcov",
+ "fident_qcov",
+ "qcov",
+ "fident",
+ )
+ if column in alignments.columns
+ ]
+ mapping_size = sum(
+ column in alignments.columns for column in mapping_columns
+ )
+ rows: dict[tuple[str, str, str], list[dict[str, Any]]] = {}
+ for key, *values in alignments[columns].itertuples(name=None):
+ mapping_signature = hashlib.sha256(
+ pickle.dumps((mapping_columns, values[:mapping_size]), protocol=5)
+ ).digest()
+ signature = hashlib.sha256(
+ mapping_signature
+ + pickle.dumps(
+ (columns[mapping_size:], values[mapping_size:]), protocol=5
+ )
+ ).digest()
+ if signature not in self._pocket_alignment_inputs:
+ self._pocket_alignment_inputs[signature] = {
+ **dict(zip(columns, values)),
+ "pocket_input_key": signature,
+ "pocket_mapping_key": mapping_signature,
+ }
+ rows.setdefault(key, []).append(
+ self._pocket_alignment_inputs[signature]
+ )
+ self._pocket_alignment_row_cache[frame_id] = (alignments, rows)
+ return self._pocket_alignment_row_cache[frame_id][1].get(
+ (query_chain, target_chain, source), []
+ )
+
+ def _aligned_query_pocket(
+ self,
+ alignment: pd.Series | dict[str, Any],
+ query_pocket: dict[int, int],
+ ) -> tuple[tuple[int, int, bool], ...] | None:
+ """Project an exact alignment onto a pocket, independently of chain names."""
+ signature: bytes | None = alignment.get("pocket_mapping_key")
+ key = (
+ (signature, tuple(sorted(query_pocket))) if signature is not None else None
+ )
+ if key is not None and key in self._aligned_query_pockets:
+ return self._aligned_query_pockets[key]
+ positions: abc.Iterable[tuple[int, int, bool]]
+ if "query_selected_residue_numbers" in alignment:
+ query = alignment["query_selected_residue_numbers"]
+ target = alignment["target_selected_residue_numbers"]
+ bits = alignment["selected_residue_identity_bits"]
+ if not all(
+ isinstance(value, abc.Iterable) for value in (query, target, bits)
+ ):
+ return None
+ positions = zip(query, target, unpack_residue_identities(bits, len(query)))
+ else:
+ positions = (
+ (
+ number,
+ alignment["trnum"].get(position, -1),
+ alignment["qaa"][position] == alignment["taa"][position],
+ )
+ for position, number in alignment["qrnum"].items()
+ )
+ result = tuple(
+ position for position in positions if position[0] in query_pocket
+ )
+ if key is not None:
+ if len(self._aligned_query_pockets) >= _POCKET_CACHE_MAX_ENTRIES:
+ self._aligned_query_pockets.clear()
+ self._aligned_query_pockets[key] = result
+ return result
+
+ def _best_pocket_chain_alignment(
+ self,
+ rows: list[dict[str, Any]],
+ mapper_column: str,
+ query_pocket: dict[int, int],
+ target_pocket: dict[int, int],
+ ) -> tuple[tuple[float, float, float, float], dict[str, Any]] | None:
+ """Reuse chain-pair selection only for identical ordered alignment inputs."""
+ if not rows:
+ return None
+ key = (
+ mapper_column,
+ tuple(row["pocket_input_key"] for row in rows),
+ tuple(sorted(query_pocket)),
+ tuple(sorted(target_pocket)),
+ )
+ if key not in self._pocket_chain_matches:
+ best = None
+ for row in rows:
+ positions = self._aligned_query_pocket(row, query_pocket)
+ if positions is None:
+ coverage = self._pocket_coverage_for_alignment_row(
+ row, query_pocket, target_pocket
+ )
+ else:
+ compact = "query_selected_residue_numbers" in row
+ coverage = sum(
+ number in target_pocket and (number >= 0 or not compact)
+ for _, number, _ in positions
+ )
+ rank = (
+ float(coverage),
+ _finite_float_or_zero(row.get(mapper_column, 0.0)),
+ _finite_float_or_zero(row.get("qcov", 0.0)),
+ _finite_float_or_zero(row.get("fident", 0.0)),
+ )
+ if best is None or rank > best[0]:
+ best = (rank, row)
+ if len(self._pocket_chain_matches) >= _POCKET_CACHE_MAX_ENTRIES:
+ self._pocket_chain_matches.clear()
+ self._pocket_chain_matches[key] = best
+ return self._pocket_chain_matches[key]
+
+ def _clear_pocket_alignment_cache(self) -> None:
+ self._pocket_alignment_row_cache.clear()
+ self._pocket_alignment_inputs.clear()
+ self._aligned_query_pockets.clear()
+ self._pocket_chain_matches.clear()
+
+ def get_ligand_pair_pocket_pli_scores(
+ self,
+ query_target_entry_alignments: pd.DataFrame,
+ query_ligand: LigandView,
+ target_ligand: LigandView,
+ ) -> tuple[
+ _SimilarityScoreDictType,
+ _SimilarityScoreDictType,
+ dict[str, list[_ChainPairType]],
+ ]:
+ """Score a ligand pair after maximizing its pocket coverage per backend."""
+ (
+ query_pocket,
+ query_interactions,
+ pocket_length,
+ pli_length,
+ ) = self._ligand_protein_only_pocket_data(query_ligand)
+ (
+ target_pocket,
+ target_interactions,
+ _,
+ _,
+ ) = self._ligand_protein_only_pocket_data(target_ligand)
+ pocket_scores: _SimilarityScoreDictType = defaultdict(float)
+ pli_scores: _SimilarityScoreDictType = defaultdict(float)
+ mappings: dict[str, list[_ChainPairType]] = {}
+ query_aliases = self._pocket_pattern_info(query_ligand)[1]
+ target_aliases = self._pocket_pattern_info(target_ligand)[1]
+ query_chains = {alias: chain for chain, alias in query_aliases.items()}
+ target_chains = {alias: chain for chain, alias in target_aliases.items()}
+
+ for source, mapper_column in (
+ ("foldseek", "lddt_qcov"),
+ ("mmseqs", "fident_qcov"),
+ ):
+ primary_weights: dict[_ChainPairType, float] = {}
+ secondary_weights: dict[_ChainPairType, float] = {}
+ selected_alignments: dict[
+ _ChainPairType, pd.DataFrame | list[tuple[str, dict[str, Any]]]
+ ] = {}
+ for query_chain in sorted(query_pocket):
+ query_asym_id = query_chain.split(".", 1)[-1]
+ for target_chain in sorted(target_pocket):
+ target_asym_id = target_chain.split(".", 1)[-1]
+ source_alignments = self._pocket_alignment_rows(
+ query_target_entry_alignments,
+ query_asym_id,
+ target_asym_id,
+ source,
+ )
+ best = self._best_pocket_chain_alignment(
+ source_alignments,
+ mapper_column,
+ query_pocket[query_chain],
+ target_pocket[target_chain],
+ )
+ if best is None:
+ continue
+ best_rank, best_alignment = best
+ chain_pair = (query_chain, target_chain)
+ primary_weights[chain_pair] = best_rank[0]
+ secondary_weights[chain_pair] = best_rank[1]
+ selected_alignments[chain_pair] = [(source, best_alignment)]
+
+ canonical_assignment = maximum_weight_bipartite_assignment(
+ (query_aliases[chain] for chain in query_pocket),
+ (target_aliases[chain] for chain in target_pocket),
+ {
+ (query_aliases[query_chain], target_aliases[target_chain]): weight
+ for (query_chain, target_chain), weight in primary_weights.items()
+ },
+ secondary_weights={
+ (query_aliases[query_chain], target_aliases[target_chain]): weight
+ for (query_chain, target_chain), weight in secondary_weights.items()
+ },
+ )
+ assignment = [
+ (query_chains[query_chain], target_chains[target_chain])
+ for query_chain, target_chain in canonical_assignment
+ ]
+ backend_alignments = {
+ pair: selected_alignments[pair]
+ for pair in assignment
+ if pair in selected_alignments
+ }
+ if not backend_alignments:
+ continue
+ backend_pocket, backend_pli = self._get_pocket_pli_scores(
+ alns=backend_alignments,
+ query_pocket=query_pocket,
+ query_interactions=query_interactions,
+ pocket_length=pocket_length,
+ pli_length=pli_length,
+ target_pocket=target_pocket,
+ target_interactions=target_interactions,
+ )
+ pocket_scores.update(backend_pocket)
+ pli_scores.update(backend_pli)
+ for metric in (*backend_pocket, *backend_pli):
+ mappings[metric] = assignment
+ return pocket_scores, pli_scores, mappings
+
+ def get_ligand_pocket_scores(
+ self,
+ alns: dict[_ChainPairType, pd.DataFrame],
+ query_ligand: LigandView,
+ ) -> _SimilarityScoreDictType:
+ """Calculate directed pocket identity for a ligand against apo/pred."""
+ (
+ query_pocket,
+ query_interactions,
+ pocket_length,
+ pli_length,
+ ) = self._ligand_protein_only_pocket_data(query_ligand)
+ pocket_scores, pli_scores = self._get_pocket_pli_scores(
+ alns=alns,
+ query_pocket=query_pocket,
+ query_interactions=query_interactions,
+ pocket_length=pocket_length,
+ pli_length=pli_length,
+ target_pocket=None,
+ target_interactions=None,
+ )
+ pocket_scores.update(pli_scores)
+ return pocket_scores
+
+ def _ligand_protein_only_pocket_data(self, ligand: LigandView) -> _PocketDataType:
+ """Cache immutable protein-only pocket inputs per ligand occurrence."""
+ if ligand.id not in self._ligand_pocket_data_cache:
+ self._ligand_pocket_data_cache[ligand.id] = self._protein_only_pocket_data(
+ ligand.pdb_id,
+ ligand.protein_chains_asym_id,
+ ligand.pocket_residue_number_to_index,
+ ligand.interactions_counter,
+ )
+ return self._ligand_pocket_data_cache[ligand.id]
+
+ def get_protein_receptor_chains(
+ self, pdb_id: str, receptor_chains: list[str]
+ ) -> list[str]:
+ """Return only polypeptide instance chains from a receptor collection."""
+ entry = self.entries.get(pdb_id)
+ if entry is None:
+ # LigandView instances constructed outside an EntryView are expected
+ # to already carry the protein-only scoring representation.
+ return sorted(set(receptor_chains))
+ result = []
+ for instance_chain in receptor_chains:
+ asym_id = instance_chain.split(".", maxsplit=1)[-1]
+ chain = entry.chains.get(asym_id)
+ if chain is not None and chain.is_polypeptide:
+ result.append(instance_chain)
+ return sorted(set(result))
+
+ def get_protein_chain_length(self, pdb_id: str, protein_chains: list[str]) -> int:
+ """Return the total SEQRES length for an instance-chain collection."""
+ return sum(
+ self.entries[pdb_id].chains[instance_chain.split(".", 1)[1]].length
+ for instance_chain in self.get_protein_receptor_chains(
+ pdb_id, protein_chains
+ )
+ )
+
+ def get_scores(
+ self,
+ search_db: str,
+ query_system: SystemView,
+ query_entry_alignments: pd.DataFrame,
+ data_dir: Path | None = None,
+ ligand_3d_candidates: list[_Ligand3DCandidateType] | None = None,
+ ligand_pair_scores: list[_LigandPairScoreType] | None = None,
+ query_ligand_ids: set[str] | None = None,
+ target_system_ids: set[str] | None = None,
+ target_ligand_ids: set[str] | None = None,
+ include_holo_protein_scores: bool = False,
+ pocket_pair_cache: dict[str, dict[str, set[str]]] | None = None,
+ query_pocket_representatives: dict[str, LigandView] | None = None,
+ target_ligand_cache: dict[str, list[LigandView]] | None = None,
+ pocket_score_cache: _PocketScoreCacheType | None = None,
+ target_alignment_cache: dict[str, pd.DataFrame] | None = None,
+ ) -> abc.Generator[dict[str, str | float | None], None, None]:
+ if search_db == "holo":
+ return self.get_scores_holo(
+ query_system,
+ query_entry_alignments,
+ data_dir=data_dir,
+ ligand_3d_candidates=ligand_3d_candidates,
+ ligand_pair_scores=ligand_pair_scores,
+ query_ligand_ids=query_ligand_ids,
+ target_system_ids=target_system_ids,
+ target_ligand_ids=target_ligand_ids,
+ include_protein_scores=include_holo_protein_scores,
+ pocket_pair_cache=pocket_pair_cache,
+ query_pocket_representatives=query_pocket_representatives,
+ target_ligand_cache=target_ligand_cache,
+ pocket_score_cache=pocket_score_cache,
+ target_alignment_cache=target_alignment_cache,
+ )
+ elif search_db == "apo" or search_db == "pred":
+ return self.get_scores_apo_pred(
+ query_system,
+ query_entry_alignments,
+ query_ligand_ids=query_ligand_ids,
+ target_system_ids=target_system_ids,
+ )
+ else:
+ raise ValueError(f"Invalid search_db: {search_db}")
+
+ @staticmethod
+ def _aligned_pocket_pairs(
+ alignments: pd.DataFrame,
+ query_ligands: list[LigandView],
+ target_ligands: list[LigandView],
+ ) -> set[tuple[str, str]]:
+ """Find ligand pairs with at least one aligned pocket-residue pair."""
+ pockets: list[dict[str, dict[int, set[str]]]] = []
+ for ligands in (query_ligands, target_ligands):
+ by_residue: dict[str, dict[int, set[str]]] = {}
+ for ligand in ligands:
+ for chain, residues in ligand.pocket_residue_number_to_index.items():
+ asym_id = chain.split(".", 1)[-1]
+ for number in residues:
+ by_residue.setdefault(asym_id, {}).setdefault(
+ int(number), set()
+ ).add(ligand.id)
+ pockets.append(by_residue)
+ query_pockets, target_pockets = pockets
+ if not query_pockets or not target_pockets:
+ return set()
+
+ pairs: set[tuple[str, str]] = set()
+ compact = "query_selected_residue_numbers" in alignments.columns
+ columns = (
+ ["query_selected_residue_numbers", "target_selected_residue_numbers"]
+ if compact
+ else ["qrnum", "trnum"]
+ )
+ for (query_chain, target_chain, _), query_values, target_values in alignments[
+ columns
+ ].itertuples(index=True, name=None):
+ query_chain_pockets = query_pockets.get(query_chain)
+ target_chain_pockets = target_pockets.get(target_chain)
+ if not query_chain_pockets or not target_chain_pockets:
+ continue
+ residue_pairs: abc.Iterable[tuple[int, int]]
+ if compact:
+ if not isinstance(query_values, abc.Iterable) or not isinstance(
+ target_values, abc.Iterable
+ ):
+ continue
+ residue_pairs = zip(query_values, target_values)
+ else:
+ residue_pairs = (
+ (number, target_values.get(position, -1))
+ for position, number in query_values.items()
+ )
+ for query_number, target_number in residue_pairs:
+ query_ids = query_chain_pockets.get(query_number)
+ target_ids = target_chain_pockets.get(target_number)
+ if query_ids and target_ids:
+ pairs.update(
+ (query_id, target_id)
+ for query_id in query_ids
+ for target_id in target_ids
+ )
+ return pairs
+
+ def _pocket_pattern_info(self, ligand: LigandView) -> _PocketPatternInfoType:
+ """Identify equivalent pockets and their copy-specific chain names."""
+ if ligand.id in self._pocket_pattern_info_cache:
+ return self._pocket_pattern_info_cache[ligand.id]
+ pocket, interactions, _, _ = self._ligand_protein_only_pocket_data(ligand)
+ chains = sorted(
+ (
+ json.dumps(
+ (
+ chain.split(".", 1)[-1],
+ sorted(pocket.get(chain, {})),
+ [
+ (number, sorted(counter.items()))
+ for number, counter in sorted(
+ interactions.get(chain, {}).items()
+ )
+ ],
+ ),
+ separators=(",", ":"),
+ ),
+ chain,
+ )
+ for chain in set(pocket) | set(interactions)
+ )
+ aliases = {
+ chain: f"{index}.{chain.split('.', 1)[-1]}"
+ for index, (_, chain) in enumerate(chains)
+ }
+ patterns = [pattern for pattern, _ in chains]
+ info = (
+ json.dumps(patterns, separators=(",", ":")),
+ aliases,
+ len(set(patterns)) == len(patterns),
+ )
+ self._pocket_pattern_info_cache[ligand.id] = info
+ return info
+
+ def _pocket_pattern(self, ligand: LigandView) -> str:
+ return self._pocket_pattern_info(ligand)[0]
+
+ def _cached_ligand_pair_pocket_scores(
+ self,
+ alignments: pd.DataFrame,
+ query_ligand: LigandView,
+ target_ligand: LigandView,
+ target_entry: str,
+ score_cache: _PocketScoreCacheType | None,
+ ) -> _PocketPairResultType:
+ if score_cache is None:
+ return self.get_ligand_pair_pocket_pli_scores(
+ alignments, query_ligand, target_ligand
+ )
+ query_pattern, query_aliases, query_unique = self._pocket_pattern_info(
+ query_ligand
+ )
+ target_pattern, target_aliases, target_unique = self._pocket_pattern_info(
+ target_ligand
+ )
+ if not query_unique or not target_unique:
+ return self.get_ligand_pair_pocket_pli_scores(
+ alignments, query_ligand, target_ligand
+ )
+ key = (target_entry, query_pattern, target_pattern)
+ if key not in score_cache:
+ (
+ pocket_scores,
+ pli_scores,
+ mappings,
+ ) = self.get_ligand_pair_pocket_pli_scores(
+ alignments, query_ligand, target_ligand
+ )
+ if len(score_cache) >= _POCKET_CACHE_MAX_ENTRIES:
+ score_cache.clear()
+ score_cache[key] = (
+ pocket_scores,
+ pli_scores,
+ {
+ metric: [
+ (query_aliases[query_chain], target_aliases[target_chain])
+ for query_chain, target_chain in pairs
+ ]
+ for metric, pairs in mappings.items()
+ },
+ )
+ return pocket_scores, pli_scores, mappings
+ pocket_scores, pli_scores, canonical_mappings = score_cache[key]
+ query_chains = {alias: chain for chain, alias in query_aliases.items()}
+ target_chains = {alias: chain for chain, alias in target_aliases.items()}
+ return (
+ pocket_scores,
+ pli_scores,
+ {
+ metric: [
+ (query_chains[query_chain], target_chains[target_chain])
+ for query_chain, target_chain in pairs
+ ]
+ for metric, pairs in canonical_mappings.items()
+ },
+ )
+
+ def get_scores_holo(
+ self,
+ query_system: SystemView,
+ query_entry_alignments: pd.DataFrame,
+ data_dir: Path | None = None,
+ ligand_3d_candidates: list[_Ligand3DCandidateType] | None = None,
+ ligand_pair_scores: list[_LigandPairScoreType] | None = None,
+ query_ligand_ids: set[str] | None = None,
+ target_system_ids: set[str] | None = None,
+ target_ligand_ids: set[str] | None = None,
+ include_protein_scores: bool = False,
+ pocket_pair_cache: dict[str, dict[str, set[str]]] | None = None,
+ query_pocket_representatives: dict[str, LigandView] | None = None,
+ target_ligand_cache: dict[str, list[LigandView]] | None = None,
+ pocket_score_cache: _PocketScoreCacheType | None = None,
+ target_alignment_cache: dict[str, pd.DataFrame] | None = None,
+ ) -> abc.Generator[dict[str, str | float | None], None, None]:
+ score_started = perf_counter()
+ deferred_rows: list[
+ tuple[
+ dict[str, str | float | None],
+ LigandView,
+ LigandView,
+ float,
+ ]
+ ] = []
+ query_ligands = [
+ ligand
+ for ligand in query_system.ligands.values()
+ if ligand.is_proper
+ and (query_ligand_ids is None or ligand.id in query_ligand_ids)
+ ]
+ if not query_ligands:
+ return
+ query_pocket_patterns = {
+ ligand.id: self._pocket_pattern(ligand) for ligand in query_ligands
+ }
+ if query_pocket_representatives is None:
+ query_pocket_representatives = {
+ self._pocket_pattern(ligand): ligand for ligand in query_ligands
+ }
+ query_instance_chains = sorted(
+ {
+ chain.split(".", 1)[1]
+ for ligand in query_ligands
+ for chain in self.get_protein_receptor_chains(
+ ligand.pdb_id, ligand.protein_chains_asym_id
+ )
+ }
+ )
+ if not query_instance_chains:
+ return
+ for target_entry in query_entry_alignments.index.get_level_values(
+ "target_entry"
+ ).unique():
+ if target_entry not in self.entries:
+ # No data for this target entry
+ continue
+ if target_alignment_cache is None:
+ target_alignment_cache = {}
+ if target_entry not in target_alignment_cache:
+ target_alignment_cache[target_entry] = query_entry_alignments.loc[
+ target_entry
+ ]
+ query_target_entry_alignments = target_alignment_cache[target_entry]
+ query_chain_mapped_values = set(
+ query_target_entry_alignments.index.get_level_values(
+ "query_chain_mapped"
+ )
+ )
+ if all(
+ chain not in query_chain_mapped_values
+ for chain in query_instance_chains
+ ):
+ # No alignments for this query system
+ continue
+ all_target_chains: set[str] = set()
+ for q_chain in query_instance_chains:
+ if q_chain in query_chain_mapped_values:
+ all_target_chains.update(
+ query_target_entry_alignments.loc[
+ q_chain
+ ].index.get_level_values("target_chain_mapped")
+ )
+ pocket_targets_by_query: dict[str, set[str]] | None = None
+ if not include_protein_scores:
+ if target_ligand_cache is None:
+ target_ligand_cache = {}
+ if target_entry not in target_ligand_cache:
+ target_ligand_cache[target_entry] = [
+ ligand
+ for system in self.entries[target_entry].systems.values()
+ if self.system_is_target_scoreable(system)
+ for ligand in system.ligands.values()
+ if ligand.is_proper
+ ]
+ if pocket_pair_cache is None:
+ pocket_pair_cache = {}
+ if target_entry not in pocket_pair_cache:
+ representative_ligands = list(query_pocket_representatives.values())
+ representative_patterns = {
+ ligand.id: pattern
+ for pattern, ligand in query_pocket_representatives.items()
+ }
+ targets_by_pattern: dict[str, set[str]] = defaultdict(set)
+ for query_id, target_id in self._aligned_pocket_pairs(
+ query_target_entry_alignments,
+ representative_ligands,
+ target_ligand_cache[target_entry],
+ ):
+ targets_by_pattern[representative_patterns[query_id]].add(
+ target_id
+ )
+ pocket_pair_cache[target_entry] = targets_by_pattern
+ pocket_targets_by_query = {
+ ligand.id: pocket_pair_cache[target_entry].get(
+ query_pocket_patterns[ligand.id], set()
+ )
+ for ligand in query_ligands
+ }
+ unmatched_pocket_cache: dict[
+ tuple[str, tuple[str, ...]], _PocketPairResultType
+ ] = {}
+ for target_system_id in self.entries[target_entry].systems:
+ target_system = self.entries[target_entry].systems[target_system_id]
+ if not self.system_is_target_scoreable(target_system) or (
+ target_system_ids is not None
+ and target_system_id not in target_system_ids
+ ):
+ continue
+ target_system_protein_chains = self.get_protein_receptor_chains(
+ target_system.pdb_id, target_system.protein_chains_asym_id
+ )
+ if (
+ target_system_id == query_system.id
+ or not target_system_protein_chains
+ or all(
+ target_instance_chain.split(".", maxsplit=1)[-1]
+ not in all_target_chains
+ for target_instance_chain in target_system_protein_chains
+ )
+ ):
+ # Same as query system or No alignments for this target system
+ continue
+ target_ligands = [
+ ligand
+ for ligand in target_system.ligands.values()
+ if ligand.is_proper
+ and (target_ligand_ids is None or ligand.id in target_ligand_ids)
+ ]
+ for query_ligand in query_ligands:
+ # Restrict both workflows to polypeptide receptors. When
+ # protein metrics are requested, this complete chain set
+ # also supplies their directed query denominator.
+ query_protein_chains = self.get_protein_receptor_chains(
+ query_ligand.pdb_id,
+ query_ligand.protein_chains_asym_id,
+ )
+ if not query_protein_chains:
+ continue
+ for target_ligand in target_ligands:
+ target_protein_chains = self.get_protein_receptor_chains(
+ target_ligand.pdb_id,
+ target_ligand.protein_chains_asym_id,
+ )
+ if not target_protein_chains:
+ continue
+ q_t_scores: dict[str, float] = {}
+ q_t_mappings: dict[str, list[_ChainPairType]] = {}
+ protein_chain_mapper = ""
+
+ if include_protein_scores:
+ # Custom workflows may request receptor-level
+ # metrics. Cache their chain assignment across
+ # ligand pairs sharing the same receptors.
+ query_protein_length = self.get_protein_chain_length(
+ query_system.pdb_id, query_protein_chains
+ )
+ protein_cache_key = (
+ query_system.pdb_id,
+ str(target_entry),
+ tuple(query_protein_chains),
+ tuple(target_protein_chains),
+ )
+ if protein_cache_key not in self._protein_score_cache:
+ self._protein_score_cache[protein_cache_key] = (
+ self.get_protein_scores(
+ query_target_entry_alignments,
+ query_system,
+ target_protein_chains,
+ query_protein_length,
+ query_protein_chains=query_protein_chains,
+ )
+ )
+ (
+ q_t_mappings,
+ protein_scores,
+ _protein_alns,
+ protein_chain_mapper,
+ ) = self._protein_score_cache[protein_cache_key]
+ if not protein_scores:
+ continue
+ q_t_scores.update(protein_scores)
+
+ if (
+ pocket_targets_by_query is not None
+ and target_ligand.id
+ not in pocket_targets_by_query[query_ligand.id]
+ ):
+ # With no aligned pocket overlap, coverage and
+ # interaction scores are zero. The remaining
+ # pocket identity depends on the target receptor
+ # chains, so reuse it across ligands there.
+ unmatched_key = (
+ query_ligand.id,
+ tuple(
+ sorted(target_ligand.pocket_residue_number_to_index)
+ ),
+ )
+ if unmatched_key not in unmatched_pocket_cache:
+ unmatched_pocket_cache[unmatched_key] = (
+ self._cached_ligand_pair_pocket_scores(
+ query_target_entry_alignments,
+ query_ligand,
+ target_ligand,
+ str(target_entry),
+ pocket_score_cache,
+ )
+ )
+ (
+ pocket_scores,
+ pli_scores,
+ pocket_mappings,
+ ) = unmatched_pocket_cache[unmatched_key]
+ else:
+ (
+ pocket_scores,
+ pli_scores,
+ pocket_mappings,
+ ) = self._cached_ligand_pair_pocket_scores(
+ query_target_entry_alignments,
+ query_ligand,
+ target_ligand,
+ str(target_entry),
+ pocket_score_cache,
+ )
+ q_t_scores.update(pocket_scores)
+ q_t_scores.update(pli_scores)
+ if not q_t_scores:
+ continue
+ ligand_mappings = {**q_t_mappings, **pocket_mappings}
+ combined: dict[str, str | float | None] = {
+ **combine_scores(
+ q_t_scores, ligand_mappings, protein_chain_mapper
+ )
+ }
+
+ if "pocket_qcov_foldseek" in pocket_scores or (
+ "pocket_qcov_mmseqs" in pocket_scores
+ ):
+ pocket_mapper = "foldseek"
+ if (
+ pocket_scores.get("pocket_qcov_mmseqs", 0.0)
+ > pocket_scores.get("pocket_qcov_foldseek", 0.0) + 1e-12
+ ):
+ pocket_mapper = "mmseqs"
+ pocket_mapping = pocket_mappings.get(
+ f"pocket_qcov_{pocket_mapper}", []
+ )
+ combined["protein_mapping"] = _format_chain_mapping(
+ pocket_mapping
+ )
+ combined["protein_mapper"] = pocket_mapper
+
+ pocket_qcov_value = combined.get("pocket_qcov", 0.0)
+ pocket_qcov = (
+ float(pocket_qcov_value)
+ if isinstance(pocket_qcov_value, (int, float))
+ else 0.0
+ )
+ defer_shape = (
+ data_dir is not None
+ and pocket_qcov > 0
+ and self.shape_score_threads > 1
+ )
+ if data_dir is not None and pocket_qcov > 0 and not defer_shape:
+ combined.update(
+ self.get_ligand_pair_shape_scores(
+ data_dir,
+ query_ligand,
+ target_ligand,
+ pocket_qcov,
+ )
+ )
+ combined.update(
+ {
+ "query_system": query_system.id,
+ "query_ligand_id": query_ligand.id,
+ "target_system": target_system.id,
+ "target_ligand_id": target_ligand.id,
+ }
+ )
+ if ligand_pair_scores is not None:
+ compact_scores: dict[str, int] = {}
+ has_positive_score = False
+ for metric in (
+ "pocket_qcov",
+ "pocket_fident_qcov",
+ "pli_qcov",
+ ):
+ value = combined.get(metric, 0.0)
+ numeric = _finite_float_or_zero(value)
+ if numeric < -1e-12 or numeric > 1.0 + 1e-12:
+ raise ValueError(
+ f"{metric} is outside [0, 1]: {numeric}"
+ )
+ has_positive_score = has_positive_score or numeric > 0
+ compact_scores[metric] = round(
+ min(1.0, max(0.0, numeric)) * 100
+ )
+ if has_positive_score:
+ ligand_pair_scores.append(
+ {
+ "query_system": query_system.id,
+ "query_ligand_id": query_ligand.id,
+ "query_entry": query_ligand.pdb_id,
+ "query_ligand_asym_id": query_ligand.asym_id,
+ "target_system": target_system.id,
+ "target_ligand_id": target_ligand.id,
+ "target_entry": target_ligand.pdb_id,
+ "target_ligand_asym_id": target_ligand.asym_id,
+ **compact_scores,
+ }
+ )
+ if (
+ ligand_3d_candidates is not None
+ and pocket_qcov > 0
+ and query_ligand.is_shape_comparable is not False
+ and target_ligand.is_shape_comparable is not False
+ ):
+ ligand_3d_candidates.append(
+ {
+ "query_system": query_system.id,
+ "query_ligand_id": query_ligand.id,
+ "query_entry": query_ligand.pdb_id,
+ "query_ligand_asym_id": query_ligand.asym_id,
+ "target_system": target_system.id,
+ "target_ligand_id": target_ligand.id,
+ "target_entry": target_ligand.pdb_id,
+ "target_ligand_asym_id": target_ligand.asym_id,
+ "protein_mapping": combined.get("protein_mapping"),
+ "protein_mapper": combined.get("protein_mapper"),
+ "pocket_qcov": pocket_qcov,
+ }
+ )
+ if defer_shape:
+ deferred_rows.append(
+ (
+ combined,
+ query_ligand,
+ target_ligand,
+ pocket_qcov,
+ )
+ )
+ else:
+ yield combined
+
+ if not deferred_rows:
+ return
+ assert data_dir is not None
+ shape_data_dir = data_dir
+
+ canonical_pairs: dict[
+ tuple[tuple[str, str], tuple[str, str]], tuple[LigandView, LigandView]
+ ] = {}
+ canonical_ligands: dict[tuple[str, str], LigandView] = {}
+ canonical_query_ligands: dict[tuple[str, str], LigandView] = {}
+ for _, query_ligand, target_ligand, _ in deferred_rows:
+ query_key = (query_ligand.pdb_id, query_ligand.asym_id)
+ target_key = (target_ligand.pdb_id, target_ligand.asym_id)
+ canonical_pairs.setdefault(
+ (query_key, target_key), (query_ligand, target_ligand)
+ )
+ canonical_query_ligands.setdefault(query_key, query_ligand)
+ canonical_ligands.setdefault(query_key, query_ligand)
+ canonical_ligands.setdefault(target_key, target_ligand)
+
+ core_seconds = perf_counter() - score_started
+
+ def load_ligand(ligand: LigandView) -> Chem.Mol | None:
+ return self._get_ligand_mol(shape_data_dir, ligand)
+
+ def score_pair(pair: tuple[LigandView, LigandView]) -> None:
+ self.get_ligand_pair_shape_scores(shape_data_dir, pair[0], pair[1], 1.0)
+
+ # Preload each canonical molecule once, then calculate each unique
+ # directed pair once. RDKit receives independent molecule clones in
+ # get_ligand_pair_shape_scores(), so comparisons are thread-isolated.
+ preload_started = perf_counter()
+ self._preload_packed_ligand_sdfs(
+ shape_data_dir, list(canonical_ligands.values())
+ )
+ ligands_to_load = [
+ ligand
+ for key, ligand in canonical_ligands.items()
+ if key not in self._ligand_mol_cache
+ ]
+ with ThreadPoolExecutor(max_workers=self.shape_score_threads) as executor:
+ list(executor.map(load_ligand, ligands_to_load))
+ preload_seconds = perf_counter() - preload_started
+ shape_started = perf_counter()
+ # The reference conformer is not modified by ShapeAlign, so detect
+ # its pharmacophore once instead of repeating that work per pair.
+ for key, ligand in canonical_query_ligands.items():
+ if key not in self._ligand_reference_feature_cache:
+ self._get_ligand_reference_features(shape_data_dir, ligand)
+ pairs_to_score = [
+ pair
+ for key, pair in canonical_pairs.items()
+ if key not in self._ligand_shape_score_cache
+ ]
+ list(executor.map(score_pair, pairs_to_score))
+ shape_seconds = perf_counter() - shape_started
+ LOG.info(
+ "ligand scoring profile for %s: rows=%d canonical_pairs=%d new_pairs=%d "
+ "core=%.2fs sdf_preload=%.2fs shape=%.2fs threads=%d",
+ query_system.id,
+ len(deferred_rows),
+ len(canonical_pairs),
+ len(pairs_to_score),
+ core_seconds,
+ preload_seconds,
+ shape_seconds,
+ self.shape_score_threads,
+ )
+
+ for combined, query_ligand, target_ligand, pocket_qcov in deferred_rows:
+ combined.update(
+ self.get_ligand_pair_shape_scores(
+ shape_data_dir, query_ligand, target_ligand, pocket_qcov
+ )
+ )
+ yield combined
+
+ def _get_suffixes(self, s: str) -> list[str]:
+ suffixes = ["_weighted_sum", "_weighted_max", "_max"]
+ if not s.startswith("protein"):
+ suffixes = [""]
+ return suffixes
+
+ def get_column_mapr(self) -> dict[str, list[str]]:
+ mapr = {"info": [x for x in INFO_COLUMNS]}
+ for s in SCORE_NAMES:
+ suffixes = self._get_suffixes(s)
+ for suffix in suffixes:
+ mapr[f"{s}{suffix}"] = [
+ f"{s}{suffix}",
+ f"{s}{suffix}_source",
+ f"{s}{suffix}_mapping",
+ ]
+ return mapr
+
+ def aggregate_scores(
+ self,
+ pdb_id: str,
+ search_db: str = "holo",
+ data_dir: Path | None = None,
+ source_to_aln_file: dict[str, Path] | None = None,
+ query_entry_alignments: pd.DataFrame | None = None,
+ query_system_ids: set[str] | None = None,
+ query_ligand_ids: set[str] | None = None,
+ target_system_ids: set[str] | None = None,
+ target_ligand_ids: set[str] | None = None,
+ ligand_3d_candidates: list[_Ligand3DCandidateType] | None = None,
+ ligand_pair_scores: list[_LigandPairScoreType] | None = None,
+ include_holo_protein_scores: bool = False,
+ ) -> Optional[pd.DataFrame]:
+ if source_to_aln_file is None:
+ source_to_aln_file = {
+ f"{search_db}_{aln_type}": self.db_dir
+ / f"{search_db}_{aln_type}"
+ / "mapped_aln"
+ / f"{pdb_id}.parquet"
+ for aln_type in ["foldseek", "mmseqs"]
+ }
+ if query_entry_alignments is None:
+ target_entry_ids = None
+ if target_system_ids is not None:
+ target_entry_ids = {
+ (
+ system_id.rsplit("_", maxsplit=1)[0]
+ if search_db in {"apo", "pred"}
+ else system_id.split("__", maxsplit=1)[0]
+ )
+ for system_id in target_system_ids
+ }
+ alignments = self.load_alignments(
+ search_db=search_db,
+ source_to_aln_file=source_to_aln_file,
+ query_entry_ids={pdb_id},
+ target_entry_ids=target_entry_ids,
+ )
+ if alignments.empty:
+ return None
+ try:
+ query_entry_alignments = alignments.loc[pdb_id]
+ except KeyError:
+ return None
+ if query_entry_alignments.empty:
+ return None
+ column_mapr = self.get_column_mapr()
+ self._clear_pocket_alignment_cache()
+ pdb_vals = []
+ pocket_pair_cache: dict[str, dict[str, set[str]]] = {}
+ target_alignment_cache: dict[str, pd.DataFrame] = {}
+ target_ligand_cache: dict[str, list[LigandView]] = {}
+ query_pocket_representatives: dict[str, LigandView] = {}
+ query_ligand_count = 0
+ query_systems = [
+ system
+ for system in self.entries[pdb_id].systems.values()
+ if self.system_is_query_scoreable(system)
+ and (query_system_ids is None or system.id in query_system_ids)
+ ]
+ if search_db == "holo" and not include_holo_protein_scores:
+ for system in query_systems:
+ for ligand in system.ligands.values():
+ if not ligand.is_proper or (
+ query_ligand_ids is not None
+ and ligand.id not in query_ligand_ids
+ ):
+ continue
+ query_ligand_count += 1
+ query_pocket_representatives.setdefault(
+ self._pocket_pattern(ligand), ligand
+ )
+ pocket_score_cache: _PocketScoreCacheType | None = (
+ {} if query_ligand_count > len(query_pocket_representatives) else None
+ )
+ if pocket_score_cache is not None:
+ LOG.info(
+ "Scoring %s: %d ligand copies share %d pocket patterns",
+ pdb_id,
+ query_ligand_count,
+ len(query_pocket_representatives),
+ )
+ scoring_started = perf_counter()
+ for system_index, system in enumerate(query_systems, 1):
+ for score_dict in self.get_scores(
+ search_db,
+ system,
+ query_entry_alignments,
+ data_dir=data_dir,
+ ligand_3d_candidates=ligand_3d_candidates,
+ ligand_pair_scores=ligand_pair_scores,
+ query_ligand_ids=query_ligand_ids,
+ target_system_ids=target_system_ids,
+ target_ligand_ids=target_ligand_ids,
+ include_holo_protein_scores=include_holo_protein_scores,
+ pocket_pair_cache=pocket_pair_cache,
+ query_pocket_representatives=query_pocket_representatives,
+ target_ligand_cache=target_ligand_cache,
+ pocket_score_cache=pocket_score_cache,
+ target_alignment_cache=target_alignment_cache,
+ ):
+ # Keep nullable identifiers (notably target_ligand_id for
+ # apo/pred) present so every search database shares a schema.
+ info = {column: score_dict.get(column) for column in INFO_COLUMNS}
+ grouped: dict[str, dict[str, str | float]] = {}
+ # iterate over groups of columns instead of raw list of columns
+ for metric, columns in column_mapr.items():
+ for column in columns:
+ score = score_dict.get(column)
+ if score is None:
+ continue
+ if metric == "info":
+ continue
+ else:
+ grouped.setdefault(metric, {})
+ abbr_column = column.replace(metric, "", 1).lstrip("_")
+ if not abbr_column:
+ abbr_column = "similarity"
+ if np.isnan(score):
+ continue
+ grouped[metric][abbr_column] = score
+ for metric, values in grouped.items():
+ if len(values) and values.get("similarity") is not None:
+ pdb_vals.append({**info, **values, **{"metric": metric}})
+ if len(query_systems) > 10 and system_index % 10 == 0:
+ LOG.info(
+ "Scoring %s: %d/%d systems in %.1fs; %d aligned pockets, %d cached chain-pair results",
+ pdb_id,
+ system_index,
+ len(query_systems),
+ perf_counter() - scoring_started,
+ len(self._aligned_query_pockets),
+ len(self._pocket_chain_matches),
+ )
+ self._clear_pocket_alignment_cache()
+ if not len(pdb_vals):
+ return None
+ df = pd.DataFrame(pdb_vals)
+ all_thresholds = [
+ (m, self.minimum_thresholds.get(m, self.minimum_threshold))
+ for m in df["metric"].unique()
+ ]
+ query = " or ".join(
+ [f"(metric=='{m}' and similarity>={t})" for (m, t) in all_thresholds]
+ )
+ df = df.query(query).copy()
+ df["protein_mapper"] = df["protein_mapper"].astype("category")
+ for col in ["source", "metric"]:
+ # PROTEIN_SIMILARITY_SCHEMA declares these dictionaries ordered.
+ df[col] = df[col].astype(pd.CategoricalDtype(ordered=True))
+ df["similarity"] = (df["similarity"] * 100).apply(round).astype(np.int8)
+ columns = [col for (col, _) in SORT_ORDER]
+ ascending = [direction == "ascending" for (_, direction) in SORT_ORDER]
+ return df.sort_values(by=columns, ascending=ascending)
+
+ def get_scores_apo_pred(
+ self,
+ query_system: SystemView,
+ query_entry_alignments: pd.DataFrame,
+ query_ligand_ids: set[str] | None = None,
+ target_system_ids: set[str] | None = None,
+ ) -> abc.Generator[dict[str, str | float | None], None, None]:
+ query_ligands = [
+ ligand
+ for ligand in query_system.ligands.values()
+ if ligand.is_proper
+ and (query_ligand_ids is None or ligand.id in query_ligand_ids)
+ ]
+ for target_entry in query_entry_alignments.index.get_level_values(
+ "target_entry"
+ ).unique():
+ query_target_entry_alignments = query_entry_alignments.loc[target_entry]
+ query_chain_mapped_values = set(
+ query_target_entry_alignments.index.get_level_values(
+ "query_chain_mapped"
+ )
+ )
+ for query_ligand in query_ligands:
+ query_protein_chains = self.get_protein_receptor_chains(
+ query_ligand.pdb_id,
+ query_ligand.protein_chains_asym_id,
+ )
+ if not query_protein_chains:
+ continue
+ mapped_query_protein_chains = [
+ chain
+ for chain in query_protein_chains
+ if chain.split(".", 1)[1] in query_chain_mapped_values
+ ]
+ if not mapped_query_protein_chains:
+ continue
+ query_protein_length = self.get_protein_chain_length(
+ query_system.pdb_id, query_protein_chains
+ )
+ target_chains: set[str] = set()
+ for query_chain in mapped_query_protein_chains:
+ q_chain = query_chain.split(".", 1)[1]
+ target_chains.update(
+ query_target_entry_alignments.loc[
+ q_chain
+ ].index.get_level_values("target_chain_mapped")
+ )
+ for t_chain in target_chains:
+ target_system_id = f"{target_entry}_{t_chain}"
+ if (
+ target_system_ids is not None
+ and target_system_id not in target_system_ids
+ ):
+ continue
+ q_t_scores: dict[str, float] = {}
+ # Protein score calculation
+ (
+ q_t_mappings,
+ protein_scores,
+ alns,
+ protein_chain_mapper,
+ ) = self.get_protein_scores(
+ query_target_entry_alignments,
+ query_system,
+ [f"0.{t_chain}"],
+ query_protein_length,
+ query_protein_chains=query_protein_chains,
+ )
+
+ if len(alns) == 0 or not len(protein_scores):
+ continue
+ q_t_scores.update(protein_scores)
+ # Pocket score calculation
+ q_t_scores.update(self.get_ligand_pocket_scores(alns, query_ligand))
+ q_t_scores_combined: dict[str, str | float | None] = {
+ **combine_scores(q_t_scores, q_t_mappings, protein_chain_mapper)
+ }
+ q_t_scores_combined["target_system"] = target_system_id
+ q_t_scores_combined["target_ligand_id"] = None
+ q_t_scores_combined["query_system"] = query_system.id
+ q_t_scores_combined["query_ligand_id"] = query_ligand.id
+ yield q_t_scores_combined
diff --git a/src/plinder/data/annotations/interaction_utils.py b/src/plinder/data/annotations/interaction_utils.py
new file mode 100644
index 000000000..3580ead2a
--- /dev/null
+++ b/src/plinder/data/annotations/interaction_utils.py
@@ -0,0 +1,834 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Protein-ligand interaction detection.
+
+Computes interaction fingerprints (hydrogen bonds, salt bridges, pi-stacking,
+pi-cation, halogen bonds) via peppr's ``ContactMeasurement``, plus water- and
+metal-bridged interactions, covalent connections from ``_struct_conn``, and
+crystallographic symmetry-mate contacts.
+"""
+
+from __future__ import annotations
+
+import multiprocessing as mp
+from collections import OrderedDict, defaultdict
+from multiprocessing.connection import Connection
+from pathlib import Path
+from threading import RLock
+from typing import Any, cast
+
+import biotite.structure as struc
+import biotite.structure.io.pdbx as pdbx
+import numpy as np
+import peppr.contacts as peppr_contacts
+from biotite.structure import filter_heavy
+from numpy.typing import NDArray
+from rdkit import Chem
+
+from plinder.core.utils.log import setup_logger
+
+log = setup_logger(__name__)
+
+# PEPPR caches interchangeable tautomers by canonical SMILES inside one
+# ContactMeasurement. Plinder creates one measurement per ligand occurrence,
+# which otherwise repeats the same expensive protein-residue enumeration many
+# times in one ingest worker. Extend the identical cache key across measurements
+# while bounding memory across a multi-entry batch.
+_MAX_TAUTOMER_CACHE_SIZE = 4096
+_TautomerCacheKey = tuple[
+ str,
+ tuple[tuple[int, int, int, int, bool, int | None], ...],
+ tuple[tuple[int, int, float, bool, bool, int], ...],
+]
+_TAUTOMER_CACHE: OrderedDict[_TautomerCacheKey, tuple[Chem.Mol, ...]] = OrderedDict()
+_TAUTOMER_CACHE_LOCK = RLock()
+_ORIGINAL_GET_INTERCHANGEABLE_TAUTOMERS = peppr_contacts.get_interchangeable_tautomers
+_ORIGINAL_FIND_RESONANCE_CHARGES = peppr_contacts.find_resonance_charges
+
+# Normal PEPPR behavior remains unchanged. Only chemically large, charged
+# residues run resonance enumeration in an interruptible child process. This
+# avoids an unkillable RDKit combinatorial tail while preserving the exact
+# result whenever enumeration completes within the generous bound.
+_RESONANCE_GUARD_MIN_ATOMS = 64
+_RESONANCE_TIMEOUT_SECONDS = 10.0
+_MAX_RESONANCE_CACHE_SIZE = 4096
+_ResonanceResult = tuple[
+ NDArray[np.bool_],
+ NDArray[np.bool_],
+ NDArray[np.int_],
+]
+_RESONANCE_CACHE: OrderedDict[_TautomerCacheKey, _ResonanceResult] = OrderedDict()
+_RESONANCE_CACHE_LOCK = RLock()
+
+
+def _tautomer_cache_key(molecule: Chem.Mol) -> _TautomerCacheKey:
+ """Include atom order and PEPPR split-residue state in the cache key."""
+ heavy_neighbors_property = peppr_contacts._ORIG_NUM_HEAVY_NEIGHS
+ atom_signature = tuple(
+ (
+ atom.GetAtomicNum(),
+ atom.GetFormalCharge(),
+ int(atom.GetHybridization()),
+ atom.GetTotalNumHs(),
+ atom.GetIsAromatic(),
+ atom.GetIntProp(heavy_neighbors_property)
+ if atom.HasProp(heavy_neighbors_property)
+ else None,
+ )
+ for atom in molecule.GetAtoms()
+ )
+ bond_signature = tuple(
+ sorted(
+ (
+ min(bond.GetBeginAtomIdx(), bond.GetEndAtomIdx()),
+ max(bond.GetBeginAtomIdx(), bond.GetEndAtomIdx()),
+ bond.GetBondTypeAsDouble(),
+ bond.GetIsAromatic(),
+ bond.GetIsConjugated(),
+ int(bond.GetStereo()),
+ )
+ for bond in molecule.GetBonds()
+ )
+ )
+ return Chem.MolToSmiles(molecule), atom_signature, bond_signature
+
+
+def _cached_get_interchangeable_tautomers(molecule: Chem.Mol) -> list[Chem.Mol]:
+ """Reuse PEPPR tautomer enumeration across ligand contact measurements."""
+ key = _tautomer_cache_key(molecule)
+ with _TAUTOMER_CACHE_LOCK:
+ cached = _TAUTOMER_CACHE.get(key)
+ if cached is not None:
+ _TAUTOMER_CACHE.move_to_end(key)
+ return [Chem.Mol(tautomer) for tautomer in cached]
+
+ generated = tuple(
+ Chem.Mol(tautomer)
+ for tautomer in _ORIGINAL_GET_INTERCHANGEABLE_TAUTOMERS(molecule)
+ )
+ with _TAUTOMER_CACHE_LOCK:
+ _TAUTOMER_CACHE[key] = generated
+ _TAUTOMER_CACHE.move_to_end(key)
+ while len(_TAUTOMER_CACHE) > _MAX_TAUTOMER_CACHE_SIZE:
+ _TAUTOMER_CACHE.popitem(last=False)
+ return [Chem.Mol(tautomer) for tautomer in generated]
+
+
+def _copy_resonance_result(result: _ResonanceResult) -> _ResonanceResult:
+ return result[0].copy(), result[1].copy(), result[2].copy()
+
+
+def _run_resonance_worker(molecule: Chem.Mol, connection: Connection) -> None:
+ """Run PEPPR's exact RDKit resonance enumeration out of process."""
+ try:
+ connection.send(("ok", _ORIGINAL_FIND_RESONANCE_CHARGES(molecule)))
+ except BaseException as exc:
+ connection.send(("error", f"{type(exc).__name__}: {exc}"))
+ finally:
+ connection.close()
+
+
+def _deposited_charge_fallback(molecule: Chem.Mol) -> _ResonanceResult:
+ """Use the estimated deposited formal-charge assignment without resonance."""
+ charges = np.fromiter(
+ (atom.GetFormalCharge() for atom in molecule.GetAtoms()),
+ dtype=int,
+ count=molecule.GetNumAtoms(),
+ )
+ return (
+ charges > 0,
+ charges < 0,
+ np.arange(molecule.GetNumAtoms(), dtype=int),
+ )
+
+
+def _bounded_find_resonance_charges(molecule: Chem.Mol) -> _ResonanceResult:
+ """Preserve exact PEPPR resonance behavior with a rare timeout fallback."""
+ is_large_and_charged = molecule.GetNumAtoms() >= _RESONANCE_GUARD_MIN_ATOMS and any(
+ atom.GetFormalCharge() != 0 for atom in molecule.GetAtoms()
+ )
+ if not is_large_and_charged:
+ result: _ResonanceResult = _ORIGINAL_FIND_RESONANCE_CHARGES(molecule)
+ return result
+
+ key = _tautomer_cache_key(molecule)
+ with _RESONANCE_CACHE_LOCK:
+ cached = _RESONANCE_CACHE.get(key)
+ if cached is not None:
+ _RESONANCE_CACHE.move_to_end(key)
+ return _copy_resonance_result(cached)
+
+ # Data ingest is Linux-only and fork lets the child reuse the already
+ # constructed RDKit molecule without serializing the full contact model.
+ context = mp.get_context("fork")
+ receive, send = context.Pipe(duplex=False)
+ process = context.Process(
+ target=_run_resonance_worker,
+ args=(molecule, send),
+ daemon=True,
+ )
+ process.start()
+ send.close()
+ status = "timeout"
+ payload: Any = None
+ try:
+ if receive.poll(_RESONANCE_TIMEOUT_SECONDS):
+ status, payload = receive.recv()
+ finally:
+ receive.close()
+ if process.is_alive():
+ process.terminate()
+ process.join(timeout=1.0)
+ if process.is_alive():
+ process.kill()
+ process.join()
+
+ if status == "ok":
+ result = cast(_ResonanceResult, payload)
+ elif status == "error":
+ raise struc.BadStructureError(
+ f"PEPPR resonance enumeration failed in worker: {payload}"
+ )
+ else:
+ result = _deposited_charge_fallback(molecule)
+ log.warning(
+ "PEPPR resonance enumeration exceeded %.1fs for a charged "
+ "%d-atom residue; using its estimated deposited formal charges",
+ _RESONANCE_TIMEOUT_SECONDS,
+ molecule.GetNumAtoms(),
+ )
+
+ with _RESONANCE_CACHE_LOCK:
+ _RESONANCE_CACHE[key] = _copy_resonance_result(result)
+ _RESONANCE_CACHE.move_to_end(key)
+ while len(_RESONANCE_CACHE) > _MAX_RESONANCE_CACHE_SIZE:
+ _RESONANCE_CACHE.popitem(last=False)
+ return _copy_resonance_result(result)
+
+
+peppr_contacts.get_interchangeable_tautomers = cast(
+ Any, _cached_get_interchangeable_tautomers
+)
+peppr_contacts.find_resonance_charges = cast(Any, _bounded_find_resonance_charges)
+ContactMeasurement = peppr_contacts.ContactMeasurement
+
+
+def get_symmetry_mate_contacts(
+ mmcif: Path | pdbx.CIFFile, contact_threshold: float = 5.0
+) -> dict[tuple[str, int], dict[tuple[str, int], dict[int, set[int]]]]:
+ """
+ Find inter-residue contacts generated by crystallographic symmetry.
+
+ Only contacts involving symmetry mates (not identity) are returned.
+
+ Parameters
+ ----------
+ mmcif : Path or CIFFile
+ Parsed mmCIF or a path to one (supports .gz). Passing a parsed file
+ avoids reading a large source entry again during ingest.
+ contact_threshold : float, optional
+ Distance cutoff in Angstrom, by default 5.0.
+
+ Returns
+ -------
+ dict[tuple[str, int], dict[tuple[str, int], dict[int, set[int]]]]
+ Mapping of (chain_id, residue_id) to partner residues,
+ with atom serials mapped to the symmetry image indices.
+ """
+ from plinder.data.annotations.cif_utils import (
+ get_structure_with_altloc,
+ get_unit_cell_with_altloc,
+ read_mmcif_file,
+ )
+
+ cif_file = mmcif if isinstance(mmcif, pdbx.CIFFile) else read_mmcif_file(mmcif)
+
+ # Build the full unit cell (all symmetry copies)
+ try:
+ unit_cell = get_unit_cell_with_altloc(
+ cif_file, model=1, use_author_fields=False
+ )
+ except Exception:
+ # No symmetry information (NMR, computational models)
+ return {}
+ unit_cell = unit_cell[~struc.filter_solvent(unit_cell)]
+ unit_cell = unit_cell[filter_heavy(unit_cell)]
+
+ if unit_cell.box is None:
+ return {}
+ box_lengths = np.linalg.norm(unit_cell.box, axis=1)
+ if not np.all(np.isfinite(box_lengths)) or np.any(
+ box_lengths <= 2 * contact_threshold
+ ):
+ # Non-crystallographic entries can carry a placeholder 1 ร box plus
+ # assembly operators (e.g. EM entry 6hbg). A periodic search radius
+ # spanning half a box or more is physically ambiguous and makes the
+ # CellList repeat a huge number of meaningless images.
+ log.warning(
+ "Skipping symmetry-mate contacts for invalid/too-small unit cell %s",
+ box_lengths.tolist(),
+ )
+ return {}
+
+ # Get ASU to determine atoms per symmetry copy
+ asu = get_structure_with_altloc(cif_file, model=1, use_author_fields=False)
+ asu = asu[~struc.filter_solvent(asu)]
+ asu = asu[filter_heavy(asu)]
+ n_asu = len(asu)
+ n_total = len(unit_cell)
+ if n_total == n_asu:
+ return {}
+ n_copies = n_total // n_asu
+
+ # Label each atom with its symmetry image index
+ image_idx = np.repeat(np.arange(n_copies), n_asu)
+
+ # Use periodic CellList to find contacts across unit cell boundaries
+ cell_list = struc.CellList(
+ unit_cell,
+ cell_size=contact_threshold,
+ periodic=True,
+ box=unit_cell.box,
+ )
+
+ results: dict[tuple[str, int], dict[tuple[str, int], dict[int, set[int]]]] = (
+ defaultdict(lambda: defaultdict(lambda: defaultdict(set)))
+ )
+
+ # For each atom in the ASU (image 0), find contacts with symmetry mates
+ for i in range(n_asu):
+ neighbors = cell_list.get_atoms(unit_cell.coord[i], radius=contact_threshold)
+ for j in neighbors:
+ if j == i or image_idx[j] == 0:
+ continue
+ c1 = (
+ unit_cell.label_asym_id[i]
+ if hasattr(unit_cell, "label_asym_id")
+ else unit_cell.chain_id[i]
+ )
+ c2 = (
+ unit_cell.label_asym_id[j]
+ if hasattr(unit_cell, "label_asym_id")
+ else unit_cell.chain_id[j]
+ )
+ r1 = int(unit_cell.res_id[i]) if unit_cell.res_id[i] else 1
+ r2 = int(unit_cell.res_id[j]) if unit_cell.res_id[j] else 1
+ atom_serial = i + 1
+ results[(c1, r1)][(c2, r2)][atom_serial].add(int(image_idx[j]))
+
+ return results
+
+
+def get_covalent_connections(
+ cif_data: pdbx.CIFBlock,
+) -> dict[str, list[tuple[str, str]]]:
+ """
+ Extract covalent connections from CIF block.
+
+ Parameters
+ ----------
+ cif_data : pdbx.CIFBlock
+ biotite CIF block
+
+ Returns
+ -------
+ dict[str, list[tuple[str, str]]]
+ ``conn_type -> [(end1, end2)]``; each end is a
+ :func:`~plinder.data.annotations.cif_utils.residue_address` with atom,
+ ``{auth_seq}:{comp_id}:{asym}:{label_seq}:{atom}``
+ """
+ from plinder.data.annotations.cif_utils import parse_struct_conn, residue_address
+
+ nucleobase_list = {"A", "C", "U", "G", "DA", "DC", "DG", "DT", "PSU"}
+ valid_types = {"covale", "metalc", "hydrog"}
+
+ cov_dict: dict[str, list[tuple[str, str]]] = defaultdict(list)
+ for c in parse_struct_conn(cif_data):
+ if c["conn_type"] not in valid_types:
+ continue
+ if c["conn_type"] == "hydrog":
+ if c["comp1"].strip() not in nucleobase_list:
+ continue
+ link1 = residue_address(
+ c["auth_seq1"], c["comp1"], c["chain1"], c["seq1"], c["atom1"]
+ )
+ link2 = residue_address(
+ c["auth_seq2"], c["comp2"], c["chain2"], c["seq2"], c["atom2"]
+ )
+ cov_dict[c["conn_type"]].append((link1, link2))
+ return cov_dict
+
+
+def extract_ligand_links_to_neighbouring_chains(
+ all_covalent_dict: dict[str, list[tuple[str, str]]],
+ ligand_asym_id: str,
+ neighboring_asym_ids: set[str],
+ link_type: str = "covale",
+) -> set[str]:
+ """
+ Parse covalant dictionary for a given ligand and its neighbours.
+
+ Parameters
+ ----------
+ all_covalent_dict : dict[str, list[tuple[str, str]]]
+ All covalent links as defined by mmcif annotations
+ ligand_asym_id : str
+ ligand asymmetric identification string
+ neighboring_asym_ids : set[str]
+ set of neighbour asymmetric identification strings
+ link_type : str, optional
+ Covalent linkage type in the dictionary. Options include ``"covale"``
+ for a covalent linkage, ``"metalc"`` for a dative bond, and
+ ``"hydrog"`` for a strong hydrogen bond in a nucleic acid. The
+ default is ``"covale"``.
+
+ Returns
+ -------
+ set[str]
+ Links between the ligand and its neighbours as ``receptor_end__ligand_end``
+
+ Notes
+ -----
+ For the purpose of covalent annotations, we only consider "covale".
+ """
+ covalent_linkages = set()
+ if link_type in all_covalent_dict:
+ for link1, link2 in all_covalent_dict[link_type]:
+ chain1, chain2 = link1.split(":")[2], link2.split(":")[2]
+ chains = {chain1, chain2}
+ if len(chains) == 1:
+ # remove linkages that are to the same chain!
+ continue
+ if ligand_asym_id not in chains:
+ # only if the ligand is involved
+ continue
+ # One chain is the ligand, the other a neighbouring (receptor)
+ # chain; emit as receptor__ligand. Match whole asym ids, which can be
+ # multi-character (e.g. "AA") once an entry has more than 26 chains.
+ if chain1 in neighboring_asym_ids and chain2 == ligand_asym_id:
+ covalent_linkages.add(f"{link1}__{link2}")
+ elif chain2 in neighboring_asym_ids and chain1 == ligand_asym_id:
+ covalent_linkages.add(f"{link2}__{link1}")
+ return covalent_linkages
+
+
+# ---------------------------------------------------------------------------
+# Bridged interaction detection
+# TODO: remove once a new peppr is released with these methods.
+# ---------------------------------------------------------------------------
+
+# Water bridge lower bound: 0.75 * VdW_sum (~2.28 A for O-O)
+# avoids clashes but allows short water-mediated H-bonds.
+# Upper bound: 1.15 * VdW_sum (~3.50 A for O-O), standard H-bond max.
+_WATER_BRIDGE_DISTANCE_SCALING = (0.75, 1.15)
+
+# Metals that form coordination bonds (not spectator ions like Na/Cl/K)
+_COORDINATION_METALS = frozenset(
+ {
+ "MG",
+ "CA",
+ "ZN",
+ "FE",
+ "FE2", # Fe(II)
+ "MN",
+ "CO",
+ "CU",
+ "CU1", # Cu(I)
+ "NI",
+ "CD",
+ "MO",
+ "4MO", # Mo(IV)
+ "6MO", # Mo(VI)
+ "W",
+ "V",
+ }
+)
+_METAL_ACCEPTOR_PATTERN = (
+ "["
+ "$([O]),"
+ "$([#7;!$([nX3]);!$([NX3]-*=[!#6]);!$([NX3]-[a]);!$([NX4])]),"
+ "$([#16]),"
+ "$([*;-{1-};!+{1-}])"
+ "]"
+)
+
+
+def _find_bridged_interactions(
+ receptor: "struc.AtomArray",
+ ligand: "struc.AtomArray",
+ bridge_atoms: "struc.AtomArray",
+ receptor_pattern: str,
+ ligand_pattern: str,
+ distance_scaling: tuple[float, float],
+) -> list[tuple[NDArray[np.int_], NDArray[np.int_], NDArray[np.int_]]]:
+ """Find interactions bridged by intermediary atoms (water or metal).
+
+ TODO: remove once peppr has ContactMeasurement.find_bridged_interactions.
+ """
+ import biotite.structure.info as info
+ from peppr.contacts import ContactMeasurement, find_atoms_by_pattern
+
+ if bridge_atoms.array_length() == 0:
+ return []
+
+ try:
+ cm = ContactMeasurement(receptor, ligand)
+ except Exception as e:
+ log.warning(f"ContactMeasurement setup failed: {e}")
+ return []
+
+ receptor_matched = find_atoms_by_pattern(cm._binding_site_mol, receptor_pattern)
+ ligand_matched = find_atoms_by_pattern(cm._ligand_mol, ligand_pattern)
+ if len(receptor_matched) == 0 or len(ligand_matched) == 0:
+ return []
+
+ receptor_coords = cm._binding_site.coord[receptor_matched]
+ ligand_coords = cm._ligand.coord[ligand_matched]
+ lo, hi = sorted(distance_scaling)
+
+ r_vdw = np.array(
+ [info.vdw_radius_single(e) for e in cm._binding_site.element[receptor_matched]]
+ )
+ l_vdw = np.array(
+ [info.vdw_radius_single(e) for e in cm._ligand.element[ligand_matched]]
+ )
+
+ bridges: list[tuple[NDArray[np.int_], NDArray[np.int_], NDArray[np.int_]]] = []
+ for bi in range(bridge_atoms.array_length()):
+ b_coord = bridge_atoms.coord[bi]
+ b_vdw = info.vdw_radius_single(bridge_atoms.element[bi])
+
+ r_dists = np.linalg.norm(receptor_coords - b_coord, axis=1)
+ r_thresholds = r_vdw + b_vdw
+ r_contacts = receptor_matched[
+ (r_dists >= lo * r_thresholds) & (r_dists <= hi * r_thresholds)
+ ]
+ if len(r_contacts) == 0:
+ continue
+
+ l_dists = np.linalg.norm(ligand_coords - b_coord, axis=1)
+ l_thresholds = l_vdw + b_vdw
+ l_contacts = ligand_matched[
+ (l_dists >= lo * l_thresholds) & (l_dists <= hi * l_thresholds)
+ ]
+ if len(l_contacts) == 0:
+ continue
+
+ for ri in r_contacts:
+ for li in l_contacts:
+ bridges.append(
+ (
+ cm._binding_site_indices[ri : ri + 1],
+ np.array([li], dtype=int),
+ np.array([bi], dtype=int),
+ )
+ )
+
+ return bridges
+
+
+def find_water_bridges(
+ receptor: "struc.AtomArray",
+ ligand: "struc.AtomArray",
+ waters: "struc.AtomArray",
+ distance_scaling: tuple[float, float] = _WATER_BRIDGE_DISTANCE_SCALING,
+) -> list[tuple[NDArray[np.int_], NDArray[np.int_], NDArray[np.int_]]]:
+ """Find water-mediated hydrogen bonds between receptor and ligand."""
+ from peppr.common import ACCEPTOR_PATTERN, DONOR_PATTERN
+
+ water_oxygens = waters[waters.element == "O"]
+ hbond_pattern = "[" + DONOR_PATTERN[1:-1] + "," + ACCEPTOR_PATTERN[1:-1] + "]"
+ return _find_bridged_interactions(
+ receptor,
+ ligand,
+ water_oxygens,
+ hbond_pattern,
+ hbond_pattern,
+ distance_scaling,
+ )
+
+
+def find_metal_bridges(
+ receptor: "struc.AtomArray",
+ ligand: "struc.AtomArray",
+ metals: "struc.AtomArray",
+ cutoff: float = 3.0,
+) -> list[tuple[NDArray[np.int_], NDArray[np.int_], NDArray[np.int_]]]:
+ """Find metal-mediated coordination between receptor and ligand."""
+ from peppr.contacts import ContactMeasurement, find_atoms_by_pattern
+
+ coord_mask = np.isin(metals.res_name, list(_COORDINATION_METALS))
+ if not np.any(coord_mask):
+ return []
+ coord_metals = metals[coord_mask]
+
+ try:
+ cm = ContactMeasurement(receptor, ligand)
+ except Exception as e:
+ log.warning(f"ContactMeasurement setup failed for metal bridges: {e}")
+ return []
+
+ receptor_matched = find_atoms_by_pattern(
+ cm._binding_site_mol, _METAL_ACCEPTOR_PATTERN
+ )
+ ligand_matched = find_atoms_by_pattern(cm._ligand_mol, _METAL_ACCEPTOR_PATTERN)
+ if len(receptor_matched) == 0 or len(ligand_matched) == 0:
+ return []
+
+ bridges: list[tuple[NDArray[np.int_], NDArray[np.int_], NDArray[np.int_]]] = []
+ for bi in range(coord_metals.array_length()):
+ b_coord = coord_metals.coord[bi]
+ r_dists = np.linalg.norm(
+ cm._binding_site.coord[receptor_matched] - b_coord, axis=1
+ )
+ r_contacts = receptor_matched[r_dists < cutoff]
+ if len(r_contacts) == 0:
+ continue
+ l_dists = np.linalg.norm(cm._ligand.coord[ligand_matched] - b_coord, axis=1)
+ l_contacts = ligand_matched[l_dists < cutoff]
+ if len(l_contacts) == 0:
+ continue
+ for ri in r_contacts:
+ for li in l_contacts:
+ bridges.append(
+ (
+ cm._binding_site_indices[ri : ri + 1],
+ np.array([li], dtype=int),
+ np.array([bi], dtype=int),
+ )
+ )
+ return bridges
+
+
+# Canonical interaction-type names recorded when a peppr detector fails, so a
+# missing interaction type can be told apart from a genuinely absent one.
+PEPPR_INTERACTION_TYPES = (
+ "hydrogen_bonds",
+ "salt_bridges",
+ "pi_stacks",
+ "pi_cation",
+ "halogen_bonds",
+ "water_bridges",
+ "metal_complexes",
+)
+
+
+def run_peppr_interactions(
+ receptor: struc.AtomArray,
+ ligand: struc.AtomArray,
+ waters: struc.AtomArray,
+ metals: struc.AtomArray,
+ ligand_chain: str,
+) -> tuple[dict[str, dict[int, list[str]]], set[tuple[str, int]], list[str]]:
+ """Compute interaction hash using peppr ContactMeasurement.
+
+ Parameters
+ ----------
+ receptor : AtomArray
+ Receptor heavy atoms.
+ ligand : AtomArray
+ Ligand heavy atoms.
+ waters : AtomArray
+ Water heavy atoms.
+ metals : AtomArray
+ Metal ion heavy atoms (used for metal bridge detection).
+ ligand_chain : str
+ Ligand chain identifier ({instance}.{chain}).
+
+ Returns
+ -------
+ interaction_hashes : dict
+ {instance.chain: {residue_number: [interaction_strings]}}
+ water_set : set
+ {(instance.chain, residue_number)} of bridging waters.
+ failed_interaction_types : list[str]
+ Interaction types (from :data:`PEPPR_INTERACTION_TYPES`) whose peppr
+ detector raised, so an empty result for them means "not computed",
+ not "none found". A failure to build the complex records all types.
+ """
+ interaction_hashes: dict[str, dict[int, list[str]]] = {}
+ water_set: set[tuple[str, int]] = set()
+ failed_interaction_types: list[str] = []
+
+ try:
+ cm = ContactMeasurement(receptor, ligand)
+ except Exception as e:
+ components = sorted({str(name) for name in ligand.res_name})
+ log.warning(
+ "run_peppr_interactions: peppr could not build the ligand %s + "
+ "binding-site complex for contact analysis; skipping its "
+ "interactions. Components: %s. Underlying error: %s",
+ ligand_chain,
+ components,
+ e,
+ )
+ # No detector could run โ every type is unknown, not absent.
+ return interaction_hashes, water_set, list(PEPPR_INTERACTION_TYPES)
+
+ def _add(chain: str, resnr: int, attr: str) -> None:
+ if chain == ligand_chain:
+ return
+ if chain not in interaction_hashes:
+ interaction_hashes[chain] = {}
+ if resnr not in interaction_hashes[chain]:
+ interaction_hashes[chain][resnr] = []
+ interaction_hashes[chain][resnr].append(attr)
+
+ _PROTEIN_MAINCHAIN = {"N", "CA", "C", "O"}
+ _NA_MAINCHAIN = {"P", "O5'", "C5'", "C4'", "C3'", "O3'"}
+ _mainchain_mask = (
+ np.isin(receptor.atom_name, list(_PROTEIN_MAINCHAIN))
+ & struc.filter_amino_acids(receptor)
+ ) | (
+ np.isin(receptor.atom_name, list(_NA_MAINCHAIN))
+ & struc.filter_nucleotides(receptor)
+ )
+
+ def _is_sidechain(atom_idx: int) -> bool:
+ return not _mainchain_mask[atom_idx]
+
+ # H-bonds
+ try:
+ rec_donates, lig_donates = cm.find_hbonds()
+ for ri, _li in rec_donates:
+ c = str(receptor.chain_id[ri])
+ sc = _is_sidechain(ri)
+ _add(
+ c,
+ int(receptor.res_id[ri]),
+ f"type:hydrogen_bonds__protisdon:True__sidechain:{sc}",
+ )
+ for ri, _li in lig_donates:
+ c = str(receptor.chain_id[ri])
+ sc = _is_sidechain(ri)
+ _add(
+ c,
+ int(receptor.res_id[ri]),
+ f"type:hydrogen_bonds__protisdon:False__sidechain:{sc}",
+ )
+ except Exception as e:
+ log.warning(f"run_peppr_interactions: find_hbonds failed: {e}")
+ failed_interaction_types.append("hydrogen_bonds")
+
+ # Salt bridges
+ try:
+ salt_bridges = cm.find_salt_bridges()
+ for ri, _li in salt_bridges:
+ c = str(receptor.chain_id[ri])
+ _add(c, int(receptor.res_id[ri]), "type:salt_bridges__protispos:True")
+ except Exception as e:
+ log.warning(f"run_peppr_interactions: find_salt_bridges failed: {e}")
+ failed_interaction_types.append("salt_bridges")
+
+ # Pi-stacking (deduplicate per residue)
+ try:
+ from biotite.structure import PiStacking
+
+ stacking = cm.find_stacking_interactions()
+ seen_stacking: set[tuple[str, int, str]] = set()
+ for rec_idx, _lig_idx, stack_type in stacking:
+ ri = rec_idx[0]
+ c = str(receptor.chain_id[ri])
+ stype = "T" if stack_type == PiStacking.PERPENDICULAR else "P"
+ key = (c, int(receptor.res_id[ri]), stype)
+ if key not in seen_stacking:
+ seen_stacking.add(key)
+ _add(c, int(receptor.res_id[ri]), f"type:pi_stacks__stack_type:{stype}")
+ except Exception as e:
+ log.warning(f"run_peppr_interactions: find_stacking_interactions failed: {e}")
+ failed_interaction_types.append("pi_stacks")
+
+ # Pi-cation
+ try:
+ pi_cation = cm.find_pi_cation_interactions()
+ for rec_idx, _lig_idx, cation_in_receptor in pi_cation:
+ ri = rec_idx[0]
+ c = str(receptor.chain_id[ri])
+ if cation_in_receptor:
+ _add(
+ c,
+ int(receptor.res_id[ri]),
+ "type:pi_cation__lig_group:Aromatic__protcharged:True",
+ )
+ else:
+ _add(
+ c,
+ int(receptor.res_id[ri]),
+ "type:pi_cation__lig_group:Cation__protcharged:False",
+ )
+ except Exception as e:
+ log.warning(f"run_peppr_interactions: find_pi_cation_interactions failed: {e}")
+ failed_interaction_types.append("pi_cation")
+
+ # Halogen bonds
+ try:
+ from peppr.common import (
+ ACCEPTOR_PATTERN,
+ HALOGEN_DISTANCE_SCALING,
+ HALOGEN_PATTERN,
+ )
+
+ halogen_bonds = cm.find_contacts_by_pattern(
+ ACCEPTOR_PATTERN,
+ HALOGEN_PATTERN,
+ HALOGEN_DISTANCE_SCALING,
+ )
+ for ri, _li in halogen_bonds:
+ c = str(receptor.chain_id[ri])
+ sc = _is_sidechain(ri)
+ _add(c, int(receptor.res_id[ri]), f"type:halogen_bonds__sidechain:{sc}")
+ except Exception as e:
+ log.warning(f"run_peppr_interactions: halogen_bonds failed: {e}")
+ failed_interaction_types.append("halogen_bonds")
+
+ # Water bridges (via plinder patch โ peppr public doesn't have this yet)
+ try:
+ if waters.array_length() > 0:
+ from peppr.common import DONOR_PATTERN
+ from peppr.contacts import find_atoms_by_pattern
+
+ receptor_donors = set(
+ find_atoms_by_pattern(cm._binding_site_mol, DONOR_PATTERN)
+ )
+ w_bridges = find_water_bridges(receptor, ligand, waters)
+ for rec_idx, _lig_idx, water_idx in w_bridges:
+ ri = rec_idx[0]
+ wi = water_idx[0]
+ # Check if receptor atom is a donor
+ bs_idx = None
+ for j, orig_idx in enumerate(cm._binding_site_indices):
+ if orig_idx == ri:
+ bs_idx = j
+ break
+ protisdon = bs_idx in receptor_donors if bs_idx is not None else True
+ c = str(receptor.chain_id[ri])
+ _add(
+ c,
+ int(receptor.res_id[ri]),
+ f"type:water_bridges__protisdon:{protisdon}",
+ )
+ w_chain = str(waters.chain_id[wi])
+ water_set.add((w_chain, int(waters.res_id[wi])))
+ except Exception as e:
+ log.warning(f"run_peppr_interactions: find_water_bridges failed: {e}")
+ failed_interaction_types.append("water_bridges")
+
+ # Metal bridges (via plinder patch โ peppr public doesn't have this yet)
+ try:
+ if metals.array_length() > 0:
+ m_bridges = find_metal_bridges(receptor, ligand, metals)
+ for rec_idx, _lig_idx, metal_idx in m_bridges:
+ ri = rec_idx[0]
+ mi = metal_idx[0]
+ c = str(receptor.chain_id[ri])
+ metal_elem = metals.element[mi]
+ _add(
+ c,
+ int(receptor.res_id[ri]),
+ f"type:metal_complexes__metal_type:{metal_elem}",
+ )
+ except Exception as e:
+ log.warning(f"run_peppr_interactions: find_metal_bridges failed: {e}")
+ failed_interaction_types.append("metal_complexes")
+
+ return interaction_hashes, water_set, failed_interaction_types
diff --git a/src/plinder/data/annotations/interface_utils.py b/src/plinder/data/annotations/interface_utils.py
new file mode 100644
index 000000000..c558fdcd9
--- /dev/null
+++ b/src/plinder/data/annotations/interface_utils.py
@@ -0,0 +1,581 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Protein-interface detection in deposited biological assemblies."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+from functools import cache
+from pathlib import Path
+from typing import TYPE_CHECKING, Iterable, Mapping
+
+import biotite.structure as struc
+import numpy as np
+import pyarrow as pa
+
+if TYPE_CHECKING:
+ from plinder.data.annotations.ligand_utils import BiounitSpatialIndex
+ from plinder.data.annotations.protein_utils import Chain
+
+PROTEIN_BACKBONE_ATOMS = frozenset({"N", "CA", "C", "O"})
+DEFAULT_MIN_INTERFACE_RESIDUES = 7
+MIN_INTERFACE_RESIDUES_METADATA_KEY = b"plinder.interface.min_interface_residues"
+PRODIGY_CONTACT_RADIUS = 5.0
+ProteinChainContacts = dict[tuple[str, str], set[tuple[int, int]]]
+PRODIGY_FEATURE_NAMES = (
+ "CP",
+ "AC",
+ "AP",
+ "AA",
+ "ALA",
+ "CYS",
+ "GLU",
+ "ASP",
+ "GLY",
+ "PHE",
+ "ILE",
+ "HIS",
+ "MET",
+ "LEU",
+ "GLN",
+ "PRO",
+ "SER",
+ "ARG",
+ "THR",
+ "VAL",
+ "TYR",
+ "link_density",
+)
+PRODIGY_AMINO_ACID_CLASSES = {
+ "ALA": "A",
+ "CYS": "A",
+ "GLU": "C",
+ "ASP": "C",
+ "GLY": "A",
+ "PHE": "A",
+ "ILE": "A",
+ "HIS": "C",
+ "LYS": "C",
+ "MET": "A",
+ "LEU": "A",
+ "ASN": "P",
+ "GLN": "P",
+ "PRO": "A",
+ "SER": "P",
+ "ARG": "C",
+ "THR": "P",
+ "TRP": "A",
+ "VAL": "A",
+ "TYR": "A",
+}
+# The model and feature ordering are pinned to official PRODIGY-cryst:
+# https://github.com/haddocking/prodigy-cryst/tree/29d99d535cae3014608c9394b8809619a60fcfa2
+# Its legacy scikit-learn pickle is represented as numeric arrays so the same
+# trees can be evaluated on every Python version supported by Plinder.
+_PRODIGY_MODEL_PATH = Path(__file__).parent / "static_files" / "prodigy_classifier.npz"
+
+INTERFACE_ANNOTATION_SCHEMA = pa.schema(
+ [
+ ("entry_pdb_id", pa.string()),
+ ("system_id", pa.string()),
+ ("system_biounit_id", pa.string()),
+ ("interface_chain_1", pa.string()),
+ ("interface_chain_2", pa.string()),
+ ("interface_chain_1_residue_numbers", pa.list_(pa.int32())),
+ ("interface_chain_1_residue_indices", pa.list_(pa.int32())),
+ ("interface_chain_2_residue_numbers", pa.list_(pa.int32())),
+ ("interface_chain_2_residue_indices", pa.list_(pa.int32())),
+ ("interface_num_contact_residue_pairs", pa.int64()),
+ ("interface_contact_area", pa.float64()),
+ ("prodigy_is_annotated", pa.bool_()),
+ ("prodigy_label", pa.string()),
+ ("prodigy_probability_bio", pa.float32()),
+ ("prodigy_link_density", pa.float32()),
+ ("prodigy_intermolecular_contacts", pa.int32()),
+ ("prodigy_charged_charged_contacts", pa.int32()),
+ ("prodigy_charged_polar_contacts", pa.int32()),
+ ("prodigy_charged_apolar_contacts", pa.int32()),
+ ("prodigy_polar_polar_contacts", pa.int32()),
+ ("prodigy_apolar_polar_contacts", pa.int32()),
+ ("prodigy_apolar_apolar_contacts", pa.int32()),
+ ]
+)
+
+
+@dataclass(frozen=True)
+class ProdigyCrystalAnnotation:
+ """PRODIGY-cryst contact features and BIO/XTAL prediction."""
+
+ label: str
+ probability_bio: float
+ link_density: float
+ intermolecular_contacts: int
+ charged_charged_contacts: int
+ charged_polar_contacts: int
+ charged_apolar_contacts: int
+ polar_polar_contacts: int
+ apolar_polar_contacts: int
+ apolar_apolar_contacts: int
+
+
+def interface_system_id(
+ pdb_id: str,
+ biounit_id: str,
+ chain_1: str,
+ chain_2: str,
+) -> str:
+ """Return the system ID for an unordered assembly-chain pair."""
+ if chain_1 == chain_2:
+ raise ValueError("an interface requires two distinct chain instances")
+ first, second = sorted((str(chain_1), str(chain_2)))
+ return f"{pdb_id.lower()}__{biounit_id}__{first}--{second}"
+
+
+@dataclass(frozen=True)
+class ProteinInterface:
+ """One unordered protein-chain interface in one biological assembly."""
+
+ pdb_id: str
+ biounit_id: str
+ chain_1: str
+ chain_2: str
+ chain_1_residue_numbers: tuple[int, ...]
+ chain_1_residue_indices: tuple[int, ...]
+ chain_2_residue_numbers: tuple[int, ...]
+ chain_2_residue_indices: tuple[int, ...]
+ num_contact_residue_pairs: int
+ prodigy: ProdigyCrystalAnnotation | None = None
+ # Voronota-LT contact area (ร ยฒ) between the two chains in the full
+ # assembly; None when the assembly tessellation was skipped or failed.
+ contact_area: float | None = None
+
+ def __post_init__(self) -> None:
+ if self.chain_1 >= self.chain_2:
+ raise ValueError("interface chains must use canonical sorted ordering")
+ if len(self.chain_1_residue_numbers) != len(self.chain_1_residue_indices):
+ raise ValueError("chain 1 interface residue mappings have unequal lengths")
+ if len(self.chain_2_residue_numbers) != len(self.chain_2_residue_indices):
+ raise ValueError("chain 2 interface residue mappings have unequal lengths")
+ if self.num_contact_residue_pairs < 1:
+ raise ValueError("an interface must contain at least one residue contact")
+
+ @property
+ def system_id(self) -> str:
+ return interface_system_id(
+ self.pdb_id,
+ self.biounit_id,
+ self.chain_1,
+ self.chain_2,
+ )
+
+ def to_row(self) -> dict[str, object]:
+ """Return one Arrow-compatible annotation row."""
+ row: dict[str, object] = {
+ "entry_pdb_id": self.pdb_id,
+ "system_id": self.system_id,
+ "system_biounit_id": self.biounit_id,
+ "interface_chain_1": self.chain_1,
+ "interface_chain_2": self.chain_2,
+ "interface_chain_1_residue_numbers": list(self.chain_1_residue_numbers),
+ "interface_chain_1_residue_indices": list(self.chain_1_residue_indices),
+ "interface_chain_2_residue_numbers": list(self.chain_2_residue_numbers),
+ "interface_chain_2_residue_indices": list(self.chain_2_residue_indices),
+ "interface_num_contact_residue_pairs": self.num_contact_residue_pairs,
+ "interface_contact_area": self.contact_area,
+ "prodigy_is_annotated": self.prodigy is not None,
+ }
+ prodigy_fields = {
+ "prodigy_label": "label",
+ "prodigy_probability_bio": "probability_bio",
+ "prodigy_link_density": "link_density",
+ "prodigy_intermolecular_contacts": "intermolecular_contacts",
+ "prodigy_charged_charged_contacts": "charged_charged_contacts",
+ "prodigy_charged_polar_contacts": "charged_polar_contacts",
+ "prodigy_charged_apolar_contacts": "charged_apolar_contacts",
+ "prodigy_polar_polar_contacts": "polar_polar_contacts",
+ "prodigy_apolar_polar_contacts": "apolar_polar_contacts",
+ "prodigy_apolar_apolar_contacts": "apolar_apolar_contacts",
+ }
+ row.update(
+ {
+ column: (
+ getattr(self.prodigy, attribute)
+ if self.prodigy is not None
+ else None
+ )
+ for column, attribute in prodigy_fields.items()
+ }
+ )
+ return row
+
+
+@cache
+def _load_prodigy_classifier() -> dict[str, np.ndarray]:
+ """Load the official PRODIGY-cryst random forest once per process."""
+ if not _PRODIGY_MODEL_PATH.is_file():
+ raise FileNotFoundError(
+ f"missing packaged PRODIGY-cryst classifier: {_PRODIGY_MODEL_PATH}"
+ )
+ with np.load(_PRODIGY_MODEL_PATH, allow_pickle=False) as model:
+ arrays = {name: model[name] for name in model.files}
+ if tuple(str(value) for value in arrays["feature_names"]) != PRODIGY_FEATURE_NAMES:
+ raise ValueError("packaged PRODIGY-cryst classifier has incompatible features")
+ if tuple(str(value) for value in arrays["classes"]) != ("BIO", "XTAL"):
+ raise ValueError("packaged PRODIGY-cryst classifier has incompatible classes")
+ return arrays
+
+
+def _predict_prodigy_probability(features: np.ndarray) -> tuple[str, float]:
+ """Evaluate the exact trees from official PRODIGY-cryst."""
+ model = _load_prodigy_classifier()
+ offsets = model["tree_offsets"]
+ left = model["children_left"]
+ right = model["children_right"]
+ node_features = model["feature"]
+ thresholds = model["threshold"]
+ leaf_probabilities = model["probability"]
+ probabilities = np.zeros(2, dtype=np.float64)
+ for tree_index in range(len(offsets) - 1):
+ node = int(offsets[tree_index])
+ while left[node] >= 0:
+ if features[node_features[node]] <= thresholds[node]:
+ node = int(left[node])
+ else:
+ node = int(right[node])
+ probabilities += leaf_probabilities[node]
+ probabilities /= len(offsets) - 1
+ return ("BIO" if probabilities[0] >= probabilities[1] else "XTAL"), float(
+ probabilities[0]
+ )
+
+
+def annotate_prodigy_crystal_interface(
+ atoms: struc.AtomArray,
+ *,
+ chain_1: str,
+ chain_2: str,
+ spatial_index: BiounitSpatialIndex,
+) -> ProdigyCrystalAnnotation | None:
+ """Classify one chain interface using official PRODIGY-cryst.
+
+ Its contact definitions, feature ordering and fixed random forest are
+ preserved. Biotite supplies the already reconstructed biological
+ assembly, and NumPy evaluates the legacy scikit-learn trees.
+ Interfaces containing unsupported modified residues remain in the dataset
+ with null PRODIGY fields.
+ """
+ chain_1_mask = atoms.chain_id == chain_1
+ chain_2_mask = atoms.chain_id == chain_2
+ if not np.any(chain_1_mask) or not np.any(chain_2_mask):
+ raise ValueError(
+ f"interface chains are absent from assembly: {chain_1}, {chain_2}"
+ )
+ chain_2_atom_mask = np.asarray(chain_2_mask, dtype=bool)
+ contact_pairs: set[tuple[tuple[int, str], tuple[int, str]]] = set()
+ chain_1_indices = np.flatnonzero(chain_1_mask)
+ for atom_index in chain_1_indices:
+ neighbors = np.asarray(
+ spatial_index.cell_list.get_atoms(
+ atoms.coord[atom_index], radius=PRODIGY_CONTACT_RADIUS
+ ),
+ dtype=int,
+ ).reshape(-1)
+ neighbors = neighbors[(neighbors >= 0) & (neighbors < len(atoms))]
+ neighbors = neighbors[chain_2_atom_mask[neighbors]]
+ residue_1 = (int(atoms.res_id[atom_index]), str(atoms.ins_code[atom_index]))
+ for target_index in neighbors:
+ residue_2 = (
+ int(atoms.res_id[target_index]),
+ str(atoms.ins_code[target_index]),
+ )
+ contact_pairs.add((residue_1, residue_2))
+ if not contact_pairs:
+ return None
+
+ residue_name_1 = {
+ (int(atoms.res_id[index]), str(atoms.ins_code[index])): str(
+ atoms.res_name[index]
+ )
+ for index in np.flatnonzero(chain_1_mask)
+ }
+ residue_name_2 = {
+ (int(atoms.res_id[index]), str(atoms.ins_code[index])): str(
+ atoms.res_name[index]
+ )
+ for index in np.flatnonzero(chain_2_mask)
+ }
+ contacted_residue_names = {
+ residue_name_1[residue_1] for residue_1, _ in contact_pairs
+ } | {residue_name_2[residue_2] for _, residue_2 in contact_pairs}
+ if not contacted_residue_names.issubset(PRODIGY_AMINO_ACID_CLASSES):
+ return None
+ bins = {name: 0 for name in ("AA", "PP", "CC", "AP", "CP", "AC")}
+ bins.update({name: 0 for name in PRODIGY_AMINO_ACID_CLASSES})
+ for residue_1, residue_2 in contact_pairs:
+ name_1 = residue_name_1[residue_1]
+ name_2 = residue_name_2[residue_2]
+ contact_type = "".join(
+ sorted(
+ (
+ PRODIGY_AMINO_ACID_CLASSES[name_1],
+ PRODIGY_AMINO_ACID_CLASSES[name_2],
+ )
+ )
+ )
+ bins[contact_type] += 1
+ bins[name_1] += 1
+ bins[name_2] += 1
+ contacted_1 = {pair[0] for pair in contact_pairs}
+ contacted_2 = {pair[1] for pair in contact_pairs}
+ link_density = len(contact_pairs) / (len(contacted_1) * len(contacted_2))
+ features = np.asarray(
+ [float(bins[name]) for name in PRODIGY_FEATURE_NAMES[:-1]] + [link_density],
+ dtype=np.float64,
+ )
+ label, probability_bio = _predict_prodigy_probability(features)
+ return ProdigyCrystalAnnotation(
+ label=label,
+ probability_bio=probability_bio,
+ link_density=link_density,
+ intermolecular_contacts=len(contact_pairs),
+ charged_charged_contacts=bins["CC"],
+ charged_polar_contacts=bins["CP"],
+ charged_apolar_contacts=bins["AC"],
+ polar_polar_contacts=bins["PP"],
+ apolar_polar_contacts=bins["AP"],
+ apolar_apolar_contacts=bins["AA"],
+ )
+
+
+def _asym_id(instance_chain: str) -> str:
+ """Extract a label asym ID from a ``copy.asym`` assembly-chain ID."""
+ try:
+ _, asym_id = instance_chain.split(".", maxsplit=1)
+ except ValueError as exc:
+ raise ValueError(
+ f"biological-assembly chain has no copy prefix: {instance_chain!r}"
+ ) from exc
+ return asym_id
+
+
+def _residue_mappings(
+ *,
+ instance_chain: str,
+ residue_numbers: Iterable[int],
+ chains: Mapping[str, Chain],
+) -> tuple[tuple[int, ...], tuple[int, ...]]:
+ """Map resolved label sequence numbers to zero-based structure indices."""
+ asym_id = _asym_id(instance_chain)
+ chain = chains[asym_id]
+ numbers = tuple(sorted(set(int(value) for value in residue_numbers)))
+ try:
+ indices = tuple(int(chain.residues[number].index) for number in numbers)
+ except KeyError as exc:
+ raise ValueError(
+ f"assembly interface residue is absent from ASU chain {asym_id}: "
+ f"{exc.args[0]}"
+ ) from exc
+ return numbers, indices
+
+
+def find_protein_chain_contacts(
+ atoms: struc.AtomArray,
+ *,
+ chains: Mapping[str, Chain],
+ contact_radius: float,
+ spatial_index: BiounitSpatialIndex,
+) -> ProteinChainContacts:
+ """Return residue contacts between every pair of polypeptide chains."""
+ if contact_radius <= 0:
+ raise ValueError("protein contact radius must be positive")
+ if spatial_index.max_radius < contact_radius:
+ raise ValueError(
+ "protein contact radius exceeds the biological-assembly index radius"
+ )
+ protein_chains = {
+ instance_chain
+ for instance_chain in spatial_index.chain_ids
+ if (chain := chains.get(_asym_id(instance_chain))) is not None
+ and "polypeptide" in chain.chain_type_str.lower()
+ }
+ if len(protein_chains) < 2:
+ return {}
+
+ protein_backbone = np.fromiter(
+ (
+ str(instance_chain) in protein_chains
+ and str(atom_name) in PROTEIN_BACKBONE_ATOMS
+ for instance_chain, atom_name in zip(atoms.chain_id, atoms.atom_name)
+ ),
+ dtype=bool,
+ count=len(atoms),
+ )
+ contacts: ProteinChainContacts = {}
+ for atom_index in np.flatnonzero(protein_backbone):
+ neighbors = np.asarray(
+ spatial_index.cell_list.get_atoms(
+ atoms.coord[atom_index], radius=contact_radius
+ ),
+ dtype=int,
+ ).reshape(-1)
+ neighbors = neighbors[(neighbors > atom_index) & (neighbors < len(atoms))]
+ neighbors = neighbors[protein_backbone[neighbors]]
+ query_chain = str(atoms.chain_id[atom_index])
+ query_residue = int(atoms.res_id[atom_index])
+ for target_index in neighbors:
+ target_chain = str(atoms.chain_id[target_index])
+ if target_chain == query_chain:
+ continue
+ target_residue = int(atoms.res_id[target_index])
+ if query_chain < target_chain:
+ key = (query_chain, target_chain)
+ residue_pair = (query_residue, target_residue)
+ else:
+ key = (target_chain, query_chain)
+ residue_pair = (target_residue, query_residue)
+ contacts.setdefault(key, set()).add(residue_pair)
+ return contacts
+
+
+def detect_protein_interfaces(
+ atoms: struc.AtomArray,
+ *,
+ pdb_id: str,
+ biounit_id: str,
+ chains: Mapping[str, Chain],
+ contact_radius: float = 10.0,
+ min_chain_length: int = 12,
+ min_interface_residues: int = DEFAULT_MIN_INTERFACE_RESIDUES,
+ annotate_prodigy: bool = True,
+ spatial_index: BiounitSpatialIndex | None = None,
+ chain_pair_contact_areas: Mapping[tuple[str, str], float] | None = None,
+ chain_contacts: ProteinChainContacts | None = None,
+) -> list[ProteinInterface]:
+ """Detect protein-chain interfaces from backbone contacts.
+
+ Every eligible polypeptide chain has a SEQRES length of at least
+ ``min_chain_length``. A residue belongs to an interface when one of its
+ ``N``, ``CA``, ``C`` or ``O`` atoms lies within ``contact_radius`` of a
+ backbone atom in another eligible assembly-chain instance. Interfaces
+ are retained only when both sides contain at least
+ ``min_interface_residues`` resolved residues.
+
+ ``chain_pair_contact_areas`` are the assembly-wide Voronota-LT areas keyed
+ by sorted chain pair; when given, each interface records its pair's area
+ (0.0 for backbone-defined interfaces without atomic contact), otherwise
+ ``contact_area`` stays ``None``.
+ """
+ if contact_radius <= 0:
+ raise ValueError("interface contact radius must be positive")
+ if min_chain_length < 1 or min_interface_residues < 1:
+ raise ValueError("interface chain and residue limits must be positive")
+ if spatial_index is None:
+ from plinder.data.annotations.ligand_utils import BiounitSpatialIndex
+
+ spatial_index = BiounitSpatialIndex.from_atoms(atoms, contact_radius)
+ elif spatial_index.max_radius < contact_radius:
+ raise ValueError(
+ "interface contact radius exceeds the biological-assembly index radius"
+ )
+
+ eligible_chains = {
+ instance_chain
+ for instance_chain in spatial_index.chain_ids
+ if (chain := chains.get(_asym_id(instance_chain))) is not None
+ and "polypeptide" in chain.chain_type_str.lower()
+ and chain.length >= min_chain_length
+ }
+ if len(eligible_chains) < 2:
+ return []
+
+ contacts = (
+ find_protein_chain_contacts(
+ atoms,
+ chains=chains,
+ contact_radius=contact_radius,
+ spatial_index=spatial_index,
+ )
+ if chain_contacts is None
+ else chain_contacts
+ )
+
+ interfaces: list[ProteinInterface] = []
+ for (chain_1, chain_2), residue_pairs in sorted(contacts.items()):
+ if chain_1 not in eligible_chains or chain_2 not in eligible_chains:
+ continue
+ chain_1_numbers, chain_1_indices = _residue_mappings(
+ instance_chain=chain_1,
+ residue_numbers=(pair[0] for pair in residue_pairs),
+ chains=chains,
+ )
+ chain_2_numbers, chain_2_indices = _residue_mappings(
+ instance_chain=chain_2,
+ residue_numbers=(pair[1] for pair in residue_pairs),
+ chains=chains,
+ )
+ if (
+ len(chain_1_numbers) < min_interface_residues
+ or len(chain_2_numbers) < min_interface_residues
+ ):
+ continue
+ interfaces.append(
+ ProteinInterface(
+ pdb_id=pdb_id.lower(),
+ biounit_id=str(biounit_id),
+ chain_1=chain_1,
+ chain_2=chain_2,
+ chain_1_residue_numbers=chain_1_numbers,
+ chain_1_residue_indices=chain_1_indices,
+ chain_2_residue_numbers=chain_2_numbers,
+ chain_2_residue_indices=chain_2_indices,
+ num_contact_residue_pairs=len(residue_pairs),
+ contact_area=(
+ None
+ if chain_pair_contact_areas is None
+ else float(chain_pair_contact_areas.get((chain_1, chain_2), 0.0))
+ ),
+ prodigy=(
+ annotate_prodigy_crystal_interface(
+ atoms,
+ chain_1=chain_1,
+ chain_2=chain_2,
+ spatial_index=spatial_index,
+ )
+ if annotate_prodigy
+ else None
+ ),
+ )
+ )
+ return interfaces
+
+
+def protein_interfaces_to_table(
+ interfaces: Iterable[ProteinInterface],
+ *,
+ min_interface_residues: int = DEFAULT_MIN_INTERFACE_RESIDUES,
+) -> pa.Table:
+ """Return a typed table with the ingest threshold in schema metadata."""
+ if min_interface_residues < 1:
+ raise ValueError("minimum interface residues must be positive")
+ schema = INTERFACE_ANNOTATION_SCHEMA.with_metadata(
+ {MIN_INTERFACE_RESIDUES_METADATA_KEY: str(min_interface_residues).encode()}
+ )
+ return pa.Table.from_pylist(
+ [interface.to_row() for interface in interfaces],
+ schema=schema,
+ )
+
+
+def min_interface_residues_from_schema(schema: pa.Schema) -> int:
+ """Read the interface threshold recorded on an interface table."""
+ metadata = schema.metadata or {}
+ value = metadata.get(MIN_INTERFACE_RESIDUES_METADATA_KEY)
+ if value is None:
+ raise ValueError("interface table does not record its minimum residue count")
+ try:
+ threshold = int(value)
+ except (TypeError, ValueError) as exc:
+ raise ValueError("invalid minimum interface residue metadata") from exc
+ if threshold < 1:
+ raise ValueError("minimum interface residues must be positive")
+ return threshold
diff --git a/src/plinder/data/annotations/ligand_utils.py b/src/plinder/data/annotations/ligand_utils.py
new file mode 100644
index 000000000..dbf33cca9
--- /dev/null
+++ b/src/plinder/data/annotations/ligand_utils.py
@@ -0,0 +1,2501 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from __future__ import annotations
+
+import logging
+import typing as ty
+from collections import Counter, defaultdict
+from dataclasses import dataclass
+from functools import cache, cached_property
+from pathlib import Path
+
+import biotite.structure as struc
+import numpy as np
+import numpy.typing as npt
+from pydantic import BeforeValidator, Field
+from rdkit import Chem, RDLogger
+from rdkit.Chem import QED, Crippen, rdMolDescriptors
+from rdkit.Chem.rdchem import Mol
+
+from plinder.core.utils.config import get_config
+from plinder.core.utils.constants import BASE_DIR
+from plinder.core.utils.sanitize import mol_from_smiles
+from plinder.data.annotations.affinity import matched_affinity
+from plinder.data.annotations.contact_areas import partner_contact_areas
+from plinder.data.annotations.interaction_utils import (
+ extract_ligand_links_to_neighbouring_chains,
+ run_peppr_interactions,
+)
+from plinder.data.annotations.protein_utils import (
+ Chain,
+ UnobservedAtom,
+)
+from plinder.data.annotations.utils import (
+ DocBaseModel,
+ description_excluded_from_flat_export,
+)
+
+LOG = logging.getLogger(__name__)
+
+
+@dataclass
+class BiounitSpatialIndex:
+ """Reusable spatial and hierarchy index for one biological assembly."""
+
+ cell_list: struc.CellList
+ residue_starts: npt.NDArray[np.int_]
+ chain_segments: dict[str, list[tuple[int, int]]]
+ max_radius: float
+ bond_neighbors: npt.NDArray[np.integer[ty.Any]] | None
+ bond_types: npt.NDArray[np.integer[ty.Any]] | None
+
+ @classmethod
+ def from_atoms(
+ cls,
+ atoms: struc.AtomArray,
+ max_radius: float,
+ ) -> "BiounitSpatialIndex":
+ """Build the expensive whole-assembly indexes exactly once."""
+ if max_radius <= 0:
+ raise ValueError("max_radius must be positive")
+ chain_starts = struc.get_chain_starts(atoms, add_exclusive_stop=True)
+ chain_segments: dict[str, list[tuple[int, int]]] = defaultdict(list)
+ for start, stop in zip(chain_starts[:-1], chain_starts[1:]):
+ chain_segments[str(atoms.chain_id[start])].append((int(start), int(stop)))
+ if atoms.bonds is None:
+ bond_neighbors = None
+ bond_types = None
+ else:
+ bond_neighbors, bond_types = atoms.bonds.get_all_bonds()
+ return cls(
+ cell_list=struc.CellList(atoms, max_radius),
+ residue_starts=ty.cast(
+ npt.NDArray[np.int_],
+ struc.get_residue_starts(atoms, add_exclusive_stop=True),
+ ),
+ chain_segments=dict(chain_segments),
+ max_radius=max_radius,
+ bond_neighbors=bond_neighbors,
+ bond_types=bond_types,
+ )
+
+ @property
+ def chain_ids(self) -> list[str]:
+ """Return chain IDs in their original assembly order."""
+ return list(self.chain_segments)
+
+ def atom_indices_for_chain(self, chain_id: str) -> npt.NDArray[np.int_]:
+ """Return sorted atom indices for a possibly segmented chain."""
+ segments = self.chain_segments.get(chain_id, [])
+ if not segments:
+ return np.array([], dtype=int)
+ return ty.cast(
+ npt.NDArray[np.int_],
+ np.concatenate(
+ [np.arange(start, stop, dtype=int) for start, stop in segments]
+ ),
+ )
+
+ def atom_indices_near(
+ self,
+ coordinates: npt.NDArray[np.floating[ty.Any]],
+ radius: float,
+ ) -> npt.NDArray[np.int_]:
+ """Return sorted unique atom indices within *radius* of coordinates."""
+ if radius > self.max_radius:
+ raise ValueError(
+ f"query radius {radius} exceeds indexed radius {self.max_radius}"
+ )
+ nearby: list[npt.NDArray[np.int_]] = []
+ for coordinate in coordinates:
+ indices = ty.cast(
+ npt.NDArray[np.int_],
+ self.cell_list.get_atoms(coordinate, radius=radius),
+ )
+ valid = indices[indices >= 0]
+ if valid.size:
+ nearby.append(valid)
+ if not nearby:
+ return np.array([], dtype=int)
+ return ty.cast(npt.NDArray[np.int_], np.unique(np.concatenate(nearby)))
+
+ def complete_residue_indices_near(
+ self,
+ coordinates: npt.NDArray[np.floating[ty.Any]],
+ radius: float,
+ ) -> npt.NDArray[np.int_]:
+ """Expand nearby atom hits to their complete residues."""
+ nearby = self.atom_indices_near(coordinates, radius)
+ if nearby.size == 0:
+ return nearby
+ residue_indices = np.unique(
+ np.searchsorted(self.residue_starts, nearby, side="right") - 1
+ )
+ return ty.cast(
+ npt.NDArray[np.int_],
+ np.concatenate(
+ [
+ np.arange(
+ self.residue_starts[index],
+ self.residue_starts[index + 1],
+ dtype=int,
+ )
+ for index in residue_indices
+ ]
+ ),
+ )
+
+ def take_atoms(
+ self,
+ atoms: struc.AtomArray,
+ indices: npt.NDArray[np.int_],
+ *,
+ include_bonds: bool,
+ ) -> struc.AtomArray:
+ """Take a subarray without globally reindexing every bond.
+
+ ``AtomArray.__getitem__`` delegates to ``BondList.__getitem__``, which
+ scans the full assembly bond graph even when only a few local atoms are
+ requested. Rebuilding the selected adjacency from ``get_bonds()`` is
+ equivalent and scales with the local slice instead.
+ """
+ subset = struc.AtomArray(len(indices))
+ subset.coord = atoms.coord[indices]
+ for category in atoms.get_annotation_categories():
+ subset.set_annotation(category, atoms.get_annotation(category)[indices])
+ if atoms.box is not None:
+ subset.box = atoms.box.copy()
+ if (
+ include_bonds
+ and self.bond_neighbors is not None
+ and self.bond_types is not None
+ ):
+ selected = {
+ int(global_index): local_index
+ for local_index, global_index in enumerate(indices)
+ }
+ bonds = struc.BondList(len(indices))
+ for local_index, global_index in enumerate(indices):
+ neighbors = self.bond_neighbors[global_index]
+ bond_types = self.bond_types[global_index]
+ for neighbor, bond_type in zip(neighbors, bond_types):
+ if neighbor < 0:
+ continue
+ other_local_index = selected.get(int(neighbor))
+ if (
+ other_local_index is not None
+ and local_index < other_local_index
+ ):
+ bonds.add_bond(
+ local_index,
+ other_local_index,
+ int(bond_type),
+ )
+ subset.bonds = bonds
+ return subset
+
+
+def get_water_chain_ids(atoms: struc.AtomArray) -> set[str]:
+ """Return chain IDs whose atoms are all classified as solvent.
+
+ Computing the solvent mask once avoids repeatedly slicing a potentially
+ large biological assembly for every ligand in that assembly.
+ """
+ solvent_mask = struc.filter_solvent(atoms)
+ solvent_chains = set(str(chain_id) for chain_id in atoms.chain_id[solvent_mask])
+ non_solvent_chains = set(
+ str(chain_id) for chain_id in atoms.chain_id[~solvent_mask]
+ )
+ return solvent_chains - non_solvent_chains
+
+
+def _template_from_user_smiles(
+ comp_id: str,
+ smiles: str,
+ cif_atom_names: list[str],
+) -> "Chem.Mol | None":
+ """Build a stereo-assigned template Mol from a user-supplied SMILES.
+
+ Used as a CCD fallback when a custom residue (e.g. Boltz ``LIG``) is
+ not in the Chemical Component Dictionary. Assumes the SMILES
+ heavy-atom parse order matches the CIF heavy-atom order โ the same
+ positional convention used by :func:`assign_bond_orders_from_smiles`.
+
+ Stereo is assigned from SMILES parity tags (``@``/``@@``) directly,
+ no 3D embed needed. PDB atom names from the CIF are stamped onto the
+ template atoms so :func:`compare_stereo_to_template` can match by name.
+
+ Returns ``None`` if the SMILES can't be parsed or the heavy-atom
+ count disagrees with the CIF (the caller then falls back to ``None``
+ for stereo_matches, matching pre-existing behaviour).
+ """
+ # Tolerant parse (over-valent boron/main-group centres), consistent with the
+ # rest of the ligand-SMILES pipeline; None (unparseable) falls back to no
+ # stereo check, as before. mol_from_smiles perceives stereo (atom @/@@ and
+ # double-bond E/Z), which compare_stereo_to_template reads.
+ mol = mol_from_smiles(smiles)
+ if mol is None:
+ return None
+ mol = Chem.RemoveHs(mol, sanitize=False)
+ if mol.GetNumAtoms() != len(cif_atom_names):
+ LOG.warning(
+ f"_template_from_user_smiles: atom count mismatch for {comp_id} "
+ f"({mol.GetNumAtoms()} in SMILES vs {len(cif_atom_names)} in CIF) โ "
+ "skipping SMILES-based stereo check"
+ )
+ return None
+ # Stereo comes from the SMILES parity tags (@/@@ and /\), which the parse
+ # records on the atoms/bonds and RemoveHs(sanitize=False) preserves;
+ # compare_stereo_to_template reads them to check chiral handedness and E/Z.
+ for atom, atom_name in zip(mol.GetAtoms(), cif_atom_names):
+ info = Chem.AtomPDBResidueInfo()
+ info.SetName(atom_name)
+ info.SetResidueName(comp_id)
+ info.SetResidueNumber(1)
+ atom.SetMonomerInfo(info)
+ return mol
+
+
+def _check_stereo_vs_template(
+ resolved_mol: "Chem.Mol",
+ custom_templates: dict[str, "Chem.Mol"] | None = None,
+ ccd_code_dict: dict[str, str] | None = None,
+) -> bool | None:
+ """Compare resolved 3D stereo against a stereo template per residue.
+
+ Template source precedence:
+ 1. ``custom_templates[resname]`` if provided โ user-supplied SMILES
+ templates win over CCD because the caller explicitly knows CCD
+ is wrong or missing (biotite ships a generic placeholder for
+ some codes like ``LIG`` that would otherwise silently hide
+ stereo mismatches).
+ 2. A mapped CCD template from ``ccd_code_dict``, with its CCD atoms
+ graph-matched and renamed to the custom CIF atom names.
+ 3. :func:`_get_ccd_mol(resname)` โ CCD ideal coordinates.
+ 4. Return ``None`` for this residue if neither source yields a
+ template.
+
+ Delegates to :func:`compare_stereo_to_template` for the actual
+ handedness comparison. Handles multi-residue ligands (e.g. glycans) by
+ checking each residue copy independently.
+
+ Returns ``True`` if all residues match or are achiral, ``False`` if
+ any stereo mismatch, ``None`` if no template was available for any
+ residue.
+ """
+ from plinder.core.structure.smallmols_utils import compare_stereo_to_template
+
+ # Group atoms by (resname, res_id) to handle repeated residue names
+ residue_atoms: dict[tuple[str, int], list[int]] = {}
+ for atom in resolved_mol.GetAtoms():
+ info = atom.GetPDBResidueInfo()
+ if info is None:
+ raise ValueError(
+ f"Atom {atom.GetIdx()} in resolved mol has no PDB residue info"
+ )
+ key = (info.GetResidueName().strip(), info.GetResidueNumber())
+ residue_atoms.setdefault(key, []).append(atom.GetIdx())
+
+ results: list[bool | None] = []
+ for (resname, res_id), atom_indices in residue_atoms.items():
+ frag = Chem.RWMol(resolved_mol)
+ remove = [
+ a.GetIdx()
+ for a in resolved_mol.GetAtoms()
+ if a.GetIdx() not in atom_indices
+ ]
+ frag.BeginBatchEdit()
+ for idx in sorted(remove, reverse=True):
+ frag.RemoveAtom(idx)
+ frag.CommitBatchEdit()
+ fragment_mol = frag.GetMol()
+
+ # User-supplied custom templates take precedence over CCD: if
+ # the caller provided a SMILES template for this residue, they
+ # explicitly know CCD is wrong or missing (biotite ships a
+ # generic placeholder for some codes like "LIG" that would
+ # otherwise hide stereo mismatches).
+ template_mol = None
+ if custom_templates is not None:
+ template_mol = custom_templates.get(resname)
+ if template_mol is None:
+ reference_code = (ccd_code_dict or {}).get(resname, resname)
+ template_mol = _get_ccd_mol(reference_code)
+ if template_mol is not None and reference_code != resname:
+ template_mol = _template_with_fragment_atom_names(
+ template_mol,
+ fragment_mol,
+ custom_comp_id=resname,
+ reference_code=reference_code,
+ )
+ if template_mol is None:
+ results.append(None)
+ continue
+
+ try:
+ results.append(compare_stereo_to_template(fragment_mol, template_mol))
+ except Exception as e:
+ LOG.warning(f"Stereo comparison failed for {resname}:{res_id}: {e}")
+ results.append(None)
+
+ if not results:
+ return None
+ if any(r is False for r in results):
+ return False
+ if any(r is True for r in results):
+ return True
+ return None
+
+
+def _template_with_fragment_atom_names(
+ template_mol: "Chem.Mol",
+ fragment_mol: "Chem.Mol",
+ *,
+ custom_comp_id: str,
+ reference_code: str,
+) -> "Chem.Mol | None":
+ """Rename a mapped CCD template using its graph match to a CIF residue."""
+ if template_mol.GetNumAtoms() != fragment_mol.GetNumAtoms():
+ LOG.warning(
+ "Mapped CCD stereo template atom count differs for %s -> %s",
+ custom_comp_id,
+ reference_code,
+ )
+ return None
+ match = fragment_mol.GetSubstructMatch(template_mol, useChirality=False)
+ if len(match) != template_mol.GetNumAtoms():
+ LOG.warning(
+ "Mapped CCD stereo template cannot be graph-matched for %s -> %s",
+ custom_comp_id,
+ reference_code,
+ )
+ return None
+ mapped = Chem.Mol(template_mol)
+ for template_atom, fragment_index in zip(mapped.GetAtoms(), match):
+ fragment_info = fragment_mol.GetAtomWithIdx(fragment_index).GetPDBResidueInfo()
+ if fragment_info is None:
+ return None
+ info = Chem.AtomPDBResidueInfo()
+ info.SetName(fragment_info.GetName())
+ info.SetResidueName(custom_comp_id)
+ info.SetResidueNumber(1)
+ template_atom.SetMonomerInfo(info)
+ return mapped
+
+
+@cache
+def _get_ccd_mol(comp_id: str) -> "Chem.Mol | None":
+ """Return a sanitized RDKit Mol for a CCD component, or None if absent.
+
+ Thin, None-safe wrapper over ``cif_utils._get_ccd_atomarray``. biotite has no
+ stereo tags, so ``atoms_to_rdkit_mol`` perceives stereo (R/S and E/Z) from the
+ ideal 3D coordinates via ``AssignStereochemistryFrom3D``.
+ """
+ from plinder.data.annotations.cif_utils import (
+ _get_ccd_atomarray,
+ atoms_to_rdkit_mol,
+ )
+
+ atoms = _get_ccd_atomarray(comp_id)
+ if atoms is None:
+ return None
+ try:
+ return atoms_to_rdkit_mol(atoms)
+ except Exception as e:
+ LOG.warning(f"Failed to build RDKit mol for {comp_id}: {e}")
+ return None
+
+
+def _get_ccd_smiles(comp_id: str) -> str | None:
+ """Get SMILES from a CCD component, with stereochemistry from ideal 3D."""
+ mol = _get_ccd_mol(comp_id)
+ if mol is None:
+ return None
+ return str(Chem.MolToSmiles(mol))
+
+
+CcdComponents = tuple[str, ...]
+
+
+def ccd_components(ccd_code: str | None) -> CcdComponents:
+ """A code's components, sorted, so list membership ignores traversal order."""
+ return tuple(sorted((ccd_code or "").split("-")))
+
+
+def lig_has_dummies(
+ ligand_code: str,
+ dummy_lig_list: list[str] = [
+ # "DUM", # OBS -> UNX (already listed below)
+ "UNX",
+ "ASX",
+ "GLX",
+ "UNL",
+ "UNK",
+ "UPL",
+ "DN",
+ "N",
+ ],
+) -> bool:
+ """Check for ccd codes containing dummy/unknown entries
+
+ Args:
+ ligand_code str: ligand CCD code
+ dummy_lig_list (list, optional): list of ccd codes for unknown or dummy entries.
+ Defaults to ['UNX', 'UNL', 'UNK', 'UPL', 'DN', 'N'].
+
+ Returns:
+ bool: if ligand considered as dummy and treated as artifact
+ """
+ # check for dummy list including composites, too!
+ return len(set(ligand_code.split("-")).intersection(dummy_lig_list)) > 0
+
+
+# lazy evaluate data fetches referenced as module globals
+COFACTORS: set[CcdComponents] | None = None
+# RDKit canonical SMILES of the cofactor / artifact reference molecules. Matching
+# on structure (not CCD code) classifies a ligand that is the same molecule under
+# a *different current* code โ the real "synonym" case. No "obsolete" codes.
+COFACTOR_SMILES: set[str] | None = None
+ARTIFACT_SMILES: set[str] | None = None
+# instantiate artifact list once and reuse variable
+ARTIFACTS: set[CcdComponents] | None = None
+BINDING_AFFINITY: dict[str, ty.Any] | None = None
+
+
+_OLIGO_SMARTS = {
+ "peptide": Chem.MolFromSmarts("C(=O)C[N;D2,D3]C(=[O;D1])CN"),
+ "saccharide": Chem.MolFromSmarts("O-[C;R0,R1]-[C;R0,R1]-[O,S;R0;D2]-[C;R1]-[O;R1]"),
+ "nucleotide": Chem.MolFromSmarts("P(=O)([O-,OH])(OC[C;r5])O[C;r5]"),
+}
+_POLYMER_CLASS_FIELDS = tuple(
+ f"is_{size}{family}"
+ for family in ("saccharide", "nucleotide", "peptide")
+ for size in ("mono", "oligo")
+)
+
+
+def _has_nucleobase_attachment(mol: Mol, ring: set[int]) -> bool:
+ """Return whether a sugar-ring carbon is bonded to a ring nitrogen."""
+ for atom_index in ring:
+ atom = mol.GetAtomWithIdx(atom_index)
+ if atom.GetAtomicNum() != 6:
+ continue
+ for neighbor in atom.GetNeighbors():
+ if (
+ neighbor.GetIdx() not in ring
+ and neighbor.GetAtomicNum() == 7
+ and neighbor.IsInRing()
+ ):
+ return True
+ return False
+
+
+def _sugar_and_nucleotide_unit_counts(mol: Mol) -> tuple[int, int]:
+ """Count conservative sugar and phosphorylated nucleoside ring motifs."""
+ saccharide_units = 0
+ nucleotide_units = 0
+ phosphorus = [atom.GetIdx() for atom in mol.GetAtoms() if atom.GetAtomicNum() == 15]
+ for atom_ring in mol.GetRingInfo().AtomRings():
+ if len(atom_ring) not in {5, 6}:
+ continue
+ ring = set(atom_ring)
+ atoms = [mol.GetAtomWithIdx(index) for index in atom_ring]
+ atomic_numbers = [atom.GetAtomicNum() for atom in atoms]
+ if any(atom.GetIsAromatic() for atom in atoms):
+ continue
+ if atomic_numbers.count(8) != 1 or atomic_numbers.count(6) != len(atoms) - 1:
+ continue
+
+ has_nucleobase = _has_nucleobase_attachment(mol, ring)
+ close_to_phosphate = any(
+ len(Chem.GetShortestPath(mol, ring_index, phosphorus_index)) - 1 <= 3
+ for ring_index in ring
+ for phosphorus_index in phosphorus
+ )
+ if has_nucleobase and close_to_phosphate:
+ nucleotide_units += 1
+ continue
+ if has_nucleobase:
+ # A nucleoside sugar is not a saccharide ligand class.
+ continue
+
+ external_oxygen_neighbors = {
+ neighbor.GetIdx()
+ for atom_index in ring
+ for neighbor in mol.GetAtomWithIdx(atom_index).GetNeighbors()
+ if neighbor.GetIdx() not in ring and neighbor.GetAtomicNum() == 8
+ }
+ if len(external_oxygen_neighbors) >= 2:
+ saccharide_units += 1
+ return saccharide_units, nucleotide_units
+
+
+def _peptide_unit_count(mol: Mol) -> int:
+ """Count alpha-amino-acid backbone centers in a molecule."""
+ units = 0
+ for atom in mol.GetAtoms():
+ if (
+ atom.GetAtomicNum() != 6
+ or atom.GetHybridization() != Chem.HybridizationType.SP3
+ ):
+ continue
+ neighbors = list(atom.GetNeighbors())
+ if not any(neighbor.GetAtomicNum() == 7 for neighbor in neighbors):
+ continue
+ has_carbonyl = False
+ for neighbor in neighbors:
+ if neighbor.GetAtomicNum() != 6:
+ continue
+ for bond in neighbor.GetBonds():
+ other = bond.GetOtherAtom(neighbor)
+ if (
+ other.GetAtomicNum() == 8
+ and bond.GetBondType() == Chem.BondType.DOUBLE
+ ):
+ has_carbonyl = True
+ break
+ if has_carbonyl:
+ break
+ units += int(has_carbonyl)
+ return units
+
+
+@cache
+def _smiles_descriptors(smiles: str | None) -> dict[str, ty.Any] | None:
+ """Cached RDKit scalar descriptors for one canonical SMILES.
+
+ Descriptors are a pure function of the SMILES, so they are memoized here
+ (keyed on the string) instead of recomputed per ligand instance in
+ ``set_rdkit``. Parsing goes through :func:`~plinder.core.utils.sanitize.mol_from_smiles` so
+ over-valent ligands still yield descriptors rather than a silent ``None``.
+ """
+ mol = mol_from_smiles(smiles)
+ if mol is None:
+ return None
+ descriptors: dict[str, ty.Any] = {
+ "molecular_weight": rdMolDescriptors.CalcExactMolWt(mol),
+ "num_rot_bonds": rdMolDescriptors.CalcNumRotatableBonds(mol),
+ "num_hba": rdMolDescriptors.CalcNumHBA(mol),
+ "num_hbd": rdMolDescriptors.CalcNumHBD(mol),
+ "crippen_clogp": Crippen.MolLogP(mol),
+ "num_rings": rdMolDescriptors.CalcNumRings(mol),
+ "num_heavy_atoms": rdMolDescriptors.CalcNumHeavyAtoms(mol),
+ "tpsa": rdMolDescriptors.CalcTPSA(mol),
+ }
+ # QED internally re-runs RemoveHs/sanitization, which rejects the over-valent
+ # main-group centres (boron cages, hypervalent metals) that peppr.sanitize
+ # tolerates. Keep the other descriptors and leave qed unset in that case.
+ try:
+ descriptors["qed"] = QED.qed(mol)
+ except Exception:
+ descriptors["qed"] = None
+ return descriptors
+
+
+@cache
+def _classify_ligand_polymer_classes(
+ smiles: str,
+ sum_disconnected_units: bool = False,
+) -> tuple[bool, ...]:
+ """Return cached class flags for one SMILES representation.
+
+ Disconnected fragments are normally treated as a mixture, so two copies
+ of a monomer do not become an oligomer. The caller may sum their units
+ when separate residue records are known to belong to one multi-residue
+ Parsing goes through :func:`~plinder.core.utils.sanitize.mol_from_smiles` so
+ over-valent ligands are still classified rather than silently skipped.
+ ligand whose inter-residue bonds were absent from the deposited CIF.
+ """
+ mol = mol_from_smiles(smiles) if smiles else None
+ unit_counts = {"saccharide": 0, "nucleotide": 0, "peptide": 0}
+ oligo_matches = {family: False for family in unit_counts}
+ if mol is not None:
+ for fragment in Chem.GetMolFrags(mol, asMols=True):
+ saccharide_units, nucleotide_units = _sugar_and_nucleotide_unit_counts(
+ fragment
+ )
+ peptide_units = _peptide_unit_count(fragment)
+ if sum_disconnected_units:
+ unit_counts["saccharide"] += saccharide_units
+ unit_counts["nucleotide"] += nucleotide_units
+ unit_counts["peptide"] += peptide_units
+ else:
+ unit_counts["saccharide"] = max(
+ unit_counts["saccharide"], saccharide_units
+ )
+ unit_counts["nucleotide"] = max(
+ unit_counts["nucleotide"], nucleotide_units
+ )
+ unit_counts["peptide"] = max(unit_counts["peptide"], peptide_units)
+ for family, pattern in _OLIGO_SMARTS.items():
+ if pattern is not None:
+ oligo_matches[family] = mol.HasSubstructMatch(pattern)
+
+ result: list[bool] = []
+ for family in ("saccharide", "nucleotide", "peptide"):
+ is_oligo = oligo_matches[family] or unit_counts[family] >= 2
+ result.extend((unit_counts[family] == 1 and not is_oligo, is_oligo))
+ return tuple(result)
+
+
+def classify_ligand_polymer_classes(
+ smiles: str | None,
+ *,
+ resolved_smiles: str | None = None,
+ is_multi_residue: bool = False,
+) -> dict[str, bool]:
+ """Classify mono/oligo saccharide, nucleotide, and peptide ligands.
+
+ Existing oligo SMARTS are retained. Conservative structural unit counts
+ distinguish one unit from multiple units. Resolved coordinates may add
+ evidence that the canonical identity omitted; disconnected resolved units
+ are summed only for a ligand already known to span multiple residues.
+ """
+ flags = dict(
+ zip(
+ _POLYMER_CLASS_FIELDS,
+ _classify_ligand_polymer_classes(smiles or ""),
+ )
+ )
+ if not resolved_smiles:
+ return flags
+
+ resolved_flags = dict(
+ zip(
+ _POLYMER_CLASS_FIELDS,
+ _classify_ligand_polymer_classes(
+ resolved_smiles,
+ sum_disconnected_units=is_multi_residue,
+ ),
+ )
+ )
+ for family in ("saccharide", "nucleotide", "peptide"):
+ mono_field = f"is_mono{family}"
+ oligo_field = f"is_oligo{family}"
+ is_oligo = flags[oligo_field] or resolved_flags[oligo_field]
+ flags[oligo_field] = is_oligo
+ flags[mono_field] = not is_oligo and (
+ flags[mono_field] or resolved_flags[mono_field]
+ )
+ return flags
+
+
+def _choose_ligand_smiles_by_heavy_atom_count(
+ reference_smiles: str | None,
+ resolved_smiles: str | None,
+) -> str:
+ """Choose the chemically useful identity, then the more complete one.
+
+ A connected coordinate-derived molecule wins over disconnected
+ per-component CCD templates because only it encodes observed
+ inter-residue bonds. Otherwise, choose the representation containing more
+ heavy atoms and prefer the resolved representation on a tie.
+ """
+
+ def valid_candidate(smiles: str | None) -> tuple[str, int, int] | None:
+ if not smiles:
+ return None
+ mol = mol_from_smiles(smiles)
+ if mol is None:
+ return None
+ return smiles, int(mol.GetNumHeavyAtoms()), len(Chem.GetMolFrags(mol))
+
+ reference = valid_candidate(reference_smiles)
+ resolved = valid_candidate(resolved_smiles)
+ if reference is None:
+ return resolved[0] if resolved is not None else (reference_smiles or "")
+ if resolved is None:
+ return reference[0]
+ if resolved[2] == 1 and reference[2] > 1:
+ return resolved[0]
+ return reference[0] if reference[1] > resolved[1] else resolved[0]
+
+
+def get_artifact_codes(data_dir: Path) -> set[CcdComponents]:
+ """Load the artifact CCD set needed for cheap ingest preflight."""
+ global ARTIFACTS, ARTIFACT_SMILES
+
+ artifacts = ARTIFACTS
+ if artifacts is None:
+ artifacts = parse_artifacts()
+ ARTIFACTS = artifacts
+ ARTIFACT_SMILES = _reference_smiles(artifacts)
+ return artifacts
+
+
+def _reference_smiles(codes: set[CcdComponents]) -> set[str]:
+ """RDKit canonical SMILES for a set of CCD codes (skipping unresolved ones).
+
+ Classifying cofactors / artifacts by this SMILES set (in addition to the CCD
+ code) catches a ligand that is the *same molecule* under a different current
+ CCD code โ the real "synonym" case. Uses :func:`_get_ccd_smiles` (derived from
+ the CCD atoms), so it needs no external descriptor column, and the
+ strings are directly comparable to a ligand's own ``self.smiles``.
+ """
+ smiles: set[str] = set()
+ for code in codes:
+ smi = _get_ccd_smiles("-".join(code))
+ if smi:
+ smiles.add(smi)
+ return smiles
+
+
+def _ligand_unresolved_atoms(
+ biounit: "struc.AtomArray",
+ heavy_indices: "npt.NDArray[np.int_]",
+ member_asym_ids: set[str],
+ unobserved_atoms: ty.Mapping[str, list[UnobservedAtom]] | None,
+ ccd_code_dict: dict[str, str] | None,
+ polymer_asym_ids: ty.Collection[str],
+) -> list[str] | None:
+ """Missing heavy atoms as ``residue_address`` with atom,
+ ``{auth_seq}:{comp_id}:{asym}:{label_seq}:{atom}``.
+
+ Every ligand residue is diffed against its CCD template by atom name; model
+ atoms the template does not define are logged. Leaving atoms of polymer
+ residues never count (linkage is implied by the sequence, as in the wwPDB
+ records); for other residues they count unless the residue is bonded outside
+ itself through their anchor (glycosidic or protein link) in the biounit. The
+ wwPDB unobserved-atom records, when the entry has them, provide the list and
+ their truly absent rows are checked against the template diff (zero-occupancy
+ atoms have coordinates); ``None`` when no template covers the ligand and
+ there are no records.
+ """
+ from plinder.core.structure.ccd_template import (
+ ccd_component_template,
+ departed_leaving_atoms,
+ )
+ from plinder.data.annotations.cif_utils import residue_address
+
+ categories = biounit.get_annotation_categories()
+ has_auth = "auth_seq_id" in categories
+ residues: dict[tuple[str, int, str], dict[str, ty.Any]] = {}
+ for index in heavy_indices:
+ index = int(index)
+ key = (
+ str(biounit.chain_id[index]),
+ int(biounit.res_id[index]),
+ str(biounit.res_name[index]),
+ )
+ info = residues.setdefault(key, {"indices": [], "names": [], "linked": set()})
+ info["indices"].append(index)
+ info["names"].append(str(biounit.atom_name[index]))
+ template_entries: list[str] = []
+ by_author: dict[tuple[str, str], dict[str, ty.Any]] = {}
+ covered = True
+ for (chain_id, res_id, res_name), info in residues.items():
+ first = info["indices"][0]
+ auth_seq = str(biounit.auth_seq_id[first]) if has_auth else str(res_id)
+ if biounit.ins_code[first]:
+ auth_seq = f"{auth_seq}{biounit.ins_code[first]}"
+ asym_id = chain_id.split(".", maxsplit=1)[-1] # asym ids may hold dots
+ label_seq: str | int = res_id if asym_id in polymer_asym_ids else "."
+ own = set(info["indices"])
+ for index in info["indices"] if biounit.bonds is not None else []:
+ partners, _ = biounit.bonds.get_bonds(index)
+ if any(int(partner) not in own for partner in partners):
+ info["linked"].add(str(biounit.atom_name[index]))
+ reference = (ccd_code_dict or {}).get(res_name, res_name)
+ template = ccd_component_template(reference)
+ info["template"] = template
+ by_author.setdefault((asym_id, auth_seq), info)
+ if template is None:
+ covered = False
+ continue
+ unknown = [name for name in info["names"] if name not in template.elements]
+ if unknown:
+ LOG.warning(
+ f"{chain_id}:{res_name}:{res_id}: atoms {unknown} are not in CCD "
+ f"template {reference}"
+ )
+ excluded = (
+ template.leaving
+ if asym_id in polymer_asym_ids or biounit.bonds is None
+ else departed_leaving_atoms(template, info["linked"])
+ )
+ template_entries.extend(
+ residue_address(auth_seq, res_name, asym_id, label_seq, name)
+ for name in template.heavy
+ if name not in excluded and name not in info["names"]
+ )
+ if unobserved_atoms is None:
+ return template_entries if covered else None
+ record_entries: list[str] = []
+ absent: set[str] = set()
+ for asym_id in sorted(member_asym_ids):
+ for row in unobserved_atoms.get(asym_id, []):
+ known = by_author.get((asym_id, row.auth_seq))
+ template = (
+ known["template"] if known else ccd_component_template(row.comp_id)
+ )
+ if template is not None:
+ if template.elements.get(row.atom_name) in {"H", "D"}:
+ continue
+ excluded = (
+ template.leaving
+ if asym_id in polymer_asym_ids
+ or known is None
+ or biounit.bonds is None
+ else departed_leaving_atoms(template, known["linked"])
+ )
+ if row.atom_name in excluded:
+ continue
+ entry = residue_address(
+ row.auth_seq, row.comp_id, asym_id, row.label_seq, row.atom_name
+ )
+ record_entries.append(entry)
+ if info is not None and not row.zero_occupancy:
+ absent.add(entry) # cross-check covers modelled residues only
+ if covered and absent != set(template_entries):
+ LOG.warning(
+ f"{sorted(member_asym_ids)}: wwPDB unobserved-atom records "
+ f"{sorted(absent ^ set(template_entries))} disagree with the CCD template diff"
+ )
+ return record_entries
+
+
+def get_molecule_type(chain_type_str: str) -> str:
+ """Collapse an mmCIF entity polymer type into the ligand molecule type."""
+ ct = chain_type_str.lower()
+ if "non-polymer" in ct:
+ return "SMALLMOLECULE"
+ if "polypeptide" in ct:
+ return "PEPTIDE"
+ if "polydeoxyribonucleotide" in ct and "polyribonucleotide" in ct:
+ return "MIXED"
+ if "polydeoxyribonucleotide" in ct:
+ return "DNA"
+ if "polyribonucleotide" in ct:
+ return "RNA"
+ if "polysaccharide" in ct or "oligosaccharide" in ct or "branched" in ct:
+ return "SACCHARIDE"
+ if "macrolide" in ct or "cyclic-pseudo-peptide" in ct:
+ return "MACROCYCLES"
+ return "UNKNOWN"
+
+
+@cache
+def parse_cofactors(data_dir: Path) -> set[str]:
+ """Download and parse cofactors.
+
+ Returns
+ -------
+ Set[str]
+ Set of cofactors
+
+ """
+ from plinder.data.pipeline.io import download_cofactors
+
+ cofactors_json = download_cofactors(data_dir=data_dir)
+ extra = {
+ "Ascorbic acid": ["UU3"],
+ "Coenzyme F420": ["6J4", "F42"],
+ "Factor F430": ["F43", "M43"],
+ "Pantetheine": ["PNY"],
+ "Pantothenic acids": ["66S", "8Q1", "PAU"],
+ "Nicotinamide": ["NCA"],
+ "Adenosine nucleotides": [
+ "A",
+ "AMP",
+ "ATP",
+ "ADP",
+ ], # + ["ANP"], # ANP is a mimic-inhibitor
+ "Guanosine nucleotides": [
+ "G",
+ "GTP",
+ "GDP",
+ "GMP",
+ # "CPG", # OBS -> 5GP (already listed)
+ # "G25", # OBS, no REL successor
+ "5GP",
+ ], # + ["GNP", "GTN"], # GNP/GTN is inhibitor
+ "Cytidine nucleotides": [
+ "C",
+ "C5P",
+ "CDP",
+ "CTP",
+ ], # C25 (OBS) -> C5P, already listed
+ "Thymidine nucleotides": [
+ "TMP",
+ "DT",
+ "TTP",
+ "THM",
+ "TYD",
+ ], # T (OBS) -> DT, already listed
+ "Uridine nucleotides": [
+ "U",
+ "DU",
+ "U5P",
+ "UMP",
+ "UDP",
+ "UTP",
+ ], # U25 (OBS) -> U5P, already listed
+ # "MIO": ["CRW"], # CRW is OBS with no REL successor (kept; verify)
+ "NAD": ["NAD"], # was NAH (OBS -> NAD)
+ "Glutathione": ["GPR"], # was CYP (OBS -> GPR)
+ "Biopterin": ["HBI", "H4B"], # was HBL->HBI, BH4->H4B, THB->H4B (dup)
+ "Tetrahydrofolic acid": ["MEF"],
+ "Lumazine": ["DLZ"],
+ "Menaquinone": ["MQ8", "MQ9", "MQE", "MQ7"], # 7MQ (OBS) -> MQ7
+ "Heme": ["1CP", "CP3", "MMP", "UP2", "UP3"],
+ "Methanopterin": ["H4M", "H4Z"],
+ "Lipoamide": ["LPM"],
+ "Ubiquinone": ["DCQ", "HQE", "PLQ"],
+ "Pyridoxal": ["PXL", "UEG"],
+ "Siderophores": ["488", "EB4", "SE8"],
+ "Methanofuran": ["MFN"],
+ "Vitamin A": ["BCR", "ECH", "EQ3"], # RAW (OBS) -> ECH, already listed
+ "Vitamin K1": ["PQN"],
+ "CHLOROPHYLL and similar": [
+ "CLA",
+ "CHL",
+ "CL0",
+ # "CL1", # OBS, no REL successor
+ # "CL2", # OBS, no REL successor
+ "CL7",
+ "BCB",
+ "BCL",
+ "07D",
+ "G9R",
+ "PEB",
+ "PUB",
+ "CYC",
+ "BPH",
+ ],
+ # "Lipids": ["SPH"], # TODO: ?
+ # "Sugars": ["NAG", "BCG", "GLC"], # TODO: more?
+ #
+ }
+ cofactors = set()
+ for c in cofactors_json:
+ for c_list in cofactors_json[c]:
+ cofactors |= set(c_list.get("cofactors", []))
+ for c in extra:
+ cofactors |= set(extra[c])
+
+ return cofactors
+
+
+@cache
+def parse_artifacts() -> set[CcdComponents]:
+ """Get and parse artifacts
+ Returns:
+ set[str]: set[str]
+ """
+ artifact_log = BASE_DIR / "annotations/static_files/artifacts_badlist.csv"
+ with open(artifact_log, "r") as f:
+ lines = f.readlines()
+ return {ccd_components(l.strip()) for l in lines if not l.startswith("#")}
+
+
+@cache
+def get_binding_affinity(data_dir: Path) -> ty.Any:
+ """Load sequence-specific, endpoint-specific BindingDB candidates."""
+ from plinder.data.pipeline.io import download_affinity_data
+
+ return download_affinity_data(data_dir=data_dir)
+
+
+def get_len_of_longest_linear_hydrocarbon_linker(
+ mol: Mol,
+ max_count: int = 50,
+ link_unit_smarts: str = "[#6D2R0]",
+) -> int | None:
+ """Estimate maximum linker length defined by link_unit_smarts, eg.
+ unbranched hydrocarbons (default)
+
+ Args:
+ mol (Mol): RDKit molecule
+ max_count (int, optional):
+ Positive search limit for linker length. Defaults to 50.
+ link_unit_smarts (str, optional):
+ Linker unit defined by SMARTS. Defaults to "[#6D2R0]".
+
+ Returns:
+ Maximum matching linker length, capped at max_count. A result equal
+ to max_count is a lower bound. Returns None if the calculation fails.
+ """
+ if max_count < 1:
+ raise ValueError("max_count must be positive")
+ try:
+ # needs ring info!
+ Chem.SanitizeMol(
+ mol, sanitizeOps=Chem.rdmolops.SanitizeFlags.SANITIZE_SYMMRINGS
+ )
+ # length of longest hydrocarbon chain (excludes the ends and rings)
+ for i in range(max_count):
+ chain_smarts = "~".join([link_unit_smarts] * (i + 1))
+ if not mol.HasSubstructMatch(Chem.MolFromSmarts(chain_smarts)):
+ return i
+ return max_count
+ except Exception as e:
+ name = mol.GetProp("_Name") if mol.HasProp("_Name") else "unnamed molecule"
+ LOG.warning(
+ "Error calculating longest linear hydrocarbon linker for %s: %s", name, e
+ )
+ return None
+
+
+def is_excluded_mol(
+ smiles: str,
+ min_C_threshold: int = 2,
+ min_HA_threshold: int = 5,
+ max_charge: int = 6,
+ max_linear_hydrocarbon_linker: int = 12,
+) -> bool:
+ """Exclude some molecules by default as useless for druglikeness
+ Uses OR logic for violating rules:
+ - less than 2 carbon atoms
+ - less than 5 non-hydrogen atoms
+ - charge larger than +/- 6
+ - unbranched hydrocarbon linker no longer than 12
+
+ Args:
+ smiles (str): molecule SMILES
+ min_C_threshold (int, optional):
+ Minimum carbon atom count. Defaults to 2.
+ min_HA_threshold (int, optional):
+ Minimum non-hydrogen atom count. Defaults to 5.
+ max_charge (int, optional):
+ Maximum allowed absolute charge. Defaults to 2.
+ max_linear_hydrocarbon_linker (int, optional):
+ Maximum allowed unbranched hydrocarbon linker. Defaults to 12.
+
+ Returns:
+ bool: should molecule be considered as artifact
+ """
+ mol = Chem.MolFromSmiles(smiles, sanitize=False)
+ # An empty or unparseable SMILES is not a molecule โ exclude it (also
+ # avoids crashing on the None RDKit returns for invalid SMILES).
+ if mol is None:
+ return True
+
+ # get heavy atom and carbon counts
+ carbon = Chem.MolFromSmarts("[#6]")
+ numC = len(mol.GetSubstructMatches(carbon))
+ numHA = mol.GetNumHeavyAtoms()
+
+ if numHA < min_HA_threshold or numC < min_C_threshold:
+ return True
+
+ # get formal charge
+ charge = Chem.rdmolops.GetFormalCharge(mol)
+ if abs(charge) > max_charge:
+ return True
+ linker_length = get_len_of_longest_linear_hydrocarbon_linker(
+ mol, max_count=max_linear_hydrocarbon_linker + 1
+ )
+ return linker_length is None or linker_length > max_linear_hydrocarbon_linker
+
+
+def is_known_artifact_ligand(
+ residue_names: ty.Iterable[str],
+ artifact_codes: set[CcdComponents],
+) -> bool:
+ """Return whether a ligand chain is provably an artifact before assembly.
+
+ Composite ligands are only rejected from CCD-code rules that are identical
+ to :meth:`Ligand.identify_artifacts_cofactors_and_other`. The molecular
+ exclusion rules are evaluated only for a single-residue CCD ligand, where
+ the CCD template is the same canonical source used by ``Ligand.from_pli``.
+ Uncertain cases deliberately return ``False`` and follow the full path.
+ """
+ names = [str(name) for name in residue_names]
+ if not names:
+ return False
+ ccd_code = "-".join(names)
+ if ccd_components(ccd_code) in artifact_codes or lig_has_dummies(ccd_code):
+ return True
+ if len(names) != 1:
+ return False
+ smiles = _get_ccd_smiles(names[0])
+ if smiles is None:
+ return False
+ try:
+ return is_excluded_mol(smiles)
+ except Exception as exc:
+ LOG.warning("Could not preclassify CCD %s: %s", names[0], exc)
+ return False
+
+
+def is_single_atom_or_ion(mol: Mol) -> bool:
+ """True if the molecule is a single non-organic heavy atom (metal ion)."""
+ numHA = mol.GetNumHeavyAtoms()
+ skip_single_elems = Chem.MolFromSmarts("[#6,#1,#0,#7,#8,#15,#16,#34,#52]")
+ numCHNOPSetc = len(mol.GetSubstructMatches(skip_single_elems))
+ return numHA == 1 and numCHNOPSetc == 0
+
+
+def validate_chain_residue(obj: dict[str, ty.Any]) -> dict[str, ty.Any]:
+ """Recursively coerce string dict keys to ints or tuples for pydantic."""
+ clean = {}
+ for k, v in obj.items():
+ if isinstance(k, str):
+ if "," in k:
+ key: ty.Any = tuple(k.split(","))
+ else:
+ try:
+ key = int(k)
+ except ValueError:
+ key = k
+ else:
+ key = k
+ if isinstance(v, dict):
+ clean[key] = validate_chain_residue(v)
+ else:
+ clean[key] = v
+ return clean
+
+
+CrystalContacts = ty.Annotated[
+ dict[tuple[str, int], set[int]],
+ BeforeValidator(validate_chain_residue),
+ Field(default_factory=dict),
+]
+
+
+class Ligand(DocBaseModel):
+ pdb_id: str = Field(
+ default_factory=str,
+ description="[EXCLUDE] RCSB PDB ID, see https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html",
+ )
+ biounit_id: str = Field(
+ default_factory=str,
+ description="[EXCLUDE] Biounit id",
+ )
+ id_legacy: str = Field(
+ default="",
+ description="Historical ligand ID using global assembly-operation chain instances",
+ )
+ asym_id: str = Field(default_factory=str, description="Ligand chain asymmetric id")
+ instance: int = Field(default_factory=int, description="Biounit instance ID")
+ ccd_code: str = Field(
+ default_factory=str,
+ description="Ligand Chemical Component Dictionary (CCD) code",
+ )
+ molecule_type: str = Field(
+ default_factory=str,
+ description=(
+ "Ligand molecule type derived from the mmCIF entity polymer type: "
+ "SMALLMOLECULE, PEPTIDE, DNA, RNA, MIXED, SACCHARIDE, MACROCYCLES, "
+ "or UNKNOWN"
+ ),
+ )
+ bird_id: str = Field(default_factory=str, description="Ligand BIRD (PRD) id")
+ is_subject_of_investigation: bool | None = Field(
+ default=None,
+ description="Whether a component of this ligand is a depositor-flagged "
+ "SUBJECT OF INVESTIGATION (_pdbx_entity_instance_feature); null when the "
+ "entry lacks the annotation, i.e. most entries deposited before ~2019",
+ )
+ smiles: str = Field(
+ default_factory=str,
+ description="Ligand SMILES from CCD lookup (user-supplied SMILES wins for custom CIFs) or resolved 3D; for composite ligands, the valid representation with more heavy atoms is used and resolved connectivity wins ties",
+ )
+ resolved_smiles: str = Field(
+ default_factory=str,
+ description="SMILES from resolved 3D coordinates: bond orders from CCD template, stereochemistry from 3D geometry",
+ )
+ resolved_stereo_matches_template: bool | None = Field(
+ default=None,
+ description="Whether resolved 3D stereo matches CCD template (True if achiral; None if no template)",
+ )
+ residue_numbers: list[int] = Field(
+ default_factory=list,
+ description="[EXCLUDE] Ligand residue numbers",
+ )
+ member_residue_numbers: dict[str, list[int]] = Field(
+ default_factory=dict,
+ description="[EXCLUDE] Residue numbers per member instance-chain. A ligand may "
+ "span several covalently-linked chains (e.g. a macrocycle whose parts "
+ "are deposited as separate chains); this maps each member "
+ "'{instance}.{asym_id}' to its residue numbers so every atom in the "
+ "ligand can be selected. Single-chain ligands map their one instance-chain.",
+ )
+ molecular_weight: float | None = Field(default=None, description="Molecular weight")
+ crippen_clogp: float | None = Field(
+ default=None,
+ description="Ligand Crippen MlogP, see https://www.rdkit.org/docs/source/rdkit.Chem.Crippen.html",
+ )
+ num_rot_bonds: int | None = Field(
+ default=None, description="Number of rotatable bonds"
+ )
+ num_hbd: int | None = Field(
+ default=None, description="Number of hydrogen bond donors"
+ )
+ num_hba: int | None = Field(
+ default=None, description="Number of hydrogen bond acceptors"
+ )
+ num_rings: int | None = Field(default=None, description="Number of rings")
+ num_heavy_atoms: int | None = Field(
+ default=None, description="Number of heavy atoms"
+ )
+ is_covalent: bool = Field(
+ default=False, description="Indicator of whether a ligand is a covalent ligand"
+ )
+ covalent_linkages: set[str] = Field(
+ default_factory=set[str],
+ description=(
+ "Covalent links from _struct_conn (conn_type_id='covale') as "
+ "receptor_end__ligand_end; each end is "
+ "{auth_seq}:{comp_id}:{asym}:{label_seq}:{atom} (auth_seq_id with "
+ "insertion code, label_comp_id, label_asym_id, label_seq_id or '.' for "
+ "non-polymers, label_atom_id), the residue address shared with "
+ "ligand_unresolved_atoms and chain_modified_residues"
+ ),
+ )
+ neighboring_residues: dict[str, list[int]] = Field(
+ default_factory=dict,
+ description="[CUSTOM_EXPORT] Dictionary of neighboring residues, with {instance}.{chain} key and residue number value",
+ )
+ neighboring_ligands: list[str] = Field(
+ default_factory=list,
+ description="[EXCLUDE] List of neighboring ligands {instance}.{chain}",
+ )
+ receptor_seqres: dict[str, str] = Field(
+ default_factory=dict,
+ description="[EXCLUDE] SEQRES sequences of neighboring receptor chains for affinity validation",
+ )
+ interacting_residues: dict[str, list[int]] = Field(
+ default_factory=dict,
+ description="[CUSTOM_EXPORT] Dictionary of interacting residues, with {instance}.{chain} key and residue number value",
+ )
+ interacting_ligands: list[str] = Field(
+ default_factory=list,
+ description="[EXCLUDE] List of interacting ligands {instance}.{chain}",
+ )
+ # Interaction hashes are computed by PEPPR.
+ interactions: dict[str, dict[int, list[str]]] = Field(
+ default_factory=dict,
+ description="[EXCLUDE] Dictionary of {instance}.{chain} to residue number to list of interaction hashes",
+ )
+ failed_interaction_types: list[str] = Field(
+ default_factory=list,
+ description="Interaction types whose calculation failed for this ligand; "
+ "counts for these types may be incomplete",
+ )
+ contact_area: float | None = Field(
+ default=None,
+ description="Voronota-LT contact area in square angstroms between the ligand "
+ "and the receptor polymer chains of its biological assembly; null when the "
+ "assembly tessellation was skipped or failed",
+ )
+ chain_contact_areas: dict[str, float] = Field(
+ default_factory=dict,
+ description="[CUSTOM_EXPORT] Voronota-LT contact area in square angstroms "
+ "between the ligand and each {instance}.{chain} it touches, receptor and "
+ "ligand chains alike",
+ )
+
+ @classmethod
+ def document_properties(
+ cls, prefix: str
+ ) -> ty.Generator[tuple[str, str | None, str], ty.Any, ty.Any]:
+ """Describe model fields plus the flat columns emitted by ``format()``."""
+ yield from super().document_properties(prefix)
+ custom_columns = (
+ (
+ "residue_numbers",
+ "list[int]",
+ "Resolved ligand residue numbers used to reconstruct this ligand "
+ "from the source mmCIF",
+ ),
+ (
+ "instance_chains",
+ "list[str]",
+ "All instance chains this ligand spans (several for a multi-chain "
+ "covalent ligand); used to reconstruct the whole-molecule SDF from "
+ "the source mmCIF",
+ ),
+ (
+ "water_residues",
+ "list[str]",
+ "Interacting water residues encoded as "
+ "._",
+ ),
+ (
+ "interactions",
+ "list[str]",
+ "Protein-ligand interactions encoded by receptor chain, residue "
+ "number, and interaction type",
+ ),
+ ("auth_id", "str", "Author chain ID of the ligand"),
+ (
+ "contact_area_chains",
+ "list[str]",
+ "Instance chains in Voronota-LT contact with the ligand, receptor "
+ "and ligand chains alike, positionally aligned with "
+ "ligand_contact_area_values",
+ ),
+ (
+ "contact_area_values",
+ "list[float]",
+ "Voronota-LT contact area in square angstroms between the ligand "
+ "and each chain in ligand_contact_area_chains",
+ ),
+ (
+ "pocket_unresolved_atoms",
+ "list[str]",
+ "Heavy atoms missing from pocket residues as "
+ "{auth_seq}:{comp_id}:{asym}:{label_seq}:{atom}, the residue address "
+ "of ligand_covalent_linkages",
+ ),
+ )
+ for suffix, dtype, description in custom_columns:
+ yield f"{prefix}_{suffix}", dtype, description
+
+ neighboring_residue_threshold: float = Field(
+ default=6.0,
+ description="[EXCLUDE] Maximum distance to consider receptor residues (protein/NA) neighboring",
+ )
+ neighboring_ligand_threshold: float = Field(
+ default=4.0,
+ description="[EXCLUDE] Maximum distance to consider ligands neighboring",
+ )
+ num_resolved_heavy_atoms: int | None = Field(
+ default=None, description="Number of resolved heavy atoms in a ligand"
+ )
+ num_unresolved_heavy_atoms: int | None = Field(
+ default=None,
+ description="Number of unresolved heavy atoms in a ligand: wwPDB unobserved or "
+ "zero-occupancy atom records, else CCD template minus resolved atoms, else "
+ "reference SMILES count minus resolved atoms",
+ )
+ unresolved_atoms: list[str] = Field(
+ default_factory=list,
+ description="Heavy atoms missing from the ligand model as "
+ "{auth_seq}:{comp_id}:{asym}:{label_seq}:{atom}, the residue address of "
+ "ligand_covalent_linkages; from wwPDB unobserved or zero-occupancy atom records, "
+ "else the CCD template minus resolved atoms; leaving atoms of polymer and linked "
+ "residues excluded",
+ )
+ tpsa: float | None = Field(
+ default=None, description="Topological polar surface area"
+ )
+ qed: float | None = Field(
+ default=None,
+ description="Ligand QED score, a measure of drug-likeness, see https://www.rdkit.org/new_docs/source/rdkit.Chem.QED.html",
+ )
+ is_ion: bool = Field(
+ default=False, description="Indicator of whether a ligand is an ion"
+ )
+ is_lipinski: bool = Field(
+ default=False,
+ description="Indicator of whether a ligand satisfies Lipinski Ro5",
+ )
+ is_fragment: bool = Field(
+ default=False,
+ description="Indicator of whether a ligand satisfies fragment Ro3",
+ )
+ is_monosaccharide: bool = Field(
+ default=False,
+ description="Indicator of whether a ligand contains one saccharide unit",
+ )
+ is_oligosaccharide: bool = Field(
+ default=False,
+ description="Indicator of whether a ligand contains multiple saccharide units",
+ )
+ is_mononucleotide: bool = Field(
+ default=False,
+ description="Indicator of whether a ligand contains one nucleotide unit",
+ )
+ is_oligonucleotide: bool = Field(
+ default=False,
+ description="Indicator of whether a ligand contains multiple nucleotide units",
+ )
+ is_monopeptide: bool = Field(
+ default=False,
+ description="Indicator of whether a ligand contains one peptide unit",
+ )
+ is_oligopeptide: bool = Field(
+ default=False,
+ description="Indicator of whether a ligand contains multiple peptide units",
+ )
+ is_cofactor: bool = Field(
+ default=False, description="Indicator of whether a ligand is a cofactor"
+ )
+ in_artifact_list: bool = Field(
+ default=False,
+ description="Indicator of whether a ligand is in the artifact list",
+ )
+ is_artifact: bool = Field(
+ default=False, description="Indicator of whether a ligand is an artifact"
+ )
+ is_other: bool = Field(
+ default=False,
+ description="Indicator of whether a ligand type is not classified as any types of small molecule "
+ + "(Lipinski, Fragment or covalent), ion, cofactor, mono/oligo (peptide, saccharide or nucleotide) or artifact",
+ )
+ is_invalid: bool = Field(
+ default=False, description="Indicator of whether a ligand is invalid"
+ )
+ unique_ccd_code: str | None = Field(
+ default=None, description="Ligand representative CCD code after de-duplicating"
+ )
+ crystal_contacts: CrystalContacts = Field(
+ default_factory=dict,
+ description="[EXCLUDE] Dictionary of {chain} to residue number to set of interacting crystal contacts",
+ )
+ waters: dict[str, list[int]] = Field(
+ default_factory=dict,
+ description="[EXCLUDE] Dictionary of {instance}.{chain} to list of interacting water residue numbers",
+ )
+ """Ligand annotation dataclass.
+
+ Holds structural, chemical, and interaction annotations for a single
+ ligand chain in a proteinโligand (or NAโligand) complex.
+ """
+
+ def set_rdkit(self) -> None:
+ """Compute RDKit molecular descriptors from ``self.smiles``."""
+ try:
+ is_multi_residue = self._is_multi_residue
+ if is_multi_residue:
+ self.smiles = _choose_ligand_smiles_by_heavy_atom_count(
+ self.smiles,
+ self.resolved_smiles,
+ )
+ # Descriptors are a pure function of the SMILES, so they are looked up
+ # from the SMILES-keyed cache rather than recomputed per instance.
+ descriptors = _smiles_descriptors(self.smiles)
+ if descriptors is not None:
+ self.molecular_weight = descriptors["molecular_weight"]
+ self.num_rot_bonds = descriptors["num_rot_bonds"]
+ self.num_hba = descriptors["num_hba"]
+ self.num_hbd = descriptors["num_hbd"]
+ self.crippen_clogp = descriptors["crippen_clogp"]
+ self.num_rings = descriptors["num_rings"]
+ self.tpsa = descriptors["tpsa"]
+ self.qed = descriptors["qed"]
+ # The composite-ligand choice above may switch ``smiles`` to the
+ # resolved representation, so keep the heavy-atom count (set at
+ # construction from the reference SMILES) in step with it.
+ self.num_heavy_atoms = descriptors["num_heavy_atoms"]
+ if (
+ not self.unresolved_atoms
+ and self.num_unresolved_heavy_atoms is None
+ and self.num_heavy_atoms
+ and self.num_resolved_heavy_atoms
+ ):
+ self.num_unresolved_heavy_atoms = (
+ self.num_heavy_atoms - self.num_resolved_heavy_atoms
+ )
+ # classify ligand based on the (tolerantly sanitized) molecule; skip
+ # when the SMILES is empty/unparseable so a structurally valid ligand
+ # that merely lost its SMILES (e.g. a multi-residue peptide) is not
+ # flagged invalid.
+ mol = mol_from_smiles(self.smiles)
+ if mol is not None:
+ self.classify_ligand_type(mol)
+
+ except Exception as e:
+ logging.warning(f"Error in setting rdkit for {self.id}: {e}")
+ # Multi-residue ligands (peptides) may fail SMILES derivation
+ # but are still structurally valid
+ if self.smiles is None:
+ self.is_invalid = True
+
+ def classify_ligand_type(self, mol: Mol) -> None:
+ """Classify ligand as ion, Lipinski, fragment, or mono/oligo class.
+
+ Uses SMARTS patterns and Lipinski rules to assign granular type
+ beyond the chain-type classification.
+
+ Note
+ ----
+ Oligo smarts obtained from https://doi.org/10.1021/acs.jcim.3c01573
+
+ Args:
+ mol (Mol): RDKit compatible molecule
+ """
+ RDLogger.DisableLog("rdApp.*")
+ if mol is not None:
+ if is_single_atom_or_ion(mol):
+ self.is_ion = True
+ else:
+ try:
+ polymer_classes = classify_ligand_polymer_classes(
+ self.smiles,
+ resolved_smiles=self.resolved_smiles,
+ is_multi_residue=self._is_multi_residue,
+ )
+ for field, value in polymer_classes.items():
+ setattr(self, field, value)
+ if self.molecule_type == "SACCHARIDE" and self._is_multi_residue:
+ self.is_monosaccharide = False
+ self.is_oligosaccharide = True
+ except RuntimeError:
+ self.is_invalid = True
+ else:
+ self.is_invalid = True
+
+ # Lipinski like Ro3 and Ro5 - for non ions only
+ if (
+ self.is_ion == False
+ and self.is_invalid == False
+ and self.molecular_weight is not None
+ and self.crippen_clogp is not None
+ and self.num_hbd is not None
+ and self.num_hba is not None
+ ):
+ if (
+ self.molecular_weight < 300
+ and self.crippen_clogp < 3
+ and self.num_hbd <= 3
+ and self.num_hba <= 3
+ ):
+ self.is_fragment = True
+ self.is_lipinski = True
+ elif (
+ self.molecular_weight < 500
+ and self.crippen_clogp < 5
+ and self.num_hbd <= 5
+ and self.num_hba <= 10
+ ):
+ self.is_lipinski = True
+
+ @classmethod
+ def from_pli(
+ cls,
+ pdb_id: str,
+ biounit_id: str,
+ biounit: ty.Any,
+ ligand_instance: int,
+ ligand_chain: Chain,
+ residue_numbers: list[int],
+ ligand_like_chains: dict[str, str],
+ all_covalent_dict: dict[str, list[tuple[str, str]]],
+ interaction_search_threshold: float = 10.0,
+ neighboring_residue_threshold: float = 6.0,
+ neighboring_ligand_threshold: float = 4.0,
+ data_dir: ty.Optional[Path] = None,
+ chain_to_seqres: dict[str, str] | None = None,
+ ligand_smiles_dict: dict[str, str] | None = None,
+ ligand_ccd_code_dict: dict[str, str] | None = None,
+ water_chains: set[str] | None = None,
+ spatial_index: BiounitSpatialIndex | None = None,
+ member_residue_numbers: dict[str, list[int]] | None = None,
+ chain_pair_contact_areas: ty.Mapping[tuple[str, str], float] | None = None,
+ subject_of_investigation_comp_ids: ty.Collection[str] | None = None,
+ unobserved_atoms: ty.Mapping[str, list[UnobservedAtom]] | None = None,
+ ) -> Ligand | None:
+ """Build a Ligand from a biounit AtomArray and chain metadata.
+
+ Extracts SMILES (CCD template โ resolved 3D fallback), computes
+ interactions via peppr, finds neighboring residues/ligands, and
+ validates stereochemistry against the CCD template.
+
+ Parameters
+ ----------
+ pdb_id : str
+ PDB entry identifier.
+ biounit_id : str
+ Biological assembly identifier.
+ biounit : struc.AtomArray
+ Full biounit atoms with bonds.
+ ligand_instance : int
+ Instance index within the biounit.
+ ligand_chain : Chain
+ Chain metadata for the ligand.
+ residue_numbers : list[int]
+ Residue numbers belonging to this ligand.
+ ligand_like_chains : dict[str, str]
+ Other ligand-like chains in the entry ``{chain_id: chain_type}``.
+ all_covalent_dict : dict[str, list[tuple[str, str]]]
+ Covalent linkages by type (``"covale"``, ``"metalc"``, ``"hydrog"``).
+ interaction_search_threshold : float
+ Receptor residues within this distance (ร ) of the ligand form the
+ complex handed to peppr; keep it at or above peppr's 8 ร contact
+ cutoff, which plinder leaves at its default.
+ neighboring_residue_threshold : float
+ Max distance (ร ) for neighboring receptor residue detection.
+ neighboring_ligand_threshold : float
+ Max distance (ร ) for neighboring ligand detection.
+ data_dir : Path, optional
+ Plinder data root for loading cofactors, affinity, etc.
+ chain_to_seqres : dict[str, str], optional
+ SEQRES per chain for binding affinity validation.
+ ligand_smiles_dict : dict[str, str], optional
+ Per-residue SMILES for components not in CCD (typically
+ custom residues like Boltz's ``LIG``). When a residue's
+ name appears in this dict, the user's SMILES takes
+ precedence over CCD for both the canonical ``smiles``
+ field and the stereo template used by
+ :func:`_check_stereo_vs_template` โ the caller is assumed
+ to know that the CCD entry is absent or a placeholder.
+ ligand_ccd_code_dict : dict[str, str], optional
+ Custom component ID to reference CCD code. This changes the
+ reported ``ccd_code`` while ``ligand_smiles_dict`` carries the
+ resolved reference SMILES used for RDKit and stereo checks.
+ water_chains : set[str], optional
+ Chain IDs containing only solvent atoms. Pass a precomputed set
+ when processing multiple ligands from the same assembly.
+ spatial_index : BiounitSpatialIndex, optional
+ Reusable whole-assembly spatial and hierarchy index.
+ member_residue_numbers : dict[str, list[int]], optional
+ Residue numbers per member instance-chain for a ligand that spans
+ several covalently-linked chains (a macrocycle deposited as
+ separate chains). Defaults to the single primary chain
+ (``{ligand_instance_chain: residue_numbers}``) when omitted.
+ chain_pair_contact_areas : Mapping[tuple[str, str], float] | None
+ Assembly-wide Voronota-LT areas keyed by sorted chain pair. When
+ given, ``chain_contact_areas`` and ``contact_area`` are filled from
+ the pairs involving the ligand's member chains; otherwise both stay
+ unset (``None`` / empty).
+ subject_of_investigation_comp_ids : Collection[str] | None
+ Depositor-flagged SUBJECT OF INVESTIGATION comp_ids; ``None`` leaves
+ ``is_subject_of_investigation`` null.
+ unobserved_atoms : Mapping[str, list[tuple[str, str, str]]] | None
+ wwPDB unobserved-atom records per asym; ``None`` falls back to the
+ CCD template diff, then to the reference SMILES count.
+
+ Returns
+ -------
+ Ligand or None
+ Populated Ligand object, or None if no atoms found.
+ """
+ if data_dir is not None:
+ global COFACTORS, ARTIFACTS, COFACTOR_SMILES, ARTIFACT_SMILES
+ global BINDING_AFFINITY
+ if COFACTORS is None:
+ COFACTORS = {ccd_components(code) for code in parse_cofactors(data_dir)}
+ COFACTOR_SMILES = _reference_smiles(COFACTORS)
+ if ARTIFACTS is None:
+ ARTIFACTS = parse_artifacts()
+ ARTIFACT_SMILES = _reference_smiles(ARTIFACTS)
+ if BINDING_AFFINITY is None:
+ try:
+ BINDING_AFFINITY = get_binding_affinity(data_dir)
+ except Exception as e:
+ LOG.warning(f"Failed to load binding affinity data: {e}")
+ BINDING_AFFINITY = {}
+
+ ligand_instance_chain = f"{ligand_instance}.{ligand_chain.asym_id}"
+ # A ligand may span several covalently-linked chains. Default to the
+ # single primary chain when no members were supplied.
+ if member_residue_numbers is None:
+ member_residue_numbers = {ligand_instance_chain: residue_numbers}
+ member_instance_chains = set(member_residue_numbers)
+ member_asym_ids = {
+ ic.split(".", maxsplit=1)[-1] for ic in member_instance_chains
+ }
+
+ if spatial_index is None:
+ spatial_index = BiounitSpatialIndex.from_atoms(
+ biounit,
+ max(
+ interaction_search_threshold,
+ neighboring_residue_threshold,
+ neighboring_ligand_threshold,
+ ),
+ )
+
+ # Select ligand atoms across all covalently-linked member chains
+ # without scanning the full assembly.
+ lig_index_parts = []
+ for member_chain, member_rns in member_residue_numbers.items():
+ member_indices = spatial_index.atom_indices_for_chain(member_chain)
+ lig_index_parts.append(
+ member_indices[np.isin(biounit.res_id[member_indices], member_rns)]
+ )
+ lig_indices = (
+ np.concatenate(lig_index_parts)
+ if lig_index_parts
+ else np.array([], dtype=int)
+ )
+ if lig_indices.size == 0:
+ LOG.warning(f"from_pli: no ligand atoms for {ligand_instance_chain}")
+ return None
+ lig_atoms = spatial_index.take_atoms(biounit, lig_indices, include_bonds=True)
+ lig_coords = lig_atoms.coord
+
+ # Find complete residues within threshold distance of ligand. Residue
+ # starts and the whole-assembly CellList are shared by every ligand.
+ nearby_indices = spatial_index.complete_residue_indices_near(
+ lig_coords, interaction_search_threshold
+ )
+ nearby_atoms = spatial_index.take_atoms(
+ biounit, nearby_indices, include_bonds=True
+ )
+
+ # build_biounit guarantees bonds and they propagate through the slice;
+ # if not - fail loud!
+ if nearby_atoms.bonds is None:
+ raise ValueError(
+ f"from_pli: pocket atoms for {ligand_instance_chain} arrived "
+ "without bonds; build_biounit must supply them."
+ )
+
+ # Split into receptor/ligand/water/metal
+ receptor_mask = struc.filter_amino_acids(
+ nearby_atoms
+ ) | struc.filter_nucleotides(nearby_atoms)
+ ligand_mask_local = np.isin(nearby_atoms.chain_id, list(member_instance_chains))
+ water_mask = struc.filter_solvent(nearby_atoms)
+ metal_mask = struc.filter_monoatomic_ions(nearby_atoms) & ~ligand_mask_local
+
+ receptor_arr = nearby_atoms[receptor_mask & ~water_mask & ~metal_mask]
+ ligand_arr = nearby_atoms[ligand_mask_local & ~water_mask]
+ water_arr = nearby_atoms[water_mask]
+ metal_arr = nearby_atoms[metal_mask]
+
+ if receptor_arr.array_length() == 0 or ligand_arr.array_length() == 0:
+ LOG.warning(
+ f"from_pli: empty receptor or ligand for {ligand_instance_chain}"
+ )
+ return None
+
+ peppr_interactions, peppr_waters, peppr_failed_types = run_peppr_interactions(
+ receptor_arr,
+ ligand_arr,
+ water_arr,
+ metal_arr,
+ ligand_instance_chain,
+ )
+
+ # CCD codes, one per residue in atom order across all member chains.
+ # Keying on (chain, res_id) avoids collisions when merged chains reuse
+ # residue numbers.
+ def _residues_in_order(atoms: "struc.AtomArray") -> list[str]:
+ seen: set[tuple[str, int]] = set()
+ names: list[str] = []
+ for chain_id, res_id, res_name in zip(
+ atoms.chain_id, atoms.res_id, atoms.res_name
+ ):
+ key = (str(chain_id), int(res_id))
+ if key not in seen:
+ seen.add(key)
+ names.append(str(res_name))
+ return names
+
+ residue_component_ids = _residues_in_order(lig_atoms)
+ ccd_code = "-".join(
+ (ligand_ccd_code_dict or {}).get(component_id, component_id)
+ for component_id in residue_component_ids
+ )
+ # Get SMILES from CCD template via biotite, fall back to structure
+ from biotite.structure import filter_heavy
+
+ smiles = None
+ heavy_mask = filter_heavy(lig_atoms)
+ lig_heavy = lig_atoms[heavy_mask]
+ lig_heavy_indices = lig_indices[heavy_mask]
+ res_names = _residues_in_order(lig_heavy)
+ reference_fragments: list[str] = []
+ for resname in res_names:
+ component_smiles: str | None
+ # User-supplied SMILES takes precedence โ when the caller
+ # explicitly provided one, CCD is assumed to be wrong or a
+ # generic placeholder (biotite returns one for some codes
+ # like "LIG"). Fall through to CCD otherwise.
+ if ligand_smiles_dict and resname in ligand_smiles_dict:
+ component_smiles = ligand_smiles_dict[resname]
+ else:
+ reference_code = (ligand_ccd_code_dict or {}).get(
+ resname,
+ resname,
+ )
+ component_smiles = _get_ccd_smiles(reference_code)
+ if component_smiles is None:
+ reference_fragments = []
+ break
+ reference_fragments.append(component_smiles)
+ if reference_fragments:
+ smiles = ".".join(reference_fragments)
+ # Build per-residue custom stereo templates from user SMILES (only
+ # populated for custom CIFs via from_custom_cif_file). The CIF atom
+ # names for each residue are taken in file order, matching the
+ # SMILES-parse-order assumption used for bond assignment.
+ custom_templates: dict[str, Chem.Mol] | None = None
+ if ligand_smiles_dict:
+ custom_templates = {}
+ for resname, user_smiles in ligand_smiles_dict.items():
+ res_mask = lig_heavy.res_name == resname
+ if not np.any(res_mask):
+ continue
+ atom_names = list(lig_heavy.atom_name[res_mask])
+ tmpl = _template_from_user_smiles(resname, user_smiles, atom_names)
+ if tmpl is not None:
+ custom_templates[resname] = tmpl
+
+ # Build the resolved (from 3D) mol once. It drives:
+ # - resolved_smiles (bond orders from CCD, stereo from 3D coords)
+ # - stereo match check against the CCD template (or custom SMILES)
+ # - fallback SMILES when the CCD/user-SMILES lookup failed
+ resolved_smiles: str | None = None
+ stereo_matches: bool | None = None
+ try:
+ from plinder.data.annotations.cif_utils import atoms_to_rdkit_mol
+
+ # biotite has no chiral tags โ stereo assigned from 3D inside helper
+ resolved_mol = atoms_to_rdkit_mol(lig_heavy)
+ resolved_smiles = str(Chem.MolToSmiles(resolved_mol))
+ # Compare resolved 3D stereo with CCD template stereo
+ # (works for both single- and multi-residue ligands)
+ stereo_matches = _check_stereo_vs_template(
+ resolved_mol,
+ custom_templates=custom_templates,
+ ccd_code_dict=ligand_ccd_code_dict,
+ )
+ except Exception as e:
+ LOG.warning(f"Failed to compute resolved SMILES for {ccd_code}: {e}")
+ # Prefer the candidate representing more atoms. Resolved coordinates
+ # can join a composite ligand correctly, but may omit unobserved atoms;
+ # the complete set of per-component references can be fuller despite
+ # not encoding the observed inter-component links. Equal-sized resolved
+ # molecules win because they do preserve those links.
+ if len(residue_component_ids) > 1:
+ smiles = _choose_ligand_smiles_by_heavy_atom_count(
+ smiles,
+ resolved_smiles,
+ )
+ elif smiles is None:
+ smiles = resolved_smiles
+ # Heavy-atom counts are structural (not rdkit descriptors): resolved is
+ # just the length of the heavy-atom biotite array (robust even if the
+ # rdkit mol build above failed), total comes from the SMILES-keyed
+ # descriptor cache, and unresolved is their difference.
+ num_resolved_heavy_atoms = lig_heavy.array_length()
+ reference_descriptors = _smiles_descriptors(smiles)
+ num_heavy_atoms = (
+ reference_descriptors["num_heavy_atoms"]
+ if reference_descriptors is not None
+ else None
+ )
+ unresolved_atoms = _ligand_unresolved_atoms(
+ biounit,
+ lig_heavy_indices,
+ member_asym_ids,
+ unobserved_atoms,
+ ligand_ccd_code_dict,
+ chain_to_seqres or {},
+ )
+ if unresolved_atoms is not None:
+ num_unresolved_heavy_atoms: int | None = len(unresolved_atoms)
+ else:
+ num_unresolved_heavy_atoms = (
+ num_heavy_atoms - num_resolved_heavy_atoms
+ if num_heavy_atoms and num_resolved_heavy_atoms
+ else None
+ )
+ # BIRD/PRD id straight from the enriched CIF: the mapping key is the PRD
+ # code (see cif_utils BIRD parse), a single canonical id for the ligand.
+ bird_id = next(iter(ligand_chain.mappings.get("BIRD", {})), "")
+ ligand = cls(
+ pdb_id=pdb_id,
+ biounit_id=biounit_id,
+ asym_id=ligand_chain.asym_id,
+ instance=ligand_instance,
+ ccd_code=ccd_code,
+ molecule_type=get_molecule_type(ligand_chain.chain_type_str),
+ bird_id=bird_id,
+ is_subject_of_investigation=(
+ None
+ if subject_of_investigation_comp_ids is None
+ else any(
+ component_id in subject_of_investigation_comp_ids
+ for component_id in residue_component_ids
+ )
+ ),
+ smiles=smiles or "",
+ neighboring_residue_threshold=neighboring_residue_threshold,
+ neighboring_ligand_threshold=neighboring_ligand_threshold,
+ resolved_smiles=resolved_smiles or "",
+ resolved_stereo_matches_template=stereo_matches,
+ num_heavy_atoms=num_heavy_atoms,
+ num_resolved_heavy_atoms=num_resolved_heavy_atoms,
+ num_unresolved_heavy_atoms=num_unresolved_heavy_atoms,
+ unresolved_atoms=unresolved_atoms or [],
+ residue_numbers=residue_numbers,
+ member_residue_numbers=member_residue_numbers,
+ )
+
+ # Find neighboring polymer residues (protein + nucleic acid) without
+ # rebuilding or scanning a whole-assembly polymer index.
+ neighbor_indices = spatial_index.atom_indices_near(
+ lig_coords, ligand.neighboring_residue_threshold
+ )
+ neighboring_atoms = spatial_index.take_atoms(
+ biounit, neighbor_indices, include_bonds=False
+ )
+ polymer_mask = struc.filter_amino_acids(
+ neighboring_atoms
+ ) | struc.filter_nucleotides(neighboring_atoms)
+ near_prot = neighboring_atoms[polymer_mask]
+
+ for chain_id in np.unique(near_prot.chain_id):
+ if chain_id in member_instance_chains:
+ continue
+ # Skip chains classified as ligands โ they belong in
+ # neighboring_ligands/interacting_ligands, not neighboring_residues
+ asym = chain_id.split(".", maxsplit=1)[-1] if "." in chain_id else chain_id
+ if asym in ligand_like_chains:
+ continue
+ chain_atoms = near_prot[near_prot.chain_id == chain_id]
+ resnums = list(dict.fromkeys(int(r) for r in chain_atoms.res_id))
+ ligand.neighboring_residues[chain_id] = resnums
+ # Store SEQRES for binding affinity validation
+ asym_id = (
+ chain_id.split(".", maxsplit=1)[-1] if "." in chain_id else chain_id
+ )
+ if chain_to_seqres and asym_id in chain_to_seqres:
+ ligand.receptor_seqres[chain_id] = chain_to_seqres[asym_id]
+
+ neighboring_asym_ids = {
+ c.split(".", maxsplit=1)[-1]
+ for c in np.unique(near_prot.chain_id)
+ if c not in member_instance_chains
+ }
+
+ # A covalently-linked group is one molecule: bonds *between* member
+ # chains are internal, so only count covale bonds from any member to a
+ # non-member (receptor) chain.
+ neighboring_non_member = neighboring_asym_ids - member_asym_ids
+ covalent_linkages: set[str] = set()
+ for member_asym in member_asym_ids:
+ covalent_linkages |= extract_ligand_links_to_neighbouring_chains(
+ all_covalent_dict,
+ member_asym,
+ neighboring_non_member,
+ link_type="covale",
+ )
+ ligand.covalent_linkages = covalent_linkages
+ ligand.is_covalent = len(ligand.covalent_linkages) > 0
+
+ if chain_pair_contact_areas is not None:
+ ligand.set_contact_areas(chain_pair_contact_areas, ligand_like_chains)
+
+ # Find neighboring ligand chains
+ near_lig_indices = spatial_index.atom_indices_near(
+ lig_coords, ligand.neighboring_ligand_threshold
+ )
+ near_all = spatial_index.take_atoms(
+ biounit, near_lig_indices, include_bonds=False
+ )
+
+ ligand.neighboring_ligands = sorted(
+ {
+ c
+ for c in np.unique(near_all.chain_id)
+ if c not in member_instance_chains
+ and "." in c
+ and c.split(".", maxsplit=1)[1] in ligand_like_chains
+ }
+ )
+ if water_chains is None:
+ water_chains = get_water_chain_ids(biounit)
+ # Populate interactions and waters from peppr results
+ ligand.interactions = peppr_interactions
+ ligand.failed_interaction_types = peppr_failed_types
+ ligand.waters = defaultdict(list)
+ for w_chain, w_resnum in peppr_waters:
+ ligand.waters[w_chain].append(w_resnum)
+
+ # Derive interacting residues from peppr interaction hashes
+ for instance_chain, residues in peppr_interactions.items():
+ if instance_chain in member_instance_chains:
+ continue
+ if instance_chain in water_chains:
+ continue
+ if instance_chain.split(".", maxsplit=1)[1] in ligand_like_chains:
+ ligand.interacting_ligands.append(instance_chain)
+ else:
+ if instance_chain not in ligand.interacting_residues:
+ ligand.interacting_residues[instance_chain] = []
+ ligand.interacting_residues[instance_chain].extend(
+ int(r) for r in residues.keys()
+ )
+ # add rdkit properties and type assignments
+ ligand.set_rdkit()
+ if data_dir is not None:
+ # set is_artifact and is_cofactor and is_other
+ ligand.identify_artifacts_cofactors_and_other()
+ # unique code parsing!
+ # obsolete codes are never ingested (PDB remediates), so the old
+ # code->canonical synonym map was an identity no-op: use the code as-is.
+ ligand.unique_ccd_code = ligand.ccd_code
+
+ return ligand
+
+ def set_contact_areas(
+ self,
+ chain_pair_contact_areas: ty.Mapping[tuple[str, str], float],
+ ligand_like_chains: ty.Collection[str],
+ ) -> None:
+ """Assign partner and receptor areas from the assembly tessellation."""
+ self.chain_contact_areas = partner_contact_areas(
+ chain_pair_contact_areas, set(self._members)
+ )
+ self.contact_area = sum(
+ area
+ for chain_id, area in self.chain_contact_areas.items()
+ if chain_id.split(".", maxsplit=1)[-1] not in ligand_like_chains
+ )
+
+ @property
+ def _members(self) -> dict[str, list[int]]:
+ """Residue numbers per member instance-chain (self, incl. covalent).
+
+ Falls back to the single primary chain for ligands built before
+ ``member_residue_numbers`` was populated.
+ """
+ return self.member_residue_numbers or {
+ self.instance_chain: self.residue_numbers
+ }
+
+ @property
+ def _is_multi_residue(self) -> bool:
+ """Whether deposited residue membership proves a composite ligand."""
+ residue_count = sum(
+ len(set(residue_numbers)) for residue_numbers in self._members.values()
+ )
+ return residue_count > 1 or len(self.ccd_code.split("-")) > 1
+
+ @property
+ def member_asym_ids(self) -> list[str]:
+ """Asym IDs of every chain this (possibly merged) ligand spans."""
+ return sorted({ic.split(".", maxsplit=1)[-1] for ic in self._members})
+
+ @cached_property
+ def selection(self) -> str:
+ """[EXCLUDE] Selection string for ligand
+
+ Spans every member instance-chain so covalently-linked ligand chains
+ (a macrocycle deposited as several chains) select all of their atoms.
+ """
+
+ def _chain_selection(instance_chain: str, resnums: list[int]) -> str:
+ selection = f"cname='{instance_chain}'"
+ if len(resnums):
+ residue_selection = " or ".join(f"rnum={rnum}" for rnum in resnums)
+ selection += f"and ({residue_selection})"
+ return selection
+
+ members = self._members
+ if len(members) == 1:
+ ((instance_chain, resnums),) = members.items()
+ return _chain_selection(instance_chain, resnums)
+ return " or ".join(
+ f"({_chain_selection(instance_chain, resnums)})"
+ for instance_chain, resnums in members.items()
+ )
+
+ @cached_property
+ def protein_chains_asym_id(self) -> list[str]:
+ """Receptor chain IDs (protein/NA) within neighboring threshold of ligand.
+
+ Returns empty list if the ligand is an artifact.
+ """
+ if self.is_artifact:
+ return []
+ else:
+ return list(sorted(self.neighboring_residues.keys()))
+
+ @cached_property
+ def num_interacting_residues(self) -> int:
+ """
+ Number of residues interacting with a given ligand.
+ """
+ return sum(
+ len(self.interacting_residues[chain]) for chain in self.interacting_residues
+ )
+
+ @cached_property
+ def num_neighboring_residues(self) -> int:
+ """Total count of receptor residues (protein/NA) within neighboring threshold."""
+ return sum(
+ len(self.neighboring_residues[chain]) for chain in self.neighboring_residues
+ )
+
+ @cached_property
+ def is_proper(self) -> bool:
+ """
+ Check if ligand is a proper ligand (not an ion or artifact)
+ """
+ return not self.is_ion and not self.is_artifact
+
+ @cached_property
+ def num_interactions(self) -> int:
+ """
+ Number of interactions for a given ligand.
+ """
+ return sum(
+ sum(len(i) for i in self.interactions[chain].values())
+ for chain in self.interactions
+ )
+
+ @cached_property
+ def num_unique_interactions(self) -> int:
+ """
+ Number of unique interactions
+ """
+ return sum(
+ sum(len(set(i)) for i in self.interactions[chain].values())
+ for chain in self.interactions
+ )
+
+ @cached_property
+ def pocket_residues(self) -> dict[str, dict[int, str]]:
+ """[EXCLUDE] Residues in the ligand's binding pocket which includes neighboring and interacting residues."""
+ residues: dict[str, dict[int, str]] = {}
+ for chain in self.neighboring_residues:
+ if chain not in residues:
+ residues[chain] = {}
+ for residue in self.neighboring_residues[chain]:
+ residues[chain][residue] = "neighboring"
+ for chain in self.interacting_residues:
+ if chain not in residues:
+ residues[chain] = {}
+ for residue in self.interacting_residues[chain]:
+ residues[chain][residue] = "interacting"
+ return residues
+
+ def get_pocket_residues_set(self) -> dict[tuple[str, int], set[str]]:
+ """
+ Get a dict of pocket residues in the format (chain_id, residue_number)
+ mapping to biounit instance set
+ """
+ pocket_residues_set = defaultdict(set)
+ for chain in self.pocket_residues:
+ for residue_number in self.pocket_residues[chain]:
+ pocket_residues_set[
+ (chain.split(".", maxsplit=1)[1], residue_number)
+ ].add(chain.split(".")[0])
+ return pocket_residues_set
+
+ def label_crystal_contacts(
+ self,
+ symmetry_mate_contacts: dict[
+ tuple[str, int], dict[tuple[str, int], dict[int, set[int]]]
+ ],
+ ) -> None:
+ """
+ Label ligand contacts to chains that are not part of the biounit.
+ """
+ crystal_contacts: dict[tuple[str, int], set[int]] = defaultdict(set[int])
+
+ # get contacts from neigchboring chain residues within the biounit
+ pocket_residues = self.get_pocket_residues_set()
+
+ for residue_number in self.residue_numbers:
+ # get all inter-chain contacts for a given ligand
+ contacts = symmetry_mate_contacts.get(
+ (self.asym_id, residue_number), dict()
+ )
+ for x, y in contacts.items():
+ # x is a tuple rec (chain_id, residue_number)
+ # y is a dict of ligand atom_id : {image_idx} - set of symmetry operations
+ num_crystal_image_contacts = len(y.values())
+ # if detected contacts have more images than contact instances in the biounit pocket
+ # then we assume that this is a crystal contact with a symmetry mate
+ if num_crystal_image_contacts > len(pocket_residues.get(x, set())):
+ # on the edge cases it may not be clear which atom is in contact with the symmetry mate, thus better to store all?
+ for atom_id, image_idx in y.items():
+ crystal_contacts[x] |= {atom_id}
+ # set crystal contacts
+ self.crystal_contacts = crystal_contacts
+
+ @cached_property
+ def num_crystal_contacted_residues(self) -> int:
+ """
+ Number of residues from other symmetry mates which are in contact with this ligand.
+ """
+ return len(self.crystal_contacts)
+
+ @cached_property
+ def num_atoms_with_crystal_contacts(self) -> int:
+ """
+ Number of atoms in this ligand which are in contact with residues from other symmetry mates.
+ """
+ all_atoms = set()
+ for x in self.crystal_contacts.values():
+ all_atoms |= x
+ return len(all_atoms)
+
+ @cached_property
+ def fraction_atoms_with_crystal_contacts(self) -> float | None:
+ """
+ Fraction of atoms in this ligand which are in contact with residues from other symmetry mates.
+ """
+ if not self.num_heavy_atoms:
+ return None
+ return self.num_atoms_with_crystal_contacts / self.num_heavy_atoms
+
+ @cached_property
+ def num_pocket_residues(self) -> int:
+ """
+ Number of residues in the ligand's binding pocket.
+ """
+ return sum([len(self.pocket_residues[chain]) for chain in self.pocket_residues])
+
+ @cached_property
+ def id(self) -> str:
+ """
+ Unique identifier for a given ligand.
+ """
+ return "__".join([self.pdb_id, self.biounit_id, self.instance_chain])
+
+ @cached_property
+ def instance_chain(self) -> str:
+ """
+ Instance chain for a given ligand.
+ """
+ return f"{self.instance}.{self.asym_id}"
+
+ @cached_property
+ def interactions_counter(self) -> dict[str, dict[int, ty.Counter[str]]]:
+ """[EXCLUDE] Counter of interactions for a given ligand."""
+ interactions_counter: dict[str, dict[int, ty.Counter[str]]] = {}
+ for chain in self.interactions:
+ interactions_counter[chain] = {}
+ for residue in self.interactions[chain]:
+ interactions_counter[chain][residue] = Counter(
+ self.interactions[chain][residue]
+ )
+ return interactions_counter
+
+ @cached_property
+ def binding_affinity(self) -> float | None:
+ """Sequence-matched pKi or pKd when BindingDB evidence is unambiguous."""
+ global BINDING_AFFINITY
+ pdbid_ligid = f"{self.pdb_id}_{self.ccd_code}".upper()
+ if BINDING_AFFINITY is None:
+ data_dir = Path(get_config().data.plinder_dir)
+ BINDING_AFFINITY = get_binding_affinity(data_dir)
+ match = matched_affinity(
+ BINDING_AFFINITY.get(pdbid_ligid, []), self.receptor_seqres
+ )
+ return match[0] if match else None
+
+ def identify_artifacts_cofactors_and_other(self) -> None:
+ """Set ``is_artifact``, ``is_cofactor``, and ``is_other`` flags in-place."""
+ assert COFACTORS is not None
+ assert ARTIFACTS is not None
+ # Match by CCD code OR by structure (RDKit SMILES), so a ligand that is
+ # the same molecule under a different current code is still classified.
+ # COFACTOR_SMILES / ARTIFACT_SMILES are None if only the code sets were
+ # populated (e.g. a test that patches COFACTORS/ARTIFACTS directly) โ
+ # fall back to code-only matching then.
+ if ccd_components(self.ccd_code) in COFACTORS or (
+ COFACTOR_SMILES is not None and self.smiles in COFACTOR_SMILES
+ ):
+ self.is_cofactor = True
+ if ccd_components(self.ccd_code) in ARTIFACTS or (
+ ARTIFACT_SMILES is not None and self.smiles in ARTIFACT_SMILES
+ ):
+ self.in_artifact_list = True
+
+ if self.is_ion:
+ self.is_artifact = False
+ elif self.in_artifact_list:
+ self.is_artifact = True
+ elif lig_has_dummies(self.ccd_code):
+ # check for dummy list including composites, too!
+ self.is_artifact = True
+ elif self._is_multi_residue and any(
+ (
+ self.is_oligosaccharide,
+ self.is_oligonucleotide,
+ self.is_oligopeptide,
+ )
+ ):
+ # Small-molecule charge and linker cutoffs do not describe
+ # recognized oligomeric ligands. For example, a short peptide can
+ # legitimately exceed the formal-charge cutoff through Lys/Arg.
+ self.is_artifact = False
+ elif is_excluded_mol(self.smiles):
+ self.is_artifact = True
+ else:
+ self.is_artifact = False
+
+ # reset: artifacts should not count to other ligand class definitions
+ if self.is_artifact:
+ self.is_ion = False
+ self.is_monosaccharide = False
+ self.is_oligosaccharide = False
+ self.is_mononucleotide = False
+ self.is_oligonucleotide = False
+ self.is_monopeptide = False
+ self.is_oligopeptide = False
+ self.is_cofactor = False
+ self.is_lipinski = False
+ self.is_fragment = False
+ self.is_covalent = False
+
+ # Indicator of whether a ligand type is not any recognized class.
+ self.is_other = not any(
+ [
+ self.is_invalid,
+ self.is_ion,
+ self.is_monosaccharide,
+ self.is_oligosaccharide,
+ self.is_mononucleotide,
+ self.is_oligonucleotide,
+ self.is_monopeptide,
+ self.is_oligopeptide,
+ self.is_artifact,
+ self.is_cofactor,
+ self.is_lipinski,
+ self.is_fragment,
+ self.is_covalent,
+ ]
+ )
+
+ def format_chains(
+ self,
+ chain_type: str,
+ chains: dict[str, Chain],
+ ) -> dict[str, ty.Any]:
+ """
+ Format chains for pd.DataFrame
+
+ Parameters
+ ----------
+ self : Ligand
+ Ligand object
+ chain_type: str
+ Chain tyoe
+ chains: dict[str, Chain]
+ Chain id : chain mapping
+ Returns
+ -------
+ dict[str, str]
+ """
+ if chain_type == "protein":
+ sub_chains = self.protein_chains_asym_id
+ elif chain_type == "interacting_ligand":
+ sub_chains = self.interacting_ligands
+ elif chain_type == "neighboring_ligand":
+ sub_chains = self.neighboring_ligands
+ else:
+ raise ValueError(f"chain_type={chain_type} not understood")
+ sub_chains_data = [
+ chains[instance_chain.split(".", maxsplit=1)[-1]].format(
+ int(instance_chain.split(".")[0])
+ )
+ for instance_chain in sub_chains
+ ]
+ data: dict[str, list[ty.Any]] = defaultdict(list)
+ if len(sub_chains_data) == 0:
+ return {}
+ for sub_chain in sub_chains_data:
+ for key in sub_chain:
+ data[f"ligand_{chain_type}_chains_{key}"].append(sub_chain[key])
+ return data
+
+ def format_residues(
+ self, residue_type: str, chains: dict[str, Chain]
+ ) -> dict[str, list[str]]:
+ """
+ Format residues for pd.DataFrame
+
+ Parameters
+ ----------
+ self : Ligand
+ Ligand object
+ residue_type : str
+ Chain tyoe
+ chains : dict[str, Chain]
+ Chain id : chain mapping
+
+ Returns
+ -------
+ List of residues in the format
+ ``.___``
+ ``_``.
+ dict[str, list[str]]
+ """
+ if residue_type == "interacting":
+ residues = self.interacting_residues
+ elif residue_type == "neighboring":
+ residues = self.neighboring_residues
+ res = []
+ for instance_chain in residues:
+ _, chain = instance_chain.split(".", maxsplit=1)
+ for residue_number in residues[instance_chain]:
+ res.append(
+ f"{instance_chain}_{residue_number}_{chains[chain].residues[residue_number].index}_{chains[chain].residues[residue_number].auth_number}_{chains[chain].residues[residue_number].insertion_code}"
+ ) # TODO: move some of this logic to Residue
+ return {f"ligand_{residue_type}_residues": res}
+
+ def format_interactions(self) -> dict[str, list[str]]:
+ """
+ Format interactions for pd.DataFrame
+
+ Parameters
+ ----------
+ self : Ligand
+
+ Returns
+ -------
+ List of interactions in the format "__"
+ dict[str, list[str]]
+
+ """
+ interactions: list[str] = []
+ for chain in self.interactions:
+ for residue in self.interactions[chain]:
+ for interaction in self.interactions[chain][int(residue)]:
+ interactions.append(f"{chain}_{residue}_{interaction}")
+ return {"ligand_interactions": interactions}
+
+ def format(self, chains: dict[str, Chain]) -> dict[str, ty.Any]:
+ """Serialize ligand annotations to a flat dict for DataFrame export."""
+ data: dict[str, ty.Any] = defaultdict(str)
+ for field, (description, _) in self.get_descriptions_and_types().items():
+ if description_excluded_from_flat_export(description):
+ continue
+ name = f"ligand_{field}"
+ data[name] = getattr(self, field)
+
+ # These internal selections are required to reconstruct a system
+ # deterministically from the source mmCIF and an annotation row.
+ data["ligand_residue_numbers"] = sorted(set(self.residue_numbers))
+ # Every instance-chain this ligand spans โ a multi-chain covalent ligand
+ # spans several โ so the source-reconstruction SDF covers the whole
+ # molecule, not just the primary chain.
+ data["ligand_instance_chains"] = sorted(self._members)
+ data["ligand_water_residues"] = sorted(
+ f"{chain_id}_{residue_number}"
+ for chain_id, residue_numbers in self.waters.items()
+ for residue_number in set(residue_numbers)
+ )
+
+ # interactions
+ data.update(self.format_interactions())
+ # contact areas: one chain list and one aligned area list
+ data["ligand_contact_area_chains"] = list(self.chain_contact_areas)
+ data["ligand_contact_area_values"] = list(self.chain_contact_areas.values())
+ from plinder.data.annotations.cif_utils import residue_address
+
+ # residue address as in covalent_linkages; an ASU fact, so no instance
+ pocket_unresolved: set[str] = set()
+ for instance_chain, residue_numbers in self.neighboring_residues.items():
+ asym_id = instance_chain.split(".", maxsplit=1)[-1]
+ for residue_number in residue_numbers:
+ residue = chains[asym_id].residues[residue_number]
+ auth_seq = residue.auth_number
+ if residue.insertion_code not in {"", ".", "?"}:
+ auth_seq = f"{auth_seq}{residue.insertion_code}"
+ pocket_unresolved.update(
+ residue_address(
+ auth_seq, residue.name, asym_id, residue_number, atom_name
+ )
+ for atom_name in residue.unresolved_atom_names
+ )
+ data["ligand_pocket_unresolved_atoms"] = sorted(pocket_unresolved)
+ # chains
+ data.update(
+ {"ligand_auth_id": chains[self.asym_id].auth_id}
+ ) # not a cached_property b/c it needs chains!
+ for chain_type in [
+ "protein",
+ "interacting_ligand",
+ "neighboring_ligand",
+ ]:
+ data.update(self.format_chains(chain_type, chains))
+ # residues
+ for residue_type in ["interacting", "neighboring"]:
+ data.update(self.format_residues(residue_type, chains))
+
+ return data
diff --git a/src/plinder/data/annotations/mmpdb_utils.py b/src/plinder/data/annotations/mmpdb_utils.py
new file mode 100644
index 000000000..a46122c62
--- /dev/null
+++ b/src/plinder/data/annotations/mmpdb_utils.py
@@ -0,0 +1,486 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Build a compact matched-molecular-pair table for unique ligand SMILES."""
+
+from __future__ import annotations
+
+import gzip
+import hashlib
+import json
+import shutil
+import subprocess
+from concurrent.futures import ThreadPoolExecutor
+from importlib.metadata import PackageNotFoundError, version
+from pathlib import Path
+from tempfile import TemporaryDirectory
+from typing import Sequence, cast
+
+import pandas as pd
+import pyarrow as pa
+import pyarrow.parquet as pq
+from rdkit import Chem
+from rdkit.rdBase import BlockLogs
+
+from plinder.core.utils import schemas
+from plinder.core.utils.log import setup_logger
+from plinder.core.utils.sanitize import mol_from_smiles
+from plinder.core.utils.sanitize import sanitize as peppr_sanitize
+
+LOG = setup_logger(__name__)
+
+
+def _mmpdb_version() -> str:
+ try:
+ return version("mmpdb")
+ except PackageNotFoundError:
+ return "unknown"
+
+
+def _empty_pair_table() -> pa.Table:
+ return pa.Table.from_arrays(
+ [pa.array([], type=field.type) for field in schemas.LIGAND_MMP_PAIR_SCHEMA],
+ schema=schemas.LIGAND_MMP_PAIR_SCHEMA,
+ )
+
+
+def _ligand_table(
+ fingerprint_path: Path,
+) -> tuple[pd.DataFrame, list[dict[str, int | str]]]:
+ if not fingerprint_path.is_file():
+ raise FileNotFoundError(
+ "matched molecular pairs require the unique ligand fingerprint table: "
+ f"{fingerprint_path}"
+ )
+ ligands = pd.read_parquet(
+ fingerprint_path,
+ columns=["ligand_smiles_id", "ligand_rdkit_canonical_smiles"],
+ )
+ if ligands["ligand_smiles_id"].isna().any():
+ raise ValueError("unique ligand SMILES contain missing ligand_smiles_id values")
+ if ligands["ligand_rdkit_canonical_smiles"].isna().any():
+ raise ValueError("unique ligand SMILES contain missing structures")
+ if ligands["ligand_smiles_id"].duplicated().any():
+ raise ValueError(
+ "unique ligand SMILES contain duplicate ligand_smiles_id values"
+ )
+ if ligands["ligand_rdkit_canonical_smiles"].duplicated().any():
+ raise ValueError("unique ligand SMILES contain duplicate structures")
+
+ ligands = ligands.sort_values("ligand_smiles_id").reset_index(drop=True)
+ ligands["ligand_smiles_id"] = ligands["ligand_smiles_id"].astype("int32")
+ ligands["ligand_rdkit_canonical_smiles"] = ligands[
+ "ligand_rdkit_canonical_smiles"
+ ].astype(str)
+ heavy_atom_counts: list[int] = []
+ included_rows: list[int] = []
+ exclusions: list[dict[str, int | str]] = []
+ with BlockLogs():
+ for row, (ligand_id, smiles) in enumerate(
+ ligands[["ligand_smiles_id", "ligand_rdkit_canonical_smiles"]].itertuples(
+ index=False, name=None
+ )
+ ):
+ # mmpdb itself uses the strict parser. Do not rewrite stored chemistry
+ # to make it fragmentable, or reject the entire release for a molecule
+ # that the rest of ingest supports.
+ mol = Chem.MolFromSmiles(smiles)
+ reason = None
+ if mol is None:
+ if mol_from_smiles(smiles) is None:
+ raise ValueError(
+ f"ligand_smiles_id {ligand_id} has invalid canonical SMILES"
+ )
+ reason = "unsupported_by_mmpdb_smiles_parser"
+ elif any(
+ str(bond.GetBondType()).startswith("DATIVE") for bond in mol.GetBonds()
+ ):
+ reason = "metal_dative_bonds"
+ if reason is not None:
+ exclusions.append(
+ {
+ "ligand_smiles_id": int(ligand_id),
+ "smiles": smiles,
+ "reason": reason,
+ }
+ )
+ continue
+ included_rows.append(row)
+ heavy_atom_counts.append(mol.GetNumHeavyAtoms())
+ ligands = ligands.iloc[included_rows].reset_index(drop=True)
+ ligands["num_heavy_atoms"] = pd.Series(heavy_atom_counts, dtype="int16")
+ if exclusions:
+ LOG.info(
+ "excluding %d ligand SMILES from MMP generation; "
+ "IDs and reasons are recorded in the MMP manifest",
+ len(exclusions),
+ )
+ return ligands, exclusions
+
+
+def _ligand_signature(ligands: pd.DataFrame) -> str:
+ digest = hashlib.sha256()
+ for ligand_id, smiles in ligands[
+ ["ligand_smiles_id", "ligand_rdkit_canonical_smiles"]
+ ].itertuples(index=False, name=None):
+ digest.update(str(int(ligand_id)).encode())
+ digest.update(b"\0")
+ digest.update(smiles.encode())
+ digest.update(b"\n")
+ return digest.hexdigest()
+
+
+def _run_command(arguments: Sequence[str], *, cwd: Path) -> None:
+ LOG.info("running %s", " ".join(arguments))
+ try:
+ completed = subprocess.run(
+ list(arguments),
+ cwd=cwd,
+ check=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ text=True,
+ )
+ except subprocess.CalledProcessError as exc:
+ output = (exc.stdout or "").strip()
+ if len(output) > 8_000:
+ output = output[-8_000:]
+ raise RuntimeError(
+ f"mmpdb command failed ({' '.join(arguments)}):\n{output}"
+ ) from exc
+ if completed.stdout:
+ LOG.info("mmpdb: %s", completed.stdout.rstrip())
+
+
+def _run_commands(
+ commands: Sequence[Sequence[str]], *, cwd: Path, workers: int
+) -> None:
+ if not commands:
+ return
+ with ThreadPoolExecutor(max_workers=min(workers, len(commands))) as executor:
+ futures = [
+ executor.submit(_run_command, command, cwd=cwd) for command in commands
+ ]
+ for future in futures:
+ future.result()
+
+
+def _gzip_has_rows(path: Path) -> bool:
+ with gzip.open(path, "rb") as handle:
+ return bool(handle.read(1))
+
+
+def _generate_pair_files(
+ *, ligands: pd.DataFrame, work_dir: Path, threads: int, executable: str
+) -> list[Path]:
+ smiles_path = work_dir / "ligands.smi"
+ ligands[["ligand_rdkit_canonical_smiles", "ligand_smiles_id"]].to_csv(
+ smiles_path, sep="\t", header=False, index=False
+ )
+ if ligands.empty:
+ return []
+
+ shard_count = min(threads, len(ligands))
+ _run_command(
+ [executable, "smi_split", "-n", str(shard_count), smiles_path.name],
+ cwd=work_dir,
+ )
+ smiles_shards = sorted(work_dir.glob("ligands.[0-9][0-9][0-9][0-9].smi"))
+ if not smiles_shards:
+ raise RuntimeError("mmpdb did not create any SMILES shards")
+ _run_commands(
+ [[executable, "fragment", "-j", "1", shard.name] for shard in smiles_shards],
+ cwd=work_dir,
+ workers=threads,
+ )
+ fragment_files = sorted(work_dir.glob("ligands.[0-9][0-9][0-9][0-9].fragdb"))
+ if len(fragment_files) != len(smiles_shards):
+ raise RuntimeError(
+ "mmpdb fragmentation did not produce one database per SMILES shard"
+ )
+
+ _run_command(
+ [
+ executable,
+ "fragdb_partition",
+ "-n",
+ str(shard_count),
+ "--template",
+ "partition.{i:04}.fragdb",
+ *[path.name for path in fragment_files],
+ ],
+ cwd=work_dir,
+ )
+ partition_files = sorted(work_dir.glob("partition.[0-9][0-9][0-9][0-9].fragdb"))
+ if not partition_files:
+ return []
+ _run_commands(
+ [
+ [
+ executable,
+ "index",
+ "--out",
+ "csv.gz",
+ "-o",
+ partition.with_suffix(".csv.gz").name,
+ partition.name,
+ ]
+ for partition in partition_files
+ ],
+ cwd=work_dir,
+ workers=threads,
+ )
+ pair_files = sorted(work_dir.glob("partition.[0-9][0-9][0-9][0-9].csv.gz"))
+ if len(pair_files) != len(partition_files):
+ raise RuntimeError("mmpdb indexing did not produce one pair file per partition")
+ return [path for path in pair_files if _gzip_has_rows(path)]
+
+
+def _core_table(shared_cores: Sequence[str]) -> pd.DataFrame:
+ rows: list[tuple[str, int, int]] = []
+ with BlockLogs():
+ for shared_core in shared_cores:
+ mol = Chem.MolFromSmiles(shared_core, sanitize=False)
+ if mol is not None:
+ peppr_sanitize(mol)
+ else:
+ mol = Chem.MolFromSmarts(shared_core)
+ if mol is None:
+ raise ValueError(
+ f"mmpdb emitted an unreadable shared core: {shared_core}"
+ )
+ rows.append((shared_core, shared_core.count("*"), mol.GetNumHeavyAtoms()))
+ return pd.DataFrame(
+ rows,
+ columns=[
+ "shared_core_smiles",
+ "num_cuts",
+ "shared_core_num_heavy_atoms",
+ ],
+ ).astype(
+ {
+ "num_cuts": "int8",
+ "shared_core_num_heavy_atoms": "int16",
+ }
+ )
+
+
+def _sql_paths(paths: Sequence[Path]) -> str:
+ return ", ".join(
+ f"'{path.as_posix().replace(chr(39), chr(39) * 2)}'" for path in paths
+ )
+
+
+def _write_pair_parquet(
+ *, pair_files: Sequence[Path], ligands: pd.DataFrame, output_path: Path
+) -> None:
+ if not pair_files:
+ pq.write_table(_empty_pair_table(), output_path, compression="zstd")
+ return
+
+ import duckdb
+
+ connection = duckdb.connect()
+ raw_path = pair_files[0].parent / "raw_pairs.parquet"
+ raw_path_sql = raw_path.as_posix().replace("'", "''")
+ pair_paths_sql = _sql_paths(pair_files)
+ connection.execute(
+ f"""
+ COPY (
+ SELECT
+ try_cast(ligand_smiles_id_1 AS INTEGER) AS ligand_smiles_id_1,
+ try_cast(ligand_smiles_id_2 AS INTEGER) AS ligand_smiles_id_2,
+ transformation,
+ shared_core_smiles
+ FROM read_csv(
+ [{pair_paths_sql}],
+ delim='\t',
+ header=false,
+ columns={{
+ 'raw_smiles_1': 'VARCHAR',
+ 'raw_smiles_2': 'VARCHAR',
+ 'ligand_smiles_id_1': 'VARCHAR',
+ 'ligand_smiles_id_2': 'VARCHAR',
+ 'transformation': 'VARCHAR',
+ 'shared_core_smiles': 'VARCHAR'
+ }}
+ )
+ ) TO '{raw_path_sql}'
+ (FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 1_000_000)
+ """
+ )
+ invalid_ids = cast(
+ tuple[int],
+ connection.execute(
+ f"""
+ SELECT count(*)
+ FROM read_parquet('{raw_path_sql}')
+ WHERE ligand_smiles_id_1 IS NULL OR ligand_smiles_id_2 IS NULL
+ """
+ ).fetchone(),
+ )[0]
+ if invalid_ids:
+ connection.close()
+ raise ValueError(f"mmpdb emitted {invalid_ids} non-integer ligand IDs")
+
+ shared_cores = (
+ connection.execute(
+ f"""
+ SELECT DISTINCT shared_core_smiles
+ FROM read_parquet('{raw_path_sql}')
+ ORDER BY shared_core_smiles
+ """
+ )
+ .fetch_df()["shared_core_smiles"]
+ .tolist()
+ )
+ core_table = _core_table(shared_cores)
+ ligand_lookup = ligands.rename(
+ columns={
+ "ligand_rdkit_canonical_smiles": "ligand_smiles",
+ "num_heavy_atoms": "ligand_num_heavy_atoms",
+ }
+ )[["ligand_smiles_id", "ligand_smiles", "ligand_num_heavy_atoms"]]
+ connection.register("ligand_lookup", ligand_lookup)
+ connection.register("core_lookup", core_table)
+ missing_ids = cast(
+ tuple[int],
+ connection.execute(
+ f"""
+ SELECT count(*)
+ FROM read_parquet('{raw_path_sql}') raw
+ LEFT JOIN ligand_lookup ligand_1
+ ON raw.ligand_smiles_id_1 = ligand_1.ligand_smiles_id
+ LEFT JOIN ligand_lookup ligand_2
+ ON raw.ligand_smiles_id_2 = ligand_2.ligand_smiles_id
+ WHERE ligand_1.ligand_smiles_id IS NULL
+ OR ligand_2.ligand_smiles_id IS NULL
+ """
+ ).fetchone(),
+ )[0]
+ if missing_ids:
+ connection.close()
+ raise ValueError(
+ f"mmpdb emitted {missing_ids} pairs with unknown ligand_smiles_id values"
+ )
+
+ output_sql = output_path.as_posix().replace("'", "''")
+ connection.execute(
+ f"""
+ COPY (
+ SELECT DISTINCT
+ raw.ligand_smiles_id_1::INTEGER AS ligand_smiles_id_1,
+ raw.ligand_smiles_id_2::INTEGER AS ligand_smiles_id_2,
+ ligand_1.ligand_smiles::VARCHAR AS ligand_smiles_1,
+ ligand_2.ligand_smiles::VARCHAR AS ligand_smiles_2,
+ raw.transformation::VARCHAR AS transformation,
+ raw.shared_core_smiles::VARCHAR AS shared_core_smiles,
+ core.num_cuts::TINYINT AS num_cuts,
+ core.shared_core_num_heavy_atoms::SMALLINT
+ AS shared_core_num_heavy_atoms,
+ ligand_1.ligand_num_heavy_atoms::SMALLINT
+ AS ligand_1_num_heavy_atoms,
+ ligand_2.ligand_num_heavy_atoms::SMALLINT
+ AS ligand_2_num_heavy_atoms,
+ cast(
+ core.shared_core_num_heavy_atoms::FLOAT
+ / nullif(ligand_1.ligand_num_heavy_atoms, 0)
+ AS FLOAT
+ ) AS ligand_1_shared_core_fraction,
+ cast(
+ core.shared_core_num_heavy_atoms::FLOAT
+ / nullif(ligand_2.ligand_num_heavy_atoms, 0)
+ AS FLOAT
+ ) AS ligand_2_shared_core_fraction
+ FROM read_parquet('{raw_path_sql}') raw
+ INNER JOIN ligand_lookup ligand_1
+ ON raw.ligand_smiles_id_1 = ligand_1.ligand_smiles_id
+ INNER JOIN ligand_lookup ligand_2
+ ON raw.ligand_smiles_id_2 = ligand_2.ligand_smiles_id
+ INNER JOIN core_lookup core USING (shared_core_smiles)
+ ORDER BY
+ ligand_smiles_id_1,
+ ligand_smiles_id_2,
+ shared_core_smiles,
+ transformation
+ ) TO '{output_sql}'
+ (FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 1_000_000)
+ """
+ )
+ connection.close()
+
+ actual_schema = pq.read_schema(output_path)
+ if not actual_schema.equals(schemas.LIGAND_MMP_PAIR_SCHEMA):
+ raise ValueError(
+ f"ligand MMP output schema differs from the release schema: {actual_schema}"
+ )
+
+
+def make_ligand_mmp_pairs(
+ *,
+ data_dir: Path,
+ scratch_dir: Path,
+ threads: int = 4,
+ force_update: bool = False,
+) -> Path:
+ """Generate matched molecular pairs for supported unique proper-ligand SMILES.
+
+ The manifest records input exclusions for chemistry that mmpdb cannot handle.
+ These exclusions apply only to MMP generation, not to the other ligand tables.
+ """
+ if threads < 1:
+ raise ValueError("MMP generation threads must be positive")
+ fingerprint_path = data_dir / "fingerprints" / "ligands_per_smiles.parquet"
+ output_path = data_dir / "index" / "ligand_mmp_pairs.parquet"
+ manifest_path = data_dir / "index" / "ligand_mmp_pairs.manifest.json"
+ ligands, exclusions = _ligand_table(fingerprint_path)
+ manifest = {
+ "mmpdb_version": _mmpdb_version(),
+ "ligand_signature": _ligand_signature(ligands),
+ "input_exclusions": exclusions,
+ }
+ if not force_update and output_path.is_file() and manifest_path.is_file():
+ try:
+ cached_manifest = json.loads(manifest_path.read_text())
+ schema_is_current = pq.read_schema(output_path).equals(
+ schemas.LIGAND_MMP_PAIR_SCHEMA
+ )
+ except (OSError, ValueError, json.JSONDecodeError):
+ schema_is_current = False
+ cached_manifest = None
+ if cached_manifest == manifest and schema_is_current:
+ LOG.info("ligand MMP pairs already match the unique ligand SMILES")
+ return output_path
+
+ executable = shutil.which("mmpdb")
+ if executable is None:
+ raise RuntimeError(
+ "mmpdb is required to generate ligand MMP pairs; install the PLINDER "
+ "data dependencies"
+ )
+ output_path.parent.mkdir(exist_ok=True, parents=True)
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ temporary_output = output_path.with_suffix(".tmp.parquet")
+ temporary_output.unlink(missing_ok=True)
+ try:
+ with TemporaryDirectory(prefix="plinder-mmp-", dir=scratch_dir) as work:
+ pair_files = _generate_pair_files(
+ ligands=ligands,
+ work_dir=Path(work),
+ threads=threads,
+ executable=executable,
+ )
+ _write_pair_parquet(
+ pair_files=pair_files,
+ ligands=ligands,
+ output_path=temporary_output,
+ )
+ temporary_output.replace(output_path)
+ except BaseException:
+ temporary_output.unlink(missing_ok=True)
+ raise
+
+ temporary_manifest = manifest_path.with_suffix(".tmp.json")
+ temporary_manifest.write_text(json.dumps(manifest, indent=2, sort_keys=True) + "\n")
+ temporary_manifest.replace(manifest_path)
+ LOG.info("wrote ligand MMP pairs to %s", output_path)
+ return output_path
diff --git a/src/plinder/data/annotations/protein_utils.py b/src/plinder/data/annotations/protein_utils.py
new file mode 100644
index 000000000..36c1a49e5
--- /dev/null
+++ b/src/plinder/data/annotations/protein_utils.py
@@ -0,0 +1,780 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from __future__ import annotations
+
+import functools
+from collections import Counter
+from collections.abc import Iterable, Mapping
+from functools import cached_property
+from typing import TYPE_CHECKING, Any, NamedTuple
+
+import biotite.structure as struc
+import biotite.structure.io.pdbx as pdbx
+import numpy as np
+from pydantic import ConfigDict, Field
+
+from plinder.core.utils.log import setup_logger
+from plinder.data.annotations.get_ligand_validation import (
+ ResidueListValidation,
+ ResidueValidation,
+ ResidueValidationThresholds,
+)
+from plinder.data.annotations.utils import DocBaseModel
+
+if TYPE_CHECKING:
+ from PDBValidation.Validation import PDBValidation
+
+
+@functools.cache
+def _standard_aa_names() -> set[str]:
+ """Standard amino acid 3-letter codes."""
+ import biotite.structure.info as info
+
+ return set(info.amino_acid_names())
+
+
+@functools.cache
+def _standard_na_names() -> set[str]:
+ """Standard nucleotide 3-letter codes (RNA + DNA)."""
+ return {"A", "C", "G", "U", "DA", "DC", "DG", "DT", "DU"}
+
+
+@functools.cache
+def _ccd_parent_components() -> dict[str, str]:
+ """``comp_id -> mon_nstd_parent_comp_id`` from biotite's bundled CCD."""
+ from biotite.structure.info import ccd as bundled_ccd
+
+ chem_comp = bundled_ccd.get_ccd()["chem_comp"]
+ return dict(
+ zip(
+ chem_comp["id"].as_array(str),
+ chem_comp["mon_nstd_parent_comp_id"].as_array(str),
+ )
+ )
+
+
+LOG = setup_logger(__name__)
+
+_CANONICAL_MONOMERS = frozenset(
+ {
+ "ALA", "ARG", "ASN", "ASP", "CYS", "GLN", "GLU", "GLY", "HIS", "ILE",
+ "LEU", "LYS", "MET", "PHE", "PRO", "SER", "THR", "TRP", "TYR", "VAL",
+ "UNK", "A", "C", "G", "U", "I", "N", "DA", "DC", "DG", "DT", "DU", "DI", "DN",
+ }
+) # fmt: skip
+
+
+def get_modified_residues(
+ block: pdbx.CIFBlock,
+ residue_author_ids: Mapping[str, Mapping[int, tuple[str, str]]] | None = None,
+) -> dict[str, list[str]]:
+ """Non-canonical SEQRES monomers per label asym.
+
+ Entries are the :func:`~plinder.data.annotations.cif_utils.residue_address`
+ ``{auth_seq}:{comp_id}:{asym}:{label_seq}`` followed by ``>{parent}`` and
+ `` (details)`` from ``pdbx_struct_mod_residue`` when present. Built from
+ ``entity_poly_seq`` (``comp_id`` is its ``mon_id``), so unresolved positions
+ are included with ``?`` as ``auth_seq``. Parent from
+ ``pdbx_struct_mod_residue``, else the CCD, else ``?``.
+ """
+ from plinder.data.annotations.cif_utils import _iter_category_rows, residue_address
+
+ if residue_author_ids is None:
+ _, residue_author_ids = get_atom_site_author_ids(block)
+ modified_by_entity: dict[str, list[tuple[int, str]]] = {}
+ for row in _iter_category_rows(
+ block, "entity_poly_seq", ["entity_id", "num", "mon_id"]
+ ):
+ if row["mon_id"] in _CANONICAL_MONOMERS:
+ continue
+ try:
+ number = int(row["num"])
+ except ValueError:
+ continue
+ modified_by_entity.setdefault(row["entity_id"], []).append(
+ (
+ number,
+ row["mon_id"],
+ )
+ )
+ if not modified_by_entity:
+ return {}
+ missing = {"", ".", "?"}
+ deposited: dict[tuple[str, int, str], tuple[str, str]] = {}
+ for row in _iter_category_rows(
+ block,
+ "pdbx_struct_mod_residue",
+ ["label_asym_id", "label_seq_id", "label_comp_id", "parent_comp_id", "details"],
+ ):
+ try:
+ key = (row["label_asym_id"], int(row["label_seq_id"]), row["label_comp_id"])
+ except ValueError:
+ continue
+ deposited[key] = (row["parent_comp_id"], row["details"])
+ ccd_parents = _ccd_parent_components()
+ modified: dict[str, list[str]] = {}
+ for row in _iter_category_rows(block, "struct_asym", ["id", "entity_id"]):
+ positions = modified_by_entity.get(row["entity_id"])
+ if not positions:
+ continue
+ asym_id = row["id"]
+ author_ids = residue_author_ids.get(asym_id, {})
+ entries = []
+ for number, mon_id in sorted(positions):
+ parent, details = deposited.get((asym_id, number, mon_id), ("", ""))
+ if parent in missing:
+ parent = ccd_parents.get(mon_id, "?")
+ if parent in missing:
+ parent = "?"
+ auth_seq, insertion = author_ids.get(number, ("?", "."))
+ if insertion not in missing:
+ auth_seq = f"{auth_seq}{insertion}"
+ entry = f"{residue_address(auth_seq, mon_id, asym_id, number)}>{parent}"
+ if details not in missing:
+ entry = f"{entry} ({details})"
+ entries.append(entry)
+ modified[asym_id] = entries
+ return modified
+
+
+class UnobservedAtom(NamedTuple):
+ """A ``pdbx_unobs_or_zero_occ_atoms`` row in ``residue_address`` fields."""
+
+ comp_id: str
+ auth_seq: str # auth_seq_id with insertion code
+ label_seq: str # label_seq_id; "." for non-polymer and branched residues
+ atom_name: str
+ zero_occupancy: bool # occupancy_flag 0: modelled at zero occupancy, not absent
+
+
+def get_unobserved_atoms(
+ block: pdbx.CIFBlock,
+) -> tuple[dict[str, dict[int, list[str]]], dict[str, list[UnobservedAtom]]] | None:
+ """Model-1 rows of ``pdbx_unobs_or_zero_occ_atoms``, or ``None`` when absent.
+
+ Returns ``(asym -> label_seq_id -> atom names)`` for polymer residues and
+ ``(asym -> [UnobservedAtom])`` for every row.
+ """
+ from plinder.data.annotations.cif_utils import _iter_category_rows
+
+ category = "pdbx_unobs_or_zero_occ_atoms"
+ if category not in block:
+ return None
+ columns = [
+ "PDB_model_num",
+ "polymer_flag",
+ "label_asym_id",
+ "label_comp_id",
+ "label_seq_id",
+ "auth_seq_id",
+ "PDB_ins_code",
+ "label_atom_id",
+ "occupancy_flag",
+ ]
+ absent = [column for column in columns if column not in block[category]]
+ if absent:
+ LOG.warning(f"{category} lacks {absent}; ignoring the category")
+ return None
+ missing = {"", ".", "?"}
+ by_residue: dict[str, dict[int, list[str]]] = {}
+ by_chain: dict[str, list[UnobservedAtom]] = {}
+ for row in _iter_category_rows(block, category, columns):
+ if row["PDB_model_num"] not in {"1", "?", "."}:
+ continue
+ asym_id = row["label_asym_id"]
+ auth_seq = row["auth_seq_id"]
+ if row["PDB_ins_code"] not in missing:
+ auth_seq = f"{auth_seq}{row['PDB_ins_code']}"
+ is_polymer = row["polymer_flag"] == "Y"
+ by_chain.setdefault(asym_id, []).append(
+ UnobservedAtom(
+ row["label_comp_id"],
+ auth_seq,
+ row["label_seq_id"] if is_polymer else ".",
+ row["label_atom_id"],
+ row["occupancy_flag"] == "0",
+ )
+ )
+ try:
+ number = int(row["label_seq_id"])
+ except ValueError:
+ continue
+ by_residue.setdefault(asym_id, {}).setdefault(number, []).append(
+ row["label_atom_id"]
+ )
+ return by_residue, by_chain
+
+
+def _get_chain_type_from_cif(block: pdbx.CIFBlock, entity_id: str) -> str:
+ """Get chain type string from CIF entity/entity_poly categories."""
+ # Try _entity_poly.type first
+ if "entity_poly" in block:
+ ep = block["entity_poly"]
+ ep_ids = ep["entity_id"].as_array()
+ ep_types = ep["type"].as_array()
+ for i, eid in enumerate(ep_ids):
+ if eid == entity_id:
+ return str(ep_types[i])
+ # Fall back to _entity.type
+ if "entity" in block:
+ ent = block["entity"]
+ ent_ids = ent["id"].as_array()
+ ent_types = ent["type"].as_array()
+ for i, eid in enumerate(ent_ids):
+ if eid == entity_id:
+ return str(ent_types[i])
+ return "unknown"
+
+
+def get_atom_site_author_ids(
+ block: pdbx.CIFBlock,
+) -> tuple[dict[str, str], dict[str, dict[int, tuple[str, str]]]]:
+ """Return author chain and residue IDs keyed by label-asym coordinates.
+
+ The residue mapping contains ``auth_seq_id`` and ``pdbx_PDB_ins_code`` for
+ each resolved ``(label_asym_id, label_seq_id)`` pair. Custom mmCIFs may
+ omit author fields, in which case the corresponding label IDs are used.
+ """
+ if "atom_site" not in block:
+ return {}, {}
+ atom_site = block["atom_site"]
+ if not {"label_asym_id", "label_seq_id"}.issubset(atom_site):
+ return {}, {}
+
+ label_asym_ids = atom_site["label_asym_id"].as_array()
+ label_seq_ids = atom_site["label_seq_id"].as_array()
+ auth_asym_ids = (
+ atom_site["auth_asym_id"].as_array()
+ if "auth_asym_id" in atom_site
+ else label_asym_ids
+ )
+ auth_seq_ids = (
+ atom_site["auth_seq_id"].as_array()
+ if "auth_seq_id" in atom_site
+ else label_seq_ids
+ )
+ insertion_codes = (
+ atom_site["pdbx_PDB_ins_code"].as_array()
+ if "pdbx_PDB_ins_code" in atom_site
+ else np.full(len(label_asym_ids), ".", dtype=object)
+ )
+
+ chain_auth_ids: dict[str, str] = {}
+ residue_author_ids: dict[str, dict[int, tuple[str, str]]] = {}
+ missing = {"", ".", "?"}
+ for label_asym, label_seq, auth_asym, auth_seq, insertion_code in zip(
+ label_asym_ids,
+ label_seq_ids,
+ auth_asym_ids,
+ auth_seq_ids,
+ insertion_codes,
+ ):
+ asym_id = str(label_asym)
+ author_chain = str(auth_asym)
+ if author_chain in missing:
+ author_chain = asym_id
+ chain_auth_ids.setdefault(asym_id, author_chain)
+ try:
+ residue_number = int(str(label_seq))
+ except ValueError:
+ # Non-polymer atoms use missing label_seq_id values and are not
+ # part of a receptor residue mapping.
+ continue
+ author_number = str(auth_seq)
+ if author_number in missing:
+ author_number = str(residue_number)
+ insertion = str(insertion_code)
+ if insertion in missing:
+ insertion = "."
+ residue_author_ids.setdefault(asym_id, {}).setdefault(
+ residue_number, (author_number, insertion)
+ )
+ return chain_auth_ids, residue_author_ids
+
+
+def get_seqres_from_cif(block: pdbx.CIFBlock) -> dict[str, str]:
+ """Extract SEQRES (one-letter sequences) per chain from CIF."""
+ seqres: dict[str, str] = {}
+ if "entity_poly" not in block:
+ return seqres
+ ep = block["entity_poly"]
+ if "pdbx_strand_id" not in ep or "pdbx_seq_one_letter_code_can" not in ep:
+ return seqres
+ strand_ids = ep["pdbx_strand_id"].as_array()
+ sequences = ep["pdbx_seq_one_letter_code_can"].as_array()
+ for strands, seq in zip(strand_ids, sequences):
+ # Clean up sequence (remove newlines, semicolons)
+ clean_seq = seq.replace("\n", "").replace(";", "").strip()
+ for chain_id in strands.split(","):
+ seqres[chain_id.strip()] = clean_seq
+ return seqres
+
+
+def _is_polypeptide(chain_type_str: str) -> bool:
+ return "polypeptide" in chain_type_str.lower()
+
+
+def _is_polynucleotide(chain_type_str: str) -> bool:
+ return (
+ "polyribonucleotide" in chain_type_str.lower()
+ or "polydeoxyribonucleotide" in chain_type_str.lower()
+ )
+
+
+def get_receptor_type(chain_types: Iterable[str]) -> str:
+ """Return a deterministic receptor-composition label for CIF chain types."""
+ components: set[str] = set()
+ for chain_type in chain_types:
+ normalized = chain_type.lower()
+ if "polypeptide" in normalized:
+ components.add("protein")
+ if "polydeoxyribonucleotide" in normalized:
+ components.add("dna")
+ if "polyribonucleotide" in normalized:
+ components.add("rna")
+ if not any(
+ marker in normalized
+ for marker in (
+ "polypeptide",
+ "polydeoxyribonucleotide",
+ "polyribonucleotide",
+ )
+ ):
+ components.add("other")
+ order = ("protein", "dna", "rna", "other")
+ return "+".join(component for component in order if component in components)
+
+
+def _is_water(chain_type_str: str) -> bool:
+ return "water" in chain_type_str.lower()
+
+
+def _is_polymer(chain_type_str: str) -> bool:
+ return "poly" in chain_type_str.lower()
+
+
+def sequences_match_core(seq_a: str, seq_b: str, min_coverage: float = 0.9) -> bool:
+ """Check that two sequences share an identical core (no internal mutations).
+
+ Allows terminal overhangs (N/C-term tags, signal peptides, construct
+ boundaries) but rejects any substitution in the aligned region.
+
+ Uses local alignment to find the best-scoring overlap, then verifies
+ that every aligned position is identical and the alignment covers at
+ least *min_coverage* of the shorter sequence.
+
+ Parameters
+ ----------
+ seq_a, seq_b : str
+ Protein sequences to compare.
+ min_coverage : float
+ Minimum fraction of the shorter sequence that must be aligned.
+
+ Returns
+ -------
+ bool
+ True if the core overlap is 100% identical and coverage is sufficient.
+ """
+ from biotite.sequence import ProteinSequence
+ from biotite.sequence.align import SubstitutionMatrix, align_optimal
+
+ if not seq_a or not seq_b:
+ return False
+ try:
+ s1 = ProteinSequence(seq_a)
+ s2 = ProteinSequence(seq_b)
+ except Exception:
+ return False
+ matrix = SubstitutionMatrix.std_protein_matrix()
+ alignments = align_optimal(s1, s2, matrix, local=True)
+ if not alignments:
+ return False
+ trace = alignments[0].trace
+ n_aligned = 0
+ n_identical = 0
+ for i, j in trace:
+ if i != -1 and j != -1:
+ n_aligned += 1
+ if s1[i] == s2[j]:
+ n_identical += 1
+ min_len = min(len(s1), len(s2))
+ return n_aligned == n_identical and n_aligned >= min_coverage * min_len
+
+
+def detect_ligand_chains(
+ entry: Any,
+ min_polymer_size: int = 12,
+) -> dict[str, str]:
+ """Detect which chains are ligands vs receptor polymers.
+
+ A polymer chain (protein, NA, saccharide) with >= min_polymer_size
+ residues is receptor. Everything else โ non-polymers, short
+ polymers, and BIRD-annotated chains โ is a ligand.
+
+ Default threshold of 12 is the minimum length for meaningful
+ sequence searches (MMseqs2/Foldseek).
+ """
+ ligand_chains = dict()
+ for chain_name, chain in entry.chains.items():
+ ct = chain.chain_type_str
+ if _is_water(ct):
+ continue
+
+ chain_length = len(chain.residues)
+ bird_id = list(chain.mappings.get("BIRD", {"": None}))[0]
+
+ # BIRD-annotated short chains are ligands irrespective of polymer type or length
+ if bird_id:
+ ligand_chains[chain_name] = ct
+ # Polymers >= threshold are receptor
+ elif _is_polymer(ct) and chain_length >= min_polymer_size:
+ continue
+ # Everything else is ligand
+ else:
+ ligand_chains[chain_name] = ct
+ return ligand_chains
+
+
+def detect_ligand_chains_from_cif(
+ block: pdbx.CIFBlock,
+ min_polymer_size: int = 12,
+) -> dict[str, str] | None:
+ """Preflight ligand-chain detection without building a bonded AtomArray.
+
+ The residue count mirrors :func:`detect_ligand_chains`: consecutive
+ ``label_seq_id`` values in model 1 correspond to the residue starts used
+ by :class:`Chain`. ``None`` means the CIF lacks the columns needed for a
+ reliable decision and the caller must fall back to full structure loading.
+ """
+ if "struct_asym" not in block or "atom_site" not in block:
+ return None
+ struct_asym = block["struct_asym"]
+ atom_site = block["atom_site"]
+ if not {"id", "entity_id"}.issubset(struct_asym) or not {
+ "label_asym_id",
+ "label_seq_id",
+ }.issubset(atom_site):
+ return None
+
+ atom_asym_ids = np.asarray(atom_site["label_asym_id"].as_array(), dtype=str)
+ atom_seq_ids = np.asarray(atom_site["label_seq_id"].as_array(), dtype=str)
+ if "pdbx_PDB_model_num" in atom_site:
+ model_numbers = np.asarray(
+ atom_site["pdbx_PDB_model_num"].as_array(), dtype=str
+ )
+ model_mask = model_numbers == "1"
+ atom_asym_ids = atom_asym_ids[model_mask]
+ atom_seq_ids = atom_seq_ids[model_mask]
+
+ valid_residue = ~np.isin(atom_seq_ids, (".", "?", ""))
+ residue_asym_ids = atom_asym_ids[valid_residue]
+ residue_seq_ids = atom_seq_ids[valid_residue]
+ residue_counts: Counter[str] = Counter()
+ if len(residue_asym_ids):
+ residue_starts = np.ones(len(residue_asym_ids), dtype=bool)
+ residue_starts[1:] = (residue_asym_ids[1:] != residue_asym_ids[:-1]) | (
+ residue_seq_ids[1:] != residue_seq_ids[:-1]
+ )
+ residue_counts.update(residue_asym_ids[residue_starts])
+
+ bird_asym_ids: set[str] = set()
+ if "pdbx_molecule" in block and "asym_id" in block["pdbx_molecule"]:
+ bird_asym_ids.update(
+ str(value) for value in block["pdbx_molecule"]["asym_id"].as_array()
+ )
+
+ observed_asym_ids = set(atom_asym_ids)
+ ligand_chains: dict[str, str] = {}
+ for asym_id, entity_id in zip(
+ struct_asym["id"].as_array(),
+ struct_asym["entity_id"].as_array(),
+ ):
+ asym_id = str(asym_id)
+ if asym_id not in observed_asym_ids:
+ continue
+ chain_type = _get_chain_type_from_cif(block, str(entity_id))
+ if _is_water(chain_type):
+ continue
+ if asym_id in bird_asym_ids:
+ ligand_chains[asym_id] = chain_type
+ elif _is_polymer(chain_type) and residue_counts[asym_id] >= min_polymer_size:
+ continue
+ else:
+ ligand_chains[asym_id] = chain_type
+ return ligand_chains
+
+
+class Residue(DocBaseModel):
+ chain: str
+ index: int
+ number: int
+ auth_number: str
+ insertion_code: str = "."
+ one_letter_code: str
+ name: str
+ chem_type: str
+ validation: ResidueValidation | None = None
+ selected_altcode: str = Field(
+ default=".",
+ exclude=True,
+ description="[EXCLUDE] Deposited alternate conformer selected for this residue",
+ )
+ unresolved_atom_names: list[str] = Field(
+ default_factory=list,
+ description="[EXCLUDE] label_atom_id of heavy atoms missing from the model (wwPDB unobserved-atom records, else CCD template minus resolved atoms)",
+ )
+ """Single residue in a polymer chain.
+
+ Parameters
+ ----------
+ chain : str
+ chain name
+ index : int
+ residue index
+ number : int
+ residue number
+ one_letter_code : str
+ residue one-letter code
+ name : str
+ residue name
+ chem_type: str
+ residue chemical type
+
+ Examples
+ --------
+ TODO: Add example
+ """
+
+
+class Chain(DocBaseModel):
+ asym_id: str = Field(description="Chain asymmetric id")
+ auth_id: str = Field(description="Chain author id")
+ entity_id: str = Field(description="Chain entity id")
+ chain_type_str: str = Field(
+ description="[EXCLUDE] Chain type string from CIF entity_poly.type"
+ )
+ residues: dict[int, Residue] = Field(
+ description="[EXCLUDE] Dictionary of residues in chain with keys as residue number"
+ )
+ length: int = Field(description="SEQRES length")
+ num_unresolved_residues: int = Field(
+ description="Number of unresolved residues (SEQRES length - len(residues))"
+ )
+ mappings: dict[str, dict[str, list[tuple[str, str] | None]]] = Field(
+ default_factory=dict,
+ description="[EXCLUDE] Mapping of metadata associated with chain with keys as chain asym id",
+ )
+ holo: bool = Field(
+ default=True, description="[EXCLUDE] Is the chain part of a holo system or not"
+ )
+ validation: ResidueListValidation | None = Field(
+ default=None,
+ description="[EXCLUDE] Crystal validation information for the residues in the chain",
+ )
+ modified_residues: list[str] = Field(
+ default_factory=list,
+ description="[EXCLUDE] Non-canonical SEQRES monomers as {auth_seq}:{comp_id}:{asym}:{label_seq}>{parent} (details); residue address as in ligand_covalent_linkages",
+ )
+
+ # Allow arbitrary types for cached properties
+ model_config = ConfigDict(
+ arbitrary_types_allowed=True,
+ )
+
+ @classmethod
+ def from_cif_data(
+ cls,
+ asym_id: str,
+ block: "pdbx.CIFBlock",
+ atoms: "struc.AtomArray",
+ seqres_length: int,
+ *,
+ entity_id: str | None = None,
+ auth_id: str | None = None,
+ chain_type_str: str | None = None,
+ residue_author_ids: Mapping[int, tuple[str, str]] | None = None,
+ modified_residues: list[str] | None = None,
+ unresolved_atoms: Mapping[int, list[str]] | None = None,
+ ) -> "Chain":
+ """Create Chain from biotite CIF data.
+
+ Parameters
+ ----------
+ asym_id : str
+ Chain asymmetric ID.
+ block : pdbx.CIFBlock
+ CIF data block for metadata lookup.
+ atoms : AtomArray
+ Atoms belonging to this chain.
+ seqres_length : int
+ SEQRES length.
+ entity_id, auth_id, chain_type_str : str, optional
+ Pre-indexed CIF metadata. Supplying these avoids repeatedly
+ scanning large ``struct_asym`` and entity categories when an
+ entry contains thousands of chains.
+ residue_author_ids : mapping, optional
+ Pre-indexed ``label_seq_id -> (auth_seq_id, insertion_code)``
+ mapping for this label-asym chain.
+ modified_residues : list[str], optional
+ Pre-indexed :func:`get_modified_residues` entries for this chain.
+ unresolved_atoms : mapping, optional
+ ``label_seq_id -> atom names`` from the wwPDB unobserved-atom records;
+ ``None`` derives them from the CCD template of each residue instead.
+ """
+ import biotite.structure as struc
+ import biotite.structure.info as info
+
+ from plinder.core.structure.ccd_template import unresolved_atoms_from_template
+
+ if auth_id is None or residue_author_ids is None:
+ chain_auth_ids, author_residues_by_chain = get_atom_site_author_ids(block)
+ if auth_id is None:
+ auth_id = chain_auth_ids.get(asym_id)
+ if residue_author_ids is None:
+ residue_author_ids = author_residues_by_chain.get(asym_id, {})
+
+ # Build residue dict
+ residues = {}
+ res_starts = struc.get_residue_starts(atoms, add_exclusive_stop=True)
+ for idx, (start, stop) in enumerate(zip(res_starts[:-1], res_starts[1:])):
+ resnum = int(atoms.res_id[start])
+ resname = atoms.res_name[start]
+ auth_resnum, insertion_code = residue_author_ids.get(
+ resnum, (str(resnum), ".")
+ )
+ selected_altcode = "."
+ if hasattr(atoms, "selected_altloc_id"):
+ selected_altcode = next(
+ (
+ str(altcode)
+ for altcode in atoms.selected_altloc_id[start:stop]
+ if str(altcode) not in {".", "?", " ", ""}
+ ),
+ ".",
+ )
+ # One-letter code: try amino acid first, then nucleotide
+ olc = "X"
+ if chain_type_str is None or "non-polymer" not in chain_type_str.lower():
+ try:
+ olc_aa = info.one_letter_code(resname)
+ if olc_aa is not None:
+ olc = olc_aa
+ except Exception:
+ pass
+ if olc == "X" and resname in _standard_na_names():
+ # Map standard nucleotides to their base letter
+ olc = resname[-1] if len(resname) <= 2 else resname[1]
+ # Determine chem_type from residue name
+ if resname in _standard_aa_names():
+ chem_type = "Peptide Linking"
+ elif resname in _standard_na_names():
+ chem_type = (
+ "RNA Linking" if resname in {"A", "C", "G", "U"} else "DNA Linking"
+ )
+ else:
+ chem_type = "Non-Polymer"
+ if unresolved_atoms is not None:
+ unresolved = list(unresolved_atoms.get(resnum, []))
+ else:
+ unresolved = (
+ unresolved_atoms_from_template(
+ resname, atoms.atom_name[start:stop].tolist()
+ )
+ or []
+ )
+ residues[resnum] = Residue(
+ chain=asym_id,
+ index=idx,
+ number=resnum,
+ auth_number=auth_resnum,
+ insertion_code=insertion_code,
+ one_letter_code=olc,
+ name=resname,
+ chem_type=chem_type,
+ selected_altcode=selected_altcode,
+ unresolved_atom_names=unresolved,
+ )
+
+ # Get entity_id from _struct_asym
+ if entity_id is None and "struct_asym" in block:
+ sa = block["struct_asym"]
+ sa_ids = sa["id"].as_array()
+ sa_entities = sa["entity_id"].as_array()
+ for i, sa_id in enumerate(sa_ids):
+ if sa_id == asym_id:
+ entity_id = str(sa_entities[i])
+ break
+ if entity_id is None:
+ entity_id = ""
+
+ # Get auth chain ID
+ if auth_id is None and hasattr(atoms, "auth_asym_id"):
+ auth_id = str(atoms.auth_asym_id[0])
+ elif auth_id is None and "atom_site" in block:
+ atom_site = block["atom_site"]
+ if "auth_asym_id" in atom_site:
+ asym_arr = atom_site["label_asym_id"].as_array()
+ auth_arr = atom_site["auth_asym_id"].as_array()
+ for i, a in enumerate(asym_arr):
+ if a == asym_id:
+ auth_id = str(auth_arr[i])
+ break
+ if auth_id is None:
+ auth_id = ""
+
+ # Get chain type from _entity_poly.type or _entity.type
+ if chain_type_str is None:
+ chain_type_str = _get_chain_type_from_cif(block, entity_id)
+
+ return cls(
+ asym_id=asym_id,
+ auth_id=auth_id,
+ entity_id=entity_id,
+ chain_type_str=chain_type_str,
+ residues=residues,
+ length=seqres_length,
+ # -1 sentinel (collation flags <0) when SEQRES is missing or
+ # shorter than the resolved residues โ surface it
+ num_unresolved_residues=max(-1, seqres_length - len(residues)),
+ modified_residues=list(modified_residues or []),
+ )
+
+ @cached_property
+ def residue_index_to_number(self) -> dict[int, int]:
+ """[EXCLUDE] Dictionary of residue index to residue number"""
+ return {self.residues[r].index: r for r in self.residues}
+
+ def format(self, instance: int) -> dict[str, Any]:
+ """
+ Format chain as a dictionary
+ """
+ data: dict[str, Any] = {
+ "asym_id": f"{instance}.{self.asym_id}",
+ "auth_id": self.auth_id,
+ "entity_id": self.entity_id,
+ "length": self.length,
+ "num_unresolved_residues": self.num_unresolved_residues,
+ }
+ # data.update(self.mappings)
+ if self.validation is not None:
+ data.update(self.validation.format())
+ return data
+
+ def set_validation(
+ self, doc: PDBValidation, residue_thresholds: ResidueValidationThresholds
+ ) -> None:
+ for residue in self.residues:
+ self.residues[residue].validation = ResidueValidation.from_residue(
+ self.asym_id,
+ residue,
+ self.entity_id,
+ doc,
+ preferred_altcode=self.residues[residue].selected_altcode,
+ )
+ validations = []
+ for r in self.residues.values():
+ if r.validation is not None:
+ validations.append(r.validation)
+ self.validation = ResidueListValidation.from_residues(
+ validations, residue_thresholds
+ )
diff --git a/src/plinder/data/annotations/save_utils.py b/src/plinder/data/annotations/save_utils.py
new file mode 100644
index 000000000..8c550360d
--- /dev/null
+++ b/src/plinder/data/annotations/save_utils.py
@@ -0,0 +1,1031 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from __future__ import annotations
+
+import re
+from dataclasses import dataclass
+from pathlib import Path
+from typing import Any, Literal, Protocol
+
+import biotite.structure as struc
+import biotite.structure.io.mol as mol
+import biotite.structure.io.pdbx as pdbx
+import numpy as np
+import pandas as pd
+from numpy.typing import NDArray
+from rdkit import Chem
+
+WaterSelection = Literal["none", "interacting", "all"]
+
+
+def _output_asym_ids(chain_ids: list[str]) -> dict[str, str]:
+ """Return unique mmCIF asym IDs while preserving assembly chain IDs."""
+ output: dict[str, str] = {}
+ used: set[str] = set()
+ for chain_id in chain_ids:
+ candidate = chain_id
+ supported = re.fullmatch(r"(?:[A-Za-z0-9]+|[0-9]+\.[A-Za-z0-9]+)", candidate)
+ if supported is None or candidate in used:
+ candidate = "C" + chain_id.encode("utf-8").hex()
+ suffix = 2
+ base = candidate
+ while candidate in used:
+ candidate = f"{base}X{suffix}"
+ suffix += 1
+ output[chain_id] = candidate
+ used.add(candidate)
+ return output
+
+
+class AnnotationRow(Protocol):
+ """Minimal interface shared by dicts and pandas Series."""
+
+ def get(self, key: str, default: Any = None) -> Any: ...
+
+
+@dataclass(frozen=True)
+class SystemReconstructionOptions:
+ """Configure which atoms are present in reconstructed mmCIF views."""
+
+ system_waters: WaterSelection = "interacting"
+ receptor_waters: WaterSelection = "interacting"
+ system_include_ligands: bool = True
+ system_include_other_protein_chains: bool = False
+ system_include_other_ligand_chains: bool = False
+ receptor_include_other_protein_chains: bool = False
+ validate_biounit_chain_ids: bool = True
+
+
+@dataclass(frozen=True)
+class SystemReconstructionOutputs:
+ """Explicit output paths; ``None`` means that file is not written."""
+
+ system_cif: Path | None = None
+ receptor_cif: Path | None = None
+ sequences_fasta: Path | None = None
+
+
+@dataclass(frozen=True)
+class ReconstructedSystem:
+ """In-memory views rebuilt from a source PDB mmCIF."""
+
+ biounit: struc.AtomArray
+ system: struc.AtomArray
+ receptor: struc.AtomArray
+
+
+@dataclass(frozen=True)
+class _ChainSelections:
+ """Chain instances selected for reconstruction views."""
+
+ expected_biounit: set[str]
+ system: set[str]
+ receptor: set[str]
+
+
+def save_ligands(
+ atoms: struc.AtomArray,
+ ligand_chain_ids: list[str] | dict[str, list[str]],
+ output_folder: str | Path,
+) -> None:
+ """Save one canonical ASU SDF per retained ligand.
+
+ RDKit supplies chemically normalized bond/aromaticity information when it
+ can sanitize the ligand. If it cannot, Biotite serializes the source bond
+ graph directly so the canonical coordinate archive remains complete.
+
+ Parameters
+ ----------
+ atoms : AtomArray
+ Full system atoms with bonds.
+ ligand_chain_ids : list[str] or dict[str, list[str]]
+ Either a list of chain IDs (one SDF per chain), or a mapping of
+ output name -> member chain IDs. The mapping form writes a single
+ SDF spanning all member chains, so covalently-linked ligand chains
+ (a macrocycle deposited as several chains) are saved as one molecule.
+ output_folder : str or Path
+ Directory to write SDF files.
+ """
+ import logging
+
+ from plinder.data.annotations.cif_utils import atoms_to_rdkit_mol
+
+ log = logging.getLogger(__name__)
+ output_folder = Path(output_folder)
+ output_folder.mkdir(parents=True, exist_ok=True)
+
+ # Normalize to {output_name: [member_chain_ids]}.
+ groups = (
+ ligand_chain_ids
+ if isinstance(ligand_chain_ids, dict)
+ else {chain_id: [chain_id] for chain_id in ligand_chain_ids}
+ )
+
+ for chain_id, member_chain_ids in groups.items():
+ lig_mask = np.isin(atoms.chain_id, member_chain_ids)
+ if not np.any(lig_mask):
+ raise ValueError(f"No atoms found for ligand chain(s) {member_chain_ids!r}")
+ lig_atoms = atoms[lig_mask]
+ output_file = output_folder / f"{chain_id}.sdf"
+ try:
+ rdkit_mol = atoms_to_rdkit_mol(lig_atoms)
+ except Exception as exc:
+ log.warning(
+ "save_ligands: RDKit conversion failed for chain %s; "
+ "writing the unsanitized Biotite structure: %s",
+ chain_id,
+ exc,
+ )
+ sdf_file = mol.SDFile()
+ mol.set_structure(sdf_file, lig_atoms, record_name=chain_id)
+ sdf_file.write(output_file)
+ else:
+ rdkit_mol.SetProp("_Name", chain_id)
+ with Chem.SDWriter(str(output_file)) as writer:
+ writer.write(rdkit_mol)
+
+
+def save_cif_file(
+ atoms: struc.AtomArray,
+ name: str,
+ output_cif_file: str | Path,
+ *,
+ source_block: pdbx.CIFBlock | None = None,
+ source_asym_ids: dict[str, str] | None = None,
+ protein_sequences: dict[str, str] | None = None,
+) -> None:
+ """Save a self-contained structure as PDBx/mmCIF.
+
+ Parameters
+ ----------
+ atoms : AtomArray
+ Atoms to save.
+ name : str
+ Data block name.
+ output_cif_file : str or Path
+ Output path.
+ source_block : CIFBlock, optional
+ Source metadata. Relevant entity, polymer, and chemical-component
+ rows are retained for the atoms in the output view.
+ source_asym_ids : dict, optional
+ Map output chain IDs to label asym IDs in ``source_block``. Assembly
+ instance IDs default to their suffix after the first ``.``.
+ protein_sequences : dict, optional
+ Canonical protein sequences keyed by output chain ID. These are used
+ when the source has no polymer metadata.
+ """
+ if atoms.array_length() == 0:
+ raise ValueError("cannot write an empty mmCIF structure")
+ atoms = atoms.copy()
+ input_chain_ids = list(dict.fromkeys(atoms.chain_id.astype(str)))
+ chain_id_map = _output_asym_ids(input_chain_ids)
+ source_asym_ids = source_asym_ids or {}
+ output_to_source_asym = {
+ chain_id_map[chain_id]: source_asym_ids.get(
+ chain_id, chain_id.split(".", maxsplit=1)[-1]
+ )
+ for chain_id in input_chain_ids
+ }
+ protein_sequences = {
+ chain_id_map.get(chain_id, chain_id): sequence
+ for chain_id, sequence in (protein_sequences or {}).items()
+ }
+ atoms.chain_id = np.asarray(
+ [chain_id_map[str(chain_id)] for chain_id in atoms.chain_id]
+ )
+ chain_ids = list(dict.fromkeys(atoms.chain_id.astype(str)))
+
+ source_asym_to_entity: dict[str, str] = {}
+ if source_block is not None and "struct_asym" in source_block:
+ struct_asym = source_block["struct_asym"]
+ if {"id", "entity_id"}.issubset(struct_asym):
+ source_asym_to_entity = dict(
+ zip(
+ struct_asym["id"].as_array(str),
+ struct_asym["entity_id"].as_array(str),
+ )
+ )
+
+ chain_to_entity: dict[str, str] = {}
+ used_entity_ids: set[str] = set()
+ for chain_id in chain_ids:
+ source_asym_id = output_to_source_asym[chain_id]
+ entity_id = source_asym_to_entity.get(source_asym_id)
+ if entity_id is not None:
+ chain_to_entity[chain_id] = entity_id
+ used_entity_ids.add(entity_id)
+ next_entity_id = 1
+ for chain_id in chain_ids:
+ if chain_id in chain_to_entity:
+ continue
+ while str(next_entity_id) in used_entity_ids:
+ next_entity_id += 1
+ entity_id = str(next_entity_id)
+ chain_to_entity[chain_id] = entity_id
+ used_entity_ids.add(entity_id)
+ next_entity_id += 1
+ atoms.set_annotation(
+ "label_entity_id",
+ np.asarray([chain_to_entity[str(chain_id)] for chain_id in atoms.chain_id]),
+ )
+
+ source_polymer_metadata_ids: set[str] = set()
+ if (
+ source_block is not None
+ and "entity_poly" in source_block
+ and "entity_poly_seq" in source_block
+ and "entity_id" in source_block["entity_poly"]
+ and "entity_id" in source_block["entity_poly_seq"]
+ ):
+ source_polymer_metadata_ids = set(
+ source_block["entity_poly"]["entity_id"].as_array(str)
+ ).intersection(source_block["entity_poly_seq"]["entity_id"].as_array(str))
+ for chain_id, sequence in protein_sequences.items():
+ if chain_id not in chain_to_entity:
+ raise ValueError(f"protein sequence refers to absent chain {chain_id!r}")
+ if chain_to_entity[chain_id] in source_polymer_metadata_ids:
+ continue
+ chain_mask = atoms.chain_id == chain_id
+ chain = atoms[chain_mask]
+ residue_starts = struc.get_residue_starts(chain, add_exclusive_stop=True)
+ residue_count = len(residue_starts) - 1
+ if residue_count > len(sequence):
+ raise ValueError(
+ f"chain {chain_id!r} has {residue_count} resolved residues but "
+ f"its supplied sequence has length {len(sequence)}"
+ )
+ new_residue_ids = np.empty(chain.array_length(), dtype=int)
+ for index, (start, stop) in enumerate(
+ zip(residue_starts[:-1], residue_starts[1:]), start=1
+ ):
+ new_residue_ids[start:stop] = index
+ atoms.res_id[chain_mask] = new_residue_ids
+ atoms.ins_code[chain_mask] = ""
+
+ annotation_categories = set(atoms.get_annotation_categories())
+ if "atom_id" not in annotation_categories:
+ atoms.set_annotation("atom_id", np.arange(1, atoms.array_length() + 1))
+ if "occupancy" not in annotation_categories:
+ atoms.set_annotation("occupancy", np.ones(atoms.array_length()))
+ if "b_factor" not in annotation_categories:
+ atoms.set_annotation("b_factor", np.zeros(atoms.array_length()))
+ if "charge" not in annotation_categories:
+ atoms.set_annotation("charge", np.zeros(atoms.array_length(), dtype=int))
+
+ cif_file = pdbx.CIFFile()
+ pdbx.set_structure(cif_file, atoms, data_block=name)
+ block = cif_file[name]
+ atom_site = block["atom_site"]
+ # Keep biological-assembly copies distinct for readers that default to
+ # author fields (including Biotite itself).
+ atom_site["auth_asym_id"] = atom_site["label_asym_id"].as_array(str)
+ if "cell" in block:
+ block["cell"]["entry_id"] = [name]
+ block["entry"] = pdbx.CIFCategory({"id": [name]})
+ block["struct_asym"] = pdbx.CIFCategory(
+ {
+ "id": chain_ids,
+ "entity_id": [chain_to_entity[chain_id] for chain_id in chain_ids],
+ }
+ )
+
+ source_entity_types: dict[str, str] = {}
+ if source_block is not None and "entity" in source_block:
+ source_entity = source_block["entity"]
+ if {"id", "type"}.issubset(source_entity):
+ source_entity_types = dict(
+ zip(
+ source_entity["id"].as_array(str),
+ source_entity["type"].as_array(str),
+ )
+ )
+ entity_types: dict[str, str] = {}
+ for chain_id in chain_ids:
+ entity_id = chain_to_entity[chain_id]
+ chain = atoms[atoms.chain_id == chain_id]
+ entity_types.setdefault(
+ entity_id,
+ source_entity_types.get(
+ entity_id,
+ "polymer"
+ if chain_id in protein_sequences
+ or np.any(struc.filter_amino_acids(chain))
+ or np.any(struc.filter_nucleotides(chain))
+ else "water"
+ if np.all(struc.filter_solvent(chain))
+ else "non-polymer",
+ ),
+ )
+ entity_ids = list(dict.fromkeys(chain_to_entity.values()))
+ block["entity"] = pdbx.CIFCategory(
+ {
+ "id": entity_ids,
+ "type": [entity_types[entity_id] for entity_id in entity_ids],
+ }
+ )
+
+ def copy_source_rows(
+ category_name: str,
+ key_name: str,
+ selected_values: set[str],
+ ) -> pdbx.CIFCategory | None:
+ if source_block is None or category_name not in source_block:
+ return None
+ source_category = source_block[category_name]
+ if key_name not in source_category:
+ return None
+ row_mask = np.isin(
+ source_category[key_name].as_array(str), list(selected_values)
+ )
+ if not np.any(row_mask):
+ return None
+ columns: dict[str, pdbx.CIFColumn] = {}
+ for column_name, column in source_category.items():
+ mask = column.mask.array[row_mask] if column.mask is not None else None
+ columns[column_name] = pdbx.CIFColumn(
+ column.data.array[row_mask], mask=mask
+ )
+ return pdbx.CIFCategory(columns)
+
+ polymer_entity_ids = {
+ entity_id
+ for entity_id, entity_type in entity_types.items()
+ if entity_type == "polymer"
+ }
+ nonpoly_entity_ids = set(entity_ids).difference(polymer_entity_ids)
+ if nonpoly_entity_ids:
+ label_seq_id = atom_site["label_seq_id"]
+ nonpoly_atom_mask = np.isin(
+ atom_site["label_entity_id"].as_array(str),
+ list(nonpoly_entity_ids),
+ )
+ label_seq_mask = (
+ label_seq_id.mask.array.copy()
+ if label_seq_id.mask is not None
+ else np.full(atom_site.row_count, pdbx.MaskValue.PRESENT)
+ )
+ label_seq_mask[nonpoly_atom_mask] = pdbx.MaskValue.INAPPLICABLE
+ atom_site["label_seq_id"] = pdbx.CIFColumn(
+ label_seq_id.data.array, mask=label_seq_mask
+ )
+ if "struct_conn" in block:
+ struct_conn = block["struct_conn"]
+ nonpoly_chain_ids = {
+ chain_id
+ for chain_id in chain_ids
+ if chain_to_entity[chain_id] in nonpoly_entity_ids
+ }
+ for partner in (1, 2):
+ asym_column = f"ptnr{partner}_label_asym_id"
+ seq_column = f"ptnr{partner}_label_seq_id"
+ if asym_column not in struct_conn or seq_column not in struct_conn:
+ continue
+ seq_id = struct_conn[seq_column]
+ seq_mask = (
+ seq_id.mask.array.copy()
+ if seq_id.mask is not None
+ else np.full(struct_conn.row_count, pdbx.MaskValue.PRESENT)
+ )
+ seq_mask[
+ np.isin(
+ struct_conn[asym_column].as_array(str),
+ list(nonpoly_chain_ids),
+ )
+ ] = pdbx.MaskValue.INAPPLICABLE
+ struct_conn[seq_column] = pdbx.CIFColumn(
+ seq_id.data.array, mask=seq_mask
+ )
+ entity_poly = copy_source_rows("entity_poly", "entity_id", polymer_entity_ids)
+ entity_poly_seq = copy_source_rows(
+ "entity_poly_seq", "entity_id", polymer_entity_ids
+ )
+ if entity_poly is not None and entity_poly_seq is not None:
+ if "pdbx_strand_id" in entity_poly:
+ entity_poly["pdbx_strand_id"] = [
+ ",".join(
+ chain_id
+ for chain_id in chain_ids
+ if chain_to_entity[chain_id] == entity_id
+ )
+ for entity_id in entity_poly["entity_id"].as_array(str)
+ ]
+ block["entity_poly"] = entity_poly
+ block["entity_poly_seq"] = entity_poly_seq
+ elif polymer_entity_ids:
+ from plinder.core.utils.constants import ONE_TO_THREE
+
+ poly_rows: list[tuple[str, str, str]] = []
+ sequence_rows: list[tuple[str, str, int, str]] = []
+ for entity_id in sorted(polymer_entity_ids):
+ entity_chains = [
+ chain_id
+ for chain_id in chain_ids
+ if chain_to_entity[chain_id] == entity_id
+ ]
+ chain_id = entity_chains[0]
+ chain = atoms[atoms.chain_id == chain_id]
+ protein_sequence = protein_sequences.get(chain_id)
+ residue_starts = struc.get_residue_starts(chain, add_exclusive_stop=False)
+ residue_names = chain.res_name[residue_starts].astype(str).tolist()
+ if protein_sequence is None:
+ if not np.any(struc.filter_amino_acids(chain)):
+ raise ValueError(
+ "source mmCIF metadata is required to write a "
+ f"non-protein polymer chain {chain_id!r}"
+ )
+ from plinder.core.utils.constants import THREE_TO_ONE
+
+ protein_sequence = "".join(
+ THREE_TO_ONE.get(residue_name, "X")
+ for residue_name in residue_names
+ )
+ monomers = [ONE_TO_THREE.get(symbol, "UNK") for symbol in protein_sequence]
+ for residue_id, residue_name in zip(
+ chain.res_id[residue_starts], residue_names
+ ):
+ if 1 <= residue_id <= len(monomers):
+ monomers[int(residue_id) - 1] = residue_name
+ poly_rows.append((entity_id, protein_sequence, ",".join(entity_chains)))
+ sequence_rows.extend(
+ (entity_id, monomer, index, "n")
+ for index, monomer in enumerate(monomers, start=1)
+ )
+ block["entity_poly"] = pdbx.CIFCategory(
+ {
+ "entity_id": [row[0] for row in poly_rows],
+ "type": ["polypeptide(L)"] * len(poly_rows),
+ "nstd_linkage": ["no"] * len(poly_rows),
+ "nstd_monomer": ["yes" if "X" in row[1] else "no" for row in poly_rows],
+ "pdbx_seq_one_letter_code": [row[1] for row in poly_rows],
+ "pdbx_seq_one_letter_code_can": [row[1] for row in poly_rows],
+ "pdbx_strand_id": [row[2] for row in poly_rows],
+ }
+ )
+ block["entity_poly_seq"] = pdbx.CIFCategory(
+ {
+ "entity_id": [row[0] for row in sequence_rows],
+ "mon_id": [row[1] for row in sequence_rows],
+ "num": [row[2] for row in sequence_rows],
+ "hetero": [row[3] for row in sequence_rows],
+ }
+ )
+
+ pdbx_entity_nonpoly = copy_source_rows(
+ "pdbx_entity_nonpoly", "entity_id", nonpoly_entity_ids
+ )
+ if pdbx_entity_nonpoly is not None:
+ block["pdbx_entity_nonpoly"] = pdbx_entity_nonpoly
+ elif nonpoly_entity_ids:
+ nonpoly_rows: list[tuple[str, str]] = []
+ for entity_id in sorted(nonpoly_entity_ids):
+ chain_id = next(
+ chain_id
+ for chain_id in chain_ids
+ if chain_to_entity[chain_id] == entity_id
+ )
+ chain = atoms[atoms.chain_id == chain_id]
+ nonpoly_rows.append((entity_id, str(chain.res_name[0])))
+ block["pdbx_entity_nonpoly"] = pdbx.CIFCategory(
+ {
+ "entity_id": [row[0] for row in nonpoly_rows],
+ "name": [row[1] for row in nonpoly_rows],
+ "comp_id": [row[1] for row in nonpoly_rows],
+ }
+ )
+
+ component_ids = set(atoms.res_name.astype(str))
+ polymer_component_ids: set[str] = set()
+ if "entity_poly_seq" in block:
+ polymer_component_ids.update(block["entity_poly_seq"]["mon_id"].as_array(str))
+ component_ids.update(polymer_component_ids)
+ source_component_types: dict[str, str] = {}
+ if source_block is not None and "chem_comp" in source_block:
+ source_chem_comp = source_block["chem_comp"]
+ if {"id", "type"}.issubset(source_chem_comp):
+ source_component_types = dict(
+ zip(
+ source_chem_comp["id"].as_array(str),
+ source_chem_comp["type"].as_array(str),
+ )
+ )
+ sorted_component_ids = sorted(component_ids)
+ block["chem_comp"] = pdbx.CIFCategory(
+ {
+ "id": sorted_component_ids,
+ "type": [
+ source_component_types.get(
+ component_id,
+ "PEPTIDE LINKING"
+ if component_id == "GLY"
+ else "L-PEPTIDE LINKING"
+ if component_id in polymer_component_ids
+ else "NON-POLYMER",
+ )
+ for component_id in sorted_component_ids
+ ],
+ }
+ )
+ block["atom_type"] = pdbx.CIFCategory(
+ {"symbol": sorted(set(atoms.element.astype(str)))}
+ )
+ if "chem_comp_bond" in block:
+ bond_order = block["chem_comp_bond"]["value_order"]
+ block["chem_comp_bond"]["value_order"] = pdbx.CIFColumn(
+ np.char.lower(bond_order.data.array.astype(str)),
+ mask=bond_order.mask,
+ )
+ if "struct_conn" in block:
+ connection_types = sorted(
+ set(block["struct_conn"]["conn_type_id"].as_array(str))
+ )
+ block["struct_conn_type"] = pdbx.CIFCategory({"id": connection_types})
+ cif_file.write(str(output_cif_file))
+
+
+def save_reconstructed_chain(
+ source_mmcif: Path | str,
+ *,
+ assembly_id: str,
+ chain_instance: str,
+ source_asym_id: str,
+ output_cif: Path | str,
+ structure_id: str,
+ superpose_to: struc.AtomArray | None = None,
+ overwrite: bool = False,
+) -> Path:
+ """Write one biological-assembly chain as a self-contained mmCIF.
+
+ If ``superpose_to`` is provided, the reconstructed chain is fitted to that
+ protein chain using sequence-matched C-alpha atoms before it is written.
+ """
+ from plinder.data.annotations.cif_utils import (
+ build_biounit,
+ get_label_asym_sequences,
+ read_mmcif_container,
+ read_mmcif_file,
+ )
+
+ if not assembly_id:
+ raise ValueError("assembly_id must not be empty")
+ if not chain_instance:
+ raise ValueError("chain_instance must not be empty")
+ if not source_asym_id:
+ raise ValueError("source_asym_id must not be empty")
+ output_cif = Path(output_cif)
+ if output_cif.exists() and not overwrite:
+ raise FileExistsError(
+ f"Refusing to overwrite reconstruction output: {output_cif}"
+ )
+
+ biounit = build_biounit(read_mmcif_file(source_mmcif), assembly_id)
+ chain_mask = biounit.chain_id.astype(str) == chain_instance
+ if not np.any(chain_mask):
+ available = sorted(set(biounit.chain_id.astype(str)))
+ raise ValueError(
+ f"Assembly {assembly_id!r} has no chain {chain_instance!r}; "
+ f"available chains are {available}"
+ )
+
+ source_block = read_mmcif_container(Path(source_mmcif))
+ source_sequences = get_label_asym_sequences(source_block)
+ protein_sequences = {}
+ if source_asym_id in source_sequences:
+ protein_sequences[chain_instance] = source_sequences[source_asym_id]
+ chain_atoms = biounit[chain_mask]
+ if superpose_to is not None:
+ from plinder.core.structure.superimpose import superimpose_chain
+
+ chain_atoms, _, _, _ = superimpose_chain(superpose_to, chain_atoms)
+ output_cif.parent.mkdir(parents=True, exist_ok=True)
+ save_cif_file(
+ chain_atoms,
+ structure_id,
+ output_cif,
+ source_block=source_block,
+ source_asym_ids={chain_instance: source_asym_id},
+ protein_sequences=protein_sequences,
+ )
+ return output_cif
+
+
+def reconstruct_interface(
+ source_mmcif: Path | str,
+ annotation: AnnotationRow,
+) -> struc.AtomArray:
+ """Rebuild one annotated protein-interface chain pair from a source mmCIF."""
+ from plinder.data.annotations.cif_utils import build_biounit, read_mmcif_file
+
+ assembly_id = str(annotation.get("system_biounit_id", ""))
+ chain_1 = str(annotation.get("interface_chain_1", ""))
+ chain_2 = str(annotation.get("interface_chain_2", ""))
+ if not assembly_id:
+ raise ValueError("interface annotation is missing system_biounit_id")
+ if not chain_1 or not chain_2:
+ raise ValueError("interface annotation is missing one or both chains")
+ if chain_1 == chain_2:
+ raise ValueError("an interface requires two distinct chain instances")
+
+ biounit = build_biounit(read_mmcif_file(source_mmcif), assembly_id)
+ selected_chains = {chain_1, chain_2}
+ _require_chains(biounit, selected_chains, view_name="interface")
+ return biounit[np.isin(biounit.chain_id, list(selected_chains))]
+
+
+def save_reconstructed_interface(
+ source_mmcif: Path | str,
+ annotation: AnnotationRow,
+ *,
+ output_cif: Path | str,
+ overwrite: bool = False,
+ reconstructed: struc.AtomArray | None = None,
+) -> Path:
+ """Write one annotated biological-assembly interface as a valid mmCIF."""
+ from plinder.data.annotations.cif_utils import (
+ get_label_asym_sequences,
+ read_mmcif_container,
+ )
+
+ output_cif = Path(output_cif)
+ if output_cif.exists() and not overwrite:
+ raise FileExistsError(
+ f"Refusing to overwrite reconstruction output: {output_cif}"
+ )
+ atoms = (
+ reconstruct_interface(source_mmcif, annotation)
+ if reconstructed is None
+ else reconstructed
+ )
+ chain_ids = [
+ str(annotation.get("interface_chain_1", "")),
+ str(annotation.get("interface_chain_2", "")),
+ ]
+ source_asym_ids = {
+ chain_id: chain_id.split(".", maxsplit=1)[-1] for chain_id in chain_ids
+ }
+ source_block = read_mmcif_container(Path(source_mmcif))
+ source_sequences = get_label_asym_sequences(source_block)
+ protein_sequences = {
+ chain_id: source_sequences[source_asym_id]
+ for chain_id, source_asym_id in source_asym_ids.items()
+ if source_asym_id in source_sequences
+ }
+ structure_id = str(annotation.get("system_id", "interface"))
+ output_cif.parent.mkdir(parents=True, exist_ok=True)
+ save_cif_file(
+ atoms,
+ structure_id,
+ output_cif,
+ source_block=source_block,
+ source_asym_ids=source_asym_ids,
+ protein_sequences=protein_sequences,
+ )
+ return output_cif
+
+
+def _string_list(value: Any) -> list[str]:
+ """Normalize Arrow/Pandas/list values from an annotation row."""
+ if value is None:
+ return []
+ if isinstance(value, str):
+ return [value]
+ if isinstance(value, np.ndarray):
+ value = value.tolist()
+ if isinstance(value, (list, tuple, set)):
+ return [str(item) for item in value]
+ try:
+ if bool(np.isnan(value)):
+ return []
+ except (TypeError, ValueError):
+ pass
+ raise TypeError(f"Expected a list-like annotation value, got {type(value)!r}")
+
+
+def _annotation_chains(annotation: AnnotationRow, column: str) -> list[str]:
+ return sorted(set(_string_list(annotation.get(column))))
+
+
+def _water_mask(
+ biounit: struc.AtomArray,
+ annotation: AnnotationRow,
+ selection: WaterSelection,
+) -> NDArray[np.bool_]:
+ if selection == "none":
+ empty_mask: NDArray[np.bool_] = np.zeros(biounit.array_length(), dtype=np.bool_)
+ return empty_mask
+ if selection == "all":
+ solvent_mask: NDArray[np.bool_] = struc.filter_solvent(biounit)
+ return solvent_mask
+ if selection != "interacting":
+ raise ValueError(f"Unknown water selection: {selection!r}")
+
+ mask: NDArray[np.bool_] = np.zeros(biounit.array_length(), dtype=np.bool_)
+ for encoded_residue in _string_list(annotation.get("system_water_residues")):
+ try:
+ chain_id, residue_number = encoded_residue.rsplit("_", maxsplit=1)
+ residue_id = int(residue_number)
+ except ValueError as exc:
+ raise ValueError(
+ "system_water_residues values must have the form "
+ f"'._', got {encoded_residue!r}"
+ ) from exc
+ mask |= (biounit.chain_id == chain_id) & (biounit.res_id == residue_id)
+ return mask
+
+
+def _require_chains(
+ biounit: struc.AtomArray,
+ chain_ids: set[str],
+ *,
+ view_name: str,
+) -> None:
+ available = set(str(chain_id) for chain_id in np.unique(biounit.chain_id))
+ missing = chain_ids - available
+ if missing:
+ raise ValueError(
+ f"Cannot reconstruct {view_name}: assembly is missing chains "
+ f"{sorted(missing)}"
+ )
+
+
+def _biounit_chain_roles(
+ annotation: AnnotationRow,
+ biounit_chains: pd.DataFrame,
+) -> dict[str, str]:
+ """Return chain-instance roles for the annotation's biological assembly."""
+ required = {
+ "entry_pdb_id",
+ "biounit_id",
+ "chain_instance",
+ "chain_asym_id",
+ "chain_role",
+ }
+ missing = required.difference(biounit_chains.columns)
+ if missing:
+ raise ValueError(f"biounit-chain metadata is missing columns {sorted(missing)}")
+ pdb_id = str(annotation.get("entry_pdb_id", ""))
+ biounit_id = str(annotation.get("system_biounit_id", ""))
+ selected = biounit_chains[
+ biounit_chains["entry_pdb_id"].astype(str).eq(pdb_id)
+ & biounit_chains["biounit_id"].astype(str).eq(biounit_id)
+ ].copy()
+ if selected.empty:
+ raise ValueError(
+ "No biological-assembly chain metadata for "
+ f"entry={pdb_id!r}, biounit={biounit_id!r}"
+ )
+ if selected["chain_instance"].duplicated().any():
+ duplicates = sorted(
+ selected.loc[
+ selected["chain_instance"].duplicated(keep=False),
+ "chain_instance",
+ ]
+ .astype(str)
+ .unique()
+ )
+ raise ValueError(f"Duplicate biological-assembly chains: {duplicates}")
+ roles = dict(
+ zip(
+ selected["chain_instance"].astype(str),
+ selected["chain_role"].astype(str),
+ )
+ )
+ invalid_roles = sorted(set(roles.values()) - {"receptor", "ligand", "water"})
+ if invalid_roles:
+ raise ValueError(f"Unknown biological-assembly chain roles: {invalid_roles}")
+ mismatched_asym_ids = selected[
+ selected["chain_instance"]
+ .astype(str)
+ .str.split(".", n=1)
+ .str[-1]
+ .ne(selected["chain_asym_id"].astype(str))
+ ]
+ if not mismatched_asym_ids.empty:
+ raise ValueError(
+ "biounit-chain metadata has inconsistent chain instance/asym IDs"
+ )
+ return roles
+
+
+def _select_chains(
+ annotation: AnnotationRow,
+ biounit_chains: pd.DataFrame,
+ options: SystemReconstructionOptions,
+) -> _ChainSelections:
+ protein_chains = set(
+ _annotation_chains(annotation, "system_protein_chains_asym_id")
+ )
+ ligand_chains = set(
+ _annotation_chains(annotation, "system_ligand_chains_asym_id")
+ or _annotation_chains(annotation, "system_ligand_chains")
+ )
+ if not protein_chains:
+ raise ValueError("annotation contains no system protein chains")
+
+ roles = _biounit_chain_roles(annotation, biounit_chains)
+ include_other = (
+ options.system_include_other_protein_chains
+ or options.system_include_other_ligand_chains
+ or options.receptor_include_other_protein_chains
+ )
+ if include_other and not roles:
+ raise ValueError(
+ "biounit-chain metadata is required when including other chains"
+ )
+ system_members = protein_chains | ligand_chains
+ other_receptor_chains = {
+ chain
+ for chain, role in roles.items()
+ if role == "receptor" and chain not in system_members
+ }
+ other_ligand_chains = {
+ chain
+ for chain, role in roles.items()
+ if role == "ligand" and chain not in system_members
+ }
+
+ system_chains = set(protein_chains)
+ if options.system_include_ligands:
+ system_chains.update(ligand_chains)
+ if options.system_include_other_protein_chains:
+ system_chains.update(other_receptor_chains)
+ if options.system_include_other_ligand_chains:
+ system_chains.update(other_ligand_chains)
+
+ receptor_chains = set(protein_chains)
+ if options.receptor_include_other_protein_chains:
+ receptor_chains.update(other_receptor_chains)
+ return _ChainSelections(
+ expected_biounit=set(roles),
+ system=system_chains,
+ receptor=receptor_chains,
+ )
+
+
+def reconstruct_system(
+ source_mmcif: Path | str,
+ annotation: AnnotationRow,
+ *,
+ biounit_chains: pd.DataFrame,
+ options: SystemReconstructionOptions = SystemReconstructionOptions(),
+) -> ReconstructedSystem:
+ """Rebuild system and receptor views from a PDB mmCIF and parquet row.
+
+ The annotation row must be one ligand-level row from the system to
+ reconstruct. System-level columns are repeated for every ligand row, so
+ no grouping or coordinate data from the parquet is required.
+
+ Parameters
+ ----------
+ source_mmcif : Path or str
+ Original PDB mmCIF used for annotation (plain or gzip-compressed).
+ annotation : mapping-like
+ A dictionary or pandas Series containing the system selection columns.
+ biounit_chains : pandas.DataFrame
+ Biological-assembly membership rows for this entry.
+ options : SystemReconstructionOptions
+ Atom-content choices for the two returned views.
+ """
+ from plinder.data.annotations.cif_utils import (
+ build_biounit,
+ read_mmcif_file,
+ )
+
+ assembly_id = str(annotation.get("system_biounit_id", ""))
+ if not assembly_id:
+ raise ValueError("annotation is missing system_biounit_id")
+ biounit = build_biounit(read_mmcif_file(source_mmcif), assembly_id)
+
+ selections = _select_chains(annotation, biounit_chains, options)
+ actual_biounit_chains = set(
+ str(chain_id) for chain_id in np.unique(biounit.chain_id)
+ )
+ if (
+ options.validate_biounit_chain_ids
+ and selections.expected_biounit
+ and selections.expected_biounit != actual_biounit_chains
+ ):
+ raise ValueError(
+ "Source mmCIF assembly chains differ from the annotation: "
+ f"expected={sorted(selections.expected_biounit)}, "
+ f"actual={sorted(actual_biounit_chains)}"
+ )
+
+ _require_chains(biounit, selections.system, view_name="system")
+ _require_chains(biounit, selections.receptor, view_name="receptor")
+ system_mask = np.isin(biounit.chain_id, list(selections.system))
+ system_mask |= _water_mask(biounit, annotation, options.system_waters)
+ receptor_mask = np.isin(biounit.chain_id, list(selections.receptor))
+ receptor_mask |= _water_mask(biounit, annotation, options.receptor_waters)
+ return ReconstructedSystem(
+ biounit=biounit,
+ system=biounit[system_mask],
+ receptor=biounit[receptor_mask],
+ )
+
+
+def save_reconstructed_system(
+ source_mmcif: Path | str,
+ annotation: AnnotationRow,
+ *,
+ outputs: SystemReconstructionOutputs,
+ biounit_chains: pd.DataFrame,
+ options: SystemReconstructionOptions = SystemReconstructionOptions(),
+ overwrite: bool = False,
+ reconstructed: ReconstructedSystem | None = None,
+) -> dict[str, Path]:
+ """Reconstruct a system and write exactly the requested mmCIF/FASTA files.
+
+ No PDB files or assembly-rotated ligand SDFs are produced. Output parents
+ are created automatically. Existing files are rejected unless
+ ``overwrite=True``. A previously reconstructed in-memory view may be
+ supplied to avoid parsing and expanding the source assembly again.
+ """
+ requested: dict[str, Path] = {
+ name: Path(path)
+ for name, path in {
+ "system_cif": outputs.system_cif,
+ "receptor_cif": outputs.receptor_cif,
+ "sequences_fasta": outputs.sequences_fasta,
+ }.items()
+ if path is not None
+ }
+ if not requested:
+ raise ValueError("At least one reconstruction output path is required")
+ if len(set(requested.values())) != len(requested):
+ raise ValueError("Reconstruction output paths must be unique")
+ existing = [path for path in requested.values() if path.exists()]
+ if existing and not overwrite:
+ raise FileExistsError(
+ "Refusing to overwrite reconstruction outputs: "
+ + ", ".join(str(path) for path in existing)
+ )
+
+ if reconstructed is None:
+ reconstructed = reconstruct_system(
+ source_mmcif,
+ annotation,
+ biounit_chains=biounit_chains,
+ options=options,
+ )
+ system_id = str(annotation.get("system_id", "plinder_system"))
+ for path in requested.values():
+ path.parent.mkdir(parents=True, exist_ok=True)
+ from plinder.data.annotations.cif_utils import (
+ get_label_asym_sequences,
+ read_mmcif_container,
+ )
+
+ source_block = read_mmcif_container(Path(source_mmcif))
+ source_sequences = get_label_asym_sequences(source_block)
+
+ def output_protein_sequences(atoms: struc.AtomArray) -> dict[str, str]:
+ return {
+ str(chain_id): source_sequences[source_asym_id]
+ for chain_id in np.unique(atoms.chain_id)
+ for source_asym_id in [str(chain_id).split(".", maxsplit=1)[-1]]
+ if source_asym_id in source_sequences
+ }
+
+ if "system_cif" in requested:
+ save_cif_file(
+ reconstructed.system,
+ system_id,
+ requested["system_cif"],
+ source_block=source_block,
+ protein_sequences=output_protein_sequences(reconstructed.system),
+ )
+ if "receptor_cif" in requested:
+ save_cif_file(
+ reconstructed.receptor,
+ system_id,
+ requested["receptor_cif"],
+ source_block=source_block,
+ protein_sequences=output_protein_sequences(reconstructed.receptor),
+ )
+ if "sequences_fasta" in requested:
+ asym_to_sequence = source_sequences
+ receptor_chain_ids = _select_chains(
+ annotation,
+ biounit_chains,
+ options,
+ ).receptor
+ output_chain_ids = _output_asym_ids(
+ list(dict.fromkeys(reconstructed.receptor.chain_id.astype(str)))
+ )
+ missing_sequences = sorted(
+ chain_id
+ for chain_id in receptor_chain_ids
+ if chain_id.split(".", maxsplit=1)[-1] not in asym_to_sequence
+ )
+ if missing_sequences:
+ raise ValueError(
+ "Source mmCIF has no entity_poly sequence for reconstructed "
+ f"receptor chains {missing_sequences}"
+ )
+ with requested["sequences_fasta"].open("w") as fasta:
+ for chain_id in sorted(receptor_chain_ids):
+ asym_id = chain_id.split(".", maxsplit=1)[-1]
+ fasta.write(
+ f">{output_chain_ids[chain_id]}\n{asym_to_sequence[asym_id]}\n"
+ )
+ return requested
diff --git a/src/plinder/data/utils/annotations/static_files/artifacts_badlist.csv b/src/plinder/data/annotations/static_files/artifacts_badlist.csv
similarity index 80%
rename from src/plinder/data/utils/annotations/static_files/artifacts_badlist.csv
rename to src/plinder/data/annotations/static_files/artifacts_badlist.csv
index 18b070a24..76f469b78 100644
--- a/src/plinder/data/utils/annotations/static_files/artifacts_badlist.csv
+++ b/src/plinder/data/annotations/static_files/artifacts_badlist.csv
@@ -27,12 +27,12 @@
3PG
3SY
3V3
-543
-6JZ
+# 543 # OBS, no REL successor
+# 6JZ # OBS, no REL successor
6PE
7E8
7E9
-7I7
+# 7I7 # OBS, no REL successor
7N5
7PE
7PG
@@ -51,9 +51,9 @@ B3H
B3P
B4T
B4X
-BAM
+# BAM # OBS -> BEN (already listed)
BCN
-BDN
+# BDN # OBS -> BEN (already listed)
BE7
BEN
BET
@@ -98,8 +98,8 @@ DIO
DKA
DMF
DMI
-DMR
-DOX
+# DMR # OBS -> MLT (already listed)
+# DOX # OBS -> DIO (already listed)
DPG
DR6
DRE
@@ -107,7 +107,7 @@ DTD
DTT
DTU
DTV
-E4N
+# E4N # OBS -> NET (already listed)
EAP
EEE
EPE
@@ -184,13 +184,13 @@ OCT
OES
OGA
OP2
-OTE
+# OTE # OBS -> C8E (already listed)
P03
P15
P1O
P22
P25
-P2K
+# P2K # OBS -> P6G (already listed)
P33
P3G
P4C
diff --git a/src/plinder/data/utils/annotations/static_files/ligand_list.tsv b/src/plinder/data/annotations/static_files/ligand_list.tsv
similarity index 100%
rename from src/plinder/data/utils/annotations/static_files/ligand_list.tsv
rename to src/plinder/data/annotations/static_files/ligand_list.tsv
diff --git a/src/plinder/data/annotations/static_files/prodigy_classifier.npz b/src/plinder/data/annotations/static_files/prodigy_classifier.npz
new file mode 100644
index 000000000..996bc5af5
Binary files /dev/null and b/src/plinder/data/annotations/static_files/prodigy_classifier.npz differ
diff --git a/src/plinder/data/utils/annotations/utils.py b/src/plinder/data/annotations/utils.py
similarity index 65%
rename from src/plinder/data/utils/annotations/utils.py
rename to src/plinder/data/annotations/utils.py
index 6a6e2c252..22af4d086 100644
--- a/src/plinder/data/utils/annotations/utils.py
+++ b/src/plinder/data/annotations/utils.py
@@ -8,6 +8,39 @@
from pydantic import BaseModel
+EXCLUDE_DESCRIPTION_PREFIX = "[EXCLUDE]"
+CUSTOM_EXPORT_DESCRIPTION_PREFIX = "[CUSTOM_EXPORT]"
+
+
+def _description_text(description: str | None) -> str:
+ if not description:
+ return ""
+ return str(description).lstrip().replace("\n", " ").strip()
+
+
+def description_excluded_from_column_docs(description: str | None) -> bool:
+ """Return whether a field is intentionally absent from column docs."""
+ return _description_text(description).startswith(EXCLUDE_DESCRIPTION_PREFIX)
+
+
+def description_excluded_from_flat_export(description: str | None) -> bool:
+ """Return whether automatic flat export must skip a field."""
+ return _description_text(description).startswith(
+ (
+ EXCLUDE_DESCRIPTION_PREFIX,
+ CUSTOM_EXPORT_DESCRIPTION_PREFIX,
+ )
+ )
+
+
+def column_description_text(description: str | None) -> str:
+ """Return public prose with any export marker removed."""
+ text = _description_text(description)
+ for prefix in (EXCLUDE_DESCRIPTION_PREFIX, CUSTOM_EXPORT_DESCRIPTION_PREFIX):
+ if text.startswith(prefix):
+ return text.removeprefix(prefix).lstrip()
+ return text
+
class DocBaseModel(BaseModel):
@classmethod
@@ -31,6 +64,7 @@ def get_descriptions_and_types(cls) -> dict[str, tuple[str | None, str | None]]:
if hasattr(prop, "func"):
dtype = prop.func.__annotations__.get("return", None)
descriptions[name] = (prop.__doc__, dtype)
+
return descriptions
@classmethod
@@ -39,14 +73,14 @@ def document_properties(
) -> Generator[tuple[str, str | None, str], Any, Any]:
for field, field_info in cls.get_descriptions_and_types().items():
description, dtype = field_info
+ if description_excluded_from_column_docs(description):
+ continue
if field.startswith(prefix):
name = field
else:
name = f"{prefix}_{field}"
if description:
- descr = description.lstrip().replace("\n", " ")
- if descr.startswith("__"):
- continue
+ descr = column_description_text(description)
else:
descr = "[DESCRIPTION MISSING]"
if "pass_criteria" in name and "validation" not in name:
diff --git a/src/plinder/data/clusters.py b/src/plinder/data/clusters.py
index c17d06772..9bfadb7d5 100644
--- a/src/plinder/data/clusters.py
+++ b/src/plinder/data/clusters.py
@@ -1,426 +1,3856 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
+import gc
+import hashlib
+import heapq
+import json
+import os
+import sys
+from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
+from dataclasses import dataclass
+from multiprocessing import get_context
from pathlib import Path
+from shutil import copyfile, copytree, rmtree
+from textwrap import dedent
from time import time
-from typing import Callable, TypeVar
+from typing import Any, Callable, Iterable, Literal, Mapping, Sequence, TypeVar, cast
+
+if sys.platform == "darwin":
+ # For macOS only: allow multiple OpenMP runtimes to coexist
+ # (needed on macOS with conda)
+ os.environ.setdefault("KMP_DUPLICATE_LIB_OK", "TRUE")
import networkit as nk
import numpy as np
import pandas as pd
+import pyarrow.parquet as pq
+from numpy.typing import NDArray
-from plinder.core import scores
+from plinder.core.scores.metrics import (
+ GATED_LIGAND_DIAGNOSTIC_METRICS,
+ is_chemical_cluster_metric,
+)
from plinder.core.utils.log import setup_logger
-from plinder.core.utils.schemas import CLUSTER_SCHEMA
LOG = setup_logger(__name__)
T = TypeVar("T")
+ClusterEntity = Literal["ligand", "interface"]
+COMPONENT_EDGE_COLUMNS = ["query_node", "target_node"]
+COMPONENT_REDUCTION_VERSION = 1
+COMPONENT_REDUCTION_DIRECTIONS = (False,)
+SYMMETRIC_EDGE_BUCKET_COUNT = 64
+SYMMETRIC_EDGE_COLUMNS = ["query_node", "target_node", "similarity"]
+INTERFACE_CLUSTER_METRICS = frozenset({"interface_qcov", "interface_side_qcov"})
+INTERFACE_REPRESENTATIVES = Path("index/interface_representatives.parquet")
+INTERFACE_HALF_REPRESENTATIVES = Path("index/interface_half_representatives.parquet")
+INTERFACE_MEMBERSHIP = Path("index/interface_membership.parquet")
-def make_nk_components(
- graph: nk.graph.Graph,
- is_directed: bool,
-) -> tuple[list[tuple[int, str]], int]:
- """
- Get connected component clusters
-
- Parameters
- ----------
- graph : nk.graph.Graph
- Input graph
- is_directed : bool
- is directed graph
-
- Returns
- -------
- tuple[list[tuple[int, str]], int]
- """
- if is_directed:
- cc = nk.components.StronglyConnectedComponents(graph)
+
+def _set_slurm_memory_limit(connection: Any, share: int) -> None:
+ memory_mb = int(os.environ.get("SLURM_MEM_PER_NODE", "0"))
+ if memory_mb > 0:
+ connection.execute("SET memory_limit = ?", [f"{memory_mb * share // 5}MB"])
+
+
+def _cluster_root(data_dir: Path, entity_type: ClusterEntity) -> Path:
+ if entity_type == "ligand":
+ return data_dir / "ligand_clusters"
+ if entity_type == "interface":
+ return data_dir / "interface_clusters"
+ raise ValueError(f"unsupported cluster entity type: {entity_type}")
+
+
+def _sampling_root(data_dir: Path, entity_type: ClusterEntity) -> Path:
+ if entity_type == "ligand":
+ return data_dir / "ligand_sampling"
+ if entity_type == "interface":
+ return data_dir / "interface_sampling"
+ raise ValueError(f"unsupported cluster entity type: {entity_type}")
+
+
+def _cluster_node_column(entity_type: ClusterEntity) -> str:
+ return "ligand_id" if entity_type == "ligand" else "system_id"
+
+
+def _symmetric_edge_plan_path(data_dir: Path, entity_type: ClusterEntity) -> Path:
+ return _cluster_root(data_dir, entity_type) / "symmetric_edges" / "plan.json"
+
+
+def _component_node_universe_paths(
+ data_dir: Path, entity_type: ClusterEntity
+) -> tuple[Path, Path]:
+ root = _cluster_root(data_dir, entity_type) / "reductions"
+ return root / "node_universe.parquet", root / "node_universe.json"
+
+
+def _component_node_universe_sources(
+ data_dir: Path, entity_type: ClusterEntity
+) -> dict[str, dict[str, str | int]]:
+ """Return every source that defines one cached clustering universe."""
+ if entity_type == "ligand":
+ paths = {"annotation": data_dir / "index/annotation_table.parquet"}
else:
- cc = nk.components.ConnectedComponents(graph)
- cc.run()
- components = cc.getComponents()
- return (
- [
- (node, f"c{idx}")
- for idx, component in enumerate(sorted(components, key=len, reverse=True))
- for node in component
- ],
- len(components),
+ paths = {
+ "annotation": data_dir / "index/interface_annotation_table.parquet",
+ "representatives": data_dir / INTERFACE_REPRESENTATIVES,
+ "half_representatives": data_dir / INTERFACE_HALF_REPRESENTATIVES,
+ "membership": data_dir / INTERFACE_MEMBERSHIP,
+ }
+ return {name: _component_source_signature(path) for name, path in paths.items()}
+
+
+def _empty_component_edges() -> pd.DataFrame:
+ """Return an empty, consistently typed component-edge table."""
+ return pd.DataFrame(
+ {
+ "query_node": pd.Series(dtype="int64"),
+ "target_node": pd.Series(dtype="int64"),
+ }
)
-def make_nk_communities(
- graph: nk.graph.Graph, directed: bool
-) -> tuple[list[tuple[int, str]], int]:
+def _reduce_undirected_component_edges(edges: pd.DataFrame) -> pd.DataFrame:
+ """Replace an undirected edge table with a connectivity-equivalent forest.
+
+ The returned forest contains at most ``number_of_nodes - number_of_components``
+ edges. Replacing any subset of an undirected graph with such a forest preserves
+ the connected components of the union with every other edge subset, which makes
+ this reduction safe to apply repeatedly to independently generated shards.
"""
- Get community clusters
+ if edges.empty:
+ return _empty_component_edges()
+ missing = sorted(set(COMPONENT_EDGE_COLUMNS).difference(edges.columns))
+ if missing:
+ raise ValueError(f"component edges are missing columns {missing}")
- Parameters
- ----------
- graph : nk.graph.Graph
+ edge_array = edges[COMPONENT_EDGE_COLUMNS].to_numpy(dtype=np.int64, copy=False)
+ edge_array = edge_array[edge_array[:, 0] != edge_array[:, 1]]
+ if not len(edge_array):
+ return _empty_component_edges()
+ edge_array = np.column_stack(
+ (
+ np.minimum(edge_array[:, 0], edge_array[:, 1]),
+ np.maximum(edge_array[:, 0], edge_array[:, 1]),
+ )
+ )
+ edge_array = np.unique(edge_array, axis=0)
+ nodes = np.unique(edge_array)
+ query_codes = np.searchsorted(nodes, edge_array[:, 0]).astype(np.uint, copy=False)
+ target_codes = np.searchsorted(nodes, edge_array[:, 1]).astype(np.uint, copy=False)
+ graph = nk.GraphFromCoo(
+ (query_codes, target_codes),
+ n=len(nodes),
+ directed=False,
+ )
+ components = nk.components.ConnectedComponents(graph)
+ components.run()
- Returns
- -------
- tuple[list[tuple[int, str]], int]
- """
- assert not directed
- communities = nk.community.detectCommunities(graph, nk.community.PLM(graph))
- community_list = [
- communities.getMembers(i) for i in range(communities.numberOfSubsets())
- ]
- return (
- [
- (node, f"c{idx}")
- for idx, component in enumerate(
- sorted(community_list, key=len, reverse=True)
- )
- for node in component
- ],
- len(community_list),
+ query_parts: list[NDArray[np.int64]] = []
+ target_parts: list[NDArray[np.int64]] = []
+ for component in components.getComponents():
+ members = np.sort(nodes[np.asarray(component, dtype=np.int64)])
+ if len(members) < 2:
+ continue
+ query_parts.append(np.full(len(members) - 1, members[0], dtype=np.int64))
+ target_parts.append(members[1:].astype(np.int64, copy=False))
+ if not query_parts:
+ return _empty_component_edges()
+ return pd.DataFrame(
+ {
+ "query_node": np.concatenate(query_parts),
+ "target_node": np.concatenate(target_parts),
+ }
)
-def make_nk_graph(
- df: pd.DataFrame,
- num_systems: int,
- system_ids_cat: pd.CategoricalDtype,
- directed: bool,
- weighted: bool,
- query_col: str = "query_system",
- target_col: str = "target_system",
- similarity_col: str = "similarity",
-) -> tuple[nk.graph.Graph, pd.CategoricalDtype]:
- """
- Make networkit graphs
-
- Parameters
- ----------
- df : pd.DataFrame
- Dataframe of edges
- num_systems : int
- Number of systems
- system_ids_cat : pd.CategoricalDtype
- system ids, must match exactly the entries in df
- directed : bool
- Whether to make directed graph
-
- Returns
- -------
- graph
+def _reduce_directed_component_edges(edges: pd.DataFrame) -> pd.DataFrame:
+ """Replace directed edges with an exact reachability-preserving subgraph.
+
+ Each local strongly connected component is represented by a bidirectional
+ star, while unique arcs in its condensation DAG are retained. Reachability
+ is therefore unchanged, even after independently reduced shards are united.
+ Unlike an undirected forest, the condensation DAG can remain large because
+ an arbitrary directed graph has no generally linear-size reachability
+ representation.
"""
- df[[query_col, target_col]] = df[[query_col, target_col]].astype(system_ids_cat)
- if weighted:
- graph = nk.GraphFromCoo(
+ if edges.empty:
+ return _empty_component_edges()
+ missing = sorted(set(COMPONENT_EDGE_COLUMNS).difference(edges.columns))
+ if missing:
+ raise ValueError(f"component edges are missing columns {missing}")
+ edge_array = edges[COMPONENT_EDGE_COLUMNS].to_numpy(dtype=np.int64, copy=False)
+ edge_array = edge_array[edge_array[:, 0] != edge_array[:, 1]]
+ if not len(edge_array):
+ return _empty_component_edges()
+ edge_array = np.unique(edge_array, axis=0)
+ nodes = np.unique(edge_array)
+ query_codes = np.searchsorted(nodes, edge_array[:, 0]).astype(np.uint, copy=False)
+ target_codes = np.searchsorted(nodes, edge_array[:, 1]).astype(np.uint, copy=False)
+ graph = nk.GraphFromCoo(
+ (query_codes, target_codes),
+ n=len(nodes),
+ directed=True,
+ )
+ components = nk.components.StronglyConnectedComponents(graph)
+ components.run()
+
+ component_by_node = np.empty(len(nodes), dtype=np.int64)
+ representatives: list[int] = []
+ query_parts: list[NDArray[np.int64]] = []
+ target_parts: list[NDArray[np.int64]] = []
+ for component_index, component in enumerate(components.getComponents()):
+ component_codes = np.asarray(component, dtype=np.int64)
+ component_by_node[component_codes] = component_index
+ members = np.sort(nodes[component_codes])
+ representative = int(members[0])
+ representatives.append(representative)
+ if len(members) < 2:
+ continue
+ others = members[1:].astype(np.int64, copy=False)
+ roots = np.full(len(others), representative, dtype=np.int64)
+ query_parts.extend([roots, others])
+ target_parts.extend([others, roots])
+
+ query_components = component_by_node[query_codes]
+ target_components = component_by_node[target_codes]
+ between_components = query_components != target_components
+ if between_components.any():
+ representatives_array = np.asarray(representatives, dtype=np.int64)
+ condensation_edges = np.column_stack(
(
- df[similarity_col].values / 100.0,
- (
- df[query_col].cat.codes.to_numpy(dtype=np.uint, copy=False),
- df[target_col].cat.codes.to_numpy(dtype=np.uint, copy=False),
- ),
- ),
- weighted=True,
- n=num_systems,
- directed=directed,
+ representatives_array[query_components[between_components]],
+ representatives_array[target_components[between_components]],
+ )
+ )
+ condensation_edges = np.unique(condensation_edges, axis=0)
+ query_parts.append(condensation_edges[:, 0])
+ target_parts.append(condensation_edges[:, 1])
+ if not query_parts:
+ return _empty_component_edges()
+ return pd.DataFrame(
+ {
+ "query_node": np.concatenate(query_parts),
+ "target_node": np.concatenate(target_parts),
+ }
+ )
+
+
+class _ComponentEdgeAccumulator:
+ """Bound memory while repeatedly reducing independent edge batches."""
+
+ def __init__(
+ self,
+ fan_in: int,
+ reducer: Callable[[pd.DataFrame], pd.DataFrame],
+ ) -> None:
+ if fan_in < 2:
+ raise ValueError("component forest fan-in must be at least two")
+ self.fan_in = fan_in
+ self.reducer = reducer
+ self.levels: list[list[pd.DataFrame]] = []
+
+ def add(self, edges: pd.DataFrame) -> None:
+ forest = self.reducer(edges)
+ if not forest.empty:
+ self._push(forest, level=0)
+
+ def _push(self, forest: pd.DataFrame, *, level: int) -> None:
+ while len(self.levels) <= level:
+ self.levels.append([])
+ self.levels[level].append(forest)
+ if len(self.levels[level]) < self.fan_in:
+ return
+ merged = self.reducer(pd.concat(self.levels[level], ignore_index=True))
+ self.levels[level] = []
+ if not merged.empty:
+ self._push(merged, level=level + 1)
+
+ def finish(self) -> pd.DataFrame:
+ forests = [forest for level in self.levels for forest in level]
+ if not forests:
+ return _empty_component_edges()
+ while len(forests) > 1:
+ reduced: list[pd.DataFrame] = []
+ for start in range(0, len(forests), self.fan_in):
+ group = forests[start : start + self.fan_in]
+ if len(group) == 1:
+ reduced.append(group[0])
+ else:
+ reduced.append(self.reducer(pd.concat(group, ignore_index=True)))
+ forests = reduced
+ return forests[0]
+
+
+def _component_labels_from_edges(
+ *, edges: pd.DataFrame, nodes: Sequence[str], directed: bool
+) -> pd.DataFrame:
+ """Assign deterministic size-ordered labels to a reduced edge table."""
+ if not nodes:
+ return pd.DataFrame(
+ {
+ "ligand_id": pd.Series(dtype="object"),
+ "label": pd.Series(dtype="object"),
+ }
)
+ if edges.empty:
+ graph = nk.Graph(len(nodes), directed=directed)
else:
+ edge_array = edges[COMPONENT_EDGE_COLUMNS].to_numpy(dtype=np.int64, copy=False)
graph = nk.GraphFromCoo(
(
- df[query_col].cat.codes.to_numpy(dtype=np.uint, copy=False),
- df[target_col].cat.codes.to_numpy(dtype=np.uint, copy=False),
+ edge_array[:, 0].astype(np.uint, copy=False),
+ edge_array[:, 1].astype(np.uint, copy=False),
),
- n=num_systems,
+ n=len(nodes),
directed=directed,
)
- return graph, system_ids_cat
+ if directed:
+ components = nk.components.StronglyConnectedComponents(graph)
+ else:
+ components = nk.components.ConnectedComponents(graph)
+ components.run()
+ ordered = sorted(
+ components.getComponents(),
+ key=lambda component: (
+ -len(component),
+ min(nodes[node] for node in component),
+ ),
+ )
+ labels = [""] * len(nodes)
+ for component_index, component in enumerate(ordered):
+ label = f"c{component_index}"
+ for node in component:
+ labels[node] = label
+ return pd.DataFrame({"ligand_id": list(nodes), "label": labels})
-def get_labels(
- graph: nk.graph.Graph,
- system_ids_and_singletons: set[str],
- system_ids_cat: pd.CategoricalDtype,
- clustering_fn: Callable[[nk.graph.Graph, bool], tuple[list[tuple[int, str]], int]],
- directed: bool,
-) -> list[dict[str, str]]:
- """
- Get community clusters
-
- Parameters
- ----------
- graph : nk.graph.Graph
- Input graph
- system_ids_and_singletons : set[str]
- All system ids, both the ones in graph \
- and singletons not in graph
- system_ids_cat : pd.CategoricalDtype
- system ids categories
- clustering_fn : Callable
- clustering function, could be a
- component or community detector
- directed : bool
- Is directed?
-
- Returns
- -------
- list[dict[str, str]]
+def make_exact_threshold_components(
+ *,
+ edge_batches: Iterable[pd.DataFrame],
+ all_nodes: Iterable[str],
+ thresholds: Sequence[int],
+ query_column: str = "query_node",
+ target_column: str = "target_node",
+ similarity_column: str = "similarity",
+ forest_fan_in: int = 8,
+ directed: bool = False,
+) -> dict[int, pd.DataFrame]:
+ """Build exact weak or strong components at many thresholds in one edge scan.
+
+ Each input edge is assigned to exactly one descending score band. Every
+ undirected batch is reduced to a spanning forest. Directed batches retain a
+ reachability-preserving SCC/condensation representation. These reduced
+ tables are recursively merged before the next threshold is labelled.
"""
- node_labels, max_cluster = clustering_fn(graph, directed)
- labels: list[dict[str, str]] = [
- {
- "system_id": system_ids_cat.categories[sys_int_id],
- "label": cluster_id,
+ nodes, reductions = reduce_threshold_component_edges(
+ edge_batches=edge_batches,
+ all_nodes=all_nodes,
+ thresholds=thresholds,
+ query_column=query_column,
+ target_column=target_column,
+ similarity_column=similarity_column,
+ forest_fan_in=forest_fan_in,
+ directed_modes=[directed],
+ )
+ return _labels_from_threshold_reductions(
+ nodes=nodes,
+ reductions=reductions[directed],
+ directed=directed,
+ )
+
+
+def reduce_threshold_component_edges(
+ *,
+ edge_batches: Iterable[pd.DataFrame],
+ all_nodes: Iterable[str],
+ thresholds: Sequence[int],
+ query_column: str = "query_node",
+ target_column: str = "target_node",
+ similarity_column: str = "similarity",
+ forest_fan_in: int = 8,
+ directed_modes: Sequence[bool] = (False, True),
+) -> tuple[list[str], dict[bool, dict[int, pd.DataFrame]]]:
+ """Reduce threshold bands for weak and strong components in one edge scan."""
+ ordered_thresholds = sorted(set(thresholds), reverse=True)
+ if not ordered_thresholds:
+ raise ValueError("at least one component threshold is required")
+ if ordered_thresholds[0] > 100 or ordered_thresholds[-1] < 0:
+ raise ValueError("component thresholds must be in [0, 100]")
+ modes = tuple(dict.fromkeys(directed_modes))
+ if not modes:
+ raise ValueError("at least one component direction mode is required")
+ nodes = sorted(set(map(str, all_nodes)))
+ node_indexes = {node: index for index, node in enumerate(nodes)}
+ accumulators = {
+ directed: {
+ threshold: _ComponentEdgeAccumulator(
+ forest_fan_in,
+ (
+ _reduce_directed_component_edges
+ if directed
+ else _reduce_undirected_component_edges
+ ),
+ )
+ for threshold in ordered_thresholds
+ }
+ for directed in modes
+ }
+ required = {query_column, target_column, similarity_column}
+
+ for batch in edge_batches:
+ missing = sorted(required.difference(batch.columns))
+ if missing:
+ raise ValueError(f"component edge batch is missing columns {missing}")
+ if batch.empty:
+ continue
+ values = batch[[query_column, target_column, similarity_column]].dropna()
+ if values.empty:
+ continue
+ query_indexes = values[query_column].astype(str).map(node_indexes)
+ target_indexes = values[target_column].astype(str).map(node_indexes)
+ similarities = pd.to_numeric(values[similarity_column], errors="coerce")
+ valid = query_indexes.notna() & target_indexes.notna() & similarities.notna()
+ if not valid.any():
+ continue
+ query_array = query_indexes.loc[valid].to_numpy(dtype=np.int64, copy=False)
+ target_array = target_indexes.loc[valid].to_numpy(dtype=np.int64, copy=False)
+ similarity_array = similarities.loc[valid].to_numpy(dtype=float, copy=False)
+ upper_bound = np.inf
+ for threshold in ordered_thresholds:
+ in_band = (similarity_array >= threshold) & (similarity_array < upper_bound)
+ if in_band.any():
+ band_edges = pd.DataFrame(
+ {
+ "query_node": query_array[in_band],
+ "target_node": target_array[in_band],
+ }
+ )
+ for directed in modes:
+ accumulators[directed][threshold].add(band_edges)
+ upper_bound = threshold
+
+ return nodes, {
+ directed: {
+ threshold: accumulators[directed][threshold].finish()
+ for threshold in ordered_thresholds
}
- for sys_int_id, cluster_id in node_labels
+ for directed in modes
+ }
+
+
+def _labels_from_threshold_reductions(
+ *,
+ nodes: Sequence[str],
+ reductions: Mapping[int, pd.DataFrame],
+ directed: bool,
+) -> dict[int, pd.DataFrame]:
+ """Compose descending score-band reductions into threshold labels."""
+ reducer = (
+ _reduce_directed_component_edges
+ if directed
+ else _reduce_undirected_component_edges
+ )
+ result: dict[int, pd.DataFrame] = {}
+ cumulative_edges = _empty_component_edges()
+ for threshold in sorted(reductions, reverse=True):
+ band_edges = reductions[threshold]
+ cumulative_edges = reducer(
+ pd.concat([cumulative_edges, band_edges], ignore_index=True)
+ )
+ result[threshold] = _component_labels_from_edges(
+ edges=cumulative_edges,
+ nodes=nodes,
+ directed=directed,
+ )
+ return result
+
+
+def make_exact_weak_and_strong_threshold_components(
+ *,
+ edge_batches: Iterable[pd.DataFrame],
+ all_nodes: Iterable[str],
+ thresholds: Sequence[int],
+ query_column: str = "query_node",
+ target_column: str = "target_node",
+ similarity_column: str = "similarity",
+ forest_fan_in: int = 8,
+) -> dict[bool, dict[int, pd.DataFrame]]:
+ """Build weak and strong component labels from a single edge scan."""
+ nodes, reductions = reduce_threshold_component_edges(
+ edge_batches=edge_batches,
+ all_nodes=all_nodes,
+ thresholds=thresholds,
+ query_column=query_column,
+ target_column=target_column,
+ similarity_column=similarity_column,
+ forest_fan_in=forest_fan_in,
+ directed_modes=[False, True],
+ )
+ return {
+ directed: _labels_from_threshold_reductions(
+ nodes=nodes,
+ reductions=reductions[directed],
+ directed=directed,
+ )
+ for directed in [False, True]
+ }
+
+
+def _component_node_hash(nodes: Sequence[str]) -> str:
+ digest = hashlib.sha256()
+ for node in nodes:
+ encoded = node.encode()
+ digest.update(len(encoded).to_bytes(8, byteorder="little"))
+ digest.update(encoded)
+ return digest.hexdigest()
+
+
+def _component_selection_hash(
+ *, nodes: Sequence[str], eligible_systems: set[str] | None
+) -> str:
+ selected = list(nodes)
+ if eligible_systems is not None:
+ selected.extend(f"system:{system_id}" for system_id in sorted(eligible_systems))
+ return _component_node_hash(selected)
+
+
+def _component_source_signature(path: Path) -> dict[str, str | int]:
+ stat = path.stat()
+ return {
+ "path": str(path.resolve()),
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ }
+
+
+# Each chemical (fingerprint) metric aggregates its own raw directed-edge shards;
+# every protein/pocket score metric shares the holo search-score dataset.
+_CHEMICAL_METRIC_SCORES_DIR = {
+ "tanimoto_similarity_ecfp4_1024": "ligand_scores",
+ "jaccard_similarity_mhfp6_2048": "mhfp6_scores",
+}
+
+
+def _raw_component_score_sources(
+ *,
+ data_dir: Path,
+ metric: str,
+ entity_type: ClusterEntity = "ligand",
+) -> list[Path]:
+ """Return raw score sources before reciprocal edge aggregation."""
+ scores_dir = _CHEMICAL_METRIC_SCORES_DIR.get(metric)
+ if entity_type == "interface":
+ if scores_dir is not None:
+ raise ValueError("interface clustering does not use chemical scores")
+ return sorted((data_dir / "interface_scores").glob("shard=*.parquet"))
+ if scores_dir is not None:
+ return sorted((data_dir / scores_dir).glob("*.parquet"))
+ compact_sources = sorted(
+ (data_dir / "exports" / "ligand_similarity_scores").glob("*.parquet")
+ )
+ if compact_sources:
+ return compact_sources
+ return sorted((data_dir / "scores" / "search_db=holo").rglob("*.parquet"))
+
+
+def _symmetric_edge_plan_hash(payload: Mapping[str, Any]) -> str:
+ return hashlib.sha256(
+ json.dumps(payload, sort_keys=True, separators=(",", ":")).encode()
+ ).hexdigest()
+
+
+def prepare_symmetric_edge_plan(
+ *,
+ data_dir: Path,
+ metrics: Sequence[str],
+ source_batch_size: int = 20,
+ bucket_count: int = SYMMETRIC_EDGE_BUCKET_COUNT,
+ entity_type: ClusterEntity = "ligand",
+) -> dict[str, Any]:
+ """Plan sharded reciprocal-minimum edges without scanning score contents."""
+ if source_batch_size < 1:
+ raise ValueError("symmetric-edge source batch size must be positive")
+ if bucket_count < 1:
+ raise ValueError("symmetric-edge bucket count must be positive")
+ selected_metrics = list(dict.fromkeys(metrics))
+ if entity_type == "interface" and (
+ not selected_metrics
+ or not set(selected_metrics).issubset(INTERFACE_CLUSTER_METRICS)
+ ):
+ raise ValueError(
+ "interface clustering supports interface_qcov and interface_side_qcov"
+ )
+ chemical_metrics = [
+ metric for metric in selected_metrics if is_chemical_cluster_metric(metric)
+ ]
+ score_metrics = [
+ metric for metric in selected_metrics if not is_chemical_cluster_metric(metric)
]
- # Add singletons
- singletons = set(system_ids_and_singletons) - {
- system_ids_cat.categories[node] for node in graph.iterNodes()
+ # Group metrics by score source; interface exports and chemical metrics
+ # have separate sources, while protein/pocket metrics share holo scores.
+ source_groups: list[tuple[str, list[str]]] = []
+ if entity_type == "interface":
+ raw_metrics: list[str] = []
+ for metric in selected_metrics:
+ export = (
+ data_dir
+ / "exports"
+ / (
+ "interface_similarity_scores.parquet"
+ if metric == "interface_qcov"
+ else "interface_half_similarity_scores.parquet"
+ )
+ )
+ if export.is_file():
+ source_groups.append((f"interface_export_{metric}", [metric]))
+ else:
+ raw_metrics.append(metric)
+ if raw_metrics:
+ source_groups.append(("interface", raw_metrics))
+ else:
+ if score_metrics:
+ source_groups.append(("score", score_metrics))
+ source_groups.extend(("chemical", [metric]) for metric in chemical_metrics)
+ batches: list[dict[str, Any]] = []
+ for kind, source_metrics in source_groups:
+ if not source_metrics:
+ continue
+ if kind.startswith("interface_export_"):
+ export_name = (
+ "interface_similarity_scores.parquet"
+ if source_metrics[0] == "interface_qcov"
+ else "interface_half_similarity_scores.parquet"
+ )
+ sources = [data_dir / "exports" / export_name]
+ else:
+ sources = _raw_component_score_sources(
+ data_dir=data_dir,
+ metric=source_metrics[0],
+ entity_type=entity_type,
+ )
+ if not sources:
+ if entity_type != "interface":
+ raise FileNotFoundError(
+ f"no raw {kind} score sources found for {source_metrics}"
+ )
+ nodes, _ = component_node_universe(
+ data_dir=data_dir,
+ metric=source_metrics[0],
+ entity_type=entity_type,
+ )
+ if nodes:
+ raise FileNotFoundError(
+ "no raw interface score sources found for a non-empty "
+ "interface universe"
+ )
+ for start in range(0, len(sources), source_batch_size):
+ selected_sources = sources[start : start + source_batch_size]
+ relative_sources = [
+ source.resolve().relative_to(data_dir.resolve()).as_posix()
+ for source in selected_sources
+ ]
+ key = hashlib.sha256(
+ json.dumps(
+ [kind, relative_sources],
+ separators=(",", ":"),
+ ).encode()
+ ).hexdigest()[:16]
+ batches.append(
+ {
+ "key": key,
+ "kind": kind,
+ "metrics": source_metrics,
+ "sources": [
+ _component_source_signature(source)
+ for source in selected_sources
+ ],
+ }
+ )
+ payload: dict[str, Any] = {
+ "version": 1,
+ "entity_type": entity_type,
+ "metrics": selected_metrics,
+ "source_batch_size": source_batch_size,
+ "bucket_count": bucket_count,
+ "batches": batches,
}
- for i, system_id in enumerate(singletons):
- labels.append(
- {
- "system_id": system_id,
- "label": f"c{max_cluster + i}",
- }
+ payload["plan_hash"] = _symmetric_edge_plan_hash(payload)
+ plan_path = _symmetric_edge_plan_path(data_dir, entity_type)
+ if plan_path.is_file():
+ try:
+ if json.loads(plan_path.read_text()) == payload:
+ return payload
+ except (OSError, ValueError, json.JSONDecodeError):
+ pass
+ plan_path.parent.mkdir(exist_ok=True, parents=True)
+ temporary = plan_path.with_suffix(".tmp.json")
+ temporary.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n")
+ temporary.replace(plan_path)
+ return payload
+
+
+def load_symmetric_edge_plan(
+ data_dir: Path,
+ *,
+ entity_type: ClusterEntity = "ligand",
+ metrics: Sequence[str] | None = None,
+) -> dict[str, Any]:
+ """Load and validate the exact raw-score inputs for symmetrization."""
+ plan_path = _symmetric_edge_plan_path(data_dir, entity_type)
+ if not plan_path.is_file():
+ raise FileNotFoundError(
+ f"symmetric-edge planning must run before clustering: {plan_path}"
)
- return labels
+ plan = cast(dict[str, Any], json.loads(plan_path.read_text()))
+ payload = {key: value for key, value in plan.items() if key != "plan_hash"}
+ if (
+ plan.get("version") != 1
+ or plan.get("entity_type", "ligand") != entity_type
+ or plan.get("plan_hash") != (_symmetric_edge_plan_hash(payload))
+ ):
+ raise ValueError(f"invalid symmetric-edge plan: {plan_path}")
+ selected_metrics = set(metrics or plan["metrics"])
+ unknown_metrics = selected_metrics.difference(plan["metrics"])
+ if unknown_metrics:
+ raise ValueError(
+ f"metrics are not in the symmetric-edge plan: {sorted(unknown_metrics)}"
+ )
+ for batch in plan["batches"]:
+ if selected_metrics.isdisjoint(batch["metrics"]):
+ continue
+ for signature in batch["sources"]:
+ source = Path(str(signature["path"]))
+ if not source.is_file() or _component_source_signature(source) != signature:
+ raise ValueError(
+ f"raw score source changed after symmetric-edge planning: {source}"
+ )
+ return plan
-def explode_ligand_clusters(
+def _symmetric_fragment_dir(
*,
data_dir: Path,
- labeldf: pd.DataFrame,
-) -> pd.DataFrame:
- ligands_per_system = pd.read_parquet(
- data_dir / "fingerprints/ligands_per_system.parquet"
+ batch_key: str,
+ entity_type: ClusterEntity = "ligand",
+) -> Path:
+ return (
+ _cluster_root(data_dir, entity_type)
+ / "symmetric_edges"
+ / "fragments"
+ / f"batch={batch_key}"
)
- annotation_df = pd.read_parquet(
- data_dir / "index" / "annotation_table.parquet",
- columns=[
- "system_id",
- "ligand_molecular_weight",
- "ligand_rdkit_canonical_smiles",
- ],
- filters=[
- ("system_id", "in", set(ligands_per_system["system_id"])),
- ("ligand_is_ion", "==", False),
- ("ligand_is_artifact", "==", False),
- ],
+
+
+def _completed_symmetric_fragment_batch(
+ *,
+ data_dir: Path,
+ plan: Mapping[str, Any],
+ batch: Mapping[str, Any],
+ output_prefix: str | None = None,
+ entity_type: ClusterEntity = "ligand",
+) -> dict[str, Any] | None:
+ output_dir = _symmetric_fragment_dir(
+ data_dir=data_dir,
+ batch_key=str(batch["key"]),
+ entity_type=entity_type,
)
- mapr = dict(
- zip(
- ligands_per_system["ligand_rdkit_canonical_smiles"],
- ligands_per_system["number_id_by_inchikeys"],
- )
- )
- annotation_df["number_id_by_inchikeys"] = annotation_df[
- "ligand_rdkit_canonical_smiles"
- ].map(mapr)
- annotation_df.dropna(subset=["number_id_by_inchikeys"], inplace=True)
- annotation_df["number_id_by_inchikeys"] = annotation_df[
- "number_id_by_inchikeys"
- ].astype(int)
- annotation_df = annotation_df.sort_values(
- by=["system_id", "ligand_molecular_weight"], ascending=[True, False]
- ).drop_duplicates(subset=["system_id"], keep="first")
- ligand_to_system: dict[int, set[str]] = {}
- for ligand_id, group in annotation_df.groupby("number_id_by_inchikeys"):
- ligand_to_system[int(ligand_id)] = set(group["system_id"])
- labeldf["system_id"] = labeldf["system_id"].astype(int).map(ligand_to_system)
- labeldf = labeldf.dropna(subset=["system_id"]).explode("system_id")
- return labeldf
-
-
-def make_cluster_file(
+ manifest_path = output_dir / "manifest.json"
+ if not manifest_path.is_file():
+ return None
+ try:
+ manifest = json.loads(manifest_path.read_text())
+ if manifest.get("version") != 1:
+ return None
+ if manifest.get("entity_type", "ligand") != entity_type:
+ return None
+ if manifest.get("plan_hash") != plan["plan_hash"]:
+ return None
+ if manifest.get("batch") != batch:
+ return None
+ outputs = manifest["outputs"]
+ if output_prefix is not None:
+ outputs = [
+ output
+ for output in outputs
+ if str(output["path"]).startswith(output_prefix)
+ ]
+ for output in outputs:
+ path = output_dir / str(output["path"])
+ if not path.is_file() or path.stat().st_size != int(output["size"]):
+ return None
+ return cast(dict[str, Any], manifest)
+ except (OSError, ValueError, KeyError, json.JSONDecodeError):
+ return None
+
+
+def symmetric_edge_fragment_batch_is_complete(
*,
- graph: nk.graph.Graph,
- system_ids_and_singletons: set[str],
- system_ids_cat: pd.CategoricalDtype,
data_dir: Path,
- metric: str,
- threshold: int,
- directed: bool,
- cluster: str,
- skip_existing_clusters: bool,
-) -> None:
- cluster_file = (
- data_dir
- / "clusters"
- / f"cluster={cluster}"
- / f"directed={directed}"
- / f"metric={metric}"
- / f"threshold={threshold}.parquet"
+ batch: Mapping[str, Any],
+ entity_type: ClusterEntity = "ligand",
+) -> bool:
+ """Return whether a planned fragment batch is complete and current."""
+ plan = load_symmetric_edge_plan(data_dir, entity_type=entity_type)
+ planned_batch = next(
+ (value for value in plan["batches"] if str(value["key"]) == str(batch["key"])),
+ None,
)
- LOG.info(f"make_cluster_file: {cluster_file}")
- if cluster_file.is_file() and skip_existing_clusters:
- LOG.info(f"skipping {cluster_file} because it exists")
- return
- func = make_nk_components if cluster == "components" else make_nk_communities
- labels = get_labels(
- graph,
- system_ids_and_singletons,
- system_ids_cat,
- func,
- directed,
- )
- if len(labels):
- labeldf = pd.DataFrame(labels)
- labeldf["metric"] = metric
- labeldf["directed"] = False
- labeldf["threshold"] = threshold
- labeldf["cluster"] = cluster
- if metric == "tanimoto_similarity_max":
- labeldf = explode_ligand_clusters(data_dir=data_dir, labeldf=labeldf)
- LOG.info(f"saving {cluster_file}")
- t0 = time()
- cluster_file.parent.mkdir(exist_ok=True, parents=True)
- labeldf.to_parquet(cluster_file, schema=CLUSTER_SCHEMA)
- t1 = time()
- LOG.info(f"make_cluster_file: saving took {t1-t0:.2f}s")
-
-
-def prepare_df_protein(
+ return (
+ planned_batch == batch
+ and _completed_symmetric_fragment_batch(
+ data_dir=data_dir,
+ plan=plan,
+ batch=batch,
+ entity_type=entity_type,
+ )
+ is not None
+ )
+
+
+def write_symmetric_edge_fragment_batch(
*,
data_dir: Path,
- metric: str,
- threshold: int,
-) -> pd.DataFrame:
- LOG.info(f"threshold={threshold} metric={metric} getting system_ids")
- t0 = time()
- system_ids_and_singletons = set(
- pd.read_parquet(
- data_dir / "index" / "annotation_table.parquet",
- columns=["system_id"],
- filters=[
- ("system_type", "==", "holo"),
- ("system_num_protein_chains", "<=", 5),
- ("system_num_ligand_chains", "<=", 5),
- ],
- )["system_id"]
- )
- t1 = time()
- LOG.info(f"getting {len(system_ids_and_singletons)} system_ids took {t1-t0:.2f}s")
- if not len(system_ids_and_singletons):
- LOG.info("no system_ids found, returning")
- return
- df = scores.query_protein_similarity(
- search_db="holo",
- columns=[
- "query_system",
- "target_system",
- "similarity",
- ],
- filters=[
- ("similarity", ">=", threshold),
- ("metric", "==", metric),
+ batch: Mapping[str, Any],
+ scratch_dir: Path,
+ threads: int = 1,
+ force_update: bool = False,
+ read_paths: Sequence[Path] | None = None,
+ entity_type: ClusterEntity = "ligand",
+) -> dict[str, Any]:
+ """Write one score batch into canonical-pair hash fragments."""
+ if threads < 1:
+ raise ValueError("symmetric-edge threads must be positive")
+ plan = load_symmetric_edge_plan(data_dir, entity_type=entity_type)
+ planned_batch = next(
+ (value for value in plan["batches"] if str(value["key"]) == str(batch["key"])),
+ None,
+ )
+ if planned_batch != batch:
+ raise ValueError(
+ f"batch is not part of the current symmetric-edge plan: {batch}"
+ )
+ if not force_update:
+ completed = _completed_symmetric_fragment_batch(
+ data_dir=data_dir,
+ plan=plan,
+ batch=batch,
+ entity_type=entity_type,
+ )
+ if completed is not None:
+ return completed
+
+ source_paths = [Path(str(value["path"])) for value in batch["sources"]]
+ scan_paths = list(read_paths or source_paths)
+ if len(scan_paths) != len(source_paths):
+ raise ValueError("symmetric-edge read paths do not match planned sources")
+ scratch_output = scratch_dir / f"symmetric-fragments-{batch['key']}"
+ rmtree(scratch_output, ignore_errors=True)
+ scratch_output.mkdir(exist_ok=True, parents=True)
+
+ import duckdb
+
+ connection = duckdb.connect()
+ _set_slurm_memory_limit(connection, 3)
+ connection.sql(f"SET threads={threads}")
+ temporary_root = scratch_dir / "duckdb"
+ temporary_root.mkdir(exist_ok=True, parents=True)
+ connection.sql(f"SET temp_directory='{temporary_root.as_posix()}'")
+ paths_sql = ", ".join(
+ f"'{path.as_posix().replace(chr(39), chr(39) * 2)}'" for path in scan_paths
+ )
+ metrics = [str(metric) for metric in batch["metrics"]]
+ if batch["kind"] == "chemical":
+ metric = metrics[0]
+ escaped_metric = metric.replace('"', '""')
+ selected_sql = dedent(
+ f"""
+ SELECT
+ '{metric.replace("'", "''")}'::VARCHAR AS metric,
+ cast(query_ligand_id AS VARCHAR) AS query_node,
+ cast(target_ligand_id AS VARCHAR) AS target_node,
+ cast("{escaped_metric}" AS DOUBLE) AS similarity
+ FROM read_parquet([{paths_sql}], union_by_name=true)
+ """
+ )
+ elif batch["kind"] == "interface":
+ metrics_sql = ", ".join(
+ f"'{metric.replace(chr(39), chr(39) * 2)}'" for metric in metrics
+ )
+ selected_sql = dedent(
+ f"""
+ SELECT
+ cast(metric AS VARCHAR) AS metric,
+ cast(query_system AS VARCHAR) AS query_node,
+ cast(target_system AS VARCHAR) AS target_node,
+ cast(similarity AS DOUBLE) AS similarity
+ FROM read_parquet([{paths_sql}], union_by_name=true)
+ WHERE cast(metric AS VARCHAR) IN ({metrics_sql})
+ """
+ )
+ elif batch["kind"] in {
+ "interface_export_interface_qcov",
+ "interface_export_interface_side_qcov",
+ }:
+ metric = metrics[0]
+ query, target = (
+ ("query_system", "target_system")
+ if metric == "interface_qcov"
+ else ("query_half_interface_id", "target_half_interface_id")
+ )
+ selected_sql = dedent(
+ f"""
+ SELECT
+ '{metric}'::VARCHAR AS metric,
+ cast({query} AS VARCHAR) AS query_node,
+ cast({target} AS VARCHAR) AS target_node,
+ cast(similarity AS DOUBLE) AS similarity
+ FROM read_parquet([{paths_sql}], union_by_name=true)
+ """
+ )
+ else:
+ nodes, eligible_systems = component_node_universe(
+ data_dir=data_dir,
+ metric=metrics[0],
+ entity_type=entity_type,
+ )
+ connection.register(
+ "eligible_systems",
+ pd.DataFrame({"system_id": sorted(eligible_systems or set())}),
+ )
+ connection.register(
+ "eligible_ligands",
+ pd.DataFrame({"ligand_id": sorted(nodes)}),
+ )
+ metrics_sql = ", ".join(
+ f"'{metric.replace(chr(39), chr(39) * 2)}'" for metric in metrics
+ )
+ source_sql = f"read_parquet([{paths_sql}], union_by_name=true)"
+ if "metric" not in pq.read_schema(scan_paths[0]).names:
+ expressions = {
+ metric: (
+ "floor(sucos_shape::DOUBLE * pocket_qcov / 100)"
+ if metric == "sucos_shape_pocket_qcov"
+ else f'"{metric.replace(chr(34), chr(34) * 2)}"'
+ )
+ for metric in metrics
+ }
+ projections = ", ".join(
+ f'{expression} AS "{metric}"'
+ for metric, expression in expressions.items()
+ )
+ source_sql = (
+ f"(UNPIVOT (SELECT query_system, query_ligand_id, "
+ f"target_system, target_ligand_id, {projections} "
+ f"FROM {source_sql}) ON "
+ + ", ".join(f'"{metric}"' for metric in metrics)
+ + " INTO NAME metric VALUE similarity)"
+ )
+ selected_sql = dedent(
+ f"""
+ SELECT
+ cast(scores.metric AS VARCHAR) AS metric,
+ cast(scores.query_ligand_id AS VARCHAR) AS query_node,
+ cast(scores.target_ligand_id AS VARCHAR) AS target_node,
+ cast(scores.similarity AS DOUBLE) AS similarity
+ FROM {source_sql} AS scores
+ INNER JOIN eligible_systems AS query_system
+ ON cast(scores.query_system AS VARCHAR) = query_system.system_id
+ INNER JOIN eligible_systems AS target_system
+ ON cast(scores.target_system AS VARCHAR) = target_system.system_id
+ INNER JOIN eligible_ligands AS query_ligand
+ ON cast(scores.query_ligand_id AS VARCHAR) = query_ligand.ligand_id
+ INNER JOIN eligible_ligands AS target_ligand
+ ON cast(scores.target_ligand_id AS VARCHAR) = target_ligand.ligand_id
+ WHERE cast(scores.metric AS VARCHAR) IN ({metrics_sql})
+ """
+ )
+ if batch["kind"] == "chemical":
+ aggregate_sql = """
+ max(similarity)::DOUBLE AS forward_similarity,
+ max(similarity)::DOUBLE AS reverse_similarity
+ """
+ else:
+ aggregate_sql = """
+ max(similarity) FILTER (WHERE query_node = low_node)::DOUBLE
+ AS forward_similarity,
+ max(similarity) FILTER (WHERE query_node = high_node)::DOUBLE
+ AS reverse_similarity
+ """
+ compact_interface_export = batch["kind"] in {
+ "interface_export_interface_qcov",
+ "interface_export_interface_side_qcov",
+ }
+ edge_rows_sql = (
+ dedent(
+ """
+ SELECT
+ metric,
+ bucket,
+ low_node,
+ high_node,
+ CASE WHEN query_node = low_node THEN similarity END
+ AS forward_similarity,
+ CASE WHEN query_node = high_node THEN similarity END
+ AS reverse_similarity
+ FROM bucketed
+ """
+ )
+ if compact_interface_export
+ else dedent(
+ f"""
+ SELECT
+ metric,
+ bucket,
+ low_node,
+ high_node,
+ {aggregate_sql}
+ FROM bucketed
+ GROUP BY metric, bucket, low_node, high_node
+ """
+ )
+ )
+ query = dedent(
+ f"""
+ COPY (
+ WITH selected AS (
+ {selected_sql}
+ ), canonical AS (
+ SELECT
+ metric,
+ query_node,
+ target_node,
+ least(query_node, target_node) AS low_node,
+ greatest(query_node, target_node) AS high_node,
+ similarity
+ FROM selected
+ WHERE query_node != target_node
+ AND similarity IS NOT NULL
+ ), bucketed AS (
+ SELECT
+ *,
+ (
+ hash(low_node, high_node)
+ % {int(plan["bucket_count"])}
+ )::INTEGER AS bucket
+ FROM canonical
+ )
+ {edge_rows_sql}
+ ) TO '{scratch_output.as_posix()}'
+ (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 500000,
+ PARTITION_BY (metric, bucket)
+ )
+ """
+ )
+ started = time()
+ LOG.info(
+ "symmetric fragment start: batch=%s kind=%s sources=%d metrics=%s",
+ batch["key"],
+ batch["kind"],
+ len(source_paths),
+ metrics,
+ )
+ connection.sql(query)
+ connection.close()
+ output_files = sorted(scratch_output.rglob("*.parquet"))
+ manifest: dict[str, Any] = {
+ "version": 1,
+ "entity_type": entity_type,
+ "status": "complete",
+ "plan_hash": plan["plan_hash"],
+ "batch": dict(batch),
+ "outputs": [
+ {
+ "path": path.relative_to(scratch_output).as_posix(),
+ "size": path.stat().st_size,
+ }
+ for path in output_files
],
+ "elapsed_seconds": time() - started,
+ }
+ output_dir = _symmetric_fragment_dir(
+ data_dir=data_dir,
+ batch_key=str(batch["key"]),
+ entity_type=entity_type,
+ )
+ temporary_output = output_dir.with_name(f"{output_dir.name}.tmp")
+ rmtree(temporary_output, ignore_errors=True)
+ copytree(scratch_output, temporary_output)
+ rmtree(output_dir, ignore_errors=True)
+ temporary_output.replace(output_dir)
+ temporary_manifest = output_dir / "manifest.tmp.json"
+ temporary_manifest.write_text(json.dumps(manifest, indent=2, sort_keys=True) + "\n")
+ temporary_manifest.replace(output_dir / "manifest.json")
+ LOG.info(
+ "symmetric fragment complete: batch=%s files=%d elapsed_seconds=%.1f",
+ batch["key"],
+ len(output_files),
+ time() - started,
)
- if df is None or df.empty:
- LOG.info("no protein similarity scores found, returning")
- return
- LOG.info(f"found {len(df.index)} similarity scores")
- return df, system_ids_and_singletons
+ return manifest
-def prepare_df_ligand(
+def _symmetric_edge_path(
*,
data_dir: Path,
metric: str,
- threshold: int,
-) -> pd.DataFrame:
- LOG.info(f"threshold={threshold} metric={metric} getting ligand_ids")
- t0 = time()
- system_ids_and_singletons = set(
- pd.read_parquet(data_dir / "fingerprints/ligands_per_system.parquet")[
- "number_id_by_inchikeys"
- ].astype(str)
- )
- t1 = time()
- LOG.info(f"getting {len(system_ids_and_singletons)} ligand_ids took {t1-t0:.2f}s")
- if not len(system_ids_and_singletons):
- LOG.info("no ligand_ids found, returning")
- return
- df = scores.query_ligand_similarity(
- columns=[
- "query_ligand_id",
- "target_ligand_id",
- "tanimoto_similarity_max",
- ],
- filters=[
- ("tanimoto_similarity_max", ">=", threshold),
- ],
- )
- if df is None or df.empty:
- LOG.info("no ligand similarity scores found, returning")
- return
- df[["query_ligand_id", "target_ligand_id"]] = df[
- ["query_ligand_id", "target_ligand_id"]
- ].astype(str)
- LOG.info(f"found {len(df.index)} similarity scores")
- df.rename(
- columns={
- "query_ligand_id": "query_system",
- "target_ligand_id": "target_system",
- "tanimoto_similarity_max": "similarity",
- },
- inplace=True,
+ bucket: int,
+ entity_type: ClusterEntity = "ligand",
+) -> Path:
+ return (
+ _cluster_root(data_dir, entity_type)
+ / "symmetric_edges"
+ / f"metric={metric}"
+ / f"bucket={bucket:03d}.parquet"
)
- return df, system_ids_and_singletons
-def make_components_and_communities(
+def write_symmetric_edge_shard(
*,
data_dir: Path,
metric: str,
- threshold: int,
- skip_existing_clusters: bool = False,
-) -> None:
- if metric == "tanimoto_similarity_max":
- df, system_ids_and_singletons = prepare_df_ligand(
+ bucket: int,
+ scratch_dir: Path,
+ threads: int = 1,
+ force_update: bool = False,
+ entity_type: ClusterEntity = "ligand",
+) -> dict[str, Any]:
+ """Merge directional maxima into one reciprocal-minimum edge shard."""
+ if threads < 1:
+ raise ValueError("symmetric-edge threads must be positive")
+ plan = load_symmetric_edge_plan(data_dir, entity_type=entity_type)
+ if metric not in plan["metrics"]:
+ raise ValueError(f"metric is not in the symmetric-edge plan: {metric}")
+ if bucket < 0 or bucket >= int(plan["bucket_count"]):
+ raise ValueError(f"symmetric-edge bucket is out of range: {bucket}")
+ fragments: list[Path] = []
+ for batch in plan["batches"]:
+ if metric not in batch["metrics"]:
+ continue
+ completed = _completed_symmetric_fragment_batch(
data_dir=data_dir,
- metric=metric,
- threshold=threshold,
+ plan=plan,
+ batch=batch,
+ output_prefix=f"metric={metric}/bucket={bucket}/",
+ entity_type=entity_type,
)
- else:
- df, system_ids_and_singletons = prepare_df_protein(
+ if completed is None:
+ raise ValueError(
+ f"symmetric-edge fragment batch is incomplete: {batch['key']}"
+ )
+ output_dir = _symmetric_fragment_dir(
data_dir=data_dir,
- metric=metric,
- threshold=threshold,
+ batch_key=str(batch["key"]),
+ entity_type=entity_type,
)
- system_ids_df = set(df["query_system"]).union(set(df["target_system"]))
- system_ids_cat = pd.CategoricalDtype(categories=list(system_ids_df))
- df[["query_system", "target_system"]] = df[
- ["query_system", "target_system"]
- ].astype(system_ids_cat)
- directed_graph, system_ids_directed_cat = make_nk_graph(
- df, len(system_ids_df), system_ids_cat, directed=True, weighted=False
- )
- make_cluster_file(
- graph=directed_graph,
- system_ids_cat=system_ids_directed_cat,
- directed=True,
- cluster="components",
- system_ids_and_singletons=system_ids_and_singletons,
+ fragments.extend(output_dir.glob(f"metric={metric}/bucket={bucket}/*.parquet"))
+ fragments = sorted(fragments)
+ output = _symmetric_edge_path(
data_dir=data_dir,
metric=metric,
- threshold=threshold,
- skip_existing_clusters=skip_existing_clusters,
- )
- del directed_graph
- del system_ids_directed_cat
- undirected_graph, system_ids_undirected_cat = make_nk_graph(
- df, len(system_ids_df), system_ids_cat, directed=False, weighted=True
- )
- for cluster in ["components", "communities"]:
- make_cluster_file(
- graph=undirected_graph,
- system_ids_cat=system_ids_undirected_cat,
- directed=False,
- cluster=cluster,
- system_ids_and_singletons=system_ids_and_singletons,
- data_dir=data_dir,
- metric=metric,
- threshold=threshold,
- skip_existing_clusters=skip_existing_clusters,
+ bucket=bucket,
+ entity_type=entity_type,
+ )
+ manifest_path = output.with_suffix(".json")
+ source_signatures = [_component_source_signature(path) for path in fragments]
+ if not force_update and output.is_file() and manifest_path.is_file():
+ try:
+ cached_manifest = json.loads(manifest_path.read_text())
+ if (
+ cached_manifest.get("version") == 1
+ and cached_manifest.get("plan_hash") == plan["plan_hash"]
+ and cached_manifest.get("fragments") == source_signatures
+ and output.stat().st_size == int(cached_manifest["size"])
+ ):
+ return cast(dict[str, Any], cached_manifest)
+ except (OSError, ValueError, KeyError, json.JSONDecodeError):
+ pass
+
+ import duckdb
+
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ local_output = scratch_dir / f"{metric}-{bucket:03d}.parquet"
+ local_output.unlink(missing_ok=True)
+ connection = duckdb.connect()
+ _set_slurm_memory_limit(connection, 3)
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ if fragments:
+ local_fragment_dir = scratch_dir / "fragments"
+ rmtree(local_fragment_dir, ignore_errors=True)
+ local_fragment_dir.mkdir(exist_ok=True, parents=True)
+ scan_fragments: list[Path] = []
+ for index, fragment in enumerate(fragments):
+ local_fragment = local_fragment_dir / f"{index:05d}.parquet"
+ copyfile(fragment, local_fragment)
+ scan_fragments.append(local_fragment)
+ paths_sql = ", ".join(
+ f"'{path.as_posix().replace(chr(39), chr(39) * 2)}'"
+ for path in scan_fragments
+ )
+ selected_sql = dedent(
+ f"""
+ WITH combined AS (
+ SELECT
+ cast(low_node AS VARCHAR) AS query_node,
+ cast(high_node AS VARCHAR) AS target_node,
+ max(forward_similarity)::DOUBLE AS forward_similarity,
+ max(reverse_similarity)::DOUBLE AS reverse_similarity
+ FROM read_parquet([{paths_sql}], union_by_name=true)
+ GROUP BY query_node, target_node
+ )
+ SELECT
+ query_node,
+ target_node,
+ forward_similarity,
+ reverse_similarity,
+ CASE
+ WHEN forward_similarity IS NOT NULL
+ AND reverse_similarity IS NOT NULL
+ THEN least(forward_similarity, reverse_similarity)
+ END::DOUBLE AS similarity,
+ CASE
+ WHEN forward_similarity IS NULL THEN reverse_similarity
+ WHEN reverse_similarity IS NULL THEN forward_similarity
+ ELSE greatest(forward_similarity, reverse_similarity)
+ END::DOUBLE AS maximum_similarity
+ FROM combined
+ WHERE forward_similarity IS NOT NULL
+ OR reverse_similarity IS NOT NULL
+ """
+ )
+ else:
+ selected_sql = """
+ SELECT
+ NULL::VARCHAR AS query_node,
+ NULL::VARCHAR AS target_node,
+ NULL::DOUBLE AS forward_similarity,
+ NULL::DOUBLE AS reverse_similarity,
+ NULL::DOUBLE AS similarity,
+ NULL::DOUBLE AS maximum_similarity
+ WHERE false
+ """
+ started = time()
+ connection.sql(
+ dedent(
+ f"""
+ COPY ({selected_sql})
+ TO '{local_output.as_posix()}'
+ (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ )
+ row_count = int(
+ cast(
+ tuple[int],
+ connection.sql(
+ f"SELECT count(*) FROM read_parquet('{local_output.as_posix()}')"
+ ).fetchone(),
+ )[0]
+ )
+ connection.close()
+ output.parent.mkdir(exist_ok=True, parents=True)
+ temporary_output = output.with_suffix(".tmp.parquet")
+ copyfile(local_output, temporary_output)
+ temporary_output.replace(output)
+ manifest: dict[str, Any] = {
+ "version": 1,
+ "status": "complete",
+ "plan_hash": plan["plan_hash"],
+ "metric": metric,
+ "bucket": bucket,
+ "fragments": source_signatures,
+ "rows": row_count,
+ "size": output.stat().st_size,
+ "elapsed_seconds": time() - started,
+ }
+ temporary_manifest = manifest_path.with_suffix(".tmp.json")
+ temporary_manifest.write_text(json.dumps(manifest, indent=2, sort_keys=True) + "\n")
+ temporary_manifest.replace(manifest_path)
+ LOG.info(
+ "symmetric edge shard complete: metric=%s bucket=%d rows=%d "
+ "fragments=%d elapsed_seconds=%.1f",
+ metric,
+ bucket,
+ row_count,
+ len(fragments),
+ time() - started,
+ )
+ return manifest
+
+
+def _completed_component_reduction(
+ *,
+ output_dir: Path,
+ source_signature: Mapping[str, str | int],
+ node_hash: str,
+ selection_hash: str,
+ thresholds: Sequence[int],
+) -> dict[str, Any] | None:
+ manifest_path = output_dir / "reduction.json"
+ if not manifest_path.is_file():
+ return None
+ try:
+ manifest = json.loads(manifest_path.read_text())
+ if manifest.get("version") != COMPONENT_REDUCTION_VERSION:
+ return None
+ if manifest.get("directed_modes") != list(COMPONENT_REDUCTION_DIRECTIONS):
+ return None
+ if manifest.get("source") != source_signature:
+ return None
+ if manifest.get("node_hash") != node_hash:
+ return None
+ if manifest.get("selection_hash") != selection_hash:
+ return None
+ if manifest.get("thresholds") != list(thresholds):
+ return None
+ outputs = manifest["outputs"]
+ for output in outputs:
+ path = output_dir / str(output["path"])
+ if not path.is_file() or path.stat().st_size != int(output["size"]):
+ return None
+ schema = pq.read_schema(path)
+ if not set(COMPONENT_EDGE_COLUMNS).issubset(schema.names):
+ return None
+ return cast(dict[str, Any], manifest)
+ except (OSError, ValueError, KeyError, json.JSONDecodeError):
+ return None
+
+
+def write_component_reduction_shard(
+ *,
+ edge_batches: Iterable[pd.DataFrame],
+ all_nodes: Iterable[str],
+ thresholds: Sequence[int],
+ source_path: Path,
+ output_dir: Path,
+ query_column: str = "query_node",
+ target_column: str = "target_node",
+ similarity_column: str = "similarity",
+ forest_fan_in: int = 8,
+ force_update: bool = False,
+ selection_hash: str | None = None,
+) -> dict[str, Any]:
+ """Persist resumable directed-component reductions for one score shard."""
+ ordered_thresholds = sorted(set(thresholds), reverse=True)
+ nodes = sorted(set(map(str, all_nodes)))
+ source_signature = _component_source_signature(source_path)
+ node_hash = _component_node_hash(nodes)
+ effective_selection_hash = selection_hash or node_hash
+ if not force_update:
+ completed = _completed_component_reduction(
+ output_dir=output_dir,
+ source_signature=source_signature,
+ node_hash=node_hash,
+ selection_hash=effective_selection_hash,
+ thresholds=ordered_thresholds,
+ )
+ if completed is not None:
+ return completed
+
+ _, reductions = reduce_threshold_component_edges(
+ edge_batches=edge_batches,
+ all_nodes=nodes,
+ thresholds=ordered_thresholds,
+ query_column=query_column,
+ target_column=target_column,
+ similarity_column=similarity_column,
+ forest_fan_in=forest_fan_in,
+ directed_modes=COMPONENT_REDUCTION_DIRECTIONS,
+ )
+ outputs: list[dict[str, str | int | bool]] = []
+ for directed in COMPONENT_REDUCTION_DIRECTIONS:
+ for threshold in ordered_thresholds:
+ relative = (
+ Path(f"directed={str(directed).lower()}")
+ / f"threshold={threshold}.parquet"
+ )
+ output = output_dir / relative
+ output.parent.mkdir(exist_ok=True, parents=True)
+ temporary = output.with_suffix(".tmp.parquet")
+ reductions[directed][threshold].to_parquet(
+ temporary,
+ index=False,
+ compression="zstd",
+ )
+ temporary.replace(output)
+ outputs.append(
+ {
+ "directed": directed,
+ "threshold": threshold,
+ "path": relative.as_posix(),
+ "rows": len(reductions[directed][threshold]),
+ "size": output.stat().st_size,
+ }
+ )
+ manifest: dict[str, Any] = {
+ "version": COMPONENT_REDUCTION_VERSION,
+ "status": "complete",
+ "directed_modes": list(COMPONENT_REDUCTION_DIRECTIONS),
+ "source": source_signature,
+ "node_hash": node_hash,
+ "selection_hash": effective_selection_hash,
+ "node_count": len(nodes),
+ "thresholds": ordered_thresholds,
+ "outputs": outputs,
+ }
+ output_dir.mkdir(exist_ok=True, parents=True)
+ manifest_path = output_dir / "reduction.json"
+ temporary_manifest = manifest_path.with_suffix(".tmp.json")
+ temporary_manifest.write_text(json.dumps(manifest, indent=2, sort_keys=True) + "\n")
+ temporary_manifest.replace(manifest_path)
+ return manifest
+
+
+def merge_component_reduction_shards(
+ *,
+ reduction_dirs: Sequence[Path],
+ all_nodes: Iterable[str],
+ thresholds: Sequence[int],
+ forest_fan_in: int = 8,
+ parquet_batch_size: int = 250_000,
+ selection_hash: str | None = None,
+) -> dict[bool, dict[int, pd.DataFrame]]:
+ """Merge completed shard reductions into exact directed-component labels."""
+ if parquet_batch_size < 1:
+ raise ValueError("component Parquet batch size must be positive")
+ ordered_thresholds = sorted(set(thresholds), reverse=True)
+ nodes = sorted(set(map(str, all_nodes)))
+ node_hash = _component_node_hash(nodes)
+ effective_selection_hash = selection_hash or node_hash
+ reduction_count = len(reduction_dirs)
+ started = time()
+ LOG.info(
+ "component merge: loading %d source reductions for %d nodes at thresholds=%s",
+ reduction_count,
+ len(nodes),
+ ordered_thresholds,
+ )
+ accumulators = {
+ directed: {
+ threshold: _ComponentEdgeAccumulator(
+ forest_fan_in,
+ (
+ _reduce_directed_component_edges
+ if directed
+ else _reduce_undirected_component_edges
+ ),
+ )
+ for threshold in ordered_thresholds
+ }
+ for directed in COMPONENT_REDUCTION_DIRECTIONS
+ }
+ for index, reduction_dir in enumerate(reduction_dirs, start=1):
+ manifest_path = reduction_dir / "reduction.json"
+ if not manifest_path.is_file():
+ raise FileNotFoundError(manifest_path)
+ manifest = json.loads(manifest_path.read_text())
+ source = cast(dict[str, str | int], manifest["source"])
+ source_path = Path(str(source["path"]))
+ completed = _completed_component_reduction(
+ output_dir=reduction_dir,
+ source_signature=_component_source_signature(source_path),
+ node_hash=node_hash,
+ selection_hash=effective_selection_hash,
+ thresholds=ordered_thresholds,
+ )
+ if completed is None:
+ raise ValueError(
+ f"stale or incomplete component reduction: {reduction_dir}"
+ )
+ output_by_key = {
+ (bool(output["directed"]), int(output["threshold"])): output
+ for output in completed["outputs"]
+ }
+ for directed in COMPONENT_REDUCTION_DIRECTIONS:
+ for threshold in ordered_thresholds:
+ output = output_by_key[(directed, threshold)]
+ path = reduction_dir / str(output["path"])
+ parquet = pq.ParquetFile(path)
+ for batch in parquet.iter_batches(
+ batch_size=parquet_batch_size,
+ columns=COMPONENT_EDGE_COLUMNS,
+ ):
+ accumulators[directed][threshold].add(batch.to_pandas())
+ if index % 25 == 0 or index == reduction_count:
+ elapsed = time() - started
+ rate = index / elapsed
+ LOG.info(
+ "component merge source progress: loaded=%d/%d rate=%.1f/s "
+ "eta_seconds=%.1f",
+ index,
+ reduction_count,
+ rate,
+ (reduction_count - index) / rate,
+ )
+
+ result: dict[bool, dict[int, pd.DataFrame]] = {}
+ for directed in COMPONENT_REDUCTION_DIRECTIONS:
+ reductions: dict[int, pd.DataFrame] = {}
+ for threshold in ordered_thresholds:
+ phase_started = time()
+ LOG.info(
+ "component merge: reducing directed=%s threshold=%d",
+ directed,
+ threshold,
+ )
+ reductions[threshold] = accumulators[directed][threshold].finish()
+ LOG.info(
+ "component merge: reduced directed=%s threshold=%d edges=%d "
+ "elapsed_seconds=%.1f",
+ directed,
+ threshold,
+ len(reductions[threshold]),
+ time() - phase_started,
+ )
+ phase_started = time()
+ result[directed] = _labels_from_threshold_reductions(
+ nodes=nodes,
+ reductions=reductions,
+ directed=directed,
+ )
+ LOG.info(
+ "component merge: labeled directed=%s thresholds=%d elapsed_seconds=%.1f",
+ directed,
+ len(ordered_thresholds),
+ time() - phase_started,
+ )
+ LOG.info("component merge complete: elapsed_seconds=%.1f", time() - started)
+ return result
+
+
+def component_score_sources(
+ *,
+ data_dir: Path,
+ metric: str,
+ entity_type: ClusterEntity = "ligand",
+) -> list[Path]:
+ """Return compact reciprocal-minimum shards for one clustering metric."""
+ plan = load_symmetric_edge_plan(
+ data_dir,
+ entity_type=entity_type,
+ metrics=[metric],
+ )
+ if metric not in plan["metrics"]:
+ raise ValueError(f"metric is not in the symmetric-edge plan: {metric}")
+ sources = [
+ _symmetric_edge_path(
+ data_dir=data_dir,
+ metric=metric,
+ bucket=bucket,
+ entity_type=entity_type,
+ )
+ for bucket in range(int(plan["bucket_count"]))
+ ]
+ incomplete: list[Path] = []
+ required_columns = {
+ "query_node",
+ "target_node",
+ "forward_similarity",
+ "reverse_similarity",
+ "similarity",
+ "maximum_similarity",
+ }
+ for bucket, path in enumerate(sources):
+ manifest_path = path.with_suffix(".json")
+ try:
+ manifest = json.loads(manifest_path.read_text())
+ valid = (
+ path.is_file()
+ and manifest.get("version") == 1
+ and manifest.get("status") == "complete"
+ and manifest.get("plan_hash") == plan["plan_hash"]
+ and manifest.get("metric") == metric
+ and int(manifest.get("bucket", -1)) == bucket
+ and int(manifest.get("size", -1)) == path.stat().st_size
+ and required_columns.issubset(pq.read_schema(path).names)
+ )
+ except (OSError, TypeError, ValueError, KeyError, json.JSONDecodeError):
+ valid = False
+ if not valid:
+ incomplete.append(path)
+ if incomplete:
+ raise FileNotFoundError(
+ f"symmetric-edge shards are incomplete for {metric}: "
+ f"{[path.name for path in incomplete[:10]]}"
+ )
+ return sources
+
+
+def iter_component_score_batches(
+ *,
+ source_path: Path,
+ metric: str,
+ batch_size: int = 250_000,
+ eligible_systems: set[str] | None = None,
+) -> Iterable[pd.DataFrame]:
+ """Read one compact reciprocal-minimum ligand-edge shard in bounded batches."""
+ if batch_size < 1:
+ raise ValueError("component score batch size must be positive")
+ parquet = pq.ParquetFile(source_path)
+ columns = SYMMETRIC_EDGE_COLUMNS
+ missing = sorted(set(columns).difference(parquet.schema.names))
+ if missing:
+ raise ValueError(f"component score shard {source_path} is missing {missing}")
+ for batch in parquet.iter_batches(
+ batch_size=batch_size,
+ columns=columns,
+ ):
+ frame = batch.to_pandas()
+ if not frame.empty:
+ yield frame[SYMMETRIC_EDGE_COLUMNS]
+
+
+def _cached_component_node_universe(
+ data_dir: Path,
+ *,
+ entity_type: ClusterEntity = "ligand",
+) -> tuple[list[str], set[str] | None] | None:
+ cache_path, manifest_path = _component_node_universe_paths(data_dir, entity_type)
+ if not cache_path.is_file() or not manifest_path.is_file():
+ return None
+ try:
+ manifest = json.loads(manifest_path.read_text())
+ if manifest.get("version") != 1 or not manifest.get("universe_hash"):
+ return None
+ if manifest.get("entity_type", "ligand") != entity_type:
+ return None
+ if manifest.get("sources") != _component_node_universe_sources(
+ data_dir, entity_type
+ ):
+ return None
+ if cache_path.stat().st_size != int(manifest["cache_size"]):
+ return None
+ if set(pq.read_schema(cache_path).names) != {"kind", "id"}:
+ return None
+ frame = pd.read_parquet(cache_path, columns=["kind", "id"])
+ if entity_type == "ligand":
+ nodes = frame.loc[frame["kind"].eq("ligand"), "id"].astype(str).tolist()
+ ligand_systems = set(
+ frame.loc[frame["kind"].eq("system"), "id"].astype(str).tolist()
+ )
+ if len(nodes) != int(manifest["ligand_count"]):
+ return None
+ if len(ligand_systems) != int(manifest["system_count"]):
+ return None
+ systems: set[str] | None = ligand_systems
+ else:
+ nodes = frame.loc[frame["kind"].eq("interface"), "id"].astype(str).tolist()
+ side_nodes = (
+ frame.loc[frame["kind"].eq("interface_side"), "id"].astype(str).tolist()
+ )
+ systems = None
+ if len(nodes) != int(manifest["interface_count"]):
+ return None
+ if len(side_nodes) != int(manifest["interface_side_count"]):
+ return None
+ nodes.extend(side_nodes)
+ return nodes, systems
+ except (OSError, ValueError, KeyError, json.JSONDecodeError):
+ return None
+
+
+def prepare_component_node_universe(
+ data_dir: Path, *, entity_type: ClusterEntity = "ligand"
+) -> dict[str, Any]:
+ """Materialize the shared clustering-node universe before scattering."""
+ cached = _cached_component_node_universe(data_dir, entity_type=entity_type)
+ if cached is not None:
+ nodes, systems = cached
+ if entity_type == "interface":
+ interface_side_count = sum("::side=" in node for node in nodes)
+ return {
+ "status": "cached",
+ "interface_count": len(nodes) - interface_side_count,
+ "interface_side_count": interface_side_count,
+ }
+ return {
+ "status": "cached",
+ "ligand_count": len(nodes),
+ "system_count": len(systems or set()),
+ }
+
+ if entity_type == "interface":
+ representative_path = data_dir / INTERFACE_REPRESENTATIVES
+ half_representative_path = data_dir / INTERFACE_HALF_REPRESENTATIVES
+ nodes = sorted(
+ set(
+ pd.read_parquet(
+ representative_path,
+ columns=["representative_system_id"],
+ )["representative_system_id"]
+ .dropna()
+ .astype(str)
+ )
+ )
+ side_nodes = sorted(
+ set(
+ pd.read_parquet(
+ half_representative_path,
+ columns=["half_interface_id"],
+ )["half_interface_id"]
+ .dropna()
+ .astype(str)
+ )
+ )
+ system_ids: list[str] = []
+ frame = pd.concat(
+ [
+ pd.DataFrame({"kind": "interface", "id": nodes}),
+ pd.DataFrame({"kind": "interface_side", "id": side_nodes}),
+ ],
+ ignore_index=True,
+ )
+ counts = {
+ "interface_count": len(nodes),
+ "interface_side_count": len(side_nodes),
+ }
+ else:
+ annotation = _eligible_annotation(data_dir)
+ nodes = sorted(
+ set(
+ annotation.loc[annotation["ligand_is_proper"], "ligand_id"]
+ .dropna()
+ .astype(str)
+ )
+ )
+ system_ids = sorted(set(annotation["system_id"].dropna().astype(str)))
+ frame = pd.concat(
+ [
+ pd.DataFrame({"kind": "ligand", "id": nodes}),
+ pd.DataFrame({"kind": "system", "id": system_ids}),
+ ],
+ ignore_index=True,
+ )
+ counts = {
+ "ligand_count": len(nodes),
+ "system_count": len(system_ids),
+ }
+ cache_path, manifest_path = _component_node_universe_paths(data_dir, entity_type)
+ cache_path.parent.mkdir(exist_ok=True, parents=True)
+ temporary_cache = cache_path.with_suffix(".tmp.parquet")
+ frame.to_parquet(temporary_cache, index=False, compression="zstd")
+ temporary_cache.replace(cache_path)
+ universe_digest = hashlib.sha256()
+ for kind, node_id in frame[["kind", "id"]].itertuples(index=False, name=None):
+ universe_digest.update(str(kind).encode())
+ universe_digest.update(b"\0")
+ universe_digest.update(str(node_id).encode())
+ universe_digest.update(b"\n")
+ manifest = {
+ "version": 1,
+ "entity_type": entity_type,
+ "sources": _component_node_universe_sources(data_dir, entity_type),
+ "cache_size": cache_path.stat().st_size,
+ "universe_hash": universe_digest.hexdigest(),
+ **counts,
+ }
+ temporary_manifest = manifest_path.with_suffix(".tmp.json")
+ temporary_manifest.write_text(json.dumps(manifest, indent=2, sort_keys=True) + "\n")
+ temporary_manifest.replace(manifest_path)
+ return {"status": "complete", **manifest}
+
+
+def component_node_universe(
+ *,
+ data_dir: Path,
+ metric: str,
+ entity_type: ClusterEntity = "ligand",
+) -> tuple[list[str], set[str] | None]:
+ if entity_type == "interface":
+ if metric not in INTERFACE_CLUSTER_METRICS:
+ raise ValueError(f"unsupported interface clustering metric: {metric}")
+ cached = _cached_component_node_universe(data_dir, entity_type=entity_type)
+ if cached is not None:
+ cached_nodes, systems = cached
+ is_side = metric == "interface_side_qcov"
+ side_nodes = [node for node in cached_nodes if "::side=" in node]
+ return (
+ side_nodes
+ if is_side
+ else [node for node in cached_nodes if "::side=" not in node],
+ systems,
+ )
+ if metric == "interface_side_qcov":
+ source = data_dir / INTERFACE_HALF_REPRESENTATIVES
+ column = "half_interface_id"
+ else:
+ source = data_dir / INTERFACE_REPRESENTATIVES
+ column = "representative_system_id"
+ nodes = sorted(
+ set(pd.read_parquet(source, columns=[column])[column].dropna().astype(str))
+ )
+ return nodes, None
+ if is_chemical_cluster_metric(metric):
+ # Chemical metrics share the ECFP4 file's ligand_smiles_id node universe.
+ nodes = (
+ pd.read_parquet(
+ data_dir / "fingerprints" / "ligands_per_smiles.parquet",
+ columns=["ligand_smiles_id"],
+ )["ligand_smiles_id"]
+ .astype(str)
+ .tolist()
+ )
+ return sorted(set(nodes)), None
+ cached = _cached_component_node_universe(data_dir, entity_type=entity_type)
+ if cached is not None:
+ return cached
+ annotation = _eligible_annotation(data_dir)
+ systems = set(annotation["system_id"].dropna().astype(str))
+ node_set = set(
+ annotation.loc[annotation["ligand_is_proper"], "ligand_id"].dropna().astype(str)
+ )
+ return sorted(node_set), systems
+
+
+def component_reduction_dir(
+ *,
+ data_dir: Path,
+ metric: str,
+ source_path: Path,
+ entity_type: ClusterEntity = "ligand",
+) -> Path:
+ """Return a stable local reduction path without embedding an absolute root."""
+ try:
+ source_name = source_path.resolve().relative_to(data_dir.resolve()).as_posix()
+ except ValueError:
+ source_name = source_path.name
+ source_key = hashlib.sha256(source_name.encode()).hexdigest()[:16]
+ return (
+ _cluster_root(data_dir, entity_type)
+ / "reductions"
+ / f"metric={metric}"
+ / f"source={source_key}"
+ )
+
+
+def directed_cover_reduction_dir(
+ *,
+ data_dir: Path,
+ metric: str,
+ source_path: Path,
+ entity_type: ClusterEntity = "ligand",
+) -> Path:
+ """Return the reduction path for any-direction cover connectivity."""
+ try:
+ source_name = source_path.resolve().relative_to(data_dir.resolve()).as_posix()
+ except ValueError:
+ source_name = source_path.name
+ source_key = hashlib.sha256(source_name.encode()).hexdigest()[:16]
+ return (
+ _sampling_root(data_dir, entity_type)
+ / "directed_set_cover"
+ / "reductions"
+ / f"metric={metric}"
+ / f"source={source_key}"
+ )
+
+
+def _directed_cover_connectivity_thresholds(
+ thresholds: Sequence[int],
+) -> list[int]:
+ """Include the threshold-50 graph needed by stricter cover passes."""
+ result = set(thresholds)
+ if any(threshold > 50 for threshold in result):
+ result.add(50)
+ return sorted(result, reverse=True)
+
+
+def _iter_directed_cover_edge_batches(
+ *, source_path: Path, batch_size: int = 250_000
+) -> Iterable[pd.DataFrame]:
+ """Read maximum-direction edges for directed-cover weak connectivity."""
+ parquet = pq.ParquetFile(source_path)
+ columns = ["query_node", "target_node", "maximum_similarity"]
+ missing = sorted(set(columns).difference(parquet.schema.names))
+ if missing:
+ raise ValueError(
+ f"directed-cover score shard {source_path} is missing {missing}"
+ )
+ for batch in parquet.iter_batches(batch_size=batch_size, columns=columns):
+ frame = batch.to_pandas().rename(columns={"maximum_similarity": "similarity"})
+ if not frame.empty:
+ yield frame[SYMMETRIC_EDGE_COLUMNS]
+
+
+def make_directed_cover_component_reduction(
+ *,
+ data_dir: Path,
+ metric: str,
+ thresholds: Sequence[int],
+ source_path: Path,
+ batch_size: int = 250_000,
+ forest_fan_in: int = 8,
+ force_update: bool = False,
+ read_path: Path | None = None,
+ all_nodes: Sequence[str] | None = None,
+ eligible_systems: set[str] | None = None,
+ entity_type: ClusterEntity = "ligand",
+) -> dict[str, Any]:
+ """Reduce one shard by edges present in either score direction."""
+ if all_nodes is None:
+ nodes, eligible_systems = component_node_universe(
+ data_dir=data_dir,
+ metric=metric,
+ entity_type=entity_type,
+ )
+ else:
+ nodes = sorted(set(map(str, all_nodes)))
+ selection_hash = _component_selection_hash(
+ nodes=nodes,
+ eligible_systems=eligible_systems,
+ )
+ return write_component_reduction_shard(
+ edge_batches=_iter_directed_cover_edge_batches(
+ source_path=read_path or source_path,
+ batch_size=batch_size,
+ ),
+ all_nodes=nodes,
+ thresholds=_directed_cover_connectivity_thresholds(thresholds),
+ source_path=source_path,
+ output_dir=directed_cover_reduction_dir(
+ data_dir=data_dir,
+ metric=metric,
+ source_path=source_path,
+ entity_type=entity_type,
+ ),
+ forest_fan_in=forest_fan_in,
+ force_update=force_update,
+ selection_hash=selection_hash,
+ )
+
+
+def merge_directed_cover_component_reductions(
+ *,
+ data_dir: Path,
+ metric: str,
+ thresholds: Sequence[int],
+ forest_fan_in: int = 8,
+ parquet_batch_size: int = 250_000,
+ entity_type: ClusterEntity = "ligand",
+) -> dict[int, pd.DataFrame]:
+ """Merge exact weak components used to bound directed set cover."""
+ thresholds = _directed_cover_connectivity_thresholds(thresholds)
+ sources = component_score_sources(
+ data_dir=data_dir,
+ metric=metric,
+ entity_type=entity_type,
+ )
+ nodes, eligible_systems = component_node_universe(
+ data_dir=data_dir,
+ metric=metric,
+ entity_type=entity_type,
+ )
+ selection_hash = _component_selection_hash(
+ nodes=nodes,
+ eligible_systems=eligible_systems,
+ )
+ labels = merge_component_reduction_shards(
+ reduction_dirs=[
+ directed_cover_reduction_dir(
+ data_dir=data_dir,
+ metric=metric,
+ source_path=source,
+ entity_type=entity_type,
+ )
+ for source in sources
+ ],
+ all_nodes=nodes,
+ thresholds=thresholds,
+ forest_fan_in=forest_fan_in,
+ parquet_batch_size=parquet_batch_size,
+ selection_hash=selection_hash,
+ )[False]
+ for threshold, label_frame in labels.items():
+ output = (
+ _sampling_root(data_dir, entity_type)
+ / "directed_set_cover"
+ / "reductions"
+ / f"metric={metric}"
+ / "labels"
+ / f"threshold={threshold}.parquet"
+ )
+ output.parent.mkdir(exist_ok=True, parents=True)
+ temporary = output.with_suffix(".tmp.parquet")
+ label_frame.rename(
+ columns={"ligand_id": _cluster_node_column(entity_type)}
+ ).to_parquet(temporary, index=False, compression="zstd")
+ temporary.replace(output)
+ return labels
+
+
+def score_component_reduction_is_complete(
+ *,
+ data_dir: Path,
+ metric: str,
+ thresholds: Sequence[int],
+ source_path: Path,
+ all_nodes: Sequence[str] | None = None,
+ eligible_systems: set[str] | None = None,
+ entity_type: ClusterEntity = "ligand",
+) -> bool:
+ """Return whether one source/metric reduction matches all current inputs."""
+ if all_nodes is None:
+ nodes, eligible_systems = component_node_universe(
+ data_dir=data_dir,
+ metric=metric,
+ entity_type=entity_type,
+ )
+ else:
+ nodes = sorted(set(map(str, all_nodes)))
+ node_hash = _component_node_hash(nodes)
+ selection_hash = _component_selection_hash(
+ nodes=nodes,
+ eligible_systems=eligible_systems,
+ )
+ return (
+ _completed_component_reduction(
+ output_dir=component_reduction_dir(
+ data_dir=data_dir,
+ metric=metric,
+ source_path=source_path,
+ entity_type=entity_type,
+ ),
+ source_signature=_component_source_signature(source_path),
+ node_hash=node_hash,
+ selection_hash=selection_hash,
+ thresholds=sorted(set(thresholds), reverse=True),
+ )
+ is not None
+ )
+
+
+def directed_cover_component_reduction_is_complete(
+ *,
+ data_dir: Path,
+ metric: str,
+ thresholds: Sequence[int],
+ source_path: Path,
+ all_nodes: Sequence[str] | None = None,
+ eligible_systems: set[str] | None = None,
+ entity_type: ClusterEntity = "ligand",
+) -> bool:
+ """Return whether one any-direction connectivity reduction is current."""
+ if all_nodes is None:
+ nodes, eligible_systems = component_node_universe(
+ data_dir=data_dir,
+ metric=metric,
+ entity_type=entity_type,
+ )
+ else:
+ nodes = sorted(set(map(str, all_nodes)))
+ node_hash = _component_node_hash(nodes)
+ selection_hash = _component_selection_hash(
+ nodes=nodes,
+ eligible_systems=eligible_systems,
+ )
+ return (
+ _completed_component_reduction(
+ output_dir=directed_cover_reduction_dir(
+ data_dir=data_dir,
+ metric=metric,
+ source_path=source_path,
+ entity_type=entity_type,
+ ),
+ source_signature=_component_source_signature(source_path),
+ node_hash=node_hash,
+ selection_hash=selection_hash,
+ thresholds=_directed_cover_connectivity_thresholds(thresholds),
+ )
+ is not None
+ )
+
+
+def make_score_component_reduction(
+ *,
+ data_dir: Path,
+ metric: str,
+ thresholds: Sequence[int],
+ source_path: Path,
+ batch_size: int = 250_000,
+ forest_fan_in: int = 8,
+ force_update: bool = False,
+ read_path: Path | None = None,
+ all_nodes: Sequence[str] | None = None,
+ eligible_systems: set[str] | None = None,
+ entity_type: ClusterEntity = "ligand",
+) -> dict[str, Any]:
+ """Map one final score shard into resumable component reductions."""
+ if all_nodes is None:
+ nodes, eligible_systems = component_node_universe(
+ data_dir=data_dir,
+ metric=metric,
+ entity_type=entity_type,
+ )
+ else:
+ nodes = sorted(set(map(str, all_nodes)))
+ selection_hash = _component_selection_hash(
+ nodes=nodes,
+ eligible_systems=eligible_systems,
+ )
+ return write_component_reduction_shard(
+ edge_batches=iter_component_score_batches(
+ source_path=read_path or source_path,
+ metric=metric,
+ batch_size=batch_size,
+ eligible_systems=eligible_systems,
+ ),
+ all_nodes=nodes,
+ thresholds=thresholds,
+ source_path=source_path,
+ output_dir=component_reduction_dir(
+ data_dir=data_dir,
+ metric=metric,
+ source_path=source_path,
+ entity_type=entity_type,
+ ),
+ forest_fan_in=forest_fan_in,
+ force_update=force_update,
+ selection_hash=selection_hash,
+ )
+
+
+def merge_score_component_reductions(
+ *,
+ data_dir: Path,
+ metric: str,
+ thresholds: Sequence[int],
+ forest_fan_in: int = 8,
+ parquet_batch_size: int = 250_000,
+ entity_type: ClusterEntity = "ligand",
+) -> dict[bool, dict[int, pd.DataFrame]]:
+ """Reduce reciprocal-minimum shards into internal connectivity labels."""
+ started = time()
+ sources = component_score_sources(
+ data_dir=data_dir,
+ metric=metric,
+ entity_type=entity_type,
+ )
+ if not sources:
+ raise FileNotFoundError(f"no component score sources found for {metric}")
+ nodes, eligible_systems = component_node_universe(
+ data_dir=data_dir,
+ metric=metric,
+ entity_type=entity_type,
+ )
+ selection_hash = _component_selection_hash(
+ nodes=nodes,
+ eligible_systems=eligible_systems,
+ )
+ LOG.info(
+ "component merge metric=%s: sources=%d nodes=%d thresholds=%s",
+ metric,
+ len(sources),
+ len(nodes),
+ sorted(set(thresholds), reverse=True),
+ )
+ labels = merge_component_reduction_shards(
+ reduction_dirs=[
+ component_reduction_dir(
+ data_dir=data_dir,
+ metric=metric,
+ source_path=source,
+ entity_type=entity_type,
+ )
+ for source in sources
+ ],
+ all_nodes=nodes,
+ thresholds=thresholds,
+ forest_fan_in=forest_fan_in,
+ parquet_batch_size=parquet_batch_size,
+ selection_hash=selection_hash,
+ )
+ for directed in COMPONENT_REDUCTION_DIRECTIONS:
+ for threshold, label_frame in labels[directed].items():
+ node_column = _cluster_node_column(entity_type)
+ internal_frame = label_frame.rename(columns={"ligand_id": node_column})
+ internal = (
+ _cluster_root(data_dir, entity_type)
+ / "reductions"
+ / f"metric={metric}"
+ / "labels"
+ / f"directed={str(directed).lower()}"
+ / f"threshold={threshold}.parquet"
+ )
+ internal.parent.mkdir(exist_ok=True, parents=True)
+ temporary_internal = internal.with_suffix(".tmp.parquet")
+ internal_frame.to_parquet(
+ temporary_internal,
+ index=False,
+ compression="zstd",
+ )
+ temporary_internal.replace(internal)
+ LOG.info(
+ "component merge metric=%s complete: elapsed_seconds=%.1f",
+ metric,
+ time() - started,
+ )
+ return labels
+
+
+def count_crossing_component_edges(
+ *,
+ edge_batches: Iterable[pd.DataFrame],
+ labels_by_threshold: Mapping[int, pd.DataFrame],
+ query_column: str = "query_node",
+ target_column: str = "target_node",
+ similarity_column: str = "similarity",
+) -> dict[int, int]:
+ """Count qualifying edges that cross generated component labels."""
+ if not labels_by_threshold:
+ raise ValueError("component labels are required for validation")
+ label_maps: dict[int, dict[str, str]] = {}
+ for threshold, labels in labels_by_threshold.items():
+ missing = sorted({"ligand_id", "label"}.difference(labels.columns))
+ if missing:
+ raise ValueError(f"component labels are missing columns {missing}")
+ if labels["ligand_id"].duplicated().any():
+ raise ValueError(f"component labels at {threshold} contain duplicate nodes")
+ label_maps[threshold] = dict(
+ zip(labels["ligand_id"].astype(str), labels["label"].astype(str))
+ )
+ crossings = dict.fromkeys(label_maps, 0)
+ required = {query_column, target_column, similarity_column}
+ for batch in edge_batches:
+ missing = sorted(required.difference(batch.columns))
+ if missing:
+ raise ValueError(f"component edge batch is missing columns {missing}")
+ if batch.empty:
+ continue
+ values = batch[[query_column, target_column, similarity_column]].dropna()
+ similarities = pd.to_numeric(values[similarity_column], errors="coerce")
+ for threshold, labels in label_maps.items():
+ qualifies = similarities >= threshold
+ if not qualifies.any():
+ continue
+ query_labels = values.loc[qualifies, query_column].astype(str).map(labels)
+ target_labels = values.loc[qualifies, target_column].astype(str).map(labels)
+ eligible = query_labels.notna() & target_labels.notna()
+ crossings[threshold] += int(
+ (query_labels.loc[eligible] != target_labels.loc[eligible]).sum()
+ )
+ return crossings
+
+
+def _eligible_annotation(data_dir: Path) -> pd.DataFrame:
+ columns = [
+ "system_id",
+ "ligand_id",
+ "system_type",
+ "ligand_is_proper",
+ ]
+ annotation = pd.read_parquet(
+ data_dir / "index" / "annotation_table.parquet",
+ columns=columns,
+ )
+ return annotation[
+ (annotation["system_type"] == "holo")
+ & annotation["ligand_is_proper"].fillna(False).astype(bool)
+ ]
+
+
+def _greedy_set_cover(
+ graph: nk.graph.Graph,
+ nodes: Sequence[str],
+) -> list[tuple[str, list[str]]]:
+ """Partition a threshold graph by greedy cover and best-representative assignment.
+
+ The first pass repeatedly selects the candidate whose closed neighborhood
+ covers the most uncovered nodes, with stable node ID as the tie-break. The
+ selected representatives stay fixed; every other node is then assigned to
+ the connected representative with its highest edge weight. Consequently
+ every member has a direct threshold-qualified edge to its representative.
+ """
+ if graph.isDirected():
+ raise ValueError("set covering requires an undirected graph")
+ if not graph.isWeighted():
+ raise ValueError("set covering requires edge weights")
+ if graph.numberOfNodes() != len(nodes):
+ raise ValueError("graph node count does not match ligand IDs")
+ size = len(nodes)
+ uncovered = set(range(size))
+ centroids: list[int] = []
+ selected: set[int] = set()
+ heap = [(-(graph.degree(node) + 1), str(nodes[node]), node) for node in range(size)]
+ heapq.heapify(heap)
+ while uncovered:
+ while heap:
+ negative_count, node_id, centroid = heapq.heappop(heap)
+ if centroid in selected:
+ continue
+ covered = {centroid} if centroid in uncovered else set()
+ covered.update(
+ int(neighbor)
+ for neighbor in graph.iterNeighbors(centroid)
+ if int(neighbor) in uncovered
+ )
+ actual_count = len(covered)
+ if actual_count == -negative_count:
+ break
+ if actual_count:
+ heapq.heappush(
+ heap,
+ (-actual_count, node_id, centroid),
+ )
+ else:
+ raise RuntimeError("greedy set cover left nodes uncovered")
+ selected.add(centroid)
+ centroids.append(centroid)
+ uncovered.difference_update(covered)
+ if len(centroids) % 100_000 == 0:
+ LOG.info(
+ "set-cover progress: nodes=%d representatives=%d covered=%d "
+ "uncovered=%d",
+ len(nodes),
+ len(centroids),
+ len(nodes) - len(uncovered),
+ len(uncovered),
+ )
+
+ centroid_set = set(centroids)
+ groups: dict[int, list[str]] = {centroid: [] for centroid in centroids}
+ for node, ligand_id in enumerate(nodes):
+ if node in centroid_set:
+ representative = node
+ else:
+ candidates = [
+ int(neighbor)
+ for neighbor in graph.iterNeighbors(node)
+ if int(neighbor) in centroid_set
+ ]
+ if not candidates:
+ raise RuntimeError(
+ f"greedy cover left {ligand_id} without a connected centroid"
+ )
+ representative = min(
+ candidates,
+ key=lambda centroid: (
+ -float(graph.weight(node, centroid)),
+ str(nodes[centroid]),
+ ),
+ )
+ groups[representative].append(str(ligand_id))
+ return [(str(nodes[centroid]), groups[centroid]) for centroid in centroids]
+
+
+@dataclass(frozen=True)
+class _RepresentativeSelection:
+ representative: int
+ order: int
+ threshold: int | None
+ marginal_gain: int
+
+
+@dataclass(frozen=True)
+class _RepresentativeAssignment:
+ query: int
+ representative: int
+ similarity: float
+ threshold: int | None
+
+
+def _selection_mask(
+ values: NDArray[np.bool_] | None,
+ *,
+ size: int,
+ name: str,
+) -> NDArray[np.bool_]:
+ if values is None:
+ return np.ones(size, dtype=bool)
+ result = np.asarray(values, dtype=bool)
+ if result.shape != (size,):
+ raise ValueError(f"{name} must have shape ({size},), got {result.shape}")
+ return result.copy()
+
+
+def _incoming_cover(
+ graph: nk.graph.Graph,
+ representative: int,
+ *,
+ minimum_weight: float,
+ uncovered: NDArray[np.bool_],
+) -> NDArray[np.int64]:
+ covered = [representative] if uncovered[representative] else []
+ covered.extend(
+ int(query)
+ for query in graph.iterInNeighbors(representative)
+ if int(query) != representative
+ and uncovered[int(query)]
+ and float(graph.weight(int(query), representative)) >= minimum_weight
+ )
+ return np.asarray(covered, dtype=np.int64)
+
+
+def _greedy_directed_set_cover(
+ graph: nk.graph.Graph,
+ nodes: Sequence[str],
+ *,
+ primary_threshold: int,
+ fallback_threshold: int = 50,
+ fallback_graph: nk.graph.Graph | None = None,
+ candidate_mask: NDArray[np.bool_] | None = None,
+ target_mask: NDArray[np.bool_] | None = None,
+ initial_primary_gains: NDArray[np.integer[Any]] | None = None,
+ initial_fallback_gains: NDArray[np.integer[Any]] | None = None,
+) -> tuple[list[_RepresentativeSelection], list[_RepresentativeAssignment]]:
+ """Select representatives by residual gain at two directed thresholds.
+
+ An edge ``query -> representative`` means that selecting the target covers
+ the query. At each threshold, the candidate covering the most uncovered
+ queries is selected, with stable node ID as the only tie-break. Existing
+ representatives are expanded when the threshold drops. Any target still
+ uncovered after the fallback pass represents itself.
+ """
+ if not graph.isDirected() or not graph.isWeighted():
+ raise ValueError("directed representative covering requires a weighted graph")
+ if graph.numberOfNodes() != len(nodes):
+ raise ValueError("graph node count does not match ligand IDs")
+ if fallback_graph is None:
+ fallback_graph = graph
+ if not fallback_graph.isDirected() or not fallback_graph.isWeighted():
+ raise ValueError("fallback covering requires a weighted directed graph")
+ if fallback_graph.numberOfNodes() != len(nodes):
+ raise ValueError("fallback graph node count does not match ligand IDs")
+ if not 0 <= fallback_threshold <= primary_threshold <= 100:
+ raise ValueError(
+ "representative thresholds must satisfy "
+ "0 <= fallback_threshold <= primary_threshold <= 100"
+ )
+ size = len(nodes)
+ candidates = _selection_mask(
+ candidate_mask,
+ size=size,
+ name="candidate_mask",
+ )
+ targets = _selection_mask(target_mask, size=size, name="target_mask")
+
+ primary_weight = primary_threshold / 100.0
+ fallback_weight = fallback_threshold / 100.0
+ uncovered = targets.copy()
+ selected = np.zeros(size, dtype=bool)
+
+ def make_heap(
+ active_graph: nk.graph.Graph,
+ minimum_weight: float,
+ heap_candidates: NDArray[np.bool_],
+ initial_gains: NDArray[np.integer[Any]] | None,
+ ) -> tuple[list[tuple[int, str, int, int]], NDArray[np.int64], NDArray[np.int64]]:
+ if initial_gains is None:
+ gains = np.zeros(size, dtype=np.int64)
+ for node in (int(index) for index in np.flatnonzero(heap_candidates)):
+ gains[node] = len(
+ _incoming_cover(
+ active_graph,
+ node,
+ minimum_weight=minimum_weight,
+ uncovered=targets,
+ )
+ )
+ else:
+ gains = np.asarray(initial_gains, dtype=np.int64).copy()
+ if gains.shape != (size,):
+ raise ValueError(f"initial gains must have shape ({size},)")
+
+ # Initial counts include every target. Remove those already covered by
+ # a stricter pass before constructing the fallback heap.
+ for query in (int(index) for index in np.flatnonzero(targets & ~uncovered)):
+ if heap_candidates[query]:
+ gains[query] -= 1
+ for target in active_graph.iterNeighbors(query):
+ candidate = int(target)
+ if (
+ candidate != query
+ and heap_candidates[candidate]
+ and float(active_graph.weight(query, candidate)) >= minimum_weight
+ ):
+ gains[candidate] -= 1
+
+ versions = np.zeros(size, dtype=np.int64)
+ heap = [
+ (-int(gains[node]), str(nodes[node]), node, 0)
+ for node in (int(index) for index in np.flatnonzero(heap_candidates))
+ ]
+ heapq.heapify(heap)
+ return heap, gains, versions
+
+ selections: list[_RepresentativeSelection] = []
+
+ def select_from_heap(
+ *,
+ active_graph: nk.graph.Graph,
+ minimum_weight: float,
+ selection_threshold: int,
+ initial_gains: NDArray[np.integer[Any]] | None,
+ ) -> None:
+ heap_candidates = candidates & ~selected
+ heap, gains, versions = make_heap(
+ active_graph,
+ minimum_weight,
+ heap_candidates,
+ initial_gains,
+ )
+ while uncovered.any():
+ while heap:
+ negative_gain, _, representative, version = heapq.heappop(heap)
+ if selected[representative] or version != versions[representative]:
+ continue
+ newly_covered = _incoming_cover(
+ active_graph,
+ representative,
+ minimum_weight=minimum_weight,
+ uncovered=uncovered,
+ )
+ if len(newly_covered) != -negative_gain:
+ raise RuntimeError("directed-cover residual gains are inconsistent")
+ if np.any(newly_covered != representative):
+ break
+ else:
+ return
+ selected[representative] = True
+ uncovered[newly_covered] = False
+ selections.append(
+ _RepresentativeSelection(
+ representative=representative,
+ order=len(selections),
+ threshold=selection_threshold,
+ marginal_gain=len(newly_covered),
+ )
+ )
+ touched: set[int] = set()
+ for query in newly_covered:
+ query = int(query)
+ if heap_candidates[query] and not selected[query]:
+ gains[query] -= 1
+ touched.add(query)
+ for target in active_graph.iterNeighbors(query):
+ candidate = int(target)
+ if (
+ candidate != query
+ and heap_candidates[candidate]
+ and not selected[candidate]
+ and float(active_graph.weight(query, candidate))
+ >= minimum_weight
+ ):
+ gains[candidate] -= 1
+ touched.add(candidate)
+ for candidate in touched:
+ versions[candidate] += 1
+ heapq.heappush(
+ heap,
+ (
+ -int(gains[candidate]),
+ str(nodes[candidate]),
+ candidate,
+ int(versions[candidate]),
+ ),
+ )
+ if len(selections) % 100_000 == 0:
+ LOG.info(
+ "directed representative cover progress: nodes=%d "
+ "selected=%d covered=%d uncovered=%d",
+ size,
+ len(selections),
+ int(targets.sum() - uncovered.sum()),
+ int(uncovered.sum()),
+ )
+
+ select_from_heap(
+ active_graph=graph,
+ minimum_weight=primary_weight,
+ selection_threshold=primary_threshold,
+ initial_gains=initial_primary_gains,
+ )
+
+ if fallback_threshold < primary_threshold and uncovered.any():
+ # Representatives selected from stricter edges remain valid choices.
+ # Before adding any new representative, let them cover all remaining
+ # queries that reach them at the fallback threshold.
+ for representative_index in np.flatnonzero(selected):
+ representative = int(representative_index)
+ newly_covered = _incoming_cover(
+ fallback_graph,
+ int(representative),
+ minimum_weight=fallback_weight,
+ uncovered=uncovered,
+ )
+ uncovered[newly_covered] = False
+ select_from_heap(
+ active_graph=fallback_graph,
+ minimum_weight=fallback_weight,
+ selection_threshold=fallback_threshold,
+ initial_gains=initial_fallback_gains,
+ )
+
+ remaining = sorted(
+ (int(index) for index in np.flatnonzero(uncovered)),
+ key=lambda node: str(nodes[node]),
+ )
+ for representative in remaining:
+ selected[representative] = True
+ uncovered[representative] = False
+ selections.append(
+ _RepresentativeSelection(
+ representative=representative,
+ order=len(selections),
+ threshold=None,
+ marginal_gain=1,
+ )
+ )
+
+ selection_by_node = {
+ selection.representative: selection for selection in selections
+ }
+ assignments: list[_RepresentativeAssignment] = []
+ for query in (int(index) for index in np.flatnonzero(targets)):
+ if query in selection_by_node:
+ representative = query
+ similarity = 100.0
+ assignment_threshold = primary_threshold
+ else:
+ strict: list[int] = []
+ for target in graph.iterNeighbors(query):
+ representative = int(target)
+ if (
+ representative in selection_by_node
+ and float(graph.weight(query, representative)) >= primary_weight
+ ):
+ strict.append(representative)
+ options = strict
+ assignment_threshold = primary_threshold
+ if not options and fallback_threshold < primary_threshold:
+ options = []
+ for target in fallback_graph.iterNeighbors(query):
+ representative = int(target)
+ if (
+ representative in selection_by_node
+ and float(fallback_graph.weight(query, representative))
+ >= fallback_weight
+ ):
+ options.append(representative)
+ assignment_threshold = fallback_threshold
+ if not options:
+ raise RuntimeError(
+ f"directed cover left {nodes[query]} without a representative"
+ )
+ representative = min(
+ options,
+ key=lambda candidate: (
+ -float(
+ (
+ graph
+ if assignment_threshold == primary_threshold
+ else fallback_graph
+ ).weight(query, candidate)
+ ),
+ str(nodes[candidate]),
+ ),
+ )
+ assignment_graph = (
+ graph if assignment_threshold == primary_threshold else fallback_graph
+ )
+ similarity = 100.0 * float(assignment_graph.weight(query, representative))
+ assignments.append(
+ _RepresentativeAssignment(
+ query=query,
+ representative=representative,
+ similarity=similarity,
+ threshold=assignment_threshold,
+ )
+ )
+ return selections, assignments
+
+
+@dataclass(frozen=True)
+class _IncomingEdgeIndex:
+ """Compact target-indexed directed edges."""
+
+ offsets: NDArray[np.int64]
+ queries: NDArray[np.uint32]
+ similarities: NDArray[np.uint8]
+
+ @property
+ def size(self) -> int:
+ return len(self.offsets) - 1
+
+ def incoming(
+ self,
+ representative: int,
+ threshold: int,
+ uncovered: NDArray[np.bool_],
+ ) -> NDArray[np.int64]:
+ start = int(self.offsets[representative])
+ end = int(self.offsets[representative + 1])
+ queries = self.queries[start:end]
+ similarities = self.similarities[start:end]
+ keep = (
+ (queries != representative)
+ & (similarities >= threshold)
+ & uncovered[queries]
+ )
+ covered = queries[keep].astype(np.int64, copy=False)
+ if uncovered[representative]:
+ covered = np.concatenate(
+ (np.asarray([representative], dtype=np.int64), covered)
+ )
+ return cast(NDArray[np.int64], covered)
+
+
+def _greedy_indexed_directed_set_cover(
+ index: _IncomingEdgeIndex,
+ nodes: Sequence[str],
+ *,
+ primary_threshold: int,
+ fallback_threshold: int,
+ primary_gains: NDArray[np.integer[Any]],
+ fallback_gains: NDArray[np.integer[Any]],
+ components: NDArray[np.integer[Any]] | None = None,
+ outgoing_index: _IncomingEdgeIndex,
+) -> tuple[
+ list[_RepresentativeSelection],
+ NDArray[np.int64],
+ NDArray[np.float32],
+ NDArray[np.int16],
+]:
+ """Run the directed cover without keeping a full graph in memory."""
+ from plinder.data._cover import decrement_gains
+
+ size = len(nodes)
+ if index.size != size:
+ raise ValueError("edge index does not match the node universe")
+ uncovered = np.ones(size, dtype=bool)
+ selected = np.zeros(size, dtype=bool)
+ selections: list[_RepresentativeSelection] = []
+ primary_gains = cast(NDArray[np.int64], primary_gains.astype(np.int64, copy=True))
+ fallback_gains = cast(NDArray[np.int64], fallback_gains.astype(np.int64, copy=True))
+
+ def cover(queries: NDArray[np.int64]) -> None:
+ uncovered[queries] = False
+ decrement_gains(
+ queries,
+ outgoing_index.offsets,
+ outgoing_index.queries,
+ outgoing_index.similarities,
+ primary_threshold,
+ fallback_threshold,
+ primary_gains,
+ fallback_gains,
+ )
+
+ def select(
+ threshold: int,
+ gains: NDArray[np.integer[Any]],
+ component_nodes: NDArray[np.int64],
+ remaining: int,
+ ) -> int:
+ heap = [
+ (-int(gains[node]), str(nodes[node]), int(node))
+ for node in component_nodes
+ if not selected[node]
+ ]
+ heapq.heapify(heap)
+ while heap and remaining:
+ negative_gain, node_id, representative = heapq.heappop(heap)
+ if selected[representative]:
+ continue
+ gain = int(gains[representative])
+ if gain != -negative_gain:
+ heapq.heappush(heap, (-gain, node_id, representative))
+ continue
+ if gain == 0 or (gain == 1 and uncovered[representative]):
+ continue
+ newly_covered = index.incoming(
+ representative,
+ threshold,
+ uncovered,
+ )
+ if not np.any(newly_covered != representative):
+ continue
+ selected[representative] = True
+ cover(newly_covered)
+ remaining -= gain
+ selections.append(
+ _RepresentativeSelection(
+ representative=representative,
+ order=len(selections),
+ threshold=threshold,
+ marginal_gain=gain,
+ )
+ )
+ return remaining
+
+ # Components are defined at the fallback threshold, so neither pass can
+ # cover another component. Keep the shared edge index and bound heap work.
+ if components is None:
+ groups = [np.arange(size, dtype=np.int64)]
+ else:
+ order = np.argsort(components, kind="stable")
+ boundaries = np.flatnonzero(np.diff(components[order])) + 1
+ groups = np.split(order, boundaries)
+ for component_nodes in groups:
+ selection_start = len(selections)
+ remaining = select(
+ primary_threshold, primary_gains, component_nodes, len(component_nodes)
+ )
+ if fallback_threshold < primary_threshold and remaining:
+ for selection in selections[selection_start:]:
+ newly_covered = index.incoming(
+ selection.representative, fallback_threshold, uncovered
+ )
+ cover(newly_covered)
+ remaining -= len(newly_covered)
+ if remaining:
+ select(fallback_threshold, fallback_gains, component_nodes, remaining)
+ for representative in sorted(
+ (int(node) for node in component_nodes if uncovered[node]),
+ key=lambda node: str(nodes[node]),
+ ):
+ selected[representative] = True
+ uncovered[representative] = False
+ selections.append(
+ _RepresentativeSelection(
+ representative=representative,
+ order=len(selections),
+ threshold=None,
+ marginal_gain=1,
+ )
+ )
+
+ representatives = np.asarray(
+ [selection.representative for selection in selections], dtype=np.int64
+ )
+ best_representative = np.full(size, -1, dtype=np.int64)
+ best_similarity = np.full(size, -1, dtype=np.float32)
+ assignment_threshold = np.full(size, primary_threshold, dtype=np.int16)
+ best_representative[representatives] = representatives
+ best_similarity[representatives] = 100.0
+
+ def assign(threshold: int, only_unassigned: bool) -> None:
+ for representative_index in representatives:
+ representative = int(representative_index)
+ start = int(index.offsets[representative])
+ end = int(index.offsets[representative + 1])
+ queries = index.queries[start:end]
+ similarities = index.similarities[start:end]
+ keep = (
+ (queries != representative)
+ & (similarities >= threshold)
+ & ~selected[queries]
+ )
+ if only_unassigned:
+ keep &= best_representative[queries] < 0
+ queries = queries[keep]
+ similarities = similarities[keep]
+ current_representatives = best_representative[queries]
+ better = similarities > best_similarity[queries]
+ tied = (similarities == best_similarity[queries]) & (
+ (current_representatives < 0)
+ | (representative < current_representatives)
+ )
+ update = better | tied
+ queries = queries[update]
+ best_representative[queries] = representative
+ best_similarity[queries] = similarities[update]
+ assignment_threshold[queries] = threshold
+
+ assign(primary_threshold, only_unassigned=False)
+ if fallback_threshold < primary_threshold:
+ assign(fallback_threshold, only_unassigned=True)
+ if np.any(best_representative < 0):
+ raise RuntimeError("directed cover left nodes without a representative")
+ return selections, best_representative, best_similarity, assignment_threshold
+
+
+def _greedy_directed_centroid_cover(
+ graph: nk.graph.Graph,
+ nodes: Sequence[str],
+) -> list[tuple[str, str, float, int, float]]:
+ """Compatibility wrapper for a full node-level directed cover."""
+ selections, assignments = _greedy_directed_set_cover(
+ graph,
+ nodes,
+ primary_threshold=0,
+ fallback_threshold=0,
+ )
+ del selections
+ target_mask = np.ones(len(nodes), dtype=bool)
+ coverage_counts = [
+ len(
+ _incoming_cover(
+ graph,
+ node,
+ minimum_weight=0.0,
+ uncovered=target_mask,
+ )
+ )
+ for node in range(len(nodes))
+ ]
+ return [
+ (
+ str(nodes[assignment.query]),
+ str(nodes[assignment.representative]),
+ assignment.similarity,
+ coverage_counts[assignment.query],
+ coverage_counts[assignment.query] / len(nodes),
+ )
+ for assignment in assignments
+ ]
+
+
+def _expand_fingerprint_cover(
+ *, data_dir: Path, assignments: pd.DataFrame
+) -> pd.DataFrame:
+ """Expand SMILES-node assignments to ligand IDs and concrete centroids."""
+ ligands_per_smiles = pd.read_parquet(
+ data_dir / "fingerprints/ligands_per_smiles.parquet",
+ columns=["ligand_rdkit_canonical_smiles", "ligand_smiles_id"],
+ )
+ annotation = pd.read_parquet(
+ data_dir / "index/annotation_table.parquet",
+ columns=[
+ "ligand_id",
+ "ligand_smiles",
+ "ligand_is_proper",
+ ],
+ filters=[("ligand_is_proper", "==", True)],
+ )
+ smiles_to_id = dict(
+ zip(
+ ligands_per_smiles["ligand_rdkit_canonical_smiles"],
+ ligands_per_smiles["ligand_smiles_id"].astype(str),
+ )
+ )
+ annotation["node"] = annotation["ligand_smiles"].map(smiles_to_id)
+ annotation.dropna(subset=["node"], inplace=True)
+ ligands_by_node = {
+ str(node): tuple(sorted(set(group["ligand_id"].astype(str))))
+ for node, group in annotation.groupby("node", sort=False)
+ }
+ representative_by_node = {
+ str(node): min(group["ligand_id"].astype(str))
+ for node, group in annotation.groupby("node", sort=False)
+ }
+ expanded = assignments.copy()
+ expanded["ligand_id"] = expanded["ligand_id"].map(ligands_by_node)
+ expanded["centroid_ligand_id"] = expanded["centroid_node"].map(
+ representative_by_node
+ )
+ return (
+ expanded.dropna(subset=["ligand_id", "centroid_ligand_id"])
+ .explode("ligand_id")
+ .reset_index(drop=True)
+ )
+
+
+def directed_set_cover_is_complete(
+ path: Path,
+ *,
+ entity_type: ClusterEntity = "ligand",
+) -> bool:
+ """Return whether a cached directed-cover artifact has the current schema."""
+ centroid_column = (
+ "centroid_ligand_id" if entity_type == "ligand" else "centroid_system_id"
+ )
+ required_columns = {
+ _cluster_node_column(entity_type),
+ centroid_column,
+ "similarity_to_centroid",
+ "coverage_count",
+ "coverage_fraction",
+ "representative_selection_order",
+ "representative_selection_threshold",
+ "representative_marginal_gain",
+ "assignment_threshold",
+ "label",
+ "metric",
+ "threshold",
+ "directed",
+ }
+ try:
+ return path.is_file() and required_columns.issubset(pq.read_schema(path).names)
+ except (OSError, ValueError):
+ return False
+
+
+def set_cover_is_complete(path: Path) -> bool:
+ """Return whether a cached ligand-Tanimoto cover has the current schema."""
+ required_columns = {
+ "ligand_id",
+ "centroid_ligand_id",
+ "label",
+ "metric",
+ "cluster",
+ "threshold",
+ "directed",
+ }
+ try:
+ return path.is_file() and required_columns.issubset(pq.read_schema(path).names)
+ except (OSError, ValueError):
+ return False
+
+
+def _directed_cover_labels(
+ *,
+ data_dir: Path,
+ metric: str,
+ threshold: int,
+ entity_type: ClusterEntity = "ligand",
+) -> pd.DataFrame:
+ """Load node labels and compact indices for one connectivity threshold."""
+ node_column = _cluster_node_column(entity_type)
+ path = (
+ _sampling_root(data_dir, entity_type)
+ / "directed_set_cover"
+ / "reductions"
+ / f"metric={metric}"
+ / "labels"
+ / f"threshold={threshold}.parquet"
+ )
+ if not path.is_file():
+ raise FileNotFoundError(
+ f"directed-cover connectivity must be merged before covering: {path}"
+ )
+ labels = pd.read_parquet(path, columns=[node_column, "label"])
+ labels[node_column] = labels[node_column].astype(str)
+ labels["label"] = labels["label"].astype(str)
+ labels["component"] = pd.factorize(labels["label"], sort=False)[0].astype(np.uint32)
+ labels = labels.sort_values(["component", node_column], kind="stable").reset_index(
+ drop=True
+ )
+ labels["component_node"] = (
+ labels.groupby("component", sort=False).cumcount().astype(np.uint32)
+ )
+ return labels
+
+
+def _stage_directed_cover_edges(
+ *,
+ data_dir: Path,
+ metric: str,
+ threshold: int,
+ staged_edges: Path,
+ incoming_counts_path: Path,
+ temporary_root: Path,
+ threads: int,
+ entity_type: ClusterEntity,
+) -> int:
+ """Write one target-sorted directed edge stream in a short-lived process."""
+ node_column = _cluster_node_column(entity_type)
+ labels = _directed_cover_labels(
+ data_dir=data_dir,
+ metric=metric,
+ threshold=threshold,
+ entity_type=entity_type,
+ )
+ labels["graph_node"] = np.arange(len(labels), dtype=np.uint32)
+ sources = component_score_sources(
+ data_dir=data_dir,
+ metric=metric,
+ entity_type=entity_type,
+ )
+ import duckdb
+
+ connection = duckdb.connect()
+ _set_slurm_memory_limit(connection, 4)
+ connection.sql(f"SET threads={threads}")
+ connection.sql("SET preserve_insertion_order=false")
+ temporary_root.mkdir(exist_ok=True, parents=True)
+ escaped_temporary_root = temporary_root.as_posix().replace("'", "''")
+ connection.sql(f"SET temp_directory='{escaped_temporary_root}'")
+ connection.register(
+ "component_labels",
+ labels[[node_column, "graph_node"]],
+ )
+ paths_sql = ", ".join(
+ f"'{path.as_posix().replace(chr(39), chr(39) * 2)}'" for path in sources
+ )
+ query = dedent(
+ f"""
+ WITH directed_edges AS (
+ SELECT
+ cast(query_node AS VARCHAR) AS query_node,
+ cast(target_node AS VARCHAR) AS target_node,
+ forward_similarity::DOUBLE AS similarity
+ FROM read_parquet([{paths_sql}])
+ WHERE forward_similarity >= {threshold}
+ UNION ALL
+ SELECT
+ cast(target_node AS VARCHAR) AS query_node,
+ cast(query_node AS VARCHAR) AS target_node,
+ reverse_similarity::DOUBLE AS similarity
+ FROM read_parquet([{paths_sql}])
+ WHERE reverse_similarity >= {threshold}
+ ), labeled AS (
+ SELECT
+ query_labels.graph_node::UINTEGER AS query_node,
+ target_labels.graph_node::UINTEGER AS target_node,
+ CAST(round(directed_edges.similarity) AS UTINYINT) AS similarity
+ FROM directed_edges
+ INNER JOIN component_labels AS query_labels
+ ON directed_edges.query_node = query_labels.{node_column}
+ INNER JOIN component_labels AS target_labels
+ ON directed_edges.target_node = target_labels.{node_column}
+ )
+ SELECT
+ query_node,
+ target_node,
+ similarity
+ FROM labeled
+ ORDER BY target_node, query_node
+ """
+ )
+ LOG.info(
+ "directed cover edge query start: metric=%s threshold=%d "
+ "sources=%d nodes=%d components=%d",
+ metric,
+ threshold,
+ len(sources),
+ len(labels),
+ labels["component"].nunique(),
+ )
+ staged_edges.unlink(missing_ok=True)
+ incoming_counts_path.unlink(missing_ok=True)
+ staged_rows = 0
+ incoming_counts = np.zeros(len(labels), dtype=np.int64)
+ stage_started = time()
+ try:
+ escaped_staged_edges = staged_edges.as_posix().replace("'", "''")
+ connection.execute(
+ f"COPY ({query}) TO '{escaped_staged_edges}' "
+ "(FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 2000000)"
+ )
+ previous_target = -1
+ for batch_index, batch in enumerate(
+ pq.ParquetFile(staged_edges).iter_batches(
+ batch_size=2_000_000, columns=["target_node"]
+ ),
+ start=1,
+ ):
+ targets = batch.column(0).to_numpy(zero_copy_only=False)
+ if len(targets) and (
+ int(targets[0]) < previous_target or np.any(targets[1:] < targets[:-1])
+ ):
+ raise ValueError("directed-cover edges are not target-sorted")
+ if len(targets):
+ previous_target = int(targets[-1])
+ staged_rows += len(targets)
+ incoming_counts += np.bincount(targets, minlength=len(labels))
+ if batch_index % 5 == 0:
+ elapsed = time() - stage_started
+ LOG.info(
+ "directed cover edge staging progress: metric=%s threshold=%d "
+ "batches=%d rows=%d rate=%.1f_rows/s elapsed_seconds=%.1f",
+ metric,
+ threshold,
+ batch_index,
+ staged_rows,
+ staged_rows / elapsed,
+ elapsed,
+ )
+ except BaseException:
+ connection.close()
+ staged_edges.unlink(missing_ok=True)
+ incoming_counts_path.unlink(missing_ok=True)
+ raise
+ else:
+ connection.close()
+ np.save(incoming_counts_path, incoming_counts, allow_pickle=False)
+ LOG.info(
+ "directed cover edge staging complete: metric=%s threshold=%d rows=%d "
+ "size_gb=%.2f elapsed_seconds=%.1f",
+ metric,
+ threshold,
+ staged_rows,
+ staged_edges.stat().st_size / (1024**3),
+ time() - stage_started,
+ )
+ return staged_rows
+
+
+def _publish_directed_cover(
+ *,
+ data_dir: Path,
+ metric: str,
+ threshold: int,
+ assignments: pd.DataFrame,
+ started: float,
+ entity_type: ClusterEntity,
+) -> Path:
+ """Add stable labels and atomically write one directed cover."""
+ node_column = _cluster_node_column(entity_type)
+ output = (
+ _sampling_root(data_dir, entity_type)
+ / "directed_set_cover"
+ / f"metric={metric}"
+ / f"threshold={threshold}.parquet"
+ )
+ published = assignments
+ published["coverage_count"] = published["coverage_count"].astype("Int32")
+ published["coverage_fraction"] = published["coverage_fraction"].astype("Float32")
+ published["representative_selection_order"] = published[
+ "representative_selection_order"
+ ].astype("Int32")
+ published["representative_selection_threshold"] = published[
+ "representative_selection_threshold"
+ ].astype("Int16")
+ published["representative_marginal_gain"] = published[
+ "representative_marginal_gain"
+ ].astype("Int32")
+ published["assignment_threshold"] = published["assignment_threshold"].astype(
+ "Int16"
+ )
+
+ representatives = published.drop_duplicates("centroid_node").sort_values(
+ ["fallback_component", "representative_selection_order"], kind="stable"
+ )
+ stable_order = dict(
+ zip(representatives["centroid_node"], range(len(representatives)))
+ )
+ published["representative_selection_order"] = (
+ published["centroid_node"].map(stable_order).astype("Int32")
+ )
+ published.drop(columns="fallback_component", inplace=True)
+ if is_chemical_cluster_metric(metric):
+ published = _expand_fingerprint_cover(
+ data_dir=data_dir,
+ assignments=published,
+ )
+ else:
+ published[
+ "centroid_ligand_id" if entity_type == "ligand" else "centroid_system_id"
+ ] = published["centroid_node"]
+ group_sizes = published.groupby("centroid_node", sort=False).size()
+ ordered_centroids = sorted(
+ group_sizes.index.astype(str),
+ key=lambda centroid: (-int(group_sizes.loc[centroid]), centroid),
+ )
+ published["label"] = published["centroid_node"].map(
+ {centroid: f"c{index}" for index, centroid in enumerate(ordered_centroids)}
+ )
+ published["metric"] = metric
+ published["threshold"] = threshold
+ published["directed"] = True
+ published.drop(columns=["centroid_node"], inplace=True)
+ published.sort_values(node_column, inplace=True, kind="stable")
+ output.parent.mkdir(exist_ok=True, parents=True)
+ temporary = output.with_suffix(".tmp.parquet")
+ published.to_parquet(temporary, index=False, compression="zstd")
+ temporary.replace(output)
+ LOG.info(
+ "directed cover complete: metric=%s threshold=%d assignments=%d "
+ "centroids=%d elapsed_seconds=%.1f",
+ metric,
+ threshold,
+ len(published),
+ published[
+ "centroid_ligand_id" if entity_type == "ligand" else "centroid_system_id"
+ ].nunique(),
+ time() - started,
+ )
+ return output
+
+
+def _build_incoming_edge_index(
+ *,
+ staged_edges: Path,
+ incoming_counts_path: Path,
+ query_index_path: Path,
+ similarity_index_path: Path,
+ thresholds: set[int],
+ node_count: int,
+ reuse_existing: bool = False,
+) -> tuple[_IncomingEdgeIndex, dict[int, NDArray[np.int64]]]:
+ """Build a compact target-indexed edge store from the staged stream."""
+ incoming_counts = np.load(incoming_counts_path, allow_pickle=False)
+ offsets = np.empty(node_count + 1, dtype=np.int64)
+ offsets[0] = 0
+ np.cumsum(incoming_counts, out=offsets[1:])
+ edge_count = int(offsets[-1])
+ coverage_counts = {
+ threshold: np.ones(node_count, dtype=np.int64) for threshold in thresholds
+ }
+ if edge_count == 0:
+ return (
+ _IncomingEdgeIndex(
+ offsets=offsets,
+ queries=np.empty(0, dtype=np.uint32),
+ similarities=np.empty(0, dtype=np.uint8),
+ ),
+ coverage_counts,
+ )
+
+ queries = np.memmap(
+ query_index_path,
+ dtype=np.uint32,
+ mode="r" if reuse_existing else "w+",
+ shape=(edge_count,),
+ )
+ indexed_similarities = np.memmap(
+ similarity_index_path,
+ dtype=np.uint8,
+ mode="r" if reuse_existing else "w+",
+ shape=(edge_count,),
+ )
+ streamed_rows = 0
+ started = time()
+ for batch_index, batch in enumerate(
+ pq.ParquetFile(staged_edges).iter_batches(batch_size=2_000_000), start=1
+ ):
+ frame = batch.to_pandas()
+ query_nodes = frame["query_node"].to_numpy(dtype=np.uint32, copy=False)
+ target_nodes = frame["target_node"].to_numpy(dtype=np.uint32, copy=False)
+ similarities = frame["similarity"].to_numpy(dtype=np.uint8, copy=False)
+
+ end = streamed_rows + len(frame)
+ if not reuse_existing:
+ queries[streamed_rows:end] = query_nodes
+ indexed_similarities[streamed_rows:end] = similarities
+
+ nonself = query_nodes != target_nodes
+ for threshold, counts in coverage_counts.items():
+ selected = nonself & (similarities >= threshold)
+ if selected.any():
+ counts += np.bincount(
+ target_nodes[selected],
+ minlength=node_count,
+ )
+ streamed_rows += len(frame)
+ if batch_index % 25 == 0:
+ elapsed = time() - started
+ LOG.info(
+ "directed cover index progress: rows=%d/%d rate=%.1f_rows/s "
+ "elapsed_seconds=%.1f",
+ streamed_rows,
+ edge_count,
+ streamed_rows / elapsed,
+ elapsed,
+ )
+ if streamed_rows != edge_count:
+ raise ValueError("directed-cover edge index is incomplete")
+ queries.flush()
+ indexed_similarities.flush()
+ return (
+ _IncomingEdgeIndex(
+ offsets=offsets,
+ queries=queries,
+ similarities=indexed_similarities,
+ ),
+ coverage_counts,
+ )
+
+
+def _build_outgoing_edge_index(
+ index: _IncomingEdgeIndex,
+ *,
+ target_index_path: Path,
+ similarity_index_path: Path,
+) -> _IncomingEdgeIndex:
+ """Transpose once so each covered query decrements its candidates once."""
+ from plinder.data._cover import outgoing_counts, transpose_edges
+
+ LOG.info("directed cover reverse index start: edges=%d", len(index.queries))
+ offsets = np.empty(index.size + 1, dtype=np.int64)
+ offsets[0] = 0
+ np.cumsum(outgoing_counts(index.queries, index.size), out=offsets[1:])
+ if not len(index.queries):
+ return _IncomingEdgeIndex(offsets, index.queries, index.similarities)
+ targets = np.memmap(
+ target_index_path, dtype=np.uint32, mode="w+", shape=index.queries.shape
+ )
+ scores = np.memmap(
+ similarity_index_path,
+ dtype=np.uint8,
+ mode="w+",
+ shape=index.similarities.shape,
+ )
+ transpose_edges(
+ index.offsets, index.queries, index.similarities, offsets, targets, scores
+ )
+ targets.flush()
+ scores.flush()
+ LOG.info("directed cover reverse index complete")
+ return _IncomingEdgeIndex(offsets, targets, scores)
+
+
+def make_directed_set_covers(
+ *,
+ data_dir: Path,
+ metric: str,
+ thresholds: Sequence[int],
+ skip_existing: bool = False,
+ scratch_dir: Path | None = None,
+ threads: int = 1,
+ entity_type: ClusterEntity = "ligand",
+ reuse_edge_index: bool = False,
+) -> list[Path]:
+ """Build every requested directed cover from one shared edge stream.
+
+ ``reuse_edge_index`` resumes a prepared index in ``scratch_dir``; it requires
+ the same score graph, minimum threshold and node ordering.
+ """
+ started = time()
+ if entity_type == "ligand" and metric in GATED_LIGAND_DIAGNOSTIC_METRICS:
+ raise ValueError(
+ f"{metric} cannot be clustered directly; use sucos_shape_pocket_qcov"
+ )
+ if threads < 1:
+ raise ValueError("directed-cover threads must be positive")
+ requested = sorted(set(thresholds), reverse=True)
+ if not requested or any(not 0 <= threshold <= 100 for threshold in requested):
+ raise ValueError("directed-cover thresholds must be in [0, 100]")
+ outputs = [
+ _sampling_root(data_dir, entity_type)
+ / "directed_set_cover"
+ / f"metric={metric}"
+ / f"threshold={threshold}.parquet"
+ for threshold in requested
+ ]
+ pending = [
+ threshold
+ for threshold, output in zip(requested, outputs)
+ if not (
+ skip_existing
+ and directed_set_cover_is_complete(output, entity_type=entity_type)
+ )
+ ]
+ if not pending:
+ return outputs
+
+ fallback_thresholds = {threshold: min(threshold, 50) for threshold in pending}
+ edge_threshold = min(fallback_thresholds.values())
+ labels_by_threshold = {
+ threshold: _directed_cover_labels(
+ data_dir=data_dir,
+ metric=metric,
+ threshold=threshold,
+ entity_type=entity_type,
+ )
+ for threshold in sorted(set(fallback_thresholds.values()))
+ }
+ base_labels = labels_by_threshold[edge_threshold]
+ node_column = _cluster_node_column(entity_type)
+ nodes = base_labels[node_column].tolist()
+ fallback_lookup: dict[int, pd.Series[Any]] = {}
+ fallback_sizes: dict[int, pd.Series[Any]] = {}
+ for threshold, labels in labels_by_threshold.items():
+ fallback_lookup[threshold] = labels.set_index(node_column)["component"]
+ fallback_sizes[threshold] = labels.groupby("component", sort=False).size()
+
+ temporary_root = scratch_dir or data_dir / "scratch/duckdb/directed_set_cover"
+ temporary_root.mkdir(exist_ok=True, parents=True)
+ staged_edges = temporary_root / f"{metric}-{edge_threshold}-directed-edges.parquet"
+ incoming_counts_path = temporary_root / f"{metric}-{edge_threshold}-counts.npy"
+ query_index_path = temporary_root / f"{metric}-{edge_threshold}-queries.bin"
+ similarity_index_path = temporary_root / f"{metric}-{edge_threshold}-scores.bin"
+ target_index_path = temporary_root / f"{metric}-{edge_threshold}-targets.bin"
+ outgoing_similarity_path = (
+ temporary_root / f"{metric}-{edge_threshold}-outgoing-scores.bin"
+ )
+ temporary_paths = [
+ staged_edges,
+ incoming_counts_path,
+ query_index_path,
+ similarity_index_path,
+ target_index_path,
+ outgoing_similarity_path,
+ ]
+ published: list[Path] = []
+ try:
+ if not reuse_edge_index:
+ with ProcessPoolExecutor(
+ max_workers=1,
+ mp_context=get_context("spawn"),
+ ) as staging_executor:
+ staging_executor.submit(
+ _stage_directed_cover_edges,
+ data_dir=data_dir,
+ metric=metric,
+ threshold=edge_threshold,
+ staged_edges=staged_edges,
+ incoming_counts_path=incoming_counts_path,
+ temporary_root=temporary_root,
+ threads=threads,
+ entity_type=entity_type,
+ ).result()
+ gc.collect()
+ index, coverage_counts = _build_incoming_edge_index(
+ staged_edges=staged_edges,
+ incoming_counts_path=incoming_counts_path,
+ query_index_path=query_index_path,
+ similarity_index_path=similarity_index_path,
+ thresholds=set(pending).union(fallback_thresholds.values()),
+ node_count=len(nodes),
+ reuse_existing=reuse_edge_index,
+ )
+ outgoing_index = _build_outgoing_edge_index(
+ index,
+ target_index_path=target_index_path,
+ similarity_index_path=outgoing_similarity_path,
+ )
+
+ def build_cover(threshold: int) -> Path:
+ LOG.info(
+ "directed cover selection start: metric=%s threshold=%d",
+ metric,
+ threshold,
+ )
+ fallback_threshold = fallback_thresholds[threshold]
+ fallback_components = (
+ fallback_lookup[fallback_threshold]
+ .reindex(nodes)
+ .to_numpy(dtype=np.uint32)
+ )
+ (
+ selections,
+ representatives,
+ similarities,
+ assignment_thresholds,
+ ) = _greedy_indexed_directed_set_cover(
+ index,
+ nodes,
+ primary_threshold=threshold,
+ fallback_threshold=fallback_threshold,
+ primary_gains=coverage_counts[threshold],
+ fallback_gains=coverage_counts[fallback_threshold],
+ components=fallback_components,
+ outgoing_index=outgoing_index,
+ )
+ selection_orders = np.empty(len(nodes), dtype=np.int32)
+ selection_thresholds = np.empty(len(nodes), dtype=np.int16)
+ selection_gains = np.empty(len(nodes), dtype=np.int32)
+ for selection in selections:
+ representative = selection.representative
+ selection_orders[representative] = selection.order
+ selection_thresholds[representative] = (
+ -1 if selection.threshold is None else selection.threshold
+ )
+ selection_gains[representative] = selection.marginal_gain
+ representative_thresholds = pd.Series(
+ selection_thresholds[representatives], copy=False
+ ).mask(lambda values: values < 0)
+ node_values = np.asarray(nodes, dtype=object)
+ component_sizes = (
+ fallback_sizes[fallback_threshold]
+ .reindex(fallback_components)
+ .to_numpy(dtype=np.int64)
+ )
+ counts = coverage_counts[threshold]
+ assignments = pd.DataFrame(
+ {
+ node_column: node_values,
+ "centroid_node": node_values[representatives],
+ "similarity_to_centroid": similarities,
+ "coverage_count": counts,
+ "coverage_fraction": counts / component_sizes,
+ "representative_selection_order": selection_orders[representatives],
+ "representative_selection_threshold": representative_thresholds,
+ "representative_marginal_gain": selection_gains[representatives],
+ "assignment_threshold": assignment_thresholds,
+ "fallback_component": fallback_components,
+ }
+ )
+ return _publish_directed_cover(
+ data_dir=data_dir,
+ metric=metric,
+ threshold=threshold,
+ assignments=assignments,
+ started=started,
+ entity_type=entity_type,
+ )
+
+ with ThreadPoolExecutor(
+ max_workers=min(threads, len(pending))
+ ) as cover_executor:
+ published = list(cover_executor.map(build_cover, pending))
+ gc.collect()
+ finally:
+ for path in temporary_paths:
+ path.unlink(missing_ok=True)
+ return published
+
+
+def make_directed_set_cover(
+ *,
+ data_dir: Path,
+ metric: str,
+ threshold: int,
+ skip_existing: bool = False,
+ scratch_dir: Path | None = None,
+ threads: int = 1,
+ entity_type: ClusterEntity = "ligand",
+) -> Path:
+ """Build one directed cover."""
+ return make_directed_set_covers(
+ data_dir=data_dir,
+ metric=metric,
+ thresholds=[threshold],
+ skip_existing=skip_existing,
+ scratch_dir=scratch_dir,
+ threads=threads,
+ entity_type=entity_type,
+ )[0]
+
+
+def make_set_cover(
+ *,
+ data_dir: Path,
+ metric: str,
+ threshold: int,
+ skip_existing_clusters: bool = False,
+ scratch_dir: Path | None = None,
+ threads: int = 1,
+ entity_type: ClusterEntity = "ligand",
+) -> Path:
+ """Build an undirected greedy set cover on reciprocal-minimum edges."""
+ started = time()
+ if entity_type != "ligand" or not is_chemical_cluster_metric(metric):
+ raise ValueError(
+ "undirected set cover is supported only for ligand chemical "
+ "(fingerprint) metrics"
+ )
+ if entity_type == "ligand" and metric in GATED_LIGAND_DIAGNOSTIC_METRICS:
+ raise ValueError(
+ f"{metric} is evaluated only for ligand pairs with positive pocket "
+ "coverage and cannot be clustered directly; use "
+ "sucos_shape_pocket_qcov"
+ )
+ if threads < 1:
+ raise ValueError("set-cover threads must be positive")
+ node_column = _cluster_node_column(entity_type)
+ output = (
+ _sampling_root(data_dir, entity_type)
+ / "set_cover"
+ / f"metric={metric}"
+ / f"threshold={threshold}.parquet"
+ )
+ if skip_existing_clusters and set_cover_is_complete(output):
+ return output
+ component_path = (
+ _cluster_root(data_dir, entity_type)
+ / "reductions"
+ / f"metric={metric}"
+ / "labels"
+ / "directed=false"
+ / f"threshold={threshold}.parquet"
+ )
+ if not component_path.is_file():
+ raise FileNotFoundError(
+ "internal connectivity labels must be merged before set cover: "
+ f"{component_path}"
+ )
+ component_labels = pd.read_parquet(component_path)
+ component_labels[node_column] = component_labels[node_column].astype(str)
+ if component_labels[node_column].duplicated().any():
+ raise ValueError(f"duplicate node IDs in component labels: {component_path}")
+ component_labels["label"] = component_labels["label"].astype(str)
+ component_labels["component"] = pd.factorize(component_labels["label"], sort=False)[
+ 0
+ ].astype(np.uint32)
+ component_labels = component_labels.sort_values(
+ ["component", node_column], kind="stable"
+ ).reset_index(drop=True)
+ component_labels["component_node"] = (
+ component_labels.groupby("component", sort=False).cumcount().astype(np.uint32)
+ )
+ nodes_by_component = {
+ int(component): group[node_column].tolist()
+ for component, group in component_labels.groupby("component", sort=False)
+ }
+ component_lookup = component_labels[[node_column, "component", "component_node"]]
+ sources = component_score_sources(
+ data_dir=data_dir,
+ metric=metric,
+ entity_type=entity_type,
+ )
+ if not sources:
+ raise FileNotFoundError(f"no set-cover score sources found for {metric}")
+
+ import duckdb
+
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ temporary_root = scratch_dir or data_dir / "scratch" / "duckdb" / "set_cover"
+ temporary_root.mkdir(exist_ok=True, parents=True)
+ connection.sql(f"SET temp_directory='{temporary_root.as_posix()}'")
+ connection.register("component_labels", component_lookup)
+ paths_sql = ", ".join(
+ f"'{path.as_posix().replace(chr(39), chr(39) * 2)}'" for path in sources
+ )
+ query = dedent(
+ f"""
+ WITH selected AS (
+ SELECT
+ cast(query_node AS VARCHAR) AS query_node,
+ cast(target_node AS VARCHAR) AS target_node,
+ cast(similarity AS DOUBLE) AS similarity
+ FROM read_parquet([{paths_sql}])
+ WHERE similarity >= {threshold}
+ ), labeled AS (
+ SELECT
+ query_labels.component AS query_component,
+ target_labels.component AS target_component,
+ query_labels.component_node::UINTEGER AS query_node,
+ target_labels.component_node::UINTEGER AS target_node,
+ selected.similarity,
+ query_labels.component != target_labels.component AS crossing_edge
+ FROM selected
+ INNER JOIN component_labels AS query_labels
+ ON selected.query_node = query_labels.{node_column}
+ INNER JOIN component_labels AS target_labels
+ ON selected.target_node = target_labels.{node_column}
+ )
+ SELECT
+ query_component AS component,
+ query_node,
+ target_node,
+ similarity,
+ crossing_edge
+ FROM labeled
+ ORDER BY crossing_edge DESC, component, query_node, target_node
+ """
+ )
+ LOG.info(
+ "set-cover edge query start: metric=%s threshold=%d sources=%d "
+ "nodes=%d components=%d elapsed_seconds=%.1f",
+ metric,
+ threshold,
+ len(sources),
+ len(component_labels),
+ len(nodes_by_component),
+ time() - started,
+ )
+ query_started = time()
+ reader = connection.execute(query).fetch_record_batch(rows_per_batch=250_000)
+ LOG.info(
+ "set-cover edge query ready: metric=%s threshold=%d elapsed_seconds=%.1f",
+ metric,
+ threshold,
+ time() - query_started,
+ )
+ cover_groups: list[tuple[str, list[str]]] = []
+ processed_nodes: set[str] = set()
+ current_component: int | None = None
+ current_nodes: list[str] = []
+ current_graph: nk.graph.Graph | None = None
+
+ def finish_component() -> None:
+ nonlocal current_component, current_graph
+ if current_component is None or current_graph is None:
+ return
+ if len(current_nodes) > 1 and current_graph.numberOfEdges() == 0:
+ raise ValueError(
+ f"non-singleton component {current_component} has no edges"
+ )
+ if current_graph.numberOfEdges() == 0:
+ groups = [(node, [node]) for node in current_nodes]
+ else:
+ groups = _greedy_set_cover(
+ current_graph,
+ current_nodes,
+ )
+ cover_groups.extend(groups)
+ processed_nodes.update(current_nodes)
+
+ streamed_rows = 0
+ stream_started = time()
+ for batch_index, record_batch in enumerate(reader, start=1):
+ frame = record_batch.to_pandas()
+ if frame.empty:
+ continue
+ crossing_edges = int(frame["crossing_edge"].fillna(False).sum())
+ if crossing_edges:
+ raise ValueError(
+ f"connectivity partition validation failed for {metric} at "
+ f"{threshold}: {crossing_edges} crossing edges"
+ )
+ frame = frame.dropna(subset=["component"])
+ streamed_rows += len(frame)
+ if batch_index % 20 == 0:
+ elapsed = time() - stream_started
+ LOG.info(
+ "set-cover edge stream progress: metric=%s threshold=%d "
+ "batches=%d rows=%d rate=%.1f_rows/s elapsed_seconds=%.1f",
+ metric,
+ threshold,
+ batch_index,
+ streamed_rows,
+ streamed_rows / elapsed,
+ elapsed,
+ )
+ for component, group in frame.groupby("component", sort=False):
+ component = int(component)
+ if component != current_component:
+ finish_component()
+ current_component = component
+ current_nodes = nodes_by_component[component]
+ current_graph = nk.Graph(
+ len(current_nodes),
+ weighted=True,
+ directed=False,
+ )
+ assert current_graph is not None
+ query_nodes = group["query_node"].to_numpy(dtype=np.uint, copy=False)
+ target_nodes = group["target_node"].to_numpy(dtype=np.uint, copy=False)
+ similarities = group["similarity"].to_numpy(dtype=float, copy=False)
+ current_graph.addEdges((similarities / 100.0, (query_nodes, target_nodes)))
+ finish_component()
+ connection.close()
+ LOG.info(
+ "set-cover edge stream complete: metric=%s threshold=%d rows=%d "
+ "elapsed_seconds=%.1f",
+ metric,
+ threshold,
+ streamed_rows,
+ time() - stream_started,
+ )
+
+ unprocessed = set(component_labels[node_column]) - processed_nodes
+ for component, nodes in nodes_by_component.items():
+ missing = [node for node in nodes if node in unprocessed]
+ if len(missing) > 1:
+ raise ValueError(
+ f"non-singleton component {component} was absent from edges"
+ )
+ cover_groups.extend((node, [node]) for node in missing)
+ ordered_groups = sorted(
+ cover_groups,
+ key=lambda item: (-len(item[1]), item[0]),
+ )
+ published = pd.DataFrame.from_records(
+ [
+ {
+ node_column: node,
+ "centroid_node": representative,
+ "label": f"c{cover_index}",
+ }
+ for cover_index, (representative, group) in enumerate(ordered_groups)
+ for node in sorted(group)
+ ],
+ columns=[node_column, "centroid_node", "label"],
+ )
+ published = _expand_fingerprint_cover(
+ data_dir=data_dir,
+ assignments=published,
+ )
+ published.drop(columns=["centroid_node"], inplace=True)
+ published.sort_values(node_column, inplace=True, kind="stable")
+ if published[node_column].duplicated().any():
+ raise ValueError(
+ "ligand Tanimoto set cover produced duplicate ligand assignments"
)
+ published["metric"] = metric
+ published["directed"] = False
+ published["threshold"] = threshold
+ published["cluster"] = "set_cover"
+ output.parent.mkdir(exist_ok=True, parents=True)
+ temporary = output.with_suffix(".tmp.parquet")
+ published.to_parquet(temporary, index=False, compression="zstd")
+ temporary.replace(output)
+ return output
diff --git a/src/plinder/data/column_descriptions/entry.tsv b/src/plinder/data/column_descriptions/entry.tsv
deleted file mode 100644
index 0d54d280f..000000000
--- a/src/plinder/data/column_descriptions/entry.tsv
+++ /dev/null
@@ -1,8 +0,0 @@
-Name Type Description
-entry_pdb_id str RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html
-entry_release_date str RCSB structure release date. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_database_PDB_rev.date_original.html
-entry_oligomeric_state str | None Author's provided description of quaternary structure in RCSB. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_pdbx_struct_assembly.oligomeric_details.html
-entry_determination_method str | None RCSB method of structure determination. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_exptl.method.html
-entry_keywords str | None RCSB keywords describing the structure. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_struct_keywords.pdbx_keywords.html
-entry_pH str | None pH at which structure is solved. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_exptl_crystal_grow.pH.html
-entry_resolution float | None RCSB structure resolution. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_refine.ls_d_res_high.html
diff --git a/src/plinder/data/column_descriptions/entry_validation.tsv b/src/plinder/data/column_descriptions/entry_validation.tsv
deleted file mode 100644
index c1db07bf6..000000000
--- a/src/plinder/data/column_descriptions/entry_validation.tsv
+++ /dev/null
@@ -1,17 +0,0 @@
-Name Type Description
-entry_validation_resolution float Resolution of the PDB entry
-entry_validation_rfree float The similarity between the observed structure-factor amplitudes and those calculated from the model. Rfree should be higher than R because it is calculated using reflections not used in the refinement. See https://www.wwpdb.org/validation/XrayValidationReportHelp
-entry_validation_r float The similarity between the observed structure-factor amplitudes and those calculated from the model. See https://www.wwpdb.org/validation/XrayValidationReportHelp
-entry_validation_clashscore float The Molprobity Clashscore is an approximation of the overall severity of the clashes in a structure, which is defined as the number of clashes per 1000 atoms (including hydrogens). See https://www.wwpdb.org/validation/XrayValidationReportHelp
-entry_validation_percent_rama_outliers float | None The percentage of Ramachandran outliers with respect to the total number of residues in the entry for which the outlier assessment is available. See https://www.wwpdb.org/validation/XrayValidationReportHelp
-entry_validation_percent_rota_outliers float | None The percentage of residues with an unusual sidechain conformation with respect to the total number of residues for which the assessment is available. See https://www.wwpdb.org/validation/XrayValidationReportHelp
-entry_validation_data_completeness float | None The number of expected diffraction spots is a function of data resolution and the space group. This metric describes the number of recorded reflections as a percentage of the number expected. See https://www.wwpdb.org/validation/XrayValidationReportHelp
-entry_validation_percent_RSRZ_outliers float | None The percentage Real-Space R-value Z-score outliers with respect to the total number of residues for which RSRZ was computed. See https://www.wwpdb.org/validation/XrayValidationReportHelp
-entry_validation_atom_count int Number of atoms in the asymmetric unit of the PDB entry
-entry_validation_molprobity float | None Overall Molprobity "effective resolution", a single-score validation number based on the correlation of multiple criteria with crystallographic resolution. as described here: https://github.com/rlabduke/MolProbity/blob/6e7512e85bdea23f7ffb16e606d1f9a0abf6e5d4/cmdline/molparser.py#L662
-entry_validation_mean_b_factor float Mean B-value calculated over all modelled atoms
-entry_validation_median_b_factor float Median B-value calculated over all modelled atoms
-entry_validation_pdbx_resolution float See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_refine.ls_d_res_high.html
-entry_validation_pdbx_reflns_resolution float | None See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_reflns.d_resolution_high.html
-entry_validation_meanI_over_sigI_obs float | None Each reflection has an intensity (I) and an uncertainty in measurement (ฯ(I)), thus this metric describes the signal-to-noise ratio
-entry_validation_r_minus_rfree float The difference between r and rfree
diff --git a/src/plinder/data/column_descriptions/extra.tsv b/src/plinder/data/column_descriptions/extra.tsv
deleted file mode 100644
index 2b8f14422..000000000
--- a/src/plinder/data/column_descriptions/extra.tsv
+++ /dev/null
@@ -1,21 +0,0 @@
-Name Type Description
-uniqueness str Uniqueness identifier differentiating systems which are simple crystal symmetries in a biounit
-biounit_num_ligands int Number of ligands within systems in the biounit
-biounit_num_unique_ccd_codes int Number of unique CCD codes within systems in the biounit
-biounit_num_proper_ligands int Number of proper ligands within systems in the biounit
-system_ligand_has_lipinski bool Whether the system has a lipinski ligand
-system_ligand_has_cofactor bool Whether the system has a cofactor ligand
-system_ligand_has_fragment bool Whether the system has a fragment ligand
-system_ligand_has_oligo bool Whether the system has an oligomer ligand
-system_ligand_has_artifact bool Whether the system has an artifact ligand
-system_ligand_has_other bool Whether the system has a ligand labelled as other
-system_ligand_has_covalent bool Whether the system has a covalent ligand
-system_ligand_has_invalid bool Whether the system has an invalid ligand
-system_ligand_has_ion bool Whether the system has an ion
-system_protein_chains_total_length int Total length of all protein chains in the system
-system_unique_ccd_codes str Unique CCD codes in the system
-system_proper_unique_ccd_codes str Unique CCD codes of proper ligands in the system
-entry_pass_validation_criteria bool Whether the entry passes crystal validation criteria
-system_pass_validation_criteria bool Whether the system passes crystal validation criteria
-ligand_interactions list[str] Interactions of the ligand
-ligand_auth_id str Author chain ID of the ligand
diff --git a/src/plinder/data/column_descriptions/ligand_interacting_ligand_chains.tsv b/src/plinder/data/column_descriptions/ligand_interacting_ligand_chains.tsv
deleted file mode 100644
index 3026d9e8a..000000000
--- a/src/plinder/data/column_descriptions/ligand_interacting_ligand_chains.tsv
+++ /dev/null
@@ -1,6 +0,0 @@
-Name Type Description
-ligand_interacting_ligand_chains_asym_id list[str] Chain asymmetric id
-ligand_interacting_ligand_chains_auth_id list[str] Chain author id
-ligand_interacting_ligand_chains_entity_id list[str] Chain entity id
-ligand_interacting_ligand_chains_length list[int] SEQRES length
-ligand_interacting_ligand_chains_num_unresolved_residues list[int] Number of unresolved residues (SEQRES length - len(residues))
diff --git a/src/plinder/data/column_descriptions/ligand_interacting_ligand_chains_validation.tsv b/src/plinder/data/column_descriptions/ligand_interacting_ligand_chains_validation.tsv
deleted file mode 100644
index 8cc9e9cdf..000000000
--- a/src/plinder/data/column_descriptions/ligand_interacting_ligand_chains_validation.tsv
+++ /dev/null
@@ -1,21 +0,0 @@
-Name Type Description
-ligand_interacting_ligand_chains_validation_num_residues list[int] Number of residues in the list
-ligand_interacting_ligand_chains_validation_num_processed_residues list[int] Number of processed residues in the list
-ligand_interacting_ligand_chains_validation_percent_processed_residues list[float] Percentage of processed residues in the list
-ligand_interacting_ligand_chains_validation_average_rsr list[float] Average Real-Space R-value across all residues in the list
-ligand_interacting_ligand_chains_validation_average_rsrz list[float] Average Real-Space R-value Z-score across all residues in the list
-ligand_interacting_ligand_chains_validation_average_rscc list[float] Average Real-Space Correlation Coefficient across all residues in the list
-ligand_interacting_ligand_chains_validation_average_occupancy list[float] Average occupancy across all residues in the list
-ligand_interacting_ligand_chains_validation_percent_rsr_under_threshold list[float] Percentage of residues with RSR under the threshold
-ligand_interacting_ligand_chains_validation_percent_rscc_over_threshold list[float] Percentage of residues with RSCC over the threshold
-ligand_interacting_ligand_chains_validation_percent_occupancy_over_threshold list[float] Percentage of residues with occupancy over the threshold
-ligand_interacting_ligand_chains_validation_average_b_factor list[float] Average B factor across all residues in the list
-ligand_interacting_ligand_chains_validation_unknown_residue_count list[int] Number of unknown residues in the list
-ligand_interacting_ligand_chains_validation_atom_count list[int] Number of atoms across all residues in the list
-ligand_interacting_ligand_chains_validation_heavy_atom_count list[int] Number of heavy atoms across all residues in the list
-ligand_interacting_ligand_chains_validation_num_unresolved_heavy_atoms list[int] Number of unresolved heavy atoms across all residues in the list
-ligand_interacting_ligand_chains_validation_max_alt_count list[int] The highest number of configurations in a single residue in the list
-ligand_interacting_ligand_chains_validation_percent_outliers_chirality list[float] Percent outliers for chirality
-ligand_interacting_ligand_chains_validation_percent_outliers_clashes list[float] Percent outliers for clashes
-ligand_interacting_ligand_chains_validation_percent_outliers_density list[float] Percent outliers for density
-ligand_interacting_ligand_chains_validation_percent_outliers_geometry list[float] Percent outliers for geometry
diff --git a/src/plinder/data/column_descriptions/ligand_neighboring_ligand_chains.tsv b/src/plinder/data/column_descriptions/ligand_neighboring_ligand_chains.tsv
deleted file mode 100644
index 945f93353..000000000
--- a/src/plinder/data/column_descriptions/ligand_neighboring_ligand_chains.tsv
+++ /dev/null
@@ -1,6 +0,0 @@
-Name Type Description
-ligand_neighboring_ligand_chains_asym_id list[str] Chain asymmetric id
-ligand_neighboring_ligand_chains_auth_id list[str] Chain author id
-ligand_neighboring_ligand_chains_entity_id list[str] Chain entity id
-ligand_neighboring_ligand_chains_length list[int] SEQRES length
-ligand_neighboring_ligand_chains_num_unresolved_residues list[int] Number of unresolved residues (SEQRES length - len(residues))
diff --git a/src/plinder/data/column_descriptions/ligand_neighboring_ligand_chains_validation.tsv b/src/plinder/data/column_descriptions/ligand_neighboring_ligand_chains_validation.tsv
deleted file mode 100644
index 99e451b4e..000000000
--- a/src/plinder/data/column_descriptions/ligand_neighboring_ligand_chains_validation.tsv
+++ /dev/null
@@ -1,21 +0,0 @@
-Name Type Description
-ligand_neighboring_ligand_chains_validation_num_residues list[int] Number of residues in the list
-ligand_neighboring_ligand_chains_validation_num_processed_residues list[int] Number of processed residues in the list
-ligand_neighboring_ligand_chains_validation_percent_processed_residues list[float] Percentage of processed residues in the list
-ligand_neighboring_ligand_chains_validation_average_rsr list[float] Average Real-Space R-value across all residues in the list
-ligand_neighboring_ligand_chains_validation_average_rsrz list[float] Average Real-Space R-value Z-score across all residues in the list
-ligand_neighboring_ligand_chains_validation_average_rscc list[float] Average Real-Space Correlation Coefficient across all residues in the list
-ligand_neighboring_ligand_chains_validation_average_occupancy list[float] Average occupancy across all residues in the list
-ligand_neighboring_ligand_chains_validation_percent_rsr_under_threshold list[float] Percentage of residues with RSR under the threshold
-ligand_neighboring_ligand_chains_validation_percent_rscc_over_threshold list[float] Percentage of residues with RSCC over the threshold
-ligand_neighboring_ligand_chains_validation_percent_occupancy_over_threshold list[float] Percentage of residues with occupancy over the threshold
-ligand_neighboring_ligand_chains_validation_average_b_factor list[float] Average B factor across all residues in the list
-ligand_neighboring_ligand_chains_validation_unknown_residue_count list[int] Number of unknown residues in the list
-ligand_neighboring_ligand_chains_validation_atom_count list[int] Number of atoms across all residues in the list
-ligand_neighboring_ligand_chains_validation_heavy_atom_count list[int] Number of heavy atoms across all residues in the list
-ligand_neighboring_ligand_chains_validation_num_unresolved_heavy_atoms list[int] Number of unresolved heavy atoms across all residues in the list
-ligand_neighboring_ligand_chains_validation_max_alt_count list[int] The highest number of configurations in a single residue in the list
-ligand_neighboring_ligand_chains_validation_percent_outliers_chirality list[float] Percent outliers for chirality
-ligand_neighboring_ligand_chains_validation_percent_outliers_clashes list[float] Percent outliers for clashes
-ligand_neighboring_ligand_chains_validation_percent_outliers_density list[float] Percent outliers for density
-ligand_neighboring_ligand_chains_validation_percent_outliers_geometry list[float] Percent outliers for geometry
diff --git a/src/plinder/data/column_descriptions/ligand_protein_chains.tsv b/src/plinder/data/column_descriptions/ligand_protein_chains.tsv
deleted file mode 100644
index 12ae2fd5d..000000000
--- a/src/plinder/data/column_descriptions/ligand_protein_chains.tsv
+++ /dev/null
@@ -1,6 +0,0 @@
-Name Type Description
-ligand_protein_chains_asym_id list[str] Chain asymmetric id
-ligand_protein_chains_auth_id list[str] Chain author id
-ligand_protein_chains_entity_id list[str] Chain entity id
-ligand_protein_chains_length list[int] SEQRES length
-ligand_protein_chains_num_unresolved_residues list[int] Number of unresolved residues (SEQRES length - len(residues))
diff --git a/src/plinder/data/column_descriptions/ligand_protein_chains_validation.tsv b/src/plinder/data/column_descriptions/ligand_protein_chains_validation.tsv
deleted file mode 100644
index 48bd60121..000000000
--- a/src/plinder/data/column_descriptions/ligand_protein_chains_validation.tsv
+++ /dev/null
@@ -1,21 +0,0 @@
-Name Type Description
-ligand_protein_chains_validation_num_residues list[int] Number of residues in the list
-ligand_protein_chains_validation_num_processed_residues list[int] Number of processed residues in the list
-ligand_protein_chains_validation_percent_processed_residues list[float] Percentage of processed residues in the list
-ligand_protein_chains_validation_average_rsr list[float] Average Real-Space R-value across all residues in the list
-ligand_protein_chains_validation_average_rsrz list[float] Average Real-Space R-value Z-score across all residues in the list
-ligand_protein_chains_validation_average_rscc list[float] Average Real-Space Correlation Coefficient across all residues in the list
-ligand_protein_chains_validation_average_occupancy list[float] Average occupancy across all residues in the list
-ligand_protein_chains_validation_percent_rsr_under_threshold list[float] Percentage of residues with RSR under the threshold
-ligand_protein_chains_validation_percent_rscc_over_threshold list[float] Percentage of residues with RSCC over the threshold
-ligand_protein_chains_validation_percent_occupancy_over_threshold list[float] Percentage of residues with occupancy over the threshold
-ligand_protein_chains_validation_average_b_factor list[float] Average B factor across all residues in the list
-ligand_protein_chains_validation_unknown_residue_count list[int] Number of unknown residues in the list
-ligand_protein_chains_validation_atom_count list[int] Number of atoms across all residues in the list
-ligand_protein_chains_validation_heavy_atom_count list[int] Number of heavy atoms across all residues in the list
-ligand_protein_chains_validation_num_unresolved_heavy_atoms list[int] Number of unresolved heavy atoms across all residues in the list
-ligand_protein_chains_validation_max_alt_count list[int] The highest number of configurations in a single residue in the list
-ligand_protein_chains_validation_percent_outliers_chirality list[float] Percent outliers for chirality
-ligand_protein_chains_validation_percent_outliers_clashes list[float] Percent outliers for clashes
-ligand_protein_chains_validation_percent_outliers_density list[float] Percent outliers for density
-ligand_protein_chains_validation_percent_outliers_geometry list[float] Percent outliers for geometry
diff --git a/src/plinder/data/column_descriptions/ligands.tsv b/src/plinder/data/column_descriptions/ligands.tsv
deleted file mode 100644
index dbdc95dda..000000000
--- a/src/plinder/data/column_descriptions/ligands.tsv
+++ /dev/null
@@ -1,55 +0,0 @@
-Name Type Description
-ligand_asym_id str Ligand chain asymmetric id
-ligand_instance int Biounit instance ID
-ligand_ccd_code str Ligand Chemical Component Dictionary (CCD) code
-ligand_plip_type str PLIP ligand type
-ligand_bird_id str Ligand BIRD id
-ligand_centroid list[float] Ligand center of geometry
-ligand_smiles str Ligand SMILES based on OpenStructure dictionary lookup, or resolved SMILES if not in dictionary
-ligand_resolved_smiles str SMILES of only resolved ligand atoms
-ligand_rdkit_canonical_smiles str | None RDKit canonical SMILES (Recommended)
-ligand_molecular_weight float | None Molecular weight
-ligand_crippen_clogp float | None Ligand Crippen MlogP, see https://www.rdkit.org/docs/source/rdkit.Chem.Crippen.html
-ligand_num_rot_bonds int | None Number of rotatable bonds
-ligand_num_hbd int | None Number of hydrogen bond donors
-ligand_num_hba int | None Number of hydrogen bond acceptors
-ligand_num_rings int | None Number of rings
-ligand_num_heavy_atoms int | None Number of heavy atoms
-ligand_is_covalent bool Indicator of whether a ligand is a covalent ligand
-ligand_covalent_linkages set[str] Ligand covalent linkages as described in https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Categories/struct_conn.html with _struct_conn.conn_type_id == 'covale', reported in format {auth_resid}:{resname}{assym_id}{seq_resid}{atom_name}__{auth_resid}:{resname}{assym_id}{seq_resid}{atom_name}
-ligand_neighboring_residues dict[str, list[int]] Dictionary of neighboring residues, with {instance}.{chain} key and residue number value
-ligand_interacting_residues dict[str, list[int]] Dictionary of interacting residues, with {instance}.{chain} key and residue number value
-ligand_num_neighboring_ppi_atoms_within_4A_of_gap int | None Number of missing neighboring protein-protein interface atoms within 4 ร of ligand of interest
-ligand_num_neighboring_ppi_atoms_within_8A_of_gap int | None Number of missing neighboring protein-protein interface atoms within 8 ร of ligand of interest
-ligand_num_missing_ppi_interface_residues int | None Number of missing neighboring protein-protein interface residues within 4 ร of ligand of interest
-ligand_num_pli_atoms_within_4A_of_gap int | None Number of missing neighboring protein-ligand interface atoms within 4 ร of ligand of interest
-ligand_num_pli_atoms_within_8A_of_gap int | None Number of missing neighboring protein-ligand interface atoms within 8 ร of ligand of interest
-ligand_num_missing_pli_interface_residues int | None Number of missing neighboring protein-ligand interface residues within 4 ร of ligand of interest
-ligand_num_resolved_heavy_atoms int | None Number of resolved heavy atoms in a ligand
-ligand_num_unresolved_heavy_atoms int | None Number of unresolved heavy atoms in a ligand
-ligand_tpsa float | None Topological polar surface area
-ligand_qed float | None Ligand QED score, a measure of drug-likeness, see https://www.rdkit.org/new_docs/source/rdkit.Chem.QED.html
-ligand_is_ion bool Indicator of whether a ligand is an ion
-ligand_is_lipinski bool Indicator of whether a ligand satisfies Lipinski Ro5
-ligand_is_fragment bool Indicator of whether a ligand satisfies fragment Ro3
-ligand_is_oligo bool Indicator of whether a ligand is an oligopeptide, oligosaccharide or oligopeptide
-ligand_is_cofactor bool Indicator of whether a ligand is a cofactor
-ligand_in_artifact_list bool Indicator of whether a ligand is in the artifact list
-ligand_is_artifact bool Indicator of whether a ligand is an artifact
-ligand_is_other bool Indicator of whether a ligand type is not classified as any types of small molecule (Lipinski, Fragment or covalent), ion, cofactor, oligo (peptide, saccharide or nucleotide) or artifact
-ligand_is_invalid bool Indicator of whether a ligand is invalid
-ligand_unique_ccd_code str | None Ligand representative CCD code after de-duplicating
-ligand_protein_chains_asym_id list[str] List of RCSB asymmetric chain ids of protein residues within 6 ร of ligand of interest unless the ligand is an artifact, in which case we return an empty list.
-ligand_num_interacting_residues int Number of residues interacting with a given ligand.
-ligand_num_neighboring_residues int Residue count of each of the proteins within 6 ร of ligand of interest.
-ligand_is_proper bool Check if ligand is a proper ligand (not an ion or artifact)
-ligand_num_interactions int Number of interactions for a given ligand.
-ligand_num_unique_interactions int Number of unique interactions
-ligand_num_crystal_contacted_residues int Number of residues from other symmetry mates which are in contact with this ligand.
-ligand_num_atoms_with_crystal_contacts int Number of atoms in this ligand which are in contact with residues from other symmetry mates.
-ligand_fraction_atoms_with_crystal_contacts float | None Fraction of atoms in this ligand which are in contact with residues from other symmetry mates.
-ligand_num_pocket_residues int Number of residues in the ligand's binding pocket.
-ligand_id str Unique identifier for a given ligand.
-ligand_instance_chain str Instance chain for a given ligand.
-ligand_is_kinase_inhibitor bool Check if ligand is a kinase inhibitor.
-ligand_binding_affinity float | None Binding affinity (pKd or pKi) from BindingDB when available.
diff --git a/src/plinder/data/column_descriptions/posebusters_checks.tsv b/src/plinder/data/column_descriptions/posebusters_checks.tsv
deleted file mode 100644
index b0b4848c4..000000000
--- a/src/plinder/data/column_descriptions/posebusters_checks.tsv
+++ /dev/null
@@ -1,124 +0,0 @@
-Name Type Description
-ligand_posebusters_all_atoms_connected bool True if all atoms form one single connected graph.
-ligand_posebusters_aromatic_ring_flatness bool True if all atoms in aromatic rings with 5 or 6 members are within 0.25 ร of the closest shared plane.
-ligand_posebusters_aromatic_ring_maximum_distance_from_plane float Maximum distance of any atom from the plane. It's a measure of planarity, the closer to zero the better.
-ligand_posebusters_bond_angles bool True if the angles in the input molecule are within 0.75 of the lower and 1.25 of the upper bounds determined by distance geometry.
-ligand_posebusters_bond_lengths bool True if the bond lengths in the input molecule are within 0.75 of the lower and 1.25 of the upper bounds determined by distance geometry.
-ligand_posebusters_double_bond_flatness bool True if both atoms in a double bond are within 0.25 ร of the double bond plane.
-ligand_posebusters_double_bond_maximum_distance_from_plane float The maximum distance of either of the atoms in a double bond to the plane of the double bond.
-ligand_posebusters_double_bond_stereochemistry bool The specifed double bond stereochemistry in the input molecule is the same as in the true molecule.
-ligand_posebusters_energy_ratio float The ratio of calculated energy of the input molecule to the average energy of an ensemble of 50 conformations generated for the input molecule. The energy is calculated using the UFF32 in RDKit and the conformations are generated with ETKDGv3 followed by force field relaxation using the UFF with up to 200 iterations.
-ligand_posebusters_ensemble_avg_energy float The average energy of an ensemble of 50 conformations generated for the input molecule. The energy is calculated using the UFF32 in RDKit and the conformations are generated with ETKDGv3 followed by force field relaxation using the UFF with up to 200 iterations.
-ligand_posebusters_hydrogens bool Boolean indicator of whether the ligand has added hydrogens.
-ligand_posebusters_inchi_crystal str The Inchi of reference crystal ligand.
-ligand_posebusters_inchi_crystal_valid bool Boolean indicator of whether the Inchi of the crystal ligand is valid.
-ligand_posebusters_inchi_docked str The Inchi of reference docked ligand.
-ligand_posebusters_inchi_docked_valid bool Boolean indicator of whether the Inchi of the docked ligand is valid.
-ligand_posebusters_inchi_overall bool Boolean operator to show if overall Inchi of crystal and docked ligand are the same.
-ligand_posebusters_inchi_version bool The Inchi version.
-ligand_posebusters_internal_energy float Internal energy of docked ligand.
-ligand_posebusters_internal_steric_clash bool The interatomic distance between pairs of non-covalently bound atoms is above 0.7 of the lower bound determined by distance geometry.
-ligand_posebusters_kabsch_rmsd float Closest RSMD between docked and crystal ligand that takes isomers into consideration.
-ligand_posebusters_longest_bond_relative_length float Maximum ratio between length of a given bond and upper limit of bond distance.
-ligand_posebusters_minimum_distance_to_inorganic_cofactors bool Minimum intermolecular distance of docked ligand atoms to atoms of inorganic cofactor.
-ligand_posebusters_minimum_distance_to_organic_cofactors bool Minimum intermolecular distance of docked ligand atoms to atoms of organic cofactor.
-ligand_posebusters_minimum_distance_to_protein bool Minimum intermolecular distance of docked ligand atoms to receptor protein atoms.
-ligand_posebusters_minimum_distance_to_waters bool Minimum intermolecular distance of docked ligand atoms to water atoms.
-ligand_posebusters_mol_cond_loaded bool Boolean indicator of whether the conditioning molecule loaded correctly.
-ligand_posebusters_mol_pred_energy float Internal energy of predicted molecule.
-ligand_posebusters_mol_pred_loaded bool Boolean indicator of whether the predicted molecule loaded correctly.
-ligand_posebusters_mol_true_loaded bool Boolean indicator of whether the ground truth molecule loaded correctly.
-ligand_posebusters_molecular_bonds bool Boolean indicator of whether the bonds in the input molecule are the same as in the true molecule.
-ligand_posebusters_molecular_formula bool Boolean indicator of whether the molecular formula of the input molecule is the same as that of the true molecule.
-ligand_posebusters_most_extreme_clash_inorganic_cofactors bool Indicator of whether the most extreme clash involves inorganic cofactor.
-ligand_posebusters_most_extreme_clash_organic_cofactors bool Indicator of whether the most extreme clash involves organic cofactor.
-ligand_posebusters_most_extreme_clash_protein bool Indicator of whether the most extreme clash involves receptor protein.
-ligand_posebusters_most_extreme_clash_waters bool Indicator of whether the most extreme clash involves binding site water.
-ligand_posebusters_most_extreme_distance_inorganic_cofactors float The most extreme distance between atoms of predicted ligand and inorganic cofactor.
-ligand_posebusters_most_extreme_distance_organic_cofactors float The most extreme distance between atoms of predicted ligand and organic cofactor.
-ligand_posebusters_most_extreme_distance_protein float The most extreme distance between atoms of predicted ligand and protein.
-ligand_posebusters_most_extreme_distance_waters float The most extreme distance between atoms of predicted ligand and binding site water.
-ligand_posebusters_most_extreme_ligand_atom_id_inorganic_cofactors int Atom ID of the most extremely clashing ligand atom with an inorganic cofactor.
-ligand_posebusters_most_extreme_ligand_atom_id_organic_cofactors int Atom ID of the most extremely clashing ligand atom with an organic cofactor.
-ligand_posebusters_most_extreme_ligand_atom_id_protein int Atom ID of the most extremely clashing ligand atom with receptor protein.
-ligand_posebusters_most_extreme_ligand_atom_id_waters int Atom ID of the most extremely clashing ligand atom with binding site water.
-ligand_posebusters_most_extreme_ligand_element_inorganic_cofactors str Element symbol of the most extremely clashing ligand atom with an inorganic cofactor.
-ligand_posebusters_most_extreme_ligand_element_organic_cofactors str Element symbol of the most extremely clashing ligand atom with an organic cofactor.
-ligand_posebusters_most_extreme_ligand_element_protein str Element symbol of the most extremely clashing ligand atom with receptor protein.
-ligand_posebusters_most_extreme_ligand_element_waters str Element symbol of the most extremely clashing ligand atom with binding site water.
-ligand_posebusters_most_extreme_ligand_vdw_inorganic_cofactors float van der Waals radius of the most extremely clashing ligand atom with an inorganic cofactor.
-ligand_posebusters_most_extreme_ligand_vdw_organic_cofactors float van der Waals radius of the most extremely clashing ligand atom with an organic cofactor.
-ligand_posebusters_most_extreme_ligand_vdw_protein float van der Waals radius of the most extremely clashing ligand atom with receptor protein.
-ligand_posebusters_most_extreme_ligand_vdw_waters float van der Waals radius of the most extremely clashing ligand atom with binding site water.
-ligand_posebusters_most_extreme_protein_atom_id_inorganic_cofactors int Atom ID of the most extremely clashing inorganic cofactors atom with predicted ligand.
-ligand_posebusters_most_extreme_protein_atom_id_organic_cofactors int Atom ID of the most extremely clashing organic cofactors atom with predicted ligand.
-ligand_posebusters_most_extreme_protein_atom_id_protein int Atom ID of the most extremely clashing receptor protein atom with predicted ligand.
-ligand_posebusters_most_extreme_protein_atom_id_waters int Atom ID of the most extremely clashing binding site water atom with predicted ligand.
-ligand_posebusters_most_extreme_protein_element_inorganic_cofactors str Element symbol of the most extremely clashing inorganic cofactors atom with predicted ligand.
-ligand_posebusters_most_extreme_protein_element_organic_cofactors str Element symbol of the most extremely clashing organic cofactors atom with predicted ligand.
-ligand_posebusters_most_extreme_protein_element_protein str Element symbol of the most extremely clashing receptor protein atom with predicted ligand.
-ligand_posebusters_most_extreme_protein_element_waters str Element symbol of the most extremely clashing binding site water atom with predicted ligand.
-ligand_posebusters_most_extreme_protein_vdw_inorganic_cofactors float van der Waals radius of the most extremely clashing inorganic cofactors atom with predicted ligand.
-ligand_posebusters_most_extreme_protein_vdw_organic_cofactors float van der Waals radius of the most extremely clashing organic cofactors atom with predicted ligand.
-ligand_posebusters_most_extreme_protein_vdw_protein float van der Waals radius of the most extremely clashing receptor protein atom with predicted ligand.
-ligand_posebusters_most_extreme_protein_vdw_waters float van der Waals radius of the most extremely clashing binding site water atom with predicted ligand.
-ligand_posebusters_most_extreme_relative_angle float See https://github.com/maabuu/posebusters/blob/6062b9981cbc8843b93c3c889779f6fde5f94f02/posebusters/modules/distance_geometry.py#L39
-ligand_posebusters_most_extreme_relative_distance_inorganic_cofactors float The smallest ratio of the distance between ligand and inorganic cofactor atoms to the sum of the pairs covalent radii.
-ligand_posebusters_most_extreme_relative_distance_organic_cofactors float The smallest ratio of the distance between ligand and organic cofactor atoms to the sum of the pairs van der Waals radii.
-ligand_posebusters_most_extreme_relative_distance_protein float The smallest ratio of the distance between proteinโligand atom pairs to the sum of the pairs van der Waals radii.
-ligand_posebusters_most_extreme_relative_distance_waters float The smallest ratio of the distance between ligand and binding site water atoms to the sum of the pairs van der Waals radii.
-ligand_posebusters_most_extreme_sum_radii_inorganic_cofactors float The sum of covalent radii of the closest ligand-inorganic cofactor atom pairs.
-ligand_posebusters_most_extreme_sum_radii_organic_cofactors float The sum of van der Waals radii of the closest ligand-organic cofactor atom pairs.
-ligand_posebusters_most_extreme_sum_radii_protein float The sum of van der Waals radii of the closest protein-ligand atom pairs.
-ligand_posebusters_most_extreme_sum_radii_scaled_inorganic_cofactors float The sum of van der Waals radii of the closest ligand and inorganic cofactors scaled by 0.5.
-ligand_posebusters_most_extreme_sum_radii_scaled_organic_cofactors float The sum of van der Waals radii of the closest ligand and organic cofactors scaled by 0.8.
-ligand_posebusters_most_extreme_sum_radii_scaled_protein float The sum of van der Waals radii of the closest ligand and protein scaled by 0.8.
-ligand_posebusters_most_extreme_sum_radii_scaled_waters float The sum of van der Waals radii of the closest ligand and binding site water scaled by 0.8.
-ligand_posebusters_most_extreme_sum_radii_waters float The sum of van der Waals radii of the closest ligand and binding site water.
-ligand_posebusters_net_charge bool Ligand net charge.
-ligand_posebusters_not_too_far_away_inorganic_cofactors bool Boolean indicator of whether ligand is too far away from inorganic cofactor.
-ligand_posebusters_not_too_far_away_organic_cofactors bool Boolean indicator of whether ligand is too far away from organic cofactor.
-ligand_posebusters_not_too_far_away_waters bool Boolean indicator of whether ligand is too far away from binding site water.
-ligand_posebusters_num_pairwise_clashes_inorganic_cofactors int Number of pairwise clashes between ligand and inorganic cofactor.
-ligand_posebusters_num_pairwise_clashes_organic_cofactors int Number of pairwise clashes between ligand and organic cofactor.
-ligand_posebusters_num_pairwise_clashes_protein int Number of pairwise clashes between ligand and receptor protein.
-ligand_posebusters_num_pairwise_clashes_waters int Number of pairwise clashes between ligand and binding site water.
-ligand_posebusters_number_angles int Number of angles checked.
-ligand_posebusters_number_aromatic_rings_checked int Number of aromatic rings checked.
-ligand_posebusters_number_aromatic_rings_pass int Number of aromatic ring that passes sanity checks.
-ligand_posebusters_number_bonds int Number of bonds in ligand.
-ligand_posebusters_number_clashes int Number of clashes in ligand.
-ligand_posebusters_number_double_bonds_checked int Number of double bonds checked.
-ligand_posebusters_number_double_bonds_pass int Number of double bonds that passes sanity check.
-ligand_posebusters_number_long_outlier_bonds int Number of long outlier bonds in predicted ligand.
-ligand_posebusters_number_noncov_pairs int Number of non-covalent pairs of atoms in predicted ligand.
-ligand_posebusters_number_outlier_angles int Number of outlier angles in predicted ligand.
-ligand_posebusters_number_short_outlier_bonds int Number of short outlier bonds.
-ligand_posebusters_number_valid_angles int Number of valid angles in predicted ligand.
-ligand_posebusters_number_valid_bonds int Number of valid bonds in predicted ligand.
-ligand_posebusters_number_valid_noncov_pairs int Number of valid non-covalent atom pairs.
-ligand_posebusters_passes_kekulization bool Boolean indicatoe of whether a ligand passes RDKit kekulization checks.
-ligand_posebusters_passes_valence_checks bool Boolean indicator of whether a ligand passes valence checks.
-ligand_posebusters_protein-ligand_maximum_distance bool The maximum interatomic distance between predicted ligand and receptor protein.
-ligand_posebusters_protons bool Boolean indicator of whether ligand has protons.
-ligand_posebusters_rmsd_โค_2รฅ bool Boolean indicator of whether the predicted ligand is within 2รฅ from the ground truth ligand.
-ligand_posebusters_sanitization bool Boolean indicator of whether predicted ligand passes RDKit sanitization.
-ligand_posebusters_shortest_bond_relative_length float The shortest bond length scaled by the lower bound of interatomic distance.
-ligand_posebusters_shortest_noncovalent_relative_distance float The shortest non-covalent interatomic distance divided by the sum of van der Waals radii of the two atoms.
-ligand_posebusters_smallest_distance_inorganic_cofactors float The smallest distance between ligand atoms and inorganic cofactor atoms.
-ligand_posebusters_smallest_distance_organic_cofactors float The smallest distance between ligand atoms and organic cofactor atoms.
-ligand_posebusters_smallest_distance_protein float The smallest distance between ligand atoms and receptor protein atoms.
-ligand_posebusters_smallest_distance_waters float The smallest distance between ligand atoms and bind site water atoms.
-ligand_posebusters_stereo_sp3 bool Boolean indicator of whether the sp3 stereo-centers in the input molecule are the same as in the true molecule.
-ligand_posebusters_stereo_sp3_inverted bool Boolean indicator of whether the inverted sp3 stereo-centers in the input molecule are the same as in the true molecule.
-ligand_posebusters_stereo_type bool Boolean indicator of whether the stereocenter type in the input molecule is the same as in the true molecule.
-ligand_posebusters_stereochemistry_preserved bool Boolean indicator of whether the specified stereochemistry in the input molecule is the same as in the true molecule.
-ligand_posebusters_tetrahedral_chirality bool Boolean indicator of whether the specified tetrahedral chirality in the input molecule is the same as in the true molecule.
-ligand_posebusters_volume_overlap_inorganic_cofactors float The share of ligand volume that intersects with inorganic cofactors. The volumes are defined by the van der Waals radii around the heavy atoms scaled by 0.5.
-ligand_posebusters_volume_overlap_organic_cofactors float The share of ligand volume that intersects with organic cofactors. The volumes are defined by the van der Waals radii around the heavy atoms scaled by 0.8.
-ligand_posebusters_volume_overlap_protein float The share of ligand volume that intersects with protein. The volumes are defined by the van der Waals radii around the heavy atoms scaled by 0.8.
-ligand_posebusters_volume_overlap_waters float The share of ligand volume that intersects with binding site water. The volumes are defined by the van der Waals radii around the heavy atoms scaled by 0.8.
-ligand_posebusters_volume_overlap_with_inorganic_cofactors bool Boolean indicator of whether the share of ligand volume that intersects with the inorganic cofactor is less than 7.5%. The volumes are defined by the van der Waals radii around the heavy atoms scaled by 0.5.
-ligand_posebusters_volume_overlap_with_organic_cofactors bool Boolean indicator of whether the share of ligand volume that intersects with the organic cofactor is less than 7.5%. The volumes are defined by the van der Waals radii around the heavy atoms scaled by 0.8.
-ligand_posebusters_volume_overlap_with_protein bool Boolean indicator of whether the share of ligand volume that intersects with the protein is less than 7.5%. The volumes are defined by the van der Waals radii around the heavy atoms scaled by 0.5.
-ligand_posebusters_volume_overlap_with_waters bool Boolean indicator of whether the share of ligand volume that intersects with the binding site water is less than 7.5%. The volumes are defined by the van der Waals radii around the heavy atoms scaled by 0.5.
diff --git a/src/plinder/data/column_descriptions/qc.tsv b/src/plinder/data/column_descriptions/qc.tsv
deleted file mode 100644
index 0737cf90e..000000000
--- a/src/plinder/data/column_descriptions/qc.tsv
+++ /dev/null
@@ -1,14 +0,0 @@
-Name Type Description
-all_ligand_chains_present bool all the ligand chains detected for the system are present in the system CIF, PDB and SDF files
-all_protein_chains_present bool all the protein chains detected for the system are present in the system CIF, PDB and SDF files
-complex_loadbable_via_biotite bool the complex can successfully be loaded with the biotite library
-ligand_is_obabel_loadable bool the ligand can successfully be loaded with the OpenBabel library
-ligand_is_obabel_loadable_with_rdkit_fix bool the ligand can successfully be loaded with the OpenBabel library after fixing valence and chirality issues
-ligand_is_rdkit_loadable bool the ligand can successfully be loaded with the RDKit library
-ligand_is_rdkit_loadable_with_fix bool the ligand can successfully be loaded with the RDKit library after fixing valence and chirality issues
-ligand_loadbable_via_biotite bool the ligand can successfully be loaded with the biotite library
-ligand_matches_smiles_atom_num bool the number of atoms in the saved ligand matches the expected number from the resolved SMILES
-ligand_positions_correct bool the positions of the saved ligand atoms match the expected positions from the PDB entry
-ligand_protein_neighbor_still_preserved_complex bool the neighboring protein chains of the saved complex match what was annotated from the PDB entry
-ligand_rdkit_validation list[str] list of RDKit fixes performed
-ligand_molvs_validation float [DESCRIPTION]
diff --git a/src/plinder/data/column_descriptions/similarity_clusters.tsv b/src/plinder/data/column_descriptions/similarity_clusters.tsv
deleted file mode 100644
index 07646f71e..000000000
--- a/src/plinder/data/column_descriptions/similarity_clusters.tsv
+++ /dev/null
@@ -1,310 +0,0 @@
-Name Type Description
-pli_qcov__50__weak__component str Cluster ID for weak component built from pli_qcov metric with 50 threshold
-pli_qcov__70__weak__component str Cluster ID for weak component built from pli_qcov metric with 70 threshold
-pli_qcov__95__weak__component str Cluster ID for weak component built from pli_qcov metric with 95 threshold
-pli_qcov__100__weak__component str Cluster ID for weak component built from pli_qcov metric with 100 threshold
-pli_qcov__50__strong__component str Cluster ID for strong component built from pli_qcov metric with 50 threshold
-pli_qcov__70__strong__component str Cluster ID for strong component built from pli_qcov metric with 70 threshold
-pli_qcov__95__strong__component str Cluster ID for strong component built from pli_qcov metric with 95 threshold
-pli_qcov__100__strong__component str Cluster ID for strong component built from pli_qcov metric with 100 threshold
-pli_unique_qcov__0__weak__component str Cluster ID for weak component built from pli_unique_qcov metric with 0 threshold
-pli_unique_qcov__50__weak__component str Cluster ID for weak component built from pli_unique_qcov metric with 50 threshold
-pli_unique_qcov__70__weak__component str Cluster ID for weak component built from pli_unique_qcov metric with 70 threshold
-pli_unique_qcov__95__weak__component str Cluster ID for weak component built from pli_unique_qcov metric with 95 threshold
-pli_unique_qcov__100__weak__component str Cluster ID for weak component built from pli_unique_qcov metric with 100 threshold
-pli_unique_qcov__0__strong__component str Cluster ID for strong component built from pli_unique_qcov metric with 0 threshold
-pli_unique_qcov__50__strong__component str Cluster ID for strong component built from pli_unique_qcov metric with 50 threshold
-pli_unique_qcov__70__strong__component str Cluster ID for strong component built from pli_unique_qcov metric with 70 threshold
-pli_unique_qcov__95__strong__component str Cluster ID for strong component built from pli_unique_qcov metric with 95 threshold
-pli_unique_qcov__100__strong__component str Cluster ID for strong component built from pli_unique_qcov metric with 100 threshold
-pocket_fident__50__weak__component str Cluster ID for weak component built from pocket_fident metric with 50 threshold
-pocket_fident__70__weak__component str Cluster ID for weak component built from pocket_fident metric with 70 threshold
-pocket_fident__95__weak__component str Cluster ID for weak component built from pocket_fident metric with 95 threshold
-pocket_fident__100__weak__component str Cluster ID for weak component built from pocket_fident metric with 100 threshold
-pocket_fident__50__strong__component str Cluster ID for strong component built from pocket_fident metric with 50 threshold
-pocket_fident__70__strong__component str Cluster ID for strong component built from pocket_fident metric with 70 threshold
-pocket_fident__95__strong__component str Cluster ID for strong component built from pocket_fident metric with 95 threshold
-pocket_fident__100__strong__component str Cluster ID for strong component built from pocket_fident metric with 100 threshold
-pocket_fident_qcov__50__weak__component str Cluster ID for weak component built from pocket_fident_qcov metric with 50 threshold
-pocket_fident_qcov__70__weak__component str Cluster ID for weak component built from pocket_fident_qcov metric with 70 threshold
-pocket_fident_qcov__95__weak__component str Cluster ID for weak component built from pocket_fident_qcov metric with 95 threshold
-pocket_fident_qcov__100__weak__component str Cluster ID for weak component built from pocket_fident_qcov metric with 100 threshold
-pocket_fident_qcov__50__strong__component str Cluster ID for strong component built from pocket_fident_qcov metric with 50 threshold
-pocket_fident_qcov__70__strong__component str Cluster ID for strong component built from pocket_fident_qcov metric with 70 threshold
-pocket_fident_qcov__95__strong__component str Cluster ID for strong component built from pocket_fident_qcov metric with 95 threshold
-pocket_fident_qcov__100__strong__component str Cluster ID for strong component built from pocket_fident_qcov metric with 100 threshold
-pocket_lddt__50__weak__component str Cluster ID for weak component built from pocket_lddt metric with 50 threshold
-pocket_lddt__70__weak__component str Cluster ID for weak component built from pocket_lddt metric with 70 threshold
-pocket_lddt__95__weak__component str Cluster ID for weak component built from pocket_lddt metric with 95 threshold
-pocket_lddt__100__weak__component str Cluster ID for weak component built from pocket_lddt metric with 100 threshold
-pocket_lddt__50__strong__component str Cluster ID for strong component built from pocket_lddt metric with 50 threshold
-pocket_lddt__70__strong__component str Cluster ID for strong component built from pocket_lddt metric with 70 threshold
-pocket_lddt__95__strong__component str Cluster ID for strong component built from pocket_lddt metric with 95 threshold
-pocket_lddt__100__strong__component str Cluster ID for strong component built from pocket_lddt metric with 100 threshold
-pocket_lddt_qcov__50__weak__component str Cluster ID for weak component built from pocket_lddt_qcov metric with 50 threshold
-pocket_lddt_qcov__70__weak__component str Cluster ID for weak component built from pocket_lddt_qcov metric with 70 threshold
-pocket_lddt_qcov__95__weak__component str Cluster ID for weak component built from pocket_lddt_qcov metric with 95 threshold
-pocket_lddt_qcov__100__weak__component str Cluster ID for weak component built from pocket_lddt_qcov metric with 100 threshold
-pocket_lddt_qcov__50__strong__component str Cluster ID for strong component built from pocket_lddt_qcov metric with 50 threshold
-pocket_lddt_qcov__70__strong__component str Cluster ID for strong component built from pocket_lddt_qcov metric with 70 threshold
-pocket_lddt_qcov__95__strong__component str Cluster ID for strong component built from pocket_lddt_qcov metric with 95 threshold
-pocket_lddt_qcov__100__strong__component str Cluster ID for strong component built from pocket_lddt_qcov metric with 100 threshold
-pocket_qcov__50__weak__component str Cluster ID for weak component built from pocket_qcov metric with 50 threshold
-pocket_qcov__70__weak__component str Cluster ID for weak component built from pocket_qcov metric with 70 threshold
-pocket_qcov__95__weak__component str Cluster ID for weak component built from pocket_qcov metric with 95 threshold
-pocket_qcov__100__weak__component str Cluster ID for weak component built from pocket_qcov metric with 100 threshold
-pocket_qcov__50__strong__component str Cluster ID for strong component built from pocket_qcov metric with 50 threshold
-pocket_qcov__70__strong__component str Cluster ID for strong component built from pocket_qcov metric with 70 threshold
-pocket_qcov__95__strong__component str Cluster ID for strong component built from pocket_qcov metric with 95 threshold
-pocket_qcov__100__strong__component str Cluster ID for strong component built from pocket_qcov metric with 100 threshold
-protein_fident_max__50__weak__component str Cluster ID for weak component built from protein_fident_max metric with 50 threshold
-protein_fident_max__70__weak__component str Cluster ID for weak component built from protein_fident_max metric with 70 threshold
-protein_fident_max__95__weak__component str Cluster ID for weak component built from protein_fident_max metric with 95 threshold
-protein_fident_max__100__weak__component str Cluster ID for weak component built from protein_fident_max metric with 100 threshold
-protein_fident_max__50__strong__component str Cluster ID for strong component built from protein_fident_max metric with 50 threshold
-protein_fident_max__70__strong__component str Cluster ID for strong component built from protein_fident_max metric with 70 threshold
-protein_fident_max__95__strong__component str Cluster ID for strong component built from protein_fident_max metric with 95 threshold
-protein_fident_max__100__strong__component str Cluster ID for strong component built from protein_fident_max metric with 100 threshold
-protein_fident_qcov_max__50__weak__component str Cluster ID for weak component built from protein_fident_qcov_max metric with 50 threshold
-protein_fident_qcov_max__70__weak__component str Cluster ID for weak component built from protein_fident_qcov_max metric with 70 threshold
-protein_fident_qcov_max__95__weak__component str Cluster ID for weak component built from protein_fident_qcov_max metric with 95 threshold
-protein_fident_qcov_max__100__weak__component str Cluster ID for weak component built from protein_fident_qcov_max metric with 100 threshold
-protein_fident_qcov_max__50__strong__component str Cluster ID for strong component built from protein_fident_qcov_max metric with 50 threshold
-protein_fident_qcov_max__70__strong__component str Cluster ID for strong component built from protein_fident_qcov_max metric with 70 threshold
-protein_fident_qcov_max__95__strong__component str Cluster ID for strong component built from protein_fident_qcov_max metric with 95 threshold
-protein_fident_qcov_max__100__strong__component str Cluster ID for strong component built from protein_fident_qcov_max metric with 100 threshold
-protein_fident_qcov_weighted_max__50__weak__component str Cluster ID for weak component built from protein_fident_qcov_weighted_max metric with 50 threshold
-protein_fident_qcov_weighted_max__70__weak__component str Cluster ID for weak component built from protein_fident_qcov_weighted_max metric with 70 threshold
-protein_fident_qcov_weighted_max__95__weak__component str Cluster ID for weak component built from protein_fident_qcov_weighted_max metric with 95 threshold
-protein_fident_qcov_weighted_max__100__weak__component str Cluster ID for weak component built from protein_fident_qcov_weighted_max metric with 100 threshold
-protein_fident_qcov_weighted_max__50__strong__component str Cluster ID for strong component built from protein_fident_qcov_weighted_max metric with 50 threshold
-protein_fident_qcov_weighted_max__70__strong__component str Cluster ID for strong component built from protein_fident_qcov_weighted_max metric with 70 threshold
-protein_fident_qcov_weighted_max__95__strong__component str Cluster ID for strong component built from protein_fident_qcov_weighted_max metric with 95 threshold
-protein_fident_qcov_weighted_max__100__strong__component str Cluster ID for strong component built from protein_fident_qcov_weighted_max metric with 100 threshold
-protein_fident_qcov_weighted_sum__50__weak__component str Cluster ID for weak component built from protein_fident_qcov_weighted_sum metric with 50 threshold
-protein_fident_qcov_weighted_sum__70__weak__component str Cluster ID for weak component built from protein_fident_qcov_weighted_sum metric with 70 threshold
-protein_fident_qcov_weighted_sum__95__weak__component str Cluster ID for weak component built from protein_fident_qcov_weighted_sum metric with 95 threshold
-protein_fident_qcov_weighted_sum__100__weak__component str Cluster ID for weak component built from protein_fident_qcov_weighted_sum metric with 100 threshold
-protein_fident_qcov_weighted_sum__50__strong__component str Cluster ID for strong component built from protein_fident_qcov_weighted_sum metric with 50 threshold
-protein_fident_qcov_weighted_sum__70__strong__component str Cluster ID for strong component built from protein_fident_qcov_weighted_sum metric with 70 threshold
-protein_fident_qcov_weighted_sum__95__strong__component str Cluster ID for strong component built from protein_fident_qcov_weighted_sum metric with 95 threshold
-protein_fident_qcov_weighted_sum__100__strong__component str Cluster ID for strong component built from protein_fident_qcov_weighted_sum metric with 100 threshold
-protein_fident_weighted_max__50__weak__component str Cluster ID for weak component built from protein_fident_weighted_max metric with 50 threshold
-protein_fident_weighted_max__70__weak__component str Cluster ID for weak component built from protein_fident_weighted_max metric with 70 threshold
-protein_fident_weighted_max__95__weak__component str Cluster ID for weak component built from protein_fident_weighted_max metric with 95 threshold
-protein_fident_weighted_max__100__weak__component str Cluster ID for weak component built from protein_fident_weighted_max metric with 100 threshold
-protein_fident_weighted_max__50__strong__component str Cluster ID for strong component built from protein_fident_weighted_max metric with 50 threshold
-protein_fident_weighted_max__70__strong__component str Cluster ID for strong component built from protein_fident_weighted_max metric with 70 threshold
-protein_fident_weighted_max__95__strong__component str Cluster ID for strong component built from protein_fident_weighted_max metric with 95 threshold
-protein_fident_weighted_max__100__strong__component str Cluster ID for strong component built from protein_fident_weighted_max metric with 100 threshold
-protein_fident_weighted_sum__50__weak__component str Cluster ID for weak component built from protein_fident_weighted_sum metric with 50 threshold
-protein_fident_weighted_sum__70__weak__component str Cluster ID for weak component built from protein_fident_weighted_sum metric with 70 threshold
-protein_fident_weighted_sum__95__weak__component str Cluster ID for weak component built from protein_fident_weighted_sum metric with 95 threshold
-protein_fident_weighted_sum__100__weak__component str Cluster ID for weak component built from protein_fident_weighted_sum metric with 100 threshold
-protein_fident_weighted_sum__50__strong__component str Cluster ID for strong component built from protein_fident_weighted_sum metric with 50 threshold
-protein_fident_weighted_sum__70__strong__component str Cluster ID for strong component built from protein_fident_weighted_sum metric with 70 threshold
-protein_fident_weighted_sum__95__strong__component str Cluster ID for strong component built from protein_fident_weighted_sum metric with 95 threshold
-protein_fident_weighted_sum__100__strong__component str Cluster ID for strong component built from protein_fident_weighted_sum metric with 100 threshold
-protein_lddt_max__70__weak__component str Cluster ID for weak component built from protein_lddt_max metric with 70 threshold
-protein_lddt_max__95__weak__component str Cluster ID for weak component built from protein_lddt_max metric with 95 threshold
-protein_lddt_max__100__weak__component str Cluster ID for weak component built from protein_lddt_max metric with 100 threshold
-protein_lddt_max__70__strong__component str Cluster ID for strong component built from protein_lddt_max metric with 70 threshold
-protein_lddt_max__95__strong__component str Cluster ID for strong component built from protein_lddt_max metric with 95 threshold
-protein_lddt_max__100__strong__component str Cluster ID for strong component built from protein_lddt_max metric with 100 threshold
-protein_lddt_qcov_max__50__weak__component str Cluster ID for weak component built from protein_lddt_qcov_max metric with 50 threshold
-protein_lddt_qcov_max__70__weak__component str Cluster ID for weak component built from protein_lddt_qcov_max metric with 70 threshold
-protein_lddt_qcov_max__95__weak__component str Cluster ID for weak component built from protein_lddt_qcov_max metric with 95 threshold
-protein_lddt_qcov_max__100__weak__component str Cluster ID for weak component built from protein_lddt_qcov_max metric with 100 threshold
-protein_lddt_qcov_max__50__strong__component str Cluster ID for strong component built from protein_lddt_qcov_max metric with 50 threshold
-protein_lddt_qcov_max__70__strong__component str Cluster ID for strong component built from protein_lddt_qcov_max metric with 70 threshold
-protein_lddt_qcov_max__95__strong__component str Cluster ID for strong component built from protein_lddt_qcov_max metric with 95 threshold
-protein_lddt_qcov_max__100__strong__component str Cluster ID for strong component built from protein_lddt_qcov_max metric with 100 threshold
-protein_lddt_qcov_weighted_max__50__weak__component str Cluster ID for weak component built from protein_lddt_qcov_weighted_max metric with 50 threshold
-protein_lddt_qcov_weighted_max__70__weak__component str Cluster ID for weak component built from protein_lddt_qcov_weighted_max metric with 70 threshold
-protein_lddt_qcov_weighted_max__95__weak__component str Cluster ID for weak component built from protein_lddt_qcov_weighted_max metric with 95 threshold
-protein_lddt_qcov_weighted_max__100__weak__component str Cluster ID for weak component built from protein_lddt_qcov_weighted_max metric with 100 threshold
-protein_lddt_qcov_weighted_max__50__strong__component str Cluster ID for strong component built from protein_lddt_qcov_weighted_max metric with 50 threshold
-protein_lddt_qcov_weighted_max__70__strong__component str Cluster ID for strong component built from protein_lddt_qcov_weighted_max metric with 70 threshold
-protein_lddt_qcov_weighted_max__95__strong__component str Cluster ID for strong component built from protein_lddt_qcov_weighted_max metric with 95 threshold
-protein_lddt_qcov_weighted_max__100__strong__component str Cluster ID for strong component built from protein_lddt_qcov_weighted_max metric with 100 threshold
-protein_lddt_qcov_weighted_sum__50__weak__component str Cluster ID for weak component built from protein_lddt_qcov_weighted_sum metric with 50 threshold
-protein_lddt_qcov_weighted_sum__70__weak__component str Cluster ID for weak component built from protein_lddt_qcov_weighted_sum metric with 70 threshold
-protein_lddt_qcov_weighted_sum__95__weak__component str Cluster ID for weak component built from protein_lddt_qcov_weighted_sum metric with 95 threshold
-protein_lddt_qcov_weighted_sum__100__weak__component str Cluster ID for weak component built from protein_lddt_qcov_weighted_sum metric with 100 threshold
-protein_lddt_qcov_weighted_sum__50__strong__component str Cluster ID for strong component built from protein_lddt_qcov_weighted_sum metric with 50 threshold
-protein_lddt_qcov_weighted_sum__70__strong__component str Cluster ID for strong component built from protein_lddt_qcov_weighted_sum metric with 70 threshold
-protein_lddt_qcov_weighted_sum__95__strong__component str Cluster ID for strong component built from protein_lddt_qcov_weighted_sum metric with 95 threshold
-protein_lddt_qcov_weighted_sum__100__strong__component str Cluster ID for strong component built from protein_lddt_qcov_weighted_sum metric with 100 threshold
-protein_lddt_weighted_max__70__weak__component str Cluster ID for weak component built from protein_lddt_weighted_max metric with 70 threshold
-protein_lddt_weighted_max__95__weak__component str Cluster ID for weak component built from protein_lddt_weighted_max metric with 95 threshold
-protein_lddt_weighted_max__100__weak__component str Cluster ID for weak component built from protein_lddt_weighted_max metric with 100 threshold
-protein_lddt_weighted_max__70__strong__component str Cluster ID for strong component built from protein_lddt_weighted_max metric with 70 threshold
-protein_lddt_weighted_max__95__strong__component str Cluster ID for strong component built from protein_lddt_weighted_max metric with 95 threshold
-protein_lddt_weighted_max__100__strong__component str Cluster ID for strong component built from protein_lddt_weighted_max metric with 100 threshold
-protein_lddt_weighted_sum__50__weak__component str Cluster ID for weak component built from protein_lddt_weighted_sum metric with 50 threshold
-protein_lddt_weighted_sum__70__weak__component str Cluster ID for weak component built from protein_lddt_weighted_sum metric with 70 threshold
-protein_lddt_weighted_sum__95__weak__component str Cluster ID for weak component built from protein_lddt_weighted_sum metric with 95 threshold
-protein_lddt_weighted_sum__100__weak__component str Cluster ID for weak component built from protein_lddt_weighted_sum metric with 100 threshold
-protein_lddt_weighted_sum__50__strong__component str Cluster ID for strong component built from protein_lddt_weighted_sum metric with 50 threshold
-protein_lddt_weighted_sum__70__strong__component str Cluster ID for strong component built from protein_lddt_weighted_sum metric with 70 threshold
-protein_lddt_weighted_sum__95__strong__component str Cluster ID for strong component built from protein_lddt_weighted_sum metric with 95 threshold
-protein_lddt_weighted_sum__100__strong__component str Cluster ID for strong component built from protein_lddt_weighted_sum metric with 100 threshold
-protein_qcov_weighted_sum__100__weak__component str Cluster ID for weak component built from protein_qcov_weighted_sum metric with 100 threshold
-protein_qcov_weighted_sum__100__strong__component str Cluster ID for strong component built from protein_qcov_weighted_sum metric with 100 threshold
-protein_seqsim_max__70__weak__component str Cluster ID for weak component built from protein_seqsim_max metric with 70 threshold
-protein_seqsim_max__95__weak__component str Cluster ID for weak component built from protein_seqsim_max metric with 95 threshold
-protein_seqsim_max__100__weak__component str Cluster ID for weak component built from protein_seqsim_max metric with 100 threshold
-protein_seqsim_max__70__strong__component str Cluster ID for strong component built from protein_seqsim_max metric with 70 threshold
-protein_seqsim_max__95__strong__component str Cluster ID for strong component built from protein_seqsim_max metric with 95 threshold
-protein_seqsim_max__100__strong__component str Cluster ID for strong component built from protein_seqsim_max metric with 100 threshold
-protein_seqsim_qcov_max__50__weak__component str Cluster ID for weak component built from protein_seqsim_qcov_max metric with 50 threshold
-protein_seqsim_qcov_max__70__weak__component str Cluster ID for weak component built from protein_seqsim_qcov_max metric with 70 threshold
-protein_seqsim_qcov_max__95__weak__component str Cluster ID for weak component built from protein_seqsim_qcov_max metric with 95 threshold
-protein_seqsim_qcov_max__100__weak__component str Cluster ID for weak component built from protein_seqsim_qcov_max metric with 100 threshold
-protein_seqsim_qcov_max__50__strong__component str Cluster ID for strong component built from protein_seqsim_qcov_max metric with 50 threshold
-protein_seqsim_qcov_max__70__strong__component str Cluster ID for strong component built from protein_seqsim_qcov_max metric with 70 threshold
-protein_seqsim_qcov_max__95__strong__component str Cluster ID for strong component built from protein_seqsim_qcov_max metric with 95 threshold
-protein_seqsim_qcov_max__100__strong__component str Cluster ID for strong component built from protein_seqsim_qcov_max metric with 100 threshold
-protein_seqsim_qcov_weighted_max__50__weak__component str Cluster ID for weak component built from protein_seqsim_qcov_weighted_max metric with 50 threshold
-protein_seqsim_qcov_weighted_max__70__weak__component str Cluster ID for weak component built from protein_seqsim_qcov_weighted_max metric with 70 threshold
-protein_seqsim_qcov_weighted_max__95__weak__component str Cluster ID for weak component built from protein_seqsim_qcov_weighted_max metric with 95 threshold
-protein_seqsim_qcov_weighted_max__100__weak__component str Cluster ID for weak component built from protein_seqsim_qcov_weighted_max metric with 100 threshold
-protein_seqsim_qcov_weighted_max__50__strong__component str Cluster ID for strong component built from protein_seqsim_qcov_weighted_max metric with 50 threshold
-protein_seqsim_qcov_weighted_max__70__strong__component str Cluster ID for strong component built from protein_seqsim_qcov_weighted_max metric with 70 threshold
-protein_seqsim_qcov_weighted_max__95__strong__component str Cluster ID for strong component built from protein_seqsim_qcov_weighted_max metric with 95 threshold
-protein_seqsim_qcov_weighted_max__100__strong__component str Cluster ID for strong component built from protein_seqsim_qcov_weighted_max metric with 100 threshold
-protein_seqsim_qcov_weighted_sum__50__weak__component str Cluster ID for weak component built from protein_seqsim_qcov_weighted_sum metric with 50 threshold
-protein_seqsim_qcov_weighted_sum__70__weak__component str Cluster ID for weak component built from protein_seqsim_qcov_weighted_sum metric with 70 threshold
-protein_seqsim_qcov_weighted_sum__95__weak__component str Cluster ID for weak component built from protein_seqsim_qcov_weighted_sum metric with 95 threshold
-protein_seqsim_qcov_weighted_sum__100__weak__component str Cluster ID for weak component built from protein_seqsim_qcov_weighted_sum metric with 100 threshold
-protein_seqsim_qcov_weighted_sum__50__strong__component str Cluster ID for strong component built from protein_seqsim_qcov_weighted_sum metric with 50 threshold
-protein_seqsim_qcov_weighted_sum__70__strong__component str Cluster ID for strong component built from protein_seqsim_qcov_weighted_sum metric with 70 threshold
-protein_seqsim_qcov_weighted_sum__95__strong__component str Cluster ID for strong component built from protein_seqsim_qcov_weighted_sum metric with 95 threshold
-protein_seqsim_qcov_weighted_sum__100__strong__component str Cluster ID for strong component built from protein_seqsim_qcov_weighted_sum metric with 100 threshold
-protein_seqsim_weighted_max__70__weak__component str Cluster ID for weak component built from protein_seqsim_weighted_max metric with 70 threshold
-protein_seqsim_weighted_max__95__weak__component str Cluster ID for weak component built from protein_seqsim_weighted_max metric with 95 threshold
-protein_seqsim_weighted_max__100__weak__component str Cluster ID for weak component built from protein_seqsim_weighted_max metric with 100 threshold
-protein_seqsim_weighted_max__70__strong__component str Cluster ID for strong component built from protein_seqsim_weighted_max metric with 70 threshold
-protein_seqsim_weighted_max__95__strong__component str Cluster ID for strong component built from protein_seqsim_weighted_max metric with 95 threshold
-protein_seqsim_weighted_max__100__strong__component str Cluster ID for strong component built from protein_seqsim_weighted_max metric with 100 threshold
-protein_seqsim_weighted_sum__50__weak__component str Cluster ID for weak component built from protein_seqsim_weighted_sum metric with 50 threshold
-protein_seqsim_weighted_sum__70__weak__component str Cluster ID for weak component built from protein_seqsim_weighted_sum metric with 70 threshold
-protein_seqsim_weighted_sum__95__weak__component str Cluster ID for weak component built from protein_seqsim_weighted_sum metric with 95 threshold
-protein_seqsim_weighted_sum__100__weak__component str Cluster ID for weak component built from protein_seqsim_weighted_sum metric with 100 threshold
-protein_seqsim_weighted_sum__50__strong__component str Cluster ID for strong component built from protein_seqsim_weighted_sum metric with 50 threshold
-protein_seqsim_weighted_sum__70__strong__component str Cluster ID for strong component built from protein_seqsim_weighted_sum metric with 70 threshold
-protein_seqsim_weighted_sum__95__strong__component str Cluster ID for strong component built from protein_seqsim_weighted_sum metric with 95 threshold
-protein_seqsim_weighted_sum__100__strong__component str Cluster ID for strong component built from protein_seqsim_weighted_sum metric with 100 threshold
-tanimoto_similarity_max__30__weak__component str Cluster ID for weak component built from tanimoto_similarity_max metric with 30 threshold
-tanimoto_similarity_max__50__weak__component str Cluster ID for weak component built from tanimoto_similarity_max metric with 50 threshold
-tanimoto_similarity_max__70__weak__component str Cluster ID for weak component built from tanimoto_similarity_max metric with 70 threshold
-tanimoto_similarity_max__95__weak__component str Cluster ID for weak component built from tanimoto_similarity_max metric with 95 threshold
-tanimoto_similarity_max__100__weak__component str Cluster ID for weak component built from tanimoto_similarity_max metric with 100 threshold
-tanimoto_similarity_max__30__strong__component str Cluster ID for strong component built from tanimoto_similarity_max metric with 30 threshold
-tanimoto_similarity_max__50__strong__component str Cluster ID for strong component built from tanimoto_similarity_max metric with 50 threshold
-tanimoto_similarity_max__70__strong__component str Cluster ID for strong component built from tanimoto_similarity_max metric with 70 threshold
-tanimoto_similarity_max__95__strong__component str Cluster ID for strong component built from tanimoto_similarity_max metric with 95 threshold
-tanimoto_similarity_max__100__strong__component str Cluster ID for strong component built from tanimoto_similarity_max metric with 100 threshold
-pli_qcov__50__community str Cluster ID for community built from pli_qcov metric with 50 threshold
-pli_qcov__70__community str Cluster ID for community built from pli_qcov metric with 70 threshold
-pli_qcov__95__community str Cluster ID for community built from pli_qcov metric with 95 threshold
-pli_qcov__100__community str Cluster ID for community built from pli_qcov metric with 100 threshold
-pli_unique_qcov__0__community str Cluster ID for community built from pli_unique_qcov metric with 0 threshold
-pli_unique_qcov__50__community str Cluster ID for community built from pli_unique_qcov metric with 50 threshold
-pli_unique_qcov__70__community str Cluster ID for community built from pli_unique_qcov metric with 70 threshold
-pli_unique_qcov__95__community str Cluster ID for community built from pli_unique_qcov metric with 95 threshold
-pli_unique_qcov__100__community str Cluster ID for community built from pli_unique_qcov metric with 100 threshold
-pocket_fident__50__community str Cluster ID for community built from pocket_fident metric with 50 threshold
-pocket_fident__70__community str Cluster ID for community built from pocket_fident metric with 70 threshold
-pocket_fident__95__community str Cluster ID for community built from pocket_fident metric with 95 threshold
-pocket_fident__100__community str Cluster ID for community built from pocket_fident metric with 100 threshold
-pocket_fident_qcov__50__community str Cluster ID for community built from pocket_fident_qcov metric with 50 threshold
-pocket_fident_qcov__70__community str Cluster ID for community built from pocket_fident_qcov metric with 70 threshold
-pocket_fident_qcov__95__community str Cluster ID for community built from pocket_fident_qcov metric with 95 threshold
-pocket_fident_qcov__100__community str Cluster ID for community built from pocket_fident_qcov metric with 100 threshold
-pocket_lddt__50__community str Cluster ID for community built from pocket_lddt metric with 50 threshold
-pocket_lddt__70__community str Cluster ID for community built from pocket_lddt metric with 70 threshold
-pocket_lddt__95__community str Cluster ID for community built from pocket_lddt metric with 95 threshold
-pocket_lddt__100__community str Cluster ID for community built from pocket_lddt metric with 100 threshold
-pocket_lddt_qcov__50__community str Cluster ID for community built from pocket_lddt_qcov metric with 50 threshold
-pocket_lddt_qcov__70__community str Cluster ID for community built from pocket_lddt_qcov metric with 70 threshold
-pocket_lddt_qcov__95__community str Cluster ID for community built from pocket_lddt_qcov metric with 95 threshold
-pocket_lddt_qcov__100__community str Cluster ID for community built from pocket_lddt_qcov metric with 100 threshold
-pocket_qcov__50__community str Cluster ID for community built from pocket_qcov metric with 50 threshold
-pocket_qcov__70__community str Cluster ID for community built from pocket_qcov metric with 70 threshold
-pocket_qcov__95__community str Cluster ID for community built from pocket_qcov metric with 95 threshold
-pocket_qcov__100__community str Cluster ID for community built from pocket_qcov metric with 100 threshold
-protein_fident_max__50__community str Cluster ID for community built from protein_fident_max metric with 50 threshold
-protein_fident_max__70__community str Cluster ID for community built from protein_fident_max metric with 70 threshold
-protein_fident_max__95__community str Cluster ID for community built from protein_fident_max metric with 95 threshold
-protein_fident_max__100__community str Cluster ID for community built from protein_fident_max metric with 100 threshold
-protein_fident_qcov_max__50__community str Cluster ID for community built from protein_fident_qcov_max metric with 50 threshold
-protein_fident_qcov_max__70__community str Cluster ID for community built from protein_fident_qcov_max metric with 70 threshold
-protein_fident_qcov_max__95__community str Cluster ID for community built from protein_fident_qcov_max metric with 95 threshold
-protein_fident_qcov_max__100__community str Cluster ID for community built from protein_fident_qcov_max metric with 100 threshold
-protein_fident_qcov_weighted_max__50__community str Cluster ID for community built from protein_fident_qcov_weighted_max metric with 50 threshold
-protein_fident_qcov_weighted_max__70__community str Cluster ID for community built from protein_fident_qcov_weighted_max metric with 70 threshold
-protein_fident_qcov_weighted_max__95__community str Cluster ID for community built from protein_fident_qcov_weighted_max metric with 95 threshold
-protein_fident_qcov_weighted_max__100__community str Cluster ID for community built from protein_fident_qcov_weighted_max metric with 100 threshold
-protein_fident_qcov_weighted_sum__50__community str Cluster ID for community built from protein_fident_qcov_weighted_sum metric with 50 threshold
-protein_fident_qcov_weighted_sum__70__community str Cluster ID for community built from protein_fident_qcov_weighted_sum metric with 70 threshold
-protein_fident_qcov_weighted_sum__95__community str Cluster ID for community built from protein_fident_qcov_weighted_sum metric with 95 threshold
-protein_fident_qcov_weighted_sum__100__community str Cluster ID for community built from protein_fident_qcov_weighted_sum metric with 100 threshold
-protein_fident_weighted_max__50__community str Cluster ID for community built from protein_fident_weighted_max metric with 50 threshold
-protein_fident_weighted_max__70__community str Cluster ID for community built from protein_fident_weighted_max metric with 70 threshold
-protein_fident_weighted_max__95__community str Cluster ID for community built from protein_fident_weighted_max metric with 95 threshold
-protein_fident_weighted_max__100__community str Cluster ID for community built from protein_fident_weighted_max metric with 100 threshold
-protein_fident_weighted_sum__50__community str Cluster ID for community built from protein_fident_weighted_sum metric with 50 threshold
-protein_fident_weighted_sum__70__community str Cluster ID for community built from protein_fident_weighted_sum metric with 70 threshold
-protein_fident_weighted_sum__95__community str Cluster ID for community built from protein_fident_weighted_sum metric with 95 threshold
-protein_fident_weighted_sum__100__community str Cluster ID for community built from protein_fident_weighted_sum metric with 100 threshold
-protein_lddt_max__70__community str Cluster ID for community built from protein_lddt_max metric with 70 threshold
-protein_lddt_max__95__community str Cluster ID for community built from protein_lddt_max metric with 95 threshold
-protein_lddt_max__100__community str Cluster ID for community built from protein_lddt_max metric with 100 threshold
-protein_lddt_qcov_max__50__community str Cluster ID for community built from protein_lddt_qcov_max metric with 50 threshold
-protein_lddt_qcov_max__70__community str Cluster ID for community built from protein_lddt_qcov_max metric with 70 threshold
-protein_lddt_qcov_max__95__community str Cluster ID for community built from protein_lddt_qcov_max metric with 95 threshold
-protein_lddt_qcov_max__100__community str Cluster ID for community built from protein_lddt_qcov_max metric with 100 threshold
-protein_lddt_qcov_weighted_max__50__community str Cluster ID for community built from protein_lddt_qcov_weighted_max metric with 50 threshold
-protein_lddt_qcov_weighted_max__70__community str Cluster ID for community built from protein_lddt_qcov_weighted_max metric with 70 threshold
-protein_lddt_qcov_weighted_max__95__community str Cluster ID for community built from protein_lddt_qcov_weighted_max metric with 95 threshold
-protein_lddt_qcov_weighted_max__100__community str Cluster ID for community built from protein_lddt_qcov_weighted_max metric with 100 threshold
-protein_lddt_qcov_weighted_sum__50__community str Cluster ID for community built from protein_lddt_qcov_weighted_sum metric with 50 threshold
-protein_lddt_qcov_weighted_sum__70__community str Cluster ID for community built from protein_lddt_qcov_weighted_sum metric with 70 threshold
-protein_lddt_qcov_weighted_sum__95__community str Cluster ID for community built from protein_lddt_qcov_weighted_sum metric with 95 threshold
-protein_lddt_qcov_weighted_sum__100__community str Cluster ID for community built from protein_lddt_qcov_weighted_sum metric with 100 threshold
-protein_lddt_weighted_max__70__community str Cluster ID for community built from protein_lddt_weighted_max metric with 70 threshold
-protein_lddt_weighted_max__95__community str Cluster ID for community built from protein_lddt_weighted_max metric with 95 threshold
-protein_lddt_weighted_max__100__community str Cluster ID for community built from protein_lddt_weighted_max metric with 100 threshold
-protein_lddt_weighted_sum__50__community str Cluster ID for community built from protein_lddt_weighted_sum metric with 50 threshold
-protein_lddt_weighted_sum__70__community str Cluster ID for community built from protein_lddt_weighted_sum metric with 70 threshold
-protein_lddt_weighted_sum__95__community str Cluster ID for community built from protein_lddt_weighted_sum metric with 95 threshold
-protein_lddt_weighted_sum__100__community str Cluster ID for community built from protein_lddt_weighted_sum metric with 100 threshold
-protein_qcov_weighted_sum__100__community str Cluster ID for community built from protein_qcov_weighted_sum metric with 100 threshold
-protein_seqsim_max__70__community str Cluster ID for community built from protein_seqsim_max metric with 70 threshold
-protein_seqsim_max__95__community str Cluster ID for community built from protein_seqsim_max metric with 95 threshold
-protein_seqsim_max__100__community str Cluster ID for community built from protein_seqsim_max metric with 100 threshold
-protein_seqsim_qcov_max__50__community str Cluster ID for community built from protein_seqsim_qcov_max metric with 50 threshold
-protein_seqsim_qcov_max__70__community str Cluster ID for community built from protein_seqsim_qcov_max metric with 70 threshold
-protein_seqsim_qcov_max__95__community str Cluster ID for community built from protein_seqsim_qcov_max metric with 95 threshold
-protein_seqsim_qcov_max__100__community str Cluster ID for community built from protein_seqsim_qcov_max metric with 100 threshold
-protein_seqsim_qcov_weighted_max__50__community str Cluster ID for community built from protein_seqsim_qcov_weighted_max metric with 50 threshold
-protein_seqsim_qcov_weighted_max__70__community str Cluster ID for community built from protein_seqsim_qcov_weighted_max metric with 70 threshold
-protein_seqsim_qcov_weighted_max__95__community str Cluster ID for community built from protein_seqsim_qcov_weighted_max metric with 95 threshold
-protein_seqsim_qcov_weighted_max__100__community str Cluster ID for community built from protein_seqsim_qcov_weighted_max metric with 100 threshold
-protein_seqsim_qcov_weighted_sum__50__community str Cluster ID for community built from protein_seqsim_qcov_weighted_sum metric with 50 threshold
-protein_seqsim_qcov_weighted_sum__70__community str Cluster ID for community built from protein_seqsim_qcov_weighted_sum metric with 70 threshold
-protein_seqsim_qcov_weighted_sum__95__community str Cluster ID for community built from protein_seqsim_qcov_weighted_sum metric with 95 threshold
-protein_seqsim_qcov_weighted_sum__100__community str Cluster ID for community built from protein_seqsim_qcov_weighted_sum metric with 100 threshold
-protein_seqsim_weighted_max__70__community str Cluster ID for community built from protein_seqsim_weighted_max metric with 70 threshold
-protein_seqsim_weighted_max__95__community str Cluster ID for community built from protein_seqsim_weighted_max metric with 95 threshold
-protein_seqsim_weighted_max__100__community str Cluster ID for community built from protein_seqsim_weighted_max metric with 100 threshold
-protein_seqsim_weighted_sum__50__community str Cluster ID for community built from protein_seqsim_weighted_sum metric with 50 threshold
-protein_seqsim_weighted_sum__70__community str Cluster ID for community built from protein_seqsim_weighted_sum metric with 70 threshold
-protein_seqsim_weighted_sum__95__community str Cluster ID for community built from protein_seqsim_weighted_sum metric with 95 threshold
-protein_seqsim_weighted_sum__100__community str Cluster ID for community built from protein_seqsim_weighted_sum metric with 100 threshold
-tanimoto_similarity_max__30__community str Cluster ID for community built from tanimoto_similarity_max metric with 30 threshold
-tanimoto_similarity_max__50__community str Cluster ID for community built from tanimoto_similarity_max metric with 50 threshold
-tanimoto_similarity_max__70__community str Cluster ID for community built from tanimoto_similarity_max metric with 70 threshold
-tanimoto_similarity_max__95__community str Cluster ID for community built from tanimoto_similarity_max metric with 95 threshold
-tanimoto_similarity_max__100__community str Cluster ID for community built from tanimoto_similarity_max metric with 100 threshold
diff --git a/src/plinder/data/column_descriptions/system.tsv b/src/plinder/data/column_descriptions/system.tsv
deleted file mode 100644
index c120d5e46..000000000
--- a/src/plinder/data/column_descriptions/system.tsv
+++ /dev/null
@@ -1,30 +0,0 @@
-Name Type Description
-system_biounit_id str Biounit ID
-system_protein_chains_asym_id list[str] Interacting protein chains of the system
-system_id_no_biounit str ID of the system without the biounit
-system_ligand_chains list[str] Ligand chains of the system
-system_num_pocket_residues int Number of pocket residues of the system
-system_proper_num_pocket_residues int Number of pocket residues of the system excluding ions and artifacts
-system_num_interactions int Number of interactions of the system
-system_proper_num_interactions int Number of interactions of the system
-system_num_unique_interactions int Number of unique interactions of the system
-system_proper_num_unique_interactions int Number of unique interactions of the system
-system_num_covalent_ligands int Number of covalent ligands of the system
-system_proper_num_covalent_ligands int Number of covalent ligands of the system
-system_id str ID of the system
-system_type str Type of the system (one of: holo, ion, artifact)
-system_has_kinase_inhibitor bool Whether the system has a kinase inhibitor
-system_has_binding_affinity bool Whether any ligand in the system has a binding affinity from BindingDB
-system_num_protein_chains int Number of interacting protein chains of the system
-system_proper_num_protein_chains int Number of interacting protein chains of the system excluding ions and artifacts
-system_num_ligand_chains int Number of ligand chains of the system
-system_proper_num_ligand_chains int Number of ligand chains of the system excluding ions and artifacts
-system_num_crystal_contacted_residues int Number of residues from other symmetry mates which are in contact with any ligand in the system.
-system_num_atoms_with_crystal_contacts int Number of atoms in the system ligands which are in contact with residues from other symmetry mates.
-system_num_heavy_atoms int | None Number of heavy atoms in the system ligands
-system_num_resolved_heavy_atoms int | None Number of resolved heavy atoms in the system ligands
-system_ligand_max_qed float Maximum QED of the system ligands
-system_ligand_max_molecular_weight float Maximum molecular weight of the system ligands
-system_proper_ligand_max_molecular_weight float Maximum molecular weight of the system ligands excluding ions and artifacts
-system_num_unresolved_heavy_atoms int | None Number of unresolved heavy atoms in the system ligands
-system_fraction_atoms_with_crystal_contacts float | None Fraction of atoms in the system ligands which are in contact with residues from other symmetry mates.
diff --git a/src/plinder/data/column_descriptions/system_ligand_chains.tsv b/src/plinder/data/column_descriptions/system_ligand_chains.tsv
deleted file mode 100644
index b8285d613..000000000
--- a/src/plinder/data/column_descriptions/system_ligand_chains.tsv
+++ /dev/null
@@ -1,6 +0,0 @@
-Name Type Description
-system_ligand_chains_asym_id list[str] Chain asymmetric id
-system_ligand_chains_auth_id list[str] Chain author id
-system_ligand_chains_entity_id list[str] Chain entity id
-system_ligand_chains_length list[int] SEQRES length
-system_ligand_chains_num_unresolved_residues list[int] Number of unresolved residues (SEQRES length - len(residues))
diff --git a/src/plinder/data/column_descriptions/system_ligand_chains_validation.tsv b/src/plinder/data/column_descriptions/system_ligand_chains_validation.tsv
deleted file mode 100644
index 7ac56acb8..000000000
--- a/src/plinder/data/column_descriptions/system_ligand_chains_validation.tsv
+++ /dev/null
@@ -1,21 +0,0 @@
-Name Type Description
-system_ligand_chains_validation_num_residues list[int] Number of residues in the list
-system_ligand_chains_validation_num_processed_residues list[int] Number of processed residues in the list
-system_ligand_chains_validation_percent_processed_residues list[float] Percentage of processed residues in the list
-system_ligand_chains_validation_average_rsr list[float] Average Real-Space R-value across all residues in the list
-system_ligand_chains_validation_average_rsrz list[float] Average Real-Space R-value Z-score across all residues in the list
-system_ligand_chains_validation_average_rscc list[float] Average Real-Space Correlation Coefficient across all residues in the list
-system_ligand_chains_validation_average_occupancy list[float] Average occupancy across all residues in the list
-system_ligand_chains_validation_percent_rsr_under_threshold list[float] Percentage of residues with RSR under the threshold
-system_ligand_chains_validation_percent_rscc_over_threshold list[float] Percentage of residues with RSCC over the threshold
-system_ligand_chains_validation_percent_occupancy_over_threshold list[float] Percentage of residues with occupancy over the threshold
-system_ligand_chains_validation_average_b_factor list[float] Average B factor across all residues in the list
-system_ligand_chains_validation_unknown_residue_count list[int] Number of unknown residues in the list
-system_ligand_chains_validation_atom_count list[int] Number of atoms across all residues in the list
-system_ligand_chains_validation_heavy_atom_count list[int] Number of heavy atoms across all residues in the list
-system_ligand_chains_validation_num_unresolved_heavy_atoms list[int] Number of unresolved heavy atoms across all residues in the list
-system_ligand_chains_validation_max_alt_count list[int] The highest number of configurations in a single residue in the list
-system_ligand_chains_validation_percent_outliers_chirality list[float] Percent outliers for chirality
-system_ligand_chains_validation_percent_outliers_clashes list[float] Percent outliers for clashes
-system_ligand_chains_validation_percent_outliers_density list[float] Percent outliers for density
-system_ligand_chains_validation_percent_outliers_geometry list[float] Percent outliers for geometry
diff --git a/src/plinder/data/column_descriptions/system_ligand_validation.tsv b/src/plinder/data/column_descriptions/system_ligand_validation.tsv
deleted file mode 100644
index edcb6deb2..000000000
--- a/src/plinder/data/column_descriptions/system_ligand_validation.tsv
+++ /dev/null
@@ -1,21 +0,0 @@
-Name Type Description
-system_ligand_validation_num_residues int Number of residues in the list
-system_ligand_validation_num_processed_residues int Number of processed residues in the list
-system_ligand_validation_percent_processed_residues float Percentage of processed residues in the list
-system_ligand_validation_average_rsr float Average Real-Space R-value across all residues in the list
-system_ligand_validation_average_rsrz float Average Real-Space R-value Z-score across all residues in the list
-system_ligand_validation_average_rscc float Average Real-Space Correlation Coefficient across all residues in the list
-system_ligand_validation_average_occupancy float Average occupancy across all residues in the list
-system_ligand_validation_percent_rsr_under_threshold float Percentage of residues with RSR under the threshold
-system_ligand_validation_percent_rscc_over_threshold float Percentage of residues with RSCC over the threshold
-system_ligand_validation_percent_occupancy_over_threshold float Percentage of residues with occupancy over the threshold
-system_ligand_validation_average_b_factor float Average B factor across all residues in the list
-system_ligand_validation_unknown_residue_count int Number of unknown residues in the list
-system_ligand_validation_atom_count int Number of atoms across all residues in the list
-system_ligand_validation_heavy_atom_count int Number of heavy atoms across all residues in the list
-system_ligand_validation_num_unresolved_heavy_atoms int Number of unresolved heavy atoms across all residues in the list
-system_ligand_validation_max_alt_count int The highest number of configurations in a single residue in the list
-system_ligand_validation_percent_outliers_chirality float Percent outliers for chirality
-system_ligand_validation_percent_outliers_clashes float Percent outliers for clashes
-system_ligand_validation_percent_outliers_density float Percent outliers for density
-system_ligand_validation_percent_outliers_geometry float Percent outliers for geometry
diff --git a/src/plinder/data/column_descriptions/system_pocket.tsv b/src/plinder/data/column_descriptions/system_pocket.tsv
deleted file mode 100644
index 3db5ca587..000000000
--- a/src/plinder/data/column_descriptions/system_pocket.tsv
+++ /dev/null
@@ -1,10 +0,0 @@
-Name Type Description
-system_pocket_CATH str CATH domain for the pocket
-system_pocket_ECOD str ECOD domain for the pocket
-system_pocket_ECOD_t_name str ECOD_t_name domain for the pocket
-system_pocket_Pfam str Pfam domain for the pocket
-system_pocket_SCOP2 str SCOP2 domain for the pocket
-system_pocket_SCOP2B str SCOP2B domain for the pocket
-system_pocket_PANTHER str PANTHER domain for the pocket
-system_pocket_UniProt str UniProt domain for the pocket
-system_pocket_kinase_name str kinase_name domain for the pocket
diff --git a/src/plinder/data/column_descriptions/system_pocket_validation.tsv b/src/plinder/data/column_descriptions/system_pocket_validation.tsv
deleted file mode 100644
index 87dc5dc00..000000000
--- a/src/plinder/data/column_descriptions/system_pocket_validation.tsv
+++ /dev/null
@@ -1,21 +0,0 @@
-Name Type Description
-system_pocket_validation_num_residues int Number of residues in the list
-system_pocket_validation_num_processed_residues int Number of processed residues in the list
-system_pocket_validation_percent_processed_residues float Percentage of processed residues in the list
-system_pocket_validation_average_rsr float Average Real-Space R-value across all residues in the list
-system_pocket_validation_average_rsrz float Average Real-Space R-value Z-score across all residues in the list
-system_pocket_validation_average_rscc float Average Real-Space Correlation Coefficient across all residues in the list
-system_pocket_validation_average_occupancy float Average occupancy across all residues in the list
-system_pocket_validation_percent_rsr_under_threshold float Percentage of residues with RSR under the threshold
-system_pocket_validation_percent_rscc_over_threshold float Percentage of residues with RSCC over the threshold
-system_pocket_validation_percent_occupancy_over_threshold float Percentage of residues with occupancy over the threshold
-system_pocket_validation_average_b_factor float Average B factor across all residues in the list
-system_pocket_validation_unknown_residue_count int Number of unknown residues in the list
-system_pocket_validation_atom_count int Number of atoms across all residues in the list
-system_pocket_validation_heavy_atom_count int Number of heavy atoms across all residues in the list
-system_pocket_validation_num_unresolved_heavy_atoms int Number of unresolved heavy atoms across all residues in the list
-system_pocket_validation_max_alt_count int The highest number of configurations in a single residue in the list
-system_pocket_validation_percent_outliers_chirality float Percent outliers for chirality
-system_pocket_validation_percent_outliers_clashes float Percent outliers for clashes
-system_pocket_validation_percent_outliers_density float Percent outliers for density
-system_pocket_validation_percent_outliers_geometry float Percent outliers for geometry
diff --git a/src/plinder/data/column_descriptions/system_protein_chains.tsv b/src/plinder/data/column_descriptions/system_protein_chains.tsv
deleted file mode 100644
index c7d3d5dfc..000000000
--- a/src/plinder/data/column_descriptions/system_protein_chains.tsv
+++ /dev/null
@@ -1,6 +0,0 @@
-Name Type Description
-system_protein_chains_asym_id list[str] Chain asymmetric id
-system_protein_chains_auth_id list[str] Chain author id
-system_protein_chains_entity_id list[str] Chain entity id
-system_protein_chains_length list[int] SEQRES length
-system_protein_chains_num_unresolved_residues list[int] Number of unresolved residues (SEQRES length - len(residues))
diff --git a/src/plinder/data/column_descriptions/system_protein_chains_validation.tsv b/src/plinder/data/column_descriptions/system_protein_chains_validation.tsv
deleted file mode 100644
index ec0d4598e..000000000
--- a/src/plinder/data/column_descriptions/system_protein_chains_validation.tsv
+++ /dev/null
@@ -1,21 +0,0 @@
-Name Type Description
-system_protein_chains_validation_num_residues list[int] Number of residues in the list
-system_protein_chains_validation_num_processed_residues list[int] Number of processed residues in the list
-system_protein_chains_validation_percent_processed_residues list[float] Percentage of processed residues in the list
-system_protein_chains_validation_average_rsr list[float] Average Real-Space R-value across all residues in the list
-system_protein_chains_validation_average_rsrz list[float] Average Real-Space R-value Z-score across all residues in the list
-system_protein_chains_validation_average_rscc list[float] Average Real-Space Correlation Coefficient across all residues in the list
-system_protein_chains_validation_average_occupancy list[float] Average occupancy across all residues in the list
-system_protein_chains_validation_percent_rsr_under_threshold list[float] Percentage of residues with RSR under the threshold
-system_protein_chains_validation_percent_rscc_over_threshold list[float] Percentage of residues with RSCC over the threshold
-system_protein_chains_validation_percent_occupancy_over_threshold list[float] Percentage of residues with occupancy over the threshold
-system_protein_chains_validation_average_b_factor list[float] Average B factor across all residues in the list
-system_protein_chains_validation_unknown_residue_count list[int] Number of unknown residues in the list
-system_protein_chains_validation_atom_count list[int] Number of atoms across all residues in the list
-system_protein_chains_validation_heavy_atom_count list[int] Number of heavy atoms across all residues in the list
-system_protein_chains_validation_num_unresolved_heavy_atoms list[int] Number of unresolved heavy atoms across all residues in the list
-system_protein_chains_validation_max_alt_count list[int] The highest number of configurations in a single residue in the list
-system_protein_chains_validation_percent_outliers_chirality list[float] Percent outliers for chirality
-system_protein_chains_validation_percent_outliers_clashes list[float] Percent outliers for clashes
-system_protein_chains_validation_percent_outliers_density list[float] Percent outliers for density
-system_protein_chains_validation_percent_outliers_geometry list[float] Percent outliers for geometry
diff --git a/src/plinder/data/column_descriptions/tables/alignment_chain_lookup.tsv b/src/plinder/data/column_descriptions/tables/alignment_chain_lookup.tsv
new file mode 100644
index 000000000..0d4ff0b41
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/alignment_chain_lookup.tsv
@@ -0,0 +1,6 @@
+Name Type Description
+entry_pdb_id string RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html
+chain_asym_id string Chain asymmetric id
+chain_auth_id string Chain author id
+selected_residue_numbers list Source-mmCIF residue numbers selected by any ligand pocket or protein interface, ordered by selected_residue_indices
+selected_residue_indices list Zero-based resolved-chain indices corresponding positionally to selected_residue_numbers
diff --git a/src/plinder/data/column_descriptions/tables/annotation.tsv b/src/plinder/data/column_descriptions/tables/annotation.tsv
new file mode 100644
index 000000000..9df496e19
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/annotation.tsv
@@ -0,0 +1,129 @@
+Name Type Description
+entry_pdb_id string RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html
+system_biounit_id string Biounit ID
+system_id_legacy string Historical system ID using global assembly-operation chain instances
+system_receptor_type string Receptor polymer composition: protein, DNA, RNA, other, or a +-joined combination
+system_protein_chains_asym_id list Chain asymmetric id
+system_num_pocket_residues int64 Number of pocket residues of the system
+system_proper_num_pocket_residues int64 Number of pocket residues of the system excluding ions and artifacts
+system_num_interactions int64 Number of interactions of the system
+system_proper_num_interactions int64 Number of interactions of the system excluding ions and artifacts
+system_num_unique_interactions int64 Number of unique interactions of the system
+system_proper_num_unique_interactions int64 Number of unique interactions of the system excluding ions and artifacts
+system_num_covalent_ligands int64 Number of covalent ligands of the system
+system_proper_num_covalent_ligands int64 Number of covalent ligands of the system excluding ions and artifacts
+system_id string ID of the system
+system_type string Type of the system (one of: holo, ion, artifact)
+system_num_protein_chains int64 Number of interacting receptor chains of the system.
+system_proper_num_protein_chains int64 Number of interacting receptor chains excluding ions and artifacts.
+system_num_ligand_chains int64 Number of ligand chains of the system
+system_proper_num_ligand_chains int64 Number of ligand chains of the system excluding ions and artifacts
+system_num_crystal_contacted_residues int64 Number of residues from other symmetry mates which are in contact with any ligand in the system.
+system_num_atoms_with_crystal_contacts int64 Number of atoms in the system ligands which are in contact with residues from other symmetry mates.
+system_num_heavy_atoms double Number of heavy atoms in the system ligands
+system_num_resolved_heavy_atoms int64 Number of resolved heavy atoms in the system ligands
+system_ligand_max_qed double Maximum QED of the system ligands
+system_ligand_max_molecular_weight double Maximum molecular weight of the system ligands
+system_proper_ligand_max_molecular_weight double Maximum molecular weight of the system ligands excluding ions and artifacts
+system_num_unresolved_heavy_atoms double Number of unresolved heavy atoms in the system ligands
+system_fraction_atoms_with_crystal_contacts double Fraction of atoms in the system ligands which are in contact with residues from other symmetry mates.
+system_pass_validation_criteria bool Whether the system passes validation criteria
+system_ligand_chains_asym_id list Chain asymmetric id
+system_water_residues list Interacting water residues encoded as ._
+ligand_id_legacy string Historical ligand ID using global assembly-operation chain instances
+ligand_asym_id string Ligand chain asymmetric id
+ligand_instance int64 Biounit instance ID
+ligand_ccd_code string Ligand Chemical Component Dictionary (CCD) code
+ligand_molecule_type string Ligand molecule type derived from the mmCIF entity polymer type: SMALLMOLECULE, PEPTIDE, DNA, RNA, MIXED, SACCHARIDE, MACROCYCLES, or UNKNOWN
+ligand_bird_id string BIRD/PRD reference-molecule id (PRD_xxxxxx) for multi-component ligands, from pdbx_molecule
+ligand_is_subject_of_investigation double Whether a component of this ligand is a depositor-flagged SUBJECT OF INVESTIGATION (_pdbx_entity_instance_feature); null when the entry lacks the annotation, i.e. most entries deposited before ~2019
+ligand_smiles string Ligand SMILES from CCD lookup or resolved 3D; for composite ligands, the valid representation with more heavy atoms is used and resolved connectivity wins ties
+ligand_resolved_smiles string SMILES from resolved 3D coordinates: bond orders from CCD template, stereochemistry from 3D geometry
+ligand_resolved_stereo_matches_template bool Whether resolved 3D stereo matches CCD template (True if achiral; None if no template)
+ligand_molecular_weight double Molecular weight
+ligand_crippen_clogp double Ligand Crippen MlogP, see https://www.rdkit.org/docs/source/rdkit.Chem.Crippen.html
+ligand_num_rot_bonds double Number of rotatable bonds
+ligand_num_hbd double Number of hydrogen bond donors
+ligand_num_hba double Number of hydrogen bond acceptors
+ligand_num_rings double Number of rings
+ligand_num_heavy_atoms double Number of heavy atoms
+ligand_is_covalent bool Indicator of whether a ligand is a covalent ligand
+ligand_covalent_linkages list Covalent links from _struct_conn (conn_type_id='covale') as receptor_end__ligand_end; each end is {auth_seq}:{comp_id}:{asym}:{label_seq}:{atom} (auth_seq_id with insertion code, label_comp_id, label_asym_id, label_seq_id or '.' for non-polymers, label_atom_id), the residue address shared with ligand_unresolved_atoms and chain_modified_residues
+ligand_failed_interaction_types list Interaction types whose calculation failed for this ligand; counts for these types may be incomplete
+ligand_contact_area double Voronota-LT contact area in square angstroms between the ligand and the receptor polymer chains of its biological assembly; null when the assembly tessellation was skipped or failed
+ligand_num_resolved_heavy_atoms int64 Number of resolved heavy atoms in a ligand
+ligand_num_unresolved_heavy_atoms double Number of unresolved heavy atoms in a ligand: wwPDB unobserved or zero-occupancy atom records, else CCD template minus resolved atoms, else reference SMILES count minus resolved atoms
+ligand_unresolved_atoms list Heavy atoms missing from the ligand model as {auth_seq}:{comp_id}:{asym}:{label_seq}:{atom}, the residue address of ligand_covalent_linkages; from wwPDB unobserved or zero-occupancy atom records, else the CCD template minus resolved atoms; leaving atoms of polymer and linked residues excluded
+ligand_tpsa double Topological polar surface area
+ligand_qed double Ligand QED score, a measure of drug-likeness, see https://www.rdkit.org/new_docs/source/rdkit.Chem.QED.html
+ligand_is_ion bool Indicator of whether a ligand is an ion
+ligand_is_lipinski bool Indicator of whether a ligand satisfies Lipinski Ro5
+ligand_is_fragment bool Indicator of whether a ligand satisfies fragment Ro3
+ligand_is_monosaccharide bool Indicator of whether a ligand contains one saccharide unit
+ligand_is_oligosaccharide bool Indicator of whether a ligand contains multiple saccharide units
+ligand_is_mononucleotide bool Indicator of whether a ligand contains one nucleotide unit
+ligand_is_oligonucleotide bool Indicator of whether a ligand contains multiple nucleotide units
+ligand_is_monopeptide bool Indicator of whether a ligand contains one peptide unit
+ligand_is_oligopeptide bool Indicator of whether a ligand contains multiple peptide units
+ligand_is_cofactor bool Indicator of whether a ligand is a cofactor
+ligand_in_artifact_list bool Indicator of whether a ligand is in the artifact list
+ligand_is_artifact bool Indicator of whether a ligand is an artifact
+ligand_is_other bool Indicator of whether a ligand type is not classified as any types of small molecule (Lipinski, Fragment or covalent), ion, cofactor, mono/oligo (peptide, saccharide or nucleotide) or artifact
+ligand_is_invalid bool Indicator of whether a ligand is invalid
+ligand_unique_ccd_code string Ligand representative CCD code after de-duplicating
+ligand__is_multi_residue bool Whether deposited residue membership proves a composite ligand.
+ligand_member_asym_ids list Asym IDs of every chain this (possibly merged) ligand spans.
+ligand_protein_chains_asym_id list Chain asymmetric id
+ligand_num_interacting_residues int64 Number of residues interacting with a given ligand.
+ligand_num_neighboring_residues int64 Total count of receptor residues (protein/NA) within neighboring threshold.
+ligand_is_proper bool Check if ligand is a proper ligand (not an ion or artifact)
+ligand_num_interactions int64 Number of interactions for a given ligand.
+ligand_num_unique_interactions int64 Number of unique interactions
+ligand_num_crystal_contacted_residues int64 Number of residues from other symmetry mates which are in contact with this ligand.
+ligand_num_atoms_with_crystal_contacts int64 Number of atoms in this ligand which are in contact with residues from other symmetry mates.
+ligand_fraction_atoms_with_crystal_contacts double Fraction of atoms in this ligand which are in contact with residues from other symmetry mates.
+ligand_num_pocket_residues int64 Number of residues in the ligand's binding pocket.
+ligand_id string Unique identifier for a given ligand.
+ligand_instance_chain string Instance chain for a given ligand.
+ligand_residue_numbers list Resolved ligand residue numbers used to reconstruct this ligand from the source mmCIF
+ligand_instance_chains list All instance chains this ligand spans (several for a multi-chain covalent ligand); used to reconstruct the whole-molecule SDF from the source mmCIF
+ligand_water_residues list Interacting water residues encoded as ._
+ligand_interactions list Protein-ligand interactions encoded by receptor chain, residue number, and interaction type
+ligand_contact_area_chains list Instance chains in Voronota-LT contact with the ligand, receptor and ligand chains alike, positionally aligned with ligand_contact_area_values
+ligand_contact_area_values list Voronota-LT contact area in square angstroms between the ligand and each chain in ligand_contact_area_chains
+ligand_pocket_unresolved_atoms list Heavy atoms missing from pocket residues as {auth_seq}:{comp_id}:{asym}:{label_seq}:{atom}, the residue address of ligand_covalent_linkages
+ligand_auth_id string Author chain ID of the ligand
+ligand_interacting_residues list Dictionary of interacting residues, with {instance}.{chain} key and residue number value
+ligand_neighboring_residues list Dictionary of neighboring residues, with {instance}.{chain} key and residue number value
+biounit_num_ligands int64 Number of ligands in the biological assembly
+biounit_num_unique_ccd_codes int64 Number of distinct ligand CCD codes in the biological assembly
+biounit_num_proper_ligands int64 Number of proper ligands in the biological assembly
+system_ligand_has_lipinski bool Whether the system has a Lipinski ligand
+system_ligand_has_cofactor bool Whether the system has a cofactor ligand
+system_ligand_has_fragment bool Whether the system has a fragment ligand
+system_ligand_has_monosaccharide bool Whether the system has a ligand containing one saccharide unit
+system_ligand_has_oligosaccharide bool Whether the system has a ligand containing multiple saccharide units
+system_ligand_has_mononucleotide bool Whether the system has a ligand containing one nucleotide unit
+system_ligand_has_oligonucleotide bool Whether the system has a ligand containing multiple nucleotide units
+system_ligand_has_monopeptide bool Whether the system has a ligand containing one peptide unit
+system_ligand_has_oligopeptide bool Whether the system has a ligand containing multiple peptide units
+system_ligand_has_artifact bool Whether the system has an artifact ligand
+system_ligand_has_other bool Whether the system has a ligand classified as other
+system_ligand_has_covalent bool Whether the system has a covalent ligand
+system_ligand_has_invalid bool Whether the system has an invalid ligand
+system_ligand_has_ion bool Whether the system has an ion
+system_protein_chains_total_length int64 Total length of all receptor polymer chains in the system
+system_unique_ccd_codes string Distinct ligand CCD codes in the system
+system_proper_unique_ccd_codes string Distinct CCD codes of proper ligands in the system
+ligand_is_shape_comparable bool Whether the canonical ligand SDF supports finite shape, color, and SuCOS self-scoring
+system_pocket_CATH string Most frequent CATH mapping among pocket residues
+system_pocket_SCOP2B string Most frequent SCOP2B mapping among pocket residues
+system_pocket_Pfam string Most frequent Pfam mapping among pocket residues
+system_pocket_UniProt string Most frequent UniProt mapping among pocket residues
+ligand_neighboring_ligand_chains_asym_id list Chain asymmetric id
+ligand_interacting_ligand_chains_asym_id list Chain asymmetric id
+system_pocket_SCOP2 string Most frequent SCOP2 mapping among pocket residues
+ligand_smiles_id int32 Integer node ID assigned to this exact canonical SMILES for ligand similarity scoring
+ligand_max_cofactor_similarity float Maximum ECFP4/1024 Tanimoto similarity, as a percentage, to any CCD structure in the cofactor list
+ligand_most_similar_cofactor string CCD code of the cofactor with maximum ECFP4/1024 Tanimoto similarity
+ligand_is_cofactor_like bool Whether maximum similarity to a listed CCD cofactor is at least 90 percent
diff --git a/src/plinder/data/column_descriptions/tables/bindingdb_measurements.tsv b/src/plinder/data/column_descriptions/tables/bindingdb_measurements.tsv
new file mode 100644
index 000000000..971deeef6
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/bindingdb_measurements.tsv
@@ -0,0 +1,17 @@
+Name Type Description
+pdbid_ligid string PDB ID and ligand HET code reported in a BindingDB cross-reference
+pdb_id string PDB ID reported in a BindingDB ligand-target-complex cross-reference
+ligand_het_id string Ligand HET code reported by BindingDB
+reactant_set_id string BindingDB source reactant-set identifier, when provided
+monomer_id string BindingDB source monomer identifier, when provided
+curation_source string BindingDB curation or imported-data source
+article_doi string DOI of the source publication, when provided by BindingDB
+bindingdb_entry_doi string BindingDB DOI for the source entry, when provided
+source_row int64 Zero-based row number in the source BindingDB TSV
+target_sequences list All target-chain sequences reported for this measurement
+target_sequence string Target-chain sequence when exactly one was reported; otherwise missing
+endpoint string Measured affinity endpoint: Ki or Kd
+raw_value string BindingDB affinity value in nM, including any inequality sign
+relation string Equality or inequality for the pKi/pKd value; reversed from the nM inequality because the logarithmic scale is inverse
+value_nm double Numeric affinity value in nM without its inequality sign
+pchembl double pKi or pKd (9 - log10 of nM value), before censoring checks
diff --git a/src/plinder/data/column_descriptions/tables/entry_biounit_chains.tsv b/src/plinder/data/column_descriptions/tables/entry_biounit_chains.tsv
new file mode 100644
index 000000000..cc34c7207
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/entry_biounit_chains.tsv
@@ -0,0 +1,10 @@
+Name Type Description
+entry_pdb_id string RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html
+biounit_id string Biological assembly identifier
+chain_instance string Assembly chain instance encoded as .
+chain_asym_id string Chain asymmetric id
+chain_role string Assembly role: receptor, ligand, or water
+chain_num_contacting_ions int64 Number of ion chains contacting this assembly-chain instance
+chain_num_contacting_artifacts int64 Number of crystallization-artifact chains contacting this assembly-chain instance
+chain_num_contacting_other_ligands int64 Number of other ligand chains contacting this assembly-chain instance
+chain_num_contacting_proteins int64 Number of other polypeptide chains contacting this assembly-chain instance
diff --git a/src/plinder/data/column_descriptions/tables/entry_chains.tsv b/src/plinder/data/column_descriptions/tables/entry_chains.tsv
new file mode 100644
index 000000000..88eeb816d
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/entry_chains.tsv
@@ -0,0 +1,15 @@
+Name Type Description
+entry_pdb_id string RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html
+chain_asym_id string Chain asymmetric id
+chain_auth_id string Chain author id
+chain_entity_id string Chain entity id
+chain_type string Raw CIF receptor polymer type
+chain_receptor_type string Receptor polymer category: protein, dna, rna, or dna+rna
+chain_sequence string Full polymer sequence in one-letter code, keyed by the source asymmetric-chain ID
+chain_sequence_noncanonical string Full polymer sequence from _entity_poly.pdbx_seq_one_letter_code, with modified residues as (CCD) tokens
+chain_modified_residues list Non-canonical SEQRES monomers as {auth_seq}:{comp_id}:{asym}:{label_seq}>{parent} (details), the residue address of ligand_covalent_linkages (comp_id is entity_poly_seq.mon_id); unresolved positions have auth_seq ?; parent and details from _pdbx_struct_mod_residue, else the CCD parent
+chain_length int64 SEQRES length
+chain_num_unresolved_residues int64 Number of unresolved residues (SEQRES length - len(residues))
+chain_is_holo bool Whether the chain participates in a holo receptor or is excluded from the apo partition
+chain_is_ligand_like bool Whether this chain is ligand-like rather than an eligible receptor chain
+chain_uniprot_ids list UniProt accessions mapped to the chain
diff --git a/src/plinder/data/column_descriptions/tables/entry_metadata.tsv b/src/plinder/data/column_descriptions/tables/entry_metadata.tsv
new file mode 100644
index 000000000..f6466b958
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/entry_metadata.tsv
@@ -0,0 +1,33 @@
+Name Type Description
+entry_pdb_id string RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html
+entry_release_date string RCSB structure release date. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_database_PDB_rev.date_original.html
+entry_oligomeric_state string Author's provided description of quaternary structure in RCSB. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_pdbx_struct_assembly.oligomeric_details.html
+entry_determination_method string RCSB method of structure determination. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_exptl.method.html
+entry_keywords string RCSB keywords describing the structure. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_struct_keywords.pdbx_keywords.html
+entry_pH string pH at which structure is solved. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_exptl_crystal_grow.pH.html
+entry_pH_min double Lowest crystallization pH parsed from _exptl_crystal_grow (pH, pdbx_pH_range, or pdbx_details); null when none parses
+entry_pH_max double Highest crystallization pH parsed from _exptl_crystal_grow (pH, pdbx_pH_range, or pdbx_details); null when none parses
+entry_resolution double RCSB structure resolution. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_refine.ls_d_res_high.html
+entry_has_ligand_of_interest bool Depositor flag _pdbx_entry_details.has_ligand_of_interest (Y true, N false); null when absent, i.e. for most entries deposited before ~2019
+entry_source_taxonomy_ids list Distinct NCBI taxonomy IDs of the deposited entities' source organisms
+entry_source_organism_names list Distinct scientific names of the deposited entities' source organisms
+entry_host_taxonomy_ids list Distinct NCBI taxonomy IDs of recombinant expression hosts
+entry_host_organism_names list Distinct scientific names of recombinant expression hosts
+entry_failed_assembly_ids list Biological-assembly IDs that could not be built; their systems and interfaces are absent from this entry
+entry_validation_resolution double Resolution of the PDB entry
+entry_validation_rfree double The similarity between the observed structure-factor amplitudes and those calculated from the model. Rfree should be higher than R because it is calculated using reflections not used in the refinement. See https://www.wwpdb.org/validation/XrayValidationReportHelp
+entry_validation_r double The similarity between the observed structure-factor amplitudes and those calculated from the model. See https://www.wwpdb.org/validation/XrayValidationReportHelp
+entry_validation_clashscore double The Molprobity Clashscore is an approximation of the overall severity of the clashes in a structure, which is defined as the number of clashes per 1000 atoms (including hydrogens). See https://www.wwpdb.org/validation/XrayValidationReportHelp
+entry_validation_percent_rama_outliers double The percentage of Ramachandran outliers with respect to the total number of residues in the entry for which the outlier assessment is available. See https://www.wwpdb.org/validation/XrayValidationReportHelp
+entry_validation_percent_rota_outliers double The percentage of residues with an unusual sidechain conformation with respect to the total number of residues for which the assessment is available. See https://www.wwpdb.org/validation/XrayValidationReportHelp
+entry_validation_data_completeness double The number of expected diffraction spots is a function of data resolution and the space group. This metric describes the number of recorded reflections as a percentage of the number expected. See https://www.wwpdb.org/validation/XrayValidationReportHelp
+entry_validation_percent_RSRZ_outliers double The percentage Real-Space R-value Z-score outliers with respect to the total number of residues for which RSRZ was computed. See https://www.wwpdb.org/validation/XrayValidationReportHelp
+entry_validation_atom_count int64 Number of atoms in the asymmetric unit of the PDB entry
+entry_validation_molprobity double "Overall Molprobity ""effective resolution"", a single-score validation number based on the correlation of multiple criteria with crystallographic resolution. as described here: https://github.com/rlabduke/MolProbity/blob/6e7512e85bdea23f7ffb16e606d1f9a0abf6e5d4/cmdline/molparser.py#L662"
+entry_validation_mean_b_factor double Mean B-value calculated over all modelled atoms
+entry_validation_median_b_factor double Median B-value calculated over all modelled atoms
+entry_validation_pdbx_resolution double See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_refine.ls_d_res_high.html
+entry_validation_pdbx_reflns_resolution double See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_reflns.d_resolution_high.html
+entry_validation_meanI_over_sigI_obs double Each reflection has an intensity (I) and an uncertainty in measurement (ฯ(I)), thus this metric describes the signal-to-noise ratio
+entry_validation_r_minus_rfree double The difference between r and rfree
+entry_pass_validation_criteria bool Whether the entry passes validation criteria
diff --git a/src/plinder/data/column_descriptions/tables/entry_sources.tsv b/src/plinder/data/column_descriptions/tables/entry_sources.tsv
new file mode 100644
index 000000000..0081e41c3
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/entry_sources.tsv
@@ -0,0 +1,4 @@
+Name Type Description
+entry_pdb_id string RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html
+source_mmcif_major_revision int64 Major revision number of the source PDB mmCIF used during ingest
+source_mmcif_minor_revision int64 Minor revision number of the source PDB mmCIF used during ingest
diff --git a/src/plinder/data/column_descriptions/tables/interface_annotations.tsv b/src/plinder/data/column_descriptions/tables/interface_annotations.tsv
new file mode 100644
index 000000000..65afd95e8
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/interface_annotations.tsv
@@ -0,0 +1,23 @@
+Name Type Description
+entry_pdb_id string RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html
+system_id string ID of the system
+system_biounit_id string Biounit ID
+interface_chain_1 string First canonical assembly-chain instance
+interface_chain_2 string Second canonical assembly-chain instance
+interface_chain_1_residue_numbers list Source-mmCIF residue numbers at the interface on chain 1
+interface_chain_1_residue_indices list Zero-based resolved-chain indices corresponding positionally to chain 1 residue numbers
+interface_chain_2_residue_numbers list Source-mmCIF residue numbers at the interface on chain 2
+interface_chain_2_residue_indices list Zero-based resolved-chain indices corresponding positionally to chain 2 residue numbers
+interface_num_contact_residue_pairs int64 Number of residue pairs in contact across the protein interface
+interface_contact_area double Voronota-LT contact area in square angstroms between the two chains in the full biological assembly; null when the assembly tessellation was skipped or failed
+prodigy_is_annotated bool Whether PRODIGY-cryst features and a biological/crystal label are available
+prodigy_label string PRODIGY-cryst BIO or XTAL interface label
+prodigy_probability_bio float PRODIGY-cryst probability that the interface is biological
+prodigy_link_density float PRODIGY-cryst interface link-density feature
+prodigy_intermolecular_contacts double PRODIGY-cryst count of intermolecular atomic contacts
+prodigy_charged_charged_contacts double PRODIGY-cryst count of charged-charged contacts
+prodigy_charged_polar_contacts double PRODIGY-cryst count of charged-polar contacts
+prodigy_charged_apolar_contacts double PRODIGY-cryst count of charged-apolar contacts
+prodigy_polar_polar_contacts double PRODIGY-cryst count of polar-polar contacts
+prodigy_apolar_polar_contacts double PRODIGY-cryst count of apolar-polar contacts
+prodigy_apolar_apolar_contacts double PRODIGY-cryst count of apolar-apolar contacts
diff --git a/src/plinder/data/column_descriptions/tables/interface_apo_structures.tsv b/src/plinder/data/column_descriptions/tables/interface_apo_structures.tsv
new file mode 100644
index 000000000..2fed5e2ad
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/interface_apo_structures.tsv
@@ -0,0 +1,21 @@
+Name Type Description
+reference_system_id string Protein-interface system linked to this apo chain
+reference_side int8 Interface side linked to this apo chain: 1 or 2
+reference_chain_instance string Assembly-chain instance on the corresponding reference interface side
+reference_chain_asym_id string Source asymmetric-chain ID on the corresponding reference interface side
+linked_structure_id string Stable identifier for the linked apo chain
+source_entry_id string PDB entry containing the linked apo chain
+source_chain_asym_id string Source asymmetric-chain ID of the linked apo chain
+source_chain_auth_id string Author chain ID of the linked apo chain
+source_biounit_id string Source biological assembly containing the apo chain
+source_chain_instance string Exact biological-assembly chain instance that was scored
+source_num_contacting_proteins int16 Number of other protein chains contacting the apo chain
+source_num_contacting_ions int16 Number of ion chains contacting the apo chain
+source_num_contacting_artifacts int16 Number of crystallization-artifact chains contacting the apo chain
+source_num_contacting_other_ligands int16 Number of other ligand chains contacting the apo chain
+source_resolution float Experimental resolution of the apo source entry
+rank int16 Apo candidate rank for this reference interface side
+mmseqs_fident float MMseqs sequence identity between reference and apo chains
+mmseqs_query_coverage float Fraction of the reference chain covered by the MMseqs alignment
+mmseqs_target_coverage float Fraction of the apo chain covered by the MMseqs alignment
+foldseek_lddt float Foldseek local-distance difference test score for the same chain pair
diff --git a/src/plinder/data/column_descriptions/tables/interface_clusters.tsv b/src/plinder/data/column_descriptions/tables/interface_clusters.tsv
new file mode 100644
index 000000000..149415595
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/interface_clusters.tsv
@@ -0,0 +1,32 @@
+Name Type Description
+system_id string ID of the system
+interface_qcov__100__directed_set_cover large_string Cluster ID for directed set cover built from interface_qcov with 100 threshold; each member's query-to-centroid score meets the threshold
+interface_qcov__100__reciprocal_component large_string Full-graph component at interface_qcov 100 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+interface_qcov__30__directed_set_cover large_string Cluster ID for directed set cover built from interface_qcov with 30 threshold; each member's query-to-centroid score meets the threshold
+interface_qcov__30__reciprocal_component large_string Full-graph component at interface_qcov 30 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+interface_qcov__50__directed_set_cover large_string Cluster ID for directed set cover built from interface_qcov with 50 threshold; each member's query-to-centroid score meets the threshold
+interface_qcov__50__reciprocal_component large_string Full-graph component at interface_qcov 50 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+interface_qcov__70__directed_set_cover large_string Cluster ID for directed set cover built from interface_qcov with 70 threshold; each member's query-to-centroid score meets the threshold
+interface_qcov__70__reciprocal_component large_string Full-graph component at interface_qcov 70 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+interface_qcov__90__directed_set_cover large_string Cluster ID for directed set cover built from interface_qcov with 90 threshold; each member's query-to-centroid score meets the threshold
+interface_qcov__90__reciprocal_component large_string Full-graph component at interface_qcov 90 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+interface_side_qcov__100__chain_1_directed_set_cover large_string Cluster ID for chain 1 directed set cover built from interface_side_qcov with 100 threshold; each member's query-to-centroid score meets the threshold
+interface_side_qcov__100__chain_1_reciprocal_component large_string Full-graph component at interface_side_qcov 100 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+interface_side_qcov__100__chain_2_directed_set_cover large_string Cluster ID for chain 2 directed set cover built from interface_side_qcov with 100 threshold; each member's query-to-centroid score meets the threshold
+interface_side_qcov__100__chain_2_reciprocal_component large_string Full-graph component at interface_side_qcov 100 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+interface_side_qcov__30__chain_1_directed_set_cover large_string Cluster ID for chain 1 directed set cover built from interface_side_qcov with 30 threshold; each member's query-to-centroid score meets the threshold
+interface_side_qcov__30__chain_1_reciprocal_component large_string Full-graph component at interface_side_qcov 30 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+interface_side_qcov__30__chain_2_directed_set_cover large_string Cluster ID for chain 2 directed set cover built from interface_side_qcov with 30 threshold; each member's query-to-centroid score meets the threshold
+interface_side_qcov__30__chain_2_reciprocal_component large_string Full-graph component at interface_side_qcov 30 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+interface_side_qcov__50__chain_1_directed_set_cover large_string Cluster ID for chain 1 directed set cover built from interface_side_qcov with 50 threshold; each member's query-to-centroid score meets the threshold
+interface_side_qcov__50__chain_1_reciprocal_component large_string Full-graph component at interface_side_qcov 50 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+interface_side_qcov__50__chain_2_directed_set_cover large_string Cluster ID for chain 2 directed set cover built from interface_side_qcov with 50 threshold; each member's query-to-centroid score meets the threshold
+interface_side_qcov__50__chain_2_reciprocal_component large_string Full-graph component at interface_side_qcov 50 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+interface_side_qcov__70__chain_1_directed_set_cover large_string Cluster ID for chain 1 directed set cover built from interface_side_qcov with 70 threshold; each member's query-to-centroid score meets the threshold
+interface_side_qcov__70__chain_1_reciprocal_component large_string Full-graph component at interface_side_qcov 70 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+interface_side_qcov__70__chain_2_directed_set_cover large_string Cluster ID for chain 2 directed set cover built from interface_side_qcov with 70 threshold; each member's query-to-centroid score meets the threshold
+interface_side_qcov__70__chain_2_reciprocal_component large_string Full-graph component at interface_side_qcov 70 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+interface_side_qcov__90__chain_1_directed_set_cover large_string Cluster ID for chain 1 directed set cover built from interface_side_qcov with 90 threshold; each member's query-to-centroid score meets the threshold
+interface_side_qcov__90__chain_1_reciprocal_component large_string Full-graph component at interface_side_qcov 90 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+interface_side_qcov__90__chain_2_directed_set_cover large_string Cluster ID for chain 2 directed set cover built from interface_side_qcov with 90 threshold; each member's query-to-centroid score meets the threshold
+interface_side_qcov__90__chain_2_reciprocal_component large_string Full-graph component at interface_side_qcov 90 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
diff --git a/src/plinder/data/column_descriptions/tables/interface_half_representatives.tsv b/src/plinder/data/column_descriptions/tables/interface_half_representatives.tsv
new file mode 100644
index 000000000..8e1d61fa0
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/interface_half_representatives.tsv
@@ -0,0 +1,7 @@
+Name Type Description
+half_interface_id string Stable identifier for one representative interface side
+entry_pdb_id string RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html
+instance_chain_id string Assembly-chain instance forming this half-interface
+chain_asym_id string Chain asymmetric id
+residue_numbers list Source-mmCIF residue numbers in this half-interface
+residue_indices list Zero-based resolved-chain indices corresponding positionally to residue_numbers
diff --git a/src/plinder/data/column_descriptions/tables/interface_membership.tsv b/src/plinder/data/column_descriptions/tables/interface_membership.tsv
new file mode 100644
index 000000000..d1425cfec
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/interface_membership.tsv
@@ -0,0 +1,5 @@
+Name Type Description
+system_id string ID of the system
+representative_system_id string System ID selected as the representative for a ligand pocket or protein interface
+side_1_half_interface_id string Representative half-interface assigned to the first query side
+side_2_half_interface_id string Representative half-interface assigned to the second query side
diff --git a/src/plinder/data/column_descriptions/tables/interface_representatives.tsv b/src/plinder/data/column_descriptions/tables/interface_representatives.tsv
new file mode 100644
index 000000000..9fcc592e5
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/interface_representatives.tsv
@@ -0,0 +1,5 @@
+Name Type Description
+representative_system_id string System ID selected as the representative for a ligand pocket or protein interface
+entry_pdb_id string RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html
+half_interface_1_id string First half-interface of this representative
+half_interface_2_id string Second half-interface of this representative
diff --git a/src/plinder/data/column_descriptions/tables/ligand_affinity.tsv b/src/plinder/data/column_descriptions/tables/ligand_affinity.tsv
new file mode 100644
index 000000000..1a1ffbcf6
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/ligand_affinity.tsv
@@ -0,0 +1,6 @@
+Name Type Description
+ligand_id string Unique identifier of the ligand in the annotation table
+ligand_binding_affinity double Median pKi or pKd for uncensored BindingDB measurements with one endpoint and a target sequence matching this ligand's receptor; missing if ambiguous
+ligand_binding_affinity_endpoint string BindingDB endpoint (Ki or Kd) used for ligand_binding_affinity
+ligand_binding_affinity_measurement_count int64 Number of BindingDB measurements used for ligand_binding_affinity
+system_has_binding_affinity bool Whether any ligand in the system has an unambiguous, sequence-matched BindingDB affinity
diff --git a/src/plinder/data/column_descriptions/tables/ligand_clusters.tsv b/src/plinder/data/column_descriptions/tables/ligand_clusters.tsv
new file mode 100644
index 000000000..c905c742b
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/ligand_clusters.tsv
@@ -0,0 +1,111 @@
+Name Type Description
+ligand_id string Unique identifier for a given ligand.
+jaccard_similarity_mhfp6_2048__100__ligand__set_cover large_string Cluster ID for ligand-level set cover built from reciprocal-minimum MHFP6/2048 MinHash-estimated Jaccard similarity (Probst & Reymond 2018) with 100 threshold; each member has a direct threshold-qualified edge to its representative
+jaccard_similarity_mhfp6_2048__100__ligand__reciprocal_component large_string Full-graph component at jaccard_similarity_mhfp6_2048 100 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+jaccard_similarity_mhfp6_2048__100__ligand__set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level set-cover cluster built from jaccard_similarity_mhfp6_2048 with 100 threshold; missing means the row is outside the clustering universe
+jaccard_similarity_mhfp6_2048__30__ligand__set_cover large_string Cluster ID for ligand-level set cover built from reciprocal-minimum MHFP6/2048 MinHash-estimated Jaccard similarity (Probst & Reymond 2018) with 30 threshold; each member has a direct threshold-qualified edge to its representative
+jaccard_similarity_mhfp6_2048__30__ligand__reciprocal_component large_string Full-graph component at jaccard_similarity_mhfp6_2048 30 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+jaccard_similarity_mhfp6_2048__30__ligand__set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level set-cover cluster built from jaccard_similarity_mhfp6_2048 with 30 threshold; missing means the row is outside the clustering universe
+jaccard_similarity_mhfp6_2048__50__ligand__set_cover large_string Cluster ID for ligand-level set cover built from reciprocal-minimum MHFP6/2048 MinHash-estimated Jaccard similarity (Probst & Reymond 2018) with 50 threshold; each member has a direct threshold-qualified edge to its representative
+jaccard_similarity_mhfp6_2048__50__ligand__reciprocal_component large_string Full-graph component at jaccard_similarity_mhfp6_2048 50 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+jaccard_similarity_mhfp6_2048__50__ligand__set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level set-cover cluster built from jaccard_similarity_mhfp6_2048 with 50 threshold; missing means the row is outside the clustering universe
+jaccard_similarity_mhfp6_2048__70__ligand__set_cover large_string Cluster ID for ligand-level set cover built from reciprocal-minimum MHFP6/2048 MinHash-estimated Jaccard similarity (Probst & Reymond 2018) with 70 threshold; each member has a direct threshold-qualified edge to its representative
+jaccard_similarity_mhfp6_2048__70__ligand__reciprocal_component large_string Full-graph component at jaccard_similarity_mhfp6_2048 70 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+jaccard_similarity_mhfp6_2048__70__ligand__set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level set-cover cluster built from jaccard_similarity_mhfp6_2048 with 70 threshold; missing means the row is outside the clustering universe
+jaccard_similarity_mhfp6_2048__90__ligand__set_cover large_string Cluster ID for ligand-level set cover built from reciprocal-minimum MHFP6/2048 MinHash-estimated Jaccard similarity (Probst & Reymond 2018) with 90 threshold; each member has a direct threshold-qualified edge to its representative
+jaccard_similarity_mhfp6_2048__90__ligand__reciprocal_component large_string Full-graph component at jaccard_similarity_mhfp6_2048 90 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+ligand_jaccard_mhfp6_2048_90_cluster large_string Cluster ID from the 90-percent MHFP6/2048 Jaccard set cover; every member has a direct threshold-qualified edge to its representative
+ligand_jaccard_mhfp6_2048_90_cluster_num_pdb_ids int32 Number of distinct PDB entries represented in the ligand's 90-percent MHFP6/2048 Jaccard set-cover cluster
+jaccard_similarity_mhfp6_2048__90__ligand__set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level set-cover cluster built from jaccard_similarity_mhfp6_2048 with 90 threshold; missing means the row is outside the clustering universe
+tanimoto_similarity_ecfp4_1024__100__ligand__set_cover large_string Cluster ID for ligand-level set cover built from reciprocal-minimum ECFP4/1024 Tanimoto similarity with 100 threshold; each member has a direct threshold-qualified edge to its representative
+tanimoto_similarity_ecfp4_1024__100__ligand__reciprocal_component large_string Full-graph component at tanimoto_similarity_ecfp4_1024 100 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+tanimoto_similarity_ecfp4_1024__100__ligand__set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level set-cover cluster built from tanimoto_similarity_ecfp4_1024 with 100 threshold; missing means the row is outside the clustering universe
+tanimoto_similarity_ecfp4_1024__30__ligand__set_cover large_string Cluster ID for ligand-level set cover built from reciprocal-minimum ECFP4/1024 Tanimoto similarity with 30 threshold; each member has a direct threshold-qualified edge to its representative
+tanimoto_similarity_ecfp4_1024__30__ligand__reciprocal_component large_string Full-graph component at tanimoto_similarity_ecfp4_1024 30 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+tanimoto_similarity_ecfp4_1024__30__ligand__set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level set-cover cluster built from tanimoto_similarity_ecfp4_1024 with 30 threshold; missing means the row is outside the clustering universe
+tanimoto_similarity_ecfp4_1024__50__ligand__set_cover large_string Cluster ID for ligand-level set cover built from reciprocal-minimum ECFP4/1024 Tanimoto similarity with 50 threshold; each member has a direct threshold-qualified edge to its representative
+tanimoto_similarity_ecfp4_1024__50__ligand__reciprocal_component large_string Full-graph component at tanimoto_similarity_ecfp4_1024 50 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+tanimoto_similarity_ecfp4_1024__50__ligand__set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level set-cover cluster built from tanimoto_similarity_ecfp4_1024 with 50 threshold; missing means the row is outside the clustering universe
+tanimoto_similarity_ecfp4_1024__70__ligand__set_cover large_string Cluster ID for ligand-level set cover built from reciprocal-minimum ECFP4/1024 Tanimoto similarity with 70 threshold; each member has a direct threshold-qualified edge to its representative
+tanimoto_similarity_ecfp4_1024__70__ligand__reciprocal_component large_string Full-graph component at tanimoto_similarity_ecfp4_1024 70 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+tanimoto_similarity_ecfp4_1024__70__ligand__set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level set-cover cluster built from tanimoto_similarity_ecfp4_1024 with 70 threshold; missing means the row is outside the clustering universe
+tanimoto_similarity_ecfp4_1024__90__ligand__set_cover large_string Cluster ID for ligand-level set cover built from reciprocal-minimum ECFP4/1024 Tanimoto similarity with 90 threshold; each member has a direct threshold-qualified edge to its representative
+tanimoto_similarity_ecfp4_1024__90__ligand__reciprocal_component large_string Full-graph component at tanimoto_similarity_ecfp4_1024 90 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+ligand_tanimoto_ecfp4_1024_90_cluster large_string Cluster ID from the 90-percent ECFP4/1024 Tanimoto set cover; every member has a direct threshold-qualified edge to its representative
+ligand_tanimoto_ecfp4_1024_90_cluster_num_pdb_ids int32 Number of distinct PDB entries represented in the ligand's 90-percent ECFP4/1024 Tanimoto set-cover cluster
+tanimoto_similarity_ecfp4_1024__90__ligand__set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level set-cover cluster built from tanimoto_similarity_ecfp4_1024 with 90 threshold; missing means the row is outside the clustering universe
+pli_qcov__100__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from pli_qcov with 100 threshold; each member's query-to-centroid score meets the threshold
+pli_qcov__100__ligand__reciprocal_component large_string Full-graph component at pli_qcov 100 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+pli_qcov__100__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from pli_qcov with 100 threshold; missing means the row is outside the clustering universe
+pli_qcov__100__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at pli_qcov 100 threshold, including itself; missing means the row is outside the clustering universe
+pli_qcov__100__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at pli_qcov 100 threshold, including itself; missing means the row is outside the clustering universe
+pli_qcov__30__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from pli_qcov with 30 threshold; each member's query-to-centroid score meets the threshold
+pli_qcov__30__ligand__reciprocal_component large_string Full-graph component at pli_qcov 30 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+pli_qcov__30__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from pli_qcov with 30 threshold; missing means the row is outside the clustering universe
+pli_qcov__30__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at pli_qcov 30 threshold, including itself; missing means the row is outside the clustering universe
+pli_qcov__30__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at pli_qcov 30 threshold, including itself; missing means the row is outside the clustering universe
+pli_qcov__50__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from pli_qcov with 50 threshold; each member's query-to-centroid score meets the threshold
+pli_qcov__50__ligand__reciprocal_component large_string Full-graph component at pli_qcov 50 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+pli_qcov__50__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from pli_qcov with 50 threshold; missing means the row is outside the clustering universe
+pli_qcov__50__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at pli_qcov 50 threshold, including itself; missing means the row is outside the clustering universe
+pli_qcov__50__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at pli_qcov 50 threshold, including itself; missing means the row is outside the clustering universe
+pli_qcov__70__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from pli_qcov with 70 threshold; each member's query-to-centroid score meets the threshold
+pli_qcov__70__ligand__reciprocal_component large_string Full-graph component at pli_qcov 70 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+pli_qcov__70__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from pli_qcov with 70 threshold; missing means the row is outside the clustering universe
+pli_qcov__70__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at pli_qcov 70 threshold, including itself; missing means the row is outside the clustering universe
+pli_qcov__70__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at pli_qcov 70 threshold, including itself; missing means the row is outside the clustering universe
+pli_qcov__90__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from pli_qcov with 90 threshold; each member's query-to-centroid score meets the threshold
+pli_qcov__90__ligand__reciprocal_component large_string Full-graph component at pli_qcov 90 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+pli_qcov__90__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from pli_qcov with 90 threshold; missing means the row is outside the clustering universe
+pli_qcov__90__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at pli_qcov 90 threshold, including itself; missing means the row is outside the clustering universe
+pli_qcov__90__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at pli_qcov 90 threshold, including itself; missing means the row is outside the clustering universe
+pocket_qcov__100__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from pocket_qcov with 100 threshold; each member's query-to-centroid score meets the threshold
+pocket_qcov__100__ligand__reciprocal_component large_string Full-graph component at pocket_qcov 100 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+pocket_qcov__100__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from pocket_qcov with 100 threshold; missing means the row is outside the clustering universe
+pocket_qcov__100__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at pocket_qcov 100 threshold, including itself; missing means the row is outside the clustering universe
+pocket_qcov__100__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at pocket_qcov 100 threshold, including itself; missing means the row is outside the clustering universe
+pocket_qcov__30__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from pocket_qcov with 30 threshold; each member's query-to-centroid score meets the threshold
+pocket_qcov__30__ligand__reciprocal_component large_string Full-graph component at pocket_qcov 30 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+pocket_qcov__30__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from pocket_qcov with 30 threshold; missing means the row is outside the clustering universe
+pocket_qcov__30__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at pocket_qcov 30 threshold, including itself; missing means the row is outside the clustering universe
+pocket_qcov__30__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at pocket_qcov 30 threshold, including itself; missing means the row is outside the clustering universe
+pocket_qcov__50__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from pocket_qcov with 50 threshold; each member's query-to-centroid score meets the threshold
+pocket_qcov__50__ligand__reciprocal_component large_string Full-graph component at pocket_qcov 50 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+pocket_qcov__50__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from pocket_qcov with 50 threshold; missing means the row is outside the clustering universe
+pocket_qcov__50__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at pocket_qcov 50 threshold, including itself; missing means the row is outside the clustering universe
+pocket_qcov__50__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at pocket_qcov 50 threshold, including itself; missing means the row is outside the clustering universe
+pocket_qcov__70__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from pocket_qcov with 70 threshold; each member's query-to-centroid score meets the threshold
+pocket_qcov__70__ligand__reciprocal_component large_string Full-graph component at pocket_qcov 70 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+pocket_qcov__70__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from pocket_qcov with 70 threshold; missing means the row is outside the clustering universe
+pocket_qcov__70__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at pocket_qcov 70 threshold, including itself; missing means the row is outside the clustering universe
+pocket_qcov__70__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at pocket_qcov 70 threshold, including itself; missing means the row is outside the clustering universe
+pocket_qcov__90__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from pocket_qcov with 90 threshold; each member's query-to-centroid score meets the threshold
+pocket_qcov__90__ligand__reciprocal_component large_string Full-graph component at pocket_qcov 90 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+pocket_qcov__90__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from pocket_qcov with 90 threshold; missing means the row is outside the clustering universe
+pocket_qcov__90__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at pocket_qcov 90 threshold, including itself; missing means the row is outside the clustering universe
+pocket_qcov__90__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at pocket_qcov 90 threshold, including itself; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__100__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from sucos_shape_pocket_qcov with 100 threshold; each member's query-to-centroid score meets the threshold
+sucos_shape_pocket_qcov__100__ligand__reciprocal_component large_string Full-graph component at sucos_shape_pocket_qcov 100 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+sucos_shape_pocket_qcov__100__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from sucos_shape_pocket_qcov with 100 threshold; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__100__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at sucos_shape_pocket_qcov 100 threshold, including itself; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__100__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at sucos_shape_pocket_qcov 100 threshold, including itself; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__30__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from sucos_shape_pocket_qcov with 30 threshold; each member's query-to-centroid score meets the threshold
+sucos_shape_pocket_qcov__30__ligand__reciprocal_component large_string Full-graph component at sucos_shape_pocket_qcov 30 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+sucos_shape_pocket_qcov__30__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from sucos_shape_pocket_qcov with 30 threshold; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__30__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at sucos_shape_pocket_qcov 30 threshold, including itself; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__30__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at sucos_shape_pocket_qcov 30 threshold, including itself; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__50__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from sucos_shape_pocket_qcov with 50 threshold; each member's query-to-centroid score meets the threshold
+sucos_shape_pocket_qcov__50__ligand__reciprocal_component large_string Full-graph component at sucos_shape_pocket_qcov 50 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+sucos_shape_pocket_qcov__50__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from sucos_shape_pocket_qcov with 50 threshold; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__50__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at sucos_shape_pocket_qcov 50 threshold, including itself; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__50__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at sucos_shape_pocket_qcov 50 threshold, including itself; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__70__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from sucos_shape_pocket_qcov with 70 threshold; each member's query-to-centroid score meets the threshold
+sucos_shape_pocket_qcov__70__ligand__reciprocal_component large_string Full-graph component at sucos_shape_pocket_qcov 70 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+sucos_shape_pocket_qcov__70__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from sucos_shape_pocket_qcov with 70 threshold; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__70__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at sucos_shape_pocket_qcov 70 threshold, including itself; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__70__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at sucos_shape_pocket_qcov 70 threshold, including itself; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__90__ligand__directed_set_cover large_string Cluster ID for ligand-level directed set cover built from sucos_shape_pocket_qcov with 90 threshold; each member's query-to-centroid score meets the threshold
+sucos_shape_pocket_qcov__90__ligand__reciprocal_component large_string Full-graph component at sucos_shape_pocket_qcov 90 threshold; an edge requires similarity in both directions. Connected members may be linked through other members rather than directly
+sucos_shape_pocket_qcov__90__ligand__directed_set_cover__is_centroid bool Whether this row is the published centroid for its ligand-level directed set-cover cluster built from sucos_shape_pocket_qcov with 90 threshold; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__90__ligand__directed_set_cover__coverage_count int32 Number of directed-cover query nodes this ligand could initially cover at sucos_shape_pocket_qcov 90 threshold, including itself; missing means the row is outside the clustering universe
+sucos_shape_pocket_qcov__90__ligand__directed_set_cover__coverage_fraction float Fraction of its directed weak component this ligand could initially cover at sucos_shape_pocket_qcov 90 threshold, including itself; missing means the row is outside the clustering universe
diff --git a/src/plinder/data/column_descriptions/tables/ligand_mmp_pairs.tsv b/src/plinder/data/column_descriptions/tables/ligand_mmp_pairs.tsv
new file mode 100644
index 000000000..7afa70a1b
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/ligand_mmp_pairs.tsv
@@ -0,0 +1,13 @@
+Name Type Description
+ligand_smiles_id_1 int32 Unique-SMILES node ID for the first MMP ligand
+ligand_smiles_id_2 int32 Unique-SMILES node ID for the second MMP ligand
+ligand_smiles_1 string Canonical SMILES for the first MMP ligand
+ligand_smiles_2 string Canonical SMILES for the second MMP ligand
+transformation string MMP transformation directed from ligand 1 to ligand 2
+shared_core_smiles string Shared MMP core with attachment points marked by *
+num_cuts int8 Number of attachment points in the shared MMP core
+shared_core_num_heavy_atoms int16 Number of heavy atoms in the shared MMP core
+ligand_1_num_heavy_atoms int16 Number of heavy atoms in the first MMP ligand
+ligand_2_num_heavy_atoms int16 Number of heavy atoms in the second MMP ligand
+ligand_1_shared_core_fraction float Fraction of the first ligand's heavy atoms contained in the shared core
+ligand_2_shared_core_fraction float Fraction of the second ligand's heavy atoms contained in the shared core
diff --git a/src/plinder/data/column_descriptions/tables/ligand_pocket_membership.tsv b/src/plinder/data/column_descriptions/tables/ligand_pocket_membership.tsv
new file mode 100644
index 000000000..9511a556d
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/ligand_pocket_membership.tsv
@@ -0,0 +1,5 @@
+Name Type Description
+system_id string ID of the system
+ligand_id string Unique identifier for a given ligand.
+representative_system_id string System ID selected as the representative for a ligand pocket or protein interface
+representative_ligand_id string Ligand ID selected as the representative for a ligand-pocket group
diff --git a/src/plinder/data/column_descriptions/tables/ligand_pocket_representatives.tsv b/src/plinder/data/column_descriptions/tables/ligand_pocket_representatives.tsv
new file mode 100644
index 000000000..2f0133992
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/ligand_pocket_representatives.tsv
@@ -0,0 +1,10 @@
+Name Type Description
+representative_ligand_id string Ligand ID selected as the representative for a ligand-pocket group
+representative_system_id string System ID selected as the representative for a ligand pocket or protein interface
+entry_pdb_id string RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html
+ligand_asym_id string Ligand chain asymmetric id
+ligand_is_shape_comparable bool Whether the canonical ligand SDF supports finite shape, color, and SuCOS self-scoring
+receptor_set_id string Stable identifier for the representative set of receptor chains
+receptor_chain_asym_ids list Asymmetric-chain IDs in the representative receptor-chain set
+pocket_residues list Representative pocket residues encoded as asym ID, residue number, and zero-based resolved-chain index
+interactions list Representative protein-ligand interactions encoded with their receptor residue mapping and interaction type
diff --git a/src/plinder/data/column_descriptions/tables/ligand_pocket_residues.tsv b/src/plinder/data/column_descriptions/tables/ligand_pocket_residues.tsv
new file mode 100644
index 000000000..e38f29e5f
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/ligand_pocket_residues.tsv
@@ -0,0 +1,12 @@
+Name Type Description
+entry_pdb_id string RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html
+system_id string ID of the system
+ligand_id string Unique identifier for a given ligand.
+chain_instance string Assembly chain instance encoded as .
+chain_asym_id string Chain asymmetric id
+chain_auth_id string Chain author id
+residue_label_seq_id int32 Receptor residue number from _atom_site.label_seq_id
+residue_index int32 Zero-based position among resolved residues in the chain
+residue_auth_seq_id string Depositor-provided receptor residue number from _atom_site.auth_seq_id
+residue_insertion_code string Depositor-provided receptor residue insertion code, or . when absent
+is_pli bool Whether this pocket residue participates in a detected protein-ligand interaction
diff --git a/src/plinder/data/column_descriptions/tables/linked_apo_structures.tsv b/src/plinder/data/column_descriptions/tables/linked_apo_structures.tsv
new file mode 100644
index 000000000..00eb6a59f
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/linked_apo_structures.tsv
@@ -0,0 +1,19 @@
+Name Type Description
+reference_system_id string Holo PLINDER system linked to this apo chain
+linked_structure_id string Stable identifier for the linked apo chain
+source_entry_id string PDB entry containing the linked apo chain
+source_chain_asym_id string Source asymmetric-chain ID of the linked apo chain
+source_chain_auth_id string Author chain ID of the linked apo chain
+source_biounit_id string Source biological assembly containing the apo chain
+source_chain_instance string Exact biological-assembly chain instance that was scored
+source_num_contacting_ions int16 Number of ion chains contacting the apo chain
+source_num_contacting_artifacts int16 Number of crystallization-artifact chains contacting the apo chain
+source_num_contacting_other_ligands int16 Number of other ligand chains contacting the apo chain
+source_resolution float Experimental resolution of the apo source entry
+rank int16 Apo candidate rank within the reference holo system
+num_ligand_pockets int16 Number of holo ligand pockets matched by this apo chain
+min_pocket_fident int8 Minimum pocket sequence identity across matched ligands
+mean_pocket_fident float Mean pocket sequence identity across matched ligands
+min_protein_fident_weighted_sum int8 Minimum chain-length-weighted protein sequence identity across matched ligands
+min_protein_fident_qcov_weighted_sum int8 Minimum chain-length-weighted protein identity times query coverage across matched ligands
+min_protein_lddt_weighted_sum int8 Minimum chain-length-weighted protein LDDT across matched ligands
diff --git a/src/plinder/data/column_descriptions/tables/protein_sequence_clusters.tsv b/src/plinder/data/column_descriptions/tables/protein_sequence_clusters.tsv
new file mode 100644
index 000000000..24b29fa10
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/protein_sequence_clusters.tsv
@@ -0,0 +1,7 @@
+Name Type Description
+entry_pdb_id string RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html
+chain_asym_id string Chain asymmetric id
+representative_entry_pdb_id string PDB entry containing the protein-cluster representative; together with representative_chain_asym_id identifies the cluster
+representative_chain_asym_id string Source label_asym_id of the protein-cluster representative; missing when the chain could not be clustered
+is_representative bool Whether this protein chain is its cluster representative; missing when the chain could not be clustered
+status string Protein clustering outcome: clustered, weekly_assigned (searched against fixed representatives), missing_sequence (MMseqs), or not_in_foldseek_db (Foldseek did not extract this chain from the deposited structure)
diff --git a/src/plinder/data/column_descriptions/tables/protein_structure_clusters.tsv b/src/plinder/data/column_descriptions/tables/protein_structure_clusters.tsv
new file mode 100644
index 000000000..24b29fa10
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/protein_structure_clusters.tsv
@@ -0,0 +1,7 @@
+Name Type Description
+entry_pdb_id string RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html
+chain_asym_id string Chain asymmetric id
+representative_entry_pdb_id string PDB entry containing the protein-cluster representative; together with representative_chain_asym_id identifies the cluster
+representative_chain_asym_id string Source label_asym_id of the protein-cluster representative; missing when the chain could not be clustered
+is_representative bool Whether this protein chain is its cluster representative; missing when the chain could not be clustered
+status string Protein clustering outcome: clustered, weekly_assigned (searched against fixed representatives), missing_sequence (MMseqs), or not_in_foldseek_db (Foldseek did not extract this chain from the deposited structure)
diff --git a/src/plinder/data/column_descriptions/tables/system_validation.tsv b/src/plinder/data/column_descriptions/tables/system_validation.tsv
new file mode 100644
index 000000000..dfa512aa9
--- /dev/null
+++ b/src/plinder/data/column_descriptions/tables/system_validation.tsv
@@ -0,0 +1,42 @@
+Name Type Description
+system_id string ID of the system
+system_ligand_validation_num_residues double Number of residues in the list
+system_ligand_validation_num_processed_residues double Number of processed residues in the list
+system_ligand_validation_percent_processed_residues double Percentage of processed residues in the list
+system_ligand_validation_average_rsr double Average Real-Space R-value across all residues in the list
+system_ligand_validation_average_rsrz double Average Real-Space R-value Z-score across all residues in the list
+system_ligand_validation_average_rscc double Average Real-Space Correlation Coefficient across all residues in the list
+system_ligand_validation_average_occupancy double Average occupancy across all residues in the list
+system_ligand_validation_percent_rsr_under_threshold double Percentage of residues with RSR under the threshold
+system_ligand_validation_percent_rscc_over_threshold double Percentage of residues with RSCC over the threshold
+system_ligand_validation_percent_occupancy_over_threshold double Percentage of residues with occupancy over the threshold
+system_ligand_validation_average_b_factor double Average B factor across all residues in the list
+system_ligand_validation_unknown_residue_count double Number of unknown residues in the list
+system_ligand_validation_atom_count double Number of atoms across all residues in the list
+system_ligand_validation_heavy_atom_count double Number of heavy atoms across all residues in the list
+system_ligand_validation_num_unresolved_heavy_atoms double Number of unresolved heavy atoms across all residues in the list; null if any residue's count is unavailable or inconsistent
+system_ligand_validation_max_alt_count double The highest number of configurations in a single residue in the list
+system_ligand_validation_percent_outliers_geometry double Percentage of residues with geometry outliers
+system_ligand_validation_percent_outliers_density double Percentage of residues with density outliers
+system_ligand_validation_percent_outliers_chirality double Percentage of residues with chirality outliers
+system_ligand_validation_percent_outliers_clashes double Percentage of residues with clashes outliers
+system_pocket_validation_num_residues double Number of residues in the list
+system_pocket_validation_num_processed_residues double Number of processed residues in the list
+system_pocket_validation_percent_processed_residues double Percentage of processed residues in the list
+system_pocket_validation_average_rsr double Average Real-Space R-value across all residues in the list
+system_pocket_validation_average_rsrz double Average Real-Space R-value Z-score across all residues in the list
+system_pocket_validation_average_rscc double Average Real-Space Correlation Coefficient across all residues in the list
+system_pocket_validation_average_occupancy double Average occupancy across all residues in the list
+system_pocket_validation_percent_rsr_under_threshold double Percentage of residues with RSR under the threshold
+system_pocket_validation_percent_rscc_over_threshold double Percentage of residues with RSCC over the threshold
+system_pocket_validation_percent_occupancy_over_threshold double Percentage of residues with occupancy over the threshold
+system_pocket_validation_average_b_factor double Average B factor across all residues in the list
+system_pocket_validation_unknown_residue_count double Number of unknown residues in the list
+system_pocket_validation_atom_count double Number of atoms across all residues in the list
+system_pocket_validation_heavy_atom_count double Number of heavy atoms across all residues in the list
+system_pocket_validation_num_unresolved_heavy_atoms double Number of unresolved heavy atoms across all residues in the list; null if any residue's count is unavailable or inconsistent
+system_pocket_validation_max_alt_count double The highest number of configurations in a single residue in the list
+system_pocket_validation_percent_outliers_geometry double Percentage of residues with geometry outliers
+system_pocket_validation_percent_outliers_density double Percentage of residues with density outliers
+system_pocket_validation_percent_outliers_chirality double Percentage of residues with chirality outliers
+system_pocket_validation_percent_outliers_clashes double Percentage of residues with clashes outliers
diff --git a/src/plinder/data/common/_version.py b/src/plinder/data/common/_version.py
deleted file mode 100644
index 2bc0efc66..000000000
--- a/src/plinder/data/common/_version.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
diff --git a/src/plinder/data/common/constants.py b/src/plinder/data/common/constants.py
deleted file mode 100644
index 1d4940343..000000000
--- a/src/plinder/data/common/constants.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from plinder.core.utils.log import setup_logger
-
-LOG = setup_logger(__name__)
-
-LOG.warning(
- "This module is deprecated. Please use plinder.core.utils.constants instead."
-)
diff --git a/src/plinder/data/common/log.py b/src/plinder/data/common/log.py
deleted file mode 100644
index fbecd5823..000000000
--- a/src/plinder/data/common/log.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from plinder.core.utils.log import setup_logger
-
-LOG = setup_logger(__name__)
-
-LOG.warning("This module is deprecated. Please use plinder.core.utils.log instead.")
diff --git a/src/plinder/data/databases.py b/src/plinder/data/databases.py
index 2cf930b35..16846291f 100644
--- a/src/plinder/data/databases.py
+++ b/src/plinder/data/databases.py
@@ -1,23 +1,33 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
-import json
+import hashlib
+import os
+import shutil
import subprocess as sp
+from collections.abc import Iterable, Iterator
from pathlib import Path
-from typing import TYPE_CHECKING, Dict, Optional
-
-import pandas as pd
+from typing import TYPE_CHECKING, Any, Dict, Optional
+from plinder.core.utils.files import (
+ link_or_copy_file,
+ read_json_cache,
+ write_json_atomic,
+)
from plinder.core.utils.log import setup_logger
if TYPE_CHECKING:
- from plinder.data.utils.annotations.aggregate_annotations import Entry
+ from plinder.core.scores.entries import EntryView
LOG = setup_logger(__name__)
+EXACT_CLUSTER_IDENTITY = 1.0
+EXACT_CLUSTER_COVERAGE = 1.0
+DATABASE_RUNTIME_DIRECTORIES = {"aln", "mapped_aln"}
+
-def run(cmd: list[str]) -> None:
+def run(cmd: list[str], *, cwd: Path | None = None) -> None:
LOG.info(" ".join(cmd))
- sp.check_call(cmd, stderr=sp.STDOUT)
+ sp.check_call(cmd, stderr=sp.STDOUT, cwd=cwd)
def make_db(
@@ -25,6 +35,7 @@ def make_db(
output_dir: Path,
db: str,
tmp_dir: Path = Path("tmp"),
+ threads: int = 1,
) -> None:
"""
Create full databases. input_dir is a misnomer
@@ -36,35 +47,585 @@ def make_db(
Parameters
----------
input_dir : Path
- location of input files for database
- (foldseek: input_dir = adir [/ **/*-enrich.cif.gz] for apo/holo and [/AF-*-F1-model_v4.cif] for pred)
- (mmseqs: input_dir = adir / seqres / pdb_seqres.txt.gz for apo/holo and / uniprot / pdb_uniprot.txt.gz for pred)
+ Input file or directory. Foldseek accepts coordinate files such as
+ ``*-enrich.cif.gz`` for apo/holo structures and
+ ``AF-*-F1-model_v4.cif`` for predicted structures. MMseqs accepts a
+ sequence file such as ``pdb_seqres.txt.gz`` or
+ ``pdb_uniprot.txt.gz``.
output_dir : Path
location of full final database (including file name)
db : str
name of db in ["foldseek", "mmseqs"]
tmp_dir : Path, default=Path("tmp")
scratch directory
+ threads : int, default=1
+ Maximum number of threads used by Foldseek or MMseqs.
"""
+ create_db(input_dir, output_dir, db, threads=threads)
+ create_db_index(output_dir, db, tmp_dir=tmp_dir, threads=threads)
+
+
+def create_db(
+ input_dir: Path,
+ output_dir: Path,
+ db: str,
+ *,
+ threads: int = 1,
+) -> None:
+ """Create a Foldseek/MMseqs database without indexing it."""
full_db = str(output_dir / db)
output_dir.mkdir(exist_ok=True, parents=True)
+ _remove_database_prefix(Path(full_db))
cmd = [
db,
"createdb",
str(input_dir),
full_db,
+ "--threads",
+ str(threads),
]
if db == "foldseek":
- cmd.extend(["--chain-name-mode", "1"])
+ # Foldseek only needs one coordinate per residue. Make the compact
+ # C-alpha/delta representation explicit so a future default change
+ # cannot inflate the build or portable search database.
+ cmd.extend(["--chain-name-mode", "1", "--coord-store-mode", "2"])
run(cmd)
+
+
+def create_db_index(
+ output_dir: Path,
+ db: str,
+ *,
+ tmp_dir: Path = Path("tmp"),
+ threads: int = 1,
+) -> None:
+ """Index an existing Foldseek/MMseqs database."""
+ full_db = str(output_dir / db)
run(
[
db,
"createindex",
full_db,
str(tmp_dir) + f"_{db}",
+ "--threads",
+ str(threads),
+ ]
+ )
+
+
+def _database_files_exist(database: Path, aln_type: str) -> bool:
+ """Return whether the minimum files for a sequence/structure DB exist."""
+ required = [database.with_suffix(".dbtype")]
+ if aln_type == "foldseek":
+ required.extend(
+ [
+ Path(f"{database}_ss.dbtype"),
+ Path(f"{database}_ca.dbtype"),
+ ]
+ )
+ return all(path.is_file() for path in required)
+
+
+def created_database_is_complete(database: Path, aln_type: str) -> bool:
+ """Return whether ``createdb`` finished all lookup and data outputs."""
+ return _database_files_exist(database, aln_type) and all(
+ path.is_file()
+ for path in [database.with_suffix(".index"), database.with_suffix(".lookup")]
+ )
+
+
+def install_database_directory(
+ source: Path,
+ target: Path,
+ *,
+ preserve_directories: tuple[str, ...] = (),
+) -> None:
+ """Copy a completed scratch DB and swap it into shared storage.
+
+ Generated search results can share a backend directory with its target
+ database. ``preserve_directories`` moves those directories through the
+ atomic swap instead of copying them to scratch or deleting them with the
+ retired database generation.
+ """
+ staging = target.parent / f".{target.name}.installing"
+ backup = target.parent / f".{target.name}.previous"
+ target.parent.mkdir(exist_ok=True, parents=True)
+ if backup.exists() and not target.exists():
+ backup.rename(target)
+ for path in [staging, backup]:
+ if path.exists():
+ shutil.rmtree(path)
+ shutil.copytree(source, staging, symlinks=True)
+ _make_database_directory_portable(staging)
+ if target.exists():
+ target.rename(backup)
+ try:
+ for name in preserve_directories:
+ preserved = backup / name
+ if not preserved.exists():
+ continue
+ destination = staging / name
+ if destination.exists():
+ raise FileExistsError(
+ f"cannot preserve {preserved}: {destination} already exists"
+ )
+ preserved.rename(destination)
+ staging.rename(target)
+ except BaseException:
+ for name in preserve_directories:
+ preserved = staging / name
+ destination = backup / name
+ if preserved.exists() and backup.exists() and not destination.exists():
+ preserved.rename(destination)
+ if backup.exists() and not target.exists():
+ backup.rename(target)
+ raise
+ if backup.exists():
+ shutil.rmtree(backup)
+
+
+def _remove_database_prefix(database: Path) -> None:
+ """Remove one generated MMseqs/Foldseek DB and all of its side files."""
+ for path in database.parent.glob(f"{database.name}*"):
+ if path.is_dir() and not path.is_symlink():
+ shutil.rmtree(path)
+ else:
+ path.unlink(missing_ok=True)
+
+
+def _database_bundle_paths(root: Path) -> Iterator[Path]:
+ """Iterate database assets without walking large runtime result trees."""
+ for current, directories, filenames in os.walk(root, topdown=True):
+ current_path = Path(current)
+ if current_path == root:
+ directories[:] = [
+ name for name in directories if name not in DATABASE_RUNTIME_DIRECTORIES
+ ]
+ yield from (current_path / name for name in directories)
+ yield from (current_path / name for name in filenames)
+
+
+def _make_database_directory_portable(root: Path) -> dict[str, int]:
+ """Replace external DB links with copies and internal links with relatives."""
+ root_resolved = root.resolve()
+ copied = 0
+ relativized = 0
+ for path in sorted(_database_bundle_paths(root)):
+ if not path.is_symlink():
+ continue
+ target = path.resolve(strict=True)
+ path.unlink()
+ if target.is_relative_to(root_resolved):
+ # Compute the relative link against the *resolved* parent: target is
+ # already canonicalized by resolve(), and on macOS the raw parent may
+ # still carry the /var -> /private/var symlink. Mixing the two makes
+ # relpath walk up to '/' and back down (../../private/var/...), an
+ # absolute-in-disguise link that breaks once copytree moves it.
+ # os.path.relpath (not Path.relative_to(walk_up=)) for ../ links: walk_up is 3.12+, project is 3.10+.
+ path.symlink_to(
+ os.path.relpath(target, start=path.parent.resolve()),
+ target_is_directory=target.is_dir(),
+ )
+ relativized += 1
+ elif target.is_dir():
+ shutil.copytree(target, path)
+ copied += 1
+ else:
+ shutil.copy2(target, path)
+ copied += 1
+ return {"external_links_copied": copied, "internal_links_relativized": relativized}
+
+
+def _has_external_database_links(
+ root: Path,
+ *,
+ paths: Iterable[Path] | None = None,
+) -> bool:
+ """Return whether selected database paths contain non-portable links.
+
+ ``paths`` bounds the check to a release bundle. This avoids recursively
+ walking large raw-alignment directories that are deliberately excluded
+ from published search databases.
+ """
+ root_resolved = root.resolve()
+ candidates = _database_bundle_paths(root) if paths is None else paths
+ for path in candidates:
+ if not path.is_symlink():
+ continue
+ if path.readlink().is_absolute():
+ return True
+ try:
+ target = path.resolve(strict=True)
+ except FileNotFoundError:
+ return True
+ if not target.is_relative_to(root_resolved):
+ return True
+ return False
+
+
+def _search_database_bundle_sources(
+ source_root: Path,
+ manifest: dict[str, Any],
+ aln_type: str,
+) -> set[Path]:
+ """Return only the files required by a published custom-search bundle."""
+ values = [manifest.get("search_target"), manifest.get("conversion_target")]
+ if aln_type == "mmseqs":
+ values.append(manifest.get("cluster_alignments"))
+ if any(
+ not isinstance(value, str) or not value or Path(value).name != value
+ for value in values
+ ):
+ raise ValueError(
+ f"unsafe database prefix in {source_root / 'exact_cluster.json'}"
+ )
+ prefixes = {value for value in values if isinstance(value, str)}
+ sources: set[Path] = set()
+ for prefix in prefixes:
+ sources.update(
+ path
+ for path in source_root.glob(f"{prefix}*")
+ if path.is_file() or path.is_symlink()
+ )
+ return sources
+
+
+def publish_search_database_bundle(
+ *,
+ source_root: Path,
+ target_root: Path,
+ aln_type: str,
+) -> dict[str, int | str]:
+ """Atomically publish the portable files needed for custom searches.
+
+ The full Foldseek source database and exact-clustering build artifacts are
+ not needed after ``createclusearchdb``. MMseqs retains its full target and
+ representative-to-member alignments because ``expandaln`` followed by
+ member-level ``align`` requires both.
+ """
+ if aln_type not in {"foldseek", "mmseqs"}:
+ raise ValueError(f"unsupported alignment type: {aln_type}")
+ full_db = source_root / source_root.name
+ manifest = _completed_exact_search_manifest(full_db, aln_type)
+ if manifest is None:
+ raise ValueError(f"incomplete exact-cluster database: {source_root}")
+
+ sources = _search_database_bundle_sources(source_root, manifest, aln_type)
+ if _has_external_database_links(source_root, paths=sources):
+ raise ValueError(f"non-portable database links in {source_root}")
+
+ staging = target_root.parent / f".{target_root.name}.installing"
+ backup = target_root.parent / f".{target_root.name}.previous"
+ target_root.parent.mkdir(exist_ok=True, parents=True)
+ for path in (staging, backup):
+ if path.exists():
+ shutil.rmtree(path)
+ staging.mkdir()
+ try:
+ for source in sorted(sources):
+ link_or_copy_file(source, staging / source.name)
+ if _has_external_database_links(staging):
+ raise ValueError(f"published database bundle is not portable: {staging}")
+ if target_root.exists():
+ target_root.rename(backup)
+ staging.rename(target_root)
+ except BaseException:
+ if staging.exists():
+ shutil.rmtree(staging)
+ if backup.exists() and not target_root.exists():
+ backup.rename(target_root)
+ raise
+ if backup.exists():
+ shutil.rmtree(backup)
+
+ regular_files = [path for path in target_root.iterdir() if path.is_file()]
+ return {
+ "alignment_type": aln_type,
+ "file_count": len(regular_files),
+ "apparent_size": sum(path.stat().st_size for path in regular_files),
+ "search_target": str(manifest["search_target"]),
+ "conversion_target": str(manifest["conversion_target"]),
+ }
+
+
+def _path_signature(path: Path, *, portable: bool = False) -> dict[str, int | str]:
+ stat = path.stat()
+ signature: dict[str, int | str] = {
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ }
+ signature["name" if portable else "path"] = (
+ path.name if portable else str(path.resolve())
+ )
+ return signature
+
+
+def _identifier_digest(identifiers: set[str]) -> str:
+ digest = hashlib.sha256()
+ for identifier in sorted(identifiers):
+ digest.update(identifier.encode())
+ digest.update(b"\n")
+ return digest.hexdigest()
+
+
+def _database_content_signature(database: Path) -> dict[str, int | str]:
+ """Hash the selected database files without including their location."""
+ files = sorted(
+ path for path in database.parent.glob(f"{database.name}*") if path.is_file()
+ )
+ if not files:
+ raise FileNotFoundError(f"missing selected database files: {database}")
+ digest = hashlib.sha256()
+ total_size = 0
+ for path in files:
+ size = path.stat().st_size
+ total_size += size
+ digest.update(path.name.removeprefix(database.name).encode())
+ digest.update(b"\0")
+ with path.open("rb") as handle:
+ while chunk := handle.read(1024 * 1024):
+ digest.update(chunk)
+ digest.update(b"\n")
+ return {
+ "file_count": len(files),
+ "size": total_size,
+ "sha256": digest.hexdigest(),
+ }
+
+
+def _database_entry_count(database: Path) -> int:
+ with database.with_suffix(".index").open("rb") as handle:
+ return sum(1 for _ in handle)
+
+
+def database_identifiers(database: Path) -> set[str]:
+ """Return identifiers for records actually selected into a database."""
+ lookup = {}
+ with database.with_suffix(".lookup").open() as handle:
+ for line in handle:
+ fields = line.split()
+ if len(fields) >= 2:
+ lookup[fields[0]] = fields[1]
+ selected = set()
+ with database.with_suffix(".index").open() as handle:
+ for line in handle:
+ fields = line.split()
+ if fields and fields[0] in lookup:
+ selected.add(lookup[fields[0]])
+ return selected
+
+
+def exact_search_database_paths(
+ db_dir: Path,
+ search_db: str,
+ aln_type: str,
+) -> tuple[Path, Path, Path | None]:
+ """Return full target, representative target and expansion alignment DB."""
+ root = db_dir / f"{search_db}_{aln_type}"
+ full_target = root / root.name
+ if aln_type == "foldseek":
+ return full_target, root / "clustered", None
+ if aln_type == "mmseqs":
+ return full_target, root / "representatives", root / "cluster_alignments"
+ raise ValueError(f"unsupported alignment type: {aln_type}")
+
+
+def _completed_exact_search_manifest(
+ full_db: Path, aln_type: str
+) -> dict[str, Any] | None:
+ """Return a valid exact-cluster manifest without mutating its database."""
+ root = full_db.parent
+ manifest = read_json_cache(root / "exact_cluster.json")
+ try:
+ source_signature = _path_signature(full_db.with_suffix(".index"), portable=True)
+ except OSError:
+ return None
+ expected = {
+ "alignment_type": aln_type,
+ "identity": EXACT_CLUSTER_IDENTITY,
+ "coverage": EXACT_CLUSTER_COVERAGE,
+ "coverage_mode": 0,
+ "source_index": source_signature,
+ "portable": True,
+ "compressed_search_target": False,
+ }
+ search_target = root / (
+ "clustered" if aln_type == "foldseek" else "representatives"
+ )
+ expected["search_target"] = search_target.name
+ expected["conversion_target"] = (
+ search_target.name if aln_type == "foldseek" else full_db.name
+ )
+ expected_outputs = [
+ search_target.with_suffix(".dbtype"),
+ Path(f"{search_target}.idx.dbtype"),
+ ]
+ if aln_type == "mmseqs":
+ expected["cluster_alignments"] = "cluster_alignments"
+ expected_outputs.append((root / "cluster_alignments").with_suffix(".dbtype"))
+ if (
+ manifest is None
+ or not all(manifest.get(key) == value for key, value in expected.items())
+ or not all(path.is_file() for path in expected_outputs)
+ ):
+ return None
+ try:
+ sources = _search_database_bundle_sources(root, manifest, aln_type)
+ except (KeyError, TypeError, ValueError):
+ return None
+ if _has_external_database_links(root, paths=sources):
+ return None
+ return manifest
+
+
+def make_exact_search_db(
+ *,
+ full_db: Path,
+ aln_type: str,
+ tmp_dir: Path,
+ threads: int,
+) -> dict[str, Any]:
+ """Build and index an exactly deduplicated, expandable search target.
+
+ The search cap is applied to representatives. Foldseek's native cluster
+ search realigns every expanded structure. MMseqs uses a representative
+ search followed by ``expandaln`` and a final member-level ``align``.
+ """
+ if aln_type not in {"foldseek", "mmseqs"}:
+ raise ValueError(f"unsupported alignment type: {aln_type}")
+ if not _database_files_exist(full_db, aln_type):
+ raise FileNotFoundError(f"missing full {aln_type} target DB: {full_db}")
+
+ root = full_db.parent
+ manifest_path = root / "exact_cluster.json"
+ source_signature = _path_signature(full_db.with_suffix(".index"), portable=True)
+ expected = {
+ "alignment_type": aln_type,
+ "identity": EXACT_CLUSTER_IDENTITY,
+ "coverage": EXACT_CLUSTER_COVERAGE,
+ "coverage_mode": 0,
+ "source_index": source_signature,
+ "portable": True,
+ "compressed_search_target": False,
+ }
+ search_target = root / (
+ "clustered" if aln_type == "foldseek" else "representatives"
+ )
+ expansion_db = root / "cluster_alignments" if aln_type == "mmseqs" else None
+ manifest = _completed_exact_search_manifest(full_db, aln_type)
+ if manifest is not None:
+ return manifest
+
+ clusters = root / "exact_clusters"
+ representatives = root / "representatives"
+ cluster_alignments = root / "cluster_alignments"
+ clustered = root / "clustered"
+ for database in [clusters, representatives, cluster_alignments, clustered]:
+ _remove_database_prefix(database)
+ manifest_path.unlink(missing_ok=True)
+ tmp_dir.mkdir(exist_ok=True, parents=True)
+
+ run(
+ [
+ aln_type,
+ "linclust",
+ str(full_db),
+ str(clusters),
+ str(tmp_dir / "linclust"),
+ "--min-seq-id",
+ str(EXACT_CLUSTER_IDENTITY),
+ "-c",
+ str(EXACT_CLUSTER_COVERAGE),
+ "--cov-mode",
+ "0",
+ "--threads",
+ str(threads),
]
)
+ if aln_type == "foldseek":
+ # Foldseek 10.941's cluster-search expansion segfaults in
+ # mergeresultsbyset for compressed createclusearchdb targets.
+ run(
+ [
+ "foldseek",
+ "createclusearchdb",
+ str(full_db),
+ str(clusters),
+ str(clustered),
+ "--threads",
+ str(threads),
+ "--compressed",
+ "0",
+ ]
+ )
+ search_target = clustered
+ else:
+ run(
+ [
+ "mmseqs",
+ "createsubdb",
+ str(clusters),
+ str(full_db),
+ str(representatives),
+ "--subdb-mode",
+ "0",
+ ]
+ )
+ # expandaln needs representative-to-member alignments, not only the
+ # key-only cluster membership emitted by linclust. Do not repeat the
+ # exact-clustering thresholds here: linclust can cluster sequences
+ # with terminal X residues that MMseqs cannot align at 100% coverage.
+ # This database is only an expansion map; the post-expansion align
+ # below applies the configured search e-value and coverage filters.
+ run(
+ [
+ "mmseqs",
+ "align",
+ str(representatives),
+ str(full_db),
+ str(clusters),
+ str(cluster_alignments),
+ "-a",
+ "-e",
+ "1e100",
+ "--add-self-matches",
+ "1",
+ "--threads",
+ str(threads),
+ ]
+ )
+ search_target = representatives
+
+ run(
+ [
+ aln_type,
+ "createindex",
+ search_target.name,
+ str((tmp_dir / "index").resolve()),
+ "--threads",
+ str(threads),
+ ],
+ cwd=root,
+ )
+ link_report = _make_database_directory_portable(root)
+ member_count = _database_entry_count(full_db)
+ representative_count = _database_entry_count(search_target)
+ payload = {
+ **expected,
+ "search_target": search_target.name,
+ "conversion_target": (
+ search_target.name if aln_type == "foldseek" else full_db.name
+ ),
+ "cluster_database": clusters.name,
+ "member_count": member_count,
+ "representative_count": representative_count,
+ "redundant_member_count": member_count - representative_count,
+ "link_normalization": link_report,
+ }
+ if expansion_db is not None:
+ payload["cluster_alignments"] = expansion_db.name
+ write_json_atomic(manifest_path, payload)
+ return payload
def make_sub_db(
@@ -72,6 +633,8 @@ def make_sub_db(
full_db: Path,
sub_db: Path,
aln_type: str,
+ *,
+ portable: bool = False,
) -> list[str]:
"""
Requires a list of already generated annotation entries.
@@ -91,12 +654,18 @@ def make_sub_db(
"""
# Map chain ids to full database ids
sub_db_lookup_file = sub_db / "ids.tsv"
+ database = sub_db / sub_db.name
+ _remove_database_prefix(database)
found = set()
with open(full_db.parent / f"{full_db.name}.lookup", "r") as f:
with open(sub_db_lookup_file, "w") as fw:
for line in f:
fields = line.split()
- if fields[1] in entry_chain_ids:
+ # Foldseek emits one record per model but uses the same chain
+ # identifier for every model. PLINDER annotations use the
+ # first model, and the lookup is ordered by model, so retain
+ # only the first record for each requested chain.
+ if fields[1] in entry_chain_ids and fields[1] not in found:
fw.write(line)
found.add(fields[1])
# Create subdb
@@ -107,31 +676,9 @@ def make_sub_db(
"createsubdb",
str(sub_db_lookup_file),
str(full_db),
- str(sub_db / sub_db.name),
+ str(database),
"--subdb-mode",
- "1",
- ]
- )
- run(
- [
- "foldseek",
- "createsubdb",
- str(sub_db_lookup_file),
- f"{full_db}_ss",
- f"{sub_db / sub_db.name}_ss",
- "--subdb-mode",
- "1",
- ]
- )
- run(
- [
- "foldseek",
- "createsubdb",
- str(sub_db_lookup_file),
- f"{full_db}_ca",
- f"{sub_db / sub_db.name}_ca",
- "--subdb-mode",
- "1",
+ "0" if portable else "1",
]
)
elif aln_type == "mmseqs":
@@ -141,7 +688,7 @@ def make_sub_db(
"createsubdb",
str(sub_db_lookup_file),
str(full_db),
- str(sub_db / sub_db.name),
+ str(database),
]
)
@@ -149,13 +696,8 @@ def make_sub_db(
return list(missing)
-def get_ids_in_db(data_dir: Path, search_db: str, aln_type: str) -> pd.DataFrame:
- sub_db_file = data_dir / "dbs" / "subdbs" / f"{search_db}_{aln_type}" / "ids.tsv"
- return pd.read_csv(sub_db_file, sep="\t", header=None)
-
-
def get_db_ids(
- entries: Dict[str, "Entry"],
+ entries: Dict[str, "EntryView"],
search_db: str,
aln_type: str,
entry_ids: Optional[list[str]] = None,
@@ -166,7 +708,7 @@ def get_db_ids(
Parameters
----------
- entries : Dict[str, Entry]
+ entries : Dict[str, EntryView]
the collection of entries
search_db : str
search_db in ["apo", "holo", "pred"]
@@ -190,7 +732,11 @@ def get_db_ids(
def make_sub_dbs(
db_dir: Path,
db_sources: Dict[str, Path],
- entries: Dict[str, "Entry"],
+ entries: Dict[str, "EntryView"] | None = None,
+ *,
+ identifiers_by_database: dict[str, set[str]] | None = None,
+ tmp_dir: Path | None = None,
+ threads: int = 1,
) -> None:
"""
Create the apo/holo subdbs for score
@@ -202,21 +748,116 @@ def make_sub_dbs(
directory where subdbs get written
db_sources : Dict[str, Path]
map of database name to path to full database
- entries : Dict[str, Entry]
- map of all the entries
+ entries : Dict[str, EntryView], optional
+ Map of entries used to derive identifiers for scorer-managed databases.
+ identifiers_by_database : dict[str, set[str]], optional
+ Precomputed identifiers keyed by ``{search_db}_{alignment_type}``.
+ The release pipeline uses this to select protein receptor chains
+ directly from the chain index without constructing all systems.
"""
- db_dir.mkdir(exist_ok=True)
+ db_dir.mkdir(exist_ok=True, parents=True)
report = {}
+ cluster_report = {}
for search_db_aln_type, full_db in db_sources.items():
- search_db, aln_type = search_db_aln_type.split("_")
+ search_db, aln_type = search_db_aln_type.rsplit("_", 1)
subdb = db_dir / search_db_aln_type
subdb.mkdir(exist_ok=True)
- report[search_db_aln_type] = make_sub_db(
- get_db_ids(entries, search_db, aln_type),
- full_db,
- subdb,
- aln_type,
+ if (
+ identifiers_by_database is not None
+ and search_db_aln_type in identifiers_by_database
+ ):
+ requested_ids = identifiers_by_database[search_db_aln_type]
+ elif entries is not None:
+ requested_ids = get_db_ids(entries, search_db, aln_type)
+ else:
+ raise ValueError(f"no identifiers supplied for {search_db_aln_type}")
+ selection_manifest = subdb / "selection.json"
+ source_lookup = full_db.parent / f"{full_db.name}.lookup"
+ selection = {
+ "alignment_type": aln_type,
+ "portable": True,
+ "identifier_count": len(requested_ids),
+ "identifier_sha256": _identifier_digest(requested_ids),
+ "source_lookup": _path_signature(source_lookup),
+ }
+ cached = read_json_cache(selection_manifest)
+ selected_database = subdb / subdb.name
+ cluster_manifest = _completed_exact_search_manifest(selected_database, aln_type)
+ complete = (
+ cached is not None
+ and all(cached.get(key) == value for key, value in selection.items())
+ and isinstance(cached.get("target_database"), dict)
+ and _database_files_exist(selected_database, aln_type)
+ and cluster_manifest is not None
)
- with (db_dir / "missing.json").open("w") as f:
- json.dump(report, f)
+ if complete:
+ assert cached is not None
+ missing = list(cached.get("missing", []))
+ else:
+ backend_tmp = (tmp_dir or db_dir / "scratch") / search_db_aln_type
+ working_subdb = subdb
+ if tmp_dir is not None:
+ working_subdb = backend_tmp / "build" / search_db_aln_type
+ if working_subdb.exists():
+ shutil.rmtree(working_subdb)
+ working_subdb.mkdir(exist_ok=True, parents=True)
+ missing = sorted(
+ make_sub_db(
+ requested_ids,
+ full_db,
+ working_subdb,
+ aln_type,
+ portable=True,
+ )
+ )
+ working_database = working_subdb / working_subdb.name
+ if search_db_aln_type.startswith("monomer_") and not (
+ working_database.with_suffix(".index").is_file()
+ and _database_entry_count(working_database)
+ ):
+ # linclust crashes on an empty database. An empty monomer
+ # universe is not an error: downstream bundling skips it.
+ # Retire any earlier build so it is not published as current.
+ LOG.info(f"no {search_db_aln_type} chains selected; skipping")
+ for stale in ("exact_cluster.json", "selection.json"):
+ (subdb / stale).unlink(missing_ok=True)
+ for prefix in (
+ subdb.name,
+ "exact_clusters",
+ "representatives",
+ "cluster_alignments",
+ "clustered",
+ ):
+ _remove_database_prefix(subdb / prefix)
+ report[search_db_aln_type] = missing
+ continue
+ cluster_manifest = make_exact_search_db(
+ full_db=working_database,
+ aln_type=aln_type,
+ tmp_dir=backend_tmp / "work",
+ threads=threads,
+ )
+ working_selection = working_subdb / "selection.json"
+ write_json_atomic(
+ working_selection,
+ {
+ **selection,
+ "target_database": _database_content_signature(working_database),
+ "missing": missing,
+ },
+ )
+ if tmp_dir is not None:
+ install_database_directory(
+ working_subdb,
+ subdb,
+ preserve_directories=("aln", "mapped_aln"),
+ )
+ report[search_db_aln_type] = missing
+ if cluster_manifest is None:
+ raise RuntimeError(
+ f"exact clustering did not complete for {search_db_aln_type}"
+ )
+ cluster_report[search_db_aln_type] = cluster_manifest
+ write_json_atomic(db_dir / "missing.json", report)
+ write_json_atomic(db_dir / "exact_clusters.json", cluster_report)
diff --git a/src/plinder/data/docs.py b/src/plinder/data/docs.py
index 8fe09cc5a..8994b3742 100644
--- a/src/plinder/data/docs.py
+++ b/src/plinder/data/docs.py
@@ -2,131 +2,754 @@
# Distributed under the terms of the Apache License 2.0
from __future__ import annotations
+import re
+from functools import cache
from pathlib import Path
import pandas as pd
+import pyarrow as pa
+import pyarrow.parquet as pq
-from plinder.data import column_descriptions
-from plinder.data.utils.annotations.aggregate_annotations import Entry, System
-from plinder.data.utils.annotations.get_ligand_validation import (
- EntryValidation,
- ResidueListValidation,
+from plinder.core.release import RELEASE_TABLES, PlinderRelease
+from plinder.core.scores.metrics import (
+ CHEMICAL_CLUSTER_SUMMARY_COLUMNS,
+ is_chemical_cluster_metric,
)
-from plinder.data.utils.annotations.ligand_utils import Ligand
-from plinder.data.utils.annotations.protein_utils import Chain
+from plinder.data import column_descriptions
TSV_DIR = Path(column_descriptions.__file__).parent
-VALIDATION_TYPES = [
- "system_pocket",
- "system_ligand",
- "ligand_interacting_ligand_chains",
- "ligand_neighboring_ligand_chains",
- "ligand_protein_chains",
- "system_ligand_chains",
- "system_protein_chains",
-]
-VALIDATION_OUTLIER_KEYS = [
- "chirality",
- "clashes",
- "density",
- "geometry",
-]
-MAPPING_NAMES = [
- "CATH",
- "ECOD",
- "ECOD_t_name",
- "Pfam",
- "SCOP2",
- "SCOP2B",
- "PANTHER",
- "UniProt",
- "kinase_name",
-]
-CHAIN_TYPES = [
- "system_protein_chains",
- "system_ligand_chains",
- "ligand_interacting_ligand_chains",
- "ligand_neighboring_ligand_chains",
- "ligand_protein_chains",
-]
+TABLE_TSV_DIR = TSV_DIR / "tables"
+
+_PUBLISHED_INTERFACE_COVER_COLUMN = re.compile(
+ r"(?:interface_qcov__\d+__(?:directed_set_cover|reciprocal_component)|"
+ r"interface_side_qcov__\d+__chain_[12]_(?:directed_set_cover|reciprocal_component))"
+)
+_PUBLISHED_LIGAND_COMPONENT_COLUMN = re.compile(
+ r"[^_]+(?:_[^_]+)*__\d+__ligand__reciprocal_component"
+)
+
+DERIVED_COLUMN_DESCRIPTIONS = {
+ "ligand_binding_affinity": (
+ "Median pKi or pKd for uncensored BindingDB measurements with one endpoint "
+ "and a target sequence matching this ligand's receptor; missing if ambiguous"
+ ),
+ "ligand_binding_affinity_endpoint": (
+ "BindingDB endpoint (Ki or Kd) used for ligand_binding_affinity"
+ ),
+ "ligand_binding_affinity_measurement_count": (
+ "Number of BindingDB measurements used for ligand_binding_affinity"
+ ),
+ "system_has_binding_affinity": (
+ "Whether any ligand in the system has an unambiguous, sequence-matched "
+ "BindingDB affinity"
+ ),
+ "pdbid_ligid": "PDB ID and ligand HET code reported in a BindingDB cross-reference",
+ "pdb_id": "PDB ID reported in a BindingDB ligand-target-complex cross-reference",
+ "ligand_het_id": "Ligand HET code reported by BindingDB",
+ "reactant_set_id": "BindingDB source reactant-set identifier, when provided",
+ "monomer_id": "BindingDB source monomer identifier, when provided",
+ "curation_source": "BindingDB curation or imported-data source",
+ "article_doi": "DOI of the source publication, when provided by BindingDB",
+ "bindingdb_entry_doi": "BindingDB DOI for the source entry, when provided",
+ "source_row": "Zero-based row number in the source BindingDB TSV",
+ "target_sequences": "All target-chain sequences reported for this measurement",
+ "target_sequence": (
+ "Target-chain sequence when exactly one was reported; otherwise missing"
+ ),
+ "endpoint": "Measured affinity endpoint: Ki or Kd",
+ "raw_value": "BindingDB affinity value in nM, including any inequality sign",
+ "relation": (
+ "Equality or inequality for the pKi/pKd value; reversed from the nM "
+ "inequality because the logarithmic scale is inverse"
+ ),
+ "value_nm": "Numeric affinity value in nM without its inequality sign",
+ "pchembl": "pKi or pKd (9 - log10 of nM value), before censoring checks",
+ "representative_entry_pdb_id": (
+ "PDB entry containing the protein-cluster representative; together with "
+ "representative_chain_asym_id identifies the cluster"
+ ),
+ "representative_chain_asym_id": (
+ "Source label_asym_id of the protein-cluster representative; missing "
+ "when the chain could not be clustered"
+ ),
+ "is_representative": (
+ "Whether this protein chain is its cluster representative; missing "
+ "when the chain could not be clustered"
+ ),
+ "status": (
+ "Protein clustering outcome: clustered, weekly_assigned (searched "
+ "against fixed representatives), missing_sequence (MMseqs), or "
+ "not_in_foldseek_db (Foldseek did not extract this chain from the "
+ "deposited structure)"
+ ),
+ "chain_is_ligand_like": (
+ "Whether this chain is ligand-like rather than an eligible receptor chain"
+ ),
+ "chain_type": "Raw CIF receptor polymer type",
+ "chain_receptor_type": ("Receptor polymer category: protein, dna, rna, or dna+rna"),
+ "chain_is_holo": (
+ "Whether the chain participates in a holo receptor or is excluded from "
+ "the apo partition"
+ ),
+ "chain_uniprot_ids": "UniProt accessions mapped to the chain",
+ "chain_sequence": (
+ "Full polymer sequence in one-letter code, keyed by the source "
+ "asymmetric-chain ID"
+ ),
+ "chain_sequence_noncanonical": (
+ "Full polymer sequence from _entity_poly.pdbx_seq_one_letter_code, with "
+ "modified residues as (CCD) tokens"
+ ),
+ "chain_modified_residues": (
+ "Non-canonical SEQRES monomers as {auth_seq}:{comp_id}:{asym}:{label_seq}"
+ ">{parent} (details), the residue address of ligand_covalent_linkages "
+ "(comp_id is entity_poly_seq.mon_id); unresolved positions have auth_seq ?; "
+ "parent and details from _pdbx_struct_mod_residue, else the CCD parent"
+ ),
+ "biounit_id": "Biological assembly identifier",
+ "chain_instance": (
+ "Assembly chain instance encoded as ."
+ ),
+ "chain_role": "Assembly role: receptor, ligand, or water",
+ "chain_num_contacting_ions": (
+ "Number of ion chains contacting this assembly-chain instance"
+ ),
+ "chain_num_contacting_artifacts": (
+ "Number of crystallization-artifact chains contacting this "
+ "assembly-chain instance"
+ ),
+ "chain_num_contacting_other_ligands": (
+ "Number of other ligand chains contacting this assembly-chain instance"
+ ),
+ "chain_num_contacting_proteins": (
+ "Number of other polypeptide chains contacting this assembly-chain instance"
+ ),
+ "source_mmcif_major_revision": (
+ "Major revision number of the source PDB mmCIF used during ingest"
+ ),
+ "source_mmcif_minor_revision": (
+ "Minor revision number of the source PDB mmCIF used during ingest"
+ ),
+ "reference_system_id": "PLINDER system or interface linked to this apo chain",
+ "reference_side": "Interface side linked to this apo chain: 1 or 2",
+ "reference_chain_instance": (
+ "Assembly-chain instance on the corresponding reference interface side"
+ ),
+ "reference_chain_asym_id": (
+ "Source asymmetric-chain ID on the corresponding reference interface side"
+ ),
+ "linked_structure_id": "Stable identifier for the linked apo chain",
+ "source_entry_id": "PDB entry containing the linked apo chain",
+ "source_chain_asym_id": "Source asymmetric-chain ID of the linked apo chain",
+ "source_chain_auth_id": "Author chain ID of the linked apo chain",
+ "source_biounit_id": "Source biological assembly containing the apo chain",
+ "source_chain_instance": "Exact biological-assembly chain instance that was scored",
+ "source_num_contacting_ions": "Number of ion chains contacting the apo chain",
+ "source_num_contacting_artifacts": (
+ "Number of crystallization-artifact chains contacting the apo chain"
+ ),
+ "source_num_contacting_other_ligands": (
+ "Number of other ligand chains contacting the apo chain"
+ ),
+ "source_num_contacting_proteins": (
+ "Number of other protein chains contacting the apo chain"
+ ),
+ "source_resolution": "Experimental resolution of the apo source entry",
+ "rank": "Apo candidate rank within the reference ligand system or interface side",
+ "num_ligand_pockets": "Number of holo ligand pockets matched by this apo chain",
+ "min_pocket_fident": "Minimum pocket sequence identity across matched ligands",
+ "mean_pocket_fident": "Mean pocket sequence identity across matched ligands",
+ "min_protein_fident_weighted_sum": (
+ "Minimum chain-length-weighted protein sequence identity across matched ligands"
+ ),
+ "min_protein_fident_qcov_weighted_sum": (
+ "Minimum chain-length-weighted protein identity times query coverage "
+ "across matched ligands"
+ ),
+ "min_protein_lddt_weighted_sum": (
+ "Minimum chain-length-weighted protein LDDT across matched ligands"
+ ),
+ "mmseqs_fident": "MMseqs sequence identity between reference and apo chains",
+ "mmseqs_query_coverage": (
+ "Fraction of the reference chain covered by the MMseqs alignment"
+ ),
+ "mmseqs_target_coverage": (
+ "Fraction of the apo chain covered by the MMseqs alignment"
+ ),
+ "foldseek_lddt": (
+ "Foldseek local-distance difference test score for the same chain pair"
+ ),
+ "selected_residue_numbers": (
+ "Source-mmCIF residue numbers selected by any ligand pocket or protein "
+ "interface, ordered by selected_residue_indices"
+ ),
+ "selected_residue_indices": (
+ "Zero-based resolved-chain indices corresponding positionally to "
+ "selected_residue_numbers"
+ ),
+ "interface_chain_1": "First canonical assembly-chain instance",
+ "interface_chain_2": "Second canonical assembly-chain instance",
+ "interface_chain_1_residue_numbers": (
+ "Source-mmCIF residue numbers at the interface on chain 1"
+ ),
+ "interface_chain_1_residue_indices": (
+ "Zero-based resolved-chain indices corresponding positionally to chain "
+ "1 residue numbers"
+ ),
+ "interface_chain_2_residue_numbers": (
+ "Source-mmCIF residue numbers at the interface on chain 2"
+ ),
+ "interface_chain_2_residue_indices": (
+ "Zero-based resolved-chain indices corresponding positionally to chain "
+ "2 residue numbers"
+ ),
+ "interface_num_contact_residue_pairs": (
+ "Number of residue pairs in contact across the protein interface"
+ ),
+ "interface_contact_area": (
+ "Voronota-LT contact area in square angstroms between the two chains in "
+ "the full biological assembly; null when the assembly tessellation was "
+ "skipped or failed"
+ ),
+ "prodigy_is_annotated": (
+ "Whether PRODIGY-cryst features and a biological/crystal label are available"
+ ),
+ "prodigy_label": "PRODIGY-cryst BIO or XTAL interface label",
+ "prodigy_probability_bio": (
+ "PRODIGY-cryst probability that the interface is biological"
+ ),
+ "prodigy_link_density": "PRODIGY-cryst interface link-density feature",
+ "prodigy_intermolecular_contacts": (
+ "PRODIGY-cryst count of intermolecular atomic contacts"
+ ),
+ "prodigy_charged_charged_contacts": (
+ "PRODIGY-cryst count of charged-charged contacts"
+ ),
+ "prodigy_charged_polar_contacts": ("PRODIGY-cryst count of charged-polar contacts"),
+ "prodigy_charged_apolar_contacts": (
+ "PRODIGY-cryst count of charged-apolar contacts"
+ ),
+ "prodigy_polar_polar_contacts": ("PRODIGY-cryst count of polar-polar contacts"),
+ "prodigy_apolar_polar_contacts": ("PRODIGY-cryst count of apolar-polar contacts"),
+ "prodigy_apolar_apolar_contacts": ("PRODIGY-cryst count of apolar-apolar contacts"),
+ "representative_ligand_id": (
+ "Ligand ID selected as the representative for a ligand-pocket group"
+ ),
+ "representative_system_id": (
+ "System ID selected as the representative for a ligand pocket or "
+ "protein interface"
+ ),
+ "receptor_chain_asym_ids": (
+ "Asymmetric-chain IDs in the representative receptor-chain set"
+ ),
+ "receptor_set_id": (
+ "Stable identifier for the representative set of receptor chains"
+ ),
+ "pocket_residues": (
+ "Representative pocket residues encoded as asym ID, residue number, "
+ "and zero-based resolved-chain index"
+ ),
+ "interactions": (
+ "Representative protein-ligand interactions encoded with their receptor "
+ "residue mapping and interaction type"
+ ),
+ "residue_label_seq_id": ("Receptor residue number from _atom_site.label_seq_id"),
+ "residue_index": "Zero-based position among resolved residues in the chain",
+ "residue_auth_seq_id": (
+ "Depositor-provided receptor residue number from _atom_site.auth_seq_id"
+ ),
+ "residue_insertion_code": (
+ "Depositor-provided receptor residue insertion code, or . when absent"
+ ),
+ "is_pli": (
+ "Whether this pocket residue participates in a detected protein-ligand "
+ "interaction"
+ ),
+ "half_interface_id": "Stable identifier for one representative interface side",
+ "instance_chain_id": "Assembly-chain instance forming this half-interface",
+ "residue_numbers": "Source-mmCIF residue numbers in this half-interface",
+ "residue_indices": (
+ "Zero-based resolved-chain indices corresponding positionally to "
+ "residue_numbers"
+ ),
+ "half_interface_1_id": "First half-interface of this representative",
+ "half_interface_2_id": "Second half-interface of this representative",
+ "side_1_half_interface_id": (
+ "Representative half-interface assigned to the first query side"
+ ),
+ "side_2_half_interface_id": (
+ "Representative half-interface assigned to the second query side"
+ ),
+ "biounit_num_ligands": "Number of ligands in the biological assembly",
+ "biounit_num_unique_ccd_codes": (
+ "Number of distinct ligand CCD codes in the biological assembly"
+ ),
+ "biounit_num_proper_ligands": (
+ "Number of proper ligands in the biological assembly"
+ ),
+ "system_protein_chains_total_length": (
+ "Total length of all receptor polymer chains in the system"
+ ),
+ "system_unique_ccd_codes": "Distinct ligand CCD codes in the system",
+ "system_proper_unique_ccd_codes": (
+ "Distinct CCD codes of proper ligands in the system"
+ ),
+ "ligand_is_shape_comparable": (
+ "Whether the canonical ligand SDF supports finite shape, color, and "
+ "SuCOS self-scoring"
+ ),
+ "ligand_smiles_id": (
+ "Integer node ID assigned to this exact canonical SMILES for ligand "
+ "similarity scoring"
+ ),
+ "ligand_smiles_id_1": "Unique-SMILES node ID for the first MMP ligand",
+ "ligand_smiles_id_2": "Unique-SMILES node ID for the second MMP ligand",
+ "ligand_smiles_1": "Canonical SMILES for the first MMP ligand",
+ "ligand_smiles_2": "Canonical SMILES for the second MMP ligand",
+ "transformation": "MMP transformation directed from ligand 1 to ligand 2",
+ "shared_core_smiles": "Shared MMP core with attachment points marked by *",
+ "num_cuts": "Number of attachment points in the shared MMP core",
+ "shared_core_num_heavy_atoms": "Number of heavy atoms in the shared MMP core",
+ "ligand_1_num_heavy_atoms": "Number of heavy atoms in the first MMP ligand",
+ "ligand_2_num_heavy_atoms": "Number of heavy atoms in the second MMP ligand",
+ "ligand_1_shared_core_fraction": (
+ "Fraction of the first ligand's heavy atoms contained in the shared core"
+ ),
+ "ligand_2_shared_core_fraction": (
+ "Fraction of the second ligand's heavy atoms contained in the shared core"
+ ),
+ "ligand_max_cofactor_similarity": (
+ "Maximum ECFP4/1024 Tanimoto similarity, as a percentage, to any CCD "
+ "structure in the cofactor list"
+ ),
+ "ligand_most_similar_cofactor": (
+ "CCD code of the cofactor with maximum ECFP4/1024 Tanimoto similarity"
+ ),
+ "ligand_is_cofactor_like": (
+ "Whether maximum similarity to a listed CCD cofactor is at least 90 percent"
+ ),
+}
+
+DERIVED_COLUMN_DESCRIPTIONS.update(
+ {
+ f"system_ligand_has_{name}": description
+ for name, description in {
+ "lipinski": "Whether the system has a Lipinski ligand",
+ "cofactor": "Whether the system has a cofactor ligand",
+ "fragment": "Whether the system has a fragment ligand",
+ "monosaccharide": (
+ "Whether the system has a ligand containing one saccharide unit"
+ ),
+ "oligosaccharide": (
+ "Whether the system has a ligand containing multiple saccharide units"
+ ),
+ "mononucleotide": (
+ "Whether the system has a ligand containing one nucleotide unit"
+ ),
+ "oligonucleotide": (
+ "Whether the system has a ligand containing multiple nucleotide units"
+ ),
+ "monopeptide": (
+ "Whether the system has a ligand containing one peptide unit"
+ ),
+ "oligopeptide": (
+ "Whether the system has a ligand containing multiple peptide units"
+ ),
+ "artifact": "Whether the system has an artifact ligand",
+ "other": "Whether the system has a ligand classified as other",
+ "covalent": "Whether the system has a covalent ligand",
+ "invalid": "Whether the system has an invalid ligand",
+ "ion": "Whether the system has an ion",
+ }.items()
+ }
+)
+
+
+# Human-readable labels for the fingerprint (chemical) clustering metrics.
+# MHFP6: Probst, D. & Reymond, J-L. "A probabilistic molecular fingerprint for
+# big data settings." J. Cheminform. 10, 8 (2018). doi:10.1186/s13321-018-0321-8
+_METRIC_LABELS = {
+ "tanimoto_similarity_ecfp4_1024": "ECFP4/1024 Tanimoto similarity",
+ "jaccard_similarity_mhfp6_2048": (
+ "MHFP6/2048 MinHash-estimated Jaccard similarity (Probst & Reymond 2018)"
+ ),
+}
+_CHEMICAL_SUMMARY_LABELS = {
+ "tanimoto_similarity_ecfp4_1024": "ECFP4/1024 Tanimoto",
+ "jaccard_similarity_mhfp6_2048": "MHFP6/2048 Jaccard",
+}
+for _metric, _column in CHEMICAL_CLUSTER_SUMMARY_COLUMNS.items():
+ DERIVED_COLUMN_DESCRIPTIONS[_column] = (
+ f"Cluster ID from the 90-percent {_CHEMICAL_SUMMARY_LABELS[_metric]} set "
+ "cover; every member has a direct threshold-qualified edge to its "
+ "representative"
+ )
+ DERIVED_COLUMN_DESCRIPTIONS[f"{_column}_num_pdb_ids"] = (
+ "Number of distinct PDB entries represented in the ligand's 90-percent "
+ f"{_CHEMICAL_SUMMARY_LABELS[_metric]} set-cover cluster"
+ )
def get_cluster_column_descriptions(
- plindex: pd.DataFrame
+ plindex: pd.DataFrame,
) -> list[tuple[str, str | None, str | None]]:
rows: list[tuple[str, str | None, str | None]] = []
- component_columns = [c for c in plindex.columns if c.endswith("__component")]
- for column in component_columns:
- metric, threshold, directed, cluster = column.split("__")
+ set_cover_columns = [
+ c
+ for c in plindex.columns
+ if c.endswith("__set_cover") and not c.endswith("__directed_set_cover")
+ ]
+ for column in set_cover_columns:
+ parts = column.split("__")
+ metric, threshold = parts[:2]
+ ligand_level = parts[2] == "ligand"
+ level = "ligand-level " if ligand_level else ""
rows.append(
(
column,
"str",
- f"Cluster ID for {directed} {cluster} built from {metric} metric with {threshold} threshold",
+ f"Cluster ID for {level}set cover built from reciprocal-minimum "
+ f"{_METRIC_LABELS.get(metric, metric)} with {threshold} threshold; "
+ "each member has a direct threshold-qualified edge to its "
+ "representative",
)
)
- community_columns = [c for c in plindex.columns if c.endswith("__community")]
- for column in community_columns:
- metric, threshold, cluster = column.split("__")
+ directed_cover_columns = [
+ c for c in plindex.columns if c.endswith("directed_set_cover")
+ ]
+ for column in directed_cover_columns:
+ parts = column.split("__")
+ metric, threshold = parts[:2]
+ ligand_level = parts[2] == "ligand"
+ half_interface = parts[-1].startswith("chain_")
+ level = (
+ "ligand-level "
+ if ligand_level
+ else f"{parts[-1].removesuffix('_directed_set_cover').replace('_', ' ')} "
+ if half_interface
+ else ""
+ )
rows.append(
(
column,
"str",
- f"Cluster ID for {cluster} built from {metric} metric with {threshold} threshold",
+ f"Cluster ID for {level}directed set cover built from "
+ f"{_METRIC_LABELS.get(metric, metric)} with {threshold} threshold; "
+ "each member's query-to-centroid score meets the threshold",
+ )
+ )
+ component_columns = [
+ column for column in plindex.columns if column.endswith("reciprocal_component")
+ ]
+ for column in component_columns:
+ metric, threshold = column.split("__", maxsplit=2)[:2]
+ rows.append(
+ (
+ column,
+ "str | None",
+ f"Full-graph component at {metric} {threshold} threshold; an edge "
+ "requires similarity in both directions. Connected members may "
+ "be linked through other members rather than directly",
)
)
- return rows
+ centroid_columns = [
+ c
+ for c in plindex.columns
+ if c.endswith(
+ (
+ "__set_cover__is_centroid",
+ "__directed_set_cover__is_centroid",
+ )
+ )
+ ]
+ for column in centroid_columns:
+ parts = column.split("__")
+ metric, threshold = parts[:2]
+ ligand_level = parts[2] == "ligand"
+ level = "ligand-level " if ligand_level else ""
+ cover_kind = (
+ "directed set-cover" if "__directed_set_cover__" in column else "set-cover"
+ )
+ rows.append(
+ (
+ column,
+ "bool | None",
+ f"Whether this row is the published centroid for its {level}"
+ f"{cover_kind} cluster built from {metric} with "
+ f"{threshold} threshold; missing means the row is outside the "
+ "clustering universe",
+ )
+ )
+ directed_coverage_columns = [
+ c
+ for c in plindex.columns
+ if c.endswith(
+ (
+ "__directed_set_cover__coverage_count",
+ "__directed_set_cover__coverage_fraction",
+ )
+ )
+ ]
+ for column in directed_coverage_columns:
+ parts = column.split("__")
+ metric, threshold = parts[:2]
+ is_count = column.endswith("__coverage_count")
+ quantity = (
+ "Number of directed-cover query nodes this ligand could initially cover"
+ if is_count
+ else "Fraction of its directed weak component this ligand could "
+ "initially cover"
+ )
+ rows.append(
+ (
+ column,
+ "int | None" if is_count else "float | None",
+ f"{quantity} at {metric} {threshold} threshold, including "
+ "itself; missing means the row is outside the clustering "
+ "universe",
+ )
+ )
+ column_order = {column: index for index, column in enumerate(plindex.columns)}
+ return sorted(rows, key=lambda row: column_order[row[0]])
-def get_all_column_descriptions(
- *,
- plindex: pd.DataFrame | None = None,
-) -> pd.DataFrame:
- if plindex is not None:
- make_column_descriptions(plindex=plindex)
- dfs = []
- for tsv in TSV_DIR.glob("*.tsv"):
- dfs.append(pd.read_csv(tsv, sep="\t"))
- return pd.concat(dfs).reset_index(drop=True)
+@cache
+def _model_description_lookup() -> dict[str, str]:
+ """Generate descriptions from the annotation models that emit the columns."""
+ from plinder.data.annotations.aggregate_annotations import Entry, System
+ from plinder.data.annotations.get_ligand_validation import (
+ EntryValidation,
+ ResidueListValidation,
+ )
+ from plinder.data.annotations.ligand_utils import Ligand
+ from plinder.data.annotations.protein_utils import Chain
+ from plinder.data.annotations.utils import DocBaseModel
+ descriptions: dict[str, str] = {}
+ model_prefixes: list[tuple[type[DocBaseModel], str]] = [
+ (Entry, "entry"),
+ (EntryValidation, "entry_validation"),
+ (System, "system"),
+ (Ligand, "ligand"),
+ (Chain, "chain"),
+ ]
+ model_prefixes.extend(
+ (Chain, prefix)
+ for prefix in [
+ "system_protein_chains",
+ "system_ligand_chains",
+ "ligand_interacting_ligand_chains",
+ "ligand_neighboring_ligand_chains",
+ "ligand_protein_chains",
+ ]
+ )
+ model_prefixes.extend(
+ (ResidueListValidation, f"{prefix}_validation")
+ for prefix in [
+ "system_pocket",
+ "system_ligand",
+ "ligand_interacting_ligand_chains",
+ "ligand_neighboring_ligand_chains",
+ "ligand_protein_chains",
+ "system_ligand_chains",
+ "system_protein_chains",
+ ]
+ )
+ for model, prefix in model_prefixes:
+ for name, _, description in model.document_properties(prefix):
+ descriptions[name] = description
+ return descriptions
-def make_column_descriptions(*, plindex: pd.DataFrame) -> None:
- output_dir = TSV_DIR
- output_dir.mkdir(parents=True, exist_ok=True)
- Entry.document_properties_to_tsv(prefix="entry", filename=output_dir / "entry.tsv")
- EntryValidation.document_properties_to_tsv(
- prefix="entry_validation", filename=output_dir / "entry_validation.tsv"
+
+def _base_description_lookup() -> dict[str, str]:
+ """Combine model-generated and explicitly derived column descriptions."""
+ descriptions: dict[str, str] = {}
+ descriptions.update(_model_description_lookup())
+ descriptions.update(DERIVED_COLUMN_DESCRIPTIONS)
+ return descriptions
+
+
+def _validate_published_cover_columns(*, table_name: str, names: list[str]) -> None:
+ """Reject cluster columns that the current finalizers do not publish."""
+ invalid: list[str] = []
+ summary_columns = tuple(CHEMICAL_CLUSTER_SUMMARY_COLUMNS.values())
+ if table_name == "annotation":
+ invalid.extend(
+ name
+ for name in names
+ if "__ligand__" in name or name.startswith(summary_columns)
+ )
+ elif table_name == "ligand_clusters":
+ cover_names = [name for name in names if "__ligand__" in name]
+ allowed_fixed = {
+ "ligand_id",
+ *summary_columns,
+ *(f"{column}_num_pdb_ids" for column in summary_columns),
+ }
+ invalid.extend(
+ name
+ for name in names
+ if name not in allowed_fixed and name not in cover_names
+ )
+ for name in cover_names:
+ metric = name.split("__", maxsplit=1)[0]
+ if name.endswith("__reciprocal_component"):
+ if _PUBLISHED_LIGAND_COMPONENT_COLUMN.fullmatch(name) is None:
+ invalid.append(name)
+ elif "__component" in name or "__community" in name:
+ invalid.append(name)
+ elif is_chemical_cluster_metric(metric):
+ # Chemical metrics publish only reciprocal ligand set covers.
+ if "__ligand__set_cover" not in name:
+ invalid.append(name)
+ elif "__set_cover" in name and "__directed_set_cover" not in name:
+ invalid.append(name)
+ elif table_name == "interface_annotations":
+ invalid.extend(
+ name
+ for name in names
+ if name.startswith(("interface_qcov__", "interface_side_qcov__"))
+ )
+ elif table_name == "interface_clusters":
+ cover_names = [
+ name
+ for name in names
+ if name.startswith(("interface_qcov__", "interface_side_qcov__"))
+ ]
+ invalid.extend(
+ name for name in names if name != "system_id" and name not in cover_names
+ )
+ invalid.extend(
+ name
+ for name in cover_names
+ if _PUBLISHED_INTERFACE_COVER_COLUMN.fullmatch(name) is None
+ )
+ if invalid:
+ raise ValueError(
+ f"release table {table_name!r} has cover columns that are not "
+ f"published by the current pipeline: {invalid}"
+ )
+
+
+def _validate_table_column_ownership(*, table_name: str, names: list[str]) -> None:
+ """Reject columns that belong to another release table."""
+ from plinder.data.pipeline.collate import (
+ SYSTEM_VALIDATION_PREFIXES,
+ _is_retired_annotation_column,
+ )
+
+ if table_name == "system_validation":
+ misplaced = sorted(
+ name
+ for name in names
+ if name != "system_id" and not name.startswith(SYSTEM_VALIDATION_PREFIXES)
+ )
+ if misplaced:
+ raise ValueError(
+ "release table 'system_validation' has non-validation columns: "
+ f"{misplaced}"
+ )
+ return
+ if table_name != "annotation":
+ return
+ repeated_entry_columns = sorted(
+ name for name in names if name.startswith("entry_") and name != "entry_pdb_id"
)
- System.document_properties_to_tsv(
- prefix="system", filename=output_dir / "system.tsv"
+ if repeated_entry_columns:
+ raise ValueError(
+ "release table 'annotation' repeats columns owned by "
+ f"'entry_metadata': {repeated_entry_columns}"
+ )
+ misplaced = sorted(name for name in names if _is_retired_annotation_column(name))
+ if misplaced:
+ raise ValueError(
+ "release table 'annotation' contains columns owned by sidecars or "
+ f"retired fields: {misplaced}"
+ )
+
+
+def get_table_column_descriptions(
+ *, table_name: str, schema: pa.Schema
+) -> pd.DataFrame:
+ """Build ordered descriptions for exactly the columns in one release table.
+
+ The Arrow schema supplies the published names, order, and data types. A
+ missing prose description is an error so documentation cannot silently lag
+ behind a release table.
+ """
+ if table_name not in RELEASE_TABLES:
+ choices = ", ".join(sorted(RELEASE_TABLES))
+ raise KeyError(f"unknown release table {table_name!r}; choose from: {choices}")
+
+ fields = list(schema)
+ names = [field.name for field in fields]
+ _validate_table_column_ownership(table_name=table_name, names=names)
+ _validate_published_cover_columns(table_name=table_name, names=names)
+ descriptions = _base_description_lookup()
+ cluster_rows = get_cluster_column_descriptions(pd.DataFrame(columns=names))
+ descriptions.update(
+ {
+ name: description
+ for name, _, description in cluster_rows
+ if description is not None
+ }
)
- for validation_type in VALIDATION_TYPES:
- ResidueListValidation.document_properties_to_tsv(
- prefix=f"{validation_type}_validation",
- filename=output_dir / f"{validation_type}_validation.tsv",
- nested=validation_type.endswith("_chains"),
- )
- with open(output_dir / f"{validation_type}_validation.tsv", "a") as f:
- typ = "list[float]" if validation_type.endswith("_chains") else "float"
- for key in VALIDATION_OUTLIER_KEYS:
- name = f"{validation_type}_validation_percent_outliers_{key}"
- f.write(f"{name}\t{typ}\tPercent outliers for {key}\n")
- for chain_type in CHAIN_TYPES:
- Chain.document_properties_to_tsv(
- prefix=chain_type,
- filename=output_dir / f"{chain_type}.tsv",
- nested=True,
- )
- with open(output_dir / "system_pocket.tsv", "w") as f:
- f.write("Name\tType\tDescription\n")
- for key in MAPPING_NAMES:
- name = f"system_pocket_{key}"
- f.write(f"{name}\tstr\t{key} domain for the pocket\n")
- Ligand.document_properties_to_tsv(
- prefix="ligand", filename=output_dir / "ligands.tsv"
+ missing = [name for name in names if name not in descriptions]
+ if missing:
+ raise ValueError(
+ f"release table {table_name!r} has undocumented columns: {missing}"
+ )
+ return pd.DataFrame(
+ {
+ "Name": names,
+ "Type": [str(field.type) for field in fields],
+ "Description": [descriptions[name] for name in names],
+ }
)
- with open(output_dir / "similarity_clusters.tsv", "w") as f:
- f.write("Name\tType\tDescription\n")
- rows = get_cluster_column_descriptions(plindex)
- for row in rows:
- f.write(f"{row[0]}\t{row[1]}\t{row[2]}\n")
+
+
+def get_column_descriptions(
+ table_name: str,
+ *,
+ description_dir: Path = TABLE_TSV_DIR,
+) -> pd.DataFrame:
+ """Read the checked-in descriptions for one release parquet table."""
+ if table_name not in RELEASE_TABLES:
+ choices = ", ".join(sorted(RELEASE_TABLES))
+ raise KeyError(f"unknown release table {table_name!r}; choose from: {choices}")
+ path = description_dir / f"{table_name}.tsv"
+ if not path.is_file():
+ raise FileNotFoundError(f"missing release column descriptions: {path}")
+ frame = pd.read_csv(path, sep="\t")
+ if frame["Name"].duplicated().any():
+ duplicates = frame.loc[frame["Name"].duplicated(), "Name"].tolist()
+ raise ValueError(f"duplicate descriptions in {path}: {duplicates}")
+ return frame
+
+
+def write_column_descriptions(
+ *,
+ data_dir: Path,
+ output_dir: Path = TABLE_TSV_DIR,
+) -> None:
+ """Write one complete description TSV per published parquet table.
+
+ TODO: the checked-in TSVs are hand-edited; nothing regenerates them or checks
+ their prose against the model descriptions. Discuss: build from the static
+ schemas already in code, add a parity test, run as a pre-commit hook.
+ """
+ release = PlinderRelease(data_dir)
+ output_dir.mkdir(parents=True, exist_ok=True)
+ expected: set[Path] = set()
+ for table_name, table in RELEASE_TABLES.items():
+ table_path = release.fetch(str(table["artifact"]))
+ descriptions = get_table_column_descriptions(
+ table_name=table_name,
+ schema=pq.read_schema(table_path),
+ )
+ output_path = output_dir / f"{table_name}.tsv"
+ descriptions.to_csv(output_path, sep="\t", index=False)
+ expected.add(output_path)
+ for stale in output_dir.glob("*.tsv"):
+ if stale not in expected:
+ stale.unlink()
diff --git a/src/plinder/data/final_structure_qc.py b/src/plinder/data/final_structure_qc.py
deleted file mode 100644
index 14d5eb46c..000000000
--- a/src/plinder/data/final_structure_qc.py
+++ /dev/null
@@ -1,515 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-import json
-from pathlib import Path
-from typing import TYPE_CHECKING, Any, Generator
-
-import numpy as np
-import pandas as pd
-from biotite.structure.io import load_structure
-from openbabel import openbabel as ob
-from rdkit import Chem
-from rdkit.Chem.MolStandardize import rdMolStandardize
-
-from plinder.core.structure import diffdock_utils
-from plinder.core.structure.contacts import get_atom_neighbors
-from plinder.core.structure.smallmols_utils import fix_valency_issues
-from plinder.core.utils.log import setup_logger
-
-if TYPE_CHECKING:
- from plinder.data.utils.annotations.aggregate_annotations import Entry
-
-LOG = setup_logger(__name__)
-
-
-def ligand_is_rdkit_loadable(sdf_path: Path) -> bool:
- """Check if structure is loadable by rdkit
-
- Parameters
- ----------
- sdf_path : Path
- Path to ligand sdf
-
- Returns
- -------
- bool
- True if loadable, False otherwise.
- """
- try:
- mol = next(Chem.SDMolSupplier(str(sdf_path)))
- if mol is not None:
- return True
- else:
- return False
- except RuntimeError:
- return False
-
-
-def ligand_is_rdkit_loadable_with_fix(sdf_path: Path) -> bool:
- """Check if structure is loadable by rdkit after fixing
-
- Parameters
- ----------
- sdf_path : Path
- Path to ligand sdf
-
- Returns
- -------
- bool
- True if loadable, False otherwise.
- """
- mol = next(Chem.SDMolSupplier(str(sdf_path), sanitize=False))
- try:
- mol = fix_valency_issues(mol)
- if mol is not None:
- return True
- else:
- return False
-
- except RuntimeError:
- return False
-
-
-def ligand_is_obabel_loadable(sdf_path: Path) -> bool:
- """Check if structure is loadable by openbabel
-
- Parameters
- ----------
- sdf_path : Path
- Path to ligand sdf
-
- Returns
- -------
- bool
- True if loadable, False otherwise.
- """
-
- obconversion = ob.OBConversion()
- obconversion.SetInFormat("sdf")
- obmol = ob.OBMol()
- return bool(obconversion.ReadFile(obmol, str(sdf_path)))
-
-
-def ligand_is_obabel_loadable_with_rdkit_fix(sdf_path: Path) -> bool:
- """Check if structure is loadable by openbabel after fixing
-
- Parameters
- ----------
- sdf_path : Path
- Path to ligand sdf
-
- Returns
- -------
- bool
- True if loadable, False otherwise.
- """
- obconversion = ob.OBConversion()
- obconversion.SetInFormat("sdf")
- obmol = ob.OBMol()
- if obconversion.ReadFile(obmol, str(sdf_path)):
- return True
- else:
- mol = next(Chem.SDMolSupplier(str(sdf_path), sanitize=False))
- try:
- mol = fix_valency_issues(mol)
- if mol is not None:
- fixed_sdf_str = Chem.MolToMolBlock(mol)
- return bool(obconversion.ReadString(obmol, fixed_sdf_str))
- else:
- return False
- except Exception:
- return False
-
-
-def ligand_matches_smiles_atom_num(smiles: str, sdf_path: Path) -> bool:
- """Check if atom number in ligand sdf matches the one from annotation smiles
-
- Parameters
- ----------
- smiles : str
- smiles from annotation foile
- sdf_path : Path
- Path to ligand sdf
-
- Returns
- -------
- bool
- True if matching, False otherwise.
- """
- mol = next(Chem.SDMolSupplier(str(sdf_path), sanitize=False))
- try:
- mol = fix_valency_issues(mol)
- except Exception:
- return False
- if mol is None:
- return False
- try:
- target_mol = Chem.MolFromSmiles(smiles, sanitize=False)
- target_mol = fix_valency_issues(target_mol)
- except Exception:
- return False
- if target_mol is None:
- return False
- else:
- # atms = [i.GetSymbol() for i in mol.GetAtoms() if i.GetSymbol() != "H"]
- # target_atms = [j.GetSymbol() for j in target_mol.GetAtoms()]
- return bool(
- len(Chem.RemoveHs(mol).GetAtoms())
- == len(Chem.RemoveHs(target_mol).GetAtoms())
- )
-
-
-def get_molvs_ligand_validation(sdf_path: Path) -> list[str]:
- """Check for errors that could be detected by MolVS
-
- Parameters
- ----------
- sdf_path : Path
- Path to ligand sdf
-
- Returns
- -------
- list[str]
- [] if not validation error.
- """
- validations = [
- rdMolStandardize.NoAtomValidation(),
- rdMolStandardize.FragmentValidation(),
- rdMolStandardize.NeutralValidation(),
- ]
- mol = fix_valency_issues(next(Chem.SDMolSupplier(str(sdf_path), sanitize=False)))
- vm = rdMolStandardize.MolVSValidation(validations)
- return list(vm.validate(mol))
-
-
-def get_rdkit_ligand_validation(sdf_path: Path) -> list[str]:
- """Check for errors that could be detected by RDKit
-
- Parameters
- ----------
- sdf_path : Path
- Path to ligand sdf
-
- Returns
- -------
- list[str]
- [] if not validation error.
- """
- mol = fix_valency_issues(next(Chem.SDMolSupplier(str(sdf_path), sanitize=False)))
- vm = rdMolStandardize.RDKitValidation()
- return list(vm.validate(mol))
-
-
-def ligand_positions_correct(
- center_of_mass: np.ndarray[Any, Any], sdf_path: Path
-) -> bool:
- """Check if ligand position is maintained
-
- Parameters
- ----------
- center_of_mass : np.ndarray[Any, Any]
- Center of mass from annotation
- sdf_path : Path
- Path to sdf ligand
-
- Returns
- -------
- bool
- True if position is maintained, otherwise False
- """
- mol = next(Chem.SDMolSupplier(str(sdf_path), sanitize=False))
- mol = fix_valency_issues(mol)
- conf = mol.GetConformer()
- return bool(
- np.allclose(
- np.mean(conf.GetPositions(), axis=0), center_of_mass, atol=0.1, rtol=0.1
- )
- )
-
-
-def file_loadbable_via_biotite(structure_path: Path) -> bool:
- """Ligand is loadable by biotite
-
- Parameters
- ----------
- structure_path : Path
- Path to stucture (could be protein/ligand/complex)
-
- Returns
- -------
- bool
- True if loadable, otherwise False
- """
-
- try:
- if structure_path.suffix == ".sdf":
- arr = load_structure(structure_path)
- else:
- arr = load_structure(structure_path, use_author_fields=False)
- return bool(arr.coord.shape[0] > 0)
- except Exception:
- return False
-
-
-def ligand_protein_neighbor_still_preserved(
- neighbor_chains: set[str], protein_file: Path, ligand_file: Path, radius: int = 6
-) -> bool:
- """
- Check if all ligand protein neighbors are saved
- in protein structure
-
- Parameters
- ----------
- neighbor_chains : set[str]
- Set of protein chain ids neighboring to ligand
- protein_file : Path
- Path to protein structure
- ligand_file : Path
- Path to ligand sdf
- radius : int
- Radius around ligand to extract neighbors
-
- Returns
- -------
- bool
- True if all neighbors are present, otherwise False
- """
-
- protein_arr = load_structure(protein_file, use_author_fields=False)
- ligand_arr = load_structure(ligand_file)
- neighbor_arr = get_atom_neighbors(protein_arr, ligand_arr, radius=radius)
- return {neighbor.chain_id for neighbor in neighbor_arr} == neighbor_chains
-
-
-def ligand_protein_neighbor_still_preserved_complex(
- neighbor_chains: set[str],
- complex_file: Path,
- protein_chains: set[str],
- ligand_chains: set[str],
- radius: int = 10,
-) -> bool:
- """
- Check if all ligand protein neighbors are saved
- in complex structure
-
- Parameters
- ----------
- neighbor_chains : set[str]
- Set of protein chain ids neighboring to ligand
- complex_file : Path
- Path to complex structure
- radius : int
- Radius around ligand to extract neighbors
-
- Returns
- -------
- bool
- True if all neighbors are present, otherwise False
- """
- complex_arr = load_structure(complex_file, use_author_fields=False)
- # protein_arr = complex_arr[~complex_arr.hetero]
- # ligand_arr = complex_arr[complex_arr.hetero]
- protein_arr = complex_arr[np.isin(complex_arr.chain_id, list(protein_chains))]
- ligand_arr = complex_arr[np.isin(complex_arr.chain_id, list(ligand_chains))]
- neighbor_arr = get_atom_neighbors(protein_arr, ligand_arr, radius=radius)
- return {str(neighbor.chain_id) for neighbor in neighbor_arr} == neighbor_chains
-
-
-def all_ligand_chains_present(ligand_chains: set[str], complex_file: Path) -> bool:
- """
- Check if all ligand chains are correctly saved
-
- Parameters
- ----------
- ligand_chains : set[str]
- Set of ligand chain ids from annotation
- complex_file : Path
- Path to complex structure
-
- Returns
- -------
- bool
- True if all ligand chains are present, otherwise False
- """
- complex_arr = load_structure(complex_file, use_author_fields=False)
- # ligand_arr = complex_arr[complex_arr.hetero]
- # chains = {ch for ch in ligand_arr.chain_id}
- chains = {ch for ch in complex_arr.chain_id}
- return bool(ligand_chains.issubset(chains))
-
-
-def all_protein_chains_present(protein_chains: set[str], complex_file: Path) -> bool:
- """
- Check if all protein chains are correctly saved
-
- Parameters
- ----------
- protein_chains : set[str]
- Set of protein chain ids from annotation
- complex_file : Path
- Path to complex structure
-
- Returns
- -------
- bool
- True if all protein chains are present, otherwise False
- """
- complex_arr = load_structure(complex_file, use_author_fields=False)
- # protein_arr = complex_arr[~complex_arr.hetero]
- # chains = {ch for ch in protein_arr.chain_id}
- chains = {ch for ch in complex_arr.chain_id}
- return bool(protein_chains.issubset(chains))
-
-
-def ligand_is_diffdock_loadable(ligand_file: Path) -> bool:
- try:
- lig = diffdock_utils.read_molecule(str(ligand_file))
- diffdock_utils.get_lig_graph_with_matching(lig)
- return True
- except Exception:
- return False
-
-
-def run_structure_checks(system_dict: dict[str, Any]) -> list[dict[str, Any]]:
- """Aggregate all the checks for a single system
-
- Parameters
- ----------
- system_dict : dict[str, Any]
- System dictionary
-
- Returns
- -------
- list[dict[str, Any]]
- """
- system_checks = []
- complex_path: Any = system_dict["complex_path"]
- for ligand_chain, ligand in system_dict["ligands"].items():
- ligand_path: Path = ligand["ligand_path"]
- protein_chains: Any = system_dict["protein_chains"]
- ligand_chains: Any = system_dict["ligand_chains"]
- system_checks.append(
- {
- "system_id": complex_path.parent.name,
- "ligand_instance": ligand["ligand_instance"],
- "ligand_asym_id": ligand["ligand_asym_id"],
- "ligand_is_rdkit_loadable": ligand_is_rdkit_loadable(ligand_path),
- "ligand_is_rdkit_loadable_with_fix": ligand_is_rdkit_loadable_with_fix(
- ligand_path
- ),
- "ligand_is_obabel_loadable": ligand_is_obabel_loadable(ligand_path),
- "ligand_is_obabel_loadable_with_rdkit_fix": ligand_is_obabel_loadable_with_rdkit_fix(
- ligand_path
- ),
- # "ligand_is_diffdock_loadable": ligand_is_diffdock_loadable(ligand_path),
- "ligand_matches_smiles_atom_num": ligand_matches_smiles_atom_num(
- ligand["ligand_resolved_smiles"], ligand_path
- ),
- "ligand_positions_correct": ligand_positions_correct(
- ligand["center_of_mass"], ligand_path
- ),
- "ligand_loadbable_via_biotite": file_loadbable_via_biotite(ligand_path),
- "ligand_molvs_validation": get_molvs_ligand_validation(ligand_path),
- "ligand_rdkit_validation": get_rdkit_ligand_validation(ligand_path),
- "complex_loadbable_via_biotite": file_loadbable_via_biotite(
- complex_path
- ),
- "ligand_protein_neighbor_still_preserved_complex": ligand_protein_neighbor_still_preserved_complex(
- protein_chains, complex_path, protein_chains, ligand_chains
- ),
- "all_ligand_chains_present": all_ligand_chains_present(
- ligand_chains, complex_path
- ),
- "all_protein_chains_present": all_protein_chains_present(
- protein_chains, complex_path
- ),
- }
- )
- return system_checks
-
-
-def prepare_system_dict(
- system_structure_path: Path,
- entry: "Entry",
-) -> Generator[dict[str, Any], None, None]:
- for sys_id, annotation in entry.systems.items():
- system_folder = sys_id
- ligands = {}
- if (system_structure_path / system_folder).exists():
- for lig in annotation.ligands:
- ligand_chain = f"{lig.instance}.{lig.asym_id}"
- ligands[ligand_chain] = {
- "ligand_path": system_structure_path
- / system_folder
- / "ligand_files"
- / f"{ligand_chain}.sdf",
- "ligand_instance": lig.instance,
- "ligand_asym_id": lig.asym_id,
- "ligand_smiles": lig.smiles,
- "ligand_resolved_smiles": lig.resolved_smiles,
- "center_of_mass": lig.centroid,
- }
- complex_file = system_structure_path / system_folder / "system.cif"
- receptor_path = system_structure_path / system_folder / "receptor.cif"
- system_dict = {
- "complex_path": complex_file,
- "receptor_path": receptor_path,
- "ligands": ligands,
- "protein_chains": set(annotation.protein_chains_asym_id),
- "ligand_chains": set(annotation.ligand_chains),
- }
- else:
- continue
- yield system_dict
-
-
-def prepare_system_dicts(
- system_structure_path: Path, all_entries_json: Path
-) -> Generator[dict[str, Any], None, None]:
- """
- Prepare dictionary input
-
- Parameters
- ----------
- system_structure_path : Path
- Folder for all system structure
- all_entries_json : Path
- All entries jsons
-
- Returns
- -------
- list[dict[str, Any]]
- """
- from plinder.data.utils.annotations.aggregate_annotations import Entry
-
- with open(all_entries_json, "rb") as f:
- data = json.load(f)
- for entry in data:
- yield from prepare_system_dict(
- system_structure_path, Entry.model_validate(entry)
- )
-
-
-def run_all_checks(system_structure_path: Path, all_entries_json: Path) -> pd.DataFrame:
- """
- Run all checks
-
- Parameters
- ----------
- system_structure_path : Path
- Folder for all system structure
- all_entries_json : Path
- All entries jsons
-
- Returns
- -------
- list[dict[str, Any]]
- """
- system_list = prepare_system_dicts(system_structure_path, all_entries_json)
- # TODO: Parallelize this, currently having issues with multiprocessing
- results = []
- for sys_dict in system_list:
- results.append(run_structure_checks(sys_dict))
- return pd.DataFrame([j for i in results for j in i])
diff --git a/src/plinder/data/get_system_annotations.py b/src/plinder/data/get_system_annotations.py
index 6e020025a..7b4eac3d4 100644
--- a/src/plinder/data/get_system_annotations.py
+++ b/src/plinder/data/get_system_annotations.py
@@ -2,16 +2,20 @@
# Distributed under the terms of the Apache License 2.0
from __future__ import annotations
-import json
import logging
from pathlib import Path
from typing import Any, Dict, Optional
import pandas as pd
-from tqdm import tqdm
+import pyarrow as pa
+import pyarrow.parquet as pq
from plinder.core.utils.log import setup_logger
-from plinder.data.utils.annotations.aggregate_annotations import Entry
+from plinder.data.annotations.aggregate_annotations import Entry
+from plinder.data.annotations.interface_utils import (
+ DEFAULT_MIN_INTERFACE_RESIDUES,
+ protein_interfaces_to_table,
+)
LOG = setup_logger(__name__, log_level=logging.DEBUG)
@@ -22,175 +26,271 @@ def __init__(
mmcif_file: Path,
validation_xml: Path,
save_folder: Optional[Path] = None,
+ data_dir: Optional[Path] = None,
neighboring_residue_threshold: float = 6.0,
- neighboring_ligand_threshold: float = 4.0, # TODO: review @VO
- min_polymer_size: int = 10, # TODO: review @VO,
+ neighboring_ligand_threshold: float = 4.0,
+ min_polymer_size: int = 12,
+ min_shared_pocket_members: int = 3,
symmetry_mate_contact_threshold: float = 5.0,
entry_cfg: Optional[Dict[Any, Any]] = None,
+ interface_cfg: Optional[Dict[Any, Any]] = None,
) -> None:
self.mmcif_file = mmcif_file
self.validation_xml = Path(validation_xml)
- self.save_folder = save_folder
+ self.save_folder = Path(save_folder) if save_folder is not None else None
+ self.data_dir = Path(data_dir) if data_dir is not None else None
self.neighboring_residue_threshold = neighboring_residue_threshold
self.neighboring_ligand_threshold = neighboring_ligand_threshold
self.min_polymer_size = min_polymer_size
+ self.min_shared_pocket_members = min_shared_pocket_members
self.symmetry_mate_contact_threshold = symmetry_mate_contact_threshold
self.entry_cfg = entry_cfg
+ self.interface_cfg = interface_cfg
- def annotate(self) -> Optional[pd.DataFrame]:
- entry_cfg = dict(
+ def _entry_options(
+ self, *, include_ligands: bool, include_interfaces: bool
+ ) -> dict[str, Any]:
+ """Resolve shared entry and protein-interface options."""
+ entry_cfg: dict[str, Any] = dict(
neighboring_residue_threshold=self.neighboring_residue_threshold,
neighboring_ligand_threshold=self.neighboring_ligand_threshold,
min_polymer_size=self.min_polymer_size,
- save_folder=self.save_folder,
+ min_shared_pocket_members=self.min_shared_pocket_members,
+ save_folder=self.save_folder if include_ligands else None,
+ data_dir=self.data_dir if include_ligands else None,
symmetry_mate_contact_threshold=self.symmetry_mate_contact_threshold,
+ include_ligands=include_ligands,
+ include_interfaces=include_interfaces,
)
if self.entry_cfg is not None:
entry_cfg.update(self.entry_cfg)
- self.entry = Entry.from_cif_file(
- self.mmcif_file,
- **entry_cfg, # type: ignore
- )
- LOG.info(f"created entry for {self.mmcif_file}")
- self.entry.set_validation(self.validation_xml, self.mmcif_file)
- if len(self.entry.systems):
- self.annotated_df = self.entry.to_df()
- if self.annotated_df.empty:
- raise ValueError(f"No ligands detected in entry {self.mmcif_file}")
- return self.annotated_df
- else:
- LOG.info(f"no entry systems for {self.mmcif_file}")
- return None
-
+ entry_cfg["include_ligands"] = include_ligands
+ entry_cfg["include_interfaces"] = include_interfaces
+ entry_cfg["save_folder"] = self.save_folder if include_ligands else None
+ entry_cfg["data_dir"] = self.data_dir if include_ligands else None
+ interface_cfg = dict(self.interface_cfg or {})
+ if interface_cfg:
+ entry_cfg.update(
+ {
+ "interface_contact_radius": interface_cfg.get(
+ "contact_radius", 10.0
+ ),
+ "interface_min_chain_length": interface_cfg.get(
+ "min_chain_length", 12
+ ),
+ "interface_min_residues": interface_cfg.get(
+ "min_interface_residues", DEFAULT_MIN_INTERFACE_RESIDUES
+ ),
+ "interface_annotate_prodigy": interface_cfg.get(
+ "annotate_prodigy", True
+ ),
+ }
+ )
+ return entry_cfg
-def hpc_save_batch(
- ids_file: Path,
- pdb_dir: Path,
- validation_dir: Path,
- output_file: Path,
- save_folder: Path,
-) -> None:
- json_list = []
- df_list = []
- errors = []
- with open(ids_file) as f:
- for pdb_id in tqdm(f):
- pdb_id = pdb_id.strip()
- try:
- cif_file = (
- pdb_dir
- / pdb_id[1:3]
- / f"pdb_0000{pdb_id}"
- / f"pdb_0000{pdb_id}_xyz-enrich.cif.gz"
- )
- validation_file = (
- validation_dir
- / pdb_id[1:3]
- / pdb_id
- / f"{pdb_id}_validation.xml.gz"
- )
- plinder_anno = GetPlinderAnnotation(
- cif_file,
- validation_file,
- save_folder=save_folder,
- )
- plinder_anno.annotate()
- json_list.append(plinder_anno.entry)
- if len(plinder_anno.entry.systems):
- df_list.append(plinder_anno.annotated_df)
- except Exception as e:
- errors.append(f"{pdb_id}: {e}\n")
- if len(df_list):
- pd.concat(df_list).to_csv(
- output_file.with_suffix(".tsv"), index=False, sep="\t"
+ def _interface_table(self, entry_cfg: dict[str, Any]) -> pa.Table:
+ return protein_interfaces_to_table(
+ self.entry.interfaces,
+ min_interface_residues=int(
+ entry_cfg.get("interface_min_residues", DEFAULT_MIN_INTERFACE_RESIDUES)
+ ),
)
- with open(output_file.with_suffix(".json"), "w") as f:
- f.write(json.dumps([entry.dict() for entry in json_list], indent=4))
- if len(errors):
- with open(output_file.with_suffix(".errors"), "w") as f:
- for line in errors:
- f.write(line)
+ def _write_shared_sidecars(
+ self,
+ entry_folder: Path,
+ interface_table: pa.Table,
+ *,
+ replace_interfaces: bool = True,
+ preserve_existing_shared: bool = False,
+ ) -> None:
+ """Write a new entry's sidecars or extend the preserved shared tables."""
+ from plinder.data.annotations.cif_utils import (
+ get_mmcif_revision,
+ read_mmcif_container,
+ )
-def cloud_save_annotation() -> None:
- from omegaconf import OmegaConf
-
- from plinder.data.pipeline.config import AnnotationConfig, EntryConfig
+ entry_folder.mkdir(parents=True, exist_ok=True)
- cfg = OmegaConf.to_container(
- OmegaConf.merge(
- {
- "mmcif_file": None,
- "validation_xml": None,
- "raise_exceptions": False,
- },
- {
- "annotation": AnnotationConfig(),
- "entry": EntryConfig(),
- },
- OmegaConf.from_cli(),
- )
- )
- assert cfg["mmcif_file"] is not None, "please pass mmcif_file=path/to/cif"
- assert cfg["validation_xml"] is not None, "please pass validation_xml=path/to/xml"
- cif = Path(cfg.pop("mmcif_file"))
- val = Path(cfg.pop("validation_xml"))
- entry_cfg = cfg.pop("entry")
- annotation_cfg = cfg.pop("annotation")
- save_folder = entry_cfg.get("save_folder")
- if save_folder is not None:
- save_folder = Path(save_folder)
- save_folder.mkdir(exist_ok=True, parents=True)
- entry_cfg["save_folder"] = save_folder
- LOG.info(f"annotating {cif}")
- gpa = GetPlinderAnnotation(
- cif,
- val,
- entry_cfg=entry_cfg,
- **annotation_cfg,
- )
- try:
- df = gpa.annotate()
- if save_folder is not None:
- pdb_id = val.stem.replace("_validation.xml", "")
- with open(f"{save_folder}/{pdb_id}.json", "w") as f:
- f.write(gpa.entry.model_dump_json(indent=4))
- except Exception as e:
- if cfg["raise_exceptions"]:
- raise e
- LOG.error(f"exception on annotating {cif}: {repr(e)}")
- if save_folder is not None:
- failure_log = Path(f"{save_folder}/failures.csv")
- pdb_id = val.stem.replace("_validation.xml", "")
- header = False
- if failure_log.is_file():
- df = pd.read_csv(failure_log, usecols=[0, 1])
- if pdb_id in df["pdb_id"]:
+ def write_dataframe(
+ path: Path,
+ frame: pd.DataFrame,
+ *,
+ merge_keys: tuple[str, ...] | None = None,
+ carry_columns: tuple[str, ...] = (),
+ replace_columns: tuple[str, ...] = (),
+ ) -> None:
+ if (
+ not preserve_existing_shared
+ and carry_columns
+ and merge_keys is not None
+ and path.is_file()
+ ):
+ existing = pd.read_parquet(path)
+ carried = [
+ column
+ for column in carry_columns
+ if column in existing.columns and column not in frame.columns
+ ]
+ if carried:
+ frame = frame.merge(
+ existing.loc[:, [*merge_keys, *carried]],
+ on=list(merge_keys),
+ how="left",
+ validate="one_to_one",
+ )
+ if preserve_existing_shared and path.is_file():
+ if merge_keys is None:
return
- else:
- header = True
- with open(f"{save_folder}/failures.csv", "a") as f:
- if header:
- f.write("pdb_id,error\n")
- f.write(f"{pdb_id},{repr(e).replace(',', '_')}\n")
+ existing = pd.read_parquet(path)
+ if not set(merge_keys).issubset(existing.columns):
+ missing = sorted(set(merge_keys).difference(existing.columns))
+ raise ValueError(f"{path} is missing merge keys: {missing}")
+ if not set(merge_keys).issubset(frame.columns):
+ missing = sorted(set(merge_keys).difference(frame.columns))
+ raise ValueError(
+ f"incoming {path} is missing merge keys: {missing}"
+ )
+ existing_columns = set(existing.columns)
+ new_columns = [
+ column for column in frame.columns if column not in existing.columns
+ ]
+ if new_columns:
+ additions = frame.loc[:, [*merge_keys, *new_columns]]
+ existing = existing.merge(
+ additions,
+ on=list(merge_keys),
+ how="left",
+ validate="one_to_one",
+ )
+ refreshed = [
+ column
+ for column in replace_columns
+ if column in existing_columns and column in frame.columns
+ ]
+ if refreshed:
+ existing = existing.drop(columns=refreshed).merge(
+ frame.loc[:, [*merge_keys, *refreshed]],
+ on=list(merge_keys),
+ how="left",
+ validate="one_to_one",
+ )
+ # Preserve ligand-derived values for existing rows while
+ # adding newly available columns and protein chains discovered
+ # by interface-only ingest.
+ incoming = frame.reindex(columns=existing.columns)
+ existing_keys = pd.MultiIndex.from_frame(
+ existing.loc[:, list(merge_keys)]
+ )
+ incoming_keys = pd.MultiIndex.from_frame(
+ incoming.loc[:, list(merge_keys)]
+ )
+ missing_rows = incoming.loc[~incoming_keys.isin(existing_keys)]
+ if missing_rows.empty and not new_columns and not refreshed:
+ return
+ frame = pd.concat([existing, missing_rows], ignore_index=True)
+ temporary = path.with_suffix(".parquet.tmp")
+ frame.to_parquet(temporary, index=False)
+ temporary.replace(path)
+ write_dataframe(
+ entry_folder / "entry_chains.parquet",
+ self.entry.chains_to_df(),
+ merge_keys=("entry_pdb_id", "chain_asym_id"),
+ )
+ write_dataframe(
+ entry_folder / "entry_metadata.parquet",
+ self.entry.metadata_to_df(),
+ merge_keys=("entry_pdb_id",),
+ )
+ interface_path = entry_folder / "interfaces.parquet"
+ if replace_interfaces or not interface_path.is_file():
+ temporary = interface_path.with_suffix(".parquet.tmp")
+ pq.write_table(interface_table, temporary)
+ temporary.replace(interface_path)
+ write_dataframe(
+ entry_folder / "entry_biounit_chains.parquet",
+ self.entry.biounit_chains_to_df(),
+ merge_keys=("entry_pdb_id", "biounit_id", "chain_instance"),
+ carry_columns=(
+ ("chain_num_contacting_proteins",) if not replace_interfaces else ()
+ ),
+ replace_columns=(
+ ("chain_num_contacting_proteins",) if preserve_existing_shared else ()
+ ),
+ )
+ source_path = entry_folder / "entry_source.parquet"
+ if not preserve_existing_shared or not source_path.is_file():
+ major_revision, minor_revision = get_mmcif_revision(
+ read_mmcif_container(self.mmcif_file)
+ )
+ write_dataframe(
+ source_path,
+ pd.DataFrame(
+ {
+ "entry_pdb_id": [self.entry.pdb_id],
+ "source_mmcif_major_revision": [major_revision],
+ "source_mmcif_minor_revision": [minor_revision],
+ }
+ ),
+ )
-if __name__ == "__main__":
- import logging
- from sys import argv
+ def annotate(self, *, include_interfaces: bool = True) -> Optional[pd.DataFrame]:
+ """Annotate ligand systems, optionally including protein interfaces."""
+ entry_cfg = self._entry_options(
+ include_ligands=True,
+ include_interfaces=include_interfaces,
+ )
+ self.entry = Entry.from_cif_file(
+ self.mmcif_file,
+ **entry_cfg,
+ )
+ LOG.info(f"created entry for {self.mmcif_file}")
+ self.entry.set_validation(self.validation_xml, self.mmcif_file)
+ interface_table = self._interface_table(entry_cfg)
+ self.interface_df = interface_table.to_pandas()
+ self.entry_metadata_df = self.entry.metadata_to_df()
+ resolved_save_folder = entry_cfg.get("save_folder")
+ if resolved_save_folder is not None:
+ if not isinstance(resolved_save_folder, (str, Path)):
+ raise TypeError("entry save_folder must be a path")
+ entry_folder = Path(resolved_save_folder) / self.entry.pdb_id
+ self._write_shared_sidecars(
+ entry_folder,
+ interface_table,
+ replace_interfaces=include_interfaces,
+ )
+ if not self.entry.systems and not self.entry.interfaces:
+ LOG.info(f"no ligand or interface systems for {self.mmcif_file}")
+ return None
+ self.annotated_df = self.entry.to_df()
+ return self.annotated_df
- # TODO : this is a naive way to branch the entrypoint
- # but will work because we in-line the entire
- # config in the cloud_save_annotation case
- # resulting in >> 6 CLI arguments
- if len(argv) == 6:
- logging.disable(logging.CRITICAL)
- hpc_save_batch(
- Path(argv[1]),
- Path(argv[2]),
- Path(argv[3]),
- Path(argv[4]),
- Path(argv[5]),
+ def annotate_interfaces(self) -> pa.Table:
+ """Annotate protein interfaces without deriving or replacing ligands."""
+ entry_cfg = self._entry_options(
+ include_ligands=False,
+ include_interfaces=True,
)
- else:
- cloud_save_annotation()
+ self.entry = Entry.from_cif_file(self.mmcif_file, **entry_cfg)
+ LOG.info(f"created interface-only entry for {self.mmcif_file}")
+ interface_table = self._interface_table(entry_cfg)
+ self.interface_df = interface_table.to_pandas()
+ if self.save_folder is None:
+ return interface_table
+
+ entry_folder = Path(self.save_folder) / self.entry.pdb_id
+ ligand_annotation = Path(self.save_folder) / f"{self.entry.pdb_id}.parquet"
+ if entry_folder.exists():
+ self._write_shared_sidecars(
+ entry_folder,
+ interface_table,
+ preserve_existing_shared=True,
+ )
+ elif ligand_annotation.is_file():
+ raise FileNotFoundError(
+ f"ligand annotation exists without its entry sidecars: {ligand_annotation}"
+ )
+ elif interface_table.num_rows:
+ self._write_shared_sidecars(entry_folder, interface_table)
+ return interface_table
diff --git a/src/plinder/data/interface_apo.py b/src/plinder/data/interface_apo.py
new file mode 100644
index 000000000..bf0452857
--- /dev/null
+++ b/src/plinder/data/interface_apo.py
@@ -0,0 +1,562 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Pair each protein-interface side with deposited non-interacting chains."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+from pathlib import Path
+from typing import Any, TypeAlias
+
+import numpy as np
+import pandas as pd
+import pyarrow as pa
+import pyarrow.dataset as ds
+import pyarrow.parquet as pq
+
+from plinder.core.utils.schemas import INTERFACE_APO_LINK_SCHEMA
+
+TableInput: TypeAlias = pd.DataFrame | str | Path
+
+INTERFACE_COLUMNS = (
+ "entry_pdb_id",
+ "system_id",
+ "interface_chain_1",
+ "interface_chain_2",
+)
+ENTRY_CHAIN_COLUMNS = (
+ "entry_pdb_id",
+ "chain_asym_id",
+ "chain_auth_id",
+ "chain_receptor_type",
+ "chain_is_ligand_like",
+)
+BIOUNIT_CHAIN_COLUMNS = (
+ "entry_pdb_id",
+ "biounit_id",
+ "chain_instance",
+ "chain_asym_id",
+ "chain_role",
+ "chain_num_contacting_proteins",
+ "chain_num_contacting_ions",
+ "chain_num_contacting_artifacts",
+ "chain_num_contacting_other_ligands",
+)
+ENTRY_METADATA_COLUMNS = ("entry_pdb_id", "entry_resolution")
+QUERY_COLUMNS = (
+ "query_entry",
+ "reference_system_id",
+ "reference_side",
+ "reference_chain_instance",
+ "reference_chain_asym_id",
+)
+CANDIDATE_COLUMNS = (
+ "target_system",
+ "source_entry_id",
+ "source_chain_asym_id",
+ "source_chain_auth_id",
+ "source_biounit_id",
+ "source_chain_instance",
+ "source_num_contacting_proteins",
+ "source_num_contacting_ions",
+ "source_num_contacting_artifacts",
+ "source_num_contacting_other_ligands",
+ "source_resolution",
+)
+ALIGNMENT_COLUMNS = (
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ "qcov",
+ "tcov",
+ "fident",
+)
+
+
+@dataclass(frozen=True)
+class InterfaceApoSelectionConfig:
+ """Similarity thresholds and maximum links for each interface side."""
+
+ max_per_side: int = 5
+ min_sequence_identity: float = 0.95
+ min_query_coverage: float = 0.80
+ min_target_coverage: float = 0.80
+
+ def __post_init__(self) -> None:
+ if self.max_per_side < 1:
+ raise ValueError("max_per_side must be positive")
+ thresholds = {
+ "min_sequence_identity": self.min_sequence_identity,
+ "min_query_coverage": self.min_query_coverage,
+ "min_target_coverage": self.min_target_coverage,
+ }
+ invalid = {
+ name: value for name, value in thresholds.items() if not 0 <= value <= 1
+ }
+ if invalid:
+ raise ValueError(f"interface apo thresholds must be in [0, 1]: {invalid}")
+
+
+def _dataset(path: str | Path) -> Any:
+ source = Path(path)
+ if source.is_dir():
+ return ds.dataset(
+ source,
+ format="parquet",
+ partitioning="hive",
+ exclude_invalid_files=True,
+ )
+ return ds.dataset(source, format="parquet", exclude_invalid_files=True)
+
+
+def _read_columns(
+ table: TableInput, columns: tuple[str, ...], name: str
+) -> pd.DataFrame:
+ if isinstance(table, pd.DataFrame):
+ available = set(table.columns)
+ frame = table
+ else:
+ available = set(_dataset(table).schema.names)
+ missing = sorted(set(columns).difference(available))
+ if missing:
+ raise ValueError(f"{name} is missing columns {missing}")
+ if not isinstance(table, pd.DataFrame):
+ frame = pd.read_parquet(table, columns=list(columns))
+ return frame.loc[:, columns].copy()
+
+
+def _required_strings(frame: pd.DataFrame, columns: tuple[str, ...], name: str) -> None:
+ for column in columns:
+ frame[column] = frame[column].astype("string")
+ if (frame[column].isna() | frame[column].str.strip().eq("")).any():
+ raise ValueError(f"{name} has empty {column} values")
+
+
+def build_interface_apo_query_manifest(interfaces: TableInput) -> pd.DataFrame:
+ """Return one query row for each side of every protein interface."""
+ frame = _read_columns(interfaces, INTERFACE_COLUMNS, "interface table")
+ _required_strings(frame, INTERFACE_COLUMNS, "interface table")
+ duplicate = frame["system_id"].duplicated(keep=False)
+ if duplicate.any():
+ examples = sorted(frame.loc[duplicate, "system_id"].unique())[:10]
+ raise ValueError(f"interface table has duplicate systems: {examples}")
+
+ sides = []
+ for side in (1, 2):
+ side_frame = frame[
+ ["entry_pdb_id", "system_id", f"interface_chain_{side}"]
+ ].rename(
+ columns={
+ "entry_pdb_id": "query_entry",
+ "system_id": "reference_system_id",
+ f"interface_chain_{side}": "reference_chain_instance",
+ }
+ )
+ side_frame["reference_side"] = side
+ sides.append(side_frame)
+ queries = pd.concat(sides, ignore_index=True)
+ queries["reference_chain_asym_id"] = (
+ queries["reference_chain_instance"].str.split(".", n=1).str[-1]
+ )
+ return queries.loc[:, QUERY_COLUMNS].sort_values(
+ ["query_entry", "reference_system_id", "reference_side"],
+ ignore_index=True,
+ )
+
+
+def _contact_counts(
+ frame: pd.DataFrame, columns: list[str], *, allow_missing: bool = False
+) -> None:
+ for column in columns:
+ frame[column] = pd.to_numeric(frame[column], errors="coerce")
+ valid = (
+ np.isfinite(frame[column])
+ & frame[column].ge(0)
+ & frame[column].mod(1).eq(0)
+ )
+ if allow_missing:
+ valid |= frame[column].isna()
+ if not valid.fillna(False).all():
+ raise ValueError(f"biological-assembly membership has invalid {column}")
+ frame[column] = frame[column].astype("Int64" if allow_missing else "int64")
+
+
+def build_interface_apo_candidate_manifest(
+ entry_chains: TableInput,
+ *,
+ biounit_chains: TableInput,
+ entry_metadata: TableInput,
+) -> pd.DataFrame:
+ """Choose a protein-contact-free assembly instance for each candidate chain."""
+ chains = _read_columns(entry_chains, ENTRY_CHAIN_COLUMNS, "entry chain table")
+ membership = _read_columns(
+ biounit_chains,
+ BIOUNIT_CHAIN_COLUMNS,
+ "biological-assembly membership table",
+ )
+ metadata = _read_columns(
+ entry_metadata,
+ ENTRY_METADATA_COLUMNS,
+ "entry metadata table",
+ )
+ _required_strings(
+ chains,
+ ("entry_pdb_id", "chain_asym_id", "chain_auth_id", "chain_receptor_type"),
+ "entry chain table",
+ )
+ if chains.duplicated(["entry_pdb_id", "chain_asym_id"]).any():
+ raise ValueError("entry chain table has duplicate entry/asym chain keys")
+ chains = chains.loc[
+ chains["chain_receptor_type"].str.lower().eq("protein")
+ & ~chains["chain_is_ligand_like"].fillna(False).astype(bool)
+ ].copy()
+
+ _required_strings(
+ membership,
+ (
+ "entry_pdb_id",
+ "biounit_id",
+ "chain_instance",
+ "chain_asym_id",
+ "chain_role",
+ ),
+ "biological-assembly membership table",
+ )
+ if membership.duplicated(["entry_pdb_id", "biounit_id", "chain_instance"]).any():
+ raise ValueError("biological-assembly membership has duplicate chain instances")
+ membership = membership.loc[
+ membership["chain_role"].str.lower().eq("receptor")
+ ].copy()
+ candidates = chains.merge(
+ membership,
+ on=["entry_pdb_id", "chain_asym_id"],
+ how="inner",
+ validate="one_to_many",
+ )
+ ligand_contact_columns = [
+ "chain_num_contacting_ions",
+ "chain_num_contacting_artifacts",
+ "chain_num_contacting_other_ligands",
+ ]
+ _contact_counts(candidates, ["chain_num_contacting_proteins"])
+ _contact_counts(candidates, ligand_contact_columns, allow_missing=True)
+ candidates = candidates.loc[candidates["chain_num_contacting_proteins"].eq(0)]
+ if candidates.empty:
+ return pd.DataFrame(columns=CANDIDATE_COLUMNS)
+
+ _required_strings(metadata, ("entry_pdb_id",), "entry metadata table")
+ if metadata["entry_pdb_id"].duplicated().any():
+ raise ValueError("entry metadata table has duplicate entries")
+ metadata["entry_resolution"] = pd.to_numeric(
+ metadata["entry_resolution"], errors="coerce"
+ )
+ invalid_resolution = metadata["entry_resolution"].notna() & ~(
+ np.isfinite(metadata["entry_resolution"]) & metadata["entry_resolution"].gt(0)
+ )
+ if invalid_resolution.any():
+ raise ValueError("entry metadata has invalid resolutions")
+ candidates = candidates.merge(
+ metadata,
+ on="entry_pdb_id",
+ how="left",
+ validate="many_to_one",
+ )
+ candidates["ligand_contacts_unknown"] = (
+ candidates[ligand_contact_columns].isna().any(axis=1)
+ )
+ candidates["ligand_contact_class"] = np.select(
+ [
+ candidates["chain_num_contacting_other_ligands"].gt(0).fillna(False),
+ candidates["chain_num_contacting_artifacts"].gt(0).fillna(False),
+ candidates["chain_num_contacting_ions"].gt(0).fillna(False),
+ ],
+ [3, 2, 1],
+ default=0,
+ )
+ candidates["num_contacting_ligands"] = candidates[ligand_contact_columns].sum(
+ axis=1, min_count=1
+ )
+ candidates = candidates.sort_values(
+ [
+ "entry_pdb_id",
+ "chain_asym_id",
+ "ligand_contacts_unknown",
+ "ligand_contact_class",
+ "num_contacting_ligands",
+ "entry_resolution",
+ "biounit_id",
+ "chain_instance",
+ ],
+ ignore_index=True,
+ na_position="last",
+ ).drop_duplicates(["entry_pdb_id", "chain_asym_id"])
+ candidates["target_system"] = (
+ candidates["entry_pdb_id"] + "_" + candidates["chain_asym_id"]
+ )
+ candidates = candidates.rename(
+ columns={
+ "entry_pdb_id": "source_entry_id",
+ "chain_asym_id": "source_chain_asym_id",
+ "chain_auth_id": "source_chain_auth_id",
+ "biounit_id": "source_biounit_id",
+ "chain_instance": "source_chain_instance",
+ "chain_num_contacting_proteins": "source_num_contacting_proteins",
+ "chain_num_contacting_ions": "source_num_contacting_ions",
+ "chain_num_contacting_artifacts": "source_num_contacting_artifacts",
+ "chain_num_contacting_other_ligands": (
+ "source_num_contacting_other_ligands"
+ ),
+ "entry_resolution": "source_resolution",
+ }
+ )
+ return candidates.loc[:, CANDIDATE_COLUMNS].reset_index(drop=True)
+
+
+def _parquet_files(path: str | Path) -> list[Path]:
+ source = Path(path)
+ if source.is_file():
+ return [source]
+ return sorted(source.rglob("*.parquet")) if source.is_dir() else []
+
+
+def _sql_string(value: str) -> str:
+ return "'" + value.replace("'", "''") + "'"
+
+
+def _sql_path(path: str | Path) -> str:
+ return _sql_string(Path(path).resolve().as_posix())
+
+
+def _sql_sources(paths: list[Path]) -> str:
+ values = ", ".join(_sql_path(path) for path in paths)
+ return f"[{values}]"
+
+
+def _empty_output(path: Path) -> Path:
+ path.parent.mkdir(parents=True, exist_ok=True)
+ temporary = path.with_suffix(path.suffix + ".tmp")
+ pq.write_table(
+ pa.Table.from_pylist([], schema=INTERFACE_APO_LINK_SCHEMA),
+ temporary,
+ compression="zstd",
+ )
+ temporary.replace(path)
+ return path
+
+
+def write_interface_apo_structure_table(
+ mmseqs_alignments: str | Path,
+ *,
+ foldseek_alignments: str | Path,
+ queries: TableInput,
+ candidates: TableInput,
+ output_path: str | Path,
+ config: InterfaceApoSelectionConfig | None = None,
+ scratch_dir: str | Path | None = None,
+ threads: int = 1,
+ memory_limit: str = "7GB",
+) -> Path:
+ """Write ranked protein-contact-free chain links for interface sides."""
+ import duckdb
+
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ config = config or InterfaceApoSelectionConfig()
+ output = Path(output_path)
+ query_frame = _read_columns(queries, QUERY_COLUMNS, "interface apo queries")
+ candidate_frame = _read_columns(
+ candidates, CANDIDATE_COLUMNS, "interface apo candidates"
+ )
+ if query_frame.empty or candidate_frame.empty:
+ return _empty_output(output)
+ mmseqs_files = _parquet_files(mmseqs_alignments)
+ if not mmseqs_files:
+ raise FileNotFoundError(
+ f"no MMseqs alignment shards found at {mmseqs_alignments}"
+ )
+ for path in mmseqs_files:
+ missing = sorted(set(ALIGNMENT_COLUMNS).difference(pq.read_schema(path).names))
+ if missing:
+ raise ValueError(f"MMseqs alignment {path} is missing columns {missing}")
+ foldseek_files = _parquet_files(foldseek_alignments)
+ for path in foldseek_files:
+ required = set(ALIGNMENT_COLUMNS) | {"lddt"}
+ missing = sorted(required.difference(pq.read_schema(path).names))
+ if missing:
+ raise ValueError(f"Foldseek alignment {path} is missing columns {missing}")
+
+ scratch = Path(scratch_dir or output.parent / ".interface-apo-scratch")
+ scratch.mkdir(parents=True, exist_ok=True)
+ output.parent.mkdir(parents=True, exist_ok=True)
+ temporary = output.with_suffix(output.suffix + ".tmp")
+ temporary.unlink(missing_ok=True)
+ foldseek_sql = (
+ f"""
+ SELECT query_entry, target_entry, query_chain_mapped,
+ target_chain_mapped, MAX(lddt) AS foldseek_lddt
+ FROM read_parquet({_sql_sources(foldseek_files)}, union_by_name=true)
+ GROUP BY query_entry, target_entry, query_chain_mapped, target_chain_mapped
+ """
+ if foldseek_files
+ else """
+ SELECT NULL::VARCHAR AS query_entry, NULL::VARCHAR AS target_entry,
+ NULL::VARCHAR AS query_chain_mapped,
+ NULL::VARCHAR AS target_chain_mapped,
+ NULL::DOUBLE AS foldseek_lddt
+ WHERE FALSE
+ """
+ )
+ connection = duckdb.connect()
+ try:
+ connection.register("interface_apo_queries", query_frame)
+ connection.register("interface_apo_candidates", candidate_frame)
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory={_sql_path(scratch)}")
+ connection.sql(f"SET memory_limit={_sql_string(memory_limit)}")
+ connection.sql("SET preserve_insertion_order=false")
+ connection.sql(
+ f"""
+ COPY (
+ WITH foldseek AS ({foldseek_sql}),
+ qualifying_mmseqs AS (
+ SELECT
+ *,
+ ROW_NUMBER() OVER (
+ PARTITION BY query_entry, target_entry,
+ query_chain_mapped, target_chain_mapped
+ ORDER BY
+ fident DESC,
+ LEAST(qcov, tcov) DESC,
+ qcov DESC,
+ tcov DESC
+ ) AS alignment_rank
+ FROM read_parquet(
+ {_sql_sources(mmseqs_files)}, union_by_name=true
+ )
+ WHERE fident >= {config.min_sequence_identity}
+ AND qcov >= {config.min_query_coverage}
+ AND tcov >= {config.min_target_coverage}
+ ),
+ mmseqs AS (
+ SELECT
+ query_entry, target_entry, query_chain_mapped,
+ target_chain_mapped,
+ fident AS mmseqs_fident,
+ qcov AS mmseqs_query_coverage,
+ tcov AS mmseqs_target_coverage
+ FROM qualifying_mmseqs
+ WHERE alignment_rank = 1
+ ),
+ eligible AS (
+ SELECT
+ query.reference_system_id,
+ query.reference_side,
+ query.reference_chain_instance,
+ query.reference_chain_asym_id,
+ candidate.*,
+ mmseqs.mmseqs_fident,
+ mmseqs.mmseqs_query_coverage,
+ mmseqs.mmseqs_target_coverage,
+ foldseek.foldseek_lddt
+ FROM interface_apo_queries AS query
+ INNER JOIN mmseqs
+ ON query.query_entry = mmseqs.query_entry
+ AND query.reference_chain_asym_id
+ = mmseqs.query_chain_mapped
+ INNER JOIN interface_apo_candidates AS candidate
+ ON candidate.source_entry_id = mmseqs.target_entry
+ AND candidate.source_chain_asym_id
+ = mmseqs.target_chain_mapped
+ LEFT JOIN foldseek
+ ON foldseek.query_entry = mmseqs.query_entry
+ AND foldseek.target_entry = mmseqs.target_entry
+ AND foldseek.query_chain_mapped = mmseqs.query_chain_mapped
+ AND foldseek.target_chain_mapped = mmseqs.target_chain_mapped
+ WHERE query.query_entry != candidate.source_entry_id
+ AND candidate.source_num_contacting_proteins = 0
+ ),
+ ranked AS (
+ SELECT *, ROW_NUMBER() OVER (
+ PARTITION BY reference_system_id, reference_side
+ ORDER BY
+ source_num_contacting_ions IS NULL
+ OR source_num_contacting_artifacts IS NULL
+ OR source_num_contacting_other_ligands IS NULL,
+ CASE
+ WHEN source_num_contacting_other_ligands > 0 THEN 3
+ WHEN source_num_contacting_artifacts > 0 THEN 2
+ WHEN source_num_contacting_ions > 0 THEN 1
+ ELSE 0
+ END,
+ COALESCE(source_num_contacting_ions, 0)
+ + COALESCE(source_num_contacting_artifacts, 0)
+ + COALESCE(
+ source_num_contacting_other_ligands, 0
+ ),
+ source_resolution IS NULL,
+ source_resolution,
+ mmseqs_fident DESC,
+ LEAST(
+ mmseqs_query_coverage,
+ mmseqs_target_coverage
+ ) DESC,
+ foldseek_lddt DESC NULLS LAST,
+ source_entry_id,
+ source_chain_asym_id
+ ) AS link_rank
+ FROM eligible
+ )
+ SELECT
+ CAST(reference_system_id AS VARCHAR) AS reference_system_id,
+ CAST(reference_side AS TINYINT) AS reference_side,
+ CAST(reference_chain_instance AS VARCHAR)
+ AS reference_chain_instance,
+ CAST(reference_chain_asym_id AS VARCHAR)
+ AS reference_chain_asym_id,
+ CAST(target_system AS VARCHAR) AS linked_structure_id,
+ CAST(source_entry_id AS VARCHAR) AS source_entry_id,
+ CAST(source_chain_asym_id AS VARCHAR)
+ AS source_chain_asym_id,
+ CAST(source_chain_auth_id AS VARCHAR)
+ AS source_chain_auth_id,
+ CAST(source_biounit_id AS VARCHAR) AS source_biounit_id,
+ CAST(source_chain_instance AS VARCHAR)
+ AS source_chain_instance,
+ CAST(source_num_contacting_proteins AS SMALLINT)
+ AS source_num_contacting_proteins,
+ CAST(source_num_contacting_ions AS SMALLINT)
+ AS source_num_contacting_ions,
+ CAST(source_num_contacting_artifacts AS SMALLINT)
+ AS source_num_contacting_artifacts,
+ CAST(source_num_contacting_other_ligands AS SMALLINT)
+ AS source_num_contacting_other_ligands,
+ CAST(source_resolution AS FLOAT) AS source_resolution,
+ CAST(link_rank AS SMALLINT) AS rank,
+ CAST(mmseqs_fident AS FLOAT) AS mmseqs_fident,
+ CAST(mmseqs_query_coverage AS FLOAT)
+ AS mmseqs_query_coverage,
+ CAST(mmseqs_target_coverage AS FLOAT)
+ AS mmseqs_target_coverage,
+ CAST(foldseek_lddt AS FLOAT) AS foldseek_lddt
+ FROM ranked
+ WHERE link_rank <= {config.max_per_side}
+ ORDER BY reference_system_id, reference_side, rank
+ ) TO {_sql_path(temporary)} (
+ FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ temporary.replace(output)
+ finally:
+ connection.close()
+ temporary.unlink(missing_ok=True)
+ return output
+
+
+__all__ = [
+ "InterfaceApoSelectionConfig",
+ "build_interface_apo_candidate_manifest",
+ "build_interface_apo_query_manifest",
+ "write_interface_apo_structure_table",
+]
diff --git a/src/plinder/data/leakage.py b/src/plinder/data/leakage.py
deleted file mode 100644
index 9dc6c1d30..000000000
--- a/src/plinder/data/leakage.py
+++ /dev/null
@@ -1,253 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from pathlib import Path
-
-import pandas as pd
-
-from plinder.core.utils import gcs
-from plinder.core.utils.log import setup_logger
-
-LOG = setup_logger(__name__)
-
-
-def get_workshop_splits() -> list[str]:
- remote_dir = "gs://plinder-collab-bucket/2024-04"
- return [
- f"{remote_dir}/v1/splits/v0/pdbbind/pdbbind.csv",
- f"{remote_dir}/v1/splits/v0/pdbbind_lp/pdbbind_lp.csv",
- f"{remote_dir}/v1/splits/v0/equibind/equibind.csv",
- f"{remote_dir}/v1/splits/v0/dockgen/dockgen.csv",
- f"{remote_dir}/v1/workshop_split/ecod_split.csv",
- f"{remote_dir}/v1/workshop_split/plinder_v0_no_posbuster.csv",
- f"{remote_dir}/v1/workshop_split/time_split.csv",
- ]
-
-
-def get_missing_pdb_ids(data_dir: Path) -> set[str]:
- entries = pd.read_parquet(data_dir / "index" / "annotation_table.parquet")
- seqsim_cluster = pd.read_parquet(
- data_dir
- / "clusters"
- / "cluster=components"
- / "directed=False"
- / "metric=protein_seqsim_max"
- / "threshold=50.parquet"
- )
-
- LOG.info(f"entries {entries.shape}")
- LOG.info(f"seqsim cluster {seqsim_cluster.shape}")
- s = seqsim_cluster.groupby("label").size()
- missing = set(
- seqsim_cluster[seqsim_cluster["label"].isin(s[s == 1].index.values)][
- "system_id"
- ]
- )
- LOG.info(f"singular system_ids {len(set(missing))}")
- pdb_ids = entries[entries["system_id"].isin(missing)][["system_id", "entry_pdb_id"]]
- LOG.info(f"missing entry_pdb_ids {pdb_ids['entry_pdb_id'].nunique()}")
- pdb_ids.to_csv("missing_pdb_ids.csv", index=False)
- LOG.info("missing the following pdb ids in the scores dataset:")
- LOG.info(",".join(set(pdb_ids["entry_pdb_id"])))
- return set(pdb_ids["entry_pdb_id"])
-
-
-def get_index_and_split_sets(
- data_dir: Path,
- split_file: str,
- compare_pair: str,
-) -> tuple[pd.DataFrame, str, pd.DataFrame, set[str], set[str]]:
- index = pd.read_parquet(data_dir / "index/annotation_table.parquet")
- missing = get_missing_pdb_ids(data_dir)
- if split_file.endswith(".csv"):
- split = pd.read_csv(split_file)
- else:
- split = pd.read_parquet(split_file)
- if compare_pair == "train_posebusters":
- left = set(split[split["split"] == "train"]["system_id"]).difference(missing)
- text = gcs.download_as_str(
- gcs_path="gs://plinder-collab-bucket/2024-04/v1/posebuster_system_ids.csv"
- )
- right = set(line.strip() for line in text.splitlines()).difference(missing)
- else:
- left_target, right_target = compare_pair.split("_")
- left = set(split[split["split"] == left_target]["system_id"]).difference(
- missing
- )
- right = set(split[split["split"] == right_target]["system_id"]).difference(
- missing
- )
- replace_keys = {
- "ecod_split": "plinder-ECOD",
- "plinder_v0_no_posbuster": "plinder-v0",
- "time_split": "plinder-Time",
- }
- split_name = Path(split_file).stem
- split_name = replace_keys.get(split_name, split_name)
- LOG.info(
- f"split_file={split_file}, split_name={split_name}, compare_pair={compare_pair}"
- )
- LOG.info(f"num_left={len(left)}, num_right={len(right)}")
- return index, split_name, split, left, right
-
-
-def compute_ligand_leakage(
- *,
- data_dir: Path,
- split_file: str,
- compare_pair: str,
- metric: str,
-) -> None:
- df, split_name, split, left, right = get_index_and_split_sets(
- data_dir, split_file, compare_pair
- )
-
- ligands_per_system = pd.read_parquet(
- data_dir / "fingerprints/ligands_per_system.parquet"
- )
- mapr = dict(
- zip(
- ligands_per_system["ligand_rdkit_canonical_smiles"],
- ligands_per_system["number_id_by_inchikeys"],
- )
- )
- df["number_id_by_inchikeys"] = df["ligand_rdkit_canonical_smiles"].map(mapr)
- LOG.info(f"number_id_by_inchikeys={df['number_id_by_inchikeys'].nunique()}")
-
- left_ligand_ids = set(df[df["system_id"].isin(left)]["number_id_by_inchikeys"])
- right_ligand_ids = set(df[df["system_id"].isin(right)]["number_id_by_inchikeys"])
- LOG.info(f"left_ligand_ids={len(left_ligand_ids)}")
- LOG.info(f"right_ligand_ids={len(right_ligand_ids)}")
-
- ligands = pd.read_parquet(
- data_dir / "ligand_scores",
- columns=["query_ligand_id", "target_ligand_id", metric],
- filters=[
- [
- ("query_ligand_id", "in", left_ligand_ids),
- ("target_ligand_id", "in", right_ligand_ids),
- ],
- [
- ("query_ligand_id", "in", right_ligand_ids),
- ("target_ligand_id", "in", left_ligand_ids),
- ],
- ],
- )
-
- LOG.info(f"ligands={len(ligands.index)}")
- LOG.info(f"unique_query_ligand_id={ligands['query_ligand_id'].nunique()}")
- LOG.info(f"unique_target_ligand_id={ligands['target_ligand_id'].nunique()}")
-
- updated_query_ligand_ids = []
- for q, t in zip(ligands["query_ligand_id"], ligands["target_ligand_id"]):
- if t in right_ligand_ids:
- updated_query_ligand_ids.append(t)
- else:
- updated_query_ligand_ids.append(q)
- ligands["updated_query_ligand_id"] = updated_query_ligand_ids
- LOG.info(
- f"unique_updated_query_ligand_id={ligands['updated_query_ligand_id'].nunique()}"
- )
-
- idx = ligands.groupby("updated_query_ligand_id")[metric].idxmax()
- ligands = ligands.loc[idx]
- ligand_to_system = {}
- for ligand_id, group in ligands_per_system.groupby("number_id_by_inchikeys"):
- ligand_to_system[ligand_id] = set(group["system_id"])
- ligands["query_system"] = ligands["query_ligand_id"].map(ligand_to_system)
- leakage_dir = data_dir / "leakage"
- leakage_dir.mkdir(exist_ok=True, parents=True)
- exploded = ligands.explode("query_system")
- LOG.info(f"exploded={len(exploded.index)}")
- filename = leakage_dir / f"{split_name}__{metric}__{compare_pair}.parquet"
- LOG.info(f"writing {filename}")
- exploded[["query_system", metric]].rename(
- columns={
- metric: "similarity",
- }
- ).to_parquet(filename, index=False)
-
-
-def compute_protein_leakage(
- *,
- data_dir: Path,
- split_file: str,
- compare_pair: str,
- metric: str,
-) -> None:
- df, split_name, split, left, right = get_index_and_split_sets(
- data_dir, split_file, compare_pair
- )
- # quality_config = TestCriteria()
- # df["system_num_covalent_ligands"] = df.groupby("system_id")["ligand_is_covalent"].transform("sum")
- # df["passes_quality"] = df.apply(lambda row: get_high_quality_systems(row, criteria=quality_config), axis=1)
- # passes_quality = set(df[df["passes_quality"]]["system_id"])
-
- leakage_dir = data_dir / "leakage"
- leakage_dir.mkdir(exist_ok=True, parents=True)
- # for metric in [
- # "pli_qcov",
- # "pocket_qcov",
- # "pocket_lddt",
- # "protein_seqsim_weighted_sum",
- # "protein_fident_weighted_sum",
- # "protein_lddt_weighted_sum",
- # "protein_lddt_qcov_weighted_sum",
- # ]:
- scores = pd.read_parquet(
- data_dir / "scores" / "search_db=holo",
- columns=["query_system", "target_system", "similarity"],
- filters=[
- [
- ("query_system", "in", left),
- ("target_system", "in", right),
- ("metric", "==", metric),
- ],
- [
- ("query_system", "in", right),
- ("target_system", "in", left),
- ("metric", "==", metric),
- ],
- ],
- )
- updated_query_systems = []
- for q, t in zip(scores["query_system"], scores["target_system"]):
- if t in right:
- updated_query_systems.append(t)
- else:
- updated_query_systems.append(q)
-
- scores["updated_query_system"] = updated_query_systems
-
- LOG.info(f"scores={len(scores.index)}")
- idx = scores.groupby("updated_query_system")["similarity"].idxmax()
- scores = scores.loc[idx][["updated_query_system", "similarity"]].rename(
- columns={"updated_query_system": "query_system"}
- )
- LOG.info(f"scores_after_groupby={len(scores.index)}")
- filename = leakage_dir / f"{split_name}__{metric}__{compare_pair}.parquet"
- LOG.info(f"writing {filename}")
- scores.to_parquet(filename, index=False)
- # if compare_pair in ["train_test", "val_test"]:
- # scores = pd.read_parquet(
- # data_dir / "scores" / "search_db=holo",
- # columns=["query_system", "similarity"],
- # filters=[
- # [
- # ("query_system", "in", left.intersection(passes_quality)),
- # ("target_system", "in", right.intersection(passes_quality)),
- # ("metric", "==", metric),
- # ],
- # [
- # ("query_system", "in", right.intersection(passes_quality)),
- # ("target_system", "in", left.intersection(passes_quality)),
- # ("metric", "==", metric),
- # ],
- # ],
- # )
- # LOG.info(f"scores_hq={len(scores.index)}")
- # idx = scores.groupby("query_system")["similarity"].idxmax()
- # scores = scores.loc[idx]
- # LOG.info(f"scores_after_groupby_hq={len(scores.index)}")
- # filename = leakage_dir / f"{split_name}__{metric}__{compare_pair}_hq.parquet"
- # LOG.info(f"writing {filename}")
- # scores.to_parquet(filename, index=False)
diff --git a/src/plinder/data/linked_apo.py b/src/plinder/data/linked_apo.py
new file mode 100644
index 000000000..f34547ea4
--- /dev/null
+++ b/src/plinder/data/linked_apo.py
@@ -0,0 +1,953 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from __future__ import annotations
+
+from dataclasses import dataclass
+from pathlib import Path
+from typing import Any, TypeAlias
+
+import numpy as np
+import pandas as pd
+import pyarrow as pa
+import pyarrow.dataset as ds
+import pyarrow.parquet as pq
+
+from plinder.core.utils.schemas import STRUCTURE_LINK_SCHEMA
+
+TableInput: TypeAlias = pd.DataFrame | str | Path
+
+REQUIRED_SCORE_METRICS = (
+ "pocket_fident",
+ "protein_fident_weighted_sum",
+ "protein_fident_qcov_weighted_sum",
+ "protein_lddt_weighted_sum",
+)
+SCORE_COLUMNS = (
+ "query_system",
+ "query_ligand_id",
+ "target_system",
+ "metric",
+ "similarity",
+)
+ANNOTATION_COLUMNS = ("system_id", "ligand_id", "ligand_is_proper")
+HOLO_CHAIN_ANNOTATION_COLUMNS = (
+ "entry_pdb_id",
+ "ligand_is_proper",
+ "ligand_protein_chains_asym_id",
+)
+ENTRY_CHAIN_COLUMNS = (
+ "entry_pdb_id",
+ "chain_asym_id",
+ "chain_auth_id",
+ "chain_entity_id",
+ "chain_receptor_type",
+ "chain_is_ligand_like",
+)
+BIOUNIT_CHAIN_COLUMNS = (
+ "entry_pdb_id",
+ "biounit_id",
+ "chain_instance",
+ "chain_asym_id",
+ "chain_role",
+ "chain_num_contacting_ions",
+ "chain_num_contacting_artifacts",
+ "chain_num_contacting_other_ligands",
+)
+ENTRY_METADATA_COLUMNS = ("entry_pdb_id", "entry_resolution")
+APO_CANDIDATE_COLUMNS = (
+ "target_system",
+ "source_entry_id",
+ "source_chain_asym_id",
+ "source_chain_auth_id",
+ "source_biounit_id",
+ "source_chain_instance",
+ "source_num_contacting_ions",
+ "source_num_contacting_artifacts",
+ "source_num_contacting_other_ligands",
+ "source_resolution",
+)
+
+
+def _sql_path(path: str | Path) -> str:
+ return Path(path).resolve().as_posix().replace("'", "''")
+
+
+def _parquet_dataset(path: str | Path) -> Any:
+ source = Path(path)
+ if source.is_dir():
+ return ds.dataset(
+ source,
+ format="parquet",
+ partitioning="hive",
+ exclude_invalid_files=True,
+ )
+ return ds.dataset(source, format="parquet", exclude_invalid_files=True)
+
+
+def _sql_parquet_source(path: str | Path) -> str:
+ source = Path(path).resolve()
+ if source.is_dir():
+ source = source / "**/*.parquet"
+ return source.as_posix().replace("'", "''")
+
+
+def _check_parquet_columns(
+ table: str | Path, columns: tuple[str, ...], name: str
+) -> None:
+ available = set(_parquet_dataset(table).schema.names)
+ missing = sorted(set(columns).difference(available))
+ if missing:
+ raise ValueError(f"{name} is missing columns {missing}")
+
+
+@dataclass(frozen=True)
+class LinkedApoSelectionConfig:
+ """Similarity thresholds and the maximum apo links per holo system."""
+
+ max_per_system: int = 5
+ min_pocket_fident: int = 95
+ min_protein_fident_weighted_sum: int = 95
+ min_protein_fident_qcov_weighted_sum: int = 80
+ min_protein_lddt_weighted_sum: int = 20
+
+ def __post_init__(self) -> None:
+ if self.max_per_system < 1:
+ raise ValueError("max_per_system must be positive")
+ thresholds = {
+ "min_pocket_fident": self.min_pocket_fident,
+ "min_protein_fident_weighted_sum": (self.min_protein_fident_weighted_sum),
+ "min_protein_fident_qcov_weighted_sum": (
+ self.min_protein_fident_qcov_weighted_sum
+ ),
+ "min_protein_lddt_weighted_sum": self.min_protein_lddt_weighted_sum,
+ }
+ invalid = {
+ name: value for name, value in thresholds.items() if not 0 <= value <= 100
+ }
+ if invalid:
+ raise ValueError(f"linked-apo thresholds must be in [0, 100]: {invalid}")
+
+
+def _read_columns(
+ table: TableInput, columns: tuple[str, ...], name: str
+) -> pd.DataFrame:
+ if isinstance(table, pd.DataFrame):
+ missing = sorted(set(columns).difference(table.columns))
+ if missing:
+ raise ValueError(f"{name} is missing columns {missing}")
+ return table.loc[:, columns].copy()
+ path = Path(table)
+ available = set(_parquet_dataset(path).schema.names)
+ missing = sorted(set(columns).difference(available))
+ if missing:
+ raise ValueError(f"{name} is missing columns {missing}")
+ return pd.read_parquet(path, columns=list(columns))
+
+
+def _read_score_columns(table: TableInput) -> pd.DataFrame:
+ if isinstance(table, pd.DataFrame):
+ return _read_columns(table, SCORE_COLUMNS, "protein score table")
+ path = Path(table)
+ available = set(_parquet_dataset(path).schema.names)
+ missing = sorted(set(SCORE_COLUMNS).difference(available))
+ if missing:
+ raise ValueError(f"protein score table is missing columns {missing}")
+ return pd.read_parquet(
+ path,
+ columns=list(SCORE_COLUMNS),
+ filters=[("metric", "in", list(REQUIRED_SCORE_METRICS))],
+ )
+
+
+def _as_required_strings(frame: pd.DataFrame, columns: list[str], name: str) -> None:
+ for column in columns:
+ frame[column] = frame[column].astype("string")
+ missing = frame[column].isna() | frame[column].str.strip().eq("")
+ if missing.any():
+ raise ValueError(f"{name} has empty {column} values")
+
+
+def ligand_holo_chain_keys(annotation: TableInput) -> pd.DataFrame:
+ """Return receptor-chain keys bound to proper ligands."""
+ frame = _read_columns(
+ annotation,
+ HOLO_CHAIN_ANNOTATION_COLUMNS,
+ "annotation table",
+ )
+ proper = frame["ligand_is_proper"].fillna(False).astype(bool)
+ keys = frame.loc[proper].explode("ligand_protein_chains_asym_id", ignore_index=True)
+ keys = keys.rename(columns={"ligand_protein_chains_asym_id": "chain_instance"})
+ keys = keys[["entry_pdb_id", "chain_instance"]]
+ encoded = keys["chain_instance"].astype("string")
+ keys = keys.loc[encoded.notna() & encoded.str.strip().ne("")].copy()
+ if keys.empty:
+ return pd.DataFrame(columns=["entry_pdb_id", "chain_asym_id"])
+ _as_required_strings(
+ keys,
+ ["entry_pdb_id", "chain_instance"],
+ "annotation table proper-ligand chains",
+ )
+ keys["chain_asym_id"] = keys.pop("chain_instance").str.split(".", n=1).str[-1]
+ return keys.drop_duplicates(ignore_index=True)
+
+
+def build_apo_candidate_manifest(
+ entry_chains: TableInput,
+ *,
+ biounit_chains: TableInput,
+ entry_metadata: TableInput,
+ annotation: TableInput,
+) -> pd.DataFrame:
+ """Build one scored target row per apo protein chain.
+
+ A protein chain is apo when it is not ligand-like, is not bound to a
+ proper ligand, and does not share an entity with a proper-ligand receptor
+ chain in its entry. Protein-interface membership is independent of this
+ ligand-relative definition. If a chain occurs in several biological
+ assemblies, the assembly with the cleanest chain-local ligand environment
+ is retained.
+ """
+ chains = _read_columns(entry_chains, ENTRY_CHAIN_COLUMNS, "entry chain table")
+ membership = _read_columns(
+ biounit_chains,
+ BIOUNIT_CHAIN_COLUMNS,
+ "biological-assembly membership table",
+ )
+ metadata = _read_columns(
+ entry_metadata,
+ ENTRY_METADATA_COLUMNS,
+ "entry metadata table",
+ )
+ holo_keys = ligand_holo_chain_keys(annotation)
+ _as_required_strings(
+ chains,
+ [
+ "entry_pdb_id",
+ "chain_asym_id",
+ "chain_auth_id",
+ "chain_receptor_type",
+ ],
+ "entry chain table",
+ )
+ chains["chain_entity_id"] = chains["chain_entity_id"].astype("string")
+ duplicate_chains = chains.duplicated(["entry_pdb_id", "chain_asym_id"], keep=False)
+ if duplicate_chains.any():
+ examples = (
+ chains.loc[duplicate_chains, ["entry_pdb_id", "chain_asym_id"]]
+ .drop_duplicates()
+ .head(10)
+ .to_dict("records")
+ )
+ raise ValueError(f"entry chain table has duplicate chains: {examples}")
+
+ holo_keys["chain_is_holo"] = True
+ chains = chains.merge(
+ holo_keys,
+ on=["entry_pdb_id", "chain_asym_id"],
+ how="left",
+ validate="one_to_one",
+ )
+ holo = chains["chain_is_holo"].eq(True)
+ usable_entity = chains["chain_entity_id"].notna() & chains[
+ "chain_entity_id"
+ ].str.strip().ne("")
+ holo_entities = chains.loc[
+ holo & usable_entity, ["entry_pdb_id", "chain_entity_id"]
+ ].drop_duplicates()
+ holo_entities["entity_is_holo"] = True
+ ligand_like = chains["chain_is_ligand_like"].fillna(False).astype(bool)
+ candidates = chains.loc[
+ chains["chain_receptor_type"].str.lower().eq("protein") & ~holo & ~ligand_like
+ ].merge(
+ holo_entities,
+ on=["entry_pdb_id", "chain_entity_id"],
+ how="left",
+ validate="many_to_one",
+ )
+ candidates = candidates.loc[candidates["entity_is_holo"].ne(True)].copy()
+ if candidates.empty:
+ return pd.DataFrame(columns=APO_CANDIDATE_COLUMNS)
+
+ _as_required_strings(
+ membership,
+ [
+ "entry_pdb_id",
+ "biounit_id",
+ "chain_instance",
+ "chain_asym_id",
+ "chain_role",
+ ],
+ "biological-assembly membership table",
+ )
+ membership_key = ["entry_pdb_id", "biounit_id", "chain_instance"]
+ duplicate_membership = membership.duplicated(membership_key, keep=False)
+ if duplicate_membership.any():
+ examples = (
+ membership.loc[duplicate_membership, membership_key]
+ .drop_duplicates()
+ .head(10)
+ .to_dict("records")
+ )
+ raise ValueError(
+ f"biological-assembly membership has duplicate chain instances: {examples}"
+ )
+ receptor_membership = (
+ membership.loc[
+ membership["chain_role"].str.lower().eq("receptor"),
+ [
+ "entry_pdb_id",
+ "biounit_id",
+ "chain_asym_id",
+ "chain_instance",
+ "chain_num_contacting_ions",
+ "chain_num_contacting_artifacts",
+ "chain_num_contacting_other_ligands",
+ ],
+ ]
+ .sort_values("chain_instance")
+ .rename(
+ columns={
+ "chain_num_contacting_ions": "source_num_contacting_ions",
+ "chain_num_contacting_artifacts": ("source_num_contacting_artifacts"),
+ "chain_num_contacting_other_ligands": (
+ "source_num_contacting_other_ligands"
+ ),
+ }
+ )
+ )
+ candidates = candidates.merge(
+ receptor_membership,
+ on=["entry_pdb_id", "chain_asym_id"],
+ how="inner",
+ validate="one_to_many",
+ )
+ contact_columns = [
+ "source_num_contacting_ions",
+ "source_num_contacting_artifacts",
+ "source_num_contacting_other_ligands",
+ ]
+ for column in contact_columns:
+ candidates[column] = pd.to_numeric(candidates[column], errors="coerce")
+ invalid = ~(
+ np.isfinite(candidates[column])
+ & candidates[column].ge(0)
+ & candidates[column].mod(1).eq(0)
+ )
+ if invalid.any():
+ raise ValueError(f"biological-assembly membership has invalid {column}")
+ candidates[column] = candidates[column].astype("int64")
+
+ _as_required_strings(metadata, ["entry_pdb_id"], "entry metadata table")
+ duplicate_metadata = metadata["entry_pdb_id"].duplicated(keep=False)
+ if duplicate_metadata.any():
+ duplicate_ids = sorted(
+ metadata.loc[duplicate_metadata, "entry_pdb_id"].unique()
+ )
+ raise ValueError(
+ f"entry metadata table has duplicate entries: {duplicate_ids[:10]}"
+ )
+ metadata["entry_resolution"] = pd.to_numeric(
+ metadata["entry_resolution"], errors="coerce"
+ )
+ invalid_resolution = metadata["entry_resolution"].notna() & ~(
+ np.isfinite(metadata["entry_resolution"]) & metadata["entry_resolution"].gt(0)
+ )
+ if invalid_resolution.any():
+ invalid = metadata.loc[
+ invalid_resolution, ["entry_pdb_id", "entry_resolution"]
+ ].to_dict("records")
+ raise ValueError(f"entry metadata has invalid resolutions: {invalid[:10]}")
+ candidates = candidates.merge(
+ metadata,
+ on="entry_pdb_id",
+ how="left",
+ validate="many_to_one",
+ )
+ candidates["resolution_missing"] = candidates["entry_resolution"].isna()
+ candidates["ligand_contact_class"] = np.select(
+ [
+ candidates["source_num_contacting_other_ligands"].gt(0),
+ candidates["source_num_contacting_artifacts"].gt(0),
+ candidates["source_num_contacting_ions"].gt(0),
+ ],
+ [3, 2, 1],
+ default=0,
+ )
+ candidates["num_contacting_ligands"] = candidates[contact_columns].sum(axis=1)
+ candidates = candidates.sort_values(
+ [
+ "entry_pdb_id",
+ "chain_asym_id",
+ "ligand_contact_class",
+ "num_contacting_ligands",
+ "resolution_missing",
+ "entry_resolution",
+ "biounit_id",
+ "chain_instance",
+ ],
+ ignore_index=True,
+ ).drop_duplicates(["entry_pdb_id", "chain_asym_id"], keep="first")
+ candidates["target_system"] = (
+ candidates["entry_pdb_id"] + "_" + candidates["chain_asym_id"]
+ )
+ candidates = candidates.rename(
+ columns={
+ "entry_pdb_id": "source_entry_id",
+ "chain_asym_id": "source_chain_asym_id",
+ "chain_auth_id": "source_chain_auth_id",
+ "biounit_id": "source_biounit_id",
+ "chain_instance": "source_chain_instance",
+ "entry_resolution": "source_resolution",
+ }
+ )
+ return candidates.loc[:, APO_CANDIDATE_COLUMNS].reset_index(drop=True)
+
+
+def _validate_apo_candidates(candidates: pd.DataFrame) -> pd.DataFrame:
+ candidates = candidates.copy()
+ _as_required_strings(
+ candidates,
+ [
+ "target_system",
+ "source_entry_id",
+ "source_chain_asym_id",
+ "source_chain_auth_id",
+ "source_biounit_id",
+ "source_chain_instance",
+ ],
+ "apo candidate manifest",
+ )
+ duplicate_ids = sorted(
+ candidates.loc[
+ candidates["target_system"].duplicated(keep=False), "target_system"
+ ].unique()
+ )
+ if duplicate_ids:
+ raise ValueError(
+ "apo candidate manifest has duplicate target_system values: "
+ f"{duplicate_ids[:10]}"
+ )
+ for column in [
+ "source_num_contacting_ions",
+ "source_num_contacting_artifacts",
+ "source_num_contacting_other_ligands",
+ ]:
+ candidates[column] = pd.to_numeric(candidates[column], errors="coerce")
+ invalid_counts = ~(
+ np.isfinite(candidates[column])
+ & candidates[column].ge(0)
+ & candidates[column].mod(1).eq(0)
+ )
+ if invalid_counts.any():
+ raise ValueError(
+ "apo candidate contact counts must be non-negative integers"
+ )
+ candidates[column] = candidates[column].astype("int64")
+ candidates["source_resolution"] = pd.to_numeric(
+ candidates["source_resolution"], errors="coerce"
+ )
+ invalid_resolution = candidates["source_resolution"].notna() & ~(
+ np.isfinite(candidates["source_resolution"])
+ & candidates["source_resolution"].gt(0)
+ )
+ if invalid_resolution.any():
+ raise ValueError("apo candidate resolutions must be positive when present")
+ return candidates
+
+
+def _proper_ligands(annotation: pd.DataFrame) -> pd.DataFrame:
+ proper = annotation.loc[
+ annotation["ligand_is_proper"].fillna(False).astype(bool),
+ ["system_id", "ligand_id"],
+ ].copy()
+ _as_required_strings(proper, ["system_id", "ligand_id"], "proper ligand rows")
+ return proper.drop_duplicates(ignore_index=True)
+
+
+def _prepare_scores(scores: pd.DataFrame) -> pd.DataFrame:
+ scores = scores.copy()
+ _as_required_strings(
+ scores,
+ ["query_system", "query_ligand_id", "target_system", "metric"],
+ "protein score table",
+ )
+ scores = scores.loc[scores["metric"].isin(REQUIRED_SCORE_METRICS)].copy()
+ scores["similarity"] = pd.to_numeric(scores["similarity"], errors="coerce")
+ invalid_similarity = ~(
+ np.isfinite(scores["similarity"])
+ & scores["similarity"].between(0, 100, inclusive="both")
+ )
+ if invalid_similarity.any():
+ raise ValueError(
+ "required protein similarities must be finite values in [0, 100]"
+ )
+ key = ["query_system", "query_ligand_id", "target_system", "metric"]
+ duplicate = scores.duplicated(key, keep=False)
+ if duplicate.any():
+ examples = (
+ scores.loc[duplicate, key].drop_duplicates().head(10).to_dict("records")
+ )
+ raise ValueError(
+ f"protein score table has duplicate required metrics: {examples}"
+ )
+ return scores
+
+
+def select_linked_apo_structures(
+ protein_scores: TableInput,
+ *,
+ annotation: TableInput,
+ candidates: TableInput,
+ config: LinkedApoSelectionConfig | None = None,
+) -> pd.DataFrame:
+ """Associate PLINDER holo systems with matching deposited apo chains.
+
+ A candidate must satisfy every required metric for every proper ligand
+ pocket in the holo system. Candidates from the holo entry itself are
+ excluded. Passing candidates prefer no chain-local ligand contacts, then
+ ion-only contacts, artifact contacts, and other ligand contacts before
+ experimental resolution and similarity.
+ """
+ config = config or LinkedApoSelectionConfig()
+ score_frame = _prepare_scores(_read_score_columns(protein_scores))
+ candidate_frame = _validate_apo_candidates(
+ _read_columns(candidates, APO_CANDIDATE_COLUMNS, "apo candidate manifest")
+ )
+ proper = _proper_ligands(
+ _read_columns(annotation, ANNOTATION_COLUMNS, "annotation table")
+ )
+ if score_frame.empty or candidate_frame.empty or proper.empty:
+ return pd.DataFrame(columns=STRUCTURE_LINK_SCHEMA.names)
+
+ score_systems = set(score_frame["query_system"])
+ known_systems = set(proper["system_id"])
+ unknown_systems = sorted(score_systems.difference(known_systems))
+ if unknown_systems:
+ raise ValueError(
+ "protein scores reference systems with no proper ligand rows: "
+ f"{unknown_systems[:10]}"
+ )
+
+ scored = score_frame.merge(
+ candidate_frame,
+ on="target_system",
+ how="inner",
+ validate="many_to_one",
+ ).merge(
+ proper,
+ left_on=["query_system", "query_ligand_id"],
+ right_on=["system_id", "ligand_id"],
+ how="inner",
+ validate="many_to_one",
+ )
+ scored = scored.loc[
+ scored["query_system"].str.split("__", n=1).str[0] != scored["source_entry_id"]
+ ]
+ if scored.empty:
+ return pd.DataFrame(columns=STRUCTURE_LINK_SCHEMA.names)
+
+ ligand_metrics = scored.pivot(
+ index=["query_system", "query_ligand_id", "target_system"],
+ columns="metric",
+ values="similarity",
+ ).reset_index()
+ for metric in REQUIRED_SCORE_METRICS:
+ if metric not in ligand_metrics:
+ ligand_metrics[metric] = np.nan
+ ligand_metrics = ligand_metrics.dropna(subset=list(REQUIRED_SCORE_METRICS))
+
+ expected_ligands = (
+ proper.groupby("system_id", observed=True)["ligand_id"]
+ .nunique()
+ .rename("expected_ligand_pockets")
+ )
+ summaries = (
+ ligand_metrics.groupby(
+ ["query_system", "target_system"], observed=True, as_index=False
+ )
+ .agg(
+ num_ligand_pockets=("query_ligand_id", "nunique"),
+ min_pocket_fident=("pocket_fident", "min"),
+ mean_pocket_fident=("pocket_fident", "mean"),
+ min_protein_fident_weighted_sum=(
+ "protein_fident_weighted_sum",
+ "min",
+ ),
+ min_protein_fident_qcov_weighted_sum=(
+ "protein_fident_qcov_weighted_sum",
+ "min",
+ ),
+ min_protein_lddt_weighted_sum=(
+ "protein_lddt_weighted_sum",
+ "min",
+ ),
+ )
+ .merge(
+ expected_ligands,
+ left_on="query_system",
+ right_index=True,
+ how="left",
+ validate="many_to_one",
+ )
+ )
+ summaries = summaries.loc[
+ (summaries["num_ligand_pockets"] == summaries["expected_ligand_pockets"])
+ & (summaries["min_pocket_fident"] >= config.min_pocket_fident)
+ & (
+ summaries["min_protein_fident_weighted_sum"]
+ >= config.min_protein_fident_weighted_sum
+ )
+ & (
+ summaries["min_protein_fident_qcov_weighted_sum"]
+ >= config.min_protein_fident_qcov_weighted_sum
+ )
+ & (
+ summaries["min_protein_lddt_weighted_sum"]
+ >= config.min_protein_lddt_weighted_sum
+ )
+ ].copy()
+ if summaries.empty:
+ return pd.DataFrame(columns=STRUCTURE_LINK_SCHEMA.names)
+
+ links = summaries.merge(
+ candidate_frame,
+ on="target_system",
+ how="inner",
+ validate="many_to_one",
+ ).rename(
+ columns={
+ "query_system": "reference_system_id",
+ "target_system": "linked_structure_id",
+ }
+ )
+ links["resolution_missing"] = links["source_resolution"].isna()
+ links["ligand_contact_class"] = np.select(
+ [
+ links["source_num_contacting_other_ligands"].gt(0),
+ links["source_num_contacting_artifacts"].gt(0),
+ links["source_num_contacting_ions"].gt(0),
+ ],
+ [3, 2, 1],
+ default=0,
+ )
+ links["num_contacting_ligands"] = links[
+ [
+ "source_num_contacting_ions",
+ "source_num_contacting_artifacts",
+ "source_num_contacting_other_ligands",
+ ]
+ ].sum(axis=1)
+ links = links.sort_values(
+ [
+ "reference_system_id",
+ "ligand_contact_class",
+ "num_contacting_ligands",
+ "resolution_missing",
+ "source_resolution",
+ "min_pocket_fident",
+ "mean_pocket_fident",
+ "min_protein_fident_qcov_weighted_sum",
+ "source_entry_id",
+ "source_chain_asym_id",
+ ],
+ ascending=[
+ True,
+ True,
+ True,
+ True,
+ True,
+ False,
+ False,
+ False,
+ True,
+ True,
+ ],
+ ignore_index=True,
+ )
+ links["rank"] = links.groupby("reference_system_id", observed=True).cumcount() + 1
+ return links.loc[
+ links["rank"] <= config.max_per_system,
+ STRUCTURE_LINK_SCHEMA.names,
+ ].reset_index(drop=True)
+
+
+def write_linked_apo_structure_table(
+ protein_scores: TableInput,
+ *,
+ annotation: TableInput,
+ candidates: TableInput,
+ output_path: str | Path,
+ config: LinkedApoSelectionConfig | None = None,
+ scratch_dir: str | Path | None = None,
+ threads: int = 1,
+ memory_limit: str = "7GB",
+) -> Path:
+ """Select linked apo structures and write the compact release table."""
+ output_path = Path(output_path)
+ if all(
+ not isinstance(table, pd.DataFrame)
+ for table in (protein_scores, annotation, candidates)
+ ):
+ return _write_linked_apo_structure_table_from_parquet(
+ protein_scores=protein_scores,
+ annotation=annotation,
+ candidates=candidates,
+ output_path=output_path,
+ config=config or LinkedApoSelectionConfig(),
+ scratch_dir=scratch_dir,
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ links = select_linked_apo_structures(
+ protein_scores,
+ annotation=annotation,
+ candidates=candidates,
+ config=config,
+ )
+ output_path.parent.mkdir(exist_ok=True, parents=True)
+ table = pa.Table.from_pandas(
+ links,
+ schema=STRUCTURE_LINK_SCHEMA,
+ preserve_index=False,
+ safe=True,
+ )
+ pq.write_table(table, output_path, compression="zstd")
+ return output_path
+
+
+def _write_linked_apo_structure_table_from_parquet(
+ *,
+ protein_scores: str | Path,
+ annotation: str | Path,
+ candidates: str | Path,
+ output_path: Path,
+ config: LinkedApoSelectionConfig,
+ scratch_dir: str | Path | None,
+ threads: int,
+ memory_limit: str,
+) -> Path:
+ """Aggregate a release-scale score table without loading it into Pandas."""
+ import duckdb
+
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ for table, columns, name in (
+ (protein_scores, SCORE_COLUMNS, "protein score table"),
+ (annotation, ANNOTATION_COLUMNS, "annotation table"),
+ (candidates, APO_CANDIDATE_COLUMNS, "apo candidate manifest"),
+ ):
+ _check_parquet_columns(table, columns, name)
+
+ scratch = Path(scratch_dir or output_path.parent / ".linked-apo-scratch")
+ scratch.mkdir(exist_ok=True, parents=True)
+ output_path.parent.mkdir(exist_ok=True, parents=True)
+ temporary = output_path.with_suffix(output_path.suffix + ".tmp")
+ temporary.unlink(missing_ok=True)
+ metrics_sql = ", ".join(f"'{metric}'" for metric in REQUIRED_SCORE_METRICS)
+
+ connection = duckdb.connect()
+ try:
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{_sql_path(scratch)}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql("SET preserve_insertion_order=false")
+ duplicate_scores = connection.sql(
+ f"""
+ SELECT
+ CAST(query_system AS VARCHAR) AS query_system,
+ CAST(query_ligand_id AS VARCHAR) AS query_ligand_id,
+ CAST(target_system AS VARCHAR) AS target_system,
+ CAST(metric AS VARCHAR) AS metric
+ FROM read_parquet('{_sql_parquet_source(protein_scores)}')
+ WHERE metric IN ({metrics_sql})
+ GROUP BY query_system, query_ligand_id, target_system, metric
+ HAVING COUNT(*) > 1
+ LIMIT 10
+ """
+ ).df()
+ if not duplicate_scores.empty:
+ raise ValueError(
+ "protein score table has duplicate required metrics: "
+ f"{duplicate_scores.to_dict('records')}"
+ )
+ if _parquet_dataset(candidates).count_rows() == 0:
+ pq.write_table(
+ pa.Table.from_pylist([], schema=STRUCTURE_LINK_SCHEMA),
+ temporary,
+ compression="zstd",
+ )
+ temporary.replace(output_path)
+ return output_path
+ connection.sql(
+ f"""
+ COPY (
+ WITH proper AS (
+ SELECT DISTINCT
+ CAST(system_id AS VARCHAR) AS system_id,
+ CAST(ligand_id AS VARCHAR) AS ligand_id
+ FROM read_parquet('{_sql_parquet_source(annotation)}')
+ WHERE COALESCE(
+ TRY_CAST(ligand_is_proper AS BOOLEAN), FALSE
+ )
+ ),
+ expected AS (
+ SELECT
+ system_id,
+ COUNT(DISTINCT ligand_id) AS expected_ligand_pockets
+ FROM proper
+ GROUP BY system_id
+ ),
+ score_base AS (
+ SELECT
+ CAST(query_system AS VARCHAR) AS query_system,
+ CAST(query_ligand_id AS VARCHAR) AS query_ligand_id,
+ CAST(target_system AS VARCHAR) AS target_system,
+ CAST(metric AS VARCHAR) AS metric,
+ TRY_CAST(similarity AS DOUBLE) AS similarity
+ FROM read_parquet('{_sql_parquet_source(protein_scores)}')
+ WHERE metric IN ({metrics_sql})
+ ),
+ scored AS (
+ SELECT
+ scores.query_system,
+ scores.query_ligand_id,
+ scores.target_system,
+ scores.metric,
+ scores.similarity
+ FROM score_base AS scores
+ INNER JOIN read_parquet(
+ '{_sql_parquet_source(candidates)}'
+ ) AS candidate USING (target_system)
+ INNER JOIN proper
+ ON scores.query_system = proper.system_id
+ AND scores.query_ligand_id = proper.ligand_id
+ WHERE split_part(scores.query_system, '__', 1)
+ != candidate.source_entry_id
+ AND scores.similarity BETWEEN 0 AND 100
+ ),
+ per_ligand AS (
+ SELECT
+ query_system,
+ query_ligand_id,
+ target_system,
+ MAX(similarity) FILTER (
+ WHERE metric = 'pocket_fident'
+ ) AS pocket_fident,
+ MAX(similarity) FILTER (
+ WHERE metric = 'protein_fident_weighted_sum'
+ ) AS protein_fident_weighted_sum,
+ MAX(similarity) FILTER (
+ WHERE metric = 'protein_fident_qcov_weighted_sum'
+ ) AS protein_fident_qcov_weighted_sum,
+ MAX(similarity) FILTER (
+ WHERE metric = 'protein_lddt_weighted_sum'
+ ) AS protein_lddt_weighted_sum
+ FROM scored
+ GROUP BY query_system, query_ligand_id, target_system
+ HAVING COUNT(*) = 4 AND COUNT(DISTINCT metric) = 4
+ ),
+ summaries AS (
+ SELECT
+ query_system,
+ target_system,
+ COUNT(DISTINCT query_ligand_id) AS num_ligand_pockets,
+ MIN(pocket_fident) AS min_pocket_fident,
+ AVG(pocket_fident) AS mean_pocket_fident,
+ MIN(protein_fident_weighted_sum)
+ AS min_protein_fident_weighted_sum,
+ MIN(protein_fident_qcov_weighted_sum)
+ AS min_protein_fident_qcov_weighted_sum,
+ MIN(protein_lddt_weighted_sum)
+ AS min_protein_lddt_weighted_sum
+ FROM per_ligand
+ GROUP BY query_system, target_system
+ ),
+ eligible AS (
+ SELECT summaries.*, candidate.* EXCLUDE (target_system)
+ FROM summaries
+ INNER JOIN expected
+ ON summaries.query_system = expected.system_id
+ INNER JOIN read_parquet(
+ '{_sql_parquet_source(candidates)}'
+ ) AS candidate USING (target_system)
+ WHERE summaries.num_ligand_pockets
+ = expected.expected_ligand_pockets
+ AND summaries.min_pocket_fident
+ >= {config.min_pocket_fident}
+ AND summaries.min_protein_fident_weighted_sum
+ >= {config.min_protein_fident_weighted_sum}
+ AND summaries.min_protein_fident_qcov_weighted_sum
+ >= {config.min_protein_fident_qcov_weighted_sum}
+ AND summaries.min_protein_lddt_weighted_sum
+ >= {config.min_protein_lddt_weighted_sum}
+ ),
+ ranked AS (
+ SELECT
+ *,
+ ROW_NUMBER() OVER (
+ PARTITION BY query_system
+ ORDER BY
+ CASE
+ WHEN source_num_contacting_other_ligands > 0
+ THEN 3
+ WHEN source_num_contacting_artifacts > 0
+ THEN 2
+ WHEN source_num_contacting_ions > 0 THEN 1
+ ELSE 0
+ END,
+ source_num_contacting_ions
+ + source_num_contacting_artifacts
+ + source_num_contacting_other_ligands,
+ source_resolution IS NULL,
+ source_resolution,
+ min_pocket_fident DESC,
+ mean_pocket_fident DESC,
+ min_protein_fident_qcov_weighted_sum DESC,
+ source_entry_id,
+ source_chain_asym_id
+ ) AS link_rank
+ FROM eligible
+ )
+ SELECT
+ CAST(query_system AS VARCHAR) AS reference_system_id,
+ CAST(target_system AS VARCHAR) AS linked_structure_id,
+ CAST(source_entry_id AS VARCHAR) AS source_entry_id,
+ CAST(source_chain_asym_id AS VARCHAR)
+ AS source_chain_asym_id,
+ CAST(source_chain_auth_id AS VARCHAR)
+ AS source_chain_auth_id,
+ CAST(source_biounit_id AS VARCHAR) AS source_biounit_id,
+ CAST(source_chain_instance AS VARCHAR)
+ AS source_chain_instance,
+ CAST(source_num_contacting_ions AS SMALLINT)
+ AS source_num_contacting_ions,
+ CAST(source_num_contacting_artifacts AS SMALLINT)
+ AS source_num_contacting_artifacts,
+ CAST(source_num_contacting_other_ligands AS SMALLINT)
+ AS source_num_contacting_other_ligands,
+ CAST(source_resolution AS FLOAT) AS source_resolution,
+ CAST(link_rank AS SMALLINT) AS rank,
+ CAST(num_ligand_pockets AS SMALLINT) AS num_ligand_pockets,
+ CAST(min_pocket_fident AS TINYINT) AS min_pocket_fident,
+ CAST(mean_pocket_fident AS FLOAT) AS mean_pocket_fident,
+ CAST(min_protein_fident_weighted_sum AS TINYINT)
+ AS min_protein_fident_weighted_sum,
+ CAST(min_protein_fident_qcov_weighted_sum AS TINYINT)
+ AS min_protein_fident_qcov_weighted_sum,
+ CAST(min_protein_lddt_weighted_sum AS TINYINT)
+ AS min_protein_lddt_weighted_sum
+ FROM ranked
+ WHERE link_rank <= {config.max_per_system}
+ ORDER BY reference_system_id, rank
+ ) TO '{_sql_path(temporary)}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ temporary.replace(output_path)
+ finally:
+ connection.close()
+ temporary.unlink(missing_ok=True)
+ return output_path
diff --git a/src/plinder/data/monomer_similarity.py b/src/plinder/data/monomer_similarity.py
new file mode 100644
index 000000000..a76ecc7d3
--- /dev/null
+++ b/src/plinder/data/monomer_similarity.py
@@ -0,0 +1,321 @@
+"""Precompute chain scores for proteins outside ligand pockets and interfaces."""
+
+from __future__ import annotations
+
+import argparse
+import shutil
+from collections.abc import Iterator
+from functools import lru_cache
+from pathlib import Path
+
+import numpy as np
+import pandas as pd
+import pyarrow as pa
+import pyarrow.dataset as ds
+import pyarrow.parquet as pq
+
+from plinder.core.scores.custom import resolve_search_database
+from plinder.core.utils.schemas import PROTEIN_SIMILARITY_EXPORT_SCHEMA
+from plinder.data import databases
+from plinder.data.annotations.get_similarity_scores import (
+ get_sequence_similarity_helper,
+ run_alignment,
+)
+from plinder.data.pipeline.config import FoldseekConfig, MMSeqsConfig
+
+
+def _chain_ids(data_dir: Path, backend: str) -> dict[str, tuple[str, str]]:
+ chains = pd.read_parquet(
+ data_dir / "index/alignment_chain_lookup.parquet",
+ columns=["entry_pdb_id", "chain_auth_id", "chain_asym_id"],
+ )
+ prefix = "pdb_0000" if backend == "foldseek" else ""
+ infix = "_xyz-enrich_" if backend == "foldseek" else "_"
+ identifiers = (
+ prefix
+ + chains["entry_pdb_id"].astype(str)
+ + infix
+ + chains["chain_auth_id"].astype(str)
+ )
+ if identifiers.duplicated().any():
+ raise ValueError("release chain lookup has ambiguous author-chain IDs")
+ return dict(
+ zip(
+ identifiers,
+ zip(chains["entry_pdb_id"], chains["chain_asym_id"], strict=True),
+ strict=True,
+ )
+ )
+
+
+def _percent(values: pd.Series, *, allow_missing: bool = False) -> pa.Array:
+ numeric = pd.to_numeric(values, errors="raise").to_numpy(dtype=float)
+ missing = np.isnan(numeric)
+ if (not allow_missing and missing.any()) or np.isinf(numeric).any():
+ raise ValueError("protein alignment contains a non-finite score")
+ scaled = np.floor(np.nan_to_num(numeric, nan=0) * 100 + 0.5)
+ return pa.array(scaled.clip(0, 100).astype("uint8"), mask=missing)
+
+
+def _alignment_frames(scanner: ds.Scanner) -> Iterator[pd.DataFrame]:
+ """Combine small search row groups before converting and writing scores."""
+ pending: list[pa.RecordBatch] = []
+ count = 0
+ for batch in scanner.to_batches():
+ if not batch.num_rows:
+ continue
+ pending.append(batch)
+ count += batch.num_rows
+ if count >= 100_000:
+ yield pa.Table.from_batches(pending).to_pandas()
+ pending.clear()
+ count = 0
+ if pending:
+ yield pa.Table.from_batches(pending).to_pandas()
+
+
+def _score_alignment_batches(
+ raw_path: Path,
+ output_path: Path,
+ *,
+ backend: str,
+ chain_ids: dict[str, tuple[str, str]],
+) -> int:
+ output_path.parent.mkdir(parents=True, exist_ok=True)
+ temporary = output_path.with_suffix(".tmp.parquet")
+ count = 0
+
+ @lru_cache(maxsize=100_000)
+ def sequence_similarity(query: str, target: str) -> float:
+ return get_sequence_similarity_helper(query, target)
+
+ with pq.ParquetWriter(
+ temporary, PROTEIN_SIMILARITY_EXPORT_SCHEMA, compression="zstd"
+ ) as writer:
+ scanner = ds.dataset(raw_path, format="parquet").scanner(
+ columns=[
+ "query",
+ "target",
+ "qcov",
+ "tcov",
+ "fident",
+ "qaln",
+ "taln",
+ *(["lddt"] if backend == "foldseek" else []),
+ ],
+ batch_size=100_000,
+ )
+ for rows in _alignment_frames(scanner):
+ query_ids = rows["query"]
+ target_ids = rows["target"]
+ if backend == "foldseek":
+ model_prefix = r"_xyz-enrich_MODEL_\d+_"
+ query_ids = query_ids.str.replace(
+ model_prefix, "_xyz-enrich_", regex=True
+ )
+ target_ids = target_ids.str.replace(
+ model_prefix, "_xyz-enrich_", regex=True
+ )
+ queries = query_ids.map(chain_ids)
+ targets = target_ids.map(chain_ids)
+ if queries.isna().any() or targets.isna().any():
+ unknown = {
+ "query": rows.loc[queries.isna(), "query"].head(5).tolist(),
+ "target": rows.loc[targets.isna(), "target"].head(5).tolist(),
+ }
+ raise ValueError(f"monomer alignment has unknown chains: {unknown}")
+ query_entry, query_chain = zip(*queries, strict=True)
+ target_entry, target_chain = zip(*targets, strict=True)
+ similarity = pd.Series(
+ [
+ sequence_similarity(str(q).upper(), str(t).upper())
+ for q, t in zip(rows["qaln"], rows["taln"], strict=True)
+ ]
+ )
+ size = len(rows)
+ table = pa.Table.from_arrays(
+ [
+ pa.array(query_entry, type=pa.string()),
+ pa.array(target_entry, type=pa.string()),
+ pa.array(query_chain, type=pa.string()),
+ pa.array(target_chain, type=pa.string()),
+ pa.array([backend] * size, type=pa.string()),
+ _percent(rows["qcov"]),
+ _percent(rows["tcov"]),
+ _percent(rows["fident"]),
+ _percent(similarity),
+ (
+ _percent(rows["lddt"], allow_missing=True)
+ if backend == "foldseek"
+ else pa.nulls(size, type=pa.uint8())
+ ),
+ ],
+ schema=PROTEIN_SIMILARITY_EXPORT_SCHEMA,
+ )
+ writer.write_table(table)
+ count += size
+ temporary.replace(output_path)
+ return count
+
+
+def score_monomer_pairs(
+ data_dir: Path,
+ *,
+ backend: str,
+ target_kind: str,
+ scratch_dir: Path,
+ output_path: Path,
+ threads: int,
+ pilot_queries: int | None = None,
+ query_batch_index: int | None = None,
+ query_batch_count: int | None = None,
+) -> int:
+ """Score unrepresented protein query chains against one target universe."""
+ if backend not in {"foldseek", "mmseqs"}:
+ raise ValueError(f"unsupported backend: {backend}")
+ if target_kind not in {"holo", "monomer"}:
+ raise ValueError(f"unsupported target universe: {target_kind}")
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ data_dir = Path(data_dir)
+ scratch_dir = Path(scratch_dir)
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ query = data_dir / "dbs/subdbs" / f"monomer_{backend}" / f"monomer_{backend}"
+ if pilot_queries is not None or query_batch_index is not None:
+ identifiers = sorted(databases.database_identifiers(query))
+ if pilot_queries is not None:
+ if pilot_queries < 1 or query_batch_index is not None:
+ raise ValueError("pilot_queries must be positive and unbatched")
+ identifiers = identifiers[:pilot_queries]
+ else:
+ if (
+ query_batch_index is None
+ or query_batch_count is None
+ or not 0 <= query_batch_index < query_batch_count
+ ):
+ raise ValueError("invalid monomer query batch")
+ start = len(identifiers) * query_batch_index // query_batch_count
+ stop = len(identifiers) * (query_batch_index + 1) // query_batch_count
+ identifiers = identifiers[start:stop]
+ print(f"Searching {len(identifiers):,} monomer query chains", flush=True)
+ subset_root = scratch_dir / "query_subset"
+ subset_root.mkdir(exist_ok=True)
+ missing = databases.make_sub_db(set(identifiers), query, subset_root, backend)
+ if missing:
+ raise ValueError(f"missing pilot query chains: {sorted(missing)[:10]}")
+ query = subset_root / subset_root.name
+
+ target = resolve_search_database(
+ backend, data_dir=data_dir, monomer=target_kind == "monomer"
+ )
+ config = FoldseekConfig() if backend == "foldseek" else MMSeqsConfig()
+ raw = scratch_dir / "raw_alignment"
+ run_alignment(
+ aln_type=backend,
+ query_db=query,
+ target_db=target.conversion_target,
+ search_target_db=target.search_target,
+ cluster_alignment_db=target.cluster_alignments,
+ search_db=scratch_dir / "results",
+ aln_file=raw,
+ alignment_config=config,
+ tmp_dir=scratch_dir / "search_tmp",
+ threads=threads,
+ )
+ try:
+ return _score_alignment_batches(
+ raw.with_suffix(".parquet"),
+ Path(output_path),
+ backend=backend,
+ chain_ids=_chain_ids(data_dir, backend),
+ )
+ finally:
+ shutil.rmtree(raw.with_suffix(".parquet"), ignore_errors=True)
+
+
+def finalize_monomer_similarity_scores(
+ data_dir: Path, *, query_batch_count: int = 8
+) -> int:
+ """Install the complete monomer-pair table after every batch succeeds."""
+ if query_batch_count < 1:
+ raise ValueError("query_batch_count must be positive")
+ exports = Path(data_dir) / "exports"
+ staging = exports / ".monomer_similarity_scores_staging"
+ installing = exports / ".monomer_similarity_scores_installing"
+ installed = exports / "monomer_similarity_scores"
+ if installed.exists():
+ raise FileExistsError(installed)
+ expected = {
+ staging
+ / f"alignment_type={backend}"
+ / f"target_kind={target_kind}"
+ / f"part-{batch_index}.parquet"
+ for backend in ("mmseqs", "foldseek")
+ for target_kind in ("holo", "monomer")
+ for batch_index in range(query_batch_count)
+ }
+ extra = set(staging.rglob("*.parquet")) - expected
+ if extra:
+ raise ValueError(f"unexpected monomer score batches: {sorted(extra)[:5]}")
+ total_rows = 0
+ for backend in ("mmseqs", "foldseek"):
+ for target_kind in ("holo", "monomer"):
+ for batch_index in range(query_batch_count):
+ path = (
+ staging
+ / f"alignment_type={backend}"
+ / f"target_kind={target_kind}"
+ / f"part-{batch_index}.parquet"
+ )
+ if not path.is_file():
+ raise FileNotFoundError(path)
+ file = pq.ParquetFile(path)
+ if not file.schema_arrow.equals(PROTEIN_SIMILARITY_EXPORT_SCHEMA):
+ raise ValueError(f"invalid monomer score schema: {path}")
+ total_rows += file.metadata.num_rows
+ if installing.exists():
+ shutil.rmtree(installing)
+ for backend in ("mmseqs", "foldseek"):
+ backend_root = installing / f"alignment_type={backend}"
+ backend_root.mkdir(parents=True)
+ for target_kind in ("holo", "monomer"):
+ target_root = (
+ staging / f"alignment_type={backend}" / f"target_kind={target_kind}"
+ )
+ for batch_index in range(query_batch_count):
+ (
+ backend_root / f"monomer_{target_kind}_{batch_index}.parquet"
+ ).hardlink_to(target_root / f"part-{batch_index}.parquet")
+ installing.rename(installed)
+ shutil.rmtree(staging, ignore_errors=True)
+ return total_rows
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument("data_dir", type=Path)
+ parser.add_argument("--backend", choices=("foldseek", "mmseqs"), required=True)
+ parser.add_argument("--target-kind", choices=("holo", "monomer"), required=True)
+ parser.add_argument("--scratch-dir", type=Path, required=True)
+ parser.add_argument("--output", type=Path, required=True)
+ parser.add_argument("--threads", type=int, default=16)
+ parser.add_argument("--pilot-queries", type=int)
+ parser.add_argument("--query-batch-index", type=int)
+ parser.add_argument("--query-batch-count", type=int)
+ args = parser.parse_args()
+ count = score_monomer_pairs(
+ args.data_dir,
+ backend=args.backend,
+ target_kind=args.target_kind,
+ scratch_dir=args.scratch_dir,
+ output_path=args.output,
+ threads=args.threads,
+ pilot_queries=args.pilot_queries,
+ query_batch_index=args.query_batch_index,
+ query_batch_count=args.query_batch_count,
+ )
+ print(f"Wrote {count:,} {args.backend}/{args.target_kind} pair rows", flush=True)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/plinder/data/pipeline/collate.py b/src/plinder/data/pipeline/collate.py
new file mode 100644
index 000000000..3fc7eab03
--- /dev/null
+++ b/src/plinder/data/pipeline/collate.py
@@ -0,0 +1,2419 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Plan, shard, validate, and install the local annotation index."""
+
+from __future__ import annotations
+
+import argparse
+import hashlib
+import json
+import os
+import re
+import stat
+import traceback
+from concurrent.futures import ThreadPoolExecutor
+from pathlib import Path
+from typing import Any, Iterable, Sequence, cast
+from uuid import uuid4
+
+import duckdb
+import pyarrow as pa
+import pyarrow.parquet as pq
+
+from plinder.core.utils.files import write_json_atomic
+from plinder.data.annotations.interface_utils import (
+ INTERFACE_ANNOTATION_SCHEMA,
+ min_interface_residues_from_schema,
+)
+from plinder.data.pipeline.ingest import (
+ BIOUNIT_CONTACT_COLUMNS,
+ BIOUNIT_LIGAND_CONTACT_COLUMNS,
+ BIOUNIT_PROTEIN_CONTACT_COLUMNS,
+ CHAIN_MODIFICATION_COLUMNS,
+ completed_entry_metrics,
+ completed_interface_metrics,
+)
+
+COLLATION_VERSION = 1
+STAGING_RELATIVE = Path("index/.staging/collation")
+MANIFEST_NAME = "entries.parquet"
+PLAN_NAME = "plan.json"
+FINAL_MARKER_NAME = "collation.json"
+PLAN_BUILD_NAME = "plan-build.json"
+PLAN_INVENTORY_DIRECTORY = "plan-inventory"
+REPAIR_REQUIRED_STATUS = "requires_downstream_repair"
+RETIRED_ENRICHMENT_MARKERS = ("ecod", "panther", "kinase")
+SYSTEM_VALIDATION_PREFIXES = (
+ "system_ligand_validation_",
+ "system_pocket_validation_",
+)
+CHAIN_SUMMARY_PREFIXES = (
+ "system_protein_chains_",
+ "system_ligand_chains_",
+ "ligand_protein_chains_",
+ "ligand_neighboring_ligand_chains_",
+ "ligand_interacting_ligand_chains_",
+)
+CHAIN_METADATA_SUFFIXES = (
+ "auth_id",
+ "entity_id",
+ "length",
+ "num_unresolved_residues",
+)
+RETIRED_ANNOTATION_COLUMNS = frozenset(
+ {
+ "system_id_no_biounit",
+ "system_ligand_chains",
+ "ligand_rdkit_canonical_smiles",
+ "ligand_binding_affinity",
+ "system_has_binding_affinity",
+ "system_pass_criteria",
+ "ligand__members",
+ }
+)
+SYSTEM_LIGAND_FLAGS = (
+ "lipinski",
+ "cofactor",
+ "fragment",
+ "monosaccharide",
+ "oligosaccharide",
+ "mononucleotide",
+ "oligonucleotide",
+ "monopeptide",
+ "oligopeptide",
+ "artifact",
+ "other",
+ "covalent",
+ "invalid",
+ "ion",
+)
+AGGREGATED_COLUMNS = (
+ "biounit_num_ligands",
+ "biounit_num_unique_ccd_codes",
+ "biounit_num_proper_ligands",
+ *(f"system_ligand_has_{name}" for name in SYSTEM_LIGAND_FLAGS),
+ "system_protein_chains_total_length",
+ "system_unique_ccd_codes",
+ "system_proper_unique_ccd_codes",
+ "ligand_is_shape_comparable",
+)
+
+
+def _is_repeated_entry_column(column: str) -> bool:
+ """Return whether a ligand row repeats data owned by entry metadata."""
+ return column.startswith("entry_") and column != "entry_pdb_id"
+
+
+def _is_repeated_chain_column(column: str) -> bool:
+ """Return whether chain data is repeated on a ligand row."""
+ for prefix in CHAIN_SUMMARY_PREFIXES:
+ if not column.startswith(prefix):
+ continue
+ suffix = column.removeprefix(prefix)
+ return suffix in CHAIN_METADATA_SUFFIXES or suffix.startswith("validation_")
+ return False
+
+
+def _is_system_validation_column(column: str) -> bool:
+ """Return whether a field belongs in the system-validation table."""
+ return column.startswith(SYSTEM_VALIDATION_PREFIXES)
+
+
+def _is_retired_annotation_column(column: str) -> bool:
+ """Return whether a field is excluded from the published ligand table."""
+ return (
+ column in RETIRED_ANNOTATION_COLUMNS
+ or _is_repeated_chain_column(column)
+ or _is_system_validation_column(column)
+ )
+
+
+def _annotation_columns_to_publish(columns: Iterable[str]) -> list[str]:
+ """Drop fields that do not belong in the published ligand table."""
+ return [
+ column
+ for column in columns
+ if not _is_repeated_entry_column(column)
+ and not _is_retired_annotation_column(column)
+ and not any(
+ marker in column.casefold() for marker in RETIRED_ENRICHMENT_MARKERS
+ )
+ ]
+
+
+def _raw_annotation_columns_to_keep(columns: Iterable[str]) -> list[str]:
+ """Return working ligand fields, excluding recomputed aggregates."""
+ return [
+ column
+ for column in columns
+ if not _is_repeated_entry_column(column)
+ and column != "ligand__members"
+ and not any(
+ marker in column.casefold() for marker in RETIRED_ENRICHMENT_MARKERS
+ )
+ and column not in AGGREGATED_COLUMNS
+ ]
+
+
+MANIFEST_SCHEMA = pa.schema(
+ [
+ ("pdb_id", pa.string()),
+ ("code", pa.string()),
+ ("annotation_path", pa.string()),
+ ("chain_path", pa.string()),
+ ("biounit_chain_path", pa.string()),
+ ("metadata_path", pa.string()),
+ ("interface_path", pa.string()),
+ ("source_path", pa.string()),
+ ("ligand_path", pa.string()),
+ ("annotation_size", pa.int64()),
+ ("annotation_mtime_ns", pa.int64()),
+ ("chain_size", pa.int64()),
+ ("chain_mtime_ns", pa.int64()),
+ ("biounit_chain_size", pa.int64()),
+ ("biounit_chain_mtime_ns", pa.int64()),
+ ("metadata_size", pa.int64()),
+ ("metadata_mtime_ns", pa.int64()),
+ ("interface_size", pa.int64()),
+ ("interface_mtime_ns", pa.int64()),
+ ("source_size", pa.int64()),
+ ("source_mtime_ns", pa.int64()),
+ ("ligand_size", pa.int64()),
+ ("ligand_mtime_ns", pa.int64()),
+ ("interface_min_residues", pa.int64()),
+ ("ligand_contacts_computed", pa.bool_()),
+ ("protein_contacts_computed", pa.bool_()),
+ ]
+)
+
+ENTRY_CHAIN_SCHEMA = pa.schema(
+ [
+ ("entry_pdb_id", pa.string()),
+ ("chain_asym_id", pa.string()),
+ ("chain_auth_id", pa.string()),
+ ("chain_entity_id", pa.string()),
+ ("chain_type", pa.string()),
+ ("chain_receptor_type", pa.string()),
+ ("chain_sequence", pa.string()),
+ ("chain_sequence_noncanonical", pa.string()),
+ ("chain_modified_residues", pa.list_(pa.string())),
+ ("chain_length", pa.int64()),
+ ("chain_num_unresolved_residues", pa.int64()),
+ ("chain_is_holo", pa.bool_()),
+ ("chain_is_ligand_like", pa.bool_()),
+ ("chain_uniprot_ids", pa.list_(pa.string())),
+ ]
+)
+
+BIOUNIT_CHAIN_SCHEMA = pa.schema(
+ [
+ ("entry_pdb_id", pa.string()),
+ ("biounit_id", pa.string()),
+ ("chain_instance", pa.string()),
+ ("chain_asym_id", pa.string()),
+ ("chain_role", pa.string()),
+ ("chain_num_contacting_ions", pa.int64()),
+ ("chain_num_contacting_artifacts", pa.int64()),
+ ("chain_num_contacting_other_ligands", pa.int64()),
+ ("chain_num_contacting_proteins", pa.int64()),
+ ]
+)
+
+ENTRY_SOURCE_SCHEMA = pa.schema(
+ [
+ ("entry_pdb_id", pa.string()),
+ ("source_mmcif_major_revision", pa.int64()),
+ ("source_mmcif_minor_revision", pa.int64()),
+ ]
+)
+
+SIDECAR_SCHEMAS = {
+ "entry_chains": ENTRY_CHAIN_SCHEMA,
+ "entry_biounit_chains": BIOUNIT_CHAIN_SCHEMA,
+ "interfaces": INTERFACE_ANNOTATION_SCHEMA,
+ "entry_sources": ENTRY_SOURCE_SCHEMA,
+}
+
+ENTRY_TABLES = {
+ "annotation": ("annotation_table.parquet", "entry_pdb_id, system_id, ligand_id"),
+ "system_validation": ("system_validation.parquet", "system_id"),
+ "entry_chains": ("entry_chains.parquet", "entry_pdb_id, chain_asym_id"),
+ "entry_biounit_chains": (
+ "entry_biounit_chains.parquet",
+ "entry_pdb_id, biounit_id, chain_instance",
+ ),
+ "entry_metadata": ("entry_metadata.parquet", "entry_pdb_id"),
+ "interfaces": ("interface_annotation_table.parquet", "entry_pdb_id, system_id"),
+ "entry_sources": ("entry_sources.parquet", "entry_pdb_id"),
+}
+
+
+def entry_table_paths(data_dir: Path) -> dict[str, Path]:
+ """Return the seven collated entry tables used by builds, repairs, and updates."""
+ return {
+ name: data_dir / "index" / filename
+ for name, (filename, _) in ENTRY_TABLES.items()
+ }
+
+
+def staging_dir(data_dir: Path) -> Path:
+ """Return the private collation workspace under the release directory."""
+ return data_dir.resolve() / STAGING_RELATIVE
+
+
+def manifest_path(data_dir: Path) -> Path:
+ return staging_dir(data_dir) / MANIFEST_NAME
+
+
+def plan_path(data_dir: Path) -> Path:
+ return staging_dir(data_dir) / PLAN_NAME
+
+
+def plan_build_path(data_dir: Path) -> Path:
+ """Return the generation marker for distributed plan inventory."""
+ return staging_dir(data_dir) / PLAN_BUILD_NAME
+
+
+def plan_inventory_dir(data_dir: Path, generation: str) -> Path:
+ """Return the private per-code inventory directory for one generation."""
+ return staging_dir(data_dir) / PLAN_INVENTORY_DIRECTORY / generation
+
+
+def _temporary_path(path: Path) -> Path:
+ return path.with_name(f".{path.name}.{os.getpid()}.{uuid4().hex}.tmp")
+
+
+def _write_table_atomic(
+ table: pa.Table,
+ path: Path,
+ *,
+ row_group_size: int = 100_000,
+) -> None:
+ path.parent.mkdir(parents=True, exist_ok=True)
+ temporary = _temporary_path(path)
+ try:
+ pq.write_table(
+ table,
+ temporary,
+ compression="zstd",
+ row_group_size=row_group_size,
+ )
+ temporary.replace(path)
+ finally:
+ temporary.unlink(missing_ok=True)
+
+
+def _stat_values(path: Path, prefix: str) -> dict[str, int]:
+ stat = path.stat()
+ return {
+ f"{prefix}_size": stat.st_size,
+ f"{prefix}_mtime_ns": stat.st_mtime_ns,
+ }
+
+
+def _row_signature(rows: Sequence[dict[str, Any]]) -> str:
+ digest = hashlib.sha256()
+ for row in sorted(rows, key=lambda item: str(item["pdb_id"])):
+ digest.update(
+ json.dumps(row, sort_keys=True, separators=(",", ":")).encode("utf-8")
+ )
+ digest.update(b"\n")
+ return digest.hexdigest()
+
+
+def _contact_columns_were_computed(path: Path, columns: set[str]) -> bool:
+ """Check whether one complete contact group is present in a sidecar."""
+ available = columns.intersection(pq.read_schema(path).names)
+ if not available:
+ return False
+ if available != columns:
+ raise ValueError(f"incomplete biological-assembly contact columns in {path}")
+ table = pq.read_table(path, columns=sorted(columns))
+ if any(
+ value is None or value < 0
+ for column in table.column_names
+ for value in table[column].to_pylist()
+ ):
+ raise ValueError(f"invalid biological-assembly contact counts in {path}")
+ return True
+
+
+def _entry_manifest_row(data_dir: Path, entry_dir: Path) -> dict[str, Any]:
+ pdb_id = entry_dir.name.lower()
+ if re.fullmatch(r"[0-9][a-z0-9]{3}", pdb_id) is None:
+ raise ValueError(f"invalid raw-entry directory: {entry_dir}")
+ code = pdb_id[1:3]
+ if entry_dir.parent.name.lower() != code:
+ raise ValueError(f"raw-entry shard does not match PDB ID: {entry_dir}")
+ annotation_path = entry_dir.parent / f"{pdb_id}.parquet"
+ ligand_path = data_dir / "ligands" / f"{pdb_id}.parquet"
+ paths = {
+ "annotation": annotation_path,
+ "chain": entry_dir / "entry_chains.parquet",
+ "biounit_chain": entry_dir / "entry_biounit_chains.parquet",
+ "metadata": entry_dir / "entry_metadata.parquet",
+ "interface": entry_dir / "interfaces.parquet",
+ "source": entry_dir / "entry_source.parquet",
+ "ligand": ligand_path,
+ }
+ optional = {"annotation", "ligand"}
+ if annotation_path.is_file() != ligand_path.is_file():
+ raise FileNotFoundError(
+ f"incomplete entry {pdb_id}; ligand outputs disagree: "
+ f"annotation={annotation_path.is_file()}, ligand={ligand_path.is_file()}"
+ )
+ path_stats: dict[str, os.stat_result] = {}
+ missing: list[Path] = []
+ for name, path in paths.items():
+ try:
+ path_stat = path.stat()
+ except FileNotFoundError:
+ if name not in optional:
+ missing.append(path)
+ continue
+ if not stat.S_ISREG(path_stat.st_mode):
+ if name not in optional:
+ missing.append(path)
+ continue
+ path_stats[name] = path_stat
+ if missing:
+ formatted = ", ".join(str(path) for path in missing)
+ raise FileNotFoundError(f"incomplete entry {pdb_id}; missing: {formatted}")
+ if annotation_path.is_file():
+ if pq.ParquetFile(annotation_path).metadata.num_rows < 1:
+ raise ValueError(f"ligand annotation is empty for entry {pdb_id}")
+ else:
+ if (
+ completed_entry_metrics(data_dir, pdb_id) is None
+ and completed_interface_metrics(data_dir, pdb_id) is None
+ ):
+ raise ValueError(
+ f"sidecar-only entry {pdb_id} has no successful ingest marker"
+ )
+ row: dict[str, Any] = {
+ "pdb_id": pdb_id,
+ "code": code,
+ "interface_min_residues": min_interface_residues_from_schema(
+ pq.read_schema(paths["interface"])
+ ),
+ "ligand_contacts_computed": _contact_columns_were_computed(
+ paths["biounit_chain"], BIOUNIT_LIGAND_CONTACT_COLUMNS
+ ),
+ "protein_contacts_computed": _contact_columns_were_computed(
+ paths["biounit_chain"], BIOUNIT_PROTEIN_CONTACT_COLUMNS
+ ),
+ **{f"{name}_path": str(path.resolve()) for name, path in paths.items()},
+ }
+ for name in paths:
+ row[f"{name}_size"] = None
+ row[f"{name}_mtime_ns"] = None
+ for name, path_stat in path_stats.items():
+ row[f"{name}_size"] = path_stat.st_size
+ row[f"{name}_mtime_ns"] = path_stat.st_mtime_ns
+ return row
+
+
+def _raw_entry_codes(data_dir: Path) -> list[str]:
+ raw_entries = data_dir / "raw_entries"
+ if not raw_entries.is_dir():
+ raise FileNotFoundError(f"missing raw-entry dataset: {raw_entries}")
+ return sorted(
+ path.name.lower()
+ for path in raw_entries.iterdir()
+ if path.is_dir() and re.fullmatch(r"[a-z0-9]{2}", path.name.lower())
+ )
+
+
+def _raw_entry_code_signatures(
+ data_dir: Path, codes: Sequence[str]
+) -> dict[str, dict[str, int]]:
+ """Fingerprint code directories without walking their entry children."""
+ signatures: dict[str, dict[str, int]] = {}
+ for code in codes:
+ stat_result = (data_dir / "raw_entries" / code).stat()
+ signatures[code] = {
+ "size": stat_result.st_size,
+ "mtime_ns": stat_result.st_mtime_ns,
+ }
+ return signatures
+
+
+def _entry_dirs_for_code(data_dir: Path, code: str) -> list[Path]:
+ code_dir = data_dir / "raw_entries" / code
+ if not code_dir.is_dir():
+ return []
+ return sorted(
+ path
+ for path in code_dir.iterdir()
+ if path.is_dir() and re.fullmatch(r"[0-9][a-z0-9]{3}", path.name.lower())
+ )
+
+
+def start_collation_plan(
+ data_dir: Path, *, include_ligand_annotations: bool = True
+) -> dict[str, Any]:
+ """Freeze the code directories for a distributed inventory generation."""
+ data_dir = data_dir.resolve()
+ codes = _raw_entry_codes(data_dir)
+ if not codes:
+ raise ValueError(f"no entries found in {data_dir / 'raw_entries'}")
+ build: dict[str, Any] = {
+ "version": COLLATION_VERSION,
+ "status": "inventorying",
+ "generation": uuid4().hex,
+ "data_dir": str(data_dir),
+ "codes": codes,
+ "code_count": len(codes),
+ "code_directory_signatures": _raw_entry_code_signatures(data_dir, codes),
+ "include_ligand_annotations": include_ligand_annotations,
+ }
+ plan_inventory_dir(data_dir, str(build["generation"])).mkdir(
+ parents=True, exist_ok=False
+ )
+ write_json_atomic(plan_build_path(data_dir), build)
+ return build
+
+
+def _load_plan_build(data_dir: Path) -> dict[str, Any]:
+ path = plan_build_path(data_dir)
+ try:
+ build = cast(dict[str, Any], json.loads(path.read_text()))
+ except (OSError, TypeError, ValueError, json.JSONDecodeError) as exc:
+ raise FileNotFoundError(
+ f"missing or invalid collation plan build: {path}"
+ ) from exc
+ if (
+ build.get("version") != COLLATION_VERSION
+ or build.get("status") != "inventorying"
+ or not isinstance(build.get("generation"), str)
+ or not isinstance(build.get("codes"), list)
+ or not isinstance(build.get("code_directory_signatures"), dict)
+ or not isinstance(build.get("include_ligand_annotations"), bool)
+ ):
+ raise ValueError(f"invalid collation plan build: {path}")
+ return build
+
+
+def inventory_collation_codes(
+ data_dir: Path,
+ codes: Sequence[str],
+ *,
+ threads: int = 1,
+) -> dict[str, Any]:
+ """Inventory selected two-character shards for one plan generation."""
+ if threads < 1:
+ raise ValueError("planning threads must be positive")
+ data_dir = data_dir.resolve()
+ build = _load_plan_build(data_dir)
+ planned_codes = {str(code) for code in build["codes"]}
+ normalized_codes = sorted({str(code).lower() for code in codes})
+ invalid = [
+ code
+ for code in normalized_codes
+ if re.fullmatch(r"[a-z0-9]{2}", code) is None or code not in planned_codes
+ ]
+ if invalid:
+ raise ValueError(f"codes are not in the collation plan build: {invalid}")
+ if not normalized_codes:
+ raise ValueError("no collation inventory codes selected")
+
+ output_root = plan_inventory_dir(data_dir, str(build["generation"]))
+ counts: dict[str, int] = {}
+ signatures: dict[str, str] = {}
+ with ThreadPoolExecutor(max_workers=threads) as executor:
+ for code in normalized_codes:
+ entry_dirs = _entry_dirs_for_code(data_dir, code)
+ rows = list(
+ executor.map(
+ lambda path: _entry_manifest_row(data_dir, path),
+ entry_dirs,
+ )
+ )
+ if len({str(row["pdb_id"]) for row in rows}) != len(rows):
+ raise ValueError(f"duplicate raw-entry annotations in shard {code}")
+ _write_table_atomic(
+ pa.Table.from_pylist(rows, schema=MANIFEST_SCHEMA),
+ output_root / f"{code}.parquet",
+ )
+ counts[code] = len(rows)
+ signatures[code] = _row_signature(rows)
+ return {
+ "status": "complete",
+ "generation": build["generation"],
+ "codes": normalized_codes,
+ "code_entry_counts": counts,
+ "code_signatures": signatures,
+ }
+
+
+def planned_inventory_code_batch(
+ data_dir: Path, *, batch_index: int, batch_size: int
+) -> list[str]:
+ """Return one fixed-size slice of codes from the active plan build."""
+ if batch_index < 0:
+ raise ValueError("batch_index must be non-negative")
+ if batch_size < 1:
+ raise ValueError("batch_size must be positive")
+ codes = [str(code) for code in _load_plan_build(data_dir)["codes"]]
+ start = batch_index * batch_size
+ return codes[start : start + batch_size]
+
+
+def finalize_collation_plan(data_dir: Path) -> dict[str, Any]:
+ """Merge a complete distributed inventory and publish the frozen plan."""
+ data_dir = data_dir.resolve()
+ build = _load_plan_build(data_dir)
+ build_codes = [str(code) for code in build["codes"]]
+ if (
+ _raw_entry_codes(data_dir) != build_codes
+ or _raw_entry_code_signatures(data_dir, build_codes)
+ != build["code_directory_signatures"]
+ ):
+ raise RuntimeError("raw-entry shard directories changed during planning")
+
+ output = manifest_path(data_dir)
+ output.parent.mkdir(parents=True, exist_ok=True)
+ temporary = _temporary_path(output)
+ inventory_root = plan_inventory_dir(data_dir, str(build["generation"]))
+ writer: Any | None = None
+ seen: set[str] = set()
+ code_signatures: dict[str, str] = {}
+ code_counts: dict[str, int] = {}
+ interface_min_residues: set[int] = set()
+ ligand_contact_states: set[bool] = set()
+ protein_contact_states: set[bool] = set()
+ total_entries = 0
+ try:
+ writer = pq.ParquetWriter(temporary, MANIFEST_SCHEMA, compression="zstd")
+ for code in build_codes:
+ inventory = inventory_root / f"{code}.parquet"
+ if not inventory.is_file():
+ raise FileNotFoundError(
+ f"collation plan inventory is incomplete for code {code}: "
+ f"{inventory}"
+ )
+ table = pq.read_table(inventory)
+ if not table.schema.equals(MANIFEST_SCHEMA):
+ raise ValueError(f"invalid collation inventory schema: {inventory}")
+ rows = cast(list[dict[str, Any]], table.to_pylist())
+ actual_ids = {str(row["pdb_id"]) for row in rows}
+ if len(actual_ids) != len(rows) or any(
+ pdb_id[1:3] != code for pdb_id in actual_ids
+ ):
+ raise ValueError(
+ f"invalid raw-entry membership in inventory shard {code}"
+ )
+ duplicates = sorted(actual_ids.intersection(seen))
+ if duplicates:
+ raise ValueError(f"duplicate raw-entry annotations: {duplicates}")
+ seen.update(actual_ids)
+ if not rows:
+ continue
+ code_signatures[code] = _row_signature(rows)
+ code_counts[code] = len(rows)
+ interface_min_residues.update(
+ int(row["interface_min_residues"]) for row in rows
+ )
+ ligand_contact_states.update(
+ bool(row["ligand_contacts_computed"]) for row in rows
+ )
+ protein_contact_states.update(
+ bool(row["protein_contacts_computed"]) for row in rows
+ )
+ total_entries += len(rows)
+ writer.write_table(table)
+ if total_entries == 0:
+ raise ValueError(f"no entries found in {data_dir / 'raw_entries'}")
+ if len(interface_min_residues) != 1:
+ raise ValueError(
+ "mixed interface.min_interface_residues values in ingest outputs: "
+ f"{sorted(interface_min_residues)}"
+ )
+ if len(ligand_contact_states) != 1 or len(protein_contact_states) != 1:
+ raise ValueError(
+ "mixed biological-assembly contact schemas in ingest outputs"
+ )
+ writer.close()
+ writer = None
+ temporary.replace(output)
+ finally:
+ if writer is not None:
+ writer.close()
+ temporary.unlink(missing_ok=True)
+
+ summary: dict[str, Any] = {
+ "version": COLLATION_VERSION,
+ "status": "complete",
+ "data_dir": str(data_dir),
+ "manifest": str(output),
+ "entry_count": total_entries,
+ "code_count": len(code_signatures),
+ "codes": sorted(code_signatures),
+ "code_entry_counts": code_counts,
+ "code_signatures": code_signatures,
+ "interface_min_residues": interface_min_residues.pop(),
+ "ligand_contacts_computed": ligand_contact_states.pop(),
+ "protein_contacts_computed": protein_contact_states.pop(),
+ "include_ligand_annotations": bool(build["include_ligand_annotations"]),
+ }
+ write_json_atomic(plan_path(data_dir), summary)
+ write_json_atomic(
+ plan_build_path(data_dir),
+ {**build, "status": "complete", "plan": str(plan_path(data_dir))},
+ )
+ return summary
+
+
+def plan_collation(
+ data_dir: Path,
+ *,
+ threads: int = 1,
+ include_ligand_annotations: bool = True,
+) -> dict[str, Any]:
+ """Inventory every entry and atomically write a collation plan."""
+ build = start_collation_plan(
+ data_dir,
+ include_ligand_annotations=include_ligand_annotations,
+ )
+ inventory_collation_codes(
+ data_dir,
+ [str(code) for code in build["codes"]],
+ threads=threads,
+ )
+ return finalize_collation_plan(data_dir)
+
+
+def load_plan(data_dir: Path) -> dict[str, Any]:
+ """Load a completed plan and verify its manifest is present."""
+ path = plan_path(data_dir)
+ if not path.is_file():
+ raise FileNotFoundError(f"missing collation plan: {path}")
+ plan = cast(dict[str, Any], json.loads(path.read_text()))
+ if plan.get("status") != "complete" or plan.get("version") != COLLATION_VERSION:
+ raise ValueError(f"invalid collation plan: {path}")
+ if int(plan.get("interface_min_residues", 0)) < 1:
+ raise ValueError(f"invalid interface threshold in collation plan: {path}")
+ if not isinstance(plan.get("ligand_contacts_computed"), bool) or not isinstance(
+ plan.get("protein_contacts_computed"), bool
+ ):
+ raise ValueError(f"invalid contact state in collation plan: {path}")
+ if not manifest_path(data_dir).is_file():
+ raise FileNotFoundError(
+ f"missing collation manifest: {manifest_path(data_dir)}"
+ )
+ return plan
+
+
+def _load_manifest_rows(data_dir: Path, code: str) -> list[dict[str, Any]]:
+ normalized = code.lower()
+ if re.fullmatch(r"[a-z0-9]{2}", normalized) is None:
+ raise ValueError(f"invalid two-character code: {code!r}")
+ table = pq.read_table(
+ manifest_path(data_dir),
+ filters=[("code", "=", normalized)],
+ )
+ return cast(list[dict[str, Any]], table.to_pylist())
+
+
+def _verify_manifest_row(row: dict[str, Any]) -> None:
+ for prefix in (
+ "annotation",
+ "chain",
+ "biounit_chain",
+ "metadata",
+ "interface",
+ "source",
+ "ligand",
+ ):
+ path = Path(str(row[f"{prefix}_path"]))
+ if row[f"{prefix}_size"] is None:
+ if path.exists():
+ raise RuntimeError(
+ "collation input appeared after planning; rerun the plan "
+ f"stage: {path}"
+ )
+ continue
+ try:
+ values = _stat_values(path, prefix)
+ except FileNotFoundError as exc:
+ raise RuntimeError(
+ f"collation input disappeared after planning: {path}"
+ ) from exc
+ if any(values[key] != row[key] for key in values):
+ raise RuntimeError(
+ f"collation input changed after planning; rerun the plan stage: {path}"
+ )
+
+
+def _verify_manifest_inputs(
+ rows: Sequence[dict[str, Any]], *, threads: int = 1
+) -> None:
+ if threads < 1:
+ raise ValueError("verification threads must be positive")
+ if threads == 1:
+ for row in rows:
+ _verify_manifest_row(row)
+ return
+ batch_size = threads * 64
+ with ThreadPoolExecutor(max_workers=threads) as executor:
+ for start in range(0, len(rows), batch_size):
+ for _ in executor.map(
+ _verify_manifest_row, rows[start : start + batch_size]
+ ):
+ pass
+
+
+def _configure_duckdb(
+ connection: duckdb.DuckDBPyConnection,
+ *,
+ threads: int,
+ memory_limit: str,
+ scratch_dir: Path | None,
+) -> None:
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ connection.execute(f"SET threads = {threads:d}")
+ connection.execute("SET preserve_insertion_order = false")
+ escaped_memory = memory_limit.replace("'", "''")
+ connection.execute(f"SET memory_limit = '{escaped_memory}'")
+ if scratch_dir is not None:
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ escaped_scratch = str(scratch_dir.resolve()).replace("'", "''")
+ connection.execute(f"SET temp_directory = '{escaped_scratch}'")
+
+
+def _fetch_scalar(connection: duckdb.DuckDBPyConnection, query: str) -> Any:
+ """Execute a query that must return exactly one scalar row."""
+ row = connection.execute(query).fetchone()
+ if row is None:
+ raise RuntimeError(f"query unexpectedly returned no rows: {query}")
+ return row[0]
+
+
+def _quote_identifier(value: str) -> str:
+ return '"' + value.replace('"', '""') + '"'
+
+
+def _copy_query(
+ connection: duckdb.DuckDBPyConnection,
+ query: str,
+ path: Path,
+ *,
+ row_group_size: int,
+) -> None:
+ escaped = str(path.resolve()).replace("'", "''")
+ connection.execute(
+ f"COPY ({query}) TO '{escaped}' "
+ f"(FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE {row_group_size:d})"
+ )
+
+
+def _merge_parquet_shards(
+ paths: list[Path], output: Path, schema: pa.Schema, *, row_group_size: int
+) -> None:
+ """Write wide annotations in bounded, useful-sized Parquet row groups."""
+
+ def write_pending(writer: pq.ParquetWriter, pending: list[pa.Table]) -> None:
+ if pending:
+ merged = pa.concat_tables(pending)
+ writer.write_table(merged, row_group_size=max(row_group_size, len(merged)))
+
+ with pq.ParquetWriter(output, schema, compression="zstd") as writer:
+ pending: list[pa.Table] = []
+ pending_rows = 0
+ for path in paths:
+ table = pq.read_table(path)
+ columns = [
+ (
+ table[field.name].cast(field.type, safe=False)
+ if field.name in table.column_names
+ else pa.nulls(table.num_rows, type=field.type)
+ )
+ for field in schema
+ ]
+ pending.append(pa.Table.from_arrays(columns, schema=schema))
+ pending_rows += len(table)
+ if pending_rows >= row_group_size:
+ write_pending(writer, pending)
+ pending.clear()
+ pending_rows = 0
+ write_pending(writer, pending)
+
+
+def _copy_query_atomic(
+ connection: duckdb.DuckDBPyConnection,
+ query: str,
+ path: Path,
+ *,
+ row_group_size: int,
+) -> None:
+ path.parent.mkdir(parents=True, exist_ok=True)
+ temporary = _temporary_path(path)
+ try:
+ _copy_query(connection, query, temporary, row_group_size=row_group_size)
+ temporary.replace(path)
+ finally:
+ temporary.unlink(missing_ok=True)
+
+
+def _relation_columns(
+ connection: duckdb.DuckDBPyConnection, relation: str
+) -> list[str]:
+ rows = connection.execute(f"PRAGMA table_info('{relation}')").fetchall()
+ return [str(row[1]) for row in rows]
+
+
+def _require_columns(
+ columns: Iterable[str], required: Iterable[str], label: str
+) -> None:
+ missing = sorted(set(required).difference(columns))
+ if missing:
+ raise ValueError(f"{label} is missing required columns: {missing}")
+
+
+def _build_annotation_view(
+ connection: duckdb.DuckDBPyConnection,
+ annotation_paths: Sequence[str],
+ ligand_paths: Sequence[str],
+ *,
+ empty: bool = False,
+) -> None:
+ annotation = connection.read_parquet(list(annotation_paths), union_by_name=True)
+ ligand = connection.read_parquet(list(ligand_paths), union_by_name=True)
+ if empty:
+ annotation = annotation.filter("false")
+ ligand = ligand.filter("false")
+ annotation.create_view("raw_annotation", replace=True)
+ ligand.create_view("raw_ligand_comparability", replace=True)
+ raw_columns = _relation_columns(connection, "raw_annotation")
+ required = {
+ "entry_pdb_id",
+ "system_biounit_id",
+ "system_id",
+ "system_type",
+ "system_protein_chains_length",
+ "ligand_id",
+ "ligand_unique_ccd_code",
+ "ligand_is_proper",
+ *(f"ligand_is_{name}" for name in SYSTEM_LIGAND_FLAGS),
+ }
+ _require_columns(raw_columns, required, "raw annotation")
+ system_validation_columns = [
+ "system_id",
+ *(column for column in raw_columns if _is_system_validation_column(column)),
+ ]
+ system_validation_select = ", ".join(
+ _quote_identifier(column) for column in system_validation_columns
+ )
+ connection.execute(
+ "CREATE OR REPLACE TEMP VIEW distinct_system_validation AS "
+ f"SELECT DISTINCT {system_validation_select} FROM raw_annotation"
+ )
+ conflicting_system_validation = connection.execute(
+ "SELECT system_id FROM distinct_system_validation GROUP BY system_id "
+ "HAVING count(*) > 1 LIMIT 10"
+ ).fetchall()
+ if conflicting_system_validation:
+ raise ValueError(
+ f"conflicting system validation rows: {conflicting_system_validation}"
+ )
+ connection.execute(
+ "CREATE OR REPLACE TEMP VIEW collated_system_validation AS "
+ "SELECT * FROM distinct_system_validation"
+ )
+ retained = _raw_annotation_columns_to_keep(raw_columns)
+ selected = ", ".join(_quote_identifier(column) for column in retained)
+ connection.execute(
+ f"CREATE OR REPLACE TEMP VIEW base_annotation AS SELECT {selected} "
+ "FROM raw_annotation"
+ )
+ comparability_columns = _relation_columns(connection, "raw_ligand_comparability")
+ _require_columns(
+ comparability_columns,
+ {"ligand_id", "ligand_is_shape_comparable"},
+ "ligand shape-comparability",
+ )
+ conflicts = connection.execute(
+ "SELECT ligand_id FROM raw_ligand_comparability GROUP BY ligand_id "
+ "HAVING count(DISTINCT ligand_is_shape_comparable) > 1 LIMIT 10"
+ ).fetchall()
+ if conflicts:
+ raise ValueError(f"conflicting shape-comparability values: {conflicts}")
+ connection.execute(
+ "CREATE OR REPLACE TEMP VIEW ligand_comparability AS "
+ "SELECT ligand_id, bool_or(ligand_is_shape_comparable) "
+ "AS ligand_is_shape_comparable FROM raw_ligand_comparability GROUP BY ligand_id"
+ )
+ missing_comparabilities = _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM base_annotation AS b "
+ "LEFT JOIN ligand_comparability AS a USING (ligand_id) "
+ "WHERE b.system_type = 'holo' AND coalesce(b.ligand_is_proper, false) "
+ "AND a.ligand_id IS NULL",
+ )
+ if missing_comparabilities:
+ raise ValueError(
+ f"{missing_comparabilities} proper holo rows lack shape-comparability annotations"
+ )
+
+ connection.execute(
+ "CREATE OR REPLACE TEMP VIEW biounit_aggregate AS "
+ "SELECT entry_pdb_id, system_biounit_id, "
+ "count(system_id)::BIGINT AS biounit_num_ligands, "
+ "count(DISTINCT ligand_unique_ccd_code)::BIGINT "
+ "AS biounit_num_unique_ccd_codes, "
+ "sum(CASE WHEN coalesce(ligand_is_proper, false) THEN 1 ELSE 0 END)::BIGINT "
+ "AS biounit_num_proper_ligands "
+ "FROM base_annotation GROUP BY entry_pdb_id, system_biounit_id"
+ )
+ flag_sql = ", ".join(
+ f"bool_or(ligand_is_{name}) AS system_ligand_has_{name}"
+ for name in SYSTEM_LIGAND_FLAGS
+ )
+ connection.execute(
+ "CREATE OR REPLACE TEMP VIEW system_aggregate AS "
+ f"SELECT system_id, {flag_sql}, "
+ "string_agg(DISTINCT ligand_unique_ccd_code, '-' "
+ "ORDER BY ligand_unique_ccd_code) AS system_unique_ccd_codes "
+ "FROM base_annotation GROUP BY system_id"
+ )
+ connection.execute(
+ "CREATE OR REPLACE TEMP VIEW proper_system_aggregate AS "
+ "SELECT system_id, string_agg(DISTINCT ligand_unique_ccd_code, '-' "
+ "ORDER BY ligand_unique_ccd_code) AS system_proper_unique_ccd_codes "
+ "FROM base_annotation WHERE coalesce(ligand_is_proper, false) "
+ "GROUP BY system_id"
+ )
+ published_retained = _annotation_columns_to_publish(retained)
+ raw_select = ", ".join(
+ f"b.{_quote_identifier(column)}" for column in published_retained
+ )
+ flag_select = ", ".join(
+ f"s.system_ligand_has_{name}" for name in SYSTEM_LIGAND_FLAGS
+ )
+ connection.execute(
+ "CREATE OR REPLACE TEMP VIEW collated_annotation AS SELECT "
+ f"{raw_select}, u.biounit_num_ligands, "
+ "u.biounit_num_unique_ccd_codes, u.biounit_num_proper_ligands, "
+ f"{flag_select}, list_sum(b.system_protein_chains_length)::BIGINT "
+ "AS system_protein_chains_total_length, s.system_unique_ccd_codes, "
+ "p.system_proper_unique_ccd_codes, "
+ "CASE WHEN b.system_type = 'holo' AND coalesce(b.ligand_is_proper, false) "
+ "THEN a.ligand_is_shape_comparable ELSE false END "
+ "AS ligand_is_shape_comparable FROM base_annotation AS b "
+ "JOIN biounit_aggregate AS u USING (entry_pdb_id, system_biounit_id) "
+ "JOIN system_aggregate AS s USING (system_id) "
+ "LEFT JOIN proper_system_aggregate AS p USING (system_id) "
+ "LEFT JOIN ligand_comparability AS a USING (ligand_id)"
+ )
+
+
+def _normalize_arrow_table(
+ table: pa.Table,
+ path: Path,
+ schema: pa.Schema,
+ *,
+ optional_columns: set[str] | frozenset[str] = frozenset(),
+) -> pa.Table:
+ if table.num_rows:
+ missing = sorted(
+ set(schema.names).difference(table.column_names, optional_columns)
+ )
+ else:
+ missing = []
+ if missing:
+ raise ValueError(f"{path} is missing sidecar columns: {missing}")
+ arrays = []
+ for field in schema:
+ if field.name in table.column_names:
+ column = table[field.name].combine_chunks().cast(field.type, safe=False)
+ else:
+ column = pa.nulls(table.num_rows, type=field.type)
+ arrays.append(column)
+ return pa.Table.from_arrays(arrays, schema=schema)
+
+
+def _normalize_table(
+ path: Path,
+ schema: pa.Schema,
+ *,
+ optional_columns: set[str] | frozenset[str] = frozenset(),
+) -> pa.Table:
+ return _normalize_arrow_table(
+ pq.read_table(path), path, schema, optional_columns=optional_columns
+ )
+
+
+def _collate_sidecars(
+ paths: Sequence[Path],
+ output: Path,
+ schema: pa.Schema,
+ *,
+ sort_columns: Sequence[str],
+ row_group_size: int,
+ optional_columns: set[str] | frozenset[str] = frozenset(),
+) -> None:
+ tables = [
+ _normalize_table(path, schema, optional_columns=optional_columns)
+ for path in paths
+ ]
+ table = (
+ pa.concat_tables(tables) if tables else pa.Table.from_batches([], schema=schema)
+ )
+ if table.num_rows:
+ table = table.sort_by([(column, "ascending") for column in sort_columns])
+ _write_table_atomic(table, output, row_group_size=row_group_size)
+
+
+def _collate_entry_metadata(
+ paths: Sequence[Path],
+ output: Path,
+ *,
+ row_group_size: int,
+) -> None:
+ """Collate entry metadata with one consistent column set."""
+ tables = []
+ for path in paths:
+ table = pq.read_table(path)
+ column = "entry_failed_assembly_ids"
+ if column in table.column_names:
+ table = table.set_column(
+ table.schema.get_field_index(column),
+ column,
+ table[column].cast(pa.list_(pa.string())),
+ )
+ tables.append(table)
+ if not tables:
+ raise ValueError("cannot collate an empty entry-metadata shard")
+ columns = set(tables[0].column_names)
+ if any(set(table.column_names) != columns for table in tables[1:]):
+ raise ValueError("entry metadata sidecars have inconsistent columns")
+ table = pa.concat_tables(tables, promote_options="default")
+ if "entry_pdb_id" not in table.column_names:
+ raise ValueError("entry metadata is missing entry_pdb_id")
+ # A wholly unknown depositor flag must stay boolean: DuckDB otherwise
+ # reads the Parquet null type as INTEGER and widens it during weekly joins.
+ flag = "entry_has_ligand_of_interest"
+ if flag in table.column_names:
+ table = table.set_column(
+ table.schema.get_field_index(flag), flag, table[flag].cast(pa.bool_())
+ )
+ table = table.sort_by([("entry_pdb_id", "ascending")])
+ _write_table_atomic(table, output, row_group_size=row_group_size)
+
+
+def _shard_paths(data_dir: Path, code: str) -> dict[str, Path]:
+ root = staging_dir(data_dir)
+ return {
+ "annotation": root / "annotations" / f"{code}.parquet",
+ "system_validation": root / "system_validation" / f"{code}.parquet",
+ "entry_chains": root / "entry_chains" / f"{code}.parquet",
+ "entry_biounit_chains": root / "entry_biounit_chains" / f"{code}.parquet",
+ "entry_metadata": root / "entry_metadata" / f"{code}.parquet",
+ "interfaces": root / "interfaces" / f"{code}.parquet",
+ "entry_sources": root / "entry_sources" / f"{code}.parquet",
+ "metrics": root / "shards" / f"{code}.json",
+ }
+
+
+def _shard_output_names(plan: dict[str, Any]) -> tuple[str, ...]:
+ names = (
+ "entry_chains",
+ "entry_biounit_chains",
+ "entry_metadata",
+ "interfaces",
+ "entry_sources",
+ )
+ if bool(plan.get("include_ligand_annotations", True)):
+ return ("annotation", "system_validation", *names)
+ return names
+
+
+def _uncomputed_contact_columns(plan: dict[str, Any]) -> set[str]:
+ columns: set[str] = set()
+ if not plan["ligand_contacts_computed"]:
+ columns.update(BIOUNIT_LIGAND_CONTACT_COLUMNS)
+ if not plan["protein_contacts_computed"]:
+ columns.update(BIOUNIT_PROTEIN_CONTACT_COLUMNS)
+ return columns
+
+
+def _completed_shard(
+ paths: dict[str, Path],
+ *,
+ signature: str,
+ output_names: Sequence[str],
+ include_ligand_annotations: bool,
+) -> dict[str, Any] | None:
+ metrics_path = paths["metrics"]
+ if not metrics_path.is_file():
+ return None
+ try:
+ metrics = cast(dict[str, Any], json.loads(metrics_path.read_text()))
+ except (OSError, json.JSONDecodeError):
+ return None
+ outputs = [paths[name] for name in output_names]
+ if (
+ metrics.get("status") == "complete"
+ and metrics.get("version") == COLLATION_VERSION
+ and metrics.get("signature") == signature
+ and bool(metrics.get("include_ligand_annotations", True))
+ == include_ligand_annotations
+ and all(path.is_file() for path in outputs)
+ ):
+ return metrics
+ return None
+
+
+def collate_shard(
+ data_dir: Path,
+ code: str,
+ *,
+ force: bool = False,
+ threads: int = 1,
+ memory_limit: str = "8GB",
+ scratch_dir: Path | None = None,
+ row_group_size: int = 100_000,
+) -> dict[str, Any]:
+ """Collate one two-character shard with bounded memory and atomic writes."""
+ data_dir = data_dir.resolve()
+ plan = load_plan(data_dir)
+ normalized = code.lower()
+ if normalized not in plan["code_signatures"]:
+ raise KeyError(f"two-character code is not in collation plan: {normalized}")
+ rows = _load_manifest_rows(data_dir, normalized)
+ signature = _row_signature(rows)
+ if signature != plan["code_signatures"][normalized]:
+ raise RuntimeError(f"manifest signature mismatch for shard {normalized}")
+ _verify_manifest_inputs(rows, threads=threads)
+ paths = _shard_paths(data_dir, normalized)
+ include_ligand_annotations = bool(plan.get("include_ligand_annotations", True))
+ output_names = _shard_output_names(plan)
+ if not force and (
+ completed := _completed_shard(
+ paths,
+ signature=signature,
+ output_names=output_names,
+ include_ligand_annotations=include_ligand_annotations,
+ )
+ ):
+ return completed
+ metrics: dict[str, Any] = {
+ "version": COLLATION_VERSION,
+ "status": "running",
+ "code": normalized,
+ "signature": signature,
+ "entry_count": len(rows),
+ "include_ligand_annotations": include_ligand_annotations,
+ "outputs": {name: str(paths[name]) for name in output_names},
+ }
+ try:
+ if include_ligand_annotations:
+ connection = duckdb.connect()
+ try:
+ shard_scratch = (
+ scratch_dir / normalized if scratch_dir is not None else None
+ )
+ _configure_duckdb(
+ connection,
+ threads=threads,
+ memory_limit=memory_limit,
+ scratch_dir=shard_scratch,
+ )
+ ligand_rows = [
+ row for row in rows if row["annotation_size"] is not None
+ ]
+ if ligand_rows:
+ schema_rows = ligand_rows
+ empty_annotation = False
+ else:
+ schema_rows = [
+ row
+ for row in cast(
+ list[dict[str, Any]],
+ pq.read_table(manifest_path(data_dir)).to_pylist(),
+ )
+ if row["annotation_size"] is not None
+ ][:1]
+ if not schema_rows:
+ raise ValueError(
+ "interface collation requires at least one "
+ "ligand-bearing entry to define the ligand "
+ "annotation schema"
+ )
+ empty_annotation = True
+ _build_annotation_view(
+ connection,
+ [str(row["annotation_path"]) for row in schema_rows],
+ [str(row["ligand_path"]) for row in schema_rows],
+ empty=empty_annotation,
+ )
+ _copy_query_atomic(
+ connection,
+ "SELECT * FROM collated_annotation "
+ "ORDER BY entry_pdb_id, system_id, ligand_id",
+ paths["annotation"],
+ row_group_size=row_group_size,
+ )
+ _copy_query_atomic(
+ connection,
+ "SELECT * FROM collated_system_validation ORDER BY system_id",
+ paths["system_validation"],
+ row_group_size=row_group_size,
+ )
+ finally:
+ connection.close()
+ _collate_sidecars(
+ [Path(str(row["chain_path"])) for row in rows],
+ paths["entry_chains"],
+ ENTRY_CHAIN_SCHEMA,
+ sort_columns=("entry_pdb_id", "chain_asym_id"),
+ row_group_size=row_group_size,
+ )
+ _collate_entry_metadata(
+ [Path(str(row["metadata_path"])) for row in rows],
+ paths["entry_metadata"],
+ row_group_size=row_group_size,
+ )
+ _collate_sidecars(
+ [Path(str(row["interface_path"])) for row in rows],
+ paths["interfaces"],
+ INTERFACE_ANNOTATION_SCHEMA,
+ sort_columns=("entry_pdb_id", "system_id"),
+ row_group_size=row_group_size,
+ )
+ _collate_sidecars(
+ [Path(str(row["biounit_chain_path"])) for row in rows],
+ paths["entry_biounit_chains"],
+ BIOUNIT_CHAIN_SCHEMA,
+ sort_columns=("entry_pdb_id", "biounit_id", "chain_instance"),
+ row_group_size=row_group_size,
+ optional_columns=_uncomputed_contact_columns(plan),
+ )
+ _collate_sidecars(
+ [Path(str(row["source_path"])) for row in rows],
+ paths["entry_sources"],
+ ENTRY_SOURCE_SCHEMA,
+ sort_columns=("entry_pdb_id",),
+ row_group_size=row_group_size,
+ )
+ metrics["counts"] = {
+ name: pq.ParquetFile(paths[name]).metadata.num_rows for name in output_names
+ }
+ metrics["status"] = "complete"
+ except BaseException as exc:
+ metrics["status"] = "failed"
+ metrics["error"] = repr(exc)
+ metrics["traceback"] = traceback.format_exc()
+ raise
+ finally:
+ write_json_atomic(paths["metrics"], metrics)
+ return metrics
+
+
+def _load_completed_shards(
+ data_dir: Path, plan: dict[str, Any]
+) -> tuple[dict[str, list[Path]], dict[str, int]]:
+ manifest_rows = cast(
+ list[dict[str, Any]],
+ pq.read_table(manifest_path(data_dir)).to_pylist(),
+ )
+ rows_by_code: dict[str, list[dict[str, Any]]] = {}
+ for row in manifest_rows:
+ rows_by_code.setdefault(str(row["code"]), []).append(row)
+ planned_codes = [str(code) for code in plan["codes"]]
+ if set(rows_by_code) != set(planned_codes):
+ raise RuntimeError("collation manifest codes differ from the completed plan")
+ for code in planned_codes:
+ rows = rows_by_code[code]
+ if len(rows) != int(plan["code_entry_counts"][code]):
+ raise RuntimeError(f"collation manifest row count changed for shard {code}")
+ signature = _row_signature(rows)
+ if signature != str(plan["code_signatures"][code]):
+ raise RuntimeError(f"collation manifest signature changed for shard {code}")
+
+ # Each shard verifies its raw inputs against the frozen manifest before it
+ # writes its outputs. Those completed shard outputs are the immutable
+ # snapshot consumed below; rescanning every raw sidecar here would repeat
+ # the expensive NFS work that distributed collation is intended to avoid.
+ # Changes to raw entries after a shard completes belong to a new plan.
+
+ output_names = _shard_output_names(plan)
+ include_ligand_annotations = bool(plan.get("include_ligand_annotations", True))
+ files: dict[str, list[Path]] = {name: [] for name in output_names}
+ expected_counts = {name: 0 for name in files}
+ for code in planned_codes:
+ rows = rows_by_code[code]
+ signature = _row_signature(rows)
+ paths = _shard_paths(data_dir, code)
+ metrics = _completed_shard(
+ paths,
+ signature=signature,
+ output_names=output_names,
+ include_ligand_annotations=include_ligand_annotations,
+ )
+ if metrics is None:
+ raise RuntimeError(f"collation shard is incomplete or stale: {code}")
+ for name in files:
+ files[name].append(paths[name])
+ expected_counts[name] += int(metrics["counts"][name])
+ return files, expected_counts
+
+
+def _install_final_tables_fail_closed(
+ temporary_paths: dict[str, Path],
+ final_paths: dict[str, Path],
+ marker_path: Path,
+ *,
+ preserve_annotation: bool = False,
+) -> None:
+ """Install validated tables while making partial generations unreadable."""
+ marker_path.unlink(missing_ok=True)
+ if not preserve_annotation:
+ final_paths["annotation"].unlink(missing_ok=True)
+ final_paths["system_validation"].unlink(missing_ok=True)
+ try:
+ for name in (
+ "entry_chains",
+ "entry_biounit_chains",
+ "entry_metadata",
+ "interfaces",
+ "entry_sources",
+ ):
+ temporary_paths[name].replace(final_paths[name])
+ if not preserve_annotation:
+ temporary_paths["system_validation"].replace(
+ final_paths["system_validation"]
+ )
+ temporary_paths["annotation"].replace(final_paths["annotation"])
+ except BaseException:
+ if not preserve_annotation:
+ final_paths["annotation"].unlink(missing_ok=True)
+ final_paths["system_validation"].unlink(missing_ok=True)
+ raise
+
+
+def _validate_final_tables(
+ paths: dict[str, Path],
+ *,
+ expected_counts: dict[str, int],
+ min_interface_residues: int,
+ ligand_contacts_computed: bool = True,
+ protein_contacts_computed: bool = True,
+ threads: int,
+ memory_limit: str,
+ scratch_dir: Path | None,
+) -> dict[str, Any]:
+ if min_interface_residues < 1:
+ raise ValueError("minimum interface residues must be positive")
+ connection = duckdb.connect()
+ try:
+ _configure_duckdb(
+ connection,
+ threads=threads,
+ memory_limit=memory_limit,
+ scratch_dir=scratch_dir,
+ )
+ for name, path in paths.items():
+ connection.read_parquet(str(path)).create_view(name, replace=True)
+ actual_counts = {
+ name: int(_fetch_scalar(connection, f"SELECT count(*) FROM {name}"))
+ for name in paths
+ }
+ if actual_counts != expected_counts:
+ raise ValueError(
+ f"final collation row counts differ: {actual_counts} != {expected_counts}"
+ )
+ duplicate_queries = {
+ "annotation": (
+ "SELECT count(*) FROM (SELECT system_id, ligand_id FROM annotation "
+ "GROUP BY system_id, ligand_id HAVING count(*) > 1)"
+ ),
+ "system_validation": (
+ "SELECT count(*) FROM (SELECT system_id FROM system_validation "
+ "GROUP BY system_id HAVING count(*) > 1)"
+ ),
+ "entry_chains": (
+ "SELECT count(*) FROM (SELECT entry_pdb_id, chain_asym_id "
+ "FROM entry_chains GROUP BY entry_pdb_id, chain_asym_id "
+ "HAVING count(*) > 1)"
+ ),
+ "entry_biounit_chains": (
+ "SELECT count(*) FROM (SELECT entry_pdb_id, biounit_id, "
+ "chain_instance FROM entry_biounit_chains GROUP BY entry_pdb_id, "
+ "biounit_id, chain_instance HAVING count(*) > 1)"
+ ),
+ "entry_metadata": (
+ "SELECT count(*) FROM (SELECT entry_pdb_id FROM entry_metadata "
+ "GROUP BY entry_pdb_id HAVING count(*) > 1)"
+ ),
+ "interfaces": (
+ "SELECT count(*) FROM (SELECT system_id FROM interfaces "
+ "GROUP BY system_id HAVING count(*) > 1)"
+ ),
+ "entry_sources": (
+ "SELECT count(*) FROM (SELECT entry_pdb_id FROM entry_sources "
+ "GROUP BY entry_pdb_id HAVING count(*) > 1)"
+ ),
+ }
+ duplicates = {
+ name: int(_fetch_scalar(connection, query))
+ for name, query in duplicate_queries.items()
+ }
+ if any(duplicates.values()):
+ raise ValueError(f"duplicate keys in final collation: {duplicates}")
+ invalid_chain_metadata = {
+ "missing_sequences": int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM entry_chains "
+ "WHERE chain_sequence IS NULL OR length(trim(chain_sequence)) = 0",
+ )
+ ),
+ "sequence_length_mismatch": int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM entry_chains "
+ "WHERE length(chain_sequence) != chain_length",
+ )
+ ),
+ "nonpositive_lengths": int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM entry_chains "
+ "WHERE chain_length IS NULL OR chain_length <= 0",
+ )
+ ),
+ "negative_unresolved": int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM entry_chains WHERE "
+ "chain_num_unresolved_residues IS NULL OR "
+ "chain_num_unresolved_residues < 0",
+ )
+ ),
+ "unresolved_exceeds_length": int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM entry_chains WHERE "
+ "chain_num_unresolved_residues > chain_length",
+ )
+ ),
+ }
+ if any(invalid_chain_metadata.values()):
+ raise ValueError(
+ f"invalid entry-chain sequence metadata: {invalid_chain_metadata}"
+ )
+ required_contact_columns: set[str] = set()
+ if ligand_contacts_computed:
+ required_contact_columns.update(BIOUNIT_LIGAND_CONTACT_COLUMNS)
+ if protein_contacts_computed:
+ required_contact_columns.update(BIOUNIT_PROTEIN_CONTACT_COLUMNS)
+ invalid_contact_checks = [
+ *(f"{column} < 0" for column in BIOUNIT_CONTACT_COLUMNS),
+ *(f"{column} IS NULL" for column in required_contact_columns),
+ ]
+ invalid_biounit_contacts = int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM entry_biounit_chains WHERE "
+ + " OR ".join(sorted(invalid_contact_checks)),
+ )
+ )
+ if invalid_biounit_contacts:
+ raise ValueError(
+ "invalid biological-assembly contact counts: "
+ f"{invalid_biounit_contacts} rows"
+ )
+ uncomputed_contact_columns = BIOUNIT_CONTACT_COLUMNS.difference(
+ required_contact_columns
+ )
+ unexpected_biounit_contacts = (
+ int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM entry_biounit_chains WHERE "
+ + " OR ".join(
+ sorted(
+ f"{column} IS NOT NULL"
+ for column in uncomputed_contact_columns
+ )
+ ),
+ )
+ )
+ if uncomputed_contact_columns
+ else 0
+ )
+ if unexpected_biounit_contacts:
+ raise ValueError(
+ "unexpected biological-assembly contact counts: "
+ f"{unexpected_biounit_contacts} rows"
+ )
+ invalid_interfaces = {
+ "system_id": int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM interfaces WHERE system_id != "
+ "entry_pdb_id || '__' || system_biounit_id || '__' || "
+ "interface_chain_1 || '--' || interface_chain_2",
+ )
+ ),
+ "same_chain": int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM interfaces WHERE "
+ "interface_chain_1 >= interface_chain_2",
+ )
+ ),
+ "short_side": int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM interfaces WHERE "
+ "len(interface_chain_1_residue_numbers) < "
+ f"{min_interface_residues} OR "
+ "len(interface_chain_2_residue_numbers) < "
+ f"{min_interface_residues}",
+ )
+ ),
+ "mapping_length": int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM interfaces WHERE "
+ "len(interface_chain_1_residue_numbers) != "
+ "len(interface_chain_1_residue_indices) OR "
+ "len(interface_chain_2_residue_numbers) != "
+ "len(interface_chain_2_residue_indices)",
+ )
+ ),
+ }
+ if any(invalid_interfaces.values()):
+ raise ValueError(f"invalid protein interfaces: {invalid_interfaces}")
+ annotation_columns = _relation_columns(connection, "annotation")
+ repeated_entry_columns = sorted(
+ column for column in annotation_columns if _is_repeated_entry_column(column)
+ )
+ if repeated_entry_columns:
+ raise ValueError(
+ "entry metadata columns remain in ligand annotation: "
+ f"{repeated_entry_columns}"
+ )
+ retired = sorted(
+ column
+ for column in annotation_columns
+ if _is_retired_annotation_column(column)
+ or any(marker in column.casefold() for marker in RETIRED_ENRICHMENT_MARKERS)
+ )
+ if retired:
+ raise ValueError(f"retired annotation columns remain: {retired}")
+ _require_columns(
+ annotation_columns,
+ AGGREGATED_COLUMNS,
+ "collated annotation",
+ )
+ orphan_sources = int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM (SELECT DISTINCT a.entry_pdb_id FROM annotation a "
+ "ANTI JOIN entry_sources s USING (entry_pdb_id))",
+ )
+ )
+ orphan_system_validation = int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM (SELECT DISTINCT system_id FROM annotation "
+ "ANTI JOIN system_validation USING (system_id))",
+ )
+ )
+ orphan_chains = int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM (SELECT DISTINCT a.entry_pdb_id FROM annotation a "
+ "ANTI JOIN entry_chains c USING (entry_pdb_id))",
+ )
+ )
+ orphan_biounits = int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM (SELECT DISTINCT entry_pdb_id, "
+ "system_biounit_id AS biounit_id FROM annotation) a ANTI JOIN "
+ "(SELECT DISTINCT entry_pdb_id, biounit_id FROM entry_biounit_chains) b "
+ "USING (entry_pdb_id, biounit_id)",
+ )
+ )
+ orphan_metadata = int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM (SELECT entry_pdb_id FROM entry_sources "
+ "ANTI JOIN entry_metadata USING (entry_pdb_id))",
+ )
+ )
+ orphan_interface_instances = int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM ("
+ "SELECT i.system_id FROM interfaces i LEFT JOIN "
+ "entry_biounit_chains b1 ON b1.entry_pdb_id = i.entry_pdb_id "
+ "AND b1.biounit_id = i.system_biounit_id "
+ "AND b1.chain_instance = i.interface_chain_1 LEFT JOIN "
+ "entry_biounit_chains b2 ON b2.entry_pdb_id = i.entry_pdb_id "
+ "AND b2.biounit_id = i.system_biounit_id "
+ "AND b2.chain_instance = i.interface_chain_2 "
+ "WHERE b1.chain_instance IS NULL OR b2.chain_instance IS NULL)",
+ )
+ )
+ orphan_interface_chains = int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM ("
+ "SELECT i.system_id FROM interfaces i LEFT JOIN entry_chains c1 "
+ "ON c1.entry_pdb_id = i.entry_pdb_id AND c1.chain_asym_id = "
+ "split_part(i.interface_chain_1, '.', 2) LEFT JOIN entry_chains c2 "
+ "ON c2.entry_pdb_id = i.entry_pdb_id AND c2.chain_asym_id = "
+ "split_part(i.interface_chain_2, '.', 2) WHERE "
+ "c1.chain_asym_id IS NULL OR c2.chain_asym_id IS NULL OR "
+ "c1.chain_receptor_type != 'protein' OR "
+ "c2.chain_receptor_type != 'protein')",
+ )
+ )
+ if (
+ orphan_sources
+ or orphan_system_validation
+ or orphan_chains
+ or orphan_biounits
+ or orphan_metadata
+ or orphan_interface_instances
+ or orphan_interface_chains
+ ):
+ raise ValueError(
+ "referential-integrity failures: "
+ f"sources={orphan_sources}, "
+ f"system_validation={orphan_system_validation}, "
+ f"chains={orphan_chains}, "
+ f"biounits={orphan_biounits}, metadata={orphan_metadata}, "
+ f"interface_instances={orphan_interface_instances}, "
+ f"interface_chains={orphan_interface_chains}"
+ )
+ missing_comparabilities = int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM annotation WHERE system_type = 'holo' "
+ "AND coalesce(ligand_is_proper, false) "
+ "AND ligand_is_shape_comparable IS NULL",
+ )
+ )
+ invalid_nonproper_comparabilities = int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM annotation WHERE NOT (system_type = 'holo' "
+ "AND coalesce(ligand_is_proper, false)) "
+ "AND coalesce(ligand_is_shape_comparable, false)",
+ )
+ )
+ invalid_systems = int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM (SELECT system_id FROM annotation "
+ "GROUP BY system_id HAVING bool_and(coalesce(ligand_is_ion, false) "
+ "OR coalesce(ligand_is_artifact, false)))",
+ )
+ )
+ mismatched_biounits = int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM annotation WHERE "
+ "split_part(ligand_id, '__', 2) IS DISTINCT FROM system_biounit_id "
+ "OR split_part(system_id, '__', 2) IS DISTINCT FROM system_biounit_id",
+ )
+ )
+ if (
+ missing_comparabilities
+ or invalid_nonproper_comparabilities
+ or invalid_systems
+ or mismatched_biounits
+ ):
+ raise ValueError(
+ "annotation validation failed: "
+ f"missing_comparability={missing_comparabilities}, "
+ f"nonproper_comparability={invalid_nonproper_comparabilities}, "
+ f"all_ion_or_artifact_systems={invalid_systems}, "
+ f"mismatched_biounits={mismatched_biounits}"
+ )
+ return {
+ "row_counts": actual_counts,
+ "duplicate_key_counts": duplicates,
+ "entry_count": int(
+ _fetch_scalar(
+ connection,
+ "SELECT count(DISTINCT entry_pdb_id) FROM entry_metadata",
+ )
+ ),
+ "system_count": int(
+ _fetch_scalar(
+ connection, "SELECT count(DISTINCT system_id) FROM annotation"
+ )
+ ),
+ "ligand_count": int(
+ _fetch_scalar(
+ connection, "SELECT count(DISTINCT ligand_id) FROM annotation"
+ )
+ ),
+ "interface_count": int(
+ _fetch_scalar(connection, "SELECT count(*) FROM interfaces")
+ ),
+ }
+ finally:
+ connection.close()
+
+
+def finalize_collation(
+ data_dir: Path,
+ *,
+ threads: int = 4,
+ memory_limit: str = "16GB",
+ scratch_dir: Path | None = None,
+ row_group_size: int = 100_000,
+) -> dict[str, Any]:
+ """Merge completed shards, validate them, and install final index files."""
+ data_dir = data_dir.resolve()
+ plan = load_plan(data_dir)
+ include_ligand_annotations = bool(plan.get("include_ligand_annotations", True))
+ shard_files, expected_counts = _load_completed_shards(data_dir, plan)
+ final_paths = entry_table_paths(data_dir)
+ if not include_ligand_annotations:
+ required_ligand_tables = [
+ final_paths["annotation"],
+ final_paths["system_validation"],
+ ]
+ missing_ligand_tables = [
+ path for path in required_ligand_tables if not path.is_file()
+ ]
+ if missing_ligand_tables:
+ raise FileNotFoundError(
+ "interface-only collation requires installed ligand tables: "
+ f"{missing_ligand_tables}"
+ )
+ temporary_paths = {name: _temporary_path(final_paths[name]) for name in shard_files}
+ for path in final_paths.values():
+ path.parent.mkdir(parents=True, exist_ok=True)
+ connection = duckdb.connect()
+ try:
+ _configure_duckdb(
+ connection,
+ threads=threads,
+ memory_limit=memory_limit,
+ scratch_dir=scratch_dir,
+ )
+ for name, paths in shard_files.items():
+ connection.read_parquet(
+ [str(path) for path in paths], union_by_name=True
+ ).create_view(f"sharded_{name}", replace=True)
+ if name == "annotation":
+ schema = (
+ connection.execute("SELECT * FROM sharded_annotation LIMIT 0")
+ .to_arrow_table()
+ .schema
+ )
+ _merge_parquet_shards(
+ paths,
+ temporary_paths[name],
+ schema,
+ row_group_size=row_group_size,
+ )
+ continue
+ _copy_query(
+ connection,
+ f"SELECT * FROM sharded_{name} ORDER BY {ENTRY_TABLES[name][1]}",
+ temporary_paths[name],
+ row_group_size=row_group_size,
+ )
+ finally:
+ connection.close()
+ try:
+ validation_paths = dict(temporary_paths)
+ if not include_ligand_annotations:
+ validation_paths["annotation"] = final_paths["annotation"]
+ validation_paths["system_validation"] = final_paths["system_validation"]
+ expected_counts["annotation"] = pq.ParquetFile(
+ final_paths["annotation"]
+ ).metadata.num_rows
+ expected_counts["system_validation"] = pq.ParquetFile(
+ final_paths["system_validation"]
+ ).metadata.num_rows
+ validation = _validate_final_tables(
+ validation_paths,
+ expected_counts=expected_counts,
+ min_interface_residues=int(plan["interface_min_residues"]),
+ ligand_contacts_computed=bool(plan["ligand_contacts_computed"]),
+ protein_contacts_computed=bool(plan["protein_contacts_computed"]),
+ threads=threads,
+ memory_limit=memory_limit,
+ scratch_dir=scratch_dir,
+ )
+ _install_final_tables_fail_closed(
+ temporary_paths,
+ final_paths,
+ data_dir / "index" / FINAL_MARKER_NAME,
+ preserve_annotation=not include_ligand_annotations,
+ )
+ finally:
+ for path in temporary_paths.values():
+ path.unlink(missing_ok=True)
+ report: dict[str, Any] = {
+ "version": COLLATION_VERSION,
+ "status": "complete",
+ "plan": str(plan_path(data_dir)),
+ "manifest": str(manifest_path(data_dir)),
+ "code_count": len(plan["codes"]),
+ "interface_min_residues": int(plan["interface_min_residues"]),
+ "ligand_contacts_computed": bool(plan["ligand_contacts_computed"]),
+ "protein_contacts_computed": bool(plan["protein_contacts_computed"]),
+ "include_ligand_annotations": include_ligand_annotations,
+ "outputs": {name: str(path) for name, path in final_paths.items()},
+ **validation,
+ }
+ write_json_atomic(data_dir / "index" / FINAL_MARKER_NAME, report)
+ return report
+
+
+def _repair_rows_differ(
+ connection: duckdb.DuckDBPyConnection, name: str, columns: Sequence[str]
+) -> bool:
+ """Compare selected installed entries with their replacement rows."""
+ installed_columns = _relation_columns(connection, f"installed_{name}")
+ installed_select = ", ".join(
+ _quote_identifier(column) if column in installed_columns else "NULL"
+ for column in columns
+ )
+ replacement_select = ", ".join(_quote_identifier(column) for column in columns)
+ installed = (
+ f"SELECT {installed_select} FROM installed_{name} "
+ "INNER JOIN repaired_entries USING (entry_pdb_id)"
+ )
+ replacement = f"SELECT {replacement_select} FROM replacement_{name}"
+ return bool(
+ _fetch_scalar(
+ connection,
+ "SELECT count(*) FROM ("
+ f"({installed} EXCEPT ALL {replacement}) UNION ALL "
+ f"({replacement} EXCEPT ALL {installed}))",
+ )
+ )
+
+
+def repair_collation(
+ data_dir: Path,
+ pdb_ids: Sequence[str],
+ *,
+ threads: int = 4,
+ memory_limit: str = "16GB",
+ scratch_dir: Path | None = None,
+ row_group_size: int = 100_000,
+) -> dict[str, Any]:
+ """Atomically replace selected entries in an existing collated index.
+
+ This is intended for corrections that require re-annotating a bounded set of
+ entries. Unselected rows are read from the installed index, so release-only
+ columns are preserved without rebuilding every raw entry. Chain modification
+ annotations can change; chain identities, sequences, assembly membership,
+ and source revisions must still match the protein scoring inputs.
+ """
+ data_dir = data_dir.resolve()
+ selected = sorted({str(pdb_id).lower() for pdb_id in pdb_ids})
+ invalid = [
+ pdb_id
+ for pdb_id in selected
+ if re.fullmatch(r"[0-9][a-z0-9]{3}", pdb_id) is None
+ ]
+ if invalid:
+ raise ValueError(f"invalid repair PDB IDs: {invalid[:10]}")
+ if not selected:
+ raise ValueError("no PDB IDs selected for index repair")
+
+ final_paths = entry_table_paths(data_dir)
+ missing_final = [path for path in final_paths.values() if not path.is_file()]
+ if missing_final:
+ raise FileNotFoundError(f"missing installed index tables: {missing_final}")
+
+ marker_path = data_dir / "index" / FINAL_MARKER_NAME
+ try:
+ installed_marker = cast(dict[str, Any], json.loads(marker_path.read_text()))
+ installed_interface_min_residues = int(
+ installed_marker["interface_min_residues"]
+ )
+ ligand_contacts_computed = installed_marker["ligand_contacts_computed"]
+ protein_contacts_computed = installed_marker["protein_contacts_computed"]
+ if not isinstance(ligand_contacts_computed, bool) or not isinstance(
+ protein_contacts_computed, bool
+ ):
+ raise TypeError("invalid contact state")
+ except (OSError, KeyError, TypeError, ValueError, json.JSONDecodeError) as exc:
+ raise ValueError(
+ "targeted repair requires a collated interface threshold"
+ ) from exc
+
+ rows = [
+ _entry_manifest_row(
+ data_dir,
+ data_dir / "raw_entries" / pdb_id[1:3] / pdb_id,
+ )
+ for pdb_id in selected
+ ]
+ if {bool(row["ligand_contacts_computed"]) for row in rows} != {
+ ligand_contacts_computed
+ } or {bool(row["protein_contacts_computed"]) for row in rows} != {
+ protein_contacts_computed
+ }:
+ raise ValueError(
+ "targeted repair contact groups differ from the installed release"
+ )
+ replacement_interface_thresholds = {
+ int(row["interface_min_residues"]) for row in rows
+ }
+ if replacement_interface_thresholds != {installed_interface_min_residues}:
+ raise ValueError(
+ "targeted repair interface.min_interface_residues differs from the "
+ f"installed release: replacement={sorted(replacement_interface_thresholds)}, "
+ f"installed={installed_interface_min_residues}"
+ )
+ _verify_manifest_inputs(rows, threads=threads)
+ temporary_paths = {
+ name: _temporary_path(final_paths[name])
+ for name in (
+ "annotation",
+ "system_validation",
+ "entry_metadata",
+ "interfaces",
+ )
+ }
+ replacement_paths = {
+ name: _temporary_path(path.with_name(f"repair-{path.name}"))
+ for name, path in final_paths.items()
+ if name not in {"annotation", "system_validation"}
+ }
+
+ chain_annotations_changed = False
+ try:
+ for name, schema in SIDECAR_SCHEMAS.items():
+ source_key = {
+ "entry_chains": "chain_path",
+ "entry_biounit_chains": "biounit_chain_path",
+ "interfaces": "interface_path",
+ "entry_sources": "source_path",
+ }[name]
+ _collate_sidecars(
+ [Path(str(row[source_key])) for row in rows],
+ replacement_paths[name],
+ schema,
+ sort_columns=tuple(ENTRY_TABLES[name][1].split(", ")),
+ row_group_size=row_group_size,
+ optional_columns=(
+ _uncomputed_contact_columns(installed_marker)
+ if name == "entry_biounit_chains"
+ else frozenset()
+ ),
+ )
+ _collate_entry_metadata(
+ [Path(str(row["metadata_path"])) for row in rows],
+ replacement_paths["entry_metadata"],
+ row_group_size=row_group_size,
+ )
+
+ connection = duckdb.connect()
+ try:
+ _configure_duckdb(
+ connection,
+ threads=threads,
+ memory_limit=memory_limit,
+ scratch_dir=scratch_dir,
+ )
+ connection.register(
+ "repaired_entries", pa.table({"entry_pdb_id": selected})
+ )
+ ligand_rows = [row for row in rows if row["annotation_size"] is not None]
+ if ligand_rows:
+ _build_annotation_view(
+ connection,
+ [str(row["annotation_path"]) for row in ligand_rows],
+ [str(row["ligand_path"]) for row in ligand_rows],
+ )
+ connection.read_parquet(str(final_paths["annotation"])).create_view(
+ "installed_annotation", replace=True
+ )
+ installed_annotation_columns = _annotation_columns_to_publish(
+ _relation_columns(connection, "installed_annotation")
+ )
+ installed_annotation_select = ", ".join(
+ f"installed.{_quote_identifier(column)}"
+ for column in installed_annotation_columns
+ )
+ repaired_annotation = (
+ "UNION ALL BY NAME SELECT * FROM collated_annotation"
+ if ligand_rows
+ else ""
+ )
+ _copy_query(
+ connection,
+ f"SELECT * FROM (SELECT {installed_annotation_select} "
+ "FROM installed_annotation "
+ "AS installed ANTI JOIN repaired_entries USING (entry_pdb_id) "
+ f"{repaired_annotation}) "
+ "ORDER BY entry_pdb_id, system_id, ligand_id",
+ temporary_paths["annotation"],
+ row_group_size=row_group_size,
+ )
+ connection.read_parquet(str(final_paths["system_validation"])).create_view(
+ "installed_system_validation", replace=True
+ )
+ replacement_system_validation = (
+ "UNION ALL BY NAME SELECT * FROM collated_system_validation"
+ if ligand_rows
+ else ""
+ )
+ _copy_query(
+ connection,
+ "SELECT * FROM (SELECT installed.* FROM "
+ "installed_system_validation AS installed ANTI JOIN "
+ "repaired_entries ON split_part(installed.system_id, '__', 1) = "
+ "repaired_entries.entry_pdb_id "
+ f"{replacement_system_validation}) ORDER BY system_id",
+ temporary_paths["system_validation"],
+ row_group_size=row_group_size,
+ )
+ for name in (
+ "entry_chains",
+ "entry_biounit_chains",
+ "entry_sources",
+ ):
+ connection.read_parquet(str(final_paths[name])).create_view(
+ f"installed_{name}", replace=True
+ )
+ connection.read_parquet(str(replacement_paths[name])).create_view(
+ f"replacement_{name}", replace=True
+ )
+ columns = SIDECAR_SCHEMAS[name].names
+ protected_columns = [
+ column
+ for column in columns
+ if name != "entry_chains"
+ or column not in CHAIN_MODIFICATION_COLUMNS
+ ]
+ installed_columns = _relation_columns(connection, f"installed_{name}")
+ if not set(columns).issubset(installed_columns):
+ raise ValueError(
+ f"installed {name} does not have the current schema"
+ )
+ if _repair_rows_differ(connection, name, protected_columns):
+ raise ValueError(
+ f"targeted repair changed {name}; rebuild the protein "
+ "scoring inputs and mapped alignments instead"
+ )
+ if name == "entry_chains":
+ chain_annotations_changed = _repair_rows_differ(
+ connection, name, columns
+ )
+ replacements = ["entry_metadata", "interfaces"]
+ if chain_annotations_changed:
+ temporary_paths["entry_chains"] = _temporary_path(
+ final_paths["entry_chains"]
+ )
+ replacements.append("entry_chains")
+ for name in replacements:
+ connection.read_parquet(str(final_paths[name])).create_view(
+ f"installed_{name}", replace=True
+ )
+ connection.read_parquet(str(replacement_paths[name])).create_view(
+ f"replacement_{name}", replace=True
+ )
+ _copy_query(
+ connection,
+ f"SELECT * FROM (SELECT installed.* FROM installed_{name} "
+ "AS installed ANTI JOIN repaired_entries USING (entry_pdb_id) "
+ f"UNION ALL BY NAME SELECT * FROM replacement_{name}) "
+ f"ORDER BY {ENTRY_TABLES[name][1]}",
+ temporary_paths[name],
+ row_group_size=row_group_size,
+ )
+ finally:
+ connection.close()
+
+ validation_paths = {**final_paths, **temporary_paths}
+ expected_counts = {
+ name: pq.ParquetFile(path).metadata.num_rows
+ for name, path in validation_paths.items()
+ }
+ validation = _validate_final_tables(
+ validation_paths,
+ expected_counts=expected_counts,
+ min_interface_residues=installed_interface_min_residues,
+ ligand_contacts_computed=ligand_contacts_computed,
+ protein_contacts_computed=protein_contacts_computed,
+ threads=threads,
+ memory_limit=memory_limit,
+ scratch_dir=scratch_dir,
+ )
+ marker = data_dir / "index" / FINAL_MARKER_NAME
+ marker.unlink(missing_ok=True)
+ final_paths["annotation"].unlink(missing_ok=True)
+ for name, path in temporary_paths.items():
+ if name != "annotation":
+ path.replace(final_paths[name])
+ temporary_paths["annotation"].replace(final_paths["annotation"])
+ finally:
+ for path in [*temporary_paths.values(), *replacement_paths.values()]:
+ path.unlink(missing_ok=True)
+
+ report: dict[str, Any] = {
+ "version": COLLATION_VERSION,
+ "status": REPAIR_REQUIRED_STATUS,
+ "mode": "targeted_repair",
+ "repaired_entry_count": len(selected),
+ "interface_min_residues": installed_interface_min_residues,
+ "ligand_contacts_computed": ligand_contacts_computed,
+ "protein_contacts_computed": protein_contacts_computed,
+ "repaired_entry_digest": hashlib.sha256(
+ ("\n".join(selected) + "\n").encode("utf-8")
+ ).hexdigest(),
+ "outputs": {name: str(path) for name, path in final_paths.items()},
+ "required_downstream_artifacts": [
+ "ligand_similarity",
+ "scores",
+ "ligand_clusters",
+ "ligand_sampling",
+ "interface_scores",
+ "interface_clusters",
+ "interface_sampling",
+ ],
+ **validation,
+ }
+ write_json_atomic(data_dir / "index" / FINAL_MARKER_NAME, report)
+ return report
+
+
+def finalize_repair_marker(data_dir: Path) -> dict[str, Any] | None:
+ """Mark a targeted collation repair complete after final index enrichment."""
+ marker_path = data_dir / "index" / FINAL_MARKER_NAME
+ if not marker_path.is_file():
+ return None
+ report = cast(dict[str, Any], json.loads(marker_path.read_text()))
+ if (
+ report.get("mode") != "targeted_repair"
+ or report.get("status") != REPAIR_REQUIRED_STATUS
+ ):
+ return None
+ report["status"] = "complete"
+ report["downstream_repair_complete"] = True
+ write_json_atomic(marker_path, report)
+ return report
+
+
+def run_collation(
+ data_dir: Path,
+ *,
+ threads: int = 1,
+ memory_limit: str = "8GB",
+ scratch_dir: Path | None = None,
+ row_group_size: int = 100_000,
+ force: bool = False,
+ include_ligand_annotations: bool = True,
+) -> dict[str, Any]:
+ """Run all collation phases locally; intended for tests and small releases."""
+ plan = plan_collation(
+ data_dir, threads=threads, include_ligand_annotations=include_ligand_annotations
+ )
+ for code in plan["codes"]:
+ collate_shard(
+ data_dir,
+ code,
+ force=force,
+ threads=threads,
+ memory_limit=memory_limit,
+ scratch_dir=scratch_dir,
+ row_group_size=row_group_size,
+ )
+ return finalize_collation(
+ data_dir,
+ threads=threads,
+ memory_limit=memory_limit,
+ scratch_dir=scratch_dir,
+ row_group_size=row_group_size,
+ )
+
+
+def planned_code_batch(
+ data_dir: Path, *, batch_index: int, batch_size: int
+) -> list[str]:
+ """Return one fixed-size slice of the planned two-character codes."""
+ if batch_index < 0:
+ raise ValueError("batch_index must be non-negative")
+ if batch_size < 1:
+ raise ValueError("batch_size must be positive")
+ codes = [str(code) for code in load_plan(data_dir)["codes"]]
+ start = batch_index * batch_size
+ return codes[start : start + batch_size]
+
+
+def build_parser() -> argparse.ArgumentParser:
+ parser = argparse.ArgumentParser(description=__doc__)
+ commands = parser.add_subparsers(dest="command", required=True)
+ for name in (
+ "plan",
+ "plan-start",
+ "plan-shard",
+ "plan-finish",
+ "shard",
+ "finalize",
+ "repair",
+ "run",
+ ):
+ command = commands.add_parser(name)
+ command.add_argument("data_dir", type=Path)
+ if name in {"plan", "plan-start"}:
+ command.add_argument("--interfaces-only", action="store_true")
+ if name in {"plan-shard", "shard"}:
+ command.add_argument("codes", nargs="*")
+ command.add_argument("--batch-index", type=int)
+ command.add_argument("--batch-size", type=int)
+ if name == "shard":
+ command.add_argument("--pdb-manifest", type=Path)
+ if name == "repair":
+ command.add_argument("--pdb-manifest", type=Path, required=True)
+ if name in {"plan", "plan-shard", "shard", "finalize", "repair", "run"}:
+ command.add_argument("--threads", type=int, default=1)
+ if name in {"shard", "finalize", "repair", "run"}:
+ command.add_argument("--memory-limit", default="8GB")
+ command.add_argument("--scratch-dir", type=Path)
+ command.add_argument("--row-group-size", type=int, default=100_000)
+ if name in {"shard", "run"}:
+ command.add_argument("--force", action="store_true")
+ return parser
+
+
+def main() -> None:
+ args = build_parser().parse_args()
+ if args.command == "plan":
+ result = plan_collation(
+ args.data_dir,
+ threads=args.threads,
+ include_ligand_annotations=not args.interfaces_only,
+ )
+ elif args.command == "plan-start":
+ result = start_collation_plan(
+ args.data_dir,
+ include_ligand_annotations=not args.interfaces_only,
+ )
+ elif args.command == "plan-shard":
+ codes = args.codes
+ if args.batch_index is not None or args.batch_size is not None:
+ if codes or args.batch_index is None or args.batch_size is None:
+ raise ValueError(
+ "pass either explicit codes or both --batch-index and --batch-size"
+ )
+ codes = planned_inventory_code_batch(
+ args.data_dir,
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ if not codes:
+ raise ValueError("no collation inventory codes selected")
+ result = inventory_collation_codes(
+ args.data_dir,
+ codes,
+ threads=args.threads,
+ )
+ elif args.command == "plan-finish":
+ result = finalize_collation_plan(args.data_dir)
+ elif args.command == "shard":
+ codes = args.codes
+ if args.pdb_manifest is not None:
+ if codes:
+ raise ValueError("pass a PDB manifest or explicit codes, not both")
+ from plinder.data.pipeline.ingest import load_manifest
+
+ codes = sorted({pdb_id[1:3] for pdb_id in load_manifest(args.pdb_manifest)})
+ if args.batch_index is not None or args.batch_size is not None:
+ if args.batch_index is None or args.batch_size is None:
+ raise ValueError(
+ "both --batch-index and --batch-size are required for a slice"
+ )
+ start = args.batch_index * args.batch_size
+ codes = codes[start : start + args.batch_size]
+ args.batch_index = None
+ args.batch_size = None
+ if args.batch_index is not None or args.batch_size is not None:
+ if codes or args.batch_index is None or args.batch_size is None:
+ raise ValueError(
+ "pass either explicit codes or both --batch-index and --batch-size"
+ )
+ codes = planned_code_batch(
+ args.data_dir,
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ if not codes:
+ raise ValueError("no collation shard codes selected")
+ result = {
+ "shards": [
+ collate_shard(
+ args.data_dir,
+ code,
+ force=args.force,
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ scratch_dir=args.scratch_dir,
+ row_group_size=args.row_group_size,
+ )
+ for code in codes
+ ]
+ }
+ elif args.command == "finalize":
+ result = finalize_collation(
+ args.data_dir,
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ scratch_dir=args.scratch_dir,
+ row_group_size=args.row_group_size,
+ )
+ elif args.command == "repair":
+ from plinder.data.pipeline.ingest import load_manifest
+
+ result = repair_collation(
+ args.data_dir,
+ load_manifest(args.pdb_manifest),
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ scratch_dir=args.scratch_dir,
+ row_group_size=args.row_group_size,
+ )
+ else:
+ result = run_collation(
+ args.data_dir,
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ scratch_dir=args.scratch_dir,
+ row_group_size=args.row_group_size,
+ force=args.force,
+ )
+ if args.command in {"finalize", "repair", "run"}:
+ from plinder.data.annotations.affinity import publish_affinity_tables
+ from plinder.data.pipeline.io import download_affinity_data
+
+ download_affinity_data(data_dir=args.data_dir)
+ publish_affinity_tables(args.data_dir)
+ printable = result
+ if args.command in {"plan", "plan-start", "plan-finish"}:
+ printable = {
+ key: value
+ for key, value in result.items()
+ if key
+ not in {
+ "code_directory_signatures",
+ "code_entry_counts",
+ "code_signatures",
+ "codes",
+ }
+ }
+ print(json.dumps(printable, indent=2, sort_keys=True))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/plinder/data/pipeline/config.py b/src/plinder/data/pipeline/config.py
index d92f171ad..b60cd4754 100644
--- a/src/plinder/data/pipeline/config.py
+++ b/src/plinder/data/pipeline/config.py
@@ -1,45 +1,19 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
+import sys
from dataclasses import dataclass, field
from functools import partial
from typing import Any, Optional
+from omegaconf import DictConfig, OmegaConf
+
+from plinder.core.scores.metrics import (
+ CHEMICAL_CLUSTER_METRICS,
+ DEFAULT_CLUSTER_METRICS,
+)
from plinder.core.utils import config as _config
-METRICS = [
- # pli_qcov:
- "pli_qcov",
- "pli_unique_qcov",
- # seq_sim:
- "protein_seqsim_qcov_max",
- "protein_seqsim_qcov_weighted_max",
- "protein_seqsim_qcov_weighted_sum",
- "protein_seqsim_max",
- "protein_seqsim_weighted_max",
- "protein_seqsim_weighted_sum",
- # protein
- "protein_fident_qcov_max",
- "protein_fident_qcov_weighted_max",
- "protein_fident_qcov_weighted_sum",
- "protein_fident_max",
- "protein_fident_weighted_max",
- "protein_fident_weighted_sum",
- "protein_lddt_max",
- "protein_lddt_qcov_max",
- "protein_lddt_qcov_weighted_max",
- "protein_lddt_qcov_weighted_sum",
- "protein_lddt_weighted_max",
- "protein_lddt_weighted_sum",
- "protein_qcov_max",
- "protein_qcov_weighted_max",
- "protein_qcov_weighted_sum",
- # pocket
- "pocket_fident_qcov",
- "pocket_fident",
- "pocket_lddt_qcov",
- "pocket_lddt",
- "pocket_qcov",
-]
+METRICS = list(DEFAULT_CLUSTER_METRICS)
@dataclass
@@ -59,12 +33,14 @@ class FlowConfig:
if set, comma-separated list of specific stages to skip
download_rcsb_files_batch_size: int
Target number of two_char_codes per task batch.
- annotation_batch_size : int, default=220
- How many system annotations to generate in a given chunk
- skip_existing_entries : bool, default=True
- if the entry JSON already exists, skip generation
- make_entries_cpu : int, default=1
- misguided experiments in multiprocessing over C++ libs (bad idea)
+ make_entries_batch_size : int, default=220
+ Number of entries per task batch.
+ make_entries_force_update : bool, default=False
+ Reprocess entries with completed annotations.
+ make_entries_cpu : int, default=4
+ Number of entry-processing workers.
+ make_entries_mode : str, default="all"
+ Generate ligands and interfaces, only ligands, or only interfaces.
"""
run_specific_stages: Any = ""
@@ -76,37 +52,74 @@ class FlowConfig:
make_entries_batch_size: int = 220
make_entries_force_update: bool = False
make_entries_cpu: int = 4
+ make_entries_mode: str = "all"
- structure_qc_force_update: bool = False
+ collate_entries_batch_size: int = 4
+ collate_entries_cpu: int = 2
+ collate_entries_memory_limit: str = "7GB"
+ finalize_entries_cpu: int = 4
+ finalize_entries_memory_limit: str = "32GB"
make_sub_dbs_cpu: int = 4
+ protein_clustering_cpu: int = 4
+ protein_sequence_cluster_identity: float = 0.4
+ protein_structure_cluster_lddt: float = 0.7
+ protein_cluster_coverage: float = 0.8
make_scorers_cpu: int = 4
download_alternative_datasets_threads: int = 10
+ make_dbs_cpu: int = 4
make_ligands_batch_size: int = 100
- make_ligands_force_update: bool = False
cluster_metrics: list[str] = field(default_factory=lambda: METRICS.copy())
- cluster_thresholds: list[int] = field(default_factory=lambda: [50, 70, 95, 100])
+ cluster_thresholds: list[int] = field(default_factory=lambda: [30, 50, 70, 90, 100])
+ symmetric_edge_source_batch_size: int = 20
+ symmetric_edge_bucket_count: int = 64
+ component_reduction_source_batch_size: int = 1
+ component_reduction_metric_workers: int = 4
+ clustering_cpu: int = 4
make_components_force_update: bool = True
make_components_stop_on_cluster: int = 0
- run_batch_searches_batch_size: int = 10050
+ run_batch_searches_batch_size: int = 5_000
+ map_batch_alignments_batch_size: int = 25
+ make_interface_scores_batch_size: int = 1
+ make_interface_scores_cpu: int = 4
+ make_interface_scores_memory_limit: str = "32GB"
make_batch_scores_batch_size: int = 90
+ make_batch_scores_cpu: int = 4
make_batch_scores_force_update: bool = False
-
- make_links_cpu: int = 8
- make_linked_structures_cpu: int = 8
- make_linked_structures_force_update: bool = False
- score_linked_structures_cpu: int = 8
- score_linked_structures_batch_size: int = 100
- score_linked_structures_force_update: bool = False
- sub_databases: Any = "apo,pred"
-
- split_config_dir: str = ""
- test_leakage: bool = False
+ make_ligand_3d_scores_batch_size: int = 30_000
+ make_ligand_3d_scores_cpu: int = 1
+ collate_ligand_3d_candidates_batch_size: int = 4
+ collate_ligand_3d_scores_batch_size: int = 4
+ merge_ligand_3d_scores_batch_size: int = 4
+ collate_partitions_cpu: int = 4
+ collate_partitions_memory_limit: str = "7GB"
def __post_init__(self) -> None:
+ if self.make_entries_mode not in {"all", "ligands", "interfaces"}:
+ raise ValueError(
+ "flow.make_entries_mode must be all, ligands, or interfaces"
+ )
+ if self.collate_entries_batch_size < 1:
+ raise ValueError("flow.collate_entries_batch_size must be positive")
+ if self.collate_entries_cpu < 1 or self.finalize_entries_cpu < 1:
+ raise ValueError("entry collation CPU counts must be positive")
+ for name in [
+ "component_reduction_metric_workers",
+ "symmetric_edge_source_batch_size",
+ "symmetric_edge_bucket_count",
+ "make_interface_scores_batch_size",
+ "make_interface_scores_cpu",
+ "make_ligand_3d_scores_batch_size",
+ "make_ligand_3d_scores_cpu",
+ "collate_ligand_3d_candidates_batch_size",
+ "collate_ligand_3d_scores_batch_size",
+ "merge_ligand_3d_scores_batch_size",
+ ]:
+ if getattr(self, name) < 1:
+ raise ValueError(f"flow.{name} must be positive")
if isinstance(self.run_specific_stages, str):
self.run_specific_stages = [
stage for stage in self.run_specific_stages.split(",") if stage
@@ -115,8 +128,25 @@ def __post_init__(self) -> None:
self.skip_specific_stages = [
stage for stage in self.skip_specific_stages.split(",") if stage
]
- if isinstance(self.sub_databases, str):
- self.sub_databases = [db for db in self.sub_databases.split(",") if db]
+
+
+@dataclass
+class SourceConfig:
+ """Locations of the source archives consumed by entry ingest.
+
+ Empty roots use ``PLINDER_PDB_NEXTGEN_ROOT`` and
+ ``PLINDER_VALIDATION_ROOT`` when set, then fall back to the release-local
+ ``ingest`` and ``reports`` directories.
+ """
+
+ pdb_nextgen_root: str = ""
+ validation_root: str = ""
+ seqres_path: str = ""
+ discovery_threads: int = 8
+
+ def __post_init__(self) -> None:
+ if self.discovery_threads < 1:
+ raise ValueError("source.discovery_threads must be positive")
@dataclass
@@ -124,55 +154,52 @@ class FoldseekConfig:
alignment_type: int = 2
score_type: str = "lddt"
evalue: float = 0.01 # pinder uses default=0.05
- max_seqs: int = 5000 # pinder uses default=1000
+ max_seqs: int = 10_000
sensitivity: float = 11.0 # pinder uses default=11.0
min_seq_id: float = 0.2
coverage: float = 0.0
alignment_filename: str = "alignment.txt"
def __post_init__(self) -> None:
- for attr, allowed in [
- ("alignment_type", [1, 2]),
- ("score_type", ["lddt", "alntmscore"]),
- ]:
- passed = getattr(self, attr, None)
- if passed not in allowed: # type: ignore
- raise ValueError(
- f"{self.__class__.__name__}.{attr} must be in {allowed}"
- )
+ if self.max_seqs < 1:
+ raise ValueError("foldseek.max_seqs must be positive")
+ if not 0 <= self.min_seq_id <= 1:
+ raise ValueError("foldseek.min_seq_id must be in [0, 1]")
+ if self.alignment_type not in {1, 2}:
+ raise ValueError("FoldseekConfig.alignment_type must be in [1, 2]")
+ if self.score_type not in {"lddt", "alntmscore"}:
+ raise ValueError(
+ "FoldseekConfig.score_type must be in ['lddt', 'alntmscore']"
+ )
@dataclass
class MMSeqsConfig:
score_type: str = "pident"
evalue: float = 0.01 # pinder uses default=0.05
- max_seqs: int = 5000 # pinder uses default=1000
+ max_seqs: int = 10_000
sensitivity: float = 11.0 # pinder uses default=11.0
min_seq_id: float = 0.2
coverage: float = 0.0
alignment_filename: str = "alignment.txt"
def __post_init__(self) -> None:
- for attr, allowed in [
- ("score_type", ["pident"]),
- ]:
- if getattr(self, attr) not in allowed:
- raise ValueError(
- f"{self.__class__.__name__}.{attr} must be in {allowed}"
- )
-
-
-@dataclass
-class GraphConfig:
- pass
+ if self.max_seqs < 1:
+ raise ValueError("mmseqs.max_seqs must be positive")
+ if not 0 <= self.min_seq_id <= 1:
+ raise ValueError("mmseqs.min_seq_id must be in [0, 1]")
+ if self.score_type != "pident":
+ raise ValueError("MMSeqsConfig.score_type must be in ['pident']")
@dataclass
class ScorerConfig:
- wipe_partition: bool = False
- rerun_existing_batch: bool = False
- minimum_threshold: float = 0.2
- sub_databases: Any = "holo,apo,pred"
+ minimum_threshold: float = 0.3
+ minimum_thresholds: dict[str, float] = field(default_factory=dict)
+ max_alignment_rows_per_query: int = 5_000_000
+ max_query_protein_chains: int = 30
+ max_query_proper_ligand_chains: int = 30
+ sub_databases: Any = "holo,apo"
def __post_init__(self) -> None:
if isinstance(self.sub_databases, str):
@@ -187,20 +214,26 @@ def __post_init__(self) -> None:
raise ValueError(
f"{self.__class__.__name__}.minimum_threshold must be in [0, 1]"
)
+ for metric, threshold in self.minimum_thresholds.items():
+ if threshold < 0 or threshold > 1:
+ raise ValueError(
+ f"scorer.minimum_thresholds[{metric!r}] must be in [0, 1]"
+ )
+ if self.max_alignment_rows_per_query < 1:
+ raise ValueError("scorer.max_alignment_rows_per_query must be positive")
+ if self.max_query_protein_chains < 1 or self.max_query_proper_ligand_chains < 1:
+ raise ValueError("scorer query system chain limits must be positive")
@dataclass
class EntryConfig:
- # TODO-tjd: deduplicate with AnnotationConfig
- max_protein_chains_to_save: int = 5
- max_ligand_chains_to_save: int = 5
- neighboring_residue_threshold: float = 6.0
- neighboring_ligand_threshold: float = 4.0
- min_polymer_size: int = 10
- max_non_small_mol_ligand_length: int = 20
- plip_complex_threshold: float = 10.0
+ """Entry-reader options; shared annotation thresholds live in AnnotationConfig."""
+
+ interaction_search_threshold: float = 10.0
+ # heavy atoms; Voronota-LT needs ~2.2 KB/atom, skipped assemblies get null areas
+ tessellation_atom_limit: int = 2_000_000
+ data_dir: Optional[str] = None
save_folder: Optional[str] = None
- skip_save_systems: bool = False
@dataclass
@@ -218,35 +251,56 @@ class AnnotationConfig:
neighboring_residue_threshold: float = 6.0
neighboring_ligand_threshold: float = 4.0
- min_polymer_size: int = 10
+ min_polymer_size: int = 12
+ min_shared_pocket_members: int = 3
-""" From
-OleinikovasV
-OleinikovasV commented Apr 22, 2024
+@dataclass
+class InterfaceConfig:
+ """Protein-interface definitions used during entry ingest."""
-Added updated artifacts list and curation, please, review the logic!
+ contact_radius: float = 10.0
+ min_chain_length: int = 12
+ min_interface_residues: int = 7
+ annotate_prodigy: bool = True
-"""
+ def __post_init__(self) -> None:
+ if self.contact_radius <= 0:
+ raise ValueError("interface.contact_radius must be positive")
+ if self.min_chain_length < 1:
+ raise ValueError("interface.min_chain_length must be positive")
+ if self.min_interface_residues < 1:
+ raise ValueError("interface.min_interface_residues must be positive")
@dataclass
class LigandConfig:
- radius: int = 2
- nbits: int = 1024
- ligand_id_split_char: str = "__"
- save_top_k_similar_ligands: int = 5000
- multiply_by: int = 100
- number_id_col: str = "number_id_by_inchikeys"
- score_name: str = "tanimoto_similarity_max"
+ minimum_similarity: float = 30.0
+ cofactor_similarity_threshold: float = 90.0
+ number_id_col: str = "ligand_smiles_id"
+
+ def __post_init__(self) -> None:
+ for name in [
+ "minimum_similarity",
+ "cofactor_similarity_threshold",
+ ]:
+ value = float(getattr(self, name))
+ if not 0 <= value <= 100:
+ raise ValueError(f"ligand.{name} must be between 0 and 100")
+ if self.minimum_similarity > 90:
+ raise ValueError(
+ "ligand.minimum_similarity must not exceed the fixed 90-percent "
+ "frequency cluster threshold"
+ )
SCHEMA = {
"flow": FlowConfig,
+ "source": SourceConfig,
"foldseek": FoldseekConfig,
"mmseqs": MMSeqsConfig,
- "graph": GraphConfig,
"annotation": AnnotationConfig,
+ "interface": InterfaceConfig,
"entry": EntryConfig,
"scorer": ScorerConfig,
"ligand": LigandConfig,
@@ -254,4 +308,56 @@ class LigandConfig:
SCHEMA.update(_config.SCHEMA)
-get_config = partial(_config._config, schema=SCHEMA, package_schema="data")
+_get_config = partial(_config._config, schema=SCHEMA, package_schema="data")
+
+
+def get_config(**kwargs: Any) -> DictConfig:
+ """Load and cross-validate the data-pipeline configuration."""
+ cli_args = kwargs.get("config_args")
+ if cli_args is None:
+ # Ignore host-program flags, but reject invalid ingest overrides before
+ # the shared reader's permissive CLI handling can discard them.
+ cli_args = [
+ arg
+ for arg in sys.argv[1:]
+ if "=" in arg and arg.split("=", 1)[0].split(".", 1)[0] in SCHEMA
+ ]
+ kwargs["config_args"] = cli_args
+ if cli_args:
+ _config._validate_cfg(cfg=OmegaConf.from_cli(cli_args), schema=SCHEMA)
+ cfg = _get_config(**kwargs)
+ unsupported_metrics = sorted(
+ set(cfg.flow.cluster_metrics).difference(DEFAULT_CLUSTER_METRICS)
+ )
+ if unsupported_metrics:
+ raise ValueError(
+ "unsupported release clustering metrics: "
+ f"{unsupported_metrics}; use sucos_shape_pocket_qcov instead of "
+ "raw shape, color, or SuCOS"
+ )
+ required_thresholds = [90.0]
+ if set(cfg.flow.cluster_metrics).intersection(CHEMICAL_CLUSTER_METRICS):
+ required_thresholds.extend(
+ float(value) for value in cfg.flow.cluster_thresholds
+ )
+ lowest_required_threshold = min(required_thresholds)
+ if cfg.ligand.minimum_similarity > lowest_required_threshold:
+ raise ValueError(
+ "ligand.minimum_similarity must not exceed the lowest requested "
+ "fingerprint (ECFP4/MHFP6) clustering threshold "
+ f"({lowest_required_threshold:g})"
+ )
+ derived_metrics = set(cfg.flow.cluster_metrics).difference(CHEMICAL_CLUSTER_METRICS)
+ lowest_cluster_threshold = min(
+ float(value) for value in cfg.flow.cluster_thresholds
+ )
+ if (
+ derived_metrics
+ and float(cfg.scorer.minimum_threshold) * 100 > lowest_cluster_threshold
+ ):
+ raise ValueError(
+ "scorer.minimum_threshold must not exceed the lowest requested "
+ "derived-score clustering threshold "
+ f"({lowest_cluster_threshold:g})"
+ )
+ return cfg
diff --git a/src/plinder/data/pipeline/ingest.py b/src/plinder/data/pipeline/ingest.py
new file mode 100644
index 000000000..f996f097e
--- /dev/null
+++ b/src/plinder/data/pipeline/ingest.py
@@ -0,0 +1,1369 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Discover, ingest, and resume PDB entry batches."""
+
+from __future__ import annotations
+
+import argparse
+import heapq
+import json
+import math
+import os
+import re
+import resource
+import shutil
+import time
+import traceback
+from collections import Counter
+from concurrent.futures import ThreadPoolExecutor
+from dataclasses import asdict, dataclass
+from pathlib import Path
+from statistics import median
+from typing import Any, Callable, Collection, Mapping, TypeVar
+
+import pandas as pd
+import pyarrow.parquet as pq
+
+from plinder.core.utils.files import write_json_atomic
+
+PDB_NEXTGEN_ROOT_ENV = "PLINDER_PDB_NEXTGEN_ROOT"
+VALIDATION_ROOT_ENV = "PLINDER_VALIDATION_ROOT"
+REQUIRED_REFERENCE_FILES = (
+ Path("dbs/cofactors/cofactors.json"),
+ Path("dbs/affinity/candidates.parquet"),
+ Path("dbs/affinity/measurements.parquet"),
+)
+INGEST_MODES = ("all", "ligands", "interfaces")
+CHAIN_MODIFICATION_COLUMNS = {"chain_sequence_noncanonical", "chain_modified_residues"}
+ENTRY_METADATA_COLUMNS = {
+ "entry_pdb_id",
+ "entry_pH_min",
+ "entry_pH_max",
+ "entry_has_ligand_of_interest",
+}
+LIGAND_ANNOTATION_COLUMNS = {
+ "ligand_contact_area",
+ "ligand_contact_area_chains",
+ "ligand_contact_area_values",
+ "ligand_unresolved_atoms",
+ "ligand_pocket_unresolved_atoms",
+ "ligand_is_subject_of_investigation",
+}
+
+T = TypeVar("T")
+
+
+def resolve_source_roots(
+ *,
+ data_dir: Path,
+ cif_root: str | Path | None = None,
+ validation_root: str | Path | None = None,
+) -> tuple[Path, Path]:
+ """Resolve source roots from config, environment, or local defaults.
+
+ Explicit arguments take precedence over environment variables. Relative
+ configured paths are interpreted relative to the Plinder data directory so
+ the same configuration works in local runs and Slurm jobs.
+ """
+
+ def resolve(
+ configured: str | Path | None,
+ environment_variable: str,
+ fallback: str,
+ ) -> Path:
+ value = configured or os.environ.get(environment_variable)
+ path = Path(value).expanduser() if value else Path(fallback)
+ if not path.is_absolute():
+ path = data_dir / path
+ return path.resolve()
+
+ return (
+ resolve(cif_root, PDB_NEXTGEN_ROOT_ENV, "ingest"),
+ resolve(validation_root, VALIDATION_ROOT_ENV, "reports"),
+ )
+
+
+def normalize_pdb_id(value: str) -> str:
+ """Validate and normalize one four-character PDB ID."""
+ pdb_id = value.strip().lower()
+ if re.fullmatch(r"[0-9][a-z0-9]{3}", pdb_id) is None:
+ raise ValueError(f"invalid four-character PDB ID: {value!r}")
+ return pdb_id
+
+
+def normalize_ingest_mode(value: str) -> str:
+ """Validate one explicit entry-ingest mode."""
+ mode = str(value).strip().lower()
+ if mode not in INGEST_MODES:
+ raise ValueError(f"ingest mode must be one of {INGEST_MODES}: {value!r}")
+ return mode
+
+
+def entry_metrics_path(output_root: Path, pdb_id: str) -> Path:
+ """Return the completion marker for one ligand or combined entry ingest."""
+ pdb_id = normalize_pdb_id(pdb_id)
+ filename = f"ingest-one-{pdb_id}.json"
+ return output_root / "metrics" / pdb_id[1:3] / filename
+
+
+def interface_metrics_path(output_root: Path, pdb_id: str) -> Path:
+ """Return the independent completion marker for interface-only ingest."""
+ pdb_id = normalize_pdb_id(pdb_id)
+ return output_root / "metrics" / pdb_id[1:3] / f"ingest-interfaces-{pdb_id}.json"
+
+
+def resolve_entry_paths(
+ pdb_id: str,
+ *,
+ cif_root: Path,
+ validation_root: Path,
+) -> tuple[Path, Path]:
+ """Resolve managed NextGen and validation inputs without staging them."""
+ pdb_id = normalize_pdb_id(pdb_id)
+ code = pdb_id[1:3]
+ cif_file = (
+ cif_root / code / f"pdb_0000{pdb_id}" / f"pdb_0000{pdb_id}_xyz-enrich.cif.gz"
+ )
+ validation_file = validation_root / code / pdb_id / f"{pdb_id}_validation.xml.gz"
+ return cif_file, validation_file
+
+
+def check_reference_data(output_root: Path) -> None:
+ """Require global annotation inputs prepared once for all array tasks."""
+ missing = [
+ output_root / relative
+ for relative in REQUIRED_REFERENCE_FILES
+ if not (output_root / relative).is_file()
+ or (output_root / relative).stat().st_size == 0
+ ]
+ if missing:
+ formatted = "\n".join(f" - {path}" for path in missing)
+ raise FileNotFoundError(
+ "missing shared ingest reference data; run the online "
+ f"reference-data preparation command first:\n{formatted}"
+ )
+
+
+def _usage() -> dict[str, float]:
+ usage = resource.getrusage(resource.RUSAGE_SELF)
+ return {
+ "user_cpu_seconds": float(usage.ru_utime),
+ "system_cpu_seconds": float(usage.ru_stime),
+ # Linux reports ru_maxrss in KiB.
+ "peak_rss_mb": float(usage.ru_maxrss) / 1024.0,
+ }
+
+
+def _run_timed(
+ stage: str,
+ func: Callable[[], T],
+ timings: list[dict[str, float | str]],
+) -> T:
+ before = _usage()
+ started = time.perf_counter()
+ status = "complete"
+ error = None
+ try:
+ return func()
+ except BaseException as exc:
+ status = "failed"
+ error = repr(exc)
+ raise
+ finally:
+ after = _usage()
+ timing: dict[str, float | str] = {
+ "stage": stage,
+ "status": status,
+ "wall_seconds": time.perf_counter() - started,
+ "user_cpu_seconds": (
+ after["user_cpu_seconds"] - before["user_cpu_seconds"]
+ ),
+ "system_cpu_seconds": (
+ after["system_cpu_seconds"] - before["system_cpu_seconds"]
+ ),
+ "peak_rss_mb": after["peak_rss_mb"],
+ }
+ if error is not None:
+ timing["error"] = error
+ timings.append(timing)
+
+
+def _entry_outputs_complete(
+ *,
+ metrics_path: Path,
+ entry_parquet: Path,
+ entry_directory: Path,
+ ligand_parquet: Path,
+ expected_interface_min_residues: int | None = None,
+ expected_annotate_prodigy: bool | None = None,
+ expected_ingest_mode: str | None = None,
+) -> bool:
+ """Return whether a prior per-entry run completed atomically."""
+ if not metrics_path.is_file():
+ return False
+ try:
+ metrics = json.loads(metrics_path.read_text())
+ except (OSError, json.JSONDecodeError):
+ return False
+ if metrics.get("status") != "complete":
+ return False
+ ingest_mode = metrics.get("mode")
+ if ingest_mode not in INGEST_MODES:
+ return False
+ if expected_ingest_mode is not None and (ingest_mode != expected_ingest_mode):
+ return False
+ if (
+ expected_annotate_prodigy is not None
+ and bool(metrics.get("interface_annotate_prodigy")) != expected_annotate_prodigy
+ ):
+ return False
+ counts = metrics.get("counts", {})
+ annotation_rows = int(counts.get("annotation_rows", 0))
+ sidecars = {
+ "entry_chains": entry_directory / "entry_chains.parquet",
+ "entry_biounit_chains": entry_directory / "entry_biounit_chains.parquet",
+ "entry_metadata": entry_directory / "entry_metadata.parquet",
+ "interfaces": entry_directory / "interfaces.parquet",
+ "entry_source": entry_directory / "entry_source.parquet",
+ }
+ if not all(path.is_file() for path in sidecars.values()):
+ return False
+ try:
+ from plinder.data.annotations.interface_utils import (
+ INTERFACE_ANNOTATION_SCHEMA,
+ min_interface_residues_from_schema,
+ )
+
+ interface_min_residues = min_interface_residues_from_schema(
+ pq.read_schema(sidecars["interfaces"])
+ )
+ except (OSError, TypeError, ValueError):
+ return False
+ if (
+ expected_interface_min_residues is not None
+ and interface_min_residues != expected_interface_min_residues
+ ):
+ return False
+ required_columns = {
+ sidecars["entry_chains"]: {
+ "chain_receptor_type",
+ "chain_is_ligand_like",
+ }
+ | CHAIN_MODIFICATION_COLUMNS,
+ sidecars["entry_biounit_chains"]: _required_biounit_contact_columns(ingest_mode)
+ | {
+ "entry_pdb_id",
+ "biounit_id",
+ "chain_instance",
+ "chain_asym_id",
+ "chain_role",
+ },
+ sidecars["entry_metadata"]: ENTRY_METADATA_COLUMNS,
+ sidecars["interfaces"]: set(INTERFACE_ANNOTATION_SCHEMA.names),
+ sidecars["entry_source"]: {"entry_pdb_id"},
+ }
+ if annotation_rows:
+ if not entry_parquet.is_file() or not ligand_parquet.is_file():
+ return False
+ required_columns.update(
+ {
+ entry_parquet: {"system_receptor_type"} | LIGAND_ANNOTATION_COLUMNS,
+ ligand_parquet: {"ligand_id", "ligand_is_shape_comparable"},
+ }
+ )
+ try:
+ schemas_are_complete = all(
+ columns.issubset(pq.read_schema(path).names)
+ for path, columns in required_columns.items()
+ )
+ return schemas_are_complete and _biounit_contacts_are_valid(
+ sidecars["entry_biounit_chains"],
+ _required_biounit_contact_columns(ingest_mode),
+ )
+ except Exception:
+ return False
+
+
+BIOUNIT_LIGAND_CONTACT_COLUMNS = {
+ "chain_num_contacting_ions",
+ "chain_num_contacting_artifacts",
+ "chain_num_contacting_other_ligands",
+}
+BIOUNIT_PROTEIN_CONTACT_COLUMNS = {"chain_num_contacting_proteins"}
+BIOUNIT_CONTACT_COLUMNS = (
+ BIOUNIT_LIGAND_CONTACT_COLUMNS | BIOUNIT_PROTEIN_CONTACT_COLUMNS
+)
+
+
+def _required_biounit_contact_columns(ingest_mode: str) -> set[str]:
+ if ingest_mode == "ligands":
+ return BIOUNIT_LIGAND_CONTACT_COLUMNS
+ if ingest_mode == "interfaces":
+ return BIOUNIT_PROTEIN_CONTACT_COLUMNS
+ return BIOUNIT_CONTACT_COLUMNS
+
+
+def _biounit_contacts_are_valid(path: Path, columns: set[str]) -> bool:
+ if not path.is_file():
+ return False
+ try:
+ if not columns.issubset(pq.read_schema(path).names):
+ return False
+ table = pq.read_table(path, columns=sorted(columns))
+ return all(
+ value is not None and value >= 0
+ for column in table.column_names
+ for value in table[column].to_pylist()
+ )
+ except (OSError, TypeError, ValueError):
+ return False
+
+
+def _shared_annotations_are_present(entry_directory: Path) -> bool:
+ try:
+ return CHAIN_MODIFICATION_COLUMNS.issubset(
+ pq.read_schema(entry_directory / "entry_chains.parquet").names
+ ) and ENTRY_METADATA_COLUMNS.issubset(
+ pq.read_schema(entry_directory / "entry_metadata.parquet").names
+ )
+ except (OSError, TypeError, ValueError):
+ return False
+
+
+def _get_annotation_class() -> Any:
+ """Import the data-generation stack only for actual entry annotation."""
+ from plinder.data.get_system_annotations import GetPlinderAnnotation
+
+ return GetPlinderAnnotation
+
+
+def _save_ligand_batch(**kwargs: Any) -> None:
+ """Import ligand annotation code only for actual entry annotation."""
+ from plinder.data.pipeline.utils import save_ligand_batch
+
+ save_ligand_batch(**kwargs)
+
+
+def completed_entry_metrics(
+ output_root: Path,
+ pdb_id: str,
+ *,
+ expected_interface_min_residues: int | None = None,
+ expected_annotate_prodigy: bool | None = None,
+ expected_ingest_mode: str | None = None,
+) -> Path | None:
+ """Return the metrics file when one entry has a complete output set."""
+ pdb_id = normalize_pdb_id(pdb_id)
+ metrics_path = entry_metrics_path(output_root, pdb_id)
+ if not metrics_path.is_file():
+ return None
+ try:
+ metrics = json.loads(metrics_path.read_text())
+ except (OSError, json.JSONDecodeError):
+ return None
+ ingest_mode = metrics.get("mode")
+ if ingest_mode not in INGEST_MODES:
+ return None
+ if expected_ingest_mode is not None and ingest_mode != expected_ingest_mode:
+ return None
+ entry_directory = output_root / "raw_entries" / pdb_id[1:3] / pdb_id
+ if metrics.get("status") == "skipped_no_ligands":
+ if (
+ ingest_mode == "ligands"
+ and "entry_chain_rows" in metrics.get("counts", {})
+ and _shared_annotations_are_present(entry_directory)
+ and _biounit_contacts_are_valid(
+ entry_directory / "entry_biounit_chains.parquet",
+ BIOUNIT_LIGAND_CONTACT_COLUMNS,
+ )
+ ):
+ return metrics_path
+ return None
+ entry_parquet = output_root / "raw_entries" / pdb_id[1:3] / f"{pdb_id}.parquet"
+ ligand_parquet = output_root / "ligands" / f"{pdb_id}.parquet"
+ if _entry_outputs_complete(
+ metrics_path=metrics_path,
+ entry_parquet=entry_parquet,
+ entry_directory=entry_directory,
+ ligand_parquet=ligand_parquet,
+ expected_interface_min_residues=expected_interface_min_residues,
+ expected_annotate_prodigy=expected_annotate_prodigy,
+ expected_ingest_mode=expected_ingest_mode,
+ ):
+ return metrics_path
+ return None
+
+
+def completed_interface_metrics(
+ output_root: Path,
+ pdb_id: str,
+ *,
+ expected_interface_min_residues: int | None = None,
+ expected_annotate_prodigy: bool | None = None,
+) -> Path | None:
+ """Return the marker when interface-only outputs are complete and current."""
+ pdb_id = normalize_pdb_id(pdb_id)
+ metrics_path = interface_metrics_path(output_root, pdb_id)
+ if not metrics_path.is_file():
+ return None
+ try:
+ metrics = json.loads(metrics_path.read_text())
+ stored_cutoff = int(metrics["interface_min_residues"])
+ except (KeyError, OSError, TypeError, ValueError, json.JSONDecodeError):
+ return None
+ if (
+ expected_interface_min_residues is not None
+ and stored_cutoff != expected_interface_min_residues
+ ):
+ return None
+ if (
+ expected_annotate_prodigy is not None
+ and bool(metrics.get("interface_annotate_prodigy")) != expected_annotate_prodigy
+ ):
+ return None
+ status = metrics.get("status")
+ if status == "skipped_no_interfaces":
+ entry_directory = output_root / "raw_entries" / pdb_id[1:3] / pdb_id
+ return None if entry_directory.exists() else metrics_path
+ if status != "complete":
+ return None
+ interface_path = (
+ output_root / "raw_entries" / pdb_id[1:3] / pdb_id / "interfaces.parquet"
+ )
+ if not interface_path.is_file():
+ return None
+ if not _shared_annotations_are_present(interface_path.parent):
+ return None
+ if not _biounit_contacts_are_valid(
+ interface_path.parent / "entry_biounit_chains.parquet",
+ BIOUNIT_PROTEIN_CONTACT_COLUMNS,
+ ):
+ return None
+ try:
+ from plinder.data.annotations.interface_utils import (
+ INTERFACE_ANNOTATION_SCHEMA,
+ min_interface_residues_from_schema,
+ )
+
+ schema = pq.read_schema(interface_path)
+ if min_interface_residues_from_schema(schema) != stored_cutoff:
+ return None
+ if not set(INTERFACE_ANNOTATION_SCHEMA.names).issubset(schema.names):
+ return None
+ if pq.ParquetFile(interface_path).metadata.num_rows != int(
+ metrics.get("counts", {}).get("interface_rows", -1)
+ ):
+ return None
+ except (OSError, TypeError, ValueError):
+ return None
+ return metrics_path
+
+
+def _ingest_interfaces(
+ *,
+ pdb_id: str,
+ output_root: Path,
+ cif_file: Path,
+ validation_file: Path,
+ raw_entry_root: Path,
+ entry_parquet: Path,
+ entry_directory: Path,
+ ligand_parquet: Path,
+ force: bool,
+ annotation_cfg: Mapping[str, Any] | None,
+ entry_cfg: Mapping[str, Any] | None,
+ interface_cfg: Mapping[str, Any] | None,
+) -> Path:
+ """Replace only interface-derived outputs while preserving ligand assets."""
+ from plinder.data.annotations.interface_utils import (
+ DEFAULT_MIN_INTERFACE_RESIDUES,
+ )
+
+ interface_options = dict(interface_cfg or {})
+ expected_cutoff = int(
+ interface_options.get("min_interface_residues", DEFAULT_MIN_INTERFACE_RESIDUES)
+ )
+ annotate_prodigy = bool(interface_options.get("annotate_prodigy", True))
+ completed = completed_interface_metrics(
+ output_root,
+ pdb_id,
+ expected_interface_min_residues=expected_cutoff,
+ expected_annotate_prodigy=annotate_prodigy,
+ )
+ if completed is not None and not force:
+ raise FileExistsError(
+ f"interface output already exists for {pdb_id}; pass --force to replace it"
+ )
+ if entry_parquet.is_file() != ligand_parquet.is_file():
+ raise FileNotFoundError(
+ f"cannot preserve incomplete ligand outputs for {pdb_id}: "
+ f"annotation={entry_parquet.is_file()}, ligand={ligand_parquet.is_file()}"
+ )
+ has_ligands = entry_parquet.is_file()
+ has_ligand_sidecars = (
+ completed_entry_metrics(
+ output_root,
+ pdb_id,
+ expected_ingest_mode="ligands",
+ )
+ is not None
+ )
+ preserve_ligand_outputs = has_ligands or has_ligand_sidecars
+ if not preserve_ligand_outputs and entry_directory.exists():
+ # This directory is owned solely by an earlier interface-only attempt,
+ # so a partial write can be rebuilt without touching ligand assets.
+ shutil.rmtree(entry_directory)
+
+ metrics_path = interface_metrics_path(output_root, pdb_id)
+ timings: list[dict[str, float | str]] = []
+ summary: dict[str, Any] = {
+ "pdb_id": pdb_id,
+ "status": "running",
+ "mode": "interfaces",
+ "interface_min_residues": expected_cutoff,
+ "interface_annotate_prodigy": annotate_prodigy,
+ "inputs": {
+ "mmcif": str(cif_file),
+ "validation_xml": str(validation_file),
+ "validation_xml_exists": validation_file.is_file(),
+ },
+ "outputs": {
+ "entry_parquet": str(entry_parquet) if entry_parquet.is_file() else None,
+ "entry_directory": str(entry_directory),
+ "interface_parquet": str(entry_directory / "interfaces.parquet"),
+ "ligand_parquet": str(ligand_parquet) if ligand_parquet.is_file() else None,
+ },
+ "timings": timings,
+ }
+ total_started = time.perf_counter()
+ try:
+ raw_entry_root.mkdir(parents=True, exist_ok=True)
+
+ def annotate_interfaces() -> Any:
+ annotation_options = dict(annotation_cfg or {})
+ entry_options = dict(entry_cfg or {})
+ entry_options.pop("save_folder", None)
+ if entry_options:
+ annotation_options["entry_cfg"] = entry_options
+ annotation_options["interface_cfg"] = interface_options
+ return _get_annotation_class()(
+ cif_file,
+ validation_file,
+ save_folder=raw_entry_root,
+ **annotation_options,
+ ).annotate_interfaces()
+
+ interface_table = _run_timed(
+ "annotate_interfaces", annotate_interfaces, timings
+ )
+ interface_rows = int(interface_table.num_rows)
+ if not interface_rows and not preserve_ligand_outputs:
+ shutil.rmtree(entry_directory, ignore_errors=True)
+ summary["status"] = "skipped_no_interfaces"
+ summary["outputs"]["entry_directory"] = None
+ summary["outputs"]["interface_parquet"] = None
+ else:
+ summary["status"] = "complete"
+ summary["counts"] = {
+ "interface_rows": interface_rows,
+ "prodigy_annotated_rows": int(
+ interface_table.column("prodigy_is_annotated").to_numpy().sum()
+ ),
+ "preserved_ligand_annotation_rows": (
+ pq.ParquetFile(entry_parquet).metadata.num_rows if has_ligands else 0
+ ),
+ }
+ except BaseException as exc:
+ summary["status"] = "failed"
+ summary["error"] = repr(exc)
+ summary["traceback"] = traceback.format_exc()
+ raise
+ finally:
+ summary["total_wall_seconds"] = time.perf_counter() - total_started
+ summary["final_resource_usage"] = _usage()
+ write_json_atomic(metrics_path, summary)
+ return metrics_path
+
+
+def _clear_entry_outputs(
+ *,
+ entry_parquet: Path,
+ entry_directory: Path,
+ ligand_parquet: Path,
+) -> None:
+ """Remove one incomplete or explicitly replaced per-entry output set."""
+ entry_parquet.unlink(missing_ok=True)
+ ligand_parquet.unlink(missing_ok=True)
+ shutil.rmtree(entry_directory, ignore_errors=True)
+
+
+def _clear_ligand_outputs(
+ *,
+ entry_parquet: Path,
+ entry_directory: Path,
+ ligand_parquet: Path,
+) -> None:
+ """Remove ligand-derived outputs without touching interface sidecars."""
+ entry_parquet.unlink(missing_ok=True)
+ ligand_parquet.unlink(missing_ok=True)
+ shutil.rmtree(entry_directory / "ligand_files", ignore_errors=True)
+
+
+def ingest_one_pdb(
+ *,
+ pdb_id: str,
+ output_root: Path,
+ cif_root: Path,
+ validation_root: Path,
+ force: bool = False,
+ check_references: bool = True,
+ annotation_cfg: Mapping[str, Any] | None = None,
+ entry_cfg: Mapping[str, Any] | None = None,
+ interface_cfg: Mapping[str, Any] | None = None,
+ mode: str = "all",
+) -> Path:
+ """Ingest ligands, protein interfaces, or both for one PDB entry."""
+ pdb_id = normalize_pdb_id(pdb_id)
+ mode = normalize_ingest_mode(mode)
+ include_interfaces = mode == "all"
+ output_root = output_root.resolve()
+ cif_file, validation_file = resolve_entry_paths(
+ pdb_id,
+ cif_root=cif_root,
+ validation_root=validation_root,
+ )
+ if not cif_file.is_file():
+ raise FileNotFoundError(f"missing NextGen mmCIF: {cif_file}")
+ if check_references and mode != "interfaces":
+ check_reference_data(output_root)
+
+ code = pdb_id[1:3]
+ raw_entry_root = output_root / "raw_entries" / code
+ entry_parquet = raw_entry_root / f"{pdb_id}.parquet"
+ entry_directory = raw_entry_root / pdb_id
+ ligand_parquet = output_root / "ligands" / f"{pdb_id}.parquet"
+ metrics_path = entry_metrics_path(output_root, pdb_id)
+ if mode == "interfaces":
+ return _ingest_interfaces(
+ pdb_id=pdb_id,
+ output_root=output_root,
+ cif_file=cif_file,
+ validation_file=validation_file,
+ raw_entry_root=raw_entry_root,
+ entry_parquet=entry_parquet,
+ entry_directory=entry_directory,
+ ligand_parquet=ligand_parquet,
+ force=force,
+ annotation_cfg=annotation_cfg,
+ entry_cfg=entry_cfg,
+ interface_cfg=interface_cfg,
+ )
+ from plinder.data.annotations.aggregate_annotations import QualityCriteria
+ from plinder.data.annotations.get_ligand_validation import (
+ ResidueValidationThresholds,
+ )
+ from plinder.data.annotations.interface_utils import (
+ DEFAULT_MIN_INTERFACE_RESIDUES,
+ )
+
+ expected_interface_min_residues = int(
+ (interface_cfg or {}).get(
+ "min_interface_residues", DEFAULT_MIN_INTERFACE_RESIDUES
+ )
+ )
+ expected_annotate_prodigy = include_interfaces and bool(
+ (interface_cfg or {}).get("annotate_prodigy", True)
+ )
+ complete = _entry_outputs_complete(
+ metrics_path=metrics_path,
+ entry_parquet=entry_parquet,
+ entry_directory=entry_directory,
+ ligand_parquet=ligand_parquet,
+ expected_interface_min_residues=(
+ expected_interface_min_residues if include_interfaces else None
+ ),
+ expected_annotate_prodigy=(
+ expected_annotate_prodigy if include_interfaces else None
+ ),
+ expected_ingest_mode=mode,
+ )
+ if complete and not force:
+ raise FileExistsError(
+ f"output already exists: {entry_parquet}; pass --force to replace it"
+ )
+ has_partial_outputs = entry_parquet.exists() or ligand_parquet.exists()
+ if mode == "all":
+ has_partial_outputs = has_partial_outputs or entry_directory.exists()
+ else:
+ has_partial_outputs = (
+ has_partial_outputs or (entry_directory / "ligand_files").exists()
+ )
+ if force or has_partial_outputs:
+ if has_partial_outputs and not force:
+ print(f"clearing incomplete outputs before retrying {pdb_id}")
+ clear = _clear_entry_outputs if mode == "all" else _clear_ligand_outputs
+ clear(
+ entry_parquet=entry_parquet,
+ entry_directory=entry_directory,
+ ligand_parquet=ligand_parquet,
+ )
+
+ timings: list[dict[str, float | str]] = []
+ summary: dict[str, Any] = {
+ "pdb_id": pdb_id,
+ "status": "running",
+ "mode": mode,
+ "interface_min_residues": expected_interface_min_residues,
+ "interface_annotate_prodigy": expected_annotate_prodigy,
+ # Standard ligand ingest uses these defaults. Record the settings even
+ # when a validation report is unavailable; results track missing data.
+ "validation_settings": {
+ "residue_thresholds": ResidueValidationThresholds().model_dump(),
+ "quality_criteria": asdict(QualityCriteria()),
+ },
+ "inputs": {
+ "mmcif": str(cif_file),
+ "validation_xml": str(validation_file),
+ "validation_xml_exists": validation_file.is_file(),
+ },
+ "outputs": {
+ "entry_parquet": str(entry_parquet),
+ "entry_directory": str(entry_directory),
+ "ligand_parquet": str(ligand_parquet),
+ },
+ "timings": timings,
+ }
+ if annotation_cfg or entry_cfg or interface_cfg:
+ summary["configuration"] = {
+ "annotation": dict(annotation_cfg or {}),
+ "entry": {
+ key: value
+ for key, value in dict(entry_cfg or {}).items()
+ if key != "save_folder"
+ },
+ "interface": dict(interface_cfg or {}),
+ }
+ total_started = time.perf_counter()
+ try:
+ raw_entry_root.mkdir(parents=True, exist_ok=True)
+ ligand_parquet.parent.mkdir(parents=True, exist_ok=True)
+
+ def annotate() -> pd.DataFrame:
+ annotation_options = dict(annotation_cfg or {})
+ entry_options = dict(entry_cfg or {})
+ entry_options.pop("save_folder", None)
+ entry_options.pop("data_dir", None)
+ if entry_options:
+ annotation_options["entry_cfg"] = entry_options
+ if interface_cfg:
+ annotation_options["interface_cfg"] = dict(interface_cfg)
+ annotator = _get_annotation_class()(
+ cif_file,
+ validation_file,
+ save_folder=raw_entry_root,
+ data_dir=output_root,
+ **annotation_options,
+ )
+ annotation = (
+ annotator.annotate()
+ if include_interfaces
+ else annotator.annotate(include_interfaces=False)
+ )
+ return annotation if annotation is not None else pd.DataFrame()
+
+ annotation = _run_timed("annotate_entry", annotate, timings)
+ interface_path = entry_directory / "interfaces.parquet"
+ interface_rows = (
+ pq.ParquetFile(interface_path).metadata.num_rows
+ if interface_path.is_file()
+ else 0
+ )
+ if annotation.empty and mode == "ligands":
+ entry_parquet.unlink(missing_ok=True)
+ ligand_parquet.unlink(missing_ok=True)
+ shutil.rmtree(entry_directory / "ligand_files", ignore_errors=True)
+ summary["outputs"]["entry_parquet"] = None
+ summary["outputs"]["ligand_parquet"] = None
+ if not entry_directory.exists():
+ summary["outputs"]["entry_directory"] = None
+ summary["counts"] = {
+ "annotation_rows": 0,
+ "interface_rows": interface_rows,
+ "interface_rows_generated": 0,
+ "entry_chain_rows": (
+ pq.ParquetFile(
+ entry_directory / "entry_chains.parquet"
+ ).metadata.num_rows
+ if (entry_directory / "entry_chains.parquet").is_file()
+ else 0
+ ),
+ "systems": 0,
+ "ligand_ids": 0,
+ "canonical_ligand_sdfs": 0,
+ }
+ summary["status"] = "skipped_no_ligands"
+ elif annotation.empty and interface_rows == 0:
+ entry_parquet.unlink(missing_ok=True)
+ ligand_parquet.unlink(missing_ok=True)
+ shutil.rmtree(entry_directory / "ligand_files", ignore_errors=True)
+ summary["outputs"]["entry_parquet"] = None
+ summary["outputs"]["ligand_parquet"] = None
+ summary["counts"] = {
+ "annotation_rows": 0,
+ "interface_rows": 0,
+ "systems": 0,
+ "ligand_ids": 0,
+ "canonical_ligand_sdfs": 0,
+ }
+ summary["status"] = "complete"
+ else:
+ if not annotation.empty:
+
+ def write_entry_parquet() -> None:
+ annotation.to_parquet(entry_parquet, index=False)
+
+ _run_timed(
+ "write_entry_parquet",
+ write_entry_parquet,
+ timings,
+ )
+
+ def write_ligand_parquet() -> None:
+ _save_ligand_batch(
+ data_dir=output_root,
+ annotation=annotation,
+ output_path=ligand_parquet,
+ )
+
+ _run_timed(
+ "write_ligand_parquet",
+ write_ligand_parquet,
+ timings,
+ )
+ else:
+ entry_parquet.unlink(missing_ok=True)
+ ligand_parquet.unlink(missing_ok=True)
+ summary["outputs"]["entry_parquet"] = None
+ summary["outputs"]["ligand_parquet"] = None
+
+ ligand_sdfs = sorted((entry_directory / "ligand_files").glob("*.sdf"))
+ summary["counts"] = {
+ "annotation_rows": len(annotation),
+ "interface_rows": interface_rows,
+ "systems": (
+ int(annotation["system_id"].nunique())
+ if not annotation.empty
+ else 0
+ ),
+ "ligand_ids": (
+ int(annotation["ligand_id"].nunique())
+ if not annotation.empty
+ else 0
+ ),
+ "canonical_ligand_sdfs": len(ligand_sdfs),
+ }
+ if mode == "ligands":
+ summary["counts"]["interface_rows_generated"] = 0
+ summary["status"] = "complete"
+ except BaseException as exc:
+ summary["status"] = "failed"
+ summary["error"] = repr(exc)
+ summary["traceback"] = traceback.format_exc()
+ raise
+ finally:
+ summary["total_wall_seconds"] = time.perf_counter() - total_started
+ summary["final_resource_usage"] = _usage()
+ write_json_atomic(metrics_path, summary)
+ return metrics_path
+
+
+@dataclass(frozen=True)
+class EntryInput:
+ pdb_id: str
+ cif_size: int
+ validation_exists: bool | None
+
+
+def discover_entries(
+ cif_root: Path,
+ validation_root: Path,
+ *,
+ check_validation: bool = True,
+ threads: int = 8,
+ two_char_codes: Collection[str] | None = None,
+ pdb_ids: Collection[str] | None = None,
+) -> list[EntryInput]:
+ """Discover unique NextGen CIFs and optionally check validation reports."""
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ directory_pattern = re.compile(r"pdb_0000([0-9a-z]{4})")
+ selected_codes = (
+ {str(code).lower() for code in two_char_codes} if two_char_codes else None
+ )
+ selected_pdb_ids = {str(pdb_id).lower() for pdb_id in pdb_ids} if pdb_ids else None
+
+ def discover_code_directory(code_directory: Path) -> list[EntryInput]:
+ discovered = []
+ with os.scandir(code_directory) as directory_entries:
+ for directory_entry in directory_entries:
+ match = directory_pattern.fullmatch(directory_entry.name)
+ if match is None or not directory_entry.is_dir(follow_symlinks=False):
+ continue
+ pdb_id = match.group(1)
+ if selected_pdb_ids is not None and pdb_id not in selected_pdb_ids:
+ continue
+ cif_path = (
+ Path(directory_entry.path) / f"pdb_0000{pdb_id}_xyz-enrich.cif.gz"
+ )
+ try:
+ cif_size = cif_path.stat().st_size
+ except FileNotFoundError:
+ continue
+ discovered.append(
+ EntryInput(
+ pdb_id=pdb_id,
+ cif_size=cif_size,
+ validation_exists=(
+ (
+ validation_root
+ / pdb_id[1:3]
+ / pdb_id
+ / f"{pdb_id}_validation.xml.gz"
+ ).is_file()
+ if check_validation
+ else None
+ ),
+ )
+ )
+ return discovered
+
+ code_directories = [
+ path
+ for path in cif_root.iterdir()
+ if path.is_dir()
+ and (selected_codes is None or path.name.lower() in selected_codes)
+ ]
+ entries: dict[str, EntryInput] = {}
+ with ThreadPoolExecutor(max_workers=threads) as executor:
+ for discovered in executor.map(discover_code_directory, code_directories):
+ for entry in discovered:
+ if entry.pdb_id in entries:
+ raise ValueError(f"duplicate NextGen CIF for PDB ID {entry.pdb_id}")
+ entries[entry.pdb_id] = entry
+ return sorted(entries.values(), key=lambda entry: entry.pdb_id)
+
+
+def balance_entries(
+ entries: list[EntryInput], *, batch_size: int
+) -> list[list[EntryInput]]:
+ """Greedily balance bytes across contiguous fixed-size manifest slices."""
+ if batch_size < 1:
+ raise ValueError("batch_size must be positive")
+ if not entries:
+ return []
+ batch_count = math.ceil(len(entries) / batch_size)
+ batches: list[list[EntryInput]] = [[] for _ in range(batch_count)]
+ remainder = len(entries) % batch_size
+ capacities = [batch_size] * batch_count
+ if remainder:
+ capacities[-1] = remainder
+ heap = [(0, 0, index) for index in range(batch_count)]
+ heapq.heapify(heap)
+ for entry in sorted(entries, key=lambda item: item.cif_size, reverse=True):
+ total_size, count, index = heapq.heappop(heap)
+ batches[index].append(entry)
+ count += 1
+ if count < capacities[index]:
+ heapq.heappush(heap, (total_size + entry.cif_size, count, index))
+ return [
+ sorted(batch, key=lambda entry: (entry.cif_size, entry.pdb_id))
+ for batch in batches
+ ]
+
+
+def _percentile(values: list[int], percentile: float) -> int:
+ """Return a linearly interpolated percentile for integer byte counts."""
+ if not values:
+ return 0
+ ordered = sorted(values)
+ position = (len(ordered) - 1) * percentile
+ lower = math.floor(position)
+ upper = math.ceil(position)
+ if lower == upper:
+ return ordered[lower]
+ weight = position - lower
+ return round(ordered[lower] * (1 - weight) + ordered[upper] * weight)
+
+
+def _write_text(path: Path, value: str) -> None:
+ path.parent.mkdir(parents=True, exist_ok=True)
+ temporary = path.with_suffix(path.suffix + ".tmp")
+ temporary.write_text(value)
+ temporary.replace(path)
+
+
+def _validation_status(value: bool | None) -> str:
+ if value is None:
+ return "unknown"
+ return str(value).lower()
+
+
+def write_manifest(
+ *,
+ entries: list[EntryInput],
+ output_path: Path,
+ batch_size: int,
+) -> dict[str, Any]:
+ """Write balanced PDB IDs plus neighboring input inventory and summary."""
+ batches = balance_entries(entries, batch_size=batch_size)
+ ordered = [entry for batch in batches for entry in batch]
+ _write_text(output_path, "".join(f"{entry.pdb_id}\n" for entry in ordered))
+ inventory_path = output_path.with_suffix(output_path.suffix + ".entries.tsv")
+ _write_text(
+ inventory_path,
+ "pdb_id\tcif_size\tvalidation_exists\n"
+ + "".join(
+ f"{entry.pdb_id}\t{entry.cif_size}\t"
+ f"{_validation_status(entry.validation_exists)}\n"
+ for entry in entries
+ ),
+ )
+ batch_bytes = [sum(entry.cif_size for entry in batch) for batch in batches]
+ cif_sizes = [entry.cif_size for entry in entries]
+ thresholds = (1_000_000, 2_000_000, 4_000_000, 8_000_000, 16_000_000)
+ validation_checked = all(entry.validation_exists is not None for entry in entries)
+ summary: dict[str, Any] = {
+ "manifest": str(output_path.resolve()),
+ "input_inventory": str(inventory_path.resolve()),
+ "batch_size": batch_size,
+ "batch_count": len(batches),
+ "entry_count": len(entries),
+ "total_cif_bytes": sum(entry.cif_size for entry in entries),
+ "maximum_batch_cif_bytes": max(batch_bytes, default=0),
+ "median_batch_cif_bytes": median(batch_bytes) if batch_bytes else 0,
+ "batch_cif_size_percentiles": {
+ name: _percentile(batch_bytes, percentile)
+ for name, percentile in (
+ ("p50", 0.5),
+ ("p90", 0.9),
+ ("p95", 0.95),
+ ("p99", 0.99),
+ ("maximum", 1.0),
+ )
+ },
+ "cif_size_percentiles": {
+ name: _percentile(cif_sizes, percentile)
+ for name, percentile in (
+ ("p50", 0.5),
+ ("p90", 0.9),
+ ("p95", 0.95),
+ ("p99", 0.99),
+ ("p99_9", 0.999),
+ ("maximum", 1.0),
+ )
+ },
+ "cif_size_threshold_counts": {
+ str(threshold): sum(size >= threshold for size in cif_sizes)
+ for threshold in thresholds
+ },
+ "largest_entries": [
+ asdict(entry)
+ for entry in sorted(
+ entries, key=lambda entry: entry.cif_size, reverse=True
+ )[:100]
+ ],
+ "validation_checked": validation_checked,
+ "missing_validation_count": (
+ sum(entry.validation_exists is False for entry in entries)
+ if validation_checked
+ else None
+ ),
+ "missing_validation_entries": (
+ [asdict(entry) for entry in entries if entry.validation_exists is False]
+ if validation_checked
+ else None
+ ),
+ }
+ summary_path = output_path.with_suffix(output_path.suffix + ".json")
+ _write_text(summary_path, json.dumps(summary, indent=2, sort_keys=True) + "\n")
+ return summary
+
+
+def load_manifest(path: Path) -> list[str]:
+ """Load unique PDB IDs from a newline-delimited manifest."""
+ pdb_ids = [
+ normalize_pdb_id(line)
+ for raw_line in path.read_text().splitlines()
+ if (line := raw_line.strip()) and not line.startswith("#")
+ ]
+ duplicates = sorted(
+ pdb_id for pdb_id, count in Counter(pdb_ids).items() if count > 1
+ )
+ if duplicates:
+ raise ValueError(f"duplicate PDB IDs in {path}: {duplicates}")
+ return pdb_ids
+
+
+def manifest_slice(
+ pdb_ids: list[str], *, batch_index: int, batch_size: int
+) -> list[str]:
+ """Select one zero-based, fixed-size manifest slice."""
+ if batch_index < 0:
+ raise ValueError("batch_index must be non-negative")
+ if batch_size < 1:
+ raise ValueError("batch_size must be positive")
+ start = batch_index * batch_size
+ return pdb_ids[start : start + batch_size]
+
+
+def ingest_pdb_batch(
+ *,
+ pdb_ids: list[str],
+ output_root: Path,
+ cif_root: Path,
+ validation_root: Path,
+ force: bool = False,
+ job_id: str = "local",
+ batch_index: int = 0,
+ annotation_cfg: Mapping[str, Any] | None = None,
+ entry_cfg: Mapping[str, Any] | None = None,
+ interface_cfg: Mapping[str, Any] | None = None,
+ mode: str = "all",
+) -> tuple[Path, bool]:
+ """Ingest PDB IDs sequentially and continue after per-entry failures."""
+ mode = normalize_ingest_mode(mode)
+ output_root = output_root.resolve()
+ batch_prefix = {
+ "all": "ingest-batch",
+ "ligands": "ligand-ingest-batch",
+ "interfaces": "interface-ingest-batch",
+ }[mode]
+ metrics_path = (
+ output_root / "metrics" / (f"{batch_prefix}-{job_id}-{batch_index:05d}.json")
+ )
+ metrics_path.parent.mkdir(parents=True, exist_ok=True)
+ payload: dict[str, Any] = {
+ "job_id": job_id,
+ "batch_index": batch_index,
+ "pdb_ids": pdb_ids,
+ "status": "running",
+ "mode": mode,
+ "entries": [],
+ }
+ started = time.perf_counter()
+ had_failures = False
+ from plinder.data.annotations.interface_utils import (
+ DEFAULT_MIN_INTERFACE_RESIDUES,
+ )
+
+ expected_interface_min_residues = int(
+ (interface_cfg or {}).get(
+ "min_interface_residues", DEFAULT_MIN_INTERFACE_RESIDUES
+ )
+ )
+ expected_annotate_prodigy = bool(
+ (interface_cfg or {}).get("annotate_prodigy", True)
+ )
+ try:
+ for pdb_id in pdb_ids:
+ entry_started = time.perf_counter()
+ completed = (
+ None
+ if force
+ else (
+ completed_interface_metrics(
+ output_root,
+ pdb_id,
+ expected_interface_min_residues=(
+ expected_interface_min_residues
+ ),
+ expected_annotate_prodigy=expected_annotate_prodigy,
+ )
+ if mode == "interfaces"
+ else completed_entry_metrics(
+ output_root,
+ pdb_id,
+ expected_interface_min_residues=(
+ expected_interface_min_residues if mode == "all" else None
+ ),
+ expected_annotate_prodigy=(
+ expected_annotate_prodigy if mode == "all" else None
+ ),
+ expected_ingest_mode=mode,
+ )
+ )
+ )
+ if completed is not None:
+ payload["entries"].append(
+ {
+ "pdb_id": pdb_id,
+ "status": "skipped_complete",
+ "metrics": str(completed),
+ "wall_seconds": time.perf_counter() - entry_started,
+ }
+ )
+ continue
+ try:
+ entry_metrics = ingest_one_pdb(
+ pdb_id=pdb_id,
+ output_root=output_root,
+ cif_root=cif_root,
+ validation_root=validation_root,
+ force=True,
+ annotation_cfg=annotation_cfg,
+ entry_cfg=entry_cfg,
+ interface_cfg=interface_cfg,
+ mode=mode,
+ )
+ entry_status = json.loads(entry_metrics.read_text()).get("status")
+ payload["entries"].append(
+ {
+ "pdb_id": pdb_id,
+ "status": entry_status,
+ "metrics": str(entry_metrics),
+ "wall_seconds": time.perf_counter() - entry_started,
+ }
+ )
+ except Exception as exc:
+ had_failures = True
+ payload["entries"].append(
+ {
+ "pdb_id": pdb_id,
+ "status": "failed",
+ "error": repr(exc),
+ "traceback": traceback.format_exc(),
+ "wall_seconds": time.perf_counter() - entry_started,
+ }
+ )
+ finally:
+ payload["total_wall_seconds"] = time.perf_counter() - started
+ write_json_atomic(metrics_path, payload)
+ payload["status"] = "completed_with_failures" if had_failures else "complete"
+ finally:
+ payload["total_wall_seconds"] = time.perf_counter() - started
+ write_json_atomic(metrics_path, payload)
+ return metrics_path, had_failures
+
+
+def _default_batch_index() -> int:
+ return int(os.environ.get("SLURM_ARRAY_TASK_ID", "0"))
+
+
+def _default_job_id() -> str:
+ return os.environ.get("SLURM_ARRAY_JOB_ID", os.environ.get("SLURM_JOB_ID", "local"))
+
+
+def build_parser() -> argparse.ArgumentParser:
+ """Build the shared manifest-generation and batch-ingest CLI."""
+ parser = argparse.ArgumentParser(description=__doc__)
+ commands = parser.add_subparsers(dest="command", required=True)
+
+ manifest_parser = commands.add_parser(
+ "manifest", help="discover source entries and write a balanced manifest"
+ )
+ manifest_parser.add_argument("cif_root", type=Path)
+ manifest_parser.add_argument("validation_root", type=Path)
+ manifest_parser.add_argument("output_path", type=Path)
+ manifest_parser.add_argument("--batch-size", type=int, default=100)
+ manifest_parser.add_argument("--threads", type=int, default=8)
+ manifest_parser.add_argument(
+ "--check-validation",
+ action="store_true",
+ help=(
+ "stat every expected validation XML; normally omit this because "
+ "each ingest task records exact availability"
+ ),
+ )
+
+ batch_parser = commands.add_parser(
+ "batch", help="ingest one fixed-size slice of a manifest"
+ )
+ batch_parser.add_argument("manifest", type=Path)
+ batch_parser.add_argument("output_root", type=Path)
+ batch_parser.add_argument("--batch-size", type=int, required=True)
+ batch_parser.add_argument("--batch-index", type=int, default=_default_batch_index())
+ batch_parser.add_argument(
+ "--cif-root",
+ type=Path,
+ default=os.environ.get(PDB_NEXTGEN_ROOT_ENV),
+ required=PDB_NEXTGEN_ROOT_ENV not in os.environ,
+ )
+ batch_parser.add_argument(
+ "--validation-root",
+ type=Path,
+ default=os.environ.get(VALIDATION_ROOT_ENV),
+ required=VALIDATION_ROOT_ENV not in os.environ,
+ )
+ batch_parser.add_argument(
+ "--interface-min-residues",
+ type=int,
+ default=os.environ.get("PLINDER_INTERFACE_MIN_RESIDUES"),
+ help=(
+ "minimum resolved contact residues required on each interface side; "
+ "defaults to interface.min_interface_residues"
+ ),
+ )
+ batch_parser.add_argument("--force", action="store_true")
+ batch_parser.add_argument(
+ "--mode",
+ choices=INGEST_MODES,
+ default="all",
+ help=(
+ "ingest ligands and interfaces (all), only ligands, or only "
+ "interfaces while preserving ligand assets"
+ ),
+ )
+ return parser
+
+
+def main() -> None:
+ """Run manifest discovery or one resumable ingest batch."""
+ args = build_parser().parse_args()
+ if args.command == "manifest":
+ entries = discover_entries(
+ args.cif_root,
+ args.validation_root,
+ check_validation=args.check_validation,
+ threads=args.threads,
+ )
+ if not entries:
+ raise FileNotFoundError(
+ f"no NextGen entry CIFs found under {args.cif_root}"
+ )
+ summary = write_manifest(
+ entries=entries,
+ output_path=args.output_path,
+ batch_size=args.batch_size,
+ )
+ print(json.dumps(summary, indent=2, sort_keys=True))
+ return
+
+ pdb_ids = manifest_slice(
+ load_manifest(args.manifest),
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ if args.interface_min_residues is not None and args.interface_min_residues < 1:
+ raise ValueError("interface minimum residues must be positive")
+ metrics_path, had_failures = ingest_pdb_batch(
+ pdb_ids=pdb_ids,
+ output_root=args.output_root,
+ cif_root=args.cif_root,
+ validation_root=args.validation_root,
+ force=args.force,
+ job_id=_default_job_id(),
+ batch_index=args.batch_index,
+ interface_cfg=(
+ {"min_interface_residues": args.interface_min_residues}
+ if args.interface_min_residues is not None
+ else None
+ ),
+ mode=args.mode,
+ )
+ print(metrics_path.read_text(), end="")
+ if had_failures:
+ raise SystemExit(1)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/plinder/data/pipeline/io.py b/src/plinder/data/pipeline/io.py
index 0b5fec452..3479bf197 100644
--- a/src/plinder/data/pipeline/io.py
+++ b/src/plinder/data/pipeline/io.py
@@ -6,11 +6,11 @@
pre-determined location before fetching it from
the network.
"""
-import gzip
+
import json
import os
-import shutil
from concurrent.futures import ALL_COMPLETED, ThreadPoolExecutor, wait
+from datetime import date
from pathlib import Path
from subprocess import check_output
from typing import Any, Literal, Optional, TypeVar
@@ -21,14 +21,17 @@
from plinder.core.utils.io import download_alphafold_cif_file, retry
from plinder.core.utils.log import setup_logger
+from plinder.data.annotations.affinity import candidate_map
from plinder.data.pipeline import transform
+# RCSB retired its NextGen rsync service in June 2026; PDBj remains an
+# official wwPDB rsync mirror for this archive.
CIF_PATH = "rsync-nextgen.pdbj.org::ftp_nextgen/data/entries/divided"
CIF_GLOB = "*-enrich.cif.gz"
-CIF_PORT = "873"
VAL_PATH = "rsync.rcsb.org::ftp/validation_reports"
VAL_GLOB = "*_validation.xml.gz"
-RCSB_PORT = "33444"
+CIF_PORT = "873"
+VAL_PORT = "33444"
KINDS = ["cif", "val"]
KIND_TYPES = Literal["cif", "val"]
LOG = setup_logger(__name__)
@@ -74,208 +77,126 @@ def download_cofactors(
return obj
+# BindingDB publishes only month-stamped dumps (BindingDB_All_YYYYMM_tsv.zip) with no
+# stable "latest" alias, and prunes older months, so the newest is found by probing back
+# from the current month (see latest_bindingdb_tsv_url).
+BINDINGDB_DOWNLOADS = "https://www.bindingdb.org/rwd/bind/downloads"
+
+
+@retry
+def latest_bindingdb_tsv_url(max_lookback_months: int = 12) -> str:
+ """Resolve the URL of the newest ``BindingDB_All_*_tsv.zip`` dump.
+
+ BindingDB ships only month-stamped dumps with no stable "latest" alias and prunes
+ older months, so walk back month by month from the current one and return the first
+ URL that exists.
+ """
+ today = date.today()
+ year, month = today.year, today.month
+ for _ in range(max_lookback_months):
+ url = f"{BINDINGDB_DOWNLOADS}/BindingDB_All_{year}{month:02d}_tsv.zip"
+ if requests.head(url, allow_redirects=True).status_code == 200:
+ return url
+ year, month = (year, month - 1) if month > 1 else (year - 1, 12)
+ raise ValueError(
+ f"no BindingDB_All_*_tsv.zip found in the {max_lookback_months} months "
+ f"up to {today:%Y%m}"
+ )
+
+
@retry
def download_affinity_data(
*,
data_dir: Path,
- bindingdb_url: str = "https://www.bindingdb.org/bind/downloads/BindingDB_All_202401_tsv.zip",
+ bindingdb_url: str | None = None,
force_update: bool = False,
-) -> Any:
+) -> dict[str, list[dict[str, Any]]]:
"""
- Download binding affinity data.
+ Prepare and read the BindingDB records and strict per-target candidates.
Parameters
----------
data_dir : Path
the root plinder dir
- bindinddb_url : str
- bindingdb : url
+ bindingdb_url : str | None, default=None
+ direct URL to a ``BindingDB_All_*_tsv.zip`` dump; if None, the latest
+ published month is resolved from BindingDB's download page. Pass an
+ explicit URL to pin a specific release for a reproducible build.
force_update : bool, default=False
if True, re-download data
Returns
-------
- binding_affinity : dict[str, Any]
- binding affinity data
+ dict[str, list[dict[str, Any]]]
+ Eligible measurements grouped by reported PDB ID and ligand HET code.
+ A ligand must still match the target sequence to its receptor chains.
"""
from io import BytesIO
from urllib.request import urlopen
from zipfile import ZipFile
- affinity_path = data_dir / "dbs" / "affinity" / "affinity.json"
- papyrus_raw_affinity_path = (
- data_dir / "dbs" / "affinity" / "papyrus_affinity_raw.tar.gz"
- )
- bindingdb_raw_affinity_path = (
- data_dir / "dbs" / "affinity" / "BindingDB_All_202401.tsv"
- )
- moad_raw_affinity_path = data_dir / "dbs" / "affinity" / "moad_affinity.csv"
+ affinity_dir = data_dir / "dbs" / "affinity"
+ bindingdb_raw_affinity_path = affinity_dir / "BindingDB_All.tsv"
+ measurements_path = affinity_dir / "measurements.parquet"
+ candidates_path = affinity_dir / "candidates.parquet"
- # Make sub directories
- papyrus_raw_affinity_path.parent.mkdir(parents=True, exist_ok=True)
- bindingdb_raw_affinity_path.parent.mkdir(parents=True, exist_ok=True)
- moad_raw_affinity_path.parent.mkdir(parents=True, exist_ok=True)
- if not affinity_path.is_file() or force_update:
+ affinity_dir.mkdir(parents=True, exist_ok=True)
+ if force_update or not measurements_path.is_file() or not candidates_path.is_file():
# Download BindingDB
if (
not bindingdb_raw_affinity_path.is_file()
or bindingdb_raw_affinity_path.stat().st_size == 0
or force_update
):
+ if bindingdb_url is None:
+ bindingdb_url = latest_bindingdb_tsv_url()
LOG.info(f"download_bindingdb_affinity_data: {bindingdb_url}...")
with urlopen(bindingdb_url) as zipresp:
with ZipFile(BytesIO(zipresp.read())) as zfile:
zfile.extractall(path=bindingdb_raw_affinity_path.parent)
- LOG.info("transforming_affinity_data: extracting median affinity")
- binding_db_affinity_df = transform.transform_bindingdb_affinity_data(
+ LOG.info("transforming_affinity_data: retaining Ki/Kd records")
+ measurements = transform.transform_bindingdb_measurements(
raw_affinity_path=bindingdb_raw_affinity_path
)
- binding_db_affinity_df["preference"] = 1
-
- all_affinity_df = binding_db_affinity_df.drop_duplicates()
- all_affinity_df = all_affinity_df[all_affinity_df["pchembl"].notna()]
-
- all_affinity_df = all_affinity_df.loc[
- all_affinity_df.groupby("pdbid_ligid")["preference"].idxmin()
- ]
- all_affinity_df = all_affinity_df.set_index("pdbid_ligid")
- affinity_json = all_affinity_df[["pchembl"]].to_json()
- obj: dict[str, Any] = json.loads(affinity_json)
- with affinity_path.open("w") as f:
- json.dump(obj, f, indent=4)
- else:
- with affinity_path.open() as f:
- obj = json.load(f)
- return obj["pchembl"]
-
-
-@retry
-def download_components_cif(
- *,
- data_dir: Path,
- url: str = "https://files.wwpdb.org/pub/pdb/data/monomers/components.cif.gz",
- force_update: bool = False,
-) -> Path:
- """
- Download components cif. Additionally aggregate
- the cif to a dataframe and store as parquet.
-
- Parameters
- ----------
- data_dir : Path
- the root plinder dir
- url : str
- URL to fetch data from
- force_update : bool, default=False
- if True, re-download data
-
- Returns
- -------
- components_path : Path
- path to downloaded components data
- """
- components_path = data_dir / "dbs" / "components" / "components.cif"
- components_path.parent.mkdir(parents=True, exist_ok=True)
- if not components_path.is_file() or force_update:
- LOG.info(f"download_components_cif: {url}")
- resp = requests.get(url)
- resp.raise_for_status()
- gz = components_path.parent / "components.cif.gz"
- gz.write_bytes(resp.content)
- with gzip.open(gz, "rb") as arch:
- with components_path.open("wb") as file:
- shutil.copyfileobj(arch, file)
- components_pqt = data_dir / "dbs" / "components" / "components.parquet"
- if not components_pqt.is_file() or force_update:
- LOG.info(f"download_components_cif: transforming {components_path}")
- df = transform.transform_components_data(raw_components_path=components_path)
- df.to_parquet(components_pqt, index=False)
- return components_path
-
-
-@retry
-def download_ecod_data(
- *,
- data_dir: Path,
- url: str = "http://prodata.swmed.edu/ecod/distributions/ecod.latest.domains.txt",
- force_update: bool = False,
-) -> Path:
- """
- Download ECOD data.
-
- Parameters
- ----------
- data_dir : Path
- the root plinder dir
- url : str
- URL to fetch data from
- force_update : bool, default=False
- if True, re-download data
-
- Returns
- -------
- ecod_path : Path
- path to downloaded ECOD data
- """
- raw_ecod_path = data_dir / "dbs" / "ecod" / "ecod_raw.tsv"
- raw_ecod_path.parent.mkdir(parents=True, exist_ok=True)
- if not raw_ecod_path.is_file() or force_update:
- LOG.info(f"download_ecod_data: {url}")
- resp = requests.get(url)
- resp.raise_for_status()
- raw_ecod_path.write_text(resp.text)
- ecod_path = data_dir / "dbs" / "ecod" / "ecod.parquet"
- if not ecod_path.is_file() or force_update:
- LOG.info(f"download_ecod_data: transforming {raw_ecod_path}")
- ecod = transform.transform_ecod_data(raw_ecod_path=raw_ecod_path)
- ecod.to_parquet(ecod_path, index=False)
- return ecod_path
-
-
-@retry
-def download_panther_data(
- *,
- data_dir: Path,
- url: str = "http://data.pantherdb.org/ftp/generic_mapping/panther_classifications.tar.gz",
- force_update: bool = False,
-) -> Path:
+ candidates = transform.strict_bindingdb_candidates(measurements)
+ records_tmp = measurements_path.with_suffix(".parquet.tmp")
+ candidates_tmp = candidates_path.with_suffix(".parquet.tmp")
+ try:
+ measurements.to_parquet(records_tmp, index=False)
+ candidates.to_parquet(candidates_tmp, index=False)
+ records_tmp.replace(measurements_path)
+ candidates_tmp.replace(candidates_path)
+ finally:
+ records_tmp.unlink(missing_ok=True)
+ candidates_tmp.unlink(missing_ok=True)
+ return candidate_map(pd.read_parquet(candidates_path))
+
+
+def refresh_bundled_ccd(
+ *, data_dir: Path | None = None, force_update: bool = False
+) -> None:
+ """Sync biotite's bundled CCD (``bt_info``) to the current wwPDB release.
+
+ ``bt_info`` is plinder's single CCD source โ atoms and bonds for
+ ``_get_ccd_atomarray``, and (via RDKit) the reference SMILES used for
+ cofactor/artifact matching. biotite ships a *frozen* snapshot that can be
+ stale (e.g. nitro groups stored over-valent, missing 5-char extended codes),
+ so the pipeline syncs it here with ``biotite.setup_ccd``, which pulls the same
+ wwPDB dictionary.
+
+ Fails loudly: this rewrites biotite's install directory, so a read-only
+ ``site-packages`` (or a download failure) raises โ deliberately, because a
+ silent failure would leave CCD lookups on a stale bundle with no fallback.
+ ``data_dir`` / ``force_update`` are accepted for task-signature compatibility
+ and ignored (``setup_ccd`` always pulls the latest).
"""
- Download panther data. Also
- partitions panther by trailing character
- in uniprot code.
-
- Parameters
- ----------
- data_dir : Path
- the root plinder dir
- url : str
- URL to fetch data from
- force_update : bool, default=False
- if True, re-download data
+ from biotite import setup_ccd
- Returns
- -------
- panther_path : Path
- path to downloaded panther data
- """
- raw_panther_path = data_dir / "dbs" / "panther" / "panther_raw.tar.gz"
- raw_panther_path.parent.mkdir(parents=True, exist_ok=True)
- if not raw_panther_path.is_file() or force_update:
- LOG.info(f"download_panther_data: {url}")
- resp = requests.get(url)
- resp.raise_for_status()
- raw_panther_path.write_bytes(resp.content)
- panther_path = data_dir / "dbs" / "panther" / "panther.parquet"
- if not panther_path.is_file() or force_update:
- LOG.info(f"download_panther_data: transforming {raw_panther_path}")
- panther = transform.transform_panther_data(raw_panther_path=raw_panther_path)
- panther["shard"] = panther["uniprotac"].str[-1]
- panther.to_parquet(raw_panther_path.parent / "panther.parquet", index=False)
- for shard, grp in panther.groupby("shard"):
- panther_shard = data_dir / "dbs" / "panther" / f"panther_{shard}.parquet"
- grp.to_parquet(panther_shard, index=False)
- return panther_path
+ setup_ccd.main()
+ LOG.info(
+ "refresh_bundled_ccd: synced biotite bundled CCD (bt_info) to current wwPDB"
+ )
@retry
@@ -313,103 +234,6 @@ def download_seqres_data(
return seqres_path
-@retry
-def download_kinase_data(
- *,
- data_dir: Path,
- url: str = "https://klifs.net/api/",
- force_update: bool = False,
-) -> Path:
- """
- Download kinase data.
-
- Parameters
- ----------
- data_dir : Path
- the root plinder dir
- url : str
- URL to fetch data from
- force_update : bool, default=False
- if True, re-download data
-
- Returns
- -------
- kinase_uniprotac_path : Path
- location of downloaded kinase data
- """
- kinase_info_path = data_dir / "dbs" / "kinase" / "kinase_information.parquet"
- if not kinase_info_path.parent.exists() or force_update:
- LOG.info(f"download_kinase_data: data_dir={data_dir}")
- kinase_info_path.parent.mkdir(exist_ok=True, parents=True)
- if not kinase_info_path.is_file() or force_update:
- LOG.info(f"download_kinase_data: {url}/kinase_information")
- resp = requests.get(f"{url}/kinase_information")
- resp.raise_for_status()
- kinase_info = pd.DataFrame(resp.json(), dtype=str)
- kinase_info.to_parquet(kinase_info_path, index=False)
- kinase_ligand_path = data_dir / "dbs" / "kinase" / "kinase_ligand_ccd_codes.parquet"
- if not kinase_ligand_path.is_file() or force_update:
- LOG.info(f"download_kinase_data: {url}/ligands_list")
- resp = requests.get(f"{url}/ligands_list")
- resp.raise_for_status()
- kinase_ligand = pd.DataFrame(resp.json(), dtype=str)
- kinase_ligand.to_parquet(kinase_ligand_path, index=False)
- kinase_struc_path = kinase_info_path.parent / "kinase_structures.parquet"
- if not kinase_struc_path.is_file() or force_update:
- kinase_info = pd.read_parquet(kinase_info_path)
- outputs = []
- LOG.info(f"download_kinase_data: {url}/structures_list iteratively...")
- for kid in kinase_info["kinase_ID"].unique():
- resp = requests.get(f"{url}/structures_list", params={"kinase_ID": kid})
- if 200 <= resp.status_code < 400:
- outputs.extend(resp.json())
- kinase_struc = pd.DataFrame(outputs, dtype=str).drop_duplicates()
- kinase_struc.to_parquet(kinase_struc_path, index=False)
- kinase_uniprotac_path = kinase_info_path.parent / "kinase_uniprotac.parquet"
- if not kinase_uniprotac_path.is_file() or force_update:
- LOG.info("download_kinase_data: merging information and structure")
- kinase_info = pd.read_parquet(kinase_info_path)
- kinase_struc = pd.read_parquet(kinase_struc_path)
- df = pd.merge(
- kinase_struc,
- kinase_info[
- [
- "kinase_ID",
- "name",
- "HGNC",
- "family",
- "group",
- "kinase_class",
- "full_name",
- "uniprot",
- ]
- ],
- on="kinase_ID",
- how="left",
- )
- df["pdb"] = df["pdb"].astype(str).map(str.lower)
- df["pdbid_chainid"] = df["pdb"].str.cat(df["chain"], sep="_")
- for int_col in [
- "structure_ID",
- "kinase_ID",
- "missing_atoms",
- "missing_residues",
- ]:
- df[int_col] = df[int_col].astype(int)
- for float_col in [
- "rmsd1",
- "rmsd2",
- "resolution",
- "quality_score",
- "Grich_distance",
- "Grich_rotation",
- "Grich_angle",
- ]:
- df[float_col] = df[float_col].astype(float)
- df.to_parquet(kinase_uniprotac_path, index=False)
- return kinase_uniprotac_path
-
-
@retry
def rsync_rcsb(
*,
@@ -419,7 +243,7 @@ def rsync_rcsb(
pdb_id: Optional[str] = None,
) -> None:
"""
- Run an RCSB rsync command.
+ Download PDB source files from the archive's supported rsync mirrors.
Parameters
----------
@@ -436,11 +260,13 @@ def rsync_rcsb(
if kind == "cif":
server = CIF_PATH
contents = CIF_GLOB
+ port = CIF_PORT
if pdb_id is not None:
suffix = f"pdb_0000{pdb_id}"
else:
server = VAL_PATH
contents = VAL_GLOB
+ port = VAL_PORT
if pdb_id is not None:
suffix = pdb_id
@@ -450,7 +276,6 @@ def rsync_rcsb(
dest = f"{data_dir}/{two_char_code}/"
Path(dest).mkdir(exist_ok=True, parents=True)
- port = CIF_PORT if kind == "cif" else RCSB_PORT
cmd = (
f"rsync -rlpt -z --delete --port={port} --no-perms "
f'--include "*/" --include "{contents}" --exclude="*" '
@@ -469,14 +294,18 @@ def list_rcsb(
) -> list[str]:
if kind not in KINDS:
raise ValueError(f"kind={kind} not in {KINDS}")
- server = CIF_PATH if kind == "cif" else VAL_PATH
+ if kind == "cif":
+ server = CIF_PATH
+ port = CIF_PORT
+ else:
+ server = VAL_PATH
+ port = VAL_PORT
if two_char_code is not None:
server = f"{server}/{two_char_code}/"
if pdb_id is not None:
server = f"{server}{pdb_id}"
else:
server = f"{server}/"
- port = CIF_PORT if kind == "cif" else RCSB_PORT
cmd = f"rsync --port={port} --list-only {server}"
LOG.info(f"running: {cmd}")
output = check_output(cmd, shell=True, text=True).splitlines()
@@ -509,24 +338,6 @@ def get_missing_two_char_codes(
return missing
-def get_missing_pdb_ids(
- *,
- kind: KIND_TYPES,
- data_dir: Path,
- two_char_code: str,
-) -> list[str]:
- missing = []
- glob = CIF_GLOB if kind == "cif" else VAL_GLOB
- for pdb_id in list_rcsb(kind=kind, two_char_code=two_char_code):
- pdb_dir = data_dir / two_char_code / pdb_id
- if not pdb_dir.is_dir():
- missing.append(pdb_id)
- continue
- if not len(list(pdb_dir.glob(glob))):
- missing.append(pdb_id)
- return missing
-
-
@retry
def download_alphafold_cif_files(
*,
diff --git a/src/plinder/data/pipeline/mpqueue.py b/src/plinder/data/pipeline/mpqueue.py
deleted file mode 100644
index add6e7711..000000000
--- a/src/plinder/data/pipeline/mpqueue.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-#!/usr/bin/env python
-
-import argparse
-import logging
-import multiprocessing
-import os
-import time
-from itertools import repeat
-from multiprocessing import cpu_count
-from subprocess import check_output
-from typing import List, Optional
-
-logging.basicConfig(format="[MPQueue] %(levelname)s: %(message)s", level=logging.DEBUG)
-
-
-class Task:
- """A task class"""
-
- def __init__(
- self, command: str, path: str = ".", timeout: Optional[int] = None
- ) -> None:
- self.command = command
- self.path = path
- if timeout is not None:
- timeout = int(timeout)
- self.timeout = timeout
-
- def run(self) -> None:
- """Runs a command in the given path"""
- try:
- check_output(self.command, shell=True, timeout=self.timeout, cwd=self.path)
- except Exception:
- pass
-
-
-class MPQueue(object):
- """Distributes Tasks to Pool"""
-
- def __init__(
- self,
- tasks: List[Task],
- num_cpus: int = 0,
- maxtasksperchild: Optional[int] = None,
- chunksize: int = 1,
- ) -> None:
- try:
- self.num_processes = int(num_cpus)
- if self.num_processes < 1:
- raise ValueError()
- except (ValueError, TypeError):
- logging.warning(
- "Number of cores not specified or incorrect. Using all cores."
- )
- self.num_processes = cpu_count() - 1
-
- logging.info(f"MPQueue will use {self.num_processes} cores")
-
- self.tasks = tasks
- self.num_tasks = len(tasks)
- self.maxtasksperchild = maxtasksperchild
- if maxtasksperchild is not None:
- self.maxtasksperchild = int(maxtasksperchild)
- self.chunksize = chunksize
-
- def process(self) -> None:
- with multiprocessing.get_context("spawn").Pool(
- processes=self.num_processes,
- maxtasksperchild=self.maxtasksperchild,
- ) as pool:
- pool.map(
- MPQueue.run_task,
- zip(enumerate(self.tasks), repeat(self.num_tasks)),
- chunksize=self.chunksize,
- )
-
- @staticmethod
- def run_task(tup: tuple[tuple[int, Task], int]) -> None:
- (item, task), total = tup
- logging.info(f"running task {item}/{total}: {task.command}")
- t0 = time.time()
- task.run()
- t1 = time.time()
- logging.info(f"running task {item}/{total} took {(t1-t0):.2f}s")
-
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(prog="mpqueue")
- parser.add_argument(
- "tasks_file_name",
- help="A file containing a task for each line",
- metavar="tasks_file_name",
- )
- parser.add_argument(
- "--cores",
- "-cores",
- "-c",
- help="CPU cores to use",
- dest="cores",
- type=int,
- default=0,
- )
- parser.add_argument(
- "--maxtasksperchild",
- "-maxtask",
- "-t",
- help="Maximum tasks per child process",
- dest="maxtasksperchild",
- type=int,
- default=1,
- )
- parser.add_argument(
- "--chunksize",
- "-chunk",
- "-s",
- help="Chunksize to pass to Pool.map",
- dest="chunksize",
- type=int,
- default=1,
- )
- parser.add_argument(
- "--cwd",
- default=".",
- )
- parser.add_argument(
- "--timeout",
- help="Timeout in seconds (must be intable)",
- default=None,
- )
- args = parser.parse_args()
- with open(args.tasks_file_name) as handle:
- tasks = []
- for line in handle:
- if line and not line.startswith("#"):
- tasks.append(Task(line.rstrip(os.linesep), args.cwd, args.timeout))
-
- queue = MPQueue(tasks, args.cores, args.maxtasksperchild)
- queue.process()
diff --git a/src/plinder/data/pipeline/pipeline.py b/src/plinder/data/pipeline/pipeline.py
index 46612427c..21caf1f7a 100644
--- a/src/plinder/data/pipeline/pipeline.py
+++ b/src/plinder/data/pipeline/pipeline.py
@@ -1,23 +1,23 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
+import tempfile
from pathlib import Path
-from typing import Any, Optional
+from typing import Any, Literal, Optional
+import pandas as pd
from omegaconf import DictConfig
from plinder.core.utils.log import setup_logger
+from plinder.data import protein_clusters
from plinder.data.pipeline import config, tasks, utils
+from plinder.data.pipeline.ingest import resolve_source_roots
LOG = setup_logger(__name__)
class IngestPipeline:
"""
- Mimic the required metaflow DAG pattern of
- - scatter
- - compute
- - join
- by convention in method names.
+ Configure pipeline stages using scatter, compute, and join methods.
scatter methods return lists of lists of primitives
compute methods may return something if intended to be joined
@@ -26,8 +26,8 @@ class IngestPipeline:
Note
----
business logic is implemented in tasks.py. The
- Pipeline is merely an interface between configuration
- and functions, which can be mirrored in metaflow.
+ Pipeline is an interface between configuration and task functions.
+ Slurm execution uses the scripts in scripts/slurm.
"""
def __init__(
@@ -48,6 +48,24 @@ def __init__(
self.plinder_dir = Path(self.cfg.data.plinder_dir)
LOG.info(f"plinder_dir={self.plinder_dir}")
+ def _entry_source_roots(self) -> tuple[Path, Path]:
+ """Resolve configured source archives for entry generation."""
+ return resolve_source_roots(
+ data_dir=self.plinder_dir,
+ cif_root=self.cfg.source.pdb_nextgen_root or None,
+ validation_root=self.cfg.source.validation_root or None,
+ )
+
+ def _seqres_source(self) -> Path | None:
+ """Resolve an optional pre-fetched PDB SEQRES input."""
+ configured = str(self.cfg.source.seqres_path)
+ if not configured:
+ return None
+ path = Path(configured).expanduser()
+ if not path.is_absolute():
+ path = self.plinder_dir / path
+ return path.resolve()
+
def __setstate__(self, state: dict[str, Any]) -> None:
self.cfg = config.get_config(config=state.pop("cfg"))
for k, v in state.items():
@@ -79,11 +97,66 @@ def download_alternative_datasets(self) -> None:
force_update=self.cfg.data.force_update,
)
+ @utils.ingest_flow_control
+ def make_protein_sequence_clusters(self) -> None:
+ protein_clusters.make_protein_sequence_clusters(
+ data_dir=self.plinder_dir,
+ scratch_dir=Path(tempfile.gettempdir()),
+ threads=self.cfg.flow.protein_clustering_cpu,
+ identity=self.cfg.flow.protein_sequence_cluster_identity,
+ coverage=self.cfg.flow.protein_cluster_coverage,
+ force_update=self.cfg.data.force_update,
+ )
+
+ @utils.ingest_flow_control
+ def make_protein_structure_clusters(self) -> None:
+ protein_clusters.make_protein_structure_clusters(
+ data_dir=self.plinder_dir,
+ scratch_dir=Path(tempfile.gettempdir()),
+ threads=self.cfg.flow.protein_clustering_cpu,
+ lddt=self.cfg.flow.protein_structure_cluster_lddt,
+ coverage=self.cfg.flow.protein_cluster_coverage,
+ force_update=self.cfg.data.force_update,
+ )
+
@utils.ingest_flow_control
def make_dbs(self) -> None:
+ cif_root, _ = self._entry_source_roots()
+ from plinder.data.pipeline.score import (
+ make_foldseek_input_manifest,
+ plan_linked_apo_scoring,
+ plan_protein_scoring,
+ )
+
+ if self.cfg.foldseek.max_seqs != self.cfg.mmseqs.max_seqs:
+ raise ValueError(
+ "Foldseek and MMseqs max_seqs must match in one scoring plan"
+ )
+ plan_protein_scoring(
+ self.plinder_dir,
+ pdb_ids=list(self.cfg.context.pdb_ids),
+ two_char_codes=list(self.cfg.context.two_char_codes),
+ max_seqs=self.cfg.foldseek.max_seqs,
+ )
+ if "apo" in self.cfg.scorer.sub_databases:
+ plan_linked_apo_scoring(
+ self.plinder_dir,
+ pdb_ids=list(self.cfg.context.pdb_ids),
+ two_char_codes=list(self.cfg.context.two_char_codes),
+ max_seqs=self.cfg.foldseek.max_seqs,
+ )
+ cif_root = make_foldseek_input_manifest(self.plinder_dir, cif_root)
+ scratch_root = Path(tempfile.gettempdir()) / "plinder-full-search-dbs"
tasks.make_dbs(
data_dir=self.plinder_dir,
sub_databases=self.cfg.scorer.sub_databases,
+ cpu=self.cfg.flow.make_dbs_cpu,
+ cif_root=cif_root,
+ seqres_path=self._seqres_source(),
+ scratch_dir=scratch_root / "work",
+ build_dir=scratch_root / "build",
+ index=False,
+ force_update=self.cfg.data.force_update,
)
@utils.ingest_flow_control
@@ -91,27 +164,39 @@ def scatter_make_entries(self) -> list[list[str]]:
force_update = (
self.cfg.data.force_update or self.cfg.flow.make_entries_force_update
)
+ cif_root, validation_root = self._entry_source_roots()
chunks: list[list[str]] = tasks.scatter_make_entries(
data_dir=self.plinder_dir,
+ cif_root=cif_root,
+ validation_root=validation_root,
batch_size=self.cfg.flow.make_entries_batch_size,
two_char_codes=self.cfg.context.two_char_codes,
pdb_ids=self.cfg.context.pdb_ids,
force_update=force_update,
+ discovery_threads=self.cfg.source.discovery_threads,
+ interface_min_residues=self.cfg.interface.min_interface_residues,
+ interface_annotate_prodigy=self.cfg.interface.annotate_prodigy,
+ ingest_mode=self.cfg.flow.make_entries_mode,
)
return chunks
@utils.ingest_flow_control
- def make_entries(self, pdb_dirs: list[str]) -> list[str]:
+ def make_entries(self, pdb_ids: list[str]) -> list[str]:
force_update = (
self.cfg.data.force_update or self.cfg.flow.make_entries_force_update
)
+ cif_root, validation_root = self._entry_source_roots()
failed: list[str] = tasks.make_entries(
data_dir=self.plinder_dir,
- pdb_dirs=pdb_dirs,
+ pdb_ids=pdb_ids,
+ cif_root=cif_root,
+ validation_root=validation_root,
force_update=force_update,
cpu=self.cfg.flow.make_entries_cpu,
annotation_cfg=self.cfg.annotation,
entry_cfg=self.cfg.entry,
+ interface_cfg=self.cfg.interface,
+ ingest_mode=self.cfg.flow.make_entries_mode,
)
return failed
@@ -123,50 +208,37 @@ def join_make_entries(self, reruns: list[list[str]]) -> list[str]:
return catted
@utils.ingest_flow_control
- def scatter_structure_qc(self) -> list[list[str]]:
- chunks: list[list[str]] = tasks.scatter_structure_qc(
+ def scatter_collate_entries(self) -> list[list[str]]:
+ return tasks.scatter_collate_entries(
data_dir=self.plinder_dir,
- two_char_codes=self.cfg.context.two_char_codes,
- batch_size=self.cfg.flow.download_rcsb_files_batch_size,
+ batch_size=self.cfg.flow.collate_entries_batch_size,
+ include_ligand_annotations=self.cfg.flow.make_entries_mode != "interfaces",
)
- return chunks
@utils.ingest_flow_control
- def structure_qc(self, two_char_codes: list[str]) -> None:
- tasks.structure_qc(
+ def collate_entries(self, two_char_codes: list[str]) -> None:
+ tasks.collate_entries(
data_dir=self.plinder_dir,
two_char_codes=two_char_codes,
+ cpu=self.cfg.flow.collate_entries_cpu,
+ memory_limit=self.cfg.flow.collate_entries_memory_limit,
)
@utils.ingest_flow_control
- def join_structure_qc(self, qcs: list[None]) -> None:
- force_update = (
- self.cfg.data.force_update or self.cfg.flow.structure_qc_force_update
- )
- utils.create_index(
- data_dir=self.plinder_dir,
- force_update=force_update,
- )
-
- @utils.ingest_flow_control
- def scatter_make_ligands(self) -> list[list[str]]:
- chunks: list[list[str]] = tasks.scatter_make_ligands(
+ def join_collate_entries(self, outputs: list[None]) -> None:
+ del outputs
+ tasks.finalize_entry_collation(
data_dir=self.plinder_dir,
- batch_size=self.cfg.flow.make_ligands_batch_size,
- two_char_codes=self.cfg.context.two_char_codes,
- pdb_ids=self.cfg.context.pdb_ids,
+ cpu=self.cfg.flow.finalize_entries_cpu,
+ memory_limit=self.cfg.flow.finalize_entries_memory_limit,
)
- return chunks
-
- @utils.ingest_flow_control
- def make_ligands(self, pdb_ids: list[str]) -> None:
- tasks.make_ligands(data_dir=self.plinder_dir, pdb_ids=pdb_ids)
+ tasks.publish_binding_affinity(data_dir=self.plinder_dir)
@utils.ingest_flow_control
def compute_ligand_fingerprints(self) -> None:
tasks.compute_ligand_fingerprints(
data_dir=self.plinder_dir,
- split_char=self.cfg.ligand.ligand_id_split_char,
+ cofactor_similarity_threshold=self.cfg.ligand.cofactor_similarity_threshold,
)
@utils.ingest_flow_control
@@ -183,36 +255,97 @@ def make_ligand_scores(self, ligand_ids: list[int]) -> None:
tasks.make_ligand_scores(
data_dir=self.plinder_dir,
ligand_ids=ligand_ids,
- save_top_k_similar_ligands=self.cfg.ligand.save_top_k_similar_ligands,
- multiply_by=self.cfg.ligand.multiply_by,
+ minimum_similarity=self.cfg.ligand.minimum_similarity,
+ number_id_col=self.cfg.ligand.number_id_col,
+ )
+
+ @utils.ingest_flow_control
+ def scatter_make_mhfp6_scores(self) -> list[list[int]]:
+ # MHFP6 clustering is opt-in: only score when the metric is configured,
+ # so dropping it from cluster_metrics also skips its all-pairs scoring.
+ from plinder.data.annotations.get_similarity_scores import MHFP6_METRIC
+
+ if MHFP6_METRIC not in self.cfg.flow.cluster_metrics:
+ LOG.info(
+ "scatter_make_mhfp6_scores: MHFP6 not in cluster_metrics; skipping"
+ )
+ return [[]]
+ ligand_ids: list[list[int]] = tasks.scatter_make_mhfp6_scores(
+ data_dir=self.plinder_dir,
+ batch_size=self.cfg.flow.make_ligands_batch_size,
+ number_id_col=self.cfg.ligand.number_id_col,
+ )
+ return ligand_ids
+
+ @utils.ingest_flow_control
+ def make_mhfp6_scores(self, ligand_ids: list[int]) -> None:
+ tasks.make_mhfp6_scores(
+ data_dir=self.plinder_dir,
+ ligand_ids=ligand_ids,
+ minimum_similarity=self.cfg.ligand.minimum_similarity,
number_id_col=self.cfg.ligand.number_id_col,
)
@utils.ingest_flow_control
- def make_mmp_index(self) -> None:
- tasks.make_mmp_index(data_dir=self.plinder_dir)
+ def annotate_ligand_similarity(self) -> None:
+ tasks.annotate_ligand_similarity(
+ data_dir=self.plinder_dir,
+ minimum_similarity=self.cfg.ligand.minimum_similarity,
+ number_id_col=self.cfg.ligand.number_id_col,
+ )
+
+ @utils.ingest_flow_control
+ def make_ligand_mmp_pairs(self, *, threads: int | None = None) -> None:
+ tasks.make_ligand_mmp_pairs(
+ data_dir=self.plinder_dir,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-mmp",
+ threads=threads or self.cfg.flow.clustering_cpu,
+ force_update=self.cfg.data.force_update,
+ )
+
+ @utils.ingest_flow_control
+ def make_ccd_ligand_dbs(self, *, threads: int | None = None) -> None:
+ tasks.make_ccd_ligand_dbs(
+ data_dir=self.plinder_dir,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-ccd-dbs",
+ threads=threads or self.cfg.flow.clustering_cpu,
+ force_update=self.cfg.data.force_update,
+ minimum_similarity=self.cfg.ligand.minimum_similarity,
+ )
@utils.ingest_flow_control
- def scatter_make_system_archives(self) -> list[list[str]]:
- chunks: list[list[str]] = tasks.scatter_make_system_archives(
+ def scatter_make_canonical_ligand_archives(self) -> list[list[str]]:
+ chunks: list[list[str]] = tasks.scatter_make_canonical_ligand_archives(
data_dir=self.plinder_dir,
two_char_codes=self.cfg.context.two_char_codes,
+ pdb_ids=self.cfg.context.pdb_ids,
batch_size=self.cfg.flow.download_rcsb_files_batch_size,
)
return chunks
@utils.ingest_flow_control
- def make_system_archives(self, two_char_codes: list[str]) -> None:
- tasks.make_system_archives(
+ def make_canonical_ligand_archives(self, two_char_codes: list[str]) -> None:
+ tasks.make_canonical_ligand_archives(
data_dir=self.plinder_dir,
two_char_codes=two_char_codes,
)
+ @utils.ingest_flow_control
+ def finalize_ligand_archives(self) -> None:
+ from plinder.data.pipeline.score import finalize_ligand_archives
+
+ finalize_ligand_archives(self.plinder_dir)
+
@utils.ingest_flow_control
def make_sub_dbs(self) -> None:
+ search_databases = list(self.cfg.scorer.sub_databases)
+ if "holo" in search_databases:
+ search_databases.append("monomer")
tasks.make_sub_dbs(
data_dir=self.plinder_dir,
- sub_databases=self.cfg.scorer.sub_databases,
+ sub_databases=search_databases,
+ cpu=self.cfg.flow.make_sub_dbs_cpu,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-exact-search-dbs",
)
@utils.ingest_flow_control
@@ -222,15 +355,49 @@ def scatter_run_batch_searches(self) -> list[list[str]]:
batch_size=self.cfg.flow.run_batch_searches_batch_size,
two_char_codes=self.cfg.context.two_char_codes,
pdb_ids=self.cfg.context.pdb_ids,
+ search_dbs=self.cfg.scorer.sub_databases,
)
return chunks
@utils.ingest_flow_control
def run_batch_searches(self, pdb_ids: list[str]) -> None:
- tasks.run_batch_searches(
- data_dir=self.plinder_dir,
- pdb_ids=pdb_ids,
+ with tempfile.TemporaryDirectory(prefix="plinder-search-") as scratch:
+ tasks.run_batch_searches(
+ data_dir=self.plinder_dir,
+ pdb_ids=pdb_ids,
+ scorer_cfg=self.cfg.scorer,
+ foldseek_cfg=self.cfg.foldseek,
+ mmseqs_cfg=self.cfg.mmseqs,
+ cpu=self.cfg.flow.make_scorers_cpu,
+ scratch_dir=Path(scratch),
+ force_update=self.cfg.data.force_update,
+ )
+
+ @utils.ingest_flow_control
+ def scatter_map_batch_alignments(self) -> list[tuple[str, list[str]]]:
+ work: list[tuple[str, list[str]]] = []
+ search_databases = list(self.cfg.scorer.sub_databases)
+ if "apo" in search_databases:
+ search_databases.insert(search_databases.index("apo") + 1, "interface_apo")
+ for search_db in search_databases:
+ chunks = tasks.scatter_missing_alignment_mappings(
+ data_dir=self.plinder_dir,
+ batch_size=self.cfg.flow.map_batch_alignments_batch_size,
+ search_db=search_db,
+ )
+ work.extend((search_db, shards) for shards in chunks if shards)
+ return work or [(str(self.cfg.scorer.sub_databases[0]), [])]
+
+ @utils.ingest_flow_control
+ def map_batch_alignments(self, work: tuple[str, list[str]]) -> None:
+ search_db, shards = work
+ force_update = self.cfg.data.force_update
+ tasks.map_batch_alignments(
+ data_dir=self.plinder_dir,
+ shards=shards,
scorer_cfg=self.cfg.scorer,
+ force_update=force_update,
+ search_db=search_db,
)
@utils.ingest_flow_control
@@ -238,6 +405,8 @@ def scatter_make_batch_scores(self) -> list[list[str]]:
chunks: list[list[str]] = tasks.scatter_missing_scores(
data_dir=self.plinder_dir,
batch_size=self.cfg.flow.make_batch_scores_batch_size,
+ scorer_cfg=self.cfg.scorer,
+ search_dbs=self.cfg.scorer.sub_databases,
)
return chunks
@@ -246,151 +415,500 @@ def make_batch_scores(self, pdb_ids: list[str]) -> None:
force_update = (
self.cfg.data.force_update or self.cfg.flow.make_batch_scores_force_update
)
- tasks.make_batch_scores(
+ with tempfile.TemporaryDirectory(prefix="plinder-score-") as scratch:
+ tasks.make_batch_scores(
+ data_dir=self.plinder_dir,
+ pdb_ids=pdb_ids,
+ scorer_cfg=self.cfg.scorer,
+ force_update=force_update,
+ scratch_dir=Path(scratch),
+ threads=self.cfg.flow.make_batch_scores_cpu,
+ defer_ligand_3d=True,
+ )
+
+ @utils.ingest_flow_control
+ def scatter_collate_ligand_3d_candidates(self) -> list[list[str]]:
+ return tasks.scatter_scoring_query_shards(
data_dir=self.plinder_dir,
- pdb_ids=pdb_ids,
- scorer_cfg=self.cfg.scorer,
- force_update=force_update,
+ batch_size=self.cfg.flow.collate_ligand_3d_candidates_batch_size,
)
@utils.ingest_flow_control
- def scatter_collate_partitions(self) -> list[list[str]]:
- chunks: list[list[str]] = tasks.scatter_collate_partitions()
- return chunks
+ def collate_ligand_3d_candidates(self, shards: list[str]) -> None:
+ tasks.collate_ligand_3d_candidates(
+ data_dir=self.plinder_dir,
+ shards=shards,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-ligand-3d-candidates",
+ threads=self.cfg.flow.make_ligand_3d_scores_cpu,
+ )
@utils.ingest_flow_control
- def collate_partitions(self, partition: list[str]) -> None:
- tasks.collate_partitions(data_dir=self.plinder_dir, partition=partition)
+ def plan_ligand_3d_scores(self) -> None:
+ from plinder.data.pipeline.score import plan_ligand_3d_batches
+
+ plan_ligand_3d_batches(
+ self.plinder_dir,
+ batch_size=self.cfg.flow.make_ligand_3d_scores_batch_size,
+ threads=self.cfg.flow.make_ligand_3d_scores_cpu,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-ligand-3d-plan",
+ )
@utils.ingest_flow_control
- def scatter_make_components_and_communities(self) -> list[list[tuple[str, int]]]:
+ def scatter_make_ligand_3d_scores(self) -> list[list[int]]:
+ return tasks.scatter_ligand_3d_score_batches(data_dir=self.plinder_dir)
+
+ @utils.ingest_flow_control
+ def make_ligand_3d_scores(self, batch_indices: list[int]) -> None:
+ from plinder.data.pipeline.score import _ligand_3d_batch
+
force_update = (
- self.cfg.data.force_update or self.cfg.flow.make_components_force_update
+ self.cfg.data.force_update or self.cfg.flow.make_batch_scores_force_update
)
- chunks: list[
- list[tuple[str, int]]
- ] = tasks.scatter_make_components_and_communities(
+ for batch_index in batch_indices:
+ pairs = _ligand_3d_batch(
+ self.plinder_dir,
+ batch_index,
+ self.cfg.flow.make_ligand_3d_scores_batch_size,
+ )
+ tasks.make_ligand_3d_scores(
+ data_dir=self.plinder_dir,
+ pairs=pairs,
+ batch_index=batch_index,
+ scorer_cfg=self.cfg.scorer,
+ force_update=force_update,
+ scratch_dir=(
+ Path(tempfile.gettempdir())
+ / "plinder-ligand-3d-score"
+ / str(batch_index)
+ ),
+ threads=self.cfg.flow.make_ligand_3d_scores_cpu,
+ )
+
+ @utils.ingest_flow_control
+ def scatter_collate_ligand_3d_scores(self) -> list[list[str]]:
+ return tasks.scatter_scoring_query_shards(
data_dir=self.plinder_dir,
- metrics=self.cfg.flow.cluster_metrics,
- thresholds=self.cfg.flow.cluster_thresholds,
- stop_on_cluster=self.cfg.flow.make_components_stop_on_cluster,
- skip_existing_clusters=not force_update,
+ batch_size=self.cfg.flow.collate_ligand_3d_scores_batch_size,
)
- return chunks
@utils.ingest_flow_control
- def make_components_and_communities(
- self, metric_thresholds: list[tuple[str, int]]
- ) -> None:
- force_update = (
- self.cfg.data.force_update or self.cfg.flow.make_components_force_update
+ def collate_ligand_3d_scores(self, shards: list[str]) -> None:
+ tasks.collate_ligand_3d_scores(
+ data_dir=self.plinder_dir,
+ shards=shards,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-ligand-3d-collate",
+ threads=self.cfg.flow.make_ligand_3d_scores_cpu,
)
- tasks.make_components_and_communities(
+
+ @utils.ingest_flow_control
+ def scatter_merge_ligand_3d_scores(self) -> list[list[str]]:
+ return tasks.scatter_scoring_query_shards(
data_dir=self.plinder_dir,
- metric_threshold=metric_thresholds,
- skip_existing_clusters=not force_update,
+ batch_size=self.cfg.flow.merge_ligand_3d_scores_batch_size,
)
@utils.ingest_flow_control
- def scatter_make_splits(self) -> list[list[tuple[DictConfig, str]]]:
- chunks: list[list[tuple[DictConfig, str]]] = tasks.scatter_make_splits(
+ def merge_ligand_3d_scores(self, shards: list[str]) -> None:
+ force_update = (
+ self.cfg.data.force_update or self.cfg.flow.make_batch_scores_force_update
+ )
+ tasks.merge_ligand_3d_scores(
data_dir=self.plinder_dir,
- split_config_dir=self.cfg.flow.split_config_dir,
+ shards=shards,
+ scorer_cfg=self.cfg.scorer,
+ force_update=force_update,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-ligand-3d-merge",
+ threads=self.cfg.flow.make_ligand_3d_scores_cpu,
)
- return chunks
@utils.ingest_flow_control
- def make_splits(self, cfg_and_path: list[tuple[DictConfig, str]]) -> None:
- tasks.make_splits(data_dir=self.plinder_dir, cfg_and_path=cfg_and_path)
+ def finalize_scores(self) -> None:
+ from plinder.data.pipeline.score import finalize_ligand_3d_artifacts
+
+ finalize_ligand_3d_artifacts(self.plinder_dir)
@utils.ingest_flow_control
- def scatter_compute_ligand_leakage(self) -> list[list[tuple[str, str, str]]]:
- chunks: list[list[tuple[str, str, str]]] = tasks.scatter_compute_ligand_leakage(
+ def scatter_export_ligand_similarity_scores(self) -> list[list[str]]:
+ return tasks.scatter_scoring_query_shards(
data_dir=self.plinder_dir,
- test_leakage=self.cfg.flow.test_leakage,
+ batch_size=self.cfg.flow.collate_ligand_3d_scores_batch_size,
)
- return chunks
@utils.ingest_flow_control
- def compute_ligand_leakage(self, inputs: list[tuple[str, str, str]]) -> None:
- tasks.compute_ligand_leakage(
- data_dir=self.plinder_dir,
- inputs=inputs,
+ def export_ligand_similarity_scores(self, shards: list[str]) -> None:
+ from plinder.data.pipeline.score import export_ligand_similarity_scores_batch
+
+ export_ligand_similarity_scores_batch(
+ self.plinder_dir,
+ output_dir=(self.plinder_dir / "exports" / "ligand_similarity_scores"),
+ shards=shards,
+ scratch_dir=(
+ Path(tempfile.gettempdir()) / "plinder-ligand-similarity-export"
+ ),
+ threads=self.cfg.flow.make_ligand_3d_scores_cpu,
)
@utils.ingest_flow_control
- def scatter_compute_protein_leakage(self) -> list[list[tuple[str, str, str]]]:
- chunks: list[
- list[tuple[str, str, str]]
- ] = tasks.scatter_compute_protein_leakage(
- data_dir=self.plinder_dir,
- test_leakage=self.cfg.flow.test_leakage,
+ def finalize_ligand_similarity_scores(self) -> None:
+ from plinder.data.pipeline.score import finalize_ligand_similarity_scores
+
+ finalize_ligand_similarity_scores(
+ self.plinder_dir,
+ source_dir=(self.plinder_dir / "exports" / "ligand_similarity_scores"),
+ output=self.plinder_dir / "exports" / "ligand_similarity_scores.parquet",
+ scratch_dir=(
+ Path(tempfile.gettempdir()) / "plinder-ligand-similarity-finalize"
+ ),
+ threads=self.cfg.flow.make_ligand_3d_scores_cpu,
)
- return chunks
@utils.ingest_flow_control
- def compute_protein_leakage(self, inputs: list[tuple[str, str, str]]) -> None:
- tasks.compute_protein_leakage(
- data_dir=self.plinder_dir,
- inputs=inputs,
+ def scatter_collate_alignments(self) -> list[list[str]]:
+ return tasks.scatter_collate_alignments(data_dir=self.plinder_dir)
+
+ @utils.ingest_flow_control
+ def collate_alignments(self, partition: list[str]) -> None:
+ tasks.collate_alignments(data_dir=self.plinder_dir, partition=partition)
+
+ @utils.ingest_flow_control
+ def finalize_alignments(self) -> None:
+ from plinder.data.pipeline.score import finalize_alignment_artifacts
+
+ finalize_alignment_artifacts(self.plinder_dir)
+
+ @utils.ingest_flow_control
+ def plan_score_batches(self) -> None:
+ from plinder.data.pipeline.score import plan_score_batches
+
+ plan_score_batches(
+ self.plinder_dir,
+ batch_size=self.cfg.flow.make_batch_scores_batch_size,
+ threads=self.cfg.flow.make_batch_scores_cpu,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-score-plan",
+ max_query_protein_chains=self.cfg.scorer.max_query_protein_chains,
+ max_query_proper_ligand_chains=(
+ self.cfg.scorer.max_query_proper_ligand_chains
+ ),
)
@utils.ingest_flow_control
- def scatter_make_links(self) -> list[list[str]]:
- chunks: list[list[str]] = tasks.scatter_make_links(
- data_dir=self.plinder_dir,
- search_dbs=self.cfg.scorer.sub_databases,
+ def plan_interface_scores(self) -> None:
+ from plinder.data.pipeline.score import plan_interface_scoring
+
+ plan_interface_scoring(
+ self.plinder_dir,
+ batch_size=self.cfg.flow.make_interface_scores_batch_size,
)
- return chunks
@utils.ingest_flow_control
- def make_links(self, search_dbs: list[str]) -> None:
- tasks.make_links(
- data_dir=self.plinder_dir,
- search_dbs=search_dbs,
+ def scatter_make_interface_scores(self) -> list[list[str]]:
+ from plinder.data.pipeline.score import (
+ INTERFACE_SCORE_WORK_RELATIVE,
+ _load_interface_score_plan,
+ )
+
+ plan = _load_interface_score_plan(self.plinder_dir)
+ work = (
+ pd.read_parquet(
+ self.plinder_dir / INTERFACE_SCORE_WORK_RELATIVE,
+ columns=["shard"],
+ )["shard"]
+ .astype(str)
+ .tolist()
)
+ batch_size = int(plan["batch_size"])
+ return [
+ work[start : start + batch_size]
+ for start in range(0, len(work), batch_size)
+ ] or [[]]
@utils.ingest_flow_control
- def make_linked_structures(self) -> None:
- force_update = (
- self.cfg.data.force_update
- or self.cfg.flow.make_linked_structures_force_update
+ def make_interface_scores(self, shards: list[str]) -> None:
+ if not shards:
+ return
+ from plinder.data.pipeline.score import score_interface_qcov_shards
+
+ score_interface_qcov_shards(
+ self.plinder_dir,
+ shards=shards,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-interface-scores",
+ threads=self.cfg.flow.make_interface_scores_cpu,
+ memory_limit=self.cfg.flow.make_interface_scores_memory_limit,
+ force_update=self.cfg.data.force_update,
+ )
+
+ @utils.ingest_flow_control
+ def finalize_interface_scores(self) -> None:
+ from plinder.data.pipeline.score import finalize_interface_similarity_scores
+
+ finalize_interface_similarity_scores(
+ self.plinder_dir,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-interface-finalize",
+ threads=self.cfg.flow.make_interface_scores_cpu,
+ memory_limit=self.cfg.flow.make_interface_scores_memory_limit,
)
- tasks.make_linked_structures(
+
+ @utils.ingest_flow_control
+ def scatter_collate_partitions(self) -> list[list[str]]:
+ chunks: list[list[str]] = tasks.scatter_collate_partitions()
+ # Holo scores are already published as two-character query shards by
+ # merge_ligand_3d_scores. Only linked apo/pred scores still use this
+ # partition collation path.
+ chunks = [
+ chunk
+ for chunk in chunks
+ if chunk
+ and chunk[0] in self.cfg.scorer.sub_databases
+ and chunk[0] in {"apo", "pred"}
+ ]
+ return chunks or [[]]
+
+ @utils.ingest_flow_control
+ def collate_partitions(self, partition: list[str]) -> None:
+ tasks.collate_partitions(
data_dir=self.plinder_dir,
- search_dbs=self.cfg.flow.sub_databases,
- cpu=self.cfg.flow.make_linked_structures_cpu,
- force_update=force_update,
+ partition=partition,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-score-partitions",
+ threads=self.cfg.flow.collate_partitions_cpu,
+ memory_limit=self.cfg.flow.collate_partitions_memory_limit,
)
@utils.ingest_flow_control
- def scatter_score_linked_structures(self) -> list[list[tuple[str, str]]]:
- chunks: list[list[tuple[str, str]]] = tasks.scatter_score_linked_structures(
+ def make_linked_apo_structures(self) -> None:
+ if "apo" not in self.cfg.scorer.sub_databases:
+ LOG.info("make_linked_apo_structures: apo scoring is disabled")
+ return
+ tasks.make_linked_apo_structures(
data_dir=self.plinder_dir,
- search_dbs=self.cfg.flow.sub_databases,
- batch_size=self.cfg.flow.score_linked_structures_batch_size,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-linked-apo",
+ threads=self.cfg.flow.collate_partitions_cpu,
+ memory_limit=self.cfg.flow.collate_partitions_memory_limit,
+ )
+
+ def _cluster_entities(
+ self,
+ ) -> list[tuple[Literal["ligand", "interface"], list[str]]]:
+ entities: list[tuple[Literal["ligand", "interface"], list[str]]] = [
+ ("ligand", list(self.cfg.flow.cluster_metrics))
+ ]
+ entities.append(("interface", ["interface_qcov", "interface_side_qcov"]))
+ return entities
+
+ @utils.ingest_flow_control
+ def plan_clusters(self) -> None:
+ from plinder.data.pipeline.score import plan_clustering
+
+ for entity_type, metrics in self._cluster_entities():
+ plan_clustering(
+ self.plinder_dir,
+ metrics=metrics,
+ thresholds=list(self.cfg.flow.cluster_thresholds),
+ source_batch_size=self.cfg.flow.symmetric_edge_source_batch_size,
+ cover_batch_size=1,
+ symmetric_bucket_count=self.cfg.flow.symmetric_edge_bucket_count,
+ entity_type=entity_type,
+ )
+
+ @utils.ingest_flow_control
+ def scatter_make_symmetric_edge_fragments(self) -> list[dict[str, Any]]:
+ from plinder.data import clusters
+
+ work: list[dict[str, Any]] = []
+ for entity_type, _ in self._cluster_entities():
+ plan = clusters.load_symmetric_edge_plan(
+ self.plinder_dir,
+ entity_type=entity_type,
+ )
+ work.extend(
+ {"entity_type": entity_type, "batches": [batch]}
+ for batch in plan["batches"]
+ )
+ return work or [{}]
+
+ @utils.ingest_flow_control
+ def make_symmetric_edge_fragments(self, work: dict[str, Any]) -> None:
+ if not work:
+ return
+ tasks.make_symmetric_edge_fragments(
+ data_dir=self.plinder_dir,
+ batches=work["batches"],
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-symmetric-fragments",
+ threads=self.cfg.flow.clustering_cpu,
+ force_update=self.cfg.data.force_update,
+ entity_type=work["entity_type"],
+ )
+
+ @utils.ingest_flow_control
+ def scatter_make_symmetric_edge_shards(self) -> list[dict[str, Any]]:
+ from plinder.data import clusters
+
+ work: list[dict[str, Any]] = []
+ for entity_type, _ in self._cluster_entities():
+ plan = clusters.load_symmetric_edge_plan(
+ self.plinder_dir,
+ entity_type=entity_type,
+ )
+ for metric in plan["metrics"]:
+ for bucket in range(int(plan["bucket_count"])):
+ work.append(
+ {
+ "entity_type": entity_type,
+ "metric_buckets": [(str(metric), bucket)],
+ }
+ )
+ return work or [{}]
+
+ @utils.ingest_flow_control
+ def make_symmetric_edge_shards(self, work: dict[str, Any]) -> None:
+ if not work:
+ return
+ tasks.make_symmetric_edge_shards(
+ data_dir=self.plinder_dir,
+ metric_buckets=work["metric_buckets"],
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-symmetric-edges",
+ threads=self.cfg.flow.clustering_cpu,
+ force_update=self.cfg.data.force_update,
+ entity_type=work["entity_type"],
+ )
+
+ @utils.ingest_flow_control
+ def scatter_make_component_reductions(self) -> list[Any]:
+ work: list[dict[str, Any]] = []
+ for entity_type, metrics in self._cluster_entities():
+ batches = tasks.scatter_component_reduction_sources(
+ data_dir=self.plinder_dir,
+ metrics=metrics,
+ batch_size=self.cfg.flow.component_reduction_source_batch_size,
+ entity_type=entity_type,
+ )
+ work.extend(
+ {"entity_type": entity_type, "metrics": metrics, "sources": batch}
+ for batch in batches
+ if batch
+ )
+ return work or [{}]
+
+ @utils.ingest_flow_control
+ def make_component_reductions(self, work: Any) -> None:
+ if not work:
+ return
+ entity_type = work["entity_type"]
+ metrics = work["metrics"]
+ source_paths = work["sources"]
+ tasks.make_component_reductions(
+ data_dir=self.plinder_dir,
+ source_paths=source_paths,
+ metrics=metrics,
+ thresholds=self.cfg.flow.cluster_thresholds,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-component-reductions",
+ force_update=self.cfg.data.force_update,
+ metric_workers=self.cfg.flow.component_reduction_metric_workers,
+ entity_type=entity_type,
)
- return chunks
@utils.ingest_flow_control
- def score_linked_structures(self, system_ids: list[tuple[str, str]]) -> None:
+ def merge_component_reductions(self) -> None:
+ for entity_type, metrics in self._cluster_entities():
+ tasks.merge_component_reductions(
+ data_dir=self.plinder_dir,
+ metrics=metrics,
+ thresholds=self.cfg.flow.cluster_thresholds,
+ entity_type=entity_type,
+ )
+
+ @utils.ingest_flow_control
+ def scatter_make_set_covers(self) -> list[Any]:
+ force_update = (
+ self.cfg.data.force_update or self.cfg.flow.make_components_force_update
+ )
+ work: list[dict[str, Any]] = []
+ for entity_type, metrics in self._cluster_entities():
+ batches = tasks.scatter_make_set_covers(
+ data_dir=self.plinder_dir,
+ metrics=metrics,
+ thresholds=self.cfg.flow.cluster_thresholds,
+ stop_on_cluster=self.cfg.flow.make_components_stop_on_cluster,
+ skip_existing_clusters=not force_update,
+ entity_type=entity_type,
+ )
+ work.extend(
+ {"entity_type": entity_type, "metric_threshold": batch}
+ for batch in batches
+ if batch
+ )
+ return work or [{}]
+
+ @utils.ingest_flow_control
+ def make_set_covers(self, work: Any) -> None:
force_update = (
- self.cfg.data.force_update
- or self.cfg.flow.score_linked_structures_force_update
+ self.cfg.data.force_update or self.cfg.flow.make_components_force_update
)
- tasks.score_linked_structures(
+ if not work:
+ return
+ entity_type = work["entity_type"]
+ metric_thresholds = work["metric_threshold"]
+ tasks.make_set_covers(
data_dir=self.plinder_dir,
- search_dbs=self.cfg.flow.sub_databases,
- system_ids=system_ids,
- cpu=self.cfg.flow.score_linked_structures_cpu,
- force_update=force_update,
+ metric_threshold=metric_thresholds,
+ skip_existing_clusters=not force_update,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-set-covers",
+ threads=self.cfg.flow.clustering_cpu,
+ entity_type=entity_type,
)
- return
@utils.ingest_flow_control
- def join_score_linked_structures(self, outputs: list[None]) -> None:
- utils.mp_pack_linked_structures(data_dir=self.plinder_dir, structures=False)
- utils.consolidate_linked_scores(data_dir=self.plinder_dir)
+ def scatter_make_directed_set_covers(self) -> list[Any]:
+ force_update = (
+ self.cfg.data.force_update or self.cfg.flow.make_components_force_update
+ )
+ work: list[dict[str, Any]] = []
+ for entity_type, metrics in self._cluster_entities():
+ batches = tasks.scatter_make_directed_set_covers(
+ data_dir=self.plinder_dir,
+ metrics=metrics,
+ thresholds=self.cfg.flow.cluster_thresholds,
+ stop_on_cluster=self.cfg.flow.make_components_stop_on_cluster,
+ skip_existing=not force_update,
+ entity_type=entity_type,
+ )
+ work.extend(
+ {"entity_type": entity_type, "metric_threshold": batch}
+ for batch in batches
+ if batch
+ )
+ return work or [{}]
+
+ @utils.ingest_flow_control
+ def make_directed_set_covers(self, work: Any) -> None:
+ force_update = (
+ self.cfg.data.force_update or self.cfg.flow.make_components_force_update
+ )
+ if not work:
+ return
+ entity_type = work["entity_type"]
+ metric_thresholds = work["metric_threshold"]
+ tasks.make_directed_set_covers(
+ data_dir=self.plinder_dir,
+ metric_threshold=metric_thresholds,
+ skip_existing=not force_update,
+ scratch_dir=Path(tempfile.gettempdir()) / "plinder-directed-set-covers",
+ threads=self.cfg.flow.clustering_cpu,
+ entity_type=entity_type,
+ )
+
+ @utils.ingest_flow_control
+ def summarize_clusters(self) -> None:
+ for entity_type, metrics in self._cluster_entities():
+ tasks.summarize_clusters(
+ data_dir=self.plinder_dir,
+ metrics=metrics,
+ thresholds=self.cfg.flow.cluster_thresholds,
+ entity_type=entity_type,
+ )
+
+ @utils.ingest_flow_control
+ def finalize_index(self) -> None:
+ tasks.finalize_index(data_dir=self.plinder_dir)
def run_stage(self, stage: str) -> None:
"""
diff --git a/src/plinder/data/pipeline/public_release.py b/src/plinder/data/pipeline/public_release.py
new file mode 100644
index 000000000..efcb05f64
--- /dev/null
+++ b/src/plinder/data/pipeline/public_release.py
@@ -0,0 +1,166 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Build a clean public release tree from a working ingest."""
+
+from __future__ import annotations
+
+import argparse
+import os
+import shutil
+import tempfile
+from pathlib import Path
+
+from plinder.core.release import RELEASE_PATHS, RELEASE_TABLES
+
+_FILE_ARTIFACTS = (
+ *(table["artifact"] for table in RELEASE_TABLES.values()),
+ "ligand_similarity_scores",
+ "interface_similarity_scores",
+ "interface_half_similarity_scores",
+)
+_PARQUET_DIRECTORIES = (
+ "protein_similarity_scores",
+ "monomer_similarity_scores",
+ "ligand_archives",
+ "ligand_scores",
+ "alignment_cigars",
+)
+_SAMPLING_DIRECTORIES = ("ligand_sampling", "interface_sampling")
+_SEARCH_DATABASES = (
+ "holo_mmseqs",
+ "holo_foldseek",
+ "monomer_mmseqs",
+ "monomer_foldseek",
+)
+# Monomer artifacts exist only when the ingest had monomer chains to search.
+_OPTIONAL = {"monomer_similarity_scores", "monomer_mmseqs", "monomer_foldseek"}
+
+
+def _public_files(source: Path) -> list[Path]:
+ files = {Path(RELEASE_PATHS[name]) for name in _FILE_ARTIFACTS}
+ for name in _PARQUET_DIRECTORIES:
+ directory = source / RELEASE_PATHS.get(name, name)
+ if not directory.is_dir():
+ if name in _OPTIONAL:
+ continue
+ raise FileNotFoundError(directory)
+ files.update(path.relative_to(source) for path in directory.rglob("*.parquet"))
+ for name in _SAMPLING_DIRECTORIES:
+ directory = source / RELEASE_PATHS.get(name, name)
+ if not directory.is_dir():
+ raise FileNotFoundError(directory)
+ for cover in ("set_cover", "directed_set_cover"):
+ files.update(
+ path.relative_to(source)
+ for path in (directory / cover).glob("metric=*/threshold=*.parquet")
+ )
+
+ database_root = source / RELEASE_PATHS["search_databases"]
+ for name in _SEARCH_DATABASES:
+ directory = database_root / name
+ if not directory.is_dir():
+ if name in _OPTIONAL:
+ continue
+ raise FileNotFoundError(directory)
+ files.update(
+ path.relative_to(source)
+ for path in directory.rglob("*")
+ if path.is_file() and path.suffix != ".json"
+ )
+ shadowed = database_root / "shadowed_entries.parquet"
+ if shadowed.is_file():
+ files.add(shadowed.relative_to(source))
+ overlay = database_root / "weekly_delta"
+ if overlay.is_dir():
+ files.update(
+ path.relative_to(source)
+ for path in overlay.rglob("*")
+ if path.is_file() and path.suffix != ".json"
+ )
+
+ missing = [str(source / path) for path in files if not (source / path).is_file()]
+ if missing:
+ raise FileNotFoundError(f"missing public release files: {missing[:10]}")
+ included = {source / item for item in files}
+ for relative in files:
+ path = source / relative
+ if path.is_symlink():
+ if Path(os.readlink(path)).is_absolute():
+ raise ValueError(f"absolute link in public release: {path}")
+ if path.resolve() not in included:
+ raise ValueError(
+ f"search database link leaves the public release: {path}"
+ )
+ return sorted(files)
+
+
+def prepare_public_release(
+ source: Path, destination: Path, *, replace: bool = False, copy: bool = False
+) -> int:
+ """Stage only public files beside an ingest; return the number of files."""
+ source = source.resolve(strict=True)
+ if destination.is_symlink():
+ raise ValueError("public release destination cannot be a symlink")
+ destination = destination.parent.resolve() / destination.name
+ if (
+ source == destination
+ or source in destination.parents
+ or destination in source.parents
+ ):
+ raise ValueError("working and public release directories must be separate")
+ if destination.exists() and not replace:
+ raise FileExistsError(destination)
+ if destination.exists() and not destination.is_dir():
+ raise NotADirectoryError(destination)
+ files = _public_files(source)
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ staging = Path(
+ tempfile.mkdtemp(prefix=f".{destination.name}-", dir=destination.parent)
+ )
+ previous = staging.with_name(staging.name + "-previous")
+ try:
+ for relative in files:
+ original = source / relative
+ target = staging / relative
+ target.parent.mkdir(parents=True, exist_ok=True)
+ if original.is_symlink():
+ target.symlink_to(os.readlink(original))
+ elif copy:
+ shutil.copy2(original, target)
+ else:
+ os.link(original, target)
+ if destination.exists():
+ destination.rename(previous)
+ try:
+ staging.rename(destination)
+ except OSError:
+ if previous.exists():
+ previous.rename(destination)
+ raise
+ if previous.exists():
+ shutil.rmtree(previous)
+ finally:
+ if staging.exists():
+ shutil.rmtree(staging)
+ return len(files)
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument("working", type=Path, help="completed working ingest")
+ parser.add_argument("public", type=Path, help="separate public release directory")
+ parser.add_argument(
+ "--replace", action="store_true", help="replace an existing public tree"
+ )
+ parser.add_argument(
+ "--copy", action="store_true", help="copy bytes instead of hard-linking"
+ )
+ args = parser.parse_args()
+ count = prepare_public_release(
+ args.working, args.public, replace=args.replace, copy=args.copy
+ )
+ print(f"Prepared {count} public files in {args.public}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/plinder/data/pipeline/score.py b/src/plinder/data/pipeline/score.py
new file mode 100644
index 000000000..51a4486af
--- /dev/null
+++ b/src/plinder/data/pipeline/score.py
@@ -0,0 +1,8335 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Shared CLI for sharded protein search and derived scoring."""
+
+from __future__ import annotations
+
+import argparse
+import hashlib
+import heapq
+import json
+import math
+import os
+from collections.abc import Iterable, Mapping
+from pathlib import Path
+from shutil import copyfile, rmtree
+from textwrap import dedent
+from time import perf_counter
+from typing import Any, cast
+
+import pandas as pd
+import pyarrow as pa
+import pyarrow.compute as pc
+import pyarrow.parquet as pq
+
+from plinder.core.scores.mapping import cigar_alignment_sql
+from plinder.core.scores.metrics import (
+ DEFAULT_CLUSTER_METRICS,
+ is_chemical_cluster_metric,
+ maximum_weight_bipartite_assignment,
+)
+from plinder.core.utils import schemas
+from plinder.core.utils.files import write_json_atomic
+from plinder.core.utils.log import setup_logger
+from plinder.data import clusters, databases
+from plinder.data.annotations.interface_utils import DEFAULT_MIN_INTERFACE_RESIDUES
+from plinder.data.pipeline import collate, config, tasks
+
+LOG = setup_logger(__name__)
+
+MANIFEST_RELATIVE = Path("manifests/protein_scoring_queries.parquet")
+PLAN_RELATIVE = Path("manifests/protein_scoring_plan.json")
+LINKED_APO_QUERY_MANIFEST_RELATIVE = Path("manifests/linked_apo_queries.parquet")
+INTERFACE_APO_QUERY_MANIFEST_RELATIVE = Path(
+ "manifests/interface_apo_search_queries.parquet"
+)
+LINKED_APO_PLAN_RELATIVE = Path("manifests/linked_apo_plan.json")
+FOLDSEEK_INPUT_RELATIVE = Path("manifests/foldseek_createdb_inputs.tsv")
+SCORE_WORK_RELATIVE = Path("manifests/protein_scoring_work.parquet")
+LIGAND_3D_CANDIDATE_MANIFEST_RELATIVE = Path("manifests/ligand_3d_candidates.parquet")
+LIGAND_3D_WORK_RELATIVE = Path("manifests/ligand_3d_work.parquet")
+LIGAND_3D_RETRY_WORK_RELATIVE = Path("manifests/ligand_3d_retry_work.parquet")
+LIGAND_3D_PAIR_VALIDATION_RELATIVE = Path("scores/ligand_3d_pair_validation.json")
+LIGAND_ARCHIVE_MANIFEST_RELATIVE = Path("ligand_archives/manifest.json")
+DROPPED_QUERY_RELATIVE = Path("manifests/dropped_queries.parquet")
+SCORE_REPAIR_RELATIVE = Path("manifests/score_repair.parquet")
+BOUNDED_SCORE_REPAIR_RELATIVE = Path("manifests/bounded_score_repair.parquet")
+SCORE_REPAIR_LIGAND_3D_RELATIVE = Path("manifests/score_repair_ligand_3d.parquet")
+SCORE_REPAIR_DROP_DIR_RELATIVE = Path("manifests/score_repair_query_drops")
+SCORE_REPAIR_DROP_RELATIVE = Path("manifests/score_repair_incomplete_queries.parquet")
+INTERFACE_SCORE_WORK_RELATIVE = Path("manifests/interface_scoring_work.parquet")
+INTERFACE_SCORE_PLAN_RELATIVE = Path("manifests/interface_scoring_plan.json")
+INTERFACE_SCORE_REPAIR_RELATIVE = Path("manifests/interface_scoring_repair.parquet")
+INTERFACE_SCORE_REPAIR_PLAN_RELATIVE = Path("manifests/interface_scoring_repair.json")
+INTERFACE_SCORE_ROOT_RELATIVE = Path("interface_scores")
+INTERFACE_SCORE_REPAIR_ROOT_RELATIVE = Path("interface_score_repairs")
+INTERFACE_SIMILARITY_EXPORT_RELATIVE = Path(
+ "exports/interface_similarity_scores.parquet"
+)
+INTERFACE_HALF_SIMILARITY_EXPORT_RELATIVE = Path(
+ "exports/interface_half_similarity_scores.parquet"
+)
+LIGAND_POCKET_QCOV_REPRESENTATIVE_ROOT_RELATIVE = Path(
+ "scores/ligand_pocket_qcov_representatives"
+)
+LIGAND_POCKET_SCORE_WORK_RELATIVE = Path(
+ "manifests/ligand_pocket_scoring_queries.parquet"
+)
+LIGAND_POCKET_SCORE_PLAN_RELATIVE = Path("manifests/ligand_pocket_scoring_plan.json")
+DEFAULT_CLUSTER_THRESHOLDS = (30, 50, 70, 90, 100)
+MINIMUM_STORED_INTERFACE_SIDE_SIMILARITY = min(DEFAULT_CLUSTER_THRESHOLDS)
+
+
+def _atomic_parquet(frame: pd.DataFrame, path: Path) -> None:
+ path.parent.mkdir(exist_ok=True, parents=True)
+ temporary = path.with_suffix(path.suffix + ".tmp")
+ frame.to_parquet(temporary, index=False)
+ temporary.replace(path)
+
+
+def _source_signature(path: Path) -> dict[str, int | str]:
+ stat = path.stat()
+ return {
+ "path": str(path.resolve()),
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ }
+
+
+def _same_file_signature(stored: Any, current: dict[str, int | str]) -> bool:
+ return isinstance(stored, dict) and all(
+ stored.get(key) == current[key] for key in ("size", "mtime_ns")
+ )
+
+
+def dropped_query_ids(data_dir: Path) -> set[str]:
+ """Return PDB IDs intentionally retained only as scoring targets."""
+ path = data_dir / DROPPED_QUERY_RELATIVE
+ if not path.is_file():
+ return set()
+ frame = pd.read_parquet(path, columns=["pdb_id"])
+ return set(frame["pdb_id"].dropna().astype(str))
+
+
+def active_scoring_query_ids(data_dir: Path) -> set[str]:
+ """Return planned derived-score queries after intentional query drops."""
+ work = pd.read_parquet(data_dir / SCORE_WORK_RELATIVE, columns=["pdb_id"])
+ return set(work["pdb_id"].dropna().astype(str)).difference(
+ dropped_query_ids(data_dir)
+ )
+
+
+def published_scoring_query_ids(data_dir: Path) -> set[str]:
+ """Return full queries plus bounded reciprocal queries with published rows."""
+ query_ids = active_scoring_query_ids(data_dir)
+ bounded = data_dir / BOUNDED_SCORE_REPAIR_RELATIVE
+ if bounded.is_file():
+ planned = set(
+ pd.read_parquet(data_dir / SCORE_WORK_RELATIVE, columns=["pdb_id"])[
+ "pdb_id"
+ ]
+ .dropna()
+ .astype(str)
+ )
+ dropped = dropped_query_ids(data_dir)
+ frame = pd.read_parquet(bounded, columns=["pdb_id", "repair_mode"])
+ bounded_ids = set(
+ frame.loc[frame["repair_mode"].eq("bounded"), "pdb_id"].dropna().astype(str)
+ ).intersection(planned, dropped)
+ repair_started_ns = bounded.stat().st_mtime_ns
+ query_ids.update(
+ pdb_id
+ for pdb_id in bounded_ids
+ if _score_repair_query_is_current(
+ data_dir, pdb_id, repair_started_ns=repair_started_ns
+ )
+ )
+ return query_ids
+
+
+def _load_pdb_id_manifest(path: Path) -> list[str]:
+ """Load a PDB-ID column from Parquet or a newline-delimited ingest manifest."""
+ if not path.is_file():
+ raise FileNotFoundError(path)
+ if path.suffix == ".parquet":
+ frame = pd.read_parquet(path, columns=["pdb_id"])
+ values = frame["pdb_id"].dropna().astype(str).str.lower().tolist()
+ else:
+ from plinder.data.pipeline.ingest import load_manifest
+
+ values = load_manifest(path)
+ if len(values) != len(set(values)):
+ raise ValueError(f"PDB manifest contains duplicate IDs: {path}")
+ return cast(list[str], values)
+
+
+def _packed_score_query_ids(
+ data_dir: Path,
+ query_ids: set[str],
+ *,
+ threads: int,
+ memory_limit: str,
+) -> set[str]:
+ """Return requested queries that have rows in the packed holo score store."""
+ if not query_ids:
+ return set()
+ paths = sorted(
+ {
+ data_dir / "scores/search_db=holo" / f"{pdb_id[1:3]}.parquet"
+ for pdb_id in query_ids
+ }
+ )
+ paths = [path for path in paths if path.is_file()]
+ if not paths:
+ return set()
+
+ import duckdb
+
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.register(
+ "requested_queries",
+ pd.DataFrame({"query_entry": sorted(query_ids)}),
+ )
+ paths_sql = ", ".join(f"'{path.as_posix()}'" for path in paths)
+ observed = connection.sql(
+ f"""
+ SELECT DISTINCT split_part(scores.query_system, '__', 1) AS query_entry
+ FROM read_parquet(
+ [{paths_sql}], union_by_name=true, hive_partitioning=false
+ ) AS scores
+ INNER JOIN requested_queries
+ ON split_part(scores.query_system, '__', 1)
+ = requested_queries.query_entry
+ """
+ ).df()
+ connection.close()
+ return set(observed["query_entry"].astype(str))
+
+
+def _packed_candidate_query_ids(
+ data_dir: Path,
+ query_ids: set[str],
+ *,
+ threads: int,
+ memory_limit: str,
+) -> set[str]:
+ """Return requested queries present in packed ligand-3D candidates."""
+ if not query_ids:
+ return set()
+ paths = sorted(
+ {
+ data_dir
+ / "scores/ligand_3d_candidate_shards"
+ / f"shard={pdb_id[1:3]}.parquet"
+ for pdb_id in query_ids
+ }
+ )
+ paths = [path for path in paths if path.is_file()]
+ if not paths:
+ return set()
+
+ import duckdb
+
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.register(
+ "requested_queries",
+ pd.DataFrame({"query_entry": sorted(query_ids)}),
+ )
+ paths_sql = ", ".join(f"'{path.as_posix()}'" for path in paths)
+ observed = connection.sql(
+ f"""
+ SELECT DISTINCT candidates.query_entry
+ FROM read_parquet(
+ [{paths_sql}], union_by_name=true, hive_partitioning=false
+ ) AS candidates
+ INNER JOIN requested_queries USING (query_entry)
+ """
+ ).df()
+ connection.close()
+ return set(observed["query_entry"].astype(str))
+
+
+def _query_eligible_entry_ids(
+ annotation: pd.DataFrame,
+ entry_chains: pd.DataFrame,
+ *,
+ max_query_protein_chains: int,
+ max_query_proper_ligand_chains: int,
+) -> set[str]:
+ """Return entries with at least one query-eligible holo system.
+
+ The ligand limit applies only to proper ligand instances. Keeping this
+ calculation at system granularity avoids excluding a useful query because
+ its system also contains ions, waters, artifacts, or other non-proper
+ ligands.
+ """
+ required = {
+ "entry_pdb_id",
+ "system_id",
+ "system_type",
+ "system_protein_chains_asym_id",
+ "ligand_id",
+ "ligand_is_proper",
+ }
+ missing = required.difference(annotation.columns)
+ if missing:
+ raise ValueError(f"annotation is missing query eligibility columns: {missing}")
+ holo = annotation.loc[
+ annotation["system_type"].astype(str).eq("holo"), list(required)
+ ].copy()
+ if holo.empty:
+ return set()
+ keys = ["entry_pdb_id", "system_id"]
+ chain_required = {"entry_pdb_id", "chain_asym_id", "chain_receptor_type"}
+ missing_chains = chain_required.difference(entry_chains.columns)
+ if missing_chains:
+ raise ValueError(
+ f"entry chains are missing eligibility columns: {missing_chains}"
+ )
+ protein_chains = {
+ (str(row.entry_pdb_id), str(row.chain_asym_id))
+ for row in entry_chains.loc[
+ entry_chains["chain_receptor_type"].fillna("").astype(str).eq("protein")
+ ].itertuples(index=False)
+ }
+ system_chains = holo.drop_duplicates(keys).set_index(keys)[
+ "system_protein_chains_asym_id"
+ ]
+ system_protein_counts = pd.Series(
+ {
+ (entry_id, system_id): len(
+ {
+ str(instance_chain)
+ for instance_chain in (
+ chains
+ if isinstance(chains, Iterable)
+ and not isinstance(chains, (str, bytes))
+ else []
+ )
+ if (str(entry_id), str(instance_chain).split(".", 1)[-1])
+ in protein_chains
+ }
+ )
+ for (entry_id, system_id), chains in system_chains.items()
+ },
+ name="protein_chains",
+ )
+ system_protein_counts.index = system_protein_counts.index.set_names(keys)
+ systems = system_protein_counts.to_frame()
+ proper = holo["ligand_is_proper"].fillna(False).astype(bool)
+ proper_counts = (
+ holo.loc[proper]
+ .groupby(keys, observed=True, sort=False)["ligand_id"]
+ .nunique()
+ .rename("proper_ligand_chains")
+ )
+ systems = systems.join(proper_counts, how="left").fillna(
+ {"proper_ligand_chains": 0}
+ )
+ eligible = systems[
+ systems["protein_chains"].gt(0)
+ & systems["protein_chains"].le(max_query_protein_chains)
+ & systems["proper_ligand_chains"].gt(0)
+ & systems["proper_ligand_chains"].le(max_query_proper_ligand_chains)
+ ]
+ return set(eligible.index.get_level_values("entry_pdb_id").astype(str))
+
+
+def _assign_repair_batches(
+ records: list[dict[str, Any]],
+ *,
+ batch_size: int,
+ index_offset: int,
+) -> int:
+ """Balance repair work while keeping every batch below its row limit."""
+ batch_count = math.ceil(len(records) / batch_size)
+ heap = [(0, 0, index_offset + index) for index in range(batch_count)]
+ heapq.heapify(heap)
+ for record in sorted(
+ records,
+ key=lambda item: (-int(item["estimated_work"]), str(item["pdb_id"])),
+ ):
+ load, count, index = heapq.heappop(heap)
+ record["repair_batch_index"] = index
+ count += 1
+ if count < batch_size:
+ heapq.heappush(heap, (load + int(record["estimated_work"]), count, index))
+ return batch_count
+
+
+def plan_score_repair(
+ data_dir: Path,
+ *,
+ affected_manifest: Path,
+ additional_full_query_manifest: Path | None = None,
+ additional_target_query_manifest: Path | None = None,
+ output_path: Path | None = None,
+ batch_size: int = 10,
+ target_batch_size: int | None = None,
+ threads: int = 4,
+ scratch_dir: Path | None = None,
+ memory_limit: str = "32GB",
+) -> dict[str, Any]:
+ """Plan full-query and target-only rescoring for affected PDB entries.
+
+ Extra full queries are rescored against all targets. Extra target queries
+ are checked against affected targets even if their old hits disappeared.
+ """
+ if target_batch_size is None:
+ target_batch_size = batch_size
+ if min(batch_size, target_batch_size, threads) < 1:
+ raise ValueError("repair batch size and threads must be positive")
+ affected = set(_load_pdb_id_manifest(affected_manifest))
+ if not affected:
+ raise ValueError("affected-entry repair manifest is empty")
+ protein_queries = set(
+ pd.read_parquet(data_dir / MANIFEST_RELATIVE, columns=["pdb_id"])[
+ "pdb_id"
+ ].astype(str)
+ ).difference(dropped_query_ids(data_dir))
+ prior_plan = _load_plan(data_dir)
+ max_query_protein_chains = int(prior_plan["score_max_query_protein_chains"])
+ max_query_proper_ligand_chains = int(
+ prior_plan["score_max_query_proper_ligand_chains"]
+ )
+ annotation = pd.read_parquet(
+ data_dir / "index/annotation_table.parquet",
+ columns=[
+ "entry_pdb_id",
+ "system_id",
+ "system_type",
+ "system_protein_chains_asym_id",
+ "ligand_id",
+ "ligand_is_proper",
+ ],
+ )
+ entry_chains = pd.read_parquet(
+ data_dir / "index/entry_chains.parquet",
+ columns=["entry_pdb_id", "chain_asym_id", "chain_receptor_type"],
+ )
+ eligible_queries = _query_eligible_entry_ids(
+ annotation,
+ entry_chains,
+ max_query_protein_chains=max_query_protein_chains,
+ max_query_proper_ligand_chains=max_query_proper_ligand_chains,
+ )
+ active = protein_queries.intersection(eligible_queries)
+ planned_active = active_scoring_query_ids(data_dir)
+ if active != planned_active:
+ raise RuntimeError(
+ "the protein-scoring work manifest does not match the repaired index; "
+ "rerun plan-score-batches before planning score repair"
+ )
+ requested_additional_full = (
+ set(_load_pdb_id_manifest(additional_full_query_manifest))
+ if additional_full_query_manifest is not None
+ else set()
+ )
+ additional_full = requested_additional_full.intersection(active)
+ full_queries = affected.intersection(active).union(additional_full)
+ additional_target_queries = (
+ (
+ set(_load_pdb_id_manifest(additional_target_query_manifest))
+ if additional_target_query_manifest is not None
+ else set()
+ )
+ .intersection(active)
+ .difference(full_queries)
+ )
+ existing_affected_queries = {
+ pdb_id
+ for pdb_id in affected
+ if (
+ data_dir / "dbs" / "subdbs" / "search_db=holo" / f"{pdb_id}.parquet"
+ ).is_file()
+ }
+ inactive_affected = affected.difference(active)
+ existing_affected_queries.update(
+ _packed_score_query_ids(
+ data_dir,
+ inactive_affected,
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ )
+ existing_affected_queries.update(
+ _packed_candidate_query_ids(
+ data_dir,
+ inactive_affected,
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ )
+ inactive_queries = existing_affected_queries.difference(active)
+ alignment_paths = sorted(
+ (data_dir / "alignment_cigars" / "search_db=holo").glob(
+ "alignment_type=*/shard=*.parquet"
+ )
+ )
+ if not alignment_paths:
+ raise FileNotFoundError("no mapped holo alignment shards found")
+
+ import duckdb
+
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ if scratch_dir is not None:
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ connection.register(
+ "affected_targets", pd.DataFrame({"target_entry": sorted(affected)})
+ )
+ connection.register("active_queries", pd.DataFrame({"query_entry": sorted(active)}))
+ connection.register(
+ "affected_queries", pd.DataFrame({"affected_query": sorted(full_queries)})
+ )
+ paths_sql = ", ".join(f"'{path.as_posix()}'" for path in alignment_paths)
+ hits = connection.sql(
+ f"""
+ SELECT
+ alignments.query_entry,
+ list_sort(
+ list(DISTINCT alignments.target_entry)
+ FILTER (WHERE affected_targets.target_entry IS NOT NULL)
+ ) AS target_entries,
+ count(*) FILTER (
+ WHERE affected_targets.target_entry IS NOT NULL
+ )::BIGINT AS target_alignment_rows,
+ count(*) FILTER (
+ WHERE affected_queries.affected_query IS NOT NULL
+ )::BIGINT AS full_alignment_rows
+ FROM read_parquet([{paths_sql}], union_by_name=true) AS alignments
+ INNER JOIN active_queries USING (query_entry)
+ LEFT JOIN affected_targets USING (target_entry)
+ LEFT JOIN affected_queries
+ ON alignments.query_entry = affected_queries.affected_query
+ WHERE affected_targets.target_entry IS NOT NULL
+ OR affected_queries.affected_query IS NOT NULL
+ GROUP BY alignments.query_entry
+ """
+ ).df()
+ connection.close()
+
+ targets_by_query: dict[str, list[str]] = {}
+ work_by_query: dict[str, int] = {}
+ if not hits.empty:
+ for row in hits.itertuples(index=False):
+ query_id = str(row.query_entry)
+ target_entries = row.target_entries
+ targets_by_query[query_id] = (
+ list(map(str, target_entries))
+ if isinstance(target_entries, Iterable)
+ and not isinstance(target_entries, (str, bytes))
+ else []
+ )
+ work_by_query[query_id] = (
+ int(row.full_alignment_rows)
+ if query_id in full_queries
+ else int(row.target_alignment_rows)
+ )
+
+ for query_id in additional_target_queries:
+ targets_by_query[query_id] = sorted(
+ set(targets_by_query.get(query_id, [])) | affected
+ )
+ work_by_query[query_id] = max(1, work_by_query.get(query_id, 0))
+
+ missing_cache_queries = {
+ pdb_id
+ for pdb_id in set(targets_by_query).difference(full_queries)
+ if not all(
+ path.is_file() for path in _score_repair_query_paths(data_dir, pdb_id)
+ )
+ }
+ full_queries.update(missing_cache_queries)
+
+ all_queries = sorted(
+ set(targets_by_query).union(full_queries).union(inactive_queries)
+ )
+ if not all_queries:
+ raise ValueError("no active score queries are affected by the repair")
+ score_work_path = data_dir / SCORE_WORK_RELATIVE
+ full_work = {pdb_id: work_by_query.get(pdb_id, 1) for pdb_id in full_queries}
+ if score_work_path.is_file():
+ score_work = pd.read_parquet(
+ score_work_path, columns=["pdb_id", "estimated_work"]
+ )
+ for row in score_work.itertuples(index=False):
+ pdb_id = str(row.pdb_id)
+ if pdb_id in full_queries:
+ full_work[pdb_id] = max(
+ full_work.get(pdb_id, 1), max(1, int(row.estimated_work))
+ )
+ records: list[dict[str, Any]] = [
+ {
+ "pdb_id": pdb_id,
+ "repair_mode": (
+ "full"
+ if pdb_id in full_queries
+ else "drop"
+ if pdb_id in inactive_queries
+ else "targets"
+ ),
+ "target_pdb_ids": (
+ []
+ if pdb_id in full_queries or pdb_id in inactive_queries
+ else targets_by_query[pdb_id]
+ ),
+ "affected_target_count": (
+ 0
+ if pdb_id in full_queries or pdb_id in inactive_queries
+ else len(targets_by_query[pdb_id])
+ ),
+ "estimated_work": (
+ full_work.get(pdb_id, 1)
+ if pdb_id in full_queries
+ else 1
+ if pdb_id in inactive_queries
+ else max(1, work_by_query[pdb_id])
+ ),
+ "shard": pdb_id[1:3],
+ }
+ for pdb_id in all_queries
+ ]
+
+ full_records = [record for record in records if record["repair_mode"] == "full"]
+ target_records = [record for record in records if record["repair_mode"] != "full"]
+ full_batch_count = _assign_repair_batches(
+ full_records,
+ batch_size=batch_size,
+ index_offset=0,
+ )
+ target_batch_count = _assign_repair_batches(
+ target_records,
+ batch_size=target_batch_size,
+ index_offset=full_batch_count,
+ )
+ batch_count = full_batch_count + target_batch_count
+
+ frame = pd.DataFrame(records).sort_values(
+ ["repair_batch_index", "estimated_work", "pdb_id"],
+ ascending=[True, False, True],
+ ignore_index=True,
+ )
+ output = output_path or data_dir / SCORE_REPAIR_RELATIVE
+ _atomic_parquet(frame, output)
+ summary = {
+ "status": "complete",
+ "affected_manifest": _source_signature(affected_manifest),
+ "additional_full_query_manifest": (
+ _source_signature(additional_full_query_manifest)
+ if additional_full_query_manifest is not None
+ else None
+ ),
+ "additional_target_query_manifest": (
+ _source_signature(additional_target_query_manifest)
+ if additional_target_query_manifest is not None
+ else None
+ ),
+ "output": _source_signature(output),
+ "affected_entry_count": len(affected),
+ "additional_full_query_count": len(additional_full),
+ "ignored_additional_full_query_count": len(
+ requested_additional_full.difference(active)
+ ),
+ "full_query_count": len(full_queries),
+ "cache_missing_full_query_count": len(missing_cache_queries),
+ "dropped_query_count": len(inactive_queries),
+ "target_only_query_count": (
+ len(all_queries) - len(full_queries) - len(inactive_queries)
+ ),
+ "query_count": len(all_queries),
+ "query_shard_count": int(frame["shard"].nunique()) if not frame.empty else 0,
+ "batch_size": max(batch_size, target_batch_size),
+ "full_query_batch_size": batch_size,
+ "full_query_batch_count": full_batch_count,
+ "target_query_batch_size": target_batch_size,
+ "target_query_batch_count": target_batch_count,
+ "batch_count": batch_count,
+ }
+ write_json_atomic(output.with_suffix(".json"), summary)
+ return summary
+
+
+def plan_bounded_score_repair(
+ data_dir: Path,
+ *,
+ pdb_manifest: Path,
+ batch_size: int = 10,
+ threads: int = 4,
+ scratch_dir: Path | None = None,
+ memory_limit: str = "32GB",
+) -> dict[str, Any]:
+ """Plan reciprocal rows for queries retained only as scoring targets.
+
+ A dropped query is evaluated only against entries for which it already has
+ a positive-pocket target-side candidate. This bounds pathological queries
+ without making the stored directed score graph appear one-sided.
+ """
+ if min(batch_size, threads) < 1:
+ raise ValueError("bounded repair batch size and threads must be positive")
+ dropped_path = data_dir / DROPPED_QUERY_RELATIVE
+ if not dropped_path.is_file():
+ raise FileNotFoundError(dropped_path)
+ dropped = pd.read_parquet(dropped_path, columns=["pdb_id", "stage"])
+ derived_drops = set(
+ dropped.loc[dropped["stage"].eq("derived_scoring"), "pdb_id"]
+ .dropna()
+ .astype(str)
+ )
+ requested = set(_load_pdb_id_manifest(pdb_manifest))
+ invalid = sorted(requested.difference(derived_drops))
+ if invalid:
+ raise ValueError(
+ f"bounded repairs require derived-scoring query drops: {invalid[:20]}"
+ )
+ request_signature = _source_signature(pdb_manifest)
+ if not requested:
+ raise ValueError("bounded score-repair query set is empty")
+
+ candidate_paths = sorted(
+ (data_dir / "scores/ligand_3d_candidate_shards").glob("shard=*.parquet")
+ )
+ if not candidate_paths:
+ raise FileNotFoundError("no query-sharded ligand 3D candidates found")
+ candidate_signatures = [_source_signature(path) for path in candidate_paths]
+
+ import duckdb
+
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ if scratch_dir is not None:
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ connection.register(
+ "requested_queries", pd.DataFrame({"pdb_id": sorted(requested)})
+ )
+ paths_sql = ", ".join(f"'{path.as_posix()}'" for path in candidate_paths)
+ started = perf_counter()
+ LOG.info(
+ "bounded score-repair planning: scanning candidate_shards=%d "
+ "requested_queries=%d",
+ len(candidate_paths),
+ len(requested),
+ )
+ incoming = connection.sql(
+ f"""
+ WITH reciprocal_targets AS (
+ SELECT DISTINCT
+ candidates.target_entry AS pdb_id,
+ candidates.query_entry AS target_pdb_id,
+ candidates.target_system AS query_system_id,
+ candidates.target_ligand_id AS query_ligand_id,
+ candidates.query_system AS target_system_id,
+ candidates.query_ligand_id AS target_ligand_id
+ FROM read_parquet([{paths_sql}], union_by_name=true) AS candidates
+ INNER JOIN requested_queries
+ ON candidates.target_entry = requested_queries.pdb_id
+ WHERE candidates.query_entry != candidates.target_entry
+ AND candidates.pocket_qcov > 0
+ )
+ SELECT
+ pdb_id,
+ list_sort(list(DISTINCT target_pdb_id)) AS target_pdb_ids,
+ list_sort(list(DISTINCT query_system_id)) AS query_system_ids,
+ list_sort(list(DISTINCT query_ligand_id)) AS query_ligand_ids,
+ list_sort(list(DISTINCT target_system_id)) AS target_system_ids,
+ list_sort(list(DISTINCT target_ligand_id)) AS target_ligand_ids,
+ count(*)::BIGINT AS estimated_work
+ FROM reciprocal_targets
+ GROUP BY pdb_id
+ ORDER BY pdb_id
+ """
+ ).df()
+ connection.close()
+ if candidate_signatures != [_source_signature(path) for path in candidate_paths]:
+ raise RuntimeError(
+ "ligand 3D candidates changed during bounded repair planning"
+ )
+ LOG.info(
+ "bounded score-repair planning: scan complete planned_queries=%d "
+ "elapsed_seconds=%.1f",
+ len(incoming),
+ perf_counter() - started,
+ )
+
+ records = [
+ {
+ "pdb_id": str(row.pdb_id),
+ "repair_mode": "bounded",
+ "target_pdb_ids": list(map(str, row.target_pdb_ids)),
+ "query_system_ids": list(map(str, row.query_system_ids)),
+ "query_ligand_ids": list(map(str, row.query_ligand_ids)),
+ "target_system_ids": list(map(str, row.target_system_ids)),
+ "target_ligand_ids": list(map(str, row.target_ligand_ids)),
+ "affected_target_count": len(row.target_pdb_ids),
+ "estimated_work": max(1, int(row.estimated_work)),
+ "shard": str(row.pdb_id)[1:3],
+ }
+ for row in incoming.itertuples(index=False)
+ ]
+ if not records:
+ raise ValueError("no dropped query has a reciprocal positive-pocket target")
+ batch_count = _assign_repair_batches(records, batch_size=batch_size, index_offset=0)
+ frame = pd.DataFrame(records).sort_values(
+ ["repair_batch_index", "estimated_work", "pdb_id"],
+ ascending=[True, False, True],
+ ignore_index=True,
+ )
+ output = data_dir / BOUNDED_SCORE_REPAIR_RELATIVE
+ _atomic_parquet(frame, output)
+ report = {
+ "status": "complete",
+ "requested_queries": request_signature,
+ "candidate_shards": {
+ "count": len(candidate_signatures),
+ "total_size": sum(int(item["size"]) for item in candidate_signatures),
+ "newest_mtime_ns": max(
+ int(item["mtime_ns"]) for item in candidate_signatures
+ ),
+ "signature": hashlib.sha256(
+ json.dumps(
+ candidate_signatures, sort_keys=True, separators=(",", ":")
+ ).encode()
+ ).hexdigest(),
+ },
+ "requested_query_count": len(requested),
+ "planned_query_count": len(frame),
+ "queries_without_incoming_candidates": sorted(
+ requested.difference(frame["pdb_id"].astype(str))
+ ),
+ "target_relation_count": int(frame["affected_target_count"].sum()),
+ "reciprocal_candidate_count": int(frame["estimated_work"].sum()),
+ "query_shard_count": int(frame["shard"].nunique()),
+ "batch_size": batch_size,
+ "batch_count": batch_count,
+ "output": _source_signature(output),
+ }
+ write_json_atomic(output.with_suffix(".json"), report)
+ return report
+
+
+def _score_repair_batch(
+ manifest_path: Path, *, batch_index: int, batch_size: int
+) -> list[dict[str, Any]]:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("repair batch index and size must be positive")
+ frame = pd.read_parquet(manifest_path)
+ selected = frame[frame["repair_batch_index"].eq(batch_index)]
+ if len(selected) > batch_size:
+ raise ValueError(
+ f"repair batch {batch_index} contains {len(selected)} rows; "
+ f"batch size is {batch_size}"
+ )
+ return cast(list[dict[str, Any]], selected.to_dict("records"))
+
+
+def _score_repair_query_paths(data_dir: Path, pdb_id: str) -> tuple[Path, Path, Path]:
+ return (
+ data_dir / "dbs/subdbs/search_db=holo" / f"{pdb_id}.parquet",
+ data_dir
+ / "scores/ligand_3d_candidates/search_db=holo"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet",
+ data_dir
+ / "scores/ligand_pair_scores/search_db=holo"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet",
+ )
+
+
+def _score_repair_query_is_current(
+ data_dir: Path, pdb_id: str, *, repair_started_ns: int
+) -> bool:
+ try:
+ return all(
+ path.stat().st_mtime_ns > repair_started_ns
+ for path in _score_repair_query_paths(data_dir, pdb_id)
+ )
+ except OSError:
+ return False
+
+
+def _score_repair_run_id(repair_manifest: Path) -> str:
+ """Return a stable identifier for one immutable repair manifest."""
+ signature = json.dumps(
+ _source_signature(repair_manifest), sort_keys=True, separators=(",", ":")
+ )
+ return hashlib.sha256(signature.encode()).hexdigest()[:16]
+
+
+def _score_repair_marker_dir(data_dir: Path, repair_manifest: Path) -> Path:
+ """Keep resource-limit markers isolated by repair run."""
+ return (
+ data_dir
+ / SCORE_REPAIR_DROP_DIR_RELATIVE
+ / _score_repair_run_id(repair_manifest)
+ )
+
+
+def _score_repair_marked_targets(
+ data_dir: Path,
+ repair_manifest: Path,
+) -> set[str]:
+ """Load and validate target-query drop markers for one repair run."""
+ marker_dir = _score_repair_marker_dir(data_dir, repair_manifest)
+ repair_run_id = _score_repair_run_id(repair_manifest)
+ marked_targets: set[str] = set()
+ if not marker_dir.is_dir():
+ return marked_targets
+ for path in sorted(marker_dir.glob("*.json")):
+ if path.name.endswith(".tmp.json"):
+ continue
+ payload = json.loads(path.read_text())
+ pdb_id = str(payload.get("pdb_id", ""))
+ if (
+ payload.get("repair_run_id") != repair_run_id
+ or payload.get("repair_mode") not in {"targets", "bounded"}
+ or not pdb_id
+ or path.stem != pdb_id
+ ):
+ raise ValueError(f"invalid target repair drop marker: {path}")
+ marked_targets.add(pdb_id)
+ return marked_targets
+
+
+def repair_target_score_remainders(
+ data_dir: Path,
+ *,
+ repair_manifest: Path,
+ batch_index: int,
+ batch_size: int,
+ scorer_cfg: Any,
+ scratch_dir: Path,
+ threads: int,
+) -> dict[str, Any]:
+ """Drop a timed-out target query and resume the rest of its batch."""
+ repairs = _score_repair_batch(
+ repair_manifest, batch_index=batch_index, batch_size=batch_size
+ )
+ repair_started_ns = repair_manifest.stat().st_mtime_ns
+ marked_targets = _score_repair_marked_targets(data_dir, repair_manifest)
+ for repair in repairs:
+ if str(repair["repair_mode"]) == "drop":
+ for path in _score_repair_query_paths(data_dir, str(repair["pdb_id"])):
+ path.unlink(missing_ok=True)
+ incomplete = [
+ repair
+ for repair in repairs
+ if str(repair["repair_mode"]) != "drop"
+ and str(repair["pdb_id"]) not in marked_targets
+ and not _score_repair_query_is_current(
+ data_dir,
+ str(repair["pdb_id"]),
+ repair_started_ns=repair_started_ns,
+ )
+ ]
+ if not incomplete:
+ return {
+ "status": "complete",
+ "batch_index": batch_index,
+ "dropped_query": None,
+ "resumed_query_count": 0,
+ }
+ invalid_modes = sorted(
+ {
+ str(repair["repair_mode"])
+ for repair in incomplete
+ if str(repair["repair_mode"]) not in {"targets", "bounded"}
+ }
+ )
+ if invalid_modes:
+ raise ValueError(
+ f"target remainder repair received non-target modes: {invalid_modes}"
+ )
+
+ stalled = incomplete[0]
+ stalled_pdb_id = str(stalled["pdb_id"])
+ for path in _score_repair_query_paths(data_dir, stalled_pdb_id):
+ path.unlink(missing_ok=True)
+ marker = (
+ _score_repair_marker_dir(data_dir, repair_manifest) / f"{stalled_pdb_id}.json"
+ )
+ write_json_atomic(
+ marker,
+ {
+ "pdb_id": stalled_pdb_id,
+ "repair_run_id": _score_repair_run_id(repair_manifest),
+ "repair_batch_index": batch_index,
+ "repair_mode": str(stalled["repair_mode"]),
+ "reason": "resource_limit",
+ },
+ )
+ remainder = incomplete[1:]
+ if remainder:
+ tasks.repair_batch_scores(
+ data_dir=data_dir,
+ repairs=remainder,
+ scorer_cfg=scorer_cfg,
+ scratch_dir=scratch_dir,
+ threads=threads,
+ )
+ return {
+ "status": "complete",
+ "batch_index": batch_index,
+ "dropped_query": stalled_pdb_id,
+ "resumed_query_count": len(remainder),
+ }
+
+
+def finalize_score_repair_queries(
+ data_dir: Path,
+ *,
+ repair_manifest: Path,
+ max_new_drops: int,
+) -> dict[str, Any]:
+ """Validate repaired queries and record only resource-limited tail queries."""
+ if max_new_drops < 0:
+ raise ValueError("max_new_drops must be non-negative")
+ repairs = pd.read_parquet(repair_manifest)
+ required = {"pdb_id", "repair_mode"}
+ missing = sorted(required.difference(repairs.columns))
+ if missing:
+ raise ValueError(f"repair manifest is missing columns {missing}")
+ repair_started_ns = repair_manifest.stat().st_mtime_ns
+ incomplete_by_mode: dict[str, set[str]] = {}
+ for row in repairs.itertuples(index=False):
+ mode = str(row.repair_mode)
+ pdb_id = str(row.pdb_id)
+ if mode == "drop" or _score_repair_query_is_current(
+ data_dir, pdb_id, repair_started_ns=repair_started_ns
+ ):
+ continue
+ incomplete_by_mode.setdefault(mode, set()).add(pdb_id)
+
+ marked_targets = _score_repair_marked_targets(data_dir, repair_manifest)
+ incomplete_targets = incomplete_by_mode.get(
+ "targets", set()
+ ) | incomplete_by_mode.get("bounded", set())
+ unexpected_targets = sorted(incomplete_targets.difference(marked_targets))
+ if unexpected_targets:
+ raise ValueError(
+ "target score repairs remain incomplete without resource-limit markers: "
+ f"{unexpected_targets[:20]}"
+ )
+ stale_markers = sorted(marked_targets.difference(incomplete_targets))
+ if stale_markers:
+ raise ValueError(
+ f"target repair drop markers unexpectedly have current outputs: "
+ f"{stale_markers[:20]}"
+ )
+ invalid_modes = sorted(
+ set(incomplete_by_mode).difference({"full", "targets", "bounded"})
+ )
+ if invalid_modes:
+ raise ValueError(f"unsupported incomplete repair modes: {invalid_modes}")
+
+ new_drops = marked_targets | incomplete_by_mode.get("full", set())
+ if len(new_drops) > max_new_drops:
+ raise ValueError(
+ f"score repair would drop {len(new_drops)} queries, exceeding "
+ f"the configured limit {max_new_drops}"
+ )
+ for pdb_id in new_drops:
+ for path in _score_repair_query_paths(data_dir, pdb_id):
+ path.unlink(missing_ok=True)
+
+ existing_columns = ["pdb_id", "stage", "reason", "details"]
+ existing = pd.DataFrame(columns=existing_columns)
+ preserved_drops: set[str] = set()
+ existing_drop_path = data_dir / DROPPED_QUERY_RELATIVE
+ if existing_drop_path.is_file():
+ existing = pd.read_parquet(existing_drop_path)
+ missing = sorted(set(existing_columns).difference(existing.columns))
+ if missing:
+ raise ValueError(f"existing dropped-query manifest is missing {missing}")
+ preserved_drops = set(
+ existing.loc[existing["stage"].eq("derived_scoring"), "pdb_id"].astype(str)
+ )
+ requested_drops = sorted(preserved_drops | new_drops)
+ source = data_dir / SCORE_REPAIR_DROP_RELATIVE
+ _atomic_parquet(pd.DataFrame({"pdb_id": requested_drops}), source)
+ existing_ids = set(existing["pdb_id"].astype(str))
+ newly_recorded = sorted(new_drops.difference(existing_ids))
+ details = json.dumps({"source_manifest": source.name}, sort_keys=True)
+ additions = pd.DataFrame(
+ [
+ {
+ "pdb_id": pdb_id,
+ "stage": "derived_scoring",
+ "reason": "resource_limit",
+ "details": details,
+ }
+ for pdb_id in newly_recorded
+ ],
+ columns=existing_columns,
+ )
+ dropped = pd.concat([existing[existing_columns], additions], ignore_index=True)
+ if dropped["pdb_id"].astype(str).duplicated().any():
+ raise ValueError("a query cannot be dropped at multiple stages")
+ dropped = dropped.sort_values("pdb_id", ignore_index=True)
+ plan_path = data_dir / PLAN_RELATIVE
+ if not plan_path.is_file():
+ raise FileNotFoundError(plan_path)
+ plan = json.loads(plan_path.read_text())
+ _atomic_parquet(dropped, existing_drop_path)
+ stage_counts = {
+ str(stage): int(count)
+ for stage, count in dropped.groupby("stage", dropna=False).size().items()
+ }
+ plan["dropped_queries"] = _source_signature(existing_drop_path)
+ plan["dropped_query_counts"] = {
+ **stage_counts,
+ "total": len(dropped),
+ }
+ write_json_atomic(plan_path, plan)
+ dropped_report = {
+ "new": len(newly_recorded),
+ "derived_scoring": stage_counts.get("derived_scoring", 0),
+ "total": len(dropped),
+ }
+ report = {
+ "status": "complete",
+ "new_target_query_drops": len(marked_targets),
+ "new_full_query_drops": len(incomplete_by_mode.get("full", set())),
+ "new_query_drops": len(new_drops),
+ "preserved_query_drops": len(preserved_drops),
+ "dropped_queries": dropped_report,
+ }
+ write_json_atomic(source.with_suffix(".json"), report)
+ return report
+
+
+def _score_repair_shard_batch(
+ manifest_path: Path, *, batch_index: int, batch_size: int
+) -> list[str]:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("repair shard batch index and size must be positive")
+ shards = sorted(
+ set(pd.read_parquet(manifest_path, columns=["shard"])["shard"].astype(str))
+ )
+ start = batch_index * batch_size
+ return shards[start : start + batch_size]
+
+
+def plan_score_repair_ligand_3d(
+ data_dir: Path,
+ *,
+ repair_manifest: Path,
+ batch_size: int,
+ threads: int,
+ scratch_dir: Path,
+ memory_limit: str = "8GB",
+) -> dict[str, Any]:
+ """Plan only canonical ligand pairs absent from the existing score cache."""
+ if min(batch_size, threads) < 1:
+ raise ValueError("repair ligand batch size and threads must be positive")
+ shards = sorted(
+ set(pd.read_parquet(repair_manifest, columns=["shard"])["shard"].astype(str))
+ )
+ candidate_paths = [
+ data_dir / "scores/ligand_3d_pair_candidate_shards" / f"shard={shard}.parquet"
+ for shard in shards
+ ]
+ cached_paths = [
+ data_dir / "scores/ligand_3d_by_query" / f"{shard}.parquet" for shard in shards
+ ]
+ missing_inputs = [
+ path for path in [*candidate_paths, *cached_paths] if not path.is_file()
+ ]
+ if missing_inputs:
+ raise FileNotFoundError(
+ f"missing ligand 3D repair inputs: {missing_inputs[:10]}"
+ )
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ import duckdb
+
+ connection = duckdb.connect()
+ annotation = data_dir / "index/annotation_table.parquet"
+ temporary = scratch_dir / "score-repair-ligand-3d.parquet"
+ temporary.unlink(missing_ok=True)
+ ligand_sizes = scratch_dir / "ligand-sizes.parquet"
+ ligand_sizes.unlink(missing_ok=True)
+ shard_scratch = scratch_dir / "missing-shards"
+ shard_scratch.mkdir(exist_ok=True)
+ output_schema = pa.schema(
+ [
+ ("query_entry", pa.string()),
+ ("query_ligand_asym_id", pa.string()),
+ ("target_entry", pa.string()),
+ ("target_ligand_asym_id", pa.string()),
+ ("estimated_work", pa.int64()),
+ ("shard", pa.string()),
+ ("repair_pair_batch_index", pa.int32()),
+ ]
+ )
+ writer: pq.ParquetWriter | None = None
+ pair_count = 0
+ nonempty_shards = 0
+ started = perf_counter()
+ try:
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql("SET preserve_insertion_order=false")
+ connection.sql(
+ f"""
+ COPY (
+ SELECT
+ entry_pdb_id AS entry,
+ ligand_asym_id AS asym_id,
+ max(greatest(coalesce(ligand_num_heavy_atoms, 1), 1))::BIGINT
+ AS heavy_atoms
+ FROM read_parquet('{annotation.as_posix()}')
+ WHERE system_type = 'holo'
+ AND coalesce(ligand_is_proper, false)
+ AND coalesce(ligand_is_shape_comparable, false)
+ GROUP BY entry_pdb_id, ligand_asym_id
+ ) TO '{ligand_sizes.as_posix()}' (
+ FORMAT PARQUET, COMPRESSION ZSTD
+ )
+ """
+ )
+ for shard_index, (shard, candidate, cached) in enumerate(
+ zip(shards, candidate_paths, cached_paths, strict=True), start=1
+ ):
+ shard_output = shard_scratch / f"shard={shard}.parquet"
+ shard_output.unlink(missing_ok=True)
+ connection.sql(
+ f"""
+ COPY (
+ WITH candidates AS (
+ SELECT
+ query_entry,
+ query_ligand_asym_id,
+ target_entry,
+ target_ligand_asym_id
+ FROM read_parquet('{candidate.as_posix()}')
+ WHERE pocket_qcov > 0
+ ), missing AS (
+ SELECT candidates.*
+ FROM candidates ANTI JOIN read_parquet(
+ '{cached.as_posix()}'
+ ) AS cached USING (
+ query_entry,
+ query_ligand_asym_id,
+ target_entry,
+ target_ligand_asym_id
+ )
+ ), sized AS (
+ SELECT
+ missing.*,
+ (query.heavy_atoms * target.heavy_atoms)::BIGINT
+ AS estimated_work
+ FROM missing
+ INNER JOIN read_parquet(
+ '{ligand_sizes.as_posix()}'
+ ) AS query
+ ON missing.query_entry = query.entry
+ AND missing.query_ligand_asym_id = query.asym_id
+ INNER JOIN read_parquet(
+ '{ligand_sizes.as_posix()}'
+ ) AS target
+ ON missing.target_entry = target.entry
+ AND missing.target_ligand_asym_id = target.asym_id
+ )
+ SELECT
+ query_entry::VARCHAR AS query_entry,
+ query_ligand_asym_id::VARCHAR AS query_ligand_asym_id,
+ target_entry::VARCHAR AS target_entry,
+ target_ligand_asym_id::VARCHAR AS target_ligand_asym_id,
+ estimated_work::BIGINT AS estimated_work,
+ '{shard}'::VARCHAR AS shard,
+ floor(({pair_count} + row_number() OVER (
+ ORDER BY
+ query_entry,
+ query_ligand_asym_id,
+ estimated_work DESC,
+ target_entry,
+ target_ligand_asym_id
+ ) - 1) / {batch_size})::INTEGER
+ AS repair_pair_batch_index
+ FROM sized
+ ) TO '{shard_output.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE {max(2_048, batch_size)}
+ )
+ """
+ )
+ observed = pq.read_schema(shard_output)
+ if not observed.equals(output_schema):
+ raise ValueError(
+ f"repair ligand work shard has unexpected schema: {observed}"
+ )
+ shard_rows = pq.ParquetFile(shard_output).metadata.num_rows
+ if shard_rows:
+ if writer is None:
+ writer = pq.ParquetWriter(
+ temporary, output_schema, compression="zstd"
+ )
+ for batch in pq.ParquetFile(shard_output).iter_batches(
+ batch_size=250_000
+ ):
+ writer.write_table(pa.Table.from_batches([batch]))
+ pair_count += shard_rows
+ nonempty_shards += 1
+ shard_output.unlink(missing_ok=True)
+ if shard_index % 25 == 0 or shard_index == len(shards):
+ elapsed = perf_counter() - started
+ LOG.info(
+ "repair ligand 3D planning: shards=%d/%d missing_pairs=%d "
+ "elapsed_seconds=%.1f eta_seconds=%.1f",
+ shard_index,
+ len(shards),
+ pair_count,
+ elapsed,
+ elapsed / shard_index * (len(shards) - shard_index),
+ )
+ if writer is None:
+ pq.write_table(pa.Table.from_pylist([], schema=output_schema), temporary)
+ else:
+ writer.close()
+ writer = None
+ except Exception:
+ if writer is not None:
+ writer.close()
+ temporary.unlink(missing_ok=True)
+ raise
+ finally:
+ connection.close()
+ batch_count = math.ceil(pair_count / batch_size)
+ output = data_dir / SCORE_REPAIR_LIGAND_3D_RELATIVE
+ output.parent.mkdir(exist_ok=True, parents=True)
+ install = output.with_suffix(output.suffix + ".tmp")
+ copyfile(temporary, install)
+ install.replace(output)
+ temporary.unlink(missing_ok=True)
+ report = {
+ "status": "complete",
+ "repair_manifest": _source_signature(repair_manifest),
+ "output": _source_signature(output),
+ "pair_count": pair_count,
+ "batch_size": batch_size,
+ "batch_count": batch_count,
+ "shard_count": nonempty_shards,
+ }
+ write_json_atomic(output.with_suffix(".json"), report)
+ return report
+
+
+def _score_repair_ligand_3d_batch(
+ data_dir: Path, *, batch_index: int, batch_size: int
+) -> pd.DataFrame:
+ work = pd.read_parquet(
+ data_dir / SCORE_REPAIR_LIGAND_3D_RELATIVE,
+ filters=[("repair_pair_batch_index", "==", batch_index)],
+ )
+ if len(work) > batch_size:
+ raise ValueError(
+ f"repair ligand batch {batch_index} contains {len(work)} pairs; "
+ f"batch size is {batch_size}"
+ )
+ return work
+
+
+def merge_score_repair_ligand_3d(
+ data_dir: Path,
+ *,
+ shards: list[str],
+ scratch_dir: Path,
+ threads: int,
+) -> dict[str, Any]:
+ """Atomically append newly scored repair pairs to canonical query caches."""
+ if threads < 1:
+ raise ValueError("repair merge threads must be positive")
+ import duckdb
+
+ work_path = data_dir / SCORE_REPAIR_LIGAND_3D_RELATIVE
+ repair_dir = data_dir / "scores/ligand_3d_pair_repairs"
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ updated: list[str] = []
+ for shard in shards:
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ batch_rows = connection.sql(
+ f"""
+ SELECT DISTINCT repair_pair_batch_index
+ FROM read_parquet('{work_path.as_posix()}')
+ WHERE shard = '{shard}'
+ ORDER BY repair_pair_batch_index
+ """
+ ).fetchall()
+ if not batch_rows:
+ connection.close()
+ continue
+ repair_paths = [repair_dir / f"{int(row[0])}.parquet" for row in batch_rows]
+ absent = [path for path in repair_paths if not path.is_file()]
+ if absent:
+ connection.close()
+ raise FileNotFoundError(
+ f"missing ligand 3D repair batches for shard {shard}: {absent[:10]}"
+ )
+ cached = data_dir / "scores/ligand_3d_by_query" / f"{shard}.parquet"
+ paths_sql = ", ".join(f"'{path.as_posix()}'" for path in repair_paths)
+ keys = ", ".join(
+ [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ )
+ validation = connection.sql(
+ f"""
+ WITH expected AS (
+ SELECT {keys}
+ FROM read_parquet('{work_path.as_posix()}')
+ WHERE shard = '{shard}'
+ ), observed AS (
+ SELECT scored.*
+ FROM read_parquet([{paths_sql}]) AS scored
+ INNER JOIN expected USING ({keys})
+ )
+ SELECT
+ (SELECT count(*) FROM expected),
+ (SELECT count(*) FROM observed),
+ (SELECT count(*) - count(DISTINCT ({keys})) FROM observed),
+ (SELECT count(*) FROM observed
+ INNER JOIN read_parquet('{cached.as_posix()}') USING ({keys}))
+ """
+ ).fetchone()
+ if validation is None or validation[0] != validation[1] or validation[2]:
+ connection.close()
+ raise ValueError(
+ f"invalid ligand 3D repair coverage for shard {shard}: {validation}"
+ )
+ if validation[3] == validation[0]:
+ connection.close()
+ continue
+ if validation[3]:
+ connection.close()
+ raise ValueError(
+ f"partly merged ligand 3D repair shard {shard}: {validation}"
+ )
+ temporary = scratch_dir / f"{shard}.parquet"
+ temporary.unlink(missing_ok=True)
+ connection.sql(
+ f"""
+ COPY (
+ WITH expected AS (
+ SELECT {keys}
+ FROM read_parquet('{work_path.as_posix()}')
+ WHERE shard = '{shard}'
+ ), repaired AS (
+ SELECT scored.*
+ FROM read_parquet([{paths_sql}]) AS scored
+ INNER JOIN expected USING ({keys})
+ )
+ SELECT * FROM read_parquet('{cached.as_posix()}')
+ UNION ALL
+ SELECT * FROM repaired
+ ORDER BY {keys}
+ ) TO '{temporary.as_posix()}' (FORMAT PARQUET, COMPRESSION ZSTD)
+ """
+ )
+ connection.close()
+ install = cached.with_suffix(cached.suffix + ".tmp")
+ copyfile(temporary, install)
+ install.replace(cached)
+ temporary.unlink(missing_ok=True)
+ updated.append(shard)
+ return {"status": "complete", "updated_shards": updated}
+
+
+def record_dropped_queries(
+ data_dir: Path,
+ *,
+ score_query_manifest: Path,
+) -> dict[str, Any]:
+ """Record mapping and resource-limited score queries in one manifest."""
+ if not score_query_manifest.is_file():
+ raise FileNotFoundError(score_query_manifest)
+ score_drops = pd.read_parquet(score_query_manifest)
+ if "pdb_id" not in score_drops.columns:
+ raise ValueError(
+ f"dropped-query source is missing pdb_id: {score_query_manifest}"
+ )
+ requested_score_ids = set(score_drops["pdb_id"].dropna().astype(str))
+ if score_drops["pdb_id"].dropna().astype(str).duplicated().any():
+ raise ValueError(
+ f"dropped-query source contains duplicate PDB IDs: {score_query_manifest}"
+ )
+
+ alignment_manifest = data_dir / "alignments" / "manifest.json"
+ if not alignment_manifest.is_file():
+ raise FileNotFoundError(alignment_manifest)
+ alignment_payload = json.loads(alignment_manifest.read_text())
+ mapping_details = alignment_payload.get("skipped_queries")
+ if not isinstance(mapping_details, dict):
+ raise ValueError("alignment manifest has no skipped-query mapping")
+ mapping_ids = set(map(str, mapping_details))
+
+ output = data_dir / DROPPED_QUERY_RELATIVE
+ if output.is_file():
+ existing = pd.read_parquet(output)
+ required = {"pdb_id", "stage", "reason", "details"}
+ missing = sorted(required.difference(existing.columns))
+ if missing:
+ raise ValueError(f"existing dropped-query manifest is missing {missing}")
+ score_ids = set()
+ for pdb_id in requested_score_ids.difference(mapping_ids):
+ score_path = (
+ data_dir / "dbs" / "subdbs" / "search_db=holo" / f"{pdb_id}.parquet"
+ )
+ candidate_path = (
+ data_dir
+ / "scores"
+ / "ligand_3d_candidates"
+ / "search_db=holo"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet"
+ )
+ ligand_pair_score_path = (
+ data_dir
+ / "scores"
+ / "ligand_pair_scores"
+ / "search_db=holo"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet"
+ )
+ try:
+ metadata = pq.read_schema(score_path).metadata or {}
+ ligand_pair_schema = pq.read_schema(ligand_pair_score_path)
+ except (OSError, ValueError):
+ metadata = {}
+ ligand_pair_schema = None
+ complete = (
+ metadata.get(b"plinder.ligand_3d") in {b"deferred", b"complete"}
+ and candidate_path.is_file()
+ and ligand_pair_schema is not None
+ and ligand_pair_schema.equals(schemas.LIGAND_PAIR_SCORE_SCHEMA)
+ )
+ if not complete:
+ score_ids.add(pdb_id)
+
+ planned_ids = set(
+ pd.read_parquet(data_dir / SCORE_WORK_RELATIVE, columns=["pdb_id"])[
+ "pdb_id"
+ ].astype(str)
+ )
+ protein_query_ids = set(
+ pd.read_parquet(data_dir / MANIFEST_RELATIVE, columns=["pdb_id"])[
+ "pdb_id"
+ ].astype(str)
+ )
+ unexpected = sorted(
+ mapping_ids.difference(protein_query_ids) | score_ids.difference(planned_ids)
+ )
+ if unexpected:
+ raise ValueError(
+ f"dropped queries are absent from the scoring plan: {unexpected[:10]}"
+ )
+
+ rows = [
+ {
+ "pdb_id": pdb_id,
+ "stage": "alignment_mapping",
+ "reason": str(details.get("reason", "alignment_mapping_skipped")),
+ "details": json.dumps(details, sort_keys=True),
+ }
+ for pdb_id, details in sorted(mapping_details.items())
+ ]
+ score_detail = json.dumps(
+ {"source_manifest": score_query_manifest.name}, sort_keys=True
+ )
+ rows.extend(
+ {
+ "pdb_id": pdb_id,
+ "stage": "derived_scoring",
+ "reason": "resource_limit",
+ "details": score_detail,
+ }
+ for pdb_id in sorted(score_ids)
+ )
+ frame = pd.DataFrame(rows, columns=["pdb_id", "stage", "reason", "details"])
+ if frame["pdb_id"].duplicated().any():
+ raise ValueError("a query cannot be dropped at multiple stages")
+ plan = _load_plan(data_dir)
+ _atomic_parquet(frame, output)
+
+ plan["dropped_queries"] = _source_signature(output)
+ plan["dropped_query_counts"] = {
+ "alignment_mapping": len(mapping_ids),
+ "derived_scoring": len(score_ids),
+ "total": len(frame),
+ }
+ write_json_atomic(data_dir / PLAN_RELATIVE, plan)
+ return {
+ "status": "complete",
+ "alignment_mapping": len(mapping_ids),
+ "requested_derived_scoring": len(requested_score_ids),
+ "completed_since_retry_manifest": len(requested_score_ids)
+ - len(mapping_ids.intersection(requested_score_ids))
+ - len(score_ids),
+ "derived_scoring": len(score_ids),
+ "total": len(frame),
+ "path": str(output),
+ }
+
+
+def plan_protein_scoring(
+ data_dir: Path,
+ *,
+ pdb_ids: list[str] | None = None,
+ two_char_codes: list[str] | None = None,
+ max_seqs: int = 10_000,
+) -> dict[str, Any]:
+ """Freeze the protein-query universe used by every array stage."""
+ if max_seqs < 1:
+ raise ValueError("max_seqs must be positive")
+ chunks = tasks.scatter_protein_scoring(
+ data_dir=data_dir,
+ batch_size=1_000_000,
+ two_char_codes=two_char_codes or [],
+ pdb_ids=pdb_ids or [],
+ )
+ query_ids = [pdb_id for chunk in chunks for pdb_id in chunk]
+ if not query_ids:
+ raise ValueError("no protein-containing entries were selected")
+ chain_path = data_dir / "index" / "entry_chains.parquet"
+ chains = tasks._protein_scoring_chains(data_dir)
+ chains = chains[chains["entry_pdb_id"].isin(query_ids)]
+ counts = chains.groupby("entry_pdb_id")["chain_asym_id"].nunique().to_dict()
+ manifest = pd.DataFrame(
+ {
+ "pdb_id": query_ids,
+ "shard": [pdb_id[1:3] for pdb_id in query_ids],
+ "protein_chain_count": [counts[pdb_id] for pdb_id in query_ids],
+ }
+ ).sort_values(["shard", "pdb_id"], ignore_index=True)
+ manifest_path = data_dir / MANIFEST_RELATIVE
+ _atomic_parquet(manifest, manifest_path)
+ payload: dict[str, Any] = {
+ "query_count": len(manifest),
+ "protein_chain_count": int(manifest["protein_chain_count"].sum()),
+ "shard_count": int(manifest["shard"].nunique()),
+ "max_seqs": max_seqs,
+ "search_databases": ["holo"],
+ "alignment_types": ["foldseek", "mmseqs"],
+ "target_clustering": {
+ "identity": 1.0,
+ "coverage": 1.0,
+ "coverage_mode": 0,
+ "expand_to_chain_level": True,
+ },
+ "entry_chains": _source_signature(chain_path),
+ "manifest": _source_signature(manifest_path),
+ }
+ half_interface_path = data_dir / tasks.INTERFACE_HALF_REPRESENTATIVES_RELATIVE
+ interface_path = data_dir / tasks.INTERFACE_REPRESENTATIVES_RELATIVE
+ if interface_path.is_file():
+ # A resumed collation may have replaced the source interface table.
+ # Refresh existing representatives before freezing their signatures.
+ tasks.make_interface_representatives(
+ data_dir=data_dir,
+ scratch_dir=Path(os.environ.get("TMPDIR", data_dir / "scratch")),
+ threads=1,
+ )
+ if half_interface_path.is_file():
+ payload["interface_half_annotation"] = _source_signature(half_interface_path)
+ if interface_path.is_file():
+ payload["interface_annotation"] = _source_signature(interface_path)
+ write_json_atomic(data_dir / PLAN_RELATIVE, payload)
+ return payload
+
+
+def plan_linked_apo_scoring(
+ data_dir: Path,
+ *,
+ pdb_ids: list[str] | None = None,
+ two_char_codes: list[str] | None = None,
+ max_seqs: int = 10_000,
+) -> dict[str, Any]:
+ """Freeze the separate ligand-apo and interface-apo query chains."""
+ if max_seqs < 1:
+ raise ValueError("max_seqs must be positive")
+ chunks = tasks.scatter_protein_scoring(
+ data_dir=data_dir,
+ batch_size=1_000_000,
+ two_char_codes=two_char_codes or [],
+ pdb_ids=pdb_ids or [],
+ search_dbs=["apo"],
+ )
+ selected_ids = {pdb_id for chunk in chunks for pdb_id in chunk}
+ if not selected_ids:
+ raise ValueError("no ligand-pocket or protein-interface chains were selected")
+
+ def write_queries(chains: pd.DataFrame, path: Path) -> pd.DataFrame:
+ selected = chains[chains["entry_pdb_id"].isin(selected_ids)].copy()
+ selected = selected.rename(columns={"entry_pdb_id": "pdb_id"})
+ selected["shard"] = selected["pdb_id"].str.slice(1, 3)
+ manifest = selected[
+ ["pdb_id", "shard", "chain_asym_id", "chain_auth_id"]
+ ].sort_values(["shard", "pdb_id", "chain_asym_id"], ignore_index=True)
+ _atomic_parquet(manifest, path)
+ return manifest
+
+ ligand_manifest_path = data_dir / LINKED_APO_QUERY_MANIFEST_RELATIVE
+ ligand_manifest = write_queries(
+ tasks._ligand_apo_query_chains(data_dir), ligand_manifest_path
+ )
+ interface_manifest_path = data_dir / INTERFACE_APO_QUERY_MANIFEST_RELATIVE
+ interface_manifest = write_queries(
+ tasks._interface_apo_query_chains(data_dir), interface_manifest_path
+ )
+ payload = {
+ "query_count": len(selected_ids),
+ "ligand_query_count": int(ligand_manifest["pdb_id"].nunique()),
+ "ligand_protein_chain_count": len(ligand_manifest),
+ "interface_query_count": int(interface_manifest["pdb_id"].nunique()),
+ "interface_protein_chain_count": len(interface_manifest),
+ "shard_count": len(
+ set(ligand_manifest["shard"]).union(interface_manifest["shard"])
+ ),
+ "max_seqs": max_seqs,
+ "search_databases": ["apo", "interface_apo"],
+ "alignment_types": ["foldseek", "mmseqs"],
+ "annotation": _source_signature(
+ data_dir / "index" / "annotation_table.parquet"
+ ),
+ "entry_chains": _source_signature(data_dir / "index" / "entry_chains.parquet"),
+ "entry_biounit_chains": _source_signature(
+ data_dir / "index" / "entry_biounit_chains.parquet"
+ ),
+ "interface_annotations": _source_signature(
+ data_dir / "index" / "interface_annotation_table.parquet"
+ ),
+ "ligand_manifest": _source_signature(ligand_manifest_path),
+ "interface_manifest": _source_signature(interface_manifest_path),
+ }
+ write_json_atomic(data_dir / LINKED_APO_PLAN_RELATIVE, payload)
+ return payload
+
+
+def _load_plan(
+ data_dir: Path,
+ *,
+ recheck_source: bool = False,
+ recheck_score_inputs: bool = True,
+) -> dict[str, Any]:
+ plan_path = data_dir / PLAN_RELATIVE
+ if not plan_path.is_file():
+ raise FileNotFoundError(f"missing protein scoring plan: {plan_path}")
+ plan: dict[str, Any] = json.loads(plan_path.read_text())
+ manifest_path = data_dir / MANIFEST_RELATIVE
+ if _source_signature(manifest_path) != plan["manifest"]:
+ raise ValueError("protein scoring query manifest changed after planning")
+ dropped_signature = plan.get("dropped_queries")
+ if dropped_signature is not None:
+ dropped_path = data_dir / DROPPED_QUERY_RELATIVE
+ if (
+ not dropped_path.is_file()
+ or _source_signature(dropped_path) != dropped_signature
+ ):
+ raise ValueError("dropped-query manifest changed after planning")
+ if recheck_source:
+ for key, description in [
+ ("entry_chains", "entry chain index"),
+ ("interface_annotation", "interface annotation index"),
+ ]:
+ signature = plan.get(key)
+ if not isinstance(signature, dict):
+ continue
+ source = Path(str(signature["path"]))
+ if _source_signature(source) != signature:
+ raise ValueError(
+ f"{description} changed after protein scoring was planned"
+ )
+ score_annotation = plan.get("score_annotation")
+ if recheck_score_inputs and isinstance(score_annotation, dict):
+ source = Path(str(score_annotation["path"]))
+ if _source_signature(source) != score_annotation:
+ raise ValueError(
+ "annotation index changed after score batches were planned"
+ )
+ return plan
+
+
+def _load_linked_apo_plan(data_dir: Path) -> dict[str, Any]:
+ """Load and validate the compact linked-apo query plan."""
+ plan_path = data_dir / LINKED_APO_PLAN_RELATIVE
+ if not plan_path.is_file():
+ raise FileNotFoundError(f"missing linked-apo scoring plan: {plan_path}")
+ plan: dict[str, Any] = json.loads(plan_path.read_text())
+ sources = {
+ "ligand_manifest": data_dir / LINKED_APO_QUERY_MANIFEST_RELATIVE,
+ "interface_manifest": data_dir / INTERFACE_APO_QUERY_MANIFEST_RELATIVE,
+ "annotation": data_dir / "index" / "annotation_table.parquet",
+ "entry_chains": data_dir / "index" / "entry_chains.parquet",
+ "entry_biounit_chains": data_dir / "index" / "entry_biounit_chains.parquet",
+ "interface_annotations": (
+ data_dir / "index" / "interface_annotation_table.parquet"
+ ),
+ }
+ for key, path in sources.items():
+ if not path.is_file() or _source_signature(path) != plan.get(key):
+ raise ValueError(f"linked-apo {key} changed after planning")
+ return plan
+
+
+def _query_batch(
+ data_dir: Path,
+ batch_index: int,
+ batch_size: int,
+ *,
+ search_db: str = "holo",
+) -> list[str]:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ if search_db == "apo":
+ _load_linked_apo_plan(data_dir)
+ else:
+ _load_plan(data_dir)
+ manifest_path = (
+ data_dir / LINKED_APO_QUERY_MANIFEST_RELATIVE
+ if search_db == "apo"
+ else data_dir / MANIFEST_RELATIVE
+ )
+ queries = pd.read_parquet(manifest_path, columns=["pdb_id"])
+ queries = queries.drop_duplicates("pdb_id", ignore_index=True)
+ start = batch_index * batch_size
+ values = queries["pdb_id"].iloc[start : start + batch_size].tolist()
+ return [str(value) for value in values]
+
+
+def _apo_search_query_batch(
+ data_dir: Path, batch_index: int, batch_size: int
+) -> list[str]:
+ """Select entries needed by either independently capped apo search."""
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ _load_linked_apo_plan(data_dir)
+ queries = pd.concat(
+ [
+ pd.read_parquet(data_dir / relative, columns=["pdb_id"])
+ for relative in (
+ LINKED_APO_QUERY_MANIFEST_RELATIVE,
+ INTERFACE_APO_QUERY_MANIFEST_RELATIVE,
+ )
+ ],
+ ignore_index=True,
+ ).drop_duplicates("pdb_id")
+ values = queries.sort_values("pdb_id")["pdb_id"].iloc[
+ batch_index * batch_size : (batch_index + 1) * batch_size
+ ]
+ return [str(value) for value in values]
+
+
+def _score_batch(data_dir: Path, batch_index: int, batch_size: int) -> list[str]:
+ """Load one cost-balanced score batch."""
+ work_path = data_dir / SCORE_WORK_RELATIVE
+ if not work_path.is_file():
+ raise FileNotFoundError(
+ f"missing score work plan; run plan-score-batches first: {work_path}"
+ )
+ plan = _load_plan(data_dir)
+ if batch_size != int(plan.get("score_batch_size", -1)):
+ raise ValueError(
+ f"score batch size is {plan.get('score_batch_size')}, got {batch_size}"
+ )
+ if _source_signature(work_path) != plan.get("score_work"):
+ raise ValueError("protein scoring work manifest changed after planning")
+ work = pd.read_parquet(
+ work_path,
+ columns=["pdb_id"],
+ filters=[("score_batch_index", "==", batch_index)],
+ )
+ dropped = dropped_query_ids(data_dir)
+ if dropped:
+ work = work[~work["pdb_id"].astype(str).isin(dropped)]
+ return [str(value) for value in work["pdb_id"]]
+
+
+def _score_manifest_batch(
+ data_dir: Path,
+ manifest_path: Path,
+ batch_index: int,
+ batch_size: int,
+) -> list[str]:
+ """Load a fixed batch from an explicit PDB retry manifest."""
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ if not manifest_path.is_file():
+ raise FileNotFoundError(manifest_path)
+ manifest = pd.read_parquet(manifest_path)
+ if "pdb_id" not in manifest.columns:
+ raise ValueError(f"score retry manifest is missing pdb_id: {manifest_path}")
+ pdb_ids = manifest["pdb_id"].dropna().astype(str)
+ if pdb_ids.duplicated().any():
+ raise ValueError(
+ f"score retry manifest contains duplicate PDB IDs: {manifest_path}"
+ )
+ dropped = dropped_query_ids(data_dir)
+ if dropped:
+ pdb_ids = pdb_ids[~pdb_ids.isin(dropped)]
+ if "retry_batch_index" in manifest.columns:
+ selected = manifest.loc[
+ manifest["retry_batch_index"].eq(batch_index), "pdb_id"
+ ].dropna()
+ if len(selected) > batch_size:
+ raise ValueError(
+ f"retry batch {batch_index} contains {len(selected)} PDB IDs, "
+ f"exceeding batch size {batch_size}"
+ )
+ return [str(value) for value in selected]
+ start = batch_index * batch_size
+ return [str(value) for value in pdb_ids.iloc[start : start + batch_size]]
+
+
+def _score_shard_batch(data_dir: Path, batch_index: int, batch_size: int) -> list[str]:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ _load_plan(data_dir)
+ shards = sorted({pdb_id[1:3] for pdb_id in published_scoring_query_ids(data_dir)})
+ start = batch_index * batch_size
+ return shards[start : start + batch_size]
+
+
+def plan_score_batches(
+ data_dir: Path,
+ *,
+ batch_size: int,
+ threads: int,
+ scratch_dir: Path,
+ max_query_protein_chains: int = 30,
+ max_query_proper_ligand_chains: int = 30,
+ reuse_mapped_alignments: bool = False,
+) -> dict[str, Any]:
+ """Estimate mapped-hit work and greedily balance fixed-size score batches.
+
+ ``reuse_mapped_alignments`` supports a derived-score repair after index
+ tables changed without invalidating the frozen mapped alignments. Fresh
+ ingest runs retain the strict source-signature check.
+ """
+ if (
+ min(
+ batch_size,
+ threads,
+ max_query_protein_chains,
+ max_query_proper_ligand_chains,
+ )
+ < 1
+ ):
+ raise ValueError("batch size, threads, and chain limits must be positive")
+ plan = _load_plan(
+ data_dir,
+ recheck_source=not reuse_mapped_alignments,
+ recheck_score_inputs=False,
+ )
+ annotation = data_dir / "index" / "annotation_table.parquet"
+ entry_chains = data_dir / "index" / "entry_chains.parquet"
+ alignment_paths = sorted(
+ (data_dir / "alignment_cigars" / "search_db=holo").glob(
+ "alignment_type=*/shard=*.parquet"
+ )
+ )
+ if not alignment_paths:
+ raise FileNotFoundError("no mapped alignment release shards found")
+
+ alignment_paths_sql = ", ".join(f"'{path.as_posix()}'" for path in alignment_paths)
+ hit_work_sql = dedent(
+ f"""
+ SELECT
+ hit.query_entry,
+ count(*)::BIGINT AS alignment_rows,
+ sum(coalesce(target.proper_ligand_rows, 0))::DOUBLE
+ AS target_ligand_hit_weight,
+ sum(coalesce(target.scoreable_canonical_ligands, 0))::DOUBLE
+ AS target_canonical_hit_weight
+ FROM read_parquet([{alignment_paths_sql}], union_by_name = true) AS hit
+ LEFT JOIN target_ligand_counts AS target
+ ON hit.target_entry = target.entry_pdb_id
+ GROUP BY hit.query_entry
+ """
+ )
+
+ import duckdb
+
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ work = connection.sql(
+ dedent(
+ f"""
+ WITH holo_annotation AS (
+ SELECT *
+ FROM read_parquet('{annotation.as_posix()}')
+ WHERE system_type = 'holo'
+ ), system_ligand_counts AS (
+ SELECT
+ entry_pdb_id,
+ system_id,
+ count(DISTINCT ligand_id) FILTER (
+ WHERE coalesce(ligand_is_proper, false)
+ )::BIGINT AS proper_ligand_chains
+ FROM holo_annotation
+ GROUP BY entry_pdb_id, system_id
+ ), system_receptor_chains AS (
+ SELECT DISTINCT
+ entry_pdb_id,
+ system_id,
+ unnest(system_protein_chains_asym_id)::VARCHAR
+ AS instance_chain
+ FROM holo_annotation
+ ), system_protein_counts AS (
+ SELECT
+ receptor.entry_pdb_id,
+ receptor.system_id,
+ count(*) FILTER (
+ WHERE chains.chain_receptor_type = 'protein'
+ )::BIGINT AS protein_chains
+ FROM system_receptor_chains AS receptor
+ LEFT JOIN read_parquet('{entry_chains.as_posix()}') AS chains
+ ON receptor.entry_pdb_id = chains.entry_pdb_id
+ AND split_part(receptor.instance_chain, '.', 2)
+ = chains.chain_asym_id
+ GROUP BY receptor.entry_pdb_id, receptor.system_id
+ ), system_counts AS (
+ SELECT
+ ligands.entry_pdb_id,
+ ligands.system_id,
+ coalesce(proteins.protein_chains, 0)::BIGINT
+ AS protein_chains,
+ ligands.proper_ligand_chains
+ FROM system_ligand_counts AS ligands
+ LEFT JOIN system_protein_counts AS proteins
+ USING (entry_pdb_id, system_id)
+ ), eligible_systems AS (
+ SELECT entry_pdb_id, system_id
+ FROM system_counts
+ WHERE protein_chains BETWEEN 1 AND {max_query_protein_chains}
+ AND proper_ligand_chains > 0
+ AND proper_ligand_chains <= {max_query_proper_ligand_chains}
+ ), target_systems AS (
+ SELECT entry_pdb_id, system_id
+ FROM system_counts
+ WHERE protein_chains > 0
+ AND proper_ligand_chains > 0
+ ), target_ligand_counts AS (
+ SELECT
+ annotation.entry_pdb_id,
+ count(*) FILTER (
+ WHERE coalesce(annotation.ligand_is_proper, false)
+ )::DOUBLE AS proper_ligand_rows,
+ count(DISTINCT annotation.ligand_asym_id) FILTER (
+ WHERE coalesce(annotation.ligand_is_proper, false)
+ AND coalesce(annotation.ligand_is_shape_comparable, false)
+ )::DOUBLE AS scoreable_canonical_ligands
+ FROM holo_annotation AS annotation
+ INNER JOIN target_systems USING (entry_pdb_id, system_id)
+ GROUP BY annotation.entry_pdb_id
+ ), query_ligand_counts AS (
+ SELECT
+ annotation.entry_pdb_id,
+ count(*) FILTER (
+ WHERE coalesce(annotation.ligand_is_proper, false)
+ )::DOUBLE AS proper_ligand_rows,
+ count(DISTINCT annotation.ligand_asym_id) FILTER (
+ WHERE coalesce(annotation.ligand_is_proper, false)
+ AND coalesce(annotation.ligand_is_shape_comparable, false)
+ )::DOUBLE AS scoreable_canonical_ligands
+ FROM holo_annotation AS annotation
+ INNER JOIN eligible_systems USING (entry_pdb_id, system_id)
+ GROUP BY annotation.entry_pdb_id
+ ), eligible_queries AS (
+ SELECT DISTINCT entry_pdb_id
+ FROM eligible_systems
+ ), hit_work_parts AS (
+ {hit_work_sql}
+ ), hit_work AS (
+ SELECT
+ query_entry,
+ sum(alignment_rows)::BIGINT AS alignment_rows,
+ sum(target_ligand_hit_weight)::DOUBLE
+ AS target_ligand_hit_weight,
+ sum(target_canonical_hit_weight)::DOUBLE
+ AS target_canonical_hit_weight
+ FROM hit_work_parts
+ GROUP BY query_entry
+ )
+ SELECT
+ query.pdb_id,
+ query.shard,
+ coalesce(hit.alignment_rows, 0)::BIGINT AS alignment_rows,
+ coalesce(query_ligands.proper_ligand_rows, 0)
+ * coalesce(hit.target_ligand_hit_weight, 0)
+ AS ligand_pair_work,
+ coalesce(query_ligands.scoreable_canonical_ligands, 0)
+ * coalesce(hit.target_canonical_hit_weight, 0)
+ AS canonical_3d_work
+ FROM read_parquet(
+ '{(data_dir / MANIFEST_RELATIVE).as_posix()}'
+ ) AS query
+ INNER JOIN eligible_queries AS eligible
+ ON query.pdb_id = eligible.entry_pdb_id
+ LEFT JOIN query_ligand_counts AS query_ligands
+ ON query.pdb_id = query_ligands.entry_pdb_id
+ LEFT JOIN hit_work AS hit
+ ON query.pdb_id = hit.query_entry
+ """
+ )
+ ).df()
+ connection.close()
+ dropped = dropped_query_ids(data_dir)
+ if dropped:
+ work = work[~work["pdb_id"].astype(str).isin(dropped)].copy()
+ if work.empty:
+ raise ValueError("no scoreable systems satisfy the configured chain limits")
+ work["estimated_work"] = work["ligand_pair_work"] + 2.0 * work["canonical_3d_work"]
+
+ assignment: dict[str, int] = {}
+ loads: list[float] = []
+ counts: list[int] = []
+ for _, shard_work in work.groupby("shard", sort=True):
+ shard_batch_count = math.ceil(len(shard_work) / batch_size)
+ offset = len(loads)
+ loads.extend([0.0] * shard_batch_count)
+ counts.extend([0] * shard_batch_count)
+ for row in shard_work.sort_values(
+ ["estimated_work", "pdb_id"], ascending=[False, True]
+ ).itertuples(index=False):
+ eligible = [
+ offset + local_index
+ for local_index in range(shard_batch_count)
+ if counts[offset + local_index] < batch_size
+ ]
+ selected = min(
+ eligible, key=lambda index: (loads[index], counts[index], index)
+ )
+ assignment[str(row.pdb_id)] = selected
+ loads[selected] += float(row.estimated_work)
+ counts[selected] += 1
+ batch_count = len(loads)
+ work["score_batch_index"] = work["pdb_id"].map(assignment).astype("int32")
+ work = work.sort_values(
+ ["score_batch_index", "estimated_work", "pdb_id"],
+ ascending=[True, False, True],
+ ignore_index=True,
+ )
+ output = data_dir / SCORE_WORK_RELATIVE
+ _atomic_parquet(work, output)
+ plan.pop("score_max_protein_chains", None)
+ plan.pop("score_max_ligand_chains", None)
+ plan.update(
+ {
+ "score_batch_size": batch_size,
+ "score_batch_count": batch_count,
+ "score_max_query_protein_chains": max_query_protein_chains,
+ "score_max_query_proper_ligand_chains": (max_query_proper_ligand_chains),
+ "score_reused_mapped_alignments": reuse_mapped_alignments,
+ "score_annotation": _source_signature(annotation),
+ "score_batch_estimated_work_min": min(loads),
+ "score_batch_estimated_work_max": max(loads),
+ "score_work": _source_signature(output),
+ }
+ )
+ write_json_atomic(data_dir / PLAN_RELATIVE, plan)
+ return {
+ "query_count": len(work),
+ "batch_size": batch_size,
+ "batch_count": batch_count,
+ "estimated_work_min": min(loads),
+ "estimated_work_max": max(loads),
+ }
+
+
+def _ligand_3d_candidate_files(data_dir: Path) -> list[Path]:
+ return sorted(
+ (data_dir / "scores" / "ligand_3d_candidate_shards").glob("shard=*.parquet")
+ )
+
+
+def plan_ligand_3d_batches(
+ data_dir: Path,
+ *,
+ batch_size: int,
+ threads: int,
+ scratch_dir: Path,
+ memory_limit: str = "8GB",
+) -> dict[str, Any]:
+ """Freeze every scoreable canonical pair with positive pocket coverage."""
+ started = perf_counter()
+ if batch_size < 1 or threads < 1:
+ raise ValueError("batch size and threads must be positive")
+ plan = _load_plan(data_dir)
+ protein_work = pd.read_parquet(data_dir / SCORE_WORK_RELATIVE, columns=["pdb_id"])
+ expected_pdb_ids = set(protein_work["pdb_id"].astype(str)).difference(
+ dropped_query_ids(data_dir)
+ )
+ expected_shards = {pdb_id[1:3] for pdb_id in expected_pdb_ids}
+ candidate_files = _ligand_3d_candidate_files(data_dir)
+ observed_shards = {path.stem.removeprefix("shard=") for path in candidate_files}
+ missing_shards = expected_shards - observed_shards
+ extra_shards = observed_shards - expected_shards
+ if missing_shards or extra_shards:
+ raise ValueError(
+ "ligand 3D candidate shards do not cover planned score queries: "
+ f"missing={sorted(missing_shards)[:10]}, "
+ f"extra={sorted(extra_shards)[:10]}"
+ )
+ candidate_signatures = []
+ pair_candidate_paths: list[Path] = []
+ manifested_pdb_ids: set[str] = set()
+ for path in candidate_files:
+ shard = path.stem.removeprefix("shard=")
+ manifest_path = path.with_suffix(".json")
+ try:
+ manifest = json.loads(manifest_path.read_text())
+ except (OSError, TypeError, ValueError) as exc:
+ raise ValueError(
+ f"invalid ligand 3D candidate shard manifest: {manifest_path}"
+ ) from exc
+ schema = pq.read_schema(path)
+ missing = sorted(
+ set(schemas.LIGAND_3D_CANDIDATE_SCHEMA.names).difference(schema.names)
+ )
+ if missing:
+ raise ValueError(f"candidate file {path} is missing columns {missing}")
+ stat = path.stat()
+ output_signature = {
+ "path": str(path.resolve()),
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ "rows": pq.ParquetFile(path).metadata.num_rows,
+ }
+ inputs = manifest.get("inputs")
+ if (
+ manifest.get("shard") != shard
+ or manifest.get("output") != output_signature
+ or not isinstance(inputs, list)
+ ):
+ raise ValueError(f"stale ligand 3D candidate shard: {path}")
+ pair_output = manifest.get("pair_output")
+ pair_path = (
+ data_dir
+ / "scores"
+ / "ligand_3d_pair_candidate_shards"
+ / f"shard={shard}.parquet"
+ )
+ if not isinstance(pair_output, dict) or not pair_path.is_file():
+ raise ValueError(f"missing compact ligand 3D candidate shard: {pair_path}")
+ pair_schema = pq.read_schema(pair_path)
+ pair_missing = sorted(
+ set(schemas.LIGAND_3D_PAIR_CANDIDATE_SCHEMA.names).difference(
+ pair_schema.names
+ )
+ )
+ if pair_missing:
+ raise ValueError(
+ f"compact candidate file {pair_path} is missing {pair_missing}"
+ )
+ pair_stat = pair_path.stat()
+ pair_output_signature = {
+ "path": str(pair_path.resolve()),
+ "size": pair_stat.st_size,
+ "mtime_ns": pair_stat.st_mtime_ns,
+ "rows": pq.ParquetFile(pair_path).metadata.num_rows,
+ }
+ if pair_output != pair_output_signature:
+ raise ValueError(f"stale compact ligand 3D candidate shard: {pair_path}")
+ pair_candidate_paths.append(pair_path)
+ ligand_pair_output = manifest.get("ligand_pair_output")
+ ligand_pair_path = (
+ data_dir / "scores" / "ligand_pair_score_shards" / f"shard={shard}.parquet"
+ )
+ if not isinstance(ligand_pair_output, dict) or not ligand_pair_path.is_file():
+ raise ValueError(f"missing ligand pair score shard: {ligand_pair_path}")
+ if not pq.read_schema(ligand_pair_path).equals(
+ schemas.LIGAND_PAIR_SCORE_SCHEMA
+ ):
+ raise ValueError(
+ f"ligand pair score shard has an unexpected schema: {ligand_pair_path}"
+ )
+ ligand_pair_stat = ligand_pair_path.stat()
+ ligand_pair_output_signature = {
+ "path": str(ligand_pair_path.resolve()),
+ "size": ligand_pair_stat.st_size,
+ "mtime_ns": ligand_pair_stat.st_mtime_ns,
+ "rows": pq.ParquetFile(ligand_pair_path).metadata.num_rows,
+ }
+ if ligand_pair_output != ligand_pair_output_signature:
+ raise ValueError(f"stale ligand pair score shard: {ligand_pair_path}")
+ for source in inputs:
+ if not isinstance(source, dict):
+ raise ValueError(f"invalid candidate input in {manifest_path}")
+ source_pdb_id = str(source.get("pdb_id", ""))
+ if not source_pdb_id:
+ raise ValueError(f"invalid candidate input in {manifest_path}")
+ manifested_pdb_ids.add(source_pdb_id)
+ candidate_signatures.append(
+ {
+ "shard": shard,
+ **output_signature,
+ "pair_path": pair_output_signature["path"],
+ "pair_size": pair_output_signature["size"],
+ "pair_mtime_ns": pair_output_signature["mtime_ns"],
+ "pair_rows": pair_output_signature["rows"],
+ "ligand_pair_path": ligand_pair_output_signature["path"],
+ "ligand_pair_size": ligand_pair_output_signature["size"],
+ "ligand_pair_mtime_ns": ligand_pair_output_signature["mtime_ns"],
+ "ligand_pair_rows": ligand_pair_output_signature["rows"],
+ }
+ )
+ LOG.info(
+ "ligand 3D planning: validated %d candidate shards in %.1fs",
+ len(candidate_files),
+ perf_counter() - started,
+ )
+ if manifested_pdb_ids != expected_pdb_ids:
+ raise ValueError(
+ "collated ligand 3D candidates do not cover their query shards: "
+ f"missing={sorted(expected_pdb_ids - manifested_pdb_ids)[:10]}, "
+ f"extra={sorted(manifested_pdb_ids - expected_pdb_ids)[:10]}"
+ )
+
+ candidate_manifest = data_dir / LIGAND_3D_CANDIDATE_MANIFEST_RELATIVE
+ work_path = data_dir / LIGAND_3D_WORK_RELATIVE
+ candidate_frame = pd.DataFrame(candidate_signatures).sort_values(
+ "shard", ignore_index=True
+ )
+ plan_is_current = False
+ if candidate_manifest.is_file() and work_path.is_file():
+ try:
+ plan_is_current = (
+ int(plan.get("ligand_3d_batch_size", -1)) == batch_size
+ and _source_signature(candidate_manifest)
+ == plan.get("ligand_3d_candidate_manifest")
+ and _source_signature(work_path) == plan.get("ligand_3d_work")
+ and pd.read_parquet(candidate_manifest).equals(candidate_frame)
+ )
+ except (OSError, TypeError, ValueError):
+ plan_is_current = False
+
+ if plan_is_current:
+ return {
+ "pair_count": int(plan["ligand_3d_pair_count"]),
+ "batch_size": batch_size,
+ "batch_count": int(plan["ligand_3d_batch_count"]),
+ "estimated_work_min": float(plan["ligand_3d_estimated_work_min"]),
+ "estimated_work_max": float(plan["ligand_3d_estimated_work_max"]),
+ "cached": True,
+ }
+
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ import duckdb
+
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql("SET preserve_insertion_order=false")
+ annotation = data_dir / "index" / "annotation_table.parquet"
+ pair_paths_sql = ", ".join(f"'{path.as_posix()}'" for path in pair_candidate_paths)
+ planned_path = scratch_dir / "ligand-3d-work.parquet"
+ planned_path.unlink(missing_ok=True)
+ connection.sql(
+ dedent(
+ f"""
+ COPY (
+ WITH ligand_sizes AS (
+ SELECT
+ entry_pdb_id AS entry,
+ ligand_asym_id AS asym_id,
+ max(greatest(coalesce(ligand_num_heavy_atoms, 1), 1))::BIGINT
+ AS heavy_atoms
+ FROM read_parquet('{annotation.as_posix()}')
+ WHERE system_type = 'holo'
+ AND coalesce(ligand_is_proper, false)
+ AND coalesce(ligand_is_shape_comparable, false)
+ GROUP BY entry_pdb_id, ligand_asym_id
+ ), scoreable_pairs AS (
+ SELECT candidate_pairs.*,
+ (query.heavy_atoms * target.heavy_atoms)::BIGINT
+ AS estimated_work
+ FROM read_parquet([{pair_paths_sql}]) AS candidate_pairs
+ INNER JOIN ligand_sizes AS query
+ ON candidate_pairs.query_entry = query.entry
+ AND candidate_pairs.query_ligand_asym_id = query.asym_id
+ INNER JOIN ligand_sizes AS target
+ ON candidate_pairs.target_entry = target.entry
+ AND candidate_pairs.target_ligand_asym_id = target.asym_id
+ WHERE candidate_pairs.pocket_qcov > 0
+ )
+ SELECT
+ query_entry,
+ query_ligand_asym_id,
+ target_entry,
+ target_ligand_asym_id,
+ estimated_work,
+ floor((row_number() OVER (
+ ORDER BY
+ query_entry,
+ query_ligand_asym_id,
+ estimated_work DESC,
+ target_entry,
+ target_ligand_asym_id
+ ) - 1) / {batch_size})::INTEGER AS ligand_3d_batch_index
+ FROM scoreable_pairs
+ ) TO '{planned_path.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE {max(2_048, batch_size)}
+ )
+ """
+ )
+ )
+
+ counts = connection.sql(
+ f"""
+ SELECT
+ count(*)::BIGINT AS pair_count,
+ count(DISTINCT substr(query_entry, 2, 2))::BIGINT AS query_shards,
+ coalesce(max(ligand_3d_batch_index) + 1, 0)::BIGINT AS batch_count
+ FROM read_parquet('{planned_path.as_posix()}')
+ """
+ ).fetchone()
+ load_bounds = connection.sql(
+ f"""
+ SELECT
+ coalesce(min(batch_work), 0)::DOUBLE,
+ coalesce(max(batch_work), 0)::DOUBLE,
+ coalesce(max(batch_rows), 0)::BIGINT
+ FROM (
+ SELECT
+ ligand_3d_batch_index,
+ sum(estimated_work)::DOUBLE AS batch_work,
+ count(*)::BIGINT AS batch_rows
+ FROM read_parquet('{planned_path.as_posix()}')
+ GROUP BY ligand_3d_batch_index
+ )
+ """
+ ).fetchone()
+ connection.close()
+ if counts is None or load_bounds is None:
+ raise RuntimeError("failed to validate ligand 3D work plan")
+ pair_count, query_shard_count, batch_count = (int(value) for value in counts)
+ estimated_work_min, estimated_work_max, maximum_batch_rows = load_bounds
+ if maximum_batch_rows > batch_size:
+ raise ValueError(
+ f"ligand 3D batch exceeds size {batch_size}: {maximum_batch_rows}"
+ )
+ work_path.parent.mkdir(exist_ok=True, parents=True)
+ install = work_path.with_suffix(work_path.suffix + ".tmp")
+ copyfile(planned_path, install)
+ install.replace(work_path)
+ planned_path.unlink(missing_ok=True)
+ _atomic_parquet(candidate_frame, candidate_manifest)
+ plan.update(
+ {
+ "ligand_3d_batch_size": batch_size,
+ "ligand_3d_batch_count": batch_count,
+ "ligand_3d_pair_count": pair_count,
+ "ligand_3d_plan_complete": True,
+ "ligand_3d_query_shard_count": query_shard_count,
+ "ligand_3d_estimated_work_min": estimated_work_min,
+ "ligand_3d_estimated_work_max": estimated_work_max,
+ "ligand_3d_candidate_manifest": _source_signature(candidate_manifest),
+ "ligand_3d_work": _source_signature(work_path),
+ }
+ )
+ for key in list(plan):
+ if key.startswith("ligand_3d_retry_"):
+ plan.pop(key)
+ write_json_atomic(data_dir / PLAN_RELATIVE, plan)
+ LOG.info(
+ "ligand 3D planning: wrote %d pairs in %d batches (total %.1fs)",
+ pair_count,
+ batch_count,
+ perf_counter() - started,
+ )
+ return {
+ "pair_count": pair_count,
+ "batch_size": batch_size,
+ "batch_count": batch_count,
+ "estimated_work_min": estimated_work_min,
+ "estimated_work_max": estimated_work_max,
+ "cached": False,
+ }
+
+
+def _ligand_3d_batch(data_dir: Path, batch_index: int, batch_size: int) -> pd.DataFrame:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ plan = _load_plan(data_dir)
+ if batch_size != int(plan.get("ligand_3d_batch_size", -1)):
+ raise ValueError(
+ f"ligand 3D batch size is {plan.get('ligand_3d_batch_size')}, "
+ f"got {batch_size}"
+ )
+ work_path = data_dir / LIGAND_3D_WORK_RELATIVE
+ if _source_signature(work_path) != plan.get("ligand_3d_work"):
+ raise ValueError("ligand 3D work manifest changed after planning")
+ return pd.read_parquet(
+ work_path,
+ filters=[("ligand_3d_batch_index", "==", batch_index)],
+ )
+
+
+def plan_ligand_3d_retries(
+ data_dir: Path,
+ *,
+ batch_size: int,
+) -> dict[str, Any]:
+ """Split only missing large 3D batches into small resumable retry units."""
+ if batch_size < 1:
+ raise ValueError("ligand 3D retry batch size must be positive")
+ plan = _load_plan(data_dir)
+ if not plan.get("ligand_3d_plan_complete", False):
+ raise ValueError("complete ligand 3D candidate planning before retry planning")
+ work_path = data_dir / LIGAND_3D_WORK_RELATIVE
+ if _source_signature(work_path) != plan.get("ligand_3d_work"):
+ raise ValueError("ligand 3D work manifest changed after planning")
+ batch_count = int(plan["ligand_3d_batch_count"])
+ output_dir = data_dir / "scores" / "ligand_3d_pairs"
+ missing_original = [
+ index
+ for index in range(batch_count)
+ if not (output_dir / f"{index}.parquet").is_file()
+ ]
+ if missing_original:
+ work = pd.read_parquet(
+ work_path,
+ filters=[("ligand_3d_batch_index", "in", missing_original)],
+ )
+ else:
+ work = pd.DataFrame()
+ parts: list[pd.DataFrame] = []
+ retry_index = 0
+ if not work.empty:
+ order = [
+ "query_entry",
+ "query_ligand_asym_id",
+ "estimated_work",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ ascending = [True, True, False, True, True]
+ for original_index, group in work.groupby("ligand_3d_batch_index", sort=True):
+ group = group.sort_values(order, ascending=ascending, ignore_index=True)
+ for start in range(0, len(group), batch_size):
+ part = group.iloc[start : start + batch_size].copy()
+ part["original_ligand_3d_batch_index"] = int(original_index)
+ part["retry_batch_index"] = retry_index
+ parts.append(part)
+ retry_index += 1
+ retry_work = (
+ pd.concat(parts, ignore_index=True)
+ if parts
+ else pd.DataFrame(
+ columns=[
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ "estimated_work",
+ "ligand_3d_batch_index",
+ "original_ligand_3d_batch_index",
+ "retry_batch_index",
+ ]
+ )
+ )
+ retry_path = data_dir / LIGAND_3D_RETRY_WORK_RELATIVE
+ _atomic_parquet(retry_work, retry_path)
+ plan.update(
+ {
+ "ligand_3d_retry_batch_size": batch_size,
+ "ligand_3d_retry_batch_count": retry_index,
+ "ligand_3d_retry_original_batches": missing_original,
+ "ligand_3d_retry_work": _source_signature(retry_path),
+ }
+ )
+ write_json_atomic(data_dir / PLAN_RELATIVE, plan)
+ return {
+ "status": "planned",
+ "missing_original_batch_count": len(missing_original),
+ "retry_pair_count": len(retry_work),
+ "retry_batch_size": batch_size,
+ "retry_batch_count": retry_index,
+ }
+
+
+def _ligand_3d_retry_batch(
+ data_dir: Path, batch_index: int, batch_size: int
+) -> pd.DataFrame:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch index must be non-negative and batch size positive")
+ plan = _load_plan(data_dir)
+ if batch_size != int(plan.get("ligand_3d_retry_batch_size", -1)):
+ raise ValueError(
+ f"ligand 3D retry batch size is "
+ f"{plan.get('ligand_3d_retry_batch_size')}, got {batch_size}"
+ )
+ retry_path = data_dir / LIGAND_3D_RETRY_WORK_RELATIVE
+ if _source_signature(retry_path) != plan.get("ligand_3d_retry_work"):
+ raise ValueError("ligand 3D retry work changed after planning")
+ return pd.read_parquet(
+ retry_path,
+ filters=[("retry_batch_index", "==", batch_index)],
+ )
+
+
+def finalize_ligand_3d_retries(
+ data_dir: Path,
+) -> dict[str, Any]:
+ """Reassemble complete fine-grained retries into their original batches."""
+ plan = _load_plan(data_dir)
+ retry_path = data_dir / LIGAND_3D_RETRY_WORK_RELATIVE
+ if _source_signature(retry_path) != plan.get("ligand_3d_retry_work"):
+ raise ValueError("ligand 3D retry work changed after planning")
+ retry_work = pd.read_parquet(retry_path)
+ pair_columns = [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ retry_output_dir = data_dir / "scores" / "ligand_3d_pair_retries"
+ valid_outputs: dict[int, pd.DataFrame] = {}
+ incomplete: list[int] = []
+ for retry_index, expected in retry_work.groupby("retry_batch_index", sort=True):
+ retry_index = int(retry_index)
+ path = retry_output_dir / f"{retry_index}.parquet"
+ try:
+ schema = pq.read_schema(path)
+ observed = pd.read_parquet(path)
+ expected_pairs = pd.MultiIndex.from_frame(expected[pair_columns])
+ observed_pairs = pd.MultiIndex.from_frame(observed[pair_columns])
+ valid = set(schemas.LIGAND_3D_SCORE_SCHEMA.names).issubset(
+ schema.names
+ ) and observed_pairs.equals(expected_pairs)
+ except (OSError, ValueError):
+ valid = False
+ observed = pd.DataFrame()
+ if valid:
+ valid_outputs[retry_index] = observed
+ else:
+ incomplete.append(retry_index)
+ if incomplete:
+ raise ValueError(f"ligand 3D retries remain incomplete: {incomplete[:20]}")
+
+ canonical_dir = data_dir / "scores" / "ligand_3d_pairs"
+ canonical_dir.mkdir(exist_ok=True, parents=True)
+ for original_index, expected_original in retry_work.groupby(
+ "original_ligand_3d_batch_index", sort=True
+ ):
+ scored_parts: list[pd.DataFrame] = []
+ for retry_index, _expected in expected_original.groupby(
+ "retry_batch_index", sort=True
+ ):
+ retry_index = int(retry_index)
+ scored_parts.append(valid_outputs[retry_index])
+ combined = pd.concat(scored_parts, ignore_index=True)
+ expected_pairs = pd.MultiIndex.from_frame(expected_original[pair_columns])
+ combined_pairs = pd.MultiIndex.from_frame(combined[pair_columns])
+ if len(combined) != len(expected_original) or set(combined_pairs) != set(
+ expected_pairs
+ ):
+ raise ValueError(
+ f"retry collation changed canonical pairs for batch {original_index}"
+ )
+ combined = expected_original[pair_columns].merge(
+ combined,
+ on=pair_columns,
+ how="left",
+ validate="one_to_one",
+ )
+ output = canonical_dir / f"{int(original_index)}.parquet"
+ temporary = output.with_suffix(".tmp.parquet")
+ combined.to_parquet(
+ temporary,
+ schema=schemas.LIGAND_3D_SCORE_SCHEMA,
+ index=False,
+ )
+ temporary.replace(output)
+
+ plan["ligand_3d_retry_complete"] = True
+ write_json_atomic(data_dir / PLAN_RELATIVE, plan)
+ return {
+ "status": "complete",
+ "retry_batch_count": int(plan["ligand_3d_retry_batch_count"]),
+ "completed_retry_batch_count": len(valid_outputs),
+ }
+
+
+def _ligand_3d_shard_batch(
+ data_dir: Path, batch_index: int, batch_size: int
+) -> list[str]:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ _load_plan(data_dir)
+ shards = sorted({pdb_id[1:3] for pdb_id in published_scoring_query_ids(data_dir)})
+ start = batch_index * batch_size
+ return shards[start : start + batch_size]
+
+
+def finalize_ligand_archives(
+ data_dir: Path,
+ *,
+ archive_dir: Path | None = None,
+ expected_shards: list[str] | None = None,
+ threads: int = 4,
+ memory_limit: str = "8GB",
+) -> dict[str, Any]:
+ """Validate canonical SDF coverage; updates can supply a staged archive folder."""
+ archive_dir = archive_dir or data_dir / "ligand_archives"
+ if expected_shards is None:
+ expected_shards = [
+ path.name
+ for path in (data_dir / "raw_entries").iterdir()
+ if path.is_dir() and any(path.glob("*.parquet"))
+ ]
+ expected_shards = sorted(expected_shards)
+ expected_shard_set = set(expected_shards)
+ archives = []
+ for path in sorted(archive_dir.glob("*.parquet")):
+ if path.stem not in expected_shard_set and pq.read_metadata(path).num_rows == 0:
+ LOG.info(f"removing stale empty canonical ligand archive {path}")
+ path.unlink()
+ continue
+ archives.append(path)
+ observed_shards = [path.stem for path in archives]
+ if observed_shards != expected_shards:
+ raise ValueError(
+ "canonical ligand archive shards do not match raw entries: "
+ f"missing={sorted(set(expected_shards) - set(observed_shards))[:10]}, "
+ f"extra={sorted(set(observed_shards) - set(expected_shards))[:10]}"
+ )
+
+ if not archives:
+ annotation = data_dir / "index" / "annotation_table.parquet"
+ if annotation.is_file() and pq.read_metadata(annotation).num_rows:
+ raise ValueError(
+ "canonical ligand archives are empty but annotation has ligands"
+ )
+ report = {
+ "status": "complete",
+ "shard_count": 0,
+ "ligand_count": 0,
+ "compressed_bytes": 0,
+ }
+ write_json_atomic(archive_dir / "manifest.json", report)
+ return report
+
+ import duckdb
+
+ annotation = data_dir / "index" / "annotation_table.parquet"
+ with duckdb.connect() as connection:
+ collate._configure_duckdb(
+ connection, threads=threads, memory_limit=memory_limit, scratch_dir=None
+ )
+ connection.read_parquet(
+ [str(path) for path in archives], union_by_name=True
+ ).create_view("packed")
+ connection.read_parquet(str(annotation)).create_view("annotation")
+ row_count, unique_count, empty_count = connection.sql(
+ """
+ SELECT
+ count(*)::BIGINT,
+ count(DISTINCT (pdb_id, ligand_asym_id))::BIGINT,
+ count(*) FILTER (WHERE sdf IS NULL OR octet_length(sdf) = 0
+ OR pdb_id IS NULL OR ligand_asym_id IS NULL)::BIGINT
+ FROM packed
+ """
+ ).fetchall()[0]
+ missing_count = connection.sql(
+ """
+ WITH expected AS (
+ SELECT DISTINCT
+ entry_pdb_id AS pdb_id,
+ ligand_asym_id
+ FROM annotation
+ WHERE ligand_asym_id IS NOT NULL
+ )
+ SELECT count(*)::BIGINT
+ FROM expected
+ ANTI JOIN packed USING (pdb_id, ligand_asym_id)
+ """
+ ).fetchall()[0][0]
+ if row_count != unique_count:
+ raise ValueError(
+ f"packed canonical ligand keys are not unique: {row_count} rows, "
+ f"{unique_count} unique keys"
+ )
+ if empty_count or missing_count:
+ raise ValueError(
+ "invalid packed canonical ligands: "
+ f"empty_sdfs={empty_count}, missing_index_ligands={missing_count}"
+ )
+ report = {
+ "status": "complete",
+ "shard_count": len(archives),
+ "ligand_count": row_count,
+ "compressed_bytes": sum(path.stat().st_size for path in archives),
+ }
+ write_json_atomic(archive_dir / "manifest.json", report)
+ return report
+
+
+def make_foldseek_input_manifest(data_dir: Path, cif_root: Path) -> Path:
+ """List release entries containing protein chains without walking PDB."""
+ _load_plan(data_dir, recheck_source=True)
+ pdb_ids = (
+ pd.read_parquet(
+ data_dir / "index" / "entry_chains.parquet",
+ columns=["entry_pdb_id"],
+ filters=[("chain_receptor_type", "==", "protein")],
+ )["entry_pdb_id"]
+ .astype(str)
+ .drop_duplicates()
+ .sort_values()
+ )
+ output = data_dir / FOLDSEEK_INPUT_RELATIVE
+ output.parent.mkdir(exist_ok=True, parents=True)
+ temporary = output.with_suffix(".tmp.tsv")
+ with temporary.open("w") as handle:
+ for pdb_id in pdb_ids:
+ cif_path = (
+ cif_root
+ / pdb_id[1:3]
+ / f"pdb_0000{pdb_id}"
+ / f"pdb_0000{pdb_id}_xyz-enrich.cif.gz"
+ )
+ handle.write(f"{cif_path}\n")
+ temporary.replace(output)
+ return output
+
+
+def make_mmseqs_input_fasta(data_dir: Path) -> Path:
+ """Write all release protein chains using the PDB/auth-chain identifiers."""
+ chains = pd.read_parquet(
+ data_dir / "index" / "entry_chains.parquet",
+ columns=[
+ "entry_pdb_id",
+ "chain_auth_id",
+ "chain_receptor_type",
+ "chain_sequence",
+ ],
+ filters=[("chain_receptor_type", "==", "protein")],
+ )
+ chains = chains.loc[
+ chains["chain_auth_id"].notna()
+ & chains["chain_sequence"].notna()
+ & chains["chain_sequence"].ne("")
+ ].copy()
+ chains["identifier"] = (
+ chains["entry_pdb_id"].astype(str) + "_" + chains["chain_auth_id"].astype(str)
+ )
+ sequence_counts = chains.groupby("identifier", observed=True)[
+ "chain_sequence"
+ ].nunique()
+ conflicting = sequence_counts[sequence_counts.gt(1)].index.tolist()
+ if conflicting:
+ raise ValueError(
+ "auth-chain identifiers have conflicting protein sequences: "
+ f"{conflicting[:10]}"
+ )
+ chains = chains.drop_duplicates("identifier").sort_values("identifier")
+ if not chains["chain_sequence"].astype(str).str.fullmatch("[A-Za-z]+").all():
+ raise ValueError("protein sequences must contain one-letter amino-acid codes")
+ output = data_dir / "manifests" / "mmseqs_createdb_inputs.fasta"
+ output.parent.mkdir(exist_ok=True, parents=True)
+ temporary = output.with_suffix(".tmp.fasta")
+ with temporary.open("w") as handle:
+ for row in chains.itertuples(index=False):
+ handle.write(f">{row.identifier}\n{row.chain_sequence}\n")
+ temporary.replace(output)
+ return output
+
+
+def _shard_batch(
+ data_dir: Path,
+ batch_index: int,
+ batch_size: int,
+ *,
+ search_db: str = "holo",
+) -> list[str]:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ if search_db == "apo":
+ _load_linked_apo_plan(data_dir)
+ else:
+ _load_plan(data_dir)
+ manifest_paths = (
+ [
+ data_dir / LINKED_APO_QUERY_MANIFEST_RELATIVE,
+ data_dir / INTERFACE_APO_QUERY_MANIFEST_RELATIVE,
+ ]
+ if search_db == "apo"
+ else [data_dir / MANIFEST_RELATIVE]
+ )
+ shards = sorted(
+ {
+ str(shard)
+ for path in manifest_paths
+ for shard in pd.read_parquet(path, columns=["shard"])["shard"].unique()
+ }
+ )
+ start = batch_index * batch_size
+ return [str(value) for value in shards[start : start + batch_size]]
+
+
+def _entry_shard_batch(data_dir: Path, batch_index: int, batch_size: int) -> list[str]:
+ """Select raw-entry shards, including entries without protein receptors."""
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ shards = sorted(
+ path.name for path in (data_dir / "raw_entries").iterdir() if path.is_dir()
+ )
+ start = batch_index * batch_size
+ return shards[start : start + batch_size]
+
+
+def _score_partition_batch(batch_index: int, batch_size: int) -> list[str]:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ partitions = [chunk[0] for chunk in tasks.scatter_collate_partitions()]
+ start = batch_index * batch_size
+ return partitions[start : start + batch_size]
+
+
+def _cluster_parameters(
+ *,
+ metrics: list[str] | None,
+ thresholds: list[int] | None,
+ entity_type: clusters.ClusterEntity = "ligand",
+) -> tuple[list[str], list[int]]:
+ defaults = (
+ DEFAULT_CLUSTER_METRICS
+ if entity_type == "ligand"
+ else sorted(clusters.INTERFACE_CLUSTER_METRICS)
+ )
+ selected_metrics = list(dict.fromkeys(metrics or defaults))
+ selected_thresholds = sorted(
+ set(thresholds or DEFAULT_CLUSTER_THRESHOLDS), reverse=True
+ )
+ if not selected_metrics:
+ raise ValueError("at least one clustering metric is required")
+ supported = (
+ set(DEFAULT_CLUSTER_METRICS)
+ if entity_type == "ligand"
+ else set(clusters.INTERFACE_CLUSTER_METRICS)
+ )
+ unsupported = sorted(set(selected_metrics).difference(supported))
+ if unsupported:
+ if set(unsupported).intersection({"shape", "color", "sucos_shape"}):
+ raise ValueError(
+ "raw 3D ligand diagnostics cannot be clustered; use "
+ "sucos_shape_pocket_qcov"
+ )
+ raise ValueError(f"unsupported release clustering metrics: {unsupported}")
+ if not selected_thresholds or not all(
+ 0 <= threshold <= 100 for threshold in selected_thresholds
+ ):
+ raise ValueError("clustering thresholds must be in [0, 100]")
+ return selected_metrics, selected_thresholds
+
+
+def _interface_clustering_min_residues(data_dir: Path) -> tuple[int, bool]:
+ """Return the ingest-frozen interface threshold and whether it is authoritative."""
+ marker_path = data_dir / "index" / "collation.json"
+ if not marker_path.is_file():
+ return DEFAULT_MIN_INTERFACE_RESIDUES, False
+ try:
+ marker = cast(dict[str, Any], json.loads(marker_path.read_text()))
+ threshold = int(marker["interface_min_residues"])
+ except (OSError, KeyError, TypeError, ValueError, json.JSONDecodeError) as exc:
+ raise ValueError(
+ "collated interface annotations do not record "
+ "interface.min_interface_residues"
+ ) from exc
+ if threshold < 1:
+ raise ValueError("collated interface minimum must be positive")
+ return threshold, True
+
+
+def _validate_interface_clustering_universe(
+ data_dir: Path, *, min_interface_residues: int
+) -> None:
+ """Ensure clustering sees the same residue-filtered universe as ingest."""
+ import duckdb
+
+ annotation_path = data_dir / "index" / "interface_annotation_table.parquet"
+ row = duckdb.sql(
+ dedent(
+ f"""
+ SELECT count(*)
+ FROM read_parquet('{annotation_path.as_posix()}')
+ WHERE len(interface_chain_1_residue_numbers) < {min_interface_residues}
+ OR len(interface_chain_2_residue_numbers) < {min_interface_residues}
+ """
+ )
+ ).fetchone()
+ invalid_count = int(row[0]) if row is not None else 0
+ if invalid_count:
+ raise ValueError(
+ f"interface annotation contains {invalid_count} rows below the frozen "
+ f"minimum of {min_interface_residues} residues per side"
+ )
+
+
+def plan_clustering(
+ data_dir: Path,
+ *,
+ metrics: list[str] | None = None,
+ thresholds: list[int] | None = None,
+ source_batch_size: int = 20,
+ cover_batch_size: int = 1,
+ symmetric_bucket_count: int = clusters.SYMMETRIC_EDGE_BUCKET_COUNT,
+ entity_type: clusters.ClusterEntity = "ligand",
+) -> dict[str, Any]:
+ """Plan internal connectivity plus directed and Tanimoto set covers."""
+ if source_batch_size < 1 or cover_batch_size < 1:
+ raise ValueError("clustering batch sizes must be positive")
+ selected_metrics, selected_thresholds = _cluster_parameters(
+ metrics=metrics,
+ thresholds=thresholds,
+ entity_type=entity_type,
+ )
+ interface_min_residues: int | None = None
+ if entity_type == "interface":
+ (
+ interface_min_residues,
+ threshold_is_frozen,
+ ) = _interface_clustering_min_residues(data_dir)
+ if threshold_is_frozen:
+ _validate_interface_clustering_universe(
+ data_dir,
+ min_interface_residues=interface_min_residues,
+ )
+ # The system-based component node universe is needed for interface metrics
+ # and for score (protein/pocket) metrics; every chemical metric uses the
+ # shared ligand_smiles_id universe read directly from the fingerprint table.
+ has_component_universe = entity_type == "interface" or any(
+ not is_chemical_cluster_metric(metric) for metric in selected_metrics
+ )
+ if has_component_universe:
+ clusters.prepare_component_node_universe(
+ data_dir,
+ entity_type=entity_type,
+ )
+ symmetric_plan = clusters.prepare_symmetric_edge_plan(
+ data_dir=data_dir,
+ metrics=selected_metrics,
+ source_batch_size=source_batch_size,
+ bucket_count=symmetric_bucket_count,
+ entity_type=entity_type,
+ )
+ cluster_root = clusters._cluster_root(data_dir, entity_type)
+ sampling_root = clusters._sampling_root(data_dir, entity_type)
+ cluster_plan_path = cluster_root / "clustering_plan.json"
+ universe_hash: str | None = None
+ if has_component_universe:
+ _, universe_manifest_path = clusters._component_node_universe_paths(
+ data_dir, entity_type
+ )
+ universe_hash = str(
+ json.loads(universe_manifest_path.read_text())["universe_hash"]
+ )
+ cluster_selection = {
+ "entity_type": entity_type,
+ "metrics": selected_metrics,
+ "thresholds": selected_thresholds,
+ "published_cluster_types": ["set_cover", "directed_set_cover"],
+ "representative_selection": "greedy_residual_gain",
+ "symmetric_plan_hash": symmetric_plan["plan_hash"],
+ "component_universe_hash": universe_hash,
+ }
+ if interface_min_residues is not None:
+ cluster_selection["min_interface_residues"] = interface_min_residues
+ set_cover_root = sampling_root / "set_cover"
+ prior_selection: dict[str, Any] | None = None
+ if cluster_plan_path.is_file():
+ try:
+ prior_selection = json.loads(cluster_plan_path.read_text())
+ except (OSError, ValueError, json.JSONDecodeError):
+ pass
+ if prior_selection != cluster_selection:
+ if set_cover_root.exists():
+ rmtree(set_cover_root)
+ directed_cover_root = sampling_root / "directed_set_cover"
+ for output_dir in directed_cover_root.glob("metric=*"):
+ rmtree(output_dir)
+ for diagnostics in [
+ cluster_root / "stats.parquet",
+ cluster_root / "stats.json",
+ ]:
+ diagnostics.unlink(missing_ok=True)
+ write_json_atomic(cluster_plan_path, cluster_selection)
+ symmetric_shard_count = len(selected_metrics) * symmetric_bucket_count
+ # TODO(mhfp6): MHFP6 is planned as a straight ECFP4 analog, so every
+ # chemical metric adds one reciprocal set cover per threshold (doubling the
+ # ligand set-cover array with the default metrics). Once MHFP6 clusters are
+ # validated on a release, consider extending it beyond this mirror: its own
+ # threshold list and cover batch sizing here, and the ECFP4-only consumers
+ # (eval stratification labels, ``cross_similarity`` default metric).
+ chemical_metric_count = len(
+ [metric for metric in selected_metrics if is_chemical_cluster_metric(metric)]
+ )
+ set_cover_task_count = (
+ chemical_metric_count * len(selected_thresholds)
+ if entity_type == "ligand"
+ else 0
+ )
+ directed_cover_task_count = len(
+ [
+ metric
+ for metric in selected_metrics
+ if not is_chemical_cluster_metric(metric)
+ ]
+ )
+ return {
+ "status": "planned",
+ "entity_type": entity_type,
+ "metrics": selected_metrics,
+ "thresholds": selected_thresholds,
+ "min_interface_residues": interface_min_residues,
+ "source_batch_size": source_batch_size,
+ "symmetric_bucket_count": symmetric_bucket_count,
+ "symmetric_fragment_batch_count": len(symmetric_plan["batches"]),
+ "symmetric_edge_shard_count": symmetric_shard_count,
+ "component_reduction_batch_count": symmetric_shard_count,
+ "set_cover_task_count": set_cover_task_count,
+ "cover_batch_size": cover_batch_size,
+ "set_cover_batch_count": math.ceil(set_cover_task_count / cover_batch_size),
+ "directed_cover_task_count": directed_cover_task_count,
+ "directed_cover_batch_count": math.ceil(
+ directed_cover_task_count / cover_batch_size
+ ),
+ }
+
+
+def summarize_clustering_artifacts(
+ data_dir: Path,
+ *,
+ metrics: list[str] | None = None,
+ thresholds: list[int] | None = None,
+ entity_type: clusters.ClusterEntity = "ligand",
+) -> dict[str, Any]:
+ """Validate published clusters and write compact diagnostic statistics."""
+ selected_metrics, selected_thresholds = _cluster_parameters(
+ metrics=metrics,
+ thresholds=thresholds,
+ entity_type=entity_type,
+ )
+ output_dir = clusters._cluster_root(data_dir, entity_type)
+ sampling_root = clusters._sampling_root(data_dir, entity_type)
+ directed_sampling_dir = sampling_root / "directed_set_cover"
+ set_cover_dir = sampling_root / "set_cover"
+ node_column = clusters._cluster_node_column(entity_type)
+ centroid_column = (
+ "centroid_ligand_id" if entity_type == "ligand" else "centroid_system_id"
+ )
+ artifacts: list[tuple[str, int, str, bool, Path]] = []
+ for metric in selected_metrics:
+ for threshold in selected_thresholds:
+ if entity_type == "ligand" and is_chemical_cluster_metric(metric):
+ artifacts.append(
+ (
+ metric,
+ threshold,
+ "set_cover",
+ False,
+ set_cover_dir
+ / f"metric={metric}"
+ / f"threshold={threshold}.parquet",
+ )
+ )
+ else:
+ artifacts.append(
+ (
+ metric,
+ threshold,
+ "directed_set_cover",
+ True,
+ directed_sampling_dir
+ / f"metric={metric}"
+ / f"threshold={threshold}.parquet",
+ )
+ )
+ expected_paths = {path for *_, path in artifacts}
+ rows: list[dict[str, Any]] = []
+ issues: list[str] = []
+ started = perf_counter()
+ for index, (metric, threshold, cluster, directed, path) in enumerate(
+ artifacts, start=1
+ ):
+ if not path.is_file():
+ issues.append(f"missing cluster artifact: {path}")
+ continue
+ frame = pd.read_parquet(path, columns=[node_column, "label", centroid_column])
+ duplicate_nodes = int(frame[node_column].duplicated().sum())
+ null_labels = int(frame["label"].isna().sum())
+ sizes = frame["label"].dropna().astype(str).value_counts()
+ rows.append(
+ {
+ "metric": metric,
+ "threshold": threshold,
+ "cluster": cluster,
+ "directed": directed,
+ "node_count": len(frame),
+ "cluster_count": len(sizes),
+ "singleton_cluster_count": int((sizes == 1).sum()),
+ "largest_cluster_size": int(sizes.max()) if len(sizes) else 0,
+ "median_cluster_size": float(sizes.median()) if len(sizes) else 0.0,
+ "p95_cluster_size": (
+ float(sizes.quantile(0.95)) if len(sizes) else 0.0
+ ),
+ "duplicate_node_count": duplicate_nodes,
+ "null_label_count": null_labels,
+ "file_size_bytes": path.stat().st_size,
+ }
+ )
+ if duplicate_nodes:
+ issues.append(f"{path} contains {duplicate_nodes} duplicate node IDs")
+ if null_labels:
+ issues.append(f"{path} contains {null_labels} null labels")
+ centroid_counts = (
+ frame[node_column].eq(frame[centroid_column]).groupby(frame["label"]).sum()
+ )
+ if centroid_counts.ne(1).any():
+ issues.append(f"{path} must have exactly one representative row per label")
+ if index % 10 == 0 or index == len(artifacts):
+ elapsed = perf_counter() - started
+ rate = index / elapsed
+ LOG.info(
+ "cluster statistics progress: "
+ f"validated={index}/{len(artifacts)} rate={rate:.2f}/s "
+ f"eta_seconds={(len(artifacts) - index) / rate:.1f}"
+ )
+
+ stats = pd.DataFrame(rows)
+ if len(stats) == len(artifacts):
+ for metric in selected_metrics:
+ metric_stats = stats[stats["metric"].eq(metric)]
+ node_counts = set(metric_stats["node_count"].astype(int))
+ if len(node_counts) != 1:
+ issues.append(
+ f"{metric} has inconsistent node counts: {sorted(node_counts)}"
+ )
+ published_paths = set(
+ directed_sampling_dir.glob("metric=*/threshold=*.parquet")
+ ) | set(set_cover_dir.glob("metric=*/threshold=*.parquet"))
+ unexpected_artifacts = sorted(
+ path.relative_to(data_dir).as_posix()
+ for path in published_paths.difference(expected_paths)
+ )
+ if unexpected_artifacts:
+ issues.append(
+ f"unexpected published cluster artifacts: {unexpected_artifacts[:20]}"
+ )
+
+ selected_metric_set = set(selected_metrics)
+ published_metrics = {
+ path.parent.name.removeprefix("metric=") for path in published_paths
+ }
+ unexpected_metrics = sorted(published_metrics.difference(selected_metric_set))
+ if unexpected_metrics:
+ issues.append(f"unexpected published cluster metrics: {unexpected_metrics}")
+
+ stats_path = output_dir / "stats.parquet"
+ _atomic_parquet(stats, stats_path)
+ report = {
+ "status": "complete" if not issues else "invalid",
+ "entity_type": entity_type,
+ "metric_count": len(selected_metrics),
+ "thresholds": selected_thresholds,
+ "artifact_count": len(stats),
+ "expected_artifact_count": len(artifacts),
+ "unexpected_artifacts": unexpected_artifacts,
+ "unexpected_metrics": unexpected_metrics,
+ "issues": issues,
+ "stats_path": stats_path.relative_to(data_dir).as_posix(),
+ "elapsed_seconds": perf_counter() - started,
+ }
+ write_json_atomic(output_dir / "stats.json", report)
+ if issues:
+ raise ValueError(f"invalid clustering artifacts: {issues[:10]}")
+ return report
+
+
+def _component_source_batch(
+ data_dir: Path,
+ *,
+ metrics: list[str],
+ batch_index: int,
+ batch_size: int,
+ entity_type: clusters.ClusterEntity = "ligand",
+) -> list[str]:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ batches = tasks.scatter_component_reduction_sources(
+ data_dir=data_dir,
+ metrics=metrics,
+ batch_size=batch_size,
+ entity_type=entity_type,
+ )
+ return batches[batch_index] if batch_index < len(batches) else []
+
+
+def _symmetric_fragment_batch(
+ data_dir: Path,
+ *,
+ batch_index: int,
+ batch_size: int,
+ entity_type: clusters.ClusterEntity = "ligand",
+) -> list[dict[str, Any]]:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ plan = clusters.load_symmetric_edge_plan(data_dir, entity_type=entity_type)
+ start = batch_index * batch_size
+ return cast(list[dict[str, Any]], plan["batches"][start : start + batch_size])
+
+
+def _symmetric_edge_shard_batch(
+ data_dir: Path,
+ *,
+ batch_index: int,
+ batch_size: int,
+ entity_type: clusters.ClusterEntity = "ligand",
+) -> list[tuple[str, int]]:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ plan = clusters.load_symmetric_edge_plan(data_dir, entity_type=entity_type)
+ work = [
+ (str(metric), bucket)
+ for metric in plan["metrics"]
+ for bucket in range(int(plan["bucket_count"]))
+ ]
+ start = batch_index * batch_size
+ return work[start : start + batch_size]
+
+
+def _cover_batch(
+ *,
+ metrics: list[str],
+ thresholds: list[int],
+ batch_index: int,
+ batch_size: int,
+) -> list[tuple[str, int]]:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ work = [(metric, threshold) for metric in metrics for threshold in thresholds]
+ start = batch_index * batch_size
+ return work[start : start + batch_size]
+
+
+def _directed_cover_batch(
+ *,
+ metrics: list[str],
+ thresholds: list[int],
+ batch_index: int,
+ batch_size: int,
+) -> list[tuple[str, int]]:
+ """Return complete threshold groups for one batch of directed metrics."""
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ start = batch_index * batch_size
+ selected = metrics[start : start + batch_size]
+ return [(metric, threshold) for metric in selected for threshold in thresholds]
+
+
+def _scoring_config(
+ data_dir: Path,
+ max_seqs: int,
+ *,
+ sub_databases: Iterable[str] = ("holo",),
+ max_query_protein_chains: int = 30,
+ max_query_proper_ligand_chains: int = 30,
+) -> Any:
+ selected_databases = list(dict.fromkeys(sub_databases))
+ minimum_thresholds = {}
+ if "apo" in selected_databases:
+ minimum_thresholds["protein_lddt_weighted_sum"] = 0.2
+ return config.get_config(
+ config={
+ "scorer": {
+ "sub_databases": ",".join(selected_databases),
+ "max_query_protein_chains": max_query_protein_chains,
+ "max_query_proper_ligand_chains": (max_query_proper_ligand_chains),
+ "minimum_thresholds": minimum_thresholds,
+ },
+ "foldseek": {"max_seqs": max_seqs, "min_seq_id": 0.0},
+ "mmseqs": {"max_seqs": max_seqs, "min_seq_id": 0.0},
+ },
+ cached=False,
+ )
+
+
+def _scoring_config_from_plan(
+ data_dir: Path,
+ plan: Mapping[str, Any],
+ *,
+ sub_databases: Iterable[str] = ("holo",),
+) -> Any:
+ """Build config before or after derived-score batch limits are planned."""
+ protein_limit = plan.get("score_max_query_protein_chains")
+ ligand_limit = plan.get("score_max_query_proper_ligand_chains")
+ if (protein_limit is None) != (ligand_limit is None):
+ raise ValueError("protein scoring plan contains incomplete score limits")
+ if protein_limit is None:
+ return _scoring_config(
+ data_dir,
+ int(plan["max_seqs"]),
+ sub_databases=sub_databases,
+ )
+ assert ligand_limit is not None
+ return _scoring_config(
+ data_dir,
+ int(plan["max_seqs"]),
+ sub_databases=sub_databases,
+ max_query_protein_chains=int(protein_limit),
+ max_query_proper_ligand_chains=int(ligand_limit),
+ )
+
+
+def _database_query_ids(database: Path, alignment_type: str) -> set[str]:
+ identifiers = databases.database_identifiers(database)
+ if alignment_type == "foldseek":
+ return {identifier.replace("pdb_0000", "", 1)[:4] for identifier in identifiers}
+ return {identifier.split("_", maxsplit=1)[0] for identifier in identifiers}
+
+
+def publish_search_database_bundles(
+ data_dir: Path,
+ *,
+ alignment_types: Iterable[str],
+) -> dict[str, dict[str, int | str]]:
+ """Publish the minimal portable search targets as one atomic generation."""
+ output = data_dir / "search_databases"
+ staging = data_dir / ".search_databases.installing"
+ backup = data_dir / ".search_databases.previous"
+ if backup.exists() and not output.exists():
+ backup.rename(output)
+ for path in (staging, backup):
+ if path.exists():
+ rmtree(path)
+ staging.mkdir(parents=True)
+ reports: dict[str, dict[str, int | str]] = {}
+ try:
+ for alignment_type in alignment_types:
+ reports[alignment_type] = databases.publish_search_database_bundle(
+ source_root=(data_dir / "dbs" / "subdbs" / f"holo_{alignment_type}"),
+ target_root=staging / f"holo_{alignment_type}",
+ aln_type=alignment_type,
+ )
+ monomer_source = data_dir / "dbs" / "subdbs" / f"monomer_{alignment_type}"
+ if (monomer_source / "exact_cluster.json").is_file():
+ databases.publish_search_database_bundle(
+ source_root=monomer_source,
+ target_root=staging / f"monomer_{alignment_type}",
+ aln_type=alignment_type,
+ )
+ overlay_source = (
+ data_dir / "dbs/weekly_delta/subdbs" / f"holo_{alignment_type}"
+ )
+ if (overlay_source / "exact_cluster.json").is_file():
+ databases.publish_search_database_bundle(
+ source_root=overlay_source,
+ target_root=staging / "weekly_delta" / f"holo_{alignment_type}",
+ aln_type=alignment_type,
+ )
+ shadowed = data_dir / "manifests/weekly_shadowed_entries.parquet"
+ if shadowed.is_file():
+ copyfile(shadowed, staging / "shadowed_entries.parquet")
+ if output.exists():
+ output.rename(backup)
+ staging.rename(output)
+ except BaseException:
+ if staging.exists():
+ rmtree(staging)
+ if backup.exists() and not output.exists():
+ backup.rename(output)
+ raise
+ if backup.exists():
+ rmtree(backup)
+ return reports
+
+
+def finalize_alignment_artifacts(data_dir: Path) -> dict[str, Any]:
+ """Validate compact release shards from their atomic mapping manifests."""
+ plan = _load_plan(data_dir, recheck_source=True, recheck_score_inputs=False)
+ expected_queries = set(
+ pd.read_parquet(data_dir / MANIFEST_RELATIVE, columns=["pdb_id"])[
+ "pdb_id"
+ ].astype(str)
+ )
+ counts: dict[str, int] = {}
+ missing: dict[str, list[str]] = {}
+ cluster_manifests: dict[str, dict[str, Any]] = {}
+ skipped_query_details: dict[str, dict[str, Any]] = {}
+ backend_queries: dict[str, set[str]] = {}
+ for alignment_type in plan["alignment_types"]:
+ root = data_dir / "dbs" / "subdbs" / f"holo_{alignment_type}"
+ cluster_manifest_path = root / "exact_cluster.json"
+ if not cluster_manifest_path.is_file():
+ raise FileNotFoundError(
+ f"missing exact-cluster manifest: {cluster_manifest_path}"
+ )
+ cluster_manifest = json.loads(cluster_manifest_path.read_text())
+ if cluster_manifest.get("alignment_type") != alignment_type:
+ raise ValueError(f"invalid exact-cluster manifest: {cluster_manifest_path}")
+ clustering = plan["target_clustering"]
+ for key in ["identity", "coverage", "coverage_mode"]:
+ if cluster_manifest.get(key) != clustering[key]:
+ raise ValueError(
+ f"{alignment_type} target clustering does not match plan: "
+ f"{key}={cluster_manifest.get(key)!r}"
+ )
+ source_index = cluster_manifest.get("source_index")
+ if not isinstance(source_index, dict):
+ raise ValueError(
+ f"invalid exact-cluster source signature: {cluster_manifest_path}"
+ )
+ source_path = root / str(source_index["name"])
+ source_stat = source_path.stat()
+ observed_source = {
+ "name": source_path.name,
+ "size": source_stat.st_size,
+ "mtime_ns": source_stat.st_mtime_ns,
+ }
+ if observed_source != source_index:
+ raise ValueError(
+ f"{alignment_type} target DB changed after exact clustering"
+ )
+ for artifact_key in ["search_target", "conversion_target"]:
+ artifact = root / str(cluster_manifest[artifact_key])
+ if not artifact.with_suffix(".dbtype").is_file():
+ raise FileNotFoundError(
+ f"missing {alignment_type} {artifact_key}: {artifact}"
+ )
+ bundle_sources = databases._search_database_bundle_sources(
+ root,
+ cluster_manifest,
+ alignment_type,
+ )
+ if databases._has_external_database_links(root, paths=bundle_sources):
+ raise ValueError(
+ f"{alignment_type} target database contains external or broken links"
+ )
+ cluster_manifests[alignment_type] = cluster_manifest
+ backend_queries[alignment_type] = _database_query_ids(
+ root / root.name, alignment_type
+ ).intersection(expected_queries)
+
+ manifest_root = data_dir / "alignments" / "manifests"
+ manifest_paths = sorted(manifest_root.glob("shard=*.json"))
+ expected_shards = {pdb_id[1:3] for pdb_id in expected_queries}
+ observed_manifest_shards = {
+ path.stem.removeprefix("shard=") for path in manifest_paths
+ }
+ absent_manifests = sorted(expected_shards.difference(observed_manifest_shards))
+ if absent_manifests:
+ missing["mapping_manifests"] = absent_manifests
+
+ lookup_signature = tasks._completed_alignment_chain_lookup(data_dir)
+ raw_queries_by_backend: dict[str, set[str]] = {
+ alignment_type: set() for alignment_type in plan["alignment_types"]
+ }
+ mapped_queries_by_backend: dict[str, set[str]] = {
+ alignment_type: set() for alignment_type in plan["alignment_types"]
+ }
+ release_shards_by_backend: dict[str, set[str]] = {
+ alignment_type: set() for alignment_type in plan["alignment_types"]
+ }
+ protein_score_sources: list[dict[str, Any]] = []
+ cigar_sources: list[dict[str, Any]] = []
+ invalid_manifests: list[str] = []
+ for manifest_path in manifest_paths:
+ shard = manifest_path.stem.removeprefix("shard=")
+ try:
+ shard_manifest = json.loads(manifest_path.read_text())
+ except (OSError, TypeError, ValueError):
+ invalid_manifests.append(shard)
+ continue
+ inputs = shard_manifest.get("inputs")
+ outputs = shard_manifest.get("outputs")
+ protein_score_outputs = shard_manifest.get("protein_score_outputs")
+ shard_skipped = shard_manifest.get("skipped_queries")
+ if (
+ shard_manifest.get("shard") != shard
+ or shard_manifest.get("alignment_chain_lookup") != lookup_signature
+ or not isinstance(inputs, dict)
+ or not isinstance(outputs, dict)
+ or not isinstance(protein_score_outputs, dict)
+ or not isinstance(shard_skipped, dict)
+ ):
+ invalid_manifests.append(shard)
+ continue
+ skipped_query_details.update(
+ {str(key): value for key, value in shard_skipped.items()}
+ )
+ for alignment_type in plan["alignment_types"]:
+ signatures = inputs.get(alignment_type)
+ if not isinstance(signatures, list):
+ invalid_manifests.append(shard)
+ continue
+ raw_queries = {
+ Path(str(signature["name"])).stem for signature in signatures
+ }
+ raw_queries_by_backend[alignment_type].update(raw_queries)
+ mapped_queries_by_backend[alignment_type].update(
+ raw_queries.difference(shard_skipped)
+ )
+ expected_output = outputs.get(alignment_type)
+ expected_protein_scores = protein_score_outputs.get(alignment_type)
+ if not signatures:
+ if expected_output is not None or expected_protein_scores is not None:
+ invalid_manifests.append(shard)
+ continue
+ release = tasks._alignment_release_path(
+ data_dir=data_dir,
+ search_db="holo",
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ if not isinstance(expected_output, dict) or not release.is_file():
+ invalid_manifests.append(shard)
+ continue
+ stat = release.stat()
+ if expected_output != {
+ "name": release.name,
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ }:
+ invalid_manifests.append(shard)
+ continue
+ columns = set(pq.read_schema(release).names)
+ if not schemas.release_alignment_mapping_schema_is_current(
+ columns, alignment_type=alignment_type, include_scores=False
+ ):
+ invalid_manifests.append(shard)
+ continue
+ protein_scores = tasks._protein_similarity_score_path(
+ data_dir=data_dir,
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ if (
+ not isinstance(expected_protein_scores, dict)
+ or not protein_scores.is_file()
+ or not pq.read_schema(protein_scores).equals(
+ schemas.PROTEIN_SIMILARITY_EXPORT_SCHEMA
+ )
+ ):
+ invalid_manifests.append(shard)
+ continue
+ score_stat = protein_scores.stat()
+ if expected_protein_scores != {
+ "name": protein_scores.name,
+ "size": score_stat.st_size,
+ "mtime_ns": score_stat.st_mtime_ns,
+ }:
+ invalid_manifests.append(shard)
+ continue
+ protein_score_sources.append(
+ {
+ "alignment_type": alignment_type,
+ "shard": shard,
+ **_source_signature(protein_scores),
+ "rows": int(pq.ParquetFile(protein_scores).metadata.num_rows),
+ }
+ )
+ cigar_sources.append(
+ {
+ "alignment_type": alignment_type,
+ "shard": shard,
+ **_source_signature(release),
+ "rows": int(pq.ParquetFile(release).metadata.num_rows),
+ }
+ )
+ release_shards_by_backend[alignment_type].add(shard)
+ if invalid_manifests:
+ missing["invalid_mapping_manifests"] = sorted(set(invalid_manifests))[:100]
+
+ observed_raw_all: set[str] = set()
+ observed_mapped_all: set[str] = set()
+ for alignment_type in plan["alignment_types"]:
+ raw_queries = raw_queries_by_backend[alignment_type]
+ mapped_queries = mapped_queries_by_backend[alignment_type]
+ skipped_queries = raw_queries.intersection(skipped_query_details)
+ observed_raw_all.update(raw_queries)
+ observed_mapped_all.update(mapped_queries)
+ counts[f"{alignment_type}_aln"] = len(raw_queries)
+ counts[f"{alignment_type}_mapped_aln"] = len(mapped_queries)
+ counts[f"{alignment_type}_skipped_queries"] = len(skipped_queries)
+ counts[f"{alignment_type}_release_shards"] = len(
+ release_shards_by_backend[alignment_type]
+ )
+ absent_raw = sorted(backend_queries[alignment_type].difference(raw_queries))
+ if absent_raw:
+ missing[f"{alignment_type}_aln"] = absent_raw[:100]
+ unexpected_raw = sorted(raw_queries.difference(expected_queries))
+ if unexpected_raw:
+ missing[f"{alignment_type}_aln_unexpected"] = unexpected_raw[:100]
+ raw_without_mapping = sorted(
+ raw_queries.difference(mapped_queries).difference(skipped_queries)
+ )
+ if raw_without_mapping:
+ missing[f"{alignment_type}_mapping"] = raw_without_mapping[:100]
+ absent_raw_all = sorted(expected_queries.difference(observed_raw_all))
+ if absent_raw_all:
+ missing["all_backends_aln"] = absent_raw_all[:100]
+ absent_mapped_all = sorted(
+ expected_queries.difference(skipped_query_details).difference(
+ observed_mapped_all
+ )
+ )
+ if absent_mapped_all:
+ missing["all_backends_mapped_aln"] = absent_mapped_all[:100]
+ if missing:
+ raise ValueError(f"protein alignment artifacts are incomplete: {missing}")
+ search_database_bundles = publish_search_database_bundles(
+ data_dir,
+ alignment_types=plan["alignment_types"],
+ )
+ report = {
+ **{
+ key: plan[key]
+ for key in [
+ "query_count",
+ "protein_chain_count",
+ "shard_count",
+ "max_seqs",
+ "search_databases",
+ "alignment_types",
+ "target_clustering",
+ ]
+ },
+ "status": "complete",
+ "artifact_counts": counts,
+ "exact_cluster_manifests": cluster_manifests,
+ "search_database_bundles": search_database_bundles,
+ "skipped_queries": skipped_query_details,
+ "protein_similarity_score_rows": sum(
+ int(source["rows"]) for source in protein_score_sources
+ ),
+ "alignment_cigar_rows": sum(int(source["rows"]) for source in cigar_sources),
+ }
+ write_json_atomic(data_dir / "alignments" / "manifest.json", report)
+ write_json_atomic(
+ data_dir / "exports" / "protein_similarity_scores.manifest.json",
+ {
+ "status": "complete",
+ "sources": protein_score_sources,
+ "row_count": report["protein_similarity_score_rows"],
+ },
+ )
+ return report
+
+
+def _ligand_3d_pair_validation_inputs(
+ *, data_dir: Path, work_path: Path, pair_paths: list[Path]
+) -> dict[str, Any]:
+ """Fingerprint inputs covered by the expensive pair-score audit."""
+ digest = hashlib.sha256()
+ pair_root = data_dir / "scores" / "ligand_3d_pairs"
+ for path in pair_paths:
+ stat = path.stat()
+ relative = path.relative_to(pair_root).as_posix()
+ digest.update(f"{relative}\0{stat.st_size}\0{stat.st_mtime_ns}\n".encode())
+ return {
+ "work": _source_signature(work_path),
+ "pair_file_count": len(pair_paths),
+ "pair_files_sha256": digest.hexdigest(),
+ "required_schema": schemas.LIGAND_3D_SCORE_SCHEMA.names,
+ }
+
+
+def finalize_ligand_3d_artifacts(data_dir: Path) -> dict[str, Any]:
+ """Validate canonical pair coverage and merged score completion."""
+ started = perf_counter()
+ LOG.info("score finalization: validating plan and candidate manifest")
+ plan = _load_plan(data_dir)
+ if not plan.get("ligand_3d_plan_complete", False):
+ raise ValueError("ligand 3D planning did not complete")
+ work_path = data_dir / LIGAND_3D_WORK_RELATIVE
+ if _source_signature(work_path) != plan.get("ligand_3d_work"):
+ raise ValueError("ligand 3D work manifest changed after planning")
+ candidate_manifest_path = data_dir / LIGAND_3D_CANDIDATE_MANIFEST_RELATIVE
+ if _source_signature(candidate_manifest_path) != plan.get(
+ "ligand_3d_candidate_manifest"
+ ):
+ raise ValueError("ligand 3D candidate manifest changed after planning")
+ candidate_manifest = pd.read_parquet(candidate_manifest_path)
+ candidate_count = len(candidate_manifest)
+ ligand_pair_score_rows = 0
+ phase_started = perf_counter()
+ for index, row in enumerate(candidate_manifest.itertuples(index=False), start=1):
+ path = Path(str(row.path))
+ if not path.is_file():
+ raise FileNotFoundError(path)
+ stat = path.stat()
+ if stat.st_size != int(row.size) or stat.st_mtime_ns != int(row.mtime_ns):
+ raise ValueError(f"ligand 3D candidate changed after planning: {path}")
+ ligand_pair_path = Path(str(row.ligand_pair_path))
+ if not ligand_pair_path.is_file():
+ raise FileNotFoundError(ligand_pair_path)
+ ligand_pair_stat = ligand_pair_path.stat()
+ ligand_pair_rows = pq.ParquetFile(ligand_pair_path).metadata.num_rows
+ if (
+ ligand_pair_stat.st_size != int(row.ligand_pair_size)
+ or ligand_pair_stat.st_mtime_ns != int(row.ligand_pair_mtime_ns)
+ or ligand_pair_rows != int(row.ligand_pair_rows)
+ ):
+ raise ValueError(
+ f"ligand pair score shard changed after planning: {ligand_pair_path}"
+ )
+ if not pq.read_schema(ligand_pair_path).equals(
+ schemas.LIGAND_PAIR_SCORE_SCHEMA
+ ):
+ raise ValueError(
+ f"ligand pair score shard has an unexpected schema: {ligand_pair_path}"
+ )
+ ligand_pair_score_rows += ligand_pair_rows
+ if index % 250 == 0 or index == candidate_count:
+ LOG.info(
+ "score finalization candidate manifests: "
+ f"validated={index}/{candidate_count} "
+ f"elapsed_seconds={perf_counter() - phase_started:.1f}"
+ )
+
+ pair_dir = data_dir / "scores" / "ligand_3d_pairs"
+ pair_paths = sorted(pair_dir.glob("*.parquet"))
+ expected_batches = set(range(int(plan["ligand_3d_batch_count"])))
+ observed_batches = {int(path.stem) for path in pair_paths if path.stem.isdigit()}
+ if observed_batches != expected_batches:
+ raise ValueError(
+ "ligand 3D pair score batches are incomplete: "
+ f"missing={sorted(expected_batches - observed_batches)[:10]}, "
+ f"extra={sorted(observed_batches - expected_batches)[:10]}"
+ )
+ expected_pdb_ids = published_scoring_query_ids(data_dir)
+ expected_query_shards = {pdb_id[1:3] for pdb_id in expected_pdb_ids}
+ final_score_dir = data_dir / "scores" / "search_db=holo"
+ final_score_paths = sorted(final_score_dir.glob("*.parquet"))
+ observed_final_shards = {path.stem for path in final_score_paths}
+ if observed_final_shards != expected_query_shards:
+ raise ValueError(
+ "packed ligand 3D score shards are incomplete: "
+ f"missing={sorted(expected_query_shards - observed_final_shards)[:10]}, "
+ f"extra={sorted(observed_final_shards - expected_query_shards)[:10]}"
+ )
+ LOG.info(
+ f"score finalization: validating {len(final_score_paths)} packed score schemas"
+ )
+ phase_started = perf_counter()
+ for index, path in enumerate(final_score_paths, start=1):
+ schema = pq.read_schema(path)
+ missing = sorted(
+ set(schemas.PROTEIN_SIMILARITY_SCHEMA.names).difference(schema.names)
+ )
+ if missing:
+ raise ValueError(f"packed score shard {path} is missing {missing}")
+ if index % 100 == 0 or index == len(final_score_paths):
+ LOG.info(
+ "score finalization packed schemas: "
+ f"validated={index}/{len(final_score_paths)} "
+ f"elapsed_seconds={perf_counter() - phase_started:.1f}"
+ )
+
+ pair_validation_inputs = _ligand_3d_pair_validation_inputs(
+ data_dir=data_dir,
+ work_path=work_path,
+ pair_paths=pair_paths,
+ )
+ validation_path = data_dir / LIGAND_3D_PAIR_VALIDATION_RELATIVE
+ cached_validation: dict[str, Any] = {}
+ if validation_path.is_file():
+ try:
+ cached_validation = json.loads(validation_path.read_text())
+ except (OSError, TypeError, ValueError):
+ cached_validation = {}
+ cached_coverage = cached_validation.get("coverage")
+ coverage_columns = [
+ "expected_rows",
+ "observed_rows",
+ "missing_rows",
+ "extra_rows",
+ "duplicate_rows",
+ ]
+ if (
+ cached_validation.get("status") == "complete"
+ and cached_validation.get("inputs") == pair_validation_inputs
+ and isinstance(cached_coverage, dict)
+ and set(coverage_columns).issubset(cached_coverage)
+ ):
+ coverage = pd.Series(
+ {column: int(cached_coverage[column]) for column in coverage_columns}
+ )
+ LOG.info(
+ "score finalization: reusing signature-matched canonical-pair "
+ f"validation counts={coverage.to_dict()}"
+ )
+ else:
+ LOG.info(f"score finalization: validating {len(pair_paths)} pair-score schemas")
+ phase_started = perf_counter()
+ for index, path in enumerate(pair_paths, start=1):
+ schema = pq.read_schema(path)
+ missing = sorted(
+ set(schemas.LIGAND_3D_SCORE_SCHEMA.names).difference(schema.names)
+ )
+ if missing:
+ raise ValueError(f"ligand 3D score batch {path} is missing {missing}")
+ if index % 1_000 == 0 or index == len(pair_paths):
+ elapsed = perf_counter() - phase_started
+ rate = index / elapsed
+ LOG.info(
+ "score finalization pair schemas: "
+ f"validated={index}/{len(pair_paths)} rate={rate:.1f}/s "
+ f"eta_seconds={(len(pair_paths) - index) / rate:.1f}"
+ )
+
+ import duckdb
+
+ connection = duckdb.connect()
+ pair_keys = ", ".join(
+ [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ )
+ pair_paths_sql = ", ".join(f"'{path.as_posix()}'" for path in pair_paths)
+ observed_sql = (
+ f"SELECT {pair_keys} FROM read_parquet([{pair_paths_sql}])"
+ if pair_paths
+ else f"SELECT {pair_keys} FROM read_parquet('{work_path.as_posix()}') "
+ "WHERE FALSE"
+ )
+ LOG.info("score finalization: starting canonical-pair coverage query")
+ phase_started = perf_counter()
+ coverage = (
+ connection.sql(
+ dedent(
+ f"""
+ WITH expected AS (
+ SELECT {pair_keys}
+ FROM read_parquet('{work_path.as_posix()}')
+ ), observed AS (
+ {observed_sql}
+ )
+ SELECT
+ (SELECT count(*) FROM expected) AS expected_rows,
+ (SELECT count(*) FROM observed) AS observed_rows,
+ (SELECT count(*) FROM (
+ SELECT * FROM expected EXCEPT SELECT * FROM observed
+ )) AS missing_rows,
+ (SELECT count(*) FROM (
+ SELECT * FROM observed EXCEPT SELECT * FROM expected
+ )) AS extra_rows,
+ (SELECT count(*) - count(DISTINCT ({pair_keys})) FROM observed)
+ AS duplicate_rows
+ """
+ )
+ )
+ .df()
+ .iloc[0]
+ )
+ connection.close()
+ LOG.info(
+ "score finalization: canonical-pair coverage query complete "
+ f"elapsed_seconds={perf_counter() - phase_started:.1f} "
+ f"counts={coverage.to_dict()}"
+ )
+ if any(
+ int(coverage[column])
+ for column in ["missing_rows", "extra_rows", "duplicate_rows"]
+ ):
+ raise ValueError(f"ligand 3D pair coverage mismatch: {coverage.to_dict()}")
+ write_json_atomic(
+ validation_path,
+ {
+ "status": "complete",
+ "inputs": pair_validation_inputs,
+ "coverage": {
+ column: int(coverage[column]) for column in coverage.index
+ },
+ },
+ )
+ report = {
+ "status": "complete",
+ "canonical_pair_count": int(coverage["expected_rows"]),
+ "pair_batch_count": len(pair_paths),
+ "query_shard_count": len(final_score_paths),
+ "query_count": len(expected_pdb_ids),
+ "ligand_pair_score_shard_count": candidate_count,
+ "ligand_pair_score_rows": ligand_pair_score_rows,
+ }
+ write_json_atomic(data_dir / "scores" / "ligand_3d_manifest.json", report)
+ LOG.info(
+ "score finalization complete: "
+ f"elapsed_seconds={perf_counter() - started:.1f} report={report}"
+ )
+ return report
+
+
+def finalize_score_repair_artifacts(
+ data_dir: Path,
+ *,
+ repair_manifest: Path,
+ require_packed_scores: bool = True,
+) -> dict[str, Any]:
+ """Validate ligand-pair caches and score shards rebuilt by a repair run.
+
+ A repair may intentionally refresh candidate shards after the original
+ all-vs-all ligand plan was finalized. The original finalizer must keep
+ rejecting that mutation; this repair-specific finalizer instead verifies
+ that every repaired shard was rebuilt from the current candidate and pair
+ inputs.
+ """
+ repairs = pd.read_parquet(repair_manifest)
+ if "shard" not in repairs.columns:
+ raise ValueError(f"repair manifest is missing shard: {repair_manifest}")
+ shards = sorted(set(repairs["shard"].dropna().astype(str)))
+ if not shards:
+ raise ValueError(f"repair manifest contains no shards: {repair_manifest}")
+
+ repair_started_ns = repair_manifest.stat().st_mtime_ns
+ candidate_dir = data_dir / "scores" / "ligand_3d_candidate_shards"
+ ligand_pair_score_dir = data_dir / "scores" / "ligand_pair_score_shards"
+ pair_candidate_dir = data_dir / "scores" / "ligand_3d_pair_candidate_shards"
+ pair_dir = data_dir / "scores" / "ligand_3d_by_query"
+ score_dir = data_dir / "scores" / "search_db=holo"
+ candidate_rows = 0
+ ligand_pair_score_rows = 0
+ pair_rows = 0
+ score_rows = 0
+ started = perf_counter()
+ for index, shard in enumerate(shards, start=1):
+ candidate = candidate_dir / f"shard={shard}.parquet"
+ ligand_pair_score = ligand_pair_score_dir / f"shard={shard}.parquet"
+ pair_candidate = pair_candidate_dir / f"shard={shard}.parquet"
+ pair = pair_dir / f"{shard}.parquet"
+ score = score_dir / f"{shard}.parquet"
+ manifest_path = candidate.with_suffix(".json")
+ required_paths = [
+ candidate,
+ ligand_pair_score,
+ pair_candidate,
+ pair,
+ manifest_path,
+ ]
+ if require_packed_scores:
+ required_paths.append(score)
+ missing_paths = [path for path in required_paths if not path.is_file()]
+ if missing_paths:
+ raise FileNotFoundError(
+ f"missing repaired score artifacts for shard {shard}: {missing_paths}"
+ )
+
+ try:
+ candidate_manifest = json.loads(manifest_path.read_text())
+ except (OSError, TypeError, ValueError) as exc:
+ raise ValueError(
+ f"invalid ligand 3D candidate manifest: {manifest_path}"
+ ) from exc
+ candidate_stat = candidate.stat()
+ ligand_pair_score_stat = ligand_pair_score.stat()
+ pair_candidate_stat = pair_candidate.stat()
+ candidate_row_count = pq.ParquetFile(candidate).metadata.num_rows
+ ligand_pair_score_row_count = pq.ParquetFile(
+ ligand_pair_score
+ ).metadata.num_rows
+ pair_candidate_row_count = pq.ParquetFile(pair_candidate).metadata.num_rows
+ expected_candidate = {
+ "path": str(candidate.resolve()),
+ "size": candidate_stat.st_size,
+ "mtime_ns": candidate_stat.st_mtime_ns,
+ "rows": candidate_row_count,
+ }
+ expected_pair_candidate = {
+ "path": str(pair_candidate.resolve()),
+ "size": pair_candidate_stat.st_size,
+ "mtime_ns": pair_candidate_stat.st_mtime_ns,
+ "rows": pair_candidate_row_count,
+ }
+ expected_ligand_pair_score = {
+ "path": str(ligand_pair_score.resolve()),
+ "size": ligand_pair_score_stat.st_size,
+ "mtime_ns": ligand_pair_score_stat.st_mtime_ns,
+ "rows": ligand_pair_score_row_count,
+ }
+ if (
+ candidate_manifest.get("shard") != shard
+ or candidate_manifest.get("output") != expected_candidate
+ or candidate_manifest.get("ligand_pair_output")
+ != expected_ligand_pair_score
+ or candidate_manifest.get("pair_output") != expected_pair_candidate
+ ):
+ raise ValueError(
+ f"stale ligand 3D candidate manifest for repaired shard {shard}"
+ )
+
+ candidate_missing = sorted(
+ set(schemas.LIGAND_3D_CANDIDATE_SCHEMA.names).difference(
+ pq.read_schema(candidate).names
+ )
+ )
+ pair_candidate_missing = sorted(
+ set(schemas.LIGAND_3D_PAIR_CANDIDATE_SCHEMA.names).difference(
+ pq.read_schema(pair_candidate).names
+ )
+ )
+ ligand_pair_score_schema_matches = pq.read_schema(ligand_pair_score).equals(
+ schemas.LIGAND_PAIR_SCORE_SCHEMA
+ )
+ pair_missing = sorted(
+ set(schemas.LIGAND_3D_SCORE_SCHEMA.names).difference(
+ pq.read_schema(pair).names
+ )
+ )
+ score_missing = (
+ sorted(
+ set(schemas.PROTEIN_SIMILARITY_SCHEMA.names).difference(
+ pq.read_schema(score).names
+ )
+ )
+ if require_packed_scores
+ else []
+ )
+ missing_columns = {
+ name: columns
+ for name, columns in [
+ ("candidate", candidate_missing),
+ (
+ "ligand_pair_score",
+ [] if ligand_pair_score_schema_matches else ["unexpected schema"],
+ ),
+ ("pair_candidate", pair_candidate_missing),
+ ("pair", pair_missing),
+ ("score", score_missing),
+ ]
+ if columns
+ }
+ if missing_columns:
+ raise ValueError(
+ f"repaired shard {shard} has incomplete schemas: {missing_columns}"
+ )
+
+ if require_packed_scores:
+ score_stat = score.stat()
+ newest_input_ns = max(
+ repair_started_ns,
+ candidate_stat.st_mtime_ns,
+ ligand_pair_score_stat.st_mtime_ns,
+ pair_candidate_stat.st_mtime_ns,
+ pair.stat().st_mtime_ns,
+ )
+ if score_stat.st_mtime_ns < newest_input_ns:
+ raise ValueError(
+ f"repaired score shard {score} predates its current inputs"
+ )
+ candidate_rows += candidate_row_count
+ ligand_pair_score_rows += ligand_pair_score_row_count
+ pair_rows += pq.ParquetFile(pair).metadata.num_rows
+ if require_packed_scores:
+ score_rows += pq.ParquetFile(score).metadata.num_rows
+ if index % 100 == 0 or index == len(shards):
+ elapsed = perf_counter() - started
+ rate = index / elapsed
+ LOG.info(
+ "score repair finalization: "
+ f"validated={index}/{len(shards)} rate={rate:.1f}/s "
+ f"eta_seconds={(len(shards) - index) / rate:.1f}"
+ )
+
+ report = {
+ "status": "complete",
+ "repair_manifest": _source_signature(repair_manifest),
+ "shard_count": len(shards),
+ "candidate_rows": candidate_rows,
+ "ligand_pair_score_rows": ligand_pair_score_rows,
+ "pair_rows": pair_rows,
+ "score_rows": score_rows,
+ }
+ write_json_atomic(data_dir / "scores" / "score_repair_manifest.json", report)
+ return report
+
+
+def _interface_score_alignment_manifest(data_dir: Path) -> tuple[Path, dict[str, Any]]:
+ path = data_dir / "alignments" / "manifest.json"
+ try:
+ payload = cast(dict[str, Any], json.loads(path.read_text()))
+ except (OSError, TypeError, ValueError) as exc:
+ raise FileNotFoundError(
+ f"missing or invalid finalized alignment manifest: {path}"
+ ) from exc
+ if payload.get("status") != "complete":
+ raise ValueError(f"protein alignments are not finalized: {path}")
+ if not isinstance(payload.get("skipped_queries"), dict):
+ raise ValueError(f"alignment manifest has no skipped-query map: {path}")
+ return path, payload
+
+
+def score_ligand_pocket_qcov_representatives(
+ data_dir: Path,
+ *,
+ shard: str,
+ output: Path,
+ scratch_dir: Path,
+ query_representative_ligand_ids: set[str],
+ threads: int = 4,
+ memory_limit: str = "32GB",
+) -> dict[str, int | str | float]:
+ """Score pockets using an exact ligand-pair-specific chain assignment."""
+ if threads < 1:
+ raise ValueError("ligand pocket scoring threads must be positive")
+ chain_lookup = data_dir / tasks.ALIGNMENT_CHAIN_LOOKUP_RELATIVE
+ alignment_selects: list[str] = []
+ for backend in ["foldseek", "mmseqs"]:
+ path = tasks._alignment_release_path(
+ data_dir=data_dir,
+ search_db="holo",
+ alignment_type=backend,
+ shard=shard,
+ )
+ if not path.is_file():
+ continue
+ identity = "lddt" if backend == "foldseek" else "fident"
+ alignment_selects.append(
+ dedent(
+ f"""
+ SELECT
+ '{backend}'::VARCHAR AS backend,
+ query_entry,
+ target_entry,
+ query_chain_mapped,
+ target_chain_mapped,
+ (qcov * {identity})::DOUBLE AS mapper_score,
+ list_transform(
+ query_selected_residue_positions,
+ position -> list_extract(
+ query_chain.selected_residue_numbers, position
+ )
+ ) AS query_selected_residue_numbers,
+ list_transform(
+ target_selected_residue_positions,
+ position -> CASE
+ WHEN position = 0 THEN -1
+ ELSE list_extract(
+ target_chain.selected_residue_numbers, position
+ )
+ END
+ ) AS target_selected_residue_numbers
+ FROM ({cigar_alignment_sql(path, chain_lookup)}) AS alignment
+ INNER JOIN read_parquet('{chain_lookup.as_posix()}') AS query_chain
+ ON alignment.query_entry = query_chain.entry_pdb_id
+ AND alignment.query_chain_mapped = query_chain.chain_asym_id
+ INNER JOIN read_parquet('{chain_lookup.as_posix()}') AS target_chain
+ ON alignment.target_entry = target_chain.entry_pdb_id
+ AND alignment.target_chain_mapped = target_chain.chain_asym_id
+ """
+ ).strip()
+ )
+ if not alignment_selects:
+ raise FileNotFoundError(f"no mapped alignments for ligand shard {shard}")
+
+ import duckdb
+
+ representatives = data_dir / tasks.LIGAND_POCKET_REPRESENTATIVES_RELATIVE
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ local_output = scratch_dir / output.name
+ local_output.unlink(missing_ok=True)
+ writer = pq.ParquetWriter(
+ local_output,
+ schemas.LIGAND_POCKET_QCOV_REPRESENTATIVE_SCHEMA,
+ compression="zstd",
+ )
+ records: list[dict[str, str | float]] = []
+ output_rows = 0
+ contribution_rows = 0
+ started = perf_counter()
+
+ def flush_records() -> None:
+ nonlocal output_rows
+ if not records:
+ return
+ writer.write_table(
+ pa.Table.from_pylist(
+ records,
+ schema=schemas.LIGAND_POCKET_QCOV_REPRESENTATIVE_SCHEMA,
+ ),
+ row_group_size=100_000,
+ )
+ output_rows += len(records)
+ records.clear()
+
+ connection = duckdb.connect()
+ try:
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ connection.sql("SET preserve_insertion_order=false")
+ connection.register(
+ "query_representative_ids",
+ pa.table(
+ {"representative_ligand_id": sorted(query_representative_ligand_ids)}
+ ),
+ )
+ mapped_sql = "\nUNION ALL\n".join(alignment_selects)
+ query = dedent(
+ f"""
+ WITH representatives AS (
+ SELECT
+ representative_ligand_id,
+ representative_system_id,
+ entry_pdb_id,
+ len(pocket_residues)::DOUBLE AS pocket_residue_count,
+ pocket_residues
+ FROM read_parquet('{representatives.as_posix()}')
+ ), pocket_residues AS (
+ SELECT
+ representative_ligand_id,
+ split_part(residue, '_', 1) AS chain_asym_id,
+ CAST(split_part(residue, '_', 2) AS INTEGER)
+ AS residue_number
+ FROM representatives,
+ unnest(pocket_residues) AS residues(residue)
+ ), pockets AS (
+ SELECT
+ representative_ligand_id,
+ chain_asym_id,
+ list(residue_number ORDER BY residue_number)
+ AS residue_numbers
+ FROM pocket_residues
+ GROUP BY representative_ligand_id, chain_asym_id
+ ), mapped AS (
+ {mapped_sql}
+ ), query_pocket_alignments AS (
+ SELECT
+ query.representative_system_id AS query_system,
+ query.representative_ligand_id AS query_ligand_id,
+ query.pocket_residue_count,
+ mapped.target_entry,
+ mapped.backend,
+ mapped.query_chain_mapped AS query_chain,
+ mapped.target_chain_mapped AS target_chain,
+ mapped.mapper_score,
+ list_transform(
+ list_filter(
+ range(
+ 1,
+ len(mapped.query_selected_residue_numbers) + 1
+ ),
+ position -> list_contains(
+ query_pocket.residue_numbers,
+ list_extract(
+ mapped.query_selected_residue_numbers,
+ position
+ )
+ )
+ ),
+ position -> list_extract(
+ mapped.target_selected_residue_numbers,
+ position
+ )
+ ) AS aligned_target_residues
+ FROM mapped
+ INNER JOIN representatives AS query
+ ON mapped.query_entry = query.entry_pdb_id
+ INNER JOIN query_representative_ids AS query_ids
+ ON query.representative_ligand_id
+ = query_ids.representative_ligand_id
+ INNER JOIN pockets AS query_pocket
+ ON query.representative_ligand_id
+ = query_pocket.representative_ligand_id
+ AND mapped.query_chain_mapped = query_pocket.chain_asym_id
+ WHERE query.pocket_residue_count > 0
+ ), coverage_candidates AS (
+ SELECT
+ query.query_system,
+ query.query_ligand_id,
+ target.representative_system_id AS target_system,
+ target.representative_ligand_id AS target_ligand_id,
+ query.backend,
+ query.query_chain,
+ query.target_chain,
+ query.pocket_residue_count,
+ len(list_intersect(
+ query.aligned_target_residues,
+ target_pocket.residue_numbers
+ ))::DOUBLE AS covered_residue_count,
+ query.mapper_score
+ FROM query_pocket_alignments AS query
+ INNER JOIN representatives AS target
+ ON query.target_entry = target.entry_pdb_id
+ INNER JOIN pockets AS target_pocket
+ ON target.representative_ligand_id
+ = target_pocket.representative_ligand_id
+ AND query.target_chain = target_pocket.chain_asym_id
+ WHERE query.query_system != target.representative_system_id
+ )
+ SELECT
+ query_system,
+ query_ligand_id,
+ target_system,
+ target_ligand_id,
+ backend,
+ query_chain,
+ target_chain,
+ pocket_residue_count,
+ max(covered_residue_count)::DOUBLE AS covered_residue_count,
+ coalesce(max(mapper_score), 0)::DOUBLE AS mapper_score
+ FROM coverage_candidates
+ GROUP BY
+ query_system,
+ query_ligand_id,
+ target_system,
+ target_ligand_id,
+ backend,
+ query_chain,
+ target_chain,
+ pocket_residue_count
+ ORDER BY
+ query_system,
+ query_ligand_id,
+ target_system,
+ target_ligand_id,
+ backend,
+ query_chain,
+ target_chain
+ """
+ )
+ LOG.info(
+ "pocket-aware ligand scoring: shard=%s query_ligands=%d starting",
+ shard,
+ len(query_representative_ligand_ids),
+ )
+ reader = connection.execute(query).to_arrow_reader(250_000)
+ current_pair: tuple[str, str, str, str] | None = None
+ current_backend: str | None = None
+ primary_weights: dict[tuple[str, str], float] = {}
+ secondary_weights: dict[tuple[str, str], float] = {}
+ query_nodes: set[str] = set()
+ target_nodes: set[str] = set()
+ pocket_residue_count = 0.0
+ backend_results: dict[str, tuple[float, str]] = {}
+
+ def finish_backend() -> None:
+ nonlocal primary_weights, secondary_weights
+ nonlocal query_nodes, target_nodes, pocket_residue_count
+ if current_backend is None or current_pair is None:
+ return
+ assignment = maximum_weight_bipartite_assignment(
+ query_nodes,
+ target_nodes,
+ primary_weights,
+ secondary_weights=secondary_weights,
+ )
+ covered = sum(primary_weights.get(pair, 0.0) for pair in assignment)
+ if covered > 0 and pocket_residue_count > 0:
+ backend_results[current_backend] = (
+ covered / pocket_residue_count,
+ ";".join(f"{query}:{target}" for query, target in assignment),
+ )
+ primary_weights = {}
+ secondary_weights = {}
+ query_nodes = set()
+ target_nodes = set()
+ pocket_residue_count = 0.0
+
+ def finish_pair() -> None:
+ if current_pair is None or not backend_results:
+ return
+ best_qcov = max(value[0] for value in backend_results.values())
+ winners = [
+ backend
+ for backend, value in backend_results.items()
+ if abs(value[0] - best_qcov) < 1e-12
+ ]
+ mapper = "foldseek" if "foldseek" in winners else winners[0]
+ records.append(
+ {
+ "query_system": current_pair[0],
+ "query_ligand_id": current_pair[1],
+ "target_system": current_pair[2],
+ "target_ligand_id": current_pair[3],
+ "protein_mapping": backend_results[mapper][1],
+ "protein_mapper": mapper,
+ "source": "both" if len(winners) == 2 else mapper,
+ "pocket_qcov": best_qcov,
+ }
+ )
+ if len(records) >= 100_000:
+ flush_records()
+
+ for batch_index, batch in enumerate(reader, start=1):
+ columns = batch.to_pydict()
+ for values in zip(
+ columns["query_system"],
+ columns["query_ligand_id"],
+ columns["target_system"],
+ columns["target_ligand_id"],
+ columns["backend"],
+ columns["query_chain"],
+ columns["target_chain"],
+ columns["pocket_residue_count"],
+ columns["covered_residue_count"],
+ columns["mapper_score"],
+ strict=True,
+ ):
+ pair = tuple(map(str, values[:4]))
+ backend = str(values[4])
+ if current_pair is not None and pair != current_pair:
+ finish_backend()
+ finish_pair()
+ backend_results = {}
+ current_backend = None
+ if current_backend is not None and backend != current_backend:
+ finish_backend()
+ current_pair = cast(tuple[str, str, str, str], pair)
+ current_backend = backend
+ query_chain = str(values[5])
+ target_chain = str(values[6])
+ chain_pair = (query_chain, target_chain)
+ query_nodes.add(query_chain)
+ target_nodes.add(target_chain)
+ pocket_residue_count = float(values[7])
+ primary_weights[chain_pair] = float(values[8])
+ secondary_weights[chain_pair] = float(values[9])
+ contribution_rows += batch.num_rows
+ if batch_index % 20 == 0:
+ elapsed = perf_counter() - started
+ LOG.info(
+ "pocket-aware ligand scoring progress: shard=%s "
+ "contributions=%d rate=%.0f/s output_rows=%d",
+ shard,
+ contribution_rows,
+ contribution_rows / elapsed,
+ output_rows + len(records),
+ )
+ finish_backend()
+ finish_pair()
+ flush_records()
+ writer.close()
+ except Exception:
+ writer.close()
+ local_output.unlink(missing_ok=True)
+ raise
+ finally:
+ connection.close()
+
+ observed = pq.read_schema(local_output)
+ if not observed.equals(schemas.LIGAND_POCKET_QCOV_REPRESENTATIVE_SCHEMA):
+ local_output.unlink(missing_ok=True)
+ raise ValueError(f"ligand pocket scores have unexpected schema: {observed}")
+ output.parent.mkdir(parents=True, exist_ok=True)
+ install = output.with_suffix(output.suffix + ".tmp")
+ copyfile(local_output, install)
+ install.replace(output)
+ local_output.unlink(missing_ok=True)
+ report: dict[str, int | str | float] = {
+ "shard": shard,
+ "row_count": output_rows,
+ "contribution_row_count": contribution_rows,
+ "elapsed_seconds": perf_counter() - started,
+ "output": str(output),
+ }
+ LOG.info(
+ "pocket-aware ligand scoring: shard=%s contributions=%d rows=%d "
+ "elapsed_seconds=%.1f",
+ shard,
+ contribution_rows,
+ output_rows,
+ report["elapsed_seconds"],
+ )
+ return report
+
+
+def plan_ligand_pocket_scoring(
+ data_dir: Path,
+ *,
+ scratch_dir: Path,
+ threads: int = 4,
+ memory_limit: str = "32GB",
+ max_query_protein_chains: int = 30,
+ max_query_proper_ligand_chains: int = 30,
+) -> dict[str, Any]:
+ """Freeze system-level query eligibility for normalized ligand scoring."""
+ if (
+ min(
+ threads,
+ max_query_protein_chains,
+ max_query_proper_ligand_chains,
+ )
+ < 1
+ ):
+ raise ValueError("threads and query chain limits must be positive")
+ tasks.make_ligand_pocket_representatives(
+ data_dir=data_dir,
+ scratch_dir=scratch_dir,
+ threads=threads,
+ )
+ annotation = data_dir / "index" / "annotation_table.parquet"
+ entry_chains = data_dir / "index" / "entry_chains.parquet"
+ membership = data_dir / tasks.LIGAND_POCKET_MEMBERSHIP_RELATIVE
+ representatives = data_dir / tasks.LIGAND_POCKET_REPRESENTATIVES_RELATIVE
+ active_work = data_dir / SCORE_WORK_RELATIVE
+ inputs = {
+ "annotation": _source_signature(annotation),
+ "entry_chains": _source_signature(entry_chains),
+ "membership": _source_signature(membership),
+ "representatives": _source_signature(representatives),
+ "active_work": _source_signature(active_work),
+ }
+ dropped_path = data_dir / DROPPED_QUERY_RELATIVE
+ if dropped_path.is_file():
+ inputs["dropped_queries"] = _source_signature(dropped_path)
+ output = data_dir / LIGAND_POCKET_SCORE_WORK_RELATIVE
+ plan_path = data_dir / LIGAND_POCKET_SCORE_PLAN_RELATIVE
+ try:
+ current = cast(dict[str, Any], json.loads(plan_path.read_text()))
+ if (
+ current.get("status") == "complete"
+ and current.get("inputs") == inputs
+ and current.get("max_query_protein_chains") == max_query_protein_chains
+ and current.get("max_query_proper_ligand_chains")
+ == max_query_proper_ligand_chains
+ and current.get("work") == _source_signature(output)
+ and pq.read_schema(output).equals(schemas.LIGAND_POCKET_SCORE_QUERY_SCHEMA)
+ ):
+ return {**current, "cached": True}
+ except (FileNotFoundError, OSError, TypeError, ValueError):
+ pass
+
+ import duckdb
+
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ local_output = scratch_dir / output.name
+ local_output.unlink(missing_ok=True)
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ connection.sql("SET preserve_insertion_order=false")
+ connection.register(
+ "active_query_entries",
+ pa.table({"pdb_id": sorted(active_scoring_query_ids(data_dir))}),
+ )
+ started = perf_counter()
+ connection.sql(
+ dedent(
+ f"""
+ COPY (
+ WITH holo AS (
+ SELECT
+ entry_pdb_id,
+ system_id,
+ ligand_id,
+ ligand_is_proper,
+ system_protein_chains_asym_id
+ FROM read_parquet('{annotation.as_posix()}')
+ WHERE system_type = 'holo'
+ ), system_ligands AS (
+ SELECT
+ entry_pdb_id,
+ system_id,
+ count(DISTINCT ligand_id) FILTER (
+ WHERE coalesce(ligand_is_proper, false)
+ )::BIGINT AS proper_ligand_chains
+ FROM holo
+ GROUP BY entry_pdb_id, system_id
+ ), receptor_instances AS (
+ SELECT DISTINCT
+ entry_pdb_id,
+ system_id,
+ unnest(system_protein_chains_asym_id)::VARCHAR
+ AS instance_chain
+ FROM holo
+ ), system_proteins AS (
+ SELECT
+ receptors.entry_pdb_id,
+ receptors.system_id,
+ count(*) FILTER (
+ WHERE chains.chain_receptor_type = 'protein'
+ )::BIGINT AS protein_chains
+ FROM receptor_instances AS receptors
+ LEFT JOIN read_parquet('{entry_chains.as_posix()}') AS chains
+ ON receptors.entry_pdb_id = chains.entry_pdb_id
+ AND split_part(receptors.instance_chain, '.', 2)
+ = chains.chain_asym_id
+ GROUP BY receptors.entry_pdb_id, receptors.system_id
+ ), eligible_systems AS (
+ SELECT ligands.entry_pdb_id, ligands.system_id
+ FROM system_ligands AS ligands
+ INNER JOIN system_proteins AS proteins
+ USING (entry_pdb_id, system_id)
+ INNER JOIN active_query_entries AS active
+ ON ligands.entry_pdb_id = active.pdb_id
+ WHERE proteins.protein_chains BETWEEN 1
+ AND {max_query_protein_chains}
+ AND ligands.proper_ligand_chains BETWEEN 1
+ AND {max_query_proper_ligand_chains}
+ )
+ SELECT DISTINCT
+ eligible.entry_pdb_id::VARCHAR AS entry_pdb_id,
+ members.system_id::VARCHAR AS system_id,
+ members.ligand_id::VARCHAR AS ligand_id,
+ members.representative_system_id::VARCHAR
+ AS representative_system_id,
+ members.representative_ligand_id::VARCHAR
+ AS representative_ligand_id,
+ substr(eligible.entry_pdb_id, 2, 2)::VARCHAR AS shard
+ FROM eligible_systems AS eligible
+ INNER JOIN read_parquet('{membership.as_posix()}') AS members
+ ON eligible.system_id = members.system_id
+ ORDER BY entry_pdb_id, system_id, ligand_id
+ ) TO '{local_output.as_posix()}' (
+ FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 100000
+ )
+ """
+ )
+ )
+ connection.close()
+ observed = pq.read_schema(local_output)
+ if not observed.equals(schemas.LIGAND_POCKET_SCORE_QUERY_SCHEMA):
+ local_output.unlink(missing_ok=True)
+ raise ValueError(f"ligand pocket query plan has unexpected schema: {observed}")
+ output.parent.mkdir(parents=True, exist_ok=True)
+ install = output.with_suffix(output.suffix + ".tmp")
+ copyfile(local_output, install)
+ install.replace(output)
+ local_output.unlink(missing_ok=True)
+ work = pd.read_parquet(output, columns=["representative_ligand_id", "shard"])
+ payload = {
+ "status": "complete",
+ "inputs": inputs,
+ "max_query_protein_chains": max_query_protein_chains,
+ "max_query_proper_ligand_chains": max_query_proper_ligand_chains,
+ "query_ligand_count": len(work),
+ "query_representative_ligand_count": int(
+ work["representative_ligand_id"].nunique()
+ ),
+ "shard_count": int(work["shard"].nunique()),
+ "elapsed_seconds": perf_counter() - started,
+ "work": _source_signature(output),
+ }
+ write_json_atomic(plan_path, payload)
+ return payload
+
+
+def _ligand_pocket_score_shard_batch(
+ data_dir: Path, batch_index: int, batch_size: int
+) -> list[str]:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ work = pd.read_parquet(data_dir / LIGAND_POCKET_SCORE_WORK_RELATIVE)
+ shards = sorted(work["shard"].dropna().astype(str).unique())
+ start = batch_index * batch_size
+ return list(shards[start : start + batch_size])
+
+
+def _ligand_pocket_query_representatives(data_dir: Path, shard: str) -> set[str]:
+ work = pd.read_parquet(
+ data_dir / LIGAND_POCKET_SCORE_WORK_RELATIVE,
+ columns=["representative_ligand_id", "shard"],
+ )
+ return set(
+ work.loc[
+ work["shard"].astype(str).eq(shard), "representative_ligand_id"
+ ].astype(str)
+ )
+
+
+def _ligand_pocket_score_inputs(data_dir: Path, shard: str) -> dict[str, Any]:
+ """Return signatures for every input that determines one ligand shard."""
+ paths = {
+ "representatives": data_dir / tasks.LIGAND_POCKET_REPRESENTATIVES_RELATIVE,
+ "representative_manifest": (
+ data_dir / tasks.LIGAND_POCKET_REPRESENTATIVES_MANIFEST_RELATIVE
+ ),
+ "score_plan": data_dir / LIGAND_POCKET_SCORE_PLAN_RELATIVE,
+ "score_work": data_dir / LIGAND_POCKET_SCORE_WORK_RELATIVE,
+ }
+ if (data_dir / DROPPED_QUERY_RELATIVE).is_file():
+ paths["dropped_queries"] = data_dir / DROPPED_QUERY_RELATIVE
+ for backend in ["foldseek", "mmseqs"]:
+ path = tasks._alignment_release_path(
+ data_dir=data_dir,
+ search_db="holo",
+ alignment_type=backend,
+ shard=shard,
+ )
+ if path.is_file():
+ paths[backend] = path
+ if "foldseek" not in paths and "mmseqs" not in paths:
+ raise FileNotFoundError(f"no mapped alignments for ligand shard {shard}")
+ missing = [str(path) for path in paths.values() if not path.is_file()]
+ if missing:
+ raise FileNotFoundError(f"missing ligand pocket scoring inputs: {missing}")
+ return {
+ "mapping_algorithm": "maximum_pocket_coverage_per_backend",
+ **{name: _source_signature(path) for name, path in paths.items()},
+ }
+
+
+def _ligand_pocket_shard_is_current(
+ *,
+ manifest_path: Path,
+ score_path: Path,
+ shard: str,
+ inputs: dict[str, Any],
+) -> bool:
+ try:
+ manifest = cast(dict[str, Any], json.loads(manifest_path.read_text()))
+ return (
+ manifest.get("status") == "complete"
+ and manifest.get("shard") == shard
+ and manifest.get("inputs") == inputs
+ and manifest.get("scores") == _source_signature(score_path)
+ and pq.read_schema(score_path).equals(
+ schemas.LIGAND_POCKET_QCOV_REPRESENTATIVE_SCHEMA
+ )
+ )
+ except (FileNotFoundError, OSError, TypeError, ValueError):
+ return False
+
+
+def score_ligand_pocket_qcov_shards(
+ data_dir: Path,
+ *,
+ shards: Iterable[str],
+ scratch_dir: Path,
+ threads: int = 4,
+ memory_limit: str = "32GB",
+ force_update: bool = False,
+) -> dict[str, Any]:
+ """Build ligand-pair-specific pocket scores for query shards."""
+ selected = list(shards)
+ score_root = data_dir / LIGAND_POCKET_QCOV_REPRESENTATIVE_ROOT_RELATIVE
+ score_root.mkdir(parents=True, exist_ok=True)
+ reports: list[dict[str, Any]] = []
+ started = perf_counter()
+ for index, shard in enumerate(selected, start=1):
+ inputs = _ligand_pocket_score_inputs(data_dir, shard)
+ query_representatives = _ligand_pocket_query_representatives(data_dir, shard)
+ score_path = score_root / f"shard={shard}.parquet"
+ manifest_path = score_root / f"shard={shard}.json"
+ if not force_update and _ligand_pocket_shard_is_current(
+ manifest_path=manifest_path,
+ score_path=score_path,
+ shard=shard,
+ inputs=inputs,
+ ):
+ reports.append(
+ {
+ "shard": shard,
+ "status": "cached",
+ "row_count": pq.ParquetFile(score_path).metadata.num_rows,
+ }
+ )
+ continue
+ shard_scratch = scratch_dir / f"shard={shard}"
+ score_report = score_ligand_pocket_qcov_representatives(
+ data_dir,
+ shard=shard,
+ output=score_path,
+ scratch_dir=shard_scratch,
+ query_representative_ligand_ids=query_representatives,
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ manifest = {
+ "status": "complete",
+ "shard": shard,
+ "inputs": inputs,
+ "scores": _source_signature(score_path),
+ "score_report": score_report,
+ }
+ write_json_atomic(manifest_path, manifest)
+ reports.append({"shard": shard, "status": "complete", **score_report})
+ elapsed = perf_counter() - started
+ LOG.info(
+ "normalized ligand score progress: shards=%d/%d shard=%s "
+ "elapsed_seconds=%.1f eta_seconds=%.1f",
+ index,
+ len(selected),
+ shard,
+ elapsed,
+ elapsed / index * (len(selected) - index),
+ )
+ return {
+ "status": "complete",
+ "shard_count": len(selected),
+ "elapsed_seconds": perf_counter() - started,
+ "shards": reports,
+ }
+
+
+def materialize_ligand_3d_pair_candidates(
+ data_dir: Path,
+ *,
+ shards: Iterable[str],
+ scratch_dir: Path,
+ threads: int = 1,
+ memory_limit: str = "8GB",
+ force_update: bool = False,
+) -> dict[str, Any]:
+ """Convert positive representative pocket scores into canonical SDF pairs."""
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ representatives = data_dir / tasks.LIGAND_POCKET_REPRESENTATIVES_RELATIVE
+ output_root = data_dir / "scores" / "ligand_3d_pair_candidate_shards"
+ output_root.mkdir(parents=True, exist_ok=True)
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ selected = list(shards)
+ reports: list[dict[str, Any]] = []
+ started = perf_counter()
+ for shard in selected:
+ scores = (
+ data_dir
+ / LIGAND_POCKET_QCOV_REPRESENTATIVE_ROOT_RELATIVE
+ / f"shard={shard}.parquet"
+ )
+ if not scores.is_file():
+ raise FileNotFoundError(scores)
+ output = output_root / f"shard={shard}.parquet"
+ if not force_update and output.is_file():
+ try:
+ current = output.stat().st_mtime_ns >= max(
+ scores.stat().st_mtime_ns,
+ representatives.stat().st_mtime_ns,
+ ) and pq.read_schema(output).equals(
+ schemas.LIGAND_3D_PAIR_CANDIDATE_SCHEMA
+ )
+ except (OSError, ValueError):
+ current = False
+ if current:
+ _refresh_ligand_3d_pair_candidate_manifest(
+ data_dir=data_dir,
+ shard=shard,
+ pair_output=output,
+ )
+ reports.append(
+ {
+ "shard": shard,
+ "status": "cached",
+ "row_count": pq.ParquetFile(output).metadata.num_rows,
+ }
+ )
+ continue
+
+ import duckdb
+
+ shard_scratch = scratch_dir / f"shard={shard}"
+ shard_scratch.mkdir(parents=True, exist_ok=True)
+ temporary = shard_scratch / output.name
+ temporary.unlink(missing_ok=True)
+ connection = duckdb.connect()
+ try:
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql(f"SET temp_directory='{shard_scratch.as_posix()}'")
+ connection.sql("SET preserve_insertion_order=false")
+ connection.sql(
+ dedent(
+ f"""
+ COPY (
+ WITH scoreable_representatives AS (
+ SELECT
+ representative_ligand_id,
+ entry_pdb_id,
+ ligand_asym_id
+ FROM read_parquet('{representatives.as_posix()}')
+ WHERE coalesce(ligand_is_shape_comparable, false)
+ )
+ SELECT
+ query.entry_pdb_id::VARCHAR AS query_entry,
+ query.ligand_asym_id::VARCHAR
+ AS query_ligand_asym_id,
+ target.entry_pdb_id::VARCHAR AS target_entry,
+ target.ligand_asym_id::VARCHAR
+ AS target_ligand_asym_id,
+ max(scores.pocket_qcov)::DOUBLE AS pocket_qcov
+ FROM read_parquet('{scores.as_posix()}') AS scores
+ INNER JOIN scoreable_representatives AS query
+ ON scores.query_ligand_id
+ = query.representative_ligand_id
+ INNER JOIN scoreable_representatives AS target
+ ON scores.target_ligand_id
+ = target.representative_ligand_id
+ WHERE scores.pocket_qcov > 0
+ GROUP BY
+ query.entry_pdb_id,
+ query.ligand_asym_id,
+ target.entry_pdb_id,
+ target.ligand_asym_id
+ ORDER BY
+ query.entry_pdb_id,
+ query.ligand_asym_id,
+ target.entry_pdb_id,
+ target.ligand_asym_id
+ ) TO '{temporary.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 100000
+ )
+ """
+ )
+ )
+ finally:
+ connection.close()
+ observed = pq.read_schema(temporary)
+ if not observed.equals(schemas.LIGAND_3D_PAIR_CANDIDATE_SCHEMA):
+ temporary.unlink(missing_ok=True)
+ raise ValueError(f"ligand 3D candidates have unexpected schema: {observed}")
+ install = output.with_suffix(output.suffix + ".tmp")
+ copyfile(temporary, install)
+ install.replace(output)
+ temporary.unlink(missing_ok=True)
+ _refresh_ligand_3d_pair_candidate_manifest(
+ data_dir=data_dir,
+ shard=shard,
+ pair_output=output,
+ )
+ row_count = pq.ParquetFile(output).metadata.num_rows
+ reports.append({"shard": shard, "status": "complete", "row_count": row_count})
+ LOG.info(
+ "ligand 3D candidate progress: shard=%s rows=%d shards=%d/%d",
+ shard,
+ row_count,
+ len(reports),
+ len(selected),
+ )
+ return {
+ "status": "complete",
+ "shard_count": len(reports),
+ "row_count": sum(int(report["row_count"]) for report in reports),
+ "elapsed_seconds": perf_counter() - started,
+ "shards": reports,
+ }
+
+
+def _refresh_ligand_3d_pair_candidate_manifest(
+ *, data_dir: Path, shard: str, pair_output: Path
+) -> None:
+ """Bind a normalized compact candidate shard to its owning manifest."""
+ candidate = (
+ data_dir / "scores" / "ligand_3d_candidate_shards" / f"shard={shard}.parquet"
+ )
+ manifest_path = candidate.with_suffix(".json")
+ try:
+ payload = json.loads(manifest_path.read_text())
+ except (OSError, TypeError, ValueError) as exc:
+ raise ValueError(
+ f"invalid ligand 3D candidate shard manifest: {manifest_path}"
+ ) from exc
+ if not candidate.is_file():
+ raise FileNotFoundError(candidate)
+ candidate_stat = candidate.stat()
+ candidate_signature = {
+ "path": str(candidate.resolve()),
+ "size": candidate_stat.st_size,
+ "mtime_ns": candidate_stat.st_mtime_ns,
+ "rows": pq.ParquetFile(candidate).metadata.num_rows,
+ }
+ if (
+ payload.get("shard") != shard
+ or payload.get("output") != candidate_signature
+ or not isinstance(payload.get("inputs"), list)
+ ):
+ raise ValueError(f"stale ligand 3D candidate shard: {candidate}")
+ pair_stat = pair_output.stat()
+ pair_signature = {
+ "path": str(pair_output.resolve()),
+ "size": pair_stat.st_size,
+ "mtime_ns": pair_stat.st_mtime_ns,
+ "rows": pq.ParquetFile(pair_output).metadata.num_rows,
+ }
+ if payload.get("pair_output") == pair_signature:
+ return
+ payload["pair_output"] = pair_signature
+ write_json_atomic(manifest_path, payload)
+
+
+def plan_interface_scoring(
+ data_dir: Path,
+ *,
+ batch_size: int = 1,
+) -> dict[str, Any]:
+ """Freeze query-sharded all-vs-all interface scoring work.
+
+ Every interface whose entry has a completed mapped protein query is kept
+ as a query. Mapping-budget drops remain valid targets but are omitted as
+ queries, matching the mapped-alignment release contract.
+ """
+ if batch_size < 1:
+ raise ValueError("interface score batch size must be positive")
+ protein_plan = _load_plan(
+ data_dir,
+ recheck_source=True,
+ recheck_score_inputs=False,
+ )
+ tasks.make_interface_representatives(
+ data_dir=data_dir,
+ scratch_dir=Path(os.environ.get("TMPDIR", data_dir / "scratch")),
+ threads=1,
+ )
+ alignment_manifest_path, alignment_manifest = _interface_score_alignment_manifest(
+ data_dir
+ )
+ interface_path = data_dir / tasks.INTERFACE_REPRESENTATIVES_RELATIVE
+ membership_path = data_dir / tasks.INTERFACE_MEMBERSHIP_RELATIVE
+ annotation_path = data_dir / "index" / "interface_annotation_table.parquet"
+
+ planned_queries = set(
+ pd.read_parquet(data_dir / MANIFEST_RELATIVE, columns=["pdb_id"])[
+ "pdb_id"
+ ].astype(str)
+ )
+ skipped_queries = {str(value) for value in alignment_manifest["skipped_queries"]}
+ query_entries = planned_queries.difference(skipped_queries)
+ representatives = pd.read_parquet(
+ interface_path,
+ columns=["entry_pdb_id", "representative_system_id"],
+ )
+ representatives["entry_pdb_id"] = representatives["entry_pdb_id"].astype(str)
+ representatives = representatives[
+ representatives["entry_pdb_id"].isin(planned_queries)
+ ].copy()
+ if representatives["representative_system_id"].duplicated().any():
+ duplicate = str(
+ representatives.loc[
+ representatives["representative_system_id"].duplicated(),
+ "representative_system_id",
+ ].iloc[0]
+ )
+ raise ValueError(f"representative interface IDs are not unique: {duplicate}")
+ query_representatives = representatives[
+ representatives["entry_pdb_id"].isin(query_entries)
+ ].copy()
+ query_representatives["shard"] = query_representatives["entry_pdb_id"].str[1:3]
+ annotation_entries = pd.read_parquet(
+ annotation_path,
+ columns=["entry_pdb_id"],
+ )["entry_pdb_id"].astype(str)
+ target_interface_count = int(annotation_entries.isin(planned_queries).sum())
+ query_interface_count = int(annotation_entries.isin(query_entries).sum())
+
+ records: list[dict[str, Any]] = []
+ for shard, shard_interfaces in query_representatives.groupby("shard", sort=True):
+ alignment_rows = 0
+ backend_count = 0
+ for alignment_type in ["foldseek", "mmseqs"]:
+ path = tasks._alignment_release_path(
+ data_dir=data_dir,
+ search_db="holo",
+ alignment_type=alignment_type,
+ shard=str(shard),
+ )
+ if path.is_file():
+ backend_count += 1
+ alignment_rows += int(pq.ParquetFile(path).metadata.num_rows)
+ if backend_count == 0:
+ raise FileNotFoundError(
+ f"no mapped alignment backend is available for interface shard {shard}"
+ )
+ records.append(
+ {
+ "shard": str(shard),
+ "query_entry_count": int(shard_interfaces["entry_pdb_id"].nunique()),
+ "query_representative_interface_count": len(shard_interfaces),
+ "alignment_rows": alignment_rows,
+ }
+ )
+ work = pd.DataFrame.from_records(
+ records,
+ columns=[
+ "shard",
+ "query_entry_count",
+ "query_representative_interface_count",
+ "alignment_rows",
+ ],
+ )
+ work_path = data_dir / INTERFACE_SCORE_WORK_RELATIVE
+ _atomic_parquet(work, work_path)
+ payload = {
+ "status": "planned",
+ "batch_size": batch_size,
+ "batch_count": math.ceil(len(work) / batch_size),
+ "shard_count": len(work),
+ "query_entry_count": int(query_representatives["entry_pdb_id"].nunique()),
+ "query_interface_count": query_interface_count,
+ "query_representative_interface_count": len(query_representatives),
+ "target_interface_count": target_interface_count,
+ "target_representative_interface_count": len(representatives),
+ "skipped_query_count": len(skipped_queries.intersection(planned_queries)),
+ "protein_manifest": protein_plan["manifest"],
+ "alignment_manifest": _source_signature(alignment_manifest_path),
+ "interface_annotation": _source_signature(annotation_path),
+ "interface_representatives": _source_signature(interface_path),
+ "interface_membership": _source_signature(membership_path),
+ "work": _source_signature(work_path),
+ }
+ write_json_atomic(data_dir / INTERFACE_SCORE_PLAN_RELATIVE, payload)
+
+ # A new frozen plan replaces the previous query universe. Remove only
+ # query-sharded interface outputs that the new plan no longer names so a
+ # resumed finalizer cannot mix generations or fail on obsolete shards.
+ expected_shards = set(work["shard"].astype(str))
+ score_root = data_dir / INTERFACE_SCORE_ROOT_RELATIVE
+ for stale in score_root.glob("shard=*.parquet"):
+ if stale.stem.removeprefix("shard=") not in expected_shards:
+ stale.unlink()
+ stale.with_suffix(".json").unlink(missing_ok=True)
+ return payload
+
+
+def _load_interface_score_plan(data_dir: Path) -> dict[str, Any]:
+ path = data_dir / INTERFACE_SCORE_PLAN_RELATIVE
+ try:
+ payload = cast(dict[str, Any], json.loads(path.read_text()))
+ except (OSError, TypeError, ValueError) as exc:
+ raise FileNotFoundError(
+ f"missing or invalid interface score plan: {path}"
+ ) from exc
+ checks = {
+ "protein_manifest": data_dir / MANIFEST_RELATIVE,
+ "alignment_manifest": data_dir / "alignments" / "manifest.json",
+ "interface_annotation": (
+ data_dir / "index" / "interface_annotation_table.parquet"
+ ),
+ "interface_representatives": (
+ data_dir / tasks.INTERFACE_REPRESENTATIVES_RELATIVE
+ ),
+ "interface_membership": data_dir / tasks.INTERFACE_MEMBERSHIP_RELATIVE,
+ "work": data_dir / INTERFACE_SCORE_WORK_RELATIVE,
+ }
+ for key, source in checks.items():
+ if not source.is_file() or payload.get(key) != _source_signature(source):
+ raise ValueError(f"interface scoring input changed after planning: {key}")
+ if payload.get("status") != "planned":
+ raise ValueError(
+ f"invalid interface score plan status: {payload.get('status')}"
+ )
+ return payload
+
+
+def _interface_score_shard_batch(
+ data_dir: Path,
+ *,
+ batch_index: int,
+ batch_size: int,
+) -> list[str]:
+ if batch_index < 0 or batch_size < 1:
+ raise ValueError("batch_index must be non-negative and batch_size positive")
+ plan = _load_interface_score_plan(data_dir)
+ if batch_size != int(plan["batch_size"]):
+ raise ValueError(
+ f"interface score batch size is {plan['batch_size']}, got {batch_size}"
+ )
+ work = pd.read_parquet(data_dir / INTERFACE_SCORE_WORK_RELATIVE, columns=["shard"])
+ start = batch_index * batch_size
+ return cast(
+ list[str],
+ work.iloc[start : start + batch_size]["shard"].astype(str).tolist(),
+ )
+
+
+def _interface_score_inputs(data_dir: Path, shard: str) -> dict[str, Any]:
+ half_interfaces = data_dir / tasks.INTERFACE_HALF_REPRESENTATIVES_RELATIVE
+ interfaces = data_dir / tasks.INTERFACE_REPRESENTATIVES_RELATIVE
+ membership = data_dir / tasks.INTERFACE_MEMBERSHIP_RELATIVE
+ mapping_manifest = tasks._alignment_mapping_manifest_path(
+ data_dir=data_dir,
+ shard=shard,
+ )
+ if not mapping_manifest.is_file():
+ raise FileNotFoundError(mapping_manifest)
+ alignments: dict[str, dict[str, int | str]] = {}
+ for alignment_type in ["foldseek", "mmseqs"]:
+ path = tasks._alignment_release_path(
+ data_dir=data_dir,
+ search_db="holo",
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ if path.is_file():
+ alignments[alignment_type] = _source_signature(path)
+ if not alignments:
+ raise FileNotFoundError(
+ f"no mapped alignment backend is available for interface shard {shard}"
+ )
+ return {
+ "half_interface_representatives": _source_signature(half_interfaces),
+ "interface_representatives": _source_signature(interfaces),
+ "interface_membership": _source_signature(membership),
+ "alignment_manifest": _source_signature(
+ data_dir / "alignments" / "manifest.json"
+ ),
+ "mapping_manifest": _source_signature(mapping_manifest),
+ "alignments": alignments,
+ "minimum_side_similarity": MINIMUM_STORED_INTERFACE_SIDE_SIMILARITY,
+ }
+
+
+def _interface_score_output_is_current(
+ *,
+ output: Path,
+ manifest: Path,
+ inputs: dict[str, Any],
+) -> dict[str, Any] | None:
+ if not output.is_file() or not manifest.is_file():
+ return None
+ try:
+ payload = cast(dict[str, Any], json.loads(manifest.read_text()))
+ if (
+ payload.get("inputs") == inputs
+ and payload.get("output") == _source_signature(output)
+ and pq.read_schema(output).equals(schemas.INTERFACE_SCORE_SHARD_SCHEMA)
+ and int(payload["rows"]) == pq.ParquetFile(output).metadata.num_rows
+ ):
+ return payload
+ except (OSError, TypeError, ValueError):
+ pass
+ return None
+
+
+def score_interface_qcov_shards(
+ data_dir: Path,
+ *,
+ shards: list[str],
+ scratch_dir: Path,
+ threads: int = 4,
+ memory_limit: str = "32GB",
+ side_coverage_bucket_count: int = 32,
+ assignment_target_bucket_count: int = 1,
+ force_update: bool = False,
+ query_entries_by_shard: Mapping[str, set[str]] | None = None,
+ output_paths_by_shard: Mapping[str, Path] | None = None,
+) -> dict[str, Any]:
+ """Score all directed interface pairs for complete query shards."""
+ if min(threads, side_coverage_bucket_count, assignment_target_bucket_count) < 1:
+ raise ValueError(
+ "interface scoring threads and side-coverage buckets must be positive"
+ )
+ _load_interface_score_plan(data_dir)
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ output_root = data_dir / INTERFACE_SCORE_ROOT_RELATIVE
+ output_root.mkdir(exist_ok=True, parents=True)
+ half_interface_path = data_dir / tasks.INTERFACE_HALF_REPRESENTATIVES_RELATIVE
+ interface_path = data_dir / tasks.INTERFACE_REPRESENTATIVES_RELATIVE
+ chain_lookup = data_dir / tasks.ALIGNMENT_CHAIN_LOOKUP_RELATIVE
+ reports: list[dict[str, Any]] = []
+ started = perf_counter()
+ for index, shard in enumerate(shards, start=1):
+ inputs = _interface_score_inputs(data_dir, shard)
+ query_entries = (
+ query_entries_by_shard.get(shard)
+ if query_entries_by_shard is not None
+ else None
+ )
+ if query_entries is not None:
+ if not query_entries or any(
+ len(entry) != 4 or not entry.isalnum() for entry in query_entries
+ ):
+ raise ValueError(
+ f"invalid query-entry selection for interface shard {shard}"
+ )
+ wrong_shard = sorted(
+ entry for entry in query_entries if entry[1:3] != shard
+ )
+ if wrong_shard:
+ raise ValueError(
+ f"query entries do not belong to shard {shard}: {wrong_shard[:10]}"
+ )
+ inputs = {**inputs, "query_entries": sorted(query_entries)}
+ output = (
+ output_paths_by_shard[shard]
+ if output_paths_by_shard is not None
+ else output_root / f"shard={shard}.parquet"
+ )
+ output.parent.mkdir(exist_ok=True, parents=True)
+ manifest = output.with_suffix(".json")
+ current = _interface_score_output_is_current(
+ output=output,
+ manifest=manifest,
+ inputs=inputs,
+ )
+ if not force_update and current is not None:
+ reports.append(current)
+ LOG.info(
+ "interface score progress: shards=%d/%d shard=%s rows=%s "
+ "elapsed_seconds=%.1f cached=true",
+ index,
+ len(shards),
+ shard,
+ current["rows"],
+ perf_counter() - started,
+ )
+ continue
+
+ backend_selects: list[str] = []
+ alignments = cast(dict[str, dict[str, Any]], inputs["alignments"])
+ query_filter = ""
+ if query_entries is not None:
+ selected = ", ".join(f"'{entry}'" for entry in sorted(query_entries))
+ query_filter = f"WHERE alignment.query_entry IN ({selected})"
+ for alignment_type, signature in alignments.items():
+ path = Path(str(signature["path"]))
+ backend_selects.append(
+ dedent(
+ f"""
+ SELECT
+ '{alignment_type}' AS backend,
+ row_number() OVER ()::BIGINT AS alignment_id,
+ alignment.query_entry,
+ alignment.target_entry,
+ alignment.query_chain_mapped,
+ alignment.target_chain_mapped,
+ list_transform(
+ alignment.query_selected_residue_positions,
+ position -> list_extract(
+ query_chain.selected_residue_numbers, position
+ )
+ ) AS query_selected_residue_numbers,
+ list_transform(
+ alignment.target_selected_residue_positions,
+ position -> CASE
+ WHEN position = 0 THEN -1
+ ELSE list_extract(
+ target_chain.selected_residue_numbers, position
+ )
+ END
+ ) AS target_selected_residue_numbers
+ FROM ({cigar_alignment_sql(path, chain_lookup)}) AS alignment
+ INNER JOIN read_parquet(
+ '{chain_lookup.as_posix()}'
+ ) AS query_chain
+ ON alignment.query_entry = query_chain.entry_pdb_id
+ AND alignment.query_chain_mapped = query_chain.chain_asym_id
+ INNER JOIN read_parquet(
+ '{chain_lookup.as_posix()}'
+ ) AS target_chain
+ ON alignment.target_entry = target_chain.entry_pdb_id
+ AND alignment.target_chain_mapped = target_chain.chain_asym_id
+ {query_filter}
+ """
+ ).strip()
+ )
+ mapped_sql = "\nUNION ALL\n".join(backend_selects)
+ local_root = scratch_dir / shard
+ local_root.mkdir(exist_ok=True, parents=True)
+ local_output = local_root / output.name
+ local_output.unlink(missing_ok=True)
+ import duckdb
+
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{local_root.as_posix()}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql("SET preserve_insertion_order=false")
+ coverage_root = local_root / "coverage_partitions"
+ side_coverage_root = local_root / "side_coverage_partitions"
+ whole_coverage_root = local_root / "whole_coverage_partitions"
+ side_coverage_output = local_root / "side_coverage.parquet"
+ rmtree(coverage_root, ignore_errors=True)
+ rmtree(side_coverage_root, ignore_errors=True)
+ rmtree(whole_coverage_root, ignore_errors=True)
+ side_coverage_output.unlink(missing_ok=True)
+ side_started = perf_counter()
+ LOG.info(
+ "interface half coverage: shard=%s buckets=%d starting",
+ shard,
+ side_coverage_bucket_count,
+ )
+ connection.sql(
+ dedent(
+ f"""
+ COPY (
+ WITH half_interfaces AS (
+ SELECT
+ entry_pdb_id,
+ half_interface_id,
+ instance_chain_id,
+ chain_asym_id AS asym_id,
+ residue_numbers,
+ len(residue_numbers)::DOUBLE AS residue_count
+ FROM read_parquet('{half_interface_path.as_posix()}')
+ ), mapped AS (
+ {mapped_sql}
+ ), query_half_alignments AS (
+ SELECT
+ mapped.backend,
+ mapped.alignment_id,
+ mapped.target_entry,
+ mapped.target_chain_mapped,
+ query_half.half_interface_id AS query_half,
+ query_half.instance_chain_id AS query_instance_chain,
+ query_half.residue_count AS query_residue_count,
+ list_transform(
+ list_filter(
+ range(
+ 1,
+ len(
+ mapped.query_selected_residue_numbers
+ ) + 1
+ ),
+ position -> list_contains(
+ query_half.residue_numbers,
+ list_extract(
+ mapped.query_selected_residue_numbers,
+ position
+ )
+ )
+ ),
+ position -> list_extract(
+ mapped.target_selected_residue_numbers,
+ position
+ )
+ ) AS aligned_target_residues
+ FROM mapped
+ INNER JOIN half_interfaces AS query_half
+ ON mapped.query_entry = query_half.entry_pdb_id
+ AND mapped.query_chain_mapped = query_half.asym_id
+ ), coverage_candidates AS (
+ SELECT
+ query.backend,
+ query.alignment_id,
+ query.query_half,
+ target_half.half_interface_id AS target_half,
+ query.query_instance_chain,
+ target_half.instance_chain_id AS target_instance_chain,
+ query.query_residue_count,
+ len(list_intersect(
+ query.aligned_target_residues,
+ target_half.residue_numbers
+ ))::DOUBLE AS covered_residue_count
+ FROM query_half_alignments AS query
+ INNER JOIN half_interfaces AS target_half
+ ON query.target_entry = target_half.entry_pdb_id
+ AND query.target_chain_mapped = target_half.asym_id
+ )
+ SELECT
+ backend,
+ query_half,
+ target_half,
+ query_instance_chain,
+ target_instance_chain,
+ covered_residue_count / query_residue_count AS qcov,
+ CAST(
+ hash(target_half)
+ % {side_coverage_bucket_count}
+ AS UTINYINT
+ ) AS target_bucket
+ FROM coverage_candidates
+ WHERE covered_residue_count > 0
+ ) TO '{coverage_root.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ PARTITION_BY (target_bucket),
+ ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ )
+ connection.close()
+ coverage_partitions = sorted(coverage_root.glob("target_bucket=*"))
+ side_coverage_root.mkdir(parents=True)
+ whole_coverage_root.mkdir()
+ coverage_rows = 0
+ side_rows = 0
+ for bucket_index, partition in enumerate(coverage_partitions, start=1):
+ source_files = sorted(partition.glob("*.parquet"))
+ coverage_rows += sum(
+ pq.ParquetFile(path).metadata.num_rows for path in source_files
+ )
+ side_part = side_coverage_root / f"part-{bucket_index:03d}.parquet"
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{local_root.as_posix()}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql("SET preserve_insertion_order=false")
+ connection.sql(
+ dedent(
+ f"""
+ COPY (
+ SELECT
+ backend,
+ query_half,
+ target_half,
+ query_instance_chain,
+ target_instance_chain,
+ max(qcov)::DOUBLE AS qcov
+ FROM read_parquet(
+ '{partition.as_posix()}/*.parquet'
+ )
+ GROUP BY
+ backend,
+ query_half,
+ target_half,
+ query_instance_chain,
+ target_instance_chain
+ ) TO '{side_part.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ )
+ whole_coverage_part = whole_coverage_root / side_part.name
+ connection.sql(
+ f"""
+ COPY (
+ SELECT backend, query_half, target_half,
+ max(qcov) AS qcov,
+ min(query_instance_chain || ':' || target_instance_chain)
+ AS mapping_part
+ FROM read_parquet('{side_part.as_posix()}')
+ GROUP BY backend, query_half, target_half
+ ) TO '{whole_coverage_part.as_posix()}'
+ (FORMAT PARQUET, COMPRESSION ZSTD)
+ """
+ )
+ connection.close()
+ side_rows += pq.ParquetFile(side_part).metadata.num_rows
+ if bucket_index % 8 == 0 or bucket_index == len(coverage_partitions):
+ LOG.info(
+ "interface side coverage progress: shard=%s buckets=%d/%d "
+ "coverage_rows=%d side_rows=%d elapsed_seconds=%.1f",
+ shard,
+ bucket_index,
+ len(coverage_partitions),
+ coverage_rows,
+ side_rows,
+ perf_counter() - side_started,
+ )
+ if coverage_partitions:
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{local_root.as_posix()}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql("SET preserve_insertion_order=false")
+ connection.sql(
+ dedent(
+ f"""
+ COPY (
+ SELECT *
+ FROM read_parquet(
+ '{side_coverage_root.as_posix()}/*.parquet'
+ )
+ ) TO '{side_coverage_output.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ )
+ connection.close()
+ else:
+ pq.write_table(
+ pa.table(
+ {
+ "backend": pa.array([], type=pa.string()),
+ "query_half": pa.array([], type=pa.string()),
+ "target_half": pa.array([], type=pa.string()),
+ "query_instance_chain": pa.array([], type=pa.string()),
+ "target_instance_chain": pa.array([], type=pa.string()),
+ "qcov": pa.array([], type=pa.float64()),
+ }
+ ),
+ side_coverage_output,
+ compression="zstd",
+ )
+ LOG.info(
+ "interface side coverage: shard=%s coverage_rows=%d rows=%d "
+ "size_mb=%.1f "
+ "elapsed_seconds=%.1f",
+ shard,
+ coverage_rows,
+ side_rows,
+ side_coverage_output.stat().st_size / (1024 * 1024),
+ perf_counter() - side_started,
+ )
+ if side_rows == 0:
+ pq.write_table(
+ pa.Table.from_pylist([], schema=schemas.INTERFACE_SCORE_SHARD_SCHEMA),
+ local_output,
+ compression="zstd",
+ )
+ else:
+ whole_score_root = local_root / "whole_score_parts"
+ side_score_root = local_root / "side_score_parts"
+ rmtree(whole_score_root, ignore_errors=True)
+ rmtree(side_score_root, ignore_errors=True)
+ whole_score_root.mkdir()
+ side_score_root.mkdir()
+ assignment_started = perf_counter()
+ assignment_bucket_count = (
+ side_coverage_bucket_count * assignment_target_bucket_count
+ )
+ LOG.info(
+ "interface assignment reduction: shard=%s buckets=%d starting",
+ shard,
+ assignment_bucket_count,
+ )
+ whole_rows = 0
+ interface_query_filter = (
+ f"entry_pdb_id IN ({selected})"
+ if query_entries is not None
+ else f"substr(entry_pdb_id, 2, 2) = '{shard}'"
+ )
+ for bucket_index in range(assignment_bucket_count):
+ query_bucket, target_bucket = divmod(
+ bucket_index, assignment_target_bucket_count
+ )
+ whole_part = whole_score_root / f"part-{bucket_index:03d}.parquet"
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{local_root.as_posix()}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql("SET preserve_insertion_order=false")
+ connection.sql(
+ dedent(
+ f"""
+ COPY (
+ WITH query_interfaces AS (
+ SELECT
+ representative_system_id AS interface_id,
+ half_interface_1_id,
+ half_interface_2_id
+ FROM read_parquet('{interface_path.as_posix()}')
+ WHERE hash(representative_system_id)
+ % {side_coverage_bucket_count} = {query_bucket}
+ AND {interface_query_filter}
+ ), target_interfaces AS (
+ SELECT
+ representative_system_id AS interface_id,
+ half_interface_1_id AS target_half_1,
+ half_interface_2_id AS target_half_2,
+ 0::TINYINT AS assignment_order
+ FROM read_parquet('{interface_path.as_posix()}')
+ WHERE hash(representative_system_id)
+ % {assignment_target_bucket_count}
+ = {target_bucket}
+ UNION ALL
+ SELECT
+ representative_system_id AS interface_id,
+ half_interface_2_id AS target_half_1,
+ half_interface_1_id AS target_half_2,
+ 1::TINYINT AS assignment_order
+ FROM read_parquet('{interface_path.as_posix()}')
+ WHERE hash(representative_system_id)
+ % {assignment_target_bucket_count}
+ = {target_bucket}
+ ), side_coverage AS (
+ SELECT
+ backend,
+ query_half,
+ target_half,
+ qcov,
+ mapping_part
+ FROM read_parquet(
+ '{whole_coverage_root.as_posix()}/*.parquet'
+ )
+ WHERE query_half IN (
+ SELECT half_interface_1_id FROM query_interfaces
+ UNION
+ SELECT half_interface_2_id FROM query_interfaces
+ ) AND target_half IN (
+ SELECT target_half_1 FROM target_interfaces
+ UNION
+ SELECT target_half_2 FROM target_interfaces
+ )
+ ), first_matches AS MATERIALIZED (
+ SELECT
+ first_side.backend,
+ query_interface.interface_id AS iface1,
+ target_interface.interface_id AS iface2,
+ first_side.qcov AS iface1_qcov,
+ first_side.mapping_part AS iface1_mapping,
+ query_interface.half_interface_2_id AS query_half_2,
+ target_interface.target_half_2,
+ target_interface.assignment_order
+ FROM query_interfaces AS query_interface
+ INNER JOIN side_coverage AS first_side
+ ON first_side.query_half
+ = query_interface.half_interface_1_id
+ INNER JOIN target_interfaces AS target_interface
+ ON first_side.target_half
+ = target_interface.target_half_1
+ WHERE query_interface.interface_id
+ != target_interface.interface_id
+ ), assignments AS (
+ SELECT first_matches.* EXCLUDE (
+ iface1_mapping, query_half_2, target_half_2
+ ),
+ second_side.qcov AS iface2_qcov,
+ iface1_qcov * second_side.qcov AS final_score,
+ iface1_mapping || ';' || second_side.mapping_part
+ AS mapping
+ FROM first_matches
+ INNER JOIN side_coverage AS second_side
+ ON second_side.query_half = first_matches.query_half_2
+ AND second_side.target_half = first_matches.target_half_2
+ AND second_side.backend = first_matches.backend
+ ), backend_best AS (
+ SELECT * EXCLUDE (
+ assignment_rank,
+ assignment_order
+ )
+ FROM (
+ SELECT
+ *,
+ row_number() OVER (
+ PARTITION BY backend, iface1, iface2
+ ORDER BY final_score DESC,
+ assignment_order,
+ mapping
+ ) AS assignment_rank
+ FROM assignments
+ )
+ WHERE assignment_rank = 1
+ ), pair_best AS (
+ SELECT
+ iface1,
+ iface2,
+ max(final_score) AS final_score
+ FROM backend_best
+ GROUP BY iface1, iface2
+ ), winning_backends AS (
+ SELECT backend_best.*
+ FROM backend_best
+ INNER JOIN pair_best USING (iface1, iface2)
+ WHERE abs(
+ backend_best.final_score
+ - pair_best.final_score
+ ) < 1e-12
+ )
+ SELECT
+ iface1::VARCHAR AS query_system,
+ iface2::VARCHAR AS target_system,
+ first(
+ mapping ORDER BY
+ CASE
+ WHEN backend = 'foldseek' THEN 0
+ ELSE 1
+ END,
+ mapping
+ )::VARCHAR AS mapping,
+ CASE
+ WHEN count(DISTINCT backend) = 2 THEN 'both'
+ ELSE min(backend)
+ END::VARCHAR AS source,
+ 'interface_qcov'::VARCHAR AS metric,
+ first(
+ iface1_qcov ORDER BY
+ CASE
+ WHEN backend = 'foldseek' THEN 0
+ ELSE 1
+ END,
+ mapping
+ )::FLOAT AS iface1_qcov,
+ first(
+ iface2_qcov ORDER BY
+ CASE
+ WHEN backend = 'foldseek' THEN 0
+ ELSE 1
+ END,
+ mapping
+ )::FLOAT AS iface2_qcov,
+ CAST(
+ least(
+ 100,
+ greatest(
+ 0,
+ round(max(final_score) * 100)
+ )
+ ) AS TINYINT
+ ) AS similarity
+ FROM winning_backends
+ GROUP BY iface1, iface2
+ HAVING max(final_score) > 0
+ ) TO '{whole_part.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ )
+ connection.close()
+ whole_rows += pq.ParquetFile(whole_part).metadata.num_rows
+ if (bucket_index + 1) % 8 == 0 or (
+ bucket_index + 1 == assignment_bucket_count
+ ):
+ LOG.info(
+ "interface assignment progress: shard=%s buckets=%d/%d "
+ "whole_rows=%d elapsed_seconds=%.1f",
+ shard,
+ bucket_index + 1,
+ assignment_bucket_count,
+ whole_rows,
+ perf_counter() - assignment_started,
+ )
+
+ side_score_rows = 0
+ side_parts = sorted(side_coverage_root.glob("*.parquet"))
+ for part_index, side_part in enumerate(side_parts, start=1):
+ side_score_part = side_score_root / f"part-{part_index:03d}.parquet"
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{local_root.as_posix()}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql("SET preserve_insertion_order=false")
+ connection.sql(
+ dedent(
+ f"""
+ COPY (
+ WITH side_coverage AS (
+ SELECT *
+ FROM read_parquet('{side_part.as_posix()}')
+ WHERE query_half != target_half
+ ), pair_best AS (
+ SELECT
+ query_half,
+ target_half,
+ max(qcov) AS qcov
+ FROM side_coverage
+ GROUP BY query_half, target_half
+ ), winners AS (
+ SELECT side_coverage.*
+ FROM side_coverage
+ INNER JOIN pair_best
+ ON side_coverage.query_half
+ = pair_best.query_half
+ AND side_coverage.target_half
+ = pair_best.target_half
+ WHERE abs(
+ side_coverage.qcov - pair_best.qcov
+ ) < 1e-12
+ )
+ SELECT
+ query_half::VARCHAR AS query_system,
+ target_half::VARCHAR AS target_system,
+ first(
+ query_instance_chain || ':'
+ || target_instance_chain
+ ORDER BY backend
+ )::VARCHAR AS mapping,
+ CASE
+ WHEN count(DISTINCT backend) = 2 THEN 'both'
+ ELSE min(backend)
+ END::VARCHAR AS source,
+ 'interface_side_qcov'::VARCHAR AS metric,
+ NULL::FLOAT AS iface1_qcov,
+ NULL::FLOAT AS iface2_qcov,
+ CAST(
+ least(
+ 100,
+ greatest(0, round(max(qcov) * 100))
+ ) AS TINYINT
+ ) AS similarity
+ FROM winners
+ GROUP BY query_half, target_half
+ HAVING round(max(qcov) * 100)
+ >= {MINIMUM_STORED_INTERFACE_SIDE_SIMILARITY}
+ ) TO '{side_score_part.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ )
+ connection.close()
+ side_score_rows += pq.ParquetFile(side_score_part).metadata.num_rows
+
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{local_root.as_posix()}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql("SET preserve_insertion_order=false")
+ connection.sql(
+ dedent(
+ f"""
+ COPY (
+ SELECT *
+ FROM read_parquet([
+ '{whole_score_root.as_posix()}/*.parquet',
+ '{side_score_root.as_posix()}/*.parquet'
+ ])
+ ) TO '{local_output.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ )
+ connection.close()
+ LOG.info(
+ "interface assignment reduction: shard=%s whole_rows=%d "
+ "side_rows=%d elapsed_seconds=%.1f",
+ shard,
+ whole_rows,
+ side_score_rows,
+ perf_counter() - assignment_started,
+ )
+ observed_schema = pq.read_schema(local_output)
+ if not observed_schema.equals(schemas.INTERFACE_SCORE_SHARD_SCHEMA):
+ local_output.unlink(missing_ok=True)
+ raise ValueError(
+ f"interface score shard has unexpected schema: {observed_schema}"
+ )
+ rows = int(pq.ParquetFile(local_output).metadata.num_rows)
+ install = output.with_suffix(output.suffix + ".tmp")
+ copyfile(local_output, install)
+ install.replace(output)
+ local_output.unlink(missing_ok=True)
+ payload = {
+ "status": "complete",
+ "shard": shard,
+ "inputs": inputs,
+ "output": _source_signature(output),
+ "rows": rows,
+ }
+ write_json_atomic(manifest, payload)
+ reports.append(payload)
+ LOG.info(
+ "interface score progress: shards=%d/%d shard=%s rows=%d "
+ "elapsed_seconds=%.1f",
+ index,
+ len(shards),
+ shard,
+ rows,
+ perf_counter() - started,
+ )
+ return {
+ "status": "complete",
+ "shard_count": len(reports),
+ "row_count": sum(int(report["rows"]) for report in reports),
+ "shards": [str(report["shard"]) for report in reports],
+ }
+
+
+def plan_interface_score_repair(
+ data_dir: Path,
+ *,
+ batch_size: int = 25,
+ query_manifest: Path | None = None,
+) -> dict[str, Any]:
+ """Split incomplete shards or selected query entries into repair batches."""
+ if batch_size < 1:
+ raise ValueError("interface repair batch size must be positive")
+ interface_plan = _load_interface_score_plan(data_dir)
+ work = pd.read_parquet(data_dir / INTERFACE_SCORE_WORK_RELATIVE)
+ incomplete_shards: list[str] = []
+ for shard in work["shard"].astype(str):
+ output = data_dir / INTERFACE_SCORE_ROOT_RELATIVE / f"shard={shard}.parquet"
+ current = _interface_score_output_is_current(
+ output=output,
+ manifest=output.with_suffix(".json"),
+ inputs=_interface_score_inputs(data_dir, shard),
+ )
+ if current is None:
+ incomplete_shards.append(shard)
+
+ protein_queries = set(
+ pd.read_parquet(data_dir / MANIFEST_RELATIVE, columns=["pdb_id"])[
+ "pdb_id"
+ ].astype(str)
+ )
+ alignment_manifest = json.loads(
+ (data_dir / "alignments" / "manifest.json").read_text()
+ )
+ skipped_queries = {
+ str(value) for value in alignment_manifest.get("skipped_queries", {})
+ }
+ active_queries = protein_queries.difference(skipped_queries)
+ selected_queries: set[str] | None = None
+ repair_mode = "replace_shards"
+ if query_manifest is not None:
+ selected_queries = set(_load_pdb_id_manifest(query_manifest))
+ if not selected_queries:
+ raise ValueError("interface repair query manifest is empty")
+ invalid_queries = sorted(selected_queries.difference(active_queries))
+ if invalid_queries:
+ raise ValueError(
+ "interface repair contains inactive protein queries: "
+ f"{invalid_queries[:20]}"
+ )
+ repair_mode = "selected_queries"
+ representatives = pd.read_parquet(
+ data_dir / tasks.INTERFACE_REPRESENTATIVES_RELATIVE,
+ columns=["entry_pdb_id", "representative_system_id"],
+ )
+ representatives["entry_pdb_id"] = representatives["entry_pdb_id"].astype(str)
+ representatives["shard"] = representatives["entry_pdb_id"].str[1:3]
+ if selected_queries is None:
+ representatives = representatives[
+ representatives["entry_pdb_id"].isin(active_queries)
+ & representatives["shard"].isin(incomplete_shards)
+ ]
+ repair_shards = incomplete_shards
+ else:
+ representatives = representatives[
+ representatives["entry_pdb_id"].isin(selected_queries)
+ ]
+ represented_queries = set(representatives["entry_pdb_id"].astype(str))
+ missing_queries = sorted(selected_queries.difference(represented_queries))
+ if missing_queries:
+ raise ValueError(
+ "interface repair queries have no representative interfaces: "
+ f"{missing_queries[:20]}"
+ )
+ repair_shards = sorted(set(representatives["shard"].astype(str)))
+ incomplete_selected = sorted(set(repair_shards).intersection(incomplete_shards))
+ if incomplete_selected:
+ raise ValueError(
+ "selected-query repair requires complete existing score shards: "
+ f"{incomplete_selected[:20]}"
+ )
+ entry_work = (
+ representatives.groupby(["shard", "entry_pdb_id"], as_index=False)
+ .size()
+ .rename(columns={"size": "query_representative_interface_count"})
+ )
+ if repair_shards and set(entry_work["shard"].astype(str)) != set(repair_shards):
+ missing = sorted(set(repair_shards).difference(entry_work["shard"].astype(str)))
+ raise ValueError(
+ f"incomplete interface shards have no query entries: {missing}"
+ )
+
+ records: list[dict[str, Any]] = []
+ next_batch_index = 0
+ for shard, shard_work in entry_work.groupby("shard", sort=True):
+ batch_count = math.ceil(len(shard_work) / batch_size)
+ loads = [0] * batch_count
+ counts = [0] * batch_count
+ assignments: dict[str, int] = {}
+ for row in shard_work.sort_values(
+ ["query_representative_interface_count", "entry_pdb_id"],
+ ascending=[False, True],
+ ).itertuples(index=False):
+ eligible = [
+ index for index in range(batch_count) if counts[index] < batch_size
+ ]
+ selected = min(
+ eligible,
+ key=lambda index: (loads[index], counts[index], index),
+ )
+ assignments[str(row.entry_pdb_id)] = next_batch_index + selected
+ loads[selected] += int(row.query_representative_interface_count)
+ counts[selected] += 1
+ for row in shard_work.itertuples(index=False):
+ records.append(
+ {
+ "repair_batch_index": assignments[str(row.entry_pdb_id)],
+ "shard": str(shard),
+ "entry_pdb_id": str(row.entry_pdb_id),
+ "query_representative_interface_count": int(
+ row.query_representative_interface_count
+ ),
+ }
+ )
+ next_batch_index += batch_count
+
+ repair = pd.DataFrame.from_records(
+ records,
+ columns=[
+ "repair_batch_index",
+ "shard",
+ "entry_pdb_id",
+ "query_representative_interface_count",
+ ],
+ ).sort_values(
+ ["repair_batch_index", "entry_pdb_id"],
+ ignore_index=True,
+ )
+ repair_path = data_dir / INTERFACE_SCORE_REPAIR_RELATIVE
+ _atomic_parquet(repair, repair_path)
+ payload = {
+ "status": "planned",
+ "repair_mode": repair_mode,
+ "batch_size": batch_size,
+ "batch_count": next_batch_index,
+ "entry_count": len(repair),
+ "shard_count": len(repair_shards),
+ "incomplete_shards": incomplete_shards,
+ "query_manifest": (
+ _source_signature(query_manifest) if query_manifest is not None else None
+ ),
+ "interface_score_plan": _source_signature(
+ data_dir / INTERFACE_SCORE_PLAN_RELATIVE
+ ),
+ "interface_score_work": interface_plan["work"],
+ "repair_manifest": _source_signature(repair_path),
+ }
+ write_json_atomic(data_dir / INTERFACE_SCORE_REPAIR_PLAN_RELATIVE, payload)
+ return payload
+
+
+def _load_interface_score_repair_plan(data_dir: Path) -> dict[str, Any]:
+ plan_path = data_dir / INTERFACE_SCORE_REPAIR_PLAN_RELATIVE
+ try:
+ payload = cast(dict[str, Any], json.loads(plan_path.read_text()))
+ except (OSError, TypeError, ValueError) as exc:
+ raise FileNotFoundError(
+ f"missing or invalid interface repair plan: {plan_path}"
+ ) from exc
+ checks = {
+ "interface_score_plan": data_dir / INTERFACE_SCORE_PLAN_RELATIVE,
+ "repair_manifest": data_dir / INTERFACE_SCORE_REPAIR_RELATIVE,
+ }
+ for key, source in checks.items():
+ if not source.is_file() or payload.get(key) != _source_signature(source):
+ raise ValueError(f"interface repair input changed after planning: {key}")
+ query_manifest = payload.get("query_manifest")
+ if query_manifest is not None:
+ source = Path(str(query_manifest.get("path", "")))
+ if not source.is_file() or query_manifest != _source_signature(source):
+ raise ValueError(
+ "interface repair input changed after planning: query_manifest"
+ )
+ if payload.get("status") != "planned":
+ raise ValueError(f"invalid interface repair status: {payload.get('status')}")
+ return payload
+
+
+def _interface_score_repair_part(
+ data_dir: Path,
+ *,
+ shard: str,
+ batch_index: int,
+) -> Path:
+ return (
+ data_dir
+ / INTERFACE_SCORE_REPAIR_ROOT_RELATIVE
+ / f"shard={shard}"
+ / f"batch={batch_index:05d}.parquet"
+ )
+
+
+def score_interface_qcov_repair_batch(
+ data_dir: Path,
+ *,
+ batch_index: int,
+ batch_size: int,
+ scratch_dir: Path,
+ threads: int = 4,
+ memory_limit: str = "32GB",
+ side_coverage_bucket_count: int = 32,
+ assignment_target_bucket_count: int = 1,
+ force_update: bool = False,
+) -> dict[str, Any]:
+ """Score one immutable, query-entry-filtered interface repair batch."""
+ plan = _load_interface_score_repair_plan(data_dir)
+ if batch_size != int(plan["batch_size"]):
+ raise ValueError(
+ f"interface repair batch size is {plan['batch_size']}, got {batch_size}"
+ )
+ repair = pd.read_parquet(data_dir / INTERFACE_SCORE_REPAIR_RELATIVE)
+ selected = repair[repair["repair_batch_index"].eq(batch_index)]
+ if selected.empty:
+ return {"status": "complete", "batch_index": batch_index, "entry_count": 0}
+ if selected["shard"].nunique() != 1:
+ raise ValueError(f"interface repair batch {batch_index} spans multiple shards")
+ if len(selected) > batch_size:
+ raise ValueError(
+ f"interface repair batch {batch_index} exceeds size {batch_size}"
+ )
+ shard = str(selected["shard"].iloc[0])
+ query_entries = set(selected["entry_pdb_id"].astype(str))
+ output = _interface_score_repair_part(
+ data_dir,
+ shard=shard,
+ batch_index=batch_index,
+ )
+ result = score_interface_qcov_shards(
+ data_dir,
+ shards=[shard],
+ scratch_dir=scratch_dir,
+ threads=threads,
+ memory_limit=memory_limit,
+ side_coverage_bucket_count=side_coverage_bucket_count,
+ assignment_target_bucket_count=assignment_target_bucket_count,
+ force_update=force_update,
+ query_entries_by_shard={shard: query_entries},
+ output_paths_by_shard={shard: output},
+ )
+ return {
+ **result,
+ "batch_index": batch_index,
+ "entry_count": len(query_entries),
+ }
+
+
+def _interface_score_repair_task_batches(
+ data_dir: Path,
+ *,
+ task_index: int,
+ batches_per_task: int,
+) -> list[int]:
+ """Map one scheduler task to consecutive checkpointed repair batches."""
+ if task_index < 0 or batches_per_task < 1:
+ raise ValueError(
+ "interface repair task index must be non-negative and "
+ "batches-per-task positive"
+ )
+ plan = _load_interface_score_repair_plan(data_dir)
+ start = task_index * batches_per_task
+ stop = min(start + batches_per_task, int(plan["batch_count"]))
+ return list(range(start, stop))
+
+
+def finalize_interface_score_repair(
+ data_dir: Path,
+ *,
+ scratch_dir: Path,
+ threads: int = 4,
+ memory_limit: str = "32GB",
+) -> dict[str, Any]:
+ """Validate repair parts and atomically replace repaired score rows."""
+ plan = _load_interface_score_repair_plan(data_dir)
+ repair = pd.read_parquet(data_dir / INTERFACE_SCORE_REPAIR_RELATIVE)
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ reports: list[dict[str, Any]] = []
+ import duckdb
+
+ for shard, shard_repair in repair.groupby("shard", sort=True):
+ shard = str(shard)
+ part_paths: list[Path] = []
+ covered_entries: set[str] = set()
+ for batch_index, batch in shard_repair.groupby("repair_batch_index", sort=True):
+ entries = set(batch["entry_pdb_id"].astype(str))
+ if covered_entries.intersection(entries):
+ raise ValueError(f"duplicate query entries in repair shard {shard}")
+ covered_entries.update(entries)
+ part = _interface_score_repair_part(
+ data_dir,
+ shard=shard,
+ batch_index=int(batch_index),
+ )
+ inputs = {
+ **_interface_score_inputs(data_dir, shard),
+ "query_entries": sorted(entries),
+ }
+ payload = _interface_score_output_is_current(
+ output=part,
+ manifest=part.with_suffix(".json"),
+ inputs=inputs,
+ )
+ if payload is None:
+ raise ValueError(f"missing or stale interface repair part: {part}")
+ part_paths.append(part)
+ expected_entries = set(shard_repair["entry_pdb_id"].astype(str))
+ if covered_entries != expected_entries:
+ raise ValueError(f"incomplete query-entry coverage for shard {shard}")
+
+ local_root = scratch_dir / shard
+ local_root.mkdir(exist_ok=True, parents=True)
+ local_output = local_root / f"shard={shard}.parquet"
+ local_output.unlink(missing_ok=True)
+ for part in part_paths:
+ if not pq.read_schema(part).equals(schemas.INTERFACE_SCORE_SHARD_SCHEMA):
+ raise ValueError(f"unexpected interface repair schema: {part}")
+ if plan.get("repair_mode") == "selected_queries":
+ output = data_dir / INTERFACE_SCORE_ROOT_RELATIVE / f"shard={shard}.parquet"
+ if not output.is_file():
+ raise ValueError(
+ f"selected-query repair requires existing score shard: {output}"
+ )
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{local_root.as_posix()}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.register(
+ "repaired_queries",
+ pd.DataFrame({"entry_pdb_id": sorted(expected_entries)}),
+ )
+ part_paths_sql = ", ".join(f"'{path.as_posix()}'" for path in part_paths)
+ source_sql = dedent(
+ f"""
+ WITH combined AS (
+ SELECT scores.*
+ FROM read_parquet('{output.as_posix()}') AS scores
+ ANTI JOIN repaired_queries
+ ON split_part(scores.query_system, '__', 1)
+ = repaired_queries.entry_pdb_id
+ UNION ALL BY NAME
+ SELECT * FROM read_parquet([{part_paths_sql}])
+ )
+ SELECT
+ query_system::VARCHAR AS query_system,
+ target_system::VARCHAR AS target_system,
+ mapping::VARCHAR AS mapping,
+ source::VARCHAR AS source,
+ metric::VARCHAR AS metric,
+ iface1_qcov::FLOAT AS iface1_qcov,
+ iface2_qcov::FLOAT AS iface2_qcov,
+ similarity::TINYINT AS similarity
+ FROM combined
+ """
+ )
+ connection.execute(
+ dedent(
+ f"""
+ COPY ({source_sql}) TO '{local_output.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ )
+ connection.close()
+ else:
+ writer = pq.ParquetWriter(
+ local_output,
+ schemas.INTERFACE_SCORE_SHARD_SCHEMA,
+ compression="zstd",
+ )
+ try:
+ for part in part_paths:
+ source = pq.ParquetFile(part)
+ for batch in source.iter_batches(batch_size=500_000):
+ writer.write_batch(batch)
+ finally:
+ writer.close()
+ if not pq.read_schema(local_output).equals(
+ schemas.INTERFACE_SCORE_SHARD_SCHEMA
+ ):
+ local_output.unlink(missing_ok=True)
+ raise ValueError(
+ f"repaired interface shard has unexpected schema: {local_output}"
+ )
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{local_root.as_posix()}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ duplicate_result = connection.sql(
+ dedent(
+ f"""
+ SELECT count(*)
+ FROM (
+ SELECT metric, query_system, target_system
+ FROM read_parquet('{local_output.as_posix()}')
+ GROUP BY metric, query_system, target_system
+ HAVING count(*) > 1
+ )
+ """
+ )
+ ).fetchone()
+ duplicate_rows = int(duplicate_result[0]) if duplicate_result is not None else 0
+ connection.close()
+ if duplicate_rows:
+ local_output.unlink(missing_ok=True)
+ raise ValueError(
+ f"interface repair shard {shard} has {duplicate_rows} duplicate pairs"
+ )
+
+ output = data_dir / INTERFACE_SCORE_ROOT_RELATIVE / f"shard={shard}.parquet"
+ install = output.with_suffix(output.suffix + ".tmp")
+ copyfile(local_output, install)
+ install.replace(output)
+ rows = int(pq.ParquetFile(output).metadata.num_rows)
+ payload = {
+ "status": "complete",
+ "shard": shard,
+ "inputs": _interface_score_inputs(data_dir, shard),
+ "output": _source_signature(output),
+ "rows": rows,
+ }
+ write_json_atomic(output.with_suffix(".json"), payload)
+ reports.append(payload)
+ LOG.info(
+ "interface repair finalization: shards=%d/%d shard=%s entries=%d rows=%d",
+ len(reports),
+ int(plan["shard_count"]),
+ shard,
+ len(expected_entries),
+ rows,
+ )
+ return {
+ "status": "complete",
+ "shard_count": len(reports),
+ "row_count": sum(int(report["rows"]) for report in reports),
+ }
+
+
+def _sort_interface_export(
+ source: Path, output: Path, *, columns: tuple[str, ...]
+) -> None:
+ """Sort bounded row-group batches to keep repeated query IDs together."""
+ parquet = pq.ParquetFile(source)
+ rows = 0
+ with pq.ParquetWriter(
+ output, parquet.schema_arrow, compression="zstd", compression_level=9
+ ) as writer:
+ for start in range(0, parquet.num_row_groups, 32):
+ block = parquet.read_row_groups(
+ range(start, min(start + 32, parquet.num_row_groups))
+ )
+ order = pc.sort_indices(
+ block,
+ sort_keys=[(column, "ascending") for column in columns],
+ )
+ writer.write_table(block.take(order), row_group_size=500_000)
+ rows += len(block)
+ if pq.ParquetFile(output).metadata.num_rows != rows:
+ raise ValueError("sorted interface export has the wrong row count")
+
+
+def _finalize_interface_half_similarity_scores(
+ data_dir: Path,
+ *,
+ sources: list[dict[str, Any]],
+ full_rows: int,
+ scratch_dir: Path,
+ threads: int,
+ memory_limit: str,
+) -> dict[str, Any]:
+ """Keep the directed chain-side scores without the raw scoring payload."""
+ output = data_dir / INTERFACE_HALF_SIMILARITY_EXPORT_RELATIVE
+ manifest = output.with_suffix(output.suffix + ".json")
+ plan_signature = _source_signature(data_dir / INTERFACE_SCORE_PLAN_RELATIVE)
+ expected_rows = sum(int(source["rows"]) for source in sources) - full_rows
+ if output.is_file() and manifest.is_file():
+ try:
+ current = cast(dict[str, Any], json.loads(manifest.read_text()))
+ if (
+ current.get("interface_plan") == plan_signature
+ and current.get("sources") == sources
+ and current.get("ordering") == "query_target_similarity"
+ and current.get("output") == _source_signature(output)
+ and current.get("row_count") == expected_rows
+ and pq.read_schema(output).equals(
+ schemas.INTERFACE_HALF_SIMILARITY_EXPORT_SCHEMA
+ )
+ ):
+ return current
+ except (OSError, TypeError, ValueError):
+ pass
+
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ output.parent.mkdir(exist_ok=True, parents=True)
+ local_output = output.with_suffix(output.suffix + ".tmp")
+ local_output.unlink(missing_ok=True)
+ if sources:
+ import duckdb
+
+ paths = [
+ data_dir
+ / INTERFACE_SCORE_ROOT_RELATIVE
+ / f"shard={source['shard']}.parquet"
+ for source in sources
+ ]
+ paths_sql = ", ".join(f"'{path.as_posix()}'" for path in paths)
+ with duckdb.connect() as connection:
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql("SET preserve_insertion_order=false")
+ connection.sql(
+ dedent(
+ f"""
+ COPY (
+ SELECT
+ query_system AS query_half_interface_id,
+ target_system AS target_half_interface_id,
+ similarity
+ FROM read_parquet([{paths_sql}])
+ WHERE metric = 'interface_side_qcov'
+ ) TO '{local_output.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ )
+ else:
+ pq.write_table(
+ pa.Table.from_pylist(
+ [], schema=schemas.INTERFACE_HALF_SIMILARITY_EXPORT_SCHEMA
+ ),
+ local_output,
+ compression="zstd",
+ )
+ if sources:
+ sorted_output = output.with_suffix(output.suffix + ".sorted.tmp")
+ sorted_output.unlink(missing_ok=True)
+ try:
+ _sort_interface_export(
+ local_output,
+ sorted_output,
+ columns=(
+ "query_half_interface_id",
+ "target_half_interface_id",
+ "similarity",
+ ),
+ )
+ sorted_output.replace(local_output)
+ finally:
+ sorted_output.unlink(missing_ok=True)
+ rows = pq.ParquetFile(local_output).metadata.num_rows
+ if rows != expected_rows or not pq.read_schema(local_output).equals(
+ schemas.INTERFACE_HALF_SIMILARITY_EXPORT_SCHEMA
+ ):
+ local_output.unlink(missing_ok=True)
+ raise ValueError(
+ "compact half-interface scores do not cover the scored side rows: "
+ f"{rows}/{expected_rows}"
+ )
+ local_output.replace(output)
+ report = {
+ "status": "complete",
+ "metric": "interface_side_qcov",
+ "direction": "query_half_interface_id_to_target_half_interface_id",
+ "ordering": "query_target_similarity",
+ "interface_plan": plan_signature,
+ "sources": sources,
+ "row_count": rows,
+ "output": _source_signature(output),
+ }
+ write_json_atomic(manifest, report)
+ return report
+
+
+def finalize_interface_half_similarity_scores(
+ data_dir: Path,
+ *,
+ scratch_dir: Path,
+ threads: int = 8,
+ memory_limit: str = "32GB",
+) -> dict[str, Any]:
+ """Build the side table from a validated, unchanged whole-interface export."""
+ output = data_dir / INTERFACE_SIMILARITY_EXPORT_RELATIVE
+ manifest = output.with_suffix(output.suffix + ".json")
+ full = cast(dict[str, Any], json.loads(manifest.read_text()))
+ if (
+ full.get("status") != "complete"
+ or full.get("interface_plan")
+ != _source_signature(data_dir / INTERFACE_SCORE_PLAN_RELATIVE)
+ or full.get("output") != _source_signature(output)
+ or not pq.read_schema(output).equals(schemas.INTERFACE_SIMILARITY_EXPORT_SCHEMA)
+ or pq.ParquetFile(output).metadata.num_rows != full.get("row_count")
+ ):
+ raise ValueError("whole-interface export is not a current reference")
+
+ sources = cast(list[dict[str, Any]], full["sources"])
+ expected_shards = (
+ pd.read_parquet(data_dir / INTERFACE_SCORE_WORK_RELATIVE, columns=["shard"])[
+ "shard"
+ ]
+ .astype(str)
+ .tolist()
+ )
+ if [source["shard"] for source in sources] != expected_shards:
+ raise ValueError("whole-interface export does not cover planned score shards")
+ for source in sources:
+ path = (
+ data_dir
+ / INTERFACE_SCORE_ROOT_RELATIVE
+ / f"shard={source['shard']}.parquet"
+ )
+ if (
+ _source_signature(path)
+ != {key: source[key] for key in ("path", "size", "mtime_ns")}
+ or not pq.read_schema(path).equals(schemas.INTERFACE_SCORE_SHARD_SCHEMA)
+ or pq.ParquetFile(path).metadata.num_rows != source["rows"]
+ ):
+ raise ValueError(f"interface score shard changed after export: {path}")
+ return _finalize_interface_half_similarity_scores(
+ data_dir,
+ sources=sources,
+ full_rows=int(full["row_count"]),
+ scratch_dir=scratch_dir,
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+
+
+def finalize_interface_similarity_scores(
+ data_dir: Path,
+ *,
+ output: Path | None = None,
+ scratch_dir: Path,
+ threads: int = 8,
+ memory_limit: str = "32GB",
+) -> dict[str, Any]:
+ """Validate interface score shards and publish the compact release table."""
+ if threads < 1:
+ raise ValueError("interface score finalization threads must be positive")
+ plan = _load_interface_score_plan(data_dir)
+ output = (output or data_dir / INTERFACE_SIMILARITY_EXPORT_RELATIVE).resolve()
+ score_root = data_dir / INTERFACE_SCORE_ROOT_RELATIVE
+ expected_shards = (
+ pd.read_parquet(
+ data_dir / INTERFACE_SCORE_WORK_RELATIVE,
+ columns=["shard"],
+ )["shard"]
+ .astype(str)
+ .tolist()
+ )
+ observed_paths = sorted(score_root.glob("shard=*.parquet"))
+ observed_shards = [path.stem.removeprefix("shard=") for path in observed_paths]
+ if observed_shards != expected_shards:
+ raise ValueError(
+ "interface score shards are incomplete: "
+ f"missing={sorted(set(expected_shards) - set(observed_shards))[:10]}, "
+ f"extra={sorted(set(observed_shards) - set(expected_shards))[:10]}"
+ )
+
+ sources: list[dict[str, Any]] = []
+ for index, (shard, path) in enumerate(
+ zip(expected_shards, observed_paths), start=1
+ ):
+ manifest = path.with_suffix(".json")
+ inputs = _interface_score_inputs(data_dir, shard)
+ payload = _interface_score_output_is_current(
+ output=path,
+ manifest=manifest,
+ inputs=inputs,
+ )
+ if payload is None or payload.get("shard") != shard:
+ raise ValueError(f"stale interface score shard: {path}")
+ sources.append(
+ {
+ "shard": shard,
+ **_source_signature(path),
+ "rows": int(payload["rows"]),
+ }
+ )
+ if index % 100 == 0 or index == len(observed_paths):
+ LOG.info(
+ "interface score finalization validation: shards=%d/%d",
+ index,
+ len(observed_paths),
+ )
+
+ release_manifest = output.with_suffix(output.suffix + ".json")
+ if output.is_file() and release_manifest.is_file():
+ try:
+ current = cast(dict[str, Any], json.loads(release_manifest.read_text()))
+ if (
+ current.get("interface_plan")
+ == _source_signature(data_dir / INTERFACE_SCORE_PLAN_RELATIVE)
+ and current.get("sources") == sources
+ and current.get("ordering") == "query_target_similarity"
+ and current.get("output") == _source_signature(output)
+ and pq.read_schema(output).equals(
+ schemas.INTERFACE_SIMILARITY_EXPORT_SCHEMA
+ )
+ ):
+ half = _finalize_interface_half_similarity_scores(
+ data_dir,
+ sources=sources,
+ full_rows=int(current["row_count"]),
+ scratch_dir=scratch_dir,
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ return {**current, "half_row_count": half["row_count"]}
+ except (OSError, TypeError, ValueError):
+ pass
+
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ local_output = scratch_dir / output.name
+ local_output.unlink(missing_ok=True)
+ if observed_paths:
+ import duckdb
+
+ paths_sql = ", ".join(f"'{path.as_posix()}'" for path in observed_paths)
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql("SET preserve_insertion_order=false")
+ result = connection.sql(
+ dedent(
+ f"""
+ SELECT
+ count(*)::BIGINT AS total_rows,
+ count(*) FILTER (
+ WHERE metric = 'interface_qcov'
+ )::BIGINT AS interface_rows,
+ count(*) FILTER (
+ WHERE query_system = target_system
+ )::BIGINT AS self_rows
+ FROM read_parquet([{paths_sql}])
+ """
+ )
+ ).fetchone()
+ if result is None:
+ connection.close()
+ raise RuntimeError("failed to validate interface score shards")
+ total_rows, rows, self_rows = (int(value) for value in result)
+ expected_rows = sum(int(source["rows"]) for source in sources)
+ if total_rows != expected_rows or self_rows:
+ connection.close()
+ raise ValueError(
+ "invalid interface score rows: "
+ f"rows={total_rows}/{expected_rows}, self_rows={self_rows}"
+ )
+ connection.sql(
+ dedent(
+ f"""
+ COPY (
+ SELECT
+ query_system,
+ target_system,
+ iface1_qcov,
+ iface2_qcov,
+ similarity
+ FROM read_parquet([{paths_sql}])
+ WHERE metric = 'interface_qcov'
+ ) TO '{local_output.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ )
+ connection.close()
+ else:
+ rows = 0
+ pq.write_table(
+ pa.Table.from_pylist([], schema=schemas.INTERFACE_SIMILARITY_EXPORT_SCHEMA),
+ local_output,
+ compression="zstd",
+ )
+ if not pq.read_schema(local_output).equals(
+ schemas.INTERFACE_SIMILARITY_EXPORT_SCHEMA
+ ):
+ local_output.unlink(missing_ok=True)
+ raise ValueError("compact interface score export has an unexpected schema")
+ if pq.ParquetFile(local_output).metadata.num_rows != rows:
+ local_output.unlink(missing_ok=True)
+ raise ValueError("compact interface score export row count changed")
+ if observed_paths:
+ sorted_output = scratch_dir / f"{output.name}.sorted.tmp"
+ sorted_output.unlink(missing_ok=True)
+ try:
+ _sort_interface_export(
+ local_output,
+ sorted_output,
+ columns=("query_system", "target_system", "similarity"),
+ )
+ sorted_output.replace(local_output)
+ finally:
+ sorted_output.unlink(missing_ok=True)
+ output.parent.mkdir(exist_ok=True, parents=True)
+ install = output.with_suffix(output.suffix + ".tmp")
+ copyfile(local_output, install)
+ install.replace(output)
+ local_output.unlink(missing_ok=True)
+ report = {
+ "status": "complete",
+ "metric": "interface_qcov",
+ "direction": "query_system_to_target_system",
+ "ordering": "query_target_similarity",
+ "interface_plan": _source_signature(data_dir / INTERFACE_SCORE_PLAN_RELATIVE),
+ "sources": sources,
+ "shard_count": len(sources),
+ "row_count": rows,
+ "query_interface_count": int(plan["query_interface_count"]),
+ "target_interface_count": int(plan["target_interface_count"]),
+ "output": _source_signature(output),
+ }
+ write_json_atomic(release_manifest, report)
+ half = _finalize_interface_half_similarity_scores(
+ data_dir,
+ sources=sources,
+ full_rows=rows,
+ scratch_dir=scratch_dir,
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ return {**report, "half_row_count": half["row_count"]}
+
+
+def export_ligand_similarity_scores_batch(
+ data_dir: Path,
+ *,
+ output_dir: Path,
+ batch_index: int | None = None,
+ batch_size: int | None = None,
+ shards: list[str] | None = None,
+ scratch_dir: Path,
+ threads: int = 4,
+ memory_limit: str = "16GB",
+) -> dict[str, Any]:
+ """Export complete ligand-pair scores as resumable query shards."""
+ if threads < 1:
+ raise ValueError("export threads must be positive")
+ if shards is None:
+ if batch_index is None or batch_size is None:
+ raise ValueError(
+ "batch index and size are required when shards are omitted"
+ )
+ shards = _ligand_3d_shard_batch(data_dir, batch_index, batch_size)
+ elif batch_index is not None or batch_size is not None:
+ raise ValueError("pass explicit shards or a batch index and size, not both")
+ output_dir = output_dir.resolve()
+ output_dir.mkdir(exist_ok=True, parents=True)
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ import duckdb
+
+ pair_keys = ", ".join(
+ [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ )
+ expected_schema = schemas.LIGAND_SIMILARITY_EXPORT_SCHEMA
+ reports: list[dict[str, Any]] = []
+ exported_rows = 0
+ started = perf_counter()
+ for index, shard in enumerate(shards, start=1):
+ pair_path = (
+ data_dir / "scores" / "ligand_pair_score_shards" / f"shard={shard}.parquet"
+ )
+ shape_path = data_dir / "scores" / "ligand_3d_by_query" / f"{shard}.parquet"
+ if not pair_path.is_file() or not shape_path.is_file():
+ raise FileNotFoundError(
+ f"missing ligand similarity input for shard {shard}: "
+ f"pairs={pair_path.is_file()} shape={shape_path.is_file()}"
+ )
+ inputs = {
+ "pairs": _source_signature(pair_path),
+ "shape": _source_signature(shape_path),
+ }
+ output = output_dir / f"{shard}.parquet"
+ manifest = output.with_suffix(".json")
+ if output.is_file() and manifest.is_file():
+ try:
+ payload = json.loads(manifest.read_text())
+ stored_inputs = payload.get("inputs")
+ if (
+ isinstance(stored_inputs, dict)
+ and all(
+ _same_file_signature(stored_inputs.get(name), signature)
+ for name, signature in inputs.items()
+ )
+ and _same_file_signature(
+ payload.get("output"), _source_signature(output)
+ )
+ and pq.read_schema(output).equals(expected_schema)
+ ):
+ if payload.get("inputs") != inputs or payload.get(
+ "output"
+ ) != _source_signature(output):
+ payload["inputs"] = inputs
+ payload["output"] = _source_signature(output)
+ write_json_atomic(manifest, payload)
+ reports.append(payload)
+ exported_rows += int(payload["rows"])
+ LOG.info(
+ "ligand similarity export progress: "
+ f"shards={index}/{len(shards)} rows={exported_rows} "
+ f"elapsed_seconds={perf_counter() - started:.1f} cached=true"
+ )
+ continue
+ except (OSError, TypeError, ValueError):
+ pass
+
+ local_output = scratch_dir / output.name
+ local_output.unlink(missing_ok=True)
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql("SET preserve_insertion_order=false")
+ duplicate = connection.sql(
+ f"""
+ SELECT query_system, query_ligand_id, target_system, target_ligand_id
+ FROM read_parquet('{pair_path.as_posix()}')
+ GROUP BY ALL
+ HAVING count(*) > 1
+ LIMIT 1
+ """
+ ).fetchone()
+ if duplicate is not None:
+ connection.close()
+ raise ValueError(
+ f"ligand pair score shard contains duplicate public keys: {shard}"
+ )
+ connection.sql(
+ f"""
+ COPY (
+ SELECT
+ pairs.query_system,
+ pairs.query_ligand_id,
+ pairs.target_system,
+ pairs.target_ligand_id,
+ pairs.pocket_qcov,
+ pairs.pocket_fident_qcov,
+ pairs.pli_qcov,
+ round(shape.shape * 100)::TINYINT AS shape,
+ round(shape.color * 100)::TINYINT AS color,
+ round(shape.sucos_shape * 100)::TINYINT AS sucos_shape
+ FROM read_parquet('{pair_path.as_posix()}') AS pairs
+ LEFT JOIN read_parquet('{shape_path.as_posix()}') AS shape
+ USING ({pair_keys})
+ ) TO '{local_output.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ connection.close()
+ if not pq.read_schema(local_output).equals(expected_schema):
+ local_output.unlink(missing_ok=True)
+ raise ValueError(
+ f"ligand similarity export shard has an unexpected schema: {shard}"
+ )
+ expected_rows = pq.ParquetFile(pair_path).metadata.num_rows
+ actual_rows = pq.ParquetFile(local_output).metadata.num_rows
+ if actual_rows != expected_rows:
+ local_output.unlink(missing_ok=True)
+ raise ValueError(
+ "ligand shape join changed the number of pair rows for shard "
+ f"{shard}: {actual_rows} != {expected_rows}"
+ )
+ install = output.with_suffix(output.suffix + ".tmp")
+ copyfile(local_output, install)
+ install.replace(output)
+ local_output.unlink(missing_ok=True)
+ metadata = pq.ParquetFile(output).metadata
+ payload = {
+ "status": "complete",
+ "shard": shard,
+ "inputs": inputs,
+ "output": _source_signature(output),
+ "rows": int(metadata.num_rows),
+ }
+ write_json_atomic(manifest, payload)
+ reports.append(payload)
+ exported_rows += int(payload["rows"])
+ elapsed = perf_counter() - started
+ LOG.info(
+ "ligand similarity export progress: "
+ f"shards={index}/{len(shards)} rows={exported_rows} "
+ f"elapsed_seconds={elapsed:.1f}"
+ )
+ return {
+ "status": "complete",
+ "selected_count": len(shards),
+ "row_count": exported_rows,
+ "outputs": [str(output_dir / f"{shard}.parquet") for shard in shards],
+ }
+
+
+def finalize_ligand_similarity_scores(
+ data_dir: Path,
+ *,
+ source_dir: Path,
+ output: Path,
+ scratch_dir: Path,
+ threads: int = 8,
+ memory_limit: str = "32GB",
+) -> dict[str, Any]:
+ """Validate ligand similarity shards and publish one release Parquet."""
+ if threads < 1:
+ raise ValueError("export threads must be positive")
+ source_dir = source_dir.resolve()
+ output = output.resolve()
+ if output.parent == source_dir or output.is_relative_to(source_dir):
+ raise ValueError(
+ "final ligand similarity table must be outside its shard directory"
+ )
+ expected_shards = sorted(
+ {pdb_id[1:3] for pdb_id in published_scoring_query_ids(data_dir)}
+ )
+ paths = sorted(source_dir.glob("*.parquet"))
+ observed_shards = [path.stem for path in paths]
+ if observed_shards != expected_shards:
+ raise ValueError(
+ "ligand similarity shards are incomplete: "
+ f"missing={sorted(set(expected_shards) - set(observed_shards))[:10]}, "
+ f"extra={sorted(set(observed_shards) - set(expected_shards))[:10]}"
+ )
+
+ sources: list[dict[str, Any]] = []
+ for index, path in enumerate(paths, start=1):
+ manifest = path.with_suffix(".json")
+ try:
+ payload = json.loads(manifest.read_text())
+ except (OSError, TypeError, ValueError) as exc:
+ raise ValueError(f"invalid ligand similarity manifest: {manifest}") from exc
+ shard = path.stem
+ pair_path = (
+ data_dir / "scores" / "ligand_pair_score_shards" / f"shard={shard}.parquet"
+ )
+ shape_path = data_dir / "scores" / "ligand_3d_by_query" / f"{shard}.parquet"
+ expected_inputs = {
+ "pairs": _source_signature(pair_path),
+ "shape": _source_signature(shape_path),
+ }
+ if (
+ payload.get("shard") != shard
+ or payload.get("inputs") != expected_inputs
+ or payload.get("output") != _source_signature(path)
+ ):
+ raise ValueError(f"stale ligand similarity shard: {path}")
+ if not pq.read_schema(path).equals(schemas.LIGAND_SIMILARITY_EXPORT_SCHEMA):
+ raise ValueError(f"invalid ligand similarity shard schema: {path}")
+ sources.append(
+ {
+ "shard": shard,
+ **_source_signature(path),
+ "rows": int(payload["rows"]),
+ }
+ )
+ if index % 100 == 0 or index == len(paths):
+ LOG.info(
+ "ligand similarity finalization validation progress: "
+ f"shards={index}/{len(paths)}"
+ )
+
+ annotation_path = data_dir / "index/annotation_table.parquet"
+ if not annotation_path.is_file():
+ raise FileNotFoundError(annotation_path)
+ annotation_signature = _source_signature(annotation_path)
+
+ release_manifest = output.with_suffix(output.suffix + ".json")
+ if output.is_file() and release_manifest.is_file():
+ try:
+ existing = cast(dict[str, Any], json.loads(release_manifest.read_text()))
+ if (
+ existing.get("sources") == sources
+ and existing.get("annotation") == annotation_signature
+ and existing.get("output") == _source_signature(output)
+ ):
+ return existing
+ except (OSError, TypeError, ValueError):
+ pass
+
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ local_output = scratch_dir / output.name
+ local_output.unlink(missing_ok=True)
+ paths_sql = ", ".join(f"'{path.as_posix()}'" for path in paths)
+ import duckdb
+
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ connection.sql(f"SET memory_limit='{memory_limit}'")
+ connection.sql("SET preserve_insertion_order=false")
+ existing_self_result = connection.sql(
+ f"""
+ SELECT count(*)
+ FROM read_parquet([{paths_sql}])
+ WHERE query_system = target_system
+ AND query_ligand_id = target_ligand_id
+ """
+ ).fetchone()
+ if existing_self_result is None:
+ connection.close()
+ raise RuntimeError("failed to count existing ligand similarity self rows")
+ existing_self_rows = int(existing_self_result[0])
+ self_result = connection.sql(
+ f"""
+ SELECT count(*)
+ FROM (
+ SELECT DISTINCT system_id, ligand_id
+ FROM read_parquet('{annotation_path.as_posix()}')
+ WHERE system_type = 'holo'
+ AND coalesce(ligand_is_proper, false)
+ )
+ """
+ ).fetchone()
+ if self_result is None:
+ connection.close()
+ raise RuntimeError("failed to count expected ligand similarity self rows")
+ self_rows = int(self_result[0])
+ LOG.info(
+ "ligand similarity finalization: concatenating "
+ f"shards={len(paths)} rows={sum(int(source['rows']) for source in sources)}"
+ )
+ connection.sql(
+ f"""
+ COPY (
+ WITH computed AS (
+ SELECT *
+ FROM read_parquet([{paths_sql}])
+ WHERE query_system != target_system
+ OR query_ligand_id != target_ligand_id
+ ), self_rows AS (
+ SELECT DISTINCT
+ system_id AS query_system,
+ ligand_id AS query_ligand_id,
+ system_id AS target_system,
+ ligand_id AS target_ligand_id,
+ 100::TINYINT AS pocket_qcov,
+ 100::TINYINT AS pocket_fident_qcov,
+ 100::TINYINT AS pli_qcov,
+ CASE
+ WHEN coalesce(ligand_is_shape_comparable, false)
+ THEN 100::TINYINT
+ ELSE NULL::TINYINT
+ END AS shape,
+ CASE
+ WHEN coalesce(ligand_is_shape_comparable, false)
+ THEN 100::TINYINT
+ ELSE NULL::TINYINT
+ END AS color,
+ CASE
+ WHEN coalesce(ligand_is_shape_comparable, false)
+ THEN 100::TINYINT
+ ELSE NULL::TINYINT
+ END AS sucos_shape
+ FROM read_parquet('{annotation_path.as_posix()}')
+ WHERE system_type = 'holo'
+ AND coalesce(ligand_is_proper, false)
+ )
+ SELECT * FROM computed
+ UNION ALL
+ SELECT * FROM self_rows
+ ) TO '{local_output.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ connection.close()
+ metadata = pq.ParquetFile(local_output).metadata
+ expected_rows = (
+ sum(int(source["rows"]) for source in sources) - existing_self_rows + self_rows
+ )
+ if metadata.num_rows != expected_rows:
+ local_output.unlink(missing_ok=True)
+ raise ValueError(
+ "final ligand similarity table has "
+ f"{metadata.num_rows} rows; expected {expected_rows}"
+ )
+ if not pq.read_schema(local_output).equals(schemas.LIGAND_SIMILARITY_EXPORT_SCHEMA):
+ local_output.unlink(missing_ok=True)
+ raise ValueError("final ligand similarity table has an unexpected schema")
+ output.parent.mkdir(exist_ok=True, parents=True)
+ install = output.with_suffix(output.suffix + ".tmp")
+ copyfile(local_output, install)
+ install.replace(output)
+ local_output.unlink(missing_ok=True)
+ report = {
+ "status": "complete",
+ "metrics": [
+ "pocket_qcov",
+ "pocket_fident_qcov",
+ "pli_qcov",
+ "shape",
+ "color",
+ "sucos_shape",
+ ],
+ "sources": sources,
+ "annotation": annotation_signature,
+ "self_row_count": self_rows,
+ "row_count": expected_rows,
+ "output": _source_signature(output),
+ }
+ write_json_atomic(release_manifest, report)
+ return report
+
+
+def _add_cluster_entity_argument(command: argparse.ArgumentParser) -> None:
+ command.add_argument(
+ "--entity-type",
+ choices=["ligand", "interface"],
+ default="ligand",
+ )
+
+
+def _add_cluster_arguments(command: argparse.ArgumentParser) -> None:
+ _add_cluster_entity_argument(command)
+ command.add_argument(
+ "--metric",
+ action="append",
+ dest="metrics",
+ help="cluster only this metric; repeat to select multiple metrics",
+ )
+ command.add_argument(
+ "--threshold",
+ action="append",
+ type=int,
+ dest="thresholds",
+ help="cluster at this 0-100 threshold; repeat to select multiple values",
+ )
+
+
+def _parser() -> argparse.ArgumentParser:
+ parser = argparse.ArgumentParser(description=__doc__)
+ subparsers = parser.add_subparsers(dest="command", required=True)
+ plan = subparsers.add_parser("plan")
+ plan.add_argument("data_dir", type=Path)
+ plan.add_argument("--max-seqs", type=int, default=10_000)
+ plan.add_argument("--pdb-id", action="append", default=[])
+ plan.add_argument("--two-char-code", action="append", default=[])
+ apo_plan = subparsers.add_parser("plan-linked-apo")
+ apo_plan.add_argument("data_dir", type=Path)
+ apo_plan.add_argument("--max-seqs", type=int, default=10_000)
+ apo_plan.add_argument("--pdb-id", action="append", default=[])
+ apo_plan.add_argument("--two-char-code", action="append", default=[])
+
+ databases = subparsers.add_parser("create-dbs")
+ databases.add_argument("data_dir", type=Path)
+ databases.add_argument("--cif-root", type=Path, required=True)
+ databases.add_argument("--seqres-path", type=Path, required=True)
+ databases.add_argument("--threads", type=int, default=1)
+ databases.add_argument("--scratch-dir", type=Path)
+ databases.add_argument("--force", action="store_true")
+
+ sub_dbs = subparsers.add_parser("make-sub-dbs")
+ sub_dbs.add_argument("data_dir", type=Path)
+ sub_dbs.add_argument("--threads", type=int, default=1)
+ sub_dbs.add_argument("--scratch-dir", type=Path, required=True)
+ sub_dbs.add_argument(
+ "--search-db",
+ action="append",
+ dest="search_dbs",
+ choices=["holo", "apo", "pred"],
+ help="database subset to build; repeat to build more than one",
+ )
+ scoring_inputs = subparsers.add_parser(
+ "prepare-scoring-inputs",
+ help="build pocket/interface representatives and chain mappings from entry tables",
+ )
+ scoring_inputs.add_argument("data_dir", type=Path)
+ scoring_inputs.add_argument("--threads", type=int, default=4)
+ scoring_inputs.add_argument("--memory-limit", default="8GB")
+ scoring_inputs.add_argument("--scratch-dir", type=Path)
+ scoring_inputs.add_argument("--force", action="store_true")
+
+ lookup_refresh = subparsers.add_parser("refresh-alignment-lookup")
+ lookup_refresh.add_argument("data_dir", type=Path)
+ lookup_refresh.add_argument("--threads", type=int, default=1)
+ lookup_refresh.add_argument("--scratch-dir", type=Path, required=True)
+
+ score_plan = subparsers.add_parser("plan-score-batches")
+ score_plan.add_argument("data_dir", type=Path)
+ score_plan.add_argument("--batch-size", type=int, default=50)
+ score_plan.add_argument("--threads", type=int, default=4)
+ score_plan.add_argument("--scratch-dir", type=Path, required=True)
+ score_plan.add_argument("--max-query-protein-chains", type=int, default=30)
+ score_plan.add_argument("--max-query-proper-ligand-chains", type=int, default=30)
+ score_plan.add_argument("--reuse-mapped-alignments", action="store_true")
+
+ ligand_3d_plan = subparsers.add_parser("plan-ligand-3d")
+ ligand_3d_plan.add_argument("data_dir", type=Path)
+ ligand_3d_plan.add_argument("--batch-size", type=int, default=30_000)
+ ligand_3d_plan.add_argument("--threads", type=int, default=4)
+ ligand_3d_plan.add_argument("--scratch-dir", type=Path, required=True)
+ ligand_3d_plan.add_argument("--memory-limit", default="8GB")
+
+ ligand_3d_retry_plan = subparsers.add_parser("plan-ligand-3d-retries")
+ ligand_3d_retry_plan.add_argument("data_dir", type=Path)
+ ligand_3d_retry_plan.add_argument("--batch-size", type=int, default=500)
+ interface_plan = subparsers.add_parser("plan-interface-scores")
+ interface_plan.add_argument("data_dir", type=Path)
+ interface_plan.add_argument("--batch-size", type=int, default=1)
+ interface_repair_plan = subparsers.add_parser("plan-interface-score-repair")
+ interface_repair_plan.add_argument("data_dir", type=Path)
+ interface_repair_plan.add_argument("--batch-size", type=int, default=25)
+ interface_repair_plan.add_argument("--query-manifest", type=Path)
+ ligand_pocket_plan = subparsers.add_parser("plan-ligand-pocket-scores")
+ ligand_pocket_plan.add_argument("data_dir", type=Path)
+ ligand_pocket_plan.add_argument("--threads", type=int, default=4)
+ ligand_pocket_plan.add_argument("--scratch-dir", type=Path, required=True)
+ ligand_pocket_plan.add_argument("--memory-limit", default="32GB")
+ ligand_pocket_plan.add_argument("--max-query-protein-chains", type=int, default=30)
+ ligand_pocket_plan.add_argument(
+ "--max-query-proper-ligand-chains", type=int, default=30
+ )
+ repair_plan = subparsers.add_parser("plan-score-repair")
+ repair_plan.add_argument("data_dir", type=Path)
+ repair_plan.add_argument("--affected-manifest", type=Path, required=True)
+ repair_plan.add_argument("--additional-full-query-manifest", type=Path)
+ repair_plan.add_argument("--output", type=Path)
+ repair_plan.add_argument("--batch-size", type=int, default=10)
+ repair_plan.add_argument("--target-batch-size", type=int, default=100)
+ repair_plan.add_argument("--threads", type=int, default=4)
+ repair_plan.add_argument("--scratch-dir", type=Path)
+ repair_plan.add_argument("--memory-limit", default="32GB")
+ bounded_repair_plan = subparsers.add_parser("plan-bounded-score-repair")
+ bounded_repair_plan.add_argument("data_dir", type=Path)
+ bounded_repair_plan.add_argument("--pdb-manifest", type=Path, required=True)
+ bounded_repair_plan.add_argument("--batch-size", type=int, default=10)
+ bounded_repair_plan.add_argument("--threads", type=int, default=4)
+ bounded_repair_plan.add_argument("--scratch-dir", type=Path)
+ bounded_repair_plan.add_argument("--memory-limit", default="32GB")
+ repair_ligand_plan = subparsers.add_parser("plan-score-repair-ligand-3d")
+ repair_ligand_plan.add_argument("data_dir", type=Path)
+ repair_ligand_plan.add_argument("--repair-manifest", type=Path, required=True)
+ repair_ligand_plan.add_argument("--batch-size", type=int, default=30_000)
+ repair_ligand_plan.add_argument("--threads", type=int, default=4)
+ repair_ligand_plan.add_argument("--scratch-dir", type=Path, required=True)
+ repair_ligand_plan.add_argument("--memory-limit", default="8GB")
+ repair_finalizer = subparsers.add_parser("finalize-score-repair-queries")
+ repair_finalizer.add_argument("data_dir", type=Path)
+ repair_finalizer.add_argument("--repair-manifest", type=Path, required=True)
+ repair_finalizer.add_argument("--max-new-drops", type=int, required=True)
+ cluster_plan = subparsers.add_parser("plan-clusters")
+ cluster_plan.add_argument("data_dir", type=Path)
+ cluster_plan.add_argument("--source-batch-size", type=int, default=20)
+ cluster_plan.add_argument("--cover-batch-size", type=int, default=1)
+ cluster_plan.add_argument(
+ "--symmetric-bucket-count",
+ type=int,
+ default=clusters.SYMMETRIC_EDGE_BUCKET_COUNT,
+ )
+ _add_cluster_arguments(cluster_plan)
+
+ cluster_stats = subparsers.add_parser("cluster-stats")
+ cluster_stats.add_argument("data_dir", type=Path)
+ _add_cluster_arguments(cluster_stats)
+ index_finalizer = subparsers.add_parser("finalize-index")
+ index_finalizer.add_argument("data_dir", type=Path)
+ dropped_queries = subparsers.add_parser("drop-score-queries")
+ dropped_queries.add_argument("data_dir", type=Path)
+ dropped_queries.add_argument("--pdb-manifest", type=Path, required=True)
+
+ for name in [
+ "search",
+ "map",
+ "pack-ligands",
+ "score",
+ "score-pdbs",
+ "repair-score-pdbs",
+ "repair-score-target-remainders",
+ "repair-pack-ligands",
+ "repair-candidates",
+ "repair-ligand-3d",
+ "repair-merge-ligand-3d",
+ "repair-score-shards",
+ "repair-ligand-similarity-shards",
+ "collate-ligand-3d-candidates",
+ "score-ligand-3d",
+ "score-ligand-3d-retry",
+ "collate-ligand-3d",
+ "merge-ligand-3d",
+ "export-ligand-similarity-shards",
+ "score-ligand-pocket-shards",
+ "materialize-ligand-3d-candidates",
+ "score-interface-shards",
+ "score-interface-repair-batches",
+ "collate-alignments",
+ "collate-score-partitions",
+ "symmetric-edge-fragments",
+ "symmetric-edge-shards",
+ "component-reductions",
+ "set-covers",
+ "directed-covers",
+ ]:
+ command = subparsers.add_parser(name)
+ command.add_argument("data_dir", type=Path)
+ command.add_argument("--batch-index", type=int, required=True)
+ command.add_argument("--batch-size", type=int, required=True)
+ command.add_argument("--threads", type=int, default=1)
+ command.add_argument("--scratch-dir", type=Path, required=True)
+ command.add_argument("--force", action="store_true")
+ if name == "score-pdbs":
+ command.add_argument("--pdb-manifest", type=Path, required=True)
+ if name.startswith("repair-"):
+ command.add_argument("--repair-manifest", type=Path, required=True)
+ if name == "search":
+ command.add_argument(
+ "--alignment-type",
+ action="append",
+ choices=["foldseek", "mmseqs"],
+ required=True,
+ )
+ if name in {"search", "map", "score", "score-pdbs"}:
+ command.add_argument(
+ "--search-db",
+ choices=["holo", "apo", "pred"],
+ default="holo",
+ )
+ if name in {"component-reductions", "set-covers", "directed-covers"}:
+ _add_cluster_arguments(command)
+ elif name in {"symmetric-edge-fragments", "symmetric-edge-shards"}:
+ _add_cluster_entity_argument(command)
+ if name in {
+ "export-ligand-similarity-shards",
+ "repair-ligand-similarity-shards",
+ }:
+ command.add_argument("--output-dir", type=Path, required=True)
+ command.add_argument("--memory-limit", default="16GB")
+ if name in {
+ "score-interface-shards",
+ "score-interface-repair-batches",
+ "score-ligand-pocket-shards",
+ "materialize-ligand-3d-candidates",
+ }:
+ command.add_argument("--memory-limit", default="32GB")
+ if name in {"score-interface-shards", "score-interface-repair-batches"}:
+ command.add_argument("--side-coverage-buckets", type=int, default=32)
+ command.add_argument("--assignment-target-buckets", type=int, default=1)
+ if name == "score-interface-repair-batches":
+ command.add_argument("--repair-batches-per-task", type=int, default=1)
+ if name == "score-ligand-pocket-shards":
+ command.add_argument(
+ "--shard",
+ action="append",
+ dest="shards",
+ default=[],
+ help="score this exact shard; repeat to select multiple shards",
+ )
+
+ finalizer = subparsers.add_parser("finalize-alignments")
+ finalizer.add_argument("data_dir", type=Path)
+ ligand_finalizer = subparsers.add_parser("finalize-ligands")
+ ligand_finalizer.add_argument("data_dir", type=Path)
+ score_finalizer = subparsers.add_parser("finalize-scores")
+ score_finalizer.add_argument("data_dir", type=Path)
+ repair_score_finalizer = subparsers.add_parser("validate-score-repair")
+ repair_score_finalizer.add_argument("data_dir", type=Path)
+ repair_score_finalizer.add_argument("--repair-manifest", type=Path, required=True)
+ retry_finalizer = subparsers.add_parser("finalize-ligand-3d-retries")
+ retry_finalizer.add_argument("data_dir", type=Path)
+ ligand_similarity_finalizer = subparsers.add_parser(
+ "finalize-ligand-similarity-scores"
+ )
+ ligand_similarity_finalizer.add_argument("data_dir", type=Path)
+ ligand_similarity_finalizer.add_argument("--source-dir", type=Path, required=True)
+ ligand_similarity_finalizer.add_argument("--output", type=Path, required=True)
+ ligand_similarity_finalizer.add_argument("--scratch-dir", type=Path, required=True)
+ ligand_similarity_finalizer.add_argument("--threads", type=int, default=8)
+ ligand_similarity_finalizer.add_argument("--memory-limit", default="32GB")
+ interface_finalizer = subparsers.add_parser("finalize-interface-scores")
+ interface_finalizer.add_argument("data_dir", type=Path)
+ interface_finalizer.add_argument("--output", type=Path)
+ interface_finalizer.add_argument("--scratch-dir", type=Path, required=True)
+ interface_finalizer.add_argument("--threads", type=int, default=8)
+ interface_finalizer.add_argument("--memory-limit", default="32GB")
+ interface_half_finalizer = subparsers.add_parser("finalize-interface-half-scores")
+ interface_half_finalizer.add_argument("data_dir", type=Path)
+ interface_half_finalizer.add_argument("--scratch-dir", type=Path, required=True)
+ interface_half_finalizer.add_argument("--threads", type=int, default=8)
+ interface_half_finalizer.add_argument("--memory-limit", default="32GB")
+ interface_repair_finalizer = subparsers.add_parser(
+ "finalize-interface-score-repair"
+ )
+ interface_repair_finalizer.add_argument("data_dir", type=Path)
+ interface_repair_finalizer.add_argument("--scratch-dir", type=Path, required=True)
+ interface_repair_finalizer.add_argument("--threads", type=int, default=8)
+ interface_repair_finalizer.add_argument("--memory-limit", default="32GB")
+ component_merger = subparsers.add_parser("merge-components")
+ component_merger.add_argument("data_dir", type=Path)
+ _add_cluster_arguments(component_merger)
+ return parser
+
+
+def main() -> None:
+ args = _parser().parse_args()
+ data_dir = args.data_dir.resolve()
+ if args.command == "plan":
+ result = plan_protein_scoring(
+ data_dir,
+ pdb_ids=args.pdb_id,
+ two_char_codes=args.two_char_code,
+ max_seqs=args.max_seqs,
+ )
+ elif args.command == "plan-linked-apo":
+ result = plan_linked_apo_scoring(
+ data_dir,
+ pdb_ids=args.pdb_id,
+ two_char_codes=args.two_char_code,
+ max_seqs=args.max_seqs,
+ )
+ elif args.command == "create-dbs":
+ foldseek_input = make_foldseek_input_manifest(
+ data_dir,
+ args.cif_root.resolve(),
+ )
+ tasks.make_dbs(
+ data_dir=data_dir,
+ sub_databases=["holo"],
+ cpu=args.threads,
+ cif_root=foldseek_input,
+ seqres_path=args.seqres_path.resolve(),
+ create=True,
+ index=False,
+ force_update=args.force,
+ build_dir=(
+ args.scratch_dir.resolve() if args.scratch_dir is not None else None
+ ),
+ )
+ result = {"status": "complete"}
+ elif args.command == "make-sub-dbs":
+ tasks.make_sub_dbs(
+ data_dir=data_dir,
+ sub_databases=args.search_dbs or ["holo", "monomer"],
+ cpu=args.threads,
+ scratch_dir=args.scratch_dir.resolve(),
+ )
+ result = {"status": "complete"}
+ elif args.command == "prepare-scoring-inputs":
+ lookup = tasks.make_alignment_chain_lookup(
+ data_dir=data_dir,
+ scratch_dir=args.scratch_dir.resolve() if args.scratch_dir else None,
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ force_update=args.force,
+ )
+ result = {"status": "complete", "alignment_chain_lookup": str(lookup)}
+ elif args.command == "refresh-alignment-lookup":
+ lookup = data_dir / tasks.ALIGNMENT_CHAIN_LOOKUP_RELATIVE
+ before = _source_signature(lookup) if lookup.is_file() else None
+ tasks.make_alignment_chain_lookup(
+ data_dir=data_dir,
+ scratch_dir=args.scratch_dir.resolve(),
+ threads=args.threads,
+ force_update=True,
+ )
+ after = _source_signature(lookup)
+ if before is not None and after != before:
+ raise RuntimeError(
+ "alignment-chain lookup content changed; mapped alignment shards "
+ "must be regenerated before score repair"
+ )
+ result = {"status": "complete", "lookup_unchanged": before == after}
+ elif args.command == "plan-score-batches":
+ result = plan_score_batches(
+ data_dir,
+ batch_size=args.batch_size,
+ threads=args.threads,
+ scratch_dir=args.scratch_dir.resolve(),
+ max_query_protein_chains=args.max_query_protein_chains,
+ max_query_proper_ligand_chains=(args.max_query_proper_ligand_chains),
+ reuse_mapped_alignments=args.reuse_mapped_alignments,
+ )
+ elif args.command == "plan-ligand-3d":
+ result = plan_ligand_3d_batches(
+ data_dir,
+ batch_size=args.batch_size,
+ threads=args.threads,
+ scratch_dir=args.scratch_dir.resolve(),
+ memory_limit=args.memory_limit,
+ )
+ elif args.command == "plan-ligand-3d-retries":
+ result = plan_ligand_3d_retries(data_dir, batch_size=args.batch_size)
+ elif args.command == "plan-interface-scores":
+ result = plan_interface_scoring(data_dir, batch_size=args.batch_size)
+ elif args.command == "plan-interface-score-repair":
+ result = plan_interface_score_repair(
+ data_dir,
+ batch_size=args.batch_size,
+ query_manifest=(
+ args.query_manifest.resolve()
+ if args.query_manifest is not None
+ else None
+ ),
+ )
+ elif args.command == "plan-ligand-pocket-scores":
+ result = plan_ligand_pocket_scoring(
+ data_dir,
+ scratch_dir=args.scratch_dir.resolve(),
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ max_query_protein_chains=args.max_query_protein_chains,
+ max_query_proper_ligand_chains=(args.max_query_proper_ligand_chains),
+ )
+ elif args.command == "plan-score-repair":
+ result = plan_score_repair(
+ data_dir,
+ affected_manifest=args.affected_manifest.resolve(),
+ additional_full_query_manifest=(
+ args.additional_full_query_manifest.resolve()
+ if args.additional_full_query_manifest is not None
+ else None
+ ),
+ output_path=args.output.resolve() if args.output is not None else None,
+ batch_size=args.batch_size,
+ target_batch_size=args.target_batch_size,
+ threads=args.threads,
+ scratch_dir=(
+ args.scratch_dir.resolve() if args.scratch_dir is not None else None
+ ),
+ memory_limit=args.memory_limit,
+ )
+ elif args.command == "plan-bounded-score-repair":
+ result = plan_bounded_score_repair(
+ data_dir,
+ pdb_manifest=args.pdb_manifest.resolve(),
+ batch_size=args.batch_size,
+ threads=args.threads,
+ scratch_dir=(
+ args.scratch_dir.resolve() if args.scratch_dir is not None else None
+ ),
+ memory_limit=args.memory_limit,
+ )
+ elif args.command == "plan-score-repair-ligand-3d":
+ result = plan_score_repair_ligand_3d(
+ data_dir,
+ repair_manifest=args.repair_manifest.resolve(),
+ batch_size=args.batch_size,
+ threads=args.threads,
+ scratch_dir=args.scratch_dir.resolve(),
+ memory_limit=args.memory_limit,
+ )
+ elif args.command == "finalize-score-repair-queries":
+ result = finalize_score_repair_queries(
+ data_dir,
+ repair_manifest=args.repair_manifest.resolve(),
+ max_new_drops=args.max_new_drops,
+ )
+ elif args.command == "plan-clusters":
+ result = plan_clustering(
+ data_dir,
+ metrics=args.metrics,
+ thresholds=args.thresholds,
+ source_batch_size=args.source_batch_size,
+ cover_batch_size=args.cover_batch_size,
+ symmetric_bucket_count=args.symmetric_bucket_count,
+ entity_type=args.entity_type,
+ )
+ elif args.command == "cluster-stats":
+ result = summarize_clustering_artifacts(
+ data_dir,
+ metrics=args.metrics,
+ thresholds=args.thresholds,
+ entity_type=args.entity_type,
+ )
+ elif args.command == "finalize-index":
+ tasks.finalize_index(data_dir=data_dir)
+ result = {"status": "complete"}
+ elif args.command == "drop-score-queries":
+ result = record_dropped_queries(
+ data_dir,
+ score_query_manifest=args.pdb_manifest.resolve(),
+ )
+ elif args.command == "finalize-alignments":
+ result = finalize_alignment_artifacts(data_dir)
+ elif args.command == "finalize-ligands":
+ result = finalize_ligand_archives(data_dir)
+ elif args.command == "finalize-scores":
+ result = finalize_ligand_3d_artifacts(data_dir)
+ elif args.command == "validate-score-repair":
+ result = finalize_score_repair_artifacts(
+ data_dir,
+ repair_manifest=args.repair_manifest.resolve(),
+ )
+ elif args.command == "finalize-ligand-3d-retries":
+ result = finalize_ligand_3d_retries(data_dir)
+ elif args.command == "finalize-ligand-similarity-scores":
+ result = finalize_ligand_similarity_scores(
+ data_dir,
+ source_dir=args.source_dir,
+ output=args.output,
+ scratch_dir=args.scratch_dir.resolve(),
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ )
+ elif args.command == "finalize-interface-scores":
+ result = finalize_interface_similarity_scores(
+ data_dir,
+ output=args.output.resolve() if args.output is not None else None,
+ scratch_dir=args.scratch_dir.resolve(),
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ )
+ elif args.command == "finalize-interface-half-scores":
+ result = finalize_interface_half_similarity_scores(
+ data_dir,
+ scratch_dir=args.scratch_dir.resolve(),
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ )
+ elif args.command == "finalize-interface-score-repair":
+ result = finalize_interface_score_repair(
+ data_dir,
+ scratch_dir=args.scratch_dir.resolve(),
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ )
+ elif args.command == "score-interface-shards":
+ shards = _interface_score_shard_batch(
+ data_dir,
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ result = score_interface_qcov_shards(
+ data_dir,
+ shards=shards,
+ scratch_dir=args.scratch_dir.resolve(),
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ side_coverage_bucket_count=args.side_coverage_buckets,
+ assignment_target_bucket_count=args.assignment_target_buckets,
+ force_update=args.force,
+ )
+ elif args.command == "score-interface-repair-batches":
+ batch_indexes = _interface_score_repair_task_batches(
+ data_dir,
+ task_index=args.batch_index,
+ batches_per_task=args.repair_batches_per_task,
+ )
+ reports = []
+ for repair_index, repair_batch_index in enumerate(batch_indexes, start=1):
+ reports.append(
+ score_interface_qcov_repair_batch(
+ data_dir,
+ batch_index=repair_batch_index,
+ batch_size=args.batch_size,
+ scratch_dir=args.scratch_dir.resolve()
+ / f"batch-{repair_batch_index:05d}",
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ side_coverage_bucket_count=args.side_coverage_buckets,
+ assignment_target_bucket_count=args.assignment_target_buckets,
+ force_update=args.force,
+ )
+ )
+ LOG.info(
+ "interface repair scheduler-task progress: batches=%d/%d "
+ "batch_index=%d",
+ repair_index,
+ len(batch_indexes),
+ repair_batch_index,
+ )
+ result = {
+ "status": "complete",
+ "task_index": args.batch_index,
+ "batch_indexes": batch_indexes,
+ "row_count": sum(int(report.get("row_count", 0)) for report in reports),
+ }
+ elif args.command == "score-ligand-pocket-shards":
+ shards = args.shards or _ligand_pocket_score_shard_batch(
+ data_dir,
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ result = score_ligand_pocket_qcov_shards(
+ data_dir,
+ shards=shards,
+ scratch_dir=args.scratch_dir.resolve(),
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ force_update=args.force,
+ )
+ elif args.command == "materialize-ligand-3d-candidates":
+ shards = _ligand_pocket_score_shard_batch(
+ data_dir,
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ result = materialize_ligand_3d_pair_candidates(
+ data_dir,
+ shards=shards,
+ scratch_dir=args.scratch_dir.resolve(),
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ force_update=args.force,
+ )
+ elif args.command in {
+ "export-ligand-similarity-shards",
+ "repair-ligand-similarity-shards",
+ }:
+ explicit_shards = None
+ batch_index = args.batch_index
+ batch_size = args.batch_size
+ if args.command == "repair-ligand-similarity-shards":
+ explicit_shards = _score_repair_shard_batch(
+ args.repair_manifest.resolve(),
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ batch_index = None
+ batch_size = None
+ result = export_ligand_similarity_scores_batch(
+ data_dir,
+ output_dir=args.output_dir,
+ batch_index=batch_index,
+ batch_size=batch_size,
+ shards=explicit_shards,
+ scratch_dir=args.scratch_dir.resolve(),
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ )
+ elif args.command == "symmetric-edge-fragments":
+ batches = _symmetric_fragment_batch(
+ data_dir,
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ entity_type=args.entity_type,
+ )
+ tasks.make_symmetric_edge_fragments(
+ data_dir=data_dir,
+ batches=batches,
+ scratch_dir=args.scratch_dir.resolve(),
+ threads=args.threads,
+ force_update=args.force,
+ entity_type=args.entity_type,
+ )
+ result = {
+ "status": "complete",
+ "batch_keys": [batch["key"] for batch in batches],
+ }
+ elif args.command == "symmetric-edge-shards":
+ metric_buckets = _symmetric_edge_shard_batch(
+ data_dir,
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ entity_type=args.entity_type,
+ )
+ tasks.make_symmetric_edge_shards(
+ data_dir=data_dir,
+ metric_buckets=metric_buckets,
+ scratch_dir=args.scratch_dir.resolve(),
+ threads=args.threads,
+ force_update=args.force,
+ entity_type=args.entity_type,
+ )
+ result = {
+ "status": "complete",
+ "metric_buckets": metric_buckets,
+ }
+ elif args.command == "component-reductions":
+ metrics, thresholds = _cluster_parameters(
+ metrics=args.metrics,
+ thresholds=args.thresholds,
+ entity_type=args.entity_type,
+ )
+ sources = _component_source_batch(
+ data_dir,
+ metrics=metrics,
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ entity_type=args.entity_type,
+ )
+ tasks.make_component_reductions(
+ data_dir=data_dir,
+ source_paths=sources,
+ metrics=metrics,
+ thresholds=thresholds,
+ scratch_dir=args.scratch_dir.resolve(),
+ force_update=args.force,
+ metric_workers=args.threads,
+ entity_type=args.entity_type,
+ )
+ result = {"status": "complete", "sources": sources}
+ elif args.command == "merge-components":
+ metrics, thresholds = _cluster_parameters(
+ metrics=args.metrics,
+ thresholds=args.thresholds,
+ entity_type=args.entity_type,
+ )
+ tasks.merge_component_reductions(
+ data_dir=data_dir,
+ metrics=metrics,
+ thresholds=thresholds,
+ entity_type=args.entity_type,
+ )
+ result = {"status": "complete", "metrics": metrics}
+ elif args.command in {"set-covers", "directed-covers"}:
+ metrics, thresholds = _cluster_parameters(
+ metrics=args.metrics,
+ thresholds=args.thresholds,
+ entity_type=args.entity_type,
+ )
+ if args.command == "set-covers":
+ metrics = [
+ metric
+ for metric in metrics
+ if args.entity_type == "ligand" and is_chemical_cluster_metric(metric)
+ ]
+ else:
+ metrics = [
+ metric for metric in metrics if not is_chemical_cluster_metric(metric)
+ ]
+ if args.command == "set-covers":
+ work = _cover_batch(
+ metrics=metrics,
+ thresholds=thresholds,
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ for metric_threshold in work:
+ tasks.make_set_covers(
+ data_dir=data_dir,
+ metric_threshold=[metric_threshold],
+ skip_existing_clusters=not args.force,
+ scratch_dir=args.scratch_dir.resolve(),
+ threads=args.threads,
+ entity_type=args.entity_type,
+ )
+ else:
+ work = _directed_cover_batch(
+ metrics=metrics,
+ thresholds=thresholds,
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ tasks.make_directed_set_covers(
+ data_dir=data_dir,
+ metric_threshold=work,
+ skip_existing=not args.force,
+ scratch_dir=args.scratch_dir.resolve(),
+ threads=args.threads,
+ entity_type=args.entity_type,
+ )
+ result = {"status": "complete", "metric_thresholds": work}
+ elif args.command == "pack-ligands":
+ shards = _entry_shard_batch(data_dir, args.batch_index, args.batch_size)
+ tasks.make_canonical_ligand_archives(
+ data_dir=data_dir,
+ two_char_codes=shards,
+ scratch_dir=args.scratch_dir.resolve(),
+ )
+ result = {"status": "complete", "shards": shards}
+ else:
+ search_db = str(getattr(args, "search_db", "holo"))
+ plan = (
+ _load_linked_apo_plan(data_dir)
+ if search_db == "apo"
+ else _load_plan(data_dir)
+ )
+ cfg = _scoring_config_from_plan(
+ data_dir,
+ plan,
+ sub_databases=[search_db],
+ )
+ scratch_dir = args.scratch_dir.resolve()
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ if args.command == "collate-alignments":
+ shards = _shard_batch(data_dir, args.batch_index, args.batch_size)
+ for shard in shards:
+ tasks.collate_alignments(
+ data_dir=data_dir,
+ partition=[shard],
+ scratch_dir=scratch_dir,
+ threads=args.threads,
+ )
+ result = {"status": "complete", "shards": shards}
+ elif args.command == "repair-candidates":
+ repair_frame = pd.read_parquet(
+ args.repair_manifest.resolve(), columns=["pdb_id"]
+ )
+ replacement_query_ids = set(repair_frame["pdb_id"].dropna().astype(str))
+ shards = _score_repair_shard_batch(
+ args.repair_manifest.resolve(),
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ outputs = tasks.collate_ligand_3d_candidates(
+ data_dir=data_dir,
+ shards=shards,
+ scratch_dir=scratch_dir,
+ threads=args.threads,
+ replacement_query_ids=replacement_query_ids,
+ source_query_ids=replacement_query_ids.intersection(
+ published_scoring_query_ids(data_dir)
+ ),
+ )
+ result = {
+ "status": "complete",
+ "shards": shards,
+ "output_count": len(outputs),
+ }
+ elif args.command == "repair-pack-ligands":
+ shards = _score_repair_shard_batch(
+ args.repair_manifest.resolve(),
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ tasks.make_canonical_ligand_archives(
+ data_dir=data_dir,
+ two_char_codes=shards,
+ scratch_dir=scratch_dir,
+ )
+ result = {"status": "complete", "shards": shards}
+ elif args.command == "repair-score-shards":
+ replacement_query_ids = set(
+ pd.read_parquet(args.repair_manifest.resolve(), columns=["pdb_id"])[
+ "pdb_id"
+ ]
+ .dropna()
+ .astype(str)
+ )
+ shards = _score_repair_shard_batch(
+ args.repair_manifest.resolve(),
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ outputs = tasks.merge_ligand_3d_scores(
+ data_dir=data_dir,
+ shards=shards,
+ scorer_cfg=cfg.scorer,
+ force_update=True,
+ scratch_dir=scratch_dir,
+ threads=args.threads,
+ reuse_cached_pairs=True,
+ replacement_query_ids=replacement_query_ids,
+ )
+ result = {
+ "status": "complete",
+ "shards": shards,
+ "output_count": len(outputs),
+ }
+ elif args.command == "repair-merge-ligand-3d":
+ shards = _score_repair_shard_batch(
+ args.repair_manifest.resolve(),
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ result = merge_score_repair_ligand_3d(
+ data_dir,
+ shards=shards,
+ scratch_dir=scratch_dir,
+ threads=args.threads,
+ )
+ elif args.command == "repair-ligand-3d":
+ pairs = _score_repair_ligand_3d_batch(
+ data_dir,
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ output = None
+ if not pairs.empty:
+ output = tasks.make_ligand_3d_scores(
+ data_dir=data_dir,
+ pairs=pairs,
+ batch_index=args.batch_index,
+ scorer_cfg=cfg.scorer,
+ force_update=args.force,
+ scratch_dir=scratch_dir,
+ threads=args.threads,
+ output_path=(
+ data_dir
+ / "scores/ligand_3d_pair_repairs"
+ / f"{args.batch_index}.parquet"
+ ),
+ )
+ result = {
+ "status": "complete",
+ "pair_count": len(pairs),
+ "output": str(output) if output is not None else None,
+ }
+ elif args.command == "collate-score-partitions":
+ partitions = _score_partition_batch(args.batch_index, args.batch_size)
+ for partition in partitions:
+ tasks.collate_partitions(
+ data_dir=data_dir,
+ partition=[partition],
+ scratch_dir=scratch_dir,
+ threads=args.threads,
+ )
+ result = {"status": "complete", "partitions": partitions}
+ elif args.command == "collate-ligand-3d-candidates":
+ shards = _score_shard_batch(data_dir, args.batch_index, args.batch_size)
+ outputs = tasks.collate_ligand_3d_candidates(
+ data_dir=data_dir,
+ shards=shards,
+ scratch_dir=scratch_dir,
+ threads=args.threads,
+ )
+ result = {
+ "status": "complete",
+ "shards": shards,
+ "output_count": len(outputs),
+ }
+ elif args.command == "map":
+ shards = _shard_batch(
+ data_dir,
+ args.batch_index,
+ args.batch_size,
+ search_db=search_db,
+ )
+ mapped_search_databases = (
+ ["apo", "interface_apo"] if search_db == "apo" else [search_db]
+ )
+ for mapped_search_db in mapped_search_databases:
+ tasks.map_batch_alignments(
+ data_dir=data_dir,
+ shards=shards,
+ scorer_cfg=cfg.scorer,
+ force_update=args.force,
+ scratch_dir=scratch_dir,
+ search_db=mapped_search_db,
+ )
+ result = {
+ "status": "complete",
+ "search_db": search_db,
+ "shards": shards,
+ }
+ elif args.command == "score-ligand-3d":
+ pairs = _ligand_3d_batch(data_dir, args.batch_index, args.batch_size)
+ output = tasks.make_ligand_3d_scores(
+ data_dir=data_dir,
+ pairs=pairs,
+ batch_index=args.batch_index,
+ scorer_cfg=cfg.scorer,
+ force_update=args.force,
+ scratch_dir=scratch_dir,
+ threads=args.threads,
+ )
+ result = {
+ "status": "complete",
+ "pair_count": len(pairs),
+ "output": str(output),
+ }
+ elif args.command == "score-ligand-3d-retry":
+ pairs = _ligand_3d_retry_batch(data_dir, args.batch_index, args.batch_size)
+ output = tasks.make_ligand_3d_scores(
+ data_dir=data_dir,
+ pairs=pairs,
+ batch_index=args.batch_index,
+ scorer_cfg=cfg.scorer,
+ force_update=args.force,
+ scratch_dir=scratch_dir,
+ threads=args.threads,
+ output_path=(
+ data_dir
+ / "scores"
+ / "ligand_3d_pair_retries"
+ / f"{args.batch_index}.parquet"
+ ),
+ )
+ result = {
+ "status": "complete",
+ "pair_count": len(pairs),
+ "output": str(output),
+ }
+ elif args.command == "collate-ligand-3d":
+ shards = _ligand_3d_shard_batch(data_dir, args.batch_index, args.batch_size)
+ outputs = tasks.collate_ligand_3d_scores(
+ data_dir=data_dir,
+ shards=shards,
+ scratch_dir=scratch_dir,
+ threads=args.threads,
+ )
+ result = {
+ "status": "complete",
+ "shards": shards,
+ "output_count": len(outputs),
+ }
+ elif args.command == "merge-ligand-3d":
+ shards = _ligand_3d_shard_batch(data_dir, args.batch_index, args.batch_size)
+ outputs = tasks.merge_ligand_3d_scores(
+ data_dir=data_dir,
+ shards=shards,
+ scorer_cfg=cfg.scorer,
+ force_update=args.force,
+ scratch_dir=scratch_dir,
+ threads=args.threads,
+ )
+ result = {
+ "status": "complete",
+ "shards": shards,
+ "output_count": len(outputs),
+ }
+ else:
+ if args.command == "repair-score-target-remainders":
+ result = repair_target_score_remainders(
+ data_dir,
+ repair_manifest=args.repair_manifest.resolve(),
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ scorer_cfg=cfg.scorer,
+ scratch_dir=scratch_dir,
+ threads=args.threads,
+ )
+ print(json.dumps(result, indent=2, sort_keys=True))
+ return
+ if args.command == "repair-score-pdbs":
+ repairs = _score_repair_batch(
+ args.repair_manifest.resolve(),
+ batch_index=args.batch_index,
+ batch_size=args.batch_size,
+ )
+ tasks.repair_batch_scores(
+ data_dir=data_dir,
+ repairs=repairs,
+ scorer_cfg=cfg.scorer,
+ scratch_dir=scratch_dir,
+ threads=args.threads,
+ )
+ result = {
+ "status": "complete",
+ "pdb_ids": [str(repair["pdb_id"]) for repair in repairs],
+ }
+ print(json.dumps(result, indent=2, sort_keys=True))
+ return
+ if args.command == "score":
+ pdb_ids = (
+ _query_batch(
+ data_dir,
+ args.batch_index,
+ args.batch_size,
+ search_db="apo",
+ )
+ if search_db == "apo"
+ else _score_batch(data_dir, args.batch_index, args.batch_size)
+ )
+ elif args.command == "score-pdbs":
+ pdb_ids = _score_manifest_batch(
+ data_dir,
+ args.pdb_manifest.resolve(),
+ args.batch_index,
+ args.batch_size,
+ )
+ else:
+ pdb_ids = (
+ _apo_search_query_batch(
+ data_dir,
+ args.batch_index,
+ args.batch_size,
+ )
+ if search_db == "apo"
+ else _query_batch(
+ data_dir,
+ args.batch_index,
+ args.batch_size,
+ search_db=search_db,
+ )
+ )
+ if args.command == "search":
+ tasks.run_batch_searches(
+ data_dir=data_dir,
+ pdb_ids=pdb_ids,
+ scorer_cfg=cfg.scorer,
+ foldseek_cfg=cfg.foldseek,
+ mmseqs_cfg=cfg.mmseqs,
+ cpu=args.threads,
+ scratch_dir=scratch_dir,
+ alignment_types=args.alignment_type,
+ force_update=args.force,
+ )
+ elif args.command in {"score", "score-pdbs"}:
+ tasks.make_batch_scores(
+ data_dir=data_dir,
+ pdb_ids=pdb_ids,
+ scorer_cfg=cfg.scorer,
+ force_update=args.force,
+ scratch_dir=scratch_dir,
+ threads=args.threads,
+ defer_ligand_3d=True,
+ )
+ result = {
+ "status": "complete",
+ "search_db": search_db,
+ "pdb_ids": pdb_ids,
+ }
+ print(json.dumps(result, indent=2, sort_keys=True))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/plinder/data/pipeline/tasks.py b/src/plinder/data/pipeline/tasks.py
index 54de5953d..9d04986da 100644
--- a/src/plinder/data/pipeline/tasks.py
+++ b/src/plinder/data/pipeline/tasks.py
@@ -2,52 +2,168 @@
# Distributed under the terms of the Apache License 2.0
from __future__ import annotations
-import os
-from concurrent.futures import ALL_COMPLETED, Future, ThreadPoolExecutor, wait
+import json
+import time
+from concurrent.futures import (
+ ALL_COMPLETED,
+ Future,
+ ProcessPoolExecutor,
+ ThreadPoolExecutor,
+ wait,
+)
+from errno import EXDEV
+from hashlib import sha256
+from itertools import islice
from pathlib import Path
-from shutil import rmtree
+from shutil import copyfile, rmtree
from string import ascii_lowercase, digits
-from subprocess import check_output
from textwrap import dedent
-from typing import Any
-from zipfile import ZIP_DEFLATED, ZipFile
+from typing import Any, Iterator, Sequence, cast
import pandas as pd
+import pyarrow as pa
+import pyarrow.compute as pc
+import pyarrow.dataset as ds
+import pyarrow.parquet as pq
from omegaconf import DictConfig
from tqdm import tqdm
-from plinder.core.structure import smallmols_similarity
-from plinder.core.utils import gcs
+from plinder.core.scores.metrics import is_chemical_cluster_metric
+from plinder.core.utils import schemas
+from plinder.core.utils.files import file_sha256, read_json_cache, write_json_atomic
from plinder.core.utils.log import setup_logger
-from plinder.data import clusters, databases, leakage, splits
-from plinder.data.pipeline import io, utils
+from plinder.data import clusters, databases
+from plinder.data.annotations import (
+ ccd_ligand_dbs,
+ get_similarity_scores,
+ mmpdb_utils,
+)
+from plinder.data.pipeline import collate, io, utils
+from plinder.data.pipeline.ingest import (
+ balance_entries,
+ completed_entry_metrics,
+ completed_interface_metrics,
+ discover_entries,
+ ingest_pdb_batch,
+ normalize_ingest_mode,
+ normalize_pdb_id,
+)
LOG = setup_logger(__name__)
+ALIGNMENT_CHAIN_LOOKUP_RELATIVE = Path("index/alignment_chain_lookup.parquet")
+ALIGNMENT_CHAIN_LOOKUP_MANIFEST_RELATIVE = Path(
+ "index/alignment_chain_lookup.manifest.json"
+)
+INTERFACE_HALF_REPRESENTATIVES_RELATIVE = Path(
+ "index/interface_half_representatives.parquet"
+)
+INTERFACE_REPRESENTATIVES_RELATIVE = Path("index/interface_representatives.parquet")
+INTERFACE_MEMBERSHIP_RELATIVE = Path("index/interface_membership.parquet")
+INTERFACE_REPRESENTATIVES_MANIFEST_RELATIVE = Path(
+ "index/interface_representatives.manifest.json"
+)
+LIGAND_POCKET_REPRESENTATIVES_RELATIVE = Path(
+ "index/ligand_pocket_representatives.parquet"
+)
+LIGAND_POCKET_MEMBERSHIP_RELATIVE = Path("index/ligand_pocket_membership.parquet")
+LIGAND_POCKET_RESIDUES_RELATIVE = Path("index/ligand_pocket_residues.parquet")
+LIGAND_POCKET_REPRESENTATIVES_MANIFEST_RELATIVE = Path(
+ "index/ligand_pocket_representatives.manifest.json"
+)
+PROTEIN_SIMILARITY_SCORES_RELATIVE = Path("exports/protein_similarity_scores")
+LIGAND_POCKET_RESIDUE_SELECTION = "neighboring"
+APO_SEARCH_METADATA_KEY = b"plinder.apo_search_inputs"
STAGES = [
"download_rcsb_files",
"download_alternative_datasets",
- "make_dbs",
"make_entries",
- "structure_qc",
- "make_system_archives",
- "make_ligands",
+ "collate_entries",
+ "make_protein_sequence_clusters",
+ "make_dbs",
+ "make_protein_structure_clusters",
+ "make_canonical_ligand_archives",
+ "finalize_ligand_archives",
"compute_ligand_fingerprints",
"make_ligand_scores",
+ "make_mhfp6_scores",
+ "annotate_ligand_similarity",
+ "make_ligand_mmp_pairs",
+ "make_ccd_ligand_dbs",
"make_sub_dbs",
"run_batch_searches",
+ "map_batch_alignments",
+ "collate_alignments",
+ "finalize_alignments",
+ "plan_score_batches",
+ "plan_interface_scores",
+ "make_interface_scores",
+ "finalize_interface_scores",
"make_batch_scores",
+ "collate_ligand_3d_candidates",
+ "plan_ligand_3d_scores",
+ "make_ligand_3d_scores",
+ "collate_ligand_3d_scores",
+ "merge_ligand_3d_scores",
+ "finalize_scores",
+ "export_ligand_similarity_scores",
+ "finalize_ligand_similarity_scores",
"collate_partitions",
- "make_mmp_index",
- "make_components_and_communities",
- "make_splits",
- "compute_ligand_leakage",
- "compute_protein_leakage",
- "make_links",
- "make_linked_structures",
- "score_linked_structures",
+ "make_linked_apo_structures",
+ "plan_clusters",
+ "make_symmetric_edge_fragments",
+ "make_symmetric_edge_shards",
+ "make_component_reductions",
+ "merge_component_reductions",
+ "make_set_covers",
+ "make_directed_set_covers",
+ "summarize_clusters",
+ "finalize_index",
]
+def _file_content_signature(path: Path) -> dict[str, int | str]:
+ """Return a stable signature for a createdb input file."""
+ return {"size": path.stat().st_size, "sha256": file_sha256(path)}
+
+
+def _foldseek_manifest_signature(
+ path: Path, *, threads: int = 1
+) -> dict[str, int | str]:
+ """Bind a Foldseek input manifest to the coordinate files it names."""
+ digest = sha256()
+ count = 0
+
+ def paths() -> Iterator[Path]:
+ with path.open() as handle:
+ for raw_line in handle:
+ value = raw_line.strip()
+ if value:
+ yield Path(value.split("\t", maxsplit=1)[0])
+
+ def signature_row(cif_path: Path) -> bytes:
+ stat = cif_path.stat()
+ return (f"{cif_path.absolute()}\0{stat.st_size}\0{stat.st_mtime_ns}\n").encode()
+
+ source_paths = paths()
+ with ThreadPoolExecutor(max_workers=threads) as executor:
+ while batch := list(islice(source_paths, 4096)):
+ for row in executor.map(signature_row, batch):
+ digest.update(row)
+ count += 1
+ return {
+ **_file_content_signature(path),
+ "referenced_cif_count": count,
+ "referenced_cifs_sha256": digest.hexdigest(),
+ }
+
+
+def _foldseek_source_signature(path: Path, *, threads: int = 1) -> dict[str, int | str]:
+ """Hash a Foldseek coordinate directly or a TSV and its referenced files."""
+ if path.suffix.casefold() == ".tsv":
+ return _foldseek_manifest_signature(path, threads=threads)
+ return _file_content_signature(path)
+
+
def scatter_download_rcsb_files(
*,
data_dir: Path,
@@ -143,15 +259,12 @@ def download_alternative_datasets(
if True, force re-download
"""
- kws = dict(data_dir=data_dir, force_update=force_update)
- with ThreadPoolExecutor() as executor:
+ kws: dict[str, Any] = dict(data_dir=data_dir, force_update=force_update)
+ with ThreadPoolExecutor(max_workers=threads) as executor:
futures: list[Future[Any]] = [
executor.submit(io.download_cofactors, **kws),
executor.submit(io.download_seqres_data, **kws),
- executor.submit(io.download_kinase_data, **kws),
- executor.submit(io.download_panther_data, **kws),
- executor.submit(io.download_components_cif, **kws),
- executor.submit(io.download_ecod_data, **kws),
+ executor.submit(io.refresh_bundled_ccd, **kws),
executor.submit(io.download_affinity_data, **kws),
]
wait(futures, return_when=ALL_COMPLETED)
@@ -161,7 +274,19 @@ def download_alternative_datasets(
raise exc
-def make_dbs(*, data_dir: Path, sub_databases: list[str]) -> None:
+def make_dbs(
+ *,
+ data_dir: Path,
+ sub_databases: list[str],
+ cpu: int,
+ cif_root: Path | None = None,
+ seqres_path: Path | None = None,
+ scratch_dir: Path | None = None,
+ create: bool = True,
+ index: bool = True,
+ force_update: bool = False,
+ build_dir: Path | None = None,
+) -> None:
"""
Make the foldseek and mmseqs dbs
@@ -172,278 +297,243 @@ def make_dbs(*, data_dir: Path, sub_databases: list[str]) -> None:
"""
input_dirs = {}
if "apo" in sub_databases or "holo" in sub_databases:
- input_dirs["foldseek"] = data_dir / "ingest"
- input_dirs["mmseqs"] = io.download_seqres_data(data_dir=data_dir)
+ input_dirs["foldseek"] = cif_root or data_dir / "ingest"
+ input_dirs["mmseqs"] = seqres_path or io.download_seqres_data(data_dir=data_dir)
+ if create:
+ for source in input_dirs.values():
+ if not source.exists():
+ raise FileNotFoundError(f"missing database source: {source}")
if "pred" in sub_databases:
input_dirs["pred_mmseqs"] = io.download_uniprot_fasta_data(data_dir=data_dir)
input_dirs["pred_foldseek"] = io.download_alphafold_cif_files(data_dir=data_dir)
for db, source in input_dirs.items():
output_dir = data_dir / "dbs" / db
- LOG.info(f"make_dbs: making {db} in {output_dir}")
- databases.make_db(source, output_dir, db.split("_")[-1])
+ working_output_dir = build_dir / db if build_dir is not None else output_dir
+ LOG.info(f"make_dbs: making {db} in {working_output_dir}")
+ database_type = db.split("_")[-1]
+ tmp_dir = (scratch_dir or data_dir / "scratch" / "databases") / db
+ tmp_dir.mkdir(exist_ok=True, parents=True)
+ database_path = output_dir / database_type
+ complete = databases.created_database_is_complete(database_path, database_type)
+ source_signature = None
+ if source.is_file():
+ source_signature = (
+ _foldseek_source_signature(source, threads=cpu)
+ if database_type == "foldseek"
+ else _file_content_signature(source)
+ )
+ input_marker = output_dir / f"{database_type}.createdb-input.json"
+ source_is_current = (
+ source_signature is None
+ or read_json_cache(input_marker) == source_signature
+ )
+ rebuild = force_update or not complete or not source_is_current
+ if create and rebuild:
+ working_marker = working_output_dir / f"{database_type}.createdb-input.json"
+ working_marker.unlink(missing_ok=True)
+ databases.create_db(
+ source,
+ working_output_dir,
+ database_type,
+ threads=cpu,
+ )
+ if source_signature is not None:
+ write_json_atomic(working_marker, source_signature)
+ elif create:
+ LOG.info(f"make_dbs: reusing completed {database_path}")
+ if index:
+ index_output_dir = working_output_dir if rebuild else output_dir
+ databases.create_db_index(
+ index_output_dir,
+ database_type,
+ tmp_dir=tmp_dir,
+ threads=cpu,
+ )
+ if build_dir is not None and create and rebuild:
+ working_database = working_output_dir / database_type
+ if not databases.created_database_is_complete(
+ working_database, database_type
+ ):
+ raise RuntimeError(f"createdb output is incomplete: {working_database}")
+ databases.install_database_directory(working_output_dir, output_dir)
def scatter_make_entries(
*,
data_dir: Path,
+ cif_root: Path,
+ validation_root: Path,
batch_size: int,
two_char_codes: list[str],
pdb_ids: list[str],
force_update: bool,
+ discovery_threads: int = 8,
+ interface_min_residues: int = 7,
+ interface_annotate_prodigy: bool = True,
+ ingest_mode: str = "all",
) -> list[list[str]]:
- """
- Distribute annotation generation by pdb id rather than
- two character code for more symmetric distributed
- processing.
-
- Parameters
- ----------
- data_dir : Path
- the root plinder dir
- batch_size : int
- how many codes to put in a chunk
- force_update : bool
- two_char_codes : list[str], default=[]
- only consider particular codes
- pdb_ids : list[str], default=[]
- only consider particular pdb IDs
- force_update : bool
- if True, re-process existing entries
- """
- pdb_dirs = utils.get_local_contents(
- data_dir=data_dir / "ingest",
- two_char_codes=two_char_codes,
- pdb_ids=pdb_ids,
+ """Discover and size-balance source entries for annotation."""
+ ingest_mode = normalize_ingest_mode(ingest_mode)
+ selected_pdb_ids = [normalize_pdb_id(pdb_id) for pdb_id in pdb_ids]
+ selected_codes = _selected_context_codes(two_char_codes, selected_pdb_ids)
+ entries = discover_entries(
+ cif_root,
+ validation_root,
+ check_validation=False,
+ threads=discovery_threads,
+ two_char_codes=selected_codes,
+ pdb_ids=selected_pdb_ids,
)
if not force_update:
- pdb_dirs = [
- pdb_dir
- for pdb_dir in pdb_dirs
- if not utils.entry_exists(
- entry_dir=data_dir / "raw_entries",
- pdb_id=pdb_dir[-4:],
+ entries = [
+ entry
+ for entry in entries
+ if (
+ completed_interface_metrics(
+ data_dir,
+ entry.pdb_id,
+ expected_interface_min_residues=interface_min_residues,
+ expected_annotate_prodigy=interface_annotate_prodigy,
+ )
+ if ingest_mode == "interfaces"
+ else completed_entry_metrics(
+ data_dir,
+ entry.pdb_id,
+ expected_interface_min_residues=(
+ interface_min_residues if ingest_mode == "all" else None
+ ),
+ expected_annotate_prodigy=(
+ interface_annotate_prodigy if ingest_mode == "all" else None
+ ),
+ expected_ingest_mode=ingest_mode,
+ )
)
+ is None
]
- LOG.info(f"scatter_make_entries: found {len(pdb_dirs)} PDBs")
+ LOG.info(f"scatter_make_entries: found {len(entries)} PDBs in {cif_root}")
return [
- pdb_dirs[pos : pos + batch_size] for pos in range(0, len(pdb_dirs), batch_size)
+ [entry.pdb_id for entry in batch]
+ for batch in balance_entries(entries, batch_size=batch_size)
]
def make_entries(
*,
data_dir: Path,
- pdb_dirs: list[str],
+ pdb_ids: list[str],
+ cif_root: Path,
+ validation_root: Path,
force_update: bool,
annotation_cfg: DictConfig,
entry_cfg: DictConfig,
+ interface_cfg: DictConfig,
cpu: int = 1,
+ ingest_mode: str = "all",
) -> list[str]:
- """
- Offload individual plinder annotation tasks to
- a multiprocessing queue wrapped as a subprocess.
- This is a simple way to gracefully handle seg-faults
- from C-extensions without impacting later entries in
- the list of pdb_dirs. Additionally keep a record of
- entries which failed so that they can be re-processed
- with larger resource requests.
+ """Run the resumable batch implementation used by Slurm."""
+ del cpu # Entry annotation is intentionally sequential within each worker.
+ normalized_ids = [normalize_pdb_id(pdb_id) for pdb_id in pdb_ids]
+ hash_id = utils.hash_contents(normalized_ids)
+ metrics_path, _ = ingest_pdb_batch(
+ pdb_ids=normalized_ids,
+ output_root=data_dir,
+ cif_root=cif_root,
+ validation_root=validation_root,
+ force=force_update,
+ job_id=f"ingest-{hash_id}",
+ annotation_cfg=annotation_cfg,
+ entry_cfg=entry_cfg,
+ interface_cfg=interface_cfg,
+ mode=normalize_ingest_mode(ingest_mode),
+ )
+ payload = json.loads(metrics_path.read_text())
+ failed = [
+ str(entry["pdb_id"])
+ for entry in payload["entries"]
+ if entry["status"] == "failed"
+ ]
+ LOG.info(f"would rerun {len(failed)} entries")
+ return failed
- Parameters
- ----------
- data_dir : Path
- the root plinder dir
- pdb_dirs : list[str]
- list of pdb directories to process
- force_update : bool
- if True, force re-processing
- annotation_cfg : DictConfig
- from plinder.data.pipeline.config.AnnotationConfig
- entry_cfg : DictConfig
- from plinder.data.pipeline.config.EntryConfig
- cpu : int, default=1
- number of CPUs to use
- Returns
- -------
- failed : list[str]
- list of pdb directories to re-process
- """
- input_dir = data_dir / "ingest"
- report_dir = data_dir / "reports"
- output_dir = data_dir / "raw_entries"
- scratch_dir = data_dir / "scratch" / "raw_entries"
- LOG.info(f"making {len(pdb_dirs)} entries in {output_dir}")
- output_dir.mkdir(exist_ok=True, parents=True)
- scratch_dir.mkdir(exist_ok=True, parents=True)
- hashed_contents = utils.hash_contents(pdb_dirs)
- scratch_tasks = scratch_dir / f"tasks_{hashed_contents}.txt"
- check_finished = []
- with scratch_tasks.open("w") as f:
- for pdb_dir in pdb_dirs:
- two_char_code = pdb_dir[-3:-1]
- pdb_id = pdb_dir[-4:]
- output = output_dir / two_char_code / (pdb_id + ".json")
- if not force_update and output.is_file():
- LOG.info(f"skipping {pdb_id} since entry exists already")
- continue
- output.parent.mkdir(exist_ok=True, parents=True)
- check_finished.append((pdb_dir, output))
- # cifs are in ingest/{two_char_code}/pdb_0000{pdb_id}/
- # but vals are in reports/{two_char_code}/{pdb_id}/
- # and not all cifs have vals so gracefully handle
- [mmcif] = list((input_dir / two_char_code / pdb_dir).glob(io.CIF_GLOB))
- try:
- [report] = list((report_dir / two_char_code / pdb_id).glob(io.VAL_GLOB))
- except Exception:
- report = (
- report_dir / two_char_code / pdb_id / (pdb_id + io.VAL_GLOB[1:])
- )
- cmd = (
- [
- "python",
- "-m",
- "plinder.data.get_system_annotations",
- f"mmcif_file={mmcif.as_posix()}",
- f"validation_xml={report.as_posix()}",
- ]
- + [f"annotation.{k}={v}" for k, v in annotation_cfg.items()]
- + [f"entry.{k}={v}" for k, v in entry_cfg.items() if k != "save_folder"]
- + [f"entry.save_folder={output.parent.as_posix()}"]
- )
- f.write(" ".join(cmd) + "\n")
- try:
- check_output(
- [
- "python",
- "-m",
- "plinder.data.pipeline.mpqueue",
- f"{scratch_tasks.as_posix()}",
- f"--cores={max(1, cpu - 1)}",
- ],
- text=True,
- timeout=10800,
- )
- scratch_tasks.unlink()
- except Exception:
- LOG.error("beep boop mpqueue timed out")
-
- rerun = []
- for pdb_dir, output in check_finished:
- if output.is_file():
- continue
- rerun.append(pdb_dir)
+def _selected_context_codes(two_char_codes: list[str], pdb_ids: list[str]) -> list[str]:
+ """Apply context precedence consistently across entry-derived stages."""
+ if pdb_ids:
+ return sorted({normalize_pdb_id(pdb_id)[1:3] for pdb_id in pdb_ids})
+ return sorted(str(code).lower() for code in two_char_codes)
- fail_dir = data_dir / "failed_entries"
- fail_dir.mkdir(exist_ok=True, parents=True)
- LOG.info(f"would rerun {len(rerun)} systems")
- with (fail_dir / f"fails_{hashed_contents}.txt").open("w") as f:
- for item in rerun:
- f.write(f"{item}\n")
- return rerun
+def _has_completed_raw_entries(entry_dir: Path) -> bool:
+ """Return whether a raw-entry shard contains completed entry parquet files."""
+ return entry_dir.is_dir() and any(entry_dir.glob("*.parquet"))
-def scatter_structure_qc(
+
+def scatter_collate_entries(
*,
data_dir: Path,
- two_char_codes: list[str],
batch_size: int,
+ include_ligand_annotations: bool = True,
) -> list[list[str]]:
- """
- Scatter two character codes for system archive generation
-
- Parameters
- ----------
- data_dir : Path
- the root plinder dir
- batch_size : int
- how many codes to put in a chunk
- two_char_codes : list[str], default=[]
- only consider particular codes
-
- Returns
- -------
- chunks : list[list[str]]
- batches of two character codes
- """
- entry_dir = data_dir / "raw_entries"
- if len(two_char_codes):
- codes = sorted(two_char_codes)
- else:
- codes = sorted(os.listdir(entry_dir.as_posix()))
- LOG.info(f"scatter_structure_qc: found {len(codes)} two character codes")
+ """Plan collation and scatter deterministic two-character shards."""
+ if batch_size < 1:
+ raise ValueError("batch_size must be positive")
+ plan = collate.plan_collation(
+ data_dir, include_ligand_annotations=include_ligand_annotations
+ )
+ codes = [str(code) for code in plan["codes"]]
return [codes[pos : pos + batch_size] for pos in range(0, len(codes), batch_size)]
-def structure_qc(
+def collate_entries(
*,
data_dir: Path,
two_char_codes: list[str],
+ cpu: int,
+ memory_limit: str,
) -> None:
- from plinder.data.final_structure_qc import (
- prepare_system_dict,
- run_structure_checks,
+ """Collate one batch of entry shards through the shared implementation."""
+ for code in two_char_codes:
+ collate.collate_shard(
+ data_dir,
+ code,
+ threads=cpu,
+ memory_limit=memory_limit,
+ scratch_dir=data_dir / "scratch" / "collation",
+ )
+
+
+def finalize_entry_collation(
+ *,
+ data_dir: Path,
+ cpu: int,
+ memory_limit: str,
+) -> dict[str, Any]:
+ """Validate and install the sharded annotation index."""
+ return collate.finalize_collation(
+ data_dir,
+ threads=cpu,
+ memory_limit=memory_limit,
+ scratch_dir=data_dir / "scratch" / "collation-finalize",
)
- from plinder.data.utils.annotations.aggregate_annotations import Entry
- entry_dir = data_dir / "raw_entries"
- err_dir = data_dir / "qc" / "logs"
- zip_dir = data_dir / "entries"
- pqt_dir = data_dir / "qc" / "index"
- err_dir.mkdir(exist_ok=True, parents=True)
- zip_dir.mkdir(exist_ok=True, parents=True)
- pqt_dir.mkdir(exist_ok=True, parents=True)
- for code in two_char_codes:
- with ZipFile(zip_dir / f"{code}.zip", "w", compression=ZIP_DEFLATED) as archive:
- with (err_dir / f"{code}_qc_fails.csv").open("w") as fails:
- fails.write("entry_json,error\n")
- LOG.info(f"structure_qc: two_char_code={code}")
- entry_dfs = []
- structure_qc = []
- for i, entry_json in enumerate((entry_dir / code).glob("*json")):
- if not i % 25:
- LOG.info(f"on entry={i} {entry_json}")
- try:
- entry = Entry.from_json(
- entry_json, clear_non_pocket_residues=True
- )
- except Exception as e:
- LOG.warning(f"failed loading {entry_json}")
- clean = str(e).replace(",", "_").replace("\n", " ")[:50]
- fails.write(f"{entry_json},{clean}")
- continue
- if len(entry.systems):
- entry_dfs.append(entry.to_df())
- archive.writestr(entry_json.name, entry.model_dump_json())
- system_structure_path = entry_dir / code
- try:
- for system_dict in prepare_system_dict(
- system_structure_path,
- entry,
- ):
- structure_qc.extend(run_structure_checks(system_dict))
- except Exception as e:
- LOG.warning(f"failed structure checks for {entry_json}")
- fails.write(f"{entry_json},{str(e).replace(',', '_')}\n")
- continue
- if len(entry_dfs) and len(structure_qc):
- entry_df = pd.concat(entry_dfs).reset_index(drop=True)
- structure_df = pd.DataFrame(structure_qc)
- pd.merge(
- entry_df,
- structure_df,
- on=["system_id", "ligand_instance", "ligand_asym_id"],
- how="left",
- ).to_parquet(pqt_dir / f"{code}.parquet", index=False)
-
-
-def scatter_make_system_archives(
+
+def publish_binding_affinity(*, data_dir: Path) -> None:
+ """Write sequence-checked ligand affinities and source measurements."""
+ from plinder.data.annotations.affinity import publish_affinity_tables
+
+ io.download_affinity_data(data_dir=data_dir)
+ publish_affinity_tables(data_dir)
+
+
+def scatter_make_canonical_ligand_archives(
*,
data_dir: Path,
two_char_codes: list[str],
+ pdb_ids: list[str],
batch_size: int,
) -> list[list[str]]:
"""
- Scatter two character codes for system archive generation
+ Scatter two-character codes for canonical ligand archive generation.
Parameters
----------
@@ -453,6 +543,8 @@ def scatter_make_system_archives(
how many codes to put in a chunk
two_char_codes : list[str], default=[]
only consider particular codes
+ pdb_ids : list[str], default=[]
+ if set, derive codes from these IDs and ignore ``two_char_codes``
Returns
-------
@@ -460,285 +552,3967 @@ def scatter_make_system_archives(
batches of two character codes
"""
entry_dir = data_dir / "raw_entries"
- if len(two_char_codes):
- codes = sorted(two_char_codes)
+ selected_codes = _selected_context_codes(two_char_codes, pdb_ids)
+ if selected_codes:
+ codes = [
+ code
+ for code in selected_codes
+ if _has_completed_raw_entries(entry_dir / code)
+ ]
else:
- codes = sorted(os.listdir(entry_dir.as_posix()))
- LOG.info(f"scatter_make_system_archives: found {len(codes)} two character codes")
+ codes = sorted(
+ path.name
+ for path in entry_dir.iterdir()
+ if _has_completed_raw_entries(path)
+ )
+ LOG.info(
+ "scatter_make_canonical_ligand_archives: "
+ f"found {len(codes)} two character codes"
+ )
return [codes[pos : pos + batch_size] for pos in range(0, len(codes), batch_size)]
-def make_system_archives(
+def make_canonical_ligand_archives(
*,
data_dir: Path,
two_char_codes: list[str],
+ scratch_dir: Path | None = None,
) -> None:
- """
- Create a zip file of all the system files in a given
- two character code to reduce pressure on the network
- for large-scale file IO.
- """
+ """Pack canonical ASU ligand SDFs into one queryable Parquet per shard."""
+ schema = pa.schema(
+ [
+ pa.field("pdb_id", pa.string(), nullable=False),
+ pa.field("ligand_asym_id", pa.string(), nullable=False),
+ pa.field("sdf", pa.binary(), nullable=False),
+ pa.field(
+ "pharmacophore_features",
+ get_similarity_scores.PHARMACOPHORE_FEATURE_TYPE,
+ ),
+ ]
+ )
for code in two_char_codes:
entry_dir = data_dir / "raw_entries" / code
- archive = data_dir / "archives" / f"{code}.zip"
+ archive = data_dir / "ligand_archives" / f"{code}.parquet"
archive.parent.mkdir(exist_ok=True, parents=True)
- with ZipFile(archive.as_posix(), "w", compression=ZIP_DEFLATED) as zip_archive:
- for subdir in os.listdir(entry_dir):
- if os.path.isdir(f"{entry_dir}/{subdir}"):
- for root, _, files in os.walk(f"{entry_dir}/{subdir}"):
- for file in files:
- full_path = os.path.join(root, file)
- parts = full_path.split(os.sep)
- arc_name = os.path.join(*parts[parts.index(code) + 1 :])
- zip_archive.write(full_path, arc_name)
+ entry_parquets = sorted(entry_dir.glob("*.parquet"))
+ if not entry_parquets:
+ archive.unlink(missing_ok=True)
+ continue
+ records = []
+ for entry_parquet in entry_parquets:
+ ligand_dir = entry_dir / entry_parquet.stem / "ligand_files"
+ for ligand_file in sorted(ligand_dir.glob("*.sdf")):
+ sdf = ligand_file.read_bytes()
+ records.append(
+ {
+ "pdb_id": entry_parquet.stem,
+ "ligand_asym_id": ligand_file.stem,
+ "sdf": sdf,
+ "pharmacophore_features": get_similarity_scores.ligand_pharmacophore_records(
+ sdf, label=str(ligand_file)
+ ),
+ }
+ )
+ table = pa.Table.from_pylist(records, schema=schema)
+ temporary_root = scratch_dir or archive.parent
+ temporary_root.mkdir(exist_ok=True, parents=True)
+ temporary = temporary_root / f"{code}.parquet"
+ if temporary == archive:
+ temporary = archive.with_suffix(".tmp.parquet")
+ pq.write_table(
+ table,
+ temporary,
+ compression="zstd",
+ compression_level=6,
+ use_dictionary=["pdb_id", "ligand_asym_id"],
+ row_group_size=2_048,
+ write_statistics=True,
+ )
+ install = archive.with_suffix(".tmp.parquet")
+ if temporary != install:
+ copyfile(temporary, install)
+ temporary.unlink(missing_ok=True)
+ install.replace(archive)
def make_sub_dbs(
*,
data_dir: Path,
sub_databases: list[str],
+ cpu: int = 1,
+ scratch_dir: Path | None = None,
) -> None:
"""
- Get the list of all pdb IDs to load all the entries
- for full sub-database generation context. Explicitly
- don't support two_char_codes forwarding to get_local_contents
- to avoid an issue where sub dbs are created without full
- context.
+ Build search databases from all eligible chains in the release.
+
+ This stage always uses the full release, even when other stages are
+ restricted to selected PDB IDs or two-character shards.
Parameters
----------
data_dir : Path
the root plinder dir
"""
- entries = utils.load_entries_from_zips(data_dir=data_dir)
+ entries = None
+ identifiers_by_database: dict[str, set[str]] = {}
+ indexed_search_databases = []
+ if set(sub_databases) <= {"holo", "apo", "monomer"}:
+ indexed_search_databases = list(sub_databases)
+ elif "monomer" in sub_databases:
+ indexed_search_databases = ["monomer"]
+ for search_db in indexed_search_databases:
+ chains = (
+ _protein_scoring_chains(data_dir)
+ if search_db == "holo"
+ else (
+ _monomer_scoring_chains(data_dir)
+ if search_db == "monomer"
+ else _apo_scoring_chains(data_dir)
+ )
+ )
+ if search_db == "holo":
+ chain_auth_ids = pd.read_parquet(
+ data_dir / "index" / "entry_chains.parquet",
+ columns=["entry_pdb_id", "chain_asym_id", "chain_auth_id"],
+ )
+ chains = chains.merge(
+ chain_auth_ids,
+ on=["entry_pdb_id", "chain_asym_id"],
+ how="left",
+ validate="one_to_one",
+ )
+ chains = chains[chains["chain_auth_id"].notna()]
+ identifiers_by_database[f"{search_db}_foldseek"] = {
+ f"pdb_0000{row.entry_pdb_id}_xyz-enrich_{row.chain_auth_id}"
+ for row in chains.itertuples(index=False)
+ }
+ identifiers_by_database[f"{search_db}_mmseqs"] = {
+ f"{row.entry_pdb_id}_{row.chain_auth_id}"
+ for row in chains.itertuples(index=False)
+ }
+ if set(sub_databases).difference({"holo", "apo", "monomer"}):
+ from plinder.core.scores.entries import entry_views_from_df
+
+ entries = entry_views_from_df(
+ pd.read_parquet(data_dir / "index" / "annotation_table.parquet"),
+ entry_chains=pd.read_parquet(data_dir / "index" / "entry_chains.parquet"),
+ )
+ if "apo" in sub_databases:
+ interface_chains = _interface_apo_scoring_chains(data_dir)
+ identifiers_by_database["interface_apo_foldseek"] = {
+ f"pdb_0000{row.entry_pdb_id}_xyz-enrich_{row.chain_auth_id}"
+ for row in interface_chains.itertuples(index=False)
+ }
+ identifiers_by_database["interface_apo_mmseqs"] = {
+ f"{row.entry_pdb_id}_{row.chain_auth_id}"
+ for row in interface_chains.itertuples(index=False)
+ }
db_dir = data_dir / "dbs" / "subdbs"
db_dir.mkdir(exist_ok=True)
LOG.info("making sub-databases for scoring")
db_sources = utils.get_db_sources(data_dir=data_dir, sub_databases=sub_databases)
- databases.make_sub_dbs(db_dir, db_sources, entries)
-
-
-def scatter_make_ligands(
- *,
- data_dir: Path,
- batch_size: int,
- two_char_codes: list[str],
- pdb_ids: list[str],
-) -> list[list[str]]:
- """ """
- pdb_ids = utils.get_local_contents(
- data_dir=data_dir / "ingest",
- two_char_codes=two_char_codes,
- pdb_ids=pdb_ids,
- as_four_char_ids=True,
+ if "apo" in sub_databases:
+ db_sources.update(
+ utils.get_db_sources(data_dir=data_dir, sub_databases=["interface_apo"])
+ )
+ databases.make_sub_dbs(
+ db_dir,
+ db_sources,
+ entries,
+ identifiers_by_database=identifiers_by_database,
+ tmp_dir=scratch_dir,
+ threads=cpu,
)
- LOG.info(f"scatter_make_ligands: found {len(pdb_ids)} PDBs from ingest")
- pdb_ids = [
- pdb_id
- for pdb_id in pdb_ids
- if utils.entry_exists(
- entry_dir=data_dir / "raw_entries",
- pdb_id=pdb_id,
+ if set(sub_databases).intersection({"holo", "apo", "monomer"}):
+ make_alignment_chain_lookup(
+ data_dir=data_dir,
+ scratch_dir=scratch_dir,
+ threads=cpu,
)
- ]
- LOG.info(f"scatter_make_ligands: found {len(pdb_ids)} PDBs from raw_entries")
- return [
- pdb_ids[pos : pos + batch_size] for pos in range(0, len(pdb_ids), batch_size)
- ]
-def make_ligands(
- *,
+def _interface_representative_source_signature(
data_dir: Path,
- pdb_ids: list[str],
-) -> None:
- """ """
- entries = utils.load_entries_from_zips(data_dir=data_dir, pdb_ids=pdb_ids)
- hashed_contents = utils.hash_contents(pdb_ids)
- output_dir = data_dir / "ligands"
- output_dir.mkdir(exist_ok=True, parents=True)
- output_path = output_dir / f"{hashed_contents}.parquet"
- LOG.info("make_ligands: running save_ligand_batch")
- utils.save_ligand_batch(
- entries=entries,
- output_path=output_path,
- )
+) -> dict[str, int | str]:
+ source = data_dir / "index" / "interface_annotation_table.parquet"
+ stat = source.stat()
+ return {
+ "name": source.name,
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ }
-def compute_ligand_fingerprints(
- *,
- data_dir: Path,
- split_char: str = "__",
- radius: int = 2,
- nbits: int = 1024,
-) -> None:
- """ """
- LOG.info("compute_ligand_fingerprints: running")
- # data_dir / "fingerprints" / ligands_per_system.parquet
- # data_dir / "fingerprints" / ligands_per_inchikey.parquet
- # data_dir / "fingerprints" /ligands_per_inchikey_ecfp4.npy
- smallmols_similarity.compute_ligand_fingerprints(
- data_dir=data_dir,
- split_char=split_char,
- radius=radius,
- nbits=nbits,
- )
+def _interface_representative_output_signature(path: Path) -> dict[str, int | str]:
+ stat = path.stat()
+ return {"name": path.name, "size": stat.st_size, "mtime_ns": stat.st_mtime_ns}
-def scatter_make_ligand_scores(
- *,
+def _completed_interface_representatives(
data_dir: Path,
- batch_size: int,
- number_id_col: str = "number_id_by_inchikeys",
-) -> list[list[int]]:
- """ """
- ligands = pd.read_parquet(
- data_dir / "fingerprints" / "ligands_per_inchikey.parquet",
- columns=[number_id_col],
- )[number_id_col].to_list()
- LOG.info(f"scatter_make_ligand_scores: found {len(ligands)} ligands")
- return [
- ligands[pos : pos + batch_size] for pos in range(0, len(ligands), batch_size)
- ]
+) -> dict[str, Any] | None:
+ manifest = read_json_cache(data_dir / INTERFACE_REPRESENTATIVES_MANIFEST_RELATIVE)
+ expected = {
+ "half_interfaces": (
+ INTERFACE_HALF_REPRESENTATIVES_RELATIVE,
+ schemas.INTERFACE_HALF_REPRESENTATIVE_SCHEMA,
+ ),
+ "interfaces": (
+ INTERFACE_REPRESENTATIVES_RELATIVE,
+ schemas.INTERFACE_REPRESENTATIVE_SCHEMA,
+ ),
+ "membership": (
+ INTERFACE_MEMBERSHIP_RELATIVE,
+ schemas.INTERFACE_MEMBERSHIP_SCHEMA,
+ ),
+ }
+ try:
+ if manifest is None or manifest.get(
+ "source"
+ ) != _interface_representative_source_signature(data_dir):
+ return None
+ for key, (relative, schema) in expected.items():
+ path = data_dir / relative
+ if not pq.read_schema(path).equals(schema) or manifest.get(
+ "outputs", {}
+ ).get(key) != _interface_representative_output_signature(path):
+ return None
+ except (OSError, TypeError, ValueError):
+ return None
+ return manifest
-def make_ligand_scores(
+def make_interface_representatives(
*,
data_dir: Path,
- ligand_ids: list[int],
- save_top_k_similar_ligands: int = 5000,
- multiply_by: int = 100,
- number_id_col: str = "number_id_by_inchikeys",
-) -> None:
- hashid = utils.hash_contents([str(i) for i in ligand_ids])
- output_path = data_dir / "ligand_scores" / f"{hashid}.parquet"
- output_path.parent.mkdir(exist_ok=True, parents=True)
- smallmols_similarity.ligand_scores(
- ligand_ids=ligand_ids,
- data_dir=data_dir,
- output_path=output_path,
- number_id_col=number_id_col,
- save_top_k_similar_ligands=save_top_k_similar_ligands,
- multiply_by=multiply_by,
+ scratch_dir: Path | None,
+ threads: int,
+ force_update: bool = False,
+ memory_limit: str = "64GB",
+) -> dict[str, Any]:
+ """Group exact assembly-copy interfaces before mapping and scoring."""
+ current = _completed_interface_representatives(data_dir)
+ if not force_update and current is not None:
+ LOG.info(
+ "make_interface_representatives: reusing %d representatives for "
+ "%d interfaces",
+ current["representative_interface_count"],
+ current["interface_count"],
+ )
+ return current
+
+ import duckdb
+
+ source_signature = _interface_representative_source_signature(data_dir)
+ started = time.monotonic()
+ LOG.info("make_interface_representatives: normalizing interface masks")
+ source = data_dir / "index" / "interface_annotation_table.parquet"
+ working_root = (scratch_dir or data_dir / "scratch") / "interface-representatives"
+ if working_root.exists():
+ rmtree(working_root)
+ working_root.mkdir(parents=True)
+ temporary_paths = {
+ "half_interfaces": working_root / INTERFACE_HALF_REPRESENTATIVES_RELATIVE.name,
+ "interfaces": working_root / INTERFACE_REPRESENTATIVES_RELATIVE.name,
+ "membership": working_root / INTERFACE_MEMBERSHIP_RELATIVE.name,
+ }
+ connection = duckdb.connect()
+ collate._configure_duckdb(
+ connection, threads=threads, memory_limit=memory_limit, scratch_dir=working_root
)
+ connection.sql(
+ dedent(
+ f"""
+ CREATE TEMP TABLE interface_sides AS
+ SELECT
+ entry_pdb_id,
+ system_id,
+ 1::TINYINT AS side,
+ interface_chain_1 AS instance_chain_id,
+ split_part(interface_chain_1, '.', 2) AS chain_asym_id,
+ interface_chain_1_residue_numbers AS residue_numbers,
+ interface_chain_1_residue_indices AS residue_indices
+ FROM read_parquet('{source.as_posix()}')
+ UNION ALL
+ SELECT
+ entry_pdb_id,
+ system_id,
+ 2::TINYINT AS side,
+ interface_chain_2 AS instance_chain_id,
+ split_part(interface_chain_2, '.', 2) AS chain_asym_id,
+ interface_chain_2_residue_numbers AS residue_numbers,
+ interface_chain_2_residue_indices AS residue_indices
+ FROM read_parquet('{source.as_posix()}');
+ CREATE TEMP TABLE half_representatives AS
+ SELECT
+ min(system_id || '::side=' || side::VARCHAR)::VARCHAR
+ AS half_interface_id,
+ entry_pdb_id,
+ arg_min(
+ instance_chain_id,
+ system_id || '::side=' || side::VARCHAR
+ )::VARCHAR AS instance_chain_id,
+ chain_asym_id,
+ residue_numbers,
+ residue_indices
+ FROM interface_sides
+ GROUP BY
+ entry_pdb_id,
+ chain_asym_id,
+ residue_numbers,
+ residue_indices;
-def scatter_protein_scoring(
- *,
- data_dir: Path,
- batch_size: int,
- two_char_codes: list[str],
- pdb_ids: list[str],
-) -> list[list[str]]:
- """
- Split all the PDB IDs in the dataset
- to be used in score generation.
+ CREATE TEMP TABLE side_membership AS
+ SELECT
+ sides.entry_pdb_id,
+ sides.system_id,
+ sides.side,
+ representatives.half_interface_id
+ FROM interface_sides AS sides
+ INNER JOIN half_representatives AS representatives
+ ON sides.entry_pdb_id = representatives.entry_pdb_id
+ AND sides.chain_asym_id = representatives.chain_asym_id
+ AND sides.residue_numbers = representatives.residue_numbers
+ AND sides.residue_indices = representatives.residue_indices;
- Parameters
- ----------
- data_dir : Path
- the root plinder dir
- batch_size : int
- how many codes to put in a chunk
- two_char_codes : list[str], default=[]
- only consider particular codes
- pdb_ids : list[str], default=[]
- only consider particular pdb IDs
+ CREATE TEMP TABLE interface_members AS
+ SELECT
+ entry_pdb_id,
+ system_id,
+ max(half_interface_id) FILTER (WHERE side = 1)
+ AS side_1_half_interface_id,
+ max(half_interface_id) FILTER (WHERE side = 2)
+ AS side_2_half_interface_id
+ FROM side_membership
+ GROUP BY entry_pdb_id, system_id;
- Returns
- -------
- codes : list[list[str]]
- list of lists of chunks of two character codes
- """
- pdb_ids = utils.get_local_contents(
- data_dir=data_dir / "ingest",
- two_char_codes=two_char_codes,
- pdb_ids=pdb_ids,
- as_four_char_ids=True,
+ CREATE TEMP TABLE representative_groups AS
+ SELECT
+ entry_pdb_id,
+ least(side_1_half_interface_id, side_2_half_interface_id)
+ AS half_interface_1_id,
+ greatest(side_1_half_interface_id, side_2_half_interface_id)
+ AS half_interface_2_id,
+ min(system_id)::VARCHAR AS representative_system_id
+ FROM interface_members
+ GROUP BY entry_pdb_id, half_interface_1_id, half_interface_2_id;
+
+ COPY (
+ SELECT * FROM half_representatives
+ ORDER BY half_interface_id
+ ) TO '{temporary_paths["half_interfaces"].as_posix()}' (
+ FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 100000
+ );
+
+ COPY (
+ SELECT
+ representative_system_id,
+ entry_pdb_id,
+ half_interface_1_id,
+ half_interface_2_id
+ FROM representative_groups
+ ORDER BY representative_system_id
+ ) TO '{temporary_paths["interfaces"].as_posix()}' (
+ FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 100000
+ );
+
+ COPY (
+ SELECT
+ members.system_id,
+ groups.representative_system_id,
+ members.side_1_half_interface_id,
+ members.side_2_half_interface_id
+ FROM interface_members AS members
+ INNER JOIN representative_groups AS groups
+ ON members.entry_pdb_id = groups.entry_pdb_id
+ AND least(
+ members.side_1_half_interface_id,
+ members.side_2_half_interface_id
+ ) = groups.half_interface_1_id
+ AND greatest(
+ members.side_1_half_interface_id,
+ members.side_2_half_interface_id
+ ) = groups.half_interface_2_id
+ ORDER BY members.system_id
+ ) TO '{temporary_paths["membership"].as_posix()}' (
+ FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 100000
+ );
+
+ """
+ )
)
- pdb_ids = [
- pdb_id
- for pdb_id in pdb_ids
- if utils.entry_exists(
- entry_dir=data_dir / "raw_entries",
- pdb_id=pdb_id,
+ connection.close()
+ LOG.info(
+ "make_interface_representatives: DuckDB normalization complete "
+ "elapsed_seconds=%.1f",
+ time.monotonic() - started,
+ )
+
+ expected = {
+ "half_interfaces": (
+ INTERFACE_HALF_REPRESENTATIVES_RELATIVE,
+ schemas.INTERFACE_HALF_REPRESENTATIVE_SCHEMA,
+ ),
+ "interfaces": (
+ INTERFACE_REPRESENTATIVES_RELATIVE,
+ schemas.INTERFACE_REPRESENTATIVE_SCHEMA,
+ ),
+ "membership": (
+ INTERFACE_MEMBERSHIP_RELATIVE,
+ schemas.INTERFACE_MEMBERSHIP_SCHEMA,
+ ),
+ }
+ for key, (_, schema) in expected.items():
+ observed = pq.read_schema(temporary_paths[key])
+ if not observed.equals(schema):
+ rmtree(working_root)
+ raise ValueError(
+ f"interface representative {key} has unexpected schema: {observed}"
+ )
+ membership_rows = pq.ParquetFile(temporary_paths["membership"]).metadata.num_rows
+ source_rows = pq.ParquetFile(source).metadata.num_rows
+ if membership_rows != source_rows:
+ rmtree(working_root)
+ raise ValueError(
+ f"interface membership is incomplete: rows={membership_rows}/{source_rows}"
)
- ]
- LOG.info(f"scatter_make_scorers: found {len(pdb_ids)} pdb IDs")
- return [
- pdb_ids[pos : pos + batch_size] for pos in range(0, len(pdb_ids), batch_size)
- ]
+ if _interface_representative_source_signature(data_dir) != source_signature:
+ rmtree(working_root)
+ raise RuntimeError("interface annotation changed while making representatives")
+
+ outputs: dict[str, dict[str, int | str]] = {}
+ for key, (relative, _) in expected.items():
+ target = data_dir / relative
+ target.parent.mkdir(parents=True, exist_ok=True)
+ install = target.with_suffix(target.suffix + ".tmp")
+ copyfile(temporary_paths[key], install)
+ install.replace(target)
+ outputs[key] = _interface_representative_output_signature(target)
+ rmtree(working_root)
+ payload = {
+ "status": "complete",
+ "source": source_signature,
+ "outputs": outputs,
+ "interface_count": source_rows,
+ "representative_interface_count": pq.ParquetFile(
+ data_dir / INTERFACE_REPRESENTATIVES_RELATIVE
+ ).metadata.num_rows,
+ "representative_half_interface_count": pq.ParquetFile(
+ data_dir / INTERFACE_HALF_REPRESENTATIVES_RELATIVE
+ ).metadata.num_rows,
+ }
+ write_json_atomic(data_dir / INTERFACE_REPRESENTATIVES_MANIFEST_RELATIVE, payload)
+ LOG.info(
+ "make_interface_representatives: complete interfaces=%d "
+ "representatives=%d half_representatives=%d reduction=%.2fx "
+ "elapsed_seconds=%.1f",
+ payload["interface_count"],
+ payload["representative_interface_count"],
+ payload["representative_half_interface_count"],
+ (
+ payload["interface_count"] / payload["representative_interface_count"]
+ if payload["representative_interface_count"]
+ else 1.0
+ ),
+ time.monotonic() - started,
+ )
+ return payload
-def run_batch_searches(
- *,
+def _ligand_pocket_representative_source_signatures(
data_dir: Path,
- # TODO: : use large batches for run_batch_searches
- pdb_ids: list[str],
- scorer_cfg: DictConfig,
-) -> None:
- scorer, entry_ids, batch_db_dir = utils.get_scorer(
- data_dir=data_dir,
- pdb_ids=pdb_ids,
- scorer_cfg=scorer_cfg,
- load_entries=True,
- )
- # TODO: convert get_similarity_scores.run_alignment to
- # accept FoldseekConfig / MMSeqsConfig
- for search_db in scorer_cfg.sub_databases:
- LOG.info(f"make_scorers: run_alignments for {search_db}")
- scorer.run_alignments(
- entry_ids=entry_ids,
- output_folder=batch_db_dir,
- overwrite=True,
- search_db=search_db,
- )
- rmtree(batch_db_dir)
+) -> dict[str, dict[str, int | str]]:
+ signatures: dict[str, dict[str, int | str]] = {}
+ for name in ["annotation_table.parquet", "entry_chains.parquet"]:
+ path = data_dir / "index" / name
+ stat = path.stat()
+ signatures[name] = {
+ "name": name,
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ }
+ return signatures
-def scatter_missing_scores(
- *,
+def _completed_ligand_pocket_representatives(
data_dir: Path,
- batch_size: int,
-) -> list[list[str]]:
- present = utils.get_pdb_ids_in_scoring_dataset(data_dir=data_dir)
- alns = utils.get_alns(data_dir=data_dir, mapped=True)
- rerun = set()
- for search_db, pdb_ids in present.items():
- aln_foldseek = alns[search_db]["foldseek"]
- aln_mmseqs = alns[search_db]["mmseqs"]
- aln = set(aln_foldseek).union(aln_mmseqs)
- rerun |= aln.difference(pdb_ids)
- run = sorted(rerun)
- return [run[pos : pos + batch_size] for pos in range(0, len(run), batch_size)]
+) -> dict[str, Any] | None:
+ manifest = read_json_cache(
+ data_dir / LIGAND_POCKET_REPRESENTATIVES_MANIFEST_RELATIVE
+ )
+ expected = {
+ "representatives": (
+ LIGAND_POCKET_REPRESENTATIVES_RELATIVE,
+ schemas.LIGAND_POCKET_REPRESENTATIVE_SCHEMA,
+ ),
+ "membership": (
+ LIGAND_POCKET_MEMBERSHIP_RELATIVE,
+ schemas.LIGAND_POCKET_MEMBERSHIP_SCHEMA,
+ ),
+ "residues": (
+ LIGAND_POCKET_RESIDUES_RELATIVE,
+ schemas.LIGAND_POCKET_RESIDUE_SCHEMA,
+ ),
+ }
+ try:
+ if (
+ manifest is None
+ or manifest.get("residue_selection") != LIGAND_POCKET_RESIDUE_SELECTION
+ or manifest.get("sources")
+ != _ligand_pocket_representative_source_signatures(data_dir)
+ ):
+ return None
+ for key, (relative, schema) in expected.items():
+ path = data_dir / relative
+ if not pq.read_schema(path).equals(schema) or manifest.get(
+ "outputs", {}
+ ).get(key) != _interface_representative_output_signature(path):
+ return None
+ except (OSError, TypeError, ValueError):
+ return None
+ return manifest
-def make_batch_scores(
+def make_ligand_pocket_representatives(
*,
data_dir: Path,
- pdb_ids: list[str],
- scorer_cfg: DictConfig,
- force_update: bool,
-) -> None:
- scorer, entry_ids, _ = utils.get_scorer(
- data_dir=data_dir,
- pdb_ids=pdb_ids,
- scorer_cfg=scorer_cfg,
+ scratch_dir: Path | None,
+ threads: int,
+ force_update: bool = False,
+ memory_limit: str = "64GB",
+) -> dict[str, Any]:
+ """Group exact protein-pocket copies and retain ligand and residue mappings."""
+ current = _completed_ligand_pocket_representatives(data_dir)
+ if not force_update and current is not None:
+ LOG.info(
+ "make_ligand_pocket_representatives: reusing %d representatives "
+ "for %d shape-comparable ligands",
+ current["representative_ligand_count"],
+ current["ligand_count"],
+ )
+ return current
+
+ import duckdb
+
+ sources = _ligand_pocket_representative_source_signatures(data_dir)
+ annotation = data_dir / "index" / "annotation_table.parquet"
+ chains = data_dir / "index" / "entry_chains.parquet"
+ working_root = (scratch_dir or data_dir / "scratch") / "ligand-representatives"
+ if working_root.exists():
+ rmtree(working_root)
+ working_root.mkdir(parents=True)
+ temporary_paths = {
+ "representatives": working_root / LIGAND_POCKET_REPRESENTATIVES_RELATIVE.name,
+ "membership": working_root / LIGAND_POCKET_MEMBERSHIP_RELATIVE.name,
+ "residues": working_root / LIGAND_POCKET_RESIDUES_RELATIVE.name,
+ }
+ started = time.monotonic()
+ LOG.info("make_ligand_pocket_representatives: grouping ligand pockets")
+ connection = duckdb.connect()
+ collate._configure_duckdb(
+ connection, threads=threads, memory_limit=memory_limit, scratch_dir=working_root
+ )
+ connection.sql(
+ dedent(
+ f"""
+ CREATE TEMP TABLE protein_receptors AS
+ SELECT entry_pdb_id, chain_asym_id, chain_auth_id
+ FROM read_parquet('{chains.as_posix()}')
+ WHERE chain_receptor_type = 'protein';
+
+ CREATE TEMP TABLE eligible_ligands AS
+ SELECT
+ entry_pdb_id,
+ system_id,
+ ligand_id,
+ ligand_asym_id,
+ coalesce(ligand_is_shape_comparable, false)
+ AS ligand_is_shape_comparable,
+ ligand_protein_chains_asym_id,
+ ligand_neighboring_residues,
+ ligand_interactions
+ FROM read_parquet('{annotation.as_posix()}')
+ WHERE system_type = 'holo' AND ligand_is_proper;
+
+ CREATE TEMP TABLE receptor_sets AS
+ SELECT
+ ligands.entry_pdb_id,
+ ligands.ligand_id,
+ list_sort(list_distinct(list(receptors.chain_asym_id)))
+ AS receptor_chain_asym_ids
+ FROM eligible_ligands AS ligands,
+ unnest(ligands.ligand_protein_chains_asym_id)
+ AS instances(instance_chain)
+ INNER JOIN protein_receptors AS receptors
+ ON ligands.entry_pdb_id = receptors.entry_pdb_id
+ AND split_part(instance_chain, '.', 2) = receptors.chain_asym_id
+ GROUP BY ligands.entry_pdb_id, ligands.ligand_id;
+
+ CREATE TEMP TABLE canonical_receptor_sets AS
+ SELECT
+ *,
+ min(ligand_id) OVER (
+ PARTITION BY entry_pdb_id, receptor_chain_asym_ids
+ )::VARCHAR AS receptor_set_id
+ FROM receptor_sets;
+
+ CREATE TEMP TABLE normalized_pockets AS
+ SELECT
+ ligands.ligand_id,
+ list_sort(list_distinct(list(
+ split_part(neighbor, '.', 2)
+ ))) AS pocket_residues
+ FROM eligible_ligands AS ligands
+ INNER JOIN canonical_receptor_sets AS receptor_sets USING (ligand_id),
+ unnest(ligands.ligand_neighboring_residues)
+ AS residues(neighbor)
+ WHERE list_contains(
+ receptor_sets.receptor_chain_asym_ids,
+ split_part(split_part(neighbor, '.', 2), '_', 1)
+ )
+ GROUP BY ligands.ligand_id;
+
+ CREATE TEMP TABLE normalized_interactions AS
+ SELECT
+ ligands.ligand_id,
+ list_sort(list(split_part(interaction, '.', 2))) AS interactions
+ FROM eligible_ligands AS ligands
+ INNER JOIN canonical_receptor_sets AS receptor_sets USING (ligand_id),
+ unnest(ligands.ligand_interactions)
+ AS interaction_rows(interaction)
+ WHERE list_contains(
+ receptor_sets.receptor_chain_asym_ids,
+ split_part(split_part(interaction, '.', 2), '_', 1)
+ )
+ GROUP BY ligands.ligand_id;
+
+ CREATE TEMP TABLE normalized_ligands AS
+ SELECT
+ ligands.entry_pdb_id,
+ ligands.system_id,
+ ligands.ligand_id,
+ ligands.ligand_asym_id,
+ ligands.ligand_is_shape_comparable,
+ receptors.receptor_set_id,
+ receptors.receptor_chain_asym_ids,
+ coalesce(pockets.pocket_residues, []::VARCHAR[])
+ AS pocket_residues,
+ coalesce(interactions.interactions, []::VARCHAR[])
+ AS interactions
+ FROM eligible_ligands AS ligands
+ INNER JOIN canonical_receptor_sets AS receptors USING (ligand_id)
+ LEFT JOIN normalized_pockets AS pockets USING (ligand_id)
+ LEFT JOIN normalized_interactions AS interactions USING (ligand_id);
+
+ CREATE TEMP TABLE representative_groups AS
+ SELECT
+ min(ligand_id)::VARCHAR AS representative_ligand_id,
+ arg_min(system_id, ligand_id)::VARCHAR AS representative_system_id,
+ entry_pdb_id,
+ ligand_asym_id,
+ ligand_is_shape_comparable,
+ receptor_set_id,
+ receptor_chain_asym_ids,
+ pocket_residues,
+ interactions
+ FROM normalized_ligands
+ GROUP BY
+ entry_pdb_id,
+ ligand_asym_id,
+ ligand_is_shape_comparable,
+ receptor_set_id,
+ receptor_chain_asym_ids,
+ pocket_residues,
+ interactions;
+
+ COPY (
+ SELECT * FROM representative_groups
+ ORDER BY representative_ligand_id
+ ) TO '{temporary_paths["representatives"].as_posix()}' (
+ FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 100000
+ );
+
+ COPY (
+ SELECT
+ ligands.system_id,
+ ligands.ligand_id,
+ representatives.representative_system_id,
+ representatives.representative_ligand_id
+ FROM normalized_ligands AS ligands
+ INNER JOIN representative_groups AS representatives
+ ON ligands.entry_pdb_id = representatives.entry_pdb_id
+ AND ligands.ligand_asym_id = representatives.ligand_asym_id
+ AND ligands.ligand_is_shape_comparable
+ = representatives.ligand_is_shape_comparable
+ AND ligands.receptor_set_id = representatives.receptor_set_id
+ AND ligands.receptor_chain_asym_ids
+ = representatives.receptor_chain_asym_ids
+ AND ligands.pocket_residues = representatives.pocket_residues
+ AND ligands.interactions = representatives.interactions
+ ORDER BY ligands.ligand_id
+ ) TO '{temporary_paths["membership"].as_posix()}' (
+ FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 100000
+ );
+
+ COPY (
+ WITH interaction_residues AS (
+ SELECT DISTINCT
+ ligands.ligand_id,
+ split_part(interaction, '_', 1) AS chain_instance,
+ try_cast(split_part(interaction, '_', 2) AS INTEGER)
+ AS residue_label_seq_id
+ FROM eligible_ligands AS ligands,
+ unnest(ligands.ligand_interactions)
+ AS interaction_rows(interaction)
+ WHERE try_cast(split_part(interaction, '_', 2) AS INTEGER)
+ IS NOT NULL
+ ),
+ parsed_pockets AS (
+ SELECT
+ ligands.entry_pdb_id,
+ ligands.system_id,
+ ligands.ligand_id,
+ split_part(residue, '_', 1) AS chain_instance,
+ split_part(split_part(residue, '_', 1), '.', 2)
+ AS chain_asym_id,
+ try_cast(split_part(residue, '_', 2) AS INTEGER)
+ AS residue_label_seq_id,
+ try_cast(split_part(residue, '_', 3) AS INTEGER)
+ AS residue_index,
+ coalesce(
+ nullif(split_part(residue, '_', 4), ''),
+ split_part(residue, '_', 2)
+ ) AS residue_auth_seq_id,
+ coalesce(
+ nullif(split_part(residue, '_', 5), ''), '.'
+ ) AS residue_insertion_code
+ FROM eligible_ligands AS ligands,
+ unnest(ligands.ligand_neighboring_residues)
+ AS pocket_rows(residue)
+ )
+ SELECT DISTINCT
+ pockets.entry_pdb_id::VARCHAR AS entry_pdb_id,
+ pockets.system_id::VARCHAR AS system_id,
+ pockets.ligand_id::VARCHAR AS ligand_id,
+ pockets.chain_instance::VARCHAR AS chain_instance,
+ pockets.chain_asym_id::VARCHAR AS chain_asym_id,
+ receptors.chain_auth_id::VARCHAR AS chain_auth_id,
+ pockets.residue_label_seq_id::INTEGER
+ AS residue_label_seq_id,
+ pockets.residue_index::INTEGER AS residue_index,
+ pockets.residue_auth_seq_id::VARCHAR AS residue_auth_seq_id,
+ pockets.residue_insertion_code::VARCHAR
+ AS residue_insertion_code,
+ (interactions.ligand_id IS NOT NULL)::BOOLEAN AS is_pli
+ FROM parsed_pockets AS pockets
+ INNER JOIN protein_receptors AS receptors
+ ON pockets.entry_pdb_id = receptors.entry_pdb_id
+ AND pockets.chain_asym_id = receptors.chain_asym_id
+ LEFT JOIN interaction_residues AS interactions
+ ON pockets.ligand_id = interactions.ligand_id
+ AND pockets.chain_instance = interactions.chain_instance
+ AND pockets.residue_label_seq_id
+ = interactions.residue_label_seq_id
+ WHERE pockets.residue_label_seq_id IS NOT NULL
+ AND pockets.residue_index IS NOT NULL
+ ORDER BY
+ pockets.ligand_id,
+ pockets.chain_instance,
+ pockets.residue_label_seq_id
+ ) TO '{temporary_paths["residues"].as_posix()}' (
+ FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 100000
+ );
+ """
+ )
+ )
+ connection.close()
+ LOG.info(
+ "make_ligand_pocket_representatives: DuckDB grouping complete "
+ "elapsed_seconds=%.1f",
+ time.monotonic() - started,
+ )
+
+ expected = {
+ "representatives": (
+ LIGAND_POCKET_REPRESENTATIVES_RELATIVE,
+ schemas.LIGAND_POCKET_REPRESENTATIVE_SCHEMA,
+ ),
+ "membership": (
+ LIGAND_POCKET_MEMBERSHIP_RELATIVE,
+ schemas.LIGAND_POCKET_MEMBERSHIP_SCHEMA,
+ ),
+ "residues": (
+ LIGAND_POCKET_RESIDUES_RELATIVE,
+ schemas.LIGAND_POCKET_RESIDUE_SCHEMA,
+ ),
+ }
+ for key, (_, schema) in expected.items():
+ observed = pq.read_schema(temporary_paths[key])
+ if not observed.equals(schema):
+ rmtree(working_root)
+ raise ValueError(
+ f"ligand pocket representative {key} has unexpected schema: {observed}"
+ )
+ ligand_count = pq.ParquetFile(temporary_paths["membership"]).metadata.num_rows
+ representative_count = pq.ParquetFile(
+ temporary_paths["representatives"]
+ ).metadata.num_rows
+ pocket_residue_count = pq.ParquetFile(temporary_paths["residues"]).metadata.num_rows
+ if _ligand_pocket_representative_source_signatures(data_dir) != sources:
+ rmtree(working_root)
+ raise RuntimeError("entry indexes changed while making ligand representatives")
+
+ outputs: dict[str, dict[str, int | str]] = {}
+ for key, (relative, _) in expected.items():
+ target = data_dir / relative
+ target.parent.mkdir(parents=True, exist_ok=True)
+ install = target.with_suffix(target.suffix + ".tmp")
+ copyfile(temporary_paths[key], install)
+ install.replace(target)
+ outputs[key] = _interface_representative_output_signature(target)
+ rmtree(working_root)
+ payload = {
+ "status": "complete",
+ "residue_selection": LIGAND_POCKET_RESIDUE_SELECTION,
+ "sources": sources,
+ "outputs": outputs,
+ "ligand_count": ligand_count,
+ "representative_ligand_count": representative_count,
+ "pocket_residue_count": pocket_residue_count,
+ }
+ write_json_atomic(
+ data_dir / LIGAND_POCKET_REPRESENTATIVES_MANIFEST_RELATIVE,
+ payload,
+ )
+ LOG.info(
+ "make_ligand_pocket_representatives: complete ligands=%d "
+ "representatives=%d reduction=%.2fx elapsed_seconds=%.1f",
+ ligand_count,
+ representative_count,
+ ligand_count / representative_count if representative_count else 1.0,
+ time.monotonic() - started,
+ )
+ return payload
+
+
+def _completed_alignment_chain_lookup(
+ data_dir: Path,
+) -> dict[str, int | str] | None:
+ lookup = data_dir / ALIGNMENT_CHAIN_LOOKUP_RELATIVE
+ manifest = data_dir / ALIGNMENT_CHAIN_LOOKUP_MANIFEST_RELATIVE
+ try:
+ if (
+ _completed_ligand_pocket_representatives(data_dir) is None
+ or _completed_interface_representatives(data_dir) is None
+ ):
+ return None
+ stat = lookup.stat()
+ columns = set(pq.read_schema(lookup).names)
+ input_signatures = _alignment_chain_lookup_input_signatures(data_dir)
+ except (OSError, TypeError, ValueError):
+ return None
+ expected_columns = {
+ "entry_pdb_id",
+ "chain_asym_id",
+ "chain_auth_id",
+ "selected_residue_numbers",
+ "selected_residue_indices",
+ }
+ output: dict[str, int | str] = {
+ "name": lookup.name,
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ }
+ if not expected_columns.issubset(columns):
+ return None
+ try:
+ payload = json.loads(manifest.read_text())
+ except (OSError, TypeError, ValueError):
+ return None
+ if payload.get("inputs") != input_signatures or payload.get("output") != output:
+ return None
+ return output
+
+
+def _alignment_chain_lookup_input_signatures(
+ data_dir: Path,
+) -> dict[str, dict[str, int | str]]:
+ signatures: dict[str, dict[str, int | str]] = {}
+ for name in [
+ LIGAND_POCKET_REPRESENTATIVES_RELATIVE.name,
+ INTERFACE_HALF_REPRESENTATIVES_RELATIVE.name,
+ "entry_chains.parquet",
+ ]:
+ path = data_dir / "index" / name
+ stat = path.stat()
+ signatures[name] = {
+ "name": name,
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ }
+ return signatures
+
+
+def _write_alignment_chain_lookup_manifest(data_dir: Path) -> None:
+ lookup = data_dir / ALIGNMENT_CHAIN_LOOKUP_RELATIVE
+ stat = lookup.stat()
+ manifest = data_dir / ALIGNMENT_CHAIN_LOOKUP_MANIFEST_RELATIVE
+ temporary = manifest.with_suffix(manifest.suffix + ".tmp")
+ temporary.write_text(
+ json.dumps(
+ {
+ "inputs": _alignment_chain_lookup_input_signatures(data_dir),
+ "output": {
+ "name": lookup.name,
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ },
+ },
+ indent=2,
+ sort_keys=True,
+ )
+ + "\n"
+ )
+ temporary.replace(manifest)
+
+
+def _refresh_representative_source_manifests(data_dir: Path) -> None:
+ """Record index-only enrichments without rebuilding unchanged representatives."""
+ ligand_manifest_path = data_dir / LIGAND_POCKET_REPRESENTATIVES_MANIFEST_RELATIVE
+ ligand_manifest = read_json_cache(ligand_manifest_path)
+ interface_manifest_path = data_dir / INTERFACE_REPRESENTATIVES_MANIFEST_RELATIVE
+ interface_manifest = read_json_cache(interface_manifest_path)
+ if ligand_manifest is None or interface_manifest is None:
+ raise RuntimeError(
+ "representative source manifests disappeared during finalization"
+ )
+ ligand_manifest["sources"] = _ligand_pocket_representative_source_signatures(
+ data_dir
+ )
+ interface_manifest["source"] = _interface_representative_source_signature(data_dir)
+ write_json_atomic(ligand_manifest_path, ligand_manifest)
+ write_json_atomic(interface_manifest_path, interface_manifest)
+
+
+def make_alignment_chain_lookup(
+ *,
+ data_dir: Path,
+ scratch_dir: Path | None,
+ threads: int,
+ force_update: bool = False,
+ memory_limit: str = "64GB",
+) -> Path:
+ """Build the compact chain and selected-residue map used by every shard."""
+ make_ligand_pocket_representatives(
+ data_dir=data_dir,
+ scratch_dir=scratch_dir,
+ threads=threads,
+ force_update=force_update,
+ memory_limit=memory_limit,
+ )
+ make_interface_representatives(
+ data_dir=data_dir,
+ scratch_dir=scratch_dir,
+ threads=threads,
+ force_update=force_update,
+ memory_limit=memory_limit,
+ )
+ lookup = data_dir / ALIGNMENT_CHAIN_LOOKUP_RELATIVE
+ if not force_update and _completed_alignment_chain_lookup(data_dir) is not None:
+ manifest = data_dir / ALIGNMENT_CHAIN_LOOKUP_MANIFEST_RELATIVE
+ if not manifest.is_file():
+ _write_alignment_chain_lookup_manifest(data_dir)
+ LOG.info(f"make_alignment_chain_lookup: reusing {lookup}")
+ return lookup
+
+ import duckdb
+
+ input_signatures = _alignment_chain_lookup_input_signatures(data_dir)
+ working_root = (scratch_dir or data_dir / "scratch") / "alignment-chain-lookup"
+ working_root.mkdir(exist_ok=True, parents=True)
+ temporary = working_root / lookup.name
+ temporary.unlink(missing_ok=True)
+ ligand_representatives = (
+ data_dir / LIGAND_POCKET_REPRESENTATIVES_RELATIVE
+ ).as_posix()
+ interfaces = (data_dir / INTERFACE_HALF_REPRESENTATIVES_RELATIVE).as_posix()
+ chains = (data_dir / "index" / "entry_chains.parquet").as_posix()
+ con = duckdb.connect()
+ collate._configure_duckdb(
+ con, threads=threads, memory_limit=memory_limit, scratch_dir=working_root
+ )
+ con.sql(
+ dedent(
+ f"""
+ COPY (
+ WITH protein_chains AS (
+ SELECT entry_pdb_id, chain_asym_id, chain_auth_id
+ FROM read_parquet('{chains}')
+ WHERE chain_receptor_type = 'protein'
+ AND chain_auth_id IS NOT NULL
+ ),
+ ligand_pocket_residues AS (
+ SELECT
+ representatives.entry_pdb_id,
+ split_part(neighbor, '_', 1) AS chain_asym_id,
+ CAST(split_part(neighbor, '_', 2) AS INTEGER)
+ AS residue_number,
+ CAST(split_part(neighbor, '_', 3) AS INTEGER)
+ AS residue_index
+ FROM read_parquet('{ligand_representatives}')
+ AS representatives,
+ UNNEST(representatives.pocket_residues)
+ AS residues(neighbor)
+ ),
+ interface_residues AS (
+ SELECT
+ entry_pdb_id,
+ chain_asym_id,
+ unnest(residue_numbers)
+ AS residue_number,
+ unnest(residue_indices)
+ AS residue_index
+ FROM read_parquet('{interfaces}')
+ ),
+ selected_residues AS (
+ SELECT * FROM ligand_pocket_residues
+ UNION ALL
+ SELECT * FROM interface_residues
+ ),
+ canonical_selected_residues AS (
+ SELECT
+ entry_pdb_id,
+ chain_asym_id,
+ residue_index,
+ min(residue_number) AS residue_number
+ FROM selected_residues
+ GROUP BY entry_pdb_id, chain_asym_id, residue_index
+ ),
+ selected_mapping AS (
+ SELECT
+ entry_pdb_id,
+ chain_asym_id,
+ list(residue_number ORDER BY residue_index)
+ AS selected_residue_numbers,
+ list(residue_index ORDER BY residue_index)
+ AS selected_residue_indices
+ FROM canonical_selected_residues
+ GROUP BY entry_pdb_id, chain_asym_id
+ )
+ SELECT
+ c.entry_pdb_id,
+ c.chain_asym_id,
+ c.chain_auth_id,
+ coalesce(p.selected_residue_numbers, []::INTEGER[])
+ AS selected_residue_numbers,
+ coalesce(p.selected_residue_indices, []::INTEGER[])
+ AS selected_residue_indices
+ FROM protein_chains c
+ LEFT JOIN selected_mapping p
+ USING (entry_pdb_id, chain_asym_id)
+ ORDER BY c.entry_pdb_id, c.chain_asym_id
+ ) TO '{temporary.as_posix()}'
+ (FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 100_000);
+ """
+ )
+ )
+ lookup_is_unchanged = False
+ if lookup.is_file():
+ lookup_schema = pq.read_schema(lookup)
+ temporary_schema = pq.read_schema(temporary)
+ if lookup_schema.equals(temporary_schema):
+ difference_count = con.sql(
+ dedent(
+ f"""
+ SELECT count(*) FROM (
+ (SELECT * FROM read_parquet('{lookup.as_posix()}')
+ EXCEPT ALL
+ SELECT * FROM read_parquet('{temporary.as_posix()}'))
+ UNION ALL
+ (SELECT * FROM read_parquet('{temporary.as_posix()}')
+ EXCEPT ALL
+ SELECT * FROM read_parquet('{lookup.as_posix()}'))
+ )
+ """
+ )
+ ).fetchone()
+ lookup_is_unchanged = difference_count == (0,)
+ con.close()
+ if _alignment_chain_lookup_input_signatures(data_dir) != input_signatures:
+ temporary.unlink(missing_ok=True)
+ raise RuntimeError("entry indexes changed while building chain lookup")
+ if lookup_is_unchanged:
+ temporary.unlink(missing_ok=True)
+ _write_alignment_chain_lookup_manifest(data_dir)
+ LOG.info(
+ "make_alignment_chain_lookup: refreshed unchanged lookup input signatures"
+ )
+ return lookup
+ lookup.parent.mkdir(exist_ok=True, parents=True)
+ install_path = lookup.with_suffix(lookup.suffix + ".tmp")
+ copyfile(temporary, install_path)
+ install_path.replace(lookup)
+ temporary.unlink(missing_ok=True)
+ _write_alignment_chain_lookup_manifest(data_dir)
+ return lookup
+
+
+def compute_ligand_fingerprints(
+ *,
+ data_dir: Path,
+ cofactor_similarity_threshold: float = 90.0,
+ retain_score_shards: bool = False,
+) -> None:
+ """Fingerprint unique ligand SMILES and annotate cofactor similarity."""
+ LOG.info("compute_ligand_fingerprints: running")
+ get_similarity_scores.compute_ligand_fingerprints(
+ data_dir=data_dir,
+ cofactor_similarity_threshold=cofactor_similarity_threshold,
+ retain_score_shards=retain_score_shards,
+ )
+
+
+def scatter_make_ligand_scores(
+ *,
+ data_dir: Path,
+ batch_size: int,
+ number_id_col: str = "ligand_smiles_id",
+) -> list[list[int]]:
+ """Scatter the unique-SMILES fingerprint node IDs."""
+ ligands = pd.read_parquet(
+ data_dir / "fingerprints" / "ligands_per_smiles.parquet",
+ columns=[number_id_col],
+ )[number_id_col].to_list()
+ LOG.info(f"scatter_make_ligand_scores: found {len(ligands)} ligands")
+ chunks = [
+ ligands[pos : pos + batch_size] for pos in range(0, len(ligands), batch_size)
+ ]
+ return chunks or [[]]
+
+
+def make_ligand_scores(
+ *,
+ data_dir: Path,
+ ligand_ids: list[int],
+ minimum_similarity: float = 30.0,
+ number_id_col: str = "ligand_smiles_id",
+) -> None:
+ if not ligand_ids:
+ LOG.info("make_ligand_scores: no ligand nodes to score")
+ return
+ hashid = utils.hash_contents([str(i) for i in ligand_ids])
+ output_path = data_dir / "ligand_scores" / f"{hashid}.parquet"
+ output_path.parent.mkdir(exist_ok=True, parents=True)
+ get_similarity_scores.ligand_scores(
+ ligand_ids=ligand_ids,
+ data_dir=data_dir,
+ output_path=output_path,
+ number_id_col=number_id_col,
+ minimum_similarity=minimum_similarity,
+ )
+
+
+def scatter_make_mhfp6_scores(
+ *,
+ data_dir: Path,
+ batch_size: int,
+ number_id_col: str = "ligand_smiles_id",
+) -> list[list[int]]:
+ """Scatter the unique-SMILES MHFP6 fingerprint node IDs."""
+ ligands = pd.read_parquet(
+ data_dir / "fingerprints" / get_similarity_scores.MHFP6_FINGERPRINT_FILE,
+ columns=[number_id_col],
+ )[number_id_col].to_list()
+ LOG.info(f"scatter_make_mhfp6_scores: found {len(ligands)} ligands")
+ chunks = [
+ ligands[pos : pos + batch_size] for pos in range(0, len(ligands), batch_size)
+ ]
+ return chunks or [[]]
+
+
+def make_mhfp6_scores(
+ *,
+ data_dir: Path,
+ ligand_ids: list[int],
+ minimum_similarity: float = 30.0,
+ number_id_col: str = "ligand_smiles_id",
+) -> None:
+ if not ligand_ids:
+ LOG.info("make_mhfp6_scores: no ligand nodes to score")
+ return
+ hashid = utils.hash_contents([str(i) for i in ligand_ids])
+ output_path = (
+ data_dir / get_similarity_scores.MHFP6_SCORES_DIR / f"{hashid}.parquet"
+ )
+ output_path.parent.mkdir(exist_ok=True, parents=True)
+ get_similarity_scores.mhfp6_ligand_scores(
+ ligand_ids=ligand_ids,
+ data_dir=data_dir,
+ output_path=output_path,
+ number_id_col=number_id_col,
+ minimum_similarity=minimum_similarity,
+ )
+
+
+def annotate_ligand_similarity(
+ *,
+ data_dir: Path,
+ minimum_similarity: float = 30.0,
+ number_id_col: str = "ligand_smiles_id",
+) -> None:
+ """Write ligand identifiers and cofactor annotations."""
+ get_similarity_scores.annotate_ligand_similarity(
+ data_dir=data_dir,
+ minimum_similarity=minimum_similarity,
+ number_id_col=number_id_col,
+ )
+
+
+def make_ligand_mmp_pairs(
+ *,
+ data_dir: Path,
+ scratch_dir: Path,
+ threads: int,
+ force_update: bool = False,
+) -> Path:
+ """Write the unique-SMILES matched-molecular-pair release table."""
+ return mmpdb_utils.make_ligand_mmp_pairs(
+ data_dir=data_dir,
+ scratch_dir=scratch_dir,
+ threads=threads,
+ force_update=force_update,
+ )
+
+
+def make_ccd_ligand_dbs(
+ *,
+ data_dir: Path,
+ scratch_dir: Path,
+ threads: int,
+ force_update: bool = False,
+ minimum_similarity: float = 30.0,
+ build_parity_scores: bool = False,
+) -> Path:
+ """Build the CCD-anchored MMP/ECFP4 databases and the ligand-to-CCD match sidecar."""
+ ccd_ligand_dbs.make_ccd_ligand_dbs(
+ data_dir=data_dir,
+ scratch_dir=scratch_dir,
+ threads=threads,
+ force_update=force_update,
+ minimum_similarity=minimum_similarity,
+ build_parity_scores=build_parity_scores,
+ )
+ return ccd_ligand_dbs.make_ligand_ccd_match(data_dir=data_dir)
+
+
+def _interface_scoring_chain_keys(data_dir: Path) -> pd.DataFrame:
+ """Return entry/asym keys used by a published protein interface."""
+ interface_path = data_dir / "index" / "interface_annotation_table.parquet"
+ if not interface_path.is_file():
+ return pd.DataFrame(
+ columns=["entry_pdb_id", "chain_asym_id", "chain_is_interface"]
+ )
+ interfaces = pd.read_parquet(
+ interface_path,
+ columns=["entry_pdb_id", "interface_chain_1", "interface_chain_2"],
+ )
+ interface_keys = pd.concat(
+ [
+ interfaces[["entry_pdb_id", column]].rename(
+ columns={column: "instance_chain"}
+ )
+ for column in ["interface_chain_1", "interface_chain_2"]
+ ],
+ ignore_index=True,
+ )
+ interface_keys["chain_asym_id"] = (
+ interface_keys.pop("instance_chain").astype(str).str.split(".", n=1).str[-1]
+ )
+ interface_keys = interface_keys.drop_duplicates()
+ interface_keys["chain_is_interface"] = True
+ return interface_keys
+
+
+def _protein_scoring_chains(data_dir: Path) -> pd.DataFrame:
+ """Return protein chains used by a ligand receptor or protein interface."""
+ chain_path = data_dir / "index" / "entry_chains.parquet"
+ chains = pd.read_parquet(
+ chain_path,
+ columns=[
+ "entry_pdb_id",
+ "chain_asym_id",
+ "chain_receptor_type",
+ "chain_is_holo",
+ ],
+ )
+ chains = chains.merge(
+ _interface_scoring_chain_keys(data_dir),
+ on=["entry_pdb_id", "chain_asym_id"],
+ how="left",
+ )
+ return chains.loc[
+ chains["chain_receptor_type"].fillna("").astype(str).eq("protein")
+ & (
+ chains["chain_is_holo"].fillna(False).astype(bool)
+ | chains["chain_is_interface"].eq(True)
+ )
+ ].copy()
+
+
+def _monomer_scoring_chains(data_dir: Path) -> pd.DataFrame:
+ """Return protein chains absent from pocket/interface search targets."""
+ chains = pd.read_parquet(
+ data_dir / "index" / "entry_chains.parquet",
+ columns=[
+ "entry_pdb_id",
+ "chain_asym_id",
+ "chain_auth_id",
+ "chain_receptor_type",
+ "chain_is_ligand_like",
+ ],
+ )
+ chains = chains.loc[
+ chains["chain_receptor_type"].eq("protein")
+ & ~chains["chain_is_ligand_like"].fillna(False).astype(bool)
+ & chains["chain_auth_id"].notna()
+ ]
+ holo = _protein_scoring_chains(data_dir)[["entry_pdb_id", "chain_asym_id"]]
+ return (
+ chains.merge(
+ holo.drop_duplicates(),
+ on=["entry_pdb_id", "chain_asym_id"],
+ how="left",
+ indicator=True,
+ )
+ .loc[lambda rows: rows["_merge"].eq("left_only")]
+ .drop(columns="_merge")
+ )
+
+
+def _ligand_apo_query_chains(data_dir: Path) -> pd.DataFrame:
+ """Return proper-ligand protein receptor chains used as apo queries."""
+ from plinder.data.linked_apo import ligand_holo_chain_keys
+
+ holo_keys = ligand_holo_chain_keys(data_dir / "index" / "annotation_table.parquet")
+ chains = pd.read_parquet(
+ data_dir / "index" / "entry_chains.parquet",
+ columns=[
+ "entry_pdb_id",
+ "chain_asym_id",
+ "chain_auth_id",
+ "chain_receptor_type",
+ ],
+ )
+ chains = chains.merge(
+ holo_keys,
+ on=["entry_pdb_id", "chain_asym_id"],
+ how="inner",
+ validate="one_to_one",
+ )
+ return (
+ chains.loc[
+ chains["chain_receptor_type"]
+ .fillna("")
+ .astype(str)
+ .str.lower()
+ .eq("protein")
+ & chains["chain_auth_id"].notna(),
+ ["entry_pdb_id", "chain_asym_id", "chain_auth_id"],
+ ]
+ .drop_duplicates(ignore_index=True)
+ .sort_values(["entry_pdb_id", "chain_asym_id"], ignore_index=True)
+ )
+
+
+def _linked_apo_query_chains(data_dir: Path) -> pd.DataFrame:
+ """Return the union of ligand-pocket and protein-interface apo queries."""
+ ligand_queries = _ligand_apo_query_chains(data_dir)
+ interface_queries = _interface_apo_query_chains(data_dir)
+ return (
+ pd.concat([ligand_queries, interface_queries], ignore_index=True)
+ .drop_duplicates(["entry_pdb_id", "chain_asym_id"], ignore_index=True)
+ .sort_values(["entry_pdb_id", "chain_asym_id"], ignore_index=True)
+ )
+
+
+def _interface_apo_query_chains(data_dir: Path) -> pd.DataFrame:
+ """Return protein chains used by a published protein interface."""
+ interface_keys = _interface_scoring_chain_keys(data_dir)
+ if interface_keys.empty:
+ return pd.DataFrame(columns=["entry_pdb_id", "chain_asym_id", "chain_auth_id"])
+ chains = pd.read_parquet(
+ data_dir / "index" / "entry_chains.parquet",
+ columns=[
+ "entry_pdb_id",
+ "chain_asym_id",
+ "chain_auth_id",
+ "chain_receptor_type",
+ ],
+ )
+ chains = chains.merge(
+ interface_keys[["entry_pdb_id", "chain_asym_id"]],
+ on=["entry_pdb_id", "chain_asym_id"],
+ how="inner",
+ validate="one_to_one",
+ )
+ return (
+ chains.loc[
+ chains["chain_receptor_type"]
+ .fillna("")
+ .astype(str)
+ .str.lower()
+ .eq("protein")
+ & chains["chain_auth_id"].notna(),
+ ["entry_pdb_id", "chain_asym_id", "chain_auth_id"],
+ ]
+ .drop_duplicates(ignore_index=True)
+ .sort_values(["entry_pdb_id", "chain_asym_id"], ignore_index=True)
+ )
+
+
+def _apo_query_auth_ids(
+ data_dir: Path, pdb_ids: Sequence[str], *, search_db: str
+) -> dict[str, set[str]]:
+ """Load query chain IDs for one of the two apo searches."""
+ from plinder.data.pipeline.score import (
+ INTERFACE_APO_QUERY_MANIFEST_RELATIVE,
+ LINKED_APO_QUERY_MANIFEST_RELATIVE,
+ )
+
+ relative = (
+ LINKED_APO_QUERY_MANIFEST_RELATIVE
+ if search_db == "apo"
+ else INTERFACE_APO_QUERY_MANIFEST_RELATIVE
+ )
+ manifest = data_dir / relative
+ if pq.ParquetFile(manifest).metadata.num_rows == 0:
+ return {}
+ chains = pd.read_parquet(
+ manifest,
+ columns=["pdb_id", "chain_auth_id"],
+ filters=[("pdb_id", "in", list(pdb_ids))],
+ ).rename(columns={"pdb_id": "entry_pdb_id"})
+ return {
+ str(pdb_id): set(rows["chain_auth_id"].astype(str))
+ for pdb_id, rows in chains.groupby("entry_pdb_id", sort=False)
+ }
+
+
+def _apo_search_signature(
+ data_dir: Path,
+ *,
+ pdb_id: str,
+ search_db: str,
+ alignment_type: str,
+ query_chain_auth_ids: set[str],
+ search_settings: dict[str, float | int],
+) -> dict[str, Any]:
+ """Describe the inputs and settings used by an apo search."""
+ selection_path = (
+ data_dir / "dbs" / "subdbs" / f"{search_db}_{alignment_type}" / "selection.json"
+ )
+ selection = read_json_cache(selection_path)
+ if not isinstance(selection, dict):
+ raise FileNotFoundError(
+ f"missing apo target selection metadata: {selection_path}"
+ )
+ target_database = selection.get("target_database")
+ if not isinstance(target_database, dict) or not target_database.get("sha256"):
+ raise ValueError(
+ f"apo target selection lacks a content fingerprint: {selection_path}"
+ )
+ target_selection = {
+ key: value for key, value in selection.items() if key != "source_lookup"
+ }
+ return {
+ "query_entry": pdb_id,
+ "query_chain_auth_ids": sorted(query_chain_auth_ids),
+ "search_settings": search_settings,
+ "target_selection": target_selection,
+ }
+
+
+def _apo_search_settings(config: DictConfig) -> dict[str, float | int]:
+ """Return the command settings that affect an apo alignment search."""
+ return {
+ "evalue": float(config.evalue),
+ "sensitivity": float(config.sensitivity),
+ "max_seqs": int(config.max_seqs),
+ "coverage": get_similarity_scores.APO_SEARCH_COVERAGE,
+ "min_seq_id": get_similarity_scores.APO_SEARCH_MIN_SEQ_ID,
+ }
+
+
+def _apo_search_metadata(signature: dict[str, Any]) -> bytes:
+ return json.dumps(signature, sort_keys=True, separators=(",", ":")).encode()
+
+
+def _apo_search_is_current(output: Path, signature: dict[str, Any]) -> bool:
+ metadata = pq.read_schema(output).metadata or {}
+ encoded = metadata.get(APO_SEARCH_METADATA_KEY)
+ if encoded is None:
+ raise ValueError(f"apo search output is missing input metadata: {output}")
+ stored = json.loads(encoded)
+ if not isinstance(stored, dict):
+ raise ValueError(f"apo search output has invalid input metadata: {output}")
+ return stored == signature
+
+
+def _apo_scoring_chains(data_dir: Path) -> pd.DataFrame:
+ """Return candidate chains for ligand-relative apo links."""
+ from plinder.data.linked_apo import ligand_holo_chain_keys
+
+ if _ligand_apo_query_chains(data_dir).empty:
+ return pd.DataFrame(columns=["entry_pdb_id", "chain_asym_id", "chain_auth_id"])
+ chains = pd.read_parquet(
+ data_dir / "index" / "entry_chains.parquet",
+ columns=[
+ "entry_pdb_id",
+ "chain_asym_id",
+ "chain_auth_id",
+ "chain_entity_id",
+ "chain_receptor_type",
+ "chain_is_ligand_like",
+ ],
+ )
+ holo_keys = ligand_holo_chain_keys(data_dir / "index" / "annotation_table.parquet")
+ holo_keys["chain_is_holo"] = True
+ chains = chains.merge(
+ holo_keys,
+ on=["entry_pdb_id", "chain_asym_id"],
+ how="left",
+ validate="one_to_one",
+ )
+ holo = chains["chain_is_holo"].eq(True)
+ entity_ids = chains["chain_entity_id"].astype("string")
+ usable_entity = entity_ids.notna() & entity_ids.str.strip().ne("")
+ holo_entities = chains.loc[
+ holo & usable_entity, ["entry_pdb_id", "chain_entity_id"]
+ ].drop_duplicates()
+ holo_entities["entity_is_holo"] = True
+ chains = chains.merge(
+ holo_entities,
+ on=["entry_pdb_id", "chain_entity_id"],
+ how="left",
+ validate="many_to_one",
+ )
+ chains = chains.loc[
+ chains["chain_receptor_type"].fillna("").astype(str).eq("protein")
+ & ~holo
+ & ~chains["chain_is_ligand_like"].fillna(False).astype(bool)
+ & chains["entity_is_holo"].ne(True)
+ & chains["chain_auth_id"].notna()
+ ].copy()
+ receptor_chains = pd.read_parquet(
+ data_dir / "index" / "entry_biounit_chains.parquet",
+ columns=["entry_pdb_id", "chain_asym_id", "chain_role"],
+ )
+ receptor_chains = receptor_chains.loc[
+ receptor_chains["chain_role"].fillna("").astype(str).str.lower().eq("receptor"),
+ ["entry_pdb_id", "chain_asym_id"],
+ ].drop_duplicates()
+ ligand_apo = chains.merge(
+ receptor_chains,
+ on=["entry_pdb_id", "chain_asym_id"],
+ how="inner",
+ validate="one_to_one",
+ )
+ return ligand_apo[["entry_pdb_id", "chain_asym_id", "chain_auth_id"]].sort_values(
+ ["entry_pdb_id", "chain_asym_id"], ignore_index=True
+ )
+
+
+def _interface_apo_scoring_chains(data_dir: Path) -> pd.DataFrame:
+ """Return candidate chains for interface-relative apo links."""
+ from plinder.data.interface_apo import build_interface_apo_candidate_manifest
+
+ if _interface_apo_query_chains(data_dir).empty:
+ return pd.DataFrame(columns=["entry_pdb_id", "chain_asym_id", "chain_auth_id"])
+ candidates = build_interface_apo_candidate_manifest(
+ data_dir / "index" / "entry_chains.parquet",
+ biounit_chains=data_dir / "index" / "entry_biounit_chains.parquet",
+ entry_metadata=data_dir / "index" / "entry_metadata.parquet",
+ ).rename(
+ columns={
+ "source_entry_id": "entry_pdb_id",
+ "source_chain_asym_id": "chain_asym_id",
+ "source_chain_auth_id": "chain_auth_id",
+ }
+ )
+ return (
+ candidates[["entry_pdb_id", "chain_asym_id", "chain_auth_id"]]
+ .drop_duplicates(ignore_index=True)
+ .sort_values(["entry_pdb_id", "chain_asym_id"], ignore_index=True)
+ )
+
+
+def scatter_protein_scoring(
+ *,
+ data_dir: Path,
+ batch_size: int,
+ two_char_codes: list[str],
+ pdb_ids: list[str],
+ search_dbs: Sequence[str] = ("holo",),
+) -> list[list[str]]:
+ """Split protein-containing release entries into search batches.
+
+ Parameters
+ ----------
+ data_dir : Path
+ the root plinder dir
+ batch_size : int
+ how many codes to put in a chunk
+ two_char_codes : list[str], default=[]
+ only consider particular codes
+ pdb_ids : list[str], default=[]
+ only consider particular pdb IDs
+
+ Returns
+ -------
+ codes : list[list[str]]
+ list of lists of chunks of two character codes
+ """
+ if batch_size < 1:
+ raise ValueError("batch_size must be positive")
+ chains = (
+ _linked_apo_query_chains(data_dir)
+ if set(search_dbs) == {"apo"}
+ else _protein_scoring_chains(data_dir)
+ )
+ protein_entries = set(chains["entry_pdb_id"].astype(str))
+ selected_pdb_ids = [normalize_pdb_id(pdb_id) for pdb_id in pdb_ids]
+ if selected_pdb_ids:
+ selected = sorted(protein_entries.intersection(selected_pdb_ids))
+ else:
+ selected_codes = {str(code).lower() for code in two_char_codes}
+ selected = sorted(
+ pdb_id
+ for pdb_id in protein_entries
+ if not selected_codes or pdb_id[1:3] in selected_codes
+ )
+ LOG.info(f"scatter_protein_scoring: found {len(selected)} protein PDB IDs")
+ chunks = [
+ selected[pos : pos + batch_size] for pos in range(0, len(selected), batch_size)
+ ]
+ return chunks or [[]]
+
+
+def run_batch_searches(
+ *,
+ data_dir: Path,
+ pdb_ids: list[str],
+ scorer_cfg: DictConfig,
+ foldseek_cfg: DictConfig,
+ mmseqs_cfg: DictConfig,
+ cpu: int,
+ scratch_dir: Path,
+ alignment_types: Sequence[str] | None = None,
+ search_databases: Sequence[str] | None = None,
+ force_update: bool = False,
+ target_database_dir: Path | None = None,
+ query_database_dir: Path | None = None,
+ result_database_dir: Path | None = None,
+) -> None:
+ selected_alignment_types = list(alignment_types or ["foldseek", "mmseqs"])
+ selected_search_databases = list(search_databases or scorer_cfg.sub_databases)
+ if search_databases is None and "apo" in selected_search_databases:
+ selected_search_databases.insert(
+ selected_search_databases.index("apo") + 1, "interface_apo"
+ )
+ for search_db in selected_search_databases:
+ apo_query_chains = (
+ _apo_query_auth_ids(data_dir, pdb_ids, search_db=search_db)
+ if search_db in {"apo", "interface_apo"}
+ else {}
+ )
+ eligible_pdb_ids = (
+ [pdb_id for pdb_id in pdb_ids if pdb_id in apo_query_chains]
+ if search_db in {"apo", "interface_apo"}
+ else pdb_ids
+ )
+ for alignment_type in selected_alignment_types:
+ search_config = foldseek_cfg if alignment_type == "foldseek" else mmseqs_cfg
+ output_dir = (
+ (result_database_dir or data_dir / "dbs/subdbs")
+ / f"{search_db}_{alignment_type}"
+ / "aln"
+ )
+ apo_signatures = (
+ {
+ pdb_id: _apo_search_signature(
+ data_dir,
+ pdb_id=pdb_id,
+ search_db=search_db,
+ alignment_type=alignment_type,
+ query_chain_auth_ids=apo_query_chains[pdb_id],
+ search_settings=_apo_search_settings(search_config),
+ )
+ for pdb_id in eligible_pdb_ids
+ }
+ if search_db in {"apo", "interface_apo"}
+ else {}
+ )
+ pending = []
+ for pdb_id in eligible_pdb_ids:
+ output = output_dir / f"{pdb_id}.parquet"
+ current = not force_update and output.is_file()
+ if current and search_db in {"apo", "interface_apo"}:
+ current = current and _apo_search_is_current(
+ output, apo_signatures[pdb_id]
+ )
+ if not current:
+ pending.append(pdb_id)
+ if not pending:
+ LOG.info(
+ f"run_batch_searches: all {len(eligible_pdb_ids)} {search_db} "
+ f"{alignment_type} queries are complete"
+ )
+ continue
+ LOG.info(
+ f"run_batch_searches: searching {len(pending)} of {len(pdb_ids)} "
+ f"{search_db} queries with {alignment_type}"
+ )
+ scorer, entry_ids, batch_db_dir = utils.get_scorer(
+ data_dir=data_dir,
+ pdb_ids=pending,
+ scorer_cfg=scorer_cfg,
+ load_entries=search_db not in {"apo", "interface_apo"},
+ foldseek_cfg=foldseek_cfg,
+ mmseqs_cfg=mmseqs_cfg,
+ scratch_dir=scratch_dir,
+ )
+ try:
+ scorer.run_alignments(
+ entry_ids=entry_ids,
+ output_folder=batch_db_dir,
+ overwrite=True,
+ search_db=search_db,
+ threads=cpu,
+ alignment_types=[alignment_type],
+ target_database_dir=target_database_dir,
+ query_database_dir=query_database_dir,
+ result_database_dir=result_database_dir,
+ query_chain_auth_ids=(
+ apo_query_chains
+ if search_db in {"apo", "interface_apo"}
+ else None
+ ),
+ output_metadata_by_entry=(
+ {
+ pdb_id: {
+ APO_SEARCH_METADATA_KEY: _apo_search_metadata(
+ apo_signatures[pdb_id]
+ )
+ }
+ for pdb_id in pending
+ }
+ if search_db in {"apo", "interface_apo"}
+ else None
+ ),
+ )
+ finally:
+ rmtree(batch_db_dir)
+ missing_outputs = [
+ pdb_id
+ for pdb_id in pending
+ if not (output_dir / f"{pdb_id}.parquet").is_file()
+ ]
+ if missing_outputs:
+ raise RuntimeError(
+ f"{search_db} {alignment_type} search produced no output for "
+ f"{len(missing_outputs)} query entries: "
+ f"{missing_outputs[:10]}"
+ )
+ if search_db == "holo" and alignment_types is None:
+ missing = [
+ pdb_id
+ for pdb_id in pdb_ids
+ if not any(
+ (
+ (result_database_dir or data_dir / "dbs/subdbs")
+ / f"{search_db}_{alignment_type}"
+ / "aln"
+ / f"{pdb_id}.parquet"
+ ).is_file()
+ for alignment_type in selected_alignment_types
+ )
+ ]
+ if missing:
+ raise RuntimeError(
+ "holo search did not produce results from either backend for "
+ f"{len(missing)} query entries: {missing[:10]}"
+ )
+
+
+def scatter_missing_alignment_mappings(
+ *,
+ data_dir: Path,
+ batch_size: int,
+ search_db: str = "holo",
+) -> list[list[str]]:
+ """Scatter query shards whose raw alignments are not mapped and published."""
+ if batch_size < 1:
+ raise ValueError("batch_size must be positive")
+ raw_root = data_dir / "dbs" / "subdbs"
+ shards = sorted(
+ {
+ path.stem[1:3]
+ for alignment_type in ["foldseek", "mmseqs"]
+ for path in (raw_root / f"{search_db}_{alignment_type}" / "aln").glob(
+ "*.parquet"
+ )
+ if not path.name.endswith(".tmp.parquet")
+ }
+ )
+ missing = [
+ shard
+ for shard in shards
+ if not alignment_mapping_shard_is_current(
+ data_dir=data_dir,
+ search_db=search_db,
+ shard=shard,
+ )
+ ]
+ chunks = [
+ missing[pos : pos + batch_size] for pos in range(0, len(missing), batch_size)
+ ]
+ return chunks or [[]]
+
+
+def _alignment_input_signatures(
+ *, data_dir: Path, shard: str, search_db: str = "holo"
+) -> dict[str, list[dict[str, int | str]]]:
+ signatures: dict[str, list[dict[str, int | str]]] = {}
+ for alignment_type in ["foldseek", "mmseqs"]:
+ source_dir = (
+ data_dir / "dbs" / "subdbs" / f"{search_db}_{alignment_type}" / "aln"
+ )
+ sources = sorted(
+ path
+ for path in source_dir.glob("*.parquet")
+ if path.stem[1:3] == shard and not path.name.endswith(".tmp.parquet")
+ )
+ signatures[alignment_type] = [
+ {
+ "name": path.name,
+ "size": path.stat().st_size,
+ "mtime_ns": path.stat().st_mtime_ns,
+ }
+ for path in sources
+ ]
+ return signatures
+
+
+def _alignment_release_path(
+ *, data_dir: Path, search_db: str, alignment_type: str, shard: str
+) -> Path:
+ return (
+ data_dir
+ / "alignment_cigars"
+ / f"search_db={search_db}"
+ / f"alignment_type={alignment_type}"
+ / f"shard={shard}.parquet"
+ )
+
+
+def _protein_similarity_score_path(
+ *, data_dir: Path, alignment_type: str, shard: str
+) -> Path:
+ return (
+ data_dir
+ / PROTEIN_SIMILARITY_SCORES_RELATIVE
+ / f"alignment_type={alignment_type}"
+ / f"shard={shard}.parquet"
+ )
+
+
+def _alignment_mapping_manifest_path(
+ *, data_dir: Path, shard: str, search_db: str = "holo"
+) -> Path:
+ root = data_dir / "alignments" / "manifests"
+ if search_db != "holo":
+ root = root / f"search_db={search_db}"
+ return root / f"shard={shard}.json"
+
+
+def _alignment_target_entry_ids(sources: Sequence[Path]) -> set[str]:
+ """Read the distinct target IDs once for a complete query shard."""
+ if not sources:
+ return set()
+ targets: set[str] = set()
+ scanner = ds.dataset(sources, format="parquet").scanner(
+ columns=["target_pdb_id"],
+ batch_size=262_144,
+ use_threads=False,
+ )
+ for batch in scanner.to_batches():
+ unique = pc.unique(batch.column(0))
+ targets.update(str(value) for value in unique.to_pylist() if value is not None)
+ return targets
+
+
+def alignment_mapping_shard_is_current(
+ *,
+ data_dir: Path,
+ shard: str,
+ search_db: str = "holo",
+ require_raw_inputs: bool = True,
+) -> bool:
+ """Validate published outputs, and raw inputs when they are retained."""
+ manifest_path = _alignment_mapping_manifest_path(
+ data_dir=data_dir,
+ search_db=search_db,
+ shard=shard,
+ )
+ try:
+ payload = json.loads(manifest_path.read_text())
+ except (OSError, TypeError, ValueError):
+ return False
+ inputs = payload.get("inputs")
+ if not isinstance(inputs, dict) or any(
+ not isinstance(signatures, list) for signatures in inputs.values()
+ ):
+ return False
+ if require_raw_inputs and inputs != _alignment_input_signatures(
+ data_dir=data_dir,
+ search_db=search_db,
+ shard=shard,
+ ):
+ return False
+ lookup_signature = _completed_alignment_chain_lookup(data_dir)
+ if lookup_signature is None:
+ return False
+ if (
+ payload.get("shard") != shard
+ or (search_db != "holo" and payload.get("search_db") != search_db)
+ or payload.get("alignment_chain_lookup") != lookup_signature
+ ):
+ return False
+ outputs = payload.get("outputs")
+ if not isinstance(outputs, dict):
+ return False
+ protein_score_outputs = payload.get("protein_score_outputs")
+ if search_db == "holo" and not isinstance(protein_score_outputs, dict):
+ return False
+ for alignment_type, source_signatures in inputs.items():
+ output = _alignment_release_path(
+ data_dir=data_dir,
+ search_db=search_db,
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ if not source_signatures:
+ if outputs.get(alignment_type) is not None:
+ return False
+ if (
+ search_db == "holo"
+ and protein_score_outputs.get(alignment_type) is not None
+ ):
+ return False
+ continue
+ if not output.is_file():
+ return False
+ try:
+ output_columns = set(pq.read_schema(output).names)
+ except (OSError, ValueError):
+ return False
+ if not schemas.release_alignment_mapping_schema_is_current(
+ output_columns,
+ alignment_type=alignment_type,
+ include_scores=search_db != "holo",
+ ):
+ return False
+ stat = output.stat()
+ if outputs.get(alignment_type) != {
+ "name": output.name,
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ }:
+ return False
+ if search_db == "holo":
+ protein_scores = _protein_similarity_score_path(
+ data_dir=data_dir,
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ if not protein_scores.is_file() or not pq.read_schema(
+ protein_scores
+ ).equals(schemas.PROTEIN_SIMILARITY_EXPORT_SCHEMA):
+ return False
+ score_stat = protein_scores.stat()
+ if protein_score_outputs.get(alignment_type) != {
+ "name": protein_scores.name,
+ "size": score_stat.st_size,
+ "mtime_ns": score_stat.st_mtime_ns,
+ }:
+ return False
+ return True
+
+
+def _restore_parquet_schema(path: Path, schema: pa.Schema) -> None:
+ """Cast a DuckDB-written file back to the shard's original physical types.
+
+ DuckDB always writes text as ``string``, while pandas 3 writes ``large_string``;
+ the values are identical, so only the physical type is restored.
+ """
+ written = pq.read_schema(path)
+ if written.equals(schema) or written.names != schema.names:
+ return
+ restored = path.with_suffix(path.suffix + ".restored")
+ with pq.ParquetWriter(restored, schema, compression="zstd") as writer:
+ for batch in pq.ParquetFile(path).iter_batches():
+ writer.write_batch(batch.cast(schema))
+ restored.replace(path)
+
+
+def _replace_release_alignment_queries(
+ *,
+ old: Path,
+ new: Path,
+ replacements: set[str],
+ scratch_dir: Path,
+ replacement_target_ids: set[str] | None = None,
+) -> None:
+ """Keep old rows outside the changed query or query-target pairs."""
+ if not old.is_file():
+ old.parent.mkdir(parents=True, exist_ok=True)
+ install = old.with_suffix(old.suffix + ".tmp")
+ copyfile(new, install)
+ install.replace(old)
+ return
+ old_schema = pq.read_schema(old)
+ new_schema = pq.read_schema(new)
+ if set(old_schema.names) != set(new_schema.names):
+ raise ValueError(f"incompatible alignment shard columns: {old}, {new}")
+ import duckdb
+
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ temporary = scratch_dir / old.name
+ temporary.unlink(missing_ok=True)
+ connection = duckdb.connect()
+ try:
+ connection.register(
+ "replacement_queries",
+ pd.DataFrame({"query_entry": sorted(replacements)}),
+ )
+ if replacement_target_ids is not None:
+ connection.register(
+ "replacement_targets",
+ pd.DataFrame({"target_entry": sorted(replacement_target_ids)}),
+ )
+ old_sql = old.as_posix().replace("'", "''")
+ new_sql = new.as_posix().replace("'", "''")
+ temporary_sql = temporary.as_posix().replace("'", "''")
+ columns = connection.sql(
+ f"DESCRIBE SELECT * FROM read_parquet('{old_sql}', hive_partitioning=false)"
+ ).fetchall()
+ typed_columns = ", ".join(
+ f'CAST("{name}" AS {dtype}) AS "{name}"' for name, dtype, *_ in columns
+ )
+ retained_condition = (
+ "WHERE NOT EXISTS ("
+ "SELECT 1 FROM replacement_queries AS rq "
+ "JOIN replacement_targets AS rt ON TRUE "
+ "WHERE existing.query_entry = rq.query_entry "
+ "AND existing.target_entry = rt.target_entry)"
+ if replacement_target_ids is not None
+ else "ANTI JOIN replacement_queries USING (query_entry)"
+ )
+ connection.sql(
+ f"""
+ COPY (
+ SELECT {typed_columns}
+ FROM (
+ SELECT existing.*
+ FROM read_parquet('{old_sql}', hive_partitioning=false) AS existing
+ {retained_condition}
+ UNION ALL BY NAME
+ SELECT * FROM read_parquet('{new_sql}', hive_partitioning=false)
+ )
+ ) TO '{temporary_sql}' (FORMAT PARQUET, COMPRESSION ZSTD)
+ """
+ )
+ finally:
+ connection.close()
+ _restore_parquet_schema(temporary, old_schema)
+ if not pq.read_schema(temporary).equals(old_schema):
+ raise ValueError(
+ f"patched alignment shard has an unexpected schema: {old}; "
+ f"expected {old_schema}, got {pq.read_schema(temporary)}"
+ )
+ install = old.with_suffix(old.suffix + ".tmp")
+ try:
+ temporary.replace(install)
+ except OSError as error:
+ if error.errno != EXDEV:
+ raise
+ copyfile(temporary, install)
+ temporary.unlink()
+ install.replace(old)
+
+
+def map_batch_alignments(
+ *,
+ data_dir: Path,
+ shards: list[str],
+ scorer_cfg: DictConfig,
+ force_update: bool,
+ scratch_dir: Path | None = None,
+ search_db: str = "holo",
+ replacement_query_ids: set[str] | None = None,
+ replacement_target_ids: set[str] | None = None,
+) -> None:
+ """Map raw backend hits directly into atomic query-shard release files."""
+ enabled = search_db in scorer_cfg.sub_databases or (
+ search_db == "interface_apo" and "apo" in scorer_cfg.sub_databases
+ )
+ if not enabled:
+ raise ValueError(f"alignment database is not enabled: {search_db}")
+ maximum_rows = int(getattr(scorer_cfg, "max_alignment_rows_per_query", 5_000_000))
+ for shard in shards:
+ if not force_update and alignment_mapping_shard_is_current(
+ data_dir=data_dir,
+ search_db=search_db,
+ shard=shard,
+ ):
+ LOG.info(
+ "map_batch_alignments: %s shard %s is complete",
+ search_db,
+ shard,
+ )
+ continue
+ new_inputs = _alignment_input_signatures(
+ data_dir=data_dir,
+ search_db=search_db,
+ shard=shard,
+ )
+ replacing = replacement_query_ids is not None
+ replacements = set(replacement_query_ids or ())
+ old_manifest = _alignment_mapping_manifest_path(
+ data_dir=data_dir, search_db=search_db, shard=shard
+ )
+ if (
+ replacing
+ and not old_manifest.is_file()
+ and any(
+ _alignment_release_path(
+ data_dir=data_dir,
+ search_db=search_db,
+ alignment_type=alignment_type,
+ shard=shard,
+ ).is_file()
+ for alignment_type in ("foldseek", "mmseqs")
+ )
+ ):
+ raise FileNotFoundError(
+ f"missing existing alignment manifest: {old_manifest}"
+ )
+ old_payload = (
+ json.loads(old_manifest.read_text())
+ if replacing and old_manifest.is_file()
+ else {}
+ )
+ if replacing:
+ for alignment_type, signatures in new_inputs.items():
+ unexpected = {
+ Path(str(item["name"])).stem for item in signatures
+ }.difference(replacements)
+ if unexpected:
+ raise ValueError(
+ f"raw {alignment_type} queries outside replacement set: {sorted(unexpected)}"
+ )
+ inputs = {
+ alignment_type: sorted(
+ [
+ item
+ for item in old_payload.get("inputs", {}).get(alignment_type, [])
+ if Path(str(item["name"])).stem not in replacements
+ ]
+ + signatures,
+ key=lambda item: str(item["name"]),
+ )
+ if replacing
+ else signatures
+ for alignment_type, signatures in new_inputs.items()
+ }
+ pdb_ids = sorted(
+ {
+ Path(str(signature["name"])).stem
+ for signatures in new_inputs.values()
+ for signature in signatures
+ }
+ )
+ if not pdb_ids and not replacing:
+ continue
+ rows_by_query: dict[str, dict[str, int]] = {pdb_id: {} for pdb_id in pdb_ids}
+ for alignment_type, signatures in new_inputs.items():
+ source_root = (
+ data_dir / "dbs" / "subdbs" / f"{search_db}_{alignment_type}" / "aln"
+ )
+ for signature in signatures:
+ source = source_root / str(signature["name"])
+ pdb_id = source.stem
+ rows_by_query[pdb_id][alignment_type] = int(
+ pq.ParquetFile(source).metadata.num_rows
+ )
+ skipped_queries = {
+ pdb_id: {
+ "reason": "raw_alignment_row_budget_exceeded",
+ "maximum_rows": maximum_rows,
+ "total_rows": sum(rows.values()),
+ "rows_by_alignment_type": rows,
+ }
+ for pdb_id, rows in rows_by_query.items()
+ if sum(rows.values()) > maximum_rows
+ }
+ if skipped_queries:
+ LOG.warning(
+ "map_batch_alignments: shard %s skips %s oversized queries: %s",
+ shard,
+ len(skipped_queries),
+ sorted(skipped_queries),
+ )
+ mapped_pdb_ids = [pdb_id for pdb_id in pdb_ids if pdb_id not in skipped_queries]
+ lookup_signature = _completed_alignment_chain_lookup(data_dir)
+ if lookup_signature is None:
+ raise FileNotFoundError(
+ "missing or stale alignment chain lookup; run make-sub-dbs first"
+ )
+ raw_root = data_dir / "dbs" / "subdbs"
+ raw_sources = [
+ raw_root / f"{search_db}_{alignment_type}" / "aln" / str(signature["name"])
+ for alignment_type, signatures in new_inputs.items()
+ for signature in signatures
+ if Path(str(signature["name"])).stem not in skipped_queries
+ ]
+ mapping_entry_ids = set(mapped_pdb_ids)
+ if search_db != "pred":
+ mapping_entry_ids.update(_alignment_target_entry_ids(raw_sources))
+ working_root = (scratch_dir or data_dir / "scratch" / "mapping") / (
+ f"{search_db}-{shard}"
+ )
+ if working_root.exists():
+ rmtree(working_root)
+ mapped_db_dir = working_root / "mapped"
+ if mapped_pdb_ids:
+ scorer, entry_ids, _ = utils.get_scorer(
+ data_dir=data_dir,
+ pdb_ids=mapped_pdb_ids,
+ scorer_cfg=scorer_cfg,
+ load_entries=False,
+ scratch_dir=working_root,
+ )
+ from plinder.core.scores.entries import load_alignment_entry_views
+
+ scorer.entries.update(
+ load_alignment_entry_views(
+ lookup_path=data_dir / ALIGNMENT_CHAIN_LOOKUP_RELATIVE,
+ pdb_ids=mapping_entry_ids,
+ )
+ )
+ missing_mapping_entries = mapping_entry_ids.difference(scorer.entries)
+ if missing_mapping_entries:
+ raise ValueError(
+ "alignment chain lookup is missing protein entries: "
+ f"{sorted(missing_mapping_entries)[:10]}"
+ )
+ try:
+ if mapped_pdb_ids:
+ for pdb_id in tqdm(entry_ids):
+ expected = sum(
+ any(
+ str(signature["name"]) == f"{pdb_id}.parquet"
+ for signature in new_inputs[alignment_type]
+ )
+ for alignment_type in ["foldseek", "mmseqs"]
+ )
+ mapped = scorer.map_alignment_files(
+ data_dir,
+ pdb_id,
+ search_db,
+ overwrite=True,
+ scratch_dir=working_root / "temporary",
+ mapped_db_dir=mapped_db_dir,
+ )
+ if len(mapped) != expected:
+ raise RuntimeError(
+ f"{search_db} alignment mapping for {pdb_id} produced "
+ f"{len(mapped)} of {expected} available backends"
+ )
+ outputs: dict[str, dict[str, int | str] | None] = {}
+ protein_score_outputs: dict[str, dict[str, int | str] | None] = {}
+ for alignment_type, source_signatures in inputs.items():
+ target = _alignment_release_path(
+ data_dir=data_dir,
+ search_db=search_db,
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ protein_scores_target = (
+ _protein_similarity_score_path(
+ data_dir=data_dir,
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ if search_db == "holo"
+ else None
+ )
+ retained = [
+ signature
+ for signature in old_payload.get("inputs", {}).get(
+ alignment_type, []
+ )
+ if Path(str(signature["name"])).stem not in replacements
+ ]
+ if (
+ replacing
+ and retained
+ and (
+ not target.is_file()
+ or (
+ protein_scores_target is not None
+ and not protein_scores_target.is_file()
+ )
+ )
+ ):
+ raise FileNotFoundError(
+ f"missing retained alignment shard for {search_db} "
+ f"{alignment_type} {shard}"
+ )
+ if not source_signatures:
+ target.unlink(missing_ok=True)
+ outputs[alignment_type] = None
+ if protein_scores_target is not None:
+ protein_scores_target.unlink(missing_ok=True)
+ protein_score_outputs[alignment_type] = None
+ continue
+ local_sources = sorted(
+ (
+ mapped_db_dir / f"{search_db}_{alignment_type}" / "mapped_aln"
+ ).glob("*.parquet")
+ )
+ new_target = working_root / "new" / alignment_type / target.name
+ new_protein_scores = (
+ working_root / "new-protein" / alignment_type / target.name
+ if protein_scores_target is not None
+ else None
+ )
+ _write_alignment_release_shard(
+ sources=local_sources,
+ target=new_target if replacing else target,
+ alignment_type=alignment_type,
+ temp_dir=working_root / "collate" / alignment_type,
+ threads=1,
+ memory_limit="7GB",
+ protein_scores_target=(
+ new_protein_scores if replacing else protein_scores_target
+ ),
+ )
+ if replacing:
+ _replace_release_alignment_queries(
+ old=target,
+ new=new_target,
+ replacements=replacements,
+ scratch_dir=working_root / "patch" / alignment_type,
+ replacement_target_ids=replacement_target_ids,
+ )
+ if (
+ protein_scores_target is not None
+ and new_protein_scores is not None
+ ):
+ _replace_release_alignment_queries(
+ old=protein_scores_target,
+ new=new_protein_scores,
+ replacements=replacements,
+ scratch_dir=working_root / "patch-protein" / alignment_type,
+ replacement_target_ids=replacement_target_ids,
+ )
+ stat = target.stat()
+ outputs[alignment_type] = {
+ "name": target.name,
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ }
+ if protein_scores_target is not None:
+ score_stat = protein_scores_target.stat()
+ protein_score_outputs[alignment_type] = {
+ "name": protein_scores_target.name,
+ "size": score_stat.st_size,
+ "mtime_ns": score_stat.st_mtime_ns,
+ }
+ manifest = _alignment_mapping_manifest_path(
+ data_dir=data_dir,
+ search_db=search_db,
+ shard=shard,
+ )
+ manifest.parent.mkdir(exist_ok=True, parents=True)
+ temporary_manifest = manifest.with_suffix(".tmp.json")
+ temporary_manifest.write_text(
+ json.dumps(
+ {
+ "search_db": search_db,
+ "shard": shard,
+ "alignment_chain_lookup": lookup_signature,
+ "inputs": inputs,
+ "outputs": outputs,
+ "protein_score_outputs": protein_score_outputs,
+ "skipped_queries": {
+ **{
+ key: value
+ for key, value in old_payload.get(
+ "skipped_queries", {}
+ ).items()
+ if key not in replacements
+ },
+ **skipped_queries,
+ },
+ },
+ indent=2,
+ sort_keys=True,
+ )
+ + "\n"
+ )
+ temporary_manifest.replace(manifest)
+ finally:
+ if working_root.exists():
+ rmtree(working_root)
+
+
+def scatter_missing_scores(
+ *,
+ data_dir: Path,
+ batch_size: int,
+ scorer_cfg: DictConfig,
+ search_dbs: Sequence[str] = ("holo",),
+) -> list[list[str]]:
+ from plinder.data.pipeline.score import dropped_query_ids
+
+ present = utils.get_pdb_ids_in_scoring_dataset(data_dir=data_dir)
+ score_work = data_dir / "manifests" / "protein_scoring_work.parquet"
+ if score_work.is_file():
+ complete_holo: list[str] = []
+ for pdb_id in present["holo"]:
+ score_path = (
+ data_dir / "dbs" / "subdbs" / "search_db=holo" / f"{pdb_id}.parquet"
+ )
+ candidate_path = (
+ data_dir
+ / "scores"
+ / "ligand_3d_candidates"
+ / "search_db=holo"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet"
+ )
+ ligand_pair_score_path = (
+ data_dir
+ / "scores"
+ / "ligand_pair_scores"
+ / "search_db=holo"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet"
+ )
+ try:
+ metadata = pq.read_schema(score_path).metadata or {}
+ ligand_pair_schema = pq.read_schema(ligand_pair_score_path)
+ except (OSError, ValueError):
+ continue
+ if (
+ metadata.get(b"plinder.ligand_3d") in {b"deferred", b"complete"}
+ and candidate_path.is_file()
+ and ligand_pair_schema.equals(schemas.LIGAND_PAIR_SCORE_SCHEMA)
+ ):
+ complete_holo.append(pdb_id)
+ present["holo"] = complete_holo
+ rerun: set[str] = set()
+ dropped = dropped_query_ids(data_dir)
+ for search_db in search_dbs:
+ score_mode = b"deferred" if search_db == "holo" else b"complete"
+ score_metrics = None
+ if search_db == "apo":
+ from plinder.data.linked_apo import REQUIRED_SCORE_METRICS
+
+ score_metrics = REQUIRED_SCORE_METRICS
+ present[search_db] = [
+ pdb_id
+ for pdb_id in present.get(search_db, [])
+ if get_similarity_scores.score_cache_is_current(
+ data_dir
+ / "dbs"
+ / "subdbs"
+ / f"search_db={search_db}"
+ / f"{pdb_id}.parquet",
+ ligand_3d_mode=score_mode,
+ minimum_threshold=float(scorer_cfg.minimum_threshold),
+ minimum_thresholds=dict(scorer_cfg.minimum_thresholds),
+ holo_protein_scores_mode=(b"excluded" if search_db == "holo" else None),
+ score_metrics=score_metrics,
+ )
+ ]
+ manifest_root = data_dir / "alignments" / "manifests"
+ if search_db != "holo":
+ manifest_root = manifest_root / f"search_db={search_db}"
+ mapped_queries: set[str] = set()
+ for manifest_path in sorted(manifest_root.glob("shard=*.json")):
+ shard = manifest_path.stem.removeprefix("shard=")
+ if not alignment_mapping_shard_is_current(
+ data_dir=data_dir,
+ search_db=search_db,
+ shard=shard,
+ ):
+ continue
+ payload = json.loads(manifest_path.read_text())
+ mapped_queries.update(
+ Path(str(signature["name"])).stem
+ for alignment_type in ["foldseek", "mmseqs"]
+ for signature in payload["inputs"][alignment_type]
+ )
+ rerun.update(
+ mapped_queries.difference(present.get(search_db, [])).difference(dropped)
+ )
+ run = sorted(rerun)
+ if score_work.is_file():
+ planned = pd.read_parquet(
+ score_work, columns=["pdb_id", "score_batch_index", "estimated_work"]
+ )
+ planned = planned[planned["pdb_id"].isin(run)].sort_values(
+ ["score_batch_index", "estimated_work"], ascending=[True, False]
+ )
+ chunks = [
+ group["pdb_id"].astype(str).tolist()
+ for _, group in planned.groupby("score_batch_index", sort=True)
+ ]
+ return chunks or [[]]
+ chunks = [run[pos : pos + batch_size] for pos in range(0, len(run), batch_size)]
+ return chunks or [[]]
+
+
+def make_batch_scores(
+ *,
+ data_dir: Path,
+ pdb_ids: list[str],
+ scorer_cfg: DictConfig,
+ force_update: bool,
+ scratch_dir: Path,
+ threads: int = 1,
+ defer_ligand_3d: bool = True,
+) -> None:
+ scorer, entry_ids, _ = utils.get_scorer(
+ data_dir=data_dir,
+ pdb_ids=pdb_ids,
+ scorer_cfg=scorer_cfg,
+ load_entries=False,
+ scratch_dir=scratch_dir,
+ )
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ scorer.shape_score_threads = threads
+ for search_db in scorer_cfg.sub_databases:
+ if search_db != "holo":
+ from plinder.core.scores.entries import load_entry_views
+ from plinder.data.linked_apo import REQUIRED_SCORE_METRICS
+
+ score_metrics = REQUIRED_SCORE_METRICS if search_db == "apo" else None
+ missing_entries = set(entry_ids).difference(scorer.entries)
+ if missing_entries:
+ scorer.entries.update(
+ load_entry_views(
+ pdb_ids=missing_entries,
+ data_dir=data_dir,
+ include_interfaces=False,
+ )
+ )
+ entries_by_shard: dict[str, list[str]] = {}
+ for pdb_id in entry_ids:
+ entries_by_shard.setdefault(pdb_id[1:3], []).append(pdb_id)
+ for shard, shard_entry_ids in entries_by_shard.items():
+ source_to_aln_file = {
+ f"{search_db}_{alignment_type}": _alignment_release_path(
+ data_dir=data_dir,
+ search_db=search_db,
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ for alignment_type in ["foldseek", "mmseqs"]
+ }
+ alignments = scorer.load_alignments(
+ source_to_aln_file=source_to_aln_file,
+ search_db=search_db,
+ query_entry_ids=set(shard_entry_ids),
+ )
+ for pdb_id in tqdm(shard_entry_ids):
+ if alignments.empty:
+ query_alignments = alignments
+ else:
+ try:
+ query_alignments = alignments.loc[pdb_id]
+ except KeyError:
+ query_alignments = pd.DataFrame()
+ scorer.get_score_df(
+ data_dir,
+ pdb_id,
+ search_db=search_db,
+ overwrite=force_update,
+ map_alignments=False,
+ scratch_dir=scratch_dir,
+ source_to_aln_file=source_to_aln_file,
+ defer_ligand_3d=False,
+ query_entry_alignments=query_alignments,
+ score_metrics=score_metrics,
+ )
+ continue
+ for pdb_id in tqdm(entry_ids):
+ source_to_aln_file = {
+ f"{search_db}_{alignment_type}": _alignment_release_path(
+ data_dir=data_dir,
+ search_db=search_db,
+ alignment_type=alignment_type,
+ shard=pdb_id[1:3],
+ )
+ for alignment_type in ["foldseek", "mmseqs"]
+ }
+ scorer.get_score_df(
+ data_dir,
+ pdb_id,
+ search_db=search_db,
+ overwrite=force_update,
+ map_alignments=False,
+ scratch_dir=scratch_dir,
+ source_to_aln_file=source_to_aln_file,
+ defer_ligand_3d=defer_ligand_3d and search_db == "holo",
+ )
+
+
+def repair_batch_scores(
+ *,
+ data_dir: Path,
+ repairs: list[dict[str, Any]],
+ scorer_cfg: DictConfig,
+ scratch_dir: Path,
+ threads: int = 1,
+) -> None:
+ """Repair complete affected queries and target-only rows in place."""
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ pdb_ids = [
+ str(repair["pdb_id"])
+ for repair in repairs
+ if str(repair["repair_mode"]) != "drop"
+ ]
+ scorer = None
+ if pdb_ids:
+ scorer, _, _ = utils.get_scorer(
+ data_dir=data_dir,
+ pdb_ids=pdb_ids,
+ scorer_cfg=scorer_cfg,
+ load_entries=False,
+ scratch_dir=scratch_dir,
+ )
+ scorer.shape_score_threads = threads
+ started = time.perf_counter()
+ for index, repair in enumerate(repairs, start=1):
+ pdb_id = str(repair["pdb_id"])
+ mode = str(repair["repair_mode"])
+ query_started = time.perf_counter()
+ LOG.info(
+ "score repair progress: query=%d/%d pdb_id=%s mode=%s targets=%d",
+ index,
+ len(repairs),
+ pdb_id,
+ mode,
+ len(repair.get("target_pdb_ids", [])),
+ )
+ if mode == "drop":
+ (
+ data_dir / "dbs" / "subdbs" / "search_db=holo" / f"{pdb_id}.parquet"
+ ).unlink(missing_ok=True)
+ (
+ data_dir
+ / "scores"
+ / "ligand_3d_candidates"
+ / "search_db=holo"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet"
+ ).unlink(missing_ok=True)
+ (
+ data_dir
+ / "scores"
+ / "ligand_pair_scores"
+ / "search_db=holo"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet"
+ ).unlink(missing_ok=True)
+ elif mode == "full":
+ if scorer is None:
+ raise RuntimeError("score repair unexpectedly lacks a scorer")
+ scorer.get_score_df(
+ data_dir,
+ pdb_id,
+ search_db="holo",
+ overwrite=True,
+ map_alignments=False,
+ scratch_dir=scratch_dir,
+ source_to_aln_file={
+ f"holo_{alignment_type}": _alignment_release_path(
+ data_dir=data_dir,
+ search_db="holo",
+ alignment_type=alignment_type,
+ shard=pdb_id[1:3],
+ )
+ for alignment_type in ["foldseek", "mmseqs"]
+ },
+ defer_ligand_3d=True,
+ )
+ elif mode in {"targets", "bounded"}:
+ if scorer is None:
+ raise RuntimeError("score repair unexpectedly lacks a scorer")
+ scorer.repair_score_df_targets(
+ data_dir,
+ pdb_id,
+ affected_target_entries=set(map(str, repair["target_pdb_ids"])),
+ scratch_dir=scratch_dir,
+ allow_missing=mode == "bounded",
+ query_system_ids=(
+ set(map(str, repair["query_system_ids"]))
+ if mode == "bounded"
+ else None
+ ),
+ query_ligand_ids=(
+ set(map(str, repair["query_ligand_ids"]))
+ if mode == "bounded"
+ else None
+ ),
+ target_system_ids=(
+ set(map(str, repair["target_system_ids"]))
+ if mode == "bounded"
+ else None
+ ),
+ target_ligand_ids=(
+ set(map(str, repair["target_ligand_ids"]))
+ if mode == "bounded"
+ else None
+ ),
+ )
+ else:
+ raise ValueError(f"unknown score repair mode: {mode!r}")
+ LOG.info(
+ "score repair complete: query=%d/%d pdb_id=%s "
+ "query_seconds=%.1f elapsed_seconds=%.1f",
+ index,
+ len(repairs),
+ pdb_id,
+ time.perf_counter() - query_started,
+ time.perf_counter() - started,
+ )
+
+
+def _ligand_3d_candidate_shard_paths(data_dir: Path, shard: str) -> tuple[Path, Path]:
+ root = data_dir / "scores" / "ligand_3d_candidate_shards"
+ return root / f"shard={shard}.parquet", root / f"shard={shard}.json"
+
+
+def _ligand_3d_pair_candidate_shard_path(data_dir: Path, shard: str) -> Path:
+ return (
+ data_dir
+ / "scores"
+ / "ligand_3d_pair_candidate_shards"
+ / f"shard={shard}.parquet"
+ )
+
+
+def _ligand_pair_score_shard_path(data_dir: Path, shard: str) -> Path:
+ return data_dir / "scores" / "ligand_pair_score_shards" / f"shard={shard}.parquet"
+
+
+def _ligand_3d_candidate_input_signatures(
+ data_dir: Path, pdb_ids: Sequence[str]
+) -> list[dict[str, int | str]]:
+ signatures: list[dict[str, int | str]] = []
+ for pdb_id in pdb_ids:
+ path = (
+ data_dir
+ / "scores"
+ / "ligand_3d_candidates"
+ / "search_db=holo"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet"
+ )
+ stat = path.stat()
+ schema = pq.read_schema(path)
+ missing = sorted(
+ set(schemas.LIGAND_3D_CANDIDATE_SCHEMA.names).difference(schema.names)
+ )
+ if missing:
+ raise ValueError(f"candidate file {path} is missing columns {missing}")
+ signatures.append(
+ {
+ "pdb_id": pdb_id,
+ "path": str(path.resolve()),
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ "rows": pq.ParquetFile(path).metadata.num_rows,
+ }
+ )
+ return signatures
+
+
+def _ligand_pair_score_input_signatures(
+ data_dir: Path, pdb_ids: Sequence[str]
+) -> list[dict[str, int | str]]:
+ signatures: list[dict[str, int | str]] = []
+ for pdb_id in pdb_ids:
+ path = (
+ data_dir
+ / "scores"
+ / "ligand_pair_scores"
+ / "search_db=holo"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet"
+ )
+ stat = path.stat()
+ schema = pq.read_schema(path)
+ if not schema.equals(schemas.LIGAND_PAIR_SCORE_SCHEMA):
+ raise ValueError(f"ligand pair score file has unexpected schema: {path}")
+ signatures.append(
+ {
+ "pdb_id": pdb_id,
+ "path": str(path.resolve()),
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ "rows": pq.ParquetFile(path).metadata.num_rows,
+ }
+ )
+ return signatures
+
+
+def scatter_scoring_query_shards(*, data_dir: Path, batch_size: int) -> list[list[str]]:
+ """Group published query shards for candidate collation and score merging."""
+ from plinder.data.pipeline.score import published_scoring_query_ids
+
+ if batch_size < 1:
+ raise ValueError("batch size must be positive")
+ shards = sorted({pdb_id[1:3] for pdb_id in published_scoring_query_ids(data_dir)})
+ return [
+ shards[start : start + batch_size]
+ for start in range(0, len(shards), batch_size)
+ ] or [[]]
+
+
+def collate_ligand_3d_candidates(
+ *,
+ data_dir: Path,
+ shards: list[str],
+ scratch_dir: Path,
+ threads: int,
+ replacement_query_ids: set[str] | None = None,
+ source_query_ids: set[str] | None = None,
+) -> list[Path]:
+ """Consolidate or patch per-PDB positive-pocket candidate shards."""
+ from plinder.data.pipeline.score import published_scoring_query_ids
+
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ import duckdb
+
+ patch_existing = replacement_query_ids is not None
+ if patch_existing:
+ replacement_query_ids = set(map(str, replacement_query_ids or set()))
+ active_queries = set(map(str, source_query_ids or set()))
+ if active_queries.difference(replacement_query_ids):
+ raise ValueError("candidate patch sources must be replacement queries")
+ elif source_query_ids is not None:
+ raise ValueError("source_query_ids requires replacement_query_ids")
+ else:
+ active_queries = published_scoring_query_ids(data_dir)
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ outputs: list[Path] = []
+ for shard in shards:
+ if len(shard) != 2 or any(
+ char not in ascii_lowercase + digits for char in shard
+ ):
+ raise ValueError(f"invalid ligand 3D candidate shard: {shard!r}")
+ pdb_ids = sorted(pdb_id for pdb_id in active_queries if pdb_id[1:3] == shard)
+ replaced_pdb_ids = sorted(
+ pdb_id for pdb_id in replacement_query_ids or set() if pdb_id[1:3] == shard
+ )
+ if patch_existing and not replaced_pdb_ids:
+ continue
+ if not patch_existing and not pdb_ids:
+ continue
+ try:
+ inputs = _ligand_3d_candidate_input_signatures(data_dir, pdb_ids)
+ ligand_pair_inputs = _ligand_pair_score_input_signatures(data_dir, pdb_ids)
+ except FileNotFoundError as exc:
+ raise FileNotFoundError(
+ f"ligand score inputs are incomplete for shard {shard}: {exc}"
+ ) from exc
+ output, manifest = _ligand_3d_candidate_shard_paths(data_dir, shard)
+ pair_output = _ligand_3d_pair_candidate_shard_path(data_dir, shard)
+ ligand_pair_output = _ligand_pair_score_shard_path(data_dir, shard)
+ if patch_existing and (
+ not output.is_file() or not ligand_pair_output.is_file()
+ ):
+ raise FileNotFoundError(
+ "ligand score patch requires existing shards: "
+ f"candidates={output.is_file()} pairs={ligand_pair_output.is_file()}"
+ )
+ output_is_current = False
+ pair_output_is_current = False
+ ligand_pair_output_is_current = False
+ payload: dict[str, Any] = {}
+ expected_inputs = (
+ {
+ "base": "existing packed candidate shard",
+ "replaced_query_ids": replaced_pdb_ids,
+ "replacements": inputs,
+ }
+ if patch_existing
+ else inputs
+ )
+ expected_ligand_pair_inputs = (
+ {
+ "base": "existing packed ligand pair score shard",
+ "replaced_query_ids": replaced_pdb_ids,
+ "replacements": ligand_pair_inputs,
+ }
+ if patch_existing
+ else ligand_pair_inputs
+ )
+ if output.is_file() and manifest.is_file():
+ try:
+ payload = json.loads(manifest.read_text())
+ stat = output.stat()
+ current_output = {
+ "path": str(output.resolve()),
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ "rows": pq.ParquetFile(output).metadata.num_rows,
+ }
+ output_is_current = (
+ payload.get("shard") == shard
+ and payload.get("inputs") == expected_inputs
+ and payload.get("output") == current_output
+ )
+ if output_is_current and pair_output.is_file():
+ pair_stat = pair_output.stat()
+ current_pair_output = {
+ "path": str(pair_output.resolve()),
+ "size": pair_stat.st_size,
+ "mtime_ns": pair_stat.st_mtime_ns,
+ "rows": pq.ParquetFile(pair_output).metadata.num_rows,
+ }
+ pair_schema = pq.read_schema(pair_output)
+ pair_output_is_current = (
+ set(schemas.LIGAND_3D_PAIR_CANDIDATE_SCHEMA.names).issubset(
+ pair_schema.names
+ )
+ and payload.get("pair_output") == current_pair_output
+ )
+ if output_is_current and ligand_pair_output.is_file():
+ ligand_pair_stat = ligand_pair_output.stat()
+ current_ligand_pair_output = {
+ "path": str(ligand_pair_output.resolve()),
+ "size": ligand_pair_stat.st_size,
+ "mtime_ns": ligand_pair_stat.st_mtime_ns,
+ "rows": pq.ParquetFile(ligand_pair_output).metadata.num_rows,
+ }
+ ligand_pair_output_is_current = (
+ payload.get("ligand_pair_inputs") == expected_ligand_pair_inputs
+ and payload.get("ligand_pair_output")
+ == current_ligand_pair_output
+ and pq.read_schema(ligand_pair_output).equals(
+ schemas.LIGAND_PAIR_SCORE_SCHEMA
+ )
+ )
+ except (OSError, TypeError, ValueError):
+ output_is_current = False
+ pair_output_is_current = False
+ ligand_pair_output_is_current = False
+
+ if (
+ output_is_current
+ and pair_output_is_current
+ and ligand_pair_output_is_current
+ ):
+ outputs.append(output)
+ continue
+
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ temporary = scratch_dir / f"shard={shard}.parquet"
+ if not output_is_current:
+ source_paths = [Path(str(item["path"])) for item in inputs]
+ paths_sql = ", ".join(f"'{path.as_posix()}'" for path in source_paths)
+ temporary.unlink(missing_ok=True)
+ if patch_existing:
+ connection.register(
+ "replacement_queries",
+ pd.DataFrame({"query_entry": replaced_pdb_ids}),
+ )
+ replacement_sql = (
+ f"SELECT * FROM read_parquet([{paths_sql}])"
+ if source_paths
+ else f"SELECT * FROM read_parquet('{output.as_posix()}') "
+ "WHERE false"
+ )
+ source_sql = f"""
+ SELECT existing.*
+ FROM read_parquet('{output.as_posix()}') AS existing
+ ANTI JOIN replacement_queries USING (query_entry)
+ UNION ALL BY NAME
+ {replacement_sql}
+ """
+ else:
+ source_sql = f"SELECT * FROM read_parquet([{paths_sql}])"
+ connection.sql(
+ f"""
+ COPY (
+ SELECT * FROM ({source_sql})
+ ORDER BY
+ query_entry,
+ query_ligand_asym_id,
+ target_entry,
+ target_ligand_asym_id,
+ query_system,
+ target_system
+ ) TO '{temporary.as_posix()}' (FORMAT PARQUET, COMPRESSION ZSTD)
+ """
+ )
+ observed_rows = pq.ParquetFile(temporary).metadata.num_rows
+ expected_rows = cast(
+ tuple[int],
+ connection.sql(f"SELECT count(*) FROM ({source_sql})").fetchone(),
+ )[0]
+ if observed_rows != expected_rows:
+ connection.close()
+ raise ValueError(
+ f"ligand 3D candidate shard {shard} has {observed_rows} rows; "
+ f"expected {expected_rows}"
+ )
+ output.parent.mkdir(exist_ok=True, parents=True)
+ install = output.with_suffix(output.suffix + ".tmp")
+ copyfile(temporary, install)
+ install.replace(output)
+ temporary.unlink(missing_ok=True)
+
+ ligand_pair_temporary = scratch_dir / f"ligand-pair-shard={shard}.parquet"
+ if not ligand_pair_output_is_current:
+ ligand_pair_columns_sql = ", ".join(schemas.LIGAND_PAIR_SCORE_SCHEMA.names)
+ ligand_pair_source_paths = [
+ Path(str(item["path"])) for item in ligand_pair_inputs
+ ]
+ ligand_pair_paths_sql = ", ".join(
+ f"'{path.as_posix()}'" for path in ligand_pair_source_paths
+ )
+ ligand_pair_temporary.unlink(missing_ok=True)
+ if patch_existing:
+ connection.register(
+ "ligand_pair_replacement_queries",
+ pd.DataFrame({"query_entry": replaced_pdb_ids}),
+ )
+ ligand_pair_replacement_sql = (
+ f"SELECT {ligand_pair_columns_sql} "
+ f"FROM read_parquet([{ligand_pair_paths_sql}])"
+ if ligand_pair_source_paths
+ else f"SELECT {ligand_pair_columns_sql} FROM "
+ f"read_parquet('{ligand_pair_output.as_posix()}') WHERE false"
+ )
+ ligand_pair_source_sql = f"""
+ SELECT {ligand_pair_columns_sql}
+ FROM read_parquet('{ligand_pair_output.as_posix()}') AS existing
+ ANTI JOIN ligand_pair_replacement_queries USING (query_entry)
+ UNION ALL BY NAME
+ {ligand_pair_replacement_sql}
+ """
+ else:
+ ligand_pair_source_sql = (
+ f"SELECT {ligand_pair_columns_sql} "
+ f"FROM read_parquet([{ligand_pair_paths_sql}])"
+ )
+ connection.sql(
+ f"""
+ COPY (
+ SELECT * FROM ({ligand_pair_source_sql})
+ ORDER BY
+ query_entry,
+ query_ligand_asym_id,
+ target_entry,
+ target_ligand_asym_id,
+ query_system,
+ query_ligand_id,
+ target_system,
+ target_ligand_id
+ ) TO '{ligand_pair_temporary.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD
+ )
+ """
+ )
+ observed_ligand_pair_rows = pq.ParquetFile(
+ ligand_pair_temporary
+ ).metadata.num_rows
+ expected_ligand_pair_rows = cast(
+ tuple[int],
+ connection.sql(
+ f"SELECT count(*) FROM ({ligand_pair_source_sql})"
+ ).fetchone(),
+ )[0]
+ duplicate_ligand_pairs = cast(
+ tuple[int],
+ connection.sql(
+ f"""
+ SELECT count(*)
+ FROM (
+ SELECT
+ query_system,
+ query_ligand_id,
+ target_system,
+ target_ligand_id
+ FROM read_parquet('{ligand_pair_temporary.as_posix()}')
+ GROUP BY ALL
+ HAVING count(*) > 1
+ )
+ """
+ ).fetchone(),
+ )[0]
+ if (
+ observed_ligand_pair_rows != expected_ligand_pair_rows
+ or duplicate_ligand_pairs
+ ):
+ connection.close()
+ raise ValueError(
+ f"ligand pair score shard {shard} has "
+ f"{observed_ligand_pair_rows}/{expected_ligand_pair_rows} rows "
+ f"and {duplicate_ligand_pairs} duplicate pairs"
+ )
+ if not pq.read_schema(ligand_pair_temporary).equals(
+ schemas.LIGAND_PAIR_SCORE_SCHEMA
+ ):
+ connection.close()
+ raise ValueError(
+ f"ligand pair score shard {shard} has an unexpected schema"
+ )
+ ligand_pair_output.parent.mkdir(exist_ok=True, parents=True)
+ ligand_pair_install = ligand_pair_output.with_suffix(
+ ligand_pair_output.suffix + ".tmp"
+ )
+ copyfile(ligand_pair_temporary, ligand_pair_install)
+ ligand_pair_install.replace(ligand_pair_output)
+ ligand_pair_temporary.unlink(missing_ok=True)
+
+ pair_temporary = scratch_dir / f"pair-shard={shard}.parquet"
+ pair_temporary.unlink(missing_ok=True)
+ connection.sql(
+ f"""
+ COPY (
+ SELECT
+ query_entry,
+ query_ligand_asym_id,
+ target_entry,
+ target_ligand_asym_id,
+ max(pocket_qcov)::DOUBLE AS pocket_qcov
+ FROM read_parquet('{output.as_posix()}')
+ GROUP BY
+ query_entry,
+ query_ligand_asym_id,
+ target_entry,
+ target_ligand_asym_id
+ ORDER BY
+ query_entry,
+ query_ligand_asym_id,
+ target_entry,
+ target_ligand_asym_id
+ ) TO '{pair_temporary.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD
+ )
+ """
+ )
+ connection.close()
+ pair_output.parent.mkdir(exist_ok=True, parents=True)
+ pair_install = pair_output.with_suffix(pair_output.suffix + ".tmp")
+ copyfile(pair_temporary, pair_install)
+ pair_install.replace(pair_output)
+ pair_temporary.unlink(missing_ok=True)
+
+ output_stat = output.stat()
+ observed_rows = pq.ParquetFile(output).metadata.num_rows
+ pair_output_stat = pair_output.stat()
+ ligand_pair_output_stat = ligand_pair_output.stat()
+ payload = {
+ "shard": shard,
+ "inputs": expected_inputs,
+ "output": {
+ "path": str(output.resolve()),
+ "size": output_stat.st_size,
+ "mtime_ns": output_stat.st_mtime_ns,
+ "rows": observed_rows,
+ },
+ "pair_output": {
+ "path": str(pair_output.resolve()),
+ "size": pair_output_stat.st_size,
+ "mtime_ns": pair_output_stat.st_mtime_ns,
+ "rows": pq.ParquetFile(pair_output).metadata.num_rows,
+ },
+ "ligand_pair_inputs": expected_ligand_pair_inputs,
+ "ligand_pair_output": {
+ "path": str(ligand_pair_output.resolve()),
+ "size": ligand_pair_output_stat.st_size,
+ "mtime_ns": ligand_pair_output_stat.st_mtime_ns,
+ "rows": pq.ParquetFile(ligand_pair_output).metadata.num_rows,
+ },
+ }
+ manifest.parent.mkdir(exist_ok=True, parents=True)
+ temporary_manifest = manifest.with_suffix(".tmp.json")
+ temporary_manifest.write_text(
+ json.dumps(payload, indent=2, sort_keys=True) + "\n"
+ )
+ temporary_manifest.replace(manifest)
+ outputs.append(output)
+ return outputs
+
+
+def make_ligand_3d_scores(
+ *,
+ data_dir: Path,
+ pairs: pd.DataFrame,
+ batch_index: int,
+ scorer_cfg: DictConfig,
+ force_update: bool,
+ scratch_dir: Path,
+ threads: int,
+ output_path: Path | None = None,
+) -> Path:
+ """Score one balanced batch of unique canonical ASU ligand pairs."""
+ if batch_index < 0 or threads < 1:
+ raise ValueError("batch index must be non-negative and threads positive")
+ pair_columns = [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ missing = sorted(set(pair_columns).difference(pairs.columns))
+ if missing:
+ raise ValueError(f"ligand 3D work batch is missing columns {missing}")
+ expected_pairs = pd.MultiIndex.from_frame(
+ pairs[pair_columns].drop_duplicates(ignore_index=True)
+ )
+ if len(expected_pairs) != len(pairs):
+ raise ValueError("ligand 3D work batch contains duplicate canonical pairs")
+ output = output_path or (
+ data_dir / "scores" / "ligand_3d_pairs" / f"{batch_index}.parquet"
+ )
+ if output.is_file() and not force_update:
+ try:
+ existing_schema = pq.read_schema(output)
+ existing_pairs = pd.MultiIndex.from_frame(
+ pd.read_parquet(output, columns=pair_columns)
+ )
+ if set(schemas.LIGAND_3D_SCORE_SCHEMA.names).issubset(
+ existing_schema.names
+ ) and existing_pairs.equals(expected_pairs):
+ return output
+ except (OSError, ValueError):
+ pass
+
+ scorer, _, _ = utils.get_scorer(
+ data_dir=data_dir,
+ pdb_ids=[],
+ scorer_cfg=scorer_cfg,
load_entries=False,
+ scratch_dir=scratch_dir,
+ )
+ scorer.shape_score_threads = threads
+ scores = scorer.score_canonical_ligand_pairs(data_dir, pairs)
+ table = pa.Table.from_pandas(
+ scores,
+ schema=schemas.LIGAND_3D_SCORE_SCHEMA,
+ preserve_index=False,
+ )
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ temporary = scratch_dir / f"ligand-3d-{output.stem}.parquet"
+ pq.write_table(
+ table,
+ temporary,
+ compression="zstd",
+ )
+ output.parent.mkdir(exist_ok=True, parents=True)
+ install = output.with_suffix(output.suffix + ".tmp")
+ copyfile(temporary, install)
+ install.replace(output)
+ temporary.unlink(missing_ok=True)
+ return output
+
+
+def scatter_ligand_3d_score_batches(*, data_dir: Path) -> list[list[int]]:
+ """Return the frozen canonical-pair batch indices."""
+ from plinder.data.pipeline.score import _load_plan
+
+ plan = _load_plan(data_dir)
+ if "ligand_3d_batch_count" not in plan:
+ raise ValueError("ligand 3D score batches have not been planned")
+ return [[index] for index in range(int(plan["ligand_3d_batch_count"]))]
+
+
+def collate_ligand_3d_scores(
+ *,
+ data_dir: Path,
+ shards: list[str],
+ scratch_dir: Path,
+ threads: int,
+) -> list[Path]:
+ """Repartition balanced pair-score batches for fast query-PDB lookup."""
+ from plinder.data.pipeline.score import (
+ LIGAND_3D_WORK_RELATIVE,
+ active_scoring_query_ids,
+ )
+
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ import duckdb
+
+ pair_columns = [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ work_path = data_dir / LIGAND_3D_WORK_RELATIVE
+ pair_dir = data_dir / "scores" / "ligand_3d_pairs"
+ output_dir = data_dir / "scores" / "ligand_3d_by_query"
+ output_dir.mkdir(exist_ok=True, parents=True)
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ active_queries = active_scoring_query_ids(data_dir)
+ outputs: list[Path] = []
+ for shard in shards:
+ if len(shard) != 2:
+ raise ValueError(f"invalid ligand 3D query shard: {shard!r}")
+ shard_queries = sorted(
+ pdb_id for pdb_id in active_queries if pdb_id[1:3] == shard
+ )
+ if not shard_queries:
+ continue
+ query_values = ", ".join(f"'{pdb_id}'" for pdb_id in shard_queries)
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{scratch_dir.as_posix()}'")
+ batch_rows = connection.sql(
+ f"""
+ SELECT DISTINCT ligand_3d_batch_index
+ FROM read_parquet('{work_path.as_posix()}')
+ WHERE substr(query_entry, 2, 2) = '{shard}'
+ AND query_entry IN ({query_values})
+ ORDER BY ligand_3d_batch_index
+ """
+ ).fetchall()
+ batch_paths = [pair_dir / f"{int(row[0])}.parquet" for row in batch_rows]
+ missing = [path for path in batch_paths if not path.is_file()]
+ if missing:
+ connection.close()
+ raise FileNotFoundError(
+ f"missing ligand 3D pair batches for shard {shard}: {missing[:10]}"
+ )
+ temporary = scratch_dir / f"{shard}.parquet"
+ temporary.unlink(missing_ok=True)
+ if not batch_paths:
+ connection.close()
+ pq.write_table(
+ pa.Table.from_pylist([], schema=schemas.LIGAND_3D_SCORE_SCHEMA),
+ temporary,
+ )
+ else:
+ paths_sql = ", ".join(f"'{path.as_posix()}'" for path in batch_paths)
+ keys = ", ".join(pair_columns)
+ counts = connection.sql(
+ f"""
+ WITH expected AS (
+ SELECT {keys}
+ FROM read_parquet('{work_path.as_posix()}')
+ WHERE substr(query_entry, 2, 2) = '{shard}'
+ AND query_entry IN ({query_values})
+ ), observed AS (
+ SELECT scored.*
+ FROM read_parquet([{paths_sql}]) AS scored
+ INNER JOIN expected USING ({keys})
+ )
+ SELECT
+ (SELECT count(*) FROM expected),
+ (SELECT count(*) FROM observed),
+ (SELECT count(*) - count(DISTINCT ({keys})) FROM observed)
+ """
+ ).fetchone()
+ if counts is None:
+ connection.close()
+ raise RuntimeError(f"failed to validate ligand 3D query shard {shard}")
+ if counts[0] != counts[1] or counts[2]:
+ connection.close()
+ raise ValueError(
+ f"ligand 3D query shard {shard} has invalid coverage: "
+ f"expected={counts[0]}, observed={counts[1]}, "
+ f"duplicates={counts[2]}"
+ )
+ connection.sql(
+ f"""
+ COPY (
+ WITH expected AS (
+ SELECT {keys}
+ FROM read_parquet('{work_path.as_posix()}')
+ WHERE substr(query_entry, 2, 2) = '{shard}'
+ AND query_entry IN ({query_values})
+ )
+ SELECT scored.*
+ FROM read_parquet([{paths_sql}]) AS scored
+ INNER JOIN expected USING ({keys})
+ ORDER BY {keys}
+ ) TO '{temporary.as_posix()}' (FORMAT PARQUET, COMPRESSION ZSTD)
+ """
+ )
+ connection.close()
+ output = output_dir / f"{shard}.parquet"
+ install = output.with_suffix(output.suffix + ".tmp")
+ copyfile(temporary, install)
+ install.replace(output)
+ temporary.unlink(missing_ok=True)
+ outputs.append(output)
+ return outputs
+
+
+def _ligand_3d_query_shard_is_ready(*, data_dir: Path, shard: str) -> bool:
+ """Return whether every canonical-pair batch needed by a query shard exists."""
+ import duckdb
+
+ from plinder.data.pipeline.score import (
+ LIGAND_3D_WORK_RELATIVE,
+ active_scoring_query_ids,
+ )
+
+ work_path = data_dir / LIGAND_3D_WORK_RELATIVE
+ shard_queries = sorted(
+ pdb_id for pdb_id in active_scoring_query_ids(data_dir) if pdb_id[1:3] == shard
+ )
+ if not shard_queries:
+ return False
+ query_values = ", ".join(f"'{pdb_id}'" for pdb_id in shard_queries)
+ batch_rows = duckdb.sql(
+ f"""
+ SELECT DISTINCT ligand_3d_batch_index
+ FROM read_parquet('{work_path.as_posix()}')
+ WHERE substr(query_entry, 2, 2) = '{shard}'
+ AND query_entry IN ({query_values})
+ """
+ ).fetchall()
+ pair_dir = data_dir / "scores" / "ligand_3d_pairs"
+ return all((pair_dir / f"{int(row[0])}.parquet").is_file() for row in batch_rows)
+
+
+def merge_ligand_3d_scores(
+ *,
+ data_dir: Path,
+ shards: list[str],
+ scorer_cfg: DictConfig,
+ force_update: bool,
+ scratch_dir: Path,
+ threads: int = 1,
+ reuse_cached_pairs: bool = False,
+ replacement_query_ids: set[str] | None = None,
+) -> list[Path]:
+ """Publish complete score shards or patch selected query entries."""
+ from plinder.data.pipeline.score import published_scoring_query_ids
+
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ import duckdb
+
+ metric_columns = ["shape", "color", "sucos_shape"]
+ all_ligand_metrics = [*metric_columns, "sucos_shape_pocket_qcov"]
+ pair_keys = [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ candidate_keys = [
+ "query_system",
+ "query_ligand_id",
+ "target_system",
+ "target_ligand_id",
+ ]
+ outputs: list[Path] = []
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ output_dir = data_dir / "scores" / "search_db=holo"
+ output_dir.mkdir(exist_ok=True, parents=True)
+ published_queries = published_scoring_query_ids(data_dir)
+ patch_existing = replacement_query_ids is not None
+ replacement_query_ids = set(map(str, replacement_query_ids or set()))
+ if patch_existing and not reuse_cached_pairs:
+ raise ValueError("query replacement requires cached ligand-pair scores")
+ active_queries = (
+ published_queries.intersection(replacement_query_ids)
+ if patch_existing
+ else published_queries
+ )
+ thresholds = {
+ metric: float(
+ scorer_cfg.minimum_thresholds.get(metric, scorer_cfg.minimum_threshold)
+ )
+ for metric in all_ligand_metrics
+ }
+
+ for shard in shards:
+ if len(shard) != 2 or any(
+ char not in ascii_lowercase + digits for char in shard
+ ):
+ raise ValueError(f"invalid ligand 3D query shard: {shard!r}")
+ output = output_dir / f"{shard}.parquet"
+ replaced_pdb_ids = sorted(
+ pdb_id for pdb_id in replacement_query_ids if pdb_id[1:3] == shard
+ )
+ if patch_existing and not replaced_pdb_ids:
+ continue
+ if patch_existing and not output.is_file():
+ raise FileNotFoundError(
+ f"score patch requires existing published shard: {output}"
+ )
+ if output.is_file() and not force_update and not patch_existing:
+ schema = pq.read_schema(output)
+ if set(schemas.PROTEIN_SIMILARITY_SCHEMA.names).issubset(schema.names):
+ outputs.append(output)
+ continue
+ pair_path = data_dir / "scores" / "ligand_3d_by_query" / f"{shard}.parquet"
+ if reuse_cached_pairs:
+ if not pair_path.is_file():
+ raise FileNotFoundError(
+ f"missing cached canonical ligand-pair scores for shard {shard}"
+ )
+ else:
+ if not _ligand_3d_query_shard_is_ready(data_dir=data_dir, shard=shard):
+ raise RuntimeError(
+ f"ligand 3D query shard {shard} is not ready; retry this merge "
+ "task after all canonical-pair batches are complete"
+ )
+ collate_ligand_3d_scores(
+ data_dir=data_dir,
+ shards=[shard],
+ scratch_dir=scratch_dir / "pairs" / shard,
+ threads=threads,
+ )
+ candidate_path = (
+ data_dir
+ / "scores"
+ / "ligand_3d_candidate_shards"
+ / f"shard={shard}.parquet"
+ )
+ pdb_ids = sorted(pdb_id for pdb_id in active_queries if pdb_id[1:3] == shard)
+ base_paths = [
+ data_dir / "dbs" / "subdbs" / "search_db=holo" / f"{pdb_id}.parquet"
+ for pdb_id in pdb_ids
+ ]
+ missing_inputs = [
+ path
+ for path in [candidate_path, pair_path, *base_paths]
+ if not path.is_file()
+ ]
+ if missing_inputs:
+ raise FileNotFoundError(
+ f"missing score inputs for query shard {shard}: {missing_inputs[:10]}"
+ )
+ base_paths_sql = ", ".join(f"'{path.as_posix()}'" for path in base_paths)
+ pair_keys_sql = ", ".join(pair_keys)
+ candidate_keys_sql = ", ".join(candidate_keys)
+ shard_scratch = scratch_dir / shard
+ shard_scratch.mkdir(exist_ok=True, parents=True)
+ connection = duckdb.connect()
+ connection.sql(f"SET threads={threads}")
+ connection.sql(f"SET temp_directory='{shard_scratch.as_posix()}'")
+ if patch_existing:
+ connection.register(
+ "replacement_queries",
+ pd.DataFrame({"query_entry": replaced_pdb_ids}),
+ )
+ candidate_sql = f"""
+ SELECT candidates.*
+ FROM read_parquet('{candidate_path.as_posix()}') AS candidates
+ INNER JOIN replacement_queries USING (query_entry)
+ """
+ else:
+ candidate_sql = f"SELECT * FROM read_parquet('{candidate_path.as_posix()}')"
+
+ validation = connection.sql(
+ f"""
+ WITH candidates AS (
+ {candidate_sql}
+ ), pairs AS (
+ SELECT *
+ FROM read_parquet('{pair_path.as_posix()}')
+ ), merged AS (
+ SELECT candidates.*, pairs.query_entry AS matched_query_entry
+ FROM candidates
+ LEFT JOIN pairs USING ({pair_keys_sql})
+ )
+ SELECT
+ (SELECT count(*) - count(DISTINCT ({candidate_keys_sql}))
+ FROM candidates) AS duplicate_candidates,
+ (SELECT count(*) FROM merged WHERE matched_query_entry IS NULL)
+ AS missing_pairs,
+ (SELECT count(*) - count(DISTINCT ({pair_keys_sql})) FROM pairs)
+ AS duplicate_pairs
+ """
+ ).fetchone()
+ if validation is None:
+ connection.close()
+ raise RuntimeError(f"failed to validate ligand 3D query shard {shard}")
+ if any(int(value) for value in validation):
+ connection.close()
+ raise ValueError(
+ f"invalid ligand 3D query shard {shard}: "
+ f"duplicate_candidates={validation[0]}, "
+ f"missing_pairs={validation[1]}, duplicate_pairs={validation[2]}"
+ )
+
+ metric_selects = []
+ for metric in all_ligand_metrics:
+ value = (
+ "sucos_shape * pocket_qcov"
+ if metric == "sucos_shape_pocket_qcov"
+ else metric
+ )
+ metric_selects.append(
+ dedent(
+ f"""
+ SELECT
+ query_system,
+ query_ligand_id,
+ target_system,
+ target_ligand_id,
+ protein_mapping,
+ NULL::VARCHAR AS mapping,
+ protein_mapper,
+ NULL::VARCHAR AS source,
+ '{metric}'::VARCHAR AS metric,
+ round(({value}) * 100)::TINYINT AS similarity
+ FROM merged
+ WHERE {value} IS NOT NULL
+ AND {value} >= {thresholds[metric]:.17g}
+ """
+ )
+ )
+ metric_union = "\nUNION ALL\n".join(metric_selects)
+ excluded_metrics = ", ".join(f"'{metric}'" for metric in all_ligand_metrics)
+ if patch_existing:
+ replacement_base_sql = (
+ f"""
+ SELECT *
+ FROM read_parquet(
+ [{base_paths_sql}],
+ hive_partitioning = false
+ )
+ WHERE metric NOT IN ({excluded_metrics})
+ AND NOT starts_with(cast(metric AS VARCHAR), 'protein_')
+ """
+ if base_paths
+ else f"""
+ SELECT *
+ FROM read_parquet(
+ '{output.as_posix()}', hive_partitioning = false
+ )
+ WHERE false
+ """
+ )
+ base_scores_sql = f"""
+ SELECT existing.*
+ FROM read_parquet(
+ '{output.as_posix()}', hive_partitioning = false
+ ) AS existing
+ ANTI JOIN replacement_queries
+ ON split_part(existing.query_system, '__', 1)
+ = replacement_queries.query_entry
+ WHERE NOT starts_with(
+ cast(existing.metric AS VARCHAR), 'protein_'
+ )
+ UNION ALL BY NAME
+ {replacement_base_sql}
+ """
+ else:
+ base_scores_sql = f"""
+ SELECT *
+ FROM read_parquet(
+ [{base_paths_sql}],
+ hive_partitioning = false
+ )
+ WHERE metric NOT IN ({excluded_metrics})
+ AND NOT starts_with(cast(metric AS VARCHAR), 'protein_')
+ """
+ local_output = shard_scratch / f"{shard}.parquet"
+ local_output.unlink(missing_ok=True)
+ connection.sql(
+ dedent(
+ f"""
+ COPY (
+ WITH candidates AS (
+ {candidate_sql}
+ ), pairs AS (
+ SELECT *
+ FROM read_parquet('{pair_path.as_posix()}')
+ ), merged AS (
+ SELECT candidates.*, pairs.shape, pairs.color,
+ pairs.sucos_shape
+ FROM candidates
+ INNER JOIN pairs USING ({pair_keys_sql})
+ ), ligand_scores AS (
+ {metric_union}
+ ), base_scores AS (
+ {base_scores_sql}
+ )
+ SELECT * FROM base_scores
+ UNION ALL
+ SELECT * FROM ligand_scores
+ ORDER BY
+ similarity DESC,
+ query_system,
+ query_ligand_id,
+ target_system,
+ target_ligand_id
+ ) TO '{local_output.as_posix()}' (
+ FORMAT PARQUET,
+ COMPRESSION ZSTD,
+ ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ )
+ connection.close()
+ install = output.with_suffix(output.suffix + ".tmp")
+ copyfile(local_output, install)
+ install.replace(output)
+ local_output.unlink(missing_ok=True)
+ outputs.append(output)
+ return outputs
+
+
+def _write_alignment_release_shard(
+ *,
+ sources: list[Path],
+ target: Path,
+ alignment_type: str,
+ temp_dir: Path,
+ threads: int,
+ memory_limit: str,
+ protein_scores_target: Path | None = None,
+) -> None:
+ """Write alignment CIGARs and compact protein statistics for one query shard."""
+ import duckdb
+
+ con = duckdb.connect()
+ temp_dir.mkdir(exist_ok=True, parents=True)
+ con.sql(f"set temp_directory='{temp_dir.as_posix()}';")
+ con.sql(f"set threads={threads};")
+ con.sql(f"set memory_limit='{memory_limit}';")
+ target.parent.mkdir(exist_ok=True, parents=True)
+ non_empty_sources = [
+ path for path in sources if pq.ParquetFile(path).metadata.num_rows > 0
+ ]
+ temporary = temp_dir / target.name
+ temporary.unlink(missing_ok=True)
+ protein_scores_temporary = (
+ temp_dir / f"protein-scores-{target.name}"
+ if protein_scores_target is not None
+ else None
)
- for search_db in scorer_cfg.sub_databases:
- for pdb_id in tqdm(entry_ids):
- scorer.get_score_df(
- data_dir, pdb_id, search_db=search_db, overwrite=force_update
+ if protein_scores_temporary is not None:
+ protein_scores_temporary.unlink(missing_ok=True)
+ if non_empty_sources:
+ source_sql = ", ".join(f"'{path.as_posix()}'" for path in non_empty_sources)
+ metric_sql = (
+ ""
+ if protein_scores_target is not None
+ else (
+ " qcov, tcov, fident, seqsim, "
+ + ("lddt" if alignment_type == "foldseek" else "NULL::DOUBLE")
+ + " AS lddt,"
+ )
+ )
+ con.sql(
+ dedent(
+ f"""
+ COPY (
+ SELECT
+ query_entry,
+ target_entry,
+ query_chain_mapped,
+ target_chain_mapped,
+ source,
+ CAST(qstart AS UINTEGER) AS query_start,
+ CAST(tstart AS UINTEGER) AS target_start,
+ cigar::VARCHAR AS cigar,
+ {metric_sql}
+ CAST(selected_residue_identity_bits AS BLOB)
+ AS selected_residue_identity_bits
+ FROM read_parquet(
+ [{source_sql}], union_by_name = true
+ )
+ ORDER BY query_entry, target_entry,
+ query_chain_mapped, target_chain_mapped, source
+ ) TO '{temporary.as_posix()}'
+ (FORMAT PARQUET, COMPRESSION ZSTD, COMPRESSION_LEVEL 9,
+ ROW_GROUP_SIZE 500_000);
+ """
+ )
+ )
+ if protein_scores_temporary is not None:
+ lddt = (
+ "CAST(least(100, greatest(0, round(lddt * 100))) AS UTINYINT)"
+ if alignment_type == "foldseek"
+ else "NULL::UTINYINT"
+ )
+ con.sql(
+ dedent(
+ f"""
+ COPY (
+ SELECT
+ query_entry::VARCHAR AS query_entry,
+ target_entry::VARCHAR AS target_entry,
+ query_chain_mapped::VARCHAR AS query_chain_mapped,
+ target_chain_mapped::VARCHAR AS target_chain_mapped,
+ source::VARCHAR AS source,
+ CAST(least(100, greatest(0, round(qcov * 100)))
+ AS UTINYINT) AS qcov,
+ CAST(least(100, greatest(0, round(tcov * 100)))
+ AS UTINYINT) AS tcov,
+ CAST(least(100, greatest(0, round(fident * 100)))
+ AS UTINYINT) AS fident,
+ CAST(least(100, greatest(0, round(seqsim * 100)))
+ AS UTINYINT) AS seqsim,
+ {lddt} AS lddt
+ FROM read_parquet([{source_sql}], union_by_name = true)
+ ORDER BY query_entry, target_entry,
+ query_chain_mapped, target_chain_mapped, source
+ ) TO '{protein_scores_temporary.as_posix()}'
+ (FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 500_000);
+ """
+ )
+ )
+ else:
+ pq.write_table(
+ pa.Table.from_pylist(
+ [],
+ schema=schemas.release_alignment_mapping_schema(
+ alignment_type=alignment_type,
+ include_scores=protein_scores_target is None,
+ ),
+ ),
+ temporary,
+ compression="zstd",
+ )
+ if protein_scores_temporary is not None:
+ pq.write_table(
+ pa.Table.from_pylist(
+ [],
+ schema=schemas.PROTEIN_SIMILARITY_EXPORT_SCHEMA,
+ ),
+ protein_scores_temporary,
+ compression="zstd",
+ )
+ con.close()
+ install_path = target.with_suffix(target.suffix + ".tmp")
+ copyfile(temporary, install_path)
+ install_path.replace(target)
+ temporary.unlink(missing_ok=True)
+ if protein_scores_target is not None and protein_scores_temporary is not None:
+ protein_scores_target.parent.mkdir(exist_ok=True, parents=True)
+ install_path = protein_scores_target.with_suffix(
+ protein_scores_target.suffix + ".tmp"
+ )
+ copyfile(protein_scores_temporary, install_path)
+ install_path.replace(protein_scores_target)
+ protein_scores_temporary.unlink(missing_ok=True)
+
+
+def scatter_collate_alignments(*, data_dir: Path) -> list[list[str]]:
+ """Return mapped alignment shards that require release collation."""
+ mapped_files = (data_dir / "dbs" / "subdbs").glob("*_*/mapped_aln/*.parquet")
+ shards = sorted(
+ {
+ path.stem[-3:-1]
+ for path in mapped_files
+ if not path.name.endswith(".tmp.parquet")
+ }
+ )
+ # Preserve a no-op branch for callers using the scatter/compute/join interface.
+ return [[shard] for shard in shards] or [[]]
+
+
+def collate_alignments(
+ *,
+ data_dir: Path,
+ partition: list[str],
+ scratch_dir: Path | None = None,
+ threads: int = 1,
+ memory_limit: str = "7GB",
+) -> None:
+ """Collate mapped Foldseek/MMseqs hits into query-addressable shards."""
+ if not partition:
+ LOG.info("collate_alignments: no mapped alignments found")
+ return
+ [shard] = partition
+
+ scratch_root = scratch_dir or data_dir / "scratch" / "duckdb" / "alignments"
+ temp_dir = scratch_root / shard
+ for search_db in ["holo", "apo", "interface_apo", "pred"]:
+ for alignment_type in ["foldseek", "mmseqs"]:
+ source_dir = (
+ data_dir
+ / "dbs"
+ / "subdbs"
+ / f"{search_db}_{alignment_type}"
+ / "mapped_aln"
+ )
+ sources = sorted(
+ path
+ for path in source_dir.glob("*.parquet")
+ if path.stem[-3:-1] == shard and not path.name.endswith(".tmp.parquet")
+ )
+ if not sources:
+ continue
+ target = _alignment_release_path(
+ data_dir=data_dir,
+ search_db=search_db,
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ _write_alignment_release_shard(
+ sources=sources,
+ target=target,
+ alignment_type=alignment_type,
+ temp_dir=temp_dir / f"{search_db}-{alignment_type}",
+ threads=threads,
+ memory_limit=memory_limit,
+ protein_scores_target=(
+ _protein_similarity_score_path(
+ data_dir=data_dir,
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ if search_db == "holo"
+ else None
+ ),
)
def scatter_collate_partitions() -> list[list[str]]:
partitions = [[i] for i in digits + ascii_lowercase] + [["apo"], ["pred"]]
- return partitions[:1]
+ return partitions
-def collate_partitions(*, data_dir: Path, partition: list[str]) -> None:
+def collate_partitions(
+ *,
+ data_dir: Path,
+ partition: list[str],
+ scratch_dir: Path | None = None,
+ threads: int = 1,
+ memory_limit: str = "7GB",
+) -> None:
"""
Collate the batch results from make_batch_scores into a partitioned
sorted dataset using duckdb.
@@ -754,8 +4528,14 @@ def collate_partitions(*, data_dir: Path, partition: list[str]) -> None:
part: str
[part] = partition
+ if threads < 1:
+ raise ValueError("threads must be positive")
con = duckdb.connect()
- con.sql(f"set temp_directory='/plinder/tmp/{part}';")
+ temp_dir = (scratch_dir or data_dir / "scratch" / "duckdb") / part
+ temp_dir.mkdir(exist_ok=True, parents=True)
+ con.sql(f"set temp_directory='{temp_dir.as_posix()}';")
+ con.sql(f"set threads={threads};")
+ con.sql(f"set memory_limit='{memory_limit}';")
search_db = "holo"
src = f"*{part}.parquet"
@@ -766,368 +4546,801 @@ def collate_partitions(*, data_dir: Path, partition: list[str]) -> None:
score_dir = data_dir / "scores" / f"search_db={search_db}"
source_dir = data_dir / "dbs" / "subdbs" / f"search_db={search_db}"
source = f"{source_dir}/{src}"
- target = f"{score_dir}/{tgt}"
+ target = score_dir / tgt
+ if not list(source_dir.glob(src)):
+ LOG.info(f"collate_partitions: no source files matching {source}")
+ return
score_dir.mkdir(exist_ok=True, parents=True)
+ local_target = temp_dir / tgt
+ local_target.unlink(missing_ok=True)
con.sql(
dedent(
f"""
COPY
(select * from '{source}')
TO
- '{target}'
- (FORMAT PARQUET, ROW_GROUP_SIZE 500_000);
+ '{local_target.as_posix()}'
+ (FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 500_000);
"""
)
)
+ con.close()
+ install = target.with_suffix(target.suffix + ".tmp")
+ copyfile(local_target, install)
+ install.replace(target)
+ local_target.unlink(missing_ok=True)
-def scatter_make_components_and_communities(
+def make_linked_apo_structures(
*,
data_dir: Path,
- metrics: list[str],
- thresholds: list[int],
- stop_on_cluster: int,
- skip_existing_clusters: bool,
-) -> list[list[tuple[str, int]]]:
- values = [[(metric, threshold)] for metric in metrics for threshold in thresholds]
-
- rerun = []
- for tup in values:
- metric, threshold = tup[0]
- do = False
- for cluster in ["components", "communities"]:
- for directed in [True, False]:
- if do:
- continue
- if not (
- data_dir
- / f"clusters/cluster={cluster}/directed={directed}/metric={metric}/threshold={threshold}.parquet"
- ).is_file() and not skip_existing_clusters:
- do = True
- if do:
- rerun.append(tup)
- if stop_on_cluster:
- values = values[:stop_on_cluster]
- return values
+ scratch_dir: Path | None = None,
+ threads: int = 1,
+ memory_limit: str = "7GB",
+) -> Path:
+ """Publish ranked deposited apo-chain links for ligands and interfaces."""
+ from plinder.data.interface_apo import (
+ CANDIDATE_COLUMNS,
+ build_interface_apo_candidate_manifest,
+ build_interface_apo_query_manifest,
+ write_interface_apo_structure_table,
+ )
+ from plinder.data.linked_apo import (
+ APO_CANDIDATE_COLUMNS,
+ build_apo_candidate_manifest,
+ ligand_holo_chain_keys,
+ write_linked_apo_structure_table,
+ )
+ from plinder.data.pipeline.score import INTERFACE_APO_QUERY_MANIFEST_RELATIVE
+ def write_empty_table(path: Path, schema: pa.Schema) -> None:
+ temporary = path.with_suffix(path.suffix + ".tmp")
+ pq.write_table(
+ pa.Table.from_pylist([], schema=schema), temporary, compression="zstd"
+ )
+ temporary.replace(path)
-def make_components_and_communities(
- *,
- data_dir: Path,
- metric_threshold: list[tuple[str, int]],
- skip_existing_clusters: bool,
-) -> None:
- [(metric, threshold)] = metric_threshold
- clusters.make_components_and_communities(
- data_dir=data_dir,
- metric=metric,
- threshold=threshold,
- # directed=True,
- skip_existing_clusters=skip_existing_clusters,
+ index_dir = data_dir / "index"
+ inputs = {
+ "annotation": index_dir / "annotation_table.parquet",
+ "entry_chains": index_dir / "entry_chains.parquet",
+ "biounit_chains": index_dir / "entry_biounit_chains.parquet",
+ "entry_metadata": index_dir / "entry_metadata.parquet",
+ "interface_annotation": index_dir / "interface_annotation_table.parquet",
+ }
+ for path in inputs.values():
+ if not path.is_file():
+ raise FileNotFoundError(path)
+ collation_marker_path = index_dir / collate.FINAL_MARKER_NAME
+ collation_marker = read_json_cache(collation_marker_path)
+ if collation_marker is None:
+ raise ValueError(
+ f"missing or invalid collation marker: {collation_marker_path}"
+ )
+ ligand_contacts_computed = collation_marker.get("ligand_contacts_computed")
+ protein_contacts_computed = collation_marker.get("protein_contacts_computed")
+ if not isinstance(ligand_contacts_computed, bool) or not isinstance(
+ protein_contacts_computed, bool
+ ):
+ raise ValueError(f"invalid contact state in {collation_marker_path}")
+
+ interface_queries = build_interface_apo_query_manifest(
+ inputs["interface_annotation"]
)
+ has_interfaces = not interface_queries.empty
+ if has_interfaces:
+ planned_interface_chains = pd.read_parquet(
+ data_dir / INTERFACE_APO_QUERY_MANIFEST_RELATIVE,
+ columns=["pdb_id", "chain_asym_id"],
+ ).rename(
+ columns={
+ "pdb_id": "query_entry",
+ "chain_asym_id": "reference_chain_asym_id",
+ }
+ )
+ interface_queries = interface_queries.merge(
+ planned_interface_chains,
+ on=["query_entry", "reference_chain_asym_id"],
+ how="inner",
+ validate="many_to_one",
+ )
+ has_ligand_queries = not ligand_holo_chain_keys(inputs["annotation"]).empty
+ manifest_dir = data_dir / "manifests"
+ manifest_dir.mkdir(exist_ok=True, parents=True)
+ output = index_dir / "linked_apo_structures.parquet"
+ if ligand_contacts_computed:
+ candidates = (
+ build_apo_candidate_manifest(
+ inputs["entry_chains"],
+ biounit_chains=inputs["biounit_chains"],
+ entry_metadata=inputs["entry_metadata"],
+ annotation=inputs["annotation"],
+ )
+ if has_ligand_queries
+ else pd.DataFrame(columns=APO_CANDIDATE_COLUMNS)
+ )
+ manifest = manifest_dir / "apo_candidates.parquet"
+ temporary_manifest = manifest.with_suffix(manifest.suffix + ".tmp")
+ candidates.to_parquet(temporary_manifest, index=False)
+ temporary_manifest.replace(manifest)
-def make_mmp_index(
- *,
- data_dir: Path,
-) -> None:
- """
- Get the list of all pdb IDs to load all the entries
- for mmp indexing.
- Parameters
- ----------
- data_dir : Path
- the root plinder dir
- """
+ if has_ligand_queries:
+ protein_scores = data_dir / "scores/search_db=apo/apo.parquet"
+ if not protein_scores.is_file():
+ raise FileNotFoundError(protein_scores)
+ write_linked_apo_structure_table(
+ protein_scores,
+ annotation=inputs["annotation"],
+ candidates=manifest,
+ output_path=output,
+ scratch_dir=scratch_dir,
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ else:
+ write_empty_table(output, schemas.STRUCTURE_LINK_SCHEMA)
+ LOG.info(
+ "make_linked_apo_structures: selected %d links from %d "
+ "apo-chain candidates",
+ pq.ParquetFile(output).metadata.num_rows,
+ len(candidates),
+ )
+ elif has_ligand_queries:
+ if not output.is_file():
+ raise FileNotFoundError(
+ "interface-only collation requires the existing ligand apo table: "
+ f"{output}"
+ )
+ LOG.info("make_linked_apo_structures: retaining %s", output)
+ else:
+ write_empty_table(output, schemas.STRUCTURE_LINK_SCHEMA)
- from plinder.data.utils.annotations.mmpdb_utils import (
- add_mmp_clusters_to_data,
- make_mmp_index_from_annotation_table,
- )
+ interface_output = index_dir / "interface_apo_structures.parquet"
+ if protein_contacts_computed:
+ for shard, rows in interface_queries.groupby(
+ interface_queries["query_entry"].str[1:3], sort=False
+ ):
+ if not alignment_mapping_shard_is_current(
+ data_dir=data_dir,
+ search_db="interface_apo",
+ shard=str(shard),
+ require_raw_inputs=False,
+ ):
+ raise ValueError(
+ f"interface apo alignment mapping is incomplete for shard {shard}"
+ )
+ mapping_path = _alignment_mapping_manifest_path(
+ data_dir=data_dir,
+ search_db="interface_apo",
+ shard=str(shard),
+ )
+ mapping = cast(dict[str, Any], read_json_cache(mapping_path))
+ mapped_entries = {
+ Path(str(source["name"])).stem for source in mapping["inputs"]["mmseqs"]
+ }.difference(mapping["skipped_queries"])
+ missing_entries = sorted(
+ set(rows["query_entry"].astype(str)).difference(mapped_entries)
+ )
+ if missing_entries:
+ raise ValueError(
+ f"interface apo queries were not mapped: {missing_entries[:10]}"
+ )
+ interface_candidates = (
+ build_interface_apo_candidate_manifest(
+ inputs["entry_chains"],
+ biounit_chains=inputs["biounit_chains"],
+ entry_metadata=inputs["entry_metadata"],
+ )
+ if not interface_queries.empty
+ else pd.DataFrame(columns=CANDIDATE_COLUMNS)
+ )
+ write_interface_apo_structure_table(
+ data_dir / "alignment_cigars/search_db=interface_apo/alignment_type=mmseqs",
+ foldseek_alignments=(
+ data_dir
+ / "alignment_cigars/search_db=interface_apo/alignment_type=foldseek"
+ ),
+ queries=interface_queries,
+ candidates=interface_candidates,
+ output_path=interface_output,
+ scratch_dir=(
+ scratch_dir / "interfaces" if scratch_dir is not None else None
+ ),
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ LOG.info(
+ "make_linked_apo_structures: selected %d interface-side links from "
+ "%d protein-contact-free candidates",
+ pq.ParquetFile(interface_output).metadata.num_rows,
+ len(interface_candidates),
+ )
+ elif has_interfaces:
+ if not interface_output.is_file():
+ raise FileNotFoundError(
+ "ligand-only collation requires the existing interface apo table: "
+ f"{interface_output}"
+ )
+ LOG.info("make_linked_apo_structures: retaining %s", interface_output)
+ else:
+ write_empty_table(interface_output, schemas.INTERFACE_APO_LINK_SCHEMA)
+ return output
- LOG.info("making annotation table (and non-redundant) indexes")
- utils.create_nonredundant_dataset(data_dir=data_dir)
- LOG.info("making mmp index for all entries")
- annotation_index = data_dir / "index" / "annotation_table.parquet"
- columns = ["system_id", "ligand_rdkit_canonical_smiles", "ligand_unique_ccd_code"]
- annotation_df = pd.read_parquet(annotation_index, columns=columns)
- mmp_df_path = make_mmp_index_from_annotation_table(data_dir, annotation_df)
- load_mmp_df = pd.read_csv(mmp_df_path, compression="gzip", header=None, sep="\t")
- load_mmp_df.columns = ["SMILES1", "SMILES2", "id1", "id2", "V1>>V2", "CONSTANT"]
- mmp_data = add_mmp_clusters_to_data(
- load_mmp_df,
- annotation_df,
- cluster_folder=data_dir / "clusters",
- )
- mmp_data.to_parquet(data_dir / "mmp" / "plinder_mmp_series.parquet", index=False)
+def scatter_component_reduction_sources(
+ *,
+ data_dir: Path,
+ metrics: list[str],
+ batch_size: int,
+ entity_type: clusters.ClusterEntity = "ligand",
+) -> list[list[str]]:
+ """Scatter each physical score shard once, independent of threshold count."""
+ if batch_size < 1:
+ raise ValueError("component reduction source batch size must be positive")
+ sources: set[Path] = set()
+ for metric in metrics:
+ sources.update(
+ clusters.component_score_sources(
+ data_dir=data_dir,
+ metric=metric,
+ entity_type=entity_type,
+ )
+ )
+ ordered = [str(path) for path in sorted(sources)]
+ return [
+ ordered[start : start + batch_size]
+ for start in range(0, len(ordered), batch_size)
+ ] or [[]]
-def scatter_make_splits(
+def make_symmetric_edge_fragments(
*,
data_dir: Path,
- split_config_dir: str,
-) -> list[list[tuple[DictConfig, str]]]:
- # defaults to empty string so skip it
- configs: list[list[tuple[DictConfig, str]]]
- if not len(split_config_dir):
- configs = [[]]
- # allow configs living in cloud buckets configured by PLINDER_BUCKET
- elif split_config_dir.startswith("gs:"):
- bucket_name = Path(split_config_dir).parts[1]
- configs = [
- [
- (
- splits.get_config(
- gcs.download_as_str(
- gcs_path=cloud_path,
- bucket_name=bucket_name,
- )
- ),
- cloud_path,
- )
- ]
- for cloud_path in gcs.list_dir(
- gcs_path=str(split_config_dir),
- bucket_name=bucket_name,
+ batches: list[dict[str, Any]],
+ scratch_dir: Path,
+ threads: int,
+ force_update: bool,
+ entity_type: clusters.ClusterEntity = "ligand",
+) -> None:
+ """Map raw score batches into hash-partitioned canonical-pair fragments."""
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ for batch_index, batch in enumerate(batches):
+ if not force_update and clusters.symmetric_edge_fragment_batch_is_complete(
+ data_dir=data_dir,
+ batch=batch,
+ entity_type=entity_type,
+ ):
+ LOG.info(
+ "symmetric fragment batch already complete: progress=%d/%d key=%s",
+ batch_index + 1,
+ len(batches),
+ batch["key"],
)
- ]
- else:
- # support relative local split_config_dir from data_dir
- # and absolute split_config_dir
- split_dir = Path(split_config_dir or "splits")
- if not split_dir.is_absolute():
- split_dir = data_dir / split_config_dir
- configs = [
- [
- (
- splits.get_config(path.read_text()),
- path.as_posix(),
- )
- ]
- for path in split_dir.rglob("*.yaml")
- ]
- for tup in configs:
- if len(tup[0]):
- LOG.info(f"scatter_make_splits: config={tup[0][1]}")
- return configs
+ continue
+ sources = [Path(str(value["path"])) for value in batch["sources"]]
+ local_sources: list[Path] = []
+ batch_scratch = scratch_dir / f"batch-{batch['key']}"
+ batch_scratch.mkdir(exist_ok=True, parents=True)
+ try:
+ for source_index, source in enumerate(sources):
+ local_source = batch_scratch / f"{source_index:04d}-{source.name}"
+ copyfile(source, local_source)
+ local_sources.append(local_source)
+ LOG.info(
+ "symmetric fragment batch copied: progress=%d/%d key=%s sources=%d",
+ batch_index + 1,
+ len(batches),
+ batch["key"],
+ len(sources),
+ )
+ clusters.write_symmetric_edge_fragment_batch(
+ data_dir=data_dir,
+ batch=batch,
+ scratch_dir=batch_scratch,
+ threads=threads,
+ force_update=force_update,
+ read_paths=local_sources,
+ entity_type=entity_type,
+ )
+ finally:
+ for local_source in local_sources:
+ local_source.unlink(missing_ok=True)
-def make_splits(
+def make_symmetric_edge_shards(
*,
data_dir: Path,
- cfg_and_path: list[tuple[DictConfig, str]],
+ metric_buckets: list[tuple[str, int]],
+ scratch_dir: Path,
+ threads: int,
+ force_update: bool,
+ entity_type: clusters.ClusterEntity = "ligand",
) -> None:
- [(cfg, path)] = cfg_and_path
- splits.split(data_dir=data_dir, cfg=cfg, relpath=path)
+ """Merge reciprocal fragment values into compact minimum edge shards."""
+ for index, (metric, bucket) in enumerate(metric_buckets, start=1):
+ LOG.info(
+ "symmetric edge shard start: progress=%d/%d metric=%s bucket=%d",
+ index,
+ len(metric_buckets),
+ metric,
+ bucket,
+ )
+ clusters.write_symmetric_edge_shard(
+ data_dir=data_dir,
+ metric=metric,
+ bucket=bucket,
+ scratch_dir=scratch_dir / f"{metric}-{bucket:03d}",
+ threads=threads,
+ force_update=force_update,
+ entity_type=entity_type,
+ )
-def scatter_compute_ligand_leakage(
+def scatter_make_set_covers(
*,
data_dir: Path,
- test_leakage: bool,
-) -> list[list[tuple[str, str, str]]]:
- paths = [path.as_posix() for path in (data_dir / "splits").glob("*parquet")]
- chunks = [
- [(path, compare_pair, metric)]
- for path in paths
- for compare_pair in [
- "train_test",
- "train_val",
- "val_test",
- "train_posebusters",
- ]
- for metric in [
- "tanimoto_similarity_max",
- ]
+ metrics: list[str],
+ thresholds: list[int],
+ stop_on_cluster: int,
+ skip_existing_clusters: bool,
+ entity_type: clusters.ClusterEntity = "ligand",
+) -> list[list[tuple[str, int]]]:
+ """Scatter ligand-Tanimoto set-cover work after component reduction."""
+ values = [
+ [(metric, threshold)]
+ for metric in metrics
+ if entity_type == "ligand" and is_chemical_cluster_metric(metric)
+ for threshold in thresholds
]
- if test_leakage:
- return chunks[:1]
- return chunks
+ if stop_on_cluster:
+ values = values[:stop_on_cluster]
+ if not skip_existing_clusters:
+ return values
+ pending = []
+ for item in values:
+ metric, threshold = item[0]
+ output = (
+ clusters._sampling_root(data_dir, entity_type)
+ / "set_cover"
+ / f"metric={metric}"
+ / f"threshold={threshold}.parquet"
+ )
+ if not clusters.set_cover_is_complete(output):
+ pending.append(item)
+ return pending or [[]]
-def scatter_compute_protein_leakage(
+def scatter_make_directed_set_covers(
*,
data_dir: Path,
- test_leakage: bool,
-) -> list[list[tuple[str, str, str]]]:
- paths = [path.as_posix() for path in (data_dir / "splits").glob("*parquet")]
- chunks = [
- [(path, compare_pair, metric)]
- for path in paths
- for compare_pair in [
- "train_test",
- "train_val",
- "val_test",
- "train_posebusters",
+ metrics: list[str],
+ thresholds: list[int],
+ stop_on_cluster: int,
+ skip_existing: bool,
+ entity_type: clusters.ClusterEntity = "ligand",
+) -> list[list[tuple[str, int]]]:
+ """Scatter one shared directed-cover pass per metric."""
+ values = [
+ (metric, threshold)
+ for metric in metrics
+ if not is_chemical_cluster_metric(metric)
+ for threshold in thresholds
+ ]
+ if stop_on_cluster:
+ values = values[:stop_on_cluster]
+ if not skip_existing:
+ pending = values
+ else:
+ pending = []
+ if skip_existing:
+ for metric, threshold in values:
+ output = (
+ clusters._sampling_root(data_dir, entity_type)
+ / "directed_set_cover"
+ / f"metric={metric}"
+ / f"threshold={threshold}.parquet"
+ )
+ if not clusters.directed_set_cover_is_complete(
+ output,
+ entity_type=entity_type,
+ ):
+ pending.append((metric, threshold))
+ grouped: dict[str, list[tuple[str, int]]] = {}
+ for metric, threshold in pending:
+ grouped.setdefault(metric, []).append((metric, threshold))
+ return list(grouped.values()) or [[]]
+
+
+_COMPONENT_REDUCTION_CONTEXT: dict[str, Any] | None = None
+
+
+def _initialize_component_reduction_worker(context: dict[str, Any]) -> None:
+ """Install immutable per-source state once in each metric worker."""
+ global _COMPONENT_REDUCTION_CONTEXT
+ _COMPONENT_REDUCTION_CONTEXT = context
+
+
+def _reduce_component_metric(metric_index: int, metric: str) -> dict[str, Any]:
+ """Reduce reciprocal and any-direction connectivity from one metric shard."""
+ context = _COMPONENT_REDUCTION_CONTEXT
+ if context is None:
+ raise RuntimeError("component reduction worker context is not initialized")
+ metric_started = time.time()
+ chemical = is_chemical_cluster_metric(metric)
+ if chemical:
+ manifests = [
+ clusters.make_score_component_reduction(
+ data_dir=context["data_dir"],
+ metric=metric,
+ thresholds=context["thresholds"],
+ source_path=context["source"],
+ read_path=context["local_source"],
+ all_nodes=context["nodes"],
+ eligible_systems=context["eligible_systems"],
+ force_update=context["force_update"],
+ entity_type=context["entity_type"],
+ )
]
- for metric in [
- "pli_qcov",
- "pocket_qcov",
- "pocket_lddt",
- "protein_seqsim_weighted_sum",
- "protein_fident_weighted_sum",
- "protein_lddt_weighted_sum",
- "protein_lddt_qcov_weighted_sum",
+ else:
+ manifests = [
+ clusters.make_score_component_reduction(
+ data_dir=context["data_dir"],
+ metric=metric,
+ thresholds=context["thresholds"],
+ source_path=context["source"],
+ read_path=context["local_source"],
+ all_nodes=context["nodes"],
+ eligible_systems=context["eligible_systems"],
+ force_update=context["force_update"],
+ entity_type=context["entity_type"],
+ ),
+ clusters.make_directed_cover_component_reduction(
+ data_dir=context["data_dir"],
+ metric=metric,
+ thresholds=context["thresholds"],
+ source_path=context["source"],
+ read_path=context["local_source"],
+ all_nodes=context["nodes"],
+ eligible_systems=context["eligible_systems"],
+ force_update=context["force_update"],
+ entity_type=context["entity_type"],
+ ),
]
- ]
- if test_leakage:
- return chunks[:1]
- return chunks
+ return {
+ "metric_index": metric_index,
+ "metric": metric,
+ "output_rows": sum(
+ int(output["rows"])
+ for manifest in manifests
+ for output in manifest["outputs"]
+ ),
+ "elapsed_seconds": time.time() - metric_started,
+ }
-def compute_ligand_leakage(
+def make_component_reductions(
*,
data_dir: Path,
- inputs: list[tuple[str, str, str]],
+ source_paths: list[str],
+ metrics: list[str],
+ thresholds: list[int],
+ scratch_dir: Path,
+ force_update: bool,
+ metric_workers: int = 1,
+ entity_type: clusters.ClusterEntity = "ligand",
) -> None:
- [(split_file, compare_pair, metric)] = inputs
- leakage.compute_ligand_leakage(
- data_dir=data_dir,
- split_file=split_file,
- compare_pair=compare_pair,
- metric=metric,
- )
+ """Map reciprocal-minimum edge sources to exact component reductions."""
+ if not source_paths:
+ return
+ if metric_workers < 1:
+ raise ValueError("component reduction metric workers must be positive")
+ nonchemical_metrics = [
+ metric for metric in metrics if not is_chemical_cluster_metric(metric)
+ ]
+ chemical_metrics = [
+ metric for metric in metrics if is_chemical_cluster_metric(metric)
+ ]
+ generic_nodes: list[str] = []
+ generic_systems: set[str] | None = None
+ if nonchemical_metrics and entity_type != "interface":
+ generic_nodes, generic_systems = clusters.component_node_universe(
+ data_dir=data_dir,
+ metric=nonchemical_metrics[0],
+ entity_type=entity_type,
+ )
+ interface_nodes: dict[str, list[str]] = {}
+ if entity_type == "interface":
+ for metric in nonchemical_metrics:
+ interface_nodes[metric], _ = clusters.component_node_universe(
+ data_dir=data_dir,
+ metric=metric,
+ entity_type=entity_type,
+ )
+ chemical_nodes: list[str] = []
+ if chemical_metrics:
+ # every chemical metric shares the ligand_smiles_id node universe, so it
+ # is resolved once and reused for every chemical source below.
+ chemical_nodes, _ = clusters.component_node_universe(
+ data_dir=data_dir,
+ metric=chemical_metrics[0],
+ entity_type=entity_type,
+ )
+ scratch_dir.mkdir(exist_ok=True, parents=True)
+ for source_index, source_value in enumerate(source_paths):
+ source = Path(source_value)
+ source_metric = source.parent.name.removeprefix("metric=")
+ if source_metric not in metrics:
+ raise ValueError(
+ f"component source metric is not selected: {source_metric}"
+ )
+ is_chemical = is_chemical_cluster_metric(source_metric)
+ source_metrics = [source_metric]
+ nodes = (
+ chemical_nodes
+ if is_chemical
+ else interface_nodes.get(source_metric, generic_nodes)
+ )
+ eligible_systems = None if is_chemical else generic_systems
+ pending_metrics = [
+ metric
+ for metric in source_metrics
+ if force_update
+ or not (
+ clusters.score_component_reduction_is_complete(
+ data_dir=data_dir,
+ metric=metric,
+ thresholds=thresholds,
+ source_path=source,
+ all_nodes=nodes,
+ eligible_systems=eligible_systems,
+ entity_type=entity_type,
+ )
+ if is_chemical
+ else (
+ clusters.score_component_reduction_is_complete(
+ data_dir=data_dir,
+ metric=metric,
+ thresholds=thresholds,
+ source_path=source,
+ all_nodes=nodes,
+ eligible_systems=eligible_systems,
+ entity_type=entity_type,
+ )
+ and clusters.directed_cover_component_reduction_is_complete(
+ data_dir=data_dir,
+ metric=metric,
+ thresholds=thresholds,
+ source_path=source,
+ all_nodes=nodes,
+ eligible_systems=eligible_systems,
+ entity_type=entity_type,
+ )
+ )
+ )
+ ]
+ if not pending_metrics:
+ LOG.info(
+ "component reduction source already complete: source=%s metrics=%d",
+ source.name,
+ len(source_metrics),
+ )
+ continue
+ source_started = time.time()
+ LOG.info(
+ "component reduction source start: source=%s size_bytes=%d "
+ "pending_metrics=%d/%d nodes=%d",
+ source.name,
+ source.stat().st_size,
+ len(pending_metrics),
+ len(source_metrics),
+ len(nodes),
+ )
+ local_source = scratch_dir / f"{source_index}-{source.name}"
+ copyfile(source, local_source)
+ try:
+ LOG.info(
+ "component reduction copied source to scratch: source=%s "
+ "elapsed_seconds=%.1f",
+ source.name,
+ time.time() - source_started,
+ )
+ context = {
+ "data_dir": data_dir,
+ "thresholds": thresholds,
+ "source": source,
+ "local_source": local_source,
+ "nodes": nodes,
+ "eligible_systems": eligible_systems,
+ "force_update": force_update,
+ "entity_type": entity_type,
+ }
-def compute_protein_leakage(
- *,
- data_dir: Path,
- inputs: list[tuple[str, str, str]],
-) -> None:
- [(split_file, compare_pair, metric)] = inputs
- leakage.compute_protein_leakage(
- data_dir=data_dir,
- split_file=split_file,
- compare_pair=compare_pair,
- metric=metric,
- )
+ def log_metric_start(metric_index: int, metric: str) -> None:
+ LOG.info(
+ "component reduction metric start: source=%s metric=%s "
+ "progress=%d/%d workers=%d",
+ source.name,
+ metric,
+ metric_index,
+ len(pending_metrics),
+ min(metric_workers, len(pending_metrics)),
+ )
+ def log_metric_complete(result: dict[str, Any]) -> None:
+ LOG.info(
+ "component reduction metric complete: source=%s metric=%s "
+ "output_rows=%d elapsed_seconds=%.1f",
+ source.name,
+ result["metric"],
+ result["output_rows"],
+ result["elapsed_seconds"],
+ )
-def scatter_make_links(
- *,
- data_dir: Path,
- search_dbs: list[str],
-) -> list[list[str]]:
- return [[obj] for obj in search_dbs]
+ workers = min(metric_workers, len(pending_metrics))
+ if workers == 1:
+ for metric_index, metric in enumerate(pending_metrics, start=1):
+ log_metric_start(metric_index, metric)
+ _initialize_component_reduction_worker(context)
+ log_metric_complete(_reduce_component_metric(metric_index, metric))
+ else:
+ for metric_index, metric in enumerate(pending_metrics, start=1):
+ log_metric_start(metric_index, metric)
+ with ProcessPoolExecutor(
+ max_workers=workers,
+ initializer=_initialize_component_reduction_worker,
+ initargs=(context,),
+ ) as executor:
+ futures = [
+ executor.submit(_reduce_component_metric, metric_index, metric)
+ for metric_index, metric in enumerate(pending_metrics, start=1)
+ ]
+ wait(futures, return_when=ALL_COMPLETED)
+ for future in futures:
+ log_metric_complete(future.result())
+ finally:
+ local_source.unlink(missing_ok=True)
+ LOG.info(
+ "component reduction source complete: source=%s metrics=%d "
+ "elapsed_seconds=%.1f",
+ source.name,
+ len(pending_metrics),
+ time.time() - source_started,
+ )
-def make_links(
+def merge_component_reductions(
*,
data_dir: Path,
- search_dbs: list[str],
- cpu: int = 8,
+ metrics: list[str],
+ thresholds: list[int],
+ entity_type: clusters.ClusterEntity = "ligand",
) -> None:
- from plinder.data.save_linked_structures import make_linked_structures_data_file
-
- save_dir = data_dir / "assignments"
- linked_structures = data_dir / "linked_staging"
- for search_db in search_dbs:
- output_file = linked_structures / f"{search_db}_links.parquet"
- make_linked_structures_data_file(
+ """Merge source reductions into internal connectivity labels."""
+ started = time.time()
+ for index, metric in enumerate(metrics, start=1):
+ metric_started = time.time()
+ LOG.info(
+ "merge_component_reductions: metric=%s progress=%d/%d",
+ metric,
+ index,
+ len(metrics),
+ )
+ clusters.merge_score_component_reductions(
data_dir=data_dir,
- search_db=search_db,
- superposed_folder=save_dir,
- output_file=output_file,
- num_processes=cpu,
+ metric=metric,
+ thresholds=thresholds,
+ entity_type=entity_type,
+ )
+ if not is_chemical_cluster_metric(metric):
+ clusters.merge_directed_cover_component_reductions(
+ data_dir=data_dir,
+ metric=metric,
+ thresholds=thresholds,
+ entity_type=entity_type,
+ )
+ elapsed = time.time() - started
+ rate = index / elapsed
+ LOG.info(
+ "merge_component_reductions: metric=%s complete "
+ "elapsed_seconds=%.1f overall_eta_seconds=%.1f",
+ metric,
+ time.time() - metric_started,
+ (len(metrics) - index) / rate,
)
-def make_linked_structures(
+def make_set_covers(
*,
data_dir: Path,
- search_dbs: list[str],
- cpu: int = 8,
- force_update: bool = False,
+ metric_threshold: list[tuple[str, int]],
+ skip_existing_clusters: bool,
+ scratch_dir: Path | None = None,
+ threads: int = 1,
+ entity_type: clusters.ClusterEntity = "ligand",
) -> None:
- import multiprocessing
-
- linked_structures = data_dir / "linked_staging"
- for search_db in search_dbs:
- if search_db == "holo":
- continue
- source_structures = linked_structures / "source" / search_db
- source_structures.mkdir(exist_ok=True, parents=True)
- df = pd.read_parquet(
- linked_structures / f"{search_db}_links.parquet", columns=["id"]
- )
- LOG.info(
- f"make_linked_structures: collecting {df['id'].nunique()} {search_db} linked structures"
- )
- func = None
- if search_db == "apo":
- func = utils.apo_file_from_link_id
- elif search_db == "pred":
- func = utils.pred_file_from_link_id
- if func is not None:
- args = [
- (data_dir, source_structures, link_id, force_update)
- for link_id in df["id"].unique()
- ]
- with multiprocessing.get_context("spawn").Pool(cpu) as p:
- p.starmap(func, args)
- utils.pack_source_structures(data_dir, search_db)
+ """Compute one ligand-Tanimoto set cover after component reduction."""
+ if not metric_threshold:
+ LOG.info("make_set_covers: all set covers are cached")
+ return
+ [(metric, threshold)] = metric_threshold
+ clusters.make_set_cover(
+ data_dir=data_dir,
+ metric=metric,
+ threshold=threshold,
+ skip_existing_clusters=skip_existing_clusters,
+ scratch_dir=scratch_dir,
+ threads=threads,
+ entity_type=entity_type,
+ )
-def scatter_score_linked_structures(
+def make_directed_set_covers(
*,
data_dir: Path,
- search_dbs: list[str],
- batch_size: int,
-) -> list[list[tuple[str, str]]]:
- items = []
- for search_db in search_dbs:
- links = pd.read_parquet(
- data_dir / "linked_staging" / f"{search_db}_links.parquet"
- )
- items.extend(
- [
- (search_db, system_id)
- for system_id in sorted(links["reference_system_id"])
- ]
+ metric_threshold: list[tuple[str, int]],
+ skip_existing: bool,
+ scratch_dir: Path | None = None,
+ threads: int = 1,
+ entity_type: clusters.ClusterEntity = "ligand",
+) -> None:
+ """Compute requested directed covers, sharing work within each metric."""
+ if not metric_threshold:
+ LOG.info("make_directed_set_covers: all covers are cached")
+ return
+ grouped: dict[str, list[int]] = {}
+ for metric, threshold in metric_threshold:
+ grouped.setdefault(metric, []).append(threshold)
+ for metric, thresholds in grouped.items():
+ clusters.make_directed_set_covers(
+ data_dir=data_dir,
+ metric=metric,
+ thresholds=thresholds,
+ skip_existing=skip_existing,
+ scratch_dir=scratch_dir,
+ threads=threads,
+ entity_type=entity_type,
)
- return [items[pos : pos + batch_size] for pos in range(0, len(items), batch_size)]
-def score_linked_structures(
+def summarize_clusters(
*,
data_dir: Path,
- search_dbs: list[str],
- system_ids: list[tuple[str, str]],
- cpu: int = 8,
- force_update: bool = False,
+ metrics: list[str],
+ thresholds: list[int],
+ entity_type: clusters.ClusterEntity = "ligand",
) -> None:
- import multiprocessing
+ """Validate and summarize every cluster artifact before index publication."""
+ from plinder.data.pipeline.score import summarize_clustering_artifacts
- from plinder.data.save_linked_structures import (
- system_save_and_score_representatives,
+ summarize_clustering_artifacts(
+ data_dir,
+ metrics=metrics,
+ thresholds=thresholds,
+ entity_type=entity_type,
)
- linked_structures = data_dir / "linked_staging"
- grouped = {
- search_db: [tup[1] for tup in system_ids if tup[0] == search_db]
- for search_db in search_dbs
- }
- dfs = []
- for search_db in search_dbs:
- df = pd.read_parquet(linked_structures / f"{search_db}_links.parquet")
- slc = df[df["reference_system_id"].isin(grouped[search_db])]
- if not slc.empty:
- dfs.append(slc.copy())
- dfs[-1]["kind"] = search_db
- if not len(dfs):
- LOG.info("no linked structures to make")
- return
- links = pd.concat(dfs).reset_index(drop=True)
-
- with multiprocessing.get_context("spawn").Pool(cpu) as p:
- p.starmap(
- system_save_and_score_representatives,
- [
- (system, group, data_dir, search_db, linked_structures, force_update)
- for (search_db, system), group in links.groupby(
- ["kind", "reference_system_id"]
- )
- ],
- )
+
+def finalize_index(
+ *,
+ data_dir: Path,
+ weekly_ligand_clusters: Path | None = None,
+ weekly_interface_clusters: Path | None = None,
+) -> None:
+ """Publish annotation enrichment and queryable cluster sidecars."""
+ lookup_was_current = _completed_alignment_chain_lookup(data_dir) is not None
+ utils.finalize_index(
+ data_dir=data_dir,
+ weekly_ligand_clusters=weekly_ligand_clusters,
+ weekly_interface_clusters=weekly_interface_clusters,
+ )
+ # finalize_index preserves the entry, chain, pocket, and interface fields
+ # used to build the representative inputs. Refresh those source signatures
+ # so an otherwise valid mapped release does not become stale merely because
+ # the final tables were published.
+ if lookup_was_current:
+ _refresh_representative_source_manifests(data_dir)
+ _write_alignment_chain_lookup_manifest(data_dir)
+ collate.finalize_repair_marker(data_dir)
diff --git a/src/plinder/data/pipeline/transform.py b/src/plinder/data/pipeline/transform.py
index 5d7a9e488..47e87163d 100644
--- a/src/plinder/data/pipeline/transform.py
+++ b/src/plinder/data/pipeline/transform.py
@@ -1,378 +1,163 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
-import tarfile
+import re
from pathlib import Path
-from typing import Any
import numpy as np
import pandas as pd
-
-def parse_pdb_range(pdb_range: str) -> tuple[str, str, str]:
- """
- Parse the PDB ranges from the raw ECOD dataset.
- Default to ".", "0", "0" if it's unparseable.
-
- Parameters
- ----------
- pdb_range : str
- "-"-delimited range values
-
- Returns
- -------
- chain, start, end : tuple[str, str, str]
- """
- if ":" not in pdb_range:
- return ".", "0", "0"
- try:
- chain, range_str = pdb_range.split(":")
- except ValueError:
- return ".", "0", "0"
- ranges = range_str.split("-")
- # single range value
- if len(ranges) == 1:
- fr = to = ranges[0]
- # two positive range values
- elif len(ranges) == 2:
- fr, to = ranges
- # one negative range value
- elif len(ranges) == 3:
- if not ranges[1]:
- fr, to = ranges[0], f"-{ranges[-1]}"
- else:
- fr, to = f"-{ranges[1]}", ranges[-1]
- # two negative range values
- elif len(ranges) == 4:
- fr, to = f"-{ranges[1]}", f"-{ranges[-1]}"
- else:
- raise Exception(f"Could not parse: {pdb_range}")
- return chain, fr, to
-
-
-def transform_ecod_data(*, raw_ecod_path: Path) -> pd.DataFrame:
- """
- Convert the raw ECOD data to a dataset more
- amenable to the plinder annotation data.
-
- Parameters
- ----------
- df : pd.DataFrame
- the raw ECOD dataset
-
- Returns
- -------
- transformed : pd.DataFrame
- the transformed ECOD dataset
- """
- df = pd.read_csv(raw_ecod_path, sep="\t", header=1, skiprows=3)
- domains = []
- for pdb, chain, pdb_ranges, ecod_domain_id, t_name in zip(
- df["pdb"],
- df["chain"],
- df["pdb_range"],
- df["ecod_domain_id"],
- df["t_name"],
- ):
- for pdb_range in pdb_ranges.split(","):
- chain, fr, to = parse_pdb_range(pdb_range)
- domains.append((pdb, chain, ecod_domain_id, t_name, fr, to))
- cols = ["pdb", "chain", "domainid", "domain", "pdb_from", "pdb_to"]
- return pd.DataFrame(domains, columns=cols)
-
-
-def transform_panther_data(*, raw_panther_path: Path) -> pd.DataFrame:
+AFFINITY_RECORD_COLUMNS = [
+ "pdbid_ligid",
+ "pdb_id",
+ "ligand_het_id",
+ "reactant_set_id",
+ "monomer_id",
+ "curation_source",
+ "article_doi",
+ "bindingdb_entry_doi",
+ "source_row",
+ "target_sequences",
+ "target_sequence",
+ "endpoint",
+ "raw_value",
+ "relation",
+ "value_nm",
+ "pchembl",
+]
+
+
+def transform_bindingdb_measurements(
+ *, raw_affinity_path: Path, chunksize: int = 100_000
+) -> pd.DataFrame:
+ """Keep each Ki/Kd measurement linked to its source row and target.
+
+ PDB/CCD cross-references are candidate matches, not evidence that an
+ assay measured a particular deposited complex. ``relation`` applies to
+ the logarithmic pKi/pKd value, so a raw ``Ki > 100 nM`` is ``pKi < 7``.
"""
- Unpack the tarball archive and collect the
- contained files to a single parquet file.
-
- Parameters
- ----------
- raw_panther_path : Path
- location of panther tarball
-
- Returns
- -------
- transformed : pd.DataFrame
- the collated panther dataset
- """
- panther_dir = raw_panther_path.parent
- with tarfile.open(raw_panther_path) as arch:
- arch.extractall(panther_dir)
- dfs = []
- names = ["uniprotac", "panther"]
- for path in (panther_dir / "panther_classifications").rglob("*"):
- dfs.append(pd.read_csv(path, delimiter="\t", header=None, names=names))
- dfs[-1]["panther_class"] = path.name
- return pd.concat(dfs).drop_duplicates()
-
-
-def transform_bindingdb_affinity_data(*, raw_affinity_path: Path) -> pd.DataFrame:
- # TODO: fix this bug https://github.com/plinder-org/plinder/issues/94
- """
- Unpack the tarball archive and collect the
- contained files to a single parquet file.
-
- Parameters
- ----------
- raw_affinity_path : Path
- location of affinity data
-
- Returns
- -------
- transformed : pd.DataFrame
- median affinity dataset
- """
-
- def calc_pchembl(affinity: float) -> Any:
- affinity = affinity * 10**-9
- if affinity > 0:
- return -1.0 * np.log10(affinity)
- else:
- return np.nan
-
- cols = [
+ header = pd.read_csv(raw_affinity_path, sep="\t", nrows=0).columns.tolist()
+ sequence_columns = [
+ column
+ for column in header
+ if re.fullmatch(r"BindingDB Target Chain\s+Sequence(?: \d+)?", column)
+ ]
+ if not sequence_columns:
+ raise ValueError("BindingDB TSV has no target-chain sequence columns")
+ required = [
"Ligand HET ID in PDB",
"PDB ID(s) for Ligand-Target Complex",
"Ki (nM)",
- # "IC50 (nM)",
"Kd (nM)",
- "EC50 (nM)",
]
- df = pd.read_csv(raw_affinity_path, sep="\t", usecols=cols, low_memory=False)
-
- df["pchembl"] = (
- # df[["Ki (nM)", "IC50 (nM)", "Kd (nM)"]]
- df[["Ki (nM)", "Kd (nM)"]]
- .apply(set, axis=1)
- .apply(lambda x: [i for i in x if str(i) != "nan"])
- )
- df = df[df["pchembl"].apply(lambda x: x != [])]
- df["pchembl"] = df["pchembl"].apply(
- lambda x: calc_pchembl(float(str(x[0]).replace(">", "").replace("<", "")))
- )
-
- df = df[
- ["PDB ID(s) for Ligand-Target Complex", "Ligand HET ID in PDB", "pchembl"]
- ].drop_duplicates()
- df = df[
- (df["Ligand HET ID in PDB"].notna())
- & (df["PDB ID(s) for Ligand-Target Complex"].notna())
- ]
- df["pdb_id"] = df["PDB ID(s) for Ligand-Target Complex"].apply(
- lambda x: x.split(",")
- )
- df = df.explode(["pdb_id"]).drop_duplicates()
- df["pdbid_ligid"] = (
- df["pdb_id"].str.upper() + "_" + df["Ligand HET ID in PDB"].str.strip()
- )
- df = df[["pdbid_ligid", "pchembl"]].drop_duplicates()
-
- return df.groupby("pdbid_ligid").median().reset_index()
-
-
-def transform_papyrus_affinity_data(*, raw_affinity_path: Path) -> pd.DataFrame:
- """
- Unpack the tarball archive and collect the
- contained files to a single parquet file.
-
- Parameters
- ----------
- raw_affinity_path : Path
- location of affinity data
-
- Returns
- -------
- transformed : pd.DataFrame
- median affinity dataset
- """
- df = pd.read_csv(raw_affinity_path, sep="\t", compression="zip")
- affinity_df = (
- df[
- [
- "accession",
- "Quality",
- "source",
- "pchembl_value_Median",
- "PDBID_ligand",
- "PDBID_protein",
- ]
- ]
- .copy()
- .rename(columns={"pchembl_value_Median": "pchembl"})
- )
- affinity_df["PDBID_protein"] = affinity_df["PDBID_protein"].apply(
- lambda x: x.split(";")
- )
- affinity_df = affinity_df.explode("PDBID_protein")
- affinity_df = affinity_df[affinity_df.pchembl.notna()]
- affinity_df["pdbid_ligid"] = (
- affinity_df["PDBID_protein"].str.upper() + "_" + affinity_df["PDBID_ligand"]
- )
- return (
- affinity_df[["pdbid_ligid", "pchembl"]]
- .groupby("pdbid_ligid")
- .median()
- .reset_index()
- )
-
-
-def transform_moad_affinity_data(*, raw_affinity_path: Path) -> pd.DataFrame:
- """
- Unpack the tarball archive and collect the
- contained files to a single parquet file.
-
- Parameters
- ----------
- raw_affinity_path : Path
- location of affinity data
-
- Returns
- -------
- transformed : pd.DataFrame
- median affinity dataset
- """
-
- def calc_pchembl(affinity: float, unit: str) -> Any:
- if unit == "fM":
- affinity = affinity * 10**-15
-
- if affinity > 0:
- return -1.0 * np.log10(affinity)
- else:
- return np.nan
- elif unit == "pM":
- affinity = affinity * 10**-12
- if affinity > 0:
- return -1.0 * np.log10(affinity)
- else:
- return np.nan
- elif unit == "nM":
- affinity = affinity * 10**-9
- if affinity > 0:
- return -1.0 * np.log10(affinity)
- else:
- return np.nan
- elif unit == "uM":
- affinity = affinity * 10**-6
- if affinity > 0:
- return -1.0 * np.log10(affinity)
- else:
- return np.nan
- elif unit == "mM":
- affinity = affinity * 10**-3
- if affinity > 0:
- return -1.0 * np.log10(affinity)
- else:
- return np.nan
- elif unit == "M":
- return affinity
-
- with open(raw_affinity_path) as f:
- combined_list = []
- for line in f.readlines():
- line_split = line.split(",")
- tmp_enzyme_class = line_split[0]
- tmp_pdbid = line_split[2]
- if len(tmp_enzyme_class.split(".")) == 4:
- new_enzyme_class = tmp_enzyme_class
- if len(tmp_pdbid) > 0:
- if "Family" in line_split[1]:
- family_representative = True
- else:
- family_representative = False
- new_pdbid = tmp_pdbid
- if (line_split[3] != "") & (line_split[5] != "Ka"):
- combined_list.append(
- [
- new_enzyme_class,
- family_representative,
- new_pdbid,
- line_split[3],
- line_split[4],
- line_split[7],
- line_split[8],
- line_split[9],
- ]
- )
- moad_df = pd.DataFrame(
- combined_list,
- columns=[
- "ec_no.",
- "ec_family_rep",
- "pdbid",
- "binder_and_chain",
- "valid_ligand",
- "affinity",
- "unit",
- "smiles",
- ],
- )
- moad_df["pdbid"] = moad_df["pdbid"].str.lower()
-
- moad_df["binder_id"] = moad_df["binder_and_chain"].apply(lambda x: x.split(":")[0])
- moad_df["binder_id"] = moad_df["binder_id"].apply(lambda x: x.split())
- moad_df = moad_df.explode("binder_id")
- moad_df["pdbid_ligid"] = moad_df["pdbid"].str.upper() + "_" + moad_df["binder_id"]
- # This will set instances with undefined affinity to nan
- moad_df["pchembl"] = moad_df[["affinity", "unit"]].apply(
- lambda x: calc_pchembl(float(x[0]), x[1]) if x[0] != "" else np.nan, axis=1
- )
- return (
- moad_df[["pdbid_ligid", "pchembl"]]
- .groupby("pdbid_ligid")
- .median()
- .reset_index()
+ missing = sorted(set(required).difference(header))
+ if missing:
+ raise ValueError(f"BindingDB TSV is missing columns: {missing}")
+ reactant_column = "BindingDB Reactant_set_id"
+ monomer_column = "BindingDB MonomerID"
+ source_columns = {
+ "curation_source": "Curation/DataSource",
+ "article_doi": "Article DOI",
+ "bindingdb_entry_doi": "BindingDB Entry DOI",
+ }
+ columns = required + sequence_columns
+ if reactant_column in header:
+ columns.append(reactant_column)
+ if monomer_column in header:
+ columns.append(monomer_column)
+ columns.extend(column for column in source_columns.values() if column in header)
+
+ parts: list[pd.DataFrame] = []
+ for chunk in pd.read_csv(
+ raw_affinity_path,
+ sep="\t",
+ usecols=columns,
+ dtype="string",
+ chunksize=chunksize,
+ ):
+ chunk = chunk.loc[
+ chunk[required[0]].notna() & chunk[required[1]].notna()
+ ].copy()
+ if chunk.empty:
+ continue
+ chunk["source_row"] = chunk.index
+ chunk["target_sequences"] = chunk[sequence_columns].apply(
+ lambda row: [
+ value.strip().upper()
+ for value in row
+ if isinstance(value, str) and value.strip()
+ ],
+ axis=1,
+ )
+ chunk["target_sequence"] = chunk["target_sequences"].map(
+ lambda values: values[0] if len(values) == 1 else None
+ )
+ chunk["reactant_set_id"] = (
+ chunk[reactant_column] if reactant_column in chunk else pd.NA
+ )
+ chunk["monomer_id"] = (
+ chunk[monomer_column] if monomer_column in chunk else pd.NA
+ )
+ for output, source in source_columns.items():
+ chunk[output] = chunk[source] if source in chunk else pd.NA
+ for endpoint in ("Ki", "Kd"):
+ source = f"{endpoint} (nM)"
+ records = chunk.loc[chunk[source].notna()].copy()
+ records["raw_value"] = records[source].str.strip()
+ records = records.loc[records["raw_value"].ne("")].copy()
+ if records.empty:
+ continue
+ parsed = records["raw_value"].str.extract(
+ r"^(?P<=|>=|<|>|=)?\s*"
+ r"(?P(?:\d+(?:\.\d*)?|\.\d+)(?:[Ee][+-]?\d+)?)$"
+ )
+ records["value_nm"] = pd.to_numeric(parsed["value"], errors="coerce")
+ records.loc[records["value_nm"] <= 0, "value_nm"] = np.nan
+ records["relation"] = (
+ parsed["bound"]
+ .fillna("=")
+ .map({"=": "=", "<": ">", "<=": ">=", ">": "<", ">=": "<="})
+ )
+ records.loc[records["value_nm"].isna(), "relation"] = None
+ with np.errstate(divide="ignore", invalid="ignore"):
+ records["pchembl"] = 9 - np.log10(records["value_nm"])
+ records["endpoint"] = endpoint
+ records["pdb_id"] = records[required[1]].str.split(r"[,;]")
+ records = records.explode("pdb_id")
+ records["pdb_id"] = records["pdb_id"].str.strip().str.upper()
+ records = records.loc[records["pdb_id"].str.fullmatch(r"[A-Z0-9]{4}")]
+ records["ligand_het_id"] = records[required[0]].str.strip().str.upper()
+ records["pdbid_ligid"] = records["pdb_id"] + "_" + records["ligand_het_id"]
+ parts.append(records[AFFINITY_RECORD_COLUMNS])
+
+ if not parts:
+ return pd.DataFrame(columns=AFFINITY_RECORD_COLUMNS)
+ return pd.concat(parts, ignore_index=True).drop_duplicates(
+ ["source_row", "pdb_id", "ligand_het_id", "endpoint"]
)
-def transform_components_data(*, raw_components_path: Path) -> pd.DataFrame:
- import gemmi
-
- data = gemmi.cif.read_file(raw_components_path.as_posix())
- rows = []
- for block in data:
- (
- binder_id,
- chemical_name,
- molecular_weight,
- ) = block.find("_chem_comp.", ["id", "name", "formula_weight"])[0]
- canonical_smiles, isomeric_smiles, inchikey = None, None, None
- for desc_row in block.find(
- "_pdbx_chem_comp_descriptor.",
- ["comp_id", "type", "program", "descriptor"],
- ):
- if (desc_row[1].strip() == "SMILES_CANONICAL") and (
- desc_row[2].strip() == '"OpenEye OEToolkits"'
- ):
- canonical_smiles = desc_row[3].strip('"').strip(";")
-
- if (desc_row[1].strip() == "SMILES") and (
- desc_row[2].strip() == '"OpenEye OEToolkits"'
- ):
- isomeric_smiles = desc_row[3].replace('"', "")
-
- if desc_row[1].strip() == "InChIKey":
- inchikey = desc_row[3]
- if any((i is None for i in (canonical_smiles, isomeric_smiles, inchikey))):
- continue
- rows.append(
- (
- binder_id,
- chemical_name,
- molecular_weight,
- canonical_smiles,
- isomeric_smiles,
- inchikey,
- )
- )
- return pd.DataFrame(
- rows,
- columns=[
- "binder_id",
- "chemical_name",
- "molecular_weight",
- "canonical_smiles",
- "isomeric_smiles",
- "inchikey",
- ],
+def strict_bindingdb_candidates(records: pd.DataFrame) -> pd.DataFrame:
+ """Summarize only comparable, uncensored measurements per target/endpoint."""
+ columns = ["pdbid_ligid", "target_sequence", "endpoint", "pchembl", "count"]
+ if records.empty:
+ return pd.DataFrame(columns=columns)
+ # Multi-chain or missing-target records cannot be checked against one
+ # receptor sequence; do not let them disappear before the ambiguity test.
+ unusable_keys = records.loc[
+ records["target_sequence"].isna(), "pdbid_ligid"
+ ].unique()
+ eligible = records.loc[~records["pdbid_ligid"].isin(unusable_keys)].copy()
+ if eligible.empty:
+ return pd.DataFrame(columns=columns)
+ eligible["valid"] = (
+ eligible["relation"].eq("=") & eligible["pchembl"].notna()
+ ).fillna(False)
+ grouped = eligible.groupby(["pdbid_ligid", "target_sequence"], sort=False).agg(
+ endpoint=("endpoint", "first"),
+ endpoint_count=("endpoint", "nunique"),
+ all_valid=("valid", "all"),
+ pchembl=("pchembl", "median"),
+ count=("pchembl", "size"),
)
+ grouped = grouped.loc[grouped["all_valid"] & grouped["endpoint_count"].eq(1)]
+ return grouped.reset_index()[columns]
diff --git a/src/plinder/data/pipeline/update_archives.py b/src/plinder/data/pipeline/update_archives.py
new file mode 100644
index 000000000..b75ccb485
--- /dev/null
+++ b/src/plinder/data/pipeline/update_archives.py
@@ -0,0 +1,187 @@
+"""Carry canonical ligand archives into a prepared entry-update workspace."""
+
+from __future__ import annotations
+
+import argparse
+import json
+from pathlib import Path
+from shutil import rmtree
+from typing import Any
+
+import duckdb
+import pyarrow as pa
+import pyarrow.parquet as pq
+
+from plinder.core.utils.files import file_sha256, link_or_copy_file, write_json_atomic
+from plinder.data.pipeline import collate, tasks
+from plinder.data.pipeline.score import finalize_ligand_archives
+from plinder.data.pipeline.update_entries import _file_stats, _prepared_entry_outputs
+
+
+def update_ligand_archives(
+ workspace: Path, *, threads: int = 4, memory_limit: str = "8GB"
+) -> dict[str, Any]:
+ """Replace changed entries' canonical SDFs while keeping the base read-only.
+
+ Unchanged shards are hard-linked, or copied across filesystems. Treat release
+ files as immutable: subsequent updates replace whole files, never edit them
+ in place. Reruns rebuild affected shards and validate the complete archive set.
+ Scores, clusters and other downstream work remain pending.
+ """
+ workspace = workspace.resolve(strict=True)
+ entry_marker = workspace / "entry_update.json"
+ entries = json.loads(entry_marker.read_text())
+ if entries["status"] != collate.REPAIR_REQUIRED_STATUS:
+ raise ValueError(
+ "finish preparing entry tables before updating ligand archives"
+ )
+ base = Path(entries["base_release"]).resolve(strict=True)
+ if workspace == base or base in workspace.parents:
+ raise ValueError("update ligand archives outside the existing release")
+ prepared = _prepared_entry_outputs(workspace)
+ base_tables = collate.entry_table_paths(base)
+ if (
+ _file_stats(prepared) != entries["outputs"]
+ or _file_stats(base_tables) != entries["inputs"]["base_tables"]
+ ):
+ raise ValueError("entry tables changed; prepare a new update workspace")
+
+ source_manifest = base / "ligand_archives/manifest.json"
+ source_report = json.loads(source_manifest.read_text())
+ old_archives = {
+ path.stem: path for path in sorted((base / "ligand_archives").glob("*.parquet"))
+ }
+ if (
+ source_report["status"] != "complete"
+ or source_report["shard_count"] != len(old_archives)
+ or source_report["ligand_count"]
+ != sum(pq.read_metadata(path).num_rows for path in old_archives.values())
+ or source_report["compressed_bytes"]
+ != sum(path.stat().st_size for path in old_archives.values())
+ ):
+ raise ValueError("base ligand archives do not match their completion manifest")
+ changed = sorted(
+ set(entries["ingested_pdb_ids"]) | set(entries["obsolete_pdb_ids"])
+ )
+ changed_codes = {pdb_id[1:3] for pdb_id in changed}
+ incoming = workspace / ".incoming"
+ sdf_sources = {
+ str(path): path
+ for pdb_id in entries["ingested_pdb_ids"]
+ for path in (
+ incoming / "raw_entries" / pdb_id[1:3] / pdb_id / "ligand_files"
+ ).glob("*.sdf")
+ }
+ sources = {
+ str(path): path
+ for path in [
+ entry_marker,
+ source_manifest,
+ *old_archives.values(),
+ *prepared.values(),
+ *base_tables.values(),
+ ]
+ }
+ sources.update(sdf_sources)
+ before = _file_stats(sources)
+ target = workspace / "ligand_archives"
+ stage = workspace / ".ligand_archives.pending"
+ backup = workspace / ".ligand_archives.previous"
+ if backup.exists():
+ if not target.exists():
+ backup.rename(target)
+ else:
+ rmtree(backup)
+ if stage.exists():
+ rmtree(stage)
+ stage.mkdir()
+ try:
+ tasks.make_canonical_ligand_archives(
+ data_dir=incoming, two_char_codes=sorted(changed_codes)
+ )
+ expected_shards = []
+ with duckdb.connect() as connection:
+ collate._configure_duckdb(
+ connection, threads=threads, memory_limit=memory_limit, scratch_dir=None
+ )
+ connection.register(
+ "changed_entries",
+ pa.table({"pdb_id": pa.array(changed, type=pa.string())}),
+ )
+ for code in sorted(set(old_archives) | changed_codes):
+ output = stage / f"{code}.parquet"
+ if code not in changed_codes:
+ link_or_copy_file(old_archives[code].resolve(strict=True), output)
+ expected_shards.append(code)
+ continue
+ queries = []
+ if code in old_archives:
+ connection.read_parquet(str(old_archives[code])).create_view(
+ "old_ligands", replace=True
+ )
+ queries.append(
+ "SELECT old_ligands.* FROM old_ligands ANTI JOIN changed_entries USING (pdb_id)"
+ )
+ new_archive = incoming / "ligand_archives" / f"{code}.parquet"
+ if new_archive.is_file():
+ connection.read_parquet(str(new_archive)).create_view(
+ "new_ligands", replace=True
+ )
+ queries.append("SELECT * FROM new_ligands")
+ if not queries:
+ continue
+ query = " UNION ALL BY NAME ".join(queries)
+ if not collate._fetch_scalar(
+ connection, f"SELECT count(*) FROM ({query})"
+ ):
+ continue
+ collate._copy_query(
+ connection,
+ f"SELECT * FROM ({query}) ORDER BY pdb_id, ligand_asym_id",
+ output,
+ row_group_size=2_048,
+ )
+ expected_shards.append(code)
+ report = finalize_ligand_archives(
+ workspace,
+ archive_dir=stage,
+ expected_shards=expected_shards,
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ if before != _file_stats(sources):
+ raise RuntimeError("archive inputs changed while preparing the update")
+ report.update(
+ updated_pdb_ids=changed,
+ entry_update_sha256=file_sha256(entry_marker),
+ base_manifest_sha256=file_sha256(source_manifest),
+ )
+ write_json_atomic(stage / "manifest.json", report)
+ if target.exists():
+ target.rename(backup)
+ stage.rename(target)
+ except BaseException:
+ if stage.exists():
+ rmtree(stage)
+ if backup.exists() and not target.exists():
+ backup.rename(target)
+ raise
+ if backup.exists():
+ rmtree(backup)
+ return report
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument("workspace", type=Path)
+ parser.add_argument("--threads", type=int, default=4)
+ parser.add_argument("--memory-limit", default="8GB")
+ args = parser.parse_args()
+ report = update_ligand_archives(
+ args.workspace, threads=args.threads, memory_limit=args.memory_limit
+ )
+ print(json.dumps(report, indent=2, sort_keys=True))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/plinder/data/pipeline/update_entries.py b/src/plinder/data/pipeline/update_entries.py
new file mode 100644
index 000000000..6fd7730f1
--- /dev/null
+++ b/src/plinder/data/pipeline/update_entries.py
@@ -0,0 +1,349 @@
+# Copyright (c) 2026, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Prepare updated entry tables in a separate, resumable workspace."""
+
+from __future__ import annotations
+
+import argparse
+import json
+from concurrent.futures import ThreadPoolExecutor
+from pathlib import Path
+from shutil import copy2
+from typing import Any, Mapping
+
+import duckdb
+import pandas as pd
+import pyarrow as pa
+import pyarrow.parquet as pq
+from omegaconf import OmegaConf
+
+from plinder.core.utils.files import write_json_atomic
+from plinder.data.annotations.affinity import publish_affinity_tables
+from plinder.data.pipeline import collate, config
+from plinder.data.pipeline.collate import ENTRY_TABLES, entry_table_paths
+from plinder.data.pipeline.ingest import REQUIRED_REFERENCE_FILES, ingest_pdb_batch
+from plinder.data.pipeline.updates import REVISION_COLUMNS, _signature, load_update_plan
+
+
+def _file_stats(paths: Mapping[str, Path]) -> dict[str, dict[str, int]]:
+ return {
+ name: {"size": path.stat().st_size, "mtime_ns": path.stat().st_mtime_ns}
+ for name, path in paths.items()
+ }
+
+
+def _prepared_entry_outputs(root: Path) -> dict[str, Path]:
+ return {
+ **entry_table_paths(root),
+ "ligand_affinity": root / "index/ligand_affinity.parquet",
+ "bindingdb_measurements": root / "index/bindingdb_measurements.parquet",
+ "collation": root / "index" / collate.FINAL_MARKER_NAME,
+ }
+
+
+def _combine_tables(
+ base: Path,
+ incoming: Path | None,
+ stage: Path,
+ removed: list[str],
+ *,
+ threads: int,
+ memory_limit: str,
+ scratch_dir: Path | None,
+) -> dict[str, int]:
+ """Replace complete entries, including their system-validation rows."""
+ stage.mkdir(parents=True, exist_ok=True)
+ workers = min(4, threads, len(ENTRY_TABLES))
+ removed_entries = pa.table({"entry_pdb_id": pa.array(removed, type=pa.string())})
+
+ def write_table(item: tuple[str, tuple[str, str]]) -> tuple[str, int]:
+ name, (filename, order_by) = item
+ connection = duckdb.connect()
+ try:
+ collate._configure_duckdb(
+ connection,
+ threads=max(1, threads // workers),
+ memory_limit=memory_limit,
+ scratch_dir=scratch_dir / name if scratch_dir is not None else None,
+ )
+ connection.register("removed_entries", removed_entries)
+ connection.read_parquet(str(base / "index" / filename)).create_view(
+ "old_rows", replace=True
+ )
+ condition = (
+ "split_part(old_rows.system_id, '__', 1) = removed_entries.entry_pdb_id"
+ if name == "system_validation"
+ else "old_rows.entry_pdb_id = removed_entries.entry_pdb_id"
+ )
+ retained = f"SELECT old_rows.* FROM old_rows ANTI JOIN removed_entries ON {condition}"
+ query = retained
+ if incoming is not None:
+ connection.read_parquet(str(incoming / "index" / filename)).create_view(
+ "new_rows", replace=True
+ )
+ query += " UNION ALL BY NAME SELECT * FROM new_rows"
+ collate._copy_query(
+ connection,
+ f"SELECT * FROM ({query}) ORDER BY {order_by}",
+ stage / filename,
+ row_group_size=100_000,
+ )
+ return name, int(pq.ParquetFile(stage / filename).metadata.num_rows)
+ finally:
+ connection.close()
+
+ with ThreadPoolExecutor(max_workers=workers) as pool:
+ return dict(pool.map(write_table, ENTRY_TABLES.items()))
+
+
+def apply_entry_update(
+ plan_dir: Path,
+ output_dir: Path,
+ *,
+ validation_root: Path,
+ annotation_cfg: Mapping[str, Any],
+ entry_cfg: Mapping[str, Any],
+ interface_cfg: Mapping[str, Any],
+ threads: int = 4,
+ memory_limit: str = "8GB",
+ scratch_dir: Path | None = None,
+) -> dict[str, Any]:
+ """Prepare entry tables; leave scores, archives, and clusters pending.
+
+ Use the release's original annotation settings. ``threads`` limits table
+ processing; entry annotation uses the existing sequential batch runner.
+ The existing release is read-only. Failed entry batches can be resumed in
+ the same workspace with the same plan and inputs.
+ """
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ plan_dir = plan_dir.resolve(strict=True)
+ plan, entries = load_update_plan(plan_dir)
+ base = Path(plan["data_dir"]).resolve(strict=True)
+ output_dir = output_dir.resolve()
+ validation_root = validation_root.resolve(strict=True)
+ if output_dir == base or base in output_dir.parents:
+ raise ValueError("write entry updates outside the existing release")
+ base_tables = entry_table_paths(base)
+ previous = entries.loc[entries.action.isin(["revised", "obsolete"])].set_index(
+ "pdb_id"
+ )
+ if not previous.empty:
+ planned_revisions = previous[
+ ["previous_major_revision", "previous_minor_revision"]
+ ].rename(
+ columns={
+ "previous_major_revision": "source_mmcif_major_revision",
+ "previous_minor_revision": "source_mmcif_minor_revision",
+ }
+ )
+ installed_revisions = pd.read_parquet(
+ base_tables["entry_sources"],
+ columns=["entry_pdb_id", *planned_revisions.columns],
+ ).set_index("entry_pdb_id")
+ if (
+ not installed_revisions.reindex(planned_revisions.index)
+ .astype("Int64")
+ .equals(planned_revisions.astype("Int64"))
+ ):
+ raise ValueError("update plan does not match the base entry revisions")
+ base_marker_path = base / "index" / collate.FINAL_MARKER_NAME
+ base_marker = json.loads(base_marker_path.read_text())
+ if base_marker["status"] != "complete":
+ raise ValueError("finish the existing release before preparing an update")
+ contact_fields = ("ligand_contacts_computed", "protein_contacts_computed")
+ if any(base_marker.get(field) is not True for field in contact_fields):
+ raise ValueError("weekly updates require complete ligand and protein contacts")
+ min_residues = int(base_marker["interface_min_residues"])
+ if int(interface_cfg["min_interface_residues"]) != min_residues:
+ raise ValueError("update interface threshold differs from the existing release")
+ changed = entries.loc[entries.action.isin(["added", "revised"])].copy()
+ remove = sorted(entries.loc[entries.action.isin(["revised", "obsolete"]), "pdb_id"])
+ reference_files = (
+ {str(path): base / path for path in REQUIRED_REFERENCE_FILES}
+ if len(changed)
+ else {}
+ )
+ binding = {
+ "plan": _signature(plan_dir / "plan.json"),
+ "base_tables": _file_stats(base_tables),
+ "base_marker": _signature(base_marker_path),
+ "validation_root": str(validation_root),
+ "annotation": dict(annotation_cfg),
+ "entry": dict(entry_cfg),
+ "interface": dict(interface_cfg),
+ "references": {
+ name: _signature(path) for name, path in reference_files.items()
+ },
+ }
+ marker_path = output_dir / "entry_update.json"
+ prepared_paths = _prepared_entry_outputs(output_dir)
+ if output_dir.exists():
+ if not marker_path.is_file():
+ raise ValueError("output directory is not an entry-update workspace")
+ previous_marker: dict[str, Any] = json.loads(marker_path.read_text())
+ if previous_marker["inputs"] != binding:
+ raise ValueError("update inputs changed; use a new workspace")
+ if previous_marker["status"] == collate.REPAIR_REQUIRED_STATUS:
+ if previous_marker["outputs"] != _file_stats(prepared_paths):
+ raise ValueError("prepared entry tables changed; use a new workspace")
+ return previous_marker
+ output_dir.mkdir(parents=True, exist_ok=True)
+ report: dict[str, Any] = {
+ "status": "preparing_entries",
+ "inputs": binding,
+ "base_release": str(base),
+ }
+ write_json_atomic(marker_path, report)
+ incoming = output_dir / ".incoming"
+ if len(changed):
+ for relative, source in reference_files.items():
+ destination = incoming / relative
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ copy2(source, destination)
+ _, failed = ingest_pdb_batch(
+ pdb_ids=changed.pdb_id.tolist(),
+ output_root=incoming,
+ cif_root=Path(plan["nextgen_root"]) / "data/entries/divided",
+ validation_root=validation_root,
+ annotation_cfg=annotation_cfg,
+ entry_cfg=entry_cfg,
+ interface_cfg=interface_cfg,
+ mode="all",
+ )
+ if failed:
+ raise RuntimeError(
+ f"entry update failed; inspect {incoming / 'metrics'} and rerun"
+ )
+ has_ligands = any(
+ (incoming / "raw_entries" / pdb_id[1:3] / f"{pdb_id}.parquet").is_file()
+ for pdb_id in changed.pdb_id
+ )
+ if not has_ligands:
+ # Sidecar-only changes still replace the entry's old ligand rows.
+ # Keep the base schemas, but none of its annotation or validation data.
+ for name in ("annotation", "system_validation"):
+ schema = pq.read_schema(base_tables[name])
+ collate._write_table_atomic(
+ pa.Table.from_batches([], schema=schema),
+ incoming / "index" / ENTRY_TABLES[name][0],
+ )
+ collate.run_collation(
+ incoming,
+ threads=threads,
+ memory_limit=memory_limit,
+ scratch_dir=scratch_dir,
+ include_ligand_annotations=has_ligands,
+ )
+ observed = pd.read_parquet(incoming / "index/entry_sources.parquet").set_index(
+ "entry_pdb_id"
+ )[REVISION_COLUMNS]
+ expected = changed.set_index("pdb_id")[
+ ["current_major_revision", "current_minor_revision"]
+ ]
+ expected.columns = REVISION_COLUMNS
+ if (
+ not observed.astype("Int64")
+ .sort_index()
+ .equals(expected.astype("Int64").sort_index())
+ ):
+ raise ValueError("processed entry revisions differ from the update plan")
+ stage = output_dir / ".entry_tables"
+ counts = _combine_tables(
+ base,
+ incoming if len(changed) else None,
+ stage,
+ remove,
+ threads=threads,
+ memory_limit=memory_limit,
+ scratch_dir=scratch_dir,
+ )
+ staged_tables = {
+ name: stage / filename for name, (filename, _) in ENTRY_TABLES.items()
+ }
+ validation = collate._validate_final_tables(
+ staged_tables,
+ expected_counts=counts,
+ min_interface_residues=min_residues,
+ threads=threads,
+ memory_limit=memory_limit,
+ scratch_dir=scratch_dir,
+ )
+ load_update_plan(plan_dir)
+ if binding["base_tables"] != _file_stats(base_tables) or binding[
+ "base_marker"
+ ] != _signature(base_marker_path):
+ raise RuntimeError("existing release changed during entry processing")
+ (output_dir / "index").mkdir(exist_ok=True)
+ collate._install_final_tables_fail_closed(
+ staged_tables,
+ entry_table_paths(output_dir),
+ output_dir / "index" / collate.FINAL_MARKER_NAME,
+ )
+ publish_affinity_tables(
+ output_dir,
+ affinity_dir=base / "dbs" / "affinity",
+ base_dir=base,
+ changed_pdb_ids=changed.pdb_id.tolist(),
+ removed_pdb_ids=remove,
+ )
+ report.update(
+ status=collate.REPAIR_REQUIRED_STATUS,
+ incoming_entries=str(incoming) if len(changed) else None,
+ ingested_pdb_ids=changed.pdb_id.tolist(),
+ obsolete_pdb_ids=entries.loc[entries.action == "obsolete", "pdb_id"].tolist(),
+ ligand_contacts_computed=True,
+ protein_contacts_computed=True,
+ **validation,
+ )
+ write_json_atomic(
+ output_dir / "index" / collate.FINAL_MARKER_NAME,
+ {
+ "status": collate.REPAIR_REQUIRED_STATUS,
+ "mode": "targeted_repair",
+ "interface_min_residues": min_residues,
+ "ligand_contacts_computed": True,
+ "protein_contacts_computed": True,
+ "entry_update": str(marker_path),
+ **validation,
+ },
+ )
+ report["outputs"] = _file_stats(prepared_paths)
+ write_json_atomic(marker_path, report)
+ return report
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument("plan_dir", type=Path)
+ parser.add_argument("output_dir", type=Path)
+ parser.add_argument("--validation-root", type=Path, required=True)
+ parser.add_argument(
+ "--config",
+ type=Path,
+ required=True,
+ help="original release's pipeline configuration",
+ )
+ parser.add_argument("--threads", type=int, default=4)
+ parser.add_argument("--memory-limit", default="8GB")
+ parser.add_argument("--scratch-dir", type=Path)
+ args = parser.parse_args()
+ cfg = config.get_config(
+ config=OmegaConf.load(args.config), config_args=[], cached=False
+ )
+ report = apply_entry_update(
+ args.plan_dir,
+ args.output_dir,
+ validation_root=args.validation_root,
+ annotation_cfg=dict(cfg.annotation),
+ entry_cfg=dict(cfg.entry),
+ interface_cfg=dict(cfg.interface),
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ scratch_dir=args.scratch_dir,
+ )
+ print(json.dumps(report, indent=2, sort_keys=True))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/plinder/data/pipeline/update_release.py b/src/plinder/data/pipeline/update_release.py
new file mode 100644
index 000000000..85a2d2bd1
--- /dev/null
+++ b/src/plinder/data/pipeline/update_release.py
@@ -0,0 +1,2802 @@
+# Copyright (c) 2026, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Finish a planned PDB update in a new release directory."""
+
+from __future__ import annotations
+
+import argparse
+import gzip
+import hashlib
+import json
+import logging
+import os
+from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor, as_completed
+from dataclasses import replace
+from itertools import groupby
+from multiprocessing import get_context
+from pathlib import Path
+from shutil import copyfile, rmtree
+from typing import Any, Iterable, cast
+
+import duckdb
+import pandas as pd
+import pyarrow as pa
+import pyarrow.compute as pc
+import pyarrow.parquet as pq
+from omegaconf import DictConfig, OmegaConf
+
+from plinder.core.release import RELEASE_PATHS
+from plinder.core.utils import schemas
+from plinder.core.utils.files import (
+ file_sha256,
+ link_or_copy_file,
+ read_json_cache,
+ write_json_atomic,
+)
+from plinder.data import clusters, databases
+from plinder.data.annotations import ccd_ligand_dbs, get_similarity_scores
+from plinder.data.pipeline import config, score, tasks, utils
+from plinder.data.pipeline.update_archives import update_ligand_archives
+from plinder.data.pipeline.update_entries import apply_entry_update
+from plinder.data.pipeline.updates import load_update_plan
+from plinder.data.pipeline.weekly_clusters import (
+ extend_interface_clusters,
+ extend_ligand_clusters,
+ extend_protein_clusters,
+)
+
+LOG = logging.getLogger(__name__)
+
+_BASE_ARTIFACT_ROOTS = (
+ "alignments",
+ "alignment_cigars",
+ "ccd_dbs",
+ "dbs",
+ "exports",
+ "fingerprints",
+ "index",
+ "interface_clusters",
+ "interface_sampling",
+ "interface_scores",
+ "ligand_clusters",
+ "ligand_sampling",
+ "ligand_scores",
+ "manifests",
+ "mhfp6_scores",
+ "protein_clusters",
+ "scores",
+ "search_databases",
+)
+_TRANSIENT_BASE_DIRECTORIES = {".staging", "ligand_3d_pair_repairs", "ligand_3d_pairs"}
+_TRANSIENT_BASE_SUFFIXES = (".installing", ".previous", ".tmp", ".tmp.parquet")
+
+_STAGES = (
+ "entries_and_archives",
+ "search_inputs",
+ "alignments",
+ "scores",
+ "ligand_chemistry",
+ "cluster_assignments",
+ "final_tables",
+)
+
+
+def _reuse_base_artifacts(base: Path, workspace: Path) -> None:
+ """Hard-link unchanged downstream files without replacing prepared files."""
+ for root_name in _BASE_ARTIFACT_ROOTS:
+ source_root = base / root_name
+ if not source_root.exists():
+ continue
+ for current, directories, filenames in os.walk(source_root, topdown=True):
+ source_dir = Path(current)
+ relative = source_dir.relative_to(base)
+ target_dir = workspace / relative
+ target_dir.mkdir(parents=True, exist_ok=True)
+ for name in list(directories):
+ if (
+ name in _TRANSIENT_BASE_DIRECTORIES
+ or (root_name == "dbs" and name == "aln")
+ or (
+ relative.as_posix() == "dbs/subdbs"
+ and name in {"search_db=holo", "search_db=apo"}
+ )
+ or name.endswith(_TRANSIENT_BASE_SUFFIXES)
+ ):
+ directories.remove(name)
+ continue
+ source = source_dir / name
+ target = target_dir / name
+ if source.is_symlink():
+ if not target.exists() and not target.is_symlink():
+ link_or_copy_file(source, target)
+ directories.remove(name)
+ else:
+ target.mkdir(exist_ok=True)
+ for name in filenames:
+ if name.endswith(_TRANSIENT_BASE_SUFFIXES):
+ continue
+ source = source_dir / name
+ target = target_dir / name
+ if not target.exists() and not target.is_symlink():
+ link_or_copy_file(source, target)
+
+
+def _chains_by_entry(chains: pd.DataFrame) -> dict[str, set[str]]:
+ return {
+ str(entry_id): set(rows["chain_auth_id"].dropna().astype(str))
+ for entry_id, rows in chains.groupby("entry_pdb_id", sort=False)
+ }
+
+
+def _scoring_chains(data_dir: Path, search_db: str) -> pd.DataFrame:
+ if search_db == "apo":
+ return tasks._apo_scoring_chains(data_dir)
+ if search_db == "interface_apo":
+ return tasks._interface_apo_scoring_chains(data_dir)
+ chains = tasks._protein_scoring_chains(data_dir)
+ auth_ids = pd.read_parquet(
+ data_dir / "index" / "entry_chains.parquet",
+ columns=["entry_pdb_id", "chain_asym_id", "chain_auth_id"],
+ )
+ return chains.merge(
+ auth_ids,
+ on=["entry_pdb_id", "chain_asym_id"],
+ how="left",
+ validate="one_to_one",
+ )
+
+
+def _query_manifest(data_dir: Path, search_db: str) -> Path:
+ if search_db == "apo":
+ return data_dir / score.LINKED_APO_QUERY_MANIFEST_RELATIVE
+ if search_db == "interface_apo":
+ return data_dir / score.INTERFACE_APO_QUERY_MANIFEST_RELATIVE
+ return data_dir / score.MANIFEST_RELATIVE
+
+
+def _database_identifiers(chains: pd.DataFrame, alignment_type: str) -> set[str]:
+ chains = chains.loc[chains["chain_auth_id"].notna()]
+ if alignment_type == "foldseek":
+ return {
+ f"pdb_0000{row.entry_pdb_id}_xyz-enrich_{row.chain_auth_id}"
+ for row in chains.itertuples(index=False)
+ }
+ return {
+ f"{row.entry_pdb_id}_{row.chain_auth_id}"
+ for row in chains.itertuples(index=False)
+ }
+
+
+def _prepare_weekly_search_overlay(
+ *,
+ base: Path,
+ data_dir: Path,
+ affected: set[str],
+ nextgen_root: Path,
+ search_databases: list[str],
+ scratch_dir: Path,
+ threads: int,
+) -> set[str]:
+ """Keep the full search DB fixed and index cumulative changed chains."""
+ shadowed_path = Path("manifests/weekly_shadowed_entries.parquet")
+ previous = base / shadowed_path
+ shadowed = set(affected)
+ if previous.is_file():
+ shadowed.update(
+ map(str, pq.read_table(previous, columns=["pdb_id"])["pdb_id"].to_pylist())
+ )
+ chains = pd.read_parquet(
+ data_dir / "index/entry_chains.parquet",
+ columns=[
+ "entry_pdb_id",
+ "chain_auth_id",
+ "chain_receptor_type",
+ "chain_sequence",
+ ],
+ filters=[("entry_pdb_id", "in", sorted(shadowed))],
+ )
+ proteins = chains.loc[
+ chains.chain_receptor_type.eq("protein") & chains.chain_auth_id.notna()
+ ].copy()
+ active = set(proteins.entry_pdb_id.astype(str))
+ overlay = data_dir / "dbs/weekly_delta"
+ if active:
+ staging = scratch_dir / "weekly_delta_build"
+ rmtree(staging, ignore_errors=True)
+ staging.mkdir(parents=True)
+ foldseek_input = staging / "foldseek_inputs.tsv"
+ with foldseek_input.open("w") as handle:
+ for pdb_id in sorted(active):
+ source = (
+ nextgen_root
+ / "data/entries/divided"
+ / pdb_id[1:3]
+ / f"pdb_0000{pdb_id}"
+ / f"pdb_0000{pdb_id}_xyz-enrich.cif.gz"
+ )
+ if not source.is_file():
+ raise FileNotFoundError(source)
+ handle.write(f"{source}\n")
+ proteins["identifier"] = (
+ proteins.entry_pdb_id.astype(str) + "_" + proteins.chain_auth_id.astype(str)
+ )
+ conflicts = proteins.groupby("identifier").chain_sequence.nunique()
+ if conflicts.gt(1).any():
+ raise ValueError("changed chains have conflicting auth-chain sequences")
+ sequences = proteins.dropna(subset=["chain_sequence"]).drop_duplicates(
+ "identifier"
+ )
+ sequences = sequences.loc[sequences.chain_sequence.ne("")]
+ if not sequences.chain_sequence.astype(str).str.fullmatch("[A-Za-z]+").all():
+ raise ValueError("changed protein sequences contain invalid residues")
+ mmseqs_input = staging / "mmseqs_inputs.fasta"
+ with mmseqs_input.open("w") as handle:
+ for row in sequences.itertuples(index=False):
+ handle.write(f">{row.identifier}\n{row.chain_sequence}\n")
+ sources_by_backend = {"foldseek": foldseek_input}
+ if not sequences.empty:
+ sources_by_backend["mmseqs"] = mmseqs_input
+ for backend, source in sources_by_backend.items():
+ databases.create_db(source, staging / backend, backend, threads=threads)
+
+ selected: dict[str, set[str]] = {}
+ sources: dict[str, Path] = {}
+ for search_db in search_databases:
+ if search_db == "pred":
+ continue
+ target_chains = _scoring_chains(data_dir, search_db)
+ target_chains = target_chains.loc[
+ target_chains.entry_pdb_id.astype(str).isin(active)
+ ]
+ for backend in ("foldseek", "mmseqs"):
+ if backend not in sources_by_backend:
+ continue
+ identifiers = _database_identifiers(target_chains, backend)
+ if identifiers:
+ key = f"{search_db}_{backend}"
+ selected[key] = identifiers
+ sources[key] = staging / backend / backend
+ if sources:
+ databases.make_sub_dbs(
+ staging / "subdbs",
+ sources,
+ identifiers_by_database=selected,
+ tmp_dir=scratch_dir / "exact-search-dbs",
+ threads=threads,
+ )
+ databases.install_database_directory(staging, overlay)
+ elif overlay.exists():
+ rmtree(overlay)
+
+ target = data_dir / shadowed_path
+ target.parent.mkdir(parents=True, exist_ok=True)
+ temporary = target.with_suffix(".parquet.tmp")
+ pq.write_table(
+ pa.table({"pdb_id": pa.array(sorted(shadowed), type=pa.string())}),
+ temporary,
+ )
+ temporary.replace(target)
+ return shadowed
+
+
+def _queries_with_old_target_hits(
+ data_dir: Path, *, search_db: str, affected: set[str]
+) -> set[str]:
+ if not affected:
+ return set()
+ paths = [
+ path
+ for alignment_type in ("foldseek", "mmseqs")
+ for path in sorted(
+ (
+ data_dir
+ / "alignment_cigars"
+ / f"search_db={search_db}"
+ / f"alignment_type={alignment_type}"
+ ).glob("shard=*.parquet")
+ )
+ ]
+ if not paths:
+ return set()
+ target_ids = pa.array(sorted(affected), type=pa.string())
+ hits: set[str] = set()
+ for path in paths:
+ for batch in pq.ParquetFile(path).iter_batches(
+ columns=["query_entry", "target_entry"], batch_size=131_072
+ ):
+ mask = pc.is_in(batch.column("target_entry"), value_set=target_ids)
+ if pc.any(mask).as_py():
+ matches = pc.unique(pc.filter(batch.column("query_entry"), mask))
+ hits.update(
+ str(value) for value in matches.to_pylist() if value is not None
+ )
+ return hits
+
+
+def _changed_target_database(
+ data_dir: Path,
+ *,
+ search_db: str,
+ affected: set[str],
+) -> Path | None:
+ chains = _scoring_chains(data_dir, search_db)
+ chains = chains.loc[chains["entry_pdb_id"].astype(str).isin(affected)]
+ if not any(_database_identifiers(chains, kind) for kind in ("foldseek", "mmseqs")):
+ return None
+ target_dir = data_dir / "dbs/weekly_delta/subdbs"
+ if not any(
+ (target_dir / f"{search_db}_{kind}/exact_cluster.json").is_file()
+ for kind in ("foldseek", "mmseqs")
+ ):
+ raise FileNotFoundError(f"missing changed-target database for {search_db}")
+ return target_dir
+
+
+def _search_changed_targets(
+ data_dir: Path,
+ *,
+ search_db: str,
+ query_ids: list[str],
+ target_database_dir: Path | None,
+ scorer_cfg: DictConfig,
+ foldseek_cfg: DictConfig,
+ mmseqs_cfg: DictConfig,
+ scratch_dir: Path,
+ threads: int,
+) -> set[str]:
+ if target_database_dir is None or not query_ids:
+ return set()
+ scorer, _, work = utils.get_scorer(
+ data_dir=data_dir,
+ pdb_ids=[],
+ scorer_cfg=scorer_cfg,
+ load_entries=False,
+ foldseek_cfg=foldseek_cfg,
+ mmseqs_cfg=mmseqs_cfg,
+ scratch_dir=scratch_dir / "queries",
+ )
+ hits: set[str] = set()
+ active = set(query_ids)
+ try:
+ for aln_type in ("mmseqs", "foldseek"):
+ if not (
+ target_database_dir / f"{search_db}_{aln_type}/exact_cluster.json"
+ ).is_file():
+ continue
+ changed_db, _, _ = databases.exact_search_database_paths(
+ target_database_dir, search_db, aln_type
+ )
+ probe_dir = work / search_db / aln_type
+ probe_dir.mkdir(parents=True, exist_ok=True)
+ # Candidate discovery is permissive; the usual forward search
+ # applies the requested cutoff and produces the release scores.
+ probe_config = replace(
+ scorer.get_config(search_db, aln_type),
+ evalue=2.0,
+ max_seqs=2_000_000,
+ coverage=0.0,
+ min_seq_id=0.0,
+ )
+ full_databases = [scorer.source_to_full_db_file[f"holo_{aln_type}"]]
+ overlay = data_dir / "dbs/weekly_delta" / aln_type / aln_type
+ if overlay.with_suffix(".dbtype").is_file():
+ full_databases.append(overlay)
+ for index, full_db in enumerate(full_databases):
+ target_identifiers = get_similarity_scores.run_alignment(
+ aln_type=aln_type,
+ query_db=changed_db,
+ target_db=full_db,
+ search_target_db=full_db,
+ search_db=probe_dir / f"search-{index}",
+ aln_file=probe_dir / f"hits-{index}.tsv",
+ alignment_config=probe_config,
+ tmp_dir=probe_dir / f"tmp-{index}",
+ threads=threads,
+ query_ids_only=True,
+ id_column="target",
+ )
+ hits.update(
+ identifier.removeprefix("pdb_0000")[:4]
+ for identifier in target_identifiers or ()
+ if identifier.removeprefix("pdb_0000")[:4] in active
+ )
+ finally:
+ rmtree(work, ignore_errors=True)
+ return hits
+
+
+def _remove_inactive_queries(
+ data_dir: Path, *, search_db: str, pdb_ids: Iterable[str]
+) -> None:
+ for pdb_id in pdb_ids:
+ for alignment_type in ("foldseek", "mmseqs"):
+ (
+ data_dir
+ / "dbs"
+ / "subdbs"
+ / f"{search_db}_{alignment_type}"
+ / "aln"
+ / f"{pdb_id}.parquet"
+ ).unlink(missing_ok=True)
+ (
+ data_dir / "dbs" / "subdbs" / f"search_db={search_db}" / f"{pdb_id}.parquet"
+ ).unlink(missing_ok=True)
+
+
+def _refresh_alignment_shards(
+ data_dir: Path,
+ *,
+ search_db: str,
+ shards: set[str],
+ replacement_query_ids: set[str],
+ replacement_target_ids: set[str] | None = None,
+ scorer_cfg: DictConfig,
+ scratch_dir: Path,
+ threads: int,
+) -> None:
+ def refresh(shard: str) -> None:
+ tasks.map_batch_alignments(
+ data_dir=data_dir,
+ shards=[shard],
+ scorer_cfg=scorer_cfg,
+ force_update=True,
+ scratch_dir=scratch_dir,
+ search_db=search_db,
+ replacement_query_ids={
+ pdb_id for pdb_id in replacement_query_ids if pdb_id[1:3] == shard
+ },
+ replacement_target_ids=replacement_target_ids,
+ )
+ if any(
+ tasks._alignment_release_path(
+ data_dir=data_dir,
+ search_db=search_db,
+ alignment_type=alignment_type,
+ shard=shard,
+ ).is_file()
+ for alignment_type in ("foldseek", "mmseqs")
+ ):
+ return
+ manifest_root = data_dir / "alignments" / "manifests"
+ if search_db != "holo":
+ manifest_root = manifest_root / f"search_db={search_db}"
+ (manifest_root / f"shard={shard}.json").unlink(missing_ok=True)
+
+ ordered = sorted(shards)
+ workers = min(4, threads, len(ordered))
+ if workers == 1:
+ for shard in ordered:
+ refresh(shard)
+ elif workers > 1:
+ with ThreadPoolExecutor(max_workers=workers) as pool:
+ list(pool.map(refresh, ordered))
+
+
+def _rebase_unchanged_alignment_manifests(
+ data_dir: Path, *, search_db: str, repaired_shards: set[str]
+) -> None:
+ """Point untouched shard reports at the updated chain lookup."""
+ lookup = tasks._completed_alignment_chain_lookup(data_dir)
+ if lookup is None:
+ raise ValueError("alignment chain lookup is incomplete")
+ manifest_root = data_dir / "alignments" / "manifests"
+ if search_db != "holo":
+ manifest_root = manifest_root / f"search_db={search_db}"
+ for path in sorted(manifest_root.glob("shard=*.json")):
+ shard = path.stem.removeprefix("shard=")
+ if shard in repaired_shards:
+ continue
+ payload = json.loads(path.read_text())
+ inputs = payload.get("inputs")
+ if not isinstance(inputs, dict):
+ raise ValueError(f"invalid alignment report inputs: {path}")
+ outputs = payload.get("outputs")
+ if not isinstance(outputs, dict):
+ raise ValueError(f"invalid alignment report: {path}")
+ for alignment_type, signatures in inputs.items():
+ output = tasks._alignment_release_path(
+ data_dir=data_dir,
+ search_db=search_db,
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ if not signatures:
+ if outputs.get(alignment_type) is not None:
+ raise ValueError(f"unexpected mapped alignment output: {output}")
+ continue
+ if not output.is_file() or not (
+ schemas.release_alignment_mapping_schema_is_current(
+ set(pq.read_schema(output).names),
+ alignment_type=alignment_type,
+ include_scores=search_db != "holo",
+ )
+ ):
+ raise ValueError(f"invalid mapped alignment output: {output}")
+ stat = output.stat()
+ if outputs.get(alignment_type) != {
+ "name": output.name,
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ }:
+ raise ValueError(f"mapped alignment report changed: {output}")
+ payload["alignment_chain_lookup"] = lookup
+ write_json_atomic(path, payload)
+
+
+def _plan_alignment_repairs(
+ data_dir: Path,
+ *,
+ search_db: str,
+ affected: set[str],
+ scorer_cfg: DictConfig,
+ foldseek_cfg: DictConfig,
+ mmseqs_cfg: DictConfig,
+ scratch_dir: Path,
+ threads: int,
+) -> set[str]:
+ """Find queries whose capped search can change in either direction."""
+ manifest_path = _query_manifest(data_dir, search_db)
+ active = set(
+ pd.read_parquet(manifest_path, columns=["pdb_id"])["pdb_id"].astype(str)
+ )
+ if search_db == "pred":
+ return active.intersection(affected)
+ old_hits = _queries_with_old_target_hits(
+ data_dir, search_db=search_db, affected=affected
+ )
+ changed_targets = _changed_target_database(
+ data_dir,
+ search_db=search_db,
+ affected=affected,
+ )
+ reverse_hits = _search_changed_targets(
+ data_dir,
+ search_db=search_db,
+ query_ids=sorted(active.difference(affected)),
+ target_database_dir=changed_targets,
+ scorer_cfg=scorer_cfg,
+ foldseek_cfg=foldseek_cfg,
+ mmseqs_cfg=mmseqs_cfg,
+ scratch_dir=scratch_dir,
+ threads=threads,
+ )
+ return active.intersection(affected | old_hits | reverse_hits)
+
+
+def _load_or_plan_alignment_repairs(
+ data_dir: Path,
+ *,
+ search_databases: list[str],
+ affected: set[str],
+ scorer_cfg: DictConfig,
+ foldseek_cfg: DictConfig,
+ mmseqs_cfg: DictConfig,
+ scratch_dir: Path,
+ threads: int,
+ batch_size: int,
+ state_path: Path,
+ report: dict[str, Any],
+) -> dict[str, set[str]]:
+ """Persist the full repair set before any raw alignment is replaced."""
+ stored = report.get("alignment_repair_queries")
+ if stored is None:
+ planned = {
+ search_db: sorted(
+ _plan_alignment_repairs(
+ data_dir,
+ search_db=search_db,
+ affected=affected,
+ scorer_cfg=scorer_cfg,
+ foldseek_cfg=foldseek_cfg,
+ mmseqs_cfg=mmseqs_cfg,
+ scratch_dir=scratch_dir / search_db,
+ threads=threads,
+ )
+ )
+ for search_db in search_databases
+ }
+ report["alignment_repair_queries"] = planned
+ write_json_atomic(state_path, report)
+ stored = planned
+ if not isinstance(stored, dict) or set(stored) != set(search_databases):
+ raise ValueError("weekly alignment repair plan does not match configuration")
+ return {
+ search_db: set(map(str, stored[search_db])) for search_db in search_databases
+ }
+
+
+def repair_alignments(
+ data_dir: Path,
+ *,
+ search_db: str,
+ affected: set[str],
+ full_queries: set[str],
+ targeted_queries: set[str] | None = None,
+ scorer_cfg: DictConfig,
+ foldseek_cfg: DictConfig,
+ mmseqs_cfg: DictConfig,
+ scratch_dir: Path,
+ threads: int,
+ batch_size: int,
+) -> set[str]:
+ """Fully search changed queries and add changed-target hits to old queries."""
+ manifest_path = _query_manifest(data_dir, search_db)
+ active = set(
+ pd.read_parquet(manifest_path, columns=["pdb_id"])["pdb_id"].astype(str)
+ )
+ full_queries = active.intersection(full_queries)
+ targeted_queries = active.intersection(targeted_queries or set()) - full_queries
+ inactive = affected.difference(active)
+ _remove_inactive_queries(data_dir, search_db=search_db, pdb_ids=inactive)
+ configured_search_db = "apo" if search_db == "interface_apo" else search_db
+ selected_cfg = cast(
+ DictConfig,
+ OmegaConf.merge(scorer_cfg, {"sub_databases": [configured_search_db]}),
+ )
+ for alignment_type in ("foldseek", "mmseqs"):
+ raw_dir = data_dir / "dbs/subdbs" / f"{search_db}_{alignment_type}" / "aln"
+ for pdb_id in full_queries | targeted_queries:
+ (raw_dir / f"{pdb_id}.parquet").unlink(missing_ok=True)
+ shadowed_path = data_dir / "manifests/weekly_shadowed_entries.parquet"
+ shadowed = set(
+ map(str, pq.read_table(shadowed_path, columns=["pdb_id"])["pdb_id"].to_pylist())
+ )
+ if targeted_queries:
+ changed_targets = _changed_target_database(
+ data_dir,
+ search_db=search_db,
+ affected=affected,
+ )
+ if changed_targets is None:
+ # Obsolete targets have no database to search. Re-search their old
+ # query partners to remove stale hits.
+ full_queries.update(targeted_queries)
+ targeted_queries.clear()
+ else:
+ # Arrow limits the partitioned raw output to 1,024 query PDBs
+ # per write batch.
+ targeted_batch_size = min(batch_size, 500)
+ available_backends = [
+ backend
+ for backend in ("foldseek", "mmseqs")
+ if (
+ changed_targets / f"{search_db}_{backend}/exact_cluster.json"
+ ).is_file()
+ ]
+ for source_label, query_ids in (
+ ("base", targeted_queries - shadowed),
+ ("overlay", targeted_queries & shadowed),
+ ):
+ ordered_targets = sorted(query_ids)
+ for start in range(0, len(ordered_targets), targeted_batch_size):
+ tasks.run_batch_searches(
+ data_dir=data_dir,
+ pdb_ids=ordered_targets[start : start + targeted_batch_size],
+ scorer_cfg=selected_cfg,
+ foldseek_cfg=foldseek_cfg,
+ mmseqs_cfg=mmseqs_cfg,
+ cpu=threads,
+ scratch_dir=(
+ scratch_dir / f"targeted-{search_db}-{source_label}-"
+ f"{start // targeted_batch_size:05d}"
+ ),
+ search_databases=[search_db],
+ alignment_types=available_backends,
+ force_update=True,
+ target_database_dir=changed_targets,
+ query_database_dir=(
+ data_dir / "dbs/weekly_delta"
+ if source_label == "overlay"
+ else None
+ ),
+ )
+ targeted_shards = {pdb_id[1:3] for pdb_id in targeted_queries}
+ _refresh_alignment_shards(
+ data_dir,
+ search_db=search_db,
+ shards=targeted_shards,
+ replacement_query_ids=targeted_queries,
+ replacement_target_ids=shadowed,
+ scorer_cfg=selected_cfg,
+ scratch_dir=scratch_dir / f"map-targeted-{search_db}",
+ threads=threads,
+ )
+ for alignment_type in ("foldseek", "mmseqs"):
+ raw_dir = (
+ data_dir / "dbs/subdbs" / f"{search_db}_{alignment_type}" / "aln"
+ )
+ for pdb_id in targeted_queries:
+ (raw_dir / f"{pdb_id}.parquet").unlink(missing_ok=True)
+ for source_label, query_ids in (
+ ("base", full_queries - shadowed),
+ ("overlay", full_queries & shadowed),
+ ):
+ ordered = sorted(query_ids)
+ for start in range(0, len(ordered), batch_size):
+ tasks.run_batch_searches(
+ data_dir=data_dir,
+ pdb_ids=ordered[start : start + batch_size],
+ scorer_cfg=selected_cfg,
+ foldseek_cfg=foldseek_cfg,
+ mmseqs_cfg=mmseqs_cfg,
+ cpu=threads,
+ scratch_dir=(
+ scratch_dir
+ / f"full-{search_db}-{source_label}-{start // batch_size:05d}"
+ ),
+ search_databases=[search_db],
+ force_update=True,
+ query_database_dir=(
+ data_dir / "dbs/weekly_delta" if source_label == "overlay" else None
+ ),
+ )
+ missing_raw = [
+ f"{search_db}_{alignment_type}/{pdb_id}"
+ for alignment_type in ("foldseek", "mmseqs")
+ for pdb_id in sorted(full_queries)
+ if not (
+ data_dir
+ / "dbs"
+ / "subdbs"
+ / f"{search_db}_{alignment_type}"
+ / "aln"
+ / f"{pdb_id}.parquet"
+ ).is_file()
+ ]
+ if missing_raw:
+ raise FileNotFoundError(f"missing weekly alignment results: {missing_raw[:10]}")
+ full_shards = {pdb_id[1:3] for pdb_id in full_queries | inactive}
+ if full_shards:
+ _refresh_alignment_shards(
+ data_dir,
+ search_db=search_db,
+ shards=full_shards,
+ replacement_query_ids=full_queries | inactive,
+ scorer_cfg=selected_cfg,
+ scratch_dir=scratch_dir / f"map-{search_db}",
+ threads=threads,
+ )
+ _rebase_unchanged_alignment_manifests(
+ data_dir,
+ search_db=search_db,
+ repaired_shards=full_shards | {pdb_id[1:3] for pdb_id in targeted_queries},
+ )
+ return full_queries
+
+
+def _write_pdb_manifest(path: Path, pdb_ids: Iterable[str]) -> Path:
+ path.parent.mkdir(exist_ok=True, parents=True)
+ identifiers = sorted(set(map(str, pdb_ids)))
+ if path.is_file() and pd.read_parquet(path)["pdb_id"].tolist() == identifiers:
+ return path
+ frame = pd.DataFrame({"pdb_id": identifiers})
+ temporary = path.with_suffix(path.suffix + ".tmp")
+ frame.to_parquet(temporary, index=False)
+ temporary.replace(path)
+ return path
+
+
+def _refresh_foldseek_source_manifest(
+ data_dir: Path, *, nextgen_root: Path, affected: set[str]
+) -> None:
+ """Point reused Foldseek source paths at the current managed snapshot."""
+ manifest = data_dir / "manifests/foldseek_createdb_inputs.tsv"
+ if not manifest.is_file() or not affected:
+ return
+ lines = manifest.read_text().splitlines()
+ updated: list[str] = []
+ for line in lines:
+ old = Path(line)
+ pdb_id = old.parent.name.removeprefix("pdb_0000")
+ if pdb_id in affected:
+ current = (
+ nextgen_root
+ / "data/entries/divided"
+ / pdb_id[1:3]
+ / f"pdb_0000{pdb_id}"
+ / old.name
+ )
+ if current.is_file():
+ line = str(current)
+ updated.append(line)
+ if updated != lines:
+ temporary = manifest.with_suffix(".tmp")
+ temporary.write_text("\n".join(updated) + "\n")
+ temporary.replace(manifest)
+
+
+def _changed_ligand_archive_entries(
+ base_data_dir: Path, data_dir: Path, affected: set[str]
+) -> set[str]:
+ """Identify entries whose ligand poses or features actually changed."""
+ by_shard: dict[str, list[str]] = {}
+ for pdb_id in sorted(affected):
+ by_shard.setdefault(pdb_id[1:3], []).append(pdb_id)
+
+ changed: set[str] = set()
+ for shard, pdb_ids in by_shard.items():
+
+ def archive_rows(root: Path) -> dict[str, list[dict[str, Any]]]:
+ path = root / "ligand_archives" / f"{shard}.parquet"
+ if not path.is_file():
+ return {}
+ rows = pq.read_table(
+ path,
+ columns=["pdb_id", "ligand_asym_id", "sdf", "pharmacophore_features"],
+ filters=[("pdb_id", "in", pdb_ids)],
+ ).to_pylist()
+ grouped: dict[str, list[dict[str, Any]]] = {}
+ for row in rows:
+ grouped.setdefault(str(row["pdb_id"]), []).append(row)
+ return grouped
+
+ before = archive_rows(base_data_dir)
+ after = archive_rows(data_dir)
+ for pdb_id in pdb_ids:
+ ordered_before = sorted(
+ before.get(pdb_id, []), key=lambda row: row["ligand_asym_id"]
+ )
+ ordered_after = sorted(
+ after.get(pdb_id, []), key=lambda row: row["ligand_asym_id"]
+ )
+ if ordered_before != ordered_after:
+ changed.add(pdb_id)
+ return changed
+
+
+def _unchanged_scoring_entries(
+ base: Path, data_dir: Path, affected: set[str]
+) -> set[str]:
+ """Find revised entries whose coordinate and scoring inputs are unchanged."""
+ if not affected:
+ return set()
+
+ def source_paths(root: Path) -> dict[str, Path]:
+ manifest = root / "manifests/foldseek_createdb_inputs.tsv"
+ if not manifest.is_file():
+ return {}
+ paths: dict[str, Path] = {}
+ with manifest.open() as lines:
+ for line in lines:
+ path = Path(line.strip())
+ pdb_id = path.parent.name.removeprefix("pdb_0000")
+ if pdb_id in affected:
+ paths[pdb_id] = path
+ return paths
+
+ old_sources = source_paths(base)
+ new_sources = source_paths(data_dir)
+
+ def source_digest(path: Path) -> str:
+ digest = hashlib.sha256()
+ opener = gzip.open if path.suffix == ".gz" else open
+ with opener(path, "rb") as handle:
+ for block in iter(lambda: handle.read(1024 * 1024), b""):
+ digest.update(block)
+ return digest.hexdigest()
+
+ unchanged = {
+ pdb_id
+ for pdb_id in affected & old_sources.keys() & new_sources.keys()
+ if old_sources[pdb_id].is_file()
+ and new_sources[pdb_id].is_file()
+ and (
+ old_sources[pdb_id] == new_sources[pdb_id]
+ or source_digest(old_sources[pdb_id]) == source_digest(new_sources[pdb_id])
+ )
+ }
+ if not unchanged:
+ return set()
+
+ columns_by_table = {
+ "entry_chains": [
+ "chain_asym_id",
+ "chain_auth_id",
+ "chain_type",
+ "chain_receptor_type",
+ "chain_sequence",
+ "chain_sequence_noncanonical",
+ "chain_is_holo",
+ "chain_is_ligand_like",
+ ],
+ "entry_biounit_chains": [
+ "biounit_id",
+ "chain_instance",
+ "chain_asym_id",
+ "chain_role",
+ "chain_num_contacting_ions",
+ "chain_num_contacting_artifacts",
+ "chain_num_contacting_other_ligands",
+ "chain_num_contacting_proteins",
+ ],
+ "annotation_table": [
+ "ligand_id",
+ "system_id",
+ "ligand_smiles",
+ "ligand_is_proper",
+ "ligand_neighboring_residues",
+ "ligand_interactions",
+ ],
+ "interface_annotation_table": [
+ "system_id",
+ "interface_chain_1_residue_numbers",
+ "interface_chain_2_residue_numbers",
+ ],
+ }
+ for table_name, columns in columns_by_table.items():
+
+ def rows(root: Path) -> dict[str, list[dict[str, Any]]] | None:
+ path = root / "index" / f"{table_name}.parquet"
+ if not path.is_file():
+ return None
+ selected = ["entry_pdb_id", *columns]
+ if not set(selected).issubset(pq.read_schema(path).names):
+ return None
+ records = pq.read_table(
+ path,
+ columns=selected,
+ filters=[("entry_pdb_id", "in", sorted(unchanged))],
+ ).to_pylist()
+ grouped: dict[str, list[dict[str, Any]]] = {}
+ for record in records:
+ grouped.setdefault(str(record.pop("entry_pdb_id")), []).append(record)
+ return grouped
+
+ before, after = rows(base), rows(data_dir)
+ if before is None or after is None:
+ return set()
+ unchanged = {
+ pdb_id
+ for pdb_id in unchanged
+ if sorted(before.get(pdb_id, []), key=str)
+ == sorted(after.get(pdb_id, []), key=str)
+ }
+ if not unchanged:
+ return set()
+ return unchanged - _changed_ligand_archive_entries(base, data_dir, unchanged)
+
+
+def _entries_with_interfaces(
+ base: Path, data_dir: Path, affected: set[str]
+) -> set[str]:
+ """Return changed entries with interfaces in either release."""
+ if not affected:
+ return set()
+ present: set[str] = set()
+ for root in (base, data_dir):
+ path = root / "index/interface_annotation_table.parquet"
+ if path.is_file():
+ present.update(
+ map(
+ str,
+ pq.read_table(
+ path,
+ columns=["entry_pdb_id"],
+ filters=[("entry_pdb_id", "in", sorted(affected))],
+ )
+ .column("entry_pdb_id")
+ .to_pylist(),
+ )
+ )
+ return present
+
+
+def _remove_affected_shape_scores(
+ data_dir: Path,
+ *,
+ shards: Iterable[str],
+ affected: set[str],
+ scratch_dir: Path,
+ threads: int,
+) -> int:
+ """Remove cached ligand-pair scores whose coordinates may have changed."""
+ if not affected:
+ return 0
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ affected_entries = pd.DataFrame({"pdb_id": sorted(affected)})
+ ordered = sorted(set(map(str, shards)))
+ workers = min(4, threads, len(ordered))
+ if not workers:
+ return 0
+
+ def remove(shard: str) -> int:
+ cached = data_dir / "scores/ligand_3d_by_query" / f"{shard}.parquet"
+ if not cached.is_file():
+ return 0
+ shard_scratch = scratch_dir / shard
+ shard_scratch.mkdir(exist_ok=True)
+ temporary = shard_scratch / f"{shard}.parquet"
+ previous_rows = pq.ParquetFile(cached).metadata.num_rows
+ with duckdb.connect() as connection:
+ connection.sql(f"SET threads={max(1, threads // workers)}")
+ connection.sql(f"SET temp_directory='{shard_scratch.as_posix()}'")
+ connection.register("affected_entries", affected_entries)
+ temporary.unlink(missing_ok=True)
+ connection.execute(
+ f"""
+ COPY (
+ SELECT scores.*
+ FROM read_parquet('{cached.as_posix()}') AS scores
+ ANTI JOIN affected_entries AS query_entries
+ ON scores.query_entry = query_entries.pdb_id
+ ANTI JOIN affected_entries AS target_entries
+ ON scores.target_entry = target_entries.pdb_id
+ ORDER BY
+ query_entry,
+ query_ligand_asym_id,
+ target_entry,
+ target_ligand_asym_id
+ ) TO '{temporary.as_posix()}' (
+ FORMAT PARQUET, COMPRESSION ZSTD
+ )
+ """
+ )
+ if not pq.read_schema(temporary).equals(schemas.LIGAND_3D_SCORE_SCHEMA):
+ temporary.unlink(missing_ok=True)
+ raise ValueError(
+ f"shape-score cache has an unexpected schema: {cached}"
+ )
+ current_rows = pq.ParquetFile(temporary).metadata.num_rows
+ install = cached.with_suffix(cached.suffix + ".tmp")
+ copyfile(temporary, install)
+ install.replace(cached)
+ temporary.unlink(missing_ok=True)
+ return int(previous_rows - current_rows)
+
+ if workers == 1:
+ return sum(remove(shard) for shard in ordered)
+ with ThreadPoolExecutor(max_workers=workers) as pool:
+ return sum(pool.map(remove, ordered))
+
+
+def _restore_score_query_caches(
+ *, base_data_dir: Path, data_dir: Path, query_ids: set[str]
+) -> None:
+ """Restore only the old queries needed for target-only score repair."""
+ by_shard: dict[str, list[str]] = {}
+ for pdb_id in sorted(query_ids):
+ source = base_data_dir / "dbs/subdbs/search_db=holo" / f"{pdb_id}.parquet"
+ if not source.is_file():
+ continue
+ destination = data_dir / "dbs/subdbs/search_db=holo" / source.name
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ if not destination.is_file():
+ link_or_copy_file(source, destination)
+ by_shard.setdefault(pdb_id[1:3], []).append(pdb_id)
+
+ sidecars = (
+ (
+ "ligand_3d_candidate_shards",
+ "ligand_3d_candidates/search_db=holo",
+ schemas.LIGAND_3D_CANDIDATE_SCHEMA,
+ ),
+ (
+ "ligand_pair_score_shards",
+ "ligand_pair_scores/search_db=holo",
+ schemas.LIGAND_PAIR_SCORE_SCHEMA,
+ ),
+ )
+ for shard, pdb_ids in by_shard.items():
+ for packed_name, query_name, schema in sidecars:
+ destinations = {
+ pdb_id: data_dir
+ / "scores"
+ / query_name
+ / f"shard={shard}"
+ / f"{pdb_id}.parquet"
+ for pdb_id in pdb_ids
+ }
+ missing = {
+ pdb_id: path
+ for pdb_id, path in destinations.items()
+ if not path.is_file()
+ }
+ if not missing:
+ continue
+ packed = base_data_dir / "scores" / packed_name / f"shard={shard}.parquet"
+ rows = (
+ pq.read_table(
+ packed,
+ columns=schema.names,
+ filters=[("query_entry", "in", list(missing))],
+ )
+ .cast(schema)
+ .sort_by([("query_entry", "ascending")])
+ )
+ seen = set()
+ offset = 0
+ for pdb_id, group in groupby(rows["query_entry"].to_pylist()):
+ count = sum(1 for _ in group)
+ selected = rows.slice(offset, count)
+ offset += count
+ if pdb_id not in missing:
+ continue
+ seen.add(pdb_id)
+ destination = missing[pdb_id]
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ temporary = destination.with_suffix(".parquet.tmp")
+ pq.write_table(selected, temporary, compression="zstd")
+ temporary.replace(destination)
+ for pdb_id in missing.keys() - seen:
+ destination = missing[pdb_id]
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ temporary = destination.with_suffix(".parquet.tmp")
+ pq.write_table(rows.slice(0, 0), temporary, compression="zstd")
+ temporary.replace(destination)
+
+
+def _repair_score_batches(
+ data_dir: Path,
+ repairs: pd.DataFrame,
+ scorer_cfg: DictConfig,
+ scratch_dir: Path,
+ threads: int,
+) -> None:
+ batches = [
+ (str(index), batch.to_dict("records"))
+ for index, batch in repairs.groupby("repair_batch_index", sort=True)
+ ]
+ workers = min(4, max(1, threads // 4), len(batches))
+ if workers < 2:
+ for index, batch in batches:
+ tasks.repair_batch_scores(
+ data_dir=data_dir,
+ repairs=batch,
+ scorer_cfg=scorer_cfg,
+ scratch_dir=scratch_dir / index,
+ threads=threads,
+ )
+ return
+
+ worker_threads = max(1, threads // workers)
+ thread_vars = ("OMP_NUM_THREADS", "OPENBLAS_NUM_THREADS", "MKL_NUM_THREADS")
+ previous = {name: os.environ.get(name) for name in thread_vars}
+ try:
+ for name in thread_vars:
+ os.environ[name] = str(worker_threads)
+ with ProcessPoolExecutor(
+ max_workers=workers, mp_context=get_context("spawn")
+ ) as pool:
+ futures = {
+ pool.submit(
+ tasks.repair_batch_scores,
+ data_dir=data_dir,
+ repairs=batch,
+ scorer_cfg=scorer_cfg,
+ scratch_dir=scratch_dir / index,
+ threads=worker_threads,
+ ): index
+ for index, batch in batches
+ }
+ for future in as_completed(futures):
+ future.result()
+ LOG.info("weekly score repair batch %s complete", futures[future])
+ finally:
+ for name, value in previous.items():
+ if value is None:
+ os.environ.pop(name, None)
+ else:
+ os.environ[name] = value
+
+
+def _collate_repaired_candidate_shards(
+ data_dir: Path,
+ shards: list[str],
+ scratch_dir: Path,
+ threads: int,
+ replacement_query_ids: set[str] | None = None,
+ source_query_ids: set[str] | None = None,
+) -> None:
+ workers = min(4, threads, len(shards))
+ if not workers:
+ return
+
+ def collate(shard: str) -> None:
+ tasks.collate_ligand_3d_candidates(
+ data_dir=data_dir,
+ shards=[shard],
+ scratch_dir=scratch_dir / shard,
+ threads=max(1, threads // workers),
+ replacement_query_ids=replacement_query_ids,
+ source_query_ids=source_query_ids,
+ )
+
+ if workers == 1:
+ for shard in shards:
+ collate(shard)
+ else:
+ with ThreadPoolExecutor(max_workers=workers) as pool:
+ list(pool.map(collate, shards))
+
+
+def _completed_holo_query_repair(
+ data_dir: Path,
+ *,
+ affected_manifest: Path,
+ full_manifest: Path,
+ target_manifest: Path,
+) -> dict[str, Any] | None:
+ repair_manifest = data_dir / score.SCORE_REPAIR_RELATIVE
+ plan_path = repair_manifest.with_suffix(".json")
+ completion_path = data_dir / score.SCORE_REPAIR_DROP_RELATIVE.with_suffix(".json")
+ if not all(
+ path.is_file() for path in (repair_manifest, plan_path, completion_path)
+ ):
+ return None
+ plan = json.loads(plan_path.read_text())
+ completion = json.loads(completion_path.read_text())
+ expected = {
+ "affected_manifest": affected_manifest,
+ "additional_full_query_manifest": full_manifest,
+ "additional_target_query_manifest": target_manifest,
+ "output": repair_manifest,
+ }
+ if completion.get("status") != "complete" or any(
+ plan.get(key) != score._source_signature(path) for key, path in expected.items()
+ ):
+ return None
+ if completion_path.stat().st_mtime_ns < repair_manifest.stat().st_mtime_ns:
+ return None
+ return cast(dict[str, Any], plan)
+
+
+def repair_holo_scores(
+ data_dir: Path,
+ *,
+ base_data_dir: Path,
+ affected: set[str],
+ full_alignment_queries: set[str],
+ targeted_alignment_queries: set[str],
+ scorer_cfg: DictConfig,
+ scratch_dir: Path,
+ threads: int,
+ memory_limit: str,
+ score_batch_size: int,
+ ligand_batch_size: int,
+) -> dict[str, Any]:
+ """Repair ligand-pocket scores and cached ligand-pair shape scores."""
+ rmtree(data_dir / "scores/ligand_3d_pair_repairs", ignore_errors=True)
+ holo_cfg = cast(
+ DictConfig, OmegaConf.merge(scorer_cfg, {"sub_databases": ["holo"]})
+ )
+ _restore_score_query_caches(
+ base_data_dir=base_data_dir,
+ data_dir=data_dir,
+ query_ids=targeted_alignment_queries,
+ )
+ affected_manifest = _write_pdb_manifest(
+ data_dir / "manifests" / "weekly_affected_entries.parquet", affected
+ )
+ full_manifest = _write_pdb_manifest(
+ data_dir / "manifests" / "weekly_full_score_queries.parquet",
+ full_alignment_queries,
+ )
+ target_manifest = _write_pdb_manifest(
+ data_dir / "manifests" / "weekly_target_score_queries.parquet",
+ targeted_alignment_queries,
+ )
+ repair_manifest = data_dir / score.SCORE_REPAIR_RELATIVE
+ plan = _completed_holo_query_repair(
+ data_dir,
+ affected_manifest=affected_manifest,
+ full_manifest=full_manifest,
+ target_manifest=target_manifest,
+ )
+ if plan is None:
+ score.plan_score_batches(
+ data_dir,
+ batch_size=score_batch_size,
+ threads=threads,
+ scratch_dir=scratch_dir / "plan-scores",
+ max_query_protein_chains=int(scorer_cfg.max_query_protein_chains),
+ max_query_proper_ligand_chains=int(
+ scorer_cfg.max_query_proper_ligand_chains
+ ),
+ reuse_mapped_alignments=True,
+ )
+ try:
+ plan = score.plan_score_repair(
+ data_dir,
+ affected_manifest=affected_manifest,
+ additional_full_query_manifest=full_manifest,
+ additional_target_query_manifest=target_manifest,
+ batch_size=score_batch_size,
+ target_batch_size=score_batch_size,
+ threads=threads,
+ scratch_dir=scratch_dir / "plan-repair",
+ memory_limit=memory_limit,
+ )
+ except ValueError as exc:
+ if str(exc) != "no active score queries are affected by the repair":
+ raise
+ return {"status": "complete", "query_count": 0, "pair_count": 0}
+ repairs = pd.read_parquet(repair_manifest)
+ _repair_score_batches(
+ data_dir,
+ repairs,
+ holo_cfg,
+ scratch_dir / "queries",
+ threads,
+ )
+ score.finalize_score_repair_queries(
+ data_dir,
+ repair_manifest=repair_manifest,
+ max_new_drops=0,
+ )
+ else:
+ repairs = pd.read_parquet(repair_manifest)
+
+ replacement_queries = set(repairs["pdb_id"].astype(str))
+ active_replacements = replacement_queries.intersection(
+ score.published_scoring_query_ids(data_dir)
+ )
+ shards = sorted(set(repairs["shard"].astype(str)))
+ existing_shards: list[str] = []
+ new_shards: list[str] = []
+ for shard in shards:
+ base_files = [
+ base_data_dir
+ / "scores"
+ / "ligand_3d_candidate_shards"
+ / f"shard={shard}.parquet",
+ base_data_dir
+ / "scores"
+ / "ligand_pair_score_shards"
+ / f"shard={shard}.parquet",
+ ]
+ if all(path.is_file() for path in base_files):
+ existing_shards.append(shard)
+ elif any(path.is_file() for path in base_files):
+ raise FileNotFoundError(
+ f"base release has an incomplete packed score shard {shard}: "
+ f"{[str(path) for path in base_files if not path.is_file()]}"
+ )
+ else:
+ new_shards.append(shard)
+ if existing_shards:
+ _collate_repaired_candidate_shards(
+ data_dir,
+ existing_shards,
+ scratch_dir / "candidate-shards",
+ threads,
+ replacement_query_ids=replacement_queries,
+ source_query_ids=active_replacements,
+ )
+ if new_shards:
+ _collate_repaired_candidate_shards(
+ data_dir,
+ new_shards,
+ scratch_dir / "candidate-shards",
+ threads,
+ )
+ pair_cache_root = data_dir / "scores" / "ligand_3d_by_query"
+ pair_cache_root.mkdir(exist_ok=True, parents=True)
+ for shard in new_shards:
+ pair_cache = pair_cache_root / f"{shard}.parquet"
+ if not pair_cache.is_file():
+ pq.write_table(
+ pa.Table.from_pylist([], schema=schemas.LIGAND_3D_SCORE_SCHEMA),
+ pair_cache,
+ )
+ removed_shape_scores = _remove_affected_shape_scores(
+ data_dir,
+ shards=shards,
+ affected=_changed_ligand_archive_entries(base_data_dir, data_dir, affected),
+ scratch_dir=scratch_dir / "invalidate-ligand-3d",
+ threads=threads,
+ )
+ ligand_plan = score.plan_score_repair_ligand_3d(
+ data_dir,
+ repair_manifest=repair_manifest,
+ batch_size=ligand_batch_size,
+ threads=threads,
+ scratch_dir=scratch_dir / "plan-ligand-3d",
+ memory_limit=memory_limit,
+ )
+ if int(ligand_plan["pair_count"]):
+ repair_pair_dir = data_dir / "scores" / "ligand_3d_pair_repairs"
+ for batch_index in range(int(ligand_plan["batch_count"])):
+ pairs = score._score_repair_ligand_3d_batch(
+ data_dir,
+ batch_index=batch_index,
+ batch_size=ligand_batch_size,
+ )
+ tasks.make_ligand_3d_scores(
+ data_dir=data_dir,
+ pairs=pairs,
+ batch_index=batch_index,
+ scorer_cfg=holo_cfg,
+ force_update=False,
+ scratch_dir=scratch_dir / "ligand-3d" / str(batch_index),
+ threads=threads,
+ output_path=repair_pair_dir / f"{batch_index}.parquet",
+ )
+ score.merge_score_repair_ligand_3d(
+ data_dir=data_dir,
+ shards=shards,
+ scratch_dir=scratch_dir / "merge-ligand-3d",
+ threads=threads,
+ )
+ repair_report = score.finalize_score_repair_artifacts(
+ data_dir,
+ repair_manifest=repair_manifest,
+ require_packed_scores=False,
+ )
+ active_shards = {
+ pdb_id[1:3] for pdb_id in score.published_scoring_query_ids(data_dir)
+ }
+ for shard in set(shards).difference(active_shards):
+ for path in [
+ data_dir / "scores/ligand_3d_candidate_shards" / f"shard={shard}.parquet",
+ data_dir / "scores/ligand_3d_candidate_shards" / f"shard={shard}.json",
+ data_dir / "scores/ligand_pair_score_shards" / f"shard={shard}.parquet",
+ data_dir
+ / "scores/ligand_3d_pair_candidate_shards"
+ / f"shard={shard}.parquet",
+ data_dir / "scores/ligand_3d_by_query" / f"{shard}.parquet",
+ data_dir / "scores/search_db=holo" / f"{shard}.parquet",
+ ]:
+ path.unlink(missing_ok=True)
+ return {
+ **plan,
+ "validation": repair_report,
+ "pair_count": int(ligand_plan["pair_count"]),
+ "removed_shape_scores": removed_shape_scores,
+ "repaired_shards": sorted(active_shards.intersection(shards)),
+ }
+
+
+def repair_non_holo_scores(
+ data_dir: Path,
+ *,
+ search_db: str,
+ affected: set[str],
+ full_alignment_queries: set[str],
+ scorer_cfg: DictConfig,
+ scratch_dir: Path,
+ threads: int,
+ memory_limit: str,
+) -> dict[str, Any]:
+ """Replace protein scores for an enabled apo or predicted target database."""
+ if search_db not in {"apo", "pred"}:
+ raise ValueError(f"expected apo or pred score database, got {search_db}")
+ query_manifest = (
+ data_dir / score.LINKED_APO_QUERY_MANIFEST_RELATIVE
+ if search_db == "apo"
+ else data_dir / score.MANIFEST_RELATIVE
+ )
+ active = set(
+ pd.read_parquet(query_manifest, columns=["pdb_id"])["pdb_id"].astype(str)
+ )
+ queries = sorted(full_alignment_queries.intersection(active))
+ selected_cfg = cast(
+ DictConfig, OmegaConf.merge(scorer_cfg, {"sub_databases": [search_db]})
+ )
+ if queries:
+ tasks.make_batch_scores(
+ data_dir=data_dir,
+ pdb_ids=queries,
+ scorer_cfg=selected_cfg,
+ force_update=True,
+ scratch_dir=scratch_dir / f"{search_db}-scores",
+ threads=threads,
+ defer_ligand_3d=False,
+ )
+ _remove_inactive_queries(
+ data_dir,
+ search_db=search_db,
+ pdb_ids=affected.difference(active),
+ )
+ output = data_dir / "scores" / f"search_db={search_db}" / f"{search_db}.parquet"
+ if search_db == "apo":
+ _merge_apo_scores(
+ data_dir,
+ output=output,
+ new_queries=queries,
+ replaced_queries=set(queries) | affected.difference(active),
+ scratch_dir=scratch_dir / "apo-partition",
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ else:
+ source_dir = data_dir / "dbs" / "subdbs" / f"search_db={search_db}"
+ if any(source_dir.glob("*.parquet")):
+ tasks.collate_partitions(
+ data_dir=data_dir,
+ partition=[search_db],
+ scratch_dir=scratch_dir / f"{search_db}-partition",
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ else:
+ output.unlink(missing_ok=True)
+ return {
+ "status": "complete",
+ "query_count": len(queries),
+ "score_path": str(output),
+ }
+
+
+def _merge_apo_scores(
+ data_dir: Path,
+ *,
+ output: Path,
+ new_queries: list[str],
+ replaced_queries: set[str],
+ scratch_dir: Path,
+ threads: int,
+ memory_limit: str,
+) -> None:
+ """Replace changed apo queries in the compact release score table."""
+ if not replaced_queries:
+ return
+ source_dir = data_dir / "dbs/subdbs/search_db=apo"
+ new_paths = [
+ source_dir / f"{pdb_id}.parquet"
+ for pdb_id in new_queries
+ if (source_dir / f"{pdb_id}.parquet").is_file()
+ ]
+ if not output.is_file() and not new_paths:
+ return
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ local_output = scratch_dir / "apo.parquet"
+ local_output.unlink(missing_ok=True)
+
+ def sql_path(path: Path) -> str:
+ return path.as_posix().replace("'", "''")
+
+ selects = []
+ if output.is_file():
+ selects.append(
+ f"""
+ SELECT old.* FROM read_parquet('{sql_path(output)}',
+ hive_partitioning=false) AS old
+ ANTI JOIN replaced_entries
+ ON split_part(old.query_system, '__', 1) = replaced_entries.pdb_id
+ """
+ )
+ if new_paths:
+ paths = ", ".join(f"'{sql_path(path)}'" for path in new_paths)
+ selects.append(
+ f"SELECT scores.*, 'apo'::VARCHAR AS search_db "
+ f"FROM read_parquet([{paths}], union_by_name=true, "
+ "hive_partitioning=false) AS scores"
+ )
+ with duckdb.connect() as connection:
+ connection.execute(f"SET threads={threads}")
+ connection.execute(f"SET memory_limit='{memory_limit}'")
+ connection.execute(f"SET temp_directory='{sql_path(scratch_dir)}'")
+ connection.execute("SET preserve_insertion_order=false")
+ connection.register(
+ "replaced_entries", pd.DataFrame({"pdb_id": sorted(replaced_queries)})
+ )
+ connection.execute(
+ f"""
+ COPY (
+ SELECT
+ query_system::VARCHAR AS query_system,
+ query_ligand_id::VARCHAR AS query_ligand_id,
+ target_system::VARCHAR AS target_system,
+ target_ligand_id::VARCHAR AS target_ligand_id,
+ protein_mapping::VARCHAR AS protein_mapping,
+ mapping::VARCHAR AS mapping,
+ protein_mapper::VARCHAR AS protein_mapper,
+ source::VARCHAR AS source,
+ metric::VARCHAR AS metric,
+ similarity::TINYINT AS similarity,
+ search_db::VARCHAR AS search_db
+ FROM ({" UNION ALL BY NAME ".join(selects)})
+ ) TO '{sql_path(local_output)}' (
+ FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ output.parent.mkdir(parents=True, exist_ok=True)
+ install = output.with_suffix(".parquet.tmp")
+ copyfile(local_output, install)
+ install.replace(output)
+ local_output.unlink(missing_ok=True)
+
+
+def repair_apo_scores(
+ data_dir: Path,
+ *,
+ affected: set[str],
+ full_alignment_queries: set[str],
+ scorer_cfg: DictConfig,
+ scratch_dir: Path,
+ threads: int,
+ memory_limit: str,
+) -> dict[str, Any]:
+ """Recompute the lightweight protein scores used for linked apo chains."""
+ report = repair_non_holo_scores(
+ data_dir,
+ search_db="apo",
+ affected=affected,
+ full_alignment_queries=full_alignment_queries,
+ scorer_cfg=scorer_cfg,
+ scratch_dir=scratch_dir,
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ output = tasks.make_linked_apo_structures(
+ data_dir=data_dir,
+ scratch_dir=scratch_dir / "linked-apo",
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ return {
+ **report,
+ "linked_apo_structures": str(output),
+ "interface_apo_structures": str(
+ data_dir / RELEASE_PATHS["interface_apo_structures"]
+ ),
+ }
+
+
+def repair_interface_scores(
+ data_dir: Path,
+ *,
+ affected: set[str],
+ full_alignment_queries: set[str],
+ scratch_dir: Path,
+ threads: int,
+ memory_limit: str,
+) -> dict[str, Any]:
+ """Replace interface rows for changed searches and retain other query rows."""
+ plan = score.plan_interface_scoring(data_dir, batch_size=1)
+ work = pd.read_parquet(data_dir / score.INTERFACE_SCORE_WORK_RELATIVE)
+ replacements = affected | full_alignment_queries
+ representatives = (
+ pq.read_table(
+ data_dir / tasks.INTERFACE_REPRESENTATIVES_RELATIVE,
+ columns=["entry_pdb_id"],
+ filters=[("entry_pdb_id", "in", sorted(replacements))],
+ )
+ .column("entry_pdb_id")
+ .to_pylist()
+ )
+ planned_queries = set(
+ pd.read_parquet(data_dir / score.MANIFEST_RELATIVE, columns=["pdb_id"])[
+ "pdb_id"
+ ].astype(str)
+ )
+ alignment_report = json.loads(
+ (data_dir / "alignments" / "manifest.json").read_text()
+ )
+ skipped_queries = set(map(str, alignment_report.get("skipped_queries", {})))
+ current_queries = set(map(str, representatives)) & planned_queries - skipped_queries
+ active_replacements = replacements.intersection(current_queries)
+ repair_root = data_dir / "interface_score_repairs" / "weekly"
+ repair_paths: dict[str, Path] = {}
+ replacements_by_shard: dict[str, set[str]] = {}
+ for pdb_id in active_replacements:
+ replacements_by_shard.setdefault(pdb_id[1:3], set()).add(pdb_id)
+ for shard, entries in sorted(replacements_by_shard.items()):
+ output = repair_root / f"shard={shard}.parquet"
+ score.score_interface_qcov_shards(
+ data_dir,
+ shards=[str(shard)],
+ scratch_dir=scratch_dir / "interface-parts" / str(shard),
+ threads=threads,
+ memory_limit=memory_limit,
+ force_update=True,
+ query_entries_by_shard={str(shard): entries},
+ output_paths_by_shard={str(shard): output},
+ )
+ repair_paths[str(shard)] = output
+
+ score_root = data_dir / score.INTERFACE_SCORE_ROOT_RELATIVE
+ active_shards = set(work["shard"].astype(str))
+ for path in score_root.glob("shard=*.parquet"):
+ if path.stem.removeprefix("shard=") not in active_shards:
+ path.unlink()
+ path.with_suffix(".json").unlink(missing_ok=True)
+ reports: list[dict[str, Any]] = []
+ for shard in work["shard"].astype(str):
+ output = score_root / f"shard={shard}.parquet"
+ repair_path = repair_paths.get(shard)
+ removed = sorted(pdb_id for pdb_id in replacements if pdb_id[1:3] == shard)
+ if not removed and repair_path is None:
+ continue
+ local_root = scratch_dir / "interface-merge" / shard
+ local_root.mkdir(parents=True, exist_ok=True)
+ local_output = local_root / output.name
+ local_output.unlink(missing_ok=True)
+ connection = duckdb.connect()
+ try:
+ connection.execute(f"SET threads={threads}")
+ connection.execute(f"SET temp_directory='{local_root.as_posix()}'")
+ connection.execute(f"SET memory_limit='{memory_limit}'")
+ selects = []
+ if output.is_file():
+ if removed:
+ connection.register(
+ "replacement_queries",
+ pd.DataFrame({"entry_pdb_id": removed}),
+ )
+ selects.append(
+ f"""
+ SELECT existing.*
+ FROM read_parquet('{output.as_posix()}') AS existing
+ ANTI JOIN replacement_queries
+ ON split_part(existing.query_system, '__', 1)
+ = replacement_queries.entry_pdb_id
+ """
+ )
+ else:
+ selects.append(f"SELECT * FROM read_parquet('{output.as_posix()}')")
+ if repair_path is not None:
+ selects.append(
+ f"SELECT * FROM read_parquet('{repair_path.as_posix()}')"
+ )
+ if not selects:
+ raise FileNotFoundError(f"interface shard has no source rows: {shard}")
+ combined = " UNION ALL BY NAME ".join(selects)
+ connection.execute(
+ f"""
+ COPY (
+ SELECT
+ query_system::VARCHAR AS query_system,
+ target_system::VARCHAR AS target_system,
+ mapping::VARCHAR AS mapping,
+ source::VARCHAR AS source,
+ metric::VARCHAR AS metric,
+ iface1_qcov::FLOAT AS iface1_qcov,
+ iface2_qcov::FLOAT AS iface2_qcov,
+ similarity::TINYINT AS similarity
+ FROM ({combined})
+ ORDER BY query_system, target_system, metric
+ ) TO '{local_output.as_posix()}' (
+ FORMAT PARQUET, COMPRESSION ZSTD, ROW_GROUP_SIZE 500000
+ )
+ """
+ )
+ duplicate = connection.execute(
+ f"""
+ SELECT count(*) FROM (
+ SELECT query_system, target_system, metric
+ FROM read_parquet('{local_output.as_posix()}')
+ GROUP BY ALL HAVING count(*) > 1
+ )
+ """
+ ).fetchone()
+ finally:
+ connection.close()
+ if duplicate is None or int(duplicate[0]):
+ raise ValueError(f"interface repair produced duplicate rows: {shard}")
+ if not pq.read_schema(local_output).equals(
+ schemas.INTERFACE_SCORE_SHARD_SCHEMA
+ ):
+ raise ValueError(f"interface repair produced the wrong schema: {shard}")
+ output.parent.mkdir(parents=True, exist_ok=True)
+ install = output.with_suffix(output.suffix + ".tmp")
+ copyfile(local_output, install)
+ install.replace(output)
+ local_output.unlink(missing_ok=True)
+ payload = {
+ "status": "complete",
+ "shard": shard,
+ "inputs": score._interface_score_inputs(data_dir, shard),
+ "output": score._source_signature(output),
+ "rows": int(pq.ParquetFile(output).metadata.num_rows),
+ }
+ write_json_atomic(output.with_suffix(".json"), payload)
+ reports.append(payload)
+ export = score.finalize_interface_similarity_scores(
+ data_dir,
+ scratch_dir=scratch_dir / "interface-export",
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ return {
+ **plan,
+ "repaired_query_count": len(active_replacements),
+ "score_rows": sum(int(report["rows"]) for report in reports),
+ "export_rows": int(export["row_count"]),
+ }
+
+
+def _chemical_score_query_ids(paths: list[Path], metric: str) -> set[int]:
+ if not paths:
+ return set()
+ sources = ", ".join(f"'{path.as_posix()}'" for path in paths)
+ with duckdb.connect() as connection:
+ rows = connection.sql(
+ f"""
+ SELECT DISTINCT query_ligand_id
+ FROM read_parquet([{sources}], union_by_name=true)
+ WHERE query_ligand_id = target_ligand_id AND {metric} = 100
+ """
+ ).fetchall()
+ return {int(row[0]) for row in rows}
+
+
+def _refresh_chemical_score_shards(
+ *,
+ data_dir: Path,
+ directory: str,
+ metric: str,
+ batch_size: int,
+ number_id_col: str,
+ minimum_similarity: float,
+ scratch_dir: Path,
+ prior_ligands: pd.DataFrame,
+ prior_manifest: dict[str, str | float],
+ current_manifest: dict[str, str | float],
+) -> dict[str, int | str]:
+ """Keep old chemical edges and calculate both directions for new nodes."""
+ if batch_size < 1:
+ raise ValueError("chemical score batch size must be positive")
+ root = data_dir / directory
+ stage = data_dir / f".{directory}.pending"
+ backup = data_dir / f".{directory}.previous"
+ if backup.exists():
+ if not root.exists():
+ backup.rename(root)
+ else:
+ rmtree(backup)
+ rmtree(stage, ignore_errors=True)
+ stage.mkdir(parents=True)
+ smiles_column = "ligand_rdkit_canonical_smiles"
+ fingerprint_column = "fingerprint" if directory == "ligand_scores" else "mhfp6"
+ fingerprint_file = (
+ "ligands_per_smiles.parquet"
+ if directory == "ligand_scores"
+ else get_similarity_scores.MHFP6_FINGERPRINT_FILE
+ )
+ current_ligands = pd.read_parquet(
+ data_dir / "fingerprints" / fingerprint_file,
+ columns=[number_id_col, smiles_column, fingerprint_column],
+ )
+ for frame, label in ((prior_ligands, "prior"), (current_ligands, "current")):
+ missing = sorted(
+ {number_id_col, smiles_column, fingerprint_column}.difference(frame.columns)
+ )
+ if missing:
+ raise ValueError(f"{label} ligand fingerprints are missing {missing}")
+ if (
+ frame[number_id_col].duplicated().any()
+ or frame[smiles_column].duplicated().any()
+ ):
+ raise ValueError(f"{label} ligand fingerprint IDs are not unique")
+ active_ids = set(map(int, current_ligands[number_id_col]))
+ id_mapping = prior_ligands.merge(
+ current_ligands,
+ on=[smiles_column, fingerprint_column],
+ how="inner",
+ suffixes=("_old", "_new"),
+ validate="one_to_one",
+ ).rename(
+ columns={
+ f"{number_id_col}_old": "old_id",
+ f"{number_id_col}_new": "new_id",
+ }
+ )[["old_id", "new_id"]]
+ id_mapping = id_mapping.astype({"old_id": "int32", "new_id": "int32"})
+ prior_paths = sorted(root.glob("*.parquet"))
+ if (
+ read_json_cache(root / get_similarity_scores.LIGAND_SCORE_MANIFEST)
+ != prior_manifest
+ ):
+ prior_paths = []
+ prior_queries = _chemical_score_query_ids(prior_paths, metric)
+ complete_mapping = id_mapping.loc[id_mapping["old_id"].isin(prior_queries)]
+ mapped_queries = set(map(int, complete_mapping["new_id"]))
+ missing_queries = active_ids.difference(mapped_queries)
+ removed_ids = set(map(int, prior_ligands[number_id_col])).difference(
+ set(map(int, id_mapping["old_id"]))
+ )
+ identity_mapping = (
+ not removed_ids
+ and len(id_mapping) == len(prior_ligands)
+ and prior_queries == set(map(int, prior_ligands[number_id_col]))
+ and id_mapping["old_id"].equals(id_mapping["new_id"])
+ )
+
+ if prior_paths and identity_mapping:
+ for index, source in enumerate(prior_paths):
+ link_or_copy_file(source, stage / f"retained-{index:05d}.parquet")
+ elif prior_paths:
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ retained = scratch_dir / "retained.parquet"
+ retained.unlink(missing_ok=True)
+ sources = ", ".join(f"'{path.as_posix()}'" for path in prior_paths)
+ retained_targets = id_mapping.loc[~id_mapping["new_id"].isin(missing_queries)]
+ with duckdb.connect() as connection:
+ connection.register("query_mapping", complete_mapping)
+ connection.register("target_mapping", retained_targets)
+ connection.execute(
+ f"""
+ COPY (
+ SELECT
+ query_mapping.new_id::INTEGER AS query_ligand_id,
+ target_mapping.new_id::INTEGER AS target_ligand_id,
+ scores.{metric}::FLOAT AS {metric}
+ FROM read_parquet([{sources}], union_by_name=true) AS scores
+ INNER JOIN query_mapping
+ ON scores.query_ligand_id = query_mapping.old_id
+ INNER JOIN target_mapping
+ ON scores.target_ligand_id = target_mapping.old_id
+ ) TO '{retained.as_posix()}' (
+ FORMAT PARQUET, COMPRESSION ZSTD
+ )
+ """
+ )
+ link_or_copy_file(retained, stage / "retained.parquet")
+
+ added_paths: list[Path] = []
+ for index, start in enumerate(range(0, len(missing_queries), batch_size)):
+ ligand_ids = sorted(missing_queries)[start : start + batch_size]
+ output = stage / f"added-{index:05d}.parquet"
+ if directory == "ligand_scores":
+ get_similarity_scores.ligand_scores(
+ ligand_ids=ligand_ids,
+ data_dir=data_dir,
+ output_path=output,
+ number_id_col=number_id_col,
+ minimum_similarity=minimum_similarity,
+ )
+ else:
+ get_similarity_scores.mhfp6_ligand_scores(
+ ligand_ids=ligand_ids,
+ data_dir=data_dir,
+ output_path=output,
+ number_id_col=number_id_col,
+ minimum_similarity=minimum_similarity,
+ )
+ added_paths.append(output)
+
+ if added_paths and active_ids.difference(missing_queries):
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ reverse = scratch_dir / "reverse.parquet"
+ reverse.unlink(missing_ok=True)
+ sources = ", ".join(f"'{path.as_posix()}'" for path in added_paths)
+ new = pd.DataFrame({"ligand_id": sorted(missing_queries)})
+ with duckdb.connect() as connection:
+ connection.register("new_ligands", new)
+ connection.execute(
+ f"""
+ COPY (
+ SELECT
+ scores.target_ligand_id::INTEGER AS query_ligand_id,
+ scores.query_ligand_id::INTEGER AS target_ligand_id,
+ scores.{metric}::FLOAT AS {metric}
+ FROM read_parquet([{sources}]) AS scores
+ ANTI JOIN new_ligands
+ ON scores.target_ligand_id = new_ligands.ligand_id
+ ) TO '{reverse.as_posix()}' (
+ FORMAT PARQUET, COMPRESSION ZSTD
+ )
+ """
+ )
+ link_or_copy_file(reverse, stage / "reverse.parquet")
+
+ installed_paths = sorted(stage.glob("*.parquet"))
+ get_similarity_scores._check_self_score_coverage(
+ installed_paths,
+ metric=metric,
+ expected_query_ids=active_ids,
+ label=metric,
+ )
+ write_json_atomic(
+ stage / get_similarity_scores.LIGAND_SCORE_MANIFEST,
+ current_manifest,
+ )
+ if root.exists():
+ root.rename(backup)
+ try:
+ stage.rename(root)
+ except BaseException:
+ if backup.exists() and not root.exists():
+ backup.rename(root)
+ raise
+ rmtree(backup, ignore_errors=True)
+ return {
+ "status": "complete",
+ "active_ligands": len(active_ids),
+ "new_query_scores": len(missing_queries),
+ "removed_ligands": len(removed_ids),
+ "shards": len(installed_paths),
+ }
+
+
+def refresh_ligand_chemistry(
+ data_dir: Path,
+ *,
+ cfg: DictConfig,
+ scratch_dir: Path,
+ threads: int,
+) -> dict[str, Any]:
+ """Update unique-ligand chemistry, pair similarities, and MMP tables."""
+ fingerprint_path = data_dir / "fingerprints/ligands_per_smiles.parquet"
+ prior_ligands = pd.read_parquet(
+ fingerprint_path,
+ columns=[
+ "ligand_smiles_id",
+ "ligand_rdkit_canonical_smiles",
+ "fingerprint",
+ ],
+ )
+ number_id_col = str(cfg.ligand.number_id_col)
+ minimum_similarity = float(cfg.ligand.minimum_similarity)
+ prior_tanimoto_manifest = get_similarity_scores.ligand_score_manifest_payload(
+ fingerprint_path=fingerprint_path,
+ fingerprint_col="fingerprint",
+ metric="tanimoto_similarity_ecfp4_1024",
+ minimum_similarity=minimum_similarity,
+ number_id_col=number_id_col,
+ )
+ use_mhfp6 = get_similarity_scores.MHFP6_METRIC in cfg.flow.cluster_metrics
+ if use_mhfp6:
+ prior_mhfp6_ligands = pd.read_parquet(
+ data_dir / "fingerprints" / get_similarity_scores.MHFP6_FINGERPRINT_FILE,
+ columns=[
+ "ligand_smiles_id",
+ "ligand_rdkit_canonical_smiles",
+ "mhfp6",
+ ],
+ )
+ prior_mhfp6_manifest = get_similarity_scores.ligand_score_manifest_payload(
+ fingerprint_path=(
+ data_dir / "fingerprints" / get_similarity_scores.MHFP6_FINGERPRINT_FILE
+ ),
+ fingerprint_col="mhfp6",
+ metric=get_similarity_scores.MHFP6_METRIC,
+ minimum_similarity=minimum_similarity,
+ number_id_col=number_id_col,
+ )
+ tasks.compute_ligand_fingerprints(
+ data_dir=data_dir,
+ cofactor_similarity_threshold=float(cfg.ligand.cofactor_similarity_threshold),
+ retain_score_shards=True,
+ )
+ ligand_scores = _refresh_chemical_score_shards(
+ data_dir=data_dir,
+ directory="ligand_scores",
+ metric="tanimoto_similarity_ecfp4_1024",
+ batch_size=int(cfg.flow.make_ligands_batch_size),
+ number_id_col=number_id_col,
+ minimum_similarity=minimum_similarity,
+ scratch_dir=scratch_dir / "tanimoto",
+ prior_ligands=prior_ligands,
+ prior_manifest=prior_tanimoto_manifest,
+ current_manifest=get_similarity_scores.ligand_score_manifest_payload(
+ fingerprint_path=fingerprint_path,
+ fingerprint_col="fingerprint",
+ metric="tanimoto_similarity_ecfp4_1024",
+ minimum_similarity=minimum_similarity,
+ number_id_col=number_id_col,
+ ),
+ )
+ mhfp6_scores = None
+ if use_mhfp6:
+ mhfp6_scores = _refresh_chemical_score_shards(
+ data_dir=data_dir,
+ directory=get_similarity_scores.MHFP6_SCORES_DIR,
+ metric=get_similarity_scores.MHFP6_METRIC,
+ batch_size=int(cfg.flow.make_ligands_batch_size),
+ number_id_col=number_id_col,
+ minimum_similarity=minimum_similarity,
+ scratch_dir=scratch_dir / "mhfp6",
+ prior_ligands=prior_mhfp6_ligands,
+ prior_manifest=prior_mhfp6_manifest,
+ current_manifest=get_similarity_scores.ligand_score_manifest_payload(
+ fingerprint_path=(
+ data_dir
+ / "fingerprints"
+ / get_similarity_scores.MHFP6_FINGERPRINT_FILE
+ ),
+ fingerprint_col="mhfp6",
+ metric=get_similarity_scores.MHFP6_METRIC,
+ minimum_similarity=minimum_similarity,
+ number_id_col=number_id_col,
+ ),
+ )
+ tasks.annotate_ligand_similarity(
+ data_dir=data_dir,
+ minimum_similarity=minimum_similarity,
+ number_id_col=number_id_col,
+ )
+ mmp = tasks.make_ligand_mmp_pairs(
+ data_dir=data_dir,
+ scratch_dir=scratch_dir / "mmp",
+ threads=threads,
+ )
+ ccd = None
+ if "make_ccd_ligand_dbs" not in cfg.flow.skip_specific_stages:
+ ccd_manifest = (
+ read_json_cache(
+ ccd_ligand_dbs.ccd_dbs_dir(data_dir) / "ccd_dbs.manifest.json"
+ )
+ or {}
+ )
+ ccd = tasks.make_ccd_ligand_dbs(
+ data_dir=data_dir,
+ scratch_dir=scratch_dir / "ccd",
+ threads=threads,
+ minimum_similarity=float(cfg.ligand.minimum_similarity),
+ build_parity_scores=bool(ccd_manifest.get("build_parity_scores"))
+ or ccd_ligand_dbs.ccd_parity_path(data_dir).is_file(),
+ )
+ return {
+ "status": "complete",
+ "tanimoto": ligand_scores,
+ "mhfp6": mhfp6_scores,
+ "mmp": str(mmp),
+ "ccd_matches": str(ccd) if ccd is not None else None,
+ }
+
+
+def _ligand_chemistry_unchanged(base: Path, data_dir: Path, affected: set[str]) -> bool:
+ """Check whether changed entries retain the same proper ligands and SMILES."""
+ columns = [
+ "entry_pdb_id",
+ "ligand_id",
+ "ligand_smiles",
+ "ligand_is_proper",
+ "system_type",
+ ]
+
+ def ligands(path: Path) -> set[tuple[str, str, str]]:
+ rows = pd.read_parquet(
+ path,
+ columns=columns,
+ filters=[("entry_pdb_id", "in", sorted(affected))],
+ )
+ rows = rows[
+ rows["ligand_is_proper"].fillna(False) & rows["system_type"].eq("holo")
+ ]
+ return set(
+ zip(
+ rows["entry_pdb_id"].astype(str),
+ rows["ligand_id"].astype(str),
+ rows["ligand_smiles"].astype(str),
+ strict=True,
+ )
+ )
+
+ return ligands(base / RELEASE_PATHS["annotation_table"]) == ligands(
+ data_dir / RELEASE_PATHS["annotation_table"]
+ )
+
+
+def refresh_ligand_score_export(
+ data_dir: Path,
+ *,
+ scratch_dir: Path,
+ threads: int,
+ memory_limit: str,
+) -> dict[str, Any]:
+ """Update the compact public ligand-pair score table."""
+ shards = sorted(
+ {pdb_id[1:3] for pdb_id in score.published_scoring_query_ids(data_dir)}
+ )
+ shard_dir = data_dir / "exports" / "ligand_similarity_scores"
+ active_shards = set(shards)
+ for path in shard_dir.glob("*.parquet"):
+ if path.stem not in active_shards:
+ path.unlink()
+ path.with_suffix(".json").unlink(missing_ok=True)
+ score.export_ligand_similarity_scores_batch(
+ data_dir,
+ output_dir=shard_dir,
+ shards=shards,
+ scratch_dir=scratch_dir / "ligand-score-shards",
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ return score.finalize_ligand_similarity_scores(
+ data_dir,
+ source_dir=shard_dir,
+ output=data_dir / RELEASE_PATHS["ligand_similarity_scores"],
+ scratch_dir=scratch_dir / "ligand-score-export",
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+
+
+def _isolated_ligand_score_export(
+ data_dir: Path, *, scratch_dir: Path, threads: int, memory_limit: str
+) -> dict[str, Any]:
+ """Release the large export's memory before continuing the update."""
+ with ProcessPoolExecutor(max_workers=1, mp_context=get_context("spawn")) as pool:
+ return pool.submit(
+ refresh_ligand_score_export,
+ data_dir,
+ scratch_dir=scratch_dir,
+ threads=threads,
+ memory_limit=memory_limit,
+ ).result()
+
+
+def rebuild_similarity_covers(
+ data_dir: Path,
+ *,
+ cfg: DictConfig,
+ scratch_dir: Path,
+ threads: int,
+) -> dict[str, Any]:
+ """Recompute release-wide ligand and interface representative covers."""
+ reports: dict[str, Any] = {}
+ entities: list[tuple[clusters.ClusterEntity, list[str]]] = [
+ ("ligand", list(cfg.flow.cluster_metrics)),
+ ("interface", list(clusters.INTERFACE_CLUSTER_METRICS)),
+ ]
+ thresholds = list(map(int, cfg.flow.cluster_thresholds))
+ for entity_type, metrics in entities:
+ plan = score.plan_clustering(
+ data_dir,
+ metrics=metrics,
+ thresholds=thresholds,
+ source_batch_size=int(cfg.flow.symmetric_edge_source_batch_size),
+ cover_batch_size=1,
+ symmetric_bucket_count=int(cfg.flow.symmetric_edge_bucket_count),
+ entity_type=entity_type,
+ )
+ symmetric = clusters.load_symmetric_edge_plan(data_dir, entity_type=entity_type)
+ for batch in symmetric["batches"]:
+ tasks.make_symmetric_edge_fragments(
+ data_dir=data_dir,
+ batches=[batch],
+ scratch_dir=scratch_dir / entity_type / "edge-fragments",
+ threads=threads,
+ force_update=True,
+ entity_type=entity_type,
+ )
+ for metric in metrics:
+ for bucket in range(int(symmetric["bucket_count"])):
+ tasks.make_symmetric_edge_shards(
+ data_dir=data_dir,
+ metric_buckets=[(metric, bucket)],
+ scratch_dir=scratch_dir / entity_type / "edge-shards",
+ threads=threads,
+ force_update=True,
+ entity_type=entity_type,
+ )
+ for sources in tasks.scatter_component_reduction_sources(
+ data_dir=data_dir,
+ metrics=metrics,
+ batch_size=int(cfg.flow.component_reduction_source_batch_size),
+ entity_type=entity_type,
+ ):
+ tasks.make_component_reductions(
+ data_dir=data_dir,
+ source_paths=sources,
+ metrics=metrics,
+ thresholds=thresholds,
+ scratch_dir=scratch_dir / entity_type / "components",
+ force_update=True,
+ metric_workers=min(
+ threads, int(cfg.flow.component_reduction_metric_workers)
+ ),
+ entity_type=entity_type,
+ )
+ tasks.merge_component_reductions(
+ data_dir=data_dir,
+ metrics=metrics,
+ thresholds=thresholds,
+ entity_type=entity_type,
+ )
+ for work in tasks.scatter_make_set_covers(
+ data_dir=data_dir,
+ metrics=metrics,
+ thresholds=thresholds,
+ stop_on_cluster=0,
+ skip_existing_clusters=False,
+ entity_type=entity_type,
+ ):
+ tasks.make_set_covers(
+ data_dir=data_dir,
+ metric_threshold=work,
+ skip_existing_clusters=False,
+ scratch_dir=scratch_dir / entity_type / "set-covers",
+ threads=threads,
+ entity_type=entity_type,
+ )
+ for work in tasks.scatter_make_directed_set_covers(
+ data_dir=data_dir,
+ metrics=metrics,
+ thresholds=thresholds,
+ stop_on_cluster=0,
+ skip_existing=False,
+ entity_type=entity_type,
+ ):
+ tasks.make_directed_set_covers(
+ data_dir=data_dir,
+ metric_threshold=work,
+ skip_existing=False,
+ scratch_dir=scratch_dir / entity_type / "directed-covers",
+ threads=threads,
+ entity_type=entity_type,
+ )
+ reports[entity_type] = {
+ **plan,
+ "summary": score.summarize_clustering_artifacts(
+ data_dir,
+ metrics=metrics,
+ thresholds=thresholds,
+ entity_type=entity_type,
+ ),
+ }
+ return {"status": "complete", **reports}
+
+
+def _load_configuration(path: Path) -> DictConfig:
+ return config.get_config(config=OmegaConf.load(path), config_args=[], cached=False)
+
+
+def _weekly_inputs(
+ plan_dir: Path, config_path: Path, validation_root: Path
+) -> dict[str, Any]:
+ return {
+ "plan": file_sha256(plan_dir / "plan.json"),
+ "entries": file_sha256(plan_dir / "entries.parquet"),
+ "config": file_sha256(config_path),
+ "validation_root": str(validation_root.resolve(strict=True)),
+ }
+
+
+def _read_weekly_report(path: Path, *, inputs: dict[str, Any]) -> dict[str, Any] | None:
+ if not path.is_file():
+ return None
+ report: dict[str, Any] = json.loads(path.read_text())
+ if report.get("inputs") != inputs:
+ raise ValueError("weekly update inputs changed; use a new workspace")
+ stages = report.get("completed_stages")
+ if not isinstance(stages, list) or stages != list(_STAGES[: len(stages)]):
+ raise ValueError(f"invalid weekly update stage report: {path}")
+ return report
+
+
+def _finish_stage(
+ path: Path,
+ report: dict[str, Any],
+ stage: str,
+ details: dict[str, Any],
+) -> None:
+ stages = cast(list[str], report["completed_stages"])
+ expected = _STAGES[len(stages)]
+ if stage != expected:
+ raise RuntimeError(f"expected weekly stage {expected}, got {stage}")
+ report[stage] = details
+ stages.append(stage)
+ report["status"] = "complete" if stage == _STAGES[-1] else "running"
+ write_json_atomic(path, report)
+
+
+def _rebase_reused_scoring_artifacts(data_dir: Path, report: dict[str, Any]) -> None:
+ """Keep unchanged scoring artifacts valid after entry tables are rewritten."""
+ if not report.get("search_inputs", {}).get("reused_base"):
+ return
+ lookup = data_dir / tasks.ALIGNMENT_CHAIN_LOOKUP_RELATIVE
+ manifest = read_json_cache(
+ data_dir / tasks.ALIGNMENT_CHAIN_LOOKUP_MANIFEST_RELATIVE
+ )
+ if manifest is None or manifest.get("output") != (
+ tasks._interface_representative_output_signature(lookup)
+ ):
+ raise ValueError("reused alignment lookup changed during the weekly update")
+ tasks._refresh_representative_source_manifests(data_dir)
+ tasks._write_alignment_chain_lookup_manifest(data_dir)
+
+
+def apply_release_update(
+ plan_dir: Path,
+ workspace: Path,
+ *,
+ validation_root: Path,
+ config_path: Path,
+ scratch_dir: Path,
+ threads: int = 8,
+ memory_limit: str = "32GB",
+ search_batch_size: int = 5_000,
+) -> dict[str, Any]:
+ """Apply one planned PDB update and finish every derived release table."""
+ if min(threads, search_batch_size) < 1:
+ raise ValueError("threads and search batch size must be positive")
+ plan_dir = plan_dir.resolve(strict=True)
+ config_path = config_path.resolve(strict=True)
+ validation_root = validation_root.resolve(strict=True)
+ scratch_dir = scratch_dir.resolve()
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ inputs = _weekly_inputs(plan_dir, config_path, validation_root)
+ state_path = workspace.resolve() / "weekly_update.json"
+ report = _read_weekly_report(state_path, inputs=inputs)
+ if report is not None and report["status"] in {"complete", "finalizing"}:
+ if report.get("search_inputs", {}).get("reused_base"):
+ planned = json.loads((plan_dir / "plan.json").read_text())
+ _refresh_foldseek_source_manifest(
+ workspace,
+ nextgen_root=Path(planned["nextgen_root"]),
+ affected=set(report["affected_pdb_ids"]),
+ )
+ marker_path = workspace / "index" / "collation.json"
+ marker = json.loads(marker_path.read_text())
+ if marker.get("status") != "complete":
+ if report["status"] == "complete":
+ raise ValueError("completed weekly update has an incomplete index")
+ else:
+ _rebase_reused_scoring_artifacts(workspace, report)
+ if report["status"] == "finalizing":
+ _finish_stage(
+ state_path,
+ report,
+ "final_tables",
+ {"collation": str(marker_path)},
+ )
+ return report
+
+ cfg = _load_configuration(config_path)
+ search_databases = list(dict.fromkeys(map(str, cfg.scorer.sub_databases)))
+ alignment_databases = list(search_databases)
+ if "apo" in alignment_databases:
+ alignment_databases.insert(
+ alignment_databases.index("apo") + 1, "interface_apo"
+ )
+ pdb_search_databases = [
+ search_db for search_db in search_databases if search_db in {"holo", "apo"}
+ ]
+ plan, entries = load_update_plan(plan_dir)
+ base = Path(plan["data_dir"]).resolve(strict=True)
+ affected = set(
+ entries.loc[
+ entries.action.isin(["added", "revised", "obsolete"]), "pdb_id"
+ ].astype(str)
+ )
+ if affected and (base / "exports/monomer_similarity_scores").exists():
+ raise NotImplementedError(
+ "weekly updates of releases with monomer similarity pairs require "
+ "a monomer delta-refresh stage"
+ )
+ if report is None:
+ entry_report = apply_entry_update(
+ plan_dir,
+ workspace,
+ validation_root=validation_root,
+ annotation_cfg=dict(cfg.annotation),
+ entry_cfg=dict(cfg.entry),
+ interface_cfg=dict(cfg.interface),
+ threads=threads,
+ memory_limit=memory_limit,
+ scratch_dir=scratch_dir / "entries",
+ )
+ archive_report = update_ligand_archives(
+ workspace, threads=threads, memory_limit=memory_limit
+ )
+ workspace = workspace.resolve(strict=True)
+ _reuse_base_artifacts(base, workspace)
+ report = {
+ "status": "running",
+ "inputs": inputs,
+ "base_release": str(base),
+ "affected_pdb_ids": sorted(affected),
+ "completed_stages": [],
+ }
+ _finish_stage(
+ state_path,
+ report,
+ "entries_and_archives",
+ {"entries": entry_report, "ligand_archives": archive_report},
+ )
+ else:
+ workspace = workspace.resolve(strict=True)
+
+ _refresh_foldseek_source_manifest(
+ workspace,
+ nextgen_root=Path(plan["nextgen_root"]),
+ affected=affected,
+ )
+ unchanged_scoring = _unchanged_scoring_entries(base, workspace, affected)
+ scoring_affected = affected - unchanged_scoring
+ report["unchanged_scoring_entries"] = sorted(unchanged_scoring)
+ if not scoring_affected:
+ report.setdefault(
+ "alignment_repair_queries",
+ {search_db: [] for search_db in alignment_databases},
+ )
+ write_json_atomic(state_path, report)
+ if not scoring_affected and set(report["completed_stages"]) == {
+ "entries_and_archives"
+ }:
+ _finish_stage(state_path, report, "search_inputs", {"reused_base": True})
+ _finish_stage(
+ state_path,
+ report,
+ "alignments",
+ {"full_queries": {search_db: [] for search_db in alignment_databases}},
+ )
+ _finish_stage(state_path, report, "scores", {"reused_base": True})
+ _finish_stage(state_path, report, "ligand_chemistry", {"reused_base": True})
+ _finish_stage(
+ state_path,
+ report,
+ "cluster_assignments",
+ {
+ "ligand": str(workspace / "index/ligand_clusters.parquet"),
+ "interface": str(workspace / "index/interface_clusters.parquet"),
+ },
+ )
+
+ completed = set(report["completed_stages"])
+ if "search_inputs" not in completed:
+ lookup = tasks.make_alignment_chain_lookup(
+ data_dir=workspace,
+ scratch_dir=scratch_dir / "scoring-inputs",
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ protein_plan = score.plan_protein_scoring(
+ workspace, max_seqs=int(cfg.foldseek.max_seqs)
+ )
+ if pdb_search_databases:
+ score.make_foldseek_input_manifest(
+ workspace, Path(plan["nextgen_root"]) / "data/entries/divided"
+ )
+ score.make_mmseqs_input_fasta(workspace)
+ shadowed = _prepare_weekly_search_overlay(
+ base=base,
+ data_dir=workspace,
+ affected=scoring_affected,
+ nextgen_root=Path(plan["nextgen_root"]),
+ search_databases=[db for db in alignment_databases if db != "pred"],
+ scratch_dir=scratch_dir / "weekly-search-overlay",
+ threads=threads,
+ )
+ sequence_clusters = extend_protein_clusters(
+ base=base,
+ data_dir=workspace,
+ affected=scoring_affected,
+ backend="mmseqs",
+ scratch_dir=scratch_dir / "protein-sequence-clusters",
+ threads=threads,
+ threshold=float(cfg.flow.protein_sequence_cluster_identity),
+ coverage=float(cfg.flow.protein_cluster_coverage),
+ )
+ structure_clusters = extend_protein_clusters(
+ base=base,
+ data_dir=workspace,
+ affected=scoring_affected,
+ backend="foldseek",
+ scratch_dir=scratch_dir / "protein-structure-clusters",
+ threads=threads,
+ threshold=float(cfg.flow.protein_structure_cluster_lddt),
+ coverage=float(cfg.flow.protein_cluster_coverage),
+ )
+ search_details: dict[str, Any] = {
+ "alignment_chain_lookup": str(lookup),
+ "protein_plan": protein_plan,
+ "protein_sequence_clusters": str(sequence_clusters),
+ "protein_structure_clusters": str(structure_clusters),
+ "search_databases": search_databases,
+ "shadowed_entries": len(shadowed),
+ }
+ if "apo" in search_databases:
+ search_details["apo_plan"] = score.plan_linked_apo_scoring(
+ workspace, max_seqs=int(cfg.foldseek.max_seqs)
+ )
+ _finish_stage(
+ state_path,
+ report,
+ "search_inputs",
+ search_details,
+ )
+
+ completed = set(report["completed_stages"])
+ if "alignments" not in completed:
+ planned_queries = _load_or_plan_alignment_repairs(
+ workspace,
+ search_databases=alignment_databases,
+ affected=scoring_affected,
+ scorer_cfg=cfg.scorer,
+ foldseek_cfg=cfg.foldseek,
+ mmseqs_cfg=cfg.mmseqs,
+ scratch_dir=scratch_dir / "alignment-planning",
+ threads=threads,
+ batch_size=search_batch_size,
+ state_path=state_path,
+ report=report,
+ )
+ full_queries = {
+ search_db: sorted(
+ repair_alignments(
+ workspace,
+ search_db=search_db,
+ affected=scoring_affected,
+ full_queries=planned_queries[search_db] & scoring_affected,
+ targeted_queries=planned_queries[search_db] - scoring_affected,
+ scorer_cfg=cfg.scorer,
+ foldseek_cfg=cfg.foldseek,
+ mmseqs_cfg=cfg.mmseqs,
+ scratch_dir=scratch_dir / "alignment-repair" / search_db,
+ threads=threads,
+ batch_size=search_batch_size,
+ )
+ )
+ for search_db in alignment_databases
+ }
+ alignment_details: dict[str, Any] = {"full_queries": full_queries}
+ if "holo" in search_databases:
+ alignment_details["holo"] = score.finalize_alignment_artifacts(workspace)
+ _finish_stage(
+ state_path,
+ report,
+ "alignments",
+ alignment_details,
+ )
+ full_query_sets = {
+ name: set(map(str, values))
+ for name, values in report["alignments"]["full_queries"].items()
+ }
+ holo_repair_queries = set(
+ map(str, report["alignment_repair_queries"].get("holo", []))
+ )
+
+ completed = set(report["completed_stages"])
+ if "scores" not in completed:
+ score_details: dict[str, Any] = {}
+ if "holo" in search_databases:
+ score_details["ligand"] = repair_holo_scores(
+ workspace,
+ base_data_dir=base,
+ affected=scoring_affected,
+ full_alignment_queries=full_query_sets["holo"],
+ targeted_alignment_queries=holo_repair_queries.difference(
+ scoring_affected
+ ),
+ scorer_cfg=cfg.scorer,
+ scratch_dir=scratch_dir / "holo-score-repair",
+ threads=threads,
+ memory_limit=memory_limit,
+ score_batch_size=int(cfg.flow.make_batch_scores_batch_size),
+ ligand_batch_size=int(cfg.flow.make_ligand_3d_scores_batch_size),
+ )
+ score_details["interface"] = (
+ repair_interface_scores(
+ workspace,
+ affected=scoring_affected,
+ full_alignment_queries=holo_repair_queries,
+ scratch_dir=scratch_dir / "interface-score-repair",
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ if _entries_with_interfaces(
+ base, workspace, scoring_affected | holo_repair_queries
+ )
+ else {"reused_base": True}
+ )
+ if "apo" in search_databases:
+ score_details["apo"] = repair_apo_scores(
+ workspace,
+ affected=scoring_affected,
+ full_alignment_queries=set(
+ map(str, report["alignment_repair_queries"]["apo"])
+ ),
+ scorer_cfg=cfg.scorer,
+ scratch_dir=scratch_dir / "apo-score-repair",
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ if "pred" in search_databases:
+ score_details["pred"] = repair_non_holo_scores(
+ workspace,
+ search_db="pred",
+ affected=scoring_affected,
+ full_alignment_queries=full_query_sets["pred"],
+ scorer_cfg=cfg.scorer,
+ scratch_dir=scratch_dir / "pred-score-repair",
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ if "holo" in search_databases:
+ score_details["ligand_export"] = _isolated_ligand_score_export(
+ workspace,
+ scratch_dir=scratch_dir / "ligand-score-export",
+ threads=threads,
+ memory_limit=memory_limit,
+ )
+ _finish_stage(
+ state_path,
+ report,
+ "scores",
+ score_details,
+ )
+
+ completed = set(report["completed_stages"])
+ if "ligand_chemistry" not in completed:
+ if _ligand_chemistry_unchanged(base, workspace, scoring_affected):
+ chemistry = {"reused_base": True}
+ else:
+ chemistry = refresh_ligand_chemistry(
+ workspace,
+ cfg=cfg,
+ scratch_dir=scratch_dir / "ligand-chemistry",
+ threads=threads,
+ )
+ _finish_stage(state_path, report, "ligand_chemistry", chemistry)
+ if report["ligand_chemistry"].get("reused_base"):
+ for name in (
+ "ligands_per_smiles.parquet",
+ get_similarity_scores.MHFP6_FINGERPRINT_FILE,
+ "ligand_similarity_annotations.parquet",
+ ):
+ source = base / "fingerprints" / name
+ destination = workspace / "fingerprints" / name
+ if source.is_file() and not destination.is_file():
+ link_or_copy_file(source, destination)
+
+ completed = set(report["completed_stages"])
+ if "cluster_assignments" not in completed:
+ staged = workspace / "index/.staging/weekly_clusters"
+ staged.mkdir(parents=True, exist_ok=True)
+ ligand_path = staged / "ligand.parquet"
+ interface_path = staged / "interface.parquet"
+ extend_ligand_clusters(
+ base=base, data_dir=workspace, affected=scoring_affected
+ ).to_parquet(ligand_path, index=False)
+ if (workspace / "index/interface_annotation_table.parquet").is_file():
+ extend_interface_clusters(
+ base=base, data_dir=workspace, affected=scoring_affected
+ ).to_parquet(interface_path, index=False)
+ _finish_stage(
+ state_path,
+ report,
+ "cluster_assignments",
+ {"ligand": str(ligand_path), "interface": str(interface_path)},
+ )
+
+ if "final_tables" not in set(report["completed_stages"]):
+ report["status"] = "finalizing"
+ write_json_atomic(state_path, report)
+ staged = report["cluster_assignments"]
+ interface_path = Path(staged["interface"])
+ has_interfaces = (
+ workspace / "index/interface_annotation_table.parquet"
+ ).is_file()
+ if has_interfaces and not interface_path.is_file():
+ raise FileNotFoundError(interface_path)
+ tasks.finalize_index(
+ data_dir=workspace,
+ weekly_ligand_clusters=Path(staged["ligand"]),
+ weekly_interface_clusters=interface_path if has_interfaces else None,
+ )
+ _rebase_reused_scoring_artifacts(workspace, report)
+ marker_path = workspace / "index" / "collation.json"
+ marker = json.loads(marker_path.read_text())
+ if marker.get("status") != "complete":
+ raise ValueError("final table assembly did not complete the update marker")
+ _finish_stage(
+ state_path,
+ report,
+ "final_tables",
+ {"collation": str(marker_path)},
+ )
+ return report
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument("plan_dir", type=Path)
+ parser.add_argument("workspace", type=Path)
+ parser.add_argument("--validation-root", type=Path, required=True)
+ parser.add_argument("--config", type=Path, required=True)
+ parser.add_argument("--scratch-dir", type=Path, required=True)
+ parser.add_argument("--threads", type=int, default=8)
+ parser.add_argument("--memory-limit", default="32GB")
+ parser.add_argument("--search-batch-size", type=int, default=5_000)
+ args = parser.parse_args()
+ report = apply_release_update(
+ args.plan_dir,
+ args.workspace,
+ validation_root=args.validation_root,
+ config_path=args.config,
+ scratch_dir=args.scratch_dir,
+ threads=args.threads,
+ memory_limit=args.memory_limit,
+ search_batch_size=args.search_batch_size,
+ )
+ print(json.dumps(report, indent=2, sort_keys=True))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/plinder/data/pipeline/updates.py b/src/plinder/data/pipeline/updates.py
new file mode 100644
index 000000000..9982b0a1f
--- /dev/null
+++ b/src/plinder/data/pipeline/updates.py
@@ -0,0 +1,384 @@
+# Copyright (c) 2026, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Plan entry updates from a local NextGen snapshot and PDB obsolete.dat."""
+
+from __future__ import annotations
+
+import argparse
+import gzip
+import json
+from collections import Counter
+from concurrent.futures import ThreadPoolExecutor
+from pathlib import Path
+from typing import Any, Collection
+
+import pandas as pd
+
+from plinder.core.utils.files import file_sha256
+from plinder.data.pipeline.ingest import load_manifest, normalize_pdb_id
+
+REVISION_COLUMNS = ["source_mmcif_major_revision", "source_mmcif_minor_revision"]
+SNAPSHOT_COLUMNS = ["entry_pdb_id", "last_modified", *REVISION_COLUMNS, "error"]
+
+
+def read_obsolete(path: Path) -> dict[str, list[str]]:
+ """Read obsolete IDs and all their successors; successors are not aliases."""
+ replacements: dict[str, set[str]] = {}
+ for number, line in enumerate(path.read_text().splitlines(), 1):
+ fields = line.split()
+ if not fields or fields[0] != "OBSLTE":
+ continue
+ if len(fields) < 3:
+ raise ValueError(f"incomplete OBSLTE record at {path}:{number}")
+ pdb_id = normalize_pdb_id(fields[2])
+ replacements.setdefault(pdb_id, set()).update(
+ normalize_pdb_id(value) for value in fields[3:]
+ )
+ return {key: sorted(values) for key, values in sorted(replacements.items())}
+
+
+def _holdings(path: Path) -> dict[str, Any]:
+ with gzip.open(path, "rt") as handle:
+ contents = json.load(handle)
+ return {
+ normalize_pdb_id(key.removeprefix("pdb_0000")): value
+ for key, value in contents.items()
+ }
+
+
+def _read_revision(path: Path) -> tuple[int, int]:
+ from plinder.data.annotations.cif_utils import (
+ get_mmcif_revision,
+ read_mmcif_container,
+ )
+
+ return get_mmcif_revision(read_mmcif_container(path))
+
+
+def read_snapshot(
+ nextgen_root: Path,
+ *,
+ threads: int = 8,
+ previous_snapshot: Path | None = None,
+ pdb_ids: Collection[str] | None = None,
+) -> pd.DataFrame:
+ """Read revisions, reusing a prior inventory for unchanged holdings timestamps.
+
+ ``nextgen_root`` contains ``holdings/`` and ``data/entries/divided/``.
+ The first comparison reads the CIFs to establish their revisions. A saved
+ inventory is only a read cache: it never proves an update was applied.
+ """
+ if threads < 1:
+ raise ValueError("threads must be positive")
+ root = nextgen_root.resolve(strict=True)
+ files = _holdings(root / "holdings/current_file_holdings.json.gz")
+ modified = _holdings(
+ root / "holdings/released_structures_last_modified_dates.json.gz"
+ )
+ selected = (
+ {normalize_pdb_id(value) for value in pdb_ids} if pdb_ids is not None else None
+ )
+ current = sorted(
+ key
+ for key, value in files.items()
+ if value.get("mmcif") and (selected is None or key in selected)
+ )
+ cached = {}
+ if previous_snapshot is not None:
+ cache = pd.read_parquet(previous_snapshot, columns=SNAPSHOT_COLUMNS)
+ cached = cache.set_index("entry_pdb_id", verify_integrity=True).to_dict(
+ orient="index"
+ )
+
+ def read(pdb_id: str) -> dict[str, Any]:
+ timestamp = modified.get(pdb_id)
+ previous = cached.get(pdb_id)
+ if (
+ previous is not None
+ and timestamp is not None
+ and previous["last_modified"] == timestamp
+ and pd.isna(previous["error"])
+ and all(pd.notna(previous[column]) for column in REVISION_COLUMNS)
+ ):
+ return {"entry_pdb_id": pdb_id, **previous}
+ row: dict[str, Any] = dict.fromkeys(SNAPSHOT_COLUMNS)
+ row.update(entry_pdb_id=pdb_id, last_modified=timestamp)
+ path = (
+ root
+ / "data/entries/divided"
+ / pdb_id[1:3]
+ / f"pdb_0000{pdb_id}"
+ / f"pdb_0000{pdb_id}_xyz-enrich.cif.gz"
+ )
+ try:
+ major, minor = _read_revision(path)
+ row.update(zip(REVISION_COLUMNS, (major, minor)))
+ except Exception as exc:
+ row["error"] = f"{type(exc).__name__}: {exc}"
+ return row
+
+ with ThreadPoolExecutor(max_workers=threads) as executor:
+ rows = list(executor.map(read, current))
+ return pd.DataFrame(rows, columns=SNAPSHOT_COLUMNS).astype(
+ {column: "Int64" for column in REVISION_COLUMNS}
+ )
+
+
+def compare_entries(
+ sources: pd.DataFrame,
+ snapshot: pd.DataFrame,
+ obsolete: dict[str, list[str]],
+) -> pd.DataFrame:
+ """Classify each entry without treating unexplained absences as removals."""
+ old = sources.set_index("entry_pdb_id", verify_integrity=True)[
+ REVISION_COLUMNS
+ ].T.to_dict("list")
+ new = snapshot.set_index("entry_pdb_id", verify_integrity=True).to_dict("index")
+ rows = []
+ for pdb_id in sorted(old.keys() | new.keys()):
+ before = old.get(pdb_id)
+ current = new.get(pdb_id)
+ after = [current[column] for column in REVISION_COLUMNS] if current else None
+ error = current["error"] if current else None
+ reason = ""
+ if pdb_id in obsolete and after is not None:
+ action, reason = "blocked", "entry is both current and obsolete"
+ elif pdb_id in obsolete:
+ action = "obsolete"
+ elif after is None:
+ action, reason = "blocked", "absent from holdings but not in obsolete.dat"
+ elif pd.notna(error):
+ action, reason = "blocked", str(error)
+ elif any(pd.isna(value) for value in (*(before or ()), *after)):
+ action, reason = "blocked", "missing source revision"
+ elif before is None:
+ action = "added"
+ elif after < before:
+ action, reason = "blocked", "snapshot revision is older than the release"
+ elif after > before:
+ action = "revised"
+ else:
+ action = "unchanged"
+ rows.append(
+ {
+ "pdb_id": pdb_id,
+ "action": action,
+ "reason": reason,
+ "previous_major_revision": before[0] if before else None,
+ "previous_minor_revision": before[1] if before else None,
+ "current_major_revision": after[0] if after else None,
+ "current_minor_revision": after[1] if after else None,
+ "replacement_pdb_ids": obsolete.get(pdb_id, []),
+ }
+ )
+ columns = [
+ "pdb_id",
+ "action",
+ "reason",
+ "previous_major_revision",
+ "previous_minor_revision",
+ "current_major_revision",
+ "current_minor_revision",
+ "replacement_pdb_ids",
+ ]
+ return pd.DataFrame(rows, columns=columns).astype(
+ {column: "Int64" for column in columns if column.endswith("_revision")}
+ )
+
+
+def _signature(path: Path) -> dict[str, str]:
+ return {
+ "path": str(path.resolve()),
+ "sha256": file_sha256(path),
+ }
+
+
+def load_update_plan(plan_dir: Path) -> tuple[dict[str, Any], pd.DataFrame]:
+ """Read a ready plan and verify that its sources and reports still match."""
+ plan = json.loads((plan_dir / "plan.json").read_text())
+ if plan["status"] != "ready":
+ raise ValueError("entry updates require a ready plan with changes")
+ for source in plan["inputs"].values():
+ if _signature(Path(source["path"])) != source:
+ raise ValueError(f"update source changed after planning: {source['path']}")
+ for name in ("entries.parquet", "snapshot.parquet"):
+ if plan.get("reports", {}).get(name) != _signature(plan_dir / name)["sha256"]:
+ raise ValueError(
+ f"update report changed or lacks a signature; regenerate the plan: {name}"
+ )
+ return plan, pd.read_parquet(plan_dir / "entries.parquet")
+
+
+def plan_update(
+ data_dir: Path,
+ *,
+ nextgen_root: Path,
+ obsolete_path: Path,
+ output_dir: Path,
+ threads: int = 8,
+ previous_snapshot: Path | None = None,
+ pdb_ids: Collection[str] | None = None,
+ refresh_pdb_ids: Collection[str] | None = None,
+) -> dict[str, Any]:
+ """Write an update report and work lists into a new, separate directory.
+
+ Nothing is applied to the release. Blocked plans are review reports, not
+ executable work lists. A partial ``pdb_ids`` scope is useful for testing;
+ omit it for a complete release comparison. Coordinate revisions determine
+ changes unless ``refresh_pdb_ids`` explicitly requests re-annotation of
+ unchanged entries against the same source revision.
+ """
+ data_dir = data_dir.resolve(strict=True)
+ nextgen_root = nextgen_root.resolve(strict=True)
+ obsolete_path = obsolete_path.resolve(strict=True)
+ output_dir = output_dir.resolve()
+ if output_dir == data_dir or data_dir in output_dir.parents:
+ raise ValueError("write the update plan outside the existing release")
+ if output_dir.exists():
+ raise FileExistsError(output_dir)
+ sources_path = data_dir / "index/entry_sources.parquet"
+ inputs = {
+ "entry_sources": sources_path,
+ "obsolete": obsolete_path,
+ "holdings": nextgen_root / "holdings/current_file_holdings.json.gz",
+ "modified": nextgen_root
+ / "holdings/released_structures_last_modified_dates.json.gz",
+ }
+ signatures = {name: _signature(path) for name, path in inputs.items()}
+ sources = pd.read_parquet(sources_path, columns=["entry_pdb_id", *REVISION_COLUMNS])
+ scope = (
+ sorted({normalize_pdb_id(value) for value in pdb_ids})
+ if pdb_ids is not None
+ else None
+ )
+ if scope is not None:
+ sources = sources.loc[sources.entry_pdb_id.isin(scope)]
+ snapshot = read_snapshot(
+ nextgen_root,
+ threads=threads,
+ previous_snapshot=previous_snapshot,
+ pdb_ids=scope,
+ )
+ entries = compare_entries(sources, snapshot, read_obsolete(obsolete_path))
+ refresh = {normalize_pdb_id(value) for value in refresh_pdb_ids or ()}
+ missing_refresh = refresh.difference(entries.pdb_id)
+ if missing_refresh:
+ raise ValueError(
+ f"refresh PDB IDs are outside the update scope: {sorted(missing_refresh)}"
+ )
+ unavailable_refresh = refresh.intersection(
+ entries.loc[entries.action != "unchanged", "pdb_id"]
+ )
+ if unavailable_refresh:
+ raise ValueError(
+ f"refresh PDB IDs must be unchanged entries: {sorted(unavailable_refresh)}"
+ )
+ entries.loc[entries.pdb_id.isin(refresh), ["action", "reason"]] = [
+ "revised",
+ "annotation refresh",
+ ]
+ counts = dict(sorted(Counter(entries.action).items()))
+ changed = bool(entries.action.isin(["added", "revised", "obsolete"]).any())
+ status = (
+ "blocked" if counts.get("blocked") else "ready" if changed else "no_changes"
+ )
+ plan: dict[str, Any] = {
+ "status": status,
+ "data_dir": str(data_dir),
+ "nextgen_root": str(nextgen_root),
+ "scope": scope,
+ "refresh_pdb_ids": sorted(refresh),
+ "inputs": signatures,
+ "counts": counts,
+ "work": {
+ "ingest": "ingest.txt",
+ "remove": "remove.txt",
+ "invalidate_queries_and_targets": "invalidate.txt",
+ "searches": [
+ {"queries": "ingest.txt", "targets": "active.txt"},
+ {"queries": "unchanged.txt", "targets": "ingest.txt"},
+ ],
+ "refresh": [
+ "entry tables and canonical ligand archives",
+ "protein clusters, search databases, and representative membership",
+ "ligand fingerprints, chemical similarities, CCD matches, and MMP pairs",
+ "ligand-pocket, PLI, SuCOS, interface, and linked-apo scores",
+ "set covers, cluster summaries, apo links, and final release tables",
+ ]
+ if changed
+ else [],
+ },
+ "notes": [
+ "Do not apply a blocked plan; resolve its source errors first.",
+ "Remove stale rows on both query and target sides before replacing scores.",
+ "Search directions are candidate work, not a complete search-cache repair plan: "
+ "changed representatives and capped hit lists can require full-query searches.",
+ "Recompute covers globally; their representatives and labels can change.",
+ "This plan compares PDB coordinate revisions and explicitly refreshed "
+ "entries; other annotation changes are not detected automatically.",
+ ],
+ }
+ # Check small catalogues again in case a source changed during revision reads.
+ if signatures != {name: _signature(path) for name, path in inputs.items()}:
+ raise RuntimeError(
+ "source catalogues changed while planning; use a fixed snapshot"
+ )
+ output_dir.mkdir(parents=True)
+ snapshot.to_parquet(output_dir / "snapshot.parquet", index=False)
+ entries.to_parquet(output_dir / "entries.parquet", index=False)
+ entries.to_csv(output_dir / "entries.tsv", sep="\t", index=False)
+ plan["reports"] = {
+ name: _signature(output_dir / name)["sha256"]
+ for name in ("snapshot.parquet", "entries.parquet")
+ }
+ if status != "blocked":
+ for name, actions in {
+ "ingest": ["added", "revised"],
+ "remove": ["obsolete"],
+ "invalidate": ["revised", "obsolete"],
+ "unchanged": ["unchanged"],
+ "active": ["added", "revised", "unchanged"],
+ }.items():
+ ids = entries.loc[entries.action.isin(actions), "pdb_id"]
+ (output_dir / f"{name}.txt").write_text(
+ "".join(f"{value}\n" for value in ids)
+ )
+ # Written last so an interrupted report is not mistaken for a finished plan.
+ (output_dir / "plan.json").write_text(
+ json.dumps(plan, indent=2, sort_keys=True) + "\n"
+ )
+ return plan
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument("data_dir", type=Path)
+ parser.add_argument("output_dir", type=Path)
+ parser.add_argument("--nextgen-root", type=Path, required=True)
+ parser.add_argument("--obsolete", type=Path, required=True)
+ parser.add_argument("--previous-snapshot", type=Path)
+ parser.add_argument("--pdb-manifest", type=Path)
+ parser.add_argument("--refresh-pdb-manifest", type=Path)
+ parser.add_argument("--threads", type=int, default=8)
+ args = parser.parse_args()
+ plan = plan_update(
+ args.data_dir,
+ nextgen_root=args.nextgen_root,
+ obsolete_path=args.obsolete,
+ output_dir=args.output_dir,
+ threads=args.threads,
+ previous_snapshot=args.previous_snapshot,
+ pdb_ids=load_manifest(args.pdb_manifest) if args.pdb_manifest else None,
+ refresh_pdb_ids=(
+ load_manifest(args.refresh_pdb_manifest)
+ if args.refresh_pdb_manifest
+ else None
+ ),
+ )
+ print(json.dumps(plan, indent=2, sort_keys=True))
+ if plan["status"] == "blocked":
+ raise SystemExit(1)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/plinder/data/pipeline/utils.py b/src/plinder/data/pipeline/utils.py
index 184c1d265..bcaa17988 100644
--- a/src/plinder/data/pipeline/utils.py
+++ b/src/plinder/data/pipeline/utils.py
@@ -2,162 +2,34 @@
# Distributed under the terms of the Apache License 2.0
from __future__ import annotations
-import multiprocessing
-import shutil
from functools import wraps
from hashlib import md5
-from itertools import repeat
from json import dumps, load
-from os import listdir
from pathlib import Path
from time import time
-from typing import TYPE_CHECKING, Any, Callable, Dict, Literal, Optional, TypeVar
-from zipfile import ZIP_DEFLATED, ZipFile
+from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar
import pandas as pd
-from omegaconf import DictConfig
-
-from plinder.core.scores import query_clusters
-from plinder.core.structure import smallmols_similarity
+import pyarrow as pa
+import pyarrow.parquet as pq
+from omegaconf import DictConfig, OmegaConf
+
+from plinder.core.scores.metrics import (
+ CHEMICAL_CLUSTER_SUMMARY_COLUMNS,
+ CHEMICAL_CLUSTER_SUMMARY_THRESHOLD,
+ is_chemical_cluster_metric,
+)
from plinder.core.utils import schemas
from plinder.core.utils.log import setup_logger
-from plinder.core.utils.unpack import expand_config_context
-from plinder.data.utils.annotations.aggregate_annotations import Entry
if TYPE_CHECKING:
- from plinder.data.utils.annotations.get_similarity_scores import Scorer
+ from plinder.data.annotations.get_similarity_scores import Scorer
LOG = setup_logger(__name__)
T = TypeVar("T")
-def timeit(func: Callable[..., T]) -> Callable[..., T]:
- """
- Simple function timer decorator
- """
-
- @wraps(func)
- def wrapped(*args: Any, **kwargs: Any) -> Any:
- name = func.__name__
- mod = func.__module__
- log = setup_logger(".".join([mod, name]))
- ts = time()
- result = None
- try:
- result = func(*args, **kwargs)
- log.info(f"runtime succeeded: {time() - ts:>9.2f}s")
- except Exception as e:
- log.error(f"runtime failed: {time() - ts:>9.2f}s")
- log.error(f"{name} failed with: {repr(e)}")
- raise
- return result
-
- return wrapped
-
-
-def entry_exists(*, entry_dir: Path, pdb_id: str) -> bool:
- """
- Check if the entry JSON file exists.
-
- Parameters
- ----------
- entry_dir : Path
- the directory containing entries
- pdb_id : str
- the PDB ID
- """
- two_char_code = pdb_id[-3:-1]
- output = entry_dir / two_char_code / (pdb_id + ".json")
- output.parent.mkdir(exist_ok=True, parents=True)
- return output.is_file()
-
-
-@timeit
-def load_entries(
- *,
- data_dir: Path,
- pdb_ids: list[str],
- clear_non_pocket_residues: bool = True,
- load_for_scoring: bool = True,
- max_protein_chains: int = 5,
- max_ligand_chains: int = 5,
-) -> Dict[str, "Entry"]:
- """
- Load entries from the entries dir into a dict
- """
- from plinder.data.utils.annotations.aggregate_annotations import Entry
-
- reduced = {}
- entry_dir = data_dir / "raw_entries"
- LOG.info(f"attempting to load {len(pdb_ids)} entries")
- for pdb_id in pdb_ids:
- try:
- reduced[pdb_id] = Entry.from_json(
- entry_dir / pdb_id[-3:-1] / (pdb_id + ".json"),
- clear_non_pocket_residues=clear_non_pocket_residues,
- load_for_scoring=load_for_scoring,
- max_protein_chains=max_protein_chains,
- max_ligand_chains=max_ligand_chains,
- )
- except Exception as e:
- LOG.error(f"pdb_id={pdb_id} failed with {repr(e)}")
- LOG.info(f"loaded {len(reduced)} entries from jsons")
- return reduced
-
-
-@timeit
-def load_entries_from_zips(
- *,
- data_dir: Path,
- two_char_codes: Optional[list[str]] = None,
- pdb_ids: Optional[list[str]] = None,
- load_for_scoring: bool = False,
-) -> Dict[str, "Entry"]:
- """
- Load entries from the qc zips into a dict
- """
- from plinder.data.utils.annotations.aggregate_annotations import Entry
-
- per_zip: dict[str, list[str]] | None = None
- entry_msg = "all"
- if pdb_ids is not None:
- zip_paths_set = set()
- per_zip = {}
- for pdb_id in pdb_ids:
- code = pdb_id[-3:-1]
- zip_paths_set.add(data_dir / "entries" / f"{code}.zip")
- per_zip.setdefault(code, [])
- per_zip[code].append(f"{pdb_id}.json")
- entry_msg = str(sum((len(pz) for pz in per_zip.values())))
- zip_paths = list(zip_paths_set)
- elif two_char_codes is not None:
- zip_paths = [data_dir / "entries" / f"{code}.zip" for code in two_char_codes]
- else:
- zip_paths = list((data_dir / "entries").glob("*"))
- reduced = {}
- LOG.info(f"attempting to load {entry_msg} entries from {len(zip_paths)} zips")
- for zip_path in zip_paths:
- if not zip_path.is_file():
- LOG.error(f"no archive {zip_path}, did you run structure_qc?")
- continue
- with ZipFile(zip_path) as archive:
- names = archive.namelist()
- if per_zip is not None:
- names = per_zip[zip_path.stem]
- for name in names:
- try:
- with archive.open(name) as obj:
- pdb_id = name.replace(".json", "")
- reduced[pdb_id] = Entry.model_validate_json(obj.read()).prune(
- load_for_scoring=load_for_scoring,
- )
- except Exception as e:
- LOG.error(f"failed to read name={name} failed with {repr(e)}")
- LOG.info(f"loaded {len(reduced)} entries from zips")
- return reduced
-
-
def get_db_sources(
*, data_dir: Path, sub_databases: list[str] | None = None
) -> dict[str, Path]:
@@ -167,9 +39,15 @@ def get_db_sources(
if "holo" in sub_databases or not len(sub_databases):
dbs["holo_foldseek"] = data_dir / "dbs" / "foldseek" / "foldseek"
dbs["holo_mmseqs"] = data_dir / "dbs" / "mmseqs" / "mmseqs"
+ if "monomer" in sub_databases:
+ dbs["monomer_foldseek"] = data_dir / "dbs" / "foldseek" / "foldseek"
+ dbs["monomer_mmseqs"] = data_dir / "dbs" / "mmseqs" / "mmseqs"
if "apo" in sub_databases or not len(sub_databases):
dbs["apo_foldseek"] = data_dir / "dbs" / "foldseek" / "foldseek"
dbs["apo_mmseqs"] = data_dir / "dbs" / "mmseqs" / "mmseqs"
+ if "interface_apo" in sub_databases:
+ dbs["interface_apo_foldseek"] = data_dir / "dbs" / "foldseek" / "foldseek"
+ dbs["interface_apo_mmseqs"] = data_dir / "dbs" / "mmseqs" / "mmseqs"
if "pred" in sub_databases or not len(sub_databases):
dbs["pred_foldseek"] = data_dir / "dbs" / "pred_foldseek" / "foldseek"
dbs["pred_mmseqs"] = data_dir / "dbs" / "pred_mmseqs" / "mmseqs"
@@ -182,8 +60,25 @@ def get_scorer(
pdb_ids: list[str],
scorer_cfg: DictConfig,
load_entries: bool,
+ scratch_dir: Path,
+ foldseek_cfg: DictConfig | None = None,
+ mmseqs_cfg: DictConfig | None = None,
) -> tuple["Scorer", list[str], Path]:
- from plinder.data.utils.annotations.get_similarity_scores import Scorer
+ from plinder.data.annotations.get_similarity_scores import Scorer
+ from plinder.data.pipeline.config import FoldseekConfig, MMSeqsConfig
+
+ foldseek_config = (
+ OmegaConf.to_object(foldseek_cfg)
+ if foldseek_cfg is not None
+ else FoldseekConfig()
+ )
+ mmseqs_config = (
+ OmegaConf.to_object(mmseqs_cfg) if mmseqs_cfg is not None else MMSeqsConfig()
+ )
+ if not isinstance(foldseek_config, FoldseekConfig):
+ raise TypeError("foldseek configuration did not resolve to FoldseekConfig")
+ if not isinstance(mmseqs_config, MMSeqsConfig):
+ raise TypeError("mmseqs configuration did not resolve to MMSeqsConfig")
# need holo to db to compare against independently of what to score
sub_dbs = list(set(scorer_cfg.sub_databases).union(["holo"]))
@@ -193,43 +88,52 @@ def get_scorer(
)
hashed_contents = hash_contents(pdb_ids)
if load_entries:
- entries = load_entries_from_zips(
- pdb_ids=None, # explicitly set to None to load all entries
- data_dir=data_dir,
- load_for_scoring=True,
- )
- # TODO: bug where scatter_make_scorers uses raw ingest files
- # instead of available entries from zips but Scorer
- # assumes all entries are present
- entry_ids = list(set(entries.keys()).intersection(pdb_ids))
+ from plinder.core.scores.entries import load_entry_views
+
+ entries = load_entry_views(pdb_ids=pdb_ids, data_dir=data_dir)
+ entry_ids = sorted(entries)
else:
entries = {}
entry_ids = pdb_ids
scores_dir = data_dir / "scores"
sub_db_dir = data_dir / "dbs" / "subdbs"
- batch_db_dir = data_dir / "dbs" / "subdbs" / "batch_dbs" / hashed_contents
+ batch_db_dir = scratch_dir / hashed_contents
batch_db_dir.mkdir(exist_ok=True, parents=True)
- return Scorer(
- entries=entries,
- source_to_full_db_file=db_sources,
- db_dir=sub_db_dir,
- scores_dir=scores_dir,
- minimum_threshold=scorer_cfg.minimum_threshold,
- ), entry_ids, batch_db_dir
+ return (
+ Scorer(
+ entries=entries,
+ source_to_full_db_file=db_sources,
+ db_dir=sub_db_dir,
+ scores_dir=scores_dir,
+ alignment_chain_lookup=data_dir / "index/alignment_chain_lookup.parquet",
+ minimum_threshold=scorer_cfg.minimum_threshold,
+ minimum_thresholds=dict(scorer_cfg.minimum_thresholds),
+ max_query_protein_chains=scorer_cfg.max_query_protein_chains,
+ max_query_proper_ligand_chains=(scorer_cfg.max_query_proper_ligand_chains),
+ foldseek_config=foldseek_config,
+ mmseqs_config=mmseqs_config,
+ ),
+ entry_ids,
+ batch_db_dir,
+ )
def save_ligand_batch(
*,
- entries: dict[str, "Entry"],
+ data_dir: Path,
+ annotation: pd.DataFrame,
output_path: Path,
) -> None:
- dfs = []
- for entry in entries.values():
- df = smallmols_similarity.load_ligands_from_entry(entry=entry)
- if df is not None:
- dfs.append(df)
- LOG.info(f"save_ligand_batch: {len(dfs)} entries have usable ligands")
- df = pd.concat(dfs).drop_duplicates().reset_index(drop=True)
+ from plinder.data.annotations.get_similarity_scores import (
+ annotate_ligand_3d_score_ability,
+ load_ligands_from_index,
+ )
+
+ df = load_ligands_from_index(annotation=annotation)
+ df = annotate_ligand_3d_score_ability(df, data_dir=data_dir)
+ LOG.info(
+ f"save_ligand_batch: collected ligands from {df['pdb_id'].nunique()} entries"
+ )
for col in df.columns:
nunique = df[col].nunique()
LOG.info(f"save_ligand_batch: unique {col}={nunique}")
@@ -254,89 +158,6 @@ def hash_contents(contents: list[str]) -> str:
return md5(dumps(sorted(contents)).encode("utf8")).hexdigest()
-def get_local_contents(
- *,
- data_dir: Path,
- two_char_codes: Optional[list[str]] = None,
- pdb_ids: Optional[list[str]] = None,
- as_four_char_ids: bool = False,
-) -> list[str]:
- """
- Starting from a root directory, assume subdirectories
- of two character codes each containing subdirectories
- of individual files. The as_ids kludge is intended to
- support both fully qualified PDB (pdb_0000{pdb_id})
- and short PDB ({pdb_id})
-
- Parameters
- ----------
- data_dir : Path
- directory containing two character code directories
- two_char_codes : list[str], default=None
- subset of two character codes
- pdb_ids : list[str], default=None
- subset of pdb IDs (overrides two_char_codes)
- as_four_char_ids : bool, default=False
- if True, return 4 character codes instead of nested
- subdirectories
-
- Returns
- -------
- contents : list[str]
- list of directory-derived metadata contents
- """
- kind, values = expand_config_context(
- pdb_ids=pdb_ids,
- two_char_codes=two_char_codes,
- )
- if kind == "pdb_ids":
- return (
- values if as_four_char_ids else [f"pdb_0000{pdb_id}" for pdb_id in values]
- )
- codes = (
- values
- if kind == "two_char_codes" and len(values)
- else listdir(data_dir.as_posix())
- )
- contents = []
- for code in codes:
- contents.extend(listdir((data_dir / code).as_posix()))
- if as_four_char_ids:
- return sorted([c[-4:] for c in contents])
- return sorted(contents)
-
-
-def partition_batch_scores(*, partition_dir: Path, scores_dir: Path) -> None:
- """
- Consolidate individual pdb ID similarity scores parquet
- files into a pre-partitioned dataset by similarity metric
- and metric value. This partitioned dataset needs to be further
- consolidated in a join step elsewhere.
-
- Parameters
- ----------
- partition_dir : Path
- destination directory for consolidated scores
- scores_dir : Path
- source directory for fragmented scores
- """
- # collect the fragmented parquets
- dfs = []
- for pqt in scores_dir.glob("*.parquet"):
- df = pd.read_parquet(pqt)
- if not df.empty:
- dfs.append(df)
- if len(dfs):
- df = pd.concat(dfs).reset_index(drop=True)
- df.to_parquet(
- partition_dir,
- partition_cols=["metric", "similarity"],
- index=False,
- max_partitions=3939,
- schema=schemas.PROTEIN_SIMILARITY_SCHEMA,
- )
-
-
def get_pdb_ids_in_scoring_dataset(*, data_dir: Path) -> dict[str, list[str]]:
"""
Get all the pdb IDs that are present in the raw scoring dataset
@@ -350,34 +171,23 @@ def get_pdb_ids_in_scoring_dataset(*, data_dir: Path) -> dict[str, list[str]]:
dbs = data_dir / "dbs" / "subdbs"
for search_db in ["holo", "apo", "pred"]:
found[search_db] = [
- path.stem for path in (dbs / f"search_db={search_db}").glob("*parquet")
+ path.stem
+ for path in (dbs / f"search_db={search_db}").glob("*parquet")
+ if not path.name.endswith(".tmp.parquet")
]
return found
-def get_alns(
- *, data_dir: Path, mapped: bool = False
-) -> dict[str, dict[str, list[str]]]:
- """
- Get all the pdb IDs that are present in the raw alignment dataset
-
- Parameters
- ----------
- data_dir : Path
- the root plinder dir
- """
- sub = "mapped_aln" if mapped else "aln"
- found: dict[str, dict[str, list[str]]] = {}
- dbs = data_dir / "dbs" / "subdbs"
- for search_db in ["holo", "apo", "pred"]:
- found.setdefault(search_db, {})
- for aln_type in ["foldseek", "mmseqs"]:
- found[search_db].setdefault(aln_type, [])
- found[search_db][aln_type] = [
- path.stem
- for path in (dbs / f"{search_db}_{aln_type}/{sub}/").glob("*parquet")
- ]
- return found
+def _mapped_alignment_file_is_current(path: Path, *, alignment_type: str) -> bool:
+ """Treat corrupt and pre-compact mapped files as incomplete cache entries."""
+ try:
+ columns = set(pq.read_schema(path).names)
+ except (OSError, ValueError) as exc:
+ LOG.warning(f"ignoring unreadable mapped alignment {path}: {exc}")
+ return False
+ return schemas.mapped_alignment_schema_is_current(
+ columns, alignment_type=alignment_type
+ )
def should_run_stage(stage: str, run: list[str], skip: list[str]) -> bool:
@@ -400,15 +210,7 @@ def should_run_stage(stage: str, run: list[str], skip: list[str]) -> bool:
run : bool
whether or not to run the function
"""
- if len(run):
- if stage in run and stage not in skip:
- return True
- return False
- elif len(skip):
- if stage in skip:
- return False
- return True
- return True
+ return stage not in skip and (not run or stage in run)
def ingest_flow_control(func: Callable[..., T]) -> Callable[..., T]:
@@ -452,369 +254,751 @@ def inner(pipe: Any, *args: Optional[list[str]], **kwargs: Any) -> Any:
return ret
else:
LOG.info(f"skipping {func.__name__}")
+ # Keep the scatter/compute/join interface valid for skipped stages.
return [[]]
return inner
-def add_cluster_columns(*, index: pd.DataFrame) -> pd.DataFrame:
- """
- Add cluster columns to the annotation table
- """
- try:
- clusters = query_clusters(
- columns=[
- "system_id",
- "label",
- "threshold",
- "metric",
- "cluster",
- "directed",
- ],
- filters=[("system_id", "in", set(index["system_id"]))],
+def _reciprocal_component_labels(
+ *, data_dir: Path, entity_type: str, metric: str, threshold: int
+) -> pd.Series:
+ """Read full-graph reciprocal component IDs for one cover threshold."""
+ path = (
+ data_dir
+ / f"{entity_type}_clusters/reductions"
+ / f"metric={metric}/labels/directed=false/threshold={threshold}.parquet"
+ )
+ if not path.is_file():
+ raise FileNotFoundError(f"reciprocal component labels are missing: {path}")
+ node_column = "ligand_id" if entity_type == "ligand" else "system_id"
+ labels = pd.read_parquet(path, columns=[node_column, "label"])
+ labels[node_column] = labels[node_column].astype(str)
+ if labels[node_column].duplicated().any():
+ raise ValueError(f"duplicate nodes in reciprocal component labels: {path}")
+ return labels.set_index(node_column)["label"]
+
+
+def build_ligand_cluster_table(*, index: pd.DataFrame, data_dir: Path) -> pd.DataFrame:
+ """Build one queryable cluster-assignment row per ligand."""
+ node_column = "ligand_id"
+ directed_cover_root = data_dir / "ligand_sampling" / "directed_set_cover"
+ marker_path = data_dir / "index" / "collation.json"
+ repair_started_ns: int | None = None
+ if marker_path.is_file():
+ with marker_path.open() as handle:
+ marker = load(handle)
+ if marker.get("status") == "requires_downstream_repair":
+ repair_started_ns = marker_path.stat().st_mtime_ns
+ set_cover_root = data_dir / "ligand_sampling" / "set_cover"
+ reciprocal_paths = sorted(set_cover_root.glob("metric=*/threshold=*.parquet"))
+ directed_cover_paths = sorted(
+ directed_cover_root.glob("metric=*/threshold=*.parquet")
+ )
+ if (
+ not reciprocal_paths
+ and not directed_cover_paths
+ and repair_started_ns is not None
+ ):
+ raise FileNotFoundError(
+ "targeted collation repair has no rebuilt ligand clusters"
+ )
+ set_cover_keys = {
+ (
+ next(
+ part.split("=", maxsplit=1)[1]
+ for part in path.relative_to(set_cover_root).parts
+ if part.startswith("metric=")
+ ),
+ int(path.stem.split("=", maxsplit=1)[1]),
+ )
+ for path in reciprocal_paths
+ }
+ directed_cover_keys = {
+ (
+ path.parent.name.split("=", maxsplit=1)[1],
+ int(path.stem.split("=", maxsplit=1)[1]),
+ )
+ for path in directed_cover_paths
+ }
+ invalid_set_cover_metrics = sorted(
+ metric for metric, _ in set_cover_keys if not is_chemical_cluster_metric(metric)
+ )
+ invalid_directed_metrics = sorted(
+ metric
+ for metric, _ in directed_cover_keys
+ if is_chemical_cluster_metric(metric)
+ )
+ if invalid_set_cover_metrics or invalid_directed_metrics:
+ raise ValueError(
+ "invalid ligand set-cover modes: "
+ f"undirected={invalid_set_cover_metrics}, "
+ f"directed={invalid_directed_metrics}"
+ )
+ node_ids = pd.Index(
+ index[node_column].dropna().astype(str).unique(),
+ name=node_column,
+ )
+ if not reciprocal_paths and not directed_cover_paths:
+ return pd.DataFrame({node_column: node_ids.to_numpy()})
+ proper = index["ligand_is_proper"].fillna(False).astype(bool)
+ holo = index["system_type"].eq("holo")
+ expected_score_nodes = set(
+ index.loc[proper & holo, node_column].dropna().astype(str)
+ )
+ expected_fingerprint_nodes = set(
+ index.loc[
+ proper & index["ligand_smiles_id"].notna(),
+ node_column,
+ ]
+ .dropna()
+ .astype(str)
+ )
+ artifacts: list[tuple[Path, str, str, bool]] = []
+ for path in reciprocal_paths:
+ relative_parts = path.relative_to(set_cover_root).parts
+ partitions = {
+ key: value
+ for key, value in (
+ part.split("=", maxsplit=1) for part in relative_parts[:-1]
+ )
+ }
+ threshold = int(path.stem.split("=", maxsplit=1)[1])
+ metric = partitions["metric"]
+ artifacts.append(
+ (
+ path,
+ metric,
+ f"{metric}__{threshold}__ligand__set_cover",
+ False,
+ )
)
- except Exception as e:
- LOG.error(f"Could not query clusters: {e}")
- return index
- if clusters is None:
- LOG.error("No clusters found")
- return index
- clusters = clusters.pivot_table(
- values="label",
- index="system_id",
- columns=["metric", "cluster", "directed", "threshold"],
- aggfunc="first",
- )
- new_column_names = []
- for metric, cluster, directed, threshold in clusters.columns:
- if cluster == "components":
- if directed == "True":
- d = "strong__component"
- else:
- d = "weak__component"
+ for path in directed_cover_paths:
+ metric = path.parent.name.split("=", maxsplit=1)[1]
+ threshold = int(path.stem.split("=", maxsplit=1)[1])
+ artifacts.append(
+ (
+ path,
+ metric,
+ f"{metric}__{threshold}__ligand__directed_set_cover",
+ True,
+ )
+ )
+ LOG.info(
+ "loading %d published ligand-cluster artifacts for %d ligand IDs",
+ len(artifacts),
+ len(node_ids),
+ )
+ cluster_columns: dict[str, Any] = {}
+ started = time()
+ for path_index, (path, metric, column, is_directed_cover) in enumerate(
+ artifacts, start=1
+ ):
+ artifact_threshold = int(path.stem.split("=", maxsplit=1)[1])
+ if (
+ repair_started_ns is not None
+ and path.stat().st_mtime_ns <= repair_started_ns
+ ):
+ raise ValueError(
+ "ligand cluster artifact predates the targeted collation "
+ f"repair: {path}"
+ )
+ columns = [node_column, "label", "centroid_ligand_id"]
+ if is_directed_cover:
+ columns.extend(["coverage_count", "coverage_fraction"])
+ labels = pd.read_parquet(path, columns=columns)
+ if labels[node_column].duplicated().any():
+ raise ValueError(f"duplicate ligand IDs in cluster artifact: {path}")
+ labels[node_column] = labels[node_column].astype(str)
+ observed_nodes = set(labels[node_column])
+ expected_nodes = (
+ expected_fingerprint_nodes
+ if is_chemical_cluster_metric(metric)
+ else expected_score_nodes
+ )
+ if observed_nodes != expected_nodes:
+ missing = sorted(expected_nodes.difference(observed_nodes))
+ extra = sorted(observed_nodes.difference(expected_nodes))
+ raise ValueError(
+ "ligand cluster artifact does not cover the current eligible "
+ f"ligand universe: {path}; missing={missing[:10]}, "
+ f"extra={extra[:10]}"
+ )
+ aligned = labels.set_index(node_column)["label"].reindex(node_ids)
+ cluster_columns[column] = aligned.astype("string[pyarrow]").array
+ component_lookup = _reciprocal_component_labels(
+ data_dir=data_dir,
+ entity_type="ligand",
+ metric=metric,
+ threshold=artifact_threshold,
+ )
+ if is_chemical_cluster_metric(metric):
+ component_nodes = (
+ index.set_index(node_column)["ligand_smiles_id"]
+ .reindex(node_ids)
+ .astype("Int64")
+ .astype("string")
+ )
else:
- d = "community"
- new_column_names.append(f"{metric}__{threshold}__{d}")
- clusters.columns = new_column_names
- clusters.reset_index(inplace=True)
- return index.merge(clusters, on="system_id", how="left")
-
-
-def add_aggregated_columns(*, index: pd.DataFrame) -> pd.DataFrame:
- """
- Add aggregated columns to the annotation table
- """
- index = add_cluster_columns(index=index)
- if "pli_qcov__100__strong__component" in index.columns:
- index["uniqueness"] = (
- index["system_id_no_biounit"]
- + "_"
- + index["pli_qcov__100__strong__component"]
+ component_nodes = pd.Series(node_ids, index=node_ids)
+ components = component_nodes.map(component_lookup)
+ if components.loc[labels[node_column]].isna().any():
+ raise ValueError(f"reciprocal components do not cover {path}")
+ cluster_columns[
+ f"{metric}__{artifact_threshold}__ligand__reciprocal_component"
+ ] = components.astype("string[pyarrow]").array
+ summary_column = CHEMICAL_CLUSTER_SUMMARY_COLUMNS.get(metric)
+ if (
+ summary_column is not None
+ and artifact_threshold == CHEMICAL_CLUSTER_SUMMARY_THRESHOLD
+ ):
+ if "entry_pdb_id" not in index.columns:
+ raise ValueError(
+ f"the {artifact_threshold}-percent {metric} set cover "
+ "requires entry_pdb_id"
+ )
+ cluster_column = summary_column
+ count_column = f"{cluster_column}_num_pdb_ids"
+ label_by_node = labels.set_index(node_column)["label"]
+ occurrences = pd.DataFrame(
+ {
+ "label": index.loc[proper & holo, node_column]
+ .astype(str)
+ .map(label_by_node),
+ "entry_pdb_id": index.loc[proper & holo, "entry_pdb_id"].astype(
+ str
+ ),
+ }
+ ).dropna(subset=["label"])
+ pdb_counts = occurrences.groupby("label", observed=True)[
+ "entry_pdb_id"
+ ].nunique()
+ cluster_columns[cluster_column] = aligned.astype("string[pyarrow]").array
+ cluster_columns[count_column] = (
+ aligned.map(pdb_counts).astype("Int32").array
+ )
+ labels["centroid_ligand_id"] = labels["centroid_ligand_id"].astype(str)
+ labels["is_centroid"] = labels[node_column].eq(labels["centroid_ligand_id"])
+ centroid_counts = labels.groupby("label", observed=True)["is_centroid"].sum()
+ invalid_labels = centroid_counts[centroid_counts.ne(1)].index.tolist()
+ if invalid_labels:
+ raise ValueError(
+ "ligand set cover must have exactly one representative row "
+ f"per label: {path}; invalid={invalid_labels[:10]}"
+ )
+ centroid_column = f"{column}__is_centroid"
+ aligned_centroids = labels.set_index(node_column)["is_centroid"].reindex(
+ node_ids
)
- index["biounit_num_ligands"] = index.groupby(["entry_pdb_id", "system_biounit_id"])[
- "system_id"
- ].transform("count")
- index["biounit_num_unique_ccd_codes"] = index.groupby(
- ["entry_pdb_id", "system_biounit_id"]
- )["ligand_unique_ccd_code"].transform("nunique")
- index["biounit_num_proper_ligands"] = index.groupby(
- ["entry_pdb_id", "system_biounit_id"]
- )["ligand_is_proper"].transform("sum")
- for n in [
- "lipinski",
- "cofactor",
- "fragment",
- "oligo",
- "artifact",
- "other",
- "covalent",
- "invalid",
- "ion",
- ]:
- index[f"system_ligand_has_{n}"] = index.groupby("system_id")[
- f"ligand_is_{n}"
- ].transform("any")
- index["system_protein_chains_total_length"] = index[
- "system_protein_chains_length"
- ].apply(sum)
- ccd_dict = (
- index.groupby("system_id")["ligand_unique_ccd_code"]
- .agg(lambda x: "-".join(sorted(set(x))))
- .to_dict()
- )
- index["system_unique_ccd_codes"] = index["system_id"].map(ccd_dict)
- ccd_proper_dict = (
- index[index["ligand_is_proper"]]
- .groupby("system_id")["ligand_unique_ccd_code"]
- .agg(lambda x: "-".join(sorted(set(x))))
- .to_dict()
- )
- index["system_proper_unique_ccd_codes"] = index["system_id"].map(ccd_proper_dict)
- return index
-
+ cluster_columns[centroid_column] = aligned_centroids.astype("boolean").array
+ if is_directed_cover:
+ if labels[["coverage_count", "coverage_fraction"]].isna().any().any():
+ raise ValueError(
+ f"directed ligand cover has missing coverage centrality: {path}"
+ )
+ if (
+ labels["coverage_count"].lt(1).any()
+ or (
+ labels["coverage_fraction"].le(0)
+ | labels["coverage_fraction"].gt(1)
+ ).any()
+ ):
+ raise ValueError(
+ f"directed ligand cover has invalid coverage centrality: {path}"
+ )
+ coverage_count_column = f"{column}__coverage_count"
+ coverage_fraction_column = f"{column}__coverage_fraction"
+ cluster_columns[coverage_count_column] = (
+ labels.set_index(node_column)["coverage_count"]
+ .reindex(node_ids)
+ .astype("Int32")
+ .array
+ )
+ cluster_columns[coverage_fraction_column] = (
+ labels.set_index(node_column)["coverage_fraction"]
+ .reindex(node_ids)
+ .astype("Float32")
+ .array
+ )
+ if path_index % 10 == 0 or path_index == len(artifacts):
+ elapsed = time() - started
+ rate = path_index / elapsed
+ LOG.info(
+ "cluster index progress: loaded=%d/%d rate=%.2f/s eta_seconds=%.1f",
+ path_index,
+ len(artifacts),
+ rate,
+ (len(artifacts) - path_index) / rate,
+ )
+ wide = pd.DataFrame(
+ {node_column: node_ids.to_numpy(), **cluster_columns},
+ copy=False,
+ )
+ LOG.info(
+ "ligand cluster table complete: rows=%d columns=%d elapsed_seconds=%.1f",
+ *wide.shape,
+ time() - started,
+ )
+ return wide
+
+
+def build_interface_cluster_table(
+ *, index: pd.DataFrame, data_dir: Path
+) -> pd.DataFrame:
+ """Build one queryable cluster-assignment row per protein interface."""
+ node_column = "system_id"
+ directed_cover_root = data_dir / "interface_sampling" / "directed_set_cover"
+ marker_path = data_dir / "index" / "collation.json"
+ repair_started_ns: int | None = None
+ if marker_path.is_file():
+ with marker_path.open() as handle:
+ marker = load(handle)
+ if marker.get("status") == "requires_downstream_repair":
+ repair_started_ns = marker_path.stat().st_mtime_ns
+ directed_cover_paths = sorted(
+ directed_cover_root.glob("metric=*/threshold=*.parquet")
+ )
+ if not directed_cover_paths:
+ if repair_started_ns is not None:
+ raise FileNotFoundError(
+ "targeted collation repair has no rebuilt interface clusters"
+ )
+ if index[node_column].notna().any():
+ raise FileNotFoundError(
+ "non-empty interface annotation has no published interface clusters"
+ )
+ return pd.DataFrame({node_column: pd.Series(dtype="string")})
-def create_index(*, data_dir: Path, force_update: bool = False) -> pd.DataFrame:
- """
- Create the index
- """
- index = data_dir / "index" / "annotation_table.parquet"
- index.parent.mkdir(exist_ok=True, parents=True)
-
- if not index.exists() or force_update:
- dfs = []
- for i, path in enumerate((data_dir / "qc" / "index").glob("*")):
- df = pd.read_parquet(path)
- LOG.info(f"{i} {path.name} shape={df.shape}")
- if not df.empty:
- dfs.append(df)
- df = pd.concat(dfs).reset_index(drop=True)
- # TODO: remove these kludges after annotations are rerun
- key = "ligand_posebusters_internal_energy"
- df[key] = df[key].astype(bool)
- df.rename(
- columns={
- f"{key}_Kinase name": f"{key}_kinase_name"
- for key in [
- "ligand_interacting_ligand_chains",
- "ligand_neighboring_ligand_chains",
- "ligand_protein_chains",
- "system_ligand_chains",
- "system_pocket",
- "system_protein_chains",
- ]
- },
- inplace=True,
+ node_ids = pd.Index(
+ index[node_column].dropna().astype(str).unique(),
+ name=node_column,
+ )
+ membership_path = data_dir / "index/interface_membership.parquet"
+ if not membership_path.is_file():
+ if len(node_ids):
+ raise FileNotFoundError(
+ "interface cluster expansion requires representative membership: "
+ f"{membership_path}"
+ )
+ membership = pd.DataFrame(
+ columns=[
+ node_column,
+ "representative_system_id",
+ "side_1_half_interface_id",
+ "side_2_half_interface_id",
+ ]
)
- df.to_parquet(index, index=False)
- else:
- df = pd.read_parquet(index)
- old_columns = set(df.columns)
- df = add_aggregated_columns(index=df)
- update = old_columns != set(df.columns)
- if update or force_update:
- df.to_parquet(index, index=False)
- return df
-
-
-def create_nonredundant_dataset(*, data_dir: Path) -> None:
- """
- This is called in make_mmp_index to ensure the existence of the index
- and simultaneously generates a non-redundant index for various use
- cases. Ultimately this should run as the join step of structure_qc.
- """
- if not (data_dir / "index" / "annotation_table.parquet").exists():
- df = create_index(data_dir=data_dir)
else:
- df = pd.read_parquet(data_dir / "index" / "annotation_table.parquet")
- df_nonredundant = df.sort_values("system_biounit_id").drop_duplicates("uniqueness")
- df_nonredundant.to_parquet(
- data_dir / "index" / "annotation_table_nonredundant.parquet", index=False
+ membership = pd.read_parquet(
+ membership_path,
+ columns=[
+ node_column,
+ "representative_system_id",
+ "side_1_half_interface_id",
+ "side_2_half_interface_id",
+ ],
+ )
+ membership[node_column] = membership[node_column].astype(str)
+ if membership[node_column].duplicated().any():
+ duplicate = membership.loc[
+ membership[node_column].duplicated(), node_column
+ ].iloc[0]
+ raise ValueError(f"duplicate interface membership for {duplicate}")
+ membership_ids = set(membership[node_column])
+ expected_ids = set(node_ids)
+ if membership_ids != expected_ids:
+ missing = sorted(expected_ids.difference(membership_ids))
+ extra = sorted(membership_ids.difference(expected_ids))
+ raise ValueError(
+ "interface representative membership does not cover the current "
+ f"interface universe: missing={missing[:10]}, extra={extra[:10]}"
+ )
+ membership = membership.set_index(node_column).reindex(node_ids)
+ expected_representatives = set(
+ membership["representative_system_id"].dropna().astype(str)
)
-
-
-def apo_file_from_link_id(
- data_dir: Path,
- output_dir: Path,
- link_id: str,
- force_update: bool = False,
-) -> dict[str, str] | None:
- from ost import io, mol
-
- from plinder.data.utils.annotations.save_utils import save_cif_file
-
- if (output_dir / f"{link_id}.cif").exists() and not force_update:
- LOG.info(f"skipping {link_id}.cif as it already exists")
- return None
-
- pdb_id, chain = link_id.split("_")
- target_cif = (
- data_dir
- / "ingest"
- / pdb_id[1:3]
- / f"pdb_0000{pdb_id}"
- / f"pdb_0000{pdb_id}_xyz-enrich.cif.gz"
- )
- if not target_cif.exists():
- LOG.info(f"skipping {link_id} as {target_cif} does not exist")
- return None
-
- target_mol, seqres, info = io.LoadMMCIF(
- target_cif.as_posix(),
- seqres=True,
- info=True,
- fault_tolerant=True,
- )
- target_mol = mol.CreateEntityFromView(target_mol.Select(f"chain='{chain}'"), True)
- cif_file = output_dir / f"{pdb_id}_{chain}.cif"
- LOG.info(f"saving {link_id} to {cif_file}")
- save_cif_file(target_mol, info, cif_file.stem, cif_file)
- return None
- # chain_to_seqres = {c.name: c.string for c in seqres}
- # return chain_to_seqres[chain]
-
-
-def pred_file_from_link_id(
- data_dir: Path,
- output_dir: Path,
- link_id: str,
- force_update: bool = False,
-) -> None:
- from ost import io, mol
-
- from plinder.data.utils.annotations.save_utils import save_cif_file
-
- if (output_dir / f"{link_id}.cif").exists() and not force_update:
- LOG.info(f"skipping {link_id}.cif as it already exists")
- return None
-
- uniprot_id, chain = link_id.split("_")
- target_cif = data_dir / "dbs" / "alphafold" / f"AF-{uniprot_id}-F1-model_v4.cif"
- if not target_cif.exists():
- LOG.info(f"skipping {link_id} as {target_cif} does not exist")
- return None
-
- target_mol, seqres, info = io.LoadMMCIF(
- target_cif.as_posix(),
- seqres=True,
- info=True,
- fault_tolerant=True,
+ expected_half_representatives = set(
+ membership[["side_1_half_interface_id", "side_2_half_interface_id"]].stack()
)
- target_mol = mol.CreateEntityFromView(target_mol.Select(f"chain='{chain}'"), True)
- cif_file = output_dir / f"{uniprot_id}_{chain}.cif"
- LOG.info(f"saving {link_id} to {cif_file}")
- save_cif_file(target_mol, info, cif_file.stem, cif_file)
- return None
- # chain_to_seqres = {c.name: c.string for c in seqres}
- # return chain_to_seqres[chain]
-
-
-def pack_linked_structures(data_dir: Path, code: str, structures: bool = True) -> None:
- """
- Pack generated linked structures into a zip file for a particular
- two character code.
-
- Parameters
- ----------
- data_dir : Path
- plinder root dir
- code : str
- two character code
- structures : bool, default=True
- if True, make structure archives
- """
- (data_dir / "links").mkdir(exist_ok=True, parents=True)
- mode: Literal["r", "w"] = "w" if structures else "r"
- with ZipFile(
- data_dir / "links" / f"{code}.zip", mode, compression=ZIP_DEFLATED
- ) as archive:
- for search_db in ["apo", "pred"]:
- jsons = []
- root = data_dir / "linked_staging" / search_db
- system_ids = [
- system_id for system_id in listdir(root) if system_id[1:3] == code
- ]
- for system_id in system_ids:
- link_ids = listdir(f"{root}/{system_id}")
- for link_id in link_ids:
- link = f"{root}/{system_id}/{link_id}"
- try:
- with open(f"{link}/scores.json") as f:
- jsons.append(load(f))
- except Exception:
- pass
- if structures:
- try:
- archive.write(
- f"{link}/superposed.cif",
- f"{search_db}/{system_id}/{link_id}/superposed.cif",
- )
- except Exception:
- pass
- df = pd.DataFrame(jsons).rename(
- columns={"reference": "reference_system_id", "model": "id"}
+ artifacts: list[tuple[Path, str, int, str]] = []
+ for path in directed_cover_paths:
+ metric = path.parent.name.split("=", maxsplit=1)[1]
+ threshold = int(path.stem.split("=", maxsplit=1)[1])
+ artifacts.append((path, metric, threshold, "directed_set_cover"))
+
+ cluster_columns: dict[str, Any] = {}
+ started = time()
+ for path_index, (path, metric, threshold, kind) in enumerate(artifacts, start=1):
+ if (
+ repair_started_ns is not None
+ and path.stat().st_mtime_ns <= repair_started_ns
+ ):
+ raise ValueError(
+ "interface cluster artifact predates the targeted collation "
+ f"repair: {path}"
)
- df.to_parquet(
- data_dir / "links" / f"{search_db}_{code}.parquet", index=False
+ labels = pd.read_parquet(path, columns=[node_column, "label"])
+ if labels[node_column].duplicated().any():
+ raise ValueError(f"duplicate interface IDs in cluster artifact: {path}")
+ labels[node_column] = labels[node_column].astype(str)
+ observed_nodes = set(labels[node_column])
+ expected_artifact_nodes = (
+ expected_half_representatives
+ if metric == "interface_side_qcov"
+ else expected_representatives
+ )
+ if observed_nodes != expected_artifact_nodes:
+ missing = sorted(expected_artifact_nodes.difference(observed_nodes))
+ extra = sorted(observed_nodes.difference(expected_artifact_nodes))
+ raise ValueError(
+ "interface cluster artifact does not cover the current interface "
+ f"universe: {path}; missing={missing[:10]}, extra={extra[:10]}"
+ )
+ label_lookup = labels.set_index(node_column)["label"]
+ component_lookup = _reciprocal_component_labels(
+ data_dir=data_dir,
+ entity_type="interface",
+ metric=metric,
+ threshold=threshold,
+ )
+ if component_lookup.reindex(labels[node_column]).isna().any():
+ raise ValueError(f"reciprocal components do not cover {path}")
+ if metric == "interface_side_qcov":
+ for side in (1, 2):
+ representative_nodes = membership[
+ f"side_{side}_half_interface_id"
+ ].astype(str)
+ aligned = representative_nodes.map(label_lookup)
+ column = f"{metric}__{threshold}__chain_{side}_{kind}"
+ cluster_columns[column] = aligned.astype("string[pyarrow]").array
+ components = representative_nodes.map(component_lookup)
+ cluster_columns[
+ f"{metric}__{threshold}__chain_{side}_reciprocal_component"
+ ] = components.astype("string[pyarrow]").array
+ else:
+ column = f"{metric}__{threshold}__{kind}"
+ aligned = (
+ membership["representative_system_id"].astype(str).map(label_lookup)
+ )
+ cluster_columns[column] = aligned.astype("string[pyarrow]").array
+ components = (
+ membership["representative_system_id"].astype(str).map(component_lookup)
+ )
+ cluster_columns[f"{metric}__{threshold}__reciprocal_component"] = (
+ components.astype("string[pyarrow]").array
+ )
+ if path_index % 10 == 0 or path_index == len(artifacts):
+ elapsed = time() - started
+ rate = path_index / elapsed
+ LOG.info(
+ "interface cluster index progress: loaded=%d/%d rate=%.2f/s "
+ "eta_seconds=%.1f",
+ path_index,
+ len(artifacts),
+ rate,
+ (len(artifacts) - path_index) / rate,
)
+ wide = pd.DataFrame(
+ {node_column: node_ids.to_numpy(), **cluster_columns},
+ copy=False,
+ )
+ LOG.info(
+ "interface cluster table complete: rows=%d columns=%d elapsed_seconds=%.1f",
+ *wide.shape,
+ time() - started,
+ )
+ return wide
-def mp_pack_linked_structures(*, data_dir: Path, structures: bool = True) -> None:
- """
- Use a process pool to pack linked structures into two character code archives.
-
- Parameters
- ----------
- data_dir : Path
- plinder root dir
- """
- with multiprocessing.get_context("spawn").Pool() as pool:
- pool.starmap(
- pack_linked_structures,
- zip(repeat(data_dir), listdir(data_dir / "ingest"), repeat(structures)),
+def add_ligand_similarity_columns(
+ *, index: pd.DataFrame, data_dir: Path
+) -> pd.DataFrame:
+ """Merge unique-SMILES and cofactor annotations into each ligand."""
+ annotation_path = (
+ data_dir / "fingerprints" / "ligand_similarity_annotations.parquet"
+ )
+ if not annotation_path.is_file():
+ raise FileNotFoundError(
+ f"missing ligand similarity annotations: {annotation_path}"
+ )
+ annotations = pd.read_parquet(annotation_path)
+ artifact_smiles_column = "ligand_rdkit_canonical_smiles"
+ index_smiles_column = "ligand_smiles"
+ if annotations[artifact_smiles_column].duplicated().any():
+ raise ValueError("ligand similarity annotations contain duplicate SMILES")
+ proper_holo = index["ligand_is_proper"].fillna(False).astype(bool) & index[
+ "system_type"
+ ].eq("holo")
+ expected_smiles = set(
+ index.loc[proper_holo, index_smiles_column]
+ .dropna()
+ .astype(str)
+ .loc[lambda values: values.ne("")]
+ )
+ observed_smiles = set(annotations[artifact_smiles_column].dropna().astype(str))
+ if observed_smiles != expected_smiles:
+ missing = sorted(expected_smiles.difference(observed_smiles))
+ extra = sorted(observed_smiles.difference(expected_smiles))
+ raise ValueError(
+ "ligand similarity annotations do not cover the current proper "
+ f"holo SMILES universe: missing={missing[:10]}, extra={extra[:10]}"
+ )
+ annotations = annotations.rename(
+ columns={artifact_smiles_column: index_smiles_column}
+ )
+ replacement_columns = set(annotations.columns).difference({index_smiles_column})
+ obsolete_columns = _chemical_cluster_summary_columns()
+ result = index.drop(
+ columns=list(
+ replacement_columns.intersection(index.columns)
+ | obsolete_columns.intersection(index.columns)
)
+ ).merge(
+ annotations,
+ on=index_smiles_column,
+ how="left",
+ validate="many_to_one",
+ )
+ has_smiles = result[index_smiles_column].notna() & result[index_smiles_column].ne(
+ ""
+ )
+ eligible = has_smiles
+ if "ligand_is_proper" in result:
+ eligible &= result["ligand_is_proper"].fillna(False)
+ if "system_type" in result:
+ eligible &= result["system_type"].eq("holo")
+ if result.loc[eligible, "ligand_smiles_id"].isna().any():
+ raise ValueError(
+ "some proper canonical ligand SMILES lack similarity annotations"
+ )
+ for column in replacement_columns:
+ if pd.api.types.is_bool_dtype(result[column].dtype):
+ result[column] = result[column].astype("boolean")
+ result.loc[~eligible, column] = pd.NA
+ result["ligand_smiles_id"] = result["ligand_smiles_id"].astype("Int32")
+ if "ligand_is_cofactor_like" in result:
+ result["ligand_is_cofactor_like"] = result["ligand_is_cofactor_like"].astype(
+ "boolean"
+ )
+ return result
+
+
+def add_ligand_3d_score_ability_column(
+ *, index: pd.DataFrame, data_dir: Path
+) -> pd.DataFrame:
+ """Merge occurrence-level canonical-SDF shape-comparability into the index."""
+ expected = index["ligand_id"].notna()
+ if "system_type" in index:
+ expected &= index["system_type"].eq("holo")
+ if "ligand_is_proper" in index:
+ expected &= index["ligand_is_proper"].fillna(False)
+ comparability_column = "ligand_is_shape_comparable"
+ if (
+ comparability_column in index
+ and not index.loc[expected, comparability_column].isna().any()
+ ):
+ comparabilities = index.loc[
+ index["ligand_id"].notna(), ["ligand_id", comparability_column]
+ ].drop_duplicates()
+ conflicts = comparabilities.groupby("ligand_id")[comparability_column].nunique()
+ if (conflicts > 1).any():
+ raise ValueError("conflicting shape-comparability annotations for a ligand")
+ result = index.copy()
+ result.loc[~expected, comparability_column] = False
+ result[comparability_column] = result[comparability_column].astype("boolean")
+ return result
+ ligand_dataset = data_dir / "ligands"
+ if not ligand_dataset.is_dir():
+ raise FileNotFoundError(f"missing ligand annotation dataset: {ligand_dataset}")
+ comparabilities = pd.read_parquet(
+ ligand_dataset,
+ columns=["ligand_id", "ligand_is_shape_comparable"],
+ ).drop_duplicates()
+ conflicts = comparabilities.groupby("ligand_id")[
+ "ligand_is_shape_comparable"
+ ].nunique()
+ if (conflicts > 1).any():
+ raise ValueError("conflicting shape-comparability annotations for a ligand")
+ comparabilities = comparabilities.drop_duplicates(subset=["ligand_id"])
+ result = index.drop(columns=["ligand_is_shape_comparable"], errors="ignore").merge(
+ comparabilities,
+ on="ligand_id",
+ how="left",
+ validate="many_to_one",
+ )
+ expected = result["ligand_id"].notna()
+ if "system_type" in result:
+ expected &= result["system_type"].eq("holo")
+ if "ligand_is_proper" in result:
+ expected &= result["ligand_is_proper"].fillna(False)
+ if result.loc[expected, "ligand_is_shape_comparable"].isna().any():
+ raise ValueError(
+ "some proper holo ligands lack a shape-comparability annotation"
+ )
+ result.loc[~expected, "ligand_is_shape_comparable"] = False
+ result["ligand_is_shape_comparable"] = result["ligand_is_shape_comparable"].astype(
+ "boolean"
+ )
+ return result
+
+
+def _chemical_cluster_summary_columns() -> set[str]:
+ """Return the 90-percent cluster sidecar columns of every chemical metric."""
+ return {
+ name
+ for column in CHEMICAL_CLUSTER_SUMMARY_COLUMNS.values()
+ for name in (column, f"{column}_num_pdb_ids")
+ }
+
+
+def _is_ligand_cluster_column(column: str) -> bool:
+ """Return whether a column belongs in the ligand-cluster sidecar."""
+ return column in _chemical_cluster_summary_columns() or (
+ "__ligand__" in column
+ and column.endswith(
+ (
+ "__component",
+ "__community",
+ "__set_cover",
+ "__set_cover__is_centroid",
+ "__directed_set_cover",
+ "__directed_set_cover__is_centroid",
+ "__directed_set_cover__coverage_count",
+ "__directed_set_cover__coverage_fraction",
+ )
+ )
+ )
-def pack_source_structures(data_dir: Path, search_db: str) -> None:
- (data_dir / "linked_structures").mkdir(exist_ok=True, parents=True)
- with ZipFile(
- data_dir / "linked_structures" / f"{search_db}.zip",
- "w",
- compression=ZIP_DEFLATED,
- ) as archive:
- source_structures = data_dir / "linked_staging" / "source" / search_db
- for path in source_structures.rglob("*.cif"):
- archive.write(path, path.name)
+def _is_interface_cluster_column(column: str) -> bool:
+ """Return whether a column belongs in the interface-cluster sidecar."""
+ return column.startswith(("interface_qcov__", "interface_side_qcov__")) and (
+ "component" in column or "community" in column or "set_cover" in column
+ )
-def consolidate_linked_scores(*, data_dir: Path) -> None:
- """
- Consolidate linked scores into a single parquet file. Assumes
- that pack_linked_structures has been run.
- Parameters
- ----------
- data_dir : Path
- plinder root dir
- """
- for search_db in ["apo", "pred"]:
- paths = list((data_dir / "links").glob(f"{search_db}_*.parquet"))
- dfs = []
- for path in paths:
- df = pd.read_parquet(path)
- if not df.empty:
- dfs.append(df)
- ndf = pd.concat(dfs)
- odf = pd.read_parquet(
- data_dir / "linked_staging" / f"{search_db}_links.parquet"
- )
- drop = list(
- set(odf.columns.intersection(ndf.columns))
- - set(["reference_system_id", "id"])
- )
- df = pd.merge(odf.drop(columns=drop), ndf, on=["reference_system_id", "id"])
- (data_dir / "links" / f"kind={search_db}").mkdir(exist_ok=True, parents=True)
- df.to_parquet(
- data_dir / "links" / f"kind={search_db}" / "links.parquet", index=False
+def _read_annotation_table(path: Path) -> pd.DataFrame:
+ """Keep nested columns in Arrow storage rather than Python objects."""
+ columns = [name for name in pq.read_schema(path).names if name != "ligand__members"]
+ return pq.read_table(path, columns=columns).to_pandas(
+ types_mapper=lambda dtype: (
+ pd.ArrowDtype(dtype) if pa.types.is_nested(dtype) else None
)
+ )
-def rename_clusters(*, data_dir: Path) -> None:
- """
- Rename cluster files to match the hive layout convention.
+def finalize_index(
+ *,
+ data_dir: Path,
+ weekly_ligand_clusters: Path | None = None,
+ weekly_interface_clusters: Path | None = None,
+) -> pd.DataFrame:
+ """Publish enriched annotations and separate cluster-assignment tables."""
+ started = time()
+ index_path = data_dir / "index" / "annotation_table.parquet"
+ if not index_path.is_file():
+ raise FileNotFoundError(index_path)
+ LOG.info("loading annotation index for final enrichment: %s", index_path)
+ index = _read_annotation_table(index_path)
+ index.drop(
+ columns=["uniqueness", "system_pass_criteria"], errors="ignore", inplace=True
+ )
+ LOG.info("loaded annotation index: rows=%d columns=%d", *index.shape)
+ index = add_ligand_3d_score_ability_column(index=index, data_dir=data_dir)
+ LOG.info("merged ligand shape-comparability annotations")
+ index = add_ligand_similarity_columns(index=index, data_dir=data_dir)
+ LOG.info("merged ligand similarity annotations")
+ ligand_clusters = (
+ pd.read_parquet(weekly_ligand_clusters)
+ if weekly_ligand_clusters is not None
+ else build_ligand_cluster_table(index=index, data_dir=data_dir)
+ )
+ if set(ligand_clusters["ligand_id"]) != set(index["ligand_id"]):
+ raise ValueError("ligand cluster assignments do not cover the annotation table")
+ index.drop(
+ columns=[column for column in index if _is_ligand_cluster_column(column)],
+ inplace=True,
+ )
+ interface_path = data_dir / "index" / "interface_annotation_table.parquet"
+ interface_index: pd.DataFrame | None = None
+ interface_clusters: pd.DataFrame | None = None
+ if interface_path.is_file():
+ interface_index = _read_annotation_table(interface_path)
+ interface_clusters = (
+ pd.read_parquet(weekly_interface_clusters)
+ if weekly_interface_clusters is not None
+ else build_interface_cluster_table(index=interface_index, data_dir=data_dir)
+ )
+ if set(interface_clusters["system_id"]) != set(interface_index["system_id"]):
+ raise ValueError(
+ "interface cluster assignments do not cover the annotation table"
+ )
+ interface_index.drop(
+ columns=[
+ column
+ for column in interface_index
+ if _is_interface_cluster_column(column)
+ ],
+ inplace=True,
+ )
- Parameters
- ----------
- data_dir : Path
- plinder root dir
- """
- cluster_dir = data_dir / "clusters"
- cluster_paths = [path for path in cluster_dir.rglob("*") if path.is_file()]
- for path in cluster_paths:
- if path.name == "data.parquet":
- continue
- base = path.parent
- name = path.stem
- apath = base / name / "data.parquet"
- apath.parent.mkdir(exist_ok=True, parents=True)
- shutil.move(path, apath)
+ temporary = index_path.with_suffix(".tmp.parquet")
+ temporary_interface = interface_path.with_suffix(".tmp.parquet")
+ ligand_clusters_path = data_dir / "index" / "ligand_clusters.parquet"
+ interface_clusters_path = data_dir / "index" / "interface_clusters.parquet"
+ temporary_ligand_clusters = ligand_clusters_path.with_suffix(".tmp.parquet")
+ temporary_interface_clusters = interface_clusters_path.with_suffix(".tmp.parquet")
+ index_marker_removed = False
+ try:
+ LOG.info("staging annotation and cluster tables")
+ pq.write_table(
+ pa.Table.from_pandas(index, preserve_index=False).replace_schema_metadata(
+ None
+ ),
+ temporary,
+ )
+ ligand_clusters.to_parquet(temporary_ligand_clusters, index=False)
+ if interface_index is not None:
+ pq.write_table(
+ pa.Table.from_pandas(
+ interface_index, preserve_index=False
+ ).replace_schema_metadata(None),
+ temporary_interface,
+ )
+ assert interface_clusters is not None
+ interface_clusters.to_parquet(
+ temporary_interface_clusters,
+ index=False,
+ )
+ # The primary annotation table is the readability marker for this
+ # generation. Install it last so an interrupted update fails closed
+ # instead of exposing mismatched annotation and cluster tables.
+ index_path.unlink()
+ index_marker_removed = True
+ if interface_index is not None:
+ temporary_interface.replace(interface_path)
+ temporary_interface_clusters.replace(interface_clusters_path)
+ temporary_ligand_clusters.replace(ligand_clusters_path)
+ temporary.replace(index_path)
+ except BaseException:
+ if index_marker_removed:
+ index_path.unlink(missing_ok=True)
+ raise
+ finally:
+ temporary.unlink(missing_ok=True)
+ temporary_interface.unlink(missing_ok=True)
+ temporary_ligand_clusters.unlink(missing_ok=True)
+ temporary_interface_clusters.unlink(missing_ok=True)
+ if interface_index is not None:
+ LOG.info(
+ "wrote interface annotations: rows=%d columns=%d",
+ *interface_index.shape,
+ )
+ LOG.info(
+ "final table publication complete: rows=%d columns=%d elapsed_seconds=%.1f",
+ *index.shape,
+ time() - started,
+ )
+ return index
diff --git a/src/plinder/data/pipeline/weekly_clusters.py b/src/plinder/data/pipeline/weekly_clusters.py
new file mode 100644
index 000000000..2963438ae
--- /dev/null
+++ b/src/plinder/data/pipeline/weekly_clusters.py
@@ -0,0 +1,595 @@
+"""Extend fixed representative covers with changed release entries."""
+
+from __future__ import annotations
+
+from pathlib import Path
+from tempfile import TemporaryDirectory
+from typing import Any
+
+import duckdb
+import numpy as np
+import pandas as pd
+import pyarrow as pa
+import pyarrow.parquet as pq
+
+from plinder.core.release import RELEASE_PATHS
+from plinder.core.scores.metrics import CHEMICAL_CLUSTER_SUMMARY_COLUMNS
+from plinder.data.databases import run
+from plinder.data.protein_clusters import SEQUENCE_CLUSTER_SCHEMA
+
+
+def _score_rows(
+ paths: list[Path], query_ids: pd.Series, columns: list[str], *, numeric: bool
+) -> pd.DataFrame:
+ if not paths or query_ids.empty:
+ return pd.DataFrame(columns=columns)
+ ids = pd.DataFrame({"id": query_ids.drop_duplicates()})
+ sources = ", ".join(
+ f"'{str(path).replace(chr(39), chr(39) * 2)}'" for path in paths
+ )
+ selected = ", ".join(f"scores.{column}" for column in columns)
+ query_column = columns[0]
+ with duckdb.connect() as connection:
+ connection.register("changed_queries", ids)
+ rows = connection.execute(
+ f"SELECT {selected} FROM read_parquet([{sources}]) AS scores "
+ f"JOIN changed_queries ON scores.{query_column} = changed_queries.id"
+ ).df()
+ if numeric:
+ rows[query_column] = rows[query_column].astype("Int64")
+ rows[columns[1]] = rows[columns[1]].astype("Int64")
+ return rows
+
+
+def _best_representatives(
+ scores: pd.DataFrame,
+ representatives: pd.DataFrame,
+ *,
+ threshold: int,
+ directed: bool,
+ previous_labels: pd.Series | None = None,
+) -> pd.DataFrame:
+ """Prefer a primary-threshold hit, then the directed-cover 50% fallback."""
+ if scores.empty or representatives.empty:
+ return pd.DataFrame(columns=["query_node", "label", "centroid"])
+ candidates = scores.merge(
+ representatives,
+ left_on="target_node",
+ right_on="centroid",
+ how="inner",
+ )
+ floor = min(threshold, 50) if directed else threshold
+ candidates = candidates.loc[candidates["similarity"].ge(floor)].copy()
+ if candidates.empty:
+ return pd.DataFrame(columns=["query_node", "label", "centroid"])
+ candidates["primary"] = candidates["similarity"].ge(threshold)
+ candidates["previous"] = (
+ candidates["label"].eq(candidates["query_node"].map(previous_labels))
+ if previous_labels is not None
+ else False
+ )
+ return (
+ candidates.sort_values(
+ ["query_node", "previous", "primary", "similarity", "centroid"],
+ ascending=[True, False, False, False, True],
+ )
+ .drop_duplicates("query_node")[["query_node", "label", "centroid"]]
+ .reset_index(drop=True)
+ )
+
+
+def extend_ligand_clusters(
+ *, base: Path, data_dir: Path, affected: set[str]
+) -> pd.DataFrame:
+ """Keep existing covers fixed and assign changed ligands to their centroids."""
+ annotation = pd.read_parquet(
+ data_dir / "index/annotation_table.parquet",
+ columns=[
+ "entry_pdb_id",
+ "ligand_id",
+ "ligand_smiles",
+ "ligand_is_proper",
+ "system_type",
+ ],
+ )
+ chemistry = pd.read_parquet(
+ data_dir / "fingerprints/ligand_similarity_annotations.parquet",
+ columns=["ligand_rdkit_canonical_smiles", "ligand_smiles_id"],
+ ).rename(columns={"ligand_rdkit_canonical_smiles": "ligand_smiles"})
+ annotation = annotation.merge(
+ chemistry, on="ligand_smiles", how="left", validate="many_to_one"
+ )
+ current = annotation.drop_duplicates("ligand_id").set_index("ligand_id")
+ changed = current.loc[current["entry_pdb_id"].isin(affected)]
+ proper = changed["ligand_is_proper"].fillna(False) & changed["system_type"].eq(
+ "holo"
+ )
+ changed_ids = changed.index[proper].astype(str)
+ previous = pd.read_parquet(base / "index/ligand_clusters.parquet").set_index(
+ "ligand_id"
+ )
+ result = previous.reindex(current.index.astype(str)).copy()
+ result.loc[changed.index.astype(str), :] = pd.NA
+
+ if len(changed_ids):
+ shards = {ligand_id[1:3] for ligand_id in changed_ids}
+ score_paths = [
+ data_dir / "exports/ligand_similarity_scores" / f"{shard}.parquet"
+ for shard in sorted(shards)
+ ]
+ score_paths = [path for path in score_paths if path.is_file()]
+ direct = _score_rows(
+ score_paths,
+ pd.Series(changed_ids, dtype="string"),
+ [
+ "query_ligand_id",
+ "target_ligand_id",
+ "pocket_qcov",
+ "pli_qcov",
+ "sucos_shape",
+ ],
+ numeric=False,
+ )
+ direct["sucos_shape_pocket_qcov"] = np.floor(
+ direct["sucos_shape"].astype("Int32")
+ * direct["pocket_qcov"].astype("Int32")
+ / 100
+ )
+ smiles = current["ligand_smiles_id"].dropna().astype("int64")
+ changed_smiles = smiles.loc[smiles.index.intersection(changed_ids)]
+ changed_lookup = changed_smiles.rename_axis("ligand_id").reset_index(
+ name="smiles_id"
+ )
+ chemical: dict[str, pd.DataFrame] = {}
+ for metric, directory in (
+ ("tanimoto_similarity_ecfp4_1024", "ligand_scores"),
+ ("jaccard_similarity_mhfp6_2048", "mhfp6_scores"),
+ ):
+ chemical[metric] = _score_rows(
+ sorted((data_dir / directory).glob("*.parquet")),
+ changed_smiles.reset_index(drop=True),
+ ["query_ligand_id", "target_ligand_id", metric],
+ numeric=True,
+ )
+
+ for column in previous.columns:
+ if not column.endswith(("__set_cover", "__directed_set_cover")):
+ continue
+ metric, threshold_text, _, mode = column.split("__")
+ threshold = int(threshold_text)
+ centroid_column = f"{column}__is_centroid"
+ centroids = previous.loc[
+ previous[centroid_column].fillna(False), [column]
+ ].reset_index()
+ centroids.columns = ["centroid", "label"]
+ centroids = centroids.loc[centroids["centroid"].isin(current.index)]
+ if mode == "directed_set_cover":
+ scores = direct[["query_ligand_id", "target_ligand_id", metric]].rename(
+ columns={
+ "query_ligand_id": "query_node",
+ "target_ligand_id": "target_node",
+ metric: "similarity",
+ }
+ )
+ else:
+ centroid_smiles = centroids.merge(
+ smiles.rename("smiles_id"),
+ left_on="centroid",
+ right_index=True,
+ how="inner",
+ )
+ edges = chemical[metric].merge(
+ changed_lookup,
+ left_on="query_ligand_id",
+ right_on="smiles_id",
+ how="inner",
+ )
+ scores = edges.merge(
+ centroid_smiles,
+ left_on="target_ligand_id",
+ right_on="smiles_id",
+ how="inner",
+ suffixes=("", "_centroid"),
+ )[["ligand_id", "centroid", metric]].rename(
+ columns={
+ "ligand_id": "query_node",
+ "centroid": "target_node",
+ metric: "similarity",
+ }
+ )
+ matches = _best_representatives(
+ scores,
+ centroids,
+ threshold=threshold,
+ directed=mode == "directed_set_cover",
+ previous_labels=previous[column],
+ ).set_index("query_node")
+ centroid_labels = centroids.set_index("centroid")["label"]
+ for ligand_id in changed_ids:
+ # A revised cover anchor keeps its ID until the scheduled
+ # full rebuild; the reference cover is fixed for this period.
+ if ligand_id in centroid_labels.index:
+ label = centroid_labels.at[ligand_id]
+ representative = ligand_id
+ elif ligand_id in matches.index:
+ label = matches.at[ligand_id, "label"]
+ representative = matches.at[ligand_id, "centroid"]
+ else:
+ label = f"weekly:{ligand_id}"
+ representative = ligand_id
+ result.at[ligand_id, column] = label
+ result.at[ligand_id, centroid_column] = representative == ligand_id
+ if mode == "directed_set_cover":
+ result.at[ligand_id, f"{column}__coverage_count"] = pd.NA
+ result.at[ligand_id, f"{column}__coverage_fraction"] = pd.NA
+
+ for metric, summary in CHEMICAL_CLUSTER_SUMMARY_COLUMNS.items():
+ if summary not in result:
+ continue
+ cover = f"{metric}__90__ligand__set_cover"
+ result.loc[changed_ids, summary] = result.loc[changed_ids, cover]
+ label_pdb = annotation.loc[
+ annotation["ligand_is_proper"].fillna(False)
+ & annotation["system_type"].eq("holo"),
+ ["entry_pdb_id", "ligand_id"],
+ ].merge(result[[summary]].reset_index(), on="ligand_id", how="left")
+ counts = label_pdb.groupby(summary)["entry_pdb_id"].nunique()
+ result[f"{summary}_num_pdb_ids"] = result[summary].map(counts).astype("Int32")
+ return result.reset_index().rename(columns={"index": "ligand_id"})
+
+
+def extend_interface_clusters(
+ *, base: Path, data_dir: Path, affected: set[str]
+) -> pd.DataFrame:
+ """Assign changed interfaces to the fixed whole- and half-interface covers."""
+ annotation = pd.read_parquet(
+ data_dir / "index/interface_annotation_table.parquet",
+ columns=["entry_pdb_id", "system_id"],
+ ).drop_duplicates("system_id")
+ current_ids = pd.Index(annotation["system_id"].astype(str), name="system_id")
+ changed_ids = annotation.loc[
+ annotation["entry_pdb_id"].isin(affected), "system_id"
+ ].astype(str)
+ previous = pd.read_parquet(base / "index/interface_clusters.parquet").set_index(
+ "system_id"
+ )
+ result = previous.reindex(current_ids).copy()
+ result.loc[changed_ids, :] = pd.NA
+ if changed_ids.empty:
+ return result.reset_index()
+
+ membership = pd.read_parquet(
+ data_dir / "index/interface_membership.parquet",
+ columns=[
+ "system_id",
+ "representative_system_id",
+ "side_1_half_interface_id",
+ "side_2_half_interface_id",
+ ],
+ ).set_index("system_id")
+ changed_membership = membership.loc[changed_ids]
+ changed_nodes = pd.Series(
+ pd.unique(changed_membership.to_numpy().ravel()), dtype="string"
+ ).dropna()
+ paths = [
+ data_dir / "interface_scores" / f"shard={shard}.parquet"
+ for shard in sorted({node[1:3] for node in changed_nodes})
+ ]
+ paths = [path for path in paths if path.is_file()]
+ edges = _score_rows(
+ paths,
+ changed_nodes,
+ ["query_system", "target_system", "metric", "similarity"],
+ numeric=False,
+ )
+ current_nodes = set(membership.to_numpy().ravel())
+ for column in previous.columns:
+ if not column.endswith("_directed_set_cover"):
+ continue
+ metric, threshold_text, kind = column.split("__")
+ threshold = int(threshold_text)
+ source = (
+ base
+ / "interface_sampling/directed_set_cover"
+ / f"metric={metric}"
+ / f"threshold={threshold}.parquet"
+ )
+ labels = (
+ pq.ParquetFile(source)
+ .read(columns=["system_id", "centroid_system_id", "label"])
+ .to_pandas()
+ )
+ centroids = labels.loc[
+ labels["system_id"].eq(labels["centroid_system_id"]),
+ ["system_id", "label"],
+ ].rename(columns={"system_id": "centroid"})
+ centroids = centroids.loc[centroids["centroid"].isin(current_nodes)]
+ centroid_labels = centroids.set_index("centroid")["label"]
+ score_rows = edges.loc[edges["metric"].eq(metric)].rename(
+ columns={
+ "query_system": "query_node",
+ "target_system": "target_node",
+ }
+ )[["query_node", "target_node", "similarity"]]
+ membership_column = (
+ "representative_system_id"
+ if kind == "directed_set_cover"
+ else "side_1_half_interface_id"
+ if kind == "chain_1_directed_set_cover"
+ else "side_2_half_interface_id"
+ )
+ previous_labels = pd.Series(
+ previous[column].reindex(changed_membership.index).to_numpy(),
+ index=changed_membership[membership_column].to_numpy(),
+ ).dropna()
+ previous_labels = previous_labels.loc[
+ ~previous_labels.index.duplicated(keep="first")
+ ]
+ matches = _best_representatives(
+ score_rows,
+ centroids,
+ threshold=threshold,
+ directed=True,
+ previous_labels=previous_labels,
+ ).set_index("query_node")
+ for system_id, member in changed_membership.iterrows():
+ node = member[membership_column]
+ if node in centroid_labels.index:
+ label = centroid_labels.at[node]
+ elif node in matches.index:
+ label = matches.at[node, "label"]
+ else:
+ label = f"weekly:{node}"
+ result.at[system_id, column] = label
+ return result.reset_index()
+
+
+def extend_protein_clusters(
+ *,
+ base: Path,
+ data_dir: Path,
+ affected: set[str],
+ backend: str,
+ threshold: float,
+ coverage: float,
+ threads: int,
+ scratch_dir: Path,
+) -> Path:
+ """Search changed chains against fixed protein-cluster representatives."""
+ if backend not in {"mmseqs", "foldseek"}:
+ raise ValueError(f"unknown protein clustering backend: {backend}")
+ artifact = (
+ "protein_sequence_clusters"
+ if backend == "mmseqs"
+ else "protein_structure_clusters"
+ )
+ old = pd.read_parquet(base / RELEASE_PATHS[artifact])
+ chains = pd.read_parquet(
+ data_dir / "index/entry_chains.parquet",
+ columns=["entry_pdb_id", "chain_asym_id", "chain_auth_id", "chain_sequence"],
+ filters=[("chain_receptor_type", "==", "protein")],
+ )
+ key = ["entry_pdb_id", "chain_asym_id"]
+ current = chains[key].merge(old, on=key, how="left", validate="one_to_one")
+ current["is_representative"] = current["is_representative"].astype("boolean")
+ changed = current["entry_pdb_id"].isin(affected)
+ current.loc[
+ changed,
+ [
+ "representative_entry_pdb_id",
+ "representative_chain_asym_id",
+ "is_representative",
+ ],
+ ] = pd.NA
+ current.loc[changed, "status"] = (
+ "missing_sequence" if backend == "mmseqs" else "not_in_foldseek_db"
+ )
+ query_chains = chains.loc[
+ chains["entry_pdb_id"].isin(affected) & chains["chain_auth_id"].notna()
+ ].copy()
+ representatives = old.loc[
+ old["is_representative"].astype("boolean").fillna(False), key
+ ]
+ representatives = representatives.merge(chains, on=key, how="inner")
+ representatives = representatives.loc[representatives["chain_auth_id"].notna()]
+ if backend == "mmseqs":
+ query_chains = query_chains.loc[query_chains["chain_sequence"].notna()]
+ representatives = representatives.loc[representatives["chain_sequence"].notna()]
+
+ def chain_name(row: Any) -> str:
+ if backend == "mmseqs":
+ return f"{row.entry_pdb_id}_{row.chain_auth_id}"
+ return f"pdb_0000{row.entry_pdb_id}_xyz-enrich_{row.chain_auth_id}"
+
+ query_names = {
+ chain_name(row): (row.entry_pdb_id, row.chain_asym_id)
+ for row in query_chains.itertuples(index=False)
+ }
+ target_names = {
+ chain_name(row): (row.entry_pdb_id, row.chain_asym_id)
+ for row in representatives.itertuples(index=False)
+ }
+ target_by_key = {chain_key: name for name, chain_key in target_names.items()}
+ old_by_key = old.set_index(key)[
+ ["representative_entry_pdb_id", "representative_chain_asym_id"]
+ ]
+ preferred = {
+ name: target_by_key.get(tuple(old_by_key.loc[chain_key]))
+ for name, chain_key in query_names.items()
+ if chain_key in old_by_key.index
+ }
+ base_db = data_dir / "dbs" / backend / backend
+ overlay_db = data_dir / "dbs/weekly_delta" / backend / backend
+ output = data_dir / RELEASE_PATHS[artifact]
+ lookup: dict[str, str] = {}
+ matched: dict[str, str] = {}
+ if query_names and target_names:
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ with TemporaryDirectory(prefix=f"weekly-{backend}-", dir=scratch_dir) as temp:
+ work = Path(temp)
+ query_db = (
+ overlay_db if overlay_db.with_suffix(".dbtype").is_file() else base_db
+ )
+ with Path(f"{query_db}.lookup").open() as handle:
+ for line in handle:
+ db_id, name, _ = line.rstrip("\n").split("\t", 2)
+ if name in query_names and name not in lookup:
+ lookup[name] = db_id
+ if lookup:
+ keys = work / "query.keys"
+ keys.write_text("".join(f"{db_id}\n" for db_id in lookup.values()))
+ run(
+ [
+ backend,
+ "createsubdb",
+ str(keys),
+ str(query_db),
+ str(work / "query"),
+ "--subdb-mode",
+ "0",
+ ]
+ )
+ shadowed_path = data_dir / "manifests/weekly_shadowed_entries.parquet"
+ shadowed = (
+ set(pd.read_parquet(shadowed_path, columns=["pdb_id"]).pdb_id)
+ if shadowed_path.is_file()
+ else set()
+ )
+ fields = "query,target,fident,qcov,tcov"
+ if backend == "foldseek":
+ fields += ",lddt"
+ parts = []
+ for label, target_db, names in (
+ (
+ "base",
+ base_db,
+ {
+ name
+ for name, chain in target_names.items()
+ if chain[0] not in shadowed
+ },
+ ),
+ (
+ "overlay",
+ overlay_db,
+ {
+ name
+ for name, chain in target_names.items()
+ if chain[0] in shadowed
+ },
+ ),
+ ):
+ if not names or not target_db.with_suffix(".dbtype").is_file():
+ continue
+ target_lookup: dict[str, str] = {}
+ with Path(f"{target_db}.lookup").open() as handle:
+ for line in handle:
+ db_id, name, _ = line.rstrip("\n").split("\t", 2)
+ if name in names and name not in target_lookup:
+ target_lookup[name] = db_id
+ if not target_lookup:
+ continue
+ target_keys = work / f"{label}.keys"
+ target_keys.write_text(
+ "".join(f"{db_id}\n" for db_id in target_lookup.values())
+ )
+ target = work / f"target-{label}"
+ run(
+ [
+ backend,
+ "createsubdb",
+ str(target_keys),
+ str(target_db),
+ str(target),
+ "--subdb-mode",
+ "0",
+ ]
+ )
+ hits_db = work / f"hits-{label}"
+ command = [
+ backend,
+ "search",
+ str(work / "query"),
+ str(target),
+ str(hits_db),
+ str(work / f"tmp-{label}"),
+ "-c",
+ str(coverage),
+ "--cov-mode",
+ "0",
+ "--max-seqs",
+ "10000",
+ "--threads",
+ str(threads),
+ ]
+ command += (
+ ["--min-seq-id", str(threshold)]
+ if backend == "mmseqs"
+ else [
+ "--lddt-threshold",
+ str(threshold),
+ "--alignment-type",
+ "2",
+ "-a",
+ "1",
+ ]
+ )
+ run(command)
+ hits_tsv = work / f"hits-{label}.tsv"
+ run(
+ [
+ backend,
+ "convertalis",
+ str(work / "query"),
+ str(target),
+ str(hits_db),
+ str(hits_tsv),
+ "--format-output",
+ fields,
+ "--threads",
+ str(threads),
+ ]
+ )
+ if hits_tsv.stat().st_size:
+ parts.append(
+ pd.read_csv(hits_tsv, sep="\t", names=fields.split(","))
+ )
+ hits = (
+ pd.concat(parts, ignore_index=True)
+ if parts
+ else pd.DataFrame(columns=fields.split(","))
+ )
+ quality = "fident" if backend == "mmseqs" else "lddt"
+ hits = hits.loc[
+ hits[quality].ge(threshold)
+ & hits["qcov"].ge(coverage)
+ & hits["tcov"].ge(coverage)
+ & hits["target"].isin(target_names)
+ ]
+ # Keep the prior assignment when it still passes. This makes
+ # revisions stable even if another representative scores better.
+ hits["preferred"] = hits["target"].eq(hits["query"].map(preferred))
+ best = hits.sort_values(
+ ["query", "preferred", quality, "target"],
+ ascending=[True, False, False, True],
+ ).drop_duplicates("query")
+ matched = dict(zip(best["query"], best["target"]))
+ indexed = current.set_index(key)
+ for name, chain_key in query_names.items():
+ if name not in lookup:
+ continue
+ representative = target_names.get(matched.get(name, ""), chain_key)
+ indexed.loc[chain_key, "representative_entry_pdb_id"] = representative[0]
+ indexed.loc[chain_key, "representative_chain_asym_id"] = representative[1]
+ indexed.loc[chain_key, "is_representative"] = representative == chain_key
+ indexed.loc[chain_key, "status"] = "weekly_assigned"
+ table = pa.Table.from_pandas(
+ indexed.reset_index()[SEQUENCE_CLUSTER_SCHEMA.names],
+ schema=SEQUENCE_CLUSTER_SCHEMA,
+ preserve_index=False,
+ )
+ output.parent.mkdir(parents=True, exist_ok=True)
+ staged = output.with_suffix(".weekly.parquet")
+ pq.write_table(table, staged, compression="zstd")
+ staged.replace(output)
+ return output
diff --git a/src/plinder/data/protein_clusters.py b/src/plinder/data/protein_clusters.py
new file mode 100644
index 000000000..868fea5be
--- /dev/null
+++ b/src/plinder/data/protein_clusters.py
@@ -0,0 +1,363 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Native protein-chain clustering for release builds."""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import subprocess
+from pathlib import Path
+from tempfile import TemporaryDirectory
+
+import pandas as pd
+import pyarrow as pa
+import pyarrow.parquet as pq
+
+from plinder.core.release import RELEASE_PATHS
+from plinder.data.databases import run
+
+SEQUENCE_CLUSTER_SCHEMA = pa.schema(
+ [
+ ("entry_pdb_id", pa.string()),
+ ("chain_asym_id", pa.string()),
+ ("representative_entry_pdb_id", pa.string()),
+ ("representative_chain_asym_id", pa.string()),
+ ("is_representative", pa.bool_()),
+ ("status", pa.string()),
+ ]
+)
+CLUSTER_METADATA_KEY = b"plinder_protein_clustering"
+
+
+def _clusters_are_current(output: Path, metadata: bytes) -> bool:
+ if not output.is_file():
+ return False
+ return (pq.read_schema(output).metadata or {}).get(CLUSTER_METADATA_KEY) == metadata
+
+
+def _read_assignments(
+ path: Path, expected_ids: set[str], foldseek_models: bool = False
+) -> pd.DataFrame:
+ """Require one native-tool assignment per submitted input."""
+ assignments = pd.read_csv(
+ path,
+ sep="\t",
+ header=None,
+ names=["representative", "member"],
+ dtype=str,
+ keep_default_na=False,
+ )
+ if foldseek_models:
+ for column in ("representative", "member"):
+ original = assignments[column]
+ without_model = original.str.replace(
+ r"_xyz-enrich_MODEL_[0-9]+_", "_xyz-enrich_", n=1, regex=True
+ )
+ assignments[column] = original.mask(
+ ~original.isin(expected_ids) & without_model.isin(expected_ids),
+ without_model,
+ )
+ observed = set(assignments["member"])
+ if len(assignments) != len(expected_ids) or observed != expected_ids:
+ raise ValueError(
+ "protein cluster membership differs from input: "
+ f"rows={len(assignments)}, expected={len(expected_ids)}, "
+ f"missing={sorted(expected_ids - observed)[:10]}, "
+ f"extra={sorted(observed - expected_ids)[:10]}"
+ )
+ return assignments
+
+
+def _write_cluster_table(
+ chains: pd.DataFrame,
+ assignments: pd.DataFrame,
+ output: Path,
+ metadata: bytes,
+ *,
+ missing_status: str | dict[str, str],
+) -> None:
+ representative_keys = chains[["member", "entry_pdb_id", "chain_asym_id"]].rename(
+ columns={
+ "member": "representative",
+ "entry_pdb_id": "representative_entry_pdb_id",
+ "chain_asym_id": "representative_chain_asym_id",
+ }
+ )
+ result = chains.merge(assignments, on="member", how="left", validate="one_to_one")
+ result = result.merge(
+ representative_keys, on="representative", how="left", validate="many_to_one"
+ )
+ result["is_representative"] = (
+ result["member"].eq(result["representative"]).astype("boolean")
+ )
+ missing = result["representative"].isna()
+ result.loc[missing, "is_representative"] = pd.NA
+ result["status"] = "clustered"
+ result.loc[missing, "status"] = (
+ result.loc[missing, "member"].map(missing_status)
+ if isinstance(missing_status, dict)
+ else missing_status
+ )
+ table = pa.Table.from_pandas(
+ result[SEQUENCE_CLUSTER_SCHEMA.names],
+ schema=SEQUENCE_CLUSTER_SCHEMA,
+ preserve_index=False,
+ ).replace_schema_metadata({CLUSTER_METADATA_KEY: metadata})
+ output.parent.mkdir(parents=True, exist_ok=True)
+ # Stage beside the destination so replacement is atomic across filesystems.
+ with TemporaryDirectory(prefix=f".{output.stem}-", dir=output.parent) as staging:
+ staged = Path(staging) / output.name
+ pq.write_table(table, staged, compression="zstd")
+ staged.replace(output)
+
+
+def make_protein_structure_clusters(
+ *,
+ data_dir: Path,
+ scratch_dir: Path,
+ threads: int = 4,
+ lddt: float = 0.7,
+ coverage: float = 0.8,
+ force_update: bool = False,
+) -> Path:
+ """Cluster release protein chains from the existing Foldseek search database.
+
+ The search database contains all chains parsed from the deposited mmCIFs.
+ A temporary subdatabase selects the release protein chains, avoiding a
+ second read of every source structure and per-chain mmCIF exports.
+ """
+
+ if threads < 1:
+ raise ValueError("protein clustering threads must be positive")
+ if not 0 <= lddt <= 1 or not 0 <= coverage <= 1:
+ raise ValueError("protein clustering lDDT and coverage must be between 0 and 1")
+ chains = (
+ pd.read_parquet(
+ data_dir / "index/entry_chains.parquet",
+ columns=["entry_pdb_id", "chain_asym_id", "chain_auth_id"],
+ filters=[("chain_receptor_type", "==", "protein")],
+ )
+ .sort_values(["entry_pdb_id", "chain_asym_id"])
+ .reset_index(drop=True)
+ )
+ if chains["chain_auth_id"].isna().any():
+ raise ValueError("protein chains require author chain IDs for Foldseek lookup")
+ chains["member"] = (
+ "pdb_0000"
+ + chains["entry_pdb_id"].astype(str)
+ + "_xyz-enrich_"
+ + chains["chain_auth_id"].astype(str)
+ )
+ if chains["member"].duplicated().any():
+ raise ValueError("protein chains have ambiguous Foldseek author chain IDs")
+ db = data_dir / "dbs/foldseek/foldseek"
+ lookup = Path(f"{db}.lookup")
+ source_manifest = Path(f"{db}.createdb-input.json")
+ for required in (db, lookup, source_manifest):
+ if not required.is_file():
+ raise FileNotFoundError(required)
+ digest = hashlib.sha256()
+ digest.update(
+ chains[["entry_pdb_id", "chain_asym_id", "member"]]
+ .to_json(orient="values")
+ .encode()
+ )
+ digest.update(source_manifest.read_bytes())
+ for path in (db, lookup):
+ stat = path.stat()
+ digest.update(f"{stat.st_size}:{stat.st_mtime_ns}".encode())
+ parameters = {
+ "backend": "foldseek",
+ "version": subprocess.check_output(["foldseek", "version"], text=True).strip(),
+ "lddt": lddt,
+ "coverage": coverage,
+ "coverage_mode": 0,
+ "cluster_mode": 0,
+ "single_step_clustering": True,
+ "alignment_type": 2,
+ "source_database_signature": digest.hexdigest(),
+ }
+ metadata = json.dumps(parameters, sort_keys=True).encode()
+ output = data_dir / RELEASE_PATHS["protein_structure_clusters"]
+ if not force_update and _clusters_are_current(output, metadata):
+ return output
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ with TemporaryDirectory(
+ prefix="plinder-structure-clusters-", dir=scratch_dir
+ ) as temporary:
+ work = Path(temporary)
+ expected = set(chains["member"])
+ keys: dict[str, str] = {}
+ with lookup.open() as handle:
+ for line in handle:
+ key, name, _ = line.rstrip("\n").split("\t", 2)
+ if name in expected and name not in keys:
+ # For NMR entries this is the first available model.
+ keys[name] = key
+ if keys:
+ key_file = work / "keys.tsv"
+ key_file.write_text("".join(f"{key}\n" for key in keys.values()))
+ subdb = work / "subdb"
+ run(["foldseek", "createsubdb", str(key_file), str(db), str(subdb)])
+ run(
+ [
+ "foldseek",
+ "cluster",
+ str(subdb),
+ str(work / "clusters"),
+ str(work / "tmp"),
+ "--lddt-threshold",
+ str(lddt),
+ "-c",
+ str(coverage),
+ "--cov-mode",
+ "0",
+ "--cluster-mode",
+ "0",
+ "--single-step-clustering",
+ "1",
+ "--alignment-type",
+ "2",
+ "--threads",
+ str(threads),
+ ]
+ )
+ assignment_file = work / "clusters.tsv"
+ run(
+ [
+ "foldseek",
+ "createtsv",
+ str(subdb),
+ str(subdb),
+ str(work / "clusters"),
+ str(assignment_file),
+ "--threads",
+ str(threads),
+ ]
+ )
+ assignments = _read_assignments(
+ assignment_file, set(keys), foldseek_models=True
+ )
+ else:
+ assignments = pd.DataFrame(columns=["representative", "member"])
+ _write_cluster_table(
+ chains,
+ assignments,
+ output,
+ metadata,
+ missing_status="not_in_foldseek_db",
+ )
+ return output
+
+
+def make_protein_sequence_clusters(
+ *,
+ data_dir: Path,
+ scratch_dir: Path,
+ threads: int = 4,
+ identity: float = 0.4,
+ coverage: float = 0.8,
+ force_update: bool = False,
+) -> Path:
+ """Cluster all release protein-chain sequences using MMseqs easy-cluster.
+
+ Each representative/member match must meet the identity threshold and cover
+ the requested fraction of both chains. Greedy set cover runs in single-step
+ mode. Apo and interface chains are included. Missing sequences have null
+ assignments and ``status='missing_sequence'`` in the output.
+
+ Intermediate MMseqs files live under ``scratch_dir`` and are removed after
+ the table is written. Parameters, input sequence digest, and MMseqs version
+ are stored in Parquet metadata to check whether a previous result is reusable.
+ """
+ if threads < 1:
+ raise ValueError("protein clustering threads must be positive")
+ if not 0 <= identity <= 1 or not 0 <= coverage <= 1:
+ raise ValueError(
+ "protein clustering identity and coverage must be between 0 and 1"
+ )
+ chains = (
+ pd.read_parquet(
+ data_dir / "index" / "entry_chains.parquet",
+ columns=["entry_pdb_id", "chain_asym_id", "chain_sequence"],
+ filters=[("chain_receptor_type", "==", "protein")],
+ )
+ .sort_values(["entry_pdb_id", "chain_asym_id"])
+ .reset_index(drop=True)
+ )
+ keys = ["entry_pdb_id", "chain_asym_id"]
+ # Generated FASTA IDs avoid any restrictions in native tools on source IDs.
+ # They are mapped back to the untouched entry/asym IDs before writing.
+ chains["member"] = pd.Series(
+ [f"chain_{i}" for i in range(len(chains))], dtype="string"
+ )
+ valid = chains["chain_sequence"].notna() & chains["chain_sequence"].ne("")
+ sequences = chains.loc[valid]
+ if not sequences["chain_sequence"].str.fullmatch("[A-Za-z]+").all():
+ raise ValueError(
+ "protein chain sequences must contain one-letter amino-acid codes"
+ )
+ digest = hashlib.sha256()
+ for row in chains[keys + ["chain_sequence"]].itertuples(index=False, name=None):
+ digest.update(
+ json.dumps([None if pd.isna(value) else value for value in row]).encode()
+ )
+ digest.update(b"\n")
+ parameters = {
+ "backend": "mmseqs",
+ "sequence_type": "protein",
+ "version": subprocess.check_output(["mmseqs", "version"], text=True).strip(),
+ "identity": identity,
+ "coverage": coverage,
+ "coverage_mode": 0,
+ "cluster_mode": 0,
+ "single_step_clustering": True,
+ "sequence_digest": digest.hexdigest(),
+ }
+ metadata = json.dumps(parameters, sort_keys=True).encode()
+ output = data_dir / RELEASE_PATHS["protein_sequence_clusters"]
+ if not force_update and _clusters_are_current(output, metadata):
+ return output
+ scratch_dir.mkdir(parents=True, exist_ok=True)
+ with TemporaryDirectory(
+ prefix="plinder-sequence-clusters-", dir=scratch_dir
+ ) as temporary:
+ work = Path(temporary)
+ if sequences.empty:
+ assignments = pd.DataFrame(columns=["representative", "member"])
+ else:
+ fasta = work / "chains.fasta"
+ with fasta.open("w") as handle:
+ for row in sequences.itertuples(index=False):
+ handle.write(f">{row.member}\n{row.chain_sequence}\n")
+ run(
+ [
+ "mmseqs",
+ "easy-cluster",
+ str(fasta),
+ str(work / "clusters"),
+ str(work / "tmp"),
+ "--dbtype",
+ "1",
+ "--min-seq-id",
+ str(identity),
+ "-c",
+ str(coverage),
+ "--cov-mode",
+ "0",
+ "--cluster-mode",
+ "0",
+ "--single-step-clustering",
+ "1",
+ "--threads",
+ str(threads),
+ ]
+ )
+ assignments = _read_assignments(
+ work / "clusters_cluster.tsv", set(sequences["member"])
+ )
+ _write_cluster_table(
+ chains, assignments, output, metadata, missing_status="missing_sequence"
+ )
+ return output
diff --git a/src/plinder/data/save_linked_structures.py b/src/plinder/data/save_linked_structures.py
deleted file mode 100644
index 34865cedb..000000000
--- a/src/plinder/data/save_linked_structures.py
+++ /dev/null
@@ -1,391 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-import json
-import multiprocessing
-from dataclasses import dataclass, field
-from pathlib import Path
-
-import gemmi
-import pandas as pd
-from ost import io, mol
-
-from plinder.core import PlinderSystem, scores
-from plinder.core.utils.log import setup_logger
-from plinder.data.utils.annotations.save_utils import save_cif_file
-from plinder.eval.docking import utils
-
-LOG = setup_logger(__name__)
-
-
-def get_resolution(cif_file: Path) -> float | None:
- if not cif_file.exists():
- LOG.info(f"no such file {cif_file}")
- return None
- block = gemmi.cif.read(cif_file.as_posix()).sole_block()
- res = block.find_value("_refine.ls_d_res_high")
- if not res:
- res = block.find_value("_em_3d_reconstruction.resolution")
- if res:
- return float(gemmi.cif.as_number(res))
- return None
-
-
-def get_plddt(cif_file: Path) -> float | None:
- # may only be present in pred_mmseqs so fail gracefully
- if not cif_file.exists():
- LOG.info(f"no such file {cif_file}")
- return None
- block = gemmi.cif.read(str(cif_file.as_posix())).sole_block()
- metric = block.find_value("_ma_qa_metric_global.metric_value")
- if metric:
- return float(gemmi.cif.as_number(metric))
- return None
-
-
-def superpose_to_system(
- system_mol: mol.EntityHandle,
- target_cif_file: Path,
- save_folder: Path,
- target_chain: str | None = None,
- name_mapping: dict[str, str] | None = None,
-) -> None:
- """
- Superpose a target asymmetric unit and chain to a system.
- Score the ligands as if transplanted from the system to the target
-
- Parameters
- ----------
- system_mol : mol.EntityHandle
- receptor.cif loaded into an EntityHandle
- target_cif_file : Path
- Path to the target asymmetric unit cif file
- save_folder : Path
- Folder to save the superposed target cif and pdb files
- target_chain : str
- Chain of the target asymmetric unit to superpose
- """
- # Load target asymmetric unit and chain
- target_mol, info = io.LoadMMCIF(
- target_cif_file.as_posix(), info=True, fault_tolerant=True
- )
- if target_chain is not None:
- target_mol = mol.CreateEntityFromView(
- target_mol.Select(f"chain='{target_chain}'"), True
- )
- target_mol = mol.CreateEntityFromView(target_mol.Select("water=False"), True)
-
- # Superpose target to query system
- superposition = mol.alg.Superpose(target_mol, system_mol, match="local-aln")
- LOG.info(f"target_cif {target_cif_file} rmsd: {superposition.rmsd}")
- target_mol.FixTransform()
-
- if name_mapping is None:
- assert target_chain is not None
- # Rename target_chain to A for PDB format
- target_pdb = target_mol.Copy()
- if target_chain != "A":
- edi = target_pdb.EditXCS(mol.BUFFERED_EDIT)
- edi.RenameChain(target_pdb.FindChain(target_chain), "A")
- edi.UpdateICS()
- else:
- # Rename target system according to its existing name mapping for PDB format
- target_pdb = target_mol.Copy()
- intermediate_names = {}
- edi = target_pdb.EditXCS(mol.BUFFERED_EDIT)
- for i, chain in enumerate(target_pdb.GetChainList()):
- intermediate_names[f"T{i}"] = chain.name
- edi.RenameChain(chain, f"T{i}")
- edi.UpdateICS()
- for i, chain in enumerate(target_pdb.GetChainList()):
- edi.RenameChain(chain, name_mapping[intermediate_names[chain.name]])
-
- # Save superposed target cif and pdb
- cif_file = save_folder / "superposed.cif"
- save_cif_file(target_mol, info, cif_file.stem, cif_file)
- pdb_file = save_folder / "superposed.pdb"
- io.SavePDB(target_pdb, pdb_file.as_posix())
-
-
-@dataclass
-class LinkedStructureConfig:
- num_per_system: (
- int
- ) = 5 # Maximum number of apo/pred/cross structures to keep per system
- filter_criteria: dict[str, int] = field(
- default_factory=lambda: {
- "pocket_fident": 95,
- "protein_fident_weighted_sum": 95,
- "protein_fident_qcov_weighted_sum": 80,
- "pocket_lddt": 20,
- "protein_lddt_weighted_sum": 20,
- }
- ) # Filter criteria for deciding whether to keep a linked structure (AND logic)
-
-
-def make_linked_structures_data_file(
- data_dir: Path,
- search_db: str,
- superposed_folder: Path,
- output_file: Path,
- cfg: LinkedStructureConfig = LinkedStructureConfig(),
- num_processes: int = 8,
-) -> None:
- def get_system_ligand_files(system_id: str) -> list[str]:
- system_folder = get_cif_file(data_dir, "holo", system_id).parent
- return [
- (system_folder / "ligand_files" / f"{c}.sdf").as_posix()
- for c in system_id.split("__")[-1].split("_")
- ]
-
- (superposed_folder / search_db).mkdir(exist_ok=True, parents=True)
- filters = []
- for metric, threshold in cfg.filter_criteria.items():
- filters.append([("metric", "==", metric), ("similarity", ">=", threshold)])
- output_file.parent.mkdir(exist_ok=True, parents=True)
- if (output_file.parent / f"{output_file.stem}_intermediate.parquet").is_file():
- links = pd.read_parquet(
- output_file.parent / f"{output_file.stem}_intermediate.parquet"
- )
- else:
- links = scores.query_protein_similarity(
- search_db=search_db,
- columns=["query_system", "target_system", "metric", "similarity"],
- filters=filters,
- )
- assert links is not None
- links = links.iloc[
- links.groupby(["query_system", "target_system", "metric"], observed=True)[
- "similarity"
- ].idxmax()
- ]
- links = links[
- links["query_system"].str[:4] != links["target_system"].str[:4]
- ].reset_index(drop=True)
- links = links.pivot(
- index=["query_system", "target_system"],
- columns="metric",
- values="similarity",
- ).reset_index()
- query = " and ".join([f"{m} >= {t}" for (m, t) in cfg.filter_criteria.items()])
- links = links.query(query)
- links["target_id"] = links["target_system"].map(lambda x: x.split("_")[0])
- links.to_parquet(
- output_file.parent / f"{output_file.stem}_intermediate.parquet", index=False
- )
-
- targets = set(links["target_id"])
- score_dir = search_db
- if search_db == "holo":
- score_dir = "apo" # always get resolution from ingest
- target_files = [get_cif_file(data_dir, score_dir, x) for x in targets]
- del links
-
- sort_scores = {}
- if search_db == "pred":
- func = get_plddt
- ascending = False
- else:
- func = get_resolution
- ascending = True
- with multiprocessing.get_context("spawn").Pool(num_processes) as pool:
- resolutions = pool.map(func, target_files)
- sort_scores = dict(zip(targets, resolutions))
-
- nonnull = sum((v for v in sort_scores.values() if v is not None))
- LOG.info(f"non null scores: {nonnull}")
- links = pd.read_parquet(
- output_file.parent / f"{output_file.stem}_intermediate.parquet"
- )
- links["sort_score"] = links["target_id"].map(sort_scores)
- links = (
- links[links["sort_score"].notna()]
- .sort_values("sort_score", ascending=ascending)
- .groupby("query_system")
- .head(cfg.num_per_system)
- .reset_index(drop=True)
- )
- links.rename(
- columns={"query_system": "reference_system_id", "target_system": "id"},
- inplace=True,
- )
- links["receptor_file"] = links.apply(
- lambda row: (
- superposed_folder
- / search_db
- / row.reference_system_id
- / row.id
- / "superposed.cif"
- ).as_posix(),
- axis=1,
- )
- links["ligand_files"] = links["reference_system_id"].apply(get_system_ligand_files)
- links.to_parquet(output_file, index=False)
-
-
-def get_cif_file(data_dir: Path, search_db: str, system: str) -> Path:
- if search_db == "apo":
- return (
- data_dir
- / "ingest"
- / system[1:3]
- / f"pdb_0000{system[:4]}"
- / f"pdb_0000{system[:4]}_xyz-enrich.cif.gz"
- )
- elif search_db == "pred":
- return (
- data_dir
- / "dbs"
- / "alphafold"
- / f"AF-{system.split('_')[0]}-F1-model_v4.cif"
- )
- elif search_db == "holo":
- return data_dir / "raw_entries" / system[1:3] / system / "receptor.cif"
- else:
- raise ValueError("search_db much be apo, holo or pred")
-
-
-def save_superposition(
- *,
- data_dir: Path,
- save_folder: Path,
- search_db: str,
- link: pd.Series,
- reference_system: PlinderSystem,
- overwrite: bool = False,
-) -> bool:
- if not overwrite and (save_folder / "superposed.cif").exists():
- LOG.warning(f"save_superposition: {save_folder / 'superposed.cif'} exists")
- return True
- target_cif_file = get_cif_file(data_dir, search_db, link.id)
- if not target_cif_file.exists():
- LOG.error(
- f"get_transplanted_ligand_scores_system: {link.id} cif file doesn't exist"
- )
- return False
- name_mapping, target_chain = None, None
- if search_db == "holo":
- name_mapping_file = target_cif_file.parent / "chain_mapping.json"
- if not name_mapping_file.exists():
- LOG.error(
- f"get_transplanted_ligand_scores_system: {name_mapping_file} does not exist"
- )
- return False
- with open(name_mapping_file) as f:
- name_mapping = json.load(f)
- else:
- target_chain = link.id.split("_")[-1]
- try:
- superpose_to_system(
- system_mol=reference_system.receptor_entity,
- target_cif_file=target_cif_file,
- save_folder=save_folder,
- name_mapping=name_mapping,
- target_chain=target_chain,
- )
- return True
- except Exception as e:
- LOG.error(f"save_superposition: Error in superpose_to_system: {repr(e)} {e}")
- return False
-
-
-def system_save_and_score_representative(
- link: pd.Series,
- reference_system: PlinderSystem,
- data_dir: Path,
- search_db: str,
- output_folder: Path,
- overwrite: bool = False,
-) -> None:
- save_folder = output_folder / search_db / link.reference_system_id / link.id
- save_folder.mkdir(exist_ok=True, parents=True)
- carry_on = save_superposition(
- data_dir=data_dir,
- save_folder=save_folder,
- search_db=search_db,
- link=link,
- reference_system=reference_system,
- overwrite=overwrite,
- )
- if not carry_on:
- return
-
- try:
- scores = utils.ModelScores.from_model_files(
- link.id,
- save_folder / "superposed.cif",
- link.ligand_files,
- reference_system,
- score_protein=True,
- score_posebusters=True,
- score_posebusters_full_report=True,
- ).summarize_scores()
- with open(save_folder / "scores.json", "w") as f:
- json.dump(scores, f)
- except Exception as e:
- LOG.error(
- f"system_save_and_score_representative: Error for {link.reference_system_id} against {link.id}: {e}"
- )
-
-
-def system_save_and_score_representatives(
- system: str,
- saver_input: pd.DataFrame,
- data_dir: Path,
- search_db: str,
- output_folder: Path,
- overwrite: bool = False,
-) -> None:
- try:
- reference_system = PlinderSystem(system_id=system)
- except Exception as e:
- LOG.error(
- f"system_save_and_score_representatives: Error in making reference system: {e}"
- )
- return
- saver_input.apply(
- lambda row: system_save_and_score_representative(
- row,
- reference_system=reference_system,
- data_dir=data_dir,
- search_db=search_db,
- output_folder=output_folder,
- overwrite=overwrite,
- ),
- axis=1,
- )
-
-
-def save_linked_structures(
- links_file: Path,
- data_dir: Path,
- search_db: str,
- output_folder: Path,
- num_threads: int = 8,
- overwrite: bool = False,
-) -> None:
- """
- Saves superposed linked structure files
-
- Parameters
- ----------
- links_file: Path
- The parquet file generated by filter_and_sort_scores
- data_dir: Path
- output_folder: Path
- Path to save superposed files, in the form ////superposed.cif
- num_threads: int
- Number of processes to use #TODO rename
- overwrite: bool
- Skips existing files if False
- """
- links = pd.read_parquet(links_file)
- with multiprocessing.get_context("spawn").Pool(num_threads) as p:
- p.starmap(
- system_save_and_score_representatives,
- [
- (system, group, data_dir, search_db, output_folder, overwrite)
- for system, group in links.groupby("reference_system_id")
- ],
- )
diff --git a/src/plinder/data/splits.py b/src/plinder/data/splits.py
deleted file mode 100644
index e6d9caf73..000000000
--- a/src/plinder/data/splits.py
+++ /dev/null
@@ -1,976 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from collections import Counter, defaultdict
-from copy import copy
-from dataclasses import dataclass, field
-from hashlib import md5
-from io import StringIO
-from json import dumps
-from pathlib import Path
-from typing import Any
-
-import networkit as nk
-import pandas as pd
-from omegaconf import DictConfig, ListConfig, OmegaConf
-from tqdm import tqdm
-
-from plinder.core import scores
-from plinder.core.utils.log import setup_logger
-from plinder.data import clusters
-
-LOG = setup_logger(__name__)
-
-
-@dataclass
-class GraphConfig:
- metric: str
- threshold: int # edges above this threshold are kept
- depth: int # neighbors at this depth are counted as leakage
-
-
-@dataclass
-class SplitConfig:
- graph_configs: list[GraphConfig] = field(
- default_factory=lambda: [
- GraphConfig("pli_unique_qcov", 30, 1),
- GraphConfig("protein_seqsim_weighted_sum", 30, 1),
- ]
- )
- # how many unique congeneric IDs passing quality to consider as MMS
- mms_unique_quality_count: int = 3
- # which metric to use for ligand clusters (these are added to test from removed if they are different from train/val and corresponding leaked systems are removed from train/val)
- ligand_cluster_metric: str = "tanimoto_similarity_max"
- # which threshold to use for ligand clusters
- ligand_cluster_threshold: int = 50
- # which cluster to use for ligand clusters
- ligand_cluster_cluster: str = "components"
- # what kind of cluster to use for sampling test
- test_cluster_cluster: str = "communities"
- # metric to use for sampling representatives from each test cluster
- test_cluster_metric: str = "pli_unique_qcov"
- # threshold to use for sampling representatives from each test cluster
- test_cluster_threshold: int = 50
- # directed to use for sampling representatives from each test cluster
- test_cluster_directed: bool = False
- # max number of representatives from each test cluster
- num_test_representatives: int = 2
- # max number of systems to choose per entry pdb id and unique ccd codes
- num_per_entry_pdb_id_and_unique_ccd_codes: int = 1
- # test should not be singletons
- min_test_cluster_size: int = 5
- # test should not be too unique
- min_test_leakage_count: int = 30
- # test should not be in too big communities or cause too many train cases to be removed
- max_test_leakage_count: int = 1000
- # maximum fraction of systems that can be removed due to test set selection
- max_removed_fraction: float = 0.2
- # test set size
- num_test: int = 1000
- # what kind of cluster to use for sampling val
- val_cluster_cluster: str = "components"
- # metric to use for splitting train and vcaal
- val_cluster_metric: str = "pocket_qcov"
- # threshold to use for splitting train and val
- val_cluster_threshold: int = 50
- # directed to use for splitting train and val
- val_cluster_directed: bool = False
- # max number of representatives from each val cluster
- num_val_representatives: int = 3
- # val should not be singletons
- min_val_cluster_size: int = 30
- # val set size
- num_val: int = 1000
- # test/val should not have too few or too many interactions
- min_max_pli: tuple[int, int] = (3, 50)
- # test/val should not have too few or too many pocket residues
- min_max_pocket: tuple[int, int] = (5, 100)
- # test/val should not have too small or too large ligands
- min_max_ligand: tuple[int, int] = (200, 800)
- # priority columns to use for scoring systems with a weight attached to each column
- test_additional_criteria: list[list[Any]] = field(
- default_factory=lambda: [
- ["system_pass_validation_criteria", "==", "True"],
- ["system_pass_statistics_criteria", "==", "True"],
- ["biounit_num_ligands", "<=", 20],
- ]
- )
- priority_columns: dict[str, float] = field(
- default_factory=lambda: {
- "system_ligand_has_cofactor": -40,
- "leakage_count": -1,
- }
- )
-
-
-_map = {
- "split": SplitConfig,
-}
-
-
-def _clean_to_python(cfg: Any) -> Any:
- """
- Recursively convert an omegaconf object to a plain
- python dict. Account for ListConfig and DictConfig
- in the nesting.
-
- Parameters
- ----------
- cfg : Any
- omegaconf container or primitive
- """
- if isinstance(cfg, DictConfig):
- return {k: _clean_to_python(v) for k, v in cfg.items()}
- elif isinstance(cfg, ListConfig):
- return [_clean_to_python(v) for v in cfg]
- else:
- return cfg
-
-
-def get_config_hash(config_obj: Any) -> str:
- """
- Get a unique string representation of the config
- passed to a splitting run.
-
- Parameters
- ----------
- config_obj : dict | dataclass | DictConfig
- the configuration to hash
-
- Returns
- -------
- config_hash : str
- the hash of the configuration
- """
- if isinstance(config_obj, dict):
- contents = config_obj
- elif isinstance(config_obj, DictConfig):
- contents = _clean_to_python(config_obj)
- else:
- contents = config_obj.__dict__
- config_hash = md5(dumps(contents, sort_keys=True).encode("utf-8")).hexdigest()
- return config_hash
-
-
-def get_default_config() -> DictConfig:
- default = DictConfig(
- OmegaConf.merge(
- {
- "split": OmegaConf.structured(SplitConfig()),
- }
- )
- )
- return default
-
-
-def get_config(config_contents: str) -> DictConfig:
- default = get_default_config()
- from_file = DictConfig(OmegaConf.load(StringIO(config_contents)))
- cfg = OmegaConf.merge(default, from_file)
- return DictConfig({str(k): _map[str(k)](**v) for k, v in cfg.items()})
-
-
-def find_neighbors_upto_specific_depth(
- graph: nk.graph.Graph, depth: int, target_nodes: set[int]
-) -> set[int]:
- """
- Find neighbors of a set of nodes
-
- Parameters
- ----------
- graph : nk.graph.Graph
- graph of systems
- depth : int
- search distance
- target_nodes: set[int]
- nodes of interest
-
- Returns
- -------
- Neighbors of all nodes
- """
- nodes_to_deleak = copy(target_nodes)
- neighbors = set()
- for depth in range(depth):
- next_nodes_to_deleak = {
- j for i in nodes_to_deleak for j in graph.iterNeighbors(i)
- } - nodes_to_deleak
- neighbors |= next_nodes_to_deleak
- nodes_to_deleak = next_nodes_to_deleak
- return neighbors
-
-
-def deleak_entry_nk_single(
- system_id: str,
- cluster_members: set[str],
- graphs: list[nk.graph.Graph],
- graph_configs: list[GraphConfig],
- vertex_mappings: list[dict[str, int]],
- vertex_ids: list[list[str]],
-) -> set[str]:
- leaked_systems = set(cluster_members) - {system_id}
- for graph, graph_config, system_id_to_vertex, vertex_ids_x in zip(
- graphs, graph_configs, vertex_mappings, vertex_ids
- ):
- if system_id not in system_id_to_vertex:
- continue
- leaked_neighbors = find_neighbors_upto_specific_depth(
- graph, graph_config.depth, {system_id_to_vertex[system_id]}
- )
- # those neighbors are leaky
- leaked_systems.update({vertex_ids_x[x] for x in leaked_neighbors})
- # the cluster + neighbors needs to be removed if that system is chosen
- return leaked_systems
-
-
-def prep_data_for_desired_properties(
- data_dir: Path,
- cfg: DictConfig,
- selected_systems: set[str] | None = None,
-) -> tuple[pd.DataFrame, dict[str, set[str]]]:
- """
- Load data and add annotations relevant for splitting
-
- Parameters
- ----------
- cfg : DictConfig
- splitting config
-
- Returns
- -------
- tuple[pd.DataFrame, dict[str, set[str]]]
- entries annotations, mapping of nonredundant systems to all systems
- """
- LOG.info(OmegaConf.to_yaml(cfg))
-
- all_entries_present = set(
- pd.read_csv(data_dir / "dbs" / "subdbs" / "holo_ids.csv")["pdb_id"]
- )
-
- filters = [
- ("system_type", "==", "holo"),
- ("system_num_protein_chains", "<=", 5),
- ("system_num_ligand_chains", "<=", 5),
- ("entry_pdb_id", "in", all_entries_present),
- ]
-
- # if selected_systems is not None, only load those systems
- if selected_systems is not None:
- filters.append(("system_id", "in", selected_systems))
-
- entries = pd.read_parquet(
- data_dir / "index" / "annotation_table.parquet",
- filters=filters,
- )
- LOG.info(f"loaded {entries['system_id'].nunique()} systems from annotation table")
- nonredundant_to_all = defaultdict(set)
- for system_id, unique_id in zip(entries["system_id"], entries["uniqueness"]):
- nonredundant_to_all[unique_id].add(system_id)
- entries = entries.sort_values("system_biounit_id").drop_duplicates(
- "uniqueness"
- ) # after this point there's only one row per system
- all_system_ids = set(entries["system_id"])
-
- LOG.info(f"loaded {len(all_system_ids)} nonredundant systems from annotation table")
-
- entries["system_pass_statistics_criteria"] = (
- (entries["system_proper_num_pocket_residues"] >= cfg.split.min_max_pocket[0])
- & (entries["system_proper_num_pocket_residues"] <= cfg.split.min_max_pocket[1])
- & (entries["system_proper_num_interactions"] >= cfg.split.min_max_pli[0])
- & (entries["system_proper_num_interactions"] <= cfg.split.min_max_pli[1])
- & (
- entries["system_proper_ligand_max_molecular_weight"]
- >= cfg.split.min_max_ligand[0]
- )
- & (
- entries["system_proper_ligand_max_molecular_weight"]
- <= cfg.split.min_max_ligand[1]
- )
- )
- entries["system_pass_validation_criteria"] = (
- entries["system_pass_validation_criteria"].fillna(False).astype(bool)
- )
- LOG.info(
- f"{entries['system_pass_validation_criteria'].sum()} systems pass validation criteria"
- )
- LOG.info(
- f"{entries['system_pass_statistics_criteria'].sum()} systems pass statistics criteria"
- )
- entries["proto_test"] = entries.eval(
- " & ".join(
- [f"({k} {op} {v})" for k, op, v in cfg.split.test_additional_criteria]
- )
- )
- LOG.info(
- f"{len(entries[entries['proto_test']].index)} systems pass quality, statistics, and additional filters"
- )
-
- apo_links = pd.read_parquet(
- data_dir / "links" / "kind=apo" / "links.parquet",
- columns=["reference_system_id"],
- )
- assert apo_links is not None, "apo_links is None"
- num_apo_links = apo_links.groupby("reference_system_id").size()
- LOG.info(f"num_apo_links has {len(num_apo_links)} elements")
-
- pred_links = pd.read_parquet(
- data_dir / "links" / "kind=pred" / "links.parquet",
- columns=["reference_system_id"],
- )
- assert pred_links is not None, "pred_links is None"
- num_pred_links = pred_links.groupby("reference_system_id").size()
- LOG.info(f"num_pred_links has {len(num_pred_links)} elements")
-
- entries["system_has_apo"] = entries["system_id"].map(
- lambda x: num_apo_links.get(x, 0) > 0
- )
- entries["system_has_pred"] = entries["system_id"].map(
- lambda x: num_pred_links.get(x, 0) > 0
- )
- entries["system_has_apo_or_pred"] = (
- entries["system_has_apo"] | entries["system_has_pred"]
- )
- return entries, nonredundant_to_all
-
-
-def load_graphs(
- data_dir: Path,
- systems: set[str],
- cfg: DictConfig,
-) -> tuple[list[nk.graph.Graph], list[dict[str, int]], list[list[str]]]:
- """
- Load graph into networkit graph
-
- Parameters
- ----------
- data_dir : Path,
- graph_config : GraphConfig
-
- Returns
- -------
- tuple[list[nk.graph.Graph], list[dict[str, int]]]
- similarity graph, vertex mapping
- """
- graphs = []
- vertex_mappings = []
- vertex_ids = []
- graph_dir = data_dir / "graph_queries"
- graph_dir.mkdir(exist_ok=True, parents=True)
-
- for graph_config in tqdm(cfg.split.graph_configs):
- graph_file = (
- graph_dir / f"{graph_config.metric}_{graph_config.threshold}.parquet"
- )
- if graph_file.is_file():
- df = pd.read_parquet(graph_file)
- else:
- df = scores.query_protein_similarity(
- search_db="holo",
- columns=["query_system", "target_system"],
- filters=[
- ("similarity", ">=", graph_config.threshold),
- ("metric", "==", graph_config.metric),
- ("query_system", "in", systems),
- ("target_system", "in", systems),
- ],
- )
- df.to_parquet(graph_file, index=False)
- LOG.info(f"Loaded {graph_config.metric} similarity dataframe")
- system_ids = set(df.query_system.unique()).union(set(df.target_system))
- system_ids_cat = pd.CategoricalDtype(categories=list(system_ids))
- graph, system_ids_cat = clusters.make_nk_graph(
- df, len(system_ids), system_ids_cat, directed=False, weighted=False
- )
-
- LOG.info(f"Built graph for {graph_config.metric}")
- vertex_mapping = {v: idx for idx, v in enumerate(system_ids_cat.categories)}
- del df
- graphs.append(graph)
- vertex_mappings.append(vertex_mapping)
- vertex_ids.append(list(system_ids_cat.categories))
- LOG.info(f"Built graph for {graph_config.metric}")
- LOG.info(f"Graph has {graph.numberOfNodes()} nodes")
- return graphs, vertex_mappings, vertex_ids
-
-
-def get_sampling_clusters(
- cfg: DictConfig, data_dir: Path, entries: pd.DataFrame
-) -> tuple[dict[str, set[str]], dict[str, str], pd.DataFrame, set[str]]:
- """
- Get sampling clusters
-
- Parameters
- ----------
- data_dir : Path
- entries : pd.DataFrame
-
- Returns
- -------
- tuple[
- dict[str, set], dict[str, str],
- pd.DataFrame, set[str]]
- (test-sampling-cluster-to-systems dictionary,
- test-systems-to-sampling-cluster dictionary,
- entries annotations,
- test-system-ids,
- """
- sampling_cluster_file = (
- data_dir
- / "clusters"
- / f"cluster={cfg.split.test_cluster_cluster}"
- / f"directed={cfg.split.test_cluster_directed}"
- / f"metric={cfg.split.test_cluster_metric}"
- / f"threshold={cfg.split.test_cluster_threshold}"
- / "data.parquet"
- )
- cluster_pq = pd.read_parquet(sampling_cluster_file)
- labels = dict(zip(cluster_pq["system_id"], cluster_pq["label"]))
- LOG.info(
- f"loaded {len(set(labels.values()))} {cfg.split.test_cluster_cluster} clusters for sampling"
- )
- entries["cluster"] = entries["system_id"].map(labels)
-
- cluster_to_size = Counter(entries["cluster"])
- system_to_cluster = dict(zip(entries["system_id"], entries["cluster"]))
- cluster_to_systems = defaultdict(set)
- for s in system_to_cluster:
- cluster_to_systems[system_to_cluster[s]].add(s)
-
- val_cluster_file = (
- data_dir
- / "clusters"
- / f"cluster={cfg.split.val_cluster_cluster}"
- / f"directed={cfg.split.val_cluster_directed}"
- / f"metric={cfg.split.val_cluster_metric}"
- / f"threshold={cfg.split.val_cluster_threshold}"
- / "data.parquet"
- )
- cluster_pq = pd.read_parquet(val_cluster_file)
- labels = dict(zip(cluster_pq["system_id"], cluster_pq["label"]))
- LOG.info(
- f"loaded {len(set(labels.values()))} {cfg.split.val_cluster_cluster} clusters for splitting train and val"
- )
- entries["cluster_for_val_split"] = entries["system_id"].map(labels)
-
- entries["split"] = "train"
- entries.loc[entries["proto_test"], "split"] = "proto-test"
-
- test_systems = set(
- row.system_id
- for _, row in tqdm(
- entries[entries["proto_test"]][["system_id", "cluster"]].iterrows()
- )
- if cluster_to_size[row["cluster"]] >= cfg.split.min_test_cluster_size
- )
- LOG.info(f"found {len(test_systems)} test systems")
-
- return (
- cluster_to_systems,
- system_to_cluster,
- entries,
- test_systems,
- )
-
-
-def remove_high_degree_systems(
- graphs: nk.graph.Graph,
- max_test_leakage_count: int,
- test_systems: set[str],
- vertex_mappings: list[dict[str, int]],
-) -> set[str]:
- """
- Prune system id list to remove high degree nodes
-
- Parameters
- ----------
- graphs : nk.graph.Graph
- Similarity graph
- max_test_leakage_count : int
- Maximum leakge allowed in proto-test systems
- test_systems : set[str]
- test systems selected for deleaking
- vertex_mappings : dict[str, str]
- systems id to vertex dictionary
-
- Returns
- -------
- set[str]
- test systems selected for deleaking
- """
- ignore_systems = set()
- for system_id in tqdm(test_systems):
- if (
- max(
- [
- graphs[idx].degreeOut(vertex_mapping[system_id])
- if system_id in vertex_mapping
- else 0
- for idx, vertex_mapping in enumerate(vertex_mappings)
- ]
- )
- > max_test_leakage_count
- ):
- ignore_systems.add(system_id)
- test_systems = test_systems.difference(ignore_systems)
- LOG.info(
- f"found {len(test_systems)} test systems after removing by first degree neighbor leakage count"
- )
- return test_systems
-
-
-def prioritize_test_sample(
- cfg: DictConfig,
- entries: pd.DataFrame,
- system_id_to_leakage: dict[str, set[str]],
- test_systems: set[str],
- cluster_to_systems: dict[str, set[str]],
- system_to_cluster: dict[str, str],
-) -> tuple[dict[str, set[str]], set[str]]:
- """
- Prioritize test systems to ensure selected clusters met a certain criteria.
- - Minimum cluster size and doesn't have more than a \
- specified number of potential leaky systems.
- - We are prioritizing representatives that have have:
- - high apo links
- - has binding affinity
- - high mms links
- - low leaky count
-
- Parameters
- ----------
- cfg : DictConfig
- Config dictionary
- entries : pd.DataFrame
- entries annotation
- system_id_to_leakage : dict[str, set[str]]
- test system id mapped to leakage
- test_systems : set[str]
- test system ids
- cluster_to_systems : dict[str, set[str]]
- cluster ids mapped to sets of system ids
- system_to_cluster : dict[str, str]
- system id mapped to cluster ids
-
- Returns
- -------
- tuple[dict[str, set[str]], set[str]]
- new_system_id_cluster_dict, test_system_ids
- system ids mapped to cluster of nodes marked for removal, test system ids
- """
- entries["leakage_count"] = entries["system_id"].map(
- lambda x: len(
- system_id_to_leakage.get(x, cluster_to_systems[system_to_cluster[x]])
- )
- )
- test_data = entries[entries["system_id"].isin(test_systems)]
-
- test_data = test_data[
- (test_data["leakage_count"] >= cfg.split.min_test_leakage_count)
- & (test_data["leakage_count"] <= cfg.split.max_test_leakage_count)
- ]
- LOG.info(
- f"found {len(set(test_data['system_id']))} test systems after removing by second pass neighbor leakage count"
- )
-
- test_data["system_score"] = (
- test_data[list(cfg.split.priority_columns)]
- .mul(cfg.split.priority_columns)
- .sum(axis=1)
- )
- test_data["cluster_score"] = test_data.groupby("cluster")["system_score"].transform(
- "max"
- )
- test_data = (
- test_data.sort_values("system_score", ascending=False)
- .groupby(["entry_pdb_id", "system_proper_unique_ccd_codes"])
- .head(cfg.split.num_per_entry_pdb_id_and_unique_ccd_codes)
- .reset_index(drop=True)
- )
- test_data = (
- test_data.sort_values(
- ["cluster_score", "system_score"],
- ascending=[False, False],
- )
- .groupby("cluster", sort=False)
- .head(cfg.split.num_test_representatives)
- .groupby("cluster")
- .apply(lambda x: x.sort_values("system_score", ascending=False))
- .reset_index(drop=True)
- )
- all_test_system_ids = test_data["system_id"].tolist()
- max_removed = int(cfg.split.max_removed_fraction * entries["system_id"].nunique())
- test_system_ids: set[str] = set()
- to_remove: set[str] = set()
- for x in all_test_system_ids:
- if len(test_system_ids) < cfg.split.num_test:
- test_system_ids.add(x)
- to_remove |= system_id_to_leakage.get(x, set())
- if len(to_remove) > max_removed:
- remaining = set(all_test_system_ids).difference(test_system_ids)
- test_clusters = set(system_to_cluster[x] for x in test_system_ids)
- for x in remaining:
- if system_to_cluster[x] in test_clusters:
- test_system_ids.add(x)
- break
- LOG.info(
- f"test_data after max_test of {cfg.split.num_test}: {len(test_system_ids)}"
- )
- return entries, test_system_ids
-
-
-def assign_split_membership(
- cfg: DictConfig,
- data_dir: Path,
- entries: pd.DataFrame,
- nonredundant_to_all: dict[str, set[str]],
- test_system_ids: set[str],
- system_id_to_leakage: dict[str, set[str]],
- split_path: Path,
-) -> pd.DataFrame:
- """
- Assign system ids to train, val, test and \
- marked others for removal.
-
-
- Parameters
- ----------
- data_dir : Path
- Data directory
- entries : pd.DataFrame
- entries annotations
- mms_df : pd.DataFrame
- matched-molecular series dataframe
- test_system_ids : set[str]
- set of test systems ids
- system_id_to_leakage : dict[str, set[str]]
- Dictionary of test systems mapped to leaked system
- relpath : str
- Relative path to save splits
-
- Returns
- -------
- pd.DataFrame
- Dataframe of splits
- """
- LOG.info(f"have {len(test_system_ids)} test system IDs")
- pdb_id_to_systems = (
- entries.groupby("entry_pdb_id")["system_id"].apply(set).to_dict()
- )
-
- remove_from_train = (
- set.union(
- *(
- system_id_to_leakage.get(system_id, set())
- for system_id in test_system_ids
- )
- )
- - test_system_ids
- )
- LOG.info(f"found {len(remove_from_train)} entries to remove from train")
-
- # Add back MMS of test systems present in remove_from_train
- quality_test_removed = (test_system_ids.union(remove_from_train)).intersection(
- entries[entries["system_pass_validation_criteria"]]["system_id"]
- )
- mms_df = pd.read_parquet(
- data_dir / "mmp/plinder_mmp_series.parquet",
- filters=[("system_id", "in", quality_test_removed)],
- )
- mms_df["system_score"] = mms_df.groupby("system_id")["congeneric_id"].transform(
- lambda x: x.nunique()
- )
- system_plindex = entries.drop_duplicates(subset=["system_id"]).reset_index(
- drop=True
- )
- system_to_entry_pdb_id = dict(
- zip(system_plindex["system_id"], system_plindex["entry_pdb_id"])
- )
- mms_df["entry_pdb_id"] = mms_df["system_id"].map(system_to_entry_pdb_id)
- system_to_ligand_ccd_codes = dict(
- zip(
- system_plindex["system_id"],
- system_plindex["system_proper_unique_ccd_codes"],
- )
- )
- mms_df["system_proper_unique_ccd_codes"] = mms_df["system_id"].map(
- system_to_ligand_ccd_codes
- )
-
- # TODO: should we better count for MMS uniqueness only when
- # system_proper_unique_ccd_codes is different and ignore entry_pdb_id here?
- mms_df["unique_id"] = (
- mms_df["entry_pdb_id"] + "__" + mms_df["system_proper_unique_ccd_codes"]
- )
- mms_count = mms_df.groupby("congeneric_id")["unique_id"].nunique()
- mms_df["mms_unique_count_in_test"] = mms_df["congeneric_id"].map(mms_count)
- good_mms_systems = set(
- mms_df[
- mms_df["mms_unique_count_in_test"] >= cfg.split.mms_unique_quality_count
- ]["system_id"]
- )
- test_congeneric_ids = set(
- mms_df[(mms_df["system_id"].isin(test_system_ids))]["congeneric_id"]
- )
- test_ccd_codes = set(
- entries[entries["system_id"].isin(test_system_ids)][
- "system_proper_unique_ccd_codes"
- ]
- )
- to_add = set(
- mms_df[
- (mms_df["congeneric_id"].isin(test_congeneric_ids))
- & (~mms_df["system_proper_unique_ccd_codes"].isin(test_ccd_codes))
- ]
- .sort_values("system_score", ascending=False)
- .groupby("unique_id")
- .head(cfg.split.num_per_entry_pdb_id_and_unique_ccd_codes)
- .reset_index(drop=True)["system_id"]
- ).intersection(good_mms_systems)
- LOG.info(f"found {len(to_add)} MMS systems to add back")
- test_system_ids |= to_add
- remove_from_train = (
- set.union(
- *(
- system_id_to_leakage.get(system_id, set())
- for system_id in test_system_ids
- )
- )
- - test_system_ids
- )
- LOG.info(
- f"found {len(remove_from_train)} entries to remove from train after adding back MMS"
- )
-
- entries["split"] = "train"
- entries.loc[entries["system_id"].isin(test_system_ids), "split"] = "test"
- entries.loc[
- (entries["split"] == "train") & entries["system_id"].isin(remove_from_train),
- "split",
- ] = "removed"
-
- # Group all train systems by their validation clusters
- entries["system_score_val"] = (
- 2 * entries["system_pass_validation_criteria"]
- + entries["system_pass_statistics_criteria"]
- )
- train_val_clusters = (
- entries[entries["split"] == "train"]
- .sort_values("system_score_val", ascending=False)
- .groupby("cluster_for_val_split")["system_id"]
- .apply(list)
- .to_dict()
- )
- passing_statistics_criteria = set(
- entries[entries["system_pass_statistics_criteria"]]["system_id"]
- )
- passing_validation_criteria = set(
- entries[entries["system_pass_validation_criteria"]]["system_id"]
- )
- # Sort clusters by size
- cluster_order = sorted(train_val_clusters, key=lambda x: len(train_val_clusters[x]))
-
- # Find the starting index for clusters that meet the minimum size
- start_cluster_index = next(
- (
- i
- for i, x in enumerate(cluster_order)
- if len(train_val_clusters[x]) >= cfg.split.min_val_cluster_size
- ),
- len(cluster_order),
- )
-
- val_system_ids = []
- remove_ids = set()
-
- for cluster in cluster_order[start_cluster_index:]:
- systems = train_val_clusters[cluster]
-
- if all(x not in passing_validation_criteria for x in systems) or all(
- x not in passing_statistics_criteria for x in systems
- ):
- # If we don't have enough valid systems to meet the minimum size, skip this cluster
- continue
-
- val_system_ids.extend(systems[: cfg.split.num_val_representatives])
-
- # Remove all systems with this cluster ID from train
- remove_ids.update(systems)
-
- if len(val_system_ids) >= cfg.split.num_val:
- break
- remove_ids -= set(val_system_ids)
- LOG.info(
- f"val_system_ids after max_val of {cfg.split.num_val}: {len(val_system_ids)}"
- )
-
- # Remove val PDB IDs
- for x in val_system_ids:
- remove_ids |= pdb_id_to_systems[x.split("__")[0]]
- remove_ids -= set(val_system_ids)
-
- entries.loc[entries["system_id"].isin(set(val_system_ids)), "split"] = "val"
- LOG.info(f"Additional {len(remove_ids)} to be removed due to val")
- entries.loc[entries["system_id"].isin(remove_ids), "split"] = "removed"
-
- # Add back systems in removed with novel ligands compared to train
- train_val_ligand_clusters = set(
- entries[entries["split"].isin(["train", "val"])][
- f"{cfg.split.ligand_cluster_metric}__{cfg.split.ligand_cluster_threshold}__weak__component"
- ]
- )
- removed_ligand_clusters = set(
- entries[
- (entries["split"] == "removed")
- & (entries["system_pass_validation_criteria"])
- & (entries["system_pass_statistics_criteria"])
- ][
- f"{cfg.split.ligand_cluster_metric}__{cfg.split.ligand_cluster_threshold}__weak__component"
- ]
- )
- novel_ligand_clusters = removed_ligand_clusters - train_val_ligand_clusters
- test_ccd_codes = set(
- entries[entries["split"] == "test"]["system_proper_unique_ccd_codes"]
- )
- # TODO: should we group here only by "system_proper_unique_ccd_codes"
- # to only be adding a novel ligand once?
- # Here it can add as many as there are but from different PDB?
- novel_ligand_systems = set(
- entries[
- entries[
- f"{cfg.split.ligand_cluster_metric}__{cfg.split.ligand_cluster_threshold}__weak__component"
- ].isin(novel_ligand_clusters)
- & (~entries["system_proper_unique_ccd_codes"].isin(test_ccd_codes))
- & (entries["split"] == "removed")
- & (entries["system_pass_validation_criteria"])
- & (entries["system_pass_statistics_criteria"])
- ]
- .groupby(["entry_pdb_id", "system_proper_unique_ccd_codes"])
- .head(cfg.split.num_per_entry_pdb_id_and_unique_ccd_codes)
- .groupby("cluster")
- .head(cfg.split.num_test_representatives)
- .reset_index(drop=True)["system_id"]
- )
- LOG.info(f"Found {len(novel_ligand_systems)} novel ligand systems in removed")
- to_remove_from_train_val: set[str] = set()
- to_add_to_test: set[str] = set()
- for x in novel_ligand_systems:
- if x in system_id_to_leakage:
- to_remove_from_train_val.update(system_id_to_leakage[x])
- to_add_to_test.add(x)
- to_remove_from_train_val = to_remove_from_train_val.intersection(
- set(entries[entries["split"].isin(["train", "val"])]["system_id"])
- )
- LOG.info(
- f"Found {len(to_add_to_test)} systems to add to test and {len(to_remove_from_train_val)} systems to remove from train/val due to novel ligands"
- )
- entries.loc[entries["system_id"].isin(to_add_to_test), "split"] = "test"
- entries.loc[
- (entries["system_id"].isin(to_remove_from_train_val))
- & (entries["split"].isin(["train", "val"])),
- "split",
- ] = "removed"
-
- final = entries[
- [
- "system_id",
- "uniqueness",
- "split",
- "cluster",
- "cluster_for_val_split",
- "system_pass_validation_criteria",
- "system_pass_statistics_criteria",
- "system_proper_num_ligand_chains",
- "system_proper_num_pocket_residues", # "system_proper_pocket_num_residues",
- "system_proper_num_interactions",
- "system_proper_ligand_max_molecular_weight",
- "system_has_binding_affinity",
- "system_has_apo_or_pred",
- ]
- ].reset_index(drop=True)
- mask = final["split"] == "train"
- final.loc[mask, "system_id"] = final.loc[mask, "uniqueness"].map(
- nonredundant_to_all
- )
- final.loc[~mask, "system_id"] = final.loc[~mask, "system_id"].map(lambda x: [x])
- final = final.explode("system_id").sort_values("system_id")
- for k, v in final.value_counts("split").items():
- LOG.info(f"final system splits {k} {v}")
- LOG.info(f"writing out final system splits {len(final.index)} records")
- final.to_parquet(split_path, index=False)
- return final
-
-
-def split(
- *,
- data_dir: Path,
- cfg: DictConfig,
- relpath: str,
- selected_systems: set[str] | None = None,
-) -> pd.DataFrame:
- OmegaConf.save(config=cfg, f=data_dir / "splits" / f"split_{relpath}.yaml")
-
- entries, nonredundant_to_all = prep_data_for_desired_properties(
- data_dir=data_dir, cfg=cfg, selected_systems=selected_systems
- )
-
- (
- cluster_to_systems,
- system_to_cluster,
- entries,
- test_systems,
- ) = get_sampling_clusters(cfg=cfg, data_dir=data_dir, entries=entries)
-
- pdb_id_to_systems = (
- entries.groupby("entry_pdb_id")["system_id"].apply(set).to_dict()
- )
- LOG.info(f"loaded {len(pdb_id_to_systems)} pdb_id to system_id mappings")
-
- graphs, vertex_mappings, vertex_ids = load_graphs(
- data_dir=data_dir, systems=set(entries["system_id"]), cfg=cfg
- )
- low_degree_test_systems = remove_high_degree_systems(
- graphs=graphs,
- max_test_leakage_count=cfg.split.max_test_leakage_count,
- test_systems=test_systems,
- vertex_mappings=vertex_mappings,
- )
- system_id_to_leakage = {}
- for system_id in tqdm(low_degree_test_systems):
- system_id_to_leakage[system_id] = deleak_entry_nk_single(
- system_id=system_id,
- cluster_members=cluster_to_systems[system_to_cluster[system_id]],
- graphs=graphs,
- graph_configs=cfg.split.graph_configs,
- vertex_mappings=vertex_mappings,
- vertex_ids=vertex_ids,
- ).union(pdb_id_to_systems[system_id.split("__")[0]]) - set([system_id])
-
- entries, test_system_ids = prioritize_test_sample(
- cfg=cfg,
- entries=entries,
- system_id_to_leakage=system_id_to_leakage,
- test_systems=low_degree_test_systems,
- cluster_to_systems=cluster_to_systems,
- system_to_cluster=system_to_cluster,
- )
-
- for system_id in test_system_ids:
- if system_id not in system_id_to_leakage:
- system_id_to_leakage[system_id] = deleak_entry_nk_single(
- system_id=system_id,
- cluster_members=cluster_to_systems[system_to_cluster[system_id]],
- graphs=graphs,
- graph_configs=cfg.split.graph_configs,
- vertex_mappings=vertex_mappings,
- vertex_ids=vertex_ids,
- ).union(pdb_id_to_systems[system_id.split("__")[0]]) - set([system_id])
- (data_dir / "splits").mkdir(exist_ok=True)
- split_path = data_dir / "splits" / f"split_{relpath}.parquet"
- return assign_split_membership(
- cfg=cfg,
- data_dir=data_dir,
- entries=entries,
- nonredundant_to_all=nonredundant_to_all,
- test_system_ids=test_system_ids,
- system_id_to_leakage=system_id_to_leakage,
- split_path=split_path,
- )
diff --git a/src/plinder/data/structure/__init__.py b/src/plinder/data/structure/__init__.py
deleted file mode 100644
index 2bc0efc66..000000000
--- a/src/plinder/data/structure/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
diff --git a/src/plinder/data/structure/atoms.py b/src/plinder/data/structure/atoms.py
deleted file mode 100644
index 1998efc5a..000000000
--- a/src/plinder/data/structure/atoms.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from plinder.core.utils.log import setup_logger
-
-LOG = setup_logger(__name__)
-
-LOG.warning(
- "This module is deprecated. Please use plinder.core.structure.atoms instead."
-)
diff --git a/src/plinder/data/structure/contacts.py b/src/plinder/data/structure/contacts.py
deleted file mode 100644
index 665d4d77a..000000000
--- a/src/plinder/data/structure/contacts.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from plinder.core.utils.log import setup_logger
-
-LOG = setup_logger(__name__)
-
-LOG.warning(
- "This module is deprecated. Please use plinder.core.structure.contacts instead."
-)
diff --git a/src/plinder/data/utils/__init__.py b/src/plinder/data/utils/__init__.py
deleted file mode 100644
index 2bc0efc66..000000000
--- a/src/plinder/data/utils/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
diff --git a/src/plinder/data/utils/annotations/__init__.py b/src/plinder/data/utils/annotations/__init__.py
deleted file mode 100644
index 2bc0efc66..000000000
--- a/src/plinder/data/utils/annotations/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
diff --git a/src/plinder/data/utils/annotations/aggregate_annotations.py b/src/plinder/data/utils/annotations/aggregate_annotations.py
deleted file mode 100644
index cadaf4ccf..000000000
--- a/src/plinder/data/utils/annotations/aggregate_annotations.py
+++ /dev/null
@@ -1,1484 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-import gzip
-import re
-import typing as ty
-from collections import Counter, defaultdict
-from dataclasses import dataclass
-from functools import cached_property
-from pathlib import Path
-
-import networkx as nx
-import pandas as pd
-from ost import io, mol
-from PDBValidation.ValidationFactory import ValidationFactory
-from plip.basic import config
-from posebusters import PoseBusters
-from pydantic import BeforeValidator, Field
-from rdkit import RDLogger
-
-from plinder.core.utils.config import get_config
-from plinder.core.utils.log import setup_logger
-from plinder.data.utils.annotations.get_ligand_validation import (
- EntryValidation,
- ResidueListValidation,
- ResidueValidationThresholds,
-)
-from plinder.data.utils.annotations.interaction_utils import (
- get_covalent_connections,
- get_symmetry_mate_contacts,
-)
-from plinder.data.utils.annotations.interface_gap import annotate_interface_gaps
-from plinder.data.utils.annotations.ligand_utils import Ligand, validate_chain_residue
-from plinder.data.utils.annotations.protein_utils import (
- Chain,
- detect_ligand_chains,
- get_chain_external_mappings,
- get_entry_info,
- read_mmcif_container,
-)
-from plinder.data.utils.annotations.save_utils import (
- save_cif_file,
- save_ligands,
- save_pdb_file,
-)
-from plinder.data.utils.annotations.utils import DocBaseModel
-
-LOG = setup_logger(__name__)
-RDLogger.DisableLog("rdApp.*")
-ECOD_DATA = None
-
-# Ignore Biolip artifacts
-config.biolip_list = []
-
-
-SymmetryMateContacts = ty.Annotated[
- dict[tuple[str, int], dict[tuple[str, int], set[int]]],
- BeforeValidator(validate_chain_residue),
- Field(default_factory=dict),
-]
-
-
-def remove_alphabets(x: str) -> int:
- """Turn alphanumeric to integer
-
- Parameters
- ----------
- x : str
- Alphanumeric string
-
- Returns
- -------
- int
- """
-
- return int(re.sub("[^0-9]", "", x))
-
-
-@dataclass
-class QualityCriteria:
- max_entry_resolution: float = 3.5
- max_entry_r: float = 0.4
- max_entry_rfree: float = 0.45
- max_entry_r_minus_rfree: float = 0.05
- ligand_max_num_unresolved_heavy_atoms: int = 0
- ligand_max_alt_count: int = 1
- ligand_min_average_occupancy: float = 0.8
- ligand_min_average_rscc: float = 0.8
- ligand_max_average_rsr: float = 0.3
- ligand_max_percent_outliers_clashes: float = 0
- ligand_max_fraction_atoms_with_crystal_contacts: float = 0
- pocket_max_num_unresolved_heavy_atoms: int = 0
- pocket_max_alt_count: int = 1
- pocket_min_average_occupancy: float = 0.8
- pocket_min_average_rscc: float = 0.8
- pocket_max_average_rsr: float = 0.3
- pocket_max_percent_outliers_clashes: int = 100
-
-
-class System(DocBaseModel):
- pdb_id: str = Field(description="__PDB ID")
- biounit_id: str = Field(description="Biounit ID")
- ligands: list[Ligand] = Field(description="__List of Ligands in a systems")
- ligand_validation: ResidueListValidation | None = Field(
- default=None,
- description="__Validation object for the ligand residues in the system",
- )
- pocket_validation: ResidueListValidation | None = Field(
- default=None, description="__Validation object for the system's pocket residues"
- )
- pass_criteria: bool | None = Field(
- default=None, description="__Passes quality criteria"
- ) # TODO: remove as attribute and have as function
-
- """
- This class defines a system which includes a protein-ligand complex
- and it's neighboring ligands and protein residues
-
- """
-
- def proper_ligands(self) -> list[Ligand]:
- return [ligand for ligand in self.ligands if ligand.is_proper]
-
- @cached_property
- def protein_chains_asym_id(self) -> list[str]:
- """
- Interacting protein chains of the system
- """
- return sorted(
- set(
- chain
- for ligand in self.ligands
- for chain in ligand.protein_chains_asym_id
- )
- )
-
- @cached_property
- def id_no_biounit(self) -> str:
- """
- ID of the system without the biounit
- """
- return "__".join(
- [
- self.pdb_id,
- "_".join(x.split(".")[1] for x in self.protein_chains_asym_id),
- "_".join(x.split(".")[1] for x in self.ligand_chains),
- ]
- )
-
- @cached_property
- def ligand_chains(self) -> list[str]:
- """
- Ligand chains of the system
- """
- return [f"{ligand.instance}.{ligand.asym_id}" for ligand in self.ligands]
-
- @cached_property
- def num_pocket_residues(self) -> int:
- """
- Number of pocket residues of the system
- """
- return sum(l.num_pocket_residues for l in self.ligands)
-
- @cached_property
- def proper_num_pocket_residues(self) -> int:
- """
- Number of pocket residues of the system excluding ions and artifacts
- """
- return sum(l.num_pocket_residues for l in self.proper_ligands())
-
- @cached_property
- def num_interactions(self) -> int:
- """
- Number of interactions of the system
- """
- return sum(l.num_interactions for l in self.ligands)
-
- @cached_property
- def proper_num_interactions(self) -> int:
- """
- Number of interactions of the system
- """
- return sum(l.num_interactions for l in self.proper_ligands())
-
- @cached_property
- def num_unique_interactions(self) -> int:
- """
- Number of unique interactions of the system
- """
- return sum(l.num_unique_interactions for l in self.ligands)
-
- @cached_property
- def proper_num_unique_interactions(self) -> int:
- """
- Number of unique interactions of the system
- """
- return sum(l.num_unique_interactions for l in self.proper_ligands())
-
- @cached_property
- def num_covalent_ligands(self) -> int:
- """
- Number of covalent ligands of the system
- """
- return sum(ligand.is_covalent for ligand in self.ligands)
-
- @cached_property
- def proper_num_covalent_ligands(self) -> int:
- """
- Number of covalent ligands of the system
- """
- return sum(ligand.is_covalent for ligand in self.proper_ligands())
-
- @cached_property
- def id(self) -> str:
- """
- ID of the system
- """
- return "__".join(
- [
- self.pdb_id,
- self.biounit_id,
- "_".join(self.protein_chains_asym_id),
- "_".join(self.ligand_chains),
- ]
- )
-
- @cached_property
- def system_type(self) -> str:
- """
- Type of the system (one of: holo, ion, artifact)
- """
- if any(not l.is_ion and not l.is_artifact for l in self.ligands):
- return "holo"
- elif any(l.is_ion for l in self.ligands):
- return "ion"
- else:
- return "artifact"
-
- @cached_property
- def has_kinase_inhibitor(self) -> bool:
- """
- Whether the system has a kinase inhibitor
- """
- return any(l.is_kinase_inhibitor for l in self.ligands)
-
- @cached_property
- def has_binding_affinity(self) -> bool:
- """
- Whether any ligand in the system has a binding affinity from BindingDB
- """
- return any(l.binding_affinity is not None for l in self.ligands)
-
- @cached_property # TODO: change this to exclude residues only interacting with artifacts or ions
- def pocket_residues(self) -> dict[str, dict[int, str]]:
- """
- __Pockets residues of the system
- """
- all_residues: dict[str, dict[int, str]] = defaultdict(dict)
- for ligand in self.ligands:
- ligand_pocket_residues = ligand.pocket_residues
- for chain in ligand_pocket_residues:
- all_residues[chain].update(ligand_pocket_residues[chain])
- return all_residues
-
- @cached_property
- def interactions(self) -> dict[str, dict[int, list[str]]]:
- """
- __Interactions of the system
- """
- all_interactions: dict[str, dict[int, list[str]]] = defaultdict(
- lambda: defaultdict(list)
- )
- for ligand in self.ligands:
- if ligand.is_artifact:
- continue
- for chain in ligand.interactions:
- for residue in ligand.interactions[chain]:
- all_interactions[chain][residue].extend(
- ligand.interactions[chain][residue]
- )
- return all_interactions
-
- @cached_property
- def interactions_counter(self) -> dict[str, dict[int, ty.Counter[str]]]:
- """
- __Counter of interactions of the system
- """
- interactions_counter: dict[str, dict[int, ty.Counter[str]]] = {}
- for chain in self.interactions:
- interactions_counter[chain] = {}
- for residue in self.interactions[chain]:
- interactions_counter[chain][residue] = Counter(
- self.interactions[chain][residue]
- )
- return interactions_counter
-
- def format_chains(
- self,
- chain_type: str,
- chains: dict[str, Chain],
- ) -> dict[str, ty.Any]:
- if chain_type == "protein":
- sub_chains = self.protein_chains_asym_id
- elif chain_type == "ligand":
- sub_chains = self.ligand_chains
- else:
- raise ValueError(f"chain_type={chain_type} not understood")
- sub_chain_list = [ch.split(".") for ch in sub_chains]
-
- sub_chains_data = [
- chains[c].format(int(instance)) for instance, c in sub_chain_list
- ]
-
- if len(sub_chains_data) == 0:
- return {}
- data: dict[str, list[str]] = defaultdict(list)
- for sub_chain in sub_chains_data:
- for key in sub_chain:
- data[f"system_{chain_type}_chains_{key}"].append(sub_chain[key])
- return data
-
- @cached_property
- def num_protein_chains(self) -> int:
- """
- Number of interacting protein chains of the system
- """
- return len(self.protein_chains_asym_id)
-
- @cached_property
- def proper_num_protein_chains(self) -> int:
- """
- Number of interacting protein chains of the system excluding ions and artifacts
- """
- return len(
- set(
- chain
- for ligand in self.proper_ligands()
- for chain in ligand.protein_chains_asym_id
- )
- )
-
- @cached_property
- def num_ligand_chains(self) -> int:
- """
- Number of ligand chains of the system
- """
- return len(self.ligands)
-
- @cached_property
- def proper_num_ligand_chains(self) -> int:
- """
- Number of ligand chains of the system excluding ions and artifacts
- """
- return len(self.proper_ligands())
-
- def format_validation(
- self, entry_pass_criteria: bool | None, criteria: QualityCriteria
- ) -> dict[str, ty.Any]:
- data = {}
- if self.ligand_validation:
- ligand_validation = self.ligand_validation.format()
- data.update({f"system_ligand_{k}": v for k, v in ligand_validation.items()})
- if self.pocket_validation:
- pocket_validation = self.pocket_validation.format()
- data.update({f"system_pocket_{k}": v for k, v in pocket_validation.items()})
- if (
- self.pocket_validation is None
- or self.ligand_validation is None
- or entry_pass_criteria is None
- or not entry_pass_criteria
- or data["system_ligand_validation_max_alt_count"] is None
- or data["system_ligand_validation_average_occupancy"] is None
- or data["system_ligand_validation_average_rscc"] is None
- or data["system_ligand_validation_average_rsr"] is None
- or data["system_ligand_validation_percent_outliers_clashes"] is None
- or data["system_pocket_validation_num_unresolved_heavy_atoms"] is None
- or data["system_pocket_validation_max_alt_count"] is None
- or data["system_pocket_validation_average_occupancy"] is None
- or data["system_pocket_validation_average_rscc"] is None
- or data["system_pocket_validation_average_rsr"] is None
- or data["system_pocket_validation_percent_outliers_clashes"] is None
- ):
- self.pass_criteria = False
- else:
- """
- Quality criteria for the system
- """
- quality = [
- # LIGAND
- self.num_unresolved_heavy_atoms is not None
- and self.num_unresolved_heavy_atoms
- <= self.num_covalent_ligands
- + criteria.ligand_max_num_unresolved_heavy_atoms,
- data["system_ligand_validation_max_alt_count"]
- <= criteria.ligand_max_alt_count,
- data["system_ligand_validation_average_occupancy"]
- >= criteria.ligand_min_average_occupancy,
- data["system_ligand_validation_average_rscc"]
- >= criteria.ligand_min_average_rscc,
- data["system_ligand_validation_average_rsr"]
- <= criteria.ligand_max_average_rsr,
- data["system_ligand_validation_percent_outliers_clashes"]
- <= criteria.ligand_max_percent_outliers_clashes,
- self.fraction_atoms_with_crystal_contacts is not None
- and self.fraction_atoms_with_crystal_contacts
- <= criteria.ligand_max_fraction_atoms_with_crystal_contacts,
- # POCKET
- data["system_pocket_validation_num_unresolved_heavy_atoms"]
- <= criteria.pocket_max_num_unresolved_heavy_atoms,
- data["system_pocket_validation_max_alt_count"]
- <= criteria.pocket_max_alt_count,
- data["system_pocket_validation_average_occupancy"]
- >= criteria.pocket_min_average_occupancy,
- data["system_pocket_validation_average_rscc"]
- >= criteria.pocket_min_average_rscc,
- data["system_pocket_validation_average_rsr"]
- <= criteria.pocket_max_average_rsr,
- data["system_pocket_validation_percent_outliers_clashes"]
- <= criteria.pocket_max_percent_outliers_clashes,
- ]
- self.pass_criteria = all(quality)
- data["system_pass_validation_criteria"] = self.pass_criteria
- return data
-
- def format(
- self,
- chains: dict[str, Chain],
- entry_pass_criteria: bool | None,
- criteria: QualityCriteria = QualityCriteria(),
- ) -> dict[str, ty.Any]:
- data: dict[str, ty.Any] = defaultdict(str)
- for field, desc_type in self.get_descriptions_and_types().items():
- # blacklist fields that will be added with custom formatters below or that we don't want to add to the plindex
- descr = str(desc_type[0]).lstrip().replace("\n", " ")
- if descr.startswith("__"):
- continue
- if not field.startswith("system_"):
- name = f"system_{field}"
- else:
- name = field
- data[name] = getattr(self, field, None)
-
- pocket_mapping = self.get_pocket_domains(chains)
- for mapping in pocket_mapping:
- data[f"system_pocket_{mapping}"] = pocket_mapping[mapping]
- data.update(self.format_validation(entry_pass_criteria, criteria))
- for chain_type in ["protein", "ligand"]:
- data.update(self.format_chains(chain_type, chains))
- return data
-
- @cached_property
- def waters(self) -> dict[str, list[int]]:
- """
- __Waters interacting (as detected by PLIP) with any of the ligands in the system
- """
- waters: dict[str, list[int]] = defaultdict(list)
- for ligand in self.ligands:
- for chain in ligand.waters:
- waters[chain] += ligand.waters[chain]
- return waters
-
- def select_waters(self) -> str:
- query = []
- for chain in self.waters:
- chain_query = " or ".join(f"rnum={resnum}" for resnum in self.waters[chain])
- query.append(f"(chain='{chain}' and ({chain_query}))")
- return " or ".join(query)
-
- @cached_property
- def num_crystal_contacted_residues(self) -> int:
- """
- Number of residues from other symmetry mates which are in contact with any ligand in the system.
- """
- residues = set()
- for ligand in self.ligands:
- residues |= set(ligand.crystal_contacts.keys())
- return len(residues)
-
- @cached_property
- def num_atoms_with_crystal_contacts(self) -> int:
- """
- Number of atoms in the system ligands which are in contact with residues from other symmetry mates.
- """
- return sum(ligand.num_atoms_with_crystal_contacts for ligand in self.ligands)
-
- @cached_property
- def num_heavy_atoms(self) -> int | None:
- """
- Number of heavy atoms in the system ligands
- """
- if any(ligand.num_heavy_atoms is None for ligand in self.ligands):
- return None
- return sum(
- ligand.num_heavy_atoms
- for ligand in self.ligands
- if ligand.num_heavy_atoms is not None
- )
-
- @cached_property
- def num_resolved_heavy_atoms(self) -> int | None:
- """
- Number of resolved heavy atoms in the system ligands
- """
- if any(ligand.num_resolved_heavy_atoms is None for ligand in self.ligands):
- return None
- return sum(
- ligand.num_resolved_heavy_atoms
- for ligand in self.ligands
- if ligand.num_resolved_heavy_atoms is not None
- )
-
- @cached_property
- def ligand_max_qed(self) -> float:
- """
- Maximum QED of the system ligands
- """
- return max(
- ligand.qed if ligand.qed is not None else -1.0 for ligand in self.ligands
- )
-
- @cached_property
- def ligand_max_molecular_weight(self) -> float:
- """
- Maximum molecular weight of the system ligands
- """
- return max(
- ligand.molecular_weight if ligand.molecular_weight is not None else -1.0
- for ligand in self.ligands
- if ligand.molecular_weight is not None
- )
-
- @cached_property
- def proper_ligand_max_molecular_weight(self) -> float:
- """
- Maximum molecular weight of the system ligands excluding ions and artifacts
- """
- ligands = self.proper_ligands()
- if len(ligands) == 0:
- return -1.0
- weights = [
- ligand.molecular_weight if ligand.molecular_weight is not None else -1.0
- for ligand in ligands
- ]
- return max(weights)
-
- @cached_property
- def num_unresolved_heavy_atoms(self) -> int | None:
- """
- Number of unresolved heavy atoms in the system ligands
- """
- if any(ligand.num_unresolved_heavy_atoms is None for ligand in self.ligands):
- return None
- return sum(
- ligand.num_unresolved_heavy_atoms
- for ligand in self.ligands
- if ligand.num_unresolved_heavy_atoms is not None
- )
-
- @cached_property
- def fraction_atoms_with_crystal_contacts(self) -> float | None:
- """
- Fraction of atoms in the system ligands which are in contact with residues from other symmetry mates.
- """
- if self.num_heavy_atoms is None:
- return None
- return self.num_atoms_with_crystal_contacts / self.num_heavy_atoms
-
- def selection(self, include_waters: bool = True) -> str:
- ligand_selection = " or ".join(
- f"({ligand.selection})" for ligand in self.ligands
- )
- protein_selection = " or ".join(
- f"(cname={mol.QueryQuoteName(chain)})"
- for chain in self.protein_chains_asym_id
- )
- selection = f"({ligand_selection}) or ({protein_selection})"
- if include_waters and len(self.waters):
- selection += f" or {self.select_waters()}"
- return selection
-
- def save_system(
- self,
- chain_to_seqres: dict[str, str],
- biounit: mol.EntityHandle,
- info: io.MMCifInfoBioUnit,
- system_folder: Path,
- include_waters: bool = True,
- ) -> None:
- system_folder.mkdir(exist_ok=True)
- with open(system_folder / "sequences.fasta", "w") as f:
- for i_c in self.protein_chains_asym_id:
- c = i_c.split(".")[1]
- if c in chain_to_seqres:
- f.write(f">{i_c}\n")
- f.write(chain_to_seqres[c] + "\n")
- selection = self.selection(include_waters=include_waters)
- ent_system = mol.CreateEntityFromView(
- biounit.Select(selection),
- True,
- )
- (system_folder / "ligand_files").mkdir(exist_ok=True)
- save_ligands(
- ent_system,
- [ligand.selection for ligand in self.ligands],
- self.ligand_chains,
- [l.smiles for l in self.ligands],
- [l.num_unresolved_heavy_atoms for l in self.ligands],
- system_folder / "ligand_files",
- )
- save_cif_file(ent_system, info, self.id, system_folder / "system.cif")
- selection = " or ".join(f"chain='{c}'" for c in self.protein_chains_asym_id)
- if include_waters and len(self.waters):
- selection += f" or {self.select_waters()}"
- save_cif_file(
- ent_system.Select(selection),
- info,
- self.id,
- system_folder / "receptor.cif",
- )
- try:
- # TODO: move out and add a flag instead
- save_pdb_file(
- biounit,
- mol.CreateEntityFromView(ent_system.Select(selection), True),
- self.protein_chains_asym_id,
- [],
- system_folder / "receptor.pdb",
- system_folder / "chain_mapping.json",
- self.waters if include_waters else {},
- system_folder / "water_mapping.json",
- )
- except Exception as e:
- LOG.error(f"save_system: Error saving system in PDB format {self.id}: {e}")
-
- def set_validation(
- self,
- chains: dict[str, Chain],
- thresholds: ResidueValidationThresholds = ResidueValidationThresholds(),
- ) -> None:
- self.ligand_validation = ResidueListValidation.from_residues(
- [
- chains[c.split(".")[1]].residues[r].validation # type: ignore
- for c in self.ligand_chains
- for r in chains[c.split(".")[1]].residues
- ],
- thresholds,
- )
- self.pocket_validation = ResidueListValidation.from_residues(
- [
- chains[c.split(".")[1]].residues[r].validation # type: ignore
- for c in self.pocket_residues
- for r in self.pocket_residues[c]
- ],
- thresholds,
- )
-
- def run_posebusters_on_system(self, system_folder: Path) -> None:
- """
- Run posebusters on the system
- """
- pb = PoseBusters(config="redock")
- receptor_file = system_folder / "receptor.pdb"
- if not receptor_file.exists():
- return
- for ligand in self.ligands:
- ligand_file = (
- system_folder / "ligand_files" / f"{ligand.instance_chain}.sdf"
- )
- if not ligand_file.exists():
- continue
- try:
- result_dict = pb.bust(
- mol_pred=str(ligand_file),
- mol_true=str(ligand_file),
- mol_cond=str(receptor_file),
- full_report=True,
- ).to_dict()
- except Exception as e:
- LOG.error(
- f"run_posebusters: Error running posebusters on {ligand.id}: {e}"
- )
- continue
- key = (str(ligand_file), ligand.instance_chain)
- ligand.posebusters_result = {
- k: v.get(key) for k, v in result_dict.items() if v.get(key)
- }
-
- def get_pocket_domains(self, chains_dict: dict[str, Chain]) -> dict[str, str]:
- global ECOD_DATA
- if ECOD_DATA is None:
- data_dir = Path(get_config().data.plinder_dir)
- ECOD_DATA = pd.read_parquet(data_dir / "dbs" / "ecod" / "ecod.parquet")
- ecod_df = ECOD_DATA[ECOD_DATA["pdb"] == self.pdb_id]
- ecod_mapping = dict(zip(ecod_df["domainid"], ecod_df["domain"]))
- pocket_mapping: dict[str, dict[str, int]] = defaultdict(
- lambda: defaultdict(int)
- )
- for (
- neighboring_chain,
- neighboring_residues_list,
- ) in self.pocket_residues.items():
- neighboring_chain = neighboring_chain.split(".")[-1]
- neighboring_residues_set = {int(i) for i in neighboring_residues_list}
- neighboring_residue_numbers_dict = {
- int(chains_dict[neighboring_chain].residues[i].auth_number): i
- for i in neighboring_residues_list
- }
- for mapping_name in chains_dict[neighboring_chain].mappings:
- if mapping_name == "BIRD":
- continue
- for domain in chains_dict[neighboring_chain].mappings[mapping_name]:
- unrolled_v = {
- tuple(range(*[remove_alphabets(j) for j in i]))
- for i in chains_dict[neighboring_chain].mappings[mapping_name][
- domain
- ]
- if i is not None
- }
- unrolled_v_2 = {j for i in unrolled_v for j in i}
- if mapping_name == "ECOD":
- intersection = set(
- neighboring_residue_numbers_dict[i]
- for i in neighboring_residue_numbers_dict
- if i in unrolled_v_2
- )
- else:
- intersection = neighboring_residues_set.intersection(
- unrolled_v_2
- )
- if len(intersection) > 0:
- pocket_mapping[mapping_name][domain] += len(intersection)
- if mapping_name == "ECOD":
- pocket_mapping[f"{mapping_name}_t_name"][
- ecod_mapping[domain]
- ] += len(intersection)
- result = {}
- for k, values in pocket_mapping.items():
- result[k] = sorted(values.items(), key=lambda x: x[1], reverse=True)[0][0]
- return result
-
-
-class Entry(DocBaseModel):
- pdb_id: str = Field(
- default_factory=str,
- description="RCSB PDB ID. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html",
- )
- release_date: str = Field(
- default_factory=str,
- description="RCSB structure release date. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_database_PDB_rev.date_original.html",
- )
- oligomeric_state: str | None = Field(
- default_factory=str,
- description="Author's provided description of quaternary structure in RCSB. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_pdbx_struct_assembly.oligomeric_details.html",
- )
- determination_method: str | None = Field(
- default_factory=str,
- description="RCSB method of structure determination. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_exptl.method.html",
- )
- keywords: str | None = Field(
- default_factory=str,
- description="RCSB keywords describing the structure. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_struct_keywords.pdbx_keywords.html",
- )
- pH: str | None = Field(
- default_factory=str,
- description="pH at which structure is solved. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_exptl_crystal_grow.pH.html",
- )
- resolution: float | None = Field(
- default_factory=float,
- description="RCSB structure resolution. See https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_refine.ls_d_res_high.html",
- )
- chains: dict[str, Chain] = Field(
- default_factory=dict,
- description="__Chains dictionary with chain name mapped to chain object",
- )
- ligand_like_chains: dict[str, str] = Field(
- default_factory=dict,
- description="__Chain: chain type for other ligand-like chains in the entry",
- )
- systems: dict[str, System] = Field(
- default_factory=dict,
- description="__System dictionary with system id mapped to system object",
- )
- covalent_bonds: dict[str, list[tuple[str, str]]] = Field(
- default_factory=dict,
- description="__All covalent interactions in the entry as defined by mmcif annotations. They types are separated by dictionary key and they include: "
- + "covale: actual covalent linkage, metalc: other dative bond interactions like metal-ligand dative bond, "
- + "hydrogc: strong hydorogen bonding of nucleic acid. For the purpose of covalent annotations, we use only covale for downstream processing.",
- )
- chain_to_seqres: dict[str, str] = Field(
- default_factory=dict, description="__Chain to sequence mapping"
- )
- validation: EntryValidation | None = Field(
- default=None, description="__Entry validation"
- )
- pass_criteria: bool | None = Field(
- default=None, description="__Entry pass validation criteria"
- )
- water_chains: list[str] = Field(
- default_factory=list, description="__Water chains in the entry"
- )
- symmetry_mate_contacts: SymmetryMateContacts = Field(
- default_factory=dict, description="__Symmetry mate contacts in the entry"
- )
-
- def prune(
- self,
- *,
- clear_non_pocket_residues: bool = True,
- load_for_scoring: bool = True,
- max_protein_chains: int = 5,
- max_ligand_chains: int = 5,
- ) -> Entry:
- """
- Update an entry in place to reduce memory footprint and discard
- unuseful systems for downstream processing.
-
- Parameters
- ----------
- clear_non_pocket_residues : bool, default=True
- remove residues not present in pockets
- load_for_scoring : bool, default=True
- remove systems that are not holo or have too many protein/ligand chains
- max_protein_chains : int, default=5
- only keep systems with leq max_protein_chains
- max_ligand_chains : int, default=5
- only keep systems with leq max_ligand_chains
-
- Returns
- -------
- self : Entry
- the updated entry
- """
- if clear_non_pocket_residues:
- self.clear_non_pocket_residues()
- if load_for_scoring:
- self.systems = {
- s.id: s
- for s in self.systems.values()
- if s.system_type == "holo"
- and len(s.protein_chains_asym_id) <= max_protein_chains
- and len(s.ligand_chains) <= max_ligand_chains
- }
- return self
-
- @classmethod
- def from_json(
- cls,
- entry_json: Path,
- clear_non_pocket_residues: bool = False,
- load_for_scoring: bool = False,
- max_protein_chains: int = 5,
- max_ligand_chains: int = 5,
- ) -> Entry:
- """
- Load an entry from a JSON file and prune it. See prune
- for more details.
- """
- with entry_json.open("rb") as f:
- entry = cls.model_validate_json(f.read())
- return entry.prune(
- clear_non_pocket_residues=clear_non_pocket_residues,
- load_for_scoring=load_for_scoring,
- max_protein_chains=max_protein_chains,
- max_ligand_chains=max_ligand_chains,
- )
-
- @classmethod
- def from_cif_file(
- cls,
- cif_file: Path,
- neighboring_residue_threshold: float = 6.0,
- neighboring_ligand_threshold: float = 4.0,
- min_polymer_size: int = 10, # TODO: this used to be max_non_small_mol_ligand_length
- max_non_small_mol_ligand_length: int = 20, # TODO: review and make consistent
- save_folder: Path | None = None,
- max_protein_chains_to_save: int = 5,
- max_ligand_chains_to_save: int = 5,
- plip_complex_threshold: float = 10.0,
- skip_save_systems: bool = False,
- skip_posebusters: bool = False,
- symmetry_mate_contact_threshold: float = 5.0,
- ) -> Entry:
- """
- Load an entry object from mmcif files
-
- Parameters
- ----------
- cif_file : Path
- mmcif files of interest
- neighboring_residue_threshold : float
- Distance from ligand for protein \
- residues to be considered a ligand
- neighboring_ligand_threshold : float
- Distance from ligand for other ligans \
- to be considered a ligand
- min_polymer_size : int = 10
- Minimum number of residues for chain to be seen as a \
- polymer, or Maximum number of residues for chain to be seen as a ligand \
- max_non_small_mol_ligand_length: int = 20
- Maximum length of polymer that should be assessed for potentially being ligand
- save_folder : Path
- Path to save files
- max_protein_chains_to_save : int
- Maximum number of protein chains to save
- max_ligand_chains_to_save : int
- Maximum number of protein chains to save
- plip_complex_threshold=10
- Maximum distance from ligand to residues to be
- included for plip calculations.
- skip_save_systems: bool = False
- skips saving system files
- skip_posebusters: bool = False
- skips running posebusters analysis
-
- Returns
- -------
- Entry
- Entry object for the given pdbid
- """
- ent, seqres, info = io.LoadMMCIF(
- str(cif_file), seqres=True, info=True, remote=False
- )
- cif_data = read_mmcif_container(cif_file)
- symmetry_mate_contacts = get_symmetry_mate_contacts(
- cif_file, symmetry_mate_contact_threshold
- )
- entry_info = get_entry_info(cif_data)
- per_chain = get_chain_external_mappings(cif_data)
- # TODO: annotate_interface_gaps does not use the same ligand chain definitions as the rest
- # move this to later after protein/ligand chain assignment?
- interface_proximal_gaps = annotate_interface_gaps(cif_file)
- resolution = entry_info.get("entry_resolution")
- r = None
- if resolution is not None:
- try:
- r = float(resolution)
- except ValueError:
- r = None
- entry = cls(
- pdb_id=info.struct_details.entry_id.lower(),
- release_date=info.revisions.GetDateOriginal(),
- oligomeric_state=str(entry_info.get("entry_oligomeric_state"))
- if entry_info.get("entry_oligomeric_state") is not None
- else None,
- determination_method=str(entry_info.get("entry_determination_method"))
- if entry_info.get("entry_determination_method") is not None
- else None,
- keywords=str(entry_info.get("entry_keywords"))
- if entry_info.get("entry_keywords", None) is not None
- else None,
- pH=str(entry_info.get("entry_pH"))
- if entry_info.get("entry_pH") is not None
- else None,
- resolution=r,
- covalent_bonds=get_covalent_connections(cif_data),
- chain_to_seqres={c.name: c.string for c in seqres},
- symmetry_mate_contacts=symmetry_mate_contacts,
- )
- entry.chains = {
- chain.name: Chain.from_ost_chain(
- chain, info, len(entry.chain_to_seqres.get(chain.name, ""))
- )
- for chain in ent.chains
- if chain.type != mol.CHAINTYPE_WATER
- }
- entry.water_chains = [
- chain.name for chain in ent.chains if chain.type == mol.CHAINTYPE_WATER
- ]
-
- data_dir = None
- if save_folder is not None:
- data_dir = save_folder.parent.parent
- for chain in per_chain:
- entry.chains[chain].mappings = per_chain[chain]
- if data_dir is not None:
- entry.add_ecod()
- entry.add_panther(data_dir / "dbs" / "panther")
- entry.add_kinase(data_dir / "dbs" / "kinase" / "kinase_uniprotac.parquet")
- entry.ligand_like_chains = detect_ligand_chains(
- ent, entry, min_polymer_size, max_non_small_mol_ligand_length
- )
- ligands = {}
- biounits = {}
- for biounit_info in info.biounits:
- biounit = mol.alg.CreateBU(ent, biounit_info)
- biounit_ligand_chains = [
- chain.name
- for chain in biounit.chains
- if chain.name.split(".")[1] in entry.ligand_like_chains
- ]
- for ligand_chain in biounit_ligand_chains:
- ligand_instance, ligand_asym_id = ligand_chain.split(".")
- data_dir = None
- if save_folder is not None:
- data_dir = save_folder.parent.parent
- residue_numbers = [
- residue.number.num
- for residue in biounit.FindChain(ligand_chain).residues
- ]
- ligand = Ligand.from_pli(
- pdb_id=entry.pdb_id,
- biounit_id=biounit_info.id,
- biounit=biounit,
- ligand_instance=int(ligand_instance),
- ligand_chain=entry.chains[ligand_asym_id],
- residue_numbers=residue_numbers,
- ligand_like_chains=entry.ligand_like_chains,
- interface_proximal_gaps=interface_proximal_gaps,
- all_covalent_dict=entry.covalent_bonds,
- plip_complex_threshold=plip_complex_threshold,
- neighboring_residue_threshold=neighboring_residue_threshold,
- neighboring_ligand_threshold=neighboring_ligand_threshold,
- data_dir=data_dir,
- )
- if ligand is not None:
- ligands[ligand.id] = ligand
- biounits[biounit_info.id] = biounit
- entry.set_systems(ligands)
- entry.label_chains()
- if save_folder is not None and not skip_save_systems:
- entry.save_systems(
- info,
- biounits,
- save_folder,
- max_protein_chains_to_save,
- max_ligand_chains_to_save,
- )
- # TODO: this is backwards because it assumes save_systems
- # has already run but will fail if it hadn't run previously
- # so we just check if save_folder is None (which it's not in the pipeline)
- # VO: added option to skip to speed up testing!
- if not skip_posebusters:
- entry.run_posebusters(
- save_folder,
- max_protein_chains_to_save,
- max_ligand_chains_to_save,
- )
- return entry
-
- def set_systems(self, ligands: dict[str, Ligand]) -> None:
- """
- Setter method for system ids for ligands
-
- Parameters
- ----------
- ligands : dict[str, Ligand]
-
- Returns
- -------
- None
- """
-
- G = nx.Graph()
- for ligand_id in ligands:
- G.add_node(ligand_id)
- for neighboring_ligand_instance_chain in (
- ligands[ligand_id].neighboring_ligands
- + ligands[ligand_id].interacting_ligands
- ):
- neighboring_ligand_id = "__".join(
- [
- self.pdb_id,
- ligands[ligand_id].biounit_id,
- f"{neighboring_ligand_instance_chain}",
- ]
- )
- if neighboring_ligand_id in ligands:
- G.add_edge(ligand_id, neighboring_ligand_id)
- system_ligands: dict[int, list[Ligand]] = {}
- for idx, component in enumerate(
- sorted(nx.connected_components(G), key=len, reverse=True)
- ):
- system_ligands[idx + 1] = []
- for ligand_id in component:
- system_ligands[idx + 1].append(ligands[ligand_id])
- self.systems: dict[str, System] = {}
- for ligs in system_ligands.values():
- system = System(
- pdb_id=self.pdb_id,
- biounit_id=ligs[0].biounit_id,
- ligands=sorted(ligs, key=lambda x: x.id),
- )
- if len(system.protein_chains_asym_id):
- self.systems[system.id] = system
-
- @cached_property
- def author_to_asym(self) -> dict[str, str]:
- """
- __Map author chain id to asym id
- """
- return {
- c.auth_id: c.asym_id
- for c in self.chains.values()
- if c.chain_type == mol.CHAINTYPE_POLY_PEPTIDE_L
- }
-
- def chains_for_alignment(self, chain_type: str, aln_type: str) -> list[str]:
- """
- Get chains for foldseek/mmseqs alignment
- Parameters
- ----------
- self : Entry
- Entry object
- chain_type : str
- Chain type (apo/holo)
- aln_type : str
- Alignment type (folseek, mmses, etc)
- Returns
- -------
- list[str]
- """
- assert chain_type in (
- "apo",
- "holo",
- "pred",
- ), "chain_type must be 'apo', 'holo', or 'pred'"
- if chain_type == "holo":
- chains = set(
- self.chains[i_c.split(".")[1]].auth_id
- for system in self.systems.values()
- for i_c in system.protein_chains_asym_id
- if system.system_type == "holo"
- )
- elif chain_type == "apo":
- holo_entities = set(
- self.chains[c].entity_id for c in self.chains if self.chains[c].holo
- )
- chains = set(
- self.chains[c].auth_id
- for c in self.chains
- if not self.chains[c].holo
- and not self.chains[c].entity_id in holo_entities
- )
- elif chain_type == "pred":
- chains = set()
- for c in self.chains:
- if self.chains[c].holo:
- chains |= set(self.chains[c].mappings.get("UniProt", {}))
- if aln_type == "foldseek":
- if chain_type == "pred":
- return [f"AF-{c}-F1-model_v4_A" for c in chains]
- else:
- return [f"pdb_0000{self.pdb_id}_xyz-enrich.cif_{c}" for c in chains]
- elif aln_type == "mmseqs":
- if chain_type == "pred":
- return list(chains)
- else:
- return [f"{self.pdb_id}_{c}" for c in chains]
- return []
-
- def label_chains(self) -> None:
- """
- Label chains as apo/holo/ligand
- Parameters
- ----------
- self : Entry
- Entry object
-
- Returns
- -------
- None
- """
- holo_chains = set()
- ligand_chains = set()
- for system in self.systems.values():
- if system.system_type == "holo":
- holo_chains.update(
- [c.split(".")[1] for c in system.protein_chains_asym_id]
- )
- ligand_chains.update([l.asym_id for l in system.ligands])
- for chain in self.chains:
- if chain not in ligand_chains and chain not in holo_chains:
- self.chains[chain].holo = False
- elif chain in holo_chains:
- self.chains[chain].holo = True
-
- def format_validation(
- self, criteria: QualityCriteria = QualityCriteria()
- ) -> dict[str, ty.Any]:
- assert self.validation is not None
- data = self.validation.format()
- data = {f"entry_{k}": v for k, v in data.items()}
- if data["entry_validation_r"] is None:
- self.pass_criteria = False
- else:
- quality = [
- # ENTRY
- data["entry_validation_resolution"] is not None
- and data["entry_validation_resolution"]
- <= criteria.max_entry_resolution,
- data["entry_validation_r"] is not None
- and data["entry_validation_r"] <= criteria.max_entry_r,
- data["entry_validation_rfree"] is not None
- and data["entry_validation_rfree"] <= criteria.max_entry_rfree,
- data["entry_validation_r_minus_rfree"] is not None
- and data["entry_validation_r_minus_rfree"]
- <= criteria.max_entry_r_minus_rfree,
- ]
- self.pass_criteria = all(quality)
- data["entry_pass_validation_criteria"] = self.pass_criteria
- return data
-
- def format(
- self, criteria: QualityCriteria = QualityCriteria()
- ) -> dict[str, ty.Any]:
- """
- Format label for entry-level annotations by prepending \
- label with "entry_"
- Parameters
- ----------
- self : Entry
- Entry object
-
- Returns
- -------
- dict[str, ty.Any]
- """
- data: dict[str, ty.Any] = defaultdict(str)
- columns = [
- "pdb_id",
- "release_date",
- "oligomeric_state",
- "determination_method",
- "keywords",
- "pH",
- "resolution",
- ]
- for field in columns:
- name = f"entry_{field}"
- data[name] = getattr(self, field, None)
-
- if self.validation:
- data.update(self.format_validation(criteria))
- data["entry_pass_validation_criteria"] = self.pass_criteria
- return data
-
- def to_df(self) -> pd.DataFrame:
- """
- Convert entry data object to pd.DataFrame
- Parameters
- ----------
- self : Entry
- Entry object
-
- Returns
- -------
- pd.DataFrame
- """
- rows = []
- entry_data = self.format()
- for system in self.systems:
- system_data = self.systems[system].format(self.chains, self.pass_criteria)
- for ligand in self.systems[system].ligands:
- ligand_data = ligand.format(self.chains)
- rows.append({**entry_data, **system_data, **ligand_data})
- return pd.DataFrame(rows)
-
- def iter_systems(
- self, max_protein_chains: int, max_ligand_chains: int
- ) -> ty.Iterator[tuple[str, System]]:
- for system_id, system in self.systems.items():
- if (
- system.system_type == "holo"
- and len(system.protein_chains_asym_id) <= max_protein_chains
- and len(system.ligand_chains) <= max_ligand_chains
- ):
- yield system_id, system
-
- def run_posebusters(
- self,
- save_folder: Path | None,
- max_protein_chains: int,
- max_ligand_chains: int,
- ) -> None:
- if save_folder is None:
- LOG.warning("run_posebusters got save_folder=None so skipping")
- return
- for system_id, system in self.iter_systems(
- max_protein_chains, max_ligand_chains
- ):
- save_folder_system = save_folder / system.id
- self.systems[system_id].run_posebusters_on_system(save_folder_system)
-
- def save_systems(
- self,
- info: io.MMCifInfoBioUnit,
- biounits: mol.EntityHandle,
- save_folder: Path,
- max_protein_chains: int = 5,
- max_ligand_chains: int = 5,
- ) -> None:
- """
- Save system files
- Parameters
- ----------
- self : Entry
- Entry object
-
- Returns
- -------
- pd.DataFrame
- """
- for _, system in self.iter_systems(max_protein_chains, max_ligand_chains):
- save_folder_system = save_folder / system.id
- system.save_system(
- self.chain_to_seqres,
- biounits[system.biounit_id],
- info,
- save_folder_system,
- )
-
- def clear_non_pocket_residues(self) -> None:
- """
- Remove non-pocket residues from chains
- """
- all_pocket_residues: dict[str, set[int]] = defaultdict(set)
- for system in self.systems.values():
- for ligand in system.ligands:
- for chain in ligand.pocket_residues:
- all_pocket_residues[chain.split(".")[1]].update(
- ligand.pocket_residues[chain].keys()
- )
- for chain in self.chains:
- if chain in all_pocket_residues:
- self.chains[chain].residues = {
- r: self.chains[chain].residues[r]
- for r in all_pocket_residues[chain]
- }
- else:
- self.chains[chain].residues = {}
-
- def set_validation(
- self,
- validation_file: Path,
- cif_file: Path,
- thresholds: ResidueValidationThresholds = ResidueValidationThresholds(),
- ) -> None:
- if self.determination_method != "X-RAY DIFFRACTION":
- LOG.warning(
- f"set_validation: Skipping validation for {self.pdb_id} as method is not X-RAY DIFFRACTION"
- )
- return
- self.label_crystal_contacts()
- if not validation_file.exists():
- LOG.error(f"set_validation: Validation file not found {validation_file}")
- return
- try:
- # libxml2 no longer decompresses gzip input by default.
- with (
- gzip.open(validation_file, "rb")
- if validation_file.suffix == ".gz"
- else validation_file.open("rb")
- ) as validation_xml:
- doc = ValidationFactory(
- validation_xml, mmcif_path=str(cif_file)
- ).getValidation()
- self.validation = EntryValidation.from_entry(doc)
- if self.validation and self.validation.r is not None:
- for chain in self.chains:
- self.chains[chain].set_validation(doc, thresholds)
- for system in self.systems:
- self.systems[system].set_validation(self.chains, thresholds)
- except Exception as e:
- LOG.error(
- f"set_validation: Error setting validation for {self.pdb_id}: {e}"
- )
-
- def label_crystal_contacts(self) -> None:
- """
- Label contacts of ligand residues to other symmetry mates
- Excludes neighboring residues (i.e same biounit)
- """
- for system in self.systems:
- for ligand in self.systems[system].ligands:
- crystal_contacts: dict[tuple[str, int], set[int]] = defaultdict(set)
- for residue_number in ligand.residue_numbers:
- # get all contacts with chains in other asymmetric units
- contacts = self.symmetry_mate_contacts.get(
- (ligand.asym_id, residue_number), dict()
- )
- for x, y in contacts.items():
- # keep only contacts with receptor
- if x[0] not in self.ligand_like_chains:
- crystal_contacts[x] |= y
- ligand.set_crystal_contacts(crystal_contacts)
-
- def add_ecod(self) -> None:
- """
- Add ECOD annotations to chains
- """
- global ECOD_DATA
- if ECOD_DATA is None:
- data_dir = Path(get_config().data.plinder_dir)
- ECOD_DATA = pd.read_parquet(data_dir / "dbs" / "ecod" / "ecod.parquet")
- ecod_df = ECOD_DATA[ECOD_DATA["pdb"] == self.pdb_id]
- if not len(ecod_df):
- return
- for chain_id, chain in self.chains.items():
- ecod_df_chain = ecod_df[ecod_df["chain"] == chain.auth_id]
- if not len(ecod_df_chain):
- continue
- mappings: dict[str, set[tuple[str, str]]] = defaultdict(set)
- for row in ecod_df_chain.T.to_dict().values():
- mappings[row["domainid"]].add((row["pdb_from"], row["pdb_to"]))
- self.chains[chain_id].mappings["ECOD"] = {
- k: list(v) for k, v in mappings.items()
- }
-
- def add_panther(self, panther_data_dir: Path) -> None:
- """
- Add panther annotations to chains
- """
- dfs = {}
- for chain_id, chain in self.chains.items():
- uniprots = chain.mappings.get("UniProt", {})
- mappings: dict[str, set[tuple[str, str]]] = defaultdict(set)
- for uniprot in uniprots:
- shard = uniprot[-1]
- if shard not in dfs:
- dfs[shard] = pd.read_parquet(
- panther_data_dir / f"panther_{shard}.parquet"
- ).set_index("uniprotac")
- if uniprot in dfs[shard].index:
- mappings[dfs[shard].loc[uniprot]["panther"]] |= set(
- uniprots[uniprot] # type: ignore
- )
- if len(mappings):
- self.chains[chain_id].mappings["PANTHER"] = {
- k: list(v) for k, v in mappings.items()
- }
-
- def add_kinase(self, kinase_data_path: Path) -> None:
- """
- Add kinase annotations to chains
- """
- kinase_df = pd.read_parquet(kinase_data_path)
- kinase_df = kinase_df[kinase_df["pdb"] == self.pdb_id]
- if not len(kinase_df):
- return
- for chain_id, chain in self.chains.items():
- kinase_df_chain = kinase_df[kinase_df["chain"] == chain.auth_id]
- if not len(kinase_df_chain):
- continue
- mappings: dict[str, set[tuple[str, str]]] = defaultdict(set)
- uniprots = chain.mappings.get("UniProt", {})
- for row in kinase_df_chain.T.to_dict().values():
- uniprot = uniprots.get(row["uniprot"])
- if uniprot is not None:
- mappings[row["kinase"]] |= set(uniprot) # type: ignore
- if len(mappings):
- self.chains[chain_id].mappings["kinase_name"] = {
- k: list(v) for k, v in mappings.items()
- }
-
-
-def document(output_dir: Path) -> None:
- """
- Document the columns in the annotation files
- """
- output_dir.mkdir(parents=True, exist_ok=True)
- Entry.document_properties_to_tsv(prefix="entry", filename=output_dir / "entry.tsv")
- EntryValidation.document_properties_to_tsv(
- prefix="entry_validation", filename=output_dir / "entry_validation.tsv"
- )
- System.document_properties_to_tsv(
- prefix="system", filename=output_dir / "system.tsv"
- )
- ResidueListValidation.document_properties_to_tsv(
- prefix="system_pocket", filename=output_dir / "system_pocket_validation.tsv"
- )
- ResidueListValidation.document_properties_to_tsv(
- prefix="system_ligand", filename=output_dir / "system_ligand_validation.tsv"
- )
- Chain.document_properties_to_tsv(
- prefix="system_protein_chains",
- filename=output_dir / "system_protein_chains.tsv",
- )
- Chain.document_properties_to_tsv(
- prefix="system_ligand_chains", filename=output_dir / "system_ligand_chains.tsv"
- )
- Ligand.document_properties_to_tsv(
- prefix="ligand", filename=output_dir / "ligands.tsv"
- )
diff --git a/src/plinder/data/utils/annotations/get_similarity_scores.py b/src/plinder/data/utils/annotations/get_similarity_scores.py
deleted file mode 100644
index 2895fd696..000000000
--- a/src/plinder/data/utils/annotations/get_similarity_scores.py
+++ /dev/null
@@ -1,1039 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-import shutil
-import subprocess
-from collections import abc, defaultdict
-from dataclasses import dataclass, field
-from pathlib import Path
-from typing import Optional
-
-import biotite.sequence as seq
-import biotite.sequence.align as align
-import numpy as np
-import pandas as pd
-import pyarrow
-import pyarrow.parquet as pq
-from pyarrow import csv
-from tqdm import tqdm
-
-from plinder.core.utils.log import setup_logger
-from plinder.data import databases
-from plinder.data.pipeline.config import FoldseekConfig, MMSeqsConfig
-from plinder.data.pipeline.utils import load_entries_from_zips
-from plinder.data.utils.annotations.aggregate_annotations import Entry, System
-
-LOG = setup_logger(__name__)
-
-SORT_ORDER = [
- ("similarity", "descending"),
- ("query_system", "ascending"),
- ("target_system", "ascending"),
-]
-INFO_COLUMNS = (
- "query_system",
- "target_system",
- "protein_mapping",
- "protein_mapper",
-)
-SCORE_NAMES = (
- "protein_lddt",
- "protein_lddt_qcov",
- "protein_qcov",
- "protein_fident",
- "protein_fident_qcov",
- "protein_seqsim",
- "protein_seqsim_qcov",
- "pocket_lddt",
- "pocket_lddt_qcov",
- "pocket_qcov",
- "pocket_fident",
- "pocket_fident_qcov",
- "pli_qcov",
- "pli_unique_qcov",
-)
-
-_ChainInstanceMapping = str
-_ChainPairType = tuple[_ChainInstanceMapping, _ChainInstanceMapping]
-_SimilarityScoreDictType = dict[str, float]
-
-
-def get_sequence_similarity(seq_str1: str, seq_str2: str) -> tuple[float, float]:
- """
- Calculate the similarity score of an alignment.
-
- If the alignment contains more than two sequences,
- all pairwise scores are counted.
-
- Parameters
- ----------
- seq_str1 : str
- First protein sequence
- seq_str2 : str
- Second protein sequence
-
- Returns
- -------
- tuple[float, float]
- Sequence identity and sequence similarity score.
- """
- non_canonical_aa: dict[str, str | int | None] = {
- "X": "A", # Replace X (any a.a with alanine)
- "B": "D", # Replace Asx ( with aspartic acid)
- "J": "L", # Replace Xle ( with leucine)
- "Z": "E", # Replace Glx (any a.a with glutamic acid)
- "U": "C", # Replace Selenocysteine(sec) (with cysteine)
- "O": "K", # replace Pyrrolysine(Pyl) (any a.a with alanine)
- }
- seq_str1 = seq_str1.translate(str.maketrans(non_canonical_aa))
- seq_str2 = seq_str2.translate(str.maketrans(non_canonical_aa))
- seq1_arr = np.array(list(seq_str1))
- seq2_arr = np.array(list(seq_str2))
- gap1 = np.where(seq1_arr == "-")
- gap2 = np.where(seq2_arr == "-")
- all_gaps = np.concatenate([gap1[0], gap2[0]])
- seq1_arr = np.delete(seq1_arr, all_gaps)
- seq2_arr = np.delete(seq2_arr, all_gaps)
- ungapped_seq_str1 = "".join(list(seq1_arr))
- ungapped_seq_str2 = "".join(list(seq2_arr))
- seq1 = seq.ProteinSequence(ungapped_seq_str1)
- seq2 = seq.ProteinSequence(ungapped_seq_str2)
- matrix = align.SubstitutionMatrix.std_protein_matrix()
- trace = align.Alignment.trace_from_strings([ungapped_seq_str1, ungapped_seq_str2])
- ali = align.Alignment([seq1, seq2], trace)
- codes = align.alignment.get_codes(ali)
- matrix = matrix.score_matrix()
-
- # Sum similarity scores (without gaps)
- scores = []
-
- # Iterate over all positions
- for pos in range(codes.shape[1]):
- column = codes[:, pos]
- # Iterate over all possible pairs
- # Do not count self-similarity
- # and do not count similarity twice (not S(i,j) and S(j,i))
- for i in range(codes.shape[0]):
- for j in range(i + 1, codes.shape[0]):
- code_i = column[i]
- code_j = column[j]
- # Ignore gaps
- if code_i != -1 and code_j != -1:
- tmp_score = max(0, matrix[code_i, code_j])
- normalizing_const = max(
- matrix[code_i, code_i], matrix[code_j, code_j]
- )
- scores.append(tmp_score / normalizing_const > 0.2)
- similarity_score = sum(scores) / len(scores)
- return (align.get_sequence_identity(ali), similarity_score)
-
-
-def get_sequence_similarity_helper(seq_str1: str, seq_str2: str) -> float:
- try:
- return get_sequence_similarity(seq_str1, seq_str2)[1]
- except Exception:
- return 0
-
-
-def run_alignment(
- aln_type: str,
- query_db: Path,
- target_db: Path,
- search_db: Path,
- aln_file: Path,
- alignment_config: FoldseekConfig | MMSeqsConfig,
- tmp_dir: Path = Path.cwd() / "tmp",
- remove_tmp: bool = True,
-) -> None:
- if search_db.with_suffix(".dbtype").exists():
- search_db.with_suffix(".dbtype").unlink()
-
- search_commands = [
- aln_type,
- "search",
- str(query_db),
- str(target_db),
- str(search_db),
- str(tmp_dir),
- "-a",
- "-e",
- f"{alignment_config.evalue}",
- "-s",
- f"{alignment_config.sensitivity}",
- "--max-seqs",
- f"{alignment_config.max_seqs}",
- "-c",
- f"{alignment_config.coverage}",
- "--cov-mode",
- "2",
- "--min-seq-id",
- f"{alignment_config.min_seq_id}",
- ]
- if aln_type == "foldseek":
- search_commands += ["--sort-by-structure-bits", "0"]
- convert_commands = [
- aln_type,
- "convertalis",
- str(query_db),
- str(target_db),
- str(search_db),
- str(aln_file.with_suffix(".tsv")),
- "--format-mode",
- "4",
- "--format-output",
- "query,target,qlen,fident,alnlen,qstart,qend,tstart,tend,evalue,bits,qcov,tcov,qaln,taln",
- ]
- if aln_type == "foldseek":
- convert_commands[-1] += ",lddt,lddtfull"
- subprocess.check_call(search_commands, stdout=subprocess.DEVNULL)
- subprocess.check_call(convert_commands, stdout=subprocess.DEVNULL)
-
- table = csv.read_csv(
- aln_file.with_suffix(".tsv"), parse_options=csv.ParseOptions(delimiter="\t")
- )
- table = table.append_column(
- "query_pdb_id",
- pyarrow.array(
- [
- str(x)
- .replace("_xyz-enrich.cif.gz", "")
- .replace("_xyz-enrich.cif", "")
- .replace("pdb_0000", "")[:4]
- for x in table["query"]
- ]
- ),
- )
- if search_db != "pred":
- table = table.append_column(
- "target_pdb_id",
- pyarrow.array(
- [
- str(x)
- .replace("_xyz-enrich.cif.gz", "")
- .replace("_xyz-enrich.cif", "")
- .replace("pdb_0000", "")[:4]
- for x in table["target"]
- ]
- ),
- )
- if aln_file.with_suffix(".parquet").exists():
- shutil.rmtree(aln_file.with_suffix(".parquet"))
- pq.write_to_dataset(
- table, aln_file.with_suffix(".parquet"), partition_cols=["query_pdb_id"]
- )
-
- # Cleanup
- if remove_tmp and tmp_dir.exists():
- shutil.rmtree(tmp_dir)
- aln_file.with_suffix(".tsv").unlink()
- for filename in search_db.parent.glob(f"{search_db.name}*"):
- if filename.is_dir():
- shutil.rmtree(filename)
- elif filename.is_file():
- filename.unlink()
-
-
-def combine_scores(
- q_t_scores: _SimilarityScoreDictType,
- q_t_mappings: dict[str, list[_ChainPairType]],
- protein_chain_mapper: str = "",
-) -> dict[str, str | float]:
- def make_mapping(mapping: list[_ChainPairType]) -> str:
- return ";".join(f"{a}:{b}" if len(b) else a for a, b in mapping)
-
- q_t_scores_combined: dict[str, str | float] = {}
- for s in SCORE_NAMES:
- for suffix in ["_max", "_weighted_max", "_weighted_sum", ""]:
- if (
- f"{s}_foldseek{suffix}" not in q_t_scores
- and f"{s}_mmseqs{suffix}" not in q_t_scores
- ):
- continue
- s1, s2 = (
- float(q_t_scores.get(f"{s}_foldseek{suffix}", 0)),
- float(q_t_scores.get(f"{s}_mmseqs{suffix}", 0)),
- )
- source = "foldseek"
- if np.abs(s1 - s2) < 1e-6:
- q_t_scores_combined[f"{s}{suffix}"] = s1
- q_t_scores_combined[f"{s}{suffix}_source"] = "both"
- else:
- index = np.argmax([s1, s2])
- q_t_scores_combined[f"{s}{suffix}"] = [s1, s2][index]
- source = ["foldseek", "mmseqs"][index]
- q_t_scores_combined[f"{s}{suffix}_source"] = source
- source_name = "mmseqs" if source == "mmseqs" else "foldseek"
- n = f"{s}_{source_name}{suffix}"
- if n in q_t_mappings:
- q_t_scores_combined[f"{s}{suffix}_mapping"] = make_mapping(
- q_t_mappings[n]
- )
- if protein_chain_mapper != "":
- q_t_scores_combined["protein_mapping"] = make_mapping(
- q_t_mappings.get(f"{protein_chain_mapper}_weighted_sum", [])
- )
- q_t_scores_combined["protein_mapper"] = (
- "foldseek" if "lddt" in protein_chain_mapper else "mmseqs"
- )
- return q_t_scores_combined
-
-
-@dataclass
-class Scorer:
- entries: dict[str, Entry]
- source_to_full_db_file: dict[str, Path]
- db_dir: Path
- scores_dir: Path
- protein_chain_mappers: list[str] = field(
- default_factory=lambda: [
- "protein_lddt_qcov_foldseek",
- "protein_fident_qcov_mmseqs",
- ]
- )
- ligand_chain_mappers: list[str] = field(
- default_factory=lambda: [
- "pocket_lddt_qcov_foldseek",
- "pocket_fident_qcov_mmseqs",
- ]
- )
- # default minimum threshold for every metric BEFORE scaling to 100
- minimum_threshold: int = 0
- # optional custom minimum threshold for each metric BEFORE scaling to 100
- minimum_thresholds: dict[str, int] = field(
- default_factory=lambda: {"pli_qcov": 0, "pocket_qcov": 0, "pli_unique_qcov": 0}
- )
-
- def __post_init__(self) -> None:
- self.db_dir.mkdir(exist_ok=True, parents=True)
- self.scores_dir.mkdir(exist_ok=True, parents=True)
-
- def make_dbs(self) -> None:
- databases.make_sub_dbs(self.db_dir, self.source_to_full_db_file, self.entries)
-
- @staticmethod
- def get_config(search_db: str, aln_type: str) -> FoldseekConfig | MMSeqsConfig:
- config: FoldseekConfig | MMSeqsConfig
- if aln_type == "foldseek":
- config = FoldseekConfig()
- else:
- config = MMSeqsConfig()
- if search_db in ["apo", "pred"]:
- config.coverage = 0.9
- config.min_seq_id = 0.9
- return config
-
- def run_alignments(
- self,
- entry_ids: list[str],
- search_db: str,
- output_folder: Path,
- overwrite: bool = False,
- ) -> None:
- output_folder.mkdir(exist_ok=True)
- for aln_type in ["mmseqs", "foldseek"]:
- sub_db = output_folder / search_db / aln_type
- sub_db.mkdir(exist_ok=True, parents=True)
- db_ids = databases.get_db_ids(
- self.entries, "holo", aln_type, entry_ids=entry_ids
- )
- databases.make_sub_db(
- db_ids,
- self.source_to_full_db_file[f"holo_{aln_type}"],
- sub_db,
- aln_type,
- )
- tmp_dir = sub_db / f"tmp_{search_db}_{aln_type}"
- tmp_dir.mkdir(exist_ok=True, parents=True)
- aln_file = sub_db / f"aln_{search_db}.tsv"
- LOG.info("run_alignments calling run_alignment:")
- LOG.info(f" sub_db={sub_db}")
- LOG.info(f" aln_file={aln_file.with_suffix('.tsv')}")
- LOG.info(f" aln_type={aln_type}")
- try:
- run_alignment(
- aln_type=aln_type,
- query_db=sub_db / sub_db.name,
- target_db=self.db_dir
- / f"{search_db}_{aln_type}"
- / f"{search_db}_{aln_type}",
- search_db=sub_db / "search",
- aln_file=aln_file.with_suffix(".tsv"),
- tmp_dir=tmp_dir / output_folder.stem,
- alignment_config=self.get_config(search_db, aln_type),
- )
- except Exception as e:
- scratch = (
- Path(*output_folder.parts[:3])
- / "scratch"
- / "scores"
- / "run_alignment_failures"
- )
- scratch.mkdir(exist_ok=True, parents=True)
- (scratch / f"{search_db}_{aln_type}.txt").write_text(f"{repr(e)}: {e}")
- LOG.error(f"scoring: Error for {search_db}_{aln_type}: {e}")
- continue
- aln_dir = self.db_dir / f"{search_db}_{aln_type}" / "aln"
- aln_dir.mkdir(exist_ok=True, parents=True)
- for pdb_id in tqdm(entry_ids):
- pdb_id_file = (
- aln_file.with_suffix(".parquet") / f"query_pdb_id={pdb_id}"
- )
- if not pdb_id_file.exists():
- scratch = (
- Path(*output_folder.parts[:3])
- / "scratch"
- / "scores"
- / "run_alignments_failures"
- )
- scratch.mkdir(exist_ok=True, parents=True)
- (scratch / f"{search_db}_{aln_type}_{pdb_id}.txt").write_text("")
- continue
- pdb_id_df = pd.read_parquet(pdb_id_file)
- if not pdb_id_df.empty:
- pdb_id_df.to_parquet(aln_dir / f"{pdb_id}.parquet")
- else:
- scratch = (
- Path(*output_folder.parts[:3])
- / "scratch"
- / "scores"
- / "run_alignments_empty"
- )
- scratch.mkdir(exist_ok=True, parents=True)
- (scratch / f"{search_db}_{aln_type}_{pdb_id}.txt").write_text("")
-
- def get_score_df(
- self, data_dir: Path, pdb_id: str, search_db: str, overwrite: bool = True
- ) -> Path:
- """
- Convert aligmnent results to mapped alignment results. Then
- aggregate the mapped alignment results into the scores dataset.
- """
- score_df_path = self.db_dir / f"search_db={search_db}" / f"{pdb_id}.parquet"
- if overwrite or not score_df_path.exists():
- LOG.info(f"get_score_df: aggregating scores for {pdb_id} to {search_db}")
- else:
- LOG.info(f"get_score_df: skipping existing {score_df_path}")
- return score_df_path
- for aln_type in ["foldseek", "mmseqs"]:
- pdb_id_file = (
- self.db_dir / f"{search_db}_{aln_type}" / "aln" / f"{pdb_id}.parquet"
- )
- if not pdb_id_file.exists():
- LOG.info(f"get_score_df: pdb_id_file={pdb_id_file} does not exist")
- continue
- pdb_file = (
- self.db_dir
- / f"{search_db}_{aln_type}"
- / "mapped_aln"
- / f"{pdb_id}.parquet"
- )
- pdb_file.parent.mkdir(exist_ok=True, parents=True)
- if overwrite or not pdb_file.exists():
- self.entries = {}
- entries_to_load = {pdb_id}
- if search_db != "pred" and pdb_id_file.exists():
- entries_to_load |= set(
- pd.read_parquet(pdb_id_file, columns=["target_pdb_id"])[
- "target_pdb_id"
- ]
- )
- entries_to_load = entries_to_load.difference(self.entries.keys())
- LOG.info(f"entries_to_load pdb_id={pdb_id} {len(entries_to_load)}")
- LOG.info(
- f"loading {len(entries_to_load)} (additional) entries for {pdb_id}"
- )
- self.entries.update(
- load_entries_from_zips(
- data_dir=data_dir,
- pdb_ids=entries_to_load,
- load_for_scoring=True,
- )
- )
-
- try:
- LOG.info(
- f"mapping aligmnet df for {pdb_id} to {search_db} for {aln_type}"
- )
- self.map_alignment_df(pdb_id_file, aln_type, search_db).to_parquet(
- pdb_file, index=True
- )
- except Exception as e:
- scratch = (
- Path(*pdb_id_file.parts[:3])
- / "scratch"
- / "scores"
- / "map_alignment_df_failures"
- )
- scratch.mkdir(exist_ok=True, parents=True)
- (scratch / f"{search_db}_{aln_type}_{pdb_id}.txt").write_text(
- f"{repr(e)}: {e}"
- )
- LOG.error(
- f"scoring: Error in map_alignment_df: {pdb_id} searching against {search_db} with {aln_type}: {repr(e)}"
- )
- continue
- else:
- LOG.info(f"skipping creating {pdb_file} because it already exists")
-
- try:
- score_df_path.parent.mkdir(exist_ok=True, parents=True)
- LOG.info(f"aggregating scores for {pdb_id} to {search_db}")
- df = self.aggregate_scores(pdb_id, search_db=search_db)
- if df is not None and not df.empty:
- df.to_parquet(score_df_path, index=False)
- except Exception as e:
- scratch = (
- Path(*score_df_path.parts[:3])
- / "scratch"
- / "scores"
- / "aggregate_scores_failures"
- )
- scratch.mkdir(exist_ok=True, parents=True)
- (scratch / f"{search_db}_{pdb_id}.txt").write_text(f"{repr(e)}: {e}")
- LOG.error(
- f"scoring: Error in aggregate_scores: {pdb_id} searching against {search_db}: {repr(e)}"
- )
- return score_df_path
-
- def load_alignments(
- self,
- source_to_aln_file: dict[str, Path],
- search_db: str = "holo",
- ) -> pd.DataFrame:
- data = []
- for source, aln_file in source_to_aln_file.items():
- sdb, aln_type = source.split("_")
- if sdb != search_db:
- continue
- if not aln_file.exists():
- continue
- aln_df = pd.read_parquet(aln_file)
- aln_df["source"] = aln_type
- aln_df["qrnum"] = aln_df["qrnum"].apply(
- lambda x: dict([(int(i), int(r)) for i, r in x])
- )
- aln_df["trnum"] = aln_df["trnum"].apply(
- lambda x: dict([(int(i), int(r)) for i, r in x])
- )
- if "lddtfull" in aln_df.columns:
- aln_df["lddtfull"] = aln_df["lddtfull"].apply(
- lambda x: dict([(int(i), l) for i, l in x])
- )
- data.append(aln_df)
- if len(data):
- df = pd.concat(data)
- return df.sort_index()
- else:
- return pd.DataFrame()
-
- def map_alignment_df(
- self, df_file: Path, aln_type: str, search_db: str
- ) -> pd.DataFrame:
- df = pd.read_parquet(df_file)
- if aln_type == "foldseek":
- df["query"] = df["query"].replace(
- {"_xyz-enrich.cif.gz": "", "_xyz-enrich.cif": "", "pdb_0000": ""},
- regex=True,
- )
- if search_db == "pred":
- df["target"] = df["target"].replace(
- {"-F1-model_v4.cif": "", "-F1-model_v4": "", "AF-": ""}, regex=True
- )
- else:
- df["target"] = df["target"].replace(
- {"_xyz-enrich.cif.gz": "", "_xyz-enrich.cif": "", "pdb_0000": ""},
- regex=True,
- )
- df["query_chain_mapped"] = (
- df["query"]
- .str.split("_", expand=True)
- .apply(lambda x: self.entries[x[0]].author_to_asym.get(x[1], None), axis=1)
- )
- df = df.dropna(subset=["query_chain_mapped"]).reset_index(drop=True)
- df["query_entry"] = df["query"].str.split("_", expand=True)[0]
- if search_db == "pred":
- df["target_chain_mapped"] = "A"
- else:
- df["target_chain_mapped"] = (
- df["target"]
- .str.split("_", expand=True)
- .apply(
- lambda x: self.entries[x[0]].author_to_asym.get(x[1], None)
- if x[0] in self.entries
- else None,
- axis=1,
- )
- )
- df = df.dropna(subset=["target_chain_mapped"]).reset_index(drop=True)
- df["target_entry"] = df["target"].str.split("_", expand=True)[0]
- df["qaln"] = df["qaln"].str.upper()
- df["taln"] = df["taln"].str.upper()
- df["seqsim"] = df[["qaln", "taln"]].apply(
- lambda x: get_sequence_similarity_helper(x["qaln"], x["taln"]), axis=1
- )
- df["seqsim_qcov"] = df["seqsim"] * df["qcov"]
- df["fident_qcov"] = df["fident"] * df["qcov"]
- if aln_type == "foldseek":
- df["lddt_qcov"] = df["lddt"] * df["qcov"]
- df["lddtaln"] = df["lddtfull"].apply(lambda x: x.split(","))
- df = df.apply(
- lambda x: self.map_row(x, aln_type=aln_type, search_db=search_db), axis=1
- )
- if aln_type == "foldseek":
- df.drop(columns=["lddtaln"], inplace=True)
- df["source"] = aln_type
- df.set_index(
- [
- "query_entry",
- "target_entry",
- "query_chain_mapped",
- "target_chain_mapped",
- "source",
- ],
- inplace=True,
- )
- return df
-
- def map_row(self, parts: pd.Series, aln_type: str, search_db: str) -> pd.Series:
- parts["qrnum"] = []
- parts["trnum"] = []
- parts["lddtfull"] = []
- q_i, t_i = int(parts["qstart"]) - 1, int(parts["tstart"]) - 1
- aln_index = 0
- for x, (q_a, t_a) in enumerate(zip(parts["qaln"], parts["taln"])):
- if q_a != "-" and t_a != "-":
- q_chain = self.entries[parts["query_entry"]].chains[
- parts["query_chain_mapped"]
- ]
- t_chain = (
- self.entries[parts["target_entry"]].chains[
- parts["target_chain_mapped"]
- ]
- if search_db != "pred"
- else None
- )
- if aln_type == "foldseek":
- # it's the residue_index, map to residue_number
- q_n = q_chain.residue_index_to_number.get(q_i, None)
- if t_chain is not None:
- t_n = t_chain.residue_index_to_number.get(t_i, None)
- else:
- t_n = None
- if q_n is not None:
- parts["qrnum"].append((x, q_n))
- parts["lddtfull"].append(
- (x, float(parts["lddtaln"][aln_index]))
- )
- if t_n is not None:
- parts["trnum"].append((x, t_n))
- elif aln_type == "mmseqs":
- if q_i in q_chain.residues:
- parts["qrnum"].append((x, q_i))
- if t_chain is not None and t_i in t_chain.residues:
- parts["trnum"].append((x, t_i))
- aln_index += 1
- if q_a != "-":
- q_i += 1
- if t_a != "-":
- t_i += 1
- return parts
-
- def get_protein_scores_pair(self, aln: pd.DataFrame) -> dict[str, float]:
- scores = {}
- for source, data in aln.iterrows():
- for score in ["qcov", "fident", "seqsim", "fident_qcov", "seqsim_qcov"]:
- scores[f"protein_{score}_{source}"] = data[score]
- if source == "foldseek":
- for score in ["lddt", "lddt_qcov"]:
- scores[f"protein_{score}_{source}"] = data[score]
- return scores
-
- def get_protein_scores(
- self,
- query_target_entry_alignments: pd.DataFrame,
- query_system: System,
- target_protein_chains: list[str],
- query_system_length: int,
- ) -> tuple[
- dict[str, list[_ChainPairType]],
- _SimilarityScoreDictType,
- dict[_ChainPairType, pd.DataFrame],
- str,
- ]:
- scores: _SimilarityScoreDictType = defaultdict(float)
- mappings: dict[str, list[_ChainPairType]] = defaultdict(list)
- max_chain_lengths: dict[str, float] = defaultdict(float)
- protein_chain_mapper = ""
- s_matrix = np.zeros(
- (len(query_system.protein_chains_asym_id), len(target_protein_chains))
- )
- for i, q_instance_chain in enumerate(query_system.protein_chains_asym_id):
- q_chain = q_instance_chain.split(".")[1]
- q_chain_length = self.entries[query_system.pdb_id].chains[q_chain].length
- for j, t_instance_chain in enumerate(target_protein_chains):
- t_chain = t_instance_chain.split(".")[1]
- try:
- aln = query_target_entry_alignments.loc[q_chain].loc[t_chain]
- except KeyError:
- LOG.debug("get_protein_scores indexing failed, aln is None")
- aln = None
- if aln is not None:
- pair = (q_instance_chain, t_instance_chain)
- pair_scores = self.get_protein_scores_pair(aln)
- if protein_chain_mapper == "":
- for chain_mapper in self.protein_chain_mappers:
- if chain_mapper in pair_scores:
- protein_chain_mapper = chain_mapper
- break
- s_matrix[i, j] = pair_scores.get(protein_chain_mapper, 0)
- for score in pair_scores:
- if (
- pair_scores[score] * q_chain_length
- > scores[f"{score}_weighted_max"]
- ):
- scores[f"{score}_weighted_max"] = (
- pair_scores[score] * q_chain_length
- )
- max_chain_lengths[f"{score}_weighted_max"] = q_chain_length
- mappings[f"{score}_weighted_max"] = [pair]
- if pair_scores[score] > scores[f"{score}_max"]:
- scores[f"{score}_max"] = pair_scores[score]
- mappings[f"{score}_max"] = [pair]
- for score in scores:
- if score.endswith("_weighted_max") and max_chain_lengths[score] > 0:
- scores[score] /= max_chain_lengths[score]
-
- # do chain mapping
- # Find the highest scores along with their indices in the matrix
- alns = {}
- while np.any(s_matrix):
- # changed score -> score_tag conflicting variable name
- score_val = np.amax(s_matrix)
- if score_val == 0:
- break
- q_idx, t_idx = np.unravel_index(np.argmax(s_matrix), s_matrix.shape)
- q_instance_chain, t_instance_chain = (
- query_system.protein_chains_asym_id[q_idx],
- target_protein_chains[t_idx],
- )
- q_chain, t_chain = (
- q_instance_chain.split(".")[1],
- t_instance_chain.split(".")[1],
- )
- try:
- aln = query_target_entry_alignments.loc[(q_chain, t_chain)]
- except KeyError:
- break
- pair = (q_instance_chain, t_instance_chain)
- pair_scores = self.get_protein_scores_pair(aln)
- for score in pair_scores:
- scores[f"{score}_weighted_sum"] += (
- pair_scores[score]
- * self.entries[query_system.pdb_id].chains[q_chain].length
- )
- alns[pair] = aln
-
- mappings[f"{protein_chain_mapper}_weighted_sum"].append(pair)
- # Zero out the entire row and column for the max element
- s_matrix[q_idx, :] = 0
- s_matrix[:, t_idx] = 0
- for score in scores:
- if score.endswith("_weighted_sum") and query_system_length > 0:
- scores[score] /= query_system_length
- return mappings, scores, alns, protein_chain_mapper
-
- def get_pocket_pli_scores(
- self,
- alns: dict[_ChainPairType, pd.DataFrame],
- query_system: System,
- target_system: System | None = None,
- ) -> tuple[
- _SimilarityScoreDictType,
- _SimilarityScoreDictType,
- ]:
- pocket_scores: _SimilarityScoreDictType = defaultdict(float)
- pli_scores: _SimilarityScoreDictType = defaultdict(float)
- pocket_length = query_system.num_pocket_residues
- pli_length = query_system.num_interactions
- pli_unique_length = query_system.num_unique_interactions
- for q_instance_chain, t_instance_chain in alns:
- aln = alns[(q_instance_chain, t_instance_chain)]
- q_pocket = query_system.pocket_residues.get(q_instance_chain, {})
- q_interactions = query_system.interactions_counter.get(q_instance_chain, {})
- if target_system is not None:
- t_pocket = target_system.pocket_residues.get(t_instance_chain, {})
- t_interactions = target_system.interactions_counter.get(
- t_instance_chain, {}
- )
- for source, aln_source in aln.iterrows():
- for i in aln_source["qrnum"]:
- q_a, t_a, lddt, q_n, t_n = (
- aln_source["qaln"][i],
- aln_source["taln"][i],
- aln_source["lddtfull"].get(i, 0),
- aln_source["qrnum"][i],
- aln_source["trnum"].get(i, None),
- )
- assert q_a != "-" and t_a != "-"
- if q_n in q_pocket:
- pocket_scores[f"pocket_lddt_{source}"] += lddt
- if q_a == t_a:
- pocket_scores[f"pocket_fident_{source}"] += 1
- if (
- target_system is not None
- and t_n is not None
- and t_n in t_pocket
- ):
- pocket_scores[f"pocket_qcov_{source}"] += 1
- pocket_scores[f"pocket_lddt_qcov_{source}"] += lddt
- if q_a == t_a:
- pocket_scores[f"pocket_fident_qcov_{source}"] += 1
- if q_n in q_interactions and t_n in t_interactions:
- pli_scores[f"pli_qcov_{source}"] += sum(
- (q_interactions[q_n] & t_interactions[t_n]).values()
- )
- pli_scores[f"pli_unique_qcov_{source}"] += len(
- (
- set(q_interactions[q_n].values())
- & set(t_interactions[t_n].values())
- )
- )
- for score in pocket_scores:
- pocket_scores[score] /= pocket_length
- for score in pli_scores:
- if "unique" in score:
- pli_scores[score] /= pli_unique_length
- else:
- pli_scores[score] /= pli_length
- return pocket_scores, pli_scores
-
- def get_scores(
- self, search_db: str, query_system: System, query_entry_alignments: pd.DataFrame
- ) -> abc.Generator[dict[str, str | float], None, None]:
- if search_db == "holo":
- return self.get_scores_holo(query_system, query_entry_alignments)
- elif search_db == "apo" or search_db == "pred":
- return self.get_scores_apo_pred(query_system, query_entry_alignments)
- else:
- raise ValueError(f"Invalid search_db: {search_db}")
-
- def get_scores_holo(
- self, query_system: System, query_entry_alignments: pd.DataFrame
- ) -> abc.Generator[dict[str, str | float], None, None]:
- query_system_length = sum(
- self.entries[query_system.pdb_id]
- .chains[q_instance_chain.split(".")[1]]
- .length
- for q_instance_chain in query_system.protein_chains_asym_id
- )
- query_instance_chains = [
- chain.split(".")[1] for chain in query_system.protein_chains_asym_id
- ]
- for target_entry in query_entry_alignments.index.get_level_values(
- "target_entry"
- ).unique():
- if target_entry not in self.entries:
- # No data for this target entry
- continue
- query_target_entry_alignments = query_entry_alignments.loc[target_entry]
- query_chain_mapped_values = set(
- query_target_entry_alignments.index.get_level_values(
- "query_chain_mapped"
- )
- )
- if all(
- chain not in query_chain_mapped_values
- for chain in query_instance_chains
- ):
- # No alignments for this query system
- continue
- all_target_chains: set[str] = set()
- for q_chain in query_instance_chains:
- if q_chain in query_chain_mapped_values:
- all_target_chains.update(
- query_target_entry_alignments.loc[
- q_chain
- ].index.get_level_values("target_chain_mapped")
- )
-
- for target_system_id in self.entries[target_entry].systems:
- target_system = self.entries[target_entry].systems[target_system_id]
- if target_system.system_type != "holo":
- continue
- if target_system_id == query_system.id or all(
- target_instance_chain.split(".")[1] not in all_target_chains
- for target_instance_chain in target_system.protein_chains_asym_id
- ):
- # Same as query system or No alignments for this target system
- continue
- q_t_scores: dict[str, float] = {}
-
- # Protein score calculation
- (
- q_t_mappings,
- protein_scores,
- alns,
- protein_chain_mapper,
- ) = self.get_protein_scores(
- query_target_entry_alignments,
- query_system,
- target_system.protein_chains_asym_id,
- query_system_length,
- )
- if not len(protein_scores):
- continue
- q_t_scores.update(protein_scores)
-
- # Pocket and PLI score calculation
- (
- pocket_scores,
- pli_scores,
- ) = self.get_pocket_pli_scores(alns, query_system, target_system)
- q_t_scores.update(pocket_scores)
- q_t_scores.update(pli_scores)
- q_t_scores_combined = combine_scores(
- q_t_scores, q_t_mappings, protein_chain_mapper
- )
- q_t_scores_combined["target_system"] = target_system.id
- q_t_scores_combined["query_system"] = query_system.id
- yield q_t_scores_combined
-
- def _get_suffixes(self, s: str) -> list[str]:
- suffixes = ["_weighted_sum", "_weighted_max", "_max"]
- if not s.startswith("protein"):
- suffixes = [""]
- return suffixes
-
- def get_column_mapr(self) -> dict[str, list[str]]:
- mapr = {"info": [x for x in INFO_COLUMNS]}
- for s in SCORE_NAMES:
- suffixes = self._get_suffixes(s)
- for suffix in suffixes:
- mapr[f"{s}{suffix}"] = [
- f"{s}{suffix}",
- f"{s}{suffix}_source",
- f"{s}{suffix}_mapping",
- ]
- return mapr
-
- def aggregate_scores(
- self,
- pdb_id: str,
- search_db: str = "holo",
- ) -> Optional[pd.DataFrame]:
- alignments = self.load_alignments(
- search_db=search_db,
- source_to_aln_file={
- f"{search_db}_{aln_type}": self.db_dir
- / f"{search_db}_{aln_type}"
- / "mapped_aln"
- / f"{pdb_id}.parquet"
- for aln_type in ["foldseek", "mmseqs"]
- },
- )
- if alignments.empty:
- return None
- column_mapr = self.get_column_mapr()
- pdb_vals = []
- for system in self.entries[pdb_id].systems.values():
- if system.system_type != "holo":
- continue
- for score_dict in self.get_scores(
- search_db, system, alignments.loc[pdb_id]
- ):
- info = {}
- grouped: dict[str, dict[str, str | float]] = {}
- # iterate over groups of columns instead of raw list of columns
- for metric, columns in column_mapr.items():
- for column in columns:
- score = score_dict.get(column)
- if score is None:
- continue
- if metric == "info":
- info[column] = score
- else:
- grouped.setdefault(metric, {})
- abbr_column = column.replace(metric, "", 1).lstrip("_")
- if not abbr_column:
- abbr_column = "similarity"
- if np.isnan(score):
- continue
- grouped[metric][abbr_column] = score
- for metric, values in grouped.items():
- if len(values) and values.get("similarity") is not None:
- pdb_vals.append({**info, **values, **{"metric": metric}})
- if not len(pdb_vals):
- return None
- df = pd.DataFrame(pdb_vals)
- all_thresholds = [
- (m, self.minimum_thresholds.get(m, self.minimum_threshold))
- for m in df["metric"].unique()
- ]
- query = " or ".join(
- [f"(metric=='{m}' and similarity>={t})" for (m, t) in all_thresholds]
- )
- df = df.query(query).copy()
- for col in [
- "protein_mapper",
- "source",
- "metric",
- ]:
- df[col] = df[col].astype("category")
- df["similarity"] = (df["similarity"] * 100).apply(round).astype(np.int8)
- columns = [col for (col, _) in SORT_ORDER]
- ascending = [direction == "ascending" for (_, direction) in SORT_ORDER]
- return df.sort_values(by=columns, ascending=ascending)
-
- def get_scores_apo_pred(
- self, query_system: System, query_entry_alignments: pd.DataFrame
- ) -> abc.Generator[dict[str, str | float], None, None]:
- q_chain = query_system.protein_chains_asym_id[0].split(".")[1]
- query_system_length = sum(
- self.entries[query_system.pdb_id]
- .chains[q_instance_chain.split(".")[1]]
- .length
- for q_instance_chain in query_system.protein_chains_asym_id
- )
- for target_entry in query_entry_alignments.index.get_level_values(
- "target_entry"
- ).unique():
- query_target_entry_alignments = query_entry_alignments.loc[target_entry]
- try:
- q_chain_alignments = query_target_entry_alignments.loc[q_chain]
- except KeyError:
- q_chain_alignments = None
- if q_chain_alignments is not None:
- for t_chain in q_chain_alignments.index.get_level_values(
- "target_chain_mapped"
- ).unique():
- if (
- target_entry in self.entries
- and self.entries[target_entry].chains[t_chain].holo
- ):
- continue
- q_t_scores: dict[str, float] = {}
- # Protein score calculation
- (
- q_t_mappings,
- protein_scores,
- alns,
- protein_chain_mapper,
- ) = self.get_protein_scores(
- query_target_entry_alignments,
- query_system,
- [f"0.{t_chain}"],
- query_system_length,
- )
-
- if len(alns) == 0 or not len(protein_scores):
- continue
- q_t_scores.update(protein_scores)
- # Pocket score calculation
- q_t_scores.update(self.get_pocket_pli_scores(alns, query_system)[0])
- q_t_scores_combined = combine_scores(
- q_t_scores, q_t_mappings, protein_chain_mapper
- )
- q_t_scores_combined["target_system"] = f"{target_entry}_{t_chain}"
- q_t_scores_combined["query_system"] = query_system.id
- yield q_t_scores_combined
diff --git a/src/plinder/data/utils/annotations/interaction_utils.py b/src/plinder/data/utils/annotations/interaction_utils.py
deleted file mode 100644
index 354952c41..000000000
--- a/src/plinder/data/utils/annotations/interaction_utils.py
+++ /dev/null
@@ -1,371 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-from collections import defaultdict
-from pathlib import Path
-
-import gemmi
-from mmcif.api.PdbxContainers import DataContainer
-from ost import io, mol
-from plip.basic.supplemental import whichchain, whichresnumber
-from plip.structure.preparation import PDBComplex, PLInteraction
-
-from plinder.core.utils.log import setup_logger
-
-log = setup_logger(__name__)
-
-INTERACTION_TYPES = [
- "hbonds_ldon",
- "hbonds_pdon",
- "hydrophobic_contacts",
- "pication_laro",
- "pication_paro",
- "halogen_bonds",
- "pistacking",
- "water_bridges",
- "saltbridge_lneg",
- "saltbridge_pneg",
- "metal_complexes",
-]
-
-# Define available names for chains in PDB format
-PDB_AVAILABLE_CHAINS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-PDB_AVAILABLE_CHAINS += PDB_AVAILABLE_CHAINS.lower() + "0123456789"
-
-
-def get_symmetry_mate_contacts(
- mmcif_filename: Path, contact_threshold: float = 5.0
-) -> dict[tuple[str, int], dict[tuple[str, int], set[int]]]:
- """
- Get all contacts within a given threshold between residues which are not in the same asymmetric unit (symmetry mates)
- """
- cif = gemmi.read_structure(mmcif_filename.__str__(), merge_chain_parts=False)
- cif.setup_entities()
- ns = gemmi.NeighborSearch(cif[0], cif.cell, contact_threshold).populate(
- include_h=False
- )
- cs = gemmi.ContactSearch(contact_threshold)
- cs.ignore = gemmi.ContactSearch.Ignore.SameAsu
- cs.twice = True
- pairs = cs.find_contacts(ns)
- results: dict[tuple[str, int], dict[tuple[str, int], set[int]]] = defaultdict(
- lambda: defaultdict(set)
- )
- for p in pairs:
- if p.partner1.residue.is_water() or p.partner2.residue.is_water():
- continue
- i1, i2 = p.partner1.residue.label_seq, p.partner2.residue.label_seq
- if i1 is None:
- i1 = 1
- if i2 is None:
- i2 = 1
- c1, c2 = p.partner1.residue.subchain, p.partner2.residue.subchain
- results[(c1, i1)][(c2, i2)].add(p.partner1.atom.serial)
- return results
-
-
-def get_covalent_connections(data: DataContainer) -> dict[str, list[tuple[str, str]]]:
- """
- Get covalent connections from any mmcif file with
- _struct_conn. attribute
-
- Parameters
- ----------
- mmcif_file : Path
- mmcif file with _struct_conn. attribute
-
- Returns
- -------
- Dict[str, List[Set[str]]]
- Mapping of covalent residues
- """
-
- cov_dict = defaultdict(list)
- nucleobase_list = ["A", "C", "U", "G", "DA", "DC", "DG", "DT", "PSU"]
-
- to_extract = [
- "ptnr1_label_asym_id",
- "ptnr2_label_asym_id",
- "ptnr1_label_seq_id",
- "ptnr2_label_seq_id",
- "ptnr1_auth_seq_id",
- "ptnr2_auth_seq_id",
- "ptnr1_label_comp_id",
- "ptnr2_label_comp_id",
- "ptnr1_label_atom_id",
- "ptnr2_label_atom_id",
- "conn_type_id",
- ]
- cons = data.getObj("struct_conn")
- if cons is None:
- return {}
- for con in cons.getCombinationCountsWithConditions(
- to_extract, [("conn_type_id", "in", ["covale", "metalc", "hydrog"])]
- ):
- con = dict(zip(to_extract, con))
-
- if con["conn_type_id"] == "hydrog":
- if con["ptnr1_label_comp_id"].strip() not in nucleobase_list:
- continue
- cov_dict[con["conn_type_id"]].append(
- (
- ":".join(
- [
- con["ptnr1_auth_seq_id"],
- con["ptnr1_label_comp_id"],
- con["ptnr1_label_asym_id"],
- con["ptnr1_label_seq_id"],
- con["ptnr1_label_atom_id"],
- ]
- ),
- ":".join(
- [
- con["ptnr2_auth_seq_id"],
- con["ptnr2_label_comp_id"],
- con["ptnr2_label_asym_id"],
- con["ptnr2_label_seq_id"],
- con["ptnr2_label_atom_id"],
- ]
- ),
- )
- )
- return cov_dict
-
-
-def extract_ligand_links_to_neighbouring_chains(
- all_covalent_dict: dict[str, list[tuple[str, str]]],
- ligand_asym_id: str,
- neighboring_asym_ids: set[str],
- link_type: str = "covale",
-) -> set[str]:
- covalent_linkages = set()
- if link_type in all_covalent_dict:
- for link1, link2 in all_covalent_dict[link_type]:
- chain1, chain2 = link1.split(":")[2], link2.split(":")[2]
- chains = {chain1, chain2}
- if len(chains) == 1:
- # remove linkages that are to the same chain!
- continue
- if set(chains).intersection(ligand_asym_id):
- # only if ligand is involved
- # now check that one chain is neighbour and the other is ligand
- # enforce receptor_ligand ordering
- if neighboring_asym_ids.intersection([chain1]) and set(
- [chain2]
- ).intersection(ligand_asym_id):
- covalent_linkages.add(f"{link1}__{link2}")
- elif neighboring_asym_ids.intersection(chain2) and set(
- [chain1]
- ).intersection(ligand_asym_id):
- covalent_linkages.add(f"{link2}__{link1}")
- return covalent_linkages
-
-
-def run_plip(biounit_pdbized: mol.EntityHandle) -> PDBComplex:
- """Load pdbized biounit and run plip analysis.
-
- Parameters
- ----------
- biounit_pdbized : mol.EntityHandle
- pdbized biounit
-
- Returns
- -------
- PDBComplex
- Complex interaction object with all plip related annotation computed
- """
-
- complex_obj = PDBComplex()
- complex_obj.load_pdb(io.EntityToPDBStr(biounit_pdbized).strip(), as_string=True)
- complex_obj.analyze()
- return complex_obj
-
-
-def pdbize(
- full_biounit: mol.EntityHandle, entity: mol.EntityHandle
-) -> mol.EntityHandle:
- """PDBize entity chains
-
- Parameters
- ----------
- entity : mol.EntityHandle
- Entity handle
- Returns
- -------
- mol.EntityHandle
- PDBized entity handle
- """
- # Intermediate renaming step
- intermediate_names = {}
- edi = entity.EditXCS(mol.BUFFERED_EDIT)
- for i, chain in enumerate(entity.GetChainList()):
- intermediate_names[f"T{i}"] = chain.name
- edi.RenameChain(chain, f"T{i}")
- edi.UpdateICS()
- # Final renaming step
- chain_index = 0
- name_mapping = {}
- for chain in entity.GetChainList():
- original_name = intermediate_names[chain.name]
- original_chain = full_biounit.FindChain(original_name)
- if chain_index >= len(PDB_AVAILABLE_CHAINS):
- raise ValueError(f"Too many chains ({chain_index}) in entity")
- final_name = PDB_AVAILABLE_CHAINS[chain_index]
- chain_index += 1
- edi.RenameChain(chain, final_name)
- edi.SetChainDescription(chain, original_chain.description)
- edi.SetChainType(chain, original_chain.type)
- name_mapping[original_name] = final_name
- edi.UpdateICS()
- return entity, name_mapping
-
-
-def run_plip_on_split_structure(
- biounit: mol.EntityHandle,
- biounit_selection: mol.EntityHandle,
- ligand_chain: str,
-) -> tuple[PLInteraction, dict[str, str]] | None:
- """Split structure into small PLI complex by ligand
-
- For every ligand, create a smaller complex for faster plip\
- process and deal with cases where plip ignores small molecule
- ligands in the presence of peptides
-
- Parameters
- ----------
- biounit : mol.EntityHandle
- biounit
- biounit_selection : mol.EntityHandle
- selection in biounit of threshold around ligand
- ligand_chain: str
- {instance}.{chain} of ligand
-
- Returns
- -------
- Tuple[PlipLigand, PDBComplex, dict[str, str]] | None
- PLIP ligand, PLIP complex object, mapping of original chain to plip chain
- """
- from plip.basic import config
-
- config.biolip_list = []
- split_structure, chain_mapping = pdbize(biounit, biounit_selection)
- ligand_plip_chain = chain_mapping[ligand_chain]
- config.PEPTIDES = (
- [ligand_plip_chain] if biounit.FindChain(ligand_chain).is_polymer else []
- )
- # TODO: review this - we might be treating some peptidic ligands as protein here
- # Consider passing ligand_like_chains to here, too
-
- complex_obj = run_plip(split_structure)
- ligand_list = [l for l in complex_obj.ligands if l.chain == ligand_plip_chain]
- if not len(ligand_list):
- log.warning(
- f"Could not find ligand at chain {ligand_plip_chain}, originally {ligand_chain}" # in {entry_pdb_id}"
- )
- return None
- ligand = ligand_list[0]
- lig_tag = f"{ligand.hetid}:{ligand.chain}:{ligand.position}"
- interactions = complex_obj.interaction_sets[lig_tag]
- chain_mapping = {v: k for k, v in chain_mapping.items()}
- return interactions, chain_mapping
-
-
-def get_plip_hash(
- interactions: PLInteraction,
- chain: str,
- plip_chain_mapping: dict[str, str],
-) -> tuple[dict[str, dict[int, list[str]]], set[(tuple[str, int])]]:
- """Get fingerprint hash from plip interaction object
-
- Parameters
- ----------
- interactions : PLInteraction
- plip interaction object for a given ligand
- chain: str
- ligand chain
- plip_chain_mapping : Dict[str, str]
- chain mapping from plip chain ID to instance.asym ID
-
- Returns
- -------
- str
- plip fingerprint hash
- """
-
- interaction_hashes: dict[str, dict[int, list[str]]] = dict()
- waters = set()
- for int_type in INTERACTION_TYPES:
- int_objs = getattr(interactions, int_type)
- interaction_attributes = []
- if int_type in ["hbonds_ldon", "hbonds_pdon"]:
- for int_obj in int_objs:
- interaction_attributes.append(
- "type:hydrogen_bonds"
- # + f"__donortype:{int_obj.dtype}__acceptortype:{int_obj.atype}"
- + f"__protisdon:{int_obj.protisdon}__sidechain:{int_obj.sidechain}"
- )
- elif int_type == "water_bridges":
- for int_obj in int_objs:
- interaction_attributes.append(
- "type:water_bridges"
- # + f"__donortype:{int_obj.dtype}__acceptortype:{int_obj.atype}"
- + f"__protisdon:{int_obj.protisdon}"
- )
- waters.add((whichchain(int_obj.water), whichresnumber(int_obj.water)))
- elif int_type == "hydrophobic_contacts":
- for int_obj in int_objs:
- interaction_attributes.append("type:hydrophobic_contacts")
- elif int_type in ["pication_laro", "pication_paro"]:
- for int_obj in int_objs:
- if int_obj.protcharged:
- group = "Aromatic"
- else:
- # group = int_obj.charge.fgroup
- group = "Cation"
- interaction_attributes.append(
- "type:pi_cation"
- + f"__lig_group:{group}"
- + f"__protcharged:{int_obj.protcharged}"
- )
- elif int_type == "halogen_bonds":
- for int_obj in int_objs:
- interaction_attributes.append(
- "type:halogen_bonds"
- # + f"__donortype:{int_obj.donortype}"
- # + f"__acceptortype:{int_obj.acctype}"
- + f"__sidechain:{int_obj.sidechain}"
- )
- elif int_type == "pistacking":
- for int_obj in int_objs:
- interaction_attributes.append(
- f"type:pi_stacks__stack_type:{int_obj.type}"
- )
- elif int_type in ["saltbridge_lneg", "saltbridge_pneg"]:
- for int_obj in int_objs:
- interaction_attributes.append(
- "type:salt_bridges"
- # + f"__pos_group:{int_obj.positive.fgroup}__neg_group:{int_obj.negative.fgroup}"
- + f"__protispos:{int_obj.protispos}"
- )
- elif int_type == "metal_complexes":
- for int_obj in int_objs:
- interaction_attributes.append(
- "type:metal_complexes"
- + f"__metal_type:{int_obj.metal_type}__target_type:"
- + f"{int_obj.target_type}__coordination:{int_obj.coordination_num}__geometry:"
- + f"{int_obj.geometry}__location:{int_obj.location}"
- )
- for int_obj, int_attr in zip(int_objs, interaction_attributes):
- instance_chain, resnr = (
- plip_chain_mapping[int_obj.reschain],
- int(int_obj.resnr),
- )
- if instance_chain == chain:
- continue
- if instance_chain not in interaction_hashes:
- interaction_hashes[instance_chain] = dict()
- if resnr not in interaction_hashes[instance_chain]:
- interaction_hashes[instance_chain][resnr] = []
- interaction_hashes[instance_chain][resnr].append(int_attr)
- return interaction_hashes, waters
diff --git a/src/plinder/data/utils/annotations/interface_gap.py b/src/plinder/data/utils/annotations/interface_gap.py
deleted file mode 100644
index cf731bf3d..000000000
--- a/src/plinder/data/utils/annotations/interface_gap.py
+++ /dev/null
@@ -1,205 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-from pathlib import Path
-from typing import Any
-
-import numpy as np
-import pandas as pd
-from biotite import structure as struc
-from biotite.structure import AtomArray
-
-from plinder.core.structure.atoms import (
- atom_array_from_cif_file,
-)
-from plinder.core.structure.contacts import (
- get_atom_neighbors,
- label_structure_gaps,
- pairwise_chain_contacts,
-)
-from plinder.core.utils.log import setup_logger
-
-log = setup_logger(__name__)
-
-
-def get_contacts_gaps_overlap(
- atoms: AtomArray,
- gaps: pd.DataFrame | None,
- contacts: pd.DataFrame,
- pdb_id: str,
- smaller_radius: float = 4.0,
- larger_radius: float = 8.0,
-) -> pd.DataFrame | None:
- smaller_radius = 4.0
- larger_radius = 8.0
- annotations = []
-
- for i, r in contacts.iterrows():
- ch1 = r.chain1
- ch2 = r.chain2
- resid1 = r.resid1
- resid2 = r.resid2
- conts = r.contacts
-
- annotation = {
- "pdb_id": pdb_id,
- "chain1": ch1,
- "resid1": resid1,
- "chain2": ch2,
- "resid2": resid2,
- }
- if len(conts) == 0:
- continue
-
- ch1_resi = set([p[0] for p in conts])
- ch2_resi = set([p[1] for p in conts])
-
- interface_mask = (
- (atoms.chain_id == ch1) & np.isin(atoms.res_id, list(ch1_resi))
- ) | ((atoms.chain_id == ch2) & np.isin(atoms.res_id, list(ch2_resi)))
- interface = atoms[interface_mask].copy()
- if gaps is None:
- continue
- ch1_gaps = gaps.query(f'chain == "{ch1}"')
- ch2_gaps = gaps.query(f'chain == "{ch2}"')
- ch1_gaps = set(ch1_gaps.gap_start).union(set(ch1_gaps.gap_end))
- ch2_gaps = set(ch2_gaps.gap_start).union(set(ch2_gaps.gap_end))
- gap_mask = ((atoms.chain_id == ch1) & np.isin(atoms.res_id, list(ch1_gaps))) | (
- (atoms.chain_id == ch2) & np.isin(atoms.res_id, list(ch2_gaps))
- )
- gap_atoms = atoms[gap_mask].copy()
-
- if not gap_atoms.shape[0]:
- continue
-
- for radius in [smaller_radius, larger_radius]:
- rad_label = int(round(radius, 0))
- gap_neigh = get_atom_neighbors(interface, gap_atoms, radius=radius)
- annot = pd.DataFrame(
- [
- {"resi": at.res_id, "resn": at.res_name, "chain": at.chain_id}
- for at in gap_neigh
- ]
- )
- missing_interface_res = 0
- if annot.empty:
- annotation[f"interface_atom_gaps_{rad_label}A"] = 0
- annotation[f"missing_interface_residues_{rad_label}A"] = 0
- else:
- for ch, ch_gap in [(ch1, ch1_gaps), (ch2, ch2_gaps)]:
- missing_interface_res += len(
- set(annot.query(f'chain == "{ch}"').resi).intersection(ch_gap)
- )
- annotation[f"interface_atom_gaps_{rad_label}A"] = annot.shape[0]
- annotation[
- f"missing_interface_residues_{rad_label}A"
- ] = missing_interface_res
-
- annotations.append(annotation)
-
- return annotations
-
-
-# TODO: review this function
-# it does not use the ligand chain definitions!
-def annotate_interface_gaps(
- cif_file: Path,
- protein_chains: list[str] | None = None,
- ligand_chains: list[str] | None = None,
- smaller_radius: float = 4.0,
- larger_radius: float = 8.0,
- use_author_fields: bool = False,
-) -> dict[str, Any]:
- pdb_id = cif_file.stem.split("_")[0].replace("pdb_0000", "")
-
- if ".cif" in cif_file.name:
- atoms = atom_array_from_cif_file(cif_file, use_author_fields=use_author_fields)
- else:
- raise ValueError(f"unsupported file extension: {cif_file}")
- assert atoms is not None
-
- # Complex atom array
- lig_filter = atoms.hetero
- prot_filter = struc.filter_amino_acids(atoms)
-
- if ligand_chains is not None:
- # Filter atoms of interest
- lig_filter = atoms.hetero & np.isin(atoms.chain_id, np.array(ligand_chains))
- if protein_chains is not None:
- prot_filter = struc.filter_amino_acids(atoms) & np.isin(
- atoms.chain_id,
- np.array(protein_chains),
- )
- prot_arr = atoms[prot_filter].copy()
- complex_arr = atoms[prot_filter | lig_filter].copy()
- ppi_contacts, pli_contacts = pairwise_chain_contacts(complex_arr)
- gaps = label_structure_gaps(prot_arr)
- pli_missing_df = pd.DataFrame(
- get_contacts_gaps_overlap(
- atoms,
- gaps,
- pli_contacts,
- pdb_id,
- smaller_radius,
- larger_radius,
- )
- )
- ppi_missing_df = pd.DataFrame(
- get_contacts_gaps_overlap(
- atoms,
- gaps,
- ppi_contacts,
- pdb_id,
- smaller_radius,
- larger_radius,
- )
- )
- ppi_missing_dict: dict[str, dict[tuple[str, str], dict[str, int]]] = {}
- pli_missing_dict: dict[str, dict[tuple[str, str], dict[str, int]]] = {}
- if not ppi_missing_df.empty:
- ppi_missing_df["chain1_chain2"] = ppi_missing_df[["chain1", "chain2"]].apply(
- tuple, axis=1
- )
- ppi_missing_df.set_index("chain1_chain2", inplace=True)
- if ppi_missing_df.index.duplicated().any():
- log.warning(
- f"found duplicate chain1_chain2 in ppi_missing_df for {cif_file}"
- )
- ppi_missing_df = ppi_missing_df[
- ~ppi_missing_df.index.duplicated(keep="first")
- ]
- ppi_missing_dict = ppi_missing_df[
- [
- "interface_atom_gaps_4A",
- "missing_interface_residues_4A",
- "interface_atom_gaps_8A",
- "missing_interface_residues_8A",
- ]
- ].to_dict(orient="index")
- if not pli_missing_df.empty:
- pli_missing_df["chain1_chain2"] = pli_missing_df[["chain1", "chain2"]].apply(
- tuple, axis=1
- )
-
- pli_missing_df.set_index("chain1_chain2", inplace=True)
- if pli_missing_df.index.duplicated().any():
- log.warning(
- f"found duplicate chain1_chain2 in pli_missing_df for {cif_file}"
- )
- pli_missing_df = pli_missing_df[
- ~pli_missing_df.index.duplicated(keep="first")
- ]
- pli_missing_dict = pli_missing_df[
- [
- "interface_atom_gaps_4A",
- "missing_interface_residues_4A",
- "interface_atom_gaps_8A",
- "missing_interface_residues_8A",
- ]
- ].to_dict(orient="index")
-
- return {
- "ppi_interface_gap_annotation": ppi_missing_dict,
- "ligand_interface_gap_annotation": pli_missing_dict,
- }
diff --git a/src/plinder/data/utils/annotations/ligand_utils.py b/src/plinder/data/utils/annotations/ligand_utils.py
deleted file mode 100644
index a5ccff606..000000000
--- a/src/plinder/data/utils/annotations/ligand_utils.py
+++ /dev/null
@@ -1,1546 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-import itertools
-import logging
-import re
-import typing as ty
-from collections import Counter, defaultdict
-from functools import cache, cached_property
-from pathlib import Path
-
-import numpy as np
-import pandas as pd
-from mmcif.api.PdbxContainers import DataContainer
-from openbabel import pybel
-from ost import io, mol
-from ost.conop import GetDefaultLib
-from pydantic import BeforeValidator, Field
-from rdkit import Chem, RDLogger
-from rdkit.Chem import QED, AllChem, Crippen, rdMolDescriptors
-from rdkit.Chem.rdchem import Mol, RWMol
-
-from plinder.core.utils.config import get_config
-from plinder.core.utils.constants import BASE_DIR
-from plinder.data.utils.annotations.interaction_utils import (
- extract_ligand_links_to_neighbouring_chains,
- get_plip_hash,
- pdbize,
- run_plip_on_split_structure,
-)
-from plinder.data.utils.annotations.protein_utils import Chain
-from plinder.data.utils.annotations.rdkit_utils import set_smiles_from_ligand_ost
-from plinder.data.utils.annotations.utils import DocBaseModel
-
-# TODO: replace above with below
-# from plinder.data.utils.annotations.rdkit_utils import set_smiles_from_ligand_ost_v2
-
-COMPOUND_LIB = GetDefaultLib()
-PEPTIDE_TYPES = [
- mol.CHAINTYPE_POLY,
- mol.CHAINTYPE_POLY_PEPTIDE_D,
- mol.CHAINTYPE_POLY_PEPTIDE_L,
-]
-
-DNA_TYPES = [mol.CHAINTYPE_POLY_DN]
-
-RNA_TYPES = [mol.CHAINTYPE_POLY_RN]
-
-MIXED_NUCLEIC_ACID_TYPES = [mol.CHAINTYPE_POLY_DN_RN, mol.CHAINTYPE_POLY_PEPTIDE_DN_RN]
-
-OLIGOSACCHARIDE_TYPES = [
- mol.CHAINTYPE_POLY_SAC_D,
- mol.CHAINTYPE_POLY_SAC_L,
- mol.CHAINTYPE_OLIGOSACCHARIDE,
- mol.CHAINTYPE_BRANCHED,
-]
-
-MACROCYCLE_TYPES = [mol.CHAINTYPE_MACROLIDE, mol.CHAINTYPE_CYCLIC_PSEUDO_PEPTIDE]
-
-NON_SMALL_MOL_LIG_TYPES = (
- PEPTIDE_TYPES
- + DNA_TYPES
- + RNA_TYPES
- + MIXED_NUCLEIC_ACID_TYPES
- + OLIGOSACCHARIDE_TYPES
- + MACROCYCLE_TYPES
-)
-
-
-def lig_has_dummies(
- ligand_code: str,
- dummy_lig_list: list[str] = [
- "DUM",
- "UNX",
- "ASX",
- "GLX",
- "UNL",
- "UNK",
- "UPL",
- "DN",
- "N",
- ],
-) -> bool:
- """Check for ccd codes containing dummy/unknown entries
-
- Args:
- ligand_code str: ligand CCD code
- dummy_lig_list (list, optional): list of ccd codes for unknown or dummy entries.
- Defaults to ['DUM', 'UNX', 'UNL', 'UNK', 'UPL', 'DN', 'N'].
-
- Returns:
- bool: if ligand considered as dummy and treated as artifact
- """
- # check for dummy list including composites, too!
- return len(set(ligand_code.split("-")).intersection(dummy_lig_list)) > 0
-
-
-def get_ccd_smiles_dict(ciffile: Path) -> dict[str, str]:
- df = pd.read_parquet(ciffile.parent / "components.parquet")
- return dict(zip(df["binder_id"], df["canonical_smiles"]))
-
-
-def sort_ccd_codes(code_list: list[str]) -> list[str]:
- """Pick long first, then alphabetical letters followed by numbers
- Args:
- code_list (Set[str]): set of CCD strings
-
- Returns:
- List[str]: list of sorted CCD string set
- """
- code_list = sorted(sorted(code_list), key=len, reverse=True)
- final_list = [code for code in code_list if not re.findall("([0-9])", code[0])] + [
- code for code in code_list if re.findall("([0-9])", code[0])
- ]
- return final_list
-
-
-@cache
-def get_ccd_synonyms(data_dir: Path) -> tuple[list[set[str]], dict[str, str]]:
- """Get Synonym dictonary for CCD SMILES
- CCD smiles dict from download_components_cif
- and get_ccd_smiles_dict
-
- Returns:
- Dict[str, str]: dictonary mapping synonymous CCD code to preferred one
- """
- from plinder.data.pipeline.io import download_components_cif
-
- ccd_lib_cifpath = download_components_cif(data_dir=data_dir)
- smidict = get_ccd_smiles_dict(ccd_lib_cifpath)
- ccd_df = pd.DataFrame.from_dict(smidict, orient="index").reset_index()
- # note: SMILES assumed to be CANONICALIZED by OE read by get_ccd_smiles_dict()
- ccd_df.columns = ["ccd_code", "SMILES"]
- # remove dummies
- ccd_df = ccd_df[~ccd_df["ccd_code"].apply(lig_has_dummies)]
- ccd_sets = ccd_df.groupby("SMILES").aggregate(list).reset_index()
- # ccd_sets
- ccd_sets["ccd_synonym_count"] = ccd_sets["ccd_code"].apply(lambda x: len(x))
- ccd_dups = ccd_sets[ccd_sets.ccd_synonym_count > 1].copy()
- list_of_synonym_sets = [set(x) for x in ccd_dups["ccd_code"].to_list()]
- # keep unique_ccd as sorted first entry
- ccd_dups["unique_ccd"] = ccd_dups["ccd_code"].apply(lambda x: sort_ccd_codes(x)[0])
- ccd_dups_exp = ccd_dups.explode("ccd_code")
- ccd_dups_exp.index = ccd_dups_exp["ccd_code"]
- ccd_synonym_dict = ccd_dups_exp["unique_ccd"].to_dict()
- return (list_of_synonym_sets, ccd_synonym_dict)
-
-
-# lazy evaluate data fetches referenced as module globals
-# TODO : clean this up and deduplicate extras with pipeline.io
-COFACTORS = None
-LIST_OF_CCD_SYNONYMS = None
-CCD_SYNONYMS_DICT = None
-# instantiate artifact list once and reuse variable
-ARTIFACTS = None
-KINASE_INHIBITORS = None
-BINDING_AFFINITY = None
-
-
-def add_missed_synonyms(current_set: set[str]) -> set[str]:
- assert LIST_OF_CCD_SYNONYMS is not None
- missed_synonyms = [
- x.difference(current_set)
- for x in LIST_OF_CCD_SYNONYMS
- if len(x.intersection(current_set)) > 0
- ]
- return set(itertools.chain(*missed_synonyms)).union(current_set)
-
-
-def get_unique_ccd_longname(longname: str) -> str:
- assert CCD_SYNONYMS_DICT is not None
-
- if longname.startswith("PRD_"):
- return longname
- else:
- return "-".join([CCD_SYNONYMS_DICT.get(s, s) for s in longname.split("-")])
-
-
-def get_ligand_chainid_comp_id_map(data: DataContainer) -> dict[str, set[str]]:
- atom_sites = data.getObj("atom_site")
- atom_site_columns = ["group_PDB", "label_comp_id", "label_asym_id"]
- if atom_sites is None:
- return {}
-
- chain_comp_id_map = defaultdict(set)
- for atom in atom_sites.getCombinationCountsWithConditions(
- atom_site_columns, [("group_PDB", "eq", "HETATM")]
- ):
- chain_comp_id_map[atom[2]].add(atom[1])
- return chain_comp_id_map
-
-
-def get_bond_info(
- data: DataContainer, comp_ids: set[str]
-) -> dict[str, list[tuple[str, str, str]]]:
- comp_bond_info = data.getObj("chem_comp_bond")
- if comp_bond_info is None:
- return {}
- comp_bond_cols = ["comp_id", "atom_id_1", "atom_id_2", "value_order"]
- bonds_dict = defaultdict(list)
- for bond in comp_bond_info.getCombinationCountsWithConditions(
- comp_bond_cols, [("comp_id", "in", comp_ids)]
- ):
- if bond[0] == "HOH":
- continue
- bonds_dict[bond[0]].append((bond[1], bond[2], bond[3]))
- return bonds_dict
-
-
-def get_all_indices(lst: list[str], item: ty.Any) -> list[int]:
- """
- Get all indices of an item in a list
-
- Parameters
- ----------
- lst : lst
- The first parameter.
-
- Returns
- -------
- list
- list of indices of the item in the list
- """
- my_list = np.array(lst)
- return [int(i) for i in np.where(my_list == item)[0]]
-
-
-def bond_pdb_order(value_order: str) -> Chem.rdchem.BondType:
- """
- Get rdkit bond type from pdb order
-
- Parameters
- ----------
- value_order : str
-
- Returns
- -------
- Chem.rdchem.BondType
- """
- if value_order.casefold() == "sing":
- return Chem.rdchem.BondType(1)
- if value_order.casefold() == "doub":
- return Chem.rdchem.BondType(2)
- if value_order.casefold() == "trip":
- return Chem.rdchem.BondType(3)
- return None
-
-
-def get_rdkit_mol_from_pdb_block(
- pdb_block: str, bonds_dict: dict[str, list[tuple[str, str, str]]]
-) -> str:
- mol = AllChem.MolFromPDBBlock(pdb_block)
- atoms_ids = [
- f"{atm.GetPDBResidueInfo().GetResidueName().strip()}"
- + f":{atm.GetPDBResidueInfo().GetName().strip()}"
- for atm in mol.GetAtoms()
- ]
-
- rw_mol = RWMol(mol)
- for comp_id, bonds in bonds_dict.items():
- for row in bonds:
- atom_1 = row[0]
- atom_2 = row[1]
-
- if (f"{comp_id}:{atom_1}" not in atoms_ids) | (
- f"{comp_id}:{atom_2}" not in atoms_ids
- ):
- # extra atom
- pass
-
- if atom_1.startswith("H") | atom_2.startswith("H"):
- # skip hydrogens
- pass
- else:
- try:
- atom_1_ids = get_all_indices(atoms_ids, f"{comp_id}:{atom_1}")
- atom_2_ids = get_all_indices(atoms_ids, f"{comp_id}:{atom_2}")
- for atom_1_id, atom_2_id, order in zip(
- atom_1_ids, atom_2_ids, np.repeat(row[2], len(atom_1_ids))
- ):
- bond_order = bond_pdb_order(order)
- rw_mol.RemoveBond(int(atom_1_id), int(atom_2_id))
- rw_mol.AddBond(int(atom_1_id), int(atom_2_id), bond_order)
- except ValueError:
- print(
- f"Error perceiving {atom_1} - {atom_2} bond in _chem_comp_bond"
- )
- except RuntimeError:
- print(f"Duplicit bond {atom_1} - {atom_2}")
-
- bonded_mol = rw_mol.GetMol()
- return str(Chem.MolToSmiles(bonded_mol))
-
-
-def get_smiles_from_cif(
- data: DataContainer, ent: io.EntityHandle, polymer_cutoff: int = 20
-) -> dict[str, str]:
- rdk_mols = {}
- chain_id_comp_id_map = get_ligand_chainid_comp_id_map(data)
- for chain_id, list_of_comp_ids in chain_id_comp_id_map.items():
- bonds_dict = get_bond_info(data, list_of_comp_ids)
- mol_ent = mol.CreateEntityFromView(
- ent.Select(f"chain='{chain_id}'"),
- True,
- )
- # If number of residue is withing cutoff range
- if len(mol_ent.residues) < polymer_cutoff:
- pdb_block = io.EntityToPDBStr(pdbize(ent, mol_ent)[0])
- rdk_mols[chain_id] = get_rdkit_mol_from_pdb_block(pdb_block, bonds_dict)
- # Skip water
- elif sum([res.name == "HOH" for res in mol_ent.residues]) > 0:
- continue
- return rdk_mols
-
-
-def get_rdkit_mol_with_bond_order_from_cif(
- rdk_smiles_dict: dict[str, str], chain_id: str
-) -> str:
- return rdk_smiles_dict.get(chain_id, "")
-
-
-def get_chain_type(chain_type: str) -> str:
- """
- Get chain type
-
- Parameter
- ---------
- chain_type : str,
- ost chain type
-
- Return
- ------
- str
- ligand type
- """
- if chain_type == mol.CHAINTYPE_NON_POLY:
- return "SMALLMOLECULE"
- if chain_type in PEPTIDE_TYPES:
- return "PEPTIDE"
- elif chain_type in DNA_TYPES:
- return "DNA"
- elif chain_type in RNA_TYPES:
- return "RNA"
- elif chain_type in MIXED_NUCLEIC_ACID_TYPES:
- return "MIXED"
- elif chain_type in OLIGOSACCHARIDE_TYPES:
- return "SACCHARIDE"
- elif chain_type in MACROCYCLE_TYPES:
- return "MACROCYCLES"
- else:
- return "UNKNOWN"
-
-
-@cache
-def parse_cofactors(data_dir: Path) -> set[str]:
- """Download and parse cofactors.
-
- Returns
- -------
- Set[str]
- Set of cofactors
-
- """
- from plinder.data.pipeline.io import download_cofactors
-
- cofactors_json = download_cofactors(data_dir=data_dir)
- extra = {
- "Ascorbic acid": ["UU3"],
- "Coenzyme F420": ["6J4", "F42"],
- "Factor F430": ["F43", "M43"],
- "Pantetheine": ["PNY"],
- "Pantothenic acids": ["66S", "8Q1", "PAU"],
- "Nicotinamide": ["NCA"],
- "Adenosine nucleotides": [
- "A",
- "AMP",
- "ATP",
- "ADP",
- ], # + ["ANP"], # ANP is a mimic-inhibitor
- "Guanosine nucleotides": [
- "G",
- "GTP",
- "GDP",
- "GMP",
- "CPG",
- "G25",
- "5GP",
- ], # + ["GNP", "GTN"], # GNP/GTN is inhibitor
- "Cytidine nucleotides": ["C", "C5P", "C25", "CDP", "CTP"],
- "Thymidine nucleotides": ["T", "TMP", "DT", "TTP", "THM", "TYD"],
- "Uridine nucleotides": ["U", "DU", "U5P", "U25", "UMP", "UDP", "UTP"],
- "MIO": ["CRW"],
- "NAD": ["NAH"],
- "Glutathione": ["CYP"],
- "Biopterin": ["HBL", "BH4", "THB"],
- "Tetrahydrofolic acid": ["MEF"],
- "Lumazine": ["DLZ"],
- "Menaquinone": ["MQ8", "MQ9", "MQE", "7MQ"],
- "Heme": ["1CP", "CP3", "MMP", "UP2", "UP3"],
- "Methanopterin": ["H4M", "H4Z"],
- "Lipoamide": ["LPM"],
- "Ubiquinone": ["DCQ", "HQE", "PLQ"],
- "Pyridoxal": ["PXL", "UEG"],
- "Siderophores": ["488", "EB4", "SE8"],
- "Methanofuran": ["MFN"],
- "Vitamin A": ["BCR", "ECH", "EQ3", "RAW"],
- "Vitamin K1": ["PQN"],
- "CHLOROPHYLL and similar": [
- "CLA",
- "CHL",
- "CL0",
- "CL1",
- "CL2",
- "CL7",
- "BCB",
- "BCL",
- "07D",
- "G9R",
- "PEB",
- "PUB",
- "CYC",
- "BPH",
- ],
- # "Lipids": ["SPH"], # TODO: ?
- # "Sugars": ["NAG", "BCG", "GLC"], # TODO: more?
- #
- }
- cofactors = set()
- for c in cofactors_json:
- for c_list in cofactors_json[c]:
- cofactors |= set(c_list.get("cofactors", []))
- for c in extra:
- cofactors |= set(extra[c])
-
- # add missed synonyms
- cofactors = add_missed_synonyms(cofactors)
-
- return cofactors
-
-
-@cache
-def parse_artifacts() -> set[str]:
- """Get and parse artifacts
- Returns:
- set[str]: set[str]
- """
- artifact_log = BASE_DIR / "utils/annotations/static_files/artifacts_badlist.csv"
- with open(artifact_log, "r") as f:
- lines = f.readlines()
- artifacts = {l.strip() for l in lines if not l.startswith("#")}
- # add missed synonyms
- artifacts = add_missed_synonyms(artifacts)
- return artifacts
-
-
-@cache
-def parse_kinase_inhibitors(data_dir: Path) -> set[str]:
- from plinder.data.pipeline.io import download_kinase_data
-
- kinase_ligand_path = download_kinase_data(data_dir=data_dir)
- kinase_ligand_path = kinase_ligand_path.with_name("kinase_ligand_ccd_codes.parquet")
- kinase_ligand_df = pd.read_parquet(kinase_ligand_path)
- return set(kinase_ligand_df["PDB-code"])
-
-
-@cache
-def get_binding_affinity(data_dir: Path) -> ty.Any:
- from plinder.data.pipeline.io import download_affinity_data
-
- return download_affinity_data(data_dir=data_dir)
-
-
-def get_num_resolved_heavy_atoms(resolved_smiles: str) -> int:
- obmol = pybel.readstring("smi", resolved_smiles)
- obmol.removeh()
- return len(obmol.atoms)
-
-
-# TODO: replace above with below
-# def get_num_resolved_heavy_atoms(matched_smiles: str) -> int:
-# matched_mol = Chem.MolFromSmiles(matched_smiles, sanitize=False)
-# return rdMolDescriptors.CalcNumHeavyAtoms(matched_mol)
-
-
-def get_len_of_longest_linear_hydrocarbon_linker(
- mol: Mol,
- max_count: int = 50,
- link_unit_smarts: str = "[#6D2R0]",
-) -> int:
- """Estimate maximum linker length defined by link_unit_smarts, eg.
- unbranched hydrocarbons (default)
-
- Args:
- mol (Mol): RDKit molecule
- max_count (int, optional):
- Max count for linker. Defaults to 50.
- link_unit_smarts (str, optional):
- Linker unit defined by SMARTS. Defaults to "[#6D2R0]".
-
- Returns:
- int: maximum linker length defined by link_unit_smarts (default: unbranched hydrocarbon)
- """
- try:
- # needs ring info!
- Chem.SanitizeMol(
- mol, sanitizeOps=Chem.rdmolops.SanitizeFlags.SANITIZE_SYMMRINGS
- )
- # length of longest hydrocarbon chain (excludes the ends and rings)
- for i in range(max_count):
- # chain_smarts = "[#6D2R0,#6D1R0]" * (i+1) # includes the ends
- chain_smarts = "~".join([link_unit_smarts] * (i + 1))
- if len(mol.GetSubstructMatches(Chem.MolFromSmarts(chain_smarts))) == 0:
- return i
- # TODO: what to do if fails or not found? now returns -1
- return -1
- except:
- return -1
-
-
-def is_excluded_mol(
- smiles: str,
- min_C_threshold: int = 2,
- min_HA_threshold: int = 5,
- max_charge: int = 2,
- max_linear_hydrocarbon_linker: int = 12,
-) -> bool:
- """Exclude some molecules by default as useless for druglikeness
- Uses OR logic for violating rules:
- - less than 2 carbon atoms
- - less than 5 non-hydrogen atoms
- - charge larger than +/- 2
- - unbranched hydrocarbon linker no longer than 12
-
- Args:
- smiles (str): molecule SMILES
- min_C_threshold (int, optional):
- Minimum carbon atom count. Defaults to 2.
- min_HA_threshold (int, optional):
- Minimum non-hydrogen atom count. Defaults to 5.
- max_charge (int, optional):
- Maximum allowed absolute charge. Defaults to 2.
- max_linear_hydrocarbon_linker (int, optional):
- Maximum allowed unbranched hydrocarbon linker. Defaults to 12.
-
- Returns:
- bool: should molecule be considered as artifact
- """
- mol = Chem.MolFromSmiles(smiles, sanitize=False)
-
- # get heavy atom and carbon counts
- carbon = Chem.MolFromSmarts("[#6]")
- numC = len(mol.GetSubstructMatches(carbon))
- numHA = mol.GetNumHeavyAtoms()
-
- if numHA < min_HA_threshold or numC < min_C_threshold:
- return True
-
- # get formal charge
- charge = Chem.rdmolops.GetFormalCharge(mol)
- if abs(charge) > max_charge:
- return True
- elif (
- get_len_of_longest_linear_hydrocarbon_linker(mol)
- > max_linear_hydrocarbon_linker
- ):
- return True
- else:
- return False
-
-
-def is_single_atom_or_ion(mol: Mol) -> bool:
- numHA = mol.GetNumHeavyAtoms()
- skip_single_elems = Chem.MolFromSmarts("[#6,#1,#0,#7,#8,#15,#16,#34,#52]")
- numCHNOPSetc = len(mol.GetSubstructMatches(skip_single_elems))
- return numHA == 1 and numCHNOPSetc == 0
-
-
-def annotate_interface_gaps_per_chain(
- interface_proximal_gaps: dict[str, dict[tuple[str, str], dict[str, int]]],
- asym_id: str,
-) -> tuple[int | None, ...]:
- try:
- ppi_atoms_within_4A_of_gap = sum(
- [
- v["interface_atom_gaps_4A"]
- for k, v in interface_proximal_gaps[
- "ppi_interface_gap_annotation"
- ].items()
- if asym_id in k
- ]
- )
- except TypeError:
- ppi_atoms_within_4A_of_gap = None
-
- try:
- ppi_atoms_within_8A_of_gap = sum(
- [
- v["interface_atom_gaps_8A"]
- for k, v in interface_proximal_gaps[
- "ppi_interface_gap_annotation"
- ].items()
- if asym_id in k
- ]
- )
- except TypeError:
- ppi_atoms_within_8A_of_gap = None
- try:
- num_missing_ppi_interface_residues = sum(
- [
- v["missing_interface_residues_4A"]
- for k, v in interface_proximal_gaps[
- "ppi_interface_gap_annotation"
- ].items()
- if asym_id in k
- ]
- )
- except TypeError:
- num_missing_ppi_interface_residues = None
- try:
- pli_atoms_within_4A_of_gap = sum(
- [
- v["interface_atom_gaps_4A"]
- for k, v in interface_proximal_gaps[
- "ligand_interface_gap_annotation"
- ].items()
- if asym_id in k
- ]
- )
- except TypeError:
- pli_atoms_within_4A_of_gap = None
-
- try:
- pli_atoms_within_8A_of_gap = sum(
- [
- v["interface_atom_gaps_8A"]
- for k, v in interface_proximal_gaps[
- "ligand_interface_gap_annotation"
- ].items()
- if asym_id in k
- ]
- )
- except TypeError:
- pli_atoms_within_8A_of_gap = None
- try:
- num_missing_pli_interface_residues = sum(
- [
- v["missing_interface_residues_4A"]
- for k, v in interface_proximal_gaps[
- "ligand_interface_gap_annotation"
- ].items()
- if asym_id in k
- ]
- )
- except TypeError:
- num_missing_pli_interface_residues = None
-
- return (
- ppi_atoms_within_4A_of_gap,
- ppi_atoms_within_8A_of_gap,
- num_missing_ppi_interface_residues,
- pli_atoms_within_4A_of_gap,
- pli_atoms_within_8A_of_gap,
- num_missing_pli_interface_residues,
- )
-
-
-def validate_chain_residue(obj: dict[str, ty.Any]) -> dict[str, ty.Any]:
- clean = {}
- for k, v in obj.items():
- key = tuple(k.split(",")) if isinstance(k, str) else k
- if isinstance(v, dict):
- clean[key] = validate_chain_residue(v)
- else:
- clean[key] = v
- return clean # type: ignore
-
-
-CrystalContacts = ty.Annotated[
- dict[tuple[str, int], set[int]],
- BeforeValidator(validate_chain_residue),
- Field(default_factory=dict),
-]
-
-
-class Ligand(DocBaseModel):
- pdb_id: str = Field(
- default_factory=str,
- description="__RCSB PDB ID, see https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entry.id.html",
- )
- biounit_id: str = Field(default_factory=str, description="__Biounit id")
- asym_id: str = Field(default_factory=str, description="Ligand chain asymmetric id")
- instance: int = Field(default_factory=int, description="Biounit instance ID")
- ccd_code: str = Field(
- default_factory=str,
- description="Ligand Chemical Component Dictionary (CCD) code",
- )
- plip_type: str = Field(default_factory=str, description="PLIP ligand type")
- bird_id: str = Field(default_factory=str, description="Ligand BIRD id")
- centroid: list[float] = Field(
- default_factory=list, description="Ligand center of geometry"
- )
- smiles: str = Field(
- default_factory=str,
- description="Ligand SMILES based on OpenStructure dictionary lookup, or resolved SMILES if not in dictionary",
- )
- resolved_smiles: str = Field(
- default_factory=str, description="SMILES of only resolved ligand atoms"
- )
- residue_numbers: list[int] = Field(
- default_factory=list, description="__Ligand residue numbers"
- )
- rdkit_canonical_smiles: str | None = Field(
- default=None, description="RDKit canonical SMILES (Recommended)"
- )
- molecular_weight: float | None = Field(default=None, description="Molecular weight")
- crippen_clogp: float | None = Field(
- default=None,
- description="Ligand Crippen MlogP, see https://www.rdkit.org/docs/source/rdkit.Chem.Crippen.html",
- )
- num_rot_bonds: int | None = Field(
- default=None, description="Number of rotatable bonds"
- )
- num_hbd: int | None = Field(
- default=None, description="Number of hydrogen bond donors"
- )
- num_hba: int | None = Field(
- default=None, description="Number of hydrogen bond acceptors"
- )
- num_rings: int | None = Field(default=None, description="Number of rings")
- num_heavy_atoms: int | None = Field(
- default=None, description="Number of heavy atoms"
- )
- is_covalent: bool = Field(
- default=False, description="Indicator of whether a ligand is a covalent ligand"
- )
- covalent_linkages: set[str] = Field(
- default_factory=set[str],
- description="Ligand covalent linkages as described in https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Categories/struct_conn.html "
- + "with _struct_conn.conn_type_id == 'covale', reported in format "
- + "{auth_resid}:{resname}{assym_id}{seq_resid}{atom_name}__{auth_resid}:{resname}{assym_id}{seq_resid}{atom_name}",
- )
- neighboring_residues: dict[str, list[int]] = Field(
- default_factory=dict,
- description="Dictionary of neighboring residues, with {instance}.{chain} key and residue number value",
- )
- neighboring_ligands: list[str] = Field(
- default_factory=list,
- description="__List of neighboring ligands {instance}.{chain}",
- )
- interacting_residues: dict[str, list[int]] = Field(
- default_factory=dict,
- description="Dictionary of interacting residues, with {instance}.{chain} key and residue number value",
- )
- interacting_ligands: list[str] = Field(
- default_factory=list,
- description="__List of interacting ligands {instance}.{chain}",
- )
- interactions: dict[str, dict[int, list[str]]] = Field(
- default_factory=dict,
- description="__Dictionary of {instance}.{chain} to residue number to list of PLIP hashes",
- )
- neighboring_residue_threshold: float = Field(
- default=6.0,
- description="__Maximum distance to consider protein residues neighboring",
- )
- neighboring_ligand_threshold: float = Field(
- default=4.0, description="__Maximum distance to consider ligands neighboring"
- )
- num_neighboring_ppi_atoms_within_4A_of_gap: int | None = Field(
- default=None,
- description="Number of missing neighboring protein-protein interface atoms within 4 ร of ligand of interest",
- )
- num_neighboring_ppi_atoms_within_8A_of_gap: int | None = Field(
- default=None,
- description="Number of missing neighboring protein-protein interface atoms within 8 ร of ligand of interest",
- )
- num_missing_ppi_interface_residues: int | None = Field(
- default=None,
- description="Number of missing neighboring protein-protein interface residues within 4 ร of ligand of interest",
- )
- num_pli_atoms_within_4A_of_gap: int | None = Field(
- default=None,
- description="Number of missing neighboring protein-ligand interface atoms within 4 ร of ligand of interest",
- )
- num_pli_atoms_within_8A_of_gap: int | None = Field(
- default=None,
- description="Number of missing neighboring protein-ligand interface atoms within 8 ร of ligand of interest",
- )
- num_missing_pli_interface_residues: int | None = Field(
- default=None,
- description="Number of missing neighboring protein-ligand interface residues within 4 ร of ligand of interest",
- )
- num_resolved_heavy_atoms: int | None = Field(
- default=None, description="Number of resolved heavy atoms in a ligand"
- )
- num_unresolved_heavy_atoms: int | None = Field(
- default=None, description="Number of unresolved heavy atoms in a ligand"
- )
- tpsa: float | None = Field(
- default=None, description="Topological polar surface area"
- )
- qed: float | None = Field(
- default=None,
- description="Ligand QED score, a measure of drug-likeness, see https://www.rdkit.org/new_docs/source/rdkit.Chem.QED.html",
- )
- is_ion: bool = Field(
- default=False, description="Indicator of whether a ligand is an ion"
- )
- is_lipinski: bool = Field(
- default=False,
- description="Indicator of whether a ligand satisfies Lipinski Ro5",
- )
- is_fragment: bool = Field(
- default=False,
- description="Indicator of whether a ligand satisfies fragment Ro3",
- )
- is_oligo: bool = Field(
- default=False,
- description="Indicator of whether a ligand is an oligopeptide, oligosaccharide or oligopeptide",
- )
- is_cofactor: bool = Field(
- default=False, description="Indicator of whether a ligand is a cofactor"
- )
- in_artifact_list: bool = Field(
- default=False,
- description="Indicator of whether a ligand is in the artifact list",
- )
- is_artifact: bool = Field(
- default=False, description="Indicator of whether a ligand is an artifact"
- )
- is_other: bool = Field(
- default=False,
- description="Indicator of whether a ligand type is not classified as any types of small molecule "
- + "(Lipinski, Fragment or covalent), ion, cofactor, oligo (peptide, saccharide or nucleotide) or artifact",
- )
- is_invalid: bool = Field(
- default=False, description="Indicator of whether a ligand is invalid"
- )
- unique_ccd_code: str | None = Field(
- default=None, description="Ligand representative CCD code after de-duplicating"
- )
- crystal_contacts: CrystalContacts = Field(
- default_factory=dict,
- description="__Dictionary of {instance}.{chain} to residue number to set of interacting crystal contacts",
- )
- waters: dict[str, list[int]] = Field(
- default_factory=dict,
- description="__Dictionary of {instance}.{chain} to list of interacting water residue numbers",
- )
- posebusters_result: dict[str, ty.Any] = Field(
- default_factory=dict,
- description="__Results from running posebusters with 're-dock'",
- )
- """
- This dataclass defines as system which included a protein-ligand complex
- and it's neighboring ligands and protein residues
-
- """
-
- def set_rdkit(self) -> None:
- try:
- rdkit_compatible_mol = Chem.MolFromSmiles(self.smiles)
- # TODO: Watch out for round trip issues reported in
- # https://github.com/rdkit/rdkit/issues/1740
- self.rdkit_canonical_smiles = Chem.CanonSmiles(self.smiles)
- self.molecular_weight = rdMolDescriptors.CalcExactMolWt(
- rdkit_compatible_mol
- )
- self.num_rot_bonds = rdMolDescriptors.CalcNumRotatableBonds(
- rdkit_compatible_mol
- )
- self.num_hba = rdMolDescriptors.CalcNumHBA(rdkit_compatible_mol)
- self.num_hbd = rdMolDescriptors.CalcNumHBD(rdkit_compatible_mol)
- self.crippen_clogp = Crippen.MolLogP(rdkit_compatible_mol)
- self.num_rings = rdMolDescriptors.CalcNumRings(rdkit_compatible_mol)
- self.num_heavy_atoms = rdMolDescriptors.CalcNumHeavyAtoms(
- rdkit_compatible_mol
- )
- self.tpsa = rdMolDescriptors.CalcTPSA(rdkit_compatible_mol)
- self.qed = QED.qed(rdkit_compatible_mol)
- self.num_resolved_heavy_atoms = get_num_resolved_heavy_atoms(
- self.resolved_smiles
- )
-
- if self.num_heavy_atoms and self.num_resolved_heavy_atoms:
- self.num_unresolved_heavy_atoms = (
- self.num_heavy_atoms - self.num_resolved_heavy_atoms
- )
- # classify ligand based on above molecule
- self.classify_ligand_type(rdkit_compatible_mol)
-
- except:
- logging.warning(f"Error in setting rdkit for {self.id}")
- self.is_invalid = True
- pass
-
- def classify_ligand_type(self, mol: Mol) -> None:
- """Get more granular classification of ligand.
- Use oligo smarts and lipinski rules to assign ligand classifications in
- addition to ligand classification obtained from PLIP
-
- Note
- ----
- Oligo smarts obtained from https://doi.org/10.1021/acs.jcim.3c01573
-
- Args:
- mol (Mol): RDKit compatible molecule
- """
- RDLogger.DisableLog("rdApp.*")
- oligo_smarts = {
- "oligopeptide": Chem.MolFromSmarts("C(=O)C[N;D2,D3]C(=[O;D1])CN"),
- "oligosaccharide": Chem.MolFromSmarts(
- "O-[C;R0,R1]-[C;R0,R1]-[O,S;R0;D2]-[C;R1]-[O;R1]"
- ),
- "oligonucleotide": Chem.MolFromSmarts("P(=O)([O-,OH])(OC[C;r5])O[C;r5]"),
- }
-
- if mol is not None:
- if is_single_atom_or_ion(mol):
- self.is_ion = True
- else:
- for sm in oligo_smarts:
- try:
- if mol.HasSubstructMatch(oligo_smarts[sm]):
- # TODO: review - reduced to one class
- self.is_oligo = True
- except RuntimeError:
- self.is_invalid = True
- else:
- self.is_invalid = True
-
- # Lipinski like Ro3 and Ro5 - for non ions only
- if (
- self.is_ion == False
- and self.is_invalid == False
- and self.molecular_weight is not None
- and self.crippen_clogp is not None
- and self.num_hbd is not None
- and self.num_hba is not None
- ):
- if (
- self.molecular_weight < 300
- and self.crippen_clogp < 3
- and self.num_hbd <= 3
- and self.num_hba <= 3
- ):
- self.is_fragment = True
- self.is_lipinski = True
- elif (
- self.molecular_weight < 500
- and self.crippen_clogp < 5
- and self.num_hbd <= 5
- and self.num_hba <= 10
- ):
- self.is_lipinski = True
-
- @classmethod
- def from_pli(
- cls,
- pdb_id: str,
- biounit_id: str,
- biounit: mol.EntityHandle,
- ligand_instance: int,
- ligand_chain: Chain,
- residue_numbers: list[int],
- ligand_like_chains: dict[str, str],
- interface_proximal_gaps: dict[str, dict[tuple[str, str], dict[str, int]]],
- all_covalent_dict: dict[str, list[tuple[str, str]]],
- plip_complex_threshold: float = 10.0,
- neighboring_residue_threshold: float = 6.0,
- neighboring_ligand_threshold: float = 4.0,
- data_dir: ty.Optional[Path] = None,
- ) -> Ligand | None:
- """
- Load ligand object from protein-ligand interaction complex
- along with other information binding site information
- Parameters
- ----------
- cls : Ligand
- pdb_id : str
- biounit_id : str
- biounit : mol.EntityHandle
- Biounit openstructure mol.EntityHandle
- ligand_instance : int
- Ligand biounit instance
- ligand_chain : Chain
- Ligand chain object
- ligand_like_chains: dict[str, str]
- Chain: chain type for other ligand-like chains in the entry
- interface_proximal_gaps: dict[str, dict[tuple[str, str], dict[str, int]]]
- TODO: document
- all_covalent_dict : dict[str, list[tuple[str, str]]]
- All "covalent" residue in entry as defined by mmcif annotations.
- They types are separated by dictionary key and they include:
- "covale": actual covalent linkage
- "metalc": other dative bond interactions\
- like metal-ligand dative bond
- "hydrogc": strong hydorogen bonding of nucleic acid
- For the purpose of covalent annotations, we selected "covale" for
- downstream processing.
- plip_complex_threshold: float = 10.0
- Maximum distance from ligand to residues to be
- included for pli calculations.
- data_dir : Path, optional
- location of plinder root
- """
- global \
- COFACTORS, \
- ARTIFACTS, \
- LIST_OF_CCD_SYNONYMS, \
- CCD_SYNONYMS_DICT, \
- KINASE_INHIBITORS, \
- BINDING_AFFINITY
- if LIST_OF_CCD_SYNONYMS is None or CCD_SYNONYMS_DICT is None:
- if data_dir is None:
- raise ValueError(
- "data_dir must be provided if CCD_SYNONYMS_DICT or LIST_OF_CCD_SYNONYMS is None"
- )
- LIST_OF_CCD_SYNONYMS, CCD_SYNONYMS_DICT = get_ccd_synonyms(data_dir)
- if COFACTORS is None:
- COFACTORS = parse_cofactors(data_dir)
- if ARTIFACTS is None:
- ARTIFACTS = parse_artifacts()
- if KINASE_INHIBITORS is None:
- KINASE_INHIBITORS = parse_kinase_inhibitors(data_dir)
- if BINDING_AFFINITY is None:
- BINDING_AFFINITY = get_binding_affinity(data_dir)
- ligand_instance_chain = f"{ligand_instance}.{ligand_chain.asym_id}"
- residue_selection = " or ".join(f"rnum={rnum}" for rnum in residue_numbers)
- ligand_selection = f"cname={mol.QueryQuoteName(ligand_instance_chain)} and ({residue_selection})"
- biounit_selection = mol.CreateEntityFromView(
- biounit.Select(
- f"{plip_complex_threshold} <> [{ligand_selection}]",
- mol.QueryFlag.MATCH_RESIDUES,
- ),
- True,
- )
- plip_output = run_plip_on_split_structure(
- biounit,
- biounit_selection,
- ligand_instance_chain,
- )
- if plip_output is None:
- return None
- (interactions, plip_chain_mapping) = plip_output
- ccd_code = "-".join(
- biounit.FindResidue(ligand_instance_chain, residue_number).name
- for residue_number in residue_numbers
- )
- ligand_ost_ent = mol.CreateEntityFromView(
- biounit.Select(ligand_selection), True
- )
- smiles = set_smiles_from_ligand_ost(ligand_ost_ent)
- # TODO: replace above with below
- # smiles, matched_smiles = set_smiles_from_ligand_ost_v2(ligand_ost_ent)
- ligand = cls(
- pdb_id=pdb_id,
- biounit_id=biounit_id,
- asym_id=ligand_chain.asym_id,
- instance=ligand_instance,
- ccd_code=ccd_code,
- plip_type=get_chain_type(
- ligand_chain.chain_type
- ), # TODO: rename variable, no longer uses plip
- bird_id=list(ligand_chain.mappings.get("BIRD", {"": None}))[0], # type: ignore
- centroid=list(ligand_ost_ent.GetCenterOfMass()),
- smiles=smiles,
- neighboring_residue_threshold=neighboring_residue_threshold,
- neighboring_ligand_threshold=neighboring_ligand_threshold,
- resolved_smiles=interactions.ligand.smiles, # TODO: only thing left that depends on PLIP
- # TODO: replace above with below
- # resolved_smiles=matched_smiles,
- residue_numbers=residue_numbers,
- )
-
- neighboring_residue_selection = biounit.Select(
- f"{ligand.neighboring_residue_threshold} <> [{ligand_selection}]"
- + " and protein=True"
- )
-
- (
- ligand.num_neighboring_ppi_atoms_within_4A_of_gap,
- ligand.num_neighboring_ppi_atoms_within_8A_of_gap,
- ligand.num_missing_ppi_interface_residues,
- ligand.num_pli_atoms_within_4A_of_gap,
- ligand.num_pli_atoms_within_8A_of_gap,
- ligand.num_missing_pli_interface_residues,
- ) = annotate_interface_gaps_per_chain(
- interface_proximal_gaps, ligand_chain.asym_id
- )
-
- for residue in neighboring_residue_selection.residues:
- instance_chain = residue.chain.name
- if instance_chain == ligand.instance_chain:
- # this chain is considered a ligand, thus, skip!
- continue
- if instance_chain not in ligand.neighboring_residues:
- ligand.neighboring_residues[instance_chain] = []
- ligand.neighboring_residues[instance_chain].append(residue.number.num)
-
- neighboring_asym_ids = {
- ch.name.split(".")[-1]
- for ch in neighboring_residue_selection.chains
- if ch.name != ligand.instance_chain
- }
-
- # DONE: output should be sufficient for RFAA, eg. [(("A", "74", "ND2"), ("B", "1"), ("CW", "null"))]
- # see: https://github.com/baker-laboratory/RoseTTAFold-All-Atom?tab=readme-ov-file#predicting-covalently-modified-proteins
-
- ligand.covalent_linkages = extract_ligand_links_to_neighbouring_chains(
- all_covalent_dict, ligand.asym_id, neighboring_asym_ids, link_type="covale"
- )
-
- ligand.is_covalent = (
- len(ligand.covalent_linkages) > 0
- ) # TODO: Check to make sure we are catching all edge cases
-
- neighboring_ligand_selection = biounit.Select(
- f"{ligand.neighboring_ligand_threshold} <> [{ligand_selection}]"
- )
-
- ligand.neighboring_ligands = list(
- set(
- residue.chain.name
- for residue in neighboring_ligand_selection.residues
- if residue.chain.name != ligand.instance_chain
- and residue.chain.name.split(".")[1] in ligand_like_chains
- )
- )
- water_chains = set(
- c.name for c in biounit.chains if c.type == mol.CHAINTYPE_WATER
- )
- ligand.waters = defaultdict(list)
- for residue in interactions.interacting_res:
- residue_number, plip_chain = int(residue[:-1]), residue[-1]
- instance_chain = plip_chain_mapping[plip_chain]
- if instance_chain == ligand.instance_chain:
- continue
- if instance_chain in water_chains:
- ligand.waters[instance_chain].append(int(residue_number))
- continue
- if instance_chain.split(".")[1] in ligand_like_chains:
- ligand.interacting_ligands.append(instance_chain)
- else:
- if instance_chain not in ligand.interacting_residues:
- ligand.interacting_residues[instance_chain] = []
- ligand.interacting_residues[instance_chain].append(int(residue_number))
- ligand.interactions, waters = get_plip_hash(
- interactions, ligand.instance_chain, plip_chain_mapping
- )
- for plip_chain, resnum in waters:
- ligand.waters[plip_chain_mapping[plip_chain]].append(resnum)
- # add rdkit properties and type assignments
- ligand.set_rdkit()
- # set is_artifact and is_cofactor and is_other
- ligand.identify_artifacts_cofactors_and_other()
- # unique code parsing!
- ligand.unique_ccd_code = get_unique_ccd_longname(ligand.ccd_code)
-
- return ligand
-
- @cached_property
- def selection(self) -> str:
- """
- __Selection string for ligand
- """
- residue_selection = " or ".join(f"rnum={rnum}" for rnum in self.residue_numbers)
- ligand_selection = f"cname={mol.QueryQuoteName(self.instance_chain)}"
- if len(self.residue_numbers):
- ligand_selection += f"and ({residue_selection})"
- return ligand_selection
-
- @cached_property
- def protein_chains_asym_id(self) -> list[str]:
- """
- List of RCSB asymmetric chain ids of protein residues within 6 ร of ligand of interest unless
- the ligand is an artifact, in which case we return an empty list.
- """
- if self.is_artifact:
- return []
- else:
- return list(sorted(self.neighboring_residues.keys()))
-
- @cached_property
- def num_interacting_residues(self) -> int:
- """
- Number of residues interacting with a given ligand.
- """
- return sum(
- len(self.interacting_residues[chain]) for chain in self.interacting_residues
- )
-
- @cached_property
- def num_neighboring_residues(self) -> int:
- """
- Residue count of each of the proteins within 6 ร of ligand of interest.
- """
- return sum(
- len(self.neighboring_residues[chain]) for chain in self.neighboring_residues
- )
-
- @cached_property
- def is_proper(self) -> bool:
- """
- Check if ligand is a proper ligand (not an ion or artifact)
- """
- return not self.is_ion and not self.is_artifact
-
- @cached_property
- def num_interactions(self) -> int:
- """
- Number of interactions for a given ligand.
- """
- return sum(
- sum(len(i) for i in self.interactions[chain].values())
- for chain in self.interactions
- )
-
- @cached_property
- def num_unique_interactions(self) -> int:
- """
- Number of unique interactions
- """
- return sum(
- sum(len(set(i)) for i in self.interactions[chain].values())
- for chain in self.interactions
- )
-
- @cached_property
- def pocket_residues(self) -> dict[str, dict[int, str]]:
- """
- __Residues in the ligand's binding pocket which includes neighboring and interacting residues.
- """
- residues: dict[str, dict[int, str]] = {}
- for chain in self.neighboring_residues:
- if chain not in residues:
- residues[chain] = {}
- for residue in self.neighboring_residues[chain]:
- residues[chain][residue] = "neighboring"
- for chain in self.interacting_residues:
- if chain not in residues:
- residues[chain] = {}
- for residue in self.interacting_residues[chain]:
- residues[chain][residue] = "interacting"
- return residues
-
- def get_pocket_residues_set(self) -> set[tuple[str, int]]:
- pocket_residues_set = set()
- for chain in self.pocket_residues:
- for residue_number in self.pocket_residues[chain]:
- pocket_residues_set.add((chain.split(".")[1], residue_number))
- return pocket_residues_set
-
- def set_crystal_contacts(
- self, crystal_contacts: dict[tuple[str, int], set[int]]
- ) -> None:
- # exclude contacts from neighboring residues in same biounit
- pocket_residues = self.get_pocket_residues_set()
- self.crystal_contacts = {
- x: y for x, y in crystal_contacts.items() if x not in pocket_residues
- }
-
- @cached_property
- def num_crystal_contacted_residues(self) -> int:
- """
- Number of residues from other symmetry mates which are in contact with this ligand.
- """
- return len(self.crystal_contacts)
-
- @cached_property
- def num_atoms_with_crystal_contacts(self) -> int:
- """
- Number of atoms in this ligand which are in contact with residues from other symmetry mates.
- """
- all_atoms = set()
- for x in self.crystal_contacts.values():
- all_atoms |= x
- return len(all_atoms)
-
- @cached_property
- def fraction_atoms_with_crystal_contacts(self) -> float | None:
- """
- Fraction of atoms in this ligand which are in contact with residues from other symmetry mates.
- """
- if self.num_heavy_atoms is None:
- return None
- return self.num_atoms_with_crystal_contacts / self.num_heavy_atoms
-
- @cached_property
- def num_pocket_residues(self) -> int:
- """
- Number of residues in the ligand's binding pocket.
- """
- return sum([len(self.pocket_residues[chain]) for chain in self.pocket_residues])
-
- @cached_property
- def id(self) -> str:
- """
- Unique identifier for a given ligand.
- """
- return "__".join([self.pdb_id, self.biounit_id, self.instance_chain])
-
- @cached_property
- def instance_chain(self) -> str:
- """
- Instance chain for a given ligand.
- """
- return f"{self.instance}.{self.asym_id}"
-
- @cached_property
- def interactions_counter(self) -> dict[str, dict[int, ty.Counter[str]]]:
- """
- __Counter of interactions for a given ligand.
- """
- interactions_counter: dict[str, dict[int, ty.Counter[str]]] = {}
- for chain in self.interactions:
- interactions_counter[chain] = {}
- for residue in self.interactions[chain]:
- interactions_counter[chain][residue] = Counter(
- self.interactions[chain][residue]
- )
- return interactions_counter
-
- @cached_property
- def is_kinase_inhibitor(self) -> bool:
- """
- Check if ligand is a kinase inhibitor.
- """
- global KINASE_INHIBITORS
- if KINASE_INHIBITORS is None:
- data_dir = Path(get_config().data.plinder_dir)
- KINASE_INHIBITORS = parse_kinase_inhibitors(data_dir)
- return any(c in KINASE_INHIBITORS for c in self.ccd_code.split("-"))
-
- @cached_property
- def binding_affinity(self) -> float | None:
- """
- Binding affinity (pKd or pKi) from BindingDB when available.
- """
- global BINDING_AFFINITY
- pdbid_ligid = f"{self.pdb_id}_{self.ccd_code}".upper()
- if BINDING_AFFINITY is None:
- data_dir = Path(get_config().data.plinder_dir)
- BINDING_AFFINITY = get_binding_affinity(data_dir)
- affinity = BINDING_AFFINITY.get(pdbid_ligid)
- if affinity is not None:
- return float(affinity)
- return None
-
- def identify_artifacts_cofactors_and_other(
- self,
- ) -> None:
- """
- Label artifacts, cofactors and other
-
- Parameters
- ----------
- self : Ligand
- Ligand object
- Returns
- -------
- dict[str, str]
- """
- assert COFACTORS is not None
- assert ARTIFACTS is not None
- if self.ccd_code in COFACTORS:
- self.is_cofactor = True
- if self.ccd_code in ARTIFACTS:
- self.in_artifact_list = True
-
- if self.is_ion:
- self.is_artifact = False
- elif self.in_artifact_list:
- self.is_artifact = True
- elif lig_has_dummies(self.ccd_code):
- # check for dummy list including composites, too!
- self.is_artifact = True
- elif is_excluded_mol(self.smiles):
- self.is_artifact = True
- else:
- self.is_artifact = False
-
- # reset: artifacts should not count to other ligand class definitions
- if self.is_artifact:
- self.is_ion = False
- self.is_oligo = False
- self.is_cofactor = False
- self.is_lipinski = False
- self.is_fragment = False
- self.is_covalent = False
-
- # Indicator of whether a ligand type is not any of small molecule (lipinski, frag, coval), ion, cofactor, oligopeptide, oligosaccharide or oligopeptide.
- if not any(
- [
- self.is_invalid,
- self.is_ion,
- self.is_oligo,
- self.is_artifact,
- self.is_cofactor,
- self.is_lipinski,
- self.is_fragment,
- self.is_covalent,
- ]
- ):
- self.is_other = True
-
- def format_chains(
- self,
- chain_type: str,
- chains: dict[str, Chain],
- ) -> dict[str, ty.Any]:
- """
- Format chains for pd.DataFrame
-
- Parameters
- ----------
- self : Ligand
- Ligand object
- chain_type: str
- Chain tyoe
- chains: dict[str, Chain]
- Chain id : chain mapping
- Returns
- -------
- dict[str, str]
- """
- if chain_type == "protein":
- sub_chains = self.protein_chains_asym_id
- elif chain_type == "interacting_ligand":
- sub_chains = self.interacting_ligands
- elif chain_type == "neighboring_ligand":
- sub_chains = self.neighboring_ligands
- else:
- raise ValueError(f"chain_type={chain_type} not understood")
- sub_chains_data = [
- chains[instance_chain.split(".")[-1]].format(
- int(instance_chain.split(".")[0])
- )
- for instance_chain in sub_chains
- ]
- data: dict[str, list[ty.Any]] = defaultdict(list)
- if len(sub_chains_data) == 0:
- return {}
- for sub_chain in sub_chains_data:
- for key in sub_chain:
- data[f"ligand_{chain_type}_chains_{key}"].append(sub_chain[key])
- return data
-
- def format_residues(
- self, residue_type: str, chains: dict[str, Chain]
- ) -> dict[str, list[str]]:
- """
- Format residues for pd.DataFrame
-
- Parameters
- ----------
- self : Ligand
- Ligand object
- residue_type : str
- Chain tyoe
- chains : dict[str, Chain]
- Chain id : chain mapping
-
- Returns
- -------
- List of residues in the format "__"
- dict[str, list[str]]
- """
- if residue_type == "interacting":
- residues = self.interacting_residues
- elif residue_type == "neighboring":
- residues = self.neighboring_residues
- res = []
- for instance_chain in residues:
- _, chain = instance_chain.split(".")
- for residue_number in residues[instance_chain]:
- res.append(
- f"{instance_chain}_{residue_number}_{chains[chain].residues[residue_number].index}"
- ) # TODO: move some of this logic to Residue
- return {f"ligand_{residue_type}_residues": res}
-
- def format_interactions(self) -> dict[str, list[str]]:
- """
- Format interactions for pd.DataFrame
-
- Parameters
- ----------
- self : Ligand
-
- Returns
- -------
- List of interactions in the format "__"
- dict[str, list[str]]
-
- """
- interactions: list[str] = []
- for chain in self.interactions:
- for residue in self.interactions[chain]:
- for interaction in self.interactions[chain][int(residue)]:
- interactions.append(f"{chain}_{residue}_{interaction}")
- return {"ligand_interactions": interactions}
-
- def format(self, chains: dict[str, Chain]) -> dict[str, ty.Any]:
- data: dict[str, ty.Any] = defaultdict(str)
- ignore_fields = set(
- [
- "posebusters_result",
- "interactions",
- "protein_chains",
- "interacting_ligands",
- "neighboring_ligands",
- "interacting_residues",
- "neighboring_residues",
- "pocket_residues",
- ]
- )
- for field, desc_type in self.get_descriptions_and_types().items():
- # blacklist fields that will be added with custom formatters below or that we don't want to add to the plindex
- descr = str(desc_type[0]).lstrip().replace("\n", " ")
- if descr.startswith("__") or field in ignore_fields:
- continue
- name = f"ligand_{field}"
- data[name] = getattr(self, field, None)
-
- # posebusters
- if self.posebusters_result is not None:
- for k in self.posebusters_result:
- data[f"ligand_posebusters_{k}"] = self.posebusters_result[k]
- # interactions
- data.update(self.format_interactions())
- # chains
- data.update(
- {"ligand_auth_id": chains[self.asym_id].auth_id}
- ) # not a cached_property b/c it needs chains!
- for chain_type in [
- "protein",
- "interacting_ligand",
- "neighboring_ligand",
- ]:
- data.update(self.format_chains(chain_type, chains))
- # residues
- for residue_type in ["interacting", "neighboring"]:
- data.update(self.format_residues(residue_type, chains))
-
- return data
diff --git a/src/plinder/data/utils/annotations/mmpdb_utils.py b/src/plinder/data/utils/annotations/mmpdb_utils.py
deleted file mode 100644
index 3c82ff741..000000000
--- a/src/plinder/data/utils/annotations/mmpdb_utils.py
+++ /dev/null
@@ -1,413 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-import logging
-import shutil
-import subprocess
-from itertools import zip_longest
-from pathlib import Path
-from typing import Any, Generator
-
-import pandas as pd
-from rdkit import Chem
-
-from plinder.core.utils.log import setup_logger
-
-LOG = setup_logger(__name__)
-
-
-def pad_integer_lig_ids_with_zeros(lig_id: str) -> str:
- """
- Fixes cases where integer ligand ids are striped\
- of their leading "0s". E.g 1 -> 001; 59 ->059
-
- Parameters
- ----------
- lig_id : str
- ligand ccd codes
- Returns
- -------
- str
- """
- try:
- lig_id = str(int(lig_id))
- return f"00{lig_id}"[-3:]
- except:
- return str(lig_id)
-
-
-def make_mmp_index_from_smiles_df(
- smiles_df: pd.DataFrame,
- output_path: Path,
- database_name: str,
- scratch_dir: Path,
- nthreads: int = 20,
-) -> Path:
- output_path.mkdir(parents=True, exist_ok=True)
- smiles_df = (
- smiles_df.groupby("ligand_ccd_code")
- .first()
- .reset_index()[["ligand_smiles", "ligand_ccd_code"]]
- )
- # remove rows with no smiles
- smiles_df = smiles_df[smiles_df.ligand_smiles.apply(lambda x: str(x) != "")]
- # Remove compounds containing metal-dative bond
- smiles_df = smiles_df[
- ~(
- smiles_df.ligand_smiles.str.contains(">")
- | smiles_df.ligand_smiles.str.contains("<")
- )
- ]
- smiles_df.dropna().to_csv(
- f"{output_path}/{database_name}_input.smi", sep=" ", index=False
- )
-
- # Split smiles file
- split_smile_cmd = (
- f"mmpdb smi_split {database_name}_input.smi --has-header -n {nthreads}"
- )
-
- try:
- subprocess.check_output(
- split_smile_cmd, shell=True, stderr=subprocess.STDOUT, cwd=output_path
- )
- except subprocess.CalledProcessError as e:
- logging.error(f"Smiles database split failed {e.output} ...")
- raise
-
- fragment_tasks = [
- f"mmpdb fragment -j 1 {smi.name}" for smi in output_path.glob("*.*.smi")
- ]
- with (scratch_dir / "fragment_tasks.txt").open("w") as f:
- f.write("\n".join(fragment_tasks))
-
- try:
- subprocess.check_output(
- [
- "python",
- "-m",
- "plinder.data.pipeline.mpqueue",
- f"{scratch_dir / 'fragment_tasks.txt'}",
- "--cwd",
- str(output_path),
- "--cores",
- str(nthreads),
- ],
- stderr=subprocess.STDOUT,
- )
- except subprocess.CalledProcessError as e:
- logging.error(f"Database fragmentation failed {e.output} ...")
- raise
- (scratch_dir / "fragment_tasks.txt").unlink()
-
- # Partition fragment database
- fragdbs = list(output_path.glob("*.*.fragdb"))
- partition_tasks = [
- f"mmpdb fragdb_partition *.*.fragdb --task-id {i + 1} --num-tasks {nthreads + 1}"
- for i in range(len(fragdbs))
- ]
- with (scratch_dir / "partition_tasks.txt").open("w") as f:
- f.write("\n".join(partition_tasks))
- try:
- subprocess.check_output(
- [
- "python",
- "-m",
- "plinder.data.pipeline.mpqueue",
- f"{scratch_dir / 'partition_tasks.txt'}",
- "--cwd",
- str(output_path),
- "--cores",
- str(nthreads),
- ],
- stderr=subprocess.STDOUT,
- cwd=output_path,
- )
- except subprocess.CalledProcessError as e:
- logging.error(f"Fragment database partitioning failed {e.output} ...")
- raise
- (scratch_dir / "partition_tasks.txt").unlink()
-
- index_tasks = [
- f"mmpdb index {partition.name} -o {partition.name}.csv.gz"
- for partition in output_path.glob("*partition.*.fragdb")
- ]
- with (scratch_dir / "index_tasks.txt").open("w") as f:
- f.write("\n".join(index_tasks))
-
- try:
- subprocess.check_output(
- [
- "python",
- "-m",
- "plinder.data.pipeline.mpqueue",
- f"{scratch_dir / 'index_tasks.txt'}",
- "--cwd",
- str(output_path),
- "--cores",
- str(nthreads),
- ],
- stderr=subprocess.STDOUT,
- )
- except subprocess.CalledProcessError as e:
- logging.error(f"Partition indexing failed {e.output} ...")
- raise
- (scratch_dir / "index_tasks.txt").unlink()
-
- # Merge
- with (output_path / f"{database_name}.csv.gz").open("wb") as db:
- for partition in output_path.glob("partition.*.csv.gz"):
- LOG.info(f"catting {partition} into {database_name}")
- with partition.open("rb") as piece:
- shutil.copyfileobj(piece, db)
-
- return output_path / f"{database_name}.csv.gz"
-
-
-def make_mmp_index_from_annotation_table(
- data_dir: Path,
- annotation_df: pd.DataFrame,
- database_name: str = "plinder_mms",
-) -> Path:
- output_path = data_dir / "mmp"
- scratch_dir = data_dir / "scratch" / "mmp"
- output_path.mkdir(exist_ok=True, parents=True)
- scratch_dir.mkdir(exist_ok=True, parents=True)
- rename = {}
- if "ligand_smiles" not in annotation_df.columns:
- rename["ligand_rdkit_canonical_smiles"] = "ligand_smiles"
- if "ligand_ccd_code" not in annotation_df.columns:
- rename["ligand_unique_ccd_code"] = "ligand_ccd_code"
- smiles_df = annotation_df.rename(columns=rename)
- smiles_df = smiles_df[~smiles_df.ligand_smiles.isna()]
- logging.info(f"smiles Dataframe output {smiles_df}")
- return make_mmp_index_from_smiles_df(
- smiles_df, output_path, database_name, scratch_dir
- )
-
-
-def add_mmp_clusters_to_data(
- load_mmp_df: pd.DataFrame,
- system_df: pd.DataFrame,
- cluster_folder: Path,
- protein_metric: str = "protein_fident_weighted_sum",
- protein_threshold: int = 95,
- protein_directed: bool = False,
- pocket_metric: str = "pocket_fident_qcov",
- pocket_threshold: int = 100,
- pocket_directed: bool = False,
- min_constant_size: int = 10,
-) -> pd.DataFrame:
- """Add mmpdb data to pocket and protein similarity dataset.
-
- Parameters
- ----------
- load_mmp_df : Path
- mmpdb index dataframe with columns \
- ["SMILES1", "SMILES2", "id1", "id2", "V1>>V2", "CONSTANT"]
- system_df : pd.DataFram
- Systems dataframe
- protein_similarity_path : Path
- protein sequence identity cluster file path
- pocket_similarity_path : Path
- pocket sequence identity cluster file path
- protein_similarity_tag : str
- protein similarity tag (e.g protein_fident_weighted_sum__0.95__weak__component)
- pocket_similarity_tag : str
- pocket similarity tag (e.g pocket_fident_weighted_sum__1.0__strong__component)
- min_constant_size : int
- minimum constant size
-
- Returns
- -------
- pd.DataFrame
- """
- protein_component_type = "strong" if protein_directed else "weak"
- protein_similarity_tag = (
- f"{protein_metric}__{protein_threshold}__{protein_component_type}__component"
- )
- pocket_component_type = "strong" if pocket_directed else "weak"
- pocket_similarity_tag = (
- f"{pocket_metric}__{pocket_threshold}__{pocket_component_type}__component"
- )
-
- # Load protein and pocket similarity data
- protein_similarity_df = pd.read_parquet(
- cluster_folder
- / "cluster=components"
- / f"directed={protein_directed}"
- / f"metric={protein_metric}"
- / f"threshold={protein_threshold}.parquet"
- )
- protein_similarity_dict = dict(
- zip(protein_similarity_df["system_id"], protein_similarity_df["label"])
- )
- pocket_similarity_df = pd.read_parquet(
- cluster_folder
- / "cluster=components"
- / f"directed={pocket_directed}"
- / f"metric={pocket_metric}"
- / f"threshold={pocket_threshold}.parquet"
- )
- pocket_similarity_dict = dict(
- zip(pocket_similarity_df["system_id"], pocket_similarity_df["label"])
- )
-
- # Merge protein similarity with system df
- system_df[protein_similarity_tag] = system_df["system_id"].map(
- protein_similarity_dict
- )
-
- # Merge pocket similarity with system df
- system_df[pocket_similarity_tag] = system_df["system_id"].map(
- pocket_similarity_dict
- )
-
- # Load mmp index
- # load_mmp_df = pd.read_csv(mmp_index, compression="gzip", sep="\t", header=None)
- # load_mmp_df.columns = ["SMILES1", "SMILES2", "id1", "id2", "V1>>V2", "CONSTANT"]
-
- # Pad interger lig ids with zeros
- load_mmp_df["id1"] = load_mmp_df.id1.apply(pad_integer_lig_ids_with_zeros)
- load_mmp_df["id2"] = load_mmp_df.id2.apply(pad_integer_lig_ids_with_zeros)
-
- # Consider only single position changes to the constant!
- load_mmp_df = load_mmp_df[
- load_mmp_df.CONSTANT.apply(lambda x: x.count("*")) == 1
- ].copy()
-
- # Select relevant columns from system df
- pocket_df = system_df[
- ["ligand_unique_ccd_code", protein_similarity_tag, pocket_similarity_tag]
- ].copy()
-
- pocket_df.loc[:, "prot_pocket_id"] = (
- pocket_df.loc[:, protein_similarity_tag]
- + "_"
- + pocket_df.loc[:, pocket_similarity_tag]
- )
-
- # Map ligand ccd code to prot_pocket_id sets
- ligand_code_pocket_mapping = (
- pocket_df.groupby("ligand_unique_ccd_code").agg(set)["prot_pocket_id"].to_dict()
- )
-
- load_mmp_df["prot_pocket_set_id1"] = load_mmp_df["id1"].map(
- ligand_code_pocket_mapping
- )
- load_mmp_df["prot_pocket_set_id2"] = load_mmp_df["id2"].map(
- ligand_code_pocket_mapping
- )
-
- load_mmp_df.dropna(inplace=True)
-
- # Get MMPs that share prot_pocket_id
- load_mmp_df["prot_pocket_set_shared"] = load_mmp_df[
- ["prot_pocket_set_id1", "prot_pocket_set_id2"]
- ].apply(lambda x: x.iloc[0].intersection(x.iloc[1]), axis=1)
- # remove pairs that do not share a prot_pocket id
- mmps_pocket_df = load_mmp_df[
- load_mmp_df["prot_pocket_set_shared"].apply(lambda x: len(x) > 0)
- ]
-
- # Group pocket across different mmps
- mmps_pocket_df1 = mmps_pocket_df.explode("prot_pocket_set_shared")
-
- # Identity congeneric series - MMS - group that shares
- # identical constant (with a single vector) and prot_pockets !
- grp_congeneric_df = mmps_pocket_df1.groupby(
- ["CONSTANT", "prot_pocket_set_shared"]
- ).agg(tuple)[["id1", "id2"]]
- # set to tuple for being hashable
- grp_congeneric_df["congeneric_series"] = grp_congeneric_df[["id1", "id2"]].apply(
- lambda x: tuple(sorted(set(list(x.iloc[0]) + list(x.iloc[1])))), axis=1
- )
-
- # NOTE: some ligands will appear in multiple instances!
- # TODO: be careful when dropping during BO to see if there were multiple and if a ligand is to be removed!
- grp_congeneric_df["mms_unique_count"] = grp_congeneric_df[
- "congeneric_series"
- ].apply(lambda x: len({i for i in x}))
-
- # Reset index to include "CONSTANT" as a column
- grp_congeneric_df = grp_congeneric_df.reset_index()
-
- # Get constant size
- const_size_map = {
- smarts: Chem.MolFromSmarts(smarts).GetNumHeavyAtoms()
- for smarts in grp_congeneric_df.CONSTANT.drop_duplicates()
- }
- grp_congeneric_df["const_size"] = grp_congeneric_df.CONSTANT.map(const_size_map)
-
- # Extract data with min_constant_size threshold
- grp_congeneric_df_thres = grp_congeneric_df[
- grp_congeneric_df.const_size >= min_constant_size
- ].copy()
-
- # Set congeneric id that is unique to mms
- grp_congeneric_df_thres = grp_congeneric_df_thres.reset_index().rename(
- columns={"index": "congeneric_id"}
- )
- grp_congeneric_df_thres["congeneric_id"] = grp_congeneric_df_thres[
- "congeneric_id"
- ].apply(lambda x: f"c{x:.0f}")
-
- # get table for each member in congeneric_series
- grp_congeneric_df_thres["congeneric_ligand_ccd_code"] = grp_congeneric_df_thres[
- "congeneric_series"
- ].copy()
- grp_congeneric_df_thres = grp_congeneric_df_thres.explode(
- "congeneric_ligand_ccd_code"
- )
-
- # Merge mms data with system-level data
- grp_congeneric_df_thres["prot_pocket_lig_tag"] = (
- grp_congeneric_df_thres["prot_pocket_set_shared"]
- + "_"
- + grp_congeneric_df_thres["congeneric_ligand_ccd_code"]
- )
- system_df["prot_pocket_lig_tag"] = system_df[
- [protein_similarity_tag, pocket_similarity_tag, "ligand_unique_ccd_code"]
- ].apply(lambda x: f"{x.iloc[0]}_{x.iloc[1]}_{x.iloc[2]}", axis=1)
-
- final_df = (
- system_df[["prot_pocket_lig_tag", "system_id"]]
- .drop_duplicates()
- .merge(grp_congeneric_df_thres, on="prot_pocket_lig_tag", how="left")
- .drop_duplicates()
- .drop(columns=["id1", "id2", "prot_pocket_lig_tag"])
- )
- # remove those that are not mapped!
- final_df = final_df[~final_df["congeneric_id"].isna()]
-
- return final_df
-
-
-def split_list_into_batches(
- lst: list[list[Any]], batch_size: int | None = None, num_batches: int | None = None
-) -> Generator[Any, Any, Any]:
- """Split list of items into list of lists.
-
- Parameters
- ----------
- lst : list[list[Any]],
- list to be split
- batch_size : int | None = None,
- size of each batch
- num_batches : int | None = None,
- number of batches to return
- Returns
- -------
- Generator[Any, Any, Any]
- """
- if batch_size is None and num_batches is None:
- raise ValueError("Either batch_size or num_batches must be provided.")
-
- if num_batches is not None:
- # Ceiling division to ensure all items are included
- batch_size = -(-len(lst) // num_batches)
-
- args = [iter(lst)] * batch_size # type: ignore
- for batch in zip_longest(*args, fillvalue=None):
- yield [item for item in batch if item is not None]
diff --git a/src/plinder/data/utils/annotations/protein_utils.py b/src/plinder/data/utils/annotations/protein_utils.py
deleted file mode 100644
index 8013b6822..000000000
--- a/src/plinder/data/utils/annotations/protein_utils.py
+++ /dev/null
@@ -1,392 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-import gzip
-from collections import defaultdict
-from functools import cached_property
-from pathlib import Path
-from typing import Any
-
-from mmcif.api.PdbxContainers import DataContainer
-from mmcif.io.PdbxReader import PdbxReader
-from ost import conop, io, mol
-from PDBValidation.Validation import PDBValidation
-from pydantic import ConfigDict, Field
-
-from plinder.data.utils.annotations.get_ligand_validation import (
- ResidueListValidation,
- ResidueValidation,
- ResidueValidationThresholds,
-)
-from plinder.data.utils.annotations.utils import DocBaseModel
-
-NON_SMALL_MOL_LIG_TYPES = [
- mol.CHAINTYPE_POLY,
- mol.CHAINTYPE_POLY_PEPTIDE_D,
- mol.CHAINTYPE_POLY_PEPTIDE_L,
- mol.CHAINTYPE_POLY_PEPTIDE_D,
- mol.CHAINTYPE_POLY_PEPTIDE_L,
- mol.CHAINTYPE_POLY_DN,
- mol.CHAINTYPE_POLY_RN,
- mol.CHAINTYPE_POLY_SAC_D,
- mol.CHAINTYPE_POLY_SAC_L,
- mol.CHAINTYPE_POLY_DN_RN,
- mol.CHAINTYPE_MACROLIDE,
- mol.CHAINTYPE_CYCLIC_PSEUDO_PEPTIDE,
- mol.CHAINTYPE_POLY_PEPTIDE_DN_RN,
- mol.CHAINTYPE_BRANCHED,
- mol.CHAINTYPE_OLIGOSACCHARIDE,
- mol.CHAINTYPE_N_CHAINTYPES,
-]
-
-
-def read_mmcif_container(mmcif_filename: Path) -> DataContainer:
- """Parse mmcif file with PDBxReader
-
- Parameters
- ----------
- mmcif_filename : Path
- Returns
- -------
- DataContainer
-
- """
- data: list[DataContainer] = []
- if mmcif_filename.suffix == ".gz":
- with gzip.open(str(mmcif_filename), "rt", encoding="utf-8") as f:
- prd = PdbxReader(f)
- prd.read(data)
- else:
- prd = PdbxReader(mmcif_filename)
- prd.read(data)
- return data[0]
-
-
-def get_entry_info(data: DataContainer) -> dict[str, str | float | None]:
- """Get entry-level information from DataContainer
-
- Parameters
- ----------
- data : DataContainer
- Data container fot mmcif attributes
- Returns
- -------
- dict[str, str | float | None]
- Dictionary of entry-level information
-
- """
- entry_info = {}
- mappings = [
- ("entry_oligomeric_state", "pdbx_struct_assembly", "oligomeric_details"),
- ("entry_determination_method", "exptl", "method"),
- ("entry_keywords", "struct_keywords", "pdbx_keywords"),
- ("entry_pH", "exptl_crystal_grow", "pH"),
- ]
- for key, obj_name, attr_name in mappings:
- x = data.getObj(obj_name)
- if x is not None:
- entry_info[key] = x.getValueOrDefault(attr_name)
- resolution_options = [
- ("refine", "ls_d_res_high"),
- # ("em_3d_reconstruction", "resolution"), # TODO: add this back for next annotation rerun
- ]
- resolution = None
- for obj_name, attr_name in resolution_options:
- x = data.getObj(obj_name)
- if x is not None:
- r = x.getValueOrDefault(attr_name)
- if r is not None:
- resolution = r
- break
- entry_info["entry_resolution"] = resolution
- return entry_info
-
-
-def get_chain_external_mappings(
- data: DataContainer
-) -> dict[str, dict[str, dict[str, list[tuple[str, str] | None]]]]:
- """Get additional metadata directory from nextgen mmcif
-
- Parameters
- ----------
- cif_file : Path
- Next-gen mmcif file
-
- Returns
- -------
- Tuple[Dict[Any, Any], Dict[Any, Any]]
- """
- per_chain: dict[str, dict[str, dict[str, set[tuple[str, str] | None]]]] = {}
-
- # SIFTS mapping
- xref = data.getObj("pdbx_sifts_xref_db_segments")
- if xref is not None:
- columns = xref.getAttributeList()
- for a in xref:
- a = dict(zip(columns, a))
- if a["asym_id"] not in per_chain:
- per_chain[a["asym_id"]] = defaultdict(lambda: defaultdict(set))
- per_chain[a["asym_id"]][a["xref_db"]][a["xref_db_acc"]].add(
- (a["seq_id_start"], a["seq_id_end"])
- )
-
- # UniProt mapping
- uniprot = data.getObj("pdbx_sifts_unp_segments")
- if uniprot is not None:
- columns = uniprot.getAttributeList()
- for a in uniprot:
- a = dict(zip(columns, a))
- if a["asym_id"] not in per_chain:
- per_chain[a["asym_id"]] = defaultdict(lambda: defaultdict(set))
- per_chain[a["asym_id"]]["UniProt"][a["unp_acc"]].add(
- (a["seq_id_start"], a["seq_id_end"])
- )
-
- # BIRD entries with PRD codes: https://www.wwpdb.org/data/bird
- pdbx_molecule = data.getObj("pdbx_molecule")
- # see: https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Categories/pdbx_molecule.html
- if pdbx_molecule is not None:
- columns = pdbx_molecule.getAttributeList()
- for a in pdbx_molecule:
- a = dict(zip(columns, a))
- if a["asym_id"] not in per_chain:
- per_chain[a["asym_id"]] = defaultdict(lambda: defaultdict(set))
- per_chain[a["asym_id"]]["BIRD"][f"{a['asym_id']}"].add(None)
- per_chain_list: dict[str, dict[str, dict[str, list[tuple[str, str] | None]]]] = {}
- for chain in per_chain:
- per_chain_list[chain] = {}
- for mapping in per_chain[chain]:
- per_chain_list[chain][mapping] = {
- k: list(v) for k, v in per_chain[chain][mapping].items()
- }
- return per_chain_list
-
-
-def detect_ligand_chains(
- entity: Any,
- entry: Any,
- min_polymer_size: int = 10,
- max_non_small_mol_ligand_length: int = 20,
-) -> dict[str, str]:
- """
- Note
- ----
- entity is the first element of the tuple returned by ost.io.LoadMMCIF
- entry is an Entry object that contains appropriate mappings
- """
- ligand_chains = dict()
- for chain in entity.chains:
- if chain.type == mol.CHAINTYPE_WATER:
- continue
- # classifying by polymer length and annotations
- chain_length = len(chain.residues)
- bird_id = list(entry.chains[chain.name].mappings.get("BIRD", {"": None}))[0]
- uniprot_id = list(entry.chains[chain.name].mappings.get("UniProt", {"": None}))[
- 0
- ]
- # TODO: Let's revisit this at some point, but I think this logic is too
- # complicated, could be simplified.
- if (
- # chain has PRD id based on BIRD annotation:
- # https://www.wwpdb.org/data/bird
- # thus can be considered as ligand!
- bird_id
- ) or (
- # short/medium synthetic peptides that do not map to UniProt are considered ligand
- chain.is_polypeptide
- and chain_length <= max_non_small_mol_ligand_length
- and not uniprot_id
- ):
- ligand_chains[chain.name] = str(chain.type)
-
- elif (
- # Polymers that do not fall for the exception above and
- # are longer that certain length to be considered as ligands
- # TODO: these are all polymer chains, we might want to separate into protein chains and other
- (chain.is_polypeptide and chain_length >= min_polymer_size)
- or (chain.is_polynucleotide and chain_length >= min_polymer_size)
- or (
- (chain.is_oligosaccharide or chain.is_polysaccharide)
- and chain_length >= min_polymer_size
- )
- or (chain.type == mol.CHAINTYPE_POLY and chain_length >= min_polymer_size)
- ):
- # these are excluded!
- continue
- else:
- # the rest is guessed as being ligand
- ligand_chains[chain.name] = str(chain.type)
- return ligand_chains
-
-
-class Residue(DocBaseModel):
- chain: str
- index: int
- number: int
- auth_number: str
- one_letter_code: str
- name: str
- chem_type: str
- validation: ResidueValidation | None = None
- """
- This dataclass defines as system which included a protein-ligand complex
- and it's neighboring ligands and protein residues
-
- Parameters
- ----------
- chain : str
- chain name
- index : int
- residue index
- number : int
- residue number
- one_letter_code : str
- residue one-letter code
- name : str
- residue name
- chem_type: mol.ChemType
- residue chemical type
-
- Attributes
- ----------
- is_ptm: bool
- Does residue have post translational modification
-
- Examples
- --------
- TODO: Add example
- """
-
- @cached_property
- def is_ptm(self) -> bool:
- """
- Does the residue have a post translational modification.
- """
- return (
- mol.ChemType(self.chem_type).IsAminoAcid()
- and self.name not in conop.STANDARD_AMINOACIDS
- )
-
-
-class Chain(DocBaseModel):
- asym_id: str = Field(description="Chain asymmetric id")
- auth_id: str = Field(description="Chain author id")
- entity_id: str = Field(description="Chain entity id")
- chain_type_str: str = Field(
- description="__Chain type string representation as defined https://openstructure.org/docs/2.8/mol/base/entity/#ost.mol.ChainType"
- )
- residues: dict[int, Residue] = Field(
- description="__Dictionary of residues in chain with keys as residue number"
- )
- length: int = Field(description="SEQRES length")
- num_unresolved_residues: int = Field(
- description="Number of unresolved residues (SEQRES length - len(residues))"
- )
- mappings: dict[str, dict[str, list[tuple[str, str] | None]]] = Field(
- default_factory=dict,
- description="__Mapping of metadata associated with chain with keys as chain asym id",
- )
- holo: bool = Field(
- default=True, description="__Is the chain part of a holo system or not"
- )
- validation: ResidueListValidation | None = Field(
- default=None,
- description="__Crystal validation information for the residues in the chain",
- )
-
- # Added this because pydantic doesn't know how to validate mol.ChainType
- model_config = ConfigDict(
- arbitrary_types_allowed=True,
- )
-
- @classmethod
- def from_ost_chain(
- cls, chain: mol.ChainHandle, info: io.MMCifInfo, length: int
- ) -> Chain:
- """Load Chain from ost Chain.
-
- Parameters
- ----------
- cls : Chain
- Chain class
- chain: mol.ChainHandle :
- Openstructure mol.ChainHandle
- info: io.MMCifInfo
- Openstructure io.MMCifInfo
- length: int
- SEQRES length
-
- Returns
- -------
- Chain
- """
- residues = {
- residue.number.num: Residue(
- chain=chain.name,
- index=residue_index,
- number=residue.number.num,
- auth_number=residue.GetStringProp("pdb_auth_resnum"),
- one_letter_code=residue.one_letter_code,
- name=residue.name,
- chem_type=str(residue.chem_type),
- )
- for residue_index, residue in enumerate(chain.residues)
- }
- auth_id = ""
- if "." not in chain.name:
- auth_id = chain.GetStringProp("pdb_auth_chain_name")
- return cls(
- asym_id=chain.name,
- auth_id=auth_id,
- entity_id=info.GetMMCifEntityIdTr(chain.name),
- chain_type_str=str(mol.StringFromChainType(chain.type)),
- residues=residues,
- length=length,
- num_unresolved_residues=length - len(residues),
- )
-
- @cached_property
- def chain_type(self) -> mol.ChainType:
- """
- __Chain type as defined https://openstructure.org/docs/2.8/mol/base/entity/#ost.mol.ChainType
- """
- return mol.ChainTypeFromString(self.chain_type_str)
-
- @cached_property
- def residue_index_to_number(self) -> dict[int, int]:
- """
- __Dictionary of residue index to residue number
- """
- return {self.residues[r].index: r for r in self.residues}
-
- def format(self, instance: int) -> dict[str, Any]:
- """
- Format chain as a dictionary
- """
- data: dict[str, Any] = {
- "asym_id": f"{instance}.{self.asym_id}",
- "auth_id": self.auth_id,
- "entity_id": self.entity_id,
- "length": self.length,
- "num_unresolved_residues": self.num_unresolved_residues,
- }
- # data.update(self.mappings)
- if self.validation is not None:
- data.update(self.validation.format())
- return data
-
- def set_validation(
- self, doc: PDBValidation, residue_thresholds: ResidueValidationThresholds
- ) -> None:
- for residue in self.residues:
- self.residues[residue].validation = ResidueValidation.from_residue(
- self.asym_id, residue, self.entity_id, doc
- )
- validations = []
- for r in self.residues.values():
- if r.validation is not None:
- validations.append(r.validation)
- self.validation = ResidueListValidation.from_residues(
- validations, residue_thresholds
- )
diff --git a/src/plinder/data/utils/annotations/rdkit_utils.py b/src/plinder/data/utils/annotations/rdkit_utils.py
deleted file mode 100644
index e92fd99e3..000000000
--- a/src/plinder/data/utils/annotations/rdkit_utils.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-from openbabel import pybel
-from ost import conop, io
-from ost import mol as omol
-from rdkit import Chem
-from rdkit.Chem.rdchem import Mol
-
-from plinder.core.structure.smallmols_utils import (
- fix_valency_issues,
- get_matched_template,
- get_matched_template_v2,
- make_rdkit_compatible_mol,
- mol_assigned_bond_orders_by_template,
- params_removeHs,
- uncharge_mol,
-)
-from plinder.core.utils.constants import BASE_DIR
-from plinder.core.utils.log import setup_logger
-
-LOG = setup_logger(__name__)
-COMPOUND_LIB = conop.GetDefaultLib()
-PRD_LIB = conop.CompoundLib.Load(
- str(BASE_DIR / "data/utils/annotations/static_files/prdcc.chemlib")
-)
-
-
-def ligand_ost_ent_to_rdkit_mol(
- ent: omol.EntityHandle,
- ligand_smiles: str | None = None,
- ligand_num_unresolved_heavy_atoms: int = 0,
-) -> Mol:
- new_chains = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- edi = ent.EditXCS(omol.BUFFERED_EDIT)
- for i, chain in enumerate(ent.GetChainList()):
- edi.RenameChain(chain, f"{new_chains[i]}")
- edi.UpdateICS()
-
- pdbstring = io.EntityToPDBStr(ent).strip()
- # NOTE: rdkit's Chem.MolFromPDBBlock does not read connect records
- # work around via openbabel bond perception
- sdfstring = pybel.readstring("pdb", pdbstring).write("sdf")
- rdkit_mol = Chem.MolFromMolBlock(sdfstring, sanitize=False) # , removeHs=True,
- # removeHs does not work when sanitize is False
- rdkit_mol = params_removeHs(rdkit_mol)
-
- if ligand_smiles:
- try:
- rdkit_mol = make_rdkit_compatible_mol(rdkit_mol)
- # if smiles match - no fix is needed!
- if Chem.CanonSmiles(ligand_smiles) == Chem.CanonSmiles(
- Chem.MolToSmiles(rdkit_mol)
- ):
- return rdkit_mol
- else:
- raise AssertionError("SMILES do not match reference - will try fixing")
- except Exception as e:
- LOG.warning(f"ligand_ost_ent_to_rdkit_mol: {e}")
- try:
- # another try via OST SDF
- # open structure output singly bonded SDF that can be adjusted with template
- # first - try to get a fixed molecule
- sdfstring_ost = io.EntityToSDFStr(ent).strip()
- rdkit_mol_tmp = Chem.MolFromMolBlock(
- sdfstring_ost,
- sanitize=False,
- # removeHs=True,
- )
- # Note: removeHs does not work when sanitize is False
- rdkit_mol_tmp = params_removeHs(rdkit_mol_tmp)
- # attempt to pre-emptively fix some valency problems
- try:
- rdkit_mol_tmp = fix_valency_issues(rdkit_mol_tmp)
- except Exception:
- LOG.warning(
- "fix_valency_issues: failed before mol_assigned_bond_orders_by_template"
- )
- # get template from smiles
- template = Chem.MolFromSmiles(ligand_smiles)
- if ligand_num_unresolved_heavy_atoms > 0:
- # update template
- # TODO: could be replaced by get_matched_template_v2
- template = get_matched_template(template, rdkit_mol_tmp)
- try:
- # Assign bonds by template
- rdkit_mol = mol_assigned_bond_orders_by_template(
- template, rdkit_mol_tmp
- )
- except ValueError as e:
- LOG.error(
- f"template bonds could not be assigned: {e}; "
- f"template_smiles: {ligand_smiles}"
- )
- raise ValueError(
- "cannot assign bonds by SMILES, use OpenBabel inference instead"
- )
- except Exception as e:
- LOG.warning(f"ligand_ost_ent_to_rdkit_mol: {e}")
- try:
- # Fix issues if any
- rdkit_mol = make_rdkit_compatible_mol(rdkit_mol)
- # run uncharger - for consistent protonation
- rdkit_mol = uncharge_mol(rdkit_mol)
- if rdkit_mol is None:
- raise ValueError("make_rdkit_compatible_mol: returned None")
- elif len(Chem.MolToSmiles(rdkit_mol).split(".")) > 1:
- raise ValueError(
- f"rdkit_mol seems fragmented: molecule is not connected: {Chem.MolToSmiles(rdkit_mol)}"
- )
- except Exception as e:
- LOG.error(f"ligand_ost_ent_to_rdkit_mol: could not fix: {e}")
- return rdkit_mol
-
-
-def set_smiles_from_ligand_ost(ent: omol.EntityHandle) -> str:
- residues = [res.name for res in ent.residues]
- if len(residues) == 1:
- resname = residues[0]
- if resname.startswith("PRD_"):
- # TODO - need to make this line used!
- # currently, PRD_entries are not mapped to residue names and are more than one residue!
- mol = PRD_LIB.FindCompound(resname)
- else:
- mol = COMPOUND_LIB.FindCompound(resname)
- if mol is not None:
- try:
- rdkit_mol = Chem.MolFromSmiles(str(mol.smiles), sanitize=False)
- rdkit_mol = make_rdkit_compatible_mol(rdkit_mol)
- # run uncharger - for consistent protonation
- rdkit_mol = uncharge_mol(rdkit_mol)
- return str(Chem.MolToSmiles(rdkit_mol))
- except Exception:
- LOG.warning(
- "set_smiles_from_ligand_ost: CCD smiles could not be loaded by rdkit, moving to fix"
- )
- rdkit_mol = ligand_ost_ent_to_rdkit_mol(ent)
- return str(Chem.MolToSmiles(rdkit_mol))
-
-
-def set_smiles_from_ligand_ost_v2(ent: omol.EntityHandle) -> tuple[str, str]:
- input_smiles = ""
- residues = [res.name for res in ent.residues]
- if len(residues) == 1:
- resname = residues[0]
- if resname.startswith("PRD_"):
- # TODO - need to make this line used!
- # currently, PRD_entries are not mapped to residue names and are more than one residue!
- mol = PRD_LIB.FindCompound(resname)
- else:
- mol = COMPOUND_LIB.FindCompound(resname)
- if mol is not None:
- try:
- template_mol = Chem.MolFromSmiles(str(mol.smiles), sanitize=False)
- template_mol = make_rdkit_compatible_mol(template_mol)
- input_smiles = str(Chem.MolToSmiles(template_mol))
- except Exception:
- LOG.warning(
- "set_smiles_from_ligand_ost_v2: CCD smiles could not be loaded by RDKit, moving to fix"
- )
- resolved_mol = ligand_ost_ent_to_rdkit_mol(ent)
- if input_smiles:
- matched_template = get_matched_template_v2(template_mol, resolved_mol)
- matched_smiles = Chem.CanonSmiles(Chem.MolToSmiles(matched_template))
- else:
- matched_smiles = Chem.CanonSmiles(str(Chem.MolToSmiles(resolved_mol)))
- # when no reference - define this as a match and the ground truth
- input_smiles = matched_smiles
- return input_smiles, matched_smiles
diff --git a/src/plinder/data/utils/annotations/save_utils.py b/src/plinder/data/utils/annotations/save_utils.py
deleted file mode 100644
index 8e2757cbd..000000000
--- a/src/plinder/data/utils/annotations/save_utils.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-import json
-import typing as ty
-from pathlib import Path
-
-from ost import conop, io, mol
-from rdkit import Chem
-
-from plinder.data.utils.annotations.rdkit_utils import ligand_ost_ent_to_rdkit_mol
-
-# Define available names for protein and ligand chains in PDB format
-PDB_PROTEIN_CHAINS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-PDB_LIGAND_CHAINS = PDB_PROTEIN_CHAINS.lower() + "0123456789"
-WATER_CHAIN_NAME = "_"
-
-
-def save_ligands(
- ent: mol.EntityHandle,
- ligand_selections: list[str],
- ligand_chains: list[str],
- ligand_smiles: list[str],
- ligand_num_unresolved_heavy_atoms: list[int | None],
- output_folder: str | Path,
-) -> None:
- for selection, chain, smiles, num_unresolved_heavy_atoms in zip(
- ligand_selections,
- ligand_chains,
- ligand_smiles,
- ligand_num_unresolved_heavy_atoms,
- ):
- ligand_ost = mol.CreateEntityFromView(ent.Select(selection), True)
- rdkit_mol = ligand_ost_ent_to_rdkit_mol(
- ligand_ost, smiles, num_unresolved_heavy_atoms or 0
- )
- rdkit_mol.SetProp("_Name", chain)
- with Chem.SDWriter(str(Path(output_folder) / f"{chain}.sdf")) as w:
- w.write(rdkit_mol)
-
-
-def save_pdb_file(
- full_biounit: mol.EntityHandle,
- ent: mol.EntityHandle,
- protein_chains: ty.List[str],
- ligand_chains: ty.List[str],
- output_pdb_file: ty.Union[str, Path],
- output_mapping_file: ty.Union[str, Path],
- waters: ty.Dict[str, ty.List[int]],
- water_mapping_file: ty.Union[str, Path],
-) -> None:
- """Renames protein and ligand chains to fit the PDB single-letter chain name convention, saves the entity to a PDB file
- and saves the mapping between original and new chain names to a JSON file
-
- Args:
- full_biounit (mol.EntityHandle): original biounit entity with all chains
- ent (mol.EntityHandle): selected entity with only the protein and ligand chains of the system
- protein_chains (ty.List[str]): list of protein chains
- ligand_chains (ty.List[str]): list of ligand chains
- waters (ty.Dict[str, ty.List[int]]): dictionary with water chain names as keys and list of water residue indices as values
- output_pdb_file (ty.Union[str, Path]): path to the output PDB file
- output_mapping_file (ty.Union[str, Path]): path to the output JSON file
- """
- if len(waters):
- ent = mol.CreateEntityFromView(ent.Select("water=False"), True)
-
- # Intermediate renaming step
- intermediate_names = {}
- edi = ent.EditXCS(mol.BUFFERED_EDIT)
- for i, chain in enumerate(ent.GetChainList()):
- intermediate_names[f"T{i}"] = chain.name
- edi.RenameChain(chain, f"T{i}")
- edi.UpdateICS()
-
- # Final renaming step
- protein_chain_index = 0
- ligand_chain_index = 0
- name_mapping = {}
- water_mapping: dict[str, dict[int, int]] = {}
-
- for chain in ent.GetChainList():
- original_name = intermediate_names[chain.name]
- original_chain = full_biounit.FindChain(original_name)
- if original_name in protein_chains:
- final_name = PDB_PROTEIN_CHAINS[protein_chain_index]
- protein_chain_index += 1
- elif original_name in ligand_chains:
- final_name = PDB_LIGAND_CHAINS[ligand_chain_index]
- ligand_chain_index += 1
- edi.RenameChain(chain, final_name)
- edi.SetChainDescription(chain, original_chain.description)
- edi.SetChainType(chain, original_chain.type)
- name_mapping[original_name] = final_name
-
- if len(waters):
- water_chain = edi.InsertChain(WATER_CHAIN_NAME)
- edi.SetChainDescription(water_chain, "Interacting waters")
- edi.SetChainType(water_chain, mol.CHAINTYPE_WATER)
- index = 1
- for chain in waters:
- water_mapping[chain] = {}
- for resnum in waters[chain]:
- new_residue = edi.AppendResidue(
- water_chain,
- full_biounit.FindChain(chain).FindResidue(resnum),
- deep=True,
- )
- edi.SetResidueNumber(new_residue, index)
- water_mapping[chain][int(resnum)] = new_residue.number.num
- index += 1
-
- edi.UpdateICS()
- io.SavePDB(ent, str(output_pdb_file))
- with open(output_mapping_file, "w") as f:
- json.dump(name_mapping, f)
- if len(waters):
- with open(water_mapping_file, "w") as f:
- json.dump(water_mapping, f)
-
-
-def save_cif_file(
- ent: mol.EntityHandle,
- info: io.MMCifInfo,
- name: str,
- output_cif_file: ty.Union[str, Path],
-) -> None:
- lib = conop.GetDefaultLib()
- entity_info = io.MMCifWriterEntityList()
- entity_ids = set(
- info.GetMMCifEntityIdTr(ch.name.split(".")[-1]) for ch in ent.chains
- )
- for entity_id in info.GetEntityIdsOfType("polymer"):
- if entity_id not in entity_ids:
- continue
- # Get entity description from info object
- entity_desc = info.GetEntityDesc(entity_id)
- e = io.MMCifWriterEntity.FromPolymer(
- entity_desc.entity_poly_type, entity_desc.mon_ids, lib
- )
- entity_info.append(e)
- # search all chains assigned to the entity we just added
- for ch in ent.chains:
- if info.GetMMCifEntityIdTr(ch.name.split(".")[-1]) == entity_id:
- entity_info[-1].asym_ids.append(ch.name)
- # deal with heterogeneities
- for a, b in zip(entity_desc.hetero_num, entity_desc.hetero_ids):
- entity_info[-1].AddHet(a, b)
- writer = io.MMCifWriter()
- writer.SetStructure(ent, lib, entity_info=entity_info)
- writer.Write(name, str(output_cif_file))
diff --git a/src/plinder/data/utils/annotations/static_files/cofactors.json b/src/plinder/data/utils/annotations/static_files/cofactors.json
deleted file mode 100644
index af2f53c38..000000000
--- a/src/plinder/data/utils/annotations/static_files/cofactors.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Coenzyme A": [{"cofactors": ["01A", "01K", "0ET", "1C4", "1CV", "1CZ", "1HA", "1VU", "1XE", "2CP", "2NE", "3CP", "3H9", "3HC", "4CA", "4CO", "8JD", "8Z2", "ACO", "AMX", "BCA", "BCO", "BSJ", "BYC", "CA3", "CA5", "CA6", "CA8", "CAA", "CAJ", "CAO", "CIC", "CMC", "CMX", "CO6", "CO8", "COA", "COD", "COF", "COO", "COT", "COW", "COZ", "DCA", "DCC", "FAM", "FCX", "FRE", "FYN", "GRA", "HAX", "HMG", "HSC", "HXC", "MCA", "MCD", "MDE", "MLC", "MYA", "NHM", "NHQ", "NHW", "NMX", "OXK", "S0N", "SCA", "SCD", "SCO", "SDX", "SOP", "T1G", "TC6", "WCA", "YNC", "ZOZ"], "EC": ["1.1.1.34", "1.1.1.88", "1.14.19.3", "1.17.99.3", "1.2.1.10", "1.2.1.17", "1.2.1.18", "1.2.1.2", "1.2.1.25", "1.2.1.27", "1.2.1.42", "1.2.1.44", "1.2.1.50", "1.2.1.51", "1.2.1.52", "1.2.1.57", "1.2.1.58", "1.2.1.75", "1.2.3.6", "1.2.7.1", "1.2.7.2", "1.2.7.3", "1.2.7.7", "1.2.7.8", "1.8.1.10", "1.8.1.14", "1.8.4.3", "2.3.1.1", "2.3.1.10", "2.3.1.100", "2.3.1.102", "2.3.1.104", "2.3.1.105", "2.3.1.106", "2.3.1.107", "2.3.1.108", "2.3.1.109", "2.3.1.11", "2.3.1.110", "2.3.1.111", "2.3.1.112", "2.3.1.113", "2.3.1.114", "2.3.1.115", "2.3.1.116", "2.3.1.117", "2.3.1.118", "2.3.1.119", "2.3.1.12", "2.3.1.121", "2.3.1.123", "2.3.1.125", "2.3.1.126", "2.3.1.127", "2.3.1.128", "2.3.1.13", "2.3.1.130", "2.3.1.131", "2.3.1.132", "2.3.1.133", "2.3.1.136", "2.3.1.137", "2.3.1.138", "2.3.1.139", "2.3.1.14", "2.3.1.140", "2.3.1.142", "2.3.1.144", "2.3.1.145", "2.3.1.146", "2.3.1.148", "2.3.1.15", "2.3.1.150", "2.3.1.151", "2.3.1.153", "2.3.1.154", "2.3.1.155", "2.3.1.156", "2.3.1.157", "2.3.1.159", "2.3.1.16", "2.3.1.160", "2.3.1.161", "2.3.1.162", "2.3.1.163", "2.3.1.164", "2.3.1.165", "2.3.1.166", "2.3.1.167", "2.3.1.168", "2.3.1.169", "2.3.1.17", "2.3.1.170", "2.3.1.171", "2.3.1.172", "2.3.1.173", "2.3.1.174", "2.3.1.175", "2.3.1.176", "2.3.1.177", "2.3.1.178", "2.3.1.18", "2.3.1.180", "2.3.1.182", "2.3.1.183", "2.3.1.185", "2.3.1.186", "2.3.1.188", "2.3.1.19", "2.3.1.2", "2.3.1.20", "2.3.1.205", "2.3.1.209", "2.3.1.21", "2.3.1.210", "2.3.1.22", "2.3.1.23", "2.3.1.24", "2.3.1.25", "2.3.1.255", "2.3.1.257", "2.3.1.258", "2.3.1.26", "2.3.1.27", "2.3.1.28", "2.3.1.29", "2.3.1.3", "2.3.1.30", "2.3.1.31", "2.3.1.33", "2.3.1.34", "2.3.1.36", "2.3.1.37", "2.3.1.38", "2.3.1.39", "2.3.1.4", "2.3.1.42", "2.3.1.44", "2.3.1.45", "2.3.1.46", "2.3.1.47", "2.3.1.48", "2.3.1.5", "2.3.1.50", "2.3.1.51", "2.3.1.52", "2.3.1.53", "2.3.1.54", "2.3.1.57", "2.3.1.58", "2.3.1.59", "2.3.1.6", "2.3.1.60", "2.3.1.61", "2.3.1.62", "2.3.1.63", "2.3.1.64", "2.3.1.65", "2.3.1.66", "2.3.1.67", "2.3.1.68", "2.3.1.69", "2.3.1.7", "2.3.1.70", "2.3.1.71", "2.3.1.74", "2.3.1.75", "2.3.1.76", "2.3.1.78", "2.3.1.79", "2.3.1.8", "2.3.1.80", "2.3.1.81", "2.3.1.82", "2.3.1.84", "2.3.1.85", "2.3.1.86", "2.3.1.87", "2.3.1.88", "2.3.1.89", "2.3.1.9", "2.3.1.93", "2.3.1.94", "2.3.1.95", "2.3.1.96", "2.3.1.97", "2.3.1.99", "2.3.1.B6", "2.3.3.1", "2.3.3.10", "2.3.3.11", "2.3.3.12", "2.3.3.13", "2.3.3.14", "2.3.3.2", "2.3.3.3", "2.3.3.4", "2.3.3.5", "2.3.3.6", "2.3.3.7", "2.3.3.8", "2.3.3.9", "2.7.7.23", "2.8.3.1", "2.8.3.5", "3.1.2.1", "3.1.2.10", "3.1.2.11", "3.1.2.17", "3.1.2.18", "3.1.2.19", "3.1.2.2", "3.1.2.20", "3.1.2.23", "3.1.2.25", "3.1.2.26", "3.1.2.27", "3.1.2.3", "3.1.2.4", "3.1.2.5", "3.8.1.7", "4.1.1.31", "4.1.3.36", "4.1.3.6", "5.4.99.13", "6.2.1.1", "6.2.1.10", "6.2.1.11", "6.2.1.12", "6.2.1.13", "6.2.1.14", "6.2.1.15", "6.2.1.16", "6.2.1.17", "6.2.1.18", "6.2.1.2", "6.2.1.23", "6.2.1.24", "6.2.1.25", "6.2.1.26", "6.2.1.27", "6.2.1.28", "6.2.1.3", "6.2.1.30", "6.2.1.31", "6.2.1.32", "6.2.1.33", "6.2.1.34", "6.2.1.4", "6.2.1.5", "6.2.1.6", "6.2.1.7", "6.2.1.8", "6.2.1.9"]}], "Orthoquinone residues (LTQ, TTQ, CTQ)": [{"cofactors": ["0AF", "TOQ", "TQQ", "TRQ"], "EC": ["1.4.99.3"]}], "Glutathione": [{"cofactors": ["0HG", "0HH", "1JO", "1JP", "1R4", "3GC", "48T", "5AU", "ABY", "AHE", "ATA", "BOB", "BYG", "EPY", "ESG", "GBI", "GBP", "GBX", "GDN", "GDS", "GF5", "GGC", "GIP", "GNB", "GPR", "GPS", "GS8", "GSB", "GSF", "GSH", "GSM", "GSN", "GSO", "GTB", "GTD", "GTS", "GTX", "GTY", "GVX", "HAG", "IBG", "ICY", "JM2", "JM5", "JM7", "L9X", "LEE", "LZ6", "RGE", "TGG", "TS5", "VWW", "ZBF"], "EC": ["1.11.1.12", "1.11.1.17", "1.11.1.9", "1.13.11.18", "1.14.16.5", "1.2.1.46", "1.20.4.1", "1.20.4.2", "1.21.99.4", "1.5.4.1", "1.8.1.10", "1.8.1.16", "1.8.1.7", "1.8.1.B5", "1.8.3.3", "1.8.4.1", "1.8.4.2", "1.8.4.3", "1.8.4.4", "1.8.4.7", "1.8.4.9", "1.8.5.1", "1.8.98.2", "2.1.1.41", "2.1.1.45", "2.5.1.18", "2.8.1.3", "2.8.2.33", "3.1.2.12", "3.1.2.13", "3.1.2.6", "3.1.2.7", "3.5.1.78", "3.5.3.8", "4.4.1.20", "4.4.1.22", "4.4.1.5", "4.5.1.1", "4.5.1.3", "5.2.1.4", "5.3.4.1", "5.3.99.2", "5.3.99.3", "5.99.1.4", "6.3.2.3"]}], "S-adenosylmethionine": [{"cofactors": ["0UM", "0XU", "0Y0", "0Y1", "0Y2", "36A", "37H", "4IK", "62X", "6NR", "76H", "76J", "76K", "76L", "76M", "EEM", "K15", "SA8", "SAH", "SAM", "SFG", "SMM", "SX0", "TT8"], "EC": ["1.1.98.6", "1.16.1.8", "1.17.4.2", "1.3.99.22", "1.97.1.4", "2.1.1.1", "2.1.1.10", "2.1.1.100", "2.1.1.101", "2.1.1.102", "2.1.1.103", "2.1.1.104", "2.1.1.105", "2.1.1.106", "2.1.1.107", "2.1.1.108", "2.1.1.109", "2.1.1.11", "2.1.1.110", "2.1.1.111", "2.1.1.112", "2.1.1.113", "2.1.1.114", "2.1.1.115", "2.1.1.116", "2.1.1.117", "2.1.1.118", "2.1.1.119", "2.1.1.12", "2.1.1.120", "2.1.1.121", "2.1.1.122", "2.1.1.123", "2.1.1.124", "2.1.1.125", "2.1.1.126", "2.1.1.127", "2.1.1.128", "2.1.1.129", "2.1.1.13", "2.1.1.130", "2.1.1.131", "2.1.1.132", "2.1.1.133", "2.1.1.136", "2.1.1.137", "2.1.1.139", "2.1.1.140", "2.1.1.141", "2.1.1.142", "2.1.1.143", "2.1.1.144", "2.1.1.145", "2.1.1.146", "2.1.1.147", "2.1.1.149", "2.1.1.15", "2.1.1.150", "2.1.1.151", "2.1.1.152", "2.1.1.153", "2.1.1.154", "2.1.1.155", "2.1.1.156", "2.1.1.157", "2.1.1.158", "2.1.1.159", "2.1.1.16", "2.1.1.160", "2.1.1.161", "2.1.1.162", "2.1.1.163", "2.1.1.164", "2.1.1.165", "2.1.1.166", "2.1.1.167", "2.1.1.168", "2.1.1.169", "2.1.1.17", "2.1.1.170", "2.1.1.171", "2.1.1.173", "2.1.1.174", "2.1.1.175", "2.1.1.176", "2.1.1.178", "2.1.1.179", "2.1.1.18", "2.1.1.180", "2.1.1.182", "2.1.1.183", "2.1.1.184", "2.1.1.185", "2.1.1.186", "2.1.1.187", "2.1.1.189", "2.1.1.190", "2.1.1.192", "2.1.1.193", "2.1.1.197", "2.1.1.199", "2.1.1.2", "2.1.1.20", "2.1.1.200", "2.1.1.201", "2.1.1.202", "2.1.1.203", "2.1.1.204", "2.1.1.206", "2.1.1.207", "2.1.1.210", "2.1.1.212", "2.1.1.214", "2.1.1.215", "2.1.1.216", "2.1.1.219", "2.1.1.22", "2.1.1.220", "2.1.1.221", "2.1.1.222", "2.1.1.224", "2.1.1.226", "2.1.1.227", "2.1.1.228", "2.1.1.229", "2.1.1.230", "2.1.1.231", "2.1.1.232", "2.1.1.233", "2.1.1.234", "2.1.1.235", "2.1.1.236", "2.1.1.237", "2.1.1.240", "2.1.1.241", "2.1.1.243", "2.1.1.244", "2.1.1.25", "2.1.1.255", "2.1.1.26", "2.1.1.260", "2.1.1.261", "2.1.1.262", "2.1.1.263", "2.1.1.264", "2.1.1.265", "2.1.1.266", "2.1.1.267", "2.1.1.27", "2.1.1.271", "2.1.1.273", "2.1.1.274", "2.1.1.278", "2.1.1.28", "2.1.1.281", "2.1.1.29", "2.1.1.290", "2.1.1.293", "2.1.1.294", "2.1.1.295", "2.1.1.296", "2.1.1.297", "2.1.1.298", "2.1.1.308", "2.1.1.309", "2.1.1.31", "2.1.1.310", "2.1.1.317", "2.1.1.32", "2.1.1.325", "2.1.1.328", "2.1.1.33", "2.1.1.333", "2.1.1.337", "2.1.1.34", "2.1.1.35", "2.1.1.36", "2.1.1.37", "2.1.1.38", "2.1.1.39", "2.1.1.4", "2.1.1.40", "2.1.1.41", "2.1.1.42", "2.1.1.43", "2.1.1.44", "2.1.1.46", "2.1.1.47", "2.1.1.48", "2.1.1.49", "2.1.1.50", "2.1.1.51", "2.1.1.52", "2.1.1.53", "2.1.1.55", "2.1.1.56", "2.1.1.57", "2.1.1.59", "2.1.1.6", "2.1.1.60", "2.1.1.61", "2.1.1.62", "2.1.1.64", "2.1.1.65", "2.1.1.66", "2.1.1.67", "2.1.1.68", "2.1.1.69", "2.1.1.7", "2.1.1.70", "2.1.1.71", "2.1.1.72", "2.1.1.75", "2.1.1.76", "2.1.1.77", "2.1.1.78", "2.1.1.79", "2.1.1.8", "2.1.1.80", "2.1.1.82", "2.1.1.83", "2.1.1.84", "2.1.1.85", "2.1.1.87", "2.1.1.88", "2.1.1.89", "2.1.1.9", "2.1.1.91", "2.1.1.94", "2.1.1.95", "2.1.1.96", "2.1.1.97", "2.1.1.98", "2.1.1.99", "2.1.1.B109", "2.1.1.B74", "2.1.1.B75", "2.1.1.B76", "2.1.1.B84", "2.1.1.B85", "2.1.1.B93", "2.3.1.161", "2.3.1.184", "2.3.1.231", "2.4.99.17", "2.5.1.108", "2.5.1.120", "2.5.1.24", "2.5.1.25", "2.5.1.38", "2.5.1.4", "2.5.1.43", "2.5.1.63", "2.5.1.77", "2.6.1.62", "2.8.1.6", "2.8.1.8", "2.8.4.3", "2.8.4.4", "2.8.4.5", "3.1.21.3", "3.1.21.5", "3.3.1.2", "4.1.1.50", "4.1.99.14", "4.1.99.15", "4.1.99.17", "4.1.99.22", "4.2.1.22", "4.3.1.30", "4.3.99.3", "4.4.1.14", "4.7.1.1", "5.4.3.2", "5.4.99.58"]}], "Nicotinamide-adenine dinucleotide": [{"cofactors": ["0WD", "1DG", "3AA", "3CD", "6V0", "8ID", "A3D", "AP0", "CND", "DG1", "DN4", "EAD", "ENA", "LNC", "N01", "NA0", "NAD", "NAE", "NAI", "NAJ", "NAP", "NAQ", "NAX", "NBD", "NBP", "NDC", "NDE", "NDO", "NDP", "NHD", "NPW", "ODP", "P1H", "PAD", "SAD", "SAE", "SND", "TAD", "TAP", "TDT", "TXD", "TXE", "TXP", "ZID"], "EC": ["1.1.1.1", "1.1.1.10", "1.1.1.100", "1.1.1.101", "1.1.1.102", "1.1.1.103", "1.1.1.104", "1.1.1.105", "1.1.1.106", "1.1.1.107", "1.1.1.108", "1.1.1.11", "1.1.1.110", "1.1.1.111", "1.1.1.112", "1.1.1.113", "1.1.1.114", "1.1.1.115", "1.1.1.116", "1.1.1.117", "1.1.1.118", "1.1.1.119", "1.1.1.12", "1.1.1.120", "1.1.1.121", "1.1.1.122", "1.1.1.123", "1.1.1.124", "1.1.1.125", "1.1.1.126", "1.1.1.127", "1.1.1.128", "1.1.1.129", "1.1.1.13", "1.1.1.130", "1.1.1.131", "1.1.1.132", "1.1.1.133", "1.1.1.134", "1.1.1.135", "1.1.1.136", "1.1.1.137", "1.1.1.138", "1.1.1.14", "1.1.1.140", "1.1.1.141", "1.1.1.142", "1.1.1.143", "1.1.1.144", "1.1.1.145", "1.1.1.146", "1.1.1.147", "1.1.1.148", "1.1.1.149", "1.1.1.15", "1.1.1.150", "1.1.1.151", "1.1.1.152", "1.1.1.153", "1.1.1.154", "1.1.1.156", "1.1.1.157", "1.1.1.158", "1.1.1.159", "1.1.1.16", "1.1.1.160", "1.1.1.161", "1.1.1.162", "1.1.1.163", "1.1.1.164", "1.1.1.165", "1.1.1.166", "1.1.1.167", "1.1.1.168", "1.1.1.169", "1.1.1.17", "1.1.1.170", "1.1.1.172", "1.1.1.173", "1.1.1.174", "1.1.1.175", "1.1.1.176", "1.1.1.177", "1.1.1.178", "1.1.1.179", "1.1.1.18", "1.1.1.181", "1.1.1.183", "1.1.1.184", "1.1.1.185", "1.1.1.186", "1.1.1.187", "1.1.1.188", "1.1.1.189", "1.1.1.19", "1.1.1.190", "1.1.1.191", "1.1.1.192", "1.1.1.193", "1.1.1.194", "1.1.1.195", "1.1.1.196", "1.1.1.197", "1.1.1.198", "1.1.1.199", "1.1.1.2", "1.1.1.20", "1.1.1.200", "1.1.1.201", "1.1.1.202", "1.1.1.203", "1.1.1.205", "1.1.1.206", "1.1.1.207", "1.1.1.208", "1.1.1.209", "1.1.1.21", "1.1.1.210", "1.1.1.211", "1.1.1.212", "1.1.1.213", "1.1.1.214", "1.1.1.215", "1.1.1.216", "1.1.1.217", "1.1.1.218", "1.1.1.219", "1.1.1.22", "1.1.1.220", "1.1.1.221", "1.1.1.222", "1.1.1.223", "1.1.1.224", "1.1.1.225", "1.1.1.226", "1.1.1.227", "1.1.1.228", "1.1.1.229", "1.1.1.23", "1.1.1.230", "1.1.1.231", "1.1.1.232", "1.1.1.233", "1.1.1.234", "1.1.1.235", "1.1.1.236", "1.1.1.237", "1.1.1.238", "1.1.1.239", "1.1.1.24", "1.1.1.240", "1.1.1.241", "1.1.1.243", "1.1.1.244", "1.1.1.245", "1.1.1.246", "1.1.1.247", "1.1.1.248", "1.1.1.25", "1.1.1.250", "1.1.1.251", "1.1.1.252", "1.1.1.254", "1.1.1.255", "1.1.1.256", "1.1.1.257", "1.1.1.258", "1.1.1.259", "1.1.1.26", "1.1.1.260", "1.1.1.261", "1.1.1.262", "1.1.1.263", "1.1.1.264", "1.1.1.265", "1.1.1.266", "1.1.1.267", "1.1.1.268", "1.1.1.269", "1.1.1.27", "1.1.1.270", "1.1.1.271", "1.1.1.272", "1.1.1.273", "1.1.1.274", "1.1.1.275", "1.1.1.276", "1.1.1.277", "1.1.1.278", "1.1.1.279", "1.1.1.28", "1.1.1.280", "1.1.1.281", "1.1.1.282", "1.1.1.283", "1.1.1.284", "1.1.1.285", "1.1.1.286", "1.1.1.287", "1.1.1.288", "1.1.1.289", "1.1.1.29", "1.1.1.290", "1.1.1.291", "1.1.1.292", "1.1.1.294", "1.1.1.295", "1.1.1.296", "1.1.1.297", "1.1.1.298", "1.1.1.299", "1.1.1.3", "1.1.1.30", "1.1.1.300", "1.1.1.301", "1.1.1.302", "1.1.1.303", "1.1.1.304", "1.1.1.305", "1.1.1.306", "1.1.1.307", "1.1.1.308", "1.1.1.309", "1.1.1.31", "1.1.1.311", "1.1.1.312", "1.1.1.314", "1.1.1.315", "1.1.1.316", "1.1.1.32", "1.1.1.320", "1.1.1.321", "1.1.1.322", "1.1.1.323", "1.1.1.324", "1.1.1.326", "1.1.1.327", "1.1.1.328", "1.1.1.329", "1.1.1.33", "1.1.1.331", "1.1.1.332", "1.1.1.333", "1.1.1.334", "1.1.1.335", "1.1.1.336", "1.1.1.337", "1.1.1.34", "1.1.1.340", "1.1.1.342", "1.1.1.343", "1.1.1.344", "1.1.1.345", "1.1.1.346", "1.1.1.347", "1.1.1.348", "1.1.1.35", "1.1.1.350", "1.1.1.351", "1.1.1.352", "1.1.1.354", "1.1.1.356", "1.1.1.357", "1.1.1.359", "1.1.1.36", "1.1.1.360", "1.1.1.361", "1.1.1.363", "1.1.1.364", "1.1.1.365", "1.1.1.366", "1.1.1.367", "1.1.1.368", "1.1.1.369", "1.1.1.37", "1.1.1.370", "1.1.1.371", "1.1.1.373", "1.1.1.375", "1.1.1.376", "1.1.1.377", "1.1.1.378", "1.1.1.379", "1.1.1.38", "1.1.1.380", "1.1.1.381", "1.1.1.382", "1.1.1.383", "1.1.1.384", "1.1.1.386", "1.1.1.387", "1.1.1.388", "1.1.1.389", "1.1.1.39", "1.1.1.390", "1.1.1.391", "1.1.1.394", "1.1.1.395", "1.1.1.396", "1.1.1.398", "1.1.1.399", "1.1.1.4", "1.1.1.40", "1.1.1.400", "1.1.1.401", "1.1.1.402", "1.1.1.403", "1.1.1.404", "1.1.1.406", "1.1.1.41", "1.1.1.410", "1.1.1.411", "1.1.1.42", "1.1.1.43", "1.1.1.44", "1.1.1.45", "1.1.1.46", "1.1.1.47", "1.1.1.48", "1.1.1.49", "1.1.1.5", "1.1.1.50", "1.1.1.51", "1.1.1.52", "1.1.1.53", "1.1.1.54", "1.1.1.55", "1.1.1.56", "1.1.1.57", "1.1.1.58", "1.1.1.59", "1.1.1.6", "1.1.1.60", "1.1.1.61", "1.1.1.62", "1.1.1.63", "1.1.1.64", "1.1.1.65", "1.1.1.66", "1.1.1.67", "1.1.1.69", "1.1.1.7", "1.1.1.71", "1.1.1.72", "1.1.1.73", "1.1.1.75", "1.1.1.76", "1.1.1.77", "1.1.1.78", "1.1.1.79", "1.1.1.8", "1.1.1.80", "1.1.1.81", "1.1.1.82", "1.1.1.83", "1.1.1.84", "1.1.1.85", "1.1.1.86", "1.1.1.87", "1.1.1.88", "1.1.1.9", "1.1.1.90", "1.1.1.91", "1.1.1.92", "1.1.1.93", "1.1.1.94", "1.1.1.95", "1.1.1.96", "1.1.1.97", "1.1.1.98", "1.1.1.99", "1.1.1.B18", "1.1.1.B19", "1.1.1.B20", "1.1.1.B25", "1.1.1.B28", "1.1.1.B3", "1.1.1.B35", "1.1.1.B38", "1.1.1.B4", "1.1.1.B40", "1.1.1.B47", "1.1.1.B52", "1.1.1.B58", "1.1.1.B60", "1.1.1.B61", "1.1.3.16", "1.1.99.14", "1.1.99.2", "1.1.99.21", "1.1.99.24", "1.1.99.28", "1.1.99.36", "1.1.99.37", "1.1.99.7", "1.10.1.1", "1.10.5.1", "1.11.1.1", "1.11.1.2", "1.11.1.23", "1.12.1.2", "1.12.1.3", "1.12.1.4", "1.12.2.1", "1.12.7.2", "1.12.98.4", "1.12.99.6", "1.13.11.20", "1.13.11.29", "1.13.11.30", "1.13.11.79", "1.13.12.14", "1.13.12.17", "1.14.12.1", "1.14.12.10", "1.14.12.11", "1.14.12.12", "1.14.12.13", "1.14.12.14", "1.14.12.15", "1.14.12.16", "1.14.12.17", "1.14.12.18", "1.14.12.19", "1.14.12.20", "1.14.12.21", "1.14.12.22", "1.14.12.23", "1.14.12.24", "1.14.12.3", "1.14.12.4", "1.14.12.5", "1.14.12.7", "1.14.12.8", "1.14.12.9", "1.14.13.1", "1.14.13.10", "1.14.13.100", "1.14.13.101", "1.14.13.102", "1.14.13.103", "1.14.13.104", "1.14.13.105", "1.14.13.106", "1.14.13.107", "1.14.13.108", "1.14.13.109", "1.14.13.11", "1.14.13.110", "1.14.13.111", "1.14.13.112", "1.14.13.113", "1.14.13.114", "1.14.13.115", "1.14.13.12", "1.14.13.123", "1.14.13.127", "1.14.13.128", "1.14.13.129", "1.14.13.13", "1.14.13.130", "1.14.13.131", "1.14.13.135", "1.14.13.14", "1.14.13.141", "1.14.13.142", "1.14.13.15", "1.14.13.151", "1.14.13.158", "1.14.13.16", "1.14.13.161", "1.14.13.162", "1.14.13.163", "1.14.13.165", "1.14.13.166", "1.14.13.167", "1.14.13.17", "1.14.13.172", "1.14.13.178", "1.14.13.179", "1.14.13.18", "1.14.13.180", "1.14.13.182", "1.14.13.19", "1.14.13.196", "1.14.13.2", "1.14.13.20", "1.14.13.202", "1.14.13.205", "1.14.13.209", "1.14.13.21", "1.14.13.210", "1.14.13.211", "1.14.13.212", "1.14.13.215", "1.14.13.216", "1.14.13.217", "1.14.13.218", "1.14.13.22", "1.14.13.220", "1.14.13.222", "1.14.13.224", "1.14.13.225", "1.14.13.23", "1.14.13.230", "1.14.13.24", "1.14.13.25", "1.14.13.26", "1.14.13.27", "1.14.13.28", "1.14.13.29", "1.14.13.3", "1.14.13.30", "1.14.13.31", "1.14.13.32", "1.14.13.33", "1.14.13.34", "1.14.13.35", "1.14.13.36", "1.14.13.37", "1.14.13.38", "1.14.13.39", "1.14.13.4", "1.14.13.40", "1.14.13.41", "1.14.13.42", "1.14.13.43", "1.14.13.44", "1.14.13.46", "1.14.13.47", "1.14.13.48", "1.14.13.49", "1.14.13.5", "1.14.13.50", "1.14.13.51", "1.14.13.52", "1.14.13.53", "1.14.13.54", "1.14.13.55", "1.14.13.56", "1.14.13.57", "1.14.13.58", "1.14.13.59", "1.14.13.6", "1.14.13.60", "1.14.13.61", "1.14.13.62", "1.14.13.63", "1.14.13.64", "1.14.13.66", "1.14.13.67", "1.14.13.68", "1.14.13.69", "1.14.13.7", "1.14.13.70", "1.14.13.71", "1.14.13.72", "1.14.13.73", "1.14.13.74", "1.14.13.75", "1.14.13.76", "1.14.13.77", "1.14.13.78", "1.14.13.79", "1.14.13.8", "1.14.13.80", "1.14.13.81", "1.14.13.82", "1.14.13.83", "1.14.13.84", "1.14.13.85", "1.14.13.86", "1.14.13.87", "1.14.13.88", "1.14.13.89", "1.14.13.9", "1.14.13.90", "1.14.13.91", "1.14.13.92", "1.14.13.93", "1.14.13.94", "1.14.13.95", "1.14.13.96", "1.14.13.97", "1.14.13.98", "1.14.13.99", "1.14.13.B1", "1.14.13.B28", "1.14.14.1", "1.14.14.10", "1.14.14.16", "1.14.14.18", "1.14.14.20", "1.14.14.21", "1.14.14.22", "1.14.14.37", "1.14.14.47", "1.14.14.9", "1.14.15.1", "1.14.15.15", "1.14.15.21", "1.14.15.3", "1.14.15.4", "1.14.16.5", "1.14.18.2", "1.14.18.3", "1.14.18.4", "1.14.18.8", "1.14.19.1", "1.14.19.17", "1.14.19.20", "1.14.19.21", "1.14.19.22", "1.14.19.3", "1.14.19.30", "1.14.19.5", "1.14.19.7", "1.14.21.1", "1.14.21.2", "1.14.21.3", "1.14.21.4", "1.14.21.5", "1.14.21.6", "1.14.21.7", "1.14.99.14", "1.14.99.15", "1.14.99.19", "1.14.99.2", "1.14.99.20", "1.14.99.21", "1.14.99.22", "1.14.99.24", "1.14.99.26", "1.14.99.3", "1.14.99.31", "1.14.99.32", "1.14.99.34", "1.14.99.40", "1.14.99.9", "1.14.99.B1", "1.16.1.1", "1.16.1.10", "1.16.1.2", "1.16.1.3", "1.16.1.4", "1.16.1.5", "1.16.1.6", "1.16.1.7", "1.16.1.8", "1.16.1.9", "1.17.1.1", "1.17.1.2", "1.17.1.3", "1.17.1.4", "1.17.1.5", "1.17.1.8", "1.17.3.2", "1.17.7.4", "1.17.99.1", "1.18.1.1", "1.18.1.2", "1.18.1.3", "1.18.1.4", "1.18.1.5", "1.18.1.6", "1.18.1.7", "1.18.1.8", "1.19.1.1", "1.2.1.10", "1.2.1.11", "1.2.1.12", "1.2.1.13", "1.2.1.15", "1.2.1.16", "1.2.1.17", "1.2.1.18", "1.2.1.19", "1.2.1.2", "1.2.1.20", "1.2.1.21", "1.2.1.22", "1.2.1.23", "1.2.1.24", "1.2.1.25", "1.2.1.26", "1.2.1.27", "1.2.1.28", "1.2.1.29", "1.2.1.3", "1.2.1.30", "1.2.1.31", "1.2.1.32", "1.2.1.33", "1.2.1.36", "1.2.1.38", "1.2.1.39", "1.2.1.4", "1.2.1.40", "1.2.1.41", "1.2.1.42", "1.2.1.43", "1.2.1.44", "1.2.1.45", "1.2.1.46", "1.2.1.47", "1.2.1.48", "1.2.1.49", "1.2.1.5", "1.2.1.50", "1.2.1.51", "1.2.1.52", "1.2.1.53", "1.2.1.54", "1.2.1.57", "1.2.1.58", "1.2.1.59", "1.2.1.60", "1.2.1.61", "1.2.1.62", "1.2.1.63", "1.2.1.64", "1.2.1.65", "1.2.1.66", "1.2.1.67", "1.2.1.68", "1.2.1.69", "1.2.1.7", "1.2.1.70", "1.2.1.71", "1.2.1.72", "1.2.1.73", "1.2.1.74", "1.2.1.75", "1.2.1.76", "1.2.1.77", "1.2.1.78", "1.2.1.79", "1.2.1.8", "1.2.1.80", "1.2.1.81", "1.2.1.83", "1.2.1.85", "1.2.1.87", "1.2.1.88", "1.2.1.89", "1.2.1.9", "1.2.1.90", "1.2.1.91", "1.2.1.92", "1.2.1.93", "1.2.1.94", "1.2.1.96", "1.2.1.97", "1.2.1.98", "1.2.1.99", "1.2.1.B29", "1.2.1.B8", "1.2.3.1", "1.2.4.1", "1.2.4.2", "1.2.4.4", "1.2.5.3", "1.2.98.1", "1.20.1.1", "1.21.1.1", "1.21.1.2", "1.21.4.1", "1.21.4.3", "1.21.4.4", "1.22.1.1", "1.3.1.1", "1.3.1.10", "1.3.1.100", "1.3.1.101", "1.3.1.102", "1.3.1.105", "1.3.1.106", "1.3.1.107", "1.3.1.109", "1.3.1.11", "1.3.1.111", "1.3.1.112", "1.3.1.12", "1.3.1.13", "1.3.1.14", "1.3.1.15", "1.3.1.16", "1.3.1.17", "1.3.1.18", "1.3.1.19", "1.3.1.2", "1.3.1.20", "1.3.1.21", "1.3.1.22", "1.3.1.24", "1.3.1.25", "1.3.1.26", "1.3.1.27", "1.3.1.28", "1.3.1.29", "1.3.1.3", "1.3.1.30", "1.3.1.31", "1.3.1.32", "1.3.1.33", "1.3.1.34", "1.3.1.35", "1.3.1.36", "1.3.1.37", "1.3.1.38", "1.3.1.39", "1.3.1.4", "1.3.1.40", "1.3.1.41", "1.3.1.42", "1.3.1.43", "1.3.1.44", "1.3.1.45", "1.3.1.46", "1.3.1.47", "1.3.1.48", "1.3.1.49", "1.3.1.5", "1.3.1.51", "1.3.1.52", "1.3.1.53", "1.3.1.54", "1.3.1.56", "1.3.1.57", "1.3.1.58", "1.3.1.6", "1.3.1.60", "1.3.1.62", "1.3.1.63", "1.3.1.64", "1.3.1.65", "1.3.1.66", "1.3.1.67", "1.3.1.68", "1.3.1.69", "1.3.1.7", "1.3.1.70", "1.3.1.71", "1.3.1.72", "1.3.1.73", "1.3.1.74", "1.3.1.75", "1.3.1.76", "1.3.1.77", "1.3.1.78", "1.3.1.79", "1.3.1.8", "1.3.1.80", "1.3.1.81", "1.3.1.82", "1.3.1.83", "1.3.1.84", "1.3.1.85", "1.3.1.86", "1.3.1.9", "1.3.1.92", "1.3.1.95", "1.3.1.98", "1.3.1.99", "1.3.3.3", "1.3.3.9", "1.3.5.2", "1.3.7.12", "1.3.7.2", "1.3.7.3", "1.3.8.1", "1.3.98.3", "1.3.99.23", "1.3.99.5", "1.3.99.6", "1.4.1.1", "1.4.1.10", "1.4.1.11", "1.4.1.12", "1.4.1.13", "1.4.1.14", "1.4.1.15", "1.4.1.16", "1.4.1.17", "1.4.1.18", "1.4.1.19", "1.4.1.2", "1.4.1.20", "1.4.1.21", "1.4.1.23", "1.4.1.3", "1.4.1.4", "1.4.1.5", "1.4.1.7", "1.4.1.8", "1.4.1.9", "1.4.1.B2", "1.4.1.B4", "1.4.1.B5", "1.4.99.6", "1.5.1.1", "1.5.1.10", "1.5.1.11", "1.5.1.12", "1.5.1.15", "1.5.1.16", "1.5.1.17", "1.5.1.18", "1.5.1.19", "1.5.1.2", "1.5.1.20", "1.5.1.21", "1.5.1.22", "1.5.1.23", "1.5.1.24", "1.5.1.25", "1.5.1.26", "1.5.1.27", "1.5.1.28", "1.5.1.29", "1.5.1.3", "1.5.1.30", "1.5.1.31", "1.5.1.32", "1.5.1.33", "1.5.1.34", "1.5.1.36", "1.5.1.37", "1.5.1.38", "1.5.1.40", "1.5.1.42", "1.5.1.43", "1.5.1.46", "1.5.1.47", "1.5.1.49", "1.5.1.5", "1.5.1.51", "1.5.1.6", "1.5.1.7", "1.5.1.8", "1.5.1.9", "1.5.1.B1", "1.5.1.B5", "1.5.3.1", "1.5.99.5", "1.6.1.1", "1.6.1.2", "1.6.2.2", "1.6.2.4", "1.6.2.5", "1.6.2.6", "1.6.3.1", "1.6.3.2", "1.6.3.3", "1.6.3.4", "1.6.5.10", "1.6.5.11", "1.6.5.2", "1.6.5.3", "1.6.5.4", "1.6.5.5", "1.6.5.6", "1.6.5.7", "1.6.5.8", "1.6.5.9", "1.6.6.9", "1.6.99.1", "1.6.99.3", "1.6.99.5", "1.6.99.6", "1.7.1.1", "1.7.1.10", "1.7.1.11", "1.7.1.12", "1.7.1.13", "1.7.1.14", "1.7.1.15", "1.7.1.16", "1.7.1.2", "1.7.1.3", "1.7.1.4", "1.7.1.5", "1.7.1.6", "1.7.1.7", "1.7.1.9", "1.7.1.B1", "1.7.1.B4", "1.7.2.3", "1.7.2.5", "1.8.1.10", "1.8.1.11", "1.8.1.12", "1.8.1.13", "1.8.1.14", "1.8.1.15", "1.8.1.16", "1.8.1.17", "1.8.1.18", "1.8.1.2", "1.8.1.3", "1.8.1.4", "1.8.1.5", "1.8.1.6", "1.8.1.7", "1.8.1.8", "1.8.1.9", "1.8.1.B1", "1.8.4.13", "1.8.4.14", "2.1.1.147", "2.1.1.148", "2.1.1.201", "2.1.1.341", "2.1.1.74", "2.1.2.13", "2.3.1.111", "2.3.1.119", "2.3.1.161", "2.3.1.165", "2.3.1.170", "2.3.1.190", "2.3.1.201", "2.3.1.203", "2.3.1.85", "2.3.1.86", "2.3.1.94", "2.4.2.19", "2.4.2.30", "2.4.2.31", "2.4.2.36", "2.4.2.B12", "2.4.2.B14", "2.4.2.B15", "2.4.2.B16", "2.5.1.21", "2.5.1.44", "2.5.1.45", "2.5.1.46", "2.7.1.160", "2.7.1.19", "2.7.1.23", "2.7.1.86", "2.7.3.2", "2.7.8.11", "2.8.1.6", "3.1.2.1", "3.13.1.1", "3.2.1.122", "3.2.1.20", "3.2.1.22", "3.2.1.49", "3.2.1.86", "3.3.1.1", "3.5.1.10", "3.5.1.98", "3.5.4.9", "3.7.1.11", "4.1.1.101", "4.1.1.3", "4.1.1.35", "4.1.1.71", "4.1.1.73", "4.1.1.75", "4.1.1.B4", "4.1.2.32", "4.1.3.30", "4.1.3.39", "4.1.99.5", "4.2.1.10", "4.2.1.115", "4.2.1.135", "4.2.1.17", "4.2.1.45", "4.2.1.46", "4.2.1.47", "4.2.1.49", "4.2.1.76", "4.2.1.93", "4.2.3.124", "4.2.3.152", "4.2.3.154", "4.2.3.155", "4.2.3.4", "4.3.1.12", "4.3.1.22", "4.3.1.28", "4.4.1.17", "5.1.2.3", "5.1.3.10", "5.1.3.12", "5.1.3.13", "5.1.3.16", "5.1.3.18", "5.1.3.2", "5.1.3.20", "5.1.3.5", "5.1.3.6", "5.1.3.7", "5.2.1.6", "5.3.1.12", "5.3.3.1", "5.3.3.2", "5.4.99.5", "5.4.99.9", "5.5.1.3", "5.5.1.4", "6.2.1.13", "6.3.2.11", "6.5.1.1", "6.5.1.2"]}], "Dipyrromethane": [{"cofactors": ["18W", "29P", "DPM"], "EC": ["2.5.1.61"]}], "Thiamine diphosphate": [{"cofactors": ["1TP", "1U0", "2TP", "5GY", "8EF", "8EL", "8EO", "8FL", "8PA", "D7K", "EN0", "HTL", "M6T", "N1T", "N3T", "R1T", "S1T", "T5X", "T6F", "TD6", "TD7", "TD8", "TD9", "TDK", "TDL", "TDM", "TDP", "TDW", "THD", "THV", "THW", "THY", "TP8", "TPP", "TPU", "TPW", "TZD", "WWF"], "EC": ["1.2.1.51", "1.2.1.58", "1.2.2.2", "1.2.3.13", "1.2.3.3", "1.2.4.1", "1.2.4.2", "1.2.4.4", "1.2.5.1", "1.2.7.1", "1.2.7.10", "1.2.7.11", "1.2.7.3", "1.2.7.8", "2.2.1.1", "2.2.1.12", "2.2.1.3", "2.2.1.4", "2.2.1.5", "2.2.1.6", "2.2.1.7", "2.2.1.9", "2.3.1.12", "2.3.1.190", "2.3.3.15", "2.4.1.12", "2.5.1.66", "2.7.1.78", "2.8.1.6", "3.7.1.11", "3.7.1.2", "4.1.1.1", "4.1.1.43", "4.1.1.47", "4.1.1.50", "4.1.1.7", "4.1.1.71", "4.1.1.72", "4.1.1.74", "4.1.1.75", "4.1.1.79", "4.1.1.8", "4.1.1.82", "4.1.2.22", "4.1.2.35", "4.1.2.38", "4.1.2.9", "4.2.1.113", "4.2.1.3"]}], "Topaquinone": [{"cofactors": ["1TY", "2TY", "AGQ", "G27", "HCC", "P2Q", "P3Q", "TPQ", "TYQ", "TYY"], "EC": ["1.4.3.13", "1.4.3.21", "1.4.3.22"]}], "Tetrahydrofolic acid": [{"cofactors": ["1YJ", "C2F", "FFO", "FON", "FOZ", "THF", "THG", "THH"], "EC": ["1.13.11.52", "1.14.13.165", "1.14.14.47", "1.14.16.1", "1.14.16.2", "1.14.16.4", "1.14.16.5", "1.14.18.1", "1.5.1.6", "1.5.3.1", "1.5.8.3", "2.1.1.13", "2.1.1.148", "2.1.1.19", "2.1.1.269", "2.1.1.341", "2.1.1.45", "2.1.2.1", "2.1.2.10", "2.1.2.11", "2.1.2.13", "2.1.2.2", "2.1.2.3", "2.1.2.5", "2.1.2.8", "2.1.2.9", "3.5.3.8", "4.1.99.3"]}], "Molybdopterin": [{"cofactors": ["2MD", "MCN", "MGD", "MSS", "MTE", "MTQ", "MTV", "PCD", "XAX"], "EC": ["1.1.1.288", "1.1.5.6", "1.1.99.33", "1.12.98.4", "1.17.1.4", "1.17.1.5", "1.17.2.1", "1.17.3.2", "1.17.3.3", "1.17.5.1", "1.17.99.2", "1.2.1.2", "1.2.2.4", "1.2.3.1", "1.2.3.8", "1.2.5.3", "1.2.7.4", "1.2.7.5", "1.2.7.6", "1.2.7.7", "1.2.99.6", "1.2.99.8", "1.2.99.9", "1.20.9.1", "1.20.98.1", "1.3.7.9", "1.3.99.16", "1.3.99.17", "1.5.99.14", "1.5.99.4", "1.7.2.3", "1.7.5.1", "1.7.7.2", "1.8.2.1", "1.8.2.4", "1.8.3.1", "1.8.5.3", "1.9.6.1", "1.97.1.1", "1.97.1.9", "4.2.1.112"]}], "Biopterin": [{"cofactors": ["4AB", "7AP", "BHS", "BIO", "H2B", "H4B", "HBI", "WSD"], "EC": ["1.14.13.12", "1.14.13.165", "1.14.14.47", "1.14.16.1", "1.14.16.2", "1.14.16.3", "1.14.16.4", "1.14.16.5", "1.14.16.6", "1.3.1.6"]}], "Flavin Mononucleotide": [{"cofactors": ["4LS", "4LU", "FMN", "FNR", "FNS", "IRF", "RBF"], "EC": ["1.1.1.27", "1.1.1.284", "1.1.1.328", "1.1.1.404", "1.1.2.3", "1.1.2.4", "1.1.3.15", "1.1.3.46", "1.1.3.6", "1.1.5.3", "1.1.99.18", "1.1.99.27", "1.1.99.31", "1.1.99.B9", "1.10.3.16", "1.10.5.1", "1.11.1.23", "1.12.1.2", "1.12.1.4", "1.12.99.6", "1.13.11.32", "1.13.11.52", "1.13.12.16", "1.13.12.4", "1.14.12.12", "1.14.12.13", "1.14.12.7", "1.14.12.8", "1.14.12.9", "1.14.13.104", "1.14.13.108", "1.14.13.109", "1.14.13.131", "1.14.13.156", "1.14.13.162", "1.14.13.165", "1.14.13.187", "1.14.13.215", "1.14.13.22", "1.14.13.28", "1.14.13.39", "1.14.13.58", "1.14.13.76", "1.14.13.B1", "1.14.14.1", "1.14.14.10", "1.14.14.11", "1.14.14.12", "1.14.14.13", "1.14.14.20", "1.14.14.21", "1.14.14.22", "1.14.14.28", "1.14.14.3", "1.14.14.30", "1.14.14.33", "1.14.14.34", "1.14.14.35", "1.14.14.47", "1.14.14.5", "1.14.14.6", "1.14.14.9", "1.14.15.1", "1.14.15.3", "1.14.19.1", "1.14.19.7", "1.14.21.1", "1.14.21.2", "1.14.99.15", "1.14.99.21", "1.14.99.24", "1.14.99.46", "1.16.1.10", "1.16.1.3", "1.16.1.4", "1.16.1.5", "1.16.1.6", "1.16.1.8", "1.16.8.1", "1.17.1.4", "1.17.1.8", "1.17.4.1", "1.17.99.3", "1.18.1.1", "1.18.1.2", "1.18.1.4", "1.18.1.8", "1.2.1.2", "1.2.1.93", "1.2.7.1", "1.21.1.1", "1.22.1.1", "1.3.1.10", "1.3.1.100", "1.3.1.108", "1.3.1.14", "1.3.1.15", "1.3.1.2", "1.3.1.31", "1.3.1.34", "1.3.1.42", "1.3.1.44", "1.3.1.6", "1.3.1.8", "1.3.1.9", "1.3.1.95", "1.3.3.1", "1.3.3.12", "1.3.3.7", "1.3.5.2", "1.3.5.3", "1.3.7.15", "1.3.8.1", "1.3.98.1", "1.3.99.24", "1.3.99.33", "1.4.1.13", "1.4.1.14", "1.4.3.1", "1.4.3.2", "1.4.3.5", "1.4.7.1", "1.5.1.20", "1.5.1.29", "1.5.1.30", "1.5.1.34", "1.5.1.36", "1.5.1.38", "1.5.1.41", "1.5.1.46", "1.5.1.B1", "1.5.3.1", "1.5.3.22", "1.5.5.2", "1.5.8.1", "1.5.8.2", "1.5.8.3", "1.5.99.1", "1.5.99.15", "1.5.99.4", "1.5.99.B2", "1.6.2.4", "1.6.3.1", "1.6.5.10", "1.6.5.11", "1.6.5.2", "1.6.5.3", "1.6.5.4", "1.6.5.5", "1.6.5.6", "1.6.5.7", "1.6.5.8", "1.6.6.9", "1.6.99.1", "1.6.99.3", "1.7.1.0", "1.7.1.16", "1.7.1.2", "1.7.1.3", "1.7.1.4", "1.7.1.6", "1.7.1.B1", "1.7.2.3", "1.7.3.1", "1.7.3.5", "1.8.1.2", "1.8.1.4", "1.8.2.3", "1.8.7.1", "1.8.99.2", "2.1.1.148", "2.1.1.21", "2.2.1.6", "2.3.1.86", "2.5.1.129", "2.5.1.15", "2.7.1.161", "2.7.1.26", "2.7.1.42", "2.7.11.1", "2.7.13.3", "2.7.7.2", "3.13.1.3", "3.6.1.18", "4.1.1.36", "4.1.1.74", "4.1.1.98", "4.1.2.32", "4.1.99.3", "4.2.3.5", "4.3.3.7", "4.99.1.7", "5.2.1.13", "5.3.3.2", "5.4.99.9", "5.5.1.18", "6.3.2.5"]}], "Ubiquinone": [{"cofactors": ["4YP", "AT5", "UQ1", "UQ2", "UQ5", "UQ6"], "EC": ["1.1.5.3", "1.1.5.4", "1.1.5.5", "1.1.99.1", "1.1.99.20", "1.1.99.22", "1.1.99.6", "1.10.2.2", "1.10.3.10", "1.17.5.2", "1.2.5.1", "1.2.5.3", "1.3.1.22", "1.3.5.1", "1.3.5.2", "1.3.5.5", "1.3.98.1", "1.4.5.1", "1.5.5.1", "1.6.5.3", "1.6.5.8", "1.8.1.4", "5.3.4.1"]}], "Flavin adenine dinucleotide": [{"cofactors": ["6FA", "FA8", "FAA", "FAB", "FAD", "FAE", "FAO", "FAS", "FCG", "FDA", "FED", "FSH", "P5F", "RFL", "SFD"], "EC": ["1.1.1.158", "1.1.1.215", "1.1.1.28", "1.1.1.289", "1.1.1.47", "1.1.1.94", "1.1.1.B58", "1.1.2.3", "1.1.2.4", "1.1.3.10", "1.1.3.12", "1.1.3.13", "1.1.3.15", "1.1.3.17", "1.1.3.19", "1.1.3.20", "1.1.3.21", "1.1.3.23", "1.1.3.28", "1.1.3.3", "1.1.3.37", "1.1.3.38", "1.1.3.39", "1.1.3.4", "1.1.3.41", "1.1.3.42", "1.1.3.43", "1.1.3.44", "1.1.3.45", "1.1.3.47", "1.1.3.49", "1.1.3.5", "1.1.3.6", "1.1.3.7", "1.1.3.8", "1.1.3.9", "1.1.5.10", "1.1.5.12", "1.1.5.3", "1.1.5.4", "1.1.5.9", "1.1.98.3", "1.1.98.4", "1.1.99.1", "1.1.99.10", "1.1.99.11", "1.1.99.13", "1.1.99.16", "1.1.99.18", "1.1.99.2", "1.1.99.20", "1.1.99.21", "1.1.99.27", "1.1.99.29", "1.1.99.3", "1.1.99.37", "1.1.99.39", "1.1.99.4", "1.1.99.40", "1.1.99.6", "1.1.99.9", "1.1.99.B1", "1.1.99.B3", "1.10.3.4", "1.10.5.1", "1.10.99.2", "1.11.1.1", "1.11.1.17", "1.11.1.23", "1.12.1.2", "1.12.1.3", "1.12.1.4", "1.12.1.5", "1.12.7.2", "1.12.98.1", "1.12.98.4", "1.12.99.6", "1.13.11.17", "1.13.11.20", "1.13.11.32", "1.13.12.1", "1.13.12.16", "1.13.12.2", "1.13.12.3", "1.13.12.4", "1.13.12.9", "1.13.99.1", "1.14.11.B1", "1.14.11.B2", "1.14.12.10", "1.14.12.11", "1.14.12.12", "1.14.12.13", "1.14.12.14", "1.14.12.15", "1.14.12.17", "1.14.12.18", "1.14.12.21", "1.14.12.22", "1.14.12.24", "1.14.12.3", "1.14.12.4", "1.14.12.5", "1.14.12.7", "1.14.12.8", "1.14.13.1", "1.14.13.10", "1.14.13.101", "1.14.13.104", "1.14.13.105", "1.14.13.107", "1.14.13.108", "1.14.13.109", "1.14.13.111", "1.14.13.113", "1.14.13.114", "1.14.13.12", "1.14.13.123", "1.14.13.127", "1.14.13.129", "1.14.13.130", "1.14.13.135", "1.14.13.148", "1.14.13.149", "1.14.13.152", "1.14.13.16", "1.14.13.160", "1.14.13.162", "1.14.13.163", "1.14.13.165", "1.14.13.166", "1.14.13.167", "1.14.13.168", "1.14.13.170", "1.14.13.171", "1.14.13.18", "1.14.13.180", "1.14.13.187", "1.14.13.19", "1.14.13.195", "1.14.13.196", "1.14.13.2", "1.14.13.20", "1.14.13.200", "1.14.13.208", "1.14.13.210", "1.14.13.211", "1.14.13.212", "1.14.13.215", "1.14.13.216", "1.14.13.217", "1.14.13.218", "1.14.13.22", "1.14.13.222", "1.14.13.223", "1.14.13.224", "1.14.13.225", "1.14.13.23", "1.14.13.231", "1.14.13.232", "1.14.13.233", "1.14.13.236", "1.14.13.24", "1.14.13.25", "1.14.13.27", "1.14.13.28", "1.14.13.29", "1.14.13.3", "1.14.13.31", "1.14.13.32", "1.14.13.33", "1.14.13.35", "1.14.13.4", "1.14.13.40", "1.14.13.44", "1.14.13.5", "1.14.13.50", "1.14.13.54", "1.14.13.58", "1.14.13.59", "1.14.13.6", "1.14.13.61", "1.14.13.63", "1.14.13.64", "1.14.13.69", "1.14.13.7", "1.14.13.76", "1.14.13.78", "1.14.13.8", "1.14.13.83", "1.14.13.84", "1.14.13.9", "1.14.13.90", "1.14.13.92", "1.14.13.B30", "1.14.14.1", "1.14.14.11", "1.14.14.12", "1.14.14.15", "1.14.14.17", "1.14.14.20", "1.14.14.21", "1.14.14.27", "1.14.14.3", "1.14.14.30", "1.14.14.47", "1.14.14.5", "1.14.14.6", "1.14.14.7", "1.14.14.8", "1.14.14.9", "1.14.15.1", "1.14.15.21", "1.14.15.3", "1.14.17.3", "1.14.19.1", "1.14.19.49", "1.14.19.7", "1.14.19.9", "1.14.19.B7", "1.14.21.1", "1.14.21.2", "1.14.21.6", "1.14.99.21", "1.14.99.24", "1.14.99.34", "1.14.99.46", "1.14.99.7", "1.16.1.1", "1.16.1.3", "1.16.1.4", "1.16.1.5", "1.16.1.6", "1.16.1.7", "1.16.1.8", "1.16.1.9", "1.16.8.1", "1.17.1.4", "1.17.1.5", "1.17.3.2", "1.17.3.3", "1.17.7.2", "1.17.7.4", "1.17.8.1", "1.17.99.1", "1.17.99.3", "1.17.99.5", "1.18.1.1", "1.18.1.2", "1.18.1.3", "1.18.1.4", "1.18.1.5", "1.18.1.6", "1.18.1.7", "1.18.1.8", "1.19.1.1", "1.2.1.36", "1.2.1.51", "1.2.1.58", "1.2.1.88", "1.2.2.2", "1.2.2.4", "1.2.3.1", "1.2.3.13", "1.2.3.3", "1.2.3.4", "1.2.3.6", "1.2.3.7", "1.2.4.2", "1.2.4.4", "1.2.5.1", "1.2.5.3", "1.2.7.1", "1.2.7.4", "1.2.99.2", "1.2.99.6", "1.2.99.8", "1.2.99.9", "1.21.1.1", "1.21.3.3", "1.21.3.7", "1.21.3.8", "1.21.98.2", "1.21.99.1", "1.22.1.1", "1.3.1.10", "1.3.1.101", "1.3.1.108", "1.3.1.109", "1.3.1.110", "1.3.1.14", "1.3.1.15", "1.3.1.2", "1.3.1.27", "1.3.1.31", "1.3.1.34", "1.3.1.42", "1.3.1.44", "1.3.1.52", "1.3.1.6", "1.3.1.72", "1.3.1.86", "1.3.1.88", "1.3.1.91", "1.3.1.95", "1.3.1.98", "1.3.2.3", "1.3.3.1", "1.3.3.12", "1.3.3.15", "1.3.3.4", "1.3.3.6", "1.3.3.7", "1.3.3.8", "1.3.5.1", "1.3.5.2", "1.3.5.4", "1.3.5.5", "1.3.5.6", "1.3.7.11", "1.3.7.13", "1.3.7.8", "1.3.7.9", "1.3.8.1", "1.3.8.10", "1.3.8.11", "1.3.8.12", "1.3.8.13", "1.3.8.2", "1.3.8.3", "1.3.8.4", "1.3.8.5", "1.3.8.6", "1.3.8.7", "1.3.8.8", "1.3.8.9", "1.3.98.1", "1.3.99.1", "1.3.99.10", "1.3.99.12", "1.3.99.13", "1.3.99.17", "1.3.99.18", "1.3.99.19", "1.3.99.2", "1.3.99.21", "1.3.99.23", "1.3.99.24", "1.3.99.28", "1.3.99.3", "1.3.99.31", "1.3.99.32", "1.3.99.33", "1.3.99.37", "1.3.99.38", "1.3.99.4", "1.3.99.5", "1.3.99.7", "1.3.99.8", "1.3.99.B12", "1.3.99.B2", "1.4.1.13", "1.4.1.14", "1.4.1.5", "1.4.3.1", "1.4.3.10", "1.4.3.11", "1.4.3.12", "1.4.3.14", "1.4.3.15", "1.4.3.16", "1.4.3.19", "1.4.3.2", "1.4.3.21", "1.4.3.22", "1.4.3.23", "1.4.3.24", "1.4.3.25", "1.4.3.3", "1.4.3.4", "1.4.3.5", "1.4.3.7", "1.4.5.1", "1.4.7.1", "1.4.99.1", "1.4.99.5", "1.4.99.6", "1.4.99.B3", "1.5.1.15", "1.5.1.20", "1.5.1.29", "1.5.1.30", "1.5.1.34", "1.5.1.B1", "1.5.3.1", "1.5.3.10", "1.5.3.11", "1.5.3.12", "1.5.3.13", "1.5.3.14", "1.5.3.15", "1.5.3.16", "1.5.3.17", "1.5.3.18", "1.5.3.19", "1.5.3.2", "1.5.3.21", "1.5.3.4", "1.5.3.5", "1.5.3.6", "1.5.3.7", "1.5.5.1", "1.5.5.2", "1.5.7.1", "1.5.7.2", "1.5.8.1", "1.5.8.2", "1.5.8.3", "1.5.8.4", "1.5.99.1", "1.5.99.12", "1.5.99.13", "1.5.99.14", "1.5.99.15", "1.5.99.2", "1.5.99.3", "1.5.99.4", "1.5.99.5", "1.5.99.6", "1.5.99.8", "1.5.99.B2", "1.6.1.1", "1.6.1.2", "1.6.1.3", "1.6.1.4", "1.6.2.2", "1.6.2.4", "1.6.2.5", "1.6.2.6", "1.6.3.1", "1.6.3.2", "1.6.3.3", "1.6.3.4", "1.6.3.5", "1.6.5.10", "1.6.5.11", "1.6.5.12", "1.6.5.2", "1.6.5.3", "1.6.5.4", "1.6.5.6", "1.6.5.7", "1.6.5.8", "1.6.5.9", "1.6.6.9", "1.6.99.1", "1.6.99.3", "1.6.99.6", "1.7.1.1", "1.7.1.10", "1.7.1.15", "1.7.1.2", "1.7.1.3", "1.7.1.4", "1.7.1.5", "1.7.1.6", "1.7.2.1", "1.7.2.3", "1.7.3.1", "1.7.3.5", "1.7.99.1", "1.8.1.10", "1.8.1.11", "1.8.1.12", "1.8.1.13", "1.8.1.14", "1.8.1.15", "1.8.1.16", "1.8.1.18", "1.8.1.19", "1.8.1.2", "1.8.1.4", "1.8.1.5", "1.8.1.7", "1.8.1.8", "1.8.1.9", "1.8.1.B1", "1.8.1.B4", "1.8.2.1", "1.8.2.3", "1.8.3.2", "1.8.3.3", "1.8.3.5", "1.8.3.6", "1.8.4.10", "1.8.5.1", "1.8.5.4", "1.8.98.1", "1.8.99.2", "2.1.1.13", "2.1.1.148", "2.1.1.190", "2.1.1.229", "2.1.1.61", "2.1.1.74", "2.1.1.90", "2.2.1.6", "2.3.1.168", "2.5.1.26", "2.5.1.94", "2.7.1.161", "2.7.1.42", "2.7.11.1", "2.7.13.3", "2.7.7.2", "2.8.1.5", "2.8.1.6", "3.1.3.43", "3.13.1.3", "3.13.1.4", "3.6.1.18", "3.7.1.11", "4.1.1.36", "4.1.1.47", "4.1.1.70", "4.1.2.10", "4.1.2.47", "4.1.99.11", "4.1.99.13", "4.1.99.3", "4.2.1.120", "4.2.1.53", "4.2.1.54", "4.2.1.B25", "4.2.3.5", "4.3.3.7", "4.6.1.15", "4.99.1.2", "5.1.1.1", "5.2.1.13", "5.3.1.12", "5.3.3.13", "5.3.3.2", "5.3.3.3", "5.3.3.B2", "5.3.99.8", "5.4.3.3", "5.4.99.9", "5.5.1.18", "5.5.1.19", "5.5.1.20"]}], "Heme": [{"cofactors": ["6HE", "7HE", "CCH", "COH", "DDH", "DHE", "FDE", "FMI", "HAS", "HDD", "HDE", "HEA", "HEB", "HEC", "HEM", "HIF", "ISW", "MH0", "MNH", "MNR", "PP9", "SH0", "SRM", "ZEM", "ZNH"], "EC": ["1.1.1.215", "1.1.1.28", "1.1.2.2", "1.1.2.3", "1.1.2.4", "1.1.2.6", "1.1.2.7", "1.1.2.8", "1.1.2.9", "1.1.2.B5", "1.1.3.39", "1.1.3.B4", "1.1.5.11", "1.1.5.5", "1.1.5.6", "1.1.9.1", "1.1.98.1", "1.1.99.11", "1.1.99.12", "1.1.99.14", "1.1.99.18", "1.1.99.20", "1.1.99.21", "1.1.99.3", "1.1.99.4", "1.1.99.6", "1.1.99.B7", "1.10.2.2", "1.10.3.1", "1.10.3.10", "1.10.3.11", "1.10.3.12", "1.10.3.13", "1.10.3.14", "1.10.3.3", "1.10.3.9", "1.10.9.1", "1.11.1.10", "1.11.1.11", "1.11.1.13", "1.11.1.14", "1.11.1.16", "1.11.1.19", "1.11.1.21", "1.11.1.5", "1.11.1.6", "1.11.1.7", "1.11.1.8", "1.11.1.B2", "1.11.1.B7", "1.11.2.1", "1.11.2.2", "1.11.2.3", "1.11.2.4", "1.11.2.5", "1.12.2.1", "1.12.5.1", "1.12.99.6", "1.13.11.11", "1.13.11.26", "1.13.11.44", "1.13.11.49", "1.13.11.50", "1.13.11.52", "1.13.11.60", "1.13.11.9", "1.13.12.16", "1.13.12.17", "1.13.99.3", "1.14.11.9", "1.14.12.17", "1.14.13.1", "1.14.13.100", "1.14.13.103", "1.14.13.104", "1.14.13.106", "1.14.13.108", "1.14.13.109", "1.14.13.11", "1.14.13.110", "1.14.13.112", "1.14.13.115", "1.14.13.119", "1.14.13.120", "1.14.13.129", "1.14.13.13", "1.14.13.137", "1.14.13.138", "1.14.13.139", "1.14.13.140", "1.14.13.141", "1.14.13.142", "1.14.13.146", "1.14.13.147", "1.14.13.15", "1.14.13.150", "1.14.13.151", "1.14.13.152", "1.14.13.154", "1.14.13.156", "1.14.13.161", "1.14.13.17", "1.14.13.177", "1.14.13.181", "1.14.13.184", "1.14.13.188", "1.14.13.197", "1.14.13.198", "1.14.13.199", "1.14.13.2", "1.14.13.202", "1.14.13.203", "1.14.13.21", "1.14.13.221", "1.14.13.25", "1.14.13.28", "1.14.13.30", "1.14.13.37", "1.14.13.39", "1.14.13.4", "1.14.13.41", "1.14.13.42", "1.14.13.47", "1.14.13.48", "1.14.13.49", "1.14.13.5", "1.14.13.52", "1.14.13.53", "1.14.13.55", "1.14.13.56", "1.14.13.57", "1.14.13.6", "1.14.13.60", "1.14.13.67", "1.14.13.68", "1.14.13.7", "1.14.13.70", "1.14.13.71", "1.14.13.72", "1.14.13.73", "1.14.13.74", "1.14.13.75", "1.14.13.76", "1.14.13.77", "1.14.13.79", "1.14.13.80", "1.14.13.81", "1.14.13.85", "1.14.13.86", "1.14.13.87", "1.14.13.88", "1.14.13.89", "1.14.13.91", "1.14.13.93", "1.14.13.94", "1.14.13.95", "1.14.13.96", "1.14.13.97", "1.14.13.98", "1.14.13.99", "1.14.13.B14", "1.14.13.B21", "1.14.13.B3", "1.14.14.1", "1.14.14.14", "1.14.14.16", "1.14.14.17", "1.14.14.18", "1.14.14.19", "1.14.14.23", "1.14.14.24", "1.14.14.25", "1.14.14.29", "1.14.14.32", "1.14.14.36", "1.14.14.40", "1.14.14.41", "1.14.14.42", "1.14.14.44", "1.14.14.45", "1.14.14.47", "1.14.15.1", "1.14.15.10", "1.14.15.13", "1.14.15.15", "1.14.15.16", "1.14.15.18", "1.14.15.19", "1.14.15.20", "1.14.15.3", "1.14.15.4", "1.14.15.5", "1.14.15.6", "1.14.15.8", "1.14.15.9", "1.14.18.1", "1.14.18.6", "1.14.18.7", "1.14.18.8", "1.14.19.1", "1.14.19.12", "1.14.19.16", "1.14.19.17", "1.14.19.18", "1.14.19.19", "1.14.19.20", "1.14.19.22", "1.14.19.25", "1.14.19.26", "1.14.19.29", "1.14.19.3", "1.14.19.30", "1.14.19.31", "1.14.19.33", "1.14.19.34", "1.14.19.38", "1.14.19.4", "1.14.19.44", "1.14.19.47", "1.14.19.51", "1.14.19.6", "1.14.21.1", "1.14.21.10", "1.14.21.11", "1.14.21.2", "1.14.21.3", "1.14.21.4", "1.14.21.5", "1.14.21.7", "1.14.21.9", "1.14.99.1", "1.14.99.10", "1.14.99.14", "1.14.99.15", "1.14.99.19", "1.14.99.22", "1.14.99.24", "1.14.99.28", "1.14.99.37", "1.14.99.39", "1.14.99.4", "1.14.99.45", "1.14.99.49", "1.14.99.57", "1.14.99.9", "1.14.99.B1", "1.15.1.2", "1.16.5.1", "1.16.9.1", "1.17.1.4", "1.17.2.1", "1.17.2.2", "1.17.99.1", "1.17.99.2", "1.18.1.8", "1.2.1.70", "1.2.2.1", "1.2.3.7", "1.2.5.2", "1.20.2.1", "1.20.99.1", "1.21.98.2", "1.3.1.6", "1.3.2.3", "1.3.3.10", "1.3.3.9", "1.3.5.1", "1.3.5.4", "1.3.98.3", "1.3.99.1", "1.4.9.1", "1.4.9.2", "1.5.1.20", "1.5.3.1", "1.5.99.3", "1.5.99.4", "1.5.99.5", "1.5.99.6", "1.6.3.1", "1.6.5.10", "1.7.1.1", "1.7.1.14", "1.7.1.15", "1.7.1.2", "1.7.1.3", "1.7.1.4", "1.7.2.1", "1.7.2.2", "1.7.2.3", "1.7.2.5", "1.7.2.6", "1.7.2.7", "1.7.2.8", "1.7.3.4", "1.7.3.6", "1.7.5.1", "1.7.5.2", "1.7.6.1", "1.7.7.1", "1.7.7.2", "1.7.7.4", "1.7.99.7", "1.8.1.2", "1.8.1.3", "1.8.2.1", "1.8.2.2", "1.8.2.3", "1.8.2.4", "1.8.2.5", "1.8.3.1", "1.8.7.1", "1.8.98.1", "1.8.98.3", "1.8.99.2", "1.8.99.3", "1.8.99.5", "1.8.99.B2", "1.9.3.1", "1.9.6.1", "1.9.98.1", "1.97.1.1", "1.97.1.9", "2.1.1.304", "2.7.13.3", "2.7.7.65", "3.1.4.52", "4.1.1.B11", "4.2.1.121", "4.2.1.22", "4.2.1.92", "4.2.1.B9", "4.3.1.26", "4.6.1.2", "4.99.1.1", "4.99.1.3", "4.99.1.5", "4.99.1.7", "5.3.99.3", "5.3.99.4", "5.3.99.5", "5.3.99.6", "5.4.4.5", "5.4.4.6", "6.6.1.2"]}], "Ascorbic acid": [{"cofactors": ["ASC"], "EC": ["1.10.99.3", "1.11.1.11", "1.13.11.5", "1.14.11.1", "1.14.11.10", "1.14.11.11", "1.14.11.13", "1.14.11.14", "1.14.11.15", "1.14.11.17", "1.14.11.18", "1.14.11.19", "1.14.11.2", "1.14.11.20", "1.14.11.22", "1.14.11.23", "1.14.11.3", "1.14.11.4", "1.14.11.6", "1.14.11.7", "1.14.11.8", "1.14.11.9", "1.14.13.38", "1.14.14.18", "1.14.15.4", "1.14.17.1", "1.14.17.3", "1.14.17.4", "1.14.18.3", "1.14.19.1", "1.14.99.21", "1.16.5.1", "1.2.2.4", "2.4.1.202", "4.1.2.32", "5.4.99.3"]}], "Adenosylcobalamin": [{"cofactors": ["B12", "CNC", "COB", "COY"], "EC": ["1.1.1.259", "1.13.12.7", "1.14.19.30", "1.17.4.1", "1.17.4.2", "1.2.1.10", "1.2.1.17", "1.2.1.25", "1.2.1.27", "1.2.1.44", "1.2.1.52", "1.2.4.4", "1.2.7.1", "1.2.7.7", "1.21.1.2", "1.21.98.3", "1.21.99.5", "1.3.1.25", "1.3.7.1", "1.8.1.18", "2.1.1.13", "2.1.1.258", "2.1.1.308", "2.1.1.326", "2.1.3.1", "2.3.1.107", "2.3.1.148", "2.3.1.180", "2.3.1.26", "2.3.3.10", "2.3.3.5", "3.4.11.18", "4.1.1.1", "4.2.1.28", "4.2.1.30", "4.3.1.2", "4.3.1.3", "4.3.1.7", "5.4.3.3", "5.4.3.4", "5.4.3.5", "5.4.3.7", "5.4.99.1", "5.4.99.13", "5.4.99.2", "5.4.99.4", "5.4.99.63", "5.4.99.64"]}], "Biotin": [{"cofactors": ["BTI", "BTN", "BYT", "DTB", "Y7Y"], "EC": ["1.14.16.1", "2.1.3.1", "4.1.1.3", "4.1.1.41", "4.1.1.70", "4.1.1.74", "4.1.1.89", "6.3.4.15", "6.3.4.6", "6.4.1.1", "6.4.1.2", "6.4.1.3", "6.4.1.4", "6.4.1.5", "6.4.1.7"]}], "Coenzyme M": [{"cofactors": ["COM"], "EC": ["1.8.1.B5", "2.8.4.1"]}], "Factor F430": [{"cofactors": ["F43", "M43"], "EC": ["2.8.4.1"]}], "Lipoic acid": [{"cofactors": ["LPA", "LPB"], "EC": ["1.1.1.5", "1.17.4.2", "1.2.4.1 ", "1.2.4.2", "1.2.4.4", "1.4.4.2", "1.8.1.4", "2.3.1.61"]}], "MIO": [{"cofactors": ["MDO"], "EC": ["4.3.1.23", "4.3.1.24", "4.3.1.25", "5.4.3.6"]}], "Pyridoxal 5'-phosphate": [{"cofactors": ["MPL", "NOP", "NPL", "PDP", "PLP", "PLR", "PMP", "PXP", "PZP", "UAH"], "EC": ["1.17.1.1", "1.4.1.12", "1.4.3.21", "1.4.3.22", "1.4.4.2", "2.1.2.1", "2.1.2.10", "2.1.2.5", "2.1.2.7", "2.2.1.8", "2.3.1.201", "2.3.1.263", "2.3.1.29", "2.3.1.30", "2.3.1.37", "2.3.1.47", "2.3.1.50", "2.4.1.1", "2.4.1.8", "2.5.1.113", "2.5.1.140", "2.5.1.47", "2.5.1.48", "2.5.1.49", "2.5.1.51", "2.5.1.52", "2.5.1.53", "2.5.1.65", "2.5.1.73", "2.5.1.76", "2.6.1.1", "2.6.1.100", "2.6.1.101", "2.6.1.102", "2.6.1.103", "2.6.1.104", "2.6.1.105", "2.6.1.106", "2.6.1.107", "2.6.1.108", "2.6.1.109", "2.6.1.11", "2.6.1.110", "2.6.1.111", "2.6.1.112", "2.6.1.113", "2.6.1.12", "2.6.1.13", "2.6.1.14", "2.6.1.15", "2.6.1.17", "2.6.1.18", "2.6.1.19", "2.6.1.2", "2.6.1.21", "2.6.1.22", "2.6.1.24", "2.6.1.26", "2.6.1.27", "2.6.1.28", "2.6.1.29", "2.6.1.3", "2.6.1.30", "2.6.1.33", "2.6.1.34", "2.6.1.35", "2.6.1.36", "2.6.1.37", "2.6.1.38", "2.6.1.39", "2.6.1.4", "2.6.1.40", "2.6.1.41", "2.6.1.42", "2.6.1.43", "2.6.1.44", "2.6.1.45", "2.6.1.46", "2.6.1.47", "2.6.1.48", "2.6.1.49", "2.6.1.5", "2.6.1.50", "2.6.1.51", "2.6.1.52", "2.6.1.55", "2.6.1.56", "2.6.1.57", "2.6.1.58", "2.6.1.59", "2.6.1.6", "2.6.1.60", "2.6.1.62", "2.6.1.63", "2.6.1.64", "2.6.1.65", "2.6.1.66", "2.6.1.67", "2.6.1.7", "2.6.1.71", "2.6.1.72", "2.6.1.75", "2.6.1.76", "2.6.1.77", "2.6.1.78", "2.6.1.79", "2.6.1.8", "2.6.1.80", "2.6.1.81", "2.6.1.82", "2.6.1.83", "2.6.1.84", "2.6.1.87", "2.6.1.88", "2.6.1.89", "2.6.1.9", "2.6.1.90", "2.6.1.92", "2.6.1.96", "2.6.1.98", "2.6.1.99", "2.6.1.B16", "2.6.1.B17", "2.6.1.B3", "2.6.1.B6", "2.6.99.3", "2.8.1.4", "2.8.1.7", "2.8.1.9", "2.9.1.1", "2.9.1.2", "3.5.1.61", "3.5.1.9", "3.5.99.7", "3.7.1.3", "4.1.1.11", "4.1.1.12", "4.1.1.14", "4.1.1.15", "4.1.1.16", "4.1.1.17", "4.1.1.18", "4.1.1.19", "4.1.1.20", "4.1.1.22", "4.1.1.24", "4.1.1.25", "4.1.1.28", "4.1.1.29", "4.1.1.50", "4.1.1.53", "4.1.1.57", "4.1.1.64", "4.1.1.65", "4.1.1.81", "4.1.1.86", "4.1.1.95", "4.1.1.96", "4.1.2.26", "4.1.2.27", "4.1.2.42", "4.1.2.48", "4.1.2.49", "4.1.2.5", "4.1.3.38", "4.1.3.41", "4.1.99.1", "4.1.99.2", "4.2.1.122", "4.2.1.144", "4.2.1.145", "4.2.1.164", "4.2.1.168", "4.2.1.20", "4.2.1.22", "4.2.1.50", "4.2.3.1", "4.2.3.134", "4.2.3.2", "4.3.1.13", "4.3.1.15", "4.3.1.16", "4.3.1.17", "4.3.1.18", "4.3.1.19", "4.3.1.20", "4.3.1.27", "4.3.1.9", "4.4.1.1", "4.4.1.10", "4.4.1.11", "4.4.1.13", "4.4.1.14", "4.4.1.15", "4.4.1.16", "4.4.1.2", "4.4.1.25", "4.4.1.28", "4.4.1.35", "4.4.1.4", "4.4.1.6", "4.4.1.8", "4.4.1.9", "4.5.1.2", "4.5.1.5", "4.99.1.6", "5.1.1.1", "5.1.1.10", "5.1.1.12", "5.1.1.13", "5.1.1.15", "5.1.1.17", "5.1.1.18", "5.1.1.2", "5.1.1.21", "5.1.1.3", "5.1.1.5", "5.1.1.6", "5.1.1.9", "5.4.3.2", "5.4.3.3", "5.4.3.4", "5.4.3.5", "5.4.3.8", "5.4.3.9"]}], "Menaquinone": [{"cofactors": ["MQ7"], "EC": ["1.1.5.4", "1.1.5.6", "1.17.99.1", "1.21.99.5", "1.3.5.4", "1.7.5.1", "1.8.5.5", "3.4.21.21", "3.4.21.6", "3.4.21.69", "4.1.1.90"]}], "Phosphopantetheine": [{"cofactors": ["PNS"], "EC": ["1.1.1.100", "1.3.1.10", "2.3.1.244", "2.3.1.38", "2.3.1.39", "2.3.1.41", "2.3.1.85", "2.3.1.86", "2.7.8.7", "3.1.2.14", "4.2.1.61", "5.1.1.11", "6.2.1.10"]}], "Pyrroloquinoline Quinone": [{"cofactors": ["PQQ"], "EC": ["1.1.2.7", "1.1.5.2", "1.1.99.1", "1.1.99.20", "1.1.99.22", "1.1.99.23", "1.1.99.8", "1.2.99.3", "1.4.99.3"]}], "Coenzyme B": [{"cofactors": ["SHT", "TP7", "TPZ", "TXZ", "XP8", "XP9"], "EC": ["2.8.4.1"]}], "NA": [{"cofactors": [null], "EC": [null]}]}
diff --git a/src/plinder/data/utils/annotations/static_files/dates.csv b/src/plinder/data/utils/annotations/static_files/dates.csv
deleted file mode 100644
index 8c0a2e88e..000000000
--- a/src/plinder/data/utils/annotations/static_files/dates.csv
+++ /dev/null
@@ -1,143801 +0,0 @@
-entry_pdb_id,entry_release_date,entry_deposition_date
-3grt,1997-08-12,1997-02-12
-1grx,1994-01-31,1993-10-01
-6grf,2018-12-19,2018-06-11
-3grj,2009-04-14,2009-03-25
-8grn,2023-06-14,2022-09-02
-4grc,2013-09-04,2012-08-24
-4grr,2013-09-25,2012-08-26
-5grq,2017-09-27,2016-08-12
-2grt,1997-08-12,1997-02-12
-8grd,2022-11-30,2022-09-01
-7grp,2024-02-14,2023-11-14
-3gr2,2009-04-14,2009-03-24
-4grs,2013-02-06,2012-08-26
-6grp,2018-07-11,2018-06-12
-4grw,2014-02-19,2012-08-27
-3grd,2009-04-07,2009-03-25
-2grj,2006-05-23,2006-04-24
-5gr5,2017-08-16,2016-08-08
-1gro,1996-04-03,1995-10-12
-5gr3,2017-08-16,2016-08-08
-7gro,2024-02-14,2023-11-14
-1grm,1994-01-31,1993-10-18
-2grz,2006-05-09,2006-04-25
-4grb,2013-08-28,2012-08-24
-7grs,2024-02-14,2023-11-14
-8grw,2023-09-06,2022-09-02
-8gr7,2023-09-06,2022-09-01
-6grq,2019-02-06,2018-06-12
-6gra,2019-05-15,2018-06-10
-8gr9,2023-04-26,2022-09-01
-8grv,2022-10-26,2022-09-02
-7grk,2024-02-14,2023-11-14
-3grr,2010-03-31,2009-03-26
-4grq,2013-10-02,2012-08-26
-4grv,2012-10-17,2012-08-27
-5grn,2017-08-16,2016-08-11
-3gru,2010-03-31,2009-03-26
-1grn,1999-12-22,1998-07-30
-5gro,2017-02-15,2016-08-12
-4gra,2013-01-16,2012-08-24
-6gri,2019-01-30,2018-06-11
-3grv,2010-03-31,2009-03-26
-3gr7,2010-03-31,2009-03-25
-4gr5,2012-11-28,2012-08-24
-1grf,1994-01-31,1992-12-15
-5gre,2017-02-15,2016-08-11
-1grp,1996-04-03,1995-10-12
-7gre,2024-02-14,2023-11-14
-5grl,2017-02-15,2016-08-11
-5grr,2017-01-04,2016-08-12
-7grx,2024-02-14,2023-11-14
-2gr1,2007-05-22,2006-04-22
-5gr2,2017-08-16,2016-08-08
-5grt,1997-08-12,1997-02-12
-3grw,2009-05-05,2009-03-26
-6grb,2018-09-26,2018-06-11
-3gra,2009-04-14,2009-03-25
-3gr9,2009-06-16,2009-03-25
-6grw,2018-08-15,2018-06-12
-7grm,2024-02-14,2023-11-14
-5grf,2017-02-15,2016-08-11
-1grh,1994-01-31,1992-12-15
-6gru,2018-06-27,2018-06-12
-1gr2,1998-12-09,1998-09-17
-2gr3,2007-05-22,2006-04-22
-3grb,2010-04-07,2009-03-25
-2grm,2007-04-03,2006-04-24
-5grb,2017-05-17,2016-08-09
-6gr0,2018-08-15,2018-06-08
-2grh,2006-05-09,2006-04-24
-1gr3,2002-02-14,2001-12-12
-6gr5,2018-10-03,2018-06-08
-6grh,2019-01-30,2018-06-11
-3gr6,2009-10-20,2009-03-25
-8gri,2023-05-31,2022-09-01
-6gr8,2019-05-15,2018-06-10
-4grk,2012-09-19,2012-08-25
-1grq,2002-01-04,2001-12-15
-6gre,2018-12-26,2018-06-11
-5grg,2017-08-09,2016-08-11
-2gr9,2006-10-03,2006-04-23
-5gr1,2017-08-16,2016-08-08
-1gre,1994-01-31,1992-12-15
-6grn,2018-10-10,2018-06-11
-6grg,2019-01-30,2018-06-11
-1gr7,2002-05-16,2001-12-14
-1grv,2002-12-13,2001-12-17
-7grh,2024-02-14,2023-11-14
-7grn,2024-02-14,2023-11-14
-8grz,2023-09-06,2022-09-03
-6gr4,2018-10-03,2018-06-08
-3grf,2009-06-30,2009-03-25
-3gri,2009-05-19,2009-03-25
-7grq,2024-02-14,2023-11-14
-1grg,1994-01-31,1992-12-15
-3gr8,2010-03-31,2009-03-25
-1gra,1994-01-31,1992-12-15
-8grj,2023-09-06,2022-09-01
-3grg,2010-04-07,2009-03-25
-4grn,2013-09-25,2012-08-26
-8gry,2023-07-19,2022-09-03
-7grz,2024-02-14,2023-11-14
-2grl,2007-04-03,2006-04-24
-1grt,1997-06-16,1996-12-17
-6grc,2018-09-26,2018-06-11
-2gr6,2007-04-17,2006-04-22
-7grv,2024-02-14,2023-11-14
-7gri,2024-02-14,2023-11-14
-6grv,2018-09-19,2018-06-12
-2grx,2006-06-13,2006-04-25
-7grr,2024-02-14,2023-11-14
-7grt,2024-02-14,2023-11-14
-6grj,2019-07-03,2018-06-11
-5grk,2017-05-03,2016-08-11
-7grw,2024-02-14,2023-11-14
-7grj,2024-02-14,2023-11-14
-2gry,2006-05-09,2006-04-25
-4grt,1997-08-12,1997-02-12
-3gr3,2009-04-07,2009-03-24
-8grq,2023-04-12,2022-09-02
-7grl,2024-02-14,2023-11-14
-4gr1,1991-10-15,1990-03-26
-3grx,1999-03-30,1998-08-17
-6gr9,2019-05-15,2018-06-10
-2gru,2007-05-08,2006-04-25
-1gr1,2002-10-24,2001-12-12
-5gri,2017-02-15,2016-08-11
-6gr7,2018-07-11,2018-06-09
-3gry,2010-03-31,2009-03-26
-8gra,2023-07-12,2022-09-01
-8grm,2023-04-12,2022-09-02
-6gro,2018-06-20,2018-06-12
-2grf,2006-05-09,2006-04-24
-2gr0,2007-05-22,2006-04-22
-5grh,2017-02-15,2016-08-11
-8gru,2022-11-30,2022-09-02
-6gr2,2019-06-19,2018-06-08
-6gr3,2018-10-03,2018-06-08
-1grr,2002-01-04,2001-12-15
-8grt,2023-09-06,2022-09-02
-7gry,2024-02-14,2023-11-14
-4gr0,2013-02-06,2012-08-24
-1grb,1994-01-31,1992-12-15
-4grx,2012-12-19,2012-08-27
-7gru,2024-02-14,2023-11-14
-5gr6,2017-08-16,2016-08-08
-6grs,2019-02-06,2018-06-12
-7grg,2024-02-14,2023-11-14
-4grf,2012-10-10,2012-08-24
-2gr2,2007-05-22,2006-04-22
-5gr0,2017-08-16,2016-08-08
-4gri,2012-09-05,2012-08-24
-1gr0,2002-03-12,2001-12-10
-4grh,2012-12-26,2012-08-24
-6grt,2019-02-06,2018-06-12
-5gr7,2017-06-07,2016-08-08
-2gra,2006-10-03,2006-04-23
-5grm,2017-10-25,2016-08-11
-5gr8,2016-12-14,2016-08-08
-5gr9,2016-11-23,2016-08-08
-5gr4,2017-08-16,2016-08-08
-7grf,2024-02-14,2023-11-14
-4gr9,2013-07-10,2012-08-24
-3grs,1988-04-16,1988-02-05
-4gr8,2013-02-06,2012-08-24
-4grj,2013-08-07,2012-08-24
-4grl,2013-11-06,2012-08-25
-4gr3,2013-02-06,2012-08-24
-6gr1,2018-10-03,2018-06-08
-8gr6,2023-06-21,2022-09-01
-6grr,2018-09-05,2018-06-12
-6grd,2018-09-26,2018-06-11
-7cjb,2021-07-14,2020-07-09
-7cjz,2020-11-18,2020-07-15
-6cju,2018-08-01,2018-02-26
-4cjc,2014-02-05,2013-12-19
-4cj3,2014-01-08,2013-12-19
-6cjc,2019-03-06,2018-02-26
-8cjk,2024-01-10,2023-02-13
-7cj9,2021-04-21,2020-07-09
-4cju,2014-01-22,2013-12-23
-3cjb,2008-03-25,2008-03-12
-6cj0,2018-05-09,2018-02-25
-6cjx,2019-03-06,2018-02-27
-4cjs,2014-01-08,2013-12-23
-1cj0,1999-05-06,1999-04-20
-2cjm,2006-04-24,2006-04-05
-5cj3,2015-07-22,2015-07-13
-5cje,2016-07-20,2015-07-14
-1cjp,1997-10-15,1996-10-03
-4cj0,2014-05-21,2013-12-18
-5cjn,2016-08-10,2015-07-14
-7cjj,2021-04-28,2020-07-11
-5cjo,2016-07-20,2015-07-14
-3cjc,2008-03-25,2008-03-12
-7cjl,2021-07-14,2020-07-11
-7cja,2021-05-12,2020-07-09
-5cjs,2015-09-09,2015-07-15
-1cja,1999-06-18,1999-04-08
-3cjp,2008-03-25,2008-03-13
-4cjx,2015-02-04,2013-12-23
-3cj4,2008-04-15,2008-03-12
-6cjp,2019-01-30,2018-02-26
-8cj2,2023-07-05,2023-02-11
-3cjj,2009-03-24,2008-03-13
-1cju,1999-08-31,1999-04-16
-5cjh,2015-09-02,2015-07-14
-5cjv,2015-09-09,2015-07-15
-8cjm,2024-01-10,2023-02-13
-2cjb,2006-06-26,2006-03-30
-1cj8,1999-04-30,1999-04-22
-7cj4,2021-04-21,2020-07-09
-4cjv,2014-01-22,2013-12-23
-2cje,2007-04-17,2006-03-31
-7cj8,2021-04-21,2020-07-09
-6cj9,2018-03-07,2018-02-26
-1cjc,1999-04-30,1999-04-12
-3cj3,2008-04-15,2008-03-12
-1cjf,1999-07-07,1999-04-13
-3cjr,2008-05-20,2008-03-13
-6cja,2018-03-21,2018-02-26
-8cj1,2023-07-05,2023-02-11
-2cju,2006-06-20,2006-04-09
-1cjy,2000-04-20,1999-04-20
-5cjz,2016-10-12,2015-07-15
-2cjs,2006-06-07,2006-04-06
-4cj6,2014-01-08,2013-12-19
-3cj0,2008-04-15,2008-03-12
-6cjw,2018-05-09,2018-02-27
-6cj3,2018-08-01,2018-02-26
-3cj8,2008-03-25,2008-03-12
-8cju,2024-01-24,2023-02-13
-4cje,2014-01-08,2013-12-19
-3cjt,2008-05-20,2008-03-13
-4cjg,2014-05-21,2013-12-20
-7cj5,2021-04-28,2020-07-09
-2cjy,2006-06-27,2006-04-09
-8cj9,2024-02-21,2023-02-12
-3cjq,2008-05-20,2008-03-13
-2cj3,2007-04-03,2006-03-27
-6cjh,2018-05-09,2018-02-26
-7cjk,2021-07-14,2020-07-11
-6cjg,2018-05-23,2018-02-26
-2cj9,2006-06-26,2006-03-29
-1cjx,2000-04-26,1999-04-20
-2cjd,2006-08-14,2006-03-31
-2cjw,2006-11-09,2006-04-09
-8cjd,2023-06-14,2023-02-13
-5cjm,2016-08-10,2015-07-14
-1cj4,1999-04-30,1999-04-21
-6cjy,2018-05-09,2018-02-27
-2cjg,2006-08-14,2006-04-01
-2cjl,2006-10-04,2006-04-04
-3cj7,2008-04-29,2008-03-12
-4cj8,2014-02-05,2013-12-19
-6cjt,2018-08-01,2018-02-26
-8cjo,2024-01-10,2023-02-13
-1cjb,1999-08-18,1999-04-08
-8cjb,2024-02-21,2023-02-13
-2cj2,2006-06-12,2006-03-26
-7cjm,2020-09-02,2020-07-11
-8cja,2024-02-21,2023-02-13
-5cjf,2015-11-04,2015-07-14
-8cjf,2023-06-14,2023-02-13
-3cjf,2008-10-07,2008-03-12
-7cjf,2020-11-11,2020-07-10
-7cj2,2021-07-14,2020-07-09
-1cjk,1999-08-31,1999-04-16
-8cjy,2023-10-25,2023-02-13
-6cje,2018-05-09,2018-02-26
-7cjq,2020-08-26,2020-07-12
-8cjv,2023-07-12,2023-02-13
-4cj4,2014-01-08,2013-12-19
-2cjz,2006-05-16,2006-04-10
-5cjx,2015-09-23,2015-07-15
-8cjg,2023-06-14,2023-02-13
-4cjk,2014-01-08,2013-12-21
-2cji,2006-05-17,2006-04-03
-3cjk,2008-12-30,2008-03-13
-4cjw,2014-01-22,2013-12-23
-2cjk,2006-06-28,2006-04-04
-1cj2,1999-04-30,1999-04-21
-8cjl,2024-01-10,2023-02-13
-7cjt,2021-04-14,2020-07-13
-8cj3,2023-07-05,2023-02-11
-3cji,2008-12-16,2008-03-13
-6cjs,2019-01-30,2018-02-26
-5cjw,2015-09-09,2015-07-15
-5cj6,2016-01-06,2015-07-14
-8cj7,2023-10-18,2023-02-12
-7cj7,2021-04-21,2020-07-09
-4cjp,2014-01-08,2013-12-22
-1cj1,1999-12-22,1999-04-21
-8cj0,2023-04-19,2023-02-11
-4cjq,2014-01-08,2013-12-22
-7cje,2021-05-05,2020-07-10
-5cju,2015-09-09,2015-07-15
-3cj9,2008-04-29,2008-03-12
-1cjv,1999-08-31,1999-04-19
-3cj5,2008-04-15,2008-03-12
-4cj5,2014-01-08,2013-12-19
-6cj4,2018-08-01,2018-02-26
-5cj2,2015-09-09,2015-07-13
-4cjn,2015-02-11,2013-12-21
-1cjt,1999-08-31,1999-04-16
-7cj3,2020-11-25,2020-07-09
-4cj7,2014-01-22,2013-12-19
-1cjw,1999-05-06,1999-04-19
-3cjy,2008-04-01,2008-03-14
-3cj2,2008-04-15,2008-03-12
-7cj6,2021-04-21,2020-07-09
-6cj5,2018-05-09,2018-02-26
-2cjc,2006-10-11,2006-03-31
-7cjs,2021-11-03,2020-07-13
-6cj6,2019-03-06,2018-02-26
-7cjg,2021-05-05,2020-07-10
-2cjx,2006-06-27,2006-04-09
-3cjo,2008-07-01,2008-03-13
-7cjo,2021-07-14,2020-07-12
-4cjl,2014-01-08,2013-12-21
-6cj1,2018-08-29,2018-02-25
-8cjc,2024-02-21,2023-02-13
-1cj6,1999-04-30,1999-04-22
-2cjf,2007-04-10,2006-03-31
-4cj1,2014-05-21,2013-12-18
-7cjd,2020-09-02,2020-07-10
-6cjv,2018-08-08,2018-02-26
-6cjj,2019-01-30,2018-02-26
-3cja,2008-04-29,2008-03-12
-4cjf,2014-01-08,2013-12-20
-8cji,2024-01-10,2023-02-13
-6cj2,2019-03-06,2018-02-26
-4cjt,2014-01-08,2013-12-23
-4cjr,2014-01-08,2013-12-22
-5cjp,2016-08-10,2015-07-14
-8cjj,2024-01-10,2023-02-13
-2cja,2006-06-26,2006-03-30
-5cj7,2016-02-24,2015-07-14
-4cjo,2014-05-21,2013-12-21
-2cjp,2006-06-07,2006-04-05
-5cjt,2015-09-09,2015-07-15
-8cjn,2024-01-10,2023-02-13
-3cjg,2008-10-07,2008-03-12
-2cj0,2006-06-12,2006-03-26
-6cjr,2019-01-30,2018-02-26
-1cj7,1999-04-30,1999-04-22
-1cj3,1999-04-30,1999-04-21
-7cji,2021-04-28,2020-07-11
-6cjl,2019-01-30,2018-02-26
-1cj9,1999-04-30,1999-04-22
-2cj1,2006-06-12,2006-03-26
-4cjb,2014-02-05,2013-12-19
-8cje,2023-06-14,2023-02-13
-6cjf,2018-05-23,2018-02-26
-2cjh,2006-08-14,2006-04-03
-2j38,2006-09-27,2006-08-18
-4j3t,2014-02-12,2013-02-06
-5j3r,2016-10-19,2016-03-31
-8j32,2024-04-17,2023-04-16
-1j3p,2004-02-24,2003-02-11
-4j3l,2013-06-26,2013-02-05
-6j3c,2019-08-21,2019-01-04
-8j30,2023-08-16,2023-04-15
-4j3p,2013-11-27,2013-02-06
-2j3e,2007-03-27,2006-08-21
-8j3o,2023-09-20,2023-04-17
-1j3s,2004-05-18,2003-02-12
-5j33,2016-05-18,2016-03-30
-1j3q,2004-02-24,2003-02-11
-6j3y,2019-08-07,2019-01-07
-4j3u,2014-02-12,2013-02-06
-5j3h,2016-06-15,2016-03-30
-5j34,2016-05-11,2016-03-30
-4j34,2013-04-10,2013-02-05
-6j3p,2019-05-01,2019-01-05
-2j3j,2006-10-05,2006-08-21
-8j3a,2024-04-17,2023-04-16
-4j3v,2014-02-12,2013-02-06
-1j3r,2004-02-24,2003-02-11
-2j3f,2007-01-23,2006-08-21
-8j3y,2024-04-24,2023-04-18
-5j3u,2016-04-20,2016-03-31
-6j3z,2019-08-07,2019-01-07
-1j36,2003-07-20,2003-01-20
-5j30,2016-10-12,2016-03-30
-4j3b,2013-08-07,2013-02-05
-8j3r,2023-09-27,2023-04-18
-6j38,2019-06-12,2019-01-04
-1j39,2003-08-19,2003-01-21
-4j3d,2013-04-03,2013-02-05
-4j3q,2013-11-27,2013-02-06
-8j3t,2023-11-08,2023-04-18
-2j3m,2006-10-11,2006-08-22
-6j3n,2020-01-15,2019-01-05
-2j3z,2006-10-11,2006-08-23
-5j37,2016-05-04,2016-03-30
-2j3l,2006-10-11,2006-08-22
-8j3p,2023-09-20,2023-04-17
-1j3n,2003-03-11,2003-02-10
-5j3b,2016-05-04,2016-03-30
-5j3t,2016-05-18,2016-03-31
-6j3x,2020-01-15,2019-01-06
-4j3i,2014-01-15,2013-02-05
-5j3j,2017-04-05,2016-03-31
-1j38,2003-07-20,2003-01-20
-5j3c,2016-10-12,2016-03-30
-1j3y,2003-07-22,2003-02-21
-8j37,2024-04-17,2023-04-16
-5j3w,2016-06-22,2016-03-31
-2j3n,2007-07-03,2006-08-22
-5j35,2017-04-12,2016-03-30
-6j3h,2019-05-15,2019-01-04
-2j3k,2006-10-05,2006-08-22
-4j3s,2014-02-12,2013-02-06
-4j3r,2013-11-27,2013-02-06
-2j3q,2007-09-04,2006-08-23
-1j3i,2003-05-06,2003-02-03
-2j32,2006-11-08,2006-08-17
-2j33,2006-11-08,2006-08-17
-5j3z,2016-05-04,2016-03-31
-6j3d,2019-11-13,2019-01-04
-8j3b,2024-04-17,2023-04-16
-8j3c,2024-04-17,2023-04-16
-5j3s,2016-05-04,2016-03-31
-6j35,2019-09-18,2019-01-09
-6j39,2019-06-12,2019-01-04
-4j35,2013-07-24,2013-02-05
-1j3z,2003-07-22,2003-02-21
-1j3b,2003-02-11,2003-01-21
-1j3j,2003-05-06,2003-02-03
-5j3p,2016-05-04,2016-03-31
-2j3g,2007-01-23,2006-08-21
-1j3f,2004-05-18,2003-01-24
-4j3f,2014-07-23,2013-02-05
-2j3d,2008-06-24,2006-08-20
-1j3k,2003-05-06,2003-02-03
-1j3g,2003-02-18,2003-01-31
-5j3o,2017-04-12,2016-03-31
-1j32,2003-02-04,2003-01-17
-8j35,2024-04-17,2023-04-16
-8j34,2024-04-17,2023-04-16
-2j31,2006-11-08,2006-08-17
-4j3g,2013-03-13,2013-02-05
-4j3y,2013-09-25,2013-02-06
-4j33,2013-04-10,2013-02-05
-6j3b,2019-08-21,2019-01-04
-1j30,2003-10-14,2003-01-16
-2j3o,2007-01-23,2006-08-22
-6j3g,2019-05-15,2019-01-04
-1j34,2003-07-08,2003-01-20
-6j3o,2019-05-01,2019-01-05
-4j36,2013-04-10,2013-02-05
-8j39,2024-04-17,2023-04-16
-4j3e,2013-04-24,2013-02-05
-6j33,2019-09-18,2019-01-09
-4j31,2013-04-10,2013-02-05
-8j3s,2023-11-08,2023-04-18
-2j3i,2006-10-05,2006-08-21
-5j3x,2016-09-21,2016-03-31
-4j3m,2013-06-26,2013-02-06
-6j31,2020-01-15,2019-01-03
-4j3w,2014-02-12,2013-02-06
-1j37,2003-07-20,2003-01-20
-6j3f,2019-02-27,2019-01-04
-4j3n,2013-10-02,2013-02-06
-8j38,2024-04-17,2023-04-16
-2j30,2006-11-08,2006-08-17
-1j3w,2004-04-13,2003-02-18
-6j34,2019-09-18,2019-01-09
-2j3u,2007-01-23,2006-08-23
-5j3l,2017-03-29,2016-03-31
-8j3w,2023-05-24,2023-04-18
-1j3l,2004-02-17,2003-02-04
-2j34,2006-09-27,2006-08-18
-8j3x,2024-04-24,2023-04-18
-5j32,2016-05-11,2016-03-30
-4j3x,2014-02-12,2013-02-06
-1j35,2003-07-08,2003-01-20
-4j3j,2014-02-05,2013-02-05
-8j36,2024-05-01,2023-04-16
-8j3z,2023-05-24,2023-04-18
-4j3h,2013-04-10,2013-02-05
-8dat,2022-11-30,2022-06-14
-4dai,2012-03-28,2012-01-12
-5dac,2016-03-02,2015-08-19
-5daf,2016-08-10,2015-08-19
-6da1,2019-01-16,2018-05-01
-6da8,2019-04-03,2018-05-01
-6da7,2018-10-03,2018-05-01
-4da8,2012-09-26,2012-01-12
-3daa,1998-04-29,1998-01-20
-3dap,1998-04-08,1997-12-29
-6dat,2019-01-16,2018-05-02
-6daf,2018-10-17,2018-05-01
-8daz,2022-09-28,2022-06-14
-1dan,1997-09-04,1997-03-05
-7dak,2021-09-22,2020-10-16
-1dag,1996-06-20,1995-05-08
-4dau,2012-06-13,2012-01-13
-5da9,2016-03-02,2015-08-19
-7daz,2021-02-10,2020-10-18
-4daj,2012-02-22,2012-01-12
-2das,2006-06-14,2005-12-14
-4daf,2012-04-04,2012-01-12
-2daa,1998-03-18,1997-10-27
-6dak,2018-09-05,2018-05-01
-6dar,2018-09-05,2018-05-01
-4dar,2012-09-26,2012-01-13
-4dan,2012-09-26,2012-01-13
-6das,2018-07-18,2018-05-01
-5dat,2016-08-31,2015-08-20
-6dad,2018-10-17,2018-05-01
-7dat,2021-11-03,2020-10-18
-8dar,2022-11-30,2022-06-14
-3daz,2009-03-03,2008-05-30
-8da0,2023-06-14,2022-06-12
-7dal,2021-09-22,2020-10-16
-7daf,2021-03-24,2020-10-16
-2dan,2006-06-14,2005-12-14
-6dax,2018-05-16,2018-05-02
-4dag,2012-02-29,2012-01-12
-4daw,2012-03-14,2012-01-13
-4dae,2012-09-26,2012-01-12
-1dae,1996-06-20,1995-05-08
-5dan,2016-09-21,2015-08-20
-2dab,1998-06-03,1997-11-30
-3dam,2008-09-23,2008-05-29
-6da0,2018-05-09,2018-05-01
-4dap,2013-08-14,2012-01-13
-5dau,2015-09-02,2015-08-20
-5das,2016-08-24,2015-08-20
-3dau,2009-04-14,2008-05-30
-3dat,2009-04-14,2008-05-30
-1dar,1996-07-11,1996-02-15
-4dab,2012-09-26,2012-01-12
-5dal,2016-12-07,2015-08-20
-5dah,2015-10-21,2015-08-19
-8dav,2022-11-30,2022-06-14
-3da2,2008-07-15,2008-05-28
-8dak,2022-06-22,2022-06-13
-7day,2021-02-10,2020-10-18
-3dak,2009-02-10,2008-05-29
-8daf,2023-06-28,2022-06-13
-7dae,2021-03-24,2020-10-16
-1dah,1996-06-20,1995-05-08
-5daa,1998-12-14,1998-12-13
-6dam,2018-09-05,2018-05-01
-3daj,2008-07-08,2008-05-29
-5dar,2016-09-14,2015-08-20
-7dau,2021-11-03,2020-10-18
-1daa,1995-09-15,1995-06-09
-3da8,2009-05-12,2008-05-28
-4da0,2012-09-26,2012-01-12
-3das,2009-06-02,2008-05-30
-3daf,2008-12-09,2008-05-29
-2dar,2006-12-12,2005-12-14
-4da1,2012-02-08,2012-01-12
-6dav,2018-05-16,2018-05-02
-3dan,2008-09-23,2008-05-29
-5dad,2016-08-10,2015-08-19
-8dan,2023-12-20,2022-06-13
-5dak,2016-12-07,2015-08-20
-3da6,2009-01-06,2008-05-28
-1dap,1997-07-07,1996-07-08
-8dai,2023-06-21,2022-06-13
-6da2,2019-04-03,2018-05-01
-6da5,2019-04-03,2018-05-01
-6dai,2018-09-05,2018-05-01
-4da5,2013-04-17,2012-01-12
-7dan,2021-06-02,2020-10-16
-5dax,2015-11-25,2015-08-20
-1daj,1997-12-24,1997-07-29
-8daw,2022-11-30,2022-06-14
-6da3,2019-04-03,2018-05-01
-8daq,2023-12-20,2022-06-13
-8day,2022-09-28,2022-06-14
-4da7,2012-09-26,2012-01-12
-8dad,2022-08-24,2022-06-13
-5da3,2016-08-24,2015-08-19
-5dag,2015-10-21,2015-08-19
-3daw,2008-07-29,2008-05-30
-5dab,2016-08-24,2015-08-19
-5dap,2015-11-25,2015-08-20
-6dah,2018-10-17,2018-05-01
-7da6,2021-08-25,2020-10-15
-6daw,2018-05-16,2018-05-02
-4daa,1998-04-29,1998-01-26
-7dao,2020-10-28,2020-10-16
-1day,2000-05-03,1999-11-01
-1dao,1997-07-23,1997-01-16
-3dav,2008-12-16,2008-05-30
-3dag,2008-12-09,2008-05-29
-5dai,2016-05-11,2015-08-20
-6da9,2018-10-03,2018-05-01
-8das,2022-11-30,2022-06-14
-7daj,2021-09-22,2020-10-16
-4da4,2012-02-22,2012-01-12
-3da9,2009-05-19,2008-05-29
-3da1,2008-07-29,2008-05-28
-8dau,2022-11-30,2022-06-14
-7dah,2021-10-20,2020-10-16
-4dat,2012-06-13,2012-01-13
-7daa,2021-10-20,2020-10-16
-6daz,2018-05-16,2018-05-02
-1dak,1999-04-06,1998-03-31
-7dad,2021-03-24,2020-10-16
-6dab,2019-04-03,2018-05-01
-1dav,2001-04-04,1999-10-31
-2dap,1998-04-08,1997-12-23
-4dao,2012-09-26,2012-01-13
-5daw,2015-11-25,2015-08-20
-5da8,2015-10-14,2015-08-19
-5day,2016-09-21,2015-08-20
-1dai,1996-06-20,1995-05-08
-5da5,2016-08-10,2015-08-19
-5daq,2015-11-25,2015-08-20
-4da2,2014-10-15,2012-01-12
-6dag,2019-04-03,2018-05-01
-6dac,2019-04-03,2018-05-01
-1daw,2000-05-03,1999-11-01
-1daq,2001-04-04,1999-10-31
-5da0,2015-09-09,2015-08-19
-2da8,1994-01-31,1993-04-09
-6dae,2018-10-17,2018-05-01
-3dah,2008-06-10,2008-05-29
-1daf,1996-06-20,1995-05-08
-6dal,2019-04-03,2018-05-01
-1dam,1999-01-13,1998-08-31
-3da3,2008-09-02,2008-05-28
-4da6,2012-09-26,2012-01-12
-1dad,1996-06-20,1995-05-08
-5dav,2015-11-25,2015-08-20
-7dax,2021-02-10,2020-10-18
-6day,2018-06-06,2018-05-02
-1daz,2000-05-03,1999-11-01
-6daa,2019-04-03,2018-05-01
-6da6,2018-10-03,2018-05-01
-6daj,2019-04-03,2018-05-01
-8dal,2022-12-21,2022-06-13
-6da4,2018-11-28,2018-05-01
-1dat,1997-03-12,1996-11-14
-187l,1995-07-10,1995-04-19
-6tow,2020-05-27,2019-12-12
-3tog,2012-08-15,2011-09-05
-5tok,2017-02-22,2016-10-17
-7to9,2023-01-25,2022-01-23
-1to9,2004-08-10,2004-06-14
-6tot,2020-01-15,2019-12-11
-3tof,2012-08-15,2011-09-05
-4tod,2015-02-11,2014-06-05
-1ton,1988-01-16,1987-06-03
-3toy,2011-09-21,2011-09-06
-5toz,2016-11-09,2016-10-19
-7toh,2022-04-13,2022-01-24
-6to3,2021-08-18,2019-12-11
-8tot,2024-02-07,2023-08-03
-3to0,2012-02-29,2011-09-02
-6to2,2020-11-18,2019-12-11
-1tom,1997-03-12,1996-12-06
-5toa,2017-06-28,2016-10-17
-7to1,2022-11-02,2022-01-22
-3to6,2011-11-09,2011-09-04
-1to5,2004-08-31,2004-06-12
-2toh,1999-08-26,1998-08-26
-4tor,2015-05-20,2014-06-06
-4tob,2015-02-11,2014-06-05
-1to4,2004-08-31,2004-06-12
-1tot,2005-01-18,2004-06-15
-1tow,2004-08-24,2004-06-15
-8toi,2024-05-08,2023-08-03
-1top,1994-01-31,1993-08-11
-6tom,2020-04-22,2019-12-11
-6to0,2020-05-27,2019-12-11
-3toz,2011-09-21,2011-09-06
-6toj,2020-04-22,2019-12-11
-3to9,2011-11-09,2011-09-04
-5tob,2017-11-29,2016-10-17
-6toy,2020-10-14,2019-12-12
-6ton,2020-04-22,2019-12-11
-6too,2020-04-22,2019-12-11
-6toq,2020-10-21,2019-12-11
-3tox,2011-09-21,2011-09-06
-5tov,2017-07-05,2016-10-19
-8tov,2023-12-20,2023-08-04
-6tol,2020-04-22,2019-12-11
-7too,2022-05-25,2022-01-24
-7toz,2022-02-09,2022-01-24
-2tod,1999-11-17,1999-05-18
-4top,2014-06-25,2014-06-06
-3tom,2012-07-04,2011-09-05
-7to6,2022-03-02,2022-01-23
-4toa,2015-02-11,2014-06-05
-7toq,2022-05-25,2022-01-24
-6toz,2020-10-14,2019-12-12
-6to5,2021-01-13,2019-12-11
-7tov,2022-02-09,2022-01-24
-5to8,2016-12-21,2016-10-17
-7to4,2022-02-16,2022-01-22
-4to2,2014-10-01,2014-06-05
-7tob,2022-02-02,2022-01-24
-1toq,2004-08-03,2004-06-15
-4tos,2015-05-20,2014-06-06
-4toh,2015-02-11,2014-06-05
-1tou,2004-08-24,2004-06-15
-6tok,2020-04-22,2019-12-11
-7top,2022-05-25,2022-01-24
-6to1,2020-12-02,2019-12-11
-3top,2011-11-23,2011-09-06
-7tor,2022-05-25,2022-01-24
-5toj,2017-02-22,2016-10-17
-6toi,2020-04-22,2019-12-11
-4tog,2015-02-11,2014-06-05
-6to4,2020-12-09,2019-12-11
-3toa,2011-11-09,2011-09-04
-8to5,2024-04-17,2023-08-02
-7to3,2023-01-11,2022-01-22
-3tor,2011-12-07,2011-09-06
-8tok,2024-05-08,2023-08-03
-8tof,2024-01-17,2023-08-03
-1tog,2004-10-05,2004-06-14
-5toy,2017-11-08,2016-10-19
-6tog,2020-04-22,2019-12-11
-7tou,2022-02-09,2022-01-24
-4to5,2014-10-01,2014-06-05
-7to0,2022-11-02,2022-01-22
-3tou,2011-09-21,2011-09-06
-1toi,2004-10-05,2004-06-14
-1to1,2004-11-09,2004-06-11
-1toh,1998-06-03,1997-06-04
-4to9,2015-02-11,2014-06-05
-6tou,2020-02-12,2019-12-12
-6to7,2020-01-01,2019-12-11
-1tox,1996-06-10,1995-10-06
-5too,2017-11-01,2016-10-18
-8toq,2024-02-07,2023-08-03
-6tod,2020-01-01,2019-12-11
-7tow,2022-02-16,2022-01-24
-6tos,2020-01-15,2019-12-11
-5tou,2017-03-08,2016-10-18
-7to8,2023-01-25,2022-01-23
-3tod,2011-09-21,2011-09-05
-3toh,2012-08-15,2011-09-05
-4toe,2015-02-11,2014-06-05
-7tol,2022-08-31,2022-01-24
-7toc,2022-02-16,2022-01-24
-5top,2017-11-08,2016-10-18
-3tos,2011-10-05,2011-09-06
-4to1,2014-10-01,2014-06-05
-4to3,2014-10-01,2014-06-05
-7tos,2022-05-25,2022-01-24
-8toa,2024-05-15,2023-08-03
-3to3,2011-10-05,2011-09-03
-7to2,2022-11-02,2022-01-22
-7toa,2023-01-25,2022-01-23
-4tot,2014-11-12,2014-06-06
-1toa,1999-07-05,1999-03-03
-8to2,2024-04-17,2023-08-02
-5tol,2016-11-23,2016-10-18
-3tob,2011-11-09,2011-09-04
-4to8,2014-11-26,2014-06-05
-5tow,2017-07-05,2016-10-19
-7tox,2022-02-09,2022-01-24
-3to5,2012-09-12,2011-09-04
-3toc,2012-05-30,2011-09-05
-4toq,2014-09-10,2014-06-06
-8tor,2024-02-07,2023-08-03
-7to7,2023-01-25,2022-01-23
-4to4,2014-10-01,2014-06-05
-6to9,2021-01-13,2019-12-11
-3to7,2011-11-09,2011-09-04
-6tor,2020-04-15,2019-12-11
-7toy,2022-02-09,2022-01-24
-6toe,2020-12-09,2019-12-11
-4tof,2015-02-11,2014-06-05
-3to4,2011-12-14,2011-09-04
-8tou,2024-02-07,2023-08-04
-3tol,2012-07-04,2011-09-05
-7to5,2022-03-02,2022-01-23
-6tof,2020-04-22,2019-12-11
-7tom,2022-08-31,2022-01-24
-4toi,2014-12-31,2014-06-05
-1to2,2004-11-09,2004-06-11
-8tos,2024-02-07,2023-08-03
-6toh,2020-04-22,2019-12-11
-5to3,2017-03-29,2016-10-16
-4to6,2014-10-01,2014-06-05
-8tol,2024-05-08,2023-08-03
-4toc,2015-02-11,2014-06-05
-1toj,2004-10-05,2004-06-14
-6top,2020-06-17,2019-12-11
-8to0,2023-11-01,2023-08-02
-5toe,2017-10-11,2016-10-17
-3to2,2012-08-29,2011-09-03
-4to0,2014-10-01,2014-06-05
-4qo8,2014-07-16,2014-06-19
-7qou,2023-01-18,2021-12-29
-6qob,2019-08-21,2019-02-12
-7qol,2023-03-29,2021-12-24
-6qoe,2020-03-04,2019-02-12
-4qop,2015-02-25,2014-06-20
-7qoh,2023-03-29,2021-12-24
-5qom,2019-05-08,2019-02-22
-2qo0,2008-05-06,2007-07-19
-5qor,2019-05-08,2019-02-22
-7qof,2023-03-29,2021-12-24
-6qos,2020-02-26,2019-02-12
-7qoo,2022-06-08,2021-12-24
-5qol,2019-05-08,2019-02-22
-6qo4,2020-03-04,2019-02-12
-5qot,2019-05-08,2019-02-22
-7qot,2023-01-18,2021-12-28
-6qoa,2020-03-04,2019-02-12
-1qom,1999-12-15,1999-11-15
-6qol,2020-02-26,2019-02-12
-5qoo,2019-05-08,2019-02-22
-4qox,2014-09-03,2014-06-20
-6qot,2020-02-26,2019-02-12
-4qol,2015-02-25,2014-06-20
-3qo3,2012-02-15,2011-02-09
-3qom,2011-03-09,2011-02-10
-5qon,2019-05-08,2019-02-22
-3qol,2011-03-16,2011-02-10
-6qou,2020-02-26,2019-02-12
-5qox,2019-05-08,2019-02-22
-3qo7,2011-08-03,2011-02-09
-2qoj,2008-11-11,2007-07-20
-3qo9,2011-05-04,2011-02-09
-2qo8,2008-01-22,2007-07-20
-6qop,2020-02-26,2019-02-12
-4qo2,2014-09-24,2014-06-19
-6qov,2020-02-26,2019-02-12
-1qo4,2000-11-02,1999-11-02
-7qon,2023-01-18,2021-12-24
-7qod,2022-07-13,2021-12-23
-4qot,2015-06-24,2014-06-20
-6qoc,2020-03-04,2019-02-12
-6qow,2020-02-26,2019-02-12
-5qop,2019-05-08,2019-02-22
-7qoc,2022-07-13,2021-12-23
-4qo7,2014-07-16,2014-06-19
-7qom,2023-03-29,2022-03-17
-5qov,2019-05-08,2019-02-22
-7qo2,2023-01-18,2021-12-23
-5qoz,2019-05-08,2019-03-21
-7qop,2023-01-18,2021-12-24
-4qos,2014-08-06,2014-06-20
-4qoo,2015-02-25,2014-06-20
-1qoo,1999-11-23,1999-11-15
-7qoq,2023-01-18,2021-12-27
-2qo3,2007-09-04,2007-07-19
-2qo4,2007-07-31,2007-07-20
-2qoe,2007-11-06,2007-07-20
-7qoi,2023-03-29,2021-12-24
-6qoh,2020-02-26,2019-02-12
-3qof,2011-03-02,2011-02-09
-7qoz,2023-07-12,2021-12-30
-5qoy,2019-05-08,2019-02-22
-8qoa,2024-03-20,2023-09-28
-6qof,2020-02-26,2019-02-12
-7qoy,2023-01-18,2021-12-29
-3qo0,2012-02-15,2011-02-09
-4qoc,2015-05-06,2014-06-19
-5qow,2019-05-08,2019-03-21
-2qo6,2007-07-31,2007-07-20
-4qom,2015-02-25,2014-06-20
-4qo1,2014-10-29,2014-06-19
-6qon,2020-02-26,2019-02-12
-2qoq,2007-10-02,2007-07-20
-1qow,2000-05-26,1999-11-19
-6qoq,2020-02-26,2019-02-12
-4qoj,2015-08-12,2014-06-20
-6qo7,2019-08-21,2019-02-12
-6qod,2020-03-04,2019-02-12
-5qoi,2019-05-08,2019-02-22
-1qoz,2000-11-24,1999-11-25
-1qo8,2000-11-02,1999-11-04
-3qow,2011-05-25,2011-02-11
-6qo8,2019-08-21,2019-02-12
-8qow,2023-12-06,2023-09-29
-4qo4,2014-07-16,2014-06-19
-4qo5,2015-12-23,2014-06-19
-6qo6,2020-03-04,2019-02-12
-1qoq,2000-11-10,1999-11-15
-6qo3,2020-03-04,2019-02-12
-6qog,2020-02-26,2019-02-12
-2qog,2008-04-01,2007-07-20
-7qov,2023-01-18,2021-12-29
-4qoe,2015-07-01,2014-06-20
-2qoa,2008-01-22,2007-07-20
-7qow,2022-11-02,2021-12-29
-3qop,2012-04-04,2011-02-10
-6qoy,2019-12-25,2019-02-13
-2qo5,2007-07-31,2007-07-20
-6qoo,2020-02-26,2019-02-12
-1qop,2000-11-10,1999-11-15
-2qo1,2008-05-06,2007-07-19
-6qo2,2020-03-04,2019-02-12
-4qod,2015-07-01,2014-06-20
-2qo9,2007-08-21,2007-07-20
-7qo6,2022-03-16,2021-12-23
-3qoo,2011-02-23,2011-02-10
-1qor,1995-06-03,1995-02-14
-4qog,2015-07-01,2014-06-20
-4qoq,2015-02-25,2014-06-20
-6qom,2020-02-26,2019-02-12
-6qor,2020-02-26,2019-02-12
-7qo9,2022-01-26,2021-12-23
-7qo1,2023-01-11,2021-12-23
-4qoi,2015-07-01,2014-06-20
-1qo0,1999-12-23,1999-10-26
-5qos,2019-05-08,2019-02-22
-6qo0,2020-03-04,2019-02-12
-3qox,2011-05-25,2011-02-11
-6qox,2020-02-26,2019-02-12
-4qo9,2015-07-29,2014-06-19
-6qo9,2019-08-21,2019-02-12
-6qoj,2020-02-26,2019-02-12
-7qox,2023-01-18,2021-12-29
-1qot,1999-11-23,1999-11-16
-7qo5,2022-03-16,2021-12-23
-7qos,2022-02-02,2021-12-28
-7qob,2023-01-18,2021-12-23
-6qok,2020-02-26,2019-02-12
-7qo4,2022-06-01,2021-12-23
-5qoq,2019-05-08,2019-02-22
-7qoe,2022-07-13,2021-12-23
-7qoa,2022-07-13,2021-12-23
-7qoj,2023-03-29,2021-12-24
-3qob,2020-06-03,2011-02-09
-1qos,2000-02-07,1999-11-16
-5qok,2019-05-08,2019-02-22
-5qoh,2019-05-08,2019-02-22
-2qo7,2007-08-28,2007-07-20
-5qoj,2019-05-08,2019-02-22
-3qou,2011-02-23,2011-02-10
-3qoa,2011-09-14,2011-02-09
-7qo7,2022-01-19,2021-12-23
-4qon,2015-02-25,2014-06-20
-4qoh,2015-07-01,2014-06-20
-6qoi,2020-02-26,2019-02-12
-1qov,1999-12-13,1999-11-17
-2qoh,2007-09-18,2007-07-20
-3qoj,2011-03-16,2011-02-10
-4qo0,2014-09-24,2014-06-19
-4qof,2015-07-01,2014-06-20
-3qo8,2011-08-03,2011-02-09
-5qou,2019-05-08,2019-02-22
-2qor,2007-08-07,2007-07-20
-4qor,2015-02-25,2014-06-20
-7qok,2023-03-29,2021-12-24
-2qoc,2007-08-21,2007-07-20
-1dy1,2001-01-21,2000-01-21
-3dyc,2008-10-21,2008-07-25
-3dyh,2009-05-05,2008-07-27
-8dyu,2023-02-01,2022-08-05
-5dyc,2016-05-25,2015-09-24
-8dy5,2023-05-03,2022-08-03
-3dye,2009-02-03,2008-07-27
-3dy3,2008-11-04,2008-07-25
-5dys,2016-08-10,2015-09-25
-7dyv,2022-02-02,2021-01-23
-6dyu,2019-03-20,2018-07-02
-6dys,2019-01-30,2018-07-02
-3dym,2008-10-28,2008-07-28
-5dy7,2016-05-25,2015-09-24
-6dy3,2018-09-26,2018-07-01
-6dyr,2019-01-30,2018-07-02
-4dyb,2013-03-06,2012-02-28
-8dyl,2023-07-12,2022-08-04
-2dyf,2006-10-24,2006-09-11
-8dyv,2023-02-01,2022-08-05
-2dy5,2007-05-22,2006-09-06
-6dye,2019-04-24,2018-07-01
-6dyc,2019-04-24,2018-07-01
-4dym,2012-03-21,2012-02-29
-4dyd,2012-11-14,2012-02-28
-4dyn,2013-03-06,2012-02-29
-8dyh,2022-09-07,2022-08-04
-3dyl,2008-09-16,2008-07-28
-4dyp,2013-03-06,2012-02-29
-8dya,2022-11-30,2022-08-03
-7dy3,2022-01-26,2021-01-20
-1dy4,2000-12-18,2000-01-26
-5dyh,2016-04-27,2015-09-24
-3dy8,2008-09-16,2008-07-25
-6dym,2019-01-30,2018-07-02
-8dyf,2022-09-07,2022-08-04
-1dyp,2001-01-16,2000-02-04
-3dyg,2009-05-05,2008-07-27
-4dyo,2012-03-14,2012-02-29
-1dyr,1995-10-15,1994-09-14
-6dyg,2019-04-24,2018-07-01
-5dyz,2016-01-20,2015-09-25
-5dyp,2016-01-20,2015-09-25
-8dy9,2023-03-01,2022-08-03
-7dya,2021-09-01,2021-01-20
-5dyw,2017-01-18,2015-09-25
-7dyq,2022-01-26,2021-01-22
-6dy7,2019-03-13,2018-07-01
-7dyu,2022-02-02,2021-01-23
-7dyi,2022-04-27,2021-01-21
-4dya,2013-03-06,2012-02-28
-6dyk,2019-04-24,2018-07-01
-7dy4,2022-01-26,2021-01-20
-6dyh,2019-04-24,2018-07-01
-2dyx,2006-10-03,2006-09-19
-7dyd,2022-01-26,2021-01-21
-6dy1,2018-09-26,2018-07-01
-5dy5,2016-01-20,2015-09-24
-5dya,2016-05-25,2015-09-24
-4dy1,2013-03-27,2012-02-28
-8dy6,2023-04-19,2022-08-03
-7dy6,2021-11-17,2021-01-20
-1dyq,2001-03-19,2000-02-05
-5dyo,2016-01-27,2015-09-25
-2dy1,2007-09-25,2006-09-04
-2dys,2007-04-03,2006-09-16
-6dyi,2019-04-24,2018-07-01
-7dyk,2022-04-27,2021-01-22
-4dy6,2012-03-07,2012-02-28
-8dy7,2023-03-01,2022-08-03
-1dy0,2000-04-11,2000-01-21
-8dye,2024-01-10,2022-08-04
-8dy8,2023-08-09,2022-08-03
-3dyb,2008-10-07,2008-07-25
-1dyu,2000-02-29,2000-02-08
-5dye,2015-12-02,2015-09-24
-5dyd,2016-05-04,2015-09-24
-1dyi,1995-06-03,1994-10-26
-3dyn,2008-09-16,2008-07-28
-6dy0,2018-09-26,2018-07-01
-8dyg,2022-09-07,2022-08-04
-1dyk,2001-02-04,2000-02-01
-6dyl,2019-04-24,2018-07-01
-7dyj,2022-04-27,2021-01-22
-7dy8,2021-09-01,2021-01-20
-4dyu,2012-03-14,2012-02-29
-7dyz,2022-01-26,2021-01-23
-6dyb,2019-04-24,2018-07-01
-6dyw,2019-03-20,2018-07-02
-4dyh,2012-04-11,2012-02-29
-2dyh,2007-09-04,2006-09-14
-5dyj,2016-06-08,2015-09-24
-3dy5,2008-10-07,2008-07-25
-6dyf,2019-04-24,2018-07-01
-4dyy,2013-01-23,2012-02-29
-1dym,2000-02-04,2000-02-03
-3dyq,2008-09-16,2008-07-28
-7dy7,2022-01-26,2021-01-20
-4dyz,2013-01-23,2012-02-29
-8dyo,2022-09-21,2022-08-04
-5dy3,2016-10-05,2015-09-24
-4dy7,2012-08-15,2012-02-28
-5dyb,2016-05-04,2015-09-24
-5dyn,2016-03-30,2015-09-24
-7dyx,2022-02-02,2021-01-23
-4dy4,2013-03-06,2012-02-28
-4dy0,2012-08-15,2012-02-28
-3dyo,2008-10-28,2008-07-28
-1dyo,2000-07-04,2000-02-03
-3dy0,2008-10-28,2008-07-25
-4dy9,2012-03-14,2012-02-28
-4dyk,2012-03-14,2012-02-29
-6dyo,2019-01-30,2018-07-02
-6dyv,2019-03-20,2018-07-02
-3dyd,2008-08-19,2008-07-27
-8dyz,2022-09-07,2022-08-05
-8dyc,2022-10-26,2022-08-04
-6dyy,2019-03-20,2018-07-02
-5dyg,2016-02-10,2015-09-24
-5dyu,2016-03-16,2015-09-25
-5dyi,2016-02-10,2015-09-24
-3dy7,2009-06-16,2008-07-25
-4dyg,2012-08-15,2012-02-29
-8dyb,2023-01-04,2022-08-03
-2dy9,2007-03-08,2006-09-08
-5dy4,2016-01-13,2015-09-24
-2dy2,2006-12-05,2006-09-05
-7dy2,2022-04-27,2021-01-20
-8dyi,2022-09-07,2022-08-04
-6dy2,2018-09-26,2018-07-01
-7dyr,2021-09-01,2021-01-22
-3dy4,2008-11-04,2008-07-25
-5dyf,2015-11-25,2015-09-24
-8dyq,2022-12-14,2022-08-04
-1dyj,1995-06-03,1994-10-26
-6dyj,2019-04-24,2018-07-01
-6dya,2019-03-13,2018-07-01
-7dyb,2021-09-01,2021-01-20
-3dy6,2008-10-07,2008-07-25
-8dyj,2023-07-12,2022-08-04
-5dy1,2016-01-13,2015-09-24
-8dyr,2023-03-29,2022-08-04
-3dys,2008-09-16,2008-07-28
-3dyp,2008-10-28,2008-07-28
-3dya,2008-11-25,2008-07-25
-6dyt,2018-10-10,2018-07-02
-6dyd,2019-04-24,2018-07-01
-6dyz,2019-03-20,2018-07-02
-7dyg,2022-01-26,2021-01-21
-1dyz,2000-07-10,2000-02-11
-7dyt,2022-02-02,2021-01-23
-7dye,2022-05-18,2021-01-21
-1dy3,2000-08-18,2000-01-21
-3dyf,2009-05-05,2008-07-27
-1dyt,2001-02-08,2000-02-08
-5dyx,2016-03-16,2015-09-25
-2dyk,2007-03-14,2006-09-14
-5dyy,2017-01-18,2015-09-25
-2dya,2007-03-08,2006-09-08
-4dyx,2013-01-23,2012-02-29
-2dy3,2007-09-11,2006-09-05
-6dy8,2019-04-24,2018-07-01
-6dyn,2019-01-30,2018-07-02
-5dy9,2016-09-28,2015-09-24
-7dyy,2022-01-26,2021-01-23
-6dy6,2019-04-24,2018-07-01
-7dy5,2021-02-17,2021-01-20
-6dy4,2019-04-24,2018-07-01
-7dyw,2022-02-02,2021-01-23
-1dy9,2001-01-28,2000-01-31
-5dy8,2016-05-04,2015-09-24
-2dyp,2006-11-07,2006-09-15
-1dy7,2000-09-24,2000-01-28
-7dy1,2022-05-18,2021-01-20
-2dy0,2007-03-04,2006-09-04
-2dyr,2007-04-03,2006-09-16
-1dyh,1995-06-03,1994-10-26
-5dy2,2016-10-05,2015-09-24
-8dyd,2024-01-10,2022-08-04
-3a4v,2010-07-28,2009-07-20
-3a4t,2010-06-30,2009-07-14
-6a4h,2019-06-19,2018-06-19
-3a4z,2010-07-28,2009-07-24
-4a4l,2012-01-11,2011-10-17
-2a49,2005-08-02,2005-06-28
-2a4r,2006-07-04,2005-06-29
-8a46,2022-07-13,2022-06-10
-6a4g,2019-06-19,2018-06-19
-7a4b,2020-12-09,2020-08-19
-8a47,2022-11-30,2022-06-10
-4a44,2012-04-04,2011-10-06
-5a4x,2016-03-02,2015-06-15
-5a4k,2016-06-29,2015-06-10
-2a4z,2005-09-20,2005-06-30
-5a4c,2015-08-05,2015-06-05
-1a4m,1998-10-14,1998-01-31
-8a4v,2023-07-05,2022-06-13
-1a4a,1998-04-29,1998-01-28
-1a47,1998-06-17,1998-02-11
-1a4b,1998-04-29,1998-01-28
-6a48,2019-06-19,2018-06-19
-1a4r,1999-03-02,1998-02-02
-2a4w,2006-07-18,2005-06-30
-3a4m,2009-10-20,2009-07-10
-8a4g,2023-07-05,2022-06-11
-8a45,2023-07-05,2022-06-10
-7a4v,2020-12-16,2020-08-20
-3a40,2010-02-02,2009-06-25
-3a4g,2010-07-14,2009-07-07
-8a4t,2022-10-12,2022-06-13
-3a4p,2010-02-16,2009-07-13
-8a4u,2023-07-05,2022-06-13
-3a4h,2010-07-14,2009-07-07
-3a44,2009-10-06,2009-06-30
-4a4c,2012-01-25,2011-10-08
-5a45,2015-11-11,2015-06-05
-2a4e,2006-04-25,2005-06-28
-6a4y,2018-07-04,2018-06-21
-6a4f,2019-03-13,2018-06-19
-4a41,2012-04-04,2011-10-06
-7a4q,2022-06-08,2020-08-20
-8a49,2022-11-30,2022-06-10
-7a4z,2021-06-30,2020-08-20
-6a4l,2019-06-26,2018-06-20
-3a4x,2010-06-09,2009-07-22
-4a48,2012-12-12,2011-10-07
-4a4b,2012-01-25,2011-10-08
-7a44,2021-04-07,2020-08-19
-4a4k,2011-12-21,2011-10-17
-7a4p,2021-07-28,2020-08-20
-4a4f,2011-11-30,2011-10-12
-1a4w,1998-04-29,1998-02-06
-2a4x,2006-07-18,2005-06-30
-6a4w,2019-06-26,2018-06-21
-1a4q,1999-03-02,1998-01-30
-6a4n,2019-03-13,2018-06-20
-2a4m,2005-08-02,2005-06-29
-5a43,2015-09-02,2015-06-04
-4a4j,2012-12-12,2011-10-14
-8a4i,2023-01-11,2022-06-11
-1a4f,1998-04-29,1998-01-29
-3a4y,2009-08-04,2009-07-22
-4a42,2012-04-04,2011-10-06
-4a4g,2011-11-30,2011-10-12
-4a45,2012-04-04,2011-10-06
-7a4x,2021-06-16,2020-08-20
-6a47,2018-11-07,2018-06-19
-5a4u,2016-06-29,2015-06-15
-6a4x,2018-08-29,2018-06-21
-7a4n,2020-11-04,2020-08-20
-5a4d,2016-09-28,2015-06-08
-8a4x,2023-07-05,2022-06-13
-1a4z,1998-04-08,1998-02-10
-8a4c,2022-08-10,2022-06-10
-6a4i,2018-07-18,2018-06-20
-1a46,1998-05-27,1998-02-11
-3a4k,2009-10-20,2009-07-09
-6a4a,2019-03-13,2018-06-19
-1a4v,1999-04-27,1998-02-05
-6a4b,2018-11-07,2018-06-19
-4a4x,2012-04-25,2011-10-20
-3a4w,2010-06-09,2009-07-22
-4a46,2012-12-12,2011-10-07
-1a4h,1998-08-05,1998-01-29
-5a4g,2016-05-18,2015-06-09
-6a4z,2018-08-29,2018-06-21
-3a4o,2009-12-08,2009-07-11
-2a41,2005-11-01,2005-06-27
-5a4i,2015-11-25,2015-06-10
-6a4q,2019-03-13,2018-06-20
-8a4a,2022-08-10,2022-06-10
-5a46,2015-08-05,2015-06-05
-6a46,2018-11-07,2018-06-19
-4a4z,2011-12-21,2011-10-20
-1a42,1999-03-23,1998-02-10
-5a4f,2015-11-25,2015-06-09
-1a4g,1999-03-02,1998-01-29
-3a47,2010-07-14,2009-07-01
-3a4j,2010-01-12,2009-07-07
-2a40,2005-11-01,2005-06-27
-7a4o,2021-06-30,2020-08-20
-8a4n,2023-07-05,2022-06-13
-2a42,2005-11-01,2005-06-27
-8a4r,2023-07-05,2022-06-13
-8a4q,2022-10-12,2022-06-13
-8a48,2022-11-30,2022-06-10
-4a4v,2012-10-03,2011-10-20
-4a4a,2012-04-04,2011-10-07
-7a4w,2021-06-30,2020-08-20
-8a4y,2022-11-23,2022-06-13
-1a4k,1998-05-13,1998-01-30
-1a4l,1998-10-14,1998-01-31
-4a4m,2012-01-25,2011-10-17
-2a4n,2005-09-20,2005-06-29
-2a4g,2006-07-04,2005-06-28
-1a49,1999-04-20,1998-02-12
-2a4t,2006-06-13,2005-06-29
-5a4j,2016-07-06,2015-06-10
-7a45,2021-04-07,2020-08-19
-7a4m,2020-10-28,2020-08-20
-2a45,2006-05-02,2005-06-27
-6a4j,2018-07-11,2018-06-20
-2a4l,2006-10-03,2005-06-29
-2a4q,2006-07-04,2005-06-29
-6a4p,2019-03-13,2018-06-20
-8a4m,2023-04-26,2022-06-13
-4a49,2012-01-25,2011-10-07
-8a40,2023-08-23,2022-06-09
-1a4c,1998-04-29,1998-01-28
-4a4e,2011-11-30,2011-10-12
-2a4o,2005-12-27,2005-06-29
-8a4e,2023-03-29,2022-06-10
-1a4e,1999-08-13,1998-01-29
-4a4h,2011-11-30,2011-10-12
-5a4w,2016-06-29,2015-06-15
-5a40,2015-09-02,2015-06-04
-6a4k,2019-03-27,2018-06-20
-6a4r,2018-10-24,2018-06-20
-4a4q,2012-11-07,2011-10-19
-5a44,2015-11-11,2015-06-05
-5a4e,2016-06-29,2015-06-08
-6a4e,2019-03-13,2018-06-19
-3a43,2009-10-06,2009-06-30
-6a4d,2019-03-13,2018-06-19
-7a4s,2021-06-30,2020-08-20
-7a4c,2020-12-09,2020-08-19
-3a4l,2009-10-20,2009-07-10
-7a49,2020-12-09,2020-08-19
-4a4w,2012-10-03,2011-10-20
-3a45,2009-07-21,2009-06-30
-1a4i,1999-02-09,1998-01-30
-7a41,2020-12-02,2020-08-19
-5a4q,2016-06-29,2015-06-11
-6a40,2019-05-01,2018-06-18
-5a4t,2016-06-29,2015-06-15
-6a4u,2018-08-22,2018-06-21
-7a47,2021-10-13,2020-08-19
-7a4k,2021-06-16,2020-08-19
-5a4m,2015-11-25,2015-06-10
-2a4f,2005-09-20,2005-06-28
-3a4a,2010-07-14,2009-07-01
-4a47,2012-12-12,2011-10-07
-4a4o,2012-01-11,2011-10-18
-5a4l,2016-06-29,2015-06-10
-8a4w,2023-07-05,2022-06-13
-7a4r,2021-06-30,2020-08-20
-8a4b,2022-08-10,2022-06-10
-5a4v,2016-06-29,2015-06-15
-8a4d,2023-07-12,2022-06-10
-3a4u,2010-01-05,2009-07-17
-7a4a,2021-09-01,2020-08-19
-5pyr,2017-03-22,2017-02-08
-6py5,2020-03-18,2019-07-29
-5py6,2017-03-22,2017-02-08
-5pys,2017-03-22,2017-02-08
-5py8,2017-03-22,2017-02-08
-8pyl,2023-09-20,2023-07-25
-1pyf,2004-03-23,2003-07-08
-4pyt,2014-05-21,2014-03-27
-1py5,2004-07-13,2003-07-08
-2pyb,2008-08-12,2007-05-16
-7py9,2022-10-12,2021-10-09
-7py7,2022-03-23,2021-10-09
-5py4,2017-03-22,2017-02-08
-1pyt,1997-01-27,1995-06-21
-4pyk,2014-06-11,2014-03-27
-1py2,2004-01-13,2003-07-07
-2pyw,2008-01-15,2007-05-16
-8pyi,2023-09-20,2023-07-25
-6pya,2019-12-25,2019-07-29
-7py5,2022-03-23,2021-10-09
-6py1,2020-07-29,2019-07-28
-1pye,2004-07-13,2003-07-08
-4pyo,2014-06-11,2014-03-27
-4py5,2014-07-30,2014-03-26
-8pyk,2023-09-20,2023-07-25
-8pyj,2023-09-20,2023-07-25
-2pyl,2007-07-17,2007-05-16
-5pyt,2017-03-22,2017-02-08
-7py3,2022-03-23,2021-10-08
-6pyl,2019-11-27,2019-07-30
-7pyd,2022-08-24,2021-10-10
-3py5,2010-12-29,2010-12-11
-1pyc,1996-08-01,1996-02-17
-7py0,2022-03-23,2021-10-08
-2py7,2008-04-22,2007-05-15
-1py6,2003-12-16,2003-07-08
-6pyp,2020-07-08,2019-07-30
-3pyh,2011-12-21,2010-12-13
-5pyn,2017-03-22,2017-02-08
-3py6,2010-12-22,2010-12-11
-2pyo,2007-11-06,2007-05-16
-6pyx,2020-01-29,2019-07-31
-1pyo,2003-08-26,2003-07-09
-1py0,2004-12-07,2003-07-07
-6pyv,2019-11-27,2019-07-31
-4pyg,2015-02-11,2014-03-27
-5pyz,2017-03-22,2017-02-08
-4py6,2014-04-30,2014-03-26
-4py2,2015-04-15,2014-03-25
-6pyu,2019-08-28,2019-07-30
-5py7,2017-03-22,2017-02-08
-5pyq,2017-03-22,2017-02-08
-7py1,2022-03-23,2021-10-08
-6pyj,2019-12-04,2019-07-30
-4py9,2014-06-25,2014-03-26
-5pyh,2017-03-22,2017-02-08
-4pyx,2015-01-28,2014-03-28
-4pys,2014-06-18,2014-03-27
-4pyi,2014-06-11,2014-03-27
-6py9,2020-04-29,2019-07-29
-2pyj,2007-07-17,2007-05-16
-2pyd,2008-04-01,2007-05-16
-5pyp,2017-03-22,2017-02-08
-7pyw,2022-08-24,2021-10-11
-3pym,2012-01-11,2010-12-13
-3pye,2012-01-25,2010-12-13
-5py3,2017-03-22,2017-02-08
-3pyx,2012-01-04,2010-12-13
-8pyq,2023-08-16,2023-07-25
-2py5,2007-07-17,2007-05-15
-7pyl,2022-08-24,2021-10-10
-8pyv,2023-10-25,2023-07-26
-3pya,2011-05-25,2010-12-12
-3py4,2011-01-05,2010-12-11
-6pyf,2019-12-25,2019-07-29
-7pyx,2022-08-24,2021-10-11
-4pyn,2014-06-11,2014-03-27
-2pyp,1998-04-29,1997-02-03
-5py0,2017-03-22,2017-02-08
-7py6,2022-03-23,2021-10-09
-5pyd,2017-03-22,2017-02-08
-1pyz,2004-12-14,2003-07-09
-6py2,2020-01-15,2019-07-28
-8pym,2023-09-20,2023-07-25
-5py9,2017-03-22,2017-02-08
-5pyl,2017-03-22,2017-02-08
-7pyj,2022-03-23,2021-10-10
-5pye,2017-03-22,2017-02-08
-1py1,2003-11-04,2003-07-07
-7pye,2022-08-24,2021-10-10
-3pyp,1999-06-01,1998-07-28
-3py7,2011-12-14,2010-12-12
-5pyw,2017-03-22,2017-02-08
-7pya,2022-10-12,2021-10-09
-2py3,2007-09-25,2007-05-15
-5py1,2017-03-22,2017-02-08
-6py0,2019-08-28,2019-07-28
-2pyz,2007-07-03,2007-05-17
-4pyq,2014-06-11,2014-03-27
-7pyr,2022-03-02,2021-10-11
-7pyo,2022-08-24,2021-10-10
-1pym,1999-07-21,1999-02-25
-5pya,2017-03-22,2017-02-08
-2py4,2007-05-22,2007-05-15
-4pyj,2014-06-11,2014-03-27
-6pyc,2019-12-25,2019-07-29
-7pyf,2022-08-24,2021-10-10
-4pyd,2015-04-29,2014-03-26
-2pyy,2008-01-22,2007-05-17
-7py8,2022-03-23,2021-10-09
-8pyh,2024-01-03,2023-07-25
-5py2,2017-03-22,2017-02-08
-4pya,2015-04-29,2014-03-26
-4py4,2015-04-01,2014-03-26
-2pym,2008-02-26,2007-05-16
-4py0,2014-04-30,2014-03-25
-6pyw,2019-11-27,2019-07-31
-5pyi,2017-03-22,2017-02-08
-5pyy,2017-03-22,2017-02-08
-3pyf,2012-01-25,2010-12-13
-6py3,2020-03-18,2019-07-28
-3pyl,2012-01-04,2010-12-13
-6pyi,2020-03-18,2019-07-29
-7pyc,2022-10-12,2021-10-09
-1pyh,2004-03-02,2003-07-08
-2pyh,2008-05-27,2007-05-16
-2pya,2008-04-29,2007-05-16
-7pyk,2022-03-23,2021-10-10
-8pyo,2023-08-16,2023-07-25
-1pyd,1994-04-30,1993-03-23
-7pyi,2022-08-24,2021-10-10
-7pyy,2022-08-24,2021-10-11
-8pyw,2023-12-27,2023-07-26
-4py8,2014-05-21,2014-03-26
-7pyt,2022-04-06,2021-10-11
-7py4,2022-04-27,2021-10-08
-8pyp,2023-08-16,2023-07-25
-3pyg,2012-01-25,2010-12-13
-3py9,2011-01-19,2010-12-12
-2pyu,2008-03-18,2007-05-16
-6py4,2020-03-18,2019-07-29
-3py8,2011-06-15,2010-12-12
-1pyg,1994-01-31,1992-07-07
-5pyo,2017-03-22,2017-02-08
-1pyi,1995-02-27,1995-01-04
-6pyb,2019-12-25,2019-07-29
-1pyn,2003-09-16,2003-07-09
-5pyj,2017-03-22,2017-02-08
-6pyd,2019-12-25,2019-07-29
-2pyr,1999-04-06,1998-03-04
-1pyy,2003-09-30,2003-07-09
-5pyf,2017-03-22,2017-02-08
-2pyn,2008-02-26,2007-05-16
-4pyr,2014-04-23,2014-03-27
-6pys,2019-08-28,2019-07-30
-3pyy,2011-03-09,2010-12-13
-6pyo,2020-01-29,2019-07-30
-7pyh,2022-08-24,2021-10-10
-2pyg,2008-05-27,2007-05-16
-4pym,2014-06-11,2014-03-27
-1pyx,2003-10-21,2003-07-09
-7pyn,2022-08-24,2021-10-10
-2pys,2007-07-31,2007-05-16
-6pye,2020-07-29,2019-07-29
-6pyy,2020-01-01,2019-07-31
-4pyl,2014-06-18,2014-03-27
-6pyr,2019-08-28,2019-07-30
-3pyb,2011-05-25,2010-12-12
-5pyx,2017-03-22,2017-02-08
-4pyw,2015-06-10,2014-03-28
-7pyz,2022-08-24,2021-10-11
-6pyz,2020-01-01,2019-07-31
-4py1,2014-09-03,2014-03-25
-2py2,2007-06-26,2007-05-15
-5pyv,2017-03-22,2017-02-08
-2pyi,2008-04-01,2007-05-16
-7pyb,2022-10-12,2021-10-09
-5pyc,2017-03-22,2017-02-08
-2pye,2007-09-25,2007-05-16
-1pys,1997-11-19,1996-11-14
-4pyy,2015-01-28,2014-03-28
-3py0,2011-02-16,2010-12-10
-4pyh,2014-04-23,2014-03-27
-3py1,2011-02-16,2010-12-10
-4pyv,2014-10-08,2014-03-28
-7pyq,2022-08-24,2021-10-10
-3pyz,2011-01-19,2010-12-13
-5pyu,2017-03-22,2017-02-08
-8pyx,2024-02-07,2023-07-26
-8pyn,2023-09-20,2023-07-25
-5pyk,2017-03-22,2017-02-08
-7pym,2022-08-24,2021-10-10
-5pyg,2017-03-22,2017-02-08
-5pym,2017-03-22,2017-02-08
-7pyg,2022-08-24,2021-10-10
-5pyb,2017-03-22,2017-02-08
-3pyk,2011-07-13,2010-12-13
-5py5,2017-03-22,2017-02-08
-7pyu,2022-08-31,2021-10-11
-7pyp,2022-08-24,2021-10-10
-7p5c,2021-08-11,2021-07-14
-8p5e,2024-05-29,2023-05-24
-7p58,2021-11-17,2021-07-14
-1p5e,2003-07-01,2003-04-26
-3p5n,2010-11-03,2010-10-09
-7p5i,2021-11-17,2021-07-14
-7p5k,2021-11-17,2021-07-14
-7p5j,2021-08-11,2021-07-14
-8p55,2024-05-01,2023-05-23
-8p5l,2024-06-05,2023-05-24
-2p57,2007-03-27,2007-03-14
-3p55,2011-10-12,2010-10-07
-4p58,2014-06-25,2014-03-15
-2p5e,2007-09-25,2007-03-15
-1p57,2004-01-20,2003-04-25
-7p5p,2021-11-17,2021-07-14
-1p52,2003-06-17,2003-04-24
-7p5u,2022-07-27,2021-07-14
-4p53,2014-07-30,2014-03-13
-1p5j,2004-06-01,2003-04-27
-8p56,2024-05-01,2023-05-23
-2p5n,2007-10-09,2007-03-15
-6p5a,2019-10-30,2019-05-30
-4p57,2014-07-16,2014-03-14
-2p53,2007-07-24,2007-03-14
-8p57,2024-05-01,2023-05-23
-2p5o,2007-04-03,2007-03-15
-3p5k,2011-11-02,2010-10-08
-3p5a,2011-10-19,2010-10-08
-6p5z,2021-06-16,2019-05-31
-4p5y,2015-10-07,2014-03-04
-6p5t,2020-01-15,2019-05-30
-7p57,2022-07-27,2021-07-14
-8p5w,2023-08-16,2023-05-24
-8p5h,2024-06-05,2023-05-24
-7p5b,2022-07-27,2021-07-14
-2p54,2007-04-24,2007-03-14
-8p54,2024-05-01,2023-05-23
-8p5c,2024-05-01,2023-05-23
-8p5r,2023-08-16,2023-05-24
-8p5j,2024-06-05,2023-05-24
-6p5x,2020-02-26,2019-05-31
-8p5z,2023-09-13,2023-05-24
-4p5q,2014-08-13,2014-03-19
-2p5b,2007-06-12,2007-03-14
-3p5w,2010-11-03,2010-10-11
-2p51,2007-05-15,2007-03-14
-7p5f,2021-11-17,2021-07-14
-2p59,2008-02-05,2007-03-14
-6p5m,2020-01-15,2019-05-30
-6p5v,2019-09-11,2019-05-31
-7p5d,2022-07-27,2021-07-14
-7p50,2021-10-06,2021-07-13
-3p5q,2011-06-08,2010-10-10
-2p5m,2007-10-30,2007-03-15
-4p5x,2014-11-26,2014-03-20
-4p59,2014-04-16,2014-03-15
-4p5w,2014-11-26,2014-03-20
-6p54,2019-08-07,2019-05-29
-8p5g,2024-06-05,2023-05-24
-4p5s,2014-04-23,2014-03-19
-7p54,2021-08-11,2021-07-14
-7p5o,2022-07-27,2021-07-14
-1p5s,2004-05-11,2003-04-28
-8p5u,2023-08-16,2023-05-24
-7p5x,2021-12-22,2021-07-15
-7p5z,2022-02-02,2021-07-15
-3p5e,2010-12-08,2010-10-08
-6p59,2019-12-25,2019-05-29
-1p5b,2003-10-28,2003-04-25
-8p5s,2023-08-16,2023-05-24
-3p5o,2010-11-17,2010-10-09
-3p5l,2011-10-19,2010-10-08
-4p5i,2015-07-15,2014-03-17
-2p5v,2007-04-03,2007-03-16
-1p5z,2003-07-01,2003-04-28
-2p5w,2007-09-25,2007-03-16
-8p5y,2023-09-13,2023-05-24
-4p5a,2015-12-09,2014-03-15
-1p5r,2003-07-29,2003-04-28
-3p5h,2010-12-08,2010-10-08
-1p50,2003-06-17,2003-04-24
-1p53,2004-05-04,2003-04-24
-6p5w,2019-09-11,2019-05-31
-2p5u,2007-04-17,2007-03-16
-6p5l,2020-05-06,2019-05-30
-8p5a,2024-05-01,2023-05-23
-3p5c,2011-10-26,2010-10-08
-6p5p,2020-01-15,2019-05-30
-7p5n,2021-11-17,2021-07-14
-2p5c,2007-09-18,2007-03-15
-7p56,2022-07-27,2021-07-14
-4p5n,2014-05-28,2014-03-18
-2p5y,2007-04-17,2007-03-16
-8p5d,2023-06-21,2023-05-23
-2p55,2007-10-02,2007-03-14
-1p5w,2003-08-26,2003-04-28
-4p5z,2014-08-13,2014-03-20
-8p5t,2023-08-16,2023-05-24
-8p53,2023-12-13,2023-05-23
-3p5g,2010-12-08,2010-10-08
-6p57,2019-12-11,2019-05-29
-3p57,2011-08-10,2010-10-08
-7p59,2022-07-27,2021-07-14
-4p5d,2014-08-20,2014-03-16
-3p5u,2010-11-03,2010-10-11
-1p5x,2003-09-30,2003-04-28
-2p5q,2007-07-24,2007-03-16
-8p58,2024-05-01,2023-05-23
-2p5r,2007-07-24,2007-03-16
-6p5c,2020-03-25,2019-05-30
-8p5i,2024-06-05,2023-05-24
-1p59,2003-07-15,2003-04-25
-7p5a,2022-07-27,2021-07-14
-4p5r,2014-04-23,2014-03-19
-4p5o,2014-07-02,2014-03-18
-6p5r,2019-11-06,2019-05-30
-4p5e,2014-08-20,2014-03-16
-8p5v,2023-08-16,2023-05-24
-4p5h,2014-07-16,2014-03-17
-3p5y,2011-09-21,2010-10-11
-3p5f,2010-12-08,2010-10-08
-4p54,2014-04-02,2014-03-14
-7p5e,2021-11-17,2021-07-14
-3p5p,2010-12-29,2010-10-10
-1p5g,2004-01-20,2003-04-26
-3p5b,2011-10-26,2010-10-08
-8p50,2023-11-01,2023-05-23
-3p50,2011-01-19,2010-10-07
-6p5s,2019-07-31,2019-05-30
-6p58,2019-12-18,2019-05-29
-4p5m,2014-08-27,2014-03-18
-6p55,2019-08-07,2019-05-29
-2p5f,2007-09-18,2007-03-15
-4p5f,2014-08-13,2014-03-17
-3p5z,2011-09-21,2010-10-11
-2p50,2007-07-24,2007-03-14
-3p5x,2010-11-03,2010-10-11
-6p5q,2019-09-18,2019-05-30
-3p5r,2010-12-29,2010-10-10
-8p5x,2023-08-16,2023-05-24
-4p5b,2015-12-09,2014-03-15
-3p5v,2010-11-03,2010-10-11
-3p5d,2010-12-08,2010-10-08
-1p5d,2004-01-20,2003-04-25
-6p5o,2019-09-18,2019-05-30
-8p5q,2024-02-21,2023-05-24
-8p5k,2024-06-05,2023-05-24
-6p50,2019-09-04,2019-05-29
-8p5b,2024-05-01,2023-05-23
-3p5i,2010-12-08,2010-10-08
-7p5m,2021-08-11,2021-07-14
-7p52,2021-10-06,2021-07-13
-3p58,2011-10-19,2010-10-08
-2p5s,2007-03-27,2007-03-16
-7p5h,2022-09-14,2021-07-14
-7p51,2021-10-06,2021-07-13
-6p5u,2020-04-08,2019-05-31
-8p5f,2023-07-05,2023-05-24
-7p5t,2022-11-16,2021-07-14
-3p5s,2011-10-19,2010-10-10
-4p56,2014-05-07,2014-03-14
-8bxd,2023-07-12,2022-12-08
-1bx6,1999-04-27,1998-10-13
-1bxu,1999-06-15,1998-10-09
-6bxb,2018-08-01,2017-12-18
-3bxv,2009-01-20,2008-01-14
-3bxl,2008-03-25,2008-01-14
-8bx5,2023-07-12,2022-12-07
-3bxh,2008-07-01,2008-01-13
-6bxp,2018-03-14,2017-12-18
-8bx6,2023-12-20,2022-12-08
-2bxh,2005-09-22,2005-07-26
-6bxm,2018-04-11,2017-12-18
-1bxo,1998-10-14,1998-10-07
-3bxu,2008-07-01,2008-01-14
-6bxc,2018-05-09,2017-12-18
-8bx9,2023-12-20,2022-12-08
-2bxt,2006-10-26,2005-07-27
-4bxw,2013-07-31,2013-07-16
-2bx7,2006-08-29,2005-07-25
-3bxr,2008-03-25,2008-01-14
-6bxk,2018-04-11,2017-12-18
-1bxk,1998-10-14,1998-10-05
-5bxv,2015-07-15,2015-06-09
-3bx1,2008-07-08,2008-01-11
-6bxv,2018-04-04,2017-12-19
-1bxh,1998-10-07,1998-10-02
-4bxd,2013-10-09,2013-07-10
-6bxh,2018-11-28,2017-12-18
-6bxi,2018-08-29,2017-12-18
-5bx5,2016-05-18,2015-06-08
-5bx6,2016-09-14,2015-06-08
-5bx9,2015-10-07,2015-06-08
-2bxv,2006-08-16,2005-07-27
-2bxy,2006-02-06,2005-07-28
-7bxf,2020-05-20,2020-04-19
-2bxa,2005-09-22,2005-07-26
-8bxy,2023-04-12,2022-12-11
-6bxo,2018-04-11,2017-12-18
-6bxw,2018-12-19,2017-12-19
-4bxz,2013-09-11,2013-07-16
-2bxc,2005-09-22,2005-07-26
-1bxg,1999-05-18,1998-10-02
-1bxd,1999-10-02,1998-10-02
-4bx3,2013-12-25,2013-07-08
-2bxp,2005-09-22,2005-07-26
-4bxe,2013-10-09,2013-07-10
-6bxa,2018-05-09,2017-12-18
-2bx8,2005-09-22,2005-07-25
-2bxq,2005-09-22,2005-07-26
-8bxn,2023-08-02,2022-12-09
-3bxx,2008-10-21,2008-01-15
-3bx3,2008-03-11,2008-01-11
-2bxs,2005-08-09,2005-07-27
-8bxi,2023-08-02,2022-12-08
-8bxz,2023-12-20,2022-12-11
-5bx1,2016-12-21,2015-06-08
-5bxo,2016-06-29,2015-06-09
-8bx0,2023-08-02,2022-12-07
-1bxm,1999-06-15,1998-10-05
-4bxc,2013-10-02,2013-07-10
-8bxg,2023-12-20,2022-12-08
-3bxg,2008-07-01,2008-01-13
-6bxq,2018-02-28,2017-12-18
-8bx8,2023-05-10,2022-12-08
-5bxs,2015-09-09,2015-06-09
-6bxx,2018-04-04,2017-12-19
-1bxq,1998-10-14,1998-10-07
-8bxe,2023-07-12,2022-12-08
-2bxm,2005-09-22,2005-07-26
-2bxk,2005-09-22,2005-07-26
-7bxq,2021-04-21,2020-04-20
-7bxo,2020-09-30,2020-04-20
-2bxf,2005-09-22,2005-07-26
-8bxh,2023-12-20,2022-12-08
-6bx5,2018-02-14,2017-12-17
-3bxn,2009-02-03,2008-01-14
-6bxl,2018-04-11,2017-12-18
-8bxl,2023-09-06,2022-12-09
-3bxs,2008-03-25,2008-01-14
-2bxz,2006-02-06,2005-07-28
-1bxr,1999-04-20,1998-10-08
-5bxp,2015-09-09,2015-06-09
-2bxn,2005-09-22,2005-07-26
-3bxz,2008-09-30,2008-01-15
-4bxs,2013-07-31,2013-07-15
-8bxv,2023-03-22,2022-12-10
-6bxu,2018-12-26,2017-12-19
-5bxt,2015-09-09,2015-06-09
-5bx0,2015-12-23,2015-06-08
-5bxu,2016-06-29,2015-06-09
-6bxj,2018-10-03,2017-12-18
-1bx0,1998-10-14,1998-10-10
-7bxv,2021-04-21,2020-04-21
-4bx7,2013-09-25,2013-07-08
-3bx5,2008-04-15,2008-01-11
-5bx2,2016-05-18,2015-06-08
-7bxu,2020-09-16,2020-04-20
-3bxo,2008-03-25,2008-01-14
-6bxr,2018-12-19,2017-12-18
-4bxk,2013-09-18,2013-07-12
-6bxf,2018-08-01,2017-12-18
-3bxd,2008-02-05,2008-01-13
-8bxu,2023-03-22,2022-12-09
-1bxi,1999-10-04,1998-10-04
-8bxk,2023-01-18,2022-12-09
-5bxl,2016-06-15,2015-06-09
-5bxn,2016-06-15,2015-06-09
-2bx2,2005-10-14,2005-07-21
-8bx4,2023-08-02,2022-12-07
-4bx2,2013-12-25,2013-07-08
-7bx9,2020-12-23,2020-04-18
-6bx6,2018-05-09,2017-12-17
-3bxq,2008-05-20,2008-01-14
-4bxv,2014-07-30,2013-07-15
-5bx3,2016-05-18,2015-06-08
-5bxy,2015-07-01,2015-06-09
-2bxe,2005-09-22,2005-07-26
-2bxr,2005-08-09,2005-07-27
-3bxi,2008-03-25,2008-01-14
-5bx7,2016-09-14,2015-06-08
-8bxx,2023-01-18,2022-12-10
-1bx3,1999-10-21,1999-10-13
-8bxs,2023-08-02,2022-12-09
-8bxq,2023-08-02,2022-12-09
-5bxc,2015-09-23,2015-06-08
-3bxm,2009-01-27,2008-01-14
-5bxq,2015-07-01,2015-06-09
-3bxk,2008-03-25,2008-01-14
-1bx1,1998-10-14,1998-10-10
-4bxo,2013-08-28,2013-07-15
-1bxa,1998-10-07,1998-10-01
-4bxn,2013-07-31,2013-07-15
-4bx0,2013-12-25,2013-07-08
-5bxr,2015-09-09,2015-06-09
-7bxs,2021-04-21,2020-04-20
-8bxo,2023-08-02,2022-12-09
-8bxm,2023-08-02,2022-12-09
-8bxb,2023-07-12,2022-12-08
-1bxs,1999-04-27,1998-10-08
-2bxo,2005-09-22,2005-07-26
-6bx4,2018-02-14,2017-12-16
-1bxz,2000-02-18,1998-10-09
-3bxf,2008-07-01,2008-01-13
-1bx2,1998-10-21,1998-10-12
-6bxn,2018-04-11,2017-12-18
-6bxz,2018-11-28,2017-12-19
-3bx2,2008-03-11,2008-01-11
-1bxv,1999-06-15,1998-10-09
-5bxa,2015-10-07,2015-06-08
-5bxj,2016-05-25,2015-06-09
-2bxu,2006-10-26,2005-07-27
-6bxt,2018-12-19,2017-12-18
-8bxc,2023-12-20,2022-12-08
-2bxb,2005-09-22,2005-07-26
-2bx9,2005-11-30,2005-07-26
-2bxi,2005-09-22,2005-07-26
-1bxx,1998-11-25,1998-10-08
-8bxw,2023-03-22,2022-12-10
-2bxg,2005-09-22,2005-07-26
-6bx7,2018-12-19,2017-12-17
-4bxf,2014-05-14,2013-07-10
-5bx4,2016-05-18,2015-06-08
-2bxd,2005-09-22,2005-07-26
-2bxl,2005-09-22,2005-07-26
-1bx9,1998-10-21,1998-10-14
-6bxy,2018-11-28,2017-12-19
-8bx3,2023-08-02,2022-12-07
-1bx4,1999-10-13,1998-10-13
-4bxx,2013-09-11,2013-07-16
-8bxf,2023-07-12,2022-12-08
-7bxr,2021-04-21,2020-04-20
-3e5u,2008-09-30,2008-08-14
-8e51,2023-03-22,2022-08-19
-7e5g,2021-10-06,2021-02-18
-8e5p,2022-09-07,2022-08-22
-3e5x,2008-12-09,2008-08-14
-5e5o,2016-01-13,2015-10-08
-2e5m,2008-01-15,2006-12-22
-4e52,2013-03-27,2012-03-13
-7e5o,2021-09-08,2021-02-19
-1e5i,2001-07-26,2000-07-26
-5e50,2015-11-18,2015-10-07
-6e58,2019-02-06,2018-07-19
-8e5z,2022-09-21,2022-08-22
-8e5l,2022-09-07,2022-08-22
-3e54,2008-12-30,2008-08-13
-2e54,2007-06-19,2006-12-19
-8e5i,2023-08-30,2022-08-22
-4e55,2013-03-20,2012-03-14
-8e56,2022-12-07,2022-08-20
-3e5k,2008-12-30,2008-08-14
-1e54,2001-07-12,2000-07-17
-1e56,2000-12-11,2000-07-18
-3e5a,2008-10-28,2008-08-13
-2e5w,2007-06-26,2006-12-25
-4e5e,2012-08-08,2012-03-14
-4e5w,2012-05-30,2012-03-14
-2e5d,2007-12-25,2006-12-20
-5e56,2015-10-28,2015-10-07
-2e5s,2007-06-26,2006-12-22
-1e5o,2000-09-07,2000-07-28
-2e5l,2007-05-15,2006-12-21
-8e5f,2023-05-10,2022-08-22
-3e50,2009-08-18,2008-08-12
-1e51,2001-07-12,2000-07-13
-8e5d,2023-05-24,2022-08-21
-4e5d,2012-09-05,2012-03-14
-4e5i,2012-08-08,2012-03-14
-3e55,2009-02-24,2008-08-13
-4e5q,2013-03-27,2012-03-14
-2e59,2007-06-26,2006-12-19
-3e5l,2008-12-30,2008-08-14
-3e5h,2008-08-26,2008-08-13
-8e52,2022-09-21,2022-08-19
-7e5f,2021-10-06,2021-02-18
-8e5x,2022-09-07,2022-08-22
-6e5y,2018-08-01,2018-07-23
-6e5b,2019-09-11,2018-07-19
-7e5i,2021-10-06,2021-02-18
-6e5p,2019-02-13,2018-07-21
-7e5a,2021-05-05,2021-02-18
-1e5y,2000-08-19,2000-08-04
-8e5o,2022-09-07,2022-08-22
-3e5z,2008-09-30,2008-08-14
-3e5p,2009-08-18,2008-08-14
-8e5k,2022-09-07,2022-08-22
-8e57,2022-12-07,2022-08-20
-5e5c,2016-09-21,2015-10-08
-6e5a,2019-03-13,2018-07-19
-3e5s,2008-11-04,2008-08-14
-7e5z,2022-02-23,2021-02-21
-1e5h,2001-07-26,2000-07-26
-6e5m,2019-03-13,2018-07-20
-2e50,2007-02-20,2006-12-18
-6e5t,2019-02-13,2018-07-23
-6e57,2019-05-29,2018-07-19
-8e50,2022-12-21,2022-08-19
-2e56,2007-06-26,2006-12-19
-4e56,2013-03-20,2012-03-14
-7e57,2021-09-29,2021-02-18
-7e5m,2021-12-15,2021-02-19
-5e5w,2016-03-23,2015-10-09
-4e5j,2012-08-08,2012-03-14
-5e5s,2016-01-13,2015-10-09
-1e5j,2001-07-26,2000-07-26
-8e5v,2023-05-03,2022-08-22
-5e5z,2015-12-16,2015-10-09
-5e5k,2016-05-04,2015-10-08
-2e53,2007-06-26,2006-12-18
-3e5o,2009-02-24,2008-08-14
-1e5s,2001-07-26,2000-07-28
-6e5f,2019-07-24,2018-07-20
-5e5h,2016-05-18,2015-10-08
-2e5r,2007-06-26,2006-12-22
-8e5c,2024-02-07,2022-08-20
-8e59,2022-12-07,2022-08-20
-7e5s,2021-11-17,2021-02-20
-6e5g,2019-01-09,2018-07-20
-7e5e,2022-03-02,2021-02-18
-5e58,2016-02-10,2015-10-08
-4e5x,2012-10-10,2012-03-14
-8e5j,2023-08-30,2022-08-22
-6e5x,2018-12-12,2018-07-23
-8e5q,2023-07-26,2022-08-22
-2e5y,2007-07-10,2006-12-25
-8e5h,2023-08-30,2022-08-22
-7e5r,2021-10-13,2021-02-20
-6e5s,2019-07-24,2018-07-22
-3e5r,2009-08-18,2008-08-14
-1e5f,2001-07-19,2000-07-25
-1e5d,2000-11-17,2000-07-24
-4e5l,2012-08-08,2012-03-14
-6e54,2019-06-26,2018-07-19
-5e5f,2015-12-09,2015-10-08
-8e5y,2023-07-05,2022-08-22
-7e51,2022-02-16,2021-02-16
-4e5k,2012-05-30,2012-03-14
-6e53,2019-03-27,2018-07-19
-8e5b,2022-12-07,2022-08-20
-4e5p,2012-05-30,2012-03-14
-8e53,2022-09-21,2022-08-19
-1e5n,2000-12-08,2000-07-27
-6e56,2019-05-22,2018-07-19
-5e5d,2016-10-12,2015-10-08
-2e5a,2007-09-04,2006-12-19
-8e58,2022-12-07,2022-08-20
-4e5n,2012-05-30,2012-03-14
-1e5z,2000-08-19,2000-08-04
-4e5v,2012-04-04,2012-03-14
-8e5s,2023-05-03,2022-08-22
-8e5a,2022-12-07,2022-08-20
-3e51,2009-08-18,2008-08-12
-4e5u,2012-03-28,2012-03-14
-7e5c,2021-03-03,2021-02-18
-8e5e,2023-05-24,2022-08-21
-1e5v,2000-08-25,2000-08-03
-2e5v,2008-01-01,2006-12-25
-5e5j,2016-05-04,2015-10-08
-4e57,2013-03-20,2012-03-14
-6e59,2018-12-12,2018-07-19
-6e5w,2019-02-13,2018-07-23
-1e5k,2000-11-07,2000-07-27
-5e5e,2015-12-09,2015-10-08
-4e51,2012-03-28,2012-03-13
-7e5v,2021-06-30,2021-02-20
-4e5g,2012-08-08,2012-03-14
-7e5q,2022-08-24,2021-02-19
-6e5l,2019-02-13,2018-07-20
-3e5i,2009-02-24,2008-08-14
-2e5x,2007-06-26,2006-12-25
-5e5i,2016-10-19,2015-10-08
-5e5v,2015-12-16,2015-10-09
-5e51,2016-10-26,2015-10-07
-1e5e,2001-07-19,2000-07-25
-4e5y,2013-04-17,2012-03-15
-2e5c,2007-12-25,2006-12-20
-4e5m,2012-05-30,2012-03-14
-4e5h,2012-08-08,2012-03-14
-2e51,2007-06-26,2006-12-18
-5e5a,2016-02-03,2015-10-08
-5e5x,2015-12-16,2015-10-09
-6e5v,2018-11-07,2018-07-23
-8e5g,2023-05-10,2022-08-22
-4e5t,2012-03-28,2012-03-14
-7e50,2022-02-16,2021-02-16
-1e55,2000-12-11,2000-07-18
-1e5q,2000-12-03,2000-07-28
-1e5a,2000-08-29,2000-07-20
-3e5j,2008-12-30,2008-08-14
-7e5h,2021-10-06,2021-02-18
-4e5f,2012-08-08,2012-03-14
-8e5t,2023-04-12,2022-08-22
-8e5u,2023-02-22,2022-08-22
-8e5n,2023-03-08,2022-08-22
-5e5g,2016-06-01,2015-10-08
-8e5m,2023-03-08,2022-08-22
-8e5r,2023-07-26,2022-08-22
-7e5j,2022-02-23,2021-02-18
-4e5o,2012-04-18,2012-03-14
-966c,1999-08-07,1998-08-07
-6jzm,2020-03-18,2019-05-02
-8jzg,2023-10-25,2023-07-05
-5jzy,2017-06-07,2016-05-17
-6jzn,2020-05-06,2019-05-02
-3jzd,2009-10-06,2009-09-23
-6jzs,2020-03-18,2019-05-03
-7jze,2021-09-22,2020-09-02
-3jz4,2010-03-16,2009-09-22
-1jzs,2001-12-21,2001-09-17
-3jzg,2009-12-15,2009-09-23
-1jze,2001-10-17,2001-09-16
-4jzt,2013-05-01,2013-04-03
-1jzq,2001-12-21,2001-09-17
-7jzq,2021-10-06,2020-09-02
-5jza,2017-05-24,2016-05-16
-7jzf,2021-09-22,2020-09-02
-5jzd,2016-07-20,2016-05-16
-6jz2,2020-06-10,2019-04-30
-5jz6,2017-05-24,2016-05-16
-4jz4,2014-04-23,2013-04-02
-7jzo,2021-10-06,2020-09-02
-3jzh,2009-12-15,2009-09-23
-1jzj,2001-10-24,2001-09-16
-6jz4,2020-06-03,2019-04-30
-4jzu,2013-05-08,2013-04-03
-4jzx,2014-03-05,2013-04-03
-4jzg,2014-04-02,2013-04-02
-7jzd,2021-09-22,2020-09-02
-7jz8,2021-10-06,2020-09-01
-3jzp,2009-11-10,2009-09-24
-1jzf,2001-10-17,2001-09-16
-8jzx,2023-09-27,2023-07-06
-3jzo,2009-11-10,2009-09-23
-7jza,2021-09-22,2020-09-01
-7jzg,2021-09-22,2020-09-02
-8jzb,2024-04-17,2023-07-05
-5jz8,2017-05-24,2016-05-16
-1jz3,2001-12-07,2001-09-13
-4jz7,2013-06-05,2013-04-02
-8jz4,2024-01-17,2023-07-04
-3jzu,2010-08-18,2009-09-24
-5jzx,2017-05-10,2016-05-17
-4jzj,2014-04-09,2013-04-03
-3jzk,2009-11-17,2009-09-23
-3jz0,2009-11-03,2009-09-22
-1jz2,2001-12-07,2001-09-13
-7jz9,2021-09-22,2020-09-01
-4jzy,2013-06-26,2013-04-03
-3jzj,2010-02-16,2009-09-23
-8jzh,2023-10-25,2023-07-05
-7jzu,2020-09-23,2020-09-02
-1jz6,2001-12-07,2001-09-13
-5jz9,2017-04-05,2016-05-16
-1jz5,2001-12-07,2001-09-13
-5jzj,2016-08-24,2016-05-17
-4jzd,2013-08-21,2013-04-02
-7jzr,2021-10-06,2020-09-02
-7jzm,2020-09-23,2020-09-02
-6jz0,2019-12-04,2019-04-30
-8jzu,2023-09-27,2023-07-06
-4jzw,2013-06-12,2013-04-03
-8jze,2024-02-28,2023-07-05
-1jzh,2001-10-17,2001-09-16
-5jzb,2017-04-05,2016-05-16
-5jzn,2016-08-24,2016-05-17
-1jzl,2001-12-19,2001-09-16
-3jz2,2009-10-20,2009-09-22
-4jzf,2013-08-21,2013-04-02
-6jz8,2020-06-10,2019-04-30
-4jzr,2013-10-30,2013-04-03
-8jzi,2023-10-25,2023-07-05
-5jzs,2017-04-05,2016-05-17
-3jze,2009-09-29,2009-09-23
-6jzi,2019-10-30,2019-05-02
-3jz6,2010-05-05,2009-09-23
-6jz3,2020-05-13,2019-04-30
-4jzb,2014-02-12,2013-04-02
-8jzs,2023-09-27,2023-07-06
-6jzy,2020-04-01,2019-05-04
-6jzz,2020-04-01,2019-05-04
-3jzt,2010-01-12,2009-09-24
-7jzi,2021-05-26,2020-09-02
-3jzc,2009-12-08,2009-09-23
-8jz7,2023-10-04,2023-07-04
-2jz8,2008-01-15,2007-12-30
-7jzs,2021-06-02,2020-09-02
-3jzs,2009-11-10,2009-09-24
-3jzf,2009-11-03,2009-09-23
-8jzr,2023-09-27,2023-07-06
-7jzc,2021-09-22,2020-09-02
-3jzi,2009-11-03,2009-09-23
-7jz6,2021-01-20,2020-09-01
-1jzi,2001-10-17,2001-09-16
-3jz1,2009-10-20,2009-09-22
-7jz0,2020-09-16,2020-09-01
-1jzw,2001-11-28,2001-09-17
-7jzp,2022-02-02,2020-09-02
-6jzb,2020-11-04,2019-04-30
-4jz0,2014-04-02,2013-04-02
-4jzz,2013-06-12,2013-04-03
-1jzg,2001-10-17,2001-09-16
-7jzv,2021-02-17,2020-09-02
-1jzr,2001-12-21,2001-09-17
-3jzr,2009-11-10,2009-09-24
-6jz6,2020-06-10,2019-04-30
-6jzv,2020-05-06,2019-05-04
-5jzu,2017-06-07,2016-05-17
-1jzm,2001-12-19,2001-09-16
-3jzv,2009-10-13,2009-09-24
-4jz2,2014-04-02,2013-04-02
-4jzv,2013-05-08,2013-04-03
-1jz4,2001-12-07,2001-09-13
-8jz5,2024-01-17,2023-07-04
-1jz7,2001-12-07,2001-09-13
-2jzw,2009-01-13,2008-01-21
-6jzo,2020-10-21,2019-05-03
-5jzv,2016-08-10,2016-05-17
-2jzi,2009-01-13,2008-01-09
-7jzl,2020-09-23,2020-09-02
-7jzk,2021-05-26,2020-09-02
-7jzb,2021-09-22,2020-09-01
-1jzn,2003-07-01,2001-09-16
-8jz2,2024-01-17,2023-07-04
-4jzi,2014-02-26,2013-04-03
-6jzh,2019-10-30,2019-05-02
-7jz7,2021-10-06,2020-09-01
-3jzm,2010-03-31,2009-09-23
-6jzw,2020-05-06,2019-05-04
-6jz7,2020-06-10,2019-04-30
-8jz3,2024-01-17,2023-07-04
-4jz6,2014-04-02,2013-04-02
-3jzq,2009-11-10,2009-09-24
-3jzb,2009-12-08,2009-09-23
-4jze,2013-08-21,2013-04-02
-5jzl,2017-12-06,2016-05-17
-7jz2,2021-01-20,2020-09-01
-4jzk,2014-04-30,2013-04-03
-6jzd,2019-07-17,2019-05-01
-4jz1,2014-02-26,2013-04-02
-7jz4,2021-05-26,2020-09-01
-7jzn,2020-09-23,2020-09-02
-6jzu,2020-04-01,2019-05-03
-8jzf,2024-02-28,2023-07-05
-8jzn,2023-10-04,2023-07-05
-1jz8,2001-12-07,2001-09-13
-1jzk,2001-12-19,2001-09-16
-6jz5,2020-06-10,2019-04-30
-8bif,2023-03-08,2022-11-02
-4bi2,2013-05-22,2013-04-09
-8bih,2023-03-08,2022-11-02
-7bih,2022-07-27,2021-01-12
-2bia,2005-05-19,2005-01-20
-7bil,2021-04-07,2021-01-12
-3bia,2008-01-01,2007-11-30
-4bii,2013-12-04,2013-04-10
-2bi2,2005-05-19,2005-01-20
-5bir,1997-12-31,1997-06-30
-8bix,2023-04-12,2022-11-02
-1bif,1997-11-12,1996-11-08
-1bi3,1999-06-22,1998-06-21
-8bic,2023-03-08,2022-11-02
-6bii,2018-01-17,2017-11-02
-6bie,2018-10-17,2017-11-01
-3biz,2007-12-25,2007-12-02
-8bia,2023-11-15,2022-11-02
-8bii,2023-03-08,2022-11-02
-7bip,2021-01-20,2021-01-12
-7bic,2022-03-02,2021-01-12
-8bij,2023-03-08,2022-11-02
-7bik,2021-11-24,2021-01-12
-8bi2,2023-06-14,2022-11-01
-7bi1,2021-04-21,2021-01-12
-7bi9,2022-03-09,2021-01-12
-3bie,2008-04-22,2007-11-30
-7bi3,2021-06-16,2021-01-12
-1bi9,1999-07-22,1998-06-23
-2bil,2005-02-07,2005-01-22
-8biq,2023-11-15,2022-11-02
-1biq,1999-01-13,1998-06-18
-2bio,2005-01-26,2005-01-25
-2bi8,2005-05-05,2005-01-20
-8bi0,2023-01-11,2022-11-01
-2bie,2005-05-19,2005-01-21
-7biq,2021-06-16,2021-01-13
-7bia,2022-03-02,2021-01-12
-1bio,1999-06-22,1998-06-18
-3bi2,2008-01-01,2007-11-29
-8bi6,2023-11-15,2022-11-01
-2bib,2005-05-09,2005-01-20
-1bik,1999-03-16,1997-11-26
-1bit,1994-11-01,1994-08-26
-1bir,1996-08-17,1996-01-04
-4bid,2013-07-03,2013-04-10
-8big,2023-03-08,2022-11-02
-4bie,2013-07-03,2013-04-10
-6biy,2018-01-17,2017-11-03
-6bin,2018-01-17,2017-11-02
-2big,2005-05-19,2005-01-21
-6bil,2018-01-17,2017-11-02
-6bix,2018-01-17,2017-11-03
-6bir,2018-01-17,2017-11-02
-3bi5,2008-01-01,2007-11-29
-2bi4,2005-07-06,2005-01-20
-7bib,2022-03-02,2021-01-12
-3bi4,2008-01-01,2007-11-29
-3bi3,2008-04-22,2007-11-29
-4biv,2014-02-12,2013-04-13
-6big,2018-07-04,2017-11-02
-3biy,2008-02-12,2007-12-02
-6bic,2018-11-07,2017-11-01
-6bi1,2018-11-07,2017-10-31
-7biz,2022-03-02,2021-01-13
-4biy,2014-02-12,2013-04-13
-3bi1,2008-01-15,2007-11-29
-4bic,2013-07-03,2013-04-10
-2bip,2005-01-26,2005-01-25
-4bi7,2013-05-29,2013-04-09
-2bi1,2005-05-19,2005-01-20
-1bin,1997-03-12,1996-08-23
-2bih,2005-03-30,2005-01-21
-1bix,1999-06-22,1998-06-19
-8bin,2022-11-23,2022-11-02
-4bi3,2013-06-19,2013-04-09
-7bir,2021-04-07,2021-01-13
-7biu,2021-04-21,2021-01-13
-2bi5,2005-05-19,2005-01-20
-3bir,1997-12-31,1997-06-27
-6bid,2018-11-07,2017-11-01
-2bis,2005-11-28,2005-01-25
-2biq,2005-01-26,2005-01-25
-6bi9,2018-11-07,2017-11-01
-4bio,2013-04-24,2013-04-12
-4bif,2013-09-11,2013-04-10
-8bir,2023-03-08,2022-11-02
-7bix,2022-03-02,2021-01-13
-3bi0,2008-01-08,2007-11-29
-2bii,2005-03-30,2005-01-21
-8bik,2024-05-15,2022-11-02
-2bir,1997-06-16,1996-12-03
-6bif,2018-11-07,2017-11-01
-8biz,2023-04-12,2022-11-02
-6bi2,2018-02-14,2017-10-31
-6bib,2018-11-07,2017-11-01
-6bi8,2018-11-07,2017-11-01
-2biy,2005-02-23,2005-01-26
-2bif,1999-02-16,1998-10-26
-2bi9,2005-05-19,2005-01-20
-4bin,2013-08-21,2013-04-12
-8biv,2023-04-12,2022-11-02
-3bi6,2007-12-18,2007-11-29
-6biz,2018-01-17,2017-11-03
-6bi4,2017-11-08,2017-10-31
-7biv,2021-04-07,2021-01-13
-6biv,2018-01-17,2017-11-03
-1biw,1999-07-16,1998-06-19
-1bib,1993-10-31,1992-07-06
-8bip,2023-02-08,2022-11-02
-6bia,2018-03-14,2017-11-01
-3bix,2007-12-18,2007-12-01
-4bib,2013-07-03,2013-04-10
-7bi6,2022-03-09,2021-01-12
-8bib,2023-03-08,2022-11-02
-1bid,1998-07-01,1997-06-27
-7biy,2021-06-16,2021-01-13
-1biu,1998-08-19,1998-06-19
-2bi7,2005-05-05,2005-01-20
-1bic,1993-10-31,1992-09-01
-4bix,2014-02-12,2013-04-13
-1bij,1999-03-30,1998-06-18
-2bik,2005-02-07,2005-01-22
-3biw,2007-12-18,2007-12-01
-6bij,2018-01-17,2017-11-02
-7bij,2022-02-23,2021-01-12
-7biw,2021-09-15,2021-01-13
-3biv,2007-12-25,2007-12-01
-2bin,2005-01-26,2005-01-25
-3biu,2007-12-25,2007-12-01
-7bi2,2022-03-09,2021-01-12
-8bid,2023-03-08,2022-11-02
-8bie,2023-03-08,2022-11-02
-4biz,2014-04-23,2013-04-13
-2bi3,2005-05-19,2005-01-20
-8biu,2023-04-12,2022-11-02
-7bit,2021-04-07,2021-01-13
-4bis,2014-02-05,2013-04-12
-4bir,1998-07-15,1998-01-13
-4biu,2014-02-12,2013-04-13
-6bik,2018-11-07,2017-11-02
-7bi5,2021-03-17,2021-01-12
-8biw,2023-04-12,2022-11-02
-8bio,2022-11-23,2022-11-02
-8bis,2023-04-12,2022-11-02
-2biv,2005-02-08,2005-01-26
-2biw,2005-04-14,2005-01-26
-7bis,2022-03-02,2021-01-13
-4bi6,2013-05-29,2013-04-09
-2bim,2005-01-26,2005-01-25
-4biw,2014-02-12,2013-04-13
-1bi0,1999-07-22,1998-06-21
-3bib,2008-01-01,2007-11-30
-8bi3,2023-05-03,2022-11-01
-8bi7,2023-03-29,2022-11-01
-8bit,2023-11-15,2022-11-02
-4bih,2013-08-07,2013-04-10
-3bin,2008-01-15,2007-11-30
-4bim,2013-04-24,2013-04-11
-1biy,1999-01-13,1998-06-21
-4bi0,2013-05-22,2013-04-09
-1bii,1998-10-14,1998-06-11
-6bih,2018-09-19,2017-11-02
-8bi5,2023-11-15,2022-11-01
-4bi1,2013-05-22,2013-04-09
-6f11,2018-01-10,2017-11-21
-8f1f,2023-11-01,2022-11-05
-5f1g,2016-12-07,2015-11-30
-1f1c,2001-08-08,2000-05-18
-3f19,2008-11-18,2008-10-27
-4f1g,2013-05-08,2012-05-06
-6f1t,2018-01-17,2017-11-23
-4f1s,2012-08-08,2012-05-07
-4f1w,2013-05-01,2012-05-07
-7f1b,2022-03-23,2021-06-08
-5f1a,2016-03-16,2015-11-30
-8f1b,2023-01-18,2022-11-04
-3f1j,2009-02-03,2008-10-28
-8f1h,2023-11-08,2022-11-05
-5f1i,2016-11-30,2015-11-30
-8f1a,2023-09-20,2022-11-04
-8f16,2023-02-15,2022-11-04
-3f1a,2008-11-18,2008-10-27
-2f1i,2006-05-30,2005-11-14
-2f1r,2005-12-06,2005-11-15
-3f1q,2009-06-09,2008-10-28
-5f19,2016-03-16,2015-11-30
-8f14,2023-02-15,2022-11-04
-7f12,2022-06-15,2021-06-07
-4f1f,2013-05-08,2012-05-06
-7f1n,2021-11-03,2021-06-09
-6f12,2018-01-10,2017-11-21
-2f1j,2006-05-30,2005-11-14
-3f1s,2009-06-30,2008-10-28
-5f1x,2016-06-15,2015-11-30
-3f18,2008-11-18,2008-10-27
-2f11,2006-11-21,2005-11-14
-1f1r,2003-06-10,2000-05-19
-5f15,2016-02-17,2015-11-30
-1f12,2000-09-27,2000-05-18
-7f1e,2022-01-12,2021-06-09
-7f14,2022-04-20,2021-06-07
-1f1d,2002-12-18,2000-05-18
-1f1f,2001-08-08,2000-05-18
-3f1v,2009-09-01,2008-10-28
-2f1w,2006-02-07,2005-11-15
-5f1r,2016-03-16,2015-11-30
-5f1j,2016-02-03,2015-11-30
-1f17,2000-09-27,2000-05-18
-6f1n,2018-05-30,2017-11-22
-6f1r,2018-05-09,2017-11-22
-3f1y,2009-11-03,2008-10-28
-1f1h,2001-04-04,2000-05-19
-8f1d,2023-10-25,2022-11-04
-7f1g,2022-02-23,2021-06-09
-3f11,2008-11-25,2008-10-27
-5f1c,2016-03-16,2015-11-30
-6f1g,2018-12-12,2017-11-21
-2f1b,2006-12-05,2005-11-14
-2f10,2006-11-21,2005-11-14
-5f1u,2016-02-17,2015-11-30
-2f1g,2006-04-04,2005-11-14
-8f1i,2023-04-05,2022-11-05
-5f16,2016-02-24,2015-11-30
-8f1j,2023-04-05,2022-11-05
-4f1z,2012-08-08,2012-05-07
-7f1d,2022-02-23,2021-06-09
-8f1y,2023-11-08,2022-11-06
-8f12,2023-02-15,2022-11-04
-8f19,2023-07-26,2022-11-04
-6f1j,2018-08-15,2017-11-22
-6f1h,2018-01-17,2017-11-22
-8f1z,2023-11-08,2022-11-06
-4f10,2012-06-27,2012-05-05
-2f1d,2006-01-24,2005-11-14
-2f16,2006-03-21,2005-11-14
-7f1t,2021-07-14,2021-06-09
-8f1g,2023-01-11,2022-11-05
-6f17,2018-08-22,2017-11-21
-1f1g,2002-12-12,2000-05-18
-6f18,2018-08-22,2017-11-21
-1f1a,2002-12-18,2000-05-18
-3f1k,2008-11-18,2008-10-28
-6f1p,2018-05-09,2017-11-22
-6f1d,2018-01-17,2017-11-21
-5f11,2016-11-30,2015-11-28
-5f1w,2016-03-16,2015-11-30
-4f1n,2012-06-13,2012-05-07
-6f10,2018-01-10,2017-11-21
-2f12,2006-11-21,2005-11-14
-6f1w,2019-03-13,2017-11-23
-5f1l,2016-03-09,2015-11-30
-1f1j,2001-05-23,2000-05-19
-6f14,2018-12-12,2017-11-21
-1f1b,2000-11-22,2000-05-18
-6f1u,2018-01-17,2017-11-23
-2f1k,2006-05-09,2005-11-14
-4f14,2012-06-20,2012-05-06
-8f1x,2023-11-08,2022-11-06
-5f1b,2016-01-20,2015-11-30
-4f1y,2012-05-16,2012-05-07
-4f13,2012-06-27,2012-05-06
-3f17,2008-11-18,2008-10-27
-6f13,2018-01-10,2017-11-21
-7f1u,2022-04-20,2021-06-09
-8f1k,2023-04-05,2022-11-05
-5f1v,2016-02-17,2015-11-30
-6f16,2018-01-10,2017-11-21
-7f1v,2022-04-20,2021-06-09
-7f15,2022-06-15,2021-06-07
-4f1t,2012-06-27,2012-05-07
-4f1c,2013-05-08,2012-05-06
-7f1z,2022-06-15,2021-06-10
-6f1q,2018-06-27,2017-11-22
-4f1d,2013-05-08,2012-05-06
-4f1o,2012-06-27,2012-05-07
-7f1a,2022-03-23,2021-06-08
-5f1t,2016-03-16,2015-11-30
-2f13,2006-11-21,2005-11-14
-2f1f,2006-01-24,2005-11-14
-7f19,2022-06-15,2021-06-08
-1f1z,2000-06-28,2000-05-21
-8f13,2023-02-15,2022-11-04
-8f1e,2023-07-26,2022-11-04
-6f1c,2018-01-17,2017-11-21
-6f19,2018-08-22,2017-11-21
-2f1a,2006-12-05,2005-11-14
-7f1o,2022-06-15,2021-06-09
-5f1q,2015-12-23,2015-11-30
-5f1h,2016-03-09,2015-11-30
-4f1a,2013-05-08,2012-05-06
-3f15,2008-11-18,2008-10-27
-4f1h,2012-10-31,2012-05-06
-8f15,2023-02-15,2022-11-04
-4f1m,2012-06-27,2012-05-07
-5f12,2016-05-25,2015-11-29
-4f1p,2012-07-18,2012-05-07
-6f1x,2018-03-07,2017-11-23
-1f1w,2000-07-06,2000-05-20
-4f12,2012-06-06,2012-05-05
-5f1m,2016-08-24,2015-11-30
-7f1m,2022-03-09,2021-06-09
-1f1m,2001-04-04,2000-05-19
-2f14,2006-10-24,2005-11-14
-6f15,2018-01-10,2017-11-21
-1f18,2002-12-18,2000-05-18
-8f10,2023-02-15,2022-11-04
-3f10,2009-04-07,2008-10-27
-2f1o,2006-05-16,2005-11-15
-8f1w,2023-11-08,2022-11-06
-8f18,2023-09-20,2022-11-04
-8f17,2023-02-15,2022-11-04
-7f1x,2021-10-27,2021-06-10
-7f11,2022-04-20,2021-06-07
-8f1c,2023-10-25,2022-11-04
-4f1b,2013-05-08,2012-05-06
-4f1q,2012-09-05,2012-05-07
-5f1f,2016-12-07,2015-11-30
-5f14,2016-02-24,2015-11-30
-5f13,2016-03-30,2015-11-30
-7f10,2022-04-20,2021-06-07
-4f1l,2012-09-05,2012-05-07
-5f1z,2016-01-13,2015-12-01
-2f1h,2006-05-30,2005-11-14
-2f18,2006-12-05,2005-11-14
-3f1o,2009-01-20,2008-10-28
-3f16,2008-11-18,2008-10-27
-1f1v,2003-06-10,2000-05-20
-6f1a,2018-08-22,2017-11-21
-7f1y,2022-06-15,2021-06-10
-1f1u,2003-06-10,2000-05-19
-3f1t,2008-11-18,2008-10-28
-4f1j,2013-01-30,2012-05-07
-2f17,2005-11-29,2005-11-14
-8f11,2023-02-15,2022-11-04
-7f16,2021-08-18,2021-06-08
-7oau,2021-08-11,2021-04-20
-1oao,2003-04-11,2003-01-20
-5oaw,2018-07-11,2017-06-24
-5oai,2019-02-13,2017-06-22
-1oa8,2003-11-06,2003-01-02
-4oav,2014-03-12,2014-01-06
-6oab,2019-07-03,2019-03-15
-4oa5,2014-03-05,2014-01-03
-7oaq,2021-08-11,2021-04-20
-3oad,2010-11-03,2010-08-05
-6oaq,2019-09-18,2019-03-18
-1oad,2003-01-30,2003-01-08
-3oaz,2011-01-12,2010-08-06
-7oaj,2021-05-19,2021-04-19
-1oas,2000-01-28,1999-01-29
-6oak,2020-03-18,2019-03-16
-2oag,2007-09-11,2006-12-15
-3oaf,2011-08-03,2010-08-05
-3oax,2011-01-19,2010-08-05
-5oa0,2018-08-01,2017-06-20
-2oas,2007-01-23,2006-12-17
-2oar,2007-01-09,2006-12-17
-2oan,2007-05-01,2006-12-16
-3oap,2010-11-17,2010-08-05
-5oa8,2018-04-04,2017-06-21
-6oap,2019-09-18,2019-03-18
-6oaa,2019-07-03,2019-03-15
-2oaa,2007-02-20,2006-12-15
-6oai,2020-03-18,2019-03-16
-3oa6,2010-08-18,2010-08-04
-6oad,2019-03-27,2019-03-15
-5oah,2018-08-01,2017-06-22
-4oar,2014-10-08,2014-01-06
-4oay,2014-11-19,2014-01-06
-3oau,2011-01-12,2010-08-05
-1oa7,2003-05-29,2003-01-02
-1oah,2003-05-08,2003-01-14
-2oad,2007-01-23,2006-12-15
-4oas,2014-02-19,2014-01-06
-6oac,2019-06-26,2019-03-15
-5oa3,2017-08-09,2017-06-20
-1oal,2003-02-27,2003-01-15
-6oal,2020-03-18,2019-03-16
-1oac,1996-04-03,1995-09-27
-1oan,2003-05-16,2003-01-16
-3oaa,2011-05-25,2010-08-05
-4oa8,2014-01-15,2014-01-03
-5oa5,2017-09-06,2017-06-20
-3oac,2010-11-03,2010-08-05
-6oa8,2020-08-05,2019-03-15
-4oau,2014-03-12,2014-01-06
-6oaz,2019-05-08,2019-03-19
-7oak,2021-05-19,2021-04-19
-4oaq,2015-02-11,2014-01-06
-1oab,2004-01-23,2003-01-06
-7oas,2022-08-03,2021-04-20
-5oa6,2018-05-02,2017-06-21
-5oab,2018-08-01,2017-06-21
-3oai,2011-12-21,2010-08-05
-7oay,2021-08-11,2021-04-20
-1oaf,2003-03-20,2003-01-13
-1oai,2003-02-20,2003-01-14
-7oai,2021-05-19,2021-04-19
-5oa1,2017-07-26,2017-06-20
-6oau,2019-05-08,2019-03-18
-4oag,2014-01-22,2014-01-04
-4oaj,2014-01-29,2014-01-04
-7oam,2021-05-19,2021-04-19
-1oa2,2003-03-27,2002-12-28
-2oac,2007-01-23,2006-12-15
-3oay,2011-01-12,2010-08-05
-1oae,2004-03-26,2003-01-09
-3oa4,2010-08-18,2010-08-04
-1oat,1998-04-01,1997-03-26
-4oat,2014-01-15,2014-01-06
-2oat,1998-12-09,1998-05-07
-7oan,2021-08-11,2021-04-19
-2oaj,2007-04-03,2006-12-15
-1oaj,2003-02-27,2003-01-14
-1oar,2004-01-15,2003-01-21
-4oa3,2014-08-20,2014-01-03
-7oa2,2021-06-02,2021-04-19
-6oa9,2019-07-03,2019-03-15
-6oae,2020-03-18,2019-03-15
-2oae,2007-02-27,2006-12-15
-5oaf,2017-12-13,2017-06-21
-7oa4,2022-08-03,2021-04-19
-2oah,2007-08-14,2006-12-15
-6oah,2019-11-06,2019-03-16
-1oax,2004-01-15,2003-01-21
-2oa8,2007-02-20,2006-12-15
-5oas,2017-10-18,2017-06-23
-2oa6,2007-01-30,2006-12-15
-3oag,2010-11-03,2010-08-05
-2oax,2007-08-14,2006-12-18
-5oa7,2018-04-04,2017-06-21
-3oah,2011-03-23,2010-08-05
-5oad,2018-08-01,2017-06-21
-7oar,2022-03-09,2021-04-20
-1oau,2004-01-15,2003-01-21
-3oaw,2010-09-22,2010-08-05
-7oao,2021-08-11,2021-04-19
-1oay,2004-01-15,2003-01-21
-5oam,2017-10-25,2017-06-23
-2oap,2007-02-13,2006-12-17
-4oa7,2015-01-07,2014-01-03
-5oar,2017-12-27,2017-06-23
-2oa7,2007-01-30,2006-12-15
-2oay,2007-05-01,2006-12-18
-3oa0,2010-08-18,2010-08-04
-5oae,2018-04-25,2017-06-21
-7oa1,2022-05-04,2021-04-18
-6oa1,2019-12-25,2019-03-15
-5oaj,2018-08-01,2017-06-22
-6oa3,2019-12-25,2019-03-15
-1oaa,1999-02-16,1997-08-25
-6oa7,2019-04-03,2019-03-15
-1oa3,2003-03-27,2002-12-28
-7oal,2021-05-19,2021-04-19
-6oay,2019-06-12,2019-03-18
-3oaj,2010-08-18,2010-08-05
-5oa4,2018-04-04,2017-06-20
-2oai,2007-01-16,2006-12-15
-4oad,2014-01-29,2014-01-04
-4oaa,2014-01-29,2014-01-03
-4oak,2014-01-15,2014-01-04
-7oat,2022-08-03,2021-04-20
-4oan,2014-01-22,2014-01-05
-5oan,2018-08-08,2017-06-23
-2oaz,2007-06-19,2006-12-18
-3oab,2010-11-03,2010-08-05
-5oat,2017-10-11,2017-06-23
-4oaz,2014-11-19,2014-01-06
-2oa9,2007-02-20,2006-12-15
-7oa0,2022-05-04,2021-04-18
-7oa7,2022-05-04,2021-04-19
-3oam,2010-09-22,2010-08-05
-5oav,2017-07-12,2017-06-23
-2oa0,2007-02-06,2006-12-14
-4oal,2015-04-01,2014-01-05
-7oap,2021-08-11,2021-04-19
-1oag,2003-03-20,2003-01-13
-6oav,2020-03-25,2019-03-18
-5oal,2018-08-01,2017-06-22
-4oae,2014-01-29,2014-01-04
-6oag,2019-11-06,2019-03-16
-5oax,2018-05-02,2017-06-25
-2oal,2007-02-13,2006-12-16
-7oa5,2021-04-28,2021-04-19
-3oa2,2010-08-18,2010-08-04
-6oa0,2019-12-25,2019-03-15
-5oa2,2018-05-02,2017-06-20
-2oa1,2007-04-10,2006-12-14
-7oa9,2022-08-03,2021-04-19
-3oa8,2011-05-18,2010-08-04
-6oax,2019-06-12,2019-03-18
-1tf9,2005-05-31,2004-05-27
-4tf4,1997-09-04,1997-05-31
-8tf9,2023-11-15,2023-07-09
-3tf1,2011-11-09,2011-08-15
-3tfv,2012-04-04,2011-08-16
-1tf7,2004-08-24,2004-05-26
-8tf2,2024-01-10,2023-07-07
-5tf4,2016-11-09,2016-09-24
-6tfq,2020-01-22,2019-11-14
-8tfo,2024-03-13,2023-07-11
-3tfu,2011-10-19,2011-08-16
-3tfd,2011-11-09,2011-08-15
-6tf9,2019-12-11,2019-11-13
-7tfb,2022-06-29,2022-01-06
-3tfp,2012-04-04,2011-08-16
-3tfe,2011-11-09,2011-08-15
-8tfq,2023-08-16,2023-07-11
-7tf8,2022-02-16,2022-01-06
-7tf9,2022-06-29,2022-01-06
-8tfh,2024-04-17,2023-07-11
-1tf8,2005-05-31,2004-05-27
-7tfh,2022-11-16,2022-01-06
-5tfb,2018-05-09,2016-09-24
-3tfn,2012-04-04,2011-08-16
-1tf4,1997-09-04,1997-05-30
-1tfz,2004-08-17,2004-05-27
-7tf2,2022-03-30,2022-01-06
-8tfz,2023-11-08,2023-07-12
-5tff,2018-05-09,2016-09-25
-3tfa,2011-11-09,2011-08-15
-1tfd,1993-04-15,1990-08-16
-5tfr,2016-10-12,2016-09-26
-7tfo,2022-01-26,2022-01-06
-5tfj,2018-05-09,2016-09-25
-5tfi,2018-05-09,2016-09-25
-3tff,2011-11-09,2011-08-15
-6tfw,2020-09-30,2019-11-14
-7tfq,2022-01-19,2022-01-07
-7tfa,2022-06-29,2022-01-06
-7tfj,2022-11-16,2022-01-06
-8tfk,2023-11-15,2023-07-11
-3tfy,2011-09-07,2011-08-16
-5tfd,2018-05-09,2016-09-24
-1tfq,2004-09-07,2004-05-27
-7tfe,2022-06-29,2022-01-06
-8tf3,2024-01-10,2023-07-07
-1tf2,2004-08-03,2004-05-26
-3tfz,2011-09-14,2011-08-16
-5tf6,2017-01-11,2016-09-24
-1tfr,1996-11-08,1996-04-27
-3tfc,2011-08-31,2011-08-15
-3tfj,2011-12-28,2011-08-15
-7tf6,2022-06-29,2022-01-06
-8tfy,2023-11-08,2023-07-12
-6tfs,2020-01-22,2019-11-14
-5tf8,2018-05-09,2016-09-24
-7tf5,2022-03-30,2022-01-06
-3tf7,2011-12-07,2011-08-15
-3tfr,2012-03-21,2011-08-16
-6tfo,2020-06-10,2019-11-14
-8tfx,2023-11-08,2023-07-12
-5tf5,2016-10-05,2016-09-24
-3tf8,2011-11-09,2011-08-15
-8tfl,2024-04-17,2023-07-11
-8tfb,2023-11-15,2023-07-09
-3tfq,2011-11-02,2011-08-16
-1tfm,2004-07-13,2004-05-27
-6tf7,2020-11-18,2019-11-13
-6tfz,2020-09-30,2019-11-14
-7tfp,2022-04-06,2022-01-06
-5tf7,2018-05-09,2016-09-24
-3tfs,2012-03-21,2011-08-16
-6tfl,2020-11-25,2019-11-14
-5tfc,2018-05-09,2016-09-24
-7tf3,2022-03-30,2022-01-06
-6tfp,2020-03-04,2019-11-14
-3tfg,2011-11-09,2011-08-15
-7tfk,2022-11-16,2022-01-06
-5tfg,2018-05-09,2016-09-25
-8tfa,2023-11-15,2023-07-09
-5tf0,2016-10-05,2016-09-23
-5tfm,2017-12-27,2016-09-25
-1tfv,2004-07-13,2004-05-27
-5tfx,2017-08-09,2016-09-26
-6tf6,2020-11-18,2019-11-13
-7tfs,2022-05-04,2022-01-07
-7tfi,2022-11-16,2022-01-06
-8tff,2024-04-17,2023-07-11
-3tfh,2011-12-28,2011-08-15
-6tfk,2020-08-12,2019-11-14
-6tfu,2020-09-30,2019-11-14
-7tfl,2022-11-16,2022-01-06
-5tfk,2017-12-27,2016-09-25
-5tfz,2017-06-14,2016-09-27
-3tfl,2011-10-12,2011-08-16
-3tf9,2011-11-09,2011-08-15
-3tf4,1997-09-04,1997-05-30
-3tf0,2011-11-09,2011-08-15
-6tfx,2020-01-22,2019-11-14
-6tfb,2020-02-26,2019-11-13
-6tfy,2020-09-30,2019-11-14
-6tfv,2020-09-30,2019-11-14
-7tf1,2022-03-30,2022-01-06
-1tf6,1998-07-10,1998-03-02
-3tft,2011-10-19,2011-08-16
-7tf0,2022-03-30,2022-01-06
-5tft,2017-01-11,2016-09-26
-5tfa,2018-05-09,2016-09-24
-1tfw,2004-08-10,2004-05-27
-7tfd,2022-06-29,2022-01-06
-7tf4,2022-03-30,2022-01-06
-8tf4,2024-01-10,2023-07-07
-6tfn,2020-10-07,2019-11-14
-7tfn,2022-01-19,2022-01-06
-1tft,2005-05-03,2004-05-27
-8tfm,2024-04-17,2023-07-11
-7tfc,2022-06-29,2022-01-06
-3tf6,2011-09-07,2011-08-15
-6tfd,2020-06-10,2019-11-13
-6tfi,2020-11-11,2019-11-14
-1tfi,1993-10-31,1993-04-27
-8tfp,2023-08-16,2023-07-11
-3tfk,2011-12-07,2011-08-15
-1tfy,2004-08-10,2004-05-27
-5tfl,2017-12-27,2016-09-25
-1tfx,1998-01-21,1997-01-21
-5tf9,2016-10-19,2016-09-24
-7tfr,2022-03-02,2022-01-07
-1tf3,1997-09-17,1997-07-01
-5tfu,2017-01-11,2016-09-26
-3tfi,2011-12-28,2011-08-15
-1zz9,2005-07-26,2005-06-13
-7zzu,2022-09-21,2022-05-26
-6zzo,2020-10-07,2020-08-04
-7zzg,2023-01-11,2022-05-25
-4zza,2016-06-29,2015-05-22
-7zz7,2023-01-11,2022-05-25
-6zza,2021-08-18,2020-08-04
-5zzt,2019-06-19,2018-06-04
-7zzf,2023-01-11,2022-05-25
-5zzd,2019-06-05,2018-05-31
-6zz1,2020-12-23,2020-08-03
-7zzd,2023-01-11,2022-05-25
-4zzu,2015-09-23,2015-04-14
-6zzm,2021-08-18,2020-08-04
-3zze,2011-09-14,2011-08-31
-4zz2,2015-12-16,2015-05-22
-2zze,2009-07-21,2009-02-10
-2zzu,2009-03-24,2009-02-25
-5zzc,2018-06-13,2018-05-31
-1zz3,2005-11-29,2005-06-13
-6zzy,2021-07-28,2020-08-05
-5zz1,2019-05-29,2018-05-29
-4zz9,2015-07-29,2015-05-22
-6zzj,2021-08-18,2020-08-04
-1zzc,2005-07-26,2005-06-13
-7zz1,2022-10-12,2022-05-25
-7zzp,2022-09-21,2022-05-25
-5zzs,2019-06-19,2018-06-04
-6zz6,2020-09-30,2020-08-04
-1zz7,2005-07-26,2005-06-13
-7zzs,2022-09-21,2022-05-26
-4zzm,2015-05-27,2015-04-10
-7zzb,2023-01-11,2022-05-25
-1zzs,2005-12-06,2005-06-14
-4zze,2016-06-29,2015-05-22
-5zzq,2019-06-19,2018-06-04
-4zz6,2015-06-10,2015-05-22
-4zzb,2016-03-02,2015-05-22
-6zzw,2021-04-07,2020-08-05
-2zzd,2009-10-13,2009-02-09
-1zzh,2005-11-29,2005-06-14
-5zzr,2019-06-19,2018-06-04
-4zz1,2015-12-16,2015-05-22
-4zzn,2015-05-27,2015-04-10
-2zzc,2009-08-18,2009-02-09
-6zz9,2021-08-18,2020-08-04
-4zzz,2015-08-12,2015-04-15
-5zzw,2018-08-22,2018-06-04
-4zzj,2015-07-15,2015-05-22
-2zzx,2009-08-11,2009-02-27
-1zzr,2005-12-06,2005-06-14
-4zz7,2016-04-06,2015-05-22
-2zz0,2009-08-18,2009-02-02
-3zzq,2011-10-12,2011-09-02
-3zz5,2012-09-19,2011-08-31
-5zza,2018-10-10,2018-05-31
-2zz1,2009-03-24,2009-02-05
-5zzg,2018-10-03,2018-06-01
-3zza,2012-09-19,2011-08-31
-7zz2,2022-10-12,2022-05-25
-7zzk,2022-08-03,2022-05-25
-1zzu,2005-12-06,2005-06-14
-4zzc,2016-03-02,2015-05-22
-3zz1,2012-12-12,2011-08-31
-6zzq,2020-10-07,2020-08-05
-3zz9,2012-09-19,2011-08-31
-5zz4,2018-09-26,2018-05-30
-7zz6,2022-12-28,2022-05-25
-1zz8,2005-07-26,2005-06-13
-6zzx,2021-07-28,2020-08-05
-7zzt,2022-09-21,2022-05-26
-1zzl,2005-09-13,2005-06-14
-2zz7,2009-03-24,2009-02-05
-7zze,2023-01-11,2022-05-25
-2zzi,2010-01-05,2009-02-16
-1zzt,2005-12-06,2005-06-14
-2zza,2010-02-23,2009-02-06
-2zzg,2009-07-21,2009-02-10
-3zzn,2012-02-08,2011-09-02
-2zzl,2009-10-06,2009-02-18
-1zzq,2005-12-06,2005-06-14
-2zz5,2009-03-24,2009-02-05
-5zzx,2019-06-19,2018-06-04
-2zzn,2009-09-15,2009-02-19
-7zzi,2023-08-30,2022-05-25
-3zzf,2012-05-02,2011-09-01
-5zz6,2018-11-07,2018-05-30
-3zz8,2012-09-19,2011-08-31
-5zzz,2019-06-19,2018-06-05
-7zzh,2023-01-11,2022-05-25
-3zzs,2011-10-12,2011-09-02
-5zzn,2018-08-01,2018-06-03
-7zza,2023-01-11,2022-05-25
-2zzf,2009-07-21,2009-02-10
-2zzv,2009-08-11,2009-02-27
-4zzy,2015-08-12,2015-04-15
-4zzq,2016-04-13,2015-04-13
-1zzz,1999-06-15,1998-06-02
-4zz3,2015-12-16,2015-05-22
-1zz0,2005-11-29,2005-06-13
-1zzb,2005-07-26,2005-06-13
-3zzk,2011-12-28,2011-09-01
-7zz5,2022-10-12,2022-05-25
-4zzp,2016-04-13,2015-04-13
-5zz7,2018-11-07,2018-05-30
-7zzr,2022-09-21,2022-05-26
-4zzi,2015-07-15,2015-05-22
-4zzw,2015-09-23,2015-04-14
-7zz0,2022-10-12,2022-05-25
-1zzm,2005-06-28,2005-06-14
-5zzb,2018-10-10,2018-05-31
-6zzp,2020-10-07,2020-08-04
-7zzl,2023-04-12,2022-05-25
-7zz8,2022-10-12,2022-05-25
-6zzk,2021-08-18,2020-08-04
-1zzd,2006-03-07,2005-06-13
-4zzd,2015-08-26,2015-05-22
-2zz3,2009-03-24,2009-02-05
-7zzn,2022-07-20,2022-05-25
-2zzj,2009-05-05,2009-02-16
-5zzy,2019-06-19,2018-06-04
-7zzw,2022-09-21,2022-05-26
-2zz4,2009-03-24,2009-02-05
-1zzi,2005-08-09,2005-06-14
-7zzc,2023-01-11,2022-05-25
-2zzw,2009-08-11,2009-02-27
-3zz7,2012-09-19,2011-08-31
-3zzm,2011-09-28,2011-09-02
-5zze,2019-02-20,2018-06-01
-6zzu,2021-11-17,2020-08-05
-3zz6,2012-09-19,2011-08-31
-1zzj,2005-08-09,2005-06-14
-5zz0,2019-06-05,2018-05-29
-7zz3,2022-10-12,2022-05-25
-3zzh,2012-05-02,2011-09-01
-3zzj,2011-12-28,2011-09-01
-4zzv,2015-09-23,2015-04-14
-3zzy,2011-12-28,2011-09-06
-4zzh,2015-07-15,2015-05-22
-4zz8,2016-04-13,2015-05-22
-5zzf,2018-10-03,2018-06-01
-6zz2,2021-08-11,2020-08-03
-3zzz,2011-12-28,2011-09-06
-7zz4,2022-10-12,2022-05-25
-3zzr,2012-07-11,2011-09-02
-4zzo,2015-05-27,2015-04-10
-3zzv,2011-12-21,2011-09-05
-6zzs,2020-10-07,2020-08-05
-5zzu,2019-06-05,2018-06-04
-4zz0,2016-04-20,2015-05-22
-3zzc,2012-09-19,2011-08-31
-6zz3,2021-07-21,2020-08-03
-7zzo,2022-09-21,2022-05-25
-2zzb,2009-08-18,2009-02-09
-3zzd,2012-09-19,2011-08-31
-2zzm,2009-09-15,2009-02-19
-7zz9,2023-01-11,2022-05-25
-5zz2,2018-09-19,2018-05-29
-2zz6,2009-03-24,2009-02-05
-3zzl,2011-10-12,2011-09-01
-3zzb,2012-09-19,2011-08-31
-4zzt,2015-09-23,2015-04-14
-4zzx,2015-08-12,2015-04-15
-1zz1,2005-11-29,2005-06-13
-6zzt,2021-02-17,2020-08-05
-1zz2,2005-10-18,2005-06-13
-2zz2,2009-03-24,2009-02-05
-7zzj,2023-01-11,2022-05-25
-7zzq,2022-12-28,2022-05-26
-2zzs,2010-03-16,2009-02-24
-5zzp,2019-06-19,2018-06-04
-7goq,2023-11-29,2023-08-24
-6god,2019-02-06,2018-06-01
-8gom,2023-03-01,2022-08-25
-4got,2012-10-10,2012-08-20
-1gox,1989-10-15,1989-06-14
-6gov,2019-02-13,2018-06-04
-6gop,2018-08-01,2018-06-01
-2gou,2006-07-25,2006-04-14
-6go7,2019-06-05,2018-06-01
-5goz,2016-12-07,2016-07-30
-2go4,2006-07-04,2006-04-12
-6gok,2018-07-25,2018-06-01
-7go6,2023-11-29,2023-08-24
-7goi,2023-11-29,2023-08-24
-3gol,2009-06-16,2009-03-19
-3god,2009-06-30,2009-03-18
-2go7,2006-05-23,2006-04-12
-7gob,2023-11-29,2023-08-24
-8goj,2023-08-30,2022-08-25
-7gos,2023-11-29,2023-08-24
-8gon,2023-03-01,2022-08-25
-6goo,2018-07-11,2018-06-01
-1gon,2002-11-07,2001-10-22
-6got,2018-10-03,2018-06-04
-8goy,2023-08-02,2022-08-25
-5goc,2016-11-02,2016-07-26
-4go8,2013-08-21,2012-08-19
-6go2,2018-06-13,2018-06-01
-5gof,2017-01-25,2016-07-26
-3goa,2009-03-31,2009-03-18
-3goc,2009-03-31,2009-03-18
-6gof,2019-02-06,2018-06-01
-4go0,2013-01-23,2012-08-17
-3gob,2009-07-28,2009-03-18
-7goy,2023-11-29,2023-08-24
-3gor,2009-05-19,2009-03-19
-3go6,2010-03-31,2009-03-18
-7gou,2023-11-29,2023-08-24
-1gof,1994-01-31,1993-09-30
-4goj,2012-09-19,2012-08-20
-6go5,2019-06-05,2018-06-01
-4go4,2013-09-04,2012-08-18
-4go9,2013-08-21,2012-08-19
-3gon,2009-07-21,2009-03-19
-6goj,2018-07-25,2018-06-01
-3go2,2009-03-31,2009-03-18
-5goy,2017-08-02,2016-07-30
-4gow,2012-12-12,2012-08-20
-2gok,2006-04-25,2006-04-13
-2go3,2006-07-04,2006-04-12
-8go8,2023-05-17,2022-08-24
-5goa,2016-10-05,2016-07-26
-3go3,2009-03-31,2009-03-18
-6gon,2018-07-11,2018-06-01
-4gop,2012-11-28,2012-08-20
-3goi,2009-04-28,2009-03-19
-4gog,2013-07-24,2012-08-20
-7gom,2023-11-29,2023-08-24
-4go7,2012-09-05,2012-08-19
-1goh,1994-01-31,1993-09-30
-5goe,2017-01-25,2016-07-26
-4gom,2014-02-26,2012-08-20
-7gow,2023-11-29,2023-08-24
-3gos,2009-05-12,2009-03-19
-2goo,2006-05-09,2006-04-13
-6goc,2019-06-19,2018-06-01
-7go1,2023-11-29,2023-08-24
-4goo,2014-02-26,2012-08-20
-4gon,2014-02-26,2012-08-20
-4gol,2014-02-26,2012-08-20
-2goy,2006-09-19,2006-04-14
-5gom,2017-02-01,2016-07-27
-7gor,2023-11-29,2023-08-24
-6go4,2019-06-05,2018-06-01
-1goy,2001-11-29,2001-10-26
-3go9,2009-04-07,2009-03-18
-4gok,2012-09-19,2012-08-20
-7go5,2023-11-29,2023-08-24
-8gob,2023-06-14,2022-08-24
-3go7,2010-03-31,2009-03-18
-7goj,2023-11-29,2023-08-24
-8gof,2022-10-05,2022-08-24
-5gop,2016-11-02,2016-07-28
-8gou,2023-06-28,2022-08-25
-5go9,2016-10-05,2016-07-26
-1go8,2002-10-17,2001-10-20
-7gog,2023-11-29,2023-08-24
-7gol,2023-11-29,2023-08-24
-7go0,2023-11-29,2023-08-24
-7goo,2023-11-29,2023-08-24
-4gos,2012-09-12,2012-08-20
-7go8,2023-11-29,2023-08-24
-6gou,2019-01-02,2018-06-04
-6goi,2018-07-25,2018-06-01
-7got,2023-11-29,2023-08-24
-5gov,2016-12-21,2016-07-29
-6gog,2019-02-06,2018-06-01
-8goe,2022-10-05,2022-08-24
-8gol,2023-08-02,2022-08-25
-3gof,2010-03-31,2009-03-19
-7go4,2023-11-29,2023-08-24
-5gol,2017-09-06,2016-07-27
-3gox,2009-04-28,2009-03-20
-4gox,2012-10-17,2012-08-20
-7goe,2023-11-29,2023-08-24
-5goo,2016-11-02,2016-07-28
-6goh,2018-07-25,2018-06-01
-6gos,2019-01-30,2018-06-04
-7gof,2023-11-29,2023-08-24
-6gob,2018-07-25,2018-06-01
-7go3,2023-11-29,2023-08-24
-7goa,2023-11-29,2023-08-24
-7gon,2023-11-29,2023-08-24
-7god,2023-11-29,2023-08-24
-8goa,2023-06-14,2022-08-24
-8go3,2023-08-30,2022-08-24
-1got,1997-03-12,1996-08-07
-7gok,2023-11-29,2023-08-24
-7gox,2023-11-29,2023-08-24
-3go8,2009-12-15,2009-03-18
-3goe,2009-04-14,2009-03-19
-6gom,2019-02-06,2018-06-01
-7goc,2023-11-29,2023-08-24
-1gor,2001-12-07,2001-10-23
-1goj,2001-11-30,2001-10-21
-3goy,2009-04-14,2009-03-20
-3gok,2010-03-02,2009-03-19
-7gop,2023-11-29,2023-08-24
-7goz,2023-11-29,2023-08-24
-1gog,1994-01-31,1993-09-30
-7go2,2023-11-29,2023-08-24
-6go6,2019-06-05,2018-06-01
-2goj,2007-08-28,2006-04-13
-1gol,1997-03-12,1996-01-23
-7go7,2023-11-29,2023-08-24
-1goq,2001-12-07,2001-10-23
-3gou,2009-04-21,2009-03-20
-7go9,2023-11-29,2023-08-24
-5god,2016-11-02,2016-07-26
-5goq,2016-11-02,2016-07-28
-5gox,2017-02-01,2016-07-30
-1go7,2002-10-17,2001-10-20
-5go5,2017-03-15,2016-07-26
-5gon,2017-03-22,2016-07-28
-8god,2023-03-29,2022-08-24
-1go2,2002-10-17,2001-10-15
-4goa,2013-08-21,2012-08-19
-7goh,2023-11-29,2023-08-24
-4go2,2013-01-23,2012-08-18
-1go6,2002-06-13,2001-10-19
-7gov,2023-11-29,2023-08-24
-3go4,2009-04-14,2009-03-18
-1gos,2001-11-29,2001-10-26
-3goq,2010-03-31,2009-03-19
-6goe,2019-02-06,2018-06-01
-4goh,2013-08-21,2012-08-20
-6go1,2019-04-10,2018-06-01
-8ilg,2024-01-17,2023-03-03
-4il3,2013-02-20,2012-12-28
-8ilv,2023-09-06,2023-03-04
-5il3,2017-03-08,2016-03-04
-3ilr,2009-09-29,2009-08-07
-6ild,2019-02-27,2018-10-17
-6ilm,2019-05-15,2018-10-19
-5ilr,2016-09-21,2016-03-04
-8ild,2024-01-10,2023-03-03
-4ilc,2013-02-20,2012-12-29
-2ilt,2007-04-03,2006-10-03
-4il6,2013-03-06,2012-12-29
-8ilr,2023-08-30,2023-03-04
-3ilp,2010-01-26,2009-08-07
-6ilr,2019-03-13,2018-10-19
-3ilj,2010-08-11,2009-08-07
-4ilt,2013-05-15,2012-12-31
-3ild,2010-03-23,2009-08-07
-1il0,2001-11-07,2001-05-07
-1il4,2002-01-16,2001-05-07
-5ily,2017-03-08,2016-03-05
-4ilx,2013-02-13,2013-01-01
-6ili,2018-11-07,2018-10-18
-6ila,2019-10-23,2018-10-17
-4ild,2013-04-10,2012-12-30
-5ilw,2016-03-23,2016-03-05
-6ilt,2019-03-13,2018-10-19
-2ily,2006-12-12,2006-10-03
-8il4,2024-03-06,2023-03-01
-5ilc,2016-12-07,2016-03-04
-1il9,2002-01-16,2001-05-07
-1ils,1996-03-08,1995-10-12
-3il6,2009-08-25,2009-08-06
-1ilh,2001-06-27,2001-05-08
-4il9,2013-02-20,2012-12-29
-1il3,2002-01-16,2001-05-07
-3ilg,2010-08-11,2009-08-07
-3ilt,2009-09-15,2009-08-07
-4ilo,2014-01-01,2012-12-31
-4il1,2013-10-02,2012-12-28
-8ilh,2024-01-10,2023-03-03
-3il1,2009-09-15,2009-08-06
-4ila,2013-02-20,2012-12-29
-6ilq,2019-09-11,2018-10-19
-6ilz,2019-06-26,2018-10-21
-2il4,2006-10-17,2006-10-02
-4ilw,2013-11-13,2013-01-01
-4il4,2013-02-20,2012-12-29
-8ill,2023-10-04,2023-03-03
-8il8,2024-03-06,2023-03-03
-8il5,2024-03-06,2023-03-01
-3ile,2010-03-23,2009-08-07
-6ilg,2019-07-24,2018-10-18
-5ilg,2016-11-16,2016-03-04
-2il2,2006-12-05,2006-10-02
-1il5,2002-01-16,2001-05-07
-5ild,2017-03-08,2016-03-04
-5ile,2016-09-21,2016-03-03
-3ilq,2010-01-26,2009-08-07
-6ilh,2019-02-27,2018-10-18
-8ils,2023-09-13,2023-03-04
-5il8,2017-03-08,2016-03-04
-3il4,2009-08-25,2009-08-06
-6il2,2019-10-23,2018-10-16
-2ilu,2007-05-08,2006-10-03
-4ilv,2013-05-15,2013-01-01
-8ile,2024-01-10,2023-03-03
-2il5,2006-10-31,2006-10-02
-5il2,2016-05-25,2016-03-04
-6il0,2019-10-23,2018-10-16
-1il2,2001-09-28,2001-05-07
-5ilm,2016-09-21,2016-03-04
-8ili,2024-01-10,2023-03-03
-5ilx,2016-03-23,2016-03-05
-5ilo,2016-11-16,2016-03-04
-2ili,2007-06-05,2006-10-02
-4ilz,2013-03-27,2013-01-01
-6il3,2018-12-12,2018-10-16
-2ilv,2007-05-22,2006-10-03
-2ilm,2007-08-14,2006-10-03
-6ilf,2019-07-24,2018-10-17
-6ilb,2019-10-23,2018-10-17
-3iln,2010-08-18,2009-08-07
-5ili,2017-03-08,2016-03-04
-6ile,2019-07-24,2018-10-17
-3ilo,2010-08-11,2009-08-07
-4il2,2013-02-20,2012-12-28
-3il5,2009-08-25,2009-08-06
-4il5,2013-12-04,2012-12-29
-8ilq,2023-09-13,2023-03-04
-5ilf,2016-12-07,2016-03-04
-5il1,2016-05-25,2016-03-04
-6ilc,2019-07-24,2018-10-17
-1ilu,1996-03-08,1995-10-12
-3ilu,2009-09-15,2009-08-07
-8il9,2024-03-06,2023-03-03
-6ilw,2019-03-27,2018-10-19
-4ilk,2013-01-30,2012-12-31
-4ile,2014-01-01,2012-12-31
-1ile,1999-04-13,1998-02-24
-6ils,2019-03-13,2018-10-19
-8ilu,2024-03-06,2023-03-04
-6ilx,2019-03-27,2018-10-20
-4ilb,2013-02-20,2012-12-29
-8ila,2023-09-20,2023-03-03
-2ilz,2006-12-12,2006-10-03
-3ilz,2010-04-28,2009-08-07
-4il8,2013-08-14,2012-12-29
-8ilf,2024-01-17,2023-03-03
-3ilm,2009-09-22,2009-08-07
-6il9,2019-10-23,2018-10-17
-3ilf,2010-04-07,2009-08-07
-2ilp,2007-06-05,2006-10-03
-5ilp,2016-09-21,2016-03-04
-5ilh,2017-03-08,2016-03-04
-2feo,2006-01-10,2005-12-16
-7fe0,2021-09-01,2021-07-19
-2fet,2006-12-19,2005-12-16
-6fex,2018-11-28,2018-01-03
-8feg,2023-12-06,2022-12-06
-4feb,2013-03-13,2012-05-29
-4fe2,2013-05-29,2012-05-29
-5fem,2016-03-16,2015-12-17
-5fep,2016-04-06,2015-12-17
-1fea,1997-01-11,1995-07-12
-5fe3,2016-01-13,2015-12-16
-5feu,2016-06-08,2015-12-17
-3fea,2009-01-27,2008-11-28
-6fec,2018-03-14,2017-12-31
-8fev,2023-09-20,2022-12-06
-7fem,2021-12-15,2021-07-21
-1fe5,2001-01-24,2000-07-21
-3fep,2009-11-10,2008-11-30
-7fe6,2021-09-01,2021-07-19
-6feg,2018-02-21,2018-01-02
-7fep,2022-07-06,2021-07-21
-6feq,2018-04-11,2018-01-03
-3fe7,2009-01-27,2008-11-28
-3fei,2009-10-20,2008-11-30
-5fet,2016-01-13,2015-12-17
-1fej,2001-06-01,2000-07-21
-7fea,2022-07-27,2021-07-19
-4fea,2012-08-01,2012-05-29
-5fey,2016-05-18,2015-12-17
-6fek,2018-02-28,2018-01-02
-5fel,2016-05-25,2015-12-17
-8fem,2023-09-20,2022-12-06
-5few,2016-04-06,2015-12-17
-5fec,2016-05-04,2015-12-16
-1feb,1997-01-11,1995-07-12
-4fe1,2012-08-15,2012-05-29
-3fed,2009-08-25,2008-11-28
-5fe5,2016-01-13,2015-12-16
-3few,2009-01-27,2008-12-01
-4fe8,2013-03-13,2012-05-29
-4few,2012-06-20,2012-05-30
-5fej,2016-09-07,2015-12-17
-4fee,2012-06-20,2012-05-30
-3fej,2009-10-20,2008-11-30
-4fem,2012-08-29,2012-05-30
-4feg,2012-06-20,2012-05-30
-5fe7,2016-01-13,2015-12-16
-4fe9,2012-08-29,2012-05-29
-4fe7,2012-12-12,2012-05-29
-5fex,2016-04-06,2015-12-17
-1fe2,2001-05-02,2000-07-20
-8fe7,2023-08-09,2022-12-05
-5fer,2016-05-18,2015-12-17
-5fee,2016-07-27,2015-12-16
-7fe4,2021-11-10,2021-07-19
-2feq,2006-08-08,2005-12-16
-8fet,2023-09-20,2022-12-06
-1fez,2000-10-04,2000-07-24
-2fe4,2006-07-04,2005-12-15
-6fe1,2018-07-04,2017-12-28
-6fe5,2019-01-30,2017-12-29
-7fer,2022-07-06,2021-07-21
-7fev,2022-04-27,2021-07-21
-5fea,2016-01-13,2015-12-16
-6fe6,2019-01-30,2017-12-29
-6fe7,2019-04-10,2017-12-29
-4fe6,2012-07-18,2012-05-29
-8fe6,2023-08-09,2022-12-05
-1fem,1994-11-01,1994-08-29
-6fet,2019-04-24,2018-01-03
-7fek,2022-07-27,2021-07-21
-1feu,2001-06-25,2000-07-23
-4fer,2012-08-22,2012-05-30
-5fe8,2016-01-13,2015-12-16
-2feu,2006-03-14,2005-12-16
-6feb,2019-04-10,2017-12-31
-4fed,2013-03-13,2012-05-30
-4fey,2012-06-13,2012-05-30
-8feu,2023-09-20,2022-12-06
-2fe8,2006-03-21,2005-12-15
-3fe4,2008-12-16,2008-11-27
-6fer,2018-11-28,2018-01-03
-5feq,2016-07-27,2015-12-17
-4feh,2012-07-04,2012-05-30
-8fe0,2023-05-10,2022-12-05
-6fe3,2019-04-10,2017-12-28
-8fen,2023-09-20,2022-12-06
-2fe1,2005-12-27,2005-12-15
-8fe1,2023-03-22,2022-12-05
-4fe3,2012-08-29,2012-05-29
-1fee,2001-01-21,2000-07-21
-2fej,2006-01-31,2005-12-16
-5fen,2016-12-21,2015-12-17
-7feu,2022-07-27,2021-07-21
-8fec,2023-10-18,2022-12-06
-7few,2022-07-27,2021-07-22
-3fes,2008-12-16,2008-12-01
-3feh,2008-12-23,2008-11-29
-6feh,2018-02-21,2018-01-02
-7fe2,2022-02-02,2021-07-19
-4feu,2012-06-20,2012-05-30
-1fe8,2001-04-04,2000-07-21
-7feh,2022-07-27,2021-07-20
-7fet,2021-12-15,2021-07-21
-3feq,2008-12-16,2008-11-30
-6fe2,2018-07-04,2017-12-28
-4fex,2012-06-20,2012-05-30
-1feh,1999-01-13,1998-10-28
-3fef,2008-12-30,2008-11-28
-5fe9,2016-01-13,2015-12-16
-3fee,2009-08-25,2008-11-28
-3fe2,2008-12-16,2008-11-27
-8fe2,2023-10-18,2022-12-05
-1fen,1994-11-01,1994-08-29
-3fec,2009-08-25,2008-11-28
-4feq,2013-03-13,2012-05-30
-1fel,1994-11-01,1994-08-29
-3fe1,2008-12-16,2008-11-27
-1fe0,2001-01-20,2000-07-20
-1fec,1997-01-11,1995-07-12
-4fef,2012-10-24,2012-05-30
-1fe4,2001-01-24,2000-07-20
-4fev,2012-06-20,2012-05-30
-5fed,2016-07-27,2015-12-16
-5fes,2016-04-06,2015-12-17
-7fee,2022-06-15,2021-07-19
-6fel,2018-01-10,2018-01-02
-5fe0,2016-01-13,2015-12-16
-5fe6,2016-01-13,2015-12-16
-5fe4,2016-01-13,2015-12-16
-3feu,2009-01-20,2008-12-01
-2fes,2006-05-09,2005-12-16
-4fes,2013-06-12,2012-05-30
-8fe8,2023-10-18,2022-12-05
-5fe2,2016-01-13,2015-12-16
-3fe5,2009-06-09,2008-11-27
-5fez,2016-04-06,2015-12-17
-8fei,2023-02-08,2022-12-06
-2fea,2005-12-27,2005-12-15
-4fec,2013-03-13,2012-05-30
-5fe1,2016-01-13,2015-12-16
-7fe1,2022-02-02,2021-07-19
-6fe0,2018-07-04,2017-12-28
-8few,2023-09-20,2022-12-06
-8fe5,2023-10-18,2022-12-05
-3feg,2008-12-23,2008-11-29
-4fet,2012-07-25,2012-05-30
-8fe9,2023-03-29,2022-12-06
-5fek,2016-05-25,2015-12-17
-6few,2018-11-28,2018-01-03
-2fe6,2006-03-14,2005-12-15
-2fer,2006-03-14,2005-12-16
-2fe3,2006-12-19,2005-12-15
-6ekc,2017-12-06,2017-09-26
-1ekk,2000-08-09,2000-03-09
-5ek0,2015-12-23,2015-11-03
-6ek6,2018-03-14,2017-09-25
-6ekz,2018-12-12,2017-09-27
-8ek9,2023-05-31,2022-09-20
-3eku,2008-10-07,2008-09-19
-7ekw,2021-11-10,2021-04-07
-5ekl,2015-11-18,2015-11-03
-4eky,2012-07-25,2012-04-10
-1ek2,2000-05-31,2000-03-06
-7ekr,2022-04-13,2021-04-06
-3ek7,2008-12-16,2008-09-18
-4ekf,2012-10-10,2012-04-09
-7ekd,2022-02-16,2021-04-05
-5ekc,2016-11-16,2015-11-03
-8eko,2022-10-26,2022-09-21
-8ek5,2023-12-06,2022-09-20
-3ekd,2008-12-30,2008-09-19
-6eki,2018-04-11,2017-09-26
-8ekx,2023-11-08,2022-09-22
-8ekb,2022-12-21,2022-09-20
-8ekt,2023-08-02,2022-09-21
-5ekg,2016-02-10,2015-11-03
-4ekl,2012-05-23,2012-04-09
-4ekk,2012-05-23,2012-04-09
-6eku,2017-11-29,2017-09-27
-4ek7,2013-02-20,2012-04-09
-3ekx,2009-09-01,2008-09-19
-6ekh,2018-01-31,2017-09-26
-7ek7,2021-12-29,2021-04-04
-4ek1,2012-07-25,2012-04-08
-1eko,2000-05-10,2000-03-09
-5ek3,2015-12-23,2015-11-03
-8ekm,2023-09-27,2022-09-21
-3ekm,2009-02-17,2008-09-19
-1ekb,1999-10-14,1999-05-02
-3ekk,2008-12-23,2008-09-19
-4ekd,2013-01-30,2012-04-09
-1ekm,2000-08-23,2000-03-09
-6ekw,2018-12-12,2017-09-27
-3ek4,2008-12-16,2008-09-18
-3eko,2008-11-25,2008-09-19
-2ekt,2007-08-14,2007-03-25
-5ekd,2016-11-16,2015-11-03
-3ekq,2009-09-01,2008-09-19
-7ekh,2021-11-03,2021-04-05
-1ekj,2000-06-07,2000-03-08
-5eks,2015-12-02,2015-11-04
-2ek0,2007-09-25,2007-03-22
-3eki,2009-06-23,2008-09-19
-8ek3,2023-07-05,2022-09-19
-5ekf,2016-02-10,2015-11-03
-6ekk,2018-10-17,2017-09-26
-1ek3,2001-03-06,2000-03-06
-5eky,2016-05-04,2015-11-04
-2ek7,2007-09-25,2007-03-22
-8ekz,2023-07-05,2022-09-22
-5ekw,2016-10-05,2015-11-04
-2ekl,2008-03-25,2007-03-23
-6eke,2018-07-11,2017-09-26
-2ek2,2007-09-25,2007-03-22
-5ekv,2016-09-07,2015-11-04
-5ekb,2016-04-27,2015-11-03
-1ekf,2001-03-08,2000-03-08
-6ekx,2018-12-12,2017-09-27
-6eko,2018-10-10,2017-09-26
-6ekg,2018-01-31,2017-09-26
-3eka,2009-09-29,2008-09-19
-1ek6,2000-05-17,2000-03-06
-8ekg,2023-10-18,2022-09-20
-5ekn,2016-07-06,2015-11-03
-5eke,2016-01-06,2015-11-03
-7eke,2021-11-03,2021-04-05
-7ekl,2021-08-25,2021-04-05
-1ek8,2001-03-07,2000-03-07
-2ek8,2008-03-25,2007-03-22
-6ek3,2018-07-25,2017-09-25
-8ekc,2022-12-07,2022-09-20
-5ek9,2016-11-16,2015-11-03
-3ekg,2008-09-30,2008-09-19
-4ek9,2012-10-17,2012-04-09
-8ekv,2023-07-05,2022-09-22
-6eky,2018-12-12,2017-09-27
-2ekg,2008-04-01,2007-03-23
-8ek7,2022-09-28,2022-09-20
-4ekc,2013-01-30,2012-04-09
-7eki,2021-05-19,2021-04-05
-2eka,2007-09-25,2007-03-22
-5ek6,2016-11-16,2015-11-03
-7ekx,2021-11-10,2021-04-07
-3ekf,2008-12-30,2008-09-19
-2eku,2007-08-14,2007-03-25
-6ekn,2018-05-16,2017-09-26
-5eko,2016-07-06,2015-11-03
-3ekz,2009-02-10,2008-09-19
-1ek0,2000-04-17,2000-03-06
-8ekl,2023-09-27,2022-09-21
-3ekl,2009-02-10,2008-09-19
-7ek5,2021-12-29,2021-04-03
-3ekh,2008-12-16,2008-09-19
-4ekg,2012-10-17,2012-04-09
-7ekc,2021-11-03,2021-04-05
-3ekt,2009-09-01,2008-09-19
-5ek8,2015-12-23,2015-11-03
-5ek2,2015-12-23,2015-11-03
-3ek5,2008-12-23,2008-09-18
-4ek8,2013-05-01,2012-04-09
-6ek9,2018-08-08,2017-09-25
-1eky,2000-03-17,2000-03-10
-3ekv,2009-09-01,2008-09-19
-3ekw,2009-09-01,2008-09-19
-4eke,2012-07-25,2012-04-09
-4ekq,2012-09-05,2012-04-09
-2ek3,2007-09-25,2007-03-22
-3ekn,2008-12-30,2008-09-19
-3ekb,2008-12-30,2008-09-19
-6ekd,2018-08-08,2017-09-26
-7ekg,2021-11-03,2021-04-05
-4ekp,2012-09-05,2012-04-09
-8ekk,2023-09-27,2022-09-21
-5eku,2016-05-18,2015-11-04
-6ekb,2017-12-06,2017-09-26
-8ekn,2023-02-22,2022-09-21
-1ek1,2000-05-31,2000-03-06
-4ekr,2012-09-05,2012-04-09
-5ekm,2016-01-06,2015-11-03
-7ekp,2021-05-19,2021-04-06
-5ekh,2016-01-06,2015-11-03
-4ekn,2012-05-09,2012-04-09
-6eks,2017-11-29,2017-09-27
-5ekk,2015-11-18,2015-11-03
-7ekt,2021-05-19,2021-04-06
-7eka,2023-11-08,2021-04-05
-7ekf,2021-11-03,2021-04-05
-1ekx,2000-05-12,2000-03-09
-3eky,2009-09-01,2008-09-19
-4ek4,2013-05-01,2012-04-09
-2ek9,2008-03-25,2007-03-22
-1ekv,2001-03-09,2000-03-09
-8ekf,2022-10-19,2022-09-20
-7ekv,2022-02-16,2021-04-06
-5ekx,2016-10-26,2015-11-04
-1ekp,2001-03-09,2000-03-09
-5ek4,2015-12-23,2015-11-03
-5ekp,2016-01-06,2015-11-03
-4ek2,2012-05-09,2012-04-09
-6ekp,2019-01-30,2017-09-26
-2ekp,2008-04-01,2007-03-23
-3eks,2008-10-07,2008-09-19
-4ekv,2012-06-13,2012-04-09
-2ekb,2007-09-25,2007-03-22
-4eki,2012-10-17,2012-04-09
-5ekj,2016-01-06,2015-11-03
-3ek8,2008-12-16,2008-09-19
-6ek4,2018-05-16,2017-09-25
-3ek3,2008-10-14,2008-09-18
-2ek4,2007-09-25,2007-03-22
-3ekr,2008-11-25,2008-09-19
-6ekq,2018-06-27,2017-09-26
-7ek4,2021-12-29,2021-04-03
-1ek5,2000-05-17,2000-03-06
-3ekp,2009-09-01,2008-09-19
-8ekd,2024-02-21,2022-09-20
-4ek6,2013-05-01,2012-04-09
-4ek5,2013-05-01,2012-04-09
-4eks,2012-09-05,2012-04-09
-3aeb,2011-02-09,2010-02-04
-1aem,1997-09-04,1997-02-25
-5ae3,2015-09-09,2015-08-25
-6aex,2019-07-17,2018-08-06
-4ae1,2012-03-28,2012-01-04
-8aek,2022-10-12,2022-07-13
-5ae2,2015-09-09,2015-08-25
-1aeu,1997-09-04,1997-02-25
-3ae4,2011-02-09,2010-02-04
-8aed,2023-08-16,2022-07-13
-6aei,2019-08-07,2018-08-05
-5aeo,2015-03-25,2015-01-07
-1aet,1997-09-04,1997-02-25
-8aeh,2023-08-16,2022-07-13
-5aeh,2016-01-13,2015-08-31
-7ae4,2021-08-25,2020-09-17
-5aei,2016-03-30,2015-08-31
-6aee,2019-07-31,2018-08-04
-2aez,2006-08-29,2005-07-25
-5ae8,2015-09-16,2015-08-26
-7aei,2021-06-02,2020-09-17
-3ael,2011-02-09,2010-02-10
-2aet,2005-10-04,2005-07-23
-3aed,2011-02-09,2010-02-04
-2ael,2005-10-04,2005-07-22
-2ae8,2005-09-06,2005-07-21
-8aei,2023-08-16,2022-07-13
-7aey,2020-10-21,2020-09-18
-7aen,2021-07-28,2020-09-17
-3aee,2011-02-09,2010-02-04
-4aec,2012-02-22,2012-01-09
-7aez,2021-10-06,2020-09-18
-6aeh,2019-05-29,2018-08-04
-1aek,1997-09-04,1997-02-25
-4ael,2012-01-25,2012-01-11
-5aen,2015-02-11,2015-01-06
-5aeb,2015-09-16,2015-08-27
-4aed,2012-04-25,2012-01-09
-3ae9,2011-02-09,2010-02-04
-5aec,2015-09-09,2015-08-28
-3aex,2010-11-17,2010-02-13
-8ae5,2022-09-28,2022-07-12
-7ae5,2021-08-25,2020-09-17
-5aee,2016-02-10,2015-08-28
-2aec,2005-10-04,2005-07-22
-4aej,2012-09-12,2012-01-11
-8aez,2023-02-22,2022-07-14
-5aed,2016-02-10,2015-08-28
-7aev,2021-02-17,2020-09-18
-8aen,2023-06-21,2022-07-13
-1aee,1997-09-04,1997-02-24
-7aeu,2021-02-17,2020-09-18
-8aeu,2023-01-18,2022-07-13
-5ael,2015-10-28,2014-12-26
-1aeo,1997-09-04,1997-02-25
-1aer,1996-06-10,1995-12-11
-3aec,2011-02-09,2010-02-04
-7aeg,2021-07-07,2020-09-17
-7aeh,2021-07-07,2020-09-17
-1aef,1997-09-04,1997-02-24
-1aei,1997-08-20,1995-09-23
-1aex,1997-06-16,1997-03-01
-1aeq,1997-09-04,1997-02-25
-3ae5,2011-02-09,2010-02-04
-2aey,2006-08-29,2005-07-25
-3ae1,2011-02-09,2010-02-04
-7aeq,2021-09-01,2020-09-18
-1aes,1997-09-04,1997-02-25
-8ae1,2022-11-30,2022-07-12
-1aev,1997-09-04,1997-02-25
-8aem,2023-03-29,2022-07-13
-7aet,2021-02-17,2020-09-18
-4ae2,2012-09-12,2012-01-05
-3ae2,2011-02-09,2010-02-04
-8ae7,2023-03-29,2022-07-12
-3aen,2011-02-09,2010-02-10
-7ae3,2021-02-03,2020-09-17
-6ae9,2019-01-02,2018-08-03
-3aeo,2011-02-09,2010-02-10
-4ae3,2013-01-16,2012-01-05
-2aef,2005-10-25,2005-07-22
-1aeb,1997-09-04,1997-02-24
-7ae6,2020-12-30,2020-09-17
-5aeu,2016-04-06,2015-01-10
-1aeh,1997-09-04,1997-02-24
-5ae1,2015-09-09,2015-08-25
-6ae3,2018-09-19,2018-08-03
-3aeg,2011-02-09,2010-02-04
-2aek,2005-10-04,2005-07-22
-4aeo,2013-01-30,2012-01-11
-3aez,2010-05-26,2010-02-18
-1aec,1993-10-31,1992-02-05
-4ae4,2012-03-21,2012-01-06
-2aeq,2005-12-20,2005-07-23
-3ae0,2010-11-24,2010-01-31
-6ael,2019-03-06,2018-08-05
-8aec,2022-10-12,2022-07-12
-8aer,2023-04-05,2022-07-13
-8aev,2023-06-14,2022-07-13
-3ae3,2011-02-09,2010-02-04
-7aew,2020-11-04,2020-09-18
-2aep,2005-12-20,2005-07-23
-1aeg,1997-09-04,1997-02-24
-1aen,1997-09-04,1997-02-25
-1ae5,1998-03-11,1997-03-05
-3aeq,2010-04-21,2010-02-10
-8ae0,2022-10-26,2022-07-12
-7aer,2020-12-30,2020-09-18
-7ae9,2020-12-30,2020-09-17
-1aed,1997-09-04,1997-02-24
-8ae3,2022-10-26,2022-07-12
-1ae8,1997-12-03,1997-03-06
-3aej,2011-02-09,2010-02-10
-7ael,2021-03-10,2020-09-17
-6aea,2019-08-14,2018-08-04
-4aea,2012-01-25,2012-01-09
-7ae1,2021-02-03,2020-09-17
-2aes,2005-10-04,2005-07-23
-8ael,2023-08-16,2022-07-13
-3aep,2011-02-09,2010-02-10
-5aeq,2015-02-18,2015-01-08
-2ae7,2005-10-04,2005-07-21
-7aea,2021-02-03,2020-09-17
-7ae7,2021-08-25,2020-09-17
-8ae2,2022-10-26,2022-07-12
-3aea,2011-02-09,2010-02-04
-8ae8,2023-08-16,2022-07-12
-5aes,2015-04-01,2015-01-09
-5ae9,2015-09-16,2015-08-26
-3ae8,2011-02-09,2010-02-04
-5ae6,2016-09-21,2015-08-26
-8aeb,2023-03-15,2022-07-12
-1aej,1997-09-04,1997-02-25
-2aeb,2005-09-06,2005-07-21
-3aem,2011-02-09,2010-02-10
-8ae4,2022-09-28,2022-07-12
-8ae9,2023-08-16,2022-07-12
-2aer,2006-07-04,2005-07-23
-1aew,1997-09-04,1997-02-26
-6aem,2018-12-12,2018-08-05
-8aej,2023-08-16,2022-07-13
-3aek,2010-04-21,2010-02-10
-2aeo,2006-05-02,2005-07-23
-1ae1,1998-11-18,1997-10-23
-6aej,2019-06-19,2018-08-05
-5aeg,2016-02-10,2015-08-30
-3ae6,2011-02-09,2010-02-04
-5aew,2016-04-06,2015-01-10
-7aem,2021-04-07,2020-09-17
-6aef,2019-06-05,2018-08-04
-5aey,2015-04-22,2015-01-12
-7aes,2021-09-01,2020-09-18
-6aek,2019-03-06,2018-08-05
-3ae7,2011-02-09,2010-02-04
-5aer,2015-02-18,2015-01-08
-2aei,2006-08-01,2005-07-22
-2ae6,2005-09-06,2005-07-21
-3aef,2011-02-09,2010-02-04
-6aec,2019-05-29,2018-08-04
-5aep,2015-04-29,2015-01-08
-2ae2,1999-02-02,1999-01-26
-4ou3,2014-11-05,2014-02-14
-2oup,2007-03-20,2007-02-12
-7ou0,2022-01-12,2021-06-10
-8ous,2023-07-26,2023-04-24
-4oud,2015-01-28,2014-02-16
-8ou9,2023-11-15,2023-04-22
-4ous,2014-10-29,2014-02-18
-2oun,2007-03-20,2007-02-12
-7ou7,2021-12-22,2021-06-11
-7oug,2021-08-18,2021-06-11
-6oum,2020-05-06,2019-05-04
-7ouy,2021-12-22,2021-06-14
-8oup,2023-07-05,2023-04-24
-8our,2023-07-26,2023-04-24
-8ouu,2023-07-05,2023-04-24
-7ou5,2021-12-22,2021-06-11
-2ou9,2007-06-12,2007-02-09
-3ouf,2011-01-12,2010-09-14
-7oub,2021-12-01,2021-06-11
-7ouf,2021-08-18,2021-06-11
-8oui,2024-05-01,2023-04-23
-8ou6,2023-11-15,2023-04-21
-5ouc,2018-09-05,2017-08-23
-4ou9,2014-03-19,2014-02-15
-5ouq,2018-04-11,2017-08-24
-2ou8,2007-06-12,2007-02-09
-2ou7,2007-04-24,2007-02-09
-8out,2023-07-26,2023-04-24
-4oue,2014-02-26,2014-02-16
-4oub,2014-12-24,2014-02-15
-8ouh,2024-05-01,2023-04-23
-8oua,2023-11-15,2023-04-22
-5ouf,2018-09-05,2017-08-23
-5ouk,2018-05-09,2017-08-24
-2ouu,2007-03-20,2007-02-12
-8ou4,2023-11-15,2023-04-21
-6ouk,2020-05-06,2019-05-04
-5ouo,2018-04-11,2017-08-24
-3oum,2011-08-10,2010-09-15
-4oul,2014-10-29,2014-02-17
-7ouh,2021-08-18,2021-06-11
-1oup,2003-08-05,2003-03-25
-7oup,2021-08-11,2021-06-12
-7ouj,2021-11-03,2021-06-11
-2ouw,2007-03-06,2007-02-12
-5ou3,2018-03-28,2017-08-23
-8ouv,2023-07-05,2023-04-24
-1oum,2004-02-17,2003-03-24
-2ous,2007-03-20,2007-02-12
-8oud,2024-05-01,2023-04-22
-1our,2003-09-09,2003-03-25
-6oun,2019-07-24,2019-05-04
-1ouu,1997-01-11,1996-06-21
-7ou6,2022-04-13,2021-06-11
-7out,2021-12-08,2021-06-13
-8ouz,2023-06-21,2023-04-25
-3oua,2011-03-30,2010-09-14
-8oub,2024-05-01,2023-04-22
-8ou2,2024-05-01,2023-04-21
-4oui,2014-08-13,2014-02-17
-2oux,2007-03-20,2007-02-12
-7ou4,2022-01-12,2021-06-11
-3ouz,2010-10-13,2010-09-15
-6oug,2020-01-15,2019-05-04
-5oui,2017-11-29,2017-08-23
-5ou8,2018-09-05,2017-08-23
-7oua,2021-12-22,2021-06-11
-5oue,2018-02-28,2017-08-23
-6ouc,2019-06-26,2019-05-04
-3oud,2011-03-30,2010-09-14
-8oul,2024-05-01,2023-04-23
-3oue,2010-12-29,2010-09-14
-5ou1,2018-03-28,2017-08-23
-7oum,2021-12-29,2021-06-12
-7oux,2021-12-08,2021-06-14
-2ou6,2007-02-20,2007-02-09
-3ous,2011-01-12,2010-09-15
-3ou3,2011-03-30,2010-09-14
-2our,2007-03-20,2007-02-12
-8ouy,2023-06-21,2023-04-25
-4oug,2014-03-05,2014-02-17
-6ouo,2019-06-19,2019-05-05
-8ouj,2024-05-01,2023-04-23
-1ou6,2004-06-01,2003-03-24
-7oud,2021-11-03,2021-06-11
-8ouw,2023-08-16,2023-04-25
-3ou4,2011-03-30,2010-09-14
-7ou2,2022-01-12,2021-06-11
-6ouh,2020-05-06,2019-05-04
-3ou8,2010-10-13,2010-09-14
-4oua,2014-06-25,2014-02-15
-2ouz,2007-05-08,2007-02-12
-5ou0,2018-05-09,2017-08-23
-1ou9,2003-09-23,2003-03-24
-5oum,2018-02-28,2017-08-24
-3oub,2011-03-30,2010-09-14
-8ou5,2023-11-15,2023-04-21
-6ous,2019-10-30,2019-05-05
-7ouq,2021-11-17,2021-06-13
-6ouw,2019-07-03,2019-05-05
-8ou0,2023-07-05,2023-04-21
-3ou2,2010-10-27,2010-09-14
-1ou8,2003-09-23,2003-03-24
-6ouj,2020-05-06,2019-05-04
-3ouj,2010-12-01,2010-09-14
-7ouk,2021-12-29,2021-06-12
-3ouh,2010-12-01,2010-09-14
-7oun,2021-09-15,2021-06-12
-2oui,2008-02-12,2007-02-11
-4our,2014-07-16,2014-02-18
-1ouy,2003-09-02,2003-03-25
-3oui,2010-12-01,2010-09-14
-5ouj,2018-05-09,2017-08-24
-7ou9,2021-12-22,2021-06-11
-2oua,2007-02-20,2007-02-09
-7ou8,2022-04-13,2021-06-11
-1ouo,2003-08-05,2003-03-25
-1oux,2003-09-09,2003-03-25
-4ou8,2014-03-19,2014-02-15
-7oue,2022-06-22,2021-06-11
-6oud,2020-05-06,2019-05-04
-5ouh,2017-11-29,2017-08-23
-4ouc,2014-04-16,2014-02-15
-4ou4,2014-07-30,2014-02-15
-5oua,2018-09-05,2017-08-23
-6oui,2020-05-06,2019-05-04
-1ouq,2003-09-16,2003-03-25
-3ou1,2011-03-30,2010-09-14
-3ouc,2011-03-30,2010-09-14
-6ouf,2020-05-06,2019-05-04
-5ou2,2018-03-28,2017-08-23
-1ou4,2004-02-17,2003-03-24
-2ou4,2007-12-25,2007-02-09
-3oup,2011-10-26,2010-09-15
-2ouy,2007-03-20,2007-02-12
-3ouq,2010-12-29,2010-09-15
-3out,2010-09-29,2010-09-15
-6ouv,2019-07-03,2019-05-05
-5ou5,2018-12-12,2017-08-23
-6oul,2020-02-26,2019-05-04
-2ou3,2007-03-06,2007-02-09
-7ouc,2021-11-03,2021-06-11
-4ou2,2014-12-24,2014-02-14
-8ou3,2023-11-15,2023-04-21
-4ou1,2014-03-05,2014-02-14
-7oui,2021-08-18,2021-06-11
-2ou0,2007-08-07,2007-02-09
-3oun,2012-02-08,2010-09-15
-5oul,2018-02-28,2017-08-24
-3ou7,2010-10-27,2010-09-14
-1out,1997-01-11,1996-06-21
-8oum,2024-05-01,2023-04-24
-6oub,2020-05-06,2019-05-04
-8ouk,2024-05-01,2023-04-23
-3oul,2011-08-10,2010-09-15
-2oub,2007-02-27,2007-02-10
-6ou2,2019-07-03,2019-05-03
-2ouv,2007-03-20,2007-02-12
-6ou3,2019-07-03,2019-05-03
-4ouk,2014-08-27,2014-02-17
-8oun,2024-05-01,2023-04-24
-7oul,2021-12-29,2021-06-12
-5ouu,2018-02-28,2017-08-25
-6ou1,2019-07-03,2019-05-03
-5ou7,2018-09-05,2017-08-23
-4ouj,2014-06-04,2014-02-17
-2ou2,2007-02-27,2007-02-09
-7ouw,2021-12-08,2021-06-14
-7ou1,2021-11-24,2021-06-10
-8ou8,2023-07-12,2023-04-22
-8ou7,2023-11-15,2023-04-22
-2ou5,2007-03-06,2007-02-09
-1ouk,2003-09-02,2003-03-24
-5ou9,2018-09-05,2017-08-23
-6oue,2020-05-06,2019-05-04
-3ou6,2010-10-27,2010-09-14
-7ouz,2022-04-20,2021-06-14
-3ouu,2010-10-20,2010-09-15
-2ouq,2007-03-20,2007-02-12
-3ou9,2011-10-26,2010-09-14
-5oug,2017-12-20,2017-08-23
-8ouq,2024-05-01,2023-04-24
-5oup,2018-04-11,2017-08-24
-2eoi,2007-10-02,2007-03-29
-1eo5,2000-11-22,2000-03-22
-3eou,2009-09-15,2008-09-29
-5eod,2016-04-06,2015-11-10
-4eo3,2012-10-17,2012-04-13
-5eor,2016-03-02,2015-11-10
-7eo7,2021-10-20,2021-04-21
-3eok,2009-10-06,2008-09-28
-8eot,2023-02-01,2022-10-04
-4eos,2013-02-06,2012-04-14
-6eox,2018-05-16,2017-10-10
-5eob,2016-10-19,2015-11-10
-3eob,2009-04-14,2008-09-26
-4eo8,2012-06-27,2012-04-13
-3eoj,2009-05-12,2008-09-27
-2eoq,2007-10-02,2007-03-29
-5eou,2016-04-27,2015-11-10
-2eow,2007-10-02,2007-03-29
-1eoc,2000-08-09,2000-03-22
-1eom,2000-07-27,2000-03-23
-3eon,2008-10-21,2008-09-28
-6eo5,2018-04-18,2017-10-09
-9eo2,2024-05-22,2024-03-14
-5eox,2016-04-27,2015-11-10
-6eo0,2017-11-01,2017-10-08
-4eog,2013-01-02,2012-04-14
-7eo2,2022-01-05,2021-04-21
-2eo5,2007-10-02,2007-03-29
-6eom,2018-03-07,2017-10-10
-1eol,2000-05-03,2000-03-23
-4eok,2013-02-06,2012-04-14
-4eop,2013-02-06,2012-04-14
-1eoj,2000-05-03,2000-03-23
-6eo9,2017-12-13,2017-10-09
-7eo9,2021-12-29,2021-04-21
-8eo8,2024-03-27,2022-10-02
-1eoa,2000-08-09,2000-03-22
-2eov,2007-10-02,2007-03-29
-2eos,2007-10-02,2007-03-29
-2eol,2007-10-02,2007-03-29
-2eoe,2007-10-02,2007-03-29
-5eoh,2016-10-19,2015-11-10
-8eo6,2023-10-04,2022-10-02
-1eo3,2000-04-04,2000-03-21
-6eoj,2017-11-15,2017-10-09
-2eoo,2007-10-02,2007-03-29
-4eoo,2013-02-06,2012-04-14
-6eon,2017-11-29,2017-10-10
-1eo7,2000-11-22,2000-03-22
-2eof,2007-10-02,2007-03-29
-2eod,2008-04-01,2007-03-29
-4eoy,2013-02-20,2012-04-16
-5eoi,2016-11-23,2015-11-10
-8eoy,2023-10-11,2022-10-04
-1eow,2000-11-17,2000-03-24
-4eoc,2012-08-29,2012-04-13
-4eor,2013-02-06,2012-04-14
-7eoq,2021-06-30,2021-04-22
-3eo3,2008-10-07,2008-09-26
-6eoe,2017-11-01,2017-10-09
-1eou,2002-02-13,2000-03-24
-8eof,2023-02-01,2022-10-03
-3eos,2009-09-15,2008-09-29
-2eop,2007-10-02,2007-03-29
-8eog,2023-05-24,2022-10-03
-6eo8,2017-12-13,2017-10-09
-1eo8,2000-04-12,2000-03-22
-7eo4,2022-01-05,2021-04-21
-2eou,2007-10-02,2007-03-29
-4eol,2013-02-06,2012-04-14
-5eo0,2016-02-24,2015-11-10
-6eo6,2017-10-25,2017-10-09
-6eo1,2017-12-27,2017-10-08
-5eok,2016-04-06,2015-11-10
-2eox,2007-10-02,2007-03-29
-4eou,2012-04-25,2012-04-15
-6eol,2018-08-22,2017-10-09
-4eod,2012-08-29,2012-04-13
-8eop,2022-12-21,2022-10-04
-8eor,2023-05-03,2022-10-04
-5eoq,2016-03-02,2015-11-10
-4eom,2013-02-06,2012-04-14
-5eoy,2016-04-27,2015-11-10
-7eo5,2022-03-09,2021-04-21
-2eo4,2007-10-02,2007-03-29
-2eoj,2007-10-02,2007-03-29
-2eoz,2007-10-02,2007-03-29
-3eof,2008-10-14,2008-09-26
-8eos,2023-02-01,2022-10-04
-6eor,2018-02-07,2017-10-10
-6eow,2018-10-24,2017-10-10
-3eo7,2008-10-28,2008-09-26
-1eo2,2000-08-09,2000-03-21
-5eo8,2016-06-29,2015-11-10
-8eo2,2023-08-09,2022-10-01
-5eo7,2016-06-29,2015-11-10
-6eoi,2018-10-31,2017-10-09
-6eop,2018-02-07,2017-10-10
-5eot,2016-12-07,2015-11-10
-7eos,2021-06-30,2021-04-22
-4eon,2013-02-06,2012-04-14
-6eoa,2018-10-31,2017-10-09
-8eo1,2023-07-05,2022-10-01
-2eok,2007-10-02,2007-03-29
-4eoj,2013-02-06,2012-04-14
-8eo4,2023-07-05,2022-10-02
-6eoh,2018-10-31,2017-10-09
-1eob,2000-08-09,2000-03-22
-4eo1,2012-05-30,2012-04-13
-3eov,2008-11-11,2008-09-29
-5eow,2016-06-08,2015-11-10
-2eon,2007-10-02,2007-03-29
-6eok,2018-10-31,2017-10-09
-8eok,2023-08-30,2022-10-03
-2eor,2007-10-02,2007-03-29
-8eoi,2023-05-24,2022-10-03
-5eo2,2016-02-03,2015-11-10
-4eox,2012-05-30,2012-04-16
-6eod,2018-10-31,2017-10-09
-4eo7,2013-04-10,2012-04-13
-8eoc,2023-02-15,2022-10-03
-7eov,2021-05-05,2021-04-22
-4eoi,2013-02-06,2012-04-14
-3eoc,2008-11-04,2008-09-26
-8eob,2023-01-25,2022-10-02
-1eos,2000-08-30,2000-03-24
-4eof,2013-04-17,2012-04-14
-6eof,2017-11-01,2017-10-09
-6eoy,2021-10-06,2017-10-10
-6eog,2018-08-22,2017-10-09
-2eoh,2007-10-02,2007-03-29
-7eot,2021-06-30,2021-04-22
-1eo4,2000-04-04,2000-03-21
-7eoz,2022-08-24,2021-04-24
-2eom,2007-10-02,2007-03-29
-5eo9,2016-01-06,2015-11-10
-4eoq,2013-02-06,2012-04-14
-4eo4,2012-07-11,2012-04-13
-3eor,2009-08-25,2008-09-29
-8eoo,2023-06-14,2022-10-03
-7eob,2021-12-29,2021-04-21
-9eo5,2024-05-22,2024-03-14
-7eou,2021-06-30,2021-04-22
-1eo9,2000-08-09,2000-03-22
-6eo4,2018-04-18,2017-10-09
-6eo7,2017-10-18,2017-10-09
-8eoh,2023-08-02,2022-10-03
-5eom,2016-06-01,2015-11-10
-6eot,2018-02-07,2017-10-10
-6eoz,2018-04-04,2017-10-10
-3eo6,2008-10-07,2008-09-26
-4eoe,2012-08-29,2012-04-13
-4eoh,2012-05-02,2012-04-14
-5eoz,2016-11-23,2015-11-10
-4eo6,2012-06-27,2012-04-13
-3eo8,2008-11-04,2008-09-26
-5eo1,2016-02-24,2015-11-10
-7eox,2022-01-12,2021-04-24
-8eoa,2023-01-25,2022-10-02
-2eo7,2007-09-18,2007-03-29
-8eoe,2023-02-01,2022-10-03
-7eor,2021-06-30,2021-04-22
-7eo3,2022-03-02,2021-04-21
-2eoy,2007-10-02,2007-03-29
-2eog,2007-10-02,2007-03-29
-5eol,2016-05-04,2015-11-10
-7eo8,2021-10-20,2021-04-21
-5etw,2016-02-10,2015-11-18
-7ety,2022-05-11,2021-05-15
-7ets,2022-04-27,2021-05-13
-8ets,2023-07-19,2022-10-17
-3etj,2008-10-21,2008-10-08
-6et9,2018-03-14,2017-10-25
-1et0,2000-07-19,2000-04-12
-1etp,1997-02-12,1996-01-23
-1et8,2000-08-24,2000-04-12
-2etm,2006-10-10,2005-10-27
-7etw,2021-06-23,2021-05-14
-5etn,2016-05-04,2015-11-17
-5etb,2016-05-25,2015-11-17
-3ete,2009-06-09,2008-10-07
-7etf,2021-11-03,2021-05-12
-6et3,2018-07-04,2017-10-25
-3eth,2008-10-21,2008-10-08
-7et8,2021-11-03,2021-05-12
-6etu,2019-02-20,2017-10-27
-7ett,2022-02-23,2021-05-14
-3etm,2009-08-11,2008-10-08
-8etg,2022-11-30,2022-10-17
-6etf,2018-07-18,2017-10-26
-5etf,2016-10-26,2015-11-17
-6eth,2018-07-18,2017-10-26
-5eto,2016-05-04,2015-11-17
-7etu,2022-02-23,2021-05-14
-4eto,2012-07-11,2012-04-24
-8etb,2023-03-22,2022-10-16
-6etw,2019-02-20,2017-10-27
-8eth,2022-11-30,2022-10-17
-8et7,2023-05-31,2022-10-16
-7etb,2021-11-03,2021-05-12
-4etm,2012-10-24,2012-04-24
-4etk,2012-06-13,2012-04-24
-4et9,2012-06-13,2012-04-24
-6etj,2018-11-07,2017-10-26
-5etl,2016-05-04,2015-11-17
-8et9,2023-05-31,2022-10-16
-3etl,2009-05-05,2008-10-08
-4etw,2012-10-17,2012-04-24
-7etd,2021-11-03,2021-05-12
-8etk,2023-11-01,2022-10-17
-2et1,2005-11-22,2005-10-27
-7etg,2021-11-03,2021-05-12
-6et5,2018-04-11,2017-10-25
-8eto,2023-02-22,2022-10-17
-3etq,2009-06-23,2008-10-08
-1etj,1997-04-21,1997-01-11
-5et8,2016-11-23,2015-11-17
-5etz,2016-07-27,2015-11-18
-6etb,2018-11-07,2017-10-26
-3et2,2009-02-17,2008-10-06
-5etr,2016-05-04,2015-11-18
-8et4,2023-03-29,2022-10-16
-7etk,2021-12-01,2021-05-13
-8eti,2022-11-30,2022-10-17
-2etk,2005-11-08,2005-10-27
-7et7,2022-05-18,2021-05-12
-8etj,2022-11-30,2022-10-17
-5etj,2016-09-14,2015-11-17
-1etz,2000-10-18,2000-04-13
-5etd,2016-05-25,2015-11-17
-7eta,2021-11-03,2021-05-12
-8etm,2023-06-07,2022-10-17
-5etq,2016-05-04,2015-11-18
-8ete,2023-11-01,2022-10-17
-7etc,2021-11-03,2021-05-12
-7eth,2021-11-03,2021-05-12
-3et5,2008-10-14,2008-10-06
-3etn,2008-10-21,2008-10-08
-4etp,2012-06-27,2012-04-24
-3et4,2008-10-14,2008-10-06
-8ety,2023-11-01,2022-10-18
-6ets,2019-02-20,2017-10-27
-5ett,2016-05-04,2015-11-18
-8etf,2023-11-01,2022-10-17
-8etw,2023-07-19,2022-10-17
-3eto,2008-12-23,2008-10-08
-1et7,2000-08-24,2000-04-12
-7et1,2021-09-01,2021-05-12
-3ett,2008-11-25,2008-10-08
-4etl,2013-05-08,2012-04-24
-2et2,2006-06-13,2005-10-27
-8etl,2023-02-22,2022-10-17
-5ety,2016-06-22,2015-11-18
-6et4,2018-03-28,2017-10-25
-4etz,2012-07-25,2012-04-24
-1etu,1988-07-16,1988-01-15
-6etd,2018-07-18,2017-10-26
-6eti,2018-04-11,2017-10-26
-1ett,1994-01-31,1992-07-06
-5etk,2016-05-04,2015-11-17
-6etg,2019-02-20,2017-10-26
-1eth,1996-12-07,1995-09-13
-5etx,2016-01-13,2015-11-18
-3etg,2009-06-09,2008-10-07
-2etz,2006-02-07,2005-10-27
-5etp,2016-05-04,2015-11-17
-5et4,2016-11-30,2015-11-17
-7et9,2021-11-03,2021-05-12
-6ett,2019-02-20,2017-10-27
-7eti,2021-11-03,2021-05-12
-8etc,2022-11-30,2022-10-16
-8et3,2023-01-25,2022-10-16
-6et8,2018-08-15,2017-10-25
-4et0,2012-09-26,2012-04-23
-1ete,2000-06-14,2000-04-12
-8etz,2023-11-01,2022-10-18
-8etu,2023-07-19,2022-10-17
-2et7,2005-11-22,2005-10-27
-3eta,2009-05-26,2008-10-07
-8et6,2023-05-31,2022-10-16
-2etj,2005-11-08,2005-10-27
-6ete,2019-02-20,2017-10-26
-1ets,1994-01-31,1992-07-06
-2etf,2005-12-06,2005-10-27
-8et5,2023-03-29,2022-10-16
-3et7,2009-06-23,2008-10-07
-4ets,2012-06-20,2012-04-24
-5etv,2016-05-04,2015-11-18
-8etd,2022-12-07,2022-10-16
-3ets,2008-11-25,2008-10-08
-5eth,2016-04-27,2015-11-17
-4etc,2012-06-13,2012-04-24
-7ete,2021-11-03,2021-05-12
-2ete,2005-11-22,2005-10-27
-3etc,2009-07-07,2008-10-07
-4et8,2012-06-13,2012-04-24
-8etr,2022-11-02,2022-10-17
-1eta,1995-01-26,1993-05-12
-3et3,2009-02-17,2008-10-06
-3et1,2009-02-17,2008-10-06
-3etr,2009-01-27,2008-10-08
-8etp,2023-08-02,2022-10-17
-2etv,2006-02-07,2005-10-27
-8etx,2023-11-01,2022-10-18
-7etl,2021-12-01,2021-05-13
-3etd,2009-06-09,2008-10-07
-1et5,2000-08-24,2000-04-12
-5etm,2016-05-04,2015-11-17
-1et1,2000-09-06,2000-04-12
-6ety,2018-11-07,2017-10-27
-6etv,2019-02-27,2017-10-27
-6et7,2018-06-13,2017-10-25
-1etr,1994-01-31,1992-07-06
-5etu,2016-10-26,2015-11-18
-1etb,1995-01-26,1993-05-12
-5ets,2016-05-04,2015-11-18
-5et6,2016-04-13,2015-11-17
-8et0,2023-10-18,2022-10-15
-5et3,2016-05-04,2015-11-17
-3et0,2009-02-17,2008-10-06
-2etr,2005-11-08,2005-10-27
-6etz,2018-01-10,2017-10-27
-7etv,2022-02-23,2021-05-14
-8et8,2023-05-31,2022-10-16
-4xaf,2015-12-16,2014-12-14
-2xa9,2011-03-16,2010-03-30
-4xae,2015-06-10,2014-12-14
-6xaj,2021-06-09,2020-06-04
-1xau,2004-10-05,2004-08-26
-1xaj,2005-03-01,2004-08-25
-1xaf,2004-08-31,2004-08-25
-8xax,2024-06-05,2023-12-05
-4xa7,2015-03-18,2014-12-12
-6xaq,2021-06-02,2020-06-04
-1xah,2005-03-01,2004-08-25
-2xah,2010-05-05,2010-03-31
-8xaw,2024-06-05,2023-12-05
-5xai,2017-06-28,2017-03-13
-4xag,2015-12-16,2014-12-14
-2xat,1998-06-17,1998-03-11
-8xay,2024-06-05,2023-12-05
-2xas,2010-05-05,2010-03-31
-6xat,2021-06-09,2020-06-04
-4xad,2014-12-31,2014-12-14
-1xa6,2004-11-23,2004-08-25
-4xaj,2015-03-04,2014-12-14
-7xay,2022-05-18,2022-03-19
-5xa1,2017-04-19,2017-03-10
-2xa5,2011-04-06,2010-03-26
-2xaq,2010-05-05,2010-03-31
-4xar,2015-02-11,2014-12-15
-1xa8,2004-11-23,2004-08-25
-4xaa,2015-08-05,2014-12-13
-7xar,2022-11-09,2022-03-18
-6xa8,2021-03-24,2020-06-04
-6xav,2020-12-16,2020-06-04
-5xa4,2017-12-06,2017-03-10
-4xab,2015-08-05,2014-12-13
-5xa7,2017-05-17,2017-03-11
-5xag,2018-01-03,2017-03-12
-2xad,2011-03-02,2010-03-31
-2xao,2010-05-19,2010-03-31
-5xat,2017-06-14,2017-03-14
-6xar,2021-03-03,2020-06-04
-7xaz,2022-07-06,2022-03-19
-2xag,2010-05-05,2010-03-31
-5xas,2017-06-14,2017-03-14
-1xa5,2004-12-21,2004-08-25
-2xau,2010-06-09,2010-03-31
-2xa4,2010-12-15,2010-03-26
-6xa9,2020-06-17,2020-06-04
-6xae,2020-06-17,2020-06-04
-2xa7,2010-07-21,2010-03-29
-6xa1,2020-10-07,2020-06-03
-4xav,2015-07-15,2014-12-15
-2xar,2010-05-19,2010-03-31
-1xal,2005-03-01,2004-08-26
-5xa9,2017-06-14,2017-03-11
-6xaa,2020-06-17,2020-06-04
-4xak,2015-08-26,2014-12-15
-7xat,2022-08-31,2022-03-19
-5xa8,2017-05-17,2017-03-11
-5xau,2017-09-20,2017-03-15
-4xas,2015-02-04,2014-12-15
-2xae,2011-03-30,2010-03-31
-4xai,2015-03-04,2014-12-14
-5xab,2017-06-07,2017-03-11
-8xam,2024-02-28,2023-12-04
-6xa7,2021-03-24,2020-06-04
-5xar,2017-06-14,2017-03-14
-6xac,2021-06-02,2020-06-04
-6xa4,2020-06-17,2020-06-03
-1xa7,2004-09-21,2004-08-25
-5xal,2018-03-14,2017-03-14
-7xau,2022-08-31,2022-03-19
-1xai,2005-03-01,2004-08-25
-6xa6,2021-03-24,2020-06-04
-6xa0,2021-06-09,2020-06-03
-6xa5,2021-06-02,2020-06-03
-4xaq,2015-02-04,2014-12-15
-4xay,2015-12-16,2014-12-16
-6xa2,2021-06-09,2020-06-03
-7xa7,2022-12-21,2022-03-17
-1xap,2004-11-16,2004-08-26
-4xat,2015-07-15,2014-12-15
-2xa2,2011-03-16,2010-03-26
-4xac,2015-08-05,2014-12-13
-7xa9,2023-03-22,2022-03-17
-2xaf,2010-05-05,2010-03-31
-7xaf,2022-06-01,2022-03-17
-6xai,2021-06-09,2020-06-04
-7xa4,2023-02-15,2022-03-17
-1xa4,2004-11-16,2004-08-25
-7xax,2023-03-22,2022-03-19
-4xau,2014-12-24,2014-12-15
-7xa1,2023-03-22,2022-03-16
-6xak,2021-06-09,2020-06-04
-1xar,2004-11-16,2004-08-26
-6xa3,2021-06-23,2020-06-03
-5xaf,2017-12-20,2017-03-12
-4xaz,2015-12-16,2014-12-16
-4xa2,2016-01-20,2014-12-12
-7xab,2023-02-22,2022-03-17
-7xav,2022-08-31,2022-03-19
-6xal,2021-06-09,2020-06-04
-8xa9,2024-03-20,2023-12-03
-5xak,2018-03-14,2017-03-14
-5xa3,2018-02-21,2017-03-10
-5xaa,2017-05-24,2017-03-11
-7xam,2023-05-03,2022-03-18
-6xaf,2021-06-09,2020-06-04
-2xab,2010-08-11,2010-03-30
-1xag,2005-03-01,2004-08-25
-1xan,1996-07-11,1996-01-26
-5xao,2017-06-28,2017-03-14
-4xa5,2016-02-10,2014-12-12
-6xas,2020-12-16,2020-06-04
-6xam,2021-06-09,2020-06-04
-7xa2,2023-02-15,2022-03-16
-2xaj,2010-05-05,2010-03-31
-2xaa,2010-08-11,2010-03-30
-7xaa,2023-02-22,2022-03-17
-4xal,2015-06-24,2014-12-15
-2xan,2010-05-19,2010-03-31
-4yhb,2015-07-15,2015-02-27
-4yho,2016-01-13,2015-02-27
-5yhw,2018-10-17,2017-09-30
-2yhe,2012-05-16,2011-04-29
-7yh2,2023-07-19,2022-07-12
-2yhh,2011-06-15,2011-05-02
-5yh2,2018-04-11,2017-09-27
-1yhr,2005-01-18,2005-01-10
-6yh8,2021-04-07,2020-03-28
-7yhh,2023-07-19,2022-07-13
-4yhq,2015-06-10,2015-02-27
-2yh1,2011-07-20,2011-04-26
-4yhy,2016-02-10,2015-02-27
-2yhn,2011-06-29,2011-05-04
-4yh6,2015-05-06,2015-02-27
-2yhg,2011-08-03,2011-04-30
-5yhr,2018-02-07,2017-09-29
-7yh3,2023-07-19,2022-07-12
-1yh8,2005-02-15,2005-01-07
-5yh3,2018-04-25,2017-09-27
-2yhi,2012-05-23,2011-05-03
-7yhd,2023-06-07,2022-07-13
-8yhh,2024-03-13,2024-02-28
-6yhq,2021-04-14,2020-03-30
-5yhl,2018-12-05,2017-09-28
-5yhb,2017-11-29,2017-09-27
-4yh8,2015-08-12,2015-02-27
-6yhb,2021-04-07,2020-03-28
-6yh1,2020-04-08,2020-03-28
-5yh8,2018-03-28,2017-09-27
-4yh4,2016-01-13,2015-02-26
-1yhm,2005-12-20,2005-01-09
-6yha,2021-04-07,2020-03-28
-5yh7,2017-10-11,2017-09-27
-1yho,2005-11-22,2005-01-10
-6yhe,2020-04-08,2020-03-29
-6yhv,2020-11-04,2020-03-31
-5yhv,2018-10-10,2017-09-30
-7yhc,2023-06-07,2022-07-13
-7yh6,2023-07-19,2022-07-12
-4yhg,2015-07-15,2015-02-27
-6yh0,2020-07-29,2020-03-28
-4yhh,2015-04-08,2015-02-27
-6yhj,2021-04-14,2020-03-30
-4yhk,2016-01-13,2015-02-27
-7yhb,2023-06-07,2022-07-13
-6yhn,2020-12-30,2020-03-30
-5yhz,2017-12-06,2017-10-01
-6yhr,2020-04-29,2020-03-30
-7yhn,2023-07-26,2022-07-14
-4yhf,2015-05-13,2015-02-27
-7yh7,2023-07-19,2022-07-13
-6yh9,2021-04-07,2020-03-28
-4yhx,2016-03-09,2015-02-27
-7yh5,2023-07-19,2022-07-12
-4yh3,2016-01-13,2015-02-26
-5yhy,2017-12-06,2017-10-01
-7yhg,2023-07-19,2022-07-13
-6yh2,2020-04-08,2020-03-28
-1yhj,2005-07-05,2005-01-09
-6yh7,2021-04-07,2020-03-28
-6yhc,2021-04-07,2020-03-28
-7yhw,2023-07-19,2022-07-14
-1yhz,2006-01-17,2005-01-10
-4yh7,2015-05-06,2015-02-27
-1yh9,2005-01-18,2005-01-07
-4yhz,2016-02-10,2015-02-27
-7yhe,2023-07-19,2022-07-13
-4yha,2015-07-01,2015-02-27
-4yhm,2016-01-13,2015-02-27
-5yh1,2018-08-01,2017-09-27
-1yhs,2005-01-25,2005-01-10
-4yht,2016-03-16,2015-02-27
-1yhl,2005-12-20,2005-01-09
-2yhu,2012-05-23,2011-05-06
-4yh0,2016-03-02,2015-02-26
-2yho,2011-06-29,2011-05-04
-6yh6,2021-04-07,2020-03-28
-7yh4,2023-08-02,2022-07-12
-1yhn,2005-05-17,2005-01-10
-6yh3,2020-04-08,2020-03-28
-8yhw,2024-03-13,2024-02-28
-6yhm,2020-12-30,2020-03-30
-6yhd,2020-04-08,2020-03-28
-4yhj,2015-07-08,2015-02-27
-4yh5,2015-09-16,2015-02-26
-6yhw,2020-05-06,2020-03-31
-2yhy,2012-02-29,2011-05-10
-1yhy,2006-01-17,2005-01-10
-7yh9,2023-06-07,2022-07-13
-2yhk,2012-05-02,2011-05-03
-5yha,2017-11-29,2017-09-27
-4yh2,2016-02-10,2015-02-26
-7yhi,2023-07-19,2022-07-13
-2yhw,2012-02-29,2011-05-08
-5yht,2018-05-23,2017-09-29
-5yho,2018-10-10,2017-09-29
-5yhx,2017-12-06,2017-10-01
-4yhi,2016-01-13,2015-02-27
-4yh1,2015-09-16,2015-02-26
-1yhc,2005-02-15,2005-01-07
-5yhe,2018-03-28,2017-09-28
-6yh5,2021-04-07,2020-03-28
-7yhk,2022-08-17,2022-07-13
-2yhd,2011-09-21,2011-04-28
-7yh8,2023-07-19,2022-07-13
-6yhg,2021-04-07,2020-03-29
-5yhg,2018-03-28,2017-09-28
-1yhq,2005-04-26,2005-01-10
-6yhs,2020-09-16,2020-03-30
-7yha,2023-06-07,2022-07-13
-5yhj,2017-12-06,2017-09-28
-6yh4,2021-04-07,2020-03-28
-4yhu,2015-07-22,2015-02-27
-1yhu,2005-02-08,2005-01-10
-1yhe,2005-01-18,2005-01-07
-7yh1,2023-07-19,2022-07-12
-2yhx,1978-05-23,1978-03-20
-2xm9,2011-01-12,2010-07-26
-7xmt,2022-08-03,2022-04-26
-7xmg,2022-11-30,2022-04-25
-2xm3,2010-10-13,2010-07-22
-4xmh,2015-07-29,2015-01-14
-4xmt,2016-03-02,2015-01-15
-7xm4,2022-07-06,2022-04-24
-7xmj,2023-05-31,2022-04-26
-5xm5,2017-05-31,2017-05-12
-2xmg,2010-12-01,2010-07-27
-5xmh,2018-03-21,2017-05-15
-1xmv,2005-01-04,2004-10-04
-1xma,2004-12-14,2004-10-01
-7xml,2022-07-27,2022-04-26
-1xmy,2004-12-14,2004-10-04
-7xm0,2023-04-26,2022-04-23
-7xmx,2022-11-23,2022-04-27
-1xmg,2005-01-18,2004-10-02
-2xm0,2010-11-10,2010-07-22
-7xm9,2022-11-30,2022-04-25
-2xmt,2010-08-18,2010-07-29
-8xmn,2024-03-06,2023-12-27
-4xmg,2015-07-29,2015-01-14
-2xmw,2010-08-18,2010-07-29
-4xm0,2015-06-10,2015-01-14
-1xm4,2004-12-14,2004-10-01
-4xm2,2015-06-10,2015-01-14
-1xm5,2004-10-12,2004-10-01
-4xm5,2015-03-25,2015-01-14
-7xme,2023-05-03,2022-04-25
-7xmb,2022-12-21,2022-04-25
-7xmk,2023-04-26,2022-04-26
-4xmd,2015-07-29,2015-01-14
-1xmj,2004-11-09,2004-10-02
-7xmn,2023-05-31,2022-04-26
-2xmo,2011-02-23,2010-07-28
-6xmq,2020-09-23,2020-06-30
-1xme,2005-03-22,2004-10-01
-4xme,2015-07-29,2015-01-14
-2xm7,2010-10-27,2010-07-25
-4xmo,2015-03-11,2015-01-14
-5xm3,2018-03-21,2017-05-12
-5xmq,2017-11-29,2017-05-16
-7xmf,2022-11-30,2022-04-25
-1xm8,2004-10-12,2004-10-01
-6xmc,2021-07-07,2020-06-30
-5xmo,2018-05-16,2017-05-16
-4xmu,2016-03-02,2015-01-15
-6xmr,2020-07-15,2020-06-30
-7xm3,2022-07-06,2022-04-24
-5xm7,2018-06-20,2017-05-12
-2xmm,2010-08-25,2010-07-28
-7xma,2022-12-21,2022-04-25
-6xmu,2020-09-23,2020-06-30
-6xm3,2020-08-12,2020-06-29
-4xmy,2016-01-27,2015-01-15
-2xmp,2010-10-13,2010-07-29
-4xmz,2016-01-27,2015-01-15
-1xmq,2004-12-14,2004-10-04
-7xm2,2022-07-06,2022-04-24
-4xm8,2015-11-11,2015-01-14
-4xm1,2015-06-10,2015-01-14
-1xmu,2004-12-14,2004-10-04
-8xmm,2024-03-06,2023-12-27
-2xml,2010-09-29,2010-07-28
-7xmw,2023-05-31,2022-04-27
-6xmx,2020-11-25,2020-07-01
-1xmi,2004-11-09,2004-10-02
-5xmf,2017-12-13,2017-05-15
-1xmh,2005-01-18,2004-10-02
-4xmf,2015-07-29,2015-01-14
-1xms,2005-01-04,2004-10-04
-5xmr,2017-11-29,2017-05-16
-5xmx,2018-05-23,2017-05-16
-2xmf,2011-08-10,2010-07-27
-6xmg,2021-01-13,2020-06-30
-6xm5,2020-07-29,2020-06-29
-4xmv,2016-02-10,2015-01-15
-1xmo,2004-12-14,2004-10-04
-2xmv,2010-08-18,2010-07-29
-5xms,2017-11-29,2017-05-16
-2xmk,2010-08-25,2010-07-28
-2xm2,2011-08-03,2010-07-22
-5xmk,2017-08-09,2017-05-15
-7xmv,2022-06-29,2022-04-27
-5xmy,2018-11-28,2017-05-16
-6xmy,2020-07-22,2020-07-01
-1xm1,2005-05-10,2004-10-01
-4xm7,2015-11-11,2015-01-14
-2xmu,2010-08-18,2010-07-29
-6xm0,2020-08-12,2020-06-29
-4xmx,2016-02-10,2015-01-15
-6xm7,2021-05-12,2020-06-29
-4xma,2016-02-03,2015-01-14
-1xmf,2005-01-18,2004-10-02
-7xmu,2022-06-29,2022-04-26
-1xmx,2004-11-16,2004-10-04
-6xma,2021-05-12,2020-06-29
-6xm6,2021-05-12,2020-06-29
-2xmj,2010-08-25,2010-07-28
-8xmi,2024-04-03,2023-12-27
-7xmc,2022-12-21,2022-04-25
-5xmz,2017-07-05,2017-05-17
-2xm1,2011-08-03,2010-07-22
-7xm5,2022-07-06,2022-04-24
-5xmp,2017-11-29,2017-05-16
-4xmc,2015-07-29,2015-01-14
-4xmp,2015-04-29,2015-01-15
-2xmr,2011-01-19,2010-07-29
-7xmz,2022-11-23,2022-04-27
-4xmr,2015-11-04,2015-01-15
-4xmb,2015-09-30,2015-01-14
-5xmu,2017-11-29,2017-05-16
-2xm8,2011-01-12,2010-07-26
-5xmi,2017-08-09,2017-05-15
-2xmc,2010-12-01,2010-07-27
-6xm4,2020-08-12,2020-06-29
-6xm8,2021-05-12,2020-06-29
-4xm6,2015-11-11,2015-01-14
-8xmh,2024-04-03,2023-12-27
-4xmw,2016-02-10,2015-01-15
-1xmk,2005-08-02,2004-10-03
-6xmk,2020-07-08,2020-06-30
-6xmf,2021-01-13,2020-06-30
-7xm1,2023-01-04,2022-04-24
-7xmd,2022-12-21,2022-04-25
-5xmv,2017-11-29,2017-05-16
-2xmy,2010-11-10,2010-07-29
-2xm4,2010-11-10,2010-07-23
-7xm7,2022-06-22,2022-04-25
-6xms,2020-09-23,2020-06-30
-6xmt,2020-09-23,2020-06-30
-5xmm,2017-12-13,2017-05-15
-5xmt,2017-11-29,2017-05-16
-8xmo,2024-03-06,2023-12-27
-4xm3,2016-01-27,2015-01-14
-1xmm,2005-03-22,2004-10-04
-2xma,2010-10-13,2010-07-26
-6xm9,2021-05-12,2020-06-29
-1xm6,2004-12-14,2004-10-01
-5xmj,2018-06-06,2017-05-15
-7zo4,2023-03-08,2022-04-24
-2zoi,2009-03-24,2008-05-21
-3zod,2014-05-14,2013-02-21
-1zoh,2005-11-29,2005-05-13
-3zoe,2014-05-14,2013-02-21
-1zoy,2005-07-12,2005-05-15
-3zoc,2014-05-14,2013-02-21
-6zo8,2021-05-19,2020-07-07
-7zo7,2023-03-08,2022-04-24
-2zon,2009-06-09,2008-05-27
-2zo3,2009-04-14,2008-05-05
-5zob,2018-10-17,2018-04-12
-2zof,2008-06-10,2008-05-14
-6zox,2020-07-22,2020-07-08
-4zob,2016-05-18,2015-05-06
-4zoe,2016-05-18,2015-05-06
-4zog,2016-09-14,2015-05-06
-6zo7,2021-05-19,2020-07-07
-1zob,2006-08-08,2005-05-12
-5zoo,2018-11-14,2018-04-13
-2zoq,2009-04-07,2008-06-01
-6zod,2021-05-19,2020-07-07
-2zoo,2009-06-09,2008-05-27
-5zol,2019-06-12,2018-04-13
-6zo2,2020-12-23,2020-07-07
-7zok,2023-02-22,2022-04-25
-4zof,2016-05-11,2015-05-06
-3zog,2014-05-14,2013-02-21
-7zon,2023-05-10,2022-04-26
-4zop,2016-05-18,2015-05-06
-6zor,2021-01-20,2020-07-07
-3zou,2014-03-12,2013-02-25
-3zoo,2013-10-23,2013-02-22
-3zom,2014-03-12,2013-02-22
-6zou,2021-05-19,2020-07-07
-7zo2,2023-03-08,2022-04-24
-5zog,2019-01-30,2018-04-13
-5zod,2019-01-30,2018-04-13
-3zok,2013-08-21,2013-02-22
-3zoi,2013-06-26,2013-02-21
-3zos,2013-05-01,2013-02-22
-4zok,2016-05-11,2015-05-06
-7zo3,2023-03-08,2022-04-24
-6zon,2020-07-29,2020-07-07
-4zoa,2016-05-18,2015-05-06
-1zot,2005-08-09,2005-05-13
-4zo2,2015-07-15,2015-05-05
-6zo5,2021-05-19,2020-07-07
-6zo3,2020-12-23,2020-07-07
-3zol,2014-03-12,2013-02-22
-5zo2,2019-01-30,2018-04-12
-5zoh,2019-04-17,2018-04-13
-1zo9,2006-08-01,2005-05-12
-1zog,2005-11-29,2005-05-13
-1zoe,2005-11-29,2005-05-13
-6zo1,2020-12-23,2020-07-07
-2zoz,2008-07-08,2008-06-20
-7zoo,2023-05-10,2022-04-26
-2zol,2008-06-10,2008-05-22
-4zo9,2016-05-18,2015-05-06
-1zov,2006-05-23,2005-05-14
-6zoh,2021-05-19,2020-07-07
-7zoq,2022-11-30,2022-04-26
-4zo1,2015-09-02,2015-05-05
-6zoo,2021-06-16,2020-07-07
-7zog,2022-09-07,2022-04-25
-2zoe,2008-12-02,2008-05-09
-6zo4,2020-07-29,2020-07-07
-3zo0,2013-05-22,2013-02-19
-6zov,2020-10-21,2020-07-07
-5zoi,2019-06-26,2018-04-13
-6zoz,2020-07-22,2020-07-08
-6zoj,2020-07-22,2020-07-07
-3zoa,2013-07-17,2013-02-21
-3zo7,2013-03-06,2013-02-20
-3zof,2014-05-14,2013-02-21
-2zo1,2008-09-09,2008-05-05
-6zof,2021-05-19,2020-07-07
-5zo8,2018-10-10,2018-04-12
-2zo9,2008-10-07,2008-05-07
-2zoa,2008-10-07,2008-05-07
-6zow,2020-07-29,2020-07-07
-1zo4,2006-08-01,2005-05-12
-1zoo,1996-12-07,1996-06-21
-4zow,2015-08-19,2015-05-07
-2zow,2009-06-30,2008-06-11
-6zol,2020-07-22,2020-07-07
-7zoc,2023-05-10,2022-04-25
-5zo9,2018-10-10,2018-04-12
-4zoc,2016-05-18,2015-05-06
-6zo9,2021-05-19,2020-07-07
-7zos,2022-09-07,2022-04-26
-2zoh,2009-03-24,2008-05-20
-1zod,2006-08-08,2005-05-12
-5zoe,2019-01-30,2018-04-13
-3zoy,2013-08-14,2013-02-26
-1zor,2006-05-16,2005-05-13
-3zo4,2013-03-06,2013-02-20
-7zo6,2023-03-08,2022-04-24
-2zok,2008-06-10,2008-05-22
-3zoh,2014-05-14,2013-02-21
-3zo9,2013-07-17,2013-02-21
-5zoc,2019-04-17,2018-04-12
-3zo3,2013-03-06,2013-02-20
-1zom,2006-05-23,2005-05-13
-4zo7,2016-05-18,2015-05-06
-1zo8,2005-10-04,2005-05-12
-1zoa,2006-08-01,2005-05-12
-3zot,2013-05-22,2013-02-24
-4zo5,2015-08-12,2015-05-06
-6zob,2021-05-19,2020-07-07
-5zo4,2019-04-10,2018-04-12
-1zol,2005-08-30,2005-05-13
-5zo5,2019-04-10,2018-04-12
-3zo1,2013-03-06,2013-02-20
-3zo2,2013-03-06,2013-02-20
-3zoz,2014-03-12,2013-02-26
-5zow,2018-12-19,2018-04-16
-6zoq,2021-01-20,2020-07-07
-2zo5,2009-05-05,2008-05-05
-6zoa,2021-05-19,2020-07-07
-7zob,2023-02-01,2022-04-25
-5zoz,2018-12-19,2018-04-16
-5zov,2018-08-01,2018-04-16
-5zou,2018-12-19,2018-04-16
-4zoh,2016-02-03,2015-05-06
-4zo0,2015-10-07,2015-05-05
-4zo8,2016-05-18,2015-05-06
-5zop,2018-10-10,2018-04-13
-5zon,2018-05-23,2018-04-13
-7zo5,2023-03-08,2022-04-24
-6zog,2021-05-19,2020-07-07
-1zos,2006-04-25,2005-05-13
-7zof,2022-07-13,2022-04-25
-5zoy,2018-12-19,2018-04-16
-6zoy,2020-07-22,2020-07-08
-6zo6,2021-05-19,2020-07-07
-7zo9,2022-12-07,2022-04-24
-2zoc,2009-04-28,2008-05-08
-4zoj,2016-05-11,2015-05-06
-2zo4,2009-03-17,2008-05-05
-2zox,2008-09-30,2008-06-17
-7zop,2023-05-10,2022-04-26
-5zo7,2018-10-10,2018-04-12
-6zot,2020-10-28,2020-07-07
-3zov,2013-05-29,2013-02-25
-4zod,2016-05-18,2015-05-06
-6zoc,2021-05-19,2020-07-07
-3zon,2013-04-10,2013-02-22
-5zo1,2019-01-30,2018-04-12
-4zo6,2016-05-18,2015-05-06
-2zog,2008-06-10,2008-05-14
-1zop,1996-12-07,1996-06-21
-6zos,2021-01-20,2020-07-07
-5zof,2019-01-30,2018-04-13
-4zom,2015-06-17,2015-05-06
-6zo0,2020-12-23,2020-07-07
-7zol,2022-11-30,2022-04-26
-7zoe,2023-05-10,2022-04-25
-5zox,2018-12-19,2018-04-16
-4zo3,2015-07-15,2015-05-05
-6zop,2021-06-16,2020-07-07
-6zok,2020-07-29,2020-07-07
-4zol,2016-07-27,2015-05-06
-7zo1,2022-10-26,2022-04-23
-3zox,2013-08-14,2013-02-26
-3zow,2013-08-14,2013-02-25
-6l1x,2020-04-01,2019-10-01
-6l1l,2020-03-18,2019-09-29
-7l11,2021-03-03,2020-12-14
-5l1t,2016-09-14,2016-07-29
-5l1l,2016-10-05,2016-07-29
-4l1y,2014-09-17,2013-06-04
-1l1z,2002-06-14,2002-02-20
-7l12,2021-03-03,2020-12-14
-6l1q,2019-12-18,2019-09-30
-2l1g,2010-09-08,2010-07-28
-4l1x,2014-04-16,2013-06-03
-7l19,2021-12-22,2020-12-14
-3l1t,2010-10-27,2009-12-14
-7l1b,2022-03-23,2020-12-14
-1l1v,2002-03-06,2002-02-20
-1l1e,2002-03-06,2002-02-15
-7l18,2021-01-13,2020-12-14
-7l1c,2022-03-23,2020-12-14
-6l1g,2020-04-01,2019-09-29
-1l1y,2002-07-17,2002-02-20
-5l1i,2016-10-05,2016-07-29
-3l14,2011-01-05,2009-12-10
-5l1p,2016-09-14,2016-07-29
-6l12,2020-05-27,2019-09-27
-1l1g,2002-08-28,2002-02-16
-7l1i,2022-02-09,2020-12-14
-4l16,2013-09-04,2013-06-02
-7l1j,2021-10-27,2020-12-14
-4l1k,2014-02-19,2013-06-03
-4l1i,2013-12-11,2013-06-03
-2l1o,2011-06-08,2010-07-31
-7l17,2021-08-04,2020-12-14
-5l1x,2016-08-24,2016-07-29
-4l1e,2014-05-21,2013-06-03
-5l1o,2016-09-14,2016-07-29
-5l11,2016-10-12,2016-07-28
-7l10,2021-03-03,2020-12-13
-4l12,2013-12-11,2013-06-01
-5l1q,2016-09-14,2016-07-29
-7l1s,2021-07-21,2020-12-15
-1l1o,2002-06-05,2002-02-19
-5l1v,2016-09-14,2016-07-29
-5l1f,2016-10-19,2016-07-29
-2l1u,2010-08-18,2010-08-06
-6l14,2020-05-27,2019-09-27
-5l14,2017-08-09,2016-07-28
-5l1w,2016-09-14,2016-07-29
-3l1l,2010-02-02,2009-12-13
-5l1s,2016-09-14,2016-07-29
-4l1l,2013-08-28,2013-06-03
-6l17,2020-09-02,2019-09-27
-4l1u,2013-10-02,2013-06-03
-5l1r,2016-09-14,2016-07-29
-3l1k,2010-12-22,2009-12-11
-7l1x,2021-08-11,2020-12-15
-4l1a,2014-04-02,2013-06-03
-3l1v,2010-01-05,2009-12-14
-4l1s,2013-10-02,2013-06-03
-6l1n,2020-03-18,2019-09-29
-7l1d,2022-03-23,2020-12-14
-4l1f,2014-01-15,2013-06-03
-4l1w,2014-04-16,2013-06-03
-3l1o,2010-03-16,2009-12-14
-6l1f,2020-09-23,2019-09-29
-7l1a,2021-03-17,2020-12-14
-6l1o,2020-03-18,2019-09-29
-7l1v,2021-02-10,2020-12-15
-5l15,2017-08-09,2016-07-28
-3l1b,2010-03-02,2009-12-11
-5l1h,2016-10-19,2016-07-29
-7l1y,2021-07-28,2020-12-15
-5l1e,2016-10-19,2016-07-29
-7l13,2021-03-03,2020-12-14
-5l17,2017-08-09,2016-07-28
-7l1g,2021-04-14,2020-12-14
-5l1k,2016-10-05,2016-07-29
-7l14,2021-03-03,2020-12-14
-7l1r,2021-07-21,2020-12-15
-7l1q,2021-07-21,2020-12-15
-6l19,2019-10-16,2019-09-28
-6l1b,2020-09-30,2019-09-28
-5l19,2016-09-07,2016-07-28
-5l12,2017-11-01,2016-07-28
-3l17,2010-02-16,2009-12-10
-3l19,2009-12-22,2009-12-11
-5l1n,2017-08-09,2016-07-29
-1l1t,2002-06-14,2002-02-19
-4l1z,2014-09-17,2013-06-04
-4l1q,2013-09-04,2013-06-03
-6l1a,2020-09-30,2019-09-28
-7l1t,2022-02-09,2020-12-15
-3l11,2010-01-19,2009-12-10
-4l19,2014-12-10,2013-06-02
-2l1r,2010-08-18,2010-08-03
-3l13,2010-02-16,2009-12-10
-6l1w,2020-01-01,2019-09-30
-5l1j,2016-10-05,2016-07-29
-5l18,2017-08-09,2016-07-28
-2l1w,2010-09-29,2010-08-06
-5l13,2017-03-08,2016-07-28
-1l1q,2002-11-27,2002-02-19
-6l16,2020-05-27,2019-09-27
-4l10,2013-10-30,2013-06-01
-6l13,2020-05-27,2019-09-27
-4l1o,2014-04-16,2013-06-03
-7l1k,2021-05-12,2020-12-14
-6l1p,2020-09-23,2019-09-29
-7l16,2021-08-04,2020-12-14
-4l17,2013-08-14,2013-06-02
-6l1h,2020-04-01,2019-09-29
-3l1s,2010-03-02,2009-12-14
-6l18,2019-12-04,2019-09-27
-3l16,2010-02-16,2009-12-10
-1l1r,2002-11-27,2002-02-19
-3l12,2009-12-29,2009-12-10
-5l1b,2016-10-19,2016-07-28
-6l1y,2020-05-20,2019-10-01
-6l1v,2020-02-05,2019-09-30
-3l1r,2010-12-15,2009-12-14
-3l1u,2010-01-05,2009-12-14
-3l1e,2010-05-12,2009-12-11
-4l1r,2013-06-26,2013-06-03
-7l15,2021-03-24,2020-12-14
-4l1t,2013-10-02,2013-06-03
-5l1z,2016-10-26,2016-07-29
-3l1m,2010-04-28,2009-12-13
-5l1u,2016-09-14,2016-07-29
-6l1j,2020-09-30,2019-09-29
-6l1z,2020-02-26,2019-10-02
-3l1c,2010-08-18,2009-12-11
-7l1h,2021-12-29,2020-12-14
-6l15,2020-05-27,2019-09-27
-6l11,2020-05-27,2019-09-27
-7l1p,2021-12-22,2020-12-15
-5l1g,2016-10-19,2016-07-29
-1zay,1999-12-16,1998-12-16
-4zao,2015-10-14,2015-04-13
-7za8,2022-12-07,2022-03-22
-2zaw,2008-01-01,2007-10-11
-4za3,2016-03-23,2015-04-13
-2za6,2008-01-22,2007-10-02
-6zal,2021-06-09,2020-06-05
-2zac,2008-05-27,2007-10-02
-6za1,2020-09-09,2020-06-04
-6zau,2021-01-20,2020-06-05
-5zax,2018-12-19,2018-02-09
-4zac,2015-06-17,2015-04-13
-2zae,2008-10-14,2007-10-04
-1za1,2005-06-07,2005-04-05
-4zay,2015-06-17,2015-04-14
-6zag,2021-06-09,2020-06-05
-2zai,2007-12-11,2007-10-05
-4zau,2015-11-11,2015-04-14
-4za0,2016-04-13,2015-04-13
-6zan,2021-06-09,2020-06-05
-7zao,2023-10-11,2022-03-22
-2zal,2007-10-30,2007-10-07
-6zam,2021-06-09,2020-06-05
-6zaa,2020-07-15,2020-06-05
-5zaf,2018-12-19,2018-02-07
-4zan,2015-06-17,2015-04-13
-1za2,2005-06-07,2005-04-05
-2zak,2008-03-25,2007-10-07
-1za0,2005-06-07,2005-04-05
-2zax,2008-01-01,2007-10-11
-1zag,1999-03-31,1999-02-02
-5zag,2018-12-19,2018-02-07
-6za7,2020-12-02,2020-06-04
-4za7,2015-06-17,2015-04-13
-4zag,2015-06-17,2015-04-13
-4zah,2015-04-29,2015-04-13
-6za3,2020-12-02,2020-06-04
-5za9,2018-12-19,2018-02-07
-4za6,2015-10-21,2015-04-13
-6zav,2021-01-20,2020-06-05
-4zas,2015-04-29,2015-04-13
-6za6,2020-07-01,2020-06-04
-5zad,2019-03-20,2018-02-07
-4zak,2015-07-01,2015-04-13
-6za2,2021-09-29,2020-06-04
-7za3,2022-11-02,2022-03-21
-2zat,2008-04-29,2007-10-10
-2zaf,2008-06-03,2007-10-05
-4zaw,2015-06-17,2015-04-14
-6zaq,2021-06-09,2020-06-05
-6zaj,2021-06-09,2020-06-05
-5zae,2018-12-19,2018-02-07
-2za3,2007-12-04,2007-09-26
-2zah,2008-10-07,2007-10-05
-2za8,2008-01-22,2007-10-02
-1zao,2005-06-21,2005-04-06
-7za2,2022-11-02,2022-03-21
-7zag,2022-08-03,2022-03-22
-7za4,2022-07-20,2022-03-22
-7zah,2022-08-03,2022-03-22
-4zaf,2015-06-17,2015-04-13
-4zab,2015-06-17,2015-04-13
-7zaa,2022-11-23,2022-03-22
-6zao,2021-06-09,2020-06-05
-1zab,2006-04-11,2005-04-06
-1zat,2006-03-28,2005-04-07
-4za8,2015-06-17,2015-04-13
-7za1,2022-11-02,2022-03-21
-1zaa,1993-10-31,1992-09-17
-5zan,2019-02-13,2018-02-07
-6zaw,2021-01-20,2020-06-05
-7za9,2022-11-23,2022-03-22
-2zao,2008-10-07,2007-10-08
-6zaz,2020-11-18,2020-06-06
-1zai,2005-05-10,2005-04-06
-4za5,2015-06-17,2015-04-13
-1zau,2005-07-05,2005-04-07
-7zad,2022-11-23,2022-03-22
-4zax,2015-06-17,2015-04-14
-2zag,2007-12-11,2007-10-05
-6zab,2020-12-02,2020-06-05
-7zar,2022-11-23,2022-03-22
-2zaz,2008-01-15,2007-10-12
-6zai,2021-06-09,2020-06-05
-7zaz,2022-07-06,2022-03-23
-6zad,2020-07-29,2020-06-05
-6za8,2021-02-10,2020-06-05
-6zat,2021-01-20,2020-06-05
-7zaq,2022-11-23,2022-03-22
-7zan,2022-10-12,2022-03-22
-4za4,2015-06-17,2015-04-13
-7zaj,2022-11-23,2022-03-22
-7zat,2022-11-23,2022-03-22
-5zah,2018-12-19,2018-02-07
-5za2,2018-03-07,2018-02-06
-7zae,2022-11-23,2022-03-22
-6zae,2021-06-09,2020-06-05
-4zaz,2015-06-17,2015-04-14
-5za1,2018-10-31,2018-02-06
-7zav,2022-11-02,2022-03-22
-6zah,2021-06-09,2020-06-05
-6zap,2021-06-09,2020-06-05
-6zar,2021-01-20,2020-06-05
-1zaj,2005-05-10,2005-04-06
-4zav,2015-06-17,2015-04-14
-7zak,2023-03-29,2022-03-22
-6zac,2020-07-01,2020-06-05
-2za5,2008-02-26,2007-10-02
-5zai,2018-08-01,2018-02-07
-7za6,2022-11-23,2022-03-22
-1za5,2006-03-14,2005-04-05
-2zas,2008-10-07,2007-10-09
-4zar,2015-05-06,2015-04-14
-7zab,2023-02-01,2022-03-22
-5zaj,2018-12-19,2018-02-07
-6zay,2020-09-30,2020-06-06
-4zad,2015-06-17,2015-04-13
-2za0,2008-08-12,2007-09-26
-1zar,2005-06-21,2005-04-06
-6zak,2022-01-12,2020-06-05
-6za0,2020-12-02,2020-06-04
-5za7,2018-12-19,2018-02-06
-5za8,2018-12-19,2018-02-06
-7zaw,2022-11-02,2022-03-22
-2zad,2008-04-08,2007-10-03
-4zal,2015-06-17,2015-04-13
-6za5,2020-07-15,2020-06-04
-7zai,2022-07-13,2022-03-22
-1zap,1997-04-21,1996-01-16
-5zac,2018-05-30,2018-02-07
-2zan,2008-10-07,2007-10-08
-2zav,2007-10-30,2007-10-11
-7zay,2022-12-07,2022-03-23
-4za9,2015-06-17,2015-04-13
-4zam,2016-01-27,2015-04-13
-1za4,2006-01-24,2005-04-05
-1zaf,2006-04-11,2005-04-06
-6zas,2021-01-20,2020-06-05
-2zaa,2008-05-27,2007-10-02
-2zab,2008-05-27,2007-10-02
-4za2,2015-04-29,2015-04-13
-7za0,2023-03-29,2022-03-21
-6zax,2021-01-20,2020-06-05
-5zab,2018-06-06,2018-02-07
-2za1,2007-12-04,2007-09-26
-1zak,1998-04-08,1997-05-31
-7za7,2022-11-23,2022-03-22
-4zae,2015-06-03,2015-04-13
-6zaf,2021-06-09,2020-06-05
-5za0,2018-05-30,2018-02-06
-6za4,2020-07-01,2020-06-04
-4zaa,2015-06-17,2015-04-13
-6vhv,2020-06-24,2020-01-10
-2vh3,2007-12-04,2007-11-17
-7vh8,2021-11-03,2021-09-21
-2vhv,2008-03-11,2007-11-26
-6vhz,2020-06-24,2020-01-10
-3vhn,2012-07-11,2011-08-30
-2vh5,2008-01-22,2007-11-19
-6vh4,2020-04-22,2020-01-09
-6vh2,2020-08-12,2020-01-09
-3vhz,2012-06-13,2011-09-13
-5vhy,2017-05-03,2017-04-13
-3vha,2012-07-18,2011-08-24
-3vhk,2012-09-05,2011-08-25
-5vh5,2017-05-03,2017-04-12
-6vh5,2020-01-29,2020-01-09
-6vh1,2020-08-12,2020-01-09
-2vha,2008-07-08,2007-11-20
-7vhz,2022-04-27,2021-09-24
-1vhd,2003-12-30,2003-12-01
-2vhx,2008-03-11,2007-11-26
-2vhz,2008-03-11,2007-11-26
-8vh9,2024-04-24,2023-12-31
-7vhy,2022-04-27,2021-09-24
-1vh3,2003-12-30,2003-12-01
-3vh7,2012-06-13,2011-08-23
-6vhx,2020-06-24,2020-01-10
-6vhn,2020-04-22,2020-01-10
-3vhh,2011-12-28,2011-08-25
-5vhw,2017-05-03,2017-04-13
-3vhs,2012-10-10,2011-09-06
-1vhb,1998-02-25,1997-02-19
-3vhe,2011-11-02,2011-08-24
-2vhf,2008-03-11,2007-11-21
-1vha,2003-12-30,2003-12-01
-3vh8,2011-10-26,2011-08-24
-2vhu,2007-12-11,2007-11-25
-5vhx,2017-05-03,2017-04-13
-3vhr,2012-02-15,2011-09-01
-5vh2,2018-04-18,2017-04-12
-2vhd,2008-02-12,2007-11-20
-3vhu,2011-12-28,2011-09-07
-6vhq,2021-01-13,2020-01-10
-6vh9,2020-09-16,2020-01-09
-2vh0,2008-11-25,2007-11-16
-3vhd,2012-07-18,2011-08-24
-2vhc,2007-12-04,2007-11-20
-8vhc,2024-04-24,2023-12-31
-7vh1,2021-09-29,2021-09-20
-6vhe,2020-09-16,2020-01-09
-7vhn,2022-12-07,2021-09-22
-3vh9,2012-05-02,2011-08-24
-2vhe,2008-01-29,2007-11-21
-7vhr,2022-03-02,2021-09-22
-7vhe,2022-07-20,2021-09-22
-6vh0,2020-08-12,2020-01-09
-6vho,2021-01-13,2020-01-10
-1vhh,1996-01-29,1995-10-03
-1vht,2003-12-30,2003-12-01
-5vhd,2018-06-13,2017-04-13
-6vhy,2020-06-24,2020-01-10
-5vhh,2017-08-23,2017-04-13
-7vhc,2022-07-20,2021-09-22
-4vhb,1999-08-31,1999-03-11
-6vhs,2020-08-26,2020-01-10
-5vh4,2017-05-03,2017-04-12
-1vhz,2003-12-30,2003-12-01
-5vhv,2017-10-25,2017-04-13
-1vh2,2003-12-30,2003-12-01
-1vhl,2003-12-30,2003-12-01
-3vhi,2011-12-28,2011-08-25
-2vhw,2008-03-11,2007-11-26
-8vhb,2024-04-24,2023-12-31
-7vhv,2022-04-13,2021-09-23
-3vhc,2012-07-18,2011-08-24
-2vh6,2008-12-16,2007-11-19
-7vh4,2022-09-28,2021-09-20
-3vhq,2012-07-11,2011-09-01
-6vhp,2020-04-22,2020-01-10
-3vh1,2011-09-21,2011-08-23
-3vht,2012-10-10,2011-09-06
-6vhh,2020-06-03,2020-01-09
-2vhj,2007-12-04,2007-11-21
-3vhm,2011-12-28,2011-08-29
-1vhn,2003-12-30,2003-12-01
-2vhq,2007-12-04,2007-11-22
-8vha,2024-04-24,2023-12-31
-6vhu,2020-06-24,2020-01-10
-5vhs,2017-08-23,2017-04-13
-7vh0,2022-03-02,2021-09-20
-2vht,2007-12-04,2007-11-25
-2vh9,2008-11-25,2007-11-20
-3vhv,2011-12-28,2011-09-07
-7vhh,2022-12-28,2021-09-22
-6vhd,2020-09-16,2020-01-09
-3vh3,2011-09-21,2011-08-23
-2vhb,1998-02-25,1997-02-19
-5vhc,2018-06-13,2017-04-12
-6vhl,2020-03-04,2020-01-10
-6vhw,2020-06-24,2020-01-10
-5vhe,2018-06-13,2017-04-13
-6vhf,2020-01-22,2020-01-09
-3vhb,1999-08-18,1999-03-17
-5vh0,2018-04-25,2017-04-12
-8vhd,2024-04-24,2023-12-31
-2vhg,2008-02-19,2007-11-21
-7vhf,2022-07-20,2021-09-22
-5vhb,2018-01-31,2017-04-12
-3vhp,2012-07-11,2011-08-30
-3vhx,2012-05-16,2011-09-12
-5vhi,2017-08-23,2017-04-13
-5vhz,2017-05-03,2017-04-13
-6vh3,2020-08-12,2020-01-09
-6vh6,2020-05-06,2020-01-09
-6vhb,2020-02-19,2020-01-09
-7vhd,2022-07-20,2021-09-22
-1vhw,2003-12-30,2003-12-01
-1vhe,2003-12-30,2003-12-01
-5vhf,2017-08-23,2017-04-13
-3vh4,2011-09-21,2011-08-23
-3vh2,2011-09-21,2011-08-23
-6vhc,2020-02-19,2020-01-09
-6vhg,2020-02-26,2020-01-09
-3vhw,2013-03-06,2011-09-08
-2vhl,2007-12-04,2007-11-22
-7ci5,2020-12-02,2020-07-07
-2ciz,2006-06-12,2006-03-26
-8cib,2023-12-20,2023-02-09
-2cig,2006-04-25,2006-03-20
-7ci0,2021-07-14,2020-07-06
-4cin,2014-11-12,2013-12-12
-5cif,2016-08-03,2015-07-12
-2ciq,2006-07-11,2006-03-24
-7ci7,2020-12-02,2020-07-07
-3cii,2008-05-13,2008-03-11
-6ci6,2018-03-07,2018-02-23
-4cis,2014-06-04,2013-12-15
-3ci3,2008-05-27,2008-03-10
-3cic,2008-06-10,2008-03-11
-6cis,2018-08-29,2018-02-25
-8ci3,2023-07-12,2023-02-08
-1cik,1999-04-09,1999-04-01
-2ciw,2006-06-12,2006-03-26
-6ci0,2018-04-25,2018-02-23
-1cib,2000-04-05,1999-03-31
-1cit,1999-05-03,1999-04-05
-7ci4,2020-12-02,2020-07-07
-7cis,2022-03-09,2020-07-08
-1ciu,1996-03-08,1995-10-23
-3cix,2008-04-08,2008-03-12
-6cir,2018-06-06,2018-02-25
-7cic,2020-12-02,2020-07-07
-2cif,2006-10-11,2006-03-20
-5cis,2017-01-18,2015-07-13
-3cig,2008-05-06,2008-03-11
-2cim,2006-06-26,2006-03-24
-4ci5,2014-12-24,2013-12-05
-1cig,1995-01-26,1994-09-26
-2cix,2006-06-12,2006-03-26
-6cig,2018-03-07,2018-02-23
-4cio,2014-09-03,2013-12-12
-3ci5,2008-08-19,2008-03-10
-7ci2,2020-10-14,2020-07-07
-7cih,2021-07-14,2020-07-07
-1ci7,2000-04-10,1999-04-08
-2cis,2006-07-12,2006-03-24
-6ciq,2018-03-28,2018-02-24
-7cit,2021-06-16,2020-07-08
-7cii,2021-01-27,2020-07-07
-2cii,2006-03-29,2006-03-21
-6cie,2018-10-31,2018-02-23
-5ci9,2015-11-18,2015-07-11
-8ciz,2023-11-29,2023-02-11
-4cie,2014-01-08,2013-12-07
-8cih,2024-02-21,2023-02-09
-2cib,2007-07-03,2006-03-17
-7cie,2020-12-02,2020-07-07
-5cix,2015-08-12,2015-07-13
-3ci0,2008-04-29,2008-03-10
-7cip,2021-07-14,2020-07-08
-8cig,2024-02-21,2023-02-09
-7cix,2021-07-21,2020-07-08
-6ci4,2018-10-17,2018-02-23
-6cip,2018-03-28,2018-02-24
-1civ,2000-04-05,1999-04-01
-3cis,2009-03-17,2008-03-11
-2cio,2006-05-18,2006-03-24
-4cia,2014-02-26,2013-12-06
-4ciu,2014-05-14,2013-12-16
-6cii,2018-04-25,2018-02-23
-4ciz,2014-01-08,2013-12-18
-5ciy,2016-03-30,2015-07-13
-8cip,2023-03-01,2023-02-10
-1ci3,1999-08-11,1999-04-07
-4ci2,2014-07-16,2013-12-05
-5ciq,2015-09-09,2015-07-13
-4ciy,2014-04-16,2013-12-17
-7ci9,2020-12-02,2020-07-07
-1cip,1999-04-09,1999-04-05
-2cik,2006-10-25,2006-03-22
-2ci7,2006-05-17,2006-03-17
-7cio,2020-12-09,2020-07-08
-2cie,2006-10-11,2006-03-20
-5cie,2016-08-03,2015-07-12
-8ci6,2024-01-24,2023-02-08
-8ci2,2023-10-11,2023-02-08
-7ci8,2020-12-02,2020-07-07
-3cid,2008-06-10,2008-03-11
-8cii,2024-02-21,2023-02-09
-8cim,2023-07-05,2023-02-10
-1cim,1994-01-31,1993-10-20
-6ciw,2019-01-02,2018-02-25
-7cij,2021-01-27,2020-07-07
-2cic,2007-03-27,2006-03-17
-7cib,2020-12-02,2020-07-07
-5ciu,2016-03-30,2015-07-13
-1cio,1999-04-09,1999-04-01
-4ci3,2014-07-16,2013-12-05
-4cip,2014-05-21,2013-12-13
-2ci5,2006-05-17,2006-03-17
-7ciy,2021-06-16,2020-07-08
-2civ,2006-06-12,2006-03-26
-5cic,2016-08-03,2015-07-11
-3ciw,2008-04-08,2008-03-12
-6cij,2018-04-25,2018-02-24
-6cia,2018-03-07,2018-02-23
-4ci6,2015-01-28,2013-12-06
-3cib,2008-06-10,2008-03-11
-1ciw,1999-07-27,1999-04-06
-6cin,2018-03-28,2018-02-24
-3cia,2008-07-01,2008-03-11
-4cik,2014-06-18,2013-12-10
-4ci7,2014-05-14,2013-12-06
-6ciy,2018-08-29,2018-02-25
-4cit,2014-10-08,2013-12-16
-8civ,2023-09-20,2023-02-10
-8cie,2023-06-14,2023-02-09
-2cih,2006-12-13,2006-03-21
-3cif,2009-03-24,2008-03-11
-5ci8,2015-11-18,2015-07-11
-6cio,2018-03-28,2018-02-24
-8cic,2023-05-31,2023-02-09
-8cij,2023-08-16,2023-02-09
-5cio,2016-06-08,2015-07-13
-3ci4,2008-05-27,2008-03-10
-4ci1,2014-07-16,2013-12-05
-7civ,2021-08-18,2020-07-08
-6cif,2018-10-31,2018-02-23
-8cin,2024-02-21,2023-02-10
-1cif,1995-01-26,1994-09-26
-7cil,2021-05-12,2020-07-07
-8cix,2023-11-29,2023-02-11
-1ci9,2001-12-12,1999-04-08
-3ci8,2008-03-25,2008-03-11
-3cin,2008-03-25,2008-03-11
-6ci5,2018-10-17,2018-02-23
-1ci6,2000-12-04,1999-04-07
-6cid,2018-10-31,2018-02-23
-7cig,2021-01-27,2020-07-07
-6ci9,2018-05-30,2018-02-23
-2cip,2006-07-12,2006-03-24
-8ci1,2023-10-11,2023-02-08
-5cih,2016-08-03,2015-07-12
-5cit,2015-09-09,2015-07-13
-8cir,2023-03-01,2023-02-10
-5cib,2016-08-03,2015-07-11
-3ciq,2008-09-02,2008-03-11
-7cid,2020-12-02,2020-07-07
-6ciz,2018-06-06,2018-02-25
-1cin,1994-01-31,1993-10-20
-1ci0,1999-08-25,1999-04-06
-5cir,2017-01-18,2015-07-13
-6cik,2018-04-25,2018-02-24
-7cia,2020-12-02,2020-07-07
-6ci7,2018-03-21,2018-02-23
-4ci9,2014-02-26,2013-12-06
-3ciz,2008-04-15,2008-03-12
-5ci5,2015-07-22,2015-07-11
-8ciw,2023-07-12,2023-02-10
-4cif,2014-01-08,2013-12-07
-6cim,2018-04-25,2018-02-24
-5ciw,2015-09-09,2015-07-13
-1cih,1995-01-26,1994-09-26
-5cig,2016-08-03,2015-07-12
-7ciw,2021-07-21,2020-07-08
-5ci7,2015-08-26,2015-07-11
-4cig,2014-01-08,2013-12-07
-2ci9,2006-04-24,2006-03-17
-8ciy,2023-11-29,2023-02-11
-2ci6,2006-05-17,2006-03-17
-7ci6,2020-12-02,2020-07-07
-4cid,2014-02-19,2013-12-06
-2cir,2006-07-12,2006-03-24
-4cix,2014-04-16,2013-12-17
-4ciw,2014-04-16,2013-12-17
-6cit,2018-06-27,2018-02-25
-6cil,2018-04-25,2018-02-24
-3cik,2009-02-17,2008-03-11
-4cic,2014-05-28,2013-12-06
-8cis,2023-03-01,2023-02-10
-3cip,2008-08-19,2008-03-11
-5cid,2016-08-03,2015-07-12
-6cib,2018-03-21,2018-02-23
-4ci0,2014-02-26,2013-12-05
-4cib,2014-02-26,2013-12-06
-1cil,1994-01-31,1993-10-20
-3ciy,2008-05-06,2008-03-12
-8ci9,2023-06-14,2023-02-09
-3ci1,2008-05-27,2008-03-10
-3ciu,2008-04-15,2008-03-11
-3cir,2008-04-01,2008-03-11
-2cin,2006-08-14,2006-03-24
-2cit,2006-04-10,2006-03-24
-1cia,1994-01-31,1993-07-19
-4civ,2014-04-16,2013-12-17
-2cij,2007-03-27,2006-03-21
-1cie,1995-01-26,1994-09-26
-4ci4,2014-12-24,2013-12-05
-2ci0,2007-07-03,2006-03-16
-1ciz,1999-09-01,1999-04-06
-5ciz,2016-06-29,2015-07-13
-2ciy,2006-06-12,2006-03-26
-8ci0,2023-03-22,2023-02-08
-6cic,2018-10-31,2018-02-23
-5cim,2015-12-09,2015-07-13
-7cim,2021-01-27,2020-07-07
-6r6v,2020-01-15,2019-03-28
-4r6s,2015-07-01,2014-08-26
-8r6q,2024-01-17,2023-11-22
-8r6f,2023-12-27,2023-11-22
-5r62,2020-10-28,2020-02-28
-1r6p,2004-06-08,2003-10-15
-7r6t,2022-08-24,2021-06-23
-1r6x,2003-11-11,2003-10-17
-3r6q,2011-07-13,2011-03-22
-3r65,2012-02-01,2011-03-21
-8r67,2024-05-22,2023-11-21
-4r6p,2015-02-18,2014-08-26
-6r6e,2020-05-06,2019-03-27
-4r66,2014-10-08,2014-08-22
-6r65,2019-05-01,2019-03-26
-1r6w,2003-11-25,2003-10-17
-4r63,2014-10-08,2014-08-22
-2r6k,2008-08-19,2007-09-06
-4r6k,2014-09-10,2014-08-25
-7r6b,2022-07-06,2021-06-22
-1r6q,2005-02-15,2003-10-16
-3r60,2012-04-11,2011-03-20
-2r66,2008-06-10,2007-09-05
-2r61,2007-11-27,2007-09-05
-5r66,2020-04-15,2020-02-28
-6r6m,2019-10-02,2019-03-27
-6r68,2019-09-11,2019-03-26
-1r65,2004-01-13,2003-10-14
-2r6g,2007-11-27,2007-09-05
-4r6a,2015-08-26,2014-08-22
-7r62,2022-07-06,2021-06-22
-1r66,2004-01-27,2003-10-14
-3r68,2011-05-18,2011-03-21
-4r6q,2015-02-18,2014-08-26
-1r6z,2004-01-13,2003-10-17
-2r6y,2008-04-08,2007-09-06
-5r64,2020-04-15,2020-02-28
-6r6o,2019-10-02,2019-03-27
-6r6j,2020-04-08,2019-03-27
-2r6n,2007-11-06,2007-09-06
-3r6s,2012-03-28,2011-03-22
-1r6b,2004-08-24,2003-10-15
-6r6g,2019-07-10,2019-03-27
-5r60,2020-10-28,2020-02-28
-6r6w,2020-01-15,2019-03-28
-3r6i,2012-05-02,2011-03-21
-4r6v,2014-10-29,2014-08-26
-2r6h,2007-09-11,2007-09-05
-3r6k,2011-05-11,2011-03-21
-4r6n,2015-02-18,2014-08-26
-3r6g,2011-07-27,2011-03-21
-6r6h,2019-08-28,2019-03-27
-2r6w,2008-04-08,2007-09-06
-6r6k,2019-07-31,2019-03-27
-2r6m,2008-09-23,2007-09-06
-3r6f,2011-03-30,2011-03-21
-2r6t,2007-12-18,2007-09-06
-4r6l,2015-07-22,2014-08-25
-2r6o,2007-09-18,2007-09-06
-4r6z,2015-07-01,2014-08-26
-1r6u,2004-01-06,2003-10-16
-4r67,2015-02-11,2014-08-22
-6r63,2019-10-02,2019-03-26
-1r6a,2004-09-21,2003-10-15
-1r6v,2004-10-19,2003-10-17
-3r6l,2011-07-27,2011-03-21
-8r6u,2024-04-24,2023-11-23
-4r69,2014-12-24,2014-08-22
-6r61,2021-04-07,2019-03-26
-4r60,2014-09-17,2014-08-22
-6r6i,2019-09-11,2019-03-27
-2r64,2008-09-09,2007-09-05
-3r6v,2011-07-13,2011-03-22
-7r6z,2021-12-01,2021-06-24
-3r6x,2012-08-08,2011-03-22
-3r6h,2011-06-08,2011-03-21
-5r69,2020-12-30,2020-02-29
-5r63,2020-10-28,2020-02-28
-7r6x,2021-07-21,2021-06-23
-1r61,2004-03-30,2003-10-14
-7r6v,2022-08-24,2021-06-23
-4r6c,2015-02-04,2014-08-24
-2r6f,2008-01-08,2007-09-05
-4r6g,2015-01-07,2014-08-25
-4r68,2014-12-24,2014-08-22
-5r67,2020-04-15,2020-02-28
-7r63,2022-05-04,2021-06-22
-7r6w,2021-07-21,2021-06-23
-3r6o,2011-06-08,2011-03-22
-3r61,2012-04-11,2011-03-20
-1r6t,2004-01-06,2003-10-16
-6r6u,2019-09-25,2019-03-28
-6r66,2019-09-11,2019-03-26
-8r6s,2024-03-13,2023-11-22
-8r6y,2024-04-24,2023-11-23
-6r6p,2019-07-10,2019-03-27
-1r6g,2005-02-15,2003-10-15
-3r6y,2011-07-13,2011-03-22
-7r6y,2022-05-25,2021-06-24
-6r62,2019-05-29,2019-03-26
-4r6x,2014-10-08,2014-08-26
-6r67,2019-09-11,2019-03-26
-6r6f,2019-12-18,2019-03-27
-7r61,2021-10-06,2021-06-22
-4r6o,2015-02-18,2014-08-26
-1r6d,2004-01-27,2003-10-14
-1r64,2004-03-09,2003-10-14
-2r6v,2007-09-25,2007-09-06
-1r67,2003-10-21,2003-10-15
-4r6e,2015-09-09,2014-08-25
-2r6x,2007-12-18,2007-09-06
-6r6x,2020-05-06,2019-03-28
-2r65,2008-09-09,2007-09-05
-7r60,2021-10-06,2021-06-22
-8r65,2024-03-27,2023-11-20
-2r6r,2007-10-16,2007-09-06
-2r6j,2008-01-15,2007-09-05
-1r6o,2005-02-15,2003-10-15
-2r68,2008-06-10,2007-09-05
-8r60,2024-03-27,2023-11-19
-4r6d,2014-11-12,2014-08-25
-3r6t,2012-02-01,2011-03-22
-3r6p,2011-12-21,2011-03-22
-7r6j,2022-07-06,2021-06-22
-5r65,2020-04-15,2020-02-28
-5r68,2020-12-30,2020-02-29
-2r6s,2008-06-03,2007-09-06
-7r6g,2022-06-29,2021-06-22
-6r6n,2019-10-02,2019-03-27
-8r6w,2024-04-24,2023-11-23
-6r6y,2020-04-08,2019-03-28
-1r6n,2004-02-24,2003-10-15
-4r6r,2015-02-18,2014-08-26
-4r65,2014-10-08,2014-08-22
-4r6u,2014-10-15,2014-08-26
-4r6t,2014-10-29,2014-08-26
-4r64,2014-10-08,2014-08-22
-3r6c,2012-09-26,2011-03-21
-4r6w,2014-10-08,2014-08-26
-6r6a,2021-04-07,2019-03-26
-3r6w,2011-08-24,2011-03-22
-5r61,2020-10-28,2020-02-28
-225l,1998-03-18,1997-06-25
-7mm5,2022-03-09,2021-04-29
-3mmd,2011-04-27,2010-04-19
-6mml,2018-11-28,2018-09-30
-6mmg,2018-11-28,2018-09-30
-2mmi,2014-10-15,2014-03-15
-3mm8,2010-07-21,2010-04-19
-5mm1,2017-08-09,2016-12-08
-7mmf,2022-03-09,2021-04-29
-4mmu,2013-11-20,2013-09-09
-5mmo,2017-04-26,2016-12-12
-3mmk,2011-07-13,2010-04-20
-6mm2,2019-09-18,2018-09-28
-1mmy,2002-09-18,2002-09-04
-1mmr,1996-04-03,1995-03-22
-7mm3,2022-03-16,2021-04-29
-4mmb,2013-10-16,2013-09-08
-7mme,2022-08-31,2021-04-29
-4mmk,2014-07-09,2013-09-09
-7mmb,2022-03-16,2021-04-29
-3mmx,2010-07-28,2010-04-20
-7mms,2022-05-04,2021-04-30
-1mmx,2002-09-18,2002-09-04
-3mmg,2010-10-20,2010-04-19
-7mmr,2022-05-04,2021-04-30
-3mmw,2010-07-28,2010-04-20
-1mmo,1995-02-27,1994-02-22
-3mm1,2011-04-27,2010-04-19
-7mmj,2022-03-09,2021-04-29
-6mmv,2018-11-28,2018-10-01
-1mmj,2002-12-23,2002-09-04
-3mmz,2010-04-28,2010-04-20
-4mmc,2013-10-16,2013-09-08
-7mmu,2022-05-04,2021-04-30
-6mmn,2018-11-28,2018-10-01
-6mmw,2018-11-28,2018-10-01
-7mm4,2022-03-16,2021-04-29
-4mmf,2013-10-16,2013-09-08
-1mmt,2003-09-04,2002-09-04
-3mm7,2010-07-21,2010-04-19
-5mma,2017-08-02,2016-12-09
-7mm0,2021-07-28,2021-04-29
-1mmn,1997-12-03,1997-07-18
-4mm3,2014-07-02,2013-09-08
-3mm9,2010-07-21,2010-04-19
-5mm3,2017-10-25,2016-12-08
-7mmn,2021-09-08,2021-04-29
-2mm3,2014-05-07,2014-03-07
-6mmj,2018-11-28,2018-09-30
-7mmz,2021-05-26,2021-04-30
-4mm9,2013-10-16,2013-09-08
-4mml,2014-07-09,2013-09-09
-4mm8,2013-10-16,2013-09-08
-4mmz,2014-03-26,2013-09-09
-3mmf,2011-04-20,2010-04-19
-7mmp,2022-05-04,2021-04-30
-7mma,2022-03-16,2021-04-29
-3mma,2010-07-21,2010-04-19
-5mm0,2017-08-09,2016-12-08
-7mm7,2022-03-09,2021-04-29
-7mm9,2022-03-16,2021-04-29
-5mmn,2017-04-26,2016-12-12
-1mm8,2002-12-13,2002-09-03
-1mma,1997-12-03,1997-07-18
-1mm6,2003-02-04,2002-09-03
-5mm6,2017-12-20,2016-12-08
-7mm2,2022-03-09,2021-04-29
-7mmi,2022-03-09,2021-04-29
-6mmx,2018-11-28,2018-10-01
-7mm1,2021-05-12,2021-04-29
-1mm3,2003-07-22,2002-09-02
-4mmd,2013-10-16,2013-09-08
-5mmw,2017-11-08,2016-12-12
-1mmb,1996-10-14,1995-08-23
-7mmo,2021-05-12,2021-04-30
-4mme,2013-10-16,2013-09-08
-3mmo,2010-09-29,2010-04-20
-4mmx,2014-03-26,2013-09-09
-5mmf,2017-05-24,2016-12-09
-3mmn,2011-04-13,2010-04-20
-1mmp,1996-04-03,1995-03-22
-5mme,2017-12-20,2016-12-09
-6mmr,2018-11-28,2018-10-01
-4mmo,2014-10-15,2013-09-09
-1mmw,2003-09-16,2002-09-04
-6mm5,2019-05-08,2018-09-29
-4mm4,2013-10-16,2013-09-08
-4mm2,2014-09-10,2013-09-07
-4mm5,2013-10-16,2013-09-08
-4mmi,2014-01-29,2013-09-09
-5mm9,2017-03-29,2016-12-08
-5mmm,2017-01-11,2016-12-11
-1mmd,1996-08-17,1995-03-21
-4mma,2013-10-16,2013-09-08
-3mmc,2010-05-12,2010-04-19
-6mma,2018-11-28,2018-09-29
-7mmw,2022-05-04,2021-04-30
-1mmm,1998-09-02,1998-08-26
-3mm6,2010-07-21,2010-04-19
-1mmz,2002-09-18,2002-09-04
-3mms,2010-05-12,2010-04-20
-3mmp,2010-06-09,2010-04-20
-5mms,2017-05-03,2016-12-12
-5mmg,2017-12-20,2016-12-09
-4mmy,2014-03-26,2013-09-09
-6mmq,2019-09-18,2018-10-01
-6mmo,2019-09-18,2018-10-01
-1mmq,1996-04-03,1995-03-22
-4mmm,2014-07-30,2013-09-09
-7mmt,2022-05-04,2021-04-30
-4mm0,2014-09-17,2013-09-07
-3mm2,2011-04-27,2010-04-19
-6mm7,2019-05-08,2018-09-29
-1mmf,2003-06-10,2002-09-03
-7mmh,2022-03-09,2021-04-29
-4mm1,2014-06-25,2013-09-07
-2mml,2014-10-15,2014-03-15
-6mm1,2019-10-02,2018-09-28
-5mmi,2017-01-11,2016-12-10
-6mmc,2019-09-18,2018-09-30
-7mmv,2022-05-04,2021-04-30
-6mmi,2018-11-28,2018-09-30
-1mmu,2002-09-18,2002-09-04
-7mmg,2022-03-09,2021-04-29
-4mmh,2014-01-29,2013-09-09
-6mmd,2019-05-29,2018-09-30
-6mmh,2018-11-28,2018-09-30
-1mm2,2003-07-22,2002-09-02
-6mmm,2018-11-28,2018-09-30
-5mmd,2017-03-29,2016-12-09
-6mme,2019-10-02,2018-09-30
-2mmh,2014-10-15,2014-03-15
-5mmv,2017-12-20,2016-12-12
-6mmb,2018-11-28,2018-09-30
-5mmb,2017-08-02,2016-12-09
-1mmg,1997-12-03,1997-07-18
-4mm6,2013-10-16,2013-09-08
-6mm6,2019-05-08,2018-09-29
-3mme,2010-06-09,2010-04-19
-5mmj,2017-01-11,2016-12-10
-3mm3,2011-04-27,2010-04-19
-6mmk,2018-11-28,2018-09-30
-5mmp,2017-04-26,2016-12-12
-4mmw,2013-09-18,2013-09-09
-7mml,2022-03-16,2021-04-29
-3mmt,2010-05-19,2010-04-20
-7mm6,2022-03-09,2021-04-29
-7mmq,2022-05-04,2021-04-30
-3mmr,2010-06-23,2010-04-20
-1mms,2000-04-17,1999-04-14
-1mmk,2003-09-04,2002-09-04
-6mmp,2018-11-28,2018-10-01
-5mmx,2017-08-02,2016-12-12
-6mmt,2018-11-28,2018-10-01
-4mmp,2014-07-09,2013-09-09
-6mmu,2018-11-28,2018-10-01
-5mm4,2018-06-27,2016-12-08
-3mmb,2010-07-21,2010-04-19
-3mmv,2010-06-02,2010-04-20
-3mm5,2010-07-21,2010-04-19
-5mmr,2017-05-24,2016-12-12
-1mm7,2003-02-04,2002-09-03
-7mmd,2022-08-31,2021-04-29
-6mm8,2019-05-08,2018-09-29
-6mm9,2018-11-28,2018-09-29
-1mmv,2003-09-16,2002-09-04
-7mmc,2022-03-16,2021-04-29
-3mmh,2010-05-19,2010-04-19
-7mmk,2022-03-16,2021-04-29
-7mm8,2022-03-09,2021-04-29
-6mms,2018-11-28,2018-10-01
-2mmk,2014-10-15,2014-03-15
-5mm7,2018-08-08,2016-12-08
-4mm7,2013-10-16,2013-09-08
-3mmu,2010-07-28,2010-04-20
-7rze,2022-08-31,2021-08-27
-4rzm,2015-01-21,2014-12-22
-3rzk,2012-06-06,2011-05-11
-3rz0,2011-08-10,2011-05-11
-3rzo,2011-08-10,2011-05-12
-5rzt,2020-11-11,2020-10-30
-6rzh,2020-07-08,2019-06-13
-5rzh,2020-11-11,2020-10-30
-6rzm,2020-07-08,2019-06-13
-5rz1,2020-11-11,2020-10-30
-6rzj,2020-07-08,2019-06-13
-5rzb,2020-11-11,2020-10-30
-5rzu,2020-11-11,2020-10-30
-5rz5,2020-11-11,2020-10-30
-6rz8,2019-12-11,2019-06-12
-7rz4,2021-10-27,2021-08-27
-1rzr,2004-10-12,2003-12-27
-1rz1,2004-04-06,2003-12-23
-7rzx,2022-11-09,2021-08-27
-4rz8,2015-09-09,2014-12-18
-7rza,2021-10-27,2021-08-27
-5rzf,2020-11-11,2020-10-30
-1rzp,2004-03-30,2003-12-26
-5rzm,2020-11-11,2020-10-30
-5rz3,2020-11-11,2020-10-30
-7rzk,2022-03-02,2021-08-27
-5rzo,2020-11-11,2020-10-30
-3rz8,2011-08-10,2011-05-11
-5rz7,2020-11-11,2020-10-30
-4rz1,2015-03-25,2014-12-18
-3rz7,2011-08-10,2011-05-11
-6rz9,2019-12-11,2019-06-12
-5rz8,2020-11-11,2020-10-30
-1rzy,2004-03-09,2003-12-29
-6rzz,2019-06-26,2019-06-13
-4rzj,2015-01-14,2014-12-22
-3rzc,2011-08-24,2011-05-11
-7rzf,2022-08-31,2021-08-27
-6rz0,2020-07-15,2019-06-12
-1rz6,2004-06-29,2003-12-24
-5rzc,2020-11-11,2020-10-30
-3rzd,2011-08-10,2011-05-11
-1rz0,2004-04-06,2003-12-23
-6rz2,2020-04-15,2019-06-12
-5rz4,2020-11-11,2020-10-30
-7rz8,2021-10-27,2021-08-27
-4rzv,2016-08-10,2014-12-24
-1rzd,1993-10-31,1993-05-25
-6rz7,2019-12-11,2019-06-12
-7rz7,2021-10-27,2021-08-27
-5rz2,2020-11-11,2020-10-30
-8rzl,2024-05-01,2024-02-12
-5rz6,2020-11-11,2020-10-30
-4rz3,2015-03-04,2014-12-18
-4rzc,2015-11-04,2014-12-19
-3rzb,2012-10-31,2011-05-11
-6rzg,2020-07-08,2019-06-13
-6rz3,2019-10-30,2019-06-12
-6rzr,2020-04-01,2019-06-13
-5rzl,2020-11-11,2020-10-30
-1rzu,2004-08-31,2003-12-29
-1rzb,1993-10-31,1993-05-25
-5rzk,2020-11-11,2020-10-30
-3rz1,2011-08-10,2011-05-11
-4rzg,2015-03-18,2014-12-21
-3rzu,2011-10-19,2011-05-12
-7rz6,2021-10-27,2021-08-27
-1rzg,2004-02-03,2003-12-24
-3rz3,2011-07-06,2011-05-11
-5rzp,2020-11-11,2020-10-30
-4rzw,2016-08-10,2014-12-24
-1rzt,2004-03-02,2003-12-29
-4rzx,2015-12-30,2014-12-26
-3rz5,2011-08-10,2011-05-11
-1rz3,2004-05-04,2003-12-23
-6rze,2019-08-07,2019-06-13
-3rze,2011-06-15,2011-05-11
-5rz9,2020-11-11,2020-10-30
-6rzi,2020-07-08,2019-06-13
-1rzj,2004-02-03,2003-12-24
-3rzi,2012-01-25,2011-05-11
-1rzq,2004-03-30,2003-12-26
-1rze,1993-10-31,1993-05-25
-5rzz,2020-11-11,2020-10-30
-6rza,2019-07-10,2019-06-13
-6rzx,2020-06-03,2019-06-13
-6rzf,2020-07-08,2019-06-13
-3rzj,2012-06-06,2011-05-11
-1rzc,1993-10-31,1993-05-25
-5rzq,2020-11-11,2020-10-30
-4rzb,2015-01-14,2014-12-19
-5rzy,2020-11-11,2020-10-30
-6rzs,2020-04-01,2019-06-13
-4rz7,2015-01-14,2014-12-18
-7rzn,2022-11-09,2021-08-27
-5rzj,2020-11-11,2020-10-30
-7rzl,2021-09-29,2021-08-27
-4rzq,2015-06-10,2014-12-23
-7rzd,2022-11-02,2021-08-27
-4rzz,2015-08-05,2014-12-27
-3rz2,2011-10-26,2011-05-11
-6rzl,2020-07-08,2019-06-13
-1rzk,2004-02-03,2003-12-24
-7rzp,2021-09-29,2021-08-27
-5rzg,2020-11-11,2020-10-30
-5rzd,2020-11-11,2020-10-30
-5rzv,2020-11-11,2020-10-30
-6rzb,2019-07-10,2019-06-13
-5rze,2020-11-11,2020-10-30
-6rzk,2020-07-08,2019-06-13
-3rzp,2011-06-29,2011-05-12
-5rzw,2020-11-11,2020-10-30
-7rz5,2021-10-27,2021-08-27
-7rzi,2022-08-31,2021-08-27
-1rzo,2004-12-28,2003-12-26
-6rz6,2019-12-11,2019-06-12
-7rzj,2022-11-02,2021-08-27
-5rzn,2020-11-11,2020-10-30
-5rzr,2020-11-11,2020-10-30
-7rzw,2022-04-13,2021-08-27
-1rzh,2004-04-13,2003-12-24
-3rzz,2011-07-20,2011-05-12
-4rzy,2015-08-05,2014-12-26
-1rzm,2004-08-10,2003-12-24
-3rzt,2011-12-28,2011-05-12
-7rzb,2022-04-13,2021-08-27
-5rz0,2020-11-11,2020-10-30
-5rzx,2020-11-11,2020-10-30
-7rzy,2022-06-08,2021-08-28
-7rzz,2022-04-13,2021-08-28
-6rz5,2019-10-30,2019-06-12
-6rzq,2019-10-02,2019-06-13
-5rzs,2020-11-11,2020-10-30
-3rzv,2011-10-19,2011-05-12
-1rza,1993-10-31,1993-05-25
-3rzf,2011-05-25,2011-05-11
-4rzr,2015-09-16,2014-12-23
-3rz6,2011-12-28,2011-05-11
-7rzc,2021-09-08,2021-08-27
-1rzz,2004-04-13,2003-12-29
-3rza,2011-06-08,2011-05-11
-6rz4,2019-10-30,2019-06-12
-1rzx,2004-01-27,2003-12-29
-5rzi,2020-11-11,2020-10-30
-6rzp,2019-07-17,2019-06-13
-5rza,2020-11-11,2020-10-30
-1rz5,2004-06-29,2003-12-24
-4rzt,2015-12-23,2014-12-24
-1aks,1997-02-12,1996-07-24
-1aky,1995-11-14,1995-07-28
-5akd,2015-07-22,2015-03-03
-3akd,2011-07-06,2010-07-12
-6ak3,2018-12-05,2018-08-29
-5ak0,2015-04-22,2015-02-27
-8akr,2024-02-14,2022-07-31
-8akn,2023-03-08,2022-07-30
-8akq,2024-02-14,2022-07-31
-1akc,1994-07-31,1994-02-28
-8akb,2023-08-16,2022-07-29
-2aka,2005-08-23,2005-08-03
-6akp,2019-02-06,2018-09-03
-7ak2,2021-05-26,2020-09-29
-1akj,1997-09-17,1997-05-21
-7ak7,2021-08-18,2020-09-30
-3akr,2011-06-01,2010-07-15
-8akj,2023-03-08,2022-07-29
-5ak3,2015-05-13,2015-03-02
-5aki,2015-05-13,2015-03-03
-5akl,2015-05-13,2015-03-03
-5akn,2015-06-17,2015-03-04
-5akm,2015-06-17,2015-03-04
-5ak7,2015-07-22,2015-03-02
-5akp,2016-05-04,2015-03-04
-5akk,2015-05-13,2015-03-03
-3akf,2010-08-25,2010-07-14
-7ak4,2020-12-02,2020-09-29
-2akf,2005-09-27,2005-08-03
-5akg,2015-05-13,2015-03-03
-4akd,2013-02-27,2012-02-22
-3akc,2011-07-06,2010-07-12
-3akn,2011-07-20,2010-07-14
-5ak2,2015-04-22,2015-02-27
-2akl,2006-07-18,2005-08-03
-1akl,1996-03-08,1995-09-16
-3akb,2011-01-26,2010-07-09
-3ak2,2011-02-02,2010-06-30
-3akk,2010-12-01,2010-07-14
-4ak8,2013-04-03,2012-02-22
-6ak5,2019-05-29,2018-08-30
-3akm,2011-07-20,2010-07-14
-7akj,2021-05-19,2020-10-01
-7aku,2020-10-28,2020-10-02
-8ak5,2023-08-16,2022-07-29
-3aky,1995-11-14,1995-07-28
-7akq,2021-10-20,2020-10-01
-2akj,2006-01-24,2005-08-03
-4aky,2012-09-05,2012-02-29
-8ak8,2023-08-16,2022-07-29
-5akb,2015-07-22,2015-03-03
-5ake,2015-05-13,2015-03-03
-6akx,2018-10-24,2018-09-04
-5akh,2015-05-13,2015-03-03
-7ak0,2020-12-09,2020-09-29
-4akb,2013-02-27,2012-02-22
-1akd,1997-11-19,1997-05-16
-7ak6,2021-02-03,2020-09-29
-2akr,2005-12-06,2005-08-03
-3ak5,2010-10-06,2010-07-07
-4akg,2012-03-14,2012-02-22
-7ak9,2021-08-18,2020-09-30
-1akr,1998-05-27,1997-05-27
-5ak8,2015-07-22,2015-03-02
-6akz,2019-09-11,2018-09-05
-5aka,2015-03-25,2015-03-03
-6akr,2020-02-12,2018-09-03
-8akg,2023-08-16,2022-07-29
-7akg,2020-12-02,2020-09-30
-2ak5,2005-10-11,2005-08-03
-3aka,2011-01-26,2010-07-09
-7akc,2020-12-09,2020-09-30
-5aks,2015-10-21,2015-03-05
-1akk,1997-09-17,1997-05-22
-7ak3,2020-11-11,2020-09-29
-7akf,2021-05-26,2020-09-30
-2akw,2005-12-27,2005-08-04
-7aks,2021-06-16,2020-10-02
-4akh,2012-03-14,2012-02-22
-7akl,2021-05-26,2020-10-01
-3ak4,2011-07-13,2010-07-07
-4akq,2012-03-14,2012-02-28
-3aki,2010-08-25,2010-07-14
-8akp,2022-12-28,2022-07-30
-5akr,2015-07-08,2015-03-05
-7ak1,2020-12-09,2020-09-29
-1akt,1998-05-27,1997-05-27
-1akn,1998-05-27,1997-05-23
-8ak6,2023-08-16,2022-07-29
-8ak3,2023-03-29,2022-07-29
-1akq,1998-12-02,1997-03-27
-2ako,2005-08-09,2005-08-03
-5akx,2015-05-13,2015-03-05
-4ako,2012-03-14,2012-02-28
-5akc,2015-07-22,2015-03-03
-8akh,2023-04-26,2022-07-29
-2ake,2006-07-11,2005-08-03
-7akr,2021-06-16,2020-10-02
-7akt,2021-10-13,2020-10-02
-1ake,1994-01-31,1991-11-08
-2aky,1995-11-14,1995-07-28
-7akb,2021-05-26,2020-09-30
-3akg,2010-08-25,2010-07-14
-7ak8,2021-08-18,2020-09-30
-7ako,2021-04-14,2020-10-01
-6akd,2019-03-06,2018-08-31
-6akn,2019-09-04,2018-09-03
-2akm,2006-03-21,2005-08-03
-5akj,2015-05-13,2015-03-03
-5ak5,2015-05-13,2015-03-02
-1aka,1994-07-31,1994-02-28
-3ak9,2011-01-12,2010-07-08
-7ake,2021-05-26,2020-09-30
-5akw,2015-07-29,2015-03-05
-1ak0,1997-12-03,1997-05-28
-1akw,1998-05-27,1997-05-27
-1aku,1998-12-02,1997-05-27
-4ak3,2012-09-12,2012-02-21
-5ak9,2015-06-17,2015-03-02
-5akv,2015-10-21,2015-03-05
-5ak6,2015-05-13,2015-03-02
-7akh,2021-05-26,2020-10-01
-8ak7,2023-08-16,2022-07-29
-8ak4,2023-09-27,2022-07-29
-5akt,2015-10-21,2015-03-05
-4akm,2012-08-15,2012-02-24
-8akf,2023-08-16,2022-07-29
-7akn,2020-12-02,2020-10-01
-5ak4,2015-05-13,2015-03-02
-5akf,2015-06-17,2015-03-03
-1ak8,1997-09-17,1997-05-29
-3akh,2010-08-25,2010-07-14
-4ak6,2012-03-21,2012-02-21
-3ak3,2011-02-02,2010-06-30
-6akh,2019-05-29,2018-08-31
-1akb,1994-07-31,1994-02-28
-8ak9,2023-08-16,2022-07-29
-7aka,2021-05-26,2020-09-30
-7akw,2020-11-25,2020-10-02
-4aki,2012-03-14,2012-02-22
-3ak0,2011-05-18,2010-06-29
-3akq,2011-06-01,2010-07-15
-4akn,2012-07-04,2012-02-26
-6aky,2018-10-24,2018-09-04
-8aki,2023-03-08,2022-07-29
-5aky,2015-05-13,2015-03-05
-6ak8,2019-05-29,2018-08-30
-8akt,2024-02-14,2022-07-31
-4ak7,2012-03-14,2012-02-21
-2akz,2006-03-21,2005-08-04
-8aks,2024-02-14,2022-07-31
-6ako,2019-02-06,2018-09-03
-3akz,2010-09-29,2010-07-19
-8aka,2023-08-16,2022-07-29
-2ak3,1995-05-08,1995-03-07
-8akm,2023-03-08,2022-07-29
-8akc,2023-08-16,2022-07-29
-1akv,1998-12-02,1997-05-27
-3aks,2011-06-01,2010-07-15
-4ak5,2012-03-14,2012-02-21
-4akp,2012-03-14,2012-02-28
-7akd,2021-05-19,2020-09-30
-7akk,2022-04-13,2020-10-01
-7akm,2021-04-14,2020-10-01
-3akl,2010-12-01,2010-07-14
-8akl,2023-03-08,2022-07-29
-7aki,2020-11-25,2020-10-01
-8ake,2023-08-16,2022-07-29
-1ak9,1997-11-12,1997-05-30
-8akk,2023-03-08,2022-07-29
-8akd,2023-08-16,2022-07-29
-5aku,2015-07-29,2015-03-05
-6ak6,2019-05-29,2018-08-30
-2ak1,2006-02-14,2005-08-02
-4ak1,2013-03-06,2012-02-21
-6ak9,2019-05-29,2018-08-30
-6ak4,2019-07-10,2018-08-30
-4akt,2012-07-18,2012-02-28
-7ak5,2021-02-03,2020-09-29
-4akj,2013-01-09,2012-02-23
-5akz,2015-05-13,2015-03-05
-6akw,2019-05-29,2018-09-04
-6ak7,2019-09-11,2018-08-30
-5akq,2015-03-18,2015-03-05
-4akc,2013-02-27,2012-02-22
-6akv,2019-02-13,2018-09-03
-3ak8,2011-01-12,2010-07-08
-105m,1998-04-08,1997-12-18
-7vef,2022-01-12,2021-09-08
-7vec,2022-03-30,2021-09-08
-3vek,2013-01-16,2012-01-09
-3vet,2012-01-25,2012-01-09
-5ve7,2017-04-12,2017-04-04
-5vej,2017-07-19,2017-04-04
-2vey,2007-11-06,2007-10-27
-2ved,2008-07-01,2007-10-19
-8vep,2024-03-20,2023-12-20
-5veg,2017-10-11,2017-04-04
-3vef,2012-01-18,2012-01-07
-8vev,2024-02-07,2023-12-20
-7vek,2022-03-02,2021-09-09
-2vev,2007-11-06,2007-10-27
-2vek,2008-02-19,2007-10-24
-1ve9,2004-04-13,2004-03-29
-7ve0,2023-02-01,2021-09-07
-6veb,2020-03-04,2019-12-31
-7vei,2022-04-06,2021-09-08
-3vey,2012-02-08,2012-01-09
-3ves,2012-01-25,2012-01-09
-5vew,2017-05-24,2017-04-05
-2ver,2008-01-08,2007-10-26
-3ven,2012-01-25,2012-01-09
-1vel,2004-06-29,2004-04-01
-7ve3,2021-09-22,2021-09-07
-7veb,2022-06-15,2021-09-08
-1vei,2004-06-29,2004-03-31
-6veq,2020-06-03,2020-01-02
-2ves,2008-01-15,2007-10-26
-1vea,2004-07-20,2004-03-29
-5vep,2017-11-29,2017-04-05
-5ve9,2017-06-21,2017-04-04
-2ve1,2008-11-04,2007-10-15
-7vex,2021-11-03,2021-09-10
-5ver,2017-11-29,2017-04-05
-6vei,2020-02-05,2020-01-02
-6vez,2021-09-01,2020-01-03
-2vew,2007-11-06,2007-10-27
-5ve2,2017-04-19,2017-04-03
-7vew,2022-08-17,2021-09-10
-3veg,2012-01-18,2012-01-07
-7vej,2022-03-02,2021-09-09
-1ven,2005-05-24,2004-04-03
-1vem,2005-05-24,2004-04-03
-7vev,2022-08-17,2021-09-10
-5vez,2017-05-10,2017-04-06
-1ve5,2005-04-19,2004-03-27
-1ve3,2005-05-24,2004-03-26
-1vew,1998-05-27,1998-01-20
-5veb,2017-06-07,2017-04-04
-6ve8,2020-09-23,2019-12-30
-6vea,2020-09-23,2019-12-30
-8veo,2024-04-24,2023-12-20
-1vep,2005-05-24,2004-04-03
-2ve3,2008-04-29,2007-10-15
-3vee,2012-01-18,2012-01-07
-3vev,2012-02-08,2012-01-09
-7vem,2021-11-10,2021-09-09
-6ven,2020-01-15,2020-01-02
-7veu,2022-08-17,2021-09-10
-1veq,2004-06-29,2004-04-03
-6vel,2020-01-29,2020-01-02
-7ve6,2022-05-18,2021-09-08
-5vem,2017-09-20,2017-04-05
-1ve7,2004-11-02,2004-03-27
-7vea,2022-06-22,2021-09-08
-2vee,2008-01-22,2007-10-22
-8ve5,2024-06-05,2023-12-18
-5vex,2017-05-17,2017-04-05
-2vem,2008-02-19,2007-10-25
-3ve7,2013-01-09,2012-01-07
-2vea,2008-09-30,2007-10-18
-1veo,2005-05-24,2004-04-03
-5ve4,2017-07-19,2017-04-03
-6vec,2020-12-09,2019-12-31
-7veg,2022-10-19,2021-09-08
-3ver,2012-01-25,2012-01-09
-5vef,2017-10-18,2017-04-04
-5vev,2017-04-12,2017-04-05
-5veo,2017-09-20,2017-04-05
-3vew,2012-01-25,2012-01-09
-3ve0,2012-04-18,2012-01-06
-5vee,2017-10-18,2017-04-04
-7veo,2022-09-28,2021-09-09
-3vez,2012-01-25,2012-01-09
-2vet,2007-12-04,2007-10-26
-3ve2,2012-02-22,2012-01-06
-1vey,2005-08-23,2004-04-06
-7ve2,2023-02-01,2021-09-07
-5ve5,2017-07-19,2017-04-03
-3ve5,2012-12-19,2012-01-07
-2vez,2009-03-10,2007-10-27
-6veo,2020-10-28,2020-01-02
-2veu,2007-11-06,2007-10-27
-1vev,2005-08-23,2004-04-06
-1vef,2005-08-02,2004-03-30
-2vex,2007-11-06,2007-10-27
-6ve0,2021-03-10,2019-12-27
-2vel,2008-02-19,2007-10-24
-5ved,2017-10-18,2017-04-04
-1ve1,2005-04-19,2004-03-26
-5ven,2017-09-20,2017-04-05
-1ve0,2005-03-22,2004-03-26
-6vef,2021-01-06,2019-12-31
-8veh,2023-12-27,2023-12-19
-3veq,2012-10-03,2012-01-09
-5vea,2018-04-25,2017-04-04
-2veg,2008-03-25,2007-10-24
-7vez,2021-11-10,2021-09-10
-6ve7,2020-02-05,2019-12-30
-5ve3,2017-07-19,2017-04-03
-2ve4,2008-04-29,2007-10-16
-5veq,2017-11-29,2017-04-05
-7vel,2022-03-02,2021-09-09
-7ve7,2022-05-11,2021-09-08
-5veu,2017-11-15,2017-04-05
-3veh,2012-06-13,2012-01-08
-8vec,2024-03-20,2023-12-18
-3veo,2012-01-25,2012-01-09
-2veb,2008-01-22,2007-10-18
-3ve3,2013-03-20,2012-01-07
-3vec,2012-01-18,2012-01-07
-3ve1,2012-02-22,2012-01-06
-2ve6,2008-01-22,2007-10-17
-7ve5,2022-05-18,2021-09-08
-8ve1,2024-06-05,2023-12-18
-3veu,2012-11-21,2012-01-09
-8ve0,2024-01-31,2023-12-18
-3ved,2012-01-18,2012-01-07
-8ve6,2024-06-05,2023-12-18
-6vep,2020-06-03,2020-01-02
-3vex,2012-01-25,2012-01-09
-3ve4,2013-03-20,2012-01-07
-6ve1,2020-11-25,2019-12-28
-1vec,2004-04-13,2004-03-29
-8veq,2024-03-20,2023-12-20
-1vez,2005-08-23,2004-04-06
-1veb,2005-03-29,2004-03-29
-5vec,2018-06-27,2017-04-04
-4mvr,2013-11-27,2013-09-24
-3mvc,2010-06-16,2010-05-03
-2mvw,2014-11-12,2014-10-17
-1mvt,2003-04-01,2002-09-26
-6mv0,2019-03-27,2018-10-24
-6mv5,2019-04-10,2018-10-24
-2mvv,2015-10-21,2014-10-15
-4mv0,2014-06-11,2013-09-23
-6mv7,2019-11-13,2018-10-24
-3mvi,2010-11-03,2010-05-04
-6mvq,2019-09-04,2018-10-26
-5mvc,2017-03-08,2017-01-16
-6mv4,2019-02-20,2018-10-24
-4mvx,2014-04-30,2013-09-24
-5mvm,2018-03-14,2017-01-16
-4mvt,2013-10-16,2013-09-24
-5mvw,2017-06-28,2017-01-17
-5mvn,2018-02-14,2017-01-16
-4mvz,2013-11-27,2013-09-24
-1mvm,1998-02-25,1996-06-21
-1mv8,2003-05-06,2002-09-24
-6mvf,2019-01-30,2018-10-25
-1mvc,2002-10-16,2002-09-24
-4mv8,2015-01-14,2013-09-23
-6mv1,2019-07-17,2018-10-24
-6mvh,2019-01-30,2018-10-25
-3mv0,2011-03-16,2010-05-03
-3mv6,2011-06-01,2010-05-03
-3mvx,2011-02-09,2010-05-05
-6mva,2019-10-30,2018-10-24
-3mv1,2011-03-16,2010-05-03
-5mv8,2017-07-05,2017-01-16
-7mvs,2021-10-20,2021-05-15
-1mvs,2003-04-01,2002-09-26
-5mvo,2018-02-28,2017-01-17
-4mvl,2015-08-12,2013-09-24
-4mvw,2014-04-30,2013-09-24
-5mvx,2017-06-14,2017-01-17
-4mvb,2015-08-19,2013-09-23
-4mvf,2014-09-03,2013-09-24
-6mvn,2019-01-16,2018-10-26
-1mvy,2002-12-18,2002-09-27
-5mv6,2017-04-05,2017-01-15
-3mvl,2010-10-13,2010-05-04
-5mva,2017-11-29,2017-01-16
-2mvi,2014-12-10,2014-10-06
-5mvr,2017-09-20,2017-01-17
-6mvg,2019-01-30,2018-10-25
-3mvk,2010-05-12,2010-05-04
-3mvf,2010-06-23,2010-05-04
-6mv2,2019-07-17,2018-10-24
-4mvm,2013-11-27,2013-09-24
-5mv5,2017-04-05,2017-01-15
-4mvq,2013-11-27,2013-09-24
-6mvx,2018-12-05,2018-10-28
-4mvy,2014-04-30,2013-09-24
-3mvw,2011-02-09,2010-05-05
-3mvy,2011-02-09,2010-05-05
-3mvj,2010-06-02,2010-05-04
-1mv5,2003-12-02,2002-09-24
-6mvs,2018-12-26,2018-10-28
-4mv5,2014-06-18,2013-09-23
-4mvd,2013-12-11,2013-09-23
-7mvv,2022-06-15,2021-05-15
-3mvv,2011-03-16,2010-05-04
-6mvu,2018-12-26,2018-10-28
-6mvp,2019-09-04,2018-10-26
-1mvo,2002-10-16,2002-09-26
-4mvh,2013-10-23,2013-09-24
-1mvl,2003-03-04,2002-09-26
-5mvf,2017-03-08,2017-01-16
-4mvo,2013-11-27,2013-09-24
-6mvd,2018-12-05,2018-10-25
-6mvm,2019-01-16,2018-10-26
-1mvq,2003-10-07,2002-09-26
-3mv4,2011-06-01,2010-05-03
-5mvd,2017-03-08,2017-01-16
-6mvk,2019-09-04,2018-10-26
-6mv9,2019-06-19,2018-10-24
-4mv1,2015-01-14,2013-09-23
-4mvn,2014-01-22,2013-09-24
-6mvj,2019-10-30,2018-10-25
-1mvn,2003-03-04,2002-09-26
-4mv6,2015-01-14,2013-09-23
-6mvt,2018-12-26,2018-10-28
-6mv8,2019-10-30,2018-10-24
-4mv4,2015-01-14,2013-09-23
-4mva,2014-04-16,2013-09-23
-2mvu,2015-10-21,2014-10-15
-6mve,2019-06-19,2018-10-25
-4mv3,2015-01-14,2013-09-23
-1mvh,2002-10-30,2002-09-25
-5mvv,2017-07-12,2017-01-17
-4mvk,2015-08-12,2013-09-24
-6mvl,2019-10-23,2018-10-26
-6mv3,2018-11-14,2018-10-24
-4mvs,2013-11-27,2013-09-24
-4mvj,2014-04-23,2013-09-24
-3mvm,2010-10-13,2010-05-04
-1mvx,2002-10-30,2002-09-26
-5mvs,2017-03-22,2017-01-17
-3mv5,2010-06-02,2010-05-03
-3mvr,2010-09-29,2010-05-04
-4mvc,2013-12-11,2013-09-23
-3mvh,2010-06-02,2010-05-04
-4mvu,2013-11-27,2013-09-24
-4mv2,2013-10-02,2013-09-23
-6mvo,2019-09-04,2018-10-26
-1mve,2003-07-15,2002-09-25
-3mvz,2011-02-09,2010-05-05
-5mvy,2018-02-14,2017-01-17
-3mvs,2010-06-09,2010-05-04
-148l,1994-04-30,1993-10-27
-5c3a,2015-09-23,2015-06-17
-8c3p,2023-11-22,2022-12-28
-2c3e,2005-10-20,2005-10-06
-7c33,2020-11-11,2020-05-11
-4c3k,2014-02-12,2013-08-25
-8c35,2023-08-16,2022-12-23
-3c3x,2008-05-06,2008-01-29
-5c3s,2015-10-21,2015-06-17
-1c3v,2003-08-26,1999-07-28
-2c38,2005-11-23,2005-10-04
-6c32,2019-01-23,2018-01-09
-1c3s,1999-09-15,1999-07-28
-1c3h,2003-12-09,1999-07-27
-4c3w,2014-07-09,2013-08-28
-7c3a,2021-05-26,2020-05-11
-2c31,2005-10-07,2005-10-03
-2c3p,2006-02-15,2005-10-11
-7c3q,2020-06-10,2020-05-13
-1c3o,1999-12-10,1999-07-28
-8c3v,2023-03-22,2022-12-28
-2c3c,2005-12-12,2005-10-05
-7c3l,2020-09-23,2020-05-12
-3c37,2008-02-12,2008-01-27
-2c3k,2005-11-23,2005-10-10
-7c3i,2020-09-23,2020-05-12
-5c3c,2015-11-18,2015-06-17
-6c3g,2018-04-18,2018-01-09
-1c3j,1999-08-09,1999-07-28
-1c3i,2000-07-26,1999-07-27
-2c3y,2006-02-15,2005-10-13
-8c3j,2023-11-29,2022-12-26
-7c3g,2021-03-03,2020-05-12
-3c32,2008-06-17,2008-01-27
-7c3v,2021-05-19,2020-05-14
-8c39,2024-01-10,2022-12-23
-6c34,2018-03-28,2018-01-09
-2c36,2005-11-23,2005-10-04
-3c35,2008-06-17,2008-01-27
-4c3h,2013-10-23,2013-08-24
-5c3k,2015-08-12,2015-06-17
-3c36,2008-06-17,2008-01-27
-4c3b,2014-01-22,2013-08-22
-7c3n,2020-06-24,2020-05-13
-8c3q,2024-01-10,2022-12-28
-6c3h,2019-01-16,2018-01-09
-2c3l,2005-11-23,2005-10-10
-6c3p,2018-01-24,2018-01-10
-7c34,2020-05-27,2020-05-11
-1c3w,1999-09-15,1999-07-28
-2c37,2005-11-23,2005-10-04
-5c3m,2016-06-29,2015-06-17
-6c35,2018-03-28,2018-01-09
-7c3y,2020-06-17,2020-05-14
-4c3j,2013-10-23,2013-08-24
-8c34,2023-08-16,2022-12-23
-5c3h,2015-08-12,2015-06-17
-8c3f,2023-03-08,2022-12-23
-6c3x,2018-06-13,2018-01-11
-5c36,2015-09-23,2015-06-17
-2c39,2005-11-23,2005-10-05
-6c3j,2019-01-16,2018-01-09
-3c3t,2008-04-22,2008-01-28
-8c3n,2023-03-08,2022-12-27
-5c3x,2015-07-01,2015-06-17
-2c3a,2005-12-21,2005-10-05
-3c33,2008-06-17,2008-01-27
-4c34,2013-10-09,2013-08-21
-8c3a,2024-01-10,2022-12-23
-8c3u,2023-09-13,2022-12-28
-5c3j,2016-06-22,2015-06-17
-8c33,2023-08-16,2022-12-23
-8c36,2023-08-16,2022-12-23
-7c3s,2021-05-26,2020-05-14
-1c3b,1999-11-24,1999-07-27
-3c34,2008-06-17,2008-01-27
-2c3f,2005-11-29,2005-10-06
-6c33,2018-03-28,2018-01-09
-3c3u,2008-08-26,2008-01-28
-8c3d,2023-09-27,2022-12-23
-4c3r,2014-05-28,2013-08-26
-7c3b,2021-05-26,2020-05-11
-4c3s,2013-09-11,2013-08-27
-5c3p,2015-10-21,2015-06-17
-8c3c,2023-06-14,2022-12-23
-7c38,2020-07-29,2020-05-11
-5c3o,2015-10-21,2015-06-17
-6c3t,2018-04-18,2018-01-10
-4c3u,2014-08-20,2013-08-27
-7c3f,2020-10-14,2020-05-12
-6c3z,2018-06-13,2018-01-11
-4c36,2013-10-09,2013-08-21
-7c3c,2020-07-29,2020-05-12
-8c3g,2024-01-10,2022-12-23
-6c36,2018-03-28,2018-01-09
-8c30,2024-01-10,2022-12-23
-5c3u,2015-12-09,2015-06-17
-8c3h,2023-02-08,2022-12-23
-4c3a,2014-04-02,2013-08-22
-1c3q,1999-08-09,1999-07-28
-5c38,2015-09-23,2015-06-17
-5c37,2016-06-22,2015-06-17
-6c3u,2018-12-26,2018-01-10
-8c3z,2023-12-27,2022-12-30
-3c3s,2008-04-22,2008-01-28
-3c3c,2008-07-01,2008-01-28
-7c3h,2020-09-23,2020-05-12
-6c39,2018-11-07,2018-01-09
-1c3r,1999-09-15,1999-07-28
-1c3m,2000-01-10,1999-07-28
-4c3x,2013-11-06,2013-08-28
-2c3q,2005-11-30,2005-10-11
-4c3d,2014-01-22,2013-08-22
-4c3o,2014-01-29,2013-08-26
-6c3d,2018-03-07,2018-01-09
-7c3k,2021-04-21,2020-05-12
-3c3v,2009-02-24,2008-01-28
-6c3e,2018-03-21,2018-01-09
-6c37,2019-01-16,2018-01-09
-3c3d,2008-02-19,2008-01-28
-7c39,2020-07-29,2020-05-11
-8c3b,2024-01-10,2022-12-23
-3c3i,2009-02-10,2008-01-28
-5c3y,2016-06-15,2015-06-17
-2c3g,2005-10-17,2005-10-07
-2c3h,2005-10-17,2005-10-07
-6c3s,2018-04-18,2018-01-10
-3c3b,2008-07-01,2008-01-28
-4c37,2013-10-09,2013-08-21
-4c38,2013-10-09,2013-08-21
-4c39,2014-04-02,2013-08-22
-8c3i,2024-01-10,2022-12-24
-4c30,2013-10-30,2013-08-21
-5c3d,2015-09-23,2015-06-17
-4c3e,2014-01-22,2013-08-22
-3c3n,2008-04-29,2008-01-28
-8c3w,2023-07-05,2022-12-29
-4c35,2013-10-09,2013-08-21
-6c3a,2018-03-07,2018-01-09
-1c39,2000-01-14,1999-07-25
-7c3d,2020-07-29,2020-05-12
-4c3p,2014-05-28,2013-08-26
-7c3o,2021-05-19,2020-05-13
-2c3o,2006-02-15,2005-10-11
-7c3t,2021-05-26,2020-05-14
-6c3m,2018-06-13,2018-01-10
-6c3k,2018-11-07,2018-01-10
-4c31,2014-04-16,2013-08-21
-6c3f,2018-04-18,2018-01-09
-4c3q,2014-07-09,2013-08-26
-6c3n,2019-01-16,2018-01-10
-1c3n,2000-01-10,1999-07-28
-7c3u,2021-05-26,2020-05-14
-8c3m,2023-07-12,2022-12-26
-4c3t,2014-09-10,2013-08-27
-5c39,2015-10-21,2015-06-17
-4c3v,2014-08-20,2013-08-27
-5c3e,2015-08-26,2015-06-17
-5c3z,2016-06-15,2015-06-17
-7c3j,2020-09-23,2020-05-12
-8c37,2023-08-16,2022-12-23
-1c3x,1999-12-22,1999-07-29
-2c3u,2006-02-15,2005-10-12
-6c3o,2018-01-31,2018-01-10
-5c3r,2015-10-21,2015-06-17
-2c3j,2005-11-23,2005-10-10
-2c3i,2005-11-01,2005-10-07
-1c30,1999-12-10,1999-07-24
-6c3l,2019-01-16,2018-01-10
-8c3o,2023-11-22,2022-12-27
-4c3f,2013-10-23,2013-08-23
-3c3y,2008-04-01,2008-01-29
-2c3x,2005-10-17,2005-10-12
-5c3q,2015-10-21,2015-06-17
-4c3i,2013-10-23,2013-08-24
-2c3w,2005-10-17,2005-10-12
-2c3d,2005-11-07,2005-10-05
-5c3b,2015-09-23,2015-06-17
-3c3a,2008-07-01,2008-01-28
-6c3y,2018-06-13,2018-01-11
-8c3r,2024-01-10,2022-12-28
-8c32,2023-08-16,2022-12-23
-1c3l,1999-08-04,1999-07-28
-2c3m,2006-02-15,2005-10-11
-8c31,2023-08-16,2022-12-23
-5c3w,2015-07-15,2015-06-17
-3c3e,2008-02-19,2008-01-28
-4c3y,2013-11-06,2013-08-28
-1c3e,1999-12-29,1999-07-27
-3c31,2008-06-17,2008-01-27
-6c3c,2018-03-07,2018-01-09
-6z1u,2020-09-09,2020-05-14
-5z1w,2018-03-28,2017-12-28
-4z11,2016-03-23,2015-03-26
-4z16,2016-02-10,2015-03-26
-7z1e,2022-03-23,2022-02-24
-6z19,2021-05-26,2020-05-13
-7z1i,2023-03-08,2022-02-24
-2z1n,2008-03-18,2007-05-10
-5z1c,2018-12-26,2017-12-25
-7z1l,2022-08-31,2022-02-24
-2z1x,2007-11-06,2007-05-16
-7z1k,2022-12-07,2022-02-24
-7z1a,2022-03-23,2022-02-24
-7z16,2022-06-22,2022-02-24
-7z13,2022-06-15,2022-02-24
-6z1q,2020-07-08,2020-05-14
-7z14,2022-08-17,2022-02-24
-4z1q,2015-04-08,2015-03-27
-5z1n,2018-10-17,2017-12-27
-7z1g,2023-03-08,2022-02-24
-2z1a,2007-11-13,2007-05-08
-4z1c,2016-03-09,2015-03-27
-6z1e,2020-09-23,2020-05-13
-7z17,2022-05-25,2022-02-24
-5z1e,2019-01-02,2017-12-26
-6z15,2021-04-21,2020-05-12
-1z1c,2005-09-06,2005-03-03
-6z17,2020-09-16,2020-05-12
-4z1m,2015-05-06,2015-03-27
-4z17,2015-07-01,2015-03-26
-7z1s,2022-07-13,2022-02-25
-5z1z,2018-09-19,2017-12-28
-6z1n,2020-10-21,2020-05-14
-6z11,2020-11-04,2020-05-11
-4z14,2016-06-29,2015-03-26
-5z1b,2018-12-12,2017-12-25
-6z1a,2020-11-11,2020-05-13
-8z10,2024-05-22,2024-04-10
-7z15,2022-06-22,2022-02-24
-2z1z,2007-07-17,2007-05-16
-7z1j,2022-03-16,2022-02-24
-7z1w,2023-01-25,2022-02-25
-7z1r,2022-07-13,2022-02-25
-5z1d,2019-01-02,2017-12-26
-4z1i,2015-04-29,2015-03-27
-1z1w,2005-05-31,2005-03-07
-4z1j,2015-08-26,2015-03-27
-1z16,2005-10-04,2005-03-03
-5z1a,2018-12-12,2017-12-25
-7z1o,2022-08-31,2022-02-24
-2z1y,2008-06-03,2007-05-16
-6z1k,2021-08-25,2020-05-13
-6z1f,2020-09-23,2020-05-13
-2z18,2008-03-18,2007-05-08
-5z15,2018-07-04,2017-12-25
-4z1g,2015-04-22,2015-03-27
-4z1s,2015-04-08,2015-03-27
-4z12,2016-03-23,2015-03-26
-5z14,2018-07-04,2017-12-25
-5z16,2019-02-20,2017-12-25
-1z1l,2005-06-21,2005-03-04
-4z1o,2015-04-29,2015-03-27
-7z1y,2023-01-25,2022-02-25
-5z1s,2019-01-02,2017-12-28
-2z1s,2007-10-02,2007-05-12
-4z1d,2016-03-09,2015-03-27
-1z1h,2005-03-22,2005-03-04
-7z1d,2022-03-23,2022-02-24
-6z1m,2020-07-22,2020-05-14
-7z18,2022-05-25,2022-02-24
-1z18,2005-10-04,2005-03-03
-1z1q,2005-06-21,2005-03-04
-6z1p,2020-06-24,2020-05-14
-5z1q,2018-04-25,2017-12-27
-4z1e,2015-08-26,2015-03-27
-4z1h,2015-04-22,2015-03-27
-6z1s,2021-03-24,2020-05-14
-4z1v,2016-01-13,2015-03-27
-7z19,2022-05-25,2022-02-24
-1z11,2005-08-16,2005-03-02
-6z1w,2021-03-03,2020-05-14
-7z10,2022-08-03,2022-02-24
-2z1u,2007-10-09,2007-05-15
-4z1y,2015-07-01,2015-03-27
-6z16,2020-08-12,2020-05-12
-6z1t,2020-07-08,2020-05-14
-7z1q,2022-07-13,2022-02-25
-2z1m,2007-11-13,2007-05-09
-4z1k,2015-08-26,2015-03-27
-6z1r,2020-09-09,2020-05-14
-1z10,2005-08-16,2005-03-02
-7z1n,2022-08-31,2022-02-24
-6z1d,2020-09-23,2020-05-13
-2z1k,2008-05-13,2007-05-08
-2z1v,2007-11-06,2007-05-15
-7z1v,2023-01-25,2022-02-25
-4z1f,2015-04-22,2015-03-27
-6z1y,2020-05-27,2020-05-14
-1z1s,2005-04-19,2005-03-06
-6z1c,2021-03-24,2020-05-13
-5z1t,2019-01-02,2017-12-28
-4z1w,2016-01-20,2015-03-27
-6z1x,2021-03-03,2020-05-14
-5z12,2018-07-04,2017-12-23
-7z1c,2022-03-23,2022-02-24
-2z12,2008-03-18,2007-05-07
-5z19,2018-12-12,2017-12-25
-6z1b,2022-06-01,2020-05-13
-6z13,2021-05-26,2020-05-12
-7z11,2022-09-21,2022-02-24
-1z17,2005-10-04,2005-03-03
-1z1y,2005-12-06,2005-03-07
-4z1n,2015-08-26,2015-03-27
-7z1f,2023-03-08,2022-02-24
-7z1m,2022-08-31,2022-02-24
-1z1f,2005-08-30,2005-03-03
-6z14,2021-05-19,2020-05-12
-4z1z,2016-03-30,2015-03-27
-6z10,2020-09-16,2020-05-11
-1z1n,2006-04-04,2005-03-04
-4z1x,2015-04-22,2015-03-27
-5z1r,2019-01-02,2017-12-28
-7z1b,2022-03-23,2022-02-24
-2z1q,2008-05-13,2007-05-11
-1z1r,2005-03-22,2005-03-06
-7z1z,2022-05-11,2022-02-25
-4z10,2016-04-06,2015-03-26
-4z13,2016-03-23,2015-03-26
-4z1l,2015-05-27,2015-03-27
-7z1u,2022-09-07,2022-02-25
-2z1w,2007-11-06,2007-05-16
-6z1j,2020-12-02,2020-05-13
-5z1x,2018-09-05,2017-12-28
-2z19,2008-03-18,2007-05-08
-3rs0,2011-09-21,2011-05-02
-5rsv,2020-12-16,2020-09-28
-7rsf,2021-08-18,2021-08-11
-2rsj,2013-03-13,2012-03-07
-4rsy,2015-12-02,2014-11-12
-4rsr,2014-12-10,2014-11-10
-6rs6,2019-09-11,2019-05-21
-2rs3,1990-01-15,1988-10-03
-6rsv,2020-07-08,2019-05-22
-1rsi,2004-03-30,2003-12-09
-5rsc,2020-12-16,2020-09-28
-4rsg,2015-11-04,2014-11-07
-3rsz,2011-08-10,2011-05-02
-1rse,1996-12-23,1996-06-20
-3rse,2011-06-01,2011-05-02
-7rs7,2021-09-22,2021-08-11
-7rs3,2021-09-08,2021-08-10
-3rs5,2011-09-21,2011-05-02
-4rsk,1998-12-09,1998-04-09
-5rsj,2020-12-16,2020-09-28
-2rs2,2011-12-28,2011-06-27
-7rsj,2021-11-24,2021-08-11
-7rsc,2021-09-22,2021-08-11
-7rs6,2022-08-17,2021-08-11
-5rsh,2020-12-16,2020-09-28
-6rsr,2020-01-01,2019-05-22
-1rsm,1986-01-21,1985-08-27
-3rs7,2011-09-21,2011-05-02
-1rs2,2004-03-30,2003-12-09
-5rsx,2020-12-16,2020-09-28
-7rsm,2022-07-20,2021-08-11
-2rsi,2013-03-13,2012-03-07
-3rsv,2011-08-31,2011-05-02
-6rse,2020-07-08,2019-05-21
-5rsl,2020-12-16,2020-09-28
-6rs5,2020-04-15,2019-05-21
-4rss,2015-10-21,2014-11-11
-4rsm,2014-12-10,2014-11-08
-6rs9,2019-09-11,2019-05-21
-3rsf,2011-06-22,2011-05-02
-8rsb,2024-05-29,2024-01-24
-6rsw,2019-11-27,2019-05-22
-3rso,2011-09-21,2011-05-02
-7rs4,2021-09-08,2021-08-10
-6rsa,1986-05-07,1986-02-25
-5rso,2020-12-16,2020-09-28
-4rs0,2015-04-08,2014-11-06
-4rso,2016-04-13,2014-11-10
-1rsn,1995-12-07,1995-09-01
-3rs9,2011-06-22,2011-05-02
-7rst,2022-08-24,2021-08-11
-1rst,1997-05-15,1995-10-19
-3rsr,2012-11-14,2011-05-02
-3rsm,2012-02-29,2011-05-02
-9rsa,1991-04-15,1989-08-28
-6rsy,2020-04-15,2019-05-22
-3rsg,2011-07-27,2011-05-02
-5rsp,2020-12-16,2020-09-28
-2rs5,1990-01-15,1988-10-03
-6rsb,2020-07-08,2019-05-21
-1rs0,2004-12-14,2003-12-09
-4rs1,2015-11-11,2014-11-06
-3rsq,2011-06-22,2011-05-02
-6rs8,2019-09-11,2019-05-21
-6rst,2020-01-01,2019-05-22
-4rsl,2015-05-20,2014-11-08
-5rsr,2020-12-16,2020-09-28
-1rsr,2003-12-23,2003-12-10
-6rsc,2020-07-08,2019-05-21
-4rs2,2014-11-19,2014-11-06
-7rsh,2022-11-23,2021-08-11
-3rsl,2011-09-21,2011-05-02
-2rsh,2013-03-13,2012-03-07
-3rsc,2011-08-10,2011-05-02
-5rsw,2020-12-16,2020-09-28
-3rsx,2011-08-31,2011-05-02
-6rs0,2020-07-08,2019-05-20
-7rs8,2021-09-22,2021-08-11
-7rsv,2021-11-24,2021-08-11
-5rsk,2020-12-16,2020-09-28
-5rsd,2020-12-16,2020-09-28
-6rsd,2020-07-08,2019-05-21
-7rsz,2022-06-08,2021-08-12
-3rsn,2011-06-22,2011-05-02
-1rs7,2004-05-18,2003-12-09
-5rsm,2020-12-16,2020-09-28
-7rse,2021-09-22,2021-08-11
-5rsu,2020-12-16,2020-09-28
-1rsg,2005-02-15,2003-12-09
-5rs7,2020-12-16,2020-09-28
-5rsz,2020-12-16,2020-09-28
-5rs9,2020-12-16,2020-09-28
-1rs9,2004-06-15,2003-12-09
-5rsy,2020-12-16,2020-09-28
-4rs3,2014-11-19,2014-11-06
-1rsz,2005-02-22,2003-12-10
-4rse,2015-04-15,2014-11-07
-2rsf,2013-03-06,2012-01-31
-4rsz,2015-01-14,2014-11-12
-5rsf,2020-12-16,2020-09-28
-6rsx,2020-10-28,2019-05-22
-6rsh,2020-07-08,2019-05-21
-3rsj,2011-08-17,2011-05-02
-7rs9,2021-09-08,2021-08-11
-3rsb,2011-05-18,2011-05-02
-1rsu,1997-05-15,1995-10-19
-2rs1,1990-01-15,1988-10-03
-5rsn,2020-12-16,2020-09-28
-5rsq,2020-12-16,2020-09-28
-1rs6,2004-05-18,2003-12-09
-7rs2,2021-09-08,2021-08-10
-6rsz,2020-04-15,2019-05-22
-4rsp,2015-06-17,2014-11-10
-8rsc,2024-05-29,2024-01-24
-7rsx,2022-06-08,2021-08-12
-1rsv,2003-12-23,2003-12-10
-3rs3,2011-09-21,2011-05-02
-5rs8,2020-12-16,2020-09-28
-5rsb,2020-12-16,2020-09-28
-2rsd,2012-08-15,2012-01-12
-3rs4,2011-09-21,2011-05-02
-1rs8,2004-06-15,2003-12-09
-6rsu,2020-04-01,2019-05-22
-4rsu,2015-02-04,2014-11-11
-2rsq,2013-04-03,2012-05-15
-7rs5,2022-08-17,2021-08-10
-7rs0,2021-09-08,2021-08-10
-4rsn,2015-12-02,2014-11-09
-3rss,2011-06-22,2011-05-02
-1rs4,2004-03-30,2003-12-09
-3rs2,2011-09-21,2011-05-02
-3rs8,2011-06-22,2011-05-02
-7rsy,2022-06-08,2021-08-12
-5rsg,2020-12-16,2020-09-28
-5rss,2020-12-16,2020-09-28
-1rsc,1995-05-08,1994-03-29
-7rso,2021-09-15,2021-08-11
-3rs6,2012-02-08,2011-05-02
-7rsp,2021-11-24,2021-08-11
-7rsn,2021-09-15,2021-08-11
-4rsc,2015-04-15,2014-11-07
-5rsi,2020-12-16,2020-09-28
-8rsa,1991-04-15,1989-08-28
-7rs1,2021-09-08,2021-08-10
-1rsd,2004-03-30,2003-12-09
-6rs7,2019-09-11,2019-05-21
-7rsi,2021-09-08,2021-08-11
-5rst,2020-12-16,2020-09-28
-5rse,2020-12-16,2020-09-28
-4usc,2015-05-27,2014-07-07
-3usp,2012-01-11,2011-11-23
-1usb,2004-09-01,2003-11-20
-5use,2017-03-08,2017-02-13
-8uss,2024-04-03,2023-10-29
-7usx,2022-10-19,2022-04-26
-3usg,2012-01-11,2011-11-23
-1usx,2004-03-19,2003-12-01
-5usa,2017-03-08,2017-02-13
-5usq,2017-04-12,2017-02-13
-3usf,2012-12-05,2011-11-23
-4usl,2015-07-29,2014-07-10
-7us9,2022-08-24,2022-04-23
-3usz,2011-12-21,2011-11-24
-1us5,2003-11-19,2003-11-18
-3usb,2011-12-07,2011-11-23
-7usz,2022-05-11,2022-04-26
-7usy,2022-10-19,2022-04-26
-4usd,2015-07-22,2014-07-07
-1us0,2004-05-07,2003-11-16
-3usj,2012-01-11,2011-11-23
-5usf,2017-05-17,2017-02-13
-7us7,2022-07-13,2022-04-23
-5usv,2018-02-21,2017-02-14
-7usw,2022-10-19,2022-04-26
-3ust,2012-10-10,2011-11-23
-4us2,2015-03-04,2014-07-02
-8usr,2024-04-03,2023-10-29
-6usa,2020-09-30,2019-10-25
-7uss,2022-12-28,2022-04-25
-1us1,2005-02-16,2003-11-17
-7usi,2023-01-18,2022-04-25
-7usf,2022-08-24,2022-04-25
-7ush,2023-01-18,2022-04-25
-7us5,2022-07-06,2022-04-23
-3us0,2012-02-01,2011-11-22
-6usm,2020-12-09,2019-10-28
-5us3,2017-05-31,2017-02-13
-1usq,2004-08-31,2003-11-27
-5usz,2017-06-07,2017-02-14
-1usk,2003-12-18,2003-11-25
-4us5,2014-07-16,2014-07-03
-4usw,2014-07-30,2014-07-13
-8usf,2023-12-06,2023-10-27
-6usc,2020-01-22,2019-10-25
-7us3,2022-11-30,2022-04-22
-4usa,2014-10-08,2014-07-03
-4usj,2014-12-03,2014-07-08
-4usi,2014-12-03,2014-07-08
-8usj,2023-12-06,2023-10-27
-5usr,2017-06-21,2017-02-13
-6us8,2020-10-28,2019-10-25
-3use,2012-03-28,2011-11-23
-3usk,2012-01-11,2011-11-23
-5usx,2017-02-22,2017-02-14
-1usn,1998-12-23,1998-06-09
-5uss,2018-02-21,2017-02-13
-6usv,2020-07-15,2019-10-28
-5us2,2017-03-08,2017-02-13
-4us8,2014-10-08,2014-07-03
-3usd,2011-12-14,2011-11-23
-1usr,2004-01-02,2003-11-28
-3usl,2012-01-11,2011-11-23
-6us3,2020-04-01,2019-10-24
-6usf,2020-04-29,2019-10-26
-4usq,2014-10-01,2014-07-11
-5us4,2017-03-22,2017-02-13
-3usi,2012-01-11,2011-11-23
-1us3,2003-12-18,2003-11-17
-3usn,1999-01-20,1998-06-18
-6usy,2020-07-01,2019-10-28
-2usn,1998-12-23,1998-06-09
-7usd,2022-09-21,2022-04-25
-4usf,2015-07-22,2014-07-07
-4us7,2015-04-29,2014-07-03
-1usf,2003-11-25,2003-11-21
-6usr,2020-06-17,2019-10-28
-7us1,2022-06-22,2022-04-22
-4usr,2014-10-01,2014-07-11
-6usn,2019-12-11,2019-10-28
-5usb,2018-04-18,2017-02-13
-7use,2022-09-21,2022-04-25
-5usn,2018-04-18,2017-02-13
-6usq,2020-06-17,2019-10-28
-6us5,2020-03-18,2019-10-24
-4uso,2015-07-22,2014-07-11
-7uso,2022-06-01,2022-04-25
-3us1,2012-02-01,2011-11-22
-3us2,2012-02-01,2011-11-22
-3usu,2012-01-04,2011-11-24
-5usd,2017-03-15,2017-02-13
-6us4,2020-04-01,2019-10-24
-6usz,2020-04-22,2019-10-28
-5usy,2017-06-07,2017-02-14
-7usl,2022-08-17,2022-04-25
-6uso,2020-06-17,2019-10-28
-3uso,2012-01-11,2011-11-23
-2ush,1999-06-15,1998-09-24
-5usj,2017-03-22,2017-02-13
-6usu,2020-07-15,2019-10-28
-6usx,2020-04-22,2019-10-28
-6us2,2020-04-01,2019-10-24
-8usw,2024-04-17,2023-10-30
-3usc,2012-03-28,2011-11-23
-1usw,2004-04-23,2003-12-01
-7usm,2022-08-17,2022-04-25
-6usp,2020-06-17,2019-10-28
-4use,2015-07-22,2014-07-07
-3us9,2012-07-11,2011-11-23
-1us4,2003-11-19,2003-11-18
-4us9,2014-10-08,2014-07-03
-7us6,2022-08-24,2022-04-23
-1usi,2003-12-18,2003-11-24
-4usx,2015-07-22,2014-07-16
-4usz,2014-10-08,2014-07-17
-6usw,2020-10-07,2019-10-28
-5usp,2018-02-21,2017-02-13
-5usg,2017-03-08,2017-02-13
-5us8,2017-03-01,2017-02-13
-4us0,2015-03-04,2014-07-02
-4us3,2014-09-24,2014-07-02
-7us8,2022-07-13,2022-04-23
-4ust,2014-07-30,2014-07-13
-7usb,2022-08-24,2022-04-23
-5us6,2018-02-21,2017-02-13
-8ush,2023-12-06,2023-10-27
-7usn,2023-04-26,2022-04-25
-4us4,2014-09-24,2014-07-02
-6ust,2020-11-11,2019-10-28
-8usl,2023-12-06,2023-10-27
-4us6,2015-05-13,2014-07-03
-7usj,2023-01-18,2022-04-25
-5uso,2018-04-18,2017-02-13
-4usv,2014-07-30,2014-07-13
-7us2,2023-04-26,2022-04-22
-3uss,2012-01-18,2011-11-23
-4uss,2014-12-03,2014-07-13
-6us9,2020-10-28,2019-10-25
-1us2,2003-12-18,2003-11-17
-8usu,2024-03-13,2023-10-30
-7us4,2023-07-26,2022-04-22
-3us3,2011-12-21,2011-11-22
-1usy,2004-12-15,2003-12-01
-7usq,2022-06-01,2022-04-25
-1ush,1999-06-15,1998-09-16
-4us1,2015-03-04,2014-07-02
-7usp,2022-06-01,2022-04-25
-8usm,2024-02-14,2023-10-27
-5us1,2017-03-15,2017-02-13
-6uss,2020-11-11,2019-10-28
-3usm,2012-01-11,2011-11-23
-4usu,2014-07-30,2014-07-13
-7usg,2023-01-18,2022-04-25
-7usr,2022-12-28,2022-04-25
-7usa,2022-08-24,2022-04-23
-1usc,2003-11-27,2003-11-21
-4yzu,2015-05-20,2015-03-25
-7yzi,2022-10-05,2022-02-20
-4yzz,2015-05-20,2015-03-25
-2yz7,2008-04-22,2007-05-04
-5yzh,2018-07-04,2017-12-14
-6yz4,2020-08-12,2020-05-06
-7yzq,2022-12-28,2022-02-21
-2yz4,2008-02-05,2007-05-02
-5yz8,2019-01-30,2017-12-13
-5yz3,2018-10-24,2017-12-12
-5yzi,2018-07-04,2017-12-14
-2yz3,2008-03-11,2007-05-02
-4yzh,2015-04-29,2015-03-25
-1yzg,2005-03-22,2005-02-28
-5yzg,2018-08-08,2017-12-14
-4yzx,2015-12-23,2015-03-25
-5yzd,2018-02-21,2017-12-14
-2yzj,2007-11-06,2007-05-06
-7yzk,2022-08-31,2022-02-20
-4yz2,2015-09-23,2015-03-24
-4yzg,2015-04-29,2015-03-25
-5yzf,2018-03-07,2017-12-14
-2yzw,2007-11-06,2007-05-06
-1yzk,2005-07-26,2005-02-28
-7yz7,2022-11-16,2022-02-18
-6yz3,2020-09-16,2020-05-06
-6yza,2020-12-02,2020-05-06
-4yz5,2015-09-23,2015-03-24
-4yz4,2015-09-23,2015-03-24
-7yz1,2023-02-22,2022-02-18
-1yzi,2005-03-15,2005-02-28
-6yz7,2020-06-03,2020-05-06
-6yzd,2021-05-12,2020-05-06
-4yzm,2015-05-06,2015-03-25
-4yz7,2015-08-05,2015-03-24
-7yzo,2022-08-17,2022-02-21
-7yz6,2023-02-22,2022-02-18
-7yzj,2023-02-01,2022-02-20
-8yz6,2024-06-05,2024-04-06
-7yza,2022-11-16,2022-02-19
-1yzn,2005-07-26,2005-02-28
-4yzc,2015-11-11,2015-03-24
-6yzc,2020-12-02,2020-05-06
-1yz0,2005-03-22,2005-02-25
-7yz0,2023-02-22,2022-02-18
-7yzn,2022-06-29,2022-02-21
-7yzt,2023-01-25,2022-02-21
-1yzx,2005-11-15,2005-02-28
-7yzr,2022-11-23,2022-02-21
-1yzl,2005-07-26,2005-02-28
-4yzo,2016-03-30,2015-03-25
-5yz2,2018-05-30,2017-12-12
-4yzd,2015-11-11,2015-03-24
-4yzn,2015-05-06,2015-03-25
-4yzt,2016-09-07,2015-03-25
-7yze,2022-11-16,2022-02-19
-2yzl,2007-11-06,2007-05-06
-4yzf,2015-11-04,2015-03-25
-5yz4,2018-12-19,2017-12-12
-7yzp,2022-08-17,2022-02-21
-6yzh,2021-05-19,2020-05-07
-2yz5,2007-11-27,2007-05-03
-7yz2,2023-02-22,2022-02-18
-4yzl,2016-03-16,2015-03-25
-5yzx,2018-12-19,2017-12-16
-6yze,2021-02-03,2020-05-06
-7yzf,2022-11-16,2022-02-19
-4yzs,2015-05-13,2015-03-25
-2yzm,2007-11-06,2007-05-06
-7yzb,2022-11-16,2022-02-19
-6yz2,2020-11-11,2020-05-06
-2yzv,2007-11-06,2007-05-06
-6yz1,2020-05-13,2020-05-06
-6yzz,2020-12-30,2020-05-07
-4yzv,2015-10-21,2015-03-25
-4yzi,2015-05-27,2015-03-25
-7yzm,2022-12-28,2022-02-21
-4yz0,2015-12-23,2015-03-24
-4yza,2015-12-23,2015-03-24
-4yz9,2015-11-11,2015-03-24
-4yz3,2016-04-20,2015-03-24
-4yzr,2016-04-13,2015-03-25
-4yzb,2016-04-06,2015-03-24
-1yzt,2005-07-26,2005-02-28
-1yzq,2005-07-26,2005-02-28
-7yz5,2023-02-22,2022-02-18
-1yzu,2005-07-26,2005-02-28
-7yzu,2022-04-13,2022-02-21
-7yzs,2022-04-13,2022-02-21
-6yz0,2020-11-11,2020-05-06
-5yzc,2018-02-21,2017-12-14
-7yzz,2022-11-02,2022-02-21
-6yz5,2020-06-03,2020-05-06
-2yzq,2007-11-06,2007-05-06
-5yz7,2018-05-30,2017-12-13
-4yzw,2015-12-23,2015-03-25
-5yzy,2018-05-02,2017-12-17
-2yzd,2008-05-06,2007-05-05
-2yzb,2008-05-06,2007-05-05
-6yzy,2021-05-19,2020-05-07
-4yzq,2015-12-23,2015-03-25
-2yzc,2008-05-06,2007-05-05
-7yzh,2023-03-01,2022-02-20
-7yz9,2022-08-31,2022-02-19
-1yzp,2005-05-10,2005-02-28
-2yzn,2007-11-06,2007-05-06
-1yzr,2005-05-10,2005-02-28
-7yz3,2023-02-22,2022-02-18
-5yz9,2018-03-28,2017-12-13
-6yzf,2021-05-12,2020-05-06
-7yzx,2022-08-31,2022-02-21
-1yz3,2006-02-07,2005-02-27
-3iay,2009-09-22,2009-07-15
-1iah,2001-06-06,2001-03-22
-8iaz,2024-04-17,2023-02-09
-3iah,2009-07-21,2009-07-14
-3ia4,2009-07-21,2009-07-13
-3ias,2009-09-15,2009-07-14
-3iaa,2010-06-02,2009-07-13
-4iau,2013-06-05,2012-12-07
-4ia6,2013-03-27,2012-12-06
-6iae,2019-04-10,2018-11-26
-5iae,2016-10-26,2016-02-21
-3iar,2009-08-11,2009-07-14
-5iav,2016-04-27,2016-02-21
-5iaw,2017-03-08,2016-02-22
-4iax,2013-06-19,2012-12-07
-2iav,2006-09-26,2006-09-08
-6iah,2019-08-14,2018-11-26
-1iam,1998-04-29,1998-02-22
-2ia0,2006-10-31,2006-09-06
-3iaw,2011-04-27,2009-07-14
-8iay,,2023-02-09
-5iax,2016-04-27,2016-02-22
-2iaa,2006-11-21,2006-09-07
-1ia0,2002-03-22,2001-03-22
-8iah,2023-05-03,2023-02-08
-1iao,1998-11-04,1998-03-13
-1iax,2001-04-04,2001-03-24
-5ias,2016-10-26,2016-02-21
-2iaf,2006-10-10,2006-09-07
-8iaj,2024-02-14,2023-02-08
-8iab,2023-08-02,2023-02-08
-6iaa,2019-03-13,2018-11-26
-3ial,2009-08-11,2009-07-14
-4iaf,2013-06-12,2012-12-06
-1iab,1994-08-31,1994-05-09
-5iab,2016-10-26,2016-02-21
-2iao,2006-09-26,2006-09-08
-6iau,2019-03-27,2018-11-27
-8ian,2023-04-19,2023-02-08
-1ia9,2001-06-06,2001-03-22
-3iai,2009-09-08,2009-07-14
-1iaj,2001-06-06,2001-03-22
-3iaf,2010-03-02,2009-07-13
-8iam,2024-02-14,2023-02-08
-3iaq,2009-12-29,2009-07-14
-5ia5,2016-11-09,2016-02-21
-8iak,2024-02-14,2023-02-08
-2iat,2006-09-26,2006-09-08
-2iag,2006-10-10,2006-09-08
-4iae,2013-11-20,2012-12-06
-3ia9,2011-07-27,2009-07-13
-1iak,1998-04-15,1997-11-18
-6iay,2019-12-18,2018-11-28
-4ia3,2013-04-24,2012-12-06
-1ia1,2001-04-11,2001-03-22
-5iar,2016-10-26,2016-02-21
-2ias,2006-09-26,2006-09-08
-4iaa,2013-12-18,2012-12-06
-3ia8,2009-07-28,2009-07-13
-8iau,2023-06-14,2023-02-09
-6iao,2019-06-05,2018-11-27
-6iaj,2019-05-22,2018-11-26
-1ia5,2001-09-19,2001-03-22
-3iap,2009-12-29,2009-07-14
-3iaz,2009-08-11,2009-07-15
-8iat,2023-06-14,2023-02-09
-5iaa,2016-09-28,2016-02-21
-8ia7,2023-12-06,2023-02-08
-3ian,2009-07-28,2009-07-14
-8ia5,2023-02-22,2023-02-07
-4iar,2013-03-13,2012-12-07
-5iaj,2016-10-26,2016-02-21
-8ia8,2023-05-24,2023-02-08
-3ia2,2010-07-21,2009-07-13
-5ia2,2016-11-09,2016-02-21
-4iam,2013-11-20,2012-12-06
-8ia4,2023-03-22,2023-02-07
-4iav,2013-12-11,2012-12-07
-5ia3,2016-11-09,2016-02-21
-5ian,2016-10-26,2016-02-21
-6ian,2019-05-01,2018-11-27
-5ia9,2017-07-12,2016-02-21
-4ia4,2013-05-29,2012-12-06
-6ia6,2019-02-20,2018-11-26
-4iaz,2013-06-12,2012-12-07
-4iaw,2013-06-19,2012-12-07
-1iay,2001-04-04,2001-03-24
-8iax,2023-06-14,2023-02-09
-2ia8,2007-08-28,2006-09-07
-8iaw,2023-06-14,2023-02-09
-8iag,2024-03-13,2023-02-08
-6ia3,2019-12-18,2018-11-26
-5iai,2016-03-09,2016-02-21
-3iax,2009-10-13,2009-07-15
-4ia1,2013-04-24,2012-12-06
-3iab,2010-01-26,2009-07-13
-8ia0,2023-05-17,2023-02-07
-1ia7,2002-10-30,2001-03-22
-2ia6,2007-09-11,2006-09-07
-2iar,2006-09-26,2006-09-08
-1ia6,2002-10-30,2001-03-22
-8iav,2023-06-14,2023-02-09
-1iau,2001-05-02,2001-03-23
-1ia3,2001-04-11,2001-03-22
-1iaa,1994-08-31,1994-05-09
-1iag,1994-08-31,1994-05-09
-6ia9,2019-12-18,2018-11-26
-5iak,2016-10-26,2016-02-21
-5iag,2016-10-26,2016-02-21
-4ial,2013-01-09,2012-12-06
-6iaf,2019-05-22,2018-11-26
-4iaj,2013-02-06,2012-12-06
-6ia1,2019-12-18,2018-11-26
-8iaa,2023-09-27,2023-02-08
-4ia7,2013-04-24,2012-12-06
-3ia7,2010-06-02,2009-07-13
-2iae,2006-12-26,2006-09-07
-3iaj,2009-12-01,2009-07-14
-4iai,2013-06-12,2012-12-06
-4iah,2013-11-20,2012-12-06
-1ia4,2001-04-11,2001-03-22
-3iak,2009-09-08,2009-07-14
-4ia0,2014-01-01,2012-12-05
-1iac,1994-08-31,1994-05-09
-6iav,2019-01-30,2018-11-27
-4ia5,2013-03-27,2012-12-06
-2ia4,2007-08-21,2006-09-07
-1iav,2001-04-18,2001-03-23
-1iaq,2001-06-06,2001-03-23
-5iao,2016-03-16,2016-02-21
-3iam,2009-09-15,2009-07-14
-2iax,2006-09-26,2006-09-08
-3ia3,2009-07-28,2009-07-13
-4iao,2012-12-26,2012-12-07
-8iad,2023-08-02,2023-02-08
-2ia5,2007-06-05,2006-09-07
-2iaw,2006-09-26,2006-09-08
-6iaq,2019-03-27,2018-11-27
-3iad,2010-01-05,2009-07-13
-2iah,2007-09-11,2006-09-08
-3iae,2010-03-02,2009-07-13
-2iap,2006-09-26,2006-09-08
-5ia1,2016-11-09,2016-02-21
-1iae,1994-08-31,1994-05-09
-6ia7,2019-04-10,2018-11-26
-8ia9,2023-09-27,2023-02-08
-2iau,2006-09-26,2006-09-08
-6iax,2019-04-24,2018-11-27
-4iac,2013-06-12,2012-12-06
-2iaq,2006-09-26,2006-09-08
-8iai,2023-05-03,2023-02-08
-4iaq,2013-03-13,2012-12-07
-3ia6,2009-10-13,2009-07-13
-4iak,2013-06-12,2012-12-06
-5ia4,2016-11-09,2016-02-21
-4ia2,2013-04-24,2012-12-06
-5ia0,2016-11-09,2016-02-21
-6ial,2019-02-27,2018-11-27
-2iaj,2006-12-19,2006-09-08
-4iay,2013-06-12,2012-12-07
-6iag,2019-12-18,2018-11-26
-4iad,2013-06-12,2012-12-06
-1ia2,2001-04-11,2001-03-22
-8qz2,2024-05-29,2023-10-26
-8qz4,2024-05-29,2023-10-26
-7qzz,2022-12-07,2022-02-01
-3qz8,2011-04-06,2011-03-04
-2qzk,2008-04-29,2007-08-16
-6qzn,2020-02-19,2019-03-11
-4qzt,2014-12-10,2014-07-28
-6qzh,2019-09-04,2019-03-11
-4qz4,2015-02-04,2014-07-27
-7qzb,2022-09-28,2022-01-31
-6qz8,2019-08-07,2019-03-11
-6qzk,2019-04-24,2019-03-11
-7qzl,2022-12-07,2022-01-31
-3qzt,2011-06-01,2011-03-07
-1qz4,2004-03-30,2003-09-15
-8qzc,2023-12-06,2023-10-26
-7qz6,2022-11-23,2022-01-30
-3qz5,2011-03-23,2011-03-04
-3qzf,2012-08-08,2011-03-06
-3qzq,2011-08-10,2011-03-07
-7qz0,2022-09-28,2022-01-30
-1qzz,2003-11-25,2003-09-19
-3qzx,2011-06-08,2011-03-07
-7qzx,2023-02-15,2022-02-01
-3qz7,2011-04-06,2011-03-04
-6qzv,2020-09-30,2019-03-12
-3qzz,2011-06-08,2011-03-07
-6qzm,2020-02-19,2019-03-11
-3qz9,2011-03-23,2011-03-04
-2qz2,2007-12-25,2007-08-16
-4qzw,2015-02-04,2014-07-29
-8qz1,2024-05-29,2023-10-26
-4qz3,2015-02-04,2014-07-27
-7qz1,2023-02-08,2022-01-30
-6qzw,2020-09-30,2019-03-12
-8qze,2024-04-03,2023-10-27
-8qz3,2024-05-29,2023-10-26
-4qzx,2015-02-04,2014-07-29
-1qz2,2004-06-22,2003-09-15
-3qzs,2011-06-01,2011-03-07
-3qzp,2011-08-31,2011-03-06
-6qz1,2020-09-30,2019-03-10
-2qz3,2007-12-11,2007-08-16
-4qz5,2015-02-04,2014-07-27
-6qzz,2020-04-01,2019-03-12
-3qzv,2011-06-01,2011-03-07
-1qz5,2003-11-11,2003-09-15
-6qzg,2020-04-01,2019-03-11
-4qz6,2015-02-04,2014-07-27
-1qzg,2003-11-18,2003-09-16
-2qz7,2007-08-28,2007-08-16
-4qzf,2015-06-10,2014-07-27
-1qz6,2003-11-11,2003-09-15
-4qzb,2015-06-10,2014-07-27
-1qzf,2003-11-11,2003-09-16
-7qzg,2022-12-07,2022-01-31
-7qzh,2022-12-07,2022-01-31
-6qzp,2019-04-24,2019-03-12
-7qzn,2022-12-07,2022-01-31
-4qz1,2015-02-04,2014-07-27
-3qzg,2012-08-08,2011-03-06
-6qzb,2019-08-07,2019-03-11
-4qz8,2015-06-10,2014-07-27
-6qz7,2019-08-07,2019-03-11
-8qzd,2024-02-28,2023-10-27
-2qzr,2007-09-11,2007-08-17
-6qz3,2020-09-30,2019-03-11
-6qzo,2019-04-03,2019-03-12
-1qzy,2003-11-25,2003-09-18
-8qz8,2023-12-27,2023-10-26
-7qzt,2022-09-28,2022-01-31
-2qzs,2008-09-09,2007-08-17
-6qz4,2020-09-30,2019-03-11
-7qzo,2022-07-06,2022-01-31
-7qzq,2022-05-04,2022-01-31
-2qzx,2008-07-08,2007-08-17
-1qzr,2003-09-30,2003-09-17
-4qzu,2014-12-10,2014-07-28
-3qz2,2012-01-25,2011-03-04
-3qzi,2012-08-08,2011-03-06
-8qzf,2024-04-03,2023-10-27
-1qz9,2004-01-20,2003-09-16
-3qzl,2011-08-31,2011-03-06
-7qzm,2023-03-22,2022-01-31
-7qz2,2022-07-06,2022-01-30
-4qzd,2015-06-10,2014-07-27
-7qzy,2023-03-22,2022-02-01
-7qzi,2022-09-28,2022-01-31
-8qzg,2023-11-08,2023-10-27
-6qz6,2019-08-07,2019-03-11
-4qzs,2014-10-29,2014-07-28
-8qzr,2024-04-03,2023-10-29
-7qzc,2022-09-28,2022-01-31
-7qz4,2022-09-28,2022-01-30
-2qzl,2008-04-22,2007-08-16
-4qze,2015-06-10,2014-07-27
-7qza,2022-08-03,2022-01-30
-4qzg,2015-06-10,2014-07-27
-3qzm,2011-08-31,2011-03-06
-2qzz,2008-01-15,2007-08-17
-3qzo,2011-08-31,2011-03-06
-6qz5,2019-08-07,2019-03-11
-3qzy,2012-02-15,2011-03-07
-7qzj,2023-02-15,2022-01-31
-1qz0,2003-11-25,2003-09-15
-2qzi,2007-08-28,2007-08-16
-4qza,2015-06-10,2014-07-27
-7qz8,2022-11-23,2022-01-30
-3qz1,2012-01-18,2011-03-04
-4qz9,2015-06-10,2014-07-27
-3qzn,2011-08-31,2011-03-06
-3qz6,2011-03-16,2011-03-04
-2qzy,2007-09-04,2007-08-17
-6qzy,2020-04-01,2019-03-12
-7qzu,2022-04-06,2022-01-31
-4qz7,2015-02-04,2014-07-27
-4qz2,2015-02-04,2014-07-27
-6qzs,2019-07-31,2019-03-12
-8qzz,2024-03-20,2023-10-30
-4qzi,2015-06-10,2014-07-27
-2qzo,2008-08-26,2007-08-16
-6qz2,2020-09-30,2019-03-10
-4qz0,2015-02-04,2014-07-27
-4qzz,2015-02-04,2014-07-29
-7qz7,2022-11-23,2022-01-30
-1qzu,2004-03-23,2003-09-17
-7qzf,2022-12-07,2022-01-31
-1qzh,2003-11-25,2003-09-16
-6qzr,2019-07-31,2019-03-12
-2qz0,2009-04-21,2007-08-15
-3qzb,2011-03-30,2011-03-04
-3qzh,2012-08-08,2011-03-06
-6qzc,2020-07-15,2019-03-11
-3qzc,2011-03-23,2011-03-04
-7qze,2022-12-07,2022-01-31
-4qzc,2015-06-10,2014-07-27
-3qzr,2011-08-10,2011-03-07
-6qza,2020-07-15,2019-03-11
-7qzr,2022-10-26,2022-01-31
-4qzv,2014-10-29,2014-07-29
-8qzs,2024-05-22,2023-10-29
-2qz4,2007-09-11,2007-08-16
-4qzh,2015-06-10,2014-07-27
-4nu5,2014-03-12,2013-12-03
-1nuf,2003-04-22,2003-01-31
-2nuu,2006-11-21,2006-11-09
-6nu3,2019-04-17,2019-01-30
-7nug,2021-07-28,2021-03-12
-1nu7,2003-10-07,2003-01-31
-2nu6,2007-07-24,2006-11-08
-7nup,2022-06-22,2021-03-12
-3nug,2011-04-20,2010-07-06
-1nuu,2003-06-03,2003-02-01
-5nu5,2017-08-16,2017-04-28
-1nuh,2003-02-11,2003-01-31
-3nu5,2010-08-25,2010-07-06
-2nux,2007-04-10,2006-11-10
-6nur,2019-05-29,2019-02-01
-5nu7,2018-03-07,2017-04-28
-4nuq,2014-09-24,2013-12-03
-4nuy,2014-04-09,2013-12-04
-6nuf,2019-07-03,2019-01-31
-3nuy,2011-05-25,2010-07-07
-6nuh,2019-06-26,2019-02-01
-1nux,2003-07-08,2003-02-01
-7nuz,2022-01-19,2021-03-15
-1nug,2003-04-22,2003-01-31
-4nun,2014-05-14,2013-12-03
-7nuh,2021-07-28,2021-03-12
-4nup,2014-09-24,2013-12-03
-1nu5,2003-12-30,2003-01-31
-1nul,1997-05-15,1996-10-15
-3nu4,2010-08-25,2010-07-06
-1nuo,2003-04-15,2003-01-31
-7nu7,2022-08-31,2021-03-11
-3nun,2011-06-22,2010-07-07
-1nup,2003-06-03,2003-02-01
-6nuj,2019-12-11,2019-02-01
-5nul,1997-03-12,1996-12-20
-5num,2018-04-04,2017-04-30
-4nuc,2014-04-02,2013-12-03
-7nu5,2022-08-31,2021-03-11
-1nu6,2003-08-26,2003-01-31
-2nuy,2007-04-10,2006-11-10
-1nu3,2003-06-10,2003-01-30
-3nuh,2010-08-11,2010-07-06
-1nuq,2003-06-03,2003-02-01
-7nu4,2022-08-31,2021-03-11
-6nus,2019-05-29,2019-02-01
-4nu7,2013-12-18,2013-12-03
-7nui,2021-04-14,2021-03-12
-3nud,2010-07-28,2010-07-06
-2nuv,2006-12-26,2006-11-10
-4nuf,2014-01-29,2013-12-03
-4nu8,2014-12-03,2013-12-03
-1nuz,2003-07-08,2003-02-01
-3nu6,2010-08-25,2010-07-06
-7nu9,2022-08-31,2021-03-11
-4nuz,2014-04-09,2013-12-04
-1nui,2003-05-27,2003-01-31
-5nun,2018-04-04,2017-04-30
-4nue,2014-04-02,2013-12-03
-3nue,2010-07-28,2010-07-06
-3nuu,2011-05-25,2010-07-07
-7nu3,2022-08-31,2021-03-11
-7nuc,2022-08-31,2021-03-11
-5nur,2017-10-25,2017-05-01
-6nud,2019-03-13,2019-01-31
-6nuo,2020-10-14,2019-02-01
-4nul,1997-03-12,1996-12-13
-1nu1,2003-10-07,2003-01-30
-6nu5,2019-08-21,2019-01-30
-2nun,2007-05-22,2006-11-09
-4nu0,2014-07-23,2013-12-03
-1nu2,2003-04-15,2003-01-30
-2nut,2007-05-22,2006-11-09
-4nuw,2013-12-18,2013-12-04
-7nub,2022-08-31,2021-03-11
-6nuc,2019-07-03,2019-01-31
-6nul,1997-03-12,1997-01-09
-3nuj,2010-08-25,2010-07-07
-4nud,2014-04-02,2013-12-03
-4nur,2014-12-10,2013-12-04
-3nuv,2011-11-23,2010-07-07
-6nux,2020-01-15,2019-02-03
-1nua,2003-03-18,2003-01-31
-6nuu,2019-07-03,2019-02-02
-5nuv,2017-07-19,2017-05-02
-6nub,2019-08-21,2019-01-31
-4num,2014-09-24,2013-12-03
-1nuc,1997-06-16,1997-02-15
-3nuq,2010-08-18,2010-07-07
-4nui,2014-05-14,2013-12-03
-2nuw,2007-04-10,2006-11-10
-4nu9,2013-12-11,2013-12-03
-6nu1,2019-08-21,2019-01-30
-6nu7,2020-02-05,2019-01-31
-3nup,2010-12-22,2010-07-07
-2nug,2007-11-20,2006-11-09
-1nuy,2003-07-08,2003-02-01
-4nuo,2014-05-14,2013-12-03
-4nuk,2014-05-14,2013-12-03
-6nut,2019-05-01,2019-02-01
-3nu9,2010-08-25,2010-07-06
-7nuu,2021-04-28,2021-03-14
-7nun,2021-05-19,2021-03-12
-2nu5,2007-08-07,2006-11-08
-7nuj,2022-09-21,2021-03-12
-2nuo,2007-08-07,2006-11-09
-4nu6,2014-03-12,2013-12-03
-5nu1,2017-06-21,2017-04-28
-1nud,2003-04-22,2003-01-31
-2nuf,2007-11-20,2006-11-09
-5nud,2018-04-04,2017-04-29
-5nuc,1998-04-29,1998-01-11
-5nuk,2018-04-04,2017-04-30
-6nu8,2020-02-05,2019-01-31
-2nu8,2007-07-24,2006-11-08
-7nut,2021-04-28,2021-03-14
-1nus,2003-06-03,2003-02-01
-1nu8,2003-08-26,2003-01-31
-3nuc,1998-03-18,1997-12-06
-7nu2,2022-08-31,2021-03-11
-6nu2,2019-04-17,2019-01-30
-1nu4,2003-02-14,2003-01-30
-7nu0,2022-09-28,2021-03-11
-3nu3,2010-08-25,2010-07-06
-2nup,2007-05-22,2006-11-09
-3nut,2011-07-20,2010-07-07
-7nud,2022-03-23,2021-03-11
-4nus,2014-03-05,2013-12-04
-3nur,2011-07-13,2010-07-07
-3nus,2011-05-25,2010-07-07
-3nu1,2010-10-13,2010-07-06
-5nux,2018-05-30,2017-05-03
-3nux,2010-12-22,2010-07-07
-6nuq,2019-12-04,2019-02-01
-7nu8,2022-08-31,2021-03-11
-1nu9,2003-10-07,2003-01-31
-7nus,2021-09-22,2021-03-13
-3nua,2010-08-25,2010-07-06
-5nue,2018-02-28,2017-04-29
-5nuu,2018-05-30,2017-05-02
-2nua,2007-07-24,2006-11-08
-7nua,2022-08-31,2021-03-11
-7nu1,2022-08-31,2021-03-11
-5nuf,2018-01-10,2017-04-29
-4nu3,2014-04-16,2013-12-03
-7nuq,2021-05-19,2021-03-12
-5nuj,2018-04-04,2017-04-30
-2nuc,1998-03-18,1997-12-06
-4nub,2014-02-26,2013-12-03
-3nub,2010-07-28,2010-07-06
-1nub,1998-12-30,1997-12-05
-1nut,2003-06-03,2003-02-01
-3nu0,2011-05-25,2010-07-06
-3nu7,2010-07-28,2010-07-06
-2nu9,2007-07-24,2006-11-08
-4nu1,2014-03-26,2013-12-03
-4nua,2014-11-19,2013-12-03
-5nus,2017-10-18,2017-05-02
-5nug,2017-06-28,2017-04-30
-7nu6,2022-08-31,2021-03-11
-6nu9,2019-02-13,2019-01-31
-6nue,2019-03-13,2019-01-31
-6nua,2019-06-26,2019-01-31
-5nu3,2017-08-16,2017-04-28
-6nun,2020-02-05,2019-02-01
-1nue,1996-04-03,1995-10-06
-5nuz,2017-06-28,2017-05-03
-7nue,2022-03-23,2021-03-11
-2nu7,2007-07-24,2006-11-08
-6nu6,2020-02-05,2019-01-31
-1nuw,2003-07-08,2003-02-01
-5nut,2018-03-14,2017-05-02
-3nuo,2010-08-25,2010-07-07
-7nuk,2021-06-16,2021-03-12
-5sm8,2022-03-16,2022-03-03
-7smz,2022-09-14,2021-10-27
-1sm1,2004-08-03,2004-03-08
-6smt,2020-08-12,2019-08-22
-6smp,2020-05-27,2019-08-22
-1sm3,1999-03-23,1997-12-23
-7smk,2023-05-24,2021-10-26
-3smo,2012-07-11,2011-06-28
-3sm3,2011-07-20,2011-06-27
-8sm9,2024-03-13,2023-04-25
-7sms,2022-03-09,2021-10-26
-1smr,1994-01-31,1992-03-11
-7smv,2022-04-06,2021-10-26
-1smm,2004-03-16,2004-03-09
-6sm8,2020-04-29,2019-08-21
-3sm1,2011-10-12,2011-06-27
-8smz,2024-01-17,2023-04-26
-6smy,2020-08-12,2019-08-23
-7smh,2022-11-02,2021-10-25
-3smn,2012-07-11,2011-06-28
-8smp,2024-05-01,2023-04-26
-6smq,2020-05-20,2019-08-22
-8smr,2023-10-11,2023-04-26
-1sml,1999-09-20,1998-09-22
-8sm7,2024-03-13,2023-04-25
-1sms,2004-08-10,2004-03-09
-1sme,1997-01-11,1996-06-11
-3smi,2011-07-20,2011-06-28
-1smp,1996-04-03,1995-01-13
-5sm9,2022-03-16,2022-03-03
-1smg,1997-08-12,1997-02-04
-5sme,2022-03-16,2022-03-03
-8smf,2023-11-22,2023-04-26
-6smo,2020-05-27,2019-08-22
-6sm3,2020-05-20,2019-08-21
-8smc,2024-01-03,2023-04-26
-5smi,2022-03-16,2022-03-03
-5sm6,2022-03-16,2022-03-03
-8sm2,2024-05-08,2023-04-25
-1sm2,2004-07-16,2004-03-08
-8sm8,2024-03-13,2023-04-25
-6smk,2020-09-09,2019-08-22
-5smg,2022-03-16,2022-03-03
-3smk,2012-07-11,2011-06-28
-8smo,2024-05-01,2023-04-26
-5smc,2022-03-16,2022-03-03
-8smu,2023-09-27,2023-04-26
-1smi,2004-06-08,2004-03-09
-6smc,2020-09-09,2019-08-21
-6sml,2020-05-20,2019-08-22
-8smk,2024-03-06,2023-04-26
-5smb,2022-03-16,2022-03-03
-5sm7,2022-03-16,2022-03-03
-5sm5,2022-03-16,2022-03-03
-6smr,2020-01-08,2019-08-22
-7smf,2022-06-29,2021-10-25
-5sma,2022-03-16,2022-03-03
-5smn,2023-04-26,2022-04-20
-5smk,2022-03-23,2022-03-08
-7smt,2022-03-09,2021-10-26
-1smc,2004-03-16,2004-03-09
-7smc,2022-06-29,2021-10-25
-5smj,2023-03-01,2022-03-05
-6smv,2019-09-04,2019-08-22
-1smw,2004-03-16,2004-03-09
-8sms,2023-09-27,2023-04-26
-8smy,2024-01-17,2023-04-26
-8smt,2023-06-28,2023-04-26
-7smp,2022-09-28,2021-10-26
-5sm4,2022-03-16,2022-03-03
-3smt,2011-07-20,2011-06-28
-3sm9,2011-07-27,2011-06-27
-6smz,2020-08-12,2019-08-23
-6smn,2020-01-08,2019-08-22
-8sm0,2024-05-01,2023-04-25
-1sm4,2004-03-16,2004-03-08
-8smi,2023-12-13,2023-04-26
-3sm4,2011-07-20,2011-06-27
-3sml,2012-07-11,2011-06-28
-5sm3,2022-03-16,2022-03-03
-3smc,2012-10-03,2011-06-27
-1smf,1994-07-31,1992-10-24
-8sma,2024-03-13,2023-04-25
-8smn,2024-05-01,2023-04-26
-3smm,2012-07-11,2011-06-28
-5smd,2022-03-16,2022-03-03
-7smr,2022-03-09,2021-10-26
-6sm1,2020-03-18,2019-08-21
-8sm1,2024-05-01,2023-04-25
-8sm6,2024-01-24,2023-04-25
-8smx,2024-01-17,2023-04-26
-3smp,2011-07-20,2011-06-28
-1smy,2004-05-18,2004-03-10
-5sm0,2022-03-16,2022-03-03
-6sm0,2021-02-17,2019-08-21
-1smu,2004-03-16,2004-03-09
-8sml,2024-03-06,2023-04-26
-5smh,2022-03-16,2022-03-03
-1smj,2004-06-08,2004-03-09
-1smv,1995-09-15,1995-06-16
-1sm8,2004-03-16,2004-03-08
-8smv,2024-02-21,2023-04-26
-7smm,2022-03-09,2021-10-26
-3sm2,2011-10-12,2011-06-27
-3sm0,2012-06-27,2011-06-27
-5smm,2023-04-26,2022-04-20
-3smj,2011-07-20,2011-06-28
-5sml,2023-04-26,2022-04-20
-6smw,2020-01-08,2019-08-23
-1sm9,2004-12-21,2004-03-08
-3sma,2011-08-24,2011-06-27
-1smd,1996-07-11,1996-01-24
-8smg,2023-11-22,2023-04-26
-6smb,2020-04-29,2019-08-21
-1smh,2004-07-06,2004-03-09
-7smg,2022-11-09,2021-10-25
-6sms,2021-02-10,2019-08-22
-8smd,2023-11-22,2023-04-26
-5smf,2022-03-16,2022-03-03
-5sm1,2022-03-16,2022-03-03
-5sm2,2022-03-16,2022-03-03
-7smq,2022-03-09,2021-10-26
-3sm8,2011-07-20,2011-06-27
-8smw,2024-01-17,2023-04-26
-3sme,2011-10-19,2011-06-27
-6sma,2020-04-08,2019-08-21
-3smb,2012-10-03,2011-06-27
-2ine,2006-11-21,2006-10-06
-8inj,2024-02-14,2023-03-10
-1ing,1996-08-17,1995-07-07
-6ini,2019-07-31,2018-10-25
-4in4,2013-05-15,2013-01-03
-1ini,2001-11-14,2001-05-14
-5ind,2016-10-05,2016-03-07
-4inf,2013-01-16,2013-01-04
-3inh,2010-03-02,2009-08-12
-5ino,2016-04-27,2016-03-07
-6in3,2019-10-30,2018-10-24
-6ing,2019-07-31,2018-10-25
-8inh,2023-04-19,2023-03-09
-3inz,2010-08-04,2009-08-13
-5in8,2016-05-25,2016-03-07
-4in5,2013-05-01,2013-01-04
-8inr,2023-09-20,2023-03-10
-3inr,2009-09-22,2009-08-12
-8in9,2023-05-31,2023-03-09
-4ins,1990-04-15,1989-07-10
-2inp,2007-01-16,2006-10-08
-4inr,2013-01-30,2013-01-06
-5inh,2017-03-15,2016-03-07
-5in2,2017-03-29,2016-03-07
-1ine,1993-10-31,1993-06-14
-1inc,1994-01-31,1993-03-19
-3ing,2009-09-01,2009-08-12
-6in7,2019-07-24,2018-10-24
-6inr,2019-07-31,2018-10-26
-4in9,2013-05-15,2013-01-04
-5inj,2016-05-11,2016-03-07
-5inr,2017-03-15,2016-03-07
-8ink,2023-08-09,2023-03-10
-1in4,2001-08-08,2001-05-12
-3ine,2010-03-02,2009-08-12
-3in8,2009-11-17,2009-08-11
-1in3,2001-05-30,2001-05-11
-1in8,2001-08-08,2001-05-12
-1inj,2001-07-11,2001-05-14
-1inq,2002-03-20,2001-05-14
-6int,2019-01-16,2018-10-26
-2inx,2007-10-23,2006-10-09
-2ins,1982-08-05,1982-05-10
-4inb,2013-02-27,2013-01-04
-4inj,2013-02-20,2013-01-04
-8inl,2024-03-13,2023-03-10
-8ino,2024-01-24,2023-03-10
-2ing,2007-09-04,2006-10-07
-5inq,2016-04-27,2016-03-07
-6ine,2019-03-20,2018-10-25
-1iny,1995-02-07,1994-09-26
-4int,2013-01-30,2013-01-06
-1ino,1996-04-03,1995-10-03
-4in7,2013-06-05,2013-01-04
-1in0,2003-06-10,2001-05-11
-4inq,2013-07-31,2013-01-05
-8ine,2023-08-09,2023-03-09
-4ine,2014-01-15,2013-01-04
-5in9,2016-05-04,2016-03-07
-6ink,2019-10-23,2018-10-25
-4inp,2014-01-08,2013-01-05
-6inl,2019-10-30,2018-10-25
-1inp,1995-01-26,1994-10-04
-3in3,2010-01-19,2009-08-11
-8ina,2024-01-24,2023-03-09
-5in3,2016-03-30,2016-03-07
-3iny,2011-01-19,2009-08-13
-5inp,2016-04-27,2016-03-07
-8inb,2024-03-13,2023-03-09
-1inv,1995-02-07,1994-09-26
-6inh,2019-07-31,2018-10-25
-3inj,2010-01-12,2009-08-12
-6inw,2019-07-03,2018-10-28
-6inf,2019-07-31,2018-10-25
-7ins,1994-01-31,1991-09-03
-5ink,2016-04-27,2016-03-07
-8inv,2024-01-24,2023-03-10
-3in2,2009-11-17,2009-08-11
-1inw,1995-02-07,1994-09-26
-6inq,2019-04-03,2018-10-26
-3inw,2010-08-18,2009-08-13
-8in7,2024-03-13,2023-03-08
-6inc,2019-01-16,2018-10-24
-4in0,2013-03-13,2013-01-03
-8in2,2024-04-24,2023-03-08
-1ind,1993-10-31,1993-06-14
-1in2,2001-05-30,2001-05-11
-1in7,2001-08-08,2001-05-12
-8in0,2024-03-13,2023-03-08
-8ind,2024-01-24,2023-03-09
-8inf,2023-08-09,2023-03-09
-8inw,2024-03-13,2023-03-10
-6iny,2020-01-01,2018-10-29
-4in6,2013-05-01,2013-01-04
-1inf,1996-08-17,1995-07-07
-1in6,2001-08-08,2001-05-12
-5ine,2016-04-20,2016-03-07
-1inx,1995-02-07,1994-09-26
-2ind,2006-12-05,2006-10-06
-4inh,2013-02-20,2013-01-04
-8in8,2023-07-05,2023-03-08
-5inm,2016-04-27,2016-03-07
-5iny,2016-09-21,2016-03-08
-6ins,1994-01-31,1992-11-25
-6inm,2019-10-23,2018-10-26
-3in0,2009-10-27,2009-08-11
-5inl,2016-04-27,2016-03-07
-8inx,2024-03-13,2023-03-10
-2in6,2007-09-18,2006-10-05
-8inp,2023-08-23,2023-03-10
-3inc,2010-08-18,2009-08-12
-1in5,2001-08-08,2001-05-12
-2inz,2006-11-21,2006-10-09
-3int,2009-09-22,2009-08-12
-3inq,2009-09-01,2009-08-12
-3inm,2009-11-24,2009-08-12
-5ini,2016-12-28,2016-03-07
-4inu,2013-01-30,2013-01-06
-3ind,2010-03-02,2009-08-12
-6in5,2019-10-30,2018-10-24
-2in4,2006-10-31,2006-10-05
-3in9,2009-09-29,2009-08-12
-3inb,2009-12-22,2009-08-12
-3ins,1989-01-09,1988-10-14
-8in6,2023-11-15,2023-03-08
-2inq,2007-02-06,2006-10-08
-3in1,2009-09-08,2009-08-11
-5inx,2017-03-15,2016-03-08
-8inu,2024-03-13,2023-03-10
-5in4,2016-08-17,2016-03-07
-6inz,2019-09-11,2018-10-29
-5in5,2016-08-17,2016-03-07
-1inn,2001-06-08,2001-05-14
-3in6,2009-08-25,2009-08-11
-3in5,2009-09-08,2009-08-11
-3in4,2010-01-19,2009-08-11
-5inc,2016-10-05,2016-03-07
-8iny,2024-03-13,2023-03-10
-3inf,2010-03-02,2009-08-12
-6in1,2019-10-30,2018-10-24
-2inv,2006-12-26,2006-10-09
-8in1,2023-11-15,2023-03-08
-2inn,2007-01-16,2006-10-08
-6inb,2019-01-16,2018-10-24
-2inc,2006-11-28,2006-10-06
-8inz,2024-04-10,2023-03-10
-5inf,2016-12-28,2016-03-07
-3inx,2010-08-18,2009-08-13
-6ind,2019-10-23,2018-10-24
-8ing,2023-04-05,2023-03-09
-3inv,2010-07-28,2009-08-13
-3inl,2010-01-12,2009-08-12
-5inb,2016-10-05,2016-03-07
-1inh,1996-08-17,1995-07-07
-3in7,2009-11-17,2009-08-11
-4ini,2013-05-22,2013-01-04
-7qa3,2022-11-23,2021-11-15
-6qat,2019-02-27,2018-12-19
-7qar,2023-04-26,2021-11-17
-8qa4,2023-11-08,2023-08-22
-4qa4,2014-08-06,2014-05-02
-5qa6,2018-01-10,2017-07-11
-6qaq,2019-03-27,2018-12-19
-4qag,2014-06-04,2014-05-04
-8qav,2024-04-10,2023-08-23
-6qa7,2019-06-26,2018-12-18
-1qak,1999-08-24,1999-03-15
-7qan,2022-11-30,2021-11-17
-5qay,2018-01-10,2017-07-11
-3qa2,2012-01-18,2011-01-10
-5qat,2018-01-10,2017-07-11
-4qar,2014-10-01,2014-05-05
-5qae,2018-01-10,2017-07-11
-1qa7,1999-04-20,1999-04-15
-8qa6,2023-11-08,2023-08-22
-4qak,2014-10-22,2014-05-05
-4qa1,2014-08-06,2014-05-02
-1qaj,2000-04-02,1999-03-18
-2qae,2008-07-22,2007-06-15
-7qa4,2022-02-02,2021-11-16
-6qap,2019-04-10,2018-12-19
-5qab,2018-01-10,2017-07-11
-6qaa,2019-03-27,2018-12-19
-8qax,2024-04-10,2023-08-23
-3qar,2011-03-30,2011-01-11
-5qap,2018-01-10,2017-07-11
-6qag,2019-03-27,2018-12-19
-6qa6,2019-06-26,2018-12-18
-1qaf,1999-08-23,1999-03-11
-4qa5,2014-08-06,2014-05-02
-2qa4,2008-04-01,2007-06-14
-5qa0,2018-08-08,2017-05-25
-3qal,2011-12-07,2011-01-11
-3qaa,2011-12-21,2011-01-10
-6qaw,2019-03-27,2018-12-19
-3qae,2011-01-26,2011-01-10
-6qa8,2019-06-26,2018-12-18
-6qa4,2019-06-26,2018-12-18
-4qai,2014-09-10,2014-05-05
-6qau,2019-02-27,2018-12-19
-5qaf,2018-01-10,2017-07-11
-6qaj,2019-07-24,2018-12-19
-7qa0,2022-11-23,2021-11-15
-3qam,2011-12-07,2011-01-11
-3qap,2011-09-14,2011-01-11
-1qap,1997-03-12,1996-09-20
-2qaj,2008-04-29,2007-06-15
-5qas,2018-01-10,2017-07-11
-2qa6,2008-03-18,2007-06-14
-5qax,2018-01-10,2017-07-11
-3qah,2011-07-06,2011-01-11
-4qa7,2014-08-06,2014-05-02
-6qac,2019-03-27,2018-12-19
-7qak,2022-04-06,2021-11-17
-5qam,2018-01-10,2017-07-11
-5qaj,2018-01-10,2017-07-11
-1qat,1997-02-12,1996-08-02
-5qaw,2018-01-10,2017-07-11
-6qav,2019-02-27,2018-12-19
-4qaf,2015-05-06,2014-05-04
-2qa2,2007-08-14,2007-06-14
-5qak,2018-01-10,2017-07-11
-2qak,2008-07-01,2007-06-16
-4qau,2015-01-21,2014-05-06
-4qac,2014-07-16,2014-05-03
-3qaq,2011-03-30,2011-01-11
-4qaa,2014-07-16,2014-05-03
-6qar,2020-01-15,2018-12-19
-5qav,2018-01-10,2017-07-11
-3qax,2012-01-18,2011-01-12
-6qab,2019-03-27,2018-12-19
-5qa2,2018-08-08,2017-05-25
-6qas,2019-02-27,2018-12-19
-5qac,2018-01-10,2017-07-11
-2qa1,2007-08-14,2007-06-14
-7qa7,2022-11-30,2021-11-16
-6qal,2019-03-27,2018-12-19
-1qay,1999-06-18,1999-04-07
-7qaa,2022-10-05,2021-11-16
-2qa8,2008-03-18,2007-06-14
-3qaz,2012-04-11,2011-01-12
-6qa9,2019-08-21,2018-12-19
-5qa1,2018-08-08,2017-05-25
-6qad,2019-03-27,2018-12-19
-6qa0,2020-01-15,2018-12-18
-4qao,2015-08-05,2014-05-05
-4qan,2014-07-23,2014-05-05
-8qay,2024-04-10,2023-08-23
-5qa4,2018-01-10,2017-07-11
-5qa8,2018-01-10,2017-07-11
-1qal,1999-08-24,1999-03-19
-5qau,2018-01-10,2017-07-11
-5qah,2018-01-10,2017-07-11
-4qaw,2014-10-08,2014-05-06
-3qai,2012-01-18,2011-01-11
-2qad,2007-09-25,2007-06-14
-5qad,2018-01-10,2017-07-11
-1qaq,2000-03-29,1999-03-28
-2qaa,2007-12-11,2007-06-14
-1qab,1999-02-16,1999-02-03
-3qag,2012-01-11,2011-01-11
-4qa2,2014-08-06,2014-05-02
-5qa7,2018-01-10,2017-07-11
-3qaw,2012-02-01,2011-01-12
-1qaw,1999-04-16,1999-03-31
-5qan,2018-01-10,2017-07-11
-7qa8,2022-03-16,2021-11-16
-4qa3,2014-08-06,2014-05-02
-8qa8,2024-02-21,2023-08-22
-8qaw,2024-04-10,2023-08-23
-1qan,2000-03-29,1999-03-26
-5qar,2018-01-10,2017-07-11
-6qah,2019-06-26,2018-12-19
-1qax,1999-06-18,1999-04-06
-5qaa,2018-01-10,2017-07-11
-5qa5,2018-01-10,2017-07-11
-6qa3,2019-06-26,2018-12-18
-3qay,2011-12-28,2011-01-12
-3qa3,2011-11-30,2011-01-10
-5qal,2018-01-10,2017-07-11
-2qa9,2007-12-11,2007-06-14
-4qav,2014-06-04,2014-05-06
-2qa0,2008-04-08,2007-06-14
-5qaz,2018-01-10,2017-07-11
-5qao,2018-01-10,2017-07-11
-2qaf,2008-04-29,2007-06-15
-4qab,2014-07-16,2014-05-03
-3qak,2011-03-09,2011-01-11
-7qaz,2022-05-04,2021-11-17
-1qa0,2000-04-10,1999-04-09
-6qae,2019-03-27,2018-12-19
-5qaq,2018-01-10,2017-07-11
-4qa6,2014-08-06,2014-05-02
-4qax,2015-05-06,2014-05-06
-7qad,2022-11-30,2021-11-16
-1qai,2000-03-20,1999-03-12
-2qab,2008-03-18,2007-06-14
-1qao,2000-03-29,1999-03-26
-4qam,2014-07-30,2014-05-05
-2qa5,2007-08-07,2007-06-14
-5qai,2018-01-10,2017-07-11
-1qae,1999-05-18,1999-03-03
-8qau,2024-04-03,2023-08-23
-2qa3,2007-12-04,2007-06-14
-6qa1,2019-06-26,2018-12-18
-3qau,2011-01-26,2011-01-11
-4qa0,2014-08-06,2014-05-02
-8qa5,2023-11-08,2023-08-22
-7qav,2022-11-30,2021-11-17
-5qag,2018-01-10,2017-07-11
-2qag,2007-08-07,2007-06-15
-2qas,2007-09-04,2007-06-15
-5qa9,2018-01-10,2017-07-11
-4qat,2014-10-01,2014-05-05
-2gpc,2007-08-28,2006-04-17
-6gpj,2018-07-18,2018-06-06
-3gpb,1992-10-15,1990-06-04
-7gp3,2023-11-29,2023-08-24
-7gpk,2023-11-29,2023-08-24
-1gpb,1992-10-15,1990-06-04
-3gpa,2009-08-11,2009-03-23
-1gp7,2002-10-31,2001-10-30
-6gpr,2018-10-03,2018-06-06
-7gp5,2023-11-29,2023-08-24
-7gps,2023-11-29,2023-08-24
-7gpe,2023-11-29,2023-08-24
-5gpn,2017-04-05,2016-08-03
-8gpv,2023-04-19,2022-08-27
-4gpb,1992-10-15,1990-06-04
-6gpe,2018-12-12,2018-06-05
-2gpl,2006-07-11,2006-04-18
-3gpl,2009-06-16,2009-03-23
-2gpp,2006-09-26,2006-04-18
-8gpc,2023-08-30,2022-08-26
-5gp4,2017-08-02,2016-07-31
-7gpp,2023-11-29,2023-08-24
-7gpj,2023-11-29,2023-08-24
-3gpo,2009-07-21,2009-03-23
-8gpz,2023-01-18,2022-08-27
-3gp2,2010-04-07,2009-03-20
-6gpc,2018-08-15,2018-06-05
-6gpf,2018-10-03,2018-06-05
-3gps,2010-04-07,2009-03-23
-2gpv,2006-09-26,2006-04-18
-6gp7,2019-01-23,2018-06-05
-7gp8,2023-11-29,2023-08-24
-4gpl,2013-09-18,2012-08-21
-4gpn,2012-10-03,2012-08-21
-2gpt,2006-06-06,2006-04-18
-3gpu,2009-11-10,2009-03-23
-7gpz,2023-11-29,2023-08-24
-1gpa,1992-10-15,1990-11-13
-4gp4,2013-01-16,2012-08-20
-3gph,2010-05-12,2009-03-23
-1gpc,1995-10-15,1995-06-01
-2gpy,2006-06-06,2006-04-18
-5gpb,1992-10-15,1990-06-04
-6gpu,2019-02-27,2018-06-07
-1gpd,1977-02-17,1975-07-01
-7gpc,2023-11-29,2023-08-24
-7gpy,2023-11-29,2023-08-24
-7gpd,2023-11-29,2023-08-24
-4gpe,2013-05-22,2012-08-20
-7gpr,2023-11-29,2023-08-24
-2gp5,2006-05-23,2006-04-16
-3gp1,2009-11-10,2009-03-20
-7gp0,2023-11-29,2023-08-24
-5gpq,2017-08-09,2016-08-04
-8gp5,2023-08-09,2022-08-25
-2gpb,1992-10-15,1990-06-04
-3gpy,2009-11-10,2009-03-23
-6gp6,2019-06-19,2018-06-05
-7gpm,2023-11-29,2023-08-24
-4gpr,2012-12-12,2012-08-21
-8gpw,2022-11-02,2022-08-27
-5gpy,2016-11-02,2016-08-05
-1gpx,1999-01-27,1998-06-10
-3gp0,2009-04-07,2009-03-20
-6gpb,1992-10-15,1990-06-04
-6gp8,2018-10-03,2018-06-05
-4gpk,2013-07-03,2012-08-21
-3gp3,2009-03-31,2009-03-20
-4gph,2013-08-21,2012-08-21
-3gpe,2009-05-05,2009-03-23
-6gph,2018-10-03,2018-06-05
-1gpm,1996-01-29,1995-04-04
-1gp4,2002-02-21,2001-10-30
-1gph,1994-07-31,1994-04-20
-6gps,2019-01-02,2018-06-07
-2gpu,2006-09-26,2006-04-18
-6gpk,2018-07-18,2018-06-06
-4gp1,2012-08-29,2012-08-20
-4gp6,2012-11-14,2012-08-20
-7gp7,2023-11-29,2023-08-24
-4gp5,2013-01-16,2012-08-20
-6gpy,2018-10-03,2018-06-07
-1gpy,1993-10-31,1993-03-31
-8gps,2023-04-19,2022-08-27
-6gpg,2018-08-08,2018-06-05
-7gpb,1992-10-15,1990-11-13
-3gpt,2009-09-15,2009-03-23
-6gp4,2018-10-03,2018-06-05
-8gpd,2023-08-30,2022-08-26
-1gp5,2002-02-21,2001-10-30
-8gp3,2023-05-17,2022-08-25
-2gpa,1999-02-26,1999-02-18
-5gpp,2017-08-09,2016-08-04
-3gpx,2009-11-10,2009-03-23
-4gpf,2013-08-21,2012-08-20
-6gpt,2018-10-03,2018-06-07
-8gpj,2023-08-09,2022-08-26
-1gp2,1997-02-12,1996-11-13
-8gpp,2023-05-31,2022-08-26
-4gp2,2012-10-10,2012-08-20
-8gpe,2023-08-30,2022-08-26
-8gpi,2023-08-09,2022-08-26
-2gp7,2006-09-26,2006-04-17
-1gpn,2002-08-29,2001-11-07
-6gpa,2018-12-26,2018-06-05
-8gpg,2023-08-09,2022-08-26
-3gpd,1983-10-27,1983-06-20
-7gp2,2023-11-29,2023-08-24
-3gp4,2009-04-21,2009-03-20
-3gp8,2009-06-16,2009-03-23
-3gpj,2009-06-02,2009-03-23
-4gpc,2013-08-21,2012-08-20
-7gph,2023-11-29,2023-08-24
-4gpj,2012-10-17,2012-08-21
-4gpu,2012-09-12,2012-08-21
-7gpx,2023-11-29,2023-08-24
-1gpj,2002-01-04,2001-11-05
-9gpb,1992-10-15,1990-12-17
-6gpx,2019-01-02,2018-06-07
-3gp6,2010-06-23,2009-03-20
-4gp8,2013-01-16,2012-08-20
-6gpl,2018-07-18,2018-06-06
-6gp3,2018-08-22,2018-06-05
-4gp7,2012-11-14,2012-08-20
-5gpj,2016-12-28,2016-08-03
-7gpq,2023-11-29,2023-08-24
-3gpc,2009-04-07,2009-03-23
-3gpq,2009-07-21,2009-03-23
-5gpo,2017-08-09,2016-08-03
-1gpl,1997-02-12,1996-07-13
-6gpo,2018-10-03,2018-06-06
-5gpa,2017-03-01,2016-08-01
-1gpe,1999-05-06,1999-03-24
-5gpr,2017-01-11,2016-08-04
-7gpt,2023-11-29,2023-08-24
-8gpm,2023-05-31,2022-08-26
-7gpo,2023-11-29,2023-08-24
-2gpj,2006-06-13,2006-04-17
-7gpw,2023-11-29,2023-08-24
-4gpt,2012-09-05,2012-08-21
-4gpa,2012-10-24,2012-08-20
-5gp0,2017-10-04,2016-07-30
-4gp9,2013-05-22,2012-08-20
-7gp6,2023-11-29,2023-08-24
-7gpl,2023-11-29,2023-08-24
-3gpw,2009-09-15,2009-03-23
-6gpv,2019-02-27,2018-06-07
-6gpp,2018-10-03,2018-06-06
-1gp6,2002-02-21,2001-10-30
-7gpg,2023-11-29,2023-08-24
-7gpf,2023-11-29,2023-08-24
-5gpg,2016-10-12,2016-08-02
-5gp9,2017-03-01,2016-08-01
-5gp1,2016-12-07,2016-07-30
-1gpz,2002-07-31,2001-11-15
-7gp1,2023-11-29,2023-08-24
-7gpa,2023-11-29,2023-08-24
-7gpv,2023-11-29,2023-08-24
-7gpu,2023-11-29,2023-08-24
-3gp9,2009-08-11,2009-03-23
-7gpn,2023-11-29,2023-08-24
-6gpw,2018-10-03,2018-06-07
-7gp9,2023-11-29,2023-08-24
-6gpn,2019-01-30,2018-06-06
-1gpi,2002-01-01,2001-11-05
-2gp3,2006-05-23,2006-04-16
-7gpi,2023-11-29,2023-08-24
-1gpu,2002-02-11,2001-11-09
-7gp4,2023-11-29,2023-08-24
-6gp2,2018-08-22,2018-06-05
-8gpb,1992-10-15,1990-11-13
-5gpe,2016-12-28,2016-08-01
-3gpp,2009-11-10,2009-03-23
-1gpk,2002-08-29,2001-11-05
-6gpz,2019-01-23,2018-06-07
-3lt1,2010-06-16,2010-02-14
-7ltj,2021-03-03,2021-02-19
-7ltv,2022-08-17,2021-02-20
-1lt1,2003-05-20,2002-05-20
-1lt3,1997-07-07,1997-04-12
-5ltx,2017-09-20,2016-09-07
-6ltl,2020-05-06,2020-01-22
-1ltx,2003-05-21,2002-05-21
-4ltc,2014-07-02,2013-07-23
-5ltj,2017-01-25,2016-09-06
-2ltn,1990-07-15,1990-06-26
-4ltp,2013-10-23,2013-07-23
-5ltt,2016-11-09,2016-09-07
-3ltd,2010-09-22,2010-02-15
-1ltw,1996-12-23,1996-11-02
-7ltw,2021-11-24,2021-02-20
-4ltn,2013-08-07,2013-07-23
-7ltt,2021-11-24,2021-02-20
-1lti,1996-08-17,1996-05-09
-6ltg,2020-06-17,2020-01-22
-3ltf,2010-08-25,2010-02-15
-4lt1,2014-07-23,2013-07-23
-3ltc,2010-09-22,2010-02-15
-1lt4,1997-06-16,1997-04-14
-3ltb,2010-09-22,2010-02-15
-7ltg,2021-05-05,2021-02-19
-1lta,1994-01-31,1993-09-15
-7ltq,2021-03-17,2021-02-19
-7ltm,2021-07-07,2021-02-19
-1ltd,1994-08-31,1994-01-14
-1ltm,1998-11-11,1997-09-26
-7lta,2022-02-23,2021-02-19
-7ltn,2021-11-10,2021-02-19
-3ltq,2011-02-16,2010-02-16
-5ltz,2017-12-06,2016-09-07
-6ltr,2020-10-28,2020-01-23
-5lt9,2017-09-20,2016-09-06
-3lth,2010-05-05,2010-02-15
-3lty,2010-06-16,2010-02-16
-6lt9,2021-01-27,2020-01-22
-5ltv,2017-09-20,2016-09-07
-7lt5,2021-05-19,2021-02-18
-7lte,2021-09-29,2021-02-19
-2lt7,2012-09-05,2012-05-15
-3ltp,2010-06-16,2010-02-16
-6ltu,2020-10-28,2020-01-23
-6ltk,2021-01-27,2020-01-22
-6ltw,2020-10-21,2020-01-23
-5ltl,2018-05-09,2016-09-07
-3lt9,2010-09-22,2010-02-15
-5lte,2016-11-09,2016-09-06
-4lt2,2014-07-23,2013-07-23
-1lt7,2002-09-11,2002-05-20
-7lt3,2021-04-14,2021-02-18
-1lt9,2002-11-06,2002-05-20
-5lt0,2017-03-01,2016-09-06
-4lt4,2013-08-07,2013-07-23
-1ltt,1994-01-31,1992-07-15
-6lt5,2021-01-27,2020-01-21
-4lto,2013-10-23,2013-07-23
-6ltj,2020-02-12,2020-01-22
-7ltp,2022-02-23,2021-02-19
-6ltm,2020-05-06,2020-01-22
-5ltk,2017-01-25,2016-09-06
-5lt1,2017-03-01,2016-09-06
-4lt5,2013-12-18,2013-07-23
-1lth,1995-03-31,1995-01-04
-5lta,2017-01-25,2016-09-06
-4lt0,2014-07-23,2013-07-23
-7lti,2022-08-17,2021-02-19
-7ltx,2022-02-23,2021-02-20
-4lt7,2013-12-11,2013-07-23
-4lte,2014-05-21,2013-07-23
-5lt8,2016-10-05,2016-09-06
-1lt0,2002-11-20,2002-05-20
-3lt8,2010-09-22,2010-02-15
-6ltv,2020-10-21,2020-01-23
-7ltl,2021-05-05,2021-02-19
-5lti,2016-11-09,2016-09-06
-6lti,2021-01-27,2020-01-22
-6ltc,2021-03-10,2020-01-22
-4lt6,2013-10-09,2013-07-23
-5ltw,2017-02-01,2016-09-07
-1lt5,1997-12-03,1997-09-30
-3lt4,2010-06-16,2010-02-15
-5ltf,2017-09-13,2016-09-06
-3ltn,2010-05-05,2010-02-16
-7lty,2022-01-12,2021-02-20
-5lt7,2016-10-05,2016-09-06
-6lt4,2021-01-27,2020-01-21
-1lt6,1997-12-03,1997-10-01
-6lts,2020-03-11,2020-01-23
-3ltl,2011-04-13,2010-02-16
-7lt0,2021-03-03,2021-02-18
-1ltj,2002-11-06,2002-05-20
-1ltz,2002-07-17,2002-05-21
-7lt4,2022-02-23,2021-02-18
-7ltu,2021-03-17,2021-02-20
-7ltr,2021-09-29,2021-02-19
-1lte,1994-01-31,1991-06-25
-4lta,2014-07-30,2013-07-23
-3lt5,2010-05-12,2010-02-15
-3lt0,2010-06-16,2010-02-14
-6lt6,2020-04-22,2020-01-21
-7ltk,2021-05-05,2021-02-19
-5ltn,2017-09-13,2016-09-07
-5lt6,2016-10-05,2016-09-06
-5lth,2016-11-09,2016-09-06
-4ltz,2013-12-18,2013-07-24
-5ltm,2017-09-20,2016-09-07
-3lt2,2010-06-16,2010-02-14
-7lt2,2021-07-21,2021-02-18
-6ltb,2021-02-24,2020-01-22
-1ltk,2003-07-29,2002-05-20
-3ltw,2010-07-07,2010-02-16
-4lt8,2014-08-06,2013-07-23
-2ltq,2013-02-27,2012-05-30
-6lt8,2021-01-27,2020-01-21
-4lt3,2014-07-23,2013-07-23
-5lts,2017-09-13,2016-09-07
-1lt8,2002-09-11,2002-05-20
-7lt9,2021-04-28,2021-02-19
-3lta,2010-09-22,2010-02-15
-1ltq,2002-10-09,2002-05-20
-7lts,2021-09-29,2021-02-20
-4ltm,2013-08-07,2013-07-23
-5lto,2017-09-20,2016-09-07
-1ltv,2002-07-17,2002-05-20
-3ltv,2010-09-08,2010-02-16
-7ltd,2022-08-17,2021-02-19
-1ltl,2003-05-27,2002-05-20
-3lts,2010-06-16,2010-02-16
-6ltd,2021-03-10,2020-01-22
-4ltw,2013-12-25,2013-07-24
-6lth,2020-02-12,2020-01-22
-4lts,2013-12-25,2013-07-23
-7ltz,2022-01-12,2021-02-20
-5ofs,2018-04-04,2017-07-11
-4ofj,2015-02-04,2014-01-14
-6ofb,2020-01-08,2019-03-28
-2ofi,2007-05-15,2007-01-03
-1ofz,2003-07-24,2003-04-22
-1ofr,2004-04-15,2003-04-18
-6ofq,2019-08-21,2019-03-31
-1ofw,2003-09-18,2003-04-22
-1ofu,2003-06-19,2003-04-21
-8ofb,2023-04-26,2023-03-15
-6ofr,2019-10-02,2019-04-01
-1ofd,2003-06-11,2003-04-14
-1ofg,1997-04-21,1996-10-17
-1ofe,2003-06-11,2003-04-14
-6of5,2019-09-04,2019-03-28
-8ofk,2024-01-17,2023-03-15
-8of1,2024-03-27,2023-03-13
-1of4,2003-04-17,2003-04-07
-5ofn,2017-11-29,2017-07-11
-5ofg,2018-05-23,2017-07-11
-4ofc,2014-11-19,2014-01-14
-8ofd,2023-06-14,2023-03-15
-7of8,2022-11-02,2021-05-04
-5ofh,2018-05-23,2017-07-11
-6ofv,2019-06-12,2019-04-01
-1ofj,1998-05-27,1998-01-30
-6ofd,2019-09-04,2019-03-29
-5ofv,2017-08-16,2017-07-11
-6ofs,2019-10-02,2019-04-01
-4ofe,2015-04-22,2014-01-14
-7of6,2021-06-09,2021-05-04
-4ofm,2014-12-03,2014-01-15
-3oft,2011-07-20,2010-08-16
-4ofu,2014-08-20,2014-01-15
-4ofr,2014-08-20,2014-01-15
-7ofc,2022-11-02,2021-05-04
-6ofi,2020-06-24,2019-03-29
-3ofs,2010-12-15,2010-08-16
-7ofl,2022-03-16,2021-05-05
-7of2,2021-06-02,2021-05-04
-5ofo,2017-08-16,2017-07-11
-4ofh,2015-04-22,2014-01-14
-3off,2011-03-02,2010-08-14
-5ofk,2017-10-04,2017-07-11
-3of6,2010-10-20,2010-08-13
-6of3,2019-09-11,2019-03-28
-5ofb,2018-02-14,2017-07-10
-8ofw,2023-09-06,2023-03-17
-3of9,2010-12-08,2010-08-14
-6of2,2019-09-11,2019-03-28
-7ofb,2022-11-02,2021-05-04
-1ofb,2004-04-08,2003-04-09
-2ofw,2007-04-10,2007-01-04
-7of0,2021-06-09,2021-05-04
-5of6,2018-05-23,2017-07-10
-3ofn,2010-09-15,2010-08-15
-5ofy,2017-09-27,2017-07-11
-1of3,2003-04-17,2003-04-07
-4ofa,2015-04-22,2014-01-14
-4ofy,2014-02-19,2014-01-15
-7of4,2021-06-09,2021-05-04
-5ofx,2017-10-04,2017-07-11
-4ofx,2014-02-05,2014-01-15
-4ofb,2015-04-15,2014-01-14
-5ofq,2017-09-27,2017-07-11
-7ofu,2021-05-12,2021-05-05
-1ofa,2004-04-08,2003-04-09
-2ofd,2007-05-01,2007-01-03
-4ofn,2014-12-03,2014-01-15
-3ofu,2011-05-04,2010-08-16
-3of8,2010-12-08,2010-08-14
-7of9,2022-11-02,2021-05-04
-2of1,2008-03-25,2007-01-02
-5ofw,2017-08-16,2017-07-11
-6ofy,2020-02-05,2019-04-01
-4ofk,2014-02-19,2014-01-15
-2of0,2007-03-13,2007-01-02
-4ofl,2014-10-01,2014-01-15
-5of3,2017-11-29,2017-07-10
-3of2,2010-12-01,2010-08-13
-2ofx,2007-04-10,2007-01-04
-7ofd,2022-11-02,2021-05-04
-5ofd,2018-05-23,2017-07-10
-4of7,2014-02-19,2014-01-14
-5of8,2018-05-23,2017-07-10
-5ofl,2017-10-04,2017-07-11
-2off,2007-08-07,2007-01-03
-4of9,2014-11-26,2014-01-14
-3of5,2011-02-02,2010-08-13
-1ofi,2003-07-03,2003-04-14
-5off,2018-05-23,2017-07-10
-8ofm,2024-03-27,2023-03-16
-8of7,2023-06-21,2023-03-14
-7ofi,2022-03-16,2021-05-05
-4ofq,2014-03-12,2014-01-15
-5ofc,2018-05-23,2017-07-10
-5ofe,2018-05-23,2017-07-10
-8ofv,2023-09-20,2023-03-16
-5of7,2018-05-23,2017-07-10
-1of5,2003-07-03,2003-04-08
-7ofz,2021-10-27,2021-05-05
-1ofq,2004-04-15,2003-04-17
-1ofm,2004-04-19,2003-04-15
-5of0,2018-08-01,2017-07-10
-8ofr,2023-09-20,2023-03-16
-8ofs,2023-09-20,2023-03-16
-5ofm,2017-08-16,2017-07-11
-2ofv,2007-02-27,2007-01-04
-3of4,2010-08-25,2010-08-13
-1ofl,2004-06-10,2003-04-15
-8ofa,2023-11-29,2023-03-14
-3of3,2010-09-01,2010-08-13
-1of1,2004-06-03,2003-04-03
-1ofs,2003-06-19,2003-04-19
-2of4,2007-02-27,2007-01-02
-1of6,2004-05-06,2003-04-08
-1ofo,2004-04-15,2003-04-17
-1ofc,2003-09-05,2003-04-10
-8ofe,2023-12-27,2023-03-15
-8of5,2024-03-27,2023-03-14
-4ofz,2014-07-16,2014-01-15
-4ofo,2014-10-01,2014-01-15
-7ofe,2022-11-02,2021-05-04
-5ofu,2017-09-20,2017-07-11
-7of3,2021-05-19,2021-05-04
-2ofp,2007-01-16,2007-01-04
-7of7,2021-06-23,2021-05-04
-7ofq,2022-01-19,2021-05-05
-7of1,2021-11-03,2021-05-04
-1of2,2004-01-29,2003-04-04
-2of8,2007-12-25,2007-01-03
-6ofw,2020-04-08,2019-04-01
-3of1,2010-12-01,2010-08-13
-8of0,2023-10-18,2023-03-13
-6of6,2020-06-24,2019-03-28
-4of4,2015-02-18,2014-01-14
-6of8,2019-04-17,2019-03-28
-1ofk,1998-11-11,1998-06-03
-6ofc,2020-01-08,2019-03-28
-7oft,2021-05-12,2021-05-05
-2ofu,2007-02-27,2007-01-04
-3ofi,2010-09-08,2010-08-15
-7ofv,2021-08-11,2021-05-05
-5ofr,2017-09-06,2017-07-11
-8of4,2023-08-09,2023-03-13
-7ofw,2021-10-27,2021-05-05
-4ofd,2014-02-19,2014-01-14
-5of1,2018-03-21,2017-07-10
-2ofr,2008-01-08,2007-01-04
-7of5,2021-06-09,2021-05-04
-4ofi,2014-02-19,2014-01-14
-8of2,2023-12-13,2023-03-13
-4ofg,2015-01-21,2014-01-14
-1ofy,2003-09-18,2003-04-22
-6of1,2019-04-17,2019-03-28
-6ofu,2019-04-24,2019-04-01
-4ofp,2014-02-19,2014-01-15
-2ofk,2007-05-15,2007-01-03
-7off,2022-11-02,2021-05-04
-3ofk,2010-10-27,2010-08-15
-4of3,2014-02-19,2014-01-14
-7ofy,2022-01-19,2021-05-05
-8ofl,2023-04-05,2023-03-16
-2ofb,2007-12-25,2007-01-03
-1of8,2004-04-08,2003-04-08
-1ofv,1994-01-31,1992-06-22
-5of5,2018-05-23,2017-07-10
-1ofh,2003-07-03,2003-04-14
-3ofm,2011-01-19,2010-08-15
-1of0,2004-05-21,2003-04-03
-5of9,2018-02-14,2017-07-10
-8ofg,2023-06-21,2023-03-15
-7ofx,2022-01-19,2021-05-05
-7ofs,2021-05-12,2021-05-05
-4of6,2014-02-19,2014-01-14
-5ofa,2018-02-14,2017-07-10
-7ofk,2022-03-16,2021-05-05
-2ofe,2007-05-01,2007-01-03
-4of8,2014-02-19,2014-01-14
-2of2,2007-02-27,2007-01-02
-7ofa,2022-11-02,2021-05-04
-5ofi,2017-10-04,2017-07-11
-5s1q,2021-01-13,2020-11-02
-3s1j,2011-09-21,2011-05-15
-7s1p,2022-03-16,2021-09-02
-6s1z,2019-11-13,2019-06-19
-7s13,2021-10-20,2021-08-31
-3s1e,2012-05-23,2011-05-15
-4s10,2015-06-03,2015-01-07
-5s1y,2021-01-13,2020-11-02
-7s1a,2021-10-06,2021-09-01
-7s1k,2022-01-19,2021-09-02
-3s1m,2011-08-10,2011-05-15
-6s1b,2019-06-26,2019-06-18
-1s1a,2005-01-18,2004-01-06
-4s1g,2015-02-25,2015-01-13
-6s1s,2019-10-09,2019-06-19
-3s13,2011-12-14,2011-05-14
-3s1s,2011-07-13,2011-05-16
-5s1g,2021-01-13,2020-11-02
-4s1b,2015-02-11,2015-01-12
-4s1f,2015-10-07,2015-01-13
-1s19,2004-04-13,2004-01-06
-1s1p,2004-03-23,2004-01-07
-3s11,2011-12-14,2011-05-14
-4s1r,2015-04-22,2015-01-14
-4s1m,2015-01-28,2015-01-14
-4s1o,2016-01-20,2015-01-14
-6s16,2019-09-25,2019-06-18
-3s1i,2011-09-21,2011-05-15
-3s1t,2012-06-13,2011-05-16
-1s1r,2004-03-23,2004-01-07
-3s14,2011-08-10,2011-05-14
-1s1o,2004-02-24,2004-01-07
-1s1q,2004-05-04,2004-01-07
-7s1j,2022-03-02,2021-09-02
-1s1t,2004-06-29,2004-01-07
-5s1c,2021-01-13,2020-11-02
-1s1s,2005-01-18,2004-01-07
-1s1x,2004-06-29,2004-01-07
-1s1v,2004-06-29,2004-01-07
-5s1w,2021-01-13,2020-11-02
-6s1u,2019-10-16,2019-06-19
-6s1h,2019-06-26,2019-06-18
-7s1r,2022-01-26,2021-09-02
-6s1f,2019-10-16,2019-06-18
-4s14,2015-02-11,2015-01-07
-4s1q,2015-04-22,2015-01-14
-5s1m,2021-01-13,2020-11-02
-6s1o,2019-12-25,2019-06-19
-1s1f,2005-01-11,2004-01-06
-4s1i,2015-02-04,2015-01-14
-6s1i,2019-06-26,2019-06-18
-6s17,2019-06-26,2019-06-18
-1s18,2004-03-16,2004-01-05
-7s1q,2022-01-26,2021-09-02
-4s1k,2015-03-25,2015-01-14
-1s1d,2004-03-16,2004-01-06
-7s1o,2022-01-19,2021-09-02
-3s1l,2012-04-25,2011-05-15
-5s1a,2021-01-13,2020-11-02
-7s14,2021-10-06,2021-08-31
-6s1y,2019-11-13,2019-06-19
-4s1d,2015-03-04,2015-01-13
-4s18,2015-11-25,2015-01-09
-4s1c,2015-02-11,2015-01-12
-5s1o,2021-01-13,2020-11-02
-1s16,2004-05-04,2004-01-05
-7s1u,2022-01-19,2021-09-02
-7s16,2022-02-16,2021-09-01
-5s1s,2021-01-13,2020-11-02
-3s1x,2011-08-24,2011-05-16
-3s17,2011-08-10,2011-05-14
-6s1x,2020-05-13,2019-06-19
-4s15,2015-02-11,2015-01-08
-3s1n,2011-08-10,2011-05-15
-7s1x,2022-05-25,2021-09-02
-6s11,2019-06-26,2019-06-18
-3s1r,2011-08-10,2011-05-16
-3s1a,2011-09-21,2011-05-14
-6s14,2019-06-26,2019-06-18
-3s1f,2012-05-23,2011-05-15
-1s1w,2004-06-29,2004-01-07
-5s1i,2021-01-13,2020-11-02
-6s1j,2019-06-26,2019-06-18
-7s1l,2023-02-08,2021-09-02
-4s1h,2015-01-28,2015-01-13
-1s17,2004-03-30,2004-01-05
-1s14,2004-05-04,2004-01-05
-7s1f,2023-02-08,2021-09-02
-5s1k,2021-01-13,2020-11-02
-1s1j,2004-05-04,2004-01-06
-7s1b,2022-11-09,2021-09-02
-3s1g,2012-05-16,2011-05-15
-3s12,2011-12-14,2011-05-14
-3s1d,2012-05-23,2011-05-15
-6s1m,2019-12-25,2019-06-19
-7s1s,2022-01-26,2021-09-02
-1s1z,2004-06-15,2004-01-07
-7s18,2022-03-02,2021-09-01
-5s1e,2021-01-13,2020-11-02
-4s17,2015-01-28,2015-01-08
-6s1t,2021-04-28,2019-06-19
-1s1m,2004-06-15,2004-01-06
-1s1y,2004-06-15,2004-01-07
-7s19,2022-03-02,2021-09-01
-3s1v,2011-08-24,2011-05-16
-5s18,2021-01-13,2020-11-02
-4s1l,2015-03-25,2015-01-14
-4s1z,2015-04-08,2015-01-16
-7s1y,2022-05-25,2021-09-02
-5s1u,2021-01-13,2020-11-02
-7s1w,2021-09-22,2021-09-02
-3s1u,2011-08-24,2011-05-16
-7s1g,2021-11-17,2021-09-02
-3s16,2011-08-10,2011-05-14
-1s1g,2004-03-23,2004-01-06
-7s1h,2021-11-17,2021-09-02
-7s11,2021-11-03,2021-08-31
-1s1e,2005-01-11,2004-01-06
-7s1t,2022-01-19,2021-09-02
-4s13,2015-05-06,2015-01-07
-3s1c,2012-05-23,2011-05-15
-1s1u,2004-06-29,2004-01-07
-7s1i,2022-03-02,2021-09-02
-1s10,2004-03-30,2004-01-05
-4s1s,2015-04-22,2015-01-14
-6s1n,2019-12-25,2019-06-19
-7s10,2022-09-07,2021-08-31
-3s1h,2012-10-31,2011-05-15
-7s1n,2021-11-03,2021-09-02
-1s1c,2004-02-10,2004-01-06
-7s15,2022-06-08,2021-09-01
-3s19,2011-06-29,2011-05-14
-3s1y,2011-06-29,2011-05-16
-7s1d,2023-02-08,2021-09-02
-3s1q,2011-08-10,2011-05-16
-3s18,2011-07-13,2011-05-14
-3s15,2011-08-10,2011-05-14
-7s1c,2023-02-08,2021-09-02
-6s1v,2019-10-16,2019-06-19
-1s13,2004-08-24,2004-01-05
-7jgp,2020-10-14,2020-07-19
-2jgi,2007-04-17,2007-02-13
-4jgo,2013-05-15,2013-03-01
-5jgy,2017-05-03,2016-04-20
-1jgt,2001-12-28,2001-06-26
-2jgu,2008-04-22,2007-02-15
-1jg4,2001-11-16,2001-06-22
-5jga,2016-07-27,2016-04-19
-5jgv,2017-02-15,2016-04-20
-6jgc,2020-08-19,2019-02-13
-8jgq,2024-05-15,2023-05-21
-7jgk,2020-10-14,2020-07-19
-2jgs,2008-03-04,2007-02-14
-5jgm,2017-05-10,2016-04-20
-4jgi,2013-08-07,2013-03-01
-5jgq,2017-05-10,2016-04-20
-8jgt,2024-05-15,2023-05-21
-8jgd,2024-01-31,2023-05-20
-7jg4,2021-03-31,2020-07-18
-1jgy,2001-09-05,2001-06-27
-2jg7,2008-05-13,2007-02-09
-8jg8,2024-04-17,2023-05-19
-7jg2,2020-11-11,2020-07-18
-7jgz,2021-07-14,2020-07-20
-7jg3,2021-03-31,2020-07-18
-5jgz,2017-02-15,2016-04-20
-1jg6,2001-08-15,2001-06-23
-7jg8,2020-08-19,2020-07-18
-2jgd,2007-02-27,2007-02-12
-6jgz,2019-12-11,2019-02-16
-7jgo,2020-10-14,2020-07-19
-2jgp,2007-10-30,2007-02-13
-6jgm,2020-02-26,2019-02-14
-4jgc,2013-05-29,2013-02-28
-4jgj,2013-03-13,2013-03-01
-2jgl,2007-04-17,2007-02-13
-7jgs,2020-09-09,2020-07-19
-1jg9,2001-10-31,2001-06-23
-8jg4,2024-05-22,2023-05-19
-4jg1,2013-08-28,2013-02-28
-8jgb,2024-01-10,2023-05-20
-5jgk,2017-03-01,2016-04-20
-6jgk,2020-08-19,2019-02-14
-5jgb,2016-07-27,2016-04-20
-8jgw,2024-05-15,2023-05-21
-7jgr,2020-09-09,2020-07-19
-6jg6,2020-08-19,2019-02-13
-6jgl,2020-08-19,2019-02-14
-7jgw,2021-02-24,2020-07-19
-2jgj,2007-04-17,2007-02-13
-2jgb,2007-02-27,2007-02-12
-1jgu,2001-12-05,2001-06-26
-1jg7,2001-08-15,2001-06-23
-2jgo,2007-07-10,2007-02-13
-1jgw,2001-09-05,2001-06-27
-4jgd,2014-03-05,2013-03-01
-5jgs,2017-01-11,2016-04-20
-7jgv,2021-02-24,2020-07-19
-1jgd,2003-07-01,2001-06-25
-2jg8,2008-02-19,2007-02-09
-4jgp,2013-05-15,2013-03-01
-1jg5,2001-10-10,2001-06-23
-6jg3,2019-12-11,2019-02-13
-1jg3,2001-11-16,2001-06-22
-2jg6,2007-02-20,2007-02-08
-7jgl,2020-10-21,2020-07-19
-1jg2,2001-11-16,2001-06-22
-5jgr,2017-02-15,2016-04-20
-6jgt,2020-08-19,2019-02-14
-1jgm,2001-07-04,2001-06-26
-1jgi,2001-10-31,2001-06-25
-1jgz,2001-09-05,2001-06-27
-5jg5,2017-01-11,2016-04-19
-1jgx,2001-09-05,2001-06-27
-4jga,2013-05-29,2013-02-28
-1jgs,2001-12-28,2001-06-26
-6jgn,2020-08-19,2019-02-14
-5jg1,2016-09-21,2016-04-19
-6jgx,2019-09-25,2019-02-15
-7jg0,2021-03-31,2020-07-18
-4jgv,2013-12-18,2013-03-04
-2jgm,2007-04-17,2007-02-13
-7jgq,2020-10-21,2020-07-19
-1jg0,2002-02-08,2001-06-22
-5jgc,2017-07-05,2016-04-20
-1jgc,2002-01-09,2001-06-24
-6jgg,2020-08-19,2019-02-14
-5jg6,2016-06-15,2016-04-19
-2jgv,2007-04-24,2007-02-16
-5jgf,2016-06-29,2016-04-20
-2jg0,2007-02-13,2007-02-07
-1jg1,2001-11-16,2001-06-22
-4jgu,2014-03-05,2013-03-03
-6jg1,2020-08-19,2019-02-13
-6jgp,2020-08-19,2019-02-14
-6jga,2020-08-19,2019-02-13
-4jg8,2013-04-10,2013-02-28
-8jg7,2024-05-22,2023-05-19
-2jg4,2007-07-03,2007-02-07
-4jgt,2013-05-29,2013-03-03
-2jgf,2007-04-17,2007-02-13
-7jg1,2020-11-11,2020-07-18
-6jg9,2019-07-03,2019-02-13
-5jgi,2017-05-10,2016-04-20
-5jg0,2017-04-19,2016-04-19
-7jgn,2020-10-14,2020-07-19
-1jge,2002-10-30,2001-06-25
-7jg5,2020-08-19,2020-07-18
-6jgr,2020-08-19,2019-02-14
-5jg3,2017-01-11,2016-04-19
-5jgl,2017-03-01,2016-04-20
-8jg2,2024-05-08,2023-05-19
-1jg8,2001-07-04,2001-06-23
-5jgn,2017-02-15,2016-04-20
-6jg2,2020-08-19,2019-02-13
-6jgd,2020-08-19,2019-02-13
-4jg7,2013-04-10,2013-02-28
-2jg3,2007-08-07,2007-02-07
-2jga,2007-04-03,2007-02-09
-2jg2,2007-05-01,2007-02-07
-7jgh,2021-01-13,2020-07-19
-4jg6,2013-04-10,2013-02-28
-5jgw,2017-05-03,2016-04-20
-6jgj,2019-04-17,2019-02-14
-6jg7,2020-08-19,2019-02-13
-6jgb,2020-08-19,2019-02-13
-1jgj,2001-07-18,2001-06-25
-6jgq,2020-08-19,2019-02-14
-7jgc,2020-08-19,2020-07-18
-7jga,2020-08-19,2020-07-18
-8jgr,2024-05-15,2023-05-21
-6jgs,2020-08-19,2019-02-14
-2jgq,2008-02-26,2007-02-14
-5jg8,2016-07-06,2016-04-19
-5jgx,2017-02-15,2016-04-20
-2jg1,2007-04-24,2007-02-07
-7jg9,2020-08-19,2020-07-18
-4jgl,2013-04-03,2013-03-01
-1jgl,2001-10-10,2001-06-26
-8jgu,2024-05-15,2023-05-21
-5jgo,2017-05-10,2016-04-20
-7jgi,2020-09-02,2020-07-19
-2jgk,2007-04-17,2007-02-13
-5jgu,2017-02-15,2016-04-20
-8jgo,2024-05-15,2023-05-21
-8jgp,2024-05-15,2023-05-21
-6jge,2020-08-19,2019-02-13
-7jgm,2020-10-14,2020-07-19
-6jgo,2020-08-19,2019-02-14
-5jgt,2017-01-11,2016-04-20
-4jg0,2013-08-28,2013-02-28
-2jg9,2008-02-19,2007-02-09
-5jgd,2016-07-27,2016-04-20
-1jkx,2001-11-30,2001-07-13
-7jkl,2021-06-30,2020-07-28
-2jk8,2009-11-17,2008-08-22
-1jk8,2001-08-22,2001-07-11
-4jkc,2013-05-22,2013-03-09
-4jkd,2013-05-22,2013-03-09
-4jkf,2013-05-22,2013-03-09
-6jki,2019-07-03,2019-03-01
-2jkx,2008-09-09,2008-09-01
-6jko,2019-06-12,2019-03-01
-1jk4,2003-02-04,2001-07-11
-4jk3,2013-06-12,2013-03-09
-5jkm,2016-10-26,2016-04-26
-2jkz,2009-11-17,2008-09-02
-2jkq,2008-09-09,2008-08-29
-4jkv,2013-04-24,2013-03-11
-7jkr,2021-03-10,2020-07-28
-5jkd,2016-06-22,2016-04-26
-2jk5,2009-11-17,2008-08-15
-2jkg,2008-09-23,2008-08-28
-2jke,2008-09-30,2008-08-28
-8jka,2024-05-08,2023-06-01
-4jk7,2013-05-22,2013-03-09
-4jk4,2013-07-24,2013-03-09
-4jk8,2013-05-22,2013-03-09
-7jk4,2020-09-09,2020-07-27
-6jka,2020-03-25,2019-02-28
-6jkx,2019-03-13,2019-03-03
-4jke,2013-05-22,2013-03-09
-4jkb,2013-05-22,2013-03-09
-4jkh,2013-05-22,2013-03-09
-8jkv,2024-05-22,2023-06-02
-7jk9,2021-03-17,2020-07-28
-6jkb,2020-03-25,2019-02-28
-2jkt,2008-10-28,2008-08-29
-6jk3,2020-03-04,2019-02-27
-1jku,2002-07-13,2001-07-13
-1jk2,2001-10-19,2001-07-11
-1jkj,2002-01-30,2001-07-12
-5jkc,2016-06-22,2016-04-26
-1jkn,2002-02-27,2001-07-12
-8jk8,2024-05-08,2023-06-01
-4jkx,2014-05-21,2013-03-12
-2jk1,2008-11-11,2008-05-26
-2jkw,2008-11-04,2008-09-01
-6jkt,2020-03-04,2019-03-01
-2jky,2009-11-17,2008-09-02
-2jkc,2008-09-02,2008-08-26
-5jk3,2017-02-15,2016-04-25
-2jkp,2008-09-30,2008-08-29
-5jke,2016-06-22,2016-04-26
-7jkp,2021-06-30,2020-07-28
-6jk4,2019-06-26,2019-02-27
-2jkv,2009-09-01,2008-09-01
-6jku,2020-03-04,2019-03-01
-6jks,2020-03-04,2019-03-01
-2jkh,2009-01-13,2008-08-28
-6jkh,2020-03-04,2019-02-28
-5jk5,2017-04-26,2016-04-26
-4jk1,2013-04-10,2013-03-09
-7jk6,2020-09-09,2020-07-27
-6jk8,2020-03-04,2019-02-27
-1jkh,2001-10-03,2001-07-12
-2jkr,2008-10-28,2008-08-29
-6jk6,2020-02-19,2019-02-27
-8jku,2023-08-09,2023-06-01
-2jkj,2008-12-16,2008-08-28
-1jki,2002-04-10,2001-07-12
-4jkw,2013-07-24,2013-03-12
-2jkk,2008-09-09,2008-08-28
-2jki,2008-10-07,2008-08-28
-7jkw,2021-08-25,2020-07-29
-6jk9,2020-02-19,2019-02-27
-2jk0,2008-08-05,2008-05-23
-2jkn,2008-12-16,2008-08-28
-4jkk,2014-09-17,2013-03-09
-7jk5,2020-09-09,2020-07-27
-4jkg,2013-05-22,2013-03-09
-4jkn,2014-02-19,2013-03-10
-8jke,2024-02-14,2023-06-01
-5jkk,2017-05-10,2016-04-26
-4jkt,2013-08-14,2013-03-11
-1jkl,2002-04-01,2001-07-12
-6jkv,2019-06-26,2019-03-02
-2jk7,2008-11-04,2008-08-21
-6jk0,2019-09-25,2019-02-27
-2jkb,2008-09-16,2008-08-26
-5jk9,2016-06-22,2016-04-26
-1jk3,2001-09-28,2001-07-11
-6jkm,2019-06-26,2019-03-01
-7jk8,2020-12-09,2020-07-27
-7jks,2021-06-09,2020-07-28
-1jk0,2001-09-05,2001-07-10
-8jk3,2024-06-05,2023-05-31
-4jk9,2013-05-22,2013-03-09
-1jkf,2002-04-10,2001-07-12
-5jkl,2016-10-26,2016-04-26
-1jke,2002-01-25,2001-07-12
-4jkp,2013-05-15,2013-03-11
-7jkt,2021-06-09,2020-07-28
-4jk5,2013-07-17,2013-03-09
-2jk9,2008-09-16,2008-08-22
-2jkl,2008-12-16,2008-08-28
-1jk9,2001-09-05,2001-07-11
-5jkw,2017-04-26,2016-04-26
-7jk3,2020-09-09,2020-07-27
-2jk6,2009-04-28,2008-08-21
-7jky,2021-08-25,2020-07-29
-4jku,2013-03-27,2013-03-11
-4jka,2013-05-22,2013-03-09
-7jkx,2021-06-23,2020-07-29
-6jkp,2019-06-12,2019-03-01
-5jkn,2016-06-22,2016-04-26
-6jkf,2020-02-19,2019-02-28
-6jke,2020-07-01,2019-02-28
-4jk6,2013-07-17,2013-03-09
-4jks,2013-03-27,2013-03-11
-4jkl,2014-09-17,2013-03-09
-5jka,2016-06-22,2016-04-26
-8jkp,2024-05-08,2023-06-01
-2jks,2009-02-03,2008-08-29
-4jky,2014-06-25,2013-03-12
-2jko,2008-09-09,2008-08-28
-4jk2,2013-04-17,2013-03-09
-5jk8,2017-05-03,2016-04-26
-8jkr,2024-05-08,2023-06-01
-7jkv,2020-09-23,2020-07-29
-1jkk,2002-04-01,2001-07-12
-5jk6,2017-04-26,2016-04-26
-1jk7,2001-08-15,2001-07-11
-1jk1,2001-10-19,2001-07-11
-5jkg,2016-10-05,2016-04-26
-1jkv,2002-07-13,2001-07-13
-5jkv,2017-04-26,2016-04-26
-2jka,2008-09-30,2008-08-23
-8jk5,2024-05-08,2023-05-31
-7jkz,2021-08-25,2020-07-29
-2jkm,2008-09-09,2008-08-28
-4jki,2013-03-20,2013-03-09
-4jkr,2013-05-15,2013-03-11
-8jkk,2024-03-06,2023-06-01
-7jk2,2020-09-09,2020-07-27
-8jk9,2024-05-08,2023-06-01
-8jkz,2024-01-24,2023-06-02
-7jk1,2021-06-30,2020-07-27
-6jkw,2019-04-17,2019-03-02
-4ity,2013-01-30,2013-01-19
-4ito,2014-03-26,2013-01-18
-8itp,2024-03-27,2023-03-22
-2itb,2006-11-07,2006-10-19
-3it5,2009-11-17,2009-08-27
-3itg,2010-01-12,2009-08-28
-3itu,2009-10-27,2009-08-28
-3itv,2010-02-02,2009-08-28
-1it8,2002-05-22,2002-01-11
-1ith,1993-10-31,1991-12-03
-4itj,2013-03-13,2013-01-18
-4itq,2013-03-27,2013-01-18
-6ity,2019-10-30,2018-11-26
-2itk,2007-05-22,2006-10-19
-4itb,2013-04-24,2013-01-18
-8itx,2024-03-27,2023-03-23
-1itw,2002-12-11,2002-02-12
-6ite,2019-09-25,2018-11-21
-3it7,2009-11-17,2009-08-27
-1ito,2003-01-19,2002-01-19
-2it5,2006-12-05,2006-10-19
-2itf,2006-12-26,2006-10-19
-4it5,2013-01-30,2013-01-17
-6itj,2019-10-23,2018-11-23
-6itl,2019-11-27,2018-11-23
-4ita,2013-04-24,2013-01-18
-3itj,2010-03-31,2009-08-28
-4itp,2014-01-01,2013-01-18
-2itx,2007-04-03,2006-05-25
-3ita,2009-10-20,2009-08-27
-8itg,2023-06-21,2023-03-22
-3itc,2010-02-02,2009-08-28
-4ite,2014-01-22,2013-01-18
-3it6,2010-03-02,2009-08-27
-4itz,2013-03-20,2013-01-19
-4itx,2014-12-24,2013-01-19
-6itx,2019-10-09,2018-11-26
-5it9,2016-05-18,2016-03-16
-6itc,2019-06-12,2018-11-21
-3itt,2010-02-02,2009-08-28
-8itf,2023-05-31,2023-03-22
-8itn,2024-03-27,2023-03-22
-5it4,2016-04-27,2016-03-16
-1it6,2002-05-22,2002-01-09
-1itc,2003-05-27,2002-01-17
-5itz,2016-06-01,2016-03-17
-6itm,2019-11-27,2018-11-23
-8it6,2024-03-27,2023-03-22
-2it6,2006-12-05,2006-10-19
-5itv,2017-02-22,2016-03-17
-8it7,2024-03-27,2023-03-22
-4itf,2014-01-22,2013-01-18
-2itn,2007-04-03,2006-05-25
-2it4,2007-09-11,2006-10-19
-5ith,2017-02-22,2016-03-16
-8ity,2023-06-07,2023-03-23
-3iti,2009-10-27,2009-08-28
-6itd,2020-01-15,2018-11-21
-5it0,2016-04-27,2016-03-16
-3it9,2009-10-20,2009-08-27
-5ito,2016-11-30,2016-03-17
-1itz,2003-02-15,2002-02-15
-6itk,2019-11-27,2018-11-23
-4itt,2013-03-20,2013-01-18
-5itc,2017-01-25,2016-03-16
-5it5,2016-10-19,2016-03-16
-8itd,2024-03-27,2023-03-22
-2itw,2007-04-03,2006-05-25
-2itc,2007-05-15,2006-10-19
-5itf,2016-10-26,2016-03-16
-2itd,2007-05-15,2006-10-19
-2ito,2007-04-03,2006-05-25
-4ith,2013-03-13,2013-01-18
-8it4,2024-03-27,2023-03-22
-3ito,2010-02-02,2009-08-28
-4itw,2013-03-20,2013-01-18
-3ith,2010-03-16,2009-08-28
-3itn,2010-03-02,2009-08-28
-8itt,2024-01-31,2023-03-22
-5itd,2016-09-07,2016-03-16
-4itl,2013-04-03,2013-01-18
-5itp,2016-11-30,2016-03-17
-8itc,2024-03-27,2023-03-22
-5it7,2016-05-18,2016-03-16
-4itu,2013-03-27,2013-01-18
-2itt,2007-04-03,2006-05-25
-5it8,2016-07-27,2016-03-16
-2itv,2007-04-03,2006-05-25
-1it7,2002-05-22,2002-01-11
-8it8,2024-03-27,2023-03-22
-1it0,2002-02-20,2001-12-27
-6itv,2019-11-27,2018-11-26
-8itz,2024-03-27,2023-03-23
-2itz,2007-04-03,2006-05-25
-3itl,2010-02-02,2009-08-28
-1it1,2002-07-10,2001-12-29
-2itm,2006-11-14,2006-10-19
-2it0,2007-02-13,2006-10-18
-1itt,2003-02-03,2002-02-03
-6itp,2019-07-24,2018-11-24
-3it3,2009-11-10,2009-08-27
-1itk,2002-08-28,2002-01-18
-5ita,2016-08-10,2016-03-16
-8ith,2023-06-21,2023-03-22
-8ita,2023-08-23,2023-03-22
-6itq,2019-07-24,2018-11-24
-4iti,2013-03-13,2013-01-18
-3it8,2009-10-20,2009-08-27
-8itr,2024-01-31,2023-03-22
-3itz,2010-03-02,2009-08-28
-4itm,2013-04-03,2013-01-18
-5it3,2016-05-18,2016-03-16
-3itx,2010-02-02,2009-08-28
-8itb,2024-03-27,2023-03-22
-4it8,2013-04-10,2013-01-18
-4itc,2013-09-25,2013-01-18
-1itq,2002-08-28,2002-02-02
-4it0,2013-03-20,2013-01-17
-3itp,2010-07-21,2009-08-28
-8itu,2023-04-12,2023-03-23
-2itq,2007-04-03,2006-05-25
-1it2,2002-01-23,2002-01-05
-5ite,2017-01-25,2016-03-16
-1itu,2002-08-28,2002-02-03
-4it1,2013-01-30,2013-01-17
-2itu,2007-04-03,2006-05-25
-3itm,2009-10-27,2009-08-28
-5it1,2016-06-08,2016-03-16
-5iti,2016-05-04,2016-03-16
-8itv,2024-03-27,2023-03-23
-8ito,2024-03-27,2023-03-22
-4itr,2013-02-20,2013-01-18
-1it3,2002-01-23,2002-01-05
-8it9,2024-02-14,2023-03-22
-3itb,2009-10-20,2009-08-27
-2itp,2007-04-03,2006-05-25
-6itt,2019-11-27,2018-11-26
-1it4,2002-09-04,2002-01-08
-6ito,2019-08-14,2018-11-24
-8it5,2024-03-27,2023-03-22
-2ity,2007-04-03,2006-05-25
-2ux9,2007-09-11,2007-03-27
-1uxr,2004-08-05,2004-03-01
-3uxk,2012-02-08,2011-12-05
-6uxu,2020-05-13,2019-11-08
-3uxv,2011-12-28,2011-12-05
-1uxy,1997-04-01,1996-11-08
-2uxb,2007-07-31,2007-03-28
-5ux7,2018-02-28,2017-02-22
-6uxz,2020-10-07,2019-11-09
-7ux2,2022-11-30,2022-05-04
-7uxk,2022-12-28,2022-05-05
-1ux6,2004-03-18,2004-02-19
-3uxm,2012-02-01,2011-12-05
-1ux7,2004-10-27,2004-02-19
-3uxl,2012-02-08,2011-12-05
-8uxu,2024-05-01,2023-11-10
-2ux5,2007-07-03,2007-03-26
-2uxu,2007-05-08,2007-03-29
-5uxu,2017-07-12,2017-02-23
-5uxc,2017-08-16,2017-02-22
-5ux4,2018-06-13,2017-02-22
-2uxf,2007-08-21,2007-03-28
-2uxa,2007-04-10,2007-03-27
-7uxz,2022-06-22,2022-05-06
-5uxe,2017-03-08,2017-02-22
-1uxx,2004-03-11,2004-03-01
-2uxm,2007-07-03,2007-03-28
-7uxm,2022-12-28,2022-05-05
-2uxg,2007-08-21,2007-03-28
-2uxq,2008-02-05,2007-03-29
-8uxe,2023-11-22,2023-11-09
-1uxt,2004-08-05,2004-03-01
-4uxx,2015-09-30,2014-08-27
-2uxk,2007-07-03,2007-03-28
-5uxn,2018-02-28,2017-02-23
-5uxm,2018-02-28,2017-02-23
-2uxo,2007-05-08,2007-03-28
-1uxn,2004-08-05,2004-02-27
-3ux3,2012-05-30,2011-12-03
-5uxh,2017-04-05,2017-02-22
-3uxy,2011-12-28,2011-12-05
-8uxw,2024-01-31,2023-11-11
-1ux0,2004-05-20,2004-02-18
-3uxf,2012-11-28,2011-12-05
-1uxi,2004-08-26,2004-02-25
-7uxy,2023-05-17,2022-05-06
-6ux0,2020-10-21,2019-11-06
-6ux8,2020-04-01,2019-11-07
-5ux6,2017-04-05,2017-02-22
-7uxw,2023-05-10,2022-05-06
-4uxl,2015-03-11,2014-08-25
-7uxq,2022-12-28,2022-05-05
-3uxh,2012-01-18,2011-12-05
-2uxx,2007-08-21,2007-03-30
-7uxs,2022-09-07,2022-05-06
-7ux3,2023-05-10,2022-05-04
-4ux3,2014-12-03,2014-08-18
-5ux5,2017-04-26,2017-02-22
-4ux8,2014-10-01,2014-08-19
-8uxh,2023-11-22,2023-11-09
-8uxg,2023-11-22,2023-11-09
-6uxc,2020-11-11,2019-11-07
-8uxc,2023-11-22,2023-11-09
-7ux6,2022-10-12,2022-05-05
-7uxo,2022-12-28,2022-05-05
-1uxu,2004-08-05,2004-03-01
-6uxw,2020-03-18,2019-11-08
-6ux2,2020-07-08,2019-11-06
-5ux2,2018-02-28,2017-02-21
-2ux6,2007-08-21,2007-03-27
-4uxn,2015-02-25,2014-08-27
-3ux8,2012-02-08,2011-12-04
-6ux4,2020-03-18,2019-11-06
-1uxv,2004-08-05,2004-03-01
-2ux0,2007-04-10,2007-03-26
-1uxm,2004-03-19,2004-02-26
-6ux9,2020-12-09,2019-11-07
-3uxe,2012-01-18,2011-12-05
-5uxz,2017-03-08,2017-02-23
-7uxj,2022-12-28,2022-05-05
-1uxg,2004-08-26,2004-02-25
-2uxr,2008-02-05,2007-03-29
-1uxs,2004-11-09,2004-03-01
-7uxf,2023-03-08,2022-05-05
-7uxv,2023-05-10,2022-05-06
-4uxb,2015-09-02,2014-08-21
-2ux8,2007-05-22,2007-03-27
-5uxs,2017-07-12,2017-02-23
-7ux8,2022-09-28,2022-05-05
-3ux0,2013-01-02,2011-12-03
-1uxe,2004-07-02,2004-02-24
-1ux1,2004-05-20,2004-02-18
-7uxl,2023-02-15,2022-05-05
-4uxw,2015-09-30,2014-08-27
-4uxi,2015-05-27,2014-08-22
-7uxd,2022-12-14,2022-05-05
-6uxx,2020-08-19,2019-11-08
-1uxa,2004-07-01,2004-02-24
-2ux3,2007-07-03,2007-03-26
-7uxh,2022-11-30,2022-05-05
-8ux7,2023-11-29,2023-11-09
-4uxh,2015-05-27,2014-08-22
-1uxp,2004-08-05,2004-02-27
-6uxj,2020-02-12,2019-11-07
-6ux1,2020-04-22,2019-11-06
-2uxz,2008-05-20,2007-04-02
-3uxp,2012-12-05,2011-12-05
-3uxi,2012-12-26,2011-12-05
-5uxd,2017-08-23,2017-02-22
-4uxq,2014-12-03,2014-08-27
-7uxi,2022-12-28,2022-05-05
-1uxl,2004-03-19,2004-02-25
-6uxe,2019-11-20,2019-11-07
-8uxx,2024-01-31,2023-11-11
-2uxn,2007-05-29,2007-03-28
-7uxp,2022-12-28,2022-05-05
-7ux4,2022-05-18,2022-05-04
-7ux0,2022-10-12,2022-05-04
-2uxd,2007-10-02,2007-03-28
-1uxw,2004-11-09,2004-03-01
-1ux2,2004-03-25,2004-02-18
-4ux4,2015-06-10,2014-08-19
-7uxn,2022-12-28,2022-05-05
-2uxp,2007-05-08,2007-03-29
-2ux4,2007-07-03,2007-03-26
-1uxq,2004-08-05,2004-03-01
-5uxy,2018-11-21,2017-02-23
-8uxm,2023-11-22,2023-11-09
-2uxw,2007-05-01,2007-03-30
-1uxk,2004-08-26,2004-02-25
-7uxc,2022-11-30,2022-05-05
-6uxn,2020-09-02,2019-11-07
-5uxo,2018-02-28,2017-02-23
-5uxa,2017-06-28,2017-02-22
-2uxj,2007-07-03,2007-03-28
-2ux1,2008-05-27,2007-03-26
-5ux9,2017-03-08,2017-02-22
-8uxf,2023-11-22,2023-11-09
-8uxl,2023-11-22,2023-11-09
-8uxi,2023-11-22,2023-11-09
-1uxb,2004-07-01,2004-02-24
-2ux7,2007-08-21,2007-03-27
-7uxu,2022-09-07,2022-05-06
-5uxf,2017-04-19,2017-02-22
-2uxh,2007-05-08,2007-03-28
-6uxy,2020-08-19,2019-11-08
-4uxu,2014-10-01,2014-08-27
-6uxl,2020-02-12,2019-11-07
-7ux7,2022-10-12,2022-05-05
-4uxz,2015-09-30,2014-08-27
-4uxj,2015-05-27,2014-08-22
-6ux6,2020-11-25,2019-11-06
-2uxi,2007-05-08,2007-03-28
-8ux2,2024-01-17,2023-11-08
-1uxh,2004-08-26,2004-02-25
-4ux6,2014-10-08,2014-08-19
-4uxa,2015-01-21,2014-08-21
-3uxd,2012-06-06,2011-12-05
-6uxi,2020-02-12,2019-11-07
-5ux1,2018-02-28,2017-02-21
-1ux8,2004-12-07,2004-02-20
-1ux9,2004-06-01,2004-02-23
-3uxj,2012-01-04,2011-12-05
-2uxl,2007-07-03,2007-03-28
-7ux5,2022-12-28,2022-05-05
-1uxj,2004-08-26,2004-02-25
-2uxc,2007-05-08,2007-03-28
-4ux9,2015-03-25,2014-08-20
-7jxa,2021-10-13,2020-08-26
-5jx2,2016-08-31,2016-05-12
-2jxm,2008-02-12,2007-11-22
-7jxq,2021-09-08,2020-08-27
-5jxn,2016-12-21,2016-05-13
-7jx9,2021-01-06,2020-08-26
-6jxi,2019-08-14,2019-04-23
-7jxy,2021-05-19,2020-08-28
-4jx5,2013-05-29,2013-03-27
-1jxn,2002-12-06,2001-09-07
-1jxi,2002-02-27,2001-09-07
-3jxs,2009-10-27,2009-09-21
-5jxi,2016-10-05,2016-05-13
-8jxv,2024-03-20,2023-07-01
-1jx9,2003-09-02,2001-09-06
-1jx1,2002-07-24,2001-09-05
-1jxz,2001-10-03,2001-09-10
-4jxx,2013-05-01,2013-03-28
-2jx9,2008-04-29,2007-11-09
-1jxa,2001-11-21,2001-09-06
-7jxt,2021-09-01,2020-08-27
-7jxx,2021-05-19,2020-08-28
-5jx7,2017-05-17,2016-05-12
-8jxu,2024-01-03,2023-07-01
-7jxz,2021-01-13,2020-08-28
-3jx3,2010-05-05,2009-09-18
-1jxp,1998-01-14,1997-08-21
-4jxh,2013-10-23,2013-03-28
-3jx4,2010-05-05,2009-09-18
-6jxd,2020-01-15,2019-04-23
-7jxk,2021-09-08,2020-08-27
-5jxp,2017-06-14,2016-05-13
-4jx9,2013-06-05,2013-03-28
-5jxf,2017-06-14,2016-05-13
-4jxz,2013-05-01,2013-03-28
-6jxn,2020-04-01,2019-04-24
-6jx0,2020-04-22,2019-04-21
-4jxf,2014-04-02,2013-03-28
-3jxt,2010-09-29,2009-09-21
-7jxp,2021-09-08,2020-08-27
-7jxb,2022-03-09,2020-08-27
-2jxr,1997-10-29,1997-04-24
-6jx2,2019-08-07,2019-04-22
-6jxt,2020-04-29,2019-04-25
-5jxg,2016-10-05,2016-05-13
-6jxg,2019-11-20,2019-04-23
-3jxa,2009-12-22,2009-09-18
-5jxq,2016-08-10,2016-05-13
-7jx1,2021-04-21,2020-08-26
-4jx4,2013-05-29,2013-03-27
-3jx5,2010-05-05,2009-09-18
-4jx0,2013-05-15,2013-03-27
-5jxs,2016-06-01,2016-05-13
-8jxq,2024-01-03,2023-07-01
-6jxj,2019-08-14,2019-04-23
-1jx4,2001-10-05,2001-09-05
-2jxc,2008-01-08,2007-11-12
-5jxm,2016-06-08,2016-05-13
-6jx4,2020-04-22,2019-04-22
-1jxj,2001-09-14,2001-09-07
-4jxg,2014-10-29,2013-03-28
-5jx9,2017-06-07,2016-05-12
-4jx1,2013-06-19,2013-03-27
-2jxy,2008-05-27,2007-12-01
-3jxp,2010-09-22,2009-09-21
-8jxt,2024-03-20,2023-07-01
-7jxn,2020-12-09,2020-08-27
-4jx8,2014-04-02,2013-03-28
-5jxu,2016-10-19,2016-05-13
-3jxu,2009-10-20,2009-09-21
-7jx0,2021-03-17,2020-08-26
-2jxa,2008-04-29,2007-11-09
-7jxg,2020-11-18,2020-08-27
-5jxw,2016-05-25,2016-05-13
-5jxz,2016-07-20,2016-05-13
-3jxe,2009-11-10,2009-09-19
-5jxt,2016-12-07,2016-05-13
-8jxw,2024-03-20,2023-07-01
-1jxm,2002-01-16,2001-09-07
-7jxf,2021-04-21,2020-08-27
-6jxh,2019-08-14,2019-04-23
-4jx7,2013-08-28,2013-03-27
-1jxq,2001-12-12,2001-09-08
-1jxl,2001-10-05,2001-09-07
-8jxz,2023-11-01,2023-07-01
-7jxm,2021-09-08,2020-08-27
-6jxk,2019-08-14,2019-04-23
-3jx6,2010-05-05,2009-09-18
-7jxw,2021-09-08,2020-08-28
-6jx3,2019-06-26,2019-04-22
-3jx0,2010-05-05,2009-09-18
-7jx7,2020-12-09,2020-08-26
-7jx3,2020-10-14,2020-08-26
-3jx2,2010-05-05,2009-09-18
-2jxl,2007-12-04,2007-11-20
-7jxl,2021-09-08,2020-08-27
-4jxr,2013-05-15,2013-03-28
-1jx0,2002-07-24,2001-09-05
-6jxs,2020-04-01,2019-04-24
-4jxe,2014-04-30,2013-03-28
-2jxn,2008-12-02,2007-11-23
-7jxh,2021-09-08,2020-08-27
-6jxl,2020-04-29,2019-04-23
-5jxa,2016-07-27,2016-05-12
-5jxh,2016-10-05,2016-05-13
-3jx1,2010-05-05,2009-09-18
-4jxv,2014-04-30,2013-03-28
-1jxk,2001-09-14,2001-09-07
-4jxw,2014-05-07,2013-03-28
-1jx6,2002-02-04,2001-09-05
-4jxc,2013-05-01,2013-03-28
-8jx6,2023-07-26,2023-06-30
-1jxf,2001-09-26,2001-09-07
-3jxw,2009-11-10,2009-09-21
-1jx2,2001-11-07,2001-09-05
-7jxi,2021-09-08,2020-08-27
-8jxx,2024-03-20,2023-07-01
-4jxs,2014-05-07,2013-03-28
-5jxj,2016-10-05,2016-05-13
-1jxg,2001-12-19,2001-09-07
-4jx6,2013-05-29,2013-03-27
-6jx9,2020-03-11,2019-04-22
-1jxd,2001-09-26,2001-09-07
-6jx7,2020-01-15,2019-04-22
-7jx6,2020-09-23,2020-08-26
-4jxy,2013-04-17,2013-03-28
-6vaw,2020-10-28,2019-12-18
-1vak,2004-11-23,2004-02-18
-6vah,2020-04-15,2019-12-17
-2va5,2007-11-13,2007-08-30
-2vaa,1996-06-20,1994-11-01
-1vah,2005-04-26,2004-02-17
-3vas,2012-11-14,2011-12-29
-3va0,2012-07-11,2011-12-28
-3vaj,2013-02-13,2011-12-29
-1var,1996-06-10,1996-01-04
-5vaj,2017-09-13,2017-03-27
-7va2,2022-09-07,2021-08-27
-3va8,2012-02-01,2011-12-29
-6va7,2021-01-27,2019-12-17
-6vao,2020-01-08,2019-12-17
-2vat,2008-09-23,2007-09-04
-2vau,2008-07-29,2007-09-04
-1vam,1997-01-11,1996-01-08
-8var,2024-03-27,2023-12-11
-7vaa,2022-07-06,2021-08-27
-6va8,2021-01-27,2019-12-17
-7vau,2022-07-13,2021-08-30
-3vad,2013-01-16,2011-12-29
-6va0,2021-01-27,2019-12-16
-6va9,2021-01-27,2019-12-17
-3vaw,2012-01-18,2011-12-29
-2vad,2007-11-06,2007-08-30
-5van,2018-01-31,2017-03-27
-8va1,2024-04-03,2023-12-10
-2vap,2007-09-11,2007-09-03
-1vay,2005-06-28,2004-02-19
-7va1,2023-03-08,2021-08-27
-5vaw,2018-03-28,2017-03-28
-7va6,2022-09-07,2021-08-27
-7va8,2022-07-06,2021-08-27
-7vab,2022-03-02,2021-08-28
-7vaq,2022-07-13,2021-08-30
-7vaz,2022-08-31,2021-08-30
-1vau,2005-03-08,2004-02-19
-2vag,2007-10-09,2007-08-31
-5vab,2017-04-19,2017-03-24
-8va2,2024-03-27,2023-12-10
-5va9,2018-03-28,2017-03-24
-8vaq,2024-03-27,2023-12-11
-2va2,2007-10-30,2007-08-28
-7vaw,2022-07-13,2021-08-30
-5var,2018-03-28,2017-03-27
-6vaj,2020-12-30,2019-12-17
-5vao,2017-06-21,2017-03-27
-2va7,2007-11-13,2007-08-30
-3vah,2013-02-13,2011-12-29
-1va3,2005-02-08,2004-02-07
-3vax,2013-01-02,2011-12-30
-2vas,2007-12-11,2007-09-04
-2vao,1997-10-15,1997-04-10
-3va5,2012-01-25,2011-12-28
-2vay,2008-09-16,2007-09-05
-3vay,2013-01-02,2011-12-30
-1vac,1996-06-20,1994-11-01
-7vax,2022-07-13,2021-08-30
-1vao,1997-10-15,1997-04-10
-2vaq,2008-09-16,2007-09-04
-3vag,2013-02-13,2011-12-29
-1val,1997-01-11,1996-01-08
-5vaa,2017-06-07,2017-03-24
-2va3,2007-10-30,2007-08-28
-3var,2012-02-29,2011-12-29
-5vaq,2018-01-31,2017-03-27
-7vay,2022-07-13,2021-08-30
-1vag,2004-06-01,2004-02-16
-3vak,2013-02-13,2011-12-29
-7vat,2022-07-13,2021-08-30
-3vaq,2012-11-14,2011-12-29
-7vao,2022-07-13,2021-08-30
-2va6,2007-11-13,2007-08-30
-7vam,2022-07-13,2021-08-30
-6vaq,2021-01-27,2019-12-17
-7vas,2022-07-13,2021-08-30
-6vav,2020-10-28,2019-12-18
-6vax,2020-08-26,2019-12-18
-3vaz,2013-01-02,2011-12-30
-1vad,1996-06-20,1994-11-01
-5va6,2017-04-19,2017-03-24
-8val,2024-03-27,2023-12-11
-3vaf,2013-02-13,2011-12-29
-8vas,2024-03-27,2023-12-11
-2vax,2008-09-23,2007-09-04
-5va4,2017-11-22,2017-03-24
-2va9,2007-11-20,2007-08-30
-3va7,2012-02-01,2011-12-29
-8vam,2024-03-27,2023-12-11
-3va4,2012-02-01,2011-12-28
-1vaf,2004-06-01,2004-02-16
-3vau,2012-04-11,2011-12-29
-5vah,2017-04-05,2017-03-26
-5va0,2017-08-09,2017-03-24
-2var,2007-10-02,2007-09-04
-5vac,2017-04-19,2017-03-24
-6vat,2020-08-26,2019-12-17
-6va5,2020-04-29,2019-12-16
-3vat,2012-02-29,2011-12-29
-5val,2017-06-28,2017-03-27
-7var,2022-07-13,2021-08-30
-2vaw,2007-09-11,2007-09-04
-7va9,2022-05-04,2021-08-27
-6vau,2020-01-01,2019-12-17
-3val,2013-02-13,2011-12-29
-5va8,2017-04-26,2017-03-24
-1va1,2005-02-08,2004-02-07
-5vam,2017-06-28,2017-03-27
-7va3,2022-09-07,2021-08-27
-5vad,2017-05-31,2017-03-24
-3vai,2013-02-13,2011-12-29
-8vap,2024-03-27,2023-12-11
-5va7,2017-08-09,2017-03-24
-7vac,2022-08-31,2021-08-28
-1va2,2005-02-08,2004-02-07
-1va6,2004-10-05,2004-02-12
-7vav,2022-07-13,2021-08-30
-7vap,2022-07-13,2021-08-30
-7van,2022-07-13,2021-08-30
-2vac,2007-10-16,2007-08-30
-7val,2022-07-13,2021-08-30
-1vai,2004-09-21,2004-02-17
-2vav,2008-09-23,2007-09-04
-8vat,2024-03-27,2023-12-11
-5vak,2018-01-31,2017-03-27
-3vam,2013-02-13,2011-12-29
-2vab,1996-06-20,1994-11-01
-3va3,2012-07-11,2011-12-28
-4hdm,2012-10-24,2012-10-02
-4hdo,2013-07-10,2012-10-02
-2hdh,1999-05-12,1998-12-04
-3hdh,1999-10-08,1999-04-13
-4hd4,2013-01-23,2012-10-02
-1hd4,2000-12-07,2000-11-07
-3hdq,2009-12-29,2009-05-07
-4hd7,2013-01-23,2012-10-02
-6hdq,2018-09-26,2018-08-18
-5hdb,2016-02-03,2016-01-05
-4hd5,2012-10-10,2012-10-02
-5hd1,2016-04-06,2016-01-04
-3hdm,2009-06-30,2009-05-07
-2hd5,2006-08-15,2006-06-20
-8hdo,2023-01-18,2022-11-05
-6hdz,2019-12-04,2018-08-20
-5hdt,2016-03-09,2016-01-05
-6hd2,2019-08-28,2018-08-17
-6hdh,2020-08-26,2018-08-17
-6hdt,2018-11-14,2018-08-19
-5hdp,2017-01-11,2016-01-05
-6hd1,2018-10-24,2018-08-17
-1hdk,2001-11-15,2000-11-16
-2hdr,2006-11-07,2006-06-20
-3hdp,2009-05-26,2009-05-07
-3hdk,2010-04-28,2009-05-07
-8hdg,2022-11-30,2022-11-04
-3hds,2009-09-29,2009-05-07
-2hds,2006-11-07,2006-06-20
-2hd6,2006-10-03,2006-06-20
-3hd7,2009-07-14,2009-05-07
-5hdr,2016-02-03,2016-01-05
-8hd8,2023-12-13,2022-11-03
-8hdp,2023-01-18,2022-11-05
-6hdc,2019-08-28,2018-08-17
-4hdc,2012-10-24,2012-10-02
-5hdg,2017-01-11,2016-01-05
-6hd6,2018-09-12,2018-08-17
-1hdf,2000-12-28,2000-11-13
-6hd0,2019-08-28,2018-08-17
-2hd4,2006-07-04,2006-06-20
-5hdj,2016-04-06,2016-01-05
-5hdk,2017-01-11,2016-01-05
-6hd7,2018-12-19,2018-08-17
-1hdc,1995-02-07,1994-10-21
-2hd0,2006-08-01,2006-06-19
-1hdb,1996-04-03,1995-04-14
-5hd4,2016-02-24,2016-01-04
-6hd8,2019-08-28,2018-08-17
-6hdm,2020-08-26,2018-08-17
-1hda,1994-05-31,1993-05-06
-2hdq,2006-11-07,2006-06-20
-3hdy,2009-12-29,2009-05-07
-4hdt,2012-10-10,2012-10-02
-6hdu,2019-08-28,2018-08-19
-5hdv,2016-03-16,2016-01-05
-6hdl,2020-08-26,2018-08-17
-5hda,2016-01-20,2016-01-05
-2hdx,2006-08-08,2006-06-21
-3hdb,2009-08-11,2009-05-07
-3hdn,2009-06-30,2009-05-07
-8hdd,2022-12-14,2022-11-04
-4hdh,2013-12-25,2012-10-02
-3hdl,2009-11-24,2009-05-07
-3hdg,2009-05-19,2009-05-07
-5hdu,2016-03-16,2016-01-05
-2hdp,2006-11-21,2006-06-20
-4hdl,2012-10-31,2012-10-02
-3hd1,2010-05-19,2009-05-06
-5hdx,2016-03-16,2016-01-05
-3hdo,2009-05-19,2009-05-07
-2hdn,2006-10-31,2006-06-20
-5hdh,2016-03-09,2016-01-05
-8hdh,2023-11-08,2022-11-04
-8hdk,2023-03-29,2022-11-04
-5hdz,2016-03-16,2016-01-05
-6hdf,2020-08-26,2018-08-17
-1hd7,2001-02-16,2000-11-09
-3hd3,2009-10-06,2009-05-06
-1hdq,2001-11-15,2000-11-17
-1hdx,1994-01-31,1993-10-15
-6hde,2019-08-28,2018-08-17
-6hdj,2020-08-26,2018-08-17
-6hd3,2019-08-28,2018-08-17
-8hd3,2023-11-08,2022-11-03
-1hdt,1995-10-15,1994-07-25
-6hd4,2018-10-24,2018-08-17
-1hdr,1994-08-31,1993-08-18
-8hd0,2023-11-08,2022-11-03
-4hd9,2013-01-23,2012-10-02
-3hd2,2010-05-19,2009-05-06
-6hdy,2019-08-28,2018-08-20
-4hdk,2012-10-24,2012-10-02
-1hdu,2001-11-15,2000-11-17
-6hdn,2018-09-26,2018-08-18
-8hdf,2023-02-15,2022-11-04
-2hdf,2007-05-08,2006-06-20
-1hdo,2001-02-28,2000-11-16
-4hdb,2013-08-14,2012-10-02
-3hda,2009-06-30,2009-05-07
-6hdo,2018-09-26,2018-08-18
-6hdr,2019-08-28,2018-08-18
-4hd8,2012-12-05,2012-10-02
-4hd6,2013-01-23,2012-10-02
-2hdu,2006-11-07,2006-06-20
-5hdm,2016-06-15,2016-01-05
-4hdr,2012-10-24,2012-10-02
-6hdg,2020-08-26,2018-08-17
-4hda,2012-12-05,2012-10-02
-5hd7,2016-02-24,2016-01-04
-1hdg,1995-03-31,1995-01-17
-5hdn,2017-01-11,2016-01-05
-2hd1,2006-06-27,2006-06-19
-3hdz,2009-07-07,2009-05-07
-5hdq,2016-09-21,2016-01-05
-4hdf,2013-08-14,2012-10-02
-6hdw,2019-08-28,2018-08-20
-1hdh,2001-11-15,2000-11-16
-8hd2,2023-05-17,2022-11-03
-4hdg,2013-12-25,2012-10-02
-6hdb,2019-08-28,2018-08-17
-4hdq,2013-07-10,2012-10-02
-1hds,1979-12-07,1979-10-01
-1hdi,2001-02-26,2000-11-16
-1hdy,1994-01-31,1993-10-15
-2hdj,2006-12-05,2006-06-20
-5hd0,2016-03-16,2016-01-04
-3hdi,2009-12-08,2009-05-07
-6hdx,2019-08-28,2018-08-20
-1hdz,1994-01-31,1993-10-15
-4hdp,2013-08-14,2012-10-02
-6hdk,2020-08-26,2018-08-17
-6hdi,2020-08-26,2018-08-17
-6hda,2019-08-28,2018-08-17
-2hd9,2006-12-20,2006-06-20
-6hd9,2019-08-28,2018-08-17
-6hdp,2019-08-28,2018-08-18
-2hdk,2006-10-24,2006-06-20
-5hdi,2016-05-04,2016-01-05
-4hd0,2012-10-31,2012-10-01
-1ov4,2004-02-17,2003-03-25
-7ovn,2022-07-20,2021-06-15
-6ovl,2020-05-13,2019-05-08
-8ov6,2023-05-17,2023-04-25
-4ovi,2014-05-28,2013-09-19
-1ovu,2004-04-06,2003-03-27
-1ovw,1997-10-29,1996-10-17
-6ov8,2019-05-15,2019-05-07
-5ovt,2017-12-06,2017-08-29
-5ovk,2018-02-28,2017-08-29
-7ovw,2021-08-11,2021-06-15
-8ov0,2023-08-16,2023-04-25
-3ovg,2010-10-13,2010-09-16
-1ovj,2004-04-06,2003-03-26
-2ovy,2007-03-06,2007-02-15
-4ovq,2014-01-22,2013-12-11
-7ovy,2021-10-27,2021-06-15
-1ov7,2004-04-06,2003-03-25
-5ovg,2019-02-06,2017-08-28
-3ov7,2010-12-01,2010-09-15
-1ovd,2003-08-19,2003-03-26
-7ov9,2022-06-22,2021-06-14
-4ovv,2014-09-03,2014-01-14
-7ove,2021-10-20,2021-06-14
-2ovv,2007-03-06,2007-02-15
-6ovt,2019-08-07,2019-05-08
-6ovy,2019-07-24,2019-05-08
-8ovr,2023-07-12,2023-04-26
-8ovu,2023-11-29,2023-04-26
-5ovi,2019-02-06,2017-08-28
-4ovl,2014-03-05,2013-11-21
-3ovj,2011-07-06,2010-09-16
-1ov3,2003-05-20,2003-03-25
-5ovb,2018-10-10,2017-08-28
-7ovs,2022-06-22,2021-06-15
-7ov3,2022-01-12,2021-06-14
-7ovh,2021-10-20,2021-06-14
-7ovd,2021-10-06,2021-06-14
-7ovm,2022-07-20,2021-06-15
-1ovz,2003-05-27,2003-03-27
-2ovq,2007-04-24,2007-02-14
-6ovz,2019-06-12,2019-05-08
-1ovk,2004-04-06,2003-03-26
-3ovs,2010-12-01,2010-09-17
-8ov4,2023-05-10,2023-04-25
-1ovr,2004-05-18,2003-03-27
-3ovb,2010-12-01,2010-09-16
-8ov2,2023-05-10,2023-04-25
-3ov1,2011-11-02,2010-09-15
-4ovh,2014-03-05,2014-02-21
-8ov1,2023-05-10,2023-04-25
-8ov8,2024-05-15,2023-04-25
-8ove,2023-11-29,2023-04-25
-5ov9,2017-09-06,2017-08-28
-3ova,2010-12-01,2010-09-16
-5ov8,2018-06-27,2017-08-28
-5ovf,2019-02-06,2017-08-28
-5ovh,2019-02-06,2017-08-28
-7ov5,,2021-06-14
-6ovd,2020-05-13,2019-05-07
-2ov3,2007-08-07,2007-02-12
-8ov5,2024-05-15,2023-04-25
-4ovr,2014-01-22,2013-12-12
-1ovn,2004-02-24,2003-03-27
-5ovo,2017-10-11,2017-08-29
-6ov0,2019-07-31,2019-05-06
-5ov3,2018-03-28,2017-08-27
-7ovb,2021-12-01,2021-06-14
-1ovp,2003-09-09,2003-03-27
-7ovi,2022-07-20,2021-06-15
-8ovz,2023-07-05,2023-04-26
-7ov7,2022-04-27,2021-06-14
-8ovs,2024-05-22,2023-04-26
-3ovr,2011-03-09,2010-09-17
-8ov3,2023-05-10,2023-04-25
-3ovz,2010-12-22,2010-09-17
-2ov0,2007-08-14,2007-02-12
-8ovj,2024-05-08,2023-04-26
-5ov5,2017-09-06,2017-08-28
-7ovr,2021-08-18,2021-06-15
-8ov7,2023-07-05,2023-04-25
-2ovm,2007-03-20,2007-02-14
-7ov0,2022-04-20,2021-06-14
-6ovf,2020-05-13,2019-05-07
-7ov8,2022-03-23,2021-06-14
-1ovx,2003-12-30,2003-03-27
-8ovp,2023-05-17,2023-04-26
-7ovk,2022-07-20,2021-06-15
-6ovn,2019-11-20,2019-05-08
-2ovw,1998-04-08,1997-04-04
-3ov9,2011-05-25,2010-09-16
-4ov4,2014-08-20,2014-02-20
-7ovl,2022-07-20,2021-06-15
-5ove,2019-02-06,2017-08-28
-5ovx,2017-11-22,2017-08-30
-8ova,2023-11-29,2023-04-25
-3ovu,2011-09-21,2010-09-17
-1ovh,2004-04-06,2003-03-26
-5ovl,2018-02-28,2017-08-29
-7ovv,2022-12-21,2021-06-15
-6ovc,2019-05-22,2019-05-07
-6ova,2020-02-12,2019-05-07
-7ov2,2022-01-12,2021-06-14
-7ova,2022-05-04,2021-06-14
-3ovq,2011-03-09,2010-09-17
-1ov5,2004-04-06,2003-03-25
-2ovu,2007-10-23,2007-02-15
-7ovf,2021-10-20,2021-06-14
-8ovh,2023-06-21,2023-04-26
-4ov0,2014-10-01,2014-02-19
-3ovn,2011-03-09,2010-09-16
-2ov4,2007-03-06,2007-02-12
-3ov6,2011-01-19,2010-09-15
-1ov8,2003-09-09,2003-03-25
-1ovm,2003-06-03,2003-03-27
-1ovv,2004-04-06,2003-03-27
-5ov7,2017-10-11,2017-08-28
-1ovs,2003-09-09,2003-03-27
-4ovd,2014-03-12,2014-02-21
-1ovt,1995-09-15,1995-04-28
-5ovv,2018-03-07,2017-08-29
-4ovw,1998-04-08,1997-10-06
-3ovm,2011-05-25,2010-09-16
-1ova,1992-04-15,1990-11-26
-4ovy,2014-02-05,2014-01-24
-2ov2,2007-03-13,2007-02-12
-3ove,2011-11-02,2010-09-16
-2ovx,2007-06-19,2007-02-15
-1ove,2003-09-02,2003-03-26
-6ovh,2020-01-29,2019-05-07
-2ovl,2007-03-20,2007-02-14
-4ovt,2014-01-08,2013-12-14
-3ovp,2011-03-09,2010-09-16
-2ovf,2007-02-27,2007-02-13
-3ovx,2010-12-22,2010-09-17
-4ovg,2014-03-05,2014-02-21
-3ovv,2011-09-21,2010-09-17
-8ovo,2023-05-17,2023-04-26
-6ov7,2019-11-20,2019-05-07
-4ov7,2014-10-29,2014-02-20
-7ovj,2022-07-20,2021-06-15
-7ovo,2022-06-22,2021-06-15
-5ovp,2018-03-07,2017-08-29
-7ovu,2022-12-21,2021-06-15
-3ov0,2010-12-29,2010-09-15
-1ovg,2004-02-17,2003-03-26
-6ovx,2019-11-27,2019-05-08
-6ov6,2020-08-05,2019-05-07
-2ovr,2007-04-24,2007-02-14
-5ovz,2018-10-10,2017-08-30
-4ovf,2014-03-05,2014-02-21
-7ov6,,2021-06-14
-4ove,2015-02-25,2014-02-21
-3ovw,1998-04-08,1997-10-06
-1ov6,2004-02-17,2003-03-25
-5ov6,2017-09-06,2017-08-28
-4ovn,2014-12-03,2013-12-10
-1ovb,1994-01-31,1992-10-05
-2ovz,2007-06-19,2007-02-15
-1ovl,2003-06-03,2003-03-26
-5ovr,2017-11-22,2017-08-29
-3ov4,2011-10-26,2010-09-15
-6ovr,2019-07-24,2019-05-08
-3ovl,2011-07-06,2010-09-16
-6ove,2020-05-13,2019-05-07
-4ovz,2014-04-23,2014-01-28
-8ovf,2024-05-08,2023-04-26
-4ov9,2014-08-20,2014-02-20
-2ovh,2007-03-20,2007-02-13
-4ovp,2014-01-08,2013-12-11
-5ovc,2018-03-07,2017-08-28
-8ovv,2024-04-24,2023-04-26
-4ov2,2014-03-26,2014-02-19
-5h9s,2016-06-29,2015-12-29
-6h9r,2019-03-13,2018-08-05
-2h9p,2006-08-01,2006-06-10
-8h9u,2023-05-31,2022-10-25
-8h9c,2023-02-08,2022-10-25
-5h9l,2016-05-11,2015-12-28
-6h92,2020-08-26,2018-08-03
-2h9k,2007-04-10,2006-06-10
-8h99,2023-02-08,2022-10-25
-3h9f,2009-05-19,2009-04-30
-4h98,2013-03-27,2012-09-24
-8h9a,2023-02-08,2022-10-25
-4h9x,2012-11-07,2012-09-25
-6h9s,2018-08-22,2018-08-06
-1h9n,1997-09-17,1997-05-29
-7h99,2024-05-29,2024-04-26
-8h9o,2023-07-26,2022-10-25
-1h9u,2002-04-03,2001-03-21
-1h97,2001-06-21,2001-03-02
-3h9v,2009-07-28,2009-04-30
-1h9q,1997-09-17,1997-05-29
-4h9l,2013-01-23,2012-09-24
-7h91,2024-05-29,2024-04-26
-2h9f,2006-08-08,2006-06-09
-1h93,2001-05-03,2001-02-23
-6h9h,2018-09-26,2018-08-04
-5h9f,2016-02-17,2015-12-28
-7h9e,2024-05-29,2024-04-26
-7h9b,2024-05-29,2024-04-26
-8h9i,2023-05-31,2022-10-25
-5h9e,2016-02-17,2015-12-28
-3h9a,2010-03-02,2009-04-30
-3h9q,2009-06-16,2009-04-30
-7h9f,2024-05-29,2024-04-26
-2h9y,2006-07-18,2006-06-12
-3h9d,2009-10-06,2009-04-30
-5h9o,2016-07-27,2015-12-29
-6h9y,2019-06-12,2018-08-06
-5h9w,2016-03-16,2015-12-29
-8h9p,2023-05-31,2022-10-25
-1h96,2001-03-06,2001-02-28
-2h9v,2006-12-05,2006-06-12
-3h9g,2009-06-16,2009-04-30
-2h94,2006-07-04,2006-06-08
-1h9o,2001-03-19,2001-03-14
-6h9q,2019-08-14,2018-08-05
-5h9p,2016-06-29,2015-12-29
-2h9n,2006-08-01,2006-06-10
-2h9h,2006-08-08,2006-06-09
-5h9y,2017-02-15,2015-12-29
-8h9h,2023-04-26,2022-10-25
-2h92,2006-08-08,2006-06-08
-3h98,2009-10-13,2009-04-30
-7h90,2024-05-29,2024-04-26
-2h90,2006-08-29,2006-06-08
-6h98,2019-06-12,2018-08-03
-4h9v,2012-11-07,2012-09-25
-1h9x,2001-08-09,2001-03-23
-7h92,2024-05-29,2024-04-26
-4h9d,2012-10-10,2012-09-24
-7h93,2024-05-29,2024-04-26
-7h9j,2024-05-29,2024-04-26
-3h9y,2009-09-08,2009-04-30
-3h99,2009-12-08,2009-04-30
-6h9t,2019-08-21,2018-08-06
-5h9v,2016-03-16,2015-12-29
-3h97,2009-12-08,2009-04-30
-3h9h,2010-01-12,2009-04-30
-4h9g,2013-09-11,2012-09-24
-7h96,2024-05-29,2024-04-26
-6h9e,2019-08-14,2018-08-03
-1h9p,2001-03-23,2001-03-16
-7h9g,2024-05-29,2024-04-26
-6h99,2019-06-12,2018-08-03
-6h9b,2018-12-19,2018-08-03
-1h9t,2001-04-04,2001-03-19
-4h9t,2012-11-07,2012-09-24
-8h9s,2023-05-31,2022-10-25
-8h9l,2023-05-31,2022-10-25
-2h9e,2007-02-13,2006-06-09
-6h9u,2019-02-06,2018-08-06
-1h9h,2004-07-26,2001-03-12
-3h9u,2009-09-29,2009-04-30
-2h96,2006-07-25,2006-06-09
-3h9e,2009-05-26,2009-04-30
-2h9a,2006-09-26,2006-06-09
-6h9i,2018-09-26,2018-08-04
-6h9f,2019-08-14,2018-08-03
-2h9i,2007-01-30,2006-06-09
-4h9u,2012-11-07,2012-09-25
-4h99,2013-01-23,2012-09-24
-6h9j,2019-08-14,2018-08-04
-3h9o,2009-08-25,2009-04-30
-1h9r,2001-06-19,2001-03-19
-2h9m,2006-08-01,2006-06-10
-4h9z,2012-11-07,2012-09-25
-6h93,2020-08-26,2018-08-03
-8h9b,2023-02-08,2022-10-25
-7h97,2024-05-29,2024-04-26
-5h9r,2016-06-29,2015-12-29
-3h9r,2009-06-02,2009-04-30
-3h9k,2010-05-12,2009-04-30
-3h90,2009-09-08,2009-04-29
-8h92,2024-01-03,2022-10-24
-6h94,2020-08-26,2018-08-03
-5h9q,2016-06-29,2015-12-29
-8h9w,2023-07-26,2022-10-25
-7h98,2024-05-29,2024-04-26
-8h9d,2023-02-08,2022-10-25
-1h9l,2001-11-27,2001-03-13
-5h9i,2016-04-27,2015-12-28
-5h92,2016-04-13,2015-12-25
-6h9a,2019-06-12,2018-08-03
-5h9b,2017-01-11,2015-12-27
-3h9z,2009-09-08,2009-04-30
-8h9z,2023-11-01,2022-10-26
-7h9d,2024-05-29,2024-04-26
-8h9t,2023-05-31,2022-10-25
-4h97,2013-03-27,2012-09-24
-6h9v,2019-04-03,2018-08-06
-4h96,2013-03-27,2012-09-24
-7h94,2024-05-29,2024-04-26
-6h91,2020-08-26,2018-08-03
-1h9w,2001-03-23,2001-03-22
-8h9v,2023-05-31,2022-10-25
-8h9y,2023-07-26,2022-10-25
-8h97,2023-02-22,2022-10-25
-1h9z,2001-06-20,2001-03-23
-1h94,2001-05-03,2001-02-23
-8h9x,2023-07-26,2022-10-25
-5h94,2016-05-18,2015-12-25
-6h9x,2019-05-15,2018-08-06
-7h95,2024-05-29,2024-04-26
-3h9c,2009-12-08,2009-04-30
-3h9b,2009-12-08,2009-04-30
-6h9p,2019-08-14,2018-08-05
-4h9k,2013-10-30,2012-09-24
-7h9i,2024-05-29,2024-04-26
-1h9g,2001-03-09,2001-03-09
-6h96,2018-11-21,2018-08-03
-3h91,2009-08-18,2009-04-29
-7h9h,2024-05-29,2024-04-26
-4h95,2013-03-27,2012-09-24
-8h98,2023-02-08,2022-10-25
-5h9m,2016-02-17,2015-12-28
-3h9j,2009-06-16,2009-04-30
-7h9a,2024-05-29,2024-04-26
-1h9i,2004-07-26,2001-03-12
-2h9t,2007-05-22,2006-06-11
-1h9a,2001-05-03,2001-03-06
-4h9y,2012-11-07,2012-09-25
-6h90,2020-08-26,2018-08-03
-2h9d,2006-08-15,2006-06-09
-2h9j,2007-04-10,2006-06-10
-3h94,2009-08-18,2009-04-30
-3h9s,2010-01-12,2009-04-30
-4h9m,2012-10-24,2012-09-24
-8h9e,2023-05-31,2022-10-25
-1h9y,2001-08-09,2001-03-23
-3ai9,2011-03-30,2010-05-11
-2aii,2005-12-13,2005-07-29
-4aic,2012-02-22,2012-02-09
-1aid,1997-10-15,1997-04-16
-2aiq,2005-09-06,2005-07-30
-7aiu,2021-10-06,2020-09-28
-8aig,2023-03-22,2022-07-26
-5aiu,2015-07-08,2015-02-17
-8ai1,2024-01-10,2022-07-25
-4aiz,2013-03-06,2012-02-15
-6aip,2019-03-20,2018-08-24
-5ai6,2015-05-13,2015-02-12
-7aih,2021-04-28,2020-09-27
-7aiq,2021-06-02,2020-09-28
-6ai9,2019-03-20,2018-08-22
-6aiy,2018-10-17,2018-08-25
-3aiw,2011-02-23,2010-05-18
-5ai3,2016-03-02,2015-02-11
-4aig,1998-11-11,1997-10-16
-1ai9,1997-11-12,1997-05-01
-6aic,2018-11-21,2018-08-22
-1ai8,1997-10-15,1997-05-01
-1ai6,1997-11-12,1997-05-01
-4ail,2012-03-07,2012-02-10
-6aix,2018-10-17,2018-08-25
-6ai5,2019-09-11,2018-08-21
-1aii,1997-03-12,1996-11-28
-3aic,2011-03-23,2010-05-12
-1ai4,1997-11-12,1997-05-01
-8ai2,2024-01-10,2022-07-25
-4ain,2012-06-06,2012-02-10
-7aii,2021-01-13,2020-09-27
-6ait,2018-12-26,2018-08-24
-5ai8,2015-05-13,2015-02-12
-7aif,2021-01-13,2020-09-27
-8aiv,2023-08-16,2022-07-27
-4aim,2012-04-18,2012-02-10
-3aie,2011-03-23,2010-05-12
-8aii,2023-08-16,2022-07-26
-7aip,2021-06-02,2020-09-28
-8aiu,2023-08-16,2022-07-27
-5ais,2015-06-03,2015-02-17
-7ai7,2021-03-31,2020-09-26
-6aif,2018-09-05,2018-08-23
-3aib,2011-03-23,2010-05-12
-3ais,2011-03-16,2010-05-18
-4ai8,2012-10-03,2012-02-08
-5aij,2015-10-07,2015-02-13
-1aiy,1997-11-12,1997-04-30
-7ai0,2021-01-20,2020-09-25
-6ai6,2018-10-31,2018-08-21
-8aiz,2023-08-16,2022-07-27
-7ai5,2021-03-31,2020-09-26
-5aik,2015-02-25,2015-02-15
-7ait,2021-10-06,2020-09-28
-2aid,1997-10-15,1997-04-17
-2aix,2005-08-09,2005-08-01
-5ai5,2015-05-13,2015-02-12
-3air,2011-03-16,2010-05-18
-4aii,2012-06-13,2012-02-10
-7ai8,2021-09-01,2020-09-26
-2aib,2006-01-17,2005-07-29
-3aih,2010-12-22,2010-05-14
-5aib,2015-05-13,2015-02-12
-8aib,2023-05-31,2022-07-26
-4air,2012-02-29,2012-02-13
-4aid,2012-04-18,2012-02-09
-3aiq,2011-02-23,2010-05-18
-2aig,1998-04-15,1997-10-12
-7aix,2021-10-06,2020-09-28
-2ai1,2005-10-25,2005-07-28
-5ai1,2015-05-20,2015-02-11
-4ai6,2012-03-14,2012-02-08
-7air,2021-06-02,2020-09-28
-2ai8,2005-09-06,2005-07-29
-8aio,2022-12-14,2022-07-26
-8aic,2023-02-22,2022-07-26
-8aie,2022-11-16,2022-07-26
-3ai2,2011-02-09,2010-05-07
-1ai7,1997-11-12,1997-05-01
-4ais,2012-06-20,2012-02-13
-4aip,2013-01-23,2012-02-11
-4ai2,2012-10-03,2012-02-07
-1aia,1994-10-15,1994-05-10
-5aiv,2015-06-03,2015-02-17
-5aig,2015-06-17,2015-02-13
-4ai1,2012-10-03,2012-02-07
-4ai0,2012-10-03,2012-02-07
-2ai9,2005-09-06,2005-07-29
-4aiu,2012-06-20,2012-02-13
-7ail,2021-10-06,2020-09-27
-8ai8,2023-05-31,2022-07-25
-1ai5,1997-11-12,1997-05-01
-2ai2,2005-10-25,2005-07-28
-7aio,2021-06-02,2020-09-28
-2aiz,2006-03-14,2005-08-01
-2air,2006-01-24,2005-07-30
-5aii,2015-06-17,2015-02-13
-7ai9,2021-09-01,2020-09-26
-8aiq,2023-08-16,2022-07-27
-6aii,2019-08-28,2018-08-23
-7aiv,2021-10-06,2020-09-28
-8aij,2022-11-02,2022-07-26
-2ai5,2006-05-23,2005-07-29
-2ai7,2005-09-06,2005-07-29
-6aim,2019-03-20,2018-08-24
-5ait,2015-07-08,2015-02-17
-5aia,2015-05-13,2015-02-12
-5ai2,2016-03-02,2015-02-11
-2ain,2006-07-18,2005-07-30
-7aiw,2021-10-06,2020-09-28
-6aik,2019-03-20,2018-08-24
-7aij,2021-01-13,2020-09-27
-5aic,2015-05-13,2015-02-12
-2aij,2005-12-13,2005-07-29
-2ai3,2005-10-25,2005-07-28
-8ai7,2023-02-01,2022-07-25
-3ai8,2011-05-18,2010-05-11
-6ai7,2019-08-28,2018-08-21
-8aip,2023-08-16,2022-07-27
-7aik,2021-11-03,2020-09-27
-7aic,2021-03-31,2020-09-26
-4aie,2012-08-29,2012-02-09
-3ai3,2011-02-09,2010-05-07
-3aiv,2011-02-23,2010-05-18
-6ai0,2019-03-20,2018-08-21
-8aiy,2022-11-02,2022-07-27
-8ai5,2024-01-10,2022-07-25
-3aii,2010-08-04,2010-05-14
-1aim,1997-10-22,1997-04-21
-1aig,1997-10-22,1997-04-17
-5ain,2015-03-25,2015-02-16
-1aic,1994-10-15,1994-05-10
-2aiu,2006-07-18,2005-08-01
-2aia,2005-09-06,2005-07-29
-7aiy,2021-10-06,2020-09-28
-3aid,1997-09-17,1997-05-15
-5aix,2015-06-03,2015-02-18
-7aid,2021-01-13,2020-09-26
-4ai9,2012-10-03,2012-02-08
-7ai1,2021-01-20,2020-09-25
-4aio,2012-08-15,2012-02-11
-1aiv,1998-04-29,1997-04-28
-1aiq,1997-11-12,1997-04-23
-1aib,1994-10-15,1994-05-10
-5ai0,2015-05-13,2015-02-11
-6aij,2018-10-10,2018-08-24
-6aid,2019-02-27,2018-08-22
-3aia,2011-03-30,2010-05-11
-5aip,2016-03-02,2015-02-16
-2aik,2005-12-13,2005-07-29
-7ai6,2021-03-31,2020-09-26
-7aie,2021-10-06,2020-09-27
-7aib,2021-03-31,2020-09-26
-1aij,1997-10-22,1997-04-18
-5aie,2015-04-29,2015-02-12
-7aig,2021-01-13,2020-09-27
-1ai2,1997-10-15,1997-04-30
-3ai7,2010-09-15,2010-05-10
-5ai9,2015-05-13,2015-02-12
-2aio,2005-10-11,2005-07-30
-7ais,2021-10-06,2020-09-28
-1aih,1997-08-20,1997-04-17
-4aif,2013-01-23,2012-02-09
-2aie,2005-09-06,2005-07-29
-4aiq,2013-01-23,2012-02-11
-8ai4,2024-01-10,2022-07-25
-8ai9,2023-05-31,2022-07-25
-2aim,1997-10-22,1997-04-21
-5ai4,2015-05-13,2015-02-12
-4ai3,2012-10-03,2012-02-07
-6ain,2018-10-31,2018-08-24
-2aip,2005-09-06,2005-07-30
-1aiz,1994-01-31,1993-11-11
-8ai0,2023-09-20,2022-07-25
-3ai0,2010-08-18,2010-05-06
-1aix,1997-10-15,1997-04-30
-4ai4,2012-02-15,2012-02-08
-1ai3,1997-11-12,1997-04-30
-4ai7,2012-02-22,2012-02-08
-4aia,2012-02-22,2012-02-08
-8ai6,2024-01-10,2022-07-25
-4ai5,2012-02-15,2012-02-08
-7ain,2021-06-02,2020-09-28
-1ai0,1997-11-12,1997-04-30
-8ai3,2024-01-10,2022-07-25
-2hca,2006-06-27,2006-06-15
-8hc4,2023-01-25,2022-11-01
-2hco,1979-08-26,1979-08-07
-1hca,1992-10-15,1992-04-02
-3hc4,2009-08-04,2009-05-05
-5hci,2016-01-20,2016-01-04
-5hch,2016-03-02,2016-01-04
-5hc8,2016-03-02,2016-01-04
-2hc0,2007-06-26,2006-06-14
-2hcn,2007-02-06,2006-06-17
-8hc0,2023-09-13,2022-11-01
-6hcs,2018-12-05,2018-08-16
-5hco,2017-01-11,2016-01-04
-2hc4,2007-05-01,2006-06-15
-6hcn,2019-02-13,2018-08-15
-6hcv,2019-04-03,2018-08-16
-6hck,2019-02-13,2018-08-15
-3hcn,2009-11-10,2009-05-06
-1hcs,1995-09-15,1994-09-02
-3hci,2009-10-13,2009-05-06
-2hcz,2006-08-22,2006-06-19
-4hcf,2012-10-17,2012-09-29
-4hcv,2012-11-14,2012-10-01
-2hcm,2006-08-15,2006-06-17
-5hca,2016-08-31,2016-01-04
-5hcn,2016-01-13,2016-01-04
-3hco,2009-11-10,2009-05-06
-8hce,2023-11-08,2022-11-01
-5hcd,2016-03-30,2016-01-04
-2hcd,2007-05-01,2006-06-16
-3hc1,2009-06-02,2009-05-05
-3hcb,2009-08-25,2009-05-06
-5hct,2016-07-20,2016-01-04
-8hc9,2023-01-25,2022-11-01
-3hc3,2009-08-04,2009-05-05
-6hc9,2019-04-03,2018-08-14
-1hcz,1997-03-12,1996-09-18
-6hcb,2019-04-03,2018-08-14
-5hc2,2017-01-18,2016-01-04
-6hco,2018-11-07,2018-08-15
-3hc6,2009-07-21,2009-05-05
-1hck,1996-12-07,1996-06-03
-2hcs,2007-02-06,2006-06-18
-2hc2,2006-06-27,2006-06-15
-5hc7,2016-03-02,2016-01-04
-1hcn,1994-09-30,1994-07-01
-5hcq,2016-04-06,2016-01-04
-8hcg,2023-11-08,2022-11-01
-3hcm,2010-02-02,2009-05-06
-1hc7,2001-06-18,2001-04-26
-6hcq,2018-10-17,2018-08-16
-2hc9,2006-08-15,2006-06-15
-6hc8,2019-08-28,2018-08-14
-6hct,2018-10-31,2018-08-16
-4hcq,2013-03-13,2012-10-01
-8hcj,2023-11-15,2022-11-01
-8hcr,2023-05-03,2022-11-02
-2hcj,2006-10-31,2006-06-16
-4hcl,2012-10-24,2012-09-30
-1hcu,2001-10-18,2001-05-09
-1hcm,2001-08-09,2001-05-05
-8hcd,2023-11-08,2022-11-01
-1hc9,2001-11-10,2001-05-02
-3hcj,2009-10-13,2009-05-06
-1hct,1995-09-15,1994-09-02
-8hca,2023-01-25,2022-11-01
-3hc5,2009-07-21,2009-05-05
-6hc7,2019-08-28,2018-08-14
-1hcy,1994-01-31,1991-05-15
-2hcr,2006-10-24,2006-06-18
-5hc0,2017-01-18,2016-01-04
-6hcj,2018-10-17,2018-08-15
-3hcr,2009-11-10,2009-05-06
-5hcl,2017-01-25,2016-01-04
-8hc5,2023-01-25,2022-11-01
-1hc1,1994-01-31,1991-05-15
-1hcb,1994-04-30,1994-01-07
-8hcf,2023-11-08,2022-11-01
-6hcz,2020-03-18,2018-08-17
-8hct,2023-03-29,2022-11-03
-4hc7,2012-12-05,2012-09-28
-4hc4,2012-10-17,2012-09-28
-4hcz,2012-11-14,2012-10-01
-5hcz,2016-09-07,2016-01-04
-3hcv,2009-06-09,2009-05-06
-4hcj,2012-10-24,2012-09-30
-1hcq,1995-11-23,1995-01-04
-3hcs,2009-05-26,2009-05-06
-3hch,2009-10-13,2009-05-06
-4hca,2012-12-05,2012-09-28
-5hce,2016-03-30,2016-01-04
-5hcr,2016-04-06,2016-01-04
-8hc7,2023-01-25,2022-11-01
-6hcc,2019-04-03,2018-08-14
-8hc6,2023-01-25,2022-11-01
-5hcv,2016-03-09,2016-01-04
-6hca,2019-04-03,2018-08-14
-3hcc,2009-08-25,2009-05-06
-6hcw,2019-04-03,2018-08-16
-3hct,2009-05-26,2009-05-06
-8hc8,2023-01-25,2022-11-01
-5hcc,2016-03-30,2016-01-04
-4hch,2012-10-24,2012-09-29
-6hch,2019-04-03,2018-08-15
-6hcy,2018-10-24,2018-08-17
-4hcu,2012-11-14,2012-10-01
-6hce,2018-08-29,2018-08-14
-8hck,2023-11-08,2022-11-01
-3hcd,2009-08-25,2009-05-06
-6hcf,2018-10-17,2018-08-14
-5hcj,2016-04-13,2016-01-04
-4hcd,2013-10-30,2012-09-29
-6hcm,2018-10-17,2018-08-15
-4hct,2012-11-14,2012-10-01
-4hcc,2013-10-09,2012-09-29
-2hcb,2006-07-25,2006-06-15
-2hch,2007-05-01,2006-06-16
-4hco,2012-10-10,2012-10-01
-8hcb,2023-01-25,2022-11-01
-3hca,2009-08-25,2009-05-06
-8hc3,2023-01-25,2022-11-01
-5hcp,2016-04-06,2016-01-04
-2hck,1997-08-20,1997-02-25
-3hc2,2010-06-16,2009-05-05
-5hc9,2016-04-27,2016-01-04
-4hc3,2012-10-31,2012-09-28
-2hct,2006-08-22,2006-06-18
-5hcx,2016-09-07,2016-01-04
-4hcy,2013-10-02,2012-10-01
-4hcg,2012-10-17,2012-09-29
-6hcx,2018-08-29,2018-08-16
-1hco,1979-08-26,1979-08-07
-6hcu,2019-04-03,2018-08-16
-4hcx,2013-02-27,2012-10-01
-4hc6,2012-11-28,2012-09-28
-5hcy,2016-09-07,2016-01-04
-4hc9,2012-12-05,2012-09-28
-8hc2,2023-01-25,2022-11-01
-8hcc,2023-11-08,2022-11-01
-2hcg,2007-03-27,2006-06-16
-2hcf,2006-08-15,2006-06-16
-3hcf,2009-08-25,2009-05-06
-3hc9,2009-12-29,2009-05-05
-3hc8,2009-07-07,2009-05-05
-3hcu,2009-05-26,2009-05-06
-1hcp,1995-11-23,1993-11-23
-6hc6,2019-08-28,2018-08-14
-2hcv,2006-12-19,2006-06-19
-5hcf,2016-08-31,2016-01-04
-3hcp,2009-11-10,2009-05-06
-3hce,2009-08-25,2009-05-06
-5hcb,2016-08-31,2016-01-04
-1hch,2002-07-19,2001-05-04
-1hcx,2001-11-29,2001-05-10
-8hch,2023-11-08,2022-11-01
-4hc1,2013-01-23,2012-09-28
-5k8r,2016-08-24,2016-05-30
-7k8t,2020-10-21,2020-09-27
-1k8i,2001-12-05,2001-10-24
-6k82,2020-06-24,2019-06-11
-7k81,2020-12-09,2020-09-24
-3k88,2009-11-10,2009-10-13
-3k8b,2009-12-22,2009-10-14
-5k8t,2016-11-09,2016-05-31
-7k8z,2020-10-21,2020-09-27
-1k8q,2002-03-06,2001-10-25
-6k88,2020-06-24,2019-06-11
-7k80,2020-12-09,2020-09-24
-8k8e,2024-01-31,2023-07-29
-5k8x,2017-06-21,2016-05-31
-6k8a,2020-06-24,2019-06-11
-1k8r,2002-03-13,2001-10-25
-4k89,2014-05-21,2013-04-18
-1k81,2002-04-24,2001-10-22
-5k8w,2017-06-21,2016-05-31
-5k8z,2017-06-21,2016-05-31
-5k8d,2017-06-14,2016-05-29
-7k8m,2020-10-21,2020-09-27
-3k8m,2010-03-02,2009-10-14
-3k8d,2009-11-10,2009-10-14
-5k81,2016-08-10,2016-05-27
-4k8x,2013-06-26,2013-04-19
-1k8z,2002-06-19,2001-10-26
-4k8b,2014-03-26,2013-04-18
-7k8e,2021-09-22,2020-09-26
-5k8i,2016-11-09,2016-05-30
-6k85,2020-06-24,2019-06-11
-6k8t,2020-03-18,2019-06-13
-7k89,2021-06-02,2020-09-26
-7k88,2021-06-02,2020-09-26
-1k8a,2002-07-19,2001-10-23
-7k8w,2020-10-21,2020-09-27
-5k8u,2016-11-09,2016-05-31
-4k8e,2013-10-09,2013-04-18
-4k87,2013-10-09,2013-04-18
-3k8o,2010-03-02,2009-10-14
-1k8y,2002-06-19,2001-10-26
-6k83,2020-06-24,2019-06-11
-1k8x,2002-12-18,2001-10-26
-1k82,2002-06-14,2001-10-22
-5k8k,2016-08-10,2016-05-30
-1k8c,2002-07-05,2001-10-23
-8k8j,2024-02-14,2023-07-30
-4k8c,2013-05-01,2013-04-18
-2k8d,2008-12-16,2008-09-05
-7k8s,2020-10-21,2020-09-27
-3k8y,2010-03-02,2009-10-15
-6k8k,2020-05-13,2019-06-12
-1k8t,2002-01-23,2001-10-25
-6k8o,2020-06-24,2019-06-13
-6k8z,2020-03-25,2019-06-13
-5k82,2016-08-10,2016-05-27
-5k8s,2016-10-12,2016-05-31
-8k8u,2024-06-05,2023-07-31
-5k8l,2016-11-09,2016-05-30
-5k85,2016-08-17,2016-05-27
-3k8s,2009-11-03,2009-10-14
-6k8d,2020-06-17,2019-06-11
-6k8i,2020-05-13,2019-06-12
-4k8h,2013-10-09,2013-04-18
-5k8p,2016-10-05,2016-05-30
-7k8k,2021-09-22,2020-09-27
-4k8y,2014-04-23,2013-04-19
-4k81,2013-09-04,2013-04-17
-5k8g,2017-09-06,2016-05-30
-6k89,2020-06-24,2019-06-11
-6k8b,2020-06-24,2019-06-11
-7k8u,2020-10-21,2020-09-27
-3k8l,2010-03-02,2009-10-14
-8k8s,2024-06-05,2023-07-31
-4k8o,2014-09-03,2013-04-18
-5k8e,2016-09-21,2016-05-30
-3k8q,2010-03-02,2009-10-14
-7k8y,2020-10-21,2020-09-27
-5k84,2017-06-07,2016-05-27
-6k8h,2019-10-09,2019-06-12
-7k8f,2021-09-22,2020-09-26
-5k83,2016-08-10,2016-05-27
-3k87,2009-11-10,2009-10-13
-7k8g,2021-06-02,2020-09-27
-6k80,2020-06-17,2019-06-11
-6k8u,2020-03-18,2019-06-13
-1k8d,2001-12-19,2001-10-23
-3k83,2009-12-01,2009-10-13
-6k8p,2019-11-13,2019-06-13
-1k8g,2001-12-20,2001-10-24
-6k8w,2020-03-18,2019-06-13
-4k8k,2013-05-01,2013-04-18
-5k8y,2016-12-07,2016-05-31
-7k84,2020-10-14,2020-09-25
-4k8p,2013-05-01,2013-04-18
-7k8x,2020-10-21,2020-09-27
-3k8k,2010-03-02,2009-10-14
-4k86,2013-10-09,2013-04-18
-3k8t,2010-03-02,2009-10-14
-5k8b,2016-06-15,2016-05-28
-5k89,2017-04-12,2016-05-27
-4k8g,2013-05-22,2013-04-18
-5k8c,2016-06-15,2016-05-28
-5k8q,2016-08-24,2016-05-30
-5k8f,2016-07-13,2016-05-30
-6k8n,2020-06-24,2019-06-13
-5k8v,2016-11-09,2016-05-31
-4k8a,2013-09-11,2013-04-18
-4k8s,2013-07-10,2013-04-18
-4k8f,2013-06-05,2013-04-18
-3k8c,2010-10-27,2009-10-14
-5k8n,2016-10-05,2016-05-30
-4k8t,2013-05-01,2013-04-18
-4k88,2013-10-09,2013-04-18
-5k8o,2016-10-05,2016-05-30
-4k8v,2013-05-15,2013-04-18
-6k86,2020-06-24,2019-06-11
-7k8v,2020-10-21,2020-09-27
-3k8x,2009-12-01,2009-10-15
-7k8h,2021-09-22,2020-09-27
-1k83,2002-02-13,2001-10-22
-6k8g,2020-06-17,2019-06-11
-7k87,2021-09-29,2020-09-25
-7ky7,2021-01-06,2020-12-07
-1kyo,2002-03-06,2002-02-05
-5ky0,2017-05-17,2016-07-20
-4ky6,2013-06-12,2013-05-28
-1kyt,2003-01-21,2002-02-05
-2kyu,2010-08-25,2010-06-08
-6kyl,2019-10-02,2019-09-19
-1kya,2002-06-19,2002-02-04
-4ky5,2013-06-12,2013-05-28
-7ky6,2021-01-06,2020-12-07
-1ky4,2002-09-25,2002-02-03
-6ky9,2019-11-13,2019-09-17
-7kye,2020-12-16,2020-12-07
-6ky4,2019-10-16,2019-09-16
-7kyl,2021-04-07,2020-12-08
-4kyw,2014-06-04,2013-05-29
-7kyu,2020-12-16,2020-12-08
-4ky4,2014-08-06,2013-05-28
-7kyh,2021-04-14,2020-12-07
-7kyd,2022-01-05,2020-12-07
-3ky9,2010-02-23,2009-12-04
-1kyj,2002-02-20,2002-02-04
-6kye,2020-01-01,2019-09-18
-6kyu,2020-09-23,2019-09-20
-6kyy,2020-02-05,2019-09-20
-1ky3,2002-06-05,2002-02-02
-6kya,2020-05-27,2019-09-17
-6kyw,2020-09-16,2019-09-20
-5ky7,2017-05-17,2016-07-21
-1kyz,2002-08-28,2002-02-06
-1kyy,2002-07-24,2002-02-06
-5kyw,2016-09-07,2016-07-22
-5ky4,2017-05-17,2016-07-21
-3kyd,2010-02-16,2009-12-05
-5kyv,2016-12-21,2016-07-22
-4kya,2014-08-06,2013-05-28
-7ky8,2021-01-06,2020-12-07
-5kyt,2016-12-21,2016-07-22
-1kyw,2002-08-28,2002-02-06
-5ky8,2017-05-17,2016-07-21
-7ky2,2021-04-14,2020-12-07
-1ky6,2002-06-12,2002-02-03
-3kyr,2010-12-29,2009-12-07
-7kyv,2021-05-19,2020-12-08
-4ky2,2013-08-28,2013-05-28
-5ky3,2017-05-17,2016-07-21
-7kya,2021-01-06,2020-12-07
-1kyf,2002-06-12,2002-02-04
-4kyt,2013-09-04,2013-05-29
-7kyf,2021-04-14,2020-12-07
-4kyv,2013-07-24,2013-05-29
-6ky7,2019-10-16,2019-09-16
-5ky2,2017-05-17,2016-07-20
-1kyq,2002-05-08,2002-02-05
-3kyj,2010-02-16,2009-12-06
-4ky7,2013-06-12,2013-05-28
-7kyy,2021-05-19,2020-12-09
-7kyk,2021-05-19,2020-12-08
-3kyv,2010-04-28,2009-12-07
-7kyp,2021-08-25,2020-12-08
-5ky5,2017-05-17,2016-07-21
-3kyu,2010-04-28,2009-12-07
-3kyn,2010-02-23,2009-12-06
-3kyf,2010-04-14,2009-12-06
-6kyh,2019-12-04,2019-09-18
-6kyk,2019-12-04,2019-09-19
-7kyc,2021-01-06,2020-12-07
-6kyf,2020-09-23,2019-09-18
-7kyr,2021-02-03,2020-12-08
-4ky8,2013-08-21,2013-05-28
-5kyi,2016-08-03,2016-07-21
-4kyr,2013-07-24,2013-05-29
-5kya,2016-09-21,2016-07-21
-6ky6,2019-10-02,2019-09-16
-3kyb,2010-12-15,2009-12-05
-7kyt,2021-12-22,2020-12-08
-3kyc,2010-02-16,2009-12-05
-3kyt,2010-03-16,2009-12-07
-3kyx,2010-04-28,2009-12-07
-7ky9,2021-01-06,2020-12-07
-1ky2,2002-06-05,2002-02-02
-4kyk,2013-08-07,2013-05-29
-4kye,2013-09-25,2013-05-28
-4kyd,2013-09-25,2013-05-28
-7ky5,2021-01-06,2020-12-07
-1kyd,2002-06-12,2002-02-04
-3kyo,2010-02-23,2009-12-06
-6ky3,2020-09-16,2019-09-16
-6kyp,2020-11-11,2019-09-19
-1kyi,2002-05-15,2002-02-04
-4kyc,2013-09-25,2013-05-28
-5kyu,2016-09-14,2016-07-22
-5kyy,2016-09-07,2016-07-22
-5kyx,2016-09-07,2016-07-22
-1kyx,2002-07-24,2002-02-06
-4kys,2013-10-30,2013-05-29
-4kyh,2013-08-07,2013-05-29
-5ky1,2016-09-07,2016-07-20
-5kyo,2017-01-04,2016-07-22
-3kyl,2010-03-31,2009-12-06
-1kyr,2002-04-10,2002-02-05
-2kyf,2011-04-06,2010-05-25
-1kys,2002-04-10,2002-02-05
-3kyy,2010-04-28,2009-12-07
-6kyv,2020-09-23,2019-09-20
-5kyn,2016-09-07,2016-07-21
-3kya,2009-12-22,2009-12-04
-5ky9,2017-05-17,2016-07-21
-3kyg,2010-04-14,2009-12-06
-5kyj,2016-09-21,2016-07-21
-4kyi,2014-08-13,2013-05-29
-1kyp,2002-04-10,2002-02-05
-7ky0,2022-01-19,2020-12-06
-1ky7,2002-06-12,2002-02-03
-1kyn,2002-05-01,2002-02-05
-1kyv,2002-07-24,2002-02-06
-1ky5,2002-09-25,2002-02-03
-3kyq,2010-03-02,2009-12-07
-7kyb,2021-01-06,2020-12-07
-5kyk,2017-04-12,2016-07-21
-5kyl,2016-08-03,2016-07-21
-1ky8,2003-02-04,2002-02-04
-3kyw,2010-04-28,2009-12-07
-1kyu,2002-06-12,2002-02-05
-1kyc,2002-08-07,2002-02-04
-2c22,2005-11-29,2005-09-26
-6c23,2018-01-24,2018-01-05
-8c2e,2023-11-01,2022-12-22
-8c2o,2023-06-14,2022-12-22
-7c2m,2020-12-02,2020-05-08
-7c2g,2020-08-05,2020-05-07
-1c2f,2000-07-26,1999-07-21
-5c23,2015-07-29,2015-06-15
-8c23,2023-05-03,2022-12-21
-4c2g,2013-12-04,2013-08-17
-4c2c,2013-12-04,2013-08-17
-4c22,2013-12-11,2013-08-16
-8c29,2023-07-26,2022-12-21
-7c2c,2020-05-20,2020-05-07
-4c2r,2013-12-11,2013-08-19
-1c2r,1992-01-15,1991-03-19
-5c2n,2016-01-20,2015-06-16
-2c2k,2006-09-20,2005-09-29
-3c2t,2009-02-24,2008-01-25
-5c24,2015-07-29,2015-06-15
-2c2a,2005-11-21,2005-09-27
-5c27,2015-10-07,2015-06-15
-7c2v,2020-11-25,2020-05-09
-1c21,1999-11-17,1999-07-22
-4c2n,2013-12-11,2013-08-19
-3c2o,2008-03-25,2008-01-25
-5c2i,2015-12-16,2015-06-16
-7c2a,2020-05-20,2020-05-07
-2c2h,2005-10-13,2005-09-29
-5c2c,2015-12-16,2015-06-15
-5c2f,2015-10-21,2015-06-15
-6c24,2018-01-24,2018-01-06
-5c20,2016-06-01,2015-06-15
-2c26,2005-10-18,2005-09-26
-5c2l,2016-06-22,2015-06-16
-3c2s,2008-08-19,2008-01-25
-7c2f,2020-08-05,2020-05-07
-7c2o,2020-05-27,2020-05-08
-4c2z,2014-10-01,2013-08-20
-5c2k,2016-06-22,2015-06-16
-6c26,2018-01-31,2018-01-06
-6c2i,2018-02-21,2018-01-08
-8c2g,2023-06-14,2022-12-22
-2c29,2006-10-16,2005-09-27
-4c2q,2013-12-11,2013-08-19
-1c2e,2000-07-26,1999-07-22
-2c2z,2006-09-20,2005-10-02
-4c2y,2014-10-01,2013-08-20
-8c2d,2023-07-26,2022-12-22
-3c2m,2008-05-20,2008-01-25
-8c25,2023-05-31,2022-12-21
-8c2f,2023-11-01,2022-12-22
-7c29,2020-05-20,2020-05-07
-2c2u,2006-07-26,2005-09-30
-4c2o,2013-12-11,2013-08-19
-4c2w,2014-02-26,2013-08-20
-8c28,2024-01-10,2022-12-21
-3c2g,2008-05-20,2008-01-24
-3c25,2008-02-12,2008-01-24
-2c2r,2005-11-29,2005-09-29
-1c2t,2000-01-05,1999-07-26
-4c20,2013-12-11,2013-08-16
-1c2y,2000-07-30,1999-07-27
-4c2t,2013-10-30,2013-08-20
-1c2h,2000-07-26,1999-07-21
-6c2h,2018-04-25,2018-01-08
-1c2i,2000-07-26,1999-07-21
-5c2j,2016-06-22,2015-06-16
-6c2c,2019-01-16,2018-01-08
-6c28,2018-05-30,2018-01-07
-6c2z,2018-04-25,2018-01-09
-4c21,2013-12-11,2013-08-16
-5c2t,2015-08-05,2015-06-16
-7c2j,2020-05-27,2020-05-07
-3c2k,2008-05-20,2008-01-25
-6c2t,2019-01-23,2018-01-08
-3c22,2009-01-27,2008-01-24
-1c27,1999-11-17,1999-07-22
-2c25,2006-01-23,2005-09-26
-6c2m,2019-01-16,2018-01-08
-4c24,2013-12-11,2013-08-16
-2c27,2005-12-01,2005-09-26
-5c2o,2016-07-13,2015-06-16
-3c2f,2008-04-01,2008-01-24
-3c2r,2008-04-01,2008-01-25
-8c2r,2024-05-22,2022-12-22
-7c2x,2021-05-12,2020-05-09
-4c2l,2013-09-25,2013-08-19
-3c2l,2008-05-20,2008-01-25
-2c2j,2007-02-20,2005-09-29
-6c2x,2018-09-05,2018-01-09
-6c2n,2019-01-16,2018-01-08
-4c2a,2014-01-08,2013-08-16
-4c2p,2013-12-11,2013-08-19
-8c2y,2024-01-10,2022-12-23
-3c23,2008-05-06,2008-01-24
-4c2v,2014-02-26,2013-08-20
-5c22,2016-02-17,2015-06-15
-6c2d,2019-01-16,2018-01-08
-5c2v,2015-10-14,2015-06-16
-7c2l,2020-07-01,2020-05-08
-3c2q,2008-02-05,2008-01-25
-1c23,1999-11-17,1999-07-22
-5c2d,2015-10-21,2015-06-15
-1c2k,2000-07-26,1999-07-21
-1c2n,1999-03-23,1998-04-27
-4c2x,2014-10-01,2013-08-20
-6c2y,2018-04-25,2018-01-09
-5c2w,2015-10-14,2015-06-16
-6c2r,2019-01-23,2018-01-08
-5c25,2015-07-29,2015-06-15
-3c21,2008-05-06,2008-01-24
-2c2w,2005-12-19,2005-09-30
-5c2h,2015-10-07,2015-06-15
-2c2e,2005-11-29,2005-09-27
-6c2q,2018-04-25,2018-01-08
-2c20,2007-02-20,2005-09-22
-4c28,2014-09-03,2013-08-16
-7c23,2020-05-20,2020-05-07
-3c2c,1984-02-02,1983-11-03
-7c2h,2020-08-05,2020-05-07
-7c2d,2020-05-20,2020-05-07
-2c2b,2005-11-28,2005-09-27
-5c2e,2015-12-02,2015-06-15
-7c2w,2020-11-25,2020-05-09
-2c21,2006-02-01,2005-09-23
-8c2q,2023-10-25,2022-12-22
-6c2o,2019-01-16,2018-01-08
-1c2d,2000-07-26,1999-07-21
-7c2k,2020-06-03,2020-05-07
-8c2s,2023-12-20,2022-12-22
-4c2d,2013-12-04,2013-08-17
-2c2g,2005-11-28,2005-09-29
-7c2e,2020-08-26,2020-05-07
-4c2s,2013-09-11,2013-08-19
-7c2n,2020-12-02,2020-05-08
-1c29,2000-01-14,1999-07-23
-4c2u,2013-10-30,2013-08-20
-8c2z,2024-01-17,2022-12-23
-4c2f,2013-12-04,2013-08-17
-2c2c,1984-02-02,1983-11-03
-4c27,2014-09-03,2013-08-16
-4c29,2014-01-08,2013-08-16
-1c2g,2000-07-26,1999-07-21
-6c2w,2018-02-28,2018-01-09
-4c2j,2014-09-03,2013-08-19
-5c26,2015-10-07,2015-06-15
-3c27,2009-02-17,2008-01-24
-5c29,2015-09-30,2015-06-15
-3c20,2008-04-29,2008-01-24
-5c2y,2016-05-04,2015-06-16
-5c2g,2015-12-16,2015-06-15
-5c28,2015-09-30,2015-06-15
-3c2y,2009-02-03,2008-01-26
-1c2j,2000-07-26,1999-07-21
-1c2m,2000-07-26,1999-07-21
-2c2o,2006-09-20,2005-09-29
-1c2l,2000-07-26,1999-07-21
-3c2v,2008-04-01,2008-01-25
-1c22,1999-11-17,1999-07-22
-7c2z,2021-05-12,2020-05-10
-7c2b,2020-10-14,2020-05-07
-4c25,2013-12-18,2013-08-16
-5c2a,2015-09-30,2015-06-15
-8c2p,2023-04-26,2022-12-22
-1c24,1999-11-17,1999-07-22
-2c2m,2006-09-20,2005-09-29
-6c25,2018-03-14,2018-01-06
-2c28,2005-11-29,2005-09-26
-2c2f,2006-07-26,2005-09-28
-2c2n,2006-01-18,2005-09-29
-3c2w,2008-09-23,2008-01-25
-2c2l,2005-11-23,2005-09-29
-2c2d,2005-11-29,2005-09-27
-7c2i,2020-05-27,2020-05-07
-4c2m,2013-10-23,2013-08-19
-7u1r,2023-03-08,2022-02-22
-7u14,2022-03-23,2022-02-19
-1u1g,2005-07-05,2004-07-15
-4u1z,2014-08-20,2014-07-16
-6u1v,2019-12-18,2019-08-16
-8u1m,2024-03-13,2023-09-01
-6u10,2019-09-11,2019-08-15
-7u16,2022-03-23,2022-02-19
-7u15,2022-03-23,2022-02-19
-6u1d,2020-05-06,2019-08-15
-1u1j,2004-09-14,2004-07-15
-4u1o,2014-08-20,2014-07-15
-1u1f,2005-07-05,2004-07-15
-7u11,2022-03-23,2022-02-19
-4u1u,2014-07-30,2014-07-16
-1u1w,2004-11-02,2004-07-16
-5u13,2017-12-06,2016-11-27
-4u1m,2015-04-08,2014-07-15
-1u18,2005-07-26,2004-07-15
-4u1v,2014-07-30,2014-07-16
-8u1e,2023-09-27,2023-08-31
-4u1x,2014-08-20,2014-07-16
-7u18,2022-03-23,2022-02-20
-4u1k,2015-04-08,2014-07-15
-5u1y,2017-01-04,2016-11-29
-3u1l,2011-11-16,2011-09-30
-3u16,2012-10-03,2011-09-29
-6u1f,2020-05-06,2019-08-15
-4u1i,2015-04-08,2014-07-15
-5u11,2017-12-06,2016-11-27
-7u10,2022-03-23,2022-02-19
-4u1r,2015-06-03,2014-07-16
-7u1d,2022-06-01,2022-02-21
-1u1h,2004-09-02,2004-07-15
-3u13,2011-11-23,2011-09-29
-5u1o,2016-12-14,2016-11-28
-8u1c,2024-03-27,2023-08-31
-5u16,2017-02-15,2016-11-27
-4u14,2014-11-26,2014-07-15
-1u1b,2005-06-28,2004-07-15
-5u1w,2017-01-04,2016-11-29
-6u1g,2020-05-06,2019-08-15
-8u14,2024-01-17,2023-08-30
-4u1p,2015-07-29,2014-07-16
-3u1b,2011-11-30,2011-09-29
-3u1m,2011-11-16,2011-09-30
-7u1p,2022-07-06,2022-02-21
-1u10,2004-09-07,2004-07-14
-8u1d,2024-01-03,2023-08-31
-4u1w,2014-08-20,2014-07-16
-6u1a,2020-04-22,2019-08-15
-1u1x,2004-11-02,2004-07-16
-8u1g,2024-01-24,2023-08-31
-6u11,2020-02-19,2019-08-15
-6u18,2020-08-19,2019-08-15
-4u1n,2015-04-08,2014-07-15
-5u1p,2016-12-21,2016-11-28
-7u12,2022-03-23,2022-02-19
-3u1w,2012-01-25,2011-09-30
-5u1u,2017-01-11,2016-11-29
-5u14,2017-12-06,2016-11-27
-8u1x,2024-01-17,2023-09-04
-7u1u,2022-06-01,2022-02-22
-4u1q,2015-08-05,2014-07-16
-3u1r,2012-10-31,2011-09-30
-8u17,2023-12-27,2023-08-30
-6u1h,2020-05-06,2019-08-15
-1u1d,2005-07-05,2004-07-15
-7u1m,2022-12-14,2022-02-21
-8u1q,2024-03-27,2023-09-01
-3u1i,2011-11-09,2011-09-29
-7u1e,2022-08-31,2022-02-21
-5u1j,2017-04-19,2016-11-28
-5u10,2017-12-06,2016-11-27
-5u1g,2017-04-19,2016-11-28
-5u1a,2017-10-11,2016-11-28
-5u1r,2017-03-15,2016-11-28
-1u17,2005-07-26,2004-07-14
-1u1i,2004-08-10,2004-07-15
-6u1m,2019-10-30,2019-08-16
-4u1y,2014-08-20,2014-07-16
-8u13,2024-01-17,2023-08-30
-5u1q,2017-11-15,2016-11-28
-7u1q,2022-08-31,2022-02-21
-7u1y,2022-06-01,2022-02-22
-1u12,2004-11-30,2004-07-14
-6u1x,2020-01-22,2019-08-17
-8u1w,2023-12-20,2023-09-03
-4u1b,2015-03-25,2014-07-15
-5u1e,2017-11-01,2016-11-28
-6u13,2019-09-11,2019-08-15
-5u1v,2017-01-11,2016-11-29
-3u15,2012-06-27,2011-09-29
-7u1x,2022-06-01,2022-02-22
-1u1c,2005-07-05,2004-07-15
-7u1c,2023-01-11,2022-02-20
-1u1u,2004-09-07,2004-07-16
-8u1l,2024-03-13,2023-09-01
-6u1k,2020-05-06,2019-08-15
-5u18,2017-11-01,2016-11-28
-7u17,2022-03-23,2022-02-19
-4u1h,2015-04-08,2014-07-15
-1u13,2004-07-27,2004-07-14
-5u12,2017-12-06,2016-11-27
-8u1u,2023-12-20,2023-09-02
-8u1n,2024-03-13,2023-09-01
-7u1s,2022-08-31,2022-02-22
-4u1s,2015-04-08,2014-07-16
-5u1x,2017-01-04,2016-11-29
-8u16,2023-12-27,2023-08-30
-6u1z,2020-08-19,2019-08-18
-5u19,2017-11-01,2016-11-28
-6u19,2020-03-18,2019-08-15
-8u1f,2024-02-14,2023-08-31
-6u1i,2020-05-06,2019-08-15
-4u15,2014-11-26,2014-07-15
-1u19,2004-10-12,2004-07-15
-1u1e,2005-07-05,2004-07-15
-7u1a,2022-07-06,2022-02-20
-3u1o,2011-10-26,2011-09-30
-8u15,2023-12-27,2023-08-30
-3u11,2011-10-26,2011-09-29
-3u10,2011-10-26,2011-09-29
-3u14,2012-04-25,2011-09-29
-6u1n,2020-02-26,2019-08-16
-5u1i,2017-11-01,2016-11-28
-3u18,2012-07-18,2011-09-29
-4u1j,2015-04-08,2014-07-15
-6u1q,2020-08-19,2019-08-16
-3u1n,2011-11-16,2011-09-30
-4u16,2014-11-26,2014-07-15
-5u1c,2017-01-11,2016-11-28
-6u1j,2020-05-06,2019-08-15
-3u17,2012-10-03,2011-09-29
-4u1l,2015-04-08,2014-07-15
-8u1s,2024-03-27,2023-09-02
-7u13,2022-03-23,2022-02-19
-7u1o,2022-12-21,2022-02-21
-8u18,2024-02-07,2023-08-30
-6u1y,2020-02-05,2019-08-17
-5u1z,2017-01-11,2016-11-29
-6u1e,2020-05-06,2019-08-15
-3u1y,2012-01-04,2011-09-30
-7u19,2022-07-06,2022-02-20
-4u10,2015-01-14,2014-07-14
-5u1l,2017-01-04,2016-11-28
-5u1h,2017-01-11,2016-11-28
-7u1v,2022-06-01,2022-02-22
-5u17,2017-02-08,2016-11-28
-4msl,2014-02-12,2013-09-18
-6msn,2019-01-30,2018-10-17
-4mse,2014-05-14,2013-09-18
-1msm,2003-11-04,2002-09-19
-5msz,2018-02-28,2017-01-06
-4msc,2014-05-14,2013-09-18
-6ms3,2019-04-17,2018-10-16
-6ms7,2019-10-23,2018-10-16
-6msy,2018-11-21,2018-10-18
-2msd,2015-06-03,2014-07-29
-5msd,2017-07-05,2017-01-04
-3ms5,2010-05-12,2010-04-29
-5msp,2017-07-05,2017-01-05
-7msd,2021-10-20,2021-05-11
-6msg,2018-11-21,2018-10-16
-7msa,2021-06-02,2021-05-10
-3msj,2010-07-14,2010-04-29
-7ms1,2022-02-02,2021-05-10
-3ms8,2011-05-11,2010-04-29
-3ms7,2011-01-05,2010-04-29
-4msm,2014-06-18,2013-09-18
-5ms8,2017-04-19,2016-12-31
-1ms8,2003-03-25,2002-09-19
-6mse,2018-11-21,2018-10-16
-6ms9,2020-04-15,2018-10-16
-7mso,2022-03-02,2021-05-11
-6msk,2018-11-21,2018-10-16
-7msz,2022-02-02,2021-05-12
-6msm,2018-11-21,2018-10-16
-5msb,2018-01-17,2017-01-02
-4msu,2014-03-12,2013-09-18
-3msc,2011-03-16,2010-04-29
-7msg,2021-10-27,2021-05-11
-5mss,2017-07-05,2017-01-05
-7ms6,2021-06-09,2021-05-10
-4msa,2014-05-14,2013-09-18
-3msn,2011-05-11,2010-04-29
-6ms2,2019-04-17,2018-10-16
-3msg,2011-05-11,2010-04-29
-4mss,2013-10-30,2013-09-18
-4msf,2013-10-23,2013-09-18
-3msf,2011-05-11,2010-04-29
-2ms1,2014-09-10,2014-07-19
-7ms5,2021-06-09,2021-05-10
-6msd,2018-12-05,2018-10-16
-5msg,2017-02-08,2017-01-04
-4ms4,2013-12-11,2013-09-18
-4msp,2013-12-25,2013-09-18
-5msr,2017-07-05,2017-01-05
-3ms4,2011-01-05,2010-04-29
-3msu,2010-05-26,2010-04-29
-6msc,2019-01-09,2018-10-16
-4ms2,2013-11-27,2013-09-18
-3ms2,2011-01-05,2010-04-29
-7msw,2021-05-26,2021-05-12
-2ms4,2015-09-09,2014-07-22
-4msk,2013-12-25,2013-09-18
-4msx,2014-04-16,2013-09-18
-1ms9,2003-03-25,2002-09-19
-2msc,2015-06-03,2014-07-29
-1msk,1997-04-01,1996-08-03
-3msd,2011-05-11,2010-04-29
-5msq,2018-01-17,2017-01-05
-4msw,2013-10-30,2013-09-18
-1mso,2003-03-04,2002-09-19
-7msp,2022-04-13,2021-05-11
-7ms3,2022-02-02,2021-05-10
-7msn,2022-04-13,2021-05-11
-2ms0,2014-09-17,2014-07-19
-3mse,2010-06-23,2010-04-29
-7msm,2022-02-02,2021-05-11
-7msh,2022-02-02,2021-05-11
-6msh,2018-11-21,2018-10-16
-5msu,2017-07-05,2017-01-05
-2ms3,2015-07-22,2014-07-22
-4ms0,2014-05-14,2013-09-18
-7ms8,2022-02-02,2021-05-10
-7mss,2022-10-12,2021-05-12
-1ms6,2003-04-22,2002-09-19
-4msv,2013-11-27,2013-09-18
-5mst,2017-07-05,2017-01-05
-7msy,2021-07-28,2021-05-12
-6msu,2019-10-23,2018-10-18
-4msh,2014-05-14,2013-09-18
-7ms7,2021-06-09,2021-05-10
-1msa,1995-09-15,1995-03-06
-7msx,2021-05-26,2021-05-12
-5mse,2018-05-02,2017-01-04
-4msd,2014-06-18,2013-09-18
-5msw,2017-07-05,2017-01-05
-3mss,2010-05-26,2010-04-29
-1msn,2003-11-04,2002-09-19
-4ms1,2013-12-11,2013-09-18
-1ms1,2003-03-25,2002-09-19
-2msb,1993-10-31,1992-07-28
-3ms9,2010-05-26,2010-04-29
-6mss,2019-10-02,2018-10-18
-6mso,2019-01-30,2018-10-17
-3msa,2011-05-11,2010-04-29
-6msx,2018-12-19,2018-10-18
-7mst,2022-10-12,2021-05-12
-7msu,2021-06-16,2021-05-12
-4ms6,2014-03-12,2013-09-18
-6ms4,2019-01-02,2018-10-16
-5mso,2017-07-05,2017-01-05
-5ms3,2018-01-17,2016-12-30
-6msa,2019-01-09,2018-10-16
-5msl,2017-06-21,2017-01-05
-1msd,1993-07-15,1992-11-10
-4ms7,2014-06-18,2013-09-18
-7msb,2021-10-20,2021-05-11
-3msk,2010-07-14,2010-04-29
-3msx,2011-03-16,2010-04-29
-3msl,2010-07-14,2010-04-29
-5msa,2018-01-17,2017-01-02
-5msc,2017-07-05,2017-01-04
-7ms9,2022-02-02,2021-05-10
-4ms3,2013-12-11,2013-09-18
-7msk,2022-04-13,2021-05-11
-6msj,2018-11-21,2018-10-16
-4msn,2014-05-14,2013-09-18
-7msq,2022-01-19,2021-05-12
-6ms8,2019-08-21,2018-10-16
-5ms9,2017-08-09,2017-01-01
-6msl,2019-10-23,2018-10-16
-3msz,2010-05-19,2010-04-29
-5msv,2017-07-05,2017-01-05
-1ms0,2003-03-25,2002-09-19
-6msb,2018-12-05,2018-10-16
-5ms7,2017-04-19,2016-12-31
-5msx,2017-03-22,2017-01-06
-3ms3,2011-05-11,2010-04-29
-5ms4,2018-01-17,2016-12-30
-2mse,2015-06-03,2014-07-29
-1ms7,2003-07-08,2002-09-19
-7msr,2022-10-12,2021-05-12
-4ms8,2014-09-24,2013-09-18
-7msc,2022-02-02,2021-05-11
-4msg,2013-12-25,2013-09-18
-4msj,2014-06-18,2013-09-18
-5ms0,2017-05-03,2016-12-29
-6ms1,2019-02-06,2018-10-16
-4msq,2014-06-18,2013-09-18
-2qwb,1998-11-11,1998-04-07
-6qw3,2019-08-28,2019-03-05
-2qwn,2007-12-18,2007-08-10
-2qwa,1998-11-11,1998-04-07
-1qw9,2003-10-07,2003-09-01
-8qwy,2024-01-17,2023-10-20
-4qww,2014-11-26,2014-07-17
-1qwn,2003-10-07,2003-09-02
-3qw9,2011-04-06,2011-02-27
-1qwl,2004-03-30,2003-09-02
-3qw0,2011-06-22,2011-02-26
-6qwu,2020-03-25,2019-03-06
-7qwq,2022-03-16,2022-01-25
-2qwh,1998-11-11,1998-04-07
-3qwv,2011-07-06,2011-02-28
-2qw0,2007-12-18,2007-08-09
-3qw2,2012-01-11,2011-02-26
-4qw9,2014-08-27,2014-07-16
-7qw6,2023-01-25,2022-01-24
-3qww,2011-07-06,2011-02-28
-4qwr,2015-02-04,2014-07-17
-8qw6,2023-12-06,2023-10-18
-2qwk,1998-11-11,1998-04-07
-2qwo,2007-12-18,2007-08-10
-7qwi,2023-02-01,2022-01-25
-4qwx,2015-02-04,2014-07-17
-4qwl,2015-02-04,2014-07-16
-3qwk,2012-08-08,2011-02-28
-3qw4,2011-04-20,2011-02-26
-6qwa,2019-08-21,2019-03-05
-3qw8,2012-02-08,2011-02-27
-7qwj,2023-02-01,2022-01-25
-4qws,2015-02-04,2014-07-17
-4qwf,2015-02-04,2014-07-16
-3qwq,2012-02-01,2011-02-28
-1qwy,2004-01-20,2003-09-03
-1qwu,2003-10-07,2003-09-03
-8qw7,2023-12-06,2023-10-18
-7qw7,2023-01-25,2022-01-24
-3qwi,2012-01-18,2011-02-28
-4qwa,2014-08-27,2014-07-16
-3qwu,2011-03-16,2011-02-28
-2qwp,2007-12-18,2007-08-10
-2qws,2008-03-18,2007-08-10
-3qwb,2012-02-08,2011-02-28
-1qwc,2003-12-09,2003-09-02
-8qws,2024-04-24,2023-10-20
-2qwf,1998-11-11,1998-04-07
-1qwz,2004-04-06,2003-09-03
-6qww,2019-03-13,2019-03-06
-7qwr,2022-03-09,2022-01-25
-7qw3,2023-02-01,2022-01-24
-4qw4,2015-02-04,2014-07-16
-1qw5,2003-12-09,2003-08-31
-8qwz,2024-01-17,2023-10-20
-1qw0,2003-11-04,2003-08-29
-6qw9,2019-08-21,2019-03-05
-7qws,2022-03-09,2022-01-25
-4qw5,2015-02-04,2014-07-16
-1qw8,2003-10-07,2003-09-01
-6qw8,2019-08-21,2019-03-05
-4qwu,2015-02-04,2014-07-17
-3qwh,2012-03-21,2011-02-28
-4qwt,2014-09-24,2014-07-17
-7qwy,2022-09-28,2022-01-26
-6qwo,2019-06-19,2019-03-05
-3qw7,2012-02-08,2011-02-27
-2qwg,1998-11-11,1998-04-07
-6qw5,2019-09-25,2019-03-05
-4qwj,2015-02-04,2014-07-16
-4qwm,2015-07-22,2014-07-16
-4qwn,2014-11-05,2014-07-16
-6qwn,2020-03-18,2019-03-05
-7qwk,2022-05-04,2022-01-25
-2qwc,1998-11-11,1998-04-07
-4qwg,2015-02-04,2014-07-16
-1qw6,2003-12-09,2003-09-01
-3qwc,2012-03-14,2011-02-28
-7qwh,2023-02-01,2022-01-25
-3qwf,2012-01-18,2011-02-28
-1qws,2003-10-14,2003-09-03
-2qwq,2007-12-18,2007-08-10
-2qwd,1998-11-11,1998-04-07
-4qw7,2015-02-04,2014-07-16
-3qw5,2012-02-08,2011-02-26
-1qwo,2004-06-01,2003-09-03
-7qwu,2022-09-28,2022-01-25
-4qwd,2014-08-27,2014-07-16
-3qwr,2012-02-01,2011-02-28
-3qw1,2011-06-22,2011-02-26
-4qwc,2014-08-27,2014-07-16
-8qwr,2024-04-24,2023-10-20
-6qw0,2019-09-25,2019-03-05
-6qwx,2019-03-13,2019-03-06
-6qw4,2020-03-25,2019-03-05
-2qw8,2008-06-10,2007-08-09
-4qwk,2015-02-04,2014-07-16
-4qw1,2015-02-04,2014-07-16
-4qwi,2015-02-04,2014-07-16
-2qwl,2007-12-18,2007-08-10
-7qwt,2022-06-01,2022-01-25
-7qwf,2022-09-28,2022-01-25
-4qw0,2015-02-04,2014-07-16
-7qwo,2022-11-23,2022-01-25
-6qwy,2019-03-13,2019-03-06
-2qw5,2007-09-04,2007-08-09
-3qwj,2012-08-08,2011-02-28
-1qwm,2004-03-30,2003-09-02
-4qw3,2015-02-04,2014-07-16
-2qwj,1998-11-11,1998-04-07
-2qwi,1998-11-11,1998-04-07
-1qw7,2004-11-30,2003-09-01
-2qwm,2007-12-18,2007-08-10
-1qw4,2003-12-09,2003-08-31
-7qw5,2023-01-25,2022-01-24
-4qw8,2014-08-27,2014-07-16
-4qw2,2014-12-03,2014-07-16
-6qw1,2020-04-01,2019-03-05
-6qwc,2019-08-21,2019-03-05
-4qw6,2015-02-04,2014-07-16
-6qw2,2020-04-01,2019-03-05
-2qwe,1998-11-11,1998-04-07
-2qw1,2008-08-05,2007-08-09
-1qwj,2003-12-09,2003-09-02
-4qwp,2015-07-22,2014-07-17
-6qw7,2019-08-21,2019-03-05
-4qwe,2014-08-27,2014-07-16
-3qwp,2011-04-06,2011-02-28
-1qwr,2004-03-02,2003-09-03
-2qwr,2007-12-18,2007-08-10
-6qw6,2019-04-17,2019-03-05
-3qw6,2012-02-08,2011-02-26
-6qwb,2019-08-21,2019-03-05
-7qwn,2023-02-01,2022-01-25
-4qwb,2014-08-27,2014-07-16
-6qwi,2019-07-03,2019-03-05
-6qwg,2019-11-20,2019-03-05
-2qwx,2008-04-29,2007-08-10
-101m,1998-04-08,1997-12-13
-4nqr,2013-12-18,2013-11-25
-2nqy,2007-11-06,2006-11-01
-4nqq,2014-09-24,2013-11-25
-2nqh,2007-11-06,2006-10-31
-7nq1,2021-07-21,2021-02-28
-7nqu,2021-03-10,2021-03-02
-4nql,2014-10-08,2013-11-25
-7nqp,2021-06-16,2021-03-02
-4nqd,2014-04-16,2013-11-25
-7nqo,2022-02-02,2021-03-01
-1nqa,2003-04-22,2003-01-21
-2nq6,2006-11-21,2006-10-30
-3nq1,2010-11-17,2010-06-29
-3nqw,2010-09-08,2010-06-30
-3nq7,2011-05-11,2010-06-29
-3nqn,2010-08-18,2010-06-29
-1nqe,2003-04-29,2003-01-21
-2nq8,2007-07-17,2006-10-30
-5nqz,2018-02-28,2017-04-21
-1nqj,2003-04-15,2003-01-21
-6nqa,2019-02-20,2019-01-19
-3nqe,2011-05-11,2010-06-29
-1nq2,2003-04-15,2003-01-21
-2nql,2006-11-14,2006-10-31
-5nqn,2017-05-31,2017-04-20
-5nq2,2018-04-25,2017-04-19
-6nqh,2020-01-29,2019-01-21
-7nqa,2021-07-21,2021-03-01
-7nq2,2021-07-21,2021-02-28
-7nq8,2021-03-24,2021-03-01
-7nq4,2021-08-11,2021-03-01
-7nqn,2022-02-02,2021-03-01
-7nqs,2021-03-17,2021-03-02
-7nq3,2021-07-21,2021-02-28
-6nqt,2020-01-29,2019-01-21
-7nq7,2021-03-24,2021-03-01
-4nq5,2014-11-26,2013-11-23
-1nqm,2003-07-15,2003-01-22
-7nqh,2021-05-05,2021-03-01
-1nqx,2004-01-23,2003-01-23
-6nqd,2019-03-06,2019-01-21
-1nqo,2003-04-22,2003-01-22
-3nqo,2010-07-21,2010-06-29
-3nqm,2011-05-11,2010-06-29
-7nqi,2021-03-24,2021-03-01
-2nqj,2007-11-06,2006-10-31
-4nq1,2014-01-01,2013-11-23
-3nqg,2011-05-11,2010-06-29
-7nqf,2022-05-04,2021-03-01
-3nqf,2011-05-11,2010-06-29
-6nq0,2019-03-27,2019-01-18
-4nqg,2014-11-26,2013-11-25
-1nq0,2003-04-15,2003-01-20
-3nq0,2010-11-17,2010-06-29
-4nq4,2014-11-26,2013-11-23
-1nqz,2003-05-13,2003-01-23
-3nqy,2010-10-06,2010-06-30
-2nqp,2007-05-15,2006-10-31
-4nq6,2014-11-26,2013-11-23
-5nqr,2018-01-31,2017-04-21
-5nq3,2018-04-25,2017-04-19
-3nq5,2010-11-17,2010-06-29
-2nqz,2007-11-13,2006-11-01
-7nq5,2021-03-24,2021-03-01
-7nq9,2021-03-24,2021-03-01
-1nqt,2003-05-06,2003-01-23
-7nqb,2022-03-23,2021-03-01
-4nqa,2014-02-26,2013-11-24
-5nqk,2018-05-30,2017-04-20
-6nq5,2020-01-22,2019-01-19
-5nq1,2018-04-25,2017-04-19
-5nqo,2017-05-31,2017-04-20
-1nqp,2004-03-02,2003-01-22
-7nqz,2021-03-10,2021-03-02
-6nqg,2019-04-10,2019-01-21
-5nqt,2017-09-27,2017-04-21
-2nqc,2007-09-11,2006-10-31
-2nq9,2007-11-13,2006-10-30
-7nql,2021-05-05,2021-03-01
-3nqz,2010-10-06,2010-06-30
-6nqf,2019-04-10,2019-01-21
-2nqa,2006-11-14,2006-10-30
-7nq0,2021-07-21,2021-02-28
-6nq2,2019-03-27,2019-01-18
-4nq2,2014-11-12,2013-11-23
-3nqs,2010-07-21,2010-06-29
-5nqa,2017-12-20,2017-04-19
-1nqc,2003-04-15,2003-01-21
-5nq7,2017-11-01,2017-04-19
-1nqg,2003-04-29,2003-01-21
-5nq5,2018-03-21,2017-04-19
-4nq3,2014-09-10,2013-11-23
-1nq5,2003-04-22,2003-01-21
-6nq3,2020-01-29,2019-01-19
-4nqn,2013-12-18,2013-11-25
-3nqc,2011-05-11,2010-06-29
-1nqi,2003-02-04,2003-01-21
-5nq0,2018-04-25,2017-04-19
-2nqi,2007-01-09,2006-10-31
-1nqu,2004-01-23,2003-01-23
-5nqm,2017-05-31,2017-04-20
-4nqm,2013-12-18,2013-11-25
-2nqd,2007-07-24,2006-10-31
-4nqv,2013-12-25,2013-11-25
-7nqj,2021-04-07,2021-03-01
-5nqc,2017-06-07,2017-04-19
-4nqc,2014-04-16,2013-11-25
-6nqm,2019-02-13,2019-01-21
-1nq6,2004-01-21,2003-01-21
-7nqw,2021-10-06,2021-03-02
-3nqb,2010-07-28,2010-06-29
-5nq8,2017-11-01,2017-04-19
-7nqq,2021-10-06,2021-03-02
-6nq4,2019-11-27,2019-01-19
-5nqw,2018-01-17,2017-04-21
-3nqt,2011-06-29,2010-06-29
-7nqe,2022-05-04,2021-03-01
-3nqr,2010-08-25,2010-06-29
-5nqu,2017-09-27,2017-04-21
-1nq1,2003-04-15,2003-01-20
-7nqr,2021-03-10,2021-03-02
-5nqv,2017-07-26,2017-04-21
-3nqx,2010-10-06,2010-06-30
-4nqy,2014-05-21,2013-11-26
-7nqm,2022-02-02,2021-03-01
-5nqe,2017-05-24,2017-04-20
-6nqu,2019-02-13,2019-01-21
-1nql,2003-03-11,2003-01-21
-6nq7,2019-04-17,2019-01-19
-3nqi,2010-08-18,2010-06-29
-6nqe,2019-04-10,2019-01-21
-3nqa,2011-05-11,2010-06-29
-1nqh,2003-04-29,2003-01-21
-4nq8,2014-01-01,2013-11-24
-2nq7,2006-11-21,2006-10-30
-4nqx,2013-12-25,2013-11-26
-2nqx,2006-11-21,2006-11-01
-4nqw,2014-01-22,2013-11-25
-1nqw,2004-01-23,2003-01-23
-3nq6,2011-05-11,2010-06-29
-3nqd,2011-05-11,2010-06-29
-1nqd,2003-04-15,2003-01-21
-7nqg,2021-10-06,2021-03-01
-5nqq,2017-06-07,2017-04-20
-1nqv,2004-01-23,2003-01-23
-4nqe,2014-04-16,2013-11-25
-1nqf,2003-04-29,2003-01-21
-5nqd,2018-05-30,2017-04-20
-7nq6,2021-04-07,2021-03-01
-2nqg,2007-01-09,2006-10-31
-1nq7,2003-09-23,2003-01-21
-5nq9,2017-11-01,2017-04-19
-7nqc,2021-09-22,2021-03-01
-3nq9,2010-07-14,2010-06-29
-13gs,1999-01-13,1997-11-20
-1wg2,2004-11-27,2004-05-27
-4wgz,2015-03-18,2014-09-19
-1wg8,2004-11-27,2004-05-27
-7wg4,2022-09-14,2021-12-28
-8wgt,2024-05-15,2023-09-22
-7wgt,2022-06-29,2021-12-28
-3wgb,2014-07-09,2013-08-03
-1wgj,1997-11-19,1996-10-24
-3wgh,2014-08-13,2013-08-05
-5wgm,2017-12-06,2017-07-14
-6wg3,2020-05-20,2020-04-04
-6wg5,2020-08-12,2020-04-04
-5wgu,2017-08-16,2017-07-14
-5wg7,2018-02-07,2017-07-13
-5wgw,2017-08-16,2017-07-14
-2wgz,2009-06-16,2009-04-28
-8wgs,2024-05-15,2023-09-22
-3wgl,2013-12-25,2013-08-06
-8wgf,2023-11-22,2023-09-21
-2wgs,2009-09-01,2009-04-27
-2wgy,2009-05-12,2009-04-28
-3wgz,2014-08-20,2013-08-20
-3wgd,2014-06-25,2013-08-04
-8wg0,2024-05-08,2023-09-20
-6wg9,2021-02-10,2020-04-05
-5wgb,2017-07-26,2017-07-13
-4wgh,2014-10-01,2014-09-18
-8wgw,2024-02-28,2023-09-22
-7wgu,2022-12-14,2021-12-29
-7wge,2023-07-05,2021-12-28
-7wg2,2022-09-14,2021-12-28
-4wgx,2015-02-11,2014-09-19
-2wgf,2009-07-21,2009-04-17
-6wge,2020-05-20,2020-04-05
-5wgl,2017-12-06,2017-07-14
-5wg1,2018-09-19,2017-07-13
-3wgw,2014-02-05,2013-08-12
-7wg6,2022-05-18,2021-12-28
-2wgd,2009-07-21,2009-04-17
-3wg3,2013-11-27,2013-07-25
-2wgc,1990-10-15,1990-04-03
-4wg4,2014-10-15,2014-09-17
-7wgy,2023-01-04,2021-12-29
-6wgz,2021-04-21,2020-04-07
-7wgo,2022-05-25,2021-12-28
-4wg3,2014-10-15,2014-09-17
-6wgs,2021-01-20,2020-04-06
-6wgw,2020-07-08,2020-04-06
-6wgm,2020-04-29,2020-04-05
-3wgg,2014-08-13,2013-08-05
-4wgg,2015-09-30,2014-09-18
-5wgg,2017-07-26,2017-07-14
-6wgc,2020-07-15,2020-04-05
-7wgb,2022-06-22,2021-12-28
-3wg6,2013-08-21,2013-07-28
-3wgm,2013-12-25,2013-08-06
-2wgj,2009-06-02,2009-04-20
-5wg5,2017-12-27,2017-07-13
-7wgv,2023-01-04,2021-12-29
-3wgv,2013-10-09,2013-08-09
-1wge,2005-08-23,2004-05-28
-6wgx,2020-10-07,2020-04-06
-3wg4,2013-11-27,2013-07-25
-2wg0,2009-08-11,2009-04-15
-7wg3,2022-11-09,2021-12-28
-6wgl,2020-09-16,2020-04-05
-5wgd,2018-06-13,2017-07-14
-4wg5,2014-10-15,2014-09-17
-5wg4,2017-12-27,2017-07-13
-5wgs,2017-08-16,2017-07-14
-7wgq,2022-05-25,2021-12-28
-7wgd,2022-06-29,2021-12-28
-4wgf,2015-07-29,2014-09-18
-3wg1,2013-11-27,2013-07-25
-2wg8,2009-06-02,2009-04-16
-5wgr,2017-08-16,2017-07-14
-7wg8,2022-06-22,2021-12-28
-2wg3,2009-06-30,2009-04-15
-3wgj,2013-12-25,2013-08-06
-2wgu,2009-11-24,2009-04-27
-5wg3,2017-12-27,2017-07-13
-5wg6,2018-06-27,2017-07-13
-7wgc,2022-06-22,2021-12-28
-2wg4,2009-06-30,2009-04-15
-3wgi,2014-08-13,2013-08-05
-6wgt,2020-09-23,2020-04-06
-7wgz,2023-01-04,2021-12-29
-3wgy,2014-08-20,2013-08-19
-8wgv,2024-02-28,2023-09-22
-2wg1,2009-08-11,2009-04-15
-3wg5,2013-10-23,2013-07-26
-2wgm,2009-06-09,2009-04-21
-6wgh,2020-05-20,2020-04-05
-5wg8,2018-07-18,2017-07-13
-4wgk,2015-07-08,2014-09-18
-5wgk,2017-12-06,2017-07-14
-5wgv,2017-08-16,2017-07-14
-7wg1,2022-09-14,2021-12-27
-7wg9,2022-06-22,2021-12-28
-5wgp,2018-02-07,2017-07-14
-2wgt,2009-11-24,2009-04-27
-4wg2,2014-11-05,2014-09-17
-5wgc,2018-04-18,2017-07-13
-7wgr,2022-06-01,2021-12-28
-6wgv,2021-01-20,2020-04-06
-6wgi,2020-07-15,2020-04-05
-5wg9,2018-01-03,2017-07-13
-2wg9,2009-06-02,2009-04-16
-5wgt,2017-08-16,2017-07-14
-7wg7,2022-06-22,2021-12-28
-2wgg,2009-07-21,2009-04-17
-5wgy,2017-08-16,2017-07-14
-4wgy,2015-03-18,2014-09-19
-2wge,2009-07-21,2009-04-17
-7wgn,2022-05-25,2021-12-28
-3wgk,2013-12-25,2013-08-06
-7wgh,2022-11-09,2021-12-28
-6wgn,2020-10-14,2020-04-06
-8wgl,2023-10-04,2023-09-22
-8wg2,2024-05-08,2023-09-20
-5wgx,2017-08-16,2017-07-14
-7wgs,2022-11-16,2021-12-28
-8wg1,2024-05-08,2023-09-20
-7wgx,2023-01-04,2021-12-29
-2wgq,2009-06-09,2009-04-23
-3wgx,2014-06-25,2013-08-13
-1wgi,1997-11-19,1996-10-24
-6wgo,2021-10-06,2020-04-06
-3wgp,2014-08-27,2013-08-07
-5wgz,2017-08-16,2017-07-14
-4wg0,2015-01-21,2014-09-17
-3wg8,2014-05-07,2013-07-31
-1wgc,1990-10-15,1990-04-03
-2wgi,2009-11-10,2009-04-20
-6wg6,2020-05-20,2020-04-04
-8wgu,2024-05-15,2023-09-22
-8wg8,2024-03-06,2023-09-20
-2wgh,2009-05-05,2009-04-19
-3wgn,2013-12-25,2013-08-06
-6wgg,2020-07-15,2020-04-05
-3wgq,2014-08-20,2013-08-07
-7wgp,2022-05-25,2021-12-28
-5wgi,2017-12-06,2017-07-14
-7wgl,2022-05-25,2021-12-28
-3wg7,2014-04-30,2013-07-29
-4wgi,2014-11-19,2014-09-18
-4wgj,2015-10-14,2014-09-18
-2wg7,2009-06-02,2009-04-16
-3wgc,2014-07-09,2013-08-03
-6wgq,2020-04-15,2020-04-06
-7wg5,2022-03-16,2021-12-28
-3wgu,2013-10-09,2013-08-09
-2wg2,2010-04-21,2009-04-15
-5wgq,2018-06-13,2017-07-14
-7wgi,2022-11-09,2021-12-28
-3wgt,2014-04-02,2013-08-09
-1bgy,1999-01-06,1998-06-02
-3bg7,2008-12-02,2007-11-26
-8bg4,2023-11-08,2022-10-27
-2bgv,2005-05-11,2005-01-05
-6bgz,2018-03-28,2017-10-29
-1bg9,1999-06-15,1998-06-05
-6bgf,2017-12-13,2017-10-28
-8bgu,2023-06-14,2022-10-28
-3bgs,2008-01-08,2007-11-27
-8bgy,2023-03-08,2022-10-28
-1bg3,1999-06-08,1998-06-04
-3bg5,2008-02-26,2007-11-26
-4bga,2013-11-27,2013-03-24
-6bg3,2018-09-26,2017-10-27
-2bgw,2005-02-23,2005-01-06
-8bgh,2023-08-16,2022-10-27
-7bgl,2021-05-05,2021-01-07
-6bgi,2017-12-27,2017-10-28
-3bgz,2007-12-11,2007-11-27
-2bgd,2005-05-04,2004-12-21
-8bgz,2023-03-08,2022-10-28
-7bg9,2021-04-28,2021-01-06
-7bgg,2021-09-22,2021-01-07
-2bgr,2005-01-27,2005-01-04
-7bgy,2021-01-27,2021-01-09
-3bgv,2007-12-04,2007-11-27
-6bgy,2018-03-28,2017-10-29
-8bgw,2023-08-16,2022-10-28
-4bgy,2013-04-24,2013-03-29
-4bgm,2014-03-12,2013-03-27
-3bg3,2008-02-26,2007-11-26
-4bge,2013-12-04,2013-03-26
-3bg9,2008-02-26,2007-11-26
-4bgd,2013-05-29,2013-03-25
-1bg0,1998-10-14,1998-06-03
-6bgr,2018-02-21,2017-10-29
-3bgi,2008-06-10,2007-11-26
-8bgo,2023-01-11,2022-10-28
-7bgi,2021-12-08,2021-01-07
-7bgq,2021-06-16,2021-01-08
-1bg7,1999-01-13,1998-06-05
-6bgc,2018-01-31,2017-10-27
-4bgw,2013-04-24,2013-03-29
-4bg1,2014-03-12,2013-03-22
-7bgc,2021-04-28,2021-01-06
-7bgv,2021-06-16,2021-01-08
-8bg3,2023-11-08,2022-10-27
-6bgp,2018-02-07,2017-10-29
-1bgv,1998-10-14,1998-06-01
-8bgp,2023-01-11,2022-10-28
-3bgo,2008-06-03,2007-11-27
-8bgn,2023-01-11,2022-10-28
-7bg4,2022-01-12,2021-01-05
-6bgs,2018-02-21,2017-10-29
-3bgb,2008-09-02,2007-11-26
-8bgg,2023-03-08,2022-10-27
-2bg7,2005-03-31,2004-12-17
-7bgn,2021-05-19,2021-01-08
-7bgm,2021-05-19,2021-01-08
-4bgu,2014-04-16,2013-03-28
-8bg2,2023-11-08,2022-10-27
-6bga,2018-07-18,2017-10-27
-7bgt,2021-12-15,2021-01-08
-2bgn,2005-01-27,2005-01-03
-6bgn,2018-02-21,2017-10-29
-7bg0,2021-08-04,2021-01-05
-6bgv,2018-03-28,2017-10-29
-2bgi,2005-09-07,2004-12-23
-3bgj,2008-11-18,2007-11-26
-3bgu,2007-12-11,2007-11-27
-3bgx,2008-12-09,2007-11-27
-4bgx,2013-04-24,2013-03-29
-4bgg,2013-04-10,2013-03-26
-8bgx,2023-03-08,2022-10-28
-3bgq,2007-12-11,2007-11-27
-3bg6,2008-12-02,2007-11-26
-1bgq,1999-06-08,1998-05-29
-7bgo,2021-11-17,2021-01-08
-2bg8,2005-03-31,2004-12-17
-3bgk,2008-12-16,2007-11-26
-8bgb,2023-11-08,2022-10-27
-4bg6,2013-05-29,2013-03-23
-2bga,2005-03-31,2004-12-17
-3bgp,2007-12-11,2007-11-27
-6bgq,2018-02-21,2017-10-29
-8bgj,2023-06-07,2022-10-27
-3bgg,2007-12-11,2007-11-26
-6bgm,2017-11-22,2017-10-28
-7bgw,2021-06-16,2021-01-08
-6bge,2018-10-31,2017-10-27
-4bgb,2013-11-27,2013-03-24
-8bgd,2023-11-08,2022-10-27
-8bga,2023-11-08,2022-10-27
-4bg9,2013-11-27,2013-03-24
-7bg3,2021-06-16,2021-01-05
-6bg0,2018-02-21,2017-10-27
-2bg6,2005-03-31,2004-12-17
-1bgn,1998-08-12,1998-05-29
-4bgh,2013-09-04,2013-03-26
-3bg8,2008-12-09,2007-11-26
-6bgl,2018-02-14,2017-10-28
-2bgm,2005-01-13,2004-12-23
-4bgk,2014-03-12,2013-03-27
-1bg2,1998-10-14,1998-06-04
-2bgj,2005-09-07,2004-12-23
-6bgt,2018-10-31,2017-10-29
-8bgt,2023-03-08,2022-10-28
-2bg2,2005-03-31,2004-12-16
-6bgx,2018-03-28,2017-10-29
-7bg6,2021-05-19,2021-01-06
-2bgg,2005-03-31,2004-12-22
-6bg4,2018-02-21,2017-10-27
-4bgz,2013-04-24,2013-03-29
-6bg5,2018-09-26,2017-10-27
-1bgo,1999-06-08,1998-05-29
-7bg5,2022-01-12,2021-01-05
-7bgu,2021-12-15,2021-01-08
-7bgp,2021-03-03,2021-01-08
-3bgr,2008-02-12,2007-11-27
-2bgl,2005-01-13,2004-12-23
-6bgj,2017-12-27,2017-10-28
-1bgp,1997-11-12,1997-07-24
-2bge,2005-05-04,2004-12-21
-3bgm,2008-10-21,2007-11-27
-8bgc,2022-11-23,2022-10-27
-4bgl,2014-04-09,2013-03-27
-3bgc,2008-09-02,2007-11-26
-4bg4,2013-09-04,2013-03-22
-6bgw,2018-03-28,2017-10-29
-8bg8,2023-11-08,2022-10-27
-1bgg,1998-05-27,1997-05-12
-4bgq,2013-05-08,2013-03-28
-3bgl,2008-01-29,2007-11-26
-6bgd,2018-01-31,2017-10-27
-3bga,2007-12-11,2007-11-26
-1bgj,1998-08-12,1998-05-29
-3bgd,2008-06-10,2007-11-26
-4bgi,2013-12-04,2013-03-27
-6bgu,2018-03-28,2017-10-29
-6bg2,2018-10-31,2017-10-27
-1bg4,1998-08-12,1998-06-05
-6bgo,2018-02-14,2017-10-29
-6bgk,2018-02-21,2017-10-28
-8bgl,2023-02-15,2022-10-28
-2bgu,1995-12-09,1994-06-09
-6bg1,2018-02-21,2017-10-27
-8bg1,2023-11-08,2022-10-27
-8bg6,2023-11-08,2022-10-27
-8bg5,2023-11-08,2022-10-27
-7bgr,2021-06-16,2021-01-08
-2bgs,2006-06-22,2005-01-05
-4bg8,2013-11-27,2013-03-24
-8bgi,2023-11-08,2022-10-27
-1zk3,2005-06-21,2005-05-02
-4zk4,2015-05-13,2015-04-29
-6zk6,2020-11-18,2020-06-29
-3zks,2013-05-29,2013-01-24
-6zkr,2020-10-07,2020-06-30
-4zko,2016-05-18,2015-04-30
-5zk1,2018-06-20,2018-03-22
-4zkh,2015-09-30,2015-04-30
-7zkb,2023-04-26,2022-04-12
-1zkn,2005-05-17,2005-05-03
-3zka,2013-11-06,2013-01-22
-7zke,2023-04-26,2022-04-12
-6zk9,2020-10-07,2020-06-30
-4zkx,2015-09-30,2015-04-30
-7zk2,2022-06-22,2022-04-12
-5zkz,2019-04-10,2018-03-26
-6zkn,2020-10-07,2020-06-30
-1zkp,2005-06-21,2005-05-03
-6zk7,2021-05-12,2020-06-30
-1zk2,2005-06-21,2005-05-02
-2zk3,2009-02-24,2008-03-12
-1zkm,2005-06-14,2005-05-03
-3zk2,2013-05-29,2013-01-21
-2zkn,2008-09-30,2008-03-26
-6zkf,2020-10-14,2020-06-30
-3zkb,2013-09-18,2013-01-22
-4zkb,2015-07-08,2015-04-30
-7zk6,2023-04-26,2022-04-12
-4zk9,2015-07-08,2015-04-30
-4zkr,2016-05-18,2015-04-30
-6zky,2022-01-26,2020-06-30
-4zkc,2015-07-08,2015-04-30
-6zk1,2022-01-12,2020-06-29
-7zk9,2023-04-26,2022-04-12
-1zky,2006-05-09,2005-05-04
-1zkl,2005-07-05,2005-05-03
-6zk3,2022-01-12,2020-06-29
-4zkw,2015-09-30,2015-04-30
-7zk5,2023-04-26,2022-04-12
-3zkd,2013-09-18,2013-01-22
-5zkv,2019-05-22,2018-03-26
-2zkm,2008-08-12,2008-03-26
-6zko,2020-10-07,2020-06-30
-5zkm,2019-03-27,2018-03-24
-4zkf,2015-06-17,2015-04-30
-1zk4,2005-06-21,2005-05-02
-7zkk,2022-11-02,2022-04-13
-7zk8,2023-04-26,2022-04-12
-7zka,2023-04-26,2022-04-12
-5zkj,2019-04-03,2018-03-24
-5zk8,2018-11-21,2018-03-23
-5zk6,2019-03-27,2018-03-23
-4zk0,2015-07-01,2015-04-29
-3zkp,2013-05-01,2013-01-24
-4zke,2015-06-17,2015-04-30
-7zku,2023-10-25,2022-04-13
-7zk3,2022-05-25,2022-04-12
-7zkh,2022-12-28,2022-04-13
-6zks,2020-10-07,2020-06-30
-6zkv,2020-10-07,2020-06-30
-2zkx,2009-03-24,2008-03-31
-5zk4,2018-06-13,2018-03-23
-2zkb,2008-10-07,2008-03-14
-1zkk,2005-06-07,2005-05-03
-5zkb,2018-11-21,2018-03-23
-6zki,2020-10-07,2020-06-30
-5zkl,2019-03-27,2018-03-24
-7zki,2022-07-20,2022-04-13
-5zk5,2019-02-20,2018-03-23
-6zkm,2020-10-07,2020-06-30
-2zka,2008-10-07,2008-03-13
-2zkc,2009-03-17,2008-03-14
-3zku,2013-02-06,2013-01-24
-2zkt,2009-04-21,2008-03-29
-7zkc,2022-04-20,2022-04-12
-6zkg,2020-10-07,2020-06-30
-6zkw,2022-01-26,2020-06-30
-6zkq,2020-10-07,2020-06-30
-3zk4,2014-01-29,2013-01-21
-1zko,2005-05-10,2005-05-03
-6zke,2020-10-07,2020-06-30
-1zkw,2005-06-28,2005-05-04
-4zkd,2015-06-17,2015-04-30
-6zkh,2020-10-07,2020-06-30
-3zkk,2013-10-30,2013-01-23
-6zk0,2020-09-23,2020-06-29
-6zk2,2022-01-12,2020-06-29
-7zkr,2022-08-31,2022-04-13
-2zky,2009-03-24,2008-03-31
-6zk4,2022-01-12,2020-06-29
-7zkg,2022-12-28,2022-04-13
-3zkn,2013-05-29,2013-01-23
-7zkv,2022-11-02,2022-04-13
-5zki,2019-04-03,2018-03-24
-6zkl,2020-10-07,2020-06-30
-7zkq,2022-11-23,2022-04-13
-4zki,2016-05-04,2015-04-30
-4zky,2015-10-28,2015-05-01
-6zkk,2020-10-07,2020-06-30
-4zks,2016-05-18,2015-04-30
-1zkq,2005-11-01,2005-05-03
-2zk1,2009-02-24,2008-03-12
-1zkf,2006-04-11,2005-05-02
-3zky,2013-03-20,2013-01-25
-4zk8,2015-05-20,2015-04-30
-6zk8,2020-11-25,2020-06-30
-6zka,2020-10-07,2020-06-30
-6zkz,2022-01-26,2020-06-30
-5zk9,2019-02-20,2018-03-23
-6zkd,2020-10-07,2020-06-30
-5zkq,2018-06-20,2018-03-25
-1zk0,2005-06-21,2005-05-02
-1zkj,2006-04-18,2005-05-03
-2zk9,2009-03-17,2008-03-13
-4zkp,2015-07-29,2015-04-30
-4zk5,2015-09-02,2015-04-29
-4zkt,2015-12-23,2015-04-30
-6zkb,2020-10-07,2020-06-30
-6zkj,2020-10-07,2020-06-30
-5zkw,2018-12-19,2018-03-26
-6zkt,2020-10-07,2020-06-30
-7zkx,2023-02-22,2022-04-13
-5zkp,2018-06-20,2018-03-25
-2zks,2009-03-31,2008-03-28
-2zkj,2008-08-05,2008-03-25
-2zkl,2009-03-31,2008-03-25
-6zkc,2020-10-07,2020-06-30
-5zk0,2018-06-06,2018-03-22
-5zkc,2018-11-21,2018-03-23
-7zk7,,2022-04-12
-6zkp,2020-10-07,2020-06-30
-5zk3,2018-11-21,2018-03-23
-3zki,2013-05-29,2013-01-23
-1zk7,2005-07-05,2005-05-02
-5zk7,2019-02-20,2018-03-23
-1zk1,2005-06-21,2005-05-02
-3zk5,2014-01-29,2013-01-21
-2zk5,2009-02-24,2008-03-12
-7zk4,2023-04-26,2022-04-12
-1zk5,2006-05-02,2005-05-02
-3zkl,2013-10-30,2013-01-23
-7zkw,2022-08-31,2022-04-13
-4zkl,2016-03-02,2015-04-30
-5zku,2018-12-19,2018-03-26
-7zks,2023-02-22,2022-04-13
-2zk6,2009-02-24,2008-03-12
-7zkj,2022-11-02,2022-04-13
-3zk1,2013-05-29,2013-01-21
-4zkn,2016-05-18,2015-04-30
-7zkt,2023-03-22,2022-04-13
-4zku,2015-06-10,2015-04-30
-2zkw,2009-03-24,2008-03-31
-7zko,2022-11-30,2022-04-13
-1zkx,2005-07-05,2005-05-04
-4zk1,2015-05-13,2015-04-29
-2zk2,2009-02-24,2008-03-12
-6zku,2020-10-07,2020-06-30
-7zkl,2022-11-30,2022-04-13
-4zkq,2015-11-18,2015-04-30
-7zkm,2022-11-30,2022-04-13
-3zk6,2013-04-24,2013-01-22
-7zkn,2022-11-30,2022-04-13
-6zk5,2022-01-12,2020-06-29
-4zk6,2016-06-29,2015-04-29
-1zke,2005-06-28,2005-05-02
-6ecj,2019-08-14,2018-08-08
-1ecq,2000-05-23,2000-01-25
-6eck,2019-12-04,2018-08-08
-5ecn,2016-11-02,2015-10-20
-6ecz,2018-11-28,2018-08-08
-3eca,1993-10-31,1993-07-02
-5ece,2015-11-25,2015-10-20
-1ecy,1997-02-12,1996-08-06
-1ec8,2000-05-23,2000-01-25
-7ecd,2022-01-19,2021-03-12
-2ec6,2008-02-26,2007-02-10
-7ecs,2021-12-08,2021-03-13
-4ecn,2012-05-23,2012-03-26
-6ecw,2018-12-12,2018-08-08
-6ect,2018-12-12,2018-08-08
-3ecr,2008-09-30,2008-09-01
-8ece,2022-11-16,2022-09-01
-4ecu,2012-07-11,2012-03-26
-1eca,1979-07-05,1979-03-07
-6ecg,2018-10-10,2018-08-07
-4ec4,2012-12-05,2012-03-26
-8ec0,2023-05-24,2022-08-31
-6ec3,2018-12-26,2018-08-07
-4ecz,2012-07-11,2012-03-26
-5ect,2016-11-02,2015-10-20
-8ecy,2022-11-02,2022-09-02
-1eco,1979-07-05,1979-03-07
-3ect,2008-09-16,2008-09-02
-6ecf,2018-12-12,2018-08-07
-5ecq,2016-11-02,2015-10-20
-4ec0,2012-05-16,2012-03-26
-2ec8,2007-08-07,2007-02-11
-5ecl,2016-11-02,2015-10-20
-5ech,2016-11-02,2015-10-20
-5ecp,2016-11-02,2015-10-20
-4ech,2012-06-13,2012-03-26
-1ec2,2002-06-26,2000-01-25
-3ec7,2008-09-23,2008-08-29
-1ec7,2000-05-23,2000-01-25
-6ech,2019-12-04,2018-08-07
-7ec6,2022-03-16,2021-03-11
-1ec9,2000-05-23,2000-01-25
-1ec0,2002-06-26,2000-01-25
-5ec0,2016-11-02,2015-10-20
-8ec4,2023-03-08,2022-09-01
-1ecf,1996-11-08,1996-04-23
-8ec9,2023-05-31,2022-09-01
-1ece,1996-10-14,1996-04-04
-4ecw,2012-07-11,2012-03-26
-2ecw,2008-02-26,2007-02-14
-3ecj,2008-10-07,2008-08-31
-5eco,2016-11-02,2015-10-20
-7ec3,2022-03-16,2021-03-11
-2ecj,2007-08-14,2007-02-13
-5ecu,2016-11-02,2015-10-20
-6ec8,2019-06-19,2018-08-07
-2ec9,2008-02-19,2007-02-13
-6ecv,2018-12-12,2018-08-08
-1ecb,1998-04-15,1997-07-15
-4ecr,2012-07-11,2012-03-26
-3ec0,2008-09-16,2008-08-28
-1ecc,1998-04-15,1997-07-09
-8ecg,2022-09-14,2022-09-01
-5ecv,2016-10-26,2015-10-20
-3ecg,2008-09-16,2008-08-29
-2ecn,2007-08-14,2007-02-13
-8ecs,2023-09-13,2022-09-02
-3ecx,2009-02-24,2008-09-02
-4eck,2013-10-02,2012-03-26
-4ec5,2012-12-05,2012-03-26
-6ecd,2018-12-12,2018-08-07
-3ecl,2009-02-24,2008-09-01
-8ec3,2023-06-07,2022-09-01
-3ecq,2008-09-09,2008-09-01
-3ecn,2008-11-25,2008-09-01
-4ecg,2012-04-11,2012-03-26
-4ecv,2012-07-11,2012-03-26
-2ecs,2008-01-08,2007-02-14
-8ec5,2023-07-26,2022-09-01
-8ecw,2023-02-22,2022-09-02
-2ecy,2008-02-26,2007-02-14
-2eco,2008-02-19,2007-02-13
-3ecm,2008-11-25,2008-09-01
-3ec8,2008-09-30,2008-08-29
-3ecz,2009-02-24,2008-09-02
-7ecc,2021-04-28,2021-03-12
-4ect,2012-07-11,2012-03-26
-6ecu,2018-12-12,2018-08-08
-1ec5,2000-07-26,2000-01-25
-6ecl,2019-08-21,2018-08-08
-5ec1,2016-04-20,2015-10-20
-2eck,1997-03-12,1996-12-16
-2eci,2008-03-18,2007-02-13
-5ecm,2016-11-02,2015-10-20
-6eci,2018-12-26,2018-08-07
-4eco,2012-05-23,2012-03-26
-4ec2,2013-01-30,2012-03-26
-4ecm,2012-04-04,2012-03-26
-5ec3,2015-11-18,2015-10-20
-7ec9,2022-03-16,2021-03-11
-3ec1,2008-10-21,2008-08-28
-4ecy,2012-07-11,2012-03-26
-1ecm,1995-12-01,1994-11-28
-6ecx,2018-12-12,2018-08-08
-2ecl,2007-08-14,2007-02-13
-3ec6,2008-09-16,2008-08-29
-4ecs,2012-07-11,2012-03-26
-7ecr,2021-12-08,2021-03-13
-1ecx,2000-03-20,2000-01-26
-5ecr,2016-11-02,2015-10-20
-6ecq,2019-03-27,2018-08-08
-7ect,2021-12-08,2021-03-13
-1ecn,1979-07-05,1979-03-07
-6ecr,2019-03-27,2018-08-08
-4ecj,2012-04-18,2012-03-26
-4ec3,2012-07-18,2012-03-26
-3ec2,2008-11-25,2008-08-28
-4ecx,2012-07-11,2012-03-26
-2ecg,2008-03-18,2007-02-13
-3ecc,2008-11-25,2008-08-29
-5ecs,2016-11-02,2015-10-20
-4ecq,2012-07-11,2012-03-26
-1ecj,1998-04-15,1997-07-16
-5ec4,2016-03-30,2015-10-20
-1ec3,2002-06-26,2000-01-25
-8ecc,2024-01-17,2022-09-01
-5eck,2016-11-02,2015-10-20
-2ecm,2007-08-14,2007-02-13
-1ecs,2001-05-02,2000-01-25
-2ect,2008-02-19,2007-02-14
-8ect,2023-09-13,2022-09-02
-8ecu,2023-09-13,2022-09-02
-7ecq,2022-04-27,2021-03-13
-1ec1,2002-06-26,2000-01-25
-5eci,2016-11-02,2015-10-20
-8eca,2023-05-31,2022-09-01
-5ecc,2016-05-18,2015-10-20
-5ec2,2016-04-20,2015-10-20
-7ec0,2021-09-29,2021-03-11
-6ece,2018-12-12,2018-08-07
-4ece,2013-02-06,2012-03-26
-8ecr,2023-09-06,2022-09-02
-2ec7,2008-02-19,2007-02-10
-1ecd,1979-07-05,1979-03-07
-1ecg,1996-11-08,1996-04-23
-2ecq,2008-02-19,2007-02-13
-5ecx,2016-05-18,2015-10-20
-2ecp,1999-06-15,1998-10-27
-6ec0,2019-05-15,2018-08-07
-6ecp,2019-03-27,2018-08-08
-5ec5,2016-05-18,2015-10-20
-1ecv,2000-03-15,2000-01-26
-5ec9,2016-03-09,2015-10-20
-8ecf,2023-03-08,2022-09-01
-2ecv,2008-02-19,2007-02-14
-5ecg,2015-12-16,2015-10-20
-3eck,2008-10-07,2008-08-31
-2ec0,2007-06-26,2007-02-09
-3ecb,2009-07-14,2008-08-29
-8ecd,2022-11-16,2022-09-01
-5ec8,2016-10-26,2015-10-20
-5m5f,2017-08-16,2016-10-21
-5m5y,2016-12-21,2016-10-23
-2m5q,2013-03-27,2013-03-04
-4m58,2014-03-26,2013-08-08
-6m5e,2020-11-18,2020-03-10
-1m5d,2002-09-18,2002-07-09
-1m5b,2002-09-18,2002-07-09
-1m5r,2002-12-11,2002-07-10
-6m5o,2021-01-20,2020-03-11
-5m5q,2017-01-11,2016-10-22
-4m54,2014-07-09,2013-08-07
-1m56,2002-08-28,2002-07-08
-3m5t,2011-05-25,2010-03-13
-1m5v,2002-10-12,2002-07-09
-1m5w,2003-07-15,2002-07-10
-4m5t,2014-04-09,2013-08-08
-7m5x,2022-03-30,2021-03-25
-5m55,2016-11-02,2016-10-20
-4m5n,2014-04-02,2013-08-08
-3m5h,2010-09-22,2010-03-12
-3m52,2010-06-09,2010-03-12
-7m5v,2022-03-30,2021-03-24
-3m58,2010-07-28,2010-03-12
-3m5l,2010-11-24,2010-03-12
-7m5z,2021-10-06,2021-03-25
-1m55,2002-08-28,2002-07-08
-5m5j,2017-05-17,2016-10-21
-5m5z,2017-05-17,2016-10-23
-4m5a,2013-08-28,2013-08-08
-5m50,2017-10-04,2016-10-20
-4m5c,2014-03-26,2013-08-08
-3m5q,2010-04-14,2010-03-12
-3m5i,2010-09-22,2010-03-12
-5m5t,2016-11-16,2016-10-22
-5m58,2017-02-15,2016-10-20
-4m5i,2014-04-02,2013-08-08
-4m5r,2013-09-18,2013-08-08
-4m55,2013-08-28,2013-08-08
-3m5n,2010-11-24,2010-03-12
-3m56,2010-07-28,2010-03-12
-6m55,2020-09-02,2020-03-10
-1m59,2003-03-18,2002-07-09
-1m57,2002-08-28,2002-07-08
-2m55,2013-05-08,2013-02-13
-3m5e,2010-10-20,2010-03-12
-1m5f,2002-09-18,2002-07-09
-5m5x,2016-12-21,2016-10-23
-3m5c,2010-07-28,2010-03-12
-4m56,2013-10-02,2013-08-08
-5m53,2016-11-09,2016-10-20
-5m56,2017-01-18,2016-10-20
-7m5c,2022-01-12,2021-03-23
-1m51,2003-09-30,2002-07-06
-2m5t,2014-03-19,2013-03-07
-6m5r,2020-10-28,2020-03-11
-6m5y,2021-03-17,2020-03-12
-5m5r,2016-11-09,2016-10-22
-2m5d,2013-10-09,2013-02-20
-1m54,2002-08-14,2002-07-08
-5m5v,2016-11-23,2016-10-22
-6m5a,2020-06-03,2020-03-10
-7m5n,2021-08-11,2021-03-24
-5m57,2016-11-23,2016-10-20
-3m59,2010-07-28,2010-03-12
-7m5o,2021-08-04,2021-03-24
-1m5q,2003-03-18,2002-07-09
-2m56,2013-08-21,2013-02-14
-3m5d,2010-07-28,2010-03-12
-6m52,2020-05-13,2020-03-09
-4m5o,2013-09-18,2013-08-08
-3m57,2010-07-28,2010-03-12
-3m51,2010-05-26,2010-03-12
-5m5c,2017-10-04,2016-10-21
-4m5b,2014-03-26,2013-08-08
-6m5m,2020-06-10,2020-03-11
-6m5u,2020-10-28,2020-03-11
-3m5k,2010-05-05,2010-03-12
-7m5y,2022-03-30,2021-03-25
-7m50,2021-12-15,2021-03-22
-1m5x,2003-06-03,2002-07-10
-1m5p,2002-10-12,2002-07-09
-5m5g,2017-01-11,2016-10-21
-4m5j,2014-04-02,2013-08-08
-4m53,2013-08-28,2013-08-07
-5m5s,2016-11-16,2016-10-22
-5m5d,2017-01-11,2016-10-21
-1m5a,2002-08-14,2002-07-09
-3m54,2010-07-28,2010-03-12
-4m5g,2014-04-02,2013-08-08
-7m5m,2021-08-11,2021-03-24
-7m57,2021-12-15,2021-03-22
-3m5o,2010-11-24,2010-03-12
-3m5j,2010-09-22,2010-03-12
-2m5r,2014-09-17,2013-03-07
-5m51,2016-11-09,2016-10-20
-3m5s,2011-05-25,2010-03-13
-1m52,2002-09-18,2002-07-08
-7m54,2021-12-15,2021-03-22
-5m5b,2016-12-28,2016-10-21
-4m5h,2014-04-02,2013-08-08
-1m5e,2002-09-18,2002-07-09
-5m5u,2016-11-23,2016-10-22
-3m5g,2010-09-22,2010-03-12
-6m5x,2020-12-30,2020-03-12
-3m55,2010-07-28,2010-03-12
-1m5c,2002-09-18,2002-07-09
-4m5f,2014-04-23,2013-08-08
-1m5k,2002-08-02,2002-07-09
-4m5m,2014-04-02,2013-08-08
-7m56,2022-03-30,2021-03-22
-2m5e,2014-07-23,2013-02-21
-5m54,2017-10-04,2016-10-20
-2m5p,2013-03-27,2013-03-03
-3m53,2010-07-28,2010-03-12
-6m5z,2021-01-20,2020-03-12
-4m5l,2014-04-02,2013-08-08
-6m54,2020-05-13,2020-03-09
-6m5w,2021-01-20,2020-03-11
-6m5q,2021-01-20,2020-03-11
-5m5e,2017-05-03,2016-10-21
-5m5k,2017-05-10,2016-10-21
-7m5l,2021-08-11,2021-03-24
-4m5k,2014-04-02,2013-08-08
-3m5p,2010-03-23,2010-03-12
-6m5g,2020-05-20,2020-03-10
-1m5h,2002-07-26,2002-07-09
-5m5a,2017-12-06,2016-10-21
-3m5m,2010-11-24,2010-03-12
-3m50,2010-05-26,2010-03-12
-7m5u,2021-09-01,2021-03-24
-7m5e,2021-05-26,2021-03-23
-6m5v,2020-10-28,2020-03-11
-7m5b,2022-01-12,2021-03-23
-2m5c,2013-10-09,2013-02-20
-4m51,2013-09-04,2013-08-07
-4m52,2013-11-27,2013-08-07
-6m5s,2020-10-28,2020-03-11
-3m5a,2010-07-28,2010-03-12
-7m5d,2022-10-19,2021-03-23
-4m5q,2013-09-18,2013-08-08
-4m5u,2013-09-25,2013-08-08
-4m5p,2014-06-25,2013-08-08
-5m5w,2016-12-07,2016-10-23
-6m5p,2021-01-20,2020-03-11
-4m5v,2013-09-18,2013-08-08
-6m53,2020-07-15,2020-03-09
-4m5e,2014-04-23,2013-08-08
-1m5o,2002-10-12,2002-07-09
-7dm6,2022-02-02,2020-12-02
-1dm8,2000-12-13,1999-12-13
-5dm2,2015-09-23,2015-09-07
-1dma,1995-09-15,1995-04-28
-3dmk,2008-10-07,2008-07-01
-5dmy,2016-10-05,2015-09-09
-5dmu,2015-10-07,2015-09-09
-5dmh,2015-10-28,2015-09-08
-3dm0,2008-09-09,2008-06-30
-8dmr,2023-07-12,2022-07-08
-8dm0,2022-08-31,2022-07-08
-1dms,1998-07-01,1996-09-03
-8dml,2023-06-14,2022-07-08
-5dmc,2016-05-04,2015-09-08
-3dmm,2009-07-14,2008-07-01
-5dmf,2016-05-04,2015-09-08
-4dm3,2012-04-25,2012-02-06
-1dmf,1995-02-07,1994-11-22
-2dmj,2007-04-24,2006-04-21
-8dmt,2023-08-02,2022-07-08
-1dmb,1993-10-31,1993-06-10
-7dmr,2020-12-16,2020-12-06
-4dma,2012-03-07,2012-02-07
-6dm1,2018-08-22,2018-06-04
-2dmr,1998-03-18,1997-04-24
-6dml,2018-12-19,2018-06-05
-7dmz,2021-12-08,2020-12-08
-8dmk,2023-02-01,2022-07-08
-8dm4,2023-01-25,2022-07-08
-4dmw,2012-07-18,2012-02-08
-1dm6,2000-12-13,1999-12-13
-1dmt,2000-12-20,1999-12-15
-5dmv,2015-10-28,2015-09-09
-5dm6,2015-11-11,2015-09-08
-1dm5,2000-03-20,1999-12-13
-8dm2,2023-01-25,2022-07-08
-3dm2,2008-08-12,2008-06-30
-4dm0,2012-02-22,2012-02-06
-6dm8,2018-08-01,2018-06-04
-3dmo,2008-07-15,2008-07-01
-8dmq,2023-07-12,2022-07-08
-6dmf,2019-05-29,2018-06-05
-1dmj,2000-12-20,1999-12-14
-6dm0,2018-08-22,2018-06-04
-3dm5,2008-11-04,2008-06-30
-8dmg,2023-07-19,2022-07-08
-5dmm,2015-11-25,2015-09-09
-1dm7,2000-12-13,1999-12-13
-1dm3,2001-08-29,1999-12-13
-7dmg,2022-04-06,2020-12-03
-1dmk,2000-12-20,1999-12-14
-4dmr,1998-03-18,1997-04-30
-8dmf,2023-01-04,2022-07-08
-6dmk,2018-12-19,2018-06-05
-8dmm,2022-12-14,2022-07-08
-1dm1,2000-06-21,1999-12-13
-5dm7,2015-11-11,2015-09-08
-8dm9,2023-02-08,2022-07-08
-6dmb,2018-07-11,2018-06-04
-3dmt,2008-10-21,2008-07-01
-5dm0,2015-09-23,2015-09-07
-1dmw,2000-03-24,1999-12-15
-7dmb,2021-02-10,2020-12-03
-8dma,2023-02-08,2022-07-08
-3dmf,2008-07-29,2008-07-01
-8dm3,2023-01-25,2022-07-08
-4dmi,2012-08-29,2012-02-07
-6dmo,2018-07-11,2018-06-05
-3dmj,2008-08-12,2008-07-01
-1dmu,1999-12-18,1999-12-15
-6dmu,2018-10-24,2018-06-05
-8dmi,2023-04-12,2022-07-08
-8dm1,2023-01-25,2022-07-08
-6dmn,2018-08-15,2018-06-05
-1dmp,1997-11-12,1996-11-01
-5dm9,2016-04-13,2015-09-08
-4dmm,2012-02-22,2012-02-08
-6dmi,2018-12-19,2018-06-05
-5dm4,2015-09-23,2015-09-07
-5dmz,2015-12-16,2015-09-09
-4dmn,2012-03-21,2012-02-08
-3dme,2008-08-26,2008-06-30
-8dmu,2023-07-12,2022-07-08
-4dm8,2012-03-07,2012-02-07
-6dmv,2018-08-15,2018-06-05
-8dm8,2023-02-08,2022-07-08
-5dm1,2015-09-23,2015-09-07
-6dmg,2018-12-19,2018-06-05
-3dmi,2009-03-17,2008-07-01
-5dm3,2015-09-16,2015-09-07
-6dmj,2018-12-19,2018-06-05
-8dm6,2023-02-08,2022-07-08
-3dm3,2008-08-26,2008-06-30
-3dmh,2008-07-29,2008-07-01
-1dm2,2000-05-31,1999-12-13
-4dmz,2012-05-23,2012-02-08
-2dm5,2006-10-17,2006-04-20
-5dmg,2015-12-16,2015-09-08
-4dmx,2012-07-11,2012-02-08
-7dmu,2020-12-23,2020-12-07
-4dmy,2012-07-11,2012-02-08
-2dm6,2006-11-28,2006-04-20
-7dm0,2021-12-15,2020-12-01
-1dmy,1996-04-03,1995-10-04
-7dmm,2021-12-08,2020-12-04
-8dmy,2023-04-12,2022-07-09
-2dmd,2006-10-21,2006-04-21
-3dm6,2008-12-16,2008-06-30
-4dmg,2012-06-27,2012-02-07
-3dmz,2008-11-11,2008-07-01
-7dm5,2022-02-02,2020-12-02
-8dm5,2023-02-08,2022-07-08
-6dm4,2018-06-27,2018-06-04
-6dmy,2018-07-11,2018-06-05
-3dmr,1998-03-18,1997-04-25
-8dmd,2023-05-17,2022-07-08
-4dmo,2013-06-26,2012-02-08
-5dmp,2015-10-07,2015-09-09
-1dmc,1995-02-07,1994-11-22
-8dmx,2023-04-12,2022-07-08
-4dm9,2012-05-23,2012-02-07
-3dmg,2008-07-29,2008-07-01
-5dms,2015-10-28,2015-09-09
-8dmh,2023-04-12,2022-07-08
-1dmd,1995-02-07,1994-11-22
-6dmw,2018-10-24,2018-06-05
-5dmj,2016-06-01,2015-09-08
-8dms,2023-07-12,2022-07-08
-3dm1,2008-08-19,2008-06-30
-7dml,2021-12-15,2020-12-04
-8dm7,2023-02-08,2022-07-08
-6dms,2018-10-03,2018-06-05
-7dmc,2021-12-08,2020-12-03
-6dmh,2018-12-19,2018-06-05
-1dme,1995-02-07,1994-11-22
-2dmi,2006-10-21,2006-04-21
-1dmx,1996-04-03,1995-10-04
-7dmy,2021-10-20,2020-12-08
-8dme,2023-07-19,2022-07-08
-1dmh,2000-05-23,1999-12-14
-6dm6,2019-06-12,2018-06-04
-4dmb,2012-04-04,2012-02-07
-4dm6,2012-03-07,2012-02-07
-1dmi,2000-12-20,1999-12-14
-1dmr,1998-03-18,1997-04-22
-7dmk,2021-10-06,2020-12-04
-1u32,2004-08-17,2004-07-20
-4u3s,2015-07-29,2014-07-22
-6u3j,2020-07-22,2019-08-21
-3u3a,2012-10-10,2011-10-05
-8u3z,2024-05-29,2023-09-08
-1u3u,2004-10-26,2004-07-23
-3u3e,2012-11-28,2011-10-05
-7u30,2022-06-01,2022-02-25
-3u3j,2011-11-16,2011-10-06
-1u33,2004-09-07,2004-07-20
-5u3a,2017-12-06,2016-12-01
-1u3d,2004-08-24,2004-07-21
-1u3w,2004-10-26,2004-07-23
-7u3h,2022-10-05,2022-02-27
-4u3m,2014-10-22,2014-07-22
-7u36,2022-04-27,2022-02-25
-5u3u,2017-03-22,2016-12-03
-8u3b,2024-01-17,2023-09-07
-4u3z,2016-01-06,2014-07-23
-3u31,2011-11-09,2011-10-04
-7u3d,2022-10-05,2022-02-27
-1u3v,2004-10-26,2004-07-23
-6u3m,2019-12-18,2019-08-22
-8u3a,2024-05-08,2023-09-07
-3u3r,2011-11-16,2011-10-06
-6u36,2019-11-06,2019-08-21
-1u30,2004-09-07,2004-07-20
-5u3e,2017-08-23,2016-12-02
-6u3b,2020-02-19,2019-08-21
-3u3h,2011-10-26,2011-10-05
-6u38,2019-11-06,2019-08-21
-8u3h,2024-05-29,2023-09-07
-1u3e,2004-08-31,2004-07-21
-7u34,2022-08-17,2022-02-25
-1u3c,2004-08-24,2004-07-21
-5u3x,2017-03-22,2016-12-03
-4u3b,2014-10-01,2014-07-19
-1u3g,2004-12-07,2004-07-21
-5u30,2017-01-25,2016-12-01
-5u3w,2017-03-22,2016-12-03
-4u30,2014-10-15,2014-07-18
-7u3m,2022-04-06,2022-02-27
-7u3k,2022-10-05,2022-02-27
-5u32,2017-11-15,2016-12-01
-3u39,2012-03-28,2011-10-05
-7u3e,2022-10-05,2022-02-27
-6u3p,2020-02-12,2019-08-22
-8u36,2023-11-22,2023-09-07
-8u30,2024-05-08,2023-09-06
-4u31,2015-07-22,2014-07-18
-3u3n,2012-02-15,2011-10-06
-7u3l,2022-10-05,2022-02-27
-4u3u,2014-10-22,2014-07-22
-1u3l,2004-08-31,2004-07-22
-1u31,2005-01-25,2004-07-20
-6u37,2020-02-12,2019-08-21
-6u3n,2019-12-18,2019-08-22
-1u38,2005-07-26,2004-07-21
-6u3o,2019-12-18,2019-08-22
-4u3f,2015-07-29,2014-07-21
-6u33,2020-03-25,2019-08-21
-6u3e,2019-09-25,2019-08-21
-5u3t,2017-03-22,2016-12-03
-7u3b,2022-10-05,2022-02-26
-5u3q,2017-03-22,2016-12-03
-4u32,2014-10-15,2014-07-18
-6u32,2020-09-30,2019-08-21
-7u31,2022-04-27,2022-02-25
-7u35,2022-03-09,2022-02-25
-8u3l,2024-05-08,2023-09-07
-6u3d,2020-02-19,2019-08-21
-4u3e,2014-09-03,2014-07-20
-8u3n,2024-01-10,2023-09-08
-5u3b,2017-06-07,2016-12-01
-5u31,2017-01-25,2016-12-01
-3u3z,2012-07-25,2011-10-06
-5u3i,2017-02-22,2016-12-02
-7u3a,2022-10-05,2022-02-26
-8u3y,2024-05-01,2023-09-08
-4u3j,2014-08-20,2014-07-22
-3u3w,2013-01-09,2011-10-06
-6u30,2020-02-19,2019-08-21
-4u3d,2014-10-01,2014-07-19
-5u3s,2017-03-22,2016-12-03
-7u3j,2022-10-05,2022-02-27
-6u3x,2019-11-06,2019-08-22
-5u3k,2017-02-15,2016-12-02
-6u3g,2019-09-25,2019-08-21
-4u3n,2014-10-22,2014-07-22
-1u3s,2005-07-26,2004-07-22
-5u3d,2018-03-14,2016-12-01
-8u37,2024-01-24,2023-09-07
-8u3j,2024-05-08,2023-09-07
-8u3g,2024-05-29,2023-09-07
-5u3c,2017-04-26,2016-12-01
-5u38,2017-10-04,2016-12-01
-5u39,2017-06-07,2016-12-01
-5u3r,2017-03-22,2016-12-03
-3u3l,2012-02-15,2011-10-06
-3u3m,2011-11-16,2011-10-06
-6u3i,2020-02-05,2019-08-21
-1u3i,2005-07-26,2004-07-22
-7u32,2022-05-11,2022-02-25
-5u3y,2017-03-22,2016-12-03
-3u33,2011-11-02,2011-10-04
-5u3f,2017-03-22,2016-12-02
-7u33,2022-04-27,2022-02-25
-8u3c,2024-05-08,2023-09-07
-6u3k,2020-02-19,2019-08-21
-6u39,2020-02-19,2019-08-21
-7u3i,2022-10-05,2022-02-27
-6u3u,2020-07-01,2019-08-22
-3u3k,2011-11-16,2011-10-06
-1u3p,2004-08-31,2004-07-22
-3u3y,2011-12-28,2011-10-06
-1u3r,2005-07-26,2004-07-22
-6u31,2020-08-26,2019-08-21
-4u3w,2014-07-30,2014-07-23
-6u34,2020-02-12,2019-08-21
-7u3g,2022-10-05,2022-02-27
-6u3a,2020-02-19,2019-08-21
-4u3c,2015-07-22,2014-07-19
-7u3f,2022-10-05,2022-02-27
-5u35,2017-01-25,2016-12-01
-3u3u,2012-02-15,2011-10-06
-6u3z,2019-11-20,2019-08-22
-3u3o,2011-11-16,2011-10-06
-5u3z,2017-03-22,2016-12-03
-4u36,2014-12-31,2014-07-18
-3u3d,2011-11-09,2011-10-05
-5u3v,2017-03-22,2016-12-03
-4u33,2015-07-22,2014-07-18
-1u3t,2004-10-26,2004-07-23
-1u3f,2004-12-07,2004-07-21
-1u3q,2005-07-26,2004-07-22
-3u32,2012-02-08,2011-10-04
-1ncr,2003-12-16,2002-12-05
-6nc2,2019-06-19,2018-12-10
-6nc9,2019-04-17,2018-12-11
-4ncg,2014-02-12,2013-10-24
-3ncg,2010-07-21,2010-06-04
-5nc3,2018-03-21,2017-03-03
-4ncs,2013-12-25,2013-10-25
-5ncv,2018-03-14,2017-03-06
-1nc2,2003-12-16,2002-12-04
-6ncr,2018-12-26,2018-12-12
-3ncq,2010-07-28,2010-06-05
-1ncg,1995-07-10,1995-03-23
-1ncq,2003-12-16,2002-12-05
-4ncl,2014-07-09,2013-10-24
-1nc8,1999-05-25,1998-05-14
-5ncn,2018-05-16,2017-03-06
-1nca,1994-01-31,1992-01-21
-1nc3,2003-03-25,2002-12-04
-4ncn,2014-07-09,2013-10-24
-7ncv,2021-05-26,2021-01-29
-4ncj,2014-03-05,2013-10-24
-4nce,2014-07-30,2013-10-24
-5nc9,2018-02-21,2017-03-03
-5ncq,2018-01-10,2017-03-06
-6ncz,2019-02-20,2018-12-12
-1nc6,2003-09-23,2002-12-04
-4ncr,2014-02-19,2013-10-25
-3ncc,2010-09-29,2010-06-04
-3nc2,2010-12-22,2010-06-04
-5nc5,2017-04-12,2017-03-03
-5nci,2017-10-04,2017-03-05
-3ncf,2010-09-29,2010-06-04
-4ncm,2014-07-30,2013-10-24
-3nck,2011-12-14,2010-06-04
-3nc9,2010-12-22,2010-06-04
-7ncx,2021-09-08,2021-01-29
-5ncb,2018-07-04,2017-03-03
-5ncw,2017-05-24,2017-03-06
-6ncm,2019-02-27,2018-12-11
-6nc4,2019-10-23,2018-12-10
-7ncp,2021-05-12,2021-01-29
-5nc6,2018-02-21,2017-03-03
-7ncz,2022-03-02,2021-01-29
-3nc8,2011-12-14,2010-06-04
-4nc8,2014-07-02,2013-10-24
-6nca,2019-10-23,2018-12-11
-5nco,2017-05-24,2017-03-06
-1ncy,1997-01-11,1996-06-02
-1nc1,2003-11-25,2002-12-04
-5ncm,2018-05-16,2017-03-06
-4nco,2013-11-13,2013-10-24
-1nc7,2003-07-01,2002-12-04
-1ncb,1994-01-31,1992-01-21
-5ncg,2018-03-21,2017-03-04
-4ncw,2014-03-12,2013-10-25
-5nc4,2018-03-21,2017-03-03
-4nc4,2016-10-26,2013-10-23
-4nc5,2013-11-06,2013-10-24
-5nc0,2018-01-10,2017-03-02
-3nc0,2010-10-27,2010-06-04
-6ncx,2019-02-20,2018-12-12
-3nc3,2010-08-11,2010-06-04
-3nce,2010-09-29,2010-06-04
-6ncy,2019-02-20,2018-12-12
-5nc2,2018-03-21,2017-03-03
-5nct,2017-05-24,2017-03-06
-6ncj,2019-01-16,2018-12-11
-4nct,2015-04-01,2013-10-25
-3ncu,2010-06-30,2010-06-05
-3ncl,2011-02-16,2010-06-04
-1ncj,1999-03-18,1999-02-02
-4nc7,2014-07-02,2013-10-24
-7ncu,2021-05-12,2021-01-29
-6nch,2019-02-06,2018-12-11
-3nc6,2010-08-11,2010-06-04
-6ncp,2019-06-19,2018-12-11
-4nck,2014-03-05,2013-10-24
-4ncf,2014-07-09,2013-10-24
-1ncz,1996-12-07,1996-06-02
-3nci,2011-02-02,2010-06-04
-2ncd,1999-06-09,1999-06-04
-5ncp,2018-03-28,2017-03-06
-6nck,2019-02-06,2018-12-11
-7nc4,2021-07-14,2021-01-28
-6nco,2019-04-17,2018-12-11
-5ncj,2017-10-04,2017-03-05
-7ncf,2021-03-03,2021-01-28
-3ncr,2010-07-28,2010-06-05
-6ncs,2018-12-26,2018-12-12
-6nc5,2019-12-25,2018-12-10
-4ncb,2014-01-15,2013-10-24
-3nc5,2010-08-11,2010-06-04
-1nc9,2003-09-02,2002-12-05
-7ncy,2022-03-02,2021-01-29
-1ncs,1996-06-10,1996-02-26
-1ncp,1993-10-31,1991-11-27
-7nc5,2021-05-12,2021-01-28
-6nc3,2019-06-19,2018-12-10
-5nc8,2017-04-12,2017-03-03
-6nce,2019-02-27,2018-12-11
-1ncd,1994-01-31,1992-01-21
-5ncu,2017-05-24,2017-03-06
-3nc1,2010-10-27,2010-06-04
-3ncz,2010-12-08,2010-06-06
-6ncf,2020-05-13,2018-12-11
-1nc4,2003-12-16,2002-12-04
-6nc6,2019-04-17,2018-12-10
-4ncz,2013-11-06,2013-10-25
-3ncj,2010-08-18,2010-06-04
-5ncf,2017-06-14,2017-03-04
-5ncd,2018-02-21,2017-03-03
-2nc3,2016-06-08,2016-03-20
-2nc4,2016-06-08,2016-03-20
-2nc6,2016-06-08,2016-03-20
-1nco,1993-10-31,1993-07-13
-2nce,2017-03-29,2016-03-28
-3nc7,2010-08-11,2010-06-04
-3nca,2010-12-22,2010-06-04
-7ncd,2021-05-12,2021-01-28
-4nca,2014-01-15,2013-10-24
-5ncl,2018-05-16,2017-03-06
-6nci,2019-02-06,2018-12-11
-4ncy,2014-04-09,2013-10-25
-5ncz,2017-06-21,2017-03-06
-3nc4,2011-01-05,2010-06-04
-6nc8,2019-04-17,2018-12-11
-5ncc,2017-08-30,2017-03-03
-2nc5,2016-06-08,2016-03-20
-6nc1,2019-10-23,2018-12-10
-4nc3,2013-12-18,2013-10-23
-1nce,2002-12-25,2002-12-05
-3ncb,2010-09-29,2010-06-04
-1nch,1995-07-10,1995-03-23
-6ncn,2019-04-17,2018-12-11
-1ncc,1994-01-31,1992-01-21
-5nc1,2018-03-14,2017-03-03
-1ncx,1996-12-07,1996-06-02
-6ncg,2019-01-16,2018-12-11
-5ncy,2017-06-21,2017-03-06
-7nc6,2021-05-12,2021-01-28
-5nc7,2018-03-21,2017-03-03
-2qb3,2007-12-04,2007-06-15
-3qbj,2012-01-25,2011-01-13
-2qb6,2007-12-11,2007-06-16
-5qbi,2020-04-22,2017-08-04
-4qbt,2014-12-17,2014-05-08
-1qbo,2000-05-03,1999-04-26
-2qbw,2008-04-22,2007-06-18
-4qbo,2014-09-10,2014-05-08
-6qbs,2019-02-06,2018-12-21
-5qba,2020-04-22,2017-08-04
-8qbk,2024-06-05,2023-08-24
-2qbo,2007-12-25,2007-06-18
-5qb0,2018-01-10,2017-07-11
-4qbq,2015-05-13,2014-05-08
-1qbk,1999-06-01,1999-04-23
-7qbz,2022-03-23,2021-11-21
-5qbf,2020-04-22,2017-08-04
-5qbb,2020-04-22,2017-08-04
-2qbp,2008-03-18,2007-06-18
-3qbd,2012-01-18,2011-01-13
-5qbk,2020-04-22,2017-08-04
-4qbg,2014-06-25,2014-05-08
-4qbz,2014-10-22,2014-05-09
-6qbw,2020-09-30,2018-12-21
-2qbx,2007-11-06,2007-06-18
-2qb2,2007-12-04,2007-06-15
-4qbi,2014-06-25,2014-05-08
-5qbo,2020-04-22,2017-08-04
-3qb5,2011-05-11,2011-01-12
-1qbs,1997-10-15,1997-04-25
-5qbs,2020-04-22,2017-08-04
-1qbu,1997-10-15,1997-04-25
-5qb3,2018-01-10,2017-07-11
-5qb8,2020-04-22,2017-08-04
-7qbk,2022-04-06,2021-11-19
-1qbi,2000-02-25,1999-04-22
-2qbl,2007-12-25,2007-06-18
-7qba,2022-08-03,2021-11-18
-7qbs,2022-02-02,2021-11-19
-3qbi,2011-08-31,2011-01-13
-3qbx,2011-02-02,2011-01-14
-3qbf,2012-01-18,2011-01-13
-6qbb,2020-01-29,2018-12-20
-8qb3,2023-12-27,2023-08-24
-1qbg,2000-04-24,1999-04-20
-7qbb,2022-02-23,2021-11-18
-3qbn,2012-01-18,2011-01-13
-4qbl,2014-09-10,2014-05-08
-2qbu,2008-04-15,2007-06-18
-1qbv,1999-10-27,1999-04-27
-6qbt,2020-09-30,2018-12-21
-4qb3,2015-04-22,2014-05-06
-4qbm,2014-05-21,2014-05-08
-5qb5,2020-04-22,2017-08-04
-3qbl,2011-08-31,2011-01-13
-5qb2,2018-01-10,2017-07-11
-7qbd,2022-03-16,2021-11-19
-7qb6,2022-10-26,2021-11-18
-5qbt,2020-04-22,2017-08-04
-2qbq,2008-03-18,2007-06-18
-5qbn,2020-04-22,2017-08-04
-7qbv,2022-02-02,2021-11-19
-3qbv,2012-02-08,2011-01-14
-2qb4,2007-08-21,2007-06-15
-7qbu,2022-02-02,2021-11-19
-6qbu,2020-04-08,2018-12-21
-5qbr,2020-04-22,2017-08-04
-7qbo,2022-01-26,2021-11-19
-1qb4,2002-05-01,1999-04-30
-5qbz,2017-12-20,2017-08-04
-7qbg,2022-03-16,2021-11-19
-8qbn,2024-05-15,2023-08-24
-4qb2,2014-10-08,2014-05-06
-3qb0,2011-05-04,2011-01-12
-6qb5,2019-02-06,2018-12-20
-3qbc,2012-01-25,2011-01-12
-8qbt,2024-03-20,2023-08-25
-1qbb,1997-02-12,1996-06-07
-7qbp,2022-04-06,2021-11-19
-3qbo,2011-02-09,2011-01-13
-3qbw,2011-02-02,2011-01-14
-7qb2,2022-11-30,2021-11-18
-3qb9,2012-02-08,2011-01-12
-3qbh,2011-03-23,2011-01-13
-1qb1,2000-04-29,1999-04-28
-4qbb,2014-11-05,2014-05-07
-6qbe,2019-08-28,2018-12-21
-3qbg,2011-08-31,2011-01-13
-1qbt,1997-10-15,1997-04-25
-3qbt,2011-03-23,2011-01-14
-5qb4,2018-01-10,2017-07-11
-1qbh,1999-10-20,1999-04-20
-7qbm,2022-01-26,2021-11-19
-5qb7,2020-04-22,2017-08-04
-7qbn,2022-01-26,2021-11-19
-2qbr,2008-03-18,2007-06-18
-7qbl,2022-01-26,2021-11-19
-3qbe,2012-01-18,2011-01-13
-6qbf,2019-11-27,2018-12-21
-5qbv,2017-12-20,2017-08-04
-4qb6,2014-10-08,2014-05-06
-1qbq,1999-06-18,1999-04-27
-2qb0,2008-10-14,2007-06-15
-2qbm,2007-12-25,2007-06-18
-2qby,2007-09-11,2007-06-18
-6qb8,2019-07-03,2018-12-20
-5qbd,2020-04-22,2017-08-04
-5qbu,2017-12-20,2017-08-04
-8qbu,2023-12-06,2023-08-25
-3qbk,2011-08-31,2011-01-13
-3qb3,2012-01-18,2011-01-12
-5qbx,2017-12-20,2017-08-04
-4qb1,2014-10-08,2014-05-06
-1qb7,1999-07-21,1999-04-30
-6qbv,2020-09-30,2018-12-21
-4qbs,2015-05-13,2014-05-08
-6qbg,2020-01-29,2018-12-21
-2qbn,2007-12-25,2007-06-18
-5qbe,2020-04-22,2017-08-04
-5qbm,2020-04-22,2017-08-04
-7qbe,2022-03-16,2021-11-19
-8qbl,2024-06-05,2023-08-24
-5qbw,2017-12-20,2017-08-04
-8qba,2023-12-13,2023-08-24
-7qb1,2022-05-04,2021-11-17
-7qb0,2022-11-30,2021-11-17
-4qby,2014-06-18,2014-05-09
-8qbm,2024-06-05,2023-08-24
-5qbp,2020-04-22,2017-08-04
-7qbi,2022-03-16,2021-11-19
-7qbt,2022-02-02,2021-11-19
-7qb5,2022-05-18,2021-11-18
-8qbc,2023-12-13,2023-08-24
-7qb9,2022-03-16,2021-11-18
-5qbg,2020-04-22,2017-08-04
-7qbf,2022-03-16,2021-11-19
-7qbc,2022-03-16,2021-11-18
-3qbu,2011-05-25,2011-01-14
-4qbh,2014-06-25,2014-05-08
-4qbk,2014-05-28,2014-05-08
-1qbj,1999-07-02,1999-04-22
-2qb8,2007-12-11,2007-06-16
-5qbc,2020-04-22,2017-08-04
-5qbj,2020-04-22,2017-08-04
-5qbq,2020-04-22,2017-08-04
-6qbx,2019-08-21,2018-12-24
-4qbr,2015-05-13,2014-05-08
-1qbz,1999-05-17,1999-04-28
-5qb6,2020-04-22,2017-08-04
-8qb1,2024-02-28,2023-08-23
-3qb7,2012-04-25,2011-01-12
-1qb8,1999-07-21,1999-04-30
-5qb9,2020-04-22,2017-08-04
-5qbl,2020-04-22,2017-08-04
-3qb8,2012-01-25,2011-01-12
-4qb8,2014-08-20,2014-05-06
-6qba,2020-06-03,2018-12-20
-4qbj,2015-04-01,2014-05-08
-1qbr,1997-10-15,1997-04-25
-7qb7,2021-12-08,2021-11-18
-6qbd,2019-08-28,2018-12-21
-2qb7,2007-12-11,2007-06-16
-5qbh,2020-04-22,2017-08-04
-5qb1,2018-01-10,2017-07-11
-6qb4,2019-11-06,2018-12-20
-7qbq,2022-11-30,2021-11-19
-3qbm,2011-02-02,2011-01-13
-1qb9,2000-04-30,1999-04-30
-1qb6,2000-04-29,1999-04-29
-4qb9,2015-04-01,2014-05-06
-4qbf,2014-06-25,2014-05-08
-1qbn,2000-05-03,1999-04-25
-2qbs,2008-03-18,2007-06-18
-4qbx,2015-07-22,2014-05-09
-2qb5,2007-07-03,2007-06-15
-5qby,2017-12-20,2017-08-04
-8qbh,2024-03-13,2023-08-24
-7qb4,2022-04-06,2021-11-18
-3qby,2011-02-09,2011-01-14
-7qbh,2022-03-16,2021-11-19
-7qbr,2022-11-30,2021-11-19
-6qbh,2020-01-29,2018-12-21
-2qbt,2007-09-04,2007-06-18
-4mh1,2014-07-23,2013-08-29
-4mh0,2014-09-03,2013-08-29
-7mh8,2021-12-29,2021-04-14
-4mh5,2013-10-16,2013-08-29
-7mhd,2022-04-20,2021-04-15
-8mht,1998-11-30,1998-08-06
-1mht,1995-06-03,1994-12-08
-3mhf,2010-04-28,2010-04-07
-3mho,2010-10-20,2010-04-08
-3mhm,2010-10-20,2010-04-08
-7mhz,2021-06-16,2021-04-16
-1mhp,2003-04-15,2002-08-20
-4mhf,2013-09-18,2013-08-29
-7mhq,2021-05-12,2021-04-15
-3mhb,2011-03-23,2010-04-07
-7mhy,2021-06-16,2021-04-16
-5mhg,2018-08-08,2016-11-24
-1mh0,2002-11-08,2002-08-18
-5mh1,2017-12-27,2016-11-22
-6mhd,2019-02-20,2018-09-17
-3mh5,2010-06-30,2010-04-07
-7mhb,2021-04-28,2021-04-15
-7mha,2022-04-27,2021-04-14
-7mh3,2021-12-29,2021-04-14
-3mhz,2010-08-11,2010-04-09
-5mh6,2018-06-06,2016-11-23
-7mh7,2021-04-21,2021-04-14
-1mhy,1997-05-15,1996-10-21
-2mhb,1983-01-20,1977-02-14
-1mh9,2002-10-30,2002-08-19
-5mho,2017-12-20,2016-11-24
-6mhm,2019-01-23,2018-09-18
-5mhe,2018-08-08,2016-11-24
-7mhf,2021-05-12,2021-04-15
-6mh8,2019-04-24,2018-09-17
-4mhv,2013-09-25,2013-08-30
-7mhp,2021-05-12,2021-04-15
-2mhm,2014-10-29,2013-11-26
-5mhj,2017-05-24,2016-11-24
-4mho,2014-07-23,2013-08-30
-7mhm,2021-05-12,2021-04-15
-6mhu,2019-04-03,2018-09-18
-6mh1,2019-08-07,2018-09-17
-5mhi,2017-12-20,2016-11-24
-7mhh,2021-05-12,2021-04-15
-1mh1,1998-01-21,1997-01-21
-7mhn,2021-05-12,2021-04-15
-5mhy,2017-05-10,2016-11-27
-7mhc,2022-04-06,2021-04-15
-6mh5,2020-03-18,2018-09-17
-4mht,1997-01-27,1996-07-24
-4mh7,2014-05-21,2013-08-29
-5mha,2018-05-09,2016-11-23
-2mha,1993-10-31,1993-07-21
-1mhe,1999-03-23,1998-08-24
-6mhb,2019-02-20,2018-09-17
-2mhu,1991-04-15,1990-05-14
-7mh9,2021-12-29,2021-04-14
-3mht,1997-01-27,1996-07-24
-7mhx,2022-03-23,2021-04-15
-2mh5,2014-03-05,2013-11-18
-7mh5,2021-12-29,2021-04-14
-4mhw,2014-09-03,2013-08-30
-5mh4,2017-04-12,2016-11-23
-5mh5,2018-05-02,2016-11-23
-5mht,1997-07-23,1996-10-22
-5mhu,2017-05-10,2016-11-25
-2mho,2014-03-12,2013-11-29
-3mhw,2010-04-21,2010-04-09
-4mha,2014-05-21,2013-08-29
-7mhe,2022-04-20,2021-04-15
-3mhx,2010-06-23,2010-04-09
-1mhc,1996-01-29,1995-08-23
-4mhu,2014-09-03,2013-08-30
-7mh4,2021-12-29,2021-04-14
-3mhj,2010-05-05,2010-04-08
-3mhr,2010-09-15,2010-04-08
-7mhi,2021-05-12,2021-04-15
-4mhi,2013-10-02,2013-08-29
-3mh6,2010-06-30,2010-04-07
-5mhc,2017-10-04,2016-11-24
-1mhl,1996-01-06,1995-06-09
-6mh0,2018-10-03,2018-09-16
-3mhc,2010-07-21,2010-04-07
-7mh1,2021-10-13,2021-04-14
-6mhe,2019-07-31,2018-09-17
-7mhs,2022-05-11,2021-04-15
-7mhj,2021-05-12,2021-04-15
-6mht,1998-08-12,1998-08-05
-5mhf,2017-12-20,2016-11-24
-3mhk,2010-05-05,2010-04-08
-5mhm,2017-12-20,2016-11-24
-7mho,2021-05-12,2021-04-15
-4mhj,2013-10-02,2013-08-29
-1mhz,1997-05-15,1996-10-21
-7mhk,2021-05-12,2021-04-15
-6mh7,2019-08-07,2018-09-17
-5mhx,2017-05-10,2016-11-26
-6mhi,2019-05-29,2018-09-18
-4mhz,2014-03-12,2013-08-30
-5mhb,2016-12-07,2016-11-23
-6mhn,2019-05-29,2018-09-18
-3mhi,2010-10-20,2010-04-08
-3mhu,2011-02-23,2010-04-08
-4mhn,2014-03-12,2013-08-30
-6mhf,2019-07-31,2018-09-17
-7mht,1998-11-30,1998-08-05
-1mhw,2002-12-11,2002-08-21
-9mht,1998-12-01,1998-08-07
-4mhs,2014-07-23,2013-08-30
-6mha,2019-09-25,2018-09-17
-7mhl,2021-05-12,2021-04-15
-1mho,1998-11-18,1997-09-11
-7mh0,2021-10-13,2021-04-14
-7mhr,2022-03-23,2021-04-15
-4mhx,2014-05-14,2013-08-30
-5mhw,2017-05-10,2016-11-26
-3mhl,2010-10-20,2010-04-08
-3mhp,2010-10-27,2010-04-08
-1mhu,1991-04-15,1990-05-14
-5mhq,2017-12-20,2016-11-25
-4mhq,2014-09-03,2013-08-30
-6mhz,2019-04-03,2018-09-18
-5mhn,2017-12-20,2016-11-24
-5mhl,2017-12-20,2016-11-24
-3mhh,2010-04-21,2010-04-08
-3mhs,2010-04-21,2010-04-08
-6mhc,2019-02-20,2018-09-17
-3mhy,2010-06-09,2010-04-09
-6mh6,2019-04-24,2018-09-17
-4mhy,2014-03-12,2013-08-30
-5mhz,2017-05-10,2016-11-27
-7mhg,2021-05-12,2021-04-15
-4mhh,2013-10-02,2013-08-29
-3mhg,2010-04-28,2010-04-07
-1mh5,2003-09-23,2002-08-19
-6mhr,2018-11-21,2018-09-18
-5mhv,2017-05-10,2016-11-25
-1mh2,2003-05-20,2002-08-19
-5mhp,2017-08-30,2016-11-25
-1kmm,1997-12-17,1997-05-09
-7kmc,2021-11-03,2020-11-02
-7kmi,2021-01-27,2020-11-02
-4km4,2013-07-24,2013-05-08
-3kmm,2010-12-08,2009-11-10
-7km9,2021-07-07,2020-11-02
-4km7,2013-08-07,2013-05-08
-7km0,2021-11-17,2020-11-02
-4kmp,2014-05-14,2013-05-08
-6km9,2020-08-05,2019-07-31
-1km0,2002-06-28,2001-12-13
-7km6,2021-05-12,2020-11-02
-4kmf,2013-07-03,2013-05-08
-7kme,1999-03-09,1999-02-26
-7km3,2021-11-10,2020-11-02
-4km2,2013-12-25,2013-05-07
-6km8,2020-02-12,2019-07-31
-1kms,2002-07-10,2001-12-17
-4kmx,2013-08-07,2013-05-08
-7kmz,2020-12-09,2020-11-03
-5kmd,2016-08-31,2016-06-26
-7kmh,2021-01-27,2020-11-02
-6kma,2020-08-05,2019-07-31
-3kmx,2010-01-19,2009-11-11
-7km8,2021-07-07,2020-11-02
-3km6,2010-03-23,2009-11-10
-3kmn,2010-03-23,2009-11-11
-5kmn,2016-12-28,2016-06-27
-1kmn,1997-12-17,1997-05-09
-7kmo,2021-05-26,2020-11-03
-2kmk,2010-03-02,2009-07-30
-4km0,2013-12-25,2013-05-07
-6km1,2020-08-05,2019-07-30
-2kmy,2010-08-11,2009-08-05
-7kmf,2021-07-14,2020-11-02
-4kmb,1997-02-12,1996-11-07
-2kmx,2009-12-01,2009-08-05
-5kmh,2016-08-31,2016-06-27
-4kmg,2014-03-26,2013-05-08
-5kmp,2017-01-25,2016-06-27
-3kmq,2010-07-07,2009-11-11
-7kml,2021-02-10,2020-11-03
-6km5,2020-08-05,2019-07-30
-2kmn,2009-08-25,2009-08-01
-5km0,2017-06-28,2016-06-26
-1kmv,2002-07-10,2001-12-17
-5kmk,2016-12-28,2016-06-27
-4kmu,2013-05-22,2013-05-08
-1kmq,2003-05-06,2001-12-17
-3kme,2009-12-22,2009-11-10
-2kmb,1997-02-12,1996-11-07
-5km3,2017-06-28,2016-06-26
-7km1,2021-11-17,2020-11-02
-5kmm,2016-12-28,2016-06-27
-3kmw,2009-12-29,2009-11-11
-3kmd,2010-02-23,2009-11-10
-6km3,2020-08-05,2019-07-30
-3kmt,2010-11-10,2009-11-11
-6kmr,2019-09-18,2019-08-01
-1km4,2002-06-28,2001-12-13
-1kme,2002-02-13,2001-12-14
-1kmj,2001-12-21,2001-12-16
-5km2,2017-06-28,2016-06-26
-1km5,2002-06-28,2001-12-13
-7kmd,2021-07-07,2020-11-02
-3kmh,2010-07-21,2009-11-10
-5kmf,2016-08-31,2016-06-26
-1km1,2002-06-28,2001-12-13
-7kmp,2021-05-26,2020-11-03
-1kmh,2002-03-13,2001-12-16
-6kmn,2020-10-21,2019-07-31
-4kmv,2013-09-04,2013-05-08
-7kmj,2022-05-25,2020-11-03
-6km4,2020-08-05,2019-07-30
-5kma,2017-06-28,2016-06-26
-4km5,2013-05-29,2013-05-08
-3kmv,2010-08-04,2009-11-11
-3km8,2010-10-20,2009-11-10
-3kmy,2010-01-19,2009-11-11
-6kmp,2020-07-29,2019-07-31
-1kmy,2002-02-20,2001-12-17
-6kme,2019-12-18,2019-07-31
-4kmm,2014-05-14,2013-05-08
-3kmf,2010-04-21,2009-11-10
-5kmc,2017-06-28,2016-06-26
-3km0,2010-11-10,2009-11-09
-3kmb,1997-02-12,1996-11-07
-3kmp,2010-02-23,2009-11-11
-4kmn,2014-05-14,2013-05-08
-7kmk,2021-02-10,2020-11-03
-7km5,2021-08-04,2020-11-02
-1km3,2002-06-28,2001-12-13
-3km5,2010-03-31,2009-11-09
-7kmm,2021-05-26,2020-11-03
-5km1,2017-06-28,2016-06-26
-3km9,2009-12-01,2009-11-10
-5kmw,2017-03-01,2016-06-27
-1km2,2002-06-28,2001-12-13
-5kms,2017-02-01,2016-06-27
-7kma,2021-07-21,2020-11-02
-5km4,2017-06-28,2016-06-26
-7km7,2021-07-07,2020-11-02
-5kmb,2017-06-28,2016-06-26
-3kmz,2010-06-02,2009-11-11
-7kmq,2021-05-26,2020-11-03
-5kmi,2016-12-28,2016-06-27
-5km9,2017-06-28,2016-06-26
-4kmz,2013-08-07,2013-05-08
-4kmr,2013-06-05,2013-05-08
-3km1,2010-12-01,2009-11-09
-3kmr,2010-06-02,2009-11-11
-1km6,2002-06-28,2001-12-13
-4km6,2013-08-07,2013-05-08
-6kmd,2019-12-18,2019-07-31
-7kms,2020-12-09,2020-11-03
-6km0,2020-08-05,2019-07-30
-5kmg,2016-08-03,2016-06-27
-7kmb,2020-12-09,2020-11-02
-4kmq,2013-05-29,2013-05-08
-2km0,2010-03-16,2009-07-15
-5kmr,2017-01-25,2016-06-27
-5km5,2017-06-28,2016-06-26
-3km4,2010-01-12,2009-11-09
-6kmk,2019-08-28,2019-07-31
-5kmj,2016-12-28,2016-06-27
-3km2,2010-12-01,2009-11-09
-6kmx,2020-01-15,2019-08-01
-5kmo,2016-12-28,2016-06-27
-6kmm,2020-10-21,2019-07-31
-3kmg,2010-01-12,2009-11-10
-5kml,2016-12-28,2016-06-27
-1kmi,2002-07-24,2001-12-16
-4kmk,2013-05-22,2013-05-08
-1kmb,1997-02-12,1996-11-07
-4kmw,2013-09-04,2013-05-08
-1kmk,2001-12-21,2001-12-16
-5kmt,2017-08-02,2016-06-27
-5kmq,2017-01-25,2016-06-27
-4kmy,2013-08-07,2013-05-08
-3kms,2010-07-07,2009-11-11
-5km8,2017-06-28,2016-06-26
-6kmw,2020-01-15,2019-08-01
-5km6,2017-06-28,2016-06-26
-8kme,1999-03-24,1999-03-21
-1kmp,2002-03-06,2001-12-17
-6km6,2020-08-05,2019-07-30
-7kmr,2021-11-10,2020-11-03
-3kmo,2010-03-23,2009-11-11
-3kmc,2009-12-22,2009-11-10
-7km2,2021-11-10,2020-11-02
-6km2,2020-08-05,2019-07-30
-7kmy,2021-01-27,2020-11-03
-1kmg,2002-10-02,2001-12-15
-6kms,2019-09-18,2019-08-01
-2qpd,2007-12-11,2007-07-23
-7qpz,2022-03-02,2022-01-05
-3qpp,2011-06-15,2011-02-14
-1qpq,1998-11-25,1998-11-20
-2qps,2008-02-12,2007-07-25
-1qp7,1999-06-04,1999-06-01
-2qp4,2008-07-29,2007-07-23
-2qpp,2007-08-07,2007-07-24
-3qpn,2011-06-15,2011-02-14
-5qpg,2020-04-29,2019-03-12
-6qp1,2020-03-04,2019-02-13
-5qp9,2019-05-08,2019-02-22
-4qpa,2015-09-23,2014-06-22
-5qpq,2020-04-29,2019-03-12
-6qph,2020-02-12,2019-02-14
-3qp2,2011-03-30,2011-02-11
-5qph,2020-04-29,2019-04-04
-5qpz,2020-04-29,2019-03-12
-5qpw,2020-04-29,2019-03-12
-7qpp,2022-12-28,2022-01-05
-5qpj,2020-04-29,2019-04-04
-4qpn,2014-07-09,2014-06-24
-1qpk,1999-11-17,1999-05-26
-5qp3,2019-05-08,2019-02-22
-6qpz,2019-11-06,2019-02-16
-7qpa,2022-07-06,2022-01-03
-4qpb,2014-07-09,2014-06-22
-2qpe,2007-12-11,2007-07-23
-6qpa,2020-03-18,2019-02-13
-6qp3,2020-03-04,2019-02-13
-4qpe,2014-09-24,2014-06-23
-3qpe,2012-02-15,2011-02-12
-5qpr,2020-04-29,2019-03-12
-1qpb,2000-02-04,1999-11-26
-5qpa,2019-05-08,2019-02-22
-7qp3,2023-01-18,2021-12-30
-5qp8,2019-05-08,2019-02-22
-6qpk,2020-03-04,2019-02-14
-6qpr,2019-03-13,2019-02-14
-6qpv,2019-11-06,2019-02-15
-6qpl,2019-07-17,2019-02-14
-4qp3,2015-09-23,2014-06-22
-5qpv,2020-04-29,2019-03-12
-2qp8,2008-03-11,2007-07-23
-1qpu,1999-06-02,1999-05-30
-4qp8,2015-09-23,2014-06-22
-4qpw,2014-08-13,2014-06-25
-3qpv,2012-02-08,2011-02-14
-6qpx,2019-11-06,2019-02-15
-5qpo,2020-04-29,2019-03-12
-5qp2,2019-05-08,2019-02-22
-3qps,2011-03-09,2011-02-14
-5qpt,2020-04-29,2019-03-12
-3qp1,2011-03-30,2011-02-11
-6qps,2019-09-25,2019-02-14
-7qp7,2022-05-11,2022-01-03
-3qp6,2011-03-30,2011-02-11
-2qpl,2007-12-18,2007-07-24
-2qpx,2007-08-07,2007-07-25
-2qpy,2007-09-25,2007-07-25
-4qpd,2015-04-15,2014-06-23
-7qp6,2022-05-11,2022-01-03
-6qp9,2019-08-21,2019-02-13
-5qpx,2020-04-29,2019-03-12
-4qpj,2015-07-15,2014-06-23
-1qpa,1997-01-11,1996-10-08
-3qpj,2012-02-15,2011-02-14
-5qpm,2020-04-29,2019-03-12
-5qpf,2020-04-29,2019-03-12
-2qpo,2007-10-16,2007-07-24
-6qp0,2019-03-13,2019-02-13
-4qpp,2014-08-20,2014-06-24
-7qpc,2022-07-06,2022-01-03
-5qpk,2020-04-29,2019-03-12
-3qpx,2011-08-10,2011-02-14
-2qp6,2008-06-03,2007-07-23
-1qpz,1999-06-07,1999-06-01
-5qpb,2019-05-08,2019-02-22
-3qpi,2011-07-06,2011-02-13
-3qp5,2011-03-30,2011-02-11
-2qp9,2007-10-09,2007-07-23
-5qp6,2019-05-08,2019-02-22
-2qpk,2007-08-07,2007-07-24
-4qpm,2014-10-22,2014-06-24
-7qp1,2023-01-11,2021-12-30
-1qpy,2001-02-21,1999-05-14
-7qps,2023-01-18,2022-01-05
-3qpk,2011-05-11,2011-02-14
-7qpj,2022-08-03,2022-01-04
-3qp8,2011-03-30,2011-02-11
-2qpt,2007-10-16,2007-07-25
-3qpz,2011-04-13,2011-02-14
-4qpf,2015-06-24,2014-06-23
-3qpy,2011-04-13,2011-02-14
-4qp4,2015-09-23,2014-06-22
-5qpd,2020-04-29,2019-03-12
-4qpx,2015-04-22,2014-06-25
-7qpr,2023-01-18,2022-01-05
-3qpg,2011-06-15,2011-02-13
-7qpv,2023-04-19,2022-01-05
-1qpd,2000-05-24,1999-05-24
-1qpg,1996-06-10,1996-01-04
-1qp8,1999-06-11,1999-06-01
-4qp1,2015-09-23,2014-06-22
-8qph,2023-11-08,2023-10-02
-3qpw,2012-02-08,2011-02-14
-3qp0,2012-02-15,2011-02-11
-4qp2,2015-09-23,2014-06-22
-4qpz,2015-03-11,2014-06-25
-1qpj,2000-05-31,1999-05-25
-6qpw,2020-02-05,2019-02-15
-5qpu,2020-04-29,2019-03-12
-6qpu,2019-11-06,2019-02-15
-1qpf,1999-08-16,1999-05-24
-6qp4,2019-08-21,2019-02-13
-3qpb,2011-08-24,2011-02-11
-4qp7,2015-09-23,2014-06-22
-5qp1,2019-05-08,2019-02-22
-4qp9,2015-09-23,2014-06-22
-8qpe,2024-05-22,2023-10-01
-3qp4,2011-03-30,2011-02-11
-5qps,2020-04-29,2019-03-12
-7qpu,2022-03-09,2022-01-05
-7qp0,2023-01-11,2021-12-30
-7qpi,2022-12-14,2022-01-04
-5qpl,2020-04-29,2019-04-04
-1qpc,2000-05-24,1999-05-21
-4qpk,2015-07-15,2014-06-23
-7qpd,2022-07-20,2022-01-03
-8qpr,2024-01-31,2023-10-03
-5qpn,2020-04-29,2019-03-12
-2qpu,2008-07-01,2007-07-25
-7qpf,2023-04-19,2022-01-04
-6qp6,2019-03-06,2019-02-13
-5qpe,2020-04-29,2019-03-12
-1qp0,1999-06-07,1999-06-01
-3qpo,2011-06-15,2011-02-14
-5qp0,2019-05-08,2019-02-22
-8qpl,2024-05-29,2023-10-02
-1qpl,1999-08-16,1999-05-25
-1qpr,1998-10-21,1998-10-17
-2qpa,2007-10-09,2007-07-23
-4qpl,2014-10-15,2014-06-23
-6qpt,2019-11-06,2019-02-15
-7qpn,2022-05-18,2022-01-05
-4qp5,2014-07-16,2014-06-22
-4qps,2015-01-14,2014-06-24
-1qps,1999-06-14,1999-05-28
-7qp4,2022-12-14,2022-01-02
-6qp8,2019-08-21,2019-02-13
-7qp8,2022-11-02,2022-01-03
-5qpi,2020-04-29,2019-03-12
-7qpm,2023-04-19,2022-01-05
-1qpe,2000-05-31,1999-05-24
-6qpp,2019-03-13,2019-02-14
-7qpt,2022-03-16,2022-01-05
-5qp5,2019-05-08,2019-02-22
-5qp7,2019-05-08,2019-02-22
-1qpw,1999-06-04,1999-05-30
-5qp4,2019-05-08,2019-02-22
-7qpw,2022-03-16,2022-01-05
-6qp7,2019-08-21,2019-02-13
-4qp6,2015-09-23,2014-06-22
-1qp9,2000-10-09,1999-06-01
-1qpn,1998-11-25,1998-11-20
-2qpj,2007-11-27,2007-07-24
-7qpb,2023-09-27,2022-01-03
-3qph,2012-05-30,2011-02-13
-6qpc,2019-03-06,2019-02-13
-2qpm,2008-07-01,2007-07-24
-7qpy,2022-03-16,2022-01-05
-7qpq,2023-04-19,2022-01-05
-1qp4,1999-06-07,1999-06-01
-2qp3,2008-07-29,2007-07-23
-5qpy,2020-04-29,2019-03-12
-7qpl,2023-01-18,2022-01-05
-6qp2,2020-03-04,2019-02-13
-7qph,2023-01-18,2022-01-04
-8qpn,2023-12-06,2023-10-02
-2qp2,2007-09-04,2007-07-22
-5qpp,2020-04-29,2019-04-04
-1g09,2000-12-27,2000-10-05
-1g0a,2000-12-27,2000-10-05
-5g0w,2016-11-30,2016-03-22
-2g0v,2006-07-04,2006-02-13
-5g00,2016-07-06,2016-03-16
-4g0v,2013-07-17,2012-07-10
-6g0z,2018-11-07,2018-03-20
-6g0h,2020-01-08,2018-03-18
-5g0h,2016-07-27,2016-03-18
-2g08,2006-04-04,2006-02-11
-6g00,2018-10-10,2018-03-15
-7g0g,2023-06-14,2023-04-27
-5g0o,2016-06-15,2016-03-21
-4g0n,2013-07-17,2012-07-09
-8g0s,2023-02-15,2023-02-01
-2g0i,2006-08-08,2006-02-13
-7g0f,2023-06-14,2023-04-27
-3g0f,2009-02-24,2009-01-27
-1g01,2001-08-01,2000-10-05
-6g0x,2018-04-04,2018-03-20
-6g0i,2018-11-21,2018-03-18
-4g0d,2013-08-21,2012-07-09
-1g0e,2000-10-18,2000-10-06
-2g0l,2006-03-28,2006-02-13
-6g07,2018-07-18,2018-03-16
-5g03,2016-05-25,2016-03-16
-4g0k,2012-09-12,2012-07-09
-4g0z,2012-07-25,2012-07-10
-3g0d,2010-02-16,2009-01-27
-8g05,2023-11-01,2023-01-31
-1g0f,2000-10-18,2000-10-06
-3g0k,2009-02-10,2009-01-28
-5g08,2017-01-25,2016-03-17
-4g0l,2012-09-12,2012-07-09
-7g00,2023-06-14,2023-04-27
-5g0b,2016-05-25,2016-03-17
-5g02,2016-11-09,2016-03-16
-2g0x,2006-07-04,2006-02-13
-6g01,2019-01-23,2018-03-15
-4g0w,2013-07-17,2012-07-10
-6g0f,2020-01-08,2018-03-18
-7g0e,2023-06-14,2023-04-27
-5g0q,2017-04-12,2016-03-22
-5g0f,2016-07-27,2016-03-18
-5g0p,2016-06-15,2016-03-21
-6g0l,2018-08-22,2018-03-19
-8g0v,2023-02-15,2023-02-01
-7g09,2023-06-14,2023-04-27
-4g0a,2012-08-22,2012-07-09
-8g0i,2024-03-20,2023-01-31
-6g0p,2018-11-28,2018-03-19
-4g0r,2013-02-27,2012-07-09
-5g01,2016-05-25,2016-03-16
-6g0r,2018-11-28,2018-03-19
-1g0u,2000-11-06,2000-10-09
-2g00,2006-10-03,2006-02-10
-5g09,2016-07-27,2016-03-17
-6g0b,2018-10-10,2018-03-16
-8g0n,2024-02-14,2023-01-31
-8g08,2023-02-15,2023-01-31
-2g0s,2006-07-04,2006-02-13
-4g07,2013-09-04,2012-07-09
-5g0v,2016-11-30,2016-03-22
-5g0n,2016-06-15,2016-03-21
-8g0t,2023-02-15,2023-02-01
-7g04,2023-06-14,2023-04-27
-8g00,2023-06-21,2023-01-31
-5g0j,2016-07-27,2016-03-18
-2g0g,2006-05-16,2006-02-13
-7g0k,2023-06-14,2023-04-27
-8g0e,2023-02-15,2023-01-31
-3g0c,2010-02-16,2009-01-27
-4g0q,2012-07-25,2012-07-09
-7g0z,2023-06-14,2023-04-27
-5g0m,2017-04-12,2016-03-21
-3g0a,2010-03-09,2009-01-27
-7g0x,2023-06-14,2023-04-27
-6g0v,2018-08-22,2018-03-19
-7g0t,2023-06-14,2023-04-27
-3g0b,2010-02-16,2009-01-27
-4g05,2012-10-24,2012-07-09
-7g06,2023-06-14,2023-04-27
-3g0x,2009-06-09,2009-01-29
-7g01,2023-06-14,2023-04-27
-8g0a,2023-02-15,2023-01-31
-5g0x,2016-11-30,2016-03-23
-7g0p,2023-06-14,2023-04-27
-2g09,2006-04-04,2006-02-11
-7g0r,2023-06-14,2023-04-27
-7g0a,2023-06-14,2023-04-27
-6g0w,2018-05-23,2018-03-20
-3g04,2009-08-04,2009-01-27
-3g03,2009-04-14,2009-01-27
-6g0a,2019-01-30,2018-03-16
-4g06,2012-07-25,2012-07-09
-5g0i,2016-07-27,2016-03-18
-7g0m,2023-06-14,2023-04-27
-3g0w,2009-04-28,2009-01-29
-2g0a,2006-04-04,2006-02-11
-8g0g,2023-07-05,2023-01-31
-8g09,2023-02-15,2023-01-31
-3g0t,2009-02-10,2009-01-28
-2g0r,2006-07-04,2006-02-13
-1g0c,2001-08-01,2000-10-05
-2g0z,2006-07-04,2006-02-13
-3g00,2010-03-09,2009-01-27
-7g0u,2023-06-14,2023-04-27
-4g0c,2012-09-19,2012-07-09
-5g0r,2016-04-13,2016-03-22
-6g0d,2020-01-08,2018-03-18
-5g0c,2016-05-25,2016-03-17
-6g09,2018-10-10,2018-03-16
-8g0m,2023-10-18,2023-01-31
-5g0a,2016-07-27,2016-03-17
-5g05,2016-05-25,2016-03-16
-3g0e,2009-02-24,2009-01-27
-4g01,2013-02-27,2012-07-09
-8g0l,2023-05-03,2023-01-31
-2g0w,2006-03-07,2006-02-13
-5g0t,2016-11-30,2016-03-22
-7g0b,2023-06-14,2023-04-27
-1g08,2000-12-27,2000-10-05
-7g0s,2023-06-14,2023-04-27
-1g0h,2001-03-14,2000-10-06
-7g0i,2023-06-14,2023-04-27
-8g0r,2023-02-15,2023-02-01
-5g04,2016-05-25,2016-03-16
-2g07,2006-04-04,2006-02-11
-6g0g,2020-01-08,2018-03-18
-3g0g,2010-02-16,2009-01-27
-7g02,2023-06-14,2023-04-27
-2g0b,2006-09-26,2006-02-11
-6g0y,2018-11-14,2018-03-20
-4g0p,2012-07-25,2012-07-09
-5g0u,2016-11-30,2016-03-22
-2g0d,2006-05-23,2006-02-12
-3g08,2009-12-08,2009-01-27
-6g0n,2018-10-10,2018-03-19
-7g05,2023-06-14,2023-04-27
-6g0j,2018-11-21,2018-03-18
-3g0q,2009-11-17,2009-01-28
-2g0y,2006-11-07,2006-02-13
-8g0h,2024-02-07,2023-01-31
-1g0b,2000-12-27,2000-10-05
-3g0y,2009-03-17,2009-01-29
-3g0s,2009-02-10,2009-01-28
-8g0c,2023-02-15,2023-01-31
-7g0h,2023-06-14,2023-04-27
-7g0y,2023-06-14,2023-04-27
-1g0o,2001-06-06,2000-10-06
-6g02,2019-01-23,2018-03-15
-8g0b,2023-02-15,2023-01-31
-7g0j,2023-06-14,2023-04-27
-3g0i,2009-06-09,2009-01-28
-7g0l,2023-06-14,2023-04-27
-8g0z,2023-06-14,2023-02-01
-7g07,2023-06-14,2023-04-27
-8g04,2023-08-30,2023-01-31
-8g0u,2023-02-15,2023-02-01
-1g0i,2001-03-14,2000-10-06
-4g0u,2013-07-17,2012-07-10
-7g0c,2023-06-14,2023-04-27
-5g0y,2016-12-07,2016-03-23
-3g0z,2009-03-31,2009-01-29
-7g0o,2023-06-14,2023-04-27
-1g02,2000-10-25,2000-10-05
-6g0e,2020-01-08,2018-03-18
-2g0h,2006-05-16,2006-02-13
-1g0r,2000-12-27,2000-10-07
-3g0h,2009-02-17,2009-01-28
-1g0v,2001-04-21,2000-10-09
-6g05,2018-07-18,2018-03-16
-8g07,2023-02-15,2023-01-31
-2g01,2006-04-18,2006-02-10
-7g0v,2023-06-14,2023-04-27
-2g0n,2006-05-30,2006-02-13
-7g03,2023-06-14,2023-04-27
-8g0d,2023-02-15,2023-01-31
-7g0q,2023-06-14,2023-04-27
-2g06,2006-04-04,2006-02-11
-4g09,2013-10-02,2012-07-09
-1g0n,2001-06-06,2000-10-06
-1g05,2001-10-05,2000-10-05
-3g0u,2009-06-09,2009-01-28
-4g0y,2012-07-25,2012-07-10
-5g0g,2016-07-27,2016-03-18
-7g08,2023-06-14,2023-04-27
-2g02,2006-05-23,2006-02-10
-5g0s,2016-11-30,2016-03-22
-6n22,2019-11-13,2018-11-12
-5n2w,2017-04-19,2017-02-08
-3n2v,2010-11-10,2010-05-19
-3n2e,2011-05-18,2010-05-18
-4n2r,2014-01-15,2013-10-06
-6n2s,2019-03-27,2018-11-14
-6n27,2019-01-23,2018-11-12
-4n2g,2015-02-04,2013-10-04
-5n28,2017-06-14,2017-02-07
-3n26,2010-06-16,2010-05-17
-6n2b,2018-12-19,2018-11-12
-1n2t,2003-01-21,2002-10-24
-4n2n,2015-02-04,2013-10-05
-5n27,2017-08-02,2017-02-07
-6n2t,2019-03-27,2018-11-14
-5n2q,2017-04-12,2017-02-08
-6n2j,2018-12-12,2018-11-13
-1n2i,2003-04-22,2002-10-22
-4n2q,2013-10-30,2013-10-06
-7n2p,2022-12-07,2021-05-29
-3n2o,2010-06-09,2010-05-18
-4n2k,2015-02-04,2013-10-05
-4n2f,2015-02-04,2013-10-04
-2n25,2015-06-17,2015-04-28
-1n29,2003-10-28,2002-10-22
-4n27,2013-12-11,2013-10-04
-7n2c,2021-07-14,2021-05-28
-3n2c,2010-06-02,2010-05-17
-3n2g,2010-07-28,2010-05-18
-7n28,2022-04-06,2021-05-28
-6n2n,2019-03-20,2018-11-13
-3n2i,2010-06-02,2010-05-18
-3n2r,2010-08-18,2010-05-18
-7n2y,2022-06-01,2021-05-30
-5n26,2017-08-02,2017-02-07
-6n2i,2019-07-10,2018-11-13
-6n2m,2019-07-17,2018-11-13
-5n2v,2017-05-24,2017-02-08
-4n2e,2015-02-04,2013-10-04
-5n2f,2017-06-28,2017-02-07
-5n22,2017-03-15,2017-02-07
-7n2x,2022-08-31,2021-05-30
-1n28,2003-10-28,2002-10-22
-4n2p,2014-01-01,2013-10-05
-7n2z,2022-06-01,2021-05-30
-7n2r,2022-12-07,2021-05-29
-6n2a,2019-04-24,2018-11-12
-4n2s,2013-10-30,2013-10-06
-2n27,2016-07-06,2015-04-29
-1n22,2002-11-27,2002-10-21
-1n2s,2002-11-01,2002-10-24
-5n25,2017-12-27,2017-02-07
-6n2k,2018-12-12,2018-11-13
-7n2u,2021-07-14,2021-05-29
-4n22,2015-02-04,2013-10-04
-1n2x,2003-01-28,2002-10-24
-4n2d,2015-02-04,2013-10-04
-5n2i,2017-04-26,2017-02-07
-5n2l,2018-02-28,2017-02-07
-3n2n,2011-01-05,2010-05-18
-6n2w,2020-05-13,2018-11-14
-1n2l,2003-12-23,2002-10-23
-5n2g,2017-11-29,2017-02-07
-6n20,2019-06-05,2018-11-12
-6n2e,2019-11-13,2018-11-12
-4n25,2015-02-04,2013-10-04
-7n2w,2022-06-01,2021-05-30
-7n2s,2022-12-07,2021-05-29
-4n2l,2015-02-04,2013-10-05
-6n29,2019-01-23,2018-11-12
-3n2k,2010-07-28,2010-05-18
-3n2p,2011-03-09,2010-05-18
-4n20,2015-02-04,2013-10-04
-5n24,2017-12-27,2017-02-07
-1n2j,2003-04-22,2002-10-22
-3n2y,2010-11-03,2010-05-19
-1n23,2002-11-27,2002-10-21
-1n2v,2003-04-08,2002-10-24
-3n20,2010-10-13,2010-05-17
-5n2r,2017-07-26,2017-02-08
-5n2s,2017-07-26,2017-02-08
-1n2z,2002-12-18,2002-10-24
-7n2q,2022-12-07,2021-05-29
-4n24,2015-02-04,2013-10-04
-5n2a,2017-06-14,2017-02-07
-1n26,2002-12-18,2002-10-22
-4n2h,2015-02-04,2013-10-04
-1n2h,2003-04-22,2002-10-22
-7n29,2022-05-04,2021-05-28
-3n21,2011-05-25,2010-05-17
-5n2m,2018-02-28,2017-02-07
-3n23,2011-01-19,2010-05-17
-7n2m,2022-04-20,2021-05-29
-6n2c,2018-12-19,2018-11-12
-7n2n,2022-12-07,2021-05-29
-6n2z,2019-02-20,2018-11-14
-1n2g,2003-04-22,2002-10-22
-6n21,2019-06-05,2018-11-12
-1n24,2002-11-27,2002-10-21
-1n20,2002-11-27,2002-10-21
-5n2j,2017-07-26,2017-02-07
-4n28,2015-02-04,2013-10-04
-3n2d,2010-07-28,2010-05-18
-5n2x,2017-06-21,2017-02-08
-6n23,2019-01-23,2018-11-12
-7n2o,2022-12-07,2021-05-29
-5n20,2017-05-17,2017-02-06
-7n27,2021-07-21,2021-05-28
-1n2o,2003-04-23,2002-10-23
-1n2e,2003-04-22,2002-10-22
-6n2f,2019-04-24,2018-11-12
-1n25,2003-06-03,2002-10-21
-3n2z,2010-07-07,2010-05-19
-1n2a,2003-11-04,2002-10-22
-3n2s,2010-09-15,2010-05-19
-2n26,2015-06-17,2015-04-28
-5n21,2017-05-17,2017-02-06
-6n2y,2019-02-20,2018-11-14
-3n2a,2010-06-30,2010-05-17
-2n2k,2015-07-08,2015-05-10
-1n2r,2004-03-16,2002-10-24
-1n2c,1997-11-12,1997-05-02
-5n2t,2017-06-21,2017-02-08
-3n25,2010-07-28,2010-05-17
-4n2a,2015-02-04,2013-10-04
-4n2c,2015-02-04,2013-10-04
-4n2i,2015-02-04,2013-10-04
-3n2u,2010-11-10,2010-05-19
-7n2a,2021-08-25,2021-05-28
-4n2b,2015-02-04,2013-10-04
-7n2v,2021-07-14,2021-05-29
-4n26,2015-02-04,2013-10-04
-3n29,2010-06-09,2010-05-17
-1n2b,2003-04-22,2002-10-22
-1n2n,2003-02-11,2002-10-23
-6n25,2019-01-23,2018-11-12
-6n2r,2019-04-03,2018-11-14
-3n2m,2011-04-06,2010-05-18
-3n2j,2011-04-06,2010-05-18
-5n2n,2017-09-13,2017-02-08
-5n2c,2017-07-26,2017-02-07
-4n2m,2015-02-04,2013-10-05
-5n23,2018-03-14,2017-02-07
-5n2d,2017-06-28,2017-02-07
-4n2z,2014-01-15,2013-10-06
-5n2z,2017-06-21,2017-02-08
-1n2k,2003-12-23,2002-10-23
-1n21,2002-11-27,2002-10-21
-6n2o,2019-03-20,2018-11-13
-6n28,2019-01-23,2018-11-12
-8gd8,2023-11-15,2023-03-03
-3gd4,2009-05-19,2009-02-23
-7gd9,2023-11-08,2023-08-11
-3gdu,2009-03-31,2009-02-24
-6gdy,2019-04-03,2018-04-24
-1gdq,2001-02-07,2000-09-28
-3gdj,2010-03-02,2009-02-24
-7gdb,2023-11-08,2023-08-11
-3gd3,2009-05-19,2009-02-23
-1gd1,1988-01-16,1987-06-22
-3gd9,2009-07-28,2009-02-23
-2gd6,2007-02-20,2006-03-15
-2gdz,2006-04-04,2006-03-17
-6gde,2019-01-30,2018-04-23
-7gdy,2023-11-08,2023-08-11
-2gdj,2006-05-16,2006-03-16
-7gdk,2023-11-08,2023-08-11
-7gdq,2023-11-08,2023-08-11
-8gdu,2024-01-24,2023-03-06
-1gdc,1994-06-22,1994-03-15
-2gde,2007-03-20,2006-03-16
-7gda,2023-11-08,2023-08-11
-7gdn,2023-11-08,2023-08-11
-2gd0,2007-02-20,2006-03-15
-8gd4,2023-10-04,2023-03-03
-8gd9,2024-01-10,2023-03-03
-7gdo,2023-11-08,2023-08-11
-3gdt,2009-06-23,2009-02-24
-8gdj,2024-03-20,2023-03-06
-8gdz,2024-03-06,2023-03-06
-3gdx,2009-05-05,2009-02-24
-5gds,1998-01-21,1997-07-17
-4gdx,2013-09-25,2012-08-01
-7gdh,2023-11-08,2023-08-11
-3gdl,2009-06-23,2009-02-24
-6gdc,2019-05-01,2018-04-23
-8gd5,2023-06-07,2023-03-03
-6gdq,2018-05-30,2018-04-24
-7gdv,2023-11-08,2023-08-11
-7gdj,2023-11-08,2023-08-11
-1gdn,2001-02-07,2000-09-28
-4gde,2012-10-17,2012-07-31
-3gdv,2009-03-31,2009-02-24
-7gdf,2023-11-08,2023-08-11
-2gdd,2006-04-11,2006-03-15
-1gdl,1995-02-27,1994-09-14
-2gdf,2006-09-16,2006-03-16
-8gd3,2023-06-07,2023-03-03
-8gda,2024-01-10,2023-03-03
-8gdv,2024-03-13,2023-03-06
-7gdp,2023-11-08,2023-08-11
-7gdi,2023-11-08,2023-08-11
-3gdc,2010-03-09,2009-02-24
-1gdd,1995-11-27,1995-07-25
-7gd6,2023-11-08,2023-08-11
-8gd2,2023-10-04,2023-03-03
-4gd4,2012-08-15,2012-07-31
-4gdj,2012-09-26,2012-07-31
-8gdx,2024-03-13,2023-03-06
-7gd5,2023-11-08,2023-08-11
-8gdi,2023-05-24,2023-03-06
-6gd2,2018-10-31,2018-04-21
-6gd0,2019-04-03,2018-04-20
-4gdl,2012-12-05,2012-07-31
-1gde,2001-09-23,2000-09-23
-4gdf,2013-04-10,2012-07-31
-7gdz,2023-11-08,2023-08-11
-1gdv,2001-04-06,2000-10-06
-4gd9,2013-06-05,2012-07-31
-1gd9,2001-09-22,2000-09-22
-7gds,2023-11-08,2023-08-11
-2gdo,2007-03-20,2006-03-16
-2gdu,2006-09-26,2006-03-17
-1gdu,2001-02-07,2000-09-29
-3gd2,2009-07-07,2009-02-23
-3gdp,2009-03-24,2009-02-24
-2gdr,2006-08-22,2006-03-16
-7gdm,2023-11-08,2023-08-11
-3gdf,2010-05-26,2009-02-24
-4gdp,2012-10-17,2012-08-01
-1gdk,1995-02-27,1994-09-14
-3gdn,2009-03-24,2009-02-24
-7gdu,2023-11-08,2023-08-11
-8gdc,2024-01-10,2023-03-03
-6gdp,2019-04-03,2018-04-24
-3gdh,2009-06-23,2009-02-24
-7gdl,2023-11-08,2023-08-11
-6gdr,2018-07-25,2018-04-24
-4gdz,2012-08-22,2012-08-01
-8gd6,2023-11-15,2023-03-03
-4gda,2013-06-05,2012-07-31
-3gd7,2010-03-02,2009-02-23
-2gdm,1995-10-15,1994-09-14
-7gdg,2023-11-08,2023-08-11
-8gdw,2024-03-13,2023-03-06
-7gd3,2023-11-08,2023-08-11
-6gdg,2018-05-16,2018-04-23
-8gdm,2023-10-04,2023-03-06
-4gd3,2013-01-02,2012-07-31
-4gd7,2013-07-31,2012-07-31
-8gds,2023-05-10,2023-03-06
-6gdo,2019-04-03,2018-04-24
-8gdk,2024-03-20,2023-03-06
-3gdq,2009-04-14,2009-02-24
-6gd4,2019-04-03,2018-04-21
-7gdc,2023-11-08,2023-08-11
-7gdx,2023-11-08,2023-08-11
-7gdw,2023-11-08,2023-08-11
-7gd0,2023-11-08,2023-08-11
-8gdb,2024-01-10,2023-03-03
-4gdb,2013-07-31,2012-07-31
-4gdy,2012-08-29,2012-08-01
-1gdj,1995-02-27,1994-09-14
-6gdf,2019-01-30,2018-04-23
-8gdl,2024-01-17,2023-03-06
-8gdr,2024-03-13,2023-03-06
-4gd6,2013-07-31,2012-07-31
-7gd1,2023-11-08,2023-08-11
-7gd8,2023-11-08,2023-08-11
-6gdd,2019-01-30,2018-04-23
-3gds,2009-03-31,2009-02-24
-2gd2,2007-02-20,2006-03-15
-6gdm,2018-05-30,2018-04-24
-6gd1,2018-10-31,2018-04-21
-3gdg,2010-06-09,2009-02-24
-7gdr,2023-11-08,2023-08-11
-1gdi,1995-02-27,1994-09-14
-2gda,1994-06-22,1994-03-15
-7gdt,2023-11-08,2023-08-11
-4gdk,2012-12-05,2012-07-31
-4gd8,2013-07-31,2012-07-31
-6gd3,2018-10-31,2018-04-21
-7gd2,2023-11-08,2023-08-11
-7gdd,2023-11-08,2023-08-11
-8gd1,2023-06-07,2023-03-03
-2gd8,2007-02-06,2006-03-15
-4gdi,2012-09-26,2012-07-31
-6gdk,2018-10-17,2018-04-23
-7gd4,2023-11-08,2023-08-11
-8gdn,2024-03-20,2023-03-06
-4gd0,2012-08-29,2012-07-31
-7gde,2023-11-08,2023-08-11
-8gd0,2023-06-07,2023-03-03
-2gdv,2006-09-26,2006-03-17
-7gd7,2023-11-08,2023-08-11
-2gds,2006-03-28,2006-03-16
-2fdd,2006-02-21,2005-12-13
-5fdn,2017-02-08,2015-12-16
-8fd7,2023-03-22,2022-12-02
-4fdp,2012-07-04,2012-05-29
-1fdk,1998-10-14,1997-09-04
-8fdk,2023-07-12,2022-12-03
-2fde,2006-02-21,2005-12-13
-3fdm,2009-03-10,2008-11-26
-1fdj,2001-07-25,2000-07-20
-8fd9,2023-07-05,2022-12-02
-3fd3,2009-02-03,2008-11-24
-7fd9,2021-09-08,2021-07-16
-8fdj,2023-07-12,2022-12-03
-2fdi,2006-02-21,2005-12-14
-6fdt,2018-08-01,2017-12-26
-7fdk,2021-08-25,2021-07-16
-7fd4,2021-11-03,2021-07-16
-6fd6,2018-08-15,2017-12-21
-1fdv,1998-05-27,1998-01-15
-2fdv,2006-11-28,2005-12-14
-6fd3,2018-01-03,2017-12-21
-6fd2,2018-01-17,2017-12-21
-5fdl,2016-02-17,2015-12-16
-2fdk,2006-02-21,2005-12-14
-8fdw,2023-05-10,2022-12-05
-5fdr,2016-03-02,2015-12-16
-3fd0,2008-12-09,2008-11-24
-7fdw,2021-08-04,2021-07-18
-5fdg,2015-12-30,2015-12-16
-6fdp,2018-08-01,2017-12-26
-4fdg,2013-03-06,2012-05-28
-2fd8,2006-02-21,2005-12-13
-5fdz,2016-01-13,2015-12-16
-8fdn,2023-07-12,2022-12-03
-1fdw,1998-05-27,1998-01-16
-7fd7,2022-07-20,2021-07-16
-1fdo,1997-08-20,1997-01-27
-6fdc,2018-05-16,2017-12-22
-2fdh,2006-02-21,2005-12-14
-5fdu,2016-01-27,2015-12-16
-7fdh,2021-08-25,2021-07-16
-7fdn,2022-07-20,2021-07-17
-4fdv,2012-10-17,2012-05-29
-4fd2,2012-07-18,2012-05-25
-6fdm,2019-01-30,2017-12-26
-8fda,2023-08-23,2022-12-02
-7fdv,2022-06-22,2021-07-18
-5fdc,2016-05-18,2015-12-16
-4fdi,2012-09-05,2012-05-28
-1fds,1997-02-12,1996-06-28
-4fdc,2012-10-17,2012-05-27
-6fd9,2018-10-24,2017-12-22
-4fdw,2012-07-25,2012-05-29
-5fdj,2016-05-25,2015-12-16
-4fdn,2012-07-04,2012-05-29
-5fdx,2016-10-26,2015-12-16
-6fdx,2019-04-10,2017-12-27
-5fd2,2016-05-04,2015-12-15
-1fdy,1997-10-22,1996-07-08
-2fdg,2006-02-21,2005-12-13
-3fdb,2008-12-09,2008-11-25
-8fdu,2023-06-21,2022-12-04
-1fd9,2001-07-25,2000-07-20
-5fdi,2016-05-18,2015-12-16
-2fdm,2006-01-10,2005-12-14
-1fdh,1976-08-19,1976-08-18
-8fdc,2023-11-01,2022-12-02
-4fdz,2013-05-29,2012-05-29
-3fdc,2009-12-01,2008-11-25
-1fdu,1998-05-27,1998-01-14
-8fdt,2023-06-21,2022-12-04
-3fdd,2009-03-17,2008-11-25
-7fd6,2022-07-20,2021-07-16
-6fds,2019-04-10,2017-12-26
-8fd6,2023-06-21,2022-12-02
-4fdo,2012-07-04,2012-05-29
-8fd8,2023-03-08,2022-12-02
-8fdl,2023-07-12,2022-12-03
-2fdr,2006-01-31,2005-12-14
-5fdw,2016-12-21,2015-12-16
-2fdu,2006-11-28,2005-12-14
-2fdp,2006-01-24,2005-12-14
-3fdn,2009-09-15,2008-11-26
-6fdu,2018-08-15,2017-12-26
-3fdo,2008-12-16,2008-11-26
-4fdj,2012-09-05,2012-05-28
-7fdy,2022-11-16,2021-07-18
-4fdh,2013-01-30,2012-05-28
-8fd0,2023-08-30,2022-12-01
-7fdx,2022-07-20,2021-07-18
-3fdy,2009-03-31,2008-11-26
-1fdi,1997-08-20,1997-01-28
-5fd8,2015-12-30,2015-12-15
-5fd0,2016-10-26,2015-12-15
-3fdx,2008-12-16,2008-11-26
-6fdf,2018-06-20,2017-12-22
-3fd6,2009-09-22,2008-11-25
-7fdz,2022-04-20,2021-07-19
-3fd5,2009-09-22,2008-11-25
-2fdf,2006-02-21,2005-12-13
-5fdv,2016-01-27,2015-12-16
-8fdb,2023-05-17,2022-12-02
-3fdj,2009-02-03,2008-11-25
-1fdt,1997-02-12,1996-06-28
-6fdz,2018-08-01,2017-12-27
-7fdg,2021-08-25,2021-07-16
-8fdz,2023-05-10,2022-12-05
-1fd7,2000-08-10,2000-07-19
-4fdm,2013-05-08,2012-05-29
-3fd2,2009-06-30,2008-11-24
-2fdw,2006-11-28,2005-12-14
-8fdx,2023-05-10,2022-12-05
-5fdq,2016-03-16,2015-12-16
-7fd8,2021-09-08,2021-07-16
-1fdr,1997-09-17,1997-03-06
-4fdk,2013-08-28,2012-05-28
-6fd4,2018-08-15,2017-12-21
-7fd5,2021-11-03,2021-07-16
-2fd6,2006-02-21,2005-12-13
-4fd8,2012-09-26,2012-05-26
-4fdq,2012-10-24,2012-05-29
-2fdc,2006-03-14,2005-12-13
-6fdj,2019-01-30,2017-12-25
-3fde,2009-01-06,2008-11-25
-3fdk,2009-06-30,2008-11-25
-2fdx,1997-04-01,1996-12-24
-6fd5,2018-08-15,2017-12-21
-6fdy,2018-08-01,2017-12-27
-1fd0,2002-09-27,2000-07-19
-6fdw,2019-04-10,2017-12-27
-4fda,2013-08-07,2012-05-27
-3fdg,2008-12-23,2008-11-25
-2fda,2006-04-18,2005-12-13
-2fdy,2006-11-28,2005-12-14
-7fdi,2021-08-25,2021-07-16
-6fdi,2019-04-10,2017-12-24
-5fd3,2016-08-03,2015-12-15
-5fdp,2016-06-08,2015-12-16
-7fd0,2022-01-19,2021-07-15
-6fdq,2018-08-15,2017-12-26
-1fd8,2001-03-14,2000-07-20
-8fdy,2023-05-10,2022-12-05
-1fdz,1997-10-22,1996-07-08
-5fdd,2015-12-30,2015-12-16
-7fd2,2022-08-10,2021-07-15
-2fdj,2006-02-21,2005-12-14
-5fd6,2016-12-28,2015-12-15
-5fdo,2016-03-02,2015-12-16
-8fd1,2023-08-30,2022-12-01
-8fdm,2023-07-12,2022-12-03
-3fdz,2009-01-13,2008-11-26
-5jjs,2016-07-06,2016-04-25
-4jjd,2014-03-12,2013-03-07
-6jj7,2019-07-03,2019-02-25
-8jjq,2024-02-07,2023-05-31
-7jj9,2020-12-23,2020-07-24
-2jji,2008-05-27,2008-04-09
-4jj0,2013-10-09,2013-03-07
-4jjg,2013-08-07,2013-03-07
-7jjo,2020-09-02,2020-07-27
-8jja,2024-05-08,2023-05-30
-6jjn,2019-05-22,2019-02-26
-1jjc,2001-11-02,2001-07-04
-2jjl,2009-01-13,2008-04-14
-7jji,2020-08-26,2020-07-26
-1jj2,2001-08-01,2001-07-03
-5jj8,2016-07-06,2016-04-22
-2jjj,2008-05-27,2008-04-09
-8jjm,2023-09-13,2023-05-31
-4jjs,2013-06-12,2013-03-08
-7jja,2020-12-23,2020-07-24
-6jjk,2020-09-02,2019-02-26
-1jjf,2001-10-31,2001-07-05
-7jjq,2020-11-11,2020-07-27
-6jjb,2020-01-22,2019-02-25
-7jj8,2020-12-23,2020-07-24
-8jj0,2024-06-05,2023-05-29
-2jjp,2009-07-14,2008-04-15
-4jjm,2013-06-12,2013-03-08
-5jjz,2016-05-25,2016-04-25
-4jju,2013-06-12,2013-03-08
-4jj8,2013-06-12,2013-03-07
-8jjc,2024-03-27,2023-05-30
-6jjj,2019-08-14,2019-02-26
-2jj4,2007-10-16,2007-07-04
-5jjj,2017-02-15,2016-04-24
-6jjr,2020-02-19,2019-02-26
-6jjw,2019-09-25,2019-02-27
-8jjk,2024-05-08,2023-05-30
-5jjk,2016-11-16,2016-04-24
-6jjd,2019-05-01,2019-02-25
-7jjc,2020-10-28,2020-07-25
-5jjl,2016-11-16,2016-04-24
-1jjt,2001-07-25,2001-07-09
-6jju,2019-05-22,2019-02-27
-7jjg,2021-07-28,2020-07-25
-2jjo,2009-07-14,2008-04-15
-6jj8,2019-07-03,2019-02-25
-2jjy,2009-02-24,2008-04-25
-4jjf,2013-08-07,2013-03-07
-4jji,2013-03-27,2013-03-07
-5jjy,2016-11-02,2016-04-25
-6jjl,2020-09-02,2019-02-26
-7jjn,2021-06-23,2020-07-27
-2jj2,2007-08-21,2007-07-03
-6jjq,2019-03-06,2019-02-26
-7jj0,2021-03-10,2020-07-24
-6jjp,2019-10-30,2019-02-26
-7jjl,2020-08-05,2020-07-27
-7jjb,2020-12-23,2020-07-24
-1jje,2001-07-25,2001-07-04
-7jjj,2020-08-26,2020-07-26
-8jjr,2024-05-15,2023-05-31
-5jjn,2017-02-15,2016-04-24
-4jj7,2013-06-12,2013-03-07
-8jjb,2024-03-27,2023-05-30
-5jjb,2016-05-18,2016-04-23
-5jjm,2017-03-15,2016-04-24
-2jjn,2009-07-14,2008-04-15
-5jjg,2016-09-07,2016-04-23
-1jj9,2001-08-01,2001-07-04
-5jju,2016-05-04,2016-04-25
-8jjt,2024-02-07,2023-05-31
-8jjs,2023-07-26,2023-05-31
-6jj9,2019-07-03,2019-02-25
-4jj3,2013-10-09,2013-03-07
-2jjb,2009-01-13,2008-03-28
-6jja,2019-07-17,2019-02-25
-8jjo,2023-09-06,2023-05-31
-2jjg,2009-06-30,2008-04-04
-4jje,2013-06-12,2013-03-07
-2jjc,2008-07-15,2008-03-31
-5jjr,2016-07-06,2016-04-25
-7jj1,2021-07-28,2020-07-24
-2jj8,2008-04-29,2008-03-19
-6jjc,2019-05-01,2019-02-25
-2jjx,2008-07-29,2008-04-23
-4jjk,2013-03-20,2013-03-08
-1jjb,2002-07-17,2001-07-04
-7jjt,2021-06-23,2020-07-27
-5jje,2017-02-15,2016-04-23
-2jj1,2007-08-21,2007-07-03
-2jjs,2008-08-05,2008-04-22
-8jje,2023-12-27,2023-05-30
-8jjn,2024-02-07,2023-05-31
-4jjq,2013-05-01,2013-03-08
-6jj6,2020-02-26,2019-02-25
-6jjm,2019-05-22,2019-02-26
-5jj5,2016-05-04,2016-04-22
-5jjt,2017-04-26,2016-04-25
-2jjh,2009-06-30,2008-04-04
-2jj3,2007-08-07,2007-07-03
-5jjq,2017-03-22,2016-04-25
-4jjj,2014-07-30,2013-03-07
-1jjw,2001-12-05,2001-07-09
-1jj0,2001-11-02,2001-07-03
-6jj5,2020-02-26,2019-02-25
-4jjz,2013-03-20,2013-03-08
-2jj0,2007-09-04,2007-07-03
-1jj7,2001-09-12,2001-07-03
-1jju,2001-12-12,2001-07-09
-8jjl,2023-09-06,2023-05-30
-8jj2,2024-06-05,2023-05-29
-5jja,2016-07-13,2016-04-22
-6jj3,2020-01-22,2019-02-25
-6jjo,2020-09-02,2019-02-26
-5jj4,2016-06-29,2016-04-22
-5jji,2016-11-16,2016-04-24
-2jje,2009-06-30,2008-04-03
-1jjv,2002-05-01,2001-07-09
-5jj0,2016-07-06,2016-04-22
-1jjk,2001-08-01,2001-07-06
-8jj1,2024-06-05,2023-05-29
-4jj2,2014-03-12,2013-03-07
-8jj5,2023-06-14,2023-05-29
-2jjk,2008-07-22,2008-04-09
-5jjo,2016-08-31,2016-04-24
-8jj8,2023-09-06,2023-05-29
-2jj9,2009-01-13,2008-03-25
-2jjz,2009-07-14,2008-05-15
-5jjf,2017-02-15,2016-04-23
-2jjq,2008-08-05,2008-04-17
-1jjd,2001-08-22,2001-07-04
-2jjt,2008-08-05,2008-04-22
-110m,1998-04-08,1997-12-23
-7fy9,2023-06-14,2023-04-27
-3fyy,2009-02-03,2009-01-23
-3fy0,2009-03-03,2009-01-21
-4fyw,2012-10-10,2012-07-05
-4fyp,2013-06-26,2012-07-05
-7fyt,2023-06-14,2023-04-27
-7fyh,2023-06-14,2023-04-27
-6fya,2018-05-02,2018-03-11
-1fy8,2000-11-08,2000-09-28
-3fyk,2009-04-07,2009-01-22
-7fyf,2023-06-14,2023-04-27
-5fyi,2016-03-16,2016-03-07
-8fyx,2024-05-15,2023-01-26
-2fyb,2006-03-14,2006-02-07
-4fyz,2012-07-25,2012-07-05
-8fye,2024-05-15,2023-01-26
-2fym,2006-02-28,2006-02-08
-5fyt,2016-03-23,2016-03-09
-6fyi,2018-07-18,2018-03-12
-7fyq,2023-06-14,2023-04-27
-5fyc,2016-03-16,2016-03-07
-5fy0,2016-03-16,2016-03-03
-6fym,2019-02-20,2018-03-12
-6fyt,2018-11-07,2018-03-12
-5fyj,2016-04-27,2016-03-08
-1fy2,2001-01-10,2000-09-28
-5fyr,2017-01-18,2016-03-09
-2fyv,2006-12-26,2006-02-08
-5fyh,2016-03-23,2016-03-07
-8fyh,2023-10-04,2023-01-26
-5fyq,2016-05-25,2016-03-09
-3fyw,2009-08-04,2009-01-23
-2fya,2006-03-14,2006-02-07
-3fyv,2009-08-04,2009-01-23
-6fyp,2018-07-18,2018-03-12
-6fyz,2018-12-05,2018-03-13
-6fyd,2018-05-02,2018-03-11
-4fy0,2012-08-08,2012-07-03
-8fyp,2023-03-08,2023-01-26
-5fys,2017-03-22,2016-03-09
-1fyz,2001-02-21,2000-10-03
-4fyd,2013-02-27,2012-07-04
-6fyu,2018-11-07,2018-03-12
-4fys,2012-09-05,2012-07-05
-4fyy,2012-10-10,2012-07-05
-3fy9,2009-08-04,2009-01-22
-6fyo,2018-07-18,2018-03-12
-8fyv,2024-05-15,2023-01-26
-8fyr,2023-03-08,2023-01-26
-5fy7,2016-03-16,2016-03-04
-6fyl,2018-07-18,2018-03-12
-7fyo,2023-06-14,2023-04-27
-7fyd,2023-06-14,2023-04-27
-2fyy,2006-12-26,2006-02-08
-2fyp,2007-02-06,2006-02-08
-7fyi,2023-06-14,2023-04-27
-4fyi,2013-01-02,2012-07-04
-3fym,2010-02-09,2009-01-22
-6fy9,2018-05-02,2018-03-11
-6fyg,2018-05-02,2018-03-11
-8fyw,2023-06-07,2023-01-26
-8fy0,2024-04-10,2023-01-25
-3fyt,2010-01-26,2009-01-23
-7fy7,2023-06-14,2023-04-27
-6fyq,2018-12-12,2018-03-12
-4fyk,2013-01-02,2012-07-04
-6fyk,2018-07-18,2018-03-12
-3fyu,2010-01-26,2009-01-23
-6fyv,2018-07-18,2018-03-12
-5fye,2017-03-22,2016-03-07
-7fyj,2023-06-14,2023-04-27
-6fyb,2018-05-02,2018-03-11
-4fyg,2012-08-22,2012-07-04
-2fye,2006-08-08,2006-02-07
-7fyu,2023-06-14,2023-04-27
-1fyd,2001-06-06,2000-09-28
-8fys,2023-03-08,2023-01-26
-6fyx,2018-12-05,2018-03-12
-3fyb,2009-02-03,2009-01-22
-3fyl,2009-04-21,2009-01-22
-1fy3,2001-09-28,2000-09-28
-3fyp,2009-03-31,2009-01-22
-2fyn,2006-08-29,2006-02-08
-8fy1,2024-04-10,2023-01-25
-5fyf,2017-01-18,2016-03-07
-5fyy,2016-03-23,2016-03-10
-7fyb,2023-06-14,2023-04-27
-2fy5,2006-12-12,2006-02-07
-2fyu,2006-08-29,2006-02-08
-2fyt,2006-03-14,2006-02-08
-8fyl,2024-05-15,2023-01-26
-8fy8,2024-05-15,2023-01-25
-1fy6,2001-04-21,2000-09-28
-3fyh,2009-09-01,2009-01-22
-6fy4,2019-03-20,2018-03-10
-7fyc,2023-06-14,2023-04-27
-3fyi,2009-06-16,2009-01-22
-2fyl,2006-10-10,2006-02-08
-5fy9,2017-03-22,2016-03-04
-5fyo,2017-01-18,2016-03-08
-7fyz,2023-06-14,2023-04-27
-4fyv,2012-10-10,2012-07-05
-2fyr,2006-07-25,2006-02-08
-2fy4,2006-12-12,2006-02-07
-5fyp,2017-01-18,2016-03-09
-1fyt,2000-11-08,2000-10-03
-1fy7,2000-11-29,2000-09-28
-8fy7,2023-08-30,2023-01-25
-3fyx,2009-06-30,2009-01-23
-5fyu,2016-03-23,2016-03-09
-5fyb,2017-03-29,2016-03-05
-6fyf,2018-05-02,2018-03-11
-8fyt,2024-05-15,2023-01-26
-1fyu,2000-10-25,2000-10-03
-5fyz,2016-03-23,2016-03-10
-8fyj,2023-10-18,2023-01-26
-4fyr,2012-09-05,2012-07-05
-7fy4,2023-06-14,2023-04-27
-5fyw,2016-05-18,2016-03-10
-4fyq,2012-09-05,2012-07-05
-7fye,2023-06-14,2023-04-27
-3fy4,2009-04-28,2009-01-21
-5fy5,2017-03-22,2016-03-04
-7fyp,2023-06-14,2023-04-27
-3fyj,2009-04-07,2009-01-22
-4fyh,2013-01-02,2012-07-04
-4fyx,2012-10-10,2012-07-05
-8fyy,2024-02-07,2023-01-27
-8fyi,2023-10-18,2023-01-26
-5fyn,2016-06-08,2016-03-08
-4fyo,2013-01-30,2012-07-05
-3fyo,2009-03-24,2009-01-22
-6fyr,2018-07-18,2018-03-12
-4fyf,2012-08-22,2012-07-04
-7fym,2023-06-14,2023-04-27
-1fyf,2000-12-27,2000-09-29
-1fyn,1996-11-08,1995-05-17
-6fyh,2018-07-11,2018-03-12
-7fyw,2023-06-14,2023-04-27
-5fy8,2016-03-16,2016-03-04
-7fys,2023-06-14,2023-04-27
-8fyn,2023-03-08,2023-01-26
-5fyk,2016-04-27,2016-03-08
-6fyy,2018-12-05,2018-03-12
-5fy1,2016-03-16,2016-03-03
-2fyd,2006-03-14,2006-02-07
-5fym,2016-03-16,2016-03-08
-2fyf,2007-01-16,2006-02-07
-8fyo,2023-05-24,2023-01-26
-7fy8,2023-06-14,2023-04-27
-7fyv,2023-06-14,2023-04-27
-2fyk,2006-08-08,2006-02-08
-4fyn,2013-01-30,2012-07-05
-1fyr,2000-12-06,2000-10-03
-1fy5,2001-02-07,2000-09-28
-3fy8,2009-08-04,2009-01-22
-7fyg,2023-06-14,2023-04-27
-8fyz,2024-02-07,2023-01-27
-3fyn,2009-02-10,2009-01-22
-5fyl,2016-04-27,2016-03-08
-7fyr,2023-06-14,2023-04-27
-7fy6,2023-06-14,2023-04-27
-8fy6,2023-08-30,2023-01-25
-8fy2,2024-04-10,2023-01-25
-5fyv,2017-03-22,2016-03-10
-2fyg,2006-08-08,2006-02-07
-2fyc,2006-03-14,2006-02-07
-3fyz,2010-02-09,2009-01-23
-8fyq,2023-03-08,2023-01-26
-5fy4,2017-03-22,2016-03-04
-7fyy,2023-06-14,2023-04-27
-6fy8,2018-05-02,2018-03-11
-3fy2,2009-02-03,2009-01-21
-7fyk,2023-06-14,2023-04-27
-3fyg,1999-06-01,1997-08-07
-5fyg,2017-01-18,2016-03-07
-7fy5,2023-06-14,2023-04-27
-7fy2,2023-06-14,2023-04-27
-7fyl,2023-06-14,2023-04-27
-3fy1,2009-03-10,2009-01-21
-6fyj,2018-08-22,2018-03-12
-6fyc,2018-05-02,2018-03-11
-8fym,2023-10-11,2023-01-26
-1fye,2001-01-10,2000-09-29
-6fyw,2018-11-07,2018-03-12
-1fys,2000-10-25,2000-10-03
-4fyt,2012-09-05,2012-07-05
-1fy4,2001-02-07,2000-09-28
-7fyx,2023-06-14,2023-04-27
-5fyx,2017-01-25,2016-03-10
-3fye,2009-06-16,2009-01-22
-6fye,2018-05-02,2018-03-11
-7fy0,2023-06-14,2023-04-27
-1fy1,2001-09-28,2000-09-28
-5kfi,2016-06-29,2016-06-12
-1kf6,2002-03-13,2001-11-19
-4kfg,2014-01-15,2013-04-26
-6kfm,2019-09-25,2019-07-08
-4kf2,2013-07-10,2013-04-26
-4kfo,2013-05-08,2013-04-27
-6kf4,2020-07-01,2019-07-06
-5kfj,2016-06-22,2016-06-12
-5kfk,2016-06-22,2016-06-12
-3kf2,2010-03-09,2009-10-27
-5kf1,2016-07-06,2016-06-11
-4kfp,2013-08-14,2013-04-27
-7kfo,2021-11-10,2020-10-14
-1kfj,2003-10-21,2001-11-21
-2kfy,2010-06-09,2009-03-02
-7kf6,2021-04-14,2020-10-13
-7kff,2020-10-28,2020-10-13
-3kf3,2010-02-23,2009-10-27
-3kf4,2009-12-22,2009-10-27
-4kft,2013-05-22,2013-04-27
-1kfs,1998-02-25,1997-08-18
-3kfe,2010-06-23,2009-10-27
-1kfg,2003-07-15,2001-11-20
-2kfx,2009-06-09,2009-02-28
-3kfh,2010-06-16,2009-10-27
-5kfn,2016-06-22,2016-06-12
-3kf7,2009-12-29,2009-10-27
-2kfn,1998-11-11,1998-07-01
-6kf9,2020-07-01,2019-07-07
-2kft,2009-04-28,2009-02-27
-4kf0,2013-07-10,2013-04-26
-4kfn,2013-05-08,2013-04-27
-5kft,2016-06-22,2016-06-12
-3kfc,2009-12-08,2009-10-27
-5kfz,2016-06-22,2016-06-12
-5kf6,2016-10-05,2016-06-12
-5kfm,2016-06-22,2016-06-12
-4kfa,2014-04-30,2013-04-26
-4kfv,2013-08-21,2013-04-28
-6kf7,2020-07-08,2019-07-06
-5kfe,2016-06-22,2016-06-12
-6kfq,2020-04-08,2019-07-08
-7kfz,2021-03-31,2020-10-15
-3kfb,2010-06-23,2009-10-27
-6kfu,2019-09-25,2019-07-08
-3kfr,2010-02-23,2009-10-27
-7kfp,2021-03-10,2020-10-14
-1kfv,2002-06-14,2001-11-23
-4kfu,2013-05-22,2013-04-27
-5kfg,2016-06-29,2016-06-12
-6kfs,2020-07-15,2019-07-08
-5kfy,2016-06-22,2016-06-12
-7kfh,2021-04-28,2020-10-13
-3kfa,2009-12-22,2009-10-27
-7kf7,2021-04-14,2020-10-13
-4kfj,2013-10-09,2013-04-26
-2kfz,1998-11-11,1998-07-02
-4kfz,2014-01-22,2013-04-28
-6kfd,2020-07-08,2019-07-07
-5kf0,2016-11-09,2016-06-10
-5kfh,2016-06-22,2016-06-12
-7kfw,2020-12-02,2020-10-15
-6kfn,2019-10-30,2019-07-08
-7kfa,2021-11-10,2020-10-13
-7kf9,2021-04-28,2020-10-13
-3kff,2010-06-16,2009-10-27
-6kfa,2020-07-08,2019-07-07
-4kf1,2013-10-02,2013-04-26
-4kfq,2013-10-09,2013-04-27
-4kf9,2013-05-22,2013-04-26
-7kfe,2021-04-28,2020-10-13
-7kfq,2021-11-10,2020-10-14
-6kfe,2020-07-08,2019-07-07
-2kfg,2009-12-22,2009-02-20
-6kfb,2020-07-08,2019-07-07
-5kfp,2016-06-22,2016-06-12
-5kfc,2016-06-22,2016-06-12
-5kfd,2016-06-22,2016-06-12
-1kfr,2002-04-24,2001-11-22
-3kfs,2010-02-23,2009-10-28
-1kfc,2003-01-07,2001-11-20
-5kfu,2016-06-22,2016-06-12
-7kfm,2021-10-20,2020-10-14
-3kfl,2010-10-27,2009-10-27
-4kfs,2013-05-22,2013-04-27
-8kfx,2024-02-07,2023-08-16
-6kf1,2020-07-08,2019-07-05
-7kfv,2020-12-02,2020-10-15
-7kfn,2021-06-16,2020-10-14
-4kfm,2013-06-12,2013-04-27
-3kfu,2010-08-25,2009-10-28
-2kff,2009-12-22,2009-02-20
-3kfn,2010-02-23,2009-10-27
-1kfa,2002-09-11,2001-11-20
-5kfo,2016-06-22,2016-06-12
-5kf8,2016-07-06,2016-06-12
-5kf7,2016-10-05,2016-06-12
-6kfc,2020-07-08,2019-07-07
-5kfr,2016-06-22,2016-06-12
-3kfx,2010-09-15,2009-10-28
-2kfh,2009-12-22,2009-02-20
-6kf3,2020-07-01,2019-07-06
-4kfd,2013-08-21,2013-04-26
-3kf0,2010-02-23,2009-10-27
-7kfy,2020-12-02,2020-10-15
-1kfl,2002-08-23,2001-11-21
-3kfj,2010-03-02,2009-10-27
-3kfk,2010-06-23,2009-10-27
-4kfr,2013-05-22,2013-04-27
-5kf9,2016-07-06,2016-06-12
-5kf2,2016-07-06,2016-06-11
-5kfa,2016-06-22,2016-06-12
-1kfq,2002-01-16,2001-11-22
-5kfs,2016-06-29,2016-06-12
-7kfx,2020-12-02,2020-10-15
-3kf9,2011-01-26,2009-10-27
-1kfk,2003-10-21,2001-11-21
-7kfr,2020-12-16,2020-10-14
-3kfi,2010-06-16,2009-10-27
-5kfv,2016-06-22,2016-06-12
-3kfm,2010-02-09,2009-10-27
-6kfz,2019-10-16,2019-07-09
-3kfy,2010-12-08,2009-10-28
-3kfg,2010-06-16,2009-10-27
-5kfx,2016-06-22,2016-06-12
-1kfb,2003-01-07,2001-11-20
-7kf8,2021-04-14,2020-10-13
-4kfe,2013-08-21,2013-04-26
-5kfw,2016-06-22,2016-06-12
-4kfb,2013-05-15,2013-04-26
-3kf5,2010-02-23,2009-10-27
-3kfp,2010-02-23,2009-10-27
-1kf0,2002-07-24,2001-11-19
-1kfy,2002-03-13,2001-11-24
-5kfl,2016-06-22,2016-06-12
-1kfi,2002-01-16,2001-11-21
-6kf5,2020-07-08,2019-07-06
-7kfb,2021-04-28,2020-10-13
-3kft,2010-02-02,2009-10-28
-5kfb,2016-06-22,2016-06-12
-8kfd,2024-05-29,2023-08-15
-6kfr,2019-09-25,2019-07-08
-5kfq,2016-06-29,2016-06-12
-4kff,2013-08-28,2013-04-26
-1kfe,2003-01-07,2001-11-20
-1kfd,1994-06-22,1993-09-23
-6kfw,2020-07-15,2019-07-09
-5kff,2016-06-22,2016-06-12
-7kfk,2021-03-31,2020-10-14
-8kfy,2024-02-07,2023-08-16
-6kft,2020-07-15,2019-07-08
-7kf3,2020-11-04,2020-10-13
-4xwr,2015-12-30,2015-01-29
-7xwe,2023-05-31,2022-05-26
-6xwz,2021-02-03,2020-01-24
-5xw0,2018-03-21,2017-06-28
-4xwt,2015-12-16,2015-01-29
-6xwg,2020-09-09,2020-01-23
-6xwe,2020-08-12,2020-01-23
-7xw9,2022-12-28,2022-05-26
-5xw8,2018-03-28,2017-06-29
-7xwz,2023-02-08,2022-05-27
-2xwg,2011-02-23,2010-11-02
-2xwn,2011-04-27,2010-11-04
-6xwp,2020-03-04,2020-01-24
-2xwe,2011-09-14,2010-11-02
-2xwm,2011-04-27,2010-11-04
-2xwr,2011-03-30,2010-11-04
-7xwp,2022-07-20,2022-05-27
-7xw6,2022-08-17,2022-05-26
-2xwt,2011-03-09,2010-11-05
-7xw5,2022-08-24,2022-05-26
-4xwh,2016-02-03,2015-01-28
-7xwv,2023-01-18,2022-05-27
-7xwg,2023-05-31,2022-05-26
-4xwz,2016-02-10,2015-01-29
-2xwy,2010-12-22,2010-11-06
-1xwh,2005-01-25,2004-11-01
-2xw7,2010-12-01,2010-11-01
-7xwf,2023-05-31,2022-05-26
-7xwq,2022-07-20,2022-05-27
-1xw4,2005-05-24,2004-10-29
-4xwk,2016-04-27,2015-01-28
-5xw6,2017-10-25,2017-06-29
-6xwq,2020-03-04,2020-01-24
-4xwp,2015-02-18,2015-01-28
-5xwm,2019-01-02,2017-06-30
-6xwb,2020-04-15,2020-01-23
-2xwq,2010-12-22,2010-11-04
-1xwk,2004-12-21,2004-11-01
-5xwl,2018-03-28,2017-06-29
-2xwl,2011-04-27,2010-11-04
-5xwd,2018-02-28,2017-06-29
-2xwb,2011-01-12,2010-11-01
-4xw5,2015-05-06,2015-01-28
-1xwd,2005-01-25,2004-10-30
-6xwl,2021-02-03,2020-01-23
-6xwo,2020-03-04,2020-01-24
-5xwj,2018-03-28,2017-06-29
-5xws,2018-06-06,2017-06-30
-5xwe,2018-07-11,2017-06-29
-2xwi,2011-11-23,2010-11-04
-1xwa,2004-11-16,2004-10-29
-1xwb,2004-11-16,2004-10-29
-7xwt,2023-01-18,2022-05-27
-1xws,2004-11-16,2004-11-02
-6xw7,2020-04-22,2020-01-23
-5xwi,2018-07-04,2017-06-29
-7xww,2023-05-31,2022-05-27
-7xwi,2022-10-26,2022-05-26
-1xwf,2005-09-20,2004-11-01
-6xw6,2020-04-22,2020-01-23
-2xwp,2010-12-22,2010-11-04
-6xwh,2020-09-09,2020-01-23
-1xwq,2005-10-11,2004-11-02
-2xw1,2010-11-10,2010-10-28
-1xw6,2004-12-21,2004-10-29
-4xwx,2015-02-25,2015-01-29
-7xw8,2022-10-12,2022-05-26
-5xww,2018-06-06,2017-06-30
-5xwt,2018-06-06,2017-06-30
-4xwg,2015-07-29,2015-01-28
-7xwh,2022-10-26,2022-05-26
-5xwz,2018-05-02,2017-06-30
-5xwv,2018-06-06,2017-06-30
-2xwd,2011-09-14,2010-11-01
-5xwu,2018-06-06,2017-06-30
-5xw1,2018-07-04,2017-06-28
-5xw9,2018-03-28,2017-06-29
-7xw2,2023-03-08,2022-05-26
-4xwi,2015-04-29,2015-01-28
-7xwl,2022-10-26,2022-05-26
-5xwa,2018-03-28,2017-06-29
-4xw4,2015-05-06,2015-01-28
-4xw2,2016-01-13,2015-01-28
-2xwo,2011-11-16,2010-11-04
-6xw0,2020-02-19,2020-01-22
-4xwm,2015-10-28,2015-01-29
-2xwj,2011-01-12,2010-11-04
-6xw2,2020-01-29,2020-01-22
-4xwa,2015-02-11,2015-01-28
-2xw0,2010-11-10,2010-10-28
-4xwo,2015-03-25,2015-01-29
-1xw5,2004-11-30,2004-10-29
-7xwn,2022-10-26,2022-05-26
-7xwm,2023-04-12,2022-05-26
-7xwj,2022-10-26,2022-05-26
-7xwa,2022-09-28,2022-05-26
-6xwk,2020-04-29,2020-01-23
-7xwk,2022-10-26,2022-05-26
-1xwy,2005-01-25,2004-11-02
-4xww,2015-12-16,2015-01-29
-2xwz,2011-05-18,2010-11-06
-6xwn,2020-03-04,2020-01-24
-6xwm,2020-05-06,2020-01-24
-7xwu,2023-05-31,2022-05-27
-5xw2,2018-04-25,2017-06-29
-4xwn,2015-10-28,2015-01-29
-4xwy,2015-07-01,2015-01-29
-5xw5,2017-08-09,2017-06-29
-5xwc,2018-03-21,2017-06-29
-7xwd,2023-05-31,2022-05-26
-4xwl,2015-10-28,2015-01-29
-6xwd,2020-11-04,2020-01-23
-7xwr,2022-07-20,2022-05-27
-1xw7,2005-04-12,2004-10-29
-5xwk,2018-07-18,2017-06-29
-4xw6,2015-05-06,2015-01-28
-2xwv,2011-11-16,2010-11-05
-2xwk,2011-11-23,2010-11-04
-2xwc,2010-11-17,2010-11-03
-5yec,2018-03-28,2017-09-16
-4yeb,2015-08-19,2015-02-23
-7yew,2023-07-12,2022-07-06
-7ye5,2022-08-24,2022-07-05
-7yen,2023-07-12,2022-07-06
-1yeu,2005-01-11,2004-12-28
-2yec,2011-06-15,2011-03-25
-7yes,2022-10-05,2022-07-06
-1yev,2005-01-11,2004-12-28
-2yea,2011-06-15,2011-03-25
-6yeu,2021-03-31,2020-03-25
-7yex,2023-07-12,2022-07-06
-2ye2,2011-06-15,2011-03-25
-1yem,2005-01-11,2004-12-28
-2yex,2012-03-14,2011-03-31
-2yeo,2011-04-13,2011-03-28
-2yek,2011-06-15,2011-03-25
-6yes,2020-10-28,2020-03-25
-1yef,1997-12-03,1997-05-29
-7yez,2023-03-29,2022-07-06
-2yeh,2011-06-15,2011-03-25
-6yeh,2020-05-20,2020-03-24
-5yeg,2017-11-29,2017-09-17
-1yet,1998-04-22,1997-03-25
-2ye7,2011-06-15,2011-03-25
-5yea,2018-07-25,2017-09-15
-6yeo,2020-06-24,2020-03-25
-7ye2,2023-01-18,2022-07-05
-7yei,2023-11-22,2022-07-05
-6yem,2020-09-09,2020-03-25
-7yec,2023-11-22,2022-07-05
-5ye8,2018-07-25,2017-09-15
-4yem,2015-03-04,2015-02-24
-5ye4,2018-08-22,2017-09-15
-5yef,2017-11-29,2017-09-17
-4yen,2015-03-04,2015-02-24
-4yec,2016-03-16,2015-02-24
-4yed,2016-01-13,2015-02-24
-6yei,2020-05-20,2020-03-24
-4ye4,2015-07-22,2015-02-23
-7yek,2023-11-22,2022-07-06
-7yer,2022-10-05,2022-07-06
-6ye0,2021-01-20,2020-03-23
-4yek,2016-03-02,2015-02-24
-6ye3,2020-12-30,2020-03-23
-5yeq,2018-07-04,2017-09-19
-2ye8,2011-06-15,2011-03-25
-4yef,2015-06-24,2015-02-24
-2yed,2011-06-15,2011-03-25
-7ye0,2023-11-22,2022-07-05
-1yea,1993-10-31,1991-10-29
-4yee,2015-04-01,2015-02-24
-1yew,2005-02-08,2004-12-28
-1ye9,2005-04-26,2004-12-28
-1ye1,2005-01-04,2004-12-27
-5yee,2018-09-19,2017-09-16
-6ye6,2021-01-20,2020-03-24
-2yer,2012-03-14,2011-03-30
-7yey,2023-07-12,2022-07-06
-7yeb,2023-11-22,2022-07-05
-7yev,2023-03-29,2022-07-06
-7yeo,2023-01-11,2022-07-06
-7yeg,2022-08-24,2022-07-05
-2yet,2011-09-07,2011-03-30
-5ye3,2018-08-22,2017-09-15
-2yej,2011-06-15,2011-03-25
-4yeh,2015-03-25,2015-02-24
-6ye2,2021-01-20,2020-03-23
-1yen,2005-01-11,2004-12-28
-1yeo,2005-02-01,2004-12-28
-7yed,2023-04-05,2022-07-05
-2yeg,2011-06-15,2011-03-25
-5yei,2018-08-29,2017-09-17
-2yef,2011-06-15,2011-03-25
-5yel,2017-11-29,2017-09-18
-7yee,2023-11-22,2022-07-05
-1ye8,2005-03-29,2004-12-28
-6yea,2021-03-31,2020-03-24
-2yes,2011-04-06,2011-03-30
-6ye7,2021-01-20,2020-03-24
-1yej,1999-01-13,1998-08-13
-2yel,2011-06-15,2011-03-25
-2ye4,2011-06-15,2011-03-25
-6ye9,2021-03-31,2020-03-24
-2yeu,2011-07-06,2011-03-30
-6yez,2020-09-30,2020-03-25
-5ye5,2017-11-15,2017-09-15
-1yek,1999-01-13,1998-08-13
-1yeg,1997-12-03,1997-05-29
-1yei,1999-01-13,1998-08-13
-4ye2,2015-04-29,2015-02-23
-2yeq,2012-04-18,2011-03-30
-6ye1,2021-01-20,2020-03-23
-5yeh,2017-11-29,2017-09-17
-7yeh,2023-07-12,2022-07-05
-1ye2,2005-01-04,2004-12-27
-4yel,2016-03-09,2015-02-24
-2yep,2011-09-07,2011-03-29
-7yep,2022-08-17,2022-07-06
-2ye9,2011-06-15,2011-03-25
-1yey,2005-01-11,2004-12-28
-7ye3,2023-07-05,2022-07-05
-2yee,2011-06-15,2011-03-25
-1ye4,2005-02-01,2004-12-28
-1yed,1997-10-15,1997-04-15
-7yel,2023-11-22,2022-07-06
-4ye3,2015-06-10,2015-02-23
-6yef,2021-01-27,2020-03-24
-5ye9,2018-07-25,2017-09-15
-4yea,2015-03-18,2015-02-23
-1yeq,2005-01-11,2004-12-28
-1yeh,1997-12-03,1997-05-29
-6yen,2020-06-24,2020-03-25
-2ye1,2012-04-11,2011-03-25
-2ye3,2011-06-15,2011-03-25
-5yew,2018-01-31,2017-09-20
-5yeu,2018-07-25,2017-09-19
-6yet,2021-03-31,2020-03-25
-4yer,2015-03-11,2015-02-24
-1ye3,2005-01-11,2004-12-27
-7yem,2023-11-22,2022-07-06
-4yes,2015-06-17,2015-02-24
-7ye1,2023-01-18,2022-07-05
-6ye8,2021-01-20,2020-03-24
-6yev,2021-04-07,2020-03-25
-1ye0,2005-01-04,2004-12-27
-1yee,1997-10-15,1997-04-15
-2yem,2011-06-15,2011-03-25
-2yeb,2011-06-15,2011-03-25
-4ye1,2015-05-13,2015-02-23
-2yei,2011-06-15,2011-03-25
-2ye5,2011-06-15,2011-03-25
-7yej,2023-11-22,2022-07-05
-2yev,2012-05-23,2011-03-31
-5yem,2018-07-18,2017-09-18
-7yet,2022-10-05,2022-07-06
-2ye6,2011-06-15,2011-03-25
-1yec,1997-10-15,1997-04-15
-4yej,2016-03-09,2015-02-24
-1ye6,2005-02-01,2004-12-28
-4yet,2015-04-15,2015-02-24
-5ye7,2018-07-25,2017-09-15
-1yeb,1993-10-31,1991-10-29
-4yeo,2015-03-04,2015-02-24
-7ye9,2022-08-24,2022-07-05
-4g4v,2013-07-24,2012-07-16
-5g4m,2016-06-22,2016-05-13
-4g4z,2013-07-24,2012-07-16
-2g4n,2007-02-20,2006-02-22
-2g43,2006-04-04,2006-02-21
-3g4u,2009-12-01,2009-02-04
-6g4d,2019-04-10,2018-03-27
-3g4a,2009-04-07,2009-02-03
-6g47,2018-05-02,2018-03-26
-8g4f,2023-08-09,2023-02-09
-2g49,2006-10-24,2006-02-21
-1g4t,2001-09-26,2000-10-28
-4g4p,2013-07-17,2012-07-16
-6g4m,2018-08-29,2018-03-28
-4g42,2012-11-21,2012-07-16
-1g4s,2001-09-26,2000-10-27
-8g44,2023-05-03,2023-02-08
-5g41,2016-12-28,2016-05-03
-8g4o,2023-09-20,2023-02-10
-2g4b,2006-07-25,2006-02-21
-4g4o,2013-02-20,2012-07-16
-5g4c,2017-05-03,2016-05-09
-6g4g,2018-11-07,2018-03-27
-8g4x,2023-09-20,2023-02-10
-5g48,2017-06-21,2016-05-06
-1g4h,2001-10-27,2000-10-27
-3g4l,2010-01-19,2009-02-03
-6g40,2019-04-10,2018-03-26
-8g43,2023-05-03,2023-02-08
-5g4r,2016-07-06,2016-05-16
-1g4x,2000-11-22,2000-10-29
-6g4f,2019-04-10,2018-03-27
-5g47,2016-07-06,2016-05-05
-2g4h,2007-03-06,2006-02-22
-1g4c,2003-04-15,2000-10-26
-8g4p,2023-12-20,2023-02-10
-3g4z,2009-04-28,2009-02-04
-3g4f,2009-06-23,2009-02-03
-5g4b,2016-07-20,2016-05-08
-3g4h,2010-02-02,2009-02-03
-8g4d,2023-06-21,2023-02-09
-1g4v,2000-11-22,2000-10-28
-8g4t,2023-07-12,2023-02-10
-5g4j,2016-10-19,2016-05-13
-6g4w,2018-06-06,2018-03-28
-4g46,2012-09-05,2012-07-16
-5g46,2016-08-03,2016-05-04
-3g43,2009-03-03,2009-02-03
-6g46,2018-09-26,2018-03-26
-1g4y,2001-05-09,2001-01-07
-6g4y,2018-07-04,2018-03-28
-2g4t,2007-02-20,2006-02-22
-1g46,2000-11-08,2000-10-26
-5g4n,2016-06-22,2016-05-13
-1g4u,2001-01-24,2000-10-28
-8g4h,2023-08-09,2023-02-09
-3g4i,2010-01-19,2009-02-03
-5g44,2016-08-03,2016-05-04
-5g4l,2016-12-07,2016-05-13
-8g46,2023-03-08,2023-02-08
-8g49,2024-02-21,2023-02-08
-5g45,2016-08-03,2016-05-04
-1g4k,2001-04-25,2000-10-27
-8g47,2023-08-09,2023-02-08
-4g4r,2013-02-20,2012-07-16
-5g4e,2017-04-19,2016-05-12
-5g4w,2017-04-19,2016-05-17
-2g42,2006-03-07,2006-02-21
-8g41,2023-02-15,2023-02-08
-3g4x,2009-04-28,2009-02-04
-5g4o,2016-06-22,2016-05-13
-1g4i,2001-04-04,2000-10-27
-3g49,2009-08-04,2009-02-03
-3g4s,2009-04-28,2009-02-04
-8g4w,2023-06-21,2023-02-10
-3g4c,2009-04-14,2009-02-03
-4g45,2012-09-05,2012-07-16
-1g43,2000-12-01,2000-10-26
-8g4m,2023-07-12,2023-02-10
-1g4a,2001-02-21,2000-10-26
-3g46,2009-12-01,2009-02-03
-4g44,2012-09-05,2012-07-16
-4g4y,2013-07-24,2012-07-16
-1g4j,2000-11-08,2000-10-27
-3g4v,2009-12-01,2009-02-04
-6g4n,2018-08-29,2018-03-28
-2g4j,2007-02-20,2006-02-22
-6g4e,2019-04-10,2018-03-27
-2g44,2007-01-09,2006-02-21
-5g42,2016-08-03,2016-05-04
-6g4p,2018-08-29,2018-03-28
-3g4w,2009-12-01,2009-02-04
-3g4t,2010-03-09,2009-02-04
-3g4g,2010-01-19,2009-02-03
-6g4z,2018-07-04,2018-03-28
-4g4c,2012-11-07,2012-07-16
-1g41,2000-11-22,2000-10-25
-4g4x,2013-07-24,2012-07-16
-6g4o,2018-08-29,2018-03-28
-4g4q,2013-02-20,2012-07-16
-4g4w,2013-07-24,2012-07-16
-4g43,2012-11-21,2012-07-16
-2g4i,2007-02-20,2006-02-22
-5g4p,2017-05-03,2016-05-15
-3g42,2009-05-19,2009-02-03
-3g4k,2010-01-19,2009-02-03
-6g48,2019-01-16,2018-03-27
-8g4z,2024-01-03,2023-02-10
-6g4t,2018-06-06,2018-03-28
-4g4h,2012-11-07,2012-07-16
-3g4r,2009-12-01,2009-02-04
-8g4c,2023-06-21,2023-02-09
-5g49,2016-12-07,2016-05-06
-1g42,2001-10-26,2000-10-26
-8g4a,2024-02-14,2023-02-08
-2g4k,2007-02-20,2006-02-22
-2g46,2006-12-05,2006-02-21
-1g45,2000-11-08,2000-10-26
-2g4z,2007-02-20,2006-02-22
-8g45,2023-05-03,2023-02-08
-5g4i,2016-10-19,2016-05-13
-5g43,2016-08-03,2016-05-04
-2g4v,2007-02-20,2006-02-22
-8g40,2023-05-31,2023-02-08
-4g4s,2012-09-05,2012-07-16
-4g48,2012-09-05,2012-07-16
-4g4n,2013-02-20,2012-07-16
-3g4e,2010-02-02,2009-02-03
-5g4q,2017-06-21,2016-05-16
-8g42,2023-08-09,2023-02-08
-1g47,2001-02-21,2000-10-26
-2g4u,2007-02-20,2006-02-22
-6g4l,2019-04-10,2018-03-27
-1g4o,2000-11-08,2000-10-27
-3g4q,2009-12-01,2009-02-04
-4g47,2012-09-05,2012-07-16
-4g41,2012-09-12,2012-07-15
-5g4h,2016-12-07,2016-05-13
-2g45,2006-04-04,2006-02-21
-1g49,2001-10-24,2000-10-26
-8g4s,2024-01-31,2023-02-10
-1g48,2000-11-08,2000-10-26
-3g45,2010-01-19,2009-02-03
-4g4j,2013-01-02,2012-07-16
-2g41,2006-04-04,2006-02-21
-5g4s,2016-07-06,2016-05-16
-8g4v,2023-02-22,2023-02-10
-3g4y,2009-12-01,2009-02-04
-8g4n,2023-09-20,2023-02-10
-1g4p,2001-09-26,2000-10-27
-5g40,2016-12-28,2016-05-03
-6oeo,2020-01-29,2019-03-27
-8oe4,2024-02-07,2023-03-10
-2oep,2007-06-19,2006-12-31
-8oew,2023-10-18,2023-03-13
-7oei,2021-10-20,2021-05-03
-6oe0,2019-06-12,2019-03-27
-6oep,2020-01-29,2019-03-27
-7oe9,2021-07-28,2021-05-02
-7oed,2021-10-20,2021-05-03
-1oe5,2003-07-11,2003-03-19
-4oew,2015-04-01,2014-01-14
-5oey,2017-09-20,2017-07-10
-4oek,2014-01-22,2014-01-13
-7oez,2021-06-16,2021-05-04
-7oeh,2021-10-20,2021-05-03
-8oej,2023-05-10,2023-03-10
-7oec,2021-05-26,2021-05-03
-3oer,2011-08-24,2010-08-13
-7oej,2021-10-20,2021-05-03
-8oep,2023-05-10,2023-03-11
-8oet,2023-11-22,2023-03-12
-1oe3,2004-07-21,2003-03-18
-5oeg,2017-07-26,2017-07-07
-1oec,2004-10-27,2003-03-24
-6oew,2019-04-17,2019-03-27
-4oel,2015-03-25,2014-01-13
-5oes,2018-04-25,2017-07-10
-6oez,2019-07-31,2019-03-28
-3oe5,2011-03-16,2010-08-12
-1oew,2003-04-02,2003-03-31
-7oe8,2021-07-28,2021-05-02
-6oem,2020-01-29,2019-03-27
-3oek,2011-05-11,2010-08-12
-4oee,2014-07-09,2014-01-13
-4oe9,2015-03-04,2014-01-12
-2oec,2008-01-01,2006-12-29
-4oeg,2014-07-09,2014-01-13
-6oea,2019-04-10,2019-03-27
-3oec,2010-09-01,2010-08-12
-8oeu,2023-10-18,2023-03-13
-7oex,2021-12-22,2021-05-04
-3oez,2011-08-17,2010-08-13
-8oer,2024-03-27,2023-03-12
-1oe6,2003-07-11,2003-03-19
-5oeq,2018-05-16,2017-07-09
-4oec,2015-01-14,2014-01-13
-4oei,2014-02-05,2014-01-13
-2oel,2007-03-20,2006-12-30
-5oed,2018-01-10,2017-07-07
-5oex,2018-08-01,2017-07-10
-5oee,2017-10-11,2017-07-07
-3oea,2010-08-25,2010-08-12
-5oec,2018-01-10,2017-07-07
-7oee,2021-10-20,2021-05-03
-4oef,2014-07-09,2014-01-13
-3oew,2010-12-01,2010-08-13
-8oem,2023-08-30,2023-03-10
-5oei,2017-11-08,2017-07-07
-4oeu,2014-10-01,2014-01-13
-7oe4,2021-07-28,2021-05-01
-3oe1,2010-09-08,2010-08-12
-8oev,2023-10-18,2023-03-13
-8oes,2024-03-27,2023-03-12
-7oep,2021-07-21,2021-05-03
-5oeh,2017-07-26,2017-07-07
-7oe6,2021-07-28,2021-05-01
-4oe4,2014-02-19,2014-01-11
-3oe7,2010-09-15,2010-08-12
-1oek,2003-08-15,2003-03-28
-7oeg,2021-10-20,2021-05-03
-1oej,2003-08-15,2003-03-27
-7oes,2021-07-21,2021-05-03
-4oes,2014-10-01,2014-01-13
-6oe2,2019-12-25,2019-03-27
-8oe0,2024-02-07,2023-03-10
-8oeh,2023-09-06,2023-03-10
-4oe2,2014-12-24,2014-01-11
-4oe5,2014-02-19,2014-01-11
-5oew,2018-01-03,2017-07-10
-1oe0,2003-10-23,2003-03-17
-1oex,2003-04-02,2003-03-31
-7oek,2021-10-20,2021-05-03
-3oel,2011-05-11,2010-08-12
-7oea,2021-12-01,2021-05-02
-6oel,2019-08-07,2019-03-27
-6oe6,2019-04-17,2019-03-27
-1oeb,2003-04-02,2003-03-24
-3oeb,2010-08-25,2010-08-12
-4oev,2014-10-01,2014-01-13
-3oey,2010-12-01,2010-08-13
-6oex,2019-07-31,2019-03-28
-7oem,2021-10-20,2021-05-03
-2oee,2007-01-30,2006-12-29
-6oev,2019-04-17,2019-03-27
-4oeh,2015-03-04,2014-01-13
-5oea,2017-10-11,2017-07-07
-6oes,2020-01-22,2019-03-27
-5oet,2018-04-25,2017-07-10
-4oe7,2014-12-24,2014-01-12
-7oer,2021-07-21,2021-05-03
-4oey,2014-08-20,2014-01-14
-3oeh,2010-09-15,2010-08-12
-7oe2,2022-02-09,2021-05-01
-5oe4,2017-09-06,2017-07-07
-3oe6,2010-10-27,2010-08-12
-3oe9,2010-10-27,2010-08-12
-7oef,2021-10-20,2021-05-03
-1oep,2003-04-02,2003-03-28
-7oeo,2021-07-21,2021-05-03
-4oea,2014-08-20,2014-01-12
-5oeu,2018-04-25,2017-07-10
-7oeu,2022-02-09,2021-05-04
-1oe1,2003-04-17,2003-03-18
-5oep,2018-05-16,2017-07-09
-2oek,2007-03-20,2006-12-30
-6oe1,2019-06-12,2019-03-27
-1oe8,2003-07-25,2003-03-19
-5oe5,2017-09-06,2017-07-07
-2oeo,2008-03-25,2006-12-30
-8oek,2023-05-31,2023-03-10
-7oe7,2021-12-01,2021-05-01
-5oe3,2017-09-06,2017-07-07
-3oev,2011-07-20,2010-08-13
-5oe6,2017-09-06,2017-07-07
-3oeo,2010-09-22,2010-08-13
-1oeu,2003-06-12,2003-03-31
-6oer,2020-01-29,2019-03-27
-5oer,2017-10-25,2017-07-09
-6oeu,2019-04-10,2019-03-27
-3oen,2011-05-11,2010-08-12
-6oe3,2019-05-15,2019-03-27
-3oe0,2010-10-27,2010-08-12
-6oen,2020-01-29,2019-03-27
-7oe3,2021-12-01,2021-05-01
-8oeo,2023-09-06,2023-03-10
-3oet,2010-08-25,2010-08-13
-2oem,2007-03-20,2006-12-30
-5oeo,2018-04-25,2017-07-09
-8oel,2023-06-14,2023-03-10
-1oet,2003-06-12,2003-03-31
-8oed,2023-09-06,2023-03-10
-5oel,2018-05-16,2017-07-08
-7oet,2021-10-13,2021-09-21
-3oee,2010-09-15,2010-08-12
-7oe5,2021-07-28,2021-05-01
-3oe4,2011-03-16,2010-08-12
-7oel,2021-10-20,2021-05-03
-6oeq,2020-01-29,2019-03-27
-2oei,2007-07-10,2006-12-29
-4oez,2014-08-20,2014-01-14
-8oeg,2023-04-26,2023-03-10
-1oev,2003-06-12,2003-03-31
-1oe2,2003-04-17,2003-03-18
-6oey,2019-07-31,2019-03-28
-7oey,2022-02-02,2021-05-04
-8oee,2023-09-20,2023-03-10
-1oee,2003-08-15,2003-03-27
-8oei,2023-08-30,2023-03-10
-4oex,2015-04-01,2014-01-14
-1oes,2003-06-12,2003-03-31
-5oe2,2017-08-02,2017-07-07
-6oet,2020-01-22,2019-03-27
-3oe8,2010-10-27,2010-08-12
-8oe6,2024-01-17,2023-03-10
-3oem,2011-05-11,2010-08-12
-3oe3,2010-12-22,2010-08-12
-6oej,2020-07-15,2019-03-27
-3oeu,2011-07-20,2010-08-13
-4oed,2014-08-20,2014-01-13
-4oem,2015-03-25,2014-01-13
-5oef,2017-11-29,2017-07-07
-2oeg,2007-02-13,2006-12-29
-1oe7,2003-07-25,2003-03-19
-7oeb,2021-12-01,2021-05-02
-3oes,2010-08-25,2010-08-13
-6oec,2019-04-24,2019-03-27
-5oeb,2017-10-11,2017-07-07
-1oez,2003-05-29,2003-04-02
-1is7,2002-02-20,2001-11-18
-3iso,2010-09-08,2009-08-27
-5is8,2017-03-15,2016-03-15
-1ism,2002-03-13,2001-12-05
-3isq,2009-09-15,2009-08-27
-8is0,2024-03-06,2023-03-20
-2is0,2006-11-14,2006-10-16
-5ise,2017-03-15,2016-03-15
-4isk,2013-12-25,2013-01-16
-6is4,2019-10-30,2018-11-15
-4isl,2013-03-06,2013-01-16
-5isk,2017-03-29,2016-03-15
-8isk,2023-08-09,2023-03-20
-1isi,2002-03-13,2001-12-05
-4isn,2013-03-06,2013-01-16
-2isi,2006-10-31,2006-10-17
-6isr,2019-07-24,2018-11-18
-3isc,2009-09-15,2009-08-25
-2isp,2007-01-30,2006-10-18
-6is3,2019-10-30,2018-11-15
-8is5,2023-08-30,2023-03-20
-4isw,2013-12-11,2013-01-17
-4isf,2013-03-20,2013-01-16
-1isy,2002-02-20,2001-12-27
-1isz,2002-02-20,2001-12-27
-2isv,2006-12-12,2006-10-18
-3ise,2010-02-02,2009-08-25
-2isf,2006-11-28,2006-10-17
-5isp,2017-06-28,2016-03-15
-5iso,2017-03-29,2016-03-15
-5isb,2017-03-29,2016-03-15
-8isp,2024-05-15,2023-03-21
-5is9,2017-03-15,2016-03-15
-2is1,2007-01-09,2006-10-16
-3isl,2010-09-15,2009-08-26
-6isd,2018-11-28,2018-11-16
-1isf,2002-03-13,2001-12-05
-2isw,2006-12-12,2006-10-18
-1isr,2002-03-13,2001-12-21
-2is6,2007-01-09,2006-10-16
-3isz,2009-11-10,2009-08-27
-8is4,2023-08-30,2023-03-20
-6isp,2019-07-24,2018-11-18
-1isw,2002-02-20,2001-12-27
-4is1,2013-02-27,2013-01-16
-4isg,2013-03-20,2013-01-16
-5is0,2016-05-25,2016-03-15
-6isv,2019-09-11,2018-11-19
-6is7,2019-08-28,2018-11-15
-4iso,2013-03-06,2013-01-16
-2isj,2007-03-27,2006-10-17
-1isj,2002-03-13,2001-12-05
-4ise,2013-03-20,2013-01-16
-3is8,2010-02-02,2009-08-25
-2ish,2006-11-07,2006-10-17
-2isc,2007-06-05,2006-10-17
-3isd,2009-09-15,2009-08-25
-6isn,2019-12-11,2018-11-17
-2isl,2007-03-27,2006-10-17
-6iss,2019-11-20,2018-11-19
-6isc,2018-12-26,2018-11-16
-2iss,2007-01-02,2006-10-18
-5isq,2017-06-28,2016-03-15
-6is2,2019-10-30,2018-11-15
-4is9,2013-10-30,2013-01-16
-2isz,2007-02-13,2006-10-18
-5is5,2016-08-10,2016-03-15
-3is2,2009-11-03,2009-08-25
-4is3,2013-04-24,2013-01-16
-3isf,2010-02-02,2009-08-25
-1isa,1994-09-30,1994-07-12
-3ish,2009-10-06,2009-08-25
-5isd,2017-03-15,2016-03-15
-4isa,2013-10-30,2013-01-16
-4ism,2013-03-20,2013-01-16
-3is9,2010-04-07,2009-08-25
-2isn,2006-10-31,2006-10-18
-5isi,2017-03-15,2016-03-15
-1is9,2002-09-04,2001-11-26
-4isp,2013-03-20,2013-01-17
-2iso,2007-01-30,2006-10-18
-1isq,2002-10-23,2001-12-19
-3isi,2010-08-04,2009-08-25
-1is3,2002-09-18,2001-11-12
-3isj,2009-10-27,2009-08-26
-6ise,2019-11-20,2018-11-16
-8isn,2023-09-13,2023-03-21
-1is4,2002-09-18,2001-11-12
-8isr,2024-05-15,2023-03-21
-1isx,2002-02-20,2001-12-27
-5isz,2017-03-01,2016-03-15
-1ish,2002-03-13,2001-12-05
-3isb,2009-09-15,2009-08-25
-6is5,2019-11-20,2018-11-15
-4isi,2013-02-27,2013-01-16
-3is4,2010-03-23,2009-08-25
-1isv,2002-02-20,2001-12-27
-5ist,2017-06-28,2016-03-15
-5isl,2016-07-27,2016-03-15
-8isj,2023-08-09,2023-03-20
-2isa,2007-01-23,2006-10-17
-2isq,2007-02-13,2006-10-18
-1is0,2002-02-06,2001-11-02
-2ise,2006-11-07,2006-10-17
-6isg,2019-08-28,2018-11-16
-4isu,2013-03-20,2013-01-17
-6isj,2019-11-20,2018-11-16
-6isf,2019-08-28,2018-11-16
-1isb,1994-09-30,1994-07-12
-5isf,2017-03-15,2016-03-15
-5is7,2017-03-15,2016-03-15
-4isd,2013-02-13,2013-01-16
-6iso,2019-01-23,2018-11-17
-8isq,2024-05-15,2023-03-21
-1iss,2002-03-13,2001-12-21
-6isl,2019-11-20,2018-11-16
-2is9,2007-06-26,2006-10-16
-5isc,2017-03-15,2016-03-15
-1isc,1994-09-30,1994-07-12
-3isv,2009-09-22,2009-08-27
-6is1,2019-10-30,2018-11-15
-5is2,2016-04-27,2016-03-15
-5isj,2017-03-29,2016-03-15
-3is5,2009-10-20,2009-08-25
-1is2,2002-04-10,2001-11-07
-5isg,2017-03-15,2016-03-15
-1is8,2002-02-20,2001-11-18
-3is7,2010-02-02,2009-08-25
-5isa,2017-03-15,2016-03-15
-5isr,2016-03-23,2016-03-15
-3isg,2009-12-01,2009-08-25
-5isy,2016-09-14,2016-03-15
-4is0,2013-04-24,2013-01-15
-1iso,1996-12-07,1996-03-01
-6is0,2018-12-05,2018-11-15
-6is6,2019-09-25,2018-11-15
-6isi,2019-08-28,2018-11-16
-2isy,2007-02-13,2006-10-18
-4ish,2013-03-20,2013-01-16
-1isg,2002-03-13,2001-12-05
-2is7,2006-11-21,2006-10-16
-3isn,2010-03-16,2009-08-26
-2ism,2007-11-13,2006-10-18
-2is4,2007-01-09,2006-10-16
-5isx,2016-06-29,2016-03-15
-6ist,2019-11-20,2018-11-19
-4isz,2013-04-10,2013-01-17
-4is5,2013-03-06,2013-01-16
-2isg,2006-11-07,2006-10-17
-5ish,2017-03-15,2016-03-15
-2isk,2007-03-27,2006-10-17
-5is4,2017-03-29,2016-03-15
-6ish,2019-08-28,2018-11-16
-6is8,2019-10-23,2018-11-15
-3ism,2009-09-08,2009-08-26
-4isx,2013-01-30,2013-01-17
-5is6,2017-03-15,2016-03-15
-3iss,2009-11-24,2009-08-27
-5ism,2016-05-11,2016-03-15
-4isj,2013-03-20,2013-01-16
-8ism,2024-03-27,2023-03-21
-5l7n,2017-03-15,2016-06-03
-6l7w,2020-06-03,2019-11-03
-5l79,2016-09-14,2016-06-02
-5l70,2017-06-21,2016-06-01
-5l74,2017-03-15,2016-06-01
-3l7d,2010-10-20,2009-12-28
-6l7d,2020-11-04,2019-11-01
-2l7x,2011-04-20,2010-12-27
-7l7l,2021-09-01,2020-12-29
-7l7i,2021-08-25,2020-12-28
-2l7l,2011-05-18,2010-12-13
-6l7j,2020-11-04,2019-11-01
-3l75,2010-02-02,2009-12-28
-4l70,2014-02-19,2013-06-13
-7l72,2021-11-17,2020-12-25
-3l72,2010-02-02,2009-12-27
-7l7z,2021-03-03,2020-12-30
-4l73,2013-10-23,2013-06-13
-3l7l,2010-04-28,2009-12-28
-7l7p,2021-09-01,2020-12-29
-1l7l,2002-12-11,2002-03-15
-1l7g,2002-05-29,2002-03-15
-7l76,2021-08-11,2020-12-26
-3l7y,2010-12-08,2009-12-29
-4l7y,2013-07-03,2013-06-14
-4l7b,2014-02-19,2013-06-13
-4l7n,2014-02-19,2013-06-14
-4l7x,2013-07-24,2013-06-14
-4l7f,2013-08-21,2013-06-13
-4l72,2013-08-21,2013-06-13
-3l7g,2010-02-09,2009-12-28
-1l7e,2002-11-20,2002-03-14
-4l7c,2014-02-19,2013-06-13
-6l7l,2020-11-04,2019-11-01
-7l7e,2021-09-01,2020-12-28
-1l7z,2003-09-16,2002-03-18
-6l7c,2020-01-15,2019-11-01
-3l7f,2010-11-10,2009-12-28
-1l7h,2002-05-29,2002-03-15
-3l7x,2010-12-08,2009-12-29
-6l7o,2020-02-19,2019-11-02
-4l71,2014-08-06,2013-06-13
-1l7k,2002-04-24,2002-03-15
-6l72,2021-03-31,2019-10-30
-5l73,2016-10-26,2016-06-01
-6l7t,2020-01-15,2019-11-03
-7l7g,2021-03-24,2020-12-28
-6l70,2020-04-29,2019-10-30
-1l7n,2002-06-19,2002-03-16
-3l7b,2010-10-20,2009-12-28
-4l7w,2013-07-03,2013-06-14
-4l76,2013-10-23,2013-06-13
-5l7k,2016-08-10,2016-06-03
-4l7d,2014-02-19,2013-06-13
-3l76,2010-06-09,2009-12-28
-6l7h,2020-02-19,2019-11-01
-4l7u,2014-02-19,2013-06-14
-3l79,2010-10-20,2009-12-28
-5l78,2017-05-10,2016-06-02
-7l7y,2021-03-03,2020-12-30
-5l7l,2016-08-03,2016-06-03
-1l7f,2002-05-29,2002-03-15
-4l78,2013-12-11,2013-06-13
-3l70,2010-02-02,2009-12-27
-4l7r,2014-02-19,2013-06-14
-1l7m,2002-04-03,2002-03-15
-6l7p,2020-02-19,2019-11-02
-6l74,2020-03-11,2019-10-31
-4l7g,2013-09-18,2013-06-13
-4l74,2013-10-23,2013-06-13
-3l7m,2010-04-28,2009-12-28
-7l7c,2021-08-11,2020-12-28
-7l7o,2021-09-01,2020-12-29
-6l7x,2020-06-03,2019-11-03
-4l7p,2014-02-19,2013-06-14
-3l7k,2010-04-28,2009-12-28
-7l78,2021-11-24,2020-12-27
-7l7n,2021-09-01,2020-12-29
-5l7j,2016-08-03,2016-06-03
-3l77,2011-01-19,2009-12-28
-4l7v,2014-06-18,2013-06-14
-5l75,2017-08-16,2016-06-01
-5l7u,2017-03-22,2016-06-03
-7l74,2022-02-09,2020-12-25
-3l73,2010-02-02,2009-12-27
-5l7g,2016-12-07,2016-06-03
-1l7o,2002-06-19,2002-03-16
-1l7p,2002-06-19,2002-03-16
-6l7y,2020-06-03,2019-11-03
-7l73,2021-06-30,2020-12-25
-5l7v,2017-03-22,2016-06-03
-7l7d,2021-09-01,2020-12-28
-7l79,2021-10-27,2020-12-27
-6l7u,2020-01-15,2019-11-03
-5l7h,2016-12-07,2016-06-03
-5l7f,2016-09-14,2016-06-03
-4l7i,2013-07-03,2013-06-13
-4l7s,2014-01-22,2013-06-14
-4l75,2013-10-23,2013-06-13
-5l7d,2016-07-20,2016-06-03
-5l7y,2016-12-21,2016-06-04
-7l7r,2021-12-01,2020-12-30
-4l7h,2013-09-18,2013-06-13
-7l7b,2022-02-02,2020-12-28
-7l7w,2021-06-16,2020-12-30
-7l7x,2021-03-03,2020-12-30
-5l7x,2016-07-13,2016-06-04
-6l7v,2020-06-03,2019-11-03
-3l7r,2011-01-12,2009-12-29
-3l74,2010-02-02,2009-12-28
-4l77,2013-07-24,2013-06-13
-5l72,2016-07-27,2016-06-01
-4l79,2014-01-29,2013-06-13
-3l7c,2010-10-20,2009-12-28
-4l7l,2014-02-19,2013-06-14
-4l7t,2014-01-01,2013-06-14
-5l7e,2016-12-07,2016-06-03
-7l7j,2021-08-25,2020-12-28
-7l7u,2021-08-04,2020-12-30
-5l7t,2016-12-21,2016-06-03
-4l7j,2013-09-18,2013-06-13
-5l7i,2016-07-20,2016-06-03
-3l7a,2010-10-20,2009-12-28
-5l7w,2016-12-21,2016-06-04
-2l74,2011-02-09,2010-12-02
-7l7t,2021-08-04,2020-12-30
-4l7o,2014-02-19,2013-06-14
-3l71,2010-02-02,2009-12-27
-5l77,2017-05-31,2016-06-02
-3l7t,2010-12-29,2009-12-29
-2l75,2011-01-19,2010-12-02
-5l7p,2017-09-13,2016-06-03
-6l7s,2020-01-15,2019-11-03
-1l7x,2002-12-04,2002-03-18
-6l71,2021-03-31,2019-10-30
-2l7p,2011-05-11,2010-12-16
-5df8,2016-01-13,2015-08-26
-7dfr,1990-07-15,1988-10-21
-7dfq,2021-03-17,2020-11-09
-3dfi,2008-07-22,2008-06-12
-6df1,2018-11-28,2018-05-13
-6df4,2018-10-31,2018-05-14
-7dfl,2021-03-31,2020-11-09
-1dfq,2000-03-24,1999-11-20
-7dfs,2021-03-17,2020-11-09
-3dfk,2008-07-22,2008-06-12
-2df8,2006-08-27,2006-02-27
-8df2,2022-08-31,2022-06-21
-7dfu,2021-05-19,2020-11-09
-5dfx,2016-09-14,2015-08-27
-4dfd,2012-02-01,2012-01-23
-6df2,2018-11-28,2018-05-13
-5df5,2016-09-14,2015-08-26
-5dfd,2015-11-11,2015-08-26
-7df8,2021-08-04,2020-11-06
-3dfv,2008-07-29,2008-06-12
-4df4,2012-05-16,2012-01-23
-7dfw,2021-08-11,2020-11-10
-1df7,2000-03-09,1999-11-17
-4df3,2012-08-08,2012-01-22
-8df7,2022-08-31,2022-06-21
-6df6,2019-02-20,2018-05-14
-7dfg,2021-11-17,2020-11-08
-5df1,2015-10-28,2015-08-26
-6df5,2019-05-22,2018-05-14
-5dfe,2016-10-12,2015-08-26
-8dfv,2022-11-16,2022-06-22
-8df8,2022-08-31,2022-06-21
-7dfk,2021-11-17,2020-11-08
-1dfo,1999-12-10,1999-11-20
-3df0,2008-11-11,2008-06-11
-4dfs,2012-03-14,2012-01-24
-3dfy,2008-11-25,2008-06-12
-1dff,1998-09-02,1997-08-19
-7df2,2020-12-09,2020-11-06
-5dfb,2015-11-11,2015-08-26
-1dfe,1999-12-01,1999-11-19
-4df1,2013-01-23,2012-01-22
-3df6,2009-06-16,2008-06-11
-1df1,1999-12-08,1999-11-16
-8dft,2023-03-22,2022-06-22
-4dfn,2012-04-25,2012-01-24
-6dfu,2018-05-23,2018-05-15
-2dfy,2006-10-31,2006-03-06
-3dff,2008-07-22,2008-06-11
-4df0,2013-01-23,2012-01-22
-5dfc,2015-11-11,2015-08-26
-3dfc,2009-05-26,2008-06-11
-8dfb,2022-08-31,2022-06-21
-8dfr,1989-10-15,1989-05-30
-2df3,2006-06-20,2006-02-23
-8dfy,2023-07-05,2022-06-22
-1df8,2000-09-20,1999-11-18
-2df7,2006-06-27,2006-02-27
-5df7,2016-01-13,2015-08-26
-6dfs,2019-04-17,2018-05-15
-1dfu,1999-12-02,1999-11-21
-8df1,2023-03-01,2022-06-21
-4dfl,2012-04-25,2012-01-24
-8df5,2022-08-03,2022-06-21
-6dfo,2019-05-15,2018-05-15
-2dfi,2007-03-06,2006-03-01
-6dff,2018-08-08,2018-05-14
-8dfq,2023-03-29,2022-06-22
-6df9,2019-05-22,2018-05-14
-4dfm,2012-05-16,2012-01-24
-1dfx,1998-10-14,1997-09-03
-5dfy,2016-09-14,2015-08-27
-7dfz,2021-08-11,2020-11-10
-6dfx,2019-04-17,2018-05-15
-4dfb,2012-02-08,2012-01-23
-1dfm,2000-02-21,1999-12-06
-3dfm,2008-07-22,2008-06-12
-2dft,2007-01-16,2006-03-03
-8dfl,2022-07-13,2022-06-22
-2dfv,2007-01-16,2006-03-03
-2df4,2006-07-18,2006-02-23
-7df4,2020-12-16,2020-11-06
-7dfh,2021-11-17,2020-11-08
-6df3,2018-08-15,2018-05-14
-4dfg,2012-03-21,2012-01-23
-4dfr,1982-10-21,1982-06-25
-1dfs,1999-12-01,1999-11-20
-4dfx,2012-06-06,2012-01-24
-6dfg,2019-11-06,2018-05-14
-2dfn,2006-09-03,2006-03-03
-6dfq,2019-04-17,2018-05-15
-6dfh,2019-11-06,2018-05-14
-6df8,2019-05-22,2018-05-14
-3dfh,2008-07-01,2008-06-12
-4dfk,2012-05-16,2012-01-24
-7dfp,2020-12-30,2020-11-09
-5dfa,2015-12-09,2015-08-26
-7df6,2021-06-23,2020-11-06
-8df9,2022-08-31,2022-06-21
-1dfk,2000-10-25,1999-11-19
-1dfh,1998-01-28,1997-01-16
-1dfl,2000-10-25,1999-11-19
-2dfd,2006-03-28,2006-02-28
-6dfr,1990-07-15,1988-10-21
-3dfx,2008-07-29,2008-06-12
-6dfe,2018-09-05,2018-05-14
-5df0,2016-09-07,2015-08-26
-1dfg,1998-01-28,1997-01-16
-3dfl,2008-10-14,2008-06-12
-4dfj,2012-05-16,2012-01-23
-6dfm,2019-05-15,2018-05-15
-8dfp,2023-03-29,2022-06-22
-4df8,2012-05-16,2012-01-23
-1dft,1999-12-01,1999-11-20
-6dfc,2019-05-22,2018-05-14
-2dfp,1999-06-28,1998-12-07
-2dfj,2006-12-05,2006-03-02
-4dfu,2012-02-08,2012-01-24
-1dfv,2000-03-06,1999-11-22
-3df9,2009-03-17,2008-06-11
-4df6,2012-07-18,2012-01-23
-4dfp,2012-05-16,2012-01-24
-6dfn,2019-02-20,2018-05-15
-6dfa,2019-05-22,2018-05-14
-7df5,2021-06-23,2020-11-06
-5dfm,2015-10-28,2015-08-27
-6dft,2018-08-08,2018-05-15
-8dfw,2023-07-05,2022-06-22
-8dfm,2023-03-29,2022-06-22
-7dfj,2021-11-17,2020-11-08
-6dfb,2019-05-22,2018-05-14
-7dfo,2020-12-30,2020-11-09
-1dfp,1998-02-25,1997-02-18
-3dfr,1982-10-21,1982-06-25
-8dfu,2023-03-22,2022-06-22
-8dfz,2023-07-05,2022-06-23
-4dff,2012-03-14,2012-01-23
-8dfx,2023-07-05,2022-06-22
-5df9,2016-01-13,2015-08-26
-5dfh,2015-10-14,2015-08-26
-4df9,2012-02-15,2012-01-23
-4df7,2012-02-01,2012-01-23
-1dfi,1998-01-28,1997-01-16
-4dfa,2012-02-01,2012-01-23
-4df2,2012-07-11,2012-01-22
-5dfp,2016-01-27,2015-08-27
-6df7,2018-11-14,2018-05-14
-5dff,2015-10-14,2015-08-26
-5dfs,2016-03-02,2015-08-27
-7dfn,2020-12-30,2020-11-09
-7df3,2020-12-16,2020-11-06
-7v55,2022-08-17,2021-08-16
-8v5g,2023-12-13,2023-11-30
-2v5z,2007-10-16,2007-07-12
-5v58,2018-01-10,2017-03-13
-4v57,2014-07-09,2007-07-21
-5v5x,2017-11-01,2017-03-15
-5v57,2017-05-24,2017-03-13
-1v51,2004-04-20,2003-11-20
-4v5d,2014-07-09,2009-03-24
-3v5u,2012-02-22,2011-12-16
-7v5u,2022-08-24,2021-08-18
-1v5i,2005-03-08,2003-11-24
-7v57,2022-08-24,2021-08-16
-2v5m,2007-09-11,2007-07-06
-5v5n,2017-08-30,2017-03-14
-1v59,2005-02-15,2003-11-21
-6v5n,2020-04-22,2019-12-04
-7v5r,2022-06-29,2021-08-17
-2v54,2008-10-21,2008-10-01
-5v5d,2017-04-12,2017-03-14
-7v56,2022-08-24,2021-08-16
-3v5g,2012-07-25,2011-12-16
-5v5z,2017-03-29,2017-03-15
-7v5c,2022-10-19,2021-08-17
-8v5o,2023-12-20,2023-11-30
-3v5f,2012-12-19,2011-12-16
-4v5r,2014-07-09,2010-12-07
-6v51,2020-10-07,2019-12-02
-6v54,2019-12-25,2019-12-03
-2v5c,2009-01-27,2008-10-02
-1v5e,2005-06-28,2003-11-22
-3v5l,2012-05-02,2011-12-16
-2v5n,2007-12-11,2007-07-06
-6v5k,2020-12-09,2019-12-04
-4v5h,2014-07-09,2009-10-26
-2v57,2009-10-20,2008-10-02
-5v54,2018-02-07,2017-03-13
-3v5w,2012-09-26,2011-12-17
-2v5x,2007-09-04,2007-07-10
-6v5m,2019-12-25,2019-12-04
-4v53,2014-07-09,2007-06-16
-3v5c,2012-12-19,2011-12-16
-4v5n,2014-07-09,2010-10-21
-4v5i,2014-07-09,2010-02-05
-3v5m,2012-08-08,2011-12-16
-5v59,2018-01-10,2017-03-13
-3v5j,2012-05-02,2011-12-16
-7v54,2022-08-24,2021-08-16
-4v55,2014-07-09,2007-06-17
-4v5p,2014-07-09,2010-12-07
-3v51,2012-03-14,2011-12-15
-6v5a,2020-07-01,2019-12-03
-4v50,2014-07-09,2006-08-16
-5v5g,2017-05-10,2017-03-14
-6v52,2020-04-08,2019-12-03
-2v55,2008-11-04,2008-10-01
-8v5y,2024-05-08,2023-12-01
-3v5a,2011-12-28,2011-12-16
-2v5a,2009-01-13,2008-10-02
-6v56,2021-02-10,2019-12-03
-5v5q,2018-03-21,2017-03-14
-1v54,2003-12-23,2003-11-21
-5v5h,2017-05-10,2017-03-14
-4v5b,2014-07-09,2007-11-22
-5v5r,2018-03-21,2017-03-15
-1v55,2003-12-23,2003-11-21
-2v5o,2007-12-11,2007-07-06
-2v5p,2007-12-11,2007-07-06
-5v5e,2017-04-12,2017-03-14
-2v59,2009-01-13,2008-10-02
-2v5s,2007-09-11,2007-07-09
-1v5n,2004-05-25,2003-11-25
-2v5f,2009-11-17,2008-10-06
-5v5c,2018-02-07,2017-03-14
-6v5p,2020-04-22,2019-12-04
-2v5y,2007-09-11,2007-07-11
-7v5q,2022-06-29,2021-08-17
-7v52,2022-08-24,2021-08-16
-4v5m,2014-07-09,2010-10-01
-3v52,2012-07-25,2011-12-15
-3v5q,2012-02-08,2011-12-16
-7v51,2023-02-22,2021-08-16
-7v5p,2022-06-29,2021-08-17
-5v53,2017-04-26,2017-03-13
-3v5h,2012-12-05,2011-12-16
-4v5j,2014-07-09,2010-03-24
-2v5t,2008-07-29,2007-07-10
-2v5k,2007-10-02,2007-07-06
-3v5d,2012-12-05,2011-12-16
-6v55,2020-01-15,2019-12-03
-3v5t,2012-03-14,2011-12-16
-2v52,2008-11-25,2008-10-01
-1v5g,2005-06-28,2003-11-22
-5v56,2017-05-24,2017-03-13
-4v54,2014-07-09,2007-06-16
-1v5h,2004-06-08,2003-11-23
-1v5z,2005-03-08,2003-11-26
-4v52,2014-07-09,2007-06-15
-6v5v,2020-01-01,2019-12-04
-4v5s,2014-07-09,2010-12-07
-2v51,2008-11-25,2008-10-01
-2v5i,2008-02-19,2007-07-05
-3v5k,2012-12-19,2011-12-16
-5v5j,2018-03-21,2017-03-14
-5v5o,2018-03-14,2017-03-14
-4v5q,2014-07-09,2010-12-07
-6v53,2020-12-09,2019-12-03
-6v5f,2021-02-03,2019-12-04
-4v59,2014-07-09,2007-03-09
-4v5f,2014-07-09,2009-09-01
-3v57,2012-10-03,2011-12-16
-3v50,2012-08-08,2011-12-15
-2v5h,2007-10-16,2007-07-04
-1v5d,2004-12-07,2003-11-22
-4v51,2014-07-09,2006-07-31
-4v5o,2014-07-09,2010-11-26
-4v56,2014-07-09,2007-07-21
-6v59,2020-07-08,2019-12-03
-3v5p,2012-03-14,2011-12-16
-3v58,2012-10-03,2011-12-16
-7v5i,2021-12-29,2021-08-17
-2v5d,2009-01-27,2008-10-02
-6v5b,2020-04-08,2019-12-04
-5v5y,2017-08-23,2017-03-15
-8v5m,2023-12-20,2023-11-30
-2v5r,2007-09-11,2007-07-09
-4v58,2014-07-09,2007-03-09
-8v5n,2023-12-20,2023-11-30
-4v5c,2014-07-09,2009-03-24
-2v53,2008-11-25,2008-10-01
-4v5a,2014-07-09,2007-06-28
-2v58,2009-01-13,2008-10-02
-1v5f,2005-06-28,2003-11-22
-2v5u,2007-10-16,2007-07-10
-2v5v,2007-10-16,2007-07-10
-7v58,2021-12-29,2021-08-16
-3v5s,2012-02-22,2011-12-16
-1v5y,2005-03-08,2003-11-26
-4v5l,2014-07-09,2010-09-02
-4v5z,2014-07-09,2008-03-27
-5v52,2017-05-24,2017-03-13
-2v5w,2007-09-04,2007-07-10
-8v5k,2024-05-22,2023-11-30
-7v50,2023-02-22,2021-08-16
-4v5g,2014-07-09,2009-09-01
-5v5p,2018-03-14,2017-03-14
-1v5r,2005-01-18,2003-11-25
-4v5e,2014-07-09,2009-04-30
-6v5l,2019-12-18,2019-12-04
-4v5k,2014-07-09,2010-05-29
-5ksr,2017-07-19,2016-07-09
-5kse,2017-06-28,2016-07-08
-6ksd,2020-08-26,2019-08-23
-6kse,2020-07-01,2019-08-23
-2ksz,2010-03-09,2010-01-14
-5ksx,2017-03-15,2016-07-10
-5ksn,2017-07-12,2016-07-08
-4ksg,2014-01-15,2013-05-17
-5ksz,2016-09-21,2016-07-10
-7kse,2021-08-11,2020-11-21
-7ksl,2020-12-09,2020-11-23
-3ksz,2010-08-18,2009-11-24
-6ksb,2020-07-01,2019-08-23
-5ksp,2016-09-21,2016-07-08
-5ksj,2017-07-26,2016-07-08
-7ksg,2021-01-20,2020-11-22
-6ksi,2020-04-08,2019-08-24
-3ks0,2010-05-26,2009-11-20
-1ksc,2003-01-21,2002-01-11
-1ksv,2002-04-24,2002-01-14
-7kso,2021-02-03,2020-11-23
-7ksr,2021-02-03,2020-11-24
-4ks7,2013-09-11,2013-05-17
-2ksq,2010-07-07,2010-01-12
-6ksu,2020-06-24,2019-08-26
-7ksv,2021-12-01,2020-11-24
-7ksy,2021-12-01,2020-11-24
-5ks1,2017-07-12,2016-07-07
-7ksx,2021-12-01,2020-11-24
-3ksg,2010-05-26,2009-11-23
-1ks4,2003-01-21,2002-01-10
-3ksb,2010-05-05,2009-11-21
-4ksp,2013-07-24,2013-05-17
-7ksq,2022-03-30,2020-11-23
-1ksz,1997-10-08,1997-01-14
-7ksm,2020-12-02,2020-11-23
-7ksw,2021-12-01,2020-11-24
-6ks1,2020-08-19,2019-08-22
-5ksy,2016-09-21,2016-07-10
-4ksy,2013-06-12,2013-05-18
-4ks2,2013-10-30,2013-05-17
-5ksc,2016-11-09,2016-07-08
-3ksm,2009-12-15,2009-11-23
-1ksf,2002-09-27,2002-01-12
-4ks3,2013-10-30,2013-05-17
-3kso,2010-09-22,2009-11-23
-5ksi,2017-07-26,2016-07-08
-5ksq,2017-07-19,2016-07-09
-7ksa,2021-06-02,2020-11-21
-7ksi,2021-03-03,2020-11-23
-6kst,2020-08-26,2019-08-26
-1ksi,1997-12-24,1996-07-20
-6ksr,2020-09-02,2019-08-25
-1ksm,2002-01-23,2002-01-14
-6ksv,2020-06-24,2019-08-26
-5ksf,2017-04-26,2016-07-08
-2ksc,2010-02-09,2010-01-02
-7kst,2021-12-01,2020-11-24
-6ksc,2020-08-26,2019-08-23
-1kss,2002-08-14,2002-01-14
-6ksh,2020-08-26,2019-08-23
-3ks6,2009-12-08,2009-11-20
-6ks6,2019-09-18,2019-08-23
-3ks3,2010-01-26,2009-11-20
-1ksp,1998-02-25,1997-08-19
-6ksa,2020-07-01,2019-08-23
-7ksz,2022-01-19,2020-11-24
-5kso,2016-09-21,2016-07-08
-7ks8,2021-06-02,2020-11-21
-5ksk,2017-04-26,2016-07-08
-7kss,2022-05-11,2020-11-24
-5ksd,2016-08-10,2016-07-08
-4ks6,2014-06-25,2013-05-17
-7ksf,2021-08-11,2020-11-21
-1ksn,2002-06-19,2002-01-14
-4ksh,2014-01-15,2013-05-17
-3ks5,2009-12-08,2009-11-20
-3ksl,2009-12-22,2009-11-23
-3kst,2009-12-08,2009-11-23
-7ksu,2022-01-19,2020-11-24
-5kss,2017-07-19,2016-07-09
-4ks0,2014-11-19,2013-05-17
-3ksa,2010-05-05,2009-11-21
-2ksp,2010-01-26,2010-01-11
-4ksi,2013-06-12,2013-05-17
-3ksw,2009-12-01,2009-11-23
-6ksg,2020-08-26,2019-08-23
-1ksj,2002-05-08,2002-01-13
-6ks9,2020-07-01,2019-08-23
-4ksa,2013-06-19,2013-05-17
-7ksj,2021-03-03,2020-11-23
-5ksw,2016-08-03,2016-07-10
-5ksb,2016-09-21,2016-07-08
-5ksg,2017-07-12,2016-07-08
-6ks0,2020-08-19,2019-08-22
-3ksq,2010-01-26,2009-11-23
-4ksz,2013-07-10,2013-05-19
-2ksu,2010-09-15,2010-01-13
-1ksw,2002-02-27,2002-01-14
-5kst,2017-07-19,2016-07-09
-6ksl,2020-04-08,2019-08-24
-3ks9,2009-12-08,2009-11-20
-7ksk,2021-03-03,2020-11-23
-4ks9,2013-06-19,2013-05-17
-7ks4,2021-05-05,2020-11-20
-4ksf,2013-06-19,2013-05-17
-5ks7,2016-07-20,2016-07-07
-7ks9,2021-02-10,2020-11-21
-1ksd,2003-01-21,2002-01-12
-1ksh,2002-05-08,2002-01-13
-4ks1,2013-10-30,2013-05-17
-6ksn,2019-11-20,2019-08-24
-1ksg,2002-05-08,2002-01-13
-5ks9,2016-09-21,2016-07-08
-5ks8,2016-10-19,2016-07-07
-3ksv,2010-01-12,2009-11-23
-1ksk,2002-04-24,2002-01-13
-2ksy,2010-06-02,2010-01-14
-4ks4,2013-10-30,2013-05-17
-3ksd,2010-08-18,2009-11-22
-4ks8,2013-09-11,2013-05-17
-6ksy,2020-08-05,2019-08-26
-3kss,2010-09-22,2009-11-23
-4ksq,2013-07-24,2013-05-17
-1ks7,2003-01-11,2002-01-11
-1ksu,2002-08-14,2002-01-14
-5ksa,2016-09-21,2016-07-08
-4ks5,2013-10-30,2013-05-17
-1ksl,2002-04-24,2002-01-13
-6ksm,2020-04-08,2019-08-24
-4jyw,2014-04-02,2013-04-01
-3jy9,2009-12-01,2009-09-21
-3jyy,2009-11-03,2009-09-22
-4jy6,2013-05-08,2013-03-29
-6jyf,2020-03-04,2019-04-26
-7jy7,2020-11-04,2020-08-29
-4jye,2013-05-01,2013-03-29
-7jyb,2021-05-26,2020-08-30
-5jyb,2016-06-15,2016-05-13
-5jya,2016-12-21,2016-05-13
-8jyr,2024-03-13,2023-07-03
-4jyo,2013-05-08,2013-03-31
-7jy8,2020-11-04,2020-08-29
-6jye,2020-03-04,2019-04-26
-6jyt,2019-09-18,2019-04-28
-5jyi,2016-07-06,2016-05-14
-5jy4,2016-07-20,2016-05-13
-8jy8,2024-05-29,2023-07-03
-6jy4,2019-09-18,2019-04-26
-8jyp,2024-01-03,2023-07-03
-2jyw,2008-02-26,2007-12-20
-6jyq,2020-05-13,2019-04-27
-8jye,2023-09-13,2023-07-03
-7jy9,2020-11-04,2020-08-29
-7jyp,2021-10-06,2020-08-31
-4jy2,2014-04-02,2013-03-28
-5jy1,2016-05-25,2016-05-13
-6jyc,2020-03-04,2019-04-26
-3jyf,2009-09-29,2009-09-21
-7jy5,2021-01-20,2020-08-28
-1jys,2002-10-01,2001-09-13
-6jy9,2020-03-04,2019-04-26
-3jyp,2010-10-27,2009-09-22
-4jym,2013-05-08,2013-03-30
-5jyo,2016-08-03,2016-05-15
-7jyw,2021-04-14,2020-09-01
-7jyr,2021-01-20,2020-08-31
-8jyq,2024-03-13,2023-07-03
-8jyo,2024-01-03,2023-07-03
-4jyq,2014-04-23,2013-03-31
-7jyd,2022-03-02,2020-08-30
-8jyk,2024-01-03,2023-07-03
-8jy9,2023-09-13,2023-07-03
-3jya,2009-11-10,2009-09-21
-7jyt,2021-01-20,2020-08-31
-4jyc,2013-07-24,2013-03-29
-5jyy,2016-06-29,2016-05-15
-4jyf,2013-05-01,2013-03-29
-8jyf,2023-09-13,2023-07-03
-4jyv,2013-07-24,2013-04-01
-5jyx,2016-11-09,2016-05-15
-4jyg,2014-03-19,2013-03-29
-1jyx,2001-12-07,2001-09-13
-4jy3,2014-04-02,2013-03-29
-1jyq,2002-03-13,2001-09-13
-4jy1,2014-04-23,2013-03-28
-2jyd,2008-01-15,2007-12-12
-7jy4,2021-01-20,2020-08-28
-7jyo,2021-07-14,2020-08-31
-4jy9,2013-05-01,2013-03-29
-5jy0,2017-06-14,2016-05-13
-4jy4,2013-05-15,2013-03-29
-5jye,2016-12-21,2016-05-13
-8jya,2023-09-13,2023-07-03
-7jy1,2021-01-13,2020-08-28
-5jy7,2017-05-24,2016-05-13
-3jyc,2010-01-12,2009-09-21
-4jyy,2014-04-02,2013-04-01
-3jyg,2009-10-13,2009-09-21
-8jy6,2024-05-29,2023-07-03
-7jyc,2020-09-09,2020-08-30
-6jy8,2020-03-04,2019-04-26
-4jyh,2014-03-19,2013-03-29
-8jyt,2023-10-11,2023-07-03
-6jy3,2019-09-18,2019-04-26
-4jyk,2013-08-14,2013-03-29
-5jyd,2016-06-08,2016-05-13
-7jy6,2020-11-04,2020-08-29
-1jyi,2002-09-12,2001-09-12
-1jy8,2002-01-30,2001-09-11
-1jyv,2001-12-07,2001-09-13
-7jym,2020-11-25,2020-08-31
-6jyn,2019-05-22,2019-04-26
-7jyq,2021-07-14,2020-08-31
-1jym,2002-03-13,2001-09-12
-1jy7,2002-03-11,2001-09-11
-1jyb,2002-09-11,2001-09-11
-3jyr,2010-02-16,2009-09-22
-6jyv,2019-05-22,2019-04-28
-1jyc,2002-09-12,2001-09-12
-6jyd,2020-03-04,2019-04-26
-3jyo,2010-10-27,2009-09-22
-5jy3,2016-11-02,2016-05-13
-4jy0,2014-04-23,2013-03-28
-6jyp,2020-05-13,2019-04-27
-7jyv,2021-04-14,2020-09-01
-4jyb,2013-07-24,2013-03-29
-5jyg,2016-07-27,2016-05-13
-6jyw,2020-04-29,2019-04-29
-1jyr,2002-03-13,2001-09-13
-8jyg,2023-09-20,2023-07-03
-4jyd,2013-05-01,2013-03-29
-4jyu,2013-07-24,2013-04-01
-8jyj,2023-08-16,2023-07-03
-4jyz,2013-05-29,2013-04-01
-5jy9,2016-07-20,2016-05-13
-6jyb,2020-03-04,2019-04-26
-5jyj,2017-05-24,2016-05-14
-8jyh,2023-08-16,2023-07-03
-5jyc,2017-01-11,2016-05-13
-6jya,2020-03-04,2019-04-26
-7jyy,2020-09-16,2020-09-01
-5jys,2016-07-20,2016-05-15
-7jy0,2021-01-13,2020-08-28
-5jy6,2016-12-21,2016-05-13
-7jyu,2021-04-14,2020-09-01
-3jys,2009-10-06,2009-09-22
-3jy0,2009-11-10,2009-09-21
-3jyn,2010-01-12,2009-09-22
-2jyi,2008-12-09,2007-12-13
-6jyl,2019-05-29,2019-04-26
-3jyq,2010-10-27,2009-09-22
-8jyx,2024-05-08,2023-07-04
-5jyp,2016-08-03,2016-05-15
-6jy6,2020-03-04,2019-04-26
-8jyi,2023-08-16,2023-07-03
-5jy8,2016-07-20,2016-05-13
-1jyn,2001-12-07,2001-09-13
-8jyc,2023-09-13,2023-07-03
-1jyl,2002-02-22,2001-09-12
-8jym,2024-01-03,2023-07-03
-4jya,2013-06-26,2013-03-29
-6jyu,2020-04-29,2019-04-28
-6jyg,2020-04-01,2019-04-26
-6jy7,2020-03-04,2019-04-26
-3jyh,2009-10-13,2009-09-21
-4jyi,2014-03-19,2013-03-29
-1jyw,2001-12-07,2001-09-13
-7jye,2022-03-02,2020-08-30
-3jyj,2010-04-07,2009-09-21
-8jyn,2024-01-03,2023-07-03
-7jys,2021-01-20,2020-08-31
-3jyt,2009-10-06,2009-09-22
-5jym,2016-12-28,2016-05-14
-7jy3,2021-01-13,2020-08-28
-6jys,2019-05-22,2019-04-27
-4jyt,2014-03-19,2013-04-01
-3o95,2011-01-26,2010-08-03
-5o91,2017-07-26,2017-06-15
-3o92,2011-01-12,2010-08-03
-3o9c,2011-08-10,2010-08-04
-2o9j,2007-02-06,2006-12-13
-5o9d,2017-10-11,2017-06-19
-3o98,2011-03-02,2010-08-04
-4o9e,2014-04-09,2014-01-02
-7o9u,2021-05-05,2021-04-17
-3o93,2011-01-12,2010-08-03
-5o97,2018-06-27,2017-06-15
-4o9m,2014-04-30,2014-01-02
-4o91,2014-07-30,2013-12-31
-4o98,2014-12-03,2014-01-02
-4o9u,2015-01-28,2014-01-02
-3o9e,2011-08-10,2010-08-04
-6o9t,2020-05-27,2019-03-15
-6o9y,2019-12-25,2019-03-15
-7o9i,2022-02-02,2021-04-16
-1o99,2002-12-23,2002-12-11
-5o9h,2018-01-10,2017-06-19
-3o91,2011-01-12,2010-08-03
-5o9g,2017-10-11,2017-06-19
-6o9g,2019-03-20,2019-03-13
-1o90,2003-08-07,2002-12-10
-3o9d,2011-08-10,2010-08-04
-7o9x,2022-07-27,2021-04-17
-4o9s,2014-07-02,2014-01-02
-7o9d,2021-12-01,2021-04-15
-5o9u,2018-06-27,2017-06-20
-4o93,2014-12-31,2013-12-31
-6o9v,2020-05-27,2019-03-15
-6o9e,2019-10-23,2019-03-13
-1o9j,2003-04-17,2002-12-15
-4o9w,2014-08-13,2014-01-03
-1o9r,2003-05-29,2002-12-18
-1o9v,2003-05-29,2002-12-20
-4o9b,2014-01-15,2014-01-02
-1o9i,2003-12-18,2002-12-13
-2o9a,2007-04-10,2006-12-13
-3o9w,2010-09-29,2010-08-04
-4o9x,2014-02-26,2014-01-03
-5o9y,2018-05-02,2017-06-20
-4o9c,2014-12-17,2014-01-02
-1o9w,2003-05-29,2002-12-20
-2o9o,2007-01-02,2006-12-14
-6o9n,2020-03-18,2019-03-14
-6o9s,2020-06-10,2019-03-14
-5o9r,2018-05-02,2017-06-20
-1o9o,2003-12-18,2002-12-18
-7o9j,2021-07-14,2021-04-16
-1o9f,2003-03-06,2002-12-12
-1o95,2003-02-06,2002-12-11
-6o95,2019-05-22,2019-03-13
-7o9r,2022-10-26,2021-04-16
-5o94,2018-04-04,2017-06-15
-2o98,2007-04-03,2006-12-13
-3o9h,2011-08-10,2010-08-04
-2o9t,2007-10-02,2006-12-14
-7o9g,2022-02-02,2021-04-16
-5o90,2018-01-31,2017-06-15
-7o93,2021-12-01,2021-04-15
-6o91,2019-04-10,2019-03-12
-6o9p,2019-04-03,2019-03-14
-6o9m,2019-05-29,2019-03-14
-1o9e,2003-03-06,2002-12-12
-5o9s,2018-06-27,2017-06-20
-3o9i,2011-08-10,2010-08-04
-7o9s,2021-06-23,2021-04-16
-6o9h,2020-01-22,2019-03-13
-4o9g,2014-04-09,2014-01-02
-3o9l,2011-03-02,2010-08-04
-7o9m,2021-06-30,2021-04-16
-2o90,2007-12-25,2006-12-12
-4o95,2015-04-01,2014-01-01
-5o98,2018-02-21,2017-06-16
-5o9p,2018-05-02,2017-06-19
-6o94,2019-05-22,2019-03-13
-6o9o,2020-03-18,2019-03-14
-4o97,2014-05-28,2014-01-02
-5o9v,2018-06-27,2017-06-20
-3o9b,2011-08-10,2010-08-04
-6o9c,2019-11-13,2019-03-13
-5o9o,2018-05-02,2017-06-19
-3o9f,2011-08-10,2010-08-04
-6o9d,2019-05-22,2019-03-13
-1o9l,2002-12-23,2002-12-17
-6o9k,2019-05-29,2019-03-14
-1o9d,2003-03-06,2002-12-12
-3o96,2010-10-13,2010-08-03
-6o9l,2019-05-29,2019-03-14
-1o9t,2003-08-07,2002-12-18
-3o9x,2010-11-10,2010-08-04
-1o92,2003-08-07,2002-12-10
-7o90,2021-12-01,2021-04-15
-2o9c,2007-03-06,2006-12-13
-7o9w,2022-01-12,2021-04-17
-1o97,2003-02-06,2002-12-11
-6o9f,2024-05-01,2019-03-13
-3o99,2011-08-10,2010-08-04
-4o9r,2014-03-05,2014-01-02
-2o9k,2006-12-19,2006-12-13
-6o98,2019-03-20,2019-03-13
-6o90,2020-09-23,2019-03-12
-5o9b,2019-02-06,2017-06-16
-6o9a,2019-04-03,2019-03-13
-3o97,2010-09-08,2010-08-04
-7o9z,2022-07-27,2021-04-18
-7o9c,2021-12-01,2021-04-15
-5o9t,2018-06-27,2017-06-20
-7o91,2021-12-01,2021-04-15
-5o9w,2018-02-14,2017-06-20
-2o9s,2007-10-30,2006-12-14
-1o9s,2003-02-06,2002-12-18
-7o99,2021-12-01,2021-04-15
-7o9y,2022-05-04,2021-04-18
-5o9a,2018-01-03,2017-06-16
-5o9x,2018-07-11,2017-06-20
-7o9f,2022-02-02,2021-04-16
-1o98,2003-05-01,2002-12-11
-3o9z,2010-08-18,2010-08-04
-5o9f,2017-10-11,2017-06-19
-2o99,2007-04-10,2006-12-13
-6o9u,2020-05-27,2019-03-15
-6o97,2019-04-17,2019-03-13
-7o9k,2021-06-30,2021-04-16
-5o96,2017-11-08,2017-06-15
-1o94,2003-02-06,2002-12-11
-3o9a,2011-08-10,2010-08-04
-7o9p,2021-12-15,2021-04-16
-3o90,2011-01-12,2010-08-03
-5o9q,2018-05-02,2017-06-20
-7o9h,2022-02-02,2021-04-16
-6o96,2019-04-24,2019-03-13
-3o9j,2010-12-15,2010-08-04
-1o93,2003-08-07,2002-12-10
-4o9v,2014-05-28,2014-01-03
-1o9x,2003-03-13,2002-12-20
-3o9p,2011-07-06,2010-08-04
-2o9i,2007-01-30,2006-12-13
-6o93,2019-03-27,2019-03-12
-4o9k,2014-01-22,2014-01-02
-3o9v,2011-02-09,2010-08-04
-3o9g,2011-08-10,2010-08-04
-6o9x,2019-12-25,2019-03-15
-7o9l,2021-07-14,2021-04-16
-2o9g,2007-02-13,2006-12-13
-6o9b,2019-11-13,2019-03-13
-2o9q,2007-12-25,2006-12-14
-2o92,2006-12-26,2006-12-13
-7o9o,2021-12-15,2021-04-16
-6o9w,2020-06-10,2019-03-15
-1o9u,2003-08-15,2002-12-19
-3o94,2011-01-12,2010-08-03
-1o96,2003-02-06,2002-12-11
-2o97,2007-03-06,2006-12-13
-2o9b,2007-03-06,2006-12-13
-7o9e,2021-12-01,2021-04-15
-3o9k,2010-12-15,2010-08-04
-2o9e,2007-02-13,2006-12-13
-1o9b,2003-02-01,2002-12-12
-2o9r,2007-10-02,2006-12-14
-1weo,2004-11-25,2004-05-25
-5wee,2018-03-28,2017-07-09
-5wef,2017-12-27,2017-07-09
-2weo,2009-11-10,2009-04-01
-5wes,2017-10-18,2017-07-10
-7wea,2022-05-04,2021-12-23
-5wei,2017-12-27,2017-07-10
-3wef,2014-02-12,2013-07-07
-5we0,2017-12-20,2017-07-06
-2wea,1998-05-27,1998-02-03
-8wea,2023-12-06,2023-09-17
-3wew,2014-07-16,2013-07-16
-3we4,2014-08-06,2013-06-29
-6weq,2020-12-23,2020-04-02
-3wez,2014-04-23,2013-07-16
-4we5,2015-02-11,2014-09-09
-3weh,2014-02-12,2013-07-07
-1wes,2004-11-25,2004-05-25
-6we2,2021-03-24,2020-04-01
-3wec,2014-01-01,2013-07-03
-5wep,2018-07-18,2017-07-10
-1weq,2004-11-25,2004-05-25
-6wep,2020-06-17,2020-04-02
-2wef,2009-04-14,2009-03-30
-6wed,2021-02-10,2020-04-02
-6wew,2020-09-09,2020-04-03
-6weg,2020-11-11,2020-04-02
-8we3,2023-12-27,2023-09-16
-2we0,2009-07-07,2009-03-27
-2we2,2009-07-07,2009-03-27
-5we2,2017-12-20,2017-07-06
-3wek,2014-02-12,2013-07-07
-3we0,2014-02-12,2013-06-26
-2wes,2009-04-21,2009-04-01
-6wet,2020-09-09,2020-04-02
-2web,1998-05-27,1998-02-03
-5wea,2017-11-22,2017-07-08
-6we0,2020-12-16,2020-04-01
-7wex,2022-06-29,2021-12-24
-4weg,2015-09-16,2014-09-10
-3weg,2014-02-12,2013-07-07
-6wej,2020-06-03,2020-04-02
-6weu,2020-09-09,2020-04-03
-6we9,2020-07-15,2020-04-01
-5wet,2017-10-18,2017-07-10
-2we5,2010-03-16,2009-03-27
-2wer,2009-04-14,2009-04-01
-7wel,2022-08-03,2021-12-23
-1we1,2004-12-21,2004-05-21
-4wev,2015-01-14,2014-09-11
-3wei,2014-02-12,2013-07-07
-5weo,2017-08-02,2017-07-10
-6we3,2021-03-24,2020-04-01
-5wew,2018-07-18,2017-07-10
-2wed,1998-05-27,1998-02-03
-6wex,2020-11-25,2020-04-03
-4wel,2015-04-22,2014-09-10
-7wez,2022-12-28,2021-12-24
-2wec,1998-05-27,1998-02-03
-5we6,2018-04-25,2017-07-07
-4weq,2014-09-24,2014-09-10
-7we4,2022-08-03,2021-12-22
-4wek,2015-04-22,2014-09-10
-2wet,2009-04-14,2009-04-01
-5wed,2017-10-18,2017-07-09
-4we3,2015-09-30,2014-09-09
-2weg,2009-11-10,2009-03-31
-4wey,2015-01-21,2014-09-11
-3wej,2014-02-12,2013-07-07
-1we2,2005-05-17,2004-05-22
-5we4,2018-04-25,2017-07-07
-4weo,2014-09-24,2014-09-10
-3wem,2014-07-16,2013-07-09
-2wey,2009-07-28,2009-04-02
-5we9,2017-12-27,2017-07-07
-3we7,2014-05-07,2013-07-01
-4we6,2015-02-11,2014-09-09
-7wec,2022-05-04,2021-12-23
-7weg,2022-11-16,2021-12-23
-1wew,2004-11-25,2004-05-25
-4wea,2015-02-11,2014-09-09
-8wej,2024-01-24,2023-09-18
-6wek,2020-06-03,2020-04-02
-4wer,2014-09-24,2014-09-10
-5wej,2017-12-13,2017-07-10
-1wet,1997-11-21,1997-04-27
-7we8,2022-05-04,2021-12-23
-1wev,2004-11-25,2004-05-25
-2wev,2009-06-09,2009-04-01
-5wev,2017-09-06,2017-07-10
-7wew,2022-02-09,2021-12-24
-1wej,1998-12-09,1998-03-26
-4we9,2015-02-11,2014-09-09
-2wex,2009-09-15,2009-04-02
-7wet,2022-12-28,2021-12-24
-2weh,2009-11-10,2009-03-31
-6we6,2020-07-08,2020-04-01
-3wev,2013-09-04,2013-07-12
-1we9,2004-11-24,2004-05-24
-8we8,2023-12-06,2023-09-17
-4wec,2014-10-08,2014-09-09
-3wel,2014-07-16,2013-07-08
-6we4,2021-03-24,2020-04-01
-1wei,2004-09-21,2004-05-25
-1wee,2004-11-24,2004-05-24
-4wef,2015-09-16,2014-09-10
-8we6,2023-12-06,2023-09-17
-6we5,2020-04-08,2020-04-01
-2we3,2009-07-07,2009-03-27
-4we1,2014-12-03,2014-09-09
-6wer,2020-12-23,2020-04-02
-2wej,2009-11-10,2009-03-31
-7web,2022-05-04,2021-12-23
-5we1,2017-12-20,2017-07-06
-3wex,2014-07-23,2013-07-16
-3we8,2014-05-21,2013-07-02
-2we1,2009-07-07,2009-03-27
-8we7,2023-12-06,2023-09-17
-1wem,2004-11-25,2004-05-25
-4wei,2015-02-04,2014-09-10
-2wez,2009-05-19,2009-04-02
-5web,2018-01-03,2017-07-08
-1weu,2004-11-25,2004-05-25
-4wed,2014-09-24,2014-09-09
-8wey,2024-02-14,2023-09-19
-3weo,2014-07-16,2013-07-09
-3wen,2014-07-16,2013-07-09
-5wek,2017-08-02,2017-07-10
-7we9,2022-05-04,2021-12-23
-1wen,2004-11-25,2004-05-25
-2weq,2009-04-14,2009-04-01
-8we9,2023-12-06,2023-09-17
-2wek,2009-12-15,2009-03-31
-2weu,2009-04-14,2009-04-01
-4web,2014-12-17,2014-09-09
-2wep,2009-04-14,2009-04-01
-4wej,2015-04-22,2014-09-10
-6wev,2020-09-09,2020-04-03
-6wel,2020-06-03,2020-04-02
-4we4,2015-02-11,2014-09-09
-2wei,2009-04-28,2009-03-31
-6wea,2020-07-15,2020-04-01
-8wex,2024-05-22,2023-09-19
-4wee,2014-10-01,2014-09-09
-6wee,2021-02-10,2020-04-02
-4we7,2015-02-11,2014-09-09
-6wef,2021-02-10,2020-04-02
-4wet,2015-01-21,2014-09-11
-5weh,2017-09-13,2017-07-10
-5wex,2017-10-11,2017-07-10
-2wel,2009-04-14,2009-03-31
-5wen,2017-08-02,2017-07-10
-1wep,2004-11-25,2004-05-25
-5wey,2017-09-13,2017-07-11
-5we7,2018-01-03,2017-07-07
-7we7,2022-05-04,2021-12-23
-4we8,2015-02-11,2014-09-09
-6we1,2020-12-16,2020-04-01
-5we8,2017-08-16,2017-07-07
-6wez,2020-11-25,2020-04-03
-6we7,2021-04-07,2020-04-01
-6weo,2021-04-28,2020-04-02
-5wel,2017-08-02,2017-07-10
-3m4p,2010-03-23,2010-03-11
-3m49,2010-04-07,2010-03-10
-1m4n,2003-04-22,2002-07-03
-4m4k,2013-09-25,2013-08-07
-7m4l,2022-07-06,2021-03-21
-4m4d,2013-10-30,2013-08-07
-7m41,2021-10-13,2021-03-19
-4m4n,2014-09-17,2013-08-07
-1m4i,2002-08-28,2002-07-02
-6m4n,2021-02-10,2020-03-07
-7m4b,2022-07-06,2021-03-21
-3m4w,2010-05-05,2010-03-12
-6m47,2021-02-17,2020-03-05
-3m4b,2011-01-12,2010-03-10
-3m4c,2011-01-12,2010-03-10
-4m42,2014-02-12,2013-08-06
-5m42,2017-03-15,2016-10-18
-1m4m,2002-09-25,2002-07-03
-7m49,2022-07-06,2021-03-21
-7m44,2022-07-06,2021-03-21
-1m49,2002-07-31,2002-07-02
-4m4p,2013-10-30,2013-08-07
-4m40,2013-09-25,2013-08-06
-7m4g,2022-07-06,2021-03-21
-7m4v,2021-05-19,2021-03-22
-6m4j,2020-04-22,2020-03-07
-7m4i,2022-07-06,2021-03-21
-4m44,2013-09-25,2013-08-06
-3m4h,2010-12-15,2010-03-11
-6m4q,2020-08-12,2020-03-08
-3m40,2010-10-20,2010-03-10
-7m43,2022-07-06,2021-03-21
-5m4j,2017-07-12,2016-10-18
-5m4q,2017-07-12,2016-10-18
-1m4a,2002-07-31,2002-07-02
-7m4u,2021-05-19,2021-03-22
-4m4v,2014-09-17,2013-08-07
-5m4h,2017-02-22,2016-10-18
-7m48,2022-07-06,2021-03-21
-6m4i,2021-03-10,2020-03-07
-1m4h,2002-08-28,2002-07-02
-1m4d,2002-08-28,2002-07-02
-7m40,2021-05-12,2021-03-19
-5m4a,2017-11-01,2016-10-18
-3m4v,2011-03-23,2010-03-12
-3m4o,2010-05-12,2010-03-11
-6m4u,2020-08-26,2020-03-09
-7m4e,2022-07-06,2021-03-21
-5m4o,2017-09-27,2016-10-18
-7m4p,2021-05-19,2021-03-22
-5m4f,2017-01-18,2016-10-18
-4m4m,2014-01-15,2013-08-07
-1m40,2002-07-17,2002-07-01
-4m4r,2013-10-30,2013-08-07
-4m45,2014-02-12,2013-08-06
-4m4l,2014-01-15,2013-08-07
-4m4s,2014-03-12,2013-08-07
-4m4b,2014-07-16,2013-08-06
-3m4r,2010-04-14,2010-03-11
-1m43,2002-07-24,2002-07-02
-7m42,2021-07-28,2021-03-19
-1m4u,2002-12-18,2002-07-03
-5m4m,2017-02-22,2016-10-18
-6m44,2020-10-07,2020-03-05
-3m4n,2010-07-28,2010-03-11
-7m4m,2022-01-05,2021-03-21
-5m44,2017-01-18,2016-10-18
-5m45,2017-08-09,2016-10-18
-6m4v,2020-08-26,2020-03-09
-7m4j,2022-07-06,2021-03-21
-5m4k,2017-02-22,2016-10-18
-5m4g,2017-07-12,2016-10-18
-5m4p,2017-02-22,2016-10-18
-3m4j,2010-07-28,2010-03-11
-1m48,2002-07-31,2002-07-02
-1m4y,2003-05-06,2002-07-05
-5m41,2017-12-06,2016-10-17
-6m4l,2020-09-16,2020-03-07
-4m4y,2013-09-25,2013-08-07
-4m41,2014-02-12,2013-08-06
-4m48,2013-09-18,2013-08-06
-5m4e,2017-02-22,2016-10-18
-2m48,2013-05-15,2013-01-30
-4m4g,2014-08-13,2013-08-07
-6m4o,2021-02-10,2020-03-08
-4m4q,2013-09-18,2013-08-07
-1m4b,2002-07-31,2002-07-02
-5m4u,2017-01-18,2016-10-19
-6m4e,2020-09-02,2020-03-06
-5m4d,2017-04-19,2016-10-18
-1m4l,2003-01-10,2002-07-03
-4m4u,2014-09-17,2013-08-07
-5m4c,2017-01-18,2016-10-18
-6m4f,2020-09-02,2020-03-06
-7m4r,2021-03-31,2021-03-22
-3m42,2011-03-23,2010-03-10
-1m4q,2002-11-06,2002-07-03
-7m4f,2022-07-06,2021-03-21
-7m4x,2021-05-19,2021-03-22
-6m49,2021-01-20,2020-03-06
-7m4h,2022-07-06,2021-03-21
-3m45,2010-09-08,2010-03-10
-1m4g,2002-08-28,2002-07-02
-4m4i,2014-01-15,2013-08-07
-5m4i,2017-01-18,2016-10-18
-4m4f,2014-01-15,2013-08-07
-5m4b,2017-04-19,2016-10-18
-7m4d,2022-07-06,2021-03-21
-7m4y,2021-05-19,2021-03-22
-4m47,2014-01-22,2013-08-06
-1m4z,2002-09-11,2002-07-05
-7m4c,2022-07-06,2021-03-21
-5m4n,2017-02-22,2016-10-18
-7m45,2022-07-06,2021-03-21
-1m4w,2003-07-08,2002-07-05
-7m4o,2022-01-05,2021-03-21
-3m4g,2010-07-28,2010-03-11
-6m4p,2020-08-12,2020-03-08
-7m4n,2022-01-05,2021-03-21
-7m4k,2022-07-06,2021-03-21
-7m46,2022-07-06,2021-03-21
-3m4e,2010-05-05,2010-03-10
-7m4w,2021-05-19,2021-03-22
-4m4a,2014-07-16,2013-08-06
-6m4m,2020-09-16,2020-03-07
-6m4k,2020-09-16,2020-03-07
-5m46,2017-04-19,2016-10-18
-6m4s,2021-02-03,2020-03-09
-4m4h,2014-01-15,2013-08-07
-7m47,2022-07-06,2021-03-21
-5m49,2017-04-19,2016-10-18
-6m48,2020-07-29,2020-03-05
-7m4t,2021-08-11,2021-03-22
-5m4z,2017-12-20,2016-10-19
-5m4l,2017-07-12,2016-10-18
-3m48,2011-02-16,2010-03-10
-4m49,2013-09-04,2013-08-06
-4m4j,2014-01-15,2013-08-07
-7m4z,2021-05-19,2021-03-22
-1m4p,2002-11-06,2002-07-03
-7m4a,2022-07-06,2021-03-21
-3m4z,2010-11-10,2010-03-12
-5m47,2016-11-02,2016-10-18
-3vg0,2012-03-14,2012-01-10
-6vgg,2020-11-25,2020-01-08
-5vge,2017-06-07,2017-04-11
-7vgt,2022-02-16,2021-09-18
-6vgn,2020-03-18,2020-01-08
-7vgv,2022-02-16,2021-09-18
-7vg7,2022-08-17,2021-09-14
-6vgz,2020-08-12,2020-01-09
-2vgq,2007-12-11,2007-11-15
-2vgz,2007-12-04,2007-11-16
-2vgg,2007-11-20,2007-11-13
-6vg9,2021-02-10,2020-01-07
-5vg9,2018-01-17,2017-04-10
-8vgz,2024-02-14,2023-12-30
-2vgb,2007-11-20,2007-11-12
-5vgt,2017-12-27,2017-04-11
-5vgc,2018-04-18,2017-04-10
-6vgy,2020-08-12,2020-01-09
-1vgn,2005-06-21,2004-04-27
-7vg8,2022-09-21,2021-09-14
-2vg6,2007-12-11,2007-11-08
-2vgc,1997-11-12,1997-05-01
-5vgm,2017-04-26,2017-04-11
-3vg6,2012-06-20,2011-08-03
-2vgt,2007-12-04,2007-11-15
-6vgl,2021-01-13,2020-01-08
-2vgp,2008-02-26,2007-11-15
-2vgr,2008-08-05,2007-11-15
-2vgw,2007-12-04,2007-11-15
-7vgi,2022-03-30,2021-09-16
-2vgs,2007-12-04,2007-11-15
-3vgl,2011-12-07,2011-08-15
-7vgp,2022-02-23,2021-09-17
-5vg0,2017-05-24,2017-04-10
-5vgp,2018-04-18,2017-04-11
-5vg1,2017-05-24,2017-04-10
-5vgy,2017-08-30,2017-04-11
-3vgi,2012-09-12,2011-08-11
-7vgz,2022-03-02,2021-09-20
-2vgj,2008-11-25,2007-11-14
-2vg9,2007-12-25,2007-11-09
-2vg1,2007-11-13,2007-11-07
-2vgf,2007-11-20,2007-11-12
-5vgx,2017-05-31,2017-04-11
-3vgj,2012-07-25,2011-08-14
-7vgu,2022-02-16,2021-09-18
-5vgs,2017-07-26,2017-04-11
-6vgc,2020-12-02,2020-01-07
-5vg7,2018-06-20,2017-04-10
-6vgf,2020-10-28,2020-01-08
-5vgr,2017-05-17,2017-04-11
-6vgi,2020-12-02,2020-01-08
-5vg2,2018-04-11,2017-04-10
-3vgc,1997-11-12,1997-05-01
-5vgi,2017-09-27,2017-04-11
-6vg5,2020-07-15,2020-01-07
-1vgv,2003-11-25,2003-11-03
-3vgg,2012-06-20,2011-08-09
-1vg0,2004-07-20,2004-04-22
-5vgd,2017-05-31,2017-04-11
-1vgx,2003-11-25,2003-11-03
-2vg8,2007-12-04,2007-11-09
-8vg5,2024-05-01,2023-12-22
-3vgk,2011-12-07,2011-08-15
-5vgv,2017-05-31,2017-04-11
-7vg5,2022-07-06,2021-09-14
-5vgo,2017-07-05,2017-04-11
-7vgf,2022-02-16,2021-09-16
-5vg3,2017-10-18,2017-04-10
-3vgf,2012-06-20,2011-08-09
-8vg3,,2023-12-22
-4vgc,1997-11-12,1997-05-01
-7vgm,2022-04-27,2021-09-17
-3vg3,2012-06-20,2011-08-03
-6vgm,2021-01-06,2020-01-08
-1vg8,2004-07-20,2004-04-23
-2vgv,2007-12-04,2007-11-15
-2vgk,2008-11-25,2007-11-14
-7vgy,2022-03-02,2021-09-20
-6vg1,2020-03-11,2020-01-07
-6vg4,2020-03-11,2020-01-07
-5vg6,2017-04-26,2017-04-10
-3vgh,2012-06-20,2011-08-09
-3vg5,2012-06-20,2011-08-03
-7vg2,2021-10-27,2021-09-14
-3vgm,2011-12-07,2011-08-15
-7vgn,2022-09-21,2021-09-17
-7vgo,2022-02-23,2021-09-17
-6vgh,2020-02-12,2020-01-08
-8vg8,2024-05-01,2023-12-23
-7vgh,2022-03-30,2021-09-16
-7vgb,2022-05-25,2021-09-15
-1vgo,2005-10-04,2004-04-28
-3vgn,2012-08-22,2011-08-16
-2vgi,2007-11-20,2007-11-13
-2vg5,2007-12-11,2007-11-08
-1vg9,2004-07-20,2004-04-23
-3vg4,2012-06-20,2011-08-03
-2vgd,2007-12-25,2007-11-12
-8vgt,2024-03-06,2023-12-27
-3vg1,2012-11-21,2012-01-10
-2vgo,2008-10-28,2007-11-15
-7vg3,2021-10-27,2021-09-14
-7vgc,2022-05-25,2021-09-15
-2vg3,2008-05-06,2007-11-08
-2vg2,2007-11-13,2007-11-07
-1vgr,2004-08-03,2004-04-28
-1vgc,1997-11-12,1997-05-01
-1vgk,2005-06-28,2004-04-27
-6vg6,2021-01-06,2020-01-07
-6vgq,2020-03-18,2020-01-08
-5vgj,2017-05-31,2017-04-11
-1vg1,2004-07-20,2004-04-22
-6vg0,2020-02-05,2020-01-07
-2vgu,2007-12-04,2007-11-15
-1vgq,2004-08-03,2004-04-28
-8vgd,2024-02-14,2023-12-27
-5vgz,2017-08-23,2017-04-12
-3vg9,2012-02-01,2011-08-04
-1vgi,2004-08-31,2004-04-26
-1vgl,2005-08-16,2004-04-27
-2vg7,2007-12-11,2007-11-08
-3vga,2012-02-01,2011-08-04
-7vgq,2021-09-29,2021-09-18
-3vgw,2011-12-28,2011-08-21
-2vg0,2007-11-13,2007-11-07
-6vgs,2020-08-05,2020-01-08
-1obo,2003-04-24,2003-01-31
-6ob3,2019-10-16,2019-03-19
-5ob2,2017-07-12,2017-06-25
-7ob6,2022-04-27,2021-04-21
-4obv,2014-10-29,2014-01-07
-6ob8,2019-09-18,2019-03-19
-6oba,2020-03-25,2019-03-20
-7obs,2022-05-04,2021-04-23
-7obg,2022-05-04,2021-04-22
-1ob2,2004-05-27,2003-01-24
-1obc,2003-05-09,2003-01-30
-5obj,2017-08-09,2017-06-28
-5obr,2017-08-09,2017-06-29
-5obt,2018-04-11,2017-06-29
-6obb,2020-03-25,2019-03-20
-2ob3,2007-01-30,2006-12-18
-1oby,2003-07-11,2003-01-31
-6obe,2020-04-01,2019-03-20
-4obw,2014-08-06,2014-01-07
-4obi,2014-02-12,2014-01-07
-2obl,2007-01-30,2006-12-19
-4obd,2014-11-26,2014-01-07
-3obt,2010-09-08,2010-08-09
-6obl,2020-03-25,2019-03-21
-2obm,2007-01-30,2006-12-19
-6obh,2019-08-28,2019-03-20
-4obg,2014-11-26,2014-01-07
-2ob2,2007-01-30,2006-12-18
-2obq,2007-07-31,2006-12-19
-7obx,2022-05-04,2021-04-23
-2obb,2007-01-16,2006-12-18
-3obz,2010-09-01,2010-08-09
-2obf,2007-10-09,2006-12-19
-1obm,1998-04-08,1997-12-19
-3ob6,2011-03-16,2010-08-06
-3ob4,2011-02-02,2010-08-06
-5obo,2018-08-01,2017-06-28
-1obn,2004-02-02,2003-01-31
-2obj,2007-02-06,2006-12-19
-5obz,2017-10-18,2017-06-29
-7obz,2021-06-30,2021-04-25
-1obv,2003-04-24,2003-01-31
-4oba,2014-03-19,2014-01-07
-7obt,2022-05-04,2021-04-23
-6ob6,2019-07-03,2019-03-19
-6ob0,2019-05-08,2019-03-19
-6obn,2019-09-18,2019-03-21
-6obp,2019-09-18,2019-03-21
-6oby,2019-12-25,2019-03-21
-7ob8,2022-05-04,2021-04-21
-5obb,2018-07-25,2017-06-26
-5obm,2017-12-13,2017-06-28
-6obg,2020-04-01,2019-03-20
-2oba,2007-01-30,2006-12-18
-4obf,2014-11-26,2014-01-07
-6ob7,2019-07-03,2019-03-19
-2obx,2007-08-14,2006-12-20
-4obb,2014-03-19,2014-01-07
-7oba,2021-12-08,2021-04-21
-1ob0,2003-01-30,2003-01-21
-4obe,2014-06-04,2014-01-07
-7obe,2021-06-09,2021-04-22
-3ob8,2011-08-17,2010-08-06
-5obg,2018-08-01,2017-06-26
-7ob9,2021-12-08,2021-04-21
-7obc,2022-05-04,2021-04-21
-6obu,2019-09-18,2019-03-21
-2obh,2007-10-09,2006-12-19
-6obo,2020-04-01,2019-03-21
-1obw,1997-09-04,1996-10-09
-7obw,2021-08-04,2021-04-23
-5obw,2018-05-09,2017-06-29
-5oby,2018-05-09,2017-06-29
-4ob6,2014-07-23,2014-01-07
-2obd,2007-01-23,2006-12-18
-6ob5,2019-12-04,2019-03-19
-6obj,2020-02-26,2019-03-20
-6obd,2019-07-03,2019-03-20
-6obf,2020-03-25,2019-03-20
-7ob5,2022-05-04,2021-04-21
-1obf,2003-06-12,2003-01-30
-2oby,2007-01-30,2006-12-20
-3obx,2010-12-01,2010-08-09
-3oba,2011-08-17,2010-08-06
-4oby,2014-02-12,2014-01-08
-4ob5,2014-10-08,2014-01-06
-4obp,2014-04-23,2014-01-07
-3ob0,2011-01-12,2010-08-06
-2obo,2007-07-31,2006-12-19
-4ob1,2014-11-26,2014-01-06
-3obq,2010-12-01,2010-08-09
-3obg,2010-08-25,2010-08-06
-3ob7,2010-12-22,2010-08-06
-4ob2,2014-11-26,2014-01-06
-2obv,2007-01-02,2006-12-20
-2obt,2007-04-24,2006-12-20
-5oba,2018-07-25,2017-06-26
-6obs,2019-09-18,2019-03-21
-7obj,2022-02-02,2021-04-22
-6ob2,2019-10-16,2019-03-19
-1ob7,2003-12-11,2003-01-24
-5obu,2018-05-09,2017-06-29
-3obp,2011-06-22,2010-08-08
-4obr,2015-01-14,2014-01-07
-7obo,2022-04-20,2021-04-23
-3obk,2010-09-15,2010-08-06
-5ob6,2017-07-26,2017-06-26
-7obh,2022-05-04,2021-04-22
-3obu,2010-12-01,2010-08-09
-4obo,2014-04-23,2014-01-07
-5obv,2018-05-09,2017-06-29
-1obr,1997-01-11,1996-06-22
-7obv,2022-04-06,2021-04-23
-3obv,2010-11-24,2010-08-09
-7obd,2022-05-04,2021-04-21
-5ob7,2017-07-26,2017-06-26
-4obs,2015-01-14,2014-01-07
-5ob8,2017-07-26,2017-06-26
-7obk,2022-05-04,2021-04-22
-7obb,2021-12-08,2021-04-21
-1obd,2003-03-06,2003-01-30
-4obu,2014-10-29,2014-01-07
-1obt,1997-06-16,1996-06-22
-4obz,2014-08-13,2014-01-08
-7obu,2022-10-26,2021-04-23
-5obh,2018-08-01,2017-06-27
-4ob3,2014-11-26,2014-01-06
-6obr,2019-09-18,2019-03-21
-1obb,2003-05-21,2003-01-29
-5obk,2018-04-04,2017-06-28
-7ob3,2022-05-04,2021-04-20
-2obs,2007-04-24,2006-12-20
-7obr,2021-07-21,2021-04-23
-1obh,2003-05-09,2003-01-31
-4obq,2014-04-23,2014-01-07
-1obx,2003-07-10,2003-01-31
-6obq,2019-09-18,2019-03-21
-7ob0,2021-06-30,2021-04-20
-6obx,2020-02-12,2019-03-21
-7obn,2022-02-09,2021-04-23
-1obz,2003-07-11,2003-01-31
-1ob5,2005-10-13,2003-01-24
-2ob0,2006-12-26,2006-12-18
-7oby,2022-05-04,2021-04-24
-2obc,2007-02-13,2006-12-18
-1obg,2003-03-06,2003-01-30
-4ob0,2014-11-26,2014-01-06
-7obq,2021-07-21,2021-04-23
-7obl,2022-05-04,2021-04-22
-3obj,2010-08-25,2010-08-06
-1lgt,2002-11-27,2002-04-16
-5lgz,2017-02-15,2016-07-08
-3lgy,2010-08-25,2010-01-21
-5lg6,2017-04-12,2016-07-06
-4lgd,2013-09-18,2013-06-27
-3lg1,2010-12-29,2010-01-19
-5lgt,2017-02-22,2016-07-08
-4lgn,2013-12-11,2013-06-28
-7lgd,2021-04-21,2021-01-20
-5lg1,2016-12-14,2016-07-05
-2lgk,2011-09-28,2011-07-28
-7lgi,2021-07-21,2021-01-20
-7lgq,2021-08-18,2021-01-20
-5lg8,2017-02-22,2016-07-06
-7lg7,2021-02-17,2021-01-19
-6lgh,2020-05-20,2019-12-05
-6lgm,2020-12-09,2019-12-05
-3lgz,2010-12-22,2010-01-21
-3lg5,2010-02-09,2010-01-19
-5lgq,2017-03-22,2016-07-08
-4lgb,2013-08-14,2013-06-27
-1lgc,1994-08-31,1994-01-07
-5lgb,2017-08-16,2016-07-06
-1lgw,2002-05-08,2002-04-16
-6lgc,2020-05-20,2019-12-05
-1lgx,2002-05-08,2002-04-16
-3lga,2010-06-02,2010-01-20
-6lg0,2020-11-18,2019-12-04
-2lgf,2012-06-13,2011-07-25
-6lg9,2020-12-09,2019-12-04
-5lgr,2017-03-22,2016-07-08
-7lg1,2021-03-10,2021-01-19
-4lga,2013-08-14,2013-06-27
-3lgx,2010-03-02,2010-01-21
-7lg2,2021-02-03,2021-01-19
-6lgd,2020-05-20,2019-12-05
-1lga,1993-10-31,1992-12-08
-7lgj,2021-08-18,2021-01-20
-5lgd,2016-08-31,2016-07-06
-6lg2,2020-02-12,2019-12-04
-7lg3,2021-02-03,2021-01-19
-4lgk,2013-10-02,2013-06-28
-3lg4,2010-07-28,2010-07-08
-5lgu,2017-02-22,2016-07-08
-1lgb,1994-08-31,1994-01-07
-3lgf,2010-03-23,2010-01-20
-4lge,2013-08-28,2013-06-27
-4lg0,2014-07-02,2013-06-27
-5lg7,2017-06-28,2016-07-06
-6lge,2020-05-20,2019-12-05
-3lgh,2010-09-15,2010-01-20
-5lgs,2017-03-22,2016-07-08
-1lgh,1997-06-05,1996-03-20
-7lgu,2021-08-25,2021-01-21
-3lgg,2010-02-09,2010-01-20
-7lgt,2021-04-21,2021-01-21
-6lgi,2020-05-20,2019-12-05
-6lg6,2020-12-09,2019-12-04
-4lg2,2013-07-10,2013-06-27
-3lgs,2010-06-30,2010-01-21
-2lgv,2012-03-28,2011-08-02
-1lg1,2002-09-18,2002-04-14
-7lgp,2021-01-27,2021-01-20
-5lgj,2017-03-15,2016-07-07
-3lgm,2010-03-09,2010-01-20
-6lgo,2020-12-09,2019-12-05
-4lgg,2013-08-07,2013-06-27
-4lgy,2013-12-11,2013-06-30
-7lgw,2021-08-25,2021-01-21
-1lgn,1997-12-24,1996-12-04
-6lg5,2020-12-09,2019-12-04
-7lg5,2021-08-18,2021-01-19
-5lgh,2016-08-03,2016-07-07
-1lgd,2002-07-24,2002-04-15
-6lg1,2020-11-18,2019-12-04
-2lgs,1994-11-30,1994-08-05
-6lg4,2020-12-09,2019-12-04
-6lgk,2020-12-09,2019-12-05
-5lgw,2016-08-17,2016-07-08
-4lg5,2013-08-14,2013-06-27
-7lgk,2021-05-05,2021-01-20
-5lge,2017-02-08,2016-07-07
-3lgb,2010-04-21,2010-01-20
-2lgl,2011-09-28,2011-07-28
-5lg0,2017-06-28,2016-07-05
-3lge,2010-02-02,2010-01-20
-3lgq,2011-02-16,2010-01-21
-3lgl,2010-03-23,2010-01-20
-5lga,2016-10-19,2016-07-06
-3lgn,2010-03-09,2010-01-20
-3lgr,2011-01-19,2010-01-21
-6lg7,2020-12-09,2019-12-04
-1lgr,1994-11-30,1994-08-05
-7lg8,2022-02-23,2021-01-19
-3lgp,2010-07-28,2010-01-21
-3lgj,2010-02-16,2010-01-20
-5lgo,2016-08-10,2016-07-07
-2lgg,2011-09-28,2011-07-26
-4lgh,2013-08-07,2013-06-27
-4lg1,2013-07-17,2013-06-27
-2lgp,2011-11-30,2011-08-01
-7lgm,2021-08-18,2021-01-20
-4lgu,2013-08-28,2013-06-28
-6lg8,2020-12-09,2019-12-04
-1lgf,2002-12-11,2002-04-15
-5lgx,2017-02-15,2016-07-08
-6lgy,2020-12-09,2019-12-06
-4lgr,2014-06-11,2013-06-28
-7lgs,2021-09-22,2021-01-21
-5lgv,2016-08-17,2016-07-08
-5lg2,2017-02-22,2016-07-05
-7lg6,2021-09-15,2021-01-19
-7lg0,2021-02-03,2021-01-19
-5lgc,2017-08-02,2016-07-06
-6lgt,2020-10-14,2019-12-05
-5lgy,2016-07-27,2016-07-08
-1lg6,2002-07-24,2002-04-15
-4lgj,2014-01-15,2013-06-28
-7lgb,2021-04-21,2021-01-19
-5lgp,2017-03-22,2016-07-08
-6lga,2020-05-20,2019-12-05
-1lg5,2002-07-24,2002-04-15
-6lgj,2020-12-09,2019-12-05
-7lgx,2022-01-26,2021-01-21
-6lgg,2020-05-20,2019-12-05
-6lgb,2020-05-20,2019-12-05
-5lgk,2017-04-05,2016-07-07
-1lg9,2002-12-11,2002-04-15
-5lg3,2016-10-26,2016-07-05
-6lgf,2020-05-20,2019-12-05
-5lgn,2017-02-22,2016-07-07
-5ewh,2016-06-08,2015-11-20
-3ewr,2009-01-13,2008-10-16
-2ewn,2006-02-21,2005-11-04
-1ewk,2000-12-18,2000-04-26
-3ewx,2009-04-07,2008-10-16
-3ewv,2009-10-20,2008-10-16
-3eww,2009-04-07,2008-10-16
-5ewa,2016-06-01,2015-11-20
-8ewh,2022-11-16,2022-10-23
-6ewo,2018-11-07,2017-11-06
-4ewg,2012-05-16,2012-04-26
-3ewy,2009-04-07,2008-10-16
-7ewb,2021-12-29,2021-05-25
-3ewu,2009-04-07,2008-10-16
-5ew9,2016-01-20,2015-11-20
-5ewg,2016-01-13,2015-11-20
-8ewr,2023-02-01,2022-10-24
-3ew9,2009-05-05,2008-10-14
-6ew6,2018-10-24,2017-11-03
-5ewj,2016-03-02,2015-11-20
-6ewf,2019-02-06,2017-11-03
-5ewy,2016-03-23,2015-11-22
-6ewr,2018-05-02,2017-11-06
-6ewk,2018-11-14,2017-11-04
-3ewk,2009-03-24,2008-10-15
-7ew4,2021-09-29,2021-05-24
-4ew3,2013-07-31,2012-04-26
-7ew0,2021-09-29,2021-05-24
-5ew6,2016-08-10,2015-11-20
-7ewu,2022-01-26,2021-05-26
-4ewo,2012-10-31,2012-04-27
-3ewf,2008-12-30,2008-10-14
-4ew7,2012-09-12,2012-04-26
-1ewp,2000-05-17,2000-04-26
-4ew4,2012-07-11,2012-04-26
-2ewu,2006-11-28,2005-11-07
-8ewe,2023-02-01,2022-10-22
-8ewm,2023-02-01,2022-10-24
-5ewv,2016-11-02,2015-11-21
-2ew1,2005-11-08,2005-11-01
-6ew0,2018-07-04,2017-11-03
-3ewz,2009-04-07,2008-10-16
-7ew7,2021-09-29,2021-05-24
-3ew8,2008-12-30,2008-10-14
-2ews,2006-09-12,2005-11-06
-1ewm,2003-06-10,2000-04-26
-3ewt,2009-10-20,2008-10-16
-2ewg,2006-10-31,2005-11-03
-7ew9,2021-12-29,2021-05-25
-3ewd,2009-09-22,2008-10-14
-5ewd,2016-05-25,2015-11-20
-4ewn,2012-12-05,2012-04-27
-8ew4,2022-11-09,2022-10-21
-4ew2,2013-07-31,2012-04-26
-5eww,2016-11-02,2015-11-21
-4ewq,2012-06-27,2012-04-27
-2ewm,2006-03-14,2005-11-04
-8ewn,2023-02-01,2022-10-24
-5ewe,2016-01-13,2015-11-20
-6ew8,2018-10-24,2017-11-03
-1ew0,2000-05-10,2000-04-21
-5ewc,2016-05-25,2015-11-20
-7ewq,2021-06-23,2021-05-25
-2ewl,2006-10-17,2005-11-04
-8ewv,2023-10-04,2022-10-24
-2ewb,2006-04-04,2005-11-02
-7ewh,2022-12-07,2021-05-25
-1ewy,2001-02-07,2000-04-28
-5ewx,2016-03-30,2015-11-22
-8ews,2023-02-01,2022-10-24
-2ewy,2006-11-07,2005-11-07
-8ewa,2022-11-09,2022-10-21
-5ewu,2016-12-07,2015-11-21
-2ew2,2005-12-13,2005-11-01
-2ew5,2006-10-24,2005-11-02
-8ew1,2023-05-10,2022-10-21
-6ewc,2018-11-07,2017-11-03
-1ewj,2001-04-26,2000-04-26
-5ew8,2016-03-30,2015-11-20
-5ews,2016-09-14,2015-11-21
-3ew5,2009-10-27,2008-10-14
-1ewo,2003-06-10,2000-04-26
-4ewv,2012-06-13,2012-04-28
-5ewm,2016-03-02,2015-11-20
-8ewq,2023-02-01,2022-10-24
-5ew3,2015-12-16,2015-11-20
-3ews,2008-11-04,2008-10-16
-8ew7,2022-11-09,2022-10-21
-8ewt,2023-11-15,2022-10-24
-6eww,2017-11-15,2017-11-06
-5ewf,2016-01-13,2015-11-20
-5ewk,2016-03-23,2015-11-20
-1ew9,2002-05-01,2000-04-24
-8ewl,2023-02-01,2022-10-24
-1ewa,2000-05-10,2000-04-24
-7ewz,2022-01-26,2021-05-26
-4ewz,2013-05-01,2012-04-29
-8ewo,2022-11-16,2022-10-24
-5ewz,2016-05-04,2015-11-23
-5ew0,2016-06-01,2015-11-20
-8ewb,2023-09-06,2022-10-22
-1ew8,2002-05-01,2000-04-24
-3ew2,2008-12-23,2008-10-14
-8ewy,2023-03-08,2022-10-24
-7eww,2022-01-26,2021-05-26
-4eww,2013-05-01,2012-04-28
-3ewp,2009-01-13,2008-10-16
-7ew2,2021-09-29,2021-05-24
-8ewf,2023-10-25,2022-10-22
-1ewt,2000-12-18,2000-04-27
-4ewx,2013-05-01,2012-04-28
-8ewp,2023-02-01,2022-10-24
-6ew7,2018-10-24,2017-11-03
-2ew6,2006-10-24,2005-11-02
-1ewn,2000-12-11,2000-04-26
-7ewk,2022-01-12,2021-05-25
-7ew1,2021-09-29,2021-05-24
-1ewl,2003-06-10,2000-04-26
-1ewh,2000-08-09,2000-04-25
-2ewv,2006-11-21,2005-11-07
-2ewa,2006-08-01,2005-11-02
-2eww,2006-11-21,2005-11-07
-3ewj,2008-11-18,2008-10-15
-4ewe,2013-05-29,2012-04-26
-3ewa,2009-05-05,2008-10-14
-6ew3,2018-10-03,2017-11-03
-1ew2,2001-04-04,2000-04-21
-4ew0,2012-07-11,2012-04-26
-4ewt,2013-02-20,2012-04-27
-4ewl,2012-09-26,2012-04-27
-1ewc,2000-05-31,2000-04-25
-4ews,2012-09-05,2012-04-27
-8ew3,2022-11-16,2022-10-21
-5ew1,2016-11-30,2015-11-20
-4ewd,2013-05-29,2012-04-26
-8ew9,2023-03-22,2022-10-21
-6ewz,2018-01-24,2017-11-07
-8ewi,2023-04-19,2022-10-23
-6ewe,2018-10-03,2017-11-03
-4ewa,2013-05-29,2012-04-26
-8ewz,2023-01-18,2022-10-24
-6ewq,2018-05-02,2017-11-06
-4ew9,2013-03-20,2012-04-26
-8ewu,2022-11-09,2022-10-24
-4ewh,2012-09-19,2012-04-27
-7ew6,2021-12-22,2021-05-24
-2ewi,2006-11-28,2005-11-03
-7ewa,2021-12-29,2021-05-25
-6ew9,2018-04-25,2017-11-03
-2ewk,2006-11-28,2005-11-03
-2ewp,2006-05-09,2005-11-04
-2ew7,2006-10-24,2005-11-02
-3ewh,2009-08-25,2008-10-15
-1ew6,2000-05-10,2000-04-24
-5ewl,2016-03-02,2015-11-20
-7ewv,2022-01-26,2021-05-26
-6ewa,2018-11-07,2017-11-03
-8ewd,2023-02-01,2022-10-22
-3ewc,2009-09-22,2008-10-14
-5ew2,2016-11-30,2015-11-20
-7ewx,2022-01-26,2021-05-26
-2ewe,2005-11-15,2005-11-02
-8ewc,2023-09-06,2022-10-22
-8pqb,2023-12-27,2023-07-11
-8pqa,2023-12-27,2023-07-11
-5pqq,2017-03-29,2017-02-07
-1pqh,2003-11-18,2003-06-18
-4pqi,2014-06-25,2014-03-03
-7pq1,2022-09-21,2021-09-15
-6pqz,2020-02-26,2019-07-10
-6pqi,2020-01-22,2019-07-09
-3pq5,2010-12-22,2010-11-25
-5pq2,2017-03-29,2017-02-07
-5pqf,2017-03-29,2017-02-07
-5pq5,2017-03-29,2017-02-07
-8pqc,2023-12-27,2023-07-11
-8pqe,2023-12-27,2023-07-11
-2pql,2007-10-09,2007-05-02
-6pqb,2019-10-16,2019-07-08
-6pq3,2020-05-20,2019-07-08
-7pqv,2022-03-16,2021-09-20
-5pqi,2017-03-29,2017-02-07
-3pqd,2012-01-18,2010-11-26
-5pqu,2017-03-29,2017-02-07
-3pqh,2012-02-22,2010-11-26
-1pq4,2003-11-04,2003-06-17
-2pqb,2008-03-11,2007-05-01
-4pq7,2014-10-08,2014-02-28
-2pqx,2007-09-18,2007-05-03
-5pq8,2017-03-29,2017-02-07
-1pqd,2003-10-07,2003-06-18
-2pqf,2007-05-15,2007-05-02
-3pqc,2011-06-08,2010-11-26
-8pqg,2023-12-27,2023-07-11
-6pqp,2020-01-08,2019-07-09
-2pqd,2008-03-11,2007-05-01
-8pq9,2023-12-27,2023-07-11
-6pqs,2019-11-27,2019-07-10
-2pqc,2008-03-11,2007-05-01
-7pqi,2022-09-28,2021-09-17
-7pqk,2023-01-18,2021-09-17
-7pqt,2022-08-17,2021-09-20
-5pqk,2017-03-29,2017-02-07
-3pqf,2012-01-11,2010-11-26
-4pqg,2014-06-18,2014-03-03
-5pqc,2017-03-29,2017-02-07
-7pqd,2021-11-24,2021-09-17
-6pqu,2019-10-09,2019-07-10
-7pqe,2021-10-06,2021-09-17
-5pqd,2017-03-29,2017-02-07
-7pq9,2022-09-28,2021-09-16
-5pq3,2017-03-29,2017-02-07
-1pq2,2004-01-13,2003-06-17
-7pqp,2021-12-15,2021-09-18
-5pqt,2017-03-29,2017-02-07
-5pq9,2017-03-29,2017-02-07
-4pqb,2015-01-14,2014-03-01
-8pqn,2024-01-10,2023-07-11
-7pqu,2022-08-17,2021-09-20
-2pqw,2007-07-31,2007-05-02
-2pq9,2008-03-11,2007-05-01
-8pq2,2023-11-01,2023-07-10
-6pqx,2019-10-09,2019-07-10
-8pqx,2024-05-29,2023-07-12
-8pqp,2024-02-21,2023-07-11
-1pq6,2003-09-09,2003-06-18
-5pqz,2017-03-29,2017-02-07
-6pqv,2020-06-03,2019-07-10
-5pqb,2017-03-29,2017-02-07
-5pqh,2017-03-29,2017-02-07
-4pq9,2014-03-12,2014-02-28
-5pqs,2017-03-29,2017-02-07
-2pq2,2007-05-29,2007-05-01
-5pqw,2017-03-29,2017-02-07
-3pq7,2010-12-22,2010-11-25
-2pq3,2007-10-16,2007-05-01
-6pq4,2020-08-05,2019-07-08
-6pq0,2020-08-05,2019-07-08
-5pql,2017-03-29,2017-02-07
-5pqg,2017-03-29,2017-02-07
-7pqy,2022-02-02,2021-09-20
-1pq7,2003-11-11,2003-06-18
-4pqc,2015-01-14,2014-03-02
-6pqw,2019-11-27,2019-07-10
-7pq3,2021-11-24,2021-09-16
-4pq6,2015-01-14,2014-02-28
-5pqr,2017-03-29,2017-02-07
-6pq8,2019-12-11,2019-07-08
-5pqj,2017-03-29,2017-02-07
-5pq6,2017-03-29,2017-02-07
-2pqy,2007-08-14,2007-05-03
-4pqt,2014-06-18,2014-03-04
-8pq0,2024-01-31,2023-07-10
-3pq4,2010-12-22,2010-11-25
-5pqp,2017-03-29,2017-02-07
-2pqz,2008-04-15,2007-05-03
-5pqa,2017-03-29,2017-02-07
-3pqr,2011-03-09,2010-11-26
-2pqk,2007-06-19,2007-05-02
-6pqr,2019-10-09,2019-07-09
-8pqi,2023-12-27,2023-07-11
-3pqi,2012-02-22,2010-11-26
-6pqn,2019-10-09,2019-07-09
-1pqj,2003-10-07,2003-06-18
-3pq3,2010-12-22,2010-11-25
-8pqf,2023-12-27,2023-07-11
-6pq1,2020-05-20,2019-07-08
-8pqw,2024-03-27,2023-07-12
-1pq8,2003-11-11,2003-06-18
-1pqc,2003-09-09,2003-06-18
-8pqy,2024-03-27,2023-07-12
-5pq1,2017-03-29,2017-02-07
-2pq7,2007-05-15,2007-05-01
-5pq4,2017-03-29,2017-02-07
-3pq6,2010-12-22,2010-11-25
-8pqd,2023-12-27,2023-07-11
-2pqr,2007-11-06,2007-05-02
-3pqz,2011-07-20,2010-11-29
-6pqc,2019-10-09,2019-07-09
-4pqa,2014-04-30,2014-03-01
-1pqp,2004-08-10,2003-06-18
-5pq7,2017-03-29,2017-02-07
-4pqh,2014-06-25,2014-03-03
-6pqa,2020-04-15,2019-07-08
-5pqm,2017-03-29,2017-02-07
-6pq6,2019-11-27,2019-07-08
-4pqu,2014-06-18,2014-03-04
-7pqm,2022-09-28,2021-09-17
-4pqn,2014-07-02,2014-03-03
-7pqc,2021-12-15,2021-09-16
-1pq3,2003-08-12,2003-06-17
-8pqr,2024-02-21,2023-07-11
-1pqw,2003-07-08,2003-06-19
-5pqy,2017-03-29,2017-02-07
-4pqw,2014-04-02,2014-03-04
-6pql,2019-10-02,2019-07-09
-1pqo,2003-10-07,2003-06-18
-6pq9,2019-12-11,2019-07-08
-8pqo,2024-05-08,2023-07-11
-3pq2,2010-12-22,2010-11-25
-5pqe,2017-03-29,2017-02-07
-4pqk,2014-06-18,2014-03-03
-5pq0,2017-03-29,2017-02-07
-7pqs,2021-12-15,2021-09-20
-6pqo,2020-01-08,2019-07-09
-8pqq,2024-02-21,2023-07-11
-8pqz,2024-03-27,2023-07-12
-5pqv,2017-03-29,2017-02-07
-8pqh,2023-12-27,2023-07-11
-2pqj,2008-02-12,2007-05-02
-1pqi,2003-10-07,2003-06-18
-1pq9,2003-09-09,2003-06-18
-1pqu,2004-08-10,2003-06-19
-8pq7,2023-07-19,2023-07-10
-3pqb,2011-05-11,2010-11-25
-1pq5,2003-11-11,2003-06-18
-1pqm,2003-10-07,2003-06-18
-7pqr,2022-08-24,2021-09-20
-5pqx,2017-03-29,2017-02-07
-6pq5,2020-04-15,2019-07-08
-8pql,2024-02-14,2023-07-11
-2pqm,2008-04-15,2007-05-02
-7pql,2022-09-28,2021-09-17
-6pqd,2019-11-27,2019-07-09
-3pq8,2010-12-22,2010-11-25
-7pqz,2022-02-02,2021-09-20
-5pqn,2017-03-29,2017-02-07
-5pqo,2017-03-29,2017-02-07
-7pqo,2022-05-18,2021-09-17
-5a2y,2015-09-09,2015-05-26
-2a2r,2006-06-06,2005-06-23
-8a2u,2022-08-10,2022-06-06
-5a2l,2015-06-03,2015-05-20
-5a2i,2015-06-03,2015-05-20
-7a20,2020-11-04,2020-08-14
-4a2e,2011-10-12,2011-09-26
-3a20,2009-05-19,2009-04-27
-6a2m,2019-04-24,2018-06-12
-6a23,2019-06-19,2018-06-08
-7a29,2020-10-21,2020-08-16
-2a2s,2006-06-06,2005-06-23
-4a2g,2012-04-25,2011-09-26
-4a2s,2012-11-07,2011-09-28
-8a2h,2022-10-12,2022-06-03
-5a24,2015-12-09,2015-05-12
-5a2h,2016-03-30,2015-05-19
-5a2b,2016-03-30,2015-05-17
-8a28,2022-10-19,2022-06-02
-8a2d,2022-10-19,2022-06-03
-8a2b,2022-10-19,2022-06-03
-1a25,1998-05-06,1998-01-16
-6a20,2018-11-21,2018-06-08
-8a21,2022-11-23,2022-06-02
-6a24,2019-06-19,2018-06-08
-1a2v,1998-05-27,1998-01-12
-1a2n,1998-04-29,1998-01-06
-5a29,2015-07-01,2015-05-15
-1a2t,1998-04-29,1998-01-11
-5a2c,2016-03-30,2015-05-17
-7a2y,2021-08-25,2020-08-18
-7a2a,2020-11-11,2020-08-17
-6a2o,2019-04-24,2018-06-12
-8a2m,2023-02-08,2022-06-03
-4a24,2012-11-07,2011-09-22
-3a24,2009-10-06,2009-04-28
-7a26,2021-03-31,2020-08-16
-1a2f,1998-11-25,1998-01-02
-7a21,2020-09-16,2020-08-14
-5a2p,2016-06-01,2015-05-21
-6a2j,2018-11-21,2018-06-12
-5a2x,2015-09-09,2015-05-26
-5a2f,2015-07-22,2015-05-18
-2a2i,2006-07-04,2005-06-22
-8a23,2023-06-14,2022-06-02
-3a2c,2010-05-12,2009-05-12
-5a2k,2015-06-03,2015-05-20
-8a2i,2022-10-12,2022-06-03
-3a25,2009-09-15,2009-04-28
-1a2q,1998-04-29,1998-01-08
-7a2i,2021-01-27,2020-08-18
-6a2k,2019-04-24,2018-06-12
-3a2y,2010-05-19,2009-06-04
-4a2r,2012-11-07,2011-09-28
-7a2n,2021-08-25,2020-08-18
-4a2h,2011-10-12,2011-09-27
-8a2y,2022-08-10,2022-06-06
-6a2f,2018-08-08,2018-06-11
-3a2g,2010-03-02,2009-05-20
-4a25,2012-10-03,2011-09-22
-2a2c,2005-07-26,2005-06-22
-8a2c,2023-06-14,2022-06-03
-7a2l,2021-08-25,2020-08-18
-5a2s,2016-02-10,2015-05-22
-5a27,2016-03-23,2015-05-15
-3a2q,2009-11-03,2009-05-26
-6a2h,2019-01-16,2018-06-11
-5a2a,2016-03-30,2015-05-16
-1a2x,1998-07-15,1998-01-13
-5a2z,2015-09-09,2015-05-26
-4a23,2011-12-07,2011-09-22
-3a2o,2010-03-02,2009-05-26
-2a2x,2006-11-14,2005-06-23
-4a2n,2012-01-11,2011-09-27
-3a2j,2010-05-26,2009-05-20
-5a25,2015-05-20,2015-05-12
-4a2z,2011-12-21,2011-09-29
-3a2h,2010-05-26,2009-05-20
-7a2k,2021-08-25,2020-08-18
-3a29,2009-10-06,2009-05-08
-4a2c,2012-08-08,2011-09-26
-4a2j,2012-04-04,2011-09-27
-3a26,2009-09-15,2009-04-28
-6a2c,2019-06-12,2018-06-10
-6a2d,2019-06-12,2018-06-10
-3a27,2009-09-15,2009-04-28
-7a28,2021-08-25,2020-08-16
-2a2d,2005-07-05,2005-06-22
-3a2m,2010-05-26,2009-05-23
-8a2r,2022-08-10,2022-06-06
-4a2x,2011-10-19,2011-09-29
-8a2o,2023-08-30,2022-06-06
-5a2q,2015-07-15,2015-05-21
-2a2a,2006-10-17,2005-06-22
-4a2b,2012-04-25,2011-09-23
-4a2v,2011-10-19,2011-09-29
-7a2m,2021-08-25,2020-08-18
-4a2d,2011-10-12,2011-09-26
-8a27,2022-10-19,2022-06-02
-2a2z,2006-01-17,2005-06-23
-2a29,2005-12-20,2005-06-22
-3a23,2009-07-14,2009-04-27
-5a2m,2016-06-01,2015-05-20
-8a2s,2022-08-10,2022-06-06
-8a2k,2022-10-12,2022-06-03
-6a2b,2019-10-23,2018-06-10
-8a26,2023-06-14,2022-06-02
-3a22,2009-07-14,2009-04-27
-1a26,1998-05-27,1998-01-16
-1a2g,1998-11-25,1998-01-02
-4a2a,2012-04-25,2011-09-23
-7a2h,2020-12-09,2020-08-18
-8a25,2023-06-14,2022-06-02
-4a2u,2012-10-10,2011-09-28
-3a2s,2010-04-07,2009-06-04
-2a20,2005-08-16,2005-06-21
-5a22,2015-08-19,2015-05-06
-2a21,2006-06-20,2005-06-21
-2a2q,2006-07-04,2005-06-22
-6a2l,2019-04-24,2018-06-12
-1a2i,1998-07-08,1998-01-05
-1a2u,1998-04-29,1998-01-11
-4a2f,2012-04-25,2011-09-26
-7a2j,2021-08-25,2020-08-18
-4a21,2011-10-05,2011-09-21
-1a2c,1998-07-01,1997-12-26
-4a28,2012-10-31,2011-09-22
-8a2p,2023-08-30,2022-06-06
-8a29,2023-06-14,2022-06-02
-1a2b,1998-06-17,1997-12-26
-6a2n,2019-04-24,2018-06-12
-5a2r,2015-08-26,2015-05-22
-7a22,2020-12-09,2020-08-15
-1a2p,1998-04-29,1998-01-07
-5a2w,2015-09-09,2015-05-26
-5a2d,2016-02-03,2015-05-17
-5a23,2015-10-07,2015-05-11
-5a2j,2015-06-03,2015-05-20
-8a2w,2023-03-29,2022-06-06
-3a2l,2010-05-26,2009-05-23
-8a2l,2023-02-08,2022-06-03
-4a22,2011-10-12,2011-09-21
-6a2w,2019-02-06,2018-06-13
-7a2b,2020-10-28,2020-08-17
-2a2g,1999-08-13,1998-11-19
-7a2w,2021-08-25,2020-08-18
-8a2z,2022-08-10,2022-06-06
-7a24,2020-10-28,2020-08-16
-6a2u,2019-06-19,2018-06-13
-3a2b,2009-07-14,2009-05-09
-6a22,2018-12-12,2018-06-08
-6a21,2019-06-19,2018-06-08
-3a2i,2010-05-26,2009-05-20
-6a2p,2019-04-24,2018-06-12
-7a2x,2021-08-25,2020-08-18
-2a2o,2005-07-26,2005-06-22
-8a2x,2023-12-20,2022-06-06
-7a25,2020-11-25,2020-08-16
-1a28,1998-07-15,1998-01-19
-4a29,2012-11-07,2011-09-23
-8a2j,2022-10-12,2022-06-03
-2a25,2005-08-09,2005-06-21
-8a22,2022-11-16,2022-06-02
-8a2v,2023-03-29,2022-06-06
-4a2m,2012-05-02,2011-09-27
-1a27,1998-05-27,1998-01-16
-8a2t,2022-08-10,2022-06-06
-4a2l,2012-05-02,2011-09-27
-5a28,2016-03-23,2015-05-15
-1a29,1998-09-16,1998-01-19
-7a2f,2021-08-25,2020-08-17
-8a2a,2022-10-19,2022-06-03
-1a2s,1998-04-29,1998-01-10
-3a28,2009-12-15,2009-05-02
-5a2e,2015-07-22,2015-05-18
-7a23,2020-10-28,2020-08-15
-7a2g,2021-12-01,2020-08-17
-7qmg,2022-08-17,2021-12-20
-7qmi,2022-08-17,2021-12-20
-4qmx,2015-07-01,2014-06-16
-2qmg,2008-03-18,2007-07-16
-7qmd,2022-08-17,2021-12-20
-7qm6,2022-08-17,2021-12-20
-8qm3,2023-11-29,2023-09-21
-3qmn,2011-03-02,2011-02-04
-1qmq,2000-10-06,1999-10-05
-6qmg,2020-02-26,2019-02-07
-7qmw,2022-08-17,2021-12-20
-7qm9,2022-08-17,2021-12-20
-8qmo,2024-01-10,2023-09-24
-6qmh,2020-02-26,2019-02-07
-3qma,2012-02-08,2011-02-03
-7qmn,2022-08-17,2021-12-20
-4qms,2015-07-01,2014-06-16
-2qmd,2008-03-11,2007-07-16
-3qm5,2012-02-08,2011-02-03
-4qm6,2014-10-08,2014-06-15
-4qmn,2015-07-01,2014-06-16
-4qmu,2015-07-01,2014-06-16
-3qm0,2011-02-16,2011-02-03
-2qmp,2008-07-22,2007-07-16
-3qmr,2012-02-08,2011-02-05
-7qme,2022-08-17,2021-12-20
-3qmi,2011-02-23,2011-02-04
-4qmy,2015-07-01,2014-06-16
-2qmq,2007-09-04,2007-07-16
-8qmx,2024-01-17,2023-09-25
-4qm9,2014-11-19,2014-06-15
-3qm1,2011-08-31,2011-02-03
-3qm4,2012-02-15,2011-02-03
-1qm6,1999-09-27,1999-09-21
-1qmh,2000-01-11,1999-09-28
-2qmj,2008-01-08,2007-07-16
-6qm0,2020-02-19,2019-02-01
-7qmp,2022-08-17,2021-12-20
-6qm5,2019-03-06,2019-02-01
-1qmg,2000-03-31,1999-09-28
-4qme,2014-10-01,2014-06-16
-6qm2,2019-05-01,2019-02-01
-6qmu,2019-08-28,2019-02-08
-2qmz,2008-06-24,2007-07-17
-7qm3,2022-08-17,2021-12-20
-3qm8,2012-02-08,2011-02-03
-7qmy,2022-08-17,2021-12-20
-8qmz,2024-02-14,2023-09-25
-7qmo,2022-08-17,2021-12-20
-7qml,2022-08-17,2021-12-20
-2qm3,2007-09-11,2007-07-13
-3qme,2011-02-23,2011-02-04
-8qmn,2023-11-22,2023-09-23
-3qmg,2011-02-23,2011-02-04
-7qm2,2022-11-02,2021-12-20
-2qmm,2007-08-14,2007-07-16
-2qm7,2007-08-28,2007-07-14
-4qm1,2014-07-23,2014-06-14
-3qm3,2011-02-23,2011-02-03
-6qm9,2019-03-06,2019-02-01
-3qm2,2011-02-23,2011-02-03
-2qmc,2008-02-12,2007-07-15
-7qmf,2022-08-17,2021-12-20
-6qmc,2019-04-24,2019-02-07
-7qma,2022-08-17,2021-12-20
-1qmf,2000-05-25,1999-09-28
-6qmi,2020-02-26,2019-02-07
-4qm0,2014-09-17,2014-06-14
-2qmf,2008-03-11,2007-07-16
-6qmq,2019-10-02,2019-02-08
-4qml,2015-07-01,2014-06-16
-4qm8,2014-11-26,2014-06-15
-7qmc,2022-08-17,2021-12-20
-2qmy,2008-06-24,2007-07-17
-6qmt,2019-04-24,2019-02-08
-6qmr,2019-04-24,2019-02-08
-7qmm,2022-08-17,2021-12-20
-7qms,2022-08-17,2021-12-20
-4qmc,2014-07-30,2014-06-16
-7qmt,2022-08-17,2021-12-20
-7qmr,2022-08-17,2021-12-20
-4qmz,2015-07-01,2014-06-16
-6qma,2019-03-06,2019-02-01
-6qme,2019-04-24,2019-02-07
-8qma,2024-03-06,2023-09-21
-3qmk,2011-10-12,2011-02-04
-8qm0,2024-05-22,2023-09-20
-6qmj,2019-04-24,2019-02-07
-7qmz,2022-08-17,2021-12-20
-7qm5,2022-08-17,2021-12-20
-3qmh,2011-02-23,2011-02-04
-3qmb,2011-02-23,2011-02-04
-7qm7,2022-08-17,2021-12-20
-3qm7,2012-02-08,2011-02-03
-6qmb,2019-03-06,2019-02-01
-6qm3,2019-09-11,2019-02-01
-7qmx,2022-08-17,2021-12-20
-4qmv,2015-07-01,2014-06-16
-1qm8,2000-08-16,1999-09-22
-3qmp,2012-01-18,2011-02-04
-6qmf,2020-02-26,2019-02-07
-1qmu,2000-10-13,1999-10-06
-2qmb,2008-07-22,2007-07-15
-6qm7,2019-04-17,2019-02-01
-1qm4,2000-09-21,1999-09-20
-2qm9,2007-10-09,2007-07-14
-4qmq,2015-07-01,2014-06-16
-7qmv,2022-08-17,2021-12-20
-7qmk,2022-08-17,2021-12-20
-7qmb,2022-08-17,2021-12-20
-7qm4,2022-08-17,2021-12-20
-6qmm,2019-03-27,2019-02-07
-2qmk,2008-03-25,2007-07-16
-3qm6,2012-02-08,2011-02-03
-2qmu,2007-11-06,2007-07-17
-4qmm,2015-07-01,2014-06-16
-2qm1,2007-07-31,2007-07-13
-3qm9,2012-02-08,2011-02-03
-4qmt,2015-07-01,2014-06-16
-8qml,2023-11-22,2023-09-22
-3qml,2011-06-29,2011-02-04
-2qmx,2007-08-07,2007-07-17
-1qmp,1999-11-14,1999-10-04
-3qms,2012-02-08,2011-02-05
-7qm8,2022-08-17,2021-12-20
-7qmh,2022-08-17,2021-12-20
-8qmm,2023-11-22,2023-09-23
-8qmy,2024-05-01,2023-09-25
-1qml,2000-10-06,1999-10-02
-7qmu,2022-08-17,2021-12-20
-7qmj,2022-08-17,2021-12-20
-8qmg,2023-11-08,2023-09-22
-6qml,2020-02-26,2019-02-07
-4qmw,2015-07-01,2014-06-16
-8qmk,2023-11-22,2023-09-22
-4qm7,2014-10-08,2014-06-15
-3qmc,2011-02-23,2011-02-04
-7qmq,2022-08-17,2021-12-20
-2qmw,2007-08-07,2007-07-17
-3qmt,2012-02-08,2011-02-05
-3qmo,2011-08-03,2011-02-04
-1qmz,1999-12-14,1999-10-11
-8qmf,2024-02-07,2023-09-22
-8qm1,2024-01-10,2023-09-21
-4qmg,2014-10-08,2014-06-16
-6qmd,2019-04-24,2019-02-07
-2qm6,2008-02-12,2007-07-14
-1qm5,2000-02-03,1999-09-20
-2qme,2007-08-28,2007-07-16
-1qmd,2000-02-06,1999-09-27
-4qma,2014-11-26,2014-06-15
-4qmp,2015-07-01,2014-06-16
-2qmi,2008-07-22,2007-07-16
-4qmo,2015-07-01,2014-06-16
-3qmd,2011-02-23,2011-02-04
-2qm2,2007-07-31,2007-07-13
-1qmo,1999-10-10,1999-10-04
-6qmk,2019-04-24,2019-02-07
-6tym,2020-01-15,2019-08-09
-6ty1,2020-10-21,2020-01-15
-7tyy,2022-03-23,2022-02-14
-3tyz,2012-03-14,2011-09-26
-6tyj,2020-01-22,2019-08-09
-5ty3,2017-09-06,2016-11-18
-5tym,2017-12-06,2016-11-21
-1tyy,2004-10-07,2004-07-08
-7ty7,2023-08-16,2022-02-11
-4tya,2015-05-06,2014-07-08
-6tyb,2019-10-02,2019-08-08
-4tyd,2014-09-10,2014-07-08
-4ty1,2015-02-04,2014-07-07
-7tyg,2022-06-22,2022-02-13
-6tyr,2020-08-12,2019-08-09
-3ty0,2011-11-23,2011-09-23
-5tyl,2017-12-06,2016-11-21
-1ty9,2004-11-23,2004-07-07
-1tyt,1994-07-31,1993-06-10
-4tyb,2015-05-20,2014-07-08
-7tyz,2022-12-07,2022-02-15
-8typ,2023-11-29,2023-08-25
-7typ,2023-05-03,2022-02-14
-4tyo,2014-08-20,2014-07-08
-1tys,1994-06-22,1993-05-07
-7tyi,2022-03-30,2022-02-13
-6ty6,2020-06-03,2020-01-15
-7tyu,2023-05-03,2022-02-14
-3tyc,2012-03-14,2011-09-24
-4ty9,2015-05-06,2014-07-08
-5tyo,2017-12-06,2016-11-21
-5tyq,2017-11-01,2016-11-21
-3tyl,2012-03-14,2011-09-26
-7tya,2023-08-16,2022-02-11
-5tyh,2017-04-12,2016-11-20
-1tyb,1994-01-31,1992-07-06
-4tyx,2014-08-13,2014-07-09
-3tyk,2011-10-12,2011-09-26
-6ty8,2019-11-20,2019-08-08
-6tyf,2020-03-11,2019-08-08
-3tym,2012-03-14,2011-09-26
-5tyn,2017-12-06,2016-11-21
-5tyd,2017-08-30,2016-11-19
-1ty8,2004-11-30,2004-07-07
-4ty8,2015-05-06,2014-07-08
-1tye,2004-10-12,2004-07-07
-5ty1,2017-10-04,2016-11-18
-4tyh,2015-07-22,2014-07-08
-5ty0,2016-11-30,2016-11-17
-8tyj,2024-01-24,2023-08-25
-4tyy,2014-12-31,2014-07-09
-3tye,2012-03-14,2011-09-24
-3tyx,2011-12-28,2011-09-26
-3ty7,2011-10-19,2011-09-23
-5tyv,2017-08-30,2016-11-21
-4tyl,2014-10-29,2014-07-08
-1tyx,1997-07-23,1996-07-26
-7ty6,2023-08-16,2022-02-11
-5tyy,2017-08-30,2016-11-21
-5tyj,2017-12-06,2016-11-20
-2tys,1997-04-01,1997-01-08
-1tyd,1994-01-31,1992-07-06
-8tyl,2024-02-07,2023-08-25
-3tyo,2012-03-14,2011-09-26
-7tyq,2023-05-03,2022-02-14
-3tyv,2012-02-01,2011-09-26
-5tyg,2017-08-30,2016-11-19
-6ty4,2020-08-19,2020-01-15
-7tyo,2022-03-23,2022-02-14
-4tyv,2015-03-18,2014-07-09
-7tyt,2022-08-31,2022-02-14
-7tyx,2022-03-30,2022-02-14
-7tys,2022-08-31,2022-02-14
-4tyt,2014-11-26,2014-07-09
-5tya,2017-08-30,2016-11-18
-1tyl,1994-09-30,1994-06-21
-3tyn,2012-03-14,2011-09-26
-6tyg,2020-03-11,2019-08-08
-3ty5,2012-01-25,2011-09-23
-1tyr,1995-09-15,1995-05-12
-6typ,2020-01-15,2019-08-09
-4tyn,2014-12-31,2014-07-08
-5tyz,2017-08-30,2016-11-21
-6ty2,2021-01-27,2020-01-15
-5ty7,2018-06-13,2016-11-18
-5tys,2017-10-18,2016-11-21
-3ty3,2011-11-09,2011-09-23
-5tyi,2017-11-15,2016-11-20
-4tyw,2014-12-31,2014-07-09
-3tyw,2012-07-11,2011-09-26
-7ty4,2023-08-16,2022-02-11
-4tyi,2014-09-24,2014-07-08
-7ty2,2022-08-31,2022-02-11
-5tye,2017-08-30,2016-11-19
-6tyq,2020-02-12,2019-08-09
-5tyw,2017-08-30,2016-11-21
-7tyf,2022-03-23,2022-02-13
-1tyo,2005-07-08,2004-07-08
-6tyx,2019-11-27,2019-08-09
-3typ,2012-05-09,2011-09-26
-4tyf,2015-07-15,2014-07-08
-7tyw,2022-03-23,2022-02-14
-1typ,1994-01-31,1992-06-29
-3tyq,2012-02-01,2011-09-26
-4ty6,2014-12-03,2014-07-07
-3tyu,2012-03-14,2011-09-26
-6tyk,2021-04-07,2019-08-09
-6tyo,2020-02-12,2019-08-09
-6tye,2020-03-11,2019-08-08
-1tyu,1997-07-23,1996-07-26
-6ty5,2020-08-12,2020-01-15
-3ty9,2012-01-25,2011-09-24
-4tyj,2014-09-24,2014-07-08
-1tyz,2004-11-02,2004-07-08
-4typ,2014-11-26,2014-07-09
-5tyu,2017-08-30,2016-11-21
-3tyi,2012-05-02,2011-09-26
-8tyo,2024-02-07,2023-08-25
-6tyh,2019-11-13,2019-08-08
-1ty2,2004-08-17,2004-07-07
-5typ,2017-12-06,2016-11-21
-3tyg,2011-10-19,2011-09-25
-7tyv,2022-06-01,2022-02-14
-5tyc,2017-08-30,2016-11-19
-7ty3,2022-08-31,2022-02-11
-5tyr,2017-10-18,2016-11-21
-5tyf,2017-08-30,2016-11-19
-4tys,2015-07-22,2014-07-09
-5ty8,2017-08-30,2016-11-18
-1tym,1994-09-30,1994-06-21
-1tyq,2004-11-09,2004-07-08
-6tys,2019-10-09,2019-08-09
-5tyx,2017-08-30,2016-11-21
-6tyn,2020-02-12,2019-08-09
-1tyw,1997-07-23,1996-07-26
-7ty8,2023-08-16,2022-02-11
-7ty0,2022-03-09,2022-02-10
-5ty2,2018-06-13,2016-11-18
-1tya,1994-01-31,1992-07-06
-3tyb,2012-03-14,2011-09-24
-3tyh,2012-09-26,2011-09-26
-3tyd,2012-03-14,2011-09-24
-4ty0,2014-08-13,2014-07-07
-8tyq,2023-12-06,2023-08-25
-8tys,2023-11-08,2023-08-25
-6tyt,2019-11-27,2019-08-09
-3tya,2012-03-14,2011-09-24
-1tyn,1995-01-26,1994-09-19
-8ty1,2023-09-13,2023-08-24
-6ty9,2019-11-20,2019-08-08
-5tyk,2017-12-06,2016-11-21
-5tyb,2017-08-30,2016-11-19
-4tyq,2014-11-26,2014-07-09
-7tyb,2022-05-18,2022-02-11
-5ty9,2017-08-30,2016-11-18
-7tyn,2022-03-30,2022-02-13
-4ty7,2014-12-03,2014-07-08
-6ty0,2021-01-27,2020-01-15
-2x05,2009-12-15,2009-12-05
-7x0t,2023-03-22,2022-02-22
-2x0e,2010-02-02,2009-12-08
-3x0m,2016-04-27,2014-10-17
-3x0o,2016-04-27,2014-10-17
-1x0s,2005-08-30,2005-03-28
-8x0x,2024-06-05,2023-11-06
-7x0n,2022-09-14,2022-02-22
-3x0l,2016-04-27,2014-10-17
-2x07,2010-11-10,2009-12-07
-2x0n,2009-12-22,2009-12-16
-7x0x,2023-01-04,2022-02-22
-6x0i,2020-08-05,2020-05-15
-4x0t,2015-01-14,2014-11-23
-4x0u,2015-01-14,2014-11-23
-3x0q,2016-04-27,2014-10-17
-3x0n,2016-04-27,2014-10-17
-2x09,2010-02-09,2009-12-07
-2x0f,2010-02-02,2009-12-08
-2x0u,2010-01-26,2009-12-17
-4x07,2014-12-17,2014-11-20
-1x0k,2005-08-02,2005-03-23
-7x09,2023-08-30,2022-02-21
-3x03,2015-10-14,2014-10-09
-5x0g,2017-04-12,2017-01-20
-6x0t,2021-05-19,2020-05-17
-7x0s,2023-04-12,2022-02-22
-3x08,2015-10-14,2014-10-09
-4x05,2014-12-17,2014-11-20
-3x00,2015-01-21,2014-10-09
-5x0j,2017-04-12,2017-01-20
-1x0x,2006-04-11,2005-03-31
-7x0j,2022-09-14,2022-02-22
-2x0q,2010-10-27,2009-12-16
-2x03,2010-08-18,2009-12-04
-7x0v,2023-04-12,2022-02-22
-7x01,2022-08-10,2022-02-20
-6x0s,2021-05-19,2020-05-17
-2x0y,2010-01-12,2009-12-18
-5x0r,2017-10-04,2017-01-23
-3x02,2015-10-14,2014-10-09
-2x06,2009-12-15,2009-12-07
-1x0i,2005-08-02,2005-03-23
-2x0h,2010-01-26,2009-12-08
-7x0h,2022-09-14,2022-02-22
-2x0l,2010-03-02,2009-12-15
-6x0c,2021-03-10,2020-05-15
-1x07,2005-03-22,2005-03-15
-4x0w,2015-10-21,2014-11-24
-4x0n,2015-11-25,2014-11-21
-4x0z,2015-04-22,2014-11-24
-7x0f,2022-06-15,2022-02-22
-6x01,2021-02-17,2020-05-15
-2x0v,2010-01-26,2009-12-17
-5x0b,2017-04-12,2017-01-20
-6x0j,2020-08-05,2020-05-15
-7x0l,2022-09-14,2022-02-22
-3x01,2015-10-14,2014-10-09
-4x0m,2014-12-24,2014-11-21
-7x0k,2022-09-14,2022-02-22
-6x0o,2020-06-10,2020-05-17
-3x09,2015-10-14,2014-10-09
-7x00,2023-05-03,2022-02-20
-3x05,2015-10-14,2014-10-09
-5x0i,2018-01-31,2017-01-20
-8x01,2024-06-05,2023-11-02
-3x04,2015-10-14,2014-10-09
-7x05,2022-09-28,2022-02-21
-5x0m,2017-03-08,2017-01-21
-3x0e,2015-07-01,2014-10-14
-1x06,2005-03-22,2005-03-15
-1x0p,2005-06-07,2005-03-27
-4x0f,2015-03-11,2014-11-21
-3x0d,2014-10-29,2014-10-10
-3x0k,2016-04-27,2014-10-16
-5x03,2017-05-24,2017-01-19
-4x0o,2014-12-03,2014-11-21
-2x0j,2009-12-22,2009-12-14
-7x0m,2022-09-14,2022-02-22
-4x06,2014-12-17,2014-11-20
-3x07,2015-10-14,2014-10-09
-6x0p,2021-04-07,2020-05-17
-7x0e,2022-07-06,2022-02-22
-2x0a,2010-12-22,2009-12-07
-3x0s,2016-04-27,2014-10-17
-6x0k,2020-08-05,2020-05-15
-1x0g,2006-06-06,2005-03-22
-4x0l,2014-12-24,2014-11-21
-6x0q,2020-12-09,2020-05-17
-2x0p,2010-10-27,2009-12-16
-1x0a,2006-03-07,2005-03-16
-4x04,2014-12-10,2014-11-20
-4x00,2014-12-03,2014-11-20
-2x0r,2009-12-29,2009-12-17
-3x0y,2015-02-25,2014-10-23
-3x06,2015-10-14,2014-10-09
-6x0h,2020-08-05,2020-05-15
-2x0g,2010-01-26,2009-12-08
-4x0p,2015-03-18,2014-11-21
-4x0c,2014-12-17,2014-11-21
-7x0r,2022-09-14,2022-02-22
-7x0y,2023-01-04,2022-02-22
-1x09,2005-03-22,2005-03-15
-5x06,2018-01-24,2017-01-20
-3x0b,2015-10-14,2014-10-09
-2x0w,2010-01-26,2009-12-17
-5x0f,2017-04-12,2017-01-20
-8x0y,2024-06-05,2023-11-06
-7x08,2022-03-09,2022-02-21
-7x06,2022-09-28,2022-02-21
-3x0r,2016-04-27,2014-10-17
-1x01,2006-05-23,2005-03-11
-3x0p,2016-04-27,2014-10-17
-5x0e,2017-04-12,2017-01-20
-5x02,2018-01-24,2017-01-19
-2x0i,2009-12-22,2009-12-14
-4x0y,2015-04-22,2014-11-24
-1x0t,2005-11-15,2005-03-29
-7x0b,2022-12-28,2022-02-21
-4x0s,2015-05-06,2014-11-23
-4x0q,2015-03-18,2014-11-22
-7x0z,2023-03-22,2022-02-22
-3x0c,2015-10-14,2014-10-09
-5x0k,2017-04-12,2017-01-20
-1x0f,2005-04-05,2005-03-22
-2x08,2010-11-10,2009-12-07
-1x0c,2006-06-13,2005-03-17
-3x0a,2015-10-14,2014-10-09
-3x0v,2015-04-08,2014-10-22
-1x08,2005-03-22,2005-03-15
-1x0n,2005-04-19,2005-03-24
-1x02,2006-03-07,2005-03-11
-2x00,2010-03-02,2009-12-04
-4b4r,2012-08-15,2012-07-31
-7b46,2021-12-08,2020-12-02
-5b43,2016-05-04,2016-03-30
-2b4v,2005-11-22,2005-09-26
-7b4j,2021-09-01,2020-12-02
-5b49,2016-09-28,2016-04-03
-2b4f,2006-09-05,2005-09-23
-4b4d,2013-08-21,2012-07-30
-6b4r,2018-10-03,2017-09-27
-1b47,1999-04-27,1999-01-06
-8b4v,2023-10-04,2022-09-21
-2b4r,2005-10-04,2005-09-26
-6b4v,2018-02-07,2017-09-27
-3b4n,2008-04-29,2007-10-24
-7b4i,2021-09-01,2020-12-02
-6b4y,2018-10-10,2017-09-27
-5b4k,2016-06-29,2016-04-05
-3b4x,2008-11-04,2007-10-24
-7b4r,2021-11-10,2020-12-02
-2b4d,2006-01-17,2005-09-23
-3b4p,2008-12-30,2007-10-24
-4b4u,2012-08-22,2012-08-01
-6b4l,2017-10-04,2017-09-26
-1b4u,1999-08-27,1998-12-29
-4b4m,2012-10-31,2012-07-31
-7b4x,2022-01-12,2020-12-02
-1b4b,1999-06-15,1998-12-18
-7b4d,2021-12-08,2020-12-02
-6b4k,2018-06-20,2017-09-26
-3b42,2008-04-08,2007-10-23
-7b47,2021-12-08,2020-12-02
-6b4j,2018-06-20,2017-09-26
-8b4w,2023-10-04,2022-09-21
-5b4o,2016-04-20,2016-04-07
-5b4b,2016-09-28,2016-04-03
-4b4g,2012-10-31,2012-07-30
-1b4n,1999-05-18,1998-12-24
-7b4f,2021-12-08,2020-12-02
-7b4w,2021-11-24,2020-12-02
-5b48,2016-09-28,2016-04-01
-1b4t,1999-12-23,1998-12-23
-4b46,2013-08-14,2012-07-27
-5b4c,2016-09-28,2016-04-03
-1b4z,1999-01-13,1999-01-04
-6b4d,2018-02-07,2017-09-26
-7b41,2020-12-09,2020-12-02
-6b4z,2018-10-10,2017-09-27
-7b4p,2021-06-02,2020-12-02
-6b4i,2018-06-20,2017-09-26
-8b4q,2023-03-29,2022-09-20
-2b44,2006-01-10,2005-09-22
-2b4b,2006-01-17,2005-09-23
-6b4u,2017-10-04,2017-09-27
-5b4i,2017-03-15,2016-04-04
-4b45,2013-08-14,2012-07-27
-4b4q,2012-08-15,2012-07-31
-1b4k,1999-07-13,1998-12-22
-6b4t,2018-10-03,2017-09-27
-7b44,2020-12-09,2020-12-02
-6b4n,2017-11-22,2017-09-27
-8b4o,2022-12-28,2022-09-20
-1b4e,1999-12-17,1998-12-19
-4b44,2013-09-18,2012-07-27
-8b4j,2023-09-27,2022-09-20
-4b4b,2012-10-31,2012-07-30
-8b4h,2023-05-03,2022-09-20
-2b4x,2006-10-10,2005-09-27
-5b4w,2016-12-28,2016-04-19
-7b4n,2021-12-08,2020-12-02
-8b46,2023-09-27,2022-09-19
-4b40,2013-04-10,2012-07-27
-8b4f,2023-09-27,2022-09-20
-4b4o,2012-08-29,2012-07-31
-7b4a,2021-12-08,2020-12-02
-8b48,2023-06-07,2022-09-20
-5b4u,2016-08-17,2016-04-19
-8b47,2023-01-11,2022-09-20
-3b4w,2007-11-27,2007-10-24
-2b4k,2005-12-27,2005-09-26
-1b4d,1998-12-23,1998-12-18
-7b45,2022-01-12,2020-12-02
-6b4e,2018-06-20,2017-09-26
-7b4c,2021-12-08,2020-12-02
-2b4g,2005-10-11,2005-09-23
-4b47,2013-05-29,2012-07-27
-1b4s,1999-06-15,1998-12-28
-5b4v,2016-08-17,2016-04-19
-6b4w,2017-10-25,2017-09-27
-2b4z,2005-10-11,2005-09-27
-7b4q,2021-12-15,2020-12-02
-8b4n,2023-02-08,2022-09-20
-8b4l,2023-10-04,2022-09-20
-2b4m,2006-03-21,2005-09-26
-7b40,2020-12-09,2020-12-01
-5b4h,2017-03-15,2016-04-04
-1b4q,1999-12-23,1998-12-25
-6b41,2018-01-24,2017-09-25
-6b4x,2018-10-10,2017-09-27
-6b4h,2018-06-20,2017-09-26
-2b4y,2006-02-28,2005-09-27
-6b4m,2018-01-17,2017-09-27
-5b4t,2016-08-17,2016-04-19
-1b4p,2003-07-08,1998-12-26
-4b4x,2013-08-21,2012-08-01
-4b4a,2012-12-05,2012-07-30
-8b4a,2022-12-14,2022-09-20
-6b42,2017-10-18,2017-09-25
-7b4o,2021-06-02,2020-12-02
-8b45,2023-09-27,2022-09-19
-7b4v,2021-11-24,2020-12-02
-1b4v,1999-01-06,1998-12-30
-8b4g,2024-04-03,2022-09-20
-1b41,2001-01-17,1999-01-05
-1b46,1999-01-13,1999-01-05
-1b4h,1998-11-18,1998-11-11
-8b4i,2023-08-09,2022-09-20
-7b4b,2021-12-08,2020-12-02
-1b42,1999-07-22,1999-01-05
-5b46,2016-09-28,2016-04-01
-2b4q,2006-05-02,2005-09-26
-8b49,2023-09-20,2022-09-20
-3b4u,2007-12-04,2007-10-24
-5b42,2016-07-13,2016-03-30
-3b4r,2008-01-15,2007-10-24
-5b4l,2016-06-29,2016-04-05
-1b48,1999-09-29,1999-01-06
-3b4v,2008-09-02,2007-10-24
-3b4y,2008-04-22,2007-10-25
-4b4y,2013-01-09,2012-08-01
-1b4x,2000-10-27,1998-12-30
-4b48,2013-05-29,2012-07-27
-4b4v,2012-08-22,2012-08-01
-8b4t,2023-10-04,2022-09-21
-4b4w,2012-08-22,2012-08-01
-5b4x,2017-04-26,2016-04-20
-3b40,2007-11-06,2007-10-23
-4b4z,2013-08-21,2012-08-02
-5b4j,2017-03-15,2016-04-04
-5b4y,2017-04-26,2016-04-20
-7b4e,2021-12-08,2020-12-02
-4b4f,2012-12-19,2012-07-30
-7b4s,2021-11-10,2020-12-02
-5b41,2016-12-07,2016-03-23
-2b4c,2005-11-15,2005-09-23
-1b4l,1999-12-23,1998-12-22
-4b43,2013-09-18,2012-07-27
-8b4m,2023-10-04,2022-09-20
-7b42,2020-12-09,2020-12-02
-6b4q,2018-10-03,2017-09-27
-7b4u,2021-11-24,2020-12-02
-7b4h,2021-12-08,2020-12-02
-5b4a,2016-09-28,2016-04-03
-8b43,2023-04-26,2022-09-19
-5b47,2016-09-28,2016-04-01
-5b4f,2017-05-10,2016-04-03
-3b4f,2008-01-22,2007-10-24
-7b4l,2022-01-12,2020-12-02
-7b4y,2022-02-09,2020-12-02
-6b40,2019-03-20,2017-09-25
-6b4o,2017-10-11,2017-09-27
-7b49,2021-12-08,2020-12-02
-7b4g,2021-12-08,2020-12-02
-5b4e,2017-05-03,2016-04-03
-2b46,2006-09-19,2005-09-22
-2b4t,2005-10-04,2005-09-26
-1b40,1999-01-13,1998-11-23
-5b4z,2017-03-01,2016-04-20
-4b42,2012-10-31,2012-07-27
-3b47,2008-04-08,2007-10-23
-7b43,2020-12-09,2020-12-02
-8b4b,2023-08-09,2022-09-20
-8b4x,2023-10-04,2022-09-21
-7b48,2021-12-08,2020-12-02
-2i79,2006-10-10,2006-08-30
-1i73,2001-03-21,2001-03-07
-2i7h,2006-10-03,2006-08-30
-8i7o,2023-10-11,2023-02-01
-4i7p,2013-03-27,2012-11-30
-5i7a,2016-08-17,2016-02-17
-8i7w,2024-02-07,2023-02-02
-4i7d,2013-08-14,2012-11-30
-6i71,2019-11-27,2018-11-15
-2i74,2006-10-24,2006-08-30
-4i76,2013-01-02,2012-11-30
-6i73,2019-11-27,2018-11-15
-6i7a,2019-05-08,2018-11-16
-6i72,2019-11-27,2018-11-15
-6i7z,2019-07-31,2018-11-19
-6i7f,2019-11-20,2018-11-16
-4i73,2013-08-07,2012-11-30
-1i7o,2001-03-28,2001-03-10
-8i70,2023-06-14,2023-01-30
-3i7b,2010-02-09,2009-07-08
-2i7p,2006-12-26,2006-08-31
-4i78,2013-01-16,2012-11-30
-2i7a,2006-09-12,2006-08-30
-1i7u,2001-10-24,2001-03-10
-4i72,2013-08-07,2012-11-30
-3i78,2010-06-02,2009-07-08
-6i7s,2019-08-21,2018-11-17
-5i7o,2016-08-17,2016-02-18
-1i7q,2001-05-16,2001-03-10
-6i75,2019-01-23,2018-11-15
-4i7n,2013-03-27,2012-11-30
-4i75,2013-08-07,2012-11-30
-3i7i,2009-09-01,2009-07-08
-4i7h,2013-05-08,2012-11-30
-2i76,2006-10-03,2006-08-30
-5i7x,2016-10-12,2016-02-18
-4i7w,2013-12-04,2012-12-01
-1i75,2001-04-11,2001-03-08
-2i7t,2007-01-30,2006-08-31
-5i74,2016-04-13,2016-02-16
-1i7w,2001-05-09,2001-03-10
-5i7z,2016-03-16,2016-02-18
-5i79,2016-12-21,2016-02-17
-3i7v,2009-07-21,2009-07-09
-5i7y,2016-10-12,2016-02-18
-6i78,2019-01-23,2018-11-15
-5i72,2016-03-09,2016-02-16
-1i7b,2001-08-22,2001-03-08
-8i77,2023-03-01,2023-01-31
-3i7r,2010-04-14,2009-07-08
-8i7x,2023-07-19,2023-02-02
-6i79,2019-07-10,2018-11-16
-8i7r,2023-10-11,2023-02-02
-8i7h,2024-02-07,2023-01-31
-6i74,2019-01-23,2018-11-15
-2i71,2006-10-03,2006-08-30
-5i77,2016-12-21,2016-02-17
-2i78,2007-10-09,2006-08-30
-3i7s,2010-04-14,2009-07-08
-5i78,2016-12-21,2016-02-17
-6i7h,2019-09-25,2018-11-16
-1i72,2001-08-22,2001-03-07
-5i7h,2016-08-17,2016-02-17
-6i7l,2019-09-25,2018-11-16
-4i71,2013-08-07,2012-11-30
-1i7c,2001-08-22,2001-03-08
-4i70,2013-08-07,2012-11-30
-1i7s,2001-05-16,2001-03-10
-5i7c,2017-03-08,2016-02-17
-6i7n,2019-05-15,2018-11-16
-6i7o,2019-01-16,2018-11-16
-3i73,2010-01-12,2009-07-08
-2i7c,2006-09-12,2006-08-30
-1i7t,2001-10-24,2001-03-10
-2i7v,2007-01-30,2006-08-31
-6i7e,2019-08-07,2018-11-16
-2i72,2007-09-11,2006-08-30
-6i7i,2019-09-25,2018-11-16
-4i7r,2013-03-27,2012-11-30
-1i74,2001-06-06,2001-03-07
-3i7g,2009-09-01,2009-07-08
-3i7e,2009-09-29,2009-07-08
-1i7m,2001-08-22,2001-03-09
-5i7f,2017-02-22,2016-02-17
-2i7n,2006-12-26,2006-08-31
-5i7v,2017-02-22,2016-02-18
-3i7z,2010-03-16,2009-07-09
-1i7a,2001-08-22,2001-03-08
-5i75,2016-04-13,2016-02-16
-1i7p,2001-12-12,2001-03-10
-1i7z,2001-08-08,2001-03-12
-1i7l,2003-07-01,2001-03-09
-8i7j,2024-02-07,2023-01-31
-6i7g,2019-09-25,2018-11-16
-3i7q,2010-04-14,2009-07-08
-1i7d,2001-06-29,2001-03-08
-3i76,2009-07-21,2009-07-08
-6i7v,2018-12-05,2018-11-19
-8i71,2023-03-22,2023-01-30
-5i7r,2016-08-17,2016-02-18
-3i77,2010-06-02,2009-07-08
-3i74,2010-01-19,2009-07-08
-1i7y,2001-03-28,2001-03-11
-1i7e,2001-06-27,2001-03-08
-8i7p,2023-09-20,2023-02-01
-1i7g,2002-03-09,2001-03-09
-6i7w,2019-01-23,2018-11-19
-5i71,2016-04-13,2016-02-16
-4i7s,2013-03-27,2012-11-30
-1i76,2001-03-21,2001-03-08
-4i7q,2013-03-27,2012-11-30
-4i7t,2013-03-27,2012-11-30
-3i7c,2010-02-09,2009-07-08
-4i7b,2013-08-14,2012-11-30
-4i7f,2013-02-20,2012-11-30
-4i7o,2013-03-27,2012-11-30
-4i7z,2013-04-17,2012-12-01
-6i7k,2019-09-25,2018-11-16
-5i7s,2017-02-22,2016-02-18
-1i7r,2001-10-24,2001-03-10
-6i7x,2019-11-27,2018-11-19
-6i76,2019-01-23,2018-11-15
-1i7i,2002-03-09,2001-03-09
-5i7i,2017-01-18,2016-02-17
-5i7u,2016-06-08,2016-02-18
-2i7o,2007-08-14,2006-08-31
-8i7q,2023-12-27,2023-02-01
-1i77,2001-08-29,2001-03-08
-8i7v,2024-02-07,2023-02-02
-8i7l,2023-02-15,2023-02-01
-2i7s,2006-12-05,2006-08-31
-6i77,2019-01-23,2018-11-15
-5i73,2016-04-13,2016-02-16
-5i70,2016-03-09,2016-02-16
-6i7y,2019-11-27,2018-11-19
-6i7p,2019-04-24,2018-11-16
-4i7m,2013-03-27,2012-11-30
-2i7d,2007-10-30,2006-08-30
-6i7c,2019-11-20,2018-11-16
-1i79,2001-08-22,2001-03-08
-4i7y,2013-10-16,2012-12-01
-4i7c,2013-08-14,2012-11-30
-4i74,2013-08-07,2012-11-30
-8i7u,2024-05-01,2023-02-02
-2i7b,2007-05-22,2006-08-30
-1q6s,2003-09-30,2003-08-13
-8q6j,2023-09-20,2023-08-11
-3q6y,2012-01-04,2011-01-04
-7q6n,2022-08-03,2021-11-08
-3q6v,2011-07-13,2011-01-03
-1q6r,2003-10-28,2003-08-13
-2q6a,2007-10-02,2007-06-04
-8q6h,2023-12-13,2023-08-11
-6q6f,2019-10-16,2018-12-10
-8q66,2024-03-06,2023-08-11
-3q6z,2011-02-09,2011-01-04
-3q6k,2011-07-27,2011-01-02
-5q64,2018-08-08,2017-05-25
-5q6t,2018-08-08,2017-05-25
-7q6f,2022-09-21,2021-11-07
-4q6h,2014-05-14,2014-04-22
-5q6l,2018-08-08,2017-05-25
-5q6a,2018-08-08,2017-05-25
-5q69,2018-08-08,2017-05-25
-6q6p,2020-01-15,2018-12-11
-6q67,2019-11-13,2018-12-10
-4q6a,2014-12-31,2014-04-21
-2q6j,2007-06-26,2007-06-05
-3q6j,2011-02-16,2011-01-01
-4q6x,2015-03-18,2014-04-23
-4q67,2014-12-31,2014-04-21
-2q6n,2007-11-06,2007-06-05
-1q65,2004-04-13,2003-08-12
-4q6d,2014-11-26,2014-04-22
-2q6f,2008-02-12,2007-06-05
-5q6d,2018-08-08,2017-05-25
-2q6c,2007-07-17,2007-06-04
-7q6w,2022-01-19,2021-11-09
-6q6b,2019-07-10,2018-12-10
-6q6l,2019-03-27,2018-12-11
-1q6n,2003-09-30,2003-08-13
-5q6h,2018-08-08,2017-05-25
-4q6t,2014-05-07,2014-04-23
-7q62,2022-04-20,2021-11-05
-7q6d,2022-09-21,2021-11-06
-4q6m,2014-11-05,2014-04-23
-5q6f,2018-08-08,2017-05-25
-2q6l,2007-12-11,2007-06-05
-3q6e,2011-04-20,2010-12-31
-4q6n,2014-11-05,2014-04-23
-4q60,2014-05-07,2014-04-18
-8q61,2023-08-16,2023-08-10
-5q6s,2018-08-08,2017-05-25
-1q6c,2004-02-24,2003-08-13
-5q68,2018-08-08,2017-05-25
-3q6w,2011-01-19,2011-01-03
-5q62,2018-08-08,2017-05-25
-3q60,2011-02-23,2010-12-30
-3q6d,2011-02-02,2010-12-31
-8q6m,2023-12-13,2023-08-14
-2q6m,2008-02-12,2007-06-05
-1q6f,2004-02-24,2003-08-13
-7q6u,2022-01-19,2021-11-09
-1q61,2003-09-30,2003-08-12
-1q6d,2004-02-24,2003-08-13
-4q6q,2014-11-05,2014-04-23
-7q6h,2022-02-02,2021-11-07
-8q6f,2023-12-13,2023-08-11
-5q6o,2018-08-08,2017-05-25
-2q68,2007-10-02,2007-06-04
-5q6u,2018-08-08,2017-05-25
-2q6u,2007-07-31,2007-06-05
-4q6f,2014-05-21,2014-04-22
-1q6m,2003-09-30,2003-08-13
-4q6p,2014-11-05,2014-04-23
-5q6x,2018-08-08,2017-05-25
-5q6e,2018-08-08,2017-05-25
-1q6e,2004-02-24,2003-08-13
-5q60,2018-08-08,2017-05-25
-2q6e,2007-06-19,2007-06-05
-4q6g,2014-11-12,2014-04-22
-5q6r,2018-08-08,2017-05-25
-2q6o,2007-12-11,2007-06-05
-1q6u,2004-01-13,2003-08-14
-1q6o,2003-10-28,2003-08-13
-6q6m,2019-11-27,2018-12-11
-4q69,2014-06-25,2014-04-21
-4q6s,2015-04-29,2014-04-23
-5q6q,2018-08-08,2017-05-25
-2q6v,2008-06-10,2007-06-05
-6q60,2019-04-17,2018-12-10
-8q6p,2023-10-18,2023-08-14
-7q6t,2022-01-19,2021-11-09
-2q66,2007-08-28,2007-06-04
-7q6s,2022-03-16,2021-11-09
-2q67,2007-10-02,2007-06-04
-1q68,2003-11-25,2003-08-12
-1q6k,2004-03-16,2003-08-13
-6q6j,2019-06-12,2018-12-11
-6q6i,2019-09-25,2018-12-11
-6q68,2019-11-13,2018-12-10
-7q6r,2022-01-26,2021-11-09
-5q65,2018-08-08,2017-05-25
-6q6o,2019-11-27,2018-12-11
-2q69,2007-10-02,2007-06-04
-4q6r,2014-05-21,2014-04-23
-8q6u,2024-03-06,2023-08-14
-1q66,2004-04-13,2003-08-12
-4q6y,2014-07-23,2014-04-23
-4q66,2014-09-17,2014-04-21
-6q62,2020-01-15,2018-12-10
-5q6i,2018-08-08,2017-05-25
-5q6p,2018-08-08,2017-05-25
-2q6k,2007-12-11,2007-06-05
-4q6w,2014-07-02,2014-04-23
-1q69,2003-11-25,2003-08-12
-4q6e,2014-11-26,2014-04-22
-8q6o,2023-10-18,2023-08-14
-5q6k,2018-08-08,2017-05-25
-6q6q,2019-05-01,2018-12-11
-8q68,2023-10-04,2023-08-11
-4q68,2014-05-07,2014-04-21
-8q6g,2023-12-13,2023-08-11
-7q6v,2022-01-19,2021-11-09
-2q6r,2007-10-23,2007-06-01
-2q6h,2007-08-21,2007-06-05
-2q61,2007-10-23,2007-06-04
-3q67,2011-01-12,2010-12-30
-7q6e,2021-12-15,2021-11-07
-7q6z,2022-01-26,2021-11-09
-1q6g,2004-02-24,2003-08-13
-4q6o,2014-11-05,2014-04-23
-1q6z,2004-11-23,2003-08-14
-5q61,2018-08-08,2017-05-25
-4q6k,2014-10-01,2014-04-22
-1q6x,2004-06-01,2003-08-14
-8q63,2023-08-30,2023-08-10
-4q6b,2014-07-02,2014-04-22
-3q6i,2012-01-11,2011-01-01
-5q6z,2018-08-08,2017-05-25
-7q6x,2022-01-26,2021-11-09
-1q6q,2003-10-28,2003-08-13
-8q6k,2023-12-06,2023-08-11
-1q6j,2003-09-30,2003-08-13
-2q6b,2007-07-17,2007-06-04
-6q6x,2019-03-20,2018-12-12
-5q66,2018-08-08,2017-05-25
-7q6q,2022-03-16,2021-11-09
-6q6r,2019-10-16,2018-12-11
-2q6s,2007-10-23,2007-06-01
-6q6n,2019-03-27,2018-12-11
-7q61,2022-04-20,2021-11-05
-5q6w,2018-08-08,2017-05-25
-5q6g,2018-08-08,2017-05-25
-1q6l,2003-10-28,2003-08-13
-1q63,2004-04-13,2003-08-12
-7q6i,2022-09-21,2021-11-07
-5q6j,2018-08-08,2017-05-25
-2q63,2008-02-26,2007-06-04
-5q63,2018-08-08,2017-05-25
-1q6t,2003-09-30,2003-08-13
-6q63,2019-05-08,2018-12-10
-5q6b,2018-08-08,2017-05-25
-2q64,2008-02-26,2007-06-04
-1q6p,2003-09-30,2003-08-13
-1q6y,2003-09-30,2003-08-14
-2q6q,2008-05-13,2007-06-05
-5q6c,2018-08-08,2017-05-25
-8q6s,2023-12-13,2023-08-14
-2q6i,2007-12-11,2007-06-05
-5q6y,2018-08-08,2017-05-25
-7q6g,2022-09-21,2021-11-07
-5q6m,2018-08-08,2017-05-25
-6q6w,2019-03-20,2018-12-12
-6q6k,2019-03-27,2018-12-11
-2q6g,2008-02-12,2007-06-05
-6q6y,2018-12-26,2018-12-12
-5q67,2018-08-08,2017-05-25
-1q6i,2004-01-13,2003-08-13
-4q63,2014-05-07,2014-04-21
-5q6n,2018-08-08,2017-05-25
-3q65,2011-01-19,2010-12-30
-5q6v,2018-08-08,2017-05-25
-5l9c,2017-06-28,2016-06-10
-3l9i,2010-12-08,2010-01-05
-6l9t,2020-09-16,2019-11-11
-6l9s,2020-01-29,2019-11-10
-5l9d,2016-08-03,2016-06-10
-3l9x,2010-11-17,2010-01-05
-7l9k,2021-07-07,2021-01-04
-4l9y,2013-12-04,2013-06-18
-7l9m,2022-01-12,2021-01-04
-1l9r,2003-02-04,2002-03-26
-5l9h,2018-03-14,2016-06-10
-7l9p,2021-03-03,2021-01-04
-3l9a,2010-04-07,2010-01-04
-7l99,2021-06-30,2021-01-03
-1l9o,2003-02-04,2002-03-26
-3l9g,2010-06-02,2010-01-05
-6l9l,2020-11-18,2019-11-10
-4l9s,2013-11-27,2013-06-18
-1l9s,2003-02-04,2002-03-26
-7l97,2021-08-25,2021-01-02
-3l95,2010-03-09,2010-01-04
-1l9c,2002-08-30,2002-03-22
-1l9d,2002-08-30,2002-03-22
-5l9e,2017-06-21,2016-06-10
-1l9n,2002-05-29,2002-03-26
-5l9z,2017-05-31,2016-06-13
-1l9y,2003-07-01,2002-03-27
-6l9c,2020-04-29,2019-11-08
-4l9i,2014-01-22,2013-06-18
-4l92,2014-04-30,2013-06-18
-3l9f,2011-01-05,2010-01-05
-6l9x,2020-11-11,2019-11-11
-3l9w,2010-11-17,2010-01-05
-5l9y,2017-05-31,2016-06-13
-6l9i,2021-01-20,2019-11-10
-4l98,2014-06-25,2013-06-18
-5l9l,2016-09-21,2016-06-10
-1l9j,2002-06-12,2002-03-24
-4l9o,2013-10-02,2013-06-18
-7l9g,2021-11-17,2021-01-04
-2l9z,2011-04-27,2011-02-26
-4l91,2014-06-18,2013-06-18
-5l90,2016-10-05,2016-06-09
-5l9b,2016-08-31,2016-06-10
-4l9d,2013-07-10,2013-06-18
-5l9q,2017-05-03,2016-06-10
-5l9r,2016-08-31,2016-06-10
-4l99,2014-04-30,2013-06-18
-5l9g,2016-09-21,2016-06-10
-1l9a,2002-06-28,2002-03-22
-5l96,2016-10-26,2016-06-09
-4l93,2014-06-18,2013-06-18
-4l9b,2014-04-30,2013-06-18
-4l9k,2013-07-24,2013-06-18
-7l9h,2021-04-28,2021-01-04
-1l9u,2002-05-22,2002-03-26
-7l9x,2021-04-14,2021-01-05
-3l9n,2011-01-19,2010-01-05
-3l9h,2010-03-02,2010-01-05
-1l9b,2002-06-12,2002-03-22
-3l91,2011-01-19,2010-01-04
-1l9q,2003-02-04,2002-03-26
-3l9e,2010-03-31,2010-01-05
-5l9k,2017-05-03,2016-06-10
-5l9o,2016-09-21,2016-06-10
-4l9w,2013-11-27,2013-06-18
-1l9h,2002-05-15,2002-03-23
-4l94,2014-06-18,2013-06-18
-7l9j,2021-07-07,2021-01-04
-6l9m,2020-11-18,2019-11-10
-5l98,2016-10-26,2016-06-09
-7l9a,2021-06-30,2021-01-03
-2l98,2011-03-30,2011-02-02
-5l97,2016-10-26,2016-06-09
-5l9i,2016-09-21,2016-06-10
-6l9k,2020-11-18,2019-11-10
-3l92,2010-01-19,2010-01-04
-7l9i,2021-04-28,2021-01-04
-3l9j,2010-02-23,2010-01-05
-7l92,2022-05-04,2021-01-01
-6l9z,2021-02-17,2019-11-11
-7l90,2021-08-04,2021-01-01
-7l9y,2021-04-21,2021-01-05
-1l9w,2003-03-26,2002-03-26
-7l9t,2021-01-20,2021-01-05
-7l91,2022-02-09,2021-01-01
-4l9p,2014-01-01,2013-06-18
-1l9t,2003-02-04,2002-03-26
-5l9n,2017-04-05,2016-06-10
-3l9y,2010-03-23,2010-01-06
-5l99,2016-10-26,2016-06-09
-4l97,2014-04-30,2013-06-18
-6l96,2020-01-15,2019-11-08
-5l94,2016-10-05,2016-06-09
-6l94,2020-11-11,2019-11-08
-4l9m,2013-08-21,2013-06-18
-5l9v,2016-08-31,2016-06-11
-7l9e,2021-12-29,2021-01-03
-5l9w,2017-01-18,2016-06-11
-6l9n,2020-11-18,2019-11-10
-7l9f,2021-04-28,2021-01-04
-1l9e,2002-08-30,2002-03-22
-1l9p,2003-02-04,2002-03-26
-7l9l,2021-07-07,2021-01-04
-3l9m,2011-01-19,2010-01-05
-5l91,2016-10-05,2016-06-09
-3l9b,2011-01-19,2010-01-04
-1l9z,2002-05-31,2002-03-27
-4l90,2014-06-18,2013-06-18
-3l9l,2011-01-19,2010-01-05
-5l92,2016-10-05,2016-06-09
-4l96,2014-06-25,2013-06-18
-5l9x,2016-06-22,2016-06-12
-4l9q,2013-07-24,2013-06-18
-5l9f,2017-04-19,2016-06-10
-3l9r,2010-06-16,2010-01-05
-1l9m,2002-05-29,2002-03-26
-6l99,2020-11-11,2019-11-08
-1l9k,2003-03-25,2002-03-25
-5l95,2016-09-21,2016-06-09
-4l9z,2013-12-04,2013-06-18
-5r51,2020-07-01,2020-02-28
-5r5b,2020-07-01,2020-02-28
-3r54,2012-03-21,2011-03-18
-1r58,2004-10-12,2003-10-09
-3r51,2012-03-28,2011-03-18
-6r5d,2019-09-11,2019-03-24
-1r51,2004-03-02,2003-10-09
-3r5x,2011-04-06,2011-03-20
-4r5j,2014-09-10,2014-08-21
-8r5h,2024-02-21,2023-11-16
-1r5x,2003-11-25,2003-10-13
-7r50,2022-04-27,2022-02-09
-3r59,2012-03-21,2011-03-18
-5r5f,2020-07-01,2020-02-28
-1r54,2004-10-12,2003-10-09
-7r5q,2022-09-07,2022-02-11
-3r5j,2011-07-27,2011-03-18
-4r5v,2014-10-29,2014-08-22
-1r5u,2004-02-17,2003-10-13
-5r5c,2020-07-01,2020-02-28
-4r5s,2014-11-12,2014-08-22
-3r56,2012-03-21,2011-03-18
-2r5w,2008-03-04,2007-09-04
-5r55,2020-07-01,2020-02-28
-5r5s,2020-07-01,2020-02-28
-8r5o,2024-03-13,2023-11-17
-5r56,2020-07-01,2020-02-28
-6r5a,2019-06-12,2019-03-24
-6r5t,2020-04-15,2019-03-25
-6r5k,2019-05-29,2019-03-25
-1r5l,2003-11-25,2003-10-10
-2r5o,2007-12-25,2007-09-04
-3r5c,2012-01-25,2011-03-18
-6r5n,2020-04-15,2019-03-25
-7r55,2022-09-14,2022-02-10
-6r5f,2019-05-01,2019-03-25
-5r5m,2020-07-01,2020-02-28
-5r5g,2020-07-01,2020-02-28
-6r51,2019-06-12,2019-03-24
-2r5t,2008-09-09,2007-09-04
-6r5b,2019-06-12,2019-03-24
-5r5z,2020-10-28,2020-02-28
-5r5e,2020-07-01,2020-02-28
-4r5h,2014-12-10,2014-08-21
-3r5u,2012-03-28,2011-03-19
-5r52,2020-07-01,2020-02-28
-4r5p,2015-03-11,2014-08-21
-6r54,2019-06-12,2019-03-24
-7r5x,2023-02-08,2022-02-11
-5r5k,2020-07-01,2020-02-28
-4r5k,2014-09-10,2014-08-21
-4r57,2015-03-25,2014-08-20
-5r5t,2020-10-28,2020-02-28
-6r5v,2020-04-15,2019-03-25
-6r5l,2020-06-17,2019-03-25
-3r58,2012-03-28,2011-03-18
-4r5b,2014-10-15,2014-08-20
-1r5n,2004-05-25,2003-10-10
-6r5c,2019-06-12,2019-03-24
-3r5z,2012-01-18,2011-03-20
-4r5x,2014-10-29,2014-08-22
-2r5p,2007-11-20,2007-09-04
-3r5t,2012-02-08,2011-03-19
-4r5y,2016-02-24,2014-08-22
-3r5b,2012-01-25,2011-03-18
-5r5h,2020-07-01,2020-02-28
-1r5v,2004-02-03,2003-10-13
-5r5n,2020-07-01,2020-02-28
-4r5f,2014-12-17,2014-08-21
-2r5d,2007-10-02,2007-09-03
-5r5i,2020-07-01,2020-02-28
-7r5c,2022-07-13,2022-02-10
-8r5t,2024-04-10,2023-11-17
-1r5h,2004-10-12,2003-10-10
-3r5i,2011-04-06,2011-03-18
-3r5r,2012-01-18,2011-03-19
-7r5f,2022-03-02,2022-02-10
-4r50,2015-07-01,2014-08-20
-1r5g,2004-10-12,2003-10-10
-7r5i,2023-08-23,2022-02-10
-6r5r,2020-04-15,2019-03-25
-7r5p,2022-05-18,2022-02-11
-6r57,2019-06-12,2019-03-24
-1r50,2004-10-19,2003-10-09
-5r5l,2020-07-01,2020-02-28
-7r59,2023-01-25,2022-02-10
-6r5s,2019-07-31,2019-03-25
-8r56,2024-05-08,2023-11-16
-2r59,2008-08-12,2007-09-03
-6r5q,2019-07-10,2019-03-25
-3r57,2012-03-21,2011-03-18
-1r55,2004-10-12,2003-10-09
-6r5e,2019-09-11,2019-03-24
-3r55,2011-08-03,2011-03-18
-1r5y,2004-04-13,2003-10-13
-4r54,2014-12-10,2014-08-20
-5r59,2020-07-01,2020-02-28
-7r5z,2022-05-04,2022-02-12
-8r5u,2024-04-10,2023-11-17
-7r5g,2022-05-18,2022-02-10
-1r5c,2004-04-13,2003-10-10
-7r5d,2023-01-25,2022-02-10
-6r5h,2021-04-07,2019-03-25
-3r5o,2011-08-17,2011-03-19
-5r5d,2020-07-01,2020-02-28
-8r5b,2024-01-17,2023-11-16
-6r5p,2020-04-15,2019-03-25
-7r5t,2022-10-19,2022-02-11
-5r50,2020-07-01,2020-02-28
-4r5e,2015-07-15,2014-08-21
-8r54,2024-05-08,2023-11-15
-5r5w,2020-10-28,2020-02-28
-3r5y,2012-01-18,2011-03-20
-3r5n,2012-02-08,2011-03-18
-5r5r,2020-07-01,2020-02-28
-8r51,2024-05-08,2023-11-15
-7r5b,2023-02-08,2022-02-10
-7r51,2022-05-04,2022-02-09
-2r5a,2007-10-30,2007-09-03
-8r5q,2024-01-17,2023-11-17
-5r5q,2020-07-01,2020-02-28
-3r5f,2011-05-25,2011-03-18
-4r5a,2014-10-15,2014-08-20
-4r5n,2014-12-03,2014-08-21
-4r5q,2014-09-17,2014-08-21
-2r5n,2007-11-06,2007-09-04
-4r55,2015-08-05,2014-08-20
-4r5l,2014-09-10,2014-08-21
-3r5v,2012-03-28,2011-03-19
-4r5t,2014-10-29,2014-08-22
-8r5k,2024-05-08,2023-11-16
-6r58,2019-06-12,2019-03-24
-4r5g,2014-09-10,2014-08-21
-5r5u,2020-10-28,2020-02-28
-5r5x,2020-10-28,2020-02-28
-3r5m,2012-02-08,2011-03-18
-7r54,2022-03-23,2022-02-10
-6r5o,2020-04-15,2019-03-25
-5r5p,2020-07-01,2020-02-28
-4r5o,2014-09-10,2014-08-21
-3r52,2012-03-28,2011-03-18
-4r5w,2015-09-02,2014-08-22
-7r56,2022-12-21,2022-02-10
-5r58,2020-07-01,2020-02-28
-5r5v,2020-10-28,2020-02-28
-1r5w,2004-03-02,2003-10-13
-6r59,2019-06-12,2019-03-24
-7r53,2022-03-23,2022-02-10
-8r5r,2024-01-17,2023-11-17
-2r5l,2007-09-18,2007-09-04
-6r5y,2019-11-13,2019-03-25
-4r5i,2014-09-10,2014-08-21
-1r5t,2004-05-25,2003-10-13
-5r5o,2020-07-01,2020-02-28
-8r57,2023-12-27,2023-11-16
-6r5i,2020-04-15,2019-03-25
-2r5q,2007-11-20,2007-09-04
-7r52,2022-03-23,2022-02-10
-5r54,2020-07-01,2020-02-28
-3r5h,2012-03-21,2011-03-18
-5r5y,2020-10-28,2020-02-28
-2r5e,2008-03-18,2007-09-03
-2r50,2007-09-18,2007-09-02
-4r5z,2015-08-26,2014-08-22
-6r5u,2020-04-15,2019-03-25
-1r5a,2003-10-28,2003-10-09
-4r59,2014-10-15,2014-08-20
-5r5a,2020-07-01,2020-02-28
-7r5e,2022-05-18,2022-02-10
-2r5b,2007-10-02,2007-09-03
-5r5j,2020-07-01,2020-02-28
-2r5c,2008-03-18,2007-09-03
-4r56,2015-08-05,2014-08-20
-4r52,2016-03-02,2014-08-20
-1r5k,2004-11-23,2003-10-10
-5r57,2020-07-01,2020-02-28
-3r5w,2012-01-18,2011-03-20
-6r53,2019-06-12,2019-03-24
-8r5v,2023-12-06,2023-11-17
-8r5c,2024-01-17,2023-11-16
-7r5l,2022-03-02,2022-02-10
-1r5o,2004-05-25,2003-10-11
-8r50,2024-05-08,2023-11-15
-3r5a,2012-01-25,2011-03-18
-6r56,2019-06-12,2019-03-24
-7r5o,2022-06-22,2022-02-11
-6r55,2019-06-12,2019-03-24
-6r5w,2019-10-30,2019-03-25
-2r5m,2007-10-30,2007-09-04
-2r58,2007-10-30,2007-09-03
-5r53,2020-07-01,2020-02-28
-6r50,2019-06-12,2019-03-24
-4r5m,2014-12-10,2014-08-21
-7r5w,2022-03-16,2022-02-11
-6r52,2019-06-12,2019-03-24
-7r5n,2023-08-23,2022-02-11
-4r51,2014-12-10,2014-08-20
-2r5v,2008-03-18,2007-09-04
-1emy,1995-04-20,1995-02-22
-3emw,2008-10-28,2008-09-25
-4em9,2013-03-06,2012-04-11
-7emf,2021-05-05,2021-04-13
-6emx,2018-06-20,2017-10-03
-3emy,2008-10-07,2008-09-25
-3emm,2008-10-14,2008-09-24
-7emy,2021-12-22,2021-04-15
-8emw,2023-05-24,2022-09-28
-5em6,2015-12-30,2015-11-05
-2emb,2007-10-02,2007-03-28
-6emn,2019-04-17,2017-10-03
-3emb,2008-11-18,2008-09-24
-3emt,2009-08-11,2008-09-25
-2emr,2007-10-02,2007-03-28
-2emf,2007-10-02,2007-03-28
-8emq,2022-12-21,2022-09-28
-5eml,2016-02-24,2015-11-06
-2em3,2007-10-02,2007-03-28
-4em2,2013-04-17,2012-04-11
-5emf,2016-01-13,2015-11-06
-4em7,2012-08-01,2012-04-11
-8emk,2024-03-27,2022-09-27
-4em0,2013-04-17,2012-04-11
-8ems,2023-05-10,2022-09-28
-4emj,2012-09-26,2012-04-12
-7ems,2022-04-20,2021-04-14
-8eme,2023-10-18,2022-09-27
-8emj,2024-03-27,2022-09-27
-9emj,2024-03-20,2024-03-08
-1emd,1993-10-31,1993-03-25
-7eme,2021-08-18,2021-04-13
-5em7,2015-12-30,2015-11-05
-2emm,2007-10-02,2007-03-28
-5em9,2016-09-07,2015-11-06
-4emi,2012-09-26,2012-04-12
-7em1,2022-03-30,2021-04-13
-2em1,2007-10-02,2007-03-28
-8emx,2023-05-24,2022-09-28
-7emm,2022-03-02,2021-04-14
-4eme,2012-06-27,2012-04-11
-8emm,2023-05-31,2022-09-28
-4emv,2012-08-01,2012-04-12
-1emh,2000-05-16,2000-03-16
-6em2,2018-10-10,2017-10-01
-6emu,2018-06-13,2017-10-03
-4ema,2013-03-06,2012-04-11
-2emg,2007-10-02,2007-03-28
-6em7,2018-10-10,2017-10-01
-1em9,2000-08-02,2000-03-16
-2emj,2007-10-02,2007-03-28
-8emr,2023-05-10,2022-09-28
-7emb,2021-12-08,2021-04-13
-4emr,2012-05-02,2012-04-12
-3emq,2009-09-29,2008-09-25
-7emw,2022-04-20,2021-04-14
-8emu,2023-02-15,2022-09-28
-4emt,2012-06-13,2012-04-12
-6emv,2018-06-13,2017-10-03
-6emm,2018-10-31,2017-10-02
-5em2,2015-12-23,2015-11-05
-4emy,2012-05-09,2012-04-12
-3emd,2008-11-18,2008-09-24
-7em3,2022-03-30,2021-04-13
-1emo,1996-12-23,1996-08-05
-2emy,2007-10-02,2007-03-28
-7emr,2022-04-20,2021-04-14
-2em9,2007-10-02,2007-03-28
-8emd,2023-07-05,2022-09-27
-9eml,2024-03-20,2024-03-08
-5em5,2015-12-30,2015-11-05
-6em0,2018-01-10,2017-10-01
-5emo,2016-01-13,2015-11-06
-7emd,2021-12-08,2021-04-13
-8emi,2024-03-27,2022-09-27
-2em7,2007-10-02,2007-03-28
-5em8,2015-12-30,2015-11-05
-2emz,2007-10-02,2007-03-28
-4emu,2012-06-13,2012-04-12
-9emv,2024-03-20,2024-03-11
-2em0,2007-10-02,2007-03-28
-7em4,2022-03-30,2021-04-13
-5eme,2016-01-13,2015-11-06
-2ema,2007-10-02,2007-03-28
-7emo,2022-04-20,2021-04-14
-5ems,2016-11-16,2015-11-06
-7em7,2022-03-30,2021-04-13
-6em6,2018-10-10,2017-10-01
-5em3,2016-06-08,2015-11-05
-2em4,2007-10-02,2007-03-28
-6emj,2017-11-08,2017-10-02
-5emi,2016-02-10,2015-11-06
-2emx,2007-10-02,2007-03-28
-3emr,2009-09-29,2008-09-25
-6ema,2018-10-10,2017-10-01
-2emc,2007-10-02,2007-03-28
-4emf,2012-05-02,2012-04-12
-2emv,2007-10-02,2007-03-28
-6em1,2017-12-27,2017-10-01
-8emg,2024-03-27,2022-09-27
-2em2,2007-10-02,2007-03-28
-6emf,2017-12-27,2017-10-02
-5emb,2016-09-07,2015-11-06
-2em5,2007-10-02,2007-03-28
-7emu,2022-04-20,2021-04-14
-2emt,2008-03-18,2007-03-28
-2emu,2007-10-02,2007-03-28
-2em8,2007-10-02,2007-03-28
-3emh,2008-10-07,2008-09-24
-1em1,2000-03-24,2000-03-14
-4em6,2012-05-02,2012-04-11
-2emh,2007-10-02,2007-03-28
-7emv,2022-04-20,2021-04-14
-5emj,2016-02-24,2015-11-06
-2emp,2007-10-02,2007-03-28
-8emv,2023-05-24,2022-09-28
-4em3,2012-10-17,2012-04-11
-3em0,2009-01-13,2008-09-23
-7em8,2022-03-30,2021-04-13
-5emy,2016-07-06,2015-11-06
-7emp,2022-04-20,2021-04-14
-7emc,2021-12-08,2021-04-13
-6emh,2018-08-08,2017-10-02
-2eml,2007-10-02,2007-03-28
-7emj,2022-04-20,2021-04-14
-5emg,2016-01-13,2015-11-06
-3em1,2009-08-11,2008-09-23
-5emq,2016-06-29,2015-11-06
-5em0,2016-06-08,2015-11-05
-3emg,2008-12-02,2008-09-24
-8em0,2023-09-06,2022-09-26
-2emk,2007-10-02,2007-03-28
-7emg,2021-10-06,2021-04-14
-7ema,2021-12-08,2021-04-13
-7em6,2022-03-30,2021-04-13
-4emw,2012-10-17,2012-04-12
-9emc,2024-05-15,2024-03-11
-8em2,2023-05-03,2022-09-26
-5emm,2016-02-24,2015-11-06
-7em9,2021-12-08,2021-04-13
-2emi,2007-10-02,2007-03-28
-7em2,2022-03-30,2021-04-13
-5emu,2016-05-04,2015-11-06
-5emc,2016-06-29,2015-11-06
-4emd,2012-04-25,2012-04-11
-1em6,2000-11-01,2000-03-16
-5emk,2016-02-24,2015-11-06
-8em8,2022-11-02,2022-09-27
-7emt,2022-04-20,2021-04-14
-2eme,2007-10-02,2007-03-28
-1emj,2000-05-16,2000-03-16
-5emp,2016-06-29,2015-11-06
-8emt,2023-05-10,2022-09-28
-5em4,2016-03-23,2015-11-05
-5emw,2015-12-23,2015-11-06
-8em4,2023-02-08,2022-09-26
-4em4,2012-10-17,2012-04-11
-9emb,2024-06-05,2024-03-07
-8em7,2023-02-08,2022-09-27
-7em5,2022-03-30,2021-04-13
-5emn,2016-08-17,2015-11-06
-3em3,2009-09-01,2008-09-23
-3ems,2008-10-21,2008-09-25
-1ems,2000-07-20,2000-03-17
-8emf,2024-03-27,2022-09-27
-7emq,2022-04-20,2021-04-14
-7emz,2021-07-14,2021-04-15
-3emz,2009-09-29,2008-09-25
-5emh,2015-11-25,2015-11-06
-2em6,2007-10-02,2007-03-28
-3eml,2008-10-14,2008-09-24
-7emk,2021-05-19,2021-04-14
-8em3,2023-09-27,2022-09-26
-3em6,2009-09-01,2008-09-23
-5ema,2016-09-07,2015-11-06
-5emt,2016-11-09,2015-11-06
-1emn,1996-12-23,1996-08-05
-2emw,2007-10-02,2007-03-28
-3em4,2009-09-01,2008-09-23
-1h8i,2001-03-02,2001-02-08
-1h82,2001-01-31,2001-01-24
-2h8d,2006-08-29,2006-06-07
-1h89,2002-01-28,2001-01-30
-4h8i,2013-09-25,2012-09-22
-7h85,2024-05-29,2024-04-26
-8h8m,2023-10-04,2022-10-23
-6h8s,2018-09-26,2018-08-03
-1h8s,2001-08-02,2001-02-15
-6h89,2019-08-14,2018-08-02
-7h8y,2024-05-29,2024-04-26
-1h8h,2001-04-15,2001-02-06
-7h82,2024-05-29,2024-04-26
-7h83,2024-05-29,2024-04-26
-8h87,2023-09-06,2022-10-21
-4h8a,2013-01-16,2012-09-22
-1h8p,2002-04-12,2001-02-14
-7h8r,2024-05-29,2024-04-26
-1h8v,2001-04-24,2001-02-16
-2h8f,2006-08-29,2006-06-07
-7h8d,2024-05-29,2024-04-26
-8h8j,2023-02-08,2022-10-23
-5h8q,2016-02-24,2015-12-23
-5h85,2017-01-11,2015-12-23
-6h8r,2018-09-26,2018-08-03
-2h89,2006-06-20,2006-06-06
-3h8i,2009-06-02,2009-04-29
-1h8e,2001-08-10,2001-02-02
-4h8e,2012-12-19,2012-09-22
-8h85,2023-04-19,2022-10-21
-4h85,2013-06-05,2012-09-21
-1h86,2001-01-31,2001-01-24
-8h8t,2023-11-01,2022-10-24
-5h8e,2016-02-10,2015-12-23
-4h8q,2013-02-06,2012-09-23
-6h8p,2018-08-15,2018-08-03
-5h8m,2016-10-26,2015-12-23
-5h82,2016-07-27,2015-12-23
-7h8s,2024-05-29,2024-04-26
-8h8q,2023-10-25,2022-10-24
-6h87,2019-08-14,2018-08-02
-7h89,2024-05-29,2024-04-26
-1h8t,2002-07-11,2001-02-15
-7h87,2024-05-29,2024-04-26
-3h80,2009-05-26,2009-04-28
-6h8w,2020-08-26,2018-08-03
-3h89,2009-10-20,2009-04-29
-4h80,2013-12-25,2012-09-21
-5h8h,2016-02-24,2015-12-23
-2h8p,2006-09-12,2006-06-07
-5h8w,2016-01-13,2015-12-24
-7h8p,2024-05-29,2024-04-26
-8h82,2023-10-11,2022-10-21
-3h85,2009-11-24,2009-04-28
-8h8o,2023-10-04,2022-10-23
-2h8k,2006-06-20,2006-06-07
-5h8f,2016-02-24,2015-12-23
-6h80,2019-03-13,2018-07-31
-1h80,2001-11-27,2001-01-22
-7h8v,2024-05-29,2024-04-26
-5h8j,2016-04-20,2015-12-23
-8h8n,2023-10-04,2022-10-23
-4h81,2013-06-05,2012-09-21
-7h84,2024-05-29,2024-04-26
-3h8f,2010-04-14,2009-04-29
-1h81,2001-01-31,2001-01-24
-3h8c,2009-10-20,2009-04-29
-7h8n,2024-05-29,2024-04-26
-8h8p,2023-10-25,2022-10-24
-1h84,2001-01-31,2001-01-24
-7h8x,2024-05-29,2024-04-26
-7h8h,2024-05-29,2024-04-26
-8h8w,2023-11-01,2022-10-24
-4h8v,2013-09-25,2012-09-24
-2h8z,2006-08-29,2006-06-08
-7h81,2024-05-29,2024-04-26
-3h8g,2010-04-14,2009-04-29
-7h8a,2024-05-29,2024-04-26
-3h87,2009-05-05,2009-04-28
-7h86,2024-05-29,2024-04-26
-7h8j,2024-05-29,2024-04-26
-6h8z,2020-08-26,2018-08-03
-6h8n,2019-11-13,2018-08-02
-5h83,2016-07-27,2015-12-23
-7h8o,2024-05-29,2024-04-26
-4h84,2013-04-24,2012-09-21
-4h88,2013-07-31,2012-09-21
-4h8h,2013-09-25,2012-09-22
-6h8h,2018-11-14,2018-08-02
-2h8x,2006-08-29,2006-06-08
-3h8t,2009-05-12,2009-04-29
-3h8j,2010-05-12,2009-04-29
-4h82,2013-05-01,2012-09-21
-4h8n,2013-08-07,2012-09-23
-2h8g,2006-10-10,2006-06-07
-4h8p,2013-02-06,2012-09-23
-1h8y,2001-07-12,2001-02-17
-6h8d,2019-08-14,2018-08-02
-6h85,2019-08-14,2018-08-01
-6h83,2019-08-14,2018-08-01
-5h84,2016-03-23,2015-12-23
-6h8l,2019-11-13,2018-08-02
-3h8v,2009-05-26,2009-04-29
-7h8b,2024-05-29,2024-04-26
-1h85,2001-11-28,2001-01-24
-1h8d,2001-02-26,2001-02-01
-3h81,2009-05-12,2009-04-28
-3h8a,2010-04-14,2009-04-29
-5h86,2016-03-23,2015-12-23
-5h81,2016-07-27,2015-12-23
-7h8z,2024-05-29,2024-04-26
-7h8k,2024-05-29,2024-04-26
-2h88,2006-06-20,2006-06-06
-1h83,2001-01-31,2001-01-24
-6h8t,2018-09-12,2018-08-03
-2h8a,2007-05-22,2006-06-07
-7h8m,2024-05-29,2024-04-26
-5h8b,2016-02-10,2015-12-23
-3h86,2009-10-06,2009-04-28
-2h8m,2007-04-24,2006-06-07
-6h8a,2019-08-14,2018-08-02
-8h8u,2023-11-01,2022-10-24
-7h80,2024-05-29,2024-04-26
-5h8s,2016-02-24,2015-12-23
-6h8g,2019-08-14,2018-08-02
-7h8c,2024-05-29,2024-04-26
-8h8l,2023-10-04,2022-10-23
-8h8r,2023-02-08,2022-10-24
-6h81,2019-08-14,2018-08-01
-3h8b,2009-10-20,2009-04-29
-3h84,2009-12-22,2009-04-28
-5h8i,2016-04-20,2015-12-23
-4h8w,2014-04-09,2012-09-24
-5h8g,2016-02-10,2015-12-23
-8h8v,2023-11-01,2022-10-24
-5h8t,2016-03-02,2015-12-23
-6h8v,2020-08-26,2018-08-03
-5h8n,2016-02-24,2015-12-23
-7h8w,2024-05-29,2024-04-26
-4h83,2012-10-10,2012-09-21
-7h8q,2024-05-29,2024-04-26
-5h8v,2016-04-13,2015-12-24
-5h8z,2016-05-18,2015-12-25
-5h8x,2016-11-02,2015-12-24
-8h8i,2023-09-13,2022-10-22
-4h8r,2013-07-24,2012-09-23
-7h8f,2024-05-29,2024-04-26
-3h83,2009-05-12,2009-04-28
-3h8s,2010-05-12,2009-04-29
-6h8b,2019-02-20,2018-08-02
-6h8x,2020-08-26,2018-08-03
-8h86,2023-09-06,2022-10-21
-3h8l,2009-06-02,2009-04-29
-1h87,2002-01-15,2001-01-25
-1h8l,2002-02-08,2001-02-09
-7h8u,2024-05-29,2024-04-26
-5h8y,2016-04-13,2015-12-25
-6h8j,2019-06-12,2018-08-02
-2h8h,2006-11-21,2006-06-07
-4h8u,2013-09-25,2012-09-24
-6h8u,2020-08-26,2018-08-03
-6h8y,2020-08-26,2018-08-03
-3h82,2010-01-12,2009-04-28
-5h8u,2016-10-26,2015-12-23
-8h8s,2023-02-08,2022-10-24
-8h81,2023-04-19,2022-10-21
-6h84,2019-08-14,2018-08-01
-1lzg,1995-05-08,1995-02-10
-6lzg,2020-03-18,2020-02-19
-1lzq,2003-04-29,2002-06-11
-7lzn,2022-03-16,2021-03-10
-7lzq,2022-08-17,2021-03-10
-1lzn,1999-04-01,1999-03-23
-4lzu,2014-08-06,2013-08-01
-2lze,2012-10-24,2012-10-01
-6lz6,2021-02-24,2020-02-18
-4lzv,2014-08-06,2013-08-01
-1lzy,1995-02-27,1995-01-09
-1lz7,2002-08-28,2002-06-10
-6lzy,2020-06-10,2020-02-19
-1lzo,2003-01-28,2002-06-11
-5lzs,2016-11-30,2016-10-02
-6lz8,2021-02-24,2020-02-18
-3lzb,2011-03-02,2010-03-01
-1lzx,2002-11-27,2002-06-11
-3lzl,2010-07-21,2010-03-01
-6lzn,2021-01-27,2020-02-19
-1lzv,2002-10-23,2002-06-11
-7lzb,2021-09-22,2021-03-09
-6lzl,2020-04-15,2020-02-19
-4lz1,2014-01-08,2013-07-31
-6lz2,2020-12-23,2020-02-17
-7lz0,2021-07-28,2021-03-08
-3lzz,2010-06-02,2010-03-02
-1lzz,2002-11-27,2002-06-11
-6lzv,2021-02-24,2020-02-19
-7lzz,2021-03-24,2021-03-10
-4lzc,2013-12-18,2013-07-31
-4lzd,2014-02-05,2013-07-31
-3lzr,2010-07-21,2010-03-01
-1lzc,1995-05-08,1995-02-10
-3lzj,2010-05-19,2010-03-01
-4lz5,2013-12-04,2013-07-31
-7lzh,2021-07-28,2021-03-09
-3lz5,2010-12-15,2010-03-01
-3lzv,2010-08-11,2010-03-01
-2lzg,2012-11-07,2012-10-02
-3lzg,2010-04-14,2010-03-01
-6lzb,2021-02-24,2020-02-18
-5lzd,2016-11-23,2016-09-29
-3lzw,2010-12-08,2010-03-02
-5lzt,2016-11-30,2016-10-02
-5lz5,2016-12-21,2016-09-29
-6lz4,2020-05-20,2020-02-18
-7lz1,2021-07-28,2021-03-08
-5lzc,2016-11-23,2016-09-29
-6lzk,2020-07-01,2020-02-19
-7lz7,2021-09-22,2021-03-09
-5lz2,2016-12-21,2016-09-29
-6lz9,2020-03-11,2020-02-18
-7lzf,2021-09-22,2021-03-09
-5lzq,2016-12-14,2016-10-01
-6lzq,2021-02-24,2020-02-19
-4lzr,2014-01-15,2013-08-01
-3lzu,2010-08-11,2010-03-01
-4lzb,2013-12-11,2013-07-31
-7lz3,2022-03-16,2021-03-08
-5lzj,2017-05-31,2016-09-29
-3lzs,2010-08-11,2010-03-01
-1lz8,1999-05-26,1999-03-14
-6lze,2020-04-29,2020-02-19
-4lz2,2013-08-21,2013-07-31
-4lzj,2014-02-26,2013-07-31
-6lzj,2020-07-01,2020-02-19
-3lz0,2010-09-15,2010-03-01
-5lzi,2017-05-31,2016-09-29
-3lzn,2010-07-21,2010-03-01
-4lz0,2013-12-18,2013-07-31
-3lzi,2010-05-12,2010-03-01
-1lzs,1995-04-20,1994-09-14
-4lzg,2014-02-05,2013-07-31
-7lz5,2022-03-16,2021-03-09
-7lzw,2021-03-24,2021-03-10
-5lzp,2016-11-23,2016-09-30
-3lz9,2010-04-07,2010-03-01
-6lzx,2020-06-10,2020-02-19
-1lze,1995-05-08,1995-02-10
-7lzo,2022-03-16,2021-03-10
-3lzp,2010-07-21,2010-03-01
-4lz7,2013-12-04,2013-07-31
-6lzh,2020-06-24,2020-02-19
-4lzs,2014-01-15,2013-08-01
-7lze,2021-08-25,2021-03-09
-5lzg,2017-05-31,2016-09-29
-7lzy,2021-03-24,2021-03-10
-7lzr,2022-03-16,2021-03-10
-5lz7,2016-12-21,2016-09-29
-5lzv,2016-11-30,2016-10-02
-7lz2,2021-07-28,2021-03-08
-6lz1,2020-09-09,2020-02-17
-3lzx,2010-12-08,2010-03-02
-5lzy,2016-11-30,2016-10-02
-3lzo,2010-07-21,2010-03-01
-5lz6,2016-12-14,2016-09-29
-5lzx,2016-11-30,2016-10-02
-5lz4,2016-12-21,2016-09-29
-1lzr,1995-04-20,1994-09-14
-5lza,2016-11-23,2016-09-29
-5lzl,2016-10-12,2016-09-30
-1lz0,2002-08-28,2002-06-10
-6lzw,2021-02-24,2020-02-19
-6lzt,2021-02-24,2020-02-19
-3lzq,2010-07-21,2010-03-01
-1lzi,2002-08-28,2002-06-10
-5lzu,2016-11-30,2016-10-02
-3lzk,2010-03-16,2010-03-01
-1lzb,1995-05-08,1995-02-10
-1lzj,2002-08-28,2002-06-10
-7lza,2021-07-14,2021-03-09
-6lzu,2021-02-24,2020-02-19
-7lzu,2021-03-24,2021-03-10
-7lzs,2022-03-16,2021-03-10
-5lz9,2016-12-21,2016-09-29
-5lzz,2016-11-30,2016-10-02
-3lz3,2010-12-15,2010-03-01
-7lzd,2021-09-22,2021-03-09
-7lzi,2021-07-28,2021-03-09
-5lzf,2016-11-23,2016-09-29
-7lzx,2021-03-24,2021-03-10
-2lzz,2013-01-30,2012-10-12
-7lzv,2021-03-24,2021-03-10
-7lz8,2021-09-22,2021-03-09
-3lzy,2011-05-25,2010-03-02
-7lz9,2021-07-14,2021-03-09
-6lzo,2021-01-27,2020-02-19
-6lz7,2020-05-13,2020-02-18
-5lzb,2016-11-23,2016-09-29
-2lzu,2014-04-16,2012-10-10
-5lze,2016-11-23,2016-09-29
-5lz8,2016-12-21,2016-09-29
-6lz3,2020-04-29,2020-02-18
-1lzw,2002-11-27,2002-06-11
-3lz6,2011-05-04,2010-03-01
-3lze,2010-04-07,2010-03-01
-3lzf,2010-04-07,2010-03-01
-6lzz,2021-02-24,2020-02-19
-7lzt,2021-03-24,2021-03-10
-4lz8,2013-12-04,2013-07-31
-3lz1,2010-09-15,2010-03-01
-6lzi,2020-07-01,2020-02-19
-7lz4,2021-05-26,2021-03-08
-5lzw,2016-11-30,2016-10-02
-7lzk,2022-03-16,2021-03-10
-4lz4,2014-01-08,2013-07-31
-1lz9,1999-05-26,1999-03-15
-7lzp,2021-12-22,2021-03-10
-4lz3,2013-12-18,2013-07-31
-5lzh,2017-05-31,2016-09-29
-5lzr,2016-12-14,2016-10-01
-6lzc,2021-02-24,2020-02-18
-4lzw,2014-12-31,2013-08-01
-1wjf,1998-12-16,1998-06-11
-5wj8,2018-07-04,2017-07-21
-1wjd,1998-05-13,1997-05-13
-4wj9,2014-12-10,2014-09-29
-3wjs,2014-09-24,2013-10-14
-5wjn,2017-09-20,2017-07-23
-4wjk,2014-12-03,2014-09-30
-6wjo,2020-04-22,2020-04-14
-7wjh,2022-09-14,2022-01-06
-6wj3,2020-09-02,2020-04-11
-7wjn,2022-09-28,2022-01-07
-2wjh,2009-07-28,2009-05-26
-3wj7,2014-06-04,2013-10-05
-6wj1,2020-07-01,2020-04-11
-3wjp,2013-12-18,2013-10-14
-5wja,2018-07-18,2017-07-21
-5wjq,2018-03-07,2017-07-24
-2wj2,2009-09-15,2009-05-19
-2wju,2009-06-09,2009-05-29
-2wjw,2009-08-18,2009-06-01
-2wj4,2010-01-26,2009-05-20
-3wjc,2014-04-09,2013-10-08
-3wjn,2014-06-18,2013-10-12
-7wjy,2022-07-13,2022-01-08
-7wjb,2022-03-30,2022-01-06
-4wjg,2014-11-26,2014-09-30
-4wjp,2014-12-31,2014-10-01
-2wji,2009-07-28,2009-05-26
-7wjs,2022-08-10,2022-01-07
-6wj9,2020-07-08,2020-04-13
-2wjl,2010-08-25,2009-05-27
-4wje,2015-10-21,2014-09-29
-2wjn,2009-09-22,2009-05-27
-7wj6,2022-11-09,2022-01-05
-2wjs,2009-06-23,2009-05-28
-4wj4,2014-12-31,2014-09-29
-3wjw,2013-12-04,2013-10-17
-6wj6,2020-08-26,2020-04-12
-1wj0,2004-11-28,2004-05-28
-5wj1,2018-02-14,2017-07-21
-5wjd,2018-03-28,2017-07-21
-7wjr,2023-01-18,2022-01-07
-2wjv,2009-07-07,2009-06-01
-4wjl,2015-03-18,2014-09-30
-2wjy,2009-07-07,2009-06-01
-3wjo,2014-06-18,2013-10-12
-1wj2,2004-11-28,2004-05-28
-3wjz,2013-12-04,2013-10-17
-3wjq,2013-12-18,2013-10-14
-6wjy,2020-08-26,2020-04-14
-5wjf,2017-12-20,2017-07-21
-1wja,1998-05-13,1997-05-13
-5wje,2018-03-28,2017-07-21
-3wjb,2014-04-09,2013-10-08
-5wj9,2017-10-18,2017-07-21
-3wjx,2013-12-04,2013-10-17
-2wjm,2009-09-22,2009-05-27
-6wjv,2020-07-08,2020-04-14
-7wjd,2022-03-30,2022-01-06
-7wjj,2022-09-21,2022-01-06
-5wjg,2017-08-02,2017-07-22
-3wj4,2014-10-15,2013-10-04
-2wj1,2009-09-15,2009-05-19
-1wjx,2004-11-29,2004-05-29
-1wjp,2004-11-29,2004-05-29
-5wjj,2018-01-17,2017-07-23
-3wjy,2013-12-04,2013-10-17
-5wjm,2018-07-04,2017-07-23
-3wj8,2013-11-27,2013-10-07
-7wj4,2023-01-11,2022-01-05
-4wjq,2014-12-31,2014-10-01
-4wjt,2015-07-08,2014-10-01
-6wjp,2020-04-22,2020-04-14
-7wj3,2022-06-22,2022-01-05
-1wje,1998-12-16,1998-06-11
-6wjb,2020-07-08,2020-04-13
-5wj0,2019-01-23,2017-07-21
-1wjb,1998-05-13,1997-05-13
-4wj8,2015-09-30,2014-09-29
-4wjb,2014-10-08,2014-09-29
-3wjm,2014-09-24,2013-10-11
-2wje,2009-07-14,2009-05-25
-7wj9,2022-03-30,2022-01-06
-5wjr,2017-08-09,2017-07-24
-2wjd,2009-07-14,2009-05-25
-6wje,2020-06-24,2020-04-13
-4wjy,2015-03-11,2014-10-01
-6wjc,2020-07-08,2020-04-13
-3wjj,2013-11-13,2013-10-10
-6wjd,2020-08-05,2020-04-13
-7wjl,2023-01-11,2022-01-07
-7wj7,2022-11-09,2022-01-05
-7wje,2022-03-30,2022-01-06
-2wjp,2010-08-25,2009-05-28
-6wj2,2020-09-02,2020-04-11
-7wjz,2022-07-13,2022-01-08
-5wjh,2017-08-02,2017-07-22
-4wj7,2014-12-24,2014-09-29
-6wjn,2020-08-05,2020-04-14
-7wj5,2022-07-13,2022-01-05
-6wjz,2021-04-21,2020-04-15
-2wjj,2009-07-28,2009-05-26
-6wja,2020-07-08,2020-04-13
-3wj5,2014-10-15,2013-10-04
-3wjl,2013-11-13,2013-10-11
-6wj5,2021-02-17,2020-04-11
-2wjf,2009-07-14,2009-05-25
-5wjo,2017-10-25,2017-07-24
-6wjt,2020-04-22,2020-04-14
-7wjo,2022-09-28,2022-01-07
-2wj6,2010-01-26,2009-05-22
-4wjv,2014-11-19,2014-10-01
-7wj2,2022-06-22,2022-01-05
-6wjm,2020-04-22,2020-04-14
-5wjk,2017-12-13,2017-07-23
-4wji,2014-10-22,2014-09-30
-5wj6,2018-01-10,2017-07-21
-2wja,2009-07-14,2009-05-25
-6wj7,2020-08-19,2020-04-13
-2wjk,2010-08-25,2009-05-27
-7wju,2023-01-18,2022-01-07
-6wjj,2020-12-16,2020-04-13
-8wjy,2023-11-22,2023-09-26
-6wj4,2021-04-14,2020-04-11
-5wjs,2017-08-09,2017-07-24
-2wj8,2009-12-08,2009-05-25
-7wjv,2022-07-13,2022-01-08
-7wjf,2022-03-30,2022-01-06
-1wjv,2004-11-29,2004-05-29
-2wjg,2009-07-28,2009-05-26
-7wj8,2022-09-21,2022-01-05
-1wjc,1998-05-13,1997-05-13
-7wjc,2022-03-30,2022-01-06
-2wjo,2010-03-02,2009-05-28
-3wjr,2013-12-18,2013-10-14
-4wjm,2014-10-22,2014-10-01
-1uf9,2003-11-28,2003-05-28
-3ufx,2012-06-27,2011-11-01
-4ufz,2015-10-28,2015-03-20
-3ufy,2012-08-15,2011-11-01
-7uf7,2022-03-30,2022-03-22
-6ufa,2020-12-02,2019-09-24
-3ufn,2012-03-28,2011-11-01
-3ufm,2012-11-07,2011-11-01
-3uf3,2012-03-28,2011-10-31
-7ufr,2022-11-16,2022-03-23
-7ufu,2022-11-16,2022-03-23
-6ufc,2020-08-05,2019-09-24
-8ufh,2024-01-03,2023-10-04
-6ufd,2020-08-05,2019-09-24
-4ufl,2015-03-25,2015-03-17
-7ufc,2022-07-27,2022-03-22
-7uf6,2022-03-30,2022-03-22
-7ufh,2022-08-17,2022-03-22
-5ufd,2017-10-18,2017-01-04
-7uf5,2022-07-20,2022-03-22
-4ufv,2016-02-03,2015-03-19
-6ufq,2019-10-23,2019-09-24
-3ufw,2012-07-11,2011-11-01
-5ufq,2017-08-02,2017-01-05
-1uf7,2004-06-08,2003-05-26
-5ufs,2017-04-26,2017-01-05
-7ufk,2022-10-19,2022-03-22
-5uf8,2017-01-25,2017-01-03
-4ufg,2016-01-27,2015-03-17
-3uf7,2012-11-07,2011-10-31
-5ufi,2017-11-01,2017-01-04
-4ufk,2015-03-25,2015-03-17
-3uf5,2012-08-22,2011-10-31
-4ufi,2015-03-25,2015-03-17
-5ufp,2017-01-25,2017-01-05
-5ufl,2017-02-15,2017-01-04
-6ufn,2019-12-04,2019-09-24
-5ufo,2017-04-05,2017-01-05
-5ufm,2017-12-13,2017-01-05
-7ufd,2022-07-27,2022-03-22
-1ufj,2004-05-18,2003-05-30
-5ufv,2017-03-15,2017-01-05
-5uf0,2017-06-28,2017-01-03
-4ufm,2015-04-01,2015-03-17
-6uf4,2020-12-02,2019-09-23
-5ufw,2018-01-10,2017-01-06
-7ufe,2022-07-27,2022-03-22
-4ufx,2016-02-03,2015-03-19
-4ufq,2016-04-13,2015-03-18
-7ufm,2022-06-08,2022-03-22
-4ufh,2015-03-25,2015-03-17
-3uff,2012-12-12,2011-11-01
-4ufd,2016-01-27,2015-03-16
-5uf2,2017-01-18,2017-01-03
-5ufc,2017-10-18,2017-01-04
-6uf8,2020-12-02,2019-09-23
-6ufo,2019-12-04,2019-09-24
-5ufj,2017-02-22,2017-01-04
-8ufa,2024-01-17,2023-10-04
-8ufp,2024-03-13,2023-10-04
-3ufu,2012-07-11,2011-11-01
-8ufj,2023-11-15,2023-10-04
-5uf1,2017-10-18,2017-01-03
-3ufh,2012-08-08,2011-11-01
-3ufo,2012-07-11,2011-11-01
-8ufu,2024-03-13,2023-10-04
-8ufr,2024-03-13,2023-10-04
-1uf5,2004-06-08,2003-05-23
-3ufr,2012-07-11,2011-11-01
-8ufb,2024-01-17,2023-10-04
-8ufc,2024-01-17,2023-10-04
-7uff,2022-07-27,2022-03-22
-7ufx,2023-03-29,2022-03-23
-5ufn,2017-12-13,2017-01-05
-3ufk,2012-08-08,2011-11-01
-3uf9,2012-10-03,2011-10-31
-7ufp,2022-10-12,2022-03-23
-7uf3,2022-07-20,2022-03-22
-8ufg,2024-01-03,2023-10-04
-6uff,2020-03-25,2019-09-24
-5ufy,2017-10-25,2017-01-06
-3uft,2012-07-11,2011-11-01
-7uft,2022-11-16,2022-03-23
-5ufg,2017-04-12,2017-01-04
-7ufg,2022-09-28,2022-03-22
-6ufx,2020-01-01,2019-09-25
-7uf1,2022-07-20,2022-03-22
-7uf8,2023-02-22,2022-03-22
-8uft,2024-03-13,2023-10-04
-5ufx,2018-01-10,2017-01-06
-4ufe,2016-01-27,2015-03-16
-5ufu,2017-05-17,2017-01-05
-7ufa,2022-07-27,2022-03-22
-3ufp,2012-07-11,2011-11-01
-7ufy,2023-04-12,2022-03-23
-7ufi,2022-06-08,2022-03-22
-7uf9,2022-07-27,2022-03-22
-7ufb,2022-07-27,2022-03-22
-7ufv,2022-05-04,2022-03-23
-1uf3,2003-11-23,2003-05-23
-4uff,2016-01-27,2015-03-16
-4uft,2015-04-29,2015-03-19
-6ufl,2020-05-20,2019-09-24
-7ufj,2022-12-14,2022-03-22
-4ufw,2016-02-03,2015-03-19
-3uf6,2011-11-16,2011-10-31
-6ufi,2020-09-30,2019-09-24
-6ufp,2020-03-18,2019-09-24
-8ufs,2024-03-13,2023-10-04
-4ufr,2015-07-08,2015-03-18
-6ufb,2020-08-05,2019-09-24
-8ufq,2024-03-13,2023-10-04
-4ufj,2015-03-25,2015-03-17
-4uf7,2015-04-01,2015-03-13
-6ufs,2020-05-20,2019-09-24
-5ufa,2017-01-18,2017-01-04
-8ufi,2024-01-17,2023-10-04
-3ufs,2012-07-11,2011-11-01
-7uf0,2022-07-20,2022-03-22
-4uf0,2015-01-14,2014-12-22
-7ufs,2022-11-16,2022-03-23
-5uf4,2017-10-18,2017-01-03
-4ufc,2015-07-08,2015-03-16
-6uf0,2019-12-18,2019-09-23
-7uf2,2022-07-20,2022-03-22
-7uf4,2022-07-20,2022-03-22
-4ufa,2015-10-07,2015-03-16
-8uf5,2023-10-18,2023-10-03
-4ufu,2016-04-13,2015-03-19
-6ufe,2020-08-05,2019-09-24
-3ufl,2012-01-18,2011-11-01
-5ufr,2017-04-05,2017-01-05
-7ufl,2022-10-19,2022-03-22
-7ufz,2023-04-12,2022-03-23
-5ufz,2018-01-10,2017-01-06
-1uf8,2004-06-08,2003-05-26
-3uf4,2011-12-07,2011-10-31
-3uf0,2011-11-23,2011-10-31
-3uf8,2011-11-09,2011-10-31
-5uff,2017-10-18,2017-01-04
-4ufy,2016-04-13,2015-03-20
-5ufe,2017-08-02,2017-01-04
-6uf7,2020-12-02,2019-09-23
-4ufb,2015-10-07,2015-03-16
-3ufa,2013-01-23,2011-10-31
-3ufg,2011-11-09,2011-11-01
-3ufq,2012-07-11,2011-11-01
-3ufv,2012-07-11,2011-11-01
-7m6d,2021-05-05,2021-03-25
-1m66,2002-12-11,2002-07-12
-7m60,2021-07-07,2021-03-25
-6m6x,2021-03-17,2020-03-16
-1m67,2002-12-11,2002-07-12
-5m6i,2017-11-15,2016-10-25
-5m65,2017-05-10,2016-10-24
-1m6w,2002-07-26,2002-07-17
-7m6g,2021-05-05,2021-03-25
-7m6b,2021-04-14,2021-03-25
-6m61,2020-12-30,2020-03-12
-4m6s,2013-10-09,2013-08-10
-1m64,2002-11-06,2002-07-12
-4m6r,2014-01-29,2013-08-10
-1m6o,2003-09-02,2002-07-17
-7m6s,2022-08-03,2021-03-26
-3m6b,2010-04-14,2010-03-15
-5m6m,2017-05-24,2016-10-25
-5m6b,2017-05-17,2016-10-24
-3m6g,2010-09-08,2010-03-15
-4m6t,2013-10-02,2013-08-11
-1m6c,1998-08-19,1998-08-12
-1m6b,2002-08-02,2002-07-15
-5m6g,2017-11-29,2016-10-25
-7m6h,2021-05-05,2021-03-25
-1m6e,2003-09-09,2002-07-16
-3m6z,2010-08-04,2010-03-16
-7m6e,2021-05-05,2021-03-25
-5m62,2016-12-07,2016-10-24
-6m62,2020-08-26,2020-03-12
-1m6y,2003-01-28,2002-07-17
-4m60,2013-09-04,2013-08-08
-7m6f,2021-05-05,2021-03-25
-6m6v,2020-09-30,2020-03-16
-6m6t,2021-03-31,2020-03-16
-2m6n,2013-05-29,2013-04-06
-5m6n,2017-05-24,2016-10-25
-4m6g,2013-09-18,2013-08-09
-7m6a,2021-09-08,2021-03-25
-5m6y,2018-06-06,2016-10-26
-5m63,2017-05-03,2016-10-24
-1m6d,2003-07-15,2002-07-15
-1m6v,2002-07-31,2002-07-17
-4m69,2013-10-16,2013-08-09
-5m6u,2017-02-01,2016-10-26
-5m6j,2017-12-20,2016-10-25
-4m6j,2013-09-25,2013-08-09
-5m6v,2018-06-06,2016-10-26
-1m68,2003-04-22,2002-07-14
-3m6i,2010-07-21,2010-03-15
-5m6f,2017-05-24,2016-10-25
-3m6h,2010-04-14,2010-03-15
-4m6e,2014-03-19,2013-08-09
-4m6o,2014-03-26,2013-08-09
-3m6m,2010-09-22,2010-03-16
-5m67,2017-05-10,2016-10-24
-7m6n,2022-08-03,2021-03-26
-3m61,2010-04-07,2010-03-15
-1m63,2002-09-25,2002-07-12
-5m6z,2017-11-29,2016-10-26
-1m6s,2002-12-11,2002-07-17
-5m69,2017-08-16,2016-10-24
-3m6r,2011-03-30,2010-03-16
-6m6r,2021-03-17,2020-03-16
-6m6y,2020-10-14,2020-03-16
-7m6q,2022-08-03,2021-03-26
-7m6t,2021-10-13,2021-03-26
-3m6a,2010-06-30,2010-03-15
-7m6i,2021-05-05,2021-03-25
-1m6i,2002-08-28,2002-07-16
-6m6a,2020-10-14,2020-03-14
-5m66,2017-05-10,2016-10-24
-4m63,2013-10-23,2013-08-08
-2m65,2013-05-22,2013-03-21
-3m6s,2010-03-31,2010-03-16
-3m64,2011-03-09,2010-03-15
-4m6l,2013-09-25,2013-08-09
-7m66,2022-09-28,2021-03-25
-7m6o,2022-08-03,2021-03-26
-5m60,2017-05-17,2016-10-23
-7m6u,2021-04-14,2021-03-26
-4m6y,2014-06-25,2013-08-12
-5m64,2016-12-21,2016-10-24
-3m6y,2010-04-07,2010-03-16
-6m69,2020-10-14,2020-03-13
-5m6k,2017-12-20,2016-10-25
-3m6f,2010-05-12,2010-03-15
-5m6r,2017-11-15,2016-10-25
-6m60,2021-06-09,2020-03-12
-4m6p,2013-09-25,2013-08-10
-7m6k,2022-02-02,2021-03-25
-6m6s,2021-03-17,2020-03-16
-3m6o,2011-03-30,2010-03-16
-4m6x,2014-06-25,2013-08-12
-3m6p,2011-03-30,2010-03-16
-3m6w,2010-03-31,2010-03-16
-6m6b,2020-10-14,2020-03-14
-3m67,2010-11-03,2010-03-15
-4m6q,2013-09-25,2013-08-10
-1m6p,1999-04-27,1998-04-19
-5m6o,2017-07-19,2016-10-25
-7m63,2021-09-01,2021-03-25
-1m6m,1998-08-19,1998-08-13
-5m6c,2017-04-12,2016-10-24
-3m63,2010-04-28,2010-03-15
-4m6v,2014-09-10,2013-08-11
-5m61,2016-11-23,2016-10-23
-4m65,2013-10-30,2013-08-08
-6m65,2020-10-14,2020-03-13
-7m6m,2022-08-03,2021-03-26
-6m63,2021-09-22,2020-03-12
-1m65,2003-04-22,2002-07-12
-3m6q,2011-03-30,2010-03-16
-7m6l,2021-08-18,2021-03-25
-2m6s,2014-04-09,2013-04-09
-2m6z,2013-09-18,2013-04-15
-4m6k,2013-09-25,2013-08-09
-6m6l,2021-03-17,2020-03-15
-1m60,2002-08-07,2002-07-11
-5m6x,2017-05-17,2016-10-26
-5m6d,2017-01-11,2016-10-25
-6m6p,2020-09-23,2020-03-16
-3m62,2010-04-28,2010-03-15
-3m6l,2010-04-28,2010-03-15
-5m6h,2017-05-24,2016-10-25
-5m6e,2017-05-24,2016-10-25
-7m6j,2021-07-07,2021-03-25
-2m6m,2014-05-07,2013-04-06
-3m6e,2010-08-04,2010-03-15
-3m6v,2010-03-31,2010-03-16
-5m6l,2017-05-24,2016-10-25
-1m6h,2002-07-26,2002-07-16
-7m6r,2022-08-03,2021-03-26
-6m6d,2021-03-10,2020-03-14
-4m6u,2014-03-05,2013-08-11
-4m6i,2013-09-18,2013-08-09
-1m6z,2003-09-16,2002-07-18
-6m6c,2020-10-14,2020-03-14
-7m6p,2022-08-03,2021-03-26
-6e67,2019-06-05,2018-07-24
-3e6q,2008-08-26,2008-08-15
-5e65,2016-03-23,2015-10-09
-6e61,2019-05-15,2018-07-23
-1e6x,2001-01-05,2000-08-23
-6e6f,2019-07-31,2018-07-24
-7e63,2022-02-23,2021-02-21
-7e6q,2021-03-17,2021-02-23
-6e62,2018-11-28,2018-07-23
-7e6z,2021-04-07,2021-02-24
-2e67,2007-06-26,2006-12-26
-1e6y,2000-10-18,2000-08-23
-2e6w,2007-11-27,2007-01-05
-2e6a,2008-01-15,2006-12-26
-8e68,2022-09-14,2022-08-22
-1e6n,2001-06-22,2000-08-21
-1e61,2000-08-25,2000-08-06
-8e6x,2022-09-07,2022-08-23
-1e62,2001-05-25,2000-08-07
-8e6n,2023-05-03,2022-08-22
-5e6y,2015-12-16,2015-10-11
-5e6u,2016-04-06,2015-10-10
-5e64,2016-03-23,2015-10-09
-2e6u,2007-01-23,2007-01-03
-6e6g,2019-07-31,2018-07-24
-2e66,2007-06-26,2006-12-25
-1e66,2001-08-02,2000-08-08
-2e68,2008-01-15,2006-12-26
-6e6v,2019-07-31,2018-07-25
-3e6e,2009-08-18,2008-08-15
-8e6m,2023-05-03,2022-08-22
-7e6y,2021-04-07,2021-02-24
-7e6f,2022-03-02,2021-02-22
-5e6x,2016-03-02,2015-10-10
-6e6j,2019-07-31,2018-07-25
-3e6s,2008-11-25,2008-08-15
-1e6d,2000-10-30,2000-08-11
-6e6a,2019-07-10,2018-07-24
-3e68,2008-10-07,2008-08-14
-5e6w,2016-03-02,2015-10-10
-7e62,2021-08-18,2021-02-21
-3e6t,2008-10-07,2008-08-15
-6e60,2019-05-15,2018-07-23
-1e67,2000-08-16,2000-08-09
-5e67,2016-01-13,2015-10-09
-1e60,2000-08-25,2000-08-06
-8e6o,2024-02-28,2022-08-23
-4e6x,2013-03-27,2012-03-16
-2e6v,2007-07-24,2007-01-04
-4e6p,2012-04-11,2012-03-15
-2e6d,2008-01-15,2006-12-26
-8e69,2022-09-21,2022-08-22
-8e6l,2023-05-03,2022-08-22
-5e6j,2016-05-18,2015-10-09
-8e62,2022-11-23,2022-08-22
-2e6s,2007-07-03,2006-12-28
-6e6k,2019-02-13,2018-07-25
-8e6k,2023-08-09,2022-08-22
-8e64,2022-09-14,2022-08-22
-8e6w,2022-09-07,2022-08-23
-2e6y,2007-02-27,2007-01-05
-3e67,2008-10-07,2008-08-14
-6e6t,2019-07-31,2018-07-25
-6e6e,2019-07-31,2018-07-24
-8e65,2022-09-14,2022-08-22
-1e6u,2000-10-22,2000-08-23
-3e6b,2008-09-30,2008-08-15
-4e6w,2013-03-27,2012-03-16
-5e6t,2015-12-09,2015-10-10
-3e6l,2008-10-07,2008-08-15
-5e6r,2016-03-02,2015-10-10
-6e6x,2019-07-31,2018-07-25
-5e6a,2017-02-08,2015-10-09
-7e6x,2021-04-07,2021-02-24
-7e6i,2021-04-14,2021-02-22
-3e64,2008-10-14,2008-08-14
-3e6p,2008-11-18,2008-08-15
-5e6d,2017-02-08,2015-10-09
-4e6e,2012-06-06,2012-03-15
-2e6c,2007-08-28,2006-12-26
-8e60,2023-05-03,2022-08-22
-8e6b,2022-09-07,2022-08-22
-8e6i,2023-05-03,2022-08-22
-8e6g,2023-02-22,2022-08-22
-3e60,2008-08-26,2008-08-14
-5e6z,2015-12-16,2015-10-11
-3e65,2008-10-07,2008-08-14
-5e69,2017-02-08,2015-10-09
-7e6g,2021-09-22,2021-02-22
-6e6i,2019-01-30,2018-07-24
-4e6m,2012-04-04,2012-03-15
-8e61,2022-09-07,2022-08-22
-5e62,2016-03-23,2015-10-09
-1e6a,2001-03-19,2000-08-09
-3e63,2008-10-14,2008-08-14
-1e6z,2001-06-22,2000-08-23
-7e6t,2021-09-22,2021-02-24
-1e6w,2001-05-25,2000-08-23
-8e6e,2022-09-07,2022-08-22
-6e6h,2019-07-31,2018-07-24
-7e64,2022-02-23,2021-02-21
-1e6s,2000-09-06,2000-08-23
-2e61,2007-06-26,2006-12-25
-2e6b,2007-08-28,2006-12-26
-3e6k,2008-12-02,2008-08-15
-6e6c,2019-07-31,2018-07-24
-6e69,2019-07-24,2018-07-24
-7e6c,2022-03-02,2021-02-22
-7e65,2022-02-23,2021-02-21
-4e6q,2012-05-30,2012-03-15
-4e6r,2012-04-04,2012-03-15
-5e6m,2016-07-20,2015-10-10
-5e6v,2016-03-02,2015-10-10
-6e68,2018-08-08,2018-07-24
-7e69,2022-02-23,2021-02-21
-1e6v,2000-10-18,2000-08-23
-5e6o,2016-01-06,2015-10-10
-7e6b,2022-03-02,2021-02-22
-1e6i,2000-11-24,2000-08-18
-7e67,2022-02-23,2021-02-21
-5e6e,2015-10-28,2015-10-09
-3e6o,2008-10-07,2008-08-15
-2e6l,2007-01-16,2006-12-27
-1e6r,2001-06-22,2000-08-22
-3e6n,2008-10-07,2008-08-15
-8e6z,2022-09-07,2022-08-23
-2e6f,2008-01-15,2006-12-26
-7e66,2022-02-23,2021-02-21
-1e64,2001-05-25,2000-08-07
-5e6h,2015-12-16,2015-10-09
-7e61,2022-02-23,2021-02-21
-1e63,2001-05-25,2000-08-07
-6e6p,2019-07-31,2018-07-25
-3e6c,2008-09-30,2008-08-15
-8e6a,2022-09-21,2022-08-22
-3e6j,2008-10-07,2008-08-15
-6e6w,2019-07-31,2018-07-25
-3e6u,2009-06-23,2008-08-16
-5e66,2016-03-23,2015-10-09
-5e63,2016-01-13,2015-10-09
-4e6d,2012-05-30,2012-03-15
-8e6h,2023-05-03,2022-08-22
-6e6l,2019-10-16,2018-07-25
-3e6y,2009-03-10,2008-08-17
-4e6n,2012-08-01,2012-03-15
-5e6b,2017-02-08,2015-10-09
-5e6s,2016-03-02,2015-10-10
-5e6c,2017-02-08,2015-10-09
-8e63,2022-09-28,2022-08-22
-1e6q,2001-01-05,2000-08-22
-6e6z,2019-07-31,2018-07-25
-3e6i,2008-09-23,2008-08-15
-3e6f,2009-08-18,2008-08-15
-7e6k,2022-02-23,2021-02-22
-5e6i,2016-10-19,2015-10-09
-2e6h,2007-08-28,2006-12-26
-8e6d,2022-09-07,2022-08-22
-6e6m,2019-02-13,2018-07-25
-8e6c,2022-09-07,2022-08-22
-2e6r,2007-07-03,2006-12-28
-7e6e,2022-03-02,2021-02-22
-4e67,2012-10-10,2012-03-15
-5e68,2016-10-12,2015-10-09
-5e61,2015-12-16,2015-10-09
-2e6i,2007-07-03,2006-12-27
-3e6z,2009-07-07,2008-08-17
-6e6b,2019-04-10,2018-07-24
-3e62,2008-10-14,2008-08-14
-1e6e,2001-08-09,2000-08-15
-4e6k,2012-08-01,2012-03-15
-3e6v,2008-12-02,2008-08-16
-7e60,2022-02-23,2021-02-21
-5e6f,2016-03-30,2015-10-09
-7a0e,2021-03-17,2020-08-07
-4a0h,2012-06-13,2011-09-09
-7a0b,2021-06-16,2020-08-07
-5a03,2015-10-21,2015-04-17
-3a0e,2010-03-16,2009-03-16
-5a0b,2015-08-19,2015-04-17
-1a00,1998-03-18,1997-12-08
-8a0i,2022-07-20,2022-05-27
-7a0c,2020-11-04,2020-08-07
-5a0e,2015-12-30,2015-04-19
-5a0c,2015-08-19,2015-04-17
-8a0t,2023-09-13,2022-05-30
-6a0b,2019-06-19,2018-06-05
-2a06,2005-06-21,2005-06-16
-4a0r,2012-06-13,2011-09-12
-2a00,2005-12-20,2005-06-15
-1a0z,1998-03-18,1997-12-08
-5a0m,2016-05-04,2015-04-21
-3a0w,2009-10-20,2009-03-24
-1a0s,1998-06-10,1997-12-07
-7a0k,2021-08-18,2020-08-09
-6a05,2019-06-19,2018-06-05
-6a0r,2018-11-28,2018-06-06
-1a0l,1999-03-23,1997-12-03
-6a0d,2019-06-19,2018-06-05
-8a0r,2022-07-20,2022-05-30
-7a0q,2021-08-18,2020-08-10
-5a0l,2015-06-03,2015-04-21
-3a0b,2009-05-19,2009-03-16
-8a0c,2023-04-26,2022-05-27
-4a0p,2011-10-26,2011-09-11
-8a0u,2022-08-17,2022-05-30
-5a0x,2015-08-05,2015-04-23
-3a0u,2009-10-20,2009-03-24
-8a0p,2022-07-20,2022-05-30
-5a06,2015-10-21,2015-04-17
-3a0n,2009-10-20,2009-03-23
-6a02,2019-02-06,2018-06-05
-3a09,2010-03-16,2009-03-12
-6a0g,2019-06-19,2018-06-05
-4a0g,2012-06-13,2011-09-09
-6a0f,2019-12-11,2018-06-05
-5a0y,2016-05-11,2015-04-24
-1a0t,1998-03-18,1997-12-08
-8a07,2023-09-13,2022-05-26
-1a07,1998-04-08,1997-12-09
-7a0p,2020-12-02,2020-08-10
-1a0i,1998-03-25,1997-12-01
-4a0q,2011-10-26,2011-09-12
-5a09,2015-08-19,2015-04-17
-8a08,2022-07-20,2022-05-27
-7a0f,2021-03-17,2020-08-07
-4a0s,2011-12-07,2011-09-12
-7a06,2020-09-09,2020-08-06
-6a04,2019-06-19,2018-06-05
-6a0q,2018-09-12,2018-06-06
-8a0x,2023-05-03,2022-05-30
-8a0h,2023-02-01,2022-05-27
-2a0y,2006-06-06,2005-06-17
-2a0c,2006-01-24,2005-06-16
-5a0f,2015-07-22,2015-04-20
-1a0r,1998-12-30,1997-12-05
-6a0k,2018-09-12,2018-06-05
-5a01,2016-04-27,2015-04-15
-1a0q,1999-03-02,1997-12-05
-4a08,2011-11-30,2011-09-08
-6a00,2019-06-19,2018-06-05
-1a0j,1999-01-13,1997-12-01
-6a07,2019-02-06,2018-06-05
-7a0j,2021-08-18,2020-08-09
-3a02,2010-03-09,2009-02-28
-2a0l,2005-11-01,2005-06-16
-5a0t,2015-08-19,2015-04-22
-5a0v,2015-08-19,2015-04-23
-5a0p,2015-08-05,2015-04-22
-3a0i,2009-04-28,2009-03-19
-4a01,2012-03-28,2011-09-07
-4a03,2012-01-18,2011-09-07
-6a0s,2018-11-28,2018-06-06
-3a04,2010-03-09,2009-03-02
-5a07,2015-08-26,2015-04-17
-3a07,2009-08-25,2009-03-04
-8a0e,2023-04-05,2022-05-27
-4a00,2011-12-28,2011-09-06
-1a01,1998-03-18,1997-12-08
-2a0w,2006-06-06,2005-06-17
-7a0x,2022-02-23,2020-08-11
-8a0q,2022-07-20,2022-05-30
-3a0k,2010-04-07,2009-03-20
-6a0h,2019-12-11,2018-06-05
-2a0f,2005-09-27,2005-06-16
-6a0j,2018-09-12,2018-06-05
-8a0o,2022-07-20,2022-05-29
-5a08,2015-08-26,2015-04-17
-7a0t,2021-08-18,2020-08-10
-6a0t,2018-11-28,2018-06-06
-3a0d,2010-03-16,2009-03-16
-5a0w,2016-05-11,2015-04-23
-6a0v,2019-06-19,2018-06-06
-1a0d,1998-06-03,1997-11-28
-6a0u,2018-11-28,2018-06-06
-1a0c,1998-06-03,1997-11-28
-2a07,2006-01-31,2005-06-16
-7a01,2020-12-30,2020-08-05
-1a0g,1998-06-03,1997-11-30
-7a04,2020-09-09,2020-08-06
-5a02,2015-10-21,2015-04-17
-8a0b,2022-09-21,2022-05-27
-2a0i,2005-10-25,2005-06-16
-8a0m,2023-04-26,2022-05-29
-4a0t,2012-05-30,2011-09-12
-4a0j,2011-11-09,2011-09-09
-1a0h,1998-06-17,1997-11-30
-8a0g,2023-04-05,2022-05-27
-6a0z,2018-06-20,2018-06-06
-1a05,1998-06-17,1997-12-09
-7a0v,2020-12-30,2020-08-11
-3a06,2010-03-16,2009-03-02
-2a0q,2005-07-12,2005-06-16
-7a0a,2021-08-18,2020-08-07
-5a00,2015-08-12,2015-04-15
-6a0l,2018-09-12,2018-06-05
-4a0m,2012-04-11,2011-09-09
-2a0b,1998-06-17,1998-04-02
-5a0a,2015-08-19,2015-04-17
-7a0d,2021-03-17,2020-08-07
-4a0i,2011-11-09,2011-09-09
-5a04,2015-10-21,2015-04-17
-7a0l,2020-12-09,2020-08-09
-8a0s,2023-09-20,2022-05-30
-4a09,2011-11-30,2011-09-08
-6a06,2019-06-19,2018-06-05
-7a00,2021-07-07,2020-08-05
-1a0b,1998-03-18,1997-11-27
-3a03,2010-03-09,2009-02-28
-3a05,2010-03-09,2009-03-02
-4a07,2011-12-07,2011-09-08
-6a01,2019-06-19,2018-06-05
-4a0n,2011-11-09,2011-09-09
-4a05,2012-07-25,2011-09-08
-4a0c,2011-11-30,2011-09-08
-8a0f,2023-04-05,2022-05-27
-7a0z,2021-04-21,2020-08-11
-6a03,2019-06-19,2018-06-05
-5a0s,2015-08-05,2015-04-22
-2a0s,2005-07-26,2005-06-16
-8a0l,2022-12-14,2022-05-28
-4a06,2011-12-07,2011-09-08
-3a0g,2010-03-23,2009-03-17
-8a0v,2022-08-17,2022-05-30
-6a0m,2019-06-19,2018-06-05
-1a08,1998-04-08,1997-12-09
-7a08,2020-09-23,2020-08-07
-6a0o,2019-06-19,2018-06-06
-4a0z,2012-09-26,2011-09-13
-3a0t,2009-10-20,2009-03-24
-1a09,1998-04-08,1997-12-10
-1a0o,1998-12-30,1997-12-05
-4a0f,2012-06-13,2011-09-09
-6a08,2019-06-19,2018-06-05
-5a05,2015-10-21,2015-04-17
-2a03,2005-06-21,2005-06-15
-1a0f,1999-01-13,1997-11-29
-7a0s,2021-08-18,2020-08-10
-8a0y,2023-11-01,2022-05-30
-7a0r,2021-08-18,2020-08-10
-2a0z,2005-08-02,2005-06-17
-3a0h,2009-05-19,2009-03-17
-1a0e,1998-06-03,1997-11-28
-2a0x,2006-06-06,2005-06-17
-3a0r,2009-10-20,2009-03-24
-4a0x,2012-09-26,2011-09-13
-5a0q,2015-12-30,2015-04-22
-6a0y,2019-06-19,2018-06-06
-8a0z,2023-06-14,2022-05-30
-7a09,2020-10-14,2020-08-07
-5a0r,2015-08-05,2015-04-22
-8a0n,2023-06-14,2022-05-29
-1a0u,1998-03-18,1997-12-08
-8j7a,2023-11-15,2023-04-27
-2j73,2006-10-17,2006-10-05
-6j71,2019-02-27,2019-01-16
-5j7g,2017-05-17,2016-04-06
-3j7i,2014-12-10,2014-07-01
-8j7j,2023-08-02,2023-04-27
-4j7e,2013-08-07,2013-02-13
-4j7u,2013-06-05,2013-02-14
-1j7n,2001-11-07,2001-05-17
-4j7c,2013-04-17,2013-02-13
-2j78,2006-10-18,2006-10-06
-4j7m,2013-03-27,2013-02-13
-2j7n,2006-12-13,2006-10-13
-4j7x,2014-02-19,2013-02-14
-4j7d,2013-08-07,2013-02-13
-8j7y,2023-09-20,2023-04-28
-1j70,2003-06-17,2001-05-15
-4j75,2013-05-22,2013-02-12
-3j7y,2014-10-15,2014-08-26
-2j7p,2006-12-11,2006-10-14
-4j7l,2013-03-27,2013-02-13
-6j79,2019-04-10,2019-01-17
-2j72,2006-10-17,2006-10-05
-6j7r,2020-05-13,2019-01-18
-5j7i,2016-09-07,2016-04-06
-8j79,2023-05-24,2023-04-27
-5j72,2017-02-08,2016-04-05
-5j7w,2016-09-28,2016-04-07
-2j7q,2007-03-20,2006-10-16
-2j77,2006-10-18,2006-10-06
-5j7m,2016-04-27,2016-04-06
-3j7t,2015-02-18,2014-08-07
-5j7r,2016-04-20,2016-04-06
-2j7k,2007-10-23,2006-10-12
-8j7g,2023-08-02,2023-04-27
-5j7k,2016-08-17,2016-04-06
-5j7a,2016-08-31,2016-04-06
-8j76,2024-04-10,2023-04-27
-6j74,2020-01-22,2019-01-16
-1j7p,2001-11-07,2001-05-17
-6j7n,2020-05-13,2019-01-18
-6j7x,2020-01-22,2019-01-18
-6j7u,2019-09-18,2019-01-18
-2j7t,2006-11-07,2006-10-17
-1j79,2001-06-20,2001-05-16
-1j73,2001-05-30,2001-05-15
-6j7b,2019-06-19,2019-01-17
-4j7t,2014-01-01,2013-02-14
-8j7m,2024-05-15,2023-04-27
-8j7o,2024-05-08,2023-04-27
-1j78,2002-02-06,2001-05-16
-8j72,2024-03-06,2023-04-27
-4j73,2013-03-27,2013-02-12
-8j7k,2023-08-02,2023-04-27
-3j7o,2014-09-03,2014-08-01
-3j7b,2014-10-08,2014-06-09
-1j7w,2002-02-27,2001-05-19
-6j7a,2019-04-10,2019-01-17
-6j7p,2020-05-13,2019-01-18
-1j75,2001-09-01,2001-05-15
-3j7p,2014-09-03,2014-08-01
-5j78,2016-09-07,2016-04-06
-8j78,2024-05-08,2023-04-27
-2j7u,2007-03-13,2006-10-17
-3j7a,2014-07-16,2014-06-03
-8j77,2024-04-10,2023-04-27
-1j7u,2001-08-08,2001-05-18
-5j7b,2016-05-18,2016-04-06
-6j7o,2020-05-13,2019-01-18
-3j7q,2014-09-03,2014-08-01
-6j7e,2019-11-27,2019-01-18
-8j7i,2024-05-01,2023-04-27
-4j77,2013-03-27,2013-02-12
-4j79,2013-03-27,2013-02-12
-6j7k,2019-05-15,2019-01-18
-6j7s,2020-05-13,2019-01-18
-4j7y,2014-01-01,2013-02-14
-2j75,2006-12-11,2006-10-06
-8j7w,2023-09-20,2023-04-28
-2j74,2007-12-18,2006-10-06
-4j7f,2014-03-26,2013-02-13
-6j7i,2019-04-10,2019-01-18
-1j7l,2001-08-08,2001-05-17
-2j7i,2006-11-06,2006-10-09
-2j7l,2006-11-01,2006-10-12
-8j74,2024-04-03,2023-04-27
-8j7z,2023-12-20,2023-04-28
-6j72,2019-09-11,2019-01-16
-3j7h,2014-07-30,2014-06-30
-5j7q,2016-05-04,2016-04-06
-4j74,2013-08-07,2013-02-12
-8j7d,2024-05-08,2023-04-27
-4j7n,2013-03-27,2013-02-13
-8j7u,2023-09-20,2023-04-28
-4j70,2013-04-17,2013-02-12
-8j7l,2024-05-01,2023-04-27
-5j7s,2017-02-15,2016-04-06
-3j77,2014-08-06,2014-05-29
-4j71,2013-03-20,2013-02-12
-2j7w,2007-03-13,2006-10-17
-6j7y,2019-08-28,2019-01-18
-6j7q,2020-05-13,2019-01-18
-2j7c,2006-10-17,2006-10-06
-3j7z,2014-10-22,2014-08-27
-2j7j,2007-10-09,2006-10-10
-2j7x,2006-11-07,2006-10-17
-8j7h,2024-05-01,2023-04-27
-2j7b,2006-10-18,2006-10-06
-1j7o,2001-11-07,2001-05-17
-5j71,2017-01-25,2016-04-05
-5j7z,2016-04-27,2016-04-07
-5j7p,2016-05-04,2016-04-06
-5j7d,2016-10-05,2016-04-06
-1j7k,2001-08-08,2001-05-16
-1j7y,2002-02-27,2001-05-19
-5j79,2016-05-18,2016-04-06
-6j7m,2019-05-15,2019-01-18
-5j7x,2016-08-10,2016-04-07
-4j7i,2014-01-08,2013-02-13
-5j7f,2017-05-17,2016-04-06
-1j77,2001-05-30,2001-05-15
-6j7l,2019-05-15,2019-01-18
-4j72,2013-09-11,2013-02-12
-1j7s,2002-02-27,2001-05-18
-4j78,2013-03-27,2013-02-12
-6j7f,2020-01-22,2019-01-18
-2j7d,2006-10-18,2006-10-06
-2j7h,2006-10-18,2006-10-08
-2j7e,2006-10-18,2006-10-07
-6j76,2020-01-22,2019-01-17
-3j7r,2014-09-03,2014-08-01
-1j7e,2002-02-06,2001-05-16
-8j7f,2024-05-15,2023-04-27
-6j7t,2020-05-13,2019-01-18
-8j75,2024-04-10,2023-04-27
-2j7m,2006-10-16,2006-10-12
-6j7c,2019-02-27,2019-01-17
-5j7l,2016-07-27,2016-04-06
-3j78,2014-08-06,2014-05-29
-6j7z,2019-08-28,2019-01-18
-4j7v,2014-02-19,2013-02-14
-5j7y,2016-09-21,2016-04-07
-5j7j,2017-10-25,2016-04-06
-1j71,2001-05-23,2001-05-15
-8j7c,2024-05-01,2023-04-27
-2j7f,2006-10-18,2006-10-07
-3j79,2014-07-16,2014-06-02
-5j75,2016-05-04,2016-04-05
-2j7o,2006-12-13,2006-10-13
-4j7h,2013-05-22,2013-02-13
-2j7a,2006-12-06,2006-10-06
-1j7j,2003-07-29,2001-05-16
-2j7g,2006-10-18,2006-10-07
-4j7g,2013-05-22,2013-02-13
-2j79,2006-10-18,2006-10-06
-8j7b,2023-11-15,2023-04-27
-2j7y,2006-11-07,2006-10-17
-5j74,2016-05-25,2016-04-05
-5xos,2017-06-14,2017-05-31
-5xoo,2018-04-11,2017-05-29
-5xon,2017-08-16,2017-05-29
-8xoy,2024-01-24,2024-01-02
-6xoc,2021-03-31,2020-07-06
-4xo0,2015-05-27,2015-01-16
-6xoo,2021-06-02,2020-07-07
-6xon,2021-06-02,2020-07-07
-8xoo,2024-03-27,2024-01-01
-7xo8,2022-06-15,2022-05-01
-5xop,2017-12-06,2017-05-30
-4xok,2015-10-14,2015-01-16
-6xoh,2021-03-24,2020-07-07
-6xox,2020-11-18,2020-07-07
-6xom,2021-06-02,2020-07-07
-4xoy,2015-08-12,2015-01-16
-7xod,2022-06-15,2022-05-01
-7xo6,2022-06-15,2022-05-01
-7xob,2022-06-15,2022-05-01
-5xob,2018-08-29,2017-05-27
-4xo7,2016-02-17,2015-01-16
-2xo6,2010-10-13,2010-08-09
-5xox,2017-07-12,2017-05-31
-6xof,2021-02-10,2020-07-07
-1xor,2004-12-14,2004-10-06
-2xo2,2011-08-03,2010-08-09
-2xod,2010-08-25,2010-08-14
-7xow,2022-07-20,2022-05-01
-6xo3,2021-01-06,2020-07-06
-4xol,2015-10-14,2015-01-16
-5xoi,2018-06-13,2017-05-28
-7xoh,2022-05-25,2022-05-01
-7xo7,2022-06-15,2022-05-01
-6xoy,2021-02-03,2020-07-07
-5xog,2017-08-16,2017-05-28
-4xoi,2015-07-15,2015-01-16
-6xov,2021-07-07,2020-07-07
-2xom,2010-09-08,2010-08-20
-7xoc,2022-06-15,2022-05-01
-2xoz,2010-09-29,2010-08-24
-4xoc,2016-01-27,2015-01-16
-4xot,2016-01-27,2015-01-16
-1xom,2004-12-14,2004-10-06
-6xop,2021-06-02,2020-07-07
-8xoa,2024-05-08,2023-12-31
-5xo8,2018-05-02,2017-05-27
-4xog,2016-02-03,2015-01-16
-2xo3,2011-08-03,2010-08-09
-1xoz,2004-12-14,2004-10-07
-6xol,2021-06-02,2020-07-07
-1xo5,2004-12-07,2004-10-05
-7xov,2022-07-20,2022-05-01
-6xo2,2021-05-19,2020-07-06
-7xoz,2023-11-08,2022-05-02
-7xog,2024-03-20,2022-05-01
-1xoi,2005-04-12,2004-10-06
-1xox,2005-01-18,2004-10-07
-1xos,2004-12-14,2004-10-06
-6xog,2021-03-10,2020-07-07
-4xo3,2016-01-27,2015-01-16
-1xoe,2005-01-11,2004-10-06
-5xo2,2017-10-25,2017-05-25
-1xo2,2005-03-01,2004-10-05
-4xo4,2016-01-27,2015-01-16
-8xop,2024-03-27,2024-01-02
-7xoy,2022-05-25,2022-05-01
-5xoj,2017-08-16,2017-05-29
-7xo5,2022-06-15,2022-05-01
-5xoh,2018-05-23,2017-05-28
-2xon,2010-09-08,2010-08-20
-6xoj,2021-01-06,2020-07-07
-5xof,2017-10-25,2017-05-28
-8xo9,2024-05-08,2023-12-31
-5xo7,2018-05-02,2017-05-27
-4xop,2016-01-27,2015-01-16
-1xov,2005-10-18,2004-10-07
-4xoe,2016-01-27,2015-01-16
-2xoc,2010-09-29,2010-08-11
-4xoj,2015-08-12,2015-01-16
-7xoa,2022-06-15,2022-05-01
-6xoq,2021-06-02,2020-07-07
-6xoz,2020-11-04,2020-07-07
-1xog,2005-01-11,2004-10-06
-7xo4,2022-06-15,2022-04-30
-2xoe,2010-08-25,2010-08-14
-7xo9,2022-06-15,2022-05-01
-2xok,2010-09-22,2010-08-18
-7xot,2023-05-03,2022-05-01
-8xon,2024-03-27,2024-01-01
-7xou,2022-07-20,2022-05-01
-4xoo,2016-02-17,2015-01-16
-4xoq,2016-02-17,2015-01-16
-5xoy,2017-09-13,2017-05-31
-1xoq,2004-12-14,2004-10-06
-8xox,2024-01-24,2024-01-02
-4xo6,2016-02-17,2015-01-16
-2xow,2010-10-13,2010-08-24
-1xow,2004-11-16,2004-10-07
-2xog,2011-01-19,2010-08-16
-4xoz,2015-08-12,2015-01-16
-5xot,2017-06-14,2017-05-31
-8xov,2024-03-06,2024-01-02
-1xot,2004-12-14,2004-10-06
-1xon,2004-12-14,2004-10-06
-2xot,2011-09-21,2010-08-23
-2xo8,2011-05-25,2010-08-10
-5xom,2018-04-11,2017-05-29
-5xow,2017-10-04,2017-05-31
-1xoc,2005-01-25,2004-10-06
-1xok,2005-01-04,2004-10-06
-4xor,2016-01-27,2015-01-16
-5xou,2017-10-04,2017-05-31
-5xoq,2018-05-30,2017-05-30
-4xou,2015-06-10,2015-01-16
-4xob,2016-01-27,2015-01-16
-2xoi,2011-01-19,2010-08-17
-7xoi,2022-06-15,2022-05-01
-4xo5,2016-01-20,2015-01-16
-4xo8,2016-01-27,2015-01-16
-4xon,2016-01-27,2015-01-16
-2xoy,2010-09-29,2010-08-24
-7xoe,2024-02-14,2022-05-01
-6xoi,2021-03-24,2020-07-07
-6xok,2020-10-14,2020-07-07
-2kg0,2010-06-09,2009-03-02
-6kgc,2020-07-08,2019-07-11
-7kg7,2021-03-10,2020-10-16
-4kga,2014-04-30,2013-04-29
-3kgr,2009-12-22,2009-10-29
-1kgz,2002-10-23,2001-11-28
-7kgn,2020-11-25,2020-10-18
-6kg2,2019-11-13,2019-07-10
-6kgf,2020-07-08,2019-07-11
-5kgu,2016-06-22,2016-06-13
-5kgh,2016-07-06,2016-06-13
-3kgy,2009-11-24,2009-10-29
-4kgn,2013-05-08,2013-04-29
-5kga,2016-07-06,2016-06-13
-1kgn,2001-12-21,2001-11-28
-6kgu,2020-03-11,2019-07-12
-5kge,2017-08-09,2016-06-13
-7kg9,2021-10-20,2020-10-16
-4kgi,2013-06-19,2013-04-29
-5kg0,2016-06-29,2016-06-12
-6kgd,2020-07-08,2019-07-11
-7kgr,2021-01-20,2020-10-18
-6kgh,2020-03-11,2019-07-11
-3kg6,2010-01-19,2009-10-28
-4kg0,2014-01-15,2013-04-28
-7kg6,2021-03-10,2020-10-16
-3kg2,2009-12-08,2009-10-28
-5kg2,2016-06-22,2016-06-12
-3kgg,2010-04-07,2009-10-29
-2kga,2009-04-14,2009-03-07
-4kgv,2013-11-27,2013-04-29
-6kgl,2020-03-25,2019-07-12
-8kgt,2024-04-03,2023-08-19
-8kgr,2024-04-03,2023-08-19
-2kgc,2009-04-14,2009-03-08
-4kgx,2013-11-27,2013-04-29
-1kgp,2001-12-21,2001-11-28
-7kg4,2021-10-20,2020-10-15
-8kg8,2023-12-06,2023-08-17
-6kgv,2020-03-11,2019-07-12
-8kg9,2023-12-06,2023-08-17
-5kg3,2016-06-22,2016-06-12
-2kge,2009-04-14,2009-03-08
-1kgb,2001-12-05,2001-11-26
-5kgd,2017-08-09,2016-06-13
-3kgd,2010-04-21,2009-10-28
-6kge,2020-07-08,2019-07-11
-1kgo,2001-12-21,2001-11-28
-1kgi,2002-11-27,2001-11-27
-6kgi,2020-01-22,2019-07-11
-2kgo,2009-03-31,2009-03-13
-3kgc,2009-12-15,2009-10-28
-2kg6,2009-04-14,2009-03-06
-7kg0,2021-03-10,2020-10-15
-7kgp,2021-01-20,2020-10-18
-1kgx,2002-01-16,2001-11-28
-5kgk,2017-08-09,2016-06-13
-2kgb,2009-03-24,2009-03-07
-1kgl,2002-06-19,2001-11-27
-7kgi,2021-03-10,2020-10-16
-4kgm,2013-08-14,2013-04-29
-7kgh,2021-03-10,2020-10-16
-6kgp,2020-03-25,2019-07-12
-7kgt,2021-01-20,2020-10-18
-5kg1,2016-06-22,2016-06-12
-8kg6,2023-12-06,2023-08-17
-7kgy,2021-11-10,2020-10-19
-1kgq,2002-04-03,2001-11-28
-7kgg,2021-03-10,2020-10-16
-7kgq,2021-01-20,2020-10-18
-4kg5,2014-10-29,2013-04-28
-3kgw,2009-12-15,2009-10-29
-4kgc,2014-03-26,2013-04-29
-7kgz,2021-11-10,2020-10-19
-1kgw,2002-01-16,2001-11-28
-3kgp,2009-12-01,2009-10-29
-6kgm,2020-03-25,2019-07-12
-6kgr,2020-03-25,2019-07-12
-5kgj,2016-07-06,2016-06-13
-5kg5,2016-06-22,2016-06-12
-1kgt,2002-04-03,2001-11-28
-4kgl,2013-09-18,2013-04-29
-2kgi,2009-05-05,2009-03-12
-5kgn,2017-04-05,2016-06-13
-7kg1,2021-03-10,2020-10-15
-5kgt,2017-06-14,2016-06-13
-8kgs,2024-04-03,2023-08-19
-5kgr,2017-02-15,2016-06-13
-4kgk,2013-08-14,2013-04-29
-3kgz,2009-11-24,2009-10-29
-7kg2,2021-10-20,2020-10-15
-5kgp,2016-07-06,2016-06-13
-6kgo,2020-03-25,2019-07-12
-5kgw,2016-10-19,2016-06-13
-7kgx,2021-05-05,2020-10-19
-3kgq,2010-10-27,2009-10-29
-6kgt,2020-03-11,2019-07-12
-7kg8,2021-03-10,2020-10-16
-5kgl,2017-04-05,2016-06-13
-7kgb,2022-01-19,2020-10-16
-7kgm,2020-11-25,2020-10-17
-3kgu,2010-03-23,2009-10-29
-2kg8,2009-04-14,2009-03-06
-6kgs,2020-03-11,2019-07-12
-2kgd,2009-04-14,2009-03-08
-6kgb,2020-07-22,2019-07-11
-3kga,2010-01-26,2009-10-28
-5kgi,2017-08-09,2016-06-13
-6kg1,2019-10-16,2019-07-09
-3kgx,2009-11-10,2009-10-29
-6kgq,2020-03-25,2019-07-12
-1kgu,2002-01-16,2001-11-28
-5kgm,2017-04-05,2016-06-13
-5kg4,2016-06-22,2016-06-12
-2kg9,2009-04-14,2009-03-07
-7kgs,2021-01-20,2020-10-18
-4kg9,2013-11-13,2013-04-29
-1kg8,2001-12-05,2001-11-26
-4kg3,2013-08-21,2013-04-28
-4kgz,2013-11-27,2013-04-29
-4kgd,2013-06-12,2013-04-29
-4kgj,2013-09-18,2013-04-29
-6kg0,2019-10-16,2019-07-09
-5kg7,2016-06-22,2016-06-12
-2kgk,2009-05-12,2009-03-12
-4kgg,2013-08-07,2013-04-29
-6kgw,2020-03-11,2019-07-12
-5kgx,2016-10-19,2016-06-13
-6kgy,2020-02-05,2019-07-12
-4kgq,2013-07-10,2013-04-29
-6kg7,2019-09-04,2019-07-11
-5kgo,2016-08-17,2016-06-13
-7kgu,2021-06-23,2020-10-18
-5kgg,2017-08-09,2016-06-13
-2kgg,2009-05-05,2009-03-11
-1kgj,2002-11-27,2001-11-27
-3kgt,2010-03-23,2009-10-29
-7kgw,2021-05-05,2020-10-19
-6kgn,2020-03-25,2019-07-12
-3kgf,2010-07-28,2009-10-29
-4kgh,2013-09-25,2013-04-29
-5kg6,2016-06-29,2016-06-12
-7kgo,2021-01-20,2020-10-18
-6kg9,2020-07-08,2019-07-11
-5kgs,2017-06-14,2016-06-13
-2kg1,2010-06-09,2009-03-02
-4kg2,2014-10-29,2013-04-28
-7kg5,2021-10-20,2020-10-15
-8kg2,2024-05-29,2023-08-17
-1kg9,2001-12-05,2001-11-26
-6kgk,2020-03-25,2019-07-12
-5k27,2017-05-24,2016-05-18
-3k2r,2010-10-13,2009-09-30
-3k2g,2009-10-13,2009-09-30
-6k28,2019-07-10,2019-05-13
-1k2i,2001-12-05,2001-09-27
-2k2c,2008-04-15,2008-03-31
-4k2i,2013-10-16,2013-04-09
-5k2z,2016-10-05,2016-05-19
-6k2v,2020-05-20,2019-05-15
-1k2t,2003-03-04,2001-09-28
-4k2z,2013-05-01,2013-04-10
-1k2m,2001-12-05,2001-09-28
-6k2p,2020-05-20,2019-05-15
-1k20,2001-10-31,2001-09-26
-1k23,2001-10-31,2001-09-26
-1k2u,2003-03-04,2001-09-28
-6k2m,2019-05-29,2019-05-15
-4k2h,2013-04-24,2013-04-09
-4k2m,2013-10-16,2013-04-09
-7k2k,2021-04-07,2020-09-08
-5k2c,2016-09-21,2016-05-18
-4k20,2014-04-09,2013-04-07
-3k2o,2009-11-03,2009-09-30
-7k2l,2021-04-07,2020-09-08
-1k2e,2002-04-03,2001-09-26
-3k28,2010-01-19,2009-09-29
-6k2u,2020-03-18,2019-05-15
-7k2q,2021-04-07,2020-09-08
-1k2r,2003-03-04,2001-09-28
-3k2x,2009-10-13,2009-09-30
-4k2x,2013-05-15,2013-04-09
-3k27,2009-12-15,2009-09-29
-1k2v,2002-04-17,2001-09-29
-7k2y,2020-11-04,2020-09-09
-3k22,2010-08-11,2009-09-29
-4k2s,2014-04-09,2013-04-09
-7k2u,2020-10-21,2020-09-09
-6k2x,2020-05-20,2019-05-15
-3k2f,2009-11-17,2009-09-30
-8k2i,2024-04-24,2023-07-12
-4k26,2014-04-09,2013-04-08
-1k2s,2003-03-04,2001-09-28
-5k2m,2016-09-07,2016-05-19
-3k21,2010-01-26,2009-09-29
-3k2l,2009-10-13,2009-09-30
-3k2i,2009-10-20,2009-09-30
-3k2q,2009-11-17,2009-09-30
-1k22,2002-05-08,2001-09-26
-8k2f,2024-04-24,2023-07-12
-5k2g,2016-09-14,2016-05-18
-7k21,2020-11-04,2020-09-08
-3k2h,2009-10-13,2009-09-30
-7k2d,2021-04-07,2020-09-08
-8k2m,2024-04-24,2023-07-12
-6k23,2020-05-13,2019-05-13
-3k24,2010-03-23,2009-09-29
-2k2f,2008-07-29,2008-04-01
-4k2p,2013-07-10,2013-04-09
-6k24,2020-03-18,2019-05-13
-2k2g,2008-05-20,2008-04-01
-5k2h,2016-09-14,2016-05-18
-7k2m,2021-04-07,2020-09-08
-4k2g,2014-06-18,2013-04-09
-6k2z,2020-06-17,2019-05-15
-1k2b,2002-07-10,2001-09-26
-7k2o,2021-04-07,2020-09-08
-3k2v,2009-12-22,2009-09-30
-5k2a,2016-09-21,2016-05-18
-5k2o,2017-02-08,2016-05-19
-5k2d,2016-09-21,2016-05-18
-6k22,2020-03-25,2019-05-13
-6k2n,2019-10-09,2019-05-15
-8k20,2024-04-03,2023-07-11
-6k21,2019-10-02,2019-05-13
-1k2f,2001-12-28,2001-09-26
-4k2f,2014-06-18,2013-04-09
-6k26,2020-05-20,2019-05-13
-8k2h,2024-04-24,2023-07-12
-1k28,2002-02-06,2001-09-26
-6k2w,2020-05-20,2019-05-15
-5k2f,2016-09-14,2016-05-18
-2k2n,2008-09-23,2008-04-04
-7k20,2020-11-04,2020-09-08
-1k21,2002-05-08,2001-09-26
-7k2t,2021-01-13,2020-09-09
-8k2g,2024-04-24,2023-07-12
-7k2f,2021-04-07,2020-09-08
-7k28,2021-04-07,2020-09-08
-3k23,2009-10-27,2009-09-29
-4k28,2013-04-17,2013-04-08
-1k2o,2001-10-17,2001-09-28
-1k2x,2003-09-09,2001-09-30
-4k21,2014-04-09,2013-04-07
-6k2s,2020-05-20,2019-05-15
-5k2b,2016-09-21,2016-05-18
-7k2e,2021-04-07,2020-09-08
-8k2k,2024-04-24,2023-07-12
-7k2i,2021-04-07,2020-09-08
-7k26,2020-11-11,2020-09-08
-1k2c,2002-07-10,2001-09-26
-7k2r,2021-04-07,2020-09-08
-4k2k,2013-04-24,2013-04-09
-5k25,2016-10-12,2016-05-18
-7k2n,2021-04-07,2020-09-08
-3k2u,2009-12-15,2009-09-30
-1k2d,2003-03-04,2001-09-26
-6k2k,2019-07-10,2019-05-14
-7k2h,2021-04-07,2020-09-08
-5k21,2016-12-07,2016-05-18
-4k2l,2013-04-24,2013-04-09
-6k2o,2019-10-09,2019-05-15
-7k2j,2021-04-07,2020-09-08
-3k2s,2010-04-07,2009-09-30
-2k2d,2008-04-15,2008-03-31
-3k2d,2010-10-13,2009-09-30
-1k27,2003-09-30,2001-09-26
-7k2s,2021-04-07,2020-09-08
-6k2l,2019-06-12,2019-05-14
-3k2b,2010-06-09,2009-09-29
-7k27,2021-09-22,2020-09-08
-7k2p,2021-04-07,2020-09-08
-6k2q,2019-05-29,2019-05-15
-2k2v,2009-04-21,2008-04-13
-4k24,2014-02-26,2013-04-08
-6k27,2019-10-02,2019-05-13
-7k2w,2020-11-04,2020-09-09
-3k2p,2010-02-09,2009-09-30
-7k2g,2021-04-07,2020-09-08
-1k26,2002-04-03,2001-09-26
-1k2n,2001-12-05,2001-09-28
-5k2e,2016-09-14,2016-05-18
-1k24,2002-03-27,2001-09-26
-3k26,2009-12-15,2009-09-29
-6k20,2020-05-13,2019-05-13
-8k2x,2023-11-29,2023-07-14
-4k25,2013-05-08,2013-04-08
-1k2y,2002-02-13,2001-09-30
-6k2t,2020-05-20,2019-05-15
-4k2r,2013-05-08,2013-04-09
-4k2y,2013-05-29,2013-04-09
-6k2r,2020-05-20,2019-05-15
-8k2w,2023-11-29,2023-07-14
-7ycr,2023-11-22,2022-07-01
-2yc3,2011-08-24,2011-03-11
-4ycv,2015-06-24,2015-02-20
-7yc1,2022-11-16,2022-06-30
-4ycx,2015-08-05,2015-02-20
-2yc5,2011-08-24,2011-03-11
-4yck,2016-03-02,2015-02-20
-2ycs,2011-11-16,2011-03-16
-7ycp,2023-11-22,2022-07-01
-7ycl,2023-02-01,2022-07-01
-8yc0,2024-05-08,2024-02-17
-2ycj,2011-06-08,2011-03-16
-6ycq,2020-09-09,2020-03-18
-5ycf,2018-09-12,2017-09-07
-5ycp,2018-09-12,2017-09-07
-2ycl,2011-06-08,2011-03-16
-2ycp,2011-09-14,2011-03-16
-2ycd,2012-03-28,2011-03-13
-1yce,2005-04-12,2004-12-22
-1ycs,1997-11-19,1996-09-30
-5yc4,2018-01-24,2017-09-06
-7yct,2024-01-24,2022-07-01
-1yc3,2005-02-22,2004-12-21
-5yc7,2018-10-03,2017-09-06
-2ycf,2011-11-16,2011-03-14
-7yca,2023-04-26,2022-07-01
-4ycp,2015-04-22,2015-02-20
-6ycs,2020-04-29,2020-03-19
-7yce,2022-08-10,2022-07-01
-5yc5,2018-03-21,2017-09-06
-5yck,2017-09-27,2017-09-07
-2ycm,2011-08-24,2011-03-16
-2ycc,1992-07-15,1991-01-29
-7yc6,2023-06-14,2022-06-30
-1ycp,1998-05-06,1997-05-01
-5yco,2017-11-15,2017-09-07
-5yci,2018-09-19,2017-09-07
-6yc3,2020-04-08,2020-03-18
-5ycd,2018-09-12,2017-09-07
-5ycj,2018-09-19,2017-09-07
-7ycx,2023-03-15,2022-07-02
-4ycu,2015-06-10,2015-02-20
-7ycq,2023-05-03,2022-07-01
-6ycc,2020-11-25,2020-03-18
-5yc3,2018-01-24,2017-09-06
-6yc2,2020-04-08,2020-03-18
-6ycm,2021-02-17,2020-03-18
-1ych,2005-04-19,2004-12-22
-1ycl,2005-03-15,2004-12-22
-5yc6,2018-10-03,2017-09-06
-2ycn,2011-09-14,2011-03-16
-6yck,2021-02-17,2020-03-18
-7ycc,2022-08-10,2022-07-01
-6yc4,2020-04-08,2020-03-18
-5ycn,2018-09-12,2017-09-07
-1ycm,2005-04-19,2004-12-22
-4ycw,2015-06-10,2015-02-20
-6yce,2020-11-25,2020-03-18
-7ycf,2024-01-24,2022-07-01
-2yct,2011-09-14,2011-03-16
-6yco,2021-02-17,2020-03-18
-4yc4,2015-07-15,2015-02-19
-2ycb,2011-05-25,2011-03-13
-7ycm,2023-11-22,2022-07-01
-1yca,1994-01-31,1993-08-10
-1ycc,1991-07-15,1990-05-09
-5yce,2018-09-19,2017-09-07
-7yc3,2022-11-16,2022-06-30
-7ycn,2023-02-01,2022-07-01
-7yc7,2023-11-22,2022-07-01
-5ycb,2018-09-12,2017-09-07
-6ycl,2021-02-17,2020-03-18
-1ycg,2005-04-19,2004-12-22
-1ycb,1994-01-31,1993-08-10
-6ycz,2020-11-11,2020-03-19
-7yck,2023-02-01,2022-07-01
-2ych,2011-05-11,2011-03-15
-2ycr,2011-11-16,2011-03-16
-4ycy,2016-03-02,2015-02-20
-2yc0,2011-03-30,2011-03-10
-6ycd,2020-11-25,2020-03-18
-6yc5,2020-08-12,2020-03-18
-6ych,2021-02-17,2020-03-18
-4ych,2016-02-24,2015-02-20
-2yck,2011-06-08,2011-03-16
-2ycg,2011-03-30,2011-03-14
-7yc2,2023-12-06,2022-06-30
-2ycw,2011-06-01,2011-03-17
-7ycd,2024-01-24,2022-07-01
-6yc8,2021-02-10,2020-03-18
-4yci,2015-03-04,2015-02-20
-4yca,2015-03-11,2015-02-19
-5ycc,2018-09-12,2017-09-07
-6ycr,2021-02-03,2020-03-18
-5yc8,2018-11-21,2017-09-06
-2ycx,2011-06-01,2011-03-17
-6ycp,2021-02-17,2020-03-18
-6yca,2020-09-09,2020-03-18
-4ycs,2015-03-18,2015-02-20
-6ycg,2020-11-25,2020-03-18
-1ycf,2005-04-19,2004-12-22
-4ycm,2016-01-13,2015-02-20
-2ycy,2011-06-08,2011-03-17
-1yc9,2005-03-01,2004-12-22
-6ycu,2020-04-08,2020-03-19
-5ycs,2018-02-21,2017-09-08
-4yct,2016-03-02,2015-02-20
-2yca,2012-03-28,2011-03-12
-7yco,2023-07-05,2022-07-01
-4ycg,2015-03-04,2015-02-20
-6yc1,2020-04-08,2020-03-18
-1yc2,2005-03-29,2004-12-21
-2ycz,2011-06-01,2011-03-17
-6yc7,2021-03-24,2020-03-18
-1ycj,2005-02-01,2004-12-22
-6ycj,2021-02-17,2020-03-18
-2yc2,2011-03-23,2011-03-11
-1ycd,2005-05-10,2004-12-22
-2ycq,2011-11-16,2011-03-16
-6yct,2021-02-17,2020-03-19
-4yc0,2015-11-18,2015-02-19
-4ycn,2016-01-13,2015-02-20
-4ycb,2016-02-24,2015-02-19
-6ycw,2020-04-08,2020-03-19
-7ycb,2024-01-24,2022-07-01
-2yc4,2011-03-23,2011-03-11
-5ycg,2018-09-19,2017-09-07
-5ycr,2018-02-21,2017-09-08
-4yc7,2015-05-13,2015-02-19
-1yc5,2005-04-26,2004-12-21
-1yc4,2005-02-22,2004-12-21
-2yce,2011-04-27,2011-03-14
-7yc5,2023-07-05,2022-06-30
-7yc9,2023-05-17,2022-07-01
-4yco,2015-04-22,2015-02-20
-4yce,2016-02-24,2015-02-19
-6yci,2021-02-17,2020-03-18
-4yc9,2015-06-24,2015-02-19
-5yc1,2017-10-11,2017-09-06
-4ycl,2015-04-01,2015-02-20
-6ycf,2020-11-25,2020-03-18
-6ycy,2020-11-11,2020-03-19
-1yc1,2005-02-22,2004-12-21
-6ycn,2021-02-17,2020-03-18
-6yc0,2020-04-08,2020-03-18
-5ych,2018-09-19,2017-09-07
-1yci,2005-05-31,2004-12-22
-6ycx,2020-11-11,2020-03-19
-4yc8,2016-03-02,2015-02-19
-6j07,2019-02-27,2018-12-21
-4j06,2013-04-17,2013-01-30
-3j06,2011-06-01,2011-04-26
-8j02,2023-12-13,2023-04-09
-6j00,2019-12-25,2018-12-20
-4j02,2013-04-17,2013-01-30
-1j07,2003-02-04,2002-11-07
-2j0a,2006-09-04,2006-08-01
-2j07,2007-05-01,2006-08-01
-4j07,2013-03-06,2013-01-30
-4j0q,2014-02-05,2013-01-31
-1j0d,2003-05-12,2002-11-12
-2j0t,2006-10-18,2006-08-04
-4j0t,2013-05-01,2013-01-31
-5j0u,2016-10-26,2016-03-28
-3j0k,2011-10-19,2011-10-04
-5j0o,2016-10-26,2016-03-28
-5j0s,2016-10-26,2016-03-28
-4j0v,2013-05-01,2013-01-31
-1j0i,2003-01-28,2002-11-14
-5j0y,2016-10-26,2016-03-28
-5j0b,2017-04-05,2016-03-28
-5j04,2016-04-20,2016-03-26
-2j0m,2007-07-03,2006-08-03
-6j03,2019-12-25,2018-12-20
-5j0r,2016-10-26,2016-03-28
-2j0v,2006-10-04,2006-08-07
-6j0z,2019-03-06,2018-12-27
-4j09,2014-04-23,2013-01-30
-1j0o,2003-11-19,2002-11-19
-6j0d,2019-11-06,2018-12-24
-6j05,2019-07-03,2018-12-21
-2j0e,2007-01-03,2006-08-02
-3j0l,2011-11-16,2011-10-04
-3j0a,2011-12-28,2011-06-02
-1j06,2003-02-04,2002-11-07
-4j08,2013-04-17,2013-01-30
-8j0w,2023-05-03,2023-04-12
-1j0e,2003-05-12,2002-11-12
-2j0k,2007-07-03,2006-08-03
-8j0k,2023-07-05,2023-04-11
-2j0y,2007-01-23,2006-08-08
-3j0p,2011-11-16,2011-10-06
-1j0n,2003-04-01,2002-11-19
-5j03,2016-09-07,2016-03-26
-8j0o,2024-04-03,2023-04-11
-4j0a,2013-04-17,2013-01-30
-1j01,2002-11-06,2002-10-25
-1j0h,2003-01-28,2002-11-14
-5j0p,2016-10-26,2016-03-28
-4j0h,2013-05-22,2013-01-30
-5j0q,2016-10-26,2016-03-28
-6j0p,2019-11-06,2018-12-25
-4j0b,2014-01-22,2013-01-30
-4j0r,2013-02-13,2013-01-31
-2j0h,2007-01-23,2006-08-03
-8j0n,2024-04-03,2023-04-11
-1j0k,2003-01-28,2002-11-14
-8j0r,2023-07-05,2023-04-11
-1j0j,2003-01-28,2002-11-14
-1j09,2003-02-25,2002-11-12
-4j04,2013-04-17,2013-01-30
-2j0s,2006-09-06,2006-08-04
-8j01,2023-12-13,2023-04-09
-3j0o,2011-11-16,2011-10-05
-2j0p,2006-08-29,2006-08-04
-8j00,2023-11-29,2023-04-09
-1j0z,2003-06-17,2002-11-25
-6j0g,2019-04-03,2018-12-24
-5j0w,2016-10-26,2016-03-28
-3j0j,2011-12-14,2011-08-24
-6j0k,2019-04-03,2018-12-24
-1j04,2003-11-11,2002-10-30
-1j0c,2003-05-12,2002-11-12
-1j0p,2003-11-19,2002-11-19
-6j0h,2019-07-24,2018-12-24
-6j06,2019-04-03,2018-12-21
-4j0k,2013-05-22,2013-01-31
-8j0d,2023-10-25,2023-04-10
-2j0g,2007-01-23,2006-08-03
-1j0a,2003-05-12,2002-11-12
-3j0q,2011-11-16,2011-10-11
-4j0d,2013-05-22,2013-01-30
-8j0e,2024-04-17,2023-04-10
-8j0x,2023-05-03,2023-04-12
-5j0x,2016-10-26,2016-03-28
-8j04,2023-12-06,2023-04-09
-2j09,2007-05-01,2006-08-01
-4j0p,2013-12-25,2013-01-31
-8j0i,2024-04-17,2023-04-11
-2j0w,2006-08-10,2006-08-07
-8j0t,2024-05-22,2023-04-11
-1j0b,2003-05-12,2002-11-12
-2j0b,2006-09-04,2006-08-01
-4j0s,2013-02-13,2013-01-31
-1j0m,2003-04-01,2002-11-19
-8j0g,2024-04-17,2023-04-10
-8j0j,2023-11-22,2023-04-11
-2j0x,2006-08-10,2006-08-07
-2j0j,2007-06-26,2006-08-03
-2j0u,2006-09-06,2006-08-04
-8j0z,2023-05-03,2023-04-12
-4j0m,2013-07-24,2013-01-31
-4j00,2013-03-27,2013-01-30
-4j0y,2013-05-01,2013-01-31
-1j0y,2003-06-17,2002-11-25
-5j0t,2016-10-26,2016-03-28
-8j0v,2023-05-03,2023-04-12
-6j0t,2020-01-01,2018-12-26
-8j03,2023-12-06,2023-04-09
-2j08,2007-05-01,2006-08-01
-4j0j,2013-05-22,2013-01-31
-4j0z,2013-05-01,2013-01-31
-1j02,2003-09-02,2002-10-28
-5j0a,2016-09-07,2016-03-28
-8j0u,2023-05-03,2023-04-12
-1j0x,2003-12-09,2002-11-25
-5j06,2017-04-05,2016-03-27
-4j0n,2013-02-20,2013-01-31
-2j0f,2006-10-11,2006-08-02
-2j0l,2007-06-26,2006-08-03
-4j03,2013-06-05,2013-01-30
-8j0y,2023-05-03,2023-04-12
-4j0g,2013-05-22,2013-01-30
-1j0q,2003-08-12,2002-11-20
-4j0l,2013-10-16,2013-01-31
-8j0s,2024-05-22,2023-04-11
-6j0e,2019-07-03,2018-12-24
-2j0d,2006-09-04,2006-08-02
-8j0f,2024-04-17,2023-04-10
-6j02,2019-11-13,2018-12-20
-5j0d,2016-10-05,2016-03-28
-2j0q,2006-08-30,2006-08-04
-6vfv,2020-03-11,2020-01-06
-1vfl,2005-08-16,2004-04-16
-7vfc,2022-09-14,2021-09-12
-3vf7,2012-11-21,2012-01-09
-6vff,2020-07-01,2020-01-03
-7vfr,2022-09-14,2021-09-13
-6vf9,2021-09-01,2020-01-03
-2vfu,2008-01-08,2007-11-05
-6vf0,2021-09-01,2020-01-03
-6vf6,2021-09-01,2020-01-03
-1vft,2004-09-14,2004-04-19
-3vf2,2012-01-25,2012-01-09
-6vf5,2021-09-01,2020-01-03
-3vfk,2013-01-09,2012-01-09
-6vf2,2021-09-01,2020-01-03
-1vfo,2005-02-08,2004-04-16
-5vfb,2017-04-19,2017-04-07
-7vf7,2022-09-14,2021-09-10
-1vf3,2005-08-23,2004-04-07
-8vfh,2024-05-08,2023-12-21
-7vf3,2022-08-17,2021-09-10
-3vfw,2012-02-22,2012-01-10
-2vfl,2008-05-06,2007-11-05
-7vf4,2021-10-06,2021-09-10
-1vfx,2004-08-10,2004-04-19
-5vf2,2017-12-06,2017-04-06
-5vfm,2017-12-20,2017-04-08
-6vfr,2020-03-11,2020-01-06
-1vf1,2005-08-23,2004-04-07
-1vfy,1999-05-06,1999-04-26
-8vff,2024-05-15,2023-12-21
-2vfc,2007-12-18,2007-11-02
-2vfa,2008-06-17,2007-11-02
-6vf8,2021-09-01,2020-01-03
-5vff,2018-04-11,2017-04-07
-7vfp,2022-11-09,2021-09-13
-5vft,2018-07-18,2017-04-09
-8vfc,2024-05-08,2023-12-21
-8vf3,2024-05-08,2023-12-21
-7vfi,2022-10-19,2021-09-13
-7vfl,2021-11-24,2021-09-13
-5vfu,2018-07-18,2017-04-09
-6vfu,2020-03-11,2020-01-06
-3vf1,2012-05-16,2012-01-09
-6vfx,2020-01-22,2020-01-06
-8vfp,2024-05-08,2023-12-21
-8vfb,2024-05-08,2023-12-21
-5vf4,2017-05-24,2017-04-06
-7vfq,2022-09-14,2021-09-13
-1vfp,2004-07-06,2004-04-18
-5vfc,2017-06-28,2017-04-07
-1vfh,2004-09-14,2004-04-13
-7vfs,2021-11-03,2021-09-13
-5vfq,2018-07-18,2017-04-09
-2vf6,2007-11-06,2007-10-31
-1vfz,2004-08-10,2004-04-19
-6vf1,2021-09-01,2020-01-03
-1vfn,1997-11-12,1996-10-08
-2vfm,2008-12-16,2007-11-05
-2vf8,2008-12-16,2007-10-31
-5vfi,2018-02-28,2017-04-07
-6vf4,2021-09-01,2020-01-03
-8vfr,2024-05-08,2023-12-21
-2vf7,2008-12-16,2007-10-31
-2vfx,2008-03-18,2007-11-05
-8vf8,2024-05-08,2023-12-21
-6vfc,2021-09-01,2020-01-03
-5vfd,2017-06-07,2017-04-07
-7vfx,2022-09-21,2021-09-14
-1vfs,2004-09-14,2004-04-19
-3vfm,2012-03-07,2012-01-10
-7vf6,2023-05-24,2021-09-10
-8vfg,2024-05-08,2023-12-21
-3vfv,2012-02-22,2012-01-10
-8vfk,2024-05-01,2023-12-21
-7vfv,2021-11-03,2021-09-13
-8vfe,2024-05-08,2023-12-21
-3vf6,2012-02-08,2012-01-09
-2vfk,2008-05-06,2007-11-05
-7vf0,2021-11-10,2021-09-10
-2vfp,2008-12-16,2007-11-05
-3vf3,2012-11-21,2012-01-09
-5vf5,2017-12-06,2017-04-06
-6vfp,2020-03-11,2020-01-06
-5vfj,2017-12-20,2017-04-07
-5vfz,2018-04-18,2017-04-10
-1vf2,2005-08-23,2004-04-07
-6vfd,2020-08-05,2020-01-03
-2vf9,2008-09-23,2007-11-01
-7vfu,2021-11-03,2021-09-13
-3vfb,2012-11-21,2012-01-09
-8vfv,2024-05-15,2023-12-22
-3vfa,2012-11-21,2012-01-09
-1vfv,2004-08-10,2004-04-19
-2vfs,2008-01-08,2007-11-05
-3vfj,2013-01-09,2012-01-09
-7vfw,2021-11-03,2021-09-13
-6vfw,2020-03-11,2020-01-06
-3vfl,2013-06-12,2012-01-10
-6vfb,2021-09-01,2020-01-03
-8vf9,2024-05-08,2023-12-21
-3vf9,2012-05-02,2012-01-09
-6vfz,2020-02-05,2020-01-07
-6vft,2020-03-11,2020-01-06
-7vf9,2022-07-27,2021-09-10
-3vf4,2012-01-25,2012-01-09
-6vfl,2020-07-22,2020-01-05
-5vf0,2017-05-17,2017-04-06
-3vf8,2012-05-02,2012-01-09
-6vfo,2020-06-17,2020-01-06
-3vft,2012-02-22,2012-01-10
-3vfs,2012-02-22,2012-01-10
-5vf9,2017-05-17,2017-04-07
-1vfg,2004-08-10,2004-04-13
-8vfi,2024-05-15,2023-12-21
-5vfn,2017-12-27,2017-04-08
-6vfs,2020-01-22,2020-01-06
-2vfq,2008-12-16,2007-11-05
-3vfq,2013-03-13,2012-01-10
-1vfe,1997-04-01,1996-10-01
-2vft,2008-01-08,2007-11-05
-6vf3,2021-09-01,2020-01-03
-6vfy,2020-01-29,2020-01-06
-3vff,2012-09-19,2012-01-09
-2vfo,2008-12-16,2007-11-05
-6vfa,2021-09-01,2020-01-03
-5vfp,2018-07-18,2017-04-09
-2vfv,2008-01-08,2007-11-05
-2vf0,2007-12-04,2007-10-27
-3vfh,2012-09-19,2012-01-09
-5vfs,2018-07-18,2017-04-09
-3vf5,2012-11-21,2012-01-09
-2vf5,2008-03-04,2007-10-30
-8vf0,2024-05-08,2023-12-21
-1vfr,1999-02-16,1998-01-09
-1vfm,2005-02-08,2004-04-16
-7vfm,2021-11-24,2021-09-13
-6vfq,2020-03-11,2020-01-06
-1vf5,2004-04-20,2004-04-08
-1vfd,1997-04-21,1996-10-01
-1vfu,2005-02-08,2004-04-19
-6vf7,2021-09-01,2020-01-03
-5vfr,2018-07-18,2017-04-09
-2vfr,2008-01-08,2007-11-05
-2vf3,2008-11-25,2007-10-30
-7vfn,2021-11-24,2021-09-13
-5vfg,2018-04-11,2017-04-07
-2vfj,2007-12-04,2007-11-04
-2vfn,2008-12-16,2007-11-05
-2vfz,2007-11-13,2007-11-06
-3vfu,2012-02-22,2012-01-10
-1vfw,2004-08-10,2004-04-19
-8vfj,2024-05-08,2023-12-21
-5vfe,2018-04-11,2017-04-07
-8vfa,2024-05-08,2023-12-21
-3vfe,2012-11-21,2012-01-09
-3e0l,2009-03-03,2008-07-31
-7e09,2022-02-02,2021-01-27
-6e0i,2019-07-10,2018-07-06
-5e0e,2016-02-10,2015-09-28
-1e0p,2000-08-19,2000-04-04
-4e0s,2012-04-18,2012-03-05
-8e0y,2022-10-12,2022-08-09
-3e0p,2008-09-09,2008-07-31
-2e0y,2006-11-28,2006-10-16
-3e08,2008-09-30,2008-07-31
-7e08,2022-02-02,2021-01-27
-5e0i,2015-12-09,2015-09-28
-6e0d,2018-09-19,2018-07-06
-6e05,2018-10-17,2018-07-06
-2e0i,2006-11-28,2006-10-10
-2e07,2007-04-02,2006-10-02
-1e04,2000-06-02,2000-03-09
-7e0u,2021-07-21,2021-01-28
-4e03,2012-06-13,2012-03-02
-8e0d,2022-11-30,2022-08-08
-4e09,2012-06-13,2012-03-02
-7e06,2022-02-02,2021-01-27
-7e03,2021-02-10,2021-01-26
-7e0q,2021-07-21,2021-01-28
-7e00,2022-02-02,2021-01-26
-1e0e,2001-03-19,2000-03-25
-8e0b,2023-08-16,2022-08-08
-3e0d,2008-09-23,2008-07-31
-8e0h,2022-11-30,2022-08-09
-4e0y,2013-02-13,2012-03-05
-4e0u,2012-05-30,2012-03-05
-3e01,2008-11-25,2008-07-30
-2e0l,2007-08-28,2006-10-10
-6e03,2019-07-17,2018-07-05
-8e0c,2023-08-16,2022-08-08
-5e0h,2016-05-04,2015-09-28
-7e0z,2022-04-27,2021-01-28
-1e0x,2001-04-05,2000-04-10
-2e08,2007-04-02,2006-10-02
-6e0s,2018-07-25,2018-07-06
-1e06,2000-12-06,2000-03-10
-6e0y,2019-02-27,2018-07-07
-6e0l,2019-02-20,2018-07-06
-6e08,2018-07-25,2018-07-06
-2e0m,2007-08-28,2006-10-10
-4e00,2013-03-27,2012-03-01
-3e0q,2009-08-18,2008-07-31
-8e0a,2022-11-30,2022-08-08
-4e0h,2012-08-29,2012-03-04
-4e07,2012-06-13,2012-03-02
-6e0a,2018-09-12,2018-07-06
-1e0j,2000-06-09,2000-03-30
-5e0x,2016-05-04,2015-09-29
-8e04,2023-08-30,2022-08-08
-5e0o,2015-10-28,2015-09-29
-4e01,2013-03-27,2012-03-02
-3e0m,2009-06-16,2008-07-31
-3e0i,2009-05-12,2008-07-31
-5e0w,2016-05-04,2015-09-29
-4e06,2012-12-05,2012-03-02
-1e0a,2000-04-18,2000-03-16
-1e08,2000-08-25,2000-03-13
-7e0b,2022-02-02,2021-01-27
-6e0q,2018-11-07,2018-07-06
-8e05,2023-08-30,2022-08-08
-4e0f,2013-10-16,2012-03-03
-8e00,2023-08-30,2022-08-08
-8e0f,2022-10-26,2022-08-09
-5e0r,2016-10-12,2015-09-29
-4e0c,2012-03-14,2012-03-02
-4e0t,2012-05-30,2012-03-05
-6e00,2018-10-17,2018-07-05
-7e0o,2021-07-21,2021-01-28
-6e0v,2019-07-17,2018-07-07
-8e0w,2023-05-10,2022-08-09
-3e0g,2008-09-23,2008-07-31
-5e0a,2015-10-14,2015-09-28
-8e0q,2023-04-19,2022-08-09
-1e0v,2001-04-05,2000-04-10
-5e0g,2016-05-04,2015-09-28
-7e0p,2021-07-21,2021-01-28
-4e05,2012-12-05,2012-03-02
-1e0y,2000-04-12,2000-04-11
-7e02,2021-02-10,2021-01-26
-1e0c,2000-05-08,2000-03-23
-7e0i,2021-06-30,2021-01-28
-2e0s,2006-10-24,2006-10-11
-5e0b,2015-10-14,2015-09-28
-5e0m,2015-12-30,2015-09-29
-5e0f,2016-09-07,2015-09-28
-4e0z,2013-02-13,2012-03-05
-4e0i,2012-08-29,2012-03-04
-2e0a,2007-10-09,2006-10-03
-2e0n,2007-01-16,2006-10-10
-4e0r,2012-11-21,2012-03-05
-4e0w,2012-05-02,2012-03-05
-7e0c,2021-04-07,2021-01-27
-4e0d,2012-06-06,2012-03-02
-7e0g,2021-03-24,2021-01-28
-4e04,2012-07-25,2012-03-02
-4e0x,2012-04-25,2012-03-05
-6e0b,2018-11-14,2018-07-06
-7e0k,2021-06-30,2021-01-28
-4e0j,2013-02-13,2012-03-04
-6e0e,2019-07-10,2018-07-06
-6e0z,2019-02-27,2018-07-07
-4e0p,2013-02-13,2012-03-05
-8e06,2023-08-30,2022-08-08
-6e02,2019-07-17,2018-07-05
-8e0t,2022-10-12,2022-08-09
-3e0y,2008-09-30,2008-08-01
-8e0x,2022-10-12,2022-08-09
-5e0y,2016-09-14,2015-09-29
-6e0h,2019-02-06,2018-07-06
-7e0d,2021-04-07,2021-01-27
-8e0v,2022-10-12,2022-08-09
-8e0e,2023-01-18,2022-08-09
-7e0t,2021-07-21,2021-01-28
-6e06,2018-10-17,2018-07-06
-6e0x,2019-02-27,2018-07-07
-7e0h,2021-06-30,2021-01-28
-8e02,2022-08-24,2022-08-08
-8e09,2022-08-24,2022-08-08
-7e0s,2021-07-21,2021-01-28
-3e03,2008-09-16,2008-07-30
-3e02,2008-08-12,2008-07-30
-5e02,2016-07-06,2015-09-28
-6e0r,2019-05-01,2018-07-06
-8e0r,2023-05-10,2022-08-09
-7e0x,2021-12-08,2021-01-28
-6e04,2019-07-17,2018-07-06
-8e0s,2022-10-12,2022-08-09
-5e00,2017-01-18,2015-09-26
-8e0g,2023-10-18,2022-08-09
-3e0x,2008-09-30,2008-08-01
-1e02,2000-12-06,2000-03-09
-1e0s,2000-04-18,2000-04-06
-7e0a,2021-09-08,2021-01-27
-1e00,2000-12-06,2000-03-07
-1e0o,2000-10-23,2000-04-03
-4e0v,2012-04-25,2012-03-05
-4e02,2013-03-13,2012-03-02
-7e0l,2022-02-02,2021-01-28
-7e07,2022-02-02,2021-01-27
-3e0b,2008-11-25,2008-07-31
-6e0n,2019-02-20,2018-07-06
-7e0j,2021-06-30,2021-01-28
-2e0x,2006-11-28,2006-10-16
-6e07,2018-07-25,2018-07-06
-4e0k,2012-12-19,2012-03-04
-1e05,2000-06-02,2000-03-09
-3e0n,2009-06-16,2008-07-31
-8e03,2022-08-24,2022-08-08
-5e0j,2016-05-04,2015-09-28
-8e0p,2023-05-03,2022-08-09
-3e0f,2008-09-02,2008-07-31
-3e00,2008-10-28,2008-07-30
-7e01,2022-02-02,2021-01-26
-6e0w,2019-07-17,2018-07-07
-2e0p,2007-09-18,2006-10-11
-8eg6,2023-05-10,2022-09-11
-7eg3,2021-06-23,2021-03-24
-4ega,2012-09-12,2012-03-30
-4egd,2012-04-11,2012-03-30
-5egb,2016-02-17,2015-10-26
-2eg3,2008-03-04,2007-02-27
-3egt,2009-05-05,2008-09-11
-4egu,2012-04-18,2012-04-01
-4egp,2013-02-20,2012-03-31
-2egm,2007-09-04,2007-03-01
-2egh,2007-06-19,2007-03-01
-8eg8,2023-03-01,2022-09-12
-2eg5,2007-05-01,2007-02-28
-7eg8,2021-05-05,2021-03-24
-8egw,2023-02-22,2022-09-13
-6egm,2019-04-03,2018-08-20
-7egr,2022-04-06,2021-03-26
-5egl,2016-11-09,2015-10-27
-7egl,2021-05-26,2021-03-24
-7egp,2022-01-12,2021-03-24
-2egn,2007-05-15,2007-03-01
-4eg7,2012-09-12,2012-03-30
-5ega,2016-08-31,2015-10-26
-7egv,2021-06-30,2021-03-26
-5egt,2015-11-11,2015-10-27
-1eg1,1997-08-20,1996-11-26
-2eg6,2007-07-03,2007-02-28
-5eg3,2016-02-03,2015-10-26
-8egz,2023-10-04,2022-09-13
-8egy,2023-10-04,2022-09-13
-4eg3,2012-09-12,2012-03-30
-7eg0,2021-09-29,2021-03-23
-8egu,2023-03-08,2022-09-13
-6egt,2017-11-01,2017-09-12
-7egu,2021-12-15,2021-03-26
-8egn,2022-09-28,2022-09-12
-3egh,2010-03-23,2008-09-10
-4eg1,2012-09-12,2012-03-30
-8eg5,2023-05-10,2022-09-11
-6egs,2018-04-11,2017-09-12
-8egb,2023-03-01,2022-09-12
-6eg8,2019-06-05,2018-08-19
-1egd,1997-06-16,1996-04-11
-8egm,2022-10-05,2022-09-12
-5ege,2016-03-09,2015-10-27
-4egc,2013-02-27,2012-03-30
-4eg5,2012-09-12,2012-03-30
-8egi,2022-11-16,2022-09-12
-5egv,2016-05-04,2015-10-27
-1eg2,2000-10-18,2000-02-11
-2egy,2008-03-04,2007-03-02
-3egi,2009-03-31,2008-09-10
-5eg7,2016-02-10,2015-10-26
-6ego,2019-04-03,2018-08-20
-8egl,2022-09-28,2022-09-12
-2egb,2007-08-28,2007-02-28
-1egc,1997-11-12,1996-04-11
-7eg5,2022-04-20,2021-03-24
-4egi,2012-05-23,2012-03-31
-7egq,2021-07-21,2021-03-25
-6egp,2020-02-26,2018-08-20
-1egv,2001-02-21,2000-02-17
-1egz,1999-03-26,1999-03-18
-2eg7,2007-07-03,2007-02-28
-1egy,2000-03-06,2000-02-17
-3egv,2008-09-23,2008-09-11
-8egx,2023-02-22,2022-09-13
-1egq,2001-02-21,2000-02-16
-6egz,2018-10-10,2017-09-12
-5egc,2016-03-23,2015-10-27
-2egw,2007-09-04,2007-03-02
-4egm,2013-02-20,2012-03-31
-8egf,2023-03-08,2022-09-12
-5egy,2016-04-13,2015-10-27
-3egk,2008-09-30,2008-09-10
-6egu,2017-11-01,2017-09-12
-5egj,2015-11-11,2015-10-27
-8egq,2023-03-08,2022-09-13
-2egp,2007-09-04,2007-03-01
-2egl,2007-09-04,2007-03-01
-1egj,2001-02-15,2000-02-15
-8eg7,2023-03-01,2022-09-11
-4egw,2012-10-31,2012-04-02
-2eg2,2008-03-04,2007-02-27
-4eg8,2012-09-12,2012-03-30
-3eg5,2008-10-14,2008-09-10
-6egy,2018-10-10,2017-09-12
-3eg9,2008-10-21,2008-09-10
-3eg1,2009-09-15,2008-09-10
-6egw,2018-10-10,2017-09-12
-2egd,2008-03-11,2007-02-28
-4egs,2012-10-03,2012-04-01
-5egu,2016-01-20,2015-10-27
-1ege,1997-06-16,1996-04-11
-3egd,2008-10-21,2008-09-10
-1egi,2000-08-30,2000-02-15
-4eg9,2012-04-11,2012-03-30
-2eg8,2007-07-03,2007-02-28
-7eg1,2021-11-03,2021-03-23
-6ege,2019-02-13,2018-08-19
-4eg6,2012-09-12,2012-03-30
-6eg5,2019-08-21,2018-08-18
-8eg0,2023-01-11,2022-09-10
-6eg3,2018-10-31,2018-08-17
-7egc,2021-05-12,2021-03-24
-1egn,2001-05-16,2000-02-16
-1egg,2000-08-30,2000-02-15
-4egh,2012-05-23,2012-03-30
-6ega,2019-02-20,2018-08-19
-7ega,2021-05-05,2021-03-24
-7eg4,2021-09-29,2021-03-24
-7eg9,2021-05-05,2021-03-24
-6egf,2019-02-13,2018-08-19
-6egl,2019-04-03,2018-08-20
-6egd,2019-02-13,2018-08-19
-8egv,2023-02-22,2022-09-13
-6eg0,2018-11-28,2018-08-17
-3egs,2009-08-25,2008-09-11
-7egn,2021-08-18,2021-03-24
-8eg3,2022-12-07,2022-09-10
-4eg4,2012-09-12,2012-03-30
-3egg,2010-03-23,2008-09-10
-5eg1,2016-08-31,2015-10-26
-4egk,2012-05-23,2012-03-31
-1egh,2000-03-01,2000-02-15
-2eg4,2008-03-04,2007-02-27
-5eg2,2016-01-13,2015-10-26
-3egj,2008-09-23,2008-09-10
-6eg2,2018-10-31,2018-08-17
-3egm,2009-07-28,2008-09-11
-1eg5,2000-04-02,2000-02-13
-7egk,2021-05-26,2021-03-24
-1eg9,2000-05-24,2000-02-15
-4ego,2013-02-20,2012-03-31
-6eg1,2018-11-28,2018-08-17
-2egv,2007-09-04,2007-03-02
-5eg5,2016-11-02,2015-10-26
-5egp,2016-02-03,2015-10-27
-7eg7,2021-05-05,2021-03-24
-6egn,2019-04-03,2018-08-20
-5egm,2015-11-18,2015-10-27
-3egz,2008-10-28,2008-09-11
-1egm,2000-09-20,2000-02-15
-3egx,2008-10-21,2008-09-11
-3egw,2010-03-02,2008-09-11
-5egi,2016-10-05,2015-10-27
-5egr,2016-11-09,2015-10-27
-4egn,2013-02-20,2012-03-31
-8egd,2023-03-08,2022-09-12
-6egr,2018-10-10,2017-09-12
-5egs,2016-02-03,2015-10-27
-5eg4,2016-07-13,2015-10-26
-4eg2,2012-05-02,2012-03-30
-4egy,2013-02-06,2012-04-02
-7ego,2022-03-30,2021-03-24
-2egq,2007-09-04,2007-03-01
-6eg9,2019-02-20,2018-08-19
-7egb,2021-05-05,2021-03-24
-7eg2,2021-06-23,2021-03-24
-5egh,2016-03-09,2015-10-27
-2egs,2007-09-04,2007-03-02
-4j6s,2013-10-02,2013-02-11
-2j6f,2006-10-11,2006-09-28
-5j61,2016-09-21,2016-04-04
-6j65,2019-09-25,2019-01-14
-8j6f,2024-03-27,2023-04-25
-6j6q,2019-04-24,2019-01-15
-6j6t,2020-01-22,2019-01-15
-6j63,2019-02-06,2019-01-13
-4j63,2014-01-22,2013-02-11
-8j6r,2023-12-06,2023-04-26
-5j67,2016-05-25,2016-04-04
-5j6a,2017-01-25,2016-04-04
-2j6u,2006-11-22,2006-10-04
-8j6n,2024-02-14,2023-04-26
-4j6c,2014-03-05,2013-02-11
-5j6o,2017-05-24,2016-04-05
-4j61,2014-01-22,2013-02-11
-5j63,2016-05-25,2016-04-04
-4j6x,2013-07-31,2013-02-12
-2j60,2007-01-23,2006-09-21
-4j6g,2013-03-13,2013-02-11
-3j6e,2014-06-04,2014-02-18
-6j64,2019-09-25,2019-01-14
-3j6g,2014-06-04,2014-02-19
-4j6w,2013-07-31,2013-02-12
-6j61,2019-06-26,2019-01-12
-6j6h,2019-04-24,2019-01-15
-5j6f,2016-09-07,2016-04-04
-5j60,2016-07-27,2016-04-04
-3j6p,2014-12-31,2014-03-20
-6j6n,2019-04-24,2019-01-15
-8j6p,2023-12-06,2023-04-26
-5j64,2017-12-06,2016-04-04
-8j6l,2024-04-03,2023-04-26
-5j6s,2017-03-15,2016-04-05
-2j66,2006-09-28,2006-09-26
-6j6j,2019-05-29,2019-01-15
-2j6v,2007-10-16,2006-10-04
-2j6o,2006-10-11,2006-10-02
-2j6s,2006-11-22,2006-10-04
-5j6h,2016-07-13,2016-04-05
-2j65,2006-11-08,2006-09-26
-6j6w,2020-01-22,2019-01-16
-2j61,2007-01-23,2006-09-21
-8j66,2024-05-29,2023-04-24
-5j69,2016-05-25,2016-04-04
-2j6l,2006-10-12,2006-09-29
-2j68,2006-12-04,2006-09-26
-8j6o,2024-05-01,2023-04-26
-4j6t,2013-12-25,2013-02-12
-4j6e,2013-05-08,2013-02-11
-5j6p,2017-11-01,2016-04-05
-4j69,2014-01-22,2013-02-11
-6j67,2019-02-13,2019-01-14
-4j62,2014-01-22,2013-02-11
-6j6m,2019-10-23,2019-01-15
-2j64,2007-01-23,2006-09-25
-6j6v,2020-01-22,2019-01-16
-3j6b,2014-04-09,2014-01-22
-1j6z,2001-08-15,2001-05-15
-4j6o,2013-04-10,2013-02-11
-5j68,2016-05-25,2016-04-04
-5j6b,2016-05-04,2016-04-04
-5j6n,2017-12-06,2016-04-05
-1j6v,2001-06-08,2001-05-14
-4j6r,2013-05-08,2013-02-11
-3j6h,2015-04-01,2014-02-21
-8j63,2023-09-20,2023-04-24
-4j6d,2014-03-05,2013-02-11
-8j6g,2023-09-20,2023-04-25
-2j6m,2007-04-03,2006-09-29
-4j6i,2013-08-28,2013-02-11
-6j66,2019-07-10,2019-01-14
-5j6m,2017-12-06,2016-04-05
-2j6x,2006-10-23,2006-10-05
-2j6k,2006-10-11,2006-09-29
-4j6h,2013-03-06,2013-02-11
-1j6x,2001-06-08,2001-05-14
-3j6q,2014-10-08,2014-03-20
-8j6h,2024-03-06,2023-04-25
-4j6b,2014-03-05,2013-02-11
-4j60,2014-01-22,2013-02-11
-6j6f,2019-03-06,2019-01-15
-6j6x,2020-01-22,2019-01-16
-8j61,2023-09-20,2023-04-24
-5j6c,2016-09-21,2016-04-04
-8j6m,2024-05-01,2023-04-26
-8j6q,2023-12-06,2023-04-26
-8j6w,2024-05-01,2023-04-26
-2j6t,2006-11-22,2006-10-04
-3j6f,2014-06-04,2014-02-19
-6j6g,2019-04-24,2019-01-15
-8j68,2024-05-01,2023-04-25
-8j62,2023-07-19,2023-04-24
-5j6y,2017-06-07,2016-04-05
-4j6v,2013-12-25,2013-02-12
-8j6x,2024-02-07,2023-04-26
-2j6a,2006-09-28,2006-09-27
-2j6h,2006-10-02,2006-09-28
-5j6d,2016-05-25,2016-04-04
-6j6o,2019-09-04,2019-01-15
-5j6l,2017-12-06,2016-04-05
-1j6p,2002-10-30,2002-07-09
-8j6d,2023-10-18,2023-04-25
-8j6z,2023-11-15,2023-04-26
-8j6j,2024-01-10,2023-04-26
-4j6y,2013-07-31,2013-02-12
-5j6g,2016-07-13,2016-04-04
-1j6w,2001-06-08,2001-05-14
-6j6i,2019-03-20,2019-01-15
-2j6e,2007-04-10,2006-09-28
-8j6i,2024-04-03,2023-04-26
-2j62,2007-02-13,2006-09-22
-5j62,2016-09-21,2016-04-04
-3k31,2009-10-20,2009-09-30
-3k3e,2010-02-16,2009-10-02
-5k3o,2017-03-29,2016-05-19
-7k3a,2020-11-11,2020-09-10
-3k3k,2009-11-17,2009-10-02
-4k3s,2013-05-01,2013-04-11
-6k3k,2019-06-12,2019-05-19
-7k3t,2020-09-23,2020-09-13
-8k3s,2024-04-03,2023-07-16
-7k3c,2021-11-10,2020-09-11
-4k3f,2013-04-24,2013-04-10
-1k39,2003-08-05,2001-10-02
-3k3i,2009-11-17,2009-10-02
-2k3m,2009-01-06,2008-05-14
-6k3c,2020-04-29,2019-05-17
-4k38,2013-05-08,2013-04-10
-3k3g,2009-11-17,2009-10-02
-2k31,2008-06-03,2008-04-16
-7k39,2020-11-11,2020-09-10
-4k3n,2013-06-12,2013-04-11
-3k3a,2010-09-01,2009-10-02
-3k3l,2010-08-18,2009-10-02
-3k3w,2009-11-10,2009-10-05
-4k3m,2013-05-01,2013-04-11
-3k3u,2010-11-03,2009-10-05
-5k3i,2016-08-24,2016-05-19
-7k35,2020-09-23,2020-09-10
-7k3w,2020-11-18,2020-09-14
-7k3b,2020-11-11,2020-09-10
-8k3p,2023-10-18,2023-07-16
-4k3h,2013-10-09,2013-04-10
-7k37,2020-11-11,2020-09-10
-5k3k,2017-05-24,2016-05-19
-5k30,2017-07-12,2016-05-19
-3k39,2010-09-01,2009-10-02
-1k3b,2002-04-02,2001-10-02
-8k34,2024-01-17,2023-07-14
-6k35,2020-05-13,2019-05-16
-4k3i,2013-07-10,2013-04-10
-5k3b,2017-02-01,2016-05-19
-6k38,2020-02-26,2019-05-16
-7k3v,2020-11-18,2020-09-14
-4k33,2013-09-11,2013-04-10
-7k3u,2020-09-23,2020-09-13
-8k3x,2023-10-18,2023-07-17
-5k3j,2016-08-24,2016-05-19
-6k30,2020-03-18,2019-05-15
-1k3x,2002-10-04,2001-10-04
-5k3m,2017-05-31,2016-05-19
-2k3h,2008-10-21,2008-05-08
-2k3r,2008-12-02,2008-05-15
-7k3y,2021-11-10,2020-09-14
-5k32,2017-03-29,2016-05-19
-6k3e,2020-05-20,2019-05-17
-8k3w,2023-10-18,2023-07-17
-4k36,2013-05-08,2013-04-10
-7k30,2021-03-17,2020-09-10
-7k32,2021-03-17,2020-09-10
-6k3d,2020-05-20,2019-05-17
-1k3c,2001-12-19,2001-10-02
-3k34,2010-05-12,2009-10-01
-6k3n,2020-05-13,2019-05-21
-7k3i,2021-03-10,2020-09-11
-7k36,2021-03-10,2020-09-10
-5k3n,2017-05-31,2016-05-19
-6k3f,2020-06-10,2019-05-18
-4k3r,2013-05-01,2013-04-11
-3k3n,2010-01-19,2009-10-03
-8k3b,2023-12-20,2023-07-14
-7k3x,2021-11-10,2020-09-14
-3k38,2010-09-01,2009-10-02
-4k3l,2013-05-01,2013-04-10
-5k3q,2016-07-20,2016-05-19
-7k31,2021-03-17,2020-09-10
-3k3f,2009-11-17,2009-10-02
-5k3e,2017-02-01,2016-05-19
-3k3h,2010-02-16,2009-10-02
-1k3u,2002-07-03,2001-10-04
-6k3l,2019-11-06,2019-05-20
-6k3o,2021-02-03,2019-05-21
-4k3y,2013-10-23,2013-04-11
-1k3g,2001-10-31,2001-10-03
-1k35,2002-02-13,2001-10-01
-4k3o,2013-05-01,2013-04-11
-4k3v,2013-07-17,2013-04-11
-4k3d,2013-06-19,2013-04-10
-6k3j,2019-06-12,2019-05-19
-5k33,2017-04-12,2016-05-19
-7k3z,2021-04-21,2020-09-14
-5k3l,2017-05-31,2016-05-19
-3k3b,2009-12-15,2009-10-02
-4k30,2013-08-14,2013-04-10
-8k3y,2023-10-25,2023-07-17
-6k31,2019-11-06,2019-05-15
-5k31,2017-03-22,2016-05-19
-4k3g,2013-10-09,2013-04-10
-5k3s,2017-02-08,2016-05-19
-6k33,2020-05-20,2019-05-16
-3k3o,2010-01-19,2009-10-03
-4k3k,2013-05-01,2013-04-10
-7k3d,2021-04-14,2020-09-11
-7k33,2021-03-17,2020-09-10
-1k3d,2001-12-19,2001-10-02
-4k3q,2013-05-01,2013-04-11
-6k36,2020-02-26,2019-05-16
-4k3j,2013-08-28,2013-04-10
-1k3h,2001-10-31,2001-10-03
-1k3i,2001-11-07,2001-10-03
-1k3y,2002-10-30,2001-10-04
-8k3t,2023-10-18,2023-07-17
-6k32,2019-11-20,2019-05-16
-5k36,2016-11-02,2016-05-19
-1k3t,2002-06-19,2001-10-04
-3k3q,2010-02-23,2009-10-04
-6k37,2020-02-26,2019-05-16
-3k37,2010-09-01,2009-10-02
-5k3w,2016-12-14,2016-05-20
-7k38,2022-02-16,2020-09-10
-2k33,2009-02-03,2008-04-18
-4k37,2013-05-08,2013-04-10
-2k3v,2009-03-31,2008-05-19
-1k3a,2001-11-28,2001-10-02
-6k3g,2020-03-25,2019-05-18
-8k3v,2023-10-18,2023-07-17
-5k3y,2016-08-17,2016-05-20
-4k3p,2013-05-01,2013-04-11
-8k3f,2023-11-01,2023-07-15
-3k36,2010-09-01,2009-10-02
-7k3p,2021-09-29,2020-09-12
-8k3u,2023-09-06,2023-07-17
-3k30,2010-05-26,2009-09-30
-5k39,2017-03-29,2016-05-19
-4k3x,2013-10-23,2013-04-11
-4k39,2013-05-08,2013-04-10
-5k3x,2017-05-24,2016-05-20
-6k3q,2020-05-27,2019-05-21
-1k3l,2002-10-23,2001-10-03
-1k3w,2002-10-04,2001-10-04
-3k3j,2009-11-10,2009-10-02
-6jvs,2020-10-28,2019-04-17
-7jvl,2020-12-02,2020-08-21
-7jvv,2020-12-16,2020-08-24
-5jvd,2016-06-08,2016-05-11
-4jvf,2013-05-22,2013-03-25
-6jvn,2020-10-28,2019-04-17
-3jvf,2009-10-20,2009-09-16
-5jvo,2016-08-31,2016-05-11
-4jv7,2013-05-01,2013-03-25
-4jv3,2013-05-22,2013-03-25
-7jv4,2020-10-14,2020-08-20
-5jvn,2017-04-05,2016-05-11
-5jvg,2016-11-09,2016-05-11
-1jvg,2002-08-30,2001-08-30
-6jvx,2020-01-01,2019-04-17
-7jvd,2021-06-30,2020-08-20
-5jv3,2016-08-03,2016-05-10
-7jvm,2020-09-23,2020-08-21
-8jvj,2024-05-08,2023-06-28
-6jvc,2020-03-18,2019-04-16
-5jv2,2017-03-15,2016-05-10
-7jvr,2021-02-24,2020-08-22
-1jv2,2001-10-17,2001-08-28
-7jvk,2020-12-02,2020-08-21
-4jvd,2013-08-07,2013-03-25
-6jvy,2020-01-01,2019-04-17
-8jv7,2023-11-29,2023-06-27
-1jvd,2002-08-29,2001-08-29
-7jvo,2020-10-14,2020-08-22
-6jvg,2020-10-28,2019-04-17
-7jvw,2020-12-16,2020-08-24
-7jva,2020-10-14,2020-08-20
-5jv4,2017-08-09,2016-05-10
-7jv1,2020-09-30,2020-08-20
-7jv6,2020-10-14,2020-08-20
-3jv7,2010-08-25,2009-09-16
-3jvg,2010-02-09,2009-09-16
-8jv0,2024-06-05,2023-06-27
-5jv1,2017-03-15,2016-05-10
-5jvh,2016-11-09,2016-05-11
-8jv5,2023-10-18,2023-06-27
-6jv2,2019-07-17,2019-04-15
-6jvo,2020-10-28,2019-04-17
-4jvn,2013-09-04,2013-03-25
-3jvt,2009-12-01,2009-09-17
-4jva,2013-09-18,2013-03-25
-1jvb,2002-08-29,2001-08-29
-4jvb,2013-05-22,2013-03-25
-6jvj,2020-10-28,2019-04-17
-4jv0,2013-08-28,2013-03-25
-7jv9,2020-09-23,2020-08-20
-1jvu,2002-06-05,2001-08-31
-8jv6,2023-10-18,2023-06-27
-3jvx,2010-09-15,2009-09-17
-3jvk,2009-10-13,2009-09-17
-8jv8,2023-11-29,2023-06-27
-5jvz,2016-10-26,2016-05-11
-7jvq,2021-02-24,2020-08-22
-5jvl,2017-04-05,2016-05-11
-4jv5,2013-06-26,2013-03-25
-6jvu,2020-02-26,2019-04-17
-1jvi,2001-10-24,2001-08-30
-4jvs,2013-05-08,2013-03-26
-3jvh,2009-09-29,2009-09-16
-6jvt,2020-10-28,2019-04-17
-2jvn,2008-05-13,2007-09-24
-1jv6,2001-10-31,2001-08-28
-4jvj,2014-01-01,2013-03-25
-3jvv,2010-06-02,2009-09-17
-4jvg,2013-05-29,2013-03-25
-5jve,2017-03-08,2016-05-11
-8jva,2024-05-22,2023-06-28
-1jvx,2001-09-12,2001-08-31
-4jve,2013-05-01,2013-03-25
-4jvh,2013-05-08,2013-03-25
-4jvy,2013-05-08,2013-03-26
-8jve,2023-11-29,2023-06-28
-1jvs,2002-10-09,2001-08-31
-6jvh,2020-10-28,2019-04-17
-6jvq,2020-10-28,2019-04-17
-6jv0,2020-01-15,2019-04-15
-4jv2,2013-08-28,2013-03-25
-1jvn,2001-10-12,2001-08-30
-3jv2,2009-11-24,2009-09-15
-3jva,2010-08-11,2009-09-16
-8jvd,2024-02-28,2023-06-28
-6jv1,2020-01-15,2019-04-15
-1jvj,2002-03-06,2001-08-30
-5jv5,2016-11-09,2016-05-10
-3jvw,2009-12-08,2009-09-17
-4jvi,2013-08-07,2013-03-25
-6jvw,2019-05-29,2019-04-17
-1jv0,2001-09-19,2001-08-28
-6jvi,2020-10-28,2019-04-17
-5jvj,2017-04-05,2016-05-11
-5jvs,2016-08-03,2016-05-11
-1jv3,2002-08-28,2001-08-28
-1jv1,2002-08-28,2001-08-28
-5jv0,2017-03-15,2016-05-10
-3jvr,2009-10-06,2009-09-17
-8jvl,2023-11-29,2023-06-28
-1jvm,2001-12-05,2001-08-30
-4jv1,2013-08-28,2013-03-25
-4jvo,2013-06-12,2013-03-25
-7jvi,2021-09-08,2020-08-21
-6jv6,2019-06-12,2019-04-16
-6jvr,2020-10-28,2019-04-17
-1jv7,2001-10-31,2001-08-28
-5jvm,2016-08-03,2016-05-11
-3jvs,2009-10-06,2009-09-17
-1jvz,2002-09-01,2001-09-01
-7jvu,2020-12-16,2020-08-24
-4jvt,2013-06-19,2013-03-26
-6jvm,2020-10-28,2019-04-17
-4jvr,2013-05-01,2013-03-26
-1jvl,2002-01-04,2001-08-30
-4jvl,2013-09-04,2013-03-25
-7jvp,2021-02-24,2020-08-22
-5jvx,2016-07-13,2016-05-11
-7jv0,2020-09-30,2020-08-20
-6jvk,2020-10-28,2019-04-17
-4jv9,2013-05-01,2013-03-25
-7jvn,2020-09-23,2020-08-21
-7jve,2021-04-21,2020-08-21
-4jv6,2013-05-22,2013-03-25
-2jvx,2008-03-18,2007-09-28
-4jv4,2013-09-18,2013-03-25
-5jvp,2016-08-03,2016-05-11
-4jvm,2013-09-04,2013-03-25
-1jvy,2001-09-12,2001-08-31
-1jv4,2001-12-05,2001-08-28
-4jv8,2013-05-22,2013-03-25
-2jvy,2008-03-18,2007-09-28
-8jvi,2024-05-08,2023-06-28
-1jvo,2002-01-04,2001-08-30
-5jvy,2016-10-26,2016-05-11
-1jvp,2001-12-21,2001-08-31
-1jvq,2003-06-03,2001-08-31
-7jv5,2021-02-24,2020-08-20
-3jvy,2009-12-08,2009-09-17
-7jvc,2020-10-14,2020-08-20
-5jvi,2016-12-21,2016-05-11
-6jvl,2020-10-28,2019-04-17
-6jv4,2019-11-27,2019-04-15
-7jv8,2020-09-23,2020-08-20
-6jvp,2020-10-28,2019-04-17
-4jvq,2014-02-05,2013-03-26
-7jvs,2021-09-01,2020-08-22
-5ol0,2018-02-28,2017-07-26
-3olu,2011-04-13,2010-08-26
-1olc,1996-01-29,1995-09-10
-4olx,2014-09-03,2014-01-25
-5olp,2017-11-29,2017-07-28
-6olg,2019-06-19,2019-04-16
-4olc,2014-02-26,2014-01-23
-5oly,2017-11-01,2017-07-28
-2olx,2007-01-30,2007-01-19
-4old,2014-05-28,2014-01-23
-2olb,1996-01-29,1995-09-10
-5olx,2017-11-01,2017-07-28
-4olg,2014-05-28,2014-01-23
-5olc,2017-12-06,2017-07-27
-6ole,2019-06-19,2019-04-16
-5olq,2017-11-29,2017-07-28
-3ol2,2010-10-13,2010-08-25
-6olx,2019-07-03,2019-04-17
-1olu,2003-08-28,2003-08-15
-7olc,2022-01-26,2021-05-19
-6ol1,2020-10-28,2019-04-15
-2olq,2007-06-12,2007-01-19
-3olg,2011-04-13,2010-08-26
-3olv,2011-08-31,2010-08-26
-6olp,2019-07-31,2019-04-16
-1ol5,2003-10-30,2003-08-06
-2oli,2007-02-13,2007-01-19
-4olt,2014-04-30,2014-01-25
-8olt,2023-08-09,2023-03-30
-6olf,2019-06-19,2019-04-16
-4oly,2014-09-03,2014-01-25
-1olp,2003-10-23,2003-08-11
-4olv,2014-09-03,2014-01-25
-7old,2022-01-26,2021-05-19
-3oli,2011-04-13,2010-08-26
-7oly,2022-02-23,2021-05-20
-7olm,2022-06-01,2021-05-20
-7ola,2022-07-13,2021-05-19
-7olr,2022-06-01,2021-05-20
-3olf,2011-01-19,2010-08-26
-2olm,2007-01-30,2007-01-19
-4olf,2015-04-15,2014-01-23
-7ol4,2022-12-14,2021-05-19
-8ol4,2023-10-25,2023-03-30
-8olu,2023-08-09,2023-03-30
-6oly,2019-12-11,2019-04-17
-5ole,2018-08-29,2017-07-27
-5olb,2018-01-03,2017-07-27
-4olm,2014-08-20,2014-01-24
-6oli,2019-06-19,2019-04-16
-6olo,2020-03-25,2019-04-16
-6olm,2019-11-20,2019-04-16
-6ol0,2020-10-28,2019-04-15
-7ols,2021-09-15,2021-05-20
-5old,2018-08-29,2017-07-27
-8ol9,2023-07-19,2023-03-30
-1ol2,2003-12-11,2003-08-05
-2ole,2008-01-22,2007-01-19
-2olh,2007-02-13,2007-01-19
-5olz,2018-01-17,2017-07-28
-2oly,2007-12-04,2007-01-20
-7ol0,2021-07-14,2021-05-18
-7ole,2021-07-07,2021-05-19
-4oll,2014-04-30,2014-01-24
-2ol3,2007-04-03,2007-01-18
-5oll,2018-08-08,2017-07-28
-1ol1,2003-12-11,2003-08-04
-2olp,2007-12-18,2007-01-19
-6ol9,2019-12-11,2019-04-16
-4oln,2014-10-29,2014-01-24
-1ols,2003-08-15,2003-08-12
-2ol1,2007-05-01,2007-01-18
-5olg,2018-01-17,2017-07-27
-6ola,2019-09-25,2019-04-16
-7ol7,2022-06-01,2021-05-19
-1olq,2003-11-25,2003-08-11
-3olh,2010-09-29,2010-08-26
-2olz,2007-12-04,2007-01-20
-7olz,2021-08-11,2021-05-20
-3oll,2010-11-17,2010-08-26
-6ol2,2020-04-15,2019-04-15
-4olw,2014-09-03,2014-01-25
-2ol0,2007-05-01,2007-01-18
-7olo,2022-06-01,2021-05-20
-3ol8,2010-12-22,2010-08-25
-5olr,2017-11-29,2017-07-28
-5olh,2018-01-17,2017-07-27
-3olr,2011-06-29,2010-08-26
-7olt,2022-06-01,2021-05-20
-4ols,2014-06-04,2014-01-24
-8olh,2024-04-10,2023-03-30
-4ol0,2014-04-09,2014-01-23
-7olw,2022-06-01,2021-05-20
-3olt,2011-04-13,2010-08-26
-2ol9,2007-01-30,2007-01-18
-4oli,2014-05-28,2014-01-23
-1oln,2003-09-11,2003-08-08
-5ol4,2018-03-07,2017-07-26
-5ols,2017-11-29,2017-07-28
-2olg,2007-02-06,2007-01-19
-7olq,2022-06-01,2021-05-20
-4olh,2014-07-23,2014-01-23
-7olp,2022-06-01,2021-05-20
-6olz,2019-06-19,2019-04-17
-8ol1,2024-02-14,2023-03-29
-5olv,2018-01-17,2017-07-28
-7olv,2021-09-15,2021-05-20
-3ol9,2010-12-22,2010-08-25
-3ole,2011-04-13,2010-08-26
-1ol7,2003-10-30,2003-08-06
-8olf,2024-04-10,2023-03-30
-2olc,2007-05-22,2007-01-18
-7ol2,2022-12-14,2021-05-19
-5ol5,2017-09-27,2017-07-26
-8olx,2023-05-24,2023-03-30
-7oll,2022-06-01,2021-05-20
-4olb,2014-02-05,2014-01-23
-3ol5,2010-11-17,2010-08-25
-5olk,2018-01-10,2017-07-28
-3olx,2011-08-31,2010-08-26
-7olu,2022-06-01,2021-05-20
-7olb,2022-06-01,2021-05-19
-8olm,2024-04-10,2023-03-30
-1ola,1994-07-31,1994-04-26
-2olr,2007-06-12,2007-01-19
-4ol7,2015-01-28,2014-01-23
-8olj,2024-01-24,2023-03-30
-3olb,2010-12-22,2010-08-25
-1ol6,2003-10-30,2003-08-06
-3old,2011-04-13,2010-08-26
-5olw,2017-11-01,2017-07-28
-2olv,2007-03-13,2007-01-19
-8olr,2023-12-06,2023-03-30
-6ol8,2020-04-22,2019-04-16
-5ol2,2017-11-29,2017-07-26
-3ol7,2010-12-22,2010-08-25
-8old,2024-01-24,2023-03-30
-4olr,2014-07-02,2014-01-24
-4olu,2014-09-03,2014-01-25
-3ola,2010-12-22,2010-08-25
-4olz,2014-09-03,2014-01-25
-2ol4,2007-07-17,2007-01-18
-8oll,2023-12-06,2023-03-30
-3ol6,2010-12-22,2010-08-25
-2olk,2008-01-15,2007-01-19
-4ol9,2014-02-26,2014-01-23
-4olk,2014-05-28,2014-01-24
-1olm,2004-08-12,2003-08-08
-8olk,2024-04-10,2023-03-30
-7oln,2022-06-01,2021-05-20
-5olt,2018-08-08,2017-07-28
-6olt,2020-04-22,2019-04-17
-5ola,2017-10-18,2017-07-27
-2olj,2008-01-15,2007-01-19
-7olk,2022-06-01,2021-05-20
-3olj,2011-08-31,2010-08-26
-2olo,2007-07-31,2007-01-19
-3olp,2011-02-16,2010-08-26
-1olt,2003-12-04,2003-08-13
-7olx,2021-09-15,2021-05-20
-3oly,2011-08-31,2010-08-26
-5olm,2018-04-25,2017-07-28
-5ol3,2018-08-29,2017-07-26
-3ols,2010-11-17,2010-08-26
-3olz,2010-11-03,2010-08-26
-5ol7,2017-09-27,2017-07-26
-8oli,2024-04-10,2023-03-30
-1olx,2003-08-28,2003-08-18
-7olj,2021-12-08,2021-05-20
-8olp,2024-04-10,2023-03-30
-5olo,2018-01-17,2017-07-28
-3olw,2011-08-31,2010-08-26
-7ol6,2022-06-01,2021-05-19
-2oln,2007-07-31,2007-01-19
-7ol3,2021-07-21,2021-05-19
-7oli,2022-06-01,2021-05-20
-5b3h,2017-03-01,2016-02-29
-9b37,2024-05-22,2024-03-18
-3b32,2007-11-13,2007-10-19
-6b3k,2017-12-27,2017-09-22
-8b3i,2023-09-27,2022-09-16
-1b3d,1999-12-10,1998-12-09
-4b3s,2013-08-07,2012-07-26
-9b3r,2024-05-29,2024-03-20
-3b3d,2008-10-21,2007-10-20
-2b3h,2005-11-22,2005-09-20
-9b3d,2024-05-29,2024-03-19
-8b3v,2022-11-30,2022-09-16
-5b3u,2017-02-15,2016-03-13
-8b3b,2023-01-25,2022-09-16
-7b33,2020-12-16,2020-11-28
-2b3l,2005-11-22,2005-09-20
-1b3a,1999-04-23,1998-12-07
-5b31,2016-08-03,2016-02-08
-7b3c,2020-12-23,2020-11-30
-1b3w,1999-04-07,1998-12-15
-2b3x,2006-01-10,2005-09-22
-4b34,2013-02-06,2012-07-20
-5b3z,2016-10-26,2016-03-17
-6b3p,2017-11-29,2017-09-22
-8b37,2024-01-17,2022-09-16
-5b3x,2016-10-26,2016-03-17
-7b31,2020-12-16,2020-11-28
-1b3n,1999-04-06,1998-12-14
-1b39,1998-12-23,1998-12-17
-7b3i,2021-12-08,2020-12-01
-4b35,2013-02-06,2012-07-20
-4b3i,2013-03-27,2012-07-24
-9b39,2024-05-22,2024-03-18
-3b39,2008-01-15,2007-10-19
-8b34,2023-09-27,2022-09-15
-5b35,2016-11-09,2016-02-10
-1b3z,1999-04-06,1998-12-15
-4b3m,2013-08-07,2012-07-25
-5b3s,2017-03-22,2016-03-11
-1b30,1999-03-31,1998-12-15
-4b3r,2013-08-07,2012-07-26
-5b3v,2017-02-15,2016-03-13
-5b3w,2016-10-26,2016-03-17
-9b3q,2024-05-29,2024-03-20
-4b32,2013-02-06,2012-07-20
-8b39,2023-09-20,2022-09-16
-7b38,2021-03-17,2020-11-29
-2b33,2005-09-27,2005-09-19
-6b30,2018-01-03,2017-09-20
-7b39,2021-09-01,2020-11-29
-4b3o,2013-01-16,2012-07-25
-3b30,2007-12-11,2007-10-19
-8b3l,2022-12-21,2022-09-16
-3b3v,2007-11-27,2007-10-22
-6b3w,2017-12-27,2017-09-25
-7b3h,2021-12-08,2020-11-30
-7b37,2021-08-04,2020-11-28
-6b3d,2017-12-06,2017-09-21
-5b3a,2016-03-16,2016-02-12
-7b3q,2020-12-09,2020-12-01
-3b3f,2007-11-06,2007-10-22
-1b3l,1998-12-16,1998-12-14
-7b3s,2022-01-12,2020-12-01
-2b35,2006-03-07,2005-09-19
-1b3h,1998-11-18,1998-11-16
-8b3r,2023-09-27,2022-09-16
-8b3t,2022-11-30,2022-09-16
-1b3v,1999-04-07,1998-12-15
-6b33,2018-11-21,2017-09-20
-6b3b,2017-11-15,2017-09-21
-7b35,2020-12-16,2020-11-28
-5b3y,2016-10-26,2016-03-17
-2b37,2006-03-07,2005-09-19
-6b37,2018-09-26,2017-09-21
-3b3s,2007-11-27,2007-10-22
-3b3b,2008-05-06,2007-10-19
-8b3a,2023-04-05,2022-09-16
-7b32,2020-12-16,2020-11-28
-2b3t,2006-01-24,2005-09-21
-7b3x,2021-12-08,2020-12-01
-3b3n,2008-07-15,2007-10-22
-4b3v,2013-01-09,2012-07-26
-1b3g,1998-12-16,1998-12-14
-8b32,2023-09-27,2022-09-15
-6b3s,2017-12-06,2017-09-23
-1b3o,1999-04-12,1998-12-14
-3b3m,2008-07-15,2007-10-22
-3b37,2008-05-06,2007-10-19
-4b3b,2013-02-27,2012-07-23
-7b3m,2021-03-03,2020-12-01
-3b3t,2007-11-27,2007-10-22
-2b3k,2005-11-22,2005-09-20
-9b36,2024-05-22,2024-03-18
-4b3g,2012-09-26,2012-07-24
-4b3u,2012-10-31,2012-07-26
-9b35,2024-05-22,2024-03-18
-8b3f,2023-09-27,2022-09-16
-1b32,1998-12-23,1998-12-15
-5b36,2016-03-16,2016-02-10
-3b34,2008-05-06,2007-10-19
-2b3p,2005-11-08,2005-09-20
-7b3f,2021-08-04,2020-11-30
-1b33,1999-02-23,1998-12-15
-6b3e,2017-12-27,2017-09-21
-3b3k,2008-10-28,2007-10-22
-4b3n,2012-10-24,2012-07-25
-4b30,2013-01-16,2012-07-19
-6b3f,2018-01-03,2017-09-21
-2b3v,2006-01-17,2005-09-21
-1b38,1998-12-23,1998-12-17
-5b38,2016-03-30,2016-02-12
-7b3v,2020-12-09,2020-12-01
-4b3w,2013-01-23,2012-07-26
-3b3o,2008-11-04,2007-10-22
-2b3j,2006-01-24,2005-09-20
-8b3k,2023-05-03,2022-09-16
-4b3q,2013-01-16,2012-07-25
-7b3t,2020-12-09,2020-12-01
-6b38,2018-01-03,2017-09-21
-7b3b,2020-12-23,2020-11-30
-3b3w,2007-11-27,2007-10-22
-9b33,2024-05-22,2024-03-18
-5b3r,2017-02-15,2016-03-10
-7b3r,2022-01-12,2020-12-01
-7b3z,2020-12-09,2020-12-01
-2b31,2005-09-27,2005-09-19
-1b3f,1998-12-16,1998-12-14
-7b36,2020-12-16,2020-11-28
-8b3s,2023-12-27,2022-09-16
-8b3w,2023-01-25,2022-09-17
-5b30,2016-06-01,2016-02-08
-3b35,2007-11-27,2007-10-19
-7b3w,2020-12-09,2020-12-01
-4b3d,2013-02-06,2012-07-23
-6b3m,2018-06-13,2017-09-22
-6b3t,2018-04-04,2017-09-24
-6b3g,2018-01-03,2017-09-21
-7b3u,2022-01-12,2020-12-01
-6b31,2018-08-01,2017-09-20
-2b36,2006-03-07,2005-09-19
-1b3j,1999-07-09,1998-12-11
-4b33,2013-02-06,2012-07-20
-6b3l,2018-09-26,2017-09-22
-2b3z,2005-11-29,2005-09-22
-8b3m,2023-05-24,2022-09-16
-6b39,2017-11-15,2017-09-21
-7b3n,2022-06-22,2020-12-01
-7b3p,2021-12-08,2020-12-01
-3b3p,2008-11-04,2007-10-22
-7b3e,2021-01-13,2020-11-30
-8b31,2023-12-27,2022-09-15
-6b3a,2017-11-15,2017-09-21
-4b31,2013-04-10,2012-07-20
-1b3r,1998-12-23,1998-12-14
-1b3i,1999-04-27,1998-12-11
-2b3q,2005-11-08,2005-09-20
-8b3d,2023-09-27,2022-09-16
-2b3f,2006-07-18,2005-09-20
-5b39,2016-03-30,2016-02-12
-3b3r,2007-12-18,2007-10-22
-6b3h,2018-01-03,2017-09-21
-1b3q,1999-12-15,1998-12-14
-1b3e,1999-03-26,1998-12-09
-4b3c,2013-02-06,2012-07-23
-6b36,2018-01-03,2017-09-21
-9b34,2024-05-22,2024-03-18
-4b3a,2013-06-12,2012-07-23
-6b3c,2018-01-03,2017-09-21
-1b3y,1999-04-06,1998-12-15
-3b3i,2008-07-22,2007-10-22
-7b3a,2021-11-10,2020-11-30
-5b3i,2017-03-01,2016-02-29
-7b3g,2021-12-08,2020-11-30
-2b3b,2006-07-18,2005-09-20
-3b3c,2007-11-27,2007-10-19
-8b3e,2023-01-25,2022-09-16
-1b37,1999-12-17,1998-12-17
-5b3j,2016-05-11,2016-03-01
-4b3t,2013-08-07,2012-07-26
-7b34,2020-12-16,2020-11-28
-1b3x,1999-04-07,1998-12-15
-8b35,2023-09-27,2022-09-15
-8b3c,2023-09-27,2022-09-16
-4b3e,2012-09-26,2012-07-23
-3b3x,2007-11-13,2007-10-23
-8b3n,2023-09-27,2022-09-16
-6b3v,2018-08-29,2017-09-25
-5b3p,2016-07-27,2016-03-09
-5b32,2016-08-03,2016-02-08
-7b3o,2020-12-16,2020-12-01
-8b3u,2022-11-30,2022-09-16
-2b30,2005-09-27,2005-09-19
-2b3i,1999-04-27,1998-12-11
-5b34,2016-11-09,2016-02-10
-4b3j,2013-03-27,2012-07-24
-3b3q,2008-01-15,2007-10-22
-7b3d,2020-12-23,2020-11-30
-7b30,2020-12-16,2020-11-28
-2b3d,2006-08-29,2005-09-20
-9b38,2024-05-22,2024-03-18
-5klf,2016-09-21,2016-06-24
-1klm,1998-03-18,1997-03-17
-4kle,2013-07-17,2013-05-07
-7kl0,2020-12-23,2020-10-28
-3kl0,2010-12-08,2009-11-06
-7kl6,2021-05-05,2020-10-29
-5kl5,2016-09-14,2016-06-23
-4kl0,2013-10-09,2013-05-07
-7klz,2021-08-18,2020-11-01
-5klx,2017-05-31,2016-06-26
-4klm,2013-07-17,2013-05-07
-4klb,2013-09-18,2013-05-07
-4klh,2013-07-17,2013-05-07
-7kl9,2020-11-11,2020-10-29
-7kl1,2020-12-23,2020-10-28
-6klo,2020-01-15,2019-07-30
-6klc,2020-03-18,2019-07-30
-6klg,2020-01-01,2019-07-30
-7kld,2021-09-01,2020-10-29
-3kll,2010-11-03,2009-11-08
-5klk,2016-11-09,2016-06-24
-1kl3,2002-04-03,2001-12-11
-4kly,2013-06-05,2013-05-07
-1klq,2002-01-25,2001-12-12
-7klb,2021-04-21,2020-10-29
-6klj,2020-01-01,2019-07-30
-4klz,2014-09-17,2013-05-07
-1klj,2002-10-09,2001-12-12
-7kl5,2021-04-07,2020-10-29
-3kle,2010-09-22,2009-11-07
-6kl5,2020-03-25,2019-07-29
-4kl4,2013-05-22,2013-05-07
-3klf,2010-09-22,2009-11-07
-4kl1,2014-04-30,2013-05-07
-1kl2,2002-07-10,2001-12-11
-3klt,2010-05-26,2009-11-09
-7kl8,2021-03-24,2020-10-29
-5kla,2016-08-17,2016-06-23
-1kli,2002-09-18,2001-12-12
-3klv,2010-07-07,2009-11-09
-5kle,2016-09-21,2016-06-24
-2klh,2009-10-20,2009-07-02
-3klm,2010-04-21,2009-11-08
-4kll,2013-07-17,2013-05-07
-4kln,2013-11-13,2013-05-07
-5klv,2016-10-12,2016-06-25
-1kln,1994-11-30,1994-05-24
-3kl3,2010-12-08,2009-11-06
-7klu,2021-11-03,2020-11-01
-5kl1,2016-08-17,2016-06-23
-7kle,2021-11-03,2020-10-30
-7klr,2021-03-03,2020-10-31
-4kli,2013-07-17,2013-05-07
-5kl6,2016-09-14,2016-06-23
-5klu,2017-03-22,2016-06-25
-7klo,2021-03-03,2020-10-30
-6kl8,2019-08-07,2019-07-29
-3kla,2010-02-16,2009-11-07
-6klh,2020-03-18,2019-07-30
-6kli,2020-01-01,2019-07-30
-6kls,2020-05-13,2019-07-30
-7klt,2021-11-03,2020-11-01
-6kla,2019-11-27,2019-07-30
-3klo,2010-02-09,2009-11-08
-5kli,2016-10-12,2016-06-24
-4klo,2013-07-17,2013-05-07
-4klj,2013-07-17,2013-05-07
-6kln,2020-01-15,2019-07-30
-3klc,2010-11-24,2009-11-07
-7klk,2021-09-29,2020-10-30
-7klm,2021-09-29,2020-10-30
-7klh,2021-02-10,2020-10-30
-3klb,2010-01-26,2009-11-07
-4klv,2013-05-22,2013-05-07
-6klv,2020-05-13,2019-07-30
-6klu,2020-01-15,2019-07-30
-3klk,2010-11-03,2009-11-08
-4klf,2013-07-17,2013-05-07
-3kl5,2010-12-08,2009-11-06
-1kl6,2002-12-11,2001-12-11
-6kl7,2020-01-29,2019-07-29
-5kly,2017-06-28,2016-06-26
-4klt,2013-07-17,2013-05-07
-1klk,2002-12-12,2001-12-12
-4kl8,2013-07-10,2013-05-07
-5klb,2016-08-31,2016-06-23
-4klx,2013-12-25,2013-05-07
-1klz,2002-06-28,2001-12-13
-6klz,2020-08-12,2019-07-30
-3klu,2009-11-24,2009-11-09
-4kld,2013-07-17,2013-05-07
-4klu,2013-07-17,2013-05-07
-5kl4,2016-09-14,2016-06-23
-5klq,2016-08-17,2016-06-24
-7kl3,2021-02-03,2020-10-28
-7klq,2021-11-03,2020-10-31
-6klt,2020-01-15,2019-07-30
-5klz,2017-06-28,2016-06-26
-3kld,2009-12-22,2009-11-07
-5klm,2016-11-09,2016-06-24
-6klx,2020-01-15,2019-07-30
-7kll,2021-09-29,2020-10-30
-5kls,2016-08-31,2016-06-25
-5kl2,2016-09-14,2016-06-23
-4klw,2013-05-22,2013-05-07
-1kl5,2002-04-03,2001-12-11
-7klx,2022-01-19,2020-11-01
-6klf,2020-08-05,2019-07-30
-1kll,2002-07-19,2001-12-12
-5kl0,2016-07-13,2016-06-23
-7klc,2021-07-07,2020-10-29
-4kl9,2013-12-25,2013-05-07
-7kly,2021-11-03,2020-11-01
-1kl9,2002-03-11,2001-12-11
-6kld,2020-03-18,2019-07-30
-5klo,2016-11-09,2016-06-24
-1kls,2002-03-13,2001-12-12
-3kls,2009-11-24,2009-11-09
-6klw,2020-01-15,2019-07-30
-4klr,2014-06-18,2013-05-07
-5kln,2016-11-09,2016-06-24
-3klh,2010-09-22,2009-11-07
-5kll,2016-11-09,2016-06-24
-4klq,2013-07-17,2013-05-07
-6klk,2019-11-06,2019-07-30
-2kli,2009-11-03,2009-07-03
-6kl6,2020-03-25,2019-07-29
-6kll,2020-01-15,2019-07-30
-7kls,2021-11-03,2020-10-31
-5kl3,2016-09-14,2016-06-23
-1kl1,2002-07-10,2001-12-11
-5kl8,2016-08-17,2016-06-23
-7klg,2021-02-10,2020-10-30
-3kl7,2010-02-02,2009-11-06
-6kl9,2019-09-11,2019-07-30
-6kle,2020-03-18,2019-07-30
-4kls,2013-07-17,2013-05-07
-1kl7,2002-04-24,2001-12-11
-4klg,2013-07-17,2013-05-07
-7klv,2021-11-03,2020-11-01
-1klr,2002-03-13,2001-12-12
-3kl9,2010-02-02,2009-11-07
-1klf,2002-06-05,2001-12-11
-4klc,2014-06-18,2013-05-07
-5kl7,2016-09-14,2016-06-23
-1kly,2002-06-28,2001-12-13
-3klp,2010-11-10,2009-11-08
-5kl9,2016-07-06,2016-06-23
-4kla,2014-05-07,2013-05-07
-3klj,2010-02-16,2009-11-08
-5klg,2016-08-31,2016-06-24
-3kl6,2009-12-01,2009-11-06
-6klb,2019-09-11,2019-07-30
-7klf,2021-11-03,2020-10-30
-7lnw,2021-12-22,2021-02-08
-4ln4,2013-10-02,2013-07-11
-7lnn,2021-03-31,2021-02-08
-4lna,2013-07-24,2013-07-11
-1lnz,2002-09-16,2002-05-04
-5ln5,2016-11-09,2016-08-03
-7lnq,2021-05-12,2021-02-08
-4lnv,2013-07-24,2013-07-12
-4lnk,2013-10-30,2013-07-11
-1lnq,2002-06-19,2002-05-03
-3lnp,2010-02-16,2010-02-02
-4lnl,2013-11-06,2013-07-11
-1lna,1995-05-08,1994-05-13
-5lnj,2017-08-16,2016-08-04
-6lny,2020-05-27,2020-01-02
-3lnh,2010-03-02,2010-02-02
-5ln2,2016-09-07,2016-08-02
-5lnq,2017-01-18,2016-08-06
-1lnd,1995-05-08,1994-05-13
-3lnj,2010-03-09,2010-02-02
-7ln7,2022-02-23,2021-02-06
-1lnx,2003-03-25,2002-05-04
-5lns,2017-01-18,2016-08-06
-7lnm,2021-08-25,2021-02-07
-6ln5,2020-08-26,2019-12-28
-4lnj,2013-11-06,2013-07-11
-4lnw,2014-03-19,2013-07-12
-5ln8,2016-08-24,2016-08-03
-6ln3,2020-04-22,2019-12-28
-1lnm,2003-06-17,2002-05-03
-7ln2,2021-09-15,2021-02-06
-3lnt,2010-02-09,2010-02-03
-4lng,2014-01-01,2013-07-11
-5lnk,2016-11-23,2016-08-04
-3lnf,2010-03-02,2010-02-02
-4lnm,2013-11-06,2013-07-11
-5lny,2017-11-29,2016-08-08
-3lne,2010-03-02,2010-02-02
-3lni,2010-03-02,2010-02-02
-1lne,1995-05-08,1994-05-13
-3lnc,2010-02-16,2010-02-02
-1lnl,2003-06-03,2002-05-03
-3lnz,2010-03-09,2010-02-03
-6lnd,2020-02-19,2019-12-28
-6ln6,2020-08-26,2019-12-28
-7ln8,2022-02-23,2021-02-06
-3lnm,2010-04-14,2010-02-02
-1ln8,2003-05-20,2002-05-03
-4lnf,2013-11-13,2013-07-11
-7ln5,2021-09-15,2021-02-06
-4ln6,2013-10-02,2013-07-11
-5lni,2017-08-16,2016-08-04
-4lnx,2014-03-19,2013-07-12
-1lnu,2002-08-14,2002-05-03
-5lnw,2017-01-18,2016-08-06
-6lnr,2020-12-23,2020-01-01
-6ln9,2020-08-26,2019-12-28
-2lnw,2012-11-21,2012-01-05
-7lnp,2022-02-09,2021-02-08
-1ln6,2002-07-10,2002-05-03
-6lna,2020-12-30,2019-12-28
-3ln4,2010-10-20,2010-02-01
-5lnf,2017-03-15,2016-08-04
-6lnq,2020-05-27,2020-01-01
-4lnb,2014-01-01,2013-07-11
-6lnb,2020-02-19,2019-12-28
-4ln1,2013-07-24,2013-07-11
-3lnb,2011-01-26,2010-02-02
-3lnk,2010-04-14,2010-02-02
-4ln3,2013-10-02,2013-07-11
-4lnc,2014-02-12,2013-07-11
-1lnh,1997-02-02,1996-03-29
-3lnn,2010-06-30,2010-02-02
-7ln0,2021-09-15,2021-02-06
-1lnf,1995-05-08,1994-05-13
-3ln0,2010-10-27,2010-02-01
-5lnv,2017-01-18,2016-08-06
-1lnb,1995-05-08,1994-05-13
-4lnd,2013-11-27,2013-07-11
-7ln6,2021-09-15,2021-02-06
-6lnk,2020-12-30,2019-12-30
-3lnl,2010-03-16,2010-02-02
-3lng,2010-03-02,2010-02-02
-7lnx,2021-12-22,2021-02-08
-4ln7,2013-09-18,2013-07-11
-3ln3,2010-02-16,2010-02-01
-6ln0,2021-05-05,2019-12-27
-5lnz,2017-11-29,2016-08-08
-5lnt,2017-01-18,2016-08-06
-5lnx,2017-08-16,2016-08-07
-4lny,2013-08-07,2013-07-12
-6ln2,2020-03-18,2019-12-28
-4lni,2013-11-06,2013-07-11
-7lnu,2021-12-22,2021-02-08
-3lnd,2010-03-02,2010-02-02
-4lnu,2014-12-03,2013-07-12
-7lnt,2021-12-22,2021-02-08
-7lnr,2021-05-12,2021-02-08
-1lny,2002-08-28,2002-05-04
-3ln1,2010-10-27,2010-02-01
-3lnv,2010-04-07,2010-02-03
-7ln1,2021-09-15,2021-02-06
-5lnr,2017-01-18,2016-08-06
-4lnt,2014-08-06,2013-07-12
-6ln8,2020-08-26,2019-12-28
-7ln9,2022-02-23,2021-02-06
-3lny,2010-03-23,2010-02-03
-6lnh,2021-01-13,2019-12-30
-2ln0,2012-06-27,2011-12-15
-5lne,2016-10-05,2016-08-04
-4ln8,2013-10-02,2013-07-11
-7ln4,2021-09-15,2021-02-06
-7lnl,2021-05-26,2021-02-07
-4lno,2013-11-13,2013-07-11
-4lnn,2013-11-13,2013-07-11
-5lnu,2017-01-18,2016-08-06
-7ln3,2021-09-15,2021-02-06
-6ln7,2020-08-26,2019-12-28
-7lnh,2022-03-02,2021-02-07
-6lnn,2021-01-13,2019-12-31
-1lnc,1995-05-08,1994-05-13
-6ln1,2021-10-06,2019-12-28
-5fw4,2016-04-06,2016-02-11
-7fwj,2023-06-14,2023-04-27
-7fwr,2023-06-14,2023-04-27
-8fwp,2023-07-05,2023-01-23
-7fwe,2023-06-14,2023-04-27
-7fw8,2023-06-14,2023-04-27
-3fw6,2009-03-03,2009-01-17
-6fwv,2018-08-08,2018-03-07
-6fwg,2019-09-18,2018-03-06
-1fwj,1997-10-15,1997-04-23
-3fw9,2009-05-19,2009-01-17
-1fwh,1997-10-15,1997-04-23
-4fwe,2013-01-16,2012-07-01
-4fwq,2013-06-19,2012-07-01
-5fwa,2016-11-09,2016-02-16
-5fwg,1999-01-27,1997-11-08
-7fwg,2023-06-14,2023-04-27
-4fw0,2013-05-15,2012-06-29
-6fwa,2019-02-13,2018-03-05
-8fww,2023-04-19,2023-01-23
-2fwj,2006-06-13,2006-02-02
-1fw6,2001-02-19,2000-09-21
-8fw3,2024-01-24,2023-01-20
-2fwf,2006-06-13,2006-02-02
-8fwz,2023-07-19,2023-01-23
-3fw7,2009-05-19,2009-01-17
-7fwh,2023-06-14,2023-04-27
-2fwt,2006-05-23,2006-02-03
-4fw3,2013-05-15,2012-06-29
-7fw1,2023-06-14,2023-04-27
-5fwu,2016-07-20,2016-02-21
-3fwp,2010-01-19,2009-01-19
-7fw9,2023-06-14,2023-04-27
-8fwj,2023-03-22,2023-01-22
-5fw0,2016-04-20,2016-02-10
-4fw8,2012-11-28,2012-06-30
-8fwn,2023-05-17,2023-01-23
-2fw4,2006-08-08,2006-02-01
-8fw8,2024-01-24,2023-01-20
-2fwz,2006-10-03,2006-02-03
-7fwn,2023-06-14,2023-04-27
-6fwc,2018-04-25,2018-03-06
-6fwz,2018-07-25,2018-03-07
-6fw8,2019-02-13,2018-03-05
-5fww,2016-07-20,2016-02-21
-4fwu,2012-09-05,2012-07-02
-2fwq,2006-03-14,2006-02-02
-8fw5,2023-07-26,2023-01-20
-2fwp,2006-06-13,2006-02-02
-4fwd,2013-06-26,2012-06-30
-3fwk,2009-05-26,2009-01-18
-3fw4,2010-05-05,2009-01-16
-4fw5,2013-05-15,2012-06-29
-7fwb,2023-06-14,2023-04-27
-7fwi,2023-06-14,2023-04-27
-4fwg,2013-06-26,2012-07-01
-1fwa,1997-10-15,1997-04-23
-1fw4,2001-05-02,2000-09-21
-4fwm,2013-06-19,2012-07-01
-1fws,2001-04-21,2000-09-24
-5fwp,2016-10-26,2016-02-18
-3fwj,2009-03-03,2009-01-18
-4fwn,2013-06-19,2012-07-01
-7fwo,2023-06-14,2023-04-27
-6fwm,2019-09-18,2018-03-06
-2fw5,2006-05-23,2006-02-01
-8fwu,2023-04-19,2023-01-23
-1fw1,2001-09-26,2000-09-20
-5fwz,2016-04-27,2016-02-22
-6fwb,2019-03-27,2018-03-06
-3fwv,2009-04-21,2009-01-19
-6fw9,2019-02-13,2018-03-05
-3fwn,2009-09-01,2009-01-19
-5fwd,2017-03-01,2016-02-12
-3fwa,2009-05-19,2009-01-17
-3fwr,2010-01-26,2009-01-19
-3fwl,2009-06-02,2009-01-19
-7fwy,2023-06-14,2023-04-27
-1fwm,2003-11-11,2000-09-23
-7fwp,2023-06-14,2023-04-27
-7fwd,2023-06-14,2023-04-27
-7fw7,2023-06-14,2023-04-27
-4fwf,2013-01-16,2012-07-01
-7fwm,2023-06-14,2023-04-27
-4fwx,2012-07-18,2012-07-02
-7fwk,2023-06-14,2023-04-27
-3fw5,2010-05-05,2009-01-16
-3fw3,2009-12-01,2009-01-16
-5fwt,2016-07-20,2016-02-21
-8fwr,2023-04-19,2023-01-23
-1fwv,2001-01-17,2000-09-24
-6fwp,2019-09-18,2018-03-06
-6fw7,2019-02-13,2018-03-05
-4fwh,2013-06-26,2012-07-01
-7fwa,2023-06-14,2023-04-27
-6fwi,2019-09-18,2018-03-06
-4fwj,2013-01-16,2012-07-01
-7fwl,2023-06-14,2023-04-27
-7fwq,2023-06-14,2023-04-27
-2fwo,2006-02-21,2006-02-02
-1fwz,2001-09-25,2000-09-25
-6fwh,2018-07-18,2018-03-06
-6fwq,2019-09-18,2018-03-07
-2fwe,2006-06-13,2006-02-02
-7fw0,2023-06-14,2023-04-27
-3fwg,2009-03-03,2009-01-18
-3fwy,2009-03-24,2009-01-19
-4fws,2013-06-19,2012-07-01
-1fwy,2000-10-18,2000-09-25
-1fw0,2000-11-15,2000-09-20
-6fw3,2019-03-20,2018-03-05
-4fw4,2013-05-15,2012-06-29
-8fwt,2023-04-19,2023-01-23
-4fwi,2013-01-30,2012-07-01
-1fwb,1997-10-15,1997-04-23
-3fwi,2009-03-03,2009-01-18
-4fwz,2012-07-18,2012-07-02
-7fwz,2023-06-14,2023-04-27
-6fwf,2018-03-14,2018-03-06
-8fwq,2023-04-19,2023-01-23
-5fw1,2016-04-20,2016-02-11
-1fww,2001-04-21,2000-09-24
-5fwq,2016-10-05,2016-02-19
-7fw6,2023-06-14,2023-04-27
-5fw2,2016-06-15,2016-02-11
-3fwf,2009-03-03,2009-01-18
-7fw2,2023-06-14,2023-04-27
-6fwo,2019-09-18,2018-03-06
-1fwf,1997-10-15,1997-04-23
-5fwm,2016-07-06,2016-02-18
-1fwu,2001-01-17,2000-09-24
-2fwn,2006-12-19,2006-02-02
-4fwb,2012-09-05,2012-06-30
-5fw3,2016-06-15,2016-02-11
-8fwo,2024-01-31,2023-01-23
-3fw1,2009-03-10,2009-01-16
-8fw6,2024-01-24,2023-01-20
-5fwx,2016-03-16,2016-02-21
-1fw2,2001-06-01,2000-09-21
-2fwi,2006-06-13,2006-02-02
-4fwk,2013-06-19,2012-07-01
-3fws,2010-01-26,2009-01-19
-6fw2,2018-10-31,2018-03-05
-5fwr,2016-11-30,2016-02-21
-1fwt,2001-04-21,2000-09-24
-7fwu,2023-06-14,2023-04-27
-4fw7,2013-05-15,2012-06-30
-8fwi,2023-03-22,2023-01-22
-7fwf,2023-06-14,2023-04-27
-5fws,2016-07-20,2016-02-21
-4fww,2012-08-08,2012-07-02
-4fwy,2012-07-18,2012-07-02
-1fwk,2000-12-20,2000-09-22
-3fwz,2009-02-10,2009-01-19
-3fw0,2009-09-01,2009-01-16
-3fw8,2009-05-19,2009-01-17
-6fwj,2019-09-18,2018-03-06
-7fws,2023-06-14,2023-04-27
-6fwk,2019-01-30,2018-03-06
-2fww,2006-02-14,2006-02-03
-5fwv,2016-07-20,2016-02-21
-8fwy,2023-07-19,2023-01-23
-2fw0,2007-02-06,2006-01-31
-4fwt,2012-08-08,2012-07-02
-5fwn,2016-06-01,2016-02-18
-8fw7,2023-08-30,2023-01-20
-1fwc,1997-10-15,1997-04-23
-5fwy,2016-03-16,2016-02-21
-7fww,2023-06-14,2023-04-27
-7fwx,2023-06-14,2023-04-27
-1fwx,2001-09-25,2000-09-25
-6fwl,2019-09-18,2018-03-06
-1fwi,1997-10-15,1997-04-23
-2fwu,2006-04-18,2006-02-03
-1fwd,1997-10-15,1997-04-23
-8fws,2023-04-19,2023-01-23
-4fwr,2013-06-19,2012-07-01
-7fwc,2023-06-14,2023-04-27
-5fwe,2016-04-06,2016-02-15
-4fw6,2013-05-15,2012-06-29
-8fwa,2023-06-28,2023-01-20
-3fwe,2009-09-08,2009-01-17
-4fwp,2013-06-19,2012-07-01
-6fwe,2019-03-27,2018-03-06
-1fwq,2000-10-04,2000-09-24
-2fwy,2006-10-03,2006-02-03
-8fwv,2023-04-19,2023-01-23
-2fwl,2006-03-28,2006-02-02
-4fwo,2013-06-19,2012-07-01
-8fw0,2024-01-24,2023-01-20
-1fwg,1997-10-15,1997-04-23
-2fws,2006-04-18,2006-02-03
-7fwv,2023-06-14,2023-04-27
-8fw1,2023-06-28,2023-01-20
-6fws,2018-12-19,2018-03-07
-1fwe,1997-10-15,1997-04-23
-5fwj,2016-04-13,2016-02-17
-3fwx,2009-03-17,2009-01-19
-5fwk,2016-07-06,2016-02-17
-5fw5,2016-07-20,2016-02-12
-5fwl,2016-07-06,2016-02-18
-7fw3,2023-06-14,2023-04-27
-6fw0,2018-04-25,2018-03-05
-4o8x,2014-01-22,2013-12-30
-7o8o,2022-02-09,2021-04-15
-3o86,2010-11-03,2010-08-02
-3o82,2010-10-06,2010-08-02
-4o86,2014-12-31,2013-12-26
-5o8h,2017-10-11,2017-06-13
-6o8y,2020-09-23,2019-03-12
-1o8p,2003-03-13,2002-11-28
-7o86,2021-09-22,2021-04-14
-3o84,2010-10-06,2010-08-02
-1o8l,2003-01-30,2002-11-27
-6o8b,2019-05-22,2019-03-09
-1o86,2003-02-07,2002-11-25
-4o8e,2014-01-22,2013-12-27
-3o80,2010-10-13,2010-08-02
-1o8a,2003-02-07,2002-11-26
-4o8f,2014-07-23,2013-12-27
-3o8h,2010-09-01,2010-08-03
-6o88,2019-06-12,2019-03-09
-3o8m,2010-10-13,2010-08-03
-1o8u,2003-01-24,2002-12-04
-2o8g,2007-07-17,2006-12-12
-3o8y,2011-01-19,2010-08-03
-6o86,2019-06-12,2019-03-09
-7o8p,2022-02-09,2021-04-15
-3o8l,2011-02-02,2010-08-03
-7o8u,2022-02-09,2021-04-15
-5o8q,2017-10-11,2017-06-14
-2o8j,2007-01-16,2006-12-12
-5o8x,2017-11-29,2017-06-14
-3o8i,2010-09-29,2010-08-03
-5o84,2017-10-25,2017-06-12
-5o83,2017-09-20,2017-06-12
-7o8j,2022-02-09,2021-04-15
-7o8r,2022-02-09,2021-04-15
-3o8r,2011-01-05,2010-08-03
-4o8r,2014-01-22,2013-12-29
-4o8n,2014-07-02,2013-12-28
-4o8m,2014-01-22,2013-12-28
-5o86,2017-09-13,2017-06-12
-3o8q,2010-08-18,2010-08-03
-6o8z,2020-09-16,2019-03-12
-5o8u,2017-09-06,2017-06-14
-1o8j,2003-01-30,2002-11-27
-5o8i,2017-06-28,2017-06-13
-7o8q,2022-02-09,2021-04-15
-5o82,2018-06-27,2017-06-12
-3o8g,2010-09-01,2010-08-03
-7o8i,2022-02-09,2021-04-15
-7o83,2022-04-20,2021-04-14
-4o8j,2014-09-10,2013-12-27
-1o8g,2003-01-30,2002-11-27
-4o8o,2014-07-02,2013-12-28
-3o8x,2010-09-29,2010-08-03
-2o88,2007-05-01,2006-12-12
-2o8q,2006-12-26,2006-12-12
-4o84,2014-12-31,2013-12-26
-7o8k,2022-02-09,2021-04-15
-3o8c,2011-01-05,2010-08-02
-4o8p,2014-07-02,2013-12-28
-5o80,2018-06-27,2017-06-12
-5o8p,2018-06-27,2017-06-14
-5o8r,2018-02-28,2017-06-14
-6o83,2019-06-19,2019-03-08
-2o8e,2007-06-05,2006-12-12
-2o8m,2007-10-09,2006-12-12
-6o8i,2019-04-03,2019-03-11
-5o8d,2017-09-13,2017-06-13
-2o8h,2007-01-09,2006-12-12
-6o8d,2019-11-20,2019-03-09
-7o8l,2022-02-09,2021-04-15
-6o8g,2020-01-22,2019-03-10
-5o8w,2017-08-23,2017-06-14
-1o8f,2003-01-30,2002-11-27
-1o8b,2003-01-24,2002-11-26
-1o87,2004-01-02,2002-11-25
-2o84,2007-01-23,2006-12-12
-4o81,2014-12-31,2013-12-26
-6o81,2019-05-15,2019-03-08
-6o80,2019-05-01,2019-03-08
-4o8a,2014-01-15,2013-12-26
-5o8l,2017-11-29,2017-06-13
-6o8w,2020-09-23,2019-03-12
-4o8c,2014-06-18,2013-12-27
-7o8s,2022-02-09,2021-04-15
-7o8z,2022-02-09,2021-04-15
-3o8d,2011-01-05,2010-08-02
-6o85,2019-05-15,2019-03-08
-2o8b,2007-06-05,2006-12-12
-7o8y,2022-02-09,2021-04-15
-2o8o,2007-12-11,2006-12-12
-3o83,2010-10-06,2010-08-02
-5o8e,2017-09-13,2017-06-13
-5o8f,2017-11-01,2017-06-13
-5o8z,2017-11-15,2017-06-14
-7o8v,2022-02-09,2021-04-15
-3o8o,2011-02-02,2010-08-03
-3o89,2011-12-07,2010-08-02
-5o8n,2017-08-09,2017-06-13
-4o8g,2014-10-01,2013-12-27
-7o8f,2022-02-09,2021-04-15
-5o8t,2018-06-27,2017-06-14
-2o86,2006-12-26,2006-12-12
-1o8s,2003-03-13,2002-11-28
-3o8n,2011-02-02,2010-08-03
-6o8u,2019-05-22,2019-03-12
-6o8m,2020-04-01,2019-03-11
-1o8c,2004-05-21,2002-11-26
-1o8k,2003-01-30,2002-11-27
-3o8a,2010-08-18,2010-08-02
-4o8z,2015-04-22,2013-12-31
-7o8t,2022-02-09,2021-04-15
-7o8a,2021-12-01,2021-04-15
-7o84,2021-07-28,2021-04-14
-6o82,2019-06-19,2019-03-08
-3o87,2010-11-03,2010-08-02
-6o87,2019-06-12,2019-03-09
-6o8v,2024-05-01,2019-03-12
-4o83,2014-12-31,2013-12-26
-6o8x,2020-09-23,2019-03-12
-3o8u,2010-09-01,2010-08-03
-7o8m,2022-02-09,2021-04-15
-5o87,2018-06-27,2017-06-12
-2o8d,2007-06-05,2006-12-12
-7o8n,2022-02-09,2021-04-15
-1o8h,2003-01-30,2002-11-27
-2o8c,2007-06-05,2006-12-12
-1o88,2003-01-30,2002-11-26
-7o8d,2021-12-01,2021-04-15
-2o8l,2007-01-02,2006-12-12
-1o8d,2003-01-30,2002-11-27
-7o8h,2022-02-09,2021-04-15
-3o8e,2010-10-13,2010-08-03
-7o85,2021-04-28,2021-04-14
-5o85,2017-10-18,2017-06-12
-4o82,2014-12-31,2013-12-26
-5o8v,2017-09-06,2017-06-14
-2o8f,2007-06-05,2006-12-12
-3o8t,2010-11-17,2010-08-03
-6o8c,2019-05-22,2019-03-09
-6o8f,2020-01-22,2019-03-10
-1o8e,2003-01-30,2002-11-27
-6o8e,2020-01-22,2019-03-10
-1o84,2003-11-20,2002-11-25
-2o8w,2007-12-25,2006-12-12
-3o8p,2010-09-01,2010-08-03
-3o8b,2011-01-05,2010-08-02
-3o88,2010-11-03,2010-08-02
-7o87,2022-10-26,2021-04-14
-7o8g,2022-02-09,2021-04-15
-2q1j,2007-08-14,2007-05-24
-1q1y,2004-07-23,2003-07-23
-2q1t,2007-10-02,2007-05-25
-6q1h,2019-12-25,2019-08-04
-5q1s,2018-08-08,2017-05-15
-7q1i,2022-04-06,2021-10-20
-5q11,2017-07-05,2017-05-31
-1q1w,2004-02-24,2003-07-22
-1q17,2003-11-18,2003-07-18
-4q1e,2014-11-05,2014-04-03
-5q12,2017-07-05,2017-05-31
-3q1r,2011-03-09,2010-12-17
-8q18,2023-11-08,2023-07-31
-1q12,2003-09-30,2003-07-18
-4q1j,2015-05-06,2014-04-03
-2q1y,2008-05-06,2007-05-25
-5q1j,2018-08-08,2017-05-15
-2q10,2007-06-05,2007-05-23
-7q19,2022-05-11,2021-10-18
-1q1a,2003-11-18,2003-07-18
-3q1f,2011-12-21,2010-12-17
-7q1m,2022-11-16,2021-10-20
-6q1l,2021-04-07,2019-08-05
-5q1d,2017-07-05,2017-05-31
-6q1s,2020-09-23,2019-08-05
-3q11,2012-01-04,2010-12-16
-4q1l,2015-04-08,2014-04-03
-2q1l,2007-07-17,2007-05-24
-7q1k,2022-08-31,2021-10-20
-1q16,2003-10-07,2003-07-18
-3q1k,2011-01-12,2010-12-17
-7q1n,2022-11-16,2021-10-20
-4q1v,2014-05-07,2014-04-04
-8q1u,2024-06-05,2023-08-01
-8q1x,2023-12-06,2023-08-01
-3q1e,2011-05-04,2010-12-17
-6q1v,2019-12-11,2019-08-06
-5q18,2017-07-05,2017-05-31
-4q17,2014-09-10,2014-04-03
-7q1o,2022-11-16,2021-10-20
-4q1q,2014-09-17,2014-04-04
-3q1d,2011-01-26,2010-12-17
-4q10,2014-08-27,2014-04-02
-5q16,2017-07-05,2017-05-31
-6q18,2019-12-18,2019-08-03
-4q1o,2014-09-10,2014-04-04
-4q1f,2014-11-05,2014-04-03
-8q17,2023-11-22,2023-07-30
-4q1b,2015-02-18,2014-04-03
-5q1g,2017-07-05,2017-05-31
-3q1x,2011-02-02,2010-12-18
-1q1f,2004-06-08,2003-07-19
-3q10,2011-02-02,2010-12-16
-5q1h,2017-07-05,2017-05-31
-1q14,2003-09-30,2003-07-18
-4q1r,2015-10-07,2014-04-04
-5q1k,2018-08-08,2017-05-15
-7q11,2022-04-13,2021-10-17
-8q19,2023-11-08,2023-07-31
-1q1p,2004-04-20,2003-07-22
-7q13,2022-07-27,2021-10-17
-5q1u,2018-08-08,2017-05-15
-4q1h,2015-05-06,2014-04-03
-4q1s,2014-07-30,2014-04-04
-4q1w,2015-02-18,2014-04-04
-4q1a,2015-02-18,2014-04-03
-8q1j,2024-05-15,2023-07-31
-1q1r,2004-02-24,2003-07-22
-8q1b,2023-11-15,2023-07-31
-7q1j,2022-04-06,2021-10-20
-3q1y,2011-01-19,2010-12-18
-4q1u,2015-02-18,2014-04-04
-6q17,2020-04-29,2019-08-02
-5q1z,2018-08-08,2017-05-15
-3q1g,2011-06-01,2010-12-17
-4q1c,2014-11-05,2014-04-03
-5q1q,2018-08-08,2017-05-15
-2q1f,2008-01-29,2007-05-24
-4q1p,2015-10-07,2014-04-04
-7q1e,2022-04-13,2021-10-19
-5q1i,2017-07-05,2017-05-31
-5q1t,2018-08-08,2017-05-15
-3q1m,2011-06-15,2010-12-17
-5q1b,2017-07-05,2017-05-31
-2q16,2008-02-19,2007-05-23
-7q1z,2022-03-09,2021-10-22
-4q1n,2014-08-06,2014-04-04
-4q13,2015-04-08,2014-04-02
-2q17,2008-04-01,2007-05-23
-6q1n,2020-08-19,2019-08-05
-1q1g,2004-03-16,2003-07-19
-5q1m,2018-08-08,2017-05-15
-7q1p,2022-11-16,2021-10-20
-2q14,2007-06-12,2007-05-23
-7q1h,2022-05-04,2021-10-20
-5q17,2017-07-05,2017-05-31
-1q19,2003-11-04,2003-07-18
-2q1u,2007-10-02,2007-05-25
-4q1d,2015-02-18,2014-04-03
-7q1u,2022-06-08,2021-10-21
-5q1p,2018-08-08,2017-05-15
-5q1x,2018-08-08,2017-05-15
-5q1f,2017-07-05,2017-05-31
-1q1s,2004-03-30,2003-07-22
-1q1n,2004-08-03,2003-07-22
-1q1m,2003-09-16,2003-07-22
-7q1d,2022-11-02,2021-10-18
-5q13,2017-07-05,2017-05-31
-3q14,2011-12-21,2010-12-16
-2q1h,2007-09-04,2007-05-24
-6q1p,2020-08-19,2019-08-05
-7q14,2022-11-16,2021-10-18
-2q15,2007-08-14,2007-05-23
-2q1q,2007-09-11,2007-05-25
-5q1e,2017-07-05,2017-05-31
-8q1s,2024-02-21,2023-08-01
-8q1w,2024-03-13,2023-08-01
-5q1v,2018-08-08,2017-05-15
-8q1r,2023-10-25,2023-08-01
-7q1f,2022-04-20,2021-10-19
-2q1w,2007-10-02,2007-05-25
-3q13,2011-06-29,2010-12-16
-8q1y,2024-06-05,2023-08-01
-5q1a,2017-07-05,2017-05-31
-6q1b,2021-02-03,2019-08-03
-4q19,2014-11-05,2014-04-03
-5q19,2017-07-05,2017-05-31
-2q1a,2008-04-08,2007-05-24
-3q15,2011-02-23,2010-12-16
-1q1k,2004-03-02,2003-07-21
-3q1i,2011-04-27,2010-12-17
-5q10,2017-07-05,2017-05-31
-7q1x,2022-11-02,2021-10-21
-8q1a,2023-11-08,2023-07-31
-8q1h,2024-05-15,2023-07-31
-5q1w,2018-08-08,2017-05-15
-2q11,2007-08-14,2007-05-23
-5q15,2017-07-05,2017-05-31
-8q1m,2024-04-03,2023-07-31
-3q1o,2011-01-12,2010-12-17
-6q11,2019-11-27,2019-08-02
-5q1o,2018-08-08,2017-05-15
-8q1z,2023-08-16,2023-08-01
-3q12,2011-02-02,2010-12-16
-7q1y,2022-04-20,2021-10-22
-5q1r,2018-08-08,2017-05-15
-6q13,2020-09-23,2019-08-02
-4q12,2014-04-23,2014-04-02
-4q15,2016-04-20,2014-04-02
-7q1c,2021-12-15,2021-10-18
-1q11,2004-01-06,2003-07-18
-2q1v,2007-09-04,2007-05-25
-5q1y,2018-08-08,2017-05-15
-6q1d,2019-09-04,2019-08-03
-1q13,2004-11-16,2003-07-18
-8q1q,2023-10-25,2023-08-01
-2q1d,2008-04-08,2007-05-24
-4q1x,2015-02-18,2014-04-04
-2q1c,2008-04-08,2007-05-24
-8q1p,2024-06-05,2023-08-01
-6q1r,2020-09-23,2019-08-05
-2q1b,2007-09-04,2007-05-24
-5q1c,2017-07-05,2017-05-31
-5q1l,2018-08-08,2017-05-15
-5q14,2017-07-05,2017-05-31
-1q1t,2004-03-30,2003-07-22
-3q19,2012-01-25,2010-12-16
-8q1v,2024-03-13,2023-08-01
-2q1s,2007-10-02,2007-05-25
-8q1g,2024-05-15,2023-07-31
-7q1w,2022-03-16,2021-10-21
-7q15,2022-09-28,2021-10-18
-6q1u,2020-04-15,2019-08-06
-4q18,2014-11-05,2014-04-03
-5q1n,2018-08-08,2017-05-15
-7q1l,2022-03-16,2021-10-20
-2q1z,2007-09-18,2007-05-25
-7q1b,2021-12-15,2021-10-18
-6q1y,2019-08-14,2019-08-06
-6q1z,2019-10-23,2019-08-06
-8q1t,2024-06-05,2023-08-01
-8q1k,2023-12-06,2023-07-31
-2q1n,2007-06-05,2007-05-25
-1q1q,2003-11-11,2003-07-22
-7q1r,2022-07-20,2021-10-20
-7q10,2022-11-02,2021-10-17
-7q12,2022-07-27,2021-10-17
-1q1z,2003-11-11,2003-07-23
-4q1y,2015-02-18,2014-04-04
-1ke6,2002-05-14,2001-11-14
-1ke3,2002-07-17,2001-11-14
-7kev,2021-11-24,2020-10-12
-6key,2020-07-01,2019-07-05
-5ke6,2016-09-14,2016-06-09
-5ket,2017-01-18,2016-06-10
-3ken,2010-03-16,2009-10-26
-5ke4,2016-07-06,2016-06-09
-6kep,2019-10-02,2019-07-04
-6ked,2020-07-08,2019-07-04
-3ke1,2009-11-10,2009-10-23
-2ke5,2009-02-17,2009-01-23
-3ke0,2010-10-27,2009-10-23
-7ked,2021-06-23,2020-10-10
-5kee,2016-06-22,2016-06-09
-6ke2,2019-10-23,2019-07-03
-7ke4,2020-11-04,2020-10-10
-4ker,2013-10-02,2013-04-26
-2ke1,2009-05-26,2009-01-22
-1ker,2002-01-25,2001-11-17
-7ke3,2021-09-01,2020-10-10
-1ke5,2002-05-14,2001-11-14
-7ke2,2021-07-14,2020-10-09
-3kef,2010-01-12,2009-10-26
-1kec,2003-09-02,2001-11-15
-6kec,2020-07-08,2019-07-04
-7ke9,2020-11-04,2020-10-10
-4kel,2014-04-30,2013-04-25
-4kev,2013-10-02,2013-04-26
-1keq,2002-03-06,2001-11-16
-4keq,2014-04-09,2013-04-26
-7kex,2021-04-28,2020-10-13
-6ke5,2019-10-23,2019-07-03
-3keh,2010-10-27,2009-10-26
-7kei,2021-10-13,2020-10-10
-3ke5,2010-10-20,2009-10-23
-5ke2,2016-07-13,2016-06-09
-7ke6,2020-11-04,2020-10-10
-8ke5,2023-11-01,2023-08-11
-1ke0,2002-07-17,2001-11-13
-5kej,2017-02-01,2016-06-09
-4kew,2013-07-10,2013-04-26
-6keh,2020-07-08,2019-07-04
-6keu,2020-07-08,2019-07-05
-3kec,2010-11-10,2009-10-25
-1kej,2002-05-16,2001-11-16
-7kec,2020-11-04,2020-10-10
-8ke2,2023-11-01,2023-08-11
-4keb,2013-10-09,2013-04-25
-5kea,2016-09-14,2016-06-09
-7kel,2021-10-13,2020-10-11
-5ker,2017-04-05,2016-06-10
-5kel,2016-09-07,2016-06-09
-4kec,2013-05-22,2013-04-25
-6ke4,2019-10-23,2019-07-03
-6kee,2020-07-08,2019-07-04
-4ket,2013-10-02,2013-04-26
-3keq,2010-11-10,2009-10-26
-7keq,2021-01-20,2020-10-11
-5ke9,2016-09-14,2016-06-09
-3keu,2009-11-03,2009-10-26
-1kep,2002-01-25,2001-11-16
-6ken,2019-10-02,2019-07-04
-4keh,2013-12-25,2013-04-25
-6ke3,2019-09-25,2019-07-03
-7kes,2020-10-21,2020-10-12
-1ke8,2002-05-14,2001-11-14
-7kee,2021-06-23,2020-10-10
-5kew,2016-07-20,2016-06-10
-7kek,2021-09-29,2020-10-11
-5ken,2016-09-07,2016-06-09
-1keo,2002-01-23,2001-11-16
-1kew,2002-01-25,2001-11-17
-6keo,2019-10-02,2019-07-04
-8ke3,2023-11-01,2023-08-11
-3kew,2009-11-03,2009-10-26
-7kea,2020-11-04,2020-10-10
-5kez,2017-03-29,2016-06-10
-5keu,2016-06-22,2016-06-10
-7ke1,2021-06-09,2020-10-09
-6kev,2020-05-13,2019-07-05
-6ke6,2020-08-05,2019-07-03
-1keb,2002-11-13,2001-11-15
-3kej,2010-11-10,2009-10-26
-8ke6,2023-11-01,2023-08-11
-7kew,2021-04-28,2020-10-13
-7kej,2021-06-23,2020-10-11
-3kex,2009-12-22,2009-10-26
-5ke3,2016-08-03,2016-06-09
-6kej,2020-07-08,2019-07-04
-1kei,2002-11-16,2001-11-16
-3kek,2010-11-10,2009-10-26
-6kez,2020-05-13,2019-07-05
-4keg,2014-04-30,2013-04-25
-6keb,2019-10-23,2019-07-04
-5ke0,2016-07-06,2016-06-09
-4ke7,2013-09-18,2013-04-25
-5kef,2017-01-18,2016-06-09
-4kep,2014-04-09,2013-04-26
-4ke6,2013-09-18,2013-04-25
-1ket,2002-01-25,2001-11-17
-7kef,2021-06-23,2020-10-10
-3ke8,2010-01-12,2009-10-24
-1ke9,2002-05-14,2001-11-14
-1keg,2002-11-15,2001-11-15
-8kei,2024-05-22,2023-08-11
-7ke7,2020-11-04,2020-10-10
-6kek,2020-07-08,2019-07-04
-3keo,2010-11-10,2009-10-26
-3ked,2010-11-03,2009-10-25
-4kes,2013-10-02,2013-04-26
-1kek,2001-12-21,2001-11-16
-1ken,2002-04-24,2001-11-16
-5keb,2016-09-14,2016-06-09
-3kez,2009-11-10,2009-10-26
-8ke1,2023-11-01,2023-08-11
-3ke6,2010-11-10,2009-10-24
-4kez,2013-10-02,2013-04-26
-6ker,2019-10-02,2019-07-04
-6kei,2020-07-08,2019-07-04
-4keu,2013-10-02,2013-04-26
-3kem,2010-01-12,2009-10-26
-1ke7,2002-05-14,2001-11-14
-3kei,2010-02-09,2009-10-26
-4ke0,2013-07-03,2013-04-25
-1kea,2002-01-23,2001-11-14
-5keg,2017-05-10,2016-06-09
-3keg,2010-01-12,2009-10-26
-1kel,1996-12-07,1996-04-16
-4ken,2014-10-29,2013-04-25
-6kef,2020-07-08,2019-07-04
-6ke0,2019-08-14,2019-07-03
-7key,2022-01-19,2020-10-13
-7ker,2021-01-20,2020-10-12
-1kee,2001-12-21,2001-11-15
-7keb,2020-11-04,2020-10-10
-7ke5,2021-09-01,2020-10-10
-8ke4,2023-11-01,2023-08-11
-3kee,2010-03-09,2009-10-26
-6keg,2020-07-08,2019-07-04
-4key,2013-07-10,2013-04-26
-5ke8,2016-09-14,2016-06-09
-1keu,2002-01-25,2001-11-17
-2kem,2009-06-02,2009-01-30
-3ket,2010-11-10,2009-10-26
-4ke5,2013-05-15,2013-04-25
-3ke9,2010-01-12,2009-10-24
-4kem,2013-05-15,2013-04-25
-4ke1,2013-07-03,2013-04-25
-7ke0,2021-09-22,2020-10-09
-3ker,2010-10-13,2009-10-26
-7kep,2021-01-20,2020-10-11
-5ke7,2016-09-14,2016-06-09
-7ke8,2020-11-04,2020-10-10
-7kem,2020-11-18,2020-10-11
-1kev,1997-10-22,1996-10-21
-5ke1,2017-03-15,2016-06-09
-1yax,2005-12-27,2004-12-17
-4yar,2015-03-04,2015-02-17
-7ya0,2022-09-21,2022-06-26
-6yac,2020-09-30,2020-03-12
-5yap,2018-05-23,2017-09-01
-6yaa,2020-05-20,2020-03-11
-1yak,2005-02-22,2004-12-17
-7ya3,2023-07-12,2022-06-27
-7yae,2023-04-19,2022-06-28
-1yaa,1998-09-16,1998-01-27
-6yap,2020-10-14,2020-03-12
-4yat,2015-06-24,2015-02-17
-4ya8,2015-12-09,2015-02-17
-6yax,2021-10-06,2020-03-14
-4ya4,2015-06-17,2015-02-17
-2yay,2011-03-16,2011-02-25
-2yaz,2011-03-16,2011-02-25
-1yas,1997-06-16,1996-05-15
-2ya5,2011-04-27,2011-02-18
-4ya0,2015-06-17,2015-02-17
-2yak,2011-04-27,2011-02-23
-2yat,2011-06-01,2011-02-24
-5yao,2018-06-27,2017-09-01
-6yab,2021-02-10,2020-03-12
-2yap,2012-02-29,2011-02-23
-7yaj,2023-03-22,2022-06-28
-2ya2,2011-04-20,2011-02-17
-2ya0,2011-04-20,2011-02-17
-4ya2,2015-06-17,2015-02-17
-7yam,2023-03-22,2022-06-28
-4yav,2016-03-09,2015-02-17
-4yao,2016-03-02,2015-02-17
-2yaw,2011-12-21,2011-02-25
-6yau,2021-01-13,2020-03-13
-2yah,2012-02-29,2011-02-22
-5yax,2017-10-11,2017-09-02
-2yam,2012-02-29,2011-02-23
-1yaz,2000-01-12,1998-12-23
-4ya7,2015-06-17,2015-02-17
-2ya8,2011-04-27,2011-02-18
-2yae,2012-02-29,2011-02-21
-4yad,2015-06-24,2015-02-17
-4yaw,2016-03-02,2015-02-17
-1yai,1997-08-20,1996-02-03
-2yav,2011-12-21,2011-02-25
-5yal,2017-12-06,2017-09-01
-6yao,2020-10-14,2020-03-12
-5yav,2018-09-05,2017-09-01
-2ya6,2011-04-27,2011-02-18
-6yaf,2020-07-29,2020-03-12
-5yaw,2018-09-05,2017-09-01
-2ya1,2011-04-20,2011-02-17
-2ya9,2011-04-13,2011-02-18
-2yaq,2012-02-29,2011-02-24
-4yan,2015-12-16,2015-02-17
-1yap,1996-04-03,1995-09-29
-4yac,2016-03-09,2015-02-17
-5yas,1999-10-13,1999-03-15
-5yak,2018-08-08,2017-09-01
-2yac,2011-04-06,2011-02-18
-1ya4,2005-08-02,2004-12-17
-6ya5,2020-09-09,2020-03-11
-5ya6,2019-02-06,2017-08-30
-7yab,2023-06-28,2022-06-27
-2yab,2011-04-13,2011-02-18
-6ya8,2020-05-27,2020-03-11
-5yat,2018-03-21,2017-09-01
-7ya9,2023-07-05,2022-06-27
-7yaw,2023-08-09,2022-06-28
-6ya0,2020-09-30,2020-03-11
-7ya1,2022-08-31,2022-06-27
-2yau,2012-01-11,2011-02-24
-4yal,2016-03-02,2015-02-17
-2yar,2012-02-29,2011-02-24
-6yav,2021-03-31,2020-03-13
-7yad,2022-08-31,2022-06-27
-6ya4,2021-02-10,2020-03-11
-4ya9,2015-06-17,2015-02-17
-6yar,2021-02-24,2020-03-12
-1ya8,2005-08-02,2004-12-17
-1yao,1996-04-03,1995-09-29
-4yax,2015-06-24,2015-02-18
-2ya3,2011-03-16,2011-02-17
-2yan,2011-11-30,2011-02-23
-4ya1,2015-06-17,2015-02-17
-7yai,2023-03-22,2022-06-28
-1yat,1993-10-31,1993-01-06
-4ya3,2015-06-17,2015-02-17
-8ya7,2024-02-28,2024-02-07
-6ya3,2021-02-10,2020-03-11
-1yag,1999-10-09,1998-10-09
-6ya1,2021-02-03,2020-03-11
-7yac,2023-04-19,2022-06-27
-2yal,2011-06-08,2011-02-23
-5ya8,2018-05-23,2017-08-31
-6yaw,2020-08-26,2020-03-13
-6ya6,2020-05-27,2020-03-11
-7ya5,2023-11-15,2022-06-27
-6yak,2020-11-25,2020-03-12
-7yag,2023-03-22,2022-06-28
-4yah,2015-04-08,2015-02-17
-1yan,1996-04-03,1995-09-29
-7yav,2024-01-24,2022-06-28
-4yaf,2016-03-09,2015-02-17
-2ya7,2011-04-27,2011-02-18
-4yai,2016-03-09,2015-02-17
-4yas,1999-10-13,1999-03-15
-1ya6,2005-08-30,2004-12-17
-4yau,2016-03-02,2015-02-17
-6ya2,2020-09-30,2020-03-11
-1yaj,2005-08-02,2004-12-17
-1yam,1996-04-03,1995-09-29
-4yay,2015-04-22,2015-02-18
-6yal,2020-04-08,2020-03-12
-7ya4,2023-07-12,2022-06-27
-6yam,2020-04-08,2020-03-12
-6yaq,2020-10-14,2020-03-12
-4ya5,2015-06-17,2015-02-17
-5yaq,2018-05-23,2017-09-01
-6yay,2021-02-24,2020-03-14
-1yae,2005-02-01,2004-12-17
-1yaq,1996-04-03,1995-09-29
-6yag,2021-02-10,2020-03-12
-2yaa,2011-04-13,2011-02-18
-5ya1,2018-07-11,2017-08-29
-4yaj,2016-01-27,2015-02-17
-7yaz,2023-08-09,2022-06-28
-4yaq,2015-06-03,2015-02-17
-4yak,2016-01-27,2015-02-17
-6yat,2020-04-29,2020-03-13
-7yah,2023-03-22,2022-06-28
-5ya2,2018-07-11,2017-08-30
-2yaj,2011-09-21,2011-02-23
-1yah,2005-08-02,2004-12-17
-2yao,2012-02-29,2011-02-23
-7yaa,2023-11-15,2022-06-27
-5ya5,2018-07-04,2017-08-30
-2yaf,2012-02-29,2011-02-22
-4yag,2016-03-09,2015-02-17
-2yax,2011-12-21,2011-02-25
-6ya7,2020-05-27,2020-03-11
-6ya9,2021-10-06,2020-03-11
-1ya3,2005-05-24,2004-12-17
-4yab,2015-06-24,2015-02-17
-4g5p,2012-08-29,2012-07-18
-2g5p,2006-07-04,2006-02-23
-6g5a,2018-08-22,2018-03-29
-6g5v,2018-07-04,2018-03-30
-8g5d,2023-05-10,2023-02-13
-4g55,2012-08-01,2012-07-17
-3g5n,2009-05-12,2009-02-05
-4g5d,2012-08-15,2012-07-17
-1g5g,2002-02-27,2000-11-01
-1g50,2002-02-06,2000-10-30
-4g5j,2012-08-29,2012-07-18
-3g5s,2009-05-19,2009-02-05
-1g55,2001-01-17,2000-10-30
-2g5g,2006-10-03,2006-02-22
-8g5c,2023-05-10,2023-02-12
-1g53,2000-11-08,2000-10-30
-3g53,2009-12-01,2009-02-04
-3g50,2009-04-28,2009-02-04
-5g5k,2017-05-17,2016-05-25
-3g51,2009-12-15,2009-02-04
-1g5a,2001-10-31,2000-10-31
-1g54,2000-11-08,2000-10-30
-5g54,2016-10-19,2016-05-19
-8g5b,2024-02-21,2023-02-12
-4g5o,2012-09-05,2012-07-18
-3g5d,2009-06-02,2009-02-05
-6g5b,2018-08-22,2018-03-29
-6g5m,2019-04-10,2018-03-29
-2g5f,2006-09-05,2006-02-22
-2g50,2006-05-09,2006-02-22
-2g54,2006-10-24,2006-02-22
-3g5c,2009-08-18,2009-02-04
-5g5s,2017-02-08,2016-06-03
-5g5w,2017-02-15,2016-06-08
-4g5g,2012-12-26,2012-07-17
-1g52,2000-11-08,2000-10-30
-2g5b,2006-07-25,2006-02-22
-8g5w,2023-06-28,2023-02-14
-5g56,2016-06-29,2016-05-21
-6g55,2018-10-31,2018-03-29
-5g5z,2017-01-18,2016-06-10
-4g50,2012-08-01,2012-07-17
-6g59,2018-05-30,2018-03-29
-5g55,2016-08-03,2016-05-20
-2g5z,2006-04-18,2006-02-23
-5g5j,2017-06-07,2016-05-25
-2g5o,2007-03-06,2006-02-23
-6g5l,2019-03-13,2018-03-29
-5g53,2016-08-03,2016-05-19
-1g5s,2001-11-02,2000-11-02
-3g5e,2009-03-24,2009-02-05
-6g50,2019-04-10,2018-03-28
-2g5c,2006-03-07,2006-02-22
-3g5i,2010-02-09,2009-02-05
-6g58,2018-05-30,2018-03-29
-3g5t,2009-03-03,2009-02-05
-3g5h,2009-04-21,2009-02-05
-6g5j,2018-09-05,2018-03-29
-5g5m,2017-06-21,2016-05-26
-1g5q,2001-05-02,2000-11-02
-8g5x,2023-06-28,2023-02-14
-6g5n,2018-04-11,2018-03-29
-3g5f,2009-04-21,2009-02-05
-3g5w,2009-02-17,2009-02-05
-1g5f,2001-11-01,2000-11-01
-6g5y,2018-06-27,2018-03-30
-6g5o,2018-11-21,2018-03-29
-5g5v,2018-03-14,2016-06-06
-3g5a,2009-05-26,2009-02-04
-1g5u,2000-11-22,2000-11-02
-4g59,2012-12-19,2012-07-17
-4g5r,2012-09-05,2012-07-18
-5g5f,2017-02-01,2016-05-24
-1g5n,2001-06-06,2000-11-01
-5g5l,2016-07-27,2016-05-26
-6g5w,2019-04-10,2018-03-30
-1g5b,2001-03-07,2000-10-31
-2g5n,2006-08-29,2006-02-23
-5g5h,2016-09-28,2016-05-25
-8g5h,2023-09-20,2023-02-13
-1g51,2000-12-06,2000-10-30
-4g5i,2012-11-07,2012-07-18
-3g58,2010-01-19,2009-02-04
-4g5q,2012-09-05,2012-07-18
-6g5q,2018-11-21,2018-03-29
-4g5h,2013-08-28,2012-07-18
-4g5s,2012-09-05,2012-07-18
-3g5u,2009-03-24,2009-02-05
-2g5i,2006-07-18,2006-02-23
-6g5i,2018-06-06,2018-03-29
-5g52,2017-03-22,2016-05-18
-6g5z,2019-04-10,2018-03-30
-1g5t,2000-11-22,2000-11-02
-2g5w,2006-04-04,2006-02-23
-5g5d,2017-04-05,2016-05-23
-8g5f,2023-09-20,2023-02-13
-8g5a,2024-02-21,2023-02-12
-1g58,2001-04-30,2000-10-30
-1g57,2001-04-30,2000-10-30
-6g5g,2019-01-16,2018-03-29
-2g5u,2006-03-07,2006-02-23
-8g5g,2023-09-20,2023-02-13
-3g5r,2009-05-19,2009-02-05
-8g5u,2023-10-18,2023-02-14
-3g5q,2009-05-19,2009-02-05
-8g59,2023-03-08,2023-02-12
-6g5c,2018-10-24,2018-03-29
-5g57,2017-11-29,2016-05-22
-8g50,2024-01-03,2023-02-10
-6g5h,2018-06-06,2018-03-29
-5g58,2017-05-03,2016-05-22
-6g5t,2018-08-22,2018-03-30
-4g5y,2013-07-03,2012-07-18
-3g59,2009-05-26,2009-02-04
-1g5i,2001-03-14,2000-11-01
-3g5p,2009-04-07,2009-02-05
-8g5y,2023-04-19,2023-02-14
-6g5p,2018-04-11,2018-03-29
-5g5a,2017-06-07,2016-05-23
-3g52,2009-12-01,2009-02-04
-4g51,2013-01-16,2012-07-17
-8g5z,2023-04-19,2023-02-14
-2g5v,2006-08-29,2006-02-23
-3g5m,2009-03-24,2009-02-05
-1g5c,2001-04-04,2000-10-31
-1g5y,2001-05-02,2000-11-02
-4g56,2012-10-03,2012-07-17
-2g5h,2006-07-18,2006-02-23
-1g5h,2001-03-14,2000-11-01
-6g5u,2019-03-13,2018-03-30
-3g5k,2009-04-07,2009-02-05
-5g59,2017-06-21,2016-05-23
-2g5r,2006-06-20,2006-02-23
-2g58,2006-03-28,2006-02-22
-2g5l,2007-02-06,2006-02-23
-2g55,2007-02-20,2006-02-22
-5g5y,2017-01-18,2016-06-10
-5g50,2017-11-29,2016-05-18
-4g5f,2013-07-17,2012-07-17
-6g5x,2019-04-10,2018-03-30
-5g5x,2017-05-24,2016-06-09
-5g5t,2017-02-08,2016-06-03
-6g54,2019-02-27,2018-03-29
-5g5g,2016-09-28,2016-05-25
-2g5t,2006-07-04,2006-02-23
-5gin,2016-09-14,2016-06-24
-2gij,2006-07-18,2006-03-28
-3gik,2009-05-19,2009-03-05
-1gik,2003-09-30,2001-02-07
-7gih,2023-11-08,2023-08-11
-5giy,2017-07-19,2016-06-25
-1gin,1997-02-12,1996-06-18
-1gi1,2002-01-22,2001-01-22
-7gic,2023-11-08,2023-08-11
-1giq,2003-01-14,2001-03-12
-3git,2009-10-06,2009-03-06
-5giq,2017-06-28,2016-06-24
-1gii,2002-02-06,2001-02-06
-3gie,2009-09-15,2009-03-05
-6giw,2018-10-17,2018-05-15
-4gij,2012-10-31,2012-08-08
-7giw,2023-11-08,2023-08-11
-5gi8,2017-07-05,2016-06-22
-1gij,2002-02-06,2001-02-06
-7giz,2023-11-08,2023-08-11
-1gic,1997-08-20,1996-08-08
-3giu,2009-03-17,2009-03-06
-4gi8,2013-02-13,2012-08-08
-8gi8,2023-07-26,2023-03-13
-1gih,2002-02-06,2001-02-06
-1gir,2003-01-14,2001-03-12
-6giv,2019-05-15,2018-05-15
-6gii,2018-05-30,2018-05-11
-7gif,2023-11-08,2023-08-11
-1gil,1995-02-14,1995-01-02
-6git,2019-11-27,2018-05-15
-8gi3,2024-03-20,2023-03-13
-3gi1,2009-08-04,2009-03-04
-2gin,2006-11-21,2006-03-29
-8gis,2024-04-17,2023-03-14
-4gih,2013-06-19,2012-08-08
-1gi6,2002-01-22,2001-01-22
-6gi6,2018-05-23,2018-05-10
-6gid,2018-06-27,2018-05-10
-8git,2024-04-17,2023-03-14
-3gi2,2009-09-29,2009-03-05
-8gi9,2023-07-26,2023-03-13
-3gi0,2011-08-10,2009-03-04
-6gia,2019-03-20,2018-05-10
-3gil,2009-05-19,2009-03-05
-2giu,2006-10-10,2006-03-29
-5gii,2017-07-05,2016-06-23
-4gi4,2013-09-04,2012-08-08
-4giy,2013-09-04,2012-08-09
-1giw,1998-12-09,1998-06-17
-4gie,2012-08-15,2012-08-08
-1gi0,2002-01-22,2001-01-22
-6gi5,2018-06-20,2018-05-09
-8gi6,2024-03-20,2023-03-13
-3gim,2009-05-19,2009-03-05
-4gi5,2012-08-22,2012-08-08
-7gi5,2023-11-08,2023-08-11
-7gip,2023-11-08,2023-08-11
-5giv,2017-07-12,2016-06-25
-1gi2,2002-01-22,2001-01-22
-1gi5,2002-01-22,2001-01-22
-2gix,2006-07-25,2006-03-29
-4giq,2012-10-24,2012-08-08
-6gi2,2018-06-20,2018-05-09
-4gia,2013-02-13,2012-08-08
-6gip,2018-05-23,2018-05-14
-6gi1,2018-06-20,2018-05-09
-6giz,2019-11-27,2018-05-15
-4gi9,2013-02-13,2012-08-08
-7gi3,2023-11-08,2023-08-11
-2git,2006-10-03,2006-03-29
-3giz,2009-05-26,2009-03-07
-6gi9,2019-03-20,2018-05-10
-8gil,2024-03-20,2023-03-14
-5gip,2016-09-14,2016-06-24
-4gid,2012-10-10,2012-08-08
-6gi8,2019-03-20,2018-05-10
-5gi5,2017-07-05,2016-06-22
-3gi5,2010-03-09,2009-03-05
-7gim,2023-11-08,2023-08-11
-7gib,2023-11-08,2023-08-11
-3gi4,2010-03-09,2009-03-05
-4gib,2012-08-22,2012-08-08
-5gig,2017-07-05,2016-06-23
-5gi7,2017-07-05,2016-06-22
-5giu,2017-06-28,2016-06-25
-4gi6,2013-02-13,2012-08-08
-7gi2,2023-11-08,2023-08-11
-8gih,2023-04-12,2023-03-14
-7giy,2023-11-08,2023-08-11
-5gi6,2017-07-05,2016-06-22
-5gih,2017-07-05,2016-06-23
-3gid,2009-03-17,2009-03-05
-4giu,2013-08-14,2012-08-09
-2gil,2006-06-27,2006-03-29
-8giz,2024-03-27,2023-03-14
-6gix,2018-10-17,2018-05-15
-3gii,2009-05-19,2009-03-05
-7gil,2023-11-08,2023-08-11
-4gir,2012-08-29,2012-08-08
-6gio,2019-03-27,2018-05-14
-7gi0,2023-11-08,2023-08-11
-1gis,2003-06-03,2001-03-15
-7gi4,2023-11-08,2023-08-11
-1gi4,2002-01-22,2001-01-22
-3giq,2009-09-01,2009-03-05
-8gim,2024-05-22,2023-03-14
-8gir,2024-04-17,2023-03-14
-1gi3,2002-01-22,2001-01-22
-6gih,2018-05-23,2018-05-11
-5gix,2017-07-19,2016-06-25
-4gip,2012-09-19,2012-08-08
-7gig,2023-11-08,2023-08-11
-8gic,2023-12-06,2023-03-14
-8giv,2023-11-15,2023-03-14
-4gis,2012-08-29,2012-08-08
-4gil,2012-10-31,2012-08-08
-5gij,2016-08-24,2016-06-23
-3gir,2009-03-17,2009-03-06
-3gi6,2010-03-09,2009-03-05
-6giu,2018-10-17,2018-05-15
-5git,2017-06-28,2016-06-25
-7gij,2023-11-08,2023-08-11
-3gix,2010-03-16,2009-03-06
-7gi7,2023-11-08,2023-08-11
-3gic,2009-06-02,2009-03-05
-8gin,2024-05-22,2023-03-14
-7gix,2023-11-08,2023-08-11
-8giy,2024-03-27,2023-03-14
-3gip,2009-09-01,2009-03-05
-7gia,2023-11-08,2023-08-11
-3gib,2009-11-17,2009-03-05
-3gin,2009-04-21,2009-03-05
-2gih,2006-07-18,2006-03-28
-8gi5,2023-06-14,2023-03-13
-3gi3,2009-10-20,2009-03-05
-7gi1,2023-11-08,2023-08-11
-1gi8,2002-01-22,2001-01-22
-7gis,2023-11-08,2023-08-11
-2gir,2007-04-03,2006-03-29
-5gif,2017-07-05,2016-06-23
-7git,2023-11-08,2023-08-11
-1gi9,2002-01-22,2001-01-22
-5gic,2016-12-07,2016-06-23
-7gik,2023-11-08,2023-08-11
-5gib,2016-08-10,2016-06-22
-3gij,2009-05-19,2009-03-05
-1gim,1996-12-23,1996-06-15
-5gid,2016-12-07,2016-06-23
-2gig,2006-07-18,2006-03-28
-4giz,2013-01-23,2012-08-09
-6gic,2018-09-12,2018-05-10
-4gik,2012-10-31,2012-08-08
-3gis,2009-08-18,2009-03-06
-7gi6,2023-11-08,2023-08-11
-8gio,2024-04-17,2023-03-14
-3gif,2009-09-15,2009-03-05
-4gii,2013-05-29,2012-08-08
-3giy,2009-12-22,2009-03-06
-7gid,2023-11-08,2023-08-11
-2giw,1998-12-09,1998-06-25
-6gib,2018-09-12,2018-05-10
-7gie,2023-11-08,2023-08-11
-2giq,2007-04-03,2006-03-29
-7gi8,2023-11-08,2023-08-11
-2gie,2006-07-18,2006-03-28
-4gim,2012-10-31,2012-08-08
-7giv,2023-11-08,2023-08-11
-1git,1997-02-12,1996-10-16
-7gii,2023-11-08,2023-08-11
-8gia,2023-05-17,2023-03-13
-7gio,2023-11-08,2023-08-11
-6giq,2019-01-02,2018-05-15
-7gi9,2023-11-08,2023-08-11
-1gi7,2002-01-22,2001-01-22
-6gi7,2019-03-20,2018-05-10
-5gim,2017-05-03,2016-06-24
-8gip,2024-05-22,2023-03-14
-5gio,2016-09-14,2016-06-24
-1gia,1994-09-30,1994-07-20
-1giu,2003-06-03,2001-03-15
-7gir,2023-11-08,2023-08-11
-5gie,2016-12-07,2016-06-23
-6gin,2018-05-23,2018-05-14
-5gi9,2017-07-05,2016-06-22
-2giv,2006-04-11,2006-03-29
-3gig,2009-09-15,2009-03-05
-2gi0,2006-07-04,2006-03-28
-4gin,2013-02-13,2012-08-08
-2gim,2006-04-11,2006-03-29
-7giu,2023-11-08,2023-08-11
-7gin,2023-11-08,2023-08-11
-4giv,2012-09-05,2012-08-09
-7giq,2023-11-08,2023-08-11
-4gi2,2013-08-14,2012-08-08
-5tdr,2016-11-02,2016-09-19
-6td7,2020-02-26,2019-11-08
-3tdb,2012-06-27,2011-08-10
-5td4,2016-11-02,2016-09-16
-3tdq,2011-08-31,2011-08-11
-7tdj,2022-03-09,2021-12-31
-6tdw,2019-11-27,2019-11-10
-8td1,2024-03-06,2023-07-02
-3tdf,2011-08-31,2011-08-11
-6tda,2020-03-18,2019-11-08
-5td3,2016-11-02,2016-09-16
-3td3,2011-10-26,2011-08-10
-1tdj,1998-10-14,1998-03-27
-2tdd,1993-07-15,1993-04-05
-3tda,2012-08-15,2011-08-10
-5td5,2016-12-28,2016-09-16
-6tdh,2020-04-29,2019-11-08
-7td8,2022-08-17,2021-12-30
-5tdw,2016-10-19,2016-09-19
-5tdf,2017-08-09,2016-09-19
-7td3,2022-02-09,2021-12-30
-7tdl,2022-06-01,2022-01-01
-5tdd,2017-03-22,2016-09-19
-5tdu,2017-03-22,2016-09-19
-3tdk,2011-10-26,2011-08-11
-1tdu,1998-07-01,1997-06-25
-7tdk,2022-03-09,2021-12-31
-1tdi,2005-01-18,2004-05-22
-5tdt,2017-03-22,2016-09-19
-6tde,2020-09-02,2019-11-08
-6tdf,2020-04-29,2019-11-08
-6td1,2020-01-22,2019-11-07
-6td8,2020-11-18,2019-11-08
-5tdh,2016-11-09,2016-09-19
-1tdb,1993-07-15,1993-02-15
-1tdk,2004-06-22,2004-05-22
-3tdw,2012-03-07,2011-08-11
-5td2,2017-01-25,2016-09-16
-6tdv,2019-11-27,2019-11-10
-7tdo,2022-04-06,2022-01-02
-1tdv,2004-06-08,2004-05-24
-5tdg,2017-08-16,2016-09-19
-6tdo,2020-03-25,2019-11-09
-3tdh,2011-11-09,2011-08-11
-7tdv,2022-06-29,2022-01-03
-5tda,2017-03-22,2016-09-19
-1tdq,2004-08-31,2004-05-24
-6tdb,2020-11-18,2019-11-08
-2tdt,1998-10-14,1998-05-05
-8tdu,2023-09-06,2023-07-05
-5tdc,2017-03-22,2016-09-19
-2tdm,1997-08-20,1997-03-28
-3tdz,2011-10-12,2011-08-11
-6tdp,2020-03-25,2019-11-10
-3tdd,2011-10-12,2011-08-10
-6tdz,2019-11-27,2019-11-10
-6tdc,2020-11-18,2019-11-08
-8tdv,2023-12-20,2023-07-05
-3tdt,1998-10-14,1998-05-06
-5td9,2017-09-27,2016-09-19
-2tdx,1998-10-14,1998-06-22
-3tdj,2011-09-21,2011-08-11
-5tdz,2017-08-09,2016-09-20
-7td4,2022-02-09,2021-12-30
-7tds,2022-07-27,2022-01-03
-5tde,2017-08-09,2016-09-19
-6td5,2020-08-26,2019-11-07
-6tdg,2020-04-29,2019-11-08
-8tdr,2024-03-13,2023-07-04
-8td0,2024-03-06,2023-07-02
-6tdy,2019-11-27,2019-11-10
-3tdc,2011-10-12,2011-08-10
-6tdq,2020-03-25,2019-11-10
-7td9,2022-08-17,2021-12-30
-5tds,2017-03-22,2016-09-19
-8tdw,2023-11-22,2023-07-05
-5tdv,2017-03-22,2016-09-19
-3tdv,2012-03-07,2011-08-11
-3tde,2011-08-17,2011-08-10
-6td2,2020-10-14,2019-11-07
-1td2,2004-07-13,2004-05-21
-7td5,2022-11-16,2021-12-30
-6tdt,2020-05-13,2019-11-10
-5td8,2016-11-16,2016-09-17
-5tdl,2017-08-16,2016-09-19
-8tdp,2023-11-22,2023-07-04
-6td0,2020-01-22,2019-11-07
-7tdu,2022-03-02,2022-01-03
-6tdu,2019-11-27,2019-11-10
-5tdi,2017-01-25,2016-09-19
-8tdq,2023-11-22,2023-07-04
-6td3,2020-06-17,2019-11-07
-7tdp,2022-06-29,2022-01-02
-1tdf,1994-11-30,1994-01-14
-1tdn,2004-06-22,2004-05-23
-7tdi,2022-03-09,2021-12-31
-3td5,2011-10-26,2011-08-10
-5tdm,2017-08-09,2016-09-19
-1tdc,1993-07-15,1993-02-15
-6td6,2020-06-03,2019-11-07
-1tdw,2004-11-30,2004-05-24
-1tdz,2004-09-07,2004-05-24
-1tdr,1995-07-10,1995-04-13
-3tdp,2012-03-07,2011-08-11
-1tdo,2004-06-22,2004-05-23
-1tdg,2004-11-23,2004-05-21
-3td7,2012-09-05,2011-08-10
-6tdr,2020-03-25,2019-11-10
-3td9,2011-09-07,2011-08-10
-3td8,2012-04-11,2011-08-10
-7tdg,2022-03-09,2021-12-31
-6tds,2020-03-25,2019-11-10
-5td7,2017-05-24,2016-09-17
-1tde,1994-11-30,1994-01-14
-7tdh,2022-03-09,2021-12-31
-1td7,2004-06-08,2004-05-21
-1tdl,2004-11-23,2004-05-23
-3td4,2011-10-26,2011-08-10
-5tdb,2017-03-22,2016-09-19
-3tdl,2012-06-27,2011-08-11
-1iq5,2001-09-26,2001-06-14
-1iqm,2003-09-23,2001-07-23
-3iqh,2009-11-17,2009-08-20
-6iqw,2019-01-16,2018-11-09
-5iqa,2016-05-25,2016-03-10
-4iqu,2013-09-04,2013-01-13
-4iqg,2013-01-30,2013-01-11
-3iqb,2010-01-19,2009-08-19
-6iqm,2018-11-21,2018-11-08
-2iqf,2007-08-28,2006-10-13
-3iqo,2010-02-02,2009-08-20
-5iqs,2016-06-29,2016-03-11
-1iqu,2002-05-08,2001-08-03
-5iqx,2016-04-20,2016-03-11
-1iq8,2002-05-22,2001-07-09
-5iqn,2016-07-06,2016-03-11
-2iqd,2006-11-28,2006-10-13
-3iqu,2010-09-01,2009-08-21
-8iq9,2024-02-21,2023-03-16
-6iqc,2019-02-20,2018-11-06
-5iqm,2016-07-06,2016-03-11
-2iq7,2007-10-23,2006-10-13
-4iqk,2013-05-15,2013-01-11
-2iqq,2006-11-14,2006-10-14
-1iqq,2001-11-07,2001-07-25
-4iq9,2013-05-01,2013-01-11
-1iqy,2003-02-04,2001-08-28
-1iqk,2003-09-23,2001-07-23
-1iqb,2001-11-07,2001-07-15
-2iqg,2007-02-27,2006-10-13
-1iq7,2001-11-28,2001-07-06
-1iqh,2003-09-23,2001-07-23
-4iqy,2013-03-06,2013-01-14
-1iqi,2003-09-23,2001-07-23
-5iqu,2016-06-29,2016-03-11
-3iq5,2010-06-16,2009-08-19
-3iqt,2009-09-22,2009-08-20
-8iqu,2023-04-26,2023-03-17
-3iqi,2009-11-17,2009-08-20
-3iqq,2010-02-02,2009-08-20
-5iqg,2016-05-25,2016-03-10
-4iqj,2013-03-13,2013-01-11
-6iq1,2019-01-30,2018-11-05
-8iqn,2024-03-27,2023-03-17
-3iqs,2009-11-10,2009-08-20
-5iql,2016-07-20,2016-03-11
-6iqx,2018-11-21,2018-11-09
-5iq6,2016-10-05,2016-03-10
-6iqy,2018-11-21,2018-11-09
-5iqc,2016-05-25,2016-03-10
-3iqa,2010-04-14,2009-08-19
-5iqe,2016-05-25,2016-03-10
-8iq1,2023-09-06,2023-03-15
-5iqo,2016-07-06,2016-03-11
-3iq6,2010-06-16,2009-08-19
-3iq7,2009-09-08,2009-08-19
-3iqj,2010-09-01,2009-08-20
-5iqt,2016-06-29,2016-03-11
-2iq1,2006-11-07,2006-10-12
-1iqx,2003-02-04,2001-08-27
-2iqj,2006-10-24,2006-10-13
-3iq0,2009-09-08,2009-08-18
-8iq8,2023-11-22,2023-03-16
-6iqn,2020-01-22,2018-11-08
-8iqd,2023-07-26,2023-03-16
-3iqz,2009-10-06,2009-08-21
-6iqd,2019-06-05,2018-11-07
-4iq6,2013-04-24,2013-01-10
-6iq5,2019-01-30,2018-11-06
-2iq0,2006-11-28,2006-10-12
-4iqr,2013-03-20,2013-01-13
-5iq4,2017-01-18,2016-03-10
-5iqd,2016-05-25,2016-03-10
-1iqc,2002-01-23,2001-07-20
-4iq0,2013-01-23,2013-01-10
-5iqj,2016-03-23,2016-03-10
-1iql,2003-09-23,2001-07-23
-4iqv,2013-09-04,2013-01-13
-8iq6,2024-01-31,2023-03-15
-1iqj,2003-09-23,2001-07-23
-3iqv,2010-09-01,2009-08-21
-5iqh,2016-05-25,2016-03-10
-6iql,2019-12-04,2018-11-08
-2iq6,2007-08-28,2006-10-13
-4iqd,2013-01-23,2013-01-11
-6iqz,2018-11-21,2018-11-09
-1iqr,2001-11-28,2001-07-27
-4iqw,2013-09-04,2013-01-13
-1iq1,2001-11-14,2001-05-28
-1iq3,2001-06-27,2001-06-06
-3iqe,2009-10-06,2009-08-20
-6iqq,2019-07-24,2018-11-08
-8iqc,2023-07-26,2023-03-16
-5iqr,2016-05-04,2016-03-11
-2iqc,2006-11-07,2006-10-13
-5iq1,2017-01-18,2016-03-10
-4iqi,2013-01-23,2013-01-11
-4iqt,2013-09-04,2013-01-13
-8iqt,2024-03-27,2023-03-17
-1iqg,2003-09-23,2001-07-23
-4iq7,2013-05-01,2013-01-11
-5iqb,2016-05-25,2016-03-10
-5iqk,2016-03-23,2016-03-10
-5iqi,2016-05-25,2016-03-10
-8iqi,2023-07-26,2023-03-16
-3iqd,2010-08-25,2009-08-20
-8iq4,2024-01-31,2023-03-15
-2iqx,2007-09-25,2006-10-14
-3iqx,2009-12-15,2009-08-21
-1iqn,2003-09-23,2001-07-23
-2iqy,2007-09-25,2006-10-14
-1iqe,2003-09-23,2001-07-23
-3iqf,2009-10-06,2009-08-20
-5iqv,2016-06-29,2016-03-11
-6iq6,2019-08-28,2018-11-06
-8iq0,2023-09-06,2023-03-15
-3iqw,2009-12-15,2009-08-21
-3iqg,2009-11-17,2009-08-20
-5iqw,2016-04-20,2016-03-11
-1iqp,2001-09-19,2001-07-24
-4iqz,2013-02-13,2013-01-14
-6iqg,2019-02-13,2018-11-08
-6iqj,2019-11-06,2018-11-08
-5iqf,2016-05-25,2016-03-10
-8iqa,2024-03-20,2023-03-16
-6iqv,2018-11-21,2018-11-09
-4iqx,2013-02-06,2013-01-14
-5iqz,2016-07-27,2016-03-11
-1iqf,2003-09-23,2001-07-23
-4iql,2014-01-29,2013-01-11
-5jmz,2017-05-03,2016-04-29
-8jmk,2024-05-29,2023-06-05
-6jmb,2020-03-11,2019-03-07
-7jmr,2021-02-17,2020-08-02
-4jmw,2013-05-01,2013-03-14
-7jmo,2020-08-26,2020-08-02
-2jmj,2007-07-03,2006-11-15
-5jms,2016-05-18,2016-04-29
-6jmv,2019-07-24,2019-03-13
-6jmd,2020-03-18,2019-03-08
-5jmy,2016-06-15,2016-04-29
-1jmj,2002-08-30,2001-07-18
-5jmg,2016-07-27,2016-04-29
-4jmy,2013-10-30,2013-03-14
-5jmd,2016-05-25,2016-04-28
-7jm5,2022-02-02,2020-07-31
-7jmg,2020-08-12,2020-07-31
-6jmh,2020-03-18,2019-03-10
-7jm7,2020-09-02,2020-07-31
-7jmk,2021-03-10,2020-08-01
-7jmh,2020-08-12,2020-07-31
-1jmh,1998-01-28,1997-09-13
-5jmf,2016-05-25,2016-04-28
-6jm9,2019-05-15,2019-03-07
-7jmq,2021-08-04,2020-08-02
-1jme,2001-11-23,2001-07-18
-4jmg,2014-04-23,2013-03-14
-6jmz,2020-01-15,2019-03-13
-4jmz,2013-05-01,2013-03-14
-5jm8,2016-06-15,2016-04-28
-5jm1,2016-12-14,2016-04-28
-6jmt,2020-05-20,2019-03-13
-6jmx,2020-01-15,2019-03-13
-5jmp,2016-08-24,2016-04-29
-4jm5,2013-05-01,2013-03-13
-8jmo,2023-11-29,2023-06-05
-8jmh,2024-02-07,2023-06-04
-8jm5,2024-06-05,2023-06-04
-7jme,2020-09-02,2020-07-31
-5jmo,2016-12-07,2016-04-29
-2jmd,2007-04-10,2006-11-02
-2jma,2007-04-24,2006-10-25
-6jm5,2019-10-16,2019-03-07
-4jm6,2013-05-01,2013-03-13
-1jmz,2002-01-16,2001-07-20
-4jmb,2013-05-01,2013-03-13
-4jmu,2013-10-30,2013-03-14
-8jmp,2023-11-29,2023-06-05
-4jmh,2014-04-23,2013-03-14
-7jmm,2020-08-26,2020-08-02
-4jme,2013-07-03,2013-03-13
-7jmt,2021-02-17,2020-08-02
-6jmq,2019-06-19,2019-03-13
-5jmu,2016-06-29,2016-04-29
-5jmn,2016-12-21,2016-04-29
-7jmv,2021-02-17,2020-08-03
-6jme,2020-03-18,2019-03-08
-1jml,2001-10-10,2001-07-19
-8jm6,2024-06-05,2023-06-04
-5jmq,2017-05-10,2016-04-29
-5jm6,2016-06-15,2016-04-28
-4jm9,2013-05-01,2013-03-13
-7jmw,2020-10-14,2020-08-03
-4jml,2013-07-17,2013-03-14
-2jm3,2007-02-06,2006-09-21
-1jmu,2002-02-06,2001-07-20
-1jms,2002-01-23,2001-07-19
-7jmj,2020-08-12,2020-07-31
-8jm4,2024-06-05,2023-06-04
-8jmz,2024-03-27,2023-06-05
-4jmt,2013-05-01,2013-03-14
-1jmm,2002-07-17,2001-07-19
-1jmb,2002-01-16,2001-07-18
-1jmg,1998-01-28,1997-09-13
-1jmx,2002-01-16,2001-07-20
-8jml,2024-05-29,2023-06-05
-5jml,2016-07-27,2016-04-29
-6jmr,2019-06-19,2019-03-13
-8jmi,2024-02-07,2023-06-04
-6jm8,2020-03-11,2019-03-07
-4jmx,2013-10-23,2013-03-14
-4jmo,2013-10-23,2013-03-14
-2jmi,2007-07-03,2006-11-15
-1jmo,2002-08-30,2001-07-19
-4jm2,2013-05-29,2013-03-13
-7jmf,2020-08-12,2020-07-31
-1jmf,1998-01-28,1997-09-13
-7jmp,2020-08-26,2020-08-02
-8jmj,2024-05-29,2023-06-05
-1jm1,2002-07-17,2001-07-17
-5jmx,2017-05-24,2016-04-29
-6jmw,2020-03-18,2019-03-13
-4jm8,2013-05-01,2013-03-13
-7jmi,2020-08-12,2020-07-31
-8jm8,2024-06-05,2023-06-04
-5jmv,2016-07-06,2016-04-29
-6jmy,2020-01-15,2019-03-13
-4jmd,2013-07-03,2013-03-13
-1jm0,2002-01-16,2001-07-17
-4jms,2013-05-01,2013-03-14
-7jm6,2020-09-02,2020-07-31
-4jmc,2013-07-03,2013-03-13
-7jms,2020-10-21,2020-08-02
-5jma,2017-05-03,2016-04-28
-1jmc,1997-10-16,1996-11-11
-6jma,2019-05-15,2019-03-07
-4jm0,2014-02-26,2013-03-13
-1jma,2001-09-26,2001-07-17
-8jma,2024-02-07,2023-06-04
-7jm1,2020-09-16,2020-07-30
-4jmv,2013-05-01,2013-03-14
-8jmr,2023-12-20,2023-06-05
-8jmn,2023-08-30,2023-06-05
-2jm4,2006-12-12,2006-10-09
-1jmi,1998-01-28,1997-09-13
-5jmw,2016-08-24,2016-04-29
-8jmx,2023-10-18,2023-06-05
-6jmn,2020-05-06,2019-03-12
-5jmm,2017-05-10,2016-04-29
-7jm2,2020-09-16,2020-07-30
-1jm6,2001-10-24,2001-07-17
-1jm7,2001-10-03,2001-07-17
-2jm1,2007-06-26,2006-09-13
-2jmo,2007-02-27,2006-11-24
-6jmf,2019-06-12,2019-03-08
-4jma,2013-05-01,2013-03-13
-6jmg,2020-03-11,2019-03-09
-5jm4,2017-05-10,2016-04-28
-8jm7,2024-06-05,2023-06-04
-5luk,2017-07-12,2016-09-09
-6lum,2020-05-27,2020-01-29
-6lur,2020-04-29,2020-01-30
-7lu9,2021-03-24,2021-02-21
-3luo,2010-03-31,2010-02-18
-5lu1,2017-02-01,2016-09-07
-7lu5,2021-11-24,2021-02-20
-1lul,1998-12-30,1998-06-30
-6luf,2020-03-18,2020-01-27
-6luy,2020-08-19,2020-02-02
-5lu7,2017-12-06,2016-09-08
-7lub,2022-02-23,2021-02-21
-3lu1,2010-07-21,2010-02-16
-4lug,2014-07-30,2013-07-25
-1lu0,2002-08-28,2002-05-21
-7lu1,2022-08-17,2021-02-20
-7lu4,2021-08-04,2021-02-20
-4lue,2014-02-12,2013-07-25
-5lua,2017-03-29,2016-09-08
-2luy,2013-05-08,2012-06-22
-3lu2,2010-03-09,2010-02-16
-7lux,2021-03-17,2021-02-23
-6lu4,2020-03-25,2020-01-25
-3lu6,2010-10-27,2010-02-17
-1luv,2002-06-19,2002-05-23
-7luj,2022-01-05,2021-02-22
-1luc,1996-12-07,1996-05-10
-4lut,2014-06-04,2013-07-25
-5lun,2017-04-19,2016-09-09
-7lul,2021-07-28,2021-02-22
-4lup,2014-02-19,2013-07-25
-5luc,2017-09-20,2016-09-08
-4luf,2014-09-17,2013-07-25
-7luh,2022-01-05,2021-02-22
-6lud,2020-10-07,2020-01-27
-2lu5,2012-06-27,2012-06-08
-5luz,2017-12-06,2016-09-12
-1lu2,1998-12-09,1998-07-30
-6lue,2020-06-10,2020-01-27
-5luh,2018-01-17,2016-09-08
-4luw,2013-10-23,2013-07-25
-4luk,2014-07-30,2013-07-25
-3luu,2010-03-09,2010-02-18
-5lu6,2017-12-06,2016-09-08
-1lue,2003-11-04,2002-05-22
-3lum,2010-03-02,2010-02-18
-3luy,2010-03-09,2010-02-18
-6luw,2020-08-19,2020-02-02
-3luj,2010-05-26,2010-02-17
-5lu8,2017-03-29,2016-09-08
-1lug,2003-09-09,2002-05-22
-4luv,2013-12-11,2013-07-25
-7lu7,2022-08-24,2021-02-21
-3lu7,2010-10-27,2010-02-17
-7lui,2021-12-29,2021-02-22
-7luz,2021-03-17,2021-02-23
-3lu9,2010-03-16,2010-02-17
-4lul,2014-07-30,2013-07-25
-2lul,2012-08-15,2012-06-15
-3lug,2010-05-26,2010-02-17
-6lup,2021-04-28,2020-01-30
-4luj,2013-08-07,2013-07-25
-5lu4,2017-05-24,2016-09-08
-7lun,2021-04-21,2021-02-22
-7lu3,2022-08-17,2021-02-20
-6lu3,2020-03-25,2020-01-25
-6lu6,2021-04-28,2020-01-26
-7lup,2021-03-03,2021-02-22
-5lui,2017-07-12,2016-09-08
-7luu,2021-07-28,2021-02-23
-6lu8,2020-08-26,2020-01-26
-5lup,2017-03-01,2016-09-09
-6luz,2020-08-19,2020-02-02
-3lud,2010-05-26,2010-02-17
-5lul,2017-07-12,2016-09-09
-5lu3,2017-02-15,2016-09-07
-6lu5,2021-04-28,2020-01-25
-5lur,2017-09-20,2016-09-09
-7lus,2021-09-15,2021-02-23
-3lu8,2010-10-27,2010-02-17
-3lut,2010-06-23,2010-02-18
-5lu9,2017-03-29,2016-09-08
-6lug,2020-06-17,2020-01-28
-5luf,2016-11-30,2016-09-08
-3luz,2010-03-02,2010-02-18
-2lux,2013-06-26,2012-06-22
-5lud,2017-04-05,2016-09-08
-6lu7,2020-02-05,2020-01-26
-6lu1,2021-03-17,2020-01-24
-3lus,2010-04-21,2010-02-18
-7luf,2021-04-07,2021-02-22
-4luh,2014-09-17,2013-07-25
-5lub,2017-03-29,2016-09-08
-5lum,2017-02-01,2016-09-09
-4lu3,2014-01-01,2013-07-24
-7lu0,2022-08-17,2021-02-20
-4lux,2013-10-23,2013-07-25
-5lug,2017-09-20,2016-09-08
-1luq,2003-09-09,2002-05-23
-7lu2,2022-08-17,2021-02-20
-6lub,2020-10-07,2020-01-27
-4luq,2013-09-18,2013-07-25
-4luc,2013-11-27,2013-07-25
-4luu,2013-12-18,2013-07-25
-3luf,2010-03-02,2010-02-17
-5luu,2016-10-12,2016-09-11
-2lua,2012-10-17,2012-06-09
-5lu5,2017-12-06,2016-09-08
-7luk,2021-05-12,2021-02-22
-4luz,2013-12-11,2013-07-25
-7lu6,2021-11-24,2021-02-21
-3lun,2010-03-02,2010-02-18
-4lum,2014-07-30,2013-07-25
-4luo,2013-12-11,2013-07-25
-3lub,2010-03-09,2010-02-17
-6lux,2020-08-19,2020-02-02
-1luw,2002-06-19,2002-05-23
-7lua,2021-03-17,2021-02-21
-1lua,2002-09-11,2002-05-22
-3lu0,2010-09-29,2010-02-16
-5lu2,2017-02-01,2016-09-07
-4lud,2014-02-12,2013-07-25
-6luh,2020-09-02,2020-01-28
-1lud,2002-12-18,2002-05-22
-1lu1,1998-12-09,1998-07-24
-7lut,2022-03-02,2021-02-23
-6luq,2020-03-04,2020-01-30
-3luh,2010-05-26,2010-02-17
-6zf5,2021-04-14,2020-06-16
-2zfs,2009-01-13,2008-01-10
-5zf4,2018-09-26,2018-03-02
-7zft,2022-11-23,2022-04-01
-4zfu,2016-03-23,2015-04-21
-3zf0,2013-01-30,2012-12-10
-2zfe,2008-11-11,2007-12-31
-3zf8,2013-09-25,2012-12-10
-2zft,2009-01-13,2008-01-11
-6zf1,2021-04-14,2020-06-16
-2zf0,2008-11-04,2007-12-18
-4zfl,2015-07-01,2015-04-21
-2zfq,2009-01-13,2008-01-10
-5zf9,2018-09-26,2018-03-02
-5zf3,2019-03-06,2018-03-02
-1zfn,2005-06-14,2005-04-20
-4zfw,2016-03-23,2015-04-21
-3zf2,2013-01-30,2012-12-10
-4zfb,2016-07-13,2015-04-21
-4zfx,2015-08-05,2015-04-22
-2zfj,2008-09-23,2008-01-08
-3zff,2013-03-27,2012-12-11
-6zf7,2021-04-14,2020-06-16
-2zf4,2008-01-01,2007-12-20
-4zfn,2015-04-29,2015-04-21
-2zfo,2008-04-22,2008-01-08
-4zfz,2016-01-13,2015-04-22
-1zfs,2006-04-11,2005-04-20
-4zfg,2015-07-01,2015-04-21
-3zf5,2013-01-30,2012-12-10
-6zfh,2021-06-30,2020-06-17
-2zfl,2008-09-23,2008-01-08
-2zfi,2008-09-23,2008-01-07
-2zff,2008-12-16,2008-01-04
-3zfc,2013-03-20,2012-12-11
-4zfq,2015-09-02,2015-04-21
-4zfh,2016-04-20,2015-04-21
-3zf3,2013-01-30,2012-12-10
-6zfo,2020-07-08,2020-06-17
-1zfq,2006-05-23,2005-04-20
-6zf6,2021-04-14,2020-06-16
-7zfn,2022-11-23,2022-04-01
-6zfx,2020-11-18,2020-06-18
-6zfb,2020-10-14,2020-06-17
-6zfk,2021-01-13,2020-06-17
-5zft,2019-03-20,2018-03-07
-1zfk,2006-05-23,2005-04-20
-6zff,2020-07-08,2020-06-17
-3zf6,2013-01-30,2012-12-10
-7zfb,2022-06-01,2022-04-01
-3zfk,2013-12-18,2012-12-11
-6zft,2021-06-30,2020-06-17
-1zfd,1996-10-14,1996-04-04
-7zfv,2022-11-23,2022-04-01
-7zfo,2022-11-23,2022-04-01
-3zf1,2013-01-30,2012-12-10
-7zfz,2022-11-23,2022-04-01
-7zf2,2023-02-08,2022-03-31
-3zfj,2013-11-20,2012-12-11
-6zfe,2021-01-13,2020-06-17
-6zfg,2021-02-17,2020-06-17
-4zfp,2015-06-24,2015-04-21
-7zfg,2022-11-23,2022-04-01
-6zfz,2021-10-06,2020-06-18
-6zfm,2020-12-02,2020-06-17
-1zfj,2000-03-29,1999-03-29
-5zf8,2018-09-26,2018-03-02
-6zfs,2021-06-30,2020-06-17
-4zf8,2016-07-13,2015-04-21
-4zfi,2016-10-19,2015-04-21
-7zf9,2022-06-01,2022-04-01
-6zfj,2021-01-13,2020-06-17
-3zfr,2013-05-15,2012-12-12
-5zfr,2018-09-19,2018-03-06
-2zfu,2008-12-02,2008-01-14
-4zft,2015-10-14,2015-04-21
-3zfe,2013-03-27,2012-12-11
-3zfd,2013-03-20,2012-12-11
-7zf6,2022-06-01,2022-04-01
-7zfs,2022-11-23,2022-04-01
-5zf7,2018-09-26,2018-03-02
-4zfm,2016-06-29,2015-04-21
-5zfb,2018-09-26,2018-03-02
-3zf4,2013-01-30,2012-12-10
-6zf4,2021-04-14,2020-06-16
-1zfo,1996-11-08,1996-05-06
-6zf9,2020-07-29,2020-06-16
-5zfx,2018-10-24,2018-03-07
-2zfk,2008-09-23,2008-01-08
-4zfy,2016-03-23,2015-04-22
-6zfu,2021-06-30,2020-06-17
-6zf2,2021-04-14,2020-06-16
-2zfa,2008-04-22,2007-12-26
-5zfa,2018-09-26,2018-03-02
-5zfs,2018-10-24,2018-03-07
-2zfx,2009-01-20,2008-01-15
-7zf7,2022-06-01,2022-04-01
-7zfy,2022-11-23,2022-04-01
-4zfc,2015-11-25,2015-04-21
-4zfo,2015-05-20,2015-04-21
-7zfr,2023-04-12,2022-04-01
-2zfz,2008-02-12,2008-01-16
-6zf8,2021-04-14,2020-06-16
-5zf0,2018-04-11,2018-03-01
-6zf3,2021-04-14,2020-06-16
-2zfd,2008-02-19,2007-12-29
-4zfv,2015-09-16,2015-04-21
-2zfp,2008-12-16,2008-01-08
-4zfa,2016-07-13,2015-04-21
-1zfp,1999-03-30,1998-03-26
-7zfx,2022-11-23,2022-04-01
-7zfc,2022-06-01,2022-04-01
-4zfk,2015-07-01,2015-04-21
-4zfr,2015-10-14,2015-04-21
-3zfg,2013-03-27,2012-12-11
-4zf6,2016-07-13,2015-04-21
-3zfz,2013-10-09,2012-12-13
-2zfm,2008-09-23,2008-01-08
-2zfn,2008-09-23,2008-01-08
-3zfq,2013-05-15,2012-12-12
-5zfj,2018-12-19,2018-03-06
-5zfk,2019-03-06,2018-03-06
-7zfu,2022-11-23,2022-04-01
-6zfv,2021-06-30,2020-06-18
-6zfc,2020-10-28,2020-06-17
-6zf0,2021-04-14,2020-06-16
-5zfi,2018-06-27,2018-03-06
-2zfb,2008-02-26,2007-12-28
-2zfg,2008-07-29,2008-01-04
-2zfr,2009-01-13,2008-01-10
-6zfn,2020-11-18,2020-06-17
-6zfa,2020-11-18,2020-06-16
-7zf0,2022-07-13,2022-03-31
-3qju,2012-01-25,2011-01-30
-6qj7,2020-02-12,2019-01-23
-1qj5,2000-06-22,1999-06-21
-6qjz,2020-08-26,2019-01-28
-6qju,2020-02-12,2019-01-25
-3qjz,2011-03-30,2011-01-31
-4qji,2014-07-02,2014-06-03
-1qja,1999-09-15,1999-06-23
-6qja,2020-02-05,2019-01-23
-2qjy,2007-12-25,2007-07-09
-1qjk,1999-08-31,1999-06-24
-3qjb,2011-02-16,2011-01-28
-5qjf,2018-12-19,2018-10-31
-2qje,2008-06-24,2007-07-07
-2qjj,2007-10-30,2007-07-07
-5qjl,2018-12-19,2018-10-31
-1qjy,1999-07-20,1999-07-06
-1qjj,2000-01-24,1999-06-24
-5qjo,2018-12-19,2018-10-31
-4qj6,2014-10-29,2014-06-03
-4qj7,2014-10-29,2014-06-03
-1qjw,1999-09-18,1999-07-06
-4qjo,2015-04-15,2014-06-04
-5qj6,2018-12-19,2018-10-31
-6qje,2019-02-27,2019-01-24
-5qjh,2018-12-19,2018-10-31
-5qjq,2018-12-19,2018-10-31
-5qj9,2018-12-19,2018-11-12
-6qjv,2020-02-12,2019-01-25
-4qjk,2014-07-16,2014-06-04
-6qj5,2020-02-05,2019-01-22
-5qjz,2018-12-19,2018-10-31
-5qjx,2018-12-19,2018-10-31
-3qjd,2011-02-16,2011-01-28
-5qj7,2018-12-19,2018-10-31
-2qjk,2007-12-25,2007-07-07
-2qjf,2008-11-11,2007-07-07
-1qjb,1999-09-15,1999-06-23
-1qj0,1999-06-22,1999-06-18
-5qjr,2018-12-19,2018-10-31
-1qjc,2001-06-27,1999-06-23
-1qj3,2000-06-22,1999-06-21
-5qjs,2018-12-19,2018-10-31
-4qjw,2015-04-15,2014-06-05
-4qjq,2014-06-18,2014-06-04
-8qjs,2024-01-17,2023-09-13
-3qjn,2011-04-13,2011-01-30
-5qjy,2018-12-19,2018-10-31
-4qjl,2014-07-16,2014-06-04
-2qjt,2008-03-04,2007-07-09
-4qjb,2014-07-02,2014-06-03
-5qjk,2018-12-19,2018-10-31
-5qjg,2018-12-19,2018-10-31
-1qj7,2000-06-22,1999-06-22
-1qjl,1999-08-31,1999-06-24
-4qjx,2015-04-15,2014-06-05
-3qje,2011-02-16,2011-01-28
-4qjg,2014-07-09,2014-06-03
-8qjr,2024-01-17,2023-09-13
-5qjv,2018-12-19,2018-10-31
-5qjt,2018-12-19,2018-10-31
-8qjt,2024-01-17,2023-09-13
-3qji,2011-03-09,2011-01-29
-6qjx,2019-08-21,2019-01-27
-3qjt,2012-01-25,2011-01-30
-1qji,2000-01-21,1999-06-24
-8qj7,2024-02-21,2023-09-12
-1qjq,2000-06-05,1999-06-29
-2qjs,2007-08-21,2007-07-09
-5qj3,2019-02-06,2018-09-26
-1qje,2000-06-29,1999-06-23
-7qjt,2022-12-28,2021-12-17
-5qji,2018-12-19,2018-10-31
-5qj2,2019-02-06,2018-09-26
-2qjr,2008-07-29,2007-07-09
-2qju,2007-08-21,2007-07-09
-1qjf,2000-06-29,1999-06-23
-3qjc,2011-02-16,2011-01-28
-5qjb,2018-12-19,2018-10-31
-4qj0,2015-04-15,2014-06-03
-2qjc,2007-07-24,2007-07-06
-5qju,2018-12-19,2018-10-31
-2qj3,2007-09-04,2007-07-06
-6qjw,2019-08-21,2019-01-27
-1qj6,2000-06-22,1999-06-22
-8qj0,2024-05-29,2023-09-12
-4qje,2014-06-18,2014-06-03
-4qj3,2014-10-22,2014-06-03
-4qjm,2015-04-15,2014-06-04
-2qj7,2008-05-20,2007-07-06
-2qjg,2007-10-30,2007-07-07
-4qjz,2015-06-10,2014-06-05
-1qjs,2000-02-03,1999-07-01
-5qjm,2018-12-19,2018-10-31
-6qj6,2020-01-15,2019-01-23
-3qj5,2011-04-06,2011-01-28
-1qjx,1999-07-20,1999-07-06
-2qjl,2007-07-17,2007-07-07
-3qj7,2011-06-15,2011-01-28
-3qjm,2011-04-13,2011-01-30
-6qjc,2020-02-05,2019-01-24
-7qjk,2022-01-26,2021-12-16
-3qj4,2011-07-13,2011-01-28
-5qje,2018-12-19,2018-10-31
-8qjz,2024-04-17,2023-09-14
-2qj5,2008-05-20,2007-07-06
-4qjp,2015-04-15,2014-06-04
-1qj1,2000-06-22,1999-06-21
-5qj8,2018-12-19,2018-10-31
-7qjl,2022-12-28,2021-12-16
-4qj5,2014-10-22,2014-06-03
-3qjk,2012-04-11,2011-01-29
-5qja,2018-12-19,2018-10-31
-7qju,2022-04-13,2021-12-17
-1qjd,1999-11-21,1999-06-23
-3qj6,2011-02-23,2011-01-28
-2qjm,2007-10-30,2007-07-08
-5qjw,2018-12-19,2018-10-31
-5qj4,2018-12-19,2018-11-12
-5qjc,2018-12-19,2018-10-31
-3qjq,2012-01-25,2011-01-30
-5qjp,2018-12-19,2018-10-31
-5qjn,2018-12-19,2018-11-12
-5qjj,2018-12-19,2018-10-31
-3qjs,2012-01-25,2011-01-30
-7qjj,2022-02-02,2021-12-16
-3qjx,2011-11-16,2011-01-31
-5qj5,2018-12-19,2018-10-31
-5qj0,2018-11-21,2018-08-13
-1qjg,1999-11-16,1999-06-24
-5qj1,2018-11-21,2018-08-13
-7qjg,2022-04-13,2021-12-16
-3qjp,2012-02-08,2011-01-30
-3qj0,2011-04-13,2011-01-28
-2qjv,2007-08-07,2007-07-09
-3qjv,2012-01-25,2011-01-30
-3qjo,2011-05-25,2011-01-30
-5qjd,2018-12-19,2018-10-31
-2qjp,2007-12-25,2007-07-08
-1qjm,1999-08-26,1999-06-27
-3qjg,2011-02-09,2011-01-28
-3qjr,2012-01-25,2011-01-30
-1qju,1999-07-20,1999-07-05
-4qj4,2014-10-22,2014-06-03
-3qj9,2011-04-27,2011-01-28
-2qjo,2008-03-11,2007-07-08
-4qj1,2014-08-06,2014-06-03
-4qjc,2015-06-10,2014-06-03
-2qjn,2007-10-30,2007-07-08
-3vnq,2013-01-23,2012-01-17
-2vnn,2008-05-20,2008-02-05
-2vnx,2008-04-08,2008-02-08
-2vnp,2008-03-18,2008-02-06
-6vno,2020-08-26,2020-01-29
-3vng,2013-01-16,2012-01-12
-5vnj,2017-07-05,2017-04-30
-3vnt,2012-04-11,2012-01-17
-5vnm,2017-07-05,2017-04-30
-5vng,2017-07-05,2017-04-30
-6vni,2021-02-17,2020-01-29
-6vnp,2021-02-03,2020-01-29
-6vny,2020-04-08,2020-01-29
-2vn8,2008-03-18,2008-01-31
-6vn3,2020-04-29,2020-01-29
-6vn2,2020-04-29,2020-01-29
-7vnm,2022-05-04,2021-10-11
-7vn7,2022-12-07,2021-10-10
-7vnt,2022-03-30,2021-10-12
-6vnf,2021-02-17,2020-01-29
-2vn0,2008-04-29,2008-01-30
-6vne,2021-02-17,2020-01-29
-5vn1,2017-05-10,2017-04-28
-2vn1,2008-05-20,2008-01-30
-3vn4,2012-12-26,2011-12-21
-6vnh,2021-02-17,2020-01-29
-3vnk,2012-08-01,2012-01-16
-6vn8,2021-02-17,2020-01-29
-5vn4,2017-05-24,2017-04-28
-3vnu,2012-08-08,2012-01-18
-7vnr,2021-12-01,2021-10-11
-2vn2,2008-08-12,2008-01-30
-6vn6,2020-04-29,2020-01-29
-3vno,2013-02-06,2012-01-17
-5vne,2017-07-05,2017-04-30
-3vnw,2013-01-23,2012-01-18
-3vni,2012-08-01,2012-01-16
-7vnb,2021-11-24,2021-10-10
-7vnc,2021-11-24,2021-10-10
-6vnj,2021-02-17,2020-01-29
-7vnl,2022-05-25,2021-10-11
-3vnm,2012-08-01,2012-01-17
-3vns,2013-01-23,2012-01-17
-7vny,2022-06-01,2021-10-12
-2vni,2008-11-11,2008-02-05
-5vns,2018-01-24,2017-05-01
-5vno,2017-07-05,2017-05-01
-2vnw,2008-04-08,2008-02-08
-5vnf,2017-07-05,2017-04-30
-2vna,2009-02-17,2008-02-01
-5vnp,2017-06-14,2017-05-01
-6vnb,2021-02-17,2020-01-29
-2vno,2008-02-19,2008-02-05
-2vnj,2008-11-11,2008-02-05
-5vnr,2017-07-26,2017-05-01
-6vn4,2020-04-29,2020-01-29
-3vnz,2012-02-22,2012-01-18
-5vn8,2017-07-12,2017-04-28
-7vn2,2022-12-07,2021-10-10
-6vnm,2021-02-17,2020-01-29
-6vnx,2020-04-08,2020-01-29
-2vnt,2008-02-19,2008-02-07
-2vnz,2008-04-08,2008-02-08
-6vn7,2020-09-02,2020-01-29
-6vnc,2021-02-17,2020-01-29
-7vnq,2021-12-01,2021-10-11
-2vnq,2008-03-18,2008-02-06
-2vnm,2008-05-20,2008-02-05
-5vnu,2017-08-16,2017-05-01
-6vnk,2021-02-17,2020-01-29
-5vnc,2018-05-02,2017-04-30
-3vnr,2013-01-23,2012-01-17
-3vnx,2012-03-28,2012-01-18
-2vnu,2008-04-08,2008-02-07
-6vnd,2020-11-04,2020-01-29
-7vnd,2021-11-24,2021-10-10
-3vnj,2012-08-01,2012-01-16
-5vnl,2017-07-05,2017-04-30
-2vn6,2008-05-13,2008-01-31
-7vn5,2022-12-07,2021-10-10
-3vn9,2012-02-29,2012-01-05
-3vnl,2012-08-01,2012-01-16
-5vn3,2017-07-12,2017-04-28
-5vn6,2017-06-07,2017-04-28
-2vnr,2008-02-19,2008-02-06
-5vn0,2017-08-02,2017-04-28
-2vn3,2008-12-23,2008-01-30
-5vnk,2017-07-05,2017-04-30
-5vnz,2017-12-06,2017-05-01
-3vnh,2013-01-16,2012-01-12
-6vns,2020-04-08,2020-01-29
-3vn2,2012-03-07,2011-12-21
-6vnv,2020-04-08,2020-01-29
-7vno,2022-03-30,2021-10-11
-7vnp,2021-12-01,2021-10-11
-5vn5,2017-09-27,2017-04-28
-3vnp,2012-03-07,2012-01-17
-2vn5,2008-05-20,2008-01-31
-7vn8,2022-12-07,2021-10-10
-7vnh,2022-04-13,2021-10-11
-2vng,2008-02-19,2008-02-04
-5vnd,2017-05-24,2017-04-30
-7vn6,2022-12-07,2021-10-10
-2vny,2008-04-08,2008-02-08
-5vnh,2017-07-05,2017-04-30
-6vn0,2020-06-24,2020-01-29
-2vn4,2008-05-20,2008-01-30
-6vnt,2021-02-03,2020-01-29
-2vnd,2008-02-12,2008-02-04
-7vn0,2022-09-14,2021-10-10
-7vng,2022-10-26,2021-10-11
-2vn9,2008-02-26,2008-01-31
-2vnh,2008-11-11,2008-02-05
-2vnv,2008-04-08,2008-02-07
-3vnv,2012-08-08,2012-01-18
-7vne,2021-11-24,2021-10-10
-7vns,2022-05-25,2021-10-12
-5vn2,2017-05-31,2017-04-28
-2vnf,2008-04-01,2008-02-04
-6vn5,2020-04-29,2020-01-29
-6vnu,2020-04-01,2020-01-29
-6vnl,2021-02-17,2020-01-29
-5vnn,2017-07-05,2017-05-01
-2vn7,2008-05-20,2008-01-31
-7vnj,2022-10-26,2021-10-11
-7vnn,2022-10-26,2021-10-11
-2vnk,2008-11-11,2008-02-05
-5vnv,2018-02-21,2017-05-01
-6vng,2021-02-17,2020-01-29
-7vn4,2022-12-07,2021-10-10
-5vni,2017-07-05,2017-04-30
-5vnw,2018-02-21,2017-05-01
-6vnr,2020-05-13,2020-01-29
-7vn9,2022-10-26,2021-10-10
-7vnx,2022-05-04,2021-10-12
-7vn3,2022-12-07,2021-10-10
-6vnq,2020-05-13,2020-01-29
-7zry,2022-08-03,2022-05-06
-5zr1,2018-07-11,2018-04-21
-7zrq,2022-12-28,2022-05-04
-5zri,2019-04-24,2018-04-24
-6zr4,2021-07-21,2020-07-10
-7zrc,2022-06-01,2022-05-04
-7zrr,2023-11-15,2022-05-05
-1zrf,2006-03-21,2005-05-19
-2zrv,2009-01-20,2008-09-01
-4zr5,2016-06-08,2015-05-11
-4zrp,2016-07-20,2015-05-12
-1zr4,2005-08-30,2005-05-19
-7zr8,2022-06-01,2022-05-03
-4zrd,2015-09-23,2015-05-12
-7zri,2022-11-16,2022-05-04
-7zr6,2022-12-28,2022-05-03
-3zrm,2011-06-29,2011-06-17
-7zrp,2022-12-28,2022-05-04
-7zre,2022-11-16,2022-05-04
-2zr9,2008-12-09,2008-08-27
-7zrl,2022-11-16,2022-05-04
-5zr3,2019-01-02,2018-04-23
-3zry,2012-01-18,2011-06-21
-6zr9,2021-06-16,2020-07-11
-5zrq,2018-09-12,2018-04-25
-5zr8,2019-04-24,2018-04-23
-7zrb,2023-05-17,2022-05-04
-7zr7,2022-06-01,2022-05-03
-2zrs,2008-11-04,2008-09-01
-5zrk,2019-04-24,2018-04-24
-3zr5,2011-09-28,2011-06-14
-1zrr,2005-12-06,2005-05-19
-5zrn,2019-04-24,2018-04-24
-6zr3,2021-07-21,2020-07-10
-2zrd,2008-12-09,2008-08-27
-7zrn,2022-11-02,2022-05-04
-4zr1,2015-07-29,2015-05-11
-2zr2,2008-09-09,2008-08-22
-6zrz,2020-12-09,2020-07-15
-4zrt,2015-06-24,2015-05-12
-2zre,2008-12-09,2008-08-27
-2zru,2009-01-20,2008-09-01
-6zrc,2020-10-28,2020-07-13
-4zr6,2016-05-11,2015-05-11
-4zr0,2015-07-29,2015-05-11
-7zrd,2022-11-16,2022-05-04
-3zrk,2011-06-29,2011-06-16
-2zrk,2008-12-09,2008-08-27
-5zre,2018-10-31,2018-04-24
-6zr7,2020-12-30,2020-07-11
-6zrd,2020-12-02,2020-07-13
-6zrg,2021-07-21,2020-07-13
-6zri,2021-07-21,2020-07-13
-3zr9,2011-06-29,2011-06-15
-5zr2,2019-04-24,2018-04-23
-7zrs,2023-02-22,2022-05-05
-2zrj,2008-12-09,2008-08-27
-1zrp,1993-10-31,1992-07-10
-7zrk,2022-11-16,2022-05-04
-2zr8,2009-07-28,2008-08-25
-2zr1,2009-08-25,2008-08-22
-7zrx,2023-05-17,2022-05-05
-1zrq,2005-08-09,2005-05-19
-7zrw,2023-05-17,2022-05-05
-3zrr,2012-06-27,2011-06-17
-1zr2,2005-08-30,2005-05-18
-5zro,2019-04-24,2018-04-24
-7zr1,2023-01-11,2022-05-03
-4zrr,2016-01-20,2015-05-12
-4zro,2015-10-14,2015-05-12
-3zrl,2011-06-29,2011-06-17
-4zrv,2016-05-25,2015-05-12
-1zrm,1999-03-23,1998-03-03
-7zrg,2022-11-16,2022-05-04
-3zra,2011-08-17,2011-06-15
-4zrm,2015-09-16,2015-05-12
-3zrb,2011-08-17,2011-06-15
-4zrw,2016-05-25,2015-05-12
-1zrz,2005-09-13,2005-05-23
-1zr6,2005-09-13,2005-05-19
-6zr5,2020-11-18,2020-07-10
-4zrb,2015-05-27,2015-05-12
-2zrt,2008-11-04,2008-09-01
-5zrl,2019-04-24,2018-04-24
-4zrn,2015-09-16,2015-05-12
-3zr6,2011-09-28,2011-06-14
-3zr4,2012-10-03,2011-06-13
-1zr0,2005-06-07,2005-05-18
-6zr0,2021-07-21,2020-07-10
-6zrn,2020-11-25,2020-07-13
-2zrm,2008-12-09,2008-08-27
-7zr4,2022-08-03,2022-05-03
-6zrp,2021-07-21,2020-07-14
-2zro,2008-12-09,2008-08-27
-4zrq,2016-07-20,2015-05-12
-7zr0,2022-12-14,2022-05-03
-7zrj,2022-11-16,2022-05-04
-6zru,2020-08-12,2020-07-14
-2zrl,2008-12-09,2008-08-27
-6zr2,2020-10-21,2020-07-10
-4zr2,2016-06-08,2015-05-11
-7zrt,2023-11-15,2022-05-05
-5zrt,2018-08-01,2018-04-25
-2zrg,2008-12-09,2008-08-27
-4zru,2015-05-27,2015-05-12
-6zra,2021-07-21,2020-07-12
-6zrk,2020-12-02,2020-07-13
-6zr8,2021-06-16,2020-07-11
-2zry,2009-01-20,2008-09-01
-6zrw,2021-07-28,2020-07-15
-7zrm,2022-11-16,2022-05-04
-6zrx,2020-12-09,2020-07-15
-6zry,2020-12-09,2020-07-15
-2zrp,2008-12-09,2008-08-27
-5zrs,2018-09-12,2018-04-25
-2zrw,2009-01-20,2008-09-01
-2zra,2008-12-09,2008-08-27
-2zrf,2008-12-09,2008-08-27
-6zrb,2022-07-27,2020-07-13
-1zr8,2005-06-14,2005-05-19
-5zr6,2019-03-20,2018-04-23
-5zrm,2019-05-01,2018-04-24
-3zrq,2012-06-27,2011-06-17
-1zr9,2005-06-07,2005-05-19
-3zr0,2011-07-27,2011-06-13
-5zrg,2019-04-24,2018-04-24
-4zr8,2015-06-03,2015-05-11
-6zrt,2020-08-12,2020-07-14
-5zrf,2018-08-08,2018-04-24
-1zrb,2005-06-07,2005-05-19
-5zru,2019-10-23,2018-04-25
-4zre,2015-09-23,2015-05-12
-3zrc,2012-03-07,2011-06-15
-2zri,2008-12-09,2008-08-27
-1zrd,2006-03-21,2005-05-19
-7zrh,2022-11-16,2022-05-04
-6zrj,2021-07-21,2020-07-13
-7zr5,2022-12-14,2022-05-03
-3zrs,2012-01-11,2011-06-17
-1zre,2006-03-21,2005-05-19
-2zrq,2009-03-03,2008-08-28
-1zrk,2006-05-09,2005-05-19
-1zrt,2005-06-07,2005-05-22
-2zrx,2009-01-20,2008-09-01
-3zrp,2012-06-27,2011-06-17
-7zr9,2022-06-01,2022-05-03
-3zr7,2011-08-17,2011-06-15
-5zrd,2018-10-31,2018-04-24
-1zrc,2006-03-21,2005-05-19
-6zr6,2021-07-21,2020-07-11
-6zrh,2021-07-21,2020-07-13
-2zrz,2009-01-20,2008-09-01
-7zrv,2023-03-08,2022-05-05
-5zrh,2019-04-24,2018-04-24
-5zrr,2018-09-12,2018-04-25
-1zrh,2005-06-07,2005-05-19
-7sy2,2021-12-29,2021-11-24
-6syx,2020-10-14,2019-10-01
-6syr,2019-11-27,2019-10-01
-1syl,2004-09-07,2004-04-01
-7sy5,2021-12-29,2021-11-24
-1syo,2004-06-29,2004-04-01
-5sys,2017-08-16,2016-08-11
-7syg,2022-07-13,2021-11-25
-5syf,2017-02-01,2016-08-11
-7syw,2022-07-13,2021-11-25
-7sy4,2021-12-29,2021-11-24
-3sya,2011-10-12,2011-07-16
-5syz,2016-10-12,2016-08-12
-1sy0,2004-06-08,2004-03-31
-8sy9,2023-09-13,2023-05-25
-6sys,2020-10-14,2019-10-01
-3syx,2011-08-03,2011-07-18
-7syt,2022-07-13,2021-11-25
-1syh,2005-03-22,2004-04-01
-7sy0,2021-12-29,2021-11-24
-6syc,2020-09-09,2019-09-27
-8sy6,2023-12-27,2023-05-24
-6syu,2019-11-27,2019-10-01
-7sy1,2021-12-29,2021-11-24
-6sy1,2020-06-24,2019-09-26
-6syz,2020-03-04,2019-10-01
-8sy0,2023-09-13,2023-05-24
-1sy7,2004-10-12,2004-04-01
-6syd,2020-09-09,2019-09-27
-7syq,2022-07-27,2021-11-25
-6sye,2020-09-09,2019-09-27
-3sy5,2011-09-21,2011-07-15
-8sye,2023-09-13,2023-05-25
-6syf,2020-08-12,2019-09-27
-5syw,2016-09-14,2016-08-12
-7syl,2022-07-13,2021-11-25
-8syl,2023-08-09,2023-05-25
-1sy1,2004-06-08,2004-03-31
-8sy4,2023-11-15,2023-05-24
-7sym,2022-07-13,2021-11-25
-6syt,2019-12-11,2019-10-01
-5sy4,2016-12-28,2016-08-10
-7syj,2022-07-13,2021-11-25
-1syb,1994-07-31,1994-01-07
-6sy3,2020-05-13,2019-09-27
-8syb,2023-09-13,2023-05-25
-5syi,2016-09-07,2016-08-11
-7syx,2022-07-13,2021-11-25
-8sya,2023-09-13,2023-05-25
-1syn,1996-01-29,1995-09-19
-6syb,2020-10-07,2019-09-27
-6syl,2021-01-20,2019-09-30
-3sym,2012-02-15,2011-07-18
-8sy5,2023-12-27,2023-05-24
-5syc,2017-02-01,2016-08-10
-7syi,2022-07-13,2021-11-25
-5sy3,2016-11-02,2016-08-10
-5syb,2016-09-07,2016-08-10
-7sys,2022-07-27,2021-11-25
-7syc,2021-12-08,2021-11-24
-6syq,2020-06-17,2019-09-30
-1sys,2004-10-19,2004-04-01
-1syi,2005-03-22,2004-04-01
-5syx,2016-09-14,2016-08-12
-7sy3,2021-12-29,2021-11-24
-6syp,2019-10-09,2019-09-30
-7syo,2022-07-27,2021-11-25
-6syw,2020-10-14,2019-10-01
-8sy7,2023-12-27,2023-05-24
-7syy,2022-06-01,2021-11-25
-3sy0,2011-08-03,2011-07-15
-7syn,2022-07-13,2021-11-25
-7sy6,2021-12-29,2021-11-24
-5syy,2016-09-14,2016-08-12
-1syf,1994-07-31,1994-01-07
-3syz,2012-06-06,2011-07-18
-5syj,2016-09-21,2016-08-11
-6syi,2020-11-25,2019-09-30
-7syz,2022-06-08,2021-11-25
-6syn,2020-10-14,2019-09-30
-5syv,2016-09-14,2016-08-12
-7syr,2022-07-27,2021-11-25
-3syt,2012-04-11,2011-07-18
-3syq,2011-10-12,2011-07-18
-5sy2,2016-11-02,2016-08-10
-3syy,2012-02-15,2011-07-18
-3syp,2011-10-12,2011-07-18
-5syu,2016-09-14,2016-08-12
-6syo,2020-10-14,2019-09-30
-7syp,2022-07-27,2021-11-25
-1sy2,2004-06-08,2004-03-31
-5syn,2016-10-26,2016-08-11
-1syv,2004-10-19,2004-04-02
-8syh,2023-09-13,2023-05-25
-5sy1,2016-08-24,2016-08-10
-5syk,2016-09-21,2016-08-11
-3sys,2012-02-08,2011-07-18
-6syy,2020-06-17,2019-10-01
-8sy3,2024-02-14,2023-05-24
-7syv,2022-07-20,2021-11-25
-6sym,2020-10-14,2019-09-30
-8syi,2023-07-05,2023-05-25
-1sy3,2004-06-08,2004-03-31
-5sym,2016-10-26,2016-08-11
-8syd,2023-09-13,2023-05-25
-5syt,2016-11-02,2016-08-11
-3sy8,2012-07-18,2011-07-16
-5syd,2017-08-16,2016-08-10
-3syi,2012-05-16,2011-07-17
-7syu,2022-07-13,2021-11-25
-6syv,2019-11-27,2019-10-01
-5sye,2017-02-01,2016-08-10
-6sya,2021-04-07,2019-09-27
-5syg,2017-02-01,2016-08-11
-5syl,2016-09-07,2016-08-11
-1syy,2004-07-13,2004-04-02
-5syo,2016-10-12,2016-08-11
-1sy9,2005-04-12,2004-04-01
-5syh,2016-09-07,2016-08-11
-1syt,2004-04-20,2004-04-02
-7syh,2022-07-13,2021-11-25
-7sy7,2021-12-29,2021-11-24
-3sy4,2012-05-16,2011-07-15
-3syc,2011-10-12,2011-07-16
-1syd,1994-07-31,1994-01-07
-6sy8,2021-07-14,2019-09-27
-7syk,2022-07-13,2021-11-25
-6sy7,2019-12-25,2019-09-27
-3syr,2012-02-15,2011-07-18
-3syo,2011-10-12,2011-07-18
-7sy8,2021-12-29,2021-11-24
-3syn,2011-11-09,2011-07-18
-1xcm,2005-05-10,2004-09-02
-5xcz,2017-07-26,2017-03-24
-4xc5,2015-04-01,2014-12-17
-7xcq,2023-03-29,2022-03-25
-5xcs,2017-10-04,2017-03-23
-2xcw,2011-03-16,2010-04-26
-2xcu,2011-05-11,2010-04-26
-6xc7,2020-07-08,2020-06-08
-2xcl,2011-03-23,2010-04-23
-2xc0,2010-08-04,2010-04-15
-6xc2,2020-07-08,2020-06-08
-2xcg,2010-10-06,2010-04-23
-4xca,2015-08-05,2014-12-17
-8xcp,2023-12-27,2023-12-10
-6xce,2020-09-23,2020-06-08
-7xcf,2023-03-29,2022-03-24
-2xc2,2010-08-11,2010-04-15
-4xcd,2016-02-10,2014-12-17
-2xcv,2011-03-16,2010-04-26
-8xcw,2023-12-27,2023-12-10
-7xck,2022-08-31,2022-03-24
-6xct,2021-06-16,2020-06-09
-7xci,2022-08-31,2022-03-24
-7xcr,2022-04-20,2022-03-25
-5xcr,2017-10-04,2017-03-23
-7xcm,2023-01-18,2022-03-24
-7xc7,2022-11-16,2022-03-23
-8xcs,2023-12-27,2023-12-10
-5xc8,2018-03-28,2017-03-22
-1xcd,2004-11-02,2004-09-01
-1xck,2005-10-25,2004-09-02
-8xcu,2023-12-27,2023-12-10
-6xc9,2021-07-14,2020-06-08
-4xc4,2015-02-11,2014-12-17
-7xcn,2023-01-18,2022-03-24
-6xcm,2020-07-01,2020-06-08
-2xc3,2010-11-10,2010-04-16
-4xc3,2016-02-03,2014-12-17
-5xc1,2018-03-28,2017-03-21
-5xcq,2017-10-04,2017-03-23
-2xcn,2010-06-02,2010-04-23
-2xc5,2010-08-04,2010-04-16
-7xch,2022-08-31,2022-03-24
-2xci,2011-05-11,2010-04-26
-7xc4,2022-11-23,2022-03-22
-6xci,2021-03-31,2020-06-08
-2xco,2010-08-04,2010-04-24
-2xcb,2010-05-05,2010-04-22
-2xcj,2010-07-28,2010-04-23
-4xcq,2016-03-09,2014-12-18
-4xcu,2015-04-01,2014-12-18
-5xcu,2017-10-04,2017-03-23
-8xcx,2023-12-27,2023-12-10
-7xcl,2023-01-18,2022-03-24
-1xc3,2004-10-12,2004-08-31
-5xc3,2017-10-25,2017-03-22
-6xcn,2020-07-01,2020-06-08
-5xc6,2017-11-08,2017-03-22
-2xch,2010-07-28,2010-04-23
-6xc3,2020-07-08,2020-06-08
-4xcb,2015-08-05,2014-12-17
-6xcd,2021-06-09,2020-06-08
-6xcf,2020-09-23,2020-06-08
-1xcl,2004-12-07,2004-09-02
-4xc8,2015-02-11,2014-12-17
-2xcd,2010-08-11,2010-04-22
-8xc1,2024-06-05,2023-12-07
-2xc4,2010-08-04,2010-04-16
-8xct,2023-12-27,2023-12-10
-5xc0,2018-03-28,2017-03-21
-8xc4,2024-01-24,2023-12-08
-2xca,2010-09-08,2010-04-20
-4xcy,2016-02-03,2014-12-18
-2xce,2010-08-11,2010-04-22
-6xc4,2020-07-08,2020-06-08
-2xck,2010-07-28,2010-04-23
-5xcv,2017-10-11,2017-03-23
-1xcw,2004-12-07,2004-09-03
-8xcq,2023-12-27,2023-12-10
-7xcb,2023-03-29,2022-03-23
-1xco,2004-12-07,2004-09-02
-4xct,2015-04-22,2014-12-18
-4xc0,2015-12-09,2014-12-17
-7xct,2022-04-20,2022-03-25
-6xcy,2021-06-16,2020-06-09
-2xc1,2011-05-04,2010-04-15
-8xco,2023-12-27,2023-12-10
-8xcm,2024-05-22,2023-12-09
-4xc7,2015-02-11,2014-12-17
-5xch,2017-10-18,2017-03-22
-6xcx,2021-06-16,2020-06-09
-4xcj,2015-12-09,2014-12-18
-1xcx,2004-12-07,2004-09-03
-1xc6,2004-11-02,2004-09-01
-1xcj,2004-12-07,2004-09-02
-1xcr,2005-09-27,2004-09-03
-8xcn,2024-05-22,2023-12-09
-5xco,2017-05-24,2017-03-23
-2xcm,2010-08-11,2010-04-23
-8xcv,2023-12-27,2023-12-10
-1xc9,2004-12-14,2004-09-01
-4xcx,2015-01-14,2014-12-18
-1xc7,2005-02-08,2004-09-01
-4xcg,2016-02-10,2014-12-18
-7xc2,2022-09-21,2022-03-22
-2xcs,2010-08-04,2010-04-25
-2xcp,2010-09-08,2010-04-24
-4xcn,2016-02-03,2014-12-18
-7xco,2022-09-21,2022-03-24
-1xcp,2005-03-15,2004-09-02
-2xcr,2010-08-04,2010-04-25
-1xch,1997-09-17,1997-06-06
-6xcc,2020-09-23,2020-06-08
-7xca,2023-03-29,2022-03-23
-5xc9,2018-03-28,2017-03-22
-4xcl,2015-12-09,2014-12-18
-6xcb,2020-09-23,2020-06-08
-2xct,2010-08-25,2010-04-25
-5xct,2017-10-04,2017-03-23
-7xc9,2023-03-29,2022-03-23
-8xcz,2023-12-27,2023-12-10
-5xc4,2018-03-28,2017-03-22
-4xcv,2014-12-31,2014-12-18
-5xc5,2017-10-25,2017-03-22
-6xch,2020-06-17,2020-06-08
-5xca,2018-03-28,2017-03-22
-8xcr,2023-12-27,2023-12-10
-5xc2,2018-03-28,2017-03-22
-4xco,2015-06-10,2014-12-18
-6xcp,2021-07-14,2020-06-08
-1xcb,2004-09-28,2004-09-01
-1xcv,2005-08-16,2004-09-03
-1xc8,2005-09-06,2004-09-01
-6xco,2021-07-14,2020-06-08
-4xc6,2015-02-11,2014-12-17
-4xck,2015-01-21,2014-12-18
-7xcp,2022-08-31,2022-03-24
-4xch,2015-06-24,2014-12-18
-6xcj,2020-12-02,2020-06-08
-2xc7,2010-04-28,2010-04-18
-8xcy,2023-12-27,2023-12-10
-4xcf,2016-02-03,2014-12-17
-4xcz,2015-01-21,2014-12-18
-6xcz,2021-06-16,2020-06-09
-4xc1,2016-02-03,2014-12-17
-7xc1,2023-03-22,2022-03-22
-1fqr,2001-01-17,2000-09-06
-8fqo,2023-07-05,2023-01-06
-3fql,2009-02-24,2009-01-07
-3fqc,2009-03-24,2009-01-07
-4fq1,2012-11-14,2012-06-24
-5fqn,2017-01-18,2015-12-14
-5fqh,2016-03-30,2015-12-10
-4fqf,2012-09-26,2012-06-25
-3fqf,2009-03-24,2009-01-07
-8fqs,2023-07-05,2023-01-06
-7fqx,2022-11-23,2022-10-19
-1fq3,2001-01-31,2000-09-03
-3fqd,2009-02-03,2009-01-07
-5fqv,2016-02-10,2015-12-14
-8fqh,2024-02-28,2023-01-06
-6fqm,2018-04-04,2018-02-14
-7fqu,2022-11-23,2022-10-19
-6fqe,2019-03-13,2018-02-14
-5fqg,2016-03-30,2015-12-10
-2fqz,2006-06-20,2006-01-18
-7fqt,2022-11-23,2022-10-19
-2fqy,2006-02-14,2006-01-18
-4fqz,2012-07-11,2012-06-26
-4fqt,2013-01-02,2012-06-25
-8fqc,2024-01-31,2023-01-05
-5fqo,2017-01-18,2015-12-14
-4fqp,2012-08-22,2012-06-25
-3fqm,2009-03-10,2009-01-07
-8fqy,2023-02-01,2023-01-06
-1fqx,2001-03-14,2000-09-07
-3fq7,2009-11-24,2009-01-07
-7fqv,2022-11-23,2022-10-19
-7fqf,2023-09-20,2022-09-12
-7fqr,2022-11-23,2022-10-19
-1fqe,2001-05-16,2000-09-04
-8fqm,2023-07-05,2023-01-06
-6fqn,2018-08-29,2018-02-14
-7fqm,2022-11-23,2022-10-19
-7fqh,2023-10-11,2022-10-05
-7fqc,2023-09-20,2022-09-12
-3fqg,2009-02-03,2009-01-07
-6fqo,2018-08-29,2018-02-14
-5fq9,2016-08-17,2015-12-08
-7fq0,2023-09-20,2022-09-10
-4fq4,2012-10-31,2012-06-25
-4fqq,2012-11-14,2012-06-25
-1fqm,2001-01-17,2000-09-06
-4fqi,2012-08-22,2012-06-25
-5fq4,2016-12-14,2015-12-04
-5fqb,2016-08-10,2015-12-08
-7fqq,2022-11-23,2022-10-19
-5fqk,2016-12-21,2015-12-11
-7fq6,2023-09-20,2022-09-12
-7fqe,2023-09-20,2022-09-12
-7fqn,2022-11-23,2022-10-19
-2fqw,2006-02-14,2006-01-18
-3fqz,2009-03-24,2009-01-07
-3fq8,2009-11-24,2009-01-07
-8fqb,2024-02-28,2023-01-05
-8fq8,2024-02-28,2023-01-05
-7fqj,2023-10-11,2022-10-05
-7fq3,2023-09-20,2022-09-12
-3fq0,2009-03-24,2009-01-06
-3fqv,2009-03-24,2009-01-07
-3fqj,2009-02-03,2009-01-07
-8fqe,2024-02-28,2023-01-06
-3fqo,2009-03-24,2009-01-07
-3fqk,2009-02-24,2009-01-07
-3fqn,2009-03-03,2009-01-07
-7fqk,2023-10-11,2022-10-05
-7fqg,2023-09-20,2022-09-12
-5fqd,2016-02-24,2015-12-09
-5fqu,2016-04-06,2015-12-14
-1fqc,2001-03-14,2000-09-04
-2fqd,2007-01-30,2006-01-18
-4fqj,2012-08-22,2012-06-25
-2fqq,2006-05-16,2006-01-18
-3fqi,2009-02-03,2009-01-07
-3fqr,2009-03-03,2009-01-07
-3fqt,2009-03-03,2009-01-07
-3fq2,2009-11-10,2009-01-06
-6fqi,2019-03-13,2018-02-14
-4fqw,2013-12-25,2012-06-25
-3fqs,2009-03-10,2009-01-07
-6fqk,2019-03-13,2018-02-14
-7fqz,2022-11-23,2022-10-20
-7fq9,2023-09-20,2022-09-12
-5fqp,2016-02-10,2015-12-14
-5fqa,2016-08-10,2015-12-08
-6fqu,2018-08-29,2018-02-14
-1fq7,2000-09-20,2000-09-04
-6fqr,2018-09-05,2018-02-14
-2fq9,2006-03-21,2006-01-17
-7fqo,2022-11-23,2022-10-19
-5fq5,2016-03-23,2015-12-07
-3fqy,2009-11-10,2009-01-07
-2fqi,2007-01-23,2006-01-18
-6fqf,2018-06-13,2018-02-14
-7fqy,2022-11-23,2022-10-19
-2fqg,2007-01-30,2006-01-18
-7fqw,2022-11-23,2022-10-19
-8fq3,2024-02-28,2023-01-05
-6fqs,2018-04-04,2018-02-14
-2fqx,2006-02-14,2006-01-18
-1fq8,2000-09-20,2000-09-04
-7fq5,2023-09-20,2022-09-12
-6fqg,2019-03-13,2018-02-14
-7fq4,2023-09-20,2022-09-12
-2fq2,2006-08-08,2006-01-17
-2fqe,2007-01-30,2006-01-18
-5fq0,2016-05-04,2015-12-03
-3fq9,2009-08-04,2009-01-07
-5fqj,2016-12-21,2015-12-11
-2fqf,2007-01-30,2006-01-18
-6fqj,2019-03-13,2018-02-14
-6fqv,2018-04-04,2018-02-14
-4fqk,2012-08-22,2012-06-25
-2fqt,2006-05-30,2006-01-18
-5fqr,2016-02-10,2015-12-14
-4fq8,2012-12-26,2012-06-25
-7fqb,2023-09-20,2022-09-12
-8fqa,2024-03-06,2023-01-05
-5fqf,2016-03-30,2015-12-10
-8fqd,2024-02-28,2023-01-06
-7fqa,2023-09-20,2022-09-12
-5fq7,2016-12-21,2015-12-07
-8fqp,2023-07-05,2023-01-06
-8fqz,2023-02-01,2023-01-06
-1fqf,2001-05-16,2000-09-04
-3fqx,2009-03-03,2009-01-07
-2fqp,2006-05-16,2006-01-18
-5fq6,2016-12-21,2015-12-07
-1fqb,2001-03-14,2000-09-04
-5fqc,2016-08-17,2015-12-08
-8fqx,2023-02-01,2023-01-06
-1fq4,2000-09-20,2000-09-03
-3fqe,2009-03-10,2009-01-07
-2fq1,2006-05-02,2006-01-17
-7fq2,2023-09-20,2022-09-10
-6fqt,2019-03-13,2018-02-14
-1fqk,2001-02-28,2000-09-05
-8fq9,2024-06-05,2023-01-05
-1fq1,2001-05-09,2000-09-01
-1fqo,2002-01-04,2000-09-06
-8fqw,2023-07-05,2023-01-06
-1fqw,2001-07-18,2000-09-07
-1fql,2001-01-17,2000-09-05
-6fqz,2018-08-22,2018-02-15
-7fq1,2023-09-20,2022-09-10
-2fq6,2006-12-26,2006-01-17
-5fq8,2016-12-21,2015-12-07
-3fq1,2009-11-10,2009-01-06
-8fq2,2024-02-28,2023-01-05
-7fqs,2022-11-23,2022-10-19
-6fqh,2019-03-13,2018-02-14
-6fqb,2018-08-22,2018-02-13
-3fqa,2009-11-24,2009-01-07
-1fq5,2000-09-20,2000-09-03
-5fqt,2016-02-10,2015-12-14
-4fqm,2012-08-22,2012-06-25
-3fqq,2009-03-24,2009-01-07
-4fqx,2013-01-09,2012-06-25
-6fqy,2018-08-22,2018-02-15
-7fq8,2023-09-20,2022-09-12
-7fqd,2023-09-20,2022-09-12
-3fqw,2009-03-03,2009-01-07
-8fqu,2023-07-05,2023-01-06
-5fqs,2016-02-10,2015-12-14
-5fql,2017-01-18,2015-12-11
-3fqh,2009-03-10,2009-01-07
-8fqq,2023-07-05,2023-01-06
-7fql,2023-10-11,2022-10-05
-2fqo,2006-05-30,2006-01-18
-4fqg,2013-02-27,2012-06-25
-1fqg,2000-11-01,2000-09-05
-8fq1,2024-02-28,2023-01-05
-6fqd,2018-05-09,2018-02-13
-7fqp,2022-11-23,2022-10-19
-4fqo,2012-10-17,2012-06-25
-1fqd,2001-03-14,2000-09-04
-8fqr,2023-07-05,2023-01-06
-8fqg,2024-02-28,2023-01-06
-8fq6,2024-02-28,2023-01-05
-6fq7,2019-03-13,2018-02-13
-1fqa,2001-03-14,2000-09-04
-4fqr,2012-09-19,2012-06-25
-4fqs,2013-08-07,2012-06-25
-7fq7,2023-09-20,2022-09-12
-3fqu,2009-03-03,2009-01-07
-1fqj,2001-02-28,2000-09-05
-8fqn,2023-07-05,2023-01-06
-1fq6,2000-09-20,2000-09-03
-7fqi,2023-10-11,2022-10-05
-2fq0,2006-08-08,2006-01-17
-6e2g,2018-08-22,2018-07-11
-7e2v,2021-12-01,2021-02-07
-1e2q,2001-05-17,2000-05-23
-7e20,2022-06-15,2021-02-04
-3e2z,2008-12-30,2008-08-06
-2e2d,2007-03-13,2006-11-11
-2e2t,2007-11-20,2006-11-17
-5e2k,2016-01-20,2015-10-01
-4e2f,2012-05-02,2012-03-08
-5e23,2016-03-23,2015-09-30
-3e2s,2009-02-03,2008-08-06
-8e2m,2022-11-16,2022-08-15
-5e28,2016-01-20,2015-09-30
-5e2f,2015-10-14,2015-10-01
-2e21,2007-11-06,2006-11-06
-7e2x,2021-04-14,2021-02-07
-1e24,2000-07-28,2000-05-16
-1e2z,2000-08-04,2000-05-30
-3e23,2008-09-30,2008-08-05
-7e22,2022-02-09,2021-02-04
-6e21,2019-04-03,2018-07-10
-8e21,2022-09-14,2022-08-12
-3e2r,2009-02-03,2008-08-06
-1e2p,2001-04-26,2000-05-23
-2e22,2007-01-30,2006-11-07
-5e2z,2015-12-02,2015-10-01
-1e2w,2000-08-04,2000-05-30
-3e2d,2009-06-16,2008-08-05
-6e25,2018-09-26,2018-07-10
-2e2h,2006-12-12,2006-11-14
-1e2i,2000-11-06,2000-05-23
-1e2a,1998-04-29,1997-04-25
-5e2t,2016-02-24,2015-10-01
-6e2f,2018-08-22,2018-07-11
-3e2y,2008-12-30,2008-08-06
-3e2q,2009-02-03,2008-08-06
-2e2v,2007-11-20,2006-11-17
-6e22,2019-03-13,2018-07-10
-5e25,2016-10-05,2015-09-30
-7e2y,2021-04-14,2021-02-07
-7e2z,2021-04-14,2021-02-07
-4e2y,2012-04-25,2012-03-09
-2e2i,2006-12-19,2006-11-14
-4e2w,2012-04-25,2012-03-09
-8e24,2022-09-28,2022-08-13
-4e2q,2012-04-18,2012-03-09
-2e2u,2007-11-20,2006-11-17
-4e2o,2013-03-13,2012-03-09
-6e2w,2020-01-15,2018-07-12
-5e2a,2015-10-28,2015-09-30
-4e2x,2012-04-25,2012-03-09
-4e2v,2013-03-27,2012-03-09
-3e22,2008-10-21,2008-08-05
-5e2p,2015-12-09,2015-10-01
-5e2b,2015-10-28,2015-09-30
-1e2k,2000-08-19,2000-05-23
-1e2j,2000-11-06,2000-05-23
-2e2q,2007-01-16,2006-11-15
-6e2x,2018-12-26,2018-07-12
-1e2l,2000-08-18,2000-05-23
-5e2w,2016-02-24,2015-10-01
-8e2p,2023-01-11,2022-08-15
-8e2q,2023-01-11,2022-08-15
-5e2q,2016-04-13,2015-10-01
-1e2f,2001-05-17,2000-05-22
-3e28,2009-06-02,2008-08-05
-3e25,2008-12-02,2008-08-05
-6e2y,2020-01-15,2018-07-12
-1e2n,2001-03-31,2000-05-23
-1e2e,2001-05-17,2000-05-22
-5e2y,2015-12-02,2015-10-01
-1e2s,2000-12-06,2000-05-24
-5e2i,2016-03-30,2015-10-01
-1e2m,2001-03-31,2000-05-23
-2e2y,2007-10-23,2006-11-18
-7e23,2021-05-05,2021-02-04
-8e23,2022-09-28,2022-08-13
-1e2g,2001-05-17,2000-05-22
-5e2r,2015-11-04,2015-10-01
-5e2v,2016-02-24,2015-10-01
-5e2l,2016-06-01,2015-10-01
-7e29,2022-02-09,2021-02-05
-7e2g,2021-12-08,2021-02-05
-2e2p,2007-01-16,2006-11-15
-5e2o,2015-12-09,2015-10-01
-2e2o,2007-01-16,2006-11-15
-4e2d,2013-03-27,2012-03-08
-8e2c,2023-08-09,2022-08-14
-3e2m,2008-08-19,2008-08-05
-4e28,2012-11-14,2012-03-07
-5e29,2015-10-14,2015-09-30
-4e20,2012-10-03,2012-03-07
-4e2g,2012-03-21,2012-03-08
-5e20,2016-10-05,2015-09-30
-6e2u,2020-01-15,2018-07-12
-4e2b,2013-03-27,2012-03-08
-1e26,2001-05-17,2000-05-17
-1e2r,2000-05-30,2000-05-24
-3e2a,2009-06-02,2008-08-05
-3e2e,2008-11-04,2008-08-05
-5e2m,2016-10-05,2015-10-01
-5e2n,2016-10-05,2015-10-01
-1e22,2000-07-28,2000-05-15
-7e2w,2021-05-19,2021-02-07
-6e2t,2020-01-15,2018-07-12
-7e2u,2021-08-25,2021-02-07
-4e2p,2013-03-13,2012-03-09
-5e2s,2016-01-20,2015-10-01
-7e21,2022-06-15,2021-02-04
-6e2b,2018-11-14,2018-07-11
-6e20,2019-03-20,2018-07-10
-5e2d,2016-04-20,2015-10-01
-3e2x,2009-08-18,2008-08-06
-2e2j,2006-12-12,2006-11-14
-2e20,2007-09-18,2006-11-04
-1e2v,2000-08-04,2000-05-29
-3e2h,2008-11-04,2008-08-05
-6e2m,2018-09-19,2018-07-11
-1e20,2000-09-11,2000-05-12
-8e2r,2023-01-11,2022-08-15
-8e25,2022-10-12,2022-08-14
-2e25,2007-03-13,2006-11-08
-3e2c,2009-05-12,2008-08-05
-4e27,2013-03-27,2012-03-07
-7e2s,2021-08-25,2021-02-07
-3e24,2009-06-02,2008-08-05
-6e2v,2020-01-15,2018-07-12
-6e27,2018-09-26,2018-07-10
-7e2t,2021-08-25,2021-02-07
-6e23,2019-03-13,2018-07-10
-5e24,2016-06-15,2015-09-30
-2e2r,2007-09-11,2006-11-16
-1e2d,2001-05-17,2000-05-22
-1e27,2000-09-12,2000-05-18
-7e27,2021-08-18,2021-02-04
-3e2o,2008-10-21,2008-08-05
-3e2j,2008-08-19,2008-08-05
-8e2s,2023-01-11,2022-08-15
-2e2b,2007-05-22,2006-11-10
-8e26,2022-10-12,2022-08-14
-4e2z,2012-04-25,2012-03-09
-8e2l,2022-11-02,2022-08-15
-2e2z,2007-10-09,2006-11-19
-3e2u,2008-08-19,2008-08-06
-4e2j,2012-03-28,2012-03-08
-6e2a,2019-02-06,2018-07-10
-7e24,2021-09-29,2021-02-04
-3e27,2008-09-09,2008-08-05
-8e2z,2023-08-02,2022-08-16
-1e29,2001-05-04,2000-05-19
-3e2n,2008-10-21,2008-08-05
-2e27,2007-11-13,2006-11-08
-4e26,2012-05-09,2012-03-07
-3e2v,2008-08-26,2008-08-06
-5e2j,2016-02-03,2015-10-01
-4e2i,2012-06-13,2012-03-08
-7e2e,2021-06-30,2021-02-05
-6e2n,2018-09-19,2018-07-11
-3e2w,2009-08-18,2008-08-06
-7e2i,2021-12-08,2021-02-05
-6e2o,2018-09-19,2018-07-11
-1e28,2000-09-12,2000-05-18
-3e2t,2008-11-04,2008-08-06
-3e2i,2009-08-11,2008-08-05
-7e2h,2021-12-08,2021-02-05
-7e2b,2022-02-09,2021-02-05
-2e26,2007-05-22,2006-11-08
-6e2z,2018-12-26,2018-07-12
-4e2s,2012-04-18,2012-03-09
-5see,2022-10-12,2022-01-21
-6sel,2019-08-21,2019-07-30
-3seu,2011-09-21,2011-06-11
-8sev,2023-05-24,2023-04-10
-1sem,1995-07-10,1995-03-28
-3se2,2011-07-06,2011-06-10
-8sen,2023-05-24,2023-04-10
-6set,2019-09-18,2019-07-30
-3ses,2011-09-21,2011-06-11
-6sep,2020-08-26,2019-07-30
-6se7,2020-08-26,2019-07-29
-8sez,2023-05-24,2023-04-10
-5se1,2022-10-12,2022-01-21
-5se6,2022-10-12,2022-01-21
-8se6,2023-10-11,2023-04-08
-7sed,2022-02-09,2021-09-30
-3se9,2011-08-10,2011-06-10
-7sev,2021-11-03,2021-10-01
-5sea,2022-10-12,2022-01-21
-3see,2011-08-03,2011-06-10
-1sed,2004-05-25,2004-02-17
-1sej,2004-05-18,2004-02-17
-5se7,2022-10-12,2022-01-21
-5sec,2022-10-12,2022-01-21
-5seq,2022-10-12,2022-01-21
-5se3,2022-10-12,2022-01-21
-5seo,2022-10-12,2022-01-21
-5se2,2022-10-12,2022-01-21
-7se8,2022-02-09,2021-09-30
-5seb,2022-10-12,2022-01-21
-7sez,2022-03-30,2021-10-02
-5sei,2022-10-12,2022-01-21
-5sej,2022-10-12,2022-01-21
-7sem,2022-02-16,2021-09-30
-1sez,2004-04-13,2004-02-19
-5sew,2022-10-12,2022-01-21
-5sed,2022-10-12,2022-01-21
-6sey,2020-08-26,2019-07-30
-3set,2011-09-21,2011-06-11
-5sep,2022-10-12,2022-01-21
-1se3,1997-06-16,1996-10-11
-2sem,1999-01-06,1998-11-02
-5se4,2022-10-12,2022-01-21
-7sej,2022-02-09,2021-09-30
-1seu,2005-04-19,2004-02-18
-1sel,1993-10-31,1993-01-17
-3se5,2012-01-25,2011-06-10
-8seu,2023-05-24,2023-04-10
-8se9,2023-10-11,2023-04-08
-8sex,2023-05-24,2023-04-10
-3sey,2011-09-21,2011-06-11
-3sez,2012-04-11,2011-06-11
-5sen,2022-10-12,2022-01-21
-5se8,2022-10-12,2022-01-21
-3sek,2011-11-02,2011-06-10
-8sep,2023-05-24,2023-04-10
-7se9,2022-02-09,2021-09-30
-6seh,2019-09-25,2019-07-30
-5ses,2022-10-12,2022-01-21
-8ser,2023-05-24,2023-04-10
-7sey,2021-12-01,2021-10-02
-3sec,2012-04-25,2011-06-10
-5sey,2022-10-12,2022-01-21
-7sek,2022-06-01,2021-09-30
-3se8,2011-08-10,2011-06-10
-5ser,2022-10-12,2022-01-21
-8se5,2023-10-11,2023-04-08
-5set,2022-10-12,2022-01-21
-5sel,2022-10-12,2022-01-21
-1se6,2005-01-25,2004-02-16
-2sec,1988-09-07,1988-09-05
-5se5,2022-10-12,2022-01-21
-1ses,1994-07-31,1994-02-21
-6se9,2019-09-11,2019-07-29
-5sef,2022-10-12,2022-01-21
-1seh,2004-09-07,2004-02-17
-3seq,2012-04-11,2011-06-10
-7seb,2022-02-09,2021-09-30
-3se7,2011-09-14,2011-06-10
-1set,1994-07-31,1994-02-21
-5se9,2022-10-12,2022-01-21
-1se4,1997-10-15,1997-04-16
-8seq,2023-05-24,2023-04-10
-6sew,2019-09-18,2019-07-30
-3sep,2012-01-18,2011-06-10
-8seb,2023-10-11,2023-04-08
-3sem,1999-01-06,1998-11-02
-3sen,2011-12-14,2011-06-10
-5sek,2022-10-12,2022-01-21
-8set,2023-05-24,2023-04-10
-6se3,2019-12-25,2019-07-29
-7seh,2022-08-17,2021-09-30
-1sen,2004-07-13,2004-02-17
-7sea,2022-02-09,2021-09-30
-5sez,2022-10-12,2022-01-21
-6se2,2020-08-26,2019-07-29
-3sel,2012-06-27,2011-06-10
-3sef,2011-07-27,2011-06-10
-3se6,2011-12-21,2011-06-10
-3se3,2011-08-31,2011-06-10
-6seu,2019-09-18,2019-07-30
-6se4,2019-08-14,2019-07-29
-6ses,2020-07-08,2019-07-30
-5se0,2022-10-12,2022-01-21
-5seg,2022-10-12,2022-01-21
-6sej,2019-08-21,2019-07-30
-6se5,2020-08-26,2019-07-29
-7seg,2021-11-24,2021-09-30
-6sez,2019-09-18,2019-07-30
-8seo,2023-05-24,2023-04-10
-6sex,2019-09-18,2019-07-30
-6se8,2019-09-11,2019-07-29
-6sed,2019-09-11,2019-07-29
-3sex,2011-09-21,2011-06-11
-7sec,2022-02-09,2021-09-30
-7seo,2022-01-05,2021-09-30
-8sey,2023-05-24,2023-04-10
-1se0,2004-04-27,2004-02-15
-7ses,2022-01-26,2021-10-01
-7se7,2022-02-09,2021-09-30
-5sex,2022-10-12,2022-01-21
-3sev,2011-09-21,2011-06-11
-6sea,2019-09-11,2019-07-29
-2seb,1998-01-28,1997-10-16
-7sei,2022-08-17,2021-09-30
-8sew,2023-05-24,2023-04-10
-3ser,2011-09-21,2011-06-11
-5seh,2022-10-12,2022-01-21
-7sew,2021-12-01,2021-10-02
-5sem,2022-10-12,2022-01-21
-3sew,2011-09-21,2011-06-11
-3se1,2012-02-29,2011-06-10
-5seu,2022-10-12,2022-01-21
-6sev,2019-09-25,2019-07-30
-8sea,2023-10-11,2023-04-08
-6sem,2019-12-25,2019-07-30
-7set,2022-10-05,2021-10-01
-6sek,2019-12-25,2019-07-30
-5sev,2022-10-12,2022-01-21
-7ser,2022-01-26,2021-10-01
-8ses,2023-05-24,2023-04-10
-3sea,2012-06-20,2011-06-10
-6sei,2019-09-25,2019-07-30
-3se4,2011-08-31,2011-06-10
-1sep,1999-01-13,1997-05-23
-6seb,2019-09-11,2019-07-29
-3sej,2011-07-13,2011-06-10
-6sec,2019-09-11,2019-07-29
-7sel,2022-03-09,2021-09-30
-7sex,2021-12-01,2021-10-02
-6af9,2018-08-29,2018-08-08
-1afr,1997-05-15,1997-03-13
-4afx,2013-01-09,2012-01-23
-6afv,2019-04-10,2018-08-08
-3af9,2010-08-11,2010-02-24
-4af0,2012-10-24,2012-01-15
-6afi,2018-08-29,2018-08-08
-7afa,2021-07-07,2020-09-19
-7afi,2021-07-07,2020-09-19
-1afv,1997-08-20,1997-03-14
-6afy,2019-04-10,2018-08-08
-8afr,2023-02-01,2022-07-18
-2afx,2005-08-23,2005-07-26
-5afx,2015-10-28,2015-01-27
-5af0,2015-04-01,2015-01-13
-7afz,2021-10-06,2020-09-21
-3af8,2010-08-11,2010-02-24
-6afx,2019-04-10,2018-08-08
-8afb,2022-11-09,2022-07-16
-2afb,2006-02-14,2005-07-25
-1afe,1997-12-03,1997-03-06
-5afn,2015-05-06,2015-01-22
-6afb,2018-08-29,2018-08-08
-1af6,1998-03-25,1997-03-21
-3afh,2010-06-30,2010-03-01
-2afm,2005-08-23,2005-07-26
-4af3,2012-04-11,2012-01-16
-2af2,2005-11-15,2005-07-25
-4afi,2012-05-30,2012-01-19
-5af2,2015-03-18,2015-01-16
-5afe,2015-02-04,2015-01-21
-2afy,2005-12-13,2005-07-26
-3afv,2011-03-16,2010-03-11
-3afk,2010-12-01,2010-03-09
-2afi,2005-09-06,2005-07-25
-6afe,2018-08-29,2018-08-08
-6afz,2019-04-10,2018-08-08
-2aft,2005-12-13,2005-07-26
-6afu,2019-04-10,2018-08-08
-2afu,2005-08-23,2005-07-26
-3af3,2010-05-26,2010-02-22
-2afw,2005-08-23,2005-07-26
-2afh,2005-09-06,2005-07-25
-8afv,2023-04-05,2022-07-18
-3afn,2010-08-11,2010-03-10
-2af4,2006-01-24,2005-07-25
-7afu,2020-10-28,2020-09-20
-7afh,2021-07-07,2020-09-19
-4afg,2012-05-30,2012-01-19
-7af1,2020-10-28,2020-09-19
-6afp,2020-01-15,2018-08-08
-5afu,2015-03-11,2015-01-26
-7af8,2021-07-07,2020-09-19
-3afj,2011-03-23,2010-03-04
-1afq,1997-09-17,1997-03-12
-8afi,2023-05-10,2022-07-18
-7af0,2020-12-02,2020-09-18
-4af7,2012-05-30,2012-01-18
-8afj,2023-03-29,2022-07-18
-5afv,2015-03-18,2015-01-26
-6af5,2018-08-29,2018-08-08
-8afa,2023-04-05,2022-07-16
-5afj,2015-05-06,2015-01-22
-8afd,2022-11-09,2022-07-16
-4afe,2012-04-25,2012-01-19
-6afs,2019-04-10,2018-08-08
-5af6,2015-03-25,2015-01-19
-3af6,2010-04-21,2010-02-24
-5afs,2016-02-24,2015-01-23
-3af5,2010-04-21,2010-02-23
-8af2,2023-08-16,2022-07-15
-2afz,2005-08-23,2005-07-26
-6afk,2019-08-14,2018-08-08
-4aff,2012-02-01,2012-01-19
-3afg,2010-08-04,2010-03-01
-6afa,2018-08-29,2018-08-08
-4afc,2012-10-17,2012-01-18
-2afn,1996-08-01,1995-07-03
-1afs,1997-10-08,1997-03-13
-3af0,2010-05-26,2010-02-19
-1afa,1996-04-03,1995-11-03
-4aft,2012-05-02,2012-01-23
-7afk,2021-07-07,2020-09-19
-6afd,2018-08-29,2018-08-08
-4afj,2012-02-29,2012-01-19
-6afr,2018-12-12,2018-08-08
-5af7,2015-06-03,2015-01-20
-1af4,1997-06-16,1997-03-21
-7afv,2020-12-09,2020-09-20
-4af8,2012-05-02,2012-01-18
-7af5,2021-07-07,2020-09-19
-6afj,2018-08-29,2018-08-08
-8af1,2023-08-16,2022-07-15
-8afn,2023-04-26,2022-07-18
-5afm,2015-05-06,2015-01-22
-3af7,2010-08-11,2010-02-24
-1afj,1997-07-23,1997-03-07
-5afi,2015-03-11,2015-01-22
-5afy,2015-08-26,2015-01-27
-7afy,2021-10-06,2020-09-21
-4af9,2012-10-17,2012-01-18
-2afo,2005-08-23,2005-07-26
-4afp,2012-05-02,2012-01-23
-1af2,1997-07-07,1997-03-20
-3af1,2010-05-26,2010-02-19
-6afg,2018-08-29,2018-08-08
-7afo,2021-07-07,2020-09-19
-7afd,2021-07-07,2020-09-19
-7afs,2020-10-28,2020-09-20
-8afc,2022-11-09,2022-07-16
-6afc,2018-08-29,2018-08-08
-2af3,2006-01-24,2005-07-25
-1afk,1998-03-18,1997-03-08
-6aff,2018-08-29,2018-08-08
-5afa,2016-02-17,2015-01-19
-1afl,1998-03-18,1997-03-08
-8afp,2023-03-08,2022-07-18
-3afp,2010-10-06,2010-03-10
-8afu,2023-04-05,2022-07-18
-3afb,2010-06-09,2010-02-25
-4afd,2012-12-26,2012-01-18
-6afw,2019-04-10,2018-08-08
-3afl,2010-04-28,2010-03-09
-4afs,2012-07-11,2012-01-23
-6afh,2018-08-29,2018-08-08
-3afo,2011-03-16,2010-03-10
-4af1,2013-03-20,2012-01-16
-5afb,2015-03-18,2015-01-21
-3afa,2010-05-26,2010-02-24
-1afd,1996-04-03,1995-11-03
-5afh,2015-05-06,2015-01-22
-3afc,2010-10-06,2010-02-26
-5afz,2015-08-26,2015-01-27
-7afx,2021-10-06,2020-09-21
-7afn,2021-07-07,2020-09-19
-8afo,2023-03-08,2022-07-18
-7afl,2021-07-07,2020-09-19
-2afs,2005-08-23,2005-07-26
-3af4,2010-05-26,2010-02-22
-4afy,2013-01-09,2012-01-23
-5afp,2015-03-18,2015-01-23
-4afa,2012-10-17,2012-01-18
-6afn,2020-01-15,2018-08-08
-5afg,2016-01-27,2015-01-22
-7af3,2021-07-07,2020-09-19
-4afk,2013-02-06,2012-01-19
-8afk,2023-08-16,2022-07-18
-4afh,2012-05-30,2012-01-19
-5afw,2016-01-13,2015-01-26
-8af3,2023-08-16,2022-07-15
-2af6,2005-10-04,2005-07-25
-7afw,2020-12-16,2020-09-21
-6afl,2018-08-29,2018-08-08
-6aft,2019-04-10,2018-08-08
-4af6,2012-05-30,2012-01-18
-5afk,2015-05-06,2015-01-22
-1af7,1998-01-28,1997-03-22
-3af2,2010-05-26,2010-02-22
-3afr,2010-03-31,2010-03-10
-1af0,1998-03-25,1997-03-20
-1afb,1996-04-03,1995-11-03
-5afl,2015-05-06,2015-01-22
-6af6,2018-09-05,2018-08-08
-5af9,2015-08-26,2015-01-20
-4afb,2012-10-17,2012-01-18
-4af5,2013-01-23,2012-01-17
-1xku,2004-11-02,2004-09-29
-6xk9,2020-12-02,2020-06-25
-5xkd,2018-05-09,2017-05-07
-4xkg,2015-04-01,2015-01-11
-6xkp,2020-10-14,2020-06-26
-6xki,2021-01-06,2020-06-26
-5xk6,2018-01-17,2017-05-05
-2xkl,2010-10-13,2010-07-09
-1xkg,2005-06-28,2004-09-29
-2xko,2010-08-18,2010-07-11
-6xka,2020-08-05,2020-06-26
-6xk8,2021-06-30,2020-06-25
-2xkh,2010-12-08,2010-07-08
-1xk3,2004-11-09,2004-09-26
-7xkf,2022-08-10,2022-04-19
-6xkz,2020-12-30,2020-06-27
-5xkm,2017-08-16,2017-05-08
-5xkg,2018-04-18,2017-05-07
-2xkq,2010-11-24,2010-07-12
-1xk8,2004-10-19,2004-09-27
-5xki,2017-09-20,2017-05-07
-6xkm,2020-07-08,2020-06-26
-2xk1,2011-01-26,2010-07-07
-2xkw,2011-08-10,2010-07-14
-7xk2,2023-02-22,2022-04-19
-7xk9,2023-04-26,2022-04-19
-2xkk,2010-09-01,2010-07-08
-7xk3,2022-07-20,2022-04-19
-7xkj,2023-08-02,2022-04-19
-6xk2,2020-07-15,2020-06-25
-2xk7,2010-10-27,2010-07-07
-5xkb,2017-12-06,2017-05-06
-6xkd,2021-06-02,2020-06-26
-7xk4,2022-07-20,2022-04-19
-8xkl,2024-06-05,2023-12-23
-7xkw,2023-10-25,2022-04-20
-4xkx,2015-02-04,2015-01-12
-4xkv,2016-01-20,2015-01-12
-1xk4,2005-10-18,2004-09-26
-1xkq,2004-10-12,2004-09-29
-1xki,2004-10-19,2004-09-29
-5xky,2017-11-01,2017-05-10
-4xkc,2015-05-20,2015-01-11
-6xk4,2021-06-30,2020-06-25
-2xk8,2010-10-27,2010-07-07
-7xk5,2022-07-20,2022-04-19
-7xkr,2022-09-21,2022-04-20
-2xkb,2010-11-10,2010-07-07
-5xkp,2017-08-09,2017-05-08
-1xkk,2004-12-07,2004-09-29
-5xko,2017-08-09,2017-05-08
-1xkh,2005-03-15,2004-09-29
-7xke,2022-08-10,2022-04-19
-5xkh,2018-06-20,2017-05-07
-6xk5,2021-06-30,2020-06-25
-4xkq,2015-02-11,2015-01-12
-5xk8,2018-01-10,2017-05-05
-1xk2,2004-11-09,2004-09-26
-1xkb,1999-03-23,1998-03-19
-4xk4,2015-05-13,2015-01-09
-2xke,2010-11-03,2010-07-07
-7xkd,2022-08-10,2022-04-19
-4xkd,2015-04-01,2015-01-11
-2xkg,2010-12-08,2010-07-08
-5xku,2017-11-29,2017-05-09
-4xkj,2015-08-05,2015-01-12
-6xku,2020-12-30,2020-06-27
-5xk9,2018-01-10,2017-05-05
-5xkt,2017-12-13,2017-05-09
-1xka,1999-03-23,1998-03-19
-2xk4,2010-10-27,2010-07-07
-2xkd,2010-10-27,2010-07-07
-2xka,2010-11-10,2010-07-07
-2xk9,2011-07-20,2010-07-07
-2xk5,2010-08-25,2010-07-07
-4xkb,2015-05-20,2015-01-11
-1xk9,2005-05-17,2004-09-28
-1xkd,2005-10-04,2004-09-28
-4xkn,2015-02-11,2015-01-12
-4xkp,2015-02-11,2015-01-12
-2xkr,2010-09-29,2010-07-12
-2xkp,2010-08-18,2010-07-11
-2xkc,2010-10-27,2010-07-07
-1xkf,2005-10-11,2004-09-28
-5xkf,2018-04-18,2017-05-07
-4xkm,2015-12-23,2015-01-12
-1xky,2005-10-04,2004-09-30
-1xkl,2004-11-30,2004-09-29
-5xkq,2017-08-09,2017-05-09
-6xk7,2021-06-30,2020-06-25
-4xkw,2016-01-20,2015-01-12
-4xkl,2015-11-11,2015-01-12
-2xkf,2010-10-27,2010-07-07
-2xki,2010-12-08,2010-07-08
-4xk8,2015-06-10,2015-01-10
-4xkr,2015-02-11,2015-01-12
-1xk5,2005-06-07,2004-09-27
-7xkp,2022-09-21,2022-04-20
-8xkf,2024-04-10,2023-12-23
-6xkt,2020-12-30,2020-06-27
-1xkv,2005-10-11,2004-09-29
-1xkz,2004-11-30,2004-09-30
-5xkr,2017-08-09,2017-05-09
-5xkx,2017-11-01,2017-05-10
-1xkn,2004-11-16,2004-09-29
-5xk7,2018-01-10,2017-05-05
-7xka,2023-04-26,2022-04-19
-4xk9,2015-06-03,2015-01-10
-1xk0,2005-12-06,2004-09-26
-4xkf,2015-03-25,2015-01-11
-2xk6,2010-10-27,2010-07-07
-7xkq,2022-09-21,2022-04-20
-1xkx,2005-03-15,2004-09-30
-1xkw,2005-10-04,2004-09-30
-5xkv,2018-05-16,2017-05-09
-2xk3,2010-10-27,2010-07-07
-4xke,2015-04-01,2015-01-11
-6xk6,2021-06-30,2020-06-25
-7xkt,2023-03-22,2022-04-20
-6xkx,2020-12-30,2020-06-27
-6xkq,2020-10-14,2020-06-26
-4xk2,2015-01-21,2015-01-09
-4xk1,2015-02-04,2015-01-09
-6xkw,2020-12-30,2020-06-27
-2xk2,2010-09-01,2010-07-07
-7xk7,2022-07-20,2022-04-19
-6xk3,2021-06-30,2020-06-25
-6xkv,2020-12-30,2020-06-27
-7xk6,2022-07-20,2022-04-19
-5xke,2018-07-04,2017-05-07
-7xks,2023-03-29,2022-04-20
-6xk0,2020-07-15,2020-06-24
-5xkw,2018-05-16,2017-05-09
-4xky,2015-04-01,2015-01-12
-6xkl,2020-07-15,2020-06-26
-1xk1,2005-12-13,2004-09-26
-6nz0,2019-06-12,2019-02-12
-1nzz,2003-06-24,2003-02-20
-7nzo,2021-10-13,2021-03-24
-7nzj,2021-09-15,2021-03-24
-2nzf,2007-05-29,2006-11-23
-4nzg,2014-02-05,2013-12-12
-1nzq,2003-10-14,2003-02-19
-2nz6,2006-12-12,2006-11-22
-7nzi,2021-09-15,2021-03-24
-6nzv,2019-07-10,2019-02-14
-1nzj,2004-04-13,2003-02-18
-6nzu,2019-05-22,2019-02-14
-4nzf,2014-12-03,2013-12-12
-3nz0,2010-10-20,2010-07-15
-4nzb,2014-07-09,2013-12-11
-4nzh,2015-03-04,2013-12-12
-7nzg,2021-06-09,2021-03-24
-6nzt,2019-07-10,2019-02-14
-2nzd,2007-04-10,2006-11-23
-6nz8,2020-02-19,2019-02-13
-4nzq,2014-05-21,2013-12-12
-3nzg,2010-08-11,2010-07-16
-2nzv,2007-05-01,2006-11-25
-1nza,2003-03-11,2003-02-17
-6nzw,2019-02-27,2019-02-14
-3nzx,2011-02-16,2010-07-17
-7nz7,2021-05-05,2021-03-23
-5nzx,2017-06-14,2017-05-15
-7nzw,2022-04-13,2021-03-24
-2nzl,2006-12-12,2006-11-24
-3nzd,2010-12-29,2010-07-16
-7nzr,2022-04-13,2021-03-24
-4nz3,2014-08-13,2013-12-11
-7nzn,2022-02-09,2021-03-24
-7nzk,2021-06-09,2021-03-24
-1nzy,1997-07-07,1996-04-02
-6nzp,2019-07-31,2019-02-14
-7nzt,2022-04-13,2021-03-24
-5nzq,2017-06-14,2017-05-14
-4nz8,2013-12-25,2013-12-11
-1nzc,2003-06-24,2003-02-17
-5nz0,2018-05-30,2017-05-12
-4nz2,2014-08-13,2013-12-11
-6nz5,2019-09-18,2019-02-12
-4nzw,2014-12-03,2013-12-13
-3nz4,2011-03-23,2010-07-16
-4nzn,2014-04-02,2013-12-12
-3nz6,2010-12-29,2010-07-16
-4nzl,2014-08-20,2013-12-12
-3nzw,2011-02-16,2010-07-17
-2nz2,2006-12-05,2006-11-22
-7nza,2021-07-07,2021-03-23
-6nz7,2019-05-08,2019-02-13
-7nz8,2021-05-05,2021-03-23
-1nz4,2003-04-08,2003-02-15
-7nzy,2022-10-05,2021-03-24
-1nze,2003-08-26,2003-02-17
-1nzv,2003-04-22,2003-02-19
-6nze,2019-07-24,2019-02-13
-3nzb,2010-12-29,2010-07-16
-5nzw,2017-06-14,2017-05-15
-1nzw,2003-06-24,2003-02-20
-5nzy,2017-06-14,2017-05-15
-5nzf,2018-07-04,2017-05-14
-7nz6,2021-06-09,2021-03-23
-5nz4,2018-07-04,2017-05-12
-1nzb,2003-09-16,2003-02-17
-7nz9,2021-05-05,2021-03-23
-7nzs,2022-04-13,2021-03-24
-5nzo,2017-06-14,2017-05-14
-7nzx,2022-04-13,2021-03-24
-1nzf,2003-09-09,2003-02-17
-6nzl,2020-10-14,2019-02-14
-6nzo,2019-08-28,2019-02-14
-4nz5,2014-11-26,2013-12-11
-3nzk,2011-01-05,2010-07-16
-2nzj,2006-12-12,2006-11-23
-3nzi,2011-02-23,2010-07-16
-7nzm,2021-09-29,2021-03-24
-5nzj,2018-04-18,2017-05-14
-7nze,2022-06-08,2021-03-24
-6nzh,2019-07-24,2019-02-13
-6nzr,2019-07-31,2019-02-14
-6nzd,2019-11-06,2019-02-13
-3nzp,2010-09-01,2010-07-16
-6nzq,2019-07-31,2019-02-14
-4nz6,2014-05-21,2013-12-11
-2nzy,2007-01-23,2006-11-27
-5nzk,2018-04-18,2017-05-14
-7nz2,2021-07-07,2021-03-23
-5nz2,2017-09-20,2017-05-12
-5nzm,2018-04-18,2017-05-14
-7nz0,2021-07-07,2021-03-23
-1nz2,2003-04-08,2003-02-15
-5nzz,2018-05-30,2017-05-15
-2nzx,2007-01-23,2006-11-27
-3nzj,2011-02-16,2010-07-16
-1nzl,2003-04-22,2003-02-18
-6nzi,2019-02-27,2019-02-13
-6nz6,2019-09-18,2019-02-12
-6nzz,2019-02-27,2019-02-14
-2nze,2007-05-29,2006-11-23
-2nz9,2006-12-26,2006-11-22
-6nzx,2019-03-06,2019-02-14
-7nzf,2022-05-11,2021-03-24
-4nz9,2014-12-31,2013-12-11
-7nzq,2021-10-13,2021-03-24
-3nzu,2010-12-29,2010-07-16
-5nzn,2018-07-04,2017-05-14
-7nzh,2022-05-11,2021-03-24
-1nzr,1995-02-27,1994-12-09
-1nzd,2003-09-09,2003-02-17
-2nz5,2007-07-03,2006-11-22
-3nzt,2010-07-28,2010-07-16
-5nz8,2017-08-09,2017-05-12
-4nzm,2014-04-02,2013-12-12
-3nzz,2010-11-17,2010-07-18
-2nz0,2006-12-26,2006-11-22
-7nz1,2021-08-18,2021-03-23
-4nzv,2014-01-08,2013-12-12
-3nzs,2010-12-29,2010-07-16
-5nzp,2017-06-14,2017-05-14
-7nzu,2022-04-13,2021-03-24
-7nz4,2021-07-07,2021-03-23
-6nzm,2019-06-12,2019-02-14
-1nz7,2003-05-20,2003-02-16
-3nz1,2011-06-29,2010-07-15
-7nz3,2021-07-07,2021-03-23
-2nzu,2007-05-01,2006-11-25
-4nzo,2014-04-02,2013-12-12
-4nzi,2014-06-18,2013-12-12
-3nzr,2010-09-08,2010-07-16
-3nzh,2011-07-27,2010-07-16
-6nz4,2019-09-18,2019-02-12
-6nzf,2019-07-24,2019-02-13
-2nzm,2007-11-20,2006-11-24
-3nze,2010-08-11,2010-07-16
-7nzp,2021-10-13,2021-03-24
-5nzl,2018-04-18,2017-05-14
-1nz5,2003-04-08,2003-02-15
-2nza,2007-07-03,2006-11-22
-4nz4,2014-08-13,2013-12-11
-6nzy,2019-12-18,2019-02-14
-3nza,2010-12-29,2010-07-16
-1nzi,2003-06-10,2003-02-18
-4nzd,2014-12-17,2013-12-12
-5nzi,2018-04-18,2017-05-14
-3nz9,2010-12-29,2010-07-16
-7nzv,2021-06-09,2021-03-24
-6nzk,2019-06-05,2019-02-13
-3nz2,2010-08-04,2010-07-15
-6nzg,2019-12-18,2019-02-13
-4nz1,2014-08-13,2013-12-11
-1nz3,2003-04-08,2003-02-15
-5nze,2018-07-04,2017-05-13
-5nz1,2018-05-30,2017-05-12
-1nzx,2003-06-24,2003-02-20
-5nzg,2018-04-18,2017-05-14
-7nz5,2022-04-13,2021-03-23
-6ktk,2019-12-25,2019-08-28
-1kti,2002-01-30,2002-01-16
-5kti,2016-08-31,2016-07-11
-3ktq,1999-01-13,1998-07-28
-7ktk,2022-05-11,2020-11-24
-5kt2,2016-08-31,2016-07-11
-5kt5,2016-08-31,2016-07-11
-1ktt,2002-02-06,2002-01-17
-1ktp,2002-03-06,2002-01-17
-3kt0,2010-02-16,2009-11-24
-4ktn,2014-01-15,2013-05-20
-3kt4,2010-01-19,2009-11-24
-2kt4,2010-09-08,2010-01-18
-4ktk,2013-07-03,2013-05-20
-5kts,2016-07-27,2016-07-12
-3ktv,2010-02-16,2009-11-26
-4ktt,2014-07-16,2013-05-21
-7ktn,2021-12-15,2020-11-24
-4ktx,2014-10-15,2013-05-21
-3ktj,2010-03-23,2009-11-25
-1kt3,2003-06-03,2002-01-15
-3ktx,2010-02-09,2009-11-26
-1kta,2002-11-20,2002-01-15
-7ktg,2021-12-15,2020-11-24
-3ktm,2010-02-23,2009-11-25
-6ktq,2020-09-02,2019-08-28
-7kta,2021-12-15,2020-11-24
-1ktr,2002-05-15,2002-01-17
-7kt3,2021-12-15,2020-11-24
-6ktr,2020-07-08,2019-08-28
-3ktn,2009-12-15,2009-11-25
-5kt4,2016-08-31,2016-07-11
-4kt1,2013-06-19,2013-05-19
-3ktw,2010-02-16,2009-11-26
-5kt7,2016-08-31,2016-07-11
-1kt8,2002-11-20,2002-01-15
-4kt7,2013-06-05,2013-05-20
-4ktc,2013-08-07,2013-05-20
-4kts,2014-04-02,2013-05-21
-7kt5,2021-12-15,2020-11-24
-7kt0,2022-01-19,2020-11-24
-7ktc,2022-05-11,2020-11-24
-4ktz,2013-08-14,2013-05-21
-1ktg,2002-05-08,2002-01-16
-7ktp,2021-02-03,2020-11-24
-7ktd,2022-05-11,2020-11-24
-5kto,2016-07-27,2016-07-12
-3kt7,2010-01-19,2009-11-24
-1ktd,2002-05-01,2002-01-15
-4kt2,2014-05-21,2013-05-19
-3kti,2010-03-23,2009-11-25
-5ktx,2016-11-02,2016-07-12
-3ktb,2009-12-08,2009-11-24
-4ktb,2013-06-05,2013-05-20
-4kty,2013-12-04,2013-05-21
-5ktu,2016-11-02,2016-07-12
-5kt6,2016-08-31,2016-07-11
-5ktp,2016-07-27,2016-07-12
-1ktc,2002-03-15,2002-01-15
-6ktb,2019-12-04,2019-08-26
-1kt7,2003-06-03,2002-01-15
-4ktu,2014-04-02,2013-05-21
-5kth,2016-08-31,2016-07-11
-5ktk,2016-09-07,2016-07-11
-3kt1,2010-01-19,2009-11-24
-7ktf,2021-12-15,2020-11-24
-5kty,2016-09-21,2016-07-12
-5kt9,2017-07-12,2016-07-11
-3kt3,2010-02-16,2009-11-24
-4ktr,2014-05-21,2013-05-21
-7ktm,2022-05-11,2020-11-24
-4ktp,2014-05-21,2013-05-21
-1kt4,2003-06-03,2002-01-15
-6ktz,2020-08-26,2019-08-29
-3ktl,2009-12-22,2009-11-25
-3kta,2010-06-30,2009-11-24
-5ktc,2016-07-27,2016-07-11
-4ktf,2013-07-03,2013-05-20
-3ktr,2010-02-23,2009-11-25
-4kt8,2014-02-26,2013-05-20
-1kts,2002-02-06,2002-01-17
-6kth,2020-09-02,2019-08-28
-5ktw,2016-11-02,2016-07-12
-1ktl,2003-02-25,2002-01-16
-1ktw,2003-06-10,2002-01-18
-3ktc,2009-12-22,2009-11-24
-1ktb,2002-03-15,2002-01-15
-5kt1,2018-01-17,2016-07-11
-1kt6,2003-06-03,2002-01-15
-7ktb,2022-05-11,2020-11-24
-7kt7,2021-12-15,2020-11-24
-6ktl,2019-12-25,2019-08-28
-7ktj,2022-05-11,2020-11-24
-5kt8,2017-07-12,2016-07-11
-5kt3,2016-08-31,2016-07-11
-3kt6,2010-02-16,2009-11-24
-6ktx,2020-08-26,2019-08-29
-4ktv,2014-07-16,2013-05-21
-5ktd,2016-07-27,2016-07-11
-4kta,2013-06-12,2013-05-20
-4kth,2013-11-27,2013-05-20
-1kt5,2003-06-03,2002-01-15
-3kt8,2010-02-16,2009-11-24
-7ktx,2020-12-02,2020-11-24
-5ktl,2016-11-30,2016-07-11
-4kt0,2014-02-05,2013-05-19
-2ktq,1999-01-13,1998-07-30
-7kt1,2022-01-19,2020-11-24
-7kth,2022-05-11,2020-11-24
-7kti,2022-05-11,2020-11-24
-6ktc,2020-02-05,2019-08-27
-3ktu,2010-07-14,2009-11-26
-7kt9,2021-12-15,2020-11-24
-6ktv,2020-08-26,2019-08-29
-6ktn,2020-02-05,2019-08-28
-4kto,2013-06-19,2013-05-20
-7kt8,2021-12-15,2020-11-24
-7kt4,2021-12-15,2020-11-24
-7kto,2021-12-01,2020-11-24
-1kto,2003-01-17,2002-01-17
-2kt3,2010-09-22,2010-01-17
-3ktk,2010-03-23,2009-11-25
-2ktd,2011-02-02,2010-01-27
-6ktw,2020-08-26,2019-08-29
-5kte,2016-11-23,2016-07-11
-3ktz,2010-01-26,2009-11-26
-7kt6,2021-12-15,2020-11-24
-4ktl,2013-07-03,2013-05-20
-7kte,2021-12-15,2020-11-24
-7kt2,2022-01-19,2020-11-24
-1kt2,2002-05-01,2002-01-15
-4ktj,2013-07-03,2013-05-20
-7ktl,2022-05-11,2020-11-24
-5kt0,2016-09-07,2016-07-10
-5ktq,1998-09-30,1998-09-22
-3ql9,2011-06-15,2011-02-02
-6qlm,2020-02-19,2019-02-01
-3qlf,2012-02-08,2011-02-02
-1qlh,2000-01-02,1999-08-31
-6ql9,2020-03-18,2019-01-31
-6qli,2019-06-05,2019-02-01
-1qlt,1999-09-20,1999-09-16
-6qlh,2019-06-05,2019-02-01
-3qlq,2012-02-08,2011-02-03
-3qlz,2011-07-20,2011-02-03
-4qlq,2014-07-23,2014-06-13
-1ql4,2000-02-03,1999-08-20
-3qle,2011-03-02,2011-02-02
-1qlk,1998-11-11,1997-09-26
-7ql7,2022-11-23,2021-12-19
-6qlj,2019-06-05,2019-02-01
-8qlq,2023-11-08,2023-09-20
-4qlt,2014-07-23,2014-06-13
-6qlt,2019-07-10,2019-02-01
-2ql5,2007-08-28,2007-07-12
-1ql0,2000-05-07,1999-08-18
-8qlp,2024-01-31,2023-09-20
-6qll,2019-06-05,2019-02-01
-1ql9,2000-08-25,1999-08-24
-2qla,2007-11-06,2007-07-12
-1qlr,2000-09-14,1999-09-11
-2qll,2008-02-19,2007-07-13
-2qln,2008-07-15,2007-07-13
-6qlb,2020-02-05,2019-01-31
-3qln,2011-06-15,2011-02-03
-6qlg,2019-06-05,2019-02-01
-6ql6,2020-03-18,2019-01-31
-3qlt,2011-08-03,2011-02-03
-3qlr,2011-07-20,2011-02-03
-7qlh,2022-12-28,2021-12-20
-2qlu,2007-11-20,2007-07-13
-4qly,2015-02-25,2014-06-13
-4qlw,2014-08-13,2014-06-13
-3ql3,2011-04-27,2011-02-02
-8qlg,2024-05-22,2023-09-19
-4ql3,2015-06-10,2014-06-10
-4qlz,2015-07-15,2014-06-13
-1qll,2000-09-07,1999-09-01
-6ql5,2020-03-18,2019-01-31
-4qlx,2015-02-25,2014-06-13
-3qls,2011-07-20,2011-02-03
-7ql5,2022-02-09,2021-12-19
-3qly,2011-07-20,2011-02-03
-2qlx,2008-12-02,2007-07-13
-8qlk,2024-05-22,2023-09-20
-6qlw,2020-02-19,2019-02-01
-7qls,2022-12-28,2021-12-20
-7ql6,2022-02-09,2021-12-19
-1qls,2000-02-25,1999-09-15
-2qlt,2007-08-07,2007-07-13
-2qls,2008-07-22,2007-07-13
-1ql7,2000-08-25,1999-08-24
-6qls,2019-07-10,2019-02-01
-4ql5,2014-07-02,2014-06-10
-2ql9,2007-08-28,2007-07-12
-2qlm,2008-07-15,2007-07-13
-8qlt,2023-11-08,2023-09-20
-6qlr,2019-07-10,2019-02-01
-1qlu,1999-09-20,1999-09-16
-4qlj,2015-06-17,2014-06-12
-3qlg,2012-02-08,2011-02-02
-2qly,2008-01-08,2007-07-13
-2ql1,2008-04-01,2007-07-12
-2ql7,2007-08-28,2007-07-12
-6qln,2019-07-10,2019-02-01
-1qle,1999-12-02,1999-08-30
-3ql0,2011-04-20,2011-02-02
-2qlb,2007-08-28,2007-07-12
-4qlv,2014-07-23,2014-06-13
-6ql8,2020-02-19,2019-01-31
-4qli,2015-06-17,2014-06-12
-3qlj,2011-02-16,2011-02-02
-6qlp,2019-07-10,2019-02-01
-1ql3,2000-02-06,1999-08-20
-1ql6,1999-12-14,1999-08-24
-3qlw,2011-07-20,2011-02-03
-6qlx,2020-02-19,2019-02-01
-3qlx,2011-07-20,2011-02-03
-6ql3,2019-09-25,2019-01-31
-6qla,2019-12-25,2019-01-31
-8qls,2023-11-08,2023-09-20
-7ql8,2022-04-27,2021-12-19
-7qlr,2022-12-28,2021-12-20
-1qlj,2000-01-02,1999-09-01
-6ql0,2020-02-19,2019-01-31
-4qls,2014-07-23,2014-06-13
-3ql8,2012-08-08,2011-02-02
-1qlg,2000-02-03,1999-08-31
-7qlg,2022-12-28,2021-12-20
-8qlr,2023-11-08,2023-09-20
-1qlf,1999-09-01,1999-08-30
-3qlc,2011-06-15,2011-02-02
-1ql8,2000-08-25,1999-08-24
-3qla,2011-06-15,2011-02-02
-4qlu,2014-07-23,2014-06-13
-2qlj,2007-08-28,2007-07-12
-4qll,2015-06-17,2014-06-12
-8qlm,2024-05-22,2023-09-20
-4qlg,2014-11-26,2014-06-12
-2qlf,2007-08-28,2007-07-12
-6qlu,2019-07-10,2019-02-01
-8qlc,2024-05-22,2023-09-19
-8qlv,2024-05-22,2023-09-20
-6ql2,2019-09-25,2019-01-31
-2qlq,2008-03-11,2007-07-13
-4ql8,2015-06-17,2014-06-11
-7qlb,2023-03-29,2021-12-20
-2qlw,2008-11-04,2007-07-13
-4qlf,2014-11-26,2014-06-12
-7qlp,2022-07-13,2021-12-20
-3qlb,2011-12-07,2011-02-02
-6ql1,2019-09-25,2019-01-31
-6qlq,2019-07-10,2019-02-01
-3qlm,2011-04-06,2011-02-03
-4qlk,2015-06-17,2014-06-12
-3qlu,2011-08-03,2011-02-03
-3qlp,2011-10-19,2011-02-03
-1qli,1997-08-20,1997-02-17
-2ql6,2007-10-02,2007-07-12
-1qln,2000-02-04,1999-09-01
-6qlv,2019-06-05,2019-02-01
-7qlt,2022-08-17,2021-12-20
-7qld,2022-12-28,2021-12-20
-1qlb,1999-11-29,1999-08-25
-7qlq,2022-12-28,2021-12-20
-2ql0,2008-07-08,2007-07-12
-6qlo,2019-07-10,2019-02-01
-3qlh,2011-12-21,2011-02-02
-4qle,2014-11-26,2014-06-12
-6qlk,2019-06-05,2019-02-01
-7mfq,2021-04-28,2021-04-10
-7mft,2022-01-05,2021-04-11
-7mfo,2021-04-28,2021-04-10
-7mfz,2022-01-12,2021-04-12
-4mfg,2013-09-04,2013-08-27
-5mf1,2017-03-08,2016-11-17
-4mfa,2014-08-27,2013-08-27
-5mfn,2017-09-13,2016-11-18
-4mfz,2014-09-03,2013-08-28
-1mfu,2002-11-20,2002-08-13
-7mfx,2022-01-12,2021-04-11
-6mf2,2019-09-11,2018-09-08
-1mft,2004-01-20,2002-08-13
-2mfp,2013-11-27,2013-10-14
-2mf8,2013-11-06,2013-10-08
-1mfc,1994-01-31,1993-10-25
-6mf0,2019-09-11,2018-09-07
-3mfu,2010-04-28,2010-04-03
-1mfe,1994-01-31,1993-10-25
-5mfo,2017-09-13,2016-11-18
-6mfv,2019-02-20,2018-09-12
-5mfr,2017-04-19,2016-11-18
-5mfs,2017-04-19,2016-11-18
-5mf5,2016-12-21,2016-11-17
-4mfp,2014-09-03,2013-08-28
-5mfq,2017-04-12,2016-11-18
-5mfp,2016-12-28,2016-11-18
-2mfh,2014-02-26,2013-10-11
-7mfp,2021-04-28,2021-04-10
-1mfa,1994-01-31,1993-10-25
-1mfs,1998-06-17,1998-04-01
-1mfi,1999-06-22,1998-08-12
-3mfs,2010-04-28,2010-04-03
-4mfb,2013-11-06,2013-08-27
-6mff,2018-11-21,2018-09-10
-6mf6,2020-02-19,2018-09-09
-3mfw,2010-05-05,2010-04-04
-3mf2,2010-07-28,2010-04-01
-1mfl,2003-01-21,2002-08-12
-6mfm,2018-09-26,2018-09-11
-6mft,2018-11-14,2018-09-12
-3mfr,2010-04-28,2010-04-03
-6mfn,2019-08-07,2018-09-11
-1mfm,1999-04-21,1999-04-16
-7mfl,2021-07-28,2021-04-09
-1mfz,2003-05-06,2002-08-14
-6mfb,2019-09-18,2018-09-10
-4mf1,2013-11-13,2013-08-27
-1mfg,2003-01-21,2002-08-10
-1mf1,2002-10-30,2002-08-09
-1mfp,2003-05-06,2002-08-13
-6mfe,2018-10-03,2018-09-10
-7mfm,2022-01-05,2021-04-10
-3mfp,2010-09-29,2010-04-03
-5mfe,2017-09-13,2016-11-18
-6mfz,2019-11-20,2018-09-12
-4mfq,2014-09-03,2013-08-28
-7mf0,2021-05-19,2021-04-08
-3mfh,2010-06-23,2010-04-02
-4mf5,2013-09-04,2013-08-27
-5mfv,2017-04-12,2016-11-18
-5mfh,2017-09-13,2016-11-18
-4mfe,2013-11-13,2013-08-27
-7mfd,2022-01-26,2021-04-09
-5mfm,2017-09-13,2016-11-18
-1mf4,2003-09-30,2002-08-09
-5mf6,2016-12-28,2016-11-17
-5mfw,2017-04-12,2016-11-18
-6mfp,2019-09-18,2018-09-11
-4mf3,2014-05-07,2013-08-27
-3mf4,2010-04-14,2010-04-01
-7mfy,2022-01-12,2021-04-12
-6mfl,2018-11-21,2018-09-11
-5mfd,2017-07-19,2016-11-18
-1mf8,2002-10-16,2002-08-09
-6mfs,2018-09-26,2018-09-12
-7mf1,2021-05-12,2021-04-08
-1mf0,2002-10-30,2002-08-09
-3mff,2010-06-02,2010-04-02
-6mfy,2019-11-20,2018-09-12
-6mf5,2020-02-19,2018-09-09
-5mfl,2017-09-13,2016-11-18
-6mf9,2018-10-10,2018-09-10
-4mfl,2014-09-03,2013-08-28
-7mfr,2021-06-16,2021-04-10
-7mfk,2021-07-28,2021-04-09
-6mfw,2019-11-20,2018-09-12
-1mfr,1999-06-22,1998-06-18
-3mfq,2011-04-13,2010-04-03
-3mfv,2010-05-05,2010-04-04
-1mfb,1994-01-31,1993-10-25
-5mfk,2017-09-13,2016-11-18
-7mfj,2021-11-24,2021-04-09
-5mf0,2017-11-15,2016-11-16
-4mf2,2014-04-16,2013-08-27
-4mff,2014-04-16,2013-08-27
-4mfd,2013-11-13,2013-08-27
-5mf2,2017-09-20,2016-11-17
-6mfu,2018-09-26,2018-09-12
-7mff,2022-01-26,2021-04-09
-3mf1,2010-07-28,2010-04-01
-4mf9,2014-03-05,2013-08-27
-7mfh,2022-04-13,2021-04-09
-5mfu,2017-03-01,2016-11-18
-5mf7,2018-05-30,2016-11-17
-5mfa,2017-04-05,2016-11-17
-5mf4,2017-09-20,2016-11-17
-5mfx,2017-01-11,2016-11-18
-4mf8,2014-08-27,2013-08-27
-4mf0,2013-11-13,2013-08-27
-5mfj,2017-09-13,2016-11-18
-6mfg,2018-11-21,2018-09-10
-4mf6,2013-09-04,2013-08-27
-3mfj,2010-04-21,2010-04-02
-7mfs,2022-04-13,2021-04-11
-6mf4,2020-02-19,2018-09-09
-5mfg,2017-09-13,2016-11-18
-5mff,2017-09-13,2016-11-18
-1mfd,1994-01-31,1993-10-25
-5mfi,2017-09-13,2016-11-18
-7mf3,2022-01-05,2021-04-08
-7mfe,2022-01-26,2021-04-09
-3mf5,2010-07-28,2010-04-01
-4mfh,2014-01-15,2013-08-27
-6mfj,2019-09-25,2018-09-11
-5mft,2017-04-19,2016-11-18
-3mfi,2010-06-23,2010-04-02
-3mf3,2011-04-20,2010-04-01
-7mfg,2021-11-03,2021-04-09
-4mfk,2014-09-03,2013-08-28
-6mfx,2019-11-20,2018-09-12
-3mfl,2011-04-13,2010-04-02
-7mfi,2021-12-15,2021-04-09
-6mfi,2019-11-13,2018-09-11
-1mfv,2002-11-20,2002-08-13
-5mfz,2016-12-28,2016-11-19
-6mfd,2019-09-18,2018-09-10
-4mfc,2014-04-16,2013-08-27
-6mfo,2019-09-18,2018-09-11
-7mfc,2021-11-24,2021-04-08
-6oy0,2019-08-21,2019-05-14
-4oy2,2014-06-25,2014-02-10
-7oy7,2022-07-13,2021-06-23
-6oy3,2019-11-06,2019-05-14
-7oy0,2022-07-13,2021-06-23
-7oy1,2022-07-13,2021-06-23
-5oy2,2019-04-17,2017-09-07
-8oyc,2023-11-22,2023-05-03
-5oy5,2019-02-06,2017-09-07
-5oyn,2018-01-24,2017-09-11
-6oyz,2019-07-10,2019-05-15
-5oy6,2017-09-27,2017-09-07
-1oy9,2003-05-13,2003-04-03
-4oy6,2014-05-28,2014-02-11
-4oyo,2014-04-02,2014-02-12
-7oy3,2021-12-01,2021-06-23
-3oyt,2011-01-12,2010-09-23
-4oyf,2014-08-13,2014-02-11
-3oy7,2010-11-17,2010-09-23
-8oyy,2023-10-18,2023-05-05
-7oyd,2022-07-20,2021-06-24
-3oya,2010-10-20,2010-09-23
-1oyw,2003-10-07,2003-04-07
-8oyh,2024-03-13,2023-05-04
-3oys,2011-08-10,2010-09-23
-1oyl,2003-08-05,2003-04-05
-5oyd,2018-02-07,2017-09-08
-6oy2,2019-08-21,2019-05-14
-5oy0,2018-02-21,2017-09-07
-3oyq,2011-08-10,2010-09-23
-3oyi,2010-11-17,2010-09-23
-1oyb,1994-11-30,1994-08-25
-2oyt,2007-10-30,2007-02-22
-7oy2,2021-12-15,2021-06-23
-2oy2,2007-03-06,2007-02-21
-1oy0,2003-07-15,2003-04-03
-1oyg,2003-10-14,2003-04-04
-2oy9,2007-03-20,2007-02-21
-6oy1,2019-08-21,2019-05-14
-5oy9,2018-03-21,2017-09-08
-3oy8,2010-11-03,2010-09-23
-2oy0,2007-04-03,2007-02-21
-5oy4,2017-11-01,2017-09-07
-3oyo,2011-02-09,2010-09-23
-1oyd,2003-05-13,2003-04-03
-4oy8,2014-05-28,2014-02-11
-3oyh,2010-11-17,2010-09-23
-2oyy,2007-04-10,2007-02-23
-4oyt,2014-12-10,2014-02-13
-7oyh,2021-12-01,2021-06-24
-8oy8,2023-11-22,2023-05-03
-2oyi,2007-05-15,2007-02-22
-7oyq,2023-01-18,2021-06-24
-4oyn,2015-09-09,2014-02-12
-6oyw,2019-11-27,2019-05-15
-2oys,2007-03-06,2007-02-22
-7oyj,2022-05-25,2021-06-24
-8oyu,2024-05-15,2023-05-05
-4oyi,2014-04-02,2014-02-12
-6oyt,2019-11-27,2019-05-15
-1oye,2003-05-13,2003-04-03
-8oye,2023-07-12,2023-05-04
-8oyz,2024-05-15,2023-05-05
-3oy5,2011-08-10,2010-09-22
-1oyv,2003-07-15,2003-04-07
-7oy8,2021-09-22,2021-06-23
-3oyg,2010-11-17,2010-09-23
-4oyq,2014-03-05,2014-02-12
-7oya,2022-07-13,2021-06-24
-8oy9,2023-11-22,2023-05-03
-4oyr,2014-04-30,2014-02-13
-3oyz,2011-06-01,2010-09-24
-4oya,2014-04-02,2014-02-11
-8oyf,2023-07-12,2023-05-04
-8oy1,2024-05-15,2023-05-03
-7oyo,2023-01-18,2021-06-24
-8oyb,2023-11-22,2023-05-03
-2oy4,2007-03-06,2007-02-21
-8oya,2023-11-22,2023-05-03
-1oyq,2003-04-29,2003-04-07
-6oyy,2020-02-05,2019-05-15
-4oys,2014-10-22,2014-02-13
-7oy4,2021-09-01,2021-06-23
-1oyy,2003-10-07,2003-04-07
-2oyr,2007-03-06,2007-02-22
-7oy5,2022-03-02,2021-06-23
-3oyd,2010-11-17,2010-09-23
-1oyh,2004-04-13,2003-04-04
-8oy3,2023-11-22,2023-05-03
-8oy5,2023-11-22,2023-05-03
-7oyf,2021-12-01,2021-06-24
-6oy9,2019-07-24,2019-05-14
-3oye,2010-11-17,2010-09-23
-3oyw,2010-11-03,2010-09-23
-1oy8,2003-05-13,2003-04-03
-2oyn,2007-03-06,2007-02-22
-5oyb,2017-12-20,2017-09-08
-3oy3,2010-12-15,2010-09-22
-7oyc,2022-07-20,2021-06-24
-6oyv,2020-03-18,2019-05-15
-4oyx,2014-04-02,2014-02-13
-2oyc,2007-03-13,2007-02-21
-3oy1,2011-08-17,2010-09-22
-7oyk,2021-11-10,2021-06-24
-3oy9,2010-10-20,2010-09-23
-6oyd,2020-05-20,2019-05-14
-3oyr,2010-10-13,2010-09-23
-7oyv,2021-12-01,2021-06-25
-7oye,2022-07-13,2021-06-24
-2oye,2007-07-24,2007-02-21
-7oyp,2023-01-18,2021-06-24
-8oy6,2023-11-22,2023-05-03
-3oyc,2010-11-17,2010-09-23
-3oyl,2010-11-17,2010-09-23
-8oyp,2023-10-18,2023-05-05
-4oym,2014-04-02,2014-02-12
-6oy7,2019-07-24,2019-05-14
-3oy0,2011-08-10,2010-09-22
-1oyr,2004-03-09,2003-04-07
-5oyl,2018-03-21,2017-09-11
-8oy4,2023-11-22,2023-05-03
-1oyf,2003-05-20,2003-04-04
-3oyj,2010-11-17,2010-09-23
-4oyv,2015-03-18,2014-02-13
-7oyn,2023-01-18,2021-06-24
-2oy3,2007-04-17,2007-02-21
-8oy0,2023-11-29,2023-05-03
-3oy4,2011-02-09,2010-09-22
-7oyl,2022-07-13,2021-06-24
-1oyk,2003-08-05,2003-04-04
-2oyf,2007-03-20,2007-02-22
-7oyr,2023-01-18,2021-06-24
-1oyc,1994-11-30,1994-08-25
-5oyh,2018-06-06,2017-09-09
-1oyn,2003-07-15,2003-04-05
-4oy9,2015-04-01,2014-02-11
-3oyb,2010-11-17,2010-09-23
-2oyk,2007-03-06,2007-02-22
-4oy3,2014-12-17,2014-02-10
-4oyb,2014-04-02,2014-02-11
-3oyx,2011-06-01,2010-09-24
-8oyw,2023-10-18,2023-05-05
-6oya,2019-07-24,2019-05-14
-7oyb,2022-07-13,2021-06-24
-1oyt,2003-06-24,2003-04-07
-5oy3,2017-09-20,2017-09-07
-1oyo,2003-05-20,2003-04-06
-8oyi,2023-11-08,2023-05-04
-8oyl,2023-10-18,2023-05-05
-7oy6,2022-03-02,2021-06-23
-3oyk,2010-11-17,2010-09-23
-6oyu,2020-03-18,2019-05-15
-7oyi,2022-07-06,2021-06-24
-1oyj,2003-07-01,2003-04-04
-5oyj,2018-03-14,2017-09-10
-6oy6,2019-06-19,2019-05-14
-7oyw,2021-12-01,2021-06-25
-5oy1,2018-10-10,2017-09-07
-6oyr,2020-05-20,2019-05-15
-8oy2,2023-11-29,2023-05-03
-3oyn,2010-11-17,2010-09-23
-6oy5,2019-06-05,2019-05-14
-3oyp,2010-12-01,2010-09-23
-2oyl,2007-03-06,2007-02-22
-2oym,2007-03-06,2007-02-22
-2oyh,2007-05-15,2007-02-22
-5oye,2018-02-07,2017-09-08
-2oyu,2007-07-24,2007-02-23
-2oyq,2007-10-23,2007-02-22
-4oyp,2014-04-02,2014-02-12
-3oyf,2010-11-17,2010-09-23
-1oya,1995-03-31,1994-08-25
-4oy7,2014-05-28,2014-02-11
-3oym,2010-11-17,2010-09-23
-5oya,2018-06-27,2017-09-08
-7oym,2023-01-18,2021-06-24
-7oyg,2021-08-25,2021-06-24
-3oy6,2011-08-10,2010-09-22
-8oyq,2024-05-15,2023-05-05
-8oy7,2023-11-22,2023-05-03
-1oy7,2003-08-26,2003-04-03
-7oyx,2021-12-01,2021-06-25
-5oyf,2018-02-28,2017-09-08
-8oyg,2023-07-12,2023-05-04
-35c8,1999-03-23,1998-03-18
-25c8,1999-03-23,1998-03-18
-7sc7,2022-08-31,2021-09-27
-3scy,2011-07-20,2011-06-08
-3sc0,2011-06-22,2011-06-06
-6sc5,2019-11-27,2019-07-23
-5sc2,2021-09-22,2021-09-14
-5scf,2022-03-16,2021-12-01
-6scx,2020-01-08,2019-07-25
-5sck,2022-03-16,2021-12-01
-5sc3,2021-09-22,2021-09-14
-6sc1,2020-08-26,2019-07-23
-6scd,2020-02-26,2019-07-24
-6sc7,2019-11-27,2019-07-23
-6scv,2020-08-26,2019-07-25
-1scm,1994-04-30,1994-01-06
-7sc8,2022-08-31,2021-09-27
-7scj,2022-09-28,2021-09-28
-7scc,2022-08-31,2021-09-27
-7sco,2022-08-24,2021-09-28
-7sc2,2021-12-01,2021-09-27
-5sc4,2021-09-22,2021-09-14
-5scb,2022-03-16,2021-12-01
-5sc7,2021-09-22,2021-09-14
-7sch,2022-09-28,2021-09-28
-7sc3,2021-12-01,2021-09-27
-5sco,2022-02-09,2021-12-20
-7sc5,2022-11-09,2021-09-27
-8scz,2024-03-13,2023-04-06
-1scu,1995-04-20,1993-11-18
-6sc2,2019-09-04,2019-07-23
-5scy,2022-02-09,2021-12-20
-7sc1,2022-02-02,2021-09-26
-5scj,2022-03-16,2021-12-01
-5scd,2022-03-16,2021-12-01
-8scg,2023-10-25,2023-04-05
-1sc6,2005-02-22,2004-02-11
-1sch,1996-07-11,1996-01-23
-5sc5,2021-09-22,2021-09-14
-5scx,2022-02-09,2021-12-20
-8scs,2023-10-25,2023-04-05
-7scf,2021-12-01,2021-09-28
-1scs,1994-05-31,1993-12-06
-8sc3,2023-10-18,2023-04-04
-7scg,2022-04-20,2021-09-28
-1scq,2004-06-29,2004-02-12
-7sck,2022-09-28,2021-09-28
-3sc2,1993-10-31,1992-07-01
-7sc9,2022-08-31,2021-09-27
-5scw,2022-02-09,2021-12-20
-5scm,2022-02-09,2021-12-20
-2scp,1993-10-31,1991-08-22
-6sc6,2019-11-27,2019-07-23
-8sc2,2023-10-18,2023-04-04
-5sc1,2021-09-22,2021-09-14
-5sc8,2022-03-16,2021-12-01
-5scs,2022-02-09,2021-12-20
-3scq,2012-06-13,2011-06-08
-3sc1,2011-10-26,2011-06-06
-3sc7,2012-06-27,2011-06-07
-3sch,2011-07-06,2011-06-07
-3sck,2012-02-08,2011-06-07
-8sct,2023-10-25,2023-04-05
-7scr,2022-03-02,2021-09-29
-8sc4,2023-10-18,2023-04-04
-8scj,2023-10-25,2023-04-05
-5sch,2022-03-16,2021-12-01
-3scu,2012-02-15,2011-06-08
-6scb,2020-09-09,2019-07-24
-6scg,2020-08-26,2019-07-24
-7sca,2022-08-31,2021-09-27
-3scl,2012-02-08,2011-06-07
-1scn,1994-08-31,1994-03-02
-6scf,2019-10-30,2019-07-24
-5scp,2022-02-09,2021-12-20
-3scw,2012-02-15,2011-06-08
-3scs,2012-06-13,2011-06-08
-8sc0,2023-04-12,2023-04-04
-6sc4,2020-04-22,2019-07-23
-1sc7,2005-04-19,2004-02-11
-5sc6,2021-09-22,2021-09-14
-3scp,2012-06-13,2011-06-08
-3sct,2012-02-15,2011-06-08
-6scy,2020-08-26,2019-07-25
-6sc0,2020-08-26,2019-07-23
-6sch,2020-08-26,2019-07-24
-8scq,2023-10-25,2023-04-05
-7scw,2022-05-18,2021-09-29
-3scf,2011-07-06,2011-06-07
-3scz,2012-06-20,2011-06-08
-5scc,2022-03-16,2021-12-01
-8scl,2023-10-25,2023-04-05
-7scb,2022-08-31,2021-09-27
-1sca,1994-01-31,1993-07-19
-2scu,1999-08-02,1998-09-24
-1scw,2004-06-22,2004-02-12
-8sci,2023-10-25,2023-04-05
-3scm,2011-10-05,2011-06-08
-5scz,2022-02-09,2021-12-20
-3scx,2011-10-12,2011-06-08
-3sci,2012-02-08,2011-06-07
-7scx,2022-05-18,2021-09-29
-1scr,1994-05-31,1993-12-06
-5scg,2022-03-16,2021-12-01
-6sck,2020-08-26,2019-07-24
-3scn,2012-02-15,2011-06-08
-1sc8,2004-06-22,2004-02-12
-6scm,2020-08-26,2019-07-24
-1scb,1994-01-31,1993-07-13
-5sct,2022-02-09,2021-12-20
-1scf,2000-07-07,1998-06-04
-7sci,2022-04-27,2021-09-28
-5scn,2022-02-09,2021-12-20
-8scm,2023-10-25,2023-04-05
-6scp,2020-03-11,2019-07-25
-8sco,2023-10-25,2023-04-05
-6scz,2020-04-01,2019-07-26
-3scr,2012-06-13,2011-06-08
-5scl,2022-03-16,2021-12-01
-3sc6,2011-06-22,2011-06-07
-5scq,2022-02-09,2021-12-20
-8scb,2023-12-27,2023-04-05
-1scv,2004-11-23,2004-02-12
-5sci,2022-03-16,2021-12-01
-6sc9,2019-11-27,2019-07-23
-3sco,2012-02-15,2011-06-08
-6sci,2020-08-26,2019-07-24
-8scr,2023-10-25,2023-04-05
-5sc9,2022-03-16,2021-12-01
-5scv,2022-02-09,2021-12-20
-7scn,2022-08-24,2021-09-28
-5sc0,2021-09-22,2021-09-14
-3scv,2012-02-15,2011-06-08
-8scd,2023-05-03,2023-04-05
-6scj,2020-02-12,2019-07-24
-3sce,2011-07-06,2011-06-07
-6sc8,2019-11-27,2019-07-23
-5scu,2022-02-09,2021-12-20
-6scu,2020-08-26,2019-07-25
-8sck,2023-10-25,2023-04-05
-1scd,1994-01-31,1993-08-23
-6sce,2020-02-19,2019-07-24
-3scg,2011-07-06,2011-06-07
-7scp,2022-03-23,2021-09-28
-8sc6,2023-10-18,2023-04-04
-1sc9,2004-06-29,2004-02-12
-3scj,2012-02-08,2011-06-07
-5sce,2022-03-16,2021-12-01
-8scu,2023-10-25,2023-04-05
-6scs,2020-03-11,2019-07-25
-8scn,2023-10-25,2023-04-05
-5sca,2022-03-16,2021-12-01
-7scm,2022-10-05,2021-09-28
-1scj,1998-12-09,1998-04-29
-6sc3,2020-08-26,2019-07-23
-5scr,2022-02-09,2021-12-20
-8scp,2023-10-25,2023-04-05
-1vmh,2004-10-05,2004-09-24
-2vme,2008-07-01,2008-01-25
-5vm2,2017-06-07,2017-04-26
-7vms,2022-08-10,2021-10-09
-3vmp,2012-02-15,2011-12-14
-5vmy,2018-04-04,2017-04-28
-2vmf,2008-04-01,2008-01-25
-3vmw,2012-07-25,2011-12-17
-2vmq,2008-12-16,2008-01-29
-2vm4,2008-02-05,2008-01-22
-7vm7,2022-11-23,2021-10-07
-7vmj,2022-10-19,2021-10-08
-5vmp,2017-09-27,2017-04-28
-7vml,2022-08-10,2021-10-09
-1vm9,2004-09-21,2004-09-13
-5vm5,2017-05-24,2017-04-26
-2vm0,2008-01-29,2008-01-20
-3vmg,2012-08-22,2011-12-12
-1vmf,2004-10-05,2004-09-23
-2vmt,2008-12-16,2008-01-29
-5vml,2017-05-24,2017-04-27
-3vma,2012-03-14,2011-12-09
-5vmz,2018-04-04,2017-04-28
-5vmc,2017-11-08,2017-04-27
-7vmw,2022-08-03,2021-10-09
-2vmh,2008-02-19,2008-01-25
-2vms,2008-12-16,2008-01-29
-6vm8,2020-11-25,2020-01-27
-2vm3,2008-02-05,2008-01-22
-3vm4,2012-05-09,2011-12-08
-2vm5,2008-01-29,2008-01-23
-7vmr,2022-08-10,2021-10-09
-6vm2,2020-07-29,2020-01-27
-2vmj,2008-12-23,2008-01-28
-6vms,2020-06-17,2020-01-28
-7vme,2022-10-12,2021-10-08
-7vmg,2022-10-19,2021-10-08
-5vme,2017-08-30,2017-04-27
-3vmt,2012-04-18,2011-12-15
-3vmr,2012-04-18,2011-12-15
-2vmu,2008-12-16,2008-01-29
-1vma,2004-09-28,2004-09-15
-6vm7,2021-01-20,2020-01-27
-2vma,2009-02-10,2008-01-25
-7vmn,2022-08-10,2021-10-09
-5vmm,2017-11-15,2017-04-27
-3vml,2012-12-26,2011-12-13
-6vm9,2021-01-20,2020-01-27
-3vmq,2012-04-18,2011-12-15
-7vm5,2022-10-12,2021-10-07
-6vmw,2020-04-08,2020-01-28
-1vm6,2004-09-21,2004-09-03
-1vmj,2004-10-12,2004-09-30
-5vmj,2017-11-08,2017-04-27
-6vmf,2020-04-08,2020-01-27
-6vmv,2020-04-08,2020-01-28
-7vmo,2022-08-10,2021-10-09
-6vma,2021-01-20,2020-01-27
-2vm9,2008-07-01,2008-01-24
-3vm7,2013-05-29,2011-12-09
-5vmt,2017-05-10,2017-04-28
-2vmp,2008-12-16,2008-01-29
-6vmd,2020-09-09,2020-01-27
-6vm3,2020-07-29,2020-01-27
-2vmb,2009-02-10,2008-01-25
-6vmb,2020-09-09,2020-01-27
-6vm5,2020-06-17,2020-01-27
-2vmz,2008-12-16,2008-01-29
-2vmc,2008-07-01,2008-01-25
-2vmy,2008-12-16,2008-01-29
-3vmf,2012-07-25,2011-12-12
-7vmq,2022-08-10,2021-10-09
-3vmj,2012-02-29,2011-12-13
-3vm1,2012-09-26,2011-12-05
-7vm4,2022-10-12,2021-10-07
-5vms,2017-06-07,2017-04-28
-7vmk,2022-10-19,2021-10-08
-5vmf,2017-11-08,2017-04-27
-6vmz,2020-07-01,2020-01-28
-7vm6,2022-10-12,2021-10-07
-3vmh,2012-08-22,2011-12-12
-3vm5,2012-06-06,2011-12-08
-3vmm,2012-04-11,2011-12-14
-2vmr,2008-12-16,2008-01-29
-6vm6,2020-06-17,2020-01-27
-7vmp,2022-08-10,2021-10-09
-2vmd,2008-07-01,2008-01-25
-7vm0,2022-10-12,2021-10-06
-2vmn,2008-12-16,2008-01-29
-3vm8,2012-10-03,2011-12-09
-2vmv,2008-12-16,2008-01-29
-6vm0,2020-07-29,2020-01-27
-2vmg,2008-02-19,2008-01-25
-5vm8,2017-05-10,2017-04-26
-3vm6,2012-04-25,2011-12-08
-6vmc,2021-01-20,2020-01-27
-6vmi,2020-08-05,2020-01-28
-3vmi,2012-08-22,2011-12-12
-2vmx,2008-12-16,2008-01-29
-3vmk,2012-02-29,2011-12-13
-7vmd,2022-08-24,2021-10-08
-3vm9,2012-09-12,2011-12-09
-1vmg,2004-10-05,2004-09-24
-7vmm,2022-08-10,2021-10-09
-5vm0,2018-05-02,2017-04-26
-3vmo,2012-02-15,2011-12-14
-2vm8,2008-08-26,2008-01-24
-5vmd,2017-07-12,2017-04-27
-1vm1,2004-09-07,2004-08-27
-5vmw,2018-04-04,2017-04-28
-3vm0,2012-09-26,2011-12-05
-5vm6,2018-05-02,2017-04-26
-2vmk,2008-07-22,2008-01-28
-5vmv,2018-04-04,2017-04-28
-2vmw,2008-12-16,2008-01-29
-2vmo,2008-12-16,2008-01-29
-5vmq,2017-05-24,2017-04-28
-6vmx,2020-07-29,2020-01-28
-2vmi,2008-02-19,2008-01-25
-5vmg,2017-11-08,2017-04-27
-2vml,2008-03-25,2008-01-28
-5vma,2018-10-31,2017-04-27
-1vm0,2004-08-31,2004-08-24
-5vmu,2018-04-04,2017-04-28
-1vmk,2004-10-12,2004-09-30
-7vmy,2022-08-03,2021-10-09
-7vm1,2022-08-17,2021-10-06
-7vmx,2022-10-12,2021-10-09
-5vmx,2018-04-04,2017-04-28
-8vm2,2024-05-01,2024-01-12
-7vmf,2022-09-21,2021-10-08
-2ic5,2006-10-10,2006-09-12
-4icl,2013-02-06,2012-12-10
-1icv,2001-04-18,2001-04-02
-1ict,2002-04-03,2001-04-02
-3ici,2010-07-21,2009-07-17
-6ict,2019-02-27,2018-09-07
-4ics,2013-10-23,2012-12-11
-6icm,2019-09-04,2018-09-06
-2icq,2007-02-13,2006-09-13
-9icl,1996-11-15,1996-01-04
-6icz,2019-03-13,2018-09-07
-8icb,1996-11-15,1996-04-19
-2ica,2006-12-19,2006-09-12
-5icc,2016-06-08,2016-02-23
-9icj,1996-11-15,1995-12-15
-9icf,1995-12-15,1995-12-15
-5icy,2016-06-15,2016-02-23
-2ick,2007-03-20,2006-09-12
-9ict,1996-11-15,1995-12-16
-3ick,2010-02-09,2009-07-17
-8ick,1996-11-15,1996-04-19
-4icq,2013-10-23,2012-12-11
-3ice,2009-11-10,2009-07-17
-2icf,2006-11-07,2006-09-12
-6icw,2019-11-27,2018-09-07
-2icv,2007-08-28,2006-09-13
-7icf,1996-11-15,1996-04-19
-6ic6,2019-04-24,2018-12-02
-6icy,2019-11-27,2018-09-07
-8icy,1995-12-15,1995-12-15
-9ics,1996-11-15,1995-12-16
-4ici,2013-01-02,2012-12-10
-3icf,2009-08-25,2009-07-17
-3ic0,2009-07-28,2009-07-17
-6icp,2019-09-04,2018-09-06
-5icl,2017-03-15,2016-02-23
-1icu,2001-04-18,2001-04-02
-2icj,2007-03-20,2006-09-12
-9icb,1995-12-15,1995-12-15
-6icj,2019-09-11,2018-09-06
-7ick,1996-04-19,1996-04-19
-7icg,1996-04-19,1996-04-19
-7icu,1996-11-15,1996-04-19
-1ic1,1998-06-17,1998-03-09
-5ic5,2016-03-02,2016-02-22
-6ico,2019-09-04,2018-09-06
-2icp,2006-09-26,2006-09-13
-3icw,2009-10-06,2009-07-18
-2icw,2007-03-20,2006-09-13
-8ica,1996-11-15,1995-12-15
-9icv,1996-11-15,1995-12-16
-9icr,1996-01-04,1996-01-04
-4icr,2013-10-23,2012-12-11
-4ic1,2013-01-16,2012-12-09
-9ici,1996-11-15,1995-12-15
-8icq,1996-11-15,1996-01-04
-7icn,1996-04-19,1996-04-19
-2ice,2006-11-07,2006-09-12
-8icf,1996-11-15,1996-04-19
-9ich,1996-11-15,1995-12-15
-3icm,2010-02-09,2009-07-17
-8icu,1996-11-15,1995-12-15
-8icz,1996-11-15,1996-01-04
-6icn,2019-09-04,2018-09-06
-5icf,2016-06-08,2016-02-23
-5icj,2017-04-26,2016-02-23
-3ic1,2009-09-22,2009-07-17
-1ics,2001-05-16,2001-04-02
-3icq,2009-08-25,2009-07-18
-7ice,1996-11-15,1996-04-19
-8icv,1996-11-15,1996-01-04
-8ich,1996-11-15,1996-04-19
-8icx,1996-11-15,1995-12-15
-7ici,1996-11-15,1996-04-19
-9icu,1996-11-15,1995-12-16
-5icg,2016-06-08,2016-02-23
-3icu,2009-09-29,2009-07-18
-9ico,1995-12-16,1995-12-16
-3icv,2009-10-06,2009-07-18
-4icb,1993-10-31,1991-08-27
-8ice,1996-11-15,1996-04-19
-3ic9,2009-07-28,2009-07-17
-5icu,2016-04-06,2016-02-23
-6ic0,2019-01-23,2018-12-01
-9icp,1996-11-15,1995-12-16
-6icv,2019-02-27,2018-09-07
-9icd,1991-10-15,1991-07-29
-4ick,2013-12-11,2012-12-10
-1icj,1999-03-23,1998-03-12
-8icp,1996-11-15,1995-12-15
-6icl,2019-09-04,2018-09-06
-5icp,2016-12-21,2016-02-23
-3icn,2010-02-09,2009-07-17
-8icl,1996-11-15,1995-12-15
-4ic3,2012-12-19,2012-12-09
-3icz,2010-02-09,2009-07-19
-1icp,2001-05-16,2001-04-02
-9icw,1996-11-15,1995-12-16
-5ick,2017-03-08,2016-02-23
-9ice,1996-11-15,1995-12-15
-7ict,1996-11-15,1996-04-19
-3icp,2010-07-21,2009-07-18
-5ic6,2016-07-20,2016-02-22
-1ici,2001-05-02,2001-04-01
-5ich,2017-03-15,2016-02-23
-5icr,2016-04-06,2016-02-23
-3icc,2009-07-28,2009-07-17
-6ic7,2019-04-24,2018-12-02
-1icr,2001-04-18,2001-04-02
-9icq,1996-11-15,1996-01-04
-5icd,1991-10-15,1990-05-30
-6ick,2019-09-04,2018-09-06
-6ic1,2019-12-18,2018-12-01
-3ics,2009-11-17,2009-07-18
-6ic2,2019-05-15,2018-12-01
-8icm,1996-11-15,1996-01-04
-6ic5,2019-04-24,2018-12-02
-6icq,2019-09-04,2018-09-06
-4icy,2013-06-12,2012-12-11
-8icn,1996-11-15,1995-12-15
-2ic1,2006-12-05,2006-09-12
-1ic6,2001-04-11,2001-03-30
-9icn,1995-12-16,1995-12-16
-6ica,2019-11-06,2018-09-05
-7ics,1996-04-19,1996-04-19
-3icr,2009-11-17,2009-07-18
-9icy,1996-11-15,1996-10-24
-2icx,2006-09-26,2006-09-13
-4icv,2014-06-18,2012-12-11
-8icg,1996-11-15,1996-04-19
-8icw,1996-11-15,1995-12-15
-4icm,2013-12-11,2012-12-10
-7icm,1996-11-15,1996-04-19
-2icy,2006-10-03,2006-09-13
-2ic3,2006-12-19,2006-09-12
-4ic0,2013-12-11,2012-12-09
-3icj,2009-07-28,2009-07-17
-8ic6,2023-08-16,2023-02-10
-8ici,1996-11-15,1996-04-19
-5icm,2016-07-13,2016-02-23
-3ic2,2009-07-28,2009-07-17
-8ict,1996-11-15,1995-12-15
-7icr,1996-11-15,1996-04-19
-5icn,2016-05-11,2016-02-23
-5icx,2016-06-15,2016-02-23
-8icr,1996-11-15,1996-01-04
-7ich,1996-04-19,1996-04-19
-8icd,1991-10-15,1990-05-30
-5icz,2016-06-15,2016-02-23
-9icm,1996-11-15,1995-12-16
-5icv,2016-06-22,2016-02-23
-9ica,1995-12-15,1995-12-15
-3icb,1986-10-24,1986-09-09
-9icc,1995-12-15,1995-12-15
-2ic0,2007-02-06,2006-09-12
-9icx,1996-11-15,1996-10-24
-2ics,2006-10-17,2006-09-13
-1icf,2000-01-12,1999-01-07
-9ick,1996-11-15,1995-12-16
-1ice,1995-07-28,1994-09-29
-5ice,2016-06-08,2016-02-23
-4icz,2013-12-11,2012-12-11
-4ic2,2012-12-19,2012-12-09
-2ici,2007-03-27,2006-09-12
-7icj,1996-11-15,1996-04-19
-7icq,1996-04-19,1996-04-19
-6icx,2019-11-27,2018-09-07
-1icq,2001-05-16,2001-04-02
-4ic7,2013-02-13,2012-12-10
-3ic4,2009-08-18,2009-07-17
-3ict,2009-11-17,2009-07-18
-6ici,2020-03-04,2018-09-06
-5ict,2016-12-21,2016-02-23
-4ict,2013-05-01,2012-12-11
-4icc,2014-02-19,2012-12-10
-5ic4,2016-07-20,2016-02-22
-7icv,1996-11-15,1996-10-24
-8ico,1996-11-15,1995-12-15
-8ic1,2023-08-16,2023-02-10
-5ic3,2017-08-09,2016-02-22
-7ico,1996-04-19,1996-04-19
-8icj,1996-11-15,1996-04-19
-3ic3,2009-09-22,2009-07-17
-7icl,1996-11-15,1996-04-19
-5icw,2016-06-22,2016-02-23
-7icp,1996-11-15,1996-04-19
-9icg,1996-11-15,1995-12-15
-4ic5,2013-05-01,2012-12-10
-8icc,1996-11-15,1996-04-19
-8ics,1996-11-15,1995-12-15
-8ic7,2023-08-16,2023-02-11
-1ic0,2001-06-06,2001-03-29
-1icc,2001-09-19,2001-03-30
-2bfd,2006-02-16,2004-12-06
-1bfn,1998-10-28,1998-05-22
-4bfg,2013-05-01,2013-03-18
-2bfo,2005-08-31,2004-12-10
-1bf2,1998-08-12,1998-05-26
-4bfe,2013-05-01,2013-03-18
-4bf5,2014-01-15,2013-03-15
-3bfb,2008-06-10,2007-11-21
-8bft,2023-02-22,2022-10-26
-7bf5,2021-01-13,2020-12-31
-7bfb,2021-03-03,2021-01-02
-4bfx,2013-05-15,2013-03-22
-2bfc,2006-02-16,2004-12-06
-6bfw,2017-11-15,2017-10-27
-8bfc,2023-03-29,2022-10-24
-2bfb,2006-02-16,2004-12-06
-6bff,2017-11-08,2017-10-26
-6bfu,2017-11-22,2017-10-27
-6bfh,2017-11-08,2017-10-26
-6bfg,2018-08-15,2017-10-26
-3bff,2007-12-18,2007-11-21
-4bfu,2013-05-15,2013-03-22
-8bfy,2023-02-01,2022-10-27
-1bfu,1998-10-28,1998-05-22
-4bf6,2014-01-22,2013-03-15
-3bfx,2007-12-04,2007-11-23
-8bfd,2022-11-23,2022-10-25
-7bfm,2022-01-12,2021-01-04
-1bfy,1999-05-25,1998-05-23
-3bfq,2008-03-04,2007-11-23
-6bf4,2018-03-07,2017-10-25
-7bf2,2021-07-21,2020-12-31
-2bfk,2005-03-31,2004-12-07
-8bf3,2022-11-30,2022-10-23
-2bfg,2005-10-12,2004-12-07
-2bfe,2006-02-16,2004-12-06
-7bf0,2021-07-14,2020-12-30
-4bfa,2013-11-06,2013-03-16
-2bfn,2006-06-26,2004-12-09
-3bfr,2008-12-09,2007-11-23
-3bfw,2008-03-04,2007-11-23
-1bfk,1998-10-28,1998-05-21
-8bf2,2023-03-08,2022-10-23
-1bf4,1999-11-10,1998-05-27
-4bf9,2013-11-06,2013-03-16
-6bfp,2018-10-31,2017-10-26
-4bf7,2013-08-07,2013-03-15
-2bfz,2005-03-31,2004-12-16
-6bfy,2018-10-31,2017-10-27
-3bfk,2007-12-04,2007-11-21
-2bf9,2004-12-08,2004-12-06
-2bfa,2005-08-31,2004-12-06
-4bfr,2014-01-15,2013-03-22
-7bf3,2021-01-13,2020-12-31
-3bfi,2008-12-02,2007-11-21
-3bft,2008-10-28,2007-11-23
-7bf1,2021-07-21,2020-12-31
-7bf4,2021-01-13,2020-12-31
-2bf6,2006-03-09,2004-12-04
-1bfv,1997-12-03,1997-05-27
-2bff,2006-02-16,2004-12-06
-7bf6,2021-01-13,2020-12-31
-1bf3,1998-08-12,1998-05-26
-3bfm,2007-12-04,2007-11-21
-1bfd,1998-06-24,1998-04-30
-8bff,2023-03-08,2022-10-25
-4bf4,2014-03-26,2013-03-14
-3bf1,2008-06-24,2007-11-20
-8bfw,2023-10-04,2022-10-27
-7bf8,2021-01-13,2021-01-01
-2bf1,2005-02-17,2004-12-02
-6bfk,2018-02-21,2017-10-26
-7bf9,2021-01-13,2021-01-01
-2bf0,2005-01-18,2004-12-02
-6bfl,2018-02-21,2017-10-26
-3bf3,2008-06-24,2007-11-20
-8bf6,2023-07-12,2022-10-24
-8bfn,2022-12-14,2022-10-26
-4bfn,2013-10-23,2013-03-21
-4bfy,2013-05-15,2013-03-22
-6bfj,2018-02-21,2017-10-26
-3bf6,2007-12-25,2007-11-20
-4bfw,2013-05-15,2013-03-22
-1bfx,1998-08-12,1998-05-23
-2bfp,2005-08-31,2004-12-10
-4bfi,2013-05-01,2013-03-19
-7bfv,2021-02-10,2021-01-04
-4bfl,2013-04-03,2013-03-19
-8bf4,2023-05-03,2022-10-24
-2bfl,2005-03-31,2004-12-08
-1bfr,1996-06-20,1994-12-16
-6bfa,2017-12-06,2017-10-26
-7bfw,2021-06-16,2021-01-05
-2bf7,2005-08-31,2004-12-06
-3bfv,2008-06-24,2007-11-23
-4bfd,2013-06-19,2013-03-18
-7bf7,2021-01-13,2021-01-01
-2bfm,2005-08-31,2004-12-09
-7bfa,2022-01-12,2021-01-02
-4bf1,2014-01-22,2013-03-13
-4bfz,2013-05-15,2013-03-22
-3bfa,2008-06-10,2007-11-21
-2bfv,1997-12-03,1997-05-27
-6bfo,2018-02-21,2017-10-26
-8bfm,2022-11-23,2022-10-26
-4bfs,2013-05-15,2013-03-22
-6bfn,2017-12-06,2017-10-26
-4bfv,2013-05-15,2013-03-22
-6bfv,2018-11-07,2017-10-27
-4bfo,2013-10-23,2013-03-21
-3bfg,2007-12-18,2007-11-21
-3bfu,2008-10-14,2007-11-23
-3bfc,2007-12-18,2007-11-21
-4bf2,2013-07-03,2013-03-13
-7bfz,2021-08-18,2021-01-05
-2bfr,2004-12-16,2004-12-10
-6bfd,2017-11-15,2017-10-26
-4bft,2013-05-15,2013-03-22
-1bf6,1999-06-08,1998-05-27
-6bfz,2018-10-31,2017-10-27
-1bfb,1996-04-03,1995-12-12
-2bf4,2006-01-17,2004-12-03
-4bff,2014-03-26,2013-03-18
-4bfj,2014-03-26,2013-03-19
-8bfe,2022-11-23,2022-10-25
-6bfe,2017-11-15,2017-10-26
-4bfq,2013-05-22,2013-03-21
-3bfj,2008-11-25,2007-11-21
-6bfx,2017-11-15,2017-10-27
-8bf5,2022-12-28,2022-10-24
-4bfp,2013-06-19,2013-03-21
-8bfs,2022-11-16,2022-10-26
-2bfy,2005-05-03,2004-12-15
-2bfq,2005-01-18,2004-12-10
-4bfk,2014-03-26,2013-03-19
-4bfm,2014-02-12,2013-03-21
-3w5k,2014-03-05,2013-01-30
-6w5u,2020-06-17,2020-03-13
-3w5m,2013-03-20,2013-01-31
-1w5u,2005-09-15,2004-08-10
-1w57,2004-10-04,2004-08-06
-5w51,2018-06-20,2017-06-13
-2w54,2008-12-23,2008-12-04
-2w5u,2009-12-22,2008-12-12
-2w5o,2009-03-03,2008-12-11
-1w5c,2004-12-21,2004-08-06
-2w5k,2009-02-17,2008-12-10
-7w58,2022-06-29,2021-11-29
-4w59,2015-04-01,2014-08-16
-1w5t,2004-10-05,2004-08-09
-1w53,2004-08-05,2004-08-05
-7w51,2022-10-26,2021-11-29
-1w51,2004-09-23,2004-08-04
-3w5f,2014-01-29,2013-01-29
-2w5l,2009-02-17,2008-12-10
-4w5s,2015-05-13,2014-08-18
-3w5r,2013-06-26,2013-02-06
-3w5o,2013-04-03,2013-02-02
-4w5q,2014-11-12,2014-08-18
-2w5f,2010-01-19,2008-12-10
-3w5d,2013-03-06,2013-01-27
-7w50,2022-10-26,2021-11-29
-1w5y,2004-10-07,2004-08-10
-4w55,2015-04-01,2014-08-16
-2w5s,2009-02-03,2008-12-11
-1w5n,2005-01-19,2004-08-09
-4w5i,2015-06-10,2014-08-18
-2w5v,2009-11-24,2008-12-15
-4w5b,2015-03-04,2014-08-17
-1w5x,2004-12-22,2004-08-10
-8w5j,2024-02-28,2023-08-27
-7w5s,2022-04-13,2021-11-30
-4w50,2014-10-08,2014-08-16
-7w5f,2022-06-01,2021-11-30
-5w5s,2017-10-04,2017-06-15
-2w5e,2009-03-10,2008-12-10
-5w5q,2018-06-20,2017-06-15
-6w59,2021-03-17,2020-03-12
-2w5t,2009-02-03,2008-12-11
-5w5t,2018-11-14,2017-06-15
-1w5o,2005-01-19,2004-08-09
-3w51,2013-07-10,2013-01-18
-3w54,2013-03-13,2013-01-21
-5w5p,2018-12-19,2017-06-15
-2w52,2009-07-21,2008-12-03
-6w5y,2020-11-11,2020-03-14
-8w5z,2024-04-10,2023-08-28
-3w5b,2013-03-06,2013-01-27
-7w5n,2023-03-01,2021-11-30
-6w53,2021-04-07,2020-03-12
-6w5j,2020-09-30,2020-03-13
-4w5l,2015-05-27,2014-08-18
-1w5b,2004-12-01,2004-08-06
-6w5k,2020-09-30,2020-03-13
-3w5p,2013-06-26,2013-02-05
-2w59,2009-01-13,2008-12-08
-7w5h,2022-08-31,2021-11-30
-3w5c,2013-03-06,2013-01-27
-6w54,2021-02-17,2020-03-12
-5w5u,2017-10-04,2017-06-15
-5w5r,2018-11-14,2017-06-15
-2w5w,2009-11-24,2008-12-15
-3w5a,2013-03-06,2013-01-27
-4w5j,2014-11-26,2014-08-18
-5w5m,2017-09-13,2017-06-15
-6w5c,2020-09-16,2020-03-13
-4w5v,2015-09-09,2014-08-19
-7w52,2022-10-26,2021-11-29
-2w5y,2009-02-10,2008-12-15
-5w5x,2018-06-27,2017-06-16
-7w5k,2023-03-01,2021-11-30
-2w55,2008-12-23,2008-12-04
-6w5s,2020-06-17,2020-03-13
-7w5p,2022-03-30,2021-11-30
-2w5x,2009-11-24,2008-12-15
-6w57,2021-04-07,2020-03-12
-2w57,2009-01-20,2008-12-05
-3w5v,2013-06-19,2013-02-06
-5w5l,2017-09-13,2017-06-15
-4w5t,2014-11-12,2014-08-18
-2w5i,2009-02-17,2008-12-10
-5w57,2017-09-20,2017-06-14
-3w5g,2014-01-29,2013-01-29
-1w5s,2004-10-05,2004-08-09
-5w5c,2017-08-23,2017-06-14
-3w55,2013-02-06,2013-01-21
-1w58,2004-12-01,2004-08-06
-4w5a,2015-01-21,2014-08-17
-5w5w,2018-06-20,2017-06-15
-4w54,2015-04-01,2014-08-16
-4w5r,2014-11-12,2014-08-18
-1w5q,2005-01-19,2004-08-09
-3w5z,2014-04-16,2013-02-10
-1w5f,2004-12-01,2004-08-06
-5w5n,2017-09-13,2017-06-15
-6w50,2020-06-10,2020-03-12
-7w5o,2022-02-23,2021-11-30
-2w5a,2008-12-23,2008-12-08
-4w5m,2015-05-27,2014-08-18
-7w5v,2022-04-13,2021-11-30
-1w54,2005-01-19,2004-08-05
-7w59,2022-06-22,2021-11-29
-6w5t,2020-06-17,2020-03-13
-3w5n,2013-03-20,2013-01-31
-2w5p,2009-06-02,2008-12-11
-1w5e,2004-12-01,2004-08-06
-1w5d,2005-12-07,2004-08-06
-5w55,2018-06-20,2017-06-14
-2w5b,2008-12-23,2008-12-08
-4w5o,2014-11-12,2014-08-18
-1w5p,2005-01-19,2004-08-09
-3w5u,2013-06-19,2013-02-06
-5w5j,2017-10-25,2017-06-15
-1w52,2006-07-12,2004-08-04
-4w5k,2014-09-24,2014-08-18
-5w58,2018-01-31,2017-06-14
-7w5e,2022-10-26,2021-11-30
-6w5v,2020-06-17,2020-03-13
-5w5o,2017-10-25,2017-06-15
-3w5w,2013-07-10,2013-02-07
-2w5r,2009-02-03,2008-12-11
-3w5j,2013-04-24,2013-01-30
-5w53,2017-11-29,2017-06-13
-7w5t,2022-04-13,2021-11-30
-6w5l,2020-09-30,2020-03-13
-7w5i,2022-06-01,2021-11-30
-7w5w,2022-10-26,2021-11-30
-3w57,2013-10-23,2013-01-24
-3w5h,2013-07-17,2013-01-30
-4w58,2015-04-01,2014-08-16
-6w5r,2020-06-17,2020-03-13
-6w56,2021-04-07,2020-03-12
-8w5k,2024-03-13,2023-08-27
-6w51,2021-03-17,2020-03-12
-6w58,2020-11-04,2020-03-12
-4w57,2015-04-01,2014-08-16
-2w5z,2009-02-10,2008-12-15
-7w5b,2022-06-22,2021-11-29
-7w5j,2022-06-01,2021-11-30
-5w5d,2017-08-23,2017-06-14
-6w5x,2021-03-17,2020-03-14
-1w5w,2004-12-22,2004-08-10
-5w5v,2018-06-27,2017-06-15
-8w53,2024-05-22,2023-08-25
-4w5c,2015-04-08,2014-08-17
-4w5y,2015-05-27,2014-08-19
-6w5h,2020-09-30,2020-03-13
-1w5a,2004-12-01,2004-08-06
-5w50,2018-02-21,2017-06-13
-1w55,2004-10-04,2004-08-05
-2w58,2009-12-22,2008-12-08
-7w55,2022-04-20,2021-11-29
-7w53,2022-04-20,2021-11-29
-4w5p,2015-05-27,2014-08-18
-5w5h,2017-07-19,2017-06-15
-4w5n,2014-11-12,2014-08-18
-3w5t,2013-06-26,2013-02-06
-1w5m,2005-01-19,2004-08-09
-4w5z,2015-08-26,2014-08-19
-5w5k,2018-06-27,2017-06-15
-8w5a,2023-09-27,2023-08-25
-2w5q,2009-02-03,2008-12-11
-7w5r,2022-12-07,2021-11-30
-3w5q,2013-06-26,2013-02-05
-3w5e,2013-05-29,2013-01-28
-7w56,2022-04-20,2021-11-29
-1w56,2005-01-19,2004-08-05
-1w5z,2005-12-08,2004-08-11
-7w5z,2022-04-06,2021-11-30
-4w56,2015-04-01,2014-08-16
-1w5v,2004-12-01,2004-08-10
-7w5c,2022-12-07,2021-11-30
-7w5a,2022-06-22,2021-11-29
-2w5g,2009-02-17,2008-12-10
-3w52,2013-04-17,2013-01-18
-8w59,2023-09-27,2023-08-25
-5w56,2017-09-20,2017-06-14
-5w5y,2017-07-26,2017-06-16
-6fm3,2019-06-12,2018-01-30
-8fm7,2023-04-05,2022-12-22
-5fmi,2016-06-01,2015-11-06
-3fmg,2009-06-23,2008-12-22
-8fmp,2024-01-31,2022-12-24
-3fmj,2009-12-22,2008-12-22
-7fm8,2022-11-02,2022-08-26
-8fms,2024-01-31,2022-12-24
-8fm1,2024-02-07,2022-12-22
-7fmm,2022-11-02,2022-08-26
-8fmt,2024-01-31,2022-12-24
-1fmo,1998-01-14,1997-07-08
-4fm8,2012-10-03,2012-06-15
-2fmp,2006-04-25,2006-01-09
-2fmz,2006-05-23,2006-01-10
-7fmy,2022-11-02,2022-08-26
-7fmt,2022-11-02,2022-08-26
-6fmo,2018-10-24,2018-02-01
-3fmr,2009-01-13,2008-12-22
-6fmk,2018-04-11,2018-01-31
-5fma,2016-04-13,2015-11-02
-2fmb,1999-01-13,1998-07-13
-1fm6,2001-02-16,2000-08-16
-7fml,2022-11-02,2022-08-26
-4fmo,2013-02-20,2012-06-18
-1fml,2001-05-02,2000-08-17
-2fmd,2006-08-22,2006-01-09
-8fmx,2023-06-28,2022-12-26
-7fmd,2022-11-02,2022-08-26
-1fmx,2002-07-31,2000-08-18
-8fmj,2023-11-22,2022-12-23
-8fmk,2023-11-22,2022-12-23
-3fmp,2009-05-19,2008-12-22
-3fm4,2009-12-22,2008-12-19
-7fmr,2022-11-02,2022-08-26
-7fm1,2022-11-02,2022-08-26
-8fmf,2024-02-07,2022-12-23
-3fmn,2009-12-22,2008-12-22
-1fmb,1996-10-14,1996-02-27
-4fmc,2012-09-05,2012-06-16
-6fmi,2018-04-11,2018-01-31
-7fmn,2022-11-02,2022-08-26
-2fm6,2007-01-16,2006-01-07
-8fmz,2023-03-29,2022-12-26
-6fms,2018-08-29,2018-02-02
-4fm5,2012-08-29,2012-06-15
-4fm9,2012-08-08,2012-06-15
-6fmj,2018-04-11,2018-01-31
-4fma,2012-09-05,2012-06-16
-3fma,2009-12-22,2008-12-19
-8fmn,2024-01-31,2022-12-23
-7fmk,2022-11-02,2022-08-26
-8fmr,2024-01-31,2022-12-24
-7fmv,2022-11-02,2022-08-26
-7fmj,2022-11-02,2022-08-26
-7fmq,2022-11-02,2022-08-26
-5fml,2016-01-13,2015-11-06
-4fmp,2013-07-31,2012-06-18
-5fm3,2016-12-28,2015-10-30
-8fmg,2024-02-07,2022-12-23
-5fm0,2016-11-16,2015-10-29
-4fm6,2012-10-17,2012-06-15
-3fme,2009-01-06,2008-12-21
-3fmw,2009-05-05,2008-12-22
-1fmj,2001-05-02,2000-08-17
-3fmq,2009-01-13,2008-12-22
-6fm2,2018-05-16,2018-01-30
-4fmt,2012-07-25,2012-06-18
-8fm0,2023-04-05,2022-12-22
-4fmu,2012-09-05,2012-06-18
-4fm1,2012-08-29,2012-06-15
-7fm3,2022-11-02,2022-08-26
-2fmy,2007-01-16,2006-01-10
-3fm5,2009-02-03,2008-12-19
-1fm7,2001-12-12,2000-08-16
-3fmi,2009-06-30,2008-12-22
-7fmb,2022-11-02,2022-08-26
-6fmq,2018-08-08,2018-02-02
-4fmm,2013-02-27,2012-06-18
-2fm1,2006-01-31,2006-01-06
-7fmo,2022-11-02,2022-08-26
-7fm7,2022-11-02,2022-08-26
-6fm1,2019-06-12,2018-01-29
-6fmn,2019-03-13,2018-02-01
-1fmi,2001-01-17,2000-08-17
-3fmu,2009-12-22,2008-12-22
-6fmf,2018-10-17,2018-01-31
-7fmz,2022-11-02,2022-08-26
-2fms,2006-04-25,2006-01-09
-3fml,2009-12-22,2008-12-22
-8fm4,2023-04-05,2022-12-22
-6fmz,2018-06-06,2018-02-02
-2fm0,2006-03-28,2006-01-06
-5fmb,2016-02-10,2015-11-02
-1fm8,2001-12-12,2000-08-16
-1fmc,1996-11-08,1996-04-26
-7fmi,2022-11-02,2022-08-26
-7fmf,2022-11-02,2022-08-26
-6fm7,2018-05-30,2018-01-30
-8fmq,2024-01-31,2022-12-24
-4fm0,2012-08-29,2012-06-15
-7fmu,2022-11-02,2022-08-26
-6fma,2019-03-13,2018-01-30
-4fmb,2012-09-05,2012-06-16
-3fmz,2009-01-27,2008-12-22
-4fme,2012-09-05,2012-06-16
-3fm6,2009-12-22,2008-12-19
-7fme,2022-11-02,2022-08-26
-4fmf,2012-08-22,2012-06-16
-4fmd,2012-09-05,2012-06-16
-3fmd,2008-12-30,2008-12-21
-3fm8,2009-08-25,2008-12-19
-7fmx,2022-11-02,2022-08-26
-7fm0,2022-11-02,2022-08-26
-8fm2,2023-04-05,2022-12-22
-2fmq,2006-04-25,2006-01-09
-2fme,2006-04-18,2006-01-09
-3fm1,2009-12-22,2008-12-19
-1fmg,2000-09-13,2000-08-17
-3fmk,2009-12-22,2008-12-22
-7fm9,2022-11-02,2022-08-26
-8fmw,2023-11-08,2022-12-25
-7fm6,2022-11-02,2022-08-26
-5fmq,2016-01-13,2015-11-07
-6fmt,2018-09-05,2018-02-02
-3fmf,2009-06-30,2008-12-21
-6fmd,2018-07-11,2018-01-30
-5fm2,2016-12-28,2015-10-30
-8fmo,2024-01-31,2022-12-24
-6fmp,2018-08-08,2018-02-01
-2fmt,1999-07-29,1998-07-29
-5fmg,2016-03-02,2015-11-04
-1fm1,2001-08-15,2000-08-15
-3fmx,2010-01-12,2008-12-22
-5fm6,2016-01-20,2015-11-02
-4fmh,2012-09-05,2012-06-17
-3fmm,2009-12-22,2008-12-22
-4fm2,2012-08-29,2012-06-15
-1fm4,2002-12-20,2000-08-16
-2fmh,2006-05-23,2006-01-09
-8fmu,2024-02-28,2022-12-24
-7fmp,2022-11-02,2022-08-26
-2fmo,2006-04-25,2006-01-09
-6fm0,2019-06-12,2018-01-29
-5fmf,2015-11-25,2015-11-03
-8fm3,2023-04-05,2022-12-22
-1fmu,2002-07-31,2000-08-18
-7fmc,2022-11-02,2022-08-26
-7fmg,2022-11-02,2022-08-26
-8fm8,2023-04-05,2022-12-22
-2fmg,2006-05-23,2006-01-09
-8fm6,2024-04-24,2022-12-22
-3fm9,2009-06-09,2008-12-19
-2fmn,2006-04-25,2006-01-09
-6fmc,2018-10-17,2018-01-30
-6fmw,2018-09-05,2018-02-02
-4fmq,2012-10-31,2012-06-18
-7fm2,2022-11-02,2022-08-26
-7fma,2022-11-02,2022-08-26
-3fmo,2009-05-19,2008-12-22
-5fm7,2016-01-20,2015-11-02
-8fmv,2023-11-15,2022-12-24
-3fms,2009-02-10,2008-12-22
-4fmk,2012-08-22,2012-06-17
-2fmj,2006-05-23,2006-01-09
-5fmh,2016-11-23,2015-11-04
-4fmn,2013-02-20,2012-06-18
-1fm9,2001-02-16,2000-08-16
-7fmh,2022-11-02,2022-08-26
-2fmx,2006-09-05,2006-01-10
-7fms,2022-11-02,2022-08-26
-4fms,2013-03-13,2012-06-18
-7fmw,2022-11-02,2022-08-26
-5fmv,2016-03-23,2015-11-09
-2fm5,2006-03-28,2006-01-07
-3fmh,2009-12-22,2008-12-22
-5fmm,2016-01-13,2015-11-06
-4fmw,2012-08-22,2012-06-18
-5fmd,2016-02-10,2015-11-02
-4fmj,2012-09-05,2012-06-17
-4fm4,2012-08-22,2012-06-15
-4fmi,2012-09-05,2012-06-17
-8fmi,2023-11-29,2022-12-23
-2fmk,2006-05-23,2006-01-09
-4fm7,2012-10-03,2012-06-15
-3fm2,2009-01-13,2008-12-19
-7fm5,2022-11-02,2022-08-26
-8fmm,2024-01-31,2022-12-23
-5fm9,2016-04-20,2015-11-02
-5fmc,2016-02-10,2015-11-02
-3fm3,2009-01-13,2008-12-19
-8fmh,2024-02-07,2022-12-23
-1fmw,2000-11-22,2000-08-18
-5fm8,2016-11-23,2015-11-02
-2fm2,2006-02-07,2006-01-06
-8fm5,2023-04-05,2022-12-22
-4fmx,2012-07-25,2012-06-18
-7fm4,2022-11-02,2022-08-26
-6fml,2018-04-25,2018-01-31
-6fmu,2018-06-06,2018-02-02
-6fm4,2019-07-10,2018-01-30
-3fbo,2009-12-08,2008-11-19
-1fbd,1993-10-31,1992-10-16
-2fbv,2006-04-25,2005-12-10
-2fbz,2006-08-29,2005-12-10
-7fbl,2022-07-13,2021-07-11
-3fba,2009-08-25,2008-11-19
-7fb8,2022-05-18,2021-07-08
-7fb7,2022-01-05,2021-07-08
-1fb7,2000-12-13,2000-07-14
-5fbi,2016-10-26,2015-12-14
-2fb3,2006-05-09,2005-12-08
-8fbv,2023-12-13,2022-11-30
-1fbf,1993-10-31,1992-10-16
-8fb5,2023-11-01,2022-11-29
-6fbv,2018-02-28,2017-12-19
-6fba,2018-02-21,2017-12-18
-5fbp,1992-07-15,1991-02-11
-4fb4,2012-09-26,2012-05-22
-4fbg,2012-11-28,2012-05-23
-5fbj,2016-12-14,2015-12-14
-5fbw,2016-12-28,2015-12-14
-8fbw,2023-01-18,2022-11-30
-7fbj,2022-07-13,2021-07-11
-7fbh,2021-12-01,2021-07-10
-6fbo,2019-01-30,2017-12-19
-7fbs,2021-09-22,2021-07-12
-4fbc,2012-10-31,2012-05-22
-3fbf,2009-08-11,2008-11-19
-6fbi,2018-09-26,2017-12-19
-4fbt,2013-06-12,2012-05-23
-5fbe,2016-10-26,2015-12-14
-7fbk,2022-07-13,2021-07-11
-6fbb,2018-03-14,2017-12-18
-7fbf,2022-07-13,2021-07-09
-5fbf,2016-12-28,2015-12-14
-5fby,2016-03-30,2015-12-14
-6fbc,2018-09-26,2017-12-19
-4fbz,2013-05-15,2012-05-23
-3fb1,2009-11-24,2008-11-18
-3fbp,1992-04-15,1990-06-07
-4fbh,2012-10-31,2012-05-23
-5fbg,2016-12-28,2015-12-14
-4fbv,2012-08-15,2012-05-23
-5fbk,2016-06-22,2015-12-14
-3fbw,2009-11-24,2008-11-20
-8fbh,2023-01-18,2022-11-29
-3fb7,2010-07-14,2008-11-18
-8fb7,2023-11-01,2022-11-29
-5fbz,2016-05-18,2015-12-14
-3fbg,2008-12-09,2008-11-19
-6fb8,2018-07-18,2017-12-18
-1fbm,2000-08-02,2000-07-16
-5fb3,2016-10-12,2015-12-14
-6fb7,2018-07-18,2017-12-18
-6fby,2018-05-16,2017-12-20
-3fbx,2009-03-03,2008-11-20
-2fby,2006-04-25,2005-12-10
-3fbr,2009-02-10,2008-11-19
-6fb2,2018-07-18,2017-12-18
-5fb2,2016-12-14,2015-12-13
-4fb2,2012-07-18,2012-05-22
-1fbv,2000-08-30,2000-07-17
-7fbw,2021-10-27,2021-07-13
-4fbx,2012-10-17,2012-05-23
-4fby,2012-06-20,2012-05-23
-3fbe,2009-06-16,2008-11-19
-8fbt,2023-05-31,2022-11-30
-3fbs,2008-12-23,2008-11-19
-5fb0,2016-05-04,2015-12-13
-2fbw,2005-12-20,2005-12-10
-3fbc,2009-08-11,2008-11-19
-5fbs,2016-01-13,2015-12-14
-5fbb,2016-12-28,2015-12-14
-6fb3,2018-03-28,2017-12-18
-7fbo,2021-12-01,2021-07-12
-6fbr,2018-12-05,2017-12-19
-4fbf,2012-09-26,2012-05-23
-3fb0,2009-12-08,2008-11-18
-2fb2,2006-05-09,2005-12-08
-7fbg,2022-07-13,2021-07-10
-3fb6,2010-05-19,2008-11-18
-4fbu,2013-06-12,2012-05-23
-5fbn,2016-02-03,2015-12-14
-5fba,2016-12-28,2015-12-14
-8fbc,2023-05-10,2022-11-29
-6fbh,2018-09-26,2017-12-19
-6fbu,2019-01-30,2017-12-19
-5fbo,2016-03-23,2015-12-14
-6fbd,2018-09-26,2017-12-19
-5fbr,2016-12-28,2015-12-14
-3fb8,2010-05-19,2008-11-18
-6fb6,2018-07-18,2017-12-18
-1fbb,2000-08-09,2000-07-15
-1fbe,1993-10-31,1992-10-16
-6fbn,2019-01-30,2017-12-19
-5fbh,2016-06-22,2015-12-14
-1fbw,2000-08-02,2000-07-17
-6fbg,2018-09-26,2017-12-19
-6fbe,2018-09-26,2017-12-19
-8fbu,2023-05-31,2022-11-30
-7fbn,2022-07-13,2021-07-11
-6fb5,2018-07-18,2017-12-18
-4fbk,2012-06-20,2012-05-23
-1fbc,1993-10-31,1992-10-14
-8fbm,2023-05-31,2022-11-29
-4fbe,2012-08-29,2012-05-23
-3fbm,2009-01-13,2008-11-19
-5fbv,2016-12-28,2015-12-14
-6fb1,2018-07-18,2017-12-18
-2fbl,2005-12-20,2005-12-09
-7fby,2022-07-20,2021-07-13
-8fbg,2023-01-18,2022-11-29
-7fbt,2021-08-11,2021-07-12
-5fbl,2016-12-28,2015-12-14
-5fb1,2016-05-04,2015-12-13
-1fby,2000-07-28,2000-07-17
-6fbz,2018-06-27,2017-12-20
-1fbl,1996-01-29,1995-04-24
-8fb1,2023-03-01,2022-11-29
-3fby,2009-06-23,2008-11-20
-5fb9,2016-12-28,2015-12-14
-7fbq,2022-07-13,2021-07-12
-1fbo,2000-08-02,2000-07-16
-6fb0,2018-07-18,2017-12-18
-3fb4,2009-09-29,2008-11-18
-8fb0,2023-06-21,2022-11-29
-5fbq,2016-12-28,2015-12-14
-1fbh,1993-10-31,1992-10-16
-2fbh,2005-12-20,2005-12-09
-6fbf,2018-09-26,2017-12-19
-8fb2,2023-03-01,2022-11-29
-1fb5,2003-08-26,2000-07-14
-5fbx,2015-12-30,2015-12-14
-7fb9,2022-10-12,2021-07-08
-8fbx,2023-11-22,2022-11-30
-6fbq,2018-12-05,2017-12-19
-4fbq,2012-06-20,2012-05-23
-6fbp,2019-01-30,2017-12-19
-3fbv,2008-12-16,2008-11-19
-7fbm,2022-07-13,2021-07-11
-3fb5,2010-05-19,2008-11-18
-5fbu,2015-12-30,2015-12-14
-6fb9,2018-07-18,2017-12-18
-8fbl,2023-02-01,2022-11-29
-2fbj,1990-07-15,1989-08-18
-8fbq,2023-10-18,2022-11-29
-3fbb,2009-08-11,2008-11-19
-4fba,2012-10-31,2012-05-22
-6fbt,2018-04-18,2017-12-19
-1fbx,2001-02-14,2000-07-17
-5fbt,2015-12-30,2015-12-14
-8fbb,2023-07-19,2022-11-29
-7fbp,2021-11-10,2021-07-12
-8fb9,2023-07-19,2022-11-29
-4fbw,2012-06-20,2012-05-23
-5fbc,2016-12-28,2015-12-14
-1fb1,2000-12-08,2000-07-14
-4fbp,1992-07-15,1991-02-11
-4fbb,2012-10-31,2012-05-22
-2fb8,2006-12-12,2005-12-08
-4fb1,2013-03-27,2012-05-22
-1fbg,1993-10-31,1992-10-16
-6fbw,2018-05-16,2017-12-20
-1fbp,1992-04-15,1990-05-31
-8fb8,2023-11-01,2022-11-29
-7fb6,2022-10-12,2021-07-08
-2fbx,2006-04-25,2005-12-10
-3fbu,2008-12-23,2008-11-19
-2fbb,2006-03-28,2005-12-09
-1fbk,2000-08-09,2000-07-15
-2fbr,2005-12-27,2005-12-09
-1fbz,2000-08-23,2000-07-17
-5fbd,2016-12-28,2015-12-14
-3url,2012-04-18,2011-11-22
-1ura,1996-07-11,1996-02-03
-3ur2,2012-08-01,2011-11-21
-7urb,2023-07-26,2022-04-21
-3ur9,2012-09-05,2011-11-21
-5urt,2018-02-14,2017-02-12
-4urn,2014-07-16,2014-07-01
-3urh,2011-12-14,2011-11-22
-4urz,2015-03-04,2014-07-02
-5ur9,2017-08-23,2017-02-09
-3urg,2012-11-28,2011-11-22
-6ur1,2020-05-13,2019-10-21
-3urq,2012-08-01,2011-11-22
-4urk,2014-10-22,2014-06-30
-5uri,2018-02-14,2017-02-10
-3ur0,2012-05-02,2011-11-21
-8urh,2024-05-29,2023-10-26
-6ura,2020-08-19,2019-10-23
-5uru,2018-02-21,2017-02-13
-7ur6,2023-04-26,2022-04-21
-7urd,2022-07-20,2022-04-21
-8urw,2023-12-27,2023-10-26
-8ur7,2023-12-27,2023-10-25
-7urc,2022-07-20,2022-04-21
-5urz,2017-05-10,2017-02-13
-5ur2,2017-08-02,2017-02-09
-8ur0,2024-05-29,2023-10-25
-3ur3,2012-03-21,2011-11-21
-7ure,2022-07-20,2022-04-21
-3urn,2012-08-01,2011-11-22
-1ur2,2003-12-18,2003-10-24
-4urw,2015-03-04,2014-07-02
-4ur8,2014-12-17,2014-06-26
-6ur5,2020-06-10,2019-10-22
-3urb,2012-08-01,2011-11-21
-1urc,2003-10-31,2003-10-28
-5ur6,2017-11-22,2017-02-09
-4urr,2015-07-15,2014-07-01
-4ur0,2014-10-15,2014-06-25
-5ure,2018-02-14,2017-02-10
-5urm,2017-07-19,2017-02-11
-1ury,2004-12-15,2003-11-12
-3ur5,2012-08-01,2011-11-21
-7uru,2023-04-26,2022-04-22
-1ur9,2004-04-27,2003-10-27
-7urp,2023-05-03,2022-04-22
-7urs,2022-05-04,2022-04-22
-5urk,2017-07-19,2017-02-10
-3urf,2012-07-11,2011-11-22
-8urb,2023-11-15,2023-10-25
-5urv,2017-05-10,2017-02-13
-1urb,1996-07-11,1996-02-03
-5ur4,2018-01-24,2017-02-09
-7ur3,2022-12-28,2022-04-21
-4urg,2014-10-08,2014-06-30
-1ur5,2003-11-05,2003-10-27
-4uro,2014-07-30,2014-07-01
-6ur4,2020-03-18,2019-10-22
-7ur4,2022-06-08,2022-04-21
-1urs,2003-12-11,2003-11-04
-6ur9,2020-03-18,2019-10-22
-6urc,2019-11-06,2019-10-23
-1urw,2004-04-23,2003-11-11
-1urd,2003-12-11,2003-10-29
-1urx,2004-03-04,2003-11-12
-5urs,2017-03-08,2017-02-12
-3urk,2012-09-05,2011-11-22
-4uri,2015-03-11,2014-06-30
-6urb,2020-11-11,2019-10-23
-3uri,2012-04-18,2011-11-22
-6urw,2020-06-17,2019-10-24
-1ur6,2004-05-07,2003-10-27
-6urg,2019-11-27,2019-10-23
-7urf,2022-07-20,2022-04-21
-7ur0,2023-04-26,2022-04-20
-4ur9,2015-02-25,2014-06-27
-4urm,2014-07-30,2014-06-30
-6urx,2020-06-17,2019-10-24
-8ur2,2023-11-08,2023-10-25
-7urq,2022-05-04,2022-04-22
-1url,2004-10-20,2003-10-31
-6ury,2020-06-17,2019-10-24
-4url,2014-07-16,2014-06-30
-6ur3,2019-10-30,2019-10-22
-6urm,2020-09-16,2019-10-23
-3ura,2012-08-01,2011-11-21
-8uri,2024-05-29,2023-10-26
-1ur0,2004-10-20,2003-10-24
-8ur1,2023-11-08,2023-10-25
-4urv,2015-03-04,2014-07-02
-1ur1,2003-12-18,2003-10-24
-1urj,2004-11-11,2003-10-30
-7ur9,2023-07-26,2022-04-21
-7urh,2023-04-26,2022-04-22
-1urg,2003-12-11,2003-10-29
-5urb,2017-02-22,2017-02-10
-5uro,2017-05-31,2017-02-11
-3urm,2012-11-28,2011-11-22
-3ur7,2012-05-30,2011-11-21
-5urc,2017-03-15,2017-02-10
-8ur5,2023-12-27,2023-10-25
-4urt,2014-09-10,2014-07-02
-1urt,1997-01-11,1996-07-03
-4ury,2015-03-04,2014-07-02
-8ur9,2024-05-15,2023-10-25
-1ur8,2004-04-27,2003-10-27
-5urq,2017-03-01,2017-02-12
-4urh,2014-10-29,2014-06-30
-5urd,2018-02-14,2017-02-10
-5ur1,2017-05-31,2017-02-09
-5urg,2018-02-14,2017-02-10
-3urz,2011-12-14,2011-11-22
-8urx,2024-05-29,2023-10-27
-5ury,2017-05-10,2017-02-13
-7ura,2022-07-20,2022-04-21
-5ura,2017-08-23,2017-02-09
-6urq,2020-07-29,2019-10-24
-4urx,2015-03-04,2014-07-02
-4ure,2015-07-08,2014-06-28
-1uri,1997-04-01,1996-11-14
-1urk,1995-05-08,1994-01-10
-1ur4,2004-10-20,2003-10-24
-4uru,2015-03-04,2014-07-02
-5urh,2018-02-14,2017-02-10
-4urf,2015-07-08,2014-06-28
-6uro,2019-11-27,2019-10-23
-5ur5,2017-11-29,2017-02-09
-6ur0,2020-05-13,2019-10-21
-7urg,2022-09-07,2022-04-21
-4ura,2015-06-17,2014-06-27
-4urs,2014-10-08,2014-07-02
-1urv,2004-12-15,2003-11-11
-5ur3,2017-03-08,2017-02-09
-6urh,2020-03-18,2019-10-23
-5ur0,2018-03-14,2017-02-09
-6ur8,2020-04-29,2019-10-22
-5urj,2017-07-19,2017-02-10
-7fao,2022-05-18,2021-07-07
-1fa6,2000-09-20,2000-07-12
-4fab,1990-07-15,1989-04-10
-5faf,2016-10-05,2015-12-11
-6faa,2018-07-11,2017-12-15
-3fat,2008-12-09,2008-11-18
-6fai,2018-02-28,2017-12-15
-2fac,2006-09-26,2005-12-07
-4fad,2013-04-03,2012-05-22
-7fan,2022-09-28,2021-07-06
-6fau,2018-05-16,2017-12-18
-2faf,2006-06-27,2005-12-07
-8fa6,2023-11-01,2022-11-25
-1fak,1999-12-03,1998-12-28
-6fa2,2018-09-05,2017-12-15
-7faz,2021-07-21,2021-07-08
-5faz,2016-12-14,2015-12-13
-6fac,2018-07-11,2017-12-15
-5fa1,2016-05-18,2015-12-10
-4fal,2012-10-10,2012-05-22
-8fav,2023-03-01,2022-11-28
-6fa3,2018-08-22,2017-12-15
-7fay,2021-07-21,2021-07-08
-1fao,2000-07-20,2000-07-13
-1far,1997-01-27,1996-09-05
-5fac,2016-12-21,2015-12-11
-8fac,2023-08-16,2022-11-25
-6fag,2018-10-10,2017-12-15
-7faq,2022-05-18,2021-07-07
-2fa3,2006-07-25,2005-12-06
-8fal,2023-03-01,2022-11-28
-6faf,2018-10-10,2017-12-15
-2fav,2006-10-10,2005-12-08
-2fae,2006-09-26,2005-12-07
-8fao,2023-12-13,2022-11-28
-5faj,2016-12-21,2015-12-11
-4fat,2012-07-11,2012-05-22
-6faw,2018-05-16,2017-12-18
-7fac,2022-08-10,2021-07-06
-3fap,2000-09-13,1999-05-06
-4fap,2000-09-13,1999-05-06
-7fam,2022-09-28,2021-07-06
-3fax,2009-04-14,2008-11-18
-4fan,2013-03-06,2012-05-22
-3fav,2009-11-24,2008-11-18
-5fa7,2016-01-20,2015-12-11
-4fa9,2013-03-06,2012-05-21
-7fae,2021-12-22,2021-07-06
-4fa1,2013-03-06,2012-05-21
-4fa2,2013-06-05,2012-05-21
-7fau,2022-06-01,2021-07-07
-4fah,2012-09-26,2012-05-22
-7fal,2022-08-31,2021-07-06
-5faw,2016-09-28,2015-12-12
-7fav,2022-07-13,2021-07-07
-4faj,2012-09-12,2012-05-22
-3faz,2009-11-24,2008-11-18
-4fa7,2012-05-30,2012-05-21
-5fae,2016-10-05,2015-12-11
-4fa3,2012-10-10,2012-05-21
-7fag,2022-07-06,2021-07-06
-5fag,2016-12-21,2015-12-11
-5fak,2016-12-14,2015-12-11
-5fa6,2016-08-17,2015-12-11
-1fa5,2000-09-20,2000-07-12
-5fa4,2016-12-21,2015-12-10
-5far,2016-01-13,2015-12-11
-8fak,2023-05-10,2022-11-28
-4fa5,2013-03-06,2012-05-21
-5fah,2016-10-26,2015-12-11
-3faa,2009-01-27,2008-11-16
-4fak,2012-06-06,2012-05-22
-1fa7,2000-09-20,2000-07-12
-4fa6,2013-04-03,2012-05-21
-5fan,2016-02-24,2015-12-11
-2fa7,2005-12-13,2005-12-07
-4faf,2012-08-29,2012-05-22
-7faj,2021-11-24,2021-07-06
-6fah,2018-01-24,2017-12-15
-6fap,2018-03-21,2017-12-16
-8fau,2023-03-01,2022-11-28
-4fas,2013-09-04,2012-05-22
-8fa8,2023-11-01,2022-11-25
-1fat,1996-12-23,1996-06-12
-4fag,2012-09-26,2012-05-22
-5fa8,2016-06-29,2015-12-11
-5fax,2016-05-18,2015-12-12
-3fah,2009-10-06,2008-11-17
-5fav,2016-09-28,2015-12-12
-8fae,2023-06-07,2022-11-26
-6fam,2018-03-21,2017-12-15
-6fak,2019-01-02,2017-12-15
-5fa3,2016-12-21,2015-12-10
-8fad,2023-06-07,2022-11-26
-1fah,1997-02-12,1996-08-01
-6fa5,2018-07-11,2017-12-15
-5fap,2016-01-20,2015-12-11
-2faq,2006-05-23,2005-12-07
-1faw,2001-12-05,2000-07-13
-7far,2022-05-18,2021-07-07
-5fay,2016-09-28,2015-12-12
-3fa6,2009-10-27,2008-11-15
-5fao,2016-02-17,2015-12-11
-6fa4,2018-08-22,2017-12-15
-3fa0,2009-02-17,2008-11-14
-3fai,2009-09-01,2008-11-17
-8faj,2023-10-11,2022-11-28
-6fay,2018-03-28,2017-12-18
-7fa0,2022-07-13,2021-07-05
-4fa4,2013-03-06,2012-05-21
-1fa9,2000-08-25,2000-07-12
-2fah,2006-06-27,2005-12-07
-2fad,2006-09-26,2005-12-07
-1fay,2001-07-14,2000-07-14
-2fak,2006-04-18,2005-12-07
-4fai,2012-08-29,2012-05-22
-6fat,2019-01-30,2017-12-17
-1fa2,2000-08-16,2000-07-12
-2far,2006-05-23,2005-12-07
-6fal,2019-01-30,2017-12-15
-4fav,2013-03-06,2012-05-22
-7fa1,2022-08-10,2021-07-05
-5fad,2016-06-29,2015-12-11
-2fax,1997-03-12,1996-12-24
-2fa9,2006-09-05,2005-12-07
-8fax,2023-05-03,2022-11-28
-3fak,2009-02-10,2008-11-17
-6far,2018-03-21,2017-12-16
-2fap,1999-05-18,1998-09-22
-3fa3,2009-01-27,2008-11-14
-8fa0,2023-01-11,2022-11-25
-6fad,2019-09-25,2017-12-15
-5fal,2016-02-24,2015-12-11
-4fa8,2012-08-29,2012-05-21
-7fat,2022-05-18,2021-07-07
-6fav,2018-05-16,2017-12-18
-6faz,2018-11-21,2017-12-18
-2fam,1993-10-31,1993-07-20
-5fat,2016-01-20,2015-12-12
-1fax,1997-10-29,1996-08-23
-1fag,1997-02-12,1996-08-01
-4fao,2012-06-20,2012-05-22
-8faz,2023-06-21,2022-11-29
-5fa2,2016-04-06,2015-12-10
-5faq,2016-01-20,2015-12-11
-4fam,2012-10-10,2012-05-22
-1fap,1997-07-23,1996-03-15
-8fah,2023-12-13,2022-11-26
-5fa5,2016-02-24,2015-12-10
-4fae,2012-08-29,2012-05-22
-7fak,2023-02-08,2021-07-06
-3faq,2009-03-31,2008-11-18
-6fa1,2018-08-22,2017-12-15
-8fan,2023-11-01,2022-11-28
-7fai,2021-11-24,2021-07-06
-1faq,1997-01-27,1996-09-05
-2faw,2006-10-03,2005-12-08
-4faa,2012-10-31,2012-05-21
-3fal,2009-04-14,2008-11-17
-3fas,2008-12-09,2008-11-18
-3fa4,2009-01-27,2008-11-14
-7fah,2022-07-06,2021-07-06
-5fas,2016-01-20,2015-12-11
-2fa1,2006-01-10,2005-12-06
-3faw,2009-04-14,2008-11-18
-2fai,2006-05-09,2005-12-07
-1fa4,2000-08-16,2000-07-12
-3fa5,2008-12-02,2008-11-14
-1fae,2000-08-02,2000-07-13
-1fa0,2000-08-30,2000-07-11
-2fal,1993-10-31,1993-06-14
-5ku8,2017-11-08,2016-07-13
-4ku1,2014-02-19,2013-05-21
-4kuv,2014-06-25,2013-05-22
-7ku9,2021-12-15,2020-11-24
-4ku5,2014-07-23,2013-05-21
-4kum,2014-05-07,2013-05-22
-2kug,2010-03-09,2010-02-17
-7kua,2021-12-01,2020-11-24
-5ku1,2016-09-21,2016-07-12
-4kuj,2014-05-28,2013-05-22
-7kui,2021-03-17,2020-11-25
-5ku9,2017-01-11,2016-07-13
-2kuh,2010-03-09,2010-02-17
-7kuv,2021-02-03,2020-11-25
-6kuy,2019-12-04,2019-09-02
-3ku0,2010-01-26,2009-11-26
-1kuj,2002-06-19,2002-01-22
-7ku5,2022-03-30,2020-11-24
-6ku3,2020-05-13,2019-08-30
-3kud,2010-03-23,2009-11-27
-6kuk,2019-10-02,2019-09-02
-4kuw,2014-06-25,2013-05-22
-7kuy,2021-09-08,2020-11-25
-7kuz,2021-12-01,2020-11-25
-4ku0,2014-05-21,2013-05-21
-4kuy,2014-06-25,2013-05-22
-5kuj,2016-09-07,2016-07-13
-4ku3,2014-07-23,2013-05-21
-5kuk,2016-08-10,2016-07-13
-3ku2,2010-02-16,2009-11-26
-5kue,2016-09-07,2016-07-13
-6ku2,2020-08-26,2019-08-30
-3kum,2010-10-13,2009-11-27
-1kux,2002-03-22,2002-01-22
-4kup,2014-04-02,2013-05-22
-3kuh,2010-11-24,2009-11-27
-4kuf,2014-07-09,2013-05-22
-6ku6,2020-07-08,2019-08-30
-4kub,2013-06-05,2013-05-21
-4ku8,2014-01-15,2013-05-21
-5kut,2016-09-21,2016-07-13
-4ku4,2013-06-05,2013-05-21
-3kui,2010-05-12,2009-11-27
-3ku1,2009-12-22,2009-11-26
-4kuh,2014-05-28,2013-05-22
-5kub,2016-09-14,2016-07-13
-2kuy,2011-05-04,2010-03-01
-1kuk,2002-07-10,2002-01-22
-6kuf,2020-09-02,2019-09-02
-3kuw,2010-04-21,2009-11-27
-7kur,2021-02-03,2020-11-25
-1kui,2002-07-10,2002-01-22
-4kug,2014-05-28,2013-05-22
-7ku7,2021-03-17,2020-11-24
-7kus,2021-02-03,2020-11-25
-4kuk,2014-11-26,2013-05-22
-1ku6,2003-12-23,2002-01-21
-2ku3,2011-02-16,2010-02-12
-6ku1,2020-08-26,2019-08-30
-6kux,2019-12-04,2019-09-02
-6kum,2020-05-20,2019-09-02
-7kut,2021-02-03,2020-11-25
-5kuh,2016-09-07,2016-07-13
-6kup,2019-10-02,2019-09-02
-5ku6,2017-07-26,2016-07-12
-6kuw,2019-12-04,2019-09-02
-2kuo,2010-05-05,2010-02-23
-3kuc,2010-03-23,2009-11-27
-6kuz,2020-07-08,2019-09-03
-6kua,2019-10-02,2019-08-31
-3kuo,2010-06-30,2009-11-27
-1kuh,1997-03-12,1996-02-22
-1kug,2002-07-10,2002-01-22
-7kuq,2021-02-03,2020-11-25
-3ku5,2010-01-19,2009-11-26
-3kuy,2010-01-05,2009-11-28
-5kum,2016-08-10,2016-07-13
-5kup,2016-09-14,2016-07-13
-3ku6,2010-01-19,2009-11-26
-7ku6,2021-12-01,2020-11-24
-4kuo,2014-11-26,2013-05-22
-4kux,2013-08-14,2013-05-22
-4ku7,2014-01-15,2013-05-21
-3ku9,2010-12-15,2009-11-27
-3ku3,2010-01-19,2009-11-26
-1ku0,2002-08-21,2002-01-18
-6kun,2020-05-13,2019-09-02
-7kue,2021-04-28,2020-11-24
-5kuy,2017-06-14,2016-07-13
-3kun,2010-06-30,2009-11-27
-5ku5,2016-09-14,2016-07-12
-4ku2,2014-07-23,2013-05-21
-7kux,2022-03-30,2020-11-25
-5kuf,2016-09-07,2016-07-13
-1kuv,2002-03-22,2002-01-22
-1kuy,2002-03-22,2002-01-22
-1kuf,2002-07-03,2002-01-21
-3kuk,2010-04-28,2009-11-27
-5ku3,2016-11-02,2016-07-12
-6ku8,2020-03-25,2019-08-31
-6kug,2020-02-05,2019-09-02
-5ebu,2016-06-29,2015-10-19
-8ebs,2023-04-19,2022-08-31
-6eb3,2019-08-07,2018-08-03
-4eb9,2012-12-05,2012-03-23
-6ebk,2018-08-22,2018-08-06
-5ebb,2016-01-20,2015-10-19
-3ebg,2009-01-27,2008-08-27
-1ebg,1995-04-27,1994-04-27
-2eb1,2007-11-06,2007-02-05
-2eb8,2007-07-03,2007-02-07
-5ebl,2016-04-20,2015-10-19
-6eb2,2019-03-06,2018-08-03
-5ebm,2016-04-20,2015-10-19
-6ebl,2018-08-22,2018-08-06
-7ebl,2021-09-15,2021-03-10
-1ebo,1999-07-02,1998-11-03
-2eb5,2007-07-17,2007-02-07
-6ebr,2019-11-13,2018-08-06
-5eb4,2016-04-20,2015-10-17
-3ebq,2008-11-04,2008-08-28
-4ebl,2013-04-03,2012-03-23
-1eb6,2001-11-23,2001-07-19
-1eb1,2002-01-28,2001-07-18
-6ebs,2019-08-21,2018-08-07
-5eb3,2016-05-18,2015-10-17
-3ebz,2008-09-16,2008-08-28
-2eb6,2007-07-17,2007-02-07
-4eb6,2012-08-01,2012-03-23
-7eb4,2021-06-23,2021-03-08
-4ebc,2012-06-13,2012-03-23
-1ebl,2000-02-11,2000-01-24
-2ebn,1995-01-26,1994-08-30
-8eb3,2023-09-13,2022-08-30
-3ebs,2008-09-23,2008-08-28
-1ebk,2000-07-26,2000-01-24
-3eb1,2009-07-07,2008-08-26
-4eb8,2013-02-06,2012-03-23
-1ebh,1995-04-27,1994-11-01
-2eba,2007-04-01,2007-02-07
-4ebd,2012-06-13,2012-03-23
-4eby,2012-06-27,2012-03-25
-4ebw,2012-07-25,2012-03-25
-3eb5,2008-09-09,2008-08-27
-8ebm,2023-02-22,2022-08-31
-7ebb,2021-08-04,2021-03-09
-5eb8,2016-10-19,2015-10-18
-4ebz,2012-06-27,2012-03-26
-4ebb,2012-09-19,2012-03-23
-3ebl,2008-11-25,2008-08-28
-5ebv,2016-03-30,2015-10-19
-3eb9,2009-05-26,2008-08-27
-3ebh,2009-01-27,2008-08-27
-8ebr,2023-03-08,2022-08-31
-1ebz,2002-06-26,2000-01-25
-8ebt,2023-04-19,2022-08-31
-5ebd,2016-02-17,2015-10-19
-6ebn,2018-12-12,2018-08-06
-3ebp,2009-09-01,2008-08-28
-4ebv,2012-08-22,2012-03-25
-7ebw,2022-01-26,2021-03-11
-7ebi,2021-09-08,2021-03-09
-7eba,2022-03-09,2021-03-09
-6ebd,2020-02-12,2018-08-06
-7ebq,2022-03-16,2021-03-10
-3ebd,2008-10-07,2008-08-27
-6eb5,2019-08-21,2018-08-04
-4ebk,2012-04-04,2012-03-23
-1ebt,2000-01-13,1998-11-04
-7ebg,2021-08-04,2021-03-09
-6ebv,2019-08-07,2018-08-07
-1eb9,2002-01-01,2001-07-24
-4eb4,2012-05-02,2012-03-23
-5ebe,2016-01-20,2015-10-19
-4eb5,2012-05-02,2012-03-23
-5ebw,2016-04-20,2015-10-19
-1ebv,2000-02-24,2000-01-24
-3ebf,2008-10-07,2008-08-27
-1ebm,2000-03-20,2000-01-24
-1eby,2002-06-26,2000-01-25
-7eb3,2021-06-23,2021-03-08
-8ebc,2022-09-07,2022-08-31
-3ebc,2008-12-23,2008-08-27
-6ebz,2018-09-19,2018-08-07
-4ebe,2012-06-13,2012-03-23
-8eb2,2022-11-30,2022-08-30
-3ebi,2009-01-27,2008-08-27
-4ebu,2012-04-18,2012-03-24
-3ebe,2008-12-09,2008-08-27
-1ebu,2000-03-08,2000-01-24
-1eba,1998-11-11,1998-10-02
-3eb0,2008-09-16,2008-08-26
-5eb2,2016-05-18,2015-10-17
-4ebp,2013-04-03,2012-03-23
-2eb0,2007-08-07,2007-02-05
-3eb6,2008-09-09,2008-08-27
-8ebx,2023-04-19,2022-08-31
-8eb0,2023-01-18,2022-08-30
-7eb5,2021-06-23,2021-03-08
-7ebp,2022-03-30,2021-03-10
-5ebt,2016-03-02,2015-10-19
-2ebq,2007-08-14,2007-02-09
-7ebv,2022-01-26,2021-03-11
-7ebj,2022-03-09,2021-03-09
-5ebc,2016-02-17,2015-10-19
-7ebx,2021-09-29,2021-03-11
-1ebp,1997-07-29,1996-05-07
-6eb7,2019-11-13,2018-08-05
-2eb3,2008-02-12,2007-02-06
-3ebo,2009-09-01,2008-08-28
-6ebp,2018-09-19,2018-08-06
-7ebm,2021-09-08,2021-03-10
-8ebi,2023-03-08,2022-08-31
-3ebb,2009-02-24,2008-08-27
-2ebr,2007-08-14,2007-02-09
-7ebe,2021-06-23,2021-03-09
-7eby,2022-01-26,2021-03-11
-8eb5,2023-08-02,2022-08-30
-1eb0,2002-01-04,2001-07-17
-1ebe,2001-07-26,2001-07-25
-4eb7,2012-05-02,2012-03-23
-4ebr,2012-10-03,2012-03-24
-4ebf,2012-05-30,2012-03-23
-6eb1,2019-03-06,2018-08-03
-8eby,2023-04-19,2022-08-31
-2ebs,2007-06-26,2007-02-09
-5ebk,2016-10-26,2015-10-19
-6ebq,2018-09-19,2018-08-06
-3ebj,2009-02-10,2008-08-27
-8ebz,2023-06-07,2022-08-31
-6ebg,2020-02-05,2018-08-06
-2ebt,2008-02-19,2007-02-09
-1ebw,2002-06-26,2000-01-25
-1ebd,1996-07-11,1996-02-03
-8ebu,2023-04-19,2022-08-31
-2ebv,2007-08-14,2007-02-09
-7ebu,2022-01-26,2021-03-11
-7ebt,2022-01-26,2021-03-11
-8ebw,2023-04-19,2022-08-31
-1ebc,1999-08-13,1999-03-04
-3eb3,2008-09-23,2008-08-26
-4eb2,2013-03-27,2012-03-23
-3eb4,2008-09-23,2008-08-26
-1eb2,2002-02-11,2001-07-18
-2ebl,2008-02-19,2007-02-09
-1ebf,2000-03-08,2000-01-24
-7eb2,2021-05-05,2021-03-08
-4eb3,2013-02-06,2012-03-23
-6ebw,2019-05-01,2018-08-07
-1eb7,2001-07-24,2001-07-24
-4ebn,2013-04-03,2012-03-23
-7ebh,2021-08-04,2021-03-09
-8ebk,2023-10-04,2022-08-31
-2ebf,2007-03-06,2007-02-08
-6ebe,2018-11-28,2018-08-06
-5eba,2016-10-19,2015-10-18
-4eb1,2012-07-18,2012-03-23
-8ebv,2023-04-19,2022-08-31
-2eb9,2007-07-03,2007-02-07
-7ebc,2021-06-23,2021-03-09
-5eb5,2016-04-20,2015-10-17
-7ebk,2022-03-09,2021-03-09
-6ebo,2018-09-19,2018-08-06
-2eb4,2007-07-17,2007-02-07
-7ebd,2021-09-15,2021-03-09
-1eb3,2001-08-02,2001-07-18
-2ebh,2007-03-06,2007-02-08
-7eb0,2021-06-23,2021-03-08
-8ebl,2023-02-22,2022-08-31
-4p4l,2015-03-18,2014-03-12
-1p4m,2003-05-13,2003-04-23
-7p47,2021-11-24,2021-07-09
-7p4e,2022-07-06,2021-07-11
-4p4r,2014-07-16,2014-03-13
-4p44,2015-05-20,2014-03-11
-3p4q,2010-12-08,2010-10-06
-1p47,2003-06-24,2003-04-21
-7p42,2022-07-20,2021-07-09
-1p45,2003-09-16,2003-04-21
-4p4y,2015-05-06,2014-03-13
-6p4d,2020-05-27,2019-05-27
-1p4h,2004-05-18,2003-04-23
-8p4h,2023-08-30,2023-05-21
-7p43,2022-07-27,2021-07-09
-8p41,2024-03-06,2023-05-18
-3p4n,2011-10-12,2010-10-06
-4p4j,2015-05-20,2014-03-12
-3p41,2010-10-20,2010-10-05
-1p4r,2004-03-30,2003-04-23
-2p41,2007-08-28,2007-03-11
-1p4d,2003-10-14,2003-04-22
-4p4v,2015-05-06,2014-03-13
-3p4f,2010-12-08,2010-10-06
-7p4s,2021-10-13,2021-07-13
-7p4j,2022-12-28,2021-07-11
-6p4j,2019-08-07,2019-05-27
-7p4u,2022-07-27,2021-07-13
-4p4p,2014-08-06,2014-03-12
-7p4p,2021-09-29,2021-07-12
-2p4z,2008-03-18,2007-03-14
-4p4w,2015-05-06,2014-03-13
-7p41,2021-08-18,2021-07-09
-6p4r,2020-03-25,2019-05-28
-2p4p,2007-05-22,2007-03-12
-1p4g,2004-05-18,2003-04-23
-8p47,2024-06-05,2023-05-19
-8p4q,2024-03-27,2023-05-23
-4p45,2015-05-20,2014-03-11
-4p4d,2015-05-20,2014-03-12
-7p49,2022-06-22,2021-07-10
-6p49,2019-07-24,2019-05-26
-7p4b,2022-07-27,2021-07-10
-3p4o,2011-10-12,2010-10-06
-4p4s,2014-10-22,2014-03-13
-2p4k,2007-04-03,2007-03-12
-7p46,2021-10-06,2021-07-09
-8p46,2024-06-05,2023-05-19
-4p4o,2014-08-06,2014-03-12
-2p4t,2007-06-05,2007-03-13
-4p4f,2015-05-20,2014-03-12
-1p4u,2003-07-29,2003-04-24
-1p48,2003-11-18,2003-04-21
-1p4c,2003-10-28,2003-04-22
-6p44,2020-05-27,2019-05-25
-2p42,2008-03-11,2007-03-11
-8p4g,2024-02-21,2023-05-21
-8p48,2024-06-05,2023-05-19
-1p44,2003-09-16,2003-04-21
-3p4s,2010-12-08,2010-10-07
-4p4k,2014-07-16,2014-03-12
-8p4f,2023-07-19,2023-05-20
-7p4z,2021-08-25,2021-07-13
-2p4y,2008-01-08,2007-03-13
-1p42,2003-06-10,2003-04-21
-6p4t,2020-03-25,2019-05-28
-2p4e,2007-04-10,2007-03-12
-1p4l,2003-11-11,2003-04-23
-3p46,2011-01-12,2010-10-06
-2p4n,2008-07-08,2007-03-12
-6p4k,2019-08-07,2019-05-27
-8p4c,2023-08-16,2023-05-20
-3p4w,2011-01-19,2010-10-07
-8p4x,2023-11-08,2023-05-23
-6p42,2019-10-23,2019-05-25
-2p4s,2008-01-15,2007-03-13
-6p48,2019-07-24,2019-05-26
-7p4w,2021-08-25,2021-07-13
-6p4m,2020-03-25,2019-05-28
-4p42,2014-05-14,2014-03-10
-8p4d,2023-08-16,2023-05-20
-3p4z,2011-02-09,2010-10-07
-6p46,2019-07-24,2019-05-26
-6p4q,2020-03-25,2019-05-28
-3p4v,2011-04-20,2010-10-07
-3p4u,2011-09-28,2010-10-07
-8p4b,2023-08-16,2023-05-20
-3p4e,2010-10-20,2010-10-06
-4p4b,2015-05-20,2014-03-12
-1p4v,2003-05-06,2003-04-24
-7p4f,2022-05-18,2021-07-11
-1p4q,2003-07-01,2003-04-23
-6p4z,2019-06-12,2019-05-29
-3p4r,2010-11-24,2010-10-07
-1p46,2003-10-07,2003-04-21
-3p4t,2010-10-20,2010-10-07
-6p43,2019-10-23,2019-05-25
-4p4q,2015-03-25,2014-03-12
-2p4i,2007-03-20,2007-03-12
-6p41,2019-10-23,2019-05-25
-8p4a,2023-08-16,2023-05-20
-6p4f,2020-06-17,2019-05-27
-1p4j,2004-05-18,2003-04-23
-1p43,2003-11-18,2003-04-21
-7p4o,2022-12-28,2021-07-12
-3p47,2011-02-02,2010-10-06
-8p44,2023-12-20,2023-05-19
-4p4e,2015-05-20,2014-03-12
-4p4i,2015-05-20,2014-03-12
-7p4v,2021-10-06,2021-07-13
-4p4g,2015-03-18,2014-03-12
-1p4n,2004-02-10,2003-04-23
-7p4d,2022-07-27,2021-07-11
-8p4e,2023-07-19,2023-05-20
-3p44,2011-10-12,2010-10-06
-3p4x,2011-06-15,2010-10-07
-2p40,2007-08-28,2007-03-11
-1p4a,2003-12-09,2003-04-22
-6p4w,2020-06-03,2019-05-28
-1p4b,2004-05-04,2003-04-22
-8p4z,2023-06-14,2023-05-23
-4p4m,2014-08-06,2014-03-12
-1p4f,2004-09-28,2003-04-23
-2p4j,2007-07-24,2007-03-12
-3p48,2010-10-27,2010-10-06
-3p4k,2011-01-05,2010-10-06
-4p4x,2015-05-06,2014-03-13
-3p43,2011-01-19,2010-10-05
-6p4u,2019-06-12,2019-05-28
-3p4m,2011-10-12,2010-10-06
-7p4h,2022-05-18,2021-07-11
-4p4z,2015-05-06,2014-03-13
-3p4p,2010-12-01,2010-10-06
-2p46,2008-03-11,2007-03-11
-6p40,2020-02-12,2019-05-25
-7p4c,2022-07-27,2021-07-11
-8p45,2023-12-20,2023-05-19
-6p4n,2020-03-25,2019-05-28
-7p4k,2022-07-06,2021-07-11
-7p48,2022-02-02,2021-07-09
-3p40,2010-11-03,2010-10-05
-1p49,2003-08-12,2003-04-21
-4p4t,2014-10-22,2014-03-13
-6p4e,2020-06-03,2019-05-27
-3p4h,2011-01-19,2010-10-06
-3p4g,2011-04-27,2010-10-06
-4p4c,2014-08-13,2014-03-12
-6p4v,2020-04-01,2019-05-28
-7p4l,2022-07-13,2021-07-12
-6hop,2019-10-02,2018-09-18
-8hot,2023-12-13,2022-12-10
-3hoh,1998-09-16,1998-09-11
-8hoi,2024-01-17,2022-12-10
-2ho4,2006-08-15,2006-07-13
-6ho5,2018-12-26,2018-09-17
-6hoz,2018-11-28,2018-09-18
-6ho4,2018-12-26,2018-09-17
-2hoh,1998-09-23,1998-09-14
-4hoj,2012-11-07,2012-10-22
-5hoy,2016-03-23,2016-01-19
-4ho2,2013-10-23,2012-10-22
-3ho0,2009-10-27,2009-06-01
-5hoh,1998-09-23,1998-09-14
-2hod,2007-05-29,2006-07-14
-4hoa,2012-11-07,2012-10-22
-5ho7,2016-06-08,2016-01-19
-6hoy,2018-11-14,2018-09-18
-6ho6,2018-12-26,2018-09-17
-5hox,2016-03-23,2016-01-19
-1hox,2001-07-20,2000-12-11
-5hoa,2016-11-23,2016-01-19
-3hof,2009-06-16,2009-06-02
-2hor,2007-02-06,2006-07-16
-6hoa,2018-12-26,2018-09-17
-4hoh,1998-09-23,1998-09-14
-6ho0,2018-12-26,2018-09-17
-8ho8,2023-12-13,2022-12-09
-8ho6,2023-10-18,2022-12-09
-4hom,2012-10-31,2012-10-22
-8hog,2024-01-17,2022-12-10
-8ho5,2023-12-20,2022-12-09
-6ho3,2018-12-26,2018-09-17
-3ho5,2009-06-23,2009-06-01
-8hop,2023-12-13,2022-12-10
-1hos,1993-10-31,1993-04-06
-4hot,2013-01-23,2012-10-22
-5hof,2017-02-01,2016-01-19
-5ho0,2017-02-01,2016-01-19
-4hov,2013-01-16,2012-10-22
-6hov,2019-10-09,2018-09-18
-6hoe,2018-12-26,2018-09-17
-8hoq,2023-12-13,2022-12-10
-1ho3,2001-03-07,2000-12-08
-4ho7,2013-07-10,2012-10-22
-1hoc,1994-04-30,1994-01-02
-8hos,2023-12-13,2022-12-10
-5ho6,2016-11-23,2016-01-19
-2hoc,2006-10-10,2006-07-14
-3how,2009-07-28,2009-06-03
-3hog,2010-06-23,2009-06-02
-8hod,2023-10-18,2022-12-09
-6hob,2018-12-26,2018-09-17
-4hor,2013-01-23,2012-10-22
-2ho0,2006-09-19,2006-07-13
-5hoo,2016-06-01,2016-01-19
-1hoo,1997-02-12,1996-04-26
-5ho1,2017-02-01,2016-01-19
-5hot,2016-12-14,2016-01-19
-6how,2019-05-08,2018-09-18
-1hoy,2000-12-27,2000-12-12
-4ho5,2013-10-23,2012-10-22
-4ho9,2013-10-23,2012-10-22
-3hoi,2009-06-23,2009-06-02
-8hon,2023-12-13,2022-12-10
-5hob,2016-10-19,2016-01-19
-4hod,2013-05-08,2012-10-22
-5ho5,2017-02-01,2016-01-19
-6hoo,2019-10-09,2018-09-17
-8hoa,2023-10-18,2022-12-09
-1ho5,2002-03-20,2000-12-08
-3hoy,2009-07-28,2009-06-03
-6hof,2018-12-26,2018-09-17
-6ho2,2018-12-26,2018-09-17
-5hor,2016-11-23,2016-01-19
-4ho3,2013-10-23,2012-10-22
-4ho6,2013-10-23,2012-10-22
-8ho0,2023-04-19,2022-12-09
-4hoz,2013-10-16,2012-10-23
-4hox,2013-11-13,2012-10-23
-4hon,2012-11-21,2012-10-22
-4ho8,2013-10-23,2012-10-22
-6hos,2018-10-24,2018-09-18
-3hok,2009-07-28,2009-06-02
-8hoz,2023-12-13,2022-12-11
-4hog,2014-03-19,2012-10-22
-6ho7,2018-12-26,2018-09-17
-5ho2,2017-02-01,2016-01-19
-2hog,2007-04-24,2006-07-14
-1hov,2001-12-12,2000-12-11
-3ho9,2010-02-09,2009-06-01
-3hou,2009-07-28,2009-06-03
-8hoh,2024-01-17,2022-12-10
-6hod,2018-12-26,2018-09-17
-3hov,2009-07-28,2009-06-03
-4hos,2013-01-23,2012-10-22
-6ho9,2018-12-26,2018-09-17
-8hor,2023-12-13,2022-12-10
-8ho1,2023-04-19,2022-12-09
-1hon,1996-11-08,1996-04-26
-5hou,2016-03-16,2016-01-19
-3hoz,2009-07-28,2009-06-03
-8hom,2023-12-13,2022-12-10
-6hot,2019-10-02,2018-09-18
-5ho8,2016-06-08,2016-01-19
-5hok,2017-02-01,2016-01-19
-5hoi,2016-06-22,2016-01-19
-6hoq,2019-10-02,2018-09-18
-1hot,1996-04-03,1995-11-17
-3ho8,2009-06-30,2009-06-01
-4how,2013-10-16,2012-10-22
-1hor,1996-01-29,1995-09-13
-6hon,2019-02-06,2018-09-17
-2hot,2006-12-12,2006-07-16
-1hoz,2001-12-12,2000-12-12
-3ho1,2009-10-06,2009-06-01
-2hos,2006-12-12,2006-07-16
-8hou,2023-12-13,2022-12-10
-2hox,2007-02-06,2006-07-17
-5hol,2016-01-27,2016-01-19
-8how,2023-01-25,2022-12-11
-6ho8,2018-12-26,2018-09-17
-8hoo,2023-12-13,2022-12-10
-4hoe,2014-03-19,2012-10-22
-6ho1,2018-12-26,2018-09-17
-4hoo,2012-11-21,2012-10-22
-2hob,2007-04-03,2006-07-14
-4hof,2014-03-19,2012-10-22
-5hon,2017-02-01,2016-01-19
-5ho9,2017-02-01,2016-01-19
-6hoc,2018-12-26,2018-09-17
-6hoi,2019-02-27,2018-09-17
-6hou,2019-10-02,2018-09-18
-2hoe,2006-08-15,2006-07-14
-2hoz,2006-08-22,2006-07-17
-4hoc,2013-10-23,2012-10-22
-1ho4,2001-03-28,2000-12-08
-3ho2,2010-02-09,2009-06-01
-3hos,2009-09-22,2009-06-03
-3hox,2009-07-28,2009-06-03
-1hop,1996-11-08,1996-04-26
-6hor,2019-10-02,2018-09-18
-8ho4,2023-12-20,2022-12-09
-8hoj,2023-12-13,2022-12-10
-8hoc,2023-12-20,2022-12-09
-3hod,2009-10-27,2009-06-02
-3hot,2009-09-22,2009-06-03
-4ho4,2013-10-23,2012-10-22
-1hha,2005-07-11,2000-12-22
-2hhb,1984-07-18,1984-03-07
-5hhj,2016-05-04,2016-01-11
-1hh3,2005-07-11,2000-12-19
-5hhp,2016-03-23,2016-01-11
-6hhs,2019-09-18,2018-08-29
-5hhh,2017-01-18,2016-01-11
-4hhd,2013-10-09,2012-10-09
-6hhz,2019-12-18,2018-08-29
-5hhk,2016-05-04,2016-01-11
-8hho,2023-02-08,2022-11-16
-5hhw,2016-04-13,2016-01-11
-1hh4,2001-08-28,2000-12-20
-1hhy,2003-09-05,2000-12-29
-4hht,2013-02-06,2012-10-10
-5hh3,2016-02-10,2016-01-09
-4hhg,2012-11-21,2012-10-09
-6hhy,2019-12-18,2018-08-29
-2hhw,2006-12-12,2006-06-28
-2hhp,2007-01-23,2006-06-28
-2hhe,1995-01-26,1994-09-29
-3hhy,2010-01-12,2009-05-18
-3hhi,2010-05-26,2009-05-15
-6hh3,2018-11-28,2018-08-24
-2hht,2006-12-12,2006-06-28
-8hhq,2023-09-20,2022-11-16
-1hhj,1993-10-31,1993-06-30
-4hhz,2013-03-27,2012-10-10
-8hh5,2023-07-26,2022-11-16
-2hhh,2006-09-26,2006-06-28
-6hh1,2019-09-18,2018-08-24
-6hh6,2018-11-28,2018-08-24
-4hhy,2013-03-27,2012-10-10
-8hhx,2023-02-01,2022-11-17
-3hhe,2009-05-26,2009-05-15
-6hh2,2019-09-11,2018-08-24
-8hh3,2023-07-19,2022-11-16
-8hh2,2023-07-19,2022-11-16
-1hh5,2001-05-03,2000-12-21
-1hhk,1993-10-31,1993-06-30
-6hhf,2019-03-20,2018-08-28
-6hhb,2019-09-11,2018-08-27
-4hhj,2013-02-27,2012-10-10
-6hhi,2019-02-20,2018-08-28
-3hht,2009-07-14,2009-05-17
-5hht,2016-11-02,2016-01-11
-5hhq,2016-03-23,2016-01-11
-8hh6,2023-07-26,2022-11-16
-2hhv,2006-12-12,2006-06-28
-8hh9,2023-07-19,2022-11-16
-1hh6,2001-01-26,2000-12-21
-3hhu,2009-07-14,2009-05-17
-4hhb,1984-07-17,1984-03-07
-1hhu,2003-09-05,2000-12-28
-4hh1,2013-06-05,2012-10-09
-1hhf,2005-07-11,2000-12-22
-8hhp,2023-11-22,2022-11-16
-2hhx,2006-12-12,2006-06-28
-8hhb,2023-07-19,2022-11-16
-2hhk,2007-03-27,2006-06-28
-1hh7,2001-01-02,2000-12-21
-5hha,2017-01-18,2016-01-10
-2hh9,2006-07-18,2006-06-28
-5hhf,2016-02-17,2016-01-10
-2hhs,2006-12-12,2006-06-28
-3hhk,2009-09-08,2009-05-15
-3hhx,2010-01-26,2009-05-18
-5hh4,2017-01-18,2016-01-09
-3hh3,2009-10-13,2009-05-14
-5hh1,2016-09-14,2016-01-09
-6hhv,2019-12-18,2018-08-29
-3hh5,2009-10-13,2009-05-14
-4hhl,2013-03-27,2012-10-10
-6hhr,2019-07-10,2018-08-29
-5hhv,2016-06-01,2016-01-11
-5hh9,2017-01-18,2016-01-10
-2hhj,2006-10-24,2006-06-28
-5hh0,2016-09-14,2016-01-09
-5hhl,2016-05-04,2016-01-11
-6hhd,2019-12-11,2018-08-28
-3hhb,1984-07-18,1984-03-07
-4hho,2013-03-27,2012-10-10
-3hh8,2009-06-09,2009-05-15
-4hhr,2013-02-20,2012-10-10
-8hh0,2023-03-22,2022-11-16
-3hhm,2009-09-29,2009-05-15
-3hh6,2009-10-13,2009-05-14
-1hhs,2001-03-27,2000-12-28
-3hhs,2009-09-29,2009-05-17
-1hht,2001-03-27,2000-12-28
-4hhs,2013-02-20,2012-10-10
-8hht,2023-03-29,2022-11-17
-8hhc,2023-07-19,2022-11-16
-5hho,2016-03-23,2016-01-11
-1hho,1983-10-27,1983-06-10
-6hhq,2019-02-20,2018-08-28
-2hhf,2006-10-24,2006-06-28
-4hhw,2012-11-21,2012-10-10
-5hh7,2016-03-09,2016-01-10
-1hhi,1993-10-31,1993-06-30
-8hh4,2023-07-19,2022-11-16
-2hhd,1995-01-26,1994-09-29
-6hhj,2019-02-20,2018-08-28
-2hh5,2006-08-15,2006-06-27
-2hh0,2006-12-26,2006-06-27
-2hha,2006-09-19,2006-06-28
-3hhq,2009-06-16,2009-05-15
-6hhp,2019-02-27,2018-08-28
-6hh5,2018-11-28,2018-08-24
-4hh4,2013-10-30,2012-10-09
-5hhy,2017-01-25,2016-01-11
-2hhu,2006-12-12,2006-06-28
-6hh9,2019-09-11,2018-08-27
-2hh7,2006-12-05,2006-06-27
-3hhn,2009-11-24,2009-05-15
-5hhi,2017-01-18,2016-01-11
-2hhm,1993-10-31,1992-10-20
-8hhv,2023-08-16,2022-11-17
-5hh5,2017-01-18,2016-01-09
-1hhz,2003-09-05,2000-12-29
-4hhh,2012-10-31,2012-10-09
-2hhg,2006-07-25,2006-06-28
-1hhc,2005-07-11,2000-12-22
-5hhn,2016-03-23,2016-01-11
-3hhj,2009-05-26,2009-05-15
-6hhx,2019-12-18,2018-08-29
-8hha,2023-07-19,2022-11-16
-6hhg,2019-02-20,2018-08-28
-6hho,2018-12-12,2018-08-28
-8hhk,2023-01-18,2022-11-16
-6hh4,2018-11-28,2018-08-24
-1hhg,1993-10-31,1993-06-30
-5hhz,2016-05-04,2016-01-11
-8hhu,2023-03-29,2022-11-17
-1hh9,2001-01-12,2000-12-21
-5hh6,2017-01-18,2016-01-09
-2hh1,2007-03-27,2006-06-27
-6hhw,2019-12-18,2018-08-29
-2hhn,2007-05-08,2006-06-28
-3hha,2009-06-23,2009-05-15
-5hhm,2016-03-23,2016-01-11
-6hhh,2019-02-20,2018-08-28
-8hh8,2023-07-26,2022-11-16
-4hhm,2013-03-27,2012-10-10
-8hhy,2023-02-01,2022-11-17
-5hhx,2016-06-01,2016-01-11
-4hhq,2013-03-27,2012-10-10
-6hhm,2019-06-26,2018-08-28
-8hh7,2023-07-26,2022-11-16
-8hhl,2023-04-12,2022-11-16
-2hhq,2006-12-12,2006-06-28
-4hh0,2013-06-05,2012-10-09
-8hhm,2023-04-12,2022-11-16
-4hh6,2013-11-20,2012-10-09
-8hh1,2023-07-19,2022-11-16
-3sax,2012-04-11,2011-06-03
-8sak,2023-10-04,2023-04-01
-1sax,2004-04-27,2004-02-09
-6saz,2019-10-23,2019-07-18
-8sau,2023-04-19,2023-04-02
-5saa,2021-06-09,2021-05-19
-6sa8,2019-11-20,2019-07-16
-1saw,2004-10-12,2004-02-09
-5sau,2022-06-29,2021-06-22
-5sal,2021-09-01,2021-05-28
-3sai,2012-06-13,2011-06-02
-3sa2,2012-06-13,2011-06-02
-5sag,2021-06-09,2021-05-19
-1sav,1998-05-27,1997-11-24
-8sar,2023-04-19,2023-04-01
-8saa,2023-04-12,2023-03-31
-2sam,1994-10-15,1994-07-08
-7saa,2022-07-20,2021-09-22
-7san,2022-05-18,2021-09-22
-3sa1,2012-06-13,2011-06-02
-6sam,2020-04-29,2019-07-17
-3sa0,2011-12-14,2011-06-02
-8sae,2023-04-12,2023-03-31
-3sa8,2012-06-06,2011-06-02
-8sam,2023-10-11,2023-04-01
-3sae,2011-12-14,2011-06-02
-3sac,2012-06-06,2011-06-02
-6sae,2019-09-18,2019-07-16
-2sar,1992-04-15,1990-12-13
-8sa8,2023-04-12,2023-03-31
-1sa5,2004-06-08,2004-02-06
-6sax,2019-12-11,2019-07-18
-8sag,2024-04-03,2023-03-31
-3sa9,2012-06-06,2011-06-02
-8say,2023-04-19,2023-04-02
-5sap,2021-09-01,2021-05-28
-5sad,2021-06-09,2021-05-19
-5sao,2021-09-01,2021-05-28
-2sas,1993-10-31,1993-07-30
-5sa3,2022-06-15,2021-05-18
-8saz,2023-04-19,2023-04-02
-5sax,2022-06-29,2021-06-22
-6saw,2019-12-11,2019-07-18
-1sa0,2004-03-23,2004-02-06
-5sat,2021-09-01,2021-05-28
-3saf,2011-07-06,2011-06-02
-5sa6,2021-06-09,2021-05-19
-6sau,2019-10-23,2019-07-17
-5saq,2021-09-01,2021-05-28
-5sas,2021-09-01,2021-05-28
-8sab,2023-04-12,2023-03-31
-6sat,2020-03-11,2019-07-17
-6sac,2020-04-15,2019-07-16
-5san,2021-09-01,2021-05-28
-7sab,2022-07-20,2021-09-22
-3sap,2012-04-11,2011-06-03
-6saf,2019-12-18,2019-07-16
-5sa1,2022-06-15,2021-05-18
-6sah,2020-12-09,2019-07-16
-5sak,2021-09-01,2021-05-28
-5sa8,2021-06-09,2021-05-19
-5sah,2021-06-09,2021-05-19
-6sal,2019-12-25,2019-07-17
-3sav,2012-01-11,2011-06-03
-5sav,2022-06-29,2021-06-22
-6sag,2019-09-18,2019-07-16
-3saj,2011-06-22,2011-06-02
-1sa3,2004-09-07,2004-02-06
-6sa0,2020-11-18,2019-07-15
-5sa0,2022-06-15,2021-05-18
-6say,2020-04-15,2019-07-18
-3sal,2011-08-10,2011-06-03
-3sah,2011-07-06,2011-06-02
-5saz,2022-06-29,2021-06-22
-8saw,2023-04-19,2023-04-02
-6sas,2020-04-15,2019-07-17
-3sa3,2012-06-06,2011-06-02
-7sa4,2022-08-03,2021-09-22
-3sad,2012-11-07,2011-06-02
-3san,2011-08-10,2011-06-03
-6sa2,2020-12-09,2019-07-16
-7saq,2022-03-09,2021-09-23
-1sac,1994-05-31,1994-01-27
-7sar,2022-03-09,2021-09-23
-7sad,2022-07-20,2021-09-22
-1sa1,2004-03-23,2004-02-06
-3sa6,2012-06-06,2011-06-02
-7sa2,2022-09-21,2021-09-21
-5sac,2021-06-09,2021-05-19
-3saz,2012-11-07,2011-06-03
-5saf,2021-06-09,2021-05-19
-5sar,2021-09-01,2021-05-28
-3saa,2012-06-06,2011-06-02
-8sa7,2023-04-12,2023-03-31
-6sa3,2020-12-09,2019-07-16
-3sau,2012-01-11,2011-06-03
-8sas,2023-04-19,2023-04-01
-5sa2,2022-06-15,2021-05-18
-6sa1,2020-11-18,2019-07-15
-8sa9,2023-04-12,2023-03-31
-3sab,2012-06-06,2011-06-02
-5saw,2022-06-29,2021-06-22
-5sab,2021-06-09,2021-05-19
-3sas,2012-01-11,2011-06-03
-7sao,2022-08-03,2021-09-23
-5sae,2021-06-09,2021-05-19
-7sa0,2022-10-05,2021-09-21
-3sar,2012-01-11,2011-06-03
-7sa3,2021-12-01,2021-09-22
-5sa9,2021-06-09,2021-05-19
-3saw,2012-01-11,2011-06-03
-6sao,2019-10-23,2019-07-17
-6san,2020-03-18,2019-07-17
-6saq,2020-07-22,2019-07-17
-1say,1999-06-08,1998-06-05
-5sai,2021-06-09,2021-05-19
-1sat,1995-07-31,1994-07-04
-5sam,2021-09-01,2021-05-28
-6sa5,2020-03-18,2019-07-16
-1saz,2005-03-29,2004-02-09
-3sat,2012-01-11,2011-06-03
-8sac,2023-04-12,2023-03-31
-5sa4,2021-06-09,2021-05-19
-8sax,2023-04-19,2023-04-02
-6sa4,2020-03-18,2019-07-16
-6sar,2020-08-26,2019-07-17
-3sa7,2012-06-06,2011-06-02
-5sa5,2021-06-09,2021-05-19
-5say,2022-06-29,2021-06-22
-3say,2012-06-13,2011-06-03
-3sa5,2012-06-06,2011-06-02
-6sav,2019-10-23,2019-07-17
-6saj,2020-12-16,2019-07-16
-8saq,2023-04-19,2023-04-01
-8sad,2023-04-12,2023-03-31
-8saf,2024-04-03,2023-03-31
-1sa4,2004-06-08,2004-02-06
-7sac,2022-07-20,2021-09-22
-8sav,2023-04-19,2023-04-02
-3sao,2011-12-28,2011-06-03
-8san,2023-04-19,2023-04-01
-3sa4,2012-06-06,2011-06-02
-5sa7,2021-06-09,2021-05-19
-7sas,2022-03-09,2021-09-23
-3sag,2011-07-06,2011-06-02
-1nww,2003-06-10,2003-02-07
-5nw3,2017-06-07,2017-05-04
-5nwt,2017-09-13,2017-05-08
-7nwg,2021-07-07,2021-03-16
-2nws,2007-04-24,2006-11-16
-2nwg,2007-02-13,2006-11-14
-7nwy,2022-03-30,2021-03-17
-6nwu,2019-07-10,2019-02-07
-6nwt,2019-07-10,2019-02-07
-3nwz,2010-09-08,2010-07-12
-6nw6,2020-02-19,2019-02-06
-7nwh,2021-07-07,2021-03-16
-2nwj,2006-11-28,2006-11-15
-7nw0,2021-05-05,2021-03-16
-6nwc,2019-11-06,2019-02-06
-3nww,2010-09-08,2010-07-12
-7nwm,2022-11-02,2021-03-17
-1nw9,2003-03-25,2003-02-05
-6nwy,2020-10-14,2019-02-07
-6nw1,2019-08-14,2019-02-05
-1nw1,2003-06-10,2003-02-05
-5nwc,2018-05-02,2017-05-05
-3nw2,2011-06-22,2010-07-09
-2nw3,2007-02-27,2006-11-14
-6nws,2019-07-10,2019-02-07
-6nwm,2019-07-17,2019-02-06
-6nwh,2019-07-17,2019-02-06
-7nww,2022-01-19,2021-03-17
-2nwp,2007-04-24,2006-11-16
-4nwc,2014-08-06,2013-12-06
-1nws,2003-08-26,2003-02-06
-4nwx,2015-01-14,2013-12-07
-2nwx,2007-02-27,2006-11-16
-7nwe,2022-11-02,2021-03-16
-2nwh,2006-12-12,2006-11-14
-4nw3,2014-04-23,2013-12-05
-5nw8,2018-05-30,2017-05-05
-3nw8,2010-12-01,2010-07-09
-3nwl,2011-07-13,2010-07-09
-4nwi,2014-03-19,2013-12-06
-4nwo,2014-05-28,2013-12-06
-7nwq,2021-07-07,2021-03-17
-1nwp,1998-01-28,1997-09-06
-7nwa,2022-11-02,2021-03-16
-1nwu,2003-08-26,2003-02-06
-7nwf,2021-08-04,2021-03-16
-6nw5,2019-10-23,2019-02-06
-3nwd,2010-12-01,2010-07-09
-6nwo,2019-07-17,2019-02-06
-6nwv,2020-02-12,2019-02-07
-6nwe,2020-02-12,2019-02-06
-1nw3,2003-03-25,2003-02-05
-7nwl,2021-06-02,2021-03-17
-2nw9,2006-12-19,2006-11-14
-5nw6,2017-11-15,2017-05-05
-6nw2,2019-05-01,2019-02-05
-3nw9,2011-03-16,2010-07-09
-7nw3,2021-07-21,2021-03-16
-1nw7,2003-07-29,2003-02-05
-6nwl,2019-10-23,2019-02-06
-1nwi,2003-08-26,2003-02-06
-5nwi,2017-11-22,2017-05-06
-3nwk,2011-07-13,2010-07-09
-6nw9,2019-06-05,2019-02-06
-5nwl,2018-03-07,2017-05-06
-4nw6,2014-02-19,2013-12-05
-5nwz,2018-04-04,2017-05-09
-5nwj,2017-11-22,2017-05-06
-7nw2,2021-07-07,2021-03-16
-4nwv,2014-08-20,2013-12-06
-2nwb,2006-12-19,2006-11-14
-3nwn,2010-07-21,2010-07-09
-7nws,2021-06-09,2021-03-17
-6nwj,2019-07-17,2019-02-06
-4nwj,2015-01-14,2013-12-06
-1nwn,2003-08-26,2003-02-06
-6nw0,2019-08-14,2019-02-05
-6nwk,2019-10-23,2019-02-06
-2nw4,2006-12-12,2006-11-14
-4nwl,2014-03-26,2013-12-06
-6nw3,2019-10-09,2019-02-05
-3nwy,2010-08-25,2010-07-12
-3nwe,2011-08-03,2010-07-09
-5nwg,2018-03-14,2017-05-05
-2nwy,2007-04-24,2006-11-16
-1nwt,2003-08-26,2003-02-06
-2nwz,2007-04-24,2006-11-16
-3nwa,2010-12-01,2010-07-09
-7nwk,2021-10-27,2021-03-16
-2nw7,2006-12-19,2006-11-14
-3nwx,2011-11-02,2010-07-12
-5nwn,2018-04-18,2017-05-07
-7nwr,2022-03-30,2021-03-17
-7nwo,2021-07-07,2021-03-17
-7nwb,2022-11-02,2021-03-16
-1nwl,2003-04-01,2003-02-06
-1nwk,2003-10-14,2003-02-06
-4nwm,2014-04-02,2013-12-06
-6nw4,2019-07-24,2019-02-06
-3nw4,2011-07-13,2010-07-09
-5nw7,2018-05-02,2017-05-05
-4nw9,2014-04-02,2013-12-05
-5nw0,2017-09-20,2017-05-04
-4nwh,2014-09-24,2013-12-06
-7nwn,2021-07-07,2021-03-17
-5nw9,2018-01-10,2017-05-05
-5nws,2018-01-24,2017-05-08
-6nwd,2019-08-14,2019-02-06
-3nw7,2010-07-28,2010-07-09
-7nwi,2021-07-07,2021-03-16
-1nwz,2003-03-11,2003-02-07
-2nww,2007-02-27,2006-11-16
-5nwb,2018-05-02,2017-05-05
-6nwb,2020-02-12,2019-02-06
-7nwt,2021-12-15,2021-03-17
-6nwg,2020-02-12,2019-02-06
-6nw7,2020-02-19,2019-02-06
-2nw6,2007-12-04,2006-11-14
-7nwv,2022-03-30,2021-03-17
-4nw7,2014-10-15,2013-12-05
-5nwd,2018-03-14,2017-05-05
-3nwf,2010-12-01,2010-07-09
-2nwl,2007-02-27,2006-11-15
-4nw8,2014-04-02,2013-12-05
-7nwz,2021-10-27,2021-03-17
-2nwn,2007-10-16,2006-11-16
-4nwz,2014-02-19,2013-12-07
-1nw2,2003-08-05,2003-02-05
-3nwq,2011-11-02,2010-07-10
-7nwx,2022-01-26,2021-03-17
-3nwi,2011-03-23,2010-07-09
-3nwv,2011-03-09,2010-07-11
-1nwg,2003-02-18,2003-02-06
-1nw4,2004-03-16,2003-02-05
-1nwr,2003-08-26,2003-02-06
-7nwc,2022-11-02,2021-03-16
-5nw1,2017-09-20,2017-05-04
-1nwo,1998-01-28,1997-09-06
-4nwk,2014-03-26,2013-12-06
-3nw6,2010-07-28,2010-07-09
-1nwe,2003-05-06,2003-02-06
-4nwd,2014-08-06,2013-12-06
-5nw2,2017-09-20,2017-05-04
-6nwn,2020-02-12,2019-02-06
-4nww,2014-08-20,2013-12-06
-3nwb,2011-08-03,2010-07-09
-5nwh,2018-04-04,2017-05-06
-3nw5,2010-07-28,2010-07-09
-1nw5,2003-07-29,2003-02-05
-6nwx,2020-08-12,2019-02-07
-3nwo,2010-08-04,2010-07-09
-5nwk,2017-11-22,2017-05-06
-2nwo,2007-04-24,2006-11-16
-1nwd,2003-04-08,2003-02-06
-7nwp,2021-07-07,2021-03-17
-5nwe,2018-07-04,2017-05-05
-1nw6,2003-07-29,2003-02-05
-6nwa,2019-05-29,2019-02-06
-4nw5,2014-02-19,2013-12-05
-2nw8,2006-12-19,2006-11-14
-3nw3,2010-08-04,2010-07-09
-6nwz,2020-02-12,2019-02-07
-6wb9,2020-06-03,2020-03-26
-7wbg,2022-12-21,2021-12-16
-1wbl,1998-04-08,1997-04-04
-1wb5,2005-02-02,2004-10-30
-6wb5,2021-04-21,2020-03-26
-4wb6,2015-01-21,2014-09-02
-8wbx,2023-09-27,2023-09-10
-1wbw,2005-11-03,2004-11-05
-5wbk,2017-12-20,2017-06-29
-2wbe,2009-03-24,2009-02-26
-6wbs,2021-04-07,2020-03-27
-3wbb,2014-03-26,2013-05-14
-5wbu,2017-12-20,2017-06-29
-6wbb,2021-07-07,2020-03-26
-4wbd,2014-12-31,2014-09-03
-6wbf,2020-06-03,2020-03-26
-7wbx,2023-07-05,2021-12-17
-7wb6,2022-06-15,2021-12-15
-2wbk,2009-03-17,2009-03-02
-3wb4,2013-10-02,2013-05-13
-6wba,2021-07-07,2020-03-26
-5wb0,2017-11-22,2017-06-27
-1wbz,2005-01-19,2004-11-05
-2wbd,2009-12-22,2009-02-26
-3wbh,2014-03-12,2013-05-17
-4wbo,2014-11-05,2014-09-03
-3wb2,2014-02-05,2013-05-11
-5wb2,2018-06-13,2017-06-27
-2wbb,2009-12-22,2009-02-26
-4wb3,2015-05-06,2014-09-02
-3wbf,2014-03-26,2013-05-15
-5wb7,2017-10-18,2017-06-28
-6wbm,2020-06-03,2020-03-26
-4wb4,2014-09-24,2014-09-02
-1wb0,2005-01-28,2004-10-29
-6wbq,2020-07-22,2020-03-27
-4wbt,2014-09-24,2014-09-03
-5wbv,2017-07-19,2017-06-29
-1wbg,2005-01-27,2004-11-01
-1wbn,2005-11-03,2004-11-04
-5wbz,2017-09-13,2017-06-29
-5wb3,2018-01-03,2017-06-27
-7wbb,2022-12-28,2021-12-16
-1wbj,2006-05-24,2004-11-01
-5wbb,2017-11-22,2017-06-28
-1wbd,2006-01-18,2004-10-31
-2wbg,2009-04-14,2009-02-27
-7wbm,2022-06-15,2021-12-17
-6wbe,2021-03-17,2020-03-26
-6wb4,2021-04-21,2020-03-26
-5wbn,2017-08-02,2017-06-29
-1wbf,1999-12-22,1998-12-16
-1wbv,2005-11-03,2004-11-05
-7wbz,2022-08-31,2021-12-17
-8wbs,2024-01-31,2023-09-10
-3wb5,2013-10-02,2013-05-13
-7wbu,2022-04-06,2021-12-17
-5wb9,2018-05-23,2017-06-28
-6wbt,2021-03-31,2020-03-27
-3wbw,2014-05-28,2013-05-22
-6wb7,2021-04-21,2020-03-26
-7wb2,2022-05-11,2021-12-15
-7wbi,2022-12-21,2021-12-16
-7wbl,2022-01-19,2021-12-17
-5wbc,2017-08-16,2017-06-28
-4wbu,2015-05-27,2014-09-03
-3wba,2013-09-04,2013-05-14
-6wbh,2020-06-17,2020-03-26
-1wb9,2006-01-18,2004-10-31
-6wbd,2020-04-08,2020-03-26
-2wbj,2009-04-07,2009-03-02
-3wbn,2013-06-12,2013-05-20
-1wbq,2005-09-29,2004-11-05
-2wbw,2009-03-17,2009-03-05
-4wb5,2015-01-21,2014-09-02
-8wbr,2024-01-31,2023-09-10
-6wbx,2020-05-13,2020-03-27
-5wbx,2017-12-20,2017-06-29
-4wbq,2014-12-10,2014-09-03
-2wbf,2009-03-31,2009-02-27
-2wb2,2009-03-17,2009-02-20
-7wb8,2022-06-15,2021-12-15
-1wbt,2005-11-03,2004-11-05
-7wbs,2022-11-02,2021-12-17
-3wby,2014-05-28,2013-05-22
-7wbp,2022-01-19,2021-12-17
-3wb0,2014-02-05,2013-05-10
-7wba,2022-06-15,2021-12-15
-3wbd,2013-10-16,2013-05-14
-7wb9,2022-06-15,2021-12-15
-7wbt,2022-04-06,2021-12-17
-1wb6,2006-05-24,2004-10-30
-7wbo,2022-12-21,2021-12-17
-6wbi,2020-06-03,2020-03-26
-8wb0,2023-12-06,2023-09-08
-1wb8,2004-11-08,2004-10-31
-2wbx,2010-04-21,2009-03-05
-3wbg,2013-10-30,2013-05-16
-6wb8,2020-04-22,2020-03-26
-8wb4,2024-06-05,2023-09-08
-5wbp,2017-09-13,2017-06-29
-6wbw,2020-05-06,2020-03-27
-1wbb,2006-01-18,2004-10-31
-2wbs,2010-04-07,2009-03-03
-4wbg,2015-07-01,2014-09-03
-1wbk,2004-11-04,2004-11-02
-7wb7,2022-06-15,2021-12-15
-5wbr,2017-09-13,2017-06-29
-7wbc,2022-12-21,2021-12-16
-4wbv,2015-05-27,2014-09-03
-2wb0,2010-03-31,2009-02-19
-1wbo,2005-01-27,2004-11-04
-4wb9,2014-12-10,2014-09-02
-2wbt,2010-03-31,2009-03-03
-2wb4,2010-04-21,2009-02-20
-4wbr,2015-09-23,2014-09-03
-5wbo,2017-09-13,2017-06-29
-4wb7,2015-01-21,2014-09-02
-4wbb,2015-05-20,2014-09-02
-5wbe,2017-07-26,2017-06-28
-6wbo,2021-05-05,2020-03-26
-4wb2,2015-05-06,2014-09-02
-2wbo,2009-06-23,2009-03-02
-3wbz,2013-12-18,2013-05-24
-7wb5,2022-10-26,2021-12-15
-1wb4,2005-02-02,2004-10-30
-5wbq,2017-09-13,2017-06-29
-2wb9,2010-03-31,2009-02-23
-6wbj,2020-06-17,2020-03-26
-1wbs,2005-11-03,2004-11-05
-4wbh,2015-02-25,2014-09-03
-8wba,2023-09-27,2023-09-09
-5wbg,2018-05-02,2017-06-29
-5wbj,2017-12-20,2017-06-29
-3wbl,2013-10-30,2013-05-20
-6wbg,2020-06-03,2020-03-26
-1wbu,2005-01-27,2004-11-05
-8wbt,2024-01-31,2023-09-10
-2wbu,2010-04-07,2009-03-05
-8wbu,2023-10-25,2023-09-10
-1wbp,2005-10-19,2004-11-04
-2wbv,2009-03-17,2009-03-05
-5wb6,2017-08-02,2017-06-28
-6wbz,2020-05-06,2020-03-28
-5wb8,2017-10-18,2017-06-28
-6wbn,2020-06-03,2020-03-26
-5wbd,2017-11-22,2017-06-28
-8wb2,2023-12-27,2023-09-08
-1wb7,2004-11-08,2004-10-31
-2wb5,2009-03-31,2009-02-20
-7wbq,2022-01-19,2021-12-17
-7wbw,2023-07-05,2021-12-17
-7wbh,2022-10-26,2021-12-16
-2wba,2009-11-24,2009-02-24
-5wba,2017-11-22,2017-06-28
-2wbq,2009-06-23,2009-03-02
-1wbm,2004-11-04,2004-11-02
-1wbi,2005-10-12,2004-11-01
-5wbm,2017-09-13,2017-06-29
-6wby,2020-05-13,2020-03-27
-8wbv,2023-10-25,2023-09-10
-6wb6,2020-11-25,2020-03-26
-2wby,2009-03-24,2009-03-06
-2wbp,2009-06-23,2009-03-02
-4wb8,2015-01-21,2014-09-02
-7wb3,2022-02-16,2021-12-15
-5wbl,2017-12-20,2017-06-29
-3wbe,2013-09-04,2013-05-14
-6wbv,2020-09-09,2020-03-27
-7wbv,2023-07-05,2021-12-17
-6wbl,2020-06-03,2020-03-26
-2wb1,2009-05-19,2009-02-19
-5j2x,2017-12-06,2016-03-30
-8j27,2024-04-17,2023-04-14
-8j2b,2024-04-17,2023-04-14
-1j2u,2004-01-27,2003-01-11
-4j24,2013-03-13,2013-02-04
-1j2b,2003-05-27,2002-12-29
-5j2g,2016-10-26,2016-03-29
-8j2v,2024-04-17,2023-04-15
-6j2k,2019-10-30,2019-01-01
-4j22,2013-06-26,2013-02-04
-2j2s,2006-08-21,2006-08-17
-3j2p,2012-12-19,2012-11-30
-5j29,2016-10-26,2016-03-29
-8j2f,2023-12-06,2023-04-14
-2j2m,2007-01-16,2006-08-17
-3j27,2012-12-19,2012-09-26
-8j2a,2024-04-17,2023-04-14
-1j2t,2004-01-27,2003-01-11
-5j2f,2016-10-26,2016-03-29
-8j2t,,2023-04-15
-8j2u,2024-04-17,2023-04-15
-1j2c,2003-09-02,2002-12-29
-2j2c,2006-09-19,2006-08-16
-1j2g,2004-06-15,2003-01-05
-1j2y,2003-06-24,2003-01-15
-6j20,2019-03-06,2018-12-30
-4j2d,2014-02-19,2013-02-04
-4j2t,2013-06-19,2013-02-05
-8j2o,2024-04-24,2023-04-14
-1j2o,2003-05-13,2003-01-08
-5j2p,2016-08-03,2016-03-29
-4j2w,2013-04-10,2013-02-05
-5j2u,2016-08-17,2016-03-30
-3j2q,2013-09-11,2012-12-11
-8j20,2024-01-24,2023-04-14
-6j28,2019-06-26,2018-12-31
-6j2v,2020-01-15,2019-01-03
-5j2q,2016-08-03,2016-03-29
-2j25,2006-12-06,2006-08-16
-6j2i,2019-09-18,2019-01-01
-4j2x,2013-11-06,2013-02-05
-1j21,2003-04-22,2002-12-24
-5j2b,2016-10-26,2016-03-29
-1j2j,2003-05-06,2003-01-05
-4j2m,2013-07-24,2013-02-04
-1j25,2003-04-22,2002-12-25
-6j2s,2020-01-01,2019-01-02
-2j27,2007-01-02,2006-08-16
-4j2o,2013-04-17,2013-02-05
-1j2e,2003-12-30,2002-12-30
-2j20,2006-09-20,2006-08-15
-8j2p,2023-09-20,2023-04-15
-8j2s,,2023-04-15
-5j2s,2017-10-11,2016-03-30
-2j2p,2007-01-23,2006-08-17
-5j2c,2016-10-26,2016-03-29
-5j2i,2016-10-26,2016-03-29
-2j2z,2006-11-08,2006-08-17
-6j2p,2019-09-11,2019-01-02
-8j2d,2024-04-17,2023-04-14
-6j21,2019-03-06,2018-12-30
-6j24,2019-05-01,2018-12-30
-3j25,2012-10-17,2012-08-22
-8j2e,2024-04-17,2023-04-14
-6j2h,2019-09-18,2019-01-01
-4j2a,2014-02-19,2013-02-04
-1j24,2003-04-22,2002-12-25
-5j2z,2017-10-04,2016-03-30
-5j23,2016-04-13,2016-03-29
-5j2h,2016-10-26,2016-03-29
-5j2k,2016-10-26,2016-03-29
-6j2m,2019-12-04,2019-01-01
-2j2i,2007-02-13,2006-08-16
-4j2b,2014-02-19,2013-02-04
-8j2h,2023-12-13,2023-04-14
-5j2t,2016-08-17,2016-03-30
-6j2f,2019-09-18,2019-01-01
-8j2m,2023-11-22,2023-04-14
-4j28,2013-05-08,2013-02-04
-6j2j,2019-09-18,2019-01-01
-2j2u,2006-09-27,2006-08-17
-8j26,2023-06-21,2023-04-14
-5j2r,2016-05-04,2016-03-29
-3j2t,2013-04-10,2012-12-23
-4j20,2013-10-02,2013-02-04
-6j23,2019-02-27,2018-12-30
-5j28,2016-10-05,2016-03-29
-6j27,2019-06-26,2018-12-31
-5j2m,2016-08-03,2016-03-29
-6j2a,2019-09-25,2018-12-31
-5j2e,2016-10-26,2016-03-29
-2j28,2006-11-08,2006-08-16
-4j2s,2013-11-20,2013-02-05
-8j22,2024-01-24,2023-04-14
-4j25,2014-02-05,2013-02-04
-8j2x,2024-04-10,2023-04-15
-8j2w,2024-04-10,2023-04-15
-4j2e,2014-02-19,2013-02-04
-5j2d,2016-10-26,2016-03-29
-6j2b,2019-10-30,2018-12-31
-2j2f,2006-10-23,2006-08-16
-4j2h,2013-05-01,2013-02-04
-5j2j,2016-10-26,2016-03-29
-5j27,2017-12-06,2016-03-29
-2j22,2006-09-06,2006-08-15
-4j2v,2013-07-24,2013-02-05
-8j28,2024-04-17,2023-04-14
-6j29,2019-09-25,2018-12-31
-5j20,2017-12-06,2016-03-29
-6j2u,2020-02-12,2019-01-03
-1j20,2003-04-22,2002-12-24
-1j2x,2003-01-30,2003-01-15
-6j2o,2019-10-30,2019-01-02
-8j2y,2024-04-10,2023-04-15
-6j2l,2020-01-01,2019-01-01
-1j2q,2003-03-18,2003-01-08
-4j26,2013-03-13,2013-02-04
-4j21,2013-06-26,2013-02-04
-5j2n,2016-08-03,2016-03-29
-8j25,2023-09-20,2023-04-14
-8j21,2024-01-24,2023-04-14
-2j21,2006-09-20,2006-08-15
-8j2l,2023-12-13,2023-04-14
-5j22,2016-04-06,2016-03-29
-6j26,2019-06-26,2018-12-31
-6j2d,2019-09-18,2019-01-01
-5j25,2017-04-05,2016-03-29
-5j2a,2016-10-26,2016-03-29
-8acp,2022-10-19,2022-07-06
-6aco,2019-07-24,2018-07-26
-4acc,2012-05-16,2011-12-14
-8ac8,2023-09-27,2022-07-05
-2acu,1994-07-31,1994-04-15
-5acr,2015-12-23,2015-08-17
-8aca,2023-04-12,2022-07-05
-6ac0,2019-05-01,2018-07-24
-3aca,2011-01-12,2009-12-30
-4ac7,2013-01-16,2011-12-14
-5acb,2016-06-15,2015-08-14
-4aci,2012-12-26,2011-12-15
-8acc,2023-05-17,2022-07-05
-2acl,2005-09-20,2005-07-19
-7acx,2022-03-09,2020-09-11
-8acb,2023-05-17,2022-07-05
-8ac2,2022-10-19,2022-07-05
-4acl,2012-04-25,2011-12-16
-8ac0,2022-10-19,2022-07-05
-2acz,2006-01-03,2005-07-19
-7ac2,2021-09-01,2020-09-09
-3ac3,2010-06-30,2009-12-28
-5aco,2015-09-30,2015-08-17
-5ac0,2015-08-26,2015-08-10
-7ac5,2021-09-01,2020-09-10
-5acp,2015-12-23,2015-08-17
-2ac7,2006-07-18,2005-07-18
-5acc,2015-12-16,2015-08-15
-3acf,2010-03-02,2010-01-04
-4ac1,2012-08-22,2011-12-12
-3acy,2010-11-24,2010-01-13
-2ack,1998-02-11,1997-10-29
-7ac4,2021-09-01,2020-09-09
-1acj,1994-08-31,1993-08-18
-5acj,2016-03-02,2015-08-17
-6ac2,2019-07-31,2018-07-24
-3ac8,2010-06-30,2009-12-29
-3acw,2010-11-24,2010-01-13
-8acu,2023-07-19,2022-07-06
-6acb,2018-09-19,2018-07-26
-5acw,2015-11-04,2015-08-18
-8ac1,2022-10-26,2022-07-05
-5acu,2015-11-04,2015-08-18
-2ach,1993-07-15,1993-04-26
-6ac1,2019-07-31,2018-07-24
-5ac5,2015-09-23,2015-08-11
-2acs,1994-07-31,1994-04-15
-6ach,2018-12-26,2018-07-26
-8aci,2024-01-17,2022-07-05
-6acr,2019-03-20,2018-07-27
-1ac5,1997-05-15,1997-02-13
-7acq,2020-11-18,2020-09-11
-7acp,2021-10-06,2020-09-11
-4act,2012-12-05,2011-12-19
-2ac3,2005-10-04,2005-07-18
-2ac1,2006-08-29,2005-07-18
-3ac5,2010-06-30,2009-12-28
-7acr,2021-08-18,2020-09-11
-2acw,2005-11-15,2005-07-19
-7acs,2020-11-04,2020-09-11
-4ac4,2012-12-26,2011-12-13
-8acs,2022-09-07,2022-07-06
-8acm,2023-11-29,2022-07-05
-4acg,2012-05-16,2011-12-15
-3acl,2010-08-18,2010-01-05
-4ac2,2012-09-26,2011-12-12
-6acx,2019-08-28,2018-07-27
-3ac1,2010-06-30,2009-12-28
-4acp,2012-04-25,2011-12-16
-1ac4,1997-09-04,1997-02-12
-7aca,2020-11-18,2020-09-10
-3acs,2010-12-22,2010-01-08
-8ac5,2023-01-11,2022-07-05
-4acr,2012-02-22,2011-12-17
-5ac2,2015-08-26,2015-08-11
-1acl,1994-08-31,1993-08-18
-5acl,2015-12-02,2015-08-17
-4acs,2011-12-28,2011-12-19
-3act,2010-12-22,2010-01-08
-8acy,2023-07-12,2022-07-07
-7ac6,2021-09-01,2020-09-10
-8acw,2023-07-12,2022-07-07
-8aco,2023-11-29,2022-07-05
-3acg,2010-03-02,2010-01-04
-7ack,2021-03-24,2020-09-11
-8acf,2024-01-17,2022-07-05
-6ac4,2019-08-28,2018-07-25
-2ace,1996-11-08,1996-06-23
-2acx,2006-04-25,2005-07-19
-3ack,2010-06-30,2010-01-05
-6acl,2019-07-24,2018-07-26
-3acj,2010-06-30,2010-01-05
-4ach,2012-05-16,2011-12-15
-7ac8,2021-05-19,2020-09-10
-8ack,2023-07-12,2022-07-05
-5ac1,2015-08-26,2015-08-11
-7acc,2020-12-09,2020-09-10
-5acy,2015-10-07,2015-08-18
-4acx,2012-02-29,2011-12-20
-4ac8,2012-09-26,2011-12-14
-8acg,2023-07-12,2022-07-05
-6acp,2019-07-24,2018-07-26
-5acv,2015-11-04,2015-08-18
-8act,2023-06-07,2022-07-06
-5acg,2016-03-02,2015-08-17
-5acq,2015-12-23,2015-08-17
-4aca,2012-11-07,2011-12-14
-5ach,2016-03-02,2015-08-17
-4ac5,2012-02-15,2011-12-14
-5aci,2016-03-02,2015-08-17
-1acc,1998-02-11,1997-02-05
-7ach,2020-11-18,2020-09-10
-5act,2015-12-23,2015-08-17
-6aci,2019-05-01,2018-07-26
-3ach,2010-03-02,2010-01-04
-4ac6,2012-12-26,2011-12-14
-8ac7,2023-07-12,2022-07-05
-8ac3,2023-01-11,2022-07-05
-4acu,2012-02-29,2011-12-19
-7acj,2021-08-18,2020-09-11
-5ack,2015-10-21,2015-08-17
-1ac8,1997-09-04,1997-02-14
-8acl,2022-09-28,2022-07-05
-4ac9,2012-08-22,2011-12-14
-3acd,2010-02-09,2009-12-30
-1aca,1994-01-31,1992-11-17
-3ac4,2010-06-30,2009-12-28
-3aci,2010-03-31,2010-01-04
-6ace,2019-07-24,2018-07-26
-2acp,2006-06-27,2005-07-19
-8acd,2022-09-28,2022-07-05
-5ac7,2016-09-28,2015-08-12
-1acm,1992-07-15,1992-07-08
-3acx,2010-11-24,2010-01-13
-4acm,2012-05-16,2011-12-16
-8ac9,2023-07-12,2022-07-05
-6acn,1990-07-15,1990-01-16
-2ac2,2005-09-20,2005-07-18
-8ac4,2023-01-11,2022-07-05
-4acb,2012-11-07,2011-12-14
-4acd,2012-05-16,2011-12-15
-6ac5,2019-05-01,2018-07-25
-5acs,2015-12-23,2015-08-17
-7acd,2020-10-28,2020-09-10
-2acr,1994-07-31,1994-04-15
-5ac4,2015-09-23,2015-08-11
-6ac9,2018-12-26,2018-07-25
-3ac2,2010-06-30,2009-12-28
-5acz,2016-09-28,2015-08-19
-2acq,1994-07-31,1994-04-15
-7acg,2020-12-16,2020-09-10
-7ac3,2021-09-01,2020-09-09
-2ac0,2006-07-11,2005-07-18
-7ac9,2021-10-06,2020-09-10
-3acc,2010-02-09,2009-12-30
-5acn,1990-07-15,1990-01-16
-5acf,2016-03-02,2015-08-17
-5acx,2015-11-04,2015-08-18
-7acf,2020-11-18,2020-09-10
-5acm,2015-12-02,2015-08-17
-4ac3,2012-02-15,2011-12-12
-4acf,2012-10-24,2011-12-15
-8acr,2023-07-12,2022-07-06
-7ac7,2021-08-18,2020-09-10
-8acn,1993-10-31,1991-05-15
-4ac0,2012-12-26,2011-12-12
-8acv,2022-11-02,2022-07-07
-8acq,2023-04-12,2022-07-06
-3ac9,2011-01-12,2009-12-30
-2ac5,2005-10-04,2005-07-18
-2acv,2005-11-15,2005-07-19
-7acu,2020-10-28,2020-09-11
-1acz,1997-07-07,1997-02-10
-3ac0,2010-08-11,2009-12-25
-1ac0,1997-07-07,1997-02-10
-7acm,2021-08-18,2020-09-11
-5ac3,2016-07-20,2015-08-11
-3aco,2010-04-14,2010-01-07
-7wcn,2022-12-21,2021-12-20
-7wcd,2022-08-10,2021-12-19
-8wco,2024-05-15,2023-09-13
-6wca,2020-04-15,2020-03-30
-4wcf,2015-09-23,2014-09-04
-2wcj,2009-08-11,2009-03-12
-6wce,2021-08-25,2020-03-30
-5wcx,2018-07-11,2017-07-02
-3wcz,2014-01-01,2013-06-05
-4wc7,2015-04-15,2014-09-04
-8wc9,2023-12-27,2023-09-11
-5wc5,2017-12-20,2017-06-29
-4wck,2014-12-24,2014-09-05
-2wc0,2009-03-24,2009-03-06
-1wcm,2004-12-14,2004-11-17
-6wco,2020-08-05,2020-03-30
-6wcv,2020-07-15,2020-03-31
-1wc1,2004-12-20,2004-11-06
-7wcc,2023-05-24,2021-12-19
-7wc6,2022-01-26,2021-12-18
-1wci,2006-02-16,2004-11-16
-2wcv,2009-11-10,2009-03-17
-2wcf,2009-06-23,2009-03-11
-3wcb,2014-06-18,2013-05-27
-6wc9,2020-04-15,2020-03-30
-6wct,2020-04-08,2020-03-31
-7wc9,2022-01-26,2021-12-18
-2wcx,2009-08-18,2009-03-17
-2wcu,2009-11-10,2009-03-17
-7wct,2022-03-30,2021-12-20
-5wcr,2019-01-23,2017-07-01
-8wc3,2023-12-27,2023-09-11
-5wcz,2018-03-28,2017-07-03
-2wcl,2009-08-11,2009-03-12
-1wc5,2004-12-20,2004-11-08
-2wc5,2009-08-11,2009-03-09
-2wc9,2009-03-24,2009-03-10
-5wcw,2019-01-23,2017-07-02
-5wcl,2017-07-19,2017-06-30
-4wc5,2015-04-15,2014-09-04
-5wc4,2017-12-13,2017-06-29
-3wc5,2013-10-02,2013-05-24
-3wcm,2014-06-18,2013-05-28
-7wcw,2022-03-30,2021-12-20
-2wch,2009-08-11,2009-03-12
-3wc7,2013-10-02,2013-05-24
-3wc3,2013-10-30,2013-05-24
-8wcn,2024-03-13,2023-09-13
-4wch,2015-06-10,2014-09-04
-2wco,2010-08-18,2009-03-12
-5wcj,2017-07-19,2017-06-30
-2wcm,2009-08-11,2009-03-12
-4wcw,2014-09-24,2014-09-05
-5wcb,2017-08-09,2017-06-29
-7wca,2022-12-21,2021-12-18
-3wcc,2014-06-18,2013-05-27
-2wc8,2009-06-23,2009-03-10
-8wce,2024-05-22,2023-09-11
-6wcc,2020-04-15,2020-03-30
-1wcq,2005-10-12,2004-11-19
-6wcn,2021-03-31,2020-03-30
-4wcc,2015-09-23,2014-09-04
-5wcq,2018-07-04,2017-07-01
-7wcm,2022-12-21,2021-12-20
-3wct,2014-06-04,2013-06-01
-3wcr,2014-04-09,2013-05-31
-6wc6,2021-06-30,2020-03-29
-5wcn,2017-08-02,2017-06-30
-7wcq,2022-11-02,2021-12-20
-2wcr,2009-05-12,2009-03-13
-1wcb,2006-03-03,2004-11-12
-2wck,2009-08-11,2009-03-12
-5wcf,2017-08-02,2017-06-30
-7wcx,2022-03-30,2021-12-20
-7wc5,2022-01-26,2021-12-18
-1wcc,2005-01-27,2004-11-12
-7wcv,2022-07-06,2021-12-20
-4wcj,2014-11-12,2014-09-04
-6wcm,2021-03-31,2020-03-30
-2wca,2009-06-16,2009-03-10
-3wcv,2014-06-04,2013-06-01
-4wc2,2015-04-15,2014-09-04
-2wc1,2010-04-21,2009-03-06
-3wca,2014-06-18,2013-05-26
-4wc0,2015-04-15,2014-09-04
-7wce,2022-09-07,2021-12-20
-6wcw,2020-07-01,2020-03-31
-3wc8,2013-12-11,2013-05-25
-1wcz,2004-06-01,2004-05-10
-4wcl,2014-12-24,2014-09-05
-6wcb,2020-04-15,2020-03-30
-1wc3,2004-12-20,2004-11-08
-6wcp,2021-03-31,2020-03-31
-4wcm,2014-12-24,2014-09-05
-5wct,2018-01-03,2017-07-01
-5wcg,2017-08-02,2017-06-30
-1wc7,2005-11-30,2004-11-09
-4wc6,2015-04-15,2014-09-04
-5wch,2018-07-04,2017-06-30
-3wcf,2014-06-18,2013-05-27
-2wce,2009-06-23,2009-03-11
-7wci,2022-12-21,2021-12-20
-7wc8,2022-01-26,2021-12-18
-4wcu,2014-10-08,2014-09-05
-4wc1,2015-04-15,2014-09-04
-2wcg,2009-11-24,2009-03-12
-6wcl,2021-03-31,2020-03-30
-3wcj,2014-06-18,2013-05-27
-3wc6,2013-10-02,2013-05-24
-8wc8,2023-12-27,2023-09-11
-7wc3,2022-12-21,2021-12-18
-5wc0,2017-08-09,2017-06-29
-8wc4,2023-12-27,2023-09-11
-5wcp,2019-01-23,2017-07-01
-3wcs,2014-04-09,2013-05-31
-1wcf,2006-07-12,2004-11-13
-1wc4,2004-12-20,2004-11-08
-2wc3,2009-04-14,2009-03-08
-7wc4,2022-01-26,2021-12-18
-2wcp,2010-04-21,2009-03-13
-4wc4,2015-04-15,2014-09-04
-4wcg,2015-11-18,2014-09-04
-1wco,2005-03-07,2004-11-19
-3wcu,2014-06-04,2013-06-01
-2wci,2009-06-23,2009-03-12
-4wcn,2014-12-24,2014-09-05
-6wcr,2020-08-05,2020-03-31
-3wc9,2014-06-18,2013-05-26
-6wcd,2020-05-06,2020-03-30
-6wcg,2021-03-31,2020-03-30
-6wcz,2020-07-08,2020-03-31
-3wcp,2013-06-26,2013-05-30
-7wcy,2022-12-28,2021-12-20
-8wc7,2023-12-27,2023-09-11
-4wcd,2015-09-30,2014-09-04
-1wcy,2005-05-07,2004-05-07
-3wcd,2014-06-18,2013-05-27
-1wc6,2004-12-20,2004-11-08
-7wcf,2022-06-29,2021-12-20
-6wcx,2020-09-16,2020-03-31
-2wc6,2009-08-11,2009-03-09
-3wc0,2013-12-18,2013-05-24
-6wch,2021-03-31,2020-03-30
-7wc2,2022-11-02,2021-12-18
-7wc7,2022-01-26,2021-12-18
-2wcb,2009-06-23,2009-03-10
-4wco,2015-06-24,2014-09-05
-4wct,2016-02-17,2014-09-05
-5wcs,2018-01-03,2017-07-01
-7wcl,2022-09-14,2021-12-20
-3wce,2014-06-18,2013-05-27
-3wcw,2014-06-04,2013-06-01
-1wc0,2004-12-20,2004-11-05
-4wcx,2015-02-04,2014-09-05
-6wc8,2021-03-31,2020-03-29
-5wcm,2017-07-19,2017-06-30
-8wca,2023-12-27,2023-09-11
-8wc6,2023-12-27,2023-09-11
-1wct,1999-06-08,1998-12-18
-2wc4,2009-04-14,2009-03-08
-3wch,2014-06-18,2013-05-27
-5wci,2017-07-26,2017-06-30
-4wce,2015-10-21,2014-09-04
-5wc2,2018-04-25,2017-06-29
-2hrg,2007-09-11,2006-07-20
-6hrt,2019-03-20,2018-09-28
-1hr0,2001-01-24,2000-12-20
-5hrt,2016-04-06,2016-01-24
-8hrq,2023-12-06,2022-12-15
-6hrg,2019-10-09,2018-09-26
-5hrw,2016-10-12,2016-01-24
-4hr6,2013-08-07,2012-10-26
-4hri,2013-04-17,2012-10-28
-8hr5,2023-09-06,2022-12-14
-3hrd,2009-06-30,2009-06-09
-6hrr,2019-06-19,2018-09-28
-8hr8,2023-02-01,2022-12-15
-6hry,2019-02-27,2018-09-28
-1hrv,1995-06-03,1995-03-02
-5hrl,2017-01-18,2016-01-23
-5hru,2016-10-19,2016-01-24
-2hr6,2007-07-31,2006-07-19
-6hrx,2019-02-27,2018-09-28
-2hrq,2007-05-01,2006-07-20
-3hrc,2009-09-15,2009-06-09
-2hrv,2000-05-03,1999-04-29
-5hrr,2016-12-14,2016-01-24
-8hrr,2023-12-06,2022-12-15
-5hr4,2016-04-27,2016-01-22
-2hrr,2007-05-01,2006-07-20
-6hri,2018-10-10,2018-09-27
-8hr6,2024-03-20,2022-12-14
-6hrw,2019-02-27,2018-09-28
-6hra,2018-12-05,2018-09-26
-4hry,2013-02-27,2012-10-29
-6hrz,2019-02-27,2018-09-28
-6hr5,2019-06-26,2018-09-26
-1hri,1993-10-31,1992-10-01
-2hr1,2006-09-19,2006-07-19
-4hrc,2014-01-29,2012-10-27
-3hrz,2009-07-07,2009-06-10
-5hrd,2017-01-18,2016-01-23
-6hrk,2019-10-09,2018-09-27
-6hr8,2019-02-13,2018-09-26
-2hrw,2006-10-03,2006-07-20
-8hr0,2023-12-20,2022-12-14
-5hrf,2017-01-18,2016-01-23
-8hrz,2023-12-20,2022-12-16
-4hro,2013-10-30,2012-10-28
-8hrs,2023-12-06,2022-12-15
-1hry,1995-09-15,1995-05-09
-4hr3,2012-11-14,2012-10-26
-3hr5,2010-05-19,2009-06-08
-2hry,2007-01-09,2006-07-20
-1hrk,2001-06-22,2000-12-21
-8hrt,2023-12-06,2022-12-15
-4hr0,2013-10-16,2012-10-26
-5hr2,2017-02-22,2016-01-22
-6hrj,2018-10-10,2018-09-27
-5hrc,2016-04-20,2016-01-23
-1hrm,1995-01-26,1994-09-21
-4hrw,2013-06-19,2012-10-29
-5hrh,2017-01-18,2016-01-23
-5hrs,2016-12-14,2016-01-24
-5hrx,2016-10-12,2016-01-24
-3hr6,2009-09-15,2009-06-08
-1hrc,1994-11-01,1994-08-16
-1hrn,1995-06-03,1995-03-31
-6hrl,2018-10-17,2018-09-27
-8hr9,2023-02-01,2022-12-15
-2hrf,2007-01-16,2006-07-20
-5hrg,2017-01-18,2016-01-23
-3hrf,2009-09-15,2009-06-09
-2hrm,2007-07-31,2006-07-20
-4hr2,2012-11-07,2012-10-26
-5hr6,2016-04-13,2016-01-22
-5hr9,2017-01-18,2016-01-23
-1hra,1994-01-31,1993-07-25
-4hra,2013-07-31,2012-10-26
-6hr2,2019-06-12,2018-09-26
-1hr9,2001-07-11,2000-12-21
-4hr4,2013-10-16,2012-10-26
-4hrh,2013-03-06,2012-10-27
-5hrm,2016-07-13,2016-01-23
-1hr7,2001-07-11,2000-12-21
-5hrk,2017-01-18,2016-01-23
-5hr5,2016-11-16,2016-01-22
-4hrq,2013-06-19,2012-10-28
-3hr9,2009-07-07,2009-06-09
-5hr1,2017-02-22,2016-01-22
-8hrf,2023-12-20,2022-12-15
-8hrh,2023-08-30,2022-12-15
-2hrd,2007-07-24,2006-07-20
-2hrs,2008-04-08,2006-07-20
-2hrp,1997-12-31,1996-12-27
-5hro,2016-06-01,2016-01-23
-5hrq,2017-01-25,2016-01-24
-2hr5,2006-10-17,2006-07-19
-3hru,2009-06-23,2009-06-09
-3hr1,2009-08-04,2009-06-08
-6hr7,2019-02-13,2018-09-26
-6hrp,2019-03-20,2018-09-28
-3hrb,2009-09-01,2009-06-09
-5hr3,2017-02-22,2016-01-22
-2hrh,2007-09-11,2006-07-20
-2hrb,2006-08-08,2006-07-20
-6hrh,2018-11-07,2018-09-27
-8hra,2023-02-01,2022-12-15
-8hrd,2023-12-20,2022-12-15
-6hr3,2019-10-09,2018-09-26
-3hrk,2009-12-01,2009-06-09
-6hrc,2019-03-06,2018-09-26
-8hro,2023-12-06,2022-12-15
-5hri,2017-01-18,2016-01-23
-4hrg,2013-03-06,2012-10-27
-1hrs,1994-05-31,1993-11-05
-5hre,2017-01-18,2016-01-23
-6hr6,2019-10-23,2018-09-26
-6hrb,2018-12-05,2018-09-26
-6hr1,2020-04-08,2018-09-26
-6hrq,2018-10-31,2018-09-28
-4hrd,2014-01-29,2012-10-27
-2hr7,2006-08-15,2006-07-19
-5hrb,2017-01-18,2016-01-23
-6hr9,2019-10-23,2018-09-26
-8hrv,2024-01-17,2022-12-16
-5hrv,2016-10-12,2016-01-24
-5hra,2016-04-20,2016-01-23
-1hro,1997-01-11,1996-07-10
-8hrp,2023-12-06,2022-12-15
-2hrn,2007-01-16,2006-07-20
-4hre,2013-03-06,2012-10-27
-5hrn,2016-12-14,2016-01-23
-6hro,2019-02-27,2018-09-27
-1hrz,1995-09-15,1995-05-09
-2hre,2007-03-13,2006-07-20
-3hr4,2009-09-08,2009-06-08
-6hrm,2018-12-19,2018-09-27
-8hrb,2023-02-01,2022-12-15
-6hrn,2019-06-05,2018-09-27
-2hrc,2007-03-13,2006-07-20
-2hr8,2007-01-20,2006-07-20
-4hrt,2012-12-12,2012-10-28
-3hrw,2009-06-23,2009-06-10
-1hrp,1994-11-01,1994-08-15
-3hrr,2009-10-20,2009-06-09
-5hr7,2016-04-13,2016-01-22
-6hr0,2019-10-16,2018-09-26
-4hrr,2013-03-13,2012-10-28
-1hr8,2001-07-11,2000-12-21
-5hr0,2017-02-22,2016-01-22
-1hr6,2001-07-11,2000-12-21
-3hrt,2009-06-23,2009-06-09
-2hrl,2006-08-15,2006-07-20
-5hrp,2016-12-14,2016-01-24
-2hru,2007-01-09,2006-07-20
-6a5u,2018-10-03,2018-06-25
-8a5w,2023-03-29,2022-06-16
-1a5u,1999-03-02,1998-02-18
-1a5i,1999-03-23,1998-02-17
-7a5l,2021-06-30,2020-08-21
-8a5c,2022-08-03,2022-06-14
-4a5r,2012-10-10,2011-10-28
-6a59,2019-06-26,2018-06-22
-2a5t,2005-11-15,2005-06-30
-8a5z,2023-03-08,2022-06-16
-3a5c,2009-10-13,2009-08-06
-2a5y,2005-10-11,2005-07-01
-3a5g,2010-02-09,2009-08-06
-4a52,2012-05-30,2011-10-24
-8a5m,2022-07-06,2022-06-15
-8a5b,2023-07-05,2022-06-14
-1a53,1999-03-23,1998-02-19
-3a58,2010-01-12,2009-08-03
-6a5l,2018-10-03,2018-06-24
-8a5q,2022-12-14,2022-06-15
-6a5d,2019-06-26,2018-06-23
-2a5c,2006-05-23,2005-06-30
-2a59,2005-07-19,2005-06-30
-1a5b,1998-05-27,1998-02-12
-1a5v,1998-05-27,1998-02-18
-5a5e,2016-04-13,2015-06-17
-7a5o,2020-10-21,2020-08-21
-6a58,2019-06-26,2018-06-22
-6a57,2019-06-26,2018-06-22
-7a5e,2021-02-03,2020-08-21
-6a52,2018-08-29,2018-06-21
-4a51,2012-10-31,2011-10-24
-7a51,2021-06-30,2020-08-20
-8a52,2023-12-27,2022-06-14
-4a59,2011-11-30,2011-10-24
-5a55,2015-09-02,2015-06-16
-6a5x,2018-10-10,2018-06-25
-2a5i,2005-10-25,2005-06-30
-7a5v,2020-11-18,2020-08-22
-5a5v,2016-07-06,2015-06-22
-3a5b,2010-02-09,2009-08-05
-6a54,2019-02-20,2018-06-21
-2a5j,2005-07-19,2005-06-30
-5a5o,2015-07-22,2015-06-20
-1a5o,1998-05-27,1998-02-17
-7a5j,2020-12-23,2020-08-21
-2a51,2006-06-20,2005-06-30
-6a56,2018-07-25,2018-06-22
-6a5s,2019-02-13,2018-06-25
-8a5l,2022-07-06,2022-06-15
-4a5l,2012-10-31,2011-10-25
-5a5z,2015-07-08,2015-06-23
-7a5a,2021-10-06,2020-08-20
-6a5o,2018-10-03,2018-06-25
-5a5i,2016-08-24,2015-06-18
-4a5s,2012-02-08,2011-10-28
-6a5n,2018-08-29,2018-06-24
-4a5w,2012-03-14,2011-10-28
-1a5s,1999-03-30,1998-02-17
-1a52,1998-09-16,1998-02-19
-3a5o,2010-10-27,2009-08-09
-3a5n,2010-10-27,2009-08-09
-5a5y,2015-08-05,2015-06-23
-5a5g,2016-07-06,2015-06-17
-7a5s,2020-09-16,2020-08-21
-2a5v,2005-09-20,2005-07-01
-2a5s,2005-11-15,2005-06-30
-2a5l,2005-07-12,2005-06-30
-5a5a,2015-09-02,2015-06-16
-8a5a,2022-12-14,2022-06-14
-7a5n,2021-06-30,2020-08-21
-5a5n,2015-07-22,2015-06-20
-2a5g,2005-08-16,2005-06-30
-7a5x,2020-11-18,2020-08-24
-6a5m,2018-08-29,2018-06-24
-5a51,2016-03-02,2015-06-16
-3a5a,2010-02-09,2009-08-05
-5a5k,2016-06-29,2015-06-18
-7a5b,2021-06-30,2020-08-20
-6a5e,2019-06-26,2018-06-23
-2a5b,2006-05-23,2005-06-30
-8a5r,2023-07-05,2022-06-15
-7a5h,2020-12-23,2020-08-21
-5a5s,2015-07-22,2015-06-20
-1a5n,1998-05-27,1998-02-17
-8a5e,2023-02-22,2022-06-14
-3a59,2009-08-18,2009-08-03
-5a5j,2016-08-03,2015-06-18
-6a5z,2018-10-10,2018-06-25
-7a5k,2020-12-23,2020-08-21
-8a5j,2022-07-13,2022-06-15
-8a57,2022-11-02,2022-06-14
-3a50,2010-07-28,2009-07-24
-6a5k,2018-08-29,2018-06-24
-4a5g,2012-11-07,2011-10-25
-1a5z,1999-03-23,1998-02-18
-4a55,2011-12-28,2011-10-24
-6a5q,2019-02-13,2018-06-25
-5a5f,2016-04-13,2015-06-17
-2a58,2005-07-19,2005-06-30
-8a56,2022-09-14,2022-06-14
-2a57,2005-07-19,2005-06-30
-8a5n,2023-02-08,2022-06-15
-2a5h,2005-10-04,2005-06-30
-2a5u,2005-09-20,2005-07-01
-7a5z,2021-02-24,2020-08-24
-8a5o,2022-12-14,2022-06-15
-3a5v,2009-08-25,2009-08-12
-7a5f,2020-12-23,2020-08-21
-7a5m,2020-10-07,2020-08-21
-8a58,2023-04-26,2022-06-14
-5a5q,2015-07-22,2015-06-20
-5a5l,2015-10-14,2015-06-19
-8a5x,2022-10-05,2022-06-16
-1a56,1998-10-21,1998-02-20
-7a59,2021-10-06,2020-08-20
-7a56,2021-09-01,2020-08-20
-8a5v,2023-03-29,2022-06-16
-5a5w,2015-09-02,2015-06-23
-1a5t,1998-05-27,1998-02-18
-1a50,1999-03-30,1998-02-18
-4a50,2012-10-31,2011-10-24
-8a5i,2022-11-02,2022-06-15
-5a54,2016-06-29,2015-06-16
-7a5d,2021-06-30,2020-08-21
-3a5y,2010-08-25,2009-08-17
-5a5p,2015-07-22,2015-06-20
-4a5a,2011-11-30,2011-10-24
-1a5w,1998-05-27,1998-02-18
-1a59,1999-03-30,1998-02-20
-2a5d,2005-08-16,2005-06-30
-2a5x,2005-08-23,2005-07-01
-7a55,2021-06-30,2020-08-20
-5a57,2015-09-02,2015-06-16
-2a5f,2005-08-16,2005-06-30
-3a51,2010-07-28,2009-07-24
-6a5y,2018-10-10,2018-06-25
-5a52,2016-03-02,2015-06-16
-6a5p,2018-10-03,2018-06-25
-8a5f,2022-08-03,2022-06-15
-7a5q,2020-12-30,2020-08-21
-7a54,2020-11-18,2020-08-20
-8a5y,2022-08-31,2022-06-16
-7a5i,2020-12-23,2020-08-21
-7a5r,2020-09-16,2020-08-21
-5a50,2016-03-02,2015-06-16
-6a5w,2018-10-10,2018-06-25
-1a54,1998-10-14,1998-02-19
-1a5a,1998-05-27,1998-02-12
-6a55,2019-02-20,2018-06-21
-7a5g,2020-12-23,2020-08-21
-2a5z,2005-08-16,2005-07-01
-3a5l,2010-10-27,2009-08-09
-3a52,2010-04-14,2009-07-24
-7a52,2021-06-30,2020-08-20
-3a5m,2010-10-27,2009-08-09
-6a5r,2018-10-03,2018-06-25
-5a56,2015-09-02,2015-06-16
-3a5z,2010-08-25,2009-08-17
-4a5y,2012-11-07,2011-10-29
-3a5r,2010-01-26,2009-08-10
-1a5h,1999-04-20,1998-02-17
-5a5d,2016-06-29,2015-06-17
-7a5y,2021-05-26,2020-08-24
-8a5s,2023-07-05,2022-06-15
-8a5k,2023-07-05,2022-06-15
-6a53,2019-02-20,2018-06-21
-8a5d,2022-12-28,2022-06-14
-3a5j,2010-08-11,2009-08-08
-8a5p,2022-12-14,2022-06-15
-6a5t,2018-10-03,2018-06-25
-1a5g,1998-05-27,1998-02-16
-5a58,2015-09-02,2015-06-16
-6a50,2019-02-20,2018-06-21
-3a5k,2010-08-11,2009-08-08
-4a5t,2012-05-23,2011-10-28
-7a53,2021-06-30,2020-08-20
-1a5x,1998-05-27,1998-02-18
-7a57,2021-09-01,2020-08-20
-8a5u,2022-08-10,2022-06-16
-5a59,2015-09-02,2015-06-16
-5a5r,2015-07-22,2015-06-20
-2a5k,2005-10-25,2005-06-30
-5lva,2016-10-19,2016-09-13
-1lvw,2003-07-29,2002-05-29
-7lv2,2021-03-17,2021-02-23
-3lvm,2010-04-21,2010-02-22
-5lvx,2017-10-25,2016-09-14
-4lvp,2013-09-11,2013-07-26
-5lvv,2017-07-12,2016-09-14
-7lv1,2022-03-02,2021-02-23
-1lva,2002-08-21,2002-05-28
-4lvh,2014-04-09,2013-07-26
-3lv5,2010-06-16,2010-02-19
-3lvk,2010-04-21,2010-02-22
-6lv1,2020-08-19,2020-02-02
-4lv1,2014-07-30,2013-07-25
-5lv3,2017-09-20,2016-09-12
-7lv4,2022-03-02,2021-02-23
-6lvb,2020-06-03,2020-02-02
-2lvk,2012-10-03,2012-07-05
-3lvq,2010-06-09,2010-02-22
-6lva,2020-08-19,2020-02-02
-7lvb,2022-03-02,2021-02-24
-6lvx,2020-11-11,2020-02-06
-3lvj,2010-04-21,2010-02-22
-4lvj,2014-09-24,2013-07-26
-1lv5,2003-03-25,2002-05-24
-4lvb,2013-09-25,2013-07-26
-1lvu,2003-09-02,2002-05-29
-6lv2,2020-08-19,2020-02-02
-4lvi,2014-09-24,2013-07-26
-5lvn,2016-10-19,2016-09-14
-6lv9,2020-08-19,2020-02-02
-7lv5,2022-03-02,2021-02-23
-6lv3,2020-08-19,2020-02-02
-7lvz,2022-01-05,2021-02-26
-1lvc,2002-12-04,2002-05-28
-4lv3,2014-07-30,2013-07-25
-6lvu,2020-04-22,2020-02-05
-3lvt,2010-03-16,2010-02-22
-3lv6,2010-06-16,2010-02-19
-6lvk,2020-04-08,2020-02-04
-7lvk,2021-12-15,2021-02-25
-6lvw,2020-10-28,2020-02-06
-4lv4,2014-01-08,2013-07-25
-4lvf,2013-09-25,2013-07-26
-1lv0,2003-08-05,2002-05-23
-6lvc,2020-06-03,2020-02-02
-4lv0,2014-07-30,2013-07-25
-3lve,1999-05-18,1998-05-12
-5lvw,2017-06-28,2016-09-14
-2lvz,2013-07-31,2012-07-17
-5lvg,2016-09-21,2016-09-14
-2lv2,2012-10-10,2012-06-27
-6lv7,2020-08-19,2020-02-02
-5lvq,2016-10-26,2016-09-14
-2lvh,2013-01-30,2012-07-05
-6lv5,2020-08-19,2020-02-02
-5lvk,2016-09-28,2016-09-14
-4lvs,2013-09-04,2013-07-26
-6lv6,2020-08-19,2020-02-02
-4lvm,2014-09-24,2013-07-26
-1lv3,2002-09-11,2002-05-24
-7lvs,2021-07-28,2021-02-26
-2lv7,2012-09-26,2012-06-29
-4lvn,2014-05-07,2013-07-26
-5lv2,2017-09-20,2016-09-12
-7lvv,2021-03-17,2021-02-26
-5lvr,2016-10-26,2016-09-14
-4lv8,2013-09-25,2013-07-26
-7lvq,2021-05-05,2021-02-26
-5lvs,2017-03-08,2016-09-14
-3lv8,2010-03-02,2010-02-19
-6lv4,2020-08-19,2020-02-02
-7lvl,2021-03-10,2021-02-25
-4lvo,2014-05-07,2013-07-26
-5lvh,2016-09-21,2016-09-14
-2lv9,2012-09-05,2012-06-29
-3lvw,2010-03-16,2010-02-22
-7lv3,2022-08-24,2021-02-23
-3lv2,2010-08-25,2010-02-19
-3lvp,2010-07-21,2010-02-22
-4lv6,2013-11-27,2013-07-26
-1lv8,2003-09-02,2002-05-27
-2lvu,2012-07-25,2012-07-11
-1lvg,2002-12-11,2002-05-28
-4lvd,2013-09-25,2013-07-26
-7lvp,2021-08-25,2021-02-26
-3lv0,2010-03-02,2010-02-18
-6lvy,2020-11-11,2020-02-06
-7lvy,2022-03-02,2021-02-26
-4lv9,2013-09-25,2013-07-26
-7lvi,2021-07-28,2021-02-25
-4lvk,2014-09-24,2013-07-26
-7lvw,2021-03-24,2021-02-26
-5lvi,2016-09-28,2016-09-14
-3lvv,2010-03-16,2010-02-22
-4lva,2013-09-25,2013-07-26
-5lvo,2016-10-19,2016-09-14
-7lv7,2021-03-17,2021-02-24
-1lvk,1998-01-28,1997-09-05
-2lvj,2012-10-03,2012-07-05
-6lv8,2020-08-19,2020-02-02
-7lvr,2021-05-05,2021-02-26
-4lvl,2014-09-24,2013-07-26
-3lvr,2010-06-09,2010-02-22
-3lvb,2010-03-16,2010-02-19
-1lvy,1997-01-27,1996-07-20
-5lvm,2016-10-19,2016-09-14
-4lvt,2013-08-14,2013-07-26
-3lvz,2011-01-12,2010-02-23
-4lvc,2014-07-30,2013-07-26
-2lvr,2012-07-25,2012-07-10
-5lve,2000-02-18,1999-02-24
-5lv4,2017-09-20,2016-09-12
-6lvl,2020-04-08,2020-02-04
-1lvh,2002-08-14,2002-05-28
-6lvm,2020-04-08,2020-02-04
-6lvv,2020-08-12,2020-02-05
-1lvm,2002-11-27,2002-05-28
-6lvs,2020-03-18,2020-02-04
-1lvl,1994-01-31,1992-12-16
-3lv4,2010-03-09,2010-02-19
-5lv5,2017-09-20,2016-09-12
-5lvl,2016-10-19,2016-09-14
-7lvx,2022-03-02,2021-02-26
-2lv6,2013-02-20,2012-06-29
-1lvn,2003-08-05,2002-05-28
-2lvt,2012-07-25,2012-07-11
-5lvd,2017-08-16,2016-09-14
-4lv2,2014-07-30,2013-07-25
-3lv3,2010-11-24,2010-02-19
-7lvh,2021-07-28,2021-02-25
-7lv6,2022-03-09,2021-02-24
-5lvj,2016-09-28,2016-09-14
-4lvg,2013-09-25,2013-07-26
-3lvf,2010-08-18,2010-02-19
-5lvp,2016-10-19,2016-09-14
-4lv5,2013-09-25,2013-07-25
-6lvz,2020-11-11,2020-02-06
-7lvc,2021-03-17,2021-02-24
-5lv0,2017-12-06,2016-09-12
-3lvl,2010-04-21,2010-02-22
-3zdc,2013-07-10,2012-11-26
-7zdc,2023-04-19,2022-03-29
-2zdp,2008-08-19,2007-11-27
-2zdt,2008-09-23,2007-11-27
-7zd2,2023-04-19,2022-03-29
-3zdy,2013-06-05,2012-12-03
-7zdv,2023-04-19,2022-03-29
-5zdm,2018-07-25,2018-02-23
-3zdz,2013-06-05,2012-12-03
-1zd0,2005-05-17,2005-04-13
-4zdc,2015-11-11,2015-04-17
-4zdt,2016-02-03,2015-04-19
-7zdy,2023-04-19,2022-03-30
-7zdd,2022-06-29,2022-03-29
-3zdx,2013-06-05,2012-12-03
-5zdb,2019-02-27,2018-02-23
-6zdh,2020-07-01,2020-06-14
-4zd5,2015-10-14,2015-04-16
-1zd4,2006-03-07,2005-04-14
-6zdi,2021-01-13,2020-06-14
-1zd5,2006-03-07,2005-04-14
-5zdk,2018-12-05,2018-02-23
-7zdp,2022-09-21,2022-03-29
-6zd2,2021-04-28,2020-06-13
-6zdg,2020-07-29,2020-06-14
-2zdz,2008-12-09,2007-12-04
-4zdo,2016-04-20,2015-04-17
-3zd7,2013-08-07,2012-11-25
-7zdm,2022-09-21,2022-03-29
-4zdi,2015-07-01,2015-04-17
-3zdf,2013-12-11,2012-11-26
-2zdy,2008-12-09,2007-12-01
-7zdn,2023-04-19,2022-03-29
-3zdp,2013-04-17,2012-11-29
-4zdp,2016-04-20,2015-04-17
-2zdk,2008-10-14,2007-11-26
-7zdz,2022-09-28,2022-03-30
-7zd7,2022-07-13,2022-03-29
-1zdj,1998-07-08,1997-12-18
-7zd4,2023-04-19,2022-03-29
-2zdg,2008-05-27,2007-11-22
-5zdl,2018-12-05,2018-02-23
-6zdr,2020-09-16,2020-06-15
-4zdq,2015-04-29,2015-04-18
-2zda,2008-10-28,2007-11-21
-2zdu,2008-09-23,2007-11-27
-3zdi,2012-12-26,2012-11-27
-2zdx,2008-12-09,2007-11-30
-5zdr,2019-02-27,2018-02-23
-7zdu,2023-04-19,2022-03-29
-7zde,2023-04-19,2022-03-29
-2zd9,2008-12-02,2007-11-21
-5zd4,2018-08-29,2018-02-22
-4zdj,2015-07-01,2015-04-17
-7zdj,2022-09-21,2022-03-29
-7zd0,2023-04-19,2022-03-29
-7zdq,2022-05-18,2022-03-29
-1zdm,2005-04-26,2005-04-14
-7zdi,2022-10-05,2022-03-29
-6zda,2021-01-13,2020-06-14
-3zdu,2013-03-20,2012-11-30
-1zdg,2005-04-26,2005-04-14
-1zde,2006-01-24,2005-04-14
-5zdf,2019-02-27,2018-02-23
-3zdh,2013-02-20,2012-11-26
-3zdq,2013-01-23,2012-11-30
-1zd3,2006-03-07,2005-04-14
-3zdw,2012-12-19,2012-12-01
-2zdl,2008-10-14,2007-11-26
-4zdk,2015-07-01,2015-04-17
-6zdx,2020-07-22,2020-06-15
-7zdk,2023-04-19,2022-03-29
-4zda,2016-06-29,2015-04-17
-1zdl,2005-11-01,2005-04-14
-7zdb,2023-04-19,2022-03-29
-4zd4,2015-10-14,2015-04-16
-5zdz,2018-04-25,2018-02-25
-1zdw,2005-06-21,2005-04-15
-1zdn,2005-05-03,2005-04-14
-7zd9,2022-07-13,2022-03-29
-6zdm,2020-10-21,2020-06-14
-7zd1,2023-04-19,2022-03-29
-7zd6,2022-09-21,2022-03-29
-1zds,2006-03-28,2005-04-14
-6zdp,2021-04-28,2020-06-15
-6zdc,2020-11-18,2020-06-14
-7zdh,2022-09-21,2022-03-29
-2zdn,2008-10-14,2007-11-26
-5zdd,2019-02-27,2018-02-23
-5zdq,2019-02-27,2018-02-23
-6zdl,2020-11-18,2020-06-14
-2zd1,2008-02-12,2007-11-16
-6zde,2021-01-13,2020-06-14
-3zd6,2013-08-07,2012-11-25
-3zds,2013-07-24,2012-11-30
-6zdv,2020-09-16,2020-06-15
-7zd8,2022-07-13,2022-03-29
-6zd5,2021-01-13,2020-06-13
-4zdm,2015-10-21,2015-04-17
-5zde,2019-02-27,2018-02-23
-7zdg,2023-04-19,2022-03-29
-2zdv,2008-10-28,2007-11-29
-4zdb,2015-11-11,2015-04-17
-2zd0,2008-04-29,2007-11-15
-2zdm,2008-10-14,2007-11-26
-7zdt,2023-04-19,2022-03-29
-5zdn,2018-07-25,2018-02-23
-1zd2,2006-03-07,2005-04-14
-3zdd,2013-07-10,2012-11-26
-7zdr,2023-04-19,2022-03-29
-5zdp,2019-02-27,2018-02-23
-1zdp,2005-04-26,2005-04-14
-4zdy,2016-03-30,2015-04-20
-3zdn,2013-10-09,2012-11-29
-7zdf,2023-04-19,2022-03-29
-3zd9,2013-07-10,2012-11-26
-7zdw,2023-04-19,2022-03-29
-1zdf,2005-04-26,2005-04-14
-5zdg,2019-02-27,2018-02-23
-3zdv,2013-09-18,2012-11-30
-6zdk,2020-11-18,2020-06-14
-6zd7,2021-01-13,2020-06-13
-3zd8,2013-07-10,2012-11-26
-3zda,2013-07-10,2012-11-26
-2zd8,2008-09-30,2007-11-20
-4zdz,2016-03-30,2015-04-20
-2zdo,2008-08-19,2007-11-27
-3zdb,2013-07-10,2012-11-26
-2zdh,2008-05-27,2007-11-22
-2zdq,2008-05-27,2007-11-27
-1zd9,2005-05-17,2005-04-14
-7zd3,2023-04-19,2022-03-29
-4zd6,2015-11-04,2015-04-17
-5zdc,2019-02-27,2018-02-23
-7zdl,2023-04-19,2022-03-29
-1zdy,2005-06-21,2005-04-15
-3zdr,2013-10-02,2012-11-30
-4zdl,2016-04-20,2015-04-17
-3zdg,2013-02-20,2012-11-26
-7zda,2023-04-19,2022-03-29
-1zdq,2006-03-28,2005-04-14
-6zdy,2021-01-13,2020-06-15
-4zdw,2015-10-14,2015-04-20
-7mty,2022-05-18,2021-05-13
-1mtc,2003-03-25,2002-09-20
-2mt5,2014-10-29,2014-08-13
-7mt6,2021-12-29,2021-05-12
-7mta,2021-07-07,2021-05-13
-6mt5,2019-02-13,2018-10-19
-6mtu,2019-08-14,2018-10-22
-7mtz,2021-06-09,2021-05-14
-1mto,2002-12-31,2002-09-21
-4mti,2013-12-11,2013-09-19
-7mt5,2021-12-29,2021-05-12
-3mtd,2011-01-05,2010-04-30
-3mtb,2011-01-05,2010-04-30
-1mti,1995-09-15,1994-12-12
-4mtu,2014-03-26,2013-09-20
-1mtj,1995-09-15,1994-12-12
-4mt9,2013-12-25,2013-09-19
-7mt3,2022-02-02,2021-05-12
-1mtu,1997-11-12,1997-05-16
-7mto,2021-06-23,2021-05-13
-5mto,2018-02-28,2017-01-10
-1mtw,1997-11-12,1997-05-16
-6mtj,2019-01-16,2018-10-19
-1mtk,1995-09-15,1994-12-12
-2mt9,2016-03-09,2014-08-15
-4mta,2015-01-14,2013-09-19
-5mtz,2017-06-21,2017-01-11
-5mt7,2017-11-15,2017-01-06
-4mtw,2014-04-02,2013-09-20
-5mt8,2017-11-15,2017-01-06
-6mt8,2019-05-15,2018-10-19
-5mtu,2017-07-05,2017-01-10
-5mtp,2017-02-15,2017-01-10
-7mtq,2021-07-07,2021-05-13
-6mtb,2018-11-21,2018-10-19
-3mtn,2010-06-09,2010-04-30
-6mtd,2018-11-21,2018-10-19
-7mtu,2021-06-09,2021-05-13
-4mtv,2013-10-16,2013-09-20
-1mt8,2003-01-07,2002-09-20
-2mta,1994-01-31,1993-10-26
-7mtc,2021-09-15,2021-05-13
-7mte,2021-09-15,2021-05-13
-4mtr,2014-09-24,2013-09-20
-7mtx,2021-06-09,2021-05-13
-5mtt,2017-07-05,2017-01-10
-5mtm,2017-04-05,2017-01-10
-4mtd,2014-11-05,2013-09-19
-1mts,1997-08-20,1997-05-16
-7mt2,2022-02-02,2021-05-12
-5mtf,2017-11-15,2017-01-09
-1mt7,2003-01-07,2002-09-20
-7mtd,2021-09-15,2021-05-13
-5mtx,2017-09-06,2017-01-11
-6mtv,2019-08-14,2018-10-22
-5mtw,2018-10-24,2017-01-10
-1mtr,1996-08-01,1996-02-15
-5mt6,2017-11-15,2017-01-06
-6mt9,2019-06-19,2018-10-19
-7mtb,2021-07-07,2021-05-13
-6mtc,2018-11-21,2018-10-19
-5mts,2017-03-15,2017-01-10
-6mt7,2019-04-10,2018-10-19
-2mtz,2015-01-14,2014-09-02
-6mtf,2019-04-10,2018-10-19
-3mtw,2010-07-28,2010-05-01
-6mtn,2019-01-16,2018-10-20
-7mt9,2021-07-07,2021-05-13
-5mt9,2017-04-05,2017-01-07
-4mtq,2014-09-24,2013-09-20
-4mto,2013-11-27,2013-09-19
-5mtd,2017-09-20,2017-01-09
-4mtt,2014-09-24,2013-09-20
-5mtk,2018-02-28,2017-01-09
-5mth,2018-05-02,2017-01-09
-5mt0,2017-02-15,2017-01-06
-7mts,2021-07-07,2021-05-13
-4mts,2014-09-24,2013-09-20
-4mt4,2014-09-24,2013-09-19
-2mte,2014-10-15,2014-08-18
-4mtz,2014-09-24,2013-09-20
-4mtg,2013-11-27,2013-09-19
-6mth,2019-05-15,2018-10-19
-1mtv,1997-11-12,1997-05-16
-4mtp,2013-12-25,2013-09-20
-4mte,2014-11-05,2013-09-19
-1mtb,2003-01-07,2002-09-20
-1mt9,2003-01-07,2002-09-20
-5mty,2017-09-06,2017-01-11
-3mta,2011-01-05,2010-04-30
-4mtf,2013-11-27,2013-09-19
-3mtl,2010-06-09,2010-04-30
-5mtv,2017-03-08,2017-01-10
-3mt7,2011-01-05,2010-04-30
-5mte,2017-11-29,2017-01-09
-6mt0,2019-01-16,2018-10-18
-4mty,2013-12-11,2013-09-20
-6mtm,2019-02-13,2018-10-19
-7mt7,2022-02-02,2021-05-13
-6mte,2018-11-21,2018-10-19
-3mt6,2010-11-03,2010-04-30
-4mth,2013-11-27,2013-09-19
-3mte,2010-12-08,2010-04-30
-3mth,1996-01-29,1995-09-13
-4mtb,2014-12-24,2013-09-19
-1mty,1997-04-21,1996-07-10
-6mti,2019-04-24,2018-10-19
-7mtr,2021-07-07,2021-05-13
-6mta,2020-04-15,2018-10-19
-3mt8,2011-01-05,2010-04-30
-3mtc,2010-06-30,2010-04-30
-7mt8,2021-07-07,2021-05-13
-5mtr,2017-02-15,2017-01-10
-5mt4,2017-02-15,2017-01-06
-7mt4,2021-12-29,2021-05-12
-6mt4,2019-02-13,2018-10-19
-5mtq,2017-02-15,2017-01-10
-3mtf,2010-06-23,2010-04-30
-5mt3,2017-04-05,2017-01-06
-4mt2,1993-07-15,1993-02-26
-5mtc,2017-09-20,2017-01-09
-6mtl,2019-02-13,2018-10-19
-6mt3,2019-02-13,2018-10-19
-6mtw,2019-03-20,2018-10-22
-3mt5,2010-06-09,2010-04-30
-6mt6,2019-02-13,2018-10-19
-3mt9,2011-01-05,2010-04-30
-4mtm,2014-10-01,2013-09-19
-1mt6,2002-11-06,2002-09-20
-3mtg,2010-05-26,2010-04-30
-1mt1,2003-03-25,2002-09-20
-3mty,2010-05-12,2010-05-01
-7gcq,2023-11-08,2023-08-11
-8gc9,2024-03-06,2023-03-01
-6gcn,2018-08-22,2018-04-18
-3gcm,2009-06-09,2009-02-22
-1gcz,2001-02-21,2000-08-24
-7gcp,2023-11-08,2023-08-11
-8gcd,2024-03-06,2023-03-01
-2gco,2007-03-27,2006-03-14
-2gc0,2006-04-11,2006-03-13
-3gcp,2009-06-09,2009-02-22
-6gch,1990-10-15,1990-04-06
-4gci,2012-08-29,2012-07-30
-2gc1,2006-04-11,2006-03-13
-1gcy,2000-08-30,2000-08-14
-7gcj,2023-11-08,2023-08-11
-7gce,2023-11-08,2023-08-11
-1gcv,2000-08-31,2000-08-08
-3gcn,2009-03-31,2009-02-22
-7gcu,2023-11-08,2023-08-11
-7gcn,2023-11-08,2023-08-11
-6gcy,2019-02-06,2018-04-20
-2gcd,2006-09-05,2006-03-14
-3gcx,2009-03-03,2009-02-22
-6gcl,2019-04-03,2018-04-18
-4gcf,2013-01-02,2012-07-30
-1gcw,2000-09-06,2000-08-08
-3gc6,2010-03-02,2009-02-21
-3gcu,2009-06-09,2009-02-22
-3gck,2009-03-31,2009-02-22
-4gc1,2013-04-10,2012-07-29
-8gca,2023-03-15,2023-03-01
-8gcr,2024-03-06,2023-03-02
-2gcp,2007-03-27,2006-03-14
-2gcg,2006-07-18,2006-03-14
-7gc8,2023-11-08,2023-08-11
-7gcb,2023-11-08,2023-08-11
-3gc4,2009-12-15,2009-02-21
-4gcz,2013-06-19,2012-07-31
-8gcz,2023-06-07,2023-03-03
-7gc1,2023-11-08,2023-08-11
-3gcq,2009-06-09,2009-02-22
-7gc0,2023-11-08,2023-08-11
-8gcc,2023-07-12,2023-03-01
-7gck,2023-11-08,2023-08-11
-4gc0,2012-10-17,2012-07-28
-6gcg,2019-01-30,2018-04-17
-5gcn,1999-07-19,1999-03-24
-3gc0,2009-03-24,2009-02-20
-1gcb,1995-10-15,1995-07-18
-7gcm,2023-11-08,2023-08-11
-7gc6,2023-11-08,2023-08-11
-6gcv,2018-09-19,2018-04-19
-4gc2,2013-04-10,2012-07-29
-3gcz,2009-03-24,2009-02-23
-6gck,2019-04-03,2018-04-18
-6gcs,2018-10-10,2018-04-19
-3gc8,2009-07-21,2009-02-21
-4gcx,2012-08-29,2012-07-31
-1gco,2001-02-28,2000-08-07
-2gc7,2007-02-06,2006-03-13
-4gca,2013-07-31,2012-07-30
-6gcr,2019-05-01,2018-04-19
-4gcv,2013-07-24,2012-07-31
-3gcl,2009-03-31,2009-02-22
-7gch,1990-10-15,1990-04-06
-7gc4,2023-11-08,2023-08-11
-4gc6,2012-10-24,2012-07-29
-4gc9,2013-07-10,2012-07-30
-4gcy,2013-07-03,2012-07-31
-7gcc,2023-11-08,2023-08-11
-8gch,1992-04-15,1991-03-27
-7gci,2023-11-08,2023-08-11
-6gc5,2019-01-30,2018-04-17
-4gcq,2012-12-19,2012-07-30
-7gcd,2023-11-08,2023-08-11
-7gco,2023-11-08,2023-08-11
-2gce,2007-02-20,2006-03-14
-2gci,2007-02-20,2006-03-14
-7gcf,2023-11-08,2023-08-11
-3gcf,2009-09-15,2009-02-22
-8gcq,2023-09-27,2023-03-02
-8gc8,2024-01-31,2023-03-01
-7gc5,2023-11-08,2023-08-11
-8gcw,2024-03-06,2023-03-03
-3gco,2009-03-31,2009-02-22
-4gcj,2012-10-31,2012-07-30
-7gcs,2023-11-08,2023-08-11
-6gci,2019-01-09,2018-04-17
-6gcp,2019-04-03,2018-04-18
-8gc0,2023-06-07,2023-02-28
-4gcb,2013-01-02,2012-07-30
-3gc9,2009-07-21,2009-02-21
-7gcw,2023-11-08,2023-08-11
-7gcl,2023-11-08,2023-08-11
-3gci,2009-03-10,2009-02-22
-7gcv,2023-11-08,2023-08-11
-2gc2,2006-04-11,2006-03-13
-2gcq,2007-04-24,2006-03-14
-8gck,2024-03-06,2023-03-02
-3gcj,2009-03-31,2009-02-22
-4gc4,2013-06-19,2012-07-29
-1gc3,2001-09-05,2000-07-18
-1gci,1998-10-21,1998-09-02
-8gc2,2024-03-13,2023-03-01
-8gc4,2024-03-13,2023-03-01
-3gc5,2009-12-15,2009-02-21
-4gch,1990-10-15,1989-09-25
-4gc7,2012-10-24,2012-07-29
-1gc1,1998-07-08,1998-06-15
-4gcs,2012-12-19,2012-07-30
-6gcq,2019-04-03,2018-04-18
-3gc7,2009-07-21,2009-02-21
-3gc1,2009-03-31,2009-02-21
-6gc8,2018-06-20,2018-04-17
-7gcr,2023-11-08,2023-08-11
-7gcz,2023-11-08,2023-08-11
-3gcv,2009-06-09,2009-02-22
-4gcp,2012-12-19,2012-07-30
-8gce,2024-03-06,2023-03-01
-7gc9,2023-11-08,2023-08-11
-8gcb,2023-07-19,2023-03-01
-3gch,1990-10-15,1989-09-25
-2gc4,2006-11-28,2006-03-13
-7gc2,2023-11-08,2023-08-11
-7gcx,2023-11-08,2023-08-11
-8gcy,2023-03-22,2023-03-03
-6gco,2018-08-22,2018-04-18
-7gcg,2023-11-08,2023-08-11
-2gc8,2006-06-13,2006-03-13
-8gc7,2024-01-31,2023-03-01
-3gc2,2009-03-10,2009-02-21
-1gck,2001-11-14,2000-08-04
-1gc6,2000-09-20,2000-07-21
-2gc3,2006-04-11,2006-03-13
-8gc3,2024-03-13,2023-03-01
-7gct,2023-11-08,2023-08-11
-4gc3,2013-02-27,2012-07-29
-1gca,1993-10-31,1993-05-13
-4gcw,2012-10-31,2012-07-31
-2gcn,2007-03-27,2006-03-14
-1gc5,2001-07-25,2000-07-20
-7gca,2023-11-08,2023-08-11
-3gcs,2009-06-09,2009-02-22
-6gcx,2019-05-01,2018-04-19
-6gcb,2018-08-29,2018-04-17
-6gcw,2019-05-01,2018-04-19
-1gc4,2001-09-05,2000-07-19
-3gcd,2009-05-26,2009-02-21
-7gcy,2023-11-08,2023-08-11
-3gcw,2009-03-03,2009-02-22
-7gc3,2023-11-08,2023-08-11
-1gcg,1994-05-31,1994-02-03
-7gc7,2023-11-08,2023-08-11
-4gcm,2012-08-29,2012-07-30
-2gcu,2006-04-18,2006-03-14
-8gcm,2024-01-03,2023-03-02
-6gct,2018-06-13,2018-04-19
-8gcp,2024-01-03,2023-03-02
-8gc5,2024-03-13,2023-03-01
-8tgp,2024-01-24,2023-07-12
-3tg0,2011-11-09,2011-08-16
-8tgh,2024-03-20,2023-07-12
-5tgc,2017-09-06,2016-09-27
-3tgw,2012-09-05,2011-08-18
-1tg2,2004-11-30,2004-05-28
-3tg5,2011-08-31,2011-08-17
-7tgv,2022-08-24,2022-01-09
-8tgg,2024-03-20,2023-07-12
-7tgh,2022-04-06,2022-01-07
-7tgw,2022-03-09,2022-01-09
-8tg4,2023-11-08,2023-07-12
-5tg4,2017-01-11,2016-09-27
-6tgd,2020-08-26,2019-11-15
-3tgu,2012-07-04,2011-08-17
-2tgp,1983-01-18,1982-09-27
-3tg6,2012-08-29,2011-08-17
-7tgu,2022-08-24,2022-01-09
-7tgk,2022-07-06,2022-01-07
-5tgo,2017-04-05,2016-09-28
-2tga,1982-03-04,1981-10-26
-6tg0,2020-09-30,2019-11-14
-6tgu,2020-07-08,2019-11-18
-3tgq,2012-04-04,2011-08-17
-7tge,2022-03-09,2022-01-07
-3tgg,2012-01-25,2011-08-17
-3tgc,2012-08-22,2011-08-17
-5tgz,2016-11-02,2016-09-28
-8tgl,2024-03-20,2023-07-12
-1tg9,2005-01-25,2004-05-28
-5tg9,2017-04-12,2016-09-27
-8tgj,2024-03-20,2023-07-12
-6tgh,2020-06-03,2019-11-15
-2tgd,1986-05-07,1986-03-17
-3tgk,2001-07-04,1998-07-19
-3tgm,2012-02-01,2011-08-17
-6tga,2020-04-22,2019-11-15
-1tg5,2004-08-17,2004-05-28
-7tgn,2022-07-06,2022-01-07
-3tga,2012-05-30,2011-08-17
-5tgk,2018-05-09,2016-09-28
-8tg5,2024-06-05,2023-07-12
-5tg2,2017-01-11,2016-09-27
-3tgn,2011-11-30,2011-08-17
-1tgt,1982-03-04,1981-10-26
-7tgx,2022-03-09,2022-01-09
-7tg5,2022-01-19,2022-01-07
-1tgb,1979-06-13,1979-03-07
-8tgd,2023-09-06,2023-07-12
-8tgy,2023-08-02,2023-07-13
-5tgu,2017-04-05,2016-09-28
-8tgk,2024-03-20,2023-07-12
-5tg8,2017-04-12,2016-09-27
-3tg4,2011-08-31,2011-08-17
-1tgm,2004-06-08,2004-05-28
-8tgo,2024-04-17,2023-07-12
-1tgy,2005-06-14,2004-05-31
-5tgy,2017-08-09,2016-09-28
-1tgg,2004-10-12,2004-05-28
-7tgr,2022-05-04,2022-01-09
-6tg7,2019-12-04,2019-11-15
-3tgb,2012-05-30,2011-08-17
-6tg8,2020-09-16,2019-11-15
-5tgs,2017-01-18,2016-09-28
-3tgx,2012-02-15,2011-08-18
-1tgu,2005-07-05,2004-05-31
-3tgy,2011-09-21,2011-08-18
-5tg3,2017-02-15,2016-09-27
-2tgt,1982-03-04,1981-10-26
-1tg3,2005-01-25,2004-05-28
-5tga,2016-11-23,2016-09-27
-3tgo,2011-09-28,2011-08-17
-3tgp,2011-10-12,2011-08-17
-3tgr,2012-04-04,2011-08-17
-6tgi,2020-10-14,2019-11-15
-3tgi,1998-12-23,1998-07-15
-5tg7,2017-01-11,2016-09-27
-5tgq,2016-12-21,2016-09-28
-5tg6,2017-01-11,2016-09-27
-8tgm,2024-03-20,2023-07-12
-1tg6,2005-03-22,2004-05-28
-6tg4,2020-07-08,2019-11-15
-3tgt,2012-04-04,2011-08-17
-5tg0,2017-06-14,2016-09-27
-5tgf,2016-10-26,2016-09-27
-1tgs,1983-01-18,1982-09-27
-5tgm,2017-01-18,2016-09-28
-7tgy,2022-03-09,2022-01-09
-5tgx,2016-12-21,2016-09-28
-8tgi,2024-03-20,2023-07-12
-5tgd,2016-10-12,2016-09-27
-3tgh,2012-03-07,2011-08-17
-3tg2,2012-08-29,2011-08-17
-7tgt,2022-08-24,2022-01-09
-6tg9,2020-04-22,2019-11-15
-8tgn,2024-03-20,2023-07-12
-6tg2,2020-01-22,2019-11-14
-6tgg,2020-04-08,2019-11-15
-6tgx,2020-06-24,2019-11-18
-6tge,2020-02-26,2019-11-15
-3tgj,1998-12-23,1998-07-16
-7tgs,2022-08-24,2022-01-09
-8tgb,2023-12-13,2023-07-12
-7tgq,2022-02-02,2022-01-09
-6tg1,2020-09-30,2019-11-14
-8tg8,2024-03-13,2023-07-12
-1tg4,2004-06-08,2004-05-28
-3tgs,2012-04-04,2011-08-17
-5tg5,2017-01-11,2016-09-27
-6tgt,2020-12-02,2019-11-18
-6tgv,2020-11-25,2019-11-18
-1tgc,1982-03-04,1981-10-26
-8tg3,2023-11-08,2023-07-12
-5tgv,2017-04-05,2016-09-28
-1tg8,2004-09-28,2004-05-28
-7tgm,2022-07-06,2022-01-07
-7tgl,2022-07-06,2022-01-07
-6tg3,2020-01-22,2019-11-14
-1tg7,2004-11-02,2004-05-28
-1tgv,2005-06-14,2004-05-31
-1tg1,2004-06-08,2004-05-28
-6tgl,2020-08-19,2019-11-16
-6tgw,2021-06-02,2019-11-18
-5tg1,2017-01-11,2016-09-27
-6tgk,2020-02-26,2019-11-16
-3tge,2011-11-09,2011-08-17
-4euh,2012-11-28,2012-04-25
-5eug,1999-07-23,1998-12-27
-6eui,2018-10-17,2017-10-30
-2eu8,2006-06-27,2005-10-28
-8eux,2023-02-22,2022-10-19
-2eud,2006-03-07,2005-10-28
-7eue,2022-03-16,2021-05-17
-4eud,2012-10-10,2012-04-25
-6euu,2018-05-02,2017-10-31
-1eu3,2000-04-26,2000-04-13
-7euy,2021-11-24,2021-05-19
-8euk,2023-02-22,2022-10-18
-7eu4,2021-07-28,2021-05-16
-7eu7,2021-08-04,2021-05-16
-7eu5,2022-05-18,2021-05-16
-7euo,2022-05-25,2021-05-18
-7eu6,2022-03-16,2021-05-16
-1eue,2001-04-04,2000-04-19
-5euf,2015-12-02,2015-11-18
-8eud,2023-02-22,2022-10-18
-7euz,2022-03-16,2021-05-19
-2eur,2006-04-11,2005-10-29
-5euj,2016-09-14,2015-11-18
-3euv,2009-07-07,2008-10-11
-6euo,2018-11-14,2017-10-30
-7euq,2022-05-18,2021-05-18
-5eul,2016-03-09,2015-11-18
-7euu,2022-05-25,2021-05-18
-3eub,2009-01-27,2008-10-09
-3euk,2009-01-20,2008-10-10
-6euz,2018-05-02,2017-10-31
-4eum,2012-05-16,2012-04-25
-7euv,2022-05-25,2021-05-19
-3euh,2009-01-20,2008-10-10
-2eul,2005-11-15,2005-10-28
-7eu8,2021-07-28,2021-05-16
-7eu1,2021-12-29,2021-05-15
-3euf,2009-03-31,2008-10-10
-5eu5,2016-03-02,2015-11-18
-4euc,2012-10-10,2012-04-25
-8eun,2023-04-05,2022-10-19
-7eu0,2021-12-29,2021-05-15
-4eu2,2013-05-01,2012-04-25
-1eua,2001-02-07,2000-04-14
-8euh,2023-02-22,2022-10-18
-4eus,2013-08-07,2012-04-25
-2eu7,2006-10-10,2005-10-28
-1euy,2000-06-04,2000-04-19
-6euv,2017-12-13,2017-10-31
-4euu,2012-05-23,2012-04-25
-7eu3,2021-12-29,2021-05-15
-7eux,2021-11-24,2021-05-19
-7eu2,2021-08-25,2021-05-15
-4eu9,2012-10-10,2012-04-25
-5euy,2016-11-30,2015-11-19
-8euc,2023-08-09,2022-10-18
-6eu2,2018-01-17,2017-10-27
-6eux,2017-12-13,2017-10-31
-6euw,2017-12-13,2017-10-31
-5eue,2016-03-16,2015-11-18
-2euq,2006-04-11,2005-10-29
-6euq,2018-08-08,2017-10-31
-6eu9,2018-03-14,2017-10-29
-3eu5,2009-07-07,2008-10-09
-8eu8,2023-01-04,2022-10-18
-8eup,2022-11-30,2022-10-19
-4eup,2013-05-01,2012-04-25
-4eux,2012-07-11,2012-04-25
-8eu0,2023-11-01,2022-10-18
-8euu,2023-09-27,2022-10-19
-6eu5,2019-02-06,2017-10-27
-5euk,2016-10-26,2015-11-18
-2eus,2006-04-11,2005-10-29
-5euq,2016-02-24,2015-11-19
-5euh,2015-12-30,2015-11-18
-6eu0,2018-01-17,2017-10-27
-2eut,2006-04-11,2005-10-29
-8eul,2023-02-22,2022-10-18
-4eu0,2012-07-25,2012-04-24
-1euf,2001-04-14,2000-04-14
-5eu4,2016-03-02,2015-11-18
-5eu3,2016-03-02,2015-11-18
-8euq,2023-04-19,2022-10-19
-2euu,2006-04-11,2005-10-29
-6eum,2018-10-03,2017-10-30
-1euu,1997-01-11,1996-06-21
-2eu0,2006-02-07,2005-10-27
-4eut,2012-05-23,2012-04-25
-8eui,2022-11-30,2022-10-18
-1euo,2000-05-10,2000-04-17
-9eun,2024-05-01,2024-03-27
-8euf,2023-07-12,2022-10-18
-5eub,2016-12-21,2015-11-18
-1eus,1997-01-11,1996-06-21
-1eu4,2000-04-26,2000-04-13
-6euh,2018-10-17,2017-10-30
-6eu1,2018-01-17,2017-10-27
-5euo,2016-11-23,2015-11-18
-8eua,2023-04-05,2022-10-18
-2eug,1999-10-13,1998-10-13
-6eue,2018-11-14,2017-10-30
-8eub,2023-09-06,2022-10-18
-5eud,2016-03-16,2015-11-18
-4eu5,2012-10-10,2012-04-25
-7euw,2022-05-25,2021-05-19
-7eup,2022-03-16,2021-05-18
-4euf,2012-11-28,2012-04-25
-2eu3,2006-07-11,2005-10-28
-2euf,2006-07-04,2005-10-28
-8euy,2022-11-30,2022-10-19
-1euq,2000-06-04,2000-04-17
-4eul,2012-10-03,2012-04-25
-5eur,2016-11-23,2015-11-19
-5eua,2016-09-21,2015-11-18
-2euo,2006-04-11,2005-10-29
-4euo,2012-11-21,2012-04-25
-8eu3,2023-08-02,2022-10-18
-5eu2,2016-10-19,2015-11-18
-8eu1,2023-11-01,2022-10-18
-5eu6,2016-03-02,2015-11-18
-2eum,2006-11-14,2005-10-28
-7eun,2022-05-18,2021-05-18
-7euk,2022-05-18,2021-05-18
-8eur,2023-02-22,2022-10-19
-4euk,2013-02-20,2012-04-25
-3euj,2009-01-20,2008-10-10
-4eu6,2012-10-10,2012-04-25
-3eu8,2008-10-21,2008-10-09
-5eu1,2016-03-09,2015-11-18
-4eue,2012-11-28,2012-04-25
-7eul,2022-05-18,2021-05-18
-8eug,2022-11-30,2022-10-18
-6eu3,2018-01-17,2017-10-27
-4eu4,2012-10-10,2012-04-25
-6eu4,2018-11-07,2017-10-27
-4eu8,2012-10-10,2012-04-25
-3eue,2009-03-31,2008-10-09
-6eur,2018-11-14,2017-10-31
-4eub,2012-10-10,2012-04-25
-2eu2,2006-07-11,2005-10-28
-7eut,2022-05-25,2021-05-18
-4eu7,2012-10-10,2012-04-25
-8euw,2023-09-27,2022-10-19
-1eu1,2000-08-02,2000-04-13
-5eu9,2016-11-23,2015-11-18
-1euc,2000-07-27,2000-04-14
-1eu8,2001-03-14,2000-04-14
-5eu8,2015-12-30,2015-11-18
-5eui,2016-11-30,2015-11-18
-3eu1,2009-11-10,2008-10-09
-7eus,2022-05-25,2021-05-18
-8eut,2023-02-22,2022-10-19
-3eu4,2009-06-16,2008-10-09
-4eua,2012-10-10,2012-04-25
-8eu9,2023-07-12,2022-10-18
-2eup,2006-04-11,2005-10-29
-8eum,2023-11-08,2022-10-18
-4euv,2012-07-25,2012-04-25
-2eun,2006-04-11,2005-10-29
-3euw,2008-10-21,2008-10-11
-1eup,2000-04-28,2000-04-17
-6euc,2018-11-14,2017-10-30
-4euz,2012-05-23,2012-04-25
-6eut,2018-05-02,2017-10-31
-6euy,2017-12-13,2017-10-31
-6euf,2018-10-17,2017-10-30
-3eu9,2009-06-23,2008-10-09
-6eug,2018-10-17,2017-10-30
-3eu3,2009-06-16,2008-10-09
-1eut,1997-01-11,1996-06-21
-2euk,2006-11-14,2005-10-28
-6eu6,2018-01-24,2017-10-28
-8euv,2023-09-27,2022-10-19
-2euh,1999-07-22,1998-11-05
-1eub,2001-04-14,2000-04-14
-1agc,1997-06-16,1997-03-24
-3agv,2010-11-10,2010-04-08
-6agf,2018-10-10,2018-08-11
-4agc,2012-09-26,2012-01-26
-5agj,2015-07-01,2015-02-02
-5agn,2015-04-29,2015-02-02
-2ag5,2005-08-09,2005-07-26
-4agw,2012-02-15,2012-02-01
-2agl,2006-04-25,2005-07-27
-8ag1,2023-07-19,2022-07-19
-1agw,1998-03-25,1997-03-25
-4agu,2012-02-08,2012-01-31
-1agp,1994-04-30,1993-03-29
-7agd,2021-04-21,2020-09-22
-2agv,2005-10-25,2005-07-27
-2agx,2006-04-25,2005-07-27
-8agv,2023-03-08,2022-07-20
-7agh,2021-04-14,2020-09-22
-6agi,2019-01-23,2018-08-11
-7agz,2021-10-06,2020-09-23
-4agt,2013-02-13,2012-01-31
-8agz,2023-03-08,2022-07-20
-7ags,2020-12-16,2020-09-23
-2age,2006-05-16,2005-07-26
-5ag6,2015-10-07,2015-01-29
-8agn,2023-08-16,2022-07-20
-7age,2021-04-21,2020-09-22
-5ag2,2016-01-13,2015-01-27
-8agm,2023-08-16,2022-07-20
-5agy,2015-12-16,2015-02-04
-2ago,2005-09-06,2005-07-27
-1agn,1997-03-12,1996-06-04
-6agn,2019-08-14,2018-08-13
-6agx,2019-08-21,2018-08-15
-6ag9,2019-09-18,2018-08-09
-7agc,2021-04-21,2020-09-22
-3agb,2010-09-01,2010-03-30
-5age,2015-10-07,2015-01-29
-4agq,2012-03-21,2012-01-30
-5ago,2015-04-29,2015-02-02
-8agt,2023-03-08,2022-07-20
-6ag7,2019-08-14,2018-08-09
-1agb,1997-06-16,1997-03-24
-5aga,2015-02-25,2015-01-29
-3agp,2010-09-01,2010-04-06
-8agy,2023-08-16,2022-07-20
-6agr,2019-08-14,2018-08-13
-6agq,2018-10-10,2018-08-13
-3ag4,2010-04-28,2010-03-19
-8ags,2023-08-16,2022-07-20
-5ag7,2015-10-07,2015-01-29
-4ag3,2013-02-06,2012-01-24
-7ag4,2021-04-14,2020-09-21
-2agi,2006-05-16,2005-07-26
-2ag8,2005-09-06,2005-07-26
-5ag5,2015-10-07,2015-01-29
-8agp,2023-08-16,2022-07-20
-7agn,2021-09-01,2020-09-23
-8agj,2022-09-07,2022-07-20
-7ag5,2022-02-02,2020-09-21
-5ag0,2016-03-09,2015-01-27
-2agw,2006-04-25,2005-07-27
-1ag0,1997-10-29,1997-03-26
-8ag2,2022-08-31,2022-07-19
-6ag3,2019-09-18,2018-08-09
-2ags,2005-11-22,2005-07-27
-3ag3,2010-04-28,2010-03-19
-4ag4,2012-04-18,2012-01-24
-2agp,2005-09-06,2005-07-27
-4ag5,2012-07-04,2012-01-24
-3ag6,2010-07-21,2010-03-19
-3ag2,2010-04-28,2010-03-19
-4ag2,2012-07-11,2012-01-23
-6ag4,2019-08-14,2018-08-09
-7ag6,2021-04-14,2020-09-21
-2agj,2006-05-02,2005-07-27
-1ag6,1998-10-21,1997-04-02
-3agi,2011-03-23,2010-03-31
-5agl,2015-04-29,2015-02-02
-1age,1997-06-16,1997-03-24
-5ag4,2015-10-07,2015-01-29
-2ag2,2005-10-25,2005-07-26
-3age,2011-04-13,2010-03-30
-1agm,1994-09-30,1994-05-13
-2ag6,2006-04-04,2005-07-26
-2ag0,2006-01-24,2005-07-26
-8agu,2023-03-08,2022-07-20
-7agi,2020-10-28,2020-09-22
-1agr,1997-06-16,1997-03-25
-5agf,2015-09-09,2015-01-30
-8agb,2022-12-07,2022-07-19
-7ago,2020-11-18,2020-09-23
-8age,2022-12-07,2022-07-19
-4ago,2012-03-21,2012-01-30
-4agl,2012-03-21,2012-01-30
-2agz,2006-04-25,2005-07-27
-6agm,2019-04-17,2018-08-13
-3agz,2011-02-23,2010-04-12
-8agd,2023-04-12,2022-07-19
-5agu,2015-06-03,2015-02-03
-8agc,2022-12-07,2022-07-19
-2ag1,2006-01-24,2005-07-26
-2agq,2005-09-06,2005-07-27
-3ag0,2011-02-02,2010-03-17
-8agg,2023-04-12,2022-07-20
-6agg,2018-09-05,2018-08-11
-5agv,2015-06-03,2015-02-03
-7agm,2020-11-18,2020-09-23
-5agp,2015-04-29,2015-02-02
-2agy,2006-04-25,2005-07-27
-4agi,2013-02-06,2012-01-30
-5agz,2015-05-06,2015-02-04
-4aga,2012-07-18,2012-01-25
-6ago,2019-03-13,2018-08-13
-8agw,2023-03-08,2022-07-20
-8agl,2022-09-07,2022-07-20
-4ag8,2012-09-26,2012-01-24
-7aga,2020-12-02,2020-09-22
-6ag5,2019-08-14,2018-08-09
-7agj,2021-10-06,2020-09-22
-5agk,2015-04-29,2015-02-02
-3ago,2010-07-07,2010-04-03
-4ag7,2012-07-25,2012-01-24
-5ags,2016-03-09,2015-02-03
-2agg,2006-05-16,2005-07-26
-5ag1,2016-03-02,2015-01-27
-8agq,2023-08-30,2022-07-20
-4agd,2012-09-26,2012-01-26
-1agd,1997-06-16,1997-03-24
-6ag0,2018-10-10,2018-08-09
-7agu,2020-12-16,2020-09-23
-4ag9,2012-07-25,2012-01-24
-3ag9,2010-09-01,2010-03-26
-8agk,2022-09-21,2022-07-20
-8ag6,2023-01-25,2022-07-19
-5agd,2015-03-25,2015-01-29
-4agm,2012-03-21,2012-01-30
-5ag3,2015-08-19,2015-01-28
-7agl,2020-11-18,2020-09-23
-3agh,2011-03-23,2010-03-31
-6agk,2019-08-21,2018-08-13
-2agd,2005-10-04,2005-07-26
-3agl,2010-09-01,2010-04-02
-3agy,2011-02-23,2010-04-12
-3agw,2010-09-29,2010-04-08
-8agx,2023-03-08,2022-07-20
-7ag8,2021-01-27,2020-09-21
-3agn,2010-07-07,2010-04-03
-6agp,2019-03-20,2018-08-13
-7agb,2021-04-21,2020-09-22
-7agk,2021-04-14,2020-09-22
-3agc,2010-09-01,2010-03-30
-5agm,2015-04-29,2015-02-02
-8ag0,2022-11-23,2022-07-18
-8agi,2022-09-07,2022-07-20
-1ag9,1997-12-24,1997-04-04
-2agt,2005-09-20,2005-07-27
-3agg,2011-03-23,2010-03-31
-7agv,2021-03-31,2020-09-23
-4agn,2012-03-21,2012-01-30
-6agt,2019-03-13,2018-08-14
-6agz,2019-06-26,2018-08-15
-6ag2,2019-09-18,2018-08-09
-4agp,2012-03-21,2012-01-30
-3ag1,2010-04-28,2010-03-19
-3agm,2010-09-01,2010-04-02
-6agb,2018-10-17,2018-08-10
-3agq,2010-09-01,2010-04-06
-3aga,2010-09-01,2010-03-30
-4ags,2012-07-04,2012-01-31
-5agi,2015-07-01,2015-02-02
-4cbr,2014-07-09,2013-10-16
-6cb7,2018-12-12,2018-02-02
-3cb0,2008-03-11,2008-02-21
-2cb8,2006-10-25,2006-01-03
-7cbt,2020-09-02,2020-06-13
-1cbm,1994-07-31,1993-02-18
-1cbl,1994-07-31,1993-02-18
-7cb5,2021-04-07,2020-06-10
-6cbn,2018-02-21,2018-02-03
-3cbb,2008-10-07,2008-02-21
-4cbc,2014-05-28,2013-10-12
-3cbp,2008-05-13,2008-02-22
-3cbc,2008-09-09,2008-02-21
-5cb9,2016-07-13,2015-06-30
-6cbh,2018-04-04,2018-02-02
-8cb9,2024-01-24,2023-01-25
-7cbq,2021-01-27,2020-06-13
-5cbt,2016-07-20,2015-07-01
-7cbk,2020-08-12,2020-06-12
-2cbc,1993-10-31,1992-06-01
-4cb4,2013-10-30,2013-10-10
-3cbe,2008-08-19,2008-02-21
-1cb8,1999-05-14,1999-03-02
-1cbj,1999-03-03,1999-02-26
-6cbq,2018-02-28,2018-02-05
-1cbv,1994-01-31,1993-03-16
-1cbo,1999-03-10,1999-02-26
-2cbs,1999-12-22,1999-02-22
-7cb7,2021-05-05,2020-06-10
-7cbo,2020-08-12,2020-06-13
-7cbb,2020-09-23,2020-06-11
-8cbh,2023-04-26,2023-01-25
-6cbz,2018-02-28,2018-02-05
-5cbh,2016-07-20,2015-06-30
-2cbb,1993-10-31,1992-06-01
-8cb6,2023-09-13,2023-01-25
-6cbp,2018-02-21,2018-02-03
-3cb2,2008-06-10,2008-02-21
-2cbx,2007-03-06,2006-01-09
-8cb2,2024-02-07,2023-01-25
-7cbs,2020-12-30,2020-06-13
-2cbn,2006-02-15,2006-01-06
-1cbx,1994-01-31,1991-10-31
-4cb5,2013-10-30,2013-10-10
-7cb1,2021-06-16,2020-06-10
-5cbb,2016-08-10,2015-06-30
-2cbd,1993-10-31,1992-06-01
-3cbi,2008-03-11,2008-02-22
-1cb0,1999-07-05,1999-02-26
-4cbb,2014-10-29,2013-10-11
-3cbq,2008-03-04,2008-02-22
-6cba,2019-02-06,2018-02-02
-5cbx,2015-12-23,2015-07-01
-6cb5,2018-04-04,2018-02-02
-6cby,2018-03-14,2018-02-05
-8cbs,2023-06-07,2023-01-25
-1cbs,1995-01-26,1994-09-28
-4cbq,2014-11-05,2013-10-16
-3cbg,2008-06-10,2008-02-22
-2cbt,2006-03-22,2006-01-06
-4cbs,2014-07-09,2013-10-16
-8cbr,2023-06-07,2023-01-25
-8cbc,2024-05-22,2023-01-25
-6cb9,2018-04-18,2018-02-02
-4cby,2013-12-11,2013-10-17
-7cbr,2021-06-09,2020-06-13
-3cb9,2008-08-19,2008-02-21
-8cbe,2024-02-07,2023-01-25
-1cbf,1999-05-11,1998-05-01
-8cb0,2023-09-27,2023-01-24
-2cbi,2006-02-13,2006-01-04
-4cbt,2013-12-11,2013-10-16
-7cbg,2020-10-07,2020-06-12
-4cbk,2014-04-23,2013-10-14
-3cb8,2008-10-28,2008-02-21
-4cb7,2013-10-30,2013-10-10
-5cbj,2016-08-10,2015-06-30
-7cb9,2021-06-16,2020-06-11
-3cba,2008-09-09,2008-02-21
-8cb1,2023-09-13,2023-01-25
-5cb8,2015-09-02,2015-06-30
-6cbd,2018-04-18,2018-02-02
-3cbd,2008-07-01,2008-02-21
-2cbz,2006-05-17,2006-01-10
-5cb2,2015-09-23,2015-06-30
-6cbl,2018-02-21,2018-02-03
-3cb3,2008-03-04,2008-02-21
-5cbk,2015-10-21,2015-07-01
-2cbu,2006-02-03,2006-01-09
-5cby,2015-12-23,2015-07-01
-1cbr,1995-01-26,1994-09-28
-5cbr,2015-12-30,2015-07-01
-8cbf,2024-02-07,2023-01-25
-3cbf,2009-01-13,2008-02-21
-3cbt,2008-03-25,2008-02-22
-7cbj,2021-06-16,2020-06-12
-5cbv,2016-07-20,2015-07-01
-2cbl,1999-05-18,1998-08-28
-4cbu,2014-04-30,2013-10-16
-4cbx,2014-04-30,2013-10-17
-6cbo,2018-02-21,2018-02-03
-5cb0,2016-02-10,2015-06-30
-1cb2,1996-10-14,1995-11-25
-8cbv,2023-06-07,2023-01-25
-5cbi,2016-08-10,2015-06-30
-8cbj,2023-05-24,2023-01-25
-6cbi,2018-07-04,2018-02-03
-1cb4,1999-03-03,1999-02-26
-1cbq,1995-01-26,1994-09-28
-3cbl,2008-03-04,2008-02-22
-7cbh,2020-10-07,2020-06-12
-7cbl,2021-04-28,2020-06-12
-6cb1,2018-03-14,2018-02-01
-5cbl,2015-11-04,2015-07-01
-4cb0,2014-02-12,2013-10-09
-5cbz,2015-12-23,2015-07-01
-6cbs,2019-02-06,2018-02-05
-1cbk,2000-03-01,1999-02-26
-4cbz,2013-11-27,2013-10-17
-5cbf,2016-07-20,2015-06-30
-5cbu,2016-07-20,2015-07-01
-7cba,2021-07-21,2020-06-11
-5cbn,2016-03-30,2015-07-01
-2cb1,2007-01-03,2005-12-28
-3cbm,2008-05-13,2008-02-22
-5cbg,2016-07-20,2015-06-30
-2cbv,2006-02-03,2006-01-09
-2cbo,2006-03-22,2006-01-06
-7cb4,2021-06-09,2020-06-10
-5cb6,2015-08-26,2015-06-30
-8cby,2023-05-10,2023-01-26
-5cbw,2016-07-20,2015-07-01
-4cbj,2014-05-28,2013-10-14
-1cb7,2000-02-28,1999-03-03
-8cbz,2023-05-10,2023-01-26
-5cb5,2015-11-04,2015-06-30
-7cb6,2021-04-07,2020-06-10
-7cbp,2020-07-08,2020-06-13
-5cb4,2015-11-04,2015-06-30
-3cbs,1999-12-22,1999-02-22
-2cbp,1997-04-21,1996-03-16
-7cb2,2021-06-16,2020-06-10
-6cbf,2018-04-04,2018-02-02
-2cb3,2006-01-26,2005-12-29
-6cbm,2018-02-21,2018-02-03
-2cbj,2006-02-13,2006-01-05
-7cbw,2021-06-09,2020-06-15
-8cbt,2023-06-07,2023-01-25
-8cbu,2023-06-07,2023-01-25
-6cbk,2018-03-07,2018-02-03
-2cbf,1999-05-11,1998-05-01
-7cb8,2021-08-18,2020-06-11
-7cbx,2020-09-30,2020-06-15
-2cbq,2006-03-22,2006-01-06
-7cbz,2021-06-23,2020-06-15
-7cbu,2021-06-09,2020-06-14
-2cb2,2006-02-24,2005-12-28
-2cba,1993-10-31,1992-06-01
-5cb3,2015-11-04,2015-06-30
-6cbg,2018-04-04,2018-02-02
-3cbo,2008-05-13,2008-02-22
-5cbm,2015-10-07,2015-07-01
-4cb6,2013-10-30,2013-10-10
-6cbv,2019-02-06,2018-02-05
-8cbd,2024-02-07,2023-01-25
-5cbs,2015-12-30,2015-07-01
-5cb7,2016-06-08,2015-06-30
-6cbt,2019-02-06,2018-02-05
-2cbr,1999-12-21,1999-02-22
-4cbw,2014-04-30,2013-10-17
-7cbi,2020-10-07,2020-06-12
-2j1x,2006-09-20,2006-08-15
-1j1g,2003-05-20,2002-12-04
-4j1b,2013-04-03,2013-02-01
-4j1k,2013-05-01,2013-02-01
-4j1v,2014-08-06,2013-02-02
-8j1o,2024-04-17,2023-04-13
-2j1z,2006-09-20,2006-08-15
-5j16,2017-02-08,2016-03-29
-1j1f,2003-05-20,2002-12-03
-4j1l,2014-02-05,2013-02-01
-3j1f,2013-08-07,2012-02-06
-5j1n,2016-06-29,2016-03-29
-6j1v,2019-09-25,2018-12-29
-1j1d,2003-07-15,2002-12-03
-2j1y,2006-09-20,2006-08-15
-6j1e,2019-11-06,2018-12-28
-1j1q,2004-02-03,2002-12-14
-8j10,2023-05-03,2023-04-12
-6j19,2019-12-04,2018-12-28
-1j1z,2003-04-22,2002-12-24
-2j1m,2007-05-15,2006-08-14
-5j19,2016-06-15,2016-03-29
-1j1e,2003-07-15,2002-12-03
-8j1b,2023-08-09,2023-04-12
-8j1z,2024-04-24,2023-04-13
-1j1t,2004-02-03,2002-12-14
-6j1i,2019-11-06,2018-12-28
-8j1c,2023-08-16,2023-04-12
-1j12,2003-06-17,2002-11-25
-1j1m,2004-02-03,2002-12-10
-5j1s,2016-08-17,2016-03-29
-4j14,2014-01-15,2013-01-31
-6j1t,2020-01-01,2018-12-29
-8j19,2023-06-21,2023-04-12
-1j15,2002-12-23,2002-11-30
-2j1v,2006-09-06,2006-08-15
-8j1v,2023-11-29,2023-04-13
-8j1k,2024-04-17,2023-04-13
-4j16,2014-02-05,2013-02-01
-2j1w,2006-09-20,2006-08-15
-8j1q,2023-06-21,2023-04-13
-6j1w,2019-09-25,2018-12-29
-2j1g,2007-01-23,2006-08-11
-4j1z,2013-07-10,2013-02-03
-1j1s,2004-02-03,2002-12-14
-1j1c,2003-12-03,2002-12-03
-5j14,2016-04-27,2016-03-28
-5j1l,2016-10-19,2016-03-29
-1j1y,2004-02-17,2002-12-24
-1j1u,2003-06-03,2002-12-17
-4j1q,2014-03-19,2013-02-01
-4j1o,2013-03-06,2013-02-01
-2j1u,2006-09-06,2006-08-15
-1j10,2003-06-17,2002-11-25
-2j1r,2006-09-06,2006-08-15
-5j1r,2017-03-29,2016-03-29
-6j1u,2020-01-01,2018-12-29
-4j1w,2013-04-03,2013-02-03
-6j17,2019-12-04,2018-12-28
-2j1n,2006-09-06,2006-08-15
-4j1n,2014-07-23,2013-02-01
-6j15,2019-11-06,2018-12-27
-6j1j,2019-11-06,2018-12-28
-2j1l,2006-09-18,2006-08-14
-2j1p,2007-01-02,2006-08-15
-5j12,2017-04-05,2016-03-28
-8j18,2023-06-21,2023-04-12
-6j1n,2019-09-11,2018-12-28
-5j1t,2016-08-17,2016-03-29
-2j12,2006-08-29,2006-08-08
-4j17,2013-05-01,2013-02-01
-6j1o,2019-05-01,2018-12-28
-5j1y,2017-04-05,2016-03-29
-5j1p,2016-06-29,2016-03-29
-8j11,2023-05-03,2023-04-12
-8j16,2023-05-03,2023-04-12
-1j17,2002-12-23,2002-11-30
-8j1h,2023-08-09,2023-04-12
-2j1s,2006-09-06,2006-08-15
-8j1n,2023-06-21,2023-04-13
-4j12,2013-05-01,2013-01-31
-5j1e,2016-06-15,2016-03-29
-1j1r,2004-02-03,2002-12-14
-2j14,2006-09-06,2006-08-08
-1j18,2003-05-27,2002-12-02
-4j1x,2013-04-03,2013-02-03
-8j1f,2023-08-09,2023-04-12
-5j1q,2017-04-19,2016-03-29
-5j1v,2016-05-04,2016-03-29
-6j10,2019-04-17,2018-12-27
-4j1i,2013-05-01,2013-02-01
-6j1l,2019-05-01,2018-12-28
-4j1r,2013-03-20,2013-02-01
-1j1n,2003-06-10,2002-12-11
-2j1t,2006-09-06,2006-08-15
-4j1p,2014-01-15,2013-02-01
-4j1h,2013-05-01,2013-02-01
-1j1a,2003-03-18,2002-12-03
-8j1e,2023-11-22,2023-04-12
-5j1u,2017-04-05,2016-03-29
-4j1c,2013-05-01,2013-02-01
-4j1t,2014-02-05,2013-02-02
-3j16,2012-02-22,2011-12-12
-1j1b,2003-12-03,2002-12-03
-2j1a,2006-08-22,2006-08-09
-6j1m,2019-09-11,2018-12-28
-6j18,2019-12-04,2018-12-28
-2j17,2007-05-22,2006-08-09
-2j18,2006-12-18,2006-08-09
-1j1w,2003-09-23,2002-12-19
-4j1e,2013-05-01,2013-02-01
-4j1m,2013-02-20,2013-02-01
-1j14,2002-12-23,2002-11-30
-5j1z,2016-04-06,2016-03-29
-4j1a,2013-04-03,2013-02-01
-5j1x,2017-04-05,2016-03-29
-2j19,2006-12-18,2006-08-09
-2j13,2006-10-03,2006-08-08
-2j1e,2006-09-20,2006-08-10
-5j18,2016-05-04,2016-03-29
-1j16,2002-12-23,2002-11-30
-5j1w,2016-05-04,2016-03-29
-3j15,2012-02-22,2011-12-12
-8j1j,2023-09-27,2023-04-13
-5j1m,2016-10-19,2016-03-29
-1j11,2003-06-17,2002-11-25
-8j12,2023-09-27,2023-04-12
-2j16,2007-05-22,2006-08-09
-5j1j,2017-03-29,2016-03-29
-5j11,2017-04-05,2016-03-28
-6j11,2019-07-24,2018-12-27
-6j1f,2019-11-06,2018-12-28
-8j1g,2023-08-16,2023-04-12
-1j1l,2003-12-16,2002-12-10
-4j1f,2013-05-01,2013-02-01
-6j1g,2019-11-06,2018-12-28
-6ujw,2020-05-27,2019-10-03
-1ujk,2004-05-11,2003-08-05
-3uja,2011-11-30,2011-11-07
-7ujf,2022-06-15,2022-03-30
-7ujh,2023-04-05,2022-03-30
-7uj4,2022-12-14,2022-03-30
-5uj7,2017-02-08,2017-01-17
-6uj7,2021-05-05,2019-10-02
-6uj4,2020-04-15,2019-10-02
-5ujf,2017-02-01,2017-01-17
-6ujl,2020-04-15,2019-10-03
-3ujb,2011-11-30,2011-11-07
-3ujn,2012-06-06,2011-11-08
-5uj0,2017-02-08,2017-01-16
-7ujo,2022-06-15,2022-03-31
-7ujt,2022-04-13,2022-03-31
-3uj6,2011-11-30,2011-11-07
-6ujd,2019-10-16,2019-10-02
-6ujj,2020-04-15,2019-10-03
-1ujw,2003-11-25,2003-08-12
-7uj1,2022-09-28,2022-03-30
-5ujx,2017-12-27,2017-01-19
-3ujp,2012-11-14,2011-11-08
-3ujz,2012-05-16,2011-11-08
-3uj7,2011-11-30,2011-11-07
-7ujk,2022-08-17,2022-03-30
-8ujh,2024-05-15,2023-10-11
-5ujp,2017-02-22,2017-01-18
-4ujc,2014-07-30,2014-06-18
-3uj9,2011-11-30,2011-11-07
-7uj3,2023-04-19,2022-03-30
-7ujl,2022-10-05,2022-03-31
-7ujx,2022-12-07,2022-03-31
-5uju,2017-04-12,2017-01-19
-6uj1,2020-10-07,2019-10-02
-4uj3,2015-08-12,2015-04-08
-6ujg,2020-10-07,2019-10-03
-6ujk,2019-10-16,2019-10-03
-3uj2,2011-11-23,2011-11-07
-3ujk,2012-02-15,2011-11-07
-7uj8,2022-06-15,2022-03-30
-3ujq,2012-11-14,2011-11-08
-5ujk,2017-02-08,2017-01-18
-6ujx,2019-12-25,2019-10-03
-6ujz,2019-12-25,2019-10-03
-6ujc,2020-02-05,2019-10-02
-4ujb,2016-04-13,2015-04-09
-4uj4,2015-08-12,2015-04-08
-7uja,2023-04-19,2022-03-30
-8ujx,2024-03-20,2023-10-11
-6ujy,2019-12-25,2019-10-03
-7ujy,2022-06-15,2022-03-31
-6ujf,2020-10-14,2019-10-03
-6ujm,2020-10-07,2019-10-03
-7uj0,2022-11-09,2022-03-29
-4uj8,2016-04-27,2015-04-08
-1uj6,2004-07-13,2003-07-26
-1ujc,2005-01-25,2003-07-31
-5uj4,2017-04-26,2017-01-16
-1ujj,2004-05-11,2003-08-05
-7ujd,2023-01-11,2022-03-30
-7uj5,2023-04-05,2022-03-30
-5uj6,2017-06-28,2017-01-17
-7ujq,2022-04-13,2022-03-31
-5uj3,2017-04-26,2017-01-16
-4ujd,2014-07-30,2014-06-18
-7ujw,2022-06-15,2022-03-31
-8ujg,2024-05-15,2023-10-11
-4uj2,2016-04-13,2015-04-07
-4uj9,2016-04-13,2015-04-09
-6uja,2020-02-05,2019-10-02
-3ujo,2012-11-14,2011-11-08
-5ujt,2017-12-20,2017-01-18
-5ujc,2017-05-03,2017-01-17
-6ujh,2020-04-15,2019-10-03
-8ujy,2023-12-20,2023-10-11
-6ujr,2020-05-27,2019-10-03
-3uj8,2011-11-30,2011-11-07
-1ujb,2005-01-25,2003-07-31
-8ujm,2024-05-15,2023-10-11
-7uje,2022-08-17,2022-03-30
-5ujj,2018-01-17,2017-01-18
-3ujl,2012-02-15,2011-11-07
-7ujn,2022-07-20,2022-03-31
-7ujj,2023-04-12,2022-03-30
-3ujh,2011-11-16,2011-11-07
-6ujn,2020-05-27,2019-10-03
-7ujp,2022-04-13,2022-03-31
-6uj5,2020-10-07,2019-10-02
-6uj6,2020-09-30,2019-10-02
-3uji,2011-12-28,2011-11-07
-1uj5,2004-07-13,2003-07-26
-6ujq,2020-08-19,2019-10-03
-3ujr,2012-08-22,2011-11-08
-7ujc,2022-06-15,2022-03-30
-5ujm,2017-02-08,2017-01-18
-8uje,2024-05-15,2023-10-11
-4uj7,2016-04-27,2015-04-08
-3ujs,2012-08-22,2011-11-08
-6ujt,2020-05-27,2019-10-03
-7ujg,2022-10-05,2022-03-30
-3uj0,2012-02-15,2011-11-07
-1uj2,2004-05-04,2003-07-25
-5uj2,2017-03-22,2017-01-16
-6ujb,2020-02-05,2019-10-02
-3ujc,2011-11-30,2011-11-07
-4uja,2016-04-13,2015-04-09
-5ujo,2017-02-08,2017-01-18
-7ujv,2023-04-05,2022-03-31
-8ujv,2024-03-20,2023-10-11
-4uj1,2016-04-13,2015-04-07
-7ujm,2022-06-15,2022-03-31
-7ujs,2022-04-13,2022-03-31
-6ujp,2020-05-27,2019-10-03
-8ujt,2024-03-20,2023-10-11
-3ujd,2011-11-30,2011-11-07
-5ujb,2017-05-03,2017-01-17
-3ujg,2012-02-15,2011-11-07
-6ujo,2020-08-19,2019-10-03
-3uje,2012-08-22,2011-11-07
-7uju,2022-10-05,2022-03-31
-3ujf,2012-08-22,2011-11-07
-5ujz,2017-05-31,2017-01-19
-4uj5,2015-08-12,2015-04-08
-6ujs,2020-05-27,2019-10-03
-7uj7,2022-05-04,2022-03-30
-8ujf,2024-05-15,2023-10-11
-6uje,2020-10-14,2019-10-03
-1uj0,2003-12-23,2003-07-24
-5ujv,2017-11-08,2017-01-19
-4e45,2013-03-20,2012-03-12
-8e45,2023-06-28,2022-08-17
-4e42,2012-08-29,2012-03-11
-7e47,2023-02-15,2021-02-10
-8e4k,2023-02-22,2022-08-18
-6e4z,2019-04-10,2018-07-18
-6e4v,2019-04-10,2018-07-18
-3e41,2008-08-26,2008-08-08
-5e4j,2016-03-30,2015-10-06
-3e4q,2008-10-21,2008-08-12
-5e4m,2016-10-05,2015-10-06
-8e4o,2022-10-26,2022-08-18
-7e4g,2021-02-24,2021-02-12
-2e46,2008-02-05,2006-12-05
-3e48,2008-08-19,2008-08-11
-7e4l,2021-05-05,2021-02-14
-7e4b,2023-02-15,2021-02-11
-7e4c,2023-02-15,2021-02-11
-1e4a,2000-11-06,2000-06-30
-6e4p,2018-12-12,2018-07-18
-1e4h,2000-08-29,2000-07-04
-1e4b,2000-11-06,2000-06-30
-7e45,2023-02-15,2021-02-10
-6e45,2018-11-14,2018-07-16
-4e47,2012-03-28,2012-03-12
-7e4a,2023-02-15,2021-02-11
-6e4a,2018-09-12,2018-07-17
-6e4u,2018-08-08,2018-07-18
-1e4v,2000-08-04,2000-07-12
-1e4o,2000-08-16,2000-07-11
-3e40,2008-08-26,2008-08-08
-5e4a,2016-03-23,2015-10-05
-1e48,2000-11-06,2000-06-30
-3e4o,2008-10-21,2008-08-12
-3e4n,2009-02-24,2008-08-12
-2e4n,2007-06-19,2006-12-13
-7e4f,2022-02-16,2021-02-11
-2e4p,2007-10-16,2006-12-15
-3e4v,2008-09-02,2008-08-12
-3e4p,2008-10-21,2008-08-12
-5e4t,2016-03-30,2015-10-07
-1e4i,2001-07-05,2000-07-06
-6e4q,2018-09-12,2018-07-18
-4e4p,2012-04-18,2012-03-13
-3e4e,2008-09-16,2008-08-11
-6e47,2018-09-12,2018-07-16
-2e49,2007-03-06,2006-12-05
-4e4k,2013-01-23,2012-03-13
-4e4h,2013-01-30,2012-03-13
-7e46,2022-02-16,2021-02-10
-8e42,2023-06-28,2022-08-17
-1e4n,2000-12-11,2000-07-11
-8e46,2023-06-28,2022-08-17
-6e4c,2019-07-17,2018-07-17
-2e40,2007-03-27,2006-12-01
-5e4l,2016-10-12,2015-10-06
-2e48,2007-03-06,2006-12-05
-4e4f,2012-03-28,2012-03-12
-3e4y,2009-08-18,2008-08-12
-7e4r,2021-07-07,2021-02-15
-3e4z,2009-08-18,2008-08-12
-8e4w,2024-02-07,2022-08-19
-1e4x,2001-07-12,2000-07-12
-5e40,2016-06-01,2015-10-05
-7e4s,2022-02-23,2021-02-15
-8e4m,2022-10-26,2022-08-18
-1e49,2000-11-06,2000-06-30
-6e4d,2019-09-11,2018-07-17
-1e4g,2000-10-18,2000-07-03
-1e4y,2000-08-04,2000-07-12
-1e4e,2001-06-28,2000-07-03
-2e4w,2007-02-27,2006-12-17
-3e45,2008-08-26,2008-08-08
-6e41,2018-11-14,2018-07-16
-6e4e,2018-07-25,2018-07-17
-1e47,2000-11-06,2000-06-30
-2e4g,2007-02-13,2006-12-07
-3e4g,2008-08-26,2008-08-11
-4e4q,2013-01-23,2012-03-13
-3e47,2008-09-02,2008-08-10
-2e4v,2007-02-27,2006-12-17
-7e4j,2022-02-16,2021-02-13
-5e4i,2016-08-31,2015-10-06
-4e4m,2012-05-30,2012-03-13
-7e4t,2021-03-31,2021-02-15
-8e4s,2022-09-21,2022-08-18
-1e42,2000-08-21,2000-06-27
-6e4t,2018-08-08,2018-07-18
-6e49,2018-08-22,2018-07-17
-8e4n,2022-10-26,2022-08-18
-8e4z,2023-02-22,2022-08-19
-8e4l,2022-10-26,2022-08-18
-4e4e,2012-08-22,2012-03-12
-1e4w,2001-07-12,2000-07-12
-6e4r,2018-09-12,2018-07-18
-2e4r,2007-06-19,2006-12-15
-1e40,2001-06-21,2000-06-27
-6e40,2018-11-14,2018-07-16
-4e4x,2012-05-09,2012-03-13
-2e4u,2007-02-27,2006-12-17
-7e4z,2021-07-07,2021-02-16
-7e48,2021-11-24,2021-02-10
-5e4h,2016-06-08,2015-10-06
-5e4n,2016-06-01,2015-10-06
-3e4a,2009-05-19,2008-08-11
-8e4i,2023-02-22,2022-08-18
-2e47,2007-12-11,2006-12-05
-8e40,2023-01-11,2022-08-17
-4e4l,2012-05-30,2012-03-13
-6e4w,2018-08-08,2018-07-18
-1e46,2000-11-06,2000-06-30
-3e4d,2009-08-18,2008-08-11
-4e4a,2012-06-27,2012-03-12
-5e4b,2016-10-05,2015-10-05
-8e4q,2022-10-26,2022-08-18
-6e46,2018-11-14,2018-07-16
-7e4y,2022-02-23,2021-02-16
-8e4a,2023-08-23,2022-08-17
-8e47,2023-06-28,2022-08-17
-6e42,2018-11-14,2018-07-16
-7e4n,2021-10-06,2021-02-14
-4e4z,2013-01-23,2012-03-13
-3e49,2008-08-26,2008-08-11
-7e4u,2022-02-16,2021-02-15
-6e4f,2018-09-05,2018-07-17
-6e4y,2019-04-10,2018-07-18
-5e4x,2015-12-02,2015-10-07
-4e43,2012-05-30,2012-03-11
-2e4a,2007-03-06,2006-12-05
-6e48,2018-09-12,2018-07-16
-4e49,2012-06-27,2012-03-12
-7e4p,2022-02-16,2021-02-14
-5e4r,2015-12-23,2015-10-07
-3e4w,2009-08-18,2008-08-12
-3e46,2008-08-26,2008-08-09
-5e4z,2016-10-12,2015-10-07
-4e4s,2012-03-21,2012-03-13
-8e4x,2022-10-26,2022-08-19
-5e41,2016-12-07,2015-10-05
-6e4l,2019-04-24,2018-07-17
-6e43,2018-11-14,2018-07-16
-3e42,2008-08-26,2008-08-08
-1e4k,2000-08-06,2000-07-07
-2e4h,2007-08-28,2006-12-08
-5e4k,2016-08-10,2015-10-06
-2e4t,2007-09-18,2006-12-16
-8e4f,2023-05-10,2022-08-18
-7e4q,2021-07-07,2021-02-14
-3e44,2008-08-26,2008-08-08
-8e4r,2022-11-23,2022-08-18
-6e4x,2019-05-22,2018-07-18
-5e4f,2016-05-18,2015-10-05
-3e4c,2008-12-30,2008-08-11
-4e4n,2012-05-30,2012-03-13
-1e4m,2001-05-25,2000-07-10
-7e49,2023-02-15,2021-02-11
-8e41,2023-06-28,2022-08-17
-5e4o,2016-03-23,2015-10-06
-8e4t,2023-06-21,2022-08-18
-4e41,2012-08-29,2012-03-11
-1e4c,2000-11-06,2000-06-30
-1e4u,2001-03-31,2000-07-12
-2e4y,2007-02-27,2006-12-17
-8e4c,2022-11-16,2022-08-18
-5e4w,2015-12-02,2015-10-07
-1e43,2001-06-21,2000-06-27
-2e4x,2007-02-27,2006-12-17
-8e4p,2022-10-26,2022-08-18
-5e4e,2015-12-02,2015-10-05
-4e4b,2013-03-27,2012-03-12
-6e44,2018-11-14,2018-07-16
-2e41,2007-06-05,2006-12-01
-7e44,2021-07-28,2021-02-10
-4e4w,2013-02-20,2012-03-13
-6p6t,2020-06-10,2019-06-04
-1p6i,2004-01-13,2003-04-29
-4p6h,2014-06-04,2014-03-24
-3p6q,2010-11-17,2010-10-11
-2p6f,2007-06-12,2007-03-18
-2p6t,2007-04-03,2007-03-19
-6p62,2019-11-20,2019-05-31
-2p6y,2007-06-05,2007-03-19
-8p6u,2024-03-06,2023-05-30
-3p6n,2010-11-17,2010-10-11
-3p65,2011-02-09,2010-10-11
-3p6t,2010-11-17,2010-10-11
-7p6n,2022-07-27,2021-07-16
-3p6f,2011-04-13,2010-10-11
-7p6u,2021-10-27,2021-07-18
-1p6e,2003-09-30,2003-04-29
-8p66,2023-11-01,2023-05-25
-7p6h,2022-03-02,2021-07-16
-4p6r,2014-07-30,2014-03-25
-2p69,2007-04-03,2007-03-16
-2p6d,2007-09-18,2007-03-17
-7p6v,2021-10-06,2021-07-18
-4p6s,2014-07-30,2014-03-25
-8p6z,2024-03-20,2023-05-30
-6p6q,2020-06-10,2019-06-04
-7p6f,2022-05-25,2021-07-16
-3p60,2011-09-21,2010-10-11
-3p67,2010-11-24,2010-10-11
-6p6k,2020-01-15,2019-06-04
-6p6u,2020-06-17,2019-06-04
-4p6x,2014-04-16,2014-03-25
-2p66,2007-04-10,2007-03-16
-8p6f,2024-04-03,2023-05-26
-3p6z,2011-06-15,2010-10-11
-6p6o,2020-06-10,2019-06-04
-3p6v,2010-11-17,2010-10-11
-4p68,2014-07-16,2014-03-22
-8p6x,2024-03-20,2023-05-30
-8p63,2024-05-29,2023-05-25
-7p6x,2021-12-15,2021-07-18
-7p62,2022-09-21,2021-07-15
-1p6n,2004-01-13,2003-04-29
-2p64,2007-06-19,2007-03-16
-1p6l,2004-01-13,2003-04-29
-6p6g,2020-01-15,2019-06-03
-6p6j,2020-03-04,2019-06-04
-2p6m,2007-09-25,2007-03-19
-2p6w,2007-08-21,2007-03-19
-8p62,2024-05-29,2023-05-25
-3p6w,2010-11-17,2010-10-11
-8p67,2024-05-22,2023-05-25
-4p65,2014-10-22,2014-03-21
-3p6e,2011-04-13,2010-10-11
-7p63,2022-09-21,2021-07-15
-1p6o,2003-08-19,2003-04-29
-1p6y,2003-10-07,2003-04-30
-7p6y,2021-10-06,2021-07-18
-1p6c,2003-09-16,2003-04-29
-2p6k,2007-09-18,2007-03-18
-6p67,2019-09-04,2019-06-03
-1p6j,2004-01-13,2003-04-29
-1p62,2003-07-01,2003-04-28
-2p6l,2007-09-25,2007-03-19
-6p6p,2020-07-01,2019-06-04
-7p6t,2022-03-16,2021-07-17
-7p6z,2022-05-25,2021-07-18
-7p6s,2022-03-16,2021-07-17
-6p68,2019-06-19,2019-06-03
-2p6a,2007-04-03,2007-03-16
-6p6d,2020-04-15,2019-06-03
-8p64,2024-03-06,2023-05-25
-3p6b,2011-08-24,2010-10-11
-6p63,2020-06-03,2019-05-31
-2p6z,2007-05-29,2007-03-19
-2p6i,2007-09-18,2007-03-18
-4p6p,2015-03-25,2014-03-25
-4p62,2015-05-27,2014-03-21
-3p6y,2010-11-03,2010-10-11
-3p6m,2010-11-17,2010-10-11
-4p66,2014-07-16,2014-03-21
-3p6u,2010-11-17,2010-10-11
-6p6l,2020-06-10,2019-06-04
-3p6x,2010-11-17,2010-10-11
-1p6b,2003-09-16,2003-04-29
-1p6x,2003-11-04,2003-04-30
-3p6d,2011-04-13,2010-10-11
-3p6g,2011-04-13,2010-10-11
-6p6a,2020-01-29,2019-06-03
-6p6e,2020-01-29,2019-06-03
-4p6f,2014-10-01,2014-03-24
-7p69,2022-09-21,2021-07-15
-6p65,2019-11-20,2019-05-31
-4p6g,2014-10-29,2014-03-24
-6p64,2020-06-03,2019-05-31
-4p6c,2015-03-25,2014-03-24
-1p6w,2003-10-14,2003-04-30
-6p6v,2020-06-10,2019-06-04
-3p6s,2010-11-17,2010-10-11
-6p69,2019-06-19,2019-06-03
-7p64,2022-09-21,2021-07-15
-3p6h,2011-04-13,2010-10-11
-2p67,2007-04-03,2007-03-16
-7p6r,2022-03-16,2021-07-17
-4p6t,2014-07-30,2014-03-25
-1p64,2003-10-07,2003-04-28
-7p61,2022-09-21,2021-07-15
-8p6i,2024-04-03,2023-05-26
-1p6m,2004-01-13,2003-04-29
-7p6w,2021-10-06,2021-07-18
-4p60,2014-11-26,2014-03-20
-4p6w,2014-04-16,2014-03-25
-3p6r,2010-11-17,2010-10-11
-3p6o,2010-11-17,2010-10-11
-3p68,2011-02-09,2010-10-11
-1p60,2003-07-01,2003-04-28
-3p66,2011-02-09,2010-10-11
-6p6m,2020-06-10,2019-06-04
-3p62,2010-11-24,2010-10-11
-2p6b,2007-06-05,2007-03-16
-8p6y,2023-08-30,2023-05-30
-8p6o,2023-07-05,2023-05-27
-6p60,2020-06-03,2019-05-31
-1p6h,2004-01-13,2003-04-29
-4p6a,2015-03-04,2014-03-23
-8p6v,2023-08-30,2023-05-30
-4p69,2014-10-08,2014-03-22
-8p60,2023-06-21,2023-05-24
-1p61,2003-07-01,2003-04-28
-6p6r,2020-06-10,2019-06-04
-2p6g,2007-06-12,2007-03-18
-2p6s,2007-04-03,2007-03-19
-3p61,2011-09-21,2010-10-11
-7p6l,2022-02-09,2021-07-16
-3p64,2011-02-09,2010-10-11
-7p6j,2022-03-02,2021-07-16
-2p6e,2007-06-12,2007-03-18
-1p6d,2003-09-30,2003-04-29
-6p6z,2020-06-10,2019-06-04
-1p6k,2004-01-13,2003-04-29
-3p6p,2010-11-17,2010-10-11
-6p6s,2020-06-10,2019-06-04
-4p6e,2014-10-29,2014-03-24
-8p6w,2024-03-20,2023-05-30
-2gt4,2006-12-12,2006-04-27
-1gt7,2002-05-03,2002-01-14
-7gtj,2024-01-24,2024-01-03
-6gtw,2019-01-16,2018-06-19
-6gtx,2019-01-16,2018-06-19
-3gtv,2010-09-08,2009-03-28
-1gtn,2002-04-05,2002-01-16
-6gtk,2019-07-03,2018-06-18
-7gt8,2024-01-24,2024-01-03
-3gtx,2009-06-30,2009-03-28
-7gts,2024-01-24,2024-01-03
-1gtk,2003-01-16,2002-01-16
-4gt8,2013-08-28,2012-08-28
-4gtt,2012-10-24,2012-08-29
-1gts,1995-02-07,1993-09-15
-8gt4,2023-03-08,2022-09-07
-5gt9,2017-05-17,2016-08-19
-3gte,2009-07-28,2009-03-27
-4gte,2012-10-17,2012-08-28
-2gtn,2006-07-11,2006-04-28
-3gtp,2009-06-09,2009-03-27
-5gt2,2017-02-08,2016-08-18
-5gte,2017-08-23,2016-08-20
-8gtr,2024-02-28,2022-09-08
-1gtb,1995-12-01,1994-12-01
-1gtf,2002-04-05,2002-01-15
-4gtm,2012-10-24,2012-08-28
-6gto,2019-03-06,2018-06-18
-8gto,2023-07-12,2022-09-08
-2gtb,2006-12-26,2006-04-27
-5gt4,2016-11-09,2016-08-18
-4gt1,2012-09-05,2012-08-28
-4gto,2012-10-24,2012-08-29
-8gtv,2023-09-13,2022-09-08
-4gt3,2012-09-12,2012-08-28
-4gtr,2012-10-24,2012-08-29
-4gtv,2012-10-24,2012-08-29
-3gtt,2010-09-08,2009-03-28
-5gt1,2017-07-19,2016-08-18
-4gtc,2012-10-17,2012-08-28
-5gto,2017-07-05,2016-08-22
-3gti,2009-06-30,2009-03-27
-8gtg,2023-09-13,2022-09-08
-2gtq,2006-05-30,2006-04-28
-5gta,2017-08-23,2016-08-19
-6gt2,2019-07-03,2018-06-15
-8gt6,2022-12-28,2022-09-07
-5gt0,2017-02-15,2016-08-18
-8gtm,2023-09-13,2022-09-08
-1gth,2002-04-11,2002-01-15
-5gth,2017-03-15,2016-08-20
-4gtf,2012-10-17,2012-08-28
-4gtp,2012-10-24,2012-08-29
-1gtj,2002-06-13,2002-01-15
-3gts,2009-07-28,2009-03-28
-2gtz,2007-06-12,2006-04-28
-4gta,2012-10-17,2012-08-28
-3gtm,2009-06-09,2009-03-27
-4gtb,2012-10-17,2012-08-28
-6gt3,2019-06-26,2018-06-15
-6gtu,2019-07-03,2018-06-19
-7gt2,2024-01-24,2024-01-03
-5gtz,2017-09-06,2016-08-24
-4gt0,2012-12-19,2012-08-28
-6gtt,2018-06-27,2018-06-19
-8gti,2023-09-13,2022-09-08
-8gtu,2023-07-26,2022-09-08
-2gtl,2006-07-18,2006-04-28
-5gtr,2017-08-30,2016-08-23
-8gtz,2023-09-13,2022-09-09
-4gtz,2012-11-07,2012-08-29
-8gt3,2023-03-08,2022-09-07
-5gtl,2017-09-06,2016-08-21
-1gt4,2003-10-03,2002-01-10
-3gtl,2009-06-09,2009-03-27
-8gt2,2023-03-08,2022-09-07
-4gt7,2012-09-12,2012-08-28
-6gtz,2019-01-16,2018-06-19
-5gt3,2017-02-15,2016-08-18
-8gth,2023-09-13,2022-09-08
-6gty,2019-01-16,2018-06-19
-6gtm,2019-07-03,2018-06-18
-5gt7,2017-08-23,2016-08-18
-5gtd,2017-01-04,2016-08-20
-2gta,2006-05-23,2006-04-27
-4gtq,2012-10-24,2012-08-29
-6gtj,2019-07-03,2018-06-18
-4gtd,2012-10-17,2012-08-28
-3gtc,2009-04-14,2009-03-27
-8gtl,2022-12-28,2022-09-08
-4gts,2012-10-24,2012-08-29
-6gtb,2019-09-11,2018-06-18
-1gtl,2002-06-13,2002-01-16
-1gt5,2003-10-03,2002-01-10
-2gtw,2007-06-12,2006-04-28
-3gta,2010-03-09,2009-03-27
-1gtr,1995-02-07,1993-09-15
-8gt5,2023-03-08,2022-09-07
-6gt0,2019-07-03,2018-06-15
-7gtr,2024-01-24,2024-01-03
-6gt9,2019-06-26,2018-06-16
-4gty,2012-11-07,2012-08-29
-4gtw,2012-11-07,2012-08-29
-6gt8,2019-06-26,2018-06-15
-5gtn,2017-07-05,2016-08-22
-6gtg,2018-12-19,2018-06-18
-7gtc,2024-01-24,2024-01-03
-3gtf,2009-06-30,2009-03-27
-2gtp,2006-05-23,2006-04-28
-5gtc,2017-06-28,2016-08-19
-4gtx,2012-11-07,2012-08-29
-1gte,2002-04-11,2002-01-15
-3gtj,2009-06-09,2009-03-27
-8gt7,2023-09-13,2022-09-07
-3gt8,2009-07-21,2009-03-27
-5gt6,2017-09-06,2016-08-18
-6gtn,2019-07-03,2018-06-18
-3gtd,2009-07-14,2009-03-27
-3gt9,2010-03-09,2009-03-27
-1gtt,2002-03-08,2002-01-18
-1gtq,1996-04-03,1995-09-16
-7gtb,2024-01-24,2024-01-03
-2gtm,2006-05-23,2006-04-28
-4gt9,2012-10-17,2012-08-28
-5gtg,2017-08-23,2016-08-20
-1gt1,2003-10-03,2002-01-10
-3gtk,2009-06-09,2009-03-27
-3gtg,2009-06-09,2009-03-27
-2gt9,2007-06-12,2006-04-27
-1gt9,2002-06-13,2002-01-14
-8gt1,2023-03-08,2022-09-07
-7gtv,2024-01-24,2024-01-03
-8gt0,2023-09-13,2022-09-07
-1gtv,2002-03-28,2002-01-21
-1gtz,2002-06-27,2002-01-22
-2gtx,2006-07-04,2006-04-28
-3gth,2009-06-30,2009-03-27
-3gto,2009-06-09,2009-03-27
-8gtp,2023-07-12,2022-09-08
-7gtp,2024-01-24,2024-01-03
-6gta,2018-08-22,2018-06-17
-7gtq,2024-01-24,2024-01-03
-6gtv,2019-01-16,2018-06-19
-6gth,2018-10-10,2018-06-18
-2gt6,2006-06-06,2006-04-27
-5gti,2017-03-15,2016-08-20
-6gtl,2019-07-03,2018-06-18
-1gtg,2002-06-13,2002-01-15
-5gtk,2017-09-06,2016-08-21
-7gtf,2024-01-24,2024-01-03
-4gt6,2012-09-26,2012-08-28
-5gtw,2017-08-30,2016-08-23
-4gtl,2012-10-17,2012-08-28
-3gtq,2009-06-09,2009-03-27
-4gt2,2013-09-11,2012-08-28
-5gtq,2016-11-09,2016-08-23
-6gtr,2019-03-06,2018-06-18
-3gt3,2009-04-14,2009-03-27
-8gty,2023-09-13,2022-09-09
-6gti,2019-07-03,2018-06-18
-1gti,1999-03-02,1998-01-09
-8gtq,2023-07-12,2022-09-08
-2gtk,2006-09-26,2006-04-28
-8gtw,2023-09-13,2022-09-08
-1gt8,2002-04-11,2002-01-14
-7gtu,2024-01-24,2024-01-03
-2gtv,2006-10-31,2006-04-28
-1gt3,2003-10-03,2002-01-10
-6gtp,2019-03-06,2018-06-18
-2gtf,2007-03-13,2006-04-27
-6gt6,2019-07-17,2018-06-15
-5gty,2017-09-06,2016-08-23
-5xvu,2017-07-12,2017-06-28
-1xvj,2005-09-20,2004-10-28
-5xvc,2018-06-27,2017-06-27
-2xvf,2011-05-04,2010-10-26
-4xvl,2015-03-11,2015-01-27
-6xvk,2020-05-27,2020-01-22
-6xvx,2020-02-19,2020-01-22
-4xvd,2015-04-15,2015-01-27
-2xvm,2011-02-16,2010-10-26
-6xvw,2020-06-03,2020-01-22
-5xv2,2018-07-04,2017-06-26
-2xv2,2010-12-29,2010-10-22
-7xvi,2023-07-05,2022-05-23
-5xvp,2017-10-04,2017-06-28
-2xvi,2011-05-04,2010-10-26
-6xvb,2020-05-27,2020-01-21
-6xv3,2020-07-08,2020-01-21
-8xvf,2024-04-03,2024-01-15
-2xvu,2010-11-10,2010-10-28
-1xvq,2004-12-07,2004-10-28
-6xvj,2020-05-27,2020-01-22
-1xvf,2005-05-03,2004-10-27
-1xvm,2005-07-26,2004-10-28
-7xvv,2023-05-31,2022-05-24
-2xvg,2011-04-13,2010-10-26
-4xv8,2015-02-18,2015-01-26
-8xv5,2024-03-27,2024-01-14
-7xvz,2022-07-20,2022-05-25
-1xvv,2005-03-15,2004-10-28
-7xve,2022-08-10,2022-05-21
-5xvo,2017-10-04,2017-06-28
-4xv4,2015-02-18,2015-01-26
-7xvr,2023-02-15,2022-05-24
-2xvz,2010-12-22,2010-10-28
-6xvt,2020-03-18,2020-01-22
-1xvc,2005-05-03,2004-10-27
-5xvk,2017-08-02,2017-06-28
-1xvp,2004-12-28,2004-10-28
-1xvg,2005-05-03,2004-10-27
-7xvf,2022-08-10,2022-05-22
-8xv9,2024-03-27,2024-01-14
-4xv5,2015-02-25,2015-01-26
-5xv7,2018-03-14,2017-06-26
-5xvg,2018-02-07,2017-06-27
-4xvy,2015-03-04,2015-01-28
-2xvc,2011-02-02,2010-10-25
-2xvj,2011-05-04,2010-10-26
-2xv1,2011-08-10,2010-10-22
-5xve,2018-02-28,2017-06-27
-4xvm,2015-03-11,2015-01-27
-4xv2,2015-10-28,2015-01-26
-2xvv,2010-11-10,2010-10-28
-6xvp,2020-05-13,2020-01-22
-7xv8,2022-12-28,2022-05-21
-7xvj,2023-04-05,2022-05-24
-1xv5,2005-08-30,2004-10-27
-6xvc,2020-07-08,2020-01-21
-4xve,2015-04-15,2015-01-27
-7xvu,2023-05-31,2022-05-24
-5xvs,2018-04-11,2017-06-28
-4xvr,2015-06-17,2015-01-27
-7xvh,2023-01-25,2022-05-23
-4xvg,2016-02-24,2015-01-27
-4xv3,2015-10-28,2015-01-26
-1xve,2005-05-03,2004-10-27
-5xvr,2018-02-28,2017-06-28
-2xv7,2011-01-12,2010-10-23
-6xvh,2021-02-03,2020-01-22
-4xv1,2015-10-28,2015-01-26
-7xv2,2023-05-24,2022-05-20
-2xvw,2010-11-10,2010-10-28
-7xv6,2022-12-28,2022-05-21
-6xv1,2020-10-28,2020-01-21
-8xv2,2024-03-27,2024-01-14
-1xvb,2005-05-03,2004-10-27
-2xv3,2010-12-29,2010-10-22
-6xv0,2020-03-18,2020-01-21
-6xv2,2021-02-03,2020-01-21
-6xvg,2020-10-28,2020-01-22
-2xvd,2011-06-08,2010-10-25
-1xvn,2005-04-12,2004-10-28
-4xvk,2015-03-11,2015-01-27
-5xvq,2017-08-02,2017-06-28
-7xvm,2023-05-24,2022-05-24
-4xv6,2015-02-18,2015-01-26
-5xvx,2018-03-21,2017-06-28
-4xvs,2015-05-06,2015-01-27
-2xve,2011-05-04,2010-10-26
-6xvd,2020-02-19,2020-01-21
-4xvx,2015-02-11,2015-01-28
-4xvu,2015-03-18,2015-01-28
-4xv7,2015-02-18,2015-01-26
-2xvq,2010-11-10,2010-10-27
-1xvd,2005-05-03,2004-10-27
-1xva,1997-01-27,1996-07-20
-4xvq,2015-06-17,2015-01-27
-1xvt,2005-03-15,2004-10-28
-1xvu,2005-03-15,2004-10-28
-6xvu,2021-06-30,2020-01-22
-2xvy,2011-11-16,2010-10-28
-5xvf,2018-02-07,2017-06-27
-5xvv,2018-03-21,2017-06-28
-1xv8,2005-10-11,2004-10-27
-2xva,2011-02-16,2010-10-25
-7xvy,2022-07-20,2022-05-25
-1xvr,2005-04-12,2004-10-28
-6xv6,2020-10-28,2020-01-21
-5xvt,2018-04-25,2017-06-28
-5xvb,2018-06-27,2017-06-27
-5xva,2018-02-07,2017-06-27
-1xv2,2004-12-14,2004-10-26
-6xv9,2020-05-27,2020-01-21
-4xv9,2015-10-28,2015-01-26
-5xvd,2018-06-27,2017-06-27
-2xvt,2010-12-29,2010-10-31
-2xvh,2011-05-04,2010-10-26
-2xvk,2011-04-13,2010-10-26
-2xvl,2011-04-13,2010-10-26
-2xv0,2010-12-29,2010-10-22
-6xva,2020-05-27,2020-01-21
-2xvn,2010-11-03,2010-10-26
-7xvw,2023-05-31,2022-05-25
-5xvz,2018-07-04,2017-06-28
-2xvx,2010-12-22,2010-10-28
-1xvl,2005-04-26,2004-10-28
-6xvf,2020-07-22,2020-01-21
-2xvb,2011-10-26,2010-10-25
-5xvh,2018-02-07,2017-06-28
-5xv0,2018-07-04,2017-06-26
-7xv9,2022-12-28,2022-05-21
-4xva,2015-02-25,2015-01-26
-1xvk,2005-04-12,2004-10-28
-6xv4,2020-03-18,2020-01-21
-6xv7,2020-07-08,2020-01-21
-4xvz,2015-03-04,2015-01-28
-5xvn,2017-10-04,2017-06-28
-4xvt,2015-07-15,2015-01-28
-7xvn,2023-11-29,2022-05-24
-1xvx,2004-12-14,2004-10-28
-5ng2,2017-06-07,2017-03-16
-6ngn,2019-03-13,2018-12-21
-3ngt,2011-04-27,2010-06-13
-6ngm,2019-03-13,2018-12-21
-4ng3,2013-11-13,2013-11-01
-6ng4,2019-03-13,2018-12-21
-6ngh,2019-03-13,2018-12-21
-3nga,2010-12-15,2010-06-11
-7ngp,2021-04-28,2021-02-09
-5ng1,2017-10-25,2017-03-16
-1ngj,1994-08-31,1994-05-17
-6ng3,2019-07-03,2018-12-21
-5ng5,2017-04-19,2017-03-16
-3ngc,2011-03-23,2010-06-11
-4ngn,2014-06-18,2013-11-02
-3ngq,2010-07-28,2010-06-13
-3ngl,2011-04-20,2010-06-12
-7ngk,2022-02-23,2021-02-09
-4ngr,2014-06-18,2013-11-02
-3ng8,2010-12-15,2010-06-11
-7ngr,2022-02-23,2021-02-09
-5ngs,2017-10-04,2017-03-20
-4ng5,2013-11-13,2013-11-01
-6nga,2019-03-13,2018-12-21
-7ngl,2021-04-28,2021-02-09
-3ng6,2010-07-28,2010-06-11
-7ng1,2022-03-02,2021-02-08
-5ngq,2017-08-23,2017-03-20
-6ngq,2019-03-13,2018-12-21
-7ng5,2021-02-24,2021-02-08
-3ng0,2011-06-15,2010-06-10
-4ngt,2014-06-18,2013-11-02
-7ngb,2021-06-09,2021-02-09
-7ngm,2022-02-23,2021-02-09
-4ngy,2014-05-28,2013-11-03
-7ngc,2021-04-07,2021-02-09
-6ngc,2019-03-13,2018-12-21
-1ng1,1999-07-30,1998-04-30
-4ngp,2014-06-18,2013-11-02
-6ngr,2019-03-13,2018-12-21
-5ngb,2017-09-13,2017-03-17
-6ng8,2019-03-13,2018-12-21
-3ngw,2010-08-11,2010-06-13
-3ngy,2011-02-16,2010-06-14
-1ng8,2002-12-31,2002-12-17
-7ngd,2022-02-23,2021-02-09
-6ngs,2019-03-13,2018-12-21
-6ngv,2019-03-13,2018-12-21
-7ng3,2021-04-07,2021-02-08
-6ng7,2019-03-13,2018-12-21
-5nge,2017-10-18,2017-03-17
-4ngm,2014-06-18,2013-11-02
-3ngn,2010-07-28,2010-06-12
-6nge,2019-03-13,2018-12-21
-1ngs,1997-02-12,1996-09-25
-6ng6,2019-03-13,2018-12-21
-5ng6,2017-06-14,2017-03-16
-7ngf,2021-04-28,2021-02-09
-7ngx,2022-02-23,2021-02-09
-2ngr,1999-01-06,1998-07-31
-1ngc,1994-08-31,1994-05-17
-7ngi,2022-02-23,2021-02-09
-4ng2,2013-12-18,2013-11-01
-4ngq,2014-06-18,2013-11-02
-6ngp,2019-03-13,2018-12-21
-4ngu,2013-12-04,2013-11-02
-4ng4,2015-06-24,2013-11-01
-7ngy,2022-02-23,2021-02-09
-6ngy,2019-03-13,2018-12-21
-1ngd,1994-08-31,1994-05-17
-7ngj,2022-02-23,2021-02-09
-7ngq,2021-04-28,2021-02-09
-7ngg,2022-02-23,2021-02-09
-1ngk,2003-05-20,2002-12-17
-5ngu,2017-04-19,2017-03-20
-3ng9,2011-12-21,2010-06-11
-2ng1,1999-07-30,1998-09-11
-4ngw,2014-05-28,2013-11-03
-3ng5,2010-07-07,2010-06-11
-5ngr,2017-10-04,2017-03-20
-1ngf,1994-08-31,1994-05-17
-7ngo,2022-02-23,2021-02-09
-1ng4,2003-04-08,2002-12-16
-7ng6,2021-04-07,2021-02-08
-5ngy,2017-11-01,2017-03-20
-3ngj,2010-07-21,2010-06-11
-7ng4,2021-02-24,2021-02-08
-1ngw,2003-02-04,2002-12-18
-3ngu,2011-04-27,2010-06-13
-4ngj,2014-05-28,2013-11-02
-6ngi,2019-03-13,2018-12-21
-4ng9,2014-01-08,2013-11-01
-6ngw,2019-03-13,2018-12-21
-7nga,2021-11-17,2021-02-08
-6ngz,2019-03-13,2018-12-21
-7ngn,2022-02-23,2021-02-09
-4ngz,2014-05-28,2013-11-03
-3ng2,2010-10-06,2010-06-10
-6ngj,2019-03-13,2018-12-21
-4nge,2014-05-14,2013-11-01
-5ng0,2017-06-07,2017-03-16
-3ngo,2010-07-28,2010-06-12
-6ng1,2019-03-13,2018-12-21
-4ngh,2014-12-03,2013-11-01
-5ngx,2018-05-16,2017-03-20
-5ng7,2018-05-16,2017-03-17
-7ngs,2022-02-23,2021-02-09
-1ngp,1996-07-11,1995-06-23
-5ngt,2017-10-04,2017-03-20
-5ngg,2017-09-27,2017-03-17
-4ngl,2014-05-28,2013-11-02
-6ngk,2019-03-13,2018-12-21
-6ngf,2019-03-13,2018-12-21
-6ngb,2019-03-13,2018-12-21
-4ng6,2014-11-19,2013-11-01
-3ngf,2010-07-07,2010-06-11
-3ng7,2011-03-16,2010-06-11
-1ngi,1994-08-31,1994-05-17
-1ng0,2003-02-04,2002-12-16
-1ng3,2003-04-08,2002-12-16
-5ngf,2017-10-18,2017-03-17
-4ng1,2014-05-28,2013-11-01
-1nga,1994-08-31,1994-05-17
-4ngv,2014-05-28,2013-11-03
-3ngb,2010-07-07,2010-06-11
-4ngo,2014-05-28,2013-11-02
-5ngm,2017-10-04,2017-03-18
-7ngt,2022-02-23,2021-02-09
-5ngl,2017-05-10,2017-03-17
-7ngw,2022-02-23,2021-02-09
-6ng2,2019-03-13,2018-12-21
-1ngg,1994-08-31,1994-05-17
-7nge,2021-12-29,2021-02-09
-3ngz,2011-02-16,2010-06-14
-5ngz,2017-05-03,2017-03-21
-7ngh,2021-09-15,2021-02-09
-6ngl,2019-03-13,2018-12-21
-7ng7,2021-09-15,2021-02-08
-1ngb,1994-08-31,1994-05-17
-4nga,2014-01-08,2013-11-01
-4ngi,2014-05-28,2013-11-02
-1nge,1994-08-31,1994-05-17
-3ng4,2010-07-14,2010-06-10
-4ngk,2014-05-28,2013-11-02
-6ngu,2019-03-13,2018-12-21
-1ngx,2003-03-18,2002-12-18
-6ngx,2019-03-13,2018-12-21
-1ngh,1994-08-31,1994-05-17
-4ng8,2014-05-28,2013-11-01
-3ng1,1999-07-30,1998-09-13
-6ngd,2019-03-13,2018-12-21
-3ngi,2011-01-26,2010-06-11
-1ng9,2003-02-11,2002-12-17
-4ngs,2014-06-18,2013-11-02
-6ng0,2019-05-01,2018-12-21
-6ng5,2019-03-13,2018-12-21
-5ng9,2017-07-26,2017-03-17
-6ngt,2019-03-13,2018-12-21
-7ngu,2022-02-23,2021-02-09
-5s2v,2021-01-13,2020-11-02
-7s2e,2022-07-13,2021-09-03
-5s2w,2021-01-13,2020-11-02
-5s28,2021-01-13,2020-11-02
-3s2n,2011-06-22,2011-05-16
-5s2s,2021-01-13,2020-11-02
-5s24,2021-01-13,2020-11-02
-7s25,2022-10-05,2021-09-03
-3s2u,2012-09-26,2011-05-17
-5s2x,2021-01-13,2020-11-02
-7s2v,2022-09-07,2021-09-03
-5s2t,2021-01-13,2020-11-02
-6s2u,2020-07-08,2019-06-22
-1s2o,2005-02-22,2004-01-09
-7s2w,2022-07-13,2021-09-03
-4s2t,2015-04-22,2015-01-22
-4s2i,2015-02-25,2015-01-20
-7s2x,2022-04-06,2021-09-04
-4s2n,2015-02-25,2015-01-21
-1s2n,2005-02-22,2004-01-09
-5s2u,2021-01-13,2020-11-02
-3s2y,2012-05-30,2011-05-17
-5s2i,2021-01-13,2020-11-02
-5s2d,2021-01-13,2020-11-02
-6s2r,2020-07-15,2019-06-21
-3s2k,2011-11-02,2011-05-16
-1s2i,2004-03-30,2004-01-08
-7s2y,2021-10-27,2021-09-04
-3s2g,2012-06-13,2011-05-16
-1s2q,2004-03-30,2004-01-09
-5s2q,2021-01-13,2020-11-02
-1s2g,2004-03-30,2004-01-08
-3s2p,2011-07-20,2011-05-17
-6s2i,2020-07-15,2019-06-20
-4s28,2015-04-08,2015-01-19
-3s2s,2012-05-16,2011-05-17
-1s2d,2004-03-30,2004-01-08
-7s2k,2023-05-03,2021-09-03
-4s20,2015-02-04,2015-01-16
-3s27,2011-08-24,2011-05-16
-6s2t,2020-07-08,2019-06-22
-3s2z,2011-08-31,2011-05-17
-5s2b,2021-01-13,2020-11-02
-3s21,2012-05-09,2011-05-16
-4s2c,2016-01-20,2015-01-20
-6s26,2019-11-27,2019-06-20
-1s2v,2004-05-04,2004-01-11
-4s2k,2015-02-25,2015-01-20
-7s2i,2023-05-03,2021-09-03
-5s2m,2021-01-13,2020-11-02
-6s2b,2021-04-28,2019-06-20
-4s2y,2015-02-11,2015-01-23
-1s24,2004-05-04,2004-01-08
-4s26,2015-04-08,2015-01-19
-3s2e,2012-06-13,2011-05-16
-6s2v,2020-07-08,2019-06-22
-3s2j,2011-06-22,2011-05-16
-7s2h,2021-10-06,2021-09-03
-7s27,2022-07-13,2021-09-03
-3s2q,2012-05-23,2011-05-17
-6s25,2019-07-31,2019-06-20
-6s2g,2020-04-29,2019-06-20
-7s28,2022-07-13,2021-09-03
-1s20,2004-01-20,2004-01-07
-5s20,2021-01-13,2020-11-02
-5s2h,2021-01-13,2020-11-02
-5s2z,2021-01-13,2020-11-02
-6s2j,2020-01-08,2019-06-21
-4s2l,2015-07-22,2015-01-21
-3s2d,2011-08-10,2011-05-16
-5s2f,2021-01-13,2020-11-02
-3s2v,2011-06-22,2011-05-17
-7s2a,2022-07-13,2021-09-03
-3s2a,2011-06-08,2011-05-16
-7s2r,2022-03-30,2021-09-03
-7s2u,2022-07-13,2021-09-03
-4s2v,2015-02-11,2015-01-23
-3s2f,2012-06-13,2011-05-16
-3s2h,2011-08-17,2011-05-16
-7s2p,2021-10-06,2021-09-03
-7s2z,2021-10-13,2021-09-04
-6s2y,2019-12-18,2019-06-23
-5s2a,2021-01-13,2020-11-02
-4s2x,2015-02-11,2015-01-23
-7s2f,2022-07-13,2021-09-03
-5s2c,2021-01-13,2020-11-02
-5s27,2021-01-13,2020-11-02
-7s2b,2022-07-13,2021-09-03
-1s26,2004-04-13,2004-01-08
-3s28,2011-08-24,2011-05-16
-4s27,2015-04-08,2015-01-19
-3s2l,2011-06-22,2011-05-16
-7s26,2022-10-05,2021-09-03
-1s2k,2004-04-27,2004-01-08
-1s2y,2004-03-30,2004-01-12
-7s2d,2022-07-13,2021-09-03
-7s2q,2022-07-13,2021-09-03
-3s2i,2012-06-13,2011-05-16
-5s2o,2021-01-13,2020-11-02
-3s26,2011-09-28,2011-05-16
-3s2m,2011-06-22,2011-05-16
-4s23,2015-03-25,2015-01-19
-6s23,2020-01-29,2019-06-20
-4s2j,2015-02-25,2015-01-20
-6s27,2019-11-27,2019-06-20
-4s2o,2015-02-25,2015-01-21
-5s26,2021-01-13,2020-11-02
-5s2l,2021-01-13,2020-11-02
-7s2c,2022-07-13,2021-09-03
-7s29,2022-07-13,2021-09-03
-6s2k,2021-01-13,2019-06-21
-5s2r,2021-01-13,2020-11-02
-6s2a,2019-07-31,2019-06-20
-1s2c,2004-03-23,2004-01-08
-6s20,2020-02-05,2019-06-19
-6s2p,2019-07-03,2019-06-21
-4s29,2015-04-08,2015-01-19
-7s2g,2022-07-13,2021-09-03
-3s23,2012-05-09,2011-05-16
-7s2s,2022-03-30,2021-09-03
-5s2y,2021-01-13,2020-11-02
-4s21,2015-07-15,2015-01-17
-5s2j,2021-01-13,2020-11-02
-4s2r,2015-04-22,2015-01-22
-5s2k,2021-01-13,2020-11-02
-5s29,2021-01-13,2020-11-02
-3s22,2011-06-29,2011-05-16
-6s2h,2020-04-29,2019-06-20
-1s22,2004-02-17,2004-01-07
-6s22,2019-12-25,2019-06-20
-5s2g,2021-01-13,2020-11-02
-3s20,2012-05-16,2011-05-16
-3s2o,2011-06-01,2011-05-17
-4s25,2015-04-08,2015-01-19
-5s2n,2021-01-13,2020-11-02
-4s2b,2016-01-20,2015-01-20
-6s2z,2019-12-18,2019-06-23
-6s24,2019-12-25,2019-06-20
-3s2x,2011-07-27,2011-05-17
-6s21,2020-02-05,2019-06-19
-3s29,2011-08-24,2011-05-16
-7s2m,2023-05-03,2021-09-03
-4s2u,2016-01-27,2015-01-23
-1s2z,2004-06-22,2004-01-12
-5s22,2021-01-13,2020-11-02
-5s2e,2021-01-13,2020-11-02
-5s2p,2021-01-13,2020-11-02
-4bzr,2014-02-26,2013-07-29
-2bz9,2006-12-07,2005-08-12
-1bz0,1998-11-11,1998-11-04
-5bzc,2016-06-29,2015-06-11
-5bz0,2016-06-15,2015-06-11
-2bz7,2006-11-20,2005-08-12
-1bzx,1998-11-11,1998-11-05
-8bz3,2023-03-01,2022-12-14
-8bzv,2023-01-18,2022-12-15
-6bzw,2018-06-20,2017-12-26
-8bz0,2023-08-02,2022-12-14
-6bzp,2018-04-04,2017-12-25
-6bzi,2019-03-20,2017-12-24
-3bze,2008-04-29,2008-01-17
-4bz2,2014-08-13,2013-07-23
-3bz8,2008-02-19,2008-01-17
-4bz5,2013-08-14,2013-07-24
-1bzl,1999-11-10,1998-11-02
-5bzg,2016-06-29,2015-06-11
-8bzb,2023-08-02,2022-12-14
-7bzj,2020-12-09,2020-04-28
-4bz0,2014-04-23,2013-07-22
-7bz5,2020-05-13,2020-04-26
-3bzj,2008-12-09,2008-01-18
-4bzd,2014-08-13,2013-07-25
-4bz7,2013-08-14,2013-07-24
-2bz5,2005-10-12,2005-08-11
-6bzx,2019-01-09,2017-12-26
-8bzz,2023-12-27,2022-12-15
-1bzc,1999-02-16,1998-10-27
-2bzk,2005-11-03,2005-08-18
-6bz0,2018-01-03,2017-12-21
-5bzh,2016-06-29,2015-06-11
-2bzc,2006-11-20,2005-08-15
-8bzp,2023-08-02,2022-12-15
-5bz4,2016-05-18,2015-06-11
-5bzm,2016-06-29,2015-06-11
-5bzu,2015-09-23,2015-06-11
-1bz1,1998-11-11,1998-11-05
-2bzi,2005-12-08,2005-08-18
-5bza,2015-09-16,2015-06-11
-2bz6,2006-02-22,2005-08-11
-7bzi,2021-04-28,2020-04-28
-5bzt,2016-06-29,2015-06-11
-6bzn,2019-03-20,2017-12-25
-6bzc,2018-01-10,2017-12-22
-5bzr,2016-06-29,2015-06-11
-2bz0,2005-08-19,2005-08-09
-3bz0,2009-01-20,2008-01-17
-5bzv,2015-09-23,2015-06-11
-8bzl,2023-12-27,2022-12-15
-5bzw,2016-05-25,2015-06-11
-5bzj,2016-06-29,2015-06-11
-6bzz,2019-03-20,2017-12-26
-7bzm,2020-07-08,2020-04-28
-7bz3,2021-04-28,2020-04-26
-6bzd,2018-05-09,2017-12-22
-8bzj,2023-01-18,2022-12-14
-1bz9,1999-05-24,1998-11-06
-2bzs,2005-09-23,2005-08-22
-8bz6,2023-12-27,2022-12-14
-5bzf,2016-06-29,2015-06-11
-1bzm,1994-04-30,1993-11-28
-5bzl,2016-06-29,2015-06-11
-1bzb,1998-11-11,1998-10-27
-6bz2,2018-02-28,2017-12-22
-8bz1,2023-05-03,2022-12-14
-8bz8,2023-12-27,2022-12-14
-3bz4,2008-07-01,2008-01-17
-5bzk,2016-06-29,2015-06-11
-7bzg,2021-02-03,2020-04-27
-6bzm,2018-04-04,2017-12-24
-7bz0,2021-03-10,2020-04-26
-4bz9,2013-08-14,2013-07-24
-8bzc,2023-12-27,2022-12-14
-3bz7,2008-02-19,2008-01-17
-1bzz,1998-11-11,1998-11-04
-1bzh,1999-02-16,1998-10-28
-4bzi,2013-09-18,2013-07-26
-4bzq,2014-08-13,2013-07-29
-5bze,2016-06-29,2015-06-11
-2bzf,2005-09-15,2005-08-16
-5bzb,2016-02-24,2015-06-11
-2bz1,2005-08-19,2005-08-09
-4bzn,2013-10-30,2013-07-29
-1bz6,1999-05-10,1998-11-05
-6bzr,2019-01-23,2017-12-25
-7bz4,2021-04-28,2020-04-26
-4bzc,2013-10-23,2013-07-25
-8bzf,2023-12-27,2022-12-14
-1bzp,1999-05-10,1998-11-02
-8bz7,2023-12-27,2022-12-14
-1bzy,1999-06-22,1998-11-05
-8bzy,2023-03-22,2022-12-15
-7bzl,2021-01-27,2020-04-28
-1bzr,1999-05-10,1998-11-03
-3bz3,2008-04-01,2008-01-17
-3bz9,2008-02-19,2008-01-17
-6bzq,2019-03-20,2017-12-25
-7bzt,2020-07-22,2020-04-28
-4bzo,2013-10-30,2013-07-29
-7bzc,2020-09-23,2020-04-27
-1bzj,1999-02-16,1998-10-29
-5bzn,2016-06-29,2015-06-11
-3bzl,2008-04-22,2008-01-18
-6bza,2019-03-20,2017-12-22
-2bza,1999-03-23,1999-03-16
-6bzt,2019-03-20,2017-12-26
-7bz1,2021-04-28,2020-04-26
-6bz3,2018-04-04,2017-12-22
-4bzx,2014-08-13,2013-07-30
-8bzx,2023-06-14,2022-12-15
-5bzp,2016-06-29,2015-06-11
-4bz6,2013-08-14,2013-07-24
-2bz8,2005-10-05,2005-08-12
-8bza,2023-08-02,2022-12-14
-8bzw,2023-08-02,2022-12-15
-6bz9,2018-06-13,2017-12-22
-4bzg,2014-08-13,2013-07-25
-3bzn,2008-05-20,2008-01-18
-7bzf,2020-06-03,2020-04-27
-4bz4,2014-02-19,2013-07-24
-8bzs,2023-09-13,2022-12-15
-2bzn,2005-09-02,2005-08-19
-3bzu,2008-06-10,2008-01-18
-2bzd,2005-08-19,2005-08-16
-7bz2,2020-08-05,2020-04-26
-4bz8,2013-08-14,2013-07-24
-4bz3,2014-08-13,2013-07-23
-3bzf,2008-04-29,2008-01-17
-5bzq,2016-06-29,2015-06-11
-4bzs,2014-02-26,2013-07-29
-5bzs,2016-06-29,2015-06-11
-7bzz,2020-09-16,2020-04-29
-8bzn,2023-12-27,2022-12-15
-4bz1,2014-08-13,2013-07-23
-6bzu,2018-06-20,2017-12-26
-7bzu,2020-07-22,2020-04-28
-2bzg,2005-08-25,2005-08-17
-1bzf,1999-05-18,1998-10-28
-3bza,2008-05-13,2008-01-17
-4bzp,2014-08-06,2013-07-29
-3bzi,2008-02-05,2008-01-18
-1bzs,2000-05-31,1998-11-04
-1bzw,1998-11-11,1998-11-05
-6bz4,2018-06-13,2017-12-22
-6bzo,2018-03-28,2017-12-25
-6bz8,2018-11-14,2017-12-22
-4bzf,2014-08-13,2013-07-25
-6bz7,2018-11-14,2017-12-22
-7bzb,2020-09-23,2020-04-27
-2bzj,2005-10-12,2005-08-18
-2bzz,2006-01-18,2005-08-24
-5bzo,2016-06-29,2015-06-11
-5bzi,2016-06-29,2015-06-11
-8bzi,2023-01-18,2022-12-14
-1bzo,1999-04-09,1998-11-02
-8bz9,2023-08-30,2022-12-14
-4bzh,2014-08-13,2013-07-25
-6bz6,2018-11-14,2017-12-22
-4bzb,2013-10-23,2013-07-25
-1jom,1996-11-08,1996-02-25
-2jox,2007-08-21,2007-04-07
-5job,2016-05-11,2016-05-02
-7job,2020-11-04,2020-08-06
-4joj,2014-01-22,2013-03-18
-6jon,2019-06-26,2019-03-22
-4joh,2014-01-22,2013-03-18
-5jop,2017-03-22,2016-05-02
-5joo,2017-08-02,2016-05-02
-7jo0,2020-11-04,2020-08-05
-6jo6,2019-06-19,2019-03-20
-7joc,2020-11-04,2020-08-06
-5jo9,2016-11-09,2016-05-02
-6jo1,2020-03-18,2019-03-19
-4jo2,2013-07-31,2013-03-16
-5joz,2016-08-10,2016-05-03
-1joi,1997-12-10,1997-06-09
-8jot,2024-03-27,2023-06-08
-2jog,2007-05-22,2007-03-10
-1joj,2001-12-19,2001-07-30
-7jo1,2020-11-04,2020-08-05
-4jou,2014-03-19,2013-03-19
-5joy,2016-08-10,2016-05-03
-8joo,2023-11-15,2023-06-08
-8joq,2023-10-11,2023-06-08
-5jo0,2016-08-24,2016-05-01
-8joj,2023-07-12,2023-06-07
-1joa,1997-01-11,1996-07-02
-8jok,2024-04-17,2023-06-07
-7jo2,2020-11-04,2020-08-05
-8jol,2023-06-28,2023-06-07
-5jou,2016-08-10,2016-05-03
-7jo3,2020-11-04,2020-08-05
-1jof,2002-04-12,2001-07-28
-4joa,2013-07-17,2013-03-18
-6jog,2019-04-03,2019-03-20
-1jop,2003-06-17,2001-07-30
-4jop,2014-01-22,2013-03-18
-1jou,2001-08-10,2001-07-31
-6jo0,2019-10-02,2019-03-19
-7jo9,2020-09-16,2020-08-06
-1jol,1996-11-08,1996-02-25
-1jo3,2001-08-08,2001-07-26
-8jo4,2024-05-01,2023-06-07
-8joy,2023-10-11,2023-06-09
-6joq,2019-06-26,2019-03-22
-1joc,2001-12-28,2001-07-27
-5jos,2017-05-03,2016-05-03
-4jo0,2013-09-11,2013-03-16
-7jod,2021-07-21,2020-08-06
-6jou,2020-03-25,2019-03-23
-6jof,2019-09-04,2019-03-20
-2joa,2007-11-20,2007-03-01
-4jos,2013-04-03,2013-03-18
-2jo9,2007-04-17,2007-03-01
-5joh,2016-11-02,2016-05-02
-6joo,2019-04-17,2019-03-22
-7joz,2021-04-14,2020-08-07
-5jo2,2016-09-07,2016-05-01
-4jor,2014-01-22,2013-03-18
-5joj,2017-04-19,2016-05-02
-5jov,2016-08-10,2016-05-03
-6jo3,2019-04-03,2019-03-20
-1jo4,2001-08-08,2001-07-26
-4joe,2014-01-22,2013-03-18
-7joa,2020-09-16,2020-08-06
-4jo8,2013-05-22,2013-03-18
-7jor,2021-09-08,2020-08-07
-8jop,2023-08-16,2023-06-08
-6joz,2020-01-29,2019-03-25
-1joq,2001-08-22,2001-07-30
-5jom,2016-08-17,2016-05-02
-5jo3,2017-05-03,2016-05-01
-1jod,2001-08-22,2001-07-27
-4joo,2013-04-10,2013-03-18
-4jog,2014-01-22,2013-03-18
-5jon,2016-11-30,2016-05-02
-1jok,2001-08-22,2001-07-30
-7jof,2021-06-16,2020-08-06
-5jog,2016-11-02,2016-05-02
-6jom,2020-03-25,2019-03-22
-6jow,2020-03-25,2019-03-24
-5jox,2016-08-10,2016-05-03
-4jom,2013-05-29,2013-03-18
-6joj,2020-03-25,2019-03-22
-6jod,2020-01-15,2019-03-20
-6jo8,2019-05-15,2019-03-20
-6jol,2020-03-25,2019-03-22
-6jok,2020-03-25,2019-03-22
-6jo5,2019-06-19,2019-03-20
-6joi,2020-03-25,2019-03-22
-4jo3,2013-07-31,2013-03-16
-1jot,1998-12-30,1997-12-05
-1job,2001-08-22,2001-07-27
-5jo1,2016-09-07,2016-05-01
-6joe,2019-09-04,2019-03-20
-4jo1,2013-07-31,2013-03-16
-4jok,2014-01-22,2013-03-18
-1joe,2001-08-08,2001-07-27
-6jop,2019-06-26,2019-03-22
-6jov,2020-01-29,2019-03-23
-7jov,2020-09-02,2020-08-07
-8jo3,2024-05-01,2023-06-07
-7joo,2020-10-14,2020-08-06
-7jom,2021-06-16,2020-08-06
-8jo0,2023-06-28,2023-06-06
-8joz,2023-08-30,2023-06-09
-7jow,2021-07-21,2020-08-07
-7jou,2020-09-02,2020-08-07
-4jof,2014-01-22,2013-03-18
-4jo5,2013-07-17,2013-03-16
-5r9f,2020-07-22,2020-03-04
-7r9z,2022-01-12,2021-06-29
-8r9q,2024-01-31,2023-11-30
-1r9j,2004-11-09,2003-10-30
-5r9v,2020-07-22,2020-03-04
-3r9b,2012-04-04,2011-03-25
-5r9x,2020-07-22,2020-03-04
-1r9z,2004-10-05,2003-10-31
-2r9w,2008-04-15,2007-09-13
-5r9a,2020-07-22,2020-03-04
-4r9c,2015-03-11,2014-09-04
-3r92,2011-06-08,2011-03-24
-7r97,2022-07-20,2021-06-28
-8r9s,2024-05-29,2023-11-30
-3r96,2011-04-20,2011-03-24
-8r9g,2024-01-31,2023-11-30
-2r9l,2008-01-08,2007-09-13
-4r9b,2015-03-11,2014-09-04
-5r94,2020-07-22,2020-03-04
-6r9w,2019-12-25,2019-04-04
-4r9i,2015-09-09,2014-09-05
-6r9q,2019-05-22,2019-04-03
-3r9u,2011-04-06,2011-03-25
-5r9b,2020-07-22,2020-03-04
-6r9u,2019-11-27,2019-04-04
-8r9x,2024-06-05,2023-11-30
-4r9x,2014-09-17,2014-09-08
-2r9o,2007-12-18,2007-09-13
-5r9d,2020-07-22,2020-03-04
-2r9z,2008-02-19,2007-09-14
-8r9c,2024-01-31,2023-11-30
-8r9b,2024-05-29,2023-11-30
-5r93,2020-07-22,2020-03-04
-5r9c,2020-07-22,2020-03-04
-2r94,2008-03-18,2007-09-12
-8r9z,2024-06-05,2023-11-30
-2r9n,2007-12-18,2007-09-13
-6r9s,2019-11-27,2019-04-04
-8r9e,2024-01-31,2023-11-30
-2r9c,2008-08-26,2007-09-12
-8r92,2024-01-31,2023-11-30
-6r9p,2019-05-22,2019-04-03
-4r9v,2014-12-03,2014-09-08
-3r94,2012-05-02,2011-03-24
-5r9j,2020-07-22,2020-03-04
-8r9u,2024-05-29,2023-11-30
-5r9q,2020-07-22,2020-03-04
-7r94,2022-07-06,2021-06-28
-8r9w,2024-06-05,2023-11-30
-5r9l,2020-07-22,2020-03-04
-8r95,2024-01-31,2023-11-30
-3r9j,2011-08-17,2011-03-25
-3r9c,2012-03-28,2011-03-25
-3r9i,2011-08-17,2011-03-25
-5r9y,2020-07-22,2020-03-04
-5r9i,2020-07-22,2020-03-04
-3r9f,2011-04-20,2011-03-25
-4r9r,2015-01-21,2014-09-07
-7r9w,2022-01-12,2021-06-29
-4r95,2014-11-05,2014-09-03
-8r9d,2024-01-31,2023-11-30
-4r92,2014-11-05,2014-09-03
-3r9g,2011-04-27,2011-03-25
-5r9g,2020-07-22,2020-03-04
-2r9e,2008-09-30,2007-09-12
-8r9m,2024-01-31,2023-11-30
-5r9k,2020-07-22,2020-03-04
-3r9o,2012-10-31,2011-03-25
-5r9o,2020-07-22,2020-03-04
-4r94,2015-01-21,2014-09-03
-6r9o,2019-05-22,2019-04-03
-2r9j,2007-10-09,2007-09-13
-8r9k,2024-01-31,2023-11-30
-5r98,2020-07-22,2020-03-04
-2r93,2007-11-27,2007-09-12
-3r9v,2011-12-07,2011-03-26
-7r9x,2022-07-13,2021-06-29
-4r97,2015-12-16,2014-09-03
-6r99,2020-04-22,2019-04-03
-2r97,2008-09-23,2007-09-12
-4r9a,2015-03-11,2014-09-04
-1r9q,2004-02-24,2003-10-30
-8r94,2024-01-31,2023-11-30
-1r9x,2004-10-05,2003-10-31
-3r9x,2011-06-22,2011-03-26
-7r9p,2022-01-05,2021-06-29
-1r9t,2004-11-16,2003-10-30
-2r9k,2007-10-30,2007-09-13
-4r98,2015-02-11,2014-09-03
-1r9o,2004-06-15,2003-10-30
-5r9u,2020-07-22,2020-03-04
-4r9k,2014-09-24,2014-09-05
-5r92,2020-07-22,2020-03-04
-4r9g,2014-10-29,2014-09-04
-8r9l,2024-01-31,2023-11-30
-3r9d,2012-10-31,2011-03-25
-8r9p,2024-01-31,2023-11-30
-1r9n,2005-03-29,2003-10-30
-2r9x,2008-04-15,2007-09-13
-5r9n,2020-07-22,2020-03-04
-5r99,2020-07-22,2020-03-04
-5r97,2020-07-22,2020-03-04
-8r9n,2024-01-31,2023-11-30
-6r9r,2019-10-02,2019-04-03
-2r98,2008-01-15,2007-09-12
-3r9w,2011-06-22,2011-03-26
-8r9y,2024-06-05,2023-11-30
-2r9m,2007-12-18,2007-09-13
-4r9s,2015-01-21,2014-09-07
-5r9m,2020-07-22,2020-03-04
-7r9t,2022-01-05,2021-06-29
-5r9e,2020-07-22,2020-03-04
-7r9l,2022-01-05,2021-06-29
-3r99,2012-04-04,2011-03-25
-4r9m,2014-11-05,2014-09-05
-4r90,2015-06-24,2014-09-03
-4r91,2014-11-05,2014-09-03
-5r90,2020-07-22,2020-03-04
-8r9r,2024-03-20,2023-11-30
-7r91,2021-07-28,2021-06-28
-4r9t,2014-11-05,2014-09-08
-1r9m,2004-06-29,2003-10-30
-7r9c,2022-01-19,2021-06-29
-3r98,2012-04-04,2011-03-25
-3r9e,2011-04-20,2011-03-25
-4r9u,2014-11-19,2014-09-08
-8r9f,2024-01-31,2023-11-30
-5r95,2020-07-22,2020-03-04
-5r9r,2020-07-22,2020-03-04
-6r9m,2019-05-22,2019-04-03
-5r9s,2020-07-22,2020-03-04
-5r9p,2020-07-22,2020-03-04
-5r96,2020-07-22,2020-03-04
-1r9s,2004-11-16,2003-10-30
-8r9o,2024-05-29,2023-11-30
-2r9q,2007-10-02,2007-09-13
-6r9x,2019-11-27,2019-04-04
-6r9h,2021-02-03,2019-04-03
-6r9v,2020-02-12,2019-04-04
-8r99,2024-05-29,2023-11-30
-8r93,2024-01-31,2023-11-30
-3r9n,2012-10-31,2011-03-25
-6r9n,2019-06-19,2019-04-03
-8r9i,2024-01-31,2023-11-30
-8r91,2024-01-31,2023-11-30
-1r9p,2004-11-09,2003-10-30
-7r9y,2022-04-06,2021-06-29
-7r9n,2022-01-05,2021-06-29
-2r96,2008-09-23,2007-09-12
-1r9c,2004-02-10,2003-10-28
-4r9d,2015-03-11,2014-09-04
-7r9v,2022-04-06,2021-06-29
-1r94,2003-12-23,2003-10-28
-4r9l,2014-09-24,2014-09-05
-2r9r,2007-11-20,2007-09-13
-5r91,2020-07-22,2020-03-04
-5r9h,2020-07-22,2020-03-04
-6r9j,2019-05-22,2019-04-03
-3r9h,2012-10-31,2011-03-25
-4r93,2014-11-05,2014-09-03
-2r9s,2007-10-16,2007-09-13
-2r9b,2007-11-27,2007-09-12
-1r9y,2004-10-05,2003-10-31
-5r9z,2020-07-22,2020-03-04
-4r9j,2014-11-05,2014-09-05
-3r91,2011-05-11,2011-03-24
-3r9r,2011-04-20,2011-03-25
-8r9h,2024-01-31,2023-11-30
-2r9f,2008-08-26,2007-09-12
-2r92,2007-11-27,2007-09-12
-3r95,2011-04-20,2011-03-24
-8r9a,2024-05-29,2023-11-30
-5r9w,2020-07-22,2020-03-04
-5r9t,2020-07-22,2020-03-04
-8r9j,2024-01-31,2023-11-30
-2r9v,2007-10-02,2007-09-13
-8r90,2024-01-31,2023-11-30
-4r9f,2014-10-29,2014-09-04
-8g70,2024-02-21,2023-02-16
-1g71,2001-01-10,2000-11-08
-6g7q,2018-09-12,2018-04-06
-8g7u,2023-11-15,2023-02-17
-6g78,2019-04-17,2018-04-04
-2g71,2007-02-13,2006-02-27
-1g79,2000-11-29,2000-11-09
-3g72,2009-06-30,2009-02-09
-6g76,2019-04-17,2018-04-04
-8g7o,2023-07-12,2023-02-16
-1g7g,2001-06-06,2000-11-10
-1g78,2000-11-29,2000-11-09
-2g7z,2006-04-04,2006-03-01
-1g7b,2001-08-03,2000-11-09
-1g7c,2000-12-06,2000-11-10
-4g7g,2013-07-24,2012-07-20
-6g7j,2018-06-27,2018-04-06
-6g7o,2019-01-02,2018-04-06
-4g70,2013-07-24,2012-07-19
-4g7a,2013-05-29,2012-07-20
-6g7p,2018-09-12,2018-04-06
-3g7j,2010-02-16,2009-02-10
-4g7r,2013-07-24,2012-07-20
-1g7w,2000-11-29,2000-11-15
-4g71,2013-07-24,2012-07-19
-8g7b,2024-02-21,2023-02-16
-2g72,2007-02-13,2006-02-27
-3g7b,2010-02-09,2009-02-09
-8g7w,2023-06-07,2023-02-17
-4g73,2012-10-24,2012-07-19
-4g72,2013-07-24,2012-07-19
-1g7s,2000-12-06,2000-11-14
-2g73,2006-04-18,2006-02-27
-8g7n,2023-07-12,2023-02-16
-1g7v,2001-05-16,2000-11-14
-8g75,2024-01-24,2023-02-16
-1g7p,2002-07-17,2000-11-13
-3g7w,2009-06-23,2009-02-11
-8g7c,2024-02-21,2023-02-16
-6g7n,2018-09-12,2018-04-06
-2g76,2006-03-21,2006-02-27
-3g77,2009-09-22,2009-02-09
-8g77,2024-02-21,2023-02-16
-3g70,2009-06-30,2009-02-09
-3g7f,2009-09-22,2009-02-09
-2g7y,2006-09-05,2006-03-01
-1g7x,2000-11-29,2000-11-15
-6g77,2019-04-17,2018-04-04
-3g7r,2009-03-10,2009-02-10
-3g7i,2010-02-16,2009-02-10
-4g7q,2013-07-24,2012-07-20
-8g73,2024-01-24,2023-02-16
-3g71,2009-04-28,2009-02-09
-3g7m,2010-03-16,2009-02-10
-2g77,2006-07-25,2006-02-27
-3g76,2009-05-12,2009-02-09
-6g79,2018-06-20,2018-04-05
-3g75,2010-02-09,2009-02-09
-4g7s,2013-07-24,2012-07-20
-8g7f,2023-06-14,2023-02-16
-3g7d,2009-06-09,2009-02-09
-8g7v,2023-11-15,2023-02-17
-2g7m,2007-03-06,2006-02-28
-2g70,2007-02-13,2006-02-27
-4g74,2012-10-24,2012-07-19
-4g7t,2012-10-31,2012-07-20
-4g7p,2012-10-31,2012-07-20
-6g7i,2018-06-27,2018-04-06
-3g7e,2010-02-09,2009-02-09
-1g7a,2001-08-03,2000-11-09
-6g7f,2018-09-12,2018-04-05
-8g74,2024-01-24,2023-02-16
-6g7h,2018-06-27,2018-04-06
-8g71,2024-02-21,2023-02-16
-8g7l,2023-07-12,2023-02-16
-2g7n,2007-03-13,2006-02-28
-8g7i,2023-06-14,2023-02-16
-8g7e,2023-06-21,2023-02-16
-4g7h,2012-10-31,2012-07-20
-1g72,2001-01-24,2000-11-08
-1g7y,2000-11-29,2000-11-15
-2g7f,2006-10-31,2006-02-28
-2g7q,2006-08-15,2006-02-28
-6g71,2019-03-13,2018-04-04
-4g7y,2014-02-05,2012-07-20
-8g7q,2024-03-06,2023-02-16
-4g7e,2013-06-05,2012-07-20
-4g7u,2012-10-31,2012-07-20
-6g7k,2018-06-27,2018-04-06
-1g7t,2000-12-01,2000-11-14
-4g7o,2012-10-31,2012-07-20
-2g79,2007-04-17,2006-02-27
-2g7b,2007-04-17,2006-02-27
-1g76,2000-11-29,2000-11-09
-3g73,2009-03-03,2009-02-09
-6g7a,2019-03-13,2018-04-05
-2g7c,2006-04-18,2006-02-28
-8g76,2024-02-21,2023-02-16
-6g72,2018-06-06,2018-04-04
-1g77,2000-11-29,2000-11-09
-8g78,2024-02-21,2023-02-16
-2g7p,2006-08-15,2006-02-28
-8g7s,2024-03-06,2023-02-16
-8g7r,2024-03-06,2023-02-16
-4g77,2012-08-29,2012-07-20
-4g7z,2012-10-31,2012-07-20
-4g75,2012-09-12,2012-07-20
-6g74,2018-04-25,2018-04-04
-1g73,2001-01-10,2000-11-08
-3g7l,2009-04-21,2009-02-10
-8g7t,2023-11-15,2023-02-17
-6g7l,2018-06-27,2018-04-06
-2g74,2006-04-18,2006-02-27
-4g7f,2012-08-29,2012-07-20
-4g7l,2012-10-31,2012-07-20
-3g7v,2009-06-23,2009-02-10
-3g7x,2010-02-16,2009-02-11
-8g7h,2023-06-14,2023-02-16
-6g7m,2019-04-03,2018-04-06
-2g78,2007-04-17,2006-02-27
-1g7q,2002-07-17,2000-11-13
-8g7g,2023-06-14,2023-02-16
-6g7r,2019-02-27,2018-04-06
-8g7m,2023-07-12,2023-02-16
-8g7a,2024-02-21,2023-02-16
-8g7p,2024-03-06,2023-02-16
-1g7f,2001-06-06,2000-11-10
-6g7d,2019-01-16,2018-04-05
-2viq,2008-01-22,2007-12-05
-6viy,2020-05-06,2020-01-14
-7vio,2022-06-08,2021-09-27
-3vi8,2012-08-29,2011-09-25
-3vik,2012-07-04,2011-10-03
-3vi1,2012-09-19,2011-09-13
-6vi4,2020-03-18,2020-01-11
-2vir,1998-04-29,1997-12-22
-7vif,2022-09-28,2021-09-26
-1vix,2003-12-30,2003-12-01
-2vij,2008-01-29,2007-12-04
-6vi3,2020-04-15,2020-01-11
-7vi0,2022-04-27,2021-09-24
-6vii,2020-04-08,2020-01-13
-1vij,1999-01-13,1997-05-07
-3vi5,2012-04-18,2011-09-21
-2vi9,2007-12-18,2007-11-28
-1vi2,2003-12-30,2003-12-01
-7vit,2022-06-08,2021-09-27
-8vij,2024-04-03,2024-01-04
-6vif,2020-06-10,2020-01-13
-5vi4,2017-09-27,2017-04-13
-3vig,2012-07-04,2011-10-03
-7vis,2022-06-08,2021-09-27
-5vim,2017-09-06,2017-04-17
-2vi0,2009-03-10,2007-11-26
-1vit,1997-04-21,1996-01-31
-5vik,2017-06-07,2017-04-17
-2viv,2008-01-22,2007-12-05
-5vib,2018-01-31,2017-04-14
-2vio,2008-01-22,2007-12-05
-2viw,2008-01-22,2007-12-05
-3vin,2012-07-04,2011-10-03
-2vi8,2007-12-18,2007-11-28
-5vii,2017-04-26,2017-04-16
-7viz,2022-03-09,2021-09-28
-6vim,2020-08-05,2020-01-13
-3vim,2012-07-04,2011-10-03
-6viv,2021-02-10,2020-01-14
-2viz,2008-01-29,2007-12-06
-3vii,2012-07-04,2011-10-03
-7vi6,2021-12-22,2021-09-26
-5viy,2017-06-21,2017-04-17
-3vip,2012-07-04,2011-10-03
-2vis,1998-04-29,1997-12-22
-5via,2017-06-21,2017-04-14
-7viw,2022-03-09,2021-09-28
-6viu,2020-11-25,2020-01-14
-3vi7,2012-04-18,2011-09-21
-5viq,2017-06-07,2017-04-17
-2vin,2008-01-22,2007-12-05
-1viz,2003-12-30,2003-12-01
-7viq,2022-06-08,2021-09-27
-7viu,2022-06-08,2021-09-27
-3vid,2012-08-15,2011-09-29
-3vio,2012-07-04,2011-10-03
-1vif,1997-10-22,1996-10-03
-7vic,2022-03-30,2021-09-26
-5vil,2018-01-17,2017-04-17
-2via,2007-12-18,2007-11-28
-3vi4,2012-02-22,2011-09-21
-2viu,1998-04-29,1997-12-22
-3vif,2012-07-04,2011-10-03
-5vi0,2017-10-25,2017-04-13
-7vip,2022-06-08,2021-09-27
-6vi0,2021-01-13,2020-01-10
-3vil,2012-07-04,2011-10-03
-6viz,2020-05-06,2020-01-14
-5vir,2017-04-26,2017-04-17
-6vip,2020-02-12,2020-01-13
-6vik,2020-04-08,2020-01-13
-6vi9,2020-07-29,2020-01-12
-5vij,2017-04-26,2017-04-16
-6vib,2020-07-29,2020-01-12
-7vir,2022-06-08,2021-09-27
-5vi9,2018-01-31,2017-04-14
-2vif,2007-12-25,2007-11-30
-5vi8,2017-04-26,2017-04-14
-7vix,2022-03-09,2021-09-28
-5vin,2018-06-27,2017-04-17
-6vi5,2020-07-29,2020-01-12
-6vi6,2020-07-29,2020-01-12
-2vi5,2008-04-08,2007-11-27
-7viy,2022-03-09,2021-09-28
-5vif,2017-10-18,2017-04-15
-3vi3,2012-02-22,2011-09-21
-2vic,2008-02-19,2007-11-29
-8vis,2024-01-31,2024-01-05
-5vis,2017-05-03,2017-04-17
-1vid,1996-07-11,1996-01-05
-6vi7,2020-02-12,2020-01-12
-3vi2,2012-08-01,2011-09-16
-2vit,1998-04-29,1997-12-22
-7vig,2022-09-28,2021-09-26
-3vi0,2012-06-13,2011-09-13
-1vik,1998-12-09,1997-05-07
-5vio,2018-01-17,2017-04-17
-6vix,2020-05-06,2020-01-14
-5vie,2017-10-18,2017-04-15
-2vib,2007-12-18,2007-11-28
-7vi7,2021-12-22,2021-09-26
-6viw,2020-05-06,2020-01-14
-6vil,2020-09-16,2020-01-13
-5vih,2017-04-26,2017-04-16
-5vi5,2017-07-26,2017-04-14
-2vip,2008-01-22,2007-12-05
-5vi6,2017-09-06,2017-04-14
-2vie,2008-01-29,2007-11-30
-3vih,2012-07-04,2011-10-03
-3viv,2012-05-23,2011-10-12
-3vij,2012-07-04,2011-10-03
-2vii,2008-01-22,2007-12-04
-6vi8,2020-07-29,2020-01-12
-7vi8,2022-09-07,2021-09-26
-2viy,2008-01-29,2007-12-06
-7vib,2022-10-05,2021-09-26
-6vij,2020-04-08,2020-01-13
-3viu,2012-01-18,2011-10-12
-1vi6,2003-12-30,2003-12-01
-5viv,2017-06-21,2017-04-17
-7vih,2022-09-28,2021-09-26
-6via,2020-07-29,2020-01-12
-1viw,1999-07-22,1998-07-21
-1vi0,2003-12-30,2003-12-01
-2vig,2007-12-25,2007-11-30
-2ypj,2012-12-19,2012-10-30
-7ypa,2022-11-16,2022-08-03
-5ypl,2018-02-21,2017-11-02
-4yp5,2015-10-14,2015-03-12
-5yp5,2018-04-04,2017-11-01
-4yph,2015-05-27,2015-03-12
-5ypu,2018-09-26,2017-11-03
-1yp6,2005-08-30,2005-01-30
-2ypg,2012-11-07,2012-10-30
-5ype,2018-08-29,2017-11-01
-6ypf,2020-07-22,2020-04-16
-6yp9,2020-12-09,2020-04-15
-4ypd,2015-05-13,2015-03-12
-4ypa,2015-09-02,2015-03-12
-6ypq,2021-01-20,2020-04-16
-5yps,2018-11-07,2017-11-03
-3ypi,1993-04-15,1990-12-31
-5ypx,2018-03-14,2017-11-04
-7ypd,2024-02-07,2022-08-03
-7ypn,2023-05-24,2022-08-03
-6ypd,2020-06-24,2020-04-15
-5yp7,2018-08-29,2017-11-01
-5ypp,2018-09-19,2017-11-02
-1ypg,2006-01-17,2005-01-31
-7ypz,2023-08-16,2022-08-05
-6yp1,2020-09-16,2020-04-15
-7yph,2023-10-25,2022-08-03
-6yph,2020-07-15,2020-04-16
-4yp9,2016-03-23,2015-03-12
-7ypb,2022-11-16,2022-08-03
-2yp9,2012-11-07,2012-10-29
-2ypo,2013-01-09,2012-10-31
-2ype,2013-07-10,2012-10-30
-1ypk,2006-01-17,2005-01-31
-7ypy,2022-09-21,2022-08-05
-2ypp,2013-01-09,2012-10-31
-2yph,2013-07-10,2012-10-30
-7yp8,2024-02-07,2022-08-02
-2ypa,2013-07-31,2012-10-30
-5ypk,2018-02-21,2017-11-02
-4ypt,2015-08-26,2015-03-13
-2ypt,2012-12-05,2012-11-01
-5yp3,2018-02-21,2017-11-01
-6yp8,2020-09-23,2020-04-15
-1ypz,2005-04-12,2005-01-31
-1ypp,1996-12-07,1996-05-29
-2ypn,1999-02-02,1999-01-11
-7ypk,2023-10-25,2022-08-03
-4yps,2015-06-03,2015-03-13
-5ypc,2018-08-29,2017-11-01
-4yp7,2015-10-14,2015-03-12
-6ypa,2020-06-03,2020-04-15
-5ypb,2018-08-29,2017-11-01
-7ypr,2023-12-06,2022-08-04
-1yp1,2006-01-17,2005-01-28
-4yp1,2015-10-07,2015-03-12
-6ypj,2020-07-15,2020-04-16
-7ypw,2023-04-19,2022-08-04
-7yp9,2022-11-16,2022-08-03
-7ypv,2023-05-31,2022-08-04
-5ypd,2018-11-07,2017-11-01
-4yp8,2015-05-20,2015-03-12
-6ypz,2020-09-16,2020-04-16
-1ypj,2006-01-17,2005-01-31
-4ypu,2015-09-02,2015-03-13
-1yp3,2005-03-15,2005-01-29
-1ypl,2006-01-17,2005-01-31
-5ypn,2018-02-21,2017-11-02
-6ypn,2020-07-15,2020-04-16
-1yp2,2005-03-15,2005-01-29
-4ypw,2016-03-16,2015-03-13
-6ypk,2020-07-15,2020-04-16
-1ype,2006-01-17,2005-01-31
-4ypz,2016-03-16,2015-03-13
-4ypb,2015-10-21,2015-03-12
-5yph,2018-08-29,2017-11-01
-5yp6,2018-02-07,2017-11-01
-2yp6,2013-10-30,2012-10-29
-2yp0,2013-07-10,2012-10-29
-1ypn,1999-03-02,1998-06-26
-4ypm,2016-03-16,2015-03-13
-5ypi,2018-02-21,2017-11-01
-2yp2,2012-11-07,2012-10-29
-1yp4,2005-03-15,2005-01-29
-4ypg,2015-05-06,2015-03-12
-6ypg,2020-07-15,2020-04-16
-6yps,2020-12-09,2020-04-16
-5ypw,2018-09-19,2017-11-03
-4ypl,2016-03-16,2015-03-13
-5yp4,2018-02-21,2017-11-01
-5ypg,2018-08-29,2017-11-01
-6ypo,2021-03-03,2020-04-16
-6ypu,2020-09-16,2020-04-16
-5ypy,2018-09-19,2017-11-04
-5yp8,2018-08-29,2017-11-01
-7yp6,2022-11-02,2022-08-02
-2yp8,2012-11-07,2012-10-29
-5ypr,2018-03-14,2017-11-02
-6ypv,2020-09-09,2020-04-16
-6yp3,2020-09-23,2020-04-15
-4ypf,2015-08-12,2015-03-12
-2ypi,1991-01-15,1990-01-12
-4ypy,2016-03-16,2015-03-13
-4yp3,2015-05-13,2015-03-12
-4yp0,2015-08-12,2015-03-12
-4ypq,2015-12-23,2015-03-13
-5yp2,2018-02-21,2017-11-01
-7ypj,2023-10-25,2022-08-03
-4ypx,2016-03-16,2015-03-13
-2ypu,2012-11-28,2012-11-01
-2ypd,2012-12-12,2012-10-30
-6yp7,2020-11-25,2020-04-15
-7ypu,2023-05-31,2022-08-04
-7ypp,2023-07-26,2022-08-04
-6yp4,2020-11-04,2020-04-15
-2yp1,2013-10-23,2012-10-29
-6ypi,2021-04-28,2020-04-16
-6ypx,2020-04-29,2020-04-16
-6ypw,2021-04-28,2020-04-16
-5ypj,2018-11-07,2017-11-01
-1yp9,2006-01-17,2005-01-31
-4ype,2015-09-02,2015-03-12
-7yp3,2022-11-02,2022-08-02
-7yp5,2022-11-02,2022-08-02
-4yp6,2015-10-14,2015-03-12
-6ypl,2020-09-23,2020-04-16
-6ypt,2020-08-05,2020-04-16
-6ypy,2020-09-23,2020-04-16
-1ypm,2006-01-17,2005-01-31
-5ypa,2018-08-29,2017-11-01
-6ypp,2021-04-28,2020-04-16
-6yp2,2020-09-23,2020-04-15
-4yp2,2015-05-20,2015-03-12
-2yp7,2012-11-07,2012-10-29
-7ypm,2023-05-24,2022-08-03
-2ypq,2013-01-09,2012-10-31
-5ypm,2018-02-21,2017-11-02
-6ype,2020-06-03,2020-04-15
-2yp5,2012-11-07,2012-10-29
-2yp4,2012-11-07,2012-10-29
-1yp7,2005-08-30,2005-01-30
-7ypi,2023-10-25,2022-08-03
-4ypo,2016-02-17,2015-03-13
-2yp3,2012-11-07,2012-10-29
-2ypc,2013-07-10,2012-10-30
-5ypf,2018-08-29,2017-11-01
-6bja,2018-02-07,2017-11-05
-2bj4,2005-02-16,2005-01-28
-4bjx,2013-10-02,2013-04-20
-5bj4,2003-09-02,1999-01-11
-8bjf,2023-08-30,2022-11-04
-1bjr,1998-11-04,1998-06-27
-3bju,2008-02-05,2007-12-04
-4bjk,2013-09-04,2013-04-18
-4bj9,2013-12-11,2013-04-17
-6bj3,2018-07-25,2017-11-03
-8bji,2023-09-20,2022-11-04
-2bjb,2006-03-09,2005-02-01
-1bjk,1998-11-04,1998-06-25
-8bja,2023-07-12,2022-11-03
-5bjs,2017-06-14,2016-10-22
-4bju,2013-05-01,2013-04-19
-2bj9,2005-04-08,2005-01-31
-3bj7,2008-09-16,2007-12-03
-2bjj,2005-08-01,2005-02-03
-1bjp,1998-12-02,1998-06-26
-6bjb,2018-02-07,2017-11-05
-8bj0,2023-11-15,2022-11-03
-1bj9,1999-01-13,1998-07-03
-7bjh,2021-07-07,2021-01-14
-7bje,2021-07-07,2021-01-14
-1bji,1998-06-03,1997-12-03
-5bjz,2018-01-17,2017-09-12
-3bjt,2008-03-04,2007-12-04
-7bjr,2021-07-07,2021-01-14
-1bjg,1998-11-04,1998-06-25
-2bjs,2006-03-09,2005-02-07
-1bj6,1999-02-02,1998-07-03
-3bji,2008-07-15,2007-12-04
-1bj3,1999-08-16,1998-07-02
-6bjc,2017-11-22,2017-11-05
-8bjp,2023-11-15,2022-11-04
-3bjf,2008-03-04,2007-12-03
-5bjy,2017-11-08,2017-09-12
-7bjj,2021-07-07,2021-01-14
-4bj0,2014-04-23,2013-04-15
-8bj8,2023-04-26,2022-11-03
-3bj3,2008-09-02,2007-12-02
-8bjd,2023-09-06,2022-11-04
-8bjk,2023-09-06,2022-11-04
-7bjw,2021-06-09,2021-01-14
-2bj7,2005-04-08,2005-01-31
-2bjm,2005-08-18,2005-02-04
-8bj1,2023-03-22,2022-11-03
-4bjj,2013-07-31,2013-04-18
-7bjy,2021-08-25,2021-01-14
-7bjk,2021-07-07,2021-01-14
-8bj9,2023-07-12,2022-11-03
-4bjt,2013-06-19,2013-04-19
-4bjc,2013-12-11,2013-04-18
-7bj6,2021-04-07,2021-01-14
-3bjy,2008-10-28,2007-12-05
-5bjw,2017-11-08,2017-09-12
-5bj3,2003-09-02,1999-01-11
-7bjv,2021-04-07,2021-01-14
-3bjs,2007-12-18,2007-12-04
-3bjd,2007-12-11,2007-12-03
-4bjo,2014-02-12,2013-04-19
-4bjy,2013-07-24,2013-04-21
-6bjs,2018-03-28,2017-11-06
-6bjy,2018-02-28,2017-11-07
-7bjb,2021-09-15,2021-01-14
-8bjt,2023-04-26,2022-11-06
-8bjo,2023-11-15,2022-11-04
-1bju,1998-12-02,1998-06-29
-7bjl,2021-06-09,2021-01-14
-6bj7,2018-11-07,2017-11-05
-7bjc,2021-04-14,2021-01-14
-8bjl,2023-11-15,2022-11-04
-8bje,2023-09-06,2022-11-04
-3bj2,2008-09-02,2007-12-02
-2bjh,2005-09-07,2005-02-02
-6bjo,2018-01-10,2017-11-06
-4bj8,2013-11-20,2013-04-17
-7bjf,2021-06-09,2021-01-14
-6bj9,2018-02-07,2017-11-05
-4bjb,2013-12-11,2013-04-17
-4bja,2014-05-07,2013-04-17
-3bjw,2007-12-18,2007-12-04
-7bj0,2021-04-07,2021-01-13
-8bjg,2023-03-29,2022-11-04
-4bjh,2013-12-18,2013-04-18
-7bj1,2021-03-03,2021-01-13
-4bj3,2013-11-20,2013-04-16
-7bjd,2021-07-07,2021-01-14
-4bjz,2013-07-24,2013-04-21
-8bj3,2023-03-22,2022-11-03
-1bjf,1999-07-22,1998-06-25
-2bj3,2005-04-08,2005-01-28
-1bje,1998-01-28,1997-10-18
-2bj8,2005-04-08,2005-01-31
-3bj1,2008-09-02,2007-12-02
-7bj8,2021-09-15,2021-01-14
-2bjk,2006-03-09,2005-02-04
-3bj4,2008-01-15,2007-12-03
-6bj5,2018-11-07,2017-11-05
-2bjr,2005-03-16,2005-02-07
-6bjd,2018-02-07,2017-11-06
-5bju,2017-11-08,2017-09-12
-6bjp,2018-11-14,2017-11-06
-8bjj,2023-09-20,2022-11-04
-8bjc,2023-09-06,2022-11-03
-7bjo,2021-07-07,2021-01-14
-7bj3,2021-05-12,2021-01-13
-2bja,2006-03-09,2005-02-01
-6bj2,2018-07-25,2017-11-03
-5bjx,2017-11-08,2017-09-12
-1bjo,1998-11-04,1998-06-25
-6bj6,2018-11-07,2017-11-05
-3bje,2007-12-18,2007-12-03
-6bjq,2018-07-25,2017-11-06
-7bjt,2021-07-14,2021-01-14
-2bji,2005-02-11,2005-02-03
-3bjp,2008-08-12,2007-12-04
-8bjy,2023-11-22,2022-11-08
-8bjq,2023-02-08,2022-11-05
-8bj7,2023-03-22,2022-11-03
-4bjr,2013-05-01,2013-04-19
-2bju,2005-04-18,2005-02-08
-1bjq,1998-12-30,1998-06-26
-3bjm,2008-04-22,2007-12-04
-7bju,2021-04-07,2021-01-14
-8bjn,2023-03-29,2022-11-04
-8bjz,2023-09-27,2022-11-08
-8bj5,2023-09-20,2022-11-03
-5bjv,2017-11-08,2017-09-12
-7bjq,2022-07-27,2021-01-14
-7bjx,2021-07-07,2021-01-14
-3bjh,2007-12-18,2007-12-04
-6bjr,2018-06-27,2017-11-06
-1bjj,1999-07-29,1998-06-25
-3bj8,2008-09-16,2007-12-03
-2bjd,2005-11-23,2005-02-02
-7bj9,2021-08-25,2021-01-14
-8bjx,2023-11-22,2022-11-08
-7bj4,2021-04-14,2021-01-14
-7bjm,2021-07-07,2021-01-14
-8bjh,2023-09-20,2022-11-04
-2bj1,2005-04-08,2005-01-27
-3bjc,2008-04-29,2007-12-03
-8bju,2023-05-31,2022-11-06
-1bjv,1998-12-02,1998-06-29
-1bj4,1999-08-16,1998-07-02
-2bjf,2005-03-03,2005-02-02
-8bj4,2023-03-22,2022-11-03
-8bj2,2023-03-22,2022-11-03
-6bj8,2018-07-25,2017-11-05
-7bjz,2021-06-16,2021-01-14
-6zvu,2021-08-04,2020-07-27
-4zvp,2016-04-20,2015-05-18
-1zv2,2005-06-21,2005-06-01
-1zvi,2005-08-02,2005-06-02
-5zvh,2018-12-12,2018-05-10
-1zvf,2006-06-02,2005-06-02
-4zvb,2015-11-11,2015-05-18
-4zvy,2015-08-26,2015-05-18
-6zv9,2020-11-25,2020-07-24
-5zvq,2019-05-22,2018-05-12
-2zva,2008-11-11,2008-11-04
-1zvs,2006-06-13,2005-06-02
-4zvn,2016-03-30,2015-05-18
-1zvx,2006-05-16,2005-06-03
-7zva,2022-08-10,2022-05-14
-7zvy,2022-08-24,2022-05-17
-6zv7,2020-08-26,2020-07-24
-3zvs,2012-08-08,2011-07-27
-4zv7,2016-01-13,2015-05-18
-6zvy,2021-08-04,2020-07-27
-7zvx,2022-09-14,2022-05-17
-7zvp,2022-07-20,2022-05-16
-4zv2,2016-02-03,2015-05-18
-6zvh,2020-08-19,2020-07-24
-1zvw,2006-01-17,2005-06-02
-4zvi,2015-07-15,2015-05-18
-5zve,2018-12-12,2018-05-10
-6zvw,2021-08-04,2020-07-27
-3zvw,2012-02-29,2011-07-28
-6zvj,2020-10-07,2020-07-24
-6zvg,2021-07-14,2020-07-24
-3zvy,2011-12-07,2011-07-28
-3zvg,2012-08-08,2011-07-24
-7zvr,2022-10-26,2022-05-17
-7zv4,2023-03-22,2022-05-13
-5zva,2018-11-21,2018-05-09
-3zvv,2011-09-28,2011-07-27
-3zvh,2012-05-02,2011-07-25
-6zv5,2021-08-04,2020-07-24
-1zv9,2006-06-13,2005-06-01
-7zvd,2023-08-23,2022-05-15
-1zvd,2005-08-09,2005-06-01
-6zvl,2020-11-11,2020-07-24
-1zv8,2006-05-16,2005-06-01
-6zv6,2021-05-12,2020-07-24
-1zvr,2006-01-31,2005-06-02
-3zv9,2012-08-08,2011-07-24
-5zv7,2018-10-03,2018-05-09
-3zvi,2012-05-02,2011-07-25
-7zvc,2022-08-10,2022-05-14
-7zv2,2022-10-19,2022-05-13
-3zvd,2012-08-08,2011-07-24
-7zvn,2022-09-14,2022-05-16
-5zvw,2018-09-05,2018-05-13
-6zvx,2021-08-04,2020-07-27
-4zvf,2015-11-11,2015-05-18
-2zvp,2008-12-30,2008-11-14
-3zvl,2011-11-16,2011-07-25
-3zvb,2012-08-08,2011-07-24
-2zvl,2009-02-10,2008-11-11
-6zvp,2021-11-17,2020-07-27
-2zv2,2009-11-03,2008-10-31
-2zvd,2009-11-10,2008-11-05
-1zvj,2006-05-23,2005-06-02
-6zvk,2020-12-23,2020-07-24
-7zvz,2023-05-24,2022-05-17
-6zvm,2020-10-14,2020-07-25
-2zvt,2009-10-06,2008-11-19
-7zv5,2022-11-30,2022-05-13
-4zv1,2016-02-03,2015-05-18
-5zvb,2018-11-21,2018-05-09
-2zvc,2009-05-05,2008-11-04
-5zvu,2019-05-01,2018-05-13
-2zvq,2008-12-30,2008-11-14
-6zvb,2021-08-04,2020-07-24
-3zvz,2011-11-30,2011-07-28
-3zvn,2011-11-16,2011-07-25
-3zve,2012-08-08,2011-07-24
-2zvk,2009-02-10,2008-11-11
-6zvv,2021-08-04,2020-07-27
-1zvc,2005-06-14,2005-06-01
-3zv7,2012-05-23,2011-07-24
-5zvc,2018-10-03,2018-05-10
-6zvd,2021-08-04,2020-07-24
-4zvz,2016-04-27,2015-05-18
-4zvv,2016-05-18,2015-05-18
-3zvf,2012-08-08,2011-07-24
-3zv6,2011-08-31,2011-07-23
-4zva,2015-11-11,2015-05-18
-4zv3,2015-06-03,2015-05-18
-1zvl,2005-08-02,2005-06-02
-3zvm,2011-11-16,2011-07-25
-2zvb,2009-05-05,2008-11-04
-4zvo,2016-04-20,2015-05-18
-3zvx,2012-01-11,2011-07-28
-5zv2,2018-07-11,2018-05-09
-4zv4,2015-11-11,2015-05-18
-5zvn,2019-06-19,2018-05-11
-3zva,2012-08-08,2011-07-24
-1zvq,2006-03-14,2005-06-02
-7zvu,2022-10-19,2022-05-17
-7zvv,2023-05-24,2022-05-17
-7zvo,2023-02-08,2022-05-16
-7zvl,2022-10-19,2022-05-16
-7zv8,2022-12-07,2022-05-13
-2zv9,2008-11-11,2008-11-04
-7zvm,2022-08-24,2022-05-16
-6zve,2021-08-04,2020-07-24
-6zvc,2021-08-04,2020-07-24
-1zvk,2006-05-23,2005-06-02
-4zvt,2016-04-20,2015-05-18
-3zvc,2012-08-08,2011-07-24
-7zvw,2023-05-31,2022-05-17
-2zv8,2008-11-11,2008-11-04
-2zvj,2009-01-06,2008-11-07
-7zvs,2022-10-12,2022-05-17
-7zv9,2023-05-31,2022-05-14
-4zvu,2016-04-20,2015-05-18
-6zvi,2020-09-09,2020-07-24
-7zv3,2022-07-06,2022-05-13
-3zvt,2012-02-29,2011-07-27
-4zvr,2016-04-20,2015-05-18
-4zvq,2016-04-20,2015-05-18
-4zvl,2016-04-06,2015-05-18
-4zv8,2016-03-30,2015-05-18
-7zv7,2022-12-07,2022-05-13
-7zv0,2023-11-22,2022-05-13
-7zvj,2022-11-30,2022-05-16
-5zvr,2019-05-01,2018-05-12
-4zvj,2016-03-09,2015-05-18
-7zvf,2023-11-29,2022-05-15
-3zv5,2011-08-31,2011-07-23
-7zvb,2022-08-10,2022-05-14
-4zvk,2016-03-30,2015-05-18
-6zv8,2020-08-26,2020-07-24
-7zvk,2023-11-29,2022-05-16
-5zvx,2019-05-01,2018-05-13
-5zvp,2019-05-15,2018-05-12
-5zvg,2018-12-12,2018-05-10
-2zvm,2009-02-10,2008-11-11
-3zvu,2012-06-13,2011-07-27
-4zvm,2016-03-30,2015-05-18
-5zv5,2018-10-03,2018-05-09
-4zvs,2016-04-20,2015-05-18
-3x16,2014-12-24,2014-10-30
-2x14,2010-12-29,2009-12-21
-1x1d,2006-07-18,2005-04-04
-7x12,2022-07-20,2022-02-22
-3x1e,2015-11-18,2014-11-16
-5x1t,2018-01-31,2017-01-26
-5x16,2018-07-04,2017-01-24
-3x13,2014-12-24,2014-10-24
-8x1n,2024-05-15,2023-11-08
-5x1h,2017-06-14,2017-01-26
-4x1t,2016-02-10,2014-11-25
-3x1z,2015-06-03,2014-12-02
-2x1w,2010-03-09,2010-01-08
-7x1l,2022-10-19,2022-02-24
-3x1s,2015-09-23,2014-11-27
-1x1z,2005-12-06,2005-04-15
-3x1m,2015-11-25,2014-11-24
-6x1m,2021-04-14,2020-05-19
-1x1s,2005-07-26,2005-04-13
-3x1g,2015-11-18,2014-11-16
-3x1v,2015-09-23,2014-11-28
-7x1m,2022-07-06,2022-02-24
-1x1j,2005-07-19,2005-04-04
-5x1w,2017-05-31,2017-01-27
-2x1v,2010-01-12,2010-01-04
-6x19,2020-09-09,2020-05-18
-3x14,2014-12-24,2014-10-25
-3x1k,2015-11-25,2014-11-20
-6x1w,2021-02-03,2020-05-19
-2x1n,2010-02-16,2009-12-31
-5x1q,2018-01-31,2017-01-26
-6x1h,2020-11-25,2020-05-18
-4x1n,2015-03-25,2014-11-25
-1x1v,2005-11-08,2005-04-14
-4x1y,2015-03-25,2014-11-25
-3x1j,2015-11-25,2014-11-19
-6x1o,2021-11-24,2020-05-19
-4x17,2015-04-22,2014-11-24
-1x1n,2006-04-18,2005-04-08
-2x1a,2010-02-02,2010-01-06
-5x1v,2017-05-31,2017-01-27
-4x14,2015-04-22,2014-11-24
-7x1y,2023-04-26,2022-02-25
-5x17,2017-10-04,2017-01-25
-8x15,2024-03-06,2023-11-06
-4x15,2015-04-22,2014-11-24
-4x1f,2015-09-09,2014-11-24
-2x1m,2010-07-28,2009-12-31
-4x13,2015-04-22,2014-11-24
-6x16,2020-11-18,2020-05-18
-6x1u,2021-02-03,2020-05-19
-1x1r,2005-07-26,2005-04-12
-4x1p,2015-10-21,2014-11-25
-7x11,2022-07-20,2022-02-22
-6x1y,2020-06-10,2020-05-19
-3x1u,2015-09-23,2014-11-28
-7x1r,2022-12-14,2022-02-24
-1x15,2005-09-13,2005-03-31
-7x1o,2023-08-30,2022-02-24
-1x1t,2006-01-10,2005-04-13
-5x1m,2017-05-17,2017-01-26
-3x1w,2015-06-03,2014-12-02
-7x1c,2023-05-03,2022-02-23
-8x19,2024-03-06,2023-11-06
-2x13,2010-12-29,2009-12-21
-4x12,2015-04-22,2014-11-24
-3x1y,2015-06-03,2014-12-02
-3x1d,2015-10-28,2014-11-14
-4x10,2015-04-22,2014-11-24
-2x1t,2010-01-26,2010-01-04
-6x1a,2020-09-09,2020-05-18
-6x1b,2020-05-27,2020-05-18
-3x1x,2015-06-03,2014-12-02
-8x16,2024-04-24,2023-11-06
-7x14,2022-09-14,2022-02-23
-4x1s,2015-10-28,2014-11-25
-8x17,2024-04-24,2023-11-06
-5x1b,2017-08-09,2017-01-25
-3x1b,2014-12-10,2014-10-31
-2x1z,2010-02-09,2010-01-09
-2x1e,2010-03-09,2009-12-23
-6x1c,2021-09-22,2020-05-18
-2x1i,2010-10-27,2009-12-28
-4x1q,2015-03-25,2014-11-25
-5x13,2017-11-22,2017-01-24
-8x1f,2023-12-13,2023-11-07
-8x1c,2024-03-06,2023-11-06
-7x1t,2022-08-31,2022-02-24
-4x1x,2015-01-14,2014-11-25
-4x1j,2015-01-14,2014-11-24
-2x17,2010-04-21,2009-12-22
-1x1a,2006-07-18,2005-04-03
-3x1t,2015-09-23,2014-11-27
-5x1k,2017-05-17,2017-01-26
-3x1f,2015-11-18,2014-11-16
-5x1n,2017-05-17,2017-01-26
-1x14,2005-09-13,2005-03-31
-5x1s,2018-01-31,2017-01-26
-2x1f,2010-02-02,2010-01-06
-4x1i,2015-03-25,2014-11-24
-6x1v,2021-02-03,2020-05-19
-3x11,2014-12-24,2014-10-24
-4x1z,2015-01-14,2014-11-25
-4x16,2015-04-22,2014-11-24
-3x12,2014-12-24,2014-10-24
-3x1l,2015-05-13,2014-11-20
-7x1x,2022-09-14,2022-02-24
-3x1n,2015-01-21,2014-11-25
-4x11,2015-05-06,2014-11-24
-5x1o,2018-03-07,2017-01-26
-4x1g,2015-09-09,2014-11-24
-2x10,2010-03-16,2009-12-21
-7x1z,2023-04-19,2022-02-25
-5x14,2017-11-22,2017-01-24
-4x1k,2015-03-25,2014-11-24
-6x11,2020-07-29,2020-05-17
-7x1u,2022-08-31,2022-02-24
-7x1b,2023-05-03,2022-02-23
-2x1l,2010-07-28,2009-12-31
-6x1q,2020-07-01,2020-05-19
-2x1h,2010-11-10,2009-12-24
-5x1l,2017-05-17,2017-01-26
-2x1x,2010-02-09,2010-01-08
-5x1y,2017-10-04,2017-01-28
-4x1b,2015-04-08,2014-11-24
-6x1s,2021-02-03,2020-05-19
-1x1c,2006-07-18,2005-04-03
-6x10,2021-06-02,2020-05-17
-2x1r,2010-01-26,2010-01-04
-7x1w,2023-03-22,2022-02-24
-2x1s,2010-01-26,2010-01-04
-4x1r,2015-03-25,2014-11-25
-3x17,2015-01-21,2014-10-30
-6x1z,2020-06-10,2020-05-19
-6x14,2020-11-18,2020-05-18
-6x1t,2021-02-03,2020-05-19
-6x1e,2021-09-22,2020-05-18
-3x15,2015-01-28,2014-10-29
-6x1j,2021-05-26,2020-05-19
-5x1f,2017-08-09,2017-01-25
-8x1a,2024-04-17,2023-11-06
-4x1h,2015-11-04,2014-11-24
-5x1j,2017-05-17,2017-01-26
-4x1d,2015-04-08,2014-11-24
-2x19,2010-02-16,2009-12-23
-6x15,2020-11-18,2020-05-18
-6x1f,2021-09-22,2020-05-18
-7x17,2022-07-13,2022-02-23
-6x1g,2020-11-25,2020-05-18
-1x1b,2006-07-18,2005-04-03
-5x19,2017-08-09,2017-01-25
-1x1i,2005-07-19,2005-04-04
-2x15,2011-02-09,2009-12-21
-2y4m,2011-02-02,2011-01-07
-1y45,2004-12-07,2004-11-30
-7y4o,2022-10-19,2022-06-15
-6y4o,2020-04-29,2020-02-21
-6y41,2020-03-04,2020-02-19
-7y4q,2022-10-19,2022-06-16
-6y4q,2020-05-20,2020-02-22
-4y4z,2016-03-02,2015-02-11
-4y4p,2015-03-18,2015-02-10
-6y4w,2020-03-04,2020-02-23
-4y4j,2016-02-17,2015-02-10
-4y4s,2015-08-12,2015-02-11
-2y4f,2011-01-26,2011-01-05
-5y48,2017-09-20,2017-08-01
-7y4g,2023-06-14,2022-06-14
-2y41,2011-01-19,2011-01-04
-1y4c,2005-02-15,2004-11-30
-6y44,2020-10-14,2020-02-19
-7y46,2022-07-13,2022-06-14
-4y43,2016-02-17,2015-02-10
-1y4p,2004-12-07,2004-12-01
-1y4t,2005-01-11,2004-12-01
-5y4p,2018-08-08,2017-08-04
-4y49,2016-07-13,2015-02-10
-4y45,2016-02-17,2015-02-10
-7y4k,2022-11-16,2022-06-15
-2y48,2011-02-16,2011-01-05
-2y4y,2012-01-18,2011-01-11
-5y4r,2017-11-29,2017-08-04
-1y46,2004-12-07,2004-11-30
-4y4u,2016-03-02,2015-02-11
-1y4r,2004-12-07,2004-12-01
-5y4c,2017-10-04,2017-08-03
-4y4f,2015-05-27,2015-02-10
-4y4d,2016-02-17,2015-02-10
-5y4k,2017-11-01,2017-08-03
-6y4d,2020-04-29,2020-02-20
-6y4n,2021-03-31,2020-02-21
-6y48,2020-04-08,2020-02-19
-1y42,2005-02-15,2004-11-29
-6y4e,2020-08-19,2020-02-20
-7y4i,2022-12-07,2022-06-14
-4y4v,2015-09-02,2015-02-11
-4y48,2016-02-17,2015-02-10
-5y49,2019-02-20,2017-08-02
-6y4f,2020-08-19,2020-02-20
-4y4g,2016-02-17,2015-02-10
-2y4j,2011-02-02,2011-01-07
-6y4k,2021-01-27,2020-02-21
-2y40,2011-01-19,2011-01-04
-4y4k,2015-05-27,2015-02-10
-1y4b,2004-12-07,2004-11-30
-2y43,2011-05-11,2011-01-04
-2y4v,2011-12-28,2011-01-11
-2y4s,2011-01-19,2011-01-10
-1y4w,2004-12-14,2004-12-01
-2y46,2012-01-25,2011-01-05
-4y4a,2016-03-02,2015-02-10
-2y4q,2011-12-21,2011-01-07
-7y4u,2022-11-23,2022-06-16
-2y4n,2011-03-01,2011-01-07
-1y4k,2005-12-13,2004-12-01
-5y4h,2018-05-16,2017-08-03
-6y47,2021-01-20,2020-02-19
-7y4t,2022-11-23,2022-06-16
-1y4q,2004-12-07,2004-12-01
-2y4i,2011-01-19,2011-01-06
-4y41,2016-02-17,2015-02-10
-6y4a,2021-09-01,2020-02-20
-6y4b,2020-12-30,2020-02-20
-2y4r,2011-01-19,2011-01-10
-5y42,2018-08-08,2017-07-31
-5y4f,2017-09-13,2017-08-03
-5y4n,2018-08-08,2017-08-04
-1y48,2005-05-17,2004-11-30
-1y44,2005-01-25,2004-11-30
-1y4s,2005-04-19,2004-12-01
-7y42,2022-07-06,2022-06-13
-4y4l,2016-03-09,2015-02-10
-7y45,2022-07-13,2022-06-14
-4y44,2016-02-17,2015-02-10
-1y4a,2005-05-17,2004-11-30
-1y4v,2004-12-07,2004-12-01
-4y4w,2016-03-02,2015-02-11
-5y4q,2018-08-08,2017-08-04
-7y44,2022-07-20,2022-06-14
-2y4g,2011-06-29,2011-01-05
-6y45,2020-03-04,2020-02-19
-5y46,2018-05-30,2017-08-01
-7y43,2023-01-18,2022-06-13
-6y4u,2020-03-04,2020-02-23
-2y4e,2011-01-26,2011-01-05
-4y4b,2016-02-17,2015-02-10
-6y4c,2020-06-17,2020-02-20
-4y4n,2016-03-09,2015-02-10
-6y4v,2020-03-04,2020-02-23
-1y4l,2005-06-28,2004-12-01
-6y4j,2021-01-13,2020-02-21
-5y41,2018-12-26,2017-07-31
-7y4x,2023-05-24,2022-06-16
-7y4r,2023-07-05,2022-06-16
-5y44,2019-02-20,2017-08-01
-2y4k,2011-02-02,2011-01-07
-6y4p,2020-04-29,2020-02-21
-7y48,2023-05-24,2022-06-14
-1y47,2005-03-22,2004-11-30
-4y4o,2015-03-18,2015-02-10
-7y47,2022-10-26,2022-06-14
-1y4g,2004-12-07,2004-11-30
-7y4a,2023-03-15,2022-06-14
-6y4x,2020-03-04,2020-02-23
-4y47,2016-02-17,2015-02-10
-4y4x,2016-03-02,2015-02-11
-1y4j,2005-02-08,2004-12-01
-6y4t,2020-03-04,2020-02-23
-4y46,2015-05-06,2015-02-10
-2y4a,2011-07-27,2011-01-05
-4y4h,2015-05-27,2015-02-10
-1y4d,2005-05-17,2004-11-30
-2y4l,2011-02-02,2011-01-07
-1y4z,2005-03-08,2004-12-01
-4y4m,2016-03-09,2015-02-10
-6y43,2020-03-04,2020-02-19
-4y4r,2015-10-07,2015-02-11
-7y4m,2022-11-16,2022-06-15
-2y4o,2011-03-09,2011-01-07
-5y4z,2017-08-30,2017-08-06
-7y4p,2022-10-19,2022-06-15
-2y42,2011-01-19,2011-01-04
-5y4a,2018-08-08,2017-08-02
-6y40,2020-10-14,2020-02-19
-4y4e,2016-02-17,2015-02-10
-5y4i,2017-09-20,2017-08-03
-7y41,2023-05-03,2022-06-13
-5y4j,2017-09-20,2017-08-03
-6y4m,2021-03-31,2020-02-21
-6y4g,2020-03-04,2020-02-20
-1y4f,2004-12-07,2004-11-30
-4y4t,2016-03-02,2015-02-11
-8y4u,2024-02-28,2024-01-30
-7y4w,2023-10-18,2022-06-16
-3i34,2010-06-30,2009-06-30
-4i3w,2013-11-27,2012-11-26
-5i3o,2016-03-09,2016-02-10
-4i32,2013-01-02,2012-11-23
-6i3v,2019-03-20,2018-11-07
-2i3v,2006-10-17,2006-08-21
-1i3o,2001-03-21,2001-02-15
-4i3l,2013-05-22,2012-11-26
-1i3d,2001-09-12,2001-02-15
-8i34,2023-08-16,2023-01-16
-2i33,2007-07-31,2006-08-17
-8i36,2023-12-20,2023-01-16
-2i36,2006-10-17,2006-08-17
-2i3p,2006-09-05,2006-08-20
-6i3c,2019-09-18,2018-11-05
-6i35,2019-11-20,2018-11-05
-3i37,2010-06-09,2009-06-30
-4i35,2013-11-27,2012-11-24
-8i39,2023-09-13,2023-01-16
-4i31,2013-01-02,2012-11-23
-5i3h,2016-05-18,2016-02-10
-8i3b,2023-09-13,2023-01-16
-8i3f,2023-05-31,2023-01-17
-3i3q,2009-08-25,2009-06-30
-6i3q,2018-11-28,2018-11-07
-8i3s,2023-10-04,2023-01-17
-4i3g,2013-02-20,2012-11-26
-4i3x,2013-11-27,2012-11-26
-4i3s,2013-01-09,2012-11-26
-4i3u,2013-11-27,2012-11-26
-6i30,2019-02-20,2018-11-02
-3i31,2009-09-22,2009-06-30
-5i3v,2016-03-30,2016-02-11
-6i3l,2019-10-02,2018-11-06
-6i3s,2018-12-19,2018-11-07
-4i3e,2013-12-18,2012-11-26
-2i3q,2006-09-05,2006-08-20
-2i3z,2006-12-12,2006-08-21
-3i3x,2009-09-01,2009-07-01
-3i3l,2010-03-09,2009-06-30
-5i34,2016-08-24,2016-02-09
-1i36,2002-05-15,2001-02-13
-2i3i,2006-09-19,2006-08-18
-8i3n,2024-01-24,2023-01-17
-3i3w,2010-01-19,2009-07-01
-5i35,2016-08-17,2016-02-09
-3i3e,2010-05-12,2009-06-30
-4i3p,2013-12-11,2012-11-26
-6i3d,2019-09-18,2018-11-05
-6i3z,2019-11-20,2018-11-08
-5i3b,2016-10-12,2016-02-10
-5i3u,2016-06-01,2016-02-11
-5i3m,2016-07-06,2016-02-10
-6i34,2019-11-20,2018-11-05
-4i3j,2013-03-20,2012-11-26
-6i3j,2019-10-02,2018-11-06
-1i3w,2001-05-21,2001-02-17
-6i3i,2018-12-26,2018-11-06
-5i30,2016-04-13,2016-02-09
-2i3d,2006-09-19,2006-08-17
-5i3i,2016-05-18,2016-02-10
-3i30,2010-06-09,2009-06-30
-4i3f,2013-06-26,2012-11-26
-4i3y,2013-11-27,2012-11-26
-1i32,2001-10-03,2001-02-12
-8i3y,2024-01-31,2023-01-18
-3i3b,2010-05-12,2009-06-30
-4i3a,2013-03-20,2012-11-26
-4i3d,2013-06-19,2012-11-26
-2i3g,2006-09-05,2006-08-18
-5i3l,2016-02-24,2016-02-10
-3i3a,2009-09-01,2009-06-30
-8i3w,2024-01-24,2023-01-18
-4i3c,2013-06-19,2012-11-26
-4i33,2013-01-02,2012-11-23
-4i3i,2013-03-20,2012-11-26
-6i3k,2019-10-02,2018-11-06
-6i36,2018-12-12,2018-11-05
-5i3r,2016-03-09,2016-02-10
-1i3j,2001-07-13,2001-02-15
-1i3r,2001-06-20,2001-02-15
-5i3a,2016-10-12,2016-02-10
-6i3t,2019-09-11,2018-11-07
-1i38,2001-03-21,2001-02-13
-3i39,2009-08-11,2009-06-30
-5i3c,2017-02-22,2016-02-10
-1i3e,2001-09-12,2001-02-15
-5i3t,2016-06-01,2016-02-11
-8i3o,2024-01-24,2023-01-17
-3i33,2009-07-21,2009-06-30
-1i3h,2001-07-25,2001-02-15
-4i3z,2012-12-26,2012-11-27
-1i37,2001-03-21,2001-02-13
-5i3q,2016-07-06,2016-02-10
-4i3b,2013-06-19,2012-11-26
-5i39,2016-08-03,2016-02-10
-3i3f,2009-09-01,2009-06-30
-8i3c,2023-09-13,2023-01-16
-5i3j,2016-05-18,2016-02-10
-4i38,2013-03-20,2012-11-26
-4i3h,2013-08-28,2012-11-26
-4i3q,2013-04-24,2012-11-26
-8i3x,2023-11-29,2023-01-18
-5i3x,2016-03-30,2016-02-11
-6i39,2019-11-20,2018-11-05
-4i3m,2013-02-27,2012-11-26
-4i30,2012-12-12,2012-11-23
-3i3c,2009-08-18,2009-06-30
-1i3f,2001-03-07,2001-02-15
-5i3z,2016-07-06,2016-02-11
-5i3y,2016-03-30,2016-02-11
-1i3u,2001-08-08,2001-02-16
-1i3i,2001-03-07,2001-02-15
-1i3n,2001-06-20,2001-02-15
-1i31,2001-02-21,2001-02-12
-2i3w,2006-10-17,2006-08-21
-1i3q,2001-04-25,2001-02-15
-5i38,2016-10-12,2016-02-10
-6i3e,2019-11-20,2018-11-05
-6i3f,2018-12-26,2018-11-06
-6i31,2019-06-19,2018-11-02
-1i30,2002-02-12,2001-02-12
-4i3k,2013-05-22,2012-11-26
-2i34,2007-07-31,2006-08-17
-8i3i,2024-01-24,2023-01-17
-5i3w,2016-03-30,2016-02-11
-6i33,2019-11-20,2018-11-05
-2i3c,2006-08-29,2006-08-17
-3i3m,2009-08-25,2009-06-30
-8i3q,2023-09-06,2023-01-17
-2i3h,2006-09-19,2006-08-18
-2i37,2006-10-17,2006-08-17
-1i3l,2001-06-20,2001-02-15
-8i3u,2023-10-04,2023-01-18
-4i3v,2013-11-27,2012-11-26
-5i3k,2016-05-18,2016-02-10
-1i33,2001-10-03,2001-02-12
-2i30,2006-12-12,2006-08-17
-3i3s,2009-12-22,2009-06-30
-8i30,2023-08-16,2023-01-16
-3i3t,2009-07-21,2009-06-30
-4i3r,2013-01-09,2012-11-26
-8i3p,2024-01-24,2023-01-17
-3i3y,2009-07-21,2009-07-01
-1i3m,2001-06-20,2001-02-15
-4i39,2013-03-20,2012-11-26
-8i3a,2023-09-13,2023-01-16
-3i3d,2010-05-12,2009-06-30
-3i3o,2009-08-04,2009-06-30
-6i3u,2019-03-20,2018-11-07
-2i35,2006-10-17,2006-08-17
-1i3k,2001-06-20,2001-02-15
-5i3p,2016-07-06,2016-02-10
-8j9q,2023-12-06,2023-05-04
-2j9p,2007-07-03,2006-11-15
-5j9z,2016-08-17,2016-04-11
-4j9g,2014-01-29,2013-02-16
-2j9b,2007-12-04,2006-11-06
-6j9k,2019-03-06,2019-01-23
-6j98,2020-03-04,2019-01-22
-4j9t,2013-03-27,2013-02-17
-6j9y,2019-10-30,2019-01-24
-6j9v,2020-01-29,2019-01-24
-5j9s,2017-03-08,2016-04-11
-2j96,2007-01-23,2006-11-02
-3j9c,2015-03-11,2014-12-25
-1j99,2002-05-24,2001-05-24
-1j97,2001-07-25,2001-05-24
-8j9w,2024-02-07,2023-05-05
-2j9g,2008-09-09,2008-03-21
-4j96,2013-08-07,2013-02-15
-2j9n,2007-04-03,2006-11-14
-5j92,2016-05-11,2016-04-08
-4j9e,2014-01-29,2013-02-16
-3j9s,2015-03-11,2015-02-19
-3j9k,2015-02-25,2015-02-04
-1j9l,2001-09-12,2001-05-28
-8j9d,2024-05-01,2023-05-03
-2j9d,2007-01-16,2006-11-07
-1j9r,2001-06-06,2001-05-28
-5j99,2016-08-17,2016-04-08
-4j95,2013-08-07,2013-02-15
-4j98,2013-08-07,2013-02-15
-4j9q,2013-05-01,2013-02-16
-8j9p,2024-03-06,2023-05-04
-4j90,2013-04-17,2013-02-15
-5j9k,2017-07-05,2016-04-10
-4j99,2013-08-07,2013-02-15
-4j9k,2013-05-01,2013-02-16
-1j9q,2001-06-06,2001-05-28
-6j9e,2019-07-17,2019-01-22
-2j95,2007-03-20,2006-11-02
-8j99,2024-05-08,2023-05-02
-3j9b,2015-02-18,2014-12-16
-2j9h,2006-11-14,2006-11-08
-1j9z,2001-08-22,2001-05-29
-4j9c,2014-01-29,2013-02-16
-4j9l,2013-05-01,2013-02-16
-5j9x,2017-12-06,2016-04-11
-8j9i,2024-02-28,2023-05-03
-1j95,2001-06-13,2001-05-23
-8j9r,2023-12-06,2023-05-04
-2j9m,2007-11-06,2006-11-13
-5j9v,2016-10-05,2016-04-11
-5j91,2016-07-06,2016-04-08
-1j9w,2001-06-13,2001-05-29
-5j9f,2016-08-10,2016-04-09
-4j9a,2013-06-26,2013-02-15
-4j9w,2013-03-13,2013-02-17
-4j9r,2013-05-01,2013-02-16
-2j9c,2007-01-16,2006-11-07
-1j9b,2001-12-05,2001-05-24
-4j9p,2013-05-01,2013-02-16
-8j9g,2024-03-06,2023-05-03
-1j9g,2001-09-05,2001-05-25
-2j91,2006-11-07,2006-11-01
-4j9s,2013-05-01,2013-02-16
-3j9d,2015-12-09,2015-01-09
-1j9j,2001-09-12,2001-05-27
-3j9l,2015-02-25,2015-02-04
-2j9q,2007-04-17,2006-11-15
-8j98,2023-10-04,2023-05-02
-5j9n,2017-05-24,2016-04-10
-1j9c,2004-07-27,2001-05-24
-1j9t,2001-06-06,2001-05-28
-3j94,2015-01-28,2014-12-05
-2j9z,2007-12-04,2006-11-16
-6j95,2020-01-22,2019-01-22
-2j90,2006-11-07,2006-10-31
-1j9e,2001-09-05,2001-05-25
-5j9a,2016-08-17,2016-04-08
-4j9h,2014-01-29,2013-02-16
-2j9u,2007-01-23,2006-11-16
-6j9u,2019-02-06,2019-01-24
-6j90,2020-01-22,2019-01-21
-1j9y,2001-06-20,2001-05-29
-6j99,2019-02-27,2019-01-22
-3j92,2015-01-21,2014-12-02
-5j9q,2016-10-26,2016-04-11
-1j96,2002-05-23,2001-05-23
-1j9m,2001-06-13,2001-05-28
-1j9n,2003-01-21,2001-05-28
-4j93,2013-07-10,2013-02-15
-5j9h,2016-10-05,2016-04-10
-8j9c,2024-05-01,2023-05-03
-8j9h,2024-02-28,2023-05-03
-2j9r,2007-01-23,2006-11-15
-2j9e,2007-01-16,2006-11-07
-8j9j,2024-02-28,2023-05-03
-3j9y,2015-04-15,2015-03-23
-5j9o,2017-05-24,2016-04-10
-4j97,2013-08-07,2013-02-15
-6j9w,2019-10-30,2019-01-24
-5j9l,2017-02-15,2016-04-10
-4j9o,2013-05-01,2013-02-16
-2j9x,2007-06-26,2006-11-16
-1j98,2001-06-06,2001-05-24
-5j9p,2016-07-20,2016-04-10
-4j91,2013-04-17,2013-02-15
-3j95,2015-01-28,2014-12-05
-8j9x,2024-02-07,2023-05-05
-8j9v,2024-02-07,2023-05-05
-6j9f,2019-07-17,2019-01-22
-4j9y,2013-03-27,2013-02-17
-5j95,2017-04-19,2016-04-08
-6j9q,2020-01-29,2019-01-24
-6j9j,2020-02-26,2019-01-23
-3j9z,2015-07-01,2015-03-27
-3j9f,2015-02-11,2015-01-15
-1j91,2002-05-29,2001-05-23
-5j93,2016-10-05,2016-04-08
-2j94,2007-03-20,2006-11-02
-2j9f,2007-02-27,2006-11-07
-8j97,2023-12-27,2023-05-02
-2j9y,2007-12-04,2006-11-16
-5j9c,2016-09-21,2016-04-08
-8j9m,2024-01-31,2023-05-04
-4j9x,2013-03-13,2013-02-17
-2j9a,2006-12-06,2006-11-06
-5j94,2016-04-20,2016-04-08
-3j9m,2015-04-15,2015-02-08
-4j9i,2014-01-29,2013-02-16
-6j94,2020-01-22,2019-01-22
-1j9s,2001-06-06,2001-05-28
-4j9m,2013-05-01,2013-02-16
-4j9v,2013-04-10,2013-02-17
-1j9k,2001-09-12,2001-05-27
-4j9n,2013-05-01,2013-02-16
-6j9t,2019-02-06,2019-01-24
-5j9y,2016-08-17,2016-04-11
-4j9z,2013-03-27,2013-02-17
-6j92,2020-01-22,2019-01-21
-1j90,2001-11-28,2001-05-23
-2j9k,2007-08-28,2006-11-11
-8j9l,2024-01-31,2023-05-04
-2j9j,2007-08-28,2006-11-11
-4j9u,2013-04-03,2013-02-17
-2j9l,2007-01-04,2006-11-13
-5j9m,2017-05-24,2016-04-10
-5j9w,2016-10-26,2016-04-11
-5o4j,2017-07-19,2017-05-29
-1o4j,2004-02-17,2003-06-15
-5o4t,2018-06-13,2017-05-30
-7o4e,2021-06-30,2021-04-06
-6o4b,2019-07-24,2019-02-28
-2o4c,2007-02-20,2006-12-04
-4o4y,2014-03-26,2013-12-19
-7o4d,2022-08-17,2021-04-06
-1o4b,2004-02-17,2003-06-15
-2o4n,2006-12-12,2006-12-04
-6o4a,2020-02-12,2019-02-28
-1o4o,2004-02-17,2003-06-15
-1o4k,2004-02-17,2003-06-15
-2o4v,2006-12-26,2006-12-05
-7o4z,2021-11-10,2021-04-07
-4o4e,2014-06-18,2013-12-18
-1o4i,2004-02-17,2003-06-15
-5o45,2017-09-20,2017-05-26
-3o4r,2010-08-04,2010-07-27
-7o4v,2021-08-25,2021-04-07
-2o4q,2007-12-18,2006-12-04
-7o4j,2021-06-16,2021-04-06
-7o40,2021-06-30,2021-04-03
-4o4s,2014-08-13,2013-12-19
-5o4l,2018-03-28,2017-05-29
-3o4h,2010-11-17,2010-07-27
-3o4p,2011-08-17,2010-07-27
-5o4p,2017-11-01,2017-05-30
-4o4j,2014-03-26,2013-12-18
-7o4n,2022-04-20,2021-04-06
-5o44,2017-11-08,2017-05-26
-1o4p,2004-02-17,2003-06-15
-3o4n,2011-08-31,2010-07-27
-6o4u,2020-03-04,2019-03-01
-7o4u,2021-08-25,2021-04-07
-1o4y,2003-12-09,2003-07-29
-5o4v,2018-05-16,2017-05-31
-4o4k,2014-01-08,2013-12-18
-5o4h,2017-07-19,2017-05-29
-4o44,2014-05-21,2013-12-18
-1o4h,2004-02-17,2003-06-15
-6o4h,2019-07-24,2019-02-28
-7o4g,2022-02-02,2021-04-06
-7o49,2021-11-03,2021-04-05
-2o4p,2006-12-12,2006-12-04
-6o4c,2019-07-24,2019-02-28
-3o4l,2011-01-12,2010-07-27
-5o4f,2017-07-26,2017-05-29
-2o4i,2007-03-13,2006-12-04
-2o4s,2006-12-12,2006-12-04
-1o46,2004-02-17,2003-06-15
-3o4v,2010-08-11,2010-07-27
-4o48,2014-04-09,2013-12-18
-5o4a,2018-02-07,2017-05-26
-5o47,2018-11-28,2017-05-26
-5o4q,2018-03-28,2017-05-30
-6o4w,2019-06-19,2019-03-01
-1o4a,2004-02-17,2003-06-15
-7o4i,2021-06-16,2021-04-06
-6o47,2019-05-29,2019-02-28
-6o4i,2019-11-06,2019-02-28
-5o4s,2018-06-13,2017-05-30
-5o41,2017-06-14,2017-05-25
-4o4v,2014-12-24,2013-12-19
-6o4k,2019-11-06,2019-02-28
-6o4e,2019-07-24,2019-02-28
-1o45,2004-02-17,2003-06-15
-2o4z,2007-05-15,2006-12-05
-6o4f,2019-07-24,2019-02-28
-4o43,2014-01-08,2013-12-18
-2o4j,2007-01-30,2006-12-04
-5o42,2018-06-06,2017-05-25
-1o4f,2004-02-17,2003-06-15
-6o44,2019-04-10,2019-02-28
-2o4g,2007-03-13,2006-12-04
-1o4n,2004-02-17,2003-06-15
-5o4k,2018-03-28,2017-05-29
-5o43,2018-06-06,2017-05-25
-1o4z,2003-12-09,2003-07-29
-6o4p,2020-05-06,2019-02-28
-7o4k,2021-06-16,2021-04-06
-6o4l,2019-11-06,2019-02-28
-1o44,2004-02-17,2003-06-15
-2o40,2006-12-19,2006-12-02
-2o4r,2007-01-30,2006-12-04
-6o48,2019-06-19,2019-02-28
-7o4t,2021-08-25,2021-04-07
-7o4l,2021-06-16,2021-04-06
-6o4x,2019-06-19,2019-03-01
-1o49,2004-02-17,2003-06-15
-7o46,2022-02-23,2021-04-05
-7o4w,2022-04-06,2021-04-07
-3o4j,2010-11-17,2010-07-27
-6o4n,2019-03-13,2019-02-28
-5o4i,2018-03-28,2017-05-29
-4o4l,2014-03-26,2013-12-18
-1o4s,2003-07-08,2003-06-26
-3o4o,2010-09-01,2010-07-27
-4o4q,2014-01-01,2013-12-19
-7o4f,2021-06-30,2021-04-06
-2o48,2007-07-31,2006-12-04
-1o4e,2004-02-17,2003-06-15
-4o4p,2014-01-29,2013-12-19
-1o4d,2004-02-17,2003-06-15
-5o49,2018-02-07,2017-05-26
-5o48,2018-05-16,2017-05-26
-7o4r,2021-08-25,2021-04-07
-4o4w,2014-12-24,2013-12-19
-4o4h,2014-03-05,2013-12-18
-2o4m,2007-12-18,2006-12-04
-6o4y,2020-01-15,2019-03-01
-5o4e,2017-08-30,2017-05-29
-7o4o,2022-04-06,2021-04-06
-2o4l,2006-12-12,2006-12-04
-4o4z,2014-09-24,2013-12-19
-6o49,2020-02-12,2019-02-28
-6o4z,2020-01-15,2019-03-01
-6o4d,2019-07-24,2019-02-28
-7o4b,2021-11-03,2021-04-05
-4o4g,2014-11-05,2013-12-18
-1o4q,2004-02-17,2003-06-15
-3o4y,2010-08-25,2010-07-27
-5o40,2018-06-13,2017-05-25
-3o4m,2010-08-25,2010-07-27
-5o4m,2017-07-19,2017-05-29
-7o4a,2021-11-03,2021-04-05
-1o4r,2004-02-17,2003-06-15
-5o4c,2017-08-16,2017-05-28
-2o4h,2007-11-06,2006-12-04
-4o4x,2015-01-14,2013-12-19
-1o43,2004-02-17,2003-06-15
-6o4g,2019-07-24,2019-02-28
-1o4g,2004-02-17,2003-06-15
-7o48,2022-04-13,2021-04-05
-3o47,2010-08-11,2010-07-26
-4o4o,2014-08-06,2013-12-19
-4o4r,2014-11-05,2013-12-19
-5o4y,2017-09-20,2017-05-31
-5o4n,2017-07-19,2017-05-29
-1o48,2004-02-17,2003-06-15
-5o4g,2018-05-16,2017-05-29
-4o4t,2014-09-24,2013-12-19
-4o47,2014-04-09,2013-12-18
-7o45,2022-04-13,2021-04-05
-5o4z,2017-10-25,2017-05-31
-5o4o,2018-05-16,2017-05-30
-7o4s,2021-08-25,2021-04-07
-1o42,2004-02-17,2003-06-15
-1o47,2004-02-17,2003-06-15
-4o4i,2014-03-12,2013-12-18
-2o4k,2006-12-12,2006-12-04
-7o4x,2022-04-20,2021-04-07
-6o46,2020-03-11,2019-02-28
-1o4t,2003-07-15,2003-07-03
-1o41,2004-02-17,2003-06-15
-4o4d,2014-06-18,2013-12-18
-4rot,2014-12-24,2014-10-28
-7ros,2022-06-08,2021-08-02
-4rou,2015-11-04,2014-10-29
-2rom,1997-10-15,1997-03-24
-8roo,2024-05-08,2024-01-11
-6roj,2019-07-03,2019-05-13
-1roz,2004-07-13,2003-12-02
-4rov,2014-12-31,2014-10-29
-5rof,2021-05-26,2020-09-23
-6roh,2019-07-03,2019-05-13
-2roy,1997-04-21,1996-10-23
-3rom,2011-12-21,2011-04-26
-7ron,2022-03-23,2021-07-31
-3rol,2012-04-04,2011-04-26
-5roq,2021-05-26,2020-09-23
-4row,2014-12-31,2014-10-29
-1ror,2004-12-07,2003-12-02
-6rob,2020-04-15,2019-05-10
-4rop,2014-12-17,2014-10-28
-6rok,2020-04-15,2019-05-13
-3rok,2011-12-21,2011-04-26
-2ro9,2008-04-08,2008-03-14
-2roa,2008-04-08,2008-03-14
-7roo,2022-03-23,2021-07-31
-5row,2021-05-26,2020-09-23
-5ror,2021-05-26,2020-09-23
-8rom,2024-04-10,2024-01-11
-3roq,2011-12-21,2011-04-26
-2ro8,2008-04-08,2008-03-14
-1ro6,2004-12-07,2003-12-01
-3roa,2012-05-09,2011-04-25
-3rog,2012-07-18,2011-04-25
-7rox,2022-11-09,2021-08-02
-3roo,2012-04-04,2011-04-26
-6ron,2020-07-08,2019-05-13
-6ro2,2020-04-15,2019-05-10
-7rol,2022-02-16,2021-07-30
-5rob,2021-03-10,2020-09-22
-3ror,2012-05-23,2011-04-26
-6rop,2019-12-04,2019-05-13
-3ro0,2011-10-05,2011-04-25
-2rox,1997-04-21,1996-10-23
-7roz,2021-12-08,2021-08-02
-1ro2,2004-01-27,2003-12-01
-4ro2,2015-07-01,2014-10-27
-2row,2008-06-24,2008-04-25
-3roy,2012-08-08,2011-04-26
-5ron,2021-05-26,2020-09-23
-8rop,2024-05-08,2024-01-12
-7ror,2022-06-08,2021-08-02
-2rok,2009-02-10,2008-03-28
-3ro5,2011-09-14,2011-04-25
-6roy,2020-02-19,2019-05-13
-7rof,2022-08-03,2021-07-30
-7roj,2022-01-12,2021-07-30
-3ro7,2012-07-18,2011-04-25
-1ro8,2004-02-03,2003-12-01
-6ro5,2019-06-19,2019-05-10
-4rol,2015-05-20,2014-10-28
-1rom,1997-10-15,1997-03-24
-6rot,2019-11-27,2019-05-13
-1ros,2004-12-07,2003-12-02
-3roe,2012-07-18,2011-04-25
-1ro0,2004-01-27,2003-12-01
-6ro3,2019-06-19,2019-05-10
-1rov,2004-03-16,2003-12-02
-3rov,2012-05-02,2011-04-26
-3rod,2011-09-07,2011-04-25
-7roq,2022-01-19,2021-08-01
-6ro1,2019-07-03,2019-05-10
-3roc,2011-06-15,2011-04-25
-4rom,2015-05-20,2014-10-28
-6roe,2020-04-15,2019-05-12
-1rob,1994-01-31,1993-08-23
-7rom,2022-08-10,2021-07-31
-3rou,2012-05-02,2011-04-26
-3ro8,2012-05-16,2011-04-25
-7rov,2021-09-22,2021-08-02
-6ro4,2019-07-03,2019-05-10
-2rob,2008-04-08,2008-03-14
-5rop,2021-05-26,2020-09-23
-7rou,2022-06-08,2021-08-02
-3roj,2012-05-02,2011-04-26
-6rog,2019-06-19,2019-05-13
-7rot,2022-06-08,2021-08-02
-4ros,2014-12-17,2014-10-28
-1ro9,2004-12-07,2003-12-01
-3rof,2011-09-07,2011-04-25
-7roy,2021-10-13,2021-08-02
-3ro9,2012-05-09,2011-04-25
-3roz,2012-07-18,2011-04-26
-1ro5,2004-08-24,2003-12-01
-3ro4,2011-08-03,2011-04-25
-3rox,2012-07-18,2011-04-26
-6ro8,2019-08-28,2019-05-10
-1ro7,2004-02-03,2003-12-01
-3rop,2011-12-28,2011-04-26
-2ro1,2008-05-20,2008-03-04
-5rol,2021-05-26,2020-09-23
-3ro6,2011-05-11,2011-04-25
-6roi,2019-07-03,2019-05-13
-6rof,2020-06-03,2019-05-12
-3ro1,2011-10-05,2011-04-25
-1mo8,2003-06-10,2002-09-08
-3moz,2011-06-22,2010-04-23
-6mop,2019-01-09,2018-10-04
-1mox,2003-09-10,2002-09-10
-3mo3,2010-05-05,2010-04-22
-1mom,1994-05-31,1994-03-04
-4mor,2014-02-05,2013-09-12
-6moz,2019-06-19,2018-10-05
-6moo,2019-07-17,2018-10-04
-3moc,2010-05-05,2010-04-22
-5mo1,2018-02-28,2016-12-13
-3moe,2010-06-02,2010-04-22
-4mom,2014-02-05,2013-09-12
-5mof,2017-04-19,2016-12-14
-6mo6,2019-04-10,2018-10-04
-3mou,2011-04-20,2010-04-23
-1moa,1995-02-07,1994-12-01
-5mot,2017-05-24,2016-12-14
-4mot,2013-11-20,2013-09-12
-3mol,2010-07-28,2010-04-22
-7mot,2021-07-14,2021-05-03
-3moy,2010-05-12,2010-04-23
-5moc,2017-10-04,2016-12-14
-5moj,2018-01-10,2016-12-14
-5mor,2018-02-28,2016-12-14
-1mod,1995-02-07,1994-12-01
-4mok,2014-02-05,2013-09-12
-5mow,2017-05-24,2016-12-14
-5mog,2017-07-12,2016-12-14
-6mov,2019-01-09,2018-10-04
-7mo3,2022-06-15,2021-05-01
-4moc,2014-07-16,2013-09-12
-5moi,2018-01-10,2016-12-14
-6mo2,2019-05-15,2018-10-03
-7mo0,2022-06-15,2021-05-01
-6mor,2019-01-09,2018-10-04
-7moe,2022-03-02,2021-05-01
-6moy,2019-01-30,2018-10-05
-7mo2,2022-06-15,2021-05-01
-4mo4,2014-01-01,2013-09-11
-4mo1,2013-09-25,2013-09-11
-6mo0,2019-05-22,2018-10-03
-5mod,2017-05-24,2016-12-14
-4moe,2014-02-05,2013-09-12
-4mo7,2014-02-05,2013-09-11
-6mo8,2019-01-23,2018-10-04
-5moo,2017-05-24,2016-12-14
-5mon,2017-05-24,2016-12-14
-5mol,2018-01-10,2016-12-14
-6mo1,2019-05-15,2018-10-03
-1mo3,2003-02-18,2002-09-07
-5mo2,2018-02-28,2016-12-13
-3mow,2011-05-04,2010-04-23
-3moo,2011-03-09,2010-04-22
-3mor,2011-11-02,2010-04-23
-3mof,2010-06-02,2010-04-22
-4mo9,2013-09-25,2013-09-11
-5mo8,2017-05-24,2016-12-13
-1mo4,2003-02-18,2002-09-07
-2mok,2015-05-20,2014-04-27
-7mon,2021-11-17,2021-05-03
-5mos,2018-02-28,2016-12-14
-1mog,2003-04-15,2002-09-09
-4moq,2014-02-05,2013-09-12
-3mom,2010-07-28,2010-04-22
-5moz,2017-07-12,2016-12-15
-3mo5,2010-06-30,2010-04-22
-4mob,2014-07-16,2013-09-12
-4mo2,2014-01-01,2013-09-11
-4moo,2014-02-05,2013-09-12
-4moi,2014-02-05,2013-09-12
-6moq,2019-01-09,2018-10-04
-6mom,2019-10-16,2018-10-04
-3mo6,2010-05-05,2010-04-22
-6mo9,2019-01-23,2018-10-04
-6mo3,2019-10-16,2018-10-04
-4mol,2014-02-05,2013-09-12
-6mon,2018-12-12,2018-10-04
-7moz,2021-07-14,2021-05-03
-4mos,2014-02-05,2013-09-12
-3mo0,2010-06-30,2010-04-22
-6moh,2019-06-05,2018-10-04
-3mo9,2010-05-05,2010-04-22
-1mos,1999-07-29,1998-07-15
-4moy,2014-03-26,2013-09-12
-1moq,1998-10-07,1997-04-11
-5mo3,2018-05-02,2016-12-13
-1mob,1995-02-07,1994-12-01
-4mog,2014-02-05,2013-09-12
-7mop,2021-07-28,2021-05-03
-4mow,2013-09-25,2013-09-12
-5mok,2018-01-10,2016-12-14
-3mo2,2010-06-30,2010-04-22
-6mob,2019-07-31,2018-10-04
-1mor,1998-10-07,1997-04-12
-7moh,2022-03-02,2021-05-01
-7moi,2022-03-02,2021-05-01
-6mo5,2019-07-17,2018-10-04
-1mok,2002-11-27,2002-09-09
-5mo4,2017-04-05,2016-12-13
-5mo0,2018-02-28,2016-12-13
-1mo5,2003-02-18,2002-09-07
-4mo5,2014-01-01,2013-09-11
-5moq,2018-02-28,2016-12-14
-7moy,2021-07-14,2021-05-03
-4mo8,2013-10-30,2013-09-11
-5mop,2018-01-17,2016-12-14
-5mox,2017-07-12,2016-12-14
-5moh,2017-05-24,2016-12-14
-1moj,2004-04-20,2002-09-09
-5mo7,2017-05-24,2016-12-13
-7moq,2021-07-14,2021-05-03
-5mo6,2017-05-24,2016-12-13
-4moj,2014-02-05,2013-09-12
-6mox,2019-01-09,2018-10-04
-5mov,2017-05-24,2016-12-14
-6mo4,2019-07-17,2018-10-04
-7mof,2022-03-02,2021-05-01
-4moh,2014-02-05,2013-09-12
-7mos,2021-07-14,2021-05-03
-5mo5,2017-05-24,2016-12-13
-7mo4,2022-06-15,2021-05-01
-4mof,2014-02-05,2013-09-12
-3moh,2010-06-02,2010-04-22
-1moz,2002-10-09,2002-09-10
-6mod,2019-07-17,2018-10-04
-6mo7,2019-01-23,2018-10-04
-6moa,2019-01-23,2018-10-04
-3mos,2010-07-28,2010-04-23
-7mox,2021-07-14,2021-05-03
-5mob,2017-08-02,2016-12-14
-3mo7,2011-04-06,2010-04-22
-4mop,2014-02-05,2013-09-12
-7mog,2022-03-02,2021-05-01
-6moi,2019-06-05,2018-10-04
-1mow,2002-11-29,2002-09-10
-3mok,2010-07-28,2010-04-22
-7mow,2022-05-18,2021-05-03
-1moh,1996-08-01,1996-02-27
-7mo1,2022-06-15,2021-05-01
-7mo5,2022-06-15,2021-05-01
-4mov,2014-03-26,2013-09-12
-1mo6,2003-02-18,2002-09-07
-3mo4,2010-05-12,2010-04-22
-1mo9,2002-11-27,2002-09-08
-1moo,2002-09-18,2002-09-09
-5moe,2017-05-24,2016-12-14
-1moc,1995-02-07,1994-12-01
-2mov,2014-06-25,2014-05-05
-7cko,2020-12-23,2020-07-18
-6ckr,2018-05-02,2018-02-28
-3ckt,2009-03-24,2008-03-17
-3ck7,2008-04-01,2008-03-14
-7ckp,2021-07-21,2020-07-18
-4ck9,2014-07-30,2013-12-31
-6ck0,2018-04-04,2018-02-27
-5ck7,2015-11-18,2015-07-15
-2ckq,2006-10-04,2006-04-20
-7ckf,2021-05-05,2020-07-16
-5ckw,2015-10-14,2015-07-15
-4cky,2015-03-25,2014-01-10
-5ckn,2017-01-18,2015-07-15
-5cku,2015-09-30,2015-07-15
-1ckm,1997-07-07,1997-04-20
-3ck8,2008-04-01,2008-03-14
-3cke,2008-04-01,2008-03-14
-6ckl,2019-03-06,2018-02-28
-3ckc,2008-04-01,2008-03-14
-8ckk,2024-02-28,2023-02-15
-6cki,2018-05-09,2018-02-28
-4ck8,2014-07-30,2013-12-30
-1ckn,1997-07-07,1997-04-20
-8ckh,2024-02-28,2023-02-15
-1cko,1998-01-28,1997-09-06
-3ckq,2008-07-29,2008-03-16
-7cki,2021-07-21,2020-07-17
-7ck1,2021-03-17,2020-07-15
-5ckm,2017-01-18,2015-07-15
-8ckf,2023-08-02,2023-02-15
-8ck7,2023-12-27,2023-02-14
-7ckk,2021-07-21,2020-07-17
-4cki,2014-03-05,2014-01-06
-3cks,2008-10-07,2008-03-17
-2ckl,2006-05-11,2006-04-20
-8cko,2024-01-24,2023-02-16
-4ckv,2015-01-28,2014-01-09
-6ck7,2018-03-07,2018-02-27
-3ckp,2008-06-03,2008-03-16
-4cku,2014-06-18,2014-01-08
-1ckd,1999-04-30,1999-04-22
-1ckb,1995-05-08,1995-01-24
-5ckd,2016-04-06,2015-07-15
-4ckl,2014-03-12,2014-01-07
-3cku,2008-10-07,2008-03-17
-7ck8,2021-05-26,2020-07-16
-7ckx,2021-03-03,2020-07-20
-8ckd,2024-01-24,2023-02-15
-2cke,2007-05-15,2006-04-18
-7ckg,2021-03-31,2020-07-17
-4ckt,2014-05-14,2014-01-08
-5ck1,2016-10-12,2015-07-15
-7ck0,2020-11-18,2020-07-15
-1ck1,2002-07-10,1999-04-26
-4ckr,2014-01-15,2014-01-07
-1ckk,1999-09-10,1998-11-20
-4ckj,2014-03-05,2014-01-06
-3ck2,2008-04-01,2008-03-14
-8ck2,2024-02-28,2023-02-14
-7ck9,2021-05-26,2020-07-16
-8ck3,2023-07-19,2023-02-14
-3ckg,2009-01-27,2008-03-14
-7ckj,2020-07-29,2020-07-17
-7ckn,2021-09-15,2020-07-17
-6ck3,2018-05-09,2018-02-27
-2ckm,2006-09-04,2006-04-20
-3ckw,2008-04-29,2008-03-17
-2cki,2006-05-09,2006-04-19
-8ckg,2024-02-28,2023-02-15
-6ck9,2018-04-25,2018-02-27
-6cks,2018-05-02,2018-02-28
-5ck3,2015-09-09,2015-07-15
-6cke,2019-03-06,2018-02-27
-3ckx,2008-04-29,2008-03-17
-3ck9,2008-05-20,2008-03-14
-8cke,2024-01-24,2023-02-15
-2ckj,2007-05-29,2006-04-19
-2ckp,2006-10-04,2006-04-20
-5ckx,2016-03-16,2015-07-15
-5ck6,2016-07-20,2015-07-15
-7ckq,2020-12-16,2020-07-18
-4ck1,2014-01-22,2013-12-23
-7ck2,2021-03-17,2020-07-15
-8ck5,2023-04-26,2023-02-14
-8ckt,2024-02-28,2023-02-16
-6ckw,2018-04-04,2018-03-01
-4ck0,2015-01-28,2013-12-23
-3ck4,2008-10-07,2008-03-14
-5ck4,2015-09-09,2015-07-15
-7ckm,2021-05-05,2020-07-17
-4ckc,2014-03-19,2014-01-02
-2ckb,1998-04-29,1998-01-14
-4ck3,2014-01-22,2013-12-24
-7cky,2021-03-03,2020-07-20
-6ck6,2018-05-09,2018-02-27
-6ckc,2018-05-16,2018-02-27
-6ckz,2019-03-06,2018-03-01
-1ckp,1999-01-13,1998-07-14
-3ck0,2003-08-05,1999-06-14
-6ckk,2019-03-06,2018-02-28
-8ck4,2023-07-19,2023-02-14
-4ckm,2014-03-05,2014-01-07
-8ckn,2024-02-28,2023-02-16
-7ckl,2021-05-05,2020-07-17
-4cka,2014-07-30,2013-12-31
-8ckc,2023-04-26,2023-02-15
-3ckn,2008-07-29,2008-03-16
-8cku,2023-09-20,2023-02-16
-2cks,2007-05-29,2006-04-21
-3cko,2008-07-29,2008-03-16
-5ckq,2017-01-18,2015-07-15
-2ck3,2006-05-08,2006-04-10
-8ckq,2024-02-28,2023-02-16
-6ckj,2019-03-06,2018-02-28
-3ck5,2008-03-25,2008-03-14
-5cks,2016-08-10,2015-07-15
-7ckv,2021-05-05,2020-07-19
-3cki,2008-08-05,2008-03-15
-3ckl,2008-04-01,2008-03-16
-7ckr,2020-12-23,2020-07-18
-3ckv,2008-07-29,2008-03-17
-7ckz,2021-03-03,2020-07-20
-6ckx,2018-08-29,2018-03-01
-6ck2,2018-06-13,2018-02-27
-5ck5,2015-09-09,2015-07-15
-8ck9,2024-02-28,2023-02-14
-5ckv,2016-01-27,2015-07-15
-1ck7,1999-08-25,1999-04-28
-5ckf,2016-04-06,2015-07-15
-2ckr,2007-05-29,2006-04-21
-6ck1,2019-03-06,2018-02-27
-5ckr,2016-03-02,2015-07-15
-1ck6,1999-12-29,1999-04-28
-8ck6,2024-02-28,2023-02-14
-6ckb,2018-08-01,2018-02-27
-4ckq,2015-01-21,2014-01-07
-4ck4,2014-10-08,2013-12-27
-2ck0,2003-08-05,1999-06-13
-4ckb,2014-03-19,2014-01-02
-5ck0,2016-10-12,2015-07-15
-3ckz,2008-05-20,2008-03-18
-1ckf,1999-04-30,1999-04-22
-8ck8,2023-07-19,2023-02-14
-8ckr,2024-02-28,2023-02-16
-1ckc,1999-04-30,1999-04-22
-4ck2,2014-01-22,2013-12-24
-6ckm,2019-03-06,2018-02-28
-4cke,2014-03-19,2014-01-03
-1ckl,1999-06-11,1999-04-22
-2ckf,2007-01-02,2006-04-18
-7cka,2020-12-30,2020-07-16
-3ckr,2008-06-03,2008-03-16
-3ckk,2008-04-01,2008-03-16
-7ckw,2021-03-03,2020-07-20
-1cka,1995-05-08,1995-01-24
-3ckb,2008-04-01,2008-03-14
-4qvu,2014-08-06,2014-07-15
-8qvo,2024-01-17,2023-10-18
-6qvg,2019-09-04,2019-03-01
-4qv9,2015-02-04,2014-07-14
-7qv9,2022-11-09,2022-01-20
-7qvi,2022-10-12,2022-01-21
-3qvd,2011-06-22,2011-02-25
-4qvd,2015-05-27,2014-07-14
-3qvr,2011-06-01,2011-02-25
-3qv6,2011-06-29,2011-02-25
-3qvt,2012-01-11,2011-02-25
-1qvu,2004-08-03,2003-08-28
-3qvi,2011-10-12,2011-02-25
-7qvd,2023-08-16,2022-01-21
-2qvu,2007-10-23,2007-08-08
-6qvo,2020-03-18,2019-03-04
-2qv4,2008-03-25,2007-08-07
-8qvu,2023-12-06,2023-10-18
-6qvj,2019-11-27,2019-03-02
-1qvg,2003-11-11,2003-08-27
-2qvc,2007-08-28,2007-08-08
-2qvv,2007-10-23,2007-08-08
-6qvy,2020-04-01,2019-03-05
-6qvz,2020-04-01,2019-03-05
-8qva,2024-03-27,2023-10-17
-1qvs,2003-11-04,2003-08-28
-6qvt,2020-06-10,2019-03-04
-2qvm,2007-11-13,2007-08-08
-4qvq,2015-02-04,2014-07-15
-4qv3,2015-02-04,2014-07-14
-4qv0,2015-02-04,2014-07-14
-2qv7,2008-06-17,2007-08-07
-1qv1,2003-11-11,2003-08-26
-4qvi,2015-02-11,2014-07-15
-6qv4,2020-01-15,2019-03-01
-4qvb,2015-02-25,2014-07-14
-1qv6,2004-01-20,2003-08-26
-4qvt,2014-07-30,2014-07-15
-4qvh,2014-12-17,2014-07-15
-2qv6,2008-01-15,2007-08-07
-7qvk,2023-02-01,2022-01-21
-1qv0,2003-11-11,2003-08-26
-4qvl,2015-02-04,2014-07-15
-1qvt,2004-08-03,2003-08-28
-4qv7,2015-02-04,2014-07-14
-4qvy,2015-02-04,2014-07-16
-4qvp,2015-02-04,2014-07-15
-2qvf,2008-08-12,2007-08-08
-3qvn,2012-02-08,2011-02-25
-3qv4,2011-03-30,2011-02-25
-2qvw,2007-09-25,2007-08-09
-8qvc,2024-05-29,2023-10-17
-3qvh,2011-07-20,2011-02-25
-2qvy,2007-12-18,2007-08-09
-3qvk,2011-05-04,2011-02-25
-6qvv,2019-09-25,2019-03-05
-2qvr,2007-10-23,2007-08-08
-3qvf,2011-07-20,2011-02-25
-8qv7,2024-01-17,2023-10-17
-1qv9,2003-11-11,2003-08-27
-6qv0,2019-05-29,2019-03-01
-2qvn,2007-09-04,2007-08-08
-4qv6,2015-02-04,2014-07-14
-3qv2,2012-04-11,2011-02-25
-7qvl,2023-02-01,2022-01-21
-7qvr,2022-07-13,2022-01-23
-3qv7,2011-06-29,2011-02-25
-1qvi,2003-12-16,2003-08-27
-1qvn,2005-04-05,2003-08-28
-8qv1,2024-03-27,2023-10-17
-2qvi,2008-08-12,2007-08-08
-4qv4,2015-02-04,2014-07-14
-6qv8,2020-03-25,2019-03-01
-7qvn,2023-01-25,2022-01-22
-8qv9,2024-03-27,2023-10-17
-8qv2,2024-04-24,2023-10-17
-7qva,2023-08-16,2022-01-20
-7qv5,2022-06-29,2022-01-19
-3qvs,2012-01-11,2011-02-25
-4qvs,2014-07-30,2014-07-15
-7qvw,2023-02-01,2022-01-23
-4qvm,2015-02-04,2014-07-15
-1qvj,2003-09-16,2003-08-27
-3qvq,2011-04-13,2011-02-25
-1qvf,2003-11-11,2003-08-27
-6qv3,2020-01-15,2019-03-01
-8qv4,2024-03-27,2023-10-17
-4qvw,2015-02-04,2014-07-16
-3qv1,2012-02-29,2011-02-25
-8qvd,2024-05-29,2023-10-17
-2qvx,2007-12-18,2007-08-09
-7qvv,2022-09-28,2022-01-23
-3qvb,2011-03-23,2011-02-25
-3qvw,2012-01-11,2011-02-26
-6qv5,2019-05-29,2019-03-01
-4qvv,2015-02-04,2014-07-16
-3qvv,2011-08-31,2011-02-26
-3qvo,2011-06-01,2011-02-25
-2qvd,2007-08-21,2007-08-08
-4qvx,2015-07-22,2014-07-16
-7qv7,2022-07-06,2022-01-19
-6qv1,2019-05-29,2019-03-01
-7qvz,2022-05-04,2022-01-24
-6qv9,2020-03-25,2019-03-01
-6qvh,2019-07-10,2019-03-01
-3qv9,2011-07-06,2011-02-25
-7qvj,2023-02-01,2022-01-21
-8qve,2024-05-29,2023-10-17
-2qv1,2008-08-19,2007-08-07
-2qve,2008-07-22,2007-08-08
-6qve,2019-11-27,2019-03-01
-4qvc,2015-05-27,2014-07-14
-3qvx,2012-01-11,2011-02-26
-7qv8,2022-03-16,2022-01-20
-7qvt,2022-09-28,2022-01-23
-8qv3,2024-04-24,2023-10-17
-7qv0,2023-02-01,2022-01-19
-2qvh,2007-08-28,2007-08-08
-3qv8,2011-06-29,2011-02-25
-1qvr,2003-10-21,2003-08-28
-3qvm,2011-04-13,2011-02-25
-1qv7,2004-01-20,2003-08-27
-4qv5,2015-02-04,2014-07-14
-6qvm,2020-03-25,2019-03-04
-4qvn,2015-02-04,2014-07-15
-6qv2,2019-05-29,2019-03-01
-4qv1,2015-02-04,2014-07-14
-3qvz,2011-06-22,2011-02-26
-3qvu,2011-08-31,2011-02-26
-3qvp,2011-06-01,2011-02-25
-4qv8,2015-02-04,2014-07-14
-3qvy,2011-06-22,2011-02-26
-7qvs,2022-09-14,2022-01-23
-6qvl,2019-09-04,2019-03-03
-3qvl,2011-05-04,2011-02-25
-7qvu,2022-09-28,2022-01-23
-2qvz,2007-12-18,2007-08-09
-3txz,2012-09-26,2011-09-23
-6txg,2020-04-29,2020-01-14
-5txm,2017-04-05,2016-11-17
-1tx0,2004-09-14,2004-07-01
-1txl,2004-07-20,2004-07-05
-7txg,2023-06-28,2022-02-09
-3txb,2013-01-30,2011-09-23
-4txt,2014-08-06,2014-07-07
-6tx7,2020-05-27,2020-01-13
-1txo,2004-11-23,2004-07-05
-1tx3,2005-02-15,2004-07-01
-7tx9,2023-03-29,2022-02-08
-4txj,2015-07-15,2014-07-03
-4tx6,2014-08-06,2014-07-02
-5txy,2017-08-30,2016-11-17
-7txr,2023-03-29,2022-02-09
-3txf,2013-01-30,2011-09-23
-5tx9,2018-05-16,2016-11-16
-6txx,2020-05-27,2020-01-14
-4txe,2014-08-06,2014-07-03
-4txn,2015-10-14,2014-07-03
-5txf,2017-10-25,2016-11-16
-5tx5,2017-07-05,2016-11-15
-5txn,2017-04-05,2016-11-17
-7txp,2022-03-09,2022-02-09
-1txx,1999-09-13,1999-04-07
-5txx,2017-08-30,2016-11-17
-6txp,2021-01-27,2020-01-14
-5txk,2018-05-09,2016-11-17
-8txe,2023-11-08,2023-08-23
-1tx6,2005-03-08,2004-07-02
-7txs,2022-03-09,2022-02-09
-3tx1,2011-10-05,2011-09-22
-8txo,2024-01-24,2023-08-23
-1txr,2004-07-20,2004-07-06
-3txt,2011-12-07,2011-09-23
-3txh,2013-01-30,2011-09-23
-7txq,2022-03-09,2022-02-09
-8txz,2023-12-06,2023-08-24
-3txk,2013-01-30,2011-09-23
-6tx0,2020-06-24,2020-01-13
-6txl,2021-07-28,2020-01-14
-8txn,2023-11-08,2023-08-23
-3tx6,2011-11-09,2011-09-22
-1tx2,2004-09-14,2004-07-01
-6txr,2020-07-15,2020-01-14
-8txg,2023-11-08,2023-08-23
-6txo,2020-10-21,2020-01-14
-1tx8,2005-10-18,2004-07-02
-6txi,2021-07-28,2020-01-14
-1txi,2005-05-10,2004-07-05
-1txc,2005-10-25,2004-07-02
-3tx2,2011-10-05,2011-09-22
-6txc,2020-06-24,2020-01-14
-3txi,2013-01-30,2011-09-23
-7txz,2022-03-09,2022-02-10
-6txf,2020-06-24,2020-01-14
-5txo,2017-04-05,2016-11-17
-6tx3,2020-02-19,2020-01-13
-5txs,2017-11-29,2016-11-17
-6txe,2020-06-24,2020-01-14
-5txh,2017-11-15,2016-11-16
-5txv,2017-03-01,2016-11-17
-4tx3,2015-02-04,2014-07-02
-4txw,2015-12-09,2014-07-07
-7tx0,2022-02-23,2022-02-07
-3txg,2013-01-30,2011-09-23
-6txs,2020-01-29,2020-01-14
-3tx0,2012-02-29,2011-09-22
-5txd,2017-11-15,2016-11-16
-3txd,2013-01-30,2011-09-23
-6txj,2021-07-28,2020-01-14
-1tx4,1998-09-16,1997-07-29
-6tx6,2020-05-27,2020-01-13
-4tx8,2015-10-14,2014-07-02
-4txd,2014-08-27,2014-07-03
-3txe,2013-01-30,2011-09-23
-7txb,2023-06-28,2022-02-08
-7txe,2023-05-10,2022-02-08
-6tx5,2020-05-27,2020-01-13
-5tx6,2017-03-01,2016-11-15
-6txn,2021-07-28,2020-01-14
-7txv,2022-06-01,2022-02-09
-6tx8,2020-05-27,2020-01-13
-7tx1,2022-02-23,2022-02-07
-4txm,2015-10-14,2014-07-03
-4txk,2015-12-23,2014-07-03
-7txc,2022-06-01,2022-02-08
-3txo,2011-11-30,2011-09-23
-4txz,2014-08-13,2014-07-07
-5txi,2018-05-16,2016-11-16
-7txt,2023-03-15,2022-02-09
-6txd,2020-06-03,2020-01-14
-5txz,2017-08-30,2016-11-17
-5txq,2017-04-26,2016-11-17
-6tx2,2020-02-19,2020-01-13
-5txu,2016-12-14,2016-11-17
-7tx5,2022-02-23,2022-02-07
-4txy,2014-08-13,2014-07-07
-7txl,2022-12-21,2022-02-09
-6txw,2020-05-13,2020-01-14
-7txh,2022-06-22,2022-02-09
-7txa,2023-06-28,2022-02-08
-6txa,2020-06-24,2020-01-13
-4txo,2014-10-01,2014-07-04
-5txr,2018-03-28,2016-11-17
-1txz,2004-11-30,2004-07-06
-7txd,2023-04-12,2022-02-08
-4txi,2016-01-13,2014-07-03
-1txt,2004-08-31,2004-07-06
-4tx9,2014-08-06,2014-07-02
-6txv,2020-05-13,2020-01-14
-4txa,2015-03-11,2014-07-03
-1txu,2004-09-21,2004-07-06
-1tx7,2005-09-20,2004-07-02
-7txk,2022-12-21,2022-02-09
-5txg,2016-12-14,2016-11-16
-4txs,2015-05-06,2014-07-07
-3tx9,2011-10-05,2011-09-22
-4txl,2015-07-15,2014-07-03
-6txk,2021-07-28,2020-01-14
-5txp,2017-04-05,2016-11-17
-3txa,2013-03-27,2011-09-23
-6tx4,2020-05-27,2020-01-13
-6tx9,2020-05-27,2020-01-13
-7txu,2022-06-01,2022-02-09
-6txb,2021-01-27,2020-01-14
-3txj,2013-01-30,2011-09-23
-3txm,2011-12-14,2011-09-23
-7txy,2023-02-15,2022-02-10
-8txh,2023-11-08,2023-08-23
-8txy,2024-01-10,2023-08-24
-4txc,2014-07-23,2014-07-03
-5txj,2017-11-15,2016-11-16
-7tx7,2022-09-21,2022-02-07
-1txf,2005-02-08,2004-07-04
-7tx2,2023-02-15,2022-02-07
-5txl,2017-04-05,2016-11-17
-7tx8,2022-06-01,2022-02-08
-7tx6,2022-09-21,2022-02-07
-1txk,2004-09-07,2004-07-05
-4txg,2015-10-14,2014-07-03
-4tx0,2014-10-15,2014-07-02
-5tx3,2017-11-22,2016-11-15
-7zq4,2022-07-20,2022-04-29
-5zqx,2018-05-30,2018-04-20
-6zqt,2020-11-25,2020-07-10
-1zqr,1996-11-15,1996-04-12
-4zqw,2015-10-28,2015-05-11
-1zq9,2005-05-31,2005-05-18
-3zqr,2011-08-24,2011-06-10
-1zqt,1996-11-15,1996-04-12
-6zqi,2021-01-20,2020-07-09
-1zqj,1996-11-15,1996-04-12
-7zq3,2022-07-20,2022-04-29
-1zqe,1996-04-12,1996-04-12
-2zq3,2008-09-30,2008-08-03
-5zqt,2019-04-24,2018-04-20
-1zqz,1996-11-15,1996-04-19
-5zqo,2019-04-03,2018-04-19
-4zqx,2015-06-03,2015-05-11
-5zq6,2018-05-23,2018-04-17
-1zqg,1996-11-15,1996-04-12
-5zqp,2019-04-03,2018-04-19
-6zq1,2020-11-11,2020-07-09
-3zqs,2011-07-20,2011-06-10
-1zqo,1996-11-15,1996-04-12
-2zqc,2009-07-28,2008-08-07
-3zqy,2011-10-05,2011-06-12
-2zqx,2009-08-25,2008-08-22
-7zq1,2023-03-22,2022-04-29
-1zqf,1996-11-15,1996-04-12
-1zqa,1996-11-15,1996-04-12
-5zqs,2018-05-30,2018-04-20
-5zqd,2018-07-25,2018-04-18
-3zq1,2013-06-19,2013-03-04
-1zq1,2005-10-18,2005-05-18
-1zqn,1996-11-15,1996-04-12
-3zq6,2011-06-22,2011-06-08
-4zq0,2016-03-30,2015-05-08
-3zqk,2011-07-27,2011-06-09
-1zqd,1996-11-15,1996-04-12
-1zqm,1996-11-15,1996-04-12
-7zqj,2023-05-10,2022-04-29
-6zqz,2020-11-04,2020-07-10
-3zqh,2011-12-28,2011-06-09
-4zqi,2016-01-13,2015-05-10
-3zq5,2011-11-30,2011-06-07
-5zq4,2018-05-23,2018-04-17
-3zqt,2011-12-07,2011-06-10
-2zq1,2009-08-04,2008-08-03
-1zqi,1996-11-15,1996-04-12
-5zq0,2018-10-24,2018-04-17
-7zqf,2023-03-22,2022-04-29
-1zqh,1996-11-15,1996-04-12
-2zqo,2008-09-02,2008-08-13
-7zqy,2022-12-28,2022-05-03
-6zqa,2020-09-23,2020-07-09
-5zqr,2019-04-03,2018-04-19
-5zqq,2019-04-03,2018-04-19
-3zq4,2011-09-14,2011-06-07
-3zq9,2011-06-22,2011-06-08
-5zq8,2018-10-24,2018-04-17
-4zqg,2016-06-29,2015-05-10
-4zqd,2015-08-12,2015-05-09
-3zqf,2011-12-28,2011-06-09
-5zq1,2018-10-24,2018-04-17
-5zqa,2018-07-25,2018-04-18
-6zqb,2020-09-23,2020-07-09
-6zqs,2020-11-18,2020-07-10
-3zqx,2012-04-25,2011-06-12
-4zqo,2015-06-17,2015-05-10
-6zqg,2020-09-23,2020-07-09
-1zqk,1996-11-15,1996-04-12
-3zqj,2011-06-22,2011-06-09
-7zqk,2022-07-20,2022-04-30
-1zqv,1996-11-15,1996-04-19
-1zql,1996-11-15,1996-04-12
-4zq3,2015-05-27,2015-05-08
-5zqu,2019-02-27,2018-04-20
-7zq9,2022-11-23,2022-04-29
-5zqe,2018-07-25,2018-04-18
-3zqo,2011-12-28,2011-06-10
-1zqs,1996-11-15,1996-04-12
-1zqp,1996-11-15,1996-04-12
-3zqz,2011-09-14,2011-06-13
-4zq9,2015-09-23,2015-05-08
-6zqu,2021-01-20,2020-07-10
-3zqi,2011-12-28,2011-06-09
-3zqw,2012-01-11,2011-06-12
-2zqd,2009-07-28,2008-08-07
-5zqg,2019-05-22,2018-04-18
-7zqu,2023-05-17,2022-05-03
-7zqd,2022-11-23,2022-04-29
-3zqu,2011-11-02,2011-06-11
-4zqh,2016-06-29,2015-05-10
-3zqe,2011-08-17,2011-06-09
-5zqk,2019-06-12,2018-04-19
-1zq5,2006-12-12,2005-05-18
-7zqc,2022-11-23,2022-04-29
-7zqv,2022-12-28,2022-05-03
-4zqp,2015-06-17,2015-05-10
-2zq9,2009-07-28,2008-08-07
-1zqc,1996-11-15,1996-04-12
-7zqq,2022-07-27,2022-05-02
-5zqb,2018-07-25,2018-04-18
-6zqm,2020-09-09,2020-07-10
-5zq7,2018-05-23,2018-04-17
-6zq2,2021-07-21,2020-07-09
-5zqc,2018-08-01,2018-04-18
-6zqx,2021-07-21,2020-07-10
-6zqy,2021-07-21,2020-07-10
-5zqy,2018-08-15,2018-04-20
-6zqf,2020-09-23,2020-07-09
-3zqa,2011-10-26,2011-06-08
-6zqr,2021-07-21,2020-07-10
-3zq8,2012-07-18,2011-06-08
-2zqj,2009-09-01,2008-08-11
-6zqv,2021-01-20,2020-07-10
-6zq0,2020-11-18,2020-07-09
-1zqb,1996-11-15,1996-04-12
-7zqs,2022-08-17,2022-05-02
-4zqc,2016-02-10,2015-05-08
-4zqq,2015-06-03,2015-05-11
-1zqq,1996-11-15,1996-04-12
-7zqw,2022-12-28,2022-05-03
-2zq0,2008-10-28,2008-07-31
-4zqn,2015-06-17,2015-05-10
-6zqc,2020-09-23,2020-07-09
-6zqe,2020-09-23,2020-07-09
-6zqj,2021-01-20,2020-07-09
-4zqm,2015-06-17,2015-05-10
-6zqd,2020-09-23,2020-07-09
-4zqb,2015-05-20,2015-05-08
-7zqx,2022-11-02,2022-05-03
-7zqz,2023-05-17,2022-05-03
-4zql,2015-06-17,2015-05-10
-6zqn,2020-09-09,2020-07-10
-7zqi,2023-05-10,2022-04-29
-2zq2,2009-08-04,2008-08-03
-4zqk,2015-11-04,2015-05-10
-4zqt,2015-10-07,2015-05-11
-3zq0,2013-06-19,2013-03-04
-3zqg,2011-12-28,2011-06-09
-2zqa,2009-07-28,2008-08-07
-4zqf,2016-06-29,2015-05-10
-5zqv,2019-03-13,2018-04-20
-3zqv,2011-10-05,2011-06-12
-7zqr,2023-04-05,2022-05-02
-4zqr,2015-06-17,2015-05-11
-5zqn,2018-05-16,2018-04-19
-5zqf,2018-08-08,2018-04-18
-5zqm,2019-02-27,2018-04-19
-6zqw,2021-01-20,2020-07-10
-2zqn,2008-09-02,2008-08-13
-7zqe,2022-11-23,2022-04-29
-1sha,1993-10-31,1992-08-18
-2shk,1998-11-18,1997-10-27
-8shi,2023-06-28,2023-04-14
-3sh9,2011-07-27,2011-06-16
-8shf,2023-11-01,2023-04-14
-6shv,2020-08-26,2019-08-08
-6shz,2020-02-19,2019-08-08
-5sh4,2022-10-12,2022-02-01
-5sh3,2022-10-12,2022-02-01
-7shp,2022-10-19,2021-10-11
-6shb,2020-07-08,2019-08-06
-7shj,2022-10-12,2021-10-09
-5shi,2022-10-12,2022-02-01
-8shc,2024-02-07,2023-04-13
-1shz,2005-01-18,2004-02-26
-7sho,2022-10-12,2021-10-10
-1shk,1998-11-18,1997-10-27
-1shw,2004-05-18,2004-02-26
-3sh0,2012-12-19,2011-06-15
-8sha,2023-10-25,2023-04-13
-6sh2,2019-09-25,2019-08-05
-8sho,2023-10-25,2023-04-14
-3sh6,2012-02-29,2011-06-16
-7shw,2022-04-13,2021-10-11
-1sho,1997-12-24,1997-07-23
-5shr,2022-10-19,2022-02-01
-3sh1,2011-10-26,2011-06-15
-3shr,2011-09-21,2011-06-16
-5shx,2022-10-12,2022-02-01
-5sh5,2022-10-12,2022-02-01
-3sh3,2011-10-05,2011-06-15
-8shq,2023-10-25,2023-04-14
-8shy,2024-04-24,2023-04-14
-6sh9,2019-11-06,2019-08-06
-1sh7,2005-02-22,2004-02-25
-6shk,2019-09-25,2019-08-07
-7shq,2022-04-06,2021-10-11
-1shu,2004-04-13,2004-02-26
-5shm,2022-10-12,2022-02-01
-1sht,2004-04-13,2004-02-26
-6shu,2020-02-12,2019-08-08
-6sh1,2019-09-25,2019-08-05
-6sh0,2020-08-26,2019-08-05
-5shk,2022-10-12,2022-02-01
-3shs,2011-06-29,2011-06-16
-5sh8,2022-10-12,2022-02-01
-3shi,2011-09-21,2011-06-16
-5shq,2022-10-12,2022-02-01
-3shv,2011-12-28,2011-06-17
-3she,2011-12-14,2011-06-16
-6sh6,2020-04-22,2019-08-05
-1shq,2004-08-31,2004-02-26
-3sha,2012-06-20,2011-06-16
-8shr,2024-04-17,2023-04-14
-8sht,2023-10-25,2023-04-14
-5sh6,2022-10-12,2022-02-01
-3shq,2011-10-12,2011-06-16
-5she,2022-10-12,2022-02-01
-7shk,2021-12-08,2021-10-09
-8shb,2024-04-24,2023-04-13
-8shz,2024-04-24,2023-04-14
-8shk,2024-04-24,2023-04-14
-5shc,2022-10-12,2022-02-01
-7shz,2021-12-22,2021-10-11
-5shb,2022-10-12,2022-02-01
-7she,2021-12-01,2021-10-08
-5shl,2022-10-12,2022-02-01
-1shr,2004-10-26,2004-02-26
-5sh0,2022-10-12,2022-02-01
-8sh8,2024-05-01,2023-04-13
-7shy,2021-12-15,2021-10-11
-1shb,1993-10-31,1992-08-18
-1sh4,2004-08-10,2004-02-25
-5shw,2022-10-12,2022-02-01
-3sh5,2011-12-14,2011-06-16
-3shb,2011-08-24,2011-06-16
-6shm,2020-09-09,2019-08-07
-1sh3,2004-03-09,2004-02-24
-1sh9,2004-10-05,2004-02-25
-1shh,2004-06-08,2004-02-25
-5sha,2022-10-12,2022-02-01
-1shv,1999-05-06,1999-02-23
-6shj,2020-02-05,2019-08-07
-5shg,2022-10-12,2022-02-01
-6sho,2019-11-06,2019-08-07
-6sh8,2020-07-08,2019-08-06
-5shh,2022-10-12,2022-02-01
-5shf,2022-10-12,2022-02-01
-5sho,2022-10-12,2022-02-01
-7shm,2021-11-03,2021-10-09
-6shh,2020-05-20,2019-08-06
-5shz,2022-10-12,2022-02-01
-7shg,2022-03-02,2021-10-08
-5shd,2022-10-12,2022-02-01
-1shx,2005-04-19,2004-02-26
-7shl,2021-12-08,2021-10-09
-3sh8,2011-07-27,2011-06-16
-7shv,2022-10-26,2021-10-11
-1shd,1995-01-26,1994-11-10
-8shp,2023-10-25,2023-04-14
-7sh5,2022-10-05,2021-10-08
-8shg,2023-10-25,2023-04-14
-8shj,2023-07-05,2023-04-14
-8she,2023-10-25,2023-04-13
-5shu,2022-10-12,2022-02-01
-8shd,2023-10-25,2023-04-13
-7shf,2021-12-01,2021-10-08
-8sh3,2024-02-07,2023-04-13
-5shp,2022-10-12,2022-02-01
-3shj,2011-12-07,2011-06-16
-5shn,2022-10-12,2022-02-01
-3shf,2011-08-24,2011-06-16
-8shu,2024-04-24,2023-04-14
-6shq,2020-02-05,2019-08-07
-7sh8,2023-04-12,2021-10-08
-7sh0,2022-07-20,2021-10-07
-6shx,2021-05-19,2019-08-08
-6shn,2020-02-05,2019-08-07
-5sht,2022-10-12,2022-02-01
-7sh7,2023-04-12,2021-10-08
-2shp,1999-02-16,1997-12-01
-1shn,2004-08-31,2004-02-26
-1shl,2004-08-17,2004-02-25
-5sh2,2022-10-12,2022-02-01
-7sh9,2023-04-12,2021-10-08
-5sh1,2022-10-12,2022-02-01
-3shl,2011-06-29,2011-06-16
-7sh4,2022-10-05,2021-10-07
-7sht,2021-12-15,2021-10-11
-3shx,2012-02-29,2011-06-17
-7shh,2022-04-13,2021-10-08
-5shv,2022-10-12,2022-02-01
-5shy,2022-10-12,2022-02-01
-3shw,2011-09-28,2011-06-17
-7sh2,2022-03-23,2021-10-07
-6sht,2020-05-13,2019-08-08
-3shd,2012-06-27,2011-06-16
-1shj,2004-08-17,2004-02-25
-7sh1,2022-10-26,2021-10-07
-8sh7,2024-05-01,2023-04-13
-5shs,2022-10-12,2022-02-01
-6sh3,2020-02-05,2019-08-05
-5sh9,2022-10-12,2022-02-01
-8shn,2023-10-25,2023-04-14
-6shi,2020-05-20,2019-08-06
-7shu,2021-12-15,2021-10-11
-8shh,2023-08-09,2023-04-14
-3shy,2011-08-24,2011-06-17
-8shl,2023-10-25,2023-04-14
-8sh9,2023-10-25,2023-04-13
-3shc,2012-06-20,2011-06-16
-5sh7,2022-10-12,2022-02-01
-3shz,2011-08-24,2011-06-17
-5shj,2022-10-12,2022-02-01
-3sh2,2012-03-07,2011-06-15
-3sh7,2011-07-27,2011-06-16
-4hi5,2013-10-30,2012-10-11
-2hix,2006-11-07,2006-06-29
-5hib,2016-04-06,2016-01-11
-6hiy,2018-09-26,2018-08-31
-1hi3,2001-05-31,2001-01-02
-6hi2,2019-09-11,2018-08-29
-3hic,2009-07-07,2009-05-19
-1hi4,2001-05-31,2001-01-02
-5hin,2016-07-20,2016-01-12
-2hib,2007-05-01,2006-06-29
-8hid,2023-10-04,2022-11-19
-3hia,2009-08-04,2009-05-19
-2hi0,2006-08-15,2006-06-28
-2hiw,2006-08-22,2006-06-29
-5hid,2016-04-06,2016-01-11
-2hi4,2007-02-20,2006-06-29
-6hij,2018-09-19,2018-08-30
-4hi4,2013-01-09,2012-10-11
-4hiz,2014-01-15,2012-10-12
-6hid,2019-02-20,2018-08-29
-5hiq,2016-04-27,2016-01-12
-3hiw,2009-12-08,2009-05-20
-6his,2018-11-07,2018-08-30
-1hi9,2001-08-09,2001-01-04
-6hi1,2019-09-11,2018-08-29
-8hic,2023-11-22,2022-11-19
-6hi7,2019-02-20,2018-08-29
-6hia,2019-02-20,2018-08-29
-5hi2,2016-04-06,2016-01-11
-3hi6,2009-09-22,2009-05-19
-5hik,2016-11-23,2016-01-12
-4his,2013-06-05,2012-10-11
-6hic,2019-02-20,2018-08-29
-6hit,2019-08-21,2018-08-30
-3hit,2009-12-08,2009-05-20
-4hin,2013-10-16,2012-10-11
-5hi5,2016-08-31,2016-01-11
-5hip,2016-04-27,2016-01-12
-3hio,2009-12-08,2009-05-20
-2hi8,2007-05-01,2006-06-29
-4hib,2012-11-14,2012-10-11
-6hi8,2019-10-16,2018-08-29
-3hij,2009-11-24,2009-05-20
-2hij,2007-06-19,2006-06-29
-6hib,2019-02-20,2018-08-29
-1him,1994-01-31,1992-07-08
-6hip,2019-03-27,2018-08-30
-5hit,2016-09-14,2016-01-12
-1hi5,2001-05-31,2001-01-02
-1hi8,2001-03-27,2001-01-03
-8hi5,2023-05-31,2022-11-18
-5his,2016-04-27,2016-01-12
-5hiw,2016-08-03,2016-01-12
-6hix,2018-09-26,2018-08-31
-8hiz,2023-02-08,2022-11-22
-5hi3,2016-08-31,2016-01-11
-2hih,2007-05-22,2006-06-29
-5hi6,2016-02-03,2016-01-11
-8hi6,2023-05-31,2022-11-18
-8hil,2023-03-22,2022-11-20
-8hio,2023-04-12,2022-11-21
-8hik,2022-12-21,2022-11-20
-1hiy,2001-05-31,2001-01-05
-2hil,2006-09-12,2006-06-29
-2hi7,2006-12-05,2006-06-29
-6hi3,2019-02-20,2018-08-29
-4hiq,2013-06-05,2012-10-11
-3hii,2009-10-20,2009-05-20
-4hip,2012-11-21,2012-10-11
-1hi6,2001-02-08,2001-01-02
-2hit,2007-03-27,2006-06-29
-3hiv,2009-12-08,2009-05-20
-6hif,2019-04-17,2018-08-29
-2his,1998-10-14,1998-02-23
-4hik,2012-12-12,2012-10-11
-4hil,2013-10-16,2012-10-11
-1hi0,2001-03-27,2000-12-31
-6hio,2018-11-07,2018-08-30
-4hi9,2013-12-11,2012-10-11
-6hi0,2019-12-18,2018-08-29
-6hih,2019-03-20,2018-08-29
-8hiv,2023-07-05,2022-11-22
-2hiy,2006-08-29,2006-06-29
-4hiu,2013-10-30,2012-10-12
-5hio,2016-04-27,2016-01-12
-8hin,2023-11-22,2022-11-21
-4hix,2013-03-13,2012-10-12
-3hi7,2009-10-20,2009-05-19
-4hiv,2013-05-08,2012-10-12
-1hii,1995-07-10,1995-03-31
-3hix,2009-05-26,2009-05-20
-5hil,2016-11-23,2016-01-12
-4hid,2012-12-12,2012-10-11
-2hi2,2006-09-12,2006-06-28
-6hiw,2018-09-26,2018-08-31
-8hip,2023-11-29,2022-11-21
-3hiu,2009-07-14,2009-05-20
-1hiv,1993-10-31,1992-02-12
-8hi8,2023-08-23,2022-11-18
-6hie,2019-02-20,2018-08-29
-2hiz,2007-01-23,2006-06-29
-4hii,2013-08-28,2012-10-11
-8hih,2023-06-07,2022-11-20
-3hik,2009-06-09,2009-05-20
-6hiz,2018-09-26,2018-08-31
-5hia,2017-01-18,2016-01-11
-4hij,2013-08-28,2012-10-11
-1hih,1995-07-10,1995-03-31
-5hi4,2016-08-31,2016-01-11
-3hiy,2010-05-12,2009-05-20
-5hi0,2016-04-06,2016-01-11
-4hi0,2013-10-16,2012-10-11
-4hio,2012-12-12,2012-10-11
-6hi9,2019-09-11,2018-08-29
-4hi7,2012-10-31,2012-10-11
-5hie,2016-04-06,2016-01-11
-1hi1,2001-03-27,2001-01-01
-6hi5,2019-02-20,2018-08-29
-8hir,2023-08-16,2022-11-21
-3hi2,2010-01-12,2009-05-18
-2him,2007-05-15,2006-06-29
-4hih,2013-08-28,2012-10-11
-1hin,1994-01-31,1992-07-08
-6hiq,2018-11-07,2018-08-30
-4hia,2013-01-16,2012-10-11
-6hi4,2019-02-20,2018-08-29
-5hif,2017-02-08,2016-01-11
-5hi8,2017-01-18,2016-01-11
-5him,2016-11-23,2016-01-12
-8hi9,2023-10-25,2022-11-19
-6hiv,2018-10-03,2018-08-31
-1hiz,2002-01-04,2001-01-05
-8hiq,2023-02-08,2022-11-21
-3hig,2009-10-20,2009-05-19
-4hi8,2013-12-11,2012-10-11
-4hi6,2013-10-30,2012-10-11
-2hig,2007-02-13,2006-06-29
-8hij,2022-12-21,2022-11-20
-6hi6,2019-02-20,2018-08-29
-6hin,2018-11-07,2018-08-30
-8hiu,2024-01-24,2022-11-22
-5hi7,2016-03-30,2016-01-11
-6hiu,2019-03-20,2018-08-31
-8him,2023-03-22,2022-11-21
-8hi7,2023-08-23,2022-11-18
-4him,2012-12-12,2012-10-11
-3hi1,2009-11-17,2009-05-18
-5hic,2016-04-06,2016-01-11
-7mkl,2021-05-12,2021-04-24
-7mkp,2021-06-23,2021-04-26
-6mkf,2018-10-31,2018-09-25
-1mku,1997-12-24,1997-09-10
-4mku,2014-09-10,2013-09-05
-1mkj,2002-10-30,2002-08-29
-4mk5,2013-09-25,2013-09-04
-7mko,2021-06-02,2021-04-26
-4mk1,2013-09-25,2013-09-04
-6mk0,2019-09-25,2018-09-24
-5mkt,2017-12-20,2016-12-05
-6mkn,2019-04-24,2018-09-25
-4mka,2013-10-09,2013-09-04
-1mky,2003-01-14,2002-08-29
-7mkd,2021-09-29,2021-04-23
-4mk3,2013-09-18,2013-09-04
-6mk9,2019-10-02,2018-09-25
-4mko,2015-03-11,2013-09-05
-6mkz,2018-12-19,2018-09-26
-4mk4,2013-09-25,2013-09-04
-1mkv,1998-03-18,1997-09-13
-4mkf,2014-03-26,2013-09-05
-3mku,2010-09-29,2010-04-15
-7mkj,2021-09-29,2021-04-23
-3mkb,2011-01-26,2010-04-14
-4mky,2013-12-11,2013-09-05
-2mke,2014-07-23,2014-02-06
-4mk7,2013-10-09,2013-09-04
-4mkb,2013-10-09,2013-09-04
-5mkm,2017-12-20,2016-12-05
-5mkg,2016-12-14,2016-12-04
-1mk1,2003-08-05,2002-08-28
-1mkq,2003-04-08,2002-08-29
-6mkt,2019-05-29,2018-09-26
-3mk7,2010-08-04,2010-04-14
-3mkz,2010-05-05,2010-04-15
-5mk9,2017-07-05,2016-12-02
-3mk5,2011-02-23,2010-04-14
-3mkv,2010-04-28,2010-04-15
-7mki,2021-09-29,2021-04-23
-3mks,2010-07-21,2010-04-15
-5mky,2017-12-20,2016-12-05
-3mkn,2010-12-01,2010-04-15
-5mkx,2017-12-20,2016-12-05
-5mkz,2017-12-20,2016-12-05
-6mkv,2019-10-16,2018-09-26
-7mkm,2021-05-12,2021-04-24
-4mk2,2013-09-25,2013-09-04
-5mki,2017-12-20,2016-12-05
-7mk4,2022-04-27,2021-04-21
-4mkg,2014-03-26,2013-09-05
-5mke,2017-01-18,2016-12-04
-2mk7,2015-02-04,2014-02-02
-3mkh,2010-06-02,2010-04-14
-1mkd,2003-03-01,2002-08-29
-7mka,2022-04-27,2021-04-22
-5mkp,2017-06-14,2016-12-05
-6mki,2018-10-31,2018-09-25
-7mk5,2022-02-02,2021-04-21
-6mkq,2019-01-30,2018-09-26
-4mkv,2013-10-16,2013-09-05
-4mkc,2014-04-09,2013-09-04
-4mkt,2014-03-12,2013-09-05
-4mkk,2014-11-12,2013-09-05
-7mke,2021-09-29,2021-04-23
-4mks,2014-05-21,2013-09-05
-5mku,2017-11-08,2016-12-05
-2mkk,2014-07-23,2014-02-07
-5mkn,2017-12-20,2016-12-05
-2mkn,2014-03-19,2014-02-10
-5mkq,2017-06-14,2016-12-05
-3mk2,2011-01-19,2010-04-13
-4mkq,2015-03-11,2013-09-05
-5mkr,2017-03-01,2016-12-05
-6mke,2018-10-03,2018-09-25
-7mk9,2022-04-27,2021-04-22
-3mkj,2010-08-11,2010-04-15
-7mkc,2022-05-04,2021-04-23
-5mko,2017-06-14,2016-12-05
-7mk3,2022-03-16,2021-04-21
-6mkl,2019-10-02,2018-09-25
-6mku,2019-08-07,2018-09-26
-5mkc,2017-03-15,2016-12-03
-7mkb,2021-05-26,2021-04-22
-4mk8,2013-10-09,2013-09-04
-7mkq,2021-06-02,2021-04-26
-1mk8,2003-04-08,2002-08-28
-6mkg,2018-10-31,2018-09-25
-4mk9,2013-10-09,2013-09-04
-5mka,2017-07-19,2016-12-02
-4mkp,2013-10-30,2013-09-05
-7mk7,2021-11-24,2021-04-21
-3mkf,2010-11-24,2010-04-14
-4mkm,2013-12-04,2013-09-05
-5mk4,2017-11-08,2016-12-02
-6mkw,2019-08-07,2018-09-26
-7mk1,2021-11-03,2021-04-21
-5mks,2017-03-01,2016-12-05
-3mk1,2011-01-19,2010-04-13
-1mkm,2002-09-11,2002-08-29
-4mkj,2014-11-12,2013-09-05
-1mko,2002-09-06,2002-08-29
-7mks,2022-05-04,2021-04-26
-5mkf,2017-01-18,2016-12-04
-1mkt,1998-03-11,1997-09-06
-7mkx,2022-11-09,2021-04-27
-5mkw,2017-06-28,2016-12-05
-2mkp,2014-02-26,2014-02-11
-1mkr,2003-04-08,2002-08-29
-2mkd,2014-03-19,2014-02-05
-6mk2,2019-09-11,2018-09-24
-3mkg,2011-05-25,2010-04-14
-1mks,1997-12-24,1997-08-27
-3mk0,2011-01-19,2010-04-13
-3mkm,2010-12-01,2010-04-15
-1mka,1996-07-11,1996-01-08
-7mk8,2021-06-02,2021-04-21
-4mk0,2014-01-22,2013-09-04
-3mk6,2010-09-15,2010-04-14
-1mk5,2003-09-09,2002-08-28
-6mkh,2018-10-31,2018-09-25
-3mkk,2010-06-23,2010-04-15
-2mki,2014-07-23,2014-02-07
-6mkk,2019-01-30,2018-09-25
-5mk5,2017-03-01,2016-12-02
-5mkj,2017-11-08,2016-12-05
-3mkd,2011-04-06,2010-04-14
-6mkb,2018-12-19,2018-09-25
-7mkr,2022-05-04,2021-04-26
-4mkh,2014-03-26,2013-09-05
-7mkn,2021-06-02,2021-04-26
-7mk2,2022-03-16,2021-04-21
-5mk6,2018-03-28,2016-12-02
-3mke,2010-11-24,2010-04-14
-8cvx,2022-07-13,2022-05-18
-5cvn,2015-10-07,2015-07-27
-7cvp,2020-09-09,2020-08-26
-3cv1,2008-11-11,2008-04-17
-4cvs,2014-08-20,2014-03-29
-7cv2,2020-12-16,2020-08-25
-8cve,2023-11-22,2022-05-18
-1cvj,1999-10-04,1999-08-23
-3cvn,2008-06-24,2008-04-18
-4cvz,2015-05-06,2014-03-31
-2cvj,2005-12-04,2005-06-04
-4cvq,2014-07-23,2014-03-28
-6cvj,2018-05-23,2018-03-28
-4cvc,2015-03-25,2014-03-25
-1cvz,2000-08-30,1999-08-24
-8cvd,2023-11-22,2022-05-18
-4cv0,2014-04-16,2014-03-22
-8cv9,2023-11-22,2022-05-18
-5cvp,2016-08-03,2015-07-27
-4cv4,2014-05-14,2014-03-23
-6cvn,2018-05-23,2018-03-28
-4cvp,2014-08-20,2014-03-28
-3cvu,2008-11-04,2008-04-20
-6cvt,2018-07-04,2018-03-28
-2cv3,2006-05-16,2005-05-31
-8cvl,2022-10-19,2022-05-18
-4cv3,2014-04-16,2014-03-22
-5cvs,2016-08-17,2015-07-27
-8cvf,2023-11-22,2022-05-18
-8cva,2023-11-22,2022-05-18
-4cvb,2015-03-25,2014-03-25
-8cvk,2022-10-19,2022-05-18
-8cvs,2022-11-02,2022-05-18
-3cvc,2008-07-08,2008-04-18
-7cvk,2020-09-09,2020-08-26
-6cvb,2019-07-24,2018-03-27
-8cvb,2023-11-22,2022-05-18
-7cvw,2021-09-01,2020-08-27
-7cvn,2020-09-23,2020-08-26
-8cv8,2023-11-22,2022-05-18
-2cvc,2006-06-06,2005-06-02
-4cvm,2015-04-22,2014-03-28
-8cvq,2023-04-12,2022-05-18
-7cvh,2021-09-08,2020-08-26
-2cvu,2006-03-07,2005-06-14
-1cvu,2000-05-16,1999-08-24
-8cvg,2023-11-22,2022-05-18
-4cvt,2014-08-20,2014-03-29
-5cvu,2015-09-16,2015-07-27
-1cvc,1994-01-31,1993-09-22
-4cvi,2014-07-16,2014-03-27
-1cvh,1995-02-07,1994-11-16
-7cv7,2021-09-01,2020-08-25
-5cvq,2016-08-03,2015-07-27
-5cvf,2016-07-27,2015-07-26
-7cvx,2020-11-18,2020-08-27
-3cvd,2008-07-08,2008-04-18
-4cvr,2014-08-20,2014-03-29
-4cv7,2014-04-02,2014-03-24
-8cv7,2023-05-24,2022-05-18
-3cv9,2008-11-04,2008-04-18
-3cvz,2009-03-17,2008-04-20
-8cvo,2023-03-15,2022-05-18
-4cva,2015-04-08,2014-03-24
-6cvf,2018-11-21,2018-03-28
-5cvj,2015-09-16,2015-07-27
-7cv0,2020-12-16,2020-08-25
-6cvv,2018-11-21,2018-03-29
-4cv8,2015-04-08,2014-03-24
-2cvw,2006-03-07,2005-06-14
-6cvu,2018-11-21,2018-03-28
-6cvq,2018-07-04,2018-03-28
-4cvk,2015-04-22,2014-03-28
-2cvy,2006-03-07,2005-06-14
-4cvw,2015-04-01,2014-03-31
-5cv4,2015-08-12,2015-07-25
-5cv5,2015-08-12,2015-07-25
-8cv6,2023-05-24,2022-05-18
-1cve,1994-11-30,1994-06-21
-5cvi,2015-08-12,2015-07-27
-3cvh,2008-09-23,2008-04-18
-6cvx,2018-08-08,2018-03-29
-2cvd,2006-04-18,2005-06-02
-5cv8,2015-08-12,2015-07-25
-2cv0,2006-09-05,2005-05-31
-3cvg,2008-05-13,2008-04-18
-1cvm,2000-02-24,1999-08-24
-1cvr,2000-03-01,1999-08-24
-6cve,2018-11-21,2018-03-28
-8cvv,2022-06-22,2022-05-18
-3cv3,2008-07-01,2008-04-17
-6cvo,2018-08-29,2018-03-28
-4cvj,2014-07-16,2014-03-27
-7cv6,2021-09-01,2020-08-25
-4cv2,2014-04-16,2014-03-22
-8cv3,2023-05-10,2022-05-17
-7cvj,2020-09-09,2020-08-26
-5cvv,2015-09-16,2015-07-27
-3cv2,2008-11-11,2008-04-17
-1cva,1993-10-31,1993-02-04
-8cvh,2023-11-22,2022-05-18
-5cv9,2015-08-12,2015-07-25
-5cvo,2015-10-07,2015-07-27
-2cv1,2006-09-05,2005-05-31
-4cv9,2015-04-08,2014-03-24
-4cvo,2014-04-09,2014-03-28
-6cvy,2018-08-08,2018-03-29
-2cvv,2006-03-07,2005-06-14
-6cvw,2018-08-08,2018-03-29
-1cvi,1999-08-31,1999-08-23
-4cvl,2015-04-22,2014-03-28
-7cvv,2021-09-01,2020-08-27
-3cv6,2009-03-03,2008-04-17
-5cve,2015-11-25,2015-07-26
-1cv8,1998-10-14,1998-05-08
-6cvc,2019-03-27,2018-03-27
-2cvq,2005-08-02,2005-06-13
-6cvd,2018-08-22,2018-03-27
-1cvw,1999-08-31,1999-08-24
-5cvl,2015-10-07,2015-07-27
-8cvj,2022-10-19,2022-05-18
-5cvd,2015-11-25,2015-07-26
-8cvp,2022-07-20,2022-05-18
-5cvt,2016-08-10,2015-07-27
-4cvg,2014-05-28,2014-03-25
-8cvt,2022-11-02,2022-05-18
-4cvn,2014-05-28,2014-03-28
-6cvl,2018-11-14,2018-03-28
-4cvh,2015-02-04,2014-03-27
-6cvm,2018-05-30,2018-03-28
-8cvc,2023-11-22,2022-05-18
-7cvr,2021-09-01,2020-08-26
-3cvb,2008-07-08,2008-04-18
-5cvh,2016-07-27,2015-07-26
-8cvu,2022-06-22,2022-05-18
-3cvk,2009-04-21,2008-04-18
-2cvi,2006-06-03,2005-06-03
-2cvt,2006-03-07,2005-06-14
-2cv2,2006-09-05,2005-05-31
-8cv5,2023-05-24,2022-05-18
-4cvu,2014-07-09,2014-03-31
-3cv0,2008-06-24,2008-04-17
-4cvx,2015-05-06,2014-03-31
-8cvr,2022-11-02,2022-05-18
-3cv5,2008-06-24,2008-04-17
-5cv7,2015-08-12,2015-07-25
-6cvs,2018-07-04,2018-03-28
-4cv1,2014-04-16,2014-03-22
-5cvk,2016-08-03,2015-07-27
-3cvl,2008-06-24,2008-04-18
-3cvp,2008-06-24,2008-04-18
-2cvz,2005-06-28,2005-06-14
-3cvw,2009-10-13,2008-04-20
-8cv4,2023-05-24,2022-05-18
-1cvb,1993-10-31,1993-02-04
-6cvr,2018-07-04,2018-03-28
-6cv7,2018-08-01,2018-03-27
-6cvp,2018-07-04,2018-03-28
-3cv7,2008-10-28,2008-04-18
-6cvz,2018-06-27,2018-03-29
-5cvc,2016-03-16,2015-07-26
-7cvl,2020-09-09,2020-08-26
-8cvm,2023-03-15,2022-05-18
-2cv5,2005-06-28,2005-05-31
-8cvn,2023-03-01,2022-05-18
-1cvn,1996-10-14,1995-08-09
-6cv0,2018-04-18,2018-03-27
-6cv8,2018-10-24,2018-03-27
-5cvm,2015-10-07,2015-07-27
-7cv8,2021-09-01,2020-08-25
-5cv6,2015-08-12,2015-07-25
-4cvy,2014-12-10,2014-03-31
-5cvy,2016-08-10,2015-07-27
-6cvh,2018-04-25,2018-03-28
-7cv9,2021-09-01,2020-08-25
-3cvy,2008-11-04,2008-04-20
-3cv8,2008-11-04,2008-04-18
-1cvl,1997-04-01,1997-01-09
-8cvw,2022-06-22,2022-05-18
-3cvq,2008-06-24,2008-04-18
-3cvx,2009-10-13,2008-04-20
-5cvw,2015-09-09,2015-07-27
-3cvv,2009-06-16,2008-04-20
-8cv2,2023-05-10,2022-05-17
-2cvx,2006-03-07,2005-06-14
-3cvj,2008-05-06,2008-04-18
-1cvd,1994-12-20,1994-06-21
-7cvm,2020-09-09,2020-08-26
-1e9b,2001-10-05,2000-10-10
-3e9i,2009-07-14,2008-08-22
-1e9n,2001-02-16,2000-10-24
-1e9p,2000-12-03,2000-10-25
-5e97,2015-11-18,2015-10-14
-3e9t,2009-09-01,2008-08-23
-5e9t,2016-03-02,2015-10-15
-1e9h,2001-10-11,2000-10-16
-6e9a,2018-11-07,2018-07-31
-8e9p,2022-11-02,2022-08-26
-4e9r,2013-05-01,2012-03-21
-7e9h,2021-06-23,2021-03-04
-8e9w,2022-11-30,2022-08-27
-2e98,2007-06-12,2007-01-24
-7e9q,2022-03-09,2021-03-04
-3e9k,2008-12-09,2008-08-22
-5e9l,2016-03-16,2015-10-15
-5e9a,2016-10-26,2015-10-14
-3e94,2009-03-10,2008-08-21
-5e9g,2016-04-27,2015-10-15
-7e99,2021-10-06,2021-03-03
-2e9z,2007-06-26,2007-01-29
-1e90,2000-11-17,2000-10-03
-6e94,2018-11-07,2018-07-31
-8e9o,2022-10-05,2022-08-26
-6e9e,2018-10-03,2018-08-01
-2e90,2007-06-12,2007-01-24
-8e90,2022-12-14,2022-08-26
-6e9o,2019-05-22,2018-08-01
-1e9y,2001-11-01,2000-11-01
-8e99,2022-12-07,2022-08-26
-4e9j,2012-12-05,2012-03-21
-7e9l,2021-05-05,2021-03-04
-7e9r,2022-03-09,2021-03-04
-2e9h,2008-01-15,2007-01-25
-6e9b,2019-05-15,2018-07-31
-2e9e,2007-02-06,2007-01-25
-8e9l,2022-10-05,2022-08-26
-8e97,2022-12-07,2022-08-26
-7e9p,2022-03-23,2021-03-04
-5e9r,2016-10-26,2015-10-15
-7e97,2021-10-06,2021-03-03
-6e9n,2019-05-22,2018-08-01
-4e9y,2013-03-27,2012-03-21
-5e9n,2015-12-23,2015-10-15
-2e92,2007-06-12,2007-01-24
-5e98,2015-11-18,2015-10-14
-7e9u,2022-03-09,2021-03-05
-6e93,2018-11-07,2018-07-31
-8e9x,2022-11-30,2022-08-27
-1e9v,2001-10-25,2000-10-27
-1e9g,2001-03-19,2000-10-12
-4e9d,2012-10-10,2012-03-21
-1e93,2000-10-13,2000-10-05
-1e94,2000-11-17,2000-10-07
-2e9b,2008-02-19,2007-01-24
-3e9j,2008-11-25,2008-08-22
-8e9h,2022-10-12,2022-08-26
-8e95,2023-03-22,2022-08-26
-7e98,2021-10-06,2021-03-03
-5e9f,2016-04-27,2015-10-15
-8e91,2023-11-08,2022-08-26
-5e9b,2015-11-18,2015-10-14
-8e9g,2022-10-12,2022-08-26
-5e9e,2016-06-08,2015-10-15
-5e9c,2015-11-18,2015-10-15
-1e9x,2000-11-01,2000-10-30
-4e90,2013-02-27,2012-03-20
-1e9a,2001-10-05,2000-10-10
-8e92,2022-12-07,2022-08-26
-4e93,2012-04-18,2012-03-20
-2e94,2007-06-12,2007-01-24
-1e9z,2001-11-01,2000-11-01
-5e9z,2016-01-27,2015-10-15
-4e99,2012-06-06,2012-03-20
-7e9t,2021-11-17,2021-03-05
-8e9d,2022-11-02,2022-08-26
-1e9o,2000-12-03,2000-10-25
-8e9i,2022-10-12,2022-08-26
-2e9o,2008-01-29,2007-01-26
-5e93,2016-10-19,2015-10-14
-5e9v,2015-10-28,2015-10-15
-2e9m,2007-09-11,2007-01-25
-2e9n,2008-01-29,2007-01-26
-4e9w,2013-03-27,2012-03-21
-3e9z,2009-09-01,2008-08-24
-8e9z,2022-11-30,2022-08-27
-4e96,2012-04-18,2012-03-20
-5e9u,2016-03-02,2015-10-15
-1e9d,2001-10-11,2000-10-10
-4e9q,2013-05-01,2012-03-21
-6e9f,2018-10-03,2018-08-01
-7e9a,2021-08-04,2021-03-03
-6e9l,2018-11-14,2018-08-01
-8e9n,2022-10-05,2022-08-26
-1e92,2001-10-05,2000-10-04
-5e9i,2016-03-16,2015-10-15
-1e9q,2000-12-03,2000-10-26
-8e98,2022-12-07,2022-08-26
-8e9k,2022-10-05,2022-08-26
-3e9c,2008-12-16,2008-08-21
-5e90,2016-05-11,2015-10-14
-8e9s,2022-10-05,2022-08-26
-6e90,2019-01-30,2018-07-31
-4e9v,2013-03-27,2012-03-21
-7e96,2021-10-06,2021-03-03
-2e9u,2008-01-29,2007-01-27
-8e9t,2022-10-05,2022-08-26
-8e9r,2022-10-05,2022-08-26
-7e9k,2021-05-05,2021-03-04
-8e9u,2022-11-09,2022-08-26
-8e93,2022-12-07,2022-08-26
-2e9s,2008-01-29,2007-01-26
-5e9k,2016-03-16,2015-10-15
-3e9h,2009-07-14,2008-08-22
-8e9f,2023-01-11,2022-08-26
-8e9v,2022-10-05,2022-08-26
-8e9e,2022-10-26,2022-08-26
-4e9u,2012-04-25,2012-03-21
-1e96,2000-11-17,2000-10-10
-2e9a,2007-06-12,2007-01-24
-6e99,2018-11-14,2018-07-31
-3e92,2008-09-30,2008-08-21
-5e9s,2016-09-28,2015-10-15
-5e91,2016-05-11,2015-10-14
-5e9h,2016-04-27,2015-10-15
-4e9a,2013-04-24,2012-03-20
-5e9q,2016-10-26,2015-10-15
-2e91,2007-06-12,2007-01-24
-4e9b,2013-04-24,2012-03-20
-8e94,2022-12-07,2022-08-26
-3e9x,2008-09-23,2008-08-24
-3e93,2008-09-30,2008-08-21
-2e9p,2008-01-29,2007-01-26
-1e9c,2001-10-11,2000-10-10
-1e9l,2001-03-01,2000-10-21
-7e9s,2021-09-08,2021-03-05
-8e9m,2022-10-05,2022-08-26
-2e9r,2007-06-26,2007-01-26
-5e9j,2016-07-13,2015-10-15
-1e98,2001-10-05,2000-10-10
-1e9e,2001-10-11,2000-10-11
-6e92,2019-03-27,2018-07-31
-5e9x,2016-10-26,2015-10-15
-4e9t,2013-05-01,2012-03-21
-2e9f,2007-07-31,2007-01-25
-2e9l,2007-09-11,2007-01-25
-3e90,2009-01-20,2008-08-21
-4e9x,2013-03-27,2012-03-21
-3e9y,2009-03-31,2008-08-24
-2e9t,2007-06-26,2007-01-26
-7e9w,2021-03-24,2021-03-05
-7e9n,2022-04-06,2021-03-04
-8e9c,2022-11-02,2022-08-26
-8e9q,2022-10-05,2022-08-26
-1e9i,2001-03-15,2000-10-17
-3e9s,2008-10-07,2008-08-23
-2e9v,2008-01-29,2007-01-27
-4e91,2012-04-25,2012-03-20
-6e9w,2018-11-14,2018-08-01
-1e9f,2001-10-11,2000-10-11
-2e9w,2007-08-07,2007-01-27
-6e9p,2018-08-08,2018-08-01
-7e9g,2021-06-23,2021-03-04
-3e9b,2008-12-02,2008-08-21
-5e9m,2016-03-16,2015-10-15
-6e91,2019-03-27,2018-07-31
-2e93,2007-06-12,2007-01-24
-8e9y,2022-11-30,2022-08-27
-5e92,2016-05-11,2015-10-14
-5e95,2016-11-02,2015-10-14
-7e9j,2021-05-05,2021-03-04
-3e9l,2008-10-07,2008-08-22
-1e99,2001-10-05,2000-10-10
-6e97,2019-08-21,2018-07-31
-2e9d,2007-06-12,2007-01-24
-2e95,2007-06-12,2007-01-24
-8e9b,2023-02-01,2022-08-26
-5e9w,2016-07-13,2015-10-15
-3e9q,2008-09-23,2008-08-23
-7e9y,2021-12-22,2021-03-05
-3e9r,2009-09-01,2008-08-23
-4e9c,2012-10-10,2012-03-21
-4e92,2012-04-25,2012-03-20
-7e9o,2022-03-09,2021-03-04
-1e9j,2002-07-25,2000-10-18
-8e9a,2023-06-21,2022-08-26
-8e96,2022-12-07,2022-08-26
-2e9c,2007-06-12,2007-01-24
-3e9d,2008-12-16,2008-08-21
-2e99,2007-06-12,2007-01-24
-4e9z,2012-04-25,2012-03-21
-4e9s,2013-05-01,2012-03-21
-8e9j,2022-11-02,2022-08-26
-4mlv,2014-04-02,2013-09-06
-4mlq,2014-04-02,2013-09-06
-7mlg,2021-12-22,2021-04-28
-1ml9,2002-10-23,2002-08-30
-1mlq,1995-02-07,1994-06-15
-4mll,2013-10-09,2013-09-06
-4mlt,2014-07-02,2013-09-06
-5ml5,2017-04-05,2016-12-06
-1ml4,2003-02-25,2002-08-30
-7ml3,2022-02-02,2021-04-27
-6ml8,2018-10-17,2018-09-27
-6ml3,2019-07-03,2018-09-26
-6mlw,2019-07-31,2018-09-28
-2mll,2000-03-20,1999-03-16
-3ml8,2010-06-02,2010-04-16
-7mls,2021-07-28,2021-04-28
-4mla,2015-03-11,2013-09-06
-1ml3,2003-07-08,2002-08-29
-5mld,2017-12-20,2016-12-06
-5mlt,2017-01-11,2016-12-07
-7mlq,2021-07-28,2021-04-28
-1mlu,1994-08-31,1994-06-15
-5mlu,2017-05-10,2016-12-07
-5mlf,2017-08-23,2016-12-06
-7ml2,2022-02-02,2021-04-27
-5ml1,2017-04-12,2016-12-06
-4mln,2014-04-16,2013-09-06
-1mlw,2002-12-18,2002-08-31
-3ml5,2011-03-02,2010-04-16
-1mll,1994-08-31,1994-06-15
-3mli,2010-05-12,2010-04-16
-5mlm,2018-08-01,2016-12-07
-6mlq,2019-05-01,2018-09-27
-1mlh,1994-08-31,1994-06-15
-6ml5,2019-07-03,2018-09-26
-4mli,2013-11-13,2013-09-06
-6mll,2019-04-17,2018-09-27
-6mlr,2019-05-01,2018-09-27
-5mlo,2017-06-28,2016-12-07
-7ml0,2022-02-02,2021-04-27
-3mly,2010-07-14,2010-04-18
-5ml9,2017-12-13,2016-12-06
-7mln,2022-02-09,2021-04-28
-6ml4,2019-07-03,2018-09-26
-6mlp,2019-08-07,2018-09-27
-3ml1,2011-04-06,2010-04-16
-3mla,2010-07-28,2010-04-16
-4mlz,2013-09-18,2013-09-06
-7mly,2021-09-29,2021-04-29
-2ml1,2014-10-01,2014-02-18
-5mle,2017-02-22,2016-12-06
-5mln,2017-12-20,2016-12-07
-7mlu,2021-09-29,2021-04-29
-7mlm,2021-07-28,2021-04-28
-3mll,2011-03-02,2010-04-16
-5mlr,2018-08-01,2016-12-07
-3ml4,2010-07-14,2010-04-16
-5ml3,2017-02-01,2016-12-06
-3ml2,2011-04-20,2010-04-16
-1mlm,1994-08-31,1994-06-15
-3mln,2010-12-01,2010-04-17
-7mlc,2021-09-29,2021-04-28
-3ml0,2010-05-05,2010-04-16
-6mlo,2019-08-07,2018-09-27
-7ml8,2021-10-27,2021-04-27
-7mlz,2021-07-28,2021-04-29
-4mlg,2014-09-17,2013-09-06
-4mlf,2013-09-25,2013-09-06
-5ml8,2017-02-01,2016-12-06
-1mlj,1994-08-31,1994-06-15
-2mlm,2014-11-19,2014-03-03
-3mle,2010-05-19,2010-04-16
-5ml4,2017-02-01,2016-12-06
-3mlp,2010-12-01,2010-04-17
-5mlx,2017-05-10,2016-12-08
-6mly,2019-10-02,2018-09-28
-2mls,2014-12-03,2014-03-04
-6mln,2019-08-07,2018-09-27
-4mlm,2014-04-16,2013-09-06
-5mlj,2017-12-20,2016-12-06
-1mlr,1994-08-31,1994-06-15
-3mlk,2011-03-02,2010-04-16
-7mlk,2022-05-04,2021-04-28
-6mlt,2019-08-28,2018-09-28
-6mlf,2019-07-31,2018-09-27
-6mli,2019-08-07,2018-09-27
-7mlj,2022-02-02,2021-04-28
-5mlg,2017-12-20,2016-12-06
-7mla,2022-05-04,2021-04-28
-7ml5,2021-11-17,2021-04-27
-6mlg,2019-08-07,2018-09-27
-3mlb,2010-07-28,2010-04-16
-6mla,2019-08-07,2018-09-27
-1ml6,2003-04-15,2002-08-30
-7mlt,2022-02-09,2021-04-29
-7ml9,2021-05-05,2021-04-27
-4mlr,2015-01-14,2013-09-06
-6ml2,2019-07-03,2018-09-26
-7ml1,2022-02-02,2021-04-27
-6mle,2019-08-07,2018-09-27
-4ml5,2014-09-10,2013-09-06
-4mls,2013-11-13,2013-09-06
-7mlf,2021-12-22,2021-04-28
-2mlf,2014-03-12,2014-02-26
-7ml4,2022-02-02,2021-04-27
-1ml7,2002-09-20,2002-08-30
-6mlh,2019-07-31,2018-09-27
-1ml2,2003-04-08,2002-08-29
-7mlp,2022-02-09,2021-04-28
-1mln,1994-08-31,1994-06-15
-6ml6,2019-07-03,2018-09-26
-6mls,2019-10-02,2018-09-27
-7mle,2022-04-06,2021-04-28
-2ml2,2014-10-01,2014-02-18
-7mlb,2022-02-02,2021-04-28
-7mli,2022-02-02,2021-04-28
-3ml9,2010-06-02,2010-04-16
-7mlr,2021-07-28,2021-04-28
-1mlf,1994-08-31,1994-06-15
-1mls,1994-08-31,1994-06-15
-1ml1,1997-03-12,1996-09-27
-5ml2,2017-02-01,2016-12-06
-4ml9,2013-09-18,2013-09-06
-5mla,2017-12-20,2016-12-06
-6mlm,2019-02-20,2018-09-27
-5mlz,2017-08-09,2016-12-08
-3mlo,2010-12-01,2010-04-17
-6ml1,2019-01-23,2018-09-26
-7ml7,2021-06-09,2021-04-27
-1mlz,2002-12-04,2002-09-02
-1mlv,2002-10-30,2002-08-30
-2ml3,2014-10-01,2014-02-18
-6ml9,2019-08-07,2018-09-27
-6ml7,2019-07-03,2018-09-26
-5ml0,2017-12-20,2016-12-05
-2mle,2014-03-12,2014-02-26
-4mlc,2013-09-18,2013-09-06
-1mlg,1994-08-31,1994-06-15
-3mls,2010-07-14,2010-04-18
-1mly,2002-12-04,2002-09-02
-7mlo,2022-02-09,2021-04-28
-1mlk,1994-08-31,1994-06-15
-1mlo,1994-08-31,1994-06-15
-4ml4,2013-09-25,2013-09-06
-7mlv,2021-09-29,2021-04-29
-4mlw,2013-11-13,2013-09-06
-5ml6,2017-02-01,2016-12-06
-4mle,2013-09-25,2013-09-06
-3mlc,2011-04-06,2010-04-16
-5mlb,2017-12-20,2016-12-06
-4mlx,2014-07-02,2013-09-06
-6mlj,2019-08-07,2018-09-27
-2mlr,2014-12-03,2014-03-04
-4mlh,2013-09-25,2013-09-06
-7mld,2021-09-29,2021-04-28
-4ml8,2015-03-11,2013-09-06
-5mli,2017-12-20,2016-12-06
-5mlh,2018-08-01,2016-12-06
-3mlj,2011-03-02,2010-04-16
-5mls,2017-12-20,2016-12-07
-4mlp,2013-10-16,2013-09-06
-4mly,2013-12-11,2013-09-06
-6mlb,2019-10-16,2018-09-27
-1lqk,2002-09-11,2002-05-10
-5lqu,2016-10-05,2016-08-17
-6lqg,2021-01-27,2020-01-13
-7lq0,2022-02-16,2021-02-12
-4lqf,2014-08-06,2013-07-17
-3lqj,2010-07-07,2010-02-09
-1lqt,2002-07-31,2002-05-13
-3lql,2010-12-15,2010-02-09
-4lqp,2014-07-30,2013-07-19
-3lq0,2010-02-23,2010-02-08
-5lqf,2017-01-11,2016-08-17
-3lqg,2010-12-15,2010-02-09
-5lq6,2016-11-02,2016-08-16
-6lqd,2020-03-11,2020-01-13
-5lqj,2016-09-28,2016-08-17
-4lq3,2014-02-12,2013-07-17
-6lqp,2020-09-16,2020-01-14
-3lq8,2010-05-19,2010-02-08
-4lqs,2014-07-30,2013-07-19
-3lq3,2010-05-05,2010-02-08
-4lqk,2013-12-25,2013-07-18
-4lq0,2014-07-16,2013-07-16
-5lqy,2016-11-16,2016-08-17
-5lqz,2016-11-16,2016-08-17
-6lqu,2020-09-16,2020-01-14
-3lqr,2010-04-28,2010-02-09
-6lq5,2020-07-01,2020-01-13
-6lqx,2021-01-20,2020-01-14
-7lqv,2021-03-24,2021-02-15
-6lq1,2020-07-01,2020-01-12
-7lqd,2022-02-16,2021-02-13
-1lqf,2002-07-24,2002-05-10
-3lqs,2010-03-16,2010-02-10
-6lq0,2020-07-01,2020-01-12
-1lqx,2002-09-04,2002-05-14
-7lqe,2021-06-30,2021-02-13
-4lqx,2013-09-04,2013-07-19
-3lqf,2010-04-21,2010-02-09
-1lqa,2003-07-08,2002-05-09
-4lqj,2014-09-17,2013-07-18
-7lq7,2021-09-15,2021-02-13
-6lq2,2020-07-01,2020-01-12
-1lqo,2002-09-11,2002-05-11
-1lqs,2002-07-17,2002-05-13
-6lqk,2021-01-20,2020-01-13
-6lql,2020-06-03,2020-01-14
-4lqy,2013-12-18,2013-07-19
-7lq5,2022-08-24,2021-02-13
-7lqc,2022-02-23,2021-02-13
-1lqd,2003-05-10,2002-05-10
-3lq2,2010-03-02,2010-02-08
-6lqy,2020-05-13,2020-01-15
-6lqr,2020-09-16,2020-01-14
-5lq1,2017-12-06,2016-08-15
-4lq1,2015-04-01,2013-07-17
-4lqq,2014-07-30,2013-07-19
-1lqy,2002-07-24,2002-05-14
-5lqs,2016-08-31,2016-08-17
-4lqg,2014-12-31,2013-07-18
-5lqx,2016-11-16,2016-08-17
-6lq7,2020-07-01,2020-01-13
-3lqq,2010-04-28,2010-02-09
-3lqh,2010-07-07,2010-02-09
-1lqw,2002-07-24,2002-05-14
-7lqu,2021-11-17,2021-02-15
-3lqz,2010-04-14,2010-02-10
-6lqc,2020-05-20,2020-01-13
-4lqv,2014-07-23,2013-07-19
-1lq8,2003-02-11,2002-05-09
-7lq4,2021-07-14,2021-02-12
-3lqa,2010-04-07,2010-02-08
-3lqc,2010-04-28,2010-02-09
-3lq4,2010-03-02,2010-02-08
-7lql,2021-05-19,2021-02-13
-6lq8,2020-11-25,2020-01-13
-6lqa,2021-03-24,2020-01-13
-4lqh,2014-07-23,2013-07-18
-7lqj,2021-05-19,2021-02-13
-6lqt,2020-09-16,2020-01-14
-7lqp,2022-02-23,2021-02-15
-2lq6,2012-10-24,2012-02-25
-5lq9,2017-08-23,2016-08-16
-5lq7,2016-11-02,2016-08-16
-5lqa,2016-10-05,2016-08-16
-6lqw,2020-01-29,2020-01-14
-7lqy,2021-04-21,2021-02-15
-4lqr,2014-07-23,2013-07-19
-6lq3,2020-07-01,2020-01-12
-1lqp,2002-09-11,2002-05-11
-6lqf,2020-06-03,2020-01-13
-4lq2,2014-08-27,2013-07-17
-7lqb,2022-02-23,2021-02-13
-5lqk,2016-08-31,2016-08-17
-6lq6,2020-07-01,2020-01-13
-3lqd,2011-02-09,2010-02-09
-3lqu,2010-09-15,2010-02-10
-2lqd,2012-05-09,2012-03-02
-7lqk,2021-05-19,2021-02-13
-2lqc,2012-06-06,2012-02-29
-4lqm,2014-01-15,2013-07-19
-7lqz,2021-04-21,2021-02-15
-7lq9,2022-02-23,2021-02-13
-5lq2,2017-07-05,2016-08-15
-5lqr,2016-10-05,2016-08-17
-5lq4,2016-11-09,2016-08-16
-3lqv,2011-01-26,2010-02-10
-7lqf,2021-06-30,2021-02-13
-6lqm,2020-08-26,2020-01-14
-5lq0,2017-07-05,2016-08-15
-6lq4,2020-07-01,2020-01-13
-6lqq,2020-09-16,2020-01-14
-6lqs,2020-09-16,2020-01-14
-3lqb,2010-09-08,2010-02-08
-3lq5,2011-01-19,2010-02-08
-7lq3,2021-07-14,2021-02-12
-7lq1,2022-02-16,2021-02-12
-7lqh,2021-06-30,2021-02-13
-7lqa,2022-02-23,2021-02-13
-6lqb,2021-01-13,2020-01-13
-4lq9,2014-02-12,2013-07-17
-5lqc,2016-08-31,2016-08-16
-5lqq,2016-12-28,2016-08-17
-6lq9,2021-06-23,2020-01-13
-1lq2,2003-11-18,2002-05-09
-7lq8,2022-02-23,2021-02-13
-7lq2,2021-07-14,2021-02-12
-5lqn,2016-10-05,2016-08-17
-1lqv,2002-06-19,2002-05-13
-7lqg,2021-06-30,2021-02-13
-4lq6,2013-12-04,2013-07-17
-1lqe,2003-05-10,2002-05-10
-7lqw,2021-03-24,2021-02-15
-4lqi,2013-12-25,2013-07-18
-6lqe,2020-06-03,2020-01-13
-4lq5,2014-07-23,2013-07-17
-1lqu,2002-07-31,2002-05-13
-6lqv,2020-09-16,2020-01-14
-3lqi,2010-07-07,2010-02-09
-2lqp,2012-06-06,2012-03-10
-7lqi,2021-06-30,2021-02-13
-2c9h,2005-12-13,2005-12-12
-2c99,2006-02-01,2005-12-09
-6c92,2018-09-05,2018-01-25
-6c9a,2018-04-04,2018-01-25
-1c9h,2000-08-03,1999-08-02
-3c96,2008-02-26,2008-02-15
-7c9i,2021-01-27,2020-06-05
-5c93,2016-07-27,2015-06-26
-1c9s,1999-09-15,1999-08-03
-4c9i,2013-10-16,2013-10-02
-6c9f,2018-11-28,2018-01-26
-4c9g,2014-01-22,2013-10-02
-6c9h,2018-11-28,2018-01-26
-1c9y,2000-06-06,1999-08-03
-6c9q,2019-05-01,2018-01-28
-6c9u,2018-05-23,2018-01-28
-7c9c,2020-11-25,2020-06-05
-3c99,2008-05-13,2008-02-15
-2c98,2006-02-01,2005-12-09
-6c9s,2019-05-01,2018-01-28
-3c9f,2008-02-26,2008-02-15
-4c9l,2013-12-04,2013-10-02
-3c9l,2008-08-05,2008-02-16
-4c91,2013-11-13,2013-10-02
-7c9m,2021-04-28,2020-06-06
-5c9v,2015-07-22,2015-06-29
-8c9d,2023-08-16,2023-01-21
-7c94,2020-09-30,2020-06-04
-7c90,2020-07-22,2020-06-04
-7c9q,2021-06-09,2020-06-07
-2c9s,2005-12-15,2005-12-14
-5c9c,2015-07-15,2015-06-26
-6c96,2018-04-04,2018-01-25
-1c9l,2000-02-07,1999-08-02
-8c9x,2023-10-11,2023-01-23
-4c9x,2014-04-02,2013-10-03
-6c9z,2018-02-28,2018-01-29
-4c9m,2013-12-04,2013-10-02
-5c9x,2016-08-10,2015-06-29
-6c9y,2018-02-28,2018-01-29
-6c9b,2018-04-04,2018-01-26
-4c9p,2013-12-04,2013-10-02
-2c90,2006-07-04,2005-12-08
-7c91,2021-06-09,2020-06-04
-1c9i,2000-02-07,1999-08-02
-8c9f,2023-08-16,2023-01-21
-3c94,2008-07-08,2008-02-15
-2c9a,2006-01-19,2005-12-09
-2c9u,2005-12-16,2005-12-14
-5c9m,2016-09-21,2015-06-28
-6c9c,2019-03-13,2018-01-26
-5c97,2015-08-26,2015-06-26
-2c9c,2006-02-01,2005-12-09
-6c9j,2018-11-28,2018-01-26
-2c9e,2007-02-20,2005-12-09
-8c9j,2023-06-28,2023-01-23
-7c98,2020-11-18,2020-06-05
-3c9i,2009-03-03,2008-02-15
-3c9r,2008-03-18,2008-02-18
-3c9m,2008-08-05,2008-02-16
-5c9w,2016-08-10,2015-06-29
-4c9k,2013-12-04,2013-10-02
-1c9d,1999-12-29,1999-08-02
-2c9m,2006-12-18,2005-12-13
-1c9m,1999-10-06,1999-08-02
-1c9q,2000-08-09,1999-08-03
-2c9q,2006-05-03,2005-12-14
-2c92,2006-12-13,2005-12-09
-4c90,2013-11-13,2013-10-02
-3c9e,2008-08-26,2008-02-15
-2c9w,2006-02-22,2005-12-14
-5c9z,2016-06-29,2015-06-29
-5c9u,2016-08-10,2015-06-29
-8c9g,2023-08-23,2023-01-22
-3c9n,2008-02-26,2008-02-18
-6c93,2018-06-20,2018-01-25
-5c9d,2015-10-14,2015-06-26
-8c9e,2023-08-16,2023-01-21
-6c9e,2018-03-21,2018-01-26
-7c9b,2021-06-09,2020-06-05
-3c9t,2008-03-18,2008-02-18
-1c9p,2000-08-03,1999-08-03
-5c9a,2015-08-26,2015-06-26
-7c9a,2020-11-18,2020-06-05
-6c9x,2018-03-07,2018-01-29
-3c9h,2008-03-04,2008-02-15
-3c9w,2008-07-08,2008-02-18
-8c9i,2024-02-07,2023-01-23
-3c9c,2008-05-13,2008-02-15
-4c98,2013-11-06,2013-10-02
-6c9w,2018-08-15,2018-01-29
-4c9o,2013-12-04,2013-10-02
-2c95,2007-02-20,2005-12-09
-7c9n,2021-04-07,2020-06-06
-2c9b,2006-12-13,2005-12-09
-4c9q,2014-01-22,2013-10-02
-5c9f,2015-10-14,2015-06-26
-5c9p,2016-10-19,2015-06-28
-6c91,2018-04-18,2018-01-25
-8c9w,2023-07-12,2023-01-23
-4c9h,2014-01-22,2013-10-02
-6c9p,2019-05-01,2018-01-28
-8c9h,2024-01-31,2023-01-22
-5c9l,2016-10-19,2015-06-27
-2c9v,2005-12-20,2005-12-14
-8c9o,2024-02-07,2023-01-23
-4c9w,2014-04-02,2013-10-03
-8c9s,2023-04-05,2023-01-23
-5c9r,2016-07-27,2015-06-28
-6c9n,2019-05-01,2018-01-28
-4c94,2013-10-16,2013-10-02
-2c97,2006-12-13,2005-12-09
-7c92,2021-06-09,2020-06-04
-6c98,2018-05-30,2018-01-25
-4c9j,2014-01-22,2013-10-02
-2c9x,2006-08-16,2005-12-15
-1c9j,1999-10-06,1999-08-02
-2c9r,2006-05-03,2005-12-14
-1c9o,2000-04-02,1999-08-03
-3c9s,2008-03-18,2008-02-18
-3c9j,2008-03-11,2008-02-15
-4c9f,2014-10-15,2013-10-02
-8c9v,2023-04-05,2023-01-23
-2c9y,2006-01-04,2005-12-15
-2c96,2006-02-01,2005-12-09
-4c9n,2013-12-04,2013-10-02
-2c9o,2006-10-23,2005-12-14
-3c95,2008-07-08,2008-02-15
-2c9z,2006-01-09,2005-12-15
-1c9k,1999-08-18,1999-08-02
-2c94,2006-12-13,2005-12-09
-1c9u,2000-02-04,1999-08-03
-6c99,2018-05-30,2018-01-25
-2c91,2006-02-15,2005-12-08
-3c9q,2008-02-26,2008-02-18
-1c9e,2000-03-22,1999-08-02
-6c9g,2018-11-28,2018-01-26
-5c91,2015-09-30,2015-06-26
-1c9n,1999-10-06,1999-08-02
-4c9z,2013-10-16,2013-10-04
-1c9w,2000-01-07,1999-08-03
-6c94,2018-06-20,2018-01-25
-5c92,2015-07-08,2015-06-26
-2c9p,2006-05-03,2005-12-14
-3c9z,2008-11-25,2008-02-19
-7c9k,2021-04-28,2020-06-06
-6c9r,2019-05-01,2018-01-28
-2c9d,2006-12-13,2005-12-09
-7c99,2020-11-18,2020-06-05
-3c9u,2008-03-18,2008-02-18
-7c9r,2020-10-07,2020-06-07
-6c9v,2019-05-01,2018-01-28
-1c9c,2000-12-20,1999-08-02
-6c90,2018-05-30,2018-01-25
-2c93,2006-07-04,2005-12-09
-7c97,2020-08-12,2020-06-05
-5kaq,2017-02-22,2016-06-01
-3ka4,2010-10-06,2009-10-18
-4kax,2013-08-14,2013-04-23
-3kab,2009-12-22,2009-10-19
-4ka3,2013-06-26,2013-04-22
-1kax,1996-11-08,1996-04-15
-4kaf,2013-06-05,2013-04-22
-3ka7,2009-11-17,2009-10-18
-6kaj,2020-01-29,2019-06-23
-7kac,2021-01-13,2020-09-30
-6kaz,2020-11-11,2019-06-24
-3kaq,2009-11-24,2009-10-19
-6kah,2020-02-19,2019-06-23
-6kal,2020-01-15,2019-06-23
-1kaz,1996-11-08,1996-04-15
-6ka2,2020-06-24,2019-06-20
-1kar,2002-06-12,2001-11-02
-6kao,2020-02-19,2019-06-23
-4kat,2014-03-26,2013-04-22
-4kaa,2013-06-05,2013-04-22
-2kaw,2009-09-15,2008-11-17
-6kab,2020-04-08,2019-06-21
-4kab,2013-09-11,2013-04-22
-4kao,2013-09-11,2013-04-22
-3kaz,2009-12-08,2009-10-19
-1kak,2002-06-19,2001-11-02
-3kaf,2009-12-22,2009-10-19
-8ka4,2024-02-21,2023-08-02
-7kad,2021-10-06,2020-09-30
-2kad,2008-11-18,2008-11-04
-6kav,2020-02-19,2019-06-24
-5ka3,2017-03-08,2016-06-01
-5kad,2017-03-01,2016-06-01
-5kap,2016-11-09,2016-06-01
-3kan,2011-04-20,2009-10-19
-3kah,2009-12-22,2009-10-19
-4kak,2013-10-09,2013-04-22
-5kaf,2016-11-23,2016-06-01
-6kar,2020-02-19,2019-06-24
-1kah,2002-06-12,2001-11-02
-3ka8,2010-10-06,2009-10-19
-5kar,2016-10-05,2016-06-02
-6kas,2020-02-19,2019-06-24
-3ka6,2010-10-06,2009-10-18
-2ka4,2009-04-21,2008-10-30
-5kag,2017-06-21,2016-06-01
-8ka3,2024-02-21,2023-08-02
-5kaj,2017-06-21,2016-06-01
-1kao,1997-12-24,1997-08-01
-8ka8,2024-01-31,2023-08-02
-6kat,2020-02-19,2019-06-24
-6kad,2019-10-23,2019-06-21
-1ka2,2002-11-06,2001-10-31
-5kas,2016-10-05,2016-06-02
-5kal,2016-10-26,2016-06-01
-6kan,2020-01-15,2019-06-23
-6ka6,2020-04-08,2019-06-21
-4kap,2013-07-10,2013-04-22
-2kau,1995-07-10,1995-02-16
-1kaq,2002-07-12,2001-11-02
-4ka9,2014-05-07,2013-04-22
-3ka9,2010-10-06,2009-10-19
-6kay,2020-11-11,2019-06-24
-5kaw,2016-08-24,2016-06-02
-5ka1,2017-03-01,2016-06-01
-6kap,2020-02-19,2019-06-23
-1ka1,2001-11-07,2001-10-31
-2kay,2009-06-30,2008-11-17
-7ka1,2021-09-29,2020-09-29
-2kaj,2009-11-10,2008-11-06
-6kaq,2020-02-19,2019-06-24
-3kaa,2010-01-26,2009-10-19
-4kac,2013-06-05,2013-04-22
-4ka7,2013-09-18,2013-04-22
-5kae,2017-06-21,2016-06-01
-4kav,2013-07-24,2013-04-23
-5kai,2016-11-23,2016-06-01
-7kaw,2021-01-06,2020-10-01
-6ka5,2019-10-16,2019-06-20
-3kam,2010-02-16,2009-10-19
-3ka3,2010-10-06,2009-10-18
-4kai,2013-05-08,2013-04-22
-4kas,2014-03-26,2013-04-22
-4kah,2013-05-22,2013-04-22
-1kay,1996-11-08,1996-04-15
-2kak,2009-05-05,2008-11-06
-3kas,2010-03-09,2009-10-19
-8ka5,2024-02-21,2023-08-02
-7kay,2021-01-06,2020-10-01
-3kap,2009-11-24,2009-10-19
-5kan,2016-11-30,2016-06-01
-6kak,2020-01-15,2019-06-23
-4kaj,2013-06-05,2013-04-22
-6kae,2020-02-19,2019-06-21
-3kac,2009-12-22,2009-10-19
-3kad,2009-12-22,2009-10-19
-1kav,2002-06-19,2001-11-03
-4kan,2013-05-22,2013-04-22
-3kag,2009-12-22,2009-10-19
-7kav,2021-01-06,2020-10-01
-8kae,2024-01-03,2023-08-03
-3kar,1998-04-29,1997-11-26
-3kal,2009-12-22,2009-10-19
-5ka9,2017-03-01,2016-06-01
-5kah,2017-06-21,2016-06-01
-4kae,2013-05-01,2013-04-22
-2ka9,2009-06-23,2008-11-03
-4kaz,2014-03-05,2013-04-23
-6ka0,2020-06-17,2019-06-19
-3ka0,2010-01-12,2009-10-16
-4kaw,2014-03-19,2013-04-23
-6kam,2020-01-15,2019-06-23
-6kaf,2019-10-23,2019-06-22
-5kao,2016-08-31,2016-06-01
-2kae,2009-01-06,2008-11-04
-7ka0,2021-05-12,2020-09-29
-6ka9,2020-02-19,2019-06-21
-1kae,2002-06-12,2001-11-01
-6kai,2020-02-19,2019-06-23
-5kam,2016-11-09,2016-06-01
-7kab,2021-05-12,2020-09-30
-5kax,2016-08-24,2016-06-02
-3kai,2009-12-22,2009-10-19
-1kap,1995-10-15,1995-06-08
-3kak,2009-12-22,2009-10-19
-1ka0,2001-11-07,2001-10-31
-4kad,2013-05-22,2013-04-22
-6ka7,2020-06-24,2019-06-21
-5kay,2016-08-03,2016-06-02
-4ka4,2013-05-15,2013-04-22
-6kac,2019-10-23,2019-06-21
-3kao,2009-10-27,2009-10-19
-5kat,2016-08-24,2016-06-02
-4kal,2013-05-22,2013-04-22
-4ka8,2013-09-18,2013-04-22
-5kau,2016-08-24,2016-06-02
-1ka4,2002-11-06,2001-10-31
-3ka2,2011-04-27,2009-10-18
-7kaz,2021-01-06,2020-10-01
-5ka7,2017-03-08,2016-06-01
-6kau,2020-02-19,2019-06-24
-4kar,2014-03-26,2013-04-22
-7kaa,2021-03-24,2020-09-30
-2ka6,2009-04-07,2008-10-30
-4kay,2013-07-17,2013-04-23
-7kaf,2021-02-03,2020-09-30
-5kab,2017-03-08,2016-06-01
-6b8u,2017-11-22,2017-10-09
-4b8t,2012-11-07,2012-08-30
-8b8y,2022-12-28,2022-10-05
-1b85,1999-02-16,1999-02-05
-3b8w,2008-07-08,2007-11-02
-6b8j,2017-11-08,2017-10-08
-1b87,1999-06-30,1999-02-09
-6b8n,2018-03-14,2017-10-09
-7b8o,2022-01-12,2020-12-13
-6b83,2018-10-03,2017-10-05
-7b88,2021-01-13,2020-12-12
-4b8n,2013-09-04,2012-08-28
-7b82,2021-10-20,2020-12-12
-4b8y,2012-11-21,2012-08-31
-8b8o,2023-10-18,2022-10-04
-1b8r,1999-02-09,1999-02-02
-3b89,2007-11-27,2007-10-31
-1b80,1999-02-09,1999-02-03
-5b80,2017-03-15,2016-06-10
-3b8t,2008-07-08,2007-11-02
-4b85,2013-09-04,2012-08-24
-1b8y,1999-08-31,1999-02-03
-1b8t,1999-05-06,1999-02-02
-7b8u,2022-01-12,2020-12-13
-3b8y,2008-04-29,2007-11-02
-7b8t,2021-10-20,2020-12-13
-1b8l,1999-10-05,1999-02-01
-7b8e,2021-03-17,2020-12-12
-2b8j,2005-11-29,2005-10-07
-3b81,2007-11-20,2007-10-31
-3b8x,2007-11-27,2007-11-02
-7b8a,2022-01-12,2020-12-12
-3b8h,2008-06-17,2007-11-01
-3b8v,2008-07-08,2007-11-02
-2b83,2006-09-19,2005-10-06
-6b8r,2017-10-18,2017-10-09
-4b8l,2013-07-10,2012-08-28
-2b82,2005-11-29,2005-10-06
-3b8r,2008-04-01,2007-11-01
-3b8i,2008-01-01,2007-11-01
-4b8s,2013-07-10,2012-08-30
-6b88,2018-10-10,2017-10-05
-4b83,2013-09-04,2012-08-24
-1b82,1999-02-16,1999-02-04
-3b8z,2007-12-11,2007-11-02
-4b87,2012-11-28,2012-08-24
-2b8w,2006-03-07,2005-10-10
-8b8f,2023-02-22,2022-10-04
-1b8n,1999-02-08,1999-02-02
-8b8w,2022-12-28,2022-10-05
-2b8o,2007-02-13,2005-10-08
-4b8p,2013-01-09,2012-08-29
-5b89,2017-06-14,2016-06-13
-8b8m,2022-11-16,2022-10-04
-6b8p,2018-03-14,2017-10-09
-7b84,2022-01-12,2020-12-12
-1b8v,1999-07-09,1999-02-02
-6b8b,2017-12-06,2017-10-06
-4b81,2013-09-04,2012-08-24
-4b8v,2013-07-17,2012-08-30
-5b87,2017-06-14,2016-06-13
-2b8q,2005-11-15,2005-10-10
-1b8c,1999-02-02,1999-01-29
-9b8z,2024-05-15,2024-04-01
-7b8d,2022-01-12,2020-12-12
-5b8f,2015-05-06,2015-04-20
-4b80,2013-09-04,2012-08-24
-6b82,2017-12-13,2017-10-05
-7b8k,2022-01-12,2020-12-12
-8b87,2023-10-18,2022-10-04
-4b86,2013-02-06,2012-08-24
-2b8v,2005-12-06,2005-10-10
-1b8s,1999-02-09,1999-02-02
-1b8o,1999-02-08,1999-02-02
-6b8m,2018-03-14,2017-10-09
-2b8l,2005-10-18,2005-10-07
-7b86,2022-01-12,2020-12-12
-8b8n,2023-02-01,2022-10-04
-7b8j,2022-01-12,2020-12-12
-6b8s,2017-11-22,2017-10-09
-7b8y,2022-01-12,2020-12-13
-1b8d,1999-02-18,1999-01-29
-6b8f,2018-05-02,2017-10-07
-7b8m,2022-01-12,2020-12-13
-6b89,2017-12-06,2017-10-05
-6b8g,2018-05-02,2017-10-07
-6b8a,2018-01-31,2017-10-05
-3b8g,2008-01-15,2007-11-01
-7b87,2022-01-12,2020-12-12
-1b8a,1999-02-02,1999-01-27
-9b8w,2024-05-15,2024-04-01
-4b84,2013-09-04,2012-08-24
-7b8w,2022-03-02,2020-12-13
-8b80,2022-10-19,2022-10-04
-4b8m,2013-07-10,2012-08-28
-3b82,2008-06-17,2007-10-31
-7b83,2021-01-13,2020-12-12
-7b8r,2021-10-20,2020-12-13
-8b8z,2022-12-28,2022-10-05
-6b8o,2018-06-27,2017-10-09
-5b8h,2015-05-13,2015-04-27
-3b8a,2008-02-26,2007-10-31
-8b8e,2023-05-17,2022-10-04
-8b8k,2022-11-16,2022-10-04
-6b8h,2018-01-17,2017-10-07
-5b82,2017-05-03,2016-06-12
-1b8j,1999-02-18,1999-02-01
-7b8l,2022-01-12,2020-12-13
-7b8n,2022-01-12,2020-12-13
-4b82,2013-09-04,2012-08-24
-4b8z,2013-02-06,2012-08-31
-6b8w,2017-10-25,2017-10-09
-6b8k,2018-10-10,2017-10-09
-5b8i,2015-05-20,2015-05-03
-9b8x,2024-05-15,2024-04-01
-7b85,2022-02-23,2020-12-12
-5b85,2016-08-10,2016-06-12
-7b8f,2022-01-12,2020-12-12
-2b8k,2006-06-20,2005-10-07
-8b8j,2022-11-16,2022-10-04
-3b8u,2008-07-08,2007-11-02
-7b89,2022-01-12,2020-12-12
-4b8u,2012-09-26,2012-08-30
-7b8c,2022-01-12,2020-12-12
-6b81,2018-10-03,2017-10-05
-7b81,2021-02-03,2020-12-12
-9b8y,2024-05-15,2024-04-01
-2b8g,2006-06-06,2005-10-06
-9b8e,2024-04-10,2024-03-29
-1b8q,1999-04-29,1999-02-01
-7b8s,2021-10-20,2020-12-13
-4b8b,2012-11-21,2012-08-26
-7b8g,2022-01-12,2020-12-12
-6b8q,2018-03-14,2017-10-09
-8b8q,2022-12-21,2022-10-04
-3b8q,2008-04-01,2007-11-01
-7b8z,2022-01-12,2020-12-13
-6b86,2018-07-04,2017-10-05
-6b8y,2018-02-07,2017-10-09
-1b86,1999-02-14,1999-02-08
-3b80,2007-12-18,2007-10-31
-8b8u,2023-02-01,2022-10-05
-7b8x,2022-01-12,2020-12-13
-1b8g,2000-01-26,1999-01-31
-2b8h,2006-09-05,2005-10-07
-8b8h,2023-04-05,2022-10-04
-6b8z,2018-06-20,2017-10-09
-3b8e,2007-12-18,2007-11-01
-7b80,2021-07-07,2020-12-12
-8b81,2022-10-19,2022-10-04
-4b8w,2012-11-21,2012-08-31
-2b8t,2005-12-20,2005-10-10
-1b8u,1999-07-09,1999-02-02
-5b84,2016-08-24,2016-06-12
-8b8x,2022-12-28,2022-10-05
-6u6i,2019-12-04,2019-08-29
-4u6a,2015-07-08,2014-07-28
-5u6q,2017-02-08,2016-12-08
-3u6j,2012-02-22,2011-10-12
-4u6s,2015-02-11,2014-07-29
-6u6l,2020-08-19,2019-08-30
-3u6f,2011-12-28,2011-10-12
-3u6p,2012-04-25,2011-10-12
-3u6m,2012-04-25,2011-10-12
-4u6p,2016-01-27,2014-07-29
-5u6c,2017-07-26,2016-12-07
-5u6x,2017-08-09,2016-12-09
-6u62,2019-10-30,2019-08-29
-3u6h,2012-02-22,2011-10-12
-4u69,2015-03-25,2014-07-28
-8u6e,2023-11-08,2023-09-13
-5u6t,2018-06-13,2016-12-08
-7u6v,2023-01-11,2022-03-06
-6u67,2020-03-04,2019-08-29
-5u6d,2017-03-15,2016-12-07
-5u6e,2017-03-22,2016-12-07
-6u6z,2020-09-02,2019-08-30
-3u6i,2012-02-22,2011-10-12
-1u6i,2005-02-01,2004-07-30
-6u61,2020-08-19,2019-08-28
-1u68,2004-10-19,2004-07-29
-4u6c,2015-03-25,2014-07-28
-3u6b,2012-02-08,2011-10-12
-7u69,2022-04-06,2022-03-03
-4u6i,2014-10-22,2014-07-29
-3u6o,2012-04-25,2011-10-12
-6u63,2020-03-04,2019-08-29
-6u6v,2020-01-01,2019-08-30
-6u6u,2020-04-22,2019-08-30
-5u6p,2017-01-25,2016-12-08
-7u6g,2022-08-31,2022-03-04
-1u6r,2005-08-02,2004-07-30
-7u63,2023-01-11,2022-03-03
-3u6e,2012-04-25,2011-10-12
-5u6a,2018-03-14,2016-12-07
-6u65,2020-03-04,2019-08-29
-8u6q,2023-11-08,2023-09-13
-3u69,2012-04-11,2011-10-12
-7u6u,2022-10-19,2022-03-06
-7u6l,2022-07-20,2022-03-04
-7u61,2023-01-11,2022-03-03
-6u6t,2020-08-12,2019-08-30
-8u6a,2023-11-08,2023-09-13
-7u6z,2022-04-13,2022-03-06
-7u66,2022-08-31,2022-03-03
-6u6b,2020-09-09,2019-08-29
-8u6p,2023-11-08,2023-09-13
-8u6s,2023-11-08,2023-09-13
-1u6k,2005-02-01,2004-07-30
-3u6a,2011-11-09,2011-10-12
-3u6t,2011-11-16,2011-10-13
-6u6k,2020-08-19,2019-08-30
-4u6d,2015-02-11,2014-07-28
-7u60,2022-08-17,2022-03-03
-4u60,2015-08-05,2014-07-26
-4u6j,2015-03-25,2014-07-29
-4u62,2015-08-05,2014-07-26
-1u6s,2005-03-22,2004-07-30
-6u6y,2020-09-02,2019-08-30
-7u68,2023-03-29,2022-03-03
-8u6i,2023-11-08,2023-09-13
-3u6c,2012-04-25,2011-10-12
-3u6k,2012-02-08,2011-10-12
-4u61,2015-08-05,2014-07-26
-5u6n,2017-05-03,2016-12-08
-4u68,2015-08-05,2014-07-28
-6u64,2020-03-04,2019-08-29
-4u6e,2015-03-25,2014-07-28
-3u6d,2012-04-25,2011-10-12
-6u6a,2019-10-30,2019-08-29
-5u6b,2017-07-26,2016-12-07
-5u6i,2017-03-15,2016-12-08
-3u6z,2011-12-07,2011-10-13
-3u6s,2012-04-25,2011-10-12
-3u6l,2012-04-25,2011-10-12
-5u6l,2017-08-02,2016-12-08
-5u66,2017-05-24,2016-12-07
-7u6e,2022-10-05,2022-03-03
-5u6g,2017-10-18,2016-12-08
-1u67,2004-09-07,2004-07-29
-8u6f,2023-11-08,2023-09-13
-5u61,2017-02-01,2016-12-07
-4u6w,2015-03-25,2014-07-30
-7u67,2022-08-31,2022-03-03
-1u6q,2004-10-19,2004-07-30
-6u66,2020-01-22,2019-08-29
-7u6j,2023-03-15,2022-03-04
-8u6m,2023-11-08,2023-09-13
-7u6a,2022-04-06,2022-03-03
-8u6b,2023-11-08,2023-09-13
-3u6w,2012-03-14,2011-10-13
-8u6j,2023-11-08,2023-09-13
-7u6i,2023-03-15,2022-03-04
-3u6n,2011-12-07,2011-10-12
-4u6y,2014-12-24,2014-07-30
-4u6f,2014-10-22,2014-07-28
-6u6w,2019-12-04,2019-08-30
-8u6r,2023-11-08,2023-09-13
-1u6j,2005-02-01,2004-07-30
-4u65,2014-08-13,2014-07-27
-3u67,2012-05-30,2011-10-12
-4u63,2015-03-25,2014-07-26
-5u60,2017-02-01,2016-12-07
-4u6b,2015-02-11,2014-07-28
-5u6j,2017-05-10,2016-12-08
-8u6n,2023-11-08,2023-09-13
-7u6h,2023-03-15,2022-03-04
-7u6y,2022-08-31,2022-03-06
-6u6f,2020-03-04,2019-08-29
-5u6v,2017-12-13,2016-12-09
-8u6h,2023-11-15,2023-09-13
-5u6m,2017-05-03,2016-12-08
-7u6m,2022-08-31,2022-03-04
-8u6c,2023-11-08,2023-09-13
-8u6g,2023-11-08,2023-09-13
-6u60,2019-09-11,2019-08-28
-6u6d,2020-03-25,2019-08-29
-1u6g,2004-12-14,2004-07-29
-8u6t,2023-11-08,2023-09-13
-7u64,2023-01-11,2022-03-03
-3u6q,2012-04-25,2011-10-12
-8u66,2023-11-22,2023-09-13
-4u67,2015-08-05,2014-07-28
-5u63,2016-12-21,2016-12-07
-4u6q,2015-02-11,2014-07-29
-8u6k,2023-11-08,2023-09-13
-4u6r,2014-10-08,2014-07-29
-1u6p,2004-11-02,2004-07-30
-5u6w,2018-06-13,2016-12-09
-7u6r,2022-11-30,2022-03-05
-7u6k,2023-03-29,2022-03-04
-7u62,2023-01-11,2022-03-03
-3u6y,2012-02-22,2011-10-13
-4u6x,2014-12-24,2014-07-30
-8u6l,2023-11-08,2023-09-13
-5u6z,2017-01-11,2016-12-09
-5u6r,2017-04-26,2016-12-08
-5u6h,2017-08-02,2016-12-08
-8u69,2023-11-08,2023-09-13
-5u69,2017-03-15,2016-12-07
-8u6d,2023-11-08,2023-09-13
-6u6x,2020-09-02,2019-08-30
-7u6b,2022-04-06,2022-03-03
-5u6s,2017-05-03,2016-12-08
-1u65,2005-07-19,2004-07-29
-5u6u,2018-06-13,2016-12-08
-6u6c,2020-09-02,2019-08-29
-8u6o,2023-11-08,2023-09-13
-5u62,2017-01-11,2016-12-07
-5u6k,2017-10-04,2016-12-08
-4u6z,2015-04-15,2014-07-30
-1igv,2001-04-25,2001-04-18
-4igh,2013-08-21,2012-12-17
-8ig4,2024-03-06,2023-02-20
-4ig1,2013-02-27,2012-12-15
-3igd,2009-10-06,2009-07-27
-8igf,2024-02-28,2023-02-20
-3igs,2009-08-04,2009-07-28
-8iga,2024-03-06,2023-02-20
-5igb,2016-03-09,2016-02-27
-8igb,2024-03-06,2023-02-20
-4ig8,2013-01-16,2012-12-16
-5igo,2016-04-20,2016-02-28
-1igr,1999-09-27,1998-09-28
-8ig8,2024-03-06,2023-02-20
-8ign,2023-04-05,2023-02-21
-6ig4,2019-07-10,2018-09-23
-5ig6,2016-06-22,2016-02-27
-4igq,2013-04-03,2012-12-17
-1igy,1998-04-15,1997-10-09
-2igx,2006-11-28,2006-09-25
-3igb,2009-11-03,2009-07-27
-2igq,2006-10-24,2006-09-23
-2igb,2007-09-25,2006-09-22
-5igf,2016-03-09,2016-02-27
-8igr,2023-05-17,2023-02-21
-3igj,2009-08-04,2009-07-27
-2igt,2006-10-24,2006-09-25
-8igx,2023-10-18,2023-02-21
-2igm,2006-10-10,2006-09-22
-3ig5,2009-09-01,2009-07-27
-4igl,2013-08-07,2012-12-17
-4igk,2013-10-30,2012-12-17
-8ig6,2024-03-06,2023-02-20
-3igo,2009-08-11,2009-07-28
-3ign,2009-08-11,2009-07-28
-4igp,2013-04-03,2012-12-17
-5igc,2016-03-09,2016-02-27
-2igo,2006-10-10,2006-09-22
-6ig1,2018-11-28,2018-09-21
-2ig3,2006-10-10,2006-09-22
-6igj,2019-12-25,2018-09-25
-2igv,2007-08-14,2006-09-25
-3igr,2009-09-01,2009-07-28
-4ig0,2013-02-06,2012-12-15
-4ign,2014-05-07,2012-12-17
-5igw,2017-04-26,2016-02-28
-2ig9,2007-04-24,2006-09-22
-3igl,2010-03-31,2009-07-28
-4igm,2014-05-07,2012-12-17
-2igf,1992-04-15,1991-03-21
-4igu,2013-12-18,2012-12-18
-5igs,2017-04-26,2016-02-28
-8ig1,2023-08-16,2023-02-20
-2ign,2006-10-10,2006-09-22
-6ig8,2019-08-07,2018-09-25
-5igg,2016-03-09,2016-02-27
-1igt,1997-07-07,1996-10-25
-6igl,2018-11-21,2018-09-25
-3ig2,2009-09-01,2009-07-27
-8igt,2023-09-13,2023-02-21
-1igx,2001-12-12,2001-04-18
-3igp,2010-03-09,2009-07-28
-2igy,2006-11-28,2006-09-25
-4igr,2013-03-06,2012-12-18
-8igi,2023-12-27,2023-02-20
-5ige,2016-03-09,2016-02-27
-1ig3,2001-04-25,2001-04-16
-5ign,2016-03-30,2016-02-28
-5igq,2016-04-20,2016-02-28
-8igy,2023-10-18,2023-02-21
-4igf,2013-11-06,2012-12-17
-5igy,2017-04-26,2016-02-28
-3iga,2009-11-17,2009-07-27
-3ig4,2009-08-04,2009-07-27
-3igg,2009-09-08,2009-07-27
-6ig6,2018-11-07,2018-09-25
-1ig1,2002-04-01,2001-04-16
-8igv,2023-07-12,2023-02-21
-5igj,2017-04-26,2016-02-28
-6ig7,2018-11-07,2018-09-25
-8ig0,2023-03-22,2023-02-20
-5igm,2016-10-19,2016-02-28
-2igk,2006-10-10,2006-09-22
-4ig2,2013-09-18,2012-12-15
-5ig2,2016-06-15,2016-02-26
-6igz,2019-02-13,2018-09-27
-4igb,2013-06-05,2012-12-17
-3igc,2010-03-02,2009-07-27
-8igq,2023-10-04,2023-02-21
-3ig1,2010-01-26,2009-07-27
-4igt,2013-03-06,2012-12-18
-4igo,2013-04-03,2012-12-17
-1ig9,2001-06-11,2001-04-17
-3igy,2009-10-27,2009-07-29
-1igf,1992-04-15,1991-03-21
-2ig6,2006-10-10,2006-09-22
-6igs,2019-10-02,2018-09-25
-3ig6,2009-10-13,2009-07-27
-4ig3,2013-02-06,2012-12-15
-3igm,2009-11-10,2009-07-28
-8igw,2023-07-12,2023-02-21
-5igr,2017-04-26,2016-02-28
-1igj,1993-04-15,1993-02-19
-2iga,2007-04-24,2006-09-22
-2ig0,2007-01-02,2006-09-22
-2igc,2007-06-12,2006-09-22
-4iga,2013-04-24,2012-12-17
-6ig0,2018-12-12,2018-09-21
-3igu,2009-10-20,2009-07-28
-4ig9,2013-11-06,2012-12-16
-1ig5,2001-04-25,2001-04-17
-4ig6,2012-12-26,2012-12-16
-8ig7,2024-03-06,2023-02-20
-1igz,2001-12-12,2001-04-18
-8igs,2023-05-17,2023-02-21
-3ig7,2009-09-08,2009-07-27
-4ig7,2013-05-29,2012-12-16
-6ig2,2019-07-10,2018-09-23
-5igk,2016-10-19,2016-02-28
-5igl,2016-10-19,2016-02-28
-4igs,2014-03-19,2012-12-18
-5igx,2016-04-06,2016-02-28
-3igz,2009-10-27,2009-07-29
-3igq,2009-12-08,2009-07-28
-2igw,2007-08-14,2006-09-25
-5igd,2016-03-09,2016-02-27
-1ig0,2001-06-20,2001-04-16
-2igi,2007-10-02,2006-09-22
-3igk,2010-03-31,2009-07-28
-3igv,2009-12-08,2009-07-28
-5ig7,2017-03-15,2016-02-27
-8ig9,2024-03-06,2023-02-20
-1igb,1996-08-01,1996-02-27
-3ig8,2009-09-01,2009-07-27
-8ig5,2024-03-06,2023-02-20
-5igv,2017-04-26,2016-02-28
-1igw,2001-09-05,2001-04-18
-5igi,2017-04-26,2016-02-28
-4ige,2013-11-06,2012-12-17
-7u08,2023-02-22,2022-02-17
-8u0o,2024-03-13,2023-08-29
-4u06,2015-06-03,2014-07-11
-5u0v,2017-12-06,2016-11-27
-5u0w,2017-12-06,2016-11-27
-1u0g,2004-11-02,2004-07-13
-4u0n,2014-09-17,2014-07-12
-4u0d,2014-11-12,2014-07-11
-5u08,2017-02-08,2016-11-23
-7u00,2023-03-15,2022-02-17
-6u0r,2020-08-19,2019-08-14
-4u03,2014-09-17,2014-07-11
-8u0k,2024-02-21,2023-08-29
-1u00,2004-10-05,2004-07-12
-5u0e,2017-08-30,2016-11-23
-8u0t,2023-12-06,2023-08-29
-6u0u,2019-09-25,2019-08-14
-3u0d,2011-10-12,2011-09-28
-6u0p,2020-03-11,2019-08-14
-5u0y,2017-12-06,2016-11-27
-4u0g,2014-10-08,2014-07-11
-7u0l,2022-08-24,2022-02-18
-6u03,2019-11-06,2019-08-13
-1u0h,2004-12-14,2004-07-13
-5u00,2017-02-22,2016-11-22
-5u0g,2017-08-30,2016-11-23
-7u0x,2023-03-01,2022-02-19
-5u0c,2017-03-29,2016-11-23
-1u0x,2004-07-20,2004-07-14
-4u0f,2014-11-12,2014-07-11
-4u0m,2014-09-17,2014-07-12
-6u0s,2020-03-11,2019-08-14
-3u0z,2011-10-26,2011-09-29
-8u0n,2024-02-21,2023-08-29
-4u09,2015-06-03,2014-07-11
-1u05,2004-08-17,2004-07-12
-5u06,2017-11-15,2016-11-22
-8u0p,2024-03-13,2023-08-29
-1u0w,2004-10-12,2004-07-14
-1u02,2004-07-20,2004-07-12
-5u0d,2017-08-30,2016-11-23
-4u0k,2014-07-30,2014-07-11
-5u0l,2017-04-26,2016-11-24
-7u0v,2023-02-22,2022-02-19
-3u0a,2011-10-05,2011-09-28
-5u0m,2017-04-26,2016-11-24
-4u0s,2014-12-10,2014-07-14
-6u0n,2019-12-11,2019-08-14
-1u0j,2004-08-24,2004-07-13
-8u01,2023-09-27,2023-08-28
-8u0q,2024-01-03,2023-08-29
-7u02,2022-06-01,2022-02-17
-5u03,2017-04-26,2016-11-22
-6u0x,2019-08-28,2019-08-15
-6u05,2019-11-06,2019-08-13
-6u0d,2020-08-19,2019-08-14
-3u06,2012-03-07,2011-09-28
-4u0z,2014-12-10,2014-07-14
-5u0z,2017-12-06,2016-11-27
-7u0e,2022-08-03,2022-02-18
-1u0c,2004-11-02,2004-07-13
-6u01,2019-12-04,2019-08-13
-6u0w,2019-08-28,2019-08-15
-6u09,2019-10-23,2019-08-13
-6u0q,2021-01-27,2019-08-14
-3u0f,2011-10-12,2011-09-28
-6u07,2020-04-15,2019-08-13
-5u0b,2017-03-29,2016-11-23
-4u0c,2014-11-12,2014-07-11
-7u0u,2022-08-03,2022-02-18
-7u09,2022-08-03,2022-02-17
-7u0t,2022-08-03,2022-02-18
-5u0j,2017-05-24,2016-11-24
-6u08,2020-07-15,2019-08-13
-3u0o,2012-03-14,2011-09-28
-4u0w,2015-01-14,2014-07-14
-3u0b,2011-10-05,2011-09-28
-7u0a,2022-08-03,2022-02-17
-4u0i,2014-10-08,2014-07-11
-6u0z,2019-09-11,2019-08-15
-4u01,2015-07-29,2014-07-11
-8u0l,2024-02-21,2023-08-29
-4u0o,2014-08-20,2014-07-13
-1u0f,2004-11-02,2004-07-13
-4u0v,2015-01-14,2014-07-14
-7u0p,2022-08-10,2022-02-18
-8u0m,2024-02-21,2023-08-29
-1u0z,2005-07-05,2004-07-14
-5u04,2017-02-22,2016-11-22
-4u0x,2014-11-19,2014-07-14
-7u0m,2022-10-05,2022-02-18
-8u0v,2023-12-13,2023-08-29
-5u0t,2017-11-01,2016-11-27
-4u00,2015-05-13,2014-07-11
-3u0p,2012-04-25,2011-09-28
-6u0y,2019-09-11,2019-08-15
-8u00,2023-09-27,2023-08-28
-7u0h,2022-12-14,2022-02-18
-6u0m,2020-03-25,2019-08-14
-6u0j,2020-07-22,2019-08-14
-1u08,2004-07-27,2004-07-13
-7u0n,2022-03-30,2022-02-18
-7u0r,2023-06-14,2022-02-18
-4u0e,2014-11-12,2014-07-11
-6u02,2019-12-04,2019-08-13
-3u0y,2012-10-24,2011-09-29
-1u0l,2004-09-07,2004-07-13
-6u0l,2019-12-11,2019-08-14
-7u0d,2022-03-30,2022-02-17
-4u07,2014-12-10,2014-07-11
-7u0q,2023-03-01,2022-02-18
-3u0e,2011-10-26,2011-09-28
-6u0h,2019-09-25,2019-08-14
-5u09,2016-12-07,2016-11-23
-4u08,2015-06-03,2014-07-11
-6u0t,2019-09-25,2019-08-14
-3u0s,2012-02-01,2011-09-29
-4u0j,2014-07-30,2014-07-11
-5u0n,2017-11-01,2016-11-25
-6u04,2019-11-27,2019-08-13
-3u0k,2012-10-03,2011-09-28
-1u0a,2005-09-06,2004-07-13
-5u0i,2017-05-24,2016-11-24
-7u0s,2022-07-27,2022-02-18
-4u0u,2014-12-10,2014-07-14
-6u0k,2020-03-11,2019-08-14
-4u0p,2014-08-20,2014-07-13
-5u0f,2017-08-30,2016-11-23
-3u0x,2012-10-24,2011-09-29
-3u04,2011-10-12,2011-09-28
-7u0o,2023-02-22,2022-02-18
-6u06,2019-10-16,2019-08-13
-1u0b,2004-11-23,2004-07-13
-5u9m,2017-05-31,2016-12-16
-7u9x,2022-08-03,2022-03-11
-5u93,2017-12-20,2016-12-15
-6u9b,2020-02-19,2019-09-07
-1u9m,2005-02-01,2004-08-10
-5u9c,2016-12-28,2016-12-15
-3u9a,2012-10-24,2011-10-18
-6u9j,2020-09-09,2019-09-09
-1u9l,2004-08-31,2004-08-10
-6u9v,2019-10-23,2019-09-09
-6u9m,2020-07-01,2019-09-09
-5u9j,2017-07-26,2016-12-16
-5u97,2017-05-31,2016-12-15
-4u9w,2015-01-28,2014-08-06
-7u9k,2023-03-15,2022-03-10
-1u95,2004-10-05,2004-08-09
-7u9n,2023-02-01,2022-03-11
-7u99,2022-11-23,2022-03-10
-6u9r,2020-07-01,2019-09-09
-5u94,2017-12-20,2016-12-15
-6u90,2020-06-10,2019-09-06
-8u98,2023-09-27,2023-09-18
-8u9g,2024-01-10,2023-09-19
-5u99,2017-09-20,2016-12-15
-6u9y,2020-11-04,2019-09-09
-8u96,2023-09-27,2023-09-18
-7u9s,2022-06-08,2022-03-11
-8u99,2023-09-27,2023-09-18
-4u9n,2014-12-03,2014-08-06
-3u92,2012-09-26,2011-10-17
-7u9o,2022-11-23,2022-03-11
-4u95,2014-10-15,2014-08-05
-6u9u,2019-11-06,2019-09-09
-6u98,2020-02-19,2019-09-06
-1u96,2004-10-05,2004-08-09
-7u9i,2023-01-18,2022-03-10
-6u9h,2020-07-15,2019-09-08
-3u9j,2012-02-22,2011-10-19
-3u99,2012-10-31,2011-10-18
-3u9g,2012-03-14,2011-10-18
-3u91,2013-04-24,2011-10-17
-5u98,2017-07-19,2016-12-15
-6u9d,2020-07-15,2019-09-08
-5u9e,2017-12-20,2016-12-16
-7u98,2022-11-23,2022-03-10
-3u9m,2012-02-22,2011-10-19
-4u9u,2014-12-03,2014-08-06
-6u9a,2020-02-19,2019-09-07
-3u9z,2012-01-25,2011-10-20
-4u9b,2014-10-01,2014-08-05
-1u9i,2005-04-19,2004-08-09
-4u98,2015-02-11,2014-08-05
-6u9z,2020-11-04,2019-09-09
-4u9l,2014-12-03,2014-08-06
-3u9e,2011-11-16,2011-10-18
-7u9q,2022-08-03,2022-03-11
-7u9b,2023-03-15,2022-03-10
-4u9k,2014-10-01,2014-08-06
-6u9k,2020-07-01,2019-09-09
-3u9s,2011-12-14,2011-10-19
-4u9h,2015-01-21,2014-08-06
-3u9w,2012-10-24,2011-10-20
-4u9j,2014-10-01,2014-08-06
-8u97,2023-09-27,2023-09-18
-4u9i,2015-01-21,2014-08-06
-3u94,2012-09-26,2011-10-17
-4u99,2014-10-01,2014-08-05
-4u93,2014-11-19,2014-08-05
-6u9w,2019-10-23,2019-09-09
-6u9q,2020-09-16,2019-09-09
-5u9h,2017-02-08,2016-12-16
-3u90,2012-04-25,2011-10-17
-3u9c,2012-05-30,2011-10-18
-3u93,2012-09-26,2011-10-17
-5u9d,2017-01-18,2016-12-16
-4u9a,2014-09-24,2014-08-05
-8u94,2023-09-27,2023-09-18
-8u9f,2024-05-29,2023-09-19
-1u9w,2005-08-11,2004-08-11
-3u9d,2012-01-25,2011-10-18
-1u9v,2005-08-11,2004-08-11
-4u90,2014-12-10,2014-08-05
-1u91,2004-10-05,2004-08-09
-5u9t,2017-04-26,2016-12-18
-5u9g,2017-03-22,2016-12-16
-3u98,2012-10-24,2011-10-18
-5u9i,2017-07-26,2016-12-16
-8u93,2023-09-27,2023-09-18
-7u9y,2022-04-27,2022-03-11
-5u9z,2017-12-20,2016-12-18
-3u9q,2011-11-09,2011-10-19
-6u9o,2020-03-25,2019-09-09
-7u9t,2022-08-03,2022-03-11
-6u9x,2019-11-06,2019-09-09
-8u9b,2023-09-27,2023-09-18
-6u9l,2020-09-16,2019-09-09
-5u9n,2017-01-18,2016-12-16
-7u92,2023-09-06,2022-03-09
-5u9w,2017-04-12,2016-12-18
-1u94,2004-09-21,2004-08-09
-7u9z,2022-08-03,2022-03-11
-5u90,2017-05-31,2016-12-15
-1u9e,2005-03-01,2004-08-09
-6u9t,2020-11-04,2019-09-09
-6u99,2020-02-19,2019-09-06
-5u9b,2017-08-02,2016-12-15
-5u9u,2017-04-26,2016-12-18
-7u9p,2022-11-23,2022-03-11
-7u9a,2022-11-23,2022-03-10
-1u9z,2005-08-23,2004-08-11
-1u90,2004-11-23,2004-08-09
-8u92,2023-09-27,2023-09-18
-6u9c,2019-09-18,2019-09-07
-4u9r,2015-07-08,2014-08-06
-1u92,2004-10-05,2004-08-09
-7u91,2022-12-21,2022-03-09
-1u9u,2005-02-01,2004-08-11
-5u9l,2017-12-20,2016-12-16
-4u9e,2015-01-21,2014-08-06
-4u9d,2015-01-14,2014-08-05
-4u9z,2015-08-12,2014-08-07
-7u9g,2022-07-20,2022-03-10
-4u94,2015-02-11,2014-08-05
-5u9p,2017-01-18,2016-12-17
-6u97,2020-02-19,2019-09-06
-4u9g,2014-10-01,2014-08-06
-4u97,2014-09-24,2014-08-05
-6u9n,2020-07-01,2019-09-09
-4u9s,2014-12-03,2014-08-06
-1u93,2004-10-05,2004-08-09
-3u95,2012-09-26,2011-10-17
-6u96,2020-05-13,2019-09-06
-6u91,2020-06-10,2019-09-06
-1u9q,2005-03-29,2004-08-10
-8u9a,2023-09-27,2023-09-18
-8u90,2023-09-27,2023-09-18
-3u9h,2011-11-02,2011-10-19
-7u9f,2022-08-17,2022-03-10
-5u9f,2017-03-22,2016-12-16
-7u9r,2022-08-03,2022-03-11
-1u9x,2005-08-11,2004-08-11
-7u9u,2022-06-08,2022-03-11
-4u9v,2015-01-28,2014-08-06
-5u95,2017-03-22,2016-12-15
-4u91,2014-12-10,2014-08-05
-6u9p,2020-11-04,2019-09-09
-7u9c,2022-03-23,2022-03-10
-3u9x,2012-05-09,2011-10-20
-3u9y,2012-01-25,2011-10-20
-1u9k,2004-12-14,2004-08-09
-3u9n,2012-01-25,2011-10-19
-3u9f,2012-02-15,2011-10-18
-3u96,2012-08-29,2011-10-17
-5u92,2017-09-06,2016-12-15
-7u9v,2022-08-17,2022-03-11
-4u9y,2015-08-12,2014-08-07
-1rb6,2004-01-13,2003-11-01
-3rb0,2011-06-15,2011-03-28
-3rbc,2012-04-04,2011-03-29
-5rbr,2020-06-03,2020-03-24
-7rbe,2022-03-09,2021-07-06
-4rbl,2015-03-18,2014-09-12
-6rbv,2020-02-19,2019-04-11
-6rbt,2020-02-19,2019-04-11
-3rbv,2011-06-08,2011-03-30
-6rbs,2020-02-19,2019-04-11
-2rbe,2008-01-15,2007-09-18
-5rb6,2020-04-22,2020-03-16
-7rb3,2023-01-11,2021-07-05
-3rbq,2011-06-08,2011-03-29
-5rb5,2020-04-22,2020-03-16
-5rb3,2020-04-22,2020-03-16
-3rb7,2011-11-02,2011-03-28
-7rbi,2022-03-09,2021-07-06
-4rb2,2015-07-15,2014-09-12
-3rbu,2012-01-04,2011-03-30
-1rb8,2004-04-13,2003-11-03
-7rb7,2021-09-22,2021-07-05
-8rbi,2024-01-17,2023-12-04
-3rb8,2012-07-04,2011-03-28
-5rbt,2020-06-03,2020-03-24
-5rb4,2020-04-22,2020-03-16
-3rbf,2011-10-19,2011-03-29
-2rbo,2008-03-18,2007-09-19
-2rbv,2008-03-18,2007-09-19
-7rbn,2022-03-09,2021-07-06
-5rb0,2020-04-22,2020-03-16
-5rbp,2020-06-03,2020-03-24
-5rb2,2020-04-22,2020-03-16
-7rb9,2021-07-28,2021-07-05
-2rb0,2008-03-18,2007-09-17
-6rbq,2020-02-19,2019-04-11
-7rbt,2022-04-13,2021-07-06
-1rby,2005-06-14,2003-11-03
-1rb3,1997-03-12,1996-11-26
-2rb1,2008-06-03,2007-09-17
-7rbf,2022-03-09,2021-07-06
-8rbz,2024-02-07,2023-12-05
-5rbu,2020-06-03,2020-03-24
-7rb6,2021-09-22,2021-07-05
-6rb5,2020-05-13,2019-04-09
-6rb0,2019-12-25,2019-04-08
-3rb5,2011-11-02,2011-03-28
-4rbm,2014-10-08,2014-09-12
-1rbj,1995-12-07,1995-05-22
-2rbm,2008-10-07,2007-09-19
-6rb1,2020-04-08,2019-04-08
-8rbn,2024-01-17,2023-12-04
-7rbh,2022-03-09,2021-07-06
-2rbs,2008-03-18,2007-09-19
-6rbr,2020-02-19,2019-04-11
-3rbd,2011-06-15,2011-03-29
-2rbw,2008-03-18,2007-09-19
-5rbq,2020-06-03,2020-03-24
-3rbz,2011-10-12,2011-03-30
-6rbl,2019-08-21,2019-04-10
-5rbw,2020-06-03,2020-03-24
-4rb4,2014-11-05,2014-09-12
-8rbo,2024-04-24,2023-12-04
-7rbx,2021-10-06,2021-07-06
-2rb2,2008-03-18,2007-09-17
-5rb7,2020-04-22,2020-03-16
-2rbn,2008-03-18,2007-09-19
-1rbz,2005-06-14,2003-11-03
-4rbs,2014-11-26,2014-09-12
-6rbp,2020-02-19,2019-04-11
-6rbj,2020-05-13,2019-04-10
-7rbv,2022-05-04,2021-07-06
-7rbs,2021-09-29,2021-07-06
-6rby,2020-02-19,2019-04-11
-1rb7,2004-03-02,2003-11-02
-7rbg,2022-03-09,2021-07-06
-7rbo,2022-03-09,2021-07-06
-3rb6,2011-06-15,2011-03-28
-5rbv,2020-06-03,2020-03-24
-6rb6,2019-07-24,2019-04-09
-6rbf,2019-08-14,2019-04-10
-1rb2,1997-03-12,1996-11-26
-1rb9,1999-02-16,1997-12-21
-1rbq,2005-06-14,2003-11-03
-1rbp,1991-07-15,1990-04-02
-8rbv,2024-05-15,2023-12-05
-1rbm,2005-06-14,2003-11-03
-2rbz,2008-03-18,2007-09-19
-3rbh,2011-07-27,2011-03-29
-3rbm,2012-02-29,2011-03-29
-5rb1,2020-04-22,2020-03-16
-6rbx,2020-02-19,2019-04-11
-6rbz,2020-02-19,2019-04-11
-5rbx,2020-06-03,2020-03-24
-6rb3,2019-07-03,2019-04-09
-2rby,2008-03-18,2007-09-19
-2rbp,2008-03-18,2007-09-19
-4rb3,2015-07-15,2014-09-12
-7rbz,2021-09-29,2021-07-06
-8rb6,2024-03-06,2023-12-03
-5rbs,2020-06-03,2020-03-24
-7rbm,2022-03-09,2021-07-06
-1rb0,2004-11-09,2003-10-31
-2rbr,2008-03-18,2007-09-19
-2rb5,2008-04-22,2007-09-18
-1rbn,1994-12-20,1994-03-29
-6rbm,2019-08-21,2019-04-11
-7rbq,2021-08-11,2021-07-06
-3rb4,2011-06-15,2011-03-28
-1rbo,1997-03-12,1996-10-31
-3rbx,2011-10-12,2011-03-30
-5rby,2020-06-03,2020-03-24
-6rbi,2020-05-13,2019-04-10
-2rbk,2008-04-22,2007-09-19
-6rbc,2020-05-13,2019-04-10
-6rb2,2020-05-06,2019-04-09
-7rb1,2021-12-01,2021-07-05
-3rb3,2011-06-15,2011-03-28
-3rba,2012-04-04,2011-03-29
-6rb4,2019-09-11,2019-04-09
-2rbu,2008-03-18,2007-09-19
-2rbq,2008-03-18,2007-09-19
-6rbw,2020-02-19,2019-04-11
-5rbz,2020-06-03,2020-03-24
-6rbo,2020-02-19,2019-04-11
-4rbp,2014-11-26,2014-09-12
-5rbo,2020-06-03,2020-03-24
-7rb8,2021-07-28,2021-07-05
-7rbj,2022-03-09,2021-07-06
-6rb7,2019-09-25,2019-04-09
-2rbx,2008-04-01,2007-09-19
-8rbu,2024-05-15,2023-12-05
-2rbt,2008-04-01,2007-09-19
-7rb5,2021-09-22,2021-07-05
-7rby,2022-03-23,2021-07-06
-3rbe,2011-06-15,2011-03-29
-2rb4,2007-10-02,2007-09-18
-7rbl,2022-03-09,2021-07-06
-7rbk,2022-03-09,2021-07-06
-1rbl,1994-06-22,1993-05-12
-8rbx,2024-02-07,2023-12-05
-4rb1,2015-07-15,2014-09-12
-7rbw,2021-11-24,2021-07-06
-7rbr,2021-09-29,2021-07-06
-7rbu,2022-05-04,2021-07-06
-6rbu,2020-02-19,2019-04-11
-2k78,2008-08-19,2008-08-06
-8k7c,2023-10-04,2023-07-26
-8k7e,2024-04-10,2023-07-26
-4k7x,2013-05-01,2013-04-17
-4k7v,2013-10-09,2013-04-17
-4k7m,2013-11-27,2013-04-17
-3k71,2010-01-12,2009-10-11
-4k78,2014-01-22,2013-04-16
-4k75,2014-01-22,2013-04-16
-4k7w,2013-05-08,2013-04-17
-5k78,2016-12-07,2016-05-25
-1k7e,2002-07-10,2001-10-19
-1k7d,2003-09-02,2001-10-19
-5k70,2016-09-28,2016-05-25
-7k71,2021-01-06,2020-09-21
-5k75,2017-12-06,2016-05-25
-1k7t,2002-04-03,2001-10-22
-5k7s,2017-04-05,2016-05-26
-5k7o,2017-04-05,2016-05-26
-1k7v,2002-04-03,2001-10-22
-3k7s,2010-10-27,2009-10-13
-2k7r,2009-03-03,2008-08-19
-4k7g,2013-05-01,2013-04-17
-4k7o,2014-04-23,2013-04-17
-6k7c,2019-09-04,2019-06-07
-8k7i,2024-04-10,2023-07-26
-6k7t,2019-11-06,2019-06-08
-1k7f,2002-07-10,2001-10-19
-1k7x,2002-06-19,2001-10-22
-1k7g,2002-10-19,2001-10-19
-4k72,2014-01-22,2013-04-16
-4k7s,2013-05-08,2013-04-17
-6k7x,2020-09-09,2019-06-10
-8k7j,2024-04-10,2023-07-26
-7k7q,2021-08-04,2020-09-23
-7k7m,2021-09-22,2020-09-23
-3k7f,2009-12-01,2009-10-13
-4k7y,2013-10-09,2013-04-17
-2k7o,2008-11-18,2008-08-17
-6k73,2020-06-10,2019-06-05
-5k7x,2016-12-07,2016-05-27
-6k7l,2019-08-28,2019-06-07
-5k77,2016-12-07,2016-05-25
-6k7h,2019-08-28,2019-06-07
-8k7l,2024-04-10,2023-07-26
-3k7w,2009-11-03,2009-10-13
-5k7h,2016-12-21,2016-05-26
-1k7l,2001-12-05,2001-10-19
-7k73,2020-10-28,2020-09-22
-1k7y,2001-12-21,2001-10-22
-3k7m,2010-01-19,2009-10-13
-6k7k,2019-08-28,2019-06-07
-4k76,2014-02-26,2013-04-16
-2k74,2008-10-07,2008-08-01
-6k7g,2019-08-28,2019-06-07
-4k7a,2014-04-16,2013-04-16
-1k77,2002-03-13,2001-10-18
-8k73,2023-12-13,2023-07-26
-3k7n,2010-03-02,2009-10-13
-3k7r,2009-11-24,2009-10-13
-1k7i,2002-10-19,2001-10-19
-7k7o,2021-08-04,2020-09-23
-4k7u,2013-05-08,2013-04-17
-1k7w,2002-03-06,2001-10-22
-6k7j,2019-08-28,2019-06-07
-7k7t,2020-11-11,2020-09-24
-5k7a,2017-06-07,2016-05-25
-2k7b,2008-11-25,2008-08-08
-8k72,2023-12-13,2023-07-26
-1k70,2002-02-06,2001-10-17
-1k7s,2002-04-17,2001-10-21
-1k7q,2002-10-20,2001-10-20
-1k73,2003-07-22,2001-10-18
-5k7t,2017-04-05,2016-05-26
-3k70,2009-11-10,2009-10-11
-3k7i,2011-01-26,2009-10-13
-4k7n,2014-04-23,2013-04-17
-8k71,2023-12-13,2023-07-26
-8k7b,2023-10-04,2023-07-26
-3k7j,2011-01-26,2009-10-13
-6k77,2020-06-10,2019-06-06
-7k7z,2020-10-28,2020-09-24
-3k7y,2010-10-13,2009-10-13
-3k7t,2010-01-19,2009-10-13
-5k7r,2017-04-05,2016-05-26
-8k7d,2024-04-10,2023-07-26
-1k7h,2002-07-31,2001-10-19
-5k7g,2017-12-06,2016-05-26
-8k7f,2024-04-10,2023-07-26
-5k7n,2017-04-05,2016-05-26
-4k7r,2013-10-16,2013-04-17
-4k73,2013-06-12,2013-04-16
-1k74,2001-12-05,2001-10-18
-2k7d,2008-11-25,2008-08-08
-1k7c,2001-12-28,2001-10-19
-5k7k,2017-06-07,2016-05-26
-3k7q,2010-01-19,2009-10-13
-6k7i,2019-08-28,2019-06-07
-8k7a,2023-10-11,2023-07-26
-4k79,2013-06-26,2013-04-16
-8k7p,2024-06-05,2023-07-27
-2k70,2008-09-09,2008-07-29
-7k7l,2020-10-28,2020-09-23
-5k7w,2016-07-06,2016-05-26
-8k7g,2024-04-10,2023-07-26
-6k7r,2020-06-10,2019-06-08
-8k77,2024-05-01,2023-07-26
-5k73,2016-12-07,2016-05-25
-5k7i,2017-12-06,2016-05-26
-4k70,2014-03-19,2013-04-16
-5k76,2017-12-06,2016-05-25
-6k7f,2019-09-18,2019-06-07
-8k7k,2024-04-10,2023-07-26
-7k7g,2021-03-31,2020-09-22
-1k7u,2002-04-03,2001-10-22
-6k7m,2019-08-28,2019-06-07
-7k75,2021-06-23,2020-09-22
-4k7d,2013-05-15,2013-04-17
-8k7x,2024-02-21,2023-07-27
-3k7g,2011-01-26,2009-10-13
-3k7k,2010-01-26,2009-10-13
-3k7h,2011-01-26,2009-10-13
-6k7n,2019-08-28,2019-06-07
-4k7z,2013-05-15,2013-04-17
-4k7q,2013-07-03,2013-04-17
-6k74,2020-06-10,2019-06-06
-5k7j,2016-08-03,2016-05-26
-5k7l,2016-08-17,2016-05-26
-5k7u,2016-07-06,2016-05-26
-6k7s,2020-06-10,2019-06-08
-5k7z,2016-12-28,2016-05-27
-4k74,2013-07-17,2013-04-16
-3k7v,2009-11-03,2009-10-13
-4k7f,2013-06-05,2013-04-17
-3k7a,2009-11-24,2009-10-12
-7k72,2020-12-02,2020-09-22
-8k7h,2024-04-10,2023-07-26
-3k72,2010-01-12,2009-10-11
-6k7y,2020-09-09,2019-06-10
-3k73,2010-08-18,2009-10-12
-7k77,2021-09-22,2020-09-22
-5k72,2017-12-06,2016-05-25
-8k7q,2024-06-05,2023-07-27
-4k7t,2013-08-14,2013-04-17
-8k7y,2024-02-21,2023-07-27
-6k76,2020-06-10,2019-06-06
-3k7l,2010-03-02,2009-10-13
-7k7j,2021-04-07,2020-09-22
-7k76,2021-06-23,2020-09-22
-5k74,2017-05-31,2016-05-25
-4k77,2013-10-02,2013-04-16
-1k72,2003-07-15,2001-10-18
-7axl,2021-01-13,2020-11-09
-2ax6,2005-09-20,2005-09-03
-6axp,2017-12-13,2017-09-07
-5axs,2015-11-18,2015-08-01
-3axd,2012-02-15,2011-04-03
-1axd,1998-10-28,1997-10-15
-7axa,2021-01-13,2020-11-09
-1axe,1998-04-15,1997-10-15
-6ax0,2018-09-12,2017-09-06
-2axi,2006-03-21,2005-09-05
-3axh,2011-10-05,2011-04-06
-6axz,2018-01-17,2017-09-07
-4axl,2013-05-08,2012-06-13
-7axo,2020-12-02,2020-11-10
-4axn,2012-09-05,2012-06-13
-3axt,2011-08-03,2011-04-14
-1axz,1998-05-06,1997-10-24
-3ax4,2012-04-04,2011-03-29
-2axt,2005-12-27,2005-09-06
-3axw,2012-04-04,2011-04-18
-3axi,2011-10-05,2011-04-06
-8axp,2022-11-09,2022-08-31
-6axv,2018-09-12,2017-09-07
-1axb,1998-10-28,1997-10-14
-8axw,2023-09-13,2022-09-01
-4axf,2012-07-04,2012-06-12
-6ax6,2018-02-21,2017-09-06
-1axn,1996-03-08,1995-08-21
-3axe,2012-02-15,2011-04-04
-3ax1,2011-07-13,2011-03-28
-5ax2,2016-07-20,2015-07-13
-6axj,2017-11-22,2017-09-06
-2axa,2005-09-20,2005-09-03
-4axe,2012-07-04,2012-06-12
-3axk,2012-04-11,2011-04-11
-7ax5,2021-08-11,2020-11-09
-8axs,2023-03-01,2022-08-31
-4ax8,2012-10-03,2012-06-11
-7axy,2021-11-24,2020-11-10
-7axg,2021-01-13,2020-11-09
-3axz,2011-08-17,2011-04-21
-8ax0,2023-03-01,2022-08-30
-5axm,2016-08-03,2015-07-31
-1axr,1998-01-28,1997-10-20
-8ax5,2022-12-07,2022-08-30
-1axx,1998-03-04,1997-10-22
-7axt,2021-11-24,2020-11-10
-1ax4,1998-01-28,1997-10-28
-5ax1,2015-08-26,2015-07-10
-3ax7,2012-02-22,2011-03-30
-4ax1,2012-06-20,2012-06-06
-7axw,2021-11-24,2020-11-10
-8ax2,2023-03-01,2022-08-30
-2ax2,2006-01-03,2005-09-02
-6axa,2018-09-12,2017-09-06
-4ax0,2012-06-20,2012-06-06
-5axd,2016-07-27,2015-07-24
-5ax0,2015-08-26,2015-07-10
-5axa,2016-07-27,2015-07-24
-6axb,2018-09-05,2017-09-06
-6axu,2017-10-18,2017-09-07
-3ax0,2011-06-29,2011-03-26
-8axh,2023-08-09,2022-08-31
-8axv,2023-03-29,2022-09-01
-2axx,1998-03-04,1997-10-22
-8axy,2023-09-13,2022-09-01
-5axu,2015-11-11,2015-08-01
-3ax8,2011-10-05,2011-03-30
-2ax7,2005-09-20,2005-09-03
-5ax3,2016-02-10,2015-07-14
-4ax3,2013-03-27,2012-06-07
-8axa,2024-04-10,2022-08-31
-5axr,2016-05-11,2015-07-31
-7ax9,2021-01-13,2020-11-09
-6axm,2017-10-18,2017-09-07
-7axf,2021-01-13,2020-11-09
-3ax9,2012-02-22,2011-03-31
-3axy,2011-08-03,2011-04-19
-7axc,2021-01-13,2020-11-09
-5axi,2016-03-02,2015-07-29
-7axr,2021-10-06,2020-11-10
-4axo,2012-06-27,2012-06-13
-8ax1,2023-03-01,2022-08-30
-2ax0,2006-01-24,2005-09-02
-4ax7,2013-01-23,2012-06-11
-6ax7,2018-02-21,2017-09-06
-1axk,1999-05-11,1997-10-16
-3axm,2012-04-11,2011-04-11
-4axb,2012-08-29,2012-06-12
-2axy,2005-09-27,2005-09-06
-7axi,2021-01-13,2020-11-09
-4axh,2012-12-05,2012-06-13
-1axw,1998-10-28,1997-10-23
-5axo,2016-05-11,2015-07-31
-8axc,2022-11-16,2022-08-31
-9axf,2024-04-17,2024-03-06
-6ax1,2017-12-27,2017-09-06
-8axu,2023-09-20,2022-09-01
-8axe,2023-09-20,2022-08-31
-3ax6,2012-04-25,2011-03-30
-8ax6,2022-12-07,2022-08-30
-8axt,2023-03-01,2022-08-31
-7axb,2021-01-13,2020-11-09
-3axb,2012-04-04,2011-04-01
-7axh,2021-01-13,2020-11-09
-4axa,2012-07-25,2012-06-12
-6ax8,2018-04-11,2017-09-06
-7ax2,2021-01-13,2020-11-09
-7axk,2021-01-13,2020-11-09
-8axi,2023-03-01,2022-08-31
-7axx,2021-12-15,2020-11-10
-6axq,2018-02-21,2017-09-07
-7axd,2021-01-13,2020-11-09
-1ax0,1998-05-06,1997-10-24
-2axn,2005-12-06,2005-09-05
-1axs,1998-02-04,1997-10-20
-5axq,2015-11-11,2015-07-31
-4axy,2012-08-15,2012-06-15
-1ax9,1998-02-11,1997-11-03
-6ax3,2018-02-28,2017-09-06
-6ax4,2018-09-12,2017-09-06
-8ax3,2024-03-13,2022-08-30
-1ax1,1998-05-06,1997-10-24
-7ax3,2021-11-10,2020-11-09
-5axg,2015-11-11,2015-07-29
-5axn,2016-08-03,2015-07-31
-3axs,2011-08-03,2011-04-13
-5axv,2015-11-11,2015-08-01
-1axa,1998-04-15,1997-10-13
-5axh,2015-11-11,2015-07-29
-2ax1,2006-01-24,2005-09-02
-2ax8,2005-09-20,2005-09-03
-2axz,2005-12-06,2005-09-06
-7ax6,2020-12-02,2020-11-09
-6ax9,2017-10-18,2017-09-06
-1ax2,1998-05-06,1997-10-24
-5ax7,2016-06-08,2015-07-16
-5axp,2015-11-11,2015-07-31
-7axv,2021-11-24,2020-11-10
-7axs,2021-12-15,2020-11-10
-5axc,2016-07-27,2015-07-24
-7axp,2021-12-15,2020-11-10
-7ax1,2021-05-12,2020-11-09
-6axe,2017-09-27,2017-09-06
-7axq,2021-12-15,2020-11-10
-8axd,2024-03-06,2022-08-31
-3axx,2012-02-01,2011-04-18
-2ax9,2005-09-20,2005-09-03
-8axf,2023-04-05,2022-08-31
-1axj,1998-01-14,1997-10-16
-4ax9,2012-06-20,2012-06-11
-4axc,2012-07-04,2012-06-12
-4axd,2012-07-04,2012-06-12
-5axw,2015-09-02,2015-08-01
-7axm,2020-12-02,2020-11-09
-7axe,2021-01-13,2020-11-09
-4axv,2012-09-26,2012-06-14
-5axb,2016-07-27,2015-07-24
-4axq,2012-06-27,2012-06-13
-2axr,2005-09-13,2005-09-05
-7ax4,2021-04-14,2020-11-09
-5axl,2016-08-03,2015-07-31
-6axn,2017-10-18,2017-09-07
-4axx,2013-06-26,2012-06-15
-4axw,2012-11-07,2012-06-14
-7ax7,2020-11-18,2020-11-09
-5ax9,2016-07-27,2015-07-21
-1axy,1998-05-06,1997-10-24
-1axg,1998-04-15,1997-10-15
-4axm,2013-05-08,2012-06-13
-7axn,2021-06-16,2020-11-10
-8ax7,2022-12-07,2022-08-30
-4ax6,2013-01-23,2012-06-10
-7axj,2021-01-13,2020-11-09
-8axz,2022-10-05,2022-09-01
-2ax4,2005-09-20,2005-09-02
-3axg,2011-12-21,2011-04-04
-5b22,2016-12-28,2015-12-28
-8b2u,2023-09-27,2022-09-14
-3b2z,2007-12-25,2007-10-19
-4b2i,2013-02-06,2012-07-16
-5b2r,2016-03-23,2016-02-02
-4b2n,2013-07-24,2012-07-17
-7b2y,2021-08-04,2020-11-28
-6b2a,2017-10-11,2017-09-19
-7b2q,2022-03-02,2020-11-27
-4b2q,2012-08-29,2012-07-17
-8b2g,2023-07-19,2022-09-13
-6b24,2017-10-11,2017-09-19
-4b28,2012-07-25,2012-07-12
-7b20,2021-03-03,2020-11-25
-8b29,2023-01-18,2022-09-13
-4b2c,2012-08-01,2012-07-13
-7b2c,2021-07-14,2020-11-26
-6b2y,2017-11-15,2017-09-20
-4b2g,2012-12-19,2012-07-16
-8b26,2022-10-19,2022-09-13
-6b2f,2019-01-23,2017-09-20
-2b2j,2005-10-11,2005-09-19
-5b2n,2016-07-13,2016-01-20
-4b2a,2012-08-01,2012-07-13
-3b2x,2008-05-06,2007-10-19
-1b20,1998-12-09,1998-12-03
-8b2v,2023-05-24,2022-09-14
-7b26,2021-12-08,2020-11-26
-8b2h,2023-07-19,2022-09-13
-8b2i,2023-03-29,2022-09-14
-8b2d,2023-06-14,2022-09-13
-4b27,2012-09-19,2012-07-12
-8b2k,2023-03-29,2022-09-14
-8b2b,2023-02-15,2022-09-13
-9b27,2024-05-29,2024-03-14
-7b2t,2021-10-06,2020-11-27
-8b2e,2023-07-19,2022-09-13
-6b2u,2018-02-28,2017-09-20
-3b2t,2008-02-26,2007-10-19
-7b29,2021-12-08,2020-11-26
-1b2m,1999-03-25,1998-11-27
-8b25,2022-10-19,2022-09-13
-8b24,2024-01-17,2022-09-12
-8b22,2024-01-17,2022-09-12
-4b2b,2012-08-01,2012-07-13
-3b28,2011-09-14,2011-07-21
-2b2u,2005-12-27,2005-09-19
-8b2o,2023-05-24,2022-09-14
-1b2o,1999-05-27,1998-11-30
-1b21,1998-12-09,1998-12-03
-8b2n,2022-12-21,2022-09-14
-4b2y,2013-04-10,2012-07-19
-7b2h,2021-07-14,2020-11-27
-5b2j,2016-06-15,2016-01-18
-3b2u,2008-02-19,2007-10-19
-3b2r,2008-05-20,2007-10-19
-5b2v,2017-02-08,2016-02-03
-3b29,2011-12-14,2011-07-22
-2b2x,2006-04-18,2005-09-19
-7b2z,2021-08-04,2020-11-28
-1b25,1999-03-24,1998-12-04
-8b2q,2022-12-21,2022-09-14
-5b2u,2017-02-08,2016-02-03
-3b26,2011-09-14,2011-07-21
-2b2d,2006-05-09,2005-09-19
-7b2x,2021-01-20,2020-11-28
-4b2k,2013-07-17,2012-07-16
-2b22,2006-01-31,2005-09-16
-3b25,2011-09-14,2011-07-21
-7b2j,2022-02-23,2020-11-27
-6b2d,2017-10-11,2017-09-19
-6b2m,2018-09-05,2017-09-20
-5b2p,2016-03-02,2016-02-01
-3b2p,2008-05-06,2007-10-18
-5b2c,2016-09-28,2016-01-14
-3b24,2011-09-14,2011-07-21
-8b20,2023-12-27,2022-09-12
-2b2v,2005-12-27,2005-09-19
-8b2w,2023-05-24,2022-09-14
-4b2x,2012-10-31,2012-07-18
-5b2q,2016-03-02,2016-02-01
-1b23,1998-12-07,1998-12-04
-7b2p,2022-03-02,2020-11-27
-4b2m,2013-05-29,2012-07-16
-6b27,2017-10-25,2017-09-19
-2b23,2006-09-19,2005-09-16
-7b2e,2021-04-28,2020-11-26
-5b2y,2017-02-08,2016-02-07
-7b2v,2021-08-04,2020-11-28
-7b2u,2022-02-23,2020-11-27
-1b2l,1999-11-26,1998-11-26
-8b2c,2023-02-15,2022-09-13
-8b2l,2023-08-23,2022-09-14
-5b2x,2017-02-08,2016-02-03
-4b2o,2013-07-24,2012-07-17
-3b2e,2012-06-27,2011-07-30
-6b2q,2018-02-14,2017-09-20
-1b2x,1998-12-09,1998-12-03
-1b2y,2000-02-16,1998-12-03
-7b23,2021-03-03,2020-11-26
-8b2p,2022-11-02,2022-09-14
-5b2d,2016-09-28,2016-01-14
-6b2c,2018-01-03,2017-09-19
-6b2w,2017-12-13,2017-09-20
-3b27,2011-09-14,2011-07-21
-7b27,2021-05-12,2020-11-26
-6b2p,2018-02-14,2017-09-20
-8b2t,2023-02-22,2022-09-14
-5b2i,2016-06-15,2016-01-16
-1b2i,1999-11-19,1999-09-24
-9b22,2024-03-27,2024-03-14
-6b22,2018-08-01,2017-09-19
-3b2d,2011-11-09,2011-07-29
-4b2p,2013-07-24,2012-07-17
-7b2l,2021-05-05,2020-11-27
-6b2b,2017-10-11,2017-09-19
-2b26,2006-09-19,2005-09-16
-4b21,2013-01-09,2012-07-12
-8b2j,2022-11-30,2022-09-14
-7b25,2021-03-03,2020-11-26
-1b2j,1999-05-27,1998-11-27
-2b2w,2005-12-27,2005-09-19
-4b2h,2013-05-29,2012-07-16
-4b20,2013-04-17,2012-07-12
-2b24,2005-10-04,2005-09-16
-1b2h,1998-11-16,1998-11-16
-7b2i,2021-12-08,2020-11-27
-7b21,2021-07-21,2020-11-25
-1b2r,1999-12-15,1998-11-27
-5b2t,2016-03-23,2016-02-02
-8b2a,2023-02-15,2022-09-13
-8b2s,2023-07-19,2022-09-14
-2b2n,2006-01-24,2005-09-19
-2b21,2006-08-29,2005-09-16
-8b2m,2022-12-21,2022-09-14
-1b2z,1998-12-09,1998-12-03
-9b20,2024-03-27,2024-03-14
-7b2m,2022-03-02,2020-11-27
-3b2s,2007-12-11,2007-10-19
-5b2f,2016-08-10,2016-01-15
-4b29,2012-07-25,2012-07-12
-5b2s,2016-03-23,2016-02-02
-5b2e,2016-08-10,2016-01-15
-8b2f,2023-07-19,2022-09-13
-5b25,2016-02-03,2016-01-07
-4b2w,2013-05-29,2012-07-18
-5b2o,2016-03-02,2016-02-01
-5b2z,2016-06-01,2016-02-07
-3b2y,2007-11-27,2007-10-19
-5b2w,2017-02-08,2016-02-03
-8b23,2024-01-17,2022-09-12
-3b2q,2008-09-09,2007-10-19
-2b2t,2005-12-27,2005-09-19
-3b2w,2007-12-18,2007-10-19
-4b2d,2012-10-10,2012-07-13
-6b2x,2017-11-15,2017-09-20
-4b2l,2013-02-06,2012-07-16
-7b2k,2022-02-09,2020-11-27
-6b2e,2018-04-25,2017-09-19
-3b20,2012-01-11,2011-07-17
-2b2k,2006-09-05,2005-09-19
-3b2n,2007-10-30,2007-10-18
-4b2j,2013-07-17,2012-07-16
-7b24,2021-03-03,2020-11-26
-3b2v,2008-02-19,2007-10-19
-9b21,2024-03-27,2024-03-14
-6b2l,2018-09-26,2017-09-20
-1b2v,1999-06-24,1998-12-01
-6hkv,2019-03-27,2018-09-08
-1hkd,2003-03-18,2003-03-06
-4hkv,2013-10-30,2012-10-15
-1hkq,2003-05-29,2003-03-11
-6hkr,2018-11-28,2018-09-07
-4hkc,2013-06-26,2012-10-15
-2hkz,2006-08-29,2006-07-06
-8hka,2023-06-21,2022-11-25
-8hkp,2023-03-22,2022-11-27
-5hk2,2016-04-06,2016-01-13
-3hko,2009-06-02,2009-05-25
-8hkz,2023-08-30,2022-11-28
-8hkk,2023-08-16,2022-11-27
-1hk7,2004-01-29,2003-03-06
-3hkk,2010-05-26,2009-05-24
-5hk0,2017-01-18,2016-01-13
-1hkk,2004-03-11,2003-03-10
-3hkc,2009-09-01,2009-05-23
-4hka,2013-03-27,2012-10-15
-3hku,2009-10-13,2009-05-25
-2hkv,2006-08-15,2006-07-05
-1hkb,1998-06-03,1997-12-01
-4hkk,2012-10-31,2012-10-15
-6hk5,2019-03-27,2018-09-05
-5hkk,2016-09-21,2016-01-14
-5hk3,2017-01-18,2016-01-13
-8hke,2023-11-29,2022-11-25
-2hk5,2006-09-05,2006-07-03
-1hk5,2003-05-16,2003-03-05
-8hk0,2023-04-26,2022-11-24
-3hkq,2009-10-13,2009-05-25
-1hko,2003-03-18,2003-03-10
-6hky,2019-09-25,2018-09-09
-8hkb,2023-06-21,2022-11-25
-5hko,2016-02-03,2016-01-14
-4hkw,2014-01-08,2012-10-15
-6hk9,2019-09-18,2018-09-06
-8hks,2024-05-01,2022-11-28
-6hk1,2019-06-19,2018-09-05
-1hku,2003-06-19,2003-03-11
-5hk9,2016-05-18,2016-01-13
-6hks,2019-05-22,2018-09-07
-3hkv,2009-06-16,2009-05-26
-6hkx,2019-09-25,2018-09-09
-1hkj,2004-03-11,2003-03-10
-4hkr,2012-11-28,2012-10-15
-1hk3,2003-05-16,2003-03-05
-4hk8,2014-01-08,2012-10-15
-4hk5,2013-09-11,2012-10-15
-5hkw,2017-01-18,2016-01-14
-3hki,2009-07-07,2009-05-23
-5hky,2017-01-18,2016-01-14
-3hkj,2009-07-07,2009-05-23
-4hki,2012-10-31,2012-10-15
-1hkm,2004-03-11,2003-03-10
-4hks,2012-11-28,2012-10-15
-3hk8,2009-08-25,2009-05-22
-5hk1,2016-04-06,2016-01-13
-1hk2,2003-05-16,2003-03-05
-2hkx,2007-03-06,2006-07-05
-4hkp,2012-11-14,2012-10-15
-1hkc,1998-11-11,1998-07-01
-6hk6,2018-10-24,2018-09-05
-2hk7,2007-06-19,2006-07-03
-2hkf,2007-11-13,2006-07-04
-5hki,2017-01-25,2016-01-14
-6hk7,2019-07-17,2018-09-05
-6hkm,2019-02-27,2018-09-07
-2hk6,2007-01-16,2006-07-03
-3hkn,2009-10-13,2009-05-25
-6hkf,2019-02-27,2018-09-06
-3hkp,2010-01-12,2009-05-25
-4hk6,2013-09-11,2012-10-15
-8hkc,2023-05-31,2022-11-25
-6hk4,2019-07-17,2018-09-05
-3hk2,2009-10-06,2009-05-22
-3hk9,2009-08-25,2009-05-22
-8hk2,2023-05-10,2022-11-24
-5hkn,2016-05-04,2016-01-14
-5hkj,2016-03-02,2016-01-14
-4hkt,2012-12-19,2012-10-15
-5hkx,2017-01-18,2016-01-14
-4hkf,2012-12-12,2012-10-15
-3hkr,2009-09-22,2009-05-25
-2hkr,2008-04-01,2006-07-05
-6hkp,2019-09-18,2018-09-07
-2hk9,2007-06-19,2006-07-03
-5hkd,2016-03-09,2016-01-13
-3hkt,2009-10-13,2009-05-25
-3hkf,2009-11-10,2009-05-23
-5hka,2016-05-18,2016-01-13
-6hkb,2019-02-27,2018-09-06
-4hkx,2012-11-21,2012-10-15
-5hkv,2017-05-03,2016-01-14
-3hky,2010-05-26,2009-05-26
-2hkk,2007-05-22,2006-07-05
-3hk5,2009-08-25,2009-05-22
-5hkg,2016-10-05,2016-01-14
-4hk7,2013-09-11,2012-10-15
-2hka,2007-06-26,2006-07-03
-8hkm,2023-08-16,2022-11-27
-1hk4,2003-05-16,2003-03-05
-3hkb,2009-09-01,2009-05-23
-8hkd,2023-11-08,2022-11-25
-2hkm,2008-04-01,2006-07-05
-4hk9,2014-01-08,2012-10-15
-8hk1,2023-03-08,2022-11-24
-8hk7,2024-03-27,2022-11-25
-5hkh,2016-03-09,2016-01-14
-8hk6,2023-08-16,2022-11-25
-2hk1,2006-08-29,2006-07-03
-4hky,2013-01-23,2012-10-15
-6hk3,2019-07-17,2018-09-05
-2hko,2006-08-29,2006-07-05
-2hkj,2006-08-29,2006-07-04
-8hko,2024-05-01,2022-11-27
-1hkv,2003-03-20,2003-03-11
-8hkn,2024-05-01,2022-11-27
-3hkw,2010-05-26,2009-05-26
-8hkf,2023-08-16,2022-11-25
-8hky,2023-08-30,2022-11-28
-3hkl,2009-08-25,2009-05-24
-6hko,2019-04-03,2018-09-07
-5hkb,2016-05-18,2016-01-13
-6hkn,2019-02-27,2018-09-07
-6hkq,2020-04-01,2018-09-07
-1hk8,2003-03-27,2003-03-06
-5hkm,2016-06-08,2016-01-14
-1hk1,2003-05-16,2003-03-05
-5hkz,2017-01-18,2016-01-14
-4hkn,2012-10-31,2012-10-15
-8hki,2023-12-13,2022-11-27
-5hk7,2016-03-09,2016-01-14
-3hke,2009-09-01,2009-05-23
-1hkn,2004-03-11,2003-03-10
-8hkh,2023-11-29,2022-11-26
-8hkj,2023-04-26,2022-11-27
-5hkc,2017-01-18,2016-01-14
-1hki,2004-03-11,2003-03-10
-8hkq,2023-08-16,2022-11-27
-6hku,2019-03-27,2018-09-08
-3hkz,2009-06-09,2009-05-26
-5hkf,2017-01-25,2016-01-14
-6hk2,2019-09-18,2018-09-05
-3hka,2009-08-25,2009-05-22
-3hk1,2009-09-22,2009-05-22
-6hkz,2018-12-05,2018-09-09
-5hk4,2017-01-18,2016-01-13
-5hkr,2016-05-04,2016-01-14
-3hk7,2009-08-25,2009-05-22
-3hkd,2009-09-01,2009-05-23
-8hkr,2023-10-18,2022-11-28
-4hkj,2012-11-14,2012-10-15
-6hkj,2018-12-05,2018-09-06
-1i50,2001-04-23,2001-02-23
-3i59,2009-09-08,2009-07-03
-2i5x,2006-09-05,2006-08-26
-5i5r,2016-03-02,2016-02-15
-2i5w,2006-10-17,2006-08-26
-8i5b,2023-06-14,2023-01-24
-8i5y,2023-06-14,2023-01-26
-5i5x,2016-03-23,2016-02-15
-1i58,2001-08-26,2001-02-26
-5i5c,2017-01-25,2016-02-15
-8i5c,2023-08-23,2023-01-24
-1i5b,2001-08-26,2001-02-26
-1i5d,2001-08-26,2001-02-26
-1i54,2001-05-09,2001-02-24
-3i5o,2009-07-21,2009-07-06
-1i53,2001-10-17,2001-02-24
-3i52,2010-02-23,2009-07-03
-8i5h,2023-04-19,2023-01-25
-4i51,2012-12-19,2012-11-28
-1i59,2001-08-26,2001-02-26
-5i5l,2016-08-03,2016-02-15
-3i5i,2009-07-28,2009-07-05
-6i58,2019-03-06,2018-11-13
-6i5s,2019-09-25,2018-11-14
-2i5p,2006-09-12,2006-08-25
-5i5u,2016-03-23,2016-02-15
-2i5b,2006-09-19,2006-08-24
-1i5u,2001-03-21,2001-02-28
-1i5z,2003-06-17,2001-03-01
-6i5n,2019-05-29,2018-11-14
-5i5t,2016-03-23,2016-02-15
-4i5i,2013-01-23,2012-11-28
-1i5s,2001-05-30,2001-02-28
-2i57,2006-12-19,2006-08-24
-5i5a,2017-01-25,2016-02-14
-8i54,2023-02-22,2023-01-24
-5i5w,2016-03-23,2016-02-15
-5i5e,2017-02-15,2016-02-15
-1i5t,2001-03-21,2001-02-28
-4i5l,2013-05-08,2012-11-28
-6i59,2019-03-13,2018-11-13
-3i5t,2009-07-14,2009-07-06
-6i51,2019-11-20,2018-11-12
-2i51,2006-09-05,2006-08-23
-5i58,2016-09-21,2016-02-14
-4i5c,2013-05-22,2012-11-28
-2i58,2007-08-07,2006-08-24
-8i51,2024-01-24,2023-01-21
-8i5n,2024-02-28,2023-01-26
-3i56,2010-03-09,2009-07-03
-8i5d,2023-08-23,2023-01-25
-8i52,2024-01-10,2023-01-23
-8i57,2024-01-31,2023-01-24
-3i58,2009-09-01,2009-07-03
-2i5o,2007-03-13,2006-08-25
-8i5u,2023-05-03,2023-01-26
-4i59,2013-05-01,2012-11-28
-6i5w,2019-04-17,2018-11-14
-3i51,2010-01-12,2009-07-03
-1i5e,2002-06-05,2001-02-27
-5i5v,2016-03-23,2016-02-15
-4i5e,2013-06-12,2012-11-28
-8i5o,2023-05-03,2023-01-26
-2i5c,2007-08-07,2006-08-24
-3i5y,2009-09-08,2009-07-06
-4i55,2013-01-23,2012-11-28
-4i5m,2013-12-25,2012-11-28
-1i5l,2001-08-28,2001-02-28
-2i56,2006-12-19,2006-08-24
-8i5q,2023-05-03,2023-01-26
-2i52,2006-09-12,2006-08-23
-5i5m,2016-03-02,2016-02-15
-3i54,2009-09-08,2009-07-03
-5i57,2016-09-21,2016-02-14
-3i5u,2009-09-01,2009-07-06
-6i5p,2019-05-08,2018-11-14
-3i5c,2009-08-18,2009-07-03
-3i5r,2010-03-02,2009-07-06
-4i56,2013-07-17,2012-11-28
-3i5a,2009-08-18,2009-07-03
-4i5k,2013-05-08,2012-11-28
-2i5n,2006-09-19,2006-08-25
-4i5x,2013-10-23,2012-11-29
-2i5r,2007-07-03,2006-08-25
-8i5g,2023-06-14,2023-01-25
-4i5h,2013-07-10,2012-11-28
-3i5z,2010-01-12,2009-07-06
-5i5z,2016-04-13,2016-02-15
-5i5b,2017-01-25,2016-02-15
-3i5j,2009-10-13,2009-07-05
-2i50,2007-08-07,2006-08-23
-8i5j,2024-01-03,2023-01-25
-2i5u,2006-11-07,2006-08-25
-8i5e,2023-08-23,2023-01-25
-6i5f,2019-08-14,2018-11-13
-4i5n,2013-05-08,2012-11-28
-5i56,2016-09-07,2016-02-14
-5i5s,2016-03-23,2016-02-15
-6i5r,2019-04-17,2018-11-14
-6i5y,2019-04-17,2018-11-15
-6i5b,2019-09-25,2018-11-13
-3i53,2009-09-01,2009-07-03
-4i5v,2013-05-08,2012-11-29
-3i5x,2009-09-08,2009-07-06
-4i52,2013-05-08,2012-11-28
-4i54,2013-05-29,2012-11-28
-8i58,2024-01-31,2023-01-24
-2i5f,2007-08-07,2006-08-24
-5i5k,2016-03-16,2016-02-15
-4i5b,2013-12-04,2012-11-28
-1i52,2001-07-11,2001-02-23
-1i57,2001-08-08,2001-02-26
-5i5q,2016-05-18,2016-02-15
-8i5p,2023-05-03,2023-01-26
-6i5v,2019-04-17,2018-11-14
-3i55,2010-03-09,2009-07-03
-4i58,2013-05-01,2012-11-28
-1i55,2001-05-09,2001-02-24
-1i5c,2001-08-26,2001-02-26
-8i5t,2023-05-03,2023-01-26
-6i5g,2019-05-29,2018-11-13
-1i5a,2001-08-26,2001-02-26
-2i5s,2006-09-05,2006-08-25
-4i5q,2013-10-16,2012-11-28
-3i5g,2009-07-28,2009-07-05
-6i5z,2019-03-27,2018-11-15
-3i5f,2009-08-04,2009-07-05
-2i54,2007-04-17,2006-08-24
-6i5c,2019-03-13,2018-11-13
-3i57,2009-09-15,2009-07-03
-8i5m,2024-02-28,2023-01-26
-1i5q,2001-06-20,2001-02-28
-3i5d,2009-08-04,2009-07-05
-6i5l,2019-01-09,2018-11-13
-3i5h,2009-07-28,2009-07-05
-6i5m,2019-01-02,2018-11-13
-1i5f,2001-11-07,2001-02-27
-6i53,2019-01-02,2018-11-12
-1i5r,2003-03-11,2001-02-28
-6i5j,2019-05-29,2018-11-13
-8i5r,2023-05-03,2023-01-26
-8i5k,2024-01-03,2023-01-25
-4i5j,2013-05-08,2012-11-28
-6i5x,2019-11-27,2018-11-15
-6i55,2018-12-19,2018-11-12
-2i5j,2006-12-05,2006-08-24
-2i5m,2007-05-22,2006-08-25
-1i5g,2001-03-14,2001-02-27
-2i5y,2006-10-10,2006-08-26
-3i5n,2010-01-12,2009-07-06
-5i59,2016-09-21,2016-02-14
-4i53,2013-05-29,2012-11-28
-8i5x,2023-06-14,2023-01-26
-4i5p,2013-12-25,2012-11-28
-5i51,2017-02-15,2016-02-13
-1i5o,2001-05-02,2001-02-28
-5i5y,2016-03-23,2016-02-15
-6i5h,2019-01-16,2018-11-13
-8i5s,2023-05-03,2023-01-26
-2i55,2007-04-17,2006-08-24
-4i50,2013-01-23,2012-11-28
-6i5k,2019-01-09,2018-11-13
-4i5w,2013-05-08,2012-11-29
-6i5i,2019-01-09,2018-11-13
-7aq5,2021-01-13,2020-10-20
-4aql,2012-05-02,2012-04-18
-1aqv,1997-12-24,1997-08-01
-5aqf,2016-10-05,2015-09-22
-6aq5,2018-08-22,2017-08-18
-6aqq,2018-02-07,2017-08-21
-4aq4,2012-10-17,2012-04-13
-7aqg,2021-02-24,2020-10-21
-8aq0,2022-11-16,2022-08-11
-1aqc,1997-12-24,1997-07-28
-8aq9,2024-01-17,2022-08-11
-4aqu,2012-07-04,2012-04-19
-5aq6,2016-01-27,2015-09-21
-1aq7,1998-02-25,1997-08-07
-1aqn,1998-01-14,1997-07-31
-4aq1,2012-06-13,2012-04-12
-6aqh,2017-08-30,2017-08-19
-5aqi,2016-10-05,2015-09-22
-2aqo,2005-12-13,2005-08-18
-7aq7,2021-01-13,2020-10-20
-1aqx,1998-03-18,1997-08-03
-5aqu,2016-10-05,2015-09-22
-4aqa,2012-11-07,2012-04-15
-3aqv,2011-04-27,2010-11-19
-5aqo,2016-10-05,2015-09-22
-1aql,1998-08-05,1997-07-30
-8aqe,2023-09-20,2022-08-12
-7aqi,2020-12-02,2020-10-21
-5aqn,2016-10-05,2015-09-22
-4aqi,2012-10-17,2012-04-17
-4aqh,2012-11-28,2012-04-17
-2aq4,2005-10-04,2005-08-17
-5aqg,2016-10-05,2015-09-22
-7aqf,2021-02-17,2020-10-21
-7aq8,2021-01-13,2020-10-20
-4aq3,2012-06-06,2012-04-12
-3aqn,2011-02-09,2010-11-09
-2aqc,2005-11-15,2005-08-17
-1aqy,1998-10-28,1997-08-04
-2aq8,2006-05-23,2005-08-17
-2aqv,2005-12-13,2005-08-18
-7aqt,2022-03-02,2020-10-23
-8aqa,2022-12-21,2022-08-11
-5aqp,2016-10-05,2015-09-22
-3aqc,2010-11-10,2010-10-28
-1aqu,1998-10-28,1997-08-01
-4aq7,2012-06-13,2012-04-13
-5aqs,2016-10-05,2015-09-22
-7aqs,2021-09-01,2020-10-22
-4aq0,2013-02-06,2012-04-12
-7aq9,2021-01-13,2020-10-20
-7aqz,2021-11-03,2020-10-23
-8aqx,2023-08-23,2022-08-14
-2aqs,2006-10-31,2005-08-18
-2aqx,2005-12-06,2005-08-18
-6aqr,2018-07-04,2017-08-21
-8aq7,2022-12-07,2022-08-11
-7aqq,2021-12-08,2020-10-22
-7aq1,2021-03-03,2020-10-20
-6aqn,2019-01-16,2017-08-20
-2aq6,2005-08-30,2005-08-17
-2aqn,2006-10-31,2005-08-18
-5aqr,2016-10-05,2015-09-22
-7aqy,2021-11-03,2020-10-23
-3aqm,2011-02-09,2010-11-09
-5aqh,2016-10-05,2015-09-22
-1aqm,1999-03-02,1997-07-31
-2aq9,2006-06-27,2005-08-17
-8aqt,2023-03-01,2022-08-13
-4aqq,2012-10-24,2012-04-19
-6aqz,2017-08-30,2017-08-21
-2aqk,2006-05-23,2005-08-18
-5aqk,2016-10-05,2015-09-22
-6aqe,2019-01-16,2017-08-19
-8aqg,2023-08-23,2022-08-12
-2aqj,2005-10-04,2005-08-18
-3aq0,2011-01-19,2010-10-24
-1aqq,1997-12-24,1997-07-31
-1aqf,1998-09-16,1997-07-29
-7aqr,2021-12-08,2020-10-22
-1aqj,1997-02-12,1996-07-25
-3aqa,2011-05-18,2010-10-27
-5aqj,2016-10-05,2015-09-22
-7aq2,2021-01-13,2020-10-20
-4aqe,2012-11-07,2012-04-16
-3aq6,2011-04-20,2010-10-25
-6aqk,2018-08-22,2017-08-20
-7aqp,2020-12-02,2020-10-22
-8aqw,2023-03-15,2022-08-13
-1aqi,1997-02-12,1996-07-25
-6aqf,2018-01-10,2017-08-19
-7aq0,2021-01-13,2020-10-20
-8aqz,2023-09-20,2022-08-15
-7aq6,2021-01-13,2020-10-20
-3aql,2011-02-09,2010-11-09
-7aqm,2021-06-16,2020-10-22
-5aqz,2016-05-11,2015-09-22
-4aqx,2012-07-04,2012-04-19
-3aq7,2011-04-20,2010-10-25
-7aqx,2021-11-03,2020-10-23
-8aqk,2022-12-21,2022-08-12
-4aqs,2012-08-15,2012-04-19
-4aqp,2013-03-27,2012-04-19
-4aqn,2012-05-02,2012-04-19
-6aq4,2018-08-01,2017-08-18
-5aqx,2016-10-05,2015-09-22
-8aqi,2023-08-23,2022-08-12
-8aql,2022-10-05,2022-08-12
-2aqt,2006-10-31,2005-08-18
-8aq5,2022-12-07,2022-08-11
-5aqc,2016-10-05,2015-09-21
-6aqo,2018-03-14,2017-08-21
-2aqi,2006-05-23,2005-08-18
-7aqj,2020-12-02,2020-10-22
-3aq9,2011-04-20,2010-10-25
-1aqr,1997-12-24,1997-07-31
-5aqq,2016-10-05,2015-09-22
-7aqu,2020-12-23,2020-10-23
-8aqo,2023-08-23,2022-08-13
-5aqt,2016-10-05,2015-09-22
-8aqb,2022-12-21,2022-08-11
-1aqa,1997-09-17,1997-07-28
-8aqu,2023-03-01,2022-08-13
-7aq4,2021-01-13,2020-10-20
-1aq0,1998-02-11,1997-08-05
-1aqe,1998-02-04,1997-07-29
-2aq2,2006-03-21,2005-08-17
-2aqd,2006-04-11,2005-08-17
-6aq6,2018-08-22,2017-08-18
-2aqp,2006-10-31,2005-08-18
-6aqp,2018-05-30,2017-08-21
-7aq3,2021-01-13,2020-10-20
-1aq2,1998-10-14,1997-08-05
-5aqw,2016-10-05,2015-09-22
-7aqa,2021-01-27,2020-10-20
-8aqf,2023-08-23,2022-08-12
-4aq2,2013-04-24,2012-04-12
-6aqs,2018-02-14,2017-08-21
-1aqs,1997-12-24,1997-07-31
-8aq1,2023-09-20,2022-08-11
-1aqw,1998-03-18,1997-08-03
-2aqh,2006-05-23,2005-08-18
-2aqr,2006-10-31,2005-08-18
-1aqb,1998-01-28,1997-07-28
-4aqy,2012-07-18,2012-04-20
-5aqd,2016-06-29,2015-09-22
-3aq4,2011-01-26,2010-10-25
-2aqq,2006-10-31,2005-08-18
-1aqh,1999-02-16,1997-07-30
-3aq5,2011-04-20,2010-10-25
-4aqb,2012-08-08,2012-04-16
-4aq6,2013-04-24,2012-04-12
-7aqe,2021-03-03,2020-10-21
-5aqe,2015-10-07,2015-09-22
-8aqs,2023-03-01,2022-08-13
-1aq8,1998-02-25,1997-08-07
-8aq8,2023-07-12,2022-08-11
-8aqm,2022-11-09,2022-08-12
-4aqt,2012-08-15,2012-04-19
-2aqu,2006-08-29,2005-08-18
-8aqp,2023-08-23,2022-08-13
-3aqb,2010-11-10,2010-10-28
-1aq1,1997-11-12,1997-08-05
-4aqo,2013-06-05,2012-04-19
-3aqj,2011-08-10,2010-11-06
-8aqy,2023-08-30,2022-08-15
-8aqc,2023-09-20,2022-08-12
-3aq8,2011-04-20,2010-10-25
-3aqz,2011-06-22,2010-11-22
-5aqy,2016-10-05,2015-09-22
-7aqb,2020-11-11,2020-10-20
-8aqd,2022-08-31,2022-08-12
-5aqv,2016-10-05,2015-09-22
-2aqb,2006-01-17,2005-08-17
-2aq7,2006-01-17,2005-08-17
-8aqj,2022-08-31,2022-08-12
-4aq8,2012-11-07,2012-04-13
-4aqc,2012-04-25,2012-04-16
-8aqv,2023-03-01,2022-08-13
-6aqg,2017-08-30,2017-08-19
-1aqp,1998-05-27,1997-07-31
-3aqx,2011-06-22,2010-11-22
-3aqt,2011-07-06,2010-11-18
-7aqw,2021-12-08,2020-10-23
-8aq6,2023-08-23,2022-08-11
-4aqj,2012-10-17,2012-04-17
-4aqr,2012-10-17,2012-04-19
-3aqi,2012-01-25,2010-11-03
-6aqj,2017-10-18,2017-08-20
-8aqn,2022-11-09,2022-08-12
-5aq1,2016-07-20,2015-09-18
-7kva,2020-12-23,2020-11-27
-6kv0,2020-05-20,2019-09-03
-3kvm,2010-03-02,2009-11-30
-3kv3,2010-08-18,2009-11-29
-1kv5,2002-03-29,2002-01-25
-7kv6,2021-02-17,2020-11-26
-4kvb,2014-06-04,2013-05-22
-7kvb,2020-12-23,2020-11-27
-4kv3,2014-04-09,2013-05-22
-1kv8,2002-04-15,2002-01-25
-3kvg,2010-01-19,2009-11-30
-4kvn,2013-08-07,2013-05-22
-3kvy,2010-04-28,2009-11-30
-6kvj,2019-11-20,2019-09-04
-3kv5,2009-12-22,2009-11-29
-4kvr,2013-06-26,2013-05-23
-7kvi,2021-01-20,2020-11-28
-1kvm,2002-03-13,2002-01-27
-5kvm,2016-09-28,2016-07-14
-4kv9,2014-02-05,2013-05-22
-6kvw,2020-09-09,2019-09-05
-3kvi,2010-04-28,2009-11-30
-6kvv,2021-07-14,2019-09-05
-6kvq,2020-01-15,2019-09-05
-3kvb,2009-12-22,2009-11-29
-6kvh,2020-09-09,2019-09-04
-7kvq,2021-01-20,2020-11-28
-7kvy,2020-12-30,2020-11-29
-4kvd,2013-08-14,2013-05-22
-3kvc,2010-02-02,2009-11-29
-6kva,2020-09-09,2019-09-03
-7kv3,2021-02-17,2020-11-26
-4kv8,2013-07-31,2013-05-22
-4kvw,2013-08-14,2013-05-23
-7kv7,2021-02-17,2020-11-26
-1kvo,1997-07-07,1996-07-29
-7kvm,2021-01-20,2020-11-28
-2kv1,2010-03-16,2010-03-04
-7kvr,2020-12-09,2020-11-28
-3kvt,1999-01-13,1998-09-25
-3kvv,2010-04-28,2009-11-30
-3kv4,2009-12-22,2009-11-29
-5kvi,2016-11-16,2016-07-14
-6kvz,2020-09-09,2019-09-05
-6kvp,2020-01-15,2019-09-05
-1kvq,1998-06-17,1997-03-07
-7kv8,2020-12-23,2020-11-27
-7kv2,2021-02-17,2020-11-26
-3kvo,2010-03-09,2009-11-30
-1kvw,1998-11-18,1998-04-24
-2kvh,2010-04-14,2010-03-15
-5kvp,2016-10-26,2016-07-15
-1kvy,1998-11-18,1998-04-29
-4kvj,2013-08-21,2013-05-22
-5kvv,2016-09-14,2016-07-15
-5kvt,2017-12-27,2016-07-15
-7kvp,2021-01-20,2020-11-28
-1kvl,2002-03-13,2002-01-27
-7kvk,2021-01-20,2020-11-28
-3kvf,2010-06-16,2009-11-30
-1kv2,2002-03-27,2002-01-23
-7kvo,2021-01-20,2020-11-28
-6kvd,2019-12-18,2019-09-04
-2kvg,2010-04-14,2010-03-15
-3kvu,2010-04-28,2009-11-30
-3kvx,2009-12-22,2009-11-30
-5kvq,2016-09-21,2016-07-15
-3kv2,2009-12-22,2009-11-28
-2kvf,2010-04-14,2010-03-15
-4kvz,2013-07-24,2013-05-23
-3kv6,2009-12-22,2009-11-29
-5kvs,2016-09-21,2016-07-15
-7kvw,2021-03-24,2020-11-29
-4kva,2014-02-05,2013-05-22
-6kvs,2020-09-09,2019-09-05
-1kv3,2002-03-13,2002-01-24
-4kvm,2013-07-31,2013-05-22
-1kvk,2002-03-27,2002-01-26
-3kvs,2011-04-13,2009-11-30
-2kvj,2010-05-12,2010-03-15
-3kvk,2010-03-02,2009-11-30
-4kv1,2013-06-26,2013-05-22
-3kva,2009-12-22,2009-11-29
-3kvl,2010-03-02,2009-11-30
-4kvk,2013-08-21,2013-05-22
-4kvx,2013-07-31,2013-05-23
-3kvw,2010-01-05,2009-11-30
-3kv9,2009-12-22,2009-11-29
-1kvr,1998-03-18,1997-03-07
-4kvi,2013-08-14,2013-05-22
-6kvf,2020-09-09,2019-09-04
-7kvh,2021-01-20,2020-11-28
-4kvl,2013-08-21,2013-05-22
-4kvg,2014-03-05,2013-05-22
-4kv4,2013-06-26,2013-05-22
-5kv9,2017-07-12,2016-07-13
-5kvu,2017-07-19,2016-07-15
-4kvo,2013-07-31,2013-05-22
-5kve,2016-08-10,2016-07-14
-5kvc,2017-01-11,2016-07-14
-7kv9,2020-12-23,2020-11-27
-6kvk,2019-11-20,2019-09-04
-4kvq,2013-06-26,2013-05-23
-3kvj,2010-03-02,2009-11-30
-6kv1,2020-01-15,2019-09-03
-1kvx,1998-11-18,1998-04-28
-7kvz,2022-02-09,2020-11-29
-6kv9,2019-11-13,2019-09-03
-6kvo,2020-04-08,2019-09-05
-6kvc,2019-11-13,2019-09-04
-5kvl,2017-05-24,2016-07-14
-4kvy,2013-08-14,2013-05-23
-7kvj,2021-01-20,2020-11-28
-1kv7,2002-02-06,2002-01-25
-6kvl,2019-11-20,2019-09-04
-4kvs,2013-06-26,2013-05-23
-5kva,2016-08-10,2016-07-14
-1kv9,2002-07-10,2002-01-25
-5kvd,2016-08-03,2016-07-14
-1kvt,1998-03-18,1997-03-07
-5kvy,2017-08-23,2016-07-15
-1kv1,2002-03-27,2002-01-23
-5kv8,2017-07-12,2016-07-13
-7kvl,2020-12-09,2020-11-28
-7kvn,2021-01-20,2020-11-28
-3kvz,2010-04-28,2009-11-30
-4kv0,2014-06-25,2013-05-22
-6kvy,2020-09-09,2019-09-05
-1kvj,2003-11-18,2002-01-26
-3kve,2010-10-13,2009-11-30
-7kvx,2021-06-02,2020-11-29
-7kvs,2021-01-20,2020-11-28
-6kvi,2019-11-20,2019-09-04
-5kvh,2016-11-16,2016-07-14
-1kvs,1998-03-18,1997-03-07
-3kv8,2010-04-21,2009-11-29
-3kvr,2010-04-28,2009-11-30
-4kv6,2013-06-12,2013-05-22
-1kvu,1998-03-18,1997-03-07
-4kvp,2013-07-31,2013-05-22
-1znq,2005-05-24,2005-05-11
-3zn3,2013-02-20,2013-02-13
-1znh,2005-12-20,2005-05-11
-6znx,2020-07-15,2020-07-07
-6zn4,2021-02-17,2020-07-06
-4zne,2015-11-11,2015-05-04
-5znt,2019-02-20,2018-04-10
-7znt,2022-09-14,2022-04-22
-7zns,2023-06-21,2022-04-21
-7znu,2022-12-07,2022-04-22
-1znl,2005-12-20,2005-05-11
-3zni,2013-07-10,2013-02-14
-5znk,2019-05-29,2018-04-09
-1znk,2005-12-20,2005-05-11
-1zns,2006-03-14,2005-05-12
-3znu,2013-02-27,2013-02-18
-1zn2,2005-09-27,2005-05-11
-2znh,2008-10-21,2008-04-25
-2znv,2008-09-02,2008-05-01
-7znv,2023-03-01,2022-04-22
-8zn4,2024-06-05,2024-05-25
-4znv,2016-05-04,2015-05-05
-3zn8,2013-03-06,2013-02-13
-6zn7,2021-02-17,2020-07-06
-6znw,2021-07-14,2020-07-06
-4znh,2016-05-04,2015-05-04
-4zn7,2016-05-04,2015-05-04
-7zna,2023-05-10,2022-04-20
-3znv,2013-06-26,2013-02-18
-4znf,1992-01-15,1990-07-09
-6znv,2020-08-26,2020-07-06
-1znm,1998-04-01,1997-11-20
-1zno,2006-07-04,2005-05-11
-6znt,2021-02-17,2020-07-06
-4zn9,2015-09-09,2015-05-04
-8zn2,2024-06-05,2024-05-25
-3znp,2013-05-15,2013-02-15
-3zno,2013-05-15,2013-02-15
-1znj,1998-01-28,1997-09-23
-2zn7,2008-10-07,2008-04-22
-3znl,2013-09-25,2013-02-15
-8zn1,2024-06-05,2024-05-25
-4znz,2015-05-20,2015-05-05
-1znb,1997-01-11,1996-06-06
-6znu,2021-02-17,2020-07-06
-4znd,2015-05-13,2015-05-04
-6znn,2020-07-29,2020-07-06
-5znj,2019-05-29,2018-04-09
-1zne,2005-12-20,2005-05-11
-4znx,2016-06-29,2015-05-05
-4znb,1999-06-08,1998-10-20
-5znf,1994-01-31,1991-08-22
-3zn1,2013-06-12,2013-02-13
-5znr,2018-07-18,2018-04-10
-5zn7,2019-04-10,2018-04-07
-1zn7,2006-04-25,2005-05-11
-3zns,2013-03-27,2013-02-15
-6zny,2020-12-23,2020-07-07
-2znu,2009-05-05,2008-05-01
-2znk,2009-04-14,2008-04-26
-1zn9,2006-04-25,2005-05-11
-2znf,1991-10-15,1990-03-30
-4zn3,2016-03-16,2015-05-04
-7zn0,2023-05-10,2022-04-20
-3znf,1992-01-15,1990-07-09
-1zni,1998-01-28,1997-09-23
-7znn,2022-11-09,2022-04-21
-1zny,2005-11-29,2005-05-12
-6znq,2020-11-25,2020-07-06
-6znd,2020-07-22,2020-07-06
-7znq,2022-08-03,2022-04-21
-4zn8,2015-05-27,2015-05-04
-6znm,2020-07-29,2020-07-06
-3znq,2013-05-15,2013-02-15
-7znw,2023-03-01,2022-04-22
-6zno,2020-07-29,2020-07-06
-1znz,2005-11-29,2005-05-12
-7znm,2023-03-01,2022-04-21
-3znx,2013-06-26,2013-02-18
-7zn6,2023-06-28,2022-04-20
-3znk,2013-09-25,2013-02-15
-5zns,2019-02-20,2018-04-10
-7znf,1994-01-31,1991-08-22
-4zn5,2015-10-28,2015-05-04
-6zng,2021-02-17,2020-07-06
-5zn8,2018-04-25,2018-04-08
-4znt,2016-05-04,2015-05-05
-2zn8,2008-09-09,2008-04-22
-1zn8,2006-04-25,2005-05-11
-1znx,2005-11-29,2005-05-12
-1znd,2005-12-20,2005-05-11
-6zn2,2021-12-08,2020-07-06
-5zno,2018-09-12,2018-04-10
-4zno,2016-01-20,2015-05-05
-1znv,2006-03-14,2005-05-12
-3zn6,2013-05-15,2013-02-13
-2znn,2009-05-05,2008-04-30
-1zng,2005-12-20,2005-05-11
-3znb,1998-01-28,1997-10-15
-7znk,2023-05-03,2022-04-21
-2znq,2009-05-05,2008-04-30
-4znl,2015-07-08,2015-05-04
-2znt,2009-05-05,2008-05-01
-6znl,2020-07-29,2020-07-06
-3znc,1999-03-23,1998-02-10
-3znn,2013-05-15,2013-02-15
-2zn9,2008-09-09,2008-04-22
-7zn8,2023-05-10,2022-04-20
-2znc,1999-03-23,1998-02-10
-1znc,1997-09-17,1996-09-17
-2znp,2009-05-05,2008-04-30
-4zns,2016-05-04,2015-05-05
-7zn1,2023-05-10,2022-04-20
-5znp,2018-07-18,2018-04-10
-5znq,2019-04-17,2018-04-10
-6zn6,2020-08-26,2020-07-06
-1znt,2005-12-06,2005-05-12
-6zns,2020-11-25,2020-07-06
-7zn3,2023-05-10,2022-04-20
-6znz,2020-12-23,2020-07-07
-6zn1,2021-01-20,2020-07-06
-7zn7,2022-11-09,2022-04-20
-3zn2,2014-03-05,2013-02-13
-4zng,2016-08-10,2015-05-04
-3znt,2014-01-08,2013-02-18
-6zn5,2020-07-29,2020-07-06
-5znn,2018-07-18,2018-04-10
-1zn3,2005-07-05,2005-05-11
-2znr,2008-09-02,2008-05-01
-4znw,2016-05-04,2015-05-05
-2zns,2009-05-05,2008-05-01
-7znp,2023-05-10,2022-04-21
-2zno,2009-05-05,2008-04-30
-4zn1,2016-03-16,2015-05-04
-4znu,2016-05-04,2015-05-05
-7zno,2022-06-22,2022-04-21
-6zn0,2020-12-09,2020-07-06
-2zny,2009-03-17,2008-05-02
-3znr,2013-03-27,2013-02-15
-2znb,1998-01-28,1997-10-14
-2znd,2008-09-09,2008-04-22
-8zn3,2024-06-05,2024-05-25
-1znf,1991-07-15,1989-09-25
-5zni,2019-01-16,2018-04-09
-6znp,2020-11-25,2020-07-06
-4znq,2016-01-20,2015-05-05
-4znr,2016-01-20,2015-05-05
-5znc,2019-01-16,2018-04-08
-2znz,2009-03-17,2008-05-02
-3znm,2013-09-25,2013-02-15
-2zne,2008-09-09,2008-04-22
-4znm,2015-05-27,2015-05-04
-5znl,2019-02-20,2018-04-09
-3zn0,2013-06-12,2013-02-13
-6znc,2021-12-08,2020-07-06
-5znh,2019-04-17,2018-04-09
-7znj,2023-04-12,2022-04-21
-7znr,2023-06-21,2022-04-21
-3c7c,2008-07-22,2008-02-07
-7c7d,2020-11-11,2020-05-25
-7c7c,2021-05-26,2020-05-24
-8c77,2023-01-25,2023-01-12
-3c7t,2009-03-24,2008-02-08
-2c7t,2006-08-16,2005-11-29
-4c7i,2014-09-24,2013-09-20
-3c7g,2008-11-18,2008-02-07
-1c7e,2000-08-23,2000-02-16
-4c7n,2014-04-02,2013-09-23
-4c7k,2014-03-05,2013-09-23
-5c7g,2016-07-06,2015-06-24
-7c7e,2021-01-20,2020-05-25
-5c7h,2015-07-08,2015-06-24
-3c76,2008-03-04,2008-02-06
-5c7z,2016-07-06,2015-06-25
-3c7a,2008-07-22,2008-02-07
-6c79,2018-03-21,2018-01-22
-8c70,2023-05-24,2023-01-12
-6c74,2018-09-12,2018-01-19
-8c7f,2024-01-24,2023-01-15
-7c7r,2021-05-12,2020-05-26
-6c7n,2019-01-30,2018-01-23
-8c7x,2023-02-22,2023-01-17
-5c7v,2016-08-10,2015-06-25
-3c7e,2008-11-18,2008-02-07
-2c7u,2006-03-08,2005-11-29
-5c7n,2015-07-08,2015-06-24
-1c72,2000-08-30,2000-02-02
-7c7n,2020-10-14,2020-05-26
-8c7s,2023-07-19,2023-01-17
-4c71,2013-10-09,2013-09-19
-4c7u,2014-10-15,2013-09-25
-4c7l,2013-10-09,2013-09-23
-7c7u,2021-05-12,2020-05-26
-8c7u,2023-06-28,2023-01-17
-6c71,2018-07-11,2018-01-19
-4c7g,2014-03-12,2013-09-20
-5c7e,2015-08-05,2015-06-24
-6c7q,2018-08-01,2018-01-23
-1c7d,2000-06-30,2000-02-09
-1c7k,2001-04-25,2000-02-19
-8c7z,2023-02-01,2023-01-18
-2c77,2006-03-16,2005-11-18
-6c7p,2018-04-25,2018-01-23
-1c75,2000-03-22,2000-02-09
-7c7b,2021-05-26,2020-05-24
-1c7s,2000-09-20,2000-03-14
-5c7o,2016-03-09,2015-06-24
-3c75,2008-12-30,2008-02-06
-7c7s,2020-07-01,2020-05-26
-5c7b,2015-08-12,2015-06-24
-4c70,2013-10-09,2013-09-19
-2c7v,2006-09-19,2005-11-29
-6c7o,2018-04-25,2018-01-23
-2c78,2006-03-16,2005-11-18
-4c7x,2014-10-08,2013-09-26
-1c7g,2003-12-09,2000-02-18
-1c7c,2000-06-30,2000-02-09
-6c7d,2018-08-15,2018-01-22
-7c7q,2020-07-01,2020-05-26
-4c72,2013-10-09,2013-09-19
-2c7f,2005-12-14,2005-11-23
-2c7q,2005-12-14,2005-11-27
-5c7d,2015-08-12,2015-06-24
-4c74,2014-02-05,2013-09-19
-2c7k,2006-01-25,2005-11-24
-7c77,2021-01-06,2020-05-23
-3c74,2009-02-10,2008-02-06
-2c7m,2006-02-15,2005-11-25
-6c7w,2018-05-23,2018-01-23
-2c79,2006-01-23,2005-11-18
-1c7n,2000-07-26,2000-03-16
-7c7p,2020-07-29,2020-05-26
-1c7p,2000-04-05,2000-02-29
-5c7k,2015-10-07,2015-06-24
-1c7j,2000-03-29,2000-02-21
-4c7t,2014-04-02,2013-09-25
-2c7p,2005-12-14,2005-11-25
-2c76,2006-04-19,2005-11-17
-6c7e,2018-08-15,2018-01-22
-8c7y,2023-02-22,2023-01-17
-8c73,2023-08-09,2023-01-12
-2c7g,2006-07-26,2005-11-24
-2c72,2006-04-19,2005-11-17
-1c7i,2000-03-29,2000-02-21
-3c7q,2008-12-23,2008-02-08
-7c74,2020-06-10,2020-05-22
-7c7i,2021-05-05,2020-05-25
-3c7i,2008-08-12,2008-02-07
-6c7r,2018-08-01,2018-01-23
-1c7o,2000-07-26,2000-03-16
-1c7m,2000-07-19,2000-03-03
-7c76,2021-01-06,2020-05-23
-4c77,2014-02-05,2013-09-19
-8c71,2023-05-24,2023-01-12
-7c7j,2021-05-05,2020-05-25
-7c70,2020-09-16,2020-05-22
-4c7j,2014-09-03,2013-09-23
-5c7c,2015-08-12,2015-06-24
-6c7z,2018-04-25,2018-01-23
-3c7k,2008-05-06,2008-02-07
-3c72,2008-07-22,2008-02-06
-1c7q,2000-09-13,2000-03-02
-1c70,2000-12-28,1999-12-29
-7c7v,2021-01-20,2020-05-26
-2c7a,2006-08-30,2005-11-19
-8c7p,2024-01-31,2023-01-16
-8c7c,2023-11-22,2023-01-14
-2c73,2006-04-19,2005-11-17
-3c7p,2009-01-13,2008-02-08
-6c7y,2018-05-02,2018-01-23
-8c7h,2023-03-01,2023-01-16
-4c7a,2013-11-06,2013-09-20
-6c7f,2018-08-15,2018-01-22
-5c77,2016-01-13,2015-06-24
-7c7w,2021-01-20,2020-05-26
-3c7m,2008-07-15,2008-02-07
-7c7g,2020-09-23,2020-05-25
-5c7a,2015-08-12,2015-06-24
-1c7f,2000-08-23,2000-02-11
-4c79,2013-11-06,2013-09-20
-6c7b,2018-09-05,2018-01-22
-1c7b,2000-06-30,2000-02-09
-6c7x,2018-05-23,2018-01-23
-5c7y,2016-06-29,2015-06-25
-5c7t,2016-01-20,2015-06-24
-2c7j,2006-01-25,2005-11-24
-6c7l,2019-02-06,2018-01-22
-8c7m,2024-01-31,2023-01-16
-5c74,2016-01-13,2015-06-24
-4c78,2013-11-20,2013-09-19
-1c7t,2000-09-20,2000-03-17
-3c79,2008-05-20,2008-02-06
-7c75,2020-06-24,2020-05-22
-5c71,2016-06-29,2015-06-24
-7c7o,2020-10-14,2020-05-26
-4c7o,2013-11-20,2013-09-23
-2c7r,2005-12-14,2005-11-27
-4c7f,2014-03-12,2013-09-20
-2c7l,2006-01-25,2005-11-25
-4c7r,2013-10-30,2013-09-24
-3c7d,2008-07-22,2008-02-07
-4c7y,2014-01-15,2013-09-27
-5c7f,2015-08-05,2015-06-24
-8c7w,2023-02-08,2023-01-17
-1c7r,2000-09-13,2000-03-02
-6c7j,2018-08-15,2018-01-22
-2c70,2006-04-19,2005-11-17
-6c7k,2018-04-25,2018-01-22
-2c71,2006-01-23,2005-11-17
-8c7r,2023-11-22,2023-01-17
-3c7f,2008-11-18,2008-02-07
-5c7r,2015-09-30,2015-06-24
-7c7m,2021-04-28,2020-05-26
-6c7i,2018-08-15,2018-01-22
-8c76,2023-08-09,2023-01-12
-2c75,2006-04-19,2005-11-17
-8c75,2024-01-24,2023-01-12
-3c7j,2008-02-26,2008-02-07
-6c75,2019-01-23,2018-01-19
-4c76,2014-10-01,2013-09-19
-2c7e,2006-02-16,2005-11-22
-2c7x,2006-07-03,2005-11-29
-5c7s,2016-06-29,2015-06-24
-1c74,2000-07-22,2000-01-22
-7c7h,2020-09-23,2020-05-25
-7c7f,2020-09-23,2020-05-25
-8c74,2023-05-24,2023-01-12
-3c77,2008-03-04,2008-02-06
-5c79,2015-10-07,2015-06-24
-7c73,2020-06-24,2020-05-22
-4c73,2013-10-09,2013-09-19
-7c7a,2020-07-08,2020-05-24
-4c7h,2014-09-24,2013-09-20
-4c7b,2013-11-20,2013-09-20
-2c7o,2005-12-14,2005-11-25
-7c7l,2020-12-23,2020-05-26
-4c7z,2014-01-15,2013-09-27
-6c76,2019-01-23,2018-01-20
-8c72,2023-05-24,2023-01-12
-6c7g,2018-08-15,2018-01-22
-3c7x,2009-02-10,2008-02-08
-4c75,2014-04-16,2013-09-19
-8c79,2023-05-24,2023-01-13
-2c74,2005-12-02,2005-11-17
-4c7w,2013-10-16,2013-09-26
-6c72,2019-01-23,2018-01-19
-3c7n,2008-05-27,2008-02-07
-6c73,2019-01-23,2018-01-19
-1c7z,2003-06-10,2000-04-03
-7c7k,2021-05-26,2020-05-26
-2c7n,2006-02-15,2005-11-25
-8c78,2023-04-26,2023-01-13
-3c7h,2008-11-18,2008-02-07
-7c79,2020-07-08,2020-05-24
-6c7s,2018-04-18,2018-01-23
-3c7o,2008-11-18,2008-02-08
-3zbx,2013-11-27,2012-11-13
-7zbe,2023-03-29,2022-03-23
-2zba,2007-12-11,2007-10-18
-5zbu,2019-02-27,2018-02-12
-2zb4,2008-09-30,2007-10-16
-5zb1,2018-08-08,2018-02-09
-5zbd,2018-12-19,2018-02-11
-3zbz,2013-07-10,2012-11-14
-5zbh,2018-04-25,2018-02-11
-2zb8,2008-09-30,2007-10-16
-1zbk,2005-05-03,2005-04-08
-5zbc,2018-12-19,2018-02-11
-7zbz,2023-04-19,2022-03-24
-8zby,2024-05-15,2024-04-28
-6zbz,2021-06-23,2020-06-09
-1zbu,2006-09-19,2005-04-08
-5zbx,2019-02-13,2018-02-13
-6zbi,2021-03-17,2020-06-08
-2zby,2008-04-08,2007-10-30
-5zbm,2018-12-26,2018-02-12
-5zb2,2019-02-27,2018-02-09
-2zbf,2007-12-11,2007-10-20
-6zbq,2021-06-23,2020-06-09
-8zbz,2024-05-15,2024-04-28
-4zbe,2016-01-27,2015-04-14
-3zbr,2013-07-10,2012-11-13
-2zb7,2008-09-30,2007-10-16
-7zb9,2023-01-11,2022-03-23
-6zb3,2020-08-05,2020-06-06
-2zbp,2008-11-11,2007-10-26
-1zbz,2005-05-03,2005-04-09
-5zbk,2018-06-27,2018-02-12
-4zbk,2015-06-03,2015-04-14
-1zbc,2005-04-19,2005-04-08
-6zbn,2021-04-07,2020-06-08
-2zbe,2007-12-11,2007-10-20
-4zbt,2015-06-17,2015-04-15
-1zbh,2006-09-26,2005-04-08
-7zb1,2022-07-06,2022-03-23
-4zb8,2015-09-30,2015-04-14
-2zbd,2007-11-20,2007-10-20
-7zbf,2023-04-05,2022-03-23
-6zbt,2021-07-21,2020-06-09
-2zb6,2007-11-06,2007-10-16
-1zb6,2005-06-21,2005-04-07
-2zbw,2007-11-13,2007-10-30
-2zbh,2007-11-13,2007-10-20
-6zb1,2020-08-05,2020-06-06
-4zb6,2015-09-30,2015-04-14
-5zbq,2018-04-25,2018-02-12
-6zbr,2021-06-23,2020-06-09
-7zbb,2023-02-01,2022-03-23
-7zbp,2022-05-18,2022-03-24
-3zbp,2013-04-03,2012-11-12
-4zbc,2016-03-23,2015-04-14
-3zbn,2013-08-14,2012-11-11
-4zbm,2015-07-29,2015-04-14
-3zbq,2013-04-03,2012-11-12
-7zb2,2022-07-06,2022-03-23
-4zbf,2015-04-29,2015-04-14
-1zbi,2005-07-12,2005-04-08
-2zbg,2007-12-11,2007-10-20
-1zbq,2005-04-26,2005-04-08
-2zbx,2008-04-08,2007-10-30
-2zbv,2007-11-13,2007-10-30
-6zbo,2021-04-07,2020-06-08
-2zbc,2008-03-11,2007-10-19
-7zbd,2023-02-01,2022-03-23
-3zbu,2013-11-20,2012-11-13
-5zbl,2018-06-27,2018-02-12
-7zbv,2022-11-09,2022-03-24
-5zbs,2018-05-30,2018-02-12
-6zbs,2022-01-12,2020-06-09
-6zbw,2021-04-28,2020-06-09
-4zba,2015-09-30,2015-04-14
-3zbt,2013-11-20,2012-11-13
-7zbu,2022-08-17,2022-03-24
-3zbw,2012-12-26,2012-11-13
-3zbf,2013-06-12,2012-11-08
-7zbo,2022-04-06,2022-03-24
-6zba,2020-09-23,2020-06-08
-5zbr,2018-05-30,2018-02-12
-4zbd,2015-09-30,2015-04-14
-2zb2,2008-09-02,2007-10-15
-2zb1,2008-01-15,2007-10-13
-4zbv,2016-03-23,2015-04-15
-3zbv,2012-12-26,2012-11-13
-2zb3,2008-09-30,2007-10-16
-7zb0,2022-07-06,2022-03-23
-7zbg,2022-05-25,2022-03-23
-6zb4,2020-09-30,2020-06-06
-5zb8,2018-04-04,2018-02-10
-4zb2,2016-03-23,2015-04-14
-2zbq,2008-11-11,2007-10-26
-4zbg,2015-04-29,2015-04-14
-6zb6,2020-12-09,2020-06-07
-4zbr,2015-12-23,2015-04-15
-5zbi,2018-05-09,2018-02-12
-5zbz,2019-02-20,2018-02-14
-6zb0,2020-08-05,2020-06-06
-6zb2,2020-08-05,2020-06-06
-6zbp,2020-07-29,2020-06-08
-5zba,2018-07-25,2018-02-10
-5zb4,2018-12-19,2018-02-09
-4zbp,2015-09-09,2015-04-15
-1zby,2005-05-03,2005-04-09
-5zb3,2018-08-08,2018-02-09
-3zbm,2013-04-03,2012-11-10
-4zb9,2015-09-30,2015-04-14
-1zbd,1999-04-02,1998-11-06
-7zbh,2023-04-05,2022-03-23
-7zba,2023-02-01,2022-03-23
-1zb7,2005-07-05,2005-04-07
-2zbu,2007-11-13,2007-10-30
-3zby,2013-02-27,2012-11-13
-6zb5,2020-09-30,2020-06-07
-4zbi,2015-04-29,2015-04-14
-4zb0,2016-03-23,2015-04-14
-2zbj,2008-08-19,2007-10-22
-2zbz,2008-04-08,2007-10-30
-3zbs,2013-07-10,2012-11-13
-2zbr,2008-11-11,2007-10-26
-5zbf,2019-02-13,2018-02-11
-7zb3,2023-04-05,2022-03-23
-1zbg,2006-04-18,2005-04-08
-2zbk,2008-02-12,2007-10-22
-4zby,2015-09-09,2015-04-15
-2zbo,2008-09-30,2007-10-26
-5zbe,2019-02-13,2018-02-11
-6zbx,2021-04-28,2020-06-09
-1zb5,2005-05-10,2005-04-07
-6zbm,2021-04-28,2020-06-08
-4zbq,2015-12-23,2015-04-15
-2zbl,2008-02-05,2007-10-24
-6zbv,2021-03-17,2020-06-09
-1zbw,2005-04-26,2005-04-09
-2zb0,2008-01-15,2007-10-13
-5zb0,2018-12-19,2018-02-09
-1zbv,2005-04-26,2005-04-09
-1zbl,2005-07-12,2005-04-08
-2zb5,2007-11-06,2007-10-16
-2zbm,2008-07-29,2007-10-24
-1zba,2005-06-28,2005-04-08
-4zbb,2015-09-30,2015-04-14
-4zb5,2016-03-23,2015-04-14
-7zbc,2023-03-29,2022-03-23
-7sqw,2022-10-12,2021-11-07
-1sqn,2004-07-27,2004-03-19
-5sq9,2022-07-06,2022-06-09
-6sq4,2020-09-30,2019-09-03
-6sqz,2020-01-29,2019-09-04
-5sqb,2022-07-06,2022-06-09
-5sqn,2022-07-06,2022-06-09
-5sqk,2022-07-06,2022-06-09
-5sqx,2022-07-06,2022-06-09
-5sq4,2022-07-06,2022-06-09
-7sqh,2022-02-23,2021-11-05
-5sqf,2022-07-06,2022-06-09
-5sqi,2022-07-06,2022-06-09
-8sqn,2023-12-20,2023-05-04
-7sq1,2022-06-22,2021-11-04
-3sqg,2011-11-30,2011-07-05
-7sqe,2021-11-17,2021-11-05
-1sqi,2004-08-17,2004-03-18
-8sqw,2023-11-15,2023-05-04
-7sql,2022-10-12,2021-11-05
-1sqz,2004-04-13,2004-03-22
-5sq1,2022-07-06,2022-06-09
-6sq0,2019-10-30,2019-09-03
-7sqg,2022-02-23,2021-11-05
-7sq4,2022-06-29,2021-11-04
-8sqf,2024-01-03,2023-05-04
-1sqf,2004-05-18,2004-03-18
-7sq0,2022-07-20,2021-11-04
-3sq4,2011-11-09,2011-07-04
-6sqq,2020-05-13,2019-09-04
-7sqv,2022-07-27,2021-11-06
-5sq3,2022-07-06,2022-06-09
-8sqq,2023-05-17,2023-05-04
-3sqx,2011-10-12,2011-07-06
-7sqn,2022-01-19,2021-11-05
-5sqd,2022-07-06,2022-06-09
-5sqo,2022-07-06,2022-06-09
-6sq3,2020-09-30,2019-09-03
-5sqy,2022-07-06,2022-06-09
-8sq8,2024-05-22,2023-05-04
-1sqo,2004-04-27,2004-03-19
-5sql,2022-07-06,2022-06-09
-5sqc,2022-07-06,2022-06-09
-6sqr,2020-05-06,2019-09-04
-8sqo,2023-05-17,2023-05-04
-1sqp,2005-11-01,2004-03-19
-5sqw,2022-07-06,2022-06-09
-3sq2,2011-11-09,2011-07-04
-3sqq,2012-10-31,2011-07-06
-1sq3,2005-04-12,2004-03-17
-6sqd,2020-04-22,2019-09-03
-7sq2,2021-11-17,2021-11-04
-8sqv,2023-08-09,2023-05-04
-3sqw,2011-10-12,2011-07-06
-6squ,2021-01-13,2019-09-04
-7sq5,2022-11-09,2021-11-04
-8sqj,2023-11-22,2023-05-04
-5sq8,2022-07-06,2022-06-09
-5sq5,2022-07-06,2022-06-09
-7sq3,2022-06-29,2021-11-04
-1sqq,2005-10-25,2004-03-19
-3sqs,2011-07-27,2011-07-06
-5sqg,2022-07-06,2022-06-09
-8sqt,2023-05-17,2023-05-04
-6sqy,2020-01-29,2019-09-04
-5sqs,2022-07-06,2022-06-09
-6sqj,2020-09-30,2019-09-04
-5sqq,2022-07-06,2022-06-09
-6sqc,2020-09-30,2019-09-03
-5sq0,2022-07-06,2022-06-09
-6sqg,2019-11-06,2019-09-03
-5sqr,2022-07-06,2022-06-09
-5sqh,2022-07-06,2022-06-09
-7squ,2022-07-27,2021-11-06
-6sqi,2020-09-30,2019-09-04
-1sqd,2004-08-17,2004-03-18
-6sqs,2020-05-06,2019-09-04
-6sqk,2020-09-30,2019-09-04
-3sq6,2011-09-28,2011-07-05
-5sqe,2022-07-06,2022-06-09
-7sqo,2022-05-25,2021-11-05
-3sqy,2011-08-31,2011-07-06
-7sqa,2023-05-10,2021-11-05
-5sq2,2022-07-06,2022-06-09
-7sqi,2022-08-03,2021-11-05
-7sqb,2023-05-10,2021-11-05
-8sqk,2023-11-22,2023-05-04
-3sqz,2012-07-11,2011-07-06
-6sqw,2020-01-29,2019-09-04
-6sq7,2020-04-22,2019-09-03
-5squ,2022-07-06,2022-06-09
-8sqh,2024-05-01,2023-05-04
-6sql,2020-04-22,2019-09-04
-3sq9,2011-09-28,2011-07-05
-5sqa,2022-07-06,2022-06-09
-1sqx,2005-09-06,2004-03-21
-7sqs,2022-07-27,2021-11-06
-3sqm,2011-07-20,2011-07-05
-5sqp,2022-07-06,2022-06-09
-6sqb,2020-04-22,2019-09-03
-1sql,2004-06-08,2004-03-19
-7sq7,2022-02-02,2021-11-04
-5sqt,2022-07-06,2022-06-09
-5sq7,2022-07-06,2022-06-09
-6sq9,2020-04-22,2019-09-03
-8sqg,2024-01-03,2023-05-04
-8squ,2023-08-23,2023-05-04
-1sqt,2004-04-27,2004-03-19
-1sqm,2004-08-03,2004-03-19
-3sq0,2011-10-12,2011-07-04
-3sqp,2011-09-14,2011-07-06
-8sq7,2024-05-22,2023-05-04
-5sqz,2022-07-06,2022-06-09
-6sqm,2020-09-30,2019-09-04
-6sqf,2020-09-30,2019-09-03
-6sq2,2020-09-30,2019-09-03
-6sqe,2020-09-30,2019-09-03
-7sq6,2022-02-02,2021-11-04
-3sq1,2011-10-12,2011-07-04
-6sqo,2020-05-06,2019-09-04
-7sqm,2021-12-29,2021-11-05
-3sqr,2012-07-11,2011-07-06
-6sqp,2020-05-06,2019-09-04
-7sqf,2022-02-23,2021-11-05
-3sqd,2011-11-09,2011-07-05
-1sqk,2004-06-15,2004-03-19
-6sq8,2020-04-22,2019-09-03
-5sq6,2022-07-06,2022-06-09
-8sqr,2023-05-17,2023-05-04
-7sq8,2022-02-02,2021-11-04
-6sq1,2020-09-30,2019-09-03
-1sqy,2004-04-13,2004-03-22
-1sq5,2004-09-28,2004-03-17
-1sqv,2005-09-06,2004-03-19
-7sqc,2022-04-13,2021-11-05
-8sqp,2023-05-17,2023-05-04
-6sq5,2020-04-22,2019-09-03
-8sq9,2023-11-22,2023-05-04
-5sqv,2022-07-06,2022-06-09
-5sqm,2022-07-06,2022-06-09
-5sqj,2022-07-06,2022-06-09
-1sqb,2004-09-07,2004-03-18
-1sqa,2004-04-27,2004-03-18
-7y28,2023-07-05,2022-06-09
-4y2n,2016-08-10,2015-02-10
-6y21,2021-02-24,2020-02-14
-4y2i,2016-02-10,2015-02-10
-6y2l,2020-04-15,2020-02-16
-4y2w,2015-09-23,2015-02-10
-5y28,2018-08-15,2017-07-24
-1y22,2004-12-07,2004-11-19
-5y2p,2018-08-08,2017-07-26
-4y2r,2015-05-06,2015-02-10
-5y2j,2018-03-14,2017-07-26
-2y2h,2011-08-03,2010-12-15
-1y2w,2004-12-21,2004-11-23
-1y2e,2005-03-01,2004-11-22
-5y2o,2017-12-20,2017-07-26
-2y2b,2011-07-20,2010-12-14
-7y26,2022-10-19,2022-06-09
-6y2n,2020-10-07,2020-02-17
-6y22,2020-09-02,2020-02-14
-7y2g,2023-12-20,2022-06-09
-2y2x,2011-12-28,2010-12-16
-5y2z,2018-05-02,2017-07-27
-1y21,2004-11-30,2004-11-19
-2y2f,2011-03-16,2010-12-14
-5y2y,2017-09-06,2017-07-27
-5y2t,2017-12-20,2017-07-27
-6y2b,2020-12-23,2020-02-15
-2y2e,2011-07-20,2010-12-14
-5y2i,2018-08-08,2017-07-26
-2y24,2011-06-01,2010-12-13
-4y2q,2015-05-06,2015-02-10
-2y2o,2011-08-03,2010-12-15
-5y2r,2018-02-14,2017-07-27
-1y28,2004-12-07,2004-11-21
-5y29,2018-01-17,2017-07-24
-5y2c,2018-01-17,2017-07-24
-7y2u,2023-12-20,2022-06-09
-2y2l,2011-08-03,2010-12-15
-5y2l,2019-01-30,2017-07-26
-1y2f,2005-03-01,2004-11-22
-5y2s,2018-02-14,2017-07-27
-8y2h,2024-06-05,2024-01-26
-6y27,2020-12-23,2020-02-15
-4y2j,2015-05-06,2015-02-10
-4y2h,2015-04-22,2015-02-09
-4y2s,2015-05-06,2015-02-10
-6y2y,2021-06-16,2020-02-17
-1y2h,2005-03-01,2004-11-22
-7y2d,2023-07-05,2022-06-09
-2y28,2011-07-20,2010-12-14
-6y2x,2020-09-02,2020-02-17
-4y2m,2016-02-10,2015-02-10
-1y23,2004-12-07,2004-11-19
-4y24,2016-04-27,2015-02-09
-6y2u,2021-03-31,2020-02-17
-6y2i,2020-04-08,2020-02-16
-5y2q,2018-08-08,2017-07-26
-4y22,2016-04-06,2015-02-09
-5y2a,2018-01-17,2017-07-24
-7y2e,2023-12-20,2022-06-09
-7y2h,2023-12-20,2022-06-09
-4y2v,2015-05-06,2015-02-10
-1y2g,2005-03-01,2004-11-22
-1y2z,2004-12-07,2004-11-23
-4y2y,2015-05-06,2015-02-10
-7y2x,2023-12-20,2022-06-09
-7y2c,2023-12-20,2022-06-09
-2y2q,2011-08-03,2010-12-15
-2y2n,2011-08-03,2010-12-15
-4y28,2015-08-19,2015-02-09
-5y21,2018-07-25,2017-07-22
-5y2d,2018-08-15,2017-07-25
-4y23,2015-11-18,2015-02-09
-1y2j,2005-03-01,2004-11-22
-6y2t,2020-07-01,2020-02-17
-6y28,2020-12-23,2020-02-15
-4y2u,2015-05-06,2015-02-10
-4y2l,2016-08-10,2015-02-10
-1y2b,2005-03-01,2004-11-22
-5y23,2018-07-25,2017-07-23
-4y2g,2016-01-27,2015-02-09
-1y2k,2005-03-01,2004-11-22
-7y27,2022-10-19,2022-06-09
-4y20,2016-04-06,2015-02-09
-6y2z,2020-09-23,2020-02-17
-4y2b,2015-04-08,2015-02-09
-4y29,2015-09-09,2015-02-09
-4y2a,2015-04-01,2015-02-09
-1y2c,2005-03-01,2004-11-22
-2y2p,2011-08-03,2010-12-15
-4y2t,2015-05-06,2015-02-10
-5y2w,2017-12-27,2017-07-27
-6y2g,2020-03-04,2020-02-15
-7y2t,2023-12-20,2022-06-09
-5y20,2018-01-24,2017-07-22
-7y2v,2023-12-20,2022-06-09
-2y2v,2011-11-30,2010-12-16
-6y2c,2020-03-25,2020-02-15
-6y2m,2020-07-01,2020-02-17
-7y24,2022-10-19,2022-06-09
-4y2p,2015-05-06,2015-02-10
-5y2u,2018-08-08,2017-07-27
-5y2f,2018-11-07,2017-07-25
-1y2u,2004-12-21,2004-11-23
-2y2d,2011-07-20,2010-12-14
-5y2g,2019-02-27,2017-07-25
-7y2f,2023-12-20,2022-06-09
-5y2v,2017-12-27,2017-07-27
-7y2s,2023-12-20,2022-06-09
-2y2j,2011-08-03,2010-12-15
-2y2g,2011-08-03,2010-12-15
-1y2x,2004-12-21,2004-11-23
-7y2a,2023-12-20,2022-06-09
-7y2r,2023-12-20,2022-06-09
-2y2k,2011-08-03,2010-12-15
-1y2v,2004-12-21,2004-11-23
-4y2d,2015-05-27,2015-02-09
-4y26,2016-04-06,2015-02-09
-2y2u,2011-11-30,2010-12-16
-4y2o,2016-08-10,2015-02-10
-2y20,2011-07-20,2010-12-12
-6y2f,2020-03-04,2020-02-15
-1y2d,2005-03-01,2004-11-22
-7y20,2023-08-09,2022-06-09
-2y27,2011-05-04,2010-12-13
-1y20,2005-07-12,2004-11-19
-7y21,2023-08-09,2022-06-09
-2y2i,2011-08-03,2010-12-15
-7y2i,2023-12-20,2022-06-09
-5y2b,2018-01-17,2017-07-24
-5y2m,2019-02-13,2017-07-26
-4y2x,2015-05-06,2015-02-10
-2y2m,2011-08-03,2010-12-15
-6y2o,2020-09-30,2020-02-17
-6y2j,2020-04-08,2020-02-16
-7y2w,2023-12-20,2022-06-09
-5y24,2018-09-19,2017-07-24
-6y25,2020-07-01,2020-02-14
-5y25,2018-07-25,2017-07-24
-3whj,2014-03-26,2013-08-26
-7whj,2022-05-11,2021-12-30
-7wh6,2023-01-25,2021-12-30
-1wht,1994-06-22,1994-03-07
-7whi,2022-05-11,2021-12-30
-5why,2017-07-26,2017-07-18
-4wh7,2014-12-10,2014-09-20
-6wht,2020-08-05,2020-04-08
-4whw,2015-10-28,2014-09-23
-5whr,2017-12-27,2017-07-18
-7wh0,2022-02-02,2021-12-29
-7whp,2022-02-02,2021-12-31
-4wh2,2015-02-18,2014-09-19
-7whe,2023-01-25,2021-12-30
-3whn,2014-02-26,2013-08-29
-2wh8,2009-07-14,2009-05-01
-5whw,2017-08-02,2017-07-18
-7wht,2022-10-12,2021-12-31
-4whm,2015-01-21,2014-09-23
-2whm,2009-05-26,2009-05-05
-6wh8,2020-08-26,2020-04-07
-2whz,2010-05-12,2009-05-07
-7whd,2023-01-18,2021-12-30
-7whk,2022-05-11,2021-12-30
-5wht,2017-10-25,2017-07-18
-5whu,2017-10-25,2017-07-18
-2whr,2009-05-26,2009-05-06
-4wh8,2014-10-15,2014-09-20
-7whg,2022-09-21,2021-12-30
-5who,2018-09-19,2017-07-17
-5wha,2018-01-03,2017-07-16
-3whs,2014-02-19,2013-08-30
-5whs,2018-01-17,2017-07-18
-7whf,2022-09-21,2021-12-30
-6wh4,2020-09-23,2020-04-07
-4wh3,2015-02-18,2014-09-19
-3whe,2014-04-23,2013-08-25
-3whl,2014-03-26,2013-08-26
-6whf,2020-04-22,2020-04-08
-4whb,2015-02-11,2014-09-21
-3wh1,2014-03-26,2013-08-21
-6whq,2021-04-21,2020-04-08
-8wha,2024-04-17,2023-09-22
-2whb,2009-06-09,2009-05-03
-3wh3,2013-10-23,2013-08-21
-7whw,2022-03-23,2021-12-31
-5whg,2017-11-15,2017-07-17
-2whe,2009-09-15,2009-05-04
-2whj,2009-05-26,2009-05-05
-5whq,2018-01-17,2017-07-18
-6why,2020-07-15,2020-04-08
-2why,2009-09-29,2009-05-07
-5wh6,2018-07-18,2017-07-14
-4wh5,2014-11-05,2014-09-20
-4whc,2015-10-07,2014-09-22
-4whs,2014-12-31,2014-09-23
-7wh7,2023-01-25,2021-12-30
-6whm,2021-02-03,2020-04-08
-2whp,2009-06-30,2009-05-06
-3wh6,2014-09-03,2013-08-21
-4wh9,2014-12-10,2014-09-20
-4whl,2014-12-03,2014-09-23
-7whs,2022-09-21,2021-12-31
-4wh6,2014-10-08,2014-09-20
-6wh0,2021-03-17,2020-04-07
-2who,2009-08-11,2009-05-05
-6whx,2020-07-15,2020-04-08
-3wh8,2014-09-03,2013-08-21
-2whl,2009-05-26,2009-05-05
-7whb,2023-01-18,2021-12-30
-6whk,2021-04-14,2020-04-08
-5whh,2018-01-17,2017-07-17
-5wh5,2018-07-18,2017-07-14
-5whb,2018-01-03,2017-07-16
-6wha,2020-09-23,2020-04-07
-6whn,2021-04-21,2020-04-08
-4whk,2014-12-03,2014-09-23
-5whp,2018-05-23,2017-07-17
-5whd,2018-01-03,2017-07-16
-5whm,2017-08-23,2017-07-17
-3wh7,2014-09-03,2013-08-21
-7whh,2022-06-01,2021-12-30
-3whw,2014-02-12,2013-09-03
-4whz,2014-11-26,2014-09-24
-4whi,2014-10-08,2014-09-22
-2whk,2009-05-26,2009-05-05
-5whe,2018-01-03,2017-07-16
-4whh,2014-12-03,2014-09-22
-2whf,2009-07-14,2009-05-04
-2whh,2009-12-01,2009-05-05
-5whn,2018-04-25,2017-07-17
-7wh5,2022-11-16,2021-12-29
-6whz,2021-04-21,2020-04-08
-2wh5,2009-07-28,2009-04-30
-2whq,2009-06-30,2009-05-06
-6whe,2021-03-10,2020-04-08
-7wha,2023-01-25,2021-12-30
-5whc,2017-12-13,2017-07-16
-3whm,2014-10-15,2013-08-27
-3wh2,2013-10-23,2013-08-21
-4whr,2014-12-31,2014-09-23
-6whw,2020-07-15,2020-04-08
-5whv,2017-10-25,2017-07-18
-6whs,2020-08-05,2020-04-08
-7wh1,2022-02-02,2021-12-29
-6wh6,2021-04-21,2020-04-07
-8wh8,2024-04-17,2023-09-22
-7whu,2022-07-06,2021-12-31
-6whu,2020-08-05,2020-04-08
-4who,2014-12-31,2014-09-23
-1whs,1994-06-22,1994-03-07
-5whl,2018-09-19,2017-07-17
-7whv,2022-03-23,2021-12-31
-4whg,2015-09-09,2014-09-22
-3whb,2014-03-19,2013-08-23
-4whq,2014-12-31,2014-09-23
-4whx,2014-10-08,2014-09-23
-4whf,2015-09-09,2014-09-22
-3whp,2014-09-03,2013-08-30
-6whr,2020-08-05,2020-04-08
-2whi,2009-09-01,2009-05-05
-2whg,2010-05-19,2009-05-05
-7whz,2022-06-22,2022-01-01
-4whu,2015-10-28,2014-09-23
-3whi,2013-12-25,2013-08-26
-8wh9,2024-04-17,2023-09-22
-2whw,2009-10-27,2009-05-07
-6who,2021-04-21,2020-04-08
-2whv,2010-04-21,2009-05-07
-3whx,2014-09-10,2013-09-03
-6wh3,2020-04-22,2020-04-07
-3whd,2013-10-23,2013-08-24
-6whv,2020-08-05,2020-04-08
-4wha,2014-11-12,2014-09-21
-3whu,2014-01-15,2013-08-30
-3wh5,2014-09-03,2013-08-21
-4whp,2014-12-31,2014-09-23
-3whk,2014-03-26,2013-08-26
-3wh9,2014-10-08,2013-08-22
-7wh4,2022-02-09,2021-12-29
-2whx,2010-04-07,2009-05-07
-2whd,2009-09-01,2009-05-04
-2wh0,2009-08-18,2009-04-28
-7wh9,2023-01-11,2021-12-30
-3wha,2014-01-29,2013-08-23
-6whd,2020-06-24,2020-04-08
-6wh5,2021-01-20,2020-04-07
-3wht,2014-01-15,2013-08-30
-5whx,2017-08-02,2017-07-18
-6whg,2021-04-21,2020-04-08
-4whv,2015-09-30,2014-09-23
-3lds,2010-06-02,2010-01-13
-4ldo,2013-09-25,2013-06-24
-6ldv,2020-11-25,2019-11-23
-7ld5,2021-06-30,2021-01-12
-3ldp,2011-01-26,2010-01-13
-6ldx,2020-11-25,2019-11-23
-5ld1,2017-06-21,2016-06-23
-3ldd,2010-08-11,2010-01-12
-7ldx,2021-01-20,2021-01-14
-5ldv,2016-10-26,2016-06-28
-3ldc,2010-08-11,2010-01-12
-3ld0,2010-02-23,2010-01-12
-4ldt,2013-08-14,2013-06-25
-6ldg,2021-03-03,2019-11-21
-6ldo,2020-10-07,2019-11-22
-5ldb,2017-06-21,2016-06-24
-9ldb,1993-10-31,1991-11-26
-6ldl,2020-10-28,2019-11-21
-5ldx,2016-09-14,2016-06-28
-3ldi,2010-06-23,2010-01-13
-6ld9,2020-11-25,2019-11-20
-1lde,1997-04-01,1996-12-25
-4ld4,2014-01-22,2013-06-24
-4ldl,2013-09-25,2013-06-24
-1ldp,1998-06-17,1998-03-15
-1ldc,1995-07-10,1995-04-13
-5ld9,2017-05-17,2016-06-24
-1ld3,2003-05-20,2002-04-08
-5ldu,2016-08-10,2016-06-27
-5ldg,2016-08-31,2016-06-26
-5ldf,2016-08-10,2016-06-25
-7ld1,2021-01-27,2021-01-12
-5ldr,2016-09-14,2016-06-27
-6lde,2021-03-03,2019-11-21
-6ldc,2021-01-27,2019-11-20
-1ldf,2002-05-08,2002-04-08
-1lds,2002-07-31,2002-04-09
-5ldp,2017-01-18,2016-06-27
-5ldk,2017-01-18,2016-06-27
-3ldg,2011-01-19,2010-01-13
-6ld8,2020-11-25,2019-11-20
-1ldq,2002-11-06,2002-04-09
-6ldi,2020-09-30,2019-11-21
-6ldf,2021-03-03,2019-11-21
-1ld8,2002-06-19,2002-04-08
-3ldx,2011-08-10,2010-01-13
-6ldy,2020-11-25,2019-11-23
-3ldy,2010-04-21,2010-01-13
-6ldr,2020-12-02,2019-11-23
-5ldq,2017-01-18,2016-06-27
-3ldq,2011-01-26,2010-01-13
-5ldh,1981-03-04,1980-10-29
-5ldz,2016-10-26,2016-06-29
-1ld9,1998-05-06,1997-04-24
-2ldb,1989-07-12,1989-03-27
-3ldk,2010-05-12,2010-01-13
-7ldl,2021-07-07,2021-01-13
-7lde,2021-05-12,2021-01-13
-3ldf,2011-01-19,2010-01-13
-3ldo,2011-01-26,2010-01-13
-5ld2,2016-10-05,2016-06-23
-4ldz,2014-07-16,2013-06-25
-1ld7,2002-06-19,2002-04-08
-4ldj,2014-06-04,2013-06-24
-2ldr,2011-12-14,2011-06-01
-3ld5,2010-12-15,2010-01-12
-7ldw,2021-09-01,2021-01-14
-6lds,2020-12-02,2019-11-23
-7ld8,2021-01-20,2021-01-12
-3ldv,2010-01-26,2010-01-13
-4ld7,2013-12-11,2013-06-24
-4ld2,2014-01-22,2013-06-24
-7ld2,2021-09-01,2021-01-12
-7ldj,2021-05-05,2021-01-13
-9ldt,1993-10-31,1991-11-26
-5ldw,2016-09-07,2016-06-28
-5ldm,2017-01-18,2016-06-27
-5ldo,2017-01-18,2016-06-27
-3lde,2010-08-11,2010-01-12
-4ldc,2013-09-11,2013-06-24
-7ld9,2022-02-23,2021-01-12
-6ldb,2021-01-27,2019-11-20
-6ldt,2020-12-02,2019-11-23
-1ldy,1997-04-21,1996-12-23
-6ld1,2020-08-12,2019-11-20
-6ld4,2020-08-19,2019-11-20
-5ld8,2016-09-21,2016-06-23
-6ldw,2020-11-25,2019-11-23
-3ldu,2010-01-26,2010-01-13
-6ldk,2020-11-04,2019-11-21
-5lda,2017-06-21,2016-06-24
-7ldd,2021-05-12,2021-01-13
-5ld5,2017-07-12,2016-06-23
-3ld4,2010-06-02,2010-01-12
-3ld8,2010-08-04,2010-01-12
-6ld0,2021-01-27,2019-11-20
-6ldu,2021-05-26,2019-11-23
-3ldr,2010-05-12,2010-01-13
-6ldd,2021-01-27,2019-11-20
-1ldg,1997-09-17,1996-09-10
-7ld3,2021-09-08,2021-01-12
-7ldg,2021-08-11,2021-01-13
-2ld1,2011-06-08,2011-05-13
-7ldy,2022-07-06,2021-01-14
-3ld2,2011-01-12,2010-01-12
-7ldv,2021-09-01,2021-01-14
-7ldu,2021-09-01,2021-01-14
-3ldw,2010-11-17,2010-01-13
-1ldt,1998-05-20,1997-05-15
-7ld4,2021-09-08,2021-01-12
-7ldt,2021-09-01,2021-01-14
-4ldk,2014-07-16,2013-06-24
-7ldq,2021-01-27,2021-01-13
-7ldc,2021-09-01,2021-01-13
-6ldm,2020-03-18,2019-11-22
-1ldj,2002-05-08,2002-04-08
-7ldz,2022-07-06,2021-01-14
-1ldk,2002-05-08,2002-04-08
-1ldn,1994-01-31,1991-11-19
-5ldt,2016-10-26,2016-06-27
-4lde,2013-09-25,2013-06-24
-6ld5,2020-08-19,2019-11-20
-3ldb,2010-08-04,2010-01-12
-5lds,2017-04-05,2016-06-27
-6ld2,2020-08-12,2019-11-20
-1ldo,2002-11-06,2002-04-09
-6ld3,2020-08-19,2019-11-20
-3ldl,2011-01-26,2010-01-13
-3ld6,2010-02-02,2010-01-12
-2ldo,2011-09-07,2011-05-30
-5he4,2016-03-16,2016-01-05
-2hev,2006-08-29,2006-06-22
-8hen,2023-12-13,2022-11-08
-4hee,2013-08-21,2012-10-03
-4hec,2012-10-17,2012-10-03
-1heb,1992-10-15,1992-07-16
-2heu,2007-06-05,2006-06-22
-5he2,2016-05-11,2016-01-05
-6he2,2019-08-28,2018-08-20
-1hec,1992-10-15,1992-07-16
-6hez,2018-08-29,2018-08-21
-8he2,2023-05-31,2022-11-07
-4he1,2013-10-09,2012-10-03
-6he0,2019-08-28,2018-08-20
-5hed,2016-11-16,2016-01-05
-4hei,2012-10-24,2012-10-03
-3heo,2009-12-29,2009-05-09
-5he0,2016-05-11,2016-01-05
-5he7,2016-03-16,2016-01-05
-6he3,2019-12-04,2018-08-20
-3hej,2010-05-19,2009-05-08
-8heo,2023-11-15,2022-11-08
-3her,2010-01-12,2009-05-10
-4hex,2013-03-06,2012-10-04
-8hei,2023-12-13,2022-11-08
-2hen,2007-02-13,2006-06-21
-1heg,1994-05-31,1992-09-21
-6hef,2018-08-29,2018-08-20
-2heo,2006-11-21,2006-06-21
-8he5,2023-07-05,2022-11-07
-4heu,2012-12-12,2012-10-04
-2hes,2007-07-03,2006-06-22
-4he7,2013-03-27,2012-10-03
-4hey,2013-10-23,2012-10-04
-5hey,2016-11-16,2016-01-06
-2hek,2006-07-04,2006-06-21
-6hea,2018-12-26,2018-08-20
-5hee,2016-06-29,2016-01-06
-5hez,2016-11-09,2016-01-06
-8he3,2023-02-22,2022-11-07
-6he4,2018-12-26,2018-08-20
-8he7,2023-11-08,2022-11-07
-8hew,2023-09-20,2022-11-08
-6he5,2018-12-26,2018-08-20
-2hei,2006-07-04,2006-06-21
-3he6,2009-07-28,2009-05-07
-6hex,2019-08-28,2018-08-20
-6heb,2018-08-29,2018-08-20
-6hec,2018-12-26,2018-08-20
-1he3,2001-02-28,2000-11-18
-5he5,2016-03-16,2016-01-05
-4heg,2013-08-21,2012-10-03
-8heb,2023-04-26,2022-11-08
-1he5,2001-02-28,2000-11-19
-3he7,2009-07-28,2009-05-08
-5hei,2016-04-06,2016-01-06
-5heb,2016-11-16,2016-01-05
-3hek,2009-09-29,2009-05-08
-2hew,2006-08-29,2006-06-22
-2heg,2008-03-04,2006-06-21
-1he2,2001-02-28,2000-11-18
-8hec,2023-04-26,2022-11-08
-6he6,2019-04-24,2018-08-20
-4hev,2013-01-23,2012-10-04
-6hev,2019-08-28,2018-08-20
-1het,2001-05-31,2000-11-25
-1hei,1998-10-07,1997-03-31
-3he3,2009-12-29,2009-05-07
-4hea,2013-02-13,2012-10-03
-6hew,2019-08-28,2018-08-20
-1hex,1994-12-20,1994-09-09
-4hew,2013-10-23,2012-10-04
-8he4,2023-05-31,2022-11-07
-1hes,2001-05-31,2000-11-24
-4hes,2012-10-17,2012-10-04
-6he8,2018-12-26,2018-08-20
-3hes,2010-01-12,2009-05-10
-4he0,2013-10-09,2012-10-03
-8hej,2023-11-15,2022-11-08
-1hee,2001-11-23,2000-11-22
-8he6,2022-11-30,2022-11-07
-8he1,2023-05-31,2022-11-07
-3hec,2009-11-10,2009-05-08
-2het,2006-10-17,2006-06-22
-1hea,1992-10-15,1992-07-16
-1he8,2001-01-08,2000-11-20
-4hej,2012-10-24,2012-10-03
-3heq,2010-01-12,2009-05-10
-8het,2023-12-13,2022-11-08
-4he9,2013-08-21,2012-10-03
-8hes,2023-11-08,2022-11-08
-5hev,2016-11-16,2016-01-06
-3heg,2009-11-10,2009-05-08
-1he1,2001-01-02,2000-11-18
-6hed,2018-12-26,2018-08-20
-4heo,2013-10-09,2012-10-04
-1he4,2001-02-28,2000-11-19
-1hed,1992-10-15,1992-07-16
-6heu,2019-08-28,2018-08-20
-4hez,2013-10-23,2012-10-04
-4hef,2013-06-05,2012-10-03
-4he2,2013-10-09,2012-10-03
-6hes,2019-08-28,2018-08-20
-3hee,2009-11-10,2009-05-08
-8hez,2023-11-15,2022-11-09
-6hem,2019-03-27,2018-08-20
-2he5,2006-12-05,2006-06-21
-5hex,2016-03-30,2016-01-06
-2heh,2006-07-18,2006-06-21
-2hej,2006-12-05,2006-06-21
-8hef,2023-04-19,2022-11-08
-6heg,2018-09-12,2018-08-20
-6he1,2019-12-04,2018-08-20
-1hew,1994-01-31,1992-01-20
-6hey,2019-08-28,2018-08-20
-4heq,2013-01-30,2012-10-04
-1heu,2001-05-31,2000-11-26
-6he9,2018-12-26,2018-08-20
-5he1,2016-05-11,2016-01-05
-3hen,2009-12-29,2009-05-09
-1hef,1994-05-31,1992-09-21
-8he9,2023-12-13,2022-11-07
-5he9,2016-06-08,2016-01-05
-3hep,2009-12-29,2009-05-09
-5hes,2016-03-30,2016-01-06
-8hed,2023-04-26,2022-11-08
-8he8,2023-11-08,2022-11-07
-6het,2019-08-28,2018-08-20
-8heh,2022-12-21,2022-11-08
-5he3,2016-05-11,2016-01-05
-188l,1995-07-10,1995-04-19
-6tc2,2020-11-11,2019-11-04
-5tcd,2017-03-22,2016-09-14
-6tcu,2020-09-16,2019-11-06
-6tcy,2020-11-04,2019-11-06
-1tcc,1994-05-31,1994-02-28
-1tc1,1999-10-07,1998-09-30
-5tck,2016-11-09,2016-09-15
-1tc2,2000-03-08,1998-11-04
-8tcw,2024-03-06,2023-07-02
-5tcw,2017-09-20,2016-09-15
-7tch,2022-04-06,2021-12-23
-3tc1,2011-08-31,2011-08-08
-5tcx,2016-11-09,2016-09-16
-5tc9,2017-01-04,2016-09-14
-8tcy,2024-03-06,2023-07-02
-6tcj,2021-10-13,2019-11-06
-7tcg,2022-04-06,2021-12-23
-7tc6,2022-06-22,2021-12-22
-6tcz,2020-08-26,2019-11-07
-8tcu,2024-03-06,2023-07-02
-5tco,2017-04-19,2016-09-15
-5tc7,2017-10-11,2016-09-14
-7tcn,2023-08-02,2021-12-27
-1tc6,2004-08-24,2004-05-20
-7tcp,2022-07-06,2021-12-27
-5tcf,2017-05-31,2016-09-15
-5tc3,2017-06-14,2016-09-14
-1tcb,1994-05-31,1994-02-28
-5tcg,2017-05-31,2016-09-15
-5tc4,2016-12-14,2016-09-14
-7tc4,2022-06-22,2021-12-22
-7tcr,2022-03-23,2021-12-28
-7tcl,2022-08-31,2021-12-26
-6tca,2020-07-22,2019-11-05
-5tc0,2017-01-25,2016-09-13
-6tcx,2019-12-04,2019-11-06
-3tcs,2011-08-31,2011-08-09
-7tci,2022-07-06,2021-12-23
-7tct,2022-08-17,2021-12-28
-3tcz,2012-06-20,2011-08-09
-6tc5,2020-05-06,2019-11-05
-1tcx,1996-12-07,1996-06-05
-3tc8,2011-08-24,2011-08-08
-1tcv,2005-05-24,2004-05-21
-5tcc,2016-10-19,2016-09-14
-8tc1,2024-05-01,2023-06-29
-5tcy,2017-04-12,2016-09-16
-6tce,2019-11-20,2019-11-05
-6tcf,2020-08-19,2019-11-05
-3tcp,2012-06-20,2011-08-09
-7tcu,2022-03-23,2021-12-28
-1tcw,1996-12-07,1996-06-05
-7tcs,2022-06-01,2021-12-28
-6tc6,2020-10-14,2019-11-05
-7tc2,2022-12-21,2021-12-22
-2tcl,1996-03-08,1994-09-07
-5tca,2016-10-19,2016-09-14
-2tci,1996-01-29,1995-09-13
-2tct,1996-04-03,1995-03-02
-6tc7,2020-05-06,2019-11-05
-7tc1,2022-03-02,2021-12-22
-8tce,2024-05-08,2023-06-30
-3tcy,2012-08-22,2011-08-09
-6tc4,2020-03-18,2019-11-05
-8tc9,2024-02-07,2023-06-30
-7tcm,2022-01-12,2021-12-27
-5tc5,2017-10-11,2016-09-14
-3tc5,2011-08-31,2011-08-08
-1tc8,2004-06-08,2004-05-21
-8tcx,2024-03-06,2023-07-02
-7tc0,2022-01-26,2021-12-22
-8tc0,2024-05-01,2023-06-29
-5tc6,2017-10-11,2016-09-14
-1tc0,2004-08-24,2004-05-20
-3tcu,2011-10-05,2011-08-09
-7tc7,2023-01-25,2021-12-23
-5tcm,2016-10-05,2016-09-15
-7tce,2023-01-18,2021-12-23
-3tc3,2012-11-07,2011-08-08
-3tcg,2011-10-12,2011-08-09
-6tch,2020-07-01,2019-11-06
-5tcu,2017-05-24,2016-09-15
-7tcy,2023-01-11,2021-12-29
-7tc8,2023-01-25,2021-12-23
-7tcd,2023-07-05,2021-12-23
-5tci,2017-05-31,2016-09-15
-6tc1,2020-08-19,2019-11-04
-6tcv,2020-02-26,2019-11-06
-3tce,2011-08-31,2011-08-09
-8tco,2023-08-09,2023-07-02
-8tc5,2024-05-15,2023-06-29
-8tcv,2024-03-06,2023-07-02
-3tcx,2011-08-31,2011-08-09
-5tcv,2017-09-20,2016-09-15
-5tcj,2017-05-31,2016-09-15
-7tcz,2022-01-12,2021-12-29
-8tc8,2024-02-07,2023-06-30
-6tcl,2020-02-19,2019-11-06
-8tcg,2023-09-27,2023-06-30
-1tca,1994-05-31,1994-02-28
-7tcc,2022-03-30,2021-12-23
-8tcf,2023-09-27,2023-06-30
-1tcf,1998-05-27,1998-03-04
-8tcz,2024-03-06,2023-07-02
-6tcw,2020-02-26,2019-11-06
-1tcs,1995-07-10,1994-12-27
-6tcb,2020-11-18,2019-11-05
-3tct,2012-05-30,2011-08-09
-3tcm,2012-07-18,2011-08-09
-5tc8,2017-10-11,2016-09-14
-7tcw,2022-03-23,2021-12-28
-7tcx,2022-03-23,2021-12-28
-1tcm,1997-04-21,1996-10-07
-5tcs,2016-11-23,2016-09-15
-7tca,2022-03-30,2021-12-23
-7tc5,2022-06-22,2021-12-22
-1tco,1997-02-12,1996-08-21
-7tco,2023-08-02,2021-12-27
-6tc9,2020-09-16,2019-11-05
-6tck,2020-09-23,2019-11-06
-1tcr,1997-03-12,1996-09-12
-7tc9,2022-03-30,2021-12-23
-1vjy,2004-08-31,2004-04-07
-5vjl,2017-05-24,2017-04-19
-6vj8,2020-09-16,2020-01-15
-7vjv,2022-02-02,2021-09-29
-6vjd,2020-02-26,2020-01-15
-3vj6,2012-03-14,2011-10-12
-5vjd,2018-04-11,2017-04-19
-5vjk,2017-05-24,2017-04-19
-2vja,2008-07-22,2007-12-09
-6vja,2020-02-26,2020-01-15
-6vjb,2020-04-15,2020-01-15
-7vj5,2022-03-09,2021-09-28
-3vjl,2012-10-24,2011-10-24
-7vj1,2022-03-09,2021-09-28
-5vjs,2018-04-25,2017-04-19
-6vjs,2020-10-07,2020-01-17
-3vjk,2012-10-24,2011-10-24
-6vjm,2020-06-10,2020-01-16
-7vju,2022-04-13,2021-09-28
-1vj3,2004-01-20,2004-01-13
-7vj2,2022-03-09,2021-09-28
-2vjf,2008-05-13,2007-12-10
-3vjo,2012-03-07,2011-10-27
-8vjk,2024-01-17,2024-01-07
-5vjm,2017-05-24,2017-04-19
-3vjm,2012-08-15,2011-10-24
-7vjl,2022-02-23,2021-09-28
-1vja,2004-06-22,2004-02-03
-6vjc,2020-11-25,2020-01-15
-8vj3,2024-01-17,2024-01-05
-3vji,2012-08-29,2011-10-20
-1vjr,2004-03-30,2004-03-22
-6vjh,2021-02-10,2020-01-16
-2vje,2008-05-13,2007-12-10
-7vja,2022-03-09,2021-09-28
-1vjo,2004-03-23,2004-03-16
-1vji,2004-03-16,2004-02-24
-7vjb,2022-03-09,2021-09-28
-2vjp,2008-01-15,2007-12-11
-7vjs,2022-02-02,2021-09-28
-2vj7,2008-01-29,2007-12-06
-7vjo,2021-10-20,2021-09-28
-1vjt,2004-03-30,2004-03-22
-6vje,2020-03-11,2020-01-15
-2vjc,2008-07-22,2007-12-09
-2vjb,2008-07-22,2007-12-09
-1vj0,2004-03-02,2003-12-02
-5vjv,2018-03-21,2017-04-20
-5vjn,2017-12-27,2017-04-19
-3vje,2012-04-11,2011-10-14
-7vj8,2022-03-09,2021-09-28
-3vjh,2012-08-29,2011-10-20
-3vjn,2012-03-07,2011-10-27
-1vjm,2004-04-06,2004-03-12
-7vjc,2022-03-09,2021-09-28
-3vjf,2012-03-28,2011-10-18
-8vj2,2024-01-17,2024-01-05
-6vjx,2021-01-20,2020-01-18
-2vj1,2008-07-01,2007-12-06
-6vjf,2020-02-19,2020-01-15
-5vjg,2017-05-03,2017-04-19
-5vjt,2018-04-25,2017-04-19
-2vjv,2008-02-19,2007-12-13
-3vj9,2012-04-11,2011-10-14
-5vja,2018-08-08,2017-04-19
-1vj5,2004-04-27,2004-02-03
-2vjt,2008-03-25,2007-12-13
-2vjd,2008-07-22,2007-12-09
-1vj6,2005-11-01,2004-02-03
-6vju,2020-02-05,2020-01-17
-7vje,2022-03-09,2021-09-28
-2vj9,2008-01-29,2007-12-07
-1vj2,2003-12-09,2003-12-03
-5vjh,2017-07-05,2017-04-19
-5vjp,2017-12-27,2017-04-19
-2vjm,2007-12-25,2007-12-11
-5vje,2018-04-11,2017-04-19
-8vjn,2024-05-08,2024-01-07
-7vj0,2022-03-09,2021-09-28
-5vjj,2017-08-30,2017-04-19
-2vjj,2008-07-01,2007-12-11
-7vjt,2022-09-28,2021-09-28
-5vjw,2018-03-21,2017-04-20
-6vjr,2021-01-27,2020-01-17
-6vj3,2020-03-11,2020-01-14
-6vjj,2020-11-25,2020-01-16
-2vjo,2007-12-25,2007-12-11
-1vje,2004-02-10,2004-02-03
-5vjz,2017-11-01,2017-04-20
-3vj7,2011-11-02,2011-10-13
-6vjn,2021-01-20,2020-01-16
-1vj7,2004-05-04,2004-02-03
-6vjv,2020-02-19,2020-01-17
-2vj3,2008-07-29,2007-12-06
-2vj0,2007-12-25,2007-12-06
-7vjj,2022-03-09,2021-09-28
-6vjk,2020-12-23,2020-01-16
-2vjy,2009-01-27,2007-12-14
-7vji,2022-03-09,2021-09-28
-7vj6,2022-03-09,2021-09-28
-1vj9,2004-06-22,2004-02-03
-2vjk,2007-12-25,2007-12-11
-7vj3,2022-03-09,2021-09-28
-6vjl,2020-12-23,2020-01-16
-7vj9,2022-03-09,2021-09-28
-2vju,2008-02-19,2007-12-13
-1vjb,2004-06-08,2004-02-03
-7vj4,2022-03-09,2021-09-28
-7vjg,2022-03-09,2021-09-28
-7vjh,2022-03-09,2021-09-28
-2vjh,2008-03-25,2007-12-10
-8vjj,2024-01-17,2024-01-07
-2vjx,2008-04-01,2007-12-14
-3vjc,2012-04-11,2011-10-14
-6vj7,2020-04-29,2020-01-15
-2vjr,2008-03-25,2007-12-12
-1vjc,2004-03-30,2004-02-03
-8vjo,2024-05-08,2024-01-07
-2vjz,2008-09-16,2007-12-14
-2vj6,2008-01-29,2007-12-06
-6vji,2020-08-12,2020-01-16
-5vj1,2017-08-16,2017-04-18
-2vj8,2008-01-15,2007-12-07
-5vjf,2018-04-11,2017-04-19
-5vju,2018-04-25,2017-04-19
-7vjk,2022-03-09,2021-09-28
-5vj5,2017-05-03,2017-04-18
-5vj7,2017-07-19,2017-04-18
-2vjl,2007-12-25,2007-12-11
-6vjp,2020-05-06,2020-01-16
-5vjo,2018-04-11,2017-04-19
-5vj3,2018-04-18,2017-04-18
-7vj7,2022-03-09,2021-09-28
-1vjd,2004-03-30,2004-02-03
-5vj0,2017-08-16,2017-04-17
-3vja,2012-04-11,2011-10-14
-6vj9,2020-09-16,2020-01-15
-8aym,2023-04-19,2022-09-02
-2ay1,1999-02-02,1998-08-06
-3ayi,2011-08-31,2011-05-07
-3ayx,2011-10-12,2011-05-20
-6ayq,2018-09-12,2017-09-08
-2ayk,1998-02-25,1997-11-06
-3ayk,1999-06-07,1999-02-01
-5ayc,2016-03-23,2015-08-13
-8ayx,2022-12-07,2022-09-04
-1ayw,1998-11-25,1997-11-10
-8ay1,2022-10-26,2022-09-01
-6ays,2018-09-12,2017-09-08
-5ayj,2016-01-20,2015-08-21
-4ay7,2012-10-31,2012-06-18
-1ay2,1998-04-29,1997-11-13
-3aym,2011-08-17,2011-05-09
-8ay3,2023-03-22,2022-09-01
-8aye,2023-03-01,2022-09-02
-3ay2,2012-05-02,2011-04-24
-4ayr,2013-01-30,2012-06-21
-7ays,2021-01-20,2020-11-13
-3ayw,2011-09-21,2011-05-19
-1ayg,1998-11-25,1997-11-04
-2ay2,1999-02-02,1998-08-06
-6ayu,2018-03-14,2017-09-08
-2ay3,1999-02-02,1998-08-06
-6ay3,2018-02-21,2017-09-07
-2ays,2005-09-20,2005-09-08
-7ay3,2020-11-18,2020-11-11
-4ayb,2012-08-08,2012-06-19
-4ay9,2012-08-08,2012-06-19
-1ayn,1998-01-21,1997-11-06
-8ay6,2023-03-22,2022-09-02
-8ayj,2022-11-16,2022-09-02
-6ayn,2017-12-13,2017-09-08
-5ayg,2016-03-02,2015-08-20
-8ayp,2023-02-22,2022-09-02
-8ayq,2023-02-22,2022-09-02
-1aya,1994-08-31,1994-05-15
-5aym,2015-11-04,2015-08-25
-5aya,2016-05-11,2015-08-12
-1aym,1998-01-21,1997-11-06
-4ayk,1999-06-05,1999-02-01
-8ayy,2022-12-07,2022-09-04
-4ayc,2012-09-26,2012-06-20
-8aya,2023-03-22,2022-09-02
-2ayi,2005-11-08,2005-09-07
-5ayn,2015-11-04,2015-08-25
-6aya,2018-09-12,2017-09-07
-3ayz,2011-10-12,2011-05-20
-6ayv,2018-03-14,2017-09-08
-7ayz,2022-06-01,2020-11-13
-5ayo,2015-11-04,2015-08-25
-9ayg,2024-04-24,2024-03-07
-4ay5,2012-10-24,2012-06-18
-3ay6,2012-05-23,2011-04-29
-8ayk,2022-11-16,2022-09-02
-8ayo,2023-04-19,2022-09-02
-3aye,2011-10-12,2011-05-04
-1ayo,1998-11-25,1997-11-07
-4ay2,2012-10-03,2012-06-17
-8ayr,2023-03-01,2022-09-02
-6ayo,2018-09-12,2017-09-08
-2ay8,1999-02-02,1998-08-06
-2ay9,1999-02-02,1998-08-06
-7ayf,2021-06-16,2020-11-12
-2ay7,1999-02-02,1998-08-06
-6ayl,2018-09-12,2017-09-08
-8ay0,2023-02-22,2022-09-01
-7ay0,2021-03-24,2020-11-10
-4aya,2012-11-14,2012-06-19
-5ayv,2016-01-27,2015-09-08
-6ayc,2017-11-22,2017-09-08
-7ay1,2021-03-24,2020-11-10
-3aya,2011-10-12,2011-05-04
-6ayi,2017-12-20,2017-09-08
-7ayr,2021-06-30,2020-11-13
-4ayo,2013-01-30,2012-06-21
-4ayx,2012-07-11,2012-06-22
-7ay9,2021-11-24,2020-11-11
-1ay0,1998-05-13,1997-11-13
-4ayh,2013-07-10,2012-06-21
-7ayg,2021-04-28,2020-11-12
-7ayi,2021-01-13,2020-11-12
-2ayd,2006-10-31,2005-09-07
-1ayk,1998-02-25,1997-11-06
-1ay8,1998-10-14,1997-11-14
-6ayk,2018-09-12,2017-09-08
-5ayy,2016-02-03,2015-09-14
-7ayx,2021-10-27,2020-11-13
-2ayh,1995-03-31,1995-02-02
-8ays,2022-11-23,2022-09-03
-7ayn,2020-12-23,2020-11-12
-4ayw,2012-07-11,2012-06-22
-6ay2,2017-12-27,2017-09-07
-1aye,1999-01-13,1997-11-03
-8ayl,2023-04-19,2022-09-02
-4ayj,2012-12-19,2012-06-21
-2ay6,1999-02-02,1998-08-06
-3ayd,2011-10-12,2011-05-04
-4ayu,2013-07-10,2012-06-22
-4ayq,2013-01-30,2012-06-21
-3ayn,2011-08-17,2011-05-09
-7ayw,2021-11-24,2020-11-13
-7ay7,2020-12-02,2020-11-11
-6ayf,2017-11-08,2017-09-08
-8ay8,2023-03-22,2022-09-02
-6ay6,2017-11-22,2017-09-07
-4ay8,2012-10-31,2012-06-18
-3ay4,2011-08-03,2011-04-28
-3ay0,2011-08-17,2011-04-21
-5ayz,2016-02-03,2015-09-14
-5ayf,2016-04-27,2015-08-20
-5ay8,2016-04-06,2015-08-10
-1ayu,1998-11-25,1997-11-10
-3ayl,2011-08-31,2011-05-07
-2ay4,1999-02-02,1998-08-06
-5ayb,2016-04-27,2015-08-12
-7ayj,2021-05-12,2020-11-12
-4ayg,2013-07-03,2012-06-21
-8ayh,2022-12-21,2022-09-02
-2ayp,2006-09-12,2005-09-07
-3ayq,2012-05-23,2011-05-13
-4ayt,2012-07-11,2012-06-22
-8ay9,2023-03-22,2022-09-02
-1ayl,1997-01-11,1995-12-07
-7aym,2020-12-16,2020-11-12
-3ayv,2011-10-19,2011-05-17
-6ay5,2018-02-21,2017-09-07
-4ayp,2013-01-30,2012-06-21
-1ay5,1998-10-14,1997-11-14
-2ayw,2006-01-17,2005-09-09
-2ayj,2006-08-22,2005-09-07
-2ayr,2005-11-22,2005-09-07
-2ayl,2006-01-24,2005-09-07
-7ay6,2021-06-30,2020-11-11
-3ays,2011-11-02,2011-05-16
-7aya,2021-11-24,2020-11-11
-5ayr,2016-06-08,2015-09-02
-1ay4,1998-10-14,1997-11-14
-5ayi,2016-04-27,2015-08-21
-3ayt,2011-10-19,2011-05-17
-3ay9,2011-12-28,2011-05-03
-7ayy,2022-06-01,2020-11-13
-7ayh,2021-01-13,2020-11-12
-8ayz,2022-12-07,2022-09-04
-8ay7,2023-03-22,2022-09-02
-4ay6,2012-10-24,2012-06-18
-1ayc,1994-08-31,1994-05-15
-6ayd,2017-12-27,2017-09-08
-7ay2,2021-03-24,2020-11-10
-4ayl,2012-12-19,2012-06-21
-9ayf,2024-04-17,2024-03-07
-6ay4,2017-11-22,2017-09-07
-1ayp,1995-07-31,1994-07-19
-6ayh,2017-12-20,2017-09-08
-3ayc,2011-10-12,2011-05-04
-1ayv,1998-11-25,1997-11-10
-6ayw,2017-11-15,2017-09-08
-4ayy,2012-08-15,2012-06-22
-4ayv,2012-08-15,2012-06-22
-3ayu,2011-08-03,2011-05-17
-1ay6,1998-03-18,1997-11-14
-5ayt,2016-01-20,2015-09-03
-8ayn,2023-04-19,2022-09-02
-6ayt,2018-09-12,2017-09-08
-6ayr,2018-09-12,2017-09-08
-3ayf,2012-01-25,2011-05-06
-4ay1,2012-08-08,2012-06-17
-1ayb,1994-08-31,1994-05-15
-3ayg,2012-01-25,2011-05-06
-6ayb,2017-11-22,2017-09-08
-5aye,2016-03-23,2015-08-13
-3ayj,2011-08-31,2011-05-07
-7ayv,2021-08-18,2020-11-13
-2ay5,1999-02-02,1998-08-06
-6ay0,2018-07-18,2017-09-07
-7ayq,2021-06-30,2020-11-13
-7k1h,2021-09-15,2020-09-07
-4k1z,2014-04-09,2013-04-07
-2k1j,2008-04-15,2008-03-05
-7k1e,2021-09-22,2020-09-07
-1k1u,2002-07-10,2001-09-25
-5k1f,2017-05-17,2016-05-18
-6k1s,2019-06-19,2019-05-12
-5k1z,2016-11-16,2016-05-18
-3k1s,2009-10-13,2009-09-28
-2k16,2008-07-15,2008-02-22
-6k1e,2019-05-22,2019-05-10
-6k1z,2019-06-12,2019-05-13
-5k1u,2017-06-07,2016-05-18
-7k1i,2021-09-15,2020-09-07
-4k1r,2014-04-23,2013-04-05
-4k13,2014-04-09,2013-04-04
-1k1o,2001-11-28,2001-09-25
-4k1t,2014-04-16,2013-04-05
-6k16,2019-06-12,2019-05-09
-6k1k,2020-01-15,2019-05-10
-8k1j,2024-04-17,2023-07-11
-3k15,2010-03-02,2009-09-25
-6k1i,2020-01-15,2019-05-10
-1k1n,2001-11-28,2001-09-25
-7k14,2021-05-26,2020-09-07
-7k1s,2021-01-20,2020-09-08
-8k1g,2024-05-29,2023-07-10
-1k1i,2001-11-28,2001-09-25
-3k1l,2010-02-16,2009-09-28
-6k18,2019-05-22,2019-05-10
-8k1q,2024-04-17,2023-07-11
-6k1r,2020-05-13,2019-05-12
-6k1h,2019-07-10,2019-05-10
-6k1j,2020-01-15,2019-05-10
-4k11,2014-04-09,2013-04-04
-6k1q,2019-07-17,2019-05-11
-6k1b,2019-05-22,2019-05-10
-3k1f,2009-11-10,2009-09-27
-3k1x,2010-02-02,2009-09-29
-4k1l,2014-04-09,2013-04-05
-4k1b,2013-05-15,2013-04-04
-1k12,2002-07-31,2001-09-23
-8k1v,2024-04-17,2023-07-11
-7k1o,2020-09-23,2020-09-08
-5k16,2016-07-20,2016-05-17
-4k17,2013-10-09,2013-04-04
-1k1k,2002-12-04,2001-09-25
-5k1d,2017-05-17,2016-05-18
-5k1x,2016-10-19,2016-05-18
-5k13,2016-06-22,2016-05-17
-5k1c,2016-07-20,2016-05-18
-7k1r,2021-11-10,2020-09-08
-5k18,2017-04-19,2016-05-17
-1k1j,2001-11-28,2001-09-25
-8k1k,2024-04-03,2023-07-11
-5k15,2017-05-24,2016-05-17
-7k15,2021-02-17,2020-09-07
-3k1e,2009-12-08,2009-09-27
-1k1y,2003-06-17,2001-09-26
-6k13,2019-10-16,2019-05-09
-1k1m,2001-11-28,2001-09-25
-1k1p,2001-11-28,2001-09-25
-4k1k,2013-06-05,2013-04-05
-3k14,2009-10-06,2009-09-25
-4k1w,2014-04-09,2013-04-06
-5k1k,2017-06-07,2016-05-18
-7k1a,2021-10-06,2020-09-07
-5k1l,2017-06-07,2016-05-18
-4k19,2013-07-31,2013-04-04
-6k1m,2020-05-13,2019-05-10
-8k1u,2024-04-03,2023-07-11
-5k1w,2017-06-07,2016-05-18
-2k1w,2009-01-27,2008-03-17
-4k1h,2013-06-05,2013-04-05
-5k11,2016-06-08,2016-05-17
-7k1l,2020-09-23,2020-09-07
-3k16,2010-03-02,2009-09-25
-6k1l,2020-05-13,2019-05-10
-4k1q,2014-04-09,2013-04-05
-3k1j,2010-09-22,2009-09-28
-5k14,2016-06-29,2016-05-17
-1k1l,2001-11-28,2001-09-25
-4k1i,2013-06-05,2013-04-05
-5k1m,2017-06-07,2016-05-18
-4k1y,2014-04-09,2013-04-07
-2k1p,2009-03-17,2008-03-13
-6k19,2019-05-22,2019-05-10
-2k1q,2009-02-03,2008-03-13
-5k17,2017-05-24,2016-05-17
-3k13,2009-12-22,2009-09-25
-7k19,2021-01-06,2020-09-07
-5k1a,2016-07-20,2016-05-18
-6k1p,2019-05-29,2019-05-10
-7k1d,2021-09-22,2020-09-07
-5k10,2016-06-08,2016-05-17
-4k18,2013-05-15,2013-04-04
-1k1d,2002-08-14,2001-09-25
-6k1g,2020-05-13,2019-05-10
-4k1c,2013-05-08,2013-04-04
-4k1j,2013-06-05,2013-04-05
-7k12,2021-01-13,2020-09-07
-8k1s,2024-04-03,2023-07-11
-7k1p,2021-09-22,2020-09-08
-5k1q,2017-06-07,2016-05-18
-5k1r,2016-11-02,2016-05-18
-6k1n,2020-05-13,2019-05-10
-3k1a,2010-02-16,2009-09-26
-2k1r,2009-03-31,2008-03-14
-6k1f,2020-05-13,2019-05-10
-8k1z,2024-04-17,2023-07-11
-4k1g,2013-07-31,2013-04-05
-5k1p,2016-10-19,2016-05-18
-6k1c,2019-05-22,2019-05-10
-5k1v,2017-03-29,2016-05-18
-7k18,2021-01-20,2020-09-07
-3k1u,2009-10-06,2009-09-28
-7k1c,2021-10-06,2020-09-07
-3k1o,2009-10-27,2009-09-28
-3k1w,2010-03-02,2009-09-29
-8k16,2024-04-03,2023-07-10
-8k1h,2024-05-29,2023-07-10
-8k1t,2024-04-03,2023-07-11
-1k1e,2002-02-27,2001-09-25
-8k14,2024-03-27,2023-07-10
-7k13,2021-01-13,2020-09-07
-4k10,2014-04-02,2013-04-04
-7k1f,2021-09-22,2020-09-07
-6k1d,2019-05-22,2019-05-10
-2k17,2008-07-15,2008-02-22
-1k1w,2003-06-17,2001-09-26
-4k1e,2014-04-09,2013-04-04
-5k1i,2016-12-21,2016-05-18
-5k1b,2016-07-20,2016-05-18
-3k1g,2010-08-18,2009-09-27
-1k1x,2003-06-17,2001-09-26
-7k17,2021-01-06,2020-09-07
-6k17,2019-05-22,2019-05-10
-6k1a,2019-05-22,2019-05-10
-1k1t,2002-07-10,2001-09-25
-5k1s,2016-08-10,2016-05-18
-4k1x,2013-11-13,2013-04-06
-6k15,2019-11-13,2019-05-09
-5ev5,2016-10-19,2015-11-19
-1evk,2000-07-19,2000-04-20
-7evo,2022-08-03,2021-05-21
-4evw,2012-05-23,2012-04-26
-3evf,2009-01-06,2008-10-13
-7evd,2022-03-23,2021-05-21
-8ev6,2023-08-09,2022-10-19
-8evy,2023-08-30,2022-10-21
-8eva,2023-08-09,2022-10-20
-7ev9,2021-07-21,2021-05-20
-2ev5,2006-03-07,2005-10-31
-6ev6,2017-12-20,2017-11-01
-6evx,2018-07-11,2017-11-03
-3evb,2009-01-06,2008-10-13
-1evw,2000-08-03,2000-04-20
-2evs,2006-11-14,2005-10-31
-6ev3,2017-12-20,2017-11-01
-8evb,2023-08-09,2022-10-20
-8evc,2023-08-09,2022-10-20
-7ev7,2021-07-14,2021-05-20
-8eve,2023-08-02,2022-10-20
-7ev6,2021-11-24,2021-05-20
-5evk,2016-06-01,2015-11-19
-7evz,2021-09-29,2021-05-24
-5eva,2016-06-08,2015-11-19
-1evl,2000-07-19,2000-04-20
-4ev5,2013-03-13,2012-04-25
-6evl,2018-09-12,2017-11-02
-6eve,2017-12-20,2017-11-01
-4evv,2012-07-11,2012-04-26
-2evc,2006-03-28,2005-10-31
-7ev1,2021-06-16,2021-05-19
-5evz,2016-06-15,2015-11-20
-5evy,2015-12-16,2015-11-20
-5evj,2016-11-30,2015-11-19
-7ev2,2022-02-16,2021-05-20
-8evf,2023-08-02,2022-10-20
-3evm,2009-08-11,2008-10-13
-6ev8,2017-12-20,2017-11-01
-6ev5,2017-12-20,2017-11-01
-7evm,2021-08-11,2021-05-21
-8evr,2023-09-06,2022-10-20
-1ev3,2000-12-04,2000-04-19
-6ev4,2017-12-27,2017-11-01
-7evh,2022-03-23,2021-05-21
-8evt,2023-09-06,2022-10-20
-7evb,2022-03-23,2021-05-21
-3evg,2009-01-06,2008-10-13
-6eva,2017-12-20,2017-11-01
-4ev2,2013-03-13,2012-04-25
-6evo,2018-09-12,2017-11-02
-5evm,2015-12-16,2015-11-20
-1evz,2001-02-22,2000-04-21
-3eve,2009-01-06,2008-10-13
-3evr,2008-12-09,2008-10-13
-6evm,2018-09-12,2017-11-02
-8ev7,2023-08-09,2022-10-19
-3evw,2009-08-11,2008-10-13
-7evk,2022-03-23,2021-05-21
-7evu,2022-03-09,2021-05-22
-4ev4,2012-05-23,2012-04-25
-6ev9,2017-12-20,2017-11-01
-8evq,2023-09-06,2022-10-20
-2ev6,2006-03-07,2005-10-31
-8ev2,2022-12-28,2022-10-19
-8evo,2023-10-25,2022-10-20
-3eva,2009-01-06,2008-10-13
-8ev9,2023-08-09,2022-10-20
-2evm,2006-03-28,2005-10-31
-6evb,2017-12-20,2017-11-01
-7evj,2022-02-16,2021-05-21
-8evn,2023-10-25,2022-10-20
-8ev5,2023-09-06,2022-10-19
-4evh,2012-07-25,2012-04-26
-4evc,2012-06-27,2012-04-26
-6evq,2018-02-07,2017-11-02
-7evn,2022-08-03,2021-05-21
-6evc,2017-12-20,2017-11-01
-7evi,2022-03-23,2021-05-21
-2evl,2006-11-14,2005-10-31
-6evy,2018-07-04,2017-11-03
-1evx,2000-08-02,2000-04-20
-7evv,2022-03-09,2021-05-22
-5ev0,2016-06-08,2015-11-19
-7ev3,2022-02-16,2021-05-20
-6ev2,2018-09-26,2017-11-01
-6evj,2017-12-13,2017-11-01
-5ev9,2016-06-08,2015-11-19
-8evx,2023-08-30,2022-10-21
-2evx,2006-11-14,2005-11-01
-8evu,2022-11-16,2022-10-20
-5evc,2015-12-02,2015-11-19
-4evy,2012-05-09,2012-04-26
-4ev6,2012-10-31,2012-04-25
-3evk,2009-08-25,2008-10-13
-3evd,2009-01-06,2008-10-13
-7eve,2022-03-23,2021-05-21
-6evn,2018-09-12,2017-11-02
-5evd,2016-06-01,2015-11-19
-1eve,1999-01-20,1998-03-04
-8evw,2023-08-30,2022-10-21
-2ev9,2006-05-01,2005-10-31
-2ev0,2006-03-07,2005-10-30
-6evr,2018-06-06,2017-11-02
-6evd,2017-12-20,2017-11-01
-3ev6,2009-06-23,2008-10-12
-3evu,2008-12-09,2008-10-13
-8ev8,2023-08-09,2022-10-20
-5ev2,2016-02-24,2015-11-19
-2evo,2006-03-28,2005-10-31
-4ev0,2012-06-20,2012-04-25
-3evc,2009-01-06,2008-10-13
-6evp,2018-09-12,2017-11-02
-6ev0,2018-05-02,2017-10-31
-7ev0,2021-06-02,2021-05-19
-5evb,2016-06-01,2015-11-19
-3ev5,2009-06-23,2008-10-12
-8evp,2023-09-06,2022-10-20
-3evv,2008-12-09,2008-10-13
-7evq,2021-06-09,2021-05-21
-4evi,2013-05-01,2012-04-26
-7evc,2022-03-23,2021-05-21
-1evj,2000-12-04,2000-04-20
-1evi,2000-10-23,2000-04-20
-3evi,2009-03-03,2008-10-13
-8ev3,2022-11-30,2022-10-19
-4evb,2012-06-27,2012-04-26
-5ev3,2016-02-24,2015-11-19
-6evf,2017-12-20,2017-11-01
-8evk,2023-03-01,2022-10-20
-5ev8,2016-06-01,2015-11-19
-1evh,1999-05-21,1999-04-21
-7ev5,2021-09-08,2021-05-20
-2evr,2005-11-22,2005-10-31
-2evd,2006-11-14,2005-10-31
-2evk,2006-04-18,2005-10-31
-6ev7,2017-12-20,2017-11-01
-7evl,2022-03-23,2021-05-21
-5eve,2016-06-08,2015-11-19
-5ev6,2016-06-01,2015-11-19
-7evy,2021-09-29,2021-05-24
-8evs,2023-09-06,2022-10-20
-6evw,2018-07-04,2017-11-02
-8evz,2023-08-30,2022-10-21
-6evz,2018-07-04,2017-11-03
-2evp,2006-03-28,2005-10-31
-6evk,2017-12-13,2017-11-01
-3evq,2008-11-04,2008-10-13
-1evr,2000-12-04,2000-04-20
-7ev4,2021-11-24,2021-05-20
-4evd,2012-06-27,2012-04-26
-1ev6,2000-12-04,2000-04-19
-2evw,2006-05-30,2005-11-01
-2eva,2006-05-02,2005-10-31
-1evu,2000-05-10,2000-04-20
-8ev1,2022-12-28,2022-10-19
-6evh,2018-07-18,2017-11-01
-5ev1,2016-02-24,2015-11-19
-1ev4,2001-02-07,2000-04-19
-1ev9,2001-02-07,2000-04-19
-5ev4,2016-02-24,2015-11-19
-3evo,2009-08-25,2008-10-13
-6evv,2018-10-24,2017-11-02
-6evg,2018-04-11,2017-11-01
-5h04,2016-11-02,2016-10-03
-4h0n,2012-11-14,2012-09-09
-5h09,2017-10-04,2016-10-04
-1h0i,2002-06-27,2002-06-19
-5h0h,2017-10-04,2016-10-04
-8h0d,2023-08-16,2022-09-28
-6h00,2018-08-08,2018-07-05
-2h03,2006-06-13,2006-05-13
-3h0a,2009-06-09,2009-04-08
-3h0z,2009-07-07,2009-04-10
-8h0m,2023-04-12,2022-09-29
-8h06,2023-07-19,2022-09-28
-1h04,2003-03-20,2002-06-11
-4h0l,2013-02-13,2012-09-08
-6h0n,2019-10-23,2018-07-10
-4h0w,2012-12-26,2012-09-10
-8h0s,2023-01-25,2022-09-30
-8h0y,2022-11-09,2022-09-30
-4h0j,2013-09-11,2012-09-08
-3h0b,2009-07-07,2009-04-08
-3h0n,2009-04-21,2009-04-09
-4h0d,2012-09-26,2012-09-07
-6h0v,2019-03-27,2018-07-10
-4h0e,2013-02-06,2012-09-08
-6h0u,2019-05-15,2018-07-10
-6h0b,2018-10-10,2018-07-08
-4h0k,2013-09-11,2012-09-08
-6h0a,2019-07-17,2018-07-07
-1h08,2003-07-11,2002-06-11
-3h0m,2009-07-21,2009-04-09
-6h06,2018-07-25,2018-07-06
-3h0c,2009-06-09,2009-04-09
-1h0c,2003-06-12,2002-06-17
-4h01,2013-09-11,2012-09-06
-6h0w,2020-01-29,2018-07-10
-4h00,2013-09-11,2012-09-06
-6h0f,2018-11-07,2018-07-09
-1h0w,2003-06-27,2002-06-27
-4h0b,2012-11-21,2012-09-07
-5h0b,2017-10-11,2016-10-04
-6h0e,2018-07-25,2018-07-09
-3h06,2009-05-05,2009-04-08
-8h09,2023-08-16,2022-09-28
-8h0o,2023-10-04,2022-09-30
-4h07,2012-11-21,2012-09-07
-2h0t,2007-01-30,2006-05-15
-2h0u,2006-06-13,2006-05-15
-6h07,2018-12-12,2018-07-06
-1h0s,2003-07-17,2002-06-27
-8h0l,2023-09-27,2022-09-29
-3h0l,2009-07-21,2009-04-09
-8h0b,2023-08-16,2022-09-28
-8h08,2023-05-31,2022-09-28
-5h0v,2017-06-14,2016-10-07
-4h0y,2013-02-20,2012-09-10
-5h02,2016-11-23,2016-10-02
-1h0r,2003-10-23,2002-06-27
-3h0j,2010-04-07,2009-04-09
-5h05,2017-08-16,2016-10-03
-6h03,2018-12-19,2018-07-06
-1h0g,2002-06-27,2002-06-19
-1h0j,2003-06-19,2002-06-20
-3h03,2009-05-05,2009-04-08
-6h0h,2019-06-19,2018-07-09
-3h08,2009-05-12,2009-04-08
-1h07,2003-07-11,2002-06-11
-2h0v,2006-05-30,2006-05-15
-4h0c,2012-09-26,2012-09-07
-3h0q,2010-04-21,2009-04-10
-2h00,2006-06-13,2006-05-12
-3h0o,2010-04-21,2009-04-09
-4h0m,2013-03-06,2012-09-09
-3h0v,2009-06-30,2009-04-10
-4h03,2013-02-20,2012-09-07
-1h00,2003-07-11,2002-06-10
-8h0z,2022-11-09,2022-09-30
-6h0t,2019-03-27,2018-07-10
-1h0a,2002-10-03,2002-06-12
-6h0y,2020-01-29,2018-07-10
-2h04,2006-06-13,2006-05-13
-5h06,2017-08-16,2016-10-03
-8h0a,2023-08-16,2022-09-28
-3h0u,2009-04-21,2009-04-10
-1h0m,2002-08-29,2002-06-25
-4h0v,2013-02-20,2012-09-10
-3h09,2009-04-21,2009-04-08
-4h04,2013-03-20,2012-09-07
-3h0g,2009-08-25,2009-04-09
-5h0e,2017-10-04,2016-10-04
-2h0j,2006-06-27,2006-05-15
-1h0n,2002-07-25,2002-06-26
-5h0g,2017-10-04,2016-10-04
-2h0k,2007-06-19,2006-05-15
-2h0b,2006-06-20,2006-05-14
-1h0v,2003-06-27,2002-06-27
-4h0s,2012-09-19,2012-09-10
-6h08,2020-02-12,2018-07-06
-1h01,2003-07-11,2002-06-10
-4h0f,2013-09-04,2012-09-08
-6h0p,2019-10-23,2018-07-10
-2h02,2006-06-13,2006-05-13
-8h0w,2022-12-07,2022-09-30
-2h0l,2007-06-19,2006-05-15
-4h0i,2013-06-19,2012-09-08
-4h0z,2012-10-03,2012-09-10
-5h08,2017-07-26,2016-10-04
-6h0x,2020-01-29,2018-07-10
-5h0m,2017-03-08,2016-10-05
-8h01,2023-04-12,2022-09-27
-8h00,2023-04-12,2022-09-27
-3h0y,2009-07-07,2009-04-10
-5h0p,2017-09-13,2016-10-06
-8h07,2023-05-31,2022-09-28
-4h0x,2013-02-20,2012-09-10
-5h0u,2017-10-04,2016-10-07
-1h02,2002-07-25,2002-06-11
-3h0w,2009-06-30,2009-04-10
-2h0f,2006-06-27,2006-05-15
-4h0h,2013-06-19,2012-09-08
-8h0v,2022-12-07,2022-09-30
-3h0s,2010-04-07,2009-04-10
-4h0t,2013-02-20,2012-09-10
-8h0i,2023-07-19,2022-09-29
-8h0c,2023-08-16,2022-09-28
-4h0u,2013-09-11,2012-09-10
-3h0r,2009-07-21,2009-04-10
-5h0o,2017-03-08,2016-10-06
-8h0t,2023-01-25,2022-09-30
-8h0x,2022-11-09,2022-09-30
-6h0s,2019-07-31,2018-07-10
-2h0d,2006-05-23,2006-05-14
-2h0y,2007-01-30,2006-05-15
-1h0o,2002-07-25,2002-06-26
-8h0q,2023-08-09,2022-09-30
-6h04,2018-12-19,2018-07-06
-6h0g,2018-11-07,2018-07-09
-6h0m,2019-07-31,2018-07-10
-6h0z,2020-01-29,2018-07-10
-3h0e,2009-11-17,2009-04-09
-2h0r,2007-03-27,2006-05-15
-8h0j,2023-10-04,2022-09-29
-6mja,2019-01-09,2018-09-20
-6mjj,2019-01-09,2018-09-21
-3mjg,2010-06-16,2010-04-12
-3mj2,2010-06-30,2010-04-12
-6mjw,2019-05-29,2018-09-23
-6mjh,2019-06-26,2018-09-20
-3mjo,2010-08-25,2010-04-13
-3mjy,2011-02-23,2010-04-13
-7mj1,2021-09-29,2021-04-19
-7mjr,2021-05-05,2021-04-20
-6mj7,2018-10-31,2018-09-20
-6mjt,2019-02-20,2018-09-21
-5mji,2016-12-28,2016-12-01
-6mj4,2019-01-09,2018-09-20
-7mjt,2022-03-23,2021-04-20
-1mja,2002-10-30,2002-08-27
-7mjx,2021-09-15,2021-04-20
-6mj2,2018-12-12,2018-09-20
-7mjo,2021-10-13,2021-04-20
-2mjp,2000-01-28,1999-01-27
-7mji,2021-05-12,2021-04-20
-5mjg,2017-12-20,2016-12-01
-5mj7,2017-03-08,2016-11-30
-4mj4,2013-09-18,2013-09-03
-5mj5,2017-11-08,2016-11-30
-6mjl,2019-09-25,2018-09-21
-7mjf,2021-07-14,2021-04-20
-6mji,2019-01-09,2018-09-20
-5mjd,2017-12-20,2016-11-30
-3mj9,2011-02-23,2010-04-12
-3mje,2010-08-18,2010-04-12
-6mjp,2019-03-27,2018-09-21
-7mj0,2021-09-29,2021-04-19
-6mj3,2019-08-21,2018-09-20
-3mj5,2010-06-30,2010-04-12
-6mjf,2018-10-03,2018-09-20
-6mjx,2019-05-29,2018-09-23
-6mjq,2019-01-09,2018-09-21
-4mjv,2014-01-15,2013-09-04
-4mj7,2013-11-06,2013-09-03
-3mjx,2011-04-27,2010-04-13
-7mj2,2021-09-29,2021-04-19
-1mjn,2003-01-28,2002-08-28
-5mj4,2017-01-11,2016-11-29
-3mjv,2010-08-18,2010-04-13
-1mj3,2002-09-24,2002-08-26
-4mju,2014-01-15,2013-09-04
-7mjc,2022-06-08,2021-04-20
-1mjb,2002-10-30,2002-08-27
-4mj0,2013-11-06,2013-09-03
-1mj2,1999-08-02,1998-01-27
-7mjy,2021-09-15,2021-04-20
-1mj4,2002-09-12,2002-08-26
-7mj6,2021-08-18,2021-04-19
-3mjw,2010-06-09,2010-04-13
-5mjv,2017-01-11,2016-12-01
-7mj5,2021-12-22,2021-04-19
-5mjl,2017-11-15,2016-12-01
-5mj3,2017-01-11,2016-11-29
-7mjs,2021-06-16,2021-04-20
-7mjp,2021-10-13,2021-04-20
-7mjj,2021-05-12,2021-04-20
-6mjs,2019-02-20,2018-09-21
-6mjo,2019-11-13,2018-09-21
-3mjm,2011-03-02,2010-04-13
-7mjg,2021-05-12,2021-04-20
-5mju,2017-04-19,2016-12-01
-5mjn,2017-12-06,2016-12-01
-3mju,2010-12-08,2010-04-13
-5mjp,2017-11-15,2016-12-01
-1mjo,1999-08-02,1998-01-28
-4mjr,2013-09-18,2013-09-04
-4mjy,2014-09-10,2013-09-04
-3mjs,2010-08-18,2010-04-13
-3mjt,2010-08-18,2010-04-13
-5mjq,2017-11-15,2016-12-01
-7mj9,2021-08-18,2021-04-19
-6mjr,2019-02-20,2018-09-21
-7mjm,2021-05-12,2021-04-20
-7mjw,2021-09-15,2021-04-20
-4mjo,2013-11-06,2013-09-04
-3mj7,2010-09-22,2010-04-12
-1mj9,2002-10-30,2002-08-27
-1mji,2003-01-21,2002-08-28
-5mjc,2017-12-20,2016-11-30
-4mjw,2014-02-12,2013-09-04
-1mjp,1999-08-02,1998-01-29
-4mj2,2013-09-18,2013-09-03
-5mjj,2017-12-20,2016-12-01
-3mj4,2010-10-20,2010-04-12
-4mj3,2015-02-25,2013-09-03
-6mju,2019-05-29,2018-09-22
-6mj6,2019-01-09,2018-09-20
-7mja,2021-08-18,2021-04-19
-4mjp,2013-09-18,2013-09-04
-7mjv,2021-09-15,2021-04-20
-5mjh,2017-05-10,2016-12-01
-5mj6,2017-04-05,2016-11-30
-7mjh,2021-05-12,2021-04-20
-3mjp,2010-12-08,2010-04-13
-5mjk,2017-04-12,2016-12-01
-3mjn,2010-06-30,2010-04-13
-4mjl,2015-03-04,2013-09-03
-1mje,2002-09-27,2002-08-27
-7mjd,2022-06-08,2021-04-20
-1mjl,1998-04-29,1998-01-26
-3mjf,2010-05-26,2010-04-12
-1mj7,2003-09-23,2002-08-27
-7mju,2021-08-04,2021-04-20
-7mjn,2021-05-12,2021-04-20
-3mj0,2011-05-25,2010-04-12
-3mj1,2010-06-30,2010-04-12
-5mjt,2017-12-20,2016-12-01
-4mjh,2014-04-09,2013-09-03
-5mjo,2017-08-23,2016-12-01
-4mjt,2015-03-11,2013-09-04
-5mjs,2017-12-20,2016-12-01
-1mjt,2003-01-07,2002-08-28
-1mjj,2003-09-23,2002-08-28
-3mjh,2010-05-05,2010-04-12
-2mjc,2015-01-07,2014-01-03
-5mjm,2017-11-15,2016-12-01
-4mji,2014-05-28,2013-09-03
-3mj6,2010-09-22,2010-04-12
-5mjb,2017-05-17,2016-11-30
-1mj5,2003-08-27,2002-08-27
-7mjl,2021-05-12,2021-04-20
-1mjh,1998-12-23,1998-11-04
-5mja,2017-05-17,2016-11-30
-1mjq,1999-08-02,1998-01-30
-1mjg,2003-01-28,2002-08-27
-4mjd,2013-09-18,2013-09-03
-6mjk,2018-10-31,2018-09-21
-2mji,2014-10-29,2014-01-09
-6mjm,2019-04-03,2018-09-21
-6mjy,2019-09-25,2018-09-23
-3mjr,2010-07-28,2010-04-13
-7mjk,2021-05-12,2021-04-20
-6mjg,2018-10-03,2018-09-20
-6mj5,2019-07-03,2018-09-20
-7mjz,2021-09-15,2021-04-20
-3mjl,2010-05-05,2010-04-13
-4mjq,2013-09-18,2013-09-04
-7mjq,2021-10-13,2021-04-20
-154l,1995-01-26,1994-05-05
-6r4h,2020-01-15,2019-03-22
-7r4e,2022-04-27,2022-02-08
-5r4b,2021-09-01,2020-02-18
-1r4v,2004-03-30,2003-10-08
-7r46,2023-02-08,2022-02-08
-3r4m,2011-04-27,2011-03-17
-6r4p,2019-05-08,2019-03-22
-6r4l,2019-09-25,2019-03-22
-6r4v,2019-09-18,2019-03-24
-2r42,2008-06-24,2007-08-30
-5r49,2021-09-01,2020-02-18
-6r42,2020-02-19,2019-03-21
-6r4y,2019-06-12,2019-03-24
-1r4m,2003-12-23,2003-10-07
-4r4o,2014-11-19,2014-08-19
-5r4r,2020-07-08,2020-02-27
-3r4t,2011-03-30,2011-03-17
-7r4a,2023-01-25,2022-02-08
-6r4s,2019-09-11,2019-03-24
-5r4a,2021-09-01,2020-02-18
-3r4l,2011-11-02,2011-03-17
-5r42,2021-09-01,2020-02-18
-7r4i,2022-06-08,2022-02-08
-4r42,2015-08-19,2014-08-19
-3r4c,2011-10-26,2011-03-17
-4r4n,2014-11-05,2014-08-19
-1r4l,2004-02-03,2003-10-07
-8r42,2024-03-13,2023-11-10
-4r4f,2014-09-17,2014-08-19
-6r4t,2019-09-11,2019-03-24
-6r48,2019-10-30,2019-03-22
-1r4o,2003-10-21,2003-10-07
-8r4v,2024-03-27,2023-11-14
-1r46,2004-03-16,2003-10-03
-5r4v,2020-05-13,2020-02-28
-3r42,2011-05-04,2011-03-17
-1r4r,2003-10-28,2003-10-07
-7r4u,2022-05-18,2022-02-09
-7r43,2023-02-08,2022-02-08
-8r43,2024-01-17,2023-11-12
-1r43,2003-11-11,2003-10-03
-2r49,2008-09-02,2007-08-30
-6r4n,2019-09-25,2019-03-22
-3r4g,2012-03-21,2011-03-17
-7r42,2023-02-08,2022-02-08
-5r4u,2020-07-08,2020-02-27
-1r4s,2004-03-02,2003-10-08
-2r43,2008-09-09,2007-08-30
-5r48,2021-09-01,2020-02-18
-5r44,2021-09-01,2020-02-18
-2r4j,2008-06-03,2007-08-31
-2r45,2008-04-15,2007-08-30
-6r4u,2019-09-11,2019-03-24
-1r4i,2004-06-29,2003-10-06
-6r4g,2020-01-15,2019-03-22
-8r4x,2024-03-13,2023-11-14
-5r4n,2020-04-01,2020-02-24
-2r4x,2007-11-27,2007-09-02
-5r46,2021-09-01,2020-02-18
-1r4p,2004-05-11,2003-10-07
-3r4s,2011-06-08,2011-03-17
-1r4z,2004-10-19,2003-10-09
-8r41,2024-03-13,2023-11-10
-1r4n,2003-12-23,2003-10-07
-3r41,2011-05-04,2011-03-17
-6r4o,2019-05-08,2019-03-22
-1r47,2004-03-16,2003-10-03
-8r4u,2024-03-27,2023-11-14
-6r44,2019-07-31,2019-03-21
-5r4l,2020-04-01,2020-02-24
-2r4t,2008-09-09,2007-09-01
-5r4g,2020-04-01,2020-02-24
-3r4d,2011-06-22,2011-03-17
-5r4j,2020-04-01,2020-02-24
-7r4o,2022-05-04,2022-02-08
-7r4f,2023-02-08,2022-02-08
-7r40,2022-04-20,2022-02-08
-3r4z,2012-02-01,2011-03-18
-2r4u,2008-09-09,2007-09-01
-5r4m,2020-04-01,2020-02-24
-2r4f,2008-04-29,2007-08-31
-5r4q,2020-07-08,2020-02-27
-6r4b,2019-05-08,2019-03-22
-7r49,2022-08-03,2022-02-08
-6r41,2019-05-08,2019-03-21
-6r4q,2020-04-08,2019-03-22
-4r4b,2014-09-10,2014-08-19
-2r4y,2007-11-27,2007-09-02
-1r4x,2003-10-28,2003-10-09
-2r4b,2008-03-18,2007-08-31
-6r4m,2019-09-25,2019-03-22
-3r4b,2011-09-21,2011-03-17
-7r4g,2023-02-08,2022-02-08
-7r4z,2022-05-18,2022-02-09
-3r4o,2011-04-27,2011-03-17
-7r4s,2022-12-21,2022-02-09
-6r4d,2019-05-08,2019-03-22
-6r4c,2019-05-01,2019-03-22
-3r4p,2011-04-27,2011-03-17
-4r4h,2014-09-17,2014-08-19
-2r46,2008-04-29,2007-08-30
-6r43,2019-04-10,2019-03-21
-6r4i,2020-01-15,2019-03-22
-7r4r,2022-06-08,2022-02-09
-7r4l,2022-07-06,2022-02-08
-7r4v,2022-05-18,2022-02-09
-3r49,2012-03-21,2011-03-17
-2r4v,2007-11-13,2007-09-02
-7r4h,2022-09-14,2022-02-08
-6r4z,2019-06-12,2019-03-24
-5r4s,2020-07-08,2020-02-27
-4r41,2014-12-10,2014-08-18
-5r4w,2020-05-13,2020-02-28
-1r42,2004-02-03,2003-10-07
-6r46,2019-10-30,2019-03-22
-3r44,2012-02-08,2011-03-17
-6r4k,2019-07-03,2019-03-22
-4r4e,2015-03-04,2014-08-19
-7r4n,2022-03-02,2022-02-08
-7r41,2023-02-08,2022-02-08
-1r4w,2004-02-03,2003-10-08
-5r4y,2020-05-13,2020-02-28
-8r4q,2024-03-27,2023-11-14
-6r49,2019-05-08,2019-03-22
-7r4j,2022-07-06,2022-02-08
-7r4p,2022-05-04,2022-02-09
-2r4w,2007-11-27,2007-09-02
-6r4w,2019-06-12,2019-03-24
-7r48,2023-02-08,2022-02-08
-2r40,2007-10-02,2007-08-30
-6r4a,2019-05-08,2019-03-22
-5r4e,2020-04-08,2020-02-21
-4r4y,2014-12-17,2014-08-20
-7r45,2023-02-08,2022-02-08
-6r4j,2020-01-15,2019-03-22
-3r4q,2011-04-06,2011-03-17
-6r4x,2019-06-12,2019-03-24
-1r4u,2004-03-02,2003-10-08
-3r40,2011-05-04,2011-03-16
-7r4k,2022-07-06,2022-02-08
-7r44,2023-02-08,2022-02-08
-6r4f,2020-01-15,2019-03-22
-1r4f,2004-04-13,2003-10-06
-5r4t,2020-07-08,2020-02-27
-7r4q,2022-06-08,2022-02-09
-5r4z,2020-05-13,2020-02-28
-3r4i,2011-04-06,2011-03-17
-3r46,2011-11-16,2011-03-17
-1r4a,2004-01-13,2003-10-04
-8r4o,2024-03-27,2023-11-14
-3r4v,2012-07-04,2011-03-17
-4r4u,2015-04-15,2014-08-19
-2r4h,2007-10-16,2007-08-31
-5r43,2021-09-01,2020-02-18
-5r45,2021-09-01,2020-02-18
-7r4m,2022-07-06,2022-02-08
-7r47,2023-02-08,2022-02-08
-5r4d,2021-09-01,2020-02-18
-5r4k,2020-04-01,2020-02-24
-6r4e,2020-01-15,2019-03-22
-2r4e,2008-04-29,2007-08-31
-5r47,2021-09-01,2020-02-18
-4r4r,2015-11-11,2014-08-19
-3r4x,2011-08-03,2011-03-18
-3r43,2012-03-28,2011-03-17
-1r44,2004-06-15,2003-10-03
-4r4q,2014-11-19,2014-08-19
-4r4c,2014-11-19,2014-08-19
-4r4j,2014-12-10,2014-08-19
-3r4n,2011-04-27,2011-03-17
-2r4z,2007-11-27,2007-09-02
-5r4i,2020-04-01,2020-02-24
-7r4d,2023-02-08,2022-02-08
-4r4x,2015-01-28,2014-08-20
-4r43,2015-04-08,2014-08-19
-5r4c,2021-09-01,2020-02-18
-5r4p,2020-07-08,2020-02-27
-4r4t,2014-11-19,2014-08-19
-7r4x,2023-02-22,2022-02-09
-8r4b,2024-05-01,2023-11-13
-4r4i,2014-11-19,2014-08-19
-7r4c,2023-02-08,2022-02-08
-5r4x,2020-05-13,2020-02-28
-5r4h,2020-04-01,2020-02-24
-8r4d,2024-05-01,2023-11-13
-4r4s,2015-11-11,2014-08-19
-109m,1998-04-08,1997-12-22
-209d,1995-10-15,1995-05-01
-4ylq,2015-12-30,2015-03-05
-4ylj,2015-03-25,2015-03-05
-5ylj,2018-04-11,2017-10-17
-5yle,2017-11-08,2017-10-17
-7yll,2023-12-06,2022-07-26
-1ylh,2005-06-28,2005-01-19
-7ylr,2023-06-14,2022-07-26
-1ylk,2005-03-08,2005-01-19
-8yle,2024-04-10,2024-03-06
-1yl9,2005-09-20,2005-01-19
-6ylh,2020-07-29,2020-04-07
-4yll,2015-03-25,2015-03-05
-6ylz,2021-04-14,2020-04-07
-6ylv,2020-06-10,2020-04-07
-6yl1,2020-07-22,2020-04-06
-4ylf,2015-07-08,2015-03-05
-4yl4,2016-03-09,2015-03-05
-7yl6,2023-06-07,2022-07-25
-2ylz,2011-06-22,2011-06-06
-1ylo,2005-03-08,2005-01-19
-1yl1,2005-07-05,2005-01-18
-6yl8,2020-07-15,2020-04-06
-1ylr,2005-02-08,2005-01-19
-4yls,2015-06-17,2015-03-05
-6ylj,2021-10-20,2020-04-07
-6ylu,2020-12-02,2020-04-07
-4yln,2015-04-22,2015-03-05
-7ylw,2023-03-29,2022-07-27
-6yl7,2020-06-10,2020-04-06
-4ylk,2015-03-25,2015-03-05
-2ylt,2011-06-22,2011-06-06
-5yl1,2018-12-12,2017-10-16
-2yli,2012-04-18,2011-06-02
-5ylz,2018-07-18,2017-10-20
-6ylt,2020-04-29,2020-04-07
-4ylr,2015-06-17,2015-03-05
-1ylc,2006-04-25,2005-01-19
-4yl1,2015-06-10,2015-03-04
-6ylc,2020-09-23,2020-04-07
-2yl8,2011-09-07,2011-05-31
-5ylc,2017-11-08,2017-10-17
-8yla,2024-04-24,2024-03-05
-2yl9,2011-09-21,2011-06-01
-2ylj,2012-06-13,2011-06-02
-2yl5,2011-09-14,2011-05-31
-2yl6,2011-09-14,2011-05-31
-2yly,2012-06-13,2011-06-06
-7ylg,2023-05-31,2022-07-26
-2yl0,2011-10-05,2011-05-30
-5ylg,2018-10-24,2017-10-17
-7ylx,2023-03-29,2022-07-27
-4ylo,2015-04-22,2015-03-05
-5yl7,2018-01-31,2017-10-17
-2yll,2011-09-21,2011-06-02
-2ylo,2011-07-06,2011-06-04
-7yl2,2023-07-26,2022-07-25
-4ylu,2015-06-17,2015-03-05
-6yls,2020-12-16,2020-04-07
-6ylr,2020-04-15,2020-04-07
-6ylq,2020-12-16,2020-04-07
-1ylp,2005-04-19,2005-01-19
-5yls,2018-04-11,2017-10-18
-2yl3,2011-10-05,2011-05-31
-1yld,2006-04-25,2005-01-19
-6ylg,2020-07-29,2020-04-07
-1yly,2005-04-26,2005-01-19
-8yl9,2024-04-24,2024-03-05
-1yle,2005-03-01,2005-01-19
-1ylu,2005-02-08,2005-01-19
-5yl4,2017-11-15,2017-10-17
-5yl6,2019-06-12,2017-10-17
-5yll,2018-06-20,2017-10-17
-6yl3,2020-05-06,2020-04-06
-7ylq,2023-08-09,2022-07-26
-4ylh,2015-08-05,2015-03-05
-5yl8,2017-11-01,2017-10-17
-6yly,2020-07-29,2020-04-07
-5ylu,2018-04-11,2017-10-19
-4ylg,2015-05-20,2015-03-05
-7ylo,2023-07-05,2022-07-26
-6yl4,2020-10-21,2020-04-06
-2yl7,2011-10-05,2011-05-31
-4yl2,2015-08-26,2015-03-04
-1ylv,2000-02-23,1999-02-22
-7yls,2023-06-14,2022-07-26
-7yl5,2023-06-07,2022-07-25
-4ylz,2015-07-01,2015-03-06
-5ylb,2018-10-24,2017-10-17
-5ylw,2018-10-24,2017-10-20
-4yl9,2015-11-04,2015-03-05
-2ylq,2011-07-06,2011-06-04
-2ylr,2011-06-22,2011-06-06
-6yln,2020-12-16,2020-04-07
-4yl0,2015-06-10,2015-03-04
-6yl0,2020-07-15,2020-04-06
-6ylk,2020-07-22,2020-04-07
-1ylt,2005-04-19,2005-01-19
-6yll,2020-09-23,2020-04-07
-2yl1,2011-10-05,2011-05-30
-5yl2,2018-04-18,2017-10-16
-4yli,2015-04-08,2015-03-05
-6ylo,2020-12-16,2020-04-07
-2yla,2011-09-07,2011-06-01
-1yl0,2005-07-05,2005-01-18
-1yli,2005-02-01,2005-01-19
-7yly,2023-03-29,2022-07-27
-6yla,2020-04-15,2020-04-06
-7yl1,2023-07-26,2022-07-25
-4yla,2016-03-16,2015-03-05
-2ylg,2011-10-05,2011-06-02
-5ylk,2018-06-20,2017-10-17
-5yl3,2017-12-27,2017-10-17
-7yla,2023-01-04,2022-07-25
-4yl3,2015-07-08,2015-03-04
-2yld,2011-10-05,2011-06-02
-2yln,2011-12-14,2011-06-03
-7yle,2023-01-25,2022-07-26
-1yl7,2006-01-17,2005-01-19
-2ylw,2011-06-22,2011-06-06
-5yli,2018-06-20,2017-10-17
-2ylx,2011-06-22,2011-06-06
-1ylj,2005-04-19,2005-01-19
-4ylw,2016-03-09,2015-03-06
-5ylf,2017-11-08,2017-10-17
-2ylp,2011-07-06,2011-06-04
-1ylz,2005-04-26,2005-01-19
-1yl5,2006-01-17,2005-01-19
-2ylc,2011-07-20,2011-06-01
-5ylv,2018-04-11,2017-10-19
-1ylb,2005-04-05,2005-01-19
-2yls,2011-06-22,2011-06-06
-5yln,2018-10-24,2017-10-18
-6yl9,2020-07-15,2020-04-06
-1yl6,2006-01-17,2005-01-19
-4ylp,2015-04-22,2015-03-05
-7yl4,2023-06-07,2022-07-25
-5yly,2018-05-23,2017-10-20
-5ylt,2018-06-20,2017-10-19
-5ylx,2018-10-24,2017-10-20
-1sz2,2004-11-16,2004-04-02
-6szw,2020-07-22,2019-10-02
-5szk,2016-08-24,2016-08-14
-5szh,2016-08-24,2016-08-14
-3sz9,2011-11-02,2011-07-18
-1sz3,2004-05-11,2004-04-02
-6sz6,2019-12-11,2019-10-02
-8szs,2023-09-06,2023-05-30
-5szc,2017-08-16,2016-08-13
-6sza,2020-02-19,2019-10-02
-1szk,2005-03-01,2004-04-05
-8sz8,2024-05-01,2023-05-27
-6szb,2020-02-19,2019-10-02
-1sza,2004-07-13,2004-04-05
-8szy,2023-09-20,2023-05-30
-7sz9,2022-11-23,2021-11-26
-8sz6,2024-03-20,2023-05-27
-1szr,2004-10-26,2004-04-06
-1szd,2004-06-15,2004-04-05
-8szo,2023-09-27,2023-05-30
-6szg,2020-01-22,2019-10-02
-3sz0,2012-05-16,2011-07-18
-1szs,2005-03-01,2004-04-06
-7szs,2021-12-15,2021-11-29
-1szm,2004-06-01,2004-04-06
-3szs,2012-07-25,2011-07-19
-5szi,2016-08-24,2016-08-14
-8szt,2023-09-06,2023-05-30
-8szi,2024-02-07,2023-05-29
-1szu,2005-03-01,2004-04-06
-3sz3,2011-09-14,2011-07-18
-5sz1,2016-12-21,2016-08-12
-1szj,1998-09-16,1997-02-04
-7szb,2023-01-25,2021-11-27
-5szz,2016-09-14,2016-08-15
-6sz7,2020-03-04,2019-10-02
-6szl,2020-03-04,2019-10-02
-6szn,2020-03-04,2019-10-02
-7szi,2022-06-08,2021-11-27
-5sz6,2016-12-28,2016-08-12
-5szj,2016-08-24,2016-08-14
-3szj,2012-04-11,2011-07-19
-5szy,2016-09-14,2016-08-15
-7szh,2022-01-19,2021-11-27
-3szf,2012-05-16,2011-07-18
-6sz0,2019-11-27,2019-10-01
-6sz5,2019-12-11,2019-10-02
-1sze,2004-07-27,2004-04-05
-1szo,2004-06-29,2004-04-06
-5szt,2016-12-14,2016-08-15
-6sze,2019-10-23,2019-10-02
-5szv,2016-09-14,2016-08-15
-6sz2,2020-03-04,2019-10-01
-1szx,2004-04-27,2004-04-06
-3szn,2012-07-25,2011-07-19
-5szo,2016-10-19,2016-08-14
-7sze,2022-01-19,2021-11-27
-8szb,2023-06-14,2023-05-29
-3szt,2011-09-28,2011-07-19
-3szw,2012-05-16,2011-07-19
-1sz6,2004-10-05,2004-04-04
-1szg,2004-07-27,2004-04-05
-3szu,2011-11-30,2011-07-19
-3sz2,2012-06-06,2011-07-18
-3sza,2011-11-02,2011-07-18
-8sz2,2024-05-29,2023-05-26
-5szu,2016-09-14,2016-08-15
-7szc,2022-12-14,2021-11-27
-1szz,2005-08-16,2004-04-06
-6szs,2019-12-04,2019-10-02
-3szz,2011-08-03,2011-07-19
-3szk,2011-09-14,2011-07-19
-7sza,2023-01-25,2021-11-27
-6szi,2020-06-17,2019-10-02
-6szy,2020-03-04,2019-10-02
-7sz2,2022-10-05,2021-11-25
-6szd,2020-10-14,2019-10-02
-6sz8,2020-03-04,2019-10-02
-5szr,2016-10-19,2016-08-14
-5sz0,2016-12-21,2016-08-12
-7szd,2022-12-14,2021-11-27
-1szc,2004-06-15,2004-04-05
-8szu,2023-09-06,2023-05-30
-3szb,2011-11-02,2011-07-18
-5szl,2016-10-19,2016-08-14
-7szf,2022-01-19,2021-11-27
-5szm,2016-10-19,2016-08-14
-8szz,2023-11-01,2023-05-30
-8szc,2023-11-15,2023-05-29
-8szq,2023-08-02,2023-05-30
-5sz3,2016-12-21,2016-08-12
-8szh,2024-02-07,2023-05-29
-1szf,2004-07-27,2004-04-05
-7szj,2022-07-13,2021-11-28
-6sz9,2020-05-13,2019-10-02
-6szh,2020-01-22,2019-10-02
-1szn,2004-08-10,2004-04-06
-5szs,2016-09-14,2016-08-15
-6szv,2020-04-15,2019-10-02
-6sz4,2019-11-27,2019-10-01
-7szr,2023-06-07,2021-11-29
-6szj,2019-12-04,2019-10-02
-1sz8,2004-04-20,2004-04-05
-8sza,2023-06-14,2023-05-29
-7szp,2021-12-15,2021-11-29
-6szo,2019-11-27,2019-10-02
-7szx,2022-03-30,2021-11-29
-8szv,2023-10-11,2023-05-30
-8sz3,2023-12-06,2023-05-26
-6szm,2019-10-16,2019-10-02
-5szq,2016-11-02,2016-08-14
-3szo,2011-11-30,2011-07-19
-3sz4,2012-02-15,2011-07-18
-3szm,2011-11-30,2011-07-19
-5sz7,2016-12-21,2016-08-12
-5sz5,2016-12-28,2016-08-12
-7szk,2022-07-13,2021-11-28
-6szu,2020-04-15,2019-10-02
-5szp,2016-10-19,2016-08-14
-6sz1,2020-03-04,2019-10-01
-3szl,2011-11-30,2011-07-19
-3szq,2011-10-12,2011-07-19
-1sz0,2004-06-29,2004-04-01
-8sze,2023-06-07,2023-05-29
-7szg,2022-01-19,2021-11-27
-8szp,2023-08-02,2023-05-30
-3szy,2011-08-03,2011-07-19
-5sz9,2016-11-02,2016-08-12
-3szg,2012-04-11,2011-07-19
-8szr,2023-08-02,2023-05-30
-5sz2,2016-12-21,2016-08-12
-3sz5,2012-02-15,2011-07-18
-8szd,2023-06-07,2023-05-29
-6szk,2020-10-14,2019-10-02
-6sz3,2020-03-04,2019-10-01
-1szb,2004-06-22,2004-04-05
-3szc,2012-05-16,2011-07-18
-5szb,2017-08-16,2016-08-13
-6szp,2019-12-25,2019-10-02
-6szt,2020-03-04,2019-10-02
-6szr,2020-03-04,2019-10-02
-8szg,2024-02-07,2023-05-29
-3sz1,2012-03-21,2011-07-18
-7sz8,2022-12-14,2021-11-26
-5sz4,2016-12-21,2016-08-12
-6szx,2020-03-04,2019-10-02
-8szj,2024-03-13,2023-05-29
-5sze,2017-04-12,2016-08-13
-7szt,2022-03-02,2021-11-29
-7sz3,2022-10-05,2021-11-25
-7szv,2021-12-22,2021-11-29
-5szn,2016-10-19,2016-08-14
-8szf,2024-02-07,2023-05-29
-7szq,2022-11-09,2021-11-29
-3uwz,2012-10-17,2011-12-03
-5uwq,2017-03-22,2017-02-21
-2uwu,2007-07-03,2007-03-23
-2uwj,2007-05-15,2007-03-22
-4uwo,2015-02-04,2014-08-14
-6uwc,2020-11-18,2019-11-05
-1uwc,2004-05-06,2004-02-03
-1uwu,2004-05-20,2004-02-11
-3uwo,2012-02-01,2011-12-02
-7uw2,2023-03-15,2022-05-02
-8uwa,2024-05-08,2023-11-06
-4uws,2015-02-04,2014-08-14
-6uwu,2020-04-15,2019-11-05
-4uwu,2014-12-10,2014-08-14
-4uwr,2015-02-04,2014-08-14
-4uw4,2014-11-12,2014-08-08
-2uw6,2007-05-08,2007-03-19
-6uwg,2019-12-18,2019-11-05
-1uwl,2004-08-19,2004-02-05
-7uwp,2023-04-12,2022-05-03
-7uwu,2023-06-14,2022-05-04
-3uwu,2012-10-17,2011-12-03
-1uwv,2004-03-18,2004-02-11
-4uwh,2014-11-26,2014-08-12
-6uwl,2020-04-22,2019-11-05
-4uw0,2014-08-27,2014-08-08
-5uwx,2017-03-01,2017-02-21
-4uw3,2014-11-12,2014-08-08
-1uwy,2004-04-08,2004-02-17
-4uwf,2014-11-26,2014-08-12
-8uwb,2024-04-17,2023-11-06
-7uwm,2022-07-27,2022-05-03
-1uwb,1997-05-15,1996-11-21
-3uwd,2012-01-11,2011-12-01
-5uw4,2018-02-28,2017-02-20
-6uwx,2020-01-01,2019-11-05
-1uw3,2004-03-25,2004-01-29
-6uwh,2019-12-18,2019-11-05
-1uw8,2004-02-19,2004-02-02
-1uw9,2005-01-12,2004-02-03
-3uw9,2012-03-14,2011-12-01
-5uwd,2017-10-18,2017-02-21
-4uwn,2014-12-10,2014-08-13
-3uwq,2011-12-14,2011-12-02
-7uww,2023-06-14,2022-05-04
-1uwj,2004-03-19,2004-02-05
-7uwe,2023-05-31,2022-05-03
-3uwx,2012-02-08,2011-12-03
-5uw1,2018-02-28,2017-02-20
-2uwh,2007-08-28,2007-03-21
-4uwk,2014-11-26,2014-08-12
-6uwb,2020-11-18,2019-11-05
-5uw7,2017-05-31,2017-02-20
-4uwq,2015-12-09,2014-08-14
-6uwq,2020-11-11,2019-11-05
-5uwc,2018-02-07,2017-02-21
-7uw0,2023-01-11,2022-05-02
-3uw5,2012-02-22,2011-11-30
-4uwj,2014-12-03,2014-08-12
-6uwp,2019-12-11,2019-11-05
-1uww,2004-05-13,2004-02-12
-3uwm,2012-09-05,2011-12-02
-6uw7,2020-05-13,2019-11-04
-6uw2,2020-10-21,2019-11-04
-2uwd,2007-04-24,2007-03-20
-5uwk,2017-07-12,2017-02-21
-2uw1,2007-05-08,2007-03-15
-6uwt,2020-01-22,2019-11-05
-1uwr,2004-05-20,2004-02-11
-5uw3,2017-05-31,2017-02-20
-2uw9,2007-05-08,2007-03-19
-2uw3,2007-05-08,2007-03-19
-6uwf,2020-06-03,2019-11-05
-2uwf,2008-05-27,2007-03-21
-6uw4,2020-07-01,2019-11-04
-6uwd,2020-11-25,2019-11-05
-6uwk,2019-12-18,2019-11-05
-8uwp,2023-11-22,2023-11-07
-2uwv,2007-07-03,2007-03-23
-6uwn,2020-03-18,2019-11-05
-2uw5,2007-05-08,2007-03-19
-2uwl,2007-04-24,2007-03-22
-5uww,2017-03-22,2017-02-21
-2uw2,2007-04-03,2007-03-16
-4uwt,2015-08-26,2014-08-14
-5uwo,2017-03-22,2017-02-21
-8uwv,2023-11-22,2023-11-08
-4uw5,2014-11-12,2014-08-08
-8uw0,2023-11-15,2023-11-05
-7uwl,2022-07-27,2022-05-03
-4uwc,2015-09-02,2014-08-11
-5uwm,2017-07-12,2017-02-21
-3uwp,2012-03-14,2011-12-02
-4uwi,2014-12-03,2014-08-12
-1uwf,2005-02-16,2004-02-05
-1uwn,2004-03-25,2004-02-10
-7uw1,2023-04-19,2022-05-02
-1uw1,2004-03-26,2004-01-28
-6uww,2020-11-11,2019-11-05
-8uw6,2024-05-29,2023-11-06
-5uw5,2017-05-31,2017-02-20
-1uws,2004-05-20,2004-02-11
-5uwl,2017-07-12,2017-02-21
-5uwf,2017-04-26,2017-02-21
-8uwl,2024-05-29,2023-11-06
-3uww,2012-10-17,2011-12-03
-3uwc,2011-12-14,2011-12-01
-7uwh,2023-05-31,2022-05-03
-3uwl,2012-08-29,2011-12-02
-2uwt,2007-07-03,2007-03-23
-3uwe,2012-04-04,2011-12-01
-2uwp,2007-05-08,2007-03-22
-1uw0,2004-08-05,2004-01-27
-6uw0,2019-12-18,2019-11-04
-1uwa,2005-01-12,2004-02-03
-6uwz,2020-04-15,2019-11-06
-7uwo,2022-12-28,2022-05-03
-6uw3,2020-05-13,2019-11-04
-5uwh,2017-03-22,2017-02-21
-6uwv,2019-12-11,2019-11-05
-2uwe,2007-09-25,2007-03-20
-6uwr,2020-01-22,2019-11-05
-3uwn,2012-03-07,2011-12-02
-2uwo,2007-05-08,2007-03-22
-5uwr,2017-03-22,2017-02-21
-1uwp,2006-05-10,2004-02-11
-6uwj,2019-12-18,2019-11-05
-7uwi,2022-12-28,2022-05-03
-2uw4,2007-05-08,2007-03-19
-2uww,2007-07-03,2007-03-23
-4uwg,2014-11-26,2014-08-12
-5uwi,2017-03-22,2017-02-21
-3uw2,2012-02-01,2011-11-30
-1uwh,2004-03-19,2004-02-05
-7uw4,2023-03-15,2022-05-02
-5uwg,2017-06-14,2017-02-21
-5uwt,2017-03-22,2017-02-21
-3uwj,2012-12-12,2011-12-02
-5uw6,2017-05-31,2017-02-20
-5uwy,2017-03-15,2017-02-21
-3uwk,2012-02-01,2011-12-02
-8uw3,2023-12-20,2023-11-06
-2uw8,2007-05-08,2007-03-19
-3uw4,2012-02-22,2011-11-30
-5uws,2017-03-22,2017-02-21
-7uwn,2022-07-27,2022-05-03
-3uwi,2012-12-05,2011-12-02
-7uw6,2022-10-19,2022-05-02
-1uwk,2004-08-19,2004-02-05
-6uwy,2020-02-12,2019-11-05
-5uwp,2017-03-22,2017-02-21
-4uw1,2015-07-08,2014-08-08
-3uw8,2012-12-05,2011-12-01
-5uwn,2017-07-12,2017-02-21
-4uwv,2014-12-10,2014-08-14
-4uwl,2014-11-26,2014-08-12
-5uw2,2017-04-12,2017-02-20
-1uwz,2004-05-20,2004-02-18
-4uwp,2015-02-04,2014-08-14
-6uw1,2020-05-13,2019-11-04
-4uwb,2015-09-02,2014-08-11
-5uwj,2017-03-22,2017-02-21
-1uwt,2004-05-20,2004-02-11
-1uwg,2004-02-27,2004-02-05
-2uw7,2007-05-08,2007-03-19
-4uwd,2014-08-27,2014-08-11
-5uw0,2018-02-28,2017-02-20
-3uwa,2013-01-09,2011-12-01
-6uwa,2020-12-09,2019-11-04
-1uw6,2004-03-25,2004-01-30
-2uws,2007-07-03,2007-03-23
-7uwj,2022-07-27,2022-05-03
-3uwv,2012-10-17,2011-12-03
-4uw9,2014-10-29,2014-08-09
-7uwt,2022-05-18,2022-05-03
-5uwu,2017-03-22,2017-02-21
-8uws,2024-05-15,2023-11-08
-6uwi,2020-01-22,2019-11-05
-2uw0,2007-05-08,2007-03-15
-4uwx,2015-05-06,2014-08-15
-3uwb,2013-01-09,2011-12-01
-4uwm,2015-08-26,2014-08-12
-7uwv,2023-06-14,2022-05-04
-6uw5,2020-05-13,2019-11-04
-4uw6,2014-11-12,2014-08-08
-6x8x,2020-09-16,2020-06-02
-2x8g,2010-07-21,2010-03-09
-4x81,2015-03-04,2014-12-09
-2x8j,2010-08-11,2010-03-09
-7x8s,2022-06-29,2022-03-14
-2x81,2010-05-05,2010-03-05
-4x8e,2015-01-28,2014-12-10
-5x8d,2018-03-14,2017-03-02
-4x8o,2015-07-15,2014-12-10
-2x8b,2010-04-28,2010-03-08
-4x8c,2015-01-28,2014-12-10
-7x8f,2023-01-18,2022-03-12
-7x8x,2023-04-12,2022-03-15
-4x8y,2016-03-23,2014-12-11
-7x88,2023-01-18,2022-03-11
-7x81,2023-02-08,2022-03-10
-7x8b,2023-01-18,2022-03-11
-6x82,2021-01-13,2020-06-01
-1x8r,2005-04-19,2004-08-18
-5x8g,2017-06-07,2017-03-02
-6x8y,2021-06-02,2020-06-02
-6x83,2021-01-13,2020-06-01
-6x85,2021-01-13,2020-06-01
-2x8h,2010-07-21,2010-03-09
-7x8g,2023-01-18,2022-03-12
-5x8k,2018-03-14,2017-03-03
-6x8d,2021-06-02,2020-06-01
-1x87,2004-10-05,2004-08-17
-5x8v,2018-03-14,2017-03-03
-7x8i,2022-06-01,2022-03-13
-4x8a,2016-03-09,2014-12-10
-7x8a,2022-11-16,2022-03-11
-1x8l,2005-02-08,2004-08-18
-2x8y,2010-06-02,2010-03-14
-1x82,2004-10-12,2004-08-17
-2x8e,2010-08-11,2010-03-09
-2x86,2010-03-16,2010-03-06
-5x8x,2017-06-07,2017-03-03
-1x8d,2005-05-17,2004-08-18
-5x80,2017-08-09,2017-02-28
-6x8z,2020-09-16,2020-06-02
-7x8k,2022-05-18,2022-03-13
-4x8u,2015-03-25,2014-12-10
-1x8h,2004-12-28,2004-08-18
-2x8u,2010-03-23,2010-03-12
-2x8p,2011-04-06,2010-03-10
-1x89,2005-01-25,2004-08-17
-7x8h,2022-06-01,2022-03-13
-2x87,2010-09-22,2010-03-06
-5x86,2018-03-14,2017-03-01
-1x8x,2005-01-25,2004-08-19
-6x8a,2021-06-02,2020-06-01
-1x8v,2004-11-23,2004-08-18
-5x8s,2017-06-07,2017-03-03
-7x8r,2022-06-29,2022-03-14
-8x83,2024-02-07,2023-11-27
-6x89,2020-09-02,2020-06-01
-1x8j,2005-02-08,2004-08-18
-7x87,2022-04-20,2022-03-11
-4x8l,2015-07-22,2014-12-10
-1x83,2005-01-25,2004-08-17
-7x86,2023-02-08,2022-03-11
-1x8n,2004-10-05,2004-08-18
-2x8m,2011-04-06,2010-03-10
-7x8c,2022-08-17,2022-03-12
-2x8z,2010-06-02,2010-03-14
-7x8e,2022-06-01,2022-03-12
-4x85,2015-06-10,2014-12-10
-1x8o,2004-10-05,2004-08-18
-5x8w,2017-06-07,2017-03-03
-7x8p,2023-02-01,2022-03-14
-7x8y,2022-12-07,2022-03-15
-1x84,2005-01-25,2004-08-17
-8x8q,2024-05-29,2023-11-28
-6x8k,2021-06-02,2020-06-01
-6x8h,2021-06-02,2020-06-01
-8x84,2024-02-07,2023-11-27
-2x8i,2010-08-11,2010-03-09
-5x87,2017-11-01,2017-03-01
-6x8i,2021-06-02,2020-06-01
-5x8c,2018-03-14,2017-03-02
-4x8q,2015-05-27,2014-12-10
-1x88,2005-11-15,2004-08-17
-1x8p,2004-10-05,2004-08-18
-7x8z,2022-12-07,2022-03-15
-1x8s,2004-12-07,2004-08-18
-5x8b,2018-03-14,2017-03-01
-6x8e,2020-11-25,2020-06-01
-4x8t,2015-03-25,2014-12-10
-6x8g,2020-11-25,2020-06-01
-2x8d,2010-08-11,2010-03-08
-6x81,2021-01-13,2020-06-01
-1x8i,2004-12-28,2004-08-18
-6x80,2020-07-08,2020-06-01
-2x8s,2011-03-23,2010-03-11
-5x8q,2017-06-07,2017-03-03
-4x8r,2014-12-24,2014-12-10
-1x81,2004-12-21,2004-08-16
-2x8f,2011-03-23,2010-03-09
-5x8n,2017-04-19,2017-03-03
-5x8u,2017-06-07,2017-03-03
-1x8t,2005-04-19,2004-08-18
-2x8c,2010-07-21,2010-03-08
-6x86,2021-01-13,2020-06-01
-4x8v,2015-03-25,2014-12-10
-2x88,2010-09-22,2010-03-06
-1x8q,2004-10-05,2004-08-18
-1x8b,2005-06-07,2004-08-17
-4x8x,2015-12-16,2014-12-11
-1x8u,2005-01-25,2004-08-18
-2x80,2011-03-23,2010-03-05
-4x8g,2015-01-28,2014-12-10
-1x8g,2004-12-28,2004-08-18
-4x8b,2015-01-28,2014-12-10
-4x8s,2015-03-25,2014-12-10
-6x8j,2021-06-02,2020-06-01
-4x88,2016-02-24,2014-12-10
-4x8d,2015-01-28,2014-12-10
-4x89,2016-03-09,2014-12-10
-4x8i,2016-02-10,2014-12-10
-7x8d,2022-06-01,2022-03-12
-1x80,2004-11-23,2004-08-16
-6x8f,2020-11-25,2020-06-01
-6x8l,2021-06-02,2020-06-01
-5x8i,2017-08-16,2017-03-02
-1x8k,2005-02-08,2004-08-18
-4x8j,2015-04-08,2014-12-10
-2x8t,2011-03-23,2010-03-11
-4x83,2015-12-16,2014-12-10
-2x8o,2011-04-06,2010-03-10
-7x8w,2022-12-07,2022-03-15
-5x8a,2018-03-14,2017-03-01
-2x85,2011-03-23,2010-03-05
-1x8c,2005-08-09,2004-08-18
-5x8f,2017-06-07,2017-03-02
-4rvu,2015-06-24,2014-11-27
-8rv5,2024-02-14,2024-01-31
-3rv6,2012-05-09,2011-05-06
-5rv6,2020-12-16,2020-09-28
-5rvf,2020-12-16,2020-09-28
-6rvz,2020-05-20,2019-06-03
-4rv8,2014-12-31,2014-11-25
-8rvm,2024-03-27,2024-02-01
-5rvm,2020-12-16,2020-10-02
-7rvy,2022-07-20,2021-08-19
-7rvi,2022-08-24,2021-08-18
-3rvr,2012-05-09,2011-05-06
-1rvy,2004-06-15,2003-12-15
-2rv3,2015-04-08,2015-01-26
-7rv3,2022-08-24,2021-08-18
-6rvd,2019-10-02,2019-05-31
-3rvn,2012-05-09,2011-05-06
-7rv9,2022-08-24,2021-08-18
-4rvd,2015-01-28,2014-11-26
-1rv8,2004-01-27,2003-12-12
-1rv7,2004-12-14,2003-12-12
-1rv4,2004-06-15,2003-12-12
-5rv8,2020-12-16,2020-09-28
-1rvc,1995-01-26,1994-10-21
-2rv4,2015-04-08,2015-01-26
-6rvc,2019-10-02,2019-05-31
-6rv6,2019-08-21,2019-05-31
-5rvq,2020-12-16,2020-10-02
-2rv6,2015-04-08,2015-01-26
-5rvb,2020-12-16,2020-09-28
-5rvi,2020-12-16,2020-09-28
-2rv1,2015-04-08,2015-01-26
-1rvg,2004-01-27,2003-12-13
-5rvp,2020-12-16,2020-10-02
-2rve,1992-01-15,1991-03-19
-1rv1,2004-01-20,2003-12-12
-5rvj,2020-12-16,2020-10-02
-2rv0,2015-04-08,2015-01-26
-7rvz,2022-07-20,2021-08-19
-5rvd,2020-12-16,2020-09-28
-6rvh,2019-09-25,2019-05-31
-3rv9,2012-05-09,2011-05-06
-5rv4,2020-12-16,2020-09-28
-5rv9,2020-12-16,2020-09-28
-7rvk,2022-08-24,2021-08-18
-7rvq,2022-07-20,2021-08-19
-1rvx,2004-03-30,2003-12-15
-7rv4,2022-08-24,2021-08-18
-3rvo,2012-05-09,2011-05-06
-3rvk,2012-05-09,2011-05-06
-1rvb,1995-01-26,1994-10-21
-5rvu,2020-12-16,2020-10-02
-4rv3,2015-07-01,2014-11-24
-7rvr,2022-07-20,2021-08-19
-3rvj,2012-05-09,2011-05-06
-3rvi,2011-08-31,2011-05-06
-6rv9,2020-03-18,2019-05-31
-3rvh,2012-05-09,2011-05-06
-7rv2,2022-11-09,2021-08-18
-2rv7,2015-04-08,2015-01-26
-5rvh,2020-12-16,2020-09-28
-5rvg,2020-12-16,2020-09-28
-4rvb,2015-12-02,2014-11-25
-4rvx,2016-05-04,2014-11-28
-6rvk,2019-08-28,2019-05-31
-7rv5,2022-08-24,2021-08-18
-4rvm,2015-06-03,2014-11-26
-7rv6,2022-08-24,2021-08-18
-6rv7,2020-03-18,2019-05-31
-6rvn,2020-02-19,2019-05-31
-1rvj,2004-04-13,2003-12-14
-5rv7,2020-12-16,2020-09-28
-1rvz,2004-03-30,2003-12-15
-6rv5,2020-04-01,2019-05-31
-7rv8,2022-08-24,2021-08-18
-4rv4,2014-12-17,2014-11-24
-5rvl,2020-12-16,2020-10-02
-2rv5,2015-04-08,2015-01-26
-2rv2,2015-04-08,2015-01-26
-7rvx,2022-07-20,2021-08-19
-4rv9,2015-02-04,2014-11-25
-3rv2,2011-05-18,2011-05-05
-5rvo,2020-12-16,2020-10-02
-8rv2,2024-04-10,2024-01-31
-3rvb,2014-09-24,2011-05-06
-3rvf,2011-09-21,2011-05-06
-4rvy,2015-11-04,2014-11-29
-4rvk,2015-06-03,2014-11-26
-7rvs,2022-07-20,2021-08-19
-6rv1,2020-04-08,2019-05-30
-4rv5,2014-12-10,2014-11-24
-7rv7,2022-08-24,2021-08-18
-5rvc,2020-12-16,2020-09-28
-7rvp,2022-07-20,2021-08-19
-6rvv,2019-06-12,2019-06-03
-4rvl,2015-06-03,2014-11-26
-5rvn,2020-12-16,2020-10-02
-5rv5,2020-12-16,2020-09-28
-1rvt,2004-03-30,2003-12-15
-4rvi,2016-05-04,2014-11-26
-4rvg,2015-01-28,2014-11-26
-3rva,2012-05-09,2011-05-06
-3rv7,2012-05-09,2011-05-06
-4rvj,2016-05-04,2014-11-26
-6rv3,2019-08-07,2019-05-30
-5rva,2020-12-16,2020-09-28
-6rv8,2020-03-18,2019-05-31
-4rvh,2015-01-28,2014-11-26
-5rvt,2020-12-16,2020-10-02
-3rvg,2012-03-21,2011-05-06
-3rv8,2012-05-09,2011-05-06
-5rvv,2020-12-16,2020-10-02
-3rvl,2012-05-09,2011-05-06
-3rv5,2011-08-31,2011-05-06
-6rvm,2020-02-19,2019-05-31
-7rvw,2022-07-20,2021-08-19
-1rvw,1998-03-25,1997-03-20
-6rv4,2019-08-07,2019-05-30
-5rv0,2020-12-16,2020-09-28
-5rvy,2020-11-25,2020-10-27
-7rvo,2022-07-20,2021-08-19
-7rvn,2022-07-20,2021-08-19
-7rvm,2022-07-20,2021-08-19
-4rvw,2015-08-19,2014-11-28
-5rvr,2020-12-16,2020-10-02
-5rvk,2020-12-16,2020-10-02
-3rvd,2012-04-25,2011-05-06
-4rvt,2015-05-27,2014-11-27
-1rv3,2004-06-15,2003-12-12
-3rv4,2011-05-18,2011-05-05
-3rvq,2012-05-09,2011-05-06
-3rv3,2011-05-18,2011-05-05
-5rv3,2020-12-16,2020-09-28
-6rvq,2020-02-19,2019-05-31
-5rvw,2020-11-25,2020-10-27
-7rv0,2022-11-09,2021-08-18
-1rvd,1999-05-28,1999-05-03
-1rv0,2004-03-30,2003-12-12
-7rvv,2022-07-20,2021-08-19
-4rvp,2015-12-16,2014-11-27
-5rvs,2020-12-16,2020-10-02
-5rv2,2020-12-16,2020-09-28
-4rvf,2015-01-28,2014-11-26
-1rvk,2003-12-23,2003-12-14
-7rvu,2022-07-20,2021-08-19
-7rv1,2022-11-09,2021-08-18
-3rvs,2012-05-09,2011-05-06
-5rve,2020-12-16,2020-09-28
-4rv7,2015-01-28,2014-11-25
-6rv0,2020-04-08,2019-05-30
-8rv0,2024-03-27,2024-01-31
-4rvr,2014-12-10,2014-11-27
-5rvz,2020-11-25,2020-10-27
-3rvp,2012-05-09,2011-05-06
-1rvv,1996-12-07,1995-10-25
-3rvm,2012-05-09,2011-05-06
-7rva,2021-09-01,2021-08-18
-5rvx,2020-11-25,2020-10-27
-6rvp,2020-02-19,2019-05-31
-1rvu,2004-06-15,2003-12-15
-6rvw,2019-06-12,2019-06-03
-6rvb,2019-09-25,2019-05-31
-4rv6,2015-12-09,2014-11-25
-7rvt,2022-07-20,2021-08-19
-4rvz,2015-03-11,2014-11-29
-3rv0,2011-08-03,2011-05-05
-6rv2,2019-08-07,2019-05-30
-1v7a,2004-12-21,2003-12-14
-3v7w,2012-03-14,2011-12-22
-2v7q,2007-09-18,2007-07-31
-2v7l,2007-08-07,2007-07-30
-7v76,2021-10-06,2021-08-21
-8v7a,2024-05-15,2023-12-04
-4v7z,2014-07-09,2010-08-18
-3v7y,2012-03-14,2011-12-22
-3v7s,2012-04-25,2011-12-21
-7v7i,2021-10-06,2021-08-21
-2v7a,2007-09-18,2007-07-27
-2v7z,2008-04-08,2007-08-02
-2v7e,2007-10-02,2007-07-30
-2v74,2007-10-02,2007-07-26
-4v7w,2014-07-09,2010-08-16
-5v7t,2017-05-03,2017-03-20
-8v7u,2023-12-20,2023-12-04
-6v7y,2020-09-16,2019-12-10
-2v7w,2008-08-12,2007-08-02
-2v70,2007-08-28,2007-07-24
-7v75,2022-08-31,2021-08-21
-3v7c,2012-04-18,2011-12-20
-8v7r,2023-12-20,2023-12-04
-5v72,2017-03-29,2017-03-17
-4v7n,2014-07-09,2009-12-15
-5v7j,2017-06-21,2017-03-20
-6v7c,2020-05-06,2019-12-08
-7v7a,2021-10-06,2021-08-21
-7v7d,2021-10-06,2021-08-21
-7v7s,2021-10-06,2021-08-21
-6v7o,2020-02-19,2019-12-09
-3v7r,2012-12-26,2011-12-21
-4v7c,2014-07-09,2013-11-20
-4v7q,2014-07-09,2010-05-13
-2v7p,2007-09-25,2007-07-31
-8v7c,2024-05-15,2023-12-04
-7v78,2021-10-06,2021-08-21
-3v70,2012-01-11,2011-12-20
-3v76,2012-01-04,2011-12-20
-6v7e,2020-05-06,2019-12-08
-6v79,2020-12-02,2019-12-08
-4v7s,2014-07-09,2010-08-05
-2v7o,2007-09-11,2007-07-31
-3v7f,2012-06-27,2011-12-21
-6v7f,2020-05-06,2019-12-08
-6v7t,2020-04-22,2019-12-09
-3v77,2012-01-18,2011-12-20
-7v7h,2021-10-06,2021-08-21
-5v71,2017-08-23,2017-03-17
-2v7y,2008-04-08,2007-08-02
-1v7t,2004-04-06,2003-12-22
-7v7k,2022-08-24,2021-08-21
-7v7u,2021-10-06,2021-08-21
-1v70,2004-12-14,2003-12-05
-5v7i,2017-10-11,2017-03-20
-8v7l,2024-03-20,2023-12-04
-1v7x,2004-06-22,2003-12-24
-5v7a,2017-12-06,2017-03-20
-4v7t,2014-07-09,2010-08-14
-5v7e,2018-06-20,2017-03-20
-7v7q,2021-10-06,2021-08-21
-2v7i,2007-08-07,2007-07-30
-3v7j,2013-01-16,2011-12-21
-3v7p,2012-01-11,2011-12-21
-7v7j,2021-10-06,2021-08-21
-7v7v,2021-10-06,2021-08-21
-2v79,2008-01-15,2007-07-27
-7v7t,2021-10-06,2021-08-21
-6v7a,2020-12-02,2019-12-08
-7v7g,2021-10-06,2021-08-21
-5v7y,2017-10-18,2017-03-21
-7v77,2021-10-06,2021-08-21
-5v79,2017-12-06,2017-03-20
-3v7t,2012-03-14,2011-12-22
-4v7p,2014-07-09,2010-04-29
-2v7d,2008-06-24,2007-07-30
-3v72,2012-07-04,2011-12-20
-6v7k,2020-12-09,2019-12-08
-8v7j,2024-05-15,2023-12-04
-1v7p,2004-09-07,2003-12-19
-5v7p,2018-01-17,2017-03-20
-4v7v,2014-07-09,2010-08-16
-1v75,2003-12-30,2003-12-12
-1v7z,2004-01-27,2003-12-26
-1v7v,2004-06-22,2003-12-24
-6v7z,2020-09-16,2019-12-10
-4v7y,2014-07-09,2010-08-18
-7v79,2021-10-06,2021-08-21
-2v7v,2008-08-12,2007-08-02
-6v7h,2020-08-12,2019-12-08
-6v7d,2020-05-06,2019-12-08
-4v7j,2014-07-09,2009-11-02
-1v7c,2003-12-30,2003-12-16
-6v7x,2020-12-16,2019-12-09
-6v73,2019-12-25,2019-12-06
-4v7b,2014-07-09,2013-10-27
-7v73,2022-08-31,2021-08-21
-1v72,2005-03-01,2003-12-09
-6v70,2019-12-25,2019-12-06
-3v7z,2012-12-26,2011-12-22
-8v7k,2024-05-15,2023-12-04
-6v7r,2020-04-01,2019-12-09
-2v7j,2007-08-07,2007-07-30
-7v7n,2021-10-06,2021-08-21
-6v7w,2020-12-16,2019-12-09
-6v7i,2020-08-12,2019-12-08
-4v7x,2014-07-09,2010-08-17
-8v7i,2024-05-15,2023-12-04
-5v7w,2017-05-10,2017-03-20
-3v78,2012-12-26,2011-12-20
-8v7b,2024-05-15,2023-12-04
-8v7h,2024-05-15,2023-12-04
-2v73,2007-08-21,2007-07-25
-2v7x,2008-08-12,2007-08-02
-2v77,2008-07-01,2007-07-27
-5v7c,2017-04-19,2017-03-20
-6v7p,2020-04-08,2019-12-09
-7v7x,2022-08-31,2021-08-22
-3v7x,2012-04-04,2011-12-22
-6v72,2019-12-25,2019-12-06
-3v7m,2012-02-22,2011-12-21
-7v7o,2021-10-06,2021-08-21
-3v7u,2012-03-14,2011-12-22
-4v7l,2014-07-09,2009-11-12
-5v7g,2017-03-29,2017-03-20
-4v7m,2014-07-09,2009-11-12
-7v7p,2021-10-06,2021-08-21
-2v7g,2008-01-15,2007-07-30
-6v7s,2020-04-01,2019-12-09
-3v7l,2013-01-16,2011-12-21
-8v7d,2024-05-15,2023-12-04
-1v7h,2004-08-03,2003-12-17
-2v7t,2008-08-12,2007-08-01
-2v7m,2007-08-07,2007-07-30
-4v7d,2014-07-09,2013-11-21
-3v7k,2013-01-16,2011-12-21
-3v7q,2012-03-07,2011-12-21
-7v7e,2021-10-06,2021-08-21
-2v7k,2007-08-07,2007-07-30
-8v7g,2024-05-15,2023-12-04
-4v7u,2014-07-09,2010-08-15
-6v7n,2020-06-17,2019-12-09
-4v7k,2014-07-09,2009-11-02
-6v7j,2020-02-19,2019-12-08
-6v7q,2020-04-01,2019-12-09
-6v76,2020-03-18,2019-12-07
-5v7n,2017-03-29,2017-03-20
-7v7z,2021-10-06,2021-08-22
-8v7e,2024-05-15,2023-12-04
-1v7w,2004-06-22,2003-12-24
-2v72,2007-08-21,2007-07-25
-2v7u,2008-08-12,2007-08-02
-7v7r,2021-10-06,2021-08-21
-7v7f,2021-10-06,2021-08-21
-1v73,2005-03-01,2003-12-09
-1v71,2005-06-14,2003-12-09
-8v7f,2024-05-15,2023-12-04
-6v71,2019-12-25,2019-12-06
-7v74,2022-08-31,2021-08-21
-5v7m,2018-03-14,2017-03-20
-6v75,2020-03-18,2019-12-07
-1v7u,2004-01-13,2003-12-24
-1v79,2004-12-21,2003-12-14
-5v7v,2017-08-16,2017-03-20
-6v77,2020-01-15,2019-12-07
-6v74,2020-03-18,2019-12-07
-3v71,2012-01-04,2011-12-20
-5s8d,2021-01-13,2020-12-17
-5s8p,2021-01-13,2020-12-17
-3s8j,2011-11-02,2011-05-29
-7s87,2021-09-29,2021-09-17
-7s8n,2021-11-17,2021-09-18
-1s8l,2004-06-08,2004-02-02
-6s82,2020-04-29,2019-07-08
-7s89,2021-11-17,2021-09-17
-5s8v,2021-02-17,2021-01-22
-1s8f,2004-06-11,2004-02-02
-5s8y,2021-02-17,2021-01-22
-7s8l,2021-11-17,2021-09-18
-5s8i,2021-01-13,2020-12-17
-1s8j,2004-06-08,2004-02-02
-8s8w,2024-03-20,2024-03-07
-6s8w,2020-08-26,2019-07-10
-7s8f,2022-11-02,2021-09-17
-7s8v,2022-07-06,2021-09-20
-5s8f,2021-01-13,2020-12-17
-6s8e,2020-07-08,2019-07-09
-5s80,2021-06-23,2020-12-11
-7s85,2022-09-28,2021-09-17
-1s8a,2004-03-30,2004-01-31
-5s8h,2021-01-13,2020-12-17
-5s85,2021-06-23,2020-12-11
-3s8h,2011-06-15,2011-05-28
-5s83,2021-06-23,2020-12-11
-6s8k,2019-11-27,2019-07-10
-5s8e,2021-01-13,2020-12-17
-6s8z,2020-02-26,2019-07-11
-3s8l,2011-11-02,2011-05-29
-5s8l,2021-01-13,2020-12-17
-3s8a,2012-04-11,2011-05-27
-3s8k,2011-11-02,2011-05-29
-7s8d,2022-08-24,2021-09-17
-1s89,2004-03-30,2004-01-31
-1s8e,2004-08-10,2004-02-02
-5s88,2021-06-23,2020-12-11
-3s8z,2011-10-26,2011-05-31
-7s86,2021-12-29,2021-09-17
-5s8w,2021-02-17,2021-01-22
-6s87,2020-10-21,2019-07-08
-1s85,2004-03-16,2004-01-30
-5s8g,2021-01-13,2020-12-17
-1s84,2004-03-16,2004-01-30
-5s86,2021-06-23,2020-12-11
-5s8q,2021-01-13,2020-12-17
-7s8b,2021-11-17,2021-09-17
-7s88,2021-11-17,2021-09-17
-7s8o,2021-11-17,2021-09-18
-7s8a,2022-11-02,2021-09-17
-7s8e,2022-11-02,2021-09-17
-5s89,2021-06-23,2020-12-11
-6s81,2020-02-05,2019-07-08
-6s8g,2019-09-25,2019-07-10
-5s8k,2021-01-13,2020-12-17
-5s8j,2021-01-13,2020-12-17
-5s8o,2021-01-13,2020-12-17
-6s8h,2019-09-25,2019-07-10
-6s8u,2019-09-25,2019-07-10
-7s8k,2022-08-24,2021-09-18
-3s8f,2011-08-03,2011-05-27
-6s8i,2020-02-12,2019-07-10
-3s8o,2011-11-02,2011-05-29
-6s8f,2019-10-30,2019-07-09
-3s8x,2012-04-11,2011-05-31
-5s8c,2021-01-13,2020-12-17
-5s8x,2021-02-17,2021-01-22
-1s82,2004-03-16,2004-01-30
-1s8c,2004-08-03,2004-02-02
-7s83,2022-11-23,2021-09-17
-6s8y,2019-09-25,2019-07-10
-6s8l,2019-11-27,2019-07-10
-5s8u,2021-02-17,2021-01-22
-7s8w,2021-10-06,2021-09-20
-6s8d,2020-02-12,2019-07-09
-5s87,2021-06-23,2020-12-11
-6s84,2019-07-17,2019-07-08
-5s8t,2021-02-17,2021-01-22
-5s8m,2021-01-13,2020-12-17
-7s8p,2021-11-17,2021-09-18
-6s85,2019-09-04,2019-07-08
-6s8a,2019-10-16,2019-07-09
-6s89,2019-10-16,2019-07-09
-6s86,2019-07-17,2019-07-08
-6s8j,2020-02-12,2019-07-10
-3s86,2012-06-06,2011-05-27
-3s88,2011-12-07,2011-05-27
-3s8n,2011-11-02,2011-05-29
-6s83,2020-02-05,2019-07-08
-3s87,2012-04-11,2011-05-27
-5s8r,2021-02-17,2021-01-22
-7s8r,2022-02-23,2021-09-19
-1s83,2004-03-16,2004-01-30
-3s8p,2011-07-06,2011-05-30
-5s8b,2021-06-23,2020-12-11
-1s8d,2005-09-06,2004-02-02
-3s82,2011-06-08,2011-05-27
-7s8t,2022-02-02,2021-09-19
-7s84,2022-09-28,2021-09-17
-7s8h,2022-06-01,2021-09-17
-6s8n,2019-09-25,2019-07-10
-5s8z,2021-02-17,2021-01-22
-8s8x,2024-03-20,2024-03-07
-3s8g,2011-08-03,2011-05-27
-6s88,2019-09-25,2019-07-08
-6s8m,2019-08-21,2019-07-10
-7s81,2022-06-29,2021-09-17
-6s8b,2020-07-08,2019-07-09
-3s83,2011-06-29,2011-05-27
-3s8b,2012-04-11,2011-05-27
-5s82,2021-06-23,2020-12-11
-3s8c,2012-04-11,2011-05-27
-5s8n,2021-01-13,2020-12-17
-5s81,2021-06-23,2020-12-11
-3s85,2012-04-11,2011-05-27
-5s84,2021-06-23,2020-12-11
-7s8c,2021-11-17,2021-09-17
-5s8s,2021-02-17,2021-01-22
-7s8m,2021-11-17,2021-09-18
-5s8a,2021-06-23,2020-12-11
-1s81,2004-03-16,2004-01-30
-3h42,2009-05-05,2009-04-17
-6h4d,2019-06-26,2018-07-20
-3h4s,2009-05-19,2009-04-20
-6h4g,2019-08-14,2018-07-21
-6h43,2018-12-26,2018-07-20
-7h4c,2024-04-24,2024-04-04
-8h48,2023-10-18,2022-10-10
-5h4c,2017-09-06,2016-10-31
-2h4y,2008-03-11,2006-05-25
-6h4u,2019-06-12,2018-07-23
-4h44,2013-02-20,2012-09-16
-4h4s,2013-10-09,2012-09-18
-5h4g,2016-11-23,2016-10-31
-3h4g,2009-05-05,2009-04-20
-1h4s,2001-06-18,2001-05-14
-4h4y,2013-10-09,2012-09-18
-4h4k,2013-03-06,2012-09-17
-7h4b,2024-04-24,2024-04-04
-6h4t,2019-06-12,2018-07-23
-7h4k,2024-04-24,2024-04-04
-6h40,2019-01-16,2018-07-20
-4h4e,2013-01-23,2012-09-17
-8h4p,2023-08-23,2022-10-11
-2h4v,2006-07-11,2006-05-25
-7h49,2024-04-24,2024-04-04
-3h4i,2009-07-28,2009-04-20
-7h4p,2024-04-24,2024-04-04
-3h4k,2009-08-25,2009-04-20
-1h4q,2001-06-18,2001-05-13
-6h4p,2019-06-12,2018-07-23
-3h4t,2009-07-28,2009-04-20
-8h49,2023-10-18,2022-10-10
-2h4z,2006-10-24,2006-05-25
-1h4g,2002-05-09,2001-05-11
-2h42,2006-06-06,2006-05-23
-5h4r,2017-09-13,2016-11-02
-6h4q,2019-06-12,2018-07-23
-1h47,2004-10-22,2003-02-24
-1h4n,1997-09-17,1997-05-29
-4h4b,2012-12-26,2012-09-17
-4h4w,2013-10-09,2012-09-18
-1h4h,2002-05-09,2001-05-11
-8h46,2023-10-18,2022-10-10
-4h4c,2013-01-23,2012-09-17
-3h4h,2010-02-02,2009-04-20
-2h4n,1997-09-17,1997-05-29
-8h4b,2023-10-18,2022-10-10
-4h49,2013-04-24,2012-09-17
-3h4d,2009-07-21,2009-04-18
-1h49,2003-03-11,2003-02-25
-6h4o,2019-06-12,2018-07-23
-2h4b,2006-09-12,2006-05-24
-6h4w,2019-06-12,2018-07-23
-8h4g,2023-10-18,2022-10-10
-7h46,2024-04-24,2024-04-04
-8h41,2023-08-16,2022-10-09
-8h4c,2023-10-18,2022-10-10
-5h47,2017-01-25,2016-10-31
-6h46,2019-04-24,2018-07-20
-8h4y,2023-10-11,2022-10-11
-1h4p,2003-10-02,2001-05-11
-8h4a,2023-10-18,2022-10-10
-4h4d,2013-01-23,2012-09-17
-1h4j,2001-08-23,2001-05-11
-4h42,2013-10-30,2012-09-14
-7h4z,2024-04-24,2024-04-04
-2h47,2006-11-21,2006-05-23
-2h4i,2006-06-13,2006-05-24
-1h45,2002-11-28,2002-10-03
-5h4s,2017-05-17,2016-11-02
-8h4f,2023-11-08,2022-10-10
-2h4l,2006-08-08,2006-05-24
-7h4o,2024-04-24,2024-04-04
-8h4h,2023-10-18,2022-10-10
-3h4b,2009-07-21,2009-04-18
-1h4w,2002-02-11,2001-05-15
-5h48,2017-09-06,2016-10-31
-7h4h,2024-04-24,2024-04-04
-4h4o,2012-12-05,2012-09-17
-5h40,2017-03-01,2016-10-28
-4h4z,2013-10-09,2012-09-18
-5h4d,2017-11-08,2016-10-31
-2h4w,2008-03-11,2006-05-25
-4h4i,2013-10-09,2012-09-17
-4h4l,2013-09-04,2012-09-17
-7h4r,2024-04-24,2024-04-04
-4h4q,2013-10-09,2012-09-18
-7h4e,2024-04-24,2024-04-04
-7h4y,2024-04-24,2024-04-04
-3h4n,2009-12-29,2009-04-20
-7h4t,2024-04-24,2024-04-04
-6h42,2018-09-05,2018-07-20
-6h41,2018-12-26,2018-07-20
-1h43,2002-11-28,2002-10-02
-4h46,2013-09-18,2012-09-16
-5h4h,2016-11-23,2016-10-31
-1h44,2002-11-28,2002-10-03
-2h4g,2006-08-29,2006-05-24
-3h4z,2010-03-31,2009-04-21
-7h4q,2024-04-24,2024-04-04
-1h41,2003-05-01,2002-09-25
-5h41,2017-03-01,2016-10-28
-3h4f,2010-02-02,2009-04-19
-1h48,2004-12-22,2003-02-24
-6h4x,2019-06-12,2018-07-23
-2h4k,2006-08-29,2006-05-24
-1h4d,2003-05-08,2003-02-26
-7h42,2024-04-24,2024-04-04
-1h4i,2001-06-14,2001-05-11
-3h4v,2009-05-05,2009-04-21
-4h4x,2013-10-09,2012-09-18
-8h4x,2023-10-25,2022-10-11
-8h43,2023-10-18,2022-10-10
-6h4y,2019-06-12,2018-07-23
-2h43,2006-12-05,2006-05-23
-4h4t,2013-10-09,2012-09-18
-1h46,2003-04-03,2002-10-03
-1h4c,2003-05-08,2003-02-26
-8h4j,2023-10-18,2022-10-10
-2h44,2006-06-06,2006-05-23
-8h4r,2023-10-11,2022-10-11
-3h44,2010-04-14,2009-04-17
-7h47,2024-04-24,2024-04-04
-5h4f,2016-11-16,2016-10-31
-6h44,2018-12-26,2018-07-20
-7h4m,2024-04-24,2024-04-04
-7h48,2024-04-24,2024-04-04
-6h4z,2019-06-12,2018-07-23
-6h4m,2018-09-26,2018-07-22
-3h4o,2009-05-19,2009-04-20
-6h4s,2019-06-12,2018-07-23
-8h4q,2023-10-18,2022-10-11
-2h48,2006-06-06,2006-05-23
-5h4i,2016-12-14,2016-10-31
-2h40,2006-06-06,2006-05-23
-7h4f,2024-04-24,2024-04-04
-6h4v,2019-06-12,2018-07-23
-4h45,2013-09-18,2012-09-16
-8h44,2023-10-18,2022-10-10
-2h4f,2006-09-05,2006-05-24
-6h4n,2018-09-05,2018-07-22
-6h4c,2019-08-28,2018-07-20
-6h4f,2018-09-26,2018-07-21
-8h4d,2023-10-18,2022-10-10
-2h4h,2006-09-05,2006-05-24
-7h4u,2024-04-24,2024-04-04
-7h40,2024-04-24,2024-04-04
-7h44,2024-04-24,2024-04-04
-6h4l,2019-08-07,2018-07-21
-6h45,2018-09-05,2018-07-20
-7h4l,2024-04-24,2024-04-04
-8h47,2023-10-18,2022-10-10
-3h4m,2009-06-09,2009-04-20
-7h43,2024-04-24,2024-04-04
-7h4g,2024-04-24,2024-04-04
-7h4a,2024-04-24,2024-04-04
-5h46,2017-09-06,2016-10-31
-8h45,2023-10-18,2022-10-10
-5h49,2017-09-13,2016-10-31
-4h4p,2013-10-09,2012-09-18
-1h42,2003-09-25,2002-09-26
-8h4e,2023-10-18,2022-10-10
-4h4u,2013-10-09,2012-09-18
-8h4m,2023-10-18,2022-10-10
-7h4s,2024-04-24,2024-04-04
-4h4m,2012-12-05,2012-09-17
-3h4l,2010-03-02,2009-04-20
-2h4j,2006-09-05,2006-05-24
-8h4v,2023-08-09,2022-10-11
-6h4a,2019-02-13,2018-07-20
-1h4b,2004-02-26,2003-02-26
-4h4v,2013-10-09,2012-09-18
-5h4z,2016-11-30,2016-11-02
-3h41,2009-05-05,2009-04-17
-5h42,2017-03-01,2016-10-28
-7h4j,2024-04-24,2024-04-04
-4h41,2012-10-10,2012-09-14
-4h4r,2013-10-09,2012-09-18
-1h4t,2001-06-18,2001-05-14
-5h4b,2017-09-13,2016-10-31
-6h4r,2019-06-12,2018-07-23
-3h40,2009-07-21,2009-04-17
-8h4k,2023-06-21,2022-10-10
-5h4j,2017-11-01,2016-11-01
-1h4e,2003-05-09,2003-02-26
-5h4y,2016-11-30,2016-11-02
-7rjt,2022-06-22,2021-07-21
-4rj3,2014-11-26,2014-10-08
-7rj8,2022-02-23,2021-07-20
-6rjm,2019-10-09,2019-04-27
-5rjv,2020-06-17,2020-06-02
-4rj5,2014-11-26,2014-10-08
-5rjq,2020-06-17,2020-06-02
-6rjc,2019-09-11,2019-04-26
-2rji,2007-11-27,2007-10-15
-3rjy,2012-02-08,2011-04-15
-3rj0,2011-06-22,2011-04-14
-7rjn,2022-08-03,2021-07-21
-5rjo,2020-06-17,2020-06-02
-3rjr,2011-06-15,2011-04-15
-3rj5,2012-05-02,2011-04-15
-2rjb,2007-10-30,2007-10-14
-4rj6,2014-11-26,2014-10-08
-4rj8,2014-11-26,2014-10-08
-2rjq,2007-12-11,2007-10-15
-8rjd,2024-01-24,2023-12-20
-2rjg,2008-07-08,2007-10-15
-2rj6,2008-02-05,2007-10-14
-5rjz,2020-06-17,2020-06-02
-3rj7,2012-02-29,2011-04-15
-5rjm,2020-06-17,2020-06-02
-5rjt,2020-06-17,2020-06-02
-3rjg,2012-01-18,2011-04-15
-2rj9,2008-02-05,2007-10-14
-1rjq,2004-04-20,2003-11-20
-7rj9,2022-07-27,2021-07-20
-3rjh,2012-01-18,2011-04-15
-6rj3,2019-08-07,2019-04-26
-7rjo,2022-08-03,2021-07-21
-6rj4,2019-12-18,2019-04-26
-7rj4,2022-07-27,2021-07-20
-5rjp,2020-06-17,2020-06-02
-6rjo,2019-10-09,2019-04-28
-2rjp,2007-12-11,2007-10-15
-3rjd,2011-09-21,2011-04-15
-1rjw,2004-05-11,2003-11-20
-7rjc,2021-09-15,2021-07-20
-5rjj,2020-06-17,2020-06-02
-4rj4,2014-11-26,2014-10-08
-6rjr,2020-03-11,2019-04-29
-7rja,2021-09-15,2021-07-20
-6rjq,2020-06-17,2019-04-29
-5rjn,2020-06-17,2020-06-02
-3rjf,2012-01-18,2011-04-15
-2rjf,2007-10-30,2007-10-14
-1rjd,2003-12-02,2003-11-19
-7rjr,2022-08-03,2021-07-21
-1rjr,2004-04-20,2003-11-20
-1rjz,2004-12-14,2003-11-20
-6rjy,2020-04-15,2019-04-29
-2rj4,2008-02-05,2007-10-14
-7rjd,2021-09-15,2021-07-20
-7rjj,2021-07-28,2021-07-21
-6rje,2019-10-16,2019-04-26
-6rjb,2019-09-11,2019-04-26
-3rjn,2012-05-09,2011-04-15
-6rjl,2020-06-17,2019-04-27
-2rjo,2007-10-23,2007-10-15
-7rji,2022-01-05,2021-07-21
-7rjq,2022-08-03,2021-07-21
-2rjh,2008-07-08,2007-10-15
-8rjw,2024-04-24,2023-12-21
-3rjl,2011-04-27,2011-04-15
-5rjx,2020-06-17,2020-06-02
-5rjl,2020-06-17,2020-06-02
-1rj5,2004-03-09,2003-11-18
-4rjl,2015-11-11,2014-10-09
-2rj5,2008-02-05,2007-10-14
-4rj7,2014-11-26,2014-10-08
-6rj6,2019-08-07,2019-04-26
-1rj6,2004-03-09,2003-11-18
-7rje,2021-09-15,2021-07-20
-5rjy,2020-06-17,2020-06-02
-3rja,2012-04-18,2011-04-15
-2rj3,2008-10-14,2007-10-14
-2rj7,2008-02-05,2007-10-14
-4rji,2014-10-22,2014-10-09
-3rj8,2012-04-18,2011-04-15
-1rj9,2004-01-27,2003-11-18
-8rjb,2024-01-24,2023-12-20
-6rj7,2019-07-31,2019-04-26
-2rj1,2008-02-05,2007-10-14
-3rj6,2012-05-09,2011-04-15
-1rjk,2004-04-13,2003-11-19
-2rj8,2008-02-05,2007-10-14
-5rjw,2020-06-17,2020-06-02
-2rjr,2008-01-15,2007-10-15
-7rj2,2022-07-27,2021-07-20
-3rje,2012-01-18,2011-04-15
-7rjk,2022-08-03,2021-07-21
-2rj2,2008-10-14,2007-10-14
-1rje,2003-12-02,2003-11-19
-5rjr,2020-06-17,2020-06-02
-7rjp,2022-08-03,2021-07-21
-3rjq,2012-05-02,2011-04-15
-1rjn,2004-11-30,2003-11-19
-6rjn,2020-03-04,2019-04-28
-3rj9,2012-05-02,2011-04-15
-7rjf,2021-10-27,2021-07-20
-2rje,2007-10-30,2007-10-14
-6rjv,2019-08-14,2019-04-29
-5rjk,2020-06-17,2020-06-02
-1rjg,2003-12-02,2003-11-19
-1rjp,2004-04-20,2003-11-20
-5rju,2020-06-17,2020-06-02
-3rjk,2012-01-18,2011-04-15
-4rj9,2015-08-26,2014-10-08
-7rjb,2021-09-15,2021-07-20
-3rjm,2011-09-21,2011-04-15
-4rjd,2015-08-26,2014-10-08
-6rjz,2020-06-17,2019-04-29
-3rji,2012-01-18,2011-04-15
-1rjy,2004-12-14,2003-11-20
-7rjm,2022-08-03,2021-07-21
-7rj7,2022-02-23,2021-07-20
-6rjj,2020-04-15,2019-04-27
-4rjj,2014-10-22,2014-10-09
-4rje,2014-12-03,2014-10-08
-4rjk,2014-10-22,2014-10-09
-3rjc,2012-10-31,2011-04-15
-7rjl,2022-08-03,2021-07-21
-1rju,2004-12-07,2003-11-20
-1rjm,2004-11-30,2003-11-19
-7rj6,2022-02-23,2021-07-20
-2rjs,2008-01-15,2007-10-15
-4rjz,2014-11-05,2014-10-11
-1rjo,2004-12-07,2003-11-19
-6rj2,2019-08-07,2019-04-26
-5rjs,2020-06-17,2020-06-02
-4rj0,2014-11-12,2014-10-07
-4rjy,2014-10-29,2014-10-11
-7rj1,2021-07-28,2021-07-20
-3rjj,2012-01-18,2011-04-15
-8rjc,2024-01-24,2023-12-20
-1rjv,2004-05-25,2003-11-20
-6rj5,2019-08-07,2019-04-26
-1rj4,2004-02-03,2003-11-18
-2rj0,2008-02-05,2007-10-14
-8epa,2023-01-25,2022-10-05
-3epi,2008-12-16,2008-09-29
-4epu,2013-04-17,2012-04-17
-2epx,2007-10-02,2007-03-30
-4ep6,2012-05-09,2012-04-17
-1epw,2000-11-01,2000-03-29
-8ep7,2022-10-19,2022-10-05
-2ep2,2007-10-02,2007-03-29
-7epk,2021-05-19,2021-04-27
-2epz,2007-10-02,2007-03-30
-1epz,2000-12-13,2000-03-30
-3ep6,2008-12-23,2008-09-29
-4epi,2012-06-20,2012-04-17
-2epr,2008-04-01,2007-03-30
-7epx,2022-05-18,2021-04-28
-8eps,2022-10-19,2022-10-06
-4epj,2012-06-06,2012-04-17
-6epa,2018-08-29,2017-10-11
-7epf,2021-06-23,2021-04-26
-4ep2,2012-06-06,2012-04-16
-6ept,2018-10-31,2017-10-12
-8epp,2023-06-21,2022-10-06
-4epk,2012-08-22,2012-04-17
-2epy,2007-10-02,2007-03-30
-8epm,2022-12-14,2022-10-06
-3epj,2008-11-04,2008-09-29
-5epe,2015-11-25,2015-11-11
-3eps,2010-04-14,2008-09-29
-2epw,2007-10-02,2007-03-30
-6eps,2018-10-31,2017-10-12
-2epj,2007-10-02,2007-03-30
-6epn,2019-02-06,2017-10-12
-3epm,2008-10-28,2008-09-29
-8ep6,2022-10-19,2022-10-05
-4epp,2012-06-20,2012-04-17
-6ep2,2019-02-06,2017-10-10
-5epa,2016-05-11,2015-11-11
-4epw,2012-05-23,2012-04-17
-4ep4,2012-11-14,2012-04-17
-2ep3,2007-10-02,2007-03-29
-7epv,2021-11-10,2021-04-27
-8epr,2023-02-22,2022-10-06
-7epm,2022-03-02,2021-04-27
-6eph,2018-05-02,2017-10-11
-4ep8,2012-08-29,2012-04-17
-6epx,2018-10-31,2017-10-12
-5epo,2016-03-23,2015-11-12
-3epb,2008-12-23,2008-09-29
-3epw,2009-03-24,2008-09-30
-7epu,2021-07-14,2021-04-27
-5epu,2016-11-23,2015-11-12
-6ep1,2018-10-31,2017-10-10
-6epj,2018-10-31,2017-10-11
-3epx,2009-03-24,2008-09-30
-6ep4,2017-12-13,2017-10-10
-5epv,2016-02-24,2015-11-12
-8epn,2023-06-21,2022-10-06
-2epf,2008-03-11,2007-03-29
-1ep1,2001-01-17,2000-03-27
-4epr,2012-05-23,2012-04-17
-2epv,2007-10-02,2007-03-30
-3epd,2008-11-11,2008-09-29
-5ep3,2016-04-20,2015-11-11
-2epp,2008-02-12,2007-03-30
-5epg,2016-02-17,2015-11-11
-3epr,2008-11-04,2008-09-29
-5epr,2016-05-25,2015-11-12
-7epe,2021-06-23,2021-04-26
-4ep3,2012-06-06,2012-04-16
-8ept,2023-07-05,2022-10-06
-4epy,2012-05-23,2012-04-17
-3ep7,2008-12-23,2008-09-29
-5epy,2016-01-13,2015-11-12
-5eps,2016-05-25,2015-11-12
-6ep9,2018-08-22,2017-10-11
-6epz,2018-04-11,2017-10-12
-2epa,2008-04-01,2007-03-29
-8epo,2023-02-22,2022-10-06
-3epa,2008-12-23,2008-09-29
-5epn,2016-01-13,2015-11-11
-3epk,2008-11-04,2008-09-29
-3eph,2008-11-04,2008-09-29
-4epm,2012-06-20,2012-04-17
-6epi,2018-05-02,2017-10-11
-4epx,2012-05-23,2012-04-17
-3ep3,2008-12-23,2008-09-29
-2epc,2007-10-02,2007-03-29
-8epy,2024-04-10,2022-10-06
-6ep6,2018-04-11,2017-10-10
-2epm,2008-03-11,2007-03-30
-3ept,2008-12-09,2008-09-30
-8epx,2023-03-22,2022-10-06
-5ep7,2016-11-23,2015-11-11
-1ep2,2001-01-17,2000-03-27
-6epw,2018-10-31,2017-10-12
-6epo,2019-02-06,2017-10-12
-8epz,2023-02-22,2022-10-07
-3epv,2008-11-25,2008-09-30
-6epy,2018-04-11,2017-10-12
-4epz,2012-07-11,2012-04-17
-4epd,2012-08-29,2012-04-17
-5ep9,2016-05-11,2015-11-11
-5epq,2015-12-02,2015-11-12
-6epr,2018-10-31,2017-10-12
-8epw,2023-06-07,2022-10-06
-7eps,2021-08-11,2021-04-27
-4eph,2013-04-17,2012-04-17
-1ep4,2000-09-27,2000-03-27
-1epl,1994-12-20,1994-07-27
-4ep9,2013-04-17,2012-04-17
-3epe,2009-05-19,2008-09-29
-8ep4,2022-11-09,2022-10-05
-3epp,2008-10-21,2008-09-29
-6epk,2018-10-31,2017-10-11
-6epp,2019-02-06,2017-10-12
-5epb,2016-11-23,2015-11-11
-6ep7,2018-04-11,2017-10-11
-1epr,1994-12-20,1994-07-27
-1epm,1994-12-20,1994-07-27
-3ep4,2008-12-23,2008-09-29
-1epb,1994-07-31,1993-06-15
-8epv,2023-04-05,2022-10-06
-1epp,1994-12-20,1994-07-27
-5ep4,2016-04-20,2015-11-11
-5ep8,2016-11-23,2015-11-11
-1epq,1994-12-20,1994-07-27
-3epy,2009-01-20,2008-09-30
-5ep2,2016-04-20,2015-11-11
-1epf,2000-10-09,2000-03-29
-1epn,1994-12-20,1994-07-27
-3epo,2008-10-28,2008-09-29
-6epm,2019-02-06,2017-10-12
-7ep0,2021-07-14,2021-04-26
-8epq,2023-06-21,2022-10-06
-3epl,2008-11-04,2008-09-29
-6epu,2018-10-31,2017-10-12
-2epn,2008-03-11,2007-03-30
-1ept,1995-02-07,1994-06-07
-8epj,2023-02-22,2022-10-05
-6ep0,2019-02-06,2017-10-10
-9epl,2024-04-17,2024-03-18
-7epq,2022-05-11,2021-04-27
-1epv,2003-01-14,2000-03-29
-7epb,2021-06-23,2021-04-26
-3ep9,2008-12-23,2008-09-29
-3epg,2008-12-16,2008-09-29
-3ep8,2008-12-23,2008-09-29
-4epq,2012-06-13,2012-04-17
-2eps,2007-10-02,2007-03-30
-2ep7,2007-10-02,2007-03-29
-6ep8,2018-09-19,2017-10-11
-3epf,2008-11-11,2008-09-29
-4ep7,2012-06-06,2012-04-17
-7epo,2021-12-22,2021-04-27
-2ep4,2007-10-02,2007-03-29
-7epw,2021-11-10,2021-04-28
-5eph,2016-09-21,2015-11-11
-5epc,2016-04-27,2015-11-11
-2ept,2007-10-02,2007-03-30
-7epz,2022-04-06,2021-04-28
-3epz,2008-11-25,2008-09-30
-6ep5,2019-02-06,2017-10-10
-1ep3,2001-01-17,2000-03-27
-6epv,2018-10-31,2017-10-12
-4epv,2012-05-23,2012-04-17
-2epu,2007-10-02,2007-03-30
-4epe,2012-08-29,2012-04-17
-2ep0,2007-10-02,2007-03-29
-4epb,2012-08-29,2012-04-17
-4epl,2012-06-20,2012-04-17
-4ept,2012-05-23,2012-04-17
-3epn,2008-10-28,2008-09-29
-7epr,2021-08-11,2021-04-27
-2epq,2008-02-12,2007-03-30
-1epy,2000-04-12,2000-03-29
-3ep5,2008-12-23,2008-09-29
-6epb,2018-09-26,2017-10-11
-8epl,2022-12-14,2022-10-06
-2ep1,2007-10-02,2007-03-29
-2eph,2007-04-17,2007-03-30
-3rxg,2011-08-24,2011-05-10
-1rxp,2004-06-08,2003-12-18
-4rxs,2015-03-11,2014-12-11
-3rxp,2011-08-24,2011-05-10
-6rxd,2020-07-08,2019-06-07
-1rx9,1997-04-01,1996-10-25
-5rxa,2020-11-11,2020-10-30
-4rxr,2015-03-11,2014-12-11
-5rxb,2020-11-11,2020-10-30
-1rxr,1998-11-11,1998-06-12
-5rx7,2020-11-11,2020-10-30
-6rxk,2020-04-15,2019-06-08
-7rxo,2022-08-31,2021-08-23
-4rxq,2015-03-11,2014-12-11
-4rx5,2015-12-02,2014-12-08
-7rxc,2021-10-06,2021-08-22
-6rx2,2020-06-17,2019-06-07
-7rxs,2022-01-19,2021-08-23
-5rxy,2020-11-11,2020-10-30
-3rxk,2011-08-24,2011-05-10
-3rx2,2011-11-30,2011-05-10
-5rxi,2020-11-11,2020-10-30
-1rx8,1997-03-12,1996-10-25
-6rxf,2020-07-08,2019-06-07
-1rxu,2004-04-13,2003-12-18
-6rxa,2019-10-30,2019-06-07
-3rxa,2011-08-24,2011-05-10
-5rxp,2020-11-11,2020-10-30
-7rxd,2021-10-06,2021-08-22
-5rxu,2020-11-11,2020-10-30
-1rx7,1997-03-12,1996-10-25
-7rxf,2022-11-09,2021-08-23
-7rxr,2022-01-19,2021-08-23
-3rxe,2011-08-24,2011-05-10
-3rxj,2011-08-24,2011-05-10
-5rx6,2020-11-11,2020-10-30
-8rxx,2024-05-15,2024-02-08
-3rx8,2011-08-24,2011-05-10
-3rx4,2011-11-30,2011-05-10
-1rxf,1999-06-08,1998-06-05
-4rx4,2015-07-01,2014-12-08
-6rx6,2020-07-15,2019-06-07
-3rxt,2011-08-24,2011-05-10
-4rxw,2015-01-21,2014-12-12
-7rxt,2022-01-19,2021-08-23
-4rxh,2015-07-01,2014-12-11
-6rxu,2019-08-14,2019-06-10
-4rx6,2015-12-30,2014-12-09
-1rx0,2004-04-20,2003-12-18
-4rxp,2015-03-11,2014-12-11
-7rxx,2021-11-10,2021-08-23
-4rxa,2015-04-15,2014-12-09
-5rxc,2020-11-11,2020-10-30
-5rxt,2020-11-11,2020-10-30
-3rxd,2011-08-24,2011-05-10
-1rxs,2004-04-13,2003-12-18
-4rx0,2015-07-29,2014-12-08
-1rxq,2004-07-20,2003-12-18
-6rxs,2020-04-15,2019-06-08
-5rxd,2020-11-11,2020-10-30
-3rxw,2012-03-21,2011-05-10
-7rxg,2022-05-18,2021-08-23
-1rx6,1997-01-11,1996-09-19
-5rxq,2020-11-11,2020-10-30
-5rx3,2020-11-11,2020-10-30
-4rxd,2015-04-15,2014-12-10
-4rxe,2015-04-15,2014-12-10
-1rx2,1997-01-11,1996-09-19
-5rx1,2020-11-11,2020-10-30
-3rxh,2011-08-24,2011-05-10
-5rxe,2020-11-11,2020-10-30
-1rxg,1999-06-08,1998-06-05
-7rxh,2022-05-18,2021-08-23
-7rxk,2022-11-09,2021-08-23
-5rxz,2020-11-11,2020-10-30
-6rxn,1991-01-15,1990-01-16
-5rxf,2020-11-11,2020-10-30
-3rxz,2011-06-22,2011-05-10
-7rxv,2021-11-03,2021-08-23
-5rx8,2020-11-11,2020-10-30
-3rxc,2011-08-24,2011-05-10
-3rxo,2011-08-24,2011-05-10
-4rx9,2015-03-18,2014-12-09
-1rxc,2004-04-13,2003-12-18
-6rxt,2019-08-14,2019-06-10
-7rx2,2022-05-18,2021-08-21
-1rxe,2004-06-01,2003-12-18
-6rx8,2019-10-30,2019-06-07
-5rxv,2020-11-11,2020-10-30
-5rxm,2020-11-11,2020-10-30
-1rxh,2004-05-11,2003-12-18
-6rxv,2019-08-14,2019-06-10
-8rxb,2024-05-15,2024-02-06
-6rxl,2020-04-15,2019-06-08
-3rxf,2011-08-24,2011-05-10
-6rx5,2020-07-15,2019-06-07
-3rxx,2012-03-21,2011-05-10
-1rxv,2004-01-27,2003-12-18
-3rxr,2011-08-24,2011-05-10
-3rxi,2011-08-24,2011-05-10
-3rx5,2011-08-24,2011-05-10
-6rxm,2020-04-15,2019-06-08
-6rxr,2020-04-15,2019-06-08
-7rx0,2022-06-15,2021-08-20
-4rxm,2014-12-24,2014-12-11
-3rxq,2011-08-24,2011-05-10
-8rxn,1993-10-31,1991-08-26
-4rxo,2015-03-11,2014-12-11
-5rx5,2020-11-11,2020-10-30
-6rxz,2019-08-14,2019-06-10
-1rxm,2004-01-27,2003-12-18
-4rx8,2015-03-18,2014-12-09
-4rxc,2015-04-15,2014-12-09
-1rxt,2005-04-12,2003-12-18
-6rxp,2020-04-15,2019-06-08
-5rx0,2020-11-11,2020-10-30
-6rxb,2020-07-15,2019-06-07
-1rxw,2004-01-27,2003-12-18
-5rxn,1985-04-01,1984-10-15
-1rxy,2004-04-13,2003-12-18
-5rxj,2020-11-11,2020-10-30
-1rx5,1997-01-11,1996-09-19
-1rxk,2004-05-11,2003-12-18
-1rx3,1997-01-11,1996-09-19
-3rx6,2012-07-25,2011-05-10
-5rxr,2020-11-11,2020-10-30
-8rxu,2024-03-27,2024-02-08
-6rxi,2020-03-18,2019-06-08
-5rxk,2020-11-11,2020-10-30
-4rxy,2015-06-24,2014-12-12
-6rx0,2020-07-15,2019-06-07
-5rx2,2020-11-11,2020-10-30
-5rx4,2020-11-11,2020-10-30
-5rxs,2020-11-11,2020-10-30
-4rxn,1985-04-01,1984-10-15
-7rxw,2021-11-10,2021-08-23
-1rx4,1997-01-11,1996-09-19
-3rxu,2011-08-24,2011-05-10
-3rxb,2011-08-24,2011-05-10
-1rxo,1997-06-16,1996-12-06
-5rxl,2020-11-11,2020-10-30
-3rx7,2011-08-24,2011-05-10
-3rxv,2011-08-24,2011-05-10
-5rxx,2020-11-11,2020-10-30
-5rxg,2020-11-11,2020-10-30
-6rxy,2019-08-14,2019-06-10
-1rx1,1997-01-11,1996-09-19
-4rx7,2015-03-18,2014-12-09
-6rxj,2020-04-15,2019-06-08
-4rxu,2014-12-24,2014-12-11
-6rxg,2020-07-08,2019-06-07
-5rxh,2020-11-11,2020-10-30
-3rx3,2011-11-30,2011-05-10
-4rxz,2015-07-22,2014-12-12
-5rx9,2020-11-11,2020-10-30
-1rxi,2004-06-01,2003-12-18
-6rxo,2020-04-15,2019-06-08
-1rxj,2004-05-11,2003-12-18
-6rxq,2020-04-15,2019-06-08
-4rxt,2014-12-24,2014-12-11
-5rxo,2020-11-11,2020-10-30
-6rx4,2019-11-20,2019-06-07
-3rxs,2011-08-24,2011-05-10
-3rxl,2011-08-24,2011-05-10
-5rxw,2020-11-11,2020-10-30
-6rxx,2019-08-14,2019-06-10
-3rxm,2011-08-24,2011-05-10
-8rx0,2024-03-06,2024-02-05
-7rxn,1991-07-15,1990-05-11
-6rxc,2020-07-15,2019-06-07
-2ywl,2007-10-23,2007-04-20
-5ywe,2018-12-05,2017-11-29
-2ywc,2007-10-23,2007-04-20
-5ywm,2018-12-05,2017-11-29
-4yw5,2015-09-23,2015-03-20
-4yw8,2015-09-23,2015-03-20
-6yw0,2020-12-30,2020-04-29
-6ywi,2021-04-21,2020-04-29
-1yws,2005-03-08,2005-02-18
-6ywz,2021-01-20,2020-04-30
-1ywh,2005-05-10,2005-02-18
-2ywp,2007-05-08,2007-04-21
-2ywg,2008-04-29,2007-04-20
-1ywt,2005-03-01,2005-02-18
-4ywr,2016-03-02,2015-03-20
-6ywe,2020-11-11,2020-04-29
-4ywv,2015-05-06,2015-03-21
-5ywg,2019-01-16,2017-11-29
-6ywk,2020-05-06,2020-04-29
-5yws,2018-05-23,2017-11-30
-5ywd,2018-05-02,2017-11-29
-7yw4,2023-07-26,2022-08-21
-1ywr,2005-05-10,2005-02-18
-7ywu,2022-11-16,2022-02-14
-7ywm,2022-06-29,2022-02-14
-5ywt,2018-05-23,2017-11-30
-8ywo,2024-05-08,2024-03-31
-5yw8,2018-05-02,2017-11-29
-6yw6,2020-07-22,2020-04-29
-2yww,2007-10-23,2007-04-23
-5ywa,2018-05-02,2017-11-29
-6yw3,2020-12-30,2020-04-29
-6yw9,2021-03-03,2020-04-29
-1ywi,2005-04-12,2005-02-18
-6ywb,2021-05-12,2020-04-29
-2ywf,2008-04-29,2007-04-20
-5yw4,2019-03-06,2017-11-28
-4yw9,2015-09-23,2015-03-20
-1yw0,2005-03-15,2005-02-16
-6ywo,2020-08-05,2020-04-29
-1ywg,2005-11-29,2005-02-17
-4yw6,2015-09-09,2015-03-20
-5ywc,2018-05-02,2017-11-29
-6ywa,2021-05-12,2020-04-29
-5ywh,2019-01-16,2017-11-29
-5ywn,2019-03-06,2017-11-29
-2yw2,2007-10-23,2007-04-19
-7ywv,2022-11-16,2022-02-14
-6yws,2020-11-11,2020-04-30
-6ywj,2021-03-03,2020-04-29
-5yw2,2018-01-03,2017-11-28
-5ywx,2018-09-05,2017-11-30
-1yw7,2006-02-21,2005-02-17
-4ywy,2015-08-05,2015-03-21
-1yw2,2005-05-10,2005-02-16
-5yw0,2018-09-05,2017-11-28
-6yw4,2020-12-30,2020-04-29
-1ywd,2005-10-04,2005-02-17
-4yw7,2015-09-09,2015-03-20
-4yw2,2015-09-23,2015-03-20
-4ywt,2015-07-29,2015-03-21
-2yw9,2007-05-15,2007-04-20
-1yw8,2006-02-21,2005-02-17
-6yw1,2020-12-30,2020-04-29
-2ywv,2007-10-23,2007-04-23
-7ywf,2022-05-04,2022-02-13
-4ywb,2015-09-23,2015-03-20
-1ywa,2005-10-04,2005-02-17
-4yw1,2015-09-23,2015-03-20
-6ywl,2020-05-06,2020-04-29
-4ywu,2015-05-06,2015-03-21
-1yw1,2005-03-01,2005-02-16
-6ywu,2022-02-23,2020-04-30
-4ywm,2015-09-23,2015-03-20
-6ywh,2021-04-21,2020-04-29
-6yw7,2020-07-22,2020-04-29
-2ywr,2007-10-23,2007-04-23
-1ywq,2005-04-12,2005-02-18
-1yw9,2006-02-21,2005-02-17
-6ywq,2021-04-21,2020-04-30
-7ywc,2022-10-26,2022-02-12
-2yw8,2008-04-22,2007-04-20
-4ywl,2015-09-23,2015-03-20
-7yw3,2023-07-26,2022-08-21
-5ywv,2018-05-23,2017-11-30
-7ywk,2022-09-21,2022-02-14
-4ywa,2015-09-09,2015-03-20
-6ywn,2020-08-05,2020-04-29
-1ywb,2005-10-04,2005-02-17
-4yws,2015-07-01,2015-03-20
-4ywq,2015-04-22,2015-03-20
-6ywv,2020-11-11,2020-04-30
-5ywy,2018-12-05,2017-11-30
-6ywg,2021-04-21,2020-04-29
-5yw7,2018-05-02,2017-11-29
-4ywd,2015-09-23,2015-03-20
-5ywi,2019-01-16,2017-11-29
-4ywh,2015-04-15,2015-03-20
-4ywg,2015-07-15,2015-03-20
-4ywe,2015-04-08,2015-03-20
-5ywr,2018-06-06,2017-11-30
-1ywn,2005-08-23,2005-02-18
-4yw3,2015-09-23,2015-03-20
-6ywp,2020-08-05,2020-04-29
-7ywp,2023-02-22,2022-02-14
-7ywt,2023-02-22,2022-02-14
-6ywx,2020-11-11,2020-04-30
-6ywy,2020-11-11,2020-04-30
-4ywo,2015-09-16,2015-03-20
-5ywk,2019-01-16,2017-11-29
-5ywu,2018-05-23,2017-11-30
-1ywc,2005-10-04,2005-02-17
-7ywa,2022-12-21,2022-08-22
-6ywr,2021-04-21,2020-04-30
-7yw9,2023-08-30,2022-08-22
-1yw4,2005-03-01,2005-02-17
-6yw5,2020-11-11,2020-04-29
-5yw9,2018-05-02,2017-11-29
-4ywj,2015-04-01,2015-03-20
-4ywp,2015-10-14,2015-03-20
-5yw3,2018-11-28,2017-11-28
-5yw5,2018-01-03,2017-11-28
-7yw2,2023-07-26,2022-08-21
-6ywt,2022-02-23,2020-04-30
-7ywb,2022-03-16,2022-02-12
-6ywm,2020-05-06,2020-04-29
-5ywb,2018-05-30,2017-11-29
-2ywh,2008-04-29,2007-04-20
-6yw2,2020-12-30,2020-04-29
-3qfc,2011-08-03,2011-01-21
-5qfe,2018-10-10,2018-08-30
-2qfa,2007-11-06,2007-06-27
-7qfn,2022-05-25,2021-12-06
-3qf7,2011-04-20,2011-01-21
-1qf8,2000-04-19,1999-04-07
-7qf9,2022-02-09,2021-12-05
-1qfm,1999-05-13,1999-04-12
-8qfn,2023-12-27,2023-09-04
-2qfv,2008-07-01,2007-06-28
-1qff,2000-07-26,1999-04-10
-3qf4,2012-03-28,2011-01-21
-6qfb,2019-04-10,2019-01-09
-7qfk,2022-12-21,2021-12-06
-6qfi,2019-06-12,2019-01-10
-7qfm,2022-12-21,2021-12-06
-8qf2,2023-12-13,2023-09-02
-6qfm,2019-06-12,2019-01-10
-2qfc,2007-11-06,2007-06-27
-6qfo,2019-11-06,2019-01-10
-4qf9,2015-04-22,2014-05-20
-8qfz,2024-02-07,2023-09-05
-8qf5,2024-03-13,2023-09-02
-1qf3,1999-07-27,1999-04-06
-8qf1,2023-12-06,2023-09-01
-4qf4,2014-06-04,2014-05-19
-4qf3,2014-07-02,2014-05-19
-1qfu,1999-04-16,1999-04-14
-2qf8,2007-07-10,2007-06-27
-4qfy,2014-10-15,2014-05-22
-3qfb,2011-07-27,2011-01-21
-4qfc,2014-07-16,2014-05-20
-1qfo,1999-04-16,1999-04-12
-4qfs,2014-08-06,2014-05-21
-3qfh,2011-02-02,2011-01-21
-3qfs,2011-08-17,2011-01-22
-5qfw,2018-10-10,2018-08-30
-4qfl,2015-01-28,2014-05-21
-8qfj,2023-11-01,2023-09-04
-5qfu,2018-10-10,2018-08-30
-4qfd,2014-07-16,2014-05-20
-8qfg,2023-11-01,2023-09-04
-4qfh,2014-06-18,2014-05-21
-8qfi,2023-11-01,2023-09-04
-8qfq,2023-12-27,2023-09-04
-4qfe,2014-06-04,2014-05-20
-5qfi,2018-10-10,2018-08-30
-1qfs,1999-05-13,1999-04-13
-8qf8,2023-12-13,2023-09-04
-7qfi,2022-12-21,2021-12-06
-2qfy,2008-07-01,2007-06-28
-5qfo,2018-10-10,2018-08-30
-8qfp,2023-12-27,2023-09-04
-6qfw,2019-04-17,2019-01-10
-3qfx,2011-06-29,2011-01-24
-4qfz,2014-10-15,2014-05-22
-7qfy,2022-12-21,2021-12-07
-5qfa,2018-10-10,2018-08-30
-3qfv,2011-10-12,2011-01-23
-1qf2,1999-12-29,1999-04-06
-8qff,2023-11-01,2023-09-11
-5qfv,2018-10-10,2018-08-30
-6qfq,2019-06-12,2019-01-10
-4qfi,2014-08-27,2014-05-21
-5qf8,2018-10-10,2018-08-30
-1qfc,2000-04-10,1999-04-08
-2qf2,2007-08-28,2007-06-26
-7qfo,2022-05-25,2021-12-06
-3qfe,2011-02-02,2011-01-21
-6qf2,2019-07-10,2019-01-09
-5qfp,2018-10-10,2018-08-30
-5qf3,2018-10-10,2018-08-30
-5qf9,2018-10-10,2018-08-30
-6qfa,2021-08-04,2019-01-09
-8qfl,2023-12-27,2023-09-04
-4qfn,2015-01-28,2014-05-21
-5qf7,2018-10-10,2018-08-30
-5qf1,2018-10-10,2018-08-30
-3qfu,2011-06-29,2011-01-22
-1qfw,2000-04-26,1999-04-15
-3qfk,2011-02-09,2011-01-21
-5qfl,2018-10-10,2018-08-30
-6qfe,2019-05-08,2019-01-10
-5qfd,2018-10-10,2018-08-30
-2qfb,2008-02-12,2007-06-27
-5qfn,2018-10-10,2018-08-30
-7qfx,2022-04-20,2021-12-06
-7qfa,2022-11-02,2021-12-05
-5qfm,2018-10-10,2018-08-30
-6qf4,2019-07-10,2019-01-09
-5qfq,2018-10-10,2018-08-30
-5qft,2018-10-10,2018-08-30
-8qfs,2023-10-11,2023-09-04
-4qfx,2014-10-15,2014-05-21
-5qfk,2018-10-10,2018-08-30
-3qfd,2011-09-28,2011-01-21
-5qfj,2018-10-10,2018-08-30
-2qfj,2008-03-04,2007-06-27
-1qfk,1999-08-01,1999-04-12
-5qf4,2018-10-10,2018-08-30
-1qf4,1999-12-02,1999-04-06
-3qfj,2012-01-11,2011-01-21
-2qf6,2008-07-01,2007-06-26
-6qff,2019-05-08,2019-01-10
-7qf2,2022-02-16,2021-12-03
-5qfh,2018-10-10,2018-08-30
-4qf6,2015-05-20,2014-05-19
-4qf7,2014-06-18,2014-05-20
-1qf9,1999-08-16,1999-04-07
-1qf0,1999-12-29,1999-04-06
-6qf3,2019-07-10,2019-01-09
-2qfp,2008-10-14,2007-06-27
-8qfh,2023-11-01,2023-09-04
-8qfy,2024-05-15,2023-09-05
-7qfd,2023-07-05,2021-12-05
-3qf9,2011-03-02,2011-01-21
-5qf2,2018-10-10,2018-08-30
-2qfo,2008-07-01,2007-06-27
-7qf8,2023-06-14,2021-12-04
-1qfx,2000-04-19,1999-04-15
-2qfu,2007-10-02,2007-06-28
-3qff,2011-12-07,2011-01-21
-1qfl,2000-04-19,1999-04-12
-3qf1,2011-04-27,2011-01-21
-8qfx,2023-11-22,2023-09-05
-7qf7,2022-11-02,2021-12-04
-4qfm,2015-06-03,2014-05-21
-1qfy,1999-04-27,1999-04-18
-7qfe,2022-03-02,2021-12-05
-7qfh,2022-12-21,2021-12-06
-5qfx,2018-10-10,2018-08-30
-1qf1,1999-12-29,1999-04-06
-2qf1,2007-08-21,2007-06-26
-7qf1,2022-05-18,2021-12-03
-2qf7,2007-09-04,2007-06-27
-5qfs,2018-10-10,2018-08-30
-3qf0,2012-01-25,2011-01-20
-3qft,2011-08-17,2011-01-22
-5qf0,2018-10-10,2018-08-30
-5qfc,2018-10-10,2018-08-30
-7qf3,2022-02-16,2021-12-03
-5qf5,2018-10-10,2018-08-30
-2qfs,2007-10-02,2007-06-28
-4qf2,2014-07-02,2014-05-19
-5qfz,2018-10-10,2018-08-30
-4qfr,2014-08-06,2014-05-21
-6qfd,2019-07-10,2019-01-10
-3qfn,2011-08-24,2011-01-22
-3qfy,2011-09-21,2011-01-24
-3qfm,2011-08-24,2011-01-22
-5qfr,2018-10-10,2018-08-30
-2qfd,2008-02-12,2007-06-27
-6qft,2019-05-22,2019-01-10
-6qfh,2019-05-08,2019-01-10
-3qfz,2011-09-21,2011-01-24
-1qfv,2000-04-19,1999-04-14
-2qfi,2007-10-16,2007-06-27
-7qf0,2022-05-18,2021-12-03
-7qf5,2022-02-16,2021-12-03
-5qfg,2018-10-10,2018-08-30
-5qfy,2018-10-10,2018-08-30
-1qfz,1999-04-27,1999-04-18
-2qfk,2008-07-08,2007-06-27
-6qfy,2019-02-06,2019-01-10
-3qfo,2011-08-24,2011-01-22
-6qf1,2019-07-10,2019-01-09
-7qf4,2022-02-16,2021-12-03
-3qfr,2011-08-03,2011-01-22
-2qfr,2008-10-14,2007-06-27
-1qf7,1999-04-26,1999-03-26
-2qfx,2008-07-01,2007-06-28
-6qfk,2019-11-06,2019-01-10
-8qfe,2023-11-01,2023-09-04
-7qff,2022-12-21,2021-12-06
-4qfo,2015-01-28,2014-05-21
-2qfn,2008-05-20,2007-06-27
-6qfx,2019-04-17,2019-01-10
-8qfm,2023-12-27,2023-09-04
-7qfb,2022-11-02,2021-12-05
-1qfe,2000-04-05,1999-04-05
-2qft,2007-10-02,2007-06-28
-6qfg,2019-05-08,2019-01-10
-5qff,2018-10-10,2018-08-30
-3qfa,2011-07-27,2011-01-21
-4qfp,2015-01-28,2014-05-21
-8qfo,2023-12-27,2023-09-04
-6qf7,2019-06-05,2019-01-09
-6qfu,2019-04-17,2019-01-10
-1qf6,1999-05-06,1999-04-06
-6qf5,2019-07-10,2019-01-09
-8qfd,2024-02-21,2023-09-04
-4qfg,2014-08-06,2014-05-20
-1qf5,1999-12-02,1999-04-06
-4qf5,2015-04-01,2014-05-19
-5qf6,2018-10-10,2018-08-30
-7qf6,2022-12-14,2021-12-03
-6qfv,2019-04-17,2019-01-10
-2qfq,2007-10-02,2007-06-27
-5qfb,2018-10-10,2018-08-30
-1qfg,2000-07-26,1999-04-10
-1qft,2000-04-19,1999-04-14
-4kky,2014-05-21,2013-05-06
-6kk8,2019-09-04,2019-07-24
-4kk7,2013-06-19,2013-05-05
-5kkn,2016-07-13,2016-06-22
-5kk8,2017-06-21,2016-06-21
-6kk6,2020-06-17,2019-07-23
-6kk2,2020-06-17,2019-07-23
-2kkr,2010-06-09,2009-06-29
-7kkt,2021-11-03,2020-10-28
-3kkx,2010-01-12,2009-11-06
-7kkl,2020-11-11,2020-10-27
-6kk1,2019-11-13,2019-07-23
-5kke,2017-03-22,2016-06-21
-6kkr,2019-10-23,2019-07-27
-1kkr,2002-01-30,2001-12-10
-7kk4,2021-01-06,2020-10-27
-6kku,2019-10-23,2019-07-27
-1kkb,2002-03-20,2001-12-06
-5kkg,2017-07-26,2016-06-21
-3kkt,2009-11-24,2009-11-06
-4kk8,2013-08-21,2013-05-05
-5kk5,2016-08-10,2016-06-21
-6kkv,2020-07-29,2019-07-27
-1kkc,2001-12-28,2001-12-07
-5kka,2016-11-02,2016-06-21
-5kkw,2017-07-05,2016-06-22
-5kkk,2017-02-15,2016-06-21
-4kkm,2013-05-15,2013-05-06
-7kka,2021-08-04,2020-10-27
-5kky,2017-06-28,2016-06-23
-7kkr,2021-08-04,2020-10-28
-7kkd,2021-11-03,2020-10-27
-6kk5,2020-06-17,2019-07-23
-6kkf,2019-09-25,2019-07-25
-7kkw,2021-04-21,2020-10-28
-4kkx,2014-01-01,2013-05-06
-5kkb,2016-12-07,2016-06-21
-7kkc,2021-12-01,2020-10-27
-2kkt,2010-06-16,2009-06-29
-1kk8,2002-10-09,2001-12-06
-1kkj,2002-07-10,2001-12-09
-1kk1,2002-04-10,2001-12-06
-3kkj,2009-11-24,2009-11-05
-7kko,2021-01-06,2020-10-27
-4kko,2013-08-14,2013-05-06
-3kkc,2009-11-17,2009-11-05
-5kkz,2016-10-12,2016-06-23
-3kko,2010-06-16,2009-11-06
-6kkw,2019-08-21,2019-07-27
-3kkz,2009-11-24,2009-11-06
-7kk1,2021-11-03,2020-10-27
-6kko,2020-06-10,2019-07-26
-1kkl,2002-08-28,2001-12-10
-5kks,2017-06-28,2016-06-22
-7kkh,2022-04-27,2020-10-27
-1kkq,2002-02-20,2001-12-10
-3kkm,2010-06-16,2009-11-06
-4kki,2013-07-17,2013-05-06
-3kkv,2010-12-22,2009-11-06
-3kkf,2009-12-01,2009-11-05
-5kkh,2017-02-15,2016-06-21
-4kkh,2014-05-21,2013-05-06
-7kk3,2021-01-06,2020-10-27
-7kk9,2021-08-04,2020-10-27
-7kkp,2021-01-06,2020-10-27
-1kk7,2002-10-09,2001-12-06
-1kk3,2002-04-10,2001-12-06
-3kk3,2010-03-23,2009-11-04
-7kkq,2021-01-06,2020-10-27
-6kkh,2019-09-04,2019-07-25
-5kk4,2016-10-05,2016-06-21
-7kkb,2021-08-04,2020-10-27
-3kkp,2010-06-16,2009-11-06
-3kku,2010-07-07,2009-11-06
-6kk3,2020-06-17,2019-07-23
-3kk8,2010-02-09,2009-11-04
-6kk7,2019-11-13,2019-07-23
-6kkt,2019-10-23,2019-07-27
-5kkc,2016-11-02,2016-06-21
-4kkl,2013-08-21,2013-05-06
-5kk7,2017-05-10,2016-06-21
-7kk8,2021-08-04,2020-10-27
-7kkg,2021-11-03,2020-10-27
-6kk0,2020-03-18,2019-07-23
-7kku,2021-04-21,2020-10-28
-5kkt,2017-06-28,2016-06-22
-1kkm,2002-08-28,2001-12-10
-1kkt,2002-01-23,2001-12-10
-3kki,2009-11-24,2009-11-05
-4kkn,2013-06-12,2013-05-06
-6kki,2020-07-29,2019-07-25
-1kkk,2002-12-10,2001-12-10
-3kkq,2010-06-16,2009-11-06
-3kkn,2010-06-16,2009-11-06
-5kkr,2016-08-31,2016-06-22
-1kk0,2002-04-10,2001-12-06
-3kk1,2010-03-23,2009-11-04
-6kks,2019-11-13,2019-07-27
-4kke,2014-05-21,2013-05-06
-1kkp,2002-07-10,2001-12-10
-6kk4,2020-06-17,2019-07-23
-7kk5,2021-01-06,2020-10-27
-7kk6,2021-01-06,2020-10-27
-5kkq,2017-05-24,2016-06-22
-3kky,2010-11-03,2009-11-06
-4kkv,2013-05-29,2013-05-06
-6kke,2019-10-23,2019-07-25
-5kkl,2017-04-19,2016-06-21
-7kkm,2021-01-06,2020-10-27
-1kkf,2002-03-20,2001-12-07
-1kk4,2002-02-20,2001-12-06
-3kk2,2010-03-23,2009-11-04
-2kkh,2010-01-26,2009-06-20
-6kka,2019-09-04,2019-07-24
-7kkn,2021-01-06,2020-10-27
-3kk6,2009-12-15,2009-11-04
-6kkb,2019-10-23,2019-07-24
-2kkf,2009-12-08,2009-06-18
-2kkd,2009-12-22,2009-06-18
-5kki,2017-02-15,2016-06-21
-4kkj,2013-07-17,2013-05-06
-7kki,2021-12-01,2020-10-27
-7kks,2021-04-21,2020-10-28
-7kkk,2020-11-11,2020-10-27
-7kke,2021-03-24,2020-10-27
-1kk2,2002-04-10,2001-12-06
-5kk0,2016-07-13,2016-06-20
-5kkj,2017-02-15,2016-06-21
-5rk5,2020-06-17,2020-06-02
-4rkk,2015-01-07,2014-10-13
-6rki,2020-06-17,2019-04-30
-4rke,2014-12-10,2014-10-13
-4rk8,2015-11-11,2014-10-12
-6rk8,2020-06-17,2019-04-30
-4rkz,2014-12-10,2014-10-14
-4rkh,2015-01-21,2014-10-13
-3rk1,2011-05-11,2011-04-16
-2rkm,1997-07-29,1997-03-25
-1rkg,2004-04-13,2003-11-21
-6rks,2019-11-06,2019-04-30
-6rkt,2020-06-03,2019-04-30
-4rks,2014-12-10,2014-10-13
-7rkh,2021-11-24,2021-07-22
-5rkk,2020-06-17,2020-06-02
-5rkh,2020-06-17,2020-06-02
-5rkb,2020-06-17,2020-06-02
-4rk6,2014-10-29,2014-10-11
-5rk6,2020-06-17,2020-06-02
-1rkb,2005-01-11,2003-11-21
-4rkn,2015-02-04,2014-10-13
-2rk2,2008-06-03,2007-10-16
-3rkq,2012-05-09,2011-04-18
-7rkt,2022-07-27,2021-07-22
-6rk9,2019-05-08,2019-04-30
-6rk7,2019-09-25,2019-04-30
-5rko,2020-06-17,2020-06-02
-2rkv,2007-12-11,2007-10-17
-5rky,2020-06-17,2020-06-02
-1rkp,2004-03-30,2003-11-22
-4rk9,2014-11-05,2014-10-12
-8rkh,2024-03-13,2023-12-25
-2rkd,2008-01-29,2007-10-16
-5rke,2020-06-17,2020-06-02
-5rks,2020-06-17,2020-06-02
-7rkp,2022-07-27,2021-07-22
-4rko,2015-03-11,2014-10-13
-4rk1,2014-10-29,2014-10-11
-4rkb,2014-11-26,2014-10-12
-6rk4,2019-10-16,2019-04-30
-5rkw,2020-06-17,2020-06-02
-7rkv,2021-09-22,2021-07-22
-1rkv,2004-03-30,2003-11-23
-5rkv,2020-06-17,2020-06-02
-6rkg,2020-03-11,2019-04-30
-1rk1,2004-12-14,2003-11-20
-2rky,2008-08-05,2007-10-18
-6rk1,2019-10-02,2019-04-29
-4rkd,2015-03-11,2014-10-12
-6rkc,2019-09-25,2019-04-30
-2rkb,2008-04-01,2007-10-16
-3rkh,2011-06-15,2011-04-18
-6rkm,2020-06-17,2019-04-30
-1rk6,2004-04-20,2003-11-20
-1rkw,2004-06-01,2003-11-23
-5rkl,2020-06-17,2020-06-02
-7rkm,2022-01-26,2021-07-22
-6rkz,2019-06-26,2019-04-30
-8rk1,2024-01-17,2023-12-22
-5rkj,2020-06-17,2020-06-02
-7rkb,2022-08-10,2021-07-22
-2rk7,2008-01-29,2007-10-16
-3rke,2011-05-04,2011-04-18
-3rko,2011-08-03,2011-04-18
-3rk2,2011-07-27,2011-04-17
-7rku,2021-09-22,2021-07-22
-7rky,2022-01-26,2021-07-22
-4rkq,2014-11-12,2014-10-13
-7rks,2021-09-22,2021-07-22
-7rkr,2022-07-27,2021-07-22
-7rkf,2022-01-26,2021-07-22
-6rko,2019-10-16,2019-04-30
-5rki,2020-06-17,2020-06-02
-5rkt,2020-06-17,2020-06-02
-6rky,2019-12-25,2019-04-30
-7rk6,2022-06-22,2021-07-22
-7rki,2022-05-18,2021-07-22
-3rky,2012-04-18,2011-04-18
-5rk9,2020-06-17,2020-06-02
-6rkk,2020-06-17,2019-04-30
-1rku,2004-03-30,2003-11-23
-6rkl,2020-04-15,2019-04-30
-3rk7,2012-10-31,2011-04-17
-7rk7,2022-11-02,2021-07-22
-7rk5,2022-07-27,2021-07-22
-3rk8,2011-04-27,2011-04-17
-5rkg,2020-06-17,2020-06-02
-2rk1,2008-06-03,2007-10-16
-8rks,2024-04-24,2023-12-30
-2rkf,2008-08-05,2007-10-16
-3rkr,2011-11-30,2011-04-18
-8rki,2024-03-13,2023-12-25
-5rkm,2020-06-17,2020-06-02
-4rkj,2015-03-11,2014-10-13
-2rkc,2007-11-20,2007-10-16
-5rk7,2020-06-17,2020-06-02
-1rk3,2004-04-13,2003-11-20
-1rk2,1999-09-01,1999-05-20
-7rkl,2022-07-20,2021-07-22
-6rka,2019-09-25,2019-04-30
-8rkg,2024-03-13,2023-12-25
-6rk2,2019-10-09,2019-04-30
-3rk9,2012-10-31,2011-04-17
-6rku,2019-11-06,2019-04-30
-6rkf,2020-03-11,2019-04-30
-2rku,2008-02-05,2007-10-17
-5rku,2020-06-17,2020-06-02
-6rkp,2020-01-29,2019-04-30
-3rki,2011-05-18,2011-04-18
-8rkq,2024-05-08,2023-12-28
-1rkh,2004-04-13,2003-11-21
-5rkr,2020-06-17,2020-06-02
-5rkp,2020-06-17,2020-06-02
-5rkx,2020-06-17,2020-06-02
-4rkx,2015-07-22,2014-10-14
-6rk6,2019-08-28,2019-04-30
-7rkz,2023-05-10,2021-07-22
-5rk2,2020-06-17,2020-06-02
-6rke,2019-12-18,2019-04-30
-7rkd,2022-07-27,2021-07-22
-8rkf,2024-03-13,2023-12-25
-3rkw,2012-04-18,2011-04-18
-3rku,2011-06-01,2011-04-18
-8rke,2024-03-13,2023-12-25
-4rk0,2014-10-29,2014-10-11
-2rke,2008-01-29,2007-10-16
-5rkf,2020-06-17,2020-06-02
-2rk8,2008-01-29,2007-10-16
-7rka,2022-07-06,2021-07-22
-5rkc,2020-06-17,2020-06-02
-1rk5,2004-04-20,2003-11-20
-3rk0,2011-05-11,2011-04-16
-4rk4,2014-11-19,2014-10-11
-1rk8,2004-04-13,2003-11-21
-6rkd,2019-12-18,2019-04-30
-7rk0,2021-09-01,2021-07-21
-4rkc,2015-03-11,2014-10-12
-7rkg,2022-05-25,2021-07-22
-6rkn,2020-04-15,2019-04-30
-7rke,2022-06-22,2021-07-22
-5rk1,2020-06-17,2020-06-02
-1rky,2004-12-07,2003-11-24
-6rkx,2020-04-15,2019-04-30
-5rk4,2020-06-17,2020-06-02
-2rka,2008-01-29,2007-10-16
-4rkl,2014-11-26,2014-10-13
-1rkd,1998-03-04,1997-11-29
-5rkn,2020-06-17,2020-06-02
-1rkx,2004-03-30,2003-11-23
-4rkf,2014-12-10,2014-10-13
-4rka,2015-11-11,2014-10-12
-4rkg,2015-01-21,2014-10-13
-3rkz,2011-07-13,2011-04-18
-3rk5,2012-10-31,2011-04-17
-5rka,2020-06-17,2020-06-02
-6rkj,2020-04-15,2019-04-30
-5rk8,2020-06-17,2020-06-02
-6rkq,2020-06-03,2019-04-30
-4rkr,2014-11-12,2014-10-13
-4rkm,2015-02-04,2014-10-13
-7rk3,2022-07-27,2021-07-21
-1rks,1999-08-31,1999-05-17
-6rkw,2019-11-06,2019-04-30
-1rkr,1998-05-20,1997-05-17
-4rku,2015-02-04,2014-10-14
-3rkb,2012-10-31,2011-04-17
-7rkw,2022-07-27,2021-07-22
-1rk0,2004-12-14,2003-11-20
-1rk9,2004-06-08,2003-11-21
-6rkh,2020-04-15,2019-04-30
-2rkn,2008-09-02,2007-10-17
-1rkq,2004-03-09,2003-11-23
-5rkd,2020-06-17,2020-06-02
-2rki,2008-04-22,2007-10-16
-7rkk,2022-07-20,2021-07-22
-2rkg,2008-08-05,2007-10-16
-5rkq,2020-06-17,2020-06-02
-5rk0,2020-06-17,2020-06-02
-4rk5,2014-11-05,2014-10-11
-6rkb,2020-01-29,2019-04-30
-6rk0,2019-05-08,2019-04-29
-4rk7,2014-10-29,2014-10-11
-5rk3,2020-06-17,2020-06-02
-5s9u,2022-06-15,2021-05-18
-5s9q,2021-09-29,2021-04-01
-5s9z,2022-06-15,2021-05-18
-5s9g,2021-02-17,2021-01-22
-7s99,2022-08-03,2021-09-20
-5s98,2021-02-17,2021-01-22
-3s9f,2012-06-13,2011-06-01
-3s9t,2012-04-18,2011-06-02
-1s9y,2004-09-28,2004-02-05
-8s93,2023-08-16,2023-03-27
-3s9h,2011-10-12,2011-06-01
-7s9i,2022-08-03,2021-09-21
-8s9i,2023-06-28,2023-03-28
-8s9m,2023-08-02,2023-03-29
-7s9m,2022-08-03,2021-09-21
-3s9i,2012-11-07,2011-06-01
-1s9p,2004-06-08,2004-02-05
-1s9q,2004-06-08,2004-02-05
-5s9y,2022-06-15,2021-05-18
-1s9t,2005-02-08,2004-02-05
-3s99,2011-06-22,2011-06-01
-7s9o,2022-08-03,2021-09-21
-7s9v,2022-06-15,2021-09-21
-3s9j,2011-06-22,2011-06-01
-8s9w,2024-02-07,2023-03-30
-5s91,2021-02-17,2021-01-22
-5s9b,2021-02-17,2021-01-22
-3s9m,2011-08-10,2011-06-01
-5s9e,2021-02-17,2021-01-22
-5s9r,2021-09-29,2021-04-01
-1s9j,2004-11-23,2004-02-04
-7s9f,2022-08-03,2021-09-20
-6s9a,2020-08-26,2019-07-11
-7s9h,2022-08-03,2021-09-21
-7s9l,2022-08-03,2021-09-21
-1s9d,2004-02-10,2004-02-04
-5s9x,2022-06-15,2021-05-18
-6s9n,2020-02-19,2019-07-15
-5s96,2021-02-17,2021-01-22
-1s9z,2004-04-06,2004-02-06
-8s94,2023-06-07,2023-03-27
-7s9j,2022-08-03,2021-09-21
-6s91,2020-07-08,2019-07-11
-3s9a,2011-09-07,2011-06-01
-5s9j,2021-02-17,2021-01-22
-6s96,2020-10-21,2019-07-11
-3s92,2011-06-29,2011-05-31
-5s93,2021-02-17,2021-01-22
-1s97,2004-04-27,2004-02-03
-1s9g,2004-05-11,2004-02-04
-8s9a,2023-07-26,2023-03-27
-7s9n,2022-08-03,2021-09-21
-5s9k,2021-06-23,2021-03-25
-7s9e,2021-11-03,2021-09-20
-5s9l,2022-04-13,2021-03-31
-1s9v,2004-03-02,2004-02-05
-7s97,2022-02-09,2021-09-20
-3s9b,2011-09-07,2011-06-01
-6s9w,2019-10-16,2019-07-15
-8s9q,2024-02-07,2023-03-29
-3s94,2011-11-02,2011-05-31
-3s9w,2011-06-22,2011-06-02
-1s95,2004-08-24,2004-02-03
-6s99,2020-08-26,2019-07-11
-7s9g,2022-08-03,2021-09-21
-6s9k,2020-01-22,2019-07-15
-7s95,2022-08-03,2021-09-20
-6s9j,2020-01-15,2019-07-15
-5s94,2021-02-17,2021-01-22
-6s9d,2019-11-20,2019-07-12
-3s95,2011-07-06,2011-05-31
-7s9y,2021-12-22,2021-09-21
-5s95,2021-02-17,2021-01-22
-5s90,2021-02-17,2021-01-22
-1s9a,2004-06-01,2004-02-04
-5s9w,2022-06-15,2021-05-18
-6s9m,2020-02-19,2019-07-15
-7s9p,2022-08-03,2021-09-21
-6s9f,2020-03-25,2019-07-12
-3s9n,2011-08-10,2011-06-01
-5s9n,2022-04-13,2021-03-31
-5s9p,2021-09-29,2021-04-01
-8s9z,2024-04-03,2023-03-30
-1s9w,2004-09-28,2004-02-05
-8s9s,2023-05-17,2023-03-30
-8s91,2023-06-07,2023-03-27
-5s9c,2021-02-17,2021-01-22
-1s9x,2004-09-28,2004-02-05
-3s9z,2012-11-07,2011-06-02
-7s9q,2022-08-03,2021-09-21
-1s9f,2005-02-15,2004-02-04
-3s9o,2012-06-06,2011-06-01
-5s92,2021-02-17,2021-01-22
-8s9h,2024-02-07,2023-03-28
-8s9c,2023-08-30,2023-03-27
-1s9r,2004-04-13,2004-02-05
-3s9q,2011-07-06,2011-06-02
-3s9u,2012-06-13,2011-06-02
-5s97,2021-02-17,2021-01-22
-5s9t,2022-06-15,2021-05-18
-6s90,2019-09-18,2019-07-11
-1s9e,2004-05-11,2004-02-04
-6s98,2020-10-21,2019-07-11
-6s9b,2019-11-20,2019-07-12
-6s9x,2019-10-16,2019-07-15
-6s9q,2020-06-17,2019-07-15
-8s96,2024-04-03,2023-03-27
-3s98,2011-08-31,2011-06-01
-3s91,2011-06-29,2011-05-31
-6s9z,2020-04-15,2019-07-15
-5s9a,2021-02-17,2021-01-22
-3s97,2011-09-28,2011-05-31
-7s9z,2021-12-22,2021-09-21
-7s9k,2022-08-03,2021-09-21
-6s9e,2020-02-19,2019-07-12
-8s98,2023-07-26,2023-03-27
-7s90,2022-08-03,2021-09-20
-3s9y,2012-04-18,2011-06-02
-7s9a,2021-11-03,2021-09-20
-7s96,2022-02-09,2021-09-20
-5s9d,2021-02-17,2021-01-22
-1s99,2004-10-05,2004-02-04
-6s9l,2020-02-19,2019-07-15
-5s9s,2022-06-15,2021-05-18
-7s98,2022-08-03,2021-09-20
-6s9c,2019-11-20,2019-07-12
-5s9m,2022-04-13,2021-03-31
-5s9o,2021-09-29,2021-04-01
-8s9b,2023-08-30,2023-03-27
-3s9l,2011-08-10,2011-06-01
-8s9f,2023-08-16,2023-03-28
-7s9x,2022-10-05,2021-09-21
-3s9c,2011-09-07,2011-06-01
-8s9n,2023-08-02,2023-03-29
-8s99,2023-07-26,2023-03-27
-3s9e,2011-09-28,2011-06-01
-5s99,2021-02-17,2021-01-22
-6s9o,2020-02-19,2019-07-15
-8s9r,2024-04-10,2023-03-30
-8s9o,2023-08-02,2023-03-29
-5s9v,2022-06-15,2021-05-18
-8s9g,2023-10-04,2023-03-28
-1s9i,2004-11-23,2004-02-04
-3s9s,2012-06-06,2011-06-02
-7s9w,2022-06-15,2021-09-21
-8s9v,2024-04-24,2023-03-30
-6s9g,2020-04-15,2019-07-12
-7tlq,2022-02-16,2022-01-18
-6tll,2020-12-16,2019-12-03
-8tlt,2024-05-15,2023-07-27
-8tl1,2024-03-06,2023-07-26
-4tla,2015-07-01,2014-05-29
-3tlk,2013-01-16,2011-08-30
-6tl3,2020-04-29,2019-11-30
-6tlf,2020-03-18,2019-12-02
-8tls,2024-04-03,2023-07-27
-5tlt,2017-01-18,2016-10-12
-8tlx,2024-05-29,2023-07-27
-3tlc,2012-02-29,2011-08-29
-3tle,2012-02-29,2011-08-29
-5tl9,2017-03-01,2016-10-10
-1tl7,2004-12-14,2004-06-09
-5tls,2016-10-26,2016-10-11
-6tlm,2020-03-04,2019-12-03
-7tll,2022-01-26,2022-01-18
-5tlj,2017-02-08,2016-10-11
-7tl1,2022-02-23,2022-01-18
-2tli,2000-02-18,1998-10-28
-8tln,1994-04-30,1993-09-01
-3tl1,2012-04-04,2011-08-29
-7tlu,2022-04-20,2022-01-18
-8tlw,2024-05-29,2023-07-27
-1tll,2004-08-31,2004-06-09
-7tlg,2022-08-03,2022-01-18
-7tle,2022-08-03,2022-01-18
-3tl0,2011-09-28,2011-08-29
-7tls,2022-04-20,2022-01-18
-5tlx,2017-01-18,2016-10-12
-4tlz,2014-09-17,2014-05-30
-3tlz,2012-02-29,2011-08-30
-4tlr,2014-12-10,2014-05-30
-4tls,2015-10-21,2014-05-30
-4tli,2000-03-13,1998-10-29
-6tld,2019-12-18,2019-12-02
-6tli,2000-03-13,1998-10-29
-6tlb,2020-06-24,2019-12-02
-8tl9,2023-11-08,2023-07-26
-7tlj,2023-02-08,2022-01-18
-3tlb,2012-02-29,2011-08-29
-5tlo,2017-01-18,2016-10-11
-5tlv,2017-01-18,2016-10-12
-4tlb,2015-07-01,2014-05-29
-4tl9,2015-07-01,2014-05-29
-3tl3,2011-09-07,2011-08-29
-6tls,2020-12-16,2019-12-03
-5tlq,2017-04-12,2016-10-11
-7tlr,2022-02-16,2022-01-18
-6tlx,2019-12-25,2019-12-03
-6tl2,2019-12-18,2019-11-29
-8tl0,2024-03-06,2023-07-26
-6tlk,2020-02-26,2019-12-02
-5tlz,2017-10-25,2016-10-12
-4tl5,2015-10-21,2014-05-28
-7tlm,2022-02-16,2022-01-18
-7tlp,2022-02-16,2022-01-18
-4tlg,2014-07-02,2014-05-29
-1tlp,1989-01-09,1987-06-29
-4tlf,2015-06-17,2014-05-29
-6tl9,2020-07-22,2019-12-02
-8tlq,2024-05-15,2023-07-27
-3tlp,2011-09-28,2011-08-30
-8tlv,2024-05-29,2023-07-27
-1tlm,1994-01-31,1992-12-22
-5tle,2017-10-25,2016-10-11
-6tl8,2020-07-22,2019-12-02
-6tly,2019-12-25,2019-12-03
-5tlk,2017-02-08,2016-10-11
-6tlr,2020-12-16,2019-12-03
-6tlv,2020-12-16,2019-12-03
-4tlx,2014-09-17,2014-05-30
-4tl3,2014-07-16,2014-05-29
-3tlm,2012-03-21,2011-08-30
-6tlq,2020-12-16,2019-12-03
-1tl2,1999-12-15,1998-12-14
-6tlz,2020-11-04,2019-12-03
-2tlx,2000-03-13,1999-01-28
-6tl5,2020-12-16,2019-12-01
-5tld,2017-01-18,2016-10-11
-1tlg,1999-07-23,1998-10-16
-1tlx,2000-03-13,1998-11-02
-7tl9,2022-02-23,2022-01-18
-1tl8,2005-06-21,2004-06-09
-4tlk,2015-10-21,2014-05-30
-7tli,2000-03-13,1998-10-30
-4tl0,2015-06-10,2014-05-28
-1tlz,2004-08-24,2004-06-10
-8tl8,2024-03-06,2023-07-26
-5tlu,2017-01-18,2016-10-12
-4tlc,2015-07-01,2014-05-29
-7tlo,2022-09-14,2022-01-18
-4tl7,2015-07-01,2014-05-29
-3tlh,1998-12-09,1998-12-03
-7tlt,2022-10-12,2022-01-18
-8tla,2023-11-08,2023-07-26
-4tld,2015-07-01,2014-05-29
-6tl4,2020-05-06,2019-12-01
-3tlr,2012-09-05,2011-08-30
-1tl4,2004-10-26,2004-06-09
-5tlp,2017-01-18,2016-10-11
-7tlz,2022-02-02,2022-01-19
-5tlm,2017-01-18,2016-10-11
-4tlh,2015-06-10,2014-05-29
-5tlb,2017-10-11,2016-10-10
-5tly,2017-01-18,2016-10-12
-8tlc,2024-02-21,2023-07-26
-4tl8,2015-07-01,2014-05-29
-6tlo,2020-12-16,2019-12-03
-5tlf,2017-01-18,2016-10-11
-5tlw,2017-10-25,2016-10-12
-1tlw,2004-08-24,2004-06-10
-5tlg,2017-01-18,2016-10-11
-6tl7,2020-07-22,2019-12-02
-6tlu,2020-12-16,2019-12-03
-1tlq,2004-06-22,2004-06-09
-7tl8,2022-08-10,2022-01-18
-4tln,1982-05-26,1982-02-08
-1tli,2000-02-18,1998-10-27
-3tli,2000-02-18,1998-10-28
-3tl9,2012-04-25,2011-08-29
-1tlf,1995-07-31,1995-03-06
-1tl1,2004-12-07,2004-06-09
-6tlw,2020-12-16,2019-12-03
-1tlc,1995-06-03,1995-03-07
-3tl5,2011-11-02,2011-08-29
-3tll,2012-07-18,2011-08-30
-4tll,2014-07-02,2014-05-30
-3tlx,2011-10-26,2011-08-30
-1tls,1997-07-07,1996-12-03
-6tlp,2020-12-16,2019-12-03
-5tli,2000-03-13,1998-10-29
-5tl5,2017-06-14,2016-10-10
-7tl7,2022-08-10,2022-01-18
-8tli,2000-03-13,1998-10-30
-7tln,1983-03-09,1983-01-27
-5tlh,2017-10-25,2016-10-11
-7tly,2022-02-02,2022-01-19
-1tl3,2004-12-07,2004-06-09
-5tll,2017-01-18,2016-10-11
-3tlj,2012-03-14,2011-08-30
-5tl4,2017-04-12,2016-10-10
-4tl6,2015-07-01,2014-05-29
-7tlk,2022-08-03,2022-01-18
-5tl7,2017-05-03,2016-10-10
-4tle,2015-07-01,2014-05-29
-1tld,1990-01-15,1989-07-24
-1tlo,2004-11-02,2004-06-09
-1tl9,2004-11-02,2004-06-09
-8tlz,2024-04-17,2023-07-27
-5tln,1982-05-26,1982-02-08
-7tlx,2022-04-06,2022-01-19
-8tld,2024-04-10,2023-07-26
-5tl6,2017-05-03,2016-10-10
-6tl0,2020-10-21,2019-11-29
-6tle,2021-06-30,2019-12-02
-5tl8,2017-10-11,2016-10-10
-4tlm,2014-07-02,2014-05-30
-7tlf,2022-02-09,2022-01-18
-6tlt,2020-12-16,2019-12-03
-4tlt,2015-10-21,2014-05-30
-3tld,2014-04-16,2011-08-29
-6tl6,2020-12-16,2019-12-01
-7tl0,2022-09-14,2022-01-17
-2hl1,2006-08-29,2006-07-06
-3hlw,2010-06-02,2009-05-28
-6hls,2019-04-03,2018-09-11
-3hly,2009-06-09,2009-05-28
-3hlv,2010-06-02,2009-05-28
-2hl2,2006-08-29,2006-07-06
-4hlw,2013-01-23,2012-10-17
-5hl0,2017-01-18,2016-01-14
-4hlh,2012-10-31,2012-10-17
-8hlj,2024-05-01,2022-11-30
-6hl5,2019-10-09,2018-09-10
-5hlp,2016-05-25,2016-01-15
-3hll,2009-07-14,2009-05-27
-5hll,2016-03-02,2016-01-15
-6hlm,2019-06-26,2018-09-11
-2hl3,2006-09-12,2006-07-06
-1hl7,2004-03-30,2003-03-14
-6hlr,2019-04-03,2018-09-11
-1hlg,2000-03-15,1999-03-12
-3hld,2009-10-27,2009-05-27
-8hlc,2024-06-05,2022-11-29
-3hlp,2010-06-02,2009-05-28
-6hll,2019-01-16,2018-09-11
-4hlq,2013-01-16,2012-10-17
-4hlb,2012-12-12,2012-10-16
-3hl7,2009-07-14,2009-05-26
-3hle,2009-10-27,2009-05-27
-2hl6,2006-10-31,2006-07-06
-2hlv,2008-03-25,2006-07-10
-6hl2,2019-06-26,2018-09-10
-1hlc,1994-04-30,1993-10-13
-5hl1,2016-08-24,2016-01-14
-5hlo,2016-06-08,2016-01-15
-1hl2,2003-05-09,2003-03-12
-6hlo,2019-01-16,2018-09-11
-8hl8,2023-03-29,2022-11-29
-6hla,2019-06-26,2018-09-11
-5hlb,2016-12-14,2016-01-14
-5hl7,2016-12-21,2016-01-14
-1hlz,2001-11-16,2000-12-04
-1hlp,1995-01-26,1994-10-04
-6hlz,2018-12-26,2018-09-11
-6hl3,2019-06-26,2018-09-10
-6hl1,2019-05-29,2018-09-10
-5hln,2016-05-25,2016-01-15
-1hlm,1995-02-07,1994-08-26
-8hlp,2024-04-24,2022-11-30
-6hl0,2019-05-29,2018-09-10
-8hlr,2024-05-01,2022-11-30
-4hln,2013-06-05,2012-10-17
-4hld,2012-10-31,2012-10-16
-4hl5,2012-10-31,2012-10-16
-8hl4,2023-11-29,2022-11-28
-1hl5,2003-05-08,2003-03-13
-1hlt,1994-12-20,1994-08-28
-3hli,2009-11-10,2009-05-27
-5hl3,2017-01-18,2016-01-14
-3hlh,2009-11-10,2009-05-27
-4hlz,2013-04-17,2012-10-17
-8hl5,2023-10-04,2022-11-28
-1hle,1994-01-31,1992-04-13
-1hlb,1994-06-22,1994-03-22
-6hl9,2019-02-20,2018-09-10
-5hlw,2016-11-23,2016-01-15
-1hlf,2000-12-13,2000-12-01
-3hlz,2009-06-16,2009-05-28
-4hlf,2012-10-31,2012-10-17
-6hl6,2019-10-09,2018-09-10
-8hls,2024-06-05,2022-11-30
-6hlb,2019-02-06,2018-09-11
-3hl4,2009-09-22,2009-05-26
-8hll,2023-07-26,2022-11-30
-4hls,2013-05-15,2012-10-17
-1hl9,2004-02-05,2003-03-14
-2hld,2006-11-28,2006-07-06
-3hl0,2009-06-16,2009-05-26
-8hl3,2023-09-20,2022-11-28
-1hld,1994-10-15,1993-11-23
-4hla,2013-07-24,2012-10-16
-6hlp,2019-01-16,2018-09-11
-4hlu,2013-02-06,2012-10-17
-2hl4,2007-05-22,2006-07-06
-8hlk,2023-12-13,2022-11-30
-5hlf,2016-02-10,2016-01-15
-4hlm,2012-10-31,2012-10-17
-3hl2,2009-10-06,2009-05-26
-3hl3,2009-06-09,2009-05-26
-8hlw,2023-09-27,2022-12-01
-5hle,2017-01-25,2016-01-14
-1hl4,2003-05-08,2003-03-13
-8hly,2023-09-27,2022-12-01
-5hla,2016-12-14,2016-01-14
-1hl3,2003-06-19,2003-03-13
-3hln,2010-07-28,2009-05-27
-2hlo,2007-07-17,2006-07-08
-2hl0,2006-08-29,2006-07-06
-4hle,2013-01-09,2012-10-16
-3hlj,2010-03-02,2009-05-27
-5hlv,2016-06-08,2016-01-15
-4hlg,2012-10-31,2012-10-17
-8hld,2024-06-05,2022-11-29
-6hle,2019-02-06,2018-09-11
-5hli,2017-01-25,2016-01-15
-8hln,2023-07-26,2022-11-30
-8hlf,2023-10-04,2022-11-30
-3hlt,2009-07-07,2009-05-28
-8hlq,2024-05-01,2022-11-30
-6hli,2019-06-26,2018-09-11
-8hl2,2023-09-20,2022-11-28
-5hld,2016-12-14,2016-01-14
-3hlg,2009-10-27,2009-05-27
-4hlc,2012-10-31,2012-10-16
-3hl8,2010-01-19,2009-05-27
-4hl1,2012-12-12,2012-10-15
-8hl1,2024-01-17,2022-11-28
-8hlm,2023-07-26,2022-11-30
-8hlt,2023-12-13,2022-12-01
-6hl8,2018-12-12,2018-09-10
-3hlx,2010-05-12,2009-05-28
-6hlf,2018-12-12,2018-09-11
-4hlk,2012-10-31,2012-10-17
-6hlq,2019-04-03,2018-09-11
-5hlm,2017-01-18,2016-01-15
-5hl4,2016-01-27,2016-01-14
-5hlk,2016-11-09,2016-01-15
-1hlu,1997-10-15,1997-05-30
-3hlo,2011-07-27,2009-05-27
-3hl5,2009-06-16,2009-05-26
-4hl2,2012-12-12,2012-10-15
-6hl4,2019-06-26,2018-09-10
-8hl7,2023-07-12,2022-11-29
-8hla,2023-03-22,2022-11-29
-6hld,2019-02-06,2018-09-11
-6hly,2018-12-26,2018-09-11
-1hlk,2001-11-30,2000-12-01
-2hln,2007-07-17,2006-07-08
-8hl6,2023-07-12,2022-11-29
-3hlf,2009-10-27,2009-05-27
-8hlv,2023-09-06,2022-12-01
-5hlx,2016-05-25,2016-01-15
-5hls,2016-02-10,2016-01-15
-2hlp,2000-02-04,1999-04-23
-4hlt,2013-05-29,2012-10-17
-5hl9,2016-12-14,2016-01-14
-6hlx,2018-12-26,2018-09-11
-5hlq,2016-05-25,2016-01-15
-8hle,2023-10-04,2022-11-30
-5hlu,2016-05-25,2016-01-15
-6hlj,2019-06-26,2018-09-11
-4gmk,2012-08-29,2012-08-16
-4gme,2012-09-12,2012-08-15
-7gm0,2023-11-08,2023-08-11
-5gmy,2017-02-01,2016-07-18
-1gmi,2001-10-25,2001-09-14
-4gm4,2013-05-22,2012-08-15
-5gm4,2017-05-17,2016-07-12
-6gmo,2019-06-19,2018-05-27
-8gmm,2024-03-27,2023-03-26
-7gmn,2023-11-08,2023-08-11
-7gmh,2023-11-08,2023-08-11
-1gmr,1993-10-31,1992-10-01
-5gmm,2017-05-24,2016-07-14
-6gmd,2018-06-06,2018-05-25
-5gmg,2016-11-02,2016-07-14
-3gmc,2009-04-14,2009-03-13
-3gme,2009-06-09,2009-03-13
-7gmt,2023-11-08,2023-08-11
-4gmc,2013-02-20,2012-08-15
-6gmb,2018-06-13,2018-05-24
-2gms,2006-09-05,2006-04-07
-7gmd,2023-11-08,2023-08-11
-3gmr,2009-11-10,2009-03-14
-6gmq,2018-08-22,2018-05-28
-3gmz,2010-01-26,2009-03-15
-8gmu,2022-12-21,2022-08-22
-8gmw,2022-09-21,2022-08-22
-6gm2,2018-11-07,2018-05-24
-6gmt,2019-06-19,2018-05-28
-1gm8,2001-11-28,2001-09-11
-5gm7,2016-07-27,2016-07-13
-7gmq,2023-11-08,2023-08-11
-1gmw,2001-11-28,2001-09-24
-5gmj,2017-05-24,2016-07-14
-1gm5,2001-10-03,2001-09-11
-8gm4,2023-05-31,2023-03-24
-8gml,2023-09-20,2023-03-26
-6gmu,2019-04-17,2018-05-28
-8gmk,2023-06-07,2023-03-26
-1gm9,2001-11-28,2001-09-12
-1gmy,2002-09-19,2001-09-25
-4gm1,2013-05-22,2012-08-15
-7gmv,2023-11-08,2023-08-11
-6gm5,2018-11-07,2018-05-24
-7gmi,2023-11-08,2023-08-11
-6gmf,2019-03-27,2018-05-25
-7gm1,2023-11-08,2023-08-11
-7gmc,2023-11-08,2023-08-11
-4gmu,2013-07-03,2012-08-16
-6gmn,2018-08-08,2018-05-27
-1gm7,2001-11-28,2001-09-11
-8gme,2023-06-28,2023-03-24
-7gm7,2023-11-08,2023-08-11
-6gmc,2018-06-13,2018-05-24
-2gm9,2007-02-13,2006-04-06
-7gmx,2023-11-08,2023-08-11
-7gmm,2023-11-08,2023-08-11
-4gmx,2012-10-17,2012-08-16
-8gmd,2023-07-12,2023-03-24
-7gms,2023-11-08,2023-08-11
-2gmr,2006-11-21,2006-04-07
-3gm6,2009-08-04,2009-03-13
-1gmc,1993-10-31,1993-08-20
-5gm8,2016-10-26,2016-07-13
-7gm9,2023-11-08,2023-08-11
-4gm3,2013-07-31,2012-08-15
-8gmv,2022-09-21,2022-08-22
-6gml,2018-09-05,2018-05-27
-6gmx,2018-08-08,2018-05-28
-8gmt,2022-12-21,2022-08-22
-7gmj,2023-11-08,2023-08-11
-6gm0,2018-11-07,2018-05-24
-3gm0,2009-10-06,2009-03-12
-6gm9,2019-06-19,2018-05-24
-5gm1,2016-09-28,2016-07-12
-4gm7,2012-09-19,2012-08-15
-6gmr,2018-08-08,2018-05-28
-8gm3,2024-03-27,2023-03-24
-7gmz,2023-11-08,2023-08-11
-2gmt,1994-11-01,1994-09-07
-7gml,2023-11-08,2023-08-11
-2gm4,2006-06-27,2006-04-05
-7gm2,2023-11-08,2023-08-11
-8gm2,2023-12-27,2023-03-24
-4gm8,2013-07-31,2012-08-15
-3gmn,2009-11-10,2009-03-14
-4gmj,2012-10-03,2012-08-16
-8gms,2022-12-21,2022-08-22
-5gmp,2017-06-28,2016-07-14
-8gmc,2023-07-12,2023-03-24
-4gmm,2013-07-03,2012-08-16
-2gmn,2007-04-24,2006-04-07
-2gm1,2006-06-27,2006-04-05
-4gmd,2012-08-29,2012-08-15
-2gmw,2007-04-10,2006-04-07
-2gmp,2006-07-25,2006-04-07
-5gmi,2017-05-24,2016-07-14
-3gmq,2009-11-10,2009-03-14
-6gmh,2018-08-22,2018-05-26
-5gmu,2017-07-26,2016-07-16
-5gm2,2016-09-28,2016-07-12
-7gmp,2023-11-08,2023-08-11
-8gm1,2024-02-07,2023-03-24
-4gmb,2014-02-19,2012-08-15
-1gm4,2002-09-05,2001-09-10
-5gmh,2016-11-02,2016-07-14
-4gms,2012-10-03,2012-08-16
-4gm5,2013-08-21,2012-08-15
-5gme,2016-12-28,2016-07-13
-2gm3,2006-04-18,2006-04-05
-6gm4,2018-11-07,2018-05-24
-6gmg,2018-10-24,2018-05-25
-5gm5,2017-05-17,2016-07-12
-4gmt,2012-10-03,2012-08-16
-7gm4,2023-11-08,2023-08-11
-3gmb,2009-04-14,2009-03-13
-7gmf,2023-11-08,2023-08-11
-4gmz,2013-07-03,2012-08-16
-5gm3,2017-05-17,2016-07-12
-7gm3,2023-11-08,2023-08-11
-7gmu,2023-11-08,2023-08-11
-8gmb,2023-08-16,2023-03-24
-3gmm,2009-11-10,2009-03-14
-7gmg,2023-11-08,2023-08-11
-6gm1,2018-11-07,2018-05-24
-6gm6,2018-11-07,2018-05-24
-6gmv,2019-06-19,2018-05-28
-1gmm,2001-11-28,2001-09-19
-5gmv,2017-03-08,2016-07-17
-3gml,2009-11-10,2009-03-14
-4gm0,2013-05-22,2012-08-15
-8gm5,2023-05-31,2023-03-24
-5gmd,2016-12-28,2016-07-13
-7gmb,2023-11-08,2023-08-11
-5gm6,2016-09-21,2016-07-12
-5gmz,2016-08-10,2016-07-18
-2gmu,2006-09-05,2006-04-07
-1gmp,1993-10-31,1992-10-01
-5gm0,2016-11-09,2016-07-12
-7gmw,2023-11-08,2023-08-11
-1gmd,1993-10-31,1993-08-20
-5gmn,2017-05-24,2016-07-14
-3gmo,2009-11-10,2009-03-14
-2gm8,2006-04-18,2006-04-06
-7gme,2023-11-08,2023-08-11
-4gmi,2013-09-04,2012-08-16
-4gmw,2013-07-03,2012-08-16
-8gmi,2023-06-07,2023-03-25
-3gmp,2009-11-10,2009-03-14
-5gmk,2016-08-17,2016-07-14
-3gmd,2010-11-17,2009-03-13
-6gm3,2018-11-07,2018-05-24
-3gma,2009-07-28,2009-03-13
-7gm6,2023-11-08,2023-08-11
-7gmr,2023-11-08,2023-08-11
-2gmk,2006-04-25,2006-04-06
-5gmq,2017-05-31,2016-07-15
-7gma,2023-11-08,2023-08-11
-7gm8,2023-11-08,2023-08-11
-2gmm,2006-07-25,2006-04-07
-2gmh,2006-10-17,2006-04-06
-1gm6,2002-05-30,2001-09-11
-8gmn,2023-05-17,2023-03-26
-7gmk,2023-11-08,2023-08-11
-7gmo,2023-11-08,2023-08-11
-6gmz,2019-04-10,2018-05-29
-2gmj,2006-10-17,2006-04-06
-4gm9,2014-02-19,2012-08-15
-1gmh,1994-09-30,1994-07-01
-7gmy,2023-11-08,2023-08-11
-6gm8,2018-11-07,2018-05-24
-5gmf,2016-11-02,2016-07-14
-1gmb,2002-09-12,2001-09-12
-1gmk,1998-07-01,1996-07-09
-4gmg,2012-10-31,2012-08-15
-7gm5,2023-11-08,2023-08-11
-2gmv,2007-05-29,2006-04-07
-5gm9,2017-04-19,2016-07-13
-2gmx,2006-06-06,2006-04-07
-4gmy,2013-06-19,2012-08-16
-4ar4,2013-01-16,2012-04-20
-8arx,2023-09-20,2022-08-17
-9art,2024-04-24,2024-02-23
-4ar9,2013-06-05,2012-04-22
-1ar6,1997-12-03,1997-08-11
-3arz,2011-04-20,2010-12-09
-3ar6,2011-02-02,2010-11-24
-8ar5,2023-09-20,2022-08-15
-1ary,1996-01-29,1995-04-25
-2arh,2005-10-04,2005-08-19
-3arj,2011-04-27,2010-12-02
-4ar2,2012-10-24,2012-04-20
-3ar2,2011-02-02,2010-11-24
-3are,2011-03-30,2010-11-27
-8ar8,2022-10-05,2022-08-15
-5ar7,2015-10-21,2015-09-24
-4arz,2012-07-25,2012-04-27
-6arl,2018-05-30,2017-08-22
-7ar0,2021-11-03,2020-10-23
-7arz,2021-11-03,2020-10-26
-6arm,2018-02-28,2017-08-22
-7arg,2021-08-04,2020-10-24
-1ar8,1997-12-03,1997-08-11
-3arl,2011-04-27,2010-12-02
-7ara,2021-07-28,2020-10-23
-4aru,2013-05-08,2012-04-26
-1ar4,1997-11-12,1997-08-09
-6arq,2018-11-21,2017-08-23
-3ara,2010-12-08,2010-11-25
-4arr,2013-02-27,2012-04-26
-8arn,2023-02-22,2022-08-17
-3aru,2011-04-20,2010-12-09
-6arg,2018-05-30,2017-08-22
-3arw,2011-04-20,2010-12-09
-7arn,2021-11-03,2020-10-25
-1arf,1994-01-31,1993-10-01
-5arg,2016-04-27,2015-09-24
-2are,2006-08-01,2005-08-19
-6arb,2018-08-01,2017-08-22
-6arx,2018-01-10,2017-08-23
-2ar8,2005-10-04,2005-08-19
-7ar7,2022-03-02,2020-10-23
-8arp,2023-03-22,2022-08-17
-4arb,2012-11-28,2012-04-23
-8ar4,2023-09-20,2022-08-15
-4ary,2013-05-15,2012-04-27
-7arl,2021-04-07,2020-10-25
-2ary,2005-08-30,2005-08-22
-3ar5,2011-02-02,2010-11-24
-5ar5,2015-10-21,2015-09-24
-1ar9,1997-12-03,1997-08-11
-4arq,2012-05-09,2012-04-25
-8arw,2023-09-20,2022-08-17
-6arj,2018-02-07,2017-08-22
-7ard,2021-12-08,2020-10-23
-3ary,2011-04-20,2010-12-09
-4ar8,2013-06-05,2012-04-21
-5arl,2016-01-20,2015-09-25
-2arp,2006-03-07,2005-08-21
-1aru,1996-01-29,1995-04-25
-6aro,2018-02-28,2017-08-23
-4ar5,2012-12-19,2012-04-20
-8aru,2023-08-23,2022-08-17
-7arb,2021-12-15,2020-10-23
-5arf,2016-04-27,2015-09-24
-4arf,2013-06-05,2012-04-23
-7aru,2020-11-11,2020-10-26
-7arj,2021-04-07,2020-10-25
-1ars,1994-08-31,1993-08-02
-8arg,2023-09-20,2022-08-16
-5arc,2016-09-14,2015-09-24
-3arg,2011-03-30,2010-11-27
-9arq,2024-04-24,2024-02-23
-3art,2011-04-20,2010-12-09
-6arr,2018-05-30,2017-08-23
-6ary,2018-01-10,2017-08-23
-1arv,1996-01-29,1995-04-25
-3arf,2011-03-30,2010-11-27
-1ar1,1998-02-11,1997-08-08
-4are,2013-06-05,2012-04-23
-1ari,1995-11-14,1995-08-23
-3ar4,2011-02-02,2010-11-24
-6ar3,2017-11-29,2017-08-21
-7aro,2021-04-07,2020-10-25
-5ark,2016-01-20,2015-09-25
-2aru,2005-10-04,2005-08-22
-2ar6,2006-08-01,2005-08-19
-4ar6,2012-12-19,2012-04-20
-2art,2005-10-04,2005-08-22
-1arz,1998-10-14,1997-08-08
-5ar8,2015-10-21,2015-09-24
-9ars,2024-04-24,2024-02-23
-6ar1,2017-11-29,2017-08-21
-7ark,2021-04-07,2020-10-25
-6art,2018-05-30,2017-08-23
-6ar4,2018-08-22,2017-08-21
-1art,1994-08-31,1993-08-02
-3ark,2011-04-27,2010-12-02
-4ar3,2013-01-16,2012-04-20
-6arf,2018-05-30,2017-08-22
-2arb,2006-08-01,2005-08-19
-5ar2,2015-10-21,2015-09-23
-6ark,2018-01-31,2017-08-22
-3arn,2010-12-15,2010-12-03
-1are,1994-01-31,1993-10-01
-8arj,2022-09-14,2022-08-17
-2ard,2005-10-04,2005-08-19
-4arc,2012-06-13,2012-04-23
-3ar7,2011-02-02,2010-11-24
-7arc,2021-12-08,2020-10-23
-1aro,1998-10-21,1997-08-08
-8arr,2023-09-20,2022-08-17
-6ard,2017-10-11,2017-08-22
-3ar8,2011-02-02,2010-11-24
-6ar2,2018-07-04,2017-08-21
-4arn,2013-01-23,2012-04-25
-6are,2018-05-30,2017-08-22
-1arc,1993-10-31,1993-04-15
-8arv,2023-04-12,2022-08-17
-6arv,2018-02-07,2017-08-23
-3ar9,2011-02-02,2010-11-24
-6ari,2018-08-22,2017-08-22
-7arw,2021-06-16,2020-10-26
-6ar9,2018-03-14,2017-08-21
-1arh,1995-11-14,1995-08-23
-4ara,2012-11-28,2012-04-23
-3arp,2011-04-20,2010-12-09
-2arc,1997-05-15,1996-10-29
-2ar3,2006-06-06,2005-08-19
-3ard,2011-03-30,2010-11-27
-7ar9,2021-12-08,2020-10-23
-4aro,2013-05-08,2012-04-25
-7ars,2021-07-14,2020-10-26
-1ar7,1997-12-03,1997-08-11
-6arc,2017-10-11,2017-08-22
-6arn,2018-02-28,2017-08-22
-2arx,2006-08-01,2005-08-22
-8arz,2023-09-20,2022-08-17
-4ark,2013-03-06,2012-04-24
-2arm,2005-09-20,2005-08-20
-3arq,2011-04-20,2010-12-09
-4ar1,2013-06-05,2012-04-20
-4arw,2012-10-31,2012-04-26
-1arw,1996-01-29,1995-04-25
-7arr,2021-07-14,2020-10-26
-3arr,2011-04-20,2010-12-09
-8arq,2023-09-20,2022-08-17
-4arx,2013-05-15,2012-04-27
-6aru,2018-08-29,2017-08-23
-3ar3,2011-02-02,2010-11-24
-5ard,2016-09-14,2015-09-24
-8are,2023-02-22,2022-08-16
-5arb,2016-09-14,2015-09-24
-1ard,1994-01-31,1993-10-01
-7arf,2020-12-02,2020-10-24
-4ari,2012-06-13,2012-04-24
-1arx,1996-01-29,1995-04-25
-1arp,1994-01-31,1993-06-18
-8aro,2023-09-20,2022-08-17
-8art,2023-08-30,2022-08-17
-5ar0,2016-05-11,2015-09-22
-3arx,2011-04-20,2010-12-09
-3arv,2011-04-20,2010-12-09
-3arb,2011-03-30,2010-11-26
-5arn,2016-10-12,2015-09-25
-5ar3,2015-10-21,2015-09-23
-2ars,2005-10-04,2005-08-22
-1arm,1996-08-17,1994-11-22
-1ar5,1997-11-12,1997-08-09
-8ari,2023-08-23,2022-08-16
-1arg,1995-11-14,1995-08-23
-8ary,2023-09-20,2022-08-17
-8ar7,2022-10-05,2022-08-15
-7ar8,2021-12-15,2020-10-23
-5ar4,2015-10-21,2015-09-24
-4tmb,2015-02-11,2014-05-31
-4tmc,2015-02-11,2014-05-31
-7tmf,2022-02-02,2022-01-19
-7tmo,2022-04-06,2022-01-19
-3tm0,2011-10-19,2011-08-30
-6tmr,2020-02-19,2019-12-05
-6tm3,2020-02-26,2019-12-03
-4tmk,1998-11-25,1998-08-31
-6tmh,2020-12-16,2019-12-04
-5tmu,2017-01-18,2016-10-13
-1tmo,1999-03-30,1998-08-03
-3tmz,2012-09-12,2011-09-01
-3tmc,2011-10-19,2011-08-31
-1tmb,1994-01-31,1993-05-27
-1tmk,1998-06-17,1997-06-12
-3tmj,2011-11-09,2011-08-31
-4tmt,2014-09-24,2014-06-02
-4tmw,2014-09-24,2014-06-02
-4tmu,2015-03-11,2014-06-02
-7tmq,2022-04-06,2022-01-19
-7tmg,2022-02-02,2022-01-19
-5tm8,2017-01-18,2016-10-12
-5tml,2017-01-18,2016-10-13
-5tmw,2017-01-18,2016-10-13
-7tm3,2022-10-19,2022-01-19
-3tm3,2014-04-16,2011-08-31
-5tmr,2017-01-18,2016-10-13
-5tmg,2017-10-18,2016-10-12
-3tmv,2012-08-22,2011-08-31
-4tmz,2014-09-24,2014-06-02
-5tmf,2016-11-23,2016-10-12
-3tmq,2011-09-21,2011-08-31
-1tmn,1989-01-09,1987-06-29
-5tmb,2016-11-02,2016-10-12
-6tmw,2020-04-22,2019-12-05
-1tmu,1994-09-30,1994-05-26
-4tmf,2015-05-13,2014-06-01
-5tm7,2017-01-18,2016-10-12
-2tmk,1998-06-17,1997-06-12
-8tm2,2024-04-17,2023-07-27
-5tmd,2016-11-02,2016-10-12
-3tmy,1997-12-03,1997-06-04
-7tmy,2023-08-02,2022-01-20
-6tm6,2020-02-19,2019-12-03
-5tm3,2017-01-18,2016-10-12
-3tm4,2012-03-14,2011-08-31
-6tmp,2020-10-14,2019-12-05
-6tms,2020-04-29,2019-12-05
-7tms,2022-04-13,2022-01-20
-1tmt,1994-09-30,1994-05-26
-4tm1,2014-09-17,2014-05-30
-7tmc,2023-01-25,2022-01-19
-6tme,2020-03-18,2019-12-04
-6tm4,2020-01-15,2019-12-03
-3tmw,2012-08-22,2011-08-31
-1tmx,2005-03-22,2004-06-11
-1tm1,2004-11-09,2004-06-10
-4tm3,2014-09-17,2014-05-30
-6tmu,2020-04-22,2019-12-05
-4tmr,2015-03-25,2014-06-02
-5tms,2017-01-18,2016-10-13
-6tma,2020-09-02,2019-12-03
-7tmw,2023-02-15,2022-01-20
-5tm4,2017-01-18,2016-10-12
-7tmt,2022-04-20,2022-01-20
-3tm5,2012-03-14,2011-08-31
-7tmu,2022-02-02,2022-01-20
-5tmq,2017-01-18,2016-10-13
-7tma,2023-01-25,2022-01-19
-7tm9,2022-02-02,2022-01-19
-7tm0,2022-02-02,2022-01-19
-6tmx,2020-04-22,2019-12-05
-5tmt,2017-01-18,2016-10-13
-4tmx,2014-09-24,2014-06-02
-4tm0,2014-09-17,2014-05-30
-7tmr,2022-04-13,2022-01-19
-7tml,2022-04-20,2022-01-19
-7tmp,2022-04-06,2022-01-19
-4tmv,2014-09-24,2014-06-02
-7tme,2023-01-25,2022-01-19
-7tm1,2022-04-20,2022-01-19
-6tmz,2020-10-14,2019-12-05
-6tmt,2020-04-22,2019-12-05
-3tmb,2011-10-19,2011-08-31
-3tmu,2012-08-22,2011-08-31
-5tmo,2017-01-18,2016-10-13
-2tmn,1989-01-09,1987-06-29
-1tmg,2004-11-09,2004-06-10
-5tmk,2017-10-18,2016-10-13
-8tmt,2023-12-06,2023-07-30
-3tm9,2014-04-16,2011-08-31
-7tmz,2022-08-17,2022-01-20
-2tmv,1989-01-09,1988-09-15
-6tmm,2020-12-16,2019-12-04
-7tmm,2022-04-06,2022-01-19
-1tmq,1999-03-02,1998-01-13
-6tm5,2020-02-19,2019-12-03
-3tme,2011-09-14,2011-08-31
-5tm9,2017-01-18,2016-10-12
-3tmd,2011-10-19,2011-08-31
-7tmk,2022-04-20,2022-01-19
-7tmh,2022-04-20,2022-01-19
-4tmp,2014-11-05,2014-06-02
-6tmf,2020-02-12,2019-12-04
-1tmj,2005-06-21,2004-06-10
-6tm0,2020-11-04,2019-12-03
-7tm6,2022-02-02,2022-01-19
-4tm6,2015-03-25,2014-05-31
-5tm5,2017-01-18,2016-10-12
-6tm9,2020-07-22,2019-12-03
-6tm7,2020-03-18,2019-12-03
-1tm3,2004-11-09,2004-06-10
-5tm2,2017-01-18,2016-10-12
-4tmy,1997-12-03,1997-06-06
-7tmi,2022-04-20,2022-01-19
-7tmv,2022-02-02,2022-01-20
-8tmr,2023-12-06,2023-07-30
-7tm2,2022-04-20,2022-01-19
-4tma,2014-07-23,2014-05-31
-2tmd,1994-01-31,1993-10-15
-5tme,2016-11-02,2016-10-12
-4tme,2015-03-25,2014-06-01
-6tmc,2020-07-22,2019-12-04
-3tmn,1989-01-09,1987-06-29
-1tm6,2004-10-12,2004-06-10
-5tm1,2017-01-18,2016-10-12
-3tmk,1999-02-16,1998-01-26
-1tm7,2004-11-09,2004-06-10
-7tm5,2022-02-02,2022-01-19
-5tma,2017-10-18,2016-10-12
-3tm8,2011-10-19,2011-08-31
-5tmz,2017-01-18,2016-10-13
-7tm7,2022-02-02,2022-01-19
-6tmb,2020-09-02,2019-12-04
-5tmv,2017-01-18,2016-10-13
-7tmx,2023-08-02,2022-01-20
-3tmx,2012-08-22,2011-08-31
-1tmm,2005-06-21,2004-06-10
-5tm6,2017-01-18,2016-10-12
-7tmb,2022-02-02,2022-01-19
-1tm5,2004-11-09,2004-06-10
-8tm0,2024-04-17,2023-07-27
-6tmk,2020-12-16,2019-12-04
-5tmc,2016-11-23,2016-10-12
-6tmq,2020-10-14,2019-12-05
-1tm4,2004-11-09,2004-06-10
-6tm2,2020-10-21,2019-12-03
-4tm7,2015-06-03,2014-05-31
-7tmj,2022-04-20,2022-01-19
-1tmc,1995-03-31,1994-12-19
-5tmm,2017-01-18,2016-10-13
-5tmh,2017-02-08,2016-10-12
-6tmy,2020-12-02,2019-12-05
-3tm2,2012-07-04,2011-08-30
-4tm4,2014-09-17,2014-05-30
-2dso,2006-12-12,2006-07-04
-4dsf,2012-06-06,2012-02-18
-8dse,2023-03-08,2022-07-22
-3dst,2008-09-09,2008-07-14
-8dso,2023-03-08,2022-07-22
-4dsj,2013-03-27,2012-02-19
-2ds7,2007-02-13,2006-06-22
-5ds0,2015-10-14,2015-09-16
-7dsd,2022-01-05,2020-12-30
-5dsg,2016-03-16,2015-09-17
-5dsh,2016-09-21,2015-09-17
-5ds3,2016-07-27,2015-09-16
-8ds7,2024-02-07,2022-07-21
-3ds0,2008-09-02,2008-07-11
-7dsk,2021-03-10,2020-12-31
-6dsx,2018-10-31,2018-06-14
-8ds5,2022-09-28,2022-07-21
-1ds6,2000-07-12,2000-01-07
-4dsz,2013-02-27,2012-02-20
-4dsb,2012-06-06,2012-02-18
-2dsz,2006-08-01,2006-07-09
-8dsc,2023-03-08,2022-07-22
-7ds1,2021-07-14,2020-12-30
-3ds3,2008-09-02,2008-07-11
-5dsm,2016-05-04,2015-09-17
-6ds7,2019-06-19,2018-06-13
-3dsw,2008-09-09,2008-07-14
-7ds0,2021-07-14,2020-12-30
-2ds6,2007-02-13,2006-06-22
-1dsg,2001-03-07,2000-01-07
-7dsa,2021-03-03,2020-12-30
-4dso,2012-04-04,2012-02-19
-1ds8,2000-03-08,2000-01-07
-5dsk,2016-05-04,2015-09-17
-2ds9,2006-07-04,2006-06-22
-8ds1,2022-09-28,2022-07-21
-6ds0,2018-08-29,2018-06-13
-2dsf,2006-07-11,2006-06-29
-4dsg,2012-06-13,2012-02-18
-3ds4,2008-09-02,2008-07-11
-3dsr,2009-06-16,2008-07-14
-1dss,1998-12-09,1997-06-04
-8dsu,2023-03-29,2022-07-22
-3dsj,2008-08-19,2008-07-12
-4dst,2012-04-04,2012-02-19
-1ds4,2001-03-07,2000-01-07
-2dsi,2006-12-30,2006-06-30
-1dsz,2000-07-10,2000-01-10
-3ds9,2008-09-30,2008-07-11
-1dso,2001-03-07,2000-01-07
-2dsv,2006-08-01,2006-07-07
-2dsw,2006-08-01,2006-07-07
-4dsa,2013-02-27,2012-02-18
-4dsy,2012-09-19,2012-02-20
-8dsl,2023-03-22,2022-07-22
-3dsx,2008-09-09,2008-07-14
-8dsj,2023-03-22,2022-07-22
-5dsx,2016-06-15,2015-09-17
-6ds1,2019-07-10,2018-06-13
-3dss,2008-09-09,2008-07-14
-4dse,2012-06-06,2012-02-18
-8dsz,2022-09-07,2022-07-24
-6dsv,2018-10-31,2018-06-14
-2dsn,2007-07-17,2006-07-03
-1ds5,2001-01-07,2000-01-07
-7dse,2022-01-05,2020-12-30
-6ds9,2018-10-03,2018-06-13
-5dsu,2017-01-11,2015-09-17
-3dsk,2008-08-19,2008-07-12
-7dsi,2022-03-23,2020-12-31
-8dsf,2023-03-08,2022-07-22
-7dsp,2021-03-17,2020-12-31
-6dss,2018-10-17,2018-06-14
-6dsr,2018-10-17,2018-06-14
-1dsw,2000-03-22,2000-01-10
-2dsy,2007-03-27,2006-07-07
-3ds6,2008-10-07,2008-07-11
-3dsu,2008-09-09,2008-07-14
-8dsk,2023-10-18,2022-07-22
-8dsg,2023-03-08,2022-07-22
-8dsh,2023-03-08,2022-07-22
-2dsu,2006-07-25,2006-07-07
-5dsc,2016-01-20,2015-09-17
-3dsd,2008-10-14,2008-07-11
-2ds5,2007-02-13,2006-06-22
-1ds7,2000-07-12,2000-01-07
-2dsa,2006-08-22,2006-06-24
-8ds2,2022-09-28,2022-07-21
-4dsi,2013-03-27,2012-02-19
-6dsy,2018-10-31,2018-06-14
-2ds1,2007-06-19,2006-06-17
-7dsx,2021-06-23,2021-01-03
-8dsv,2023-07-26,2022-07-22
-6dsu,2018-10-31,2018-06-14
-2dsg,2006-12-30,2006-06-30
-4ds8,2012-06-06,2012-02-18
-7dsn,2021-03-10,2020-12-31
-2ds8,2007-02-13,2006-06-22
-4dsh,2012-06-13,2012-02-18
-8ds8,2023-08-02,2022-07-21
-7dsl,2021-03-10,2020-12-31
-4dsn,2012-04-25,2012-02-19
-8dsd,2023-03-08,2022-07-22
-3ds1,2008-09-02,2008-07-11
-5dsf,2016-02-03,2015-09-17
-6dsw,2018-10-31,2018-06-14
-8dsn,2023-03-22,2022-07-22
-7dsy,2021-11-24,2021-01-03
-7dso,2021-03-17,2020-12-31
-3dsy,2009-06-30,2008-07-14
-4dsc,2012-06-06,2012-02-18
-3dsq,2008-08-12,2008-07-14
-8dst,2023-05-31,2022-07-22
-8dsi,2023-03-08,2022-07-22
-2dsl,2006-12-30,2006-06-30
-6ds2,2018-07-04,2018-06-13
-5ds7,2016-09-28,2015-09-17
-4ds5,2012-06-06,2012-02-17
-1dsq,2000-01-28,2000-01-08
-7dsr,2021-03-17,2020-12-31
-1ds1,2000-07-06,2000-01-06
-6ds6,2018-08-29,2018-06-13
-7dsf,2021-01-13,2020-12-31
-1dsp,2001-03-07,2000-01-07
-3dsz,2009-05-19,2008-07-14
-3dsf,2008-10-14,2008-07-12
-1dse,2001-03-07,2000-01-07
-1dsr,1997-02-12,1996-07-05
-3dso,2009-03-10,2008-07-13
-5dsy,2016-07-27,2015-09-17
-6ds5,2018-10-24,2018-06-13
-1dsd,1996-12-07,1996-08-10
-5ds8,2016-01-20,2015-09-17
-3dse,2008-09-30,2008-07-11
-1dsv,2000-01-28,2000-01-08
-8dsm,2023-08-02,2022-07-22
-5ds5,2015-10-28,2015-09-16
-1dsy,2000-01-26,2000-01-10
-1dsc,1996-12-07,1996-08-10
-4ds7,2012-03-07,2012-02-18
-7dsj,2021-03-17,2020-12-31
-2dsc,2006-11-14,2006-06-28
-8dsy,2022-09-07,2022-07-24
-2ds0,2007-02-06,2006-06-16
-7dsu,2022-01-05,2021-01-02
-4dsu,2012-04-04,2012-02-19
-2dsh,2006-12-30,2006-06-30
-4ds4,2012-06-06,2012-02-17
-8dsr,2022-10-19,2022-07-22
-3dsi,2008-08-19,2008-07-12
-5dst,2016-02-24,2015-09-17
-4dsk,2013-03-27,2012-02-19
-8dsw,2023-09-27,2022-07-23
-1dsn,1996-03-08,1995-12-13
-7dsc,2022-01-05,2020-12-30
-4ds0,2012-04-11,2012-02-17
-2dsx,2006-10-10,2006-07-07
-7dsh,2022-03-23,2020-12-31
-2dsd,2006-11-14,2006-06-28
-7dsq,2021-03-10,2020-12-31
-3dsv,2008-09-09,2008-07-14
-3dsl,2008-10-21,2008-07-13
-5dsl,2016-05-04,2015-09-17
-6dsp,2019-02-06,2018-06-14
-1sp5,2005-07-19,2004-03-16
-8spw,2024-01-24,2023-05-03
-3sp6,2011-07-20,2011-07-01
-3sp3,2011-07-27,2011-07-01
-1sps,1994-05-31,1993-03-05
-5spa,2022-07-13,2022-06-09
-3sp1,2011-08-17,2011-06-30
-7spa,2022-04-06,2021-11-02
-5spj,2022-07-13,2022-06-09
-5spz,2022-07-06,2022-06-09
-1sp9,2004-09-21,2004-03-16
-5sp8,2022-07-13,2022-06-09
-5sp6,2022-07-13,2022-06-09
-3sp5,2016-05-04,2011-07-01
-1sp3,2004-09-21,2004-03-16
-8spc,2023-12-13,2023-05-02
-7sp3,2022-03-09,2021-11-02
-6spt,2020-01-01,2019-09-02
-1spb,1995-10-15,1995-06-21
-7spg,2022-06-01,2021-11-02
-5spe,2022-07-13,2022-06-09
-3sp9,2011-07-20,2011-07-01
-1sp2,1997-04-21,1996-11-21
-3spi,2011-08-24,2011-07-01
-8sp7,2024-05-22,2023-05-02
-6spp,2020-01-01,2019-09-02
-5spt,2022-07-13,2022-06-09
-5sp4,2022-07-13,2022-06-09
-6sps,2020-09-30,2019-09-02
-5spm,2022-07-13,2022-06-09
-2spm,1994-01-31,1993-08-25
-5sp2,2022-07-13,2022-06-09
-7sp8,2022-04-06,2021-11-02
-3spc,2011-08-24,2011-07-01
-6spn,2020-01-01,2019-09-02
-5spc,2022-07-13,2022-06-09
-8sp5,2024-05-22,2023-05-02
-8spf,2023-12-27,2023-05-03
-3spj,2011-08-24,2011-07-01
-6sp1,2020-06-03,2019-08-30
-6spv,2019-10-02,2019-09-02
-7spo,2022-01-05,2021-11-02
-3sp7,2012-07-04,2011-07-01
-6spq,2020-01-01,2019-09-02
-3spl,2011-10-12,2011-07-02
-5spf,2022-07-13,2022-06-09
-6spr,2020-01-01,2019-09-02
-5spg,2022-07-13,2022-06-09
-1spj,2005-01-25,2004-03-16
-1sp4,2004-05-04,2004-03-16
-7spd,2022-06-08,2021-11-02
-6spl,2019-10-02,2019-09-01
-5spo,2022-07-13,2022-06-09
-6spx,2020-01-29,2019-09-03
-1spe,1996-03-08,1995-10-25
-8spl,2023-08-09,2023-05-03
-3spf,2012-06-27,2011-07-01
-5sps,2022-07-13,2022-06-09
-5spp,2022-07-13,2022-06-09
-8spd,2023-10-11,2023-05-02
-5spu,2022-07-13,2022-06-09
-1spg,1997-03-12,1996-02-05
-1sp8,2004-09-21,2004-03-16
-6spa,2020-03-18,2019-08-31
-5sp9,2022-07-13,2022-06-09
-8spx,2024-01-24,2023-05-03
-8sph,2023-08-02,2023-05-03
-5spy,2022-07-06,2022-06-09
-6spy,2020-09-30,2019-09-03
-6spk,2020-03-18,2019-09-01
-3spg,2011-08-24,2011-07-01
-5spw,2022-07-13,2022-06-09
-8spi,2023-08-02,2023-05-03
-3spx,2012-07-04,2011-07-04
-7spz,2022-07-20,2021-11-04
-8sp0,2023-08-23,2023-05-01
-5sp3,2022-07-13,2022-06-09
-7spm,2021-11-10,2021-11-02
-6spi,2020-03-18,2019-09-01
-3sp4,2011-10-12,2011-07-01
-5sp1,2022-07-13,2022-06-09
-3spt,2012-08-08,2011-07-03
-6spu,2020-09-30,2019-09-02
-2spn,1994-01-31,1993-08-25
-6spz,2019-10-02,2019-09-03
-3sph,2011-08-24,2011-07-01
-6sp9,2019-10-02,2019-08-31
-5spr,2022-07-13,2022-06-09
-7spt,2022-05-18,2021-11-03
-3spy,2011-10-12,2011-07-04
-7sps,2022-05-18,2021-11-03
-8sp8,2023-08-23,2023-05-02
-5spq,2022-07-13,2022-06-09
-6sp0,2020-07-01,2019-08-30
-7spw,2022-05-11,2021-11-03
-8spp,2023-08-23,2023-05-03
-5sp0,2022-07-13,2022-06-09
-7spe,2022-06-01,2021-11-02
-7spf,2022-06-01,2021-11-02
-7sp7,2022-04-06,2021-11-02
-6sp4,2020-06-03,2019-08-30
-5spn,2022-07-13,2022-06-09
-1spu,1997-03-12,1996-11-13
-7spp,2022-01-05,2021-11-02
-7sph,2022-06-01,2021-11-02
-7spr,2023-05-10,2021-11-03
-3spk,2011-10-12,2011-07-01
-5sp7,2022-07-13,2022-06-09
-2spl,1994-01-31,1993-08-25
-5spv,2022-07-13,2022-06-09
-5spx,2022-07-06,2022-06-09
-5spi,2022-07-13,2022-06-09
-7spq,2023-05-10,2021-11-03
-6sph,2020-03-18,2019-09-01
-8spo,2023-08-23,2023-05-03
-7sp9,2022-04-06,2021-11-02
-1spa,1993-10-31,1993-01-26
-3spr,2012-07-04,2011-07-03
-6spo,2020-01-01,2019-09-02
-1sp1,1997-04-21,1996-11-21
-7sp2,2022-11-09,2021-11-02
-5spd,2022-07-13,2022-06-09
-6spj,2020-03-18,2019-09-01
-6sp7,2020-01-22,2019-08-31
-1spd,1994-04-30,1993-07-21
-8spn,2024-05-01,2023-05-03
-7sp6,2022-04-06,2021-11-02
-3spd,2011-10-12,2011-07-01
-8spe,2023-12-27,2023-05-03
-5spk,2022-07-13,2022-06-09
-3spz,2011-10-12,2011-07-04
-6sp2,2020-01-01,2019-08-30
-8sp2,2024-03-06,2023-05-01
-7spy,2022-07-20,2021-11-04
-5spl,2022-07-13,2022-06-09
-6spm,2020-09-30,2019-09-02
-6spg,2019-10-16,2019-09-01
-2spo,1994-01-31,1993-08-25
-8spq,2024-05-01,2023-05-03
-3spu,2011-08-03,2011-07-03
-6sp6,2020-01-22,2019-08-31
-8spm,2024-04-10,2023-05-03
-5sph,2022-07-13,2022-06-09
-6sp8,2020-11-18,2019-08-31
-7spx,2022-05-11,2021-11-03
-7spv,2022-05-11,2021-11-03
-2spt,1994-05-31,1994-02-01
-6spw,2020-01-29,2019-09-03
-7sp0,2022-10-12,2021-11-01
-3spv,2012-07-04,2011-07-04
-8sp3,2023-08-23,2023-05-01
-6sp3,2020-09-09,2019-08-30
-5spb,2022-07-13,2022-06-09
-4d4k,2016-01-20,2014-10-29
-3d4g,2008-12-02,2008-05-14
-3d4x,2009-05-19,2008-05-15
-8d4a,2023-01-18,2022-06-01
-1d4s,1999-10-12,1999-10-05
-8d4x,2023-04-19,2022-06-02
-6d49,2019-04-17,2018-04-17
-6d4e,2019-05-01,2018-04-18
-3d4b,2008-09-30,2008-05-14
-1d4y,1999-10-13,1999-10-06
-2d4q,2006-03-07,2005-10-22
-4d4m,2016-01-20,2014-10-29
-4d4z,2015-04-15,2014-10-31
-2d4c,2006-07-11,2005-10-13
-5d40,2016-06-22,2015-08-06
-7d41,2022-03-23,2020-09-21
-4d4n,2015-09-09,2014-10-30
-6d4b,2019-04-24,2018-04-17
-4d44,2015-03-04,2014-10-26
-4d4c,2015-03-25,2014-10-27
-8d4z,2023-09-20,2022-06-03
-6d4i,2019-05-01,2018-04-18
-8d4u,2022-12-21,2022-06-02
-1d4p,1999-10-20,1999-10-04
-5d41,2016-06-08,2015-08-07
-5d4h,2016-03-09,2015-08-07
-2d43,2006-09-19,2005-10-07
-1d4u,1999-10-17,1999-10-06
-4d40,2015-04-29,2014-10-24
-3d42,2009-03-17,2008-05-13
-8d4f,2023-06-14,2022-06-01
-5d46,2016-07-27,2015-08-07
-5d4b,2016-07-27,2015-08-07
-3d45,2009-03-17,2008-05-13
-3d4s,2008-06-17,2008-05-14
-7d4k,2021-09-15,2020-09-24
-3d4u,2008-08-19,2008-05-15
-4d49,2016-01-13,2014-10-27
-8d4d,2023-06-14,2022-06-01
-3d4f,2009-02-10,2008-05-14
-7d4r,2021-10-06,2020-09-24
-6d4u,2019-05-01,2018-04-18
-7d4m,2021-09-15,2020-09-24
-7d47,2020-10-07,2020-09-22
-7d4p,2021-03-31,2020-09-24
-8d48,2023-01-25,2022-06-01
-5d47,2016-06-22,2015-08-07
-5d4v,2016-07-20,2015-08-09
-6d4c,2019-04-24,2018-04-17
-1d4f,2001-01-17,2000-06-22
-7d4f,2020-11-11,2020-09-23
-1d4m,1999-12-23,1999-10-04
-6d4q,2019-05-01,2018-04-18
-5d4k,2016-03-16,2015-08-07
-5d43,2016-09-07,2015-08-07
-8d4q,2022-12-21,2022-06-02
-3d47,2008-06-03,2008-05-14
-3d4c,2008-12-02,2008-05-14
-7d4l,2021-06-09,2020-09-24
-2d4v,2006-11-14,2005-10-24
-6d4w,2019-05-01,2018-04-18
-3d4l,2008-07-01,2008-05-14
-5d42,2016-03-16,2015-08-07
-8d4k,2022-07-13,2022-06-02
-3d44,2009-03-17,2008-05-13
-3d4n,2008-07-22,2008-05-14
-3d4z,2008-08-05,2008-05-15
-5d4u,2016-07-20,2015-08-09
-5d4f,2016-09-07,2015-08-07
-2d40,2006-09-26,2005-10-05
-3d4y,2008-08-05,2008-05-15
-3d43,2009-04-28,2008-05-13
-4d46,2015-03-04,2014-10-26
-1d4n,2000-03-01,1999-10-04
-5d4i,2016-03-09,2015-08-07
-6d4t,2019-05-01,2018-04-18
-4d42,2015-03-04,2014-10-26
-3d49,2009-04-14,2008-05-14
-7d4d,2021-02-10,2020-09-23
-8d4e,2023-06-14,2022-06-01
-5d4d,2016-07-06,2015-08-07
-5d4q,2016-02-10,2015-08-08
-7d4c,2021-02-10,2020-09-23
-1d4x,2001-05-02,1999-10-06
-6d4a,2019-04-17,2018-04-17
-1d4l,2000-10-11,1999-10-04
-4d4u,2015-03-11,2014-10-31
-4d45,2015-03-04,2014-10-26
-8d41,2022-07-06,2022-06-01
-4d4s,2015-02-18,2014-10-31
-7d4e,2021-02-10,2020-09-23
-7d4o,2021-03-17,2020-09-24
-4d4l,2016-01-20,2014-10-29
-4d4t,2015-03-04,2014-10-31
-1d4e,1999-12-01,1999-10-03
-4d4v,2015-02-18,2014-10-31
-4d4g,2015-07-01,2014-10-29
-5d4g,2016-03-23,2015-08-07
-5d4p,2016-09-28,2015-08-08
-4d41,2015-03-04,2014-10-26
-8d4g,2023-06-14,2022-06-01
-6d42,2018-07-11,2018-04-17
-8d4r,2023-12-13,2022-06-02
-5d4c,2016-07-06,2015-08-07
-4d4i,2015-07-01,2014-10-29
-4d47,2015-08-05,2014-10-27
-5d45,2016-06-22,2015-08-07
-7d4u,2021-03-17,2020-09-24
-2d4f,2006-08-08,2005-10-18
-7d4i,2021-10-06,2020-09-24
-4d4o,2015-01-14,2014-10-30
-6d4n,2019-05-01,2018-04-18
-1d4i,2002-06-26,1999-10-04
-3d4k,2009-03-03,2008-05-14
-6d4g,2018-09-12,2018-04-18
-2d4n,2006-11-21,2005-10-20
-1d4d,1999-12-01,1999-10-03
-8d4c,2023-06-14,2022-06-01
-3d4q,2008-08-19,2008-05-14
-4d4p,2015-01-14,2014-10-30
-3d41,2008-08-12,2008-05-13
-8d4o,2022-12-21,2022-06-02
-8d4s,2022-12-21,2022-06-02
-7d4n,2021-09-15,2020-09-24
-1d4a,1999-10-15,1999-10-01
-6d4o,2018-07-25,2018-04-18
-6d41,2018-10-17,2018-04-17
-4d4b,2015-03-25,2014-10-27
-4d4x,2015-09-09,2014-10-31
-2d4k,2006-07-11,2005-10-20
-3d4d,2008-11-04,2008-05-14
-4d4j,2016-01-20,2014-10-29
-2d4e,2006-04-18,2005-10-18
-8d4m,2022-07-13,2022-06-02
-1d4c,1999-12-01,1999-10-03
-2d41,2006-08-01,2005-10-05
-1d4o,2000-01-20,1999-10-04
-6d4r,2019-05-01,2018-04-18
-3d4a,2009-05-26,2008-05-14
-2d4i,2006-07-11,2005-10-20
-5d48,2016-06-22,2015-08-07
-2d44,2006-09-19,2005-10-07
-1d4h,2002-06-26,1999-10-04
-5d4y,2016-02-24,2015-08-10
-5d4o,2016-09-28,2015-08-08
-5d4a,2016-06-22,2015-08-07
-8d42,2023-05-24,2022-06-01
-7d42,2020-12-02,2020-09-22
-4d4d,2015-03-25,2014-10-27
-5d4e,2016-07-06,2015-08-07
-6d4v,2019-05-01,2018-04-18
-5d4n,2016-09-28,2015-08-08
-7d48,2021-03-17,2020-09-23
-1d4k,2000-10-11,1999-10-04
-5d49,2016-07-27,2015-08-07
-8d40,2023-08-30,2022-06-01
-8d4i,2022-11-16,2022-06-02
-2d4h,2006-03-07,2005-10-19
-3d46,2008-06-03,2008-05-14
-8d43,2022-11-16,2022-06-01
-4d43,2015-03-04,2014-10-26
-7d4x,2021-06-09,2020-09-24
-7d4q,2021-03-31,2020-09-24
-7d49,2021-06-09,2020-09-23
-6d4s,2019-05-01,2018-04-18
-8d4t,2022-07-06,2022-06-02
-5d4w,2016-12-07,2015-08-09
-7d4b,2021-07-14,2020-09-23
-6d45,2018-05-23,2018-04-17
-3d4p,2009-06-02,2008-05-14
-2d4d,2006-08-08,2005-10-17
-8d4p,2023-06-07,2022-06-02
-6d4k,2019-02-27,2018-04-18
-1d4j,2002-06-26,1999-10-04
-7d4j,2021-03-17,2020-09-24
-7d4s,2021-03-17,2020-09-24
-6d4m,2019-05-01,2018-04-18
-5d4j,2016-03-09,2015-08-07
-2wv3,2009-12-15,2009-10-13
-6wvl,2020-05-20,2020-05-06
-4wvx,2015-11-11,2014-11-07
-3wvn,2014-10-01,2014-05-30
-4wvo,2015-02-11,2014-11-06
-7wvw,2022-04-13,2022-02-11
-5wvz,2017-04-26,2016-12-30
-7wvv,2022-04-13,2022-02-11
-3wvc,2015-04-29,2014-05-16
-1wvj,2005-04-26,2004-12-15
-5wvx,2018-06-13,2016-12-29
-6wv6,2020-11-11,2020-05-05
-6wvm,2020-05-20,2020-05-06
-6wvq,2021-02-17,2020-05-06
-3wv6,2015-05-20,2014-05-16
-4wvv,2015-09-23,2014-11-07
-3wvw,2015-07-15,2014-06-09
-6wvz,2021-04-28,2020-05-07
-8wvb,2023-12-13,2023-10-23
-5wv1,2017-01-25,2016-12-21
-7wv9,2022-06-15,2022-02-10
-1wvx,2006-04-11,2004-12-27
-6wv4,2020-11-11,2020-05-05
-1wv4,2004-12-28,2004-12-11
-4wvi,2015-09-23,2014-11-05
-1wvp,2005-01-18,2004-12-23
-3wvh,2015-04-08,2014-05-21
-7wvs,2023-02-15,2022-02-11
-3wv3,2014-09-24,2014-05-12
-4wv9,2015-04-22,2014-11-04
-4wv7,2015-01-14,2014-11-04
-8wve,2023-12-27,2023-10-23
-4wvp,2015-02-11,2014-11-06
-1wv1,2005-12-10,2004-12-10
-4wv3,2015-11-11,2014-11-04
-5wvr,2017-05-10,2016-12-28
-1wvg,2005-01-26,2004-12-15
-3wve,2015-06-17,2014-05-17
-6wvo,2021-03-31,2020-05-06
-6wv7,2020-11-11,2020-05-05
-5wv4,2017-12-27,2016-12-22
-2wvg,2010-02-09,2009-10-16
-3wv8,2015-04-29,2014-05-16
-6wvh,2020-11-11,2020-05-06
-5wvg,2017-12-27,2016-12-24
-4wvw,2015-09-23,2014-11-07
-4wv8,2016-01-27,2014-11-04
-3wvs,2014-10-01,2014-06-06
-3wv7,2015-04-29,2014-05-16
-4wvg,2015-09-23,2014-11-05
-7wv3,2022-11-16,2022-02-09
-2wva,2010-02-09,2009-10-15
-3wvi,2015-04-08,2014-05-21
-5wve,2017-02-08,2016-12-24
-7wvg,2023-01-18,2022-02-10
-2wvs,2010-02-02,2009-10-20
-5wvb,2017-12-27,2016-12-23
-8wv8,2023-12-27,2023-10-23
-3wv1,2015-05-20,2014-05-12
-6wvv,2020-12-16,2020-05-07
-3wvp,2015-04-08,2014-06-02
-3wvg,2015-04-08,2014-05-21
-4wvl,2014-12-03,2014-11-06
-6wvp,2021-02-17,2020-05-06
-4wvc,2015-03-11,2014-11-05
-2wv2,2009-11-10,2009-10-12
-1wv7,2005-12-11,2004-12-11
-3wvy,2015-06-10,2014-06-11
-1wva,2005-09-06,2004-12-14
-2wvz,2009-12-29,2009-10-21
-4wvu,2015-03-04,2014-11-07
-6wvj,2020-11-18,2020-05-06
-3wv5,2014-10-01,2014-05-15
-7wvu,2022-04-13,2022-02-11
-1wve,2005-03-08,2004-12-15
-2wvl,2010-03-31,2009-10-19
-3wvk,2015-04-08,2014-05-22
-5wvw,2017-04-26,2016-12-29
-6wv5,2020-11-11,2020-05-05
-6wvn,2020-05-13,2020-05-06
-2wvi,2010-03-09,2009-10-16
-5wvu,2017-02-22,2016-12-29
-5wv3,2017-02-15,2016-12-21
-4wvt,2015-03-04,2014-11-07
-3wv9,2015-04-29,2014-05-16
-3wvr,2014-11-19,2014-06-04
-3wv0,2014-06-11,2014-05-10
-6wvw,2021-03-17,2020-05-07
-7wvd,2023-01-18,2022-02-10
-5wvf,2017-12-27,2016-12-24
-3wvv,2015-07-15,2014-06-09
-4wvz,2016-02-24,2014-11-09
-1wvy,2006-04-11,2004-12-27
-2wvu,2010-02-02,2009-10-20
-5wvh,2017-12-27,2016-12-24
-2wv7,2010-09-08,2009-10-15
-2wvt,2010-02-02,2009-10-20
-6wvk,2020-11-18,2020-05-06
-1wvm,2006-03-21,2004-12-16
-4wvh,2015-09-23,2014-11-05
-6wvg,2020-09-16,2020-05-06
-5wv9,2017-12-27,2016-12-23
-7wva,2022-09-07,2022-02-10
-6wv3,2020-11-11,2020-05-05
-3wv2,2014-09-24,2014-05-12
-6wvt,2020-10-07,2020-05-06
-4wvf,2015-07-15,2014-11-05
-3wvd,2015-06-17,2014-05-17
-4wv6,2015-01-28,2014-11-04
-6wvr,2020-05-20,2020-05-06
-1wvr,2005-07-05,2004-12-24
-6wv1,2021-02-17,2020-05-05
-3wvu,2015-07-15,2014-06-09
-2wvf,2010-01-19,2009-10-16
-7wvk,2022-10-19,2022-02-10
-1wvf,2005-03-08,2004-12-15
-1wvb,2005-09-06,2004-12-14
-6wv2,2021-05-12,2020-05-05
-4wvd,2015-02-11,2014-11-05
-4wvb,2015-03-11,2014-11-05
-1wvc,2005-01-11,2004-12-14
-5wvp,2018-01-31,2016-12-28
-2wvk,2010-03-31,2009-10-19
-6wvx,2021-09-01,2020-05-07
-8wvf,2023-12-13,2023-10-23
-5wvd,2018-01-03,2016-12-24
-6wvb,2020-11-11,2020-05-05
-6wv8,2020-11-11,2020-05-05
-3wvl,2014-09-17,2014-05-23
-2wvj,2009-10-27,2009-10-17
-4wvj,2015-09-23,2014-11-05
-5wvy,2017-04-26,2016-12-29
-7wv5,2022-11-16,2022-02-09
-6wvc,2021-02-17,2020-05-05
-4wvy,2015-02-18,2014-11-08
-1wv0,2005-12-10,2004-12-10
-6wvf,2021-01-13,2020-05-05
-2wvp,2010-07-14,2009-10-19
-2wvm,2010-03-31,2009-10-19
-5wvo,2017-11-15,2016-12-28
-2wv8,2010-08-25,2009-10-15
-2wvx,2009-11-03,2009-10-21
-2m1r,2012-12-26,2012-12-05
-5m1a,2017-02-08,2016-10-07
-1m1n,2002-09-11,2002-06-19
-3m1n,2010-03-16,2010-03-05
-3m13,2010-04-21,2010-03-04
-7m1h,2021-12-22,2021-03-13
-6m18,2020-03-11,2020-02-25
-3m1o,2010-11-17,2010-03-05
-4m1w,2013-11-27,2013-08-04
-6m16,2020-05-27,2020-02-24
-1m1b,2002-08-28,2002-06-18
-6m1b,2021-01-06,2020-02-25
-1m1a,2003-02-18,2002-06-18
-5m1q,2016-10-26,2016-10-09
-4m1k,2014-08-06,2013-08-02
-7m1i,2022-08-17,2021-03-13
-4m17,2013-12-04,2013-08-02
-3m14,2011-05-25,2010-03-04
-6m1y,2020-11-04,2020-02-26
-5m11,2016-11-09,2016-10-07
-3m1k,2010-11-17,2010-03-05
-3m1q,2011-05-25,2010-03-05
-7m10,2021-05-26,2021-03-11
-4m1p,2014-05-21,2013-08-03
-1m19,2003-02-18,2002-06-18
-1m1p,2002-08-14,2002-06-20
-5m19,2017-02-08,2016-10-07
-4m1t,2013-11-27,2013-08-04
-6m11,2020-09-02,2020-02-24
-5m1p,2016-10-26,2016-10-09
-4m15,2014-04-02,2013-08-02
-3m1e,2011-04-27,2010-03-04
-3m1i,2010-06-02,2010-03-05
-6m1t,2020-04-08,2020-02-26
-7m1p,2021-09-08,2021-03-14
-7m1j,2022-08-31,2021-03-13
-4m19,2015-01-14,2013-08-02
-7m1q,2021-09-08,2021-03-14
-5m1k,2016-10-26,2016-10-09
-3m1r,2010-03-16,2010-03-05
-4m1y,2013-11-27,2013-08-04
-4m1s,2013-11-27,2013-08-04
-4m14,2014-04-02,2013-08-02
-3m1m,2010-06-16,2010-03-05
-4m11,2014-01-22,2013-08-02
-4m1u,2013-11-20,2013-08-04
-1m1r,2002-08-14,2002-06-20
-5m10,2016-12-07,2016-10-06
-7m1t,2021-06-16,2021-03-15
-5m1m,2017-02-08,2016-10-09
-6m1k,2021-03-10,2020-02-26
-5m16,2016-11-09,2016-10-07
-5m12,2016-11-09,2016-10-07
-2m1s,2013-01-30,2012-12-06
-5m17,2017-01-11,2016-10-07
-1m1q,2002-08-14,2002-06-20
-1m1o,2002-11-29,2002-06-20
-5m1j,2017-01-18,2016-10-07
-1m1d,2002-10-30,2002-06-18
-5m1y,2016-10-26,2016-10-11
-3m1d,2010-05-26,2010-03-04
-5m1i,2016-11-09,2016-10-07
-7m11,2022-03-16,2021-03-11
-3m12,2010-04-21,2010-03-04
-1m18,2003-02-18,2002-06-18
-5m1e,2017-01-11,2016-10-07
-4m1i,2013-08-21,2013-08-02
-1m15,2002-12-04,2002-06-17
-2m10,2013-07-03,2012-11-09
-5m1d,2017-01-11,2016-10-07
-3m1h,2011-03-23,2010-03-05
-7m15,2021-03-24,2021-03-12
-3m1c,2010-07-07,2010-03-04
-1m1u,2002-08-07,2002-06-20
-4m1o,2013-11-27,2013-08-03
-4m1c,2014-08-06,2013-08-02
-7m1k,2022-08-31,2021-03-13
-5m1r,2017-12-20,2016-10-10
-7m1y,2021-03-24,2021-03-15
-1m1k,2002-07-19,2002-06-19
-6m17,2020-03-11,2020-02-24
-6m1j,2020-09-02,2020-02-26
-5m18,2017-02-08,2016-10-07
-2m13,2013-04-03,2012-11-14
-7m1v,2021-04-21,2021-03-15
-3m1z,2010-06-16,2010-03-06
-4m1n,2013-08-21,2013-08-03
-1m17,2002-09-04,2002-06-17
-1m13,2003-03-04,2002-06-17
-5m1n,2016-10-26,2016-10-09
-5m1z,2016-12-28,2016-10-11
-7m1z,2022-09-21,2021-03-15
-7m18,2021-09-08,2021-03-12
-7m16,2021-09-29,2021-03-12
-7m14,2021-03-24,2021-03-12
-3m1v,2010-09-15,2010-03-05
-1m1x,2002-08-14,2002-06-20
-6m15,2020-05-27,2020-02-24
-6m1w,2021-01-06,2020-02-26
-7m17,2021-03-24,2021-03-12
-7m13,2021-03-24,2021-03-12
-3m1w,2011-05-25,2010-03-05
-5m1t,2017-03-01,2016-10-10
-4m1j,2013-08-28,2013-08-02
-5m1o,2016-10-26,2016-10-09
-4m13,2014-04-02,2013-08-02
-7m19,2021-03-24,2021-03-12
-6m1c,2021-06-02,2020-02-25
-3m1y,2010-03-23,2010-03-05
-6m1s,2020-09-02,2020-02-26
-1m1j,2002-06-26,2002-06-19
-6m12,2020-09-02,2020-02-24
-4m1l,2014-05-07,2013-08-03
-4m18,2013-12-04,2013-08-02
-3m15,2011-01-12,2010-03-04
-3m11,2011-03-09,2010-03-03
-7m1a,2021-04-21,2021-03-12
-1m1y,2003-02-11,2002-06-20
-4m12,2014-04-02,2013-08-02
-4m1e,2013-08-21,2013-08-02
-3m1s,2010-12-22,2010-03-05
-3m1a,2010-03-23,2010-03-04
-4m10,2014-01-22,2013-08-02
-3m1j,2011-01-19,2010-03-05
-4m1m,2013-11-13,2013-08-03
-6m13,2020-09-02,2020-02-24
-3m1f,2010-09-15,2010-03-04
-4x44,2015-12-02,2014-12-02
-2x41,2010-02-09,2010-01-28
-4x4b,2015-03-11,2014-12-02
-5x4q,2017-05-24,2017-02-13
-4x4l,2015-02-11,2014-12-03
-6x4n,2020-06-24,2020-05-22
-5x4a,2017-09-20,2017-02-11
-5x45,2018-02-21,2017-02-10
-7x4q,2023-03-08,2022-03-03
-3x40,2015-08-19,2015-03-10
-7x48,2023-03-08,2022-03-02
-1x4w,2005-11-15,2005-05-15
-5x4r,2017-05-03,2017-02-14
-6x4h,2020-08-12,2020-05-22
-2x4q,2010-03-02,2010-02-02
-2x42,2010-02-09,2010-01-28
-7x4y,2023-04-05,2022-03-03
-5x4h,2018-02-14,2017-02-13
-2x4s,2010-03-02,2010-02-02
-5x42,2017-06-14,2017-02-09
-1x4k,2005-11-14,2005-05-14
-3x44,2015-07-29,2015-03-13
-5x4p,2017-05-24,2017-02-13
-6x4d,2020-07-22,2020-05-22
-7x4w,2023-03-08,2022-03-03
-2x4f,2010-02-09,2010-01-29
-7x4n,2022-09-21,2022-03-03
-6x42,2020-10-07,2020-05-21
-4x4v,2015-02-11,2014-12-03
-7x4h,2023-01-18,2022-03-02
-1x4v,2005-11-15,2005-05-15
-6x4m,2020-06-24,2020-05-22
-6x4f,2020-07-22,2020-05-22
-6x4t,2020-10-14,2020-05-23
-2x4n,2010-03-02,2010-02-02
-7x4g,2023-03-08,2022-03-02
-6x4b,2020-07-22,2020-05-22
-3x43,2015-07-29,2015-03-13
-4x4k,2015-12-09,2014-12-03
-4x47,2015-07-22,2014-12-02
-2x49,2010-03-31,2010-01-28
-5x4i,2018-02-14,2017-02-13
-5x4k,2018-02-14,2017-02-13
-4x41,2015-11-18,2014-12-02
-5x4t,2017-07-26,2017-02-14
-4x4q,2015-02-11,2014-12-03
-6x4c,2020-07-22,2020-05-22
-6x46,2021-03-03,2020-05-22
-2x4r,2010-03-02,2010-02-02
-5x4j,2018-02-14,2017-02-13
-5x40,2017-04-05,2017-02-09
-4x4m,2015-04-08,2014-12-03
-6x4k,2021-11-24,2020-05-22
-7x4u,2023-03-08,2022-03-03
-6x4y,2021-02-03,2020-05-24
-4x4r,2015-02-11,2014-12-03
-5x4v,2017-07-26,2017-02-14
-7x4l,2023-05-03,2022-03-02
-6x47,2020-07-22,2020-05-22
-2x4u,2010-03-02,2010-02-02
-5x4n,2017-05-24,2017-02-13
-6x4p,2020-06-24,2020-05-22
-8x43,2024-01-17,2023-11-15
-2x4p,2010-03-02,2010-02-02
-4x4j,2015-12-02,2014-12-02
-4x4o,2015-02-11,2014-12-03
-5x4m,2017-05-24,2017-02-13
-5x49,2017-05-17,2017-02-10
-2x4t,2010-03-02,2010-02-02
-6x4g,2020-10-14,2020-05-22
-5x4z,2017-05-17,2017-02-14
-1x4j,2005-11-14,2005-05-14
-6x40,2020-09-09,2020-05-21
-2x4k,2010-07-21,2010-02-01
-6x49,2020-07-22,2020-05-22
-3x41,2015-08-19,2015-03-10
-4x4t,2015-02-11,2014-12-03
-6x4i,2020-06-03,2020-05-22
-4x4s,2015-02-11,2014-12-03
-1x4i,2005-11-14,2005-05-14
-2x4z,2010-05-19,2010-02-03
-6x4q,2020-06-24,2020-05-22
-4x45,2015-12-02,2014-12-02
-1x4s,2005-11-14,2005-05-14
-6x4a,2020-07-22,2020-05-22
-3x42,2015-08-19,2015-03-10
-1x4l,2005-11-14,2005-05-14
-7x4t,2023-03-08,2022-03-03
-4x4n,2015-02-11,2014-12-03
-6x4s,2020-09-02,2020-05-22
-4x48,2015-05-06,2014-12-02
-4x4u,2015-02-11,2014-12-03
-1x4u,2005-11-15,2005-05-15
-1x46,2005-05-24,2005-05-14
-6x4j,2021-11-24,2020-05-22
-7x4p,2023-03-08,2022-03-03
-5x4u,2017-07-26,2017-02-14
-2x45,2011-02-09,2010-01-28
-6x4o,2020-06-24,2020-05-22
-6x4e,2020-07-22,2020-05-22
-6x48,2020-08-12,2020-05-22
-6x4l,2021-11-24,2020-05-22
-2x4o,2010-03-02,2010-02-02
-5x4s,2017-05-03,2017-02-14
-7x4x,2023-03-08,2022-03-03
-5x4o,2017-05-24,2017-02-13
-2x4h,2010-07-21,2010-01-31
-5x4b,2017-05-31,2017-02-11
-2x4d,2010-03-16,2010-01-29
-4x4a,2015-07-22,2014-12-02
-6x43,2021-02-03,2020-05-22
-6x4w,2021-02-03,2020-05-24
-4x49,2015-07-22,2014-12-02
-3ogm,2010-10-13,2010-08-17
-6ogo,2020-04-15,2019-04-03
-7ogb,2022-02-09,2021-05-06
-6ogh,2019-04-24,2019-04-02
-5og6,2018-05-23,2017-07-11
-7ogz,2022-02-16,2021-05-07
-1ogk,2004-01-22,2003-05-07
-3og6,2010-10-20,2010-08-16
-4ogc,2014-02-12,2014-01-15
-7ogc,2022-02-09,2021-05-06
-5ogh,2018-08-01,2017-07-13
-1og3,2003-08-28,2003-04-24
-3ogd,2010-09-15,2010-08-16
-7ogd,2022-02-09,2021-05-06
-8ogc,2023-06-14,2023-03-19
-2og7,2007-03-06,2007-01-05
-5ogq,2018-11-21,2017-07-13
-3ogv,2011-03-16,2010-08-17
-8ogt,2024-03-27,2023-03-20
-3ogc,2011-03-16,2010-08-16
-8ogb,2023-06-14,2023-03-19
-7og9,2022-02-09,2021-05-06
-1og4,2003-08-28,2003-04-24
-1ogq,2003-07-24,2003-05-08
-2ogi,2007-01-16,2007-01-05
-4og7,2014-03-05,2014-01-15
-3ogl,2010-10-13,2010-08-17
-7og4,2021-06-23,2021-05-06
-3ogu,2010-11-24,2010-08-17
-7og3,2021-10-06,2021-05-06
-1og5,2003-07-17,2003-04-24
-5ogb,2018-10-24,2017-07-12
-5ogc,2017-10-25,2017-07-12
-3ogn,2010-11-03,2010-08-17
-3ogs,2011-03-16,2010-08-17
-8og9,2023-06-14,2023-03-19
-7ogf,2022-02-09,2021-05-06
-8ogq,2024-03-27,2023-03-20
-5ogf,2018-05-23,2017-07-13
-3ogb,2010-09-08,2010-08-16
-1og1,2003-08-28,2003-04-23
-8ogv,2024-03-27,2023-03-20
-4oge,2014-02-12,2014-01-15
-6ogr,2020-04-08,2019-04-03
-3ogk,2010-10-13,2010-08-16
-1ogx,2003-05-20,2003-05-17
-2ogf,2007-01-16,2007-01-05
-6ogx,2019-07-10,2019-04-03
-8ogz,2024-03-27,2023-03-20
-4ogk,2015-03-04,2014-01-16
-7oga,2022-02-09,2021-05-06
-5og9,2018-08-01,2017-07-12
-1oga,2003-06-19,2003-04-28
-5ogo,2018-08-01,2017-07-13
-5ogj,2018-08-01,2017-07-13
-1ogz,2003-09-04,2003-05-20
-5ogg,2018-05-23,2017-07-13
-6oge,2019-05-15,2019-04-02
-3og2,2011-03-16,2010-08-16
-1ogj,2003-09-25,2003-05-06
-2ogy,2007-01-23,2007-01-09
-5ogw,2017-09-27,2017-07-13
-7ogi,2022-06-01,2021-05-06
-7ogj,2021-05-19,2021-05-06
-1og6,2003-05-29,2003-04-24
-1oge,2003-09-01,2003-04-30
-7ogr,2021-07-07,2021-05-07
-5og3,2018-05-23,2017-07-11
-1ogo,2003-09-11,2003-05-08
-4og2,2014-01-29,2014-01-15
-3ogh,2010-09-15,2010-08-16
-8ogn,2024-03-27,2023-03-20
-8ogu,2024-03-27,2023-03-20
-2og5,2007-03-06,2007-01-05
-1ogd,2003-09-01,2003-04-30
-3ogx,2010-09-01,2010-08-17
-1og0,2004-04-30,2003-04-22
-7ogq,2022-02-16,2021-05-07
-8ogf,2024-03-27,2023-03-20
-5ogx,2018-07-04,2017-07-13
-1ogg,2004-04-27,2003-04-30
-2og6,2007-03-06,2007-01-05
-4og8,2014-03-05,2014-01-15
-7ogp,2021-07-07,2021-05-07
-8ogo,2024-03-27,2023-03-20
-5ogr,2018-11-21,2017-07-13
-3ogj,2011-05-11,2010-08-16
-8ogp,2024-03-27,2023-03-20
-8og0,2024-03-27,2023-03-17
-5ogl,2017-10-25,2017-07-13
-4ogm,2015-01-14,2014-01-16
-8ogw,2024-03-27,2023-03-20
-7og1,2022-06-01,2021-05-05
-6ogt,2020-04-08,2019-04-03
-5og1,2017-08-16,2017-07-11
-7og2,2021-11-10,2021-05-06
-3og4,2010-10-20,2010-08-16
-1ogp,2003-10-09,2003-05-08
-5og5,2018-05-23,2017-07-11
-2ogx,2007-04-24,2007-01-09
-3og7,2010-09-22,2010-08-16
-8ogs,2024-03-27,2023-03-20
-5ogk,2017-11-22,2017-07-13
-7oge,2022-02-09,2021-05-06
-8ogg,2023-08-30,2023-03-20
-5og2,2018-05-23,2017-07-11
-2oge,2007-05-15,2007-01-05
-2og9,2007-02-27,2007-01-05
-8ogy,2024-03-27,2023-03-20
-2oga,2007-05-15,2007-01-05
-5ogt,2018-08-01,2017-07-13
-1ogs,2003-07-03,2003-05-13
-3ogt,2011-08-17,2010-08-17
-8og7,2023-06-14,2023-03-19
-7og0,2021-10-27,2021-05-05
-4ogn,2014-04-02,2014-01-16
-1ogu,2003-09-02,2003-05-13
-1og2,2003-07-17,2003-04-23
-3og8,2010-11-03,2010-08-16
-1ogv,2003-08-05,2003-05-13
-1ogy,2003-10-09,2003-05-19
-3ogp,2011-06-08,2010-08-17
-7ogk,2021-07-07,2021-05-06
-4ogj,2014-02-26,2014-01-16
-7og6,2021-06-23,2021-05-06
-4ogq,2014-05-14,2014-01-16
-2og2,2007-12-11,2007-01-04
-5og4,2018-05-23,2017-07-11
-2og8,2007-02-27,2007-01-05
-1ogi,2003-09-25,2003-05-06
-8ogh,2023-05-10,2023-03-20
-4og5,2014-03-05,2014-01-15
-8og2,2024-04-03,2023-03-17
-6ogl,2020-04-08,2019-04-02
-8og1,2023-07-12,2023-03-17
-6og0,2019-04-17,2019-04-01
-4ogv,2014-04-02,2014-01-16
-4ogl,2015-03-04,2014-01-16
-8ogr,2024-03-27,2023-03-20
-4oga,2014-08-27,2014-01-15
-4og3,2014-03-05,2014-01-15
-1ogt,2004-01-29,2003-05-13
-2ogj,2007-02-20,2007-01-05
-6ogq,2020-04-08,2019-04-03
-4ogh,2014-08-20,2014-01-16
-8ogk,2024-03-27,2023-03-20
-7ogn,2022-04-06,2021-05-07
-6ogk,2019-05-01,2019-04-02
-6og1,2019-06-12,2019-04-01
-8og4,2023-07-12,2023-03-18
-7ogo,2022-02-16,2021-05-07
-6ogn,2019-04-17,2019-04-03
-7og7,2021-07-07,2021-05-06
-4og6,2014-03-05,2014-01-15
-3ogr,2011-03-16,2010-08-17
-4ogu,2015-01-21,2014-01-16
-6ogs,2020-04-08,2019-04-03
-8ogx,2024-01-10,2023-03-20
-8og5,2023-06-14,2023-03-19
-8oga,2023-06-14,2023-03-19
-8og8,2023-06-14,2023-03-19
-2ogz,2007-03-06,2007-01-09
-6ogy,2019-05-22,2019-04-03
-4ogt,2014-04-02,2014-01-16
-2ogg,2007-02-06,2007-01-05
-8oge,2024-02-07,2023-03-20
-4ogw,2014-10-08,2014-01-16
-8ogd,2024-02-07,2023-03-20
-4ogb,2015-01-21,2014-01-15
-8og3,2023-04-19,2023-03-17
-7ogu,2022-02-16,2021-05-07
-5og7,2018-08-08,2017-07-12
-4ogr,2014-05-07,2014-01-16
-3ogq,2011-06-08,2010-08-17
-8og6,2023-06-14,2023-03-19
-2ogw,2007-03-06,2007-01-09
-6ogz,2019-05-22,2019-04-03
-4og4,2014-03-05,2014-01-15
-5og0,2017-09-27,2017-07-11
-7ogy,2021-07-28,2021-05-07
-4ogi,2014-02-26,2014-01-16
-6ogp,2020-04-08,2019-04-03
-6og2,2019-06-12,2019-04-01
-2ogd,2007-10-02,2007-01-05
-7lov,2021-11-17,2021-02-10
-1loy,2002-08-21,2002-05-07
-6loy,2020-11-18,2020-01-07
-3loo,2011-02-02,2010-02-04
-2lo2,2012-01-25,2012-01-10
-5lok,2017-08-23,2016-08-09
-4loy,2014-06-04,2013-07-14
-6lob,2021-01-06,2020-01-04
-6lox,2021-01-13,2020-01-07
-3lon,2011-01-19,2010-02-04
-6lod,2020-11-04,2020-01-05
-4lo9,2013-07-31,2013-07-12
-4lox,2014-09-24,2013-07-14
-7lop,2021-03-03,2021-02-10
-4loh,2013-08-14,2013-07-12
-7lor,2022-02-23,2021-02-10
-6loz,2020-11-18,2020-01-07
-1loo,2002-08-28,2002-05-06
-7log,2021-08-25,2021-02-10
-3loz,2010-12-08,2010-02-04
-5lom,2016-09-21,2016-08-09
-4loq,2013-08-21,2013-07-13
-1loe,1994-04-30,1993-01-27
-4loo,2013-08-21,2013-07-13
-7loe,2021-05-19,2021-02-10
-1lok,2002-11-27,2002-05-06
-1lom,2002-06-26,2002-05-06
-2lo4,2013-01-23,2012-01-12
-7lot,2021-02-24,2021-02-10
-1lo3,2002-07-03,2002-05-06
-1lo1,2003-04-22,2002-05-05
-7lo2,2021-03-31,2021-02-09
-1lo6,2002-05-15,2002-05-06
-3lo8,2010-03-16,2010-02-03
-3lox,2011-02-23,2010-02-04
-7lox,2021-05-12,2021-02-11
-7lo1,2022-04-27,2021-02-08
-1lo8,2002-05-17,2002-05-06
-5loa,2017-08-16,2016-08-09
-3lok,2010-12-22,2010-02-04
-1lon,2002-08-28,2002-05-06
-5lo0,2017-11-29,2016-08-08
-5low,2017-06-21,2016-08-10
-1lo0,2002-06-26,2002-05-05
-4lo2,2013-10-30,2013-07-12
-7lo4,2021-03-31,2021-02-09
-4lop,2013-08-21,2013-07-13
-7los,2021-02-24,2021-02-10
-7loa,2021-05-19,2021-02-09
-1lo7,2002-05-13,2002-05-06
-3lob,2010-04-21,2010-02-03
-5lop,2016-10-05,2016-08-09
-1lo2,2002-06-26,2002-05-06
-7loo,2021-09-15,2021-02-10
-3lov,2010-02-23,2010-02-04
-3lot,2010-02-23,2010-02-04
-4lo3,2013-10-30,2013-07-12
-5lof,2016-10-26,2016-08-09
-7lob,2021-05-19,2021-02-09
-4lom,2013-08-28,2013-07-13
-1lo9,2002-05-13,2002-05-06
-7low,2021-03-31,2021-02-10
-3lop,2010-02-23,2010-02-04
-3log,2011-02-09,2010-02-03
-5lo1,2017-11-29,2016-08-08
-4lo6,2013-10-30,2013-07-12
-1lox,1998-11-04,1997-10-06
-5lol,2017-06-07,2016-08-09
-7lo0,2022-02-16,2021-02-08
-4low,2013-09-11,2013-07-13
-5los,2018-05-02,2016-08-09
-7lom,2021-08-25,2021-02-10
-4loe,2013-07-31,2013-07-12
-4lof,2013-07-31,2013-07-12
-4lok,2013-08-14,2013-07-12
-4loc,2014-09-10,2013-07-12
-5loq,2016-10-26,2016-08-09
-6loq,2020-11-18,2020-01-07
-7loq,2022-02-23,2021-02-10
-3lo5,2010-03-02,2010-02-03
-5lo9,2016-10-12,2016-08-08
-7lon,2021-08-25,2021-02-10
-1lop,1996-12-23,1996-06-17
-7lou,2021-11-17,2021-02-10
-6loc,2021-01-06,2020-01-04
-3loc,2010-03-16,2010-02-03
-6lo9,2021-01-06,2020-01-04
-3loq,2010-02-16,2010-02-04
-7lol,2021-05-12,2021-02-10
-4lov,2014-02-12,2013-07-13
-3loj,2010-08-11,2010-02-04
-1loq,2002-08-07,2002-05-06
-4lor,2013-08-07,2013-07-13
-6lon,2020-06-24,2020-01-06
-6lo0,2020-05-27,2020-01-02
-1lo5,2002-12-18,2002-05-06
-6loe,2020-11-04,2020-01-05
-1lor,2002-08-07,2002-05-06
-1lol,2002-08-07,2002-05-06
-5lo6,2017-11-29,2016-08-08
-7loc,2021-05-19,2021-02-09
-4loj,2013-08-14,2013-07-12
-1lof,1994-04-30,1993-01-27
-7lo5,2021-03-17,2021-02-09
-1loa,1994-04-30,1993-01-27
-5log,2017-06-21,2016-08-09
-4los,2013-08-07,2013-07-13
-4lo1,2013-10-30,2013-07-12
-5loe,2017-01-11,2016-08-09
-6low,2020-11-18,2020-01-07
-1loc,1994-04-30,1993-01-27
-1loj,2003-03-25,2002-05-06
-7lo6,2021-04-14,2021-02-09
-6lop,2020-11-18,2020-01-07
-4lo5,2013-10-30,2013-07-12
-1lot,2002-07-31,2002-05-07
-1loh,2002-08-07,2002-05-06
-5lor,2017-08-16,2016-08-09
-6loo,2020-11-18,2020-01-07
-7lof,2021-05-19,2021-02-10
-7lok,2021-04-14,2021-02-10
-3lor,2010-03-16,2010-02-04
-5loh,2016-09-07,2016-08-09
-5lov,2016-11-30,2016-08-10
-1lod,1994-04-30,1993-01-27
-6loj,2020-12-23,2020-01-06
-7loz,2021-03-31,2021-02-11
-5lo8,2017-06-21,2016-08-08
-1los,2002-08-07,2002-05-06
-4lol,2013-08-21,2013-07-12
-5lot,2017-01-18,2016-08-09
-6lor,2020-11-18,2020-01-07
-7loj,2021-05-19,2021-02-10
-7lod,2021-05-19,2021-02-10
-6lo2,2021-07-07,2020-01-02
-1lov,2002-08-21,2002-05-07
-6lov,2020-11-18,2020-01-07
-4loi,2013-08-14,2013-07-12
-5lo5,2017-11-29,2016-08-08
-2lo3,2012-01-25,2012-01-10
-6loa,2021-01-06,2020-01-04
-2lob,2012-06-13,2012-01-20
-5lob,2017-06-21,2016-08-09
-3loy,2010-03-16,2010-02-04
-1log,1994-04-30,1994-01-27
-1low,2002-08-21,2002-05-07
-1lob,1994-04-30,1993-01-27
-8fuf,2023-08-09,2023-01-17
-3fua,1996-10-14,1996-02-14
-2fuc,2006-03-21,2006-01-26
-7fux,2023-03-29,2023-03-09
-4fui,2012-08-22,2012-06-28
-5fut,2016-09-21,2016-01-29
-3fur,2009-06-09,2009-01-14
-1fue,2002-02-06,2000-09-15
-6fug,2018-06-06,2018-02-27
-7fu8,2024-02-21,2023-02-08
-7fuu,2023-03-29,2023-03-09
-5fu2,2016-06-22,2016-01-20
-5fuv,2016-07-27,2016-01-31
-3fu0,2009-07-28,2009-01-13
-2fuu,2006-07-11,2006-01-27
-7fuz,2023-03-29,2023-03-09
-4fuj,2012-08-22,2012-06-28
-7fud,2024-02-21,2023-02-08
-4fum,2013-01-16,2012-06-28
-4fun,2013-01-16,2012-06-28
-8fu7,2023-04-05,2023-01-16
-5fuf,2016-05-04,2016-01-26
-1fui,1997-10-15,1997-04-14
-6fu4,2018-05-16,2018-02-26
-4fuu,2012-10-31,2012-06-28
-5fup,2016-03-23,2016-01-28
-7fuo,2024-02-21,2023-02-08
-2fu5,2006-04-04,2006-01-26
-4fu9,2012-08-22,2012-06-28
-8fu8,2023-04-05,2023-01-16
-8fum,2023-04-05,2023-01-17
-3ful,2010-01-05,2009-01-14
-1fub,2000-10-16,2000-09-14
-7fue,2024-02-21,2023-02-08
-4fu5,2013-07-17,2012-06-28
-1fu2,2000-10-16,2000-09-13
-3fud,2009-07-28,2009-01-14
-3fum,2009-07-28,2009-01-14
-7fu6,2024-02-21,2023-02-08
-6fu2,2018-10-24,2018-02-26
-2fu4,2006-05-16,2006-01-26
-6fuy,2018-03-14,2018-02-28
-5fuc,2017-01-25,2016-01-25
-5fuh,2017-02-22,2016-01-27
-6fua,2018-10-24,2018-02-26
-8fuw,2023-03-08,2023-01-18
-1fu8,2000-10-04,2000-09-14
-4fuo,2013-01-16,2012-06-28
-3fuh,2009-07-28,2009-01-14
-8fug,2023-06-07,2023-01-17
-8ful,2023-04-05,2023-01-17
-8fup,2024-02-07,2023-01-18
-6fuk,2018-10-10,2018-02-27
-8fuz,2023-04-19,2023-01-18
-2fuq,2006-04-18,2006-01-27
-4fua,1996-10-14,1996-02-14
-4fuy,2012-08-22,2012-06-28
-6fu3,2019-03-13,2018-02-26
-6fuj,2018-06-06,2018-02-27
-3fu8,2009-09-22,2009-01-14
-3fu6,2009-07-28,2009-01-14
-1fuq,1997-03-12,1996-08-29
-7ful,2024-02-21,2023-02-08
-6ful,2018-10-10,2018-02-27
-7fuh,2024-02-21,2023-02-08
-3fug,2009-05-12,2009-01-14
-6fuf,2018-10-03,2018-02-27
-3fui,2009-07-28,2009-01-14
-3fuz,2010-01-19,2009-01-15
-4fuh,2012-08-22,2012-06-28
-1fut,1993-10-31,1993-01-18
-5fuq,2017-02-22,2016-01-29
-7fuf,2024-02-21,2023-02-08
-5fun,2016-04-13,2016-01-28
-4fut,2012-07-25,2012-06-28
-7fu9,2024-02-21,2023-02-08
-7fug,2024-02-21,2023-02-08
-7fu0,2024-02-21,2023-02-08
-7fuy,2023-03-29,2023-03-09
-7fut,2023-03-29,2023-03-09
-3fuw,2009-03-31,2009-01-14
-8fu9,2023-04-05,2023-01-16
-5fue,2016-03-09,2016-01-26
-8fux,2023-03-08,2023-01-18
-6fu5,2018-04-25,2018-02-26
-4fup,2013-01-16,2012-06-28
-2fua,1996-10-14,1996-02-14
-1fu4,2000-10-04,2000-09-14
-6fuw,2018-03-21,2018-02-28
-7fuc,2024-02-21,2023-02-08
-8fuo,2023-04-05,2023-01-17
-7fu7,2024-02-21,2023-02-08
-7fus,2023-03-29,2023-03-09
-2fub,2006-02-14,2006-01-26
-7fu2,2024-02-21,2023-02-08
-5fui,2016-03-02,2016-01-27
-7fu4,2024-02-21,2023-02-08
-4fu0,2012-09-19,2012-06-28
-5fuy,2016-07-27,2016-01-31
-5ful,2016-11-09,2016-01-27
-1fup,1997-03-12,1996-08-29
-5fuw,2016-07-27,2016-01-31
-8fuj,2023-05-24,2023-01-17
-6fue,2018-06-20,2018-02-26
-5fus,2016-06-01,2016-01-29
-4fug,2012-08-22,2012-06-28
-3fub,2009-06-02,2009-01-14
-7fui,2024-02-21,2023-02-08
-7fuj,2024-02-21,2023-02-08
-1fuj,1996-07-11,1996-01-25
-1fuy,2001-01-17,2000-09-18
-4fu4,2013-08-21,2012-06-28
-7fu5,2024-02-21,2023-02-08
-2fut,2006-04-18,2006-01-27
-4fuc,2012-08-22,2012-06-28
-7fuk,2024-02-21,2023-02-08
-3fu9,2009-09-22,2009-01-14
-2fum,2006-08-01,2006-01-27
-3fuj,2009-07-28,2009-01-14
-2fuv,2006-03-07,2006-01-27
-3fu3,2009-07-28,2009-01-13
-5fu0,2017-02-22,2016-01-19
-3fus,2009-06-30,2009-01-14
-3fuf,2009-07-28,2009-01-14
-7fun,2024-02-21,2023-02-08
-3fu1,2009-07-28,2009-01-13
-4fub,2012-08-22,2012-06-28
-3fuu,2009-03-31,2009-01-14
-1fua,1996-10-14,1996-02-14
-3fu7,2009-09-22,2009-01-14
-6fu1,2019-03-13,2018-02-26
-7fum,2024-02-21,2023-02-08
-1fuk,2000-11-29,2000-09-15
-4fus,2012-10-17,2012-06-28
-4ful,2012-10-17,2012-06-28
-3fup,2009-02-10,2009-01-14
-7fu1,2024-02-21,2023-02-08
-7fuw,2023-03-29,2023-03-09
-6fuv,2019-03-20,2018-02-27
-3fun,2009-07-28,2009-01-14
-7fup,2024-02-21,2023-02-08
-6fuh,2018-06-06,2018-02-27
-7fuq,2024-02-21,2023-02-08
-3fuk,2009-07-28,2009-01-14
-6fui,2018-06-06,2018-02-27
-6fuu,2018-05-16,2018-02-27
-7fua,2024-02-21,2023-02-08
-2fug,2006-02-14,2006-01-26
-8fui,2023-05-24,2023-01-17
-4fud,2012-08-22,2012-06-28
-1fu7,2000-10-04,2000-09-14
-7fub,2024-02-21,2023-02-08
-7fuv,2023-03-29,2023-03-09
-5fub,2016-11-09,2016-01-22
-5fu4,2016-06-22,2016-01-20
-4fuf,2012-08-22,2012-06-28
-6fux,2019-03-20,2018-02-28
-2fue,2006-03-21,2006-01-26
-8fur,2023-04-26,2023-01-18
-6fu6,2019-03-20,2018-02-26
-1fun,1999-07-23,1998-07-23
-4fu8,2012-08-22,2012-06-28
-4fuk,2012-08-29,2012-06-28
-3fu5,2009-07-28,2009-01-14
-4fu7,2012-08-22,2012-06-28
-5fuu,2016-03-09,2016-01-29
-6fu7,2018-10-24,2018-02-26
-5fu8,2017-02-22,2016-01-21
-8fun,2023-04-05,2023-01-17
-3fux,2009-03-31,2009-01-14
-8fu4,2024-03-27,2023-01-16
-2fud,2006-08-01,2006-01-26
-8fu3,2023-11-01,2023-01-16
-3fue,2009-07-28,2009-01-14
-4fue,2012-08-22,2012-06-28
-7fu3,2024-02-21,2023-02-08
-1fu9,2000-10-04,2000-09-14
-5fux,2016-07-27,2016-01-31
-7fur,2024-02-21,2023-02-08
-4fux,2012-08-22,2012-06-28
-2fu8,2007-01-30,2006-01-26
-5fum,2016-09-21,2016-01-28
-5fuk,2017-02-22,2016-01-27
-2fu7,2007-01-30,2006-01-26
-2fu9,2007-01-30,2006-01-26
-5fuj,2017-02-22,2016-01-27
-6fut,2018-06-06,2018-02-27
-3fuc,2009-12-08,2009-01-14
-5fu3,2016-06-22,2016-01-20
-6qsk,2019-10-02,2019-02-21
-2qsv,2007-09-25,2007-07-31
-2qs3,2008-08-05,2007-07-30
-7qse,2023-01-25,2022-01-13
-4qsu,2014-07-23,2014-07-06
-5qsj,2019-08-21,2019-05-25
-8qsj,2023-12-13,2023-10-10
-5qsr,2019-08-21,2019-05-25
-7qsw,2022-10-12,2022-01-14
-5qsa,2019-08-21,2019-05-25
-3qs5,2011-10-12,2011-02-19
-4qsa,2015-01-21,2014-07-03
-2qs2,2008-08-05,2007-07-30
-5qsb,2019-08-21,2019-05-25
-6qs5,2019-02-27,2019-02-20
-2qsy,2007-08-14,2007-07-31
-8qsq,2024-05-08,2023-10-11
-4qsv,2014-07-23,2014-07-06
-5qsk,2019-08-21,2019-05-25
-6qsz,2019-09-18,2019-02-22
-7qsl,2022-05-25,2022-01-13
-1qsc,1999-08-01,1999-06-20
-7qsx,2022-10-12,2022-01-14
-3qs4,2011-10-12,2011-02-19
-1qs7,2003-06-24,1999-06-25
-7qsr,2022-07-20,2022-01-14
-1qss,1999-08-16,1999-06-23
-3qsu,2012-09-12,2011-02-21
-4qsh,2014-10-29,2014-07-04
-5qsd,2019-08-21,2019-05-25
-7qst,2022-03-30,2022-01-14
-3qs0,2011-03-16,2011-02-19
-4qsm,2014-12-03,2014-07-06
-6qsi,2020-01-08,2019-02-20
-6qss,2019-07-17,2019-02-21
-6qsn,2019-10-16,2019-02-21
-2qsc,2008-01-15,2007-07-30
-3qsi,2012-04-04,2011-02-21
-4qsf,2014-07-30,2014-07-03
-5qs1,2019-07-10,2019-05-25
-5qss,2019-08-21,2019-05-25
-5qsv,2019-08-21,2019-05-25
-4qsz,2015-07-08,2014-07-06
-1qsy,1999-08-16,1999-06-24
-5qso,2019-08-21,2019-05-25
-4qsw,2014-07-23,2014-07-06
-1qse,1999-12-21,1999-06-21
-1qs4,1999-11-17,1999-06-25
-6qsw,2019-03-27,2019-02-22
-2qse,2008-03-18,2007-07-30
-5qs4,2019-07-10,2019-05-25
-1qsi,1999-07-02,1999-06-22
-7qsk,2022-05-25,2022-01-13
-4qsk,2014-10-29,2014-07-04
-3qs7,2011-03-16,2011-02-19
-2qsp,2008-09-02,2007-07-31
-3qse,2011-06-01,2011-02-21
-7qsv,2022-10-12,2022-01-14
-1qs0,1999-08-18,1999-06-24
-2qss,2008-09-02,2007-07-31
-4qs5,2014-08-06,2014-07-02
-4qs7,2015-02-11,2014-07-03
-3qsp,2011-03-09,2011-02-21
-6qsb,2020-03-18,2019-02-20
-3qss,2011-06-01,2011-02-21
-5qsw,2019-08-21,2019-05-25
-7qsd,2022-03-02,2022-01-13
-3qsz,2011-04-20,2011-02-22
-7qsy,2022-10-12,2022-01-14
-4qsx,2014-07-23,2014-07-06
-7qsi,2023-01-25,2022-01-13
-5qsy,2019-08-21,2019-05-25
-5qs2,2019-07-10,2019-05-25
-5qsn,2019-08-21,2019-05-25
-4qs6,2014-08-06,2014-07-03
-5qse,2019-08-21,2019-05-25
-3qsa,2012-08-22,2011-02-20
-4qsj,2015-01-21,2014-07-04
-3qsy,2012-03-21,2011-02-22
-6qsx,2019-03-27,2019-02-22
-4qsc,2014-07-23,2014-07-03
-3qs1,2011-05-11,2011-02-19
-6qst,2020-03-18,2019-02-22
-7qsf,2022-07-13,2022-01-13
-6qsa,2019-06-19,2019-02-20
-7qsc,2023-01-25,2022-01-13
-5qsu,2019-08-21,2019-05-25
-1qs8,1999-07-07,1999-06-25
-4qsb,2015-01-21,2014-07-03
-5qsl,2019-07-10,2019-05-25
-5qs3,2019-07-10,2019-05-25
-1qsg,1999-07-21,1999-06-21
-7qs8,2022-09-07,2022-01-13
-6qsq,2020-01-29,2019-02-21
-7qsm,2022-05-25,2022-01-13
-5qsc,2019-08-21,2019-05-25
-7qsa,2022-08-31,2022-01-13
-2qs4,2008-08-05,2007-07-30
-8qs0,2024-02-21,2023-10-10
-1qsn,1999-09-08,1999-06-22
-7qso,2022-05-25,2022-01-13
-3qsr,2012-07-04,2011-02-21
-3qsb,2011-06-08,2011-02-20
-1qsh,1999-07-02,1999-06-22
-5qsf,2019-08-21,2019-05-25
-1qsl,1999-06-30,1999-06-22
-1qs2,1999-12-29,1999-06-25
-5qsp,2019-08-21,2019-05-25
-1qsf,1999-12-21,1999-06-21
-5qsi,2019-08-21,2019-05-25
-6qsr,2019-04-03,2019-02-21
-6qsc,2020-03-18,2019-02-20
-4qsp,2014-07-23,2014-07-06
-5qsq,2019-08-21,2019-05-25
-5qs7,2019-08-21,2019-05-25
-2qs8,2007-08-21,2007-07-30
-5qsg,2019-08-21,2019-05-25
-8qso,2024-02-14,2023-10-10
-4qsd,2014-08-06,2014-07-03
-8qsk,2023-11-01,2023-10-10
-4qs9,2015-02-11,2014-07-03
-5qs8,2019-08-21,2019-05-25
-8qsl,2023-10-25,2023-10-10
-3qs6,2011-10-12,2011-02-19
-7qsz,2022-10-12,2022-01-14
-5qst,2019-08-21,2019-05-25
-3qs8,2012-08-22,2011-02-20
-5qsm,2019-08-21,2019-05-25
-6qs1,2019-05-22,2019-02-20
-5qs5,2019-07-10,2019-05-25
-7qsn,2022-05-25,2022-01-13
-6qs7,2019-07-03,2019-02-20
-3qsd,2011-08-10,2011-02-21
-6qsy,2020-03-18,2019-02-22
-5qsz,2019-08-21,2019-05-25
-3qst,2012-07-04,2011-02-21
-3qsm,2011-06-01,2011-02-21
-1qsm,1999-12-22,1999-06-22
-3qsv,2011-06-22,2011-02-22
-5qs9,2019-08-21,2019-05-25
-6qs8,2019-07-03,2019-02-20
-5qsx,2019-08-21,2019-07-16
-2qsw,2007-08-21,2007-07-31
-6qsu,2021-01-20,2019-02-22
-4qsi,2015-01-21,2014-07-04
-3qsj,2011-04-13,2011-02-21
-6qs4,2019-07-03,2019-02-20
-5qsh,2019-08-21,2019-05-25
-1qsr,1999-09-08,1999-06-23
-5qs6,2019-08-21,2019-06-19
-2qs1,2008-08-05,2007-07-30
-4qst,2014-07-23,2014-07-06
-7qs9,2022-08-31,2022-01-13
-6qs9,2019-09-11,2019-02-20
-5qs0,2019-07-10,2019-05-25
-6qs6,2019-07-03,2019-02-20
-7qsj,2023-01-25,2022-01-13
-5ao0,2015-10-14,2015-09-09
-6aok,2018-01-10,2017-08-16
-3ao3,2011-03-09,2010-09-20
-5ao3,2016-04-20,2015-09-09
-6ao7,2017-08-30,2017-08-15
-3ao0,2011-08-03,2010-09-16
-3aos,2011-10-12,2010-10-06
-5aoi,2015-12-16,2015-09-10
-8ao2,2022-09-28,2022-08-08
-8ao5,2022-09-28,2022-08-08
-3aow,2011-10-12,2010-10-07
-6aoc,2018-08-08,2017-08-15
-5aog,2016-01-13,2015-09-10
-7aou,2021-04-21,2020-10-15
-6ao8,2017-08-30,2017-08-15
-2aow,2005-09-13,2005-08-14
-7ao9,2020-11-11,2020-10-14
-8aog,2022-09-28,2022-08-08
-1aol,1997-10-15,1997-07-08
-8ao6,2022-09-28,2022-08-08
-7ao0,2020-12-02,2020-10-13
-7aod,2021-02-24,2020-10-14
-6aoi,2018-08-22,2017-08-16
-5aoq,2015-11-25,2015-09-11
-7aot,2021-04-21,2020-10-15
-7ao7,2021-04-07,2020-10-13
-3aox,2011-05-25,2010-10-08
-5aor,2015-11-18,2015-09-11
-2aoj,2006-01-17,2005-08-12
-4ao7,2012-08-08,2012-03-23
-8ao7,2022-09-28,2022-08-08
-3aop,1998-01-14,1997-07-09
-4aos,2012-05-30,2012-03-29
-4aoa,2012-10-24,2012-03-25
-3aoi,2010-12-08,2010-09-30
-8aoz,2022-09-07,2022-08-09
-1aod,1998-01-07,1997-07-02
-5ao1,2015-10-14,2015-09-09
-6aol,2017-10-11,2017-08-16
-3aof,2011-08-10,2010-09-27
-6aov,2017-10-18,2017-08-16
-6aon,2017-08-23,2017-08-16
-3aod,2011-11-30,2010-09-23
-7ao2,2020-12-02,2020-10-13
-6aos,2017-10-18,2017-08-16
-1aoe,1998-01-07,1997-07-02
-5aom,2015-12-16,2015-09-10
-7aoc,2021-02-24,2020-10-14
-8aoe,2022-09-28,2022-08-08
-6aop,2017-10-18,2017-08-16
-6aod,2018-03-14,2017-08-15
-4aop,1998-01-14,1997-07-09
-6ao5,2017-11-08,2017-08-15
-8aoy,2023-09-20,2022-08-09
-1aom,1998-02-04,1997-07-08
-5ao2,2015-10-14,2015-09-09
-7aoi,2020-12-02,2020-10-14
-2aob,2005-10-04,2005-08-12
-3ao9,2011-09-28,2010-09-22
-6aoq,2017-10-18,2017-08-16
-1aoq,1998-02-04,1997-07-09
-8aoo,2023-05-31,2022-08-08
-6aou,2017-10-18,2017-08-16
-5aol,2015-12-16,2015-09-10
-7aos,2021-08-04,2020-10-15
-5aov,2016-03-02,2015-09-12
-1aop,1997-12-24,1997-07-08
-8aoc,2022-09-28,2022-08-08
-2aoi,2006-01-17,2005-08-12
-3ao1,2011-03-09,2010-09-17
-2aop,1998-01-14,1997-07-09
-8aoh,2022-09-28,2022-08-08
-8aoi,2022-09-28,2022-08-08
-8aow,2023-03-29,2022-08-08
-2ao2,2006-06-13,2005-08-12
-5aop,1998-01-14,1997-07-10
-8aox,2023-03-29,2022-08-08
-8aoa,2022-09-28,2022-08-08
-1aox,1998-11-25,1997-07-13
-8ao0,2022-11-23,2022-08-08
-1ao0,1997-11-12,1997-07-15
-1aoo,1997-12-24,1997-07-08
-6aoh,2018-08-22,2017-08-16
-3aoh,2010-12-08,2010-09-28
-2aoe,2006-01-17,2005-08-12
-4aov,2012-07-11,2012-03-30
-2aos,2005-09-13,2005-08-14
-2aoh,2006-01-17,2005-08-12
-8aof,2022-09-28,2022-08-08
-5aok,2015-12-16,2015-09-10
-8aol,2023-08-23,2022-08-08
-7aoe,2021-02-24,2020-10-14
-4aoz,2013-05-01,2012-03-30
-2aof,2006-01-17,2005-08-12
-4aon,2012-10-31,2012-03-29
-7aoa,2020-11-11,2020-10-14
-1aob,1998-07-01,1997-06-30
-7ao5,2020-12-02,2020-10-13
-6ao1,2017-08-23,2017-08-15
-6aor,2017-10-18,2017-08-16
-3aoc,2011-11-30,2010-09-23
-1ao8,1998-02-25,1997-07-22
-5ao7,2016-07-20,2015-09-09
-6aob,2017-11-22,2017-08-15
-8aoq,2023-01-11,2022-08-08
-3ao2,2011-03-16,2010-09-20
-3ao4,2011-03-09,2010-09-20
-5aob,2015-12-09,2015-09-10
-6aox,2018-02-28,2017-08-16
-8aoj,2022-09-28,2022-08-08
-4aot,2012-04-11,2012-03-29
-7aog,2021-06-16,2020-10-14
-5aoj,2015-12-16,2015-09-10
-5ao4,2015-10-14,2015-09-09
-2aot,2005-09-13,2005-08-14
-4aoc,2012-08-15,2012-03-26
-8aok,2023-06-14,2022-08-08
-2aoa,2005-10-04,2005-08-12
-2aox,2005-09-13,2005-08-14
-5ao8,2016-07-20,2015-09-09
-6aoy,2018-02-28,2017-08-16
-4ao5,2013-04-03,2012-03-23
-8aop,2023-01-11,2022-08-08
-3aov,2011-10-12,2010-10-07
-7aom,2021-06-02,2020-10-14
-1ao7,1997-09-17,1997-07-21
-4aox,2012-05-30,2012-03-30
-7aop,2021-06-02,2020-10-14
-8aom,2023-06-14,2022-08-08
-2ao6,2005-08-30,2005-08-12
-5ao5,2015-10-28,2015-09-09
-3ao5,2011-03-09,2010-09-21
-1aoz,1993-10-31,1992-01-08
-7ao8,2020-11-11,2020-10-14
-1aor,1995-04-20,1995-02-13
-7ao3,2020-12-02,2020-10-13
-8ao3,2022-09-28,2022-08-08
-8aob,2022-09-28,2022-08-08
-4aor,2013-01-09,2012-03-29
-3aoe,2011-09-07,2010-09-27
-8ao8,2022-09-28,2022-08-08
-4aof,2012-05-09,2012-03-26
-4aoq,2013-01-09,2012-03-29
-6aom,2017-10-11,2017-08-16
-8aov,2023-05-31,2022-08-08
-3aob,2011-11-30,2010-09-23
-4ao9,2012-10-24,2012-03-25
-6ao6,2018-07-18,2017-08-15
-6aog,2018-08-22,2017-08-16
-1aof,1997-10-15,1997-07-02
-1aog,1997-09-17,1997-07-03
-7aoz,2021-10-06,2020-10-15
-7aov,2022-03-02,2020-10-15
-6aot,2017-10-18,2017-08-16
-7ao1,2020-12-02,2020-10-13
-4aoi,2012-09-26,2012-03-27
-1ao5,1997-10-15,1997-07-16
-4aou,2012-07-11,2012-03-30
-6aoj,2018-01-10,2017-08-16
-2aoq,2005-10-11,2005-08-13
-4aoj,2012-08-15,2012-03-28
-2aov,2005-09-13,2005-08-14
-4aoo,2013-04-17,2012-03-29
-8ao9,2022-09-28,2022-08-08
-5aoh,2017-01-25,2015-09-10
-2aor,2005-10-11,2005-08-13
-1aon,1997-10-15,1997-07-08
-7aoh,2021-10-06,2020-10-14
-7aof,2021-10-06,2020-10-14
-3aou,2011-08-17,2010-10-06
-7aor,2021-04-28,2020-10-15
-3aog,2011-09-07,2010-09-28
-5aoc,2015-12-09,2015-09-10
-4ao4,2012-06-06,2012-03-23
-7aol,2020-12-02,2020-10-14
-2aou,2005-09-13,2005-08-14
-8ao4,2022-09-28,2022-08-08
-8snj,2023-05-10,2023-04-27
-5snm,2023-12-20,2022-05-30
-8snf,2024-03-06,2023-04-27
-6snw,2020-01-15,2019-08-27
-5snn,2023-12-20,2022-05-30
-6sna,2020-04-15,2019-08-23
-3snb,2011-09-07,2011-06-29
-6snl,2020-12-09,2019-08-26
-1snc,1990-10-15,1989-07-21
-3snn,2011-10-12,2011-06-29
-8sn1,2024-01-17,2023-04-26
-7snm,2022-10-05,2021-10-28
-6snx,2020-09-09,2019-08-27
-5snl,2023-12-20,2022-05-30
-5sn9,2023-12-20,2022-05-30
-8snc,2024-05-01,2023-04-27
-3sng,2012-07-04,2011-06-29
-3sn7,2011-10-26,2011-06-28
-6snv,2021-05-19,2019-08-27
-1snk,2004-06-22,2004-03-11
-8sn4,2024-01-17,2023-04-26
-3sn5,2011-07-13,2011-06-28
-7sno,2022-10-05,2021-10-28
-6snd,2019-11-06,2019-08-23
-1sn8,2004-08-17,2004-03-10
-6sny,2019-09-04,2019-08-27
-3snm,2012-08-01,2011-06-29
-1sn5,2004-08-03,2004-03-10
-5snq,2023-12-20,2022-05-30
-8snn,2024-05-29,2023-04-27
-7snw,2022-11-16,2021-10-28
-3sn4,2011-07-27,2011-06-28
-1sn7,2004-06-01,2004-03-10
-5snk,2023-12-20,2022-05-30
-1sn0,2004-08-03,2004-03-10
-8sn9,2024-01-17,2023-04-26
-8snz,2024-03-13,2023-04-28
-5sn6,2023-12-20,2022-05-30
-5snr,2023-12-20,2022-05-30
-8snm,2024-05-29,2023-04-27
-7sna,2022-04-06,2021-10-27
-6snq,2020-04-08,2019-08-27
-5sne,2023-12-20,2022-05-30
-7snk,2022-10-05,2021-10-28
-7snn,2022-10-05,2021-10-28
-7snz,2022-03-16,2021-10-28
-5snc,2023-12-20,2022-05-30
-6sni,2020-03-11,2019-08-24
-5sni,2023-12-20,2022-05-30
-5snb,2023-12-20,2022-05-30
-8sno,2024-05-29,2023-04-27
-8snd,2024-05-01,2023-04-27
-7snt,2022-11-16,2021-10-28
-7snu,2022-07-06,2021-10-28
-7snp,2022-03-16,2021-10-28
-3sn8,2011-09-07,2011-06-29
-7snj,2022-10-05,2021-10-28
-3sn0,2011-07-27,2011-06-28
-3snz,2011-11-16,2011-06-29
-8snk,2024-03-06,2023-04-27
-8sn7,2024-01-17,2023-04-26
-5sn7,2023-12-20,2022-05-30
-6snu,2019-10-09,2019-08-27
-2sns,1982-07-29,1982-05-14
-5sna,2023-12-20,2022-05-30
-3snl,2011-10-26,2011-06-29
-8snl,2024-05-29,2023-04-27
-7sn3,2021-12-08,2021-10-27
-7sn0,2021-12-08,2021-10-27
-5snv,2023-12-20,2022-05-30
-3snc,2011-09-07,2011-06-29
-2snm,1993-01-15,1991-04-03
-8sn0,2024-01-17,2023-04-26
-5snz,2023-12-20,2022-05-30
-6sno,2020-04-08,2019-08-27
-8sn8,2024-01-17,2023-04-26
-5snh,2023-12-20,2022-05-30
-5sn5,2023-12-20,2022-05-30
-8snh,2023-10-11,2023-04-27
-1snm,1991-07-15,1990-02-15
-5sns,2023-12-20,2022-05-30
-6snt,2020-03-04,2019-08-27
-8snb,2023-06-28,2023-04-26
-7snh,2022-07-13,2021-10-28
-8snp,2024-02-07,2023-04-27
-1snn,2004-07-20,2004-03-11
-7snv,2023-05-03,2021-10-28
-7snl,2022-10-05,2021-10-28
-5snd,2023-12-20,2022-05-30
-6snh,2020-03-11,2019-08-24
-7sn8,2022-10-12,2021-10-27
-5snt,2023-12-20,2022-05-30
-3snd,2011-09-07,2011-06-29
-3sny,2011-11-16,2011-06-29
-8sn6,2024-01-17,2023-04-26
-7sn6,2022-07-27,2021-10-27
-6snc,2019-11-06,2019-08-23
-5snf,2023-12-20,2022-05-30
-3sn1,2011-07-27,2011-06-28
-6snp,2020-04-08,2019-08-27
-5snp,2023-12-20,2022-05-30
-3sn6,2011-07-20,2011-06-28
-8sn3,2024-01-17,2023-04-26
-5sn8,2023-12-20,2022-05-30
-6sne,2019-11-06,2019-08-23
-3sne,2011-09-07,2011-06-29
-7sne,2022-04-13,2021-10-28
-8sng,2023-05-10,2023-04-27
-7sn2,2021-12-08,2021-10-27
-6sns,2021-05-19,2019-08-27
-3sn9,2012-01-25,2011-06-29
-5snw,2023-12-20,2022-05-30
-3sna,2011-09-07,2011-06-29
-5snj,2023-12-20,2022-05-30
-6sn6,2019-10-09,2019-08-23
-1sny,2004-09-28,2004-03-12
-1snu,2004-07-20,2004-03-12
-2sni,1988-09-07,1988-09-05
-1snr,2004-06-22,2004-03-11
-8sn5,2024-01-17,2023-04-26
-5snu,2023-12-20,2022-05-30
-7snb,2022-03-02,2021-10-27
-8sny,2023-12-20,2023-04-28
-1snf,2004-03-16,2004-03-10
-5sno,2023-12-20,2022-05-30
-8sne,2024-05-01,2023-04-27
-5sng,2023-12-20,2022-05-30
-8sn2,2024-01-17,2023-04-26
-5sny,2023-12-20,2022-05-30
-7sni,2022-07-13,2021-10-28
-5snx,2023-12-20,2022-05-30
-3sni,2011-10-26,2011-06-29
-8sna,2024-01-17,2023-04-26
-2h7j,2006-10-24,2006-06-02
-3h7g,2009-09-15,2009-04-27
-1h70,2001-08-02,2001-06-30
-7h71,2024-05-29,2024-04-26
-4h7c,2013-03-20,2012-09-20
-7h7e,2024-05-29,2024-04-26
-3h7u,2009-08-04,2009-04-28
-5h70,2016-12-07,2016-11-15
-6h7p,2019-04-03,2018-07-31
-1h7o,2001-07-10,2001-07-09
-4h7j,2013-06-05,2012-09-20
-4h76,2013-04-24,2012-09-20
-4h7l,2013-01-02,2012-09-20
-7h7s,2024-05-29,2024-04-26
-2h79,2006-07-25,2006-06-01
-6h77,2018-10-31,2018-07-30
-4h7d,2013-06-05,2012-09-20
-4h7k,2013-06-05,2012-09-20
-2h7x,2006-09-19,2006-06-05
-1h78,2002-07-04,2001-07-04
-3h72,2009-05-12,2009-04-24
-5h75,2017-06-28,2016-11-17
-8h7n,2023-10-25,2022-10-20
-1h7v,2002-01-29,2001-01-16
-7h7w,2024-05-29,2024-04-26
-4h7x,2012-12-12,2012-09-21
-4h77,2013-06-05,2012-09-20
-5h7l,2018-02-21,2016-11-18
-1h7h,2001-09-13,2001-07-06
-2h7r,2006-10-31,2006-06-02
-8h7x,2023-10-25,2022-10-21
-3h7r,2009-08-04,2009-04-28
-6h70,2018-12-19,2018-07-30
-5h7w,2017-11-22,2016-11-21
-3h7h,2009-12-08,2009-04-27
-6h7j,2018-10-17,2018-07-31
-2h7c,2006-08-29,2006-06-02
-3h77,2009-09-15,2009-04-24
-2h7y,2006-09-19,2006-06-06
-8h72,2023-08-23,2022-10-18
-4h7q,2013-06-05,2012-09-20
-7h7c,2024-05-29,2024-04-26
-6h78,2018-10-31,2018-07-30
-8h7j,2023-10-25,2022-10-20
-6h7o,2018-10-17,2018-07-31
-1h7k,2004-02-25,2001-07-08
-6h7e,2020-02-19,2018-07-31
-1h71,2003-02-13,2001-07-02
-3h7y,2009-09-22,2009-04-28
-3h70,2009-05-05,2009-04-24
-1h7q,2001-12-13,2001-07-09
-1h76,2002-01-15,2001-07-03
-4h7h,2013-06-05,2012-09-20
-6h7n,2018-10-17,2018-07-31
-4h7o,2013-10-02,2012-09-20
-1h7t,2001-09-13,2001-07-10
-5h7o,2017-12-13,2016-11-20
-6h79,2019-03-20,2018-07-30
-1h7l,2001-12-13,2001-07-09
-8h7y,2023-04-19,2022-10-21
-7h75,2024-05-29,2024-04-26
-3h7m,2009-06-30,2009-04-27
-2h7q,2006-10-31,2006-06-02
-4h75,2012-10-03,2012-09-20
-8h79,2023-10-25,2022-10-19
-5h71,2017-08-09,2016-11-15
-1h73,2001-09-13,2001-07-02
-5h7j,2018-02-21,2016-11-18
-7h7o,2024-05-29,2024-04-26
-1h79,2002-03-28,2001-07-04
-6h7u,2018-12-26,2018-07-31
-8h7f,2023-03-01,2022-10-20
-8h7l,2023-08-30,2022-10-20
-7h7k,2024-05-29,2024-04-26
-7h7a,2024-05-29,2024-04-26
-7h76,2024-05-29,2024-04-26
-7h73,2024-05-29,2024-04-26
-1h7w,2001-02-23,2001-01-19
-8h7i,2023-10-25,2022-10-20
-4h7i,2013-06-05,2012-09-20
-4h71,2012-10-03,2012-09-19
-5h7n,2017-02-15,2016-11-19
-4h7f,2013-06-05,2012-09-20
-7h7l,2024-05-29,2024-04-26
-7h72,2024-05-29,2024-04-26
-8h7c,2023-09-20,2022-10-19
-6h74,2018-11-14,2018-07-30
-6h7x,2018-08-08,2018-07-31
-6h7f,2018-10-10,2018-07-31
-5h73,2017-07-26,2016-11-16
-6h7d,2019-02-06,2018-07-31
-3h7j,2009-09-22,2009-04-27
-7h78,2024-05-29,2024-04-26
-7h77,2024-05-29,2024-04-26
-3h7v,2009-05-12,2009-04-28
-7h7r,2024-05-29,2024-04-26
-5h7g,2016-12-07,2016-11-18
-3h7c,2009-05-26,2009-04-24
-8h7m,2023-10-25,2022-10-20
-8h7b,2023-02-22,2022-10-19
-8h7w,2023-10-11,2022-10-21
-8h7h,2023-03-22,2022-10-20
-7h7z,2024-05-29,2024-04-26
-3h78,2009-09-15,2009-04-24
-6h73,2018-11-14,2018-07-30
-7h7v,2024-05-29,2024-04-26
-3h7t,2009-05-12,2009-04-28
-8h7r,2023-10-25,2022-10-20
-6h7m,2018-10-17,2018-07-31
-6h75,2019-08-14,2018-07-30
-6h7y,2018-12-05,2018-07-31
-6h7c,2019-08-14,2018-07-31
-3h7b,2010-01-12,2009-04-24
-3h7d,2010-04-28,2009-04-24
-7h7i,2024-05-29,2024-04-26
-1h7p,2001-07-13,2001-07-09
-6h72,2018-12-19,2018-07-30
-8h77,2023-01-04,2022-10-19
-5h7d,2017-06-28,2016-11-17
-2h7v,2006-09-19,2006-06-04
-5h74,2017-11-22,2016-11-17
-1h72,2001-09-13,2001-07-02
-5h7s,2017-11-29,2016-11-21
-5h7q,2017-02-15,2016-11-20
-7h7n,2024-05-29,2024-04-26
-7h7x,2024-05-29,2024-04-26
-1h7n,2001-07-10,2001-07-09
-1h7a,2002-03-28,2001-07-04
-5h7h,2016-12-07,2016-11-18
-4h73,2013-10-02,2012-09-20
-7h7j,2024-05-29,2024-04-26
-4h7v,2013-09-25,2012-09-20
-7h7b,2024-05-29,2024-04-26
-4h7u,2013-08-07,2012-09-20
-8h7p,2023-11-01,2022-10-20
-6h76,2019-08-14,2018-07-30
-6h7t,2019-08-14,2018-07-31
-8h75,2023-10-25,2022-10-19
-1h7f,2001-09-13,2001-07-06
-4h7z,2012-10-10,2012-09-21
-6h7z,2018-12-05,2018-07-31
-3h7s,2009-09-22,2009-04-28
-3h73,2009-05-12,2009-04-24
-1h7g,2001-09-13,2001-07-06
-7h7g,2024-05-29,2024-04-26
-3h7f,2009-05-05,2009-04-24
-8h7o,2023-11-01,2022-10-20
-1h74,2001-11-28,2001-07-02
-1h7u,2001-11-27,2001-07-10
-5h7r,2017-11-29,2016-11-21
-2h77,2006-07-25,2006-06-01
-1h7r,2001-07-12,2001-07-09
-8h7v,2023-04-19,2022-10-21
-6h7s,2019-08-14,2018-07-31
-4h7e,2013-06-05,2012-09-20
-3h7k,2009-05-26,2009-04-27
-2h7s,2006-10-31,2006-06-02
-7h7y,2024-05-29,2024-04-26
-1h7x,2001-02-23,2001-01-19
-3h7w,2010-01-12,2009-04-28
-3h7p,2009-09-22,2009-04-28
-6h7l,2018-10-17,2018-07-31
-8h78,2023-01-18,2022-10-19
-5h7k,2018-02-21,2016-11-18
-19hc,1999-12-01,1998-12-01
-8x5n,2024-02-28,2023-11-17
-2x5l,2010-11-10,2010-02-10
-6x50,2021-02-03,2020-05-24
-6x5k,2020-10-07,2020-05-26
-7x54,2023-03-08,2022-03-04
-8x53,2024-05-29,2023-11-16
-4x5e,2015-11-25,2014-12-05
-5x51,2017-05-17,2017-02-14
-5x52,2017-05-17,2017-02-14
-6x5c,2020-10-21,2020-05-25
-7x56,2023-03-08,2022-03-04
-6x59,2020-09-16,2020-05-25
-5x5g,2017-07-12,2017-02-15
-6x5w,2021-09-01,2020-05-27
-8x5j,2023-12-27,2023-11-17
-7x5m,2022-06-01,2022-03-05
-7x5q,2023-03-08,2022-03-05
-8x54,2024-05-29,2023-11-16
-1x54,2006-05-23,2005-05-15
-7x5p,2023-03-08,2022-03-05
-8x5l,2023-12-27,2023-11-17
-7x5n,2022-07-06,2022-03-05
-2x50,2011-01-12,2010-02-03
-2x51,2011-01-26,2010-02-04
-8x52,2024-05-29,2023-11-16
-5x5h,2017-03-01,2017-02-16
-4x56,2015-03-11,2014-12-04
-8x5m,2023-12-27,2023-11-17
-7x5z,2022-06-01,2022-03-05
-7x5r,2022-06-01,2022-03-05
-7x55,2023-03-08,2022-03-04
-4x5s,2015-05-20,2014-12-05
-6x5v,2021-09-01,2020-05-27
-6x5i,2020-06-03,2020-05-26
-7x51,2023-04-19,2022-03-03
-8x5k,2023-12-27,2023-11-17
-5x5o,2017-12-27,2017-02-17
-5x5u,2017-05-10,2017-02-17
-7x5u,2022-06-01,2022-03-05
-4x5i,2016-01-13,2014-12-05
-4x5g,2016-01-13,2014-12-05
-4x53,2015-03-11,2014-12-04
-2x5f,2010-07-21,2010-02-08
-6x5e,2020-08-26,2020-05-26
-6x5z,2020-07-22,2020-05-27
-8x51,2024-02-28,2023-11-16
-7x52,2023-04-05,2022-03-03
-7x5j,2023-03-08,2022-03-04
-7x59,2023-03-08,2022-03-04
-5x50,2017-05-17,2017-02-14
-6x5l,2020-06-24,2020-05-26
-6x5y,2021-06-02,2020-05-27
-6x5s,2020-10-07,2020-05-26
-7x5w,2022-06-01,2022-03-05
-4x5f,2016-01-13,2014-12-05
-4x5c,2015-11-25,2014-12-05
-2x5c,2010-07-21,2010-02-08
-5x54,2017-03-29,2017-02-14
-2x5v,2010-05-12,2010-02-10
-2x5x,2010-06-09,2010-02-11
-4x59,2015-11-25,2014-12-04
-6x5a,2020-09-16,2020-05-25
-4x5t,2015-02-25,2014-12-05
-2x5r,2010-07-28,2010-02-10
-4x5h,2016-01-13,2014-12-05
-7x5y,2022-06-01,2022-03-05
-7x5h,2022-09-14,2022-03-04
-4x5j,2016-01-13,2014-12-05
-7x5o,2022-07-06,2022-03-05
-2x58,2010-05-12,2010-02-05
-2x5u,2010-05-12,2010-02-10
-4x5b,2015-11-18,2014-12-05
-6x5u,2020-10-07,2020-05-26
-5x57,2017-07-05,2017-02-15
-1x5w,2005-11-17,2005-05-17
-4x5l,2015-12-09,2014-12-05
-4x5p,2015-05-20,2014-12-05
-4x5z,2015-04-15,2014-12-06
-4x5d,2015-09-23,2014-12-05
-6x5t,2020-10-07,2020-05-26
-6x5x,2020-10-07,2020-05-27
-2x5o,2010-09-15,2010-02-10
-6x5p,2020-06-24,2020-05-26
-5x5m,2017-12-06,2017-02-16
-2x53,2010-02-16,2010-02-05
-7x53,2023-03-08,2022-03-03
-5x58,2017-05-03,2017-02-15
-4x5v,2015-10-28,2014-12-05
-7x5x,2022-06-01,2022-03-05
-5x5q,2017-06-28,2017-02-17
-5x5d,2017-06-28,2017-02-15
-4x5r,2015-05-20,2014-12-05
-4x58,2015-11-25,2014-12-04
-4x5k,2015-12-16,2014-12-05
-6x5b,2020-10-21,2020-05-25
-2x5d,2010-07-21,2010-02-08
-2x5w,2010-06-16,2010-02-10
-5x5p,2018-02-21,2017-02-17
-4x55,2015-03-11,2014-12-04
-7x5l,2022-06-01,2022-03-04
-6x5h,2020-10-07,2020-05-26
-1x55,2006-05-23,2005-05-15
-7x5s,2022-06-01,2022-03-05
-6x5j,2020-06-24,2020-05-26
-8x5y,2024-01-17,2023-11-20
-5x59,2017-05-03,2017-02-15
-4x5q,2015-05-20,2014-12-05
-8x5i,2024-02-28,2023-11-17
-6x5r,2020-10-07,2020-05-26
-4x5y,2015-04-15,2014-12-06
-7x5b,2023-03-08,2022-03-04
-2x52,2010-02-23,2010-02-05
-4x50,2015-05-20,2014-12-04
-2x5z,2010-06-23,2010-02-12
-5fgp,2016-01-20,2015-12-21
-6fg0,2018-12-19,2018-01-09
-2fgi,1999-09-13,1998-09-15
-8fga,2023-10-11,2022-12-12
-3fg1,2009-08-18,2008-12-04
-4fgc,2012-07-11,2012-06-04
-6fga,2019-06-12,2018-01-10
-6fgc,2019-01-16,2018-01-10
-2fgl,2006-09-26,2005-12-22
-4fgj,2013-03-13,2012-06-04
-6fg6,2018-05-30,2018-01-10
-3fgo,2009-04-07,2008-12-08
-7fgb,2022-08-03,2021-07-26
-6fg8,2018-01-24,2018-01-10
-3fgv,2008-12-23,2008-12-08
-6fg5,2019-01-30,2018-01-10
-5fgw,2016-03-30,2015-12-21
-8fg6,2024-03-20,2022-12-12
-6fgx,2018-02-07,2018-01-11
-1fgr,2001-07-04,2000-07-28
-6fgo,2018-06-20,2018-01-11
-7fgi,2022-07-27,2021-07-27
-5fg6,2016-02-03,2015-12-20
-2fg4,2006-07-04,2005-12-21
-7fgy,2022-06-29,2021-07-28
-4fgx,2013-01-16,2012-06-05
-4fg4,2012-08-22,2012-06-03
-7fgd,2022-08-03,2021-07-26
-8fgk,2023-10-11,2022-12-12
-6fgv,2018-05-30,2018-01-11
-2fgr,2006-01-31,2005-12-22
-9fgr,2024-06-05,2024-05-25
-7fg8,2022-02-09,2021-07-26
-3fgw,2009-09-15,2008-12-08
-2fgv,2006-11-07,2005-12-22
-7fgx,2022-06-29,2021-07-28
-5fgb,2016-01-20,2015-12-20
-8fgq,2023-10-11,2022-12-12
-3fgz,2009-09-22,2008-12-08
-4fgr,2013-06-05,2012-06-04
-6fgr,2018-08-08,2018-01-11
-5fg3,2016-05-04,2015-12-20
-5fgh,2016-03-23,2015-12-20
-6fgy,2018-06-06,2018-01-11
-8fgu,2023-10-11,2022-12-12
-4fga,2012-06-27,2012-06-04
-3fg8,2009-01-20,2008-12-05
-4fgl,2013-03-13,2012-06-04
-1fgc,2001-06-01,2000-07-28
-7fgz,2022-08-03,2021-07-28
-3fgg,2009-01-06,2008-12-05
-8fgo,2023-10-11,2022-12-12
-1fgi,1998-04-08,1997-03-22
-5fgn,2017-02-15,2015-12-21
-1fg6,2001-06-01,2000-07-25
-8fg4,2023-09-06,2022-12-12
-6fgl,2018-05-30,2018-01-11
-7fgj,2022-07-27,2021-07-27
-1fgs,1999-05-04,1998-04-29
-5fg5,2015-12-30,2015-12-20
-7fgp,2022-08-31,2021-07-27
-8fg8,2023-06-14,2022-12-12
-7fgr,2022-07-27,2021-07-27
-3fg6,2009-08-11,2008-12-05
-3fg9,2008-12-23,2008-12-05
-5fgf,2016-03-23,2015-12-20
-5fgc,2016-01-20,2015-12-20
-7fgv,2022-02-09,2021-07-28
-1fg7,2001-08-22,2000-07-28
-4fg7,2013-01-23,2012-06-04
-4fg3,2013-06-12,2012-06-02
-2fgj,2006-08-08,2005-12-22
-6fgu,2018-05-30,2018-01-11
-8fg3,2023-09-06,2022-12-12
-7fgm,2022-07-27,2021-07-27
-3fg3,2009-08-18,2008-12-04
-1fgt,2001-07-04,2000-07-28
-5fgi,2016-03-23,2015-12-20
-8fgl,2023-10-11,2022-12-12
-8fgz,2023-04-12,2022-12-13
-6fgs,2018-05-30,2018-01-11
-4fgz,2012-07-25,2012-06-05
-1fgm,2001-10-24,2000-07-28
-2fgy,2006-01-17,2005-12-22
-8fg0,2023-05-10,2022-12-11
-1fg2,2000-10-04,2000-07-27
-5fgz,2016-01-20,2015-12-21
-2fg6,2006-05-23,2005-12-21
-5fge,2016-03-23,2015-12-20
-8fgt,2023-10-11,2022-12-12
-3fg4,2009-08-18,2008-12-04
-7fgq,2022-07-27,2021-07-27
-6fgh,2018-05-30,2018-01-10
-6fg9,2018-08-01,2018-01-10
-3fgt,2009-09-15,2008-12-08
-6fgw,2018-05-30,2018-01-11
-4fgh,2013-01-09,2012-06-04
-5fgj,2016-05-18,2015-12-20
-3fg5,2008-12-23,2008-12-05
-8fgw,2023-02-22,2022-12-12
-8fgx,2023-09-06,2022-12-13
-7fgw,2022-06-29,2021-07-28
-5fgg,2016-03-23,2015-12-20
-8fg7,2023-03-01,2022-12-12
-2fgu,2006-11-07,2005-12-22
-8fgn,2023-10-11,2022-12-12
-6fgi,2018-05-30,2018-01-10
-1fgq,2001-07-04,2000-07-28
-5fg1,2016-07-06,2015-12-19
-2fgq,2006-01-31,2005-12-22
-6fgg,2018-05-30,2018-01-10
-3fgh,2009-04-07,2008-12-06
-5fgs,2016-07-20,2015-12-21
-1fgx,2000-08-16,2000-07-29
-6fgd,2019-01-16,2018-01-10
-4fgm,2012-08-01,2012-06-04
-3fga,2009-09-22,2008-12-05
-1fg3,2001-08-22,2000-07-27
-4fg2,2012-08-22,2012-06-02
-7fgg,2022-07-27,2021-07-27
-2fgc,2006-02-07,2005-12-21
-6fgb,2018-08-29,2018-01-10
-8fgy,2023-04-12,2022-12-13
-8fg5,2023-03-01,2022-12-12
-7fgc,2022-08-03,2021-07-26
-3fge,2008-12-30,2008-12-05
-6fg2,2019-07-24,2018-01-09
-8fgp,2023-10-11,2022-12-12
-8fgv,2023-10-11,2022-12-12
-2fg8,2006-07-04,2005-12-21
-8fgc,2023-10-11,2022-12-12
-8fge,2023-10-11,2022-12-12
-3fgc,2009-05-26,2008-12-05
-7fgu,2022-02-09,2021-07-28
-4fgk,2013-03-13,2012-06-04
-6fgt,2018-05-30,2018-01-11
-5fg0,2016-07-06,2015-12-19
-3fg2,2009-09-01,2008-12-04
-2fge,2006-05-16,2005-12-21
-8fgr,2023-10-11,2022-12-12
-5fg9,2016-03-23,2015-12-20
-4fg8,2013-01-23,2012-06-04
-4fgu,2013-07-03,2012-06-05
-5fga,2016-03-23,2015-12-20
-1fg8,2001-06-01,2000-07-25
-2fgz,2006-06-13,2005-12-23
-8fgf,2023-10-11,2022-12-12
-7fg1,2022-07-27,2021-07-25
-2fg7,2006-05-23,2005-12-21
-2fgh,2006-04-18,2005-12-22
-2fg5,2006-01-10,2005-12-21
-6fg3,2018-08-08,2018-01-09
-8fgi,2023-10-11,2022-12-12
-1fgj,1998-03-04,1997-03-03
-7fgh,2022-07-27,2021-07-27
-4fgt,2013-03-06,2012-06-04
-8fgb,2023-10-11,2022-12-12
-3fgd,2009-12-15,2008-12-05
-7fge,2022-08-03,2021-07-26
-5fg8,2016-12-28,2015-12-20
-6fgf,2018-05-30,2018-01-10
-2fgb,2006-12-12,2005-12-21
-6fg7,2018-01-24,2018-01-10
-5fgr,2016-07-20,2015-12-21
-2fgn,2006-03-28,2005-12-22
-8fgj,2023-10-11,2022-12-12
-4fgo,2012-06-20,2012-06-04
-8fgm,2023-10-11,2022-12-12
-4fgg,2013-01-09,2012-06-04
-2fg9,2006-01-10,2005-12-21
-4fgy,2013-03-20,2012-06-05
-7fga,2022-06-01,2021-07-26
-2fgk,2006-08-08,2005-12-22
-6fgn,2018-05-30,2018-01-11
-8fgd,2023-10-11,2022-12-12
-5fgl,2016-12-21,2015-12-21
-8fgg,2023-10-11,2022-12-12
-7fgl,2022-07-27,2021-07-27
-6fgq,2018-08-22,2018-01-11
-5fgd,2016-03-23,2015-12-20
-3fgr,2009-09-15,2008-12-08
-5fg4,2016-01-13,2015-12-20
-5fgk,2016-02-03,2015-12-20
-8fg9,2023-10-11,2022-12-12
-7fg9,2022-06-01,2021-07-26
-8fgs,2023-10-11,2022-12-12
-3fgs,2009-05-19,2008-12-08
-1fgy,2000-08-23,2000-07-29
-1fgo,2001-07-04,2000-07-28
-4fg9,2013-01-23,2012-06-04
-6fg4,2018-08-08,2018-01-09
-8fgh,2023-10-11,2022-12-12
-5fg7,2016-03-23,2015-12-20
-3fgu,2009-12-15,2008-12-08
-176d,1994-11-01,1994-05-17
-8avg,2022-12-07,2022-08-26
-2avu,2005-12-13,2005-08-30
-5avi,2015-08-26,2015-06-16
-3avc,2012-01-18,2011-03-02
-7avx,2021-03-03,2020-11-06
-4avs,2013-06-19,2012-05-29
-7avi,2021-03-24,2020-11-05
-3avf,2012-01-18,2011-03-05
-8ava,2023-05-03,2022-08-26
-3av0,2011-05-25,2011-02-18
-4av3,2012-08-08,2012-05-23
-1avn,1997-12-24,1997-09-17
-1avb,1998-10-14,1997-09-15
-8avt,2023-07-26,2022-08-26
-1av5,1998-03-25,1997-09-25
-1ava,1999-03-16,1997-09-15
-5avv,2015-09-02,2015-07-01
-1avw,1998-10-28,1997-09-21
-4ave,2013-04-17,2012-05-25
-5avj,2016-07-06,2015-06-17
-2av7,2005-10-18,2005-08-29
-5avr,2015-09-02,2015-07-01
-7avu,2021-03-24,2020-11-06
-4av7,2012-12-05,2012-05-24
-6av5,2018-07-11,2017-09-01
-1avs,1997-12-24,1997-09-19
-8av1,2023-04-19,2022-08-26
-1avx,1998-10-28,1997-09-21
-3avw,2012-01-18,2011-03-08
-3avx,2012-01-18,2011-03-08
-2avs,2006-01-24,2005-08-30
-3avj,2012-01-18,2011-03-05
-5avp,2016-06-29,2015-06-29
-5avn,2015-07-08,2015-06-23
-4avv,2013-06-19,2012-05-29
-5avb,2015-12-23,2015-06-12
-2avf,2005-12-20,2005-08-30
-6avs,2018-02-28,2017-09-04
-6avp,2018-09-12,2017-09-04
-4avx,2012-06-13,2012-05-30
-4avg,2012-08-22,2012-05-25
-1avh,1994-01-31,1991-10-17
-2avx,2006-06-20,2005-08-30
-4avu,2012-06-13,2012-05-29
-5avt,2015-09-02,2015-07-01
-5ave,2016-03-02,2015-06-15
-9avq,2024-04-24,2024-03-04
-2avn,2005-10-18,2005-08-30
-7av4,2021-04-21,2020-11-04
-6avk,2018-08-08,2017-09-02
-3avk,2012-01-18,2011-03-05
-4avj,2012-06-27,2012-05-26
-1av2,1998-07-01,1997-09-23
-2avv,2006-01-24,2005-08-30
-7avv,2021-03-24,2020-11-06
-7avw,2023-01-18,2020-11-06
-3avu,2012-01-18,2011-03-08
-2av6,2005-09-06,2005-08-29
-8av0,2023-04-26,2022-08-26
-8avc,2023-04-05,2022-08-26
-8avm,2023-04-19,2022-08-26
-6av2,2018-07-11,2017-09-01
-5av8,2015-12-23,2015-06-12
-2avp,2005-09-13,2005-08-30
-5avz,2015-09-02,2015-07-01
-6avo,2017-12-06,2017-09-04
-3av6,2011-05-04,2011-02-22
-4avd,2013-04-17,2012-05-25
-7av7,2020-12-30,2020-11-04
-6av1,2018-07-11,2017-09-01
-8av8,2023-09-06,2022-08-26
-6ave,2018-03-21,2017-09-02
-8avq,2023-09-06,2022-08-26
-3avn,2012-01-18,2011-03-05
-3ava,2012-01-18,2011-03-02
-8avl,2023-04-19,2022-08-26
-3ave,2011-04-06,2011-03-04
-6avl,2017-09-20,2017-09-02
-6avz,2018-05-16,2017-09-05
-5avk,2016-07-06,2015-06-17
-4avh,2012-06-27,2012-05-26
-7avl,2021-03-24,2020-11-05
-3avh,2012-01-18,2011-03-05
-4avn,2013-06-12,2012-05-28
-4avt,2013-06-19,2012-05-29
-8av4,2023-09-20,2022-08-26
-8av7,2023-09-20,2022-08-26
-3av4,2011-05-04,2011-02-22
-5avc,2015-12-23,2015-06-12
-3avs,2011-10-19,2011-03-07
-8av6,2022-12-14,2022-08-26
-5av5,2015-12-23,2015-06-11
-3av5,2011-05-04,2011-02-22
-8avz,2023-08-09,2022-08-28
-4avb,2012-07-11,2012-05-24
-5avy,2015-09-02,2015-07-01
-8avk,2023-04-19,2022-08-26
-4av6,2012-08-08,2012-05-23
-5avu,2015-09-02,2015-07-01
-5avx,2015-09-02,2015-07-01
-4avi,2012-06-27,2012-05-26
-6avt,2018-08-15,2017-09-04
-7avs,2021-03-24,2020-11-06
-3avp,2011-08-17,2011-03-06
-9avk,2024-05-08,2024-03-04
-8avi,2023-07-12,2022-08-26
-3avo,2011-08-17,2011-03-06
-2avq,2006-01-24,2005-08-30
-6av9,2018-01-17,2017-09-01
-5av4,2015-10-07,2015-06-10
-8avh,2023-07-12,2022-08-26
-3avm,2012-01-18,2011-03-05
-2avm,2006-01-24,2005-08-30
-7av2,2021-02-17,2020-11-03
-2av8,1998-10-28,1997-09-30
-2avo,2006-01-24,2005-08-30
-6av7,2018-07-11,2017-09-01
-7avt,2021-03-24,2020-11-06
-6av0,2018-07-11,2017-09-01
-2av1,2005-10-18,2005-08-29
-8avn,2023-04-19,2022-08-26
-6av6,2018-07-11,2017-09-01
-3av9,2012-01-18,2011-03-02
-9avs,2024-04-17,2024-03-04
-4avq,2012-08-22,2012-05-29
-7avy,2021-03-03,2020-11-06
-4avw,2012-06-13,2012-05-29
-4avk,2012-06-27,2012-05-26
-1avf,1998-02-25,1997-09-16
-1av4,1998-03-25,1997-09-24
-1ave,1994-01-31,1993-03-05
-2av0,2006-03-28,2005-08-29
-1avl,1998-03-18,1997-09-17
-8avp,2023-04-12,2022-08-26
-6avm,2018-08-15,2017-09-03
-1avc,1998-01-28,1997-09-16
-8avv,2022-12-21,2022-08-27
-7avd,2020-12-02,2020-11-05
-5avq,2015-09-02,2015-07-01
-2avi,1993-07-15,1993-04-23
-9av7,2024-03-13,2024-03-01
-1avd,1994-01-31,1993-03-05
-8av9,2023-05-24,2022-08-26
-6avh,2018-02-14,2017-09-02
-4ava,2012-07-11,2012-05-24
-4avl,2012-08-22,2012-05-28
-5avs,2015-09-02,2015-07-01
-7avq,2020-11-18,2020-11-05
-8avy,2023-09-06,2022-08-27
-3avq,2011-08-17,2011-03-06
-5av2,2015-10-07,2015-06-10
-4av5,2012-06-27,2012-05-23
-7avc,2021-02-10,2020-11-05
-5av3,2015-10-07,2015-06-10
-3avg,2012-01-18,2011-03-05
-1av6,1998-02-25,1997-09-26
-1av7,1998-04-01,1997-09-29
-5av0,2015-10-07,2015-06-10
-4av4,2012-06-27,2012-05-23
-5av6,2015-12-23,2015-06-12
-6avi,2018-09-12,2017-09-02
-3avb,2012-01-18,2011-03-02
-8av3,2023-09-20,2022-08-26
-6av4,2018-07-11,2017-09-01
-5avw,2015-09-02,2015-07-01
-6av3,2018-07-11,2017-09-01
-1avm,1998-03-18,1997-09-17
-2avd,2005-09-13,2005-08-29
-7av0,2021-02-17,2020-11-03
-3av7,2012-03-07,2011-02-23
-7ava,2021-04-28,2020-11-05
-3avy,2012-01-18,2011-03-08
-8av2,2023-04-05,2022-08-26
-3avl,2012-01-18,2011-03-05
-4avo,2013-06-12,2012-05-28
-6avb,2018-01-17,2017-09-01
-4avc,2012-07-11,2012-05-24
-7avz,2021-03-03,2020-11-06
-5avl,2015-08-26,2015-06-17
-8avw,2022-12-21,2022-08-27
-2av3,2006-03-28,2005-08-29
-3av3,2012-03-07,2011-02-18
-7av1,2021-02-17,2020-11-03
-5ava,2016-04-27,2015-06-12
-4av0,2012-06-27,2012-05-23
-8avx,2022-12-21,2022-08-27
-1avr,1994-01-31,1991-10-17
-7av5,2021-03-03,2020-11-04
-4av1,2012-06-13,2012-05-23
-5av7,2016-04-27,2015-06-12
-3avt,2012-01-18,2011-03-08
-8avd,2023-04-05,2022-08-26
-3avr,2011-10-19,2011-03-07
-5av9,2015-12-23,2015-06-12
-3avz,2011-12-14,2011-03-09
-8av5,2023-08-02,2022-08-26
-1avt,1998-03-25,1997-09-19
-3avi,2012-02-15,2011-03-05
-3avv,2012-01-18,2011-03-08
-7k6x,2020-12-23,2020-09-21
-7k6s,2020-12-09,2020-09-21
-7k6m,2021-01-06,2020-09-21
-1k6m,2002-12-11,2001-10-16
-4k6t,2014-10-22,2013-04-16
-7k6r,2020-12-09,2020-09-21
-7k6z,2020-12-23,2020-09-21
-3k6h,2009-10-27,2009-10-08
-8k66,2024-04-03,2023-07-25
-7k62,2021-03-17,2020-09-18
-4k6f,2013-05-15,2013-04-15
-7k66,2020-10-14,2020-09-18
-5k6y,2016-09-28,2016-05-25
-5k6n,2016-10-05,2016-05-25
-3k6a,2009-10-20,2009-10-08
-7k6g,2021-09-29,2020-09-20
-4k6y,2014-01-22,2013-04-16
-2k6z,2008-09-09,2008-07-28
-6k67,2019-08-14,2019-06-01
-4k6o,2014-05-07,2013-04-16
-5k61,2017-04-19,2016-05-24
-1k6c,2002-02-06,2001-10-15
-6k60,2019-11-27,2019-05-31
-4k6z,2013-10-02,2013-04-16
-3k64,2009-11-03,2009-10-08
-7k6o,2021-01-06,2020-09-21
-1k6r,2003-06-24,2001-10-17
-2k60,2008-10-07,2008-07-02
-3k6i,2010-03-02,2009-10-08
-4k60,2013-05-29,2013-04-15
-5k6t,2017-02-08,2016-05-25
-5k6o,2016-10-05,2016-05-25
-4k65,2013-05-22,2013-04-15
-1k6x,2002-02-20,2001-10-17
-7k6e,2020-09-30,2020-09-19
-7k6c,2021-03-17,2020-09-19
-4k6a,2013-05-01,2013-04-15
-5k60,2017-01-11,2016-05-24
-6k61,2019-10-09,2019-05-31
-4k6i,2013-11-13,2013-04-15
-1k6n,2002-08-07,2001-10-16
-7k6v,2022-03-02,2020-09-21
-3k6j,2010-10-13,2009-10-09
-8k6d,2024-06-05,2023-07-25
-3k6p,2010-10-20,2009-10-09
-3k6n,2009-11-17,2009-10-09
-7k6n,2021-01-06,2020-09-21
-7k6h,2021-09-22,2020-09-20
-5k6x,2016-09-28,2016-05-25
-4k6w,2014-10-22,2013-04-16
-7k6i,2020-12-23,2020-09-20
-1k6v,2002-02-06,2001-10-17
-1k6w,2002-02-06,2001-10-17
-5k6z,2016-09-28,2016-05-25
-5k6e,2017-05-31,2016-05-24
-6k6v,2020-08-19,2019-06-05
-6k6j,2020-06-03,2019-06-03
-5k6w,2016-09-28,2016-05-25
-4k6v,2014-10-22,2013-04-16
-3k62,2009-11-03,2009-10-08
-7k6j,2020-12-23,2020-09-20
-5k6a,2017-03-22,2016-05-24
-7k6p,2021-02-10,2020-09-21
-4k6r,2014-04-16,2013-04-16
-5k67,2016-07-20,2016-05-24
-7k69,2021-03-17,2020-09-19
-5k6v,2016-09-28,2016-05-25
-4k64,2013-05-22,2013-04-15
-7k68,2021-03-17,2020-09-19
-4k6b,2013-08-28,2013-04-15
-7k6u,2020-12-23,2020-09-21
-1k63,2003-08-26,2001-10-15
-7k64,2021-05-26,2020-09-18
-5k6u,2016-09-28,2016-05-25
-8k65,2023-11-15,2023-07-25
-1k6p,2002-02-06,2001-10-16
-3k6b,2009-11-10,2009-10-08
-5k6j,2017-05-31,2016-05-24
-3k6s,2010-01-12,2009-10-09
-5k6q,2017-05-31,2016-05-25
-5k66,2017-01-11,2016-05-24
-5k68,2016-07-20,2016-05-24
-5k6k,2016-07-06,2016-05-24
-5k6b,2016-08-31,2016-05-24
-7k6k,2020-12-23,2020-09-20
-1k6s,2003-06-24,2001-10-17
-1k6e,2003-08-19,2001-10-16
-3k60,2010-08-18,2009-10-08
-3k6d,2010-03-02,2009-10-08
-1k6l,2002-08-07,2001-10-16
-4k62,2013-05-22,2013-04-15
-1k6t,2002-02-06,2001-10-17
-7k6d,2020-09-30,2020-09-19
-8k6j,2024-05-22,2023-07-25
-1k68,2003-12-16,2001-10-15
-1k6y,2001-12-21,2001-10-17
-8k6k,2024-05-22,2023-07-25
-4k69,2013-05-29,2013-04-15
-2k62,2008-11-04,2008-07-03
-7k6t,2020-12-23,2020-09-21
-5k64,2017-09-06,2016-05-24
-4k66,2013-05-22,2013-04-15
-7k6l,2020-12-23,2020-09-21
-2k61,2009-05-05,2008-07-02
-6k6k,2020-06-03,2019-06-03
-1k6d,2002-06-26,2001-10-15
-3k61,2009-11-03,2009-10-08
-4k67,2013-05-22,2013-04-15
-6k6i,2020-06-03,2019-06-03
-4k6m,2013-08-28,2013-04-16
-5k62,2017-01-11,2016-05-24
-4k6u,2014-10-22,2013-04-16
-4k63,2013-05-22,2013-04-15
-4k6d,2013-04-24,2013-04-15
-5k6i,2016-08-17,2016-05-24
-3k6q,2009-10-27,2009-10-09
-8k69,2024-04-03,2023-07-25
-7k65,2021-03-17,2020-09-18
-5k6m,2016-10-05,2016-05-25
-7k6q,2021-02-10,2020-09-21
-5k69,2016-11-09,2016-05-24
-6k6s,2020-10-07,2019-06-04
-8k6y,2023-11-15,2023-07-25
-6k63,2019-07-31,2019-06-01
-8k6l,2023-09-13,2023-07-25
-5k6r,2017-02-08,2016-05-25
-3k6l,2009-11-10,2009-10-09
-4k6n,2013-07-10,2013-04-16
-7k6a,2021-03-17,2020-09-19
-6k6t,2020-06-17,2019-06-04
-6k6w,2020-10-07,2019-06-05
-5k65,2017-09-06,2016-05-24
-5k63,2017-01-11,2016-05-24
-4k6e,2013-08-21,2013-04-15
-7l6d,2021-06-23,2020-12-23
-3l61,2010-04-21,2009-12-22
-7l68,2021-02-03,2020-12-23
-1l6s,2002-04-17,2002-03-13
-4l6h,2014-03-05,2013-06-12
-4l61,2014-03-05,2013-06-11
-7l6s,2021-01-13,2020-12-23
-4l68,2014-03-05,2013-06-12
-5l6b,2016-11-09,2016-05-28
-6l66,2020-11-04,2019-10-28
-2l65,2011-03-02,2010-11-15
-2l6m,2011-08-24,2010-11-23
-1l6m,2003-03-11,2002-03-11
-5l6f,2016-09-21,2016-05-30
-3l6c,2010-01-26,2009-12-23
-5l6k,2017-03-01,2016-05-30
-6l6e,2020-09-02,2019-10-28
-6l69,2020-09-23,2019-10-28
-1l6r,2003-01-21,2002-03-13
-6l6i,2020-11-04,2019-10-29
-5l66,2016-11-09,2016-05-28
-3l6q,2010-02-02,2009-12-24
-5l61,2016-11-09,2016-05-28
-5l6n,2017-03-29,2016-05-30
-7l6n,2021-05-26,2020-12-23
-6l6x,2020-03-04,2019-10-29
-5l6e,2016-10-12,2016-05-29
-5l6h,2017-06-14,2016-05-30
-3l62,2010-04-21,2009-12-22
-4l6o,2014-03-05,2013-06-12
-5l6i,2017-06-14,2016-05-30
-2l6z,2011-08-31,2010-12-01
-7l61,2021-02-03,2020-12-23
-2l61,2011-05-25,2010-11-12
-6l6a,2020-03-04,2019-10-28
-6l68,2020-03-04,2019-10-28
-1l6z,2002-09-14,2002-03-14
-4l63,2013-11-27,2013-06-11
-5l6p,2016-08-10,2016-05-30
-7l6o,2021-04-14,2020-12-23
-7l62,2021-02-03,2020-12-23
-4l6v,2014-02-05,2013-06-13
-7l64,2021-02-03,2020-12-23
-4l6b,2014-06-18,2013-06-12
-7l69,2022-01-05,2020-12-23
-7l6x,2021-06-30,2020-12-24
-1l6i,2002-04-10,2002-03-11
-6l65,2020-11-04,2019-10-28
-3l66,2010-03-23,2009-12-23
-4l6s,2013-08-07,2013-06-12
-5l6c,2016-11-09,2016-05-28
-2l6l,2011-12-07,2010-11-23
-7l6h,2021-02-03,2020-12-23
-5l6x,2017-06-28,2016-06-01
-4l6g,2013-07-24,2013-06-12
-5l63,2016-11-09,2016-05-28
-5l6v,2016-09-07,2016-05-31
-4l64,2014-03-05,2013-06-11
-7l63,2021-02-03,2020-12-23
-6l67,2020-03-04,2019-10-28
-6l6l,2019-11-20,2019-10-29
-5l6a,2016-11-09,2016-05-28
-6l6j,2020-08-12,2019-10-29
-4l6z,2014-02-19,2013-06-13
-7l6j,2021-12-01,2020-12-23
-3l6t,2010-05-19,2009-12-24
-6l6r,2020-10-28,2019-10-29
-2l6j,2011-12-28,2010-11-22
-5l6s,2016-09-07,2016-05-31
-5l62,2016-11-09,2016-05-28
-5l60,2016-11-09,2016-05-28
-5l6z,2017-06-21,2016-06-01
-5l6g,2016-09-21,2016-05-30
-3l63,2010-04-21,2009-12-22
-7l6a,2021-02-03,2020-12-23
-5l65,2016-11-09,2016-05-28
-3l68,2010-03-23,2009-12-23
-5l69,2016-11-09,2016-05-28
-7l67,2021-02-03,2020-12-23
-4l6t,2013-11-06,2013-06-12
-7l6c,2021-01-13,2020-12-23
-5l6q,2017-05-31,2016-05-31
-5l6d,2016-10-12,2016-05-29
-4l6d,2013-11-13,2013-06-12
-5l6w,2016-06-08,2016-05-31
-3l6r,2010-01-26,2009-12-24
-5l64,2016-11-09,2016-05-28
-2l6x,2011-11-09,2010-11-29
-5l6o,2016-08-10,2016-05-30
-1l6g,2002-06-05,2002-03-10
-5l6t,2017-06-21,2016-05-31
-4l66,2013-06-26,2013-06-12
-6l6n,2021-01-13,2019-10-29
-6l6w,2020-03-04,2019-10-29
-4l6q,2013-10-02,2013-06-12
-4l6a,2014-02-12,2013-06-12
-6l6c,2020-03-04,2019-10-28
-1l6j,2002-07-03,2002-03-11
-5l6j,2017-06-14,2016-05-30
-6l63,2020-09-02,2019-10-26
-6l64,2020-03-04,2019-10-28
-4l6i,2014-06-25,2013-06-12
-1l6o,2003-06-03,2002-03-11
-6l6b,2020-03-04,2019-10-28
-7l6r,2021-01-06,2020-12-23
-3l6b,2010-01-26,2009-12-23
-4l65,2014-03-05,2013-06-12
-3l67,2010-03-23,2009-12-23
-3l6i,2010-01-26,2009-12-23
-7l6v,2021-12-22,2020-12-24
-5l68,2016-11-09,2016-05-28
-4l6c,2014-09-10,2013-06-12
-7l6t,2021-01-06,2020-12-23
-6l6d,2020-03-04,2019-10-28
-6l6k,2020-11-04,2019-10-29
-1l6f,2002-06-05,2002-03-09
-6l6o,2020-11-11,2019-10-29
-3l6j,2010-05-12,2009-12-23
-7l65,2021-02-03,2020-12-23
-1l6y,2002-04-17,2002-03-14
-3l6n,2010-04-14,2009-12-23
-5l67,2016-11-09,2016-05-28
-3l6p,2010-03-02,2009-12-23
-3l65,2010-03-23,2009-12-23
-7l6e,2021-02-03,2020-12-23
-2l6y,2011-08-31,2010-12-01
-2l62,2011-05-25,2010-11-12
-7l6g,2021-05-26,2020-12-23
-6l6q,2019-11-20,2019-10-29
-7l66,2021-02-03,2020-12-23
-7nlr,2021-06-30,2021-02-22
-6nl8,2019-01-23,2019-01-08
-1nly,2003-05-06,2003-01-08
-1nlp,1997-01-27,1996-08-04
-6nlv,2020-01-15,2019-01-09
-3nlm,2010-11-03,2010-06-21
-7nlk,2022-09-07,2021-02-22
-5nlq,2017-11-01,2017-04-04
-1nlx,2003-01-21,2003-01-07
-7nle,2021-06-09,2021-02-22
-4nl8,2014-01-08,2013-11-13
-5nld,2018-02-14,2017-04-04
-1nlm,2003-02-11,2003-01-07
-1nl7,2004-04-06,2003-01-06
-7nla,2021-06-09,2021-02-22
-3nlf,2010-11-03,2010-06-21
-4nlq,2014-01-22,2013-11-14
-6nlq,2020-01-15,2019-01-08
-6nlg,2019-05-08,2019-01-08
-5nls,2017-11-01,2017-04-04
-3nlx,2011-01-19,2010-06-21
-1nlt,2004-01-13,2003-01-07
-3nls,2011-09-07,2010-06-21
-1nl5,2003-08-12,2003-01-06
-4nlt,2014-01-22,2013-11-14
-1nl1,2003-09-16,2003-01-06
-4nlz,2014-01-22,2013-11-14
-7nlt,2021-06-30,2021-02-22
-4nlk,2014-01-22,2013-11-14
-2nli,2007-10-23,2006-10-20
-4nls,2014-01-22,2013-11-14
-7nls,2021-06-30,2021-02-22
-3nly,2011-01-19,2010-06-21
-3nlj,2010-11-03,2010-06-21
-4nl4,2014-01-08,2013-11-13
-6nli,2019-05-08,2019-01-08
-7nl5,2021-04-28,2021-02-22
-2nlr,1999-11-10,1998-11-02
-6nl6,2019-01-23,2019-01-08
-7nlu,2021-06-30,2021-02-22
-4nln,2014-01-22,2013-11-14
-5nlr,2017-11-01,2017-04-04
-4nlx,2014-01-22,2013-11-14
-3nlc,2010-08-18,2010-06-21
-5nlk,2018-02-21,2017-04-04
-6nl5,2020-01-15,2019-01-08
-7nlq,2021-06-30,2021-02-22
-4nlu,2014-01-22,2013-11-14
-6nle,2020-01-15,2019-01-08
-6nl7,2019-01-23,2019-01-08
-7nlm,2022-09-07,2021-02-22
-5nlt,2017-11-01,2017-04-04
-7nlp,2021-06-30,2021-02-22
-4nld,2014-03-19,2013-11-14
-2nlq,2006-10-31,2006-10-20
-1nl0,2004-01-20,2003-01-06
-6nlz,2020-01-15,2019-01-10
-7nl7,2021-10-27,2021-02-22
-4nlg,2014-01-22,2013-11-14
-3nli,2010-11-03,2010-06-21
-3nl1,2011-07-13,2010-06-21
-5nll,1997-03-12,1996-12-23
-3nlu,2011-01-19,2010-06-21
-7nl4,2021-11-03,2021-02-22
-3nlq,2010-11-03,2010-06-21
-3nlz,2011-01-19,2010-06-21
-5nle,2018-02-14,2017-04-04
-1nlq,2003-03-01,2003-01-07
-3nlk,2010-11-03,2010-06-21
-7nlz,2021-06-30,2021-02-22
-6nla,2019-01-23,2019-01-08
-3nl3,2010-11-10,2010-06-21
-1nl2,2003-09-16,2003-01-06
-3nlv,2011-01-19,2010-06-21
-5nlj,2017-04-26,2017-04-04
-1nlo,1997-01-27,1996-08-04
-5nln,2017-11-01,2017-04-04
-3nlp,2010-11-03,2010-06-21
-6nlx,2019-01-23,2019-01-09
-5nlp,2017-11-01,2017-04-04
-1nl9,2003-04-08,2003-01-06
-7nlx,2021-06-30,2021-02-22
-7nl2,2021-06-09,2021-02-22
-4nll,1997-03-12,1996-12-16
-5nlh,2018-02-14,2017-04-04
-5nl5,2017-04-26,2017-04-04
-1nlu,2004-01-20,2003-01-07
-3nlo,2010-11-03,2010-06-21
-6nlb,2019-01-23,2019-01-08
-2nly,2006-11-07,2006-10-20
-5nl4,2017-04-26,2017-04-04
-6nlt,2020-01-29,2019-01-09
-1nls,1997-11-26,1997-01-28
-3nlr,2010-11-03,2010-06-21
-3nle,2010-11-03,2010-06-21
-3nlh,2010-11-03,2010-06-21
-4nlp,2014-01-22,2013-11-14
-7nll,2022-02-02,2021-02-22
-5nlm,2018-01-31,2017-04-04
-1nlj,2003-01-14,2003-01-07
-7nly,2021-06-30,2021-02-22
-7nlv,2022-03-02,2021-02-22
-6nl4,2020-01-15,2019-01-07
-6nlf,2019-05-08,2019-01-08
-3nlg,2010-11-03,2010-06-21
-7nl1,2022-03-02,2021-02-22
-3nll,1997-03-12,1996-12-10
-5nlf,2017-05-03,2017-04-04
-3nlt,2011-01-19,2010-06-21
-4nl9,2014-07-16,2013-11-13
-1nlv,2003-01-21,2003-01-07
-3nl7,2010-07-14,2010-06-21
-3nlb,2011-05-18,2010-06-21
-5nli,2017-05-03,2017-04-04
-6nlh,2019-06-19,2019-01-08
-4nly,2014-01-22,2013-11-14
-4nlw,2014-01-22,2013-11-14
-7nl8,2022-03-02,2021-02-22
-3nln,2010-11-03,2010-06-21
-2nl9,2007-03-27,2006-10-19
-6nlj,2019-05-08,2019-01-08
-4nlv,2014-01-22,2013-11-14
-3nld,2010-11-03,2010-06-21
-1nl4,2003-02-11,2003-01-06
-6nl0,2020-01-08,2019-01-07
-7nlw,2021-06-30,2021-02-22
-5nlx,2017-09-27,2017-04-05
-1nl6,2003-01-14,2003-01-06
-5nl7,2018-05-16,2017-04-04
-6nl9,2019-01-23,2019-01-08
-6nlk,2019-05-08,2019-01-08
-3nl5,2010-11-10,2010-06-21
-2nll,1997-03-12,1996-11-20
-7nld,2021-08-11,2021-02-22
-4nl0,2014-11-19,2013-11-13
-5nlo,2017-11-01,2017-04-04
-4nl1,2014-05-14,2013-11-13
-1nlk,1994-05-31,1994-03-01
-3nl0,2011-07-13,2010-06-21
-6nln,2019-05-08,2019-01-08
-7nlo,2021-06-30,2021-02-22
-4nlr,2014-01-22,2013-11-14
-6nlr,2019-12-25,2019-01-09
-6nll,2019-05-08,2019-01-08
-7nl6,2021-10-27,2021-02-22
-7nln,2021-06-30,2021-02-22
-4nl5,2014-06-25,2013-11-13
-6nlm,2019-05-08,2019-01-08
-3nlw,2011-01-19,2010-06-21
-3nl6,2010-11-10,2010-06-21
-4nlo,2014-01-22,2013-11-14
-2nlj,2007-05-15,2006-10-20
-1nli,2003-01-21,2003-01-07
-4nl3,2014-09-10,2013-11-13
-8c44,2023-08-16,2022-12-31
-7c4i,2020-07-08,2020-05-18
-8c4g,2023-08-02,2023-01-03
-1c4d,2000-01-03,1999-06-04
-2c4c,2005-10-26,2005-10-18
-3c4e,2008-02-26,2008-01-29
-7c4a,2020-06-03,2020-05-15
-1c4u,2000-09-27,1999-09-25
-8c4p,2023-06-07,2023-01-04
-3c4n,2008-02-26,2008-01-30
-4c4i,2013-12-04,2013-09-05
-8c4c,2024-01-17,2023-01-03
-3c4t,2008-02-19,2008-01-30
-2c42,2006-12-20,2005-10-14
-6c4v,2018-01-31,2018-01-12
-2c4e,2006-08-30,2005-10-18
-4c4b,2014-07-23,2013-09-03
-1c4g,1999-08-27,1999-08-24
-6c4m,2018-04-11,2018-01-12
-5c40,2016-06-15,2015-06-17
-4c4d,2014-01-08,2013-09-05
-5c4d,2015-09-23,2015-06-18
-8c4t,2023-06-07,2023-01-04
-6c4p,2018-04-25,2018-01-12
-1c40,1999-08-09,1999-08-03
-1c41,2000-08-06,1999-08-03
-6c49,2018-01-24,2018-01-11
-3c4x,2008-03-11,2008-01-30
-6c4o,2018-04-18,2018-01-12
-2c40,2007-02-27,2005-10-13
-7c4m,2020-12-02,2020-05-18
-6c4h,2018-02-21,2018-01-12
-5c4q,2015-07-08,2015-06-18
-4c4g,2013-12-04,2013-09-05
-6c4j,2018-05-16,2018-01-12
-1c4q,2000-09-20,1999-08-31
-4c4z,2014-10-01,2013-09-09
-2c4d,2006-01-23,2005-10-18
-6c4x,2018-08-15,2018-01-13
-4c4x,2014-10-01,2013-09-09
-2c4w,2006-02-22,2005-10-24
-5c41,2016-06-15,2015-06-17
-6c46,2018-02-14,2018-01-11
-4c43,2013-12-25,2013-08-29
-2c44,2006-06-28,2005-10-15
-7c4l,2020-12-02,2020-05-18
-5c47,2015-09-23,2015-06-17
-6c4c,2018-06-06,2018-01-11
-8c41,2024-01-10,2022-12-30
-5c4v,2016-10-12,2015-06-18
-4c4y,2014-10-01,2013-09-09
-4c4e,2013-12-04,2013-09-05
-4c48,2014-04-30,2013-09-02
-4c4s,2014-07-16,2013-09-09
-5c4a,2015-08-26,2015-06-17
-3c4z,2008-03-11,2008-01-30
-5c4w,2015-08-26,2015-06-18
-3c4w,2008-03-11,2008-01-30
-2c4t,2007-03-27,2005-10-22
-4c4c,2014-01-08,2013-09-05
-3c4m,2008-04-08,2008-01-30
-5c4n,2015-12-09,2015-06-18
-2c47,2005-11-07,2005-10-16
-3c4v,2008-04-01,2008-01-30
-2c4h,2006-06-14,2005-10-19
-8c4r,2023-06-07,2023-01-04
-8c47,2024-03-06,2023-01-02
-2c43,2005-10-24,2005-10-14
-8c4l,2024-01-17,2023-01-04
-4c4h,2013-12-04,2013-09-05
-2c4j,2005-10-26,2005-10-20
-5c4g,2016-01-20,2015-06-18
-6c4w,2018-02-07,2018-01-13
-8c4u,2023-06-07,2023-01-04
-7c40,2021-05-19,2020-05-14
-5c4e,2015-09-23,2015-06-18
-2c4n,2006-01-26,2005-10-20
-4c4a,2014-07-02,2013-09-02
-8c40,2023-12-27,2022-12-30
-3c4u,2008-08-26,2008-01-30
-3c4c,2008-02-26,2008-01-29
-5c4u,2015-12-16,2015-06-18
-5c4f,2015-09-23,2015-06-18
-4c44,2014-09-17,2013-08-30
-1c4a,1999-12-22,1999-08-13
-2c4m,2007-02-27,2005-10-20
-1c4v,2000-09-27,1999-09-25
-5c44,2015-08-26,2015-06-17
-3c4j,2009-02-03,2008-01-30
-5c4j,2015-08-26,2015-06-18
-4c4r,2014-07-16,2013-09-09
-7c4b,2021-04-07,2020-05-15
-5c4h,2015-07-15,2015-06-18
-4c4o,2014-07-16,2013-09-06
-7c43,2021-04-07,2020-05-14
-5c4x,2015-08-26,2015-06-18
-2c4l,2007-03-27,2005-10-20
-6c4a,2018-06-06,2018-01-11
-5c4s,2015-12-16,2015-06-18
-7c4u,2020-08-12,2020-05-18
-6c4d,2018-03-21,2018-01-11
-4c4j,2013-12-04,2013-09-05
-8c4y,2023-08-30,2023-01-05
-3c4h,2008-02-12,2008-01-30
-5c4m,2016-06-29,2015-06-18
-5c46,2016-01-20,2015-06-17
-7c49,2020-06-03,2020-05-15
-5c4t,2015-12-16,2015-06-18
-5c4b,2015-09-23,2015-06-17
-8c4d,2023-12-13,2023-01-03
-5c4k,2016-02-03,2015-06-18
-8c4j,2023-06-07,2023-01-04
-5c42,2015-11-11,2015-06-17
-6c40,2018-10-17,2018-01-11
-6c42,2018-02-14,2018-01-11
-2c4i,2006-07-05,2005-10-19
-8c4w,2023-11-22,2023-01-05
-2c4r,2005-10-25,2005-10-21
-6c4s,2019-01-23,2018-01-12
-5c4o,2015-12-16,2015-06-18
-6c4k,2018-05-16,2018-01-12
-6c4i,2018-02-21,2018-01-12
-2c4x,2005-10-27,2005-10-25
-1c4y,2000-10-09,1999-10-05
-7c47,2021-04-07,2020-05-15
-3c45,2008-04-22,2008-01-29
-1c4c,1999-12-22,1999-08-16
-7c44,2020-06-17,2020-05-15
-5c4l,2016-02-03,2015-06-18
-8c4n,2023-06-07,2023-01-04
-4c4p,2013-09-18,2013-09-07
-7c4v,2020-08-12,2020-05-18
-4c4t,2014-07-16,2013-09-09
-2c4f,2006-10-18,2005-10-18
-8c42,2023-12-27,2022-12-30
-7c4h,2020-12-09,2020-05-17
-4c49,2014-10-01,2013-09-02
-3c41,2009-02-03,2008-01-29
-8c48,2024-05-22,2023-01-03
-4c4f,2013-12-04,2013-09-05
-6c4n,2018-04-11,2018-01-12
-2c4g,2005-11-23,2005-10-19
-2c4a,2007-03-27,2005-10-17
-8c49,2023-07-19,2023-01-03
-4c4u,2014-08-06,2013-09-09
-8c4o,2023-06-07,2023-01-04
-8c46,2023-09-06,2023-01-02
-5c4p,2016-07-13,2015-06-18
-3c4q,2008-04-01,2008-01-30
-5c49,2015-09-23,2015-06-17
-3c4a,2008-02-05,2008-01-29
-6c4t,2018-04-11,2018-01-12
-7c45,2021-04-07,2020-05-15
-7c4c,2021-04-07,2020-05-15
-8c4e,2024-01-17,2023-01-03
-6c4g,2018-06-13,2018-01-11
-6c4u,2018-05-30,2018-01-12
-3c4f,2008-02-26,2008-01-29
-1c4k,2000-02-26,1999-08-26
-7c4k,2020-12-02,2020-05-18
-7c41,2021-05-19,2020-05-14
-2c49,2006-08-30,2005-10-17
-8c4v,2023-06-07,2023-01-04
-8c4m,2023-06-07,2023-01-04
-5c4z,2015-07-15,2015-06-18
-5c4i,2015-07-01,2015-06-18
-5c4c,2015-09-23,2015-06-18
-5c48,2015-09-23,2015-06-17
-7c4n,2020-12-02,2020-05-18
-1c47,1999-08-13,1999-08-11
-8c43,2023-12-27,2022-12-30
-7c42,2021-04-07,2020-05-14
-4c4m,2013-10-02,2013-09-05
-3c49,2008-02-12,2008-01-29
-8c4f,2023-08-02,2023-01-03
-3c43,2008-04-22,2008-01-29
-7g8v,2023-07-12,2023-06-22
-7g8r,2023-07-12,2023-06-22
-4g87,2013-03-13,2012-07-22
-4g89,2012-09-19,2012-07-23
-6g8e,2019-04-24,2018-04-08
-6g8f,2018-10-10,2018-04-08
-8g82,2024-01-24,2023-02-17
-2g82,2007-03-13,2006-03-01
-1g8w,2000-12-13,2000-11-21
-3g8i,2009-06-02,2009-02-12
-8g84,2023-08-09,2023-02-17
-6g8r,2018-04-18,2018-04-09
-1g8m,2001-04-27,2000-11-17
-1g8o,2001-05-20,2000-11-20
-7g81,2023-07-12,2023-06-22
-4g8r,2013-12-25,2012-07-23
-4g8p,2012-10-31,2012-07-23
-6g8h,2019-04-17,2018-04-08
-4g8j,2013-07-24,2012-07-23
-3g8q,2009-05-26,2009-02-12
-8g89,2023-08-09,2023-02-17
-7g8i,2023-07-12,2023-06-22
-6g8m,2018-09-12,2018-04-09
-6g8g,2019-04-17,2018-04-08
-7g8s,2023-07-12,2023-06-22
-7g8l,2023-07-12,2023-06-22
-8g8f,2023-04-19,2023-02-17
-2g8s,2006-08-08,2006-03-03
-2g8h,2006-04-25,2006-03-02
-3g8f,2009-03-10,2009-02-12
-2g8y,2006-04-25,2006-03-03
-6g8n,2018-09-12,2018-04-09
-8g8p,2024-02-28,2023-02-18
-8g8a,2024-05-22,2023-02-17
-1g8h,2001-05-23,2000-11-17
-3g8o,2010-02-16,2009-02-12
-4g8y,2012-11-21,2012-07-23
-8g85,2023-04-19,2023-02-17
-6g8c,2019-04-24,2018-04-08
-6g8d,2019-04-24,2018-04-08
-7g86,2023-07-12,2023-06-22
-2g8a,2006-03-14,2006-03-02
-1g82,2001-03-07,2000-11-16
-4g8s,2012-08-08,2012-07-23
-4g8v,2012-11-21,2012-07-23
-7g8y,2023-07-12,2023-06-22
-2g8g,2007-01-02,2006-03-02
-2g8u,2006-04-25,2006-03-03
-3g83,2009-03-17,2009-02-11
-7g8a,2023-07-12,2023-06-22
-2g84,2006-04-04,2006-03-01
-4g8a,2012-10-17,2012-07-23
-7g8z,2023-07-12,2023-06-22
-3g8b,2009-06-30,2009-02-11
-2g8v,2006-04-25,2006-03-03
-6g8q,2019-04-17,2018-04-09
-8g8v,2024-02-21,2023-02-20
-6g80,2019-01-16,2018-04-06
-2g8r,2006-08-15,2006-03-03
-3g86,2009-09-08,2009-02-11
-3g8r,2009-04-07,2009-02-12
-7g8x,2023-07-12,2023-06-22
-7g8c,2023-07-12,2023-06-22
-6g8p,2019-04-17,2018-04-09
-6g8k,2019-04-17,2018-04-09
-7g8k,2023-07-12,2023-06-22
-2g81,2007-01-02,2006-03-01
-6g8l,2019-04-17,2018-04-09
-4g8n,2012-08-29,2012-07-23
-8g8o,2023-06-21,2023-02-18
-1g8s,2003-10-14,2000-11-20
-1g8z,2001-07-25,2000-11-21
-7g84,2023-07-12,2023-06-22
-1g8f,2001-05-23,2000-11-17
-2g8i,2006-04-25,2006-03-02
-7g8j,2023-07-12,2023-06-22
-3g8c,2009-03-03,2009-02-12
-2g8j,2006-06-06,2006-03-02
-6g8i,2019-04-17,2018-04-09
-6g8b,2018-08-01,2018-04-08
-7g82,2023-07-12,2023-06-22
-6g8a,2018-08-01,2018-04-08
-6g86,2018-10-17,2018-04-07
-4g82,2013-01-16,2012-07-20
-4g8u,2012-10-31,2012-07-23
-4g8m,2012-08-08,2012-07-23
-2g8z,2006-04-04,2006-03-04
-2g8n,2006-09-12,2006-03-02
-4g86,2012-10-24,2012-07-21
-7g8n,2023-07-12,2023-06-22
-8g8j,2024-02-21,2023-02-17
-7g85,2023-07-12,2023-06-22
-7g8g,2023-07-12,2023-06-22
-7g8e,2023-07-12,2023-06-22
-2g8k,2006-04-25,2006-03-02
-4g8o,2013-12-25,2012-07-23
-7g8u,2023-07-12,2023-06-22
-2g8t,2006-09-05,2006-03-03
-6g82,2019-03-20,2018-04-07
-3g8x,2009-04-21,2009-02-12
-3g89,2009-06-30,2009-02-11
-8g8w,2023-06-07,2023-02-20
-4g8w,2012-10-31,2012-07-23
-4g8c,2013-01-16,2012-07-23
-3g88,2009-06-30,2009-02-11
-6g8x,2018-05-30,2018-04-10
-6g8u,2019-07-31,2018-04-10
-3g8u,2009-04-21,2009-02-12
-7g8q,2023-07-12,2023-06-22
-2g8w,2006-04-25,2006-03-03
-6g88,2019-04-24,2018-04-08
-2g89,2006-03-14,2006-03-02
-4g8t,2012-08-15,2012-07-23
-1g8k,2000-12-13,2000-11-17
-4g8h,2012-08-29,2012-07-23
-3g82,2010-02-16,2009-02-11
-8g8h,2024-02-21,2023-02-17
-2g8e,2006-06-06,2006-03-02
-6g83,2018-08-01,2018-04-07
-3g8m,2009-11-10,2009-02-12
-6g81,2018-10-10,2018-04-07
-8g8z,2023-06-21,2023-02-20
-4g83,2013-01-16,2012-07-20
-1g85,2002-06-26,2000-11-16
-7g83,2023-07-12,2023-06-22
-7g88,2023-07-12,2023-06-22
-1g8j,2000-12-13,2000-11-17
-8g8c,2024-05-22,2023-02-17
-3g8a,2009-06-30,2009-02-11
-7g87,2023-07-12,2023-06-22
-7g8w,2023-07-12,2023-06-22
-4g8z,2013-05-29,2012-07-23
-2g8d,2006-03-14,2006-03-02
-4g8l,2012-10-31,2012-07-23
-6g8v,2019-07-31,2018-04-10
-7g8b,2023-07-12,2023-06-22
-2g88,2006-05-16,2006-03-02
-3g84,2009-03-17,2009-02-11
-8g8n,2024-01-17,2023-02-18
-3g8d,2009-03-03,2009-02-12
-7g89,2023-07-12,2023-06-22
-1g8t,2000-12-06,2000-11-21
-7g8h,2023-07-12,2023-06-22
-2g87,2006-09-02,2006-03-02
-2g83,2006-10-10,2006-03-01
-1g8i,2001-05-09,2000-11-17
-1g86,2002-06-19,2000-11-16
-7g8d,2023-07-12,2023-06-22
-2g8f,2006-04-25,2006-03-02
-3g8e,2009-08-18,2009-02-12
-2g86,2006-03-14,2006-03-01
-1g8g,2001-05-23,2000-11-17
-1g87,2003-07-15,2000-11-16
-7g8p,2023-07-12,2023-06-22
-7g8t,2023-07-12,2023-06-22
-2g80,2006-03-28,2006-03-01
-1g8x,2001-01-17,2000-11-21
-8g8d,2024-05-22,2023-02-17
-8g8x,2023-06-21,2023-02-20
-6g8j,2019-04-17,2018-04-09
-7g8o,2023-07-12,2023-06-22
-4g8b,2013-01-16,2012-07-23
-6g85,2018-10-17,2018-04-07
-7g8m,2023-07-12,2023-06-22
-6g84,2018-10-10,2018-04-07
-4g88,2013-07-24,2012-07-22
-7g8f,2023-07-12,2023-06-22
-3g81,2009-03-17,2009-02-11
-7g80,2023-07-12,2023-06-22
-1ide,1996-03-08,1995-01-18
-3idx,2009-11-17,2009-07-22
-1idr,2001-08-22,2001-04-05
-5idh,2017-03-15,2016-02-24
-5idw,2016-03-16,2016-02-24
-6ida,2019-11-27,2018-09-09
-3ide,2009-12-29,2009-07-21
-1id5,2001-09-05,2001-04-03
-4idk,2013-02-06,2012-12-12
-2id0,2006-10-03,2006-09-13
-5id9,2016-05-11,2016-02-24
-4idb,2013-04-17,2012-12-12
-2idj,2006-12-19,2006-09-15
-4idv,2013-04-17,2012-12-13
-5idp,2016-12-21,2016-02-24
-8id3,2023-03-15,2023-02-12
-2idz,2007-07-24,2006-09-15
-4id5,2013-02-06,2012-12-11
-2id4,2007-05-01,2006-09-14
-2idu,2007-03-13,2006-09-15
-8idd,2023-10-04,2023-02-12
-3idz,2009-08-04,2009-07-22
-6id8,2019-11-27,2018-09-09
-3id7,2010-01-12,2009-07-20
-3idh,2010-07-28,2009-07-21
-8idq,2023-05-17,2023-02-14
-6idf,2018-12-26,2018-09-09
-4idy,2013-12-18,2012-12-13
-3idb,2009-09-29,2009-07-20
-3idc,2009-09-29,2009-07-20
-3idi,2010-03-02,2009-07-21
-3idp,2009-10-06,2009-07-21
-6idv,2019-05-15,2018-09-11
-3idv,2010-07-07,2009-07-21
-3id5,2009-08-25,2009-07-20
-2idf,2008-03-18,2006-09-15
-8idy,2023-08-09,2023-02-14
-6id3,2019-11-27,2018-09-08
-8ido,2024-02-28,2023-02-14
-4idc,2013-04-17,2012-12-12
-4ide,2013-04-17,2012-12-12
-3idn,2010-02-02,2009-07-21
-6idw,2018-10-17,2018-09-11
-5idu,2016-03-09,2016-02-24
-3id0,2010-02-09,2009-07-19
-1id0,2001-10-17,2001-04-02
-8idu,2023-12-27,2023-02-14
-6idd,2019-11-27,2018-09-09
-8idt,2023-08-09,2023-02-14
-5idl,2016-10-05,2016-02-24
-6ide,2019-01-16,2018-09-09
-6idj,2019-09-11,2018-09-10
-2id2,2007-09-18,2006-09-14
-4idg,2012-12-26,2012-12-12
-2id8,2006-10-10,2006-09-14
-1ids,1994-12-20,1994-09-29
-2ids,2007-03-13,2006-09-15
-5idb,2016-07-06,2016-02-24
-3idq,2009-08-25,2009-07-21
-3ids,2009-08-11,2009-07-21
-5id0,2016-06-15,2016-02-23
-1ida,1995-01-26,1994-10-19
-5idn,2016-12-21,2016-02-24
-5id7,2016-05-11,2016-02-24
-5idt,2016-03-09,2016-02-24
-1ido,1996-08-01,1996-03-12
-4idw,2013-06-05,2012-12-13
-1idt,2003-09-16,2001-04-05
-6id4,2019-02-06,2018-09-08
-4idr,2012-12-26,2012-12-13
-6idn,2018-11-21,2018-09-10
-8id1,2024-03-27,2023-02-11
-3idm,2010-02-02,2009-07-21
-3id6,2009-08-25,2009-07-20
-8idh,2023-10-04,2023-02-13
-8id8,2023-03-15,2023-02-12
-4idq,2013-01-09,2012-12-12
-2idw,2006-10-03,2006-09-15
-5ido,2016-10-26,2016-02-24
-8idm,2024-02-28,2023-02-13
-6idy,2019-09-18,2018-09-12
-1idc,1996-03-08,1995-01-18
-4id0,2012-12-26,2012-12-11
-5idj,2016-10-05,2016-02-24
-8idp,2023-05-17,2023-02-14
-4id9,2012-12-26,2012-12-12
-5idz,2017-02-22,2016-02-24
-3idj,2010-02-02,2009-07-21
-4ido,2013-01-09,2012-12-12
-8ide,2023-07-26,2023-02-13
-5idm,2016-10-05,2016-02-24
-6idg,2019-02-13,2018-09-10
-4idz,2013-04-03,2012-12-13
-8idi,2024-02-28,2023-02-13
-5idd,2016-05-18,2016-02-24
-4id4,2013-12-25,2012-12-11
-2id3,2006-10-17,2006-09-14
-2idt,2007-03-13,2006-09-15
-6id6,2019-09-11,2018-09-08
-6id1,2019-03-13,2018-09-07
-5ida,2016-06-29,2016-02-24
-1idb,1995-01-26,1994-10-19
-2ido,2006-11-14,2006-09-15
-4id7,2013-01-30,2012-12-11
-5id1,2016-06-15,2016-02-23
-3ida,2010-03-02,2009-07-20
-4idd,2013-04-17,2012-12-12
-1id8,2001-06-27,2001-04-04
-2id5,2006-09-26,2006-09-14
-6idb,2019-11-27,2018-09-09
-3idg,2010-03-02,2009-07-21
-5idk,2016-12-14,2016-02-24
-4idt,2013-04-17,2012-12-13
-6id5,2019-11-27,2018-09-08
-4idn,2013-01-09,2012-12-12
-8idf,2023-08-09,2023-02-13
-4idf,2013-04-17,2012-12-12
-3id8,2010-07-28,2009-07-20
-2idk,2006-12-19,2006-09-15
-2idv,2007-06-12,2006-09-15
-3idy,2009-11-17,2009-07-22
-2idq,2007-03-13,2006-09-15
-2idx,2007-02-06,2006-09-15
-4idp,2013-01-09,2012-12-12
-6idz,2019-11-27,2018-09-12
-8ids,2023-05-03,2023-02-14
-6id9,2019-11-27,2018-09-09
-3idu,2009-08-04,2009-07-21
-2idl,2006-10-17,2006-09-15
-2ida,2006-10-24,2006-09-14
-5id6,2016-04-27,2016-02-24
-6id0,2019-03-13,2018-09-07
-8idn,2023-06-21,2023-02-13
-1id3,2001-09-28,2001-04-03
-5idy,2016-03-16,2016-02-24
-1id2,2001-04-11,2001-04-03
-4id1,2013-05-01,2012-12-11
-7u4l,2022-12-07,2022-02-28
-5u4u,2017-09-20,2016-12-06
-5u41,2017-03-22,2016-12-03
-7u4b,2022-05-25,2022-02-28
-4u4o,2014-10-22,2014-07-24
-1u4o,2005-06-21,2004-07-26
-8u4f,2024-02-14,2023-09-10
-4u4n,2014-10-22,2014-07-24
-3u4l,2012-04-25,2011-10-09
-3u40,2011-10-19,2011-10-06
-3u4c,2013-03-06,2011-10-07
-4u45,2014-09-03,2014-07-23
-8u4i,2024-03-13,2023-09-10
-6u4n,2019-10-23,2019-08-26
-5u4s,2017-01-18,2016-12-06
-6u4a,2020-08-19,2019-08-24
-3u4x,2012-09-12,2011-10-10
-5u4c,2017-09-27,2016-12-03
-5u4a,2017-09-27,2016-12-03
-7u4o,2022-10-05,2022-02-28
-4u4v,2015-07-15,2014-07-24
-6u4x,2019-09-04,2019-08-26
-3u4e,2011-11-30,2011-10-07
-1u4h,2004-08-31,2004-07-25
-4u4r,2014-10-22,2014-07-24
-6u4r,2019-09-04,2019-08-26
-7u4c,2023-03-08,2022-02-28
-3u4h,2012-10-10,2011-10-08
-5u4h,2016-12-14,2016-12-04
-8u4r,2024-03-13,2023-09-11
-4u4l,2014-08-20,2014-07-23
-4u4z,2014-10-22,2014-07-24
-7u4f,2022-10-19,2022-02-28
-8u4s,2024-03-13,2023-09-11
-5u40,2017-03-22,2016-12-03
-5u48,2017-09-27,2016-12-03
-8u4v,2023-10-25,2023-09-11
-3u4i,2012-10-10,2011-10-08
-6u4t,2020-01-22,2019-08-26
-4u41,2016-01-06,2014-07-23
-4u40,2016-01-06,2014-07-23
-8u47,2024-05-29,2023-09-09
-7u4z,2023-03-08,2022-03-01
-1u45,2004-09-14,2004-07-23
-4u4a,2015-08-26,2014-07-23
-6u4l,2020-07-08,2019-08-26
-7u4k,2022-12-07,2022-02-28
-3u43,2012-03-21,2011-10-07
-5u4e,2017-09-27,2016-12-03
-4u4t,2015-07-15,2014-07-24
-8u4l,2024-03-13,2023-09-10
-5u4f,2017-09-27,2016-12-03
-8u4a,2024-02-14,2023-09-10
-6u42,2019-11-13,2019-08-22
-1u49,2004-09-14,2004-07-23
-4u49,2015-08-05,2014-07-23
-5u4t,2017-11-01,2016-12-06
-5u4j,2017-01-11,2016-12-04
-4u4g,2014-10-22,2014-07-23
-8u43,2024-05-08,2023-09-08
-3u4w,2012-02-22,2011-10-10
-6u4v,2020-07-08,2019-08-26
-1u47,2004-09-14,2004-07-23
-3u4a,2013-04-10,2011-10-07
-8u49,2024-02-14,2023-09-10
-5u4i,2017-01-11,2016-12-04
-8u4q,2024-03-13,2023-09-11
-6u48,2019-09-18,2019-08-23
-7u4n,2022-12-07,2022-02-28
-1u4j,2004-08-10,2004-07-26
-7u4m,2022-12-07,2022-02-28
-4u4s,2014-11-19,2014-07-24
-6u4i,2020-09-23,2019-08-25
-3u4f,2011-10-19,2011-10-07
-8u45,2023-11-01,2023-09-08
-1u4l,2004-11-09,2004-07-26
-3u4o,2011-12-07,2011-10-10
-7u4t,2022-08-24,2022-03-01
-3u4r,2011-12-07,2011-10-10
-3u4m,2012-08-08,2011-10-10
-8u4j,2024-03-13,2023-09-10
-3u4u,2012-08-22,2011-10-10
-6u4m,2019-10-23,2019-08-26
-4u4m,2015-07-29,2014-07-24
-7u4r,2022-10-05,2022-02-28
-5u4b,2017-09-27,2016-12-03
-7u4h,2022-03-09,2022-02-28
-7u4j,2022-12-07,2022-02-28
-8u4t,2024-03-13,2023-09-11
-4u4q,2014-10-22,2014-07-24
-6u43,2020-03-18,2019-08-22
-1u4b,2004-09-14,2004-07-23
-1u48,2004-09-14,2004-07-23
-8u4n,2024-03-13,2023-09-11
-1u4m,2004-11-09,2004-07-26
-3u45,2012-10-10,2011-10-07
-6u45,2020-03-18,2019-08-22
-3u47,2012-10-10,2011-10-07
-7u4q,2023-03-15,2022-02-28
-5u4w,2017-01-11,2016-12-06
-6u4j,2020-03-04,2019-08-25
-4u43,2014-09-03,2014-07-23
-5u44,2017-03-22,2016-12-03
-7u4i,2022-12-07,2022-02-28
-4u4x,2014-11-19,2014-07-24
-5u46,2017-03-22,2016-12-03
-5u43,2017-03-22,2016-12-03
-8u4z,2024-04-24,2023-09-11
-8u4p,2024-03-13,2023-09-11
-7u48,2022-05-25,2022-02-28
-4u42,2016-01-06,2014-07-23
-4u44,2014-09-03,2014-07-23
-5u4q,2016-12-14,2016-12-05
-1u43,2004-08-31,2004-07-23
-5u49,2017-09-27,2016-12-03
-5u4g,2017-09-27,2016-12-03
-1u4s,2005-06-21,2004-07-26
-5u4p,2017-09-06,2016-12-05
-8u4w,2024-03-27,2023-09-11
-6u4s,2020-07-08,2019-08-26
-3u4j,2011-10-19,2011-10-08
-3u48,2013-04-10,2011-10-07
-4u4f,2014-08-27,2014-07-23
-1u4d,2004-08-31,2004-07-23
-4u4u,2014-10-22,2014-07-24
-3u4s,2012-02-08,2011-10-10
-1u40,2004-08-31,2004-07-23
-8u4d,2024-05-08,2023-09-10
-5u4y,2017-05-17,2016-12-06
-5u45,2017-03-22,2016-12-03
-5u42,2017-03-22,2016-12-03
-6u44,2020-03-18,2019-08-22
-7u4g,2022-10-19,2022-02-28
-7u49,2022-05-25,2022-02-28
-6u4b,2020-01-22,2019-08-25
-7u4e,2022-10-19,2022-02-28
-4u4y,2014-10-22,2014-07-24
-5u4d,2017-09-27,2016-12-03
-1u4g,2004-08-24,2004-07-25
-8u4o,2024-03-13,2023-09-11
-8u4k,2024-03-13,2023-09-10
-6u4q,2020-01-22,2019-08-26
-112m,1998-04-08,1997-12-24
-2wwn,2010-11-03,2009-10-26
-6wwu,2021-05-05,2020-05-09
-6wwv,2021-05-05,2020-05-09
-4wwp,2014-12-17,2014-11-11
-1ww6,2005-08-23,2005-01-03
-6wwn,2021-05-05,2020-05-09
-2ww1,2009-12-29,2009-10-21
-5wwx,2017-08-23,2017-01-05
-6wwm,2021-05-05,2020-05-09
-3wwg,2014-11-12,2014-06-17
-6wwf,2021-05-05,2020-05-09
-7www,2023-02-22,2022-02-14
-4wwz,2014-12-24,2014-11-13
-3ww2,2015-04-29,2014-06-13
-2wwu,2009-11-17,2009-10-29
-2wwz,2009-11-24,2009-10-30
-2ww8,2010-01-19,2009-10-22
-1wws,2006-01-24,2005-01-18
-2ww2,2009-12-29,2009-10-21
-8wwv,2024-01-03,2023-10-26
-1ww3,2005-12-13,2004-12-31
-6wwh,2021-05-05,2020-05-09
-4ww8,2015-07-01,2014-11-10
-5wwd,2017-11-15,2016-12-31
-3wwh,2015-08-12,2014-06-18
-1wwe,2005-03-22,2005-01-05
-1ww2,2005-12-13,2004-12-30
-6wwg,2021-05-05,2020-05-09
-2wwd,2010-04-21,2009-10-22
-7wwy,2023-02-15,2022-02-14
-2ww4,2010-03-09,2009-10-21
-7wwc,2023-02-15,2022-02-12
-7wwo,2022-03-09,2022-02-14
-3wwi,2015-08-19,2014-06-18
-2wwy,2009-12-29,2009-10-30
-2wwi,2010-04-21,2009-10-23
-7wwb,2022-06-22,2022-02-12
-4wwn,2014-12-17,2014-11-11
-4ww6,2015-07-01,2014-11-10
-2wwj,2010-03-09,2009-10-23
-6wwr,2021-05-05,2020-05-09
-8ww2,2024-02-14,2023-10-24
-4wwl,2014-11-26,2014-11-11
-7ww7,2022-06-01,2022-02-12
-4www,2014-12-24,2014-11-12
-2www,2009-11-17,2009-10-30
-6wwp,2021-05-05,2020-05-09
-4ww3,2015-06-17,2014-11-10
-8www,2024-06-05,2023-10-27
-4ww4,2015-02-18,2014-11-10
-7wwt,2023-02-15,2022-02-14
-4ww7,2015-03-18,2014-11-10
-7wwx,2022-03-30,2022-02-14
-5ww8,2017-08-09,2016-12-31
-4ww2,2016-02-03,2014-11-10
-5ww4,2017-08-09,2016-12-31
-7wwp,2022-09-21,2022-02-14
-3wwc,2015-04-29,2014-06-17
-7wwz,2022-06-08,2022-02-14
-4ww9,2015-03-18,2014-11-10
-8wwu,2024-01-03,2023-10-26
-7wwi,2023-02-15,2022-02-13
-1ww5,2005-08-23,2005-01-03
-7ww0,2023-02-15,2022-02-12
-1ww4,2005-08-23,2004-12-31
-3wwq,2015-05-13,2014-06-23
-6ww1,2020-10-07,2020-05-07
-2ww0,2009-12-29,2009-10-21
-5ww6,2017-08-09,2016-12-31
-6wws,2021-05-05,2020-05-09
-1wwz,2005-02-01,2005-01-19
-1wwd,2005-03-22,2005-01-05
-4wwk,2016-02-03,2014-11-11
-7wwa,2022-06-01,2022-02-12
-3wwv,2014-10-01,2014-06-30
-5www,2017-08-23,2017-01-05
-6wwe,2021-05-05,2020-05-09
-3wwo,2014-10-22,2014-06-23
-5wwr,2017-06-28,2017-01-04
-6wwj,2021-05-05,2020-05-09
-1wwk,2006-01-17,2005-01-06
-8wwy,2024-03-13,2023-10-27
-6ww4,2020-08-05,2020-05-07
-7ww6,2022-06-01,2022-02-12
-6wwb,2021-11-17,2020-05-08
-3wwr,2014-12-31,2014-06-27
-5wwj,2018-01-17,2017-01-01
-4wwh,2014-11-26,2014-11-11
-1ww1,2005-02-22,2004-12-30
-4ww5,2015-03-18,2014-11-10
-4wwu,2015-02-04,2014-11-12
-7ww5,2022-06-01,2022-02-12
-4wwy,2015-07-22,2014-11-12
-6wwi,2021-05-05,2020-05-09
-7wwj,2023-02-15,2022-02-13
-7ww4,2023-02-15,2022-02-12
-6wwx,2021-05-12,2020-05-09
-7ww2,2023-02-22,2022-02-12
-6wwc,2021-02-24,2020-05-09
-4wwd,2015-02-11,2014-11-10
-4ww0,2015-05-06,2014-11-09
-3wwt,2015-07-01,2014-06-27
-1ww9,2005-08-23,2005-01-05
-2ww3,2010-01-26,2009-10-21
-1wwg,2005-04-05,2005-01-05
-8wwo,2024-02-21,2023-10-26
-6wwl,2021-05-05,2020-05-09
-2wwf,2010-04-21,2009-10-23
-1wwr,2005-02-01,2005-01-12
-5ww5,2017-08-09,2016-12-31
-5ww3,2017-08-09,2016-12-31
-5wwg,2018-01-17,2017-01-01
-3wwn,2014-11-19,2014-06-21
-6wwq,2021-05-05,2020-05-09
-6ww0,2021-05-26,2020-05-07
-3ww3,2015-04-29,2014-06-13
-4wws,2015-02-04,2014-11-12
-6wwt,2021-05-05,2020-05-09
-7wwm,2022-06-01,2022-02-13
-2wwo,2010-11-03,2009-10-26
-7wwl,2022-06-01,2022-02-13
-2wwh,2010-04-21,2009-10-23
-5wwv,2018-01-17,2017-01-05
-4wwo,2014-12-17,2014-11-11
-5ww9,2017-08-09,2016-12-31
-3wwl,2014-11-19,2014-06-21
-7wwn,2022-04-06,2022-02-14
-5wwc,2017-04-26,2016-12-31
-4wwx,2015-02-25,2014-11-12
-1wwl,2005-02-22,2005-01-06
-3ww1,2015-04-29,2014-06-13
-7ww8,2022-06-01,2022-02-12
-3wwm,2014-11-19,2014-06-21
-3wwx,2015-07-08,2014-07-03
-7ww9,2022-06-01,2022-02-12
-4wwj,2014-12-24,2014-11-11
-1wwf,2005-04-05,2005-01-05
-6wwk,2021-05-05,2020-05-09
-3ww4,2015-04-29,2014-06-13
-5wwp,2017-07-05,2017-01-03
-6ww7,2020-05-27,2020-05-08
-7wwd,2022-07-13,2022-02-12
-3wwj,2015-08-12,2014-06-18
-2wwt,2010-09-08,2009-10-27
-5wws,2017-06-28,2017-01-04
-6ww3,2020-08-05,2020-05-07
-6ww8,2020-08-26,2020-05-08
-2wwg,2010-04-21,2009-10-23
-5ww7,2017-08-09,2016-12-31
-6wwo,2021-05-05,2020-05-09
-2wwr,2010-10-13,2009-10-26
-4wwf,2015-02-11,2014-11-10
-4wwb,2015-02-11,2014-11-10
-7d23,2021-04-14,2020-09-15
-2d2n,2005-10-25,2005-09-12
-1d2v,2000-04-24,1999-09-28
-8d2l,2023-12-20,2022-05-30
-7d2j,2021-04-14,2020-09-16
-2d2c,2005-12-13,2005-09-07
-8d20,2023-05-31,2022-05-27
-4d2r,2015-04-22,2014-05-12
-5d25,2016-01-20,2015-08-05
-8d25,2022-09-14,2022-05-27
-3d2i,2009-05-12,2008-05-08
-4d2w,2014-10-08,2014-05-13
-5d24,2016-01-20,2015-08-05
-7d2s,2021-02-24,2020-09-17
-8d22,2023-05-31,2022-05-27
-2d22,2006-10-10,2005-09-02
-5d2h,2016-05-04,2015-08-05
-7d2v,2021-03-31,2020-09-17
-6d2s,2019-04-17,2018-04-13
-6d2z,2018-09-05,2018-04-14
-6d24,2018-05-02,2018-04-12
-7d2w,2021-09-22,2020-09-17
-4d26,2014-06-18,2014-05-07
-8d2q,2023-12-20,2022-05-30
-4d2s,2015-04-22,2014-05-12
-7d2b,2021-04-14,2020-09-16
-2d24,2006-10-10,2005-09-02
-1d2i,2000-02-21,1999-09-23
-8d2k,2023-12-20,2022-05-30
-1d2e,1999-09-28,1999-09-23
-6d2v,2018-06-13,2018-04-14
-4d25,2014-06-18,2014-05-07
-6d2n,2018-09-05,2018-04-13
-7d21,2021-04-14,2020-09-15
-6d26,2018-10-03,2018-04-13
-7d26,2021-07-28,2020-09-15
-3d2r,2008-08-05,2008-05-08
-2d2h,2005-09-20,2005-09-09
-8d2y,2022-11-16,2022-05-31
-3d2l,2008-05-20,2008-05-08
-1d2a,2000-03-01,1999-09-22
-6d2b,2018-10-03,2018-04-13
-4d2v,2014-10-15,2014-05-13
-3d2m,2008-12-23,2008-05-08
-5d28,2016-11-16,2015-08-05
-2d2v,2006-09-12,2005-09-16
-6d27,2018-10-03,2018-04-13
-8d2s,2023-05-10,2022-05-30
-3d2d,2008-10-28,2008-05-08
-1d2u,2001-10-03,1999-09-28
-4d2p,2014-10-08,2014-05-12
-5d27,2016-04-20,2015-08-05
-4d2i,2014-12-03,2014-05-09
-3d20,2008-05-27,2008-05-07
-2d2j,2005-09-20,2005-09-09
-5d2i,2016-05-04,2015-08-05
-2d2g,2005-09-20,2005-09-08
-5d2g,2016-05-04,2015-08-05
-5d26,2016-01-20,2015-08-05
-3d2p,2008-12-23,2008-05-08
-5d2t,2016-09-07,2015-08-06
-8d2z,2023-07-05,2022-05-31
-3d26,2008-06-10,2008-05-07
-4d2c,2014-06-25,2014-05-09
-6d2r,2018-10-03,2018-04-13
-3d2q,2008-12-02,2008-05-08
-3d25,2009-02-10,2008-05-07
-3d2u,2008-07-08,2008-05-08
-2d23,2006-10-10,2005-09-02
-3d29,2008-06-10,2008-05-07
-2d29,2006-03-05,2005-09-05
-7d2f,2021-09-22,2020-09-16
-8d2o,2023-12-20,2022-05-30
-2d2m,2005-10-25,2005-09-12
-2d2o,2006-08-29,2005-09-13
-3d2y,2009-06-16,2008-05-09
-3d27,2008-08-19,2008-05-07
-7d24,2021-07-28,2020-09-15
-2d2d,2005-09-20,2005-09-08
-3d2k,2009-05-12,2008-05-08
-8d21,2023-04-12,2022-05-27
-1d2s,2000-06-28,1999-09-28
-3d2o,2009-05-12,2008-05-08
-3d23,2008-09-16,2008-05-07
-1d2l,2000-01-14,1999-09-24
-5d2a,2016-02-10,2015-08-05
-5d2w,2016-09-07,2015-08-06
-7d2u,2021-02-24,2020-09-17
-6d2l,2018-05-23,2018-04-13
-7d2a,2020-12-30,2020-09-16
-4d2d,2014-06-25,2014-05-09
-3d2e,2008-06-17,2008-05-08
-8d29,2022-11-30,2022-05-28
-2d2x,2006-10-03,2005-09-20
-2d2i,2006-07-11,2005-09-09
-7d2x,2021-03-31,2020-09-17
-5d2j,2016-05-04,2015-08-05
-3d2z,2009-06-16,2008-05-09
-8d24,2023-05-31,2022-05-27
-3d2n,2008-12-02,2008-05-08
-5d2n,2015-10-07,2015-08-05
-7d25,2021-07-28,2020-09-15
-2d20,2006-10-10,2005-09-02
-6d2c,2018-06-06,2018-04-13
-7d2k,2021-10-06,2020-09-16
-7d2d,2021-04-14,2020-09-16
-8d2v,2023-05-10,2022-05-30
-1d2j,2000-03-22,1999-09-23
-6d2m,2018-09-05,2018-04-13
-4d2e,2014-07-23,2014-05-09
-5d21,2015-11-25,2015-08-05
-3d2w,2009-04-07,2008-05-09
-5d2l,2015-10-07,2015-08-05
-8d2m,2023-04-12,2022-05-30
-5d2c,2016-03-09,2015-08-05
-7d2i,2021-04-14,2020-09-16
-5d2e,2015-08-26,2015-08-05
-1d2h,1999-10-25,1999-10-11
-2d2f,2005-10-25,2005-09-08
-3d2f,2008-06-17,2008-05-08
-7d22,2021-07-28,2020-09-15
-6d2t,2018-10-03,2018-04-13
-8d2p,2023-12-20,2022-05-30
-7d2z,2021-02-17,2020-09-17
-3d2t,2008-05-20,2008-05-08
-6d20,2018-05-02,2018-04-12
-5d2b,2016-08-17,2015-08-05
-6d2y,2019-10-16,2018-04-14
-8d2n,2023-12-20,2022-05-30
-6d2o,2018-09-05,2018-04-13
-4d2z,2014-12-24,2014-10-20
-4d2y,2014-12-24,2014-10-20
-6d29,2018-10-03,2018-04-13
-7d2r,2021-06-16,2020-09-17
-5d2k,2016-05-04,2015-08-05
-1d2n,1998-10-14,1998-06-30
-5d2d,2016-03-16,2015-08-05
-3d2j,2008-10-28,2008-05-08
-6d2i,2019-03-20,2018-04-13
-8d23,2022-09-14,2022-05-27
-8d2u,2023-05-10,2022-05-30
-6d2g,2019-04-17,2018-04-13
-5d29,2016-04-27,2015-08-05
-6d2j,2018-09-05,2018-04-13
-3d2h,2008-10-28,2008-05-08
-6d2e,2019-04-17,2018-04-13
-1d2f,2000-01-12,1999-09-23
-5d2u,2016-05-04,2015-08-06
-6d28,2018-05-16,2018-04-13
-3d2s,2008-12-02,2008-05-08
-5d2r,2016-01-20,2015-08-06
-3d28,2009-05-19,2008-05-07
-4d2t,2014-10-15,2014-05-13
-7d2t,2021-02-24,2020-09-17
-7d29,2020-12-30,2020-09-16
-5d2o,2016-03-16,2015-08-05
-7xdl,2023-03-15,2022-03-27
-6xdb,2021-04-21,2020-06-10
-7xd9,2022-12-21,2022-03-26
-2xdh,2010-05-26,2010-05-02
-4xd4,2015-12-23,2014-12-19
-6xd9,2020-12-23,2020-06-10
-5xd2,2017-08-09,2017-03-24
-2xd5,2010-05-26,2010-04-29
-7xdg,2023-03-29,2022-03-27
-4xdd,2015-11-11,2014-12-19
-7xdu,2023-04-05,2022-03-28
-4xd5,2015-12-23,2014-12-19
-2xdc,2010-08-11,2010-04-30
-8xd2,2023-12-27,2023-12-10
-6xd7,2020-12-09,2020-06-10
-1xdq,2004-10-12,2004-09-07
-6xdq,2020-09-02,2020-06-11
-1xd9,2005-03-01,2004-09-05
-6xdt,2020-12-02,2020-06-11
-4xdp,2015-03-25,2014-12-19
-6xdr,2020-09-02,2020-06-11
-4xdm,2015-12-09,2014-12-19
-7xdf,2023-03-29,2022-03-27
-1xds,2004-11-23,2004-09-08
-7xdx,2023-03-29,2022-03-29
-4xdr,2015-10-14,2014-12-19
-1xd3,2004-11-23,2004-09-03
-2xd1,2010-05-26,2010-04-28
-6xd4,2021-04-21,2020-06-09
-7xdq,2023-02-08,2022-03-28
-5xdx,2018-02-07,2017-03-30
-5xdc,2017-08-09,2017-03-28
-5xd3,2017-08-09,2017-03-24
-6xdf,2021-04-21,2020-06-10
-1xd0,2004-12-07,2004-09-03
-2xda,2010-11-24,2010-04-30
-4xdg,2016-01-13,2014-12-19
-4xd2,2015-01-14,2014-12-18
-2xdo,2011-03-23,2010-05-05
-2xdm,2010-07-21,2010-05-04
-1xdj,2005-03-01,2004-09-06
-8xd4,2023-12-27,2023-12-10
-4xds,2015-02-25,2014-12-19
-2xdw,2010-06-23,2010-05-09
-5xdk,2017-12-13,2017-03-28
-4xdc,2015-11-11,2014-12-19
-4xdk,2015-03-18,2014-12-19
-2xd6,2010-08-11,2010-04-29
-2xds,2010-09-01,2010-05-07
-2xd9,2010-11-24,2010-04-30
-4xdt,2015-10-14,2014-12-19
-1xdn,2004-12-07,2004-09-07
-6xd1,2020-09-23,2020-06-09
-1xdu,2004-11-23,2004-09-08
-2xdq,2010-06-16,2010-05-06
-5xd9,2017-09-27,2017-03-27
-1xdc,2005-03-22,2004-09-05
-1xdf,2005-02-15,2004-09-06
-2xd3,2010-06-09,2010-04-28
-4xd6,2015-12-23,2014-12-19
-1xdh,2005-08-23,2004-09-06
-5xdw,2017-08-02,2017-03-30
-4xd0,2015-01-21,2014-12-18
-5xdz,2017-06-14,2017-03-30
-5xdu,2017-08-02,2017-03-30
-6xd2,2021-06-16,2020-06-09
-1xda,1997-07-07,1996-12-18
-5xdo,2017-06-28,2017-03-28
-4xd1,2015-01-21,2014-12-18
-7xde,2023-03-29,2022-03-26
-1xdi,2004-10-19,2004-09-06
-6xds,2021-02-17,2020-06-11
-7xdb,2023-03-01,2022-03-26
-2xdx,2010-09-01,2010-05-10
-7xdy,2023-03-29,2022-03-29
-8xd1,2023-12-27,2023-12-10
-1xdg,2004-09-21,2004-09-06
-5xd1,2017-08-09,2017-03-24
-8xd5,2023-12-27,2023-12-10
-2xde,2010-12-22,2010-04-30
-4xdz,2015-04-22,2014-12-20
-7xdj,2022-12-14,2022-03-27
-2xdg,2010-06-16,2010-04-30
-4xd3,2015-12-23,2014-12-19
-8xd6,2023-12-27,2023-12-10
-4xdv,2015-07-15,2014-12-20
-4xdi,2015-01-21,2014-12-19
-6xdk,2020-06-24,2020-06-10
-8xd3,2023-12-27,2023-12-10
-7xdv,2023-03-29,2022-03-29
-5xdr,2017-06-21,2017-03-29
-2xdd,2011-01-12,2010-04-30
-2xdr,2011-06-22,2010-05-06
-2xdk,2010-09-01,2010-05-04
-4xdq,2015-01-14,2014-12-19
-6xdm,2020-07-29,2020-06-11
-5xdq,2017-07-12,2017-03-29
-2xdl,2010-09-01,2010-05-04
-4xda,2015-03-04,2014-12-19
-2xdb,2011-01-12,2010-04-30
-5xdl,2017-12-13,2017-03-28
-8xd0,2023-12-27,2023-12-10
-5xdg,2017-08-09,2017-03-28
-6xdj,2021-06-16,2020-06-10
-5xdh,2018-03-28,2017-03-28
-1xd1,2004-12-07,2004-09-03
-5xd5,2017-08-09,2017-03-24
-4xdo,2015-03-25,2014-12-19
-6xdg,2020-06-24,2020-06-10
-2xd4,2011-03-23,2010-04-29
-4xdu,2015-10-14,2014-12-20
-1xdd,2004-09-21,2004-09-06
-5xdd,2017-08-09,2017-03-28
-1xdk,2004-11-09,2004-09-07
-5xds,2018-04-04,2017-03-29
-4xdh,2016-01-13,2014-12-19
-7xd8,2022-12-21,2022-03-26
-1xdp,2005-06-21,2004-09-07
-5xdt,2017-08-02,2017-03-30
-7xdw,2023-03-29,2022-03-29
-4xd8,2015-12-09,2014-12-19
-4xdj,2015-03-18,2014-12-19
-4xdy,2015-04-22,2014-12-20
-5xdb,2017-08-09,2017-03-28
-5xd7,2017-09-27,2017-03-27
-7xdk,2023-03-01,2022-03-27
-6xd0,2020-09-23,2020-06-09
-4xd7,2015-08-26,2014-12-19
-6xd3,2020-09-09,2020-06-09
-1xdy,2004-10-12,2004-09-08
-1xd2,2004-11-02,2004-09-03
-5xdv,2017-08-02,2017-03-30
-5xd8,2017-09-27,2017-03-27
-5xdf,2017-04-26,2017-03-28
-6xdd,2021-04-21,2020-06-10
-5xde,2017-08-09,2017-03-28
-2xdu,2010-09-01,2010-05-07
-5xd4,2017-08-09,2017-03-24
-2xdv,2010-05-26,2010-05-07
-2xdj,2010-09-15,2010-05-04
-4xdl,2015-03-18,2014-12-19
-5xd6,2018-04-04,2017-03-27
-19gs,1998-12-30,1997-12-14
-2flb,2006-04-04,2006-01-05
-8fle,2023-07-12,2022-12-21
-5fl3,2015-11-11,2015-10-21
-4flh,2012-08-29,2012-06-14
-3flw,2009-12-22,2008-12-19
-7flc,2022-11-02,2022-08-26
-3flt,2009-01-20,2008-12-19
-7flk,2022-11-02,2022-08-26
-7flh,2022-11-02,2022-08-26
-8flc,2023-07-12,2022-12-21
-8flg,2023-03-01,2022-12-21
-5fl5,2015-11-11,2015-10-21
-7fld,2022-11-02,2022-08-26
-3flv,2009-02-03,2008-12-19
-1flz,2001-01-17,2000-08-15
-4fl3,2012-11-28,2012-06-14
-7fll,2022-11-02,2022-08-26
-6fl2,2018-08-08,2018-01-25
-7fl1,2022-11-02,2022-08-26
-8fl0,2023-07-12,2022-12-21
-2flp,2006-12-05,2006-01-06
-1fl3,2000-11-01,2000-08-11
-4flm,2012-09-05,2012-06-14
-4flk,2012-09-19,2012-06-14
-7flb,2022-11-02,2022-08-26
-5flq,2016-03-02,2015-10-28
-5fls,2016-03-02,2015-10-28
-3fln,2009-12-22,2008-12-19
-4fli,2012-09-19,2012-06-14
-4flx,2012-08-29,2012-06-15
-8fl1,2023-05-31,2022-12-21
-7flp,2022-11-02,2022-08-26
-4fl0,2013-02-20,2012-06-14
-4flz,2012-08-29,2012-06-15
-6fly,2018-08-15,2018-01-29
-6flo,2019-08-14,2018-01-26
-7flm,2022-11-02,2022-08-26
-6fli,2018-05-16,2018-01-26
-5flp,2016-03-02,2015-10-28
-8flo,2023-03-29,2022-12-22
-7fle,2022-11-02,2022-08-26
-7fl5,2022-11-02,2022-08-26
-2flr,2007-01-23,2006-01-06
-8flm,2023-11-01,2022-12-21
-5flc,2015-12-30,2015-10-23
-7flg,2022-11-02,2022-08-26
-8flt,2023-04-26,2022-12-22
-8fl6,2023-07-12,2022-12-21
-6fl8,2018-09-12,2018-01-25
-4fl9,2013-10-02,2012-06-14
-5fl0,2016-08-31,2015-10-20
-3flo,2009-06-09,2008-12-19
-6fl5,2018-10-10,2018-01-25
-4flp,2012-07-11,2012-06-15
-6fle,2019-02-06,2018-01-25
-8flv,2023-04-05,2022-12-22
-1flv,1993-10-31,1992-07-02
-2flm,2006-02-28,2006-01-06
-4flg,2012-10-17,2012-06-14
-7fl4,2022-11-02,2022-08-26
-3fll,2009-02-10,2008-12-18
-8flk,2023-11-01,2022-12-21
-1flg,2000-08-30,2000-08-14
-1fl6,2001-11-14,2000-08-11
-5fl6,2015-11-11,2015-10-21
-1flj,2000-09-04,2000-08-14
-2fl2,2006-02-07,2006-01-05
-7flf,2022-11-02,2022-08-26
-7fl7,2022-11-02,2022-08-26
-6flv,2019-02-06,2018-01-29
-3fl3,2009-03-24,2008-12-18
-7flx,2022-11-02,2022-08-26
-2fli,2006-03-07,2006-01-06
-4flw,2012-08-29,2012-06-15
-3flz,2009-12-22,2008-12-19
-4flu,2012-08-29,2012-06-15
-1fla,1997-03-12,1996-12-18
-5flr,2016-03-02,2015-10-28
-5flg,2016-11-16,2015-10-26
-4fll,2012-09-19,2012-06-14
-1fl9,2002-08-07,2000-08-13
-2flv,1997-03-12,1996-12-19
-2fl6,2006-02-07,2006-01-05
-6flu,2019-02-06,2018-01-28
-7flo,2022-11-02,2022-08-26
-2fl5,2006-02-21,2006-01-05
-3fl2,2009-01-20,2008-12-18
-4fl1,2012-11-28,2012-06-14
-1fl2,2001-03-21,2000-08-11
-5fl7,2016-06-29,2015-10-22
-3fl8,2009-04-28,2008-12-18
-8flw,2023-05-31,2022-12-22
-7flj,2022-11-02,2022-08-26
-8flb,2023-07-12,2022-12-21
-7flt,2022-11-02,2022-08-26
-4flv,2012-08-29,2012-06-15
-5flj,2016-06-01,2015-10-26
-6fl1,2019-02-06,2018-01-25
-7fl8,2022-11-02,2022-08-26
-6flr,2018-12-19,2018-01-27
-8fl4,2023-07-12,2022-12-21
-6flp,2018-03-07,2018-01-26
-1flm,2000-03-06,1999-03-10
-8fl9,2023-07-12,2022-12-21
-2flw,2006-05-23,2006-01-06
-7fls,2022-11-02,2022-08-26
-7fly,2022-11-02,2022-08-26
-1fls,2001-08-15,2000-08-15
-3fls,2009-12-22,2008-12-19
-7fl0,2022-11-02,2022-08-26
-1fl7,2001-03-14,2000-08-11
-7fla,2022-11-02,2022-08-26
-6fl4,2019-02-06,2018-01-25
-8fla,2023-07-12,2022-12-21
-4fl8,2012-10-17,2012-06-14
-5fly,2015-12-02,2015-10-29
-5flh,2016-06-01,2015-10-26
-3fl1,2009-03-24,2008-12-18
-8flh,2023-03-01,2022-12-21
-7fli,2022-11-02,2022-08-26
-3flr,2009-01-20,2008-12-19
-7flq,2022-11-02,2022-08-26
-5flo,2016-03-02,2015-10-28
-3flp,2009-01-20,2008-12-19
-1fl1,2000-11-22,2000-08-11
-8fl7,2023-07-12,2022-12-21
-7flu,2022-11-02,2022-08-26
-6flg,2018-04-18,2018-01-25
-3flq,2009-12-22,2008-12-19
-1fld,1997-03-12,1996-12-17
-4fls,2012-10-31,2012-06-15
-1flp,1994-07-31,1994-05-16
-8fld,2023-07-12,2022-12-21
-7fl6,2022-11-02,2022-08-26
-6flz,2018-08-15,2018-01-29
-7fl2,2022-11-02,2022-08-26
-5flm,2016-01-20,2015-10-26
-3fli,2009-12-22,2008-12-18
-5flt,2016-03-02,2015-10-28
-1flr,1995-09-15,1995-01-19
-8fl2,2023-07-12,2022-12-21
-4flt,2012-08-29,2012-06-15
-6flq,2018-03-21,2018-01-26
-4fl4,2012-06-27,2012-06-14
-7fl9,2022-11-02,2022-08-26
-3fl7,2009-01-27,2008-12-18
-2fle,2007-01-16,2006-01-05
-7flz,2022-11-02,2022-08-26
-5flx,2015-12-23,2015-10-28
-4fl5,2013-12-11,2012-06-14
-4flf,2012-07-11,2012-06-14
-5fl4,2015-11-11,2015-10-21
-3fl5,2009-08-18,2008-12-18
-3fl4,2009-12-22,2008-12-18
-8fll,2023-03-01,2022-12-21
-8flf,2023-07-12,2022-12-21
-2fl0,2006-04-04,2006-01-05
-2fll,2006-12-12,2006-01-06
-7flr,2022-11-02,2022-08-26
-2flq,2006-01-31,2006-01-06
-4fly,2012-08-29,2012-06-15
-5fl1,2016-08-31,2015-10-20
-8fl8,2024-01-17,2022-12-21
-2flc,2006-02-21,2006-01-05
-3flf,2010-01-12,2008-12-18
-8flz,2023-04-05,2022-12-22
-8fln,2023-03-01,2022-12-21
-3fl9,2009-04-28,2008-12-18
-8fl3,2023-07-12,2022-12-21
-1fln,1997-03-12,1996-12-18
-2fls,2006-01-24,2006-01-06
-4fl2,2012-11-28,2012-06-14
-6fl3,2018-09-12,2018-01-25
-5fli,2016-06-01,2015-10-26
-7fl3,2022-11-02,2022-08-26
-8fly,2023-04-05,2022-12-22
-7flw,2022-11-02,2022-08-26
-2fld,2006-06-06,2006-01-05
-4flb,2012-08-15,2012-06-14
-7fln,2022-11-02,2022-08-26
-6fld,2018-08-29,2018-01-25
-3fl0,2009-03-24,2008-12-18
-5fle,2016-09-14,2015-10-26
-7flv,2022-11-02,2022-08-26
-3flk,2009-12-22,2008-12-18
-1flc,2000-03-01,1999-02-22
-4fl7,2012-08-15,2012-06-14
-3fly,2009-12-22,2008-12-19
-2fln,2006-12-05,2006-01-06
-2flh,2006-11-21,2006-01-06
-4flj,2012-09-19,2012-06-14
-5fll,2016-11-16,2015-10-26
-6xlx,2020-10-07,2020-06-29
-2xl8,2010-09-29,2010-07-20
-4xle,2016-01-20,2015-01-13
-6xlg,2021-06-30,2020-06-28
-2xlg,2010-08-11,2010-07-20
-5xl1,2017-08-02,2017-05-10
-4xld,2015-08-12,2015-01-13
-4xlh,2016-01-20,2015-01-13
-5xl7,2017-08-02,2017-05-10
-1xl2,2005-06-07,2004-09-30
-6xll,2021-04-07,2020-06-28
-6xl6,2021-04-07,2020-06-28
-4xlz,2015-06-10,2015-01-14
-1xl4,2004-12-07,2004-09-30
-5xle,2018-06-06,2017-05-10
-6xlh,2021-06-30,2020-06-28
-6xl3,2020-07-29,2020-06-28
-7xld,2023-05-31,2022-04-21
-6xla,2021-04-07,2020-06-28
-6xlr,2021-02-03,2020-06-29
-4xly,2015-02-04,2015-01-14
-6xlj,2021-04-07,2020-06-28
-1xll,1993-07-15,1991-10-09
-5xlk,2017-06-14,2017-05-10
-4xlq,2015-09-23,2015-01-13
-6xl8,2021-06-23,2020-06-28
-5xlg,2018-06-06,2017-05-10
-2xl3,2010-08-04,2010-07-19
-1xlf,1993-07-15,1991-10-09
-5xly,2017-08-23,2017-05-12
-5xl6,2017-08-02,2017-05-10
-4xlp,2015-09-23,2015-01-13
-1xlr,2004-11-09,2004-09-30
-1xlm,1998-01-28,1997-07-22
-4xlv,2015-03-25,2015-01-13
-1xlc,1993-07-15,1991-10-09
-5xla,2017-08-02,2017-05-10
-5xld,2017-08-02,2017-05-10
-4xl9,2016-01-20,2015-01-13
-1xlt,2005-04-05,2004-09-30
-5xlf,2018-06-06,2017-05-10
-6xld,2021-06-30,2020-06-28
-4xli,2015-04-01,2015-01-13
-6xl9,2021-04-07,2020-06-28
-1xlx,2004-12-14,2004-09-30
-4xlo,2015-01-28,2015-01-13
-5xl3,2017-08-02,2017-05-10
-5xlh,2018-06-06,2017-05-10
-4xlf,2016-01-20,2015-01-13
-1xlh,1993-07-15,1991-10-09
-5xl8,2017-08-02,2017-05-10
-6xlv,2020-10-07,2020-06-29
-2xlv,2010-11-10,2010-07-22
-1xlj,1993-07-15,1991-10-09
-8xln,2024-05-01,2023-12-26
-5xl0,2017-08-16,2017-05-10
-8xld,2024-03-06,2023-12-25
-7xli,2023-05-31,2022-04-21
-2xle,2010-11-10,2010-07-20
-4xla,2016-01-20,2015-01-13
-6xlp,2020-08-26,2020-06-29
-4xlw,2015-03-04,2015-01-13
-5xl9,2017-08-02,2017-05-10
-1xl0,2005-03-15,2004-09-30
-7xlz,2023-05-31,2022-04-23
-6xls,2021-02-03,2020-06-29
-8xlm,2024-05-01,2023-12-26
-7xlq,2023-02-08,2022-04-22
-5xl2,2017-08-02,2017-05-10
-5xlb,2017-08-02,2017-05-10
-5xl5,2017-08-02,2017-05-10
-4xl8,2015-01-21,2015-01-13
-1xlv,2005-02-01,2004-09-30
-6xlw,2020-10-07,2020-06-29
-2xlm,2010-11-10,2010-07-21
-6xlo,2021-05-26,2020-06-28
-4xlr,2015-09-23,2015-01-13
-2xlo,2010-11-10,2010-07-21
-2xlu,2010-09-15,2010-07-21
-5xlx,2017-08-23,2017-05-12
-5xl4,2017-08-02,2017-05-10
-6xln,2021-04-07,2020-06-28
-2xlh,2010-09-29,2010-07-20
-6xl4,2021-06-30,2020-06-28
-1xlw,2005-02-01,2004-09-30
-6xlm,2021-04-07,2020-06-28
-5xlt,2017-09-27,2017-05-11
-1xlu,2005-02-01,2004-09-30
-2xls,2010-09-15,2010-07-21
-4xls,2015-09-23,2015-01-13
-6xle,2021-06-30,2020-06-28
-6xl1,2020-12-30,2020-06-27
-4xl1,2015-03-04,2015-01-13
-5xlc,2017-08-02,2017-05-10
-1xlb,1993-07-15,1991-10-09
-1xld,1993-07-15,1991-10-09
-2xll,2011-04-20,2010-07-21
-1xl6,2004-12-07,2004-09-30
-1xlz,2004-12-14,2004-09-30
-2xlt,2010-09-15,2010-07-21
-6xl5,2021-04-07,2020-06-28
-1xl8,2004-10-19,2004-09-30
-2xl6,2010-11-10,2010-07-19
-2xlp,2010-09-15,2010-07-21
-6xlt,2021-02-03,2020-06-29
-6xly,2020-12-23,2020-06-29
-2xla,2010-08-11,2010-07-20
-1xlg,1993-07-15,1991-10-09
-7xlp,2023-03-01,2022-04-22
-2xld,2010-11-10,2010-07-20
-2xlr,2010-09-15,2010-07-21
-2xl7,2010-08-11,2010-07-19
-4xlc,2016-01-20,2015-01-13
-2xlq,2010-10-27,2010-07-21
-7xl4,2022-07-27,2022-04-21
-4xl4,2015-10-07,2015-01-13
-1xls,2004-12-28,2004-09-30
-7xl3,2022-07-27,2022-04-21
-5xlu,2018-05-16,2017-05-11
-4xlg,2015-03-25,2015-01-13
-1xl5,2005-06-07,2004-09-30
-4xln,2015-09-23,2015-01-13
-5xlj,2017-06-14,2017-05-10
-6xlk,2021-04-07,2020-06-28
-2xlw,2010-11-10,2010-07-22
-1xli,1993-07-15,1991-10-09
-5xlz,2017-11-22,2017-05-12
-6xlu,2020-08-12,2020-06-29
-2xl9,2010-08-11,2010-07-20
-1xlk,1993-07-15,1991-10-09
-1xl1,2005-03-15,2004-09-30
-7xl9,2022-07-13,2022-04-21
-1xle,1993-07-15,1991-10-09
-5xls,2017-07-05,2017-05-11
-7xlf,2023-04-26,2022-04-21
-2xln,2011-01-26,2010-07-21
-7xll,2023-03-01,2022-04-22
-6xlc,2021-06-30,2020-06-28
-6xlf,2021-06-30,2020-06-28
-6xlz,2021-07-07,2020-06-29
-6kbp,2020-07-08,2019-06-26
-7kb6,2021-10-06,2020-10-01
-3kb9,2010-02-09,2009-10-20
-5kbg,2016-07-13,2016-06-03
-3kbz,2010-02-02,2009-10-20
-7kbt,2020-11-18,2020-10-02
-7kbc,2021-02-03,2020-10-02
-4kbn,2013-10-09,2013-04-23
-7kbg,2020-12-30,2020-10-02
-1kb4,2002-05-03,2001-11-05
-1kbi,2002-04-03,2001-11-06
-5kb1,2016-08-31,2016-06-02
-8kb0,2024-05-29,2023-08-03
-3kbp,1996-12-07,1995-10-02
-4kb2,2014-03-12,2013-04-23
-1kbq,2002-01-16,2001-11-06
-2kbm,2009-02-10,2008-12-02
-6kbd,2020-06-24,2019-06-24
-5kbi,2016-07-13,2016-06-03
-4kb0,2014-03-05,2013-04-23
-4kb1,2014-03-05,2013-04-23
-6kb3,2020-11-11,2019-06-24
-3kbw,2010-06-16,2009-10-20
-7kb7,2020-10-14,2020-10-01
-3kbh,2009-12-15,2009-10-20
-5kbv,2016-07-13,2016-06-03
-6kbi,2020-07-01,2019-06-25
-1kb6,2002-05-03,2001-11-05
-5kb6,2017-06-07,2016-06-02
-1kbj,2002-04-03,2001-11-06
-3kba,2009-12-08,2009-10-20
-3kb0,2009-12-08,2009-10-19
-2kbx,2008-12-30,2008-12-10
-7kbr,2021-10-06,2020-10-02
-3kbs,2010-06-16,2009-10-20
-5kb2,2016-08-31,2016-06-02
-1kbp,1996-10-14,1995-02-20
-3kbo,2009-10-27,2009-10-20
-5kbe,2016-07-13,2016-06-03
-3kbr,2009-11-10,2009-10-20
-3kbk,2010-02-09,2009-10-20
-7kb8,2021-10-06,2020-10-01
-1kbn,2003-11-11,2001-11-06
-7kbs,2020-11-18,2020-10-02
-4kbl,2013-05-29,2013-04-23
-4kbe,2013-05-22,2013-04-23
-4kb7,2013-05-08,2013-04-23
-4kby,2013-05-29,2013-04-24
-4kbz,2013-05-15,2013-04-24
-1kbc,1997-08-12,1997-04-29
-4kbo,2014-04-02,2013-04-23
-7kbj,2021-10-06,2020-10-02
-5kbz,2017-05-10,2016-06-03
-4kbi,2013-05-08,2013-04-23
-5kbn,2016-08-03,2016-06-03
-5kbm,2016-08-24,2016-06-03
-1kb2,2002-05-03,2001-11-05
-4kbf,2013-07-31,2013-04-23
-5kbt,2016-07-13,2016-06-03
-5kbu,2016-07-13,2016-06-03
-1kbe,2002-01-23,2001-11-06
-1kbg,1999-02-09,1998-08-28
-3kb8,2009-10-27,2009-10-20
-5kbd,2016-08-31,2016-06-03
-7kbn,2021-10-13,2020-10-02
-6kbc,2020-06-24,2019-06-24
-5kbk,2016-08-24,2016-06-03
-7kbi,2021-08-04,2020-10-02
-5kb3,2016-11-16,2016-06-02
-4kbb,2013-07-03,2013-04-23
-5kb0,2016-08-31,2016-06-02
-6kbw,2020-07-08,2019-06-26
-5kb5,2017-06-07,2016-06-02
-6kb9,2020-11-11,2019-06-24
-5kbf,2016-10-12,2016-06-03
-1kb9,2002-09-18,2001-11-05
-4kbk,2013-09-18,2013-04-23
-6kb4,2020-11-11,2019-06-24
-6kbq,2020-08-05,2019-06-26
-3kb7,2010-05-19,2009-10-20
-2kbo,2009-02-03,2008-12-04
-7kbh,2020-12-30,2020-10-02
-7kb1,2021-06-23,2020-10-01
-5kbs,2016-07-13,2016-06-03
-4kb9,2013-09-04,2013-04-23
-3kbu,2010-02-02,2009-10-20
-3kbv,2010-06-16,2009-10-20
-6kb7,2020-11-11,2019-06-24
-5kby,2016-07-13,2016-06-03
-4kb4,2014-03-12,2013-04-23
-3kb2,2009-10-27,2009-10-20
-4kb8,2013-09-18,2013-04-23
-4kbp,1996-12-07,1995-10-02
-3kbn,2010-06-16,2009-10-20
-6kba,2020-11-11,2019-06-24
-5kbr,2016-09-28,2016-06-03
-6kbs,2019-07-10,2019-06-26
-6kbz,2019-07-10,2019-06-26
-1kbf,2002-01-23,2001-11-06
-6kb8,2020-11-11,2019-06-24
-6kb2,2020-11-11,2019-06-24
-3kbx,2010-10-27,2009-10-20
-4kbc,2013-09-18,2013-04-23
-3kb1,2009-10-27,2009-10-19
-2kb2,2009-04-07,2008-11-19
-1kb0,2001-12-28,2001-11-05
-3kb6,2009-11-10,2009-10-20
-3kbc,2009-12-01,2009-10-20
-8kb1,2024-05-29,2023-08-03
-5kbw,2016-06-29,2016-06-03
-5kbh,2016-07-13,2016-06-03
-6kbf,2020-04-08,2019-06-24
-3kbf,2010-11-03,2009-10-20
-1kb3,2002-05-01,2001-11-05
-1kbv,2001-12-05,2001-11-06
-1kbb,2002-04-10,2001-11-05
-6kbh,2020-07-01,2019-06-25
-2kbs,2009-03-31,2008-12-05
-6kbx,2019-07-10,2019-06-26
-6kbj,2020-08-12,2019-06-25
-1kbw,2001-12-05,2001-11-06
-7kbk,2021-08-04,2020-10-02
-4kba,2013-09-18,2013-04-23
-7kbu,2021-02-10,2020-10-03
-6kbb,2020-01-29,2019-06-24
-1kbk,2002-04-10,2001-11-06
-4kb6,2013-06-05,2013-04-23
-5kbl,2016-08-24,2016-06-03
-6kby,2019-10-16,2019-06-26
-1kbz,2002-06-28,2001-11-07
-1kby,2002-11-13,2001-11-07
-3kb3,2009-12-08,2009-10-20
-5kbq,2016-09-28,2016-06-03
-3kbm,2010-06-16,2009-10-20
-1kbo,2002-01-16,2001-11-06
-4huv,2013-02-27,2012-11-04
-5hum,2016-04-13,2016-01-27
-2hu8,2007-05-15,2006-07-26
-6hu9,2018-12-26,2018-10-05
-4huw,2013-02-27,2012-11-04
-5hue,2017-08-02,2016-01-27
-4hur,2012-11-14,2012-11-03
-8huq,2023-08-09,2022-12-24
-6hue,2018-10-17,2018-10-07
-5hux,2016-06-08,2016-01-27
-1hu8,2001-07-04,2001-01-04
-4huz,2013-04-17,2012-11-05
-2hun,2007-01-26,2006-07-26
-5hui,2017-02-01,2016-01-27
-6huc,2019-01-30,2018-10-05
-3hu6,2009-10-20,2009-06-13
-8hun,2023-08-09,2022-12-24
-6hu2,2018-10-31,2018-10-05
-6huz,2019-01-09,2018-10-09
-3hu8,2009-11-03,2009-06-13
-3hud,1994-01-31,1993-01-04
-5huf,2016-04-13,2016-01-27
-8hum,2023-08-09,2022-12-24
-2huw,2006-08-15,2006-07-27
-4huo,2012-12-26,2012-11-02
-6hum,2019-01-09,2018-10-09
-5huq,2016-02-10,2016-01-27
-6hun,2019-06-12,2018-10-09
-4hul,2013-02-06,2012-11-02
-6hui,2019-09-04,2018-10-08
-4huc,2012-12-12,2012-11-02
-6hu7,2018-12-26,2018-10-05
-2huu,2006-09-26,2006-07-27
-1huh,1994-04-30,1993-10-28
-6hux,2019-01-09,2018-10-09
-5hu6,2016-03-02,2016-01-27
-1hug,1994-04-30,1993-10-28
-6huf,2019-03-27,2018-10-08
-2hux,2007-01-27,2006-07-27
-1hux,2001-03-21,2001-01-04
-2hu5,2007-05-15,2006-07-26
-2hup,2006-08-08,2006-07-27
-5huw,2016-03-09,2016-01-27
-5huy,2016-03-16,2016-01-28
-5hua,2016-09-14,2016-01-27
-8hu2,2024-01-17,2022-12-22
-6hua,2019-10-23,2018-10-05
-5hu0,2016-11-09,2016-01-27
-8hu1,2024-04-03,2022-12-22
-6hul,2018-11-07,2018-10-08
-6hu1,2018-10-31,2018-10-05
-5hud,2017-08-02,2016-01-27
-1huj,1998-04-08,1997-12-26
-4hun,2013-02-06,2012-11-02
-5hur,2016-02-10,2016-01-27
-8huh,2023-12-27,2022-12-23
-5huv,2017-05-03,2016-01-27
-3hup,2009-12-15,2009-06-15
-6hug,2019-01-02,2018-10-08
-8huo,2023-08-09,2022-12-24
-3huc,2010-03-09,2009-06-13
-3huq,2009-11-03,2009-06-15
-4hu7,2013-05-29,2012-11-02
-4huk,2013-02-06,2012-11-02
-4hu1,2013-04-10,2012-11-02
-4hum,2013-02-06,2012-11-02
-8huu,2023-06-21,2022-12-24
-4hu0,2012-12-05,2012-11-02
-2hu9,2007-07-03,2006-07-26
-8hud,2023-12-27,2022-12-23
-4hup,2012-12-26,2012-11-02
-6hu4,2018-12-26,2018-10-05
-3hun,2009-11-10,2009-06-15
-2hu2,2006-10-31,2006-07-26
-1hut,1994-06-22,1993-05-27
-3hus,2009-08-18,2009-06-15
-2hu1,2007-05-22,2006-07-26
-8hua,2023-03-01,2022-12-22
-8hup,2023-08-09,2022-12-24
-1huk,1998-04-08,1997-12-26
-4hux,2013-02-27,2012-11-05
-4hug,2012-12-19,2012-11-02
-8hug,2023-12-27,2022-12-23
-6hu3,2018-10-31,2018-10-05
-3huo,2010-05-26,2009-06-15
-4hua,2013-05-29,2012-11-02
-8hut,2023-06-21,2022-12-24
-2hue,2006-11-21,2006-07-26
-8huf,2023-12-27,2022-12-23
-6huy,2019-01-09,2018-10-09
-2huc,2006-08-08,2006-07-26
-5huk,2016-04-13,2016-01-27
-6hu0,2018-10-31,2018-10-05
-2hut,2007-01-27,2006-07-27
-2hub,2007-07-24,2006-07-26
-8hus,2023-06-21,2022-12-24
-6huq,2019-01-30,2018-10-09
-6hup,2019-01-02,2018-10-09
-3huj,2009-07-28,2009-06-14
-3hu1,2010-06-16,2009-06-12
-1huq,2001-02-07,2001-01-04
-5hu3,2017-02-01,2016-01-27
-3hu3,2010-06-16,2009-06-12
-8huk,2023-08-09,2022-12-24
-3huk,2009-11-03,2009-06-14
-4hu9,2013-05-29,2012-11-02
-4huu,2013-02-27,2012-11-04
-2huo,2006-09-26,2006-07-27
-5huh,2017-01-25,2016-01-27
-4hus,2012-11-21,2012-11-03
-1huv,2001-09-19,2001-01-04
-2hu3,2007-07-24,2006-07-26
-8hui,2023-12-27,2022-12-24
-5huc,2017-08-02,2016-01-27
-4huf,2012-12-19,2012-11-02
-8hux,2023-06-21,2022-12-24
-6huu,2019-01-30,2018-10-09
-3hu9,2009-11-03,2009-06-13
-2hu6,2006-12-19,2006-07-26
-2hu4,2006-09-05,2006-07-26
-1hu0,2003-02-25,2001-01-03
-6huj,2019-01-02,2018-10-08
-1hup,1995-10-15,1994-09-21
-1hur,1995-07-10,1995-04-19
-2huh,2006-08-29,2006-07-26
-6huo,2019-01-02,2018-10-09
-2huq,2007-01-27,2006-07-27
-1hu9,2003-06-03,2001-01-04
-1huo,2001-04-23,2001-01-04
-6huv,2019-01-30,2018-10-09
-4hue,2012-12-19,2012-11-02
-8hur,2023-06-21,2022-12-24
-5hu9,2016-07-13,2016-01-27
-6hub,2019-01-30,2018-10-05
-5hun,2016-04-13,2016-01-27
-6huk,2019-01-02,2018-10-08
-3hum,2009-11-10,2009-06-15
-2huv,2007-01-27,2006-07-27
-6hur,2019-09-04,2018-10-09
-8hul,2023-08-09,2022-12-24
-5hu1,2016-11-09,2016-01-27
-3huf,2009-10-13,2009-06-13
-5hu8,2016-04-13,2016-01-27
-3hu2,2010-06-16,2009-06-12
-3hub,2010-03-09,2009-06-13
-2hu0,2006-09-05,2006-07-26
-2hu7,2007-05-15,2006-07-26
-3hua,2009-11-03,2009-06-13
-3hug,2010-03-02,2009-06-14
-2huf,2006-09-26,2006-07-26
-8hu4,2023-12-27,2022-12-22
-6hus,2019-09-04,2018-10-09
-4hut,2013-01-23,2012-11-04
-8huw,2023-06-21,2022-12-24
-5hug,2016-04-13,2016-01-27
-8hu6,2023-01-18,2022-12-22
-5huu,2017-05-03,2016-01-27
-8hub,2023-01-18,2022-12-23
-8huv,2023-06-21,2022-12-24
-5hut,2017-05-03,2016-01-27
-3huv,2010-06-02,2009-06-15
-1huz,2001-04-23,2001-01-04
-5a86,2015-10-21,2015-07-13
-1a8z,1998-06-17,1998-03-30
-3a88,2010-09-29,2009-10-05
-2a8k,2005-09-20,2005-07-08
-2a83,2005-12-27,2005-07-07
-3a8a,2010-09-29,2009-10-05
-4a86,2012-05-30,2011-11-18
-8a8z,2023-01-25,2022-06-27
-1a8p,1998-06-17,1998-03-28
-4a8p,2012-02-15,2011-11-21
-6a8i,2018-12-19,2018-07-09
-7a8q,2021-10-06,2020-08-30
-8a8t,2023-04-05,2022-06-24
-5a8j,2016-06-22,2015-07-16
-2a84,2006-02-21,2005-07-07
-3a8t,2009-12-29,2009-10-09
-3a8h,2010-04-14,2009-10-06
-8a8x,2022-07-06,2022-06-24
-4a87,2012-05-30,2011-11-18
-5a8l,2015-12-02,2015-07-16
-5a8k,2016-08-03,2015-07-16
-8a8l,2023-07-05,2022-06-23
-3a89,2010-09-29,2009-10-05
-8a8k,2023-04-26,2022-06-23
-8a8w,2022-10-26,2022-06-24
-5a8q,2016-01-20,2015-07-16
-6a8h,2018-12-19,2018-07-09
-5a8y,2016-08-03,2015-07-17
-1a8r,1999-05-11,1998-03-27
-3a8c,2010-09-29,2009-10-05
-8a8g,2023-04-26,2022-06-23
-3a8m,2010-04-14,2009-10-06
-5a8z,2016-08-03,2015-07-17
-8a8v,2022-10-26,2022-06-24
-3a8r,2009-10-27,2009-10-07
-6a8b,2019-07-10,2018-07-06
-5a88,2015-12-09,2015-07-13
-5a8h,2015-08-05,2015-07-15
-8a8u,2022-10-26,2022-06-24
-2a8g,2006-05-23,2005-07-08
-4a8v,2012-05-30,2011-11-21
-5a87,2015-12-23,2015-07-13
-3a8w,2010-05-05,2009-10-11
-5a85,2015-08-12,2015-07-11
-8a8j,2023-04-26,2022-06-23
-3a87,2010-09-29,2009-10-05
-4a8h,2012-02-15,2011-11-21
-3a80,2010-09-29,2009-10-05
-5a80,2016-01-13,2015-07-11
-2a8a,2005-09-20,2005-07-07
-6a88,2019-10-23,2018-07-06
-5a8b,2016-02-10,2015-07-14
-5a8a,2015-12-09,2015-07-13
-3a82,2010-09-29,2009-10-05
-1a8e,1998-06-17,1998-03-24
-3a8z,2010-03-09,2009-10-15
-5a81,2015-08-12,2015-07-11
-4a8w,2012-07-04,2011-11-21
-5a8p,2016-01-20,2015-07-16
-6a8o,2019-07-10,2018-07-09
-2a8s,2006-03-28,2005-07-08
-5a8c,2016-07-27,2015-07-14
-2a8n,2005-09-27,2005-07-08
-5a8n,2016-01-20,2015-07-16
-6a8d,2019-07-10,2018-07-06
-2a8r,2006-03-28,2005-07-08
-5a83,2015-08-12,2015-07-11
-1a8j,1998-06-17,1998-03-26
-5a8r,2016-08-10,2015-07-16
-2a8t,2006-03-28,2005-07-08
-3a85,2010-09-29,2009-10-05
-8a8i,2023-03-01,2022-06-23
-7a8v,2021-10-06,2020-08-31
-3a8i,2010-04-07,2009-10-06
-2a8h,2006-02-07,2005-07-08
-8a8o,2023-04-26,2022-06-23
-4a8l,2011-11-30,2011-11-21
-1a8t,1998-10-14,1998-03-23
-2a8q,2006-03-28,2005-07-08
-8a8m,2022-07-13,2022-06-23
-1a8v,1999-05-04,1998-03-28
-3a83,2010-09-29,2009-10-05
-1a8a,1998-06-17,1998-03-23
-1a80,1999-03-30,1998-03-31
-4a8m,2012-07-04,2011-11-21
-7a8r,2021-10-06,2020-08-30
-6a82,2018-12-26,2018-07-06
-3a8l,2010-04-14,2009-10-06
-2a8d,2006-04-18,2005-07-07
-2a8x,2005-08-16,2005-07-10
-4a8g,2012-05-30,2011-11-21
-2a87,2005-11-29,2005-07-07
-1a8c,1998-10-21,1998-03-23
-2a85,2006-07-11,2005-07-07
-5a82,2015-08-12,2015-07-11
-8a82,2023-03-08,2022-06-21
-1a8h,1999-05-04,1998-03-26
-5a8m,2016-01-20,2015-07-16
-6a8s,2019-06-12,2018-07-10
-5a89,2015-12-09,2015-07-13
-4a84,2012-05-30,2011-11-18
-1a8l,1999-03-30,1998-03-26
-1a8g,1998-07-15,1998-03-24
-6a86,2019-04-10,2018-07-06
-5a8o,2016-01-20,2015-07-16
-1a8d,1998-10-14,1998-03-23
-2a8u,2005-12-13,2005-07-09
-5a8e,2015-09-30,2015-07-15
-6a87,2019-04-10,2018-07-06
-2a89,2006-01-17,2005-07-07
-3a8b,2010-09-29,2009-10-05
-4a8n,2012-02-29,2011-11-21
-4a85,2012-05-30,2011-11-18
-4a8s,2012-07-04,2011-11-21
-1a82,1999-05-11,1998-03-31
-4a8i,2011-11-30,2011-11-21
-2a86,2006-02-21,2005-07-07
-3a84,2010-09-29,2009-10-05
-5a8w,2016-08-03,2015-07-17
-6a83,2018-12-26,2018-07-06
-3a8d,2010-09-29,2009-10-05
-6a89,2018-07-25,2018-07-06
-3a8e,2010-09-22,2009-10-05
-4a81,2012-05-30,2011-11-18
-6a8x,2018-12-19,2018-07-11
-6a84,2019-04-03,2018-07-06
-1a8k,1999-01-13,1998-03-27
-3a8u,2009-11-10,2009-10-11
-5a8x,2016-08-03,2015-07-17
-2a8p,2006-03-28,2005-07-08
-6a8a,2019-07-10,2018-07-06
-3a8o,2010-04-14,2009-10-07
-4a8f,2012-07-04,2011-11-21
-2a8c,2006-04-18,2005-07-07
-6a8c,2019-07-10,2018-07-06
-3a86,2010-09-29,2009-10-05
-4a8y,2012-07-04,2011-11-21
-6a8g,2019-02-20,2018-07-08
-4a8o,2012-07-04,2011-11-21
-2a8y,2006-03-28,2005-07-10
-6a8n,2019-02-20,2018-07-09
-2a8v,1999-04-26,1998-11-08
-1a8i,1998-07-01,1998-03-25
-1a8f,1998-06-17,1998-03-25
-4a83,2012-05-30,2011-11-18
-4a8k,2012-07-04,2011-11-21
-6a8z,2019-07-17,2018-07-11
-6a80,2019-06-12,2018-07-05
-8a8f,2023-11-29,2022-06-22
-7a8p,2020-12-30,2020-08-30
-4a8t,2012-02-15,2011-11-21
-4a8r,2011-11-30,2011-11-21
-4a8q,2012-07-04,2011-11-21
-3a81,2010-09-29,2009-10-05
-7a8y,2021-10-06,2020-08-31
-2a8w,2005-12-13,2005-07-09
-5a8v,2015-09-02,2015-07-17
-6a8l,2018-08-01,2018-07-09
-6a8p,2018-09-26,2018-07-09
-2a81,2005-08-23,2005-07-07
-1a8b,1998-06-17,1998-03-23
-8a8d,2023-04-26,2022-06-22
-3a8g,2010-04-14,2009-10-06
-4a80,2012-05-30,2011-11-18
-6umf,2020-10-14,2019-10-09
-6umd,2020-10-14,2019-10-09
-5umb,2022-07-27,2017-01-26
-1umv,2003-09-18,2003-08-28
-1ump,2004-02-03,2003-08-27
-7umx,2023-02-15,2022-04-08
-4umr,2014-10-08,2014-05-20
-6umj,2020-02-12,2019-10-09
-4umu,2014-10-22,2014-05-21
-7umh,2023-05-17,2022-04-07
-3umr,2012-10-24,2011-11-14
-6umh,2020-02-12,2019-10-09
-3umv,2011-12-21,2011-11-14
-8umy,2024-05-08,2023-10-18
-7uma,2022-11-02,2022-04-06
-3umd,2012-04-11,2011-11-13
-3umh,2012-01-25,2011-11-13
-6uml,2020-04-15,2019-10-09
-3um6,2012-07-18,2011-11-12
-4um5,2015-02-11,2014-05-15
-8umt,2024-05-08,2023-10-18
-4umw,2014-08-13,2014-05-21
-4ume,2015-02-11,2014-05-16
-6um1,2020-02-26,2019-10-08
-6ume,2020-10-14,2019-10-09
-7umb,2023-09-27,2022-04-06
-7um2,2023-04-26,2022-04-06
-6um6,2019-12-18,2019-10-09
-3umk,2012-01-25,2011-11-13
-4um9,2014-11-12,2014-05-15
-1umi,2004-04-06,2003-10-01
-4umo,2014-11-05,2014-05-20
-6umr,2020-07-29,2019-10-10
-4um7,2015-02-11,2014-05-15
-7um9,2023-04-26,2022-04-06
-4umn,2014-05-28,2014-05-20
-3um8,2012-07-18,2011-11-12
-6umy,2020-07-15,2019-10-10
-1umz,2004-03-18,2003-09-03
-5um6,2017-06-14,2017-01-26
-1umy,2004-05-06,2003-09-02
-3umb,2012-11-14,2011-11-12
-5umz,2017-12-27,2017-01-30
-3ume,2012-04-11,2011-11-13
-4um1,2015-07-22,2014-05-14
-4umb,2014-10-08,2014-05-16
-7umt,2022-07-27,2022-04-07
-4ump,2014-10-08,2014-05-20
-7ums,2022-07-27,2022-04-07
-1um0,2004-06-01,2003-09-18
-7um1,2022-07-06,2022-04-05
-6um5,2019-12-18,2019-10-09
-6umw,2020-10-14,2019-10-10
-4umv,2014-08-13,2014-05-21
-3umw,2012-10-03,2011-11-14
-4umx,2014-11-19,2014-05-22
-5um8,2017-05-24,2017-01-26
-4umt,2014-10-22,2014-05-21
-7umu,2022-10-05,2022-04-07
-7um8,2023-02-15,2022-04-06
-5umw,2018-07-04,2017-01-29
-8umv,2024-05-08,2023-10-18
-7um7,2022-07-20,2022-04-06
-6um2,2020-02-26,2019-10-08
-1umg,2004-07-13,2003-09-30
-5umm,2018-01-31,2017-01-27
-4umq,2014-10-08,2014-05-20
-1umd,2004-03-30,2003-09-25
-7um0,2022-07-06,2022-04-05
-6um8,2020-03-04,2019-10-09
-3umm,2012-06-06,2011-11-14
-1umw,2003-10-16,2003-08-29
-7umk,2022-04-20,2022-04-07
-1umk,2004-11-02,2003-10-03
-5umf,2017-02-15,2017-01-27
-3um7,2012-02-08,2011-11-12
-5um3,2017-03-22,2017-01-26
-1uma,1996-11-08,1996-03-26
-8um6,2024-02-07,2023-10-17
-7um5,2022-07-20,2022-04-06
-3um5,2012-07-18,2011-11-12
-8umu,2024-05-08,2023-10-18
-8umc,2024-05-29,2023-10-17
-6umz,2020-07-15,2019-10-10
-4umj,2015-03-11,2014-05-18
-4umf,2015-02-11,2014-05-16
-7umy,2023-02-15,2022-04-08
-7umv,2022-10-05,2022-04-07
-7umg,2022-08-03,2022-04-06
-5uml,2018-01-31,2017-01-27
-7umo,2023-07-26,2022-04-07
-6umk,2020-02-05,2019-10-09
-7um4,2022-07-20,2022-04-06
-1umb,2004-03-30,2003-09-25
-5ume,2017-02-22,2017-01-27
-7umz,2023-04-12,2022-04-08
-1um5,2004-10-05,2003-09-23
-1uml,2004-09-21,2003-10-03
-3umc,2012-11-14,2011-11-13
-4umz,2015-06-17,2014-05-22
-5umc,2017-12-06,2017-01-26
-3umi,2012-01-25,2011-11-13
-7ump,2022-05-18,2022-04-07
-3ums,2012-02-08,2011-11-14
-8um3,2023-11-01,2023-10-17
-5um9,2017-06-28,2017-01-26
-6umc,2020-10-14,2019-10-09
-1um8,2003-12-23,2003-09-25
-1umn,2004-04-23,2003-08-26
-3umy,2012-10-31,2011-11-15
-1umc,2004-03-30,2003-09-25
-3umj,2012-02-22,2011-11-13
-4umm,2014-06-25,2014-05-19
-1um4,2004-10-05,2003-09-23
-3um9,2012-11-14,2011-11-12
-5umx,2018-07-04,2017-01-29
-3umq,2012-07-04,2011-11-14
-4umc,2014-10-08,2014-05-16
-1umo,2004-09-02,2003-08-26
-8umo,2024-01-17,2023-10-18
-5umy,2018-07-04,2017-01-29
-1umx,2004-06-29,2003-09-02
-1ums,1996-03-08,1995-10-31
-7um6,2022-07-20,2022-04-06
-4um8,2014-11-12,2014-05-15
-3ump,2012-11-14,2011-11-14
-8umw,2024-05-08,2023-10-18
-5umh,2017-02-15,2017-01-27
-5umn,2017-05-24,2017-01-27
-6umt,2019-11-27,2019-10-10
-3umo,2012-11-14,2011-11-14
-5um1,2017-08-23,2017-01-25
-6um7,2019-12-18,2019-10-09
-4um3,2015-07-22,2014-05-14
-6umq,2020-07-29,2019-10-10
-3umx,2012-08-08,2011-11-15
-5umd,2017-03-01,2017-01-27
-7umw,2022-12-14,2022-04-08
-4uma,2014-10-08,2014-05-16
-4umy,2014-11-19,2014-05-22
-1umh,2004-04-06,2003-10-01
-7umr,2022-10-12,2022-04-07
-1um2,2004-09-22,2003-09-22
-1umt,1996-03-08,1995-10-31
-7umm,2022-11-23,2022-04-07
-7d9x,2021-06-23,2020-10-14
-7d9t,2021-08-11,2020-10-14
-8d9l,2023-01-11,2022-06-10
-2d9q,2006-02-07,2005-12-12
-7d9o,2021-08-25,2020-10-14
-5d9x,2016-02-03,2015-08-19
-8d9t,2022-11-09,2022-06-11
-2d9m,2006-06-12,2005-12-12
-5d9t,2016-02-03,2015-08-19
-1d9k,1999-12-15,1999-10-28
-6d9l,2018-07-25,2018-04-30
-8d9i,2023-06-14,2022-06-09
-8d9r,2022-11-09,2022-06-11
-5d9z,2016-02-24,2015-08-19
-5d9m,2015-11-04,2015-08-18
-2d9h,2006-06-09,2005-12-09
-6d9a,2019-05-15,2018-04-28
-1d9f,1999-12-02,1999-10-27
-6d96,2019-05-01,2018-04-27
-7d9p,2021-08-25,2020-10-14
-5d9w,2016-02-03,2015-08-19
-6d9b,2019-05-15,2018-04-28
-2d9g,2006-06-09,2005-12-09
-7d90,2020-12-30,2020-10-12
-5d98,2015-10-21,2015-08-18
-5d9h,2015-09-02,2015-08-18
-3d94,2008-07-29,2008-05-26
-6d9k,2018-07-25,2018-04-30
-7d99,2020-12-30,2020-10-12
-4d9p,2012-03-28,2012-01-11
-8d96,2023-04-19,2022-06-09
-3d9p,2008-06-10,2008-05-27
-3d9r,2008-07-01,2008-05-27
-8d97,2023-06-14,2022-06-09
-4d94,2012-10-17,2012-01-11
-8d95,2022-11-02,2022-06-09
-8d9o,2022-09-28,2022-06-10
-5d92,2015-11-04,2015-08-18
-4d92,2012-05-30,2012-01-11
-7d9u,2021-08-11,2020-10-14
-4d9u,2012-04-11,2012-01-12
-5d9d,2015-09-23,2015-08-18
-5d9v,2016-02-03,2015-08-19
-4d9q,2012-02-22,2012-01-11
-4d9t,2012-04-25,2012-01-12
-3d9v,2008-06-10,2008-05-27
-6d9e,2019-05-15,2018-04-28
-6d9i,2018-09-05,2018-04-30
-8d9s,2022-11-09,2022-06-11
-4d9m,2012-04-25,2012-01-11
-7d9f,2021-11-17,2020-10-13
-7d91,2021-01-27,2020-10-12
-5d9i,2015-09-09,2015-08-18
-6d97,2019-01-09,2018-04-27
-8d9d,2023-04-19,2022-06-09
-6d92,2018-07-25,2018-04-27
-7d93,2021-01-27,2020-10-12
-6d9w,2019-02-13,2018-04-30
-6d94,2019-05-01,2018-04-27
-8d9u,2022-11-09,2022-06-11
-3d9m,2008-06-10,2008-05-27
-3d90,2009-05-26,2008-05-26
-3d91,2008-06-17,2008-05-26
-5d9q,2016-08-17,2015-08-18
-6d99,2019-05-15,2018-04-28
-8d9e,2023-06-14,2022-06-09
-3d9t,2008-06-10,2008-05-27
-7d9v,2021-02-24,2020-10-14
-8d9v,2022-11-09,2022-06-11
-3d9e,2009-04-07,2008-05-27
-3d9l,2008-06-10,2008-05-27
-4d9c,2012-05-30,2012-01-11
-7d9g,2021-11-17,2020-10-13
-8d9j,2023-07-05,2022-06-10
-2d9k,2006-06-10,2005-12-10
-1d9z,2000-05-03,1999-10-30
-8d9p,2022-09-28,2022-06-10
-7d9h,2021-11-17,2020-10-13
-2d9l,2006-12-11,2005-12-11
-5d9y,2015-11-04,2015-08-19
-8d98,2022-09-28,2022-06-09
-6d9m,2019-04-10,2018-04-30
-5d9l,2015-09-02,2015-08-18
-4d99,2012-05-30,2012-01-11
-7d9r,2021-08-11,2020-10-14
-3d9q,2009-06-02,2008-05-27
-3d97,2008-07-22,2008-05-26
-1d9d,1999-12-02,1999-10-27
-5d9o,2015-11-04,2015-08-18
-6d9j,2018-06-06,2018-04-30
-7d9e,2021-06-23,2020-10-13
-3d9z,2009-03-03,2008-05-28
-5d9n,2015-11-04,2015-08-18
-5d9k,2015-09-02,2015-08-18
-7d9q,2021-08-25,2020-10-14
-3d9u,2008-06-10,2008-05-27
-3d9c,2008-09-23,2008-05-27
-7d94,2021-01-27,2020-10-12
-4d91,2013-01-16,2012-01-11
-4d9z,2013-01-16,2012-01-12
-8d9w,2023-07-05,2022-06-11
-3d9n,2008-06-10,2008-05-27
-4d9w,2013-01-16,2012-01-12
-4d9f,2012-05-30,2012-01-11
-7d9l,2021-10-27,2020-10-13
-7d9w,2021-06-23,2020-10-14
-7d9i,2021-11-17,2020-10-13
-5d9g,2016-08-10,2015-08-18
-5d91,2015-11-11,2015-08-18
-3d9b,2008-07-01,2008-05-27
-8d99,2022-09-28,2022-06-09
-8d94,2023-07-05,2022-06-09
-4d96,2012-05-30,2012-01-11
-4d9n,2012-04-25,2012-01-11
-6d9f,2019-05-08,2018-04-28
-6d95,2018-08-08,2018-04-27
-8d9m,2022-09-14,2022-06-10
-1d9y,1999-11-17,1999-10-30
-5d9p,2015-11-04,2015-08-18
-3d9o,2008-06-10,2008-05-27
-6d9s,2019-05-01,2018-04-30
-6d9c,2019-05-15,2018-04-28
-3d9d,2009-04-07,2008-05-27
-8d9f,2023-06-14,2022-06-09
-6d9r,2019-05-01,2018-04-30
-4d9b,2012-05-30,2012-01-11
-8d9a,2022-09-28,2022-06-09
-7d9b,2021-08-11,2020-10-12
-2d9n,2006-06-12,2005-12-12
-4d90,2012-05-30,2012-01-11
-4d9h,2012-09-26,2012-01-11
-1d9u,2001-05-23,1999-10-30
-5d9f,2016-08-31,2015-08-18
-5d9c,2015-09-23,2015-08-18
-3d9k,2008-06-10,2008-05-27
-8d9b,2022-09-28,2022-06-09
-8d9g,2023-06-14,2022-06-09
-4d9e,2012-05-30,2012-01-11
-1d9x,2000-05-03,1999-10-30
-3d9g,2009-04-07,2008-05-27
-7d92,2021-01-27,2020-10-12
-1d9i,2000-10-30,1999-10-27
-6d9t,2019-05-08,2018-04-30
-4d97,2012-05-30,2012-01-11
-6d9x,2018-09-05,2018-04-30
-3d9f,2009-04-07,2008-05-27
-7d9s,2021-08-11,2020-10-14
-7d9c,2021-08-11,2020-10-13
-5d9j,2016-03-16,2015-08-18
-8d9c,2022-09-28,2022-06-09
-5d9b,2015-09-23,2015-08-18
-7d9j,2021-11-17,2020-10-13
-3d9s,2008-08-26,2008-05-27
-6d9h,2018-06-20,2018-04-29
-6d9y,2018-06-06,2018-04-30
-6d9d,2019-05-15,2018-04-28
-3d92,2008-09-02,2008-05-26
-8d9h,2023-06-14,2022-06-09
-5tr8,2018-05-09,2016-10-25
-1trp,1994-04-30,1993-07-06
-4tro,2015-04-29,2014-06-17
-6tra,2020-09-16,2019-12-18
-8tro,2024-04-17,2023-08-09
-3tro,2012-09-12,2011-09-09
-3tri,2011-09-28,2011-09-09
-3trp,2012-02-22,2011-09-09
-5tr1,2017-01-11,2016-10-25
-5trq,2017-11-29,2016-10-27
-3tr9,2011-09-28,2011-09-09
-7trf,2022-04-20,2022-01-28
-4trf,2015-09-30,2014-06-16
-6tr3,2020-10-28,2019-12-17
-6trv,2020-12-23,2019-12-19
-7trb,2022-06-29,2022-01-28
-6tr5,2020-01-15,2019-12-17
-5trb,2016-11-02,2016-10-25
-7tre,2022-04-20,2022-01-28
-8trm,2024-03-06,2023-08-09
-6trl,2021-06-30,2019-12-19
-4tr6,2014-09-10,2014-06-14
-7trm,2023-08-02,2022-01-29
-7tr8,2022-08-10,2022-01-28
-3tr3,2011-09-28,2011-09-09
-5trj,2016-11-30,2016-10-26
-6trh,2020-05-27,2019-12-18
-5trl,2017-12-06,2016-10-26
-5trs,2017-01-11,2016-10-27
-4trg,2014-07-02,2014-06-16
-4tr8,2014-09-10,2014-06-15
-1trm,1988-07-16,1987-10-21
-4try,2015-07-29,2014-06-18
-3tr5,2011-09-28,2011-09-09
-5trp,2017-03-15,2016-10-27
-1trh,1994-01-31,1993-11-18
-8tre,,2023-08-09
-1try,1996-01-01,1994-03-07
-4tr1,2014-10-01,2014-06-13
-6tr9,2020-02-19,2019-12-18
-7trg,2022-12-28,2022-01-28
-2trx,1991-10-15,1990-03-19
-3tr1,2011-09-28,2011-09-09
-5tri,2016-11-30,2016-10-26
-7trq,2023-05-17,2022-01-30
-7tr2,2022-07-13,2022-01-27
-5tr2,2017-02-08,2016-10-25
-7trs,2023-05-17,2022-01-30
-6tr4,2020-10-28,2019-12-17
-5trf,2016-11-09,2016-10-26
-7tr1,2022-07-20,2022-01-27
-5trx,2017-03-22,2016-10-27
-3trz,2011-11-16,2011-09-11
-3tr0,2011-09-21,2011-09-09
-6trz,2020-02-19,2019-12-19
-8try,2024-04-24,2023-08-10
-4tr9,2015-08-26,2014-06-15
-5trh,2016-11-30,2016-10-26
-1trd,1993-10-31,1992-10-06
-7trl,2023-08-02,2022-01-29
-1tro,1994-01-31,1992-08-30
-7trt,2023-03-15,2022-01-30
-6trt,2020-01-08,2019-12-19
-6trr,2020-06-03,2019-12-19
-3tru,2011-09-28,2011-09-10
-5trd,2016-11-23,2016-10-26
-6try,2021-01-13,2019-12-19
-3tr6,2011-09-28,2011-09-09
-3trn,2011-10-12,2011-09-09
-5trz,2018-05-09,2016-10-27
-4trj,2014-08-13,2014-06-17
-1tr5,2004-07-06,2004-06-20
-7tr3,2022-07-20,2022-01-27
-1trn,1995-06-03,1995-03-16
-7tr0,2022-07-20,2022-01-27
-6trw,2021-01-13,2019-12-19
-5tr3,2016-11-09,2016-10-25
-3tr8,2011-09-21,2011-09-09
-4trc,2014-07-30,2014-06-16
-4trn,2015-04-29,2014-06-17
-7tr7,2023-04-12,2022-01-28
-1trg,1998-08-12,1998-05-21
-6trd,2020-09-16,2019-12-18
-3trl,2011-10-12,2011-09-09
-6tr1,2019-12-25,2019-12-17
-7tra,2022-08-10,2022-01-28
-1trz,1994-01-31,1993-11-19
-6trc,2020-09-16,2019-12-18
-4trd,2014-07-16,2014-06-16
-5try,2017-01-11,2016-10-27
-1trb,1994-01-31,1991-09-07
-7trk,2023-05-17,2022-01-29
-3trq,2011-12-21,2011-09-09
-7trp,2023-05-17,2022-01-30
-5trr,2017-01-11,2016-10-27
-6trx,2021-01-13,2019-12-19
-3trd,2011-09-21,2011-09-09
-5tr9,2016-11-09,2016-10-25
-5trg,2017-01-11,2016-10-26
-4tri,2014-09-17,2014-06-17
-8trn,2024-03-06,2023-08-09
-8trt,2023-11-22,2023-08-10
-5tr4,2017-11-01,2016-10-25
-5trt,2016-11-16,2016-10-27
-7tro,2023-02-01,2022-01-29
-1trk,1994-04-30,1993-11-22
-5tr6,2016-11-30,2016-10-25
-5trk,2016-11-30,2016-10-26
-4tr0,2014-10-01,2014-06-13
-6tr8,2020-02-05,2019-12-18
-8tr1,2024-05-08,2023-08-09
-1trr,1993-10-21,1993-10-21
-6tr6,2020-01-08,2019-12-17
-7tri,2023-08-02,2022-01-28
-1tr7,2005-05-03,2004-06-21
-7trw,2022-02-09,2022-01-31
-7trd,2022-04-20,2022-01-28
-2trc,1997-06-05,1997-01-06
-4trw,2015-07-01,2014-06-18
-8trg,2023-11-15,2023-08-09
-4trz,2015-07-01,2014-06-18
-6trk,2020-08-12,2019-12-19
-2trm,1988-07-16,1988-04-25
-2trt,1996-06-20,1994-03-04
-5tr0,2017-11-01,2016-10-24
-8trs,2023-11-22,2023-08-10
-3trc,2011-09-28,2011-09-09
-6trq,2020-07-22,2019-12-19
-1trq,1994-04-30,1993-07-06
-4tr2,2014-09-17,2014-06-13
-3tr4,2011-10-19,2011-09-09
-3trk,2011-09-28,2011-09-09
-7tr9,2022-08-10,2022-01-28
-6trf,2020-01-08,2019-12-18
-8tr4,2024-04-24,2023-08-09
-7tru,2023-03-15,2022-01-31
-6tr7,2020-01-08,2019-12-17
-2trs,1997-04-01,1997-01-07
-5gwr,2017-10-25,2016-09-13
-4gwx,2013-09-04,2012-09-03
-4gws,2013-09-04,2012-09-03
-8gwf,2023-01-11,2022-09-17
-8gw7,2023-11-15,2022-09-16
-1gws,2003-02-13,2002-03-25
-8gww,2023-09-20,2022-09-17
-3gw1,2009-05-05,2009-03-31
-3gwu,2009-05-12,2009-04-01
-2gw3,2007-05-08,2006-05-03
-5gwo,2017-09-13,2016-09-12
-1gwc,2002-06-06,2002-03-14
-4gw2,2012-10-03,2012-08-31
-1gww,2003-03-20,2002-03-26
-1gwu,2003-03-28,2002-03-25
-8gws,2023-08-23,2022-09-17
-1gwt,2003-03-28,2002-03-25
-6gwi,2019-05-08,2018-06-25
-1gwr,2002-08-29,2002-03-22
-1gwv,2003-03-20,2002-03-26
-2gwk,2006-08-29,2006-05-04
-1gwg,2002-06-06,2002-03-15
-4gw9,2012-09-26,2012-09-01
-4gwi,2012-11-21,2012-09-03
-4gw5,2013-10-09,2012-08-31
-5gwj,2017-08-23,2016-09-12
-3gwf,2009-05-05,2009-04-01
-1gwx,2000-03-17,1999-03-17
-6gwg,2018-08-22,2018-06-24
-8gwi,2022-12-14,2022-09-17
-1gwh,2002-03-19,2002-03-15
-5gwe,2017-07-12,2016-09-11
-8gwd,2023-09-20,2022-09-16
-8gw6,2023-11-15,2022-09-16
-4gw1,2013-10-09,2012-08-31
-8gw4,2023-08-23,2022-09-16
-3gww,2009-05-12,2009-04-01
-4gwm,2012-09-19,2012-09-03
-4gw8,2012-10-03,2012-09-01
-8gwb,2022-12-07,2022-09-16
-1gwe,2002-04-26,2002-03-15
-3gwn,2009-07-07,2009-04-01
-8gw0,2023-09-20,2022-09-16
-2gwc,2006-06-20,2006-05-04
-4gw0,2012-10-03,2012-08-31
-3gwz,2010-04-07,2009-04-01
-8gwg,2022-12-14,2022-09-17
-4gw6,2013-05-01,2012-08-31
-8gw1,2023-10-25,2022-09-16
-3gwq,2009-04-14,2009-04-01
-6gw9,2018-09-05,2018-06-22
-8gwh,2023-09-20,2022-09-17
-3gws,2009-04-28,2009-04-01
-2gwr,2006-05-23,2006-05-05
-1gwl,2003-03-20,2002-03-19
-8gwe,2023-01-11,2022-09-16
-6gwe,2019-09-25,2018-06-23
-5gwk,2017-08-23,2016-09-12
-8gwm,2024-02-28,2022-09-17
-5gwz,2017-03-29,2016-09-14
-4gwe,2012-10-03,2012-09-02
-1gw2,2003-03-28,2002-03-03
-6gwv,2018-11-07,2018-06-26
-5gwt,2017-10-25,2016-09-13
-6gw1,2018-10-17,2018-06-21
-3gwg,2010-03-09,2009-04-01
-8gwk,2024-02-28,2022-09-17
-1gwq,2002-08-29,2002-03-22
-4gw3,2013-02-06,2012-08-31
-5gwy,2017-09-20,2016-09-14
-2gwl,2006-08-29,2006-05-04
-1gw1,2002-09-05,2002-03-01
-6gwd,2019-01-30,2018-06-22
-5gw8,2017-09-27,2016-09-09
-3gw9,2009-11-17,2009-03-31
-2gwj,2006-08-29,2006-05-04
-8gwa,2022-11-23,2022-09-16
-5gwp,2017-09-13,2016-09-12
-3gw5,2009-06-23,2009-03-31
-4gwj,2012-11-21,2012-09-03
-3gwd,2009-05-05,2009-03-31
-5gww,2017-09-20,2016-09-14
-5gwa,2017-07-12,2016-09-09
-4gww,2013-09-11,2012-09-03
-4gwb,2012-09-19,2012-09-01
-6gwc,2019-01-30,2018-06-22
-3gwl,2009-07-07,2009-04-01
-3gwo,2009-12-15,2009-04-01
-6gwb,2018-10-24,2018-06-22
-6gw3,2019-10-09,2018-06-21
-6gw0,2018-10-17,2018-06-21
-4gwl,2012-09-19,2012-09-03
-1gw6,2003-03-06,2002-03-07
-5gws,2017-10-25,2016-09-13
-1gwj,2002-06-27,2002-03-18
-6gw2,2018-10-17,2018-06-21
-1gw0,2002-07-31,2002-03-01
-5gwv,2017-09-20,2016-09-14
-5gwi,2017-08-23,2016-09-12
-1gwd,2002-06-06,2002-03-14
-3gwv,2009-05-12,2009-04-01
-3gwt,2010-04-07,2009-04-01
-1gwa,2002-06-06,2002-03-13
-1gwo,2003-03-28,2002-03-20
-3gw6,2010-02-02,2009-03-31
-6gwf,2018-08-22,2018-06-24
-1gw9,2002-06-06,2002-03-13
-3gw7,2009-04-14,2009-03-31
-6gwj,2019-07-03,2018-06-25
-8gwn,2022-12-14,2022-09-17
-8gw8,2023-06-14,2022-09-16
-4gwz,2013-09-04,2012-09-03
-2gwh,2006-05-16,2006-05-04
-2gwg,2006-05-23,2006-05-04
-5gwd,2017-02-15,2016-09-10
-4gwu,2013-09-04,2012-09-03
-4gwy,2013-09-11,2012-09-03
-4gw4,2013-04-17,2012-08-31
-2gwn,2006-06-06,2006-05-04
-6gwu,2018-11-07,2018-06-26
-4gwn,2012-09-19,2012-09-03
-1gwf,2002-04-26,2002-03-15
-6gw4,2018-10-17,2018-06-21
-8gwj,2023-09-20,2022-09-17
-5gwf,2017-06-21,2016-09-11
-3gwj,2009-05-05,2009-04-01
-5gwx,2016-11-23,2016-09-14
-1gwi,2003-01-29,2002-03-15
-6gwr,2018-08-08,2018-06-25
-5gw7,2016-10-12,2016-09-08
-2gwd,2006-06-20,2006-05-04
-1gwb,2003-02-06,2002-03-14
-6gwt,2018-08-15,2018-06-25
-8gwo,2022-11-30,2022-09-17
-4gwd,2012-09-26,2012-09-01
-2gw4,2007-05-08,2006-05-03
-2gws,2006-09-05,2006-05-05
-3gwc,2009-04-28,2009-03-31
-4gwc,2012-09-26,2012-09-01
-1gwn,2002-04-05,2002-03-19
-1gwm,2003-03-20,2002-03-19
-4gwa,2013-06-12,2012-09-01
-8gwr,2022-12-21,2022-09-17
-6gw8,2018-09-19,2018-06-22
-4rmo,2015-09-30,2014-10-21
-4rm1,2014-11-12,2014-10-18
-7rmb,2021-11-10,2021-07-27
-3rmu,2011-05-11,2011-04-21
-7rm3,2022-01-26,2021-07-26
-3rm7,2012-08-08,2011-04-20
-4rm2,2015-09-30,2014-10-18
-8rmo,2024-04-03,2024-01-08
-1rm0,2004-05-25,2003-11-26
-6rm3,2019-07-10,2019-05-05
-5rm2,2020-09-30,2020-09-16
-6rmw,2020-07-15,2019-05-07
-7rm5,2021-09-08,2021-07-26
-4rmk,2015-08-19,2014-10-21
-3rmz,2011-10-05,2011-04-21
-3rmw,2011-05-11,2011-04-21
-5rmg,2020-09-30,2020-09-16
-1rmq,2004-12-14,2003-11-28
-7rmo,2021-11-24,2021-07-27
-3rmj,2012-03-14,2011-04-20
-3rm6,2012-08-08,2011-04-20
-2rmc,1995-02-14,1994-01-07
-7rml,2022-11-02,2021-07-27
-3rm8,2011-08-24,2011-04-20
-6rma,2020-02-05,2019-05-06
-7rmd,2022-08-03,2021-07-27
-5rm9,2020-09-30,2020-09-16
-6rm7,2020-06-17,2019-05-05
-4rmj,2015-02-25,2014-10-21
-1rmy,2004-12-14,2003-11-28
-3rmf,2012-10-31,2011-04-20
-3rmm,2012-04-25,2011-04-21
-6rm1,2020-04-15,2019-05-03
-2rmp,1997-09-17,1997-05-30
-5rm3,2020-09-30,2020-09-16
-1rmt,2004-12-14,2003-11-28
-5rmc,2020-09-30,2020-09-16
-6rmk,2019-06-05,2019-05-07
-7rmi,2021-11-03,2021-07-27
-6rmb,2020-02-05,2019-05-06
-3rmo,2012-04-25,2011-04-21
-5rmd,2020-09-30,2020-09-16
-2rm2,1990-01-15,1988-10-03
-1rm3,2004-07-27,2003-11-27
-6rmd,2020-07-15,2019-05-06
-6rml,2019-06-12,2019-05-07
-4rme,2015-09-16,2014-10-21
-5rm0,2020-09-30,2020-09-16
-8rm7,2024-04-24,2024-01-05
-4rmh,2015-02-25,2014-10-21
-4rmg,2015-02-25,2014-10-21
-6rmx,2020-06-03,2019-05-07
-4rmi,2015-02-25,2014-10-21
-4rm0,2015-06-24,2014-10-18
-6rmy,2020-06-03,2019-05-07
-1rm6,2004-12-21,2003-11-27
-5rma,2020-09-30,2020-09-16
-5rml,2020-09-30,2020-09-16
-7rmz,2021-11-10,2021-07-28
-3rms,2011-05-11,2011-04-21
-3rml,2012-04-25,2011-04-21
-3rm1,2012-04-25,2011-04-20
-1rmh,1996-10-14,1995-07-31
-7rmu,2022-08-31,2021-07-28
-7rmv,2021-11-24,2021-07-28
-3rm0,2012-04-25,2011-04-20
-5rmm,2020-09-30,2020-09-16
-6rmn,2021-05-19,2019-05-07
-7rm6,2022-04-27,2021-07-26
-1rmg,1998-03-04,1997-02-26
-4rml,2015-08-19,2014-10-21
-2rma,1995-02-07,1994-01-07
-4rmp,2015-05-13,2014-10-22
-2rmn,2008-11-11,2007-11-01
-7rme,2021-11-10,2021-07-27
-4rm5,2014-11-19,2014-10-19
-6rm5,2020-06-17,2019-05-05
-4rmz,2016-01-13,2014-10-22
-5rmj,2020-09-30,2020-09-16
-6rme,2020-07-08,2019-05-06
-7rm7,2022-03-02,2021-07-26
-5rmb,2020-09-30,2020-09-16
-6rmc,2020-02-05,2019-05-06
-7rmj,2022-08-03,2021-07-27
-4rmn,2015-09-30,2014-10-21
-4rmc,2015-09-16,2014-10-21
-3rmn,2012-04-25,2011-04-21
-6rmf,2019-09-11,2019-05-06
-5rm5,2020-09-30,2020-09-16
-7rma,2022-05-11,2021-07-27
-5rm1,2020-09-30,2020-09-16
-7rmw,2021-12-22,2021-07-28
-6rm8,2020-02-05,2019-05-06
-7rmt,2021-11-10,2021-07-28
-6rmg,2019-10-09,2019-05-06
-5rmi,2020-09-30,2020-09-16
-8rm6,2024-04-24,2024-01-05
-2rmk,2007-11-13,2007-10-25
-3rm9,2011-08-24,2011-04-20
-5rmk,2020-09-30,2020-09-16
-3rme,2011-08-24,2011-04-20
-7rm0,2022-01-26,2021-07-26
-2rmb,1995-02-07,1994-01-07
-1rm8,2004-03-09,2003-11-27
-6rmm,2019-06-12,2019-05-07
-5rm4,2020-09-30,2020-09-16
-1rm5,2004-07-27,2003-11-27
-4rmd,2015-09-23,2014-10-21
-6rm9,2020-02-05,2019-05-06
-6rm2,2020-06-03,2019-05-04
-6rmp,2020-04-15,2019-05-07
-7rmp,2023-05-10,2021-07-28
-3rm4,2011-08-24,2011-04-20
-7rmk,2021-11-24,2021-07-27
-3rmk,2012-02-08,2011-04-21
-5rm6,2020-09-30,2020-09-16
-5rm8,2020-09-30,2020-09-16
-4rm4,2015-02-04,2014-10-18
-1rm4,2004-07-27,2003-11-27
-6rmr,2020-05-13,2019-05-07
-5rme,2020-09-30,2020-09-16
-1rmd,1997-07-23,1997-01-10
-7rm4,2022-02-09,2021-07-26
-1rmz,2004-12-14,2003-11-28
-7rmc,2021-11-24,2021-07-27
-7rm2,2021-11-10,2021-07-26
-5rm7,2020-09-30,2020-09-16
-3rmq,2011-05-11,2011-04-21
-3rmd,2011-08-10,2011-04-20
-4rm3,2015-09-30,2014-10-18
-3rmv,2011-05-18,2011-04-21
-2rm0,2007-11-06,2007-09-06
-5rmf,2020-09-30,2020-09-16
-6rms,2020-02-19,2019-05-07
-3rm2,2012-04-25,2011-04-20
-1rmv,1997-05-15,1997-02-11
-5rmh,2020-09-30,2020-09-16
-1rms,1992-07-15,1991-12-02
-3mr1,2010-05-26,2010-04-28
-6mrf,2018-10-31,2018-10-12
-4mru,2013-10-02,2013-09-17
-1mrb,1991-04-15,1990-05-14
-5mrw,2017-06-21,2016-12-27
-4mri,2014-07-30,2013-09-17
-3mre,2011-05-25,2010-04-29
-7mrb,2022-08-03,2021-05-07
-1mrs,2003-01-07,2002-09-18
-6mrg,2018-10-31,2018-10-12
-7mrh,2022-08-03,2021-05-07
-7mrg,2022-08-03,2021-05-07
-4mre,2014-04-16,2013-09-17
-4mr5,2013-11-27,2013-09-17
-5mrv,2018-01-17,2016-12-27
-5mr2,2017-06-14,2016-12-21
-5mrm,2017-07-19,2016-12-23
-7mri,2022-05-11,2021-05-07
-3mrl,2011-05-25,2010-04-29
-7mr6,2022-05-18,2021-05-07
-3mrh,2011-05-25,2010-04-29
-7mrc,2022-05-18,2021-05-07
-4mr9,2013-12-11,2013-09-17
-4mrw,2014-05-14,2013-09-17
-1mrj,1995-02-07,1994-07-01
-4mra,2014-05-07,2013-09-17
-4mrm,2013-12-11,2013-09-17
-1mrf,1995-02-14,1994-06-13
-4mrq,2014-01-08,2013-09-17
-7mrd,2022-05-18,2021-05-07
-1mrh,1995-02-07,1994-07-01
-5mra,2017-11-29,2016-12-22
-6mre,2019-01-09,2018-10-12
-6mrd,2020-04-15,2018-10-12
-1mr9,2003-08-26,2002-09-18
-6mrc,2020-04-15,2018-10-12
-6mrq,2020-07-01,2018-10-15
-1mrr,1994-01-31,1992-07-28
-5mrc,2017-02-15,2016-12-22
-4mr1,2014-06-04,2013-09-17
-5mrh,2017-05-17,2016-12-23
-5mr8,2018-01-17,2016-12-21
-4mrp,2014-03-19,2013-09-17
-3mr9,2011-05-25,2010-04-29
-3mr3,2010-06-30,2010-04-28
-6mrv,2019-10-02,2018-10-15
-4mr7,2013-12-11,2013-09-17
-6mr8,2019-01-30,2018-10-11
-1mrn,2003-01-07,2002-09-18
-7mra,2022-08-03,2021-05-07
-5mrk,2017-01-25,2016-12-23
-1mr8,2000-05-17,1999-04-13
-6mr2,2019-01-09,2018-10-11
-1mrd,1995-02-14,1994-06-13
-1mrx,2003-11-04,2002-09-18
-7mrp,2022-05-11,2021-05-07
-4mrg,2014-04-16,2013-09-17
-1mrq,2003-09-30,2002-09-18
-3mr6,2010-06-30,2010-04-28
-6mr9,2019-05-15,2018-10-12
-5mr6,2017-06-28,2016-12-21
-5mrq,2017-07-19,2016-12-23
-3mry,2010-06-23,2010-04-29
-3mrc,2011-05-25,2010-04-29
-6mrl,2019-10-16,2018-10-14
-6mr6,2019-01-09,2018-10-11
-5mrp,2017-07-19,2016-12-23
-4mrd,2014-04-16,2013-09-17
-7mr9,2022-08-03,2021-05-07
-1mrp,1998-01-28,1997-05-14
-5mr3,2017-06-14,2016-12-21
-4mrh,2014-04-30,2013-09-17
-5mre,2017-02-15,2016-12-22
-5mrt,2018-01-17,2016-12-26
-3mr2,2010-06-30,2010-04-28
-5mrn,2017-07-19,2016-12-23
-5mro,2017-07-19,2016-12-23
-1mrl,2003-08-26,2002-09-18
-3mrt,2011-01-05,2010-04-29
-6mrm,2019-10-16,2018-10-14
-4mrr,2014-03-19,2013-09-17
-6mrh,2019-01-09,2018-10-12
-2mrb,1991-04-15,1990-05-14
-4mrz,2014-05-14,2013-09-17
-3mr5,2010-06-30,2010-04-28
-1mrw,2003-11-04,2002-09-18
-4mrb,2014-01-08,2013-09-17
-1mr3,2002-11-20,2002-09-17
-4mr8,2013-12-11,2013-09-17
-4mr6,2013-11-27,2013-09-17
-5mrl,2017-01-11,2016-12-23
-3mrx,2011-01-05,2010-04-29
-7mrr,2021-05-19,2021-05-08
-5mr0,2018-01-17,2016-12-21
-3mrj,2011-05-25,2010-04-29
-1mre,1995-02-14,1994-06-13
-4mr3,2013-11-27,2013-09-17
-5mri,2017-05-17,2016-12-23
-1mr2,2003-08-05,2002-09-17
-1mrt,1991-04-15,1990-05-14
-4mro,2014-05-07,2013-09-17
-4mrx,2014-03-12,2013-09-17
-4mrs,2014-03-19,2013-09-17
-4mrc,2014-01-08,2013-09-17
-3mrk,2011-05-25,2010-04-29
-3mrd,2011-05-25,2010-04-29
-7mr7,2022-05-11,2021-05-07
-5mru,2018-01-17,2016-12-26
-4mr4,2013-11-27,2013-09-17
-1mra,1996-08-01,1996-03-12
-6mr5,2018-12-05,2018-10-11
-4mrt,2014-04-23,2013-09-17
-3mru,2010-09-01,2010-04-29
-3mrv,2011-01-05,2010-04-29
-6mr0,2019-01-09,2018-10-11
-5mrd,2017-01-18,2016-12-22
-1mro,1998-11-11,1997-10-01
-1mrg,1995-02-07,1994-07-01
-4mrv,2014-03-19,2013-09-17
-1mrc,1995-02-14,1994-06-13
-7mr5,2022-05-18,2021-05-07
-2mrt,1991-04-15,1990-05-14
-6mro,2018-10-24,2018-10-15
-4mrf,2014-04-16,2013-09-17
-5mrr,2018-01-17,2016-12-26
-7mr8,2022-05-11,2021-05-07
-1mru,2003-02-11,2002-09-18
-7mrz,2022-01-19,2021-05-10
-5mrs,2018-01-17,2016-12-26
-6mr1,2019-01-02,2018-10-11
-5mrb,2017-07-26,2016-12-22
-3mrw,2010-06-23,2010-04-29
-5mrf,2017-02-15,2016-12-22
-3mrf,2011-05-25,2010-04-29
-6mrj,2019-11-20,2018-10-13
-2mrf,2014-10-01,2014-07-03
-3mrg,2011-05-25,2010-04-29
-3mrb,2011-05-25,2010-04-29
-6mri,2019-01-09,2018-10-12
-3mri,2011-05-25,2010-04-29
-4mry,2014-03-12,2013-09-17
-4mr0,2014-02-05,2013-09-17
-1mrk,1995-02-07,1994-07-01
-2mre,2014-10-22,2014-07-03
-6mr7,2019-01-30,2018-10-11
-1mr1,2003-01-21,2002-09-17
-1uk4,2003-11-18,2003-08-14
-1uk7,2004-09-14,2003-08-19
-1uka,2004-09-14,2003-08-19
-6ukf,2019-12-18,2019-10-04
-1uki,2004-08-30,2003-08-23
-6uke,2019-12-18,2019-10-04
-7ukg,2022-06-29,2022-04-01
-8uk2,2024-03-27,2023-10-12
-2ukd,1998-05-20,1997-05-20
-6uk3,2019-10-16,2019-10-04
-5ukm,2017-04-12,2017-01-23
-3ukq,2012-02-22,2011-11-09
-1ukg,2004-02-10,2003-08-21
-1uky,1995-01-26,1994-07-13
-6uk0,2019-12-25,2019-10-03
-8ukq,2024-04-24,2023-10-15
-5uk7,2018-05-09,2017-01-20
-6uko,2020-02-12,2019-10-05
-3uk4,2011-11-23,2011-11-09
-7uk7,2023-02-15,2022-03-31
-5ukg,2018-02-07,2017-01-22
-3ukd,1998-05-20,1997-05-20
-6ukw,2020-08-19,2019-10-06
-6uk1,2020-10-07,2019-10-03
-5ukj,2017-05-10,2017-01-23
-3uk2,2011-11-16,2011-11-08
-7uk8,2023-02-15,2022-03-31
-5uka,2018-01-24,2017-01-20
-6uka,2020-08-12,2019-10-04
-6ukm,2020-08-19,2019-10-05
-6ukx,2020-08-19,2019-10-06
-1uku,2004-01-13,2003-09-01
-1ukc,2004-07-27,2003-08-19
-3uku,2013-02-13,2011-11-09
-3ukk,2012-02-22,2011-11-09
-3ukr,2013-02-13,2011-11-09
-1uk8,2004-09-14,2003-08-19
-3uko,2012-11-14,2011-11-09
-6ukh,2019-12-18,2019-10-04
-5uk5,2017-03-08,2017-01-19
-6uk6,2020-10-07,2019-10-04
-7ukd,2022-06-29,2022-04-01
-7ukk,2022-10-05,2022-04-01
-8uks,2024-04-24,2023-10-15
-5ukd,1999-08-14,1999-04-18
-4ukd,1998-05-20,1997-05-20
-3uk3,2012-12-05,2011-11-08
-8uk5,2024-06-05,2023-10-12
-7ukp,2022-08-17,2022-04-01
-1ukm,2003-11-04,2003-08-27
-7ukt,2022-08-17,2022-04-01
-7ukw,2022-11-23,2022-04-02
-3uk9,2012-11-14,2011-11-09
-7ukv,2022-11-23,2022-04-02
-6uki,2019-12-18,2019-10-04
-7uk1,2022-09-21,2022-03-31
-7uko,2022-08-17,2022-04-01
-1ukt,2004-02-24,2003-09-01
-7uk9,2022-08-17,2022-03-31
-8ukr,2024-04-24,2023-10-15
-3uk0,2011-11-23,2011-11-08
-7ukz,2022-10-26,2022-04-03
-5ukf,2017-03-29,2017-01-22
-8uke,2024-03-20,2023-10-12
-8uk3,2024-03-27,2023-10-12
-5ukr,2017-12-06,2017-01-23
-8uk4,2024-03-20,2023-10-12
-6uk2,2020-08-19,2019-10-04
-7ukl,2023-10-04,2022-04-01
-5ukw,2017-04-19,2017-01-23
-7ukf,2022-06-29,2022-04-01
-6ukj,2019-12-04,2019-10-05
-5uk9,2018-01-10,2017-01-20
-1ukw,2004-11-09,2003-09-02
-1ukv,2004-09-01,2003-09-01
-3ukm,2012-02-08,2011-11-09
-1uk0,2004-01-27,2003-08-13
-1uks,2004-02-24,2003-09-01
-8ukz,2024-01-10,2023-10-15
-3ukj,2011-11-23,2011-11-09
-7ukr,2022-07-27,2022-04-01
-6uku,2020-08-19,2019-10-06
-5uk8,2017-06-14,2017-01-20
-7ukh,2022-06-29,2022-04-01
-7uk2,2022-11-02,2022-03-31
-6ukn,2020-06-10,2019-10-05
-7ukm,2023-10-04,2022-04-01
-5uk1,2017-05-31,2017-01-19
-6ukl,2020-07-08,2019-10-05
-3ukl,2012-02-22,2011-11-09
-6ukk,2020-07-08,2019-10-05
-3uka,2012-02-22,2011-11-09
-3ukp,2012-02-22,2011-11-09
-6ukz,2020-08-19,2019-10-06
-3ukg,2011-12-07,2011-11-09
-3ukh,2012-02-22,2011-11-09
-6uk5,2020-10-07,2019-10-04
-8uk9,2023-12-13,2023-10-12
-7ukc,2022-06-29,2022-04-01
-1ukz,1995-01-26,1994-07-13
-1uke,1998-04-29,1998-01-07
-3uk6,2012-07-25,2011-11-09
-8ukt,2024-04-24,2023-10-15
-7uka,2023-02-15,2022-03-31
-7uks,2022-07-27,2022-04-01
-6uky,2020-08-19,2019-10-06
-6ukb,2020-10-07,2019-10-04
-1uk9,2004-09-14,2003-08-19
-6ukd,2020-09-09,2019-10-04
-5uki,2018-02-21,2017-01-22
-8uk6,2024-03-06,2023-10-12
-1uk1,2004-09-14,2003-08-14
-7uk5,2022-06-29,2022-03-31
-6uks,2020-02-05,2019-10-05
-3uk8,2012-07-11,2011-11-09
-6uk4,2020-08-19,2019-10-04
-5ukh,2017-07-26,2017-01-22
-5ukl,2017-04-05,2017-01-23
-7uke,2022-06-29,2022-04-01
-6ukv,2020-08-19,2019-10-06
-5ukv,2017-12-06,2017-01-23
-5uky,2017-12-06,2017-01-23
-5uk0,2017-05-31,2017-01-19
-5ukk,2017-04-05,2017-01-23
-3ukf,2012-02-22,2011-11-09
-1ukq,2004-02-24,2003-09-01
-5uk2,2017-05-31,2017-01-19
-8uku,2024-04-24,2023-10-15
-8c6e,2023-07-05,2023-01-11
-4c6f,2014-02-05,2013-09-18
-2c63,2005-11-21,2005-11-07
-6c6a,2019-01-30,2018-01-18
-7c6k,2020-09-16,2020-05-21
-4c61,2014-01-08,2013-09-17
-7c64,2020-09-16,2020-05-21
-5c6m,2016-02-03,2015-06-23
-7c66,2020-09-16,2020-05-21
-1c6t,2000-10-04,1999-12-21
-8c6s,2023-05-24,2023-01-12
-3c6q,2008-02-26,2008-02-05
-1c68,2000-10-04,1999-12-21
-5c6x,2016-07-13,2015-06-23
-7c6w,2020-09-16,2020-05-22
-3c6p,2008-04-22,2008-02-04
-4c6m,2014-01-08,2013-09-18
-1c6j,2000-10-04,1999-12-21
-1c6q,2000-10-04,1999-12-21
-1c6z,2000-12-28,1999-12-28
-6c69,2019-01-30,2018-01-18
-2c69,2005-12-07,2005-11-08
-1c64,2000-10-04,1999-12-21
-5c68,2016-07-13,2015-06-22
-7c63,2020-09-16,2020-05-21
-5c6y,2015-11-11,2015-06-24
-4c68,2014-09-24,2013-09-17
-6c6f,2019-01-30,2018-01-18
-7c69,2020-09-16,2020-05-21
-3c6o,2008-04-22,2008-02-04
-7c6b,2020-11-25,2020-05-21
-2c67,2006-01-04,2005-11-07
-4c6v,2013-10-09,2013-09-19
-4c6n,2014-02-05,2013-09-18
-2c6i,2005-12-07,2005-11-10
-2c6m,2005-12-07,2005-11-10
-1c6y,2000-12-28,1999-12-28
-5c6l,2015-07-08,2015-06-23
-2c6g,2006-02-15,2005-11-09
-5c6j,2015-07-08,2015-06-23
-4c62,2014-01-08,2013-09-17
-6c62,2018-03-21,2018-01-17
-7c6d,2021-03-31,2020-05-21
-1c6a,2000-10-04,1999-12-21
-7c6n,2020-09-16,2020-05-21
-4c6u,2013-10-09,2013-09-19
-2c6w,2005-12-07,2005-11-14
-8c6h,2023-11-01,2023-01-11
-4c6s,2014-05-28,2013-09-19
-1c6r,2000-04-12,1999-04-06
-8c6c,2023-11-01,2023-01-11
-7c61,2020-07-29,2020-05-21
-1c6o,2000-04-12,1999-04-07
-2c6l,2005-12-07,2005-11-10
-6c6i,2018-10-17,2018-01-18
-5c6a,2015-07-08,2015-06-22
-7c6j,2020-09-16,2020-05-21
-1c6f,2000-10-04,1999-12-21
-1c6c,2000-10-04,1999-12-21
-3c6w,2008-06-03,2008-02-05
-4c6j,2014-02-05,2013-09-18
-7c67,2020-10-21,2020-05-21
-2c6a,2006-01-04,2005-11-08
-5c65,2015-07-08,2015-06-22
-8c6p,2023-05-24,2023-01-12
-6c6z,2018-01-31,2018-01-19
-8c6a,2023-11-01,2023-01-11
-5c6v,2015-08-05,2015-06-23
-6c6h,2019-01-30,2018-01-18
-3c6t,2008-04-22,2008-02-05
-6c6n,2019-01-16,2018-01-19
-2c6r,2007-02-20,2005-11-11
-4c6x,2013-10-09,2013-09-19
-6c6j,2019-01-30,2018-01-18
-1c67,2000-10-04,1999-12-21
-6c6c,2019-01-30,2018-01-18
-8c6z,2023-05-31,2023-01-12
-3c6e,2008-04-08,2008-02-04
-4c6y,2014-04-16,2013-09-19
-5c6p,2015-09-23,2015-06-23
-6c6s,2018-07-25,2018-01-19
-5c6e,2016-06-22,2015-06-22
-8c6m,2024-04-24,2023-01-12
-6c6g,2018-03-21,2018-01-18
-7c68,2020-09-16,2020-05-21
-1c6i,2000-10-04,1999-12-21
-2c6b,2006-01-04,2005-11-08
-1c6k,2000-10-04,1999-12-21
-5c66,2016-06-01,2015-06-22
-5c6u,2015-07-15,2015-06-23
-3c62,2008-05-06,2008-02-02
-5c6d,2015-09-09,2015-06-22
-4c6d,2014-02-05,2013-09-18
-1c6h,2000-10-04,1999-12-21
-6c6r,2019-01-16,2018-01-19
-7c6p,2021-05-12,2020-05-22
-4c6o,2014-02-05,2013-09-18
-3c61,2008-02-26,2008-02-01
-7c6h,2020-10-21,2020-05-21
-4c6q,2014-02-05,2013-09-18
-8c6b,2023-11-01,2023-01-11
-2c66,2006-01-04,2005-11-07
-2c64,2006-01-04,2005-11-07
-4c6k,2014-02-05,2013-09-18
-7c6g,2020-10-21,2020-05-21
-7c60,2020-08-05,2020-05-21
-8c6g,2023-07-05,2023-01-11
-3c6k,2008-02-19,2008-02-04
-2c6k,2005-12-07,2005-11-10
-3c6v,2008-02-19,2008-02-05
-7c6a,2020-07-29,2020-05-21
-2c6p,2006-02-15,2005-11-11
-1c6e,2000-10-04,1999-12-21
-2c6f,2006-11-08,2005-11-09
-6c6e,2019-01-30,2018-01-18
-7c6o,2020-12-02,2020-05-22
-7c6l,2020-09-16,2020-05-21
-3c6g,2008-02-19,2008-02-04
-7c6v,2020-09-16,2020-05-22
-5c6q,2015-08-05,2015-06-23
-8c6o,2023-03-29,2023-01-12
-6c6o,2018-09-05,2018-01-19
-8c69,2023-11-01,2023-01-11
-4c6e,2014-02-05,2013-09-18
-2c68,2005-12-07,2005-11-08
-7c6i,2020-09-16,2020-05-21
-2c6y,2006-04-18,2005-11-15
-3c6n,2008-04-22,2008-02-04
-6c6t,2018-07-25,2018-01-19
-8c6n,2024-04-24,2023-01-12
-6c6p,2019-01-16,2018-01-19
-4c6h,2014-05-14,2013-09-18
-8c6q,2023-05-24,2023-01-12
-7c6u,2020-09-02,2020-05-22
-1c65,2000-10-04,1999-12-21
-2c6t,2005-12-07,2005-11-11
-2c6c,2006-02-15,2005-11-09
-4c6z,2013-10-09,2013-09-19
-5c6f,2016-07-27,2015-06-23
-3c6l,2008-04-29,2008-02-04
-4c6c,2014-01-08,2013-09-18
-5c6o,2015-09-23,2015-06-23
-2c6d,2006-01-11,2005-11-09
-7c6m,2020-09-16,2020-05-21
-1c6s,1998-04-08,1997-03-31
-2c60,2005-11-29,2005-11-04
-7c6t,2020-09-16,2020-05-22
-3c6h,2009-01-13,2008-02-04
-1c6b,2000-10-04,1999-12-21
-8c6k,2023-11-22,2023-01-12
-1c6x,2000-12-28,1999-12-28
-8c6t,2023-05-24,2023-01-12
-7c6q,2021-05-26,2020-05-22
-1c6n,2000-10-04,1999-12-21
-4c6w,2013-10-09,2013-09-19
-6c6w,2018-02-07,2018-01-19
-6c6q,2018-09-12,2018-01-19
-3c6m,2008-02-19,2008-02-04
-7c65,2020-10-14,2020-05-21
-1c6m,2000-10-04,1999-12-21
-5c6t,2015-09-23,2015-06-23
-6c67,2019-05-01,2018-01-17
-3c6s,2008-07-01,2008-02-05
-1c6d,2000-10-04,1999-12-21
-2c6h,2006-07-03,2005-11-09
-2c6e,2006-01-11,2005-11-09
-3c6u,2008-04-22,2008-02-05
-3c63,2008-05-06,2008-02-02
-6c6k,2018-04-04,2018-01-18
-1c62,2000-10-04,1999-12-21
-4c6p,2014-02-05,2013-09-18
-2c6q,2005-11-30,2005-11-11
-2c6z,2006-05-17,2005-11-16
-1c66,2000-10-04,1999-12-21
-6c66,2018-06-27,2018-01-17
-4c69,2014-06-04,2013-09-17
-7c6s,2020-09-02,2020-05-22
-3c6c,2008-02-19,2008-02-04
-8c6l,2024-04-24,2023-01-12
-6c6b,2018-02-07,2018-01-18
-5c6c,2016-01-20,2015-06-22
-2c6o,2005-12-07,2005-11-10
-8c6j,2023-07-12,2023-01-12
-1c6g,2000-10-04,1999-12-21
-5c6i,2015-07-08,2015-06-23
-2c6x,2007-06-26,2005-11-14
-4c6l,2014-02-05,2013-09-18
-3c6a,2009-01-13,2008-02-04
-6c6u,2018-07-25,2018-01-19
-7c6r,2020-09-16,2020-05-22
-4c6i,2014-01-08,2013-09-18
-2c6n,2006-03-15,2005-11-10
-1c61,2000-10-04,1999-12-21
-8c6i,2023-02-01,2023-01-11
-8c60,2023-05-10,2023-01-10
-2c65,2006-01-04,2005-11-07
-4c66,2013-10-02,2013-09-17
-8c6f,2023-11-01,2023-01-11
-4c67,2013-10-02,2013-09-17
-108m,1998-05-20,1997-12-23
-208l,1996-10-14,1996-03-26
-1te3,2005-01-25,2004-05-24
-6te3,2021-05-19,2019-11-11
-6tee,2020-02-05,2019-11-11
-5ter,2017-01-11,2016-09-22
-6tez,2021-05-19,2019-11-12
-3tei,2012-08-15,2011-08-15
-7te7,2022-01-19,2022-01-04
-6tei,2020-07-08,2019-11-12
-1te1,2004-07-20,2004-05-24
-8te4,2024-03-13,2023-07-05
-6tel,2019-12-11,2019-11-12
-8ted,2024-04-17,2023-07-06
-5tea,2016-10-05,2016-09-20
-3teg,2011-11-23,2011-08-14
-6te6,2019-12-11,2019-11-11
-3te4,2012-07-11,2011-08-12
-7tey,2022-03-16,2022-01-06
-1tei,1997-08-20,1997-05-28
-5te1,2017-08-09,2016-09-20
-3tel,2011-10-12,2011-08-15
-7te0,2022-01-12,2022-01-03
-5tem,2017-10-18,2016-09-22
-5teg,2016-12-07,2016-09-21
-5te4,2016-11-23,2016-09-20
-1tem,1997-05-15,1996-05-28
-5te6,2016-11-16,2016-09-20
-7te2,2022-08-31,2022-01-04
-7ten,2022-06-29,2022-01-05
-7tel,2023-01-11,2022-01-05
-5tek,2017-10-18,2016-09-21
-3tex,2011-10-26,2011-08-15
-7tez,2022-03-16,2022-01-06
-7te5,2022-01-12,2022-01-04
-5tet,2017-08-09,2016-09-22
-6teu,2021-05-19,2019-11-12
-7teu,2023-06-21,2022-01-05
-2tep,1999-04-08,1999-04-05
-3tet,2011-10-19,2011-08-15
-1tez,2004-12-14,2004-05-26
-7ted,2022-04-06,2022-01-04
-6ted,2020-07-22,2019-11-11
-3tea,2012-08-15,2011-08-12
-5te2,2017-05-31,2016-09-20
-6te2,2020-07-08,2019-11-11
-1te6,2004-09-21,2004-05-24
-1tex,2004-07-20,2004-05-25
-3tem,2011-09-21,2011-08-15
-1tec,1989-10-15,1989-05-24
-1tef,2005-11-01,2004-05-25
-6tec,2021-05-19,2019-11-11
-6te1,2020-06-03,2019-11-11
-5te5,2017-03-15,2016-09-20
-8teo,2023-12-20,2023-07-06
-3teh,2011-11-23,2011-08-14
-5ten,2017-10-18,2016-09-22
-5tez,2017-09-27,2016-09-23
-7tem,2022-01-19,2022-01-05
-8te3,2024-03-13,2023-07-05
-7tea,2022-06-29,2022-01-04
-3tep,2011-10-12,2011-08-15
-1teh,1996-12-07,1996-02-05
-6tes,2021-05-19,2019-11-12
-3te5,2011-11-09,2011-08-12
-5te3,2017-03-15,2016-09-20
-5tew,2016-10-05,2016-09-22
-5te8,2016-12-07,2016-09-20
-7tev,2022-04-06,2022-01-05
-7tep,2022-06-29,2022-01-05
-3te9,2011-08-24,2011-08-12
-5ted,2017-10-18,2016-09-21
-6ter,2020-06-10,2019-11-12
-8tef,2024-04-17,2023-07-06
-2tec,1992-01-15,1990-10-26
-8teb,2024-03-13,2023-07-06
-1teq,2005-01-25,2004-05-25
-7te8,2022-01-12,2022-01-04
-5teq,2017-08-09,2016-09-22
-6tek,2020-04-01,2019-11-12
-6tef,2020-02-05,2019-11-11
-6te4,2020-11-04,2019-11-11
-3tew,2011-10-26,2011-08-15
-6teo,2020-03-18,2019-11-12
-7tei,2022-02-16,2022-01-05
-5tes,2017-08-09,2016-09-22
-7tef,2022-11-30,2022-01-04
-1teu,2005-01-25,2004-05-25
-6tev,2021-05-26,2019-11-12
-8te1,2024-03-13,2023-07-05
-1tes,1996-11-08,1996-05-06
-6te5,2020-11-18,2019-11-11
-3te7,2011-09-21,2011-08-12
-5teh,2017-09-27,2016-09-21
-3tec,1992-01-15,1990-10-26
-6tet,2021-05-26,2019-11-12
-6tej,2020-04-01,2019-11-12
-7tek,2023-01-11,2022-01-05
-5tej,2017-10-18,2016-09-21
-7tex,2022-03-30,2022-01-06
-3teb,2011-08-31,2011-08-12
-5tex,2017-10-11,2016-09-23
-5te7,2016-11-16,2016-09-20
-3tey,2011-10-26,2011-08-15
-6tex,2021-05-19,2019-11-12
-5tey,2016-11-23,2016-09-23
-3tez,2011-10-26,2011-08-15
-8tey,2023-08-30,2023-07-07
-5tel,2017-10-11,2016-09-22
-5te0,2016-11-02,2016-09-20
-6teq,2020-06-10,2019-11-12
-5tei,2017-09-27,2016-09-21
-6tew,2020-07-08,2019-11-12
-6teg,2020-02-05,2019-11-11
-1teg,2005-11-01,2004-05-25
-1te2,2004-08-03,2004-05-24
-7teh,2022-03-02,2022-01-05
-6te7,2021-05-26,2019-11-11
-6ten,2019-12-11,2019-11-12
-6tep,2020-06-10,2019-11-12
-3ten,2011-10-19,2011-08-15
-7tew,2022-03-16,2022-01-06
-6te0,2019-11-27,2019-11-10
-5mip,2017-04-12,2016-11-29
-5miw,2017-12-20,2016-11-29
-4mij,2013-09-18,2013-08-31
-5mic,2017-05-10,2016-11-28
-1miy,2002-12-13,2002-08-23
-7mim,2021-07-21,2021-04-17
-5mim,2017-05-10,2016-11-28
-1mic,1997-02-12,1996-05-22
-7mif,2021-10-13,2021-04-16
-3mi0,2010-06-23,2010-04-09
-5mi3,2017-12-20,2016-11-27
-6mit,2019-03-27,2018-09-20
-6mi1,2019-05-29,2018-09-18
-1mi4,2002-12-18,2002-08-21
-3mia,2010-06-09,2010-04-09
-7mio,2021-07-21,2021-04-17
-6miy,2019-01-09,2018-09-20
-2miu,2014-01-15,2013-12-20
-4mik,2014-09-10,2013-08-31
-2mij,2014-03-12,2013-12-13
-3mi2,2010-05-26,2010-04-09
-7mip,2021-10-13,2021-04-17
-7mi5,2021-11-17,2021-04-16
-4mic,2014-07-23,2013-08-30
-4miy,2015-03-04,2013-09-02
-3miy,2010-06-30,2010-04-12
-4mi9,2014-07-23,2013-08-30
-1miu,2002-09-25,2002-08-23
-3mib,2010-11-24,2010-04-10
-4mig,2013-12-11,2013-08-31
-3mi3,2010-04-28,2010-04-09
-6mio,2018-11-14,2018-09-19
-5miu,2017-07-12,2016-11-29
-7mig,2021-10-13,2021-04-16
-2mip,1993-10-31,1993-06-03
-7miz,2021-06-02,2021-04-18
-1miz,2003-01-28,2002-08-23
-7mis,2021-08-18,2021-04-17
-6mi8,2019-04-03,2018-09-19
-3mis,2010-05-19,2010-04-12
-6mi0,2019-07-10,2018-09-18
-5miv,2017-07-12,2016-11-29
-5mib,2017-05-10,2016-11-28
-5mih,2017-10-11,2016-11-28
-3min,1997-04-01,1996-12-20
-6mis,2018-10-03,2018-09-20
-4mi6,2014-07-23,2013-08-30
-7mih,2021-10-13,2021-04-16
-7mi4,2021-11-17,2021-04-16
-3mit,2010-09-08,2010-04-12
-4miu,2013-10-02,2013-09-02
-5mi4,2017-11-01,2016-11-27
-7mi3,2021-05-26,2021-04-16
-1miv,2002-12-13,2002-08-23
-5mio,2017-07-19,2016-11-28
-5mie,2017-05-10,2016-11-28
-1mid,2004-04-06,2002-08-23
-7mix,2021-07-07,2021-04-18
-6miv,2019-01-09,2018-09-20
-1mik,1996-03-08,1995-09-20
-5mif,2017-08-23,2016-11-28
-4mih,2013-12-11,2013-08-31
-7miu,2021-10-13,2021-04-17
-4mix,2013-10-16,2013-09-02
-6mif,2018-10-31,2018-09-19
-7mir,2021-08-18,2021-04-17
-3mig,2010-11-24,2010-04-10
-4mi1,2014-04-23,2013-08-30
-6miu,2018-10-31,2018-09-20
-7mi9,2021-11-17,2021-04-16
-3mio,2011-02-23,2010-04-11
-6min,2018-11-14,2018-09-19
-4miv,2014-05-14,2013-09-02
-4mio,2015-03-04,2013-09-02
-5mi8,2017-12-20,2016-11-27
-6mij,2018-10-03,2018-09-19
-5mit,2017-04-12,2016-11-29
-6mid,2019-01-16,2018-09-19
-3mi9,2010-06-09,2010-04-09
-5mi6,2017-11-01,2016-11-27
-3mif,2010-11-24,2010-04-10
-6mik,2019-02-27,2018-09-19
-4mi0,2013-09-25,2013-08-30
-5mi9,2017-12-20,2016-11-27
-5min,2017-12-20,2016-11-28
-3miv,2010-09-08,2010-04-12
-1mih,2003-04-08,2002-08-23
-4mia,2014-05-07,2013-08-30
-4mif,2013-12-11,2013-08-31
-3miu,2010-09-08,2010-04-12
-5miy,2018-05-23,2016-11-29
-6mi6,2018-12-05,2018-09-19
-4mit,2014-09-03,2013-09-02
-5mil,2017-09-06,2016-11-28
-7mil,2021-07-21,2021-04-17
-3mi4,2010-04-28,2010-04-09
-7mie,2021-06-30,2021-04-16
-5mi7,2017-11-01,2016-11-27
-1mio,1993-10-31,1993-03-24
-5mid,2017-05-10,2016-11-28
-6mi2,2018-11-21,2018-09-19
-3mi5,2011-04-27,2010-04-09
-1mi3,2003-08-05,2002-08-21
-1miw,2002-12-13,2002-08-23
-5mi1,2017-05-10,2016-11-27
-2min,1997-04-01,1996-12-20
-3mid,2010-11-24,2010-04-10
-3mip,2010-05-19,2010-04-11
-6mig,2019-02-27,2018-09-19
-7mit,2021-10-13,2021-04-17
-7miv,2021-10-13,2021-04-17
-3mic,2010-11-24,2010-04-10
-2miq,2014-01-29,2013-12-17
-5miq,2017-04-12,2016-11-29
-4min,2015-03-04,2013-09-01
-7min,2021-07-21,2021-04-17
-6mil,2018-11-14,2018-09-19
-5mik,2017-03-15,2016-11-28
-6mih,2019-02-27,2018-09-19
-6miq,2018-11-14,2018-09-19
-7mi6,2021-05-26,2021-04-16
-4miw,2014-03-19,2013-09-02
-5mij,2017-03-15,2016-11-28
-4mi3,2014-07-23,2013-08-30
-5mi2,2017-05-10,2016-11-27
-7mii,2021-10-13,2021-04-16
-4mim,2014-08-13,2013-09-01
-3mie,2010-11-24,2010-04-10
-5mig,2017-05-10,2016-11-28
-5mis,2017-04-12,2016-11-29
-7miy,2021-07-07,2021-04-18
-7mid,2021-11-17,2021-04-16
-5mi5,2017-11-01,2016-11-27
-7mij,2021-07-21,2021-04-17
-1mi5,2003-02-04,2002-08-21
-4mi5,2014-01-08,2013-08-30
-6mi5,2018-11-07,2018-09-19
-7mik,2021-07-21,2021-04-17
-4mib,2014-05-07,2013-08-30
-3mi1,2011-04-27,2010-04-09
-5mir,2017-04-12,2016-11-29
-3mih,2010-11-24,2010-04-10
-6mim,2018-11-14,2018-09-19
-6mia,2019-04-17,2018-09-19
-5mia,2017-05-10,2016-11-28
-7tql,2022-04-27,2022-01-26
-5tqf,2017-02-01,2016-10-24
-8tq0,2023-09-20,2023-08-06
-3tql,2011-10-05,2011-09-09
-7tq3,2022-06-22,2022-01-26
-8tqp,2023-12-20,2023-08-08
-3tq4,2011-10-12,2011-09-09
-5tqu,2017-04-12,2016-10-24
-6tqz,2020-04-15,2019-12-17
-5tqg,2017-02-01,2016-10-24
-7tqd,2023-01-11,2022-01-26
-3tqw,2011-09-21,2011-09-09
-3tq1,2012-02-08,2011-09-08
-5tqp,2017-11-01,2016-10-24
-5tq8,2017-01-11,2016-10-23
-5tqo,2017-11-01,2016-10-24
-7tqy,2022-07-20,2022-01-27
-5tqr,2017-06-14,2016-10-24
-7tq6,2022-02-09,2022-01-26
-6tqh,2020-06-03,2019-12-16
-6tqs,2020-11-18,2019-12-17
-6tqk,2020-11-04,2019-12-16
-7tqz,2022-07-13,2022-01-27
-7tq5,2022-02-09,2022-01-26
-5tq4,2017-01-11,2016-10-23
-6tqn,2020-08-05,2019-12-17
-4tqp,2015-06-24,2014-06-11
-5tqh,2017-01-25,2016-10-24
-6tqg,2020-08-19,2019-12-16
-6tq0,2021-01-13,2019-12-15
-1tqt,2005-01-25,2004-06-18
-7tq2,2022-06-22,2022-01-26
-6tqq,2020-06-03,2019-12-17
-3tqb,2011-11-02,2011-09-09
-7tq0,2022-09-14,2022-01-26
-4tq3,2014-07-16,2014-06-10
-5tqn,2017-11-01,2016-10-24
-7tqe,2022-09-14,2022-01-26
-4tqd,2014-11-12,2014-06-11
-5tq2,2016-12-14,2016-10-21
-3tq9,2011-11-02,2011-09-09
-6tqd,2021-01-13,2019-12-16
-7tqk,2022-09-14,2022-01-26
-5tq6,2017-01-11,2016-10-23
-1tqu,2005-01-25,2004-06-18
-4tq4,2014-07-16,2014-06-10
-4tq6,2014-07-16,2014-06-10
-1tqy,2004-07-27,2004-06-18
-3tq0,2012-05-16,2011-09-08
-3tqq,2011-09-28,2011-09-09
-6tqo,2020-08-05,2019-12-17
-5tqc,2017-02-15,2016-10-23
-8tqv,2024-04-24,2023-08-08
-1tqh,2004-09-28,2004-06-17
-6tqw,2020-04-15,2019-12-17
-4tqk,2015-06-03,2014-06-11
-1tqs,2005-01-25,2004-06-18
-7tqf,2022-09-14,2022-01-26
-5tq7,2017-01-11,2016-10-23
-6tql,2020-11-04,2019-12-16
-7tqm,2023-01-04,2022-01-26
-6tq7,2020-01-01,2019-12-16
-5tq0,2016-12-14,2016-10-21
-7tq1,2023-05-03,2022-01-26
-5tq1,2017-04-19,2016-10-21
-5tq5,2017-01-11,2016-10-23
-4tq9,2015-06-10,2014-06-10
-6tqy,2020-04-15,2019-12-17
-3tqc,2011-09-21,2011-09-09
-6tqv,2020-04-15,2019-12-17
-1tqw,2005-02-01,2004-06-18
-4tqq,2014-07-16,2014-06-11
-1tq6,2004-09-21,2004-06-16
-3tq3,2011-10-12,2011-09-09
-4tqb,2014-08-13,2014-06-10
-8tqa,2024-03-20,2023-08-06
-4tq8,2015-06-24,2014-06-10
-6tq4,2020-01-01,2019-12-16
-1tqx,2004-12-21,2004-06-18
-3tq5,2011-10-12,2011-09-09
-6tqf,2020-04-01,2019-12-16
-7tq9,2022-09-14,2022-01-26
-7tqc,2022-09-14,2022-01-26
-7tq7,2022-02-09,2022-01-26
-6tqe,2020-04-01,2019-12-16
-5tqs,2017-04-19,2016-10-24
-4tqi,2015-06-24,2014-06-11
-6tq9,2020-01-01,2019-12-16
-5tq3,2017-01-11,2016-10-23
-3tqh,2011-09-28,2011-09-09
-1tq7,2004-08-03,2004-06-16
-3tqu,2011-09-21,2011-09-09
-4tqm,2015-06-03,2014-06-11
-4tqn,2015-06-24,2014-06-11
-4tqg,2014-06-25,2014-06-11
-7tqh,2022-09-14,2022-01-26
-4tqr,2015-01-14,2014-06-11
-3tq8,2011-11-02,2011-09-09
-3tqx,2011-09-21,2011-09-09
-7tqx,2022-07-20,2022-01-27
-4tqc,2014-08-13,2014-06-10
-3tqp,2011-09-28,2011-09-09
-4tqu,2015-07-22,2014-06-12
-7tq8,2022-03-02,2022-01-26
-4tqo,2014-09-24,2014-06-11
-3tqj,2011-09-21,2011-09-09
-3tqk,2011-09-21,2011-09-09
-6tqa,2020-05-27,2019-12-16
-1tqf,2004-11-09,2004-06-17
-1tq9,2004-09-14,2004-06-17
-1tq4,2004-09-21,2004-06-16
-8tqs,2024-05-01,2023-08-08
-6tq5,2020-04-08,2019-12-16
-6tqr,2020-11-18,2019-12-17
-1tq2,2004-09-21,2004-06-16
-6tq1,2020-01-15,2019-12-15
-3tqd,2011-10-26,2011-09-09
-3tqo,2011-09-28,2011-09-09
-6tq2,2020-02-19,2019-12-15
-3tqe,2011-09-21,2011-09-09
-4tqe,2015-07-29,2014-06-11
-1tqp,2004-09-28,2004-06-17
-4tqt,2014-08-06,2014-06-12
-7tqj,2022-09-14,2022-01-26
-8tqd,2024-04-24,2023-08-07
-4tqh,2015-06-24,2014-06-11
-6tqb,2020-05-27,2019-12-16
-5tqz,2017-07-19,2016-10-25
-3tqa,2011-11-02,2011-09-09
-7tqi,2022-09-14,2022-01-26
-8tqg,2024-04-24,2023-08-07
-6tqm,2020-06-03,2019-12-16
-6tqp,2020-06-03,2019-12-17
-4tqs,2015-01-14,2014-06-11
-4tqa,2015-06-10,2014-06-10
-6tq6,2020-01-01,2019-12-16
-7tq4,2022-06-22,2022-01-26
-5tqe,2017-02-01,2016-10-24
-1tq5,2005-06-14,2004-06-16
-1tqm,2004-09-28,2004-06-17
-5tqm,2017-04-26,2016-10-24
-4tqf,2014-11-12,2014-06-11
-1tqn,2004-07-27,2004-06-17
-8tqm,2024-03-13,2023-08-07
-1tqv,2005-02-01,2004-06-18
-4drk,2012-05-16,2012-02-17
-3dro,2008-07-29,2008-07-11
-6dre,2018-10-31,2018-06-11
-3dr3,2008-08-05,2008-07-10
-1dre,1997-03-12,1996-11-28
-3dr9,2009-01-27,2008-07-10
-4dro,2012-05-16,2012-02-17
-6dr4,2018-10-17,2018-06-11
-4drh,2013-02-06,2012-02-17
-6drz,2018-08-29,2018-06-13
-4drr,2012-04-11,2012-02-17
-5drp,2016-03-09,2015-09-16
-2dri,1995-01-26,1994-09-23
-3drt,2009-06-23,2008-07-11
-8drm,2022-10-12,2022-07-21
-7drc,2022-06-22,2020-12-27
-1drt,2000-07-06,2000-01-06
-7dr2,2022-02-16,2020-12-25
-2dr6,2006-08-22,2006-06-08
-4dr0,2012-04-11,2012-02-16
-7drp,2021-09-08,2020-12-29
-3dr7,2008-10-14,2008-07-10
-8drr,2022-09-21,2022-07-21
-5drr,2016-03-09,2015-09-16
-5drs,2016-09-28,2015-09-16
-8dr4,2022-08-17,2022-07-20
-8drf,2022-10-12,2022-07-20
-8drp,2023-05-31,2022-07-21
-3dr2,2008-10-07,2008-07-10
-7dr1,2022-02-16,2020-12-25
-4drv,2012-04-11,2012-02-17
-8dr0,2022-08-24,2022-07-20
-8drx,2022-09-21,2022-07-21
-4dr7,2012-11-14,2012-02-16
-2drd,2006-08-22,2006-06-08
-8drj,2022-10-12,2022-07-21
-7drm,2021-09-08,2020-12-29
-8dr2,2022-12-14,2022-07-20
-8drw,2022-09-21,2022-07-21
-1drj,1995-01-26,1994-09-23
-2dra,2006-11-14,2006-06-08
-2dr8,2006-11-14,2006-06-08
-6drd,2019-06-12,2018-06-11
-5dr7,2016-09-28,2015-09-15
-5dr3,2016-09-28,2015-09-15
-3drc,1994-01-31,1992-09-22
-6drs,2019-06-19,2018-06-12
-1dr1,1993-10-31,1992-03-14
-1drm,2000-01-24,2000-01-06
-3drq,2008-10-07,2008-07-11
-2drs,2006-06-27,2006-06-12
-4dre,2012-10-03,2012-02-17
-6dr8,2019-06-19,2018-06-11
-5drg,2016-07-27,2015-09-15
-7drv,2021-08-25,2020-12-29
-5dr0,2016-09-28,2015-09-15
-2drq,2006-06-27,2006-06-12
-1drb,1994-01-31,1991-11-06
-6drj,2018-09-19,2018-06-12
-5dr6,2016-07-20,2015-09-15
-1dr6,1993-10-31,1992-03-14
-2drj,2007-04-24,2006-06-09
-6drx,2018-08-29,2018-06-13
-5drb,2016-09-07,2015-09-15
-4drp,2012-05-16,2012-02-17
-8dr7,2022-08-17,2022-07-20
-5dr1,2016-09-28,2015-09-15
-4dri,2013-02-06,2012-02-17
-4drm,2012-05-16,2012-02-17
-1drw,1997-01-27,1996-06-28
-4drq,2012-04-18,2012-02-17
-1dr4,1993-10-31,1992-03-14
-4dr2,2012-11-14,2012-02-16
-5drc,2016-09-28,2015-09-15
-2dre,2006-12-26,2006-06-08
-2drw,2006-07-04,2006-06-15
-1dr9,2000-01-10,2000-01-06
-6dr0,2018-08-01,2018-06-11
-4dr6,2012-11-14,2012-02-16
-4dr1,2012-11-14,2012-02-16
-3dra,2008-09-30,2008-07-10
-2drr,2006-06-27,2006-06-12
-8dr1,2022-08-17,2022-07-20
-6drt,2018-09-26,2018-06-13
-5drk,2016-10-12,2015-09-15
-3drp,2008-10-14,2008-07-11
-1dr2,1993-10-31,1992-03-14
-7drj,2021-12-08,2020-12-28
-7drn,2021-09-08,2020-12-29
-2drp,1994-08-31,1994-06-06
-7drk,2021-12-08,2020-12-28
-2dr0,2006-08-29,2006-06-02
-5drf,2016-07-27,2015-09-15
-5drm,2016-05-04,2015-09-16
-7drb,2022-06-22,2020-12-27
-5dr4,2016-09-28,2015-09-15
-1dru,1997-01-27,1996-06-28
-4drj,2013-02-06,2012-02-17
-8drl,2022-10-12,2022-07-21
-4dr4,2012-11-14,2012-02-16
-6dr6,2018-10-17,2018-06-11
-7drt,2021-07-14,2020-12-29
-7dr0,2022-02-16,2020-12-25
-3dr0,2009-07-14,2008-07-10
-4drx,2012-07-11,2012-02-17
-1dr7,1993-10-31,1992-03-14
-2dr2,2006-07-11,2006-06-05
-3drh,2009-03-31,2008-07-11
-5drh,2016-09-21,2015-09-15
-4dr3,2012-11-14,2012-02-16
-3drb,2009-03-17,2008-07-11
-3drw,2008-12-23,2008-07-11
-2dru,2006-07-04,2006-06-15
-3drg,2009-03-31,2008-07-11
-5dry,2016-06-15,2015-09-16
-5drq,2016-03-09,2015-09-16
-8dr6,2022-08-24,2022-07-20
-6drc,2018-08-01,2018-06-11
-8drz,2022-09-28,2022-07-21
-6dra,2018-08-01,2018-06-11
-7drx,2022-03-23,2020-12-30
-3dr8,2008-08-12,2008-07-10
-4drz,2012-02-29,2012-02-17
-8dr5,2022-08-17,2022-07-20
-5drv,2015-10-14,2015-09-16
-1dr5,1993-10-31,1992-03-14
-4dr8,2013-03-06,2012-02-17
-1dry,2000-07-06,2000-01-06
-3dr1,2009-06-16,2008-07-10
-1drk,1995-01-26,1994-09-23
-3drj,2009-03-31,2008-07-11
-7drz,2021-07-14,2020-12-30
-3drr,2008-10-14,2008-07-11
-5drj,2016-05-04,2015-09-15
-5dri,2016-09-28,2015-09-15
-2drm,2007-05-29,2006-06-09
-6drg,2018-12-26,2018-06-11
-5drn,2016-01-20,2015-09-16
-8drd,2022-10-12,2022-07-20
-3drs,2008-10-14,2008-07-11
-3dr4,2008-10-14,2008-07-10
-5dr8,2016-09-28,2015-09-15
-4dr9,2013-01-16,2012-02-17
-1drv,1997-01-27,1996-06-28
-1drf,1992-01-15,1990-08-09
-6dr2,2018-07-18,2018-06-11
-1dra,1994-01-31,1991-11-06
-3dri,2009-03-31,2008-07-11
-5drd,2016-07-20,2015-09-15
-6dry,2018-08-29,2018-06-13
-5dro,2016-03-09,2015-09-16
-5drz,2016-10-19,2015-09-16
-6drh,2018-10-31,2018-06-11
-5dr9,2016-07-20,2015-09-15
-4drn,2012-05-16,2012-02-17
-2dro,2006-06-27,2006-06-12
-2drc,1994-01-31,1992-06-10
-8dr9,2023-08-30,2022-07-20
-8drb,2022-12-14,2022-07-20
-3drk,2009-03-31,2008-07-11
-5drt,2016-06-15,2015-09-16
-2dr3,2006-12-06,2006-06-06
-7dry,2021-07-14,2020-12-30
-6drw,2018-07-18,2018-06-13
-1dr3,1993-10-31,1992-03-14
-7drq,2021-03-31,2020-12-29
-4dru,2012-04-18,2012-02-17
-8dr3,2022-08-17,2022-07-20
-5dr2,2016-07-20,2015-09-15
-7dro,2021-09-08,2020-12-29
-2drz,2007-02-06,2006-06-16
-4dr5,2012-11-14,2012-02-16
-6dru,2018-08-22,2018-06-13
-3drf,2009-03-31,2008-07-11
-4drt,2012-04-18,2012-02-17
-2dr1,2006-12-05,2006-06-05
-1drh,1995-02-07,1994-11-30
-8u2e,2024-01-31,2023-09-05
-3u2p,2011-11-09,2011-10-04
-6u2w,2019-09-25,2019-08-20
-5u2o,2018-05-30,2016-11-30
-1u2d,2005-01-25,2004-07-19
-5u2f,2017-02-08,2016-11-30
-7u2h,2022-07-13,2022-02-24
-7u2a,2022-09-14,2022-02-23
-4u2w,2015-01-14,2014-07-18
-8u2r,2023-09-13,2023-09-06
-5u2t,2017-05-24,2016-11-30
-4u25,2014-07-30,2014-07-16
-1u27,2005-02-01,2004-07-16
-3u2k,2012-01-11,2011-10-03
-7u2j,2022-07-13,2022-02-24
-3u27,2012-02-08,2011-10-01
-3u2s,2011-11-30,2011-10-04
-5u29,2017-12-06,2016-11-30
-1u2g,2005-01-25,2004-07-19
-6u2o,2020-08-26,2019-08-20
-6u2z,2019-09-04,2019-08-21
-5u2c,2017-02-08,2016-11-30
-7u21,2022-06-01,2022-02-22
-3u2t,2011-11-02,2011-10-04
-7u2f,2023-03-01,2022-02-23
-7u2v,2023-05-10,2022-02-24
-4u26,2014-07-30,2014-07-16
-1u29,2005-02-01,2004-07-16
-4u23,2014-08-20,2014-07-16
-7u2i,2022-07-13,2022-02-24
-5u28,2017-02-08,2016-11-30
-4u2y,2015-08-12,2014-07-18
-5u2h,2017-01-04,2016-11-30
-3u2c,2011-11-02,2011-10-03
-7u2l,2022-05-04,2022-02-24
-6u2g,2019-08-28,2019-08-19
-7u2d,2022-05-04,2022-02-23
-7u2t,2022-04-20,2022-02-24
-8u2u,2023-09-13,2023-09-06
-8u28,2023-11-15,2023-09-05
-4u2z,2015-07-22,2014-07-18
-4u2p,2014-08-20,2014-07-17
-5u24,2017-01-11,2016-11-29
-6u25,2019-11-06,2019-08-19
-7u2q,2022-04-20,2022-02-24
-5u2d,2017-04-05,2016-11-30
-5u21,2017-01-11,2016-11-29
-6u2n,2019-11-06,2019-08-20
-5u26,2016-12-21,2016-11-29
-6u2f,2020-02-05,2019-08-19
-7u2b,2022-09-14,2022-02-23
-4u27,2014-07-30,2014-07-16
-8u2d,2024-01-31,2023-09-05
-8u27,2023-09-13,2023-09-05
-6u23,2019-09-25,2019-08-19
-8u2s,2023-09-13,2023-09-06
-3u2q,2012-05-02,2011-10-04
-6u2y,2019-09-04,2019-08-20
-1u2t,2005-06-14,2004-07-20
-4u20,2014-07-30,2014-07-16
-4u21,2014-08-20,2014-07-16
-8u2t,2023-09-13,2023-09-06
-8u2q,2023-09-13,2023-09-06
-7u2u,2022-06-08,2022-02-24
-6u2k,2019-09-25,2019-08-20
-4u2a,2014-12-31,2014-07-16
-8u2w,2023-09-13,2023-09-06
-4u2s,2014-12-10,2014-07-18
-4u2q,2014-08-20,2014-07-17
-8u2o,2023-09-27,2023-09-06
-4u22,2014-08-20,2014-07-16
-3u2o,2011-11-16,2011-10-04
-1u2o,2004-08-03,2004-07-19
-5u2i,2017-01-25,2016-11-30
-7u2n,2023-03-08,2022-02-24
-5u2k,2016-12-14,2016-11-30
-7u2r,2022-04-20,2022-02-24
-5u20,2017-01-11,2016-11-29
-6u2x,2019-11-06,2019-08-20
-7u2z,2022-04-27,2022-02-25
-5u2b,2017-04-26,2016-11-30
-1u2w,2005-07-12,2004-07-20
-7u2o,2023-03-01,2022-02-24
-5u2j,2017-04-12,2016-11-30
-8u2z,2024-05-08,2023-09-06
-5u2n,2017-06-28,2016-11-30
-5u2e,2017-02-08,2016-11-30
-1u2y,2004-09-07,2004-07-20
-3u2d,2012-01-11,2011-10-03
-5u2w,2017-01-18,2016-12-01
-6u2h,2019-08-28,2019-08-19
-3u2l,2012-06-06,2011-10-04
-1u2r,2004-09-14,2004-07-20
-4u24,2014-07-30,2014-07-16
-4u2l,2014-12-10,2014-07-17
-3u2x,2011-11-02,2011-10-04
-5u2m,2017-06-28,2016-11-30
-3u2w,2011-11-02,2011-10-04
-6u2l,2019-09-25,2019-08-20
-7u24,2022-08-31,2022-02-23
-7u2p,2022-05-04,2022-02-24
-5u27,2016-12-21,2016-11-29
-6u2a,2020-05-27,2019-08-19
-6u22,2020-07-01,2019-08-19
-1u22,2004-09-07,2004-07-16
-7u2k,2022-12-07,2022-02-24
-6u2p,2019-11-06,2019-08-20
-3u21,2011-11-02,2011-09-30
-1u2n,2005-04-26,2004-07-19
-5u25,2016-12-21,2016-11-29
-3u2z,2012-09-12,2011-10-04
-7u2e,2022-05-04,2022-02-23
-1u2s,2005-06-14,2004-07-20
-4u2k,2015-07-29,2014-07-17
-6u2m,2020-09-30,2019-08-20
-7u2s,2022-04-20,2022-02-24
-3u2m,2012-06-06,2011-10-04
-3u2u,2011-11-02,2011-10-04
-7u2m,2023-03-08,2022-02-24
-6u2j,2019-09-25,2019-08-20
-1u28,2005-01-18,2004-07-16
-4u2t,2014-12-10,2014-07-18
-7u29,2022-03-09,2022-02-23
-3u2e,2011-10-12,2011-10-03
-8u29,2023-12-06,2023-09-05
-5u23,2017-01-11,2016-11-29
-5u2r,2017-05-24,2016-11-30
-6u24,2020-07-01,2019-08-19
-1u2z,2004-09-07,2004-07-20
-8u2p,2023-09-13,2023-09-06
-3u2v,2011-12-07,2011-10-04
-7u25,2022-06-01,2022-02-23
-3u24,2012-05-09,2011-09-30
-3u25,2011-12-28,2011-09-30
-6u26,2019-11-06,2019-08-19
-7u22,2022-10-19,2022-02-22
-1u2v,2004-11-09,2004-07-20
-1u21,2005-06-28,2004-07-16
-7u28,2022-03-09,2022-02-23
-7u2x,2022-08-31,2022-02-25
-8u2m,2024-01-10,2023-09-06
-5u2s,2017-05-24,2016-11-30
-5u2v,2017-02-08,2016-12-01
-5g2n,2016-04-20,2016-04-11
-4g27,2012-09-12,2012-07-11
-4g2u,2013-03-27,2012-07-13
-6g29,2019-06-26,2018-03-22
-3g2t,2009-12-15,2009-02-01
-8g2x,2023-02-15,2023-02-06
-3g2z,2009-03-24,2009-02-01
-5g27,2016-11-23,2016-04-07
-3g20,2009-07-28,2009-01-30
-3g2x,2009-08-11,2009-02-01
-2g27,2006-06-13,2006-02-15
-1g28,2001-03-21,2000-10-17
-6g20,2018-11-28,2018-03-22
-2g25,2006-04-25,2006-02-15
-6g2a,2018-11-28,2018-03-22
-4g20,2012-09-26,2012-07-11
-8g2g,2023-04-26,2023-02-03
-4g2t,2012-07-25,2012-07-12
-2g21,2006-06-13,2006-02-15
-2g2z,2006-06-27,2006-02-17
-2g2c,2006-03-28,2006-02-15
-8g2j,2023-03-01,2023-02-04
-8g2l,2023-02-15,2023-02-05
-6g2p,2018-05-16,2018-03-23
-4g2w,2013-06-26,2012-07-13
-5g22,2017-02-15,2016-04-06
-6g22,2018-07-11,2018-03-22
-8g2f,2023-05-10,2023-02-03
-6g2c,2019-06-26,2018-03-22
-5g2a,2016-10-19,2016-04-07
-8g2e,2023-05-17,2023-02-03
-3g2l,2010-02-16,2009-01-31
-4g2d,2012-10-24,2012-07-11
-1g25,2000-11-01,2000-10-17
-5g2p,2016-07-27,2016-04-12
-6g2y,2019-04-10,2018-03-23
-4g26,2012-09-26,2012-07-11
-8g27,2023-03-01,2023-02-03
-3g2y,2009-03-24,2009-02-01
-6g2z,2019-04-10,2018-03-23
-3g2p,2009-05-05,2009-01-31
-6g2f,2019-06-26,2018-03-23
-2g2i,2006-05-23,2006-02-16
-8g24,2023-04-26,2023-02-03
-5g2g,2016-07-13,2016-04-08
-1g2f,2001-09-07,2000-10-18
-3g2i,2010-02-16,2009-01-31
-6g2m,2018-07-11,2018-03-23
-3g24,2009-06-23,2009-01-30
-5g20,2017-02-15,2016-04-06
-1g27,2001-10-17,2000-10-17
-1g2k,2001-06-01,2000-10-20
-4g2r,2014-02-19,2012-07-12
-4g25,2012-09-26,2012-07-11
-6g2o,2019-06-26,2018-03-23
-2g2n,2006-12-12,2006-02-16
-1g2v,2000-12-27,2000-10-21
-1g23,2000-12-27,2000-10-16
-4g2o,2013-07-17,2012-07-12
-3g2c,2010-03-09,2009-01-31
-6g2l,2018-07-11,2018-03-23
-3g2f,2009-02-17,2009-01-31
-4g2f,2012-10-24,2012-07-12
-1g2w,2000-11-15,2000-10-21
-4g2j,2013-05-29,2012-07-12
-8g2w,2023-06-21,2023-02-06
-3g25,2009-02-17,2009-01-30
-4g28,2012-09-12,2012-07-11
-4g2l,2013-05-29,2012-07-12
-3g2o,2009-05-05,2009-01-31
-5g2b,2017-11-29,2016-04-07
-4g2h,2012-09-26,2012-07-12
-3g2k,2010-02-16,2009-01-31
-8g2m,2024-02-14,2023-02-05
-1g29,2000-12-06,2000-10-18
-5g2d,2016-10-19,2016-04-07
-6g2u,2019-04-10,2018-03-23
-8g2k,2024-05-15,2023-02-05
-5g2m,2017-05-17,2016-04-09
-6g25,2019-06-26,2018-03-22
-3g2n,2010-02-16,2009-01-31
-1g21,2001-01-31,2000-10-16
-5g2v,2017-05-24,2016-04-14
-6g2r,2019-03-20,2018-03-23
-5g2t,2017-05-24,2016-04-13
-4g2c,2012-10-24,2012-07-11
-3g2v,2009-12-15,2009-02-01
-3g22,2009-06-23,2009-01-30
-2g2s,2006-04-18,2006-02-16
-7g21,2023-06-14,2023-05-04
-8g29,2023-12-27,2023-02-03
-6g2n,2018-07-11,2018-03-23
-2g2h,2006-05-23,2006-02-16
-1g2m,2001-10-20,2000-10-20
-5g2s,2017-02-15,2016-04-13
-8g2o,2023-10-18,2023-02-06
-1g2d,2001-09-07,2000-10-18
-7g20,2023-06-14,2023-04-27
-8g2c,2023-12-27,2023-02-03
-4g2s,2013-05-15,2012-07-12
-6g2x,2019-04-10,2018-03-23
-8g2i,2024-02-21,2023-02-03
-3g2w,2009-12-15,2009-02-01
-4g24,2012-09-26,2012-07-11
-2g2f,2006-05-23,2006-02-15
-1g20,2001-01-31,2000-10-16
-6g27,2019-06-26,2018-03-22
-5g21,2017-02-15,2016-04-06
-3g27,2009-03-24,2009-01-30
-4g2g,2012-09-05,2012-07-12
-8g2d,2023-12-27,2023-02-03
-8g20,2023-12-13,2023-02-03
-1g2a,2001-10-17,2000-10-18
-6g2k,2018-10-31,2018-03-23
-8g2t,2023-08-09,2023-02-06
-6g24,2019-06-26,2018-03-22
-2g2p,2006-12-12,2006-02-16
-5g2i,2017-04-19,2016-04-08
-1g2o,2001-08-01,2000-10-20
-5g2r,2017-02-15,2016-04-13
-3g2q,2009-05-05,2009-01-31
-3g2d,2010-03-09,2009-01-31
-8g2s,2023-02-15,2023-02-06
-4g21,2012-09-26,2012-07-11
-6g2v,2019-04-10,2018-03-23
-2g20,2006-06-20,2006-02-15
-6g2b,2019-06-26,2018-03-22
-3g2u,2009-12-15,2009-02-01
-4g2z,2012-08-01,2012-07-13
-8g26,2023-04-26,2023-02-03
-5g28,2016-10-19,2016-04-07
-5g2u,2017-05-24,2016-04-14
-3g2j,2010-02-16,2009-01-31
-6g2s,2019-03-20,2018-03-23
-1g2l,2001-10-20,2000-10-20
-2g28,2006-04-25,2006-02-15
-8g2a,2023-12-27,2023-02-03
-4g2y,2013-06-26,2012-07-13
-3g2h,2010-02-16,2009-01-31
-4g23,2012-09-26,2012-07-11
-2g2l,2006-08-29,2006-02-16
-5g2c,2016-10-19,2016-04-07
-2g24,2006-06-13,2006-02-15
-2g2r,2006-12-05,2006-02-16
-5g2o,2016-05-25,2016-04-11
-6g2q,2018-07-04,2018-03-23
-8g2b,2023-12-27,2023-02-03
-6g2j,2018-06-06,2018-03-23
-4g2i,2012-09-26,2012-07-12
-6g28,2018-11-28,2018-03-22
-8g2r,2023-08-09,2023-02-06
-2g26,2006-06-13,2006-02-15
-2g22,2006-06-13,2006-02-15
-8g2y,2023-05-10,2023-02-06
-6g2e,2019-06-26,2018-03-23
-5g2h,2017-04-19,2016-04-08
-5g2q,2016-07-27,2016-04-12
-6g21,2018-05-23,2018-03-22
-6g2w,2019-04-10,2018-03-23
-8g23,2024-05-22,2023-02-03
-2l4i,2011-03-09,2010-10-06
-6l4y,2020-10-07,2019-10-21
-2l47,2011-10-12,2010-10-01
-3l45,2010-04-28,2009-12-18
-1l4x,2002-11-13,2002-03-06
-5l43,2016-10-26,2016-05-24
-2l46,2011-12-14,2010-10-01
-7l4t,2021-08-11,2020-12-21
-2l43,2011-08-31,2010-10-01
-4l4b,2013-07-31,2013-06-07
-3l4x,2010-02-09,2009-12-21
-3l4j,2010-05-26,2009-12-20
-5l4l,2016-10-05,2016-05-25
-6l4m,2019-12-04,2019-10-18
-4l4x,2013-06-19,2013-06-10
-3l4w,2010-02-09,2009-12-21
-6l4n,2021-04-21,2019-10-18
-7l49,2021-06-02,2020-12-18
-4l44,2013-07-24,2013-06-07
-2l4d,2011-01-26,2010-10-04
-4l45,2013-07-24,2013-06-07
-3l4n,2010-04-07,2009-12-21
-3l4t,2010-02-09,2009-12-21
-4l4c,2013-07-31,2013-06-07
-4l4p,2014-05-07,2013-06-08
-7l4b,2021-12-22,2020-12-18
-5l4s,2016-08-31,2016-05-26
-7l48,2021-06-02,2020-12-18
-7l4c,2021-08-04,2020-12-18
-5l4v,2017-06-21,2016-05-26
-3l4g,2010-03-09,2009-12-20
-4l48,2014-03-26,2013-06-07
-3l4v,2010-02-09,2009-12-21
-6l42,2020-05-13,2019-10-15
-6l46,2020-02-12,2019-10-16
-3l4p,2010-02-16,2009-12-21
-7l4w,2021-08-11,2020-12-21
-1l4l,2002-09-07,2002-03-06
-6l48,2020-04-29,2019-10-16
-6l47,2020-04-29,2019-10-16
-3l4s,2010-08-18,2009-12-21
-7l4f,2021-08-04,2020-12-19
-7l4g,2020-12-30,2020-12-19
-7l4u,2021-08-11,2020-12-21
-6l4c,2019-12-04,2019-10-16
-3l4m,2010-03-23,2009-12-21
-4l49,2013-07-31,2013-06-07
-1l4y,2002-06-12,2002-03-06
-6l4p,2020-02-19,2019-10-19
-1l4k,2002-09-07,2002-03-06
-2l45,2011-12-14,2010-10-01
-7l4m,2021-08-04,2020-12-19
-7l4d,2021-12-29,2020-12-18
-3l47,2011-01-12,2009-12-18
-5l4g,2016-09-07,2016-05-25
-5l4q,2016-06-08,2016-05-26
-4l4z,2013-11-06,2013-06-10
-4l4l,2014-06-11,2013-06-08
-1l4h,2002-09-07,2002-03-06
-4l46,2013-07-24,2013-06-07
-5l4h,2016-12-21,2016-05-25
-4l4e,2013-07-31,2013-06-07
-4l4v,2013-07-17,2013-06-09
-7l4k,2021-08-04,2020-12-19
-1l4f,2002-09-07,2002-03-06
-7l4l,2021-09-22,2020-12-19
-4l4d,2013-07-31,2013-06-07
-4l4f,2013-07-31,2013-06-07
-6l4z,2020-07-15,2019-10-21
-5l4y,2017-06-21,2016-05-26
-1l4g,2002-09-07,2002-03-06
-6l4w,2020-10-07,2019-10-21
-3l4u,2010-02-09,2009-12-21
-5l4u,2017-06-21,2016-05-26
-4l42,2013-07-24,2013-06-07
-4l4g,2013-07-31,2013-06-07
-1l4z,2002-12-11,2002-03-06
-6l4t,2020-05-20,2019-10-21
-5l47,2016-12-21,2016-05-25
-2l41,2010-11-17,2010-09-28
-1l4u,2002-06-12,2002-03-05
-5l4t,2017-06-21,2016-05-26
-5l44,2016-10-26,2016-05-24
-6l4q,2021-05-19,2019-10-19
-2l4z,2011-10-26,2010-10-22
-7l4n,2021-08-04,2020-12-19
-5l4x,2017-06-21,2016-05-26
-3l4d,2009-12-29,2009-12-19
-3l4i,2010-01-19,2009-12-20
-1l4e,2002-09-07,2002-03-06
-3l41,2010-02-09,2009-12-18
-4l4m,2014-06-11,2013-06-08
-1l4n,2002-09-07,2002-03-06
-6l4k,2020-10-21,2019-10-17
-5l42,2017-05-03,2016-05-24
-7l4z,2021-06-30,2020-12-21
-1l4m,2002-09-07,2002-03-06
-2l4h,2011-03-09,2010-10-06
-3l4k,2010-05-26,2009-12-20
-2l4l,2010-12-08,2010-10-08
-6l40,2020-07-08,2019-10-15
-4l4s,2014-04-30,2013-06-09
-5l4i,2016-10-05,2016-05-25
-4l4t,2013-07-17,2013-06-09
-5l4e,2016-12-21,2016-05-25
-5l4f,2016-10-05,2016-05-25
-2l4t,2011-04-06,2010-10-13
-5l4w,2017-06-21,2016-05-26
-5l4m,2016-10-05,2016-05-25
-7l4j,2021-08-04,2020-12-19
-5l41,2016-12-21,2016-05-24
-3l4z,2010-02-09,2009-12-21
-4l4j,2013-08-28,2013-06-07
-5l4n,2017-03-22,2016-05-26
-4l43,2013-07-24,2013-06-07
-3l48,2010-03-02,2009-12-18
-5l4j,2016-10-12,2016-05-25
-7l4i,2021-08-04,2020-12-19
-4l47,2014-08-06,2013-06-07
-6l4u,2020-05-20,2019-10-21
-4l4a,2013-07-31,2013-06-07
-7l47,2021-12-29,2020-12-18
-4l40,2013-11-27,2013-06-07
-5l46,2016-08-17,2016-05-25
-3l4l,2011-01-12,2009-12-20
-7l4a,2020-12-30,2020-12-18
-2l44,2011-10-12,2010-10-01
-3l4y,2010-02-09,2009-12-21
-7l4h,2021-08-04,2020-12-19
-4l41,2013-10-02,2013-06-07
-3l4o,2010-03-23,2009-12-21
-6vuj,2020-02-26,2020-02-15
-7vux,2021-11-17,2021-11-04
-7vug,2021-12-29,2021-11-02
-6vuc,2020-02-26,2020-02-14
-6vue,2020-11-04,2020-02-15
-5vug,2017-06-14,2017-05-19
-5vuu,2017-08-16,2017-05-19
-5vu8,2017-12-06,2017-05-18
-3vuy,2013-02-13,2012-07-09
-5vu4,2017-06-28,2017-05-18
-7vuo,2022-11-09,2021-11-03
-8vue,2024-05-22,2024-01-29
-2vuz,2008-08-05,2008-06-02
-5vui,2017-08-16,2017-05-19
-7vu3,2022-11-09,2021-11-01
-7vut,2022-07-27,2021-11-04
-5vum,2017-08-16,2017-05-19
-5vua,2017-12-13,2017-05-18
-6vu6,2020-08-26,2020-02-14
-6vuz,2020-06-03,2020-02-16
-5vul,2017-08-16,2017-05-19
-6vur,2020-06-03,2020-02-16
-6vu4,2020-06-17,2020-02-14
-6vum,2020-05-13,2020-02-16
-2vui,2008-11-11,2008-05-26
-7vu1,2022-11-09,2021-11-01
-5vur,2017-08-16,2017-05-19
-7vu8,2022-06-01,2021-11-01
-2vuo,2008-09-16,2008-05-27
-3vuw,2013-02-13,2012-07-09
-7vuj,2021-12-29,2021-11-02
-3vuc,2013-05-15,2012-06-26
-2vuu,2008-07-29,2008-05-30
-3vun,2012-08-01,2012-07-02
-7vuw,2022-11-16,2021-11-04
-7vuc,2022-07-27,2021-11-02
-5vuc,2017-12-13,2017-05-18
-6vuf,2020-02-26,2020-02-15
-2vuk,2008-07-22,2008-05-26
-5vu7,2017-12-06,2017-05-18
-5vuy,2017-08-16,2017-05-19
-7vur,2022-07-27,2021-11-04
-7vuu,2022-07-27,2021-11-04
-5vud,2018-10-03,2017-05-19
-3vuv,2012-08-08,2012-07-09
-2vus,2008-07-29,2008-05-30
-3vux,2013-02-13,2012-07-09
-7vuz,2021-12-01,2021-11-04
-7vuk,2022-04-06,2021-11-02
-3vus,2012-11-14,2012-07-05
-7vu0,2022-11-09,2021-11-01
-2vug,2008-06-03,2008-05-26
-5vun,2017-08-16,2017-05-19
-2vuv,2008-08-05,2008-05-30
-7vus,2022-07-27,2021-11-04
-5vuz,2017-08-23,2017-05-19
-2vuc,2009-07-21,2008-05-22
-2vud,2009-07-21,2008-05-22
-7vua,2022-06-01,2021-11-01
-2vu2,2008-10-28,2008-05-19
-3vuf,2012-09-05,2012-06-28
-6vut,2020-06-03,2020-02-16
-3vu2,2013-05-08,2012-06-14
-5vu0,2018-05-23,2017-05-18
-3vuz,2013-03-27,2012-07-10
-2vut,2008-07-29,2008-05-30
-7vum,2022-03-09,2021-11-03
-7vui,2021-12-29,2021-11-02
-2vuf,2008-06-24,2008-05-24
-5vut,2017-08-16,2017-05-19
-5vuo,2017-08-16,2017-05-19
-5vup,2017-08-16,2017-05-19
-7vu9,2022-10-12,2021-11-01
-5vub,2017-12-13,2017-05-18
-7vu2,2022-11-09,2021-11-01
-7vun,2022-09-14,2021-11-03
-2vur,2009-02-10,2008-05-29
-5vue,2018-10-03,2017-05-19
-2vu1,2008-10-28,2008-05-19
-5vuq,2017-08-16,2017-05-19
-6vu3,2020-09-02,2020-02-14
-7vuf,2022-04-06,2021-11-02
-7vuh,2021-12-29,2021-11-02
-2vu0,2008-10-28,2008-05-19
-6vub,2020-02-26,2020-02-14
-6vuw,2020-06-03,2020-02-16
-3vu1,2013-01-23,2012-06-13
-6vuu,2020-06-03,2020-02-16
-6vuy,2020-06-03,2020-02-16
-3vu8,2013-06-26,2012-06-22
-3vu3,2013-11-20,2012-06-15
-5vuw,2017-08-23,2017-05-19
-7vub,2023-03-08,2021-11-02
-2vu3,2008-08-05,2008-05-20
-6vua,2020-06-03,2020-02-14
-7vu6,2022-04-06,2021-11-01
-2vu4,2009-07-21,2008-05-21
-2vun,2008-12-09,2008-05-27
-5vuk,2017-08-16,2017-05-19
-6vus,2020-06-03,2020-02-16
-2vux,2008-07-15,2008-05-31
-2vuw,2008-09-16,2008-05-30
-2vu9,2008-08-26,2008-05-22
-2vue,2008-06-17,2008-05-24
-6vux,2020-06-03,2020-02-16
-5vux,2017-08-23,2017-05-19
-7vue,2022-03-16,2021-11-02
-6vuq,2021-01-13,2020-02-16
-5vuv,2017-08-23,2017-05-19
-5vuj,2017-08-16,2017-05-19
-5vuf,2018-10-03,2017-05-19
-6vu9,2020-03-04,2020-02-14
-7vuy,2021-12-01,2021-11-04
-7vud,2022-11-02,2021-11-02
-2vum,2008-06-17,2008-05-27
-5vus,2017-08-16,2017-05-19
-4a1z,2012-10-31,2011-09-20
-6a19,2019-06-19,2018-06-06
-3a1e,2009-07-21,2009-03-31
-6a1c,2019-03-06,2018-06-07
-3a12,2010-04-07,2009-03-25
-3a15,2009-09-08,2009-03-26
-5a10,2015-08-26,2015-04-27
-8a1o,2023-06-14,2022-06-01
-6a12,2018-06-20,2018-06-06
-4a1x,2012-09-19,2011-09-20
-5a1l,2015-06-17,2015-05-01
-3a11,2010-03-31,2009-03-25
-5a1p,2015-06-24,2015-05-04
-7a1x,2021-10-13,2020-08-14
-8a19,2022-12-07,2022-06-01
-8a11,2023-06-14,2022-05-30
-3a1a,2009-11-10,2009-03-28
-8a1l,2023-06-14,2022-06-01
-8a16,2023-03-15,2022-05-31
-1a1n,1998-04-08,1997-12-11
-2a1i,2005-08-02,2005-06-20
-5a14,2015-07-22,2015-04-27
-7a1q,2021-08-25,2020-08-13
-5a1s,2016-02-17,2015-05-05
-8a1v,2023-06-14,2022-06-02
-3a1f,2010-04-07,2009-04-01
-1a1m,1998-04-08,1997-12-11
-4a1o,2011-09-28,2011-09-17
-6a1g,2018-10-03,2018-06-07
-8a15,2023-06-14,2022-05-31
-2a1j,2005-08-02,2005-06-20
-6a1e,2019-06-12,2018-06-07
-2a11,2005-07-05,2005-06-17
-4a1w,2011-12-28,2011-09-20
-6a1i,2019-06-12,2018-06-07
-6a1d,2019-06-12,2018-06-07
-6a15,2019-06-12,2018-06-06
-6a17,2019-06-12,2018-06-06
-6a13,2019-06-19,2018-06-06
-8a1m,2023-06-14,2022-06-01
-7a1r,2021-06-02,2020-08-13
-3a1u,2009-09-22,2009-04-22
-6a1a,2019-06-19,2018-06-07
-4a1i,2012-09-26,2011-09-15
-2a1o,2005-07-05,2005-06-20
-8a1n,2023-06-14,2022-06-01
-8a1p,2023-02-01,2022-06-01
-1a1a,1998-04-08,1997-12-10
-3a17,2009-09-08,2009-03-26
-7a16,2020-09-23,2020-08-11
-5a1j,2015-05-13,2015-04-30
-6a1m,2019-06-19,2018-06-07
-3a14,2010-04-07,2009-03-25
-8a1y,2023-06-14,2022-06-02
-7a1k,2021-08-25,2020-08-13
-6a1f,2018-10-03,2018-06-07
-1a1r,1998-06-17,1997-12-15
-6a1z,2018-11-21,2018-06-08
-7a13,2020-09-23,2020-08-11
-8a1f,2023-03-15,2022-06-01
-7a1p,2021-08-25,2020-08-13
-6a1h,2019-06-19,2018-06-07
-1a1h,1998-06-10,1997-12-10
-7a1e,2021-04-21,2020-08-12
-6a1l,2019-06-19,2018-06-07
-7a17,2020-12-30,2020-08-12
-1a16,1999-04-06,1997-12-22
-2a19,2005-09-27,2005-06-19
-7a18,2021-10-06,2020-08-12
-6a1b,2019-06-19,2018-06-07
-7a15,2020-09-23,2020-08-11
-3a1i,2009-10-27,2009-04-03
-7a1w,2021-10-13,2020-08-14
-3a16,2009-09-08,2009-03-26
-5a1m,2015-09-16,2015-05-01
-5a1t,2016-03-02,2015-05-05
-7a1g,2020-10-14,2020-08-13
-2a1h,2005-09-06,2005-06-20
-3a1b,2009-11-10,2009-03-28
-2a15,2005-10-11,2005-06-17
-1a1e,1998-04-08,1997-12-10
-6a16,2019-06-12,2018-06-06
-7a1z,2020-12-09,2020-08-14
-4a16,2012-03-28,2011-09-14
-7a1u,2020-12-02,2020-08-14
-8a1s,2022-07-20,2022-06-02
-4a14,2012-01-25,2011-09-14
-3a1d,2009-07-21,2009-03-31
-6a1r,2019-06-19,2018-06-08
-1a14,1998-05-13,1997-12-21
-3a1l,2009-05-12,2009-04-09
-3a1s,2009-09-22,2009-04-22
-6a1w,2019-06-19,2018-06-08
-3a1m,2010-04-21,2009-04-11
-1a1l,1998-06-17,1997-12-10
-8a18,2023-06-14,2022-06-01
-3a1n,2010-03-31,2009-04-18
-8a1d,2022-07-20,2022-06-01
-8a1z,2022-11-23,2022-06-02
-7a1o,2021-08-25,2020-08-13
-3a1c,2009-07-21,2009-03-31
-4a15,2012-02-01,2011-09-14
-5a1f,2015-05-06,2015-04-29
-1a1i,1998-06-17,1997-12-10
-7a1n,2021-08-25,2020-08-13
-8a1a,2022-12-07,2022-06-01
-8a12,2023-06-21,2022-05-31
-1a1v,1999-01-13,1997-12-17
-4a1n,2012-02-29,2011-09-16
-2a1k,2006-05-09,2005-06-20
-8a1r,2023-06-14,2022-06-01
-2a1n,2005-07-05,2005-06-20
-1a1k,1998-06-10,1997-12-10
-1a1o,1998-04-08,1997-12-11
-1a1t,1998-06-17,1997-12-15
-7a1a,2020-10-21,2020-08-12
-4a1r,2011-10-05,2011-09-19
-8a1u,2023-09-20,2022-06-02
-2a1t,2005-07-05,2005-06-21
-2a1u,2005-07-05,2005-06-21
-3a1z,2010-04-28,2009-04-27
-4a1t,2012-09-19,2011-09-19
-3a18,2009-09-08,2009-03-26
-6a11,2019-06-19,2018-06-06
-7a1i,2021-07-28,2020-08-13
-1a1g,1998-06-10,1997-12-10
-6a1t,2018-12-26,2018-06-08
-7a1j,2021-08-25,2020-08-13
-1a1c,1998-04-08,1997-12-10
-5a1i,2016-03-09,2015-04-30
-8a1h,2023-02-08,2022-06-01
-2a1d,2005-09-27,2005-06-20
-8a1t,2023-06-14,2022-06-02
-8a1b,2022-07-13,2022-06-01
-7a10,2021-04-21,2020-08-11
-5a19,2016-02-17,2015-04-28
-2a1r,2005-12-20,2005-06-21
-6a18,2019-06-12,2018-06-06
-5a13,2015-09-02,2015-04-27
-3a1t,2009-09-22,2009-04-22
-3a1j,2009-06-02,2009-04-08
-1a1j,1998-06-17,1997-12-10
-8a17,2023-03-15,2022-05-31
-8a1k,2023-06-14,2022-06-01
-7a1v,2021-08-25,2020-08-14
-5a12,2015-09-02,2015-04-27
-7a1s,2021-08-25,2020-08-13
-2a1m,2005-07-05,2005-06-20
-8a1w,2023-06-14,2022-06-02
-7a14,2020-09-23,2020-08-11
-7a12,2020-09-23,2020-08-11
-6a1p,2019-06-19,2018-06-07
-2a1e,2006-02-21,2005-06-20
-2a1y,2006-07-04,2005-06-21
-1a1f,1998-06-10,1997-12-10
-7a19,2020-10-21,2020-08-12
-7a1f,2021-01-20,2020-08-12
-7a1b,2020-12-09,2020-08-12
-6a1n,2019-06-19,2018-06-07
-3a10,2009-10-20,2009-03-25
-5a1g,2016-02-17,2015-04-30
-8a1q,2023-02-01,2022-06-01
-2a1x,2005-08-16,2005-06-21
-7a1l,2021-08-25,2020-08-13
-5a1a,2015-05-06,2015-04-29
-7a1t,2021-05-19,2020-08-14
-4a1v,2012-09-19,2011-09-20
-8a1c,2022-07-13,2022-06-01
-8a1j,2023-06-14,2022-06-01
-7a1m,2021-08-25,2020-08-13
-5a1r,2015-06-24,2015-05-04
-1a1b,1998-04-08,1997-12-10
-2a14,2005-06-28,2005-06-17
-3a13,2010-04-07,2009-03-25
-8a1x,2023-06-14,2022-06-02
-7a1y,2021-10-13,2020-08-14
-6jrj,2020-04-15,2019-04-04
-2jr7,2008-03-25,2007-06-21
-5jr2,2016-07-06,2016-05-05
-5jrs,2016-08-31,2016-05-06
-8jrl,2024-04-17,2023-06-17
-6jr2,2020-04-08,2019-04-02
-5jr6,2016-08-31,2016-05-05
-6jrg,2019-10-23,2019-04-03
-4jrf,2013-04-03,2013-03-21
-4jr5,2013-05-08,2013-03-21
-5jrq,2016-09-14,2016-05-06
-8jr0,2024-05-01,2023-06-15
-3jrv,2009-11-10,2009-09-09
-8jrn,2024-06-05,2023-06-17
-5jrn,2017-05-24,2016-05-06
-8jro,2024-06-05,2023-06-17
-4jr3,2013-06-19,2013-03-21
-4jra,2013-11-20,2013-03-21
-6jr7,2019-04-24,2019-04-02
-5jrh,2016-12-21,2016-05-06
-8jrp,2024-06-05,2023-06-17
-5jrc,2016-09-28,2016-05-06
-5jrp,2017-11-08,2016-05-06
-5jru,2016-07-06,2016-05-06
-8jr4,2024-06-05,2023-06-16
-1jr0,2002-05-08,2001-08-09
-7jrl,2021-02-03,2020-08-12
-5jri,2017-11-15,2016-05-06
-1jrq,2001-11-21,2001-08-14
-4jrp,2013-05-08,2013-03-21
-6jr9,2020-04-08,2019-04-03
-4jre,2013-05-15,2013-03-21
-7jrv,2021-04-28,2020-08-13
-4jr1,2013-05-08,2013-03-20
-2jrj,2007-07-10,2007-06-27
-4jrz,2014-01-01,2013-03-22
-6jr5,2020-04-08,2019-04-02
-5jrx,2016-07-06,2016-05-06
-7jrh,2020-09-09,2020-08-12
-6jrq,2020-04-08,2019-04-05
-6jr8,2019-04-24,2019-04-02
-7jru,2021-04-28,2020-08-13
-6jr1,2019-10-02,2019-04-02
-1jrc,2003-09-09,2001-08-13
-5jr3,2016-06-01,2016-05-05
-6jrd,2020-04-08,2019-04-03
-3jrs,2009-11-03,2009-09-08
-8jrr,2024-06-05,2023-06-17
-5jr4,2017-02-22,2016-05-05
-4jrx,2013-04-10,2013-03-22
-1jr9,2002-08-14,2001-08-13
-7jri,2021-04-07,2020-08-12
-1jrb,2003-09-09,2001-08-13
-7jr8,2021-05-26,2020-08-11
-3jr8,2010-09-08,2009-09-08
-1jr3,2001-09-26,2001-08-10
-1jr1,2001-09-05,2001-08-09
-7jro,2021-01-20,2020-08-12
-7jr6,2021-05-26,2020-08-11
-3jrn,2009-10-20,2009-09-08
-4jr7,2014-03-05,2013-03-21
-3jr7,2009-10-20,2009-09-08
-1jrx,2001-11-02,2001-08-15
-3jrq,2009-11-03,2009-09-08
-1jrs,1996-10-14,1996-02-07
-4jrv,2013-06-19,2013-03-22
-7jr5,2021-10-06,2020-08-11
-1jr8,2001-12-28,2001-08-13
-7jrn,2020-08-26,2020-08-12
-6jre,2020-03-11,2019-04-03
-8jr1,2024-05-01,2023-06-15
-6jrb,2020-04-08,2019-04-03
-1jry,2001-11-02,2001-08-15
-4jr2,2013-05-08,2013-03-20
-5jrg,2017-03-08,2016-05-06
-1jrt,1996-10-14,1996-02-07
-5jrk,2016-09-28,2016-05-06
-4jrn,2013-10-23,2013-03-21
-5jrw,2017-01-25,2016-05-06
-1jrz,2001-11-02,2001-08-15
-5jra,2017-03-08,2016-05-06
-1jr4,2002-08-10,2001-08-10
-3jr2,2009-10-13,2009-09-08
-6jrs,2019-07-17,2019-04-05
-5jrr,2017-05-10,2016-05-06
-4jr8,2014-03-26,2013-03-21
-6jra,2020-04-08,2019-04-03
-7jrd,2021-10-13,2020-08-12
-6jrk,2020-04-15,2019-04-04
-5jr1,2016-07-13,2016-05-05
-7jrq,2021-01-13,2020-08-12
-3jr5,2009-11-03,2009-09-08
-4jro,2013-04-03,2013-03-21
-8jrq,2024-06-05,2023-06-17
-4jr0,2013-05-08,2013-03-20
-1jre,2003-06-17,2001-08-13
-1jro,2002-01-11,2001-08-14
-1jr7,2001-08-22,2001-08-12
-7jrw,2021-04-28,2020-08-13
-1jrf,2002-03-08,2001-08-13
-8jrj,2024-06-05,2023-06-17
-5jry,2016-06-08,2016-05-06
-1jra,2001-12-28,2001-08-13
-5jr7,2017-03-15,2016-05-05
-6jrr,2019-07-17,2019-04-05
-8jrk,2024-06-05,2023-06-17
-7jrg,2021-01-20,2020-08-12
-7jrp,2021-01-20,2020-08-12
-3jru,2010-09-08,2009-09-08
-7jrm,2021-02-03,2020-08-12
-8jrv,2023-08-16,2023-06-17
-3jr4,2009-11-03,2009-09-08
-2jrp,2007-07-10,2007-06-28
-6jrx,2020-04-15,2019-04-06
-6jrc,2020-04-08,2019-04-03
-3jrx,2010-01-12,2009-09-09
-5jrj,2016-08-03,2016-05-06
-8jr9,2023-08-02,2023-06-16
-5jrv,2016-07-06,2016-05-06
-8jru,2023-08-16,2023-06-17
-4jr9,2013-05-15,2013-03-21
-7jr1,2021-07-21,2020-08-11
-7jre,2021-08-25,2020-08-12
-6jrf,2019-10-23,2019-04-03
-5jrd,2017-03-08,2016-05-06
-4jrg,2013-07-24,2013-03-21
-5jre,2016-09-28,2016-05-06
-3jr3,2009-09-29,2009-09-08
-6jr0,2019-10-02,2019-04-02
-1jrp,2002-01-11,2001-08-14
-4jry,2013-04-10,2013-03-22
-7jra,2020-12-09,2020-08-11
-3t19,2011-10-26,2011-07-21
-5t1f,2017-06-28,2016-08-19
-8t1g,2024-05-29,2023-06-02
-1t1y,2005-09-06,2004-04-19
-1t1w,2005-09-06,2004-04-19
-8t1d,2023-07-05,2023-06-02
-7t1g,2022-10-05,2021-12-01
-8t1t,2023-11-22,2023-06-03
-6t1b,2020-01-29,2019-10-03
-6t1g,2020-10-14,2019-10-04
-3t12,2011-08-31,2011-07-21
-3t1g,2012-02-08,2011-07-21
-1t1i,2004-08-03,2004-04-16
-6t1j,2019-11-06,2019-10-04
-1t1a,2005-01-18,2004-04-15
-7t1x,2022-12-07,2021-12-02
-7t1t,2022-05-25,2021-12-02
-3t1a,2011-10-26,2011-07-21
-1t1z,2005-09-06,2004-04-19
-5t1u,2017-01-11,2016-08-22
-5t1a,2016-12-14,2016-08-18
-5t1k,2016-10-26,2016-08-19
-6t1i,2019-11-06,2019-10-04
-5t1m,2016-10-26,2016-08-19
-5t1h,2017-11-22,2016-08-19
-8t1s,2023-11-22,2023-06-03
-6t13,2020-12-23,2019-10-03
-3t1l,2011-12-28,2011-07-22
-5t1p,2016-09-07,2016-08-19
-3t1k,2012-01-25,2011-07-22
-7t1f,2022-12-14,2021-12-01
-6t1a,2020-10-14,2019-10-03
-3t14,2012-05-16,2011-07-21
-3t1q,2011-08-31,2011-07-22
-5t1e,2017-06-28,2016-08-19
-7t19,2022-05-25,2021-12-01
-8t1c,2023-07-05,2023-06-02
-3t1h,2012-01-25,2011-07-21
-3t1c,2011-10-05,2011-07-21
-3t1r,2011-08-31,2011-07-22
-1t1f,2005-10-04,2004-04-16
-6t1d,2020-02-19,2019-10-04
-5t1z,2017-08-30,2016-08-22
-3t1u,2012-03-07,2011-07-22
-7t18,2022-05-25,2021-12-01
-8t1y,2023-10-04,2023-06-05
-6t1m,2019-11-06,2019-10-04
-5t19,2017-04-12,2016-08-18
-6t1s,2021-04-14,2019-10-05
-6t1u,2020-01-08,2019-10-06
-8t1f,2023-07-05,2023-06-02
-1t1s,2004-09-14,2004-04-17
-6t16,2020-06-17,2019-10-03
-1t13,2005-04-19,2004-04-15
-5t1q,2017-06-07,2016-08-19
-1t16,2004-06-15,2004-04-15
-7t1a,2022-05-25,2021-12-01
-6t1t,2020-01-08,2019-10-06
-1t1c,2005-01-18,2004-04-15
-3t1i,2011-11-30,2011-07-22
-6t19,2020-10-14,2019-10-03
-1t1b,2005-01-18,2004-04-15
-1t1e,2004-08-03,2004-04-16
-8t1q,2023-11-08,2023-06-02
-3t1o,2011-08-31,2011-07-22
-6t1z,2020-07-29,2019-10-07
-8t1r,2023-11-08,2023-06-02
-7t1h,2022-10-05,2021-12-01
-7t11,2022-03-09,2021-11-30
-6t1h,2020-10-14,2019-10-04
-8t1j,2023-11-29,2023-06-02
-3t1t,2011-08-31,2011-07-22
-3t1n,2011-11-30,2011-07-22
-6t12,2020-03-04,2019-10-03
-8t1o,2023-07-12,2023-06-02
-6t1e,2020-10-14,2019-10-04
-6t15,2020-04-22,2019-10-03
-5t1l,2016-10-26,2016-08-19
-5t18,2017-03-08,2016-08-18
-7t1y,2022-02-16,2021-12-02
-6t1o,2019-11-06,2019-10-04
-8t1e,2023-07-05,2023-06-02
-3t13,2011-08-03,2011-07-21
-5t13,2017-04-12,2016-08-17
-6t1c,2020-10-14,2019-10-03
-7t1k,2022-08-24,2021-12-02
-5t1s,2017-05-03,2016-08-22
-7t1v,2022-01-12,2021-12-02
-1t1g,2004-08-03,2004-04-16
-8t10,2024-05-08,2023-06-01
-1t1x,2005-09-06,2004-04-19
-5t15,2016-10-12,2016-08-17
-1t18,2005-01-18,2004-04-15
-7t1q,2021-12-15,2021-12-02
-8t1z,2023-10-04,2023-06-05
-7t1j,2022-09-07,2021-12-02
-1t19,2005-01-18,2004-04-15
-5t1t,2017-05-03,2016-08-22
-6t1l,2019-11-06,2019-10-04
-1t1n,1999-04-29,1999-03-05
-8t1k,2023-11-29,2023-06-02
-5t1d,2016-12-28,2016-08-18
-8t1b,2023-07-05,2023-06-02
-3t1v,2011-08-31,2011-07-22
-8t1u,2023-11-22,2023-06-03
-7t1b,2022-05-25,2021-12-01
-8t13,2024-01-17,2023-06-01
-5t1g,2016-09-14,2016-08-19
-1t1r,2004-09-14,2004-04-17
-5t1w,2017-01-11,2016-08-22
-1t15,2004-05-11,2004-04-15
-6t1k,2020-10-14,2019-10-04
-5t14,2016-12-21,2016-08-17
-7t1u,2022-08-24,2021-12-02
-7t1l,2022-08-24,2021-12-02
-3t10,2012-01-25,2011-07-21
-7t1i,2022-10-05,2021-12-02
-6t10,2020-03-04,2019-10-03
-3t1y,2012-01-25,2011-07-22
-6t18,2020-06-17,2019-10-03
-1t10,2004-06-29,2004-04-14
-8t14,2024-06-05,2023-06-01
-6t14,2020-10-14,2019-10-03
-8t12,2024-01-17,2023-06-01
-7t1w,2022-12-07,2021-12-02
-7t1d,2023-05-17,2021-12-01
-6t1v,2021-04-14,2019-10-06
-8t1p,2023-11-15,2023-06-02
-6t1y,2020-03-04,2019-10-07
-3t11,2012-08-22,2011-07-21
-3t1m,2011-12-28,2011-07-22
-6t1n,2019-11-06,2019-10-04
-6t1p,2020-06-17,2019-10-04
-6t11,2020-03-04,2019-10-03
-3t1f,2011-09-21,2011-07-21
-2bpw,1999-02-23,1998-01-22
-8bp4,2023-11-29,2022-11-16
-2bpe,2006-08-31,2005-04-19
-4bp2,1991-10-15,1990-09-07
-6bpt,2018-07-04,2017-11-26
-3bpz,2008-03-25,2007-12-19
-1bpe,1994-07-31,1994-04-12
-6bpr,2019-04-17,2017-11-26
-5bp5,2015-09-02,2015-05-27
-5bpa,2015-06-17,2015-05-27
-6bpl,2018-05-02,2017-11-23
-8bpp,2024-02-28,2022-11-17
-7bpb,2021-03-31,2020-03-22
-1bp6,1998-08-19,1998-08-13
-4bpz,2013-12-18,2013-05-29
-8bpc,2023-05-10,2022-11-16
-2bp6,2006-02-22,2005-04-18
-6bpm,2018-11-28,2017-11-23
-6bpp,2018-05-02,2017-11-24
-6bps,2018-07-04,2017-11-26
-4bpu,2013-09-25,2013-05-28
-3bp7,2008-12-23,2007-12-18
-8bpr,2023-04-26,2022-11-17
-1bp0,2000-01-12,1998-08-11
-5bpq,2015-07-01,2015-05-28
-2bpv,1999-02-23,1998-01-22
-4bp3,2014-06-25,2013-05-23
-8bpw,2023-11-29,2022-11-18
-2bpn,2006-03-15,2005-04-21
-7bpc,2020-07-15,2020-03-22
-7bp8,2021-03-31,2020-03-21
-5bp9,2015-06-10,2015-05-27
-7bp4,2020-11-11,2020-03-21
-5bpj,2015-12-30,2015-05-28
-4bpk,2014-04-09,2013-05-27
-8bpb,2023-05-10,2022-11-16
-1bpy,1997-06-16,1997-04-15
-8bpo,2023-07-05,2022-11-17
-3bpm,2008-12-30,2007-12-18
-7bpi,2021-01-27,2020-03-22
-2bp0,2006-07-26,2005-04-17
-3bps,2008-02-12,2007-12-19
-3bp1,2008-01-08,2007-12-18
-8bpu,2023-06-28,2022-11-17
-4bpb,2013-06-19,2013-05-23
-7bp5,2020-11-11,2020-03-21
-3bpw,2008-11-18,2007-12-19
-7bpz,2020-11-11,2020-03-23
-7bp1,2020-07-15,2020-03-21
-4bpj,2014-04-09,2013-05-27
-5bp7,2015-06-10,2015-05-27
-2bpp,1993-10-31,1992-01-17
-6bpu,2018-07-04,2017-11-26
-1bp2,1981-05-21,1981-04-06
-3bpu,2008-01-08,2007-12-19
-5bpl,2016-09-14,2015-05-28
-8bpy,2022-12-28,2022-11-18
-4bpd,2014-05-07,2013-05-24
-8bp2,2023-02-08,2022-11-15
-8bpg,2023-04-12,2022-11-16
-8bpx,2023-01-25,2022-11-18
-6bp0,2017-12-06,2017-11-21
-2bpf,1994-12-14,1994-05-19
-3bpb,2008-06-17,2007-12-18
-5bp4,2016-03-09,2015-05-27
-1bpm,1993-07-15,1993-03-02
-7bpo,2021-03-24,2020-03-23
-8bpq,2024-06-05,2022-11-17
-8bpa,2023-05-10,2022-11-16
-7bp9,2021-03-31,2020-03-21
-2bpo,2006-07-13,2005-04-21
-8bpj,2023-06-28,2023-01-17
-8bp1,2024-02-28,2022-11-15
-1bpz,1997-06-16,1997-04-14
-3bpd,2008-01-08,2007-12-18
-3bp2,1983-09-15,1983-06-27
-2bpz,1999-02-23,1998-01-22
-2bpc,1994-08-31,1994-07-08
-2bp8,2006-07-26,2005-04-18
-3bpo,2008-02-05,2007-12-18
-4bph,2014-06-11,2013-05-26
-5bp0,2015-06-24,2015-05-27
-7bph,2021-03-31,2020-03-22
-2bpb,2005-04-28,2005-04-19
-5bpx,2015-06-10,2015-05-28
-5bph,2016-03-02,2015-05-28
-1bpw,1998-08-19,1998-08-12
-6bpx,2018-07-04,2017-11-26
-1bp3,1998-08-19,1998-08-12
-8bp8,2023-04-05,2022-11-16
-4bpi,2014-04-09,2013-05-27
-5bpu,2015-07-01,2015-05-28
-2bpy,1999-02-23,1998-01-22
-6bp4,2018-07-25,2017-11-21
-3bpt,2008-01-08,2007-12-19
-6bpy,2019-01-09,2017-11-27
-5bps,2015-08-26,2015-05-28
-1bpq,1993-10-31,1991-10-28
-5bpf,2016-03-02,2015-05-28
-4bp9,2014-02-12,2013-05-23
-8bp6,2023-11-29,2022-11-16
-5bpm,2016-09-14,2015-05-28
-5bp2,2016-03-09,2015-05-27
-3bp4,2008-12-23,2007-12-18
-8bp7,2024-04-24,2022-11-16
-1bpx,1997-06-16,1997-04-11
-5bpb,2015-07-01,2015-05-27
-6bpf,2018-11-28,2017-11-23
-4bpm,2014-04-16,2013-05-27
-8bp9,2023-05-03,2022-11-16
-8bpd,2023-11-08,2022-11-16
-4bpa,2013-07-17,2013-05-23
-6bpw,2018-07-04,2017-11-26
-6bp1,2018-01-24,2017-11-21
-4bp1,2014-06-04,2013-05-23
-5bpy,2015-09-23,2015-05-28
-6bpg,2018-11-28,2017-11-23
-3bpx,2008-05-20,2007-12-19
-5bpp,2016-08-10,2015-05-28
-8bpf,2023-04-12,2022-11-16
-6bp2,2018-01-17,2017-11-21
-2bph,2006-08-31,2005-04-19
-7bpr,2020-07-15,2020-03-23
-3bpc,2009-01-13,2007-12-18
-1bp7,1999-01-06,1998-08-13
-6bpi,2017-12-27,2017-11-23
-2bpi,2006-10-11,2005-04-20
-5bpe,2015-11-25,2015-05-28
-1bpj,1998-08-19,1998-08-11
-4bps,2013-09-18,2013-05-28
-7bpy,2020-11-11,2020-03-23
-5bpk,2016-05-18,2015-05-28
-3bpr,2008-01-29,2007-12-19
-1bph,1993-01-15,1992-10-30
-8bpn,2023-01-18,2023-01-09
-6bpv,2018-07-04,2017-11-26
-7bp6,2020-11-11,2020-03-21
-2bpu,2006-08-24,2005-04-25
-2bp1,2005-05-11,2005-04-17
-8bpe,2023-04-12,2022-11-16
-3bpl,2008-02-05,2007-12-18
-4bpx,2013-09-25,2013-05-28
-8bpv,2023-11-29,2022-11-18
-2bpg,1994-08-31,1994-05-19
-4bp0,2014-06-18,2013-05-22
-7bps,2020-07-15,2020-03-23
-4bpr,2013-11-20,2013-05-28
-3bp8,2008-05-27,2007-12-18
-5bpc,2015-08-19,2015-05-28
-2bpm,2005-12-08,2005-04-21
-2bpa,1991-12-03,1991-12-03
-1bpn,1993-07-15,1993-03-02
-4bpw,2013-09-25,2013-05-28
-7bpa,2021-03-31,2020-03-21
-6bpn,2018-11-28,2017-11-23
-4bpv,2014-06-11,2013-05-28
-1bp4,1999-08-12,1998-08-12
-3bpn,2008-02-05,2007-12-18
-2bpx,1999-02-23,1998-01-22
-3bpf,2008-12-30,2007-12-18
-1d7u,1999-11-19,1999-10-19
-8d7o,2023-05-17,2022-06-07
-6d7a,2018-05-16,2018-04-24
-8d7a,2023-05-10,2022-06-07
-3d73,2009-05-26,2008-05-20
-7d7d,2021-01-20,2020-10-03
-1d7i,1999-10-21,1999-10-18
-2d7f,2006-12-19,2005-11-19
-8d7m,2023-05-17,2022-06-07
-1d7q,2000-03-17,1999-10-19
-6d7c,2018-05-30,2018-04-24
-5d7i,2016-01-27,2015-08-14
-8d7w,2022-07-20,2022-06-07
-6d72,2018-05-16,2018-04-23
-3d72,2008-06-17,2008-05-20
-5d75,2016-04-06,2015-08-13
-1d7p,1999-12-01,1999-10-19
-6d7g,2019-01-23,2018-04-24
-2d7g,2006-11-07,2005-11-21
-4d7v,2015-07-22,2014-11-27
-8d7z,2022-07-20,2022-06-07
-8d75,2023-05-10,2022-06-07
-5d7d,2015-11-11,2015-08-13
-5d7f,2016-08-17,2015-08-13
-8d7r,2023-03-29,2022-06-07
-5d77,2016-08-17,2015-08-13
-5d7o,2015-12-02,2015-08-14
-7d7l,2021-04-21,2020-10-04
-5d74,2016-08-17,2015-08-13
-4d7o,2015-07-01,2014-11-25
-6d7v,2018-07-18,2018-04-25
-4d7h,2015-07-01,2014-11-25
-4d7e,2015-04-01,2014-11-24
-8d74,2023-03-29,2022-06-07
-5d7w,2016-01-13,2015-08-14
-7d7m,2020-11-18,2020-10-05
-6d7q,2018-07-18,2018-04-25
-3d7h,2008-12-30,2008-05-21
-6d78,2019-04-03,2018-04-24
-6d7f,2018-10-17,2018-04-24
-3d7r,2009-06-09,2008-05-21
-8d7n,2023-05-17,2022-06-07
-3d7b,2009-02-10,2008-05-21
-3d7f,2008-12-30,2008-05-21
-8d7s,2023-05-10,2022-06-07
-7d72,2021-05-05,2020-10-02
-5d7n,2015-12-02,2015-08-14
-6d7j,2019-05-01,2018-04-24
-6d7x,2018-07-18,2018-04-25
-4d7b,2016-01-20,2014-11-21
-4d72,2015-01-21,2014-11-19
-3d7j,2008-10-21,2008-05-21
-1d7o,1999-11-08,1999-10-19
-3d78,2009-05-26,2008-05-20
-6d71,2019-10-09,2018-04-23
-8d7y,2022-07-20,2022-06-07
-4d7c,2014-12-24,2014-11-21
-5d76,2016-08-17,2015-08-13
-3d7o,2009-05-05,2008-05-21
-8d76,2022-07-27,2022-06-07
-5d73,2015-11-11,2015-08-13
-7d7p,2020-11-18,2020-10-05
-8d7q,2023-05-10,2022-06-07
-6d7o,2018-07-18,2018-04-25
-2d7r,2006-11-07,2005-11-25
-4d7f,2016-01-20,2014-11-24
-2d7d,2006-05-02,2005-11-18
-6d7h,2019-07-24,2018-04-24
-5d7c,2015-11-25,2015-08-13
-2d7y,2006-11-14,2005-11-30
-4d7y,2015-01-28,2014-12-01
-3d7k,2008-07-01,2008-05-21
-2d74,2006-07-25,2005-11-16
-6d7p,2018-07-18,2018-04-25
-1d7x,2000-10-23,1999-10-20
-4d7i,2015-07-01,2014-11-25
-8d7p,2023-05-17,2022-06-07
-1d7c,2000-10-18,1999-10-16
-8d73,2022-07-27,2022-06-07
-5d7j,2016-01-27,2015-08-14
-1d7y,2000-12-20,1999-10-21
-4d77,2014-12-24,2014-11-20
-2d7c,2006-09-26,2005-11-16
-4d7s,2015-02-11,2014-11-27
-7d7k,2021-04-21,2020-10-04
-4d7m,2014-12-10,2014-11-25
-4d7g,2016-01-20,2014-11-24
-5d79,2016-06-22,2015-08-13
-5d7r,2015-11-18,2015-08-14
-4d7n,2014-12-10,2014-11-25
-3d74,2009-05-26,2008-05-20
-2d7h,2006-11-07,2005-11-21
-3d7v,2008-06-24,2008-05-22
-3d75,2009-05-26,2008-05-20
-3d76,2009-05-26,2008-05-20
-2d7i,2006-11-07,2005-11-21
-3d7s,2008-07-29,2008-05-21
-1d7j,1999-10-21,1999-10-18
-5d7y,2016-02-17,2015-08-14
-3d7z,2008-07-22,2008-05-22
-4d7a,2015-05-06,2014-11-21
-1d7a,1999-12-03,1999-10-16
-1d7w,2001-12-12,1999-10-20
-3d7w,2008-06-17,2008-05-22
-8d7l,2023-05-10,2022-06-07
-8d7j,2023-05-10,2022-06-07
-8d7u,2022-07-20,2022-06-07
-6d73,2019-05-15,2018-04-23
-2d7z,2006-11-14,2005-11-30
-4d75,2015-09-23,2014-11-19
-7d7q,2020-11-18,2020-10-05
-8d7c,2023-05-10,2022-06-07
-5d7z,2015-09-09,2015-08-14
-8d7h,2023-03-29,2022-06-07
-6d7u,2018-05-30,2018-04-25
-1d7f,2000-03-17,1999-10-18
-7d7e,2021-08-25,2020-10-03
-4d7u,2015-07-22,2014-11-27
-7d74,2021-05-19,2020-10-02
-7d7f,2021-09-01,2020-10-03
-5d7q,2015-12-02,2015-08-14
-7d76,2021-02-03,2020-10-03
-5d7a,2016-08-17,2015-08-13
-4d71,2015-01-21,2014-11-19
-1d7e,2000-03-31,1999-10-17
-7d77,2021-02-03,2020-10-03
-7d79,2021-01-27,2020-10-03
-3d71,2008-08-26,2008-05-20
-5d7s,2015-10-14,2015-08-14
-3d7d,2008-12-30,2008-05-21
-7d75,2021-10-06,2020-10-03
-1d7r,1999-11-19,1999-10-19
-8d7b,2023-05-10,2022-06-07
-4d7d,2015-09-23,2014-11-22
-8d71,2023-05-03,2022-06-07
-5d7p,2015-12-02,2015-08-14
-1d7b,2000-10-18,1999-10-16
-8d7d,2023-05-10,2022-06-07
-3d77,2009-05-26,2008-05-20
-7d73,2021-05-05,2020-10-02
-8d7v,2022-07-20,2022-06-07
-1d7v,1999-11-19,1999-10-19
-8d7x,2022-07-20,2022-06-07
-5d7e,2015-09-23,2015-08-13
-5d7l,2016-01-27,2015-08-14
-7d7c,2021-01-20,2020-10-03
-3d7t,2008-08-05,2008-05-21
-1d7s,1999-11-19,1999-10-19
-7d7v,2020-11-25,2020-10-06
-6d7k,2019-06-26,2018-04-24
-3d7m,2009-03-03,2008-05-21
-6d7w,2018-07-11,2018-04-25
-4d7t,2015-02-11,2014-11-27
-4d76,2016-01-20,2014-11-20
-6d7t,2018-07-18,2018-04-25
-8d7e,2023-03-29,2022-06-07
-3d7g,2008-12-30,2008-05-21
-4d7j,2015-07-01,2014-11-25
-4d78,2015-09-23,2014-11-21
-7d7u,2020-11-25,2020-10-06
-4d7p,2015-10-07,2014-11-26
-8d77,2023-05-10,2022-06-07
-7d7o,2021-08-18,2020-10-05
-1d7l,2000-01-21,1999-10-18
-5d7x,2016-05-25,2015-08-14
-1d7d,2000-10-18,1999-10-16
-2d73,2007-02-27,2005-11-15
-4d79,2015-05-06,2014-11-21
-7d78,2021-01-27,2020-10-03
-3swj,2011-11-09,2011-07-14
-3sww,2011-10-26,2011-07-14
-3sw7,2012-08-01,2011-07-13
-1swe,1998-03-04,1997-03-04
-1sww,2004-10-05,2004-03-30
-1sw7,2004-08-24,2004-03-30
-6swp,2020-04-01,2019-09-22
-1swt,1999-07-30,1998-10-22
-5swb,2016-12-14,2016-08-08
-8swy,2023-11-08,2023-05-19
-1swn,1999-02-09,1998-01-27
-1sw3,2004-08-24,2004-03-30
-3swb,2012-07-18,2011-07-13
-8sw1,2023-07-26,2023-05-17
-1swy,2004-11-23,2004-03-30
-8swu,2023-10-18,2023-05-19
-7swg,2022-04-06,2021-11-19
-8swe,2024-02-14,2023-05-18
-8swa,2023-11-15,2023-05-18
-8swq,2023-10-18,2023-05-19
-5swi,2016-12-14,2016-08-08
-3sw4,2012-08-01,2011-07-13
-5sw4,2016-08-24,2016-08-08
-6swn,2020-04-01,2019-09-22
-6swo,2020-04-01,2019-09-22
-3swz,2012-01-25,2011-07-14
-6swx,2020-08-05,2019-09-24
-5swc,2016-10-26,2016-08-08
-5sww,2016-12-28,2016-08-09
-5swg,2017-02-15,2016-08-08
-8sw8,2024-06-05,2023-05-17
-3swc,2011-11-30,2011-07-13
-3swa,2012-03-07,2011-07-13
-1swv,2004-10-05,2004-03-30
-3swo,2011-08-03,2011-07-14
-3sw6,2012-05-02,2011-07-13
-3swe,2012-03-14,2011-07-13
-3sw8,2011-07-27,2011-07-13
-5sws,2016-10-05,2016-08-08
-3swr,2011-08-10,2011-07-14
-6swe,2020-02-19,2019-09-20
-7swx,2022-11-23,2021-11-21
-8swk,2024-02-14,2023-05-18
-8swi,2023-12-27,2023-05-18
-6swr,2020-04-15,2019-09-23
-7swl,2022-03-02,2021-11-20
-1swk,1999-02-09,1998-01-27
-6swj,2020-10-14,2019-09-22
-8sww,2024-05-22,2023-05-19
-6sw2,2020-06-03,2019-09-19
-7swq,2022-11-23,2021-11-21
-3sw1,2012-02-15,2011-07-13
-8sw4,2024-05-29,2023-05-17
-5swp,2017-02-15,2016-08-08
-8swl,2024-03-27,2023-05-19
-5swh,2017-08-16,2016-08-08
-1sw4,2004-09-14,2004-03-30
-8sw7,2023-07-26,2023-05-17
-6swd,2020-02-19,2019-09-20
-7swd,2022-04-06,2021-11-19
-3swi,2012-03-07,2011-07-13
-5swf,2016-11-30,2016-08-08
-8swx,2024-05-22,2023-05-19
-8sw5,2024-05-29,2023-05-17
-5sw1,2017-08-09,2016-08-08
-5swn,2017-02-01,2016-08-08
-8swm,2024-04-24,2023-05-19
-1sw1,2004-09-14,2004-03-30
-5swa,2016-12-14,2016-08-08
-3swm,2012-04-11,2011-07-14
-7swf,2022-08-03,2021-11-19
-8swz,2023-11-08,2023-05-19
-3swq,2012-03-07,2011-07-14
-8swt,2023-10-18,2023-05-19
-3swn,2011-10-26,2011-07-14
-8sw0,2023-07-26,2023-05-17
-6sw0,2020-01-22,2019-09-19
-8sws,2023-10-18,2023-05-19
-3sw2,2011-11-16,2011-07-13
-5sw5,2016-08-24,2016-08-08
-3swg,2012-03-14,2011-07-13
-5sw7,2016-08-31,2016-08-08
-6swq,2020-04-01,2019-09-22
-8swr,2023-10-18,2023-05-19
-1swr,1999-02-09,1998-01-27
-3swd,2012-03-14,2011-07-13
-3swf,2011-09-14,2011-07-13
-8sw6,2024-05-29,2023-05-17
-3swt,2011-08-03,2011-07-14
-1swm,1994-01-31,1992-03-03
-7swi,2022-04-06,2021-11-19
-6swa,2020-09-30,2019-09-20
-1swz,2005-01-18,2004-03-30
-5swq,2016-10-05,2016-08-08
-1swp,1999-02-09,1998-01-27
-1sw0,2004-08-24,2004-03-30
-5swr,2017-02-15,2016-08-08
-8sw2,2023-11-15,2023-05-17
-8swv,2024-05-22,2023-05-19
-7sww,2022-11-23,2021-11-21
-3sw9,2011-12-07,2011-07-13
-3sws,2012-07-25,2011-07-14
-5swo,2017-02-15,2016-08-08
-8sw9,2024-04-24,2023-05-17
-5sw8,2017-02-15,2016-08-08
-8swp,2023-10-18,2023-05-19
-6swl,2020-10-14,2019-09-22
-6sw9,2020-02-19,2019-09-20
-8swd,2023-05-31,2023-05-18
-8swh,2024-05-22,2023-05-18
-6sw1,2020-06-03,2019-09-19
-5swz,2016-10-05,2016-08-09
-1sw5,2004-09-14,2004-03-30
-1swd,1998-03-04,1997-03-04
-1swg,1998-07-15,1997-07-12
-8swn,2024-01-17,2023-05-19
-6swm,2020-10-07,2019-09-22
-6swc,2020-02-19,2019-09-20
-1sw8,2004-04-06,2004-03-30
-5swm,2016-09-21,2016-08-08
-6swv,2020-05-20,2019-09-24
-5sw6,2016-08-24,2016-08-08
-5swt,2017-02-15,2016-08-08
-5sw3,2017-07-19,2016-08-08
-8tvq,2024-01-24,2023-08-18
-5tv8,2016-12-07,2016-11-08
-4tvm,2015-01-14,2014-06-27
-3tvo,2012-08-08,2011-09-20
-4tv5,2014-10-29,2014-06-25
-7tve,2022-06-22,2022-02-04
-6tvy,2020-12-16,2020-01-10
-5tvh,2017-11-15,2016-11-08
-7tv4,2022-08-17,2022-02-03
-4tvz,2015-07-08,2014-06-29
-6tve,2020-02-19,2020-01-09
-6tv0,2021-01-27,2020-01-08
-5tv7,2016-12-14,2016-11-08
-4tvj,2015-07-08,2014-06-27
-6tvp,2020-04-22,2020-01-10
-8tvg,2024-05-08,2023-08-18
-3tvm,2012-02-01,2011-09-20
-5tvp,2017-10-11,2016-11-09
-4tvx,2014-08-13,2014-06-28
-7tvz,2022-06-08,2022-02-06
-6tv3,2021-01-27,2020-01-08
-7tvp,2022-10-05,2022-02-05
-5tvn,2017-02-01,2016-11-09
-3tvy,2013-03-27,2011-09-21
-4tvy,2014-10-22,2014-06-28
-1tv4,2004-10-19,2004-06-26
-6tv4,2020-10-28,2020-01-08
-3tv8,2012-01-04,2011-09-19
-4tv3,2014-08-06,2014-06-25
-1tv6,2004-07-20,2004-06-28
-5tvu,2018-03-14,2016-11-10
-1tv3,2004-10-19,2004-06-26
-7tva,2023-02-15,2022-02-04
-1tvg,2004-11-09,2004-06-29
-6tvn,2020-11-25,2020-01-10
-3tvc,2012-06-20,2011-09-20
-1tvo,2005-09-13,2004-06-30
-6tvd,2020-10-21,2020-01-09
-1tvc,2004-10-12,2004-06-29
-4tvf,2014-11-12,2014-06-26
-1tvb,2005-04-19,2004-06-29
-8tvi,2024-05-01,2023-08-18
-4tvb,2015-07-08,2014-06-26
-1tvk,2004-09-14,2004-06-29
-6tvb,2020-10-21,2020-01-09
-4tvt,2014-07-16,2014-06-28
-1tvu,1998-01-28,1997-09-17
-3tvq,2012-04-04,2011-09-20
-7tvx,2022-02-16,2022-02-06
-5tvt,2017-11-15,2016-11-10
-4tvw,2014-10-22,2014-06-28
-6tvi,2020-02-12,2020-01-09
-5tvk,2016-11-23,2016-11-09
-5tv4,2017-09-20,2016-11-08
-8tvh,2024-05-08,2023-08-18
-8tvp,2024-01-24,2023-08-18
-4tv8,2014-08-27,2014-06-26
-6tvv,2021-01-27,2020-01-10
-6tvf,2020-10-21,2020-01-09
-4tvh,2014-09-17,2014-06-26
-7tvb,2023-02-15,2022-02-04
-6tvg,2020-02-26,2020-01-09
-5tv6,2016-12-07,2016-11-08
-4tvk,2014-10-08,2014-06-27
-1tvh,2005-04-19,2004-06-29
-5tvq,2017-09-27,2016-11-09
-4tv0,2014-09-17,2014-06-25
-5tvj,2017-03-01,2016-11-09
-1tve,2004-07-13,2004-06-29
-3tvi,2011-11-09,2011-09-20
-6tvo,2020-07-08,2020-01-10
-3tvu,2011-10-19,2011-09-20
-4tv1,2015-01-28,2014-06-25
-8tvb,2024-05-01,2023-08-17
-8tv7,2024-04-24,2023-08-17
-3tva,2011-10-05,2011-09-19
-1tv9,2004-11-23,2004-06-29
-4tv9,2014-08-20,2014-06-26
-6tvk,2021-07-21,2020-01-09
-6tv9,2020-04-22,2020-01-09
-5tvr,2017-02-01,2016-11-09
-4tv6,2014-10-29,2014-06-26
-5tvo,2016-12-28,2016-11-09
-5tvs,2017-02-01,2016-11-09
-5tv0,2017-06-07,2016-11-07
-6tv7,2021-10-27,2020-01-09
-4tva,2015-03-18,2014-06-26
-1tvp,2005-05-17,2004-06-30
-5tva,2016-12-07,2016-11-08
-3tvd,2012-10-10,2011-09-20
-7tvi,2023-03-22,2022-02-04
-3tvw,2011-10-19,2011-09-20
-1tvw,1998-01-28,1997-09-17
-4tvo,2015-01-14,2014-06-27
-8tvw,2024-01-24,2023-08-18
-8tvy,2024-01-24,2023-08-18
-3tv4,2011-10-05,2011-09-19
-6tvw,2021-01-27,2020-01-10
-3tv7,2012-02-15,2011-09-19
-8tv6,2024-04-17,2023-08-17
-3tv1,2011-12-28,2011-09-19
-3tv2,2011-09-28,2011-09-19
-3tv3,2011-10-19,2011-09-19
-3tv6,2011-10-05,2011-09-19
-3tvn,2012-08-08,2011-09-20
-4tvc,2015-07-29,2014-06-26
-8tvs,2024-01-24,2023-08-18
-8tve,2024-05-08,2023-08-18
-7tvf,2022-05-04,2022-02-04
-4tvu,2014-12-17,2014-06-28
-1tv5,2005-09-06,2004-06-27
-8tvf,2024-05-08,2023-08-18
-8tvx,2024-01-24,2023-08-18
-6tvs,2020-10-21,2020-01-10
-1tv2,2004-10-19,2004-06-26
-4tvd,2015-08-05,2014-06-26
-3tvk,2012-10-03,2011-09-20
-5tvg,2016-11-16,2016-11-08
-1tvr,1997-03-12,1996-04-16
-6tvx,2020-02-19,2020-01-10
-1tva,2004-11-23,2004-06-29
-5tvc,2016-11-30,2016-11-08
-5tvv,2017-10-04,2016-11-10
-1tvy,2004-12-14,2004-06-30
-7tv3,2023-02-15,2022-02-03
-5tv3,2017-09-20,2016-11-07
-3tv5,2011-10-19,2011-09-19
-4tvg,2014-09-24,2014-06-26
-1tvv,1998-01-28,1997-09-17
-5tvw,2018-03-14,2016-11-10
-7tvs,2022-02-16,2022-02-05
-4tvr,2015-06-24,2014-06-27
-6tvr,2020-10-21,2020-01-10
-6tvc,2020-10-21,2020-01-09
-4tvp,2014-10-08,2014-06-27
-6tvl,2020-04-29,2020-01-10
-3tvx,2012-01-25,2011-09-20
-5tvx,2017-10-25,2016-11-10
-6tvt,2020-10-21,2020-01-10
-6tv6,2021-07-21,2020-01-09
-8tvv,2024-01-24,2023-08-18
-6tva,2020-10-21,2020-01-09
-7tv9,2022-03-30,2022-02-04
-1tv8,2004-08-31,2004-06-28
-4pwy,2014-04-16,2014-03-21
-1pwg,2004-07-13,2003-07-01
-3pwp,2011-03-09,2010-12-08
-1pwb,2003-08-05,2003-07-01
-5pw8,2017-03-29,2017-02-07
-3pwb,2011-12-21,2010-12-08
-5pw5,2017-03-29,2017-02-07
-5pwo,2017-03-22,2017-02-08
-5pwu,2017-03-22,2017-02-08
-7pwd,2021-10-20,2021-10-06
-7pwf,2022-05-25,2021-10-06
-4pwg,2014-11-26,2014-03-20
-3pwg,2011-12-28,2010-12-08
-3pw8,2011-01-19,2010-12-07
-8pwa,2023-11-08,2023-07-19
-4pw4,2014-06-25,2014-03-18
-1pwy,2004-03-23,2003-07-02
-1pw8,2004-07-13,2003-07-01
-5pwz,2017-03-22,2017-02-08
-3pwf,2011-06-22,2010-12-08
-2pwv,2007-10-30,2007-05-13
-7pwg,2022-04-20,2021-10-06
-4pwv,2014-07-23,2014-03-21
-2pwa,2007-05-29,2007-05-11
-1pww,2004-01-27,2003-07-02
-3pwd,2011-11-02,2010-12-08
-3pww,2011-12-14,2010-12-09
-4pwb,2014-04-02,2014-03-19
-2pwg,2007-06-26,2007-05-11
-4pwx,2014-04-09,2014-03-21
-1pw9,2003-08-05,2003-07-01
-6pw4,2019-09-25,2019-07-22
-7pwz,2022-12-21,2021-10-07
-5pwt,2017-03-22,2017-02-08
-6pww,2019-12-18,2019-07-23
-2pwl,2007-09-25,2007-05-11
-5pwg,2017-03-22,2017-02-08
-5pw7,2017-03-29,2017-02-07
-3pwr,2011-04-20,2010-12-08
-5pwe,2017-03-22,2017-02-08
-7pwt,2022-12-21,2021-10-07
-5pwj,2017-03-22,2017-02-08
-5pwh,2017-03-22,2017-02-08
-3pwk,2012-01-04,2010-12-08
-6pw6,2020-06-24,2019-07-22
-3pw0,2011-08-10,2010-12-07
-3pwh,2011-09-07,2010-12-08
-3pwm,2011-04-20,2010-12-08
-6pw7,2019-11-13,2019-07-22
-7pww,2022-05-11,2021-10-07
-1pwu,2004-02-03,2003-07-02
-6pwy,2020-07-29,2019-07-24
-2pwy,2008-02-26,2007-05-14
-4pwk,2014-11-26,2014-03-20
-8pwh,2024-02-21,2023-07-20
-5pwr,2017-03-22,2017-02-08
-7pwq,2022-05-11,2021-10-07
-7pwb,2022-04-20,2021-10-06
-7pwu,2022-05-11,2021-10-07
-6pwk,2019-10-09,2019-07-23
-5pwy,2017-03-22,2017-02-08
-6pwc,2019-12-04,2019-07-22
-5pwd,2017-03-15,2017-02-07
-7pwa,2022-05-11,2021-10-06
-5pwp,2017-03-22,2017-02-08
-5pw2,2017-03-29,2017-02-07
-8pw9,2023-11-08,2023-07-19
-2pw8,2007-08-21,2007-05-10
-5pwf,2017-03-22,2017-02-08
-6pw8,2020-07-22,2019-07-22
-7pwp,2022-05-11,2021-10-07
-4pwa,2015-06-03,2014-03-19
-5pwc,2017-03-15,2017-02-07
-5pwv,2017-03-22,2017-02-08
-6pwu,2020-02-26,2019-07-23
-1pw3,2004-08-17,2003-06-30
-7pw3,2022-05-11,2021-10-06
-8pw8,2023-11-08,2023-07-19
-1pw7,2003-11-25,2003-06-30
-3pwy,2011-04-20,2010-12-09
-6pwv,2019-12-18,2019-07-23
-6pwz,2020-07-29,2019-07-24
-7pw6,2021-12-01,2021-10-06
-7pwc,2022-05-11,2021-10-06
-6pw3,2019-11-06,2019-07-22
-3pwv,2011-08-24,2010-12-09
-5pwb,2017-03-29,2017-02-07
-5pw9,2017-03-29,2017-02-07
-3pwc,2011-12-21,2010-12-08
-7pws,2022-05-11,2021-10-07
-4pw9,2015-06-03,2014-03-19
-3pws,2012-01-04,2010-12-08
-2pwf,2007-06-26,2007-05-11
-7pw9,2021-12-01,2021-10-06
-7pwm,2022-05-11,2021-10-07
-2pwh,2007-06-26,2007-05-11
-7pw4,2021-12-01,2021-10-06
-6pwg,2019-09-11,2019-07-23
-3pwu,2011-08-24,2010-12-09
-3pw2,2011-08-10,2010-12-07
-2pw1,2007-05-22,2007-05-10
-5pws,2017-03-22,2017-02-08
-7pwi,2022-04-20,2021-10-06
-3pw5,2011-08-10,2010-12-07
-2pwc,2008-04-15,2007-05-11
-8pw1,2024-01-31,2023-07-19
-1pwh,2003-12-02,2003-07-01
-1pwv,2004-02-03,2003-07-02
-3pw7,2011-08-10,2010-12-07
-4pwl,2015-02-11,2014-03-20
-6pwq,2020-07-22,2019-07-23
-6pwj,2019-10-09,2019-07-23
-1pw5,2004-03-02,2003-06-30
-5pwk,2017-03-22,2017-02-08
-5pwa,2017-03-29,2017-02-07
-3pwn,2011-03-09,2010-12-08
-3pwl,2011-03-09,2010-12-08
-5pwx,2017-03-22,2017-02-08
-1pwq,2004-01-13,2003-07-02
-2pw2,2007-05-22,2007-05-10
-8pwn,2023-10-25,2023-07-20
-5pw1,2017-03-29,2017-02-07
-3pwx,2011-01-19,2010-12-09
-8pw5,2024-04-24,2023-07-19
-6pwr,2019-09-11,2019-07-23
-4pwj,2014-11-26,2014-03-20
-7pwy,2022-04-20,2021-10-07
-4pwh,2014-11-26,2014-03-20
-6pwt,2019-09-11,2019-07-23
-8pw6,2024-04-24,2023-07-19
-3pwi,2011-12-28,2010-12-08
-5pw0,2017-03-29,2017-02-07
-1pwp,2004-01-13,2003-07-02
-7pwh,2022-04-20,2021-10-06
-7pwn,2022-02-09,2021-10-07
-1pw6,2004-01-13,2003-06-30
-2pwu,2007-10-30,2007-05-13
-7pwl,2022-05-11,2021-10-07
-6pw5,2019-09-25,2019-07-22
-5pwn,2017-03-22,2017-02-08
-7pw8,2021-12-01,2021-10-06
-6pw1,2019-11-27,2019-07-21
-7pw5,2021-12-01,2021-10-06
-7pw7,2021-12-01,2021-10-06
-7pwr,2022-05-11,2021-10-07
-8pw7,2024-04-24,2023-07-19
-7pwo,2022-04-20,2021-10-07
-2pw3,2007-10-23,2007-05-10
-5pww,2017-03-22,2017-02-08
-5pw3,2017-03-29,2017-02-07
-3pw3,2010-12-22,2010-12-07
-5pwl,2017-03-22,2017-02-08
-2pws,2007-05-22,2007-05-13
-5pwm,2017-03-22,2017-02-08
-1pwd,2004-07-13,2003-07-01
-4pwd,2014-06-18,2014-03-19
-3pw1,2011-01-19,2010-12-07
-4pwi,2014-11-26,2014-03-20
-6pw0,2019-11-27,2019-07-21
-6pwm,2020-10-21,2019-07-23
-6pwh,2019-12-04,2019-07-23
-7pw1,2022-04-06,2021-10-05
-1pwl,2004-02-24,2003-07-02
-2pw0,2007-08-21,2007-05-10
-2pwr,2008-04-15,2007-05-12
-3pw4,2011-08-10,2010-12-07
-1pwm,2004-02-24,2003-07-02
-5pwq,2017-03-22,2017-02-08
-2pwb,2007-05-22,2007-05-11
-4pwc,2014-04-02,2014-03-19
-2pw6,2007-06-12,2007-05-10
-6pws,2019-09-11,2019-07-23
-8pwb,2023-11-08,2023-07-19
-5pwi,2017-03-22,2017-02-08
-2pwe,2007-06-26,2007-05-11
-6pw9,2020-02-19,2019-07-22
-1pwc,2004-07-13,2003-07-01
-4pw8,2014-08-06,2014-03-19
-4pwf,2014-11-26,2014-03-20
-7pwk,2022-05-11,2021-10-07
-2pwd,2007-06-26,2007-05-11
-1pw1,2004-07-13,2003-06-30
-4pw3,2015-06-03,2014-03-18
-3pw9,2011-10-26,2010-12-08
-6pwl,2020-10-21,2019-07-23
-3pwj,2011-03-09,2010-12-08
-5pw6,2017-03-29,2017-02-07
-1pwz,2003-10-07,2003-07-02
-5pw4,2017-03-29,2017-02-07
-8pw0,2024-05-08,2023-07-18
-2r04,1990-01-15,1988-10-03
-3r0q,2011-10-19,2011-03-08
-7r0s,2022-08-10,2022-02-02
-7r01,2022-09-28,2022-02-01
-1r0e,2004-10-12,2003-09-20
-3r02,2011-05-11,2011-03-07
-4r09,2015-01-14,2014-07-30
-1r0q,2004-09-28,2003-09-22
-5r0k,2020-06-03,2020-02-12
-7r0i,2022-09-14,2022-02-02
-1r0x,2003-12-09,2003-09-23
-3r01,2011-05-11,2011-03-07
-7r0m,2022-04-27,2022-02-02
-1r0c,2004-06-08,2003-09-19
-5r0a,2020-06-03,2020-02-12
-3r0x,2011-06-29,2011-03-09
-6r08,2020-04-01,2019-03-12
-5r0d,2020-06-03,2020-02-12
-3r0l,2011-10-12,2011-03-08
-7r0q,2022-04-27,2022-02-02
-6r0i,2019-04-17,2019-03-13
-4r0l,2015-07-08,2014-07-31
-4r04,2016-01-06,2014-07-29
-4r0u,2014-12-17,2014-08-01
-2r09,2007-12-04,2007-08-17
-2r0n,2008-04-22,2007-08-20
-4r0t,2015-05-06,2014-08-01
-4r0v,2015-01-28,2014-08-01
-1r0j,2004-02-10,2003-09-22
-4r00,2015-02-04,2014-07-29
-2r01,2007-09-04,2007-08-17
-6r0z,2019-08-28,2019-03-13
-4r0a,2015-01-14,2014-07-30
-7r0e,2022-12-28,2022-02-01
-8r04,2023-12-20,2023-10-30
-5r0j,2020-06-03,2020-02-12
-7r0a,2022-04-27,2022-02-01
-6r0f,2020-04-01,2019-03-12
-7r0n,2022-04-27,2022-02-02
-7r00,2022-12-07,2022-02-01
-5r0f,2020-06-03,2020-02-12
-1r0b,2004-06-08,2003-09-19
-4r0c,2015-04-29,2014-07-30
-2r0u,2007-10-30,2007-08-21
-6r00,2020-04-01,2019-03-12
-3r03,2011-05-11,2011-03-07
-5r0c,2020-06-03,2020-02-12
-6r0a,2020-04-01,2019-03-12
-6r05,2020-04-01,2019-03-12
-1r0h,2004-02-10,2003-09-22
-1r0g,2004-02-10,2003-09-22
-7r0z,2022-03-09,2022-02-02
-2r07,1990-01-15,1988-10-03
-8r08,2024-05-22,2023-10-31
-4r08,2015-01-14,2014-07-30
-6r0c,2019-09-25,2019-03-12
-7r04,2022-03-30,2022-02-01
-1r00,2003-11-25,2003-09-19
-1r0y,2003-12-09,2003-09-23
-1r0f,2004-02-10,2003-09-22
-1r0p,2003-10-07,2003-09-22
-8r02,2024-03-27,2023-10-30
-7r07,2022-09-07,2022-02-01
-2r0t,2007-12-18,2007-08-21
-6r0s,2019-08-07,2019-03-13
-3r0o,2011-03-16,2011-03-08
-2r0m,2008-04-22,2007-08-20
-8r0j,2024-03-27,2023-10-31
-5r0m,2020-06-03,2020-02-12
-5r08,2020-06-03,2020-02-12
-6r02,2019-08-07,2019-03-12
-5r0e,2020-06-03,2020-02-12
-3r0n,2011-04-27,2011-03-08
-6r07,2020-04-01,2019-03-12
-2r0w,2007-10-16,2007-08-21
-7r0f,2023-02-15,2022-02-02
-6r0y,2019-08-28,2019-03-13
-8r0i,2024-03-06,2023-10-31
-1r0r,2003-11-11,2003-09-22
-4r06,2016-01-27,2014-07-30
-5r0i,2020-06-03,2020-02-12
-1r09,1991-10-15,1990-05-04
-2r03,2007-12-18,2007-08-17
-4r0p,2014-12-17,2014-08-01
-3r0y,2012-04-04,2011-03-09
-7r0t,2022-11-02,2022-02-02
-2r0y,2007-10-30,2007-08-21
-7r02,2022-04-27,2022-02-01
-5r0h,2020-06-03,2020-02-12
-7r0u,2022-08-10,2022-02-02
-5r0l,2020-06-03,2020-02-12
-5r0b,2020-06-03,2020-02-12
-3r0d,2012-03-07,2011-03-07
-2r0g,2007-09-25,2007-08-19
-2r0h,2008-05-20,2007-08-20
-2r0z,2007-10-16,2007-08-21
-3r0w,2012-04-04,2011-03-09
-3r05,2011-06-15,2011-03-07
-7r0d,2023-11-29,2022-02-01
-6r0u,2019-08-07,2019-03-13
-6r04,2020-04-01,2019-03-12
-5r0g,2020-06-03,2020-02-12
-2r0c,2007-09-25,2007-08-18
-1r0o,2003-10-21,2003-09-22
-3r0i,2011-09-07,2011-03-08
-3r0u,2011-04-06,2011-03-09
-3r0g,2011-06-08,2011-03-08
-4r0m,2015-04-15,2014-08-01
-1r0a,2004-08-03,2003-09-19
-4r07,2015-01-14,2014-07-30
-7r0w,2022-07-06,2022-02-02
-6r0w,2019-08-28,2019-03-13
-3r0t,2011-12-07,2011-03-09
-3r09,2011-04-20,2011-03-07
-7r0b,2022-09-28,2022-02-01
-8r06,2023-11-22,2023-10-30
-5r09,2020-06-03,2020-02-12
-6r0r,2020-04-01,2019-03-13
-2r0l,2007-12-25,2007-08-20
-4r0o,2015-10-07,2014-08-01
-2r0d,2007-12-04,2007-08-18
-1r0n,2003-10-21,2003-09-22
-3r04,2011-05-11,2011-03-07
-7r09,2022-04-06,2022-02-01
-3r0h,2011-11-30,2011-03-08
-4r0w,2014-12-17,2014-08-01
-7r05,2022-11-23,2022-02-01
-6r0t,2020-04-01,2019-03-13
-1r08,1990-01-15,1988-10-03
-7r0y,2022-11-23,2022-02-02
-7r0l,2022-11-16,2022-02-02
-1r0z,2003-12-09,2003-09-23
-6r0p,2020-04-01,2019-03-13
-8r05,2023-12-20,2023-10-30
-2r00,2008-04-08,2007-08-17
-2r0p,2007-09-25,2007-08-20
-6r0g,2020-04-01,2019-03-12
-6r0q,2019-08-07,2019-03-13
-6r01,2019-07-10,2019-03-12
-7r0h,2022-09-14,2022-02-02
-7r0p,2022-10-19,2022-02-02
-3r00,2011-05-11,2011-03-07
-4r0q,2014-08-27,2014-08-01
-1r0l,2004-07-13,2003-09-22
-1r0i,2004-02-10,2003-09-22
-6r06,2020-04-01,2019-03-12
-1r03,2004-06-29,2003-09-19
-8r0v,2023-11-29,2023-11-01
-6r0h,2019-04-10,2019-03-13
-8r03,2023-12-20,2023-10-30
-6r0k,2019-10-09,2019-03-13
-3r0f,2011-08-10,2011-03-08
-2r06,1990-01-15,1988-10-03
-6r0b,2020-04-01,2019-03-12
-4r0i,2015-02-11,2014-07-31
-4r02,2014-08-13,2014-07-29
-6r09,2020-04-01,2019-03-12
-6r0v,2019-08-07,2019-03-13
-5hzn,2016-04-06,2016-02-02
-6hzf,2019-03-20,2018-10-23
-5hzu,2017-03-15,2016-02-03
-3hzb,2009-12-01,2009-06-23
-2hz4,2007-01-16,2006-08-08
-1hzl,2001-05-23,2001-01-25
-3hzl,2009-10-20,2009-06-23
-6hz4,2019-07-24,2018-10-22
-5hz6,2016-12-14,2016-02-02
-6hz8,2019-07-24,2018-10-22
-4hzo,2013-01-30,2012-11-15
-5hz3,2017-03-22,2016-02-02
-6hzl,2019-03-27,2018-10-23
-3hza,2009-11-24,2009-06-23
-6hzd,2019-02-06,2018-10-23
-6hzb,2019-02-06,2018-10-23
-6hz7,2019-07-24,2018-10-22
-3hzs,2009-07-07,2009-06-24
-8hz7,2023-12-20,2023-01-08
-6hzm,2018-11-14,2018-10-23
-1hzs,2001-07-26,2001-01-26
-2hz8,2007-07-17,2006-08-08
-6hzg,2019-03-20,2018-10-23
-3hzm,2010-01-12,2009-06-23
-2hzv,2006-08-22,2006-08-09
-3hzi,2009-07-28,2009-06-23
-3hzh,2010-02-16,2009-06-23
-4hzx,2013-11-06,2012-11-15
-4hze,2013-03-20,2012-11-15
-5hzv,2017-06-07,2016-02-03
-1hzy,2001-04-04,2001-01-26
-2hz0,2007-01-16,2006-08-08
-3hz2,2009-12-01,2009-06-23
-5hz7,2016-05-18,2016-02-02
-1hzx,2001-07-04,2001-01-26
-3hz6,2009-07-21,2009-06-23
-2hz3,2006-08-29,2006-08-08
-6hz9,2019-07-24,2018-10-22
-1hzv,2001-09-26,2001-01-26
-5hza,2016-03-02,2016-02-02
-5hzw,2017-06-07,2016-02-03
-4hzm,2013-06-19,2012-11-15
-8hz9,2023-12-20,2023-01-08
-2hza,2006-08-22,2006-08-08
-6hzw,2018-12-19,2018-10-24
-3hzc,2011-04-27,2009-06-23
-1hzu,2001-09-26,2001-01-26
-1hz1,2001-01-31,2001-01-23
-6hzv,2019-10-23,2018-10-24
-6hzy,2019-02-20,2018-10-24
-5hzj,2016-12-21,2016-02-02
-4hzw,2013-11-06,2012-11-15
-4hzf,2013-10-30,2012-11-15
-5hzi,2016-12-21,2016-02-02
-8hza,2023-12-20,2023-01-08
-3hzo,2010-06-02,2009-06-23
-4hzv,2013-11-06,2012-11-15
-5hzr,2016-07-20,2016-02-02
-4hz1,2012-12-12,2012-11-14
-4hzt,2013-03-06,2012-11-15
-5hzc,2016-11-23,2016-02-02
-5hzb,2016-03-02,2016-02-02
-5hzx,2016-02-10,2016-02-03
-4hz8,2012-12-19,2012-11-14
-1hze,2001-09-05,2001-01-24
-4hzc,2014-02-19,2012-11-15
-1hzj,2001-05-09,2001-01-25
-5hzf,2016-03-02,2016-02-02
-6hz6,2019-07-24,2018-10-22
-4hz3,2012-12-26,2012-11-14
-1hzc,2001-11-07,2001-01-24
-6hzz,2019-04-03,2018-10-24
-3hzy,2010-01-12,2009-06-24
-5hze,2017-05-03,2016-02-02
-2hzl,2007-04-03,2006-08-09
-6hz1,2018-12-19,2018-10-22
-6hze,2019-03-20,2018-10-23
-2hz2,2006-08-29,2006-08-08
-2hzc,2006-08-29,2006-08-08
-2hzh,2007-08-14,2006-08-09
-2hz5,2007-08-14,2006-08-08
-1hz5,2001-04-04,2001-01-23
-3hzg,2009-07-07,2009-06-23
-5hzq,2016-06-01,2016-02-02
-5hzz,2016-10-26,2016-02-03
-5hzt,2017-03-15,2016-02-03
-2hzn,2007-01-16,2006-08-09
-5hzm,2016-02-17,2016-02-02
-8hz6,2023-12-20,2023-01-08
-4hzd,2014-02-19,2012-11-15
-4hzp,2013-01-30,2012-11-15
-4hzy,2013-11-06,2012-11-16
-5hzh,2016-12-21,2016-02-02
-3hzw,2010-05-12,2009-06-24
-3hzt,2009-07-21,2009-06-24
-2hz1,2006-08-29,2006-08-08
-4hz0,2013-02-13,2012-11-14
-6hzn,2020-01-22,2018-10-23
-2hzy,2006-08-22,2006-08-09
-4hz2,2012-11-28,2012-11-14
-2hzi,2007-01-16,2006-08-09
-4hzh,2013-06-26,2012-11-15
-6hzc,2019-02-06,2018-10-23
-3hz5,2010-07-14,2009-06-23
-6hzx,2019-09-18,2018-10-24
-1hzh,2001-08-15,2001-01-24
-3hzx,2010-05-19,2009-06-24
-3hzn,2009-07-07,2009-06-23
-5hzg,2016-08-03,2016-02-02
-5hzl,2016-02-17,2016-02-02
-3hzv,2010-01-12,2009-06-24
-5hzd,2016-10-26,2016-02-02
-4hzz,2013-11-06,2012-11-16
-6hzu,2019-10-23,2018-10-24
-1hz8,2001-08-15,2001-01-23
-5hz9,2016-12-14,2016-02-02
-8hz2,2023-01-25,2023-01-07
-3hzd,2009-07-07,2009-06-23
-3hzk,2010-01-12,2009-06-23
-4hz7,2012-12-19,2012-11-14
-5hz5,2017-01-25,2016-02-02
-6hzp,2018-12-26,2018-10-23
-3hz3,2010-06-30,2009-06-23
-6hz0,2018-12-19,2018-10-22
-5hz1,2017-03-22,2016-02-02
-8hzr,2024-01-17,2023-01-09
-5hzs,2017-03-15,2016-02-03
-2hzq,2007-08-14,2006-08-09
-1hzz,2001-08-29,2001-01-27
-6hza,2019-02-06,2018-10-23
-2hzg,2006-08-29,2006-08-08
-1hzb,2001-11-07,2001-01-24
-6hz5,2019-07-24,2018-10-22
-8hz8,2024-03-13,2023-01-08
-2hzp,2006-11-07,2006-08-09
-5hz8,2016-12-14,2016-02-02
-8hzu,2023-12-20,2023-01-09
-5hz0,2017-04-05,2016-02-02
-3hz1,2010-07-14,2009-06-23
-4hz5,2013-02-13,2012-11-14
-5hzk,2016-12-21,2016-02-02
-3hzf,2009-07-21,2009-06-23
-6hw3,2019-01-30,2018-10-11
-3hwn,2009-09-15,2009-06-18
-5hwz,2016-05-04,2016-01-29
-5hw5,2017-06-28,2016-01-28
-3hwf,2010-06-02,2009-06-17
-1hwp,2001-01-24,2001-01-09
-2hwb,1994-11-01,1994-01-25
-6hwb,2019-01-30,2018-10-11
-5hwc,2016-09-14,2016-01-29
-3hwx,2009-11-03,2009-06-19
-8hwh,2024-01-10,2022-12-29
-8hw0,2024-01-17,2022-12-28
-4hwt,2013-09-18,2012-11-08
-5hwu,2016-10-26,2016-01-29
-8hwi,2024-01-03,2022-12-30
-5hwn,2016-03-23,2016-01-29
-2hwc,1994-11-01,1994-01-25
-8hws,2023-12-06,2023-01-02
-3hwd,2010-06-02,2009-06-17
-3hwg,2010-06-02,2009-06-17
-4hws,2013-09-18,2012-11-08
-8hwk,2024-01-03,2022-12-30
-8hw8,2024-06-05,2022-12-29
-6hwv,2019-04-17,2018-10-15
-2hwi,2006-11-07,2006-08-01
-3hw1,2009-11-03,2009-06-17
-5hwe,2017-02-01,2016-01-29
-6hwk,2019-05-01,2018-10-12
-4hwp,2013-09-18,2012-11-08
-2hw2,2007-07-31,2006-07-31
-1hwj,2001-05-11,2001-01-09
-5hw0,2016-04-06,2016-01-28
-2hw1,2007-07-10,2006-07-31
-5hws,2016-05-18,2016-01-29
-3hw3,2009-10-13,2009-06-17
-8hw6,2024-06-05,2022-12-29
-2hw5,2006-08-22,2006-07-31
-8hwa,2024-01-10,2022-12-29
-5hww,2016-03-02,2016-01-29
-3hw5,2009-10-13,2009-06-17
-5hwm,2016-03-23,2016-01-29
-8hw3,2024-01-03,2022-12-28
-3hwt,2009-08-25,2009-06-18
-2hw8,2006-12-19,2006-08-01
-2hwu,2007-08-07,2006-08-02
-8hwn,2024-01-17,2022-12-31
-6hwl,2019-05-01,2018-10-12
-5hwp,2016-05-11,2016-01-29
-6hw8,2019-01-30,2018-10-11
-6hw9,2019-01-30,2018-10-11
-2hwh,2006-11-07,2006-08-01
-6hwh,2018-11-07,2018-10-12
-5hw8,2016-09-14,2016-01-28
-3hw6,2009-10-13,2009-06-17
-3hwo,2010-02-16,2009-06-18
-8hw4,2023-06-07,2022-12-28
-2hwg,2006-11-14,2006-08-01
-1hw1,2001-01-24,2001-01-09
-4hwo,2013-09-18,2012-11-08
-8hwl,2024-01-31,2022-12-30
-6hwr,2019-04-03,2018-10-13
-1hw2,2001-01-22,2001-01-09
-6hws,2019-10-30,2018-10-13
-3hws,2009-11-24,2009-06-18
-5hwl,2017-11-08,2016-01-29
-1hwn,2001-01-24,2001-01-09
-1hwl,2001-05-11,2001-01-09
-2hw3,2006-12-12,2006-07-31
-6hwu,2019-04-17,2018-10-15
-6hw1,2018-10-24,2018-10-11
-3hw8,2009-08-25,2009-06-17
-6hwf,2019-01-30,2018-10-11
-6hwc,2019-01-30,2018-10-11
-5hw4,2016-10-19,2016-01-28
-3hw4,2009-11-10,2009-06-17
-3hw9,2009-12-08,2009-06-17
-2hwl,2006-09-19,2006-08-01
-4hww,2013-03-20,2012-11-09
-3hwe,2010-06-02,2009-06-17
-5hw1,2017-06-28,2016-01-28
-8hwd,2024-01-10,2022-12-29
-3hw7,2010-06-23,2009-06-17
-8hwp,2023-06-28,2023-01-02
-6hwe,2019-01-30,2018-10-11
-8hwy,2024-01-10,2023-01-03
-4hwv,2013-10-23,2012-11-09
-1hwy,2001-01-31,2001-01-10
-8hwe,2024-01-10,2022-12-29
-1hwo,2001-01-24,2001-01-09
-5hwy,2016-05-18,2016-01-29
-8hw1,2023-01-18,2022-12-28
-8hw7,2024-06-05,2022-12-29
-1hwm,2001-01-24,2001-01-09
-8hw2,2023-06-07,2022-12-28
-1hwi,2001-05-11,2001-01-09
-6hw7,2019-01-30,2018-10-11
-8hwr,2023-12-20,2023-01-02
-6hwm,2019-09-18,2018-10-12
-4hwk,2013-06-05,2012-11-08
-8hwb,2024-01-10,2022-12-29
-2hw7,2006-08-29,2006-08-01
-3hww,2009-11-03,2009-06-19
-5hwh,2017-02-01,2016-01-29
-6hwt,2019-04-17,2018-10-15
-4hw8,2012-11-21,2012-11-07
-6hwz,2018-12-26,2018-10-15
-2hwr,2007-08-07,2006-08-01
-1hwt,1999-11-10,1998-09-17
-5hwa,2017-02-08,2016-01-29
-8hwj,2024-01-03,2022-12-30
-5hwx,2016-05-11,2016-01-29
-1hww,2002-01-10,2001-01-10
-6hw2,2020-01-29,2018-10-11
-6hw6,2019-01-30,2018-10-11
-5hwr,2016-05-11,2016-01-29
-1hwr,1999-03-23,1998-03-20
-2hwo,2007-02-27,2006-08-01
-6hwd,2019-01-30,2018-10-11
-3hwb,2009-12-08,2009-06-17
-4hw3,2013-01-09,2012-11-07
-8hwf,2024-01-10,2022-12-29
-8hwg,2024-01-10,2022-12-29
-6hwj,2019-05-01,2018-10-12
-5hwq,2016-05-11,2016-01-29
-4hw2,2013-01-09,2012-11-07
-4hw7,2013-03-27,2012-11-07
-2hwp,2007-02-27,2006-08-01
-3hwp,2009-12-15,2009-06-18
-6hw5,2019-01-30,2018-10-11
-2hwf,1994-09-30,1994-01-25
-4hwr,2013-09-18,2012-11-08
-3hwr,2009-06-30,2009-06-18
-6hw0,2019-01-30,2018-10-11
-6hwo,2019-07-24,2018-10-12
-1hw5,2001-01-17,2001-01-09
-1hw7,2001-05-16,2001-01-09
-5hwg,2017-02-01,2016-01-29
-4hwz,2013-10-16,2012-11-09
-6hwp,2018-10-24,2018-10-12
-4hwl,2013-03-20,2012-11-08
-1hw6,2001-06-20,2001-01-09
-5hw2,2016-02-10,2016-01-28
-1hwk,2001-05-11,2001-01-09
-2hwd,1994-09-30,1994-01-25
-4hwy,2012-12-05,2012-11-09
-6hw4,2019-01-30,2018-10-11
-6hwa,2019-01-30,2018-10-11
-2hwe,1994-09-30,1994-01-25
-2hwq,2007-08-07,2006-08-01
-1hw8,2001-05-11,2001-01-09
-1hw9,2001-05-11,2001-01-09
-4hxb,2013-07-24,2012-11-09
-3hx4,2009-07-21,2009-06-19
-6hxq,2019-04-10,2018-10-17
-3hx3,2009-10-20,2009-06-19
-4hx3,2012-12-05,2012-11-09
-1hxk,2002-01-16,2001-01-16
-6hx8,2019-02-27,2018-10-16
-2hxh,2006-10-10,2006-08-03
-3hxi,2009-08-25,2009-06-20
-2hxu,2006-12-19,2006-08-03
-1hx6,2001-01-24,2001-01-11
-2hx4,2007-04-24,2006-08-02
-4hxv,2013-11-13,2012-11-12
-3hxu,2009-12-15,2009-06-22
-3hxw,2009-12-15,2009-06-22
-2hxz,2006-10-24,2006-08-04
-6hx1,2019-02-27,2018-10-15
-3hxv,2009-12-15,2009-06-22
-5hxa,2016-02-10,2016-01-29
-4hxr,2013-04-03,2012-11-12
-1hxw,1998-02-04,1997-01-24
-4hxg,2013-05-08,2012-11-09
-1hx9,2003-06-24,2001-01-12
-5hxd,2017-02-08,2016-01-30
-6hxl,2019-04-10,2018-10-17
-8hxi,2023-11-01,2023-01-04
-3hxz,2009-12-15,2009-06-22
-5hxp,2017-04-05,2016-01-31
-8hxj,2024-01-10,2023-01-04
-5hxi,2016-10-12,2016-01-30
-8hx2,2023-12-20,2023-01-03
-1hxi,2001-03-21,2001-01-15
-4hx7,2012-11-21,2012-11-09
-5hxh,2016-05-11,2016-01-30
-2hxa,2007-01-30,2006-08-03
-5hxz,2017-02-01,2016-01-31
-2hxd,2007-08-14,2006-08-03
-3hx9,2009-12-01,2009-06-19
-6hxh,2019-04-10,2018-10-17
-3hxc,2009-09-08,2009-06-20
-2hxf,2006-10-10,2006-08-03
-2hxs,2007-08-07,2006-08-03
-5hxb,2016-06-29,2016-01-30
-3hxm,2009-10-06,2009-06-21
-3hxt,2009-07-14,2009-06-22
-4hxe,2013-05-08,2012-11-09
-6hxx,2019-08-07,2018-10-18
-5hx5,2016-05-18,2016-01-29
-5hxt,2017-04-05,2016-01-31
-4hx1,2013-10-02,2012-11-09
-3hxf,2009-09-08,2009-06-20
-3hxn,2010-06-30,2009-06-21
-8hxg,2023-12-20,2023-01-04
-3hxg,2009-08-25,2009-06-20
-5hxm,2017-01-25,2016-01-31
-4hxo,2013-04-03,2012-11-12
-4hxn,2013-04-03,2012-11-12
-4hx0,2013-09-11,2012-11-09
-4hx4,2012-11-21,2012-11-09
-1hxl,2003-06-17,2001-01-16
-4hxq,2013-03-20,2012-11-12
-2hx3,2007-04-24,2006-08-02
-4hxm,2013-04-03,2012-11-12
-6hxb,2019-02-27,2018-10-16
-4hxp,2013-04-03,2012-11-12
-5hxx,2016-02-24,2016-01-31
-1hxp,1996-11-08,1995-06-09
-5hxw,2016-08-03,2016-01-31
-6hx7,2019-06-05,2018-10-16
-3hxy,2009-12-15,2009-06-22
-1hxy,2001-06-27,2001-01-17
-6hxn,2019-04-10,2018-10-17
-8hxf,2023-12-20,2023-01-04
-6hxr,2019-10-30,2018-10-18
-8hxu,2023-11-01,2023-01-05
-4hxl,2013-04-03,2012-11-12
-2hxt,2006-12-19,2006-08-03
-4hxs,2013-04-03,2012-11-12
-5hxc,2016-05-11,2016-01-30
-8hx4,2023-12-20,2023-01-03
-3hx6,2010-01-26,2009-06-19
-3hx0,2009-08-25,2009-06-19
-5hx6,2016-03-02,2016-01-29
-4hxw,2013-02-13,2012-11-12
-5hxf,2017-02-15,2016-01-30
-6hxw,2019-08-28,2018-10-18
-8hxk,2024-01-10,2023-01-04
-3hxe,2009-09-08,2009-06-20
-8hxx,2023-09-27,2023-01-05
-3hxs,2010-01-12,2009-06-22
-6hxf,2018-10-31,2018-10-17
-8hxp,2023-11-01,2023-01-05
-2hxm,2006-12-05,2006-08-03
-6hx2,2019-09-04,2018-10-15
-6hxu,2019-09-25,2018-10-18
-5hxu,2017-02-01,2016-01-31
-2hxv,2006-08-15,2006-08-04
-8hx5,2023-11-01,2023-01-04
-4hx2,2012-12-05,2012-11-09
-1hxc,2003-06-24,2001-01-12
-4hxx,2013-04-03,2012-11-12
-5hxs,2016-05-11,2016-01-31
-1hx3,2001-07-11,2001-01-11
-5hxe,2016-05-11,2016-01-30
-6hxd,2019-10-30,2018-10-17
-4hxy,2013-07-10,2012-11-12
-3hxd,2009-09-08,2009-06-20
-8hx8,2023-10-18,2023-01-04
-8hx6,2023-10-18,2023-01-04
-2hxg,2006-08-15,2006-08-03
-8hx9,2023-10-18,2023-01-04
-1hxe,1996-11-08,1995-12-07
-1hxd,2001-05-30,2001-01-12
-1hxq,1997-10-22,1996-06-16
-6hxj,2019-04-10,2018-10-17
-8hxv,2023-11-01,2023-01-05
-5hx8,2016-03-16,2016-01-29
-4hxk,2013-04-03,2012-11-12
-2hx8,2007-01-30,2006-08-03
-4hx5,2013-05-08,2012-11-09
-6hxp,2019-04-10,2018-10-17
-6hxs,2019-10-30,2018-10-18
-8hxe,2023-11-01,2023-01-04
-6hxm,2019-04-10,2018-10-17
-2hx1,2006-09-05,2006-08-02
-6hxi,2019-04-10,2018-10-17
-1hxn,1995-10-15,1995-06-01
-3hxx,2009-12-15,2009-06-22
-2hx0,2006-09-19,2006-08-02
-5hxr,2016-05-11,2016-01-31
-2hx7,2007-01-30,2006-08-03
-2hxc,2006-09-26,2006-08-03
-8hxy,2023-09-27,2023-01-05
-2hx2,2007-04-24,2006-08-02
-4hxj,2012-11-28,2012-11-11
-5hx1,2016-10-26,2016-01-29
-8hxn,2023-11-01,2023-01-05
-1hxz,2003-06-17,2001-01-17
-2hxl,2007-06-19,2006-08-03
-4hxz,2013-02-13,2012-11-12
-5hxq,2017-04-05,2016-01-31
-1hxa,2003-06-24,2001-01-12
-1hxb,1997-03-12,1996-09-13
-2hx9,2007-01-30,2006-08-03
-8hxh,2023-12-20,2023-01-04
-1hxr,2001-02-14,2001-01-16
-8hx7,2023-10-18,2023-01-04
-2hxq,2007-06-19,2006-08-03
-1hxg,2003-06-24,2001-01-12
-8hxo,2023-11-01,2023-01-05
-1hx0,2001-08-08,2001-01-11
-6hx5,2018-12-26,2018-10-16
-8hxw,2023-11-01,2023-01-05
-4hxd,2013-02-13,2012-11-09
-3hxb,2009-09-08,2009-06-20
-4hxf,2013-05-08,2012-11-09
-7b6g,2021-01-13,2020-12-07
-5b6b,2016-07-06,2016-05-26
-8b6i,2023-07-12,2022-09-27
-3b6z,2008-09-16,2007-10-29
-6b6g,2018-02-14,2017-10-02
-8b6k,2023-10-25,2022-09-27
-8b6e,2023-07-12,2022-09-27
-8b61,2023-05-31,2022-09-25
-7b60,2020-12-23,2020-12-07
-1b66,1999-04-27,1999-01-20
-3b6l,2008-07-01,2007-10-29
-7b6a,2022-06-22,2020-12-07
-3b65,2008-09-09,2007-10-27
-3b6h,2007-11-20,2007-10-29
-7b63,2021-03-24,2020-12-07
-2b6a,2005-11-01,2005-09-30
-7b6c,2022-06-22,2020-12-07
-7b6b,2021-03-10,2020-12-07
-4b64,2012-10-03,2012-08-09
-5b6v,2016-12-21,2016-06-02
-3b68,2008-09-09,2007-10-27
-8b6d,2024-01-17,2022-09-27
-8b6q,2023-10-11,2022-09-27
-1b6a,2000-01-13,1999-01-13
-8b69,2023-08-23,2022-09-26
-6b68,2018-06-27,2017-10-01
-7b6s,2022-09-21,2020-12-08
-6b6d,2018-06-27,2017-10-01
-6b6c,2018-06-27,2017-10-01
-4b68,2012-10-03,2012-08-09
-3b6w,2008-02-05,2007-10-29
-4b6e,2012-10-03,2012-08-09
-5b6x,2016-12-21,2016-06-02
-8b62,2023-10-04,2022-09-25
-6b6r,2017-11-01,2017-10-03
-3b6n,2007-11-20,2007-10-29
-3b6o,2008-09-23,2007-10-29
-5b6t,2016-09-07,2016-06-01
-8b6c,2023-02-22,2022-09-26
-4b6q,2012-12-19,2012-08-14
-5b60,2016-12-07,2016-05-24
-8b6v,2023-05-31,2022-09-27
-7b6u,2022-09-21,2020-12-08
-7b66,2021-03-24,2020-12-07
-8b6t,2023-07-26,2022-09-27
-5b62,2017-01-11,2016-05-24
-3b6p,2008-09-23,2007-10-29
-4b6u,2013-03-06,2012-08-15
-5b6g,2017-05-31,2016-05-27
-3b6t,2008-02-05,2007-10-29
-2b60,2006-11-14,2005-09-29
-1b6p,2000-01-07,1999-01-17
-4b6l,2013-08-21,2012-08-14
-8b6f,2023-03-29,2022-09-27
-4b60,2013-10-09,2012-08-08
-4b66,2012-10-03,2012-08-09
-3b6f,2007-12-25,2007-10-29
-7b65,2021-03-24,2020-12-07
-3b69,2008-05-13,2007-10-28
-1b6k,2000-01-07,1999-01-17
-2b6h,2005-10-11,2005-10-01
-6b67,2018-04-11,2017-10-01
-8b6r,2023-07-26,2022-09-27
-3b6e,2007-11-13,2007-10-29
-5b6h,2017-05-31,2016-05-27
-2b67,2005-11-15,2005-09-30
-5b6a,2016-08-10,2016-05-25
-1b6s,1999-11-30,1999-01-18
-7b6k,2020-12-23,2020-12-07
-8b67,2023-10-25,2022-09-26
-5b6e,2017-01-25,2016-05-26
-6b69,2018-06-27,2017-10-01
-6b6o,2018-02-21,2017-10-03
-6b6x,2018-10-03,2017-10-03
-8b68,2024-01-10,2022-09-26
-7b6f,2020-12-16,2020-12-07
-8b6s,2023-07-26,2022-09-27
-8b66,2023-10-11,2022-09-26
-1b63,1999-06-08,1999-01-20
-6b6e,2018-06-27,2017-10-01
-6b64,2018-10-03,2017-10-01
-6b6t,2018-03-14,2017-10-03
-7b6n,2020-12-23,2020-12-07
-1b6m,2000-01-07,1999-01-17
-3b6i,2007-12-11,2007-10-29
-4b6z,2013-03-27,2012-08-16
-5b6w,2016-12-21,2016-06-02
-2b65,2005-11-15,2005-09-30
-3b6c,2008-02-05,2007-10-28
-6b6p,2017-11-01,2017-10-03
-4b67,2012-10-03,2012-08-09
-3b6m,2007-12-11,2007-10-29
-6b6q,2017-11-01,2017-10-03
-7b6i,2020-12-23,2020-12-07
-1b6h,1998-11-18,1998-11-13
-2b6n,2006-03-07,2005-10-03
-3b6u,2007-11-13,2007-10-29
-7b6j,2020-12-23,2020-12-07
-8b6m,2023-10-11,2022-09-27
-1b6l,2000-01-07,1999-01-17
-3b6a,2008-02-05,2007-10-28
-5b66,2017-02-01,2016-05-25
-5b6i,2016-10-26,2016-05-29
-3b6q,2008-02-05,2007-10-29
-6b60,2018-10-03,2017-10-01
-1b6z,2000-01-21,1999-01-18
-4b6r,2012-12-19,2012-08-14
-6b6k,2018-10-10,2017-10-02
-7b64,2021-03-24,2020-12-07
-7b6m,2020-12-23,2020-12-07
-2b63,2005-12-06,2005-09-30
-4b69,2012-10-03,2012-08-09
-6b6f,2018-06-27,2017-10-01
-6b62,2018-10-03,2017-10-01
-4b6d,2012-12-12,2012-08-09
-5b6q,2016-10-19,2016-06-01
-8b6h,2023-03-29,2022-09-27
-4b6f,2012-10-03,2012-08-09
-6b6w,2018-10-03,2017-10-03
-6b6h,2017-11-15,2017-10-02
-6b6n,2017-11-01,2017-10-03
-6b6u,2017-12-20,2017-10-03
-4b6s,2012-12-19,2012-08-14
-6b65,2018-10-03,2017-10-01
-5b6z,2016-12-21,2016-06-02
-7b67,2021-03-24,2020-12-07
-7b62,2021-04-28,2020-12-07
-5b6l,2016-09-21,2016-05-30
-3b6d,2007-12-18,2007-10-29
-7b6v,2022-09-21,2020-12-08
-3b6g,2007-12-25,2007-10-29
-3b6r,2008-11-04,2007-10-29
-8b6j,2023-03-29,2022-09-27
-5b6d,2017-01-25,2016-05-26
-8b6g,2023-03-29,2022-09-27
-3b67,2008-09-09,2007-10-27
-4b6p,2012-12-19,2012-08-14
-3b6v,2007-11-13,2007-10-29
-3b6k,2007-12-11,2007-10-29
-3b66,2008-09-09,2007-10-27
-6b61,2018-10-03,2017-10-01
-4b63,2012-10-03,2012-08-09
-4b6c,2013-01-23,2012-08-09
-8b64,2023-02-01,2022-09-26
-8b6w,2023-05-31,2022-09-27
-7b6q,2020-12-23,2020-12-08
-7b6l,2020-12-23,2020-12-07
-7b6w,2022-01-12,2020-12-08
-4b6o,2012-12-19,2012-08-14
-6b6s,2017-11-01,2017-10-03
-8b6u,2023-05-31,2022-09-27
-3b6s,2008-07-22,2007-10-29
-1b6t,2000-04-19,1999-01-18
-6b6a,2018-06-27,2017-10-01
-7b6t,2022-09-21,2020-12-08
-6b6z,2018-12-19,2017-10-03
-5b6s,2016-09-07,2016-06-01
-7b68,2020-12-23,2020-12-07
-7b61,2021-01-13,2020-12-07
-2b6f,2006-09-19,2005-10-01
-3b6b,2008-11-04,2007-10-28
-3b6x,2008-02-05,2007-10-29
-3b6j,2007-12-11,2007-10-29
-6b63,2018-10-03,2017-10-01
-5b6y,2016-12-21,2016-06-02
-4b61,2013-07-17,2012-08-08
-8b6z,2022-12-07,2022-09-27
-1b6j,2000-01-07,1999-01-17
-4b65,2012-10-03,2012-08-09
-7b6p,2020-12-23,2020-12-08
-2b69,2005-10-18,2005-09-30
-6b66,2018-10-03,2017-10-01
-8b63,2023-10-04,2022-09-25
-1b62,1999-04-28,1999-01-11
-3b60,2007-12-04,2007-10-26
-6z59,2020-06-03,2020-05-26
-6z5f,2020-12-09,2020-05-26
-7z5s,2022-06-08,2022-03-10
-4z50,2015-10-14,2015-04-02
-5z5f,2018-04-25,2018-01-18
-6z5v,2020-12-09,2020-05-27
-5z58,2018-09-19,2018-01-17
-6z51,2020-06-03,2020-05-26
-7z5a,2022-10-19,2022-03-08
-5z5p,2018-11-07,2018-01-19
-2z58,2008-01-01,2007-06-29
-2z5q,2008-07-29,2007-07-16
-2z50,2008-07-01,2007-06-26
-4z54,2016-04-06,2015-04-02
-7z57,2022-10-12,2022-03-08
-2z5u,2008-04-01,2007-07-17
-5z5k,2018-06-20,2018-01-18
-2z5x,2008-04-01,2007-07-20
-5z5y,2018-05-30,2018-01-22
-7z5z,2022-10-26,2022-03-10
-1z50,2005-05-24,2005-03-16
-1z5r,2005-07-12,2005-03-18
-7z5r,2023-03-22,2022-03-09
-5z53,2018-12-19,2018-01-16
-1z5o,2005-10-04,2005-03-18
-6z5k,2020-09-16,2020-05-26
-2z54,2008-07-01,2007-06-28
-1z5c,2005-06-14,2005-03-17
-7z5b,2023-03-22,2022-03-08
-2z5p,2008-07-29,2007-07-16
-4z5z,2016-04-13,2015-04-03
-1z5w,2005-05-31,2005-03-20
-2z56,2008-01-01,2007-06-29
-2z57,2008-01-01,2007-06-29
-2z5z,2007-08-14,2007-07-20
-7z5y,2022-10-26,2022-03-10
-7z58,2023-03-22,2022-03-08
-7z5n,2023-03-22,2022-03-09
-2z51,2008-07-15,2007-06-26
-7z51,2022-04-20,2022-03-07
-5z5c,2018-02-14,2018-01-17
-7z5x,2022-08-17,2022-03-10
-2z5d,2007-10-09,2007-07-06
-7z5m,2022-06-22,2022-03-09
-1z59,2005-06-14,2005-03-17
-2z5f,2007-08-14,2007-07-07
-6z5y,2021-08-11,2020-05-27
-5z5u,2019-01-23,2018-01-20
-1z5v,2005-05-31,2005-03-20
-2z55,2008-01-01,2007-06-28
-5z5v,2019-01-23,2018-01-20
-7z5o,2022-07-13,2022-03-09
-4z5x,2015-05-13,2015-04-03
-6z5r,2021-01-13,2020-05-27
-4z55,2016-02-03,2015-04-02
-6z58,2020-06-03,2020-05-26
-6z53,2020-06-03,2020-05-26
-5z5d,2018-04-25,2018-01-17
-7z54,2022-06-22,2022-03-07
-2z5r,2008-07-29,2007-07-16
-7z53,2022-10-26,2022-03-07
-4z53,2016-09-14,2015-04-02
-5z54,2018-12-19,2018-01-17
-2z5y,2008-04-01,2007-07-20
-1z53,2005-06-21,2005-03-17
-7z5p,2022-05-11,2022-03-09
-6z5d,2020-06-03,2020-05-26
-7z5j,2022-07-13,2022-03-09
-1z5x,2005-04-05,2005-03-21
-5z5o,2018-09-26,2018-01-19
-4z5p,2015-07-29,2015-04-02
-6z5t,2020-12-02,2020-05-27
-4z5q,2015-08-12,2015-04-02
-5z5i,2018-04-25,2018-01-18
-6z57,2020-06-03,2020-05-26
-7z59,2022-06-29,2022-03-08
-1z5u,2006-03-21,2005-03-20
-2z52,2008-07-01,2007-06-26
-1z57,2005-04-12,2005-03-17
-6z5b,2020-06-03,2020-05-26
-6z5s,2021-01-13,2020-05-27
-6z5a,2020-06-03,2020-05-26
-1z5b,2005-06-14,2005-03-17
-7z5h,2022-05-11,2022-03-09
-5z5s,2018-10-17,2018-01-19
-4z5y,2016-04-13,2015-04-03
-1z55,2005-07-05,2005-03-17
-6z5h,2020-06-24,2020-05-26
-7z55,2022-11-23,2022-03-08
-5z5n,2018-11-07,2018-01-18
-6z54,2020-06-03,2020-05-26
-5z5t,2019-01-23,2018-01-20
-7z52,2022-06-22,2022-03-07
-1z5m,2005-04-19,2005-03-18
-1z5g,2006-03-21,2005-03-18
-5z5l,2019-04-10,2018-01-18
-1z5n,2005-10-04,2005-03-18
-6z5o,2020-12-09,2020-05-27
-4z5w,2016-03-02,2015-04-03
-1z5a,2005-06-14,2005-03-17
-1z5l,2005-07-19,2005-03-18
-6z52,2020-06-03,2020-05-26
-7z5w,2022-08-17,2022-03-10
-6z55,2020-06-03,2020-05-26
-5z56,2018-09-19,2018-01-17
-6z5u,2021-05-05,2020-05-27
-4z51,2016-04-06,2015-04-02
-6z5e,2020-06-03,2020-05-26
-6z56,2020-06-03,2020-05-26
-2z5g,2007-10-30,2007-07-08
-5z57,2018-09-19,2018-01-17
-6z50,2020-06-03,2020-05-26
-2z5i,2008-04-22,2007-07-12
-7z5u,2022-11-09,2022-03-10
-7z50,2022-07-20,2022-03-06
-6z5c,2020-06-03,2020-05-26
-1z5h,2005-06-28,2005-03-18
-5z5h,2018-04-25,2018-01-18
-6tsk,2020-01-08,2019-12-20
-5ts8,2018-01-17,2016-10-28
-6ts1,2020-02-19,2019-12-19
-5tsp,2017-03-29,2016-10-31
-5tsb,2017-09-20,2016-10-28
-1tsv,1996-03-08,1995-12-05
-3tsn,2011-10-12,2011-09-13
-6ts0,2020-02-19,2019-12-19
-6ts2,2020-01-08,2019-12-19
-1ts0,2005-07-05,2004-06-21
-4tsk,2014-07-09,2014-06-18
-4tsn,2015-03-04,2014-06-19
-6tsn,2020-07-29,2019-12-20
-4tsl,2015-03-04,2014-06-19
-4tsq,2015-03-04,2014-06-19
-1tsu,2005-03-29,2004-06-21
-3tsk,2012-06-20,2011-09-13
-1tsr,1996-01-29,1995-07-28
-2tsa,1996-11-08,1996-05-10
-4tsr,2015-05-06,2014-06-19
-3tsq,2011-12-28,2011-09-13
-3tsu,2011-12-28,2011-09-13
-1tsl,1998-06-17,1997-06-12
-7tsp,2022-07-13,2022-01-31
-6tsl,2020-07-29,2019-12-20
-1tsn,1997-07-07,1996-12-02
-8tsc,2023-11-22,2023-08-11
-6tsj,2020-02-19,2019-12-20
-4tsh,2014-10-22,2014-06-18
-7tse,2022-07-13,2022-01-31
-6tsz,2020-01-01,2019-12-22
-1ts8,2005-07-05,2004-06-21
-5ts2,2016-11-09,2016-10-27
-7ts3,2022-07-13,2022-01-31
-3tso,2012-09-19,2011-09-13
-6ts5,2020-07-08,2019-12-20
-7tsj,2022-05-04,2022-01-31
-3tsp,2011-12-28,2011-09-13
-5ts3,2016-11-09,2016-10-27
-3ts0,2011-11-16,2011-09-11
-6tss,2020-02-19,2019-12-21
-3ts6,2011-10-12,2011-09-12
-7tsl,2022-07-13,2022-01-31
-6tsg,2020-07-22,2019-12-20
-7tsm,2022-07-13,2022-01-31
-8ts9,2023-11-22,2023-08-11
-2tsc,1991-10-15,1991-07-03
-5tsq,2016-12-14,2016-10-31
-7tsf,2022-07-13,2022-01-31
-8tsd,2023-11-22,2023-08-11
-5tsu,2017-10-11,2016-10-31
-7ts5,2022-07-13,2022-01-31
-6tsm,2020-07-29,2019-12-20
-7tsb,2022-07-13,2022-01-31
-5tsd,2016-11-16,2016-10-28
-5ts5,2017-04-26,2016-10-27
-4tss,1997-12-24,1996-12-11
-7tsa,2022-07-13,2022-01-31
-4ts7,2014-07-30,2014-06-18
-7tsg,2022-07-13,2022-01-31
-6tse,2020-11-25,2019-12-20
-7tsd,2022-07-13,2022-01-31
-4ts3,2015-07-08,2014-06-18
-4ts1,1989-10-15,1989-06-29
-5tsf,2017-10-25,2016-10-28
-4tsp,2015-03-04,2014-06-19
-1tsy,1996-03-08,1995-12-05
-6tsh,2020-01-08,2019-12-20
-3tsj,2012-09-19,2011-09-13
-7tsq,2023-01-11,2022-01-31
-1tsi,1994-01-31,1992-11-19
-4tsm,2015-01-14,2014-06-19
-6tsp,2020-08-05,2019-12-21
-3tsl,2011-10-12,2011-09-13
-8ts4,2024-05-08,2023-08-10
-6tsq,2020-07-29,2019-12-21
-5ts0,2017-01-11,2016-10-27
-7tsc,2022-07-13,2022-01-31
-1ts6,2005-07-05,2004-06-21
-1ts7,2005-07-05,2004-06-21
-6tsy,2020-01-15,2019-12-21
-1tsd,1996-01-29,1995-08-15
-8tsa,2023-11-22,2023-08-11
-4tsz,2014-09-10,2014-06-19
-2tsy,1997-04-01,1997-01-03
-7ts4,2022-07-13,2022-01-31
-4tsx,2014-12-17,2014-06-19
-2tsr,1999-02-16,1998-06-19
-7tsn,2022-07-13,2022-01-31
-5tsv,2017-11-08,2016-10-31
-5tso,2017-05-03,2016-10-30
-7ts9,2022-07-13,2022-01-31
-5tsg,2017-05-17,2016-10-28
-5tsn,2017-04-12,2016-10-30
-7ts6,2022-07-13,2022-01-31
-6tsi,2020-11-18,2019-12-20
-5tsz,2016-12-28,2016-10-31
-7ts1,2022-07-13,2022-01-31
-7tsw,2023-02-08,2022-01-31
-6tsr,2020-07-29,2019-12-21
-6tsf,2020-02-19,2019-12-20
-3tsh,2012-09-19,2011-09-13
-5tsa,2017-09-20,2016-10-28
-7tsi,2022-07-13,2022-01-31
-5tsh,2017-05-17,2016-10-28
-6tsx,2020-02-19,2019-12-21
-3ts4,2012-06-20,2011-09-12
-7tsk,2022-07-13,2022-01-31
-6ts7,2020-07-08,2019-12-20
-4tsd,2015-06-10,2014-06-18
-3ts8,2011-11-23,2011-09-12
-8tsi,2024-04-17,2023-08-11
-6tsd,2021-07-07,2019-12-20
-3ts5,2011-11-23,2011-09-12
-4ts8,2015-07-01,2014-06-18
-8ts5,2023-11-22,2023-08-10
-3tsa,2012-02-15,2011-09-12
-7tsh,2022-07-13,2022-01-31
-8tsb,2023-11-22,2023-08-11
-7ts2,2022-07-13,2022-01-31
-5ts1,2018-05-09,2016-10-27
-6tso,2020-07-29,2019-12-20
-8tsh,2024-04-17,2023-08-11
-4ts9,2015-07-08,2014-06-18
-1tsm,1998-06-17,1997-06-12
-7ts7,2022-07-13,2022-01-31
-6tsc,2020-06-24,2019-12-20
-3ts2,2011-11-16,2011-09-11
-2tsb,1996-11-08,1996-05-10
-7ts8,2022-07-13,2022-01-31
-7tsx,2023-01-11,2022-01-31
-4tsf,2014-08-06,2014-06-18
-1tsx,1996-03-08,1995-12-05
-7tso,2022-07-13,2022-01-31
-5tsx,2017-11-08,2016-10-31
-3ts1,1989-10-15,1989-06-29
-4tsy,2015-03-04,2014-06-19
-6tsa,2020-02-19,2019-12-20
-4ts5,2014-07-30,2014-06-18
-3tsc,2011-10-05,2011-09-12
-4tso,2015-03-04,2014-06-19
-6ts6,2020-07-08,2019-12-20
-6ts4,2020-07-08,2019-12-19
-3tsd,2011-10-05,2011-09-13
-1p7m,2003-11-25,2003-05-02
-1p7z,2003-09-09,2003-05-06
-6p7o,2019-12-25,2019-06-06
-7p7t,2022-02-23,2021-07-20
-8p78,2024-03-20,2023-05-30
-1p7r,2003-10-28,2003-05-05
-1p72,2003-11-04,2003-04-30
-7p7n,2022-06-01,2021-07-20
-6p7h,2020-06-10,2019-06-05
-2p7z,2008-02-26,2007-03-21
-7p7m,2022-09-21,2021-07-19
-4p7a,2014-04-09,2014-03-26
-6p73,2020-04-01,2019-06-04
-3p7p,2010-12-08,2010-10-12
-7p7h,2022-04-13,2021-07-19
-3p70,2011-09-28,2010-10-11
-7p7u,2022-02-23,2021-07-20
-3p7h,2010-11-03,2010-10-12
-2p75,2007-09-25,2007-03-20
-7p79,2021-08-04,2021-07-19
-3p7t,2010-12-08,2010-10-12
-6p7s,2019-09-25,2019-06-06
-7p7g,2022-04-13,2021-07-19
-3p7g,2010-11-03,2010-10-12
-8p74,2024-03-20,2023-05-30
-1p7p,2004-02-17,2003-05-05
-2p79,2007-09-25,2007-03-20
-8p7n,2023-10-25,2023-05-30
-8p71,2024-03-20,2023-05-30
-8p7s,2023-10-25,2023-05-31
-3p7c,2011-10-12,2010-10-12
-7p74,2022-07-27,2021-07-19
-6p7k,2020-04-08,2019-06-05
-4p76,2015-04-29,2014-03-26
-3p7i,2011-10-12,2010-10-12
-8p7v,2023-10-25,2023-05-31
-4p73,2014-06-25,2014-03-25
-2p7s,2007-05-29,2007-03-20
-4p7x,2014-09-17,2014-03-28
-6p7m,2019-08-21,2019-06-06
-8p7l,2024-03-20,2023-05-30
-2p7u,2008-03-25,2007-03-20
-3p7z,2010-12-08,2010-10-13
-8p72,2024-03-20,2023-05-30
-8p7i,2023-10-25,2023-05-30
-2p7a,2008-02-26,2007-03-20
-8p7t,2023-10-25,2023-05-31
-7p7k,2022-09-21,2021-07-19
-6p78,2019-09-18,2019-06-05
-7p7r,2022-03-23,2021-07-20
-1p7c,2003-11-04,2003-05-01
-4p7i,2014-04-09,2014-03-27
-7p7e,2022-09-21,2021-07-19
-1p75,2003-11-04,2003-04-30
-7p7c,2022-09-21,2021-07-19
-4p75,2014-06-25,2014-03-25
-7p71,2022-07-27,2021-07-19
-3p7w,2010-12-08,2010-10-12
-8p7j,2023-07-05,2023-05-30
-6p7n,2019-08-21,2019-06-06
-4p7n,2014-07-02,2014-03-27
-8p7f,2023-11-01,2023-05-30
-4p7e,2014-11-19,2014-03-27
-8p7m,2023-10-25,2023-05-30
-1p7a,2003-12-30,2003-04-30
-3p76,2011-02-09,2010-10-12
-3p7v,2010-12-08,2010-10-12
-3p72,2010-11-24,2010-10-12
-2p77,2007-09-25,2007-03-20
-2p72,2007-08-21,2007-03-19
-4p74,2014-06-25,2014-03-25
-4p7s,2014-10-15,2014-03-27
-8p7k,2023-06-07,2023-05-30
-6p74,2020-01-29,2019-06-04
-2p7o,2007-07-17,2007-03-20
-4p70,2014-08-13,2014-03-25
-2p7j,2007-05-01,2007-03-20
-8p73,2024-03-20,2023-05-30
-3p74,2011-03-23,2010-10-12
-7p77,2021-08-04,2021-07-19
-3p7y,2011-03-02,2010-10-13
-4p7w,2014-09-17,2014-03-28
-6p7p,2019-12-25,2019-06-06
-8p7h,2023-10-25,2023-05-30
-2p73,2007-08-21,2007-03-19
-7p78,2021-08-04,2021-07-19
-3p7l,2011-07-20,2010-10-12
-3p7f,2010-11-03,2010-10-12
-3p7u,2010-12-08,2010-10-12
-2p7g,2008-02-26,2007-03-20
-7p7j,2022-09-21,2021-07-19
-6p7a,2020-04-29,2019-06-05
-7p7l,2022-09-21,2021-07-19
-4p7j,2014-06-18,2014-03-27
-8p75,2024-03-20,2023-05-30
-4p7m,2014-10-15,2014-03-27
-4p7q,2014-07-02,2014-03-27
-8p7q,2023-10-25,2023-05-30
-3p7n,2011-05-25,2010-10-12
-2p7v,2007-08-21,2007-03-20
-7p7w,2022-08-03,2021-07-20
-2p70,2007-04-10,2007-03-19
-7p7y,2021-07-28,2021-07-21
-1p7v,2004-05-18,2003-05-06
-4p7r,2014-07-02,2014-03-27
-4p7g,2014-06-18,2014-03-27
-6p7e,2020-03-04,2019-06-05
-7p72,2022-07-27,2021-07-19
-1p7q,2003-10-14,2003-05-05
-7p7o,2022-06-01,2021-07-20
-6p72,2019-09-25,2019-06-04
-7p7f,2022-04-13,2021-07-19
-2p74,2007-04-24,2007-03-19
-4p7k,2014-06-18,2014-03-27
-1p7l,2004-03-02,2003-05-02
-3p79,2011-10-12,2010-10-12
-1p7t,2003-09-09,2003-05-05
-2p7h,2007-04-03,2007-03-20
-6p7q,2019-12-25,2019-06-06
-2p7t,2007-10-09,2007-03-20
-2p78,2007-09-25,2007-03-20
-8p7r,2023-10-25,2023-05-30
-7p7p,2022-01-26,2021-07-20
-2p7p,2007-07-17,2007-03-20
-1p77,2003-08-12,2003-04-30
-8p7u,2023-10-25,2023-05-31
-1p7y,2003-09-09,2003-05-06
-3p78,2011-10-12,2010-10-12
-1p7w,2004-05-18,2003-05-06
-6p7z,2020-01-15,2019-06-06
-2p76,2007-04-03,2007-03-20
-6p7d,2020-02-26,2019-06-05
-4p72,2014-06-25,2014-03-25
-7p7q,2022-02-23,2021-07-20
-4p7f,2014-06-11,2014-03-27
-7p7s,2022-02-23,2021-07-20
-1p7b,2003-06-17,2003-05-01
-6p7i,2019-06-26,2019-06-05
-6p7u,2020-06-10,2019-06-06
-7p73,2022-07-27,2021-07-19
-6p7g,2020-09-23,2019-06-05
-7p70,2022-07-27,2021-07-19
-8p70,2024-03-20,2023-05-30
-3p7r,2010-12-08,2010-10-12
-6p7c,2020-02-26,2019-06-05
-3p75,2010-11-17,2010-10-12
-6p71,2019-07-24,2019-06-04
-3p7a,2011-10-12,2010-10-12
-6p70,2019-06-19,2019-06-04
-6p7y,2019-09-25,2019-06-06
-7p76,2021-10-27,2021-07-19
-3p7q,2010-12-08,2010-10-12
-3p7b,2011-10-12,2010-10-12
-4p77,2015-03-25,2014-03-26
-8p76,2024-03-20,2023-05-30
-2p7i,2007-04-03,2007-03-20
-8p77,2024-03-20,2023-05-30
-7p7x,2021-07-28,2021-07-20
-3p7s,2010-12-08,2010-10-12
-2p7q,2007-07-17,2007-03-20
-7p7i,2022-07-27,2021-07-19
-7p7a,2021-08-04,2021-07-19
-3p71,2011-02-16,2010-10-11
-3djp,2009-06-30,2008-06-24
-2djf,2006-11-14,2006-04-02
-2djb,2007-03-13,2006-03-31
-4djt,2012-02-15,2012-02-02
-3djy,2008-12-02,2008-06-24
-2djw,2006-09-12,2006-04-05
-5dj8,2016-03-30,2015-09-01
-1djh,1997-07-07,1996-09-25
-7djs,2021-09-15,2020-11-21
-4djo,2012-08-01,2012-02-02
-1dje,2000-12-04,1999-12-02
-5djc,2016-03-30,2015-09-01
-7djo,2021-11-24,2020-11-20
-4dj7,2012-06-20,2012-02-01
-5djt,2016-07-20,2015-09-02
-7djc,2021-04-07,2020-11-20
-5dja,2016-03-30,2015-09-01
-3dj7,2009-05-05,2008-06-22
-3dj6,2009-05-05,2008-06-22
-7djz,2021-06-09,2020-11-22
-7djm,2022-06-08,2020-11-20
-8djb,2023-07-05,2022-06-30
-1djr,2000-06-30,1999-12-03
-6dj1,2018-10-17,2018-05-24
-5djh,2015-11-11,2015-09-02
-1dj5,1999-12-10,1999-12-01
-3dje,2008-07-22,2008-06-23
-2djr,2006-10-05,2006-04-05
-4djp,2012-08-01,2012-02-02
-1djw,1997-07-23,1996-08-24
-4djx,2012-03-21,2012-02-02
-7djt,2021-05-19,2020-11-21
-8djv,2022-12-21,2022-07-01
-3dj8,2008-07-08,2008-06-22
-1djp,2000-01-24,1999-12-03
-8dj2,2023-08-02,2022-06-29
-2djx,2007-06-26,2006-04-05
-8dju,2023-01-18,2022-07-01
-6djf,2019-05-29,2018-05-25
-2dji,2007-05-29,2006-04-03
-7djk,2022-06-08,2020-11-20
-8dj3,2023-07-05,2022-06-29
-6djk,2019-05-29,2018-05-25
-6djq,2018-08-22,2018-05-25
-2djz,2006-10-06,2006-04-06
-2djl,2007-06-26,2006-04-04
-1dj1,1999-12-10,1999-11-30
-3djv,2009-06-30,2008-06-24
-5dj5,2015-10-28,2015-09-01
-5djs,2015-10-28,2015-09-02
-6djg,2019-05-29,2018-05-25
-4dja,2013-04-17,2012-02-01
-1dj3,2000-03-24,1999-12-01
-4djv,2012-03-21,2012-02-02
-6dj2,2018-10-17,2018-05-24
-4djr,2012-08-01,2012-02-02
-1djz,1997-07-07,1996-08-24
-8dj7,2023-05-10,2022-06-30
-3djl,2008-09-23,2008-06-23
-1djo,2000-01-24,1999-12-03
-4djc,2012-02-22,2012-02-01
-2dja,2006-10-01,2006-03-31
-5dj4,2015-11-25,2015-09-01
-5djr,2015-09-30,2015-09-02
-2djg,2006-11-14,2006-04-02
-6djj,2019-05-29,2018-05-25
-5dj9,2016-10-05,2015-09-01
-3djo,2009-06-30,2008-06-24
-3dji,2008-12-23,2008-06-23
-3djx,2009-06-30,2008-06-24
-6dje,2019-05-29,2018-05-25
-3djq,2009-06-30,2008-06-24
-5djy,2016-03-30,2015-09-02
-6djz,2018-10-17,2018-05-28
-8djs,2023-01-18,2022-07-01
-6djw,2018-07-04,2018-05-26
-5dj1,2015-11-25,2015-09-01
-6dja,2019-05-29,2018-05-24
-1dji,1997-07-07,1996-09-25
-5djz,2016-03-30,2015-09-02
-1djq,1999-12-22,1999-12-03
-3djk,2008-09-30,2008-06-23
-5dji,2015-11-11,2015-09-02
-8dj9,2022-11-09,2022-06-30
-5dj6,2016-03-30,2015-09-01
-8djf,2023-01-11,2022-06-30
-1djg,1997-07-07,1996-09-25
-6djc,2018-07-25,2018-05-25
-1djl,2000-12-06,1999-12-03
-5djd,2016-03-30,2015-09-02
-2djh,2007-01-23,2006-04-03
-8djx,2023-01-18,2022-07-01
-1dj2,2000-03-24,1999-12-01
-5djl,2016-11-02,2015-09-02
-7dj2,2021-04-07,2020-11-19
-4dje,2012-03-14,2012-02-01
-5dj0,2016-03-30,2015-09-01
-5djf,2015-11-11,2015-09-02
-3dj5,2009-05-05,2008-06-22
-8djh,2022-08-10,2022-06-30
-6djn,2019-02-27,2018-05-25
-5djq,2016-01-13,2015-09-02
-8djr,2023-01-18,2022-07-01
-4dj6,2012-06-20,2012-02-01
-5dju,2016-07-20,2015-09-02
-1dju,2001-04-11,1999-12-06
-4djy,2012-03-21,2012-02-02
-6dj5,2018-10-17,2018-05-24
-8djy,2022-12-21,2022-07-01
-3djj,2008-08-05,2008-06-23
-4djf,2012-03-14,2012-02-01
-2dj8,2006-10-01,2006-03-31
-2dj7,2006-10-01,2006-03-31
-8djm,2022-08-03,2022-07-01
-7dj1,2021-04-07,2020-11-19
-7djq,2020-12-09,2020-11-20
-5djx,2016-03-30,2015-09-02
-6dji,2019-05-29,2018-05-25
-6djm,2019-02-27,2018-05-25
-8djd,2023-03-22,2022-06-30
-3dj4,2009-05-19,2008-06-22
-5djv,2015-10-07,2015-09-02
-6dju,2018-09-26,2018-05-26
-6djp,2018-07-25,2018-05-25
-4dj8,2012-06-20,2012-02-01
-6dj0,2018-10-31,2018-05-24
-3djd,2008-07-22,2008-06-23
-5djk,2015-11-11,2015-09-02
-5djg,2015-11-11,2015-09-02
-4djd,2012-03-14,2012-02-01
-4djh,2012-03-21,2012-02-01
-8dji,2022-08-10,2022-06-30
-6dj6,2019-05-29,2018-05-24
-5djm,2016-11-02,2015-09-02
-1djx,1997-07-07,1996-08-24
-4djw,2012-03-21,2012-02-02
-6djo,2019-02-27,2018-05-25
-5dj3,2015-11-25,2015-09-01
-8djw,2023-01-18,2022-07-01
-8djk,2022-08-03,2022-06-30
-4djl,2013-02-06,2012-02-02
-4djs,2012-10-17,2012-02-02
-6djv,2018-09-26,2018-05-26
-3djb,2008-08-19,2008-06-23
-1djn,1999-12-22,1999-12-03
-5djp,2015-09-30,2015-09-02
-5dj2,2016-03-30,2015-09-01
-6djh,2019-05-29,2018-05-25
-8dje,2023-03-22,2022-06-30
-1dj9,2000-12-06,1999-12-02
-6djd,2019-05-29,2018-05-25
-3djg,2008-08-05,2008-06-23
-7djl,2022-06-08,2020-11-20
-3djf,2009-06-30,2008-06-23
-8djc,2023-03-22,2022-06-30
-1djy,1997-07-07,1996-08-24
-5djj,2015-11-11,2015-09-02
-8djz,2023-01-11,2022-07-01
-8dj6,2023-07-26,2022-06-30
-4djj,2012-03-07,2012-02-02
-6dj7,2018-10-17,2018-05-24
-4dju,2012-03-21,2012-02-02
-7djj,2022-06-08,2020-11-20
-6djx,2018-07-04,2018-05-27
-4dj4,2012-11-07,2012-02-01
-6dj8,2019-05-29,2018-05-24
-4djq,2012-08-01,2012-02-02
-7dji,2021-11-24,2020-11-20
-8djt,2023-01-18,2022-07-01
-8djq,2023-01-18,2022-07-01
-1esa,1994-04-30,1994-02-04
-3esa,2009-07-28,2008-10-05
-4esh,2012-05-23,2012-04-23
-5esk,2016-11-23,2015-11-16
-6esd,2017-12-06,2017-10-20
-6esa,2018-10-31,2017-10-19
-6est,1991-10-15,1990-06-15
-5ese,2016-11-23,2015-11-16
-5esv,2015-12-16,2015-11-17
-5es1,2015-12-02,2015-11-16
-7esz,2021-11-10,2021-05-12
-6esm,2018-05-16,2017-10-23
-8esk,2023-06-07,2022-10-14
-4esq,2012-07-18,2012-04-23
-1esq,2000-08-09,2000-04-10
-5esu,2016-06-22,2015-11-17
-3esr,2008-10-14,2008-10-06
-5esn,2016-11-23,2015-11-16
-1es3,2000-05-03,2000-04-07
-3est,1988-01-16,1987-09-17
-4es8,2012-09-19,2012-04-23
-5ess,2016-06-22,2015-11-17
-7est,1991-10-15,1990-06-15
-8esc,2022-11-16,2022-10-13
-5esj,2016-11-23,2015-11-16
-1esz,2002-04-17,2000-04-11
-3esk,2009-07-07,2008-10-06
-3esb,2009-07-28,2008-10-05
-4es5,2013-03-06,2012-04-22
-8es8,2023-05-03,2022-10-13
-7esc,2021-11-03,2021-05-10
-4est,1992-04-15,1989-05-15
-7es1,2021-12-08,2021-05-08
-6esc,2017-11-08,2017-10-20
-6esy,2017-12-13,2017-10-24
-3esd,2009-07-28,2008-10-05
-8esz,2023-03-29,2022-10-15
-3es3,2008-10-21,2008-10-03
-2es4,2006-03-07,2005-10-25
-5esm,2016-11-23,2015-11-16
-3esj,2009-08-25,2008-10-06
-6esj,2017-12-13,2017-10-20
-7esr,2021-12-15,2021-05-11
-8es9,2023-05-03,2022-10-13
-5es9,2016-01-20,2015-11-16
-4es0,2012-05-30,2012-04-21
-5esl,2016-11-23,2015-11-16
-8ess,2023-12-06,2022-10-14
-6esn,2018-08-22,2017-10-23
-4esv,2012-10-24,2012-04-23
-8esu,2023-12-06,2022-10-14
-4eso,2012-05-16,2012-04-23
-5est,1992-04-15,1989-05-15
-6es9,2018-01-03,2017-10-19
-4esi,2012-10-31,2012-04-23
-3esy,2009-02-10,2008-10-06
-2es2,2006-09-05,2005-10-25
-7esa,2021-11-03,2021-05-09
-3es9,2009-01-20,2008-10-05
-5esx,2016-03-30,2015-11-17
-5es8,2016-01-20,2015-11-16
-1es1,2000-08-09,2000-04-07
-1esb,1994-04-30,1994-02-04
-2esf,2006-04-18,2005-10-26
-8esx,2023-02-08,2022-10-15
-3esp,2009-04-07,2008-10-06
-7esl,2021-08-04,2021-05-11
-8esr,2022-11-30,2022-10-14
-1esf,1996-07-11,1995-05-25
-4esk,2012-05-02,2012-04-23
-7esb,2021-11-03,2021-05-09
-1esw,2001-04-11,2000-04-11
-3ess,2009-09-15,2008-10-06
-6esl,2018-04-04,2017-10-22
-2esu,2006-06-13,2005-10-27
-2esr,2006-02-07,2005-10-26
-8esl,2023-11-01,2022-10-14
-3esx,2009-02-10,2008-10-06
-5esh,2016-11-23,2015-11-16
-5esp,2016-03-30,2015-11-16
-2esh,2005-12-06,2005-10-26
-7esy,2021-11-10,2021-05-12
-5es4,2016-03-02,2015-11-16
-5esr,2016-06-01,2015-11-17
-3esf,2009-05-12,2008-10-05
-8esv,2023-06-14,2022-10-14
-2esl,2005-12-13,2005-10-26
-5es7,2016-01-20,2015-11-16
-4esa,2012-11-07,2012-04-23
-1esn,2000-11-17,2000-04-10
-6esq,2018-03-14,2017-10-24
-1esp,1995-12-07,1995-08-11
-7esq,2022-03-23,2021-05-11
-8esi,2023-11-01,2022-10-14
-5esd,2016-06-22,2015-11-16
-3esn,2009-04-07,2008-10-06
-4esm,2013-05-08,2012-04-23
-3eso,2009-04-07,2008-10-06
-2esc,2005-12-20,2005-10-26
-3esw,2008-11-11,2008-10-06
-8esy,2023-02-08,2022-10-15
-5esz,2015-12-16,2015-11-17
-3es8,2008-10-21,2008-10-04
-1esv,2000-07-19,2000-04-11
-5esi,2016-11-23,2015-11-16
-6es0,2018-02-21,2017-10-19
-7esk,2021-08-04,2021-05-11
-5esg,2016-11-23,2015-11-16
-3esc,2009-07-28,2008-10-05
-1esl,1994-08-31,1994-06-03
-2esa,2006-10-03,2005-10-25
-1esm,2000-09-20,2000-04-10
-5es3,2016-01-13,2015-11-16
-7es0,2021-12-08,2021-05-08
-7esm,2021-08-04,2021-05-11
-7ese,2021-05-26,2021-05-10
-2esd,2006-05-02,2005-10-26
-8esg,2023-11-01,2022-10-14
-8esw,2023-03-29,2022-10-15
-1esg,2000-05-31,2000-04-09
-9est,1994-01-31,1991-01-14
-3esq,2008-10-14,2008-10-06
-5eso,2016-06-22,2015-11-16
-5esf,2016-11-23,2015-11-16
-4esj,2012-06-13,2012-04-23
-1eso,1998-07-01,1997-06-27
-4ese,2012-05-23,2012-04-23
-7es2,2021-12-08,2021-05-08
-1est,1976-05-27,1976-05-17
-8esq,2022-11-30,2022-10-14
-6esu,2018-01-03,2017-10-24
-7esn,2021-08-04,2021-05-11
-6esb,2018-05-02,2017-10-20
-2esw,2006-04-11,2005-10-27
-2esm,2005-11-08,2005-10-26
-8est,1992-10-15,1990-02-21
-3es7,2008-10-21,2008-10-04
-3es6,2008-10-28,2008-10-04
-8esm,2023-06-07,2022-10-14
-7esi,2022-02-09,2021-05-11
-3esz,2009-02-10,2008-10-06
-5esq,2016-06-15,2015-11-16
-4esn,2012-06-20,2012-04-23
-8es7,2023-05-03,2022-10-13
-1esk,2000-04-26,2000-04-10
-2esv,2006-03-21,2005-10-27
-5esb,2016-11-30,2015-11-16
-8esh,2023-01-25,2022-10-14
-2ess,2006-03-28,2005-10-26
-2im0,2006-12-12,2006-10-03
-3imp,2010-08-04,2009-08-11
-3imq,2009-11-10,2009-08-11
-5imi,2016-05-25,2016-03-06
-1imc,1995-02-27,1994-02-08
-8im5,2023-08-30,2023-03-06
-5imd,2016-09-21,2016-03-06
-8im6,2024-03-06,2023-03-06
-2ime,2007-06-12,2006-10-04
-1ima,1995-02-27,1994-02-08
-4imf,2013-11-06,2013-01-02
-4imm,2014-03-26,2013-01-03
-4imy,2013-03-13,2013-01-03
-5imv,2016-09-21,2016-03-07
-4ima,2013-01-23,2013-01-02
-2imd,2007-06-12,2006-10-04
-2imb,2007-06-05,2006-10-04
-8imn,2023-10-25,2023-03-07
-4imz,2013-02-20,2013-01-03
-3imc,2009-10-13,2009-08-10
-6im7,2019-03-20,2018-10-22
-2imq,2007-08-21,2006-10-04
-5imx,2016-05-04,2016-03-07
-5imt,2016-08-24,2016-03-06
-8imd,2024-01-17,2023-03-06
-5imr,2016-05-18,2016-03-06
-2imr,2006-10-17,2006-10-04
-4imt,2013-04-24,2013-01-03
-2imt,2007-01-23,2006-10-04
-5ims,2017-02-15,2016-03-06
-1im5,2001-12-12,2001-05-09
-6imt,2019-10-23,2018-10-23
-1im8,2001-11-07,2001-05-10
-3im0,2009-10-20,2009-08-08
-1im9,2001-05-30,2001-05-10
-3imx,2009-10-06,2009-08-11
-8imo,2023-10-25,2023-03-07
-3im9,2010-06-16,2009-08-10
-1im2,2001-08-08,2001-05-09
-6im4,2019-01-23,2018-10-22
-2imp,2007-02-13,2006-10-04
-4imi,2013-08-07,2013-01-03
-5imn,2016-05-25,2016-03-06
-2im3,2006-12-12,2006-10-03
-8ime,2024-01-03,2023-03-06
-6im1,2019-07-17,2018-10-21
-4imj,2013-08-07,2013-01-03
-8im3,2023-10-18,2023-03-05
-5imu,2017-03-08,2016-03-07
-4imq,2013-02-20,2013-01-03
-4imx,2013-04-24,2013-01-03
-1imb,1995-02-27,1994-02-08
-5ime,2016-05-25,2016-03-06
-2ima,2007-06-05,2006-10-04
-8imx,2023-08-16,2023-03-07
-5imf,2016-09-21,2016-03-06
-2imc,2007-06-05,2006-10-04
-8imm,2023-10-25,2023-03-07
-6ime,2019-09-04,2018-10-22
-8imi,2023-10-25,2023-03-07
-6imc,2020-01-22,2018-10-22
-6im0,2019-07-17,2018-10-21
-6im3,2019-07-17,2018-10-22
-8img,2024-01-03,2023-03-06
-3imb,2010-08-11,2009-08-10
-4ims,2013-04-24,2013-01-03
-6imo,2019-10-23,2018-10-23
-3im4,2010-02-02,2009-08-09
-3imy,2009-09-08,2009-08-11
-6imw,2019-04-10,2018-10-23
-4imo,2013-03-20,2013-01-03
-6imv,2019-04-10,2018-10-23
-6imr,2019-10-23,2018-10-23
-2imz,2007-05-01,2006-10-05
-3ime,2009-10-13,2009-08-10
-6imz,2019-10-30,2018-10-24
-4imr,2013-01-16,2013-01-03
-4im0,2013-03-06,2013-01-01
-8imf,2024-01-03,2023-03-06
-5ima,2016-09-21,2016-03-06
-8imk,2023-10-25,2023-03-07
-1imd,1995-02-27,1994-02-08
-6imu,2019-04-10,2018-10-23
-3ims,2010-01-12,2009-08-11
-4img,2013-11-06,2013-01-02
-8im7,2024-01-17,2023-03-06
-6imq,2019-07-31,2018-10-23
-5imh,2017-03-15,2016-03-06
-4imw,2013-04-24,2013-01-03
-4imp,2013-03-27,2013-01-03
-5im7,2016-10-05,2016-03-05
-3img,2009-10-13,2009-08-10
-1imx,2001-09-05,2001-05-11
-6imj,2019-02-27,2018-10-23
-2im1,2006-12-12,2006-10-03
-3imd,2009-11-17,2009-08-10
-5im9,2016-09-21,2016-03-05
-4imb,2014-01-29,2013-01-02
-5im3,2016-05-04,2016-03-05
-1iml,1996-07-11,1995-12-23
-3imj,2009-11-17,2009-08-10
-3imr,2010-01-12,2009-08-11
-1ime,1995-02-27,1994-02-08
-1im3,2001-06-06,2001-05-09
-3imv,2010-01-12,2009-08-11
-8imy,2023-08-16,2023-03-07
-2im2,2006-12-12,2006-10-03
-8iml,2023-10-25,2023-03-07
-2imk,2007-10-09,2006-10-02
-4imk,2013-04-17,2013-01-03
-3imm,2009-08-18,2009-08-10
-2imi,2007-10-09,2006-10-02
-5imc,2016-09-21,2016-03-06
-3imu,2010-01-12,2009-08-11
-4imu,2013-04-24,2013-01-03
-6imi,2019-10-23,2018-10-23
-3imw,2010-01-12,2009-08-11
-6imy,2019-03-13,2018-10-24
-4im3,2013-03-06,2013-01-01
-3imh,2009-08-18,2009-08-10
-4im7,2013-01-23,2013-01-02
-4im2,2013-03-06,2013-01-01
-3imn,2009-09-29,2009-08-10
-6im6,2019-10-23,2018-10-22
-5imz,2016-09-21,2016-03-07
-6imb,2019-10-23,2018-10-22
-3imi,2009-08-18,2009-08-10
-2iml,2006-10-17,2006-10-04
-5img,2017-03-15,2016-03-06
-2ims,2006-12-26,2006-10-04
-8im8,2023-05-24,2023-03-06
-3imt,2010-01-12,2009-08-11
-2imw,2007-01-16,2006-10-05
-5imq,2016-05-18,2016-03-06
-8imj,2023-10-25,2023-03-07
-8im2,2023-10-18,2023-03-05
-5imp,2016-05-25,2016-03-06
-2imf,2007-06-12,2006-10-04
-1imv,2001-09-26,2001-05-11
-6imd,2019-10-23,2018-10-22
-6j4v,2019-05-01,2019-01-10
-1j4j,2003-06-03,2001-10-02
-5j46,2016-04-13,2016-03-31
-6j4e,2020-01-15,2019-01-08
-1j4l,2001-12-05,2001-10-03
-6j4p,2019-05-01,2019-01-10
-4j4p,2014-03-12,2013-02-07
-6j44,2019-05-29,2019-01-07
-6j4g,2020-01-15,2019-01-08
-8j4g,2024-04-24,2023-04-19
-6j4q,2019-05-01,2019-01-10
-4j4q,2013-10-30,2013-02-07
-1j40,2003-07-22,2003-02-21
-4j49,2013-06-12,2013-02-06
-4j4v,2013-05-22,2013-02-07
-4j46,2013-09-25,2013-02-06
-5j4v,2016-07-20,2016-04-01
-6j42,2020-01-15,2019-01-07
-8j4z,2024-04-24,2023-04-21
-1j4k,2001-12-05,2001-10-03
-2j4s,2007-05-15,2006-09-05
-4j47,2013-09-25,2013-02-06
-5j4z,2016-09-21,2016-04-01
-5j4d,2016-05-18,2016-03-31
-5j4e,2016-06-22,2016-04-01
-2j4d,2007-06-19,2006-08-28
-2j4k,2007-02-27,2006-09-01
-2j4z,2006-11-06,2006-09-08
-1j4g,2001-10-24,2001-09-30
-2j45,2006-11-30,2006-08-24
-6j4f,2020-01-15,2019-01-08
-1j49,2002-05-29,2001-08-14
-2j4f,2006-09-05,2006-08-30
-4j4s,2013-05-22,2013-02-07
-5j4b,2016-04-27,2016-03-31
-2j41,2006-10-11,2006-08-24
-6j40,2019-08-07,2019-01-07
-5j4h,2016-10-19,2016-04-01
-5j41,2016-11-30,2016-03-31
-1j4r,2001-12-19,2001-10-29
-8j4j,2024-01-10,2023-04-20
-5j4k,2016-10-26,2016-04-01
-4j4t,2014-07-23,2013-02-07
-1j4i,2003-06-03,2001-09-30
-8j4l,2024-05-01,2023-04-20
-5j4x,2017-02-08,2016-04-01
-6j4t,2019-07-31,2019-01-10
-1j41,2003-07-22,2003-02-21
-2j4y,2007-09-25,2006-09-07
-6j4c,2020-01-15,2019-01-08
-6j4h,2019-09-18,2019-01-09
-8j4q,2024-04-24,2023-04-20
-8j4b,2024-02-28,2023-04-19
-2j4g,2007-01-30,2006-08-31
-2j4l,2007-02-27,2006-09-01
-2j4q,2007-08-07,2006-09-05
-3j4k,2013-09-25,2013-08-26
-4j4j,2013-11-06,2013-02-06
-4j4m,2013-07-10,2013-02-07
-4j4n,2013-09-11,2013-02-07
-2j4r,2007-10-16,2006-09-05
-2j4i,2006-09-27,2006-08-31
-2j47,2006-10-03,2006-08-25
-5j42,2016-05-04,2016-03-31
-4j4k,2014-04-30,2013-02-07
-3j4s,2014-02-19,2013-10-03
-8j49,2024-02-28,2023-04-19
-8j40,2024-02-28,2023-04-18
-5j4r,2017-04-12,2016-04-01
-5j4c,2016-04-27,2016-03-31
-6j43,2020-01-15,2019-01-07
-5j4t,2017-02-08,2016-04-01
-8j4k,2024-04-24,2023-04-20
-8j43,2024-04-24,2023-04-19
-6j4n,2019-02-27,2019-01-10
-4j45,2013-09-25,2013-02-06
-2j4h,2007-08-07,2006-08-31
-2j46,2006-11-30,2006-08-24
-6j4w,2019-02-20,2019-01-10
-2j40,2007-10-02,2006-08-24
-6j4z,2019-02-20,2019-01-10
-8j4u,2024-01-03,2023-04-20
-5j48,2017-04-12,2016-03-31
-6j46,2019-05-01,2019-01-08
-8j44,2024-04-24,2023-04-19
-8j45,2024-01-17,2023-04-19
-1j4x,2001-12-19,2001-12-13
-1j4h,2003-06-03,2001-09-30
-4j48,2013-09-25,2013-02-06
-4j4h,2013-06-12,2013-02-06
-6j4y,2019-02-20,2019-01-10
-5j4n,2016-08-31,2016-04-01
-3j41,2013-07-31,2013-05-31
-4j4o,2013-09-11,2013-02-07
-5j4u,2017-04-12,2016-04-01
-2j4x,2007-09-25,2006-09-07
-2j44,2006-12-11,2006-08-24
-8j4h,2024-01-10,2023-04-20
-4j44,2013-09-25,2013-02-06
-2j4e,2006-09-20,2006-08-29
-8j48,2024-02-28,2023-04-19
-6j4j,2019-09-18,2019-01-09
-5j47,2016-07-20,2016-03-31
-4j4b,2013-06-12,2013-02-06
-2j4c,2007-03-27,2006-08-28
-6j4b,2020-01-15,2019-01-08
-6j4m,2019-09-18,2019-01-09
-8j4r,2024-04-24,2023-04-20
-1j4u,2002-03-27,2001-10-30
-2j4j,2007-02-27,2006-09-01
-4j43,2013-06-12,2013-02-06
-2j4a,2007-09-25,2006-08-28
-8j4f,2023-06-14,2023-04-19
-6j4x,2019-02-20,2019-01-10
-5j4y,2016-07-20,2016-04-01
-5j40,2016-07-20,2016-03-31
-2cqt,2006-05-16,2005-05-20
-5cqw,2015-09-09,2015-07-22
-7cq4,2021-06-16,2020-08-08
-5cq8,2015-09-09,2015-07-21
-3cqx,2008-11-25,2008-04-03
-5cqh,2015-10-07,2015-07-21
-4cql,2014-09-10,2014-02-19
-5cq6,2015-09-09,2015-07-21
-5cq0,2015-10-28,2015-07-21
-3cqv,2008-08-05,2008-04-03
-6cqy,2018-12-05,2018-03-16
-8cqx,2023-04-05,2023-03-07
-6cqp,2018-08-22,2018-03-15
-5cqa,2015-09-09,2015-07-21
-6cqu,2018-12-05,2018-03-16
-8cq6,2023-08-30,2023-03-03
-3cqe,2009-02-24,2008-04-02
-4cqb,2015-03-04,2014-02-13
-3cqp,2008-04-29,2008-04-03
-2cqs,2006-05-16,2005-05-20
-1cq6,2000-12-20,1999-08-06
-6cq4,2018-12-05,2018-03-14
-7cqs,2022-03-16,2020-08-11
-8cqe,2023-09-27,2023-03-06
-3cqz,2008-07-22,2008-04-03
-4cqz,2014-05-28,2014-02-21
-5cqk,2015-10-07,2015-07-21
-6cqz,2018-12-05,2018-03-16
-5cqc,2015-09-09,2015-07-21
-4cqd,2015-03-04,2014-02-13
-7cqn,2020-11-18,2020-08-11
-8cq8,2024-03-13,2023-03-04
-8cql,2023-09-27,2023-03-06
-4cqr,2014-05-28,2014-02-21
-8cqs,2024-03-27,2023-03-07
-3cqd,2008-09-16,2008-04-02
-5cqp,2016-10-26,2015-07-21
-1cqs,2003-06-17,1999-08-11
-1cqf,2000-08-07,1999-08-06
-4cqv,2014-05-28,2014-02-21
-8cqi,2024-01-10,2023-03-06
-4cqu,2014-05-28,2014-02-21
-3cq3,2009-04-07,2008-04-02
-4cqh,2014-05-28,2014-02-17
-1cqq,1999-09-20,1999-08-10
-6cqs,2018-08-29,2018-03-16
-1cqx,1999-08-31,1999-08-12
-8cqq,2024-03-27,2023-03-07
-4cq7,2015-03-04,2014-02-11
-7cqx,2020-11-18,2020-08-11
-8cqb,2024-03-13,2023-03-04
-4cqn,2014-07-02,2014-02-20
-4cqj,2014-05-28,2014-02-17
-1cqv,1999-08-22,1999-08-11
-7cqv,2021-06-23,2020-08-11
-7cqq,2020-11-18,2020-08-11
-8cqy,2023-05-10,2023-03-07
-5cqz,2015-12-23,2015-07-22
-3cqo,2009-04-28,2008-04-03
-1cqp,2000-08-07,1999-08-10
-1cq2,1999-08-16,1999-08-04
-6cqn,2018-06-06,2018-03-15
-8cqk,2023-09-27,2023-03-06
-5cq5,2015-09-09,2015-07-21
-8cqa,2024-03-13,2023-03-04
-4cqa,2014-04-30,2014-02-12
-2cqf,2005-11-19,2005-05-19
-2cqe,2005-11-19,2005-05-19
-4cq1,2014-02-19,2014-02-10
-4cq9,2014-04-30,2014-02-12
-4cqk,2014-04-16,2014-02-17
-5cqu,2015-09-09,2015-07-22
-5cql,2016-10-26,2015-07-22
-4cqq,2014-05-28,2014-02-21
-5cqo,2016-10-26,2015-07-21
-3cql,2008-08-05,2008-04-03
-8cqm,2023-10-18,2023-03-06
-3cqr,2009-04-21,2008-04-03
-7cqh,2021-06-23,2020-08-10
-5cqt,2016-01-13,2015-07-22
-8cqh,2024-03-13,2023-03-06
-6cqr,2018-06-06,2018-03-16
-7cqt,2021-07-14,2020-08-11
-3cqu,2008-05-27,2008-04-03
-5cqj,2015-08-19,2015-07-21
-6cqh,2018-03-28,2018-03-15
-3cqb,2008-05-27,2008-04-02
-1cqi,2000-01-07,1999-08-06
-6cq5,2018-12-05,2018-03-14
-8cqv,2024-03-27,2023-03-07
-4cq0,2014-04-16,2014-02-10
-6cq8,2018-03-28,2018-03-14
-7cq6,2020-11-11,2020-08-08
-4cqf,2014-04-02,2014-02-14
-4cqe,2014-12-10,2014-02-14
-6cqq,2018-06-06,2018-03-16
-1cqd,1999-09-28,1999-06-15
-3cq5,2008-07-01,2008-04-02
-5cqd,2015-10-07,2015-07-21
-5cq3,2015-09-09,2015-07-21
-6cq2,2018-05-30,2018-03-14
-1cqr,2000-03-20,1999-08-11
-6cq9,2018-04-11,2018-03-14
-7cqk,2021-02-10,2020-08-11
-6cq1,2019-03-20,2018-03-14
-5cq4,2015-09-09,2015-07-21
-7cq7,2020-11-11,2020-08-08
-7cqr,2022-03-16,2020-08-11
-6cqj,2018-06-06,2018-03-15
-6cqd,2018-12-19,2018-03-14
-3cqw,2008-05-27,2008-04-03
-3cqk,2008-11-25,2008-04-03
-7cqw,2020-11-18,2020-08-11
-6cqg,2019-06-19,2018-03-15
-4cq8,2014-04-30,2014-02-12
-4cq6,2015-03-04,2014-02-11
-6cqc,2019-03-20,2018-03-14
-6cqa,2019-01-09,2018-03-14
-3cqq,2008-04-29,2008-04-03
-7cqi,2021-02-10,2020-08-11
-4cqc,2015-03-04,2014-02-13
-6cqx,2018-12-05,2018-03-16
-8cqt,2024-03-27,2023-03-07
-7cqp,2021-06-23,2020-08-11
-5cqm,2016-10-26,2015-07-22
-7cqu,2020-11-18,2020-08-11
-6cqf,2018-12-19,2018-03-15
-5cq7,2015-09-09,2015-07-21
-7cqo,2021-08-11,2020-08-11
-1cq8,2000-12-20,1999-08-06
-1cq1,2000-02-04,1999-08-04
-6cqt,2018-12-05,2018-03-16
-4cqx,2014-05-28,2014-02-21
-5cqi,2015-10-07,2015-07-21
-3cq8,2008-09-02,2008-04-02
-6cqw,2018-12-05,2018-03-16
-7cq3,2021-06-16,2020-08-08
-6cq0,2018-12-05,2018-03-14
-4cqg,2014-07-09,2014-02-17
-7cq2,2021-06-16,2020-08-08
-6cqv,2018-12-05,2018-03-16
-2cqz,2006-08-15,2005-05-20
-5cq1,2015-11-04,2015-07-21
-8cqp,2024-03-27,2023-03-07
-4cqw,2014-05-28,2014-02-21
-8cqf,2023-06-21,2023-03-06
-7cqe,2020-11-04,2020-08-10
-4cqy,2014-05-28,2014-02-21
-4cq5,2014-05-07,2014-02-11
-1cqj,2000-01-10,1999-08-06
-6cq6,2018-03-28,2018-03-14
-6cql,2018-06-06,2018-03-15
-8cqg,2023-06-21,2023-03-06
-8cq9,2024-03-13,2023-03-04
-3cqj,2008-11-25,2008-04-03
-4cqs,2014-05-28,2014-02-21
-5cqg,2015-09-09,2015-07-21
-1cq9,2002-05-01,1999-08-06
-7cq5,2020-11-11,2020-08-08
-1cqe,1999-06-30,1999-06-15
-4cqp,2014-05-28,2014-02-21
-4cqm,2014-09-10,2014-02-19
-1cq7,2000-12-20,1999-08-06
-7y01,2023-04-12,2022-06-03
-2y0c,2011-07-27,2010-12-02
-1y0t,2004-12-07,2004-11-16
-1y0l,2005-04-05,2004-11-15
-7y09,2023-03-29,2022-06-03
-6y0a,2021-02-17,2020-02-07
-1y09,2004-11-30,2004-11-15
-1y0b,2005-02-22,2004-11-15
-6y0g,2020-04-15,2020-02-07
-1y02,2004-12-28,2004-11-14
-7y0t,2023-06-14,2022-06-06
-1y0d,2004-11-30,2004-11-15
-7y03,2022-12-21,2022-06-03
-1y0a,2004-12-07,2004-11-15
-4y0y,2015-06-24,2015-02-06
-4y08,2015-09-23,2015-02-05
-1y0y,2005-03-01,2004-11-16
-2y0i,2011-02-02,2010-12-02
-5y0f,2018-06-06,2017-07-17
-5y06,2018-05-02,2017-07-14
-4y0w,2016-01-27,2015-02-06
-2y00,2011-01-12,2010-11-30
-4y00,2016-02-10,2015-02-05
-7y0l,2023-08-02,2022-06-05
-5y0z,2018-07-25,2017-07-19
-6y0b,2021-02-17,2020-02-07
-5y0d,2018-07-18,2017-07-16
-2y0d,2011-07-27,2010-12-02
-1y0g,2004-12-21,2004-11-15
-2y01,2011-03-30,2010-11-30
-7y0s,2023-06-14,2022-06-06
-4y0e,2015-11-25,2015-02-06
-6y00,2020-09-23,2020-02-05
-2y02,2011-01-12,2010-11-30
-6y0p,2021-02-17,2020-02-10
-5y0n,2018-07-18,2017-07-18
-4y0a,2015-08-12,2015-02-05
-2y06,2011-12-28,2010-11-30
-2y0e,2011-07-27,2010-12-02
-5y0u,2018-08-01,2017-07-18
-4y05,2015-06-17,2015-02-05
-7y0q,2023-06-14,2022-06-06
-5y0t,2018-07-18,2017-07-18
-4y0x,2015-05-20,2015-02-06
-6y0q,2020-09-09,2020-02-10
-4y04,2015-07-15,2015-02-05
-4y0h,2015-03-11,2015-02-06
-1y0c,2004-12-07,2004-11-15
-5y0v,2018-01-24,2017-07-18
-4y06,2015-07-15,2015-02-05
-7y0i,2022-10-12,2022-06-05
-6y02,2021-02-17,2020-02-06
-2y0p,2011-06-15,2010-12-07
-7y0j,2023-04-05,2022-06-05
-6y09,2020-09-30,2020-02-07
-4y0v,2015-03-04,2015-02-06
-4y03,2015-05-20,2015-02-05
-1y0w,2004-12-07,2004-11-16
-1y0x,2004-12-07,2004-11-16
-8y0p,2024-04-17,2024-01-22
-7y0b,2023-07-05,2022-06-04
-7y0f,2023-12-06,2022-06-04
-7y02,2022-12-21,2022-06-03
-7y0w,2022-09-28,2022-06-06
-6y0f,2021-02-17,2020-02-07
-6y0v,2021-02-24,2020-02-10
-6y0k,2020-08-05,2020-02-08
-5y0g,2018-06-06,2017-07-17
-4y0i,2016-02-17,2015-02-06
-7y0r,2023-06-14,2022-06-06
-1y0s,2005-03-29,2004-11-16
-4y0u,2016-01-13,2015-02-06
-6y05,2021-02-17,2020-02-06
-7y0x,2023-05-31,2022-06-06
-2y03,2011-01-12,2010-11-30
-6y0o,2020-09-09,2020-02-10
-5y07,2018-08-01,2017-07-25
-6y04,2020-07-08,2020-02-06
-7y0v,2022-09-28,2022-06-06
-6y0s,2020-02-19,2020-02-10
-6y0u,2021-02-24,2020-02-10
-7y07,2022-12-21,2022-06-03
-2y0m,2011-01-12,2010-12-03
-2y09,2011-02-09,2010-12-01
-1y0v,2005-05-03,2004-11-16
-8y0x,2024-02-07,2024-01-23
-5y0c,2018-07-18,2017-07-16
-2y0j,2011-06-15,2010-12-03
-7y06,2022-12-21,2022-06-03
-5y0p,2018-07-18,2017-07-18
-7y08,2022-12-21,2022-06-03
-1y0r,2005-03-01,2004-11-16
-7y0a,2023-07-05,2022-06-04
-8y0u,2024-02-07,2024-01-23
-1y0j,2005-01-25,2004-11-15
-6y0e,2021-02-17,2020-02-07
-4y0q,2015-07-01,2015-02-06
-6y08,2021-02-17,2020-02-06
-6y03,2021-02-17,2020-02-06
-2y0s,2011-02-16,2010-12-07
-1y01,2004-12-21,2004-11-14
-4y02,2015-07-15,2015-02-05
-7y0u,2023-06-14,2022-06-06
-4y0f,2016-02-10,2015-02-06
-7y0p,2023-06-14,2022-06-06
-4y0z,2015-06-24,2015-02-06
-4y0j,2015-04-22,2015-02-06
-4y0p,2015-07-01,2015-02-06
-5y0l,2018-07-25,2017-07-18
-4y0k,2015-09-23,2015-02-06
-7y0c,2022-09-28,2022-06-04
-7y05,2022-12-21,2022-06-03
-2y07,2011-12-28,2010-11-30
-5y0q,2018-07-18,2017-07-18
-6y0z,2020-02-19,2020-02-10
-4y0d,2015-02-25,2015-02-05
-6y0w,2021-02-17,2020-02-10
-7y0n,2023-09-13,2022-06-05
-2y04,2011-01-12,2010-11-30
-2y0o,2011-05-25,2010-12-07
-7y0h,2023-04-12,2022-06-05
-7y0e,2023-12-06,2022-06-04
-1y0p,2005-11-08,2004-11-16
-4y0r,2015-07-01,2015-02-06
-7y04,2023-01-04,2022-06-03
-5y0x,2018-06-06,2017-07-19
-6y0r,2020-06-03,2020-02-10
-6y0n,2020-09-09,2020-02-10
-2y05,2011-01-26,2010-11-30
-1y0z,2004-11-30,2004-11-16
-5y0y,2017-09-13,2017-07-19
-6y0x,2021-02-17,2020-02-10
-1y07,2005-11-22,2004-11-15
-4y0s,2015-07-01,2015-02-06
-2y08,2011-06-29,2010-11-30
-5y05,2018-05-02,2017-07-14
-5y02,2017-11-22,2017-07-14
-7y0k,2023-06-14,2022-06-05
-8y0w,2024-02-07,2024-01-23
-6crn,2019-01-23,2018-03-19
-4crt,2014-04-02,2014-02-28
-3crb,2008-04-29,2008-04-05
-8crk,2023-10-04,2023-03-08
-8cr8,2024-02-07,2023-03-08
-3cr6,2009-03-17,2008-04-04
-3cr3,2008-10-21,2008-04-04
-8crl,2023-06-07,2023-03-08
-1crp,1994-07-31,1993-11-24
-4crl,2015-09-23,2014-02-27
-3cr7,2009-02-17,2008-04-04
-6crw,2018-04-11,2018-03-19
-7cr4,2020-09-16,2020-08-12
-6cr0,2018-03-28,2018-03-16
-5crh,2015-10-07,2015-07-22
-4cr9,2015-02-11,2014-02-26
-8crf,2023-10-04,2023-03-08
-1cr5,1999-12-22,1999-08-13
-7cr2,2020-09-16,2020-08-12
-3crz,2008-10-21,2008-04-08
-5cre,2015-10-07,2015-07-22
-7crr,2020-10-21,2020-08-14
-6crk,2018-10-24,2018-03-19
-1crc,1996-03-08,1995-03-22
-3cr9,2008-04-29,2008-04-05
-7cr1,2020-09-16,2020-08-12
-6cri,2018-08-01,2018-03-18
-6cr8,2018-07-04,2018-03-16
-7crf,2021-06-23,2020-08-13
-3cr2,2008-06-24,2008-04-04
-5crl,2016-09-07,2015-07-23
-8crp,2023-10-18,2023-03-08
-8cr3,2023-07-05,2023-03-07
-6cr4,2018-07-18,2018-03-16
-1crb,1994-12-20,1993-02-10
-5crd,2015-10-07,2015-07-22
-7crl,2021-04-14,2020-08-13
-6cr3,2018-06-27,2018-03-16
-7crz,2021-01-13,2020-08-14
-5cr0,2016-02-24,2015-07-22
-3crt,2009-02-24,2008-04-07
-1cr4,1999-11-10,1999-08-12
-1cr2,1999-11-10,1999-08-12
-5cr7,2016-01-13,2015-07-22
-4crn,2014-07-23,2014-02-28
-7cri,2020-09-30,2020-08-13
-2crc,2005-11-20,2005-05-20
-5cr5,2015-08-12,2015-07-22
-7cro,2020-10-21,2020-08-14
-7crq,2020-10-21,2020-08-14
-4crf,2015-02-11,2014-02-26
-1cr6,1999-11-19,1999-08-13
-5cr3,2015-08-05,2015-07-22
-6crq,2018-04-18,2018-03-19
-1cry,1994-04-30,1993-12-27
-4crs,2014-03-12,2014-02-28
-4crm,2014-07-23,2014-02-28
-7cre,2021-12-15,2020-08-13
-4cr8,2014-07-09,2014-02-25
-4cr6,2014-07-09,2014-02-25
-8crj,2023-06-07,2023-03-08
-1crq,1994-07-31,1993-11-24
-4cri,2014-08-06,2014-02-26
-6crm,2018-10-17,2018-03-19
-8crr,2022-07-20,2022-05-11
-8crq,2022-07-20,2022-05-11
-8cr1,2023-11-29,2023-03-07
-1crh,1994-01-31,1993-08-06
-6cr7,2018-07-04,2018-03-16
-7crk,2021-04-14,2020-08-13
-4cry,2015-03-25,2014-03-02
-4crc,2015-02-11,2014-02-26
-6crh,2019-03-20,2018-03-17
-5cra,2015-11-25,2015-07-22
-7crj,2020-09-16,2020-08-13
-5cry,2015-10-14,2015-07-23
-4cr0,2014-05-28,2014-02-21
-8crx,2023-03-22,2022-05-12
-5cr2,2016-04-06,2015-07-22
-5cr9,2015-08-12,2015-07-22
-6crd,2019-01-23,2018-03-16
-4crz,2015-03-25,2014-03-02
-1cr7,2001-04-21,1999-08-14
-6cr5,2018-07-18,2018-03-16
-6cr9,2018-07-04,2018-03-16
-1cru,2000-03-01,1999-08-16
-6cre,2019-03-20,2018-03-17
-6crg,2018-11-07,2018-03-17
-3crw,2008-06-10,2008-04-07
-5crg,2015-10-07,2015-07-22
-6crc,2018-07-25,2018-03-16
-8crn,2023-10-18,2023-03-08
-8crm,2023-10-04,2023-03-08
-7crt,2021-04-14,2020-08-14
-7crp,2020-10-21,2020-08-14
-3crp,2008-10-07,2008-04-07
-8cro,2024-04-17,2023-03-08
-3cr4,2008-08-05,2008-04-04
-4crb,2015-02-11,2014-02-26
-3crl,2008-04-29,2008-04-07
-8crt,2022-07-20,2022-05-11
-1crg,1994-01-31,1993-08-06
-7crh,2021-03-03,2020-08-13
-7crs,2021-04-14,2020-08-14
-1crj,1994-01-31,1993-08-06
-8crc,2023-08-16,2023-03-08
-8cr5,2024-02-07,2023-03-07
-3crk,2008-04-29,2008-04-07
-3cr0,2009-02-24,2008-04-03
-4crj,2015-01-28,2014-02-27
-2crw,2005-11-20,2005-05-20
-1crl,1994-01-31,1993-03-02
-5crm,2016-01-13,2015-07-23
-4cre,2015-02-11,2014-02-26
-7cry,2021-04-14,2020-08-14
-8crh,2023-08-02,2023-03-08
-7cr7,2020-09-16,2020-08-12
-2crr,2005-11-20,2005-05-20
-8cri,2023-06-07,2023-03-08
-1crr,1994-07-31,1993-11-24
-3crn,2008-04-22,2008-04-07
-5crz,2016-01-13,2015-07-23
-3crc,2008-04-22,2008-04-05
-1cr1,1999-11-10,1999-08-12
-8cr7,2023-07-05,2023-03-07
-5cr1,2015-10-21,2015-07-22
-8crd,2023-09-06,2023-03-08
-2cr8,2005-11-20,2005-05-20
-6crt,2018-04-04,2018-03-19
-7crc,2020-12-16,2020-08-13
-4crq,2015-01-14,2014-02-28
-1cra,1994-01-31,1992-10-21
-1cr8,1998-12-23,1998-12-14
-6crx,2018-04-11,2018-03-19
-3cr5,2008-06-24,2008-04-04
-3crr,2008-04-29,2008-04-07
-6crz,2018-04-11,2018-03-19
-3crq,2008-04-29,2008-04-07
-4cra,2015-02-11,2014-02-26
-6cr2,2018-06-27,2018-03-16
-8cr2,2023-11-29,2023-03-07
-8crg,2023-06-14,2023-03-08
-4cr7,2014-07-09,2014-02-25
-6crv,2018-04-11,2018-03-19
-8cr6,2024-02-07,2023-03-07
-6cr6,2018-08-22,2018-03-16
-4crv,2014-05-07,2014-03-01
-1crm,1995-02-07,1994-03-04
-4crg,2015-02-11,2014-02-26
-7cr5,2021-03-24,2020-08-12
-4crd,2015-02-11,2014-02-26
-8cr4,2023-07-05,2023-03-07
-1cri,1994-01-31,1993-08-06
-3cru,2009-02-24,2008-04-07
-6crb,2018-07-18,2018-03-16
-7crx,2021-04-14,2020-08-14
-4cr5,2015-02-11,2014-02-25
-3tty,2012-03-21,2011-09-15
-4tts,2015-04-15,2014-06-23
-8ttg,2024-05-29,2023-08-13
-6ttm,2020-03-18,2019-12-29
-6ttt,2020-03-04,2019-12-30
-4tth,2014-08-06,2014-06-20
-6tt0,2020-06-10,2019-12-22
-6ttd,2021-04-07,2019-12-26
-5ttg,2017-02-01,2016-11-03
-5tt7,2016-11-30,2016-11-01
-6tth,2020-01-15,2019-12-27
-6ttr,2021-01-13,2019-12-30
-8ttb,2023-10-25,2023-08-13
-6ttp,2020-03-04,2019-12-30
-6tts,2021-01-13,2019-12-30
-3ttq,2012-01-25,2011-09-15
-3tti,2012-02-01,2011-09-14
-4ttg,2015-03-25,2014-06-20
-3tt7,2011-12-21,2011-09-14
-8tty,2024-02-07,2023-08-15
-8ttp,2023-09-06,2023-08-14
-1ttm,2004-10-05,2004-06-23
-8tt3,2024-04-17,2023-08-12
-6ttw,2020-03-04,2019-12-30
-7tth,2022-06-29,2022-02-01
-1tt5,2004-09-14,2004-06-21
-7ttj,2022-08-31,2022-02-01
-7ttk,2023-02-15,2022-02-01
-6ttk,2020-02-12,2019-12-27
-7tta,2022-05-11,2022-02-01
-7ttx,2022-04-27,2022-02-02
-4tt3,2014-08-06,2014-06-19
-7tti,2022-06-29,2022-02-01
-5ttu,2017-02-22,2016-11-04
-4tte,2014-12-24,2014-06-20
-5ttj,2017-02-08,2016-11-03
-3ttw,2011-10-12,2011-09-15
-6tt9,2020-05-13,2019-12-26
-1ttv,2005-01-04,2004-06-23
-1ttq,1996-03-08,1995-10-11
-4tti,2015-07-08,2014-06-21
-5ttc,2017-08-23,2016-11-02
-6tt5,2020-02-12,2019-12-23
-3ttt,2011-10-12,2011-09-15
-1tt0,2005-06-21,2004-06-21
-6tt2,2020-11-25,2019-12-23
-5tth,2017-08-23,2016-11-03
-7ttq,2022-05-11,2022-02-01
-3ttv,2011-10-12,2011-09-15
-7ttb,2022-05-11,2022-02-01
-6ttn,2020-03-18,2019-12-29
-3ttc,2011-12-28,2011-09-14
-5tt8,2017-09-13,2016-11-02
-4ttj,2015-07-08,2014-06-21
-3ttx,2011-10-12,2011-09-15
-1tt4,2004-08-17,2004-06-21
-5ttv,2017-02-22,2016-11-04
-4tt5,2015-02-18,2014-06-19
-5tts,2017-02-22,2016-11-04
-5ttk,2017-01-25,2016-11-03
-4ttr,2014-12-10,2014-06-22
-5tto,2017-05-24,2016-11-04
-7ttp,2022-05-11,2022-02-01
-1ttt,1996-12-23,1995-11-16
-4tta,2015-07-08,2014-06-20
-5tt3,2017-09-13,2016-11-01
-8ttz,2024-02-07,2023-08-15
-1tt1,2005-02-08,2004-06-21
-7ttv,2023-04-12,2022-02-02
-6tt3,2020-04-01,2019-12-23
-7ttd,2023-04-12,2022-02-01
-5ttf,2016-12-21,2016-11-03
-8ttw,2023-11-08,2023-08-15
-7ttf,2023-04-12,2022-02-01
-6ttx,2020-03-04,2019-12-30
-3tt1,2012-01-04,2011-09-13
-6tt4,2020-04-01,2019-12-23
-7tt9,2022-02-16,2022-02-01
-3ttp,2012-09-26,2011-09-15
-6tt7,2020-09-23,2019-12-23
-1tt6,2004-10-12,2004-06-22
-8tti,2023-08-30,2023-08-14
-7ttc,2022-03-30,2022-02-01
-4tt7,2015-02-11,2014-06-19
-7ttt,2022-12-28,2022-02-01
-5ttz,2018-01-10,2016-11-04
-4ttb,2014-11-26,2014-06-20
-7tto,2022-05-11,2022-02-01
-4ttc,2014-11-26,2014-06-20
-1tti,1995-10-15,1995-04-19
-5tte,2017-08-23,2016-11-03
-6ttl,2020-12-09,2019-12-28
-6ttb,2021-01-13,2019-12-26
-1ttp,1996-03-08,1995-10-11
-4tt4,2014-12-24,2014-06-19
-7ttm,2022-04-27,2022-02-01
-3ttf,2011-12-28,2011-09-14
-7tte,2023-04-12,2022-02-01
-3tt4,2012-06-20,2011-09-14
-3tt0,2012-06-13,2011-09-13
-6tt8,2021-01-13,2019-12-25
-1tth,2004-07-20,2004-06-22
-1ttj,1995-09-15,1995-04-20
-3ttj,2012-01-25,2011-09-14
-5tt0,2016-11-09,2016-10-31
-3ttu,2011-10-12,2011-09-15
-7tts,2022-09-28,2022-02-01
-6ttu,2020-02-12,2019-12-30
-6tte,2020-01-15,2019-12-27
-1tt2,2004-07-06,2004-06-21
-5tt6,2017-03-08,2016-11-01
-7tty,2022-05-04,2022-02-02
-7ttn,2022-12-28,2022-02-01
-1ttx,2005-01-18,2004-06-23
-4tt8,2015-04-15,2014-06-20
-8ttj,2023-08-30,2023-08-14
-3ttb,2011-10-05,2011-09-14
-6ttq,2020-01-15,2019-12-30
-3tta,2011-10-12,2011-09-14
-6ttc,2021-01-13,2019-12-26
-3ttz,2011-11-16,2011-09-15
-4ttq,2014-12-10,2014-06-22
-6ttg,2020-12-30,2019-12-27
-5tt5,2017-03-08,2016-11-01
-6tto,2020-03-18,2019-12-29
-6ttz,2020-03-25,2019-12-30
-6tta,2021-01-13,2019-12-26
-4ttu,2015-07-29,2014-06-23
-3tte,2011-09-28,2011-09-14
-7ttz,2023-02-01,2022-02-02
-7ttl,2022-08-31,2022-02-01
-7ttr,2022-09-28,2022-02-01
-4ttt,2015-01-28,2014-06-23
-8tte,2024-05-29,2023-08-13
-4ttv,2015-09-30,2014-06-23
-3ttd,2011-12-28,2011-09-14
-3tto,2012-01-25,2011-09-15
-6ttf,2020-01-15,2019-12-27
-3tts,2012-03-21,2011-09-15
-5ttd,2017-03-01,2016-11-02
-6tti,2020-01-15,2019-12-27
-7tt8,2022-05-11,2022-01-31
-6tt1,2020-04-01,2019-12-23
-6ttv,2020-03-04,2019-12-30
-4tt2,2014-12-24,2014-06-19
-3ttr,2011-10-19,2011-09-15
-6qip,2020-02-05,2019-01-21
-5qi5,2019-04-10,2018-05-21
-6qi1,2019-09-25,2019-01-17
-5qi6,2019-04-10,2018-05-21
-6qih,2020-02-05,2019-01-18
-2qi4,2008-04-22,2007-07-03
-3qi6,2011-03-02,2011-01-26
-3qiw,2011-04-27,2011-01-27
-1qi2,2000-06-07,1999-06-02
-4qi8,2015-07-15,2014-05-30
-4qij,2014-11-19,2014-05-31
-4qi6,2015-07-15,2014-05-30
-7qi9,2022-12-28,2021-12-14
-3qid,2011-12-21,2011-01-27
-3qiz,2011-04-13,2011-01-28
-1qi5,1999-11-24,1999-06-03
-2qir,2008-04-08,2007-07-05
-7qie,2022-05-18,2021-12-14
-1qio,2001-04-11,1999-06-14
-4qim,2014-07-23,2014-05-31
-5qik,2018-10-31,2018-08-05
-5qil,2018-10-31,2018-08-05
-6qil,2019-07-10,2019-01-21
-1qit,2000-06-05,1999-06-15
-6qiu,2020-05-13,2019-01-21
-3qi2,2012-02-01,2011-01-26
-7qi1,2022-05-25,2021-12-14
-6qix,2019-06-12,2019-01-21
-3qiy,2011-04-13,2011-01-28
-5qi9,2019-04-10,2018-05-21
-5qib,2018-07-18,2018-05-22
-4qir,2014-09-24,2014-06-01
-3qih,2012-02-01,2011-01-27
-2qie,2008-02-19,2007-07-04
-4qif,2015-02-18,2014-05-30
-1qin,1999-11-24,1999-06-14
-5qig,2018-07-18,2018-05-22
-2qim,2008-04-29,2007-07-05
-7qi5,2023-07-05,2021-12-14
-2qi5,2008-04-22,2007-07-03
-6qi9,2019-05-15,2019-01-18
-5qip,2019-12-18,2018-08-10
-5qic,2018-07-18,2018-05-22
-1qir,2000-06-05,1999-06-15
-6qid,2019-03-06,2019-01-18
-6qi0,2019-09-25,2019-01-17
-7qiz,2022-08-03,2021-12-16
-5qij,2018-12-19,2018-07-03
-5qii,2018-12-19,2018-07-03
-3qi3,2011-04-27,2011-01-26
-3qin,2011-04-20,2011-01-27
-7qic,2021-12-29,2021-12-14
-6qie,2019-03-06,2019-01-18
-4qin,2014-07-23,2014-05-31
-7qiw,2022-07-13,2021-12-16
-5qiz,2019-12-18,2018-08-10
-8qic,2024-04-10,2023-09-13
-7qiv,2022-02-16,2021-12-16
-2qis,2007-07-24,2007-07-05
-7qib,2022-12-28,2021-12-14
-1qiq,2000-06-16,1999-06-15
-6qin,2019-12-25,2019-01-21
-5qif,2018-07-18,2018-05-22
-2qiz,2007-09-18,2007-07-06
-2qin,2007-08-14,2007-07-05
-5qi7,2019-04-10,2018-05-21
-5qir,2019-12-18,2018-08-10
-1qib,1999-11-19,1999-06-11
-5qi1,2019-04-10,2018-05-21
-2qi0,2008-04-22,2007-07-03
-1qi8,1999-07-11,1999-06-07
-2qi6,2008-04-22,2007-07-03
-4qiz,2015-04-15,2014-06-03
-1qix,1999-12-14,1999-06-18
-3qix,2011-04-13,2011-01-28
-7qiy,2022-06-15,2021-12-16
-2qi3,2008-04-22,2007-07-03
-4qi7,2015-07-15,2014-05-30
-4qid,2015-07-29,2014-05-30
-7qi6,2023-05-17,2021-12-14
-2qic,2008-05-13,2007-07-03
-2qiu,2008-02-26,2007-07-05
-4qiu,2015-07-08,2014-06-02
-5qix,2019-12-18,2018-08-10
-5qiy,2019-12-18,2018-08-10
-6qio,2020-02-05,2019-01-21
-5qim,2018-10-31,2018-08-05
-1qi0,2000-06-07,1999-06-02
-5qi4,2019-04-10,2018-05-21
-5qi8,2019-04-10,2018-05-21
-7qik,2021-12-29,2021-12-15
-5qin,2018-10-31,2018-08-05
-5qia,2019-04-10,2018-05-21
-1qic,2003-02-11,1999-06-11
-7qix,2022-06-15,2021-12-16
-2qi7,2008-04-22,2007-07-03
-5qie,2018-07-18,2018-05-22
-7qin,2022-02-16,2021-12-15
-3qib,2011-04-27,2011-01-26
-3qi8,2011-05-04,2011-01-26
-7qi4,2022-07-13,2021-12-14
-4qil,2014-07-16,2014-05-31
-1qi1,2001-01-10,1999-06-02
-4qiy,2015-04-15,2014-06-03
-5qis,2019-12-18,2018-08-10
-5qiw,2019-12-18,2018-08-10
-4qip,2015-01-14,2014-06-01
-4qi4,2015-07-15,2014-05-30
-3qiu,2011-04-27,2011-01-27
-3qip,2011-04-20,2011-01-27
-6qi2,2019-09-25,2019-01-17
-5qit,2019-12-18,2018-08-10
-6qi4,2019-07-17,2019-01-17
-7qi8,2022-10-19,2021-12-14
-7qip,2021-12-29,2021-12-15
-4qiw,2014-10-08,2014-06-02
-5qi2,2019-04-10,2018-05-21
-5qio,2019-12-18,2018-08-10
-7qif,2022-02-02,2021-12-14
-4qis,2015-07-08,2014-06-02
-1qiz,1999-06-22,1999-06-18
-4qit,2015-07-08,2014-06-02
-3qi5,2011-03-09,2011-01-26
-1qi4,1999-11-24,1999-06-01
-2qiv,2007-10-02,2007-07-05
-6qig,2019-09-04,2019-01-18
-5qi3,2019-04-10,2018-05-21
-3qi1,2012-03-28,2011-01-26
-4qiq,2014-08-06,2014-06-01
-2qif,2008-07-08,2007-07-04
-2qiq,2008-02-12,2007-07-05
-6qi3,2019-09-25,2019-01-17
-1qi3,1999-11-24,1999-06-01
-2qi1,2008-04-22,2007-07-03
-4qia,2015-05-13,2014-05-30
-3qio,2011-04-20,2011-01-27
-3qi9,2012-02-15,2011-01-26
-1qip,1999-11-24,1999-06-14
-6qib,2019-04-17,2019-01-18
-3qic,2011-06-01,2011-01-27
-7qim,2022-03-16,2021-12-15
-4qi1,2015-07-29,2014-05-30
-5qiv,2019-12-18,2018-08-10
-2qio,2008-07-08,2007-07-05
-5qih,2018-07-18,2018-05-22
-1qiw,2000-03-28,1999-06-17
-1qiy,1999-06-22,1999-06-18
-5qiq,2019-12-18,2018-08-10
-2qia,2007-10-02,2007-07-03
-4qi5,2015-07-15,2014-05-30
-2qii,2007-07-17,2007-07-04
-4qii,2014-11-19,2014-05-31
-5qiu,2019-12-18,2018-08-10
-3qi4,2011-04-27,2011-01-26
-1qis,2000-06-05,1999-06-15
-4qi9,2014-07-02,2014-05-30
-6qii,2019-10-23,2019-01-19
-4qi3,2015-07-15,2014-05-30
-5qi0,2019-04-10,2018-05-21
-7qi0,2022-11-23,2021-12-14
-6qi8,2019-04-10,2019-01-18
-5qid,2018-07-18,2018-05-22
-6qik,2019-06-26,2019-01-20
-1qia,2003-02-11,1999-06-11
-1qiv,2000-03-28,1999-06-17
-4ix6,2013-10-02,2013-01-24
-2ixa,2007-04-10,2006-07-07
-3ixj,2010-03-02,2009-09-04
-3ixp,2010-12-15,2009-09-04
-8ixz,2024-02-07,2023-04-03
-6ix7,2019-07-17,2018-12-09
-5ixv,2017-08-09,2016-03-23
-2ixf,2006-10-11,2006-07-08
-1ix9,2002-12-17,2002-06-17
-2ixg,2006-10-11,2006-07-08
-4ixk,2013-03-20,2013-01-26
-6ix8,2019-07-17,2018-12-09
-5ixo,2016-04-20,2016-03-23
-4ix5,2013-10-02,2013-01-24
-3ixc,2009-09-22,2009-09-03
-5ix6,2016-07-06,2016-03-23
-2ix0,2006-10-05,2006-07-05
-1ix4,2003-09-02,2002-06-10
-4ix2,2013-02-06,2013-01-24
-6ixj,2019-02-13,2018-12-10
-4ixt,2013-02-20,2013-01-28
-8ix9,2024-04-03,2023-03-31
-4ixn,2013-02-27,2013-01-26
-6ixw,2019-06-19,2018-12-12
-1ixy,2002-12-04,2002-07-09
-3ixe,2009-12-15,2009-09-03
-2ixl,2006-10-26,2006-07-08
-4ixm,2013-02-27,2013-01-26
-4ixv,2013-12-11,2013-01-28
-2ixb,2007-04-10,2006-07-07
-6ixm,2019-04-03,2018-12-11
-8ixd,2023-08-16,2023-03-31
-8ixf,2023-08-16,2023-03-31
-2ixd,2007-07-17,2006-07-07
-4ixh,2013-04-03,2013-01-25
-2ix7,2006-12-13,2006-07-07
-3ixl,2010-02-23,2009-09-04
-8ixh,2024-04-03,2023-04-01
-2ixv,2007-07-03,2006-07-11
-1ixf,2002-12-18,2002-06-20
-8ix7,2024-04-03,2023-03-31
-1ixr,2002-11-06,2002-07-04
-4ixx,2013-12-11,2013-01-28
-2ixh,2006-10-26,2006-07-08
-8ixv,2023-09-13,2023-04-03
-3ix2,2021-07-21,2009-09-03
-1ix3,2003-09-02,2002-06-10
-3ix8,2009-09-15,2009-09-03
-8ixq,2024-04-03,2023-04-02
-8ixm,2024-04-03,2023-04-01
-3ixh,2010-02-16,2009-09-04
-5ixj,2016-08-17,2016-03-23
-4ixd,2014-01-29,2013-01-25
-5ixc,2016-06-08,2016-03-23
-5ixq,2016-04-20,2016-03-23
-2ix1,2006-10-05,2006-07-05
-6ixi,2020-01-15,2018-12-10
-4ix3,2013-10-02,2013-01-24
-4ixg,2013-05-15,2013-01-25
-4ixf,2013-05-29,2013-01-25
-3ixk,2010-09-08,2009-09-04
-1ixz,2002-11-06,2002-07-10
-5ixr,2017-08-09,2016-03-23
-4ixw,2013-02-20,2013-01-28
-5ixz,2017-11-01,2016-03-23
-4ix0,2013-08-21,2013-01-24
-4ixo,2013-02-27,2013-01-27
-2ixp,2006-07-31,2006-07-09
-4ixe,2013-05-29,2013-01-25
-8ixe,2023-08-16,2023-03-31
-6ixn,2019-12-18,2018-12-11
-1ixe,2003-07-29,2002-06-20
-6ixd,2019-05-22,2018-12-10
-5ixw,2017-08-09,2016-03-23
-1ixx,1998-05-06,1997-05-01
-1ix7,2002-07-03,2002-06-14
-8ix6,2024-04-03,2023-03-31
-3ix3,2009-09-15,2009-09-03
-3ixf,2010-05-19,2009-09-03
-2ixk,2006-08-14,2006-07-08
-4ixr,2013-02-20,2013-01-27
-5ix0,2016-08-31,2016-03-23
-5ix2,2016-08-17,2016-03-23
-5ixh,2017-03-22,2016-03-23
-5ixb,2016-08-17,2016-03-23
-8ixa,2023-08-16,2023-03-31
-5ix1,2016-08-17,2016-03-23
-8ix2,2023-09-06,2023-03-31
-4ix4,2013-10-02,2013-01-24
-2ixc,2006-10-26,2006-07-07
-2ix4,2007-02-06,2006-07-06
-5ixt,2016-04-20,2016-03-23
-1ix6,2002-07-03,2002-06-14
-3ix4,2009-09-15,2009-09-03
-2ixu,2007-07-03,2006-07-11
-3ix1,2010-10-13,2009-09-03
-8ixu,2024-05-22,2023-04-03
-8ix0,2023-09-06,2023-03-31
-2ixi,2006-07-11,2006-07-08
-6ix5,2019-07-17,2018-12-09
-6ix3,2019-07-17,2018-12-09
-8ixb,2023-08-16,2023-03-31
-8ixx,2024-04-03,2023-04-03
-6ixr,2019-03-06,2018-12-11
-5ixx,2017-08-09,2016-03-23
-4ixj,2014-01-01,2013-01-25
-5ixk,2016-06-15,2016-03-23
-6ixt,2019-12-18,2018-12-12
-1ix8,2002-07-03,2002-06-14
-5ixe,2016-07-20,2016-03-23
-4ixc,2013-04-24,2013-01-25
-1ixn,2003-02-11,2002-06-28
-1ixs,2002-11-06,2002-07-04
-8ixg,2023-08-16,2023-03-31
-6ix4,2019-12-11,2018-12-09
-2ix6,2006-08-08,2006-07-07
-6ix9,2019-07-17,2018-12-09
-2ix5,2006-08-08,2006-07-07
-5ixg,2017-03-22,2016-03-23
-8ix1,2023-09-06,2023-03-31
-4ixq,2013-02-20,2013-01-27
-8ix8,2024-04-03,2023-03-31
-8ixt,2024-05-22,2023-04-03
-6ixx,2019-12-18,2018-12-12
-3ixg,2010-02-16,2009-09-04
-1ixo,2003-02-11,2002-06-28
-2ixt,2007-08-21,2006-07-11
-4ixu,2013-12-11,2013-01-28
-1ix1,2003-09-09,2002-06-07
-5ixs,2016-09-14,2016-03-23
-8ixs,2023-06-14,2023-04-03
-3ix9,2010-02-02,2009-09-03
-5ixy,2016-09-14,2016-03-23
-3ixa,2010-01-12,2009-09-03
-3ixb,2010-02-16,2009-09-03
-2ixe,2006-10-11,2006-07-07
-1mb0,2002-12-04,2002-08-02
-1mb4,2003-01-07,2002-08-02
-1mbs,1979-05-15,1979-03-22
-4mby,2013-12-04,2013-08-21
-4mbk,2014-07-30,2013-08-19
-3mbp,1997-12-24,1997-06-25
-3mby,2010-06-09,2010-03-26
-3mbh,2010-06-02,2010-03-25
-7mbu,2021-07-07,2021-04-01
-3mbx,2010-06-30,2010-03-26
-4mbp,1998-02-25,1997-08-17
-5mb7,2017-12-20,2016-11-07
-1mbu,2002-12-11,2002-08-03
-5mb9,2016-12-28,2016-11-07
-4mb1,2013-09-25,2013-08-19
-4mbs,2013-09-11,2013-08-19
-5mbk,2017-04-05,2016-11-08
-1mbd,1982-02-03,1981-08-27
-7mb7,2022-06-22,2021-03-31
-4mbl,2013-09-11,2013-08-19
-6mbn,2019-08-14,2018-08-30
-6mbq,2019-07-31,2018-08-30
-1mbo,1982-02-03,1981-08-27
-4mb9,2013-10-16,2013-08-19
-2mbr,1997-04-01,1996-11-08
-5mb4,2017-02-22,2016-11-07
-1mbz,2002-10-23,2002-08-04
-7mbx,2021-05-26,2021-04-01
-4mb3,2014-03-19,2013-08-19
-5mba,1992-07-15,1991-01-14
-4mbu,2014-09-03,2013-08-19
-5mby,2017-12-20,2016-11-09
-6mbk,2018-12-19,2018-08-30
-1mb9,2002-10-23,2002-08-02
-5mbs,2017-12-20,2016-11-08
-6mbt,2019-07-31,2018-08-30
-4mbi,2013-09-18,2013-08-19
-1mbb,1996-10-14,1995-11-07
-6mb7,2018-11-07,2018-08-29
-4mb7,2013-10-30,2013-08-19
-7mbv,2021-07-07,2021-04-01
-7mb5,2022-06-22,2021-03-31
-4mbf,2014-07-30,2013-08-19
-4mbo,2013-11-06,2013-08-19
-7mb8,2022-06-22,2021-03-31
-5mb0,2017-12-20,2016-11-07
-7mby,2021-05-26,2021-04-01
-5mbw,2017-09-27,2016-11-09
-4mb2,2014-08-06,2013-08-19
-6mbf,2018-09-19,2018-08-29
-3mbo,2010-09-29,2010-03-25
-6mb9,2018-11-07,2018-08-29
-1mba,1990-01-15,1989-02-22
-6mb4,2018-11-07,2018-08-29
-1mb2,2003-01-07,2002-08-02
-6mbp,2019-02-27,2018-08-30
-3mbc,2011-04-06,2010-03-25
-6mbd,2019-03-06,2018-08-29
-5mbj,2017-04-05,2016-11-08
-3mbl,2010-07-28,2010-03-25
-4mbg,2014-01-01,2013-08-19
-3mb6,2010-05-05,2010-03-25
-3mbv,2010-11-03,2010-03-26
-4mbe,2014-07-02,2013-08-19
-4mbj,2013-10-02,2013-08-19
-3mbj,2010-05-12,2010-03-25
-5mbe,2017-04-05,2016-11-08
-7mb0,2022-10-12,2021-03-31
-2mb5,1991-04-15,1989-10-11
-6mbj,2018-12-19,2018-08-30
-7mb4,2022-06-22,2021-03-31
-2mbz,2014-12-10,2013-08-12
-5mb1,2017-12-20,2016-11-07
-3mbe,2010-05-12,2010-03-25
-6mbo,2019-02-27,2018-08-30
-7mb6,2022-06-22,2021-03-31
-7mbq,2021-07-07,2021-04-01
-1mb3,2002-12-04,2002-08-02
-6mbv,2019-03-13,2018-08-30
-3mb7,2010-05-05,2010-03-25
-6mb6,2018-11-07,2018-08-29
-7mb9,2022-06-22,2021-03-31
-7mbi,2021-07-21,2021-03-31
-3mbr,2010-06-30,2010-03-25
-6mbg,2018-09-19,2018-08-29
-7mbt,2021-07-07,2021-04-01
-4mbx,2013-12-04,2013-08-21
-6mby,2019-03-13,2018-08-30
-6mbu,2019-07-31,2018-08-30
-1mbi,1991-10-15,1990-06-25
-6mb5,2018-11-07,2018-08-29
-4mb5,2014-03-19,2013-08-19
-7mbs,2021-07-07,2021-04-01
-4mb4,2014-03-19,2013-08-19
-7mbp,2021-09-22,2021-04-01
-4mbc,2013-10-16,2013-08-19
-3mb9,2011-03-09,2010-03-25
-7mbh,2022-11-09,2021-03-31
-1mbn,1976-05-19,1973-04-05
-5mb3,2017-12-20,2016-11-07
-3mbm,2010-04-07,2010-03-25
-5mbn,1989-07-12,1988-01-14
-7mbo,2021-09-15,2021-04-01
-6mb0,2019-06-05,2018-08-29
-1mbt,1996-10-14,1995-11-28
-1mbx,2002-12-11,2002-08-03
-7mbl,2021-04-14,2021-03-31
-3mba,1990-01-15,1989-02-22
-5mbb,2017-04-05,2016-11-08
-5mbx,2017-01-18,2016-11-09
-4mb6,2013-09-04,2013-08-19
-7mb2,2022-10-12,2021-03-31
-7mb3,2022-10-12,2021-03-31
-3mb8,2011-04-06,2010-03-25
-3mbw,2010-06-09,2010-03-26
-3mbi,2011-04-20,2010-03-25
-2mb0,2014-04-09,2013-07-22
-3mbg,2010-07-21,2010-03-25
-7mbr,2021-07-07,2021-04-01
-7mb1,2022-10-12,2021-03-31
-4mbh,2014-07-30,2013-08-19
-4mbn,1989-07-12,1988-01-14
-5mbz,2017-12-20,2016-11-09
-3mb5,2010-05-12,2010-03-25
-5mbd,2017-04-05,2016-11-08
-3mbs,2011-03-30,2010-03-26
-2mbw,1996-12-23,1996-06-20
-7mbw,2022-02-23,2021-04-01
-2mbv,2014-08-20,2013-08-06
-6mb1,2019-06-05,2018-08-29
-4mbz,2013-12-04,2013-08-21
-1mbq,2002-12-11,2002-08-03
-5mbc,2017-04-05,2016-11-08
-1mbc,1989-01-09,1988-09-15
-5mbh,2017-04-05,2016-11-08
-3mbf,2010-04-07,2010-03-25
-3mbz,2011-03-16,2010-03-26
-3mbb,2010-08-18,2010-03-25
-2mbx,2014-08-20,2013-08-07
-4mba,1990-01-15,1989-02-22
-6mbl,2018-12-19,2018-08-30
-5mb5,2018-01-17,2016-11-07
-8qub,2024-03-27,2023-10-16
-4qux,2015-02-04,2014-07-14
-6quy,2019-11-27,2019-02-28
-4qul,2014-11-05,2014-07-10
-6que,2019-08-28,2019-02-27
-8quc,2024-04-03,2023-10-16
-2quz,2007-12-11,2007-08-07
-7qu2,2022-02-09,2022-01-17
-7qu5,2022-02-09,2022-01-17
-2quj,2008-04-29,2007-08-05
-5qud,2021-03-03,2020-01-27
-2qu5,2007-09-25,2007-08-03
-6qua,2019-07-10,2019-02-27
-2qu3,2008-08-05,2007-08-03
-3qui,2012-02-08,2011-02-24
-1qus,1999-09-15,1999-07-03
-3qut,2011-04-13,2011-02-24
-1qut,1999-09-15,1999-07-03
-1qu4,1999-11-17,1999-07-06
-7qu0,2022-02-09,2022-01-17
-3quy,2011-06-29,2011-02-24
-6quq,2019-12-04,2019-02-28
-6qu3,2020-03-18,2019-02-26
-6quc,2020-03-18,2019-02-27
-6qut,2020-03-25,2019-02-28
-3qu3,2011-06-01,2011-02-23
-6qu0,2020-02-05,2019-02-26
-2qua,2007-08-28,2007-08-04
-7qus,2022-06-08,2022-01-18
-2qu2,2008-08-05,2007-08-03
-5que,2021-03-03,2020-01-27
-3qu2,2011-04-27,2011-02-23
-7qup,2022-11-02,2022-01-18
-4quv,2014-10-08,2014-07-12
-4quj,2014-11-05,2014-07-10
-4qub,2014-11-05,2014-07-10
-8quy,2024-03-27,2023-10-17
-3quk,2012-03-21,2011-02-24
-3que,2012-01-18,2011-02-23
-4quq,2015-07-15,2014-07-11
-5qub,2021-03-03,2020-01-27
-4qud,2014-11-05,2014-07-10
-2qu6,2007-09-25,2007-08-03
-5qus,2021-03-03,2020-01-27
-6qun,2019-12-04,2019-02-28
-3qur,2011-07-20,2011-02-24
-5qu8,2020-02-12,2019-12-13
-6quz,2019-05-29,2019-03-01
-6qup,2020-08-05,2019-02-28
-7qun,2022-11-16,2022-01-18
-7qum,2023-03-01,2022-01-18
-2qu9,2007-08-14,2007-08-04
-4qur,2015-07-15,2014-07-11
-7quy,2022-08-17,2022-01-19
-5quf,2021-03-03,2020-01-27
-8qug,2023-12-06,2023-10-16
-2qur,2008-07-29,2007-08-06
-3quq,2011-04-13,2011-02-24
-2qub,2007-08-28,2007-08-04
-7quq,2022-09-21,2022-01-18
-8quw,2024-03-27,2023-10-17
-7qug,2023-01-18,2022-01-18
-3qul,2012-03-21,2011-02-24
-7qud,2022-09-21,2022-01-17
-7quj,2022-12-28,2022-01-18
-6qu9,2020-03-18,2019-02-26
-4qu7,2014-08-13,2014-07-10
-4qum,2014-12-10,2014-07-10
-5qui,2021-03-03,2020-01-27
-6qu4,2020-03-18,2019-02-26
-2qum,2007-12-25,2007-08-06
-7quo,2023-02-01,2022-01-18
-1qu0,1999-12-03,1999-07-05
-7qul,2022-08-17,2022-01-18
-7quf,2022-02-02,2022-01-17
-1qum,1999-08-31,1999-07-01
-4qu9,2014-11-05,2014-07-10
-6qu5,2020-03-18,2019-02-26
-4que,2014-11-05,2014-07-10
-5quj,2021-03-03,2020-01-27
-8qui,2024-03-27,2023-10-16
-4quu,2014-07-30,2014-07-12
-2qu8,2007-08-28,2007-08-03
-1quf,1997-09-17,1996-09-07
-8qud,2024-04-03,2023-10-16
-6qub,2020-03-18,2019-02-27
-6quu,2019-07-31,2019-02-28
-6qu6,2019-09-18,2019-02-26
-3qum,2011-11-09,2011-02-24
-4qui,2014-11-05,2014-07-10
-6qu7,2019-06-05,2019-02-26
-1qua,2000-07-05,1999-06-30
-2qu0,2008-08-05,2007-08-03
-4quh,2014-11-05,2014-07-10
-7qu4,2023-01-25,2022-01-17
-3qu9,2011-04-27,2011-02-23
-7que,2022-02-02,2022-01-17
-4qu6,2014-08-13,2014-07-10
-6quw,2019-07-31,2019-02-28
-8qux,2024-03-27,2023-10-17
-4quf,2014-08-20,2014-07-10
-6qul,2019-04-10,2019-02-27
-4qup,2015-07-15,2014-07-11
-6qu8,2019-09-18,2019-02-26
-5qug,2021-03-03,2020-01-27
-7quw,2022-03-09,2022-01-19
-5quh,2021-03-03,2020-01-27
-3qux,2011-06-29,2011-02-24
-8quh,2024-03-27,2023-10-16
-6qu1,2019-07-17,2019-02-26
-7qu1,2022-02-09,2022-01-17
-3qua,2011-03-09,2011-02-23
-7qu7,2022-11-23,2022-01-17
-3qu4,2011-04-27,2011-02-23
-6qug,2020-05-27,2019-02-27
-3quo,2011-07-20,2011-02-24
-4qu1,2015-07-15,2014-07-10
-4qu5,2014-11-05,2014-07-10
-3qu1,2011-03-09,2011-02-23
-1qu3,1999-08-31,1999-07-06
-8qul,2024-03-27,2023-10-16
-4qug,2014-11-05,2014-07-10
-2qul,2007-12-25,2007-08-06
-7qur,2022-06-01,2022-01-18
-7qux,2022-12-28,2022-01-19
-2qun,2007-12-25,2007-08-06
-7qub,2022-04-27,2022-01-17
-8quj,2024-03-27,2023-10-16
-2que,2007-08-14,2007-08-05
-8qu9,2024-05-15,2023-10-15
-1qur,1999-10-14,1999-07-02
-1qub,1999-10-08,1999-07-01
-6qui,2020-05-27,2019-02-27
-4qu8,2014-11-05,2014-07-10
-4quo,2014-09-10,2014-07-11
-6quv,2019-07-31,2019-02-28
-4quy,2015-02-04,2014-07-14
-8qu8,2023-12-06,2023-10-14
-6qu2,2020-03-18,2019-02-26
-6qus,2019-11-27,2019-02-28
-4qut,2014-07-30,2014-07-12
-7qut,2022-04-13,2022-01-18
-2qui,2008-04-29,2007-08-05
-5quc,2021-03-03,2020-01-27
-6qux,2019-07-31,2019-02-28
-7quv,2023-02-01,2022-01-19
-6qud,2020-03-18,2019-02-27
-6quh,2020-05-27,2019-02-27
-4qua,2014-11-05,2014-07-10
-4qu2,2015-07-15,2014-07-10
-3quz,2011-06-29,2011-02-24
-3qun,2011-07-20,2011-02-24
-7quk,2022-11-23,2022-01-18
-6quj,2020-05-27,2019-02-27
-1qu2,1999-08-31,1999-07-06
-3qu7,2011-04-27,2011-02-23
-5qut,2021-03-03,2020-01-27
-1que,1997-05-15,1996-07-06
-3qup,2011-12-21,2011-02-24
-4qu3,2014-12-31,2014-07-10
-2qu1,2007-09-11,2007-08-03
-3qu8,2011-09-21,2011-02-23
-7quc,2022-09-21,2022-01-17
-7qu3,2022-02-09,2022-01-17
-7qu9,2023-01-25,2022-01-17
-3qu6,2011-06-01,2011-02-23
-2quh,2008-04-29,2007-08-05
-3qus,2011-12-14,2011-02-24
-8quk,2024-03-27,2023-10-16
-3qu0,2012-10-31,2011-02-23
-5qur,2021-03-03,2020-01-27
-6qum,2019-08-28,2019-02-27
-6quf,2019-03-13,2019-02-27
-4qu0,2014-11-05,2014-07-10
-7qui,2023-01-18,2022-01-18
-6quk,2019-03-13,2019-02-27
-5qu0,2020-02-05,2019-11-19
-3qud,2012-04-11,2011-02-23
-6vow,2021-02-03,2020-01-31
-6vok,2020-09-09,2020-01-30
-3vom,2012-02-22,2012-01-30
-5vob,2017-07-05,2017-05-02
-5voi,2017-05-24,2017-05-02
-5voe,2018-06-20,2017-05-02
-5voo,2018-01-17,2017-05-03
-7voo,2022-10-19,2021-10-14
-7vob,2022-05-04,2021-10-13
-7vo7,2022-08-17,2021-10-12
-6voj,2020-09-09,2020-01-30
-3vob,2012-08-29,2012-01-20
-6vot,2020-05-13,2020-01-31
-7voe,2021-12-22,2021-10-13
-2vot,2008-04-01,2008-02-20
-2vo2,2008-04-08,2008-02-08
-5voj,2017-06-21,2017-05-03
-6vou,2021-06-02,2020-01-31
-3vo8,2012-08-29,2012-01-20
-7vot,2022-04-27,2021-10-14
-2vo4,2008-12-02,2008-02-08
-2voj,2008-03-04,2008-02-18
-6vox,2021-02-03,2020-01-31
-7vo0,2022-08-03,2021-10-12
-2vop,2008-05-06,2008-02-19
-6vol,2020-09-09,2020-01-30
-6vof,2020-09-09,2020-01-30
-2vou,2008-05-13,2008-02-21
-6voh,2020-09-09,2020-01-30
-5vo6,2017-05-31,2017-05-02
-5vod,2017-07-05,2017-05-02
-3voz,2012-06-13,2012-02-23
-3vo2,2012-12-05,2012-01-18
-5vo1,2017-10-04,2017-05-01
-2von,2008-05-06,2008-02-19
-6voi,2020-09-09,2020-01-30
-5vog,2017-05-24,2017-05-02
-6vo6,2020-04-01,2020-01-30
-6voy,2020-07-01,2020-02-01
-6vog,2020-09-09,2020-01-30
-2vor,2008-07-01,2008-02-19
-2vo9,2008-02-19,2008-02-09
-3voa,2012-08-29,2012-01-20
-1vot,1997-06-16,1996-06-23
-5vo3,2018-07-25,2017-05-01
-2vow,2008-03-18,2008-02-22
-2voo,2008-05-06,2008-02-19
-5vol,2017-07-19,2017-05-03
-3voi,2012-03-21,2012-01-24
-6voo,2020-09-09,2020-01-30
-7vod,2021-12-22,2021-10-13
-5voc,2017-07-05,2017-05-02
-6vo2,2020-04-08,2020-01-29
-6vo8,2020-03-25,2020-01-30
-7voy,2022-05-04,2021-10-15
-6vov,2020-03-11,2020-01-31
-3voo,2013-02-06,2012-01-31
-6vo1,2020-07-01,2020-01-29
-7vo1,2022-03-30,2021-10-12
-6voq,2020-02-19,2020-01-31
-3vol,2012-05-23,2012-01-27
-2vo6,2008-04-08,2008-02-08
-7vo5,2022-01-19,2021-10-12
-7vox,2022-08-17,2021-10-15
-6vod,2020-05-13,2020-01-30
-3voh,2012-03-21,2012-01-24
-3vow,2012-10-03,2012-02-22
-3vot,2012-11-07,2012-02-08
-3vov,2012-06-27,2012-02-21
-6vo3,2020-09-23,2020-01-29
-6vom,2020-09-09,2020-01-30
-5vop,2018-01-17,2017-05-03
-7vok,2022-10-19,2021-10-14
-3vof,2012-03-21,2012-01-23
-3voc,2013-02-20,2012-01-21
-8voi,2024-05-15,2024-01-15
-1vom,1996-12-23,1995-11-09
-2vo7,2008-04-08,2008-02-08
-2vos,2008-07-01,2008-02-19
-7voc,2022-05-04,2021-10-13
-5vom,2017-08-02,2017-05-03
-7vo8,2022-09-21,2021-10-12
-7vor,2022-04-27,2021-10-14
-5vo2,2017-10-04,2017-05-01
-3vo0,2012-02-22,2012-01-18
-5vo0,2017-12-06,2017-05-01
-3vo1,2012-12-05,2012-01-18
-2vo0,2008-04-08,2008-02-08
-3vo3,2013-03-06,2012-01-19
-3vou,2012-05-02,2012-02-10
-6voe,2020-05-13,2020-01-30
-5vof,2018-06-13,2017-05-02
-2vod,2008-05-06,2008-02-15
-7vo9,2022-08-03,2021-10-13
-6vo0,2020-07-01,2020-01-29
-2vo3,2008-04-08,2008-02-08
-6von,2020-09-09,2020-01-30
-7voa,2022-08-10,2021-10-13
-6vor,2020-09-16,2020-01-31
-2vo5,2008-04-01,2008-02-08
-5vo8,2017-05-24,2017-05-02
-2vov,2008-03-18,2008-02-22
-5vo4,2018-03-14,2017-05-02
-2vox,2008-03-18,2008-02-22
-7voj,2021-12-01,2021-10-14
-5voh,2017-08-02,2017-05-02
-11gs,1999-01-13,1997-11-03
-2llq,2012-02-01,2011-11-15
-1ll5,2002-11-27,2002-04-26
-5llh,2017-08-16,2016-07-27
-5ll5,2017-08-16,2016-07-26
-7lli,2021-11-17,2021-02-04
-4ll0,2013-09-11,2013-07-09
-3ll2,2010-10-06,2010-01-28
-2ll4,2012-04-04,2011-10-26
-1lls,2002-09-18,2002-04-30
-6llx,2020-11-25,2019-12-24
-4ll2,2013-10-02,2013-07-09
-3ll3,2010-03-23,2010-01-28
-4llg,2013-11-13,2013-07-09
-5lly,2017-03-15,2016-07-28
-7ll1,2021-03-17,2021-02-03
-3lll,2010-05-26,2010-01-29
-6ll2,2020-06-10,2019-12-21
-7llq,2022-06-22,2021-02-04
-1ll4,2002-09-25,2002-04-26
-6ll7,2020-03-25,2019-12-21
-3ll4,2010-03-09,2010-01-28
-3llt,2010-08-04,2010-01-29
-7ll4,2022-01-12,2021-02-03
-1llc,1989-07-12,1988-11-21
-6llk,2021-01-27,2019-12-23
-4llt,2013-07-24,2013-07-09
-3llf,2010-06-16,2010-01-29
-7lld,2021-09-22,2021-02-03
-6ll8,2020-03-25,2019-12-21
-7llb,2021-05-26,2021-02-03
-5ll9,2017-08-16,2016-07-27
-4ll7,2014-02-12,2013-07-09
-1llf,2003-01-07,2002-04-28
-5ll6,2017-04-12,2016-07-26
-5llp,2017-08-16,2016-07-28
-5llo,2017-08-16,2016-07-28
-1llq,2002-05-08,2002-04-29
-7ll2,2021-03-17,2021-02-03
-7ll5,2022-01-12,2021-02-03
-6llh,2021-01-27,2019-12-23
-5ll8,2017-08-16,2016-07-27
-5lld,2016-10-19,2016-07-27
-4llp,2014-02-26,2013-07-09
-4lls,2013-07-24,2013-07-09
-3lle,2010-12-29,2010-01-28
-4llf,2013-10-30,2013-07-09
-1ll1,1997-08-20,1997-03-17
-3lli,2010-03-23,2010-01-29
-1llu,2003-11-11,2002-04-30
-6llm,2021-01-27,2019-12-23
-3llk,2010-03-31,2010-01-29
-6lla,2020-07-29,2019-12-22
-6ll4,2021-01-27,2019-12-21
-7ll3,2021-03-31,2021-02-03
-3llp,2010-04-07,2010-01-29
-7lla,2021-03-03,2021-02-03
-6llb,2020-01-01,2019-12-22
-7llj,2021-11-17,2021-02-04
-7llf,2021-02-24,2021-02-03
-5ll7,2018-02-21,2016-07-26
-1ll2,2002-05-15,2002-04-26
-4llj,2014-02-26,2013-07-09
-1llw,2002-07-31,2002-04-30
-1ll9,2002-10-02,2002-04-26
-5llu,2017-04-19,2016-07-28
-6lly,2020-08-26,2019-12-24
-5ll4,2017-08-16,2016-07-26
-2llo,2012-02-01,2011-11-15
-3lla,2010-03-16,2010-01-28
-4lly,2014-01-29,2013-07-09
-1llr,2002-08-14,2002-04-30
-6llz,2020-09-09,2019-12-24
-7ll6,2021-03-03,2021-02-03
-4ll3,2014-04-16,2013-07-09
-6llc,2020-11-25,2019-12-23
-4llh,2014-05-07,2013-07-09
-3llz,2010-09-22,2010-01-29
-3llu,2010-02-09,2010-01-29
-7llk,2021-06-02,2021-02-04
-3llx,2010-02-09,2010-01-29
-5lle,2017-08-16,2016-07-27
-5llb,2017-10-11,2016-07-27
-4ll5,2014-02-12,2013-07-09
-7llz,2021-02-24,2021-02-04
-1llo,1996-03-08,1995-11-08
-1llp,1996-03-08,1995-11-09
-6llf,2021-01-27,2019-12-23
-5lli,2016-11-09,2016-07-27
-3ll8,2011-01-12,2010-01-28
-2lli,2012-03-21,2011-11-10
-5lla,2017-08-16,2016-07-27
-6ll1,2021-01-27,2019-12-21
-1lld,1994-01-31,1992-06-08
-7llh,2021-05-26,2021-02-03
-5llt,2016-11-30,2016-07-28
-6ll5,2020-02-26,2019-12-21
-5lls,2016-09-14,2016-07-28
-4llx,2014-02-26,2013-07-09
-1llb,2002-10-02,2002-04-26
-5llg,2017-08-16,2016-07-27
-6lle,2020-08-26,2019-12-23
-1lla,1994-01-31,1992-09-07
-2ll8,2011-11-30,2011-10-31
-6ll0,2021-01-27,2019-12-21
-1llz,2002-07-31,2002-04-30
-5lln,2017-08-16,2016-07-28
-3lld,2010-06-16,2010-01-28
-7ll7,2021-08-04,2021-02-03
-6ll9,2020-07-15,2019-12-22
-3ll9,2010-06-02,2010-01-28
-4llk,2014-02-26,2013-07-09
-1llm,2003-09-30,2002-04-29
-7lle,2021-09-22,2021-02-03
-5llx,2017-03-15,2016-07-28
-5llc,2017-08-16,2016-07-27
-5ll3,2017-04-12,2016-07-26
-3llm,2010-05-12,2010-01-29
-6llw,2020-08-05,2019-12-23
-5llw,2017-03-15,2016-07-28
-4llb,2013-10-16,2013-07-09
-5llm,2017-04-19,2016-07-27
-6ll6,2020-02-26,2019-12-21
-7llp,2022-02-23,2021-02-04
-3ll5,2010-06-02,2010-01-28
-5llz,2017-08-16,2016-07-28
-4oqh,2015-05-20,2014-02-09
-1oqh,2003-03-18,2003-03-10
-7oqg,2022-06-22,2021-06-03
-3oqj,2011-02-23,2010-09-03
-2oqa,2007-05-29,2007-01-31
-8oq6,2023-08-30,2023-04-11
-7oqh,2022-02-09,2021-06-03
-2oqi,2007-04-03,2007-01-31
-4oqj,2014-03-19,2014-02-09
-7oqf,2022-04-13,2021-06-03
-8oqt,2024-01-24,2023-04-12
-8oqs,2024-01-24,2023-04-12
-3oqf,2010-10-13,2010-09-03
-7oqj,2022-06-22,2021-06-03
-7oq9,2022-08-10,2021-06-02
-8oq8,2023-08-30,2023-04-11
-7oqr,2022-06-22,2021-06-04
-8oqz,2024-04-24,2023-04-12
-5oqd,2017-11-01,2017-08-11
-1oq9,2003-05-13,2003-03-07
-4oqd,2014-02-26,2014-02-08
-7oqx,2021-11-03,2021-06-04
-7oqm,2022-04-13,2021-06-03
-4oqo,2014-03-12,2014-02-10
-8oqn,2024-01-24,2023-04-12
-2oqr,2007-10-16,2007-02-01
-5oqt,2018-02-14,2017-08-14
-1oqu,2004-04-20,2003-03-11
-6oqy,2019-08-28,2019-04-29
-4oq7,2014-02-26,2014-02-07
-3oq5,2010-09-22,2010-09-02
-1oqg,2003-03-18,2003-03-09
-3oq6,2010-11-10,2010-09-02
-4oqx,2014-08-13,2014-02-10
-1oqc,2003-04-15,2003-03-07
-7oql,2021-10-20,2021-06-03
-7oqu,2022-06-22,2021-06-04
-6oqr,2020-06-03,2019-04-29
-1oq4,2003-05-13,2003-03-07
-4oqi,2015-05-20,2014-02-09
-3oq2,2010-12-22,2010-09-02
-1oql,2003-07-01,2003-03-10
-4oqm,2014-08-13,2014-02-10
-6oqd,2019-05-15,2019-04-26
-6oq5,2019-07-10,2019-04-25
-4oqc,2014-12-24,2014-02-08
-6oqa,2020-04-29,2019-04-26
-7oqo,2021-10-20,2021-06-03
-3oqu,2011-09-14,2010-09-04
-6oqs,2020-06-03,2019-04-29
-5oqw,2018-06-27,2017-08-14
-8oqp,2024-01-24,2023-04-12
-4oqg,2015-05-20,2014-02-09
-8oq9,2023-08-23,2023-04-11
-2oqv,2007-04-24,2007-02-01
-7oq7,2022-06-22,2021-06-02
-1oq7,2003-05-13,2003-03-07
-3oq3,2011-05-18,2010-09-02
-8oq2,2024-04-24,2023-04-10
-6oqt,2020-06-03,2019-04-29
-8oqd,2023-06-14,2023-04-12
-3oq1,2011-07-20,2010-09-02
-8oqx,2023-08-02,2023-04-12
-4oqn,2014-08-13,2014-02-10
-8oqy,2024-04-24,2023-04-12
-7oqs,2022-06-22,2021-06-04
-1oqm,2003-03-18,2003-03-10
-3oqe,2011-11-02,2010-09-02
-8oqr,2024-01-24,2023-04-12
-8oq3,2024-02-21,2023-04-11
-5oqm,2018-05-09,2017-08-13
-6oq4,2020-06-24,2019-04-25
-1oq5,2004-03-23,2003-03-07
-8oqc,2023-06-14,2023-04-12
-3oqq,2011-09-14,2010-09-03
-1oqo,2003-03-20,2003-03-10
-5oq5,2017-10-25,2017-08-10
-7oqw,2022-06-22,2021-06-04
-7oqd,2021-10-27,2021-06-03
-8oqv,2024-01-24,2023-04-12
-7oqy,2021-08-25,2021-06-04
-6oqz,2019-12-11,2019-04-29
-6oql,2020-07-29,2019-04-26
-3oqt,2011-07-20,2010-09-04
-6oqb,2019-05-15,2019-04-26
-7oqa,2022-08-10,2021-06-02
-4oq0,2015-05-20,2014-02-07
-7oq2,2022-06-22,2021-06-02
-7oqp,2021-10-20,2021-06-03
-4oq3,2014-04-23,2014-02-07
-3oqg,2010-10-20,2010-09-03
-4oq6,2014-03-12,2014-02-07
-3oqr,2010-10-13,2010-09-03
-8oqf,2023-06-14,2023-04-12
-2oq6,2007-03-13,2007-01-31
-4oqy,2014-10-22,2014-02-10
-6oqq,2019-05-15,2019-04-28
-2oqy,2007-03-06,2007-02-01
-7oq6,2022-06-22,2021-06-02
-2oqu,2007-05-01,2007-02-01
-6oqm,2019-05-29,2019-04-26
-2oq2,2008-01-15,2007-01-31
-6oqv,2020-06-03,2019-04-29
-7oqi,2022-04-13,2021-06-03
-7oqq,2021-12-08,2021-06-04
-6oqo,2020-07-29,2019-04-26
-2oqe,2007-04-10,2007-01-31
-6oqw,2020-06-24,2019-04-29
-4oqp,2014-06-04,2014-02-10
-7oq4,2021-08-25,2021-06-02
-8oqm,2024-01-24,2023-04-12
-3oq8,2010-09-15,2010-09-02
-8oqu,2024-01-24,2023-04-12
-4oq4,2014-02-19,2014-02-07
-4oqa,2014-07-02,2014-02-07
-5oq8,2017-10-25,2017-08-10
-5oqu,2018-02-28,2017-08-14
-8oqh,2023-11-29,2023-04-12
-4oql,2014-08-13,2014-02-10
-7oqk,2022-04-13,2021-06-03
-3oqs,2011-07-27,2010-09-03
-8oqe,2023-06-14,2023-04-12
-5oq6,2017-10-25,2017-08-10
-8oq7,2023-08-30,2023-04-11
-6oqi,2020-07-29,2019-04-26
-8oqj,2024-02-07,2023-04-12
-7oq8,2022-06-22,2021-06-02
-2oq1,2007-03-06,2007-01-30
-5oql,2017-10-11,2017-08-12
-4oqt,2014-05-14,2014-02-10
-4oqb,2014-07-02,2014-02-07
-1oqn,2003-08-05,2003-03-10
-7oq1,2022-06-22,2021-06-02
-2oqx,2007-02-20,2007-02-01
-5oqj,2018-04-25,2017-08-11
-2oql,2008-02-19,2007-01-31
-4oqv,2014-06-04,2014-02-10
-8oqa,2023-08-30,2023-04-11
-3oqk,2010-10-27,2010-09-03
-6oqn,2019-05-15,2019-04-26
-6oq3,2020-06-24,2019-04-25
-4oqr,2015-02-18,2014-02-10
-4oqs,2015-02-18,2014-02-10
-5oq4,2017-09-06,2017-08-10
-1oqx,2003-03-25,2003-03-11
-6oq7,2019-07-10,2019-04-25
-6oqx,2019-08-28,2019-04-29
-5oq1,2018-01-17,2017-08-10
-4oq8,2014-09-10,2014-02-07
-1oq6,2003-09-16,2003-03-07
-1oqb,2003-05-13,2003-03-07
-4oq9,2014-09-10,2014-02-07
-6oqc,2019-05-15,2019-04-26
-1oqj,2003-11-11,2003-03-10
-7oqn,2022-04-13,2021-06-03
-2oqj,2008-01-15,2007-01-31
-8oqo,2024-01-24,2023-04-12
-2oq7,2007-03-13,2007-01-31
-8oqq,2024-01-24,2023-04-12
-4oq5,2014-03-12,2014-02-07
-2oq4,2008-02-26,2007-01-31
-4oqe,2014-02-26,2014-02-08
-5oq7,2017-10-25,2017-08-10
-6oqu,2020-06-03,2019-04-29
-8t9a,2024-04-10,2023-06-23
-5t9r,2016-10-12,2016-09-09
-8t90,2023-11-15,2023-06-23
-7t94,2023-01-25,2021-12-17
-7t9u,2022-12-21,2021-12-20
-6t9a,2020-04-22,2019-10-26
-1t9h,2004-11-02,2004-05-17
-8t9x,2024-02-21,2023-06-26
-5t9s,2016-10-12,2016-09-09
-7t92,2022-07-06,2021-12-17
-7t90,2023-01-25,2021-12-17
-7t9v,2022-12-21,2021-12-20
-1t9b,2004-12-21,2004-05-16
-6t95,2020-11-18,2019-10-25
-7t9x,2022-06-29,2021-12-20
-6t99,2020-04-22,2019-10-26
-5t9k,2017-08-30,2016-09-09
-6t9p,2020-07-15,2019-10-28
-3t9v,2011-08-17,2011-08-03
-1t9r,2004-08-03,2004-05-18
-5t9x,2017-09-13,2016-09-09
-1t9v,2005-10-04,2004-05-18
-5t9m,2016-10-12,2016-09-09
-1t96,2005-06-14,2004-05-14
-6t92,2020-11-18,2019-10-25
-5t96,2017-03-22,2016-09-09
-8t96,2023-11-15,2023-06-23
-5t9z,2017-01-25,2016-09-09
-7t9h,2022-04-06,2021-12-19
-1t9n,2005-01-25,2004-05-18
-1t9o,2004-10-05,2004-05-18
-7t9d,2023-01-25,2021-12-18
-7t9c,2023-01-25,2021-12-18
-3t90,2012-04-11,2011-08-02
-6t9o,2019-11-20,2019-10-28
-1t91,2005-05-17,2004-05-14
-1t90,2006-01-03,2004-05-14
-7t9a,2022-09-28,2021-12-18
-8t93,2023-11-15,2023-06-23
-5t9c,2016-11-02,2016-09-09
-6t9r,2020-02-12,2019-10-28
-6t9x,2020-09-09,2019-10-29
-1t92,2004-10-05,2004-05-14
-1t93,2005-01-25,2004-05-14
-1t9z,2004-08-31,2004-05-19
-6t9t,2020-11-18,2019-10-28
-1t9d,2004-12-21,2004-05-16
-5t9j,2016-09-21,2016-09-09
-5t97,2017-03-29,2016-09-09
-6t98,2020-11-18,2019-10-26
-5t90,2017-04-12,2016-09-08
-7t9t,2023-08-16,2021-12-20
-7t9l,2021-12-29,2021-12-19
-1t9g,2004-06-08,2004-05-17
-3t9k,2012-07-18,2011-08-03
-3t9g,2012-05-09,2011-08-02
-1t99,2005-06-14,2004-05-16
-3t9o,2012-09-05,2011-08-03
-5t99,2017-09-13,2016-09-09
-1t9w,2005-10-04,2004-05-18
-6t9v,2020-11-18,2019-10-28
-5t9g,2017-09-13,2016-09-09
-3t9d,2011-12-07,2011-08-02
-3t9i,2011-10-12,2011-08-02
-7t9n,2022-08-03,2021-12-19
-3t9q,2011-12-07,2011-08-03
-7t9j,2021-12-29,2021-12-19
-7t9b,2022-09-28,2021-12-18
-3t9e,2011-12-07,2011-08-02
-8t95,2023-11-15,2023-06-23
-3t99,2011-12-07,2011-08-02
-3t93,2011-08-17,2011-08-02
-7t96,2023-01-25,2021-12-18
-5t95,2017-06-28,2016-09-09
-3t9t,2011-10-12,2011-08-03
-6t9y,2019-12-11,2019-10-29
-1t9i,2004-11-16,2004-05-17
-6t9b,2020-04-22,2019-10-26
-5t9n,2016-10-12,2016-09-09
-8t92,2023-11-15,2023-06-23
-1t9q,2004-10-05,2004-05-18
-3t91,2011-12-07,2011-08-02
-6t97,2020-11-18,2019-10-26
-6t9c,2020-02-26,2019-10-27
-6t9n,2019-11-20,2019-10-28
-1t9u,2005-10-04,2004-05-18
-3t9w,2012-08-29,2011-08-03
-7t9e,2023-01-25,2021-12-18
-6t9l,2020-01-29,2019-10-28
-8t9u,2023-11-29,2023-06-26
-1t9a,2004-12-21,2004-05-16
-5t93,2017-09-13,2016-09-09
-5t9y,2017-03-22,2016-09-09
-6t96,2019-12-25,2019-10-26
-5t91,2016-11-02,2016-09-09
-3t9b,2011-12-07,2011-08-02
-7t9o,2022-04-06,2021-12-19
-7t9y,2022-06-22,2021-12-20
-6t9f,2020-11-18,2019-10-28
-5t9q,2017-08-30,2016-09-09
-3t9u,2011-08-17,2011-08-03
-5t92,2017-03-29,2016-09-09
-3t95,2011-12-07,2011-08-02
-7t9k,2021-12-29,2021-12-19
-1t9p,2004-10-05,2004-05-18
-1t9y,2005-10-04,2004-05-19
-5t9t,2016-10-19,2016-09-09
-3t94,2011-08-24,2011-08-02
-5t9e,2017-06-28,2016-09-09
-5t9u,2017-01-25,2016-09-09
-8t94,2024-05-08,2023-06-23
-8t9c,2023-08-23,2023-06-23
-5t9b,2016-11-02,2016-09-09
-7t9m,2022-08-10,2021-12-19
-1t9c,2004-12-21,2004-05-16
-6t94,2020-11-18,2019-10-25
-6t9u,2020-11-18,2019-10-28
-1t9x,2005-10-04,2004-05-19
-5t9w,2017-01-25,2016-09-09
-3t9a,2011-12-07,2011-08-02
-7t9r,2023-01-18,2021-12-19
-8t98,2023-11-15,2023-06-23
-6t9g,2020-11-18,2019-10-28
-1t9s,2004-08-03,2004-05-18
-1t9m,2004-11-02,2004-05-18
-7t9i,2022-08-03,2021-12-19
-3t92,2012-08-08,2011-08-02
-7t9z,2022-05-04,2021-12-20
-7t91,2022-12-21,2021-12-17
-6t9s,2020-07-15,2019-10-28
-3t9x,2011-08-17,2011-08-03
-8t9f,2023-09-06,2023-06-23
-8t99,2023-11-15,2023-06-23
-7t9g,2022-05-25,2021-12-19
-6t9w,2020-08-05,2019-10-29
-8t9v,2024-05-01,2023-06-26
-5t9i,2017-08-30,2016-09-09
-3t96,2011-08-17,2011-08-02
-3t9h,2011-08-17,2011-08-02
-5t9f,2017-06-28,2016-09-09
-5t9v,2016-10-12,2016-09-09
-3wtr,2015-04-01,2014-04-19
-6wtq,2021-05-05,2020-05-03
-2wt9,2009-11-10,2009-09-15
-2wtw,2010-01-26,2009-09-24
-7wtq,2022-10-19,2022-02-05
-2wta,2009-11-10,2009-09-15
-4wtb,2015-11-11,2014-10-29
-6wt4,2020-09-09,2020-05-01
-1wtg,2005-11-23,2004-11-23
-2wth,2010-04-21,2009-09-16
-2wtf,2010-03-31,2009-09-16
-5wt2,2017-12-13,2016-12-09
-3wtg,2014-07-02,2014-04-11
-7wt5,2022-06-22,2022-02-03
-2wtc,2009-12-29,2009-09-15
-7wta,2022-11-09,2022-02-04
-4wt8,2015-01-21,2014-10-29
-7wtp,2022-10-19,2022-02-05
-8wtd,2023-12-13,2023-10-18
-1wta,2006-02-07,2004-11-18
-7wtb,2022-11-09,2022-02-04
-4wtm,2015-02-11,2014-10-30
-4wtf,2015-02-11,2014-10-30
-1wtf,2005-11-08,2004-11-22
-3wtq,2015-04-15,2014-04-15
-4wtq,2015-12-23,2014-10-30
-5wtd,2017-12-20,2016-12-11
-8wtf,2023-11-15,2023-10-18
-5wtl,2017-12-13,2016-12-13
-4wt1,2015-06-10,2014-10-29
-4wt7,2014-11-12,2014-10-29
-2wt0,2010-08-11,2009-09-10
-2wto,2010-08-18,2009-09-18
-3wt7,2014-06-11,2014-04-08
-5wtq,2017-03-22,2016-12-13
-7wtz,2022-10-19,2022-02-05
-1wt2,2004-12-07,2004-11-12
-5wt1,2017-12-13,2016-12-09
-5wtr,2017-04-05,2016-12-14
-5wt9,2017-02-15,2016-12-10
-3wt4,2014-04-16,2014-04-07
-6wth,2020-08-12,2020-05-02
-6wts,2020-07-08,2020-05-03
-1wt9,2006-03-07,2004-11-18
-1wto,2005-02-22,2004-11-29
-3wtl,2015-02-04,2014-04-11
-1wtq,2005-02-22,2004-11-29
-3wtm,2015-02-04,2014-04-11
-2wti,2009-12-29,2009-09-16
-4wtc,2015-02-11,2014-10-29
-4wtl,2015-02-11,2014-10-30
-3wtn,2015-02-04,2014-04-11
-4wtj,2015-02-11,2014-10-30
-2wtg,2010-04-21,2009-09-16
-6wtf,2020-12-23,2020-05-02
-1wth,2005-03-08,2004-11-23
-7wt2,2022-04-13,2022-02-03
-2wtk,2009-12-15,2009-09-16
-4wtk,2015-02-11,2014-10-30
-3wt3,2015-04-29,2014-04-07
-6wtj,2020-05-20,2020-05-02
-1wtx,2005-02-22,2004-11-29
-7wti,2022-12-21,2022-02-04
-2wtn,2010-01-19,2009-09-17
-4wte,2015-02-11,2014-10-29
-6wtx,2020-09-16,2020-05-04
-7wtr,2022-10-19,2022-02-05
-6wtn,2021-05-05,2020-05-03
-4wtv,2015-07-15,2014-10-30
-2wtx,2010-02-23,2009-09-25
-4wti,2015-02-11,2014-10-30
-7wtn,2022-10-19,2022-02-05
-3wtk,2015-02-04,2014-04-11
-4wth,2016-03-09,2014-10-30
-7wtw,2022-10-19,2022-02-05
-1wtw,2005-02-22,2004-11-29
-1wtr,2005-02-22,2004-11-29
-1wtc,2005-11-01,2004-11-22
-4wtz,2015-11-04,2014-10-30
-7wtc,2022-11-09,2022-02-04
-6wta,2021-05-05,2020-05-01
-7wtf,2022-12-14,2022-02-04
-1wtv,2005-02-22,2004-11-29
-7wtx,2022-10-19,2022-02-05
-3wtj,2015-02-04,2014-04-11
-1wt1,2004-12-07,2004-11-12
-1wt0,2004-12-07,2004-11-12
-4wtu,2015-03-04,2014-10-30
-1wte,2004-12-14,2004-11-22
-3wt5,2014-06-11,2014-04-08
-2wtd,2009-12-29,2009-09-15
-5wt3,2017-12-13,2016-12-09
-7wt1,2022-04-13,2022-02-03
-2wt1,2010-08-11,2009-09-10
-5wtz,2017-03-01,2016-12-15
-6wte,2020-12-23,2020-05-02
-3wto,2015-02-04,2014-04-11
-7wt8,2023-06-07,2022-02-04
-5wt5,2017-12-13,2016-12-09
-7wtl,2022-10-19,2022-02-05
-7wt7,2023-06-07,2022-02-04
-2wtv,2010-01-26,2009-09-22
-8wtb,2024-05-08,2023-10-18
-2wtp,2010-08-18,2009-09-18
-4wt2,2014-12-03,2014-10-30
-7wtm,2022-10-19,2022-02-05
-6wt2,2020-05-13,2020-05-01
-8wtc,2024-05-08,2023-10-18
-5wt6,2017-12-13,2016-12-09
-7wte,2022-11-09,2022-02-04
-1wtb,2005-04-05,2004-11-22
-7wt4,2022-06-22,2022-02-03
-8wtq,2024-05-22,2023-10-19
-2wts,2010-09-01,2009-09-21
-3wt6,2014-06-11,2014-04-08
-4wt6,2015-02-11,2014-10-29
-5wt4,2017-12-13,2016-12-09
-7wtk,2022-12-14,2022-02-04
-7wt3,2022-06-22,2022-02-03
-7wtd,2022-11-09,2022-02-04
-7wt0,2022-04-13,2022-02-03
-5wtc,2017-01-25,2016-12-11
-6wtt,2020-05-20,2020-05-03
-8wtr,2024-05-22,2023-10-19
-4wtr,2015-08-12,2014-10-30
-1wtp,2005-02-22,2004-11-29
-6wti,2021-01-20,2020-05-02
-3wti,2015-02-04,2014-04-11
-8wte,2024-05-01,2023-10-18
-4wty,2015-11-04,2014-10-30
-6wtk,2020-05-20,2020-05-03
-4wts,2015-08-12,2014-10-30
-2wt4,2009-11-24,2009-09-11
-6wto,2021-05-05,2020-05-03
-1wt3,2004-12-03,2004-11-12
-8wt1,2024-03-13,2023-10-17
-2wtl,2009-12-15,2009-09-17
-4wt0,2015-05-06,2014-10-29
-5wtt,2017-12-20,2016-12-14
-2wtu,2010-02-09,2009-09-22
-4wtg,2015-02-11,2014-10-30
-6wt7,2020-09-09,2020-05-01
-7wtt,2022-10-19,2022-02-05
-3wt0,2015-04-29,2014-03-31
-7wtv,2022-10-19,2022-02-05
-2wt2,2010-08-11,2009-09-10
-6wtb,2021-05-05,2020-05-02
-4wta,2015-02-11,2014-10-29
-5wti,2017-11-01,2016-12-13
-7wtu,2022-10-19,2022-02-05
-7wto,2022-10-19,2022-02-05
-6wtp,2021-05-05,2020-05-03
-4wtd,2015-02-11,2014-10-29
-3wth,2015-02-04,2014-04-11
-2wtr,2009-09-29,2009-09-21
-2wtj,2009-12-29,2009-09-16
-2wtz,2009-12-15,2009-09-25
-8bqg,2023-01-18,2022-11-21
-7bqg,2020-09-23,2020-03-24
-3bq1,2008-04-08,2007-12-19
-2bq1,2006-05-17,2005-04-26
-8bqj,2023-01-18,2022-11-21
-3bqf,2008-02-19,2007-12-20
-4bqs,2013-08-07,2013-06-02
-1bqh,1998-08-19,1998-08-16
-8bqe,2022-12-28,2022-11-21
-4bqi,2014-02-19,2013-05-30
-6bqo,2018-03-07,2017-11-28
-1bqi,1999-08-16,1998-08-16
-4bq3,2013-08-14,2013-05-29
-4bqh,2013-07-17,2013-05-30
-5bqy,2015-08-12,2015-05-29
-4bqo,2013-11-06,2013-05-31
-1bqy,1999-08-20,1998-08-20
-4bq6,2013-06-12,2013-05-30
-6bqa,2018-11-14,2017-11-27
-4bqg,2013-10-23,2013-05-30
-5bq6,2015-08-26,2015-05-28
-8bqp,2023-03-08,2022-11-21
-8bqk,2023-01-18,2022-11-21
-6bq1,2017-12-13,2017-11-27
-7bq0,2020-11-11,2020-03-23
-1bq4,1998-08-26,1998-08-20
-8bqa,2023-11-29,2022-11-20
-6bqr,2017-12-20,2017-11-28
-1bq5,1999-08-21,1998-08-21
-6bqg,2018-02-14,2017-11-27
-1bqr,1999-08-17,1998-08-17
-8bq2,2023-05-03,2022-11-18
-5bqg,2016-04-13,2015-05-29
-5bqe,2015-07-01,2015-05-28
-8bql,2023-01-18,2022-11-21
-8bqm,2023-06-28,2022-11-21
-4bq2,2013-08-14,2013-05-29
-8bqx,2023-03-22,2022-11-21
-7bql,2020-10-14,2020-03-24
-4bq5,2013-08-14,2013-05-29
-6bqk,2018-03-21,2017-11-28
-3bq0,2008-04-08,2007-12-19
-2bqv,2005-12-14,2005-04-28
-5bqd,2016-03-16,2015-05-28
-5bqu,2015-10-14,2015-05-29
-3bqr,2008-02-26,2007-12-20
-7bqj,2020-10-14,2020-03-24
-5bqs,2016-05-18,2015-05-29
-6bqx,2017-12-27,2017-11-29
-5bqi,2016-04-13,2015-05-29
-6bql,2017-12-13,2017-11-28
-5bqz,2015-10-14,2015-05-29
-4bq4,2013-08-14,2013-05-29
-1bqn,1999-01-06,1998-08-17
-8bqo,2023-05-03,2022-11-21
-8bq3,2023-11-29,2022-11-18
-8bqf,2023-05-10,2022-11-21
-6bqf,2018-02-28,2017-11-27
-1bqo,1999-08-17,1998-08-17
-2bqr,2005-06-23,2005-04-27
-2bq7,2006-04-26,2005-04-27
-6bqv,2017-12-20,2017-11-28
-5bq5,2015-09-02,2015-05-28
-4bqn,2013-11-06,2013-05-31
-6bqq,2017-12-13,2017-11-28
-6bqz,2017-12-13,2017-11-29
-8bq4,2022-12-28,2022-11-18
-1bqq,1999-08-18,1998-08-18
-4bqf,2014-02-19,2013-05-30
-4bqe,2014-02-19,2013-05-30
-3bq5,2008-03-11,2007-12-19
-8bq8,2023-11-29,2022-11-20
-4bqv,2014-06-18,2013-06-03
-4bqy,2013-06-19,2013-06-03
-6bq9,2017-12-06,2017-11-27
-2bqu,2005-06-23,2005-04-28
-3bqz,2008-12-23,2007-12-20
-4bql,2014-02-12,2013-05-31
-8bqs,2023-08-23,2022-11-21
-7bqk,2020-10-14,2020-03-24
-6bqp,2017-12-13,2017-11-28
-1bq9,1998-08-26,1998-08-22
-4bq0,2013-06-05,2013-05-29
-4bqt,2013-06-12,2013-06-02
-8bqu,2024-03-13,2022-11-21
-3bqv,2009-01-06,2007-12-20
-4bqx,2013-06-19,2013-06-03
-5bq1,2015-10-28,2015-05-28
-2bq6,2006-04-26,2005-04-27
-2bqw,2006-04-26,2005-04-28
-4bqp,2013-12-11,2013-05-31
-6bq0,2018-03-14,2017-11-27
-7bq7,2020-06-17,2020-03-24
-4bq9,2013-06-12,2013-05-30
-1bqp,1998-08-26,1998-08-17
-6bq2,2018-02-28,2017-11-27
-5bq2,2015-07-15,2015-05-28
-7bqv,2020-08-26,2020-03-25
-6bqw,2018-02-28,2017-11-28
-3bqp,2008-02-05,2007-12-20
-5bqh,2016-04-13,2015-05-29
-1bq6,1999-08-11,1998-08-21
-5bqk,2015-07-01,2015-05-29
-7bqo,2020-10-14,2020-03-25
-3bqn,2008-08-19,2007-12-20
-6bq4,2018-02-28,2017-11-27
-5bq0,2015-09-23,2015-05-28
-2bqp,1998-12-16,1998-12-08
-3bqd,2008-01-15,2007-12-20
-5bqx,2015-06-24,2015-05-29
-2bq4,2005-05-19,2005-04-27
-3bq6,2008-03-11,2007-12-19
-4bq8,2013-06-12,2013-05-30
-8bqr,2023-03-08,2022-11-21
-5bqt,2015-09-02,2015-05-29
-5bqf,2015-06-17,2015-05-29
-6bqh,2018-02-14,2017-11-27
-3bqc,2008-01-15,2007-12-20
-8bqb,2023-11-29,2022-11-20
-8bqq,2023-03-08,2022-11-21
-1bqk,1999-08-17,1998-08-17
-7bqu,2020-08-26,2020-03-25
-6bqu,2018-12-05,2017-11-28
-8bq5,2023-03-22,2022-11-18
-4bq1,2013-12-18,2013-05-29
-8bq7,2023-11-29,2022-11-19
-4bqj,2013-10-23,2013-05-30
-7bq6,2021-03-24,2020-03-24
-6bqb,2018-03-07,2017-11-27
-6bq6,2018-02-28,2017-11-27
-5bqq,2016-02-03,2015-05-29
-5bqj,2015-08-26,2015-05-29
-6bqj,2018-03-21,2017-11-28
-8bqd,2023-03-22,2022-11-21
-1bqe,2002-02-27,1998-08-14
-8bq6,2023-05-10,2022-11-18
-7bq2,2020-11-11,2020-03-23
-1bqb,1999-01-13,1998-07-14
-6bq8,2018-03-21,2017-11-27
-4bqw,2013-06-19,2013-06-03
-2bq8,2005-10-24,2005-04-27
-5bqm,2015-08-19,2015-05-29
-2bq3,2005-06-22,2005-04-27
-4bqu,2014-06-18,2013-06-02
-4bqz,2013-07-17,2013-06-03
-1bqm,1999-01-06,1998-08-17
-6bqd,2019-02-20,2017-11-27
-8bqi,2023-01-18,2022-11-21
-7bqy,2020-04-22,2020-03-26
-8bqt,2023-03-08,2022-11-21
-3bqm,2008-08-19,2007-12-20
-3bq8,2008-03-25,2007-12-19
-1bq1,1999-05-18,1998-08-20
-5bqa,2015-08-26,2015-05-28
-6bq3,2018-02-28,2017-11-27
-6bq5,2018-02-28,2017-11-27
-4bqr,2013-12-11,2013-05-31
-4bqb,2013-06-12,2013-05-30
-3bqb,2008-04-08,2007-12-20
-2bqz,2005-06-08,2005-04-28
-3bq2,2008-04-08,2007-12-19
-7bq3,2020-11-11,2020-03-23
-1bqs,1999-08-13,1998-08-18
-5bqp,2015-07-01,2015-05-29
-8bqh,2023-01-18,2022-11-21
-1bq8,1998-08-26,1998-08-22
-4k9v,2013-06-19,2013-04-21
-4k9f,2013-12-04,2013-04-19
-1k9i,2001-12-21,2001-10-29
-8k9l,2024-05-29,2023-08-01
-5k9g,2016-09-07,2016-05-31
-4k9a,2013-05-15,2013-04-19
-5k9c,2016-10-12,2016-05-31
-7k96,2021-02-03,2020-09-28
-4k90,2013-10-23,2013-04-19
-4k94,2013-10-16,2013-04-19
-3k97,2010-02-09,2009-10-15
-6k91,2020-03-25,2019-06-13
-3k93,2009-11-03,2009-10-15
-3k9f,2009-10-27,2009-10-15
-1k9k,2002-04-10,2001-10-29
-7k9y,2021-08-18,2020-09-29
-1k96,2002-04-10,2001-10-26
-7k9k,2021-09-29,2020-09-29
-1k90,2002-01-23,2001-10-26
-4k9g,2014-09-24,2013-04-19
-7k9a,2020-11-25,2020-09-29
-7k9h,2021-09-29,2020-09-29
-8k9n,2024-02-14,2023-08-01
-7k9v,2021-01-27,2020-09-29
-4k9n,2013-05-08,2013-04-20
-6k9a,2020-06-17,2019-06-14
-5k9d,2016-10-12,2016-05-31
-1k9f,2002-10-29,2001-10-29
-3k9n,2010-03-02,2009-10-16
-3k9q,2010-08-18,2009-10-16
-2k9h,2009-01-27,2008-10-13
-7k99,2020-11-25,2020-09-28
-8k9f,2024-03-06,2023-08-01
-7k9w,2021-01-27,2020-09-29
-4k9d,2013-05-01,2013-04-19
-3k9u,2009-11-17,2009-10-16
-1k9m,2002-07-19,2001-10-29
-6k9i,2020-06-17,2019-06-16
-5k97,2017-06-28,2016-05-31
-7k97,2021-02-03,2020-09-28
-5k9t,2017-06-07,2016-06-01
-4k93,2013-05-22,2013-04-19
-6k9m,2020-06-17,2019-06-16
-3k9g,2009-11-03,2009-10-15
-1k97,2001-12-07,2001-10-26
-5k91,2017-06-21,2016-05-31
-4k97,2013-05-15,2013-04-19
-5k92,2016-08-31,2016-05-31
-1k9j,2001-12-21,2001-10-29
-1k9y,2001-11-07,2001-10-31
-7k9z,2020-10-28,2020-09-29
-4k9j,2013-10-02,2013-04-20
-3k99,2010-02-09,2009-10-15
-4k9o,2013-05-08,2013-04-20
-7k9u,2021-01-27,2020-09-29
-4k9e,2013-10-16,2013-04-19
-4k99,2013-05-15,2013-04-19
-5k9w,2017-03-01,2016-06-01
-5k9q,2016-11-30,2016-06-01
-7k9i,2021-09-29,2020-09-29
-1k9e,2002-10-29,2001-10-29
-1k9r,2001-12-28,2001-10-30
-1k9s,2001-11-28,2001-10-30
-3k9l,2010-11-03,2009-10-15
-4k9c,2013-05-22,2013-04-19
-3k9j,2010-07-14,2009-10-15
-3k9z,2009-12-01,2009-10-16
-5k99,2017-03-22,2016-05-31
-4k9t,2013-06-19,2013-04-21
-7k98,2021-05-12,2020-09-28
-3k9s,2010-05-12,2009-10-16
-7k95,2020-11-11,2020-09-28
-6k9r,2020-07-08,2019-06-17
-4k9r,2013-05-08,2013-04-20
-4k95,2013-05-15,2013-04-19
-4k9i,2013-05-22,2013-04-19
-5k90,2017-06-21,2016-05-31
-7k9s,2021-01-27,2020-09-29
-7k90,2020-10-21,2020-09-27
-3k9b,2010-01-19,2009-10-15
-4k9u,2013-06-19,2013-04-21
-2k9c,2008-11-18,2008-10-08
-4k96,2013-05-15,2013-04-19
-7k9n,2021-09-29,2020-09-29
-6k9h,2020-04-22,2019-06-15
-6k9j,2020-06-17,2019-06-16
-5k95,2016-09-07,2016-05-31
-6k92,2020-03-25,2019-06-13
-6k9s,2020-03-18,2019-06-17
-3k9x,2009-12-15,2009-10-16
-4k98,2013-05-15,2013-04-19
-4k9x,2013-06-19,2013-04-21
-6k9z,2019-12-18,2019-06-19
-6k9x,2021-04-28,2019-06-18
-4k9l,2013-05-08,2013-04-20
-4k9p,2013-05-15,2013-04-20
-1k9u,2003-04-30,2001-10-30
-4k9h,2013-07-10,2013-04-19
-3k90,2009-11-10,2009-10-15
-1k98,2001-12-21,2001-10-27
-1k94,2001-12-07,2001-10-26
-7k93,2020-12-23,2020-09-28
-1k9z,2001-11-07,2001-10-31
-3k9w,2009-11-03,2009-10-16
-6k90,2020-03-25,2019-06-13
-8k9p,2024-02-14,2023-08-01
-5k9o,2016-12-28,2016-06-01
-4k9k,2013-05-08,2013-04-20
-5k9k,2016-12-21,2016-05-31
-5k9h,2016-09-28,2016-05-31
-7k9o,2021-09-29,2020-09-29
-7k9j,2021-09-29,2020-09-29
-6k9v,2019-08-28,2019-06-18
-6k9g,2020-04-22,2019-06-15
-3k9v,2009-12-15,2009-10-16
-6k9t,2019-10-16,2019-06-17
-8k9r,2023-12-20,2023-08-01
-3k9y,2009-12-15,2009-10-16
-3k98,2010-02-09,2009-10-15
-4k9m,2013-05-08,2013-04-20
-4k9w,2013-06-19,2013-04-21
-1k9q,2001-12-28,2001-10-30
-4k9y,2013-09-11,2013-04-21
-8k9k,2024-05-29,2023-08-01
-5k9f,2016-06-15,2016-05-31
-6k9c,2020-04-08,2019-06-14
-6k96,2019-12-25,2019-06-14
-5k9i,2017-02-01,2016-05-31
-1k93,2002-01-23,2001-10-26
-4k9q,2014-04-23,2013-04-20
-3k9t,2009-11-10,2009-10-16
-4k9b,2013-05-15,2013-04-19
-6k9u,2019-07-17,2019-06-18
-8k9y,2023-09-13,2023-08-02
-7k9t,2021-09-29,2020-09-29
-8k9o,2024-05-15,2023-08-01
-8k9q,2023-12-20,2023-08-01
-1k9t,2002-11-06,2001-10-30
-7k9m,2021-05-12,2020-09-29
-5k9r,2016-08-24,2016-06-01
-8k9t,2023-12-20,2023-08-01
-5k9b,2017-08-02,2016-05-31
-7k9q,2021-09-29,2020-09-29
-8k9e,2024-03-06,2023-08-01
-207l,1996-10-14,1996-03-26
-107m,1998-04-08,1997-12-22
-4l05,2013-10-23,2013-05-30
-6l0b,2020-12-02,2019-09-26
-7l05,2021-12-22,2020-12-11
-3l0k,2010-01-26,2009-12-10
-5l0h,2016-08-31,2016-07-27
-3l0n,2010-01-26,2009-12-10
-4l0p,2014-06-11,2013-05-31
-4l0j,2013-06-19,2013-05-31
-4l0o,2013-12-25,2013-05-31
-3l01,2010-12-29,2009-12-09
-7l01,2021-05-19,2020-12-10
-3l0l,2010-03-16,2009-12-10
-1l0y,2002-04-03,2002-02-14
-7l0r,2021-01-06,2020-12-12
-5l0c,2016-08-31,2016-07-27
-5l0t,2017-08-09,2016-07-28
-5l0g,2016-08-31,2016-07-27
-6l04,2020-09-30,2019-09-26
-3l03,2010-12-08,2009-12-09
-6l0i,2020-12-02,2019-09-26
-2l0i,2010-09-08,2010-07-06
-2l0b,2010-08-25,2010-06-30
-4l0q,2013-06-26,2013-05-31
-6l03,2020-09-30,2019-09-25
-7l0o,2021-09-08,2020-12-11
-5l0k,2016-08-10,2016-07-27
-5l0q,2016-11-09,2016-07-28
-7l0b,2020-12-30,2020-12-11
-4l0l,2013-08-21,2013-05-31
-7l0d,2021-02-10,2020-12-11
-4l0v,2013-10-30,2013-06-01
-5l09,2016-09-07,2016-07-26
-6l01,2020-05-06,2019-09-25
-7l02,2020-12-30,2020-12-10
-3l0d,2009-12-29,2009-12-09
-3l0b,2010-03-23,2009-12-09
-5l05,2016-08-24,2016-07-26
-3l0o,2010-05-26,2009-12-10
-2l00,2011-07-20,2010-06-29
-4l02,2013-07-24,2013-05-30
-5l0n,2017-08-02,2016-07-27
-4l03,2013-07-17,2013-05-30
-1l0z,2002-08-28,2002-02-14
-3l0a,2010-01-12,2009-12-09
-6l0c,2020-07-01,2019-09-26
-3l04,2010-03-31,2009-12-09
-3l0p,2010-12-15,2009-12-10
-7l0j,2021-06-23,2020-12-11
-4l09,2013-10-30,2013-05-31
-1l0n,2003-04-08,2002-02-11
-3l0f,2010-12-29,2009-12-09
-2l0x,2010-08-04,2010-07-19
-5l0a,2017-08-16,2016-07-27
-5l0i,2016-08-31,2016-07-27
-7l0s,2021-01-06,2020-12-12
-3l06,2010-03-31,2009-12-09
-5l0m,2016-11-09,2016-07-27
-1l0s,2002-06-19,2002-02-12
-7l08,2021-05-12,2020-12-11
-6l0k,2020-12-02,2019-09-26
-6l0p,2020-09-23,2019-09-26
-1l0v,2002-03-13,2002-02-13
-3l0j,2010-03-16,2009-12-10
-5l0d,2016-08-31,2016-07-27
-4l0m,2013-08-14,2013-05-31
-1l0c,2002-06-19,2002-02-08
-7l09,2020-12-30,2020-12-11
-4l0i,2013-10-30,2013-05-31
-1l0i,2003-02-11,2002-02-11
-6l0u,2020-09-30,2019-09-27
-7l00,2021-12-22,2020-12-10
-6l05,2020-09-30,2019-09-26
-3l05,2010-03-31,2009-12-09
-3l0s,2010-12-15,2009-12-10
-3l02,2010-03-31,2009-12-09
-6l0a,2020-12-02,2019-09-26
-7l0a,2020-12-23,2020-12-11
-5l03,2017-11-08,2016-07-26
-1l0l,2003-04-08,2002-02-11
-3l0t,2010-03-02,2009-12-10
-5l0b,2016-08-10,2016-07-27
-7l0p,2021-01-06,2020-12-12
-4l0d,2013-09-18,2013-05-31
-7l0f,2021-03-24,2020-12-11
-3l08,2010-06-23,2009-12-09
-4l0b,2013-10-30,2013-05-31
-7l0l,2021-11-03,2020-12-11
-5l0e,2016-08-10,2016-07-27
-7l03,2021-12-22,2020-12-11
-7l0q,2021-01-06,2020-12-12
-5l0s,2017-08-09,2016-07-28
-7l0g,2021-03-24,2020-12-11
-6l0g,2020-12-02,2019-09-26
-3l0q,2010-01-05,2009-12-10
-3l0h,2010-01-12,2009-12-10
-6l0q,2020-09-23,2019-09-26
-5l01,2017-01-25,2016-07-26
-5l0y,2017-03-22,2016-07-28
-4l0e,2013-09-25,2013-05-31
-4l0s,2013-10-30,2013-06-01
-5l0r,2017-08-09,2016-07-28
-6l0s,2020-09-23,2019-09-26
-5l02,2016-08-10,2016-07-26
-2l0z,2010-11-10,2010-07-21
-4l06,2013-07-24,2013-05-30
-5l0v,2017-08-09,2016-07-28
-7l0n,2021-02-17,2020-12-11
-6l0f,2020-12-02,2019-09-26
-7l0k,2021-05-19,2020-12-11
-1l0o,2002-04-03,2002-02-12
-7l0e,2021-06-02,2020-12-11
-5l0u,2017-08-09,2016-07-28
-6l0r,2020-09-23,2019-09-26
-3l0y,2010-03-23,2009-12-10
-3l00,2010-12-15,2009-12-09
-5l0z,2017-08-02,2016-07-28
-3l0c,2010-03-23,2009-12-09
-1l0h,2003-02-11,2002-02-11
-1l0p,2002-06-19,2002-02-12
-4l0g,2014-04-30,2013-05-31
-4l0f,2013-09-25,2013-05-31
-4l0t,2013-10-30,2013-06-01
-3l0v,2010-03-02,2009-12-10
-3l0e,2010-04-07,2009-12-09
-6l0j,2020-12-02,2019-09-26
-6l0h,2020-12-02,2019-09-26
-1l0g,2002-08-14,2002-02-09
-4l04,2013-07-31,2013-05-30
-6l0z,2019-10-16,2019-09-27
-7l06,2020-12-30,2020-12-11
-8w88,2023-11-22,2023-09-01
-6w84,2021-01-27,2020-03-20
-5w83,2017-09-06,2017-06-21
-6w85,2021-01-27,2020-03-20
-6w8z,2021-01-13,2020-03-21
-4w8e,2015-03-18,2014-08-24
-6w88,2021-01-27,2020-03-20
-5w8i,2018-01-17,2017-06-21
-1w8e,2005-10-26,2004-09-21
-6w89,2020-04-15,2020-03-20
-5w8c,2017-08-23,2017-06-21
-6w86,2021-01-27,2020-03-20
-2w83,2009-07-14,2009-01-08
-3w8d,2014-03-12,2013-03-12
-1w85,2004-11-02,2004-09-16
-5w8r,2017-07-19,2017-06-22
-2w8c,2009-10-27,2009-01-15
-5w89,2018-01-17,2017-06-21
-5w8k,2018-01-17,2017-06-21
-5w88,2017-07-12,2017-06-21
-2w87,2009-01-27,2009-01-14
-3w81,2013-08-21,2013-03-11
-1w8o,2004-09-29,2004-09-24
-7w8n,2022-02-23,2021-12-08
-7w8s,2022-08-17,2021-12-08
-4w8y,2014-10-15,2014-08-26
-4w88,2015-03-11,2014-08-22
-4w86,2015-03-11,2014-08-22
-1w8d,2004-10-28,2004-09-20
-3w8s,2013-08-14,2013-03-21
-8w8a,2023-11-22,2023-09-01
-3w8q,2014-03-26,2013-03-20
-6w8h,2020-11-04,2020-03-20
-5w86,2017-10-11,2017-06-21
-1w88,2004-11-02,2004-09-16
-5w8s,2018-01-31,2017-06-22
-6w83,2021-01-27,2020-03-20
-1w8g,2006-07-05,2004-09-21
-3w8o,2014-01-29,2013-03-20
-2w86,2009-05-26,2009-01-09
-7w8j,2022-04-06,2021-12-07
-6w8v,2020-07-08,2020-03-21
-5w8l,2018-01-17,2017-06-21
-4w87,2015-03-11,2014-08-22
-8w89,2023-11-22,2023-09-01
-5w8w,2017-07-12,2017-06-22
-3w8k,2014-04-23,2013-03-15
-6w87,2021-01-27,2020-03-20
-7w85,2022-04-06,2021-12-07
-7w80,2022-09-21,2021-12-07
-3w83,2014-04-09,2013-03-12
-1w8c,2006-08-30,2004-09-20
-5w8p,2017-07-12,2017-06-22
-3w8z,2013-10-30,2013-03-22
-6w8y,2021-01-13,2020-03-21
-3w8r,2014-03-26,2013-03-21
-6w8k,2021-01-13,2020-03-20
-7w8w,2022-10-19,2021-12-08
-4w8n,2015-02-11,2014-08-25
-1w87,2005-10-19,2004-09-16
-5w8b,2018-05-30,2017-06-21
-5w8q,2017-12-13,2017-06-22
-5w80,2017-07-19,2017-06-21
-5w8h,2018-01-17,2017-06-21
-1w8p,2005-02-03,2004-09-24
-4w8f,2014-11-12,2014-08-24
-5w8u,2017-09-27,2017-06-22
-1w8u,2005-03-22,2004-09-28
-3w88,2014-03-12,2013-03-12
-1w80,2004-10-27,2004-09-14
-3w8x,2013-10-30,2013-03-22
-5w8g,2017-08-23,2017-06-21
-5w85,2017-10-11,2017-06-21
-3w80,2013-07-03,2013-03-11
-6w81,2021-03-24,2020-03-20
-7w81,2022-10-19,2021-12-07
-3w8v,2014-02-12,2013-03-21
-6w8c,2021-01-27,2020-03-20
-8w8b,2023-11-22,2023-09-01
-8w86,2023-11-08,2023-08-31
-6w8j,2020-04-15,2020-03-20
-6w8p,2021-08-04,2020-03-21
-8w84,2023-11-08,2023-08-31
-5w84,2017-10-11,2017-06-21
-7w8y,2022-10-19,2021-12-08
-8w8k,2024-04-17,2023-09-03
-5w8f,2018-01-17,2017-06-21
-4w89,2015-03-11,2014-08-22
-1w8n,2004-09-30,2004-09-24
-3w82,2013-08-21,2013-03-11
-5w81,2017-07-19,2017-06-21
-7w8d,2022-08-17,2021-12-07
-6w8m,2021-01-13,2020-03-20
-3w8f,2014-03-12,2013-03-12
-2w8t,2009-01-27,2009-01-19
-2w8g,2009-04-14,2009-01-16
-6w8i,2020-11-18,2020-03-20
-8w8s,2024-01-03,2023-09-04
-2w8r,2009-06-09,2009-01-19
-7w8i,2022-12-21,2021-12-07
-8w8e,2024-04-10,2023-09-02
-7w8e,2022-12-14,2021-12-07
-6w8w,2020-07-08,2020-03-21
-4w8d,2015-03-18,2014-08-24
-7w8m,2022-08-24,2021-12-08
-2w8w,2009-01-27,2009-01-19
-5w8t,2017-09-27,2017-06-22
-5w8v,2017-08-30,2017-06-22
-6w80,2020-04-08,2020-03-20
-6w8d,2020-04-15,2020-03-20
-2w8s,2010-02-23,2009-01-19
-5w8o,2017-07-12,2017-06-22
-8w8f,2024-04-10,2023-09-02
-3w8e,2014-03-12,2013-03-12
-2w8z,2009-04-07,2009-01-20
-8w83,2023-11-08,2023-08-31
-1w8q,2005-06-28,2004-09-24
-6w8q,2021-01-13,2020-03-21
-3w8n,2013-09-25,2013-03-19
-3w84,2014-03-12,2013-03-12
-5w8x,2018-01-31,2017-06-22
-2w8y,2009-04-28,2009-01-20
-4w8l,2015-06-03,2014-08-25
-5w8a,2017-08-23,2017-06-21
-3w8m,2014-01-29,2013-03-19
-5w8j,2018-01-17,2017-06-21
-2w88,2009-10-27,2009-01-14
-4w8k,2014-09-17,2014-08-25
-1w8m,2004-09-30,2004-09-24
-7w8v,2022-10-19,2021-12-08
-3w86,2014-03-12,2013-03-12
-2w8l,2009-01-27,2009-01-16
-1w82,2005-02-08,2004-09-16
-6w8a,2021-01-27,2020-03-20
-6w8l,2020-04-08,2020-03-20
-3w8w,2013-10-30,2013-03-22
-1w8l,2004-09-30,2004-09-23
-7w8x,2022-10-19,2021-12-08
-1w8t,2005-03-22,2004-09-28
-4w8c,2015-07-15,2014-08-23
-2w8h,2009-02-10,2009-01-16
-1w83,2005-02-08,2004-09-16
-2w8v,2009-01-27,2009-01-19
-8w85,2023-11-08,2023-08-31
-6w82,2021-01-27,2020-03-20
-2w8u,2009-01-27,2009-01-19
-2w8k,2009-01-27,2009-01-16
-3w85,2014-03-12,2013-03-12
-1w84,2005-02-08,2004-09-16
-6w8f,2021-01-27,2020-03-20
-7w8g,2022-04-13,2021-12-07
-7w8l,2022-08-24,2021-12-08
-1w8y,2005-06-28,2004-10-01
-5w8d,2017-08-23,2017-06-21
-7w8f,2022-12-07,2021-12-07
-4w84,2015-03-11,2014-08-22
-4w8b,2015-03-11,2014-08-22
-5w8e,2017-08-23,2017-06-21
-4w8x,2014-10-15,2014-08-26
-2w8j,2009-01-27,2009-01-16
-1w8f,2005-03-31,2004-09-21
-3w87,2014-04-09,2013-03-12
-8w8r,2024-01-03,2023-09-04
-7w86,2022-12-14,2021-12-07
-4w8h,2015-09-09,2014-08-24
-4w8j,2014-09-17,2014-08-25
-2w8f,2009-04-14,2009-01-16
-2w8d,2009-03-03,2009-01-15
-8w87,2023-11-22,2023-09-01
-1w8b,2005-10-25,2004-09-17
-1w8h,2005-03-31,2004-09-21
-4w85,2015-03-11,2014-08-22
-1w8s,2005-03-23,2004-09-27
-3w8j,2013-09-04,2013-03-13
-4w82,2014-10-15,2014-08-22
-6w8b,2020-04-15,2020-03-20
-4d5a,2015-03-04,2014-11-03
-6d5w,2019-03-27,2018-04-19
-2d52,2006-11-14,2005-10-27
-5d5d,2016-01-13,2015-08-10
-7d5k,2021-07-28,2020-09-26
-1d5g,2002-07-24,1999-10-07
-8d5g,2022-06-15,2022-06-04
-7d53,2021-10-06,2020-09-24
-8d5q,2022-09-14,2022-06-05
-5d5m,2016-01-27,2015-08-11
-2d5f,2006-11-14,2005-11-01
-2d58,2006-10-10,2005-10-31
-4d58,2015-02-18,2014-11-03
-8d5j,2022-07-06,2022-06-04
-6d5p,2018-09-19,2018-04-19
-2d5x,2006-03-07,2005-11-08
-6d5t,2018-09-19,2018-04-19
-5d5g,2015-09-02,2015-08-10
-1d5b,2000-02-09,1999-10-06
-4d5p,2015-03-25,2014-11-07
-5d5a,2016-01-13,2015-08-10
-6d5r,2018-09-19,2018-04-19
-6d5k,2018-10-10,2018-04-19
-2d5n,2005-11-29,2005-11-02
-8d5x,2023-05-10,2022-06-06
-5d5n,2015-10-07,2015-08-11
-3d5w,2008-08-26,2008-05-17
-3d52,2008-08-05,2008-05-15
-1d5l,2001-12-12,1999-10-07
-3d5x,2008-08-26,2008-05-17
-5d58,2016-01-13,2015-08-10
-5d56,2016-01-13,2015-08-10
-6d5d,2019-04-24,2018-04-19
-7d5s,2021-10-06,2020-09-28
-7d5x,2021-07-21,2020-09-28
-7d5p,2021-06-09,2020-09-27
-2d5b,2006-11-28,2005-10-31
-7d59,2021-02-17,2020-09-25
-2d5m,2006-11-21,2005-11-02
-8d5k,2022-07-06,2022-06-05
-1d5c,2000-08-30,1999-10-06
-2d5c,2006-05-01,2005-10-31
-3d5f,2008-06-03,2008-05-16
-5d5c,2016-01-13,2015-08-10
-3d5y,2009-04-21,2008-05-18
-6d5b,2019-04-24,2018-04-19
-7d5n,2021-09-29,2020-09-27
-7d50,2021-10-06,2020-09-24
-5d5r,2015-09-16,2015-08-11
-4d5i,2015-03-25,2014-11-05
-1d5x,2000-06-28,1999-10-12
-6d5o,2018-09-19,2018-04-19
-6d51,2019-02-27,2018-04-19
-6d5m,2018-09-19,2018-04-19
-8d50,2023-12-13,2022-06-03
-4d5v,2015-03-25,2014-11-07
-7d5g,2021-12-01,2020-09-25
-2d5a,2006-10-31,2005-10-31
-6d57,2018-05-23,2018-04-19
-4d5b,2015-06-03,2014-11-03
-6d5u,2018-09-19,2018-04-19
-4d5q,2015-03-25,2014-11-07
-8d56,2023-06-07,2022-06-04
-8d5t,2023-05-10,2022-06-06
-3d57,2008-10-14,2008-05-15
-8d5d,2022-11-16,2022-06-04
-8d5n,2022-09-14,2022-06-05
-4d50,2015-04-15,2014-10-31
-4d5d,2015-06-03,2014-11-03
-7d52,2020-10-14,2020-09-24
-6d58,2019-05-15,2018-04-19
-4d5o,2015-03-25,2014-11-07
-7d5r,2021-06-02,2020-09-28
-8d51,2023-06-14,2022-06-03
-1d5m,2000-06-28,1999-10-07
-6d52,2019-05-15,2018-04-19
-5d5s,2016-08-17,2015-08-11
-3d5j,2008-10-28,2008-05-16
-3d5o,2008-11-11,2008-05-16
-1d5j,2000-10-09,1999-10-07
-8d5h,2022-06-15,2022-06-04
-6d5j,2018-09-19,2018-04-19
-8d5s,2023-05-10,2022-06-06
-1d5i,2000-02-09,1999-10-07
-5d5v,2015-12-30,2015-08-11
-8d5r,2022-11-16,2022-06-06
-3d5z,2009-04-21,2008-05-18
-7d57,2021-10-13,2020-09-25
-8d5u,2023-05-10,2022-06-06
-3d51,2008-08-05,2008-05-15
-3d5i,2009-05-26,2008-05-16
-7d5i,2021-06-23,2020-09-26
-7d5u,2021-03-31,2020-09-28
-8d5i,2022-06-15,2022-06-04
-7d5q,2021-06-09,2020-09-27
-4d5j,2015-03-25,2014-11-05
-1d5a,2000-03-24,1999-10-06
-2d55,1995-10-15,1995-05-01
-3d5q,2008-10-07,2008-05-16
-2d5g,2006-11-01,2005-11-01
-5d5q,2016-10-26,2015-08-11
-6d59,2018-09-19,2018-04-19
-8d5z,2023-05-10,2022-06-06
-5d51,2016-03-23,2015-08-10
-6d5l,2018-09-19,2018-04-19
-3d50,2008-08-05,2008-05-15
-5d59,2016-01-13,2015-08-10
-3d5k,2009-06-02,2008-05-16
-4d5g,2015-01-21,2014-11-04
-4d59,2015-03-04,2014-11-03
-4d56,2015-07-01,2014-11-03
-6d5e,2018-09-19,2018-04-19
-2d5i,2006-05-16,2005-11-02
-8d5a,2023-06-07,2022-06-04
-4d5h,2015-02-18,2014-11-05
-6d50,2018-10-17,2018-04-19
-7d5b,2021-03-31,2020-09-25
-6d5v,2018-09-19,2018-04-19
-2d54,2006-12-19,2005-10-28
-3d5m,2009-05-19,2008-05-16
-8d5e,2022-07-06,2022-06-04
-2d5y,2006-11-14,2005-11-08
-6d55,2018-09-19,2018-04-19
-6d5h,2018-09-19,2018-04-19
-4d5e,2015-01-21,2014-11-03
-7d5m,2021-09-29,2020-09-27
-5d5f,2016-01-13,2015-08-10
-4d57,2015-07-01,2014-11-03
-8d5b,2023-01-11,2022-06-04
-7d56,2021-06-02,2020-09-25
-7d5w,2021-07-21,2020-09-28
-6d5g,2018-09-19,2018-04-19
-7d5a,2021-03-31,2020-09-25
-3d5t,2008-06-03,2008-05-16
-6d5n,2018-10-31,2018-04-19
-3d54,2008-07-22,2008-05-15
-6d5q,2018-09-19,2018-04-19
-7d5o,2021-12-22,2020-09-27
-7d5c,2021-02-24,2020-09-25
-2d5z,2006-03-07,2005-11-08
-1d5z,2000-06-28,1999-10-12
-2d5w,2006-10-17,2005-11-07
-8d52,2023-06-14,2022-06-03
-8d55,2023-06-07,2022-06-04
-6d56,2018-09-19,2018-04-19
-7d5l,2020-12-16,2020-09-26
-2d5h,2006-11-14,2005-11-01
-7d5t,2021-10-06,2020-09-28
-8d59,2023-01-11,2022-06-04
-6d5x,2018-10-10,2018-04-19
-8d5w,2023-05-10,2022-06-06
-4d52,2015-03-11,2014-11-01
-1d5n,2000-03-02,1999-10-08
-8d5f,2022-07-06,2022-06-04
-5d5b,2016-01-13,2015-08-10
-7d58,2021-02-17,2020-09-25
-6d5s,2018-09-19,2018-04-19
-7d54,2021-10-06,2020-09-24
-3ta5,2011-10-12,2011-08-03
-7tag,2023-01-25,2021-12-20
-8tal,2023-09-06,2023-06-27
-7tan,2022-05-04,2021-12-21
-6tam,2020-04-08,2019-10-30
-5ta3,2016-10-12,2016-09-09
-3tau,2011-08-24,2011-08-04
-7tal,2023-07-05,2021-12-21
-1tat,1994-01-31,1993-10-04
-6tay,2020-07-01,2019-10-31
-6taa,1993-10-31,1992-08-21
-5tax,2016-10-12,2016-09-10
-3ta9,2012-02-22,2011-08-03
-5taj,2017-08-30,2016-09-10
-5ta2,2017-01-25,2016-09-09
-6tav,2021-05-12,2019-10-30
-8tay,2023-10-25,2023-06-28
-5ta7,2017-09-13,2016-09-09
-8taf,2024-01-10,2023-06-27
-3tao,2011-11-30,2011-08-04
-5taw,2016-10-12,2016-09-10
-3tap,2011-10-19,2011-08-04
-6ta3,2020-04-22,2019-10-29
-6taw,2020-08-19,2019-10-30
-3ta7,2011-10-12,2011-08-03
-7tay,2023-01-18,2021-12-21
-6taj,2020-11-18,2019-10-29
-5tat,2016-10-12,2016-09-10
-3tav,2011-08-17,2011-08-04
-5tak,2017-08-30,2016-09-10
-5tay,2016-10-12,2016-09-10
-1tah,1994-05-31,1993-12-21
-7tas,2022-01-12,2021-12-21
-3tax,2011-11-16,2011-08-04
-6tao,2020-11-18,2019-10-30
-6ta0,2020-11-18,2019-10-29
-5ta1,2017-09-13,2016-09-09
-5tav,2016-10-12,2016-09-10
-5taq,2016-10-12,2016-09-10
-5ta0,2017-09-13,2016-09-09
-1tas,1994-01-31,1993-10-04
-6tap,2020-01-01,2019-10-30
-8ta2,2024-01-31,2023-06-26
-1tau,1997-04-18,1996-06-17
-3tak,2011-08-24,2011-08-04
-1taq,1996-12-07,1996-06-04
-5tap,2016-10-12,2016-09-10
-1tae,2004-11-23,2004-05-19
-1ta3,2004-07-20,2004-05-19
-1tag,1995-02-07,1994-11-23
-6tax,2020-07-01,2019-10-31
-1tar,1994-01-31,1993-10-04
-6tak,2020-11-25,2019-10-29
-3ta1,2011-10-26,2011-08-03
-7tav,2021-12-29,2021-12-21
-6tae,2020-03-18,2019-10-29
-7tad,2022-03-16,2021-12-20
-8tah,2023-09-27,2023-06-27
-8tag,2023-09-06,2023-06-27
-8tai,2023-09-06,2023-06-27
-7ta0,2022-05-04,2021-12-20
-6ta1,2019-11-06,2019-10-29
-3ta8,2012-02-08,2011-08-03
-7tab,2022-08-17,2021-12-20
-8tao,2023-10-11,2023-06-27
-5ta5,2017-09-13,2016-09-09
-8tat,2024-06-05,2023-06-27
-1ta1,2005-08-16,2004-05-19
-8tan,2024-01-17,2023-06-27
-6tac,2020-11-18,2019-10-29
-3tar,2011-10-19,2011-08-04
-3tam,2011-10-26,2011-08-04
-1ta6,2004-06-08,2004-05-19
-8tab,2024-05-01,2023-06-27
-5ta8,2017-02-22,2016-09-09
-1taf,1996-12-07,1996-06-01
-6ta4,2020-03-04,2019-10-29
-7taf,2023-01-25,2021-12-20
-7tak,2023-01-25,2021-12-21
-3ta3,2011-11-23,2011-08-03
-5tab,2016-10-26,2016-09-09
-1ta8,2004-11-23,2004-05-19
-7ta1,2022-05-04,2021-12-20
-6ta2,2020-11-18,2019-10-29
-3ta4,2012-09-12,2011-08-03
-7tam,2022-12-28,2021-12-21
-5tai,2017-08-30,2016-09-10
-8tar,2023-09-27,2023-06-27
-5tau,2016-10-12,2016-09-10
-7tat,2022-01-12,2021-12-21
-3tas,2012-08-29,2011-08-04
-5tae,2017-08-30,2016-09-09
-3taw,2011-08-24,2011-08-04
-6ta7,2021-05-12,2019-10-29
-5ta6,2017-02-22,2016-09-09
-6tas,2020-01-01,2019-10-30
-1ta2,2004-06-08,2004-05-19
-5ta9,2017-09-13,2016-09-09
-5tal,2016-10-12,2016-09-10
-5tam,2016-10-12,2016-09-10
-5tac,2017-08-30,2016-09-09
-8taw,2023-10-25,2023-06-28
-5tas,2016-10-12,2016-09-10
-5tao,2016-11-09,2016-09-10
-1ta9,2005-08-16,2004-05-19
-5ta4,2017-01-25,2016-09-09
-3taq,2011-10-19,2011-08-04
-1tad,1995-05-08,1995-01-05
-3tan,2011-10-19,2011-08-04
-5tan,2016-10-12,2016-09-10
-5tad,2017-08-30,2016-09-09
-7tac,2022-03-16,2021-12-20
-7taa,1998-11-25,1997-10-06
-5taz,2016-10-12,2016-09-10
-1taw,1997-06-24,1996-12-19
-3tat,1999-08-12,1998-08-12
-5tar,2016-11-02,2016-09-10
-8tad,2024-05-01,2023-06-27
-3taj,2011-08-31,2011-08-04
-3tay,2012-10-17,2011-08-04
-6tal,2020-08-19,2019-10-29
-3ta0,2011-10-26,2011-08-03
-3taz,2011-11-23,2011-08-04
-7tai,2023-01-25,2021-12-20
-1ta0,2004-08-31,2004-05-19
-7ta6,2022-06-29,2021-12-20
-3ta2,2011-10-26,2011-08-03
-1taz,2004-08-03,2004-05-19
-8tau,2023-09-27,2023-06-27
-6tan,2020-04-08,2019-10-30
-3tah,2011-12-14,2011-08-04
-7taz,2023-04-12,2021-12-21
-3tal,2011-11-23,2011-08-04
-6tah,2020-09-16,2019-10-29
-3c50,2008-03-11,2008-01-30
-3c59,2008-02-19,2008-01-31
-4c5s,2014-05-07,2013-09-16
-1c5s,2000-12-22,1999-12-22
-7c5f,2020-09-23,2020-05-20
-4c5y,2014-07-02,2013-09-17
-3c5h,2008-02-12,2008-01-31
-3c56,2008-08-26,2008-01-30
-1c5y,2000-12-22,1999-12-22
-8c53,2024-01-17,2023-01-06
-3c52,2008-08-26,2008-01-30
-1c5x,2000-12-22,1999-12-22
-4c5c,2015-01-21,2013-09-10
-2c54,2005-11-14,2005-10-25
-7c5h,2021-05-26,2020-05-20
-7c5q,2021-05-26,2020-05-20
-7c5g,2021-05-26,2020-05-20
-2c5x,2006-03-01,2005-11-03
-6c5i,2019-01-09,2018-01-16
-4c54,2013-11-13,2013-09-10
-1c5v,2000-12-22,1999-12-22
-1c5t,2000-12-22,1999-12-22
-3c5n,2008-04-01,2008-01-31
-8c5m,2023-03-01,2023-01-09
-6c58,2019-01-16,2018-01-15
-1c5k,2000-12-06,1999-12-05
-3c5q,2008-05-27,2008-02-01
-3c5t,2008-02-19,2008-02-01
-1c52,1998-06-24,1997-06-23
-7c5i,2021-05-26,2020-05-20
-8c5y,2023-05-03,2023-01-10
-8c57,2024-01-17,2023-01-06
-8c56,2024-01-17,2023-01-06
-8c5p,2023-04-19,2023-01-10
-1c5o,2000-12-22,1999-12-22
-2c5u,2005-11-04,2005-11-01
-3c5j,2008-08-05,2008-01-31
-1c5r,2000-12-22,1999-12-22
-2c5n,2006-03-01,2005-10-30
-5c5o,2016-06-22,2015-06-21
-3c5c,2008-02-12,2008-01-31
-6c5j,2019-01-09,2018-01-16
-4c57,2013-10-09,2013-09-10
-6c5m,2019-01-30,2018-01-16
-5c5x,2015-12-02,2015-06-22
-1c50,1999-12-23,1999-12-15
-5c5n,2016-06-22,2015-06-21
-5c5l,2015-07-08,2015-06-20
-7c5r,2021-05-26,2020-05-20
-2c59,2005-11-14,2005-10-26
-5c5q,2015-08-12,2015-06-21
-7c5k,2021-05-26,2020-05-20
-4c5o,2014-02-19,2013-09-13
-2c5s,2005-11-30,2005-11-01
-8c5q,2024-01-24,2023-01-10
-1c57,2000-05-08,1999-10-26
-3c5p,2008-02-19,2008-02-01
-6c5w,2018-07-11,2018-01-17
-1c5u,2000-12-22,1999-12-22
-6c57,2018-09-05,2018-01-15
-2c53,2005-11-28,2005-10-25
-3c5x,2008-04-08,2008-02-01
-6c5l,2018-02-21,2018-01-16
-4c50,2013-11-13,2013-09-10
-2c56,2005-11-28,2005-10-26
-5c5j,2016-06-22,2015-06-20
-3c5k,2008-02-19,2008-01-31
-6c5v,2018-05-02,2018-01-16
-2c5b,2007-02-20,2005-10-26
-4c5n,2014-03-19,2013-09-12
-8c5s,2023-08-30,2023-01-10
-6c5z,2019-01-23,2018-01-17
-4c58,2013-10-09,2013-09-10
-6c5q,2018-08-01,2018-01-16
-8c5x,2023-11-22,2023-01-10
-1c5i,2000-05-12,1999-11-24
-2c5w,2005-12-07,2005-11-02
-8c5w,2023-12-13,2023-01-10
-3c51,2008-03-11,2008-01-30
-4c5r,2014-05-07,2013-09-16
-3c5u,2008-03-25,2008-02-01
-5c58,2016-06-29,2015-06-19
-4c5k,2014-03-19,2013-09-12
-6c55,2019-01-16,2018-01-14
-6c5a,2019-01-16,2018-01-15
-1c5l,2000-12-22,1999-12-22
-6c56,2018-09-05,2018-01-15
-7c5j,2021-05-26,2020-05-20
-6c5k,2019-01-09,2018-01-16
-2c5o,2006-03-01,2005-10-30
-5c5m,2015-07-08,2015-06-20
-2c5g,2006-06-14,2005-10-27
-4c5l,2014-03-19,2013-09-12
-8c5z,2023-05-10,2023-01-10
-5c55,2016-06-22,2015-06-19
-6c5c,2018-01-24,2018-01-16
-8c58,2024-01-17,2023-01-06
-2c5r,2005-11-08,2005-10-31
-6c5u,2018-04-11,2018-01-16
-8c54,2023-09-20,2023-01-06
-7c53,2021-05-19,2020-05-19
-5c5r,2015-08-12,2015-06-21
-4c55,2013-11-13,2013-09-10
-8c5h,2023-08-02,2023-01-09
-5c53,2016-01-27,2015-06-19
-8c59,2024-01-17,2023-01-06
-5c5h,2015-10-07,2015-06-19
-2c5a,2005-11-14,2005-10-26
-2c5c,2006-11-27,2005-10-26
-8c5l,2024-01-10,2023-01-09
-1c5f,1999-12-03,1999-11-22
-4c52,2014-02-05,2013-09-10
-3c5m,2008-02-26,2008-01-31
-5c5v,2015-11-04,2015-06-22
-4c51,2013-11-13,2013-09-10
-7c5m,2021-05-26,2020-05-20
-5c5t,2015-09-30,2015-06-22
-8c5f,2023-04-19,2023-01-07
-7c5n,2021-05-26,2020-05-20
-4c5b,2015-01-21,2013-09-10
-1c5c,2000-10-11,1999-11-09
-1c5w,2000-12-22,1999-12-22
-6c5n,2019-01-30,2018-01-16
-5c51,2016-05-11,2015-06-19
-5c5u,2015-09-30,2015-06-22
-2c5f,2006-06-14,2005-10-27
-4c5a,2015-01-21,2013-09-10
-2c5h,2006-10-25,2005-10-27
-8c5d,2023-05-24,2023-01-06
-6c5x,2018-05-02,2018-01-17
-6c5b,2018-03-21,2018-01-15
-1c5z,2000-12-22,1999-12-22
-1c5n,2000-12-22,1999-12-22
-5c5a,2016-06-29,2015-06-19
-3c5g,2008-07-29,2008-01-31
-2c5e,2005-11-14,2005-10-26
-3c5e,2008-02-26,2008-01-31
-1c5q,2000-12-22,1999-12-22
-2c5l,2006-02-20,2005-10-27
-7c5o,2021-05-26,2020-05-20
-2c58,2006-06-14,2005-10-26
-4c53,2013-10-02,2013-09-10
-1c5p,2000-12-22,1999-12-22
-8c5o,2023-12-13,2023-01-10
-2c5y,2006-03-01,2005-11-03
-3c5i,2008-02-19,2008-01-31
-8c5e,2023-04-19,2023-01-06
-2c5v,2006-03-01,2005-11-02
-8c5c,2023-01-25,2023-01-06
-5c5k,2016-02-17,2015-06-20
-3c5l,2009-02-17,2008-01-31
-7c5l,2021-05-26,2020-05-20
-5c52,2016-05-11,2015-06-19
-2c57,2006-02-22,2005-10-26
-4c5d,2014-02-05,2013-09-11
-6c5f,2018-06-13,2018-01-16
-4c5m,2014-03-19,2013-09-12
-8c51,2024-01-17,2023-01-06
-7c52,2021-03-03,2020-05-18
-3c58,2008-12-16,2008-01-31
-6c5h,2019-01-09,2018-01-16
-5c5p,2015-08-12,2015-06-21
-4c59,2013-10-09,2013-09-10
-7c5p,2021-05-26,2020-05-20
-7c5e,2020-08-05,2020-05-19
-5c5e,2015-08-05,2015-06-19
-4c5w,2014-03-12,2013-09-16
-8c5u,2023-08-30,2023-01-10
-6c5t,2018-08-01,2018-01-16
-2c5d,2005-12-19,2005-10-26
-3si0,2011-06-29,2011-06-17
-8siv,2023-11-01,2023-04-17
-3sip,2011-08-10,2011-06-20
-3si3,2012-06-20,2011-06-17
-5sib,2022-10-12,2022-02-01
-6sic,2020-07-08,2019-08-09
-5sis,2022-10-12,2022-02-01
-7siq,2021-10-27,2021-10-14
-6sip,2020-06-17,2019-08-10
-3siy,2011-07-13,2011-06-20
-5si8,2022-10-12,2022-02-01
-5si7,2022-10-12,2022-02-01
-5siy,2022-10-12,2022-02-01
-6si3,2020-02-19,2019-08-08
-3sik,2012-05-02,2011-06-19
-3sia,2011-06-29,2011-06-17
-8sio,2024-04-17,2023-04-16
-8si4,2023-05-17,2023-04-14
-5sid,2022-10-12,2022-02-01
-8siw,2023-11-01,2023-04-17
-7si0,2021-12-15,2021-10-12
-6six,2020-01-15,2019-08-12
-8sik,2023-05-31,2023-04-16
-8sir,2024-03-13,2023-04-16
-7sie,2022-10-19,2021-10-13
-6sit,2019-12-18,2019-08-11
-7sij,2023-01-11,2021-10-14
-5sim,2022-10-12,2022-02-01
-8si5,2023-05-17,2023-04-14
-6siw,2020-01-15,2019-08-12
-7sid,2022-02-02,2021-10-13
-8sie,2024-02-07,2023-04-16
-5si3,2022-10-12,2022-02-01
-5siv,2022-10-12,2022-02-01
-7siy,2022-11-09,2021-10-15
-5si0,2022-10-12,2022-02-01
-8si9,2023-08-30,2023-04-14
-7sil,2022-01-19,2021-10-14
-3sis,2011-09-28,2011-06-20
-7sig,2022-11-23,2021-10-14
-7si3,2022-03-16,2021-10-12
-7sia,2022-10-19,2021-10-12
-7sib,2023-01-11,2021-10-13
-8sia,2023-05-17,2023-04-14
-6si5,2020-08-26,2019-08-08
-6sin,2020-06-17,2019-08-10
-5six,2022-10-12,2022-02-01
-5sih,2022-10-12,2022-02-01
-5si1,2022-10-12,2022-02-01
-2sim,1994-11-30,1994-07-15
-1siw,2004-06-08,2004-03-01
-8six,2023-11-01,2023-04-17
-1si1,2004-06-08,2004-02-26
-3siw,2012-02-08,2011-06-20
-8si3,2023-05-17,2023-04-14
-7si9,2021-10-20,2021-10-12
-3siz,2011-06-29,2011-06-20
-5sir,2022-10-12,2022-02-01
-1si0,2004-06-08,2004-02-26
-3si6,2011-10-12,2011-06-17
-7siz,2022-05-04,2021-10-15
-6sik,2019-11-06,2019-08-10
-5sij,2022-10-12,2022-02-01
-8sit,2024-03-13,2023-04-16
-2sic,1993-04-15,1991-04-01
-6sis,2019-12-04,2019-08-10
-1siv,1994-01-31,1993-08-24
-1sii,2004-09-07,2004-02-29
-7sii,2022-02-02,2021-10-14
-5sil,2022-10-12,2022-02-01
-7sin,2022-01-19,2021-10-14
-6si2,2020-02-19,2019-08-08
-3siq,2011-08-10,2011-06-20
-3si2,2011-06-29,2011-06-17
-3si7,2012-02-01,2011-06-17
-5si2,2022-10-12,2022-02-01
-1si3,2004-05-25,2004-02-27
-6siq,2020-06-17,2019-08-10
-8si8,2023-05-17,2023-04-14
-3sie,2011-08-24,2011-06-17
-3sic,1994-01-31,1991-08-30
-7sih,2022-11-23,2021-10-14
-7sip,2022-03-30,2021-10-14
-5si4,2022-10-12,2022-02-01
-7sic,2022-02-02,2021-10-13
-3si4,2012-06-20,2011-06-17
-6sir,2019-12-18,2019-08-10
-6si8,2020-02-05,2019-08-09
-6si0,2020-02-19,2019-08-08
-5sii,2022-10-12,2022-02-01
-3six,2012-02-08,2011-06-20
-5siu,2022-10-12,2022-02-01
-1siz,2004-05-25,2004-03-02
-7sit,2022-05-04,2021-10-14
-7sif,2022-11-23,2021-10-14
-7sim,2022-01-19,2021-10-14
-6sio,2020-06-17,2019-08-10
-5sia,2022-10-12,2022-02-01
-1si6,2005-03-08,2004-02-27
-6si9,2020-02-19,2019-08-09
-3sit,2011-09-28,2011-06-20
-5si9,2022-10-12,2022-02-01
-6sij,2019-11-06,2019-08-10
-5si6,2022-10-12,2022-02-01
-5sin,2022-10-12,2022-02-01
-8si7,2023-05-17,2023-04-14
-5siz,2022-10-12,2022-02-01
-7si7,2022-03-16,2021-10-12
-1siq,2004-09-07,2004-03-01
-3sig,2011-08-24,2011-06-18
-1si4,2004-10-26,2004-02-27
-1sie,1996-06-20,1995-12-12
-6siy,2020-01-15,2019-08-12
-5sic,1994-01-31,1991-11-18
-6siz,2020-01-15,2019-08-12
-6sii,2020-08-26,2019-08-09
-5sif,2022-10-12,2022-02-01
-8sih,2024-04-24,2023-04-16
-8sij,2023-08-23,2023-04-16
-6sil,2019-11-06,2019-08-10
-5sie,2022-10-12,2022-02-01
-6sim,2019-11-06,2019-08-10
-3si1,2011-06-29,2011-06-17
-6siu,2020-03-18,2019-08-12
-7si6,2022-03-16,2021-10-12
-8sic,2024-04-17,2023-04-14
-7sis,2022-11-23,2021-10-14
-1siu,2004-03-30,2004-03-01
-8sis,2024-03-13,2023-04-16
-1sib,1993-10-31,1993-08-02
-7si2,2022-04-27,2021-10-12
-5sit,2022-10-12,2022-02-01
-1sir,2004-09-07,2004-03-01
-1sio,2004-03-30,2004-03-01
-6siv,2019-08-21,2019-08-12
-3sio,2011-10-26,2011-06-19
-1sid,1996-06-20,1995-12-12
-5sig,2022-10-12,2022-02-01
-5si5,2022-10-12,2022-02-01
-8sig,2024-04-24,2023-04-16
-3sid,2011-08-31,2011-06-17
-1six,2004-03-09,2004-03-01
-5sio,2022-10-12,2022-02-01
-7si5,2022-11-09,2021-10-12
-8si2,2023-05-17,2023-04-14
-8sip,2024-02-07,2023-04-16
-1si2,2004-05-25,2004-02-26
-5sik,2022-10-12,2022-02-01
-8si0,2024-04-24,2023-04-14
-8sid,2023-08-30,2023-04-14
-7si4,2022-11-09,2021-10-12
-8siq,2024-03-13,2023-04-16
-3sii,2011-08-24,2011-06-18
-1si8,2004-05-04,2004-02-28
-5siq,2022-10-12,2022-02-01
-3sib,2011-06-29,2011-06-17
-3si8,2011-08-03,2011-06-17
-5sip,2022-10-12,2022-02-01
-6si1,2020-02-19,2019-08-08
-6si4,2020-02-19,2019-08-08
-8si6,2023-05-17,2023-04-14
-1sih,2004-09-07,2004-02-29
-3sil,1998-11-11,1998-07-07
-5siw,2022-10-12,2022-02-01
-8sim,2023-05-31,2023-04-16
-7siu,2022-03-02,2021-10-14
-1sij,2004-07-27,2004-03-01
-5hjd,2016-04-20,2016-01-13
-4hj1,2013-01-16,2012-10-12
-1hj1,2002-01-04,2001-01-08
-6hjz,2019-09-18,2018-09-04
-6hju,2018-12-19,2018-09-04
-1hj9,2002-01-04,2001-01-10
-1hju,2003-06-02,2003-02-27
-1hj6,2001-01-16,2001-01-08
-5hjz,2017-01-18,2016-01-13
-1hjv,2003-03-11,2003-02-28
-3hjq,2010-01-12,2009-05-22
-8hjp,2024-05-29,2022-11-23
-4hjf,2012-10-31,2012-10-12
-1hjj,2003-05-09,2003-02-27
-4hjx,2013-03-13,2012-10-14
-3hjr,2009-06-02,2009-05-22
-5hjg,2016-05-04,2016-01-13
-5hj2,2017-04-12,2016-01-12
-1hjs,2003-06-02,2003-02-27
-3hjv,2009-06-09,2009-05-22
-2hjo,2008-04-08,2006-06-30
-6hja,2019-09-18,2018-09-03
-5hji,2016-10-12,2016-01-13
-4hjy,2012-10-24,2012-10-14
-3hjo,2009-09-22,2009-05-22
-3hja,2009-06-02,2009-05-21
-5hja,2016-04-13,2016-01-13
-3hji,2009-09-29,2009-05-21
-6hjj,2018-10-03,2018-09-04
-5hjy,2017-01-18,2016-01-13
-6hjh,2019-12-04,2018-09-03
-4hj2,2013-03-27,2012-10-12
-4hjv,2012-10-24,2012-10-14
-4hje,2013-07-17,2012-10-12
-1hj7,2001-07-11,2001-01-09
-6hj3,2019-09-11,2018-08-31
-3hj1,2010-05-12,2009-05-20
-4hj4,2013-01-16,2012-10-12
-6hjd,2019-08-14,2018-09-03
-2hjh,2008-04-08,2006-06-30
-8hjl,2024-05-29,2022-11-23
-2hjb,2007-11-06,2006-06-30
-8hjh,2024-05-29,2022-11-23
-6hjk,2018-10-03,2018-09-04
-8hja,2023-03-29,2022-11-22
-8hjb,2023-02-08,2022-11-23
-2hjp,2006-10-03,2006-06-30
-6hjg,2018-11-07,2018-09-03
-5hjx,2017-01-18,2016-01-13
-4hjh,2012-11-21,2012-10-12
-5hjr,2016-07-27,2016-01-13
-8hjt,2023-09-13,2022-11-23
-4hj7,2012-12-12,2012-10-12
-3hjb,2009-06-16,2009-05-21
-3hjx,2010-01-12,2009-05-22
-8hje,2023-05-03,2022-11-23
-5hj9,2016-04-13,2016-01-13
-2hjg,2006-08-08,2006-06-30
-4hjo,2012-11-14,2012-10-13
-8hjn,2024-05-29,2022-11-23
-2hj9,2006-09-26,2006-06-30
-3hjf,2009-10-06,2009-05-21
-8hjd,2022-12-07,2022-11-23
-2hji,2006-10-24,2006-06-30
-4hju,2013-12-04,2012-10-14
-4hj5,2012-12-12,2012-10-12
-5hjm,2016-10-12,2016-01-13
-6hjs,2019-09-18,2018-09-04
-3hjt,2009-12-01,2009-05-22
-5hjc,2016-04-20,2016-01-13
-1hjl,2003-05-09,2003-02-27
-2hjn,2006-09-26,2006-06-30
-8hjv,2023-09-20,2022-11-23
-2hjr,2006-08-01,2006-06-30
-1hj3,2001-01-16,2001-01-08
-8hjf,2024-05-29,2022-11-23
-3hjk,2009-09-29,2009-05-21
-2hj3,2006-08-22,2006-06-30
-4hj3,2013-01-16,2012-10-12
-1hjx,2003-03-11,2003-02-28
-3hjn,2009-06-02,2009-05-22
-3hjz,2009-06-09,2009-05-22
-8hjg,2024-05-29,2022-11-23
-8hj9,2023-02-08,2022-11-22
-6hjn,2018-09-26,2018-09-04
-5hj8,2016-03-09,2016-01-13
-1hjt,1997-11-12,1997-06-24
-1hjo,1998-10-21,1998-10-13
-6hjw,2019-01-16,2018-09-04
-4hjw,2013-09-11,2012-10-14
-4hj8,2012-12-12,2012-10-12
-1hjf,2001-06-01,2001-01-15
-6hjf,2018-11-07,2018-09-03
-5hjs,2016-04-06,2016-01-13
-6hjc,2018-10-10,2018-09-03
-3hjh,2009-10-20,2009-05-21
-8hjo,2024-05-29,2022-11-23
-5hj5,2016-02-03,2016-01-12
-3hjm,2009-09-22,2009-05-22
-1hjk,1997-10-15,1997-05-30
-6hj4,2018-10-10,2018-08-31
-5hj7,2016-05-25,2016-01-12
-3hj0,2009-12-22,2009-05-20
-6hj5,2018-10-10,2018-08-31
-6hjb,2019-09-18,2018-09-03
-8hjz,2023-06-14,2022-11-24
-2hj6,2007-03-27,2006-06-30
-2hj4,2007-11-06,2006-06-30
-4hji,2012-12-19,2012-10-12
-6hjo,2019-12-04,2018-09-04
-5hj0,2016-03-09,2016-01-12
-2hje,2006-09-26,2006-06-30
-4hjs,2013-12-04,2012-10-14
-4hjz,2012-10-24,2012-10-14
-3hj8,2010-01-12,2009-05-21
-6hjq,2018-09-26,2018-09-04
-4hjl,2013-10-16,2012-10-12
-5hjp,2016-04-06,2016-01-13
-1hj5,2001-01-16,2001-01-08
-5hjb,2016-04-20,2016-01-12
-8hj3,2023-02-08,2022-11-22
-1hjq,2003-07-25,2003-02-27
-5hje,2017-01-25,2016-01-13
-8hju,2023-09-20,2022-11-23
-8hjy,2023-06-14,2022-11-24
-3hj3,2010-06-02,2009-05-20
-8hjx,2023-06-14,2022-11-24
-6hj2,2020-03-25,2018-08-31
-5hjk,2016-10-12,2016-01-13
-3hj9,2009-06-16,2009-05-21
-6hj6,2018-10-10,2018-08-31
-5hjh,2017-01-25,2016-01-13
-6hje,2018-11-07,2018-09-03
-5hjo,2016-07-27,2016-01-13
-4hj6,2013-01-16,2012-10-12
-1hjw,2003-03-11,2003-02-28
-6hjx,2019-10-09,2018-09-04
-6hji,2019-09-18,2018-09-03
-3hjs,2010-01-12,2009-05-22
-8hjk,2024-05-29,2022-11-23
-3hjw,2009-06-23,2009-05-22
-2hjf,2006-12-05,2006-06-30
-8hj5,2023-05-31,2022-11-22
-6hjr,2018-09-26,2018-09-04
-5hj3,2016-03-09,2016-01-12
-6hjt,2018-12-19,2018-09-04
-1hjg,2001-06-01,2001-01-15
-1hj4,2001-01-16,2001-01-08
-5hjq,2016-09-21,2016-01-13
-1hj8,2002-01-04,2001-01-09
-4hjt,2013-12-04,2012-10-14
-6hjp,2018-09-26,2018-09-04
-5jn2,2016-05-25,2016-04-29
-1jno,2001-08-08,2001-07-24
-1jn0,2001-11-30,2001-07-21
-5jnl,2016-08-24,2016-04-30
-6jnf,2019-10-16,2019-03-14
-1jnw,2001-08-01,2001-07-25
-6jn4,2019-07-17,2019-03-13
-1jn5,2001-10-17,2001-07-23
-5jne,2016-08-10,2016-04-29
-6jni,2019-09-25,2019-03-16
-7jn9,2020-08-26,2020-08-04
-7jne,2020-08-26,2020-08-04
-4jnj,2013-05-29,2013-03-15
-1jn7,2002-09-25,2001-07-23
-1jnk,1999-06-08,1998-06-03
-6jnn,2019-03-27,2019-03-17
-8jnw,2024-05-22,2023-06-08
-4jna,2014-03-05,2013-03-14
-5jn3,2017-05-03,2016-04-29
-1jnu,2002-06-14,2001-07-25
-6jn6,2019-07-17,2019-03-13
-8jnp,2023-11-15,2023-06-06
-5jn8,2017-05-03,2016-04-29
-4jno,2013-03-27,2013-03-15
-4jnq,2013-04-03,2013-03-15
-2jn3,2007-07-03,2006-12-22
-4jne,2013-05-29,2013-03-15
-5jn5,2017-02-08,2016-04-29
-1jni,2002-05-17,2001-07-24
-1jne,2002-05-01,2001-07-23
-5jnn,2016-08-17,2016-04-30
-1jnh,2002-02-06,2001-07-24
-6jnt,2019-04-24,2019-03-18
-1jnr,2002-02-27,2001-07-25
-7jn7,2021-05-19,2020-08-04
-1jn9,2003-09-09,2001-07-23
-1jnn,2002-02-06,2001-07-24
-8jnq,2023-11-15,2023-06-06
-6jnu,2019-04-24,2019-03-18
-1jnz,2002-03-27,2001-07-26
-6jnr,2020-03-25,2019-03-18
-7jnr,2020-11-04,2020-08-05
-7jnb,2021-02-03,2020-08-04
-6jnl,2019-03-27,2019-03-17
-4jnc,2013-06-05,2013-03-15
-6jn0,2020-01-15,2019-03-13
-1jnx,2001-09-21,2001-07-26
-1jn4,2003-06-03,2001-07-23
-4jnm,2013-05-29,2013-03-15
-7jnp,2021-03-24,2020-08-05
-4jn4,2013-05-29,2013-03-14
-2jnx,2008-02-12,2007-02-11
-7jnd,2021-02-03,2020-08-04
-6jnx,2019-06-12,2019-03-18
-7jnz,2020-11-04,2020-08-05
-7jni,2022-02-09,2020-08-04
-8jnu,2024-04-17,2023-06-06
-5jn7,2017-05-03,2016-04-29
-5jnc,2017-05-03,2016-04-29
-4jny,2013-08-28,2013-03-16
-7jnw,2020-11-04,2020-08-05
-2jnd,2007-03-13,2007-01-08
-4jnk,2013-05-22,2013-03-15
-8jnc,2023-11-15,2023-06-06
-1jnf,2001-08-01,2001-07-24
-7jn2,2020-08-12,2020-08-03
-7jnt,2020-09-02,2020-08-05
-4jnd,2013-06-19,2013-03-15
-5jnq,2017-01-11,2016-04-30
-4jn0,2013-05-01,2013-03-14
-4jn9,2014-04-09,2013-03-14
-7jn8,2020-08-26,2020-08-04
-7jnx,2020-11-04,2020-08-05
-7jn3,2021-03-17,2020-08-03
-7jnf,2021-02-03,2020-08-04
-6jn3,2019-07-17,2019-03-13
-6jn8,2020-01-15,2019-03-13
-6jnh,2019-03-27,2019-03-14
-2jnp,2007-12-11,2007-01-30
-7jn5,2020-10-28,2020-08-03
-1jnq,2003-06-03,2001-07-24
-6jn5,2019-07-17,2019-03-13
-6jnm,2019-03-27,2019-03-17
-8jnr,2024-01-24,2023-06-06
-5jn9,2017-05-03,2016-04-29
-1jny,2002-01-23,2001-07-26
-2jne,2007-02-13,2007-01-12
-5jnw,2017-03-29,2016-04-30
-4jn7,2013-04-03,2013-03-14
-6jn7,2020-01-15,2019-03-13
-8jnk,2024-01-24,2023-06-06
-1jn2,2003-07-01,2001-07-22
-1jn1,2002-08-21,2001-07-21
-7jna,2020-11-11,2020-08-04
-5jnx,2016-06-15,2016-05-01
-4jnx,2014-03-19,2013-03-16
-6jn1,2020-01-15,2019-03-13
-8jns,2023-06-28,2023-06-06
-1jnd,2002-05-01,2001-07-23
-8jnv,2024-05-22,2023-06-06
-4jnz,2013-08-28,2013-03-16
-4jnt,2013-04-17,2013-03-15
-6jno,2019-11-20,2019-03-17
-6jnk,2019-05-15,2019-03-16
-7jnv,2020-11-04,2020-08-05
-4jn2,2013-03-27,2013-03-14
-8jnx,2023-12-13,2023-06-06
-7jnc,2020-11-11,2020-08-04
-5jnb,2016-06-22,2016-04-29
-4jn6,2013-05-08,2013-03-14
-5jna,2017-05-03,2016-04-29
-2jnr,2007-05-08,2007-02-01
-8jno,2023-11-22,2023-06-06
-6xho,2020-07-08,2020-06-19
-7xhf,2023-01-18,2022-04-08
-5xha,2017-07-19,2017-04-19
-6xh8,2021-04-14,2020-06-18
-6xhf,2021-03-17,2020-06-18
-2xh8,2011-04-27,2010-06-09
-1xh4,2005-09-17,2004-09-17
-4xho,2016-03-09,2015-01-06
-7xhh,2023-04-19,2022-04-08
-1xhl,2004-09-28,2004-09-20
-6xhy,2020-12-23,2020-06-19
-2xhl,2010-12-01,2010-06-18
-4xhk,2015-02-11,2015-01-05
-2xhj,2010-07-21,2010-06-16
-4xhg,2016-01-06,2015-01-05
-7xhq,2023-02-15,2022-04-09
-7xh2,2023-02-08,2022-04-07
-6xhq,2021-04-21,2020-06-19
-1xh2,2005-05-24,2004-09-17
-5xhs,2018-05-02,2017-04-24
-2xhi,2011-01-26,2010-06-16
-6xhd,2021-03-17,2020-06-18
-2xhh,2010-07-21,2010-06-16
-2xhb,2010-07-21,2010-06-14
-6xhb,2021-01-13,2020-06-18
-5xhp,2018-05-02,2017-04-22
-7xhg,2023-01-18,2022-04-08
-8xho,2024-04-03,2023-12-18
-7xhe,2022-07-27,2022-04-08
-2xhr,2010-09-01,2010-06-21
-2xh9,2011-06-29,2010-06-09
-4xhj,2015-05-13,2015-01-05
-5xhm,2017-08-09,2017-04-21
-6xhx,2020-12-23,2020-06-19
-5xhn,2017-08-09,2017-04-21
-6xh7,2021-04-14,2020-06-18
-6xhi,2021-03-17,2020-06-18
-6xhc,2020-12-02,2020-06-18
-1xh6,2005-09-17,2004-09-17
-6xhg,2020-10-28,2020-06-18
-7xhl,2023-04-12,2022-04-08
-8xhr,2024-02-28,2023-12-18
-4xhn,2016-03-09,2015-01-06
-2xh4,2010-08-25,2010-06-09
-5xhu,2018-05-02,2017-04-24
-4xh6,2015-08-26,2015-01-05
-4xhu,2015-09-30,2015-01-06
-7xhb,2023-01-11,2022-04-07
-1xhb,2004-10-26,2004-09-17
-5xh8,2017-07-19,2017-04-19
-4xh4,2015-08-19,2015-01-04
-2xhx,2010-09-01,2010-06-21
-1xh0,2005-05-24,2004-09-17
-4xh0,2016-01-06,2015-01-04
-6xhk,2021-04-21,2020-06-18
-1xhv,2004-09-28,2004-09-20
-5xhg,2017-12-20,2017-04-20
-2xhv,2010-08-04,2010-06-21
-6xhl,2020-07-08,2020-06-19
-8xhk,2024-05-01,2023-12-18
-5xh9,2017-07-19,2017-04-19
-2xhk,2010-08-18,2010-06-17
-1xh9,2005-09-17,2004-09-17
-6xhj,2021-03-17,2020-06-18
-2xh2,2010-08-25,2010-06-08
-7xha,2023-01-11,2022-04-07
-8xha,2024-05-01,2023-12-17
-6xhn,2020-07-08,2020-06-19
-1xhg,2004-11-02,2004-09-19
-2xhd,2010-07-21,2010-06-14
-1xhx,2004-12-07,2004-09-21
-5xhk,2017-09-06,2017-04-21
-5xhi,2017-08-09,2017-04-21
-2xh0,2010-08-25,2010-06-08
-6xhw,2020-12-23,2020-06-19
-4xhe,2015-06-03,2015-01-05
-6xhh,2020-10-28,2020-06-18
-6xht,2021-04-21,2020-06-19
-4xhb,2016-01-27,2015-01-05
-2xh5,2010-06-16,2010-06-09
-4xhl,2016-01-06,2015-01-05
-2xh7,2010-08-25,2010-06-09
-5xhc,2017-10-18,2017-04-20
-4xhs,2016-01-27,2015-01-06
-4xhv,2015-07-01,2015-01-06
-8xhu,2024-04-10,2023-12-18
-4xhf,2015-12-16,2015-01-05
-2xhs,2011-07-20,2010-06-21
-5xhr,2017-09-27,2017-04-24
-1xh5,2005-09-17,2004-09-17
-4xhq,2016-10-12,2015-01-06
-2xh1,2010-07-28,2010-06-08
-5xh2,2017-12-20,2017-04-19
-4xh5,2015-09-23,2015-01-04
-2xht,2010-09-01,2010-06-21
-5xhj,2017-12-06,2017-04-21
-7xhw,2023-02-15,2022-04-11
-6xhv,2020-12-23,2020-06-19
-1xhc,2004-11-23,2004-09-17
-1xhu,2004-09-28,2004-09-20
-4xhx,2016-01-20,2015-01-06
-1xhy,2005-03-22,2004-09-21
-4xhd,2015-01-28,2015-01-05
-6xhe,2021-03-17,2020-06-18
-5xh6,2017-06-14,2017-04-19
-1xhm,2005-08-09,2004-09-20
-5xh7,2017-06-14,2017-04-19
-7xh6,2022-07-27,2022-04-07
-5xhy,2018-05-02,2017-04-25
-1xh7,2005-09-17,2004-09-17
-4xh1,2015-08-19,2015-01-04
-7xhk,2023-06-14,2022-04-08
-2xhg,2011-07-06,2010-06-15
-8xhd,2024-05-01,2023-12-17
-5xho,2017-08-09,2017-04-21
-4xhz,2016-09-21,2015-01-06
-1xh1,2005-05-24,2004-09-17
-4xhc,2015-04-15,2015-01-05
-1xh8,2005-09-17,2004-09-17
-1xhz,2004-12-07,2004-09-21
-7xho,2022-12-14,2022-04-09
-6xhs,2021-04-21,2020-06-19
-2xhn,2010-09-29,2010-06-18
-4xhp,2016-03-09,2015-01-06
-7xhy,2022-11-30,2022-04-11
-6xhm,2020-07-08,2020-06-19
-1xha,2005-09-17,2004-09-17
-6xha,2021-01-13,2020-06-18
-1xhf,2005-05-17,2004-09-18
-7xh4,2023-02-08,2022-04-07
-7xht,2022-12-14,2022-04-10
-2xhm,2010-07-14,2010-06-18
-1xh3,2004-11-23,2004-09-17
-7xhn,2023-01-25,2022-04-09
-4xha,2015-11-04,2015-01-05
-5xh3,2017-12-20,2017-04-19
-5xht,2018-05-02,2017-04-24
-7xhx,2023-02-15,2022-04-11
-5tk0,2017-04-05,2016-10-06
-6tkh,2020-11-04,2019-11-28
-5tkf,2017-05-17,2016-10-06
-4tko,2014-07-09,2014-05-27
-4tkx,2014-12-31,2014-05-28
-6tkq,2020-07-08,2019-11-28
-1tkt,2004-12-07,2004-06-09
-4tk3,2014-12-24,2014-05-25
-1tkr,2004-07-06,2004-06-09
-1tky,2004-11-30,2004-06-09
-6tkr,2020-07-08,2019-11-28
-6tk3,2020-05-27,2019-11-28
-4tk1,2014-12-24,2014-05-25
-5tk7,2016-11-16,2016-10-06
-5tk6,2016-11-23,2016-10-06
-3tki,2012-04-11,2011-08-26
-1tkj,2005-06-14,2004-06-08
-6tkg,2020-11-04,2019-11-28
-1tkf,2005-06-14,2004-06-08
-1tkg,2004-11-30,2004-06-08
-1tkz,2004-12-07,2004-06-09
-6tk5,2020-05-27,2019-11-28
-6tkz,2020-01-22,2019-11-29
-5tkn,2017-10-04,2016-10-07
-8tki,2023-11-08,2023-07-25
-3tk6,2012-08-29,2011-08-25
-5tk2,2016-11-16,2016-10-06
-6tk7,2020-05-27,2019-11-28
-6tkm,2020-07-08,2019-11-28
-5tkq,2017-04-12,2016-10-07
-5tk5,2017-04-12,2016-10-06
-5tkj,2018-04-04,2016-10-06
-4tk2,2014-12-24,2014-05-25
-1tk6,2004-10-19,2004-06-08
-1tk2,2004-06-22,2004-06-08
-5tkt,2017-03-01,2016-10-07
-1tk4,2004-06-22,2004-06-08
-4tkn,2014-07-30,2014-05-27
-3tkw,2012-04-25,2011-08-29
-5tkd,2016-12-28,2016-10-06
-4tkm,2014-06-25,2014-05-27
-6tkn,2020-07-08,2019-11-28
-4tk0,2014-11-05,2014-05-25
-5tkk,2018-04-04,2016-10-06
-3tkl,2012-06-27,2011-08-27
-3tky,2012-08-29,2011-08-29
-1tko,2004-10-19,2004-06-09
-5tk3,2017-10-04,2016-10-06
-4tk5,2014-10-15,2014-05-25
-1tka,1994-11-30,1994-02-07
-6tkj,2020-11-04,2019-11-28
-5tky,2016-11-16,2016-10-10
-5tku,2017-03-01,2016-10-07
-5tkc,2017-10-04,2016-10-06
-3tk1,2011-10-05,2011-08-25
-4tkj,2015-01-28,2014-05-26
-1tkd,2004-08-31,2004-06-08
-8tkg,2023-11-08,2023-07-25
-6tk2,2020-05-27,2019-11-28
-4tkr,2014-06-18,2014-05-27
-5tk9,2016-11-16,2016-10-06
-5tkb,2016-12-28,2016-10-06
-4tky,2015-01-14,2014-05-28
-6tkv,2020-01-29,2019-11-29
-8tkh,2023-11-08,2023-07-25
-5tkm,2017-06-14,2016-10-07
-6tkl,2020-11-04,2019-11-28
-7tku,2022-02-16,2022-01-17
-1tkc,1994-11-30,1994-02-07
-3tkh,2012-04-11,2011-08-26
-3tku,2011-10-05,2011-08-29
-1tkw,2005-05-24,2004-06-09
-1tk3,2004-07-06,2004-06-08
-3tkj,2012-10-10,2011-08-26
-3tkk,2011-11-16,2011-08-26
-5tkp,2017-10-04,2016-10-07
-3tkc,2012-03-07,2011-08-26
-7tkx,2023-01-25,2022-01-17
-7tkz,2023-01-25,2022-01-17
-4tkg,2014-10-15,2014-05-26
-1tkp,2004-10-19,2004-06-09
-1tku,2004-09-07,2004-06-09
-3tkd,2011-09-21,2011-08-26
-8tk8,2023-11-08,2023-07-25
-6tk4,2020-05-27,2019-11-28
-4tk4,2014-12-24,2014-05-25
-1tk8,2004-08-31,2004-06-08
-6tk8,2021-05-26,2019-11-28
-6tks,2020-07-08,2019-11-28
-5tkl,2017-10-04,2016-10-06
-8tkd,2023-11-08,2023-07-25
-1tkq,2004-07-13,2004-06-09
-3tka,2012-05-30,2011-08-25
-6tko,2020-06-17,2019-11-28
-5tkg,2017-05-17,2016-10-06
-5tkr,2017-02-08,2016-10-07
-8tkf,2023-11-08,2023-07-25
-3tkt,2012-02-29,2011-08-29
-4tki,2014-10-15,2014-05-26
-6tki,2020-11-04,2019-11-28
-6tkp,2020-07-08,2019-11-28
-1tkb,1994-11-30,1994-02-07
-1tk5,2004-08-31,2004-06-08
-3tkm,2012-07-04,2011-08-27
-5tki,2017-05-17,2016-10-06
-3tk0,2012-08-29,2011-08-25
-5tks,2017-03-01,2016-10-07
-8tke,2023-11-08,2023-07-25
-7tkt,2022-10-26,2022-01-17
-3tk3,2011-11-16,2011-08-25
-4tkf,2014-11-05,2014-05-26
-3tk8,2011-10-12,2011-08-25
-6tkk,2020-12-16,2019-11-28
-8tkp,2024-03-27,2023-07-25
-6tk6,2020-05-27,2019-11-28
-6tka,2020-03-04,2019-11-28
-4tkc,2015-06-03,2014-05-26
-1tke,2004-11-30,2004-06-08
-5tkv,2017-04-26,2016-10-07
-3tk4,2012-09-05,2011-08-25
-1tkh,2005-06-14,2004-06-08
-4tkp,2015-07-22,2014-05-27
-1tkk,2004-08-31,2004-06-08
-5tkh,2017-05-17,2016-10-06
-1tkx,2004-12-07,2004-06-09
-3tk7,2011-09-07,2011-08-25
-4tkq,2014-06-18,2014-05-27
-3tkz,2011-10-26,2011-08-29
-3tkg,2012-04-25,2011-08-26
-1tk0,2004-08-31,2004-06-07
-6tk1,2020-05-27,2019-11-28
-5tk8,2016-11-16,2016-10-06
-3tk5,2012-08-29,2011-08-25
-3tk2,2012-09-05,2011-08-25
-3tkf,2011-09-07,2011-08-26
-5tka,2016-11-16,2016-10-06
-6d66,2018-09-19,2018-04-20
-3d6z,2008-08-26,2008-05-20
-6d6c,2018-08-08,2018-04-20
-5d63,2016-03-02,2015-08-11
-6d6j,2018-05-02,2018-04-21
-7d6f,2020-11-04,2020-09-30
-6d6f,2018-09-19,2018-04-20
-5d6y,2016-02-10,2015-08-13
-6d61,2018-06-06,2018-04-19
-3d68,2008-07-01,2008-05-19
-6d6b,2018-08-08,2018-04-20
-5d6e,2016-01-13,2015-08-12
-2d63,2006-11-14,2005-11-09
-8d6x,2022-08-03,2022-06-06
-1d6y,2000-02-02,1999-10-16
-6d6a,2018-08-08,2018-04-20
-6d6p,2018-08-08,2018-04-21
-4d64,2016-03-09,2014-11-08
-3d6f,2010-03-02,2008-05-19
-1d6v,2000-02-09,1999-10-15
-7d6l,2021-10-13,2020-09-30
-5d6c,2015-11-11,2015-08-12
-4d6t,2015-01-14,2014-11-14
-2d61,2006-11-14,2005-11-08
-7d63,2021-10-06,2020-09-29
-1d6g,1999-11-17,1999-10-13
-7d6x,2021-04-07,2020-10-02
-8d6v,2022-08-03,2022-06-06
-6d6n,2018-08-08,2018-04-21
-1d6h,2000-02-03,1999-10-13
-3d6o,2009-02-10,2008-05-20
-4d6i,2014-11-26,2014-11-11
-5d6q,2015-11-25,2015-08-12
-3d6n,2009-01-20,2008-05-20
-8d6y,2022-08-03,2022-06-06
-7d6i,2021-10-13,2020-09-30
-3d6y,2008-08-26,2008-05-20
-3d6d,2008-12-30,2008-05-19
-2d6c,2006-10-31,2005-11-11
-2d65,2006-11-14,2005-11-09
-4d6e,2014-11-26,2014-11-11
-8d6c,2022-07-27,2022-06-06
-8d6k,2022-10-19,2022-06-06
-6d6d,2018-08-08,2018-04-20
-8d6f,2022-07-27,2022-06-06
-5d61,2016-03-02,2015-08-11
-4d6o,2014-12-17,2014-11-13
-4d6j,2014-11-26,2014-11-11
-4d6z,2015-09-23,2014-11-19
-8d6n,2023-02-01,2022-06-06
-4d6q,2014-12-24,2014-11-14
-4d6h,2014-11-26,2014-11-11
-3d6g,2009-06-16,2008-05-19
-6d6y,2018-05-09,2018-04-23
-3d6h,2010-03-02,2008-05-19
-7d6g,2021-06-09,2020-09-30
-4d6y,2015-07-08,2014-11-18
-3d60,2009-04-21,2008-05-18
-8d69,2023-05-10,2022-06-06
-5d69,2015-09-02,2015-08-11
-5d6p,2015-11-25,2015-08-12
-5d62,2016-03-02,2015-08-11
-4d6r,2014-12-24,2014-11-14
-6d67,2018-09-19,2018-04-20
-8d62,2023-05-10,2022-06-06
-1d6a,1999-12-16,1999-10-12
-3d6q,2009-02-10,2008-05-20
-7d6r,2021-04-14,2020-10-01
-3d6c,2008-11-04,2008-05-19
-2d64,2006-11-14,2005-11-09
-4d6d,2014-11-26,2014-11-11
-7d6h,2020-11-04,2020-09-30
-1d6q,2000-01-21,1999-10-15
-6d6l,2018-08-08,2018-04-21
-3d62,2008-07-01,2008-05-18
-2d6p,2006-09-26,2005-11-14
-3d6w,2008-07-15,2008-05-20
-1d66,1992-03-06,1992-03-06
-5d65,2016-04-20,2015-08-11
-8d6e,2022-07-27,2022-06-06
-8d6j,2023-05-03,2022-06-06
-6d63,2018-11-14,2018-04-19
-8d6l,2023-02-15,2022-06-06
-7d6m,2020-12-23,2020-10-01
-7d6w,2021-10-06,2020-10-02
-5d6f,2016-01-13,2015-08-12
-3d61,2009-04-21,2008-05-18
-8d6m,2022-11-02,2022-06-06
-3d6p,2009-02-10,2008-05-20
-5d6d,2016-02-10,2015-08-12
-4d6u,2015-01-14,2014-11-14
-6d64,2019-01-16,2018-04-20
-4d6p,2015-01-14,2014-11-13
-6d60,2018-06-06,2018-04-19
-1d6u,2000-02-02,1999-10-15
-5d6l,2016-08-17,2015-08-12
-5d6j,2016-03-02,2015-08-12
-7d6a,2021-01-13,2020-09-29
-2d6f,2006-07-11,2005-11-13
-1d6s,2000-04-15,1999-10-15
-7d6v,2021-04-07,2020-10-02
-1d6w,2000-10-25,1999-10-15
-7d6j,2021-02-03,2020-09-30
-8d6i,2023-05-10,2022-06-06
-6d6u,2018-06-27,2018-04-22
-3d6t,2008-06-10,2008-05-20
-5d6t,2015-09-16,2015-08-12
-8d6a,2023-03-29,2022-06-06
-8d6w,2022-08-03,2022-06-06
-4d6n,2014-12-17,2014-11-13
-2d60,2006-03-07,2005-11-08
-6d62,2018-06-06,2018-04-19
-1d6e,2000-06-28,1999-10-13
-4d6s,2014-12-24,2014-11-14
-6d6t,2018-06-27,2018-04-22
-8d61,2023-05-10,2022-06-06
-6d6q,2018-06-20,2018-04-22
-4d63,2015-10-14,2014-11-08
-8d6t,2022-11-02,2022-06-06
-6d6m,2018-08-08,2018-04-21
-8d6s,2022-11-02,2022-06-06
-2d6n,2006-09-26,2005-11-14
-5d6r,2016-07-20,2015-08-12
-4d62,2015-10-14,2014-11-08
-8d6h,2023-02-01,2022-06-06
-2d66,2006-11-14,2005-11-09
-4d6f,2014-11-26,2014-11-11
-8d6d,2022-07-27,2022-06-06
-7d6b,2021-01-13,2020-09-29
-4d6g,2014-11-26,2014-11-11
-3d6u,2008-05-27,2008-05-20
-6d6w,2018-10-17,2018-04-23
-4d6w,2015-03-04,2014-11-18
-1d6z,2000-02-02,1999-10-16
-7d62,2020-10-28,2020-09-28
-3d66,2008-07-01,2008-05-19
-5d6s,2015-09-23,2015-08-12
-5d6m,2016-03-09,2015-08-12
-3d67,2008-07-01,2008-05-19
-1d6p,2000-01-21,1999-10-15
-8d60,2023-05-10,2022-06-06
-6d6r,2018-06-20,2018-04-22
-3d6m,2010-03-02,2008-05-19
-6d6o,2018-08-08,2018-04-21
-2d6o,2006-09-26,2005-11-14
-5d6o,2015-12-09,2015-08-12
-3d64,2008-06-03,2008-05-18
-2d6m,2006-09-26,2005-11-14
-8d6b,2023-05-10,2022-06-06
-4d69,2014-11-19,2014-11-10
-8d6o,2022-11-02,2022-06-06
-7d6n,2020-12-23,2020-10-01
-7d64,2021-09-29,2020-09-29
-3d6v,2008-05-27,2008-05-20
-7d6y,2021-10-06,2020-10-02
-3d65,2009-06-16,2008-05-19
-5d6a,2015-08-26,2015-08-11
-3d6e,2009-05-19,2008-05-19
-2d6b,2005-11-29,2005-11-10
-1d6n,1999-12-30,1999-10-14
-6d6v,2018-05-30,2018-04-22
-8d6u,2022-11-02,2022-06-06
-3d6b,2008-06-03,2008-05-19
-3d6a,2009-03-03,2008-05-19
-4x99,2015-06-03,2014-12-11
-8x9d,2024-04-17,2023-11-30
-4x98,2015-06-03,2014-12-11
-7x91,2022-12-07,2022-03-15
-4x9c,2014-12-24,2014-12-11
-1x92,2004-10-26,2004-08-19
-6x9n,2020-09-02,2020-06-03
-5x9w,2017-11-22,2017-03-10
-4x9n,2015-03-04,2014-12-11
-4x9i,2015-12-16,2014-12-11
-1x9f,2004-11-30,2004-08-20
-2x98,2010-05-19,2010-03-14
-4x93,2015-03-25,2014-12-11
-6x9p,2021-06-02,2020-06-03
-7x95,2023-03-22,2022-03-15
-6x91,2020-12-09,2020-06-02
-2x9p,2010-08-04,2010-03-23
-6x94,2020-11-04,2020-06-02
-2x9v,2010-06-23,2010-03-24
-6x97,2021-12-08,2020-06-02
-4x96,2015-03-25,2014-12-11
-2x97,2010-06-02,2010-03-14
-4x97,2015-03-11,2014-12-11
-6x9t,2020-11-04,2020-06-03
-2x99,2010-07-21,2010-03-15
-6x9b,2020-12-30,2020-06-02
-4x9q,2015-11-25,2014-12-11
-4x9l,2015-06-10,2014-12-11
-7x94,2023-03-22,2022-03-15
-2x9l,2011-02-09,2010-03-23
-1x9j,2005-08-30,2004-08-21
-7x9p,2023-03-22,2022-03-15
-6x9j,2021-07-07,2020-06-02
-2x94,2010-06-02,2010-03-14
-6x95,2021-06-02,2020-06-02
-4x9e,2015-02-25,2014-12-11
-6x99,2020-12-30,2020-06-02
-4x95,2015-03-25,2014-12-11
-1x9h,2004-12-07,2004-08-21
-7x9k,2022-06-01,2022-03-15
-7x90,2022-12-07,2022-03-15
-6x9k,2021-07-07,2020-06-02
-5x9a,2018-03-14,2017-03-06
-4x9y,2014-12-31,2014-12-11
-6x9i,2021-07-07,2020-06-02
-1x97,2004-09-07,2004-08-19
-4x9k,2014-12-24,2014-12-11
-7x9n,2022-06-01,2022-03-15
-7x9d,2023-03-15,2022-03-15
-6x9r,2020-11-04,2020-06-03
-5x98,2018-03-14,2017-03-05
-1x9r,2005-03-22,2004-08-24
-1x9d,2005-02-22,2004-08-20
-1x9t,2005-01-18,2004-08-24
-4x9m,2015-03-04,2014-12-11
-5x9v,2017-10-25,2017-03-09
-7x9j,2022-06-01,2022-03-15
-7x92,2022-12-07,2022-03-15
-5x9o,2017-08-16,2017-03-08
-1x9m,2004-10-26,2004-08-23
-2x90,2010-06-02,2010-03-14
-1x9p,2005-01-18,2004-08-24
-4x9r,2015-07-29,2014-12-11
-8x93,2024-03-20,2023-11-29
-5x9s,2017-08-30,2017-03-09
-6x96,2021-12-08,2020-06-02
-2x9i,2010-11-17,2010-03-20
-2x9m,2010-04-21,2010-03-23
-8x9f,2024-04-17,2023-11-30
-2x9e,2010-12-29,2010-03-17
-5x9g,2017-08-16,2017-03-07
-7x9q,2022-09-28,2022-03-15
-7x9z,2023-03-22,2022-03-16
-1x9z,2004-10-26,2004-08-24
-4x9g,2015-12-16,2014-12-11
-7x96,2023-03-22,2022-03-15
-8x9e,2024-04-17,2023-11-30
-4x9h,2015-12-16,2014-12-11
-2x9j,2010-11-17,2010-03-21
-8x90,2024-03-20,2023-11-29
-7x9l,2022-06-01,2022-03-15
-2x93,2010-06-02,2010-03-14
-2x9f,2010-09-29,2010-03-17
-5x9h,2017-08-16,2017-03-07
-5x9p,2017-08-16,2017-03-08
-2x92,2010-06-02,2010-03-14
-1x9i,2004-12-07,2004-08-21
-7x93,2023-03-22,2022-03-15
-7x9w,2022-10-12,2022-03-16
-1x9q,2005-03-22,2004-08-24
-2x9h,2011-05-11,2010-03-19
-6x9d,2020-12-30,2020-06-02
-6x9v,2020-11-04,2020-06-03
-6x9c,2020-12-30,2020-06-02
-2x9o,2011-03-30,2010-03-23
-6x9q,2020-09-02,2020-06-03
-6x90,2021-03-24,2020-06-02
-1x9l,2004-08-31,2004-08-23
-8x91,2024-03-20,2023-11-29
-1x9n,2004-11-30,2004-08-23
-4x9f,2015-12-16,2014-12-11
-6x9u,2020-11-04,2020-06-03
-4x9p,2015-01-14,2014-12-11
-7x9f,2022-12-14,2022-03-15
-8x9h,2024-04-17,2023-11-30
-4x9j,2015-05-13,2014-12-11
-2x9x,2010-06-30,2010-03-25
-1x9w,2004-10-26,2004-08-24
-4x9b,2015-12-16,2014-12-11
-2x91,2010-06-02,2010-03-14
-5x9r,2017-06-14,2017-03-08
-7x97,2022-12-14,2022-03-15
-8x9g,2024-04-17,2023-11-30
-6x98,2021-12-08,2020-06-02
-1x9s,2004-10-26,2004-08-24
-7x9o,2022-06-01,2022-03-15
-2x9g,2010-06-16,2010-03-18
-5x94,2017-09-13,2017-03-05
-4x91,2015-03-11,2014-12-11
-6x9h,2020-12-30,2020-06-02
-4x92,2015-03-11,2014-12-11
-6x9m,2021-06-02,2020-06-03
-7x9x,2023-02-15,2022-03-16
-5x99,2018-03-14,2017-03-06
-6x9f,2020-09-02,2020-06-02
-2x95,2010-06-02,2010-03-14
-1x98,2004-09-07,2004-08-19
-6x9s,2020-11-04,2020-06-03
-2x9d,2011-03-23,2010-03-15
-4x94,2015-03-11,2014-12-11
-5x93,2017-08-16,2017-03-05
-5x9d,2018-05-02,2017-03-06
-4x90,2015-03-11,2014-12-11
-4x9d,2015-12-23,2014-12-11
-7x9h,2022-06-01,2022-03-15
-4x9w,2015-07-29,2014-12-11
-2x9n,2010-06-30,2010-03-23
-5x9i,2018-03-07,2017-03-07
-1x96,2004-09-07,2004-08-19
-6x9a,2020-12-30,2020-06-02
-2x96,2010-06-02,2010-03-14
-1x9u,2005-03-22,2004-08-24
-6x9l,2020-09-09,2020-06-03
-5x9u,2017-10-25,2017-03-09
-7x9i,2022-06-01,2022-03-15
-6gym,2018-12-05,2018-06-30
-1gy1,2002-05-23,2002-04-16
-3gyu,2009-07-07,2009-04-05
-2gyd,2006-06-13,2006-05-09
-8gy3,2023-08-02,2022-09-21
-4gyf,2013-02-06,2012-09-05
-6gyx,2019-01-23,2018-07-02
-6gya,2019-01-23,2018-06-28
-6gy9,2018-08-22,2018-06-28
-2gyv,2006-08-15,2006-05-10
-2gyw,2006-08-15,2006-05-10
-6gye,2019-07-10,2018-06-29
-3gyb,2009-04-14,2009-04-03
-8gyq,2024-04-17,2022-09-23
-1gyc,2002-08-22,2002-04-23
-4gy9,2013-09-04,2012-09-05
-2gy5,2006-06-06,2006-05-09
-5gy2,2017-02-15,2016-09-21
-6gyu,2018-12-05,2018-07-02
-4gy0,2013-08-21,2012-09-05
-1gy8,2003-05-22,2002-04-21
-8gyt,2024-04-17,2022-09-23
-1gyb,2002-06-20,2002-04-22
-3gya,2009-04-21,2009-04-03
-8gyc,2023-10-18,2022-09-22
-3gys,2010-03-16,2009-04-05
-8gyd,2023-08-23,2022-09-22
-1gyl,1995-03-31,1995-01-30
-4gy7,2012-11-07,2012-09-05
-4gyb,2013-10-02,2012-09-05
-4gyp,2012-09-12,2012-09-05
-3gy4,2010-03-23,2009-04-03
-3gyl,2009-04-21,2009-04-03
-8gy6,2023-11-01,2022-09-21
-5gy0,2017-09-27,2016-09-21
-2gy7,2006-06-06,2006-05-09
-1gyp,1995-12-07,1995-08-01
-6gyr,2018-10-17,2018-07-01
-3gyd,2009-04-21,2009-04-03
-8gyg,2023-10-18,2022-09-22
-4gyi,2012-10-17,2012-09-05
-8gyk,2023-08-30,2022-09-22
-8gya,2023-09-27,2022-09-21
-3gyy,2010-04-07,2009-04-06
-8gy1,2023-03-29,2022-09-21
-3gy7,2010-03-23,2009-04-03
-6gyt,2018-10-17,2018-07-01
-3gyi,2009-12-01,2009-04-03
-3gye,2010-04-07,2009-04-03
-4gy1,2013-08-21,2012-09-05
-3gyj,2009-12-01,2009-04-03
-3gyr,2009-04-28,2009-04-05
-4gyj,2012-12-19,2012-09-05
-6gyf,2019-07-10,2018-06-29
-5gy7,2016-11-30,2016-09-21
-4gye,2013-10-30,2012-09-05
-8gym,2023-06-14,2022-09-23
-1gym,1996-11-08,1996-05-02
-4gyk,2012-12-19,2012-09-05
-1gyg,2002-06-13,2002-04-23
-8gy7,2023-01-11,2022-09-21
-8gyb,2023-09-27,2022-09-22
-4gy3,2013-03-06,2012-09-05
-8gye,2023-09-27,2022-09-22
-1gya,1996-11-08,1995-05-26
-1gyy,2002-10-10,2002-04-30
-6gy5,2018-08-08,2018-06-28
-4gyo,2013-04-03,2012-09-05
-3gyf,2009-11-03,2009-04-03
-1gye,2002-08-23,2002-04-23
-1gyq,1999-03-16,1999-03-05
-4gyc,2013-05-08,2012-09-05
-4gy5,2012-11-14,2012-09-05
-5gy6,2017-09-27,2016-09-21
-3gy1,2009-04-14,2009-04-03
-3gyh,2009-06-16,2009-04-03
-6gyi,2019-01-30,2018-06-29
-3gy3,2010-03-23,2009-04-03
-4gyw,2012-10-31,2012-09-05
-8gyi,2023-02-22,2022-09-22
-8gyw,2023-03-22,2022-09-24
-1gy2,2002-05-23,2002-04-16
-6gyo,2019-05-01,2018-06-30
-2gys,2006-06-20,2006-05-09
-8gy9,2023-09-27,2022-09-21
-3gyg,2009-05-12,2009-04-03
-6gyk,2018-12-05,2018-06-30
-3gyt,2009-07-07,2009-04-05
-6gyp,2018-12-05,2018-07-01
-6gys,2018-12-05,2018-07-01
-3gyx,2009-12-15,2009-04-06
-6gyl,2018-12-05,2018-06-30
-8gyj,2023-02-22,2022-09-22
-8gyp,2024-04-17,2022-09-23
-4gy2,2013-02-20,2012-09-05
-1gyk,2003-05-22,2002-04-25
-4gy4,2012-09-19,2012-09-05
-3gy8,2010-03-23,2009-04-03
-6gy1,2018-10-10,2018-06-27
-3gy2,2010-03-23,2009-04-03
-5gyz,2017-09-27,2016-09-26
-6gyh,2019-03-27,2018-06-29
-3gyz,2009-06-16,2009-04-06
-4gyq,2012-09-26,2012-09-05
-3gy0,2009-04-14,2009-04-03
-1gy3,2002-04-29,2002-04-19
-5gy1,2017-09-27,2016-09-21
-6gy0,2019-02-06,2018-06-27
-4gyd,2013-09-11,2012-09-05
-4gym,2012-09-26,2012-09-05
-8gy2,2023-08-02,2022-09-21
-1gyt,2002-06-06,2002-04-29
-5gyq,2016-10-26,2016-09-23
-1gy9,2002-04-26,2002-04-22
-8gyo,2024-04-17,2022-09-23
-8gyx,2023-03-22,2022-09-24
-6gyj,2019-08-28,2018-06-30
-2gyo,2007-06-05,2006-05-09
-4gyt,2012-09-26,2012-09-05
-5gyy,2017-09-27,2016-09-24
-8gyy,2023-10-25,2022-09-24
-2gyk,2007-05-15,2006-05-09
-2gyq,2006-06-13,2006-05-09
-3gyq,2009-04-14,2009-04-04
-4gyl,2013-08-21,2012-09-05
-2gyu,2006-08-15,2006-05-10
-3gy9,2009-04-21,2009-04-03
-5gyn,2017-09-27,2016-09-23
-3gy6,2010-03-23,2009-04-03
-1gyo,2002-05-24,2002-04-29
-8gyr,2023-06-28,2022-09-23
-3gy5,2010-03-23,2009-04-03
-3gyn,2009-12-08,2009-04-04
-1gyn,2003-02-26,2002-04-27
-4gyy,2012-10-31,2012-09-05
-4gyz,2012-10-31,2012-09-05
-5gyr,2017-02-08,2016-09-23
-2gyi,1995-07-10,1994-09-01
-3fil,2009-08-18,2008-12-12
-2fi3,2006-01-24,2005-12-27
-5fix,2016-02-10,2015-10-02
-1fig,1994-05-31,1994-01-07
-2fif,2006-02-07,2005-12-29
-8fi6,2022-12-28,2022-12-15
-5fis,2015-12-23,2015-10-02
-8fiv,2023-08-09,2022-12-16
-1fi6,2001-07-18,2000-08-03
-8fiu,2023-02-15,2022-12-16
-5fiy,2016-11-16,2015-10-03
-4fic,2013-04-10,2012-06-08
-8fim,2023-09-06,2022-12-16
-6fiz,2019-03-06,2018-01-19
-7fi0,2021-10-27,2021-07-30
-5fib,2016-07-06,2015-12-22
-1fiq,2000-10-04,2000-08-04
-1fit,1997-11-19,1997-05-17
-5fi7,2016-05-11,2015-12-22
-3fid,2009-02-10,2008-12-11
-1fi3,2001-03-14,2000-08-03
-2fix,2006-02-21,2005-12-30
-3fi5,2009-02-17,2008-12-11
-4fik,2012-06-27,2012-06-08
-8fif,2023-12-20,2022-12-16
-6fit,1998-03-25,1997-09-25
-4fi8,2013-02-20,2012-06-08
-2fie,2006-02-21,2005-12-29
-7fi1,2021-10-27,2021-07-30
-5fit,1998-03-25,1997-09-25
-2fik,2006-03-21,2005-12-29
-5fiu,2015-12-23,2015-10-02
-2fi5,2006-01-24,2005-12-27
-7fie,2021-11-24,2021-07-31
-5fic,2016-07-06,2015-12-22
-7fix,2022-09-21,2021-08-01
-6fij,2018-03-21,2018-01-18
-7fig,2021-09-29,2021-07-31
-2fiw,2006-02-14,2005-12-30
-6fi5,2018-05-16,2018-01-17
-6fih,2018-07-11,2018-01-18
-5fi6,2016-05-11,2015-12-22
-1fi2,2001-05-01,2000-08-03
-1fic,1997-04-01,1996-08-24
-8fis,2023-02-01,2022-12-16
-8fiy,2023-03-29,2022-12-17
-4fir,2012-11-14,2012-06-11
-6fiv,1998-12-09,1998-12-02
-7fi3,2022-04-13,2021-07-30
-5fin,2016-11-16,2015-09-30
-1fi9,2000-08-23,2000-08-03
-4fig,2012-09-12,2012-06-08
-8fib,2023-07-05,2022-12-16
-4fia,2013-01-09,2012-06-08
-2fir,2006-07-11,2005-12-30
-8fix,2023-03-29,2022-12-17
-4fiy,2012-06-20,2012-06-11
-6fiw,2019-01-30,2018-01-19
-2fib,1997-10-15,1997-06-03
-7fiz,2021-11-24,2021-08-01
-4fip,2012-07-25,2012-06-10
-6fir,2019-01-30,2018-01-19
-2fi4,2006-01-24,2005-12-27
-1fi5,2000-08-23,2000-08-03
-6fi2,2018-05-02,2018-01-16
-4fi7,2013-02-20,2012-06-08
-3fi0,2009-02-03,2008-12-10
-5fi3,2016-07-27,2015-12-22
-1fif,2000-08-23,2000-08-03
-3fie,2009-06-23,2008-12-11
-6fic,2018-01-31,2018-01-17
-4fie,2012-09-12,2012-06-08
-5fi2,2016-05-11,2015-12-22
-2fiv,1997-11-12,1997-07-21
-1fiy,1999-02-09,1998-05-02
-7fih,2021-09-29,2021-07-31
-4fii,2012-09-12,2012-06-08
-8fij,2023-09-06,2022-12-16
-3fi3,2009-03-03,2008-12-10
-6fi4,2018-05-16,2018-01-17
-8fii,2023-09-06,2022-12-16
-6fi9,2019-02-20,2018-01-17
-5fiv,1998-12-09,1998-12-02
-7fis,2022-01-05,2021-08-01
-5fio,2016-11-16,2015-09-30
-4fiz,2013-07-03,2012-06-11
-8fia,2023-05-03,2022-12-15
-2fiy,2006-02-14,2005-12-30
-3fi2,2009-03-03,2008-12-10
-6fii,2018-05-30,2018-01-18
-8fiw,2023-08-09,2022-12-16
-6fiy,2018-08-08,2018-01-19
-6fi3,2019-01-30,2018-01-16
-8fic,2023-07-05,2022-12-16
-1fi1,2001-08-29,2000-08-03
-7fio,2022-02-16,2021-07-31
-4fil,2013-06-12,2012-06-08
-6fil,2018-11-28,2018-01-19
-4fix,2012-06-20,2012-06-11
-1fin,1997-01-27,1996-07-14
-4fiv,1999-01-13,1998-07-15
-6fio,2018-11-28,2018-01-19
-7fid,2021-11-24,2021-07-31
-3fi4,2009-12-22,2008-12-10
-5fi5,2016-07-27,2015-12-22
-8fi9,2024-01-17,2022-12-15
-6fin,2018-11-28,2018-01-19
-5fih,2016-02-17,2015-09-25
-3fit,1997-11-19,1997-05-17
-5fii,2016-03-30,2015-09-25
-6fie,2018-10-10,2018-01-18
-2fi1,2006-02-07,2005-12-27
-3fig,2008-12-23,2008-12-11
-1fih,2000-08-23,2000-08-03
-6fid,2018-02-07,2018-01-18
-1fiv,1995-07-31,1995-05-04
-2fid,2006-02-07,2005-12-29
-7fip,2022-01-05,2021-08-01
-6fi8,2018-03-28,2018-01-17
-4fi1,2013-06-19,2012-06-07
-3fij,2009-01-13,2008-12-11
-3fii,2009-06-23,2008-12-11
-6fi1,2018-03-21,2018-01-16
-3fim,2009-11-03,2008-12-12
-1fiw,2000-11-08,2000-08-07
-3fib,1997-09-17,1997-07-14
-6fig,2018-07-11,2018-01-18
-8fik,2023-09-06,2022-12-16
-3fi6,2009-04-07,2008-12-11
-4fi3,2012-09-19,2012-06-07
-2fic,2006-11-14,2005-12-29
-8fig,2023-11-22,2022-12-16
-5fi4,2016-02-03,2015-12-22
-5fie,2016-07-20,2015-12-23
-4fim,2012-06-27,2012-06-09
-8fid,2023-07-05,2022-12-16
-4fif,2012-09-12,2012-06-08
-1fid,1997-04-01,1996-08-24
-3fi8,2009-02-10,2008-12-11
-3fiu,2009-03-03,2008-12-12
-8fi4,2022-12-28,2022-12-15
-6fi6,2019-01-30,2018-01-17
-5fiw,2015-10-14,2015-10-02
-4fiu,2012-11-21,2012-06-11
-8fi3,2022-12-28,2022-12-15
-5fi8,2016-05-18,2015-12-22
-4fid,2012-11-28,2012-06-08
-1fio,2000-10-11,2000-08-04
-2fit,1997-11-19,1997-05-17
-1fib,1997-04-01,1996-04-02
-7fiq,2022-01-05,2021-08-01
-8fie,2023-07-05,2022-12-16
-7fin,2022-02-23,2021-07-31
-8fi5,2022-12-28,2022-12-15
-3fiv,1997-11-12,1997-07-09
-3fia,2008-12-30,2008-12-11
-6fis,2019-01-30,2018-01-19
-1fi7,2000-08-23,2000-08-03
-3fir,2009-03-10,2008-12-12
-6fiq,2018-11-28,2018-01-19
-8fip,2023-09-20,2022-12-16
-4fi4,2012-06-27,2012-06-07
-5fi9,2016-07-06,2015-12-22
-7fir,2022-01-05,2021-08-01
-6fi0,2018-03-21,2018-01-16
-7fic,2022-06-08,2021-07-31
-4fi6,2013-02-20,2012-06-08
-2fim,2006-02-07,2005-12-29
-8fio,2023-09-20,2022-12-16
-1fiu,2001-02-07,2000-08-07
-6fiu,2019-01-30,2018-01-19
-1fiz,2000-11-08,2000-08-07
-7fiy,2022-03-02,2021-08-01
-6fif,2018-01-31,2018-01-18
-6ijp,2019-02-06,2018-10-11
-5ijs,2016-06-15,2016-03-02
-3ij8,2009-10-27,2009-08-04
-6ijr,2019-10-16,2018-10-11
-2ij5,2006-11-07,2006-09-29
-5ij4,2016-10-05,2016-03-01
-1ije,2001-05-09,2001-04-26
-2ij2,2006-11-07,2006-09-29
-8ijn,2023-04-12,2023-02-27
-3ij3,2009-08-11,2009-08-03
-1ijl,2001-12-28,2001-04-27
-5ijt,2017-09-06,2016-03-02
-3ijs,2009-10-06,2009-08-04
-3ijh,2009-10-06,2009-08-04
-4ijd,2013-02-13,2012-12-21
-4iji,2013-02-20,2012-12-21
-4ijk,2013-01-09,2012-12-21
-8ijv,2023-08-30,2023-02-28
-3ijd,2009-09-01,2009-08-04
-5ijx,2016-04-06,2016-03-02
-3ij1,2009-09-15,2009-08-03
-4ij9,2013-05-01,2012-12-21
-8ijd,2024-01-03,2023-02-27
-5ij9,2016-04-20,2016-03-01
-8ij9,2023-06-14,2023-02-26
-4ij1,2013-12-25,2012-12-20
-5iju,2016-09-21,2016-03-02
-5ijf,2016-03-16,2016-03-02
-1ijj,2002-04-15,2001-04-26
-6ija,2019-09-18,2018-10-09
-4ijo,2013-05-01,2012-12-22
-1ij1,2001-08-08,2001-04-24
-6ijm,2019-02-06,2018-10-10
-3ije,2009-09-29,2009-08-04
-4ij4,2014-03-26,2012-12-21
-1ijd,2001-10-17,2001-04-25
-4ijr,2013-11-27,2012-12-23
-2ij3,2006-11-07,2006-09-29
-6ij2,2019-10-09,2018-10-08
-6ijh,2019-04-10,2018-10-10
-3ijl,2010-07-21,2009-08-04
-6iji,2019-04-10,2018-10-10
-1ijh,2001-12-28,2001-04-26
-4ijl,2013-08-14,2012-12-21
-8ijw,2023-08-30,2023-02-28
-4ijw,2014-06-11,2012-12-23
-8ij6,2024-02-28,2023-02-26
-1ij0,2001-08-08,2001-04-24
-2ij7,2006-11-07,2006-09-29
-8ijm,2023-08-02,2023-02-27
-5ije,2016-04-27,2016-03-01
-8ijl,2023-10-18,2023-02-27
-3ijy,2009-10-06,2009-08-05
-3ij6,2009-08-18,2009-08-03
-5ij3,2017-02-08,2016-03-01
-3ij7,2009-10-27,2009-08-03
-5ijw,2016-05-25,2016-03-02
-6ijx,2019-10-16,2018-10-12
-5ijz,2016-03-23,2016-03-03
-5ijd,2016-04-27,2016-03-01
-8ij1,2024-02-28,2023-02-24
-1ij6,2003-02-11,2001-04-25
-3ijo,2009-09-15,2009-08-04
-4ij6,2013-03-20,2012-12-21
-5ijr,2017-03-29,2016-03-02
-3ijg,2010-06-16,2009-08-04
-4ije,2013-10-09,2012-12-21
-5ij0,2016-04-20,2016-03-01
-3ijx,2009-09-15,2009-08-05
-4iju,2014-06-11,2012-12-23
-5ij2,2017-02-08,2016-03-01
-2ij4,2006-11-07,2006-09-29
-5ijl,2016-08-31,2016-03-02
-6ijo,2019-03-20,2018-10-10
-6ijj,2019-03-20,2018-10-10
-8ijk,2024-01-17,2023-02-27
-5ijc,2016-04-27,2016-03-01
-4ijn,2013-01-16,2012-12-21
-5ij5,2016-03-16,2016-03-01
-5ijb,2016-04-27,2016-03-01
-4ija,2013-06-12,2012-12-21
-4ij2,2013-12-25,2012-12-21
-1ijv,2001-10-24,2001-04-30
-4ijq,2013-03-27,2012-12-22
-6ijs,2019-10-16,2018-10-11
-2ijd,2007-02-13,2006-09-29
-6ijl,2019-08-14,2018-10-10
-4ijs,2013-04-24,2012-12-23
-8ijs,2023-12-27,2023-02-28
-8ijg,2024-03-06,2023-02-27
-1ijf,2001-05-09,2001-04-26
-4ijh,2013-08-14,2012-12-21
-4ijm,2013-02-13,2012-12-21
-3ij9,2009-10-27,2009-08-04
-4ijg,2013-12-25,2012-12-21
-5ijq,2016-06-15,2016-03-02
-3ijc,2009-09-15,2009-08-04
-5ijk,2017-03-15,2016-03-02
-8ija,2024-01-03,2023-02-26
-5ij7,2016-05-04,2016-03-01
-4ijt,2013-08-14,2012-12-23
-6ijn,2019-02-06,2018-10-10
-2ijn,2006-11-28,2006-09-29
-4ijx,2013-03-20,2012-12-24
-6ijb,2019-07-03,2018-10-09
-5ij8,2016-05-04,2016-03-01
-5ij1,2017-02-08,2016-03-01
-3ijz,2010-08-11,2009-08-05
-2ijg,2006-11-28,2006-09-29
-4ijv,2014-06-11,2012-12-23
-3ijr,2009-09-08,2009-08-04
-8ijr,2024-02-28,2023-02-28
-8ijb,2024-01-03,2023-02-27
-1iji,2001-08-29,2001-04-26
-6ij9,2019-10-16,2018-10-09
-2ijm,2007-08-14,2006-09-29
-3ij0,2009-09-15,2009-08-03
-4ijp,2013-08-28,2012-12-22
-3ijm,2009-09-22,2009-08-04
-3ijq,2010-07-21,2009-08-04
-3ij4,2009-11-10,2009-08-03
-6ijy,2019-02-20,2018-10-12
-2ija,2006-11-28,2006-09-29
-3ijw,2009-10-13,2009-08-05
-6ijd,2019-09-18,2018-10-09
-5ijg,2017-04-05,2016-03-02
-3ijf,2010-03-02,2009-08-04
-1ijs,1996-12-23,1996-09-12
-6ijt,2019-10-16,2018-10-12
-8ijx,2023-08-30,2023-02-28
-1ijr,2002-05-01,2001-04-27
-3iji,2010-07-21,2009-08-04
-5ij6,2017-03-15,2016-03-01
-3ijj,2010-06-16,2009-08-04
-4ij7,2013-10-16,2012-12-21
-1ij2,2001-08-08,2001-04-24
-1ij8,2001-09-12,2001-04-25
-1adc,1995-06-03,1993-12-13
-2add,2006-08-29,2005-07-20
-1ad4,1998-04-29,1997-02-20
-5ad3,2016-09-28,2015-08-19
-4adf,2012-08-22,2011-12-23
-5ad6,2015-10-28,2015-08-20
-1ady,1997-08-20,1997-02-19
-6adq,2018-11-14,2018-08-01
-5adf,2015-10-28,2015-08-20
-7ad7,2021-03-10,2020-09-14
-7adc,2020-11-25,2020-09-14
-5ad9,2015-10-28,2015-08-20
-1ad2,1997-05-15,1997-02-20
-4adu,2012-01-25,2012-01-03
-7ad8,2021-07-28,2020-09-14
-7adg,2021-10-06,2020-09-14
-3ad4,2011-01-19,2010-01-14
-4adg,2013-01-09,2011-12-26
-3adt,2010-12-22,2010-01-29
-5ad5,2015-10-28,2015-08-20
-2adr,1998-06-17,1998-03-20
-6add,2018-12-26,2018-07-31
-8ad3,2023-07-12,2022-07-07
-4ad3,2012-02-01,2011-12-21
-5adj,2015-10-28,2015-08-20
-5ad8,2015-10-28,2015-08-20
-2adj,2005-09-20,2005-07-20
-3adp,2010-02-09,2010-01-26
-4adc,2013-01-16,2011-12-23
-6adu,2019-08-21,2018-08-02
-2adm,1997-01-27,1996-07-15
-7adb,2020-11-04,2020-09-14
-4adq,2012-08-22,2012-01-02
-5adk,2015-10-28,2015-08-20
-1adf,1994-01-31,1993-10-18
-7adi,2022-01-12,2020-09-15
-7ad3,2020-12-09,2020-09-14
-7adw,2020-12-02,2020-09-16
-2ad6,2006-07-25,2005-07-20
-5adt,2016-01-13,2015-08-24
-4ad6,2013-01-16,2011-12-22
-5ad7,2015-10-28,2015-08-20
-6ady,2019-03-13,2018-08-02
-3ada,2010-08-25,2010-01-15
-6ade,2018-08-22,2018-07-31
-3adb,2010-07-28,2010-01-18
-5adn,2015-10-28,2015-08-20
-7adt,2021-10-06,2020-09-16
-8adh,1989-10-15,1989-04-20
-6adc,2019-08-28,2018-07-31
-8adl,2022-11-02,2022-07-08
-8ad1,2022-10-19,2022-07-07
-4ad9,2012-02-01,2011-12-22
-5adu,2015-11-25,2015-08-24
-6adx,2019-03-13,2018-08-02
-2ada,1995-03-31,1994-12-02
-2ady,2006-07-11,2005-07-21
-7adh,1984-07-18,1984-01-16
-1add,1994-01-31,1992-12-22
-3adz,2010-11-24,2010-01-31
-8adr,2023-08-16,2022-07-11
-5add,2015-10-28,2015-08-20
-2adq,2006-07-04,2005-07-20
-1adv,1996-06-20,1995-05-12
-3ad5,2011-01-19,2010-01-14
-8adm,2023-04-26,2022-07-08
-5ada,2015-10-28,2015-08-20
-8ady,2022-10-26,2022-07-12
-2ad9,2005-10-04,2005-07-20
-8ad6,2023-07-19,2022-07-07
-7adp,2020-12-02,2020-09-15
-1adg,1994-01-31,1993-10-18
-1adj,1997-08-20,1997-02-18
-4ado,2012-03-07,2011-12-31
-7adx,2021-10-06,2020-09-16
-7ad5,2021-10-06,2020-09-14
-2ad5,2005-11-01,2005-07-19
-4adb,2013-01-16,2011-12-23
-7adf,2021-10-06,2020-09-14
-6adl,2019-12-25,2018-08-01
-1adn,1994-01-31,1993-09-30
-5ad4,2015-10-28,2015-08-20
-2ad8,2006-07-25,2005-07-20
-5adq,2016-01-13,2015-08-24
-2adu,2005-09-13,2005-07-20
-5adi,2015-10-28,2015-08-20
-1adb,1995-06-03,1993-12-13
-5ade,2015-10-28,2015-08-20
-8ad5,2023-07-12,2022-07-07
-8ad8,2022-10-12,2022-07-08
-2ad7,2006-07-25,2005-07-20
-6adm,2019-02-06,2018-08-01
-8ad2,2023-01-18,2022-07-07
-6adi,2018-09-05,2018-08-01
-5ady,2015-10-14,2015-08-25
-5adv,2016-05-25,2015-08-24
-8ad0,2023-07-12,2022-07-07
-5adg,2015-10-28,2015-08-20
-8ad9,2023-03-29,2022-07-08
-2adp,2006-07-04,2005-07-20
-1adu,1996-06-20,1995-05-11
-3adr,2010-04-21,2010-01-28
-3adw,2010-12-22,2010-01-29
-6ad5,2019-08-14,2018-07-30
-3ad7,2010-08-25,2010-01-15
-3ad6,2011-01-19,2010-01-14
-1ad8,1997-11-12,1997-02-24
-3ads,2010-12-22,2010-01-29
-5adr,2016-01-13,2015-08-24
-5adc,2015-10-28,2015-08-20
-3adc,2010-07-28,2010-01-18
-8adi,2023-01-11,2022-07-08
-2ade,2006-08-29,2005-07-20
-7ad0,2020-10-28,2020-09-13
-4adi,2013-01-09,2011-12-26
-3adu,2010-12-22,2010-01-29
-7adn,2021-06-16,2020-09-15
-4adn,2012-03-07,2011-12-31
-7adu,2021-03-24,2020-09-16
-5ad0,2016-09-28,2015-08-19
-5adz,2015-09-23,2015-08-25
-7add,2020-11-25,2020-09-14
-4adw,2013-01-16,2012-01-04
-8adz,2022-10-26,2022-07-12
-4ad7,2012-03-21,2011-12-22
-1ad3,1997-07-07,1996-06-25
-8ad4,2023-07-12,2022-07-07
-3adv,2010-12-22,2010-01-29
-5adm,2015-10-28,2015-08-20
-8adf,2023-04-26,2022-07-08
-6ad9,2018-11-14,2018-07-31
-1ad1,1998-04-29,1997-02-19
-8adq,2022-11-23,2022-07-11
-7ad9,2020-10-28,2020-09-14
-4add,2013-01-16,2011-12-23
-3add,2010-07-28,2010-01-18
-5ad1,2016-09-28,2015-08-19
-2adc,2005-10-04,2005-07-20
-4ad5,2012-02-01,2011-12-21
-1ad5,1997-05-15,1997-02-20
-4adj,2013-01-09,2011-12-26
-3ade,2010-03-16,2010-01-19
-7adq,2021-11-03,2020-09-15
-4ad4,2012-02-01,2011-12-21
-6adg,2018-09-05,2018-08-01
-8adj,2023-06-14,2022-07-08
-6adf,2019-08-14,2018-07-31
-7ad6,2021-03-10,2020-09-14
-5ads,2016-01-13,2015-08-24
-7ado,2020-12-02,2020-09-15
-7ads,2021-10-06,2020-09-16
-3ad9,2010-08-25,2010-01-15
-3ad8,2010-08-25,2010-01-15
-7adv,2021-03-24,2020-09-16
-8ad7,2022-10-12,2022-07-08
-2adi,2005-09-20,2005-07-20
-5adb,2015-10-28,2015-08-20
-6ad4,2019-07-31,2018-07-30
-5ad2,2016-09-28,2015-08-19
-2adb,2005-10-04,2005-07-20
-6adr,2019-02-06,2018-08-02
-7ad1,2020-11-04,2020-09-14
-3adx,2010-12-22,2010-01-29
-5adh,1984-07-18,1984-01-16
-4ad2,2012-02-01,2011-12-21
-1adw,1997-05-15,1997-02-18
-5adl,2015-10-28,2015-08-20
-6adj,2019-08-07,2018-08-01
-2adw,2006-03-28,2005-07-21
-7ade,2020-11-25,2020-09-14
-5adw,2016-05-25,2015-08-24
-1ads,1993-10-31,1992-07-08
-6adh,1984-07-18,1984-01-16
-4d0n,2014-05-21,2014-04-29
-6d03,2018-06-20,2018-04-10
-5d0y,2016-04-06,2015-08-03
-3d09,2009-01-20,2008-05-01
-1d0q,2000-03-29,1999-09-14
-6d0v,2019-04-17,2018-04-11
-5d09,2016-08-10,2015-08-02
-4d0t,2014-05-28,2014-04-30
-8d02,2023-05-24,2022-05-25
-2d02,2006-04-04,2005-07-21
-7d0o,2021-07-07,2020-09-11
-3d0n,2008-07-29,2008-05-02
-8d0z,2023-03-22,2022-05-26
-3d00,2008-05-20,2008-04-30
-4d0c,2015-05-06,2014-04-25
-5d0s,2016-03-23,2015-08-03
-3d0b,2008-06-17,2008-05-01
-1d0o,2001-11-21,1999-09-13
-3d0y,2009-04-14,2008-05-02
-8d0d,2022-09-21,2022-05-26
-5d0b,2016-09-28,2015-08-03
-8d0f,2022-09-21,2022-05-26
-7d0j,2021-03-03,2020-09-10
-3d03,2008-10-14,2008-04-30
-5d0v,2016-03-23,2015-08-03
-7d0b,2021-03-10,2020-09-09
-6d00,2019-04-03,2018-04-09
-7d0p,2021-07-07,2020-09-11
-4d0d,2015-05-06,2014-04-25
-6d0b,2018-10-31,2018-04-10
-6d07,2019-04-10,2018-04-10
-6d0u,2019-01-16,2018-04-11
-6d05,2018-06-20,2018-04-10
-4d0x,2014-07-23,2014-04-30
-2d0e,2005-10-25,2005-08-02
-6d04,2018-06-20,2018-04-10
-4d0g,2015-05-20,2014-04-25
-2d0f,2006-07-11,2005-08-02
-3d0z,2009-02-24,2008-05-02
-4d07,2014-10-22,2014-04-24
-5d0x,2016-03-23,2015-08-03
-2d0n,2005-08-23,2005-08-04
-4d0b,2015-05-06,2014-04-25
-3d0v,2008-07-29,2008-05-02
-7d0a,2020-12-16,2020-09-09
-2d0q,2006-02-05,2005-08-05
-2d09,2005-10-25,2005-07-30
-4d0y,2014-08-06,2014-04-30
-3d0a,2009-01-20,2008-05-01
-1d07,2000-09-11,1999-09-09
-1d0j,2000-03-08,1999-09-10
-2d0v,2006-08-09,2005-08-09
-1d0k,2000-03-06,1999-09-12
-7d0v,2021-09-15,2020-09-12
-1d06,2000-03-15,1999-09-09
-8d0c,2022-09-21,2022-05-26
-7d0s,2021-07-07,2020-09-11
-5d05,2016-08-10,2015-08-02
-1d04,1999-12-29,1999-09-08
-4d09,2014-08-06,2014-04-24
-7d0u,2021-09-15,2020-09-11
-4d01,2014-10-01,2014-04-23
-5d0j,2016-06-15,2015-08-03
-5d0g,2016-08-10,2015-08-03
-3d06,2009-01-20,2008-05-01
-7d03,2021-03-10,2020-09-09
-6d06,2019-02-20,2018-04-10
-8d0q,2023-05-31,2022-05-26
-2d0o,2006-02-28,2005-08-05
-2d0w,2006-08-10,2005-08-10
-2d0c,2006-07-18,2005-07-31
-1d0s,1999-12-29,1999-09-14
-1d0c,2001-11-21,1999-09-09
-5d0e,2016-08-10,2015-08-03
-5d08,2016-09-28,2015-08-02
-7d0d,2021-03-10,2020-09-09
-4d00,2014-06-11,2014-04-23
-5d02,2016-08-10,2015-08-02
-5d0i,2015-12-09,2015-08-03
-7d09,2020-12-16,2020-09-09
-8d0h,2022-09-21,2022-05-26
-5d04,2016-08-10,2015-08-02
-5d0h,2016-08-10,2015-08-03
-7d08,2020-12-16,2020-09-09
-1d03,1999-12-29,1999-09-08
-6d08,2019-04-10,2018-04-10
-2d0p,2006-02-28,2005-08-05
-8d0m,2022-09-21,2022-05-26
-3d0g,2008-07-08,2008-05-01
-8d0v,2023-01-25,2022-05-26
-1d00,2000-03-29,1999-09-07
-4d0r,2015-05-20,2014-04-29
-1d0l,2000-03-06,1999-09-12
-4d0p,2014-07-23,2014-04-29
-5d0a,2016-09-28,2015-08-03
-7d0i,2020-10-28,2020-09-10
-3d04,2008-12-09,2008-05-01
-8d0a,2023-02-01,2022-05-25
-5d0t,2016-03-23,2015-08-03
-6d0k,2018-07-04,2018-04-10
-1d01,2003-12-02,1999-09-07
-3d0h,2008-07-08,2008-05-01
-3d08,2009-01-20,2008-05-01
-5d0c,2016-01-13,2015-08-03
-6d0p,2018-04-25,2018-04-10
-3d05,2009-01-20,2008-05-01
-8d0r,2023-05-24,2022-05-26
-8d0s,2023-05-24,2022-05-26
-4d05,2014-11-12,2014-04-24
-1d0v,1999-12-29,1999-09-14
-1d0g,1999-10-22,1999-09-09
-7d00,2021-03-10,2020-09-09
-4d0m,2014-05-28,2014-04-29
-4d06,2015-04-08,2014-04-24
-5d0m,2015-12-09,2015-08-03
-7d0q,2021-07-07,2020-09-11
-3d0i,2008-07-08,2008-05-01
-1d0a,2000-03-08,1999-09-09
-5d0r,2016-03-16,2015-08-03
-4d0s,2015-05-20,2014-04-29
-2d06,2005-10-25,2005-07-25
-6d0n,2018-07-04,2018-04-10
-1d0h,2000-03-27,1999-09-10
-2d0s,2006-05-23,2005-08-08
-7d0r,2021-07-07,2020-09-11
-3d07,2009-01-20,2008-05-01
-7d0e,2021-03-31,2020-09-09
-3d0p,2008-10-07,2008-05-02
-8d0w,2023-05-24,2022-05-26
-2d04,2006-06-20,2005-07-25
-7d0t,2021-09-15,2020-09-11
-6d0y,2018-04-25,2018-04-11
-5d03,2016-08-10,2015-08-02
-6d0f,2019-04-17,2018-04-10
-6d0d,2019-05-01,2018-04-10
-5d00,2016-09-07,2015-08-01
-5d0z,2016-03-23,2015-08-03
-6d0z,2018-09-05,2018-04-11
-4d04,2014-12-10,2014-04-24
-4d02,2014-09-03,2014-04-23
-8d0y,2023-07-19,2022-05-26
-5d0u,2016-02-10,2015-08-03
-6d0j,2018-07-04,2018-04-10
-4d0l,2014-05-28,2014-04-29
-6d09,2018-10-31,2018-04-10
-6d0o,2018-08-15,2018-04-10
-2d01,2006-04-04,2005-07-21
-8d0p,2023-05-24,2022-05-26
-5d0w,2016-03-23,2015-08-03
-6d0m,2018-09-05,2018-04-10
-8d0x,2023-05-24,2022-05-26
-5d0f,2016-05-18,2015-08-03
-5d0n,2016-02-24,2015-08-03
-8d0u,2023-05-24,2022-05-26
-4d0w,2014-07-23,2014-04-30
-2d0h,2006-07-11,2005-08-02
-5d0k,2015-12-09,2015-08-03
-7d0c,2021-03-10,2020-09-09
-4d0e,2014-05-21,2014-04-25
-6d0e,2019-05-01,2018-04-10
-1d09,2000-01-28,1999-09-09
-8d0o,2023-05-24,2022-05-26
-3d0e,2008-10-21,2008-05-01
-1d0b,2000-01-07,1999-09-09
-2d0g,2006-07-11,2005-08-02
-2d00,2005-12-06,2005-07-21
-2d0t,2006-01-31,2005-08-08
-4d03,2014-12-10,2014-04-24
-1d0m,2000-03-06,1999-09-12
-5d01,2016-09-07,2015-08-02
-6d0g,2018-04-25,2018-04-10
-4d0f,2014-05-21,2014-04-25
-2d0k,2006-02-28,2005-08-04
-4d08,2014-08-06,2014-04-24
-2d0b,2006-07-18,2005-07-31
-8d0i,2022-09-21,2022-05-26
-2d0u,2006-01-31,2005-08-08
-3d0l,2008-10-07,2008-05-01
-6d0w,2019-04-17,2018-04-11
-4d0z,2014-05-28,2014-04-30
-8d0e,2022-09-21,2022-05-26
-8d0g,2022-09-21,2022-05-26
-12as,1998-12-30,1997-12-02
-6tpk,2020-08-05,2019-12-13
-8tpp,2024-05-08,2023-08-04
-6tpg,2020-01-01,2019-12-13
-3tpq,2011-10-12,2011-09-08
-3tpw,2011-10-05,2011-09-08
-8tp8,2023-11-29,2023-08-04
-5tp0,2017-05-17,2016-10-19
-7tpf,2022-02-09,2022-01-25
-6tp0,2020-10-14,2019-12-12
-7tpc,2022-02-09,2022-01-25
-8tpf,2024-01-24,2023-08-04
-5tpr,2017-02-22,2016-10-21
-3tp4,2011-10-05,2011-09-07
-6tpx,2020-01-15,2019-12-15
-6tp3,2020-01-01,2019-12-12
-7tpu,2023-02-15,2022-01-26
-3tp1,2011-09-21,2011-09-07
-7tp5,2023-01-04,2022-01-25
-7tp9,2022-02-09,2022-01-25
-8tpe,2024-01-24,2023-08-04
-4tpi,1985-11-08,1985-06-11
-6tp2,2020-10-14,2019-12-12
-1tpy,2004-10-19,2004-06-16
-2tps,1999-03-18,1999-03-09
-8tpc,2024-01-24,2023-08-04
-4tpw,2014-08-13,2014-06-09
-7tpd,2022-08-17,2022-01-25
-7tp6,2023-01-04,2022-01-25
-3tpp,2011-11-23,2011-09-08
-6tps,2020-03-18,2019-12-14
-4tpy,2014-10-22,2014-06-10
-5tpi,2016-11-02,2016-10-20
-6tpo,2020-11-18,2019-12-13
-2tpr,1993-10-31,1991-08-22
-3tpn,2011-10-12,2011-09-08
-3tp7,2011-09-21,2011-09-07
-4tpr,2015-07-29,2014-06-09
-7tpa,2022-02-09,2022-01-25
-6tp9,2020-04-22,2019-12-12
-3tpi,1983-01-18,1982-09-27
-8tpq,2024-05-08,2023-08-04
-4tpl,2014-10-15,2014-06-08
-5tps,2017-10-25,2016-10-21
-6tpj,2020-01-01,2019-12-13
-8tpo,2024-05-15,2023-08-04
-5tp9,2016-11-30,2016-10-20
-7tpz,2022-09-14,2022-01-26
-1tpz,2004-09-21,2004-06-16
-6tpa,2020-11-18,2019-12-12
-7tpv,2022-09-14,2022-01-26
-4tpt,2014-10-22,2014-06-09
-7tpw,2022-09-14,2022-01-26
-3tp0,2011-12-21,2011-09-07
-4tpg,2014-07-09,2014-06-07
-8tpb,2024-01-24,2023-08-04
-7tpt,2022-05-25,2022-01-26
-5tpa,2016-11-30,2016-10-20
-8tp2,2023-10-11,2023-08-04
-5tpc,2017-01-18,2016-10-20
-6tpd,2020-06-10,2019-12-13
-7tpe,2022-02-09,2022-01-25
-8tpy,2024-05-08,2023-08-06
-7tp0,2022-02-09,2022-01-24
-3tp6,2011-09-21,2011-09-07
-8tpa,2023-10-11,2023-08-04
-3tpv,2012-10-03,2011-09-08
-1tph,1994-04-30,1993-12-22
-8tps,2024-05-08,2023-08-04
-6tp4,2020-01-01,2019-12-12
-1tpu,1995-04-20,1994-11-07
-1tpp,1983-01-18,1982-09-27
-7tpi,2023-11-15,2022-01-25
-8tp5,2023-10-11,2023-08-04
-3tpt,2012-10-03,2011-09-08
-3tpu,2011-12-07,2011-09-08
-6tp6,2020-01-01,2019-12-12
-8tpr,2024-05-08,2023-08-04
-3tp5,2011-09-21,2011-09-07
-1tp5,2005-09-20,2004-06-15
-6tpl,2021-01-13,2019-12-13
-6tp1,2020-10-14,2019-12-12
-1tp7,2005-06-21,2004-06-15
-7tpn,2022-09-14,2022-01-25
-3tps,2011-10-12,2011-09-08
-6tpm,2020-11-25,2019-12-13
-5tpw,2016-12-14,2016-10-21
-3tpm,2011-10-12,2011-09-08
-4tpu,2015-05-13,2014-06-09
-3tpr,2011-11-23,2011-09-08
-5tp4,2017-04-05,2016-10-19
-2tpi,1982-03-04,1981-10-26
-4tpk,2014-10-22,2014-06-07
-8tpj,2024-04-17,2023-08-04
-5tpg,2017-01-25,2016-10-20
-8tpn,2024-05-08,2023-08-04
-5tpv,2017-02-01,2016-10-21
-3tp2,2012-03-14,2011-09-07
-8tp3,2023-10-11,2023-08-04
-6tpr,2020-05-13,2019-12-14
-7tpk,2023-02-08,2022-01-25
-1tpa,1983-01-18,1982-09-27
-4tpn,2014-09-10,2014-06-08
-8tpl,2024-06-05,2023-08-04
-8tpv,2024-05-08,2023-08-05
-8tpi,2024-01-24,2023-08-04
-5tpk,2017-10-25,2016-10-20
-7tpy,2022-09-14,2022-01-26
-5tpb,2017-01-18,2016-10-20
-5tpz,2016-12-14,2016-10-21
-6tpc,2021-01-13,2019-12-13
-8tpk,2023-11-29,2023-08-04
-6tpn,2020-01-01,2019-12-13
-1tpv,1995-04-20,1994-11-07
-6tpq,2020-09-30,2019-12-13
-3tp9,2011-09-21,2011-09-07
-3tpy,2011-10-12,2011-09-08
-6tpz,2020-01-15,2019-12-15
-3tp8,2011-09-21,2011-09-07
-1tp8,2004-08-03,2004-06-16
-4tpm,2014-12-17,2014-06-08
-4tpj,2014-07-09,2014-06-07
-7tp1,2022-02-09,2022-01-24
-6tp5,2020-12-23,2019-12-12
-1tpw,1995-04-20,1994-11-07
-7tpo,2022-09-14,2022-01-25
-7tps,2022-03-16,2022-01-26
-8tph,2024-01-24,2023-08-04
-7tp4,2022-02-23,2022-01-24
-7tpg,2022-04-06,2022-01-25
-2tpl,1997-04-01,1997-01-23
-5tpx,2017-01-04,2016-10-21
-7tpl,2022-02-09,2022-01-25
-6tpe,2020-06-10,2019-12-13
-4tpo,2014-09-10,2014-06-08
-6tpy,2020-01-15,2019-12-15
-4tph,2014-07-09,2014-06-07
-5tpp,2017-03-15,2016-10-20
-1tpb,1995-02-14,1994-02-03
-7tpx,2022-09-14,2022-01-26
-1tp3,2005-09-20,2004-06-15
-8tpd,2024-01-24,2023-08-04
-1tps,1995-01-26,1994-09-04
-8tp6,2023-10-11,2023-08-04
-8tpt,2024-05-08,2023-08-04
-1tpo,1983-01-18,1982-09-27
-7tp2,2022-02-09,2022-01-24
-6tp8,2020-05-20,2019-12-12
-7tp8,2022-02-09,2022-01-25
-7tph,2022-02-09,2022-01-25
-8tp1,2024-06-05,2023-08-04
-8tp9,2023-10-11,2023-08-04
-8tp7,2023-10-11,2023-08-04
-3tpx,2012-06-20,2011-09-08
-8tp4,2023-10-11,2023-08-04
-1tpc,1995-02-14,1994-02-03
-5tpq,2017-11-01,2016-10-20
-8tpg,2024-01-24,2023-08-04
-1tp2,2004-06-29,2004-06-15
-7tp7,2022-02-09,2022-01-25
-4tpp,2014-12-17,2014-06-09
-6tpf,2020-06-10,2019-12-13
-7tpm,2023-03-15,2022-01-25
-5tpu,2017-02-01,2016-10-21
-8v07,2024-03-13,2023-11-17
-4v0v,2015-03-25,2014-09-18
-4v05,2014-12-10,2014-09-10
-1v0f,2004-12-13,2004-03-28
-5v06,2017-05-24,2017-02-28
-5v01,2017-03-15,2017-02-28
-1v03,2004-05-20,2004-03-22
-2v0d,2007-06-26,2007-05-14
-4v00,2015-09-30,2014-09-10
-8v0i,2024-03-06,2023-11-17
-6v0a,2020-06-17,2019-11-18
-8v0k,2024-03-06,2023-11-17
-5v0d,2017-05-24,2017-02-28
-6v0u,2020-03-11,2019-11-19
-4v0j,2015-08-26,2014-09-17
-4v0r,2015-01-28,2014-09-18
-5v08,2017-05-24,2017-02-28
-2v0u,2007-12-11,2007-05-18
-2v0y,2008-06-10,2007-05-21
-1v00,2004-06-22,2004-03-21
-7v0b,2023-05-17,2022-05-10
-3v0b,2012-03-14,2011-12-07
-5v0v,2017-03-15,2017-02-28
-3v0l,2013-01-23,2011-12-08
-5v0s,2017-03-08,2017-02-28
-4v0o,2014-11-19,2014-09-17
-5v0i,2017-03-22,2017-02-28
-7v0h,2022-06-08,2022-05-10
-2v0h,2008-01-15,2007-05-14
-2v0a,2007-06-19,2007-05-11
-3v0s,2012-02-22,2011-12-08
-5v0w,2018-03-07,2017-02-28
-4v0h,2016-01-13,2014-09-16
-6v0t,2019-12-18,2019-11-19
-4v06,2014-10-15,2014-09-11
-6v09,2020-06-17,2019-11-18
-5v0q,2017-09-27,2017-02-28
-3v0t,2012-02-22,2011-12-08
-3v04,2012-05-09,2011-12-07
-2v06,2007-10-16,2007-05-08
-2v0j,2008-01-15,2007-05-14
-3v0x,2012-12-12,2011-12-09
-5v03,2018-03-07,2017-02-28
-6v02,2020-09-30,2019-11-18
-5v0c,2017-05-24,2017-02-28
-3v0h,2012-05-09,2011-12-08
-4v04,2014-12-10,2014-09-10
-6v0q,2020-03-11,2019-11-19
-6v04,2020-11-18,2019-11-18
-5v0x,2018-03-07,2017-02-28
-3v00,2012-04-18,2011-12-07
-1v0h,2004-06-23,2004-03-29
-7v0r,2023-05-10,2022-05-10
-7v0f,2022-12-07,2022-05-10
-7v0s,2022-07-20,2022-05-10
-6v0o,2020-08-26,2019-11-19
-4v03,2015-01-14,2014-09-10
-1v0o,2004-04-07,2004-03-31
-4v08,2015-07-15,2014-09-11
-4v01,2014-12-10,2014-09-10
-7v00,2022-07-06,2022-05-09
-1v0l,2004-08-16,2004-03-31
-1v0p,2004-05-06,2004-04-01
-5v02,2018-03-07,2017-02-28
-7v0e,2022-06-22,2022-05-10
-4v0s,2016-01-13,2014-09-18
-5v0b,2017-05-24,2017-02-28
-2v0s,2007-07-17,2007-05-17
-4v0q,2015-01-28,2014-09-18
-7v0c,2023-05-10,2022-05-10
-8v04,2024-01-31,2023-11-16
-2v0l,2008-01-15,2007-05-14
-5v05,2017-05-24,2017-02-28
-2v02,2007-08-14,2007-05-04
-6v0p,2020-11-25,2019-11-19
-4v0u,2015-03-25,2014-09-18
-4v0x,2015-03-25,2014-09-18
-2v08,2007-07-24,2007-05-10
-6v06,2020-06-17,2019-11-18
-3v0m,2013-01-23,2011-12-08
-1v0c,2008-09-02,2008-03-20
-8v05,2024-03-13,2023-11-17
-6v0y,2020-11-25,2019-11-19
-7v0i,2023-04-05,2022-05-10
-4v02,2015-01-14,2014-09-10
-2v0i,2008-01-15,2007-05-14
-8v08,2024-03-13,2023-11-17
-8v01,2024-03-06,2023-11-16
-1v0z,2006-01-25,2004-03-12
-2v01,2007-08-14,2007-05-04
-8v06,2024-03-13,2023-11-17
-1v07,2004-06-03,2004-03-24
-7v0j,2023-04-05,2022-05-10
-1v08,2004-05-20,2004-03-25
-4v0m,2014-11-19,2014-09-17
-1v0j,2005-01-26,2004-03-30
-3v0q,2013-01-23,2011-12-08
-2v0k,2008-01-15,2007-05-14
-7v0k,2022-07-20,2022-05-10
-5v0u,2017-03-08,2017-02-28
-5v0f,2018-03-21,2017-02-28
-2v07,2007-07-24,2007-05-09
-6v08,2020-06-17,2019-11-18
-8v0y,2024-03-06,2023-11-17
-5v0n,2017-05-03,2017-02-28
-7v07,2022-07-20,2022-05-10
-2v03,2007-10-09,2007-05-08
-4v0n,2014-11-19,2014-09-17
-1v0n,2004-08-16,2004-03-31
-4v0z,2015-09-30,2014-09-19
-5v0p,2017-03-22,2017-02-28
-6v0v,2020-01-29,2019-11-19
-1v0a,2005-01-12,2004-03-25
-4v0l,2014-11-19,2014-09-17
-6v0r,2020-04-01,2019-11-19
-1v0m,2004-08-16,2004-03-31
-4v0g,2016-01-13,2014-09-16
-2v0p,2007-07-17,2007-05-15
-5v09,2017-05-24,2017-02-28
-5v0z,2017-03-15,2017-02-28
-2v0c,2007-07-03,2007-05-14
-2v0n,2007-08-21,2007-05-15
-4v0i,2015-09-30,2014-09-16
-4v0k,2014-11-19,2014-09-17
-3v0c,2012-03-14,2011-12-07
-3v01,2012-05-09,2011-12-07
-5v0t,2017-04-05,2017-02-28
-7v0g,2022-12-07,2022-05-10
-6v0z,2020-11-25,2019-11-19
-5v0r,2017-03-29,2017-02-28
-3v0a,2012-03-14,2011-12-07
-7v08,2023-03-15,2022-05-10
-6v00,2019-12-04,2019-11-16
-2v0z,2007-07-03,2007-05-21
-1v0y,2004-06-03,2004-04-02
-2v09,2007-10-30,2007-05-10
-6v0x,2020-03-11,2019-11-19
-2v00,2007-12-04,2007-05-03
-7v09,2022-05-18,2022-05-10
-2v0m,2007-06-26,2007-05-15
-1v04,2004-04-23,2004-03-22
-4v07,2015-07-15,2014-09-11
-7v04,2022-12-21,2022-05-09
-5v0a,2017-05-24,2017-02-28
-3v0p,2013-01-23,2011-12-08
-4v0c,2014-11-05,2014-09-14
-2v0g,2007-07-03,2007-05-14
-5v07,2017-05-24,2017-02-28
-6v0s,2020-03-11,2019-11-19
-1v0k,2004-08-16,2004-03-31
-1v0d,2004-05-21,2004-03-26
-7v0z,2022-08-03,2022-05-11
-3v03,2012-01-04,2011-12-07
-3v0o,2013-01-23,2011-12-08
-5v0e,2017-05-24,2017-02-28
-4v0w,2015-03-25,2014-09-18
-7v0w,2023-05-17,2022-05-11
-3v0n,2013-01-23,2011-12-08
-6v01,2019-12-04,2019-11-18
-5v04,2017-05-24,2017-02-28
-2v0b,2008-06-03,2007-05-11
-2v0w,2007-12-11,2007-05-20
-7v01,2022-07-06,2022-05-09
-6v0n,2020-08-26,2019-11-19
-2oz6,2008-03-04,2007-02-24
-1ozh,2003-11-04,2003-04-09
-2oz4,2007-10-16,2007-02-23
-7ozx,2022-05-25,2021-06-29
-4ozn,2014-07-02,2014-02-17
-2oz5,2007-05-01,2007-02-23
-7ozf,2021-12-01,2021-06-28
-6ozq,2019-09-04,2019-05-15
-4ozi,2014-04-16,2014-02-16
-7oza,2022-06-29,2021-06-27
-2ozn,2008-05-06,2007-02-26
-7ozv,2021-08-18,2021-06-28
-1ozu,2003-05-27,2003-04-09
-4oz7,2015-05-20,2014-02-14
-7ozb,2021-12-01,2021-06-27
-2oze,2008-03-11,2007-02-26
-3ozc,2011-09-28,2010-09-24
-2ozq,2008-01-15,2007-02-27
-1ozm,2003-09-30,2003-04-09
-3ozu,2011-03-16,2010-09-27
-6ozo,2019-09-04,2019-05-15
-8ozw,2023-08-30,2023-05-09
-6oz6,2019-07-10,2019-05-15
-6ozb,2020-05-20,2019-05-15
-3ozj,2011-02-02,2010-09-25
-6oz7,2019-05-29,2019-05-15
-6ozy,2019-11-27,2019-05-16
-3oz2,2010-10-27,2010-09-24
-1oz1,2003-09-23,2003-04-07
-4ozt,2014-07-30,2014-02-19
-1ozn,2003-05-20,2003-04-09
-3ozw,2011-03-16,2010-09-27
-6ozw,2019-06-26,2019-05-16
-8oz0,2024-02-07,2023-05-06
-8ozv,2023-08-30,2023-05-09
-3ozl,2011-09-28,2010-09-25
-4ozg,2014-04-16,2014-02-16
-7oz9,2022-06-29,2021-06-27
-7ozc,2022-06-29,2021-06-27
-7ozu,2021-08-18,2021-06-28
-7oz6,2021-11-24,2021-06-25
-2ozb,2007-03-20,2007-02-26
-6ozf,2019-09-04,2019-05-15
-1ozs,2003-09-16,2003-04-09
-3ozo,2011-09-28,2010-09-27
-6ozm,2019-09-04,2019-05-15
-7ozn,2021-10-06,2021-06-28
-7oz5,2021-12-08,2021-06-25
-4oz6,2014-05-14,2014-02-14
-7ozr,2023-03-01,2021-06-28
-2oz7,2007-03-27,2007-02-25
-2ozs,2007-10-23,2007-02-27
-4oz9,2015-03-18,2014-02-14
-1ozr,2003-08-05,2003-04-09
-6ozk,2019-09-04,2019-05-15
-1ozg,2003-11-04,2003-04-09
-2oz3,2007-03-06,2007-02-23
-7oz7,2021-07-14,2021-06-26
-7oze,2022-06-29,2021-06-27
-8ozg,2023-08-16,2023-05-09
-2ozm,2007-10-23,2007-02-26
-4ozv,2015-03-04,2014-02-19
-8ozi,2023-08-16,2023-05-09
-3ozd,2011-09-28,2010-09-24
-1ozq,2003-09-30,2003-04-09
-4oz1,2014-05-14,2014-02-13
-4ozq,2014-07-09,2014-02-18
-7oz8,2022-06-29,2021-06-27
-3ozp,2011-08-17,2010-09-27
-3ozs,2011-03-16,2010-09-27
-1oz0,2003-09-30,2003-04-07
-3oz0,2011-01-19,2010-09-24
-1ozj,2004-03-23,2003-04-09
-3ozy,2011-09-28,2010-09-27
-1oz6,2003-12-30,2003-04-08
-3ozz,2011-09-14,2010-09-27
-4ozo,2014-03-05,2014-02-17
-7oz2,2021-12-08,2021-06-25
-7ozq,2021-10-27,2021-06-28
-7ozo,2021-10-06,2021-06-28
-2ozt,2007-03-13,2007-02-27
-6ozr,2019-09-04,2019-05-15
-1ozb,2003-10-14,2003-04-08
-6ozn,2019-09-04,2019-05-15
-1ozp,2003-09-09,2003-04-09
-6ozp,2019-09-04,2019-05-15
-7ozk,2022-07-27,2021-06-28
-2oz1,2008-01-08,2007-02-23
-4ozf,2014-04-16,2014-02-15
-6ozv,2019-05-29,2019-05-16
-7ozl,2022-07-27,2021-06-28
-7ozw,2021-12-08,2021-06-28
-6oz3,2020-08-19,2019-05-15
-3ozx,2011-02-02,2010-09-27
-2ozg,2007-03-13,2007-02-26
-7ozp,2021-10-06,2021-06-28
-6ozh,2019-09-04,2019-05-15
-3ozt,2011-03-16,2010-09-27
-3ozm,2011-09-28,2010-09-25
-3ozg,2011-09-28,2010-09-24
-2oz0,2007-09-11,2007-02-23
-7oz1,2021-09-22,2021-06-25
-6oza,2020-05-20,2019-05-15
-6oz2,2020-08-19,2019-05-15
-1ozl,2003-08-05,2003-04-09
-4oz3,2014-04-02,2014-02-13
-2oz9,2007-03-06,2007-02-25
-2oz2,2008-02-26,2007-02-23
-6oze,2019-09-04,2019-05-15
-7ozy,2021-12-01,2021-06-29
-3ozf,2011-09-28,2010-09-24
-1oze,2003-08-05,2003-04-08
-4oze,2014-08-13,2014-02-15
-7oz3,2021-08-11,2021-06-25
-8oza,2023-07-05,2023-05-08
-6ozg,2019-09-04,2019-05-15
-3ozk,2011-08-24,2010-09-25
-8ozf,2023-08-16,2023-05-09
-6ozc,2020-05-20,2019-05-15
-6oz1,2020-04-22,2019-05-15
-3ozb,2011-08-10,2010-09-24
-1ozv,2003-07-01,2003-04-09
-2ozo,2007-05-22,2007-02-26
-3ozi,2011-04-27,2010-09-25
-2ozl,2007-05-22,2007-02-26
-6oz9,2020-03-11,2019-05-15
-7ozd,2021-12-01,2021-06-27
-4oz5,2015-02-18,2014-02-13
-8oz5,2024-06-05,2023-05-08
-8oz8,2024-04-10,2023-05-08
-4ozl,2014-07-02,2014-02-17
-4oz2,2014-04-02,2014-02-13
-1ozw,2003-08-05,2003-04-09
-3ozv,2011-03-16,2010-09-27
-2ozu,2007-03-13,2007-02-27
-8oz2,2024-05-15,2023-05-08
-6ozs,2019-09-04,2019-05-15
-1ozf,2003-11-11,2003-04-09
-2ozr,2007-07-24,2007-02-27
-3oz1,2010-11-24,2010-09-24
-4ozj,2014-07-02,2014-02-17
-6ozi,2019-09-04,2019-05-15
-4ozh,2014-04-16,2014-02-16
-8oz9,2024-05-15,2023-05-08
-6oz4,2020-08-19,2019-05-15
-8oz1,2024-02-28,2023-05-06
-6oz5,2020-11-18,2019-05-15
-8oz7,2024-04-03,2023-05-08
-3ozr,2011-03-16,2010-09-27
-6ozl,2019-09-04,2019-05-15
-2ozy,2007-08-07,2007-02-28
-6eq1,2018-04-11,2017-10-12
-6eq6,2018-10-31,2017-10-12
-8eqi,2023-04-19,2022-10-07
-8eqe,2022-11-30,2022-10-07
-4eqp,2012-05-02,2012-04-19
-3eqq,2009-03-17,2008-10-01
-8eq9,2022-11-30,2022-10-07
-5eqg,2016-04-13,2015-11-12
-4eqw,2012-10-17,2012-04-19
-6eqo,2018-10-24,2017-10-13
-5eqh,2016-04-13,2015-11-12
-5eq1,2016-05-25,2015-11-12
-3eqr,2008-12-02,2008-10-01
-4eqm,2012-06-27,2012-04-19
-3eqh,2009-02-24,2008-09-30
-2eqf,2007-10-02,2007-03-30
-3eq6,2008-10-28,2008-09-30
-1eq4,2000-04-19,2000-04-03
-3eqi,2009-02-24,2008-09-30
-7eqz,2021-11-10,2021-05-05
-4eq5,2012-05-09,2012-04-18
-3eqb,2008-11-11,2008-09-30
-1eqg,2001-04-11,2000-04-04
-8eq0,2023-01-18,2022-10-07
-1eqd,2000-05-03,2000-04-03
-8eqf,2023-10-11,2022-10-07
-4eq9,2012-05-02,2012-04-18
-8eqa,2023-08-09,2022-10-07
-3eqy,2009-03-17,2008-10-01
-7eqk,2022-03-16,2021-05-03
-1equ,1999-12-02,1998-12-02
-3eqo,2009-02-03,2008-10-01
-8eq5,2023-04-26,2022-10-07
-4eqc,2013-08-28,2012-04-18
-4eqr,2012-10-17,2012-04-19
-6eq5,2018-10-31,2017-10-12
-8eqg,2023-07-05,2022-10-07
-6eqm,2018-09-19,2017-10-13
-8eq4,2023-02-01,2022-10-07
-6eq7,2018-10-31,2017-10-12
-5eqx,2016-06-15,2015-11-13
-4eqi,2012-05-23,2012-04-18
-5eq2,2016-01-27,2015-11-12
-4eqn,2012-05-02,2012-04-19
-7eqr,2022-08-10,2021-05-04
-3eq8,2009-08-25,2008-09-30
-1eq2,2000-11-08,2000-03-31
-2eq1,2007-10-02,2007-03-30
-7eq7,2022-05-11,2021-04-30
-2eqg,2007-10-02,2007-03-30
-1eqq,2003-09-23,2000-04-06
-4eqk,2013-03-06,2012-04-19
-6eqs,2017-11-01,2017-10-15
-2eq2,2007-10-02,2007-03-30
-3eq7,2009-08-25,2008-09-30
-5eqt,2016-11-23,2015-11-13
-3eqs,2009-03-17,2008-10-01
-5eqp,2016-01-06,2015-11-13
-6eq0,2018-04-11,2017-10-12
-2eq9,2008-04-01,2007-03-30
-2eq7,2008-04-01,2007-03-30
-3eq1,2009-03-03,2008-09-30
-6eqb,2018-10-10,2017-10-12
-6eq2,2018-10-31,2017-10-12
-1eqc,2000-10-03,2000-04-03
-5eqr,2016-11-23,2015-11-13
-6eqq,2017-12-13,2017-10-15
-4eqx,2012-10-17,2012-04-19
-2eq6,2008-04-01,2007-03-30
-2eq8,2008-04-01,2007-03-30
-3eqt,2009-03-10,2008-10-01
-3eqe,2008-10-14,2008-09-30
-6eqz,2017-11-01,2017-10-16
-1eq5,2000-04-19,2000-04-03
-5eqc,2016-02-24,2015-11-12
-1eqa,1999-07-22,1999-01-05
-4eqj,2012-06-06,2012-04-19
-1eqj,2001-04-05,2000-04-05
-5eqb,2016-01-13,2015-11-12
-6eqv,2018-02-28,2017-10-16
-8eql,2023-07-05,2022-10-07
-4eqs,2012-10-17,2012-04-19
-5equ,2016-05-11,2015-11-13
-3eq9,2009-08-25,2008-09-30
-3eqg,2009-02-24,2008-09-30
-1eqm,2001-04-05,2000-04-05
-1eqz,2000-04-17,2000-04-06
-5eq6,2016-04-27,2015-11-12
-6eqw,2018-02-28,2017-10-16
-7eqw,2022-05-04,2021-05-04
-5eqn,2016-05-18,2015-11-13
-5eqm,2016-10-19,2015-11-13
-1eqw,2000-09-08,2000-04-06
-4equ,2012-11-07,2012-04-19
-8eqx,2023-02-22,2022-10-10
-8eqm,2022-12-28,2022-10-08
-6eq3,2018-10-31,2017-10-12
-4eq0,2012-06-06,2012-04-17
-3eql,2008-10-28,2008-09-30
-1eqr,2000-06-29,2000-04-06
-3eqm,2008-12-23,2008-10-01
-3eqa,2009-10-13,2008-09-30
-6eq4,2018-10-31,2017-10-12
-1eqh,2001-04-11,2000-04-04
-8eqk,2023-07-05,2022-10-07
-5eqy,2016-01-06,2015-11-13
-1eqy,2000-05-03,2000-04-06
-4eqo,2012-05-02,2012-04-19
-7eqd,2021-08-18,2021-05-01
-6eqp,2017-12-13,2017-10-14
-5eq8,2016-03-30,2015-11-12
-2eqe,2007-10-02,2007-03-30
-6eqx,2018-02-28,2017-10-16
-4eqb,2012-05-02,2012-04-18
-3eq0,2009-08-18,2008-09-30
-5eqi,2016-04-13,2015-11-12
-7eqx,2021-11-10,2021-05-05
-7equ,2021-05-19,2021-05-04
-4eql,2012-06-20,2012-04-19
-3eqc,2009-02-24,2008-09-30
-1eqe,2000-04-19,2000-04-04
-6eqa,2018-10-10,2017-10-12
-5eqv,2015-11-25,2015-11-13
-6eql,2017-12-20,2017-10-13
-7eqv,2022-05-18,2021-05-04
-9eq4,2024-04-03,2024-03-20
-5eqs,2016-11-23,2015-11-13
-4eqf,2012-05-30,2012-04-18
-5eqf,2016-11-23,2015-11-12
-4eqh,2012-05-02,2012-04-18
-2eq4,2007-10-02,2007-03-30
-8eqd,2022-11-30,2022-10-07
-9eq3,2024-04-10,2024-03-20
-6equ,2017-12-13,2017-10-15
-2eq3,2007-10-02,2007-03-30
-9eqh,2024-05-15,2024-03-21
-3eqf,2009-02-24,2008-09-30
-7eqm,2022-08-10,2021-05-04
-2eqd,2007-09-18,2007-03-30
-5eqq,2016-01-13,2015-11-13
-8eq7,2023-02-22,2022-10-07
-4eqe,2012-05-02,2012-04-18
-5eq4,2016-01-27,2015-11-12
-4eqg,2012-05-02,2012-04-18
-5eqd,2016-11-23,2015-11-12
-8eqz,2023-03-15,2022-10-11
-2eq0,2007-10-02,2007-03-30
-5eqe,2016-01-06,2015-11-12
-3eqn,2009-02-03,2008-10-01
-5eq3,2016-01-27,2015-11-12
-3eqp,2008-12-02,2008-10-01
-6eq8,2018-04-18,2017-10-12
-7eqt,2022-05-04,2021-05-04
-8eqo,2023-02-15,2022-10-08
-7eq2,2022-11-02,2021-04-28
-2eqw,2007-10-02,2007-03-30
-4eq4,2012-06-20,2012-04-18
-1eqb,2000-04-19,2000-04-03
-7eqf,2022-04-27,2021-05-01
-3eqd,2009-02-24,2008-09-30
-2eqa,2008-01-15,2007-03-30
-6eqe,2018-04-25,2017-10-12
-7eqh,2022-05-11,2021-05-02
-6eq9,2018-08-08,2017-10-12
-5eq9,2016-03-30,2015-11-12
-8ikj,2024-02-14,2023-02-28
-2ikc,2006-10-17,2006-10-02
-5ikk,2016-04-20,2016-03-03
-3ik7,2010-06-23,2009-08-05
-6ik9,2019-01-30,2018-10-15
-5ikw,2016-06-29,2016-03-04
-1iky,2001-06-06,2001-05-07
-3ikv,2010-06-09,2009-08-06
-6ikt,2019-10-23,2018-10-16
-4iks,2013-12-11,2012-12-28
-1ike,2001-10-03,2001-05-03
-6ika,2019-01-30,2018-10-15
-8ikw,2024-02-07,2023-03-01
-3ikd,2009-09-22,2009-08-05
-3ik2,2009-08-18,2009-08-05
-5ikj,2016-04-20,2016-03-03
-3ikr,2009-11-17,2009-08-06
-5ikd,2016-07-13,2016-03-03
-1ikv,2001-06-06,2001-05-07
-1ikt,2001-11-14,2001-05-07
-3ik1,2010-08-11,2009-08-05
-3ik6,2009-09-15,2009-08-05
-4ikz,2013-07-10,2012-12-28
-4ik6,2013-01-30,2012-12-25
-4ik9,2014-01-29,2012-12-25
-6ik5,2018-11-28,2018-10-15
-3ike,2009-08-18,2009-08-05
-2ikf,2007-02-20,2006-10-02
-4ik3,2014-01-29,2012-12-25
-5iku,2017-03-15,2016-03-03
-5iko,2016-07-20,2016-03-03
-6ikg,2018-11-14,2018-10-16
-5ikp,2016-07-20,2016-03-03
-3ik4,2009-08-18,2009-08-05
-2iku,2006-12-05,2006-10-02
-8ikg,2024-06-05,2023-02-28
-5ikg,2016-07-13,2016-03-03
-4ika,2013-09-04,2012-12-25
-2iko,2006-11-14,2006-10-02
-1ikg,2002-09-11,2001-05-03
-2ik9,2007-02-13,2006-10-02
-2ik6,2007-02-13,2006-10-02
-3ikc,2009-10-06,2009-08-05
-3ika,2010-01-12,2009-08-05
-8ik7,2024-03-06,2023-02-28
-4ik1,2014-02-05,2012-12-25
-5ik0,2016-10-05,2016-03-03
-1ik3,2001-11-14,2001-05-01
-1ikf,1995-03-31,1993-12-09
-1ikx,2001-06-06,2001-05-07
-5ikf,2016-04-20,2016-03-03
-4ikd,2013-04-24,2012-12-26
-4ikj,2013-01-30,2012-12-26
-5iks,2016-09-21,2016-03-03
-8iks,2024-03-06,2023-03-01
-5iki,2016-05-25,2016-03-03
-4ikf,2013-04-03,2012-12-26
-3ikn,2009-11-17,2009-08-06
-4ike,2014-07-02,2012-12-26
-2ik0,2007-02-13,2006-10-02
-4iku,2013-12-11,2012-12-28
-3ikh,2009-08-18,2009-08-05
-8ik3,2023-05-17,2023-02-28
-6iky,2019-10-23,2018-10-16
-5ik5,2016-08-10,2016-03-03
-5ikm,2016-03-16,2016-03-03
-5ikq,2016-05-25,2016-03-03
-2ikj,2007-05-01,2006-10-02
-5ikb,2016-08-24,2016-03-03
-2ik2,2007-02-13,2006-10-02
-5ik8,2016-08-10,2016-03-03
-2ik1,2007-02-13,2006-10-02
-4ik4,2014-02-05,2012-12-25
-4ikl,2013-01-30,2012-12-26
-4ikr,2013-12-11,2012-12-28
-4ikm,2013-05-08,2012-12-26
-3ik3,2009-11-03,2009-08-05
-4ik2,2013-12-25,2012-12-25
-8ikb,2024-03-06,2023-02-28
-2ik8,2006-11-21,2006-10-02
-2ik7,2007-02-13,2006-10-02
-4ikb,2013-04-24,2012-12-26
-8ikh,2024-06-05,2023-02-28
-5ika,2016-10-05,2016-03-03
-4iki,2013-01-30,2012-12-26
-5ikv,2016-05-25,2016-03-03
-4ikt,2013-12-11,2012-12-28
-5ik9,2016-10-05,2016-03-03
-3ikt,2010-06-09,2009-08-06
-4ikn,2013-02-20,2012-12-26
-5iky,2016-06-01,2016-03-04
-2ikg,2007-05-01,2006-10-02
-4ikp,2013-02-13,2012-12-27
-2ikh,2007-05-01,2006-10-02
-1ikj,2001-10-03,2001-05-03
-5ikr,2016-05-25,2016-03-03
-5ikh,2016-10-05,2016-03-03
-8ikp,2024-03-06,2023-02-28
-3ikw,2009-09-29,2009-08-06
-1ikw,2001-06-06,2001-05-07
-5ikz,2016-06-01,2016-03-04
-6ik7,2018-11-28,2018-10-15
-3ikp,2009-11-17,2009-08-06
-1iki,2002-09-11,2001-05-03
-4ik8,2014-02-05,2012-12-25
-6ik6,2018-11-28,2018-10-15
-5ik6,2016-10-05,2016-03-03
-6ik4,2019-10-16,2018-10-14
-5ikt,2016-05-25,2016-03-03
-3ik0,2010-08-11,2009-08-05
-5ik4,2016-08-10,2016-03-03
-1ikq,2001-12-12,2001-05-04
-6ikz,2019-10-16,2018-10-16
-1ika,1994-07-31,1993-06-15
-1ik4,2001-09-26,2001-05-02
-3ik9,2010-06-23,2009-08-05
-1iko,2002-05-03,2001-05-03
-5ik2,2016-09-21,2016-03-03
-4ik5,2014-01-29,2012-12-25
-8ikx,2024-02-07,2023-03-01
-2iki,2007-05-01,2006-10-02
-1ikp,2001-12-12,2001-05-04
-5ik1,2016-05-04,2016-03-03
-8ikz,2024-03-06,2023-03-01
-4ikh,2013-01-16,2012-12-26
-6ik8,2018-11-28,2018-10-15
-4ikk,2013-01-30,2012-12-26
-3ikf,2009-08-18,2009-08-05
-2ik4,2007-02-13,2006-10-02
-8ik2,2023-11-01,2023-02-28
-5ik7,2016-08-10,2016-03-03
-3ikq,2009-11-17,2009-08-06
-3ikg,2009-09-22,2009-08-05
-4ik7,2013-01-30,2012-12-25
-3ant,2011-01-19,2010-09-08
-5ani,2016-04-13,2015-09-07
-7any,2022-02-02,2020-10-13
-6an9,2019-01-16,2017-08-12
-1anj,1996-01-29,1995-09-06
-5ank,2016-04-13,2015-09-07
-7an1,2021-10-27,2020-10-10
-6ann,2017-11-15,2017-08-14
-2anv,2006-02-07,2005-08-11
-8any,2023-08-16,2022-08-06
-4anj,2012-10-17,2012-03-19
-5anh,2016-08-24,2015-09-07
-2ano,2006-07-25,2005-08-11
-2an9,2005-08-30,2005-08-11
-3ank,2010-10-06,2010-09-02
-8ans,2022-08-31,2022-08-05
-1anx,1994-12-20,1993-10-26
-5anw,2016-03-02,2015-09-08
-6anx,2017-11-22,2017-08-14
-7ans,2020-12-02,2020-10-12
-5an1,2016-10-12,2015-09-02
-3any,2011-08-03,2010-09-16
-1an1,1998-07-01,1997-06-26
-3an1,2010-12-01,2010-08-27
-2an6,2006-05-30,2005-08-11
-6an8,2018-08-15,2017-08-12
-7an9,2022-04-20,2020-10-11
-2anz,2006-04-11,2005-08-11
-6an0,2017-08-23,2017-08-11
-5anz,2016-07-20,2015-09-09
-9ant,1998-10-14,1998-07-02
-5ang,2016-04-13,2015-09-07
-2anp,2005-10-04,2005-08-11
-8anr,2023-05-31,2022-08-05
-6any,2018-03-28,2017-08-14
-1an9,1997-11-12,1997-06-28
-2ans,1999-07-22,1999-01-19
-2an3,2006-03-14,2005-08-11
-1ani,1996-01-29,1995-09-06
-8anc,2023-08-16,2022-08-05
-1an0,1999-01-13,1997-06-26
-2an0,2006-08-29,2005-08-10
-6anf,2018-02-21,2017-08-13
-7anq,2021-10-20,2020-10-12
-3ang,2011-03-09,2010-09-01
-1ank,1994-05-31,1994-02-28
-7an8,2022-04-20,2020-10-11
-4an0,2012-05-16,2012-03-14
-5an7,2016-08-17,2015-09-04
-3anl,2011-02-23,2010-09-03
-5an6,2015-12-23,2015-09-04
-1anw,1994-12-20,1993-10-26
-8anp,2023-04-12,2022-08-05
-5and,2016-04-13,2015-09-07
-2anb,2005-08-30,2005-08-11
-7ana,2021-11-10,2020-10-11
-4an1,2012-05-16,2012-03-14
-7an4,2020-10-21,2020-10-10
-6ane,2018-04-18,2017-08-12
-4an4,2012-09-05,2012-03-15
-7anj,2020-10-21,2020-10-11
-8an9,2023-05-31,2022-08-04
-7an7,2022-04-20,2020-10-11
-4anq,2013-03-27,2012-03-21
-4ang,2013-02-27,2012-03-16
-5ane,2016-04-13,2015-09-07
-8an2,2023-08-16,2022-08-04
-1ann,1996-01-29,1995-09-21
-4anv,2012-05-09,2012-03-22
-5anv,2016-03-02,2015-09-08
-2anj,2005-08-30,2005-08-11
-3ann,2011-02-23,2010-09-03
-6ana,2018-01-31,2017-08-12
-7anv,2020-12-30,2020-10-12
-4anw,2012-05-09,2012-03-22
-1anc,1997-04-01,1994-12-21
-6anj,2017-09-20,2017-08-13
-1and,1997-04-01,1994-12-21
-1anv,1997-02-12,1996-03-14
-1an5,1998-07-01,1997-06-26
-6an6,2018-08-15,2017-08-12
-4anb,2012-12-19,2012-03-16
-5anl,2016-04-13,2015-09-07
-3anx,2011-04-13,2010-09-14
-6anv,2017-10-25,2017-08-14
-8anh,2023-08-02,2022-08-05
-3anq,2010-11-10,2010-09-06
-8an3,2023-08-16,2022-08-04
-5anm,2015-09-30,2015-09-07
-4an9,2012-12-19,2012-03-16
-8an8,2022-08-31,2022-08-04
-6anl,2018-01-17,2017-08-14
-5ans,2016-03-02,2015-09-08
-4an7,2012-11-07,2012-03-15
-2an4,2006-03-14,2005-08-11
-7ant,2021-04-07,2020-10-12
-6an1,2018-02-14,2017-08-11
-8ana,2023-03-08,2022-08-05
-5anq,2016-03-23,2015-09-07
-7anc,2020-10-21,2020-10-11
-2ant,1997-06-16,1997-01-28
-5ant,2016-03-02,2015-09-08
-6ank,2017-09-20,2017-08-13
-7anu,2021-11-03,2020-10-12
-5anu,2016-03-02,2015-09-08
-2anm,2006-06-13,2005-08-11
-4an2,2012-12-19,2012-03-14
-7an5,2022-04-20,2020-10-11
-2anq,2006-07-25,2005-08-11
-5ann,2016-02-10,2015-09-07
-3anr,2010-11-10,2010-09-06
-2anu,2005-10-18,2005-08-11
-4ano,2012-12-05,2012-03-21
-7anb,2021-10-27,2020-10-11
-2anh,1996-01-29,1995-09-06
-1anf,1997-12-24,1997-06-25
-4anx,2012-05-09,2012-03-22
-4anp,2012-04-11,2012-03-21
-2an2,2006-08-29,2005-08-11
-3anm,2011-02-23,2010-09-03
-7anw,2020-11-11,2020-10-13
-3anu,2011-06-15,2010-09-09
-3an3,2011-07-27,2010-08-30
-4ans,2013-03-27,2012-03-22
-6ans,2017-08-30,2017-08-14
-8anv,2023-10-25,2022-08-05
-5anj,2016-04-13,2015-09-07
-8anf,2023-09-20,2022-08-05
-3ans,2011-01-19,2010-09-08
-8anu,2023-10-25,2022-08-05
-6an2,2018-08-15,2017-08-11
-6ang,2019-01-16,2017-08-13
-2ani,2006-07-25,2005-08-11
-4an3,2012-12-19,2012-03-15
-3anp,2011-03-09,2010-09-06
-8anl,2023-08-02,2022-08-05
-3an4,2011-07-27,2010-08-30
-8an6,2023-04-12,2022-08-04
-2anx,2006-02-07,2005-08-11
-6an3,2018-07-18,2017-08-11
-4anm,2012-05-23,2012-03-20
-7ane,2021-06-23,2020-10-11
-8anb,2023-08-16,2022-08-05
-1anb,1997-04-01,1994-12-21
-4anu,2012-05-09,2012-03-22
-8ano,2023-05-31,2022-08-05
-2anl,2006-04-04,2005-08-11
-8ani,2023-08-02,2022-08-05
-6anq,2018-08-15,2017-08-14
-6anh,2019-01-16,2017-08-13
-4anr,2012-04-04,2012-03-22
-7an6,2022-04-20,2020-10-11
-3anv,2011-06-15,2010-09-09
-2an5,2006-03-14,2005-08-11
-2ank,2006-11-14,2005-08-11
-6an4,2018-08-15,2017-08-12
-7n8l,2022-02-02,2021-06-15
-5n8x,2017-05-10,2017-02-24
-5n8t,2017-10-04,2017-02-24
-7n83,2021-09-08,2021-06-12
-3n8s,2010-11-24,2010-05-28
-6n8z,2019-01-02,2018-11-30
-7n8k,2021-10-13,2021-06-15
-1n8w,2002-12-18,2002-11-21
-1n8i,2002-12-18,2002-11-20
-4n8p,2013-10-30,2013-10-17
-5n8j,2017-10-25,2017-02-23
-3n8u,2010-07-28,2010-05-28
-6n85,2019-07-10,2018-11-28
-3n87,2011-05-11,2010-05-27
-3n8x,2010-07-28,2010-05-28
-3n8d,2010-10-13,2010-05-28
-5n8b,2017-10-04,2017-02-23
-4n8e,2014-02-12,2013-10-17
-4n8d,2014-02-12,2013-10-17
-4n8i,2014-04-09,2013-10-17
-3n8m,2010-12-15,2010-05-28
-2n8r,2016-02-24,2015-10-24
-7n8h,2021-07-14,2021-06-14
-5n8g,2017-07-26,2017-02-23
-6n83,2019-11-06,2018-11-28
-5n8h,2017-07-26,2017-02-23
-3n85,2010-07-28,2010-05-27
-7n8r,2022-02-16,2021-06-15
-4n87,2014-02-19,2013-10-17
-1n8k,2003-02-04,2002-11-21
-2n8l,2017-01-25,2015-10-21
-3n8y,2010-07-28,2010-05-28
-5n82,2017-12-13,2017-02-22
-5n8e,2017-10-11,2017-02-23
-6n8t,2019-01-02,2018-11-30
-4n8v,2014-02-05,2013-10-18
-4n8o,2014-05-28,2013-10-17
-4n8r,2014-05-14,2013-10-17
-6n87,2019-01-30,2018-11-28
-3n8i,2011-12-07,2010-05-28
-3n81,2011-04-13,2010-05-27
-4n83,2014-01-08,2013-10-16
-5n87,2017-05-31,2017-02-23
-4n86,2014-02-19,2013-10-17
-4n8f,2014-03-12,2013-10-17
-7n8c,2021-06-23,2021-06-14
-5n8i,2017-07-26,2017-02-23
-3n8h,2010-06-16,2010-05-28
-1n8v,2003-04-01,2002-11-21
-7n8q,2022-04-06,2021-06-15
-1n84,2003-03-18,2002-11-19
-6n84,2019-07-10,2018-11-28
-4n8g,2013-10-30,2013-10-17
-4n8n,2014-05-28,2013-10-17
-5n8f,2017-07-26,2017-02-23
-3n8r,2011-12-14,2010-05-28
-4n8y,2013-11-20,2013-10-18
-2n8m,2017-01-25,2015-10-21
-6n8b,2020-07-15,2018-11-29
-5n80,2018-03-14,2017-02-21
-7n88,2021-12-01,2021-06-14
-6n80,2019-06-26,2018-11-28
-7n8w,2022-07-06,2021-06-15
-7n8e,2022-02-02,2021-06-14
-7n8m,2022-02-02,2021-06-15
-4n85,2014-02-19,2013-10-17
-3n8z,2010-07-28,2010-05-28
-3n8f,2010-07-14,2010-05-28
-7n86,2021-09-01,2021-06-13
-1n8z,2003-02-18,2002-11-21
-5n8z,2018-03-14,2017-02-24
-1n8n,2004-02-03,2002-11-21
-7n8i,2021-07-14,2021-06-14
-4n8z,2013-10-30,2013-10-18
-6n8x,2019-07-03,2018-11-30
-4n80,2014-04-23,2013-10-16
-3n8v,2010-07-28,2010-05-28
-4n8t,2014-10-08,2013-10-18
-2n8y,2016-06-29,2015-10-28
-6n8e,2019-07-24,2018-11-29
-5n8a,2017-06-07,2017-02-23
-1n8p,2002-12-04,2002-11-21
-5n8w,2017-10-04,2017-02-24
-5n83,2018-03-14,2017-02-22
-4n8m,2014-03-12,2013-10-17
-6n8v,2019-01-02,2018-11-30
-7n8b,2022-05-11,2021-06-14
-3n8g,2011-06-08,2010-05-28
-1n8y,2003-02-18,2002-11-21
-4n8q,2014-04-23,2013-10-17
-3n86,2011-05-11,2010-05-27
-1n83,2002-12-11,2002-11-19
-5n84,2017-05-31,2017-02-22
-5n8v,2017-03-15,2017-02-24
-1n8u,2003-04-01,2002-11-21
-4n8w,2014-11-26,2013-10-18
-3n8n,2011-05-11,2010-05-28
-6n8j,2019-03-13,2018-11-29
-3n8b,2010-10-06,2010-05-28
-1n82,2003-11-25,2002-11-19
-7n81,2021-06-30,2021-06-11
-4n8j,2014-04-09,2013-10-17
-5n89,2017-10-04,2017-02-23
-3n8k,2010-07-21,2010-05-28
-3n8w,2010-07-28,2010-05-28
-3n82,2011-04-13,2010-05-27
-4n8u,2014-10-29,2013-10-18
-4n8s,2013-11-06,2013-10-18
-5n81,2017-12-13,2017-02-22
-5n8p,2017-04-12,2017-02-24
-4n82,2014-01-08,2013-10-16
-1n8r,2003-07-22,2002-11-21
-3n8l,2011-12-14,2010-05-28
-2n8a,2015-12-02,2015-10-08
-7n8f,2022-06-15,2021-06-14
-3n84,2011-01-12,2010-05-27
-1n8f,2003-04-22,2002-11-20
-1n86,2003-01-07,2002-11-19
-6n8k,2019-03-13,2018-11-29
-3n83,2011-04-13,2010-05-27
-5n8c,2017-03-29,2017-02-23
-5n8r,2018-03-14,2017-02-24
-3n80,2011-04-13,2010-05-27
-1n8q,2003-06-03,2002-11-21
-7n8o,2021-12-29,2021-06-15
-4n8c,2014-10-22,2013-10-17
-7n8d,2023-01-25,2021-06-14
-7n8t,2022-06-22,2021-06-15
-4n88,2014-04-23,2013-10-17
-6n8y,2019-07-03,2018-11-30
-6n82,2019-11-06,2018-11-28
-6n8g,2018-12-12,2018-11-29
-5n8u,2018-03-14,2017-02-24
-13pk,1997-12-24,1996-11-23
-6a3h,1999-07-24,1998-07-22
-7a3l,2021-06-30,2020-08-18
-7a3i,2021-06-30,2020-08-18
-1a3i,1998-05-06,1998-01-22
-2a3z,2005-11-01,2005-06-27
-1a34,1998-04-29,1998-01-28
-6a3j,2018-09-26,2018-06-15
-7a3w,2021-08-25,2020-08-18
-1a3j,1998-05-06,1998-01-22
-5a3k,2015-08-19,2015-06-01
-7a3n,2021-12-08,2020-08-18
-7a3r,2021-12-08,2020-08-18
-1a3g,1998-05-27,1998-01-21
-4a32,2011-12-21,2011-09-29
-1a3v,1998-04-29,1998-01-24
-4a35,2011-10-12,2011-09-30
-7a36,2021-08-25,2020-08-18
-5a3r,2016-04-13,2015-06-02
-2a3x,2005-07-26,2005-06-27
-3a3u,2009-07-14,2009-06-20
-8a3w,2023-12-20,2022-06-09
-1a39,1999-03-02,1998-01-28
-2a3w,2005-07-26,2005-06-27
-7a3j,2021-06-30,2020-08-18
-4a3q,2011-12-28,2011-10-04
-3a3e,2009-12-22,2009-06-12
-6a30,2019-01-30,2018-06-14
-6a37,2019-03-27,2018-06-15
-8a3g,2022-10-05,2022-06-08
-8a37,2023-07-05,2022-06-07
-6a3a,2019-06-19,2018-06-15
-3a37,2010-01-12,2009-06-10
-1a3x,1998-05-27,1998-01-26
-7a3z,2021-02-03,2020-08-19
-3a35,2009-11-10,2009-06-09
-1a3d,1998-04-29,1998-01-20
-7a3t,2021-12-08,2020-08-18
-5a30,2015-09-09,2015-05-26
-5a3a,2015-07-29,2015-05-28
-4a3j,2011-12-07,2011-09-30
-4a3l,2011-12-07,2011-09-30
-6a3x,2019-06-19,2018-06-18
-5a3b,2015-07-29,2015-05-28
-3a3h,1999-03-16,1998-02-01
-2a3c,2005-09-27,2005-06-24
-6a3e,2019-06-19,2018-06-15
-3a3z,2010-02-02,2009-06-25
-2a3g,2005-10-25,2005-06-24
-2a3y,2005-07-26,2005-06-27
-5a39,2015-06-24,2015-05-28
-4a3f,2011-12-07,2011-09-30
-4a31,2011-12-21,2011-09-29
-6a3b,2019-06-19,2018-06-15
-4a36,2011-10-19,2011-09-30
-3a3f,2009-12-22,2009-06-12
-6a3d,2019-06-19,2018-06-15
-2a39,1999-02-16,1998-01-30
-2a3f,2006-06-06,2005-06-24
-1a3w,1998-05-27,1998-01-26
-6a3k,2019-06-12,2018-06-15
-2a3b,2005-09-27,2005-06-24
-4a3m,2011-12-07,2011-09-30
-3a3k,2010-03-16,2009-06-14
-5a3n,2015-07-08,2015-06-02
-2a3u,2005-08-02,2005-06-27
-7a3p,2021-12-08,2020-08-18
-8a38,2023-09-20,2022-06-07
-8a3t,2022-08-31,2022-06-09
-8a3u,2023-12-20,2022-06-09
-1a37,1999-03-02,1998-01-28
-5a3h,1999-07-24,1998-07-23
-8a33,2023-07-05,2022-06-07
-3a3o,2009-08-18,2009-06-15
-4a30,2011-12-21,2011-09-29
-2a3p,2006-04-18,2005-06-25
-2a31,2006-07-04,2005-06-23
-4a3u,2012-10-17,2011-10-04
-7a3q,2021-12-08,2020-08-18
-1a3t,1998-04-29,1998-01-24
-4a3e,2011-12-07,2011-09-30
-5a3o,2015-07-22,2015-06-02
-4a3z,2012-04-04,2011-10-06
-2a3e,2005-09-27,2005-06-24
-5a3l,2016-06-29,2015-06-02
-3a3y,2009-09-08,2009-06-23
-8a3f,2023-07-05,2022-06-08
-2a3m,2006-04-25,2005-06-25
-2a3i,2005-07-19,2005-06-24
-4a3k,2011-12-07,2011-09-30
-6a36,2019-06-19,2018-06-15
-4a38,2012-05-09,2011-09-30
-1a3z,1998-07-29,1998-01-27
-3a3i,2009-12-22,2009-06-12
-2a3a,2005-09-27,2005-06-24
-7a3g,2021-06-30,2020-08-18
-2a30,2006-01-17,2005-06-23
-6a3v,2018-10-10,2018-06-17
-3a3c,2009-08-04,2009-06-11
-4a3x,2012-02-22,2011-10-05
-7a33,2021-08-25,2020-08-18
-8a3x,2023-03-08,2022-06-09
-8a3n,2022-10-19,2022-06-08
-8a3l,2023-05-10,2022-06-08
-1a30,1998-04-29,1998-01-27
-5a3y,2015-11-11,2015-06-04
-3a3q,2009-11-03,2009-06-16
-7a3x,2021-06-16,2020-08-18
-1a3o,1998-04-29,1998-01-22
-5a3s,2016-04-13,2015-06-03
-3a31,2009-10-27,2009-06-07
-5a3x,2016-06-29,2015-06-03
-7a3k,2021-07-07,2020-08-18
-7a3v,2021-06-16,2020-08-18
-8a31,2022-11-30,2022-06-06
-6a3l,2019-06-12,2018-06-15
-3a34,2010-06-16,2009-06-09
-5a3q,2016-04-13,2015-06-02
-2a38,2006-06-24,2005-06-24
-5a3u,2015-06-17,2015-06-03
-2a3h,1999-03-16,1998-01-22
-5a3t,2015-06-17,2015-06-02
-4a39,2012-05-09,2011-09-30
-8a3d,2023-03-08,2022-06-08
-2a3l,2005-07-19,2005-06-25
-8a3h,2000-01-21,1999-01-20
-4a3i,2012-02-08,2011-09-30
-6a3z,2019-06-19,2018-06-18
-5a31,2015-11-18,2015-05-26
-4a33,2011-12-21,2011-09-29
-8a3a,2023-09-20,2022-06-07
-4a3h,1999-07-23,1998-07-22
-5a3c,2015-07-29,2015-05-28
-2a32,2006-07-04,2005-06-23
-1a3u,1998-04-29,1998-01-24
-7a3s,2021-12-08,2020-08-18
-8a32,2022-11-30,2022-06-06
-5a3m,2016-06-29,2015-06-02
-2a33,2005-07-19,2005-06-23
-5a3p,2015-06-10,2015-06-02
-8a34,2023-09-27,2022-06-07
-6a39,2019-06-19,2018-06-15
-1a3e,1998-06-03,1998-01-21
-5a3w,2015-06-17,2015-06-03
-1a3k,1998-07-15,1998-01-22
-6a3i,2018-09-26,2018-06-15
-4a3b,2011-12-07,2011-09-30
-6a3t,2019-06-19,2018-06-16
-4a3g,2012-02-08,2011-09-30
-8a30,2023-04-05,2022-06-06
-1a3l,1999-02-16,1998-01-22
-1a3c,1998-08-05,1998-01-20
-6a38,2019-06-19,2018-06-15
-4a3r,2012-08-15,2011-10-04
-3a3v,2009-11-03,2009-06-22
-8a35,2023-02-01,2022-06-07
-4a3c,2011-11-16,2011-09-30
-8a36,2023-07-05,2022-06-07
-1a3b,1998-06-03,1998-01-20
-2a3r,2005-08-30,2005-06-26
-3a3w,2010-01-12,2009-06-23
-1a38,1999-03-02,1998-01-28
-6a3n,2019-04-10,2018-06-15
-7a3o,2021-12-08,2020-08-18
-3a36,2010-01-12,2009-06-10
-3a3b,2009-11-10,2009-06-11
-6a3g,2018-09-26,2018-06-15
-6a3w,2018-10-10,2018-06-17
-1a3n,1998-04-29,1998-01-22
-4a34,2011-10-12,2011-09-29
-4a3d,2011-12-07,2011-09-30
-3a3n,2009-08-18,2009-06-15
-5a3i,2015-07-22,2015-06-01
-3a3p,2009-08-18,2009-06-15
-4a3n,2011-12-28,2011-10-01
-8a3q,2022-11-02,2022-06-08
-5a3d,2015-07-01,2015-05-28
-3a32,2009-10-27,2009-06-07
-5a3j,2016-09-28,2015-06-01
-2a3t,2005-08-02,2005-06-27
-6a31,2018-06-27,2018-06-14
-8a3v,2023-02-15,2022-06-09
-3a3g,2009-11-10,2009-06-12
-6a3c,2019-06-19,2018-06-15
-4a37,2012-05-09,2011-09-30
-4a3w,2012-08-08,2011-10-05
-3a3x,2010-01-12,2009-06-23
-3nis,2010-09-15,2010-06-16
-6nid,2020-01-01,2018-12-27
-5ni5,2018-08-22,2017-03-23
-1nin,1996-10-14,1996-03-13
-7nir,2021-12-01,2021-02-13
-7ni9,2021-10-20,2021-02-11
-5nim,2017-11-15,2017-03-24
-1nib,1995-12-07,1995-07-03
-6nij,2019-07-31,2018-12-29
-1ni1,2004-04-06,2002-12-20
-7niq,2021-11-17,2021-02-13
-3nii,2010-09-15,2010-06-16
-4ni3,2013-12-25,2013-11-05
-4ni1,2014-09-17,2013-11-05
-3niw,2010-06-30,2010-06-16
-4niv,2014-02-19,2013-11-08
-3nip,2011-06-01,2010-06-16
-7nix,2021-06-16,2021-02-14
-3ni5,2011-06-22,2010-06-15
-3nif,2010-12-22,2010-06-15
-4nil,2014-05-14,2013-11-06
-5ni4,2017-08-23,2017-03-23
-3nio,2011-06-01,2010-06-16
-4nio,2013-12-04,2013-11-06
-1nia,1995-12-07,1995-07-03
-6nih,2019-04-17,2018-12-27
-6ni3,2019-11-20,2018-12-26
-4ni8,2014-11-26,2013-11-05
-3niu,2010-07-14,2010-06-16
-5ni1,2017-04-12,2017-03-22
-7nim,2021-08-18,2021-02-12
-3ni2,2010-09-08,2010-06-14
-1niv,1996-10-14,1996-03-15
-6nig,2019-04-17,2018-12-27
-5nia,2017-08-23,2017-03-23
-3nig,2010-12-22,2010-06-15
-4nig,2014-04-16,2013-11-06
-4nij,2014-09-17,2013-11-06
-3niz,2010-07-28,2010-06-16
-7niv,2021-08-25,2021-02-14
-7ni6,2021-09-01,2021-02-11
-6nib,2019-03-20,2018-12-27
-3nia,2011-03-02,2010-06-15
-7ni1,2022-02-23,2021-02-11
-7nit,2021-12-22,2021-02-14
-3nin,2010-09-15,2010-06-16
-4nic,2014-07-16,2013-11-06
-4nih,2014-04-16,2013-11-06
-7nio,2021-03-17,2021-02-12
-1niq,2003-12-25,2002-12-25
-7nif,2021-06-16,2021-02-12
-5ni2,2017-08-23,2017-03-23
-6nie,2019-10-02,2018-12-27
-1ni4,2003-06-17,2002-12-20
-4nid,2014-04-16,2013-11-06
-1niw,2003-02-18,2002-12-26
-7ni5,2021-09-01,2021-02-11
-7ni3,2022-02-23,2021-02-11
-7nin,2021-08-18,2021-02-12
-1nis,1993-10-31,1993-01-17
-4nir,2014-05-14,2013-11-06
-4nin,2013-12-04,2013-11-06
-5nih,2017-07-26,2017-03-24
-7ni0,2021-12-01,2021-02-11
-7ni8,2021-10-20,2021-02-11
-5nit,2017-11-15,2017-03-27
-7ni7,2021-10-20,2021-02-11
-3nim,2010-09-15,2010-06-16
-7nic,2021-11-17,2021-02-11
-5nid,2017-08-23,2017-03-23
-7nii,2021-08-25,2021-02-12
-7nid,2021-10-20,2021-02-11
-3nie,2010-08-11,2010-06-15
-7niw,2021-08-25,2021-02-14
-7nih,2021-08-25,2021-02-12
-4nix,2014-02-19,2013-11-08
-7niu,2021-08-25,2021-02-14
-7ni4,2021-09-01,2021-02-11
-3nij,2010-09-15,2010-06-16
-4nii,2014-04-16,2013-11-06
-7niz,2021-12-01,2021-02-14
-1nie,1995-12-07,1995-07-03
-4ni5,2013-11-13,2013-11-05
-1nic,1995-12-07,1995-07-03
-6nic,2019-03-20,2018-12-27
-1nik,2003-04-29,2002-12-24
-3ni3,2010-09-15,2010-06-15
-1ni6,2003-04-01,2002-12-21
-5nii,2017-12-06,2017-03-24
-7nil,2021-12-01,2021-02-12
-3niq,2011-06-01,2010-06-16
-6nin,2019-06-19,2018-12-31
-5nib,2018-08-22,2017-03-23
-4niy,2014-02-19,2013-11-08
-3nil,2010-09-15,2010-06-16
-7nig,2021-06-16,2021-02-12
-3nik,2010-09-15,2010-06-16
-7nia,2021-10-20,2021-02-11
-5niz,2017-11-15,2017-03-27
-4nif,2014-11-12,2013-11-06
-5nio,2017-11-15,2017-03-24
-1niu,2003-09-16,2002-12-26
-5niy,2018-10-10,2017-03-27
-5niw,2017-11-15,2017-03-27
-1nio,2003-08-05,2002-12-24
-7nik,2021-12-01,2021-02-12
-7niy,2021-07-21,2021-02-14
-5nin,2017-12-06,2017-03-24
-4ni0,2014-08-20,2013-11-05
-3nid,2010-12-22,2010-06-15
-4nia,2014-09-10,2013-11-05
-5nie,2017-08-23,2017-03-23
-1nid,1995-12-07,1995-07-03
-3nit,2010-09-15,2010-06-16
-5ni0,2017-04-26,2017-03-22
-7nis,2021-12-01,2021-02-13
-4niw,2014-02-19,2013-11-08
-1nih,1992-10-15,1990-03-14
-5nif,2017-08-02,2017-03-23
-3nix,2010-06-30,2010-06-16
-4nie,2013-12-11,2013-11-06
-5ni6,2017-08-23,2017-03-23
-5ni7,2018-08-22,2017-03-23
-6nix,2020-01-22,2019-01-01
-6nil,2019-12-11,2018-12-29
-1nir,1997-12-03,1997-06-17
-1nip,1993-10-31,1992-09-29
-1nif,1995-12-07,1995-07-03
-5niu,2017-12-06,2017-03-27
-5ni8,2018-08-22,2017-03-23
-3nih,2010-09-15,2010-06-16
-4nip,2013-12-04,2013-11-06
-5ni3,2018-09-12,2017-03-23
-1zsr,2006-04-25,2005-05-24
-3zsc,2012-07-11,2011-06-24
-3zsx,2012-07-11,2011-07-01
-6zs2,2020-10-07,2020-07-15
-3zs9,2011-09-07,2011-06-24
-2zs7,2009-07-21,2008-09-03
-5zso,2019-05-01,2018-04-29
-7zs7,2023-05-17,2022-05-06
-3zs6,2012-07-04,2011-06-23
-7zsj,2022-11-09,2022-05-06
-7zse,2022-08-03,2022-05-06
-4zsd,2015-08-12,2015-05-13
-7zsm,2023-05-17,2022-05-07
-3zs1,2011-08-31,2011-06-21
-1zsn,2006-05-30,2005-05-24
-1zs0,2006-05-02,2005-05-23
-5zsb,2019-01-30,2018-04-28
-4zsc,2015-08-12,2015-05-13
-2zsj,2008-10-21,2008-09-11
-3zsr,2012-07-11,2011-06-30
-7zsq,2023-05-17,2022-05-08
-4zso,2016-05-18,2015-05-13
-6zs1,2021-04-07,2020-07-15
-6zsm,2021-10-27,2020-07-16
-4zsm,2015-06-10,2015-05-13
-3zso,2012-07-11,2011-06-30
-6zsn,2021-10-27,2020-07-16
-7zsi,2022-11-09,2022-05-06
-6zsx,2021-07-28,2020-07-16
-1zs2,2006-05-02,2005-05-23
-3zs5,2012-07-04,2011-06-23
-4zst,2015-09-02,2015-05-13
-6zst,2021-05-19,2020-07-16
-7zs2,2023-05-17,2022-05-05
-6zsa,2020-10-21,2020-07-15
-2zsb,2009-07-21,2008-09-04
-1zs7,2005-07-05,2005-05-23
-2zsv,2008-11-04,2008-09-18
-5zsn,2019-01-30,2018-04-28
-5zs3,2019-01-30,2018-04-27
-1zsc,1996-07-11,1996-01-09
-2zs0,2008-10-21,2008-09-02
-7zsr,2023-05-17,2022-05-08
-1zs8,2005-07-26,2005-07-22
-4zs0,2016-07-20,2015-05-12
-2zsy,2009-02-24,2008-09-18
-4zsq,2015-06-10,2015-05-13
-4zse,2016-06-15,2015-05-13
-5zs6,2019-01-30,2018-04-28
-6zs5,2020-09-02,2020-07-15
-4zs9,2016-06-29,2015-05-13
-4zsy,2015-07-08,2015-05-14
-3zsv,2012-07-11,2011-07-01
-2zsr,2009-02-24,2008-09-17
-6zsv,2022-07-20,2020-07-16
-2zsh,2008-11-25,2008-09-10
-7zss,2023-03-01,2022-05-08
-5zsc,2019-01-30,2018-04-28
-2zsc,2009-02-17,2008-09-05
-7zsf,2022-11-09,2022-05-06
-2zs9,2009-07-21,2008-09-04
-2zsf,2009-07-21,2008-09-05
-2zsn,2009-02-24,2008-09-17
-4zsh,2016-03-30,2015-05-13
-1zs9,2005-06-21,2005-05-23
-1zs5,2006-05-23,2005-05-23
-4zsk,2016-06-08,2015-05-13
-2zsg,2008-10-14,2008-09-10
-2zsi,2008-11-25,2008-09-10
-1zs6,2005-06-07,2005-05-23
-6zs7,2021-07-28,2020-07-15
-3zst,2011-09-14,2011-06-30
-1zsj,2006-05-23,2005-05-24
-7zst,2022-08-24,2022-05-08
-5zss,2019-05-01,2018-04-29
-2zsm,2008-10-21,2008-09-17
-7zso,2023-05-17,2022-05-07
-6zsg,2020-10-14,2020-07-15
-4zsg,2016-05-04,2015-05-13
-5zsi,2019-01-30,2018-04-28
-2zsz,2009-02-24,2008-09-18
-4zs2,2015-11-04,2015-05-13
-5zsh,2019-01-30,2018-04-28
-7zs0,2023-05-17,2022-05-05
-2zs8,2009-07-21,2008-09-03
-3zs8,2011-09-07,2011-06-24
-2zsl,2008-10-21,2008-09-17
-2zsa,2009-07-21,2008-09-04
-4zsi,2016-06-08,2015-05-13
-1zsk,2006-05-23,2005-05-24
-3zsj,2011-12-14,2011-06-28
-5zsj,2019-01-30,2018-04-28
-2zsx,2009-02-24,2008-09-18
-2zsu,2008-10-21,2008-09-17
-5zsd,2019-01-30,2018-04-28
-3zsn,2012-05-09,2011-06-29
-3zs7,2012-06-20,2011-06-23
-3zsi,2012-06-13,2011-06-28
-4zsn,2016-09-07,2015-05-13
-3zse,2012-02-08,2011-06-27
-3zsq,2012-07-11,2011-06-30
-6zsp,2021-03-03,2020-07-16
-1zsq,2006-01-31,2005-05-25
-3zsw,2012-07-11,2011-07-01
-5zsz,2019-05-22,2018-04-30
-6zsj,2020-09-02,2020-07-15
-4zsw,2015-07-08,2015-05-14
-4zs4,2015-09-02,2015-05-13
-6zs9,2020-10-14,2020-07-15
-4zsu,2015-09-02,2015-05-14
-2zsp,2009-02-24,2008-09-17
-7zsx,2023-05-17,2022-05-09
-6zsi,2020-09-02,2020-07-15
-7zsb,2022-11-16,2022-05-06
-1zsw,2005-06-07,2005-05-25
-4zsf,2015-10-07,2015-05-13
-4zsl,2016-05-04,2015-05-13
-5zsm,2019-01-30,2018-04-28
-7zsa,2022-11-16,2022-05-06
-7zsl,2023-05-17,2022-05-07
-6zsd,2020-09-16,2020-07-15
-2zst,2009-02-24,2008-09-17
-7zsd,2023-03-01,2022-05-06
-3zs4,2012-07-11,2011-06-22
-6zsb,2020-09-16,2020-07-15
-7zsn,2023-05-17,2022-05-07
-2zs1,2008-10-21,2008-09-02
-6zsk,2021-07-28,2020-07-15
-7zs4,2023-05-17,2022-05-06
-7zs1,2023-05-17,2022-05-05
-1zsb,1996-07-11,1996-01-09
-1zsf,2006-04-25,2005-05-24
-6zsq,2020-09-30,2020-07-16
-6zsl,2020-07-29,2020-07-15
-3zsg,2012-06-13,2011-06-28
-6zsc,2020-09-16,2020-07-15
-2zse,2009-07-21,2008-09-05
-5zsk,2019-05-01,2018-04-28
-6zsr,2020-09-30,2020-07-16
-4zsa,2015-06-17,2015-05-13
-4zs3,2015-11-04,2015-05-13
-7zsg,2022-11-09,2022-05-06
-5zsf,2019-01-30,2018-04-28
-4zs6,2015-09-02,2015-05-13
-2zso,2009-02-24,2008-09-17
-7zs9,2022-11-16,2022-05-06
-5zs8,2019-05-22,2018-04-28
-4zsj,2016-05-04,2015-05-13
-7zsw,2023-05-17,2022-05-09
-1zsz,2005-08-23,2005-05-25
-5zsg,2019-01-30,2018-04-28
-7zsp,2023-05-17,2022-05-08
-3zsz,2012-07-11,2011-07-01
-2zsd,2009-07-21,2008-09-05
-3zs2,2011-08-31,2011-06-21
-1zsp,2006-05-02,2005-05-24
-7zsh,2022-11-09,2022-05-06
-6zs8,2020-12-23,2020-07-15
-4zsr,2015-06-10,2015-05-13
-1zsl,2006-05-09,2005-05-24
-7zsv,2023-05-17,2022-05-09
-5zsl,2019-01-30,2018-04-28
-7zsu,2023-04-05,2022-05-09
-7zs8,2023-04-12,2022-05-06
-3zsh,2012-06-13,2011-06-28
-2zsq,2009-02-24,2008-09-17
-3zsy,2012-07-11,2011-07-01
-2zsw,2008-11-04,2008-09-18
-2zss,2009-02-24,2008-09-17
-6zsw,2021-07-28,2020-07-16
-5zsx,2019-06-12,2018-04-30
-4zsp,2015-06-10,2015-05-13
-1zsh,2006-01-31,2005-05-24
-7zs6,2022-07-13,2022-05-06
-1zsx,2005-06-07,2005-05-25
-6zse,2020-09-16,2020-07-15
-5zse,2019-01-30,2018-04-28
-6zs3,2020-10-07,2020-07-15
-5zsa,2019-01-30,2018-04-28
-3zs0,2011-08-31,2011-06-21
-6zs4,2020-10-07,2020-07-15
-3ie7,2009-08-04,2009-07-22
-4iee,2013-05-01,2012-12-13
-2ieh,2007-01-23,2006-09-19
-2ie0,2007-07-24,2006-09-15
-3ie2,2009-08-04,2009-07-22
-8ieg,2023-09-06,2023-02-15
-3ie0,2009-08-04,2009-07-22
-3ieo,2010-01-26,2009-07-23
-4ief,2013-04-10,2012-12-13
-5ieg,2016-07-27,2016-02-25
-3iel,2010-07-28,2009-07-23
-4iei,2013-05-01,2012-12-13
-4iep,2013-06-26,2012-12-13
-6ie0,2019-09-18,2018-09-12
-8iem,2023-12-20,2023-02-15
-8iej,2023-09-06,2023-02-15
-1iem,2001-08-15,2001-04-10
-3iem,2010-07-28,2009-07-23
-3ie9,2009-10-06,2009-07-22
-4iex,2013-06-26,2012-12-13
-6ieq,2019-05-22,2018-09-16
-4ie4,2013-04-03,2012-12-13
-6ieh,2019-04-03,2018-09-14
-4ieg,2013-07-24,2012-12-13
-2ieg,2006-12-26,2006-09-19
-1iee,2001-08-08,2001-04-09
-1ier,1997-01-11,1996-05-28
-6ieg,2019-04-03,2018-09-14
-6iey,2019-02-06,2018-09-18
-4ie5,2013-04-03,2012-12-13
-2ier,2007-01-09,2006-09-19
-2iew,2006-10-24,2006-09-19
-6ie2,2019-09-18,2018-09-13
-1ie7,2001-04-25,2001-04-09
-2ieo,2006-10-03,2006-09-19
-5ieo,2017-03-01,2016-02-25
-4ie0,2013-04-03,2012-12-13
-4ie9,2013-05-01,2012-12-13
-2iez,2007-05-01,2006-09-19
-5iey,2016-04-27,2016-02-25
-3ied,2009-08-25,2009-07-22
-4ien,2013-01-16,2012-12-13
-4ie2,2013-03-20,2012-12-13
-5ie3,2016-12-07,2016-02-24
-4ies,2013-06-26,2012-12-13
-6ies,2019-09-18,2018-09-17
-8iex,2024-02-21,2023-02-16
-3iev,2009-08-25,2009-07-23
-5ied,2016-07-27,2016-02-25
-3ie3,2009-10-27,2009-07-22
-5iea,2016-06-15,2016-02-25
-5iex,2016-04-27,2016-02-25
-2ie3,2006-11-07,2006-09-17
-5ier,2017-03-01,2016-02-25
-3iei,2010-08-11,2009-07-22
-3ie1,2009-08-04,2009-07-22
-2ie4,2006-11-07,2006-09-17
-5iev,2016-04-27,2016-02-25
-6iej,2019-05-22,2018-09-14
-2iej,2007-01-23,2006-09-19
-5ie4,2017-01-04,2016-02-25
-3iea,2009-10-06,2009-07-22
-1ie9,2001-05-16,2001-04-09
-2iea,2006-10-03,2006-09-18
-4iel,2012-12-26,2012-12-13
-1iel,2001-08-15,2001-04-10
-8ie8,2023-05-24,2023-02-15
-3iew,2009-08-18,2009-07-23
-5ief,2016-07-27,2016-02-25
-1ie8,2001-05-16,2001-04-09
-6iet,2019-09-18,2018-09-17
-3ieq,2009-08-04,2009-07-23
-1iew,2001-11-14,2001-04-11
-4iet,2013-06-26,2012-12-13
-3ie4,2009-08-18,2009-07-22
-4iec,2013-12-18,2012-12-13
-2iec,2006-10-03,2006-09-18
-5ie6,2017-01-04,2016-02-25
-1ie3,2001-09-19,2001-04-05
-2ieb,2007-07-24,2006-09-18
-4iev,2013-06-26,2012-12-13
-4ie7,2013-04-03,2012-12-13
-4ier,2013-06-26,2012-12-13
-8ie7,2023-05-24,2023-02-15
-1ieb,1997-06-05,1996-04-05
-5ieq,2017-02-22,2016-02-25
-5iez,2017-01-18,2016-02-25
-3ies,2010-02-16,2009-07-23
-4iez,2013-06-26,2012-12-13
-3iex,2010-03-16,2009-07-23
-4iey,2013-06-26,2012-12-13
-6ien,2019-02-20,2018-09-14
-8ieo,2023-12-20,2023-02-15
-4ie3,2013-03-20,2012-12-13
-4ie6,2013-04-03,2012-12-13
-1ieq,2001-11-14,2001-04-11
-8ie5,2023-05-24,2023-02-15
-1iea,1997-06-05,1996-04-05
-5ie9,2016-03-30,2016-02-25
-4iem,2013-01-23,2012-12-13
-4ied,2014-01-22,2012-12-13
-5ie1,2016-03-30,2016-02-24
-1ies,1997-01-11,1996-05-28
-3iej,2009-10-06,2009-07-22
-8iey,2024-03-20,2023-02-16
-6ie6,2019-01-16,2018-09-13
-8iek,2023-12-27,2023-02-15
-4ie1,2013-03-20,2012-12-13
-2ie6,2007-02-06,2006-09-18
-1ie4,2002-04-10,2001-04-06
-2iei,2006-12-26,2006-09-19
-8ie6,2023-05-24,2023-02-15
-5iee,2016-07-27,2016-02-25
-1iej,2001-06-20,2001-04-10
-6ied,2018-11-21,2018-09-13
-2ieq,2007-01-09,2006-09-19
-5ie5,2017-01-04,2016-02-25
-4iew,2013-06-26,2012-12-13
-4iej,2013-01-02,2012-12-13
-4ieu,2013-06-26,2012-12-13
-6ie7,2019-01-16,2018-09-13
-8ies,2023-12-20,2023-02-15
-5ies,2016-04-06,2016-02-25
-6ie4,2019-01-16,2018-09-13
-5iep,2017-03-01,2016-02-25
-6ieu,2019-09-18,2018-09-17
-3ieh,2009-08-04,2009-07-22
-6ie9,2019-02-13,2018-09-13
-2ie7,2007-02-06,2006-09-18
-4iea,2013-09-25,2012-12-13
-1iev,2001-11-14,2001-04-11
-4ieb,2013-12-25,2012-12-13
-5ie2,2016-12-07,2016-02-24
-1iei,2002-04-10,2001-04-09
-5ien,2017-03-01,2016-02-25
-4ieh,2013-07-10,2012-12-13
-3iet,2010-06-23,2009-07-23
-2iey,2007-05-01,2006-09-19
-2ien,2006-10-03,2006-09-19
-5iel,2017-03-08,2016-02-25
-4ieq,2013-06-26,2012-12-13
-3ieu,2009-08-25,2009-07-23
-5ie7,2017-01-04,2016-02-25
-8iew,2024-02-28,2023-02-16
-1iex,2001-11-14,2001-04-11
-8ien,2023-12-20,2023-02-15
-1iep,2001-04-18,2001-04-10
-6ie3,2019-09-18,2018-09-13
-3iek,2010-07-28,2009-07-22
-1ie0,2001-10-03,2001-04-05
-4ieo,2013-06-26,2012-12-13
-6ie8,2019-02-13,2018-09-13
-6iez,2019-02-27,2018-09-18
-5stb,2022-11-02,2022-08-26
-8stu,2023-11-29,2023-05-11
-5sts,2022-11-02,2022-08-26
-1sts,1996-03-08,1995-09-12
-6stx,2019-11-13,2019-09-12
-8st1,2024-02-07,2023-05-09
-6stg,2020-04-22,2019-09-10
-5stu,2022-11-02,2022-08-26
-5sta,2022-11-02,2022-08-26
-8sty,2023-08-30,2023-05-11
-8st3,2024-02-07,2023-05-09
-1stg,1995-01-26,1994-10-27
-8stp,2023-11-29,2023-05-11
-1st2,1991-07-15,1990-03-21
-6sti,2019-11-20,2019-09-10
-1st4,2004-04-13,2004-03-24
-5stx,2022-11-02,2022-08-26
-4std,1999-12-29,1999-02-10
-3st1,2011-11-02,2011-07-08
-2std,1999-02-16,1997-12-21
-1st8,2005-03-01,2004-03-25
-7stc,2022-11-16,2021-11-12
-7ste,2022-04-06,2021-11-12
-8stq,2023-11-29,2023-05-11
-5st3,2022-11-02,2022-08-26
-7stt,2022-01-26,2021-11-15
-8sth,2023-07-26,2023-05-10
-5st4,2022-11-02,2022-08-26
-6stn,2021-07-14,2019-09-11
-5stl,2022-11-02,2022-08-26
-7stb,2022-03-23,2021-11-12
-7stv,2022-01-26,2021-11-15
-7sto,2022-07-13,2021-11-14
-5stz,2022-11-02,2022-08-26
-8str,2023-11-29,2023-05-11
-6stt,2021-03-31,2019-09-11
-7stq,2022-06-01,2021-11-15
-5stt,2022-11-02,2022-08-26
-8st0,2024-02-07,2023-05-09
-5st6,2022-11-02,2022-08-26
-8ste,2023-05-17,2023-05-10
-5st1,2022-11-02,2022-08-26
-8sts,2023-11-29,2023-05-11
-1stc,1998-02-25,1997-10-10
-6stf,2020-04-22,2019-09-10
-1sta,1994-06-22,1994-01-17
-8stw,2023-11-22,2023-05-11
-3st5,2011-08-17,2011-07-08
-1ste,1996-12-23,1995-08-21
-7stu,2022-01-26,2021-11-15
-7st9,2022-03-23,2021-11-12
-1str,1996-03-08,1995-09-12
-8st6,2024-05-15,2023-05-09
-8st5,2024-05-15,2023-05-09
-3stp,2011-08-17,2011-07-11
-3std,1999-10-16,1998-10-16
-1st0,2004-04-13,2004-03-24
-3stw,2012-05-02,2011-07-11
-8sti,2023-07-26,2023-05-10
-3stf,2011-11-23,2011-07-09
-5st8,2022-11-02,2022-08-26
-3stl,2012-04-18,2011-07-11
-3st6,2012-05-30,2011-07-08
-5sth,2022-11-02,2022-08-26
-5stg,2022-11-02,2022-08-26
-3st9,2011-09-07,2011-07-09
-5st9,2022-11-02,2022-08-26
-3stv,2012-05-02,2011-07-11
-6stp,2021-07-14,2019-09-11
-6sto,2021-07-14,2019-09-11
-7stm,2022-07-13,2021-11-14
-5st5,2022-11-02,2022-08-26
-7std,1999-12-29,1999-02-11
-6stq,2021-07-14,2019-09-11
-6str,2021-07-14,2019-09-11
-1std,1995-08-19,1994-08-19
-6sty,2020-04-29,2019-09-12
-6st5,2022-08-10,2019-09-10
-7stz,2022-01-26,2021-11-15
-3str,2011-07-27,2011-07-11
-3st7,2012-02-15,2011-07-09
-5stj,2022-11-02,2022-08-26
-7st7,2022-02-23,2021-11-12
-8stn,2023-08-23,2023-05-10
-6st7,2020-09-30,2019-09-10
-3stc,2011-11-23,2011-07-09
-5std,1999-12-29,1999-02-10
-6std,1999-12-29,1999-02-11
-8stb,2024-05-22,2023-05-09
-2sta,2000-01-19,1998-12-10
-1sth,1995-02-27,1994-10-27
-2stb,2000-01-19,1998-12-11
-5sti,2022-11-02,2022-08-26
-5sto,2022-11-02,2022-08-26
-1sty,1993-04-15,1993-02-18
-7stx,2021-12-22,2021-11-15
-8std,2023-12-27,2023-05-10
-5st0,2022-11-02,2022-08-26
-8stv,2023-11-29,2023-05-11
-5stf,2022-11-02,2022-08-26
-7stn,2022-07-13,2021-11-14
-3st8,2012-08-08,2011-07-09
-3ste,2011-11-23,2011-07-09
-1stb,1994-07-31,1994-01-17
-1stp,1992-10-15,1992-03-12
-6st0,2019-12-18,2019-09-09
-5st7,2022-11-02,2022-08-26
-5sty,2022-11-02,2022-08-26
-6stz,2020-02-19,2019-09-12
-5st2,2022-11-02,2022-08-26
-2st1,1991-07-15,1990-05-11
-5stm,2022-11-02,2022-08-26
-5stp,2022-11-02,2022-08-26
-5stq,2022-11-02,2022-08-26
-5stn,2022-11-02,2022-08-26
-1stx,2004-04-06,2004-03-25
-5str,2022-11-02,2022-08-26
-5stk,2022-11-02,2022-08-26
-8st4,2024-02-07,2023-05-09
-8st2,2024-02-07,2023-05-09
-3stz,2012-04-18,2011-07-11
-6st3,2019-12-04,2019-09-10
-5stv,2022-11-02,2022-08-26
-8stt,2023-11-29,2023-05-11
-8stz,2023-08-30,2023-05-11
-7stw,2021-12-01,2021-11-15
-1sto,1994-05-31,1993-12-20
-1st3,1994-01-31,1991-11-22
-6stu,2020-09-16,2019-09-11
-1stq,2004-07-13,2004-03-25
-5stc,2022-11-02,2022-08-26
-5stw,2022-11-02,2022-08-26
-7st4,2022-11-16,2021-11-11
-8stg,2023-06-07,2023-05-10
-3stx,2012-05-02,2011-07-11
-3stu,2012-05-02,2011-07-11
-8stm,2023-08-23,2023-05-10
-3s6a,2012-01-25,2011-05-25
-6s60,2020-07-22,2019-07-02
-1s6v,2004-04-27,2004-01-27
-1s6b,2004-02-10,2004-01-23
-7s67,2021-09-22,2021-09-13
-6s6j,2020-07-22,2019-07-03
-3s6x,2011-11-23,2011-05-26
-6s6c,2020-07-22,2019-07-02
-3s6d,2011-06-22,2011-05-25
-7s6k,2022-05-11,2021-09-14
-3s6f,2011-07-06,2011-05-25
-7s66,2021-09-22,2021-09-13
-1s6j,2004-12-21,2004-01-23
-7s68,2022-06-29,2021-09-13
-6s6k,2020-12-09,2019-07-03
-3s66,2011-08-03,2011-05-25
-6s6z,2020-03-18,2019-07-04
-6s66,2020-07-22,2019-07-02
-1s6u,2004-04-06,2004-01-27
-3s6u,2012-04-11,2011-05-26
-7s60,2021-12-01,2021-09-12
-7s6t,2021-12-29,2021-09-14
-7s6m,2022-06-29,2021-09-14
-7s6h,2022-06-29,2021-09-14
-7s6r,2021-12-29,2021-09-14
-6s6v,2019-09-04,2019-07-03
-6s65,2020-07-15,2019-07-02
-7s61,2021-12-01,2021-09-12
-6s6x,2019-09-11,2019-07-03
-6s6s,2019-09-11,2019-07-03
-6s63,2020-07-22,2019-07-02
-1s61,2004-06-29,2004-01-22
-6s6b,2020-07-08,2019-07-02
-7s6u,2022-11-09,2021-09-15
-1s6p,2004-05-11,2004-01-26
-7s6v,2022-11-09,2021-09-15
-1s63,2004-07-27,2004-01-22
-7s6i,2022-05-11,2021-09-14
-1s6i,2004-06-15,2004-01-23
-3s65,2011-08-03,2011-05-25
-6s64,2020-07-22,2019-07-02
-1s66,2004-06-22,2004-01-22
-3s6v,2012-04-11,2011-05-26
-6s6u,2019-09-11,2019-07-03
-3s6g,2012-04-18,2011-05-25
-7s6l,2022-05-11,2021-09-14
-7s6y,2022-07-27,2021-09-15
-5s66,2021-06-30,2020-11-08
-6s6g,2020-07-15,2019-07-03
-7s6q,2021-12-29,2021-09-14
-5s64,2021-06-30,2020-11-08
-3s6c,2011-07-20,2011-05-25
-6s6d,2019-10-16,2019-07-02
-7s6e,2021-10-13,2021-09-14
-3s68,2012-02-01,2011-05-25
-1s60,2004-05-18,2004-01-22
-3s6h,2012-04-25,2011-05-25
-6s6r,2020-07-15,2019-07-03
-7s6c,2021-11-03,2021-09-13
-7s62,2022-01-05,2021-09-12
-1s64,2004-07-27,2004-01-22
-1s6c,2004-02-24,2004-01-23
-7s6f,2021-10-20,2021-09-14
-6s6t,2019-09-11,2019-07-03
-3s69,2012-05-23,2011-05-25
-5s6y,2020-11-25,2020-11-13
-5s6z,2020-11-25,2020-11-13
-5s65,2021-06-30,2020-11-08
-1s6m,2005-06-14,2004-01-26
-5s62,2021-06-30,2020-11-08
-1s6r,2004-02-24,2004-01-27
-3s61,2011-07-13,2011-05-23
-6s6q,2020-01-29,2019-07-03
-3s6j,2011-07-13,2011-05-25
-7s65,2021-09-22,2021-09-13
-5s6x,2020-11-25,2020-11-13
-3s6b,2011-06-29,2011-05-25
-7s6w,2022-07-27,2021-09-15
-1s6h,2004-03-16,2004-01-23
-1s6q,2004-05-11,2004-01-26
-7s63,2022-01-05,2021-09-13
-3s6t,2012-04-11,2011-05-26
-7s6j,2022-05-11,2021-09-14
-6s6y,2019-12-04,2019-07-04
-7s6n,2022-05-25,2021-09-14
-6s6w,2020-04-22,2019-07-03
-7s6d,2021-11-03,2021-09-13
-1s6a,2004-09-21,2004-01-22
-7s6x,2022-07-27,2021-09-15
-7s6z,2022-07-27,2021-09-15
-5s61,2021-06-30,2020-11-08
-5s67,2021-06-30,2020-11-08
-5s63,2021-06-30,2020-11-08
-1s69,2004-09-21,2004-01-22
-1s67,2004-06-22,2004-01-22
-3s6z,2011-11-23,2011-05-26
-1s68,2004-02-24,2004-01-22
-7s69,2022-05-25,2021-09-13
-6s69,2020-07-22,2019-07-02
-3s6l,2011-06-22,2011-05-25
-3s6y,2011-11-23,2011-05-26
-1s6f,2004-03-16,2004-01-23
-5s60,2021-06-30,2020-11-08
-3s6p,2012-05-30,2011-05-25
-6s61,2019-07-10,2019-07-02
-6s6a,2019-10-16,2019-07-02
-7s6s,2021-12-29,2021-09-14
-3s6i,2011-12-14,2011-05-25
-11as,1998-12-30,1997-12-02
-3ppe,2011-02-02,2010-11-24
-8ppm,2024-02-07,2023-07-07
-8pp8,2024-02-28,2023-07-07
-3pp9,2011-01-12,2010-11-24
-5ppe,2017-03-29,2017-02-07
-3ppr,2011-05-11,2010-11-25
-1ppb,1994-01-31,1991-10-24
-5pp3,2017-03-29,2017-02-07
-5pp7,2017-03-29,2017-02-07
-3pp0,2011-03-30,2010-11-23
-6pp8,2020-03-11,2019-07-05
-8pp5,2023-12-27,2023-07-06
-1pp4,2004-03-02,2003-06-16
-1ppm,1993-10-31,1992-06-01
-2ppc,2008-04-01,2007-04-28
-8ppz,2023-08-09,2023-07-10
-8ppd,2024-02-28,2023-07-07
-4pph,2015-02-11,2014-02-27
-8pps,2024-05-15,2023-07-08
-4ppz,2014-03-26,2014-02-27
-6ppv,2020-06-17,2019-07-08
-3pp5,2011-06-08,2010-11-24
-5ppl,2017-03-29,2017-02-07
-2ppd,2008-01-15,2007-04-28
-7ppy,2022-04-06,2021-09-15
-8ppc,2024-02-28,2023-07-07
-5ppm,2017-03-29,2017-02-07
-4pp4,2015-01-21,2014-02-26
-3ppv,2011-05-04,2010-11-25
-8pp9,2024-02-28,2023-07-07
-4pp6,2014-05-07,2014-02-26
-3ppc,2011-10-12,2010-11-24
-5pp1,2017-03-29,2017-02-07
-1pp9,2004-07-20,2003-06-16
-8ppj,2024-02-28,2023-07-07
-4ppu,2014-09-03,2014-02-27
-3ppd,2011-06-29,2010-11-24
-4pp3,2014-06-18,2014-02-26
-8pph,2024-02-28,2023-07-07
-5ppy,2017-03-29,2017-02-07
-8ppp,2024-02-07,2023-07-07
-4ppb,2014-06-04,2014-02-26
-2pp9,2008-04-01,2007-04-28
-2ppq,2007-06-05,2007-04-30
-5pph,2017-03-29,2017-02-07
-5ppt,2017-03-29,2017-02-07
-4ppe,2014-03-26,2014-02-26
-6ppn,2020-06-17,2019-07-08
-7pp6,2022-02-16,2021-09-13
-3ppl,2010-12-22,2010-11-24
-3ppy,2011-05-04,2010-11-25
-6ppo,2020-03-11,2019-07-08
-1ppf,1994-01-31,1991-10-24
-6ppq,2020-06-17,2019-07-08
-6ppr,2019-11-20,2019-07-08
-4ppp,2014-05-07,2014-02-27
-6ppj,2019-11-20,2019-07-07
-4ppa,2014-06-04,2014-02-26
-1ppk,1994-05-31,1994-01-20
-1ppj,2004-07-20,2003-06-16
-7ppi,2022-06-15,2021-09-13
-6ppe,2020-03-11,2019-07-06
-2ppf,2008-01-15,2007-04-28
-8ppk,2023-10-18,2023-07-07
-6pp6,2020-03-11,2019-07-05
-2ppb,2007-07-17,2007-04-28
-4ppo,2015-01-14,2014-02-27
-8ppw,2024-01-31,2023-07-10
-8pp7,2024-03-27,2023-07-06
-6pp2,2020-04-29,2019-07-05
-1ppr,1997-08-20,1996-03-06
-5ppk,2017-03-29,2017-02-07
-2pp7,2008-04-01,2007-04-28
-3ppw,2011-05-04,2010-11-25
-4ppt,2014-09-03,2014-02-27
-8ppn,2023-09-13,2023-07-07
-8ppa,2024-02-28,2023-07-07
-6pp9,2019-10-09,2019-07-05
-1ppw,2004-06-24,2003-06-17
-7ppl,2022-09-07,2021-09-14
-5ppo,2017-03-29,2017-02-07
-5ppb,2017-03-29,2017-02-07
-3ppi,2010-12-08,2010-11-24
-6ppm,2019-11-13,2019-07-08
-3ppk,2011-02-02,2010-11-24
-8ppv,2023-12-20,2023-07-10
-4ppc,2014-06-04,2014-02-26
-5ppr,2017-03-29,2017-02-07
-3ppo,2011-05-11,2010-11-24
-5ppn,2017-03-29,2017-02-07
-8ppi,2024-02-28,2023-07-07
-5ppp,2017-03-29,2017-02-07
-4ppr,2014-11-05,2014-02-27
-4pps,2014-05-07,2014-02-27
-6pp1,2020-04-29,2019-07-05
-7ppf,2022-06-15,2021-09-13
-7pp9,2022-09-21,2021-09-13
-2ppe,2008-01-15,2007-04-28
-8pp4,2023-12-27,2023-07-06
-8pp3,2023-12-27,2023-07-06
-5ppi,2017-03-29,2017-02-07
-7pp4,2022-09-21,2021-09-13
-6pp3,2020-04-29,2019-07-05
-1ppc,1994-01-31,1991-10-24
-4pp9,2014-06-04,2014-02-26
-1ppx,2003-08-26,2003-06-17
-5pp9,2017-03-29,2017-02-07
-2pp1,2007-08-07,2007-04-27
-6ppy,2019-10-02,2019-07-08
-7ppj,2022-01-26,2021-09-14
-5ppq,2017-03-29,2017-02-07
-8ppf,2024-02-28,2023-07-07
-5ppu,2017-03-29,2017-02-07
-5pp0,2017-03-15,2017-02-07
-1pp7,2003-11-18,2003-06-16
-7pp1,2022-11-02,2021-09-13
-7ppx,2022-09-21,2021-09-15
-8ppe,2024-02-28,2023-07-07
-6ppp,2020-06-17,2019-07-08
-6ppg,2019-12-11,2019-07-06
-7pp8,2022-07-06,2021-09-13
-5pp2,2017-03-29,2017-02-07
-7ppe,2022-06-15,2021-09-13
-6ppk,2019-09-18,2019-07-07
-8ppb,2024-02-28,2023-07-07
-6ppz,2019-10-02,2019-07-08
-3pp1,2011-02-23,2010-11-23
-7ppg,2022-06-15,2021-09-13
-6ppw,2019-10-02,2019-07-08
-8pp0,2024-02-07,2023-07-05
-6pp7,2020-03-11,2019-07-05
-5ppf,2017-03-29,2017-02-07
-2ppt,2007-10-02,2007-04-30
-1ppp,1994-01-31,1993-03-17
-2pp3,2007-08-07,2007-04-27
-4ppf,2015-03-18,2014-02-26
-1ppt,1981-02-19,1981-01-16
-7ppt,2022-06-08,2021-09-15
-6pp5,2020-03-11,2019-07-05
-1ppo,1993-10-31,1991-07-12
-4pp0,2014-10-22,2014-02-26
-6ppl,2020-02-19,2019-07-08
-7pp7,2021-12-22,2021-09-13
-7ppn,2022-09-07,2021-09-14
-5ppj,2017-03-29,2017-02-07
-5ppd,2017-03-29,2017-02-07
-1ppl,1993-10-31,1992-06-01
-4pp7,2014-04-09,2014-02-26
-5pp4,2017-03-29,2017-02-07
-7pp0,2022-03-16,2021-09-10
-4ppx,2014-04-02,2014-02-27
-2pp8,2008-04-01,2007-04-28
-4ppv,2014-09-03,2014-02-27
-1ppv,2004-06-29,2003-06-17
-5ppa,2017-03-29,2017-02-07
-5pps,2017-03-29,2017-02-07
-7ppp,2021-12-08,2021-09-14
-8pp2,2023-12-27,2023-07-06
-3ppu,2010-12-22,2010-11-25
-7ppo,2021-10-27,2021-09-14
-4pp5,2014-06-18,2014-02-26
-3pps,2011-05-18,2010-11-25
-5pp6,2017-03-29,2017-02-07
-5pp8,2017-03-29,2017-02-07
-1ppg,1994-01-31,1991-10-24
-3ppj,2011-02-02,2010-11-24
-5pp5,2017-03-29,2017-02-07
-7ppq,2022-04-06,2021-09-14
-5ppg,2017-03-29,2017-02-07
-1ppi,1995-05-24,1994-02-22
-6pp4,2020-04-29,2019-07-05
-3ppx,2011-05-04,2010-11-25
-8ppu,2023-12-20,2023-07-10
-3ppg,2011-10-12,2010-11-24
-8ppg,2024-02-28,2023-07-07
-8pp6,2024-04-03,2023-07-06
-2ppl,2007-06-05,2007-04-30
-8ppt,2023-12-20,2023-07-10
-7ppm,2022-09-07,2021-09-14
-7ppv,2022-06-08,2021-09-15
-5ppz,2017-03-29,2017-02-07
-7pp2,2022-06-29,2021-09-13
-1ppa,1994-01-31,1991-10-29
-3pp7,2010-12-15,2010-11-24
-5ppv,2017-03-29,2017-02-07
-6pps,2020-07-15,2019-07-08
-1pph,1994-01-31,1991-10-24
-5ppw,2017-03-29,2017-02-07
-7ppu,2022-06-08,2021-09-15
-6ppu,2019-11-20,2019-07-08
-2ppa,2008-04-01,2007-04-28
-5ppc,2017-03-29,2017-02-07
-3ppm,2011-11-09,2010-11-24
-6pp0,2020-04-29,2019-07-05
-4ppm,2015-01-14,2014-02-27
-3ppz,2011-12-07,2010-11-25
-5ppx,2017-03-29,2017-02-07
-7pph,2022-06-15,2021-09-13
-6q02,2019-11-20,2019-08-01
-7q0x,2022-05-25,2021-10-16
-3q0j,2012-01-25,2010-12-15
-4q01,2014-09-10,2014-03-31
-2q01,2007-05-29,2007-05-18
-6q0r,2019-11-13,2019-08-02
-6q00,2020-04-29,2019-08-01
-8q0o,2024-06-05,2023-07-28
-1q0y,2004-04-20,2003-07-17
-4q06,2015-01-28,2014-04-01
-6q0h,2019-12-18,2019-08-01
-5q0j,2017-07-05,2017-05-31
-7q0j,2022-03-23,2021-10-15
-3q0a,2011-02-23,2010-12-15
-3q0o,2011-03-16,2010-12-15
-5q0n,2017-07-05,2017-05-31
-7q0p,2022-05-18,2021-10-15
-3q0e,2012-02-22,2010-12-15
-4q0i,2014-07-16,2014-04-02
-4q0x,2014-07-09,2014-04-02
-7q05,2022-03-30,2021-10-14
-3q0r,2011-03-16,2010-12-15
-2q04,2007-06-12,2007-05-18
-5q0w,2017-07-05,2017-05-31
-4q0o,2014-05-07,2014-04-02
-3q00,2011-12-21,2010-12-15
-5q03,2019-01-09,2017-04-18
-1q0k,2004-05-18,2003-07-16
-7q0c,2022-01-12,2021-10-14
-8q0t,2023-11-22,2023-07-29
-6q0t,2019-10-09,2019-08-02
-7q0g,2021-12-22,2021-10-14
-4q0j,2014-07-16,2014-04-02
-7q0s,2022-07-27,2021-10-16
-7q0y,2022-04-13,2021-10-17
-3q01,2011-05-11,2010-12-15
-6q0s,2020-01-22,2019-08-02
-6q09,2020-01-22,2019-08-01
-5q08,2019-01-09,2017-04-18
-4q0u,2014-05-28,2014-04-02
-3q0u,2012-01-11,2010-12-16
-5q09,2019-01-09,2017-04-16
-8q0f,2024-06-05,2023-07-28
-5q0t,2017-07-05,2017-05-31
-7q08,2022-05-25,2021-10-14
-5q0s,2017-07-05,2017-05-31
-6q0g,2020-03-18,2019-08-01
-5q0x,2017-07-05,2017-05-31
-2q0i,2008-06-03,2007-05-22
-5q0u,2017-07-05,2017-05-31
-2q0n,2007-06-26,2007-05-22
-3q0g,2012-01-25,2010-12-15
-1q09,2003-09-16,2003-07-15
-7q0k,2022-03-23,2021-10-15
-4q0t,2014-09-10,2014-04-02
-1q06,2003-09-16,2003-07-15
-1q0f,2004-05-18,2003-07-16
-6q0l,2019-12-18,2019-08-01
-3q0q,2011-03-16,2010-12-15
-4q0z,2014-08-27,2014-04-02
-6q0u,2019-11-13,2019-08-02
-1q0d,2004-05-18,2003-07-16
-2q0d,2007-08-28,2007-05-21
-1q0p,2004-03-30,2003-07-17
-6q0c,2019-08-28,2019-08-01
-4q0p,2014-05-28,2014-04-02
-6q0d,2020-09-23,2019-08-01
-7q0u,2022-05-25,2021-10-16
-7q0f,2022-05-18,2021-10-14
-1q0g,2004-05-18,2003-07-16
-7q0o,2022-06-22,2021-10-15
-4q0k,2014-04-23,2014-04-02
-6q0m,2019-11-13,2019-08-02
-6q04,2019-12-11,2019-08-01
-5q0q,2017-07-05,2017-05-31
-4q0s,2014-05-28,2014-04-02
-5q0b,2019-01-09,2017-04-18
-2q08,2007-06-19,2007-05-21
-2q0g,2007-08-28,2007-05-21
-8q0a,2024-06-05,2023-07-28
-7q0i,2021-12-22,2021-10-14
-6q0i,2019-12-18,2019-08-01
-4q0n,2014-05-07,2014-04-02
-1q0l,2004-07-20,2003-07-16
-7q04,2022-04-06,2021-10-14
-8q0u,2023-11-22,2023-07-29
-2q0o,2007-09-25,2007-05-22
-6q03,2019-11-27,2019-08-01
-3q0l,2011-03-16,2010-12-15
-3q0n,2011-03-16,2010-12-15
-4q09,2015-01-28,2014-04-01
-2q0y,2007-06-05,2007-05-22
-3q08,2011-01-05,2010-12-15
-5q0e,2017-07-12,2017-05-01
-7q0q,2022-11-02,2021-10-16
-2q0m,2007-12-11,2007-05-22
-5q0v,2017-07-05,2017-05-31
-5q00,2019-01-16,2017-04-18
-4q0q,2014-05-28,2014-04-02
-2q09,2007-06-05,2007-05-21
-1q0n,2003-08-26,2003-07-16
-6q0f,2020-03-18,2019-08-01
-2q0f,2007-08-28,2007-05-21
-5q04,2019-01-09,2017-04-18
-6q0y,2019-11-27,2019-08-02
-1q0s,2003-09-23,2003-07-17
-1q0r,2003-11-25,2003-07-17
-2q0c,2007-08-28,2007-05-21
-3q03,2011-06-22,2010-12-15
-3q06,2011-05-11,2010-12-15
-5q05,2019-01-09,2017-04-20
-7q0h,2021-12-22,2021-10-14
-4q0b,2014-06-18,2014-04-01
-7q0m,2022-03-09,2021-10-15
-4q03,2014-09-10,2014-03-31
-6q0v,2019-11-13,2019-08-02
-1q0h,2004-07-20,2003-07-16
-3q0s,2011-03-16,2010-12-15
-5q07,2019-01-09,2017-04-16
-3q0t,2012-02-29,2010-12-16
-6q0q,2020-04-29,2019-08-02
-5q0y,2017-07-05,2017-05-31
-1q0z,2003-11-25,2003-07-18
-4q0w,2014-08-27,2014-04-02
-5q0i,2017-07-05,2017-05-31
-1q05,2003-09-16,2003-07-15
-4q0r,2014-08-27,2014-04-02
-4q0y,2014-06-18,2014-04-02
-5q01,2019-01-09,2017-04-18
-4q0l,2015-01-28,2014-04-02
-6q0a,2019-11-27,2019-08-01
-4q0a,2014-07-02,2014-04-01
-7q0a,2022-02-23,2021-10-14
-2q0e,2007-08-28,2007-05-21
-4q02,2014-09-10,2014-03-31
-5q0p,2017-07-05,2017-05-31
-3q0z,2011-04-27,2010-12-16
-4q0e,2014-10-15,2014-04-01
-2q0l,2007-07-03,2007-05-22
-2q02,2007-06-05,2007-05-18
-3q05,2011-05-11,2010-12-15
-3q0k,2012-02-15,2010-12-15
-7q0r,2022-05-25,2021-10-16
-7q07,2021-12-08,2021-10-14
-8q0j,2024-06-05,2023-07-28
-5q0r,2017-07-05,2017-05-31
-3q09,2011-01-05,2010-12-15
-4q04,2014-04-23,2014-03-31
-1q0c,2003-07-29,2003-07-15
-6q0n,2019-11-13,2019-08-02
-5q0h,2017-07-12,2017-05-01
-1q0m,2004-05-18,2003-07-16
-4q0m,2014-12-10,2014-04-02
-8q00,2023-12-13,2023-07-27
-2q0b,2007-09-25,2007-05-21
-3q07,2011-12-21,2010-12-15
-1q0e,2003-09-23,2003-07-16
-3q0m,2011-03-16,2010-12-15
-6q0w,2019-11-13,2019-08-02
-2q0j,2008-06-03,2007-05-22
-6q0o,2019-12-18,2019-08-02
-3q0w,2011-12-21,2010-12-16
-8q0s,2024-02-07,2023-07-29
-7q01,2022-11-02,2021-10-13
-6q0j,2019-10-09,2019-08-01
-7q06,2022-03-30,2021-10-14
-8q0m,2024-06-05,2023-07-28
-5q0g,2017-07-12,2017-05-01
-1q0b,2004-01-13,2003-07-15
-4q0d,2014-10-15,2014-04-01
-8q0n,2024-01-10,2023-07-28
-7q09,2022-02-09,2021-10-14
-4q07,2015-01-28,2014-04-01
-7q03,2021-12-08,2021-10-14
-4q0v,2014-05-28,2014-04-02
-7q0v,2022-05-25,2021-10-16
-2q0k,2007-07-03,2007-05-22
-7q0e,2022-01-12,2021-10-14
-5q0f,2017-07-12,2017-05-01
-5q0l,2017-07-05,2017-05-31
-8q0q,2024-06-05,2023-07-28
-7q0t,2022-05-25,2021-10-16
-6q05,2019-12-11,2019-08-01
-6q06,2019-12-11,2019-08-01
-6q07,2019-12-11,2019-08-01
-6q0z,2020-02-05,2019-08-02
-1q0a,2003-09-16,2003-07-15
-2q0u,2007-07-17,2007-05-22
-4q05,2014-06-04,2014-03-31
-3q0v,2012-01-11,2010-12-16
-1q08,2003-09-16,2003-07-15
-2q0h,2008-06-10,2007-05-22
-1q0o,2003-07-29,2003-07-16
-5q0a,2019-01-09,2017-04-11
-1q07,2003-09-16,2003-07-15
-6q01,2020-04-29,2019-08-01
-5q0z,2017-07-05,2017-05-31
-5q0m,2017-07-05,2017-05-31
-4q0h,2014-07-16,2014-04-02
-5q0o,2017-07-05,2017-05-31
-1q0q,2004-07-20,2003-07-17
-7q0d,2022-01-12,2021-10-14
-5q0c,2019-01-09,2017-04-18
-2q0a,2007-06-19,2007-05-21
-5q06,2019-01-09,2017-04-18
-2q0r,2007-07-17,2007-05-22
-5q0d,2017-07-12,2017-05-01
-5q02,2019-01-09,2017-04-18
-3q0p,2011-03-16,2010-12-15
-8q0c,2024-03-06,2023-07-28
-7q0w,2022-05-25,2021-10-16
-3q02,2011-06-22,2010-12-15
-4q08,2015-01-28,2014-04-01
-1q0t,2003-09-23,2003-07-17
-5q3l,2018-08-08,2017-05-25
-4q3y,2015-02-18,2014-04-12
-5q3j,2018-08-08,2017-05-25
-3q3o,2011-12-28,2010-12-22
-5q39,2018-08-08,2017-05-25
-3q3b,2011-06-15,2010-12-21
-7q3p,2022-09-28,2021-10-28
-4q38,2014-09-10,2014-04-11
-7q37,2022-04-27,2021-10-27
-4q3v,2014-07-16,2014-04-12
-8q3p,2023-09-27,2023-08-04
-3q3c,2011-02-23,2010-12-21
-3q3l,2012-02-08,2010-12-22
-1q39,2004-08-03,2003-07-29
-8q3u,2023-09-20,2023-08-04
-4q3x,2015-02-18,2014-04-12
-5q3i,2018-08-08,2017-05-25
-1q3d,2003-10-21,2003-07-29
-8q3z,2023-11-22,2023-08-04
-1q3f,2004-03-23,2003-07-29
-5q3c,2018-08-08,2017-05-25
-6q3e,2019-07-31,2018-12-04
-2q32,2007-06-05,2007-05-29
-1q36,2003-12-16,2003-07-28
-7q35,2022-04-27,2021-10-27
-4q3i,2014-11-12,2014-04-11
-8q3n,2023-09-27,2023-08-04
-3q32,2011-02-16,2010-12-21
-3q3h,2011-08-24,2010-12-21
-5q3t,2018-08-08,2017-05-25
-1q3a,2004-04-06,2003-07-29
-4q3n,2015-02-25,2014-04-11
-6q37,2019-08-28,2018-12-03
-3q3x,2011-09-07,2010-12-22
-7q3m,2022-11-09,2021-10-28
-4q3m,2015-02-25,2014-04-11
-1q3q,2004-01-27,2003-07-31
-5q3m,2018-08-08,2017-05-25
-3q38,2011-05-11,2010-12-21
-5q3f,2018-08-08,2017-05-25
-3q3j,2011-01-12,2010-12-21
-5q32,2018-08-08,2017-05-25
-7q34,2022-06-01,2021-10-26
-6q3x,2020-07-15,2018-12-04
-4q3w,2015-02-18,2014-04-12
-8q3a,2023-12-06,2023-08-03
-7q3s,2022-05-04,2021-10-28
-8q30,2024-03-06,2023-08-03
-1q3z,2004-09-07,2003-08-01
-1q3w,2003-10-21,2003-08-01
-5q31,2018-08-08,2017-05-25
-5q3v,2018-08-08,2017-05-25
-7q3e,2022-04-06,2021-10-27
-1q3v,2003-09-16,2003-08-01
-6q3u,2019-05-08,2018-12-04
-7q3r,2022-11-16,2021-10-28
-1q3k,2003-08-12,2003-07-30
-5q3z,2018-08-08,2017-05-25
-5q34,2018-08-08,2017-05-25
-6q35,2019-04-24,2018-12-03
-6q3o,2019-12-25,2018-12-04
-6q31,2019-07-31,2018-12-03
-5q3a,2018-08-08,2017-05-25
-7q32,2022-05-04,2021-10-26
-2q3v,2007-06-19,2007-05-30
-6q34,2019-07-31,2018-12-03
-7q3g,2022-11-16,2021-10-27
-1q3h,2003-12-09,2003-07-29
-5q3k,2018-08-08,2017-05-25
-8q3o,2023-09-27,2023-08-04
-7q3l,2022-03-30,2021-10-28
-3q3s,2012-01-18,2010-12-22
-7q3x,2022-02-16,2021-10-29
-2q3l,2007-06-12,2007-05-30
-2q3k,2007-08-21,2007-05-30
-4q3z,2015-02-18,2014-04-12
-5q3x,2018-08-08,2017-05-25
-2q3c,2007-06-12,2007-05-30
-4q33,2014-07-09,2014-04-10
-8q3g,2023-12-06,2023-08-04
-4q3s,2014-07-16,2014-04-12
-7q3w,2022-11-09,2021-10-28
-8q3b,2024-02-14,2023-08-03
-2q3d,2007-06-12,2007-05-30
-3q3u,2011-03-02,2010-12-22
-6q3g,2019-11-06,2018-12-04
-5q36,2018-08-08,2017-05-25
-6q3s,2019-07-24,2018-12-04
-7q3c,2022-04-20,2021-10-27
-6q36,2019-07-03,2018-12-03
-7q3z,2022-01-26,2021-10-29
-8q3k,2024-02-14,2023-08-04
-6q3q,2018-12-19,2018-12-04
-4q39,2014-04-23,2014-04-11
-3q36,2011-04-13,2010-12-21
-2q3f,2007-06-12,2007-05-30
-8q3e,2024-03-27,2023-08-04
-1q3c,2004-08-03,2003-07-29
-8q38,2023-12-06,2023-08-03
-4q32,2014-07-09,2014-04-10
-2q3e,2007-07-03,2007-05-30
-5q3h,2018-08-08,2017-05-25
-3q3n,2011-12-28,2010-12-22
-7q36,2022-04-27,2021-10-27
-3q31,2011-03-09,2010-12-21
-6q32,2021-02-17,2018-12-03
-7q30,2022-04-06,2021-10-26
-2q3i,2007-06-12,2007-05-30
-6q3y,2019-03-06,2018-12-04
-3q3v,2011-01-12,2010-12-22
-4q3r,2014-07-16,2014-04-12
-2q3p,2007-06-19,2007-05-30
-2q3j,2008-04-22,2007-05-30
-8q34,2024-02-07,2023-08-03
-1q3u,2003-09-16,2003-08-01
-5q3b,2018-08-08,2017-05-25
-2q38,2007-10-02,2007-05-30
-3q3m,2011-12-28,2010-12-22
-3q3a,2011-05-11,2010-12-21
-6q3r,2019-06-12,2018-12-04
-5q3p,2018-08-08,2017-05-25
-5q3w,2018-08-08,2017-05-25
-7q3n,2022-03-16,2021-10-28
-5q3s,2018-08-08,2017-05-25
-7q3b,2022-06-15,2021-10-27
-4q3j,2014-07-30,2014-04-11
-2q3z,2007-10-23,2007-05-30
-5q37,2018-08-08,2017-05-25
-6q3b,2019-03-20,2018-12-04
-3q3d,2011-06-15,2010-12-21
-2q3y,2007-09-04,2007-05-30
-4q3d,2014-04-23,2014-04-11
-6q30,2019-04-24,2018-12-03
-3q39,2011-05-11,2010-12-21
-5q3r,2018-08-08,2017-05-25
-5q38,2018-08-08,2017-05-25
-1q3p,2004-01-27,2003-07-31
-7q3f,2022-04-20,2021-10-27
-4q30,2014-06-04,2014-04-10
-3q3y,2011-09-07,2010-12-22
-3q3t,2011-08-03,2010-12-22
-4q3a,2014-04-23,2014-04-11
-2q3u,2007-06-19,2007-05-30
-4q3u,2014-07-16,2014-04-12
-3q3g,2011-11-30,2010-12-21
-5q3d,2018-08-08,2017-05-25
-4q36,2014-09-10,2014-04-11
-2q3n,2007-06-26,2007-05-30
-4q3q,2014-07-16,2014-04-12
-3q35,2011-02-02,2010-12-21
-2q3h,2007-06-19,2007-05-30
-5q3e,2018-08-08,2017-05-25
-6q3c,2019-03-20,2018-12-04
-8q3x,2024-03-27,2023-08-04
-6q39,2019-08-28,2018-12-03
-6q3f,2019-03-20,2018-12-04
-2q31,2007-06-05,2007-05-29
-1q3g,2003-12-16,2003-07-29
-4q37,2014-07-16,2014-04-11
-5q30,2018-08-08,2017-05-25
-8q37,2023-12-06,2023-08-03
-3q30,2011-12-21,2010-12-21
-5q3y,2018-08-08,2017-05-25
-2q37,2007-06-12,2007-05-30
-6q3z,2019-03-06,2018-12-04
-8q3q,2023-09-27,2023-08-04
-4q3c,2014-04-23,2014-04-11
-1q3e,2003-09-09,2003-07-29
-3q34,2011-02-23,2010-12-21
-7q39,2022-04-20,2021-10-27
-5q3u,2018-08-08,2017-05-25
-1q3x,2004-08-03,2003-08-01
-3q3q,2011-12-28,2010-12-22
-1q3b,2004-08-03,2003-07-29
-6q3m,2019-12-25,2018-12-04
-2q3x,2007-08-28,2007-05-30
-4q3b,2014-04-23,2014-04-11
-5q3g,2018-08-08,2017-05-25
-3q3k,2011-12-28,2010-12-22
-1q3y,2004-09-07,2003-08-01
-8q39,2023-12-06,2023-08-03
-2q3w,2007-06-19,2007-05-30
-6q3d,2019-07-31,2018-12-04
-4q3t,2014-07-16,2014-04-12
-8q31,2023-12-06,2023-08-03
-2q36,2007-06-05,2007-05-29
-4q3g,2014-11-12,2014-04-11
-7q3q,2022-11-16,2021-10-28
-8q36,2024-03-27,2023-08-03
-7q38,2022-04-27,2021-10-27
-4q3p,2014-07-16,2014-04-12
-5q35,2018-08-08,2017-05-25
-5q3o,2018-08-08,2017-05-25
-7q3a,2022-05-04,2021-10-27
-1q33,2003-09-30,2003-07-28
-5q3n,2018-08-08,2017-05-25
-8q32,2023-12-06,2023-08-03
-7q33,2023-02-08,2021-10-26
-3q33,2011-02-02,2010-12-21
-8q35,2023-12-06,2023-08-03
-8q3m,2024-03-27,2023-08-04
-8q33,2023-12-06,2023-08-03
-5q33,2018-08-08,2017-05-25
-1q3i,2004-08-03,2003-07-30
-7q3y,2022-07-20,2021-10-29
-5q3q,2018-08-08,2017-05-25
-6q3w,2019-01-23,2018-12-04
-4q3e,2014-04-23,2014-04-11
-4q3k,2015-02-25,2014-04-11
-1q3s,2004-01-27,2003-07-31
-1q3l,2004-10-12,2003-07-30
-2q3r,2007-06-19,2007-05-30
-2q3o,2007-06-19,2007-05-30
-7q3t,2022-07-06,2021-10-28
-6q3k,2019-07-24,2018-12-04
-7q31,2022-04-06,2021-10-26
-3ma0,2010-08-18,2010-03-23
-7mal,2022-04-06,2021-03-31
-5mah,2017-12-06,2016-11-03
-4mab,2013-11-20,2013-08-15
-1ma9,2003-02-04,2002-08-02
-4map,2013-11-27,2013-08-16
-2ma6,2013-07-31,2013-06-28
-1max,1996-10-14,1996-02-06
-7map,2022-11-09,2021-03-31
-6maj,2019-12-25,2018-08-27
-6ma2,2018-10-17,2018-08-25
-5maf,2017-12-06,2016-11-03
-3ma9,2010-12-01,2010-03-23
-5mau,2017-12-20,2016-11-04
-4mar,2013-10-09,2013-08-16
-3ma3,2010-04-14,2010-03-23
-5mad,2017-12-06,2016-11-03
-6mak,2019-12-25,2018-08-27
-4mai,2013-12-18,2013-08-16
-7maj,2022-04-20,2021-03-31
-6mac,2019-07-17,2018-08-27
-1maa,1999-04-20,1998-11-04
-6ma1,2018-10-17,2018-08-25
-7man,2022-04-27,2021-03-31
-6may,2019-06-05,2018-08-29
-7maa,2022-11-09,2021-03-31
-4ma5,2013-08-28,2013-08-15
-3ma7,2011-03-16,2010-03-23
-2mat,1999-06-18,1999-03-29
-5ma0,2017-07-12,2016-11-02
-6mar,2018-09-26,2018-08-28
-3mau,2010-08-18,2010-03-24
-3max,2010-04-28,2010-03-24
-7max,2022-10-12,2021-03-31
-7ma2,2022-04-27,2021-03-31
-7ma8,2022-11-09,2021-03-31
-1maw,2003-01-07,2002-08-02
-6mav,2019-05-15,2018-08-28
-2map,2014-02-19,2013-07-16
-5ma5,2017-11-08,2016-11-03
-7maq,2022-11-09,2021-03-31
-1map,1994-01-31,1993-09-10
-6ma5,2018-10-17,2018-08-25
-5mar,2017-03-15,2016-11-04
-1mac,1995-02-27,1994-12-22
-7maz,2022-10-12,2021-03-31
-5ma7,2017-08-16,2016-11-03
-5mam,2017-04-05,2016-11-03
-5maz,2017-12-20,2016-11-07
-5man,2017-12-20,2016-11-03
-4ma1,2014-04-09,2013-08-15
-7ma7,2022-11-09,2021-03-31
-6mau,2019-04-03,2018-08-28
-6maz,2019-06-05,2018-08-29
-7ma6,2022-11-09,2021-03-31
-6maq,2019-09-04,2018-08-28
-7mah,2022-04-27,2021-03-31
-4mam,2013-08-28,2013-08-16
-6maw,2019-09-04,2018-08-28
-3mak,2011-03-30,2010-03-24
-6ma4,2018-10-17,2018-08-25
-1mas,1996-08-17,1995-12-18
-7mat,2022-10-12,2021-03-31
-7ma4,2022-11-09,2021-03-31
-4mag,2014-07-02,2013-08-16
-4ma8,2014-01-22,2013-08-15
-2ma5,2013-08-14,2013-06-28
-3maw,2010-05-26,2010-03-24
-6max,2019-04-17,2018-08-28
-6mao,2018-09-12,2018-08-28
-3mag,1999-07-22,1998-07-12
-7mac,2022-04-06,2021-03-31
-1may,1996-10-14,1996-02-06
-3ma2,2010-06-30,2010-03-23
-7ma1,2022-04-27,2021-03-31
-5mat,2017-02-08,2016-11-04
-4mao,2014-10-22,2013-08-16
-5maa,2017-07-12,2016-11-03
-7mas,2022-11-09,2021-03-31
-5mag,2017-12-06,2016-11-03
-1mat,1994-01-31,1992-12-02
-4mav,2013-09-11,2013-08-17
-5map,2017-05-10,2016-11-04
-1mav,2002-12-04,2002-08-02
-6ma6,2019-01-16,2018-08-26
-4mat,1999-06-18,1999-03-29
-1mai,1996-11-08,1996-05-23
-5ma1,2017-07-12,2016-11-02
-3map,2010-11-10,2010-03-24
-7maf,2022-04-27,2021-03-31
-6mae,2019-01-23,2018-08-27
-7mau,2022-10-12,2021-03-31
-1ma0,2002-08-02,2002-07-30
-7maw,2022-10-12,2021-03-31
-3mas,2010-11-10,2010-03-24
-5maj,2017-01-11,2016-11-03
-2ma7,2013-09-04,2013-06-28
-2mas,1997-08-12,1996-10-17
-5ma2,2017-07-12,2016-11-03
-6ma3,2018-10-17,2018-08-25
-7ma9,2022-11-09,2021-03-31
-4ma7,2014-01-22,2013-08-15
-5mai,2017-12-06,2016-11-03
-1mab,1998-09-30,1998-08-06
-4ma4,2013-12-11,2013-08-15
-2man,1999-08-13,1998-08-12
-1ma1,2002-08-21,2002-07-31
-7mad,2022-04-06,2021-03-31
-4ma0,2013-08-28,2013-08-15
-3ma6,2010-07-21,2010-03-23
-6map,2019-09-04,2018-08-28
-4maz,2013-09-25,2013-08-18
-4ma6,2013-11-27,2013-08-15
-7mav,2022-10-12,2021-03-31
-7ma0,2022-04-27,2021-03-31
-5maq,2017-12-20,2016-11-04
-4maf,2014-03-12,2013-08-16
-1mag,1997-01-11,1996-06-06
-4man,2014-01-29,2013-08-16
-5mac,2017-02-08,2016-11-03
-4mah,2013-12-18,2013-08-16
-7mai,2022-04-06,2021-03-31
-3man,1999-08-13,1998-08-12
-7mag,2022-04-20,2021-03-31
-5mae,2017-01-11,2016-11-03
-7mab,2022-04-27,2021-03-31
-1ma3,2002-10-16,2002-07-31
-6mam,2019-03-20,2018-08-28
-5mab,2017-12-20,2016-11-03
-3maq,2010-04-07,2010-03-24
-7mae,2022-04-20,2021-03-31
-4max,2013-08-28,2013-08-18
-6mat,2019-02-06,2018-08-28
-7ma3,2022-11-09,2021-03-31
-6ma8,2019-01-16,2018-08-26
-3mat,1999-06-18,1999-03-29
-4mas,2013-09-25,2013-08-16
-3mar,2010-11-10,2010-03-24
-1mah,1996-04-03,1995-11-21
-5may,2017-12-20,2016-11-07
-7mak,2022-04-20,2021-03-31
-6mal,2018-09-05,2018-08-28
-1maq,1994-01-31,1993-09-10
-7mao,2022-04-06,2021-03-31
-7mar,2022-11-09,2021-03-31
-6ma7,2019-01-16,2018-08-26
-4mae,2013-09-18,2013-08-16
-1mau,2003-01-07,2002-08-02
-7ma5,2022-11-09,2021-03-31
-3mao,2010-04-07,2010-03-24
-4ma9,2013-11-20,2013-08-15
-3maa,2010-04-07,2010-03-23
-6vyw,2020-09-02,2020-02-27
-5vy9,2017-07-19,2017-05-24
-6vy4,2020-12-30,2020-02-25
-2vy5,2009-02-17,2008-07-18
-1vyw,2004-06-10,2004-05-07
-3vy5,2013-09-25,2012-09-21
-3vyg,2013-11-13,2012-09-25
-3vym,2012-11-07,2012-09-28
-5vye,2018-06-27,2017-05-25
-7vy1,2022-11-23,2021-11-13
-6vys,2020-09-02,2020-02-27
-2vy4,2009-02-17,2008-07-17
-7vya,2022-12-14,2021-11-13
-5vy2,2018-11-21,2017-05-24
-2vyo,2008-08-12,2008-07-25
-2vyv,2008-08-05,2008-07-29
-6vyu,2020-09-02,2020-02-27
-3vyl,2013-10-02,2012-09-27
-7vyp,2022-11-16,2021-11-15
-3vyf,2012-12-19,2012-09-24
-2vyf,2008-12-30,2008-07-23
-1vyz,2004-06-17,2004-05-07
-5vys,2017-07-05,2017-05-26
-1vyr,2004-06-10,2004-05-05
-6vyo,2020-03-11,2020-02-27
-6vyb,2020-03-11,2020-02-25
-8vyg,2024-03-27,2024-02-08
-7vyg,2022-11-23,2021-11-14
-2vyp,2009-02-24,2008-07-25
-6vyh,2020-11-11,2020-02-26
-2vyc,2009-03-31,2008-07-22
-3vy9,2013-01-02,2012-09-21
-5vyf,2018-04-04,2017-05-25
-7vy8,2022-12-14,2021-11-13
-7vyx,2022-11-02,2021-11-15
-5vyl,2017-08-02,2017-05-25
-7vyo,2022-11-16,2021-11-14
-6vy6,2021-01-06,2020-02-25
-6vya,2021-02-03,2020-02-25
-3vye,2012-12-19,2012-09-24
-1vy7,2014-08-20,2014-05-13
-1vy5,2014-08-20,2014-05-13
-5vyr,2017-07-05,2017-05-26
-3vyw,2012-10-17,2012-10-03
-3vya,2013-09-25,2012-09-22
-5vyu,2017-07-05,2017-05-26
-6vyq,2020-09-02,2020-02-27
-5vyp,2017-08-02,2017-05-25
-1vyq,2005-05-26,2004-05-05
-7vyj,2022-11-16,2021-11-14
-6vyt,2020-09-02,2020-02-27
-1vy6,2014-08-20,2014-05-13
-6vyp,2020-05-27,2020-02-27
-5vyq,2017-07-12,2017-05-26
-3vyt,2012-11-28,2012-10-02
-5vyy,2018-04-18,2017-05-26
-3vyq,2013-01-16,2012-10-02
-5vyt,2017-07-05,2017-05-26
-6vyy,2020-09-02,2020-02-27
-5vya,2017-07-05,2017-05-24
-2vy3,2009-11-17,2008-07-17
-3vys,2012-11-28,2012-10-02
-5vyc,2017-07-19,2017-05-24
-7vy3,2022-04-27,2021-11-13
-5vyb,2017-07-05,2017-05-24
-7vys,2022-12-14,2021-11-15
-1vyk,2005-05-26,2004-04-30
-3vy7,2013-09-25,2012-09-21
-6vyd,2020-07-08,2020-02-26
-5vyo,2018-03-21,2017-05-25
-7vyw,2022-02-02,2021-11-15
-6vyz,2020-09-02,2020-02-27
-5vyd,2017-10-18,2017-05-25
-2vyn,2008-08-05,2008-07-25
-7vye,2022-12-14,2021-11-14
-3vyv,2013-10-09,2012-10-03
-1vyp,2004-05-26,2004-05-04
-2vyq,2009-04-21,2008-07-28
-5vyj,2017-06-28,2017-05-25
-3vyh,2013-11-13,2012-09-25
-6vyx,2020-09-02,2020-02-27
-2vyz,2008-10-07,2008-07-29
-3vyp,2013-06-19,2012-09-30
-1vyx,2004-10-01,2004-05-07
-3vy2,2013-09-25,2012-09-21
-5vy8,2017-07-05,2017-05-24
-5vyw,2017-08-16,2017-05-26
-2vye,2008-12-30,2008-07-23
-7vyf,2022-11-23,2021-11-14
-8vy8,2024-03-06,2024-02-07
-3vyk,2013-10-02,2012-09-26
-1vyj,2005-01-13,2004-04-30
-1vyd,2004-06-17,2004-04-27
-5vyh,2017-08-30,2017-05-25
-7vy9,2022-12-14,2021-11-13
-2vyx,2009-11-17,2008-07-29
-3vy8,2013-01-02,2012-09-21
-6vy2,2020-05-06,2020-02-25
-2vyt,2008-08-05,2008-07-28
-6vyr,2020-09-02,2020-02-27
-7vyh,2022-11-23,2021-11-14
-8vye,2024-03-27,2024-02-08
-8vyf,2024-03-27,2024-02-08
-7vyi,2022-11-23,2021-11-14
-2vyw,2008-08-12,2008-07-29
-7vyq,2022-04-06,2021-11-15
-7vyy,2022-11-16,2021-11-15
-6vy5,2021-01-06,2020-02-25
-7vyn,2022-12-28,2021-11-14
-5vyz,2017-08-16,2017-05-26
-2vyy,2008-10-07,2008-07-29
-3vy6,2013-09-25,2012-09-21
-7vy2,2022-04-27,2021-11-13
-5vyg,2017-08-09,2017-05-25
-3vyd,2012-12-19,2012-09-24
-1vys,2004-05-26,2004-05-05
-1vy4,2014-08-20,2014-05-13
-6vyj,2021-01-27,2020-02-26
-2vy0,2009-03-24,2008-07-15
-7o09,2021-09-01,2021-03-25
-3o0f,2010-08-25,2010-07-19
-1o0m,2003-12-09,2003-02-24
-4o0g,2014-04-30,2013-12-13
-2o04,2007-11-20,2006-11-27
-4o0x,2014-02-12,2013-12-14
-1o0n,2003-12-09,2003-02-24
-7o00,2022-05-11,2021-03-25
-6o0p,2019-05-22,2019-02-17
-4o0v,2014-02-12,2013-12-14
-5o0h,2017-06-28,2017-05-16
-5o0n,2017-10-18,2017-05-16
-6o0j,2020-02-19,2019-02-16
-5o0m,2017-10-18,2017-05-16
-6o0m,2019-05-22,2019-02-16
-2o0z,2008-04-08,2006-11-28
-3o03,2010-12-15,2010-07-18
-7o0t,2021-05-05,2021-03-26
-2o06,2006-12-12,2006-11-27
-1o0f,2003-12-09,2003-02-21
-7o0c,2022-02-02,2021-03-26
-5o07,2017-08-02,2017-05-16
-2o07,2006-12-12,2006-11-27
-2o0u,2007-02-27,2006-11-28
-3o0h,2010-08-18,2010-07-19
-3o0r,2010-12-29,2010-07-20
-2o0d,2008-04-08,2006-11-27
-4o0b,2014-04-09,2013-12-13
-4o01,2014-05-07,2013-12-13
-7o0v,2022-03-02,2021-03-27
-5o09,2017-07-19,2017-05-16
-6o0n,2020-02-19,2019-02-16
-7o04,2022-04-13,2021-03-25
-6o0l,2019-05-22,2019-02-16
-2o0o,2007-10-30,2006-11-27
-6o0k,2019-05-22,2019-02-16
-6o0e,2019-07-10,2019-02-16
-7o0p,2021-09-15,2021-03-26
-4o08,2014-10-29,2013-12-13
-3o0w,2010-09-29,2010-07-20
-5o0a,2017-06-28,2017-05-16
-2o03,2007-02-13,2006-11-27
-5o0q,2017-10-18,2017-05-16
-5o0p,2017-10-18,2017-05-16
-2o0w,2007-11-20,2006-11-28
-7o0r,2021-09-15,2021-03-26
-3o0m,2010-08-04,2010-07-19
-6o08,2019-06-26,2019-02-15
-7o0l,2021-09-01,2021-03-26
-1o04,2003-06-24,2003-02-20
-7o0e,2021-09-08,2021-03-26
-5o0f,2017-06-28,2017-05-16
-3o00,2010-11-17,2010-07-18
-4o03,2014-05-21,2013-12-13
-4o0o,2014-01-01,2013-12-14
-5o0k,2017-10-18,2017-05-16
-2o0b,2008-04-08,2006-11-27
-1o0v,2002-09-18,2002-09-06
-4o0s,2014-12-17,2013-12-14
-2o0g,2007-01-30,2006-11-27
-4o0y,2014-02-12,2013-12-14
-2o08,2006-12-19,2006-11-27
-1o06,2003-07-22,2003-02-20
-2o0e,2008-04-08,2006-11-27
-5o0l,2017-10-18,2017-05-16
-7o0w,2022-03-02,2021-03-27
-1o0c,2003-04-15,2003-02-20
-7o0q,2021-09-15,2021-03-26
-5o0y,2018-05-30,2017-05-17
-4o0m,2014-05-14,2013-12-13
-5o0o,2017-10-18,2017-05-16
-3o0q,2010-07-28,2010-07-19
-4o0z,2014-06-18,2013-12-14
-1o02,2003-06-24,2003-02-20
-2o0c,2007-01-30,2006-11-27
-4o07,2014-04-09,2013-12-13
-5o0z,2017-11-15,2017-05-17
-7o08,2021-09-01,2021-03-25
-2o0v,2007-11-20,2006-11-28
-6o0h,2019-04-17,2019-02-16
-4o0u,2014-12-17,2013-12-14
-4o02,2014-04-02,2013-12-13
-4o0e,2014-04-30,2013-12-13
-1o0b,2003-04-15,2003-02-20
-2o01,2007-05-08,2006-11-27
-2o0h,2007-04-03,2006-11-27
-2o09,2007-01-30,2006-11-27
-4o0w,2014-12-17,2013-12-14
-5o0r,2017-11-08,2017-05-16
-1o0t,2003-07-15,2003-02-24
-3o07,2010-11-24,2010-07-19
-7o0u,2022-03-02,2021-03-27
-2o0r,2007-02-27,2006-11-28
-6o0g,2020-02-19,2019-02-16
-4o0r,2014-02-12,2013-12-14
-6o0o,2019-05-22,2019-02-17
-1o08,2003-03-18,2003-02-20
-1o0h,2003-12-09,2003-02-21
-2o02,2007-11-27,2006-11-27
-4o0i,2014-12-17,2013-12-13
-1o0q,2003-07-15,2003-02-24
-5o0b,2017-06-28,2017-05-16
-4o04,2014-12-24,2013-12-13
-7o0y,2022-04-13,2021-03-28
-6o0f,2019-07-10,2019-02-16
-3o0u,2011-03-30,2010-07-20
-2o0l,2006-12-12,2006-11-27
-4o09,2014-04-09,2013-12-13
-5o0s,2017-08-09,2017-05-16
-2o0j,2007-04-03,2006-11-27
-4o0l,2014-08-13,2013-12-13
-4o0a,2014-01-08,2013-12-13
-7o0m,2021-09-15,2021-03-26
-7o0o,2021-10-13,2021-03-26
-4o0d,2014-04-30,2013-12-13
-5o0e,2018-05-30,2017-05-16
-4o0j,2014-07-02,2013-12-13
-5o08,2017-06-28,2017-05-16
-2o0x,2008-04-08,2006-11-28
-5o0c,2017-06-28,2017-05-16
-1o0s,2003-07-22,2003-02-24
-1o05,2003-03-04,2003-02-20
-3o0n,2010-07-28,2010-07-19
-1o07,2003-08-26,2003-02-20
-3o0d,2010-11-24,2010-07-19
-6o0a,2019-03-06,2019-02-15
-3o0v,2010-09-29,2010-07-20
-7o0x,2022-03-02,2021-03-28
-3o0i,2011-10-05,2010-07-19
-4o0t,2014-02-12,2013-12-14
-4o0f,2014-04-30,2013-12-13
-1o0d,2003-10-14,2003-02-21
-2o05,2006-12-12,2006-11-27
-4o0p,2014-05-07,2013-12-14
-1o0r,2003-03-04,2003-02-24
-1o00,2003-06-24,2003-02-20
-3o0j,2011-08-10,2010-07-19
-3o01,2010-11-17,2010-07-18
-4o0h,2014-04-30,2013-12-13
-1o0o,2003-12-09,2003-02-24
-3o0o,2010-07-28,2010-07-19
-7o0d,2022-04-13,2021-03-26
-4o0c,2014-04-30,2013-12-13
-3o02,2010-11-17,2010-07-18
-5o0j,2018-05-30,2017-05-16
-1o01,2003-06-24,2003-02-20
-6o07,2019-06-12,2019-02-15
-1o0a,2003-04-22,2003-02-20
-5o0x,2017-06-28,2017-05-17
-5o0t,2017-06-28,2017-05-17
-3o05,2010-11-24,2010-07-19
-7o0k,2021-05-12,2021-03-26
-3o0g,2011-01-26,2010-07-19
-5o0d,2017-06-28,2017-05-16
-7o0n,2021-09-15,2021-03-26
-4o05,2014-04-09,2013-12-13
-1o03,2003-03-18,2003-02-20
-6o04,2020-02-19,2019-02-15
-6o0q,2019-09-04,2019-02-17
-5o00,2017-05-24,2017-05-15
-6o0w,2019-09-04,2019-02-17
-7o07,2021-10-13,2021-03-25
-3o0x,2010-09-29,2010-07-20
-4z4r,2015-05-27,2015-04-02
-6z4v,2021-02-10,2020-05-25
-2z4t,2008-04-08,2007-06-25
-1z4q,2005-07-26,2005-03-16
-6z4o,2020-09-16,2020-05-25
-1z4z,2005-05-24,2005-03-16
-7z41,2023-01-25,2022-03-03
-6z47,2020-12-09,2020-05-22
-6z45,2020-12-23,2020-05-22
-5z4m,2018-10-31,2018-01-11
-2z4y,2008-07-01,2007-06-26
-5z41,2018-04-25,2018-01-10
-4z4h,2015-09-23,2015-04-02
-1z4l,2005-07-26,2005-03-16
-2z4o,2008-04-22,2007-06-20
-2z48,2007-10-30,2007-06-13
-4z4w,2015-05-27,2015-04-02
-1z44,2005-05-17,2005-03-15
-7z4n,2022-08-24,2022-03-04
-6z4w,2020-09-02,2020-05-26
-6z4s,2021-02-10,2020-05-25
-6z4z,2020-06-03,2020-05-26
-6z4k,2020-09-16,2020-05-25
-6z4m,2020-09-16,2020-05-25
-6z4y,2020-06-03,2020-05-26
-1z4k,2005-07-26,2005-03-16
-4z4y,2015-05-27,2015-04-02
-1z4w,2005-05-24,2005-03-16
-5z43,2018-06-06,2018-01-10
-4z4v,2015-05-27,2015-04-02
-7z4a,2022-08-17,2022-03-03
-6z4j,2020-09-16,2020-05-25
-1z4u,2005-06-07,2005-03-16
-1z42,2005-05-17,2005-03-15
-5z4d,2018-10-31,2018-01-11
-4z4e,2015-09-23,2015-04-02
-7z4d,2022-08-31,2022-03-03
-4z4p,2015-09-09,2015-04-02
-7z4v,2022-04-06,2022-03-04
-1z4o,2005-04-19,2005-03-16
-2z4b,2007-08-07,2007-06-14
-4z41,2015-09-02,2015-04-01
-7z4o,2022-05-11,2022-03-04
-7z43,2022-05-11,2022-03-03
-5z4t,2018-06-20,2018-01-13
-4z4u,2015-05-27,2015-04-02
-5z4f,2019-01-30,2018-01-11
-4z4d,2015-09-23,2015-04-02
-1z4x,2005-05-24,2005-03-16
-1z4r,2005-03-29,2005-03-16
-2z45,2008-06-24,2007-06-12
-1z4v,2005-05-24,2005-03-16
-4z42,2016-04-13,2015-04-01
-4z4q,2016-09-14,2015-04-02
-6z4r,2021-04-28,2020-05-25
-7z4j,2022-08-31,2022-03-03
-4z4g,2015-09-23,2015-04-02
-7z4l,2022-08-31,2022-03-04
-1z41,2005-05-17,2005-03-15
-4z46,2015-05-27,2015-04-01
-6z48,2022-06-01,2020-05-23
-6z4l,2020-09-16,2020-05-25
-4z4m,2016-04-06,2015-04-02
-5z4w,2018-02-14,2018-01-15
-4z49,2016-03-16,2015-04-01
-2z4q,2007-10-30,2007-06-22
-5z49,2018-10-10,2018-01-10
-2z4e,2007-10-23,2007-06-16
-5z4v,2018-02-14,2018-01-15
-7z4x,2023-02-22,2022-03-06
-2z47,2008-06-17,2007-06-13
-7z4q,2022-08-24,2022-03-04
-6z43,2020-06-03,2020-05-22
-4z4z,2015-05-27,2015-04-02
-8z4b,2024-05-22,2024-04-17
-5z4o,2018-12-12,2018-01-12
-4z4i,2015-09-23,2015-04-02
-1z45,2005-04-05,2005-03-15
-4z4s,2015-05-27,2015-04-02
-1z4n,2005-04-19,2005-03-16
-6z4b,2020-11-11,2020-05-25
-5z45,2018-06-06,2018-01-10
-6z42,2020-06-17,2020-05-22
-6z4i,2020-09-16,2020-05-25
-7z4s,2023-03-22,2022-03-04
-5z48,2019-01-16,2018-01-10
-2z4p,2007-09-18,2007-06-21
-7z4m,2022-08-24,2022-03-04
-1z4j,2005-07-26,2005-03-16
-5z46,2018-06-06,2018-01-10
-6z4g,2020-09-16,2020-05-25
-5z4h,2018-12-12,2018-01-11
-5z4a,2018-10-31,2018-01-10
-1z4m,2005-07-26,2005-03-16
-7z4i,2022-08-31,2022-03-03
-2z4w,2008-07-01,2007-06-26
-5z4p,2019-01-16,2018-01-12
-2z4j,2007-12-04,2007-06-19
-2z4s,2008-02-19,2007-06-25
-6z4q,2021-02-10,2020-05-25
-5z4g,2018-04-11,2018-01-11
-7z42,2022-05-18,2022-03-03
-2z4x,2008-07-01,2007-06-26
-6z4n,2021-04-07,2020-05-25
-6z4d,2020-11-11,2020-05-25
-2z4g,2007-11-27,2007-06-17
-5z42,2018-04-25,2018-01-10
-4z44,2016-04-13,2015-04-01
-2z4r,2008-02-19,2007-06-25
-7z4u,2022-03-16,2022-03-04
-4z43,2016-01-20,2015-04-01
-2z4z,2008-07-01,2007-06-26
-4z48,2015-04-22,2015-04-01
-4z4c,2015-09-23,2015-04-02
-1z48,2005-05-17,2005-03-15
-6z4t,2021-04-28,2020-05-25
-5z4j,2018-10-31,2018-01-11
-7z4r,2022-08-24,2022-03-04
-2z4v,2008-07-01,2007-06-26
-5z4u,2019-01-23,2018-01-14
-5z44,2018-06-06,2018-01-10
-4z4t,2015-05-27,2015-04-02
-2z49,2007-10-30,2007-06-13
-1z4y,2005-05-24,2005-03-16
-1z4p,2005-07-26,2005-03-16
-4z4f,2015-09-23,2015-04-02
-1z4i,2005-07-26,2005-03-16
-4z4k,2016-04-06,2015-04-02
-6z4h,2020-09-16,2020-05-25
-6z4x,2020-12-09,2020-05-26
-2glp,2007-03-13,2006-04-05
-5gl2,2016-12-14,2016-07-07
-7gl4,2023-11-08,2023-08-11
-2gls,1989-10-15,1989-05-19
-8gl6,2024-01-31,2023-03-21
-8glo,2024-03-27,2023-03-22
-1gll,1999-05-18,1998-09-24
-6glj,2019-02-20,2018-05-23
-5glm,2017-03-15,2016-07-12
-7glr,2023-11-08,2023-08-11
-3gl9,2009-10-27,2009-03-11
-4gl5,2012-09-12,2012-08-13
-5gly,2017-04-19,2016-07-12
-5glr,2017-03-15,2016-07-12
-6glq,2019-02-20,2018-05-23
-6glc,2018-06-13,2018-05-23
-1glc,1994-05-31,1994-03-07
-1gl1,2001-11-28,2001-08-22
-3gli,2009-05-26,2009-03-12
-7gln,2023-11-08,2023-08-11
-7glh,2023-11-08,2023-08-11
-8glj,2024-01-31,2023-03-22
-7glm,2023-11-08,2023-08-11
-7glo,2023-11-08,2023-08-11
-3glx,2009-06-09,2009-03-12
-8glg,2023-09-20,2023-03-22
-4glo,2012-08-29,2012-08-14
-3glb,2009-05-19,2009-03-11
-7gl2,2023-11-08,2023-08-11
-1glq,1994-05-31,1994-03-07
-3glw,2009-09-15,2009-03-12
-8gli,2023-09-20,2023-03-22
-5glg,2017-07-12,2016-07-11
-6glh,2019-02-20,2018-05-23
-6gl0,2018-10-31,2018-05-22
-3glt,2009-06-16,2009-03-12
-7gl9,2023-11-08,2023-08-11
-6gl1,2018-08-08,2018-05-22
-5gl0,2016-08-24,2016-07-07
-1glb,1993-10-31,1992-10-28
-7gli,2023-11-08,2023-08-11
-4glq,2013-01-16,2012-08-14
-5gll,2017-03-15,2016-07-12
-1gl9,2002-02-11,2001-08-30
-2gli,1993-11-09,1993-11-09
-3gls,2009-06-16,2009-03-12
-3glv,2009-05-12,2009-03-12
-4gl2,2013-01-09,2012-08-13
-5glt,2016-11-09,2016-07-12
-1gl6,2002-05-16,2001-08-28
-5gl1,2016-08-24,2016-07-07
-6gle,2019-02-20,2018-05-23
-6gl3,2018-08-15,2018-05-22
-8gle,2023-09-20,2023-03-22
-7gll,2023-11-08,2023-08-11
-8glp,2023-04-19,2023-03-22
-3glz,2009-07-28,2009-03-12
-4gll,2012-09-05,2012-08-14
-3glu,2009-06-16,2009-03-12
-3gl0,2009-08-04,2009-03-11
-5glb,2017-02-15,2016-07-10
-5glp,2017-03-15,2016-07-12
-8gl0,2023-11-15,2023-03-20
-2glm,2007-03-13,2006-04-05
-6gl8,2018-11-07,2018-05-23
-6glv,2019-02-20,2018-05-23
-5glu,2016-11-09,2016-07-12
-7glq,2023-11-08,2023-08-11
-1gle,1994-05-31,1994-03-07
-3glf,2009-05-26,2009-03-12
-5glq,2017-03-15,2016-07-12
-6gl6,2018-12-26,2018-05-23
-7gl7,2023-11-08,2023-08-11
-8gl4,2023-11-15,2023-03-20
-1glj,1999-05-18,1998-09-03
-7glf,2023-11-08,2023-08-11
-1glp,1994-06-22,1994-03-07
-6gla,2018-06-27,2018-05-23
-3glq,2009-03-24,2009-03-12
-2glq,2006-04-25,2006-04-05
-7glx,2023-11-08,2023-08-11
-2gl0,2006-06-06,2006-04-04
-4gld,2012-08-29,2012-08-14
-4glx,2012-10-10,2012-08-15
-6gls,2019-02-20,2018-05-23
-8glm,2024-01-31,2023-03-22
-4gl9,2013-03-06,2012-08-14
-3glr,2009-06-16,2009-03-12
-2glj,2006-06-13,2006-04-04
-3gl6,2009-05-05,2009-03-11
-7gl6,2023-11-08,2023-08-11
-1glh,1995-02-07,1994-11-25
-7glb,2023-11-08,2023-08-11
-4glj,2013-02-20,2012-08-14
-1gl0,2001-11-28,2001-08-22
-3glj,2009-10-20,2009-03-12
-5gl5,2017-01-11,2016-07-08
-7glc,2023-11-08,2023-08-11
-7gla,2023-11-08,2023-08-11
-7gl0,2023-11-08,2023-08-11
-5glz,2016-11-09,2016-07-12
-7gld,2023-11-08,2023-08-11
-6glb,2018-06-27,2018-05-23
-2glr,1994-07-31,1994-05-04
-6glz,2018-11-07,2018-05-24
-4gly,2013-05-15,2012-08-15
-7glj,2023-11-08,2023-08-11
-2gl5,2006-04-18,2006-04-04
-6gll,2019-02-20,2018-05-23
-3gl5,2009-03-31,2009-03-11
-5gl8,2017-10-25,2016-07-10
-5gl4,2016-12-14,2016-07-08
-7glg,2023-11-08,2023-08-11
-6gly,2018-11-07,2018-05-24
-8glb,2023-06-07,2023-03-21
-3gln,2009-09-22,2009-03-12
-6glp,2019-02-20,2018-05-23
-6glu,2019-02-20,2018-05-23
-8gl8,2024-01-31,2023-03-21
-3glg,2009-05-26,2009-03-12
-7gl3,2023-11-08,2023-08-11
-2glu,2006-04-18,2006-04-05
-1glg,1994-05-31,1993-12-27
-3gl2,2009-08-04,2009-03-11
-5gls,2016-07-27,2016-07-12
-7gls,2023-11-08,2023-08-11
-2gl9,2007-02-13,2006-04-04
-7gle,2023-11-08,2023-08-11
-7gly,2023-11-08,2023-08-11
-3gly,1994-11-01,1994-06-03
-6glg,2019-02-20,2018-05-23
-5gl3,2016-12-14,2016-07-07
-3glc,2009-09-08,2009-03-11
-5gl7,2017-07-12,2016-07-08
-5gln,2017-03-15,2016-07-12
-2gl3,2006-09-19,2006-04-04
-6gln,2019-02-20,2018-05-23
-5glo,2017-03-15,2016-07-12
-7gl1,2023-11-08,2023-08-11
-6glr,2019-02-20,2018-05-23
-1glf,1998-10-16,1998-08-30
-7glp,2023-11-08,2023-08-11
-5gld,2017-02-15,2016-07-10
-6gl9,2018-06-27,2018-05-23
-4glw,2012-10-10,2012-08-15
-1gl3,2001-11-01,2001-08-23
-1glm,1994-06-22,1994-04-25
-1glu,1994-01-31,1992-08-30
-8gly,2024-02-07,2023-03-23
-7glv,2023-11-08,2023-08-11
-1gl7,2002-05-16,2001-08-28
-7glz,2023-11-08,2023-08-11
-1gl4,2001-11-28,2001-08-23
-5glw,2016-11-09,2016-07-12
-1gli,1996-08-01,1996-02-22
-8glf,2023-09-20,2023-03-22
-2glx,2006-08-29,2006-04-05
-7gl5,2023-11-08,2023-08-11
-2glz,2006-04-18,2006-04-05
-7gl8,2023-11-08,2023-08-11
-3glm,2009-07-28,2009-03-12
-8glh,2023-09-20,2023-03-22
-6gl5,2019-06-19,2018-05-23
-2gln,2006-09-19,2006-04-05
-1gld,1994-05-31,1994-03-07
-8gln,2024-01-31,2023-03-22
-2glk,2006-05-16,2006-04-05
-4gl7,2012-09-12,2012-08-13
-7glw,2023-11-08,2023-08-11
-7glt,2023-11-08,2023-08-11
-6gl4,2019-05-15,2018-05-22
-5glk,2017-03-15,2016-07-12
-8glz,2023-12-27,2023-03-23
-6gli,2019-02-20,2018-05-23
-4gl4,2013-02-27,2012-08-13
-2glf,2006-06-13,2006-04-04
-8gla,2023-07-26,2023-03-21
-6glm,2019-02-20,2018-05-23
-7glu,2023-11-08,2023-08-11
-8gl5,2023-11-15,2023-03-20
-4gl1,2013-09-04,2012-08-13
-7glk,2023-11-08,2023-08-11
-4glb,2012-09-05,2012-08-14
-4glt,2012-08-29,2012-08-14
-3gl1,2009-03-24,2009-03-11
-8glk,2024-01-31,2023-03-22
-8gl9,2023-07-26,2023-03-21
-7x6z,2022-08-10,2022-03-08
-4x6s,2015-09-23,2014-12-09
-1x61,2005-11-17,2005-05-17
-5x6i,2018-02-28,2017-02-22
-5x6k,2018-02-28,2017-02-22
-2x6b,2010-06-23,2010-02-15
-5x6a,2018-02-21,2017-02-21
-1x6a,2005-11-17,2005-05-17
-2x6f,2010-04-07,2010-02-17
-8x64,2024-01-17,2023-11-20
-5x6p,2018-02-21,2017-02-22
-7x6v,2023-09-13,2022-03-08
-4x65,2015-11-18,2014-12-06
-2x6n,2010-08-11,2010-02-18
-5x62,2017-07-26,2017-02-20
-2x61,2011-03-02,2010-02-16
-6x68,2020-07-22,2020-05-27
-6x6u,2021-12-15,2020-05-29
-4x6l,2015-02-25,2014-12-08
-5x6m,2017-03-15,2017-02-22
-4x66,2015-11-18,2014-12-06
-2x6s,2010-08-11,2010-02-19
-6x67,2020-07-22,2020-05-27
-7x67,2022-06-01,2022-03-06
-4x6m,2015-02-18,2014-12-08
-1x6m,2004-11-23,2004-08-11
-6x6m,2021-09-01,2020-05-28
-7x68,2022-05-04,2022-03-06
-1x6n,2005-07-26,2004-08-11
-4x60,2015-04-22,2014-12-06
-5x6j,2018-02-28,2017-02-22
-8x6m,2024-03-27,2023-11-21
-7x6r,2022-12-14,2022-03-08
-4x61,2015-04-22,2014-12-06
-5x67,2017-06-28,2017-02-21
-1x68,2005-11-17,2005-05-17
-6x6d,2021-06-02,2020-05-28
-7x64,2022-06-01,2022-03-06
-7x6u,2023-08-16,2022-03-08
-7x6s,2023-09-13,2022-03-08
-2x6a,2010-06-23,2010-02-15
-6x6x,2021-07-28,2020-05-29
-1x6f,2005-11-17,2005-05-17
-4x6t,2015-12-23,2014-12-09
-7x6j,2022-07-06,2022-03-07
-8x6z,2024-01-03,2023-11-22
-6x6g,2021-06-02,2020-05-28
-2x6u,2010-04-28,2010-02-22
-5x6l,2018-02-28,2017-02-22
-8x63,2024-01-17,2023-11-20
-7x6n,2022-06-01,2022-03-07
-4x6n,2015-02-18,2014-12-08
-5x6g,2017-03-15,2017-02-21
-2x6e,2010-07-07,2010-02-17
-5x6h,2017-03-15,2017-02-22
-4x6k,2015-07-22,2014-12-08
-2x6y,2011-03-02,2010-02-22
-2x62,2011-02-23,2010-02-14
-4x63,2015-04-22,2014-12-06
-2x6c,2010-06-23,2010-02-15
-2x6o,2011-03-02,2010-02-18
-2x6w,2011-03-02,2010-02-22
-8x61,2024-05-08,2023-11-20
-4x6o,2015-02-18,2014-12-08
-2x6j,2010-04-07,2010-02-17
-8x6r,2024-01-17,2023-11-21
-5x6t,2017-10-11,2017-02-23
-5x6y,2018-02-28,2017-02-23
-7x6m,2022-06-01,2022-03-07
-2x60,2010-06-23,2010-02-12
-2x6p,2010-09-22,2010-02-18
-7x62,2022-06-01,2022-03-06
-5x69,2017-06-28,2017-02-21
-6x6e,2021-06-02,2020-05-28
-7x6i,2023-04-26,2022-03-07
-4x6a,2015-02-04,2014-12-07
-4x6r,2015-07-22,2014-12-09
-2x6v,2010-04-28,2010-02-22
-6x6z,2020-09-30,2020-05-29
-5x60,2017-04-12,2017-02-20
-2x6t,2010-03-02,2010-02-21
-7x69,2022-06-01,2022-03-06
-2x6k,2010-04-07,2010-02-17
-1x64,2005-11-17,2005-05-17
-7x6t,2023-03-22,2022-03-08
-4x6z,2015-12-23,2014-12-09
-2x64,2010-03-02,2010-02-14
-6x6t,2020-09-02,2020-05-29
-1x6h,2005-11-17,2005-05-17
-6x6q,2021-09-01,2020-05-28
-4x6h,2015-09-23,2014-12-08
-6x6r,2021-10-13,2020-05-29
-6x6h,2020-09-09,2020-05-28
-5x68,2018-02-21,2017-02-21
-1x6e,2005-11-17,2005-05-17
-4x6y,2015-04-08,2014-12-09
-1x62,2005-11-17,2005-05-17
-6x6v,2021-07-28,2020-05-29
-4x64,2015-11-18,2014-12-06
-5x6e,2017-04-12,2017-02-21
-7x6k,2022-07-06,2022-03-07
-5x61,2017-03-15,2017-02-20
-2x66,2010-03-02,2010-02-15
-7x6y,2022-08-10,2022-03-08
-1x6v,2005-03-22,2004-08-12
-2x63,2011-02-23,2010-02-14
-2x6i,2010-04-07,2010-02-17
-4x6x,2015-04-08,2014-12-09
-4x6u,2015-06-10,2014-12-09
-5x66,2017-06-28,2017-02-21
-4x6j,2015-09-09,2014-12-08
-2x68,2010-03-02,2010-02-15
-7x6c,2023-05-24,2022-03-07
-1x63,2005-11-17,2005-05-17
-8x6b,2024-04-24,2023-11-21
-6x6i,2021-06-02,2020-05-28
-6x6y,2021-06-02,2020-05-29
-4x6d,2015-01-28,2014-12-08
-5x6c,2017-12-06,2017-02-21
-7x6w,2023-07-19,2022-03-08
-2x6x,2011-03-02,2010-02-22
-5x6s,2017-08-23,2017-02-23
-4x6i,2015-09-30,2014-12-08
-4x6c,2015-01-28,2014-12-08
-5x6z,2018-02-28,2017-02-23
-1x6u,2005-07-26,2004-08-12
-2x6d,2010-07-07,2010-02-17
-4x62,2015-11-18,2014-12-06
-2x65,2010-06-23,2010-02-15
-4x68,2015-07-01,2014-12-07
-5x6r,2018-02-21,2017-02-23
-5x6v,2017-12-06,2017-02-23
-6x6c,2021-03-10,2020-05-27
-6x6p,2020-06-10,2020-05-28
-7x6f,2023-03-15,2022-03-07
-4x69,2015-07-01,2014-12-07
-4x67,2015-02-04,2014-12-07
-2x6m,2010-06-23,2010-02-18
-4x6p,2015-02-18,2014-12-08
-2x67,2010-03-02,2010-02-15
-5x6q,2018-02-21,2017-02-23
-3sgk,2011-08-03,2011-06-15
-4sgb,1990-07-15,1989-09-21
-1sgf,1998-05-27,1997-08-08
-1sgu,2004-10-05,2004-02-24
-2sge,2003-08-26,1999-03-25
-7sgh,2022-10-05,2021-10-05
-6sgb,2019-09-25,2019-08-03
-7sg1,2022-02-23,2021-10-04
-3sgu,2012-05-02,2011-06-15
-1sgc,1986-07-14,1986-04-18
-8sg9,2023-10-25,2023-04-12
-5sgz,2022-10-12,2022-02-01
-5sgg,2022-10-12,2022-02-01
-3sg2,2012-06-20,2011-06-14
-5sgd,2022-10-12,2022-02-01
-3sgy,2012-03-07,2011-06-15
-5sg3,2022-10-12,2022-02-01
-3sg4,2012-06-20,2011-06-14
-1sg4,2005-01-18,2004-02-23
-8sgc,2023-10-25,2023-04-12
-8sg8,2023-10-25,2023-04-11
-5sg8,2022-10-12,2022-02-01
-1sg0,2005-01-25,2004-02-22
-5sg6,2022-10-12,2022-02-01
-3sgl,2011-07-06,2011-06-15
-7sgf,2022-10-12,2021-10-05
-3sgz,2012-03-07,2011-06-15
-8sgv,2024-02-21,2023-04-13
-3sgj,2011-08-03,2011-06-15
-6sgv,2020-08-26,2019-08-05
-8sge,2024-01-03,2023-04-12
-7sg4,2021-11-10,2021-10-04
-5sg1,2022-10-12,2022-02-01
-8sgu,2023-12-13,2023-04-13
-7sgv,2021-10-20,2021-10-07
-7sgm,2022-02-02,2021-10-06
-3sg6,2012-06-20,2011-06-14
-5sgf,2022-10-12,2022-02-01
-8sgr,2024-02-21,2023-04-13
-5sgl,2022-10-12,2022-02-01
-3sg0,2011-06-29,2011-06-14
-7sgi,2022-10-05,2021-10-05
-6sge,2019-09-25,2019-08-04
-8sg1,2023-11-01,2023-04-11
-6sga,2019-09-18,2019-08-03
-8sgs,2024-02-21,2023-04-13
-5sgn,2022-10-12,2022-02-01
-3sga,1991-10-15,1990-05-29
-3sgt,2012-12-19,2011-06-15
-6sgd,2020-06-17,2019-08-04
-8sg5,2023-10-11,2023-04-11
-6sgl,2020-02-05,2019-08-05
-3sg7,2012-06-20,2011-06-14
-6sg2,2020-07-08,2019-08-02
-7sgs,2022-05-18,2021-10-07
-5sg7,2022-10-12,2022-02-01
-5sgi,2022-10-19,2022-02-01
-8sgx,2023-05-17,2023-04-13
-5sgv,2022-10-12,2022-02-01
-7sgl,2022-01-12,2021-10-06
-8sgb,2024-04-24,2023-04-12
-8sga,2024-04-17,2023-04-12
-5sgw,2022-10-12,2022-02-01
-8sgd,2023-06-28,2023-04-12
-5sga,1991-10-15,1990-05-29
-5sgr,2022-10-12,2022-02-01
-6sgh,2020-06-17,2019-08-04
-8sgq,2023-11-01,2023-04-12
-1sgi,2004-06-08,2004-02-23
-6sgg,2020-02-05,2019-08-04
-1sg6,2004-08-31,2004-02-23
-8sg0,2024-03-13,2023-04-11
-6sg8,2019-10-09,2019-08-02
-5sg5,2022-10-12,2022-02-01
-8sgn,2024-04-17,2023-04-12
-8sgp,2024-02-21,2023-04-12
-7sgj,2022-10-05,2021-10-05
-8sgt,2023-10-11,2023-04-13
-3sgi,2012-06-20,2011-06-15
-7sg0,2022-02-23,2021-10-04
-5sgh,2022-10-12,2022-02-01
-7sgx,2022-10-26,2021-10-07
-6sgk,2020-06-17,2019-08-05
-6sg9,2019-09-18,2019-08-03
-4sga,1991-10-15,1990-05-29
-5sgs,2022-10-12,2022-02-01
-3sgx,2012-12-19,2011-06-15
-5sgq,2022-10-12,2022-02-01
-6sgc,2019-12-04,2019-08-03
-8sgl,2023-10-25,2023-04-12
-3sg9,2011-06-29,2011-06-14
-3sge,2011-11-09,2011-06-14
-2sgd,2003-08-26,1999-03-25
-6sgf,2019-11-20,2019-08-04
-1sg8,2004-06-08,2004-02-23
-6sgm,2020-02-05,2019-08-05
-1sgw,2004-08-10,2004-02-24
-1sgt,1988-07-16,1988-04-13
-1sgj,2004-08-17,2004-02-23
-8sgi,2024-04-24,2023-04-12
-5sgx,2022-10-12,2022-02-01
-5sg0,2022-10-12,2022-02-01
-8sgj,2023-10-11,2023-04-12
-7sgg,2022-10-05,2021-10-05
-3sg8,2011-06-29,2011-06-14
-7sgw,2021-10-20,2021-10-07
-8sgk,2024-05-22,2023-04-12
-5sge,2022-10-12,2022-02-01
-1sg9,2004-08-17,2004-02-23
-6sg0,2020-08-26,2019-08-02
-5sgk,2022-10-12,2022-02-01
-3sg5,2012-06-20,2011-06-14
-5sgp,2022-10-12,2022-02-01
-7sgd,2022-10-12,2021-10-05
-5sgc,2022-10-12,2022-02-01
-5sgo,2022-10-12,2022-02-01
-7sgz,2022-03-23,2021-10-07
-5sgb,2022-10-12,2022-02-01
-6sg6,2020-08-26,2019-08-02
-8sgy,2023-05-17,2023-04-13
-8sgo,2023-08-30,2023-04-12
-7sgu,2021-10-20,2021-10-07
-7sgc,2021-10-13,2021-10-05
-8sgw,2024-02-07,2023-04-13
-5sgm,2022-10-12,2022-02-01
-5sg4,2022-10-12,2022-02-01
-6sgn,2020-02-05,2019-08-05
-5sgt,2022-10-12,2022-02-01
-5sg2,2022-10-12,2022-02-01
-5sg9,2022-10-12,2022-02-01
-3sgv,2012-12-19,2011-06-15
-7sgk,2022-10-05,2021-10-05
-5sgy,2022-10-12,2022-02-01
-5sgj,2022-10-12,2022-02-01
-3sgd,2011-11-09,2011-06-14
-8sgf,2024-01-03,2023-04-12
-6sgp,2020-08-26,2019-08-05
-6sgi,2020-06-17,2019-08-05
-3sg3,2012-06-20,2011-06-14
-5sgu,2022-10-12,2022-02-01
-7sg2,2022-02-23,2021-10-04
-8sgz,2023-05-17,2023-04-13
-5ut8,2018-02-28,2017-02-14
-3ut6,2012-05-23,2011-11-25
-1utp,2004-01-15,2003-12-09
-4utg,2016-01-13,2014-07-21
-6utk,2020-09-23,2019-10-29
-3utb,2012-04-11,2011-11-25
-8utb,2024-02-21,2023-10-30
-1ut7,2004-03-19,2003-12-04
-1utq,2004-01-15,2003-12-09
-1ut6,2005-04-21,2003-12-04
-3utu,2012-08-29,2011-11-26
-4utr,2014-08-20,2014-07-22
-5ut5,2017-06-07,2017-02-14
-1ut5,2004-02-05,2003-12-04
-5utq,2017-04-19,2017-02-15
-3utd,2012-09-05,2011-11-25
-1ute,1999-10-01,1999-01-18
-1utr,1995-12-07,1995-09-01
-6utq,2019-11-06,2019-10-29
-5uta,2018-02-28,2017-02-14
-5utu,2017-03-01,2017-02-15
-4utz,2014-08-20,2014-07-24
-1uto,2004-01-15,2003-12-09
-3ut2,2012-07-25,2011-11-24
-7ut5,2022-12-28,2022-04-26
-6ut6,2020-10-21,2019-10-29
-7utl,2022-09-21,2022-04-27
-3utg,2012-02-08,2011-11-25
-5ut3,2017-06-07,2017-02-14
-4utb,2015-01-28,2014-07-18
-5utr,2017-04-19,2017-02-15
-4utf,2014-12-24,2014-07-21
-6utu,2020-09-02,2019-10-30
-7utz,2022-08-03,2022-04-28
-5ut7,2018-02-28,2017-02-14
-1ut8,2004-02-05,2003-12-04
-6utw,2020-08-26,2019-10-30
-8utl,2024-02-14,2023-10-31
-8utx,2024-06-05,2023-10-31
-5uti,2018-03-07,2017-02-15
-8ut9,2024-05-08,2023-10-30
-6utb,2020-10-07,2019-10-29
-5ut9,2018-02-28,2017-02-14
-4utv,2014-08-20,2014-07-23
-5uty,2017-03-29,2017-02-15
-7utj,2023-03-08,2022-04-27
-3ut1,2011-12-28,2011-11-24
-5utn,2017-03-29,2017-02-15
-6uto,2019-12-11,2019-10-29
-6ut8,2020-10-21,2019-10-29
-4ut0,2014-12-17,2014-07-17
-6uty,2020-08-26,2019-10-30
-8ut3,2024-05-08,2023-10-30
-3uta,2012-04-11,2011-11-25
-6utn,2019-12-11,2019-10-29
-5ute,2017-03-15,2017-02-14
-5utj,2018-03-07,2017-02-15
-4ut6,2015-01-28,2014-07-18
-4utk,2015-08-05,2014-07-21
-1utt,2004-12-15,2003-12-10
-8ut5,2024-05-08,2023-10-30
-4utu,2014-10-15,2014-07-23
-7utt,2023-05-03,2022-04-27
-5utc,2018-02-28,2017-02-14
-1utn,2004-01-09,2003-12-09
-6utm,2019-12-11,2019-10-29
-5utm,2018-02-28,2017-02-15
-5ut2,2017-06-07,2017-02-14
-5utf,2017-03-29,2017-02-14
-6ut3,2020-10-21,2019-10-29
-7utd,2023-01-04,2022-04-26
-1utx,2004-09-16,2003-12-12
-8ute,2024-03-06,2023-10-31
-4utx,2014-08-20,2014-07-23
-3utv,2012-05-09,2011-11-26
-4uta,2015-01-28,2014-07-18
-8ut7,2024-05-08,2023-10-30
-7ut1,2022-08-24,2022-04-26
-3utx,2012-05-09,2011-11-27
-4ut9,2015-01-28,2014-07-18
-4ut3,2015-07-22,2014-07-17
-6ut5,2020-10-21,2019-10-29
-5utb,2018-02-28,2017-02-14
-7utc,2022-05-04,2022-04-26
-1ut0,2004-06-01,2003-12-02
-6utr,2019-11-06,2019-10-29
-5utp,2017-04-19,2017-02-15
-7utb,2022-12-14,2022-04-26
-5ut6,2017-06-07,2017-02-14
-7ute,2022-05-25,2022-04-26
-5ut1,2017-06-07,2017-02-14
-6ut1,2020-10-07,2019-10-29
-4utj,2015-08-05,2014-07-21
-6utt,2019-11-06,2019-10-29
-4utp,2014-08-13,2014-07-22
-6ut4,2020-10-21,2019-10-29
-1utc,2004-02-25,2003-12-08
-6utx,2020-08-26,2019-10-30
-1utl,2004-01-15,2003-12-09
-6uts,2019-11-06,2019-10-29
-1utz,2004-12-15,2003-12-12
-4uth,2015-08-05,2014-07-21
-3utf,2012-02-08,2011-11-25
-3uth,2012-02-08,2011-11-25
-4uto,2015-03-11,2014-07-22
-5utd,2018-02-28,2017-02-14
-1utm,2004-01-09,2003-12-09
-3utw,2012-05-09,2011-11-27
-4uti,2015-08-05,2014-07-21
-6utp,2019-11-06,2019-10-29
-1utk,2004-01-29,2003-12-09
-4utl,2015-08-05,2014-07-21
-3ut3,2013-02-06,2011-11-25
-4utn,2014-08-20,2014-07-21
-4utc,2015-01-28,2014-07-18
-4utm,2015-08-05,2014-07-21
-8ut6,2024-05-08,2023-10-30
-6ut7,2020-10-21,2019-10-29
-3ut9,2012-04-11,2011-11-25
-5utl,2018-03-07,2017-02-15
-3utc,2012-09-05,2011-11-25
-7utw,2023-02-01,2022-04-27
-4ut5,2015-07-22,2014-07-18
-7uty,2022-08-24,2022-04-28
-7uti,2022-09-21,2022-04-27
-1utj,2004-01-15,2003-12-09
-8ut4,2024-05-08,2023-10-30
-5ut4,2017-06-07,2017-02-14
-5ut0,2017-06-07,2017-02-14
-3ute,2012-02-08,2011-11-25
-3uty,2012-05-09,2011-11-27
-8ut8,2024-05-08,2023-10-30
-6utd,2020-10-07,2019-10-29
-1utd,2004-01-15,2003-12-08
-6utz,2020-08-26,2019-10-30
-7ut3,2022-09-21,2022-04-26
-3ut0,2011-12-21,2011-11-24
-3ut5,2012-08-01,2011-11-25
-4ut4,2016-01-13,2014-07-18
-4ut2,2015-07-22,2014-07-17
-5uth,2017-03-08,2017-02-15
-6utv,2020-08-26,2019-10-30
-8ut1,2024-02-21,2023-10-30
-6ut0,2020-04-22,2019-10-29
-4utw,2014-10-15,2014-07-23
-6z7l,2020-07-29,2020-05-31
-2z70,2008-06-24,2007-08-09
-7z79,2022-04-13,2022-03-15
-5z7j,2018-05-02,2018-01-29
-6z7u,2020-10-21,2020-06-01
-4z7g,2015-05-27,2015-04-07
-7z7t,2022-09-21,2022-03-16
-6z7e,2021-03-17,2020-05-30
-5z7o,2018-09-26,2018-01-30
-5z7y,2018-08-29,2018-01-30
-6z7z,2020-12-30,2020-06-02
-5z7x,2018-08-29,2018-01-30
-6z74,2020-12-02,2020-05-29
-6z7g,2020-07-29,2020-05-30
-5z7p,2018-09-26,2018-01-30
-6z7a,2021-05-26,2020-05-30
-5z75,2018-08-22,2018-01-27
-6z7o,2020-10-21,2020-05-31
-6z7p,2020-07-15,2020-06-01
-6z7d,2021-03-17,2020-05-30
-6z7b,2021-03-24,2020-05-30
-7z7b,2022-06-22,2022-03-15
-6z7t,2020-10-21,2020-06-01
-2z7j,2008-02-05,2007-08-23
-5z7m,2018-09-26,2018-01-30
-4z72,2015-08-26,2015-04-06
-1z7s,2005-08-02,2005-03-28
-2z71,2008-08-26,2007-08-10
-2z73,2008-05-13,2007-08-13
-7z7f,2022-03-23,2022-03-15
-4z70,2015-08-26,2015-04-06
-7z7x,2022-07-13,2022-03-16
-2z7c,2008-08-05,2007-08-17
-5z79,2018-08-29,2018-01-27
-2z7u,2008-09-02,2007-08-28
-4z7x,2015-04-22,2015-04-08
-5z7b,2018-08-29,2018-01-28
-2z7l,2008-08-12,2007-08-27
-7z77,2022-09-14,2022-03-15
-7z70,2022-06-22,2022-03-14
-7z75,2022-08-31,2022-03-15
-1z7z,2005-08-02,2005-03-28
-1z7n,2005-08-09,2005-03-25
-1z7k,2005-04-05,2005-03-25
-7z7e,2022-06-29,2022-03-15
-7z7v,2022-09-21,2022-03-16
-6z7f,2020-07-29,2020-05-30
-2z7i,2008-07-08,2007-08-23
-4z7h,2015-05-27,2015-04-07
-6z79,2021-03-17,2020-05-30
-7z74,2022-08-31,2022-03-15
-6z7c,2021-03-17,2020-05-30
-4z76,2015-06-24,2015-04-06
-7z7s,2022-09-21,2022-03-16
-6z7r,2020-09-09,2020-06-01
-4z7v,2015-06-03,2015-04-08
-4z7m,2016-04-13,2015-04-07
-1z76,2006-03-21,2005-03-24
-2z7b,2007-11-13,2007-08-17
-2z7g,2008-07-01,2007-08-20
-4z79,2015-10-21,2015-04-06
-5z72,2018-02-28,2018-01-26
-2z7x,2007-10-02,2007-08-29
-4z7j,2016-04-13,2015-04-07
-7z71,2022-07-06,2022-03-14
-7z7c,2023-03-29,2022-03-15
-1z7y,2005-09-20,2005-03-28
-1z7e,2005-06-07,2005-03-24
-6z7v,2021-06-09,2020-06-01
-6z72,2020-12-02,2020-05-29
-1z72,2005-05-17,2005-03-23
-4z7u,2015-06-03,2015-04-08
-2z7y,2008-09-02,2007-08-30
-4z73,2015-08-26,2015-04-06
-6z7n,2021-02-10,2020-05-31
-2z7s,2008-05-13,2007-08-28
-7z7h,2022-06-29,2022-03-15
-2z77,2007-09-18,2007-08-16
-7z76,2022-09-14,2022-03-15
-5z7f,2019-01-30,2018-01-28
-2z7f,2008-08-26,2007-08-20
-7z78,2022-09-14,2022-03-15
-4z7c,2015-09-16,2015-04-07
-5z7w,2018-08-29,2018-01-30
-2z7h,2008-05-06,2007-08-23
-8z77,2024-05-08,2024-04-19
-2z7k,2008-08-26,2007-08-24
-1z71,2005-05-17,2005-03-23
-6z7k,2021-06-09,2020-05-31
-4z71,2015-08-26,2015-04-06
-5z7n,2018-09-26,2018-01-30
-6z7m,2020-07-29,2020-05-31
-1z7w,2005-09-20,2005-03-28
-2z7r,2008-05-13,2007-08-28
-2z7q,2008-05-13,2007-08-28
-5z7e,2019-01-30,2018-01-28
-7z7d,2022-04-27,2022-03-15
-1z70,2005-07-22,2005-03-23
-5z74,2018-05-30,2018-01-27
-4z7r,2016-04-20,2015-04-07
-4z7o,2016-01-27,2015-04-07
-4z7n,2015-12-16,2015-04-07
-4z74,2015-08-26,2015-04-06
-1z7h,2005-05-10,2005-03-24
-2z7w,2008-09-02,2007-08-29
-4z7q,2015-12-16,2015-04-07
-7z7r,2022-09-21,2022-03-16
-4z7f,2015-07-29,2015-04-07
-2z78,2008-07-08,2007-08-16
-8z75,2024-05-08,2024-04-19
-7z7i,2022-06-29,2022-03-15
-4z7i,2015-08-26,2015-04-07
-2z7z,2008-09-02,2007-08-30
-2z72,2008-07-29,2007-08-10
-1z7j,2005-06-07,2005-03-25
-4z77,2015-06-24,2015-04-06
-8z76,2024-05-08,2024-04-19
-4z7w,2015-06-03,2015-04-08
-4x3q,2015-11-25,2014-12-01
-2x3k,2010-11-10,2010-01-25
-5x3k,2018-02-07,2017-02-06
-1x3m,2005-09-27,2005-05-09
-6x39,2021-05-26,2020-05-21
-1x3f,2005-08-15,2005-05-05
-3x3m,2015-12-09,2015-01-24
-5x3j,2018-02-07,2017-02-06
-4x3t,2015-03-04,2014-12-01
-1x3w,2005-06-14,2005-05-11
-4x32,2015-02-18,2014-11-27
-4x31,2015-02-18,2014-11-27
-1x35,2005-10-18,2005-04-29
-4x3p,2016-01-13,2014-12-01
-3x3y,2015-08-19,2015-03-10
-4x3i,2015-06-03,2014-11-30
-6x3m,2021-06-09,2020-05-21
-3x3n,2015-12-09,2015-01-24
-3x34,2015-07-15,2015-01-14
-4x3r,2015-10-14,2014-12-01
-2x3u,2010-05-26,2010-01-27
-8x39,2024-04-03,2023-11-12
-2x3c,2011-02-02,2010-01-22
-7x36,2023-04-05,2022-02-28
-7x3p,2023-09-06,2022-03-01
-3x3g,2015-12-23,2015-01-20
-4x36,2015-05-27,2014-11-28
-1x3c,2005-11-02,2005-05-02
-7x3t,2023-09-20,2022-03-01
-6x3w,2020-09-09,2020-05-21
-2x3a,2011-02-02,2010-01-22
-6x38,2021-05-26,2020-05-21
-4x3b,2015-06-10,2014-11-28
-3x36,2016-01-20,2015-01-16
-6x3k,2021-05-26,2020-05-21
-7x3l,2023-03-08,2022-03-01
-2x38,2010-02-02,2010-01-22
-6x3r,2020-06-24,2020-05-21
-3x3c,2015-04-08,2015-01-18
-1x3e,2005-08-15,2005-05-04
-6x37,2021-05-26,2020-05-21
-2x3y,2010-05-19,2010-01-28
-8x38,2024-01-24,2023-11-12
-7x3w,2023-09-20,2022-03-01
-6x3v,2020-09-09,2020-05-21
-7x3m,2023-03-08,2022-03-01
-3x3x,2015-08-19,2015-03-10
-4x33,2015-01-21,2014-11-27
-2x3n,2010-07-21,2010-01-25
-5x3c,2017-05-31,2017-02-04
-5x31,2017-04-12,2017-02-03
-4x3l,2016-01-20,2014-12-01
-1x3n,2005-09-27,2005-05-10
-7x3j,2023-06-07,2022-03-01
-4x3z,2014-12-10,2014-12-02
-2x39,2010-02-23,2010-01-22
-7x3u,2023-06-07,2022-03-01
-6x3d,2021-05-26,2020-05-21
-5x37,2017-05-31,2017-02-04
-2x3l,2010-07-21,2010-01-25
-1x3g,2005-08-15,2005-05-05
-1x3k,2005-05-24,2005-05-09
-4x3o,2016-01-13,2014-12-01
-6x32,2021-01-13,2020-05-21
-1x3x,2006-06-06,2005-05-11
-1x36,2005-10-18,2005-04-29
-4x3c,2015-12-23,2014-11-28
-1x33,2005-10-18,2005-04-29
-6x3q,2021-11-17,2020-05-21
-7x3x,2023-09-20,2022-03-01
-4x30,2015-12-02,2014-11-27
-5x30,2017-04-12,2017-02-02
-4x3g,2014-12-31,2014-11-28
-5x3s,2017-12-20,2017-02-07
-2x3t,2010-06-30,2010-01-26
-4x34,2015-03-04,2014-11-27
-6x3t,2020-09-09,2020-05-21
-2x3f,2010-07-21,2010-01-24
-5x3d,2017-09-13,2017-02-04
-5x39,2017-05-31,2017-02-04
-2x34,2010-03-23,2010-01-19
-6x3n,2020-07-22,2020-05-21
-6x3x,2020-09-09,2020-05-21
-3x39,2015-04-22,2015-01-16
-2x3j,2011-01-19,2010-01-25
-7x3z,2023-01-25,2022-03-01
-5x33,2018-01-03,2017-02-03
-6x34,2021-01-13,2020-05-21
-8x37,2024-02-07,2023-11-12
-6x35,2021-01-13,2020-05-21
-6x3j,2020-11-18,2020-05-21
-6x3u,2020-09-09,2020-05-21
-5x3z,2017-12-13,2017-02-09
-8x3h,2023-12-13,2023-11-13
-8x36,2024-02-07,2023-11-12
-4x3s,2015-03-04,2014-12-01
-5x36,2017-05-31,2017-02-04
-3x33,2015-07-15,2015-01-14
-1x31,2005-07-05,2005-04-27
-8x35,2024-02-07,2023-11-12
-1x3h,2005-11-09,2005-05-09
-7x32,2022-10-12,2022-02-27
-6x3i,2020-09-23,2020-05-21
-5x3t,2017-06-07,2017-02-07
-3x3b,2015-04-08,2015-01-18
-4x3e,2015-01-21,2014-11-28
-3x3f,2015-12-23,2015-01-20
-6x3y,2020-06-24,2020-05-21
-6x3l,2020-08-12,2020-05-21
-4x3h,2015-06-03,2014-11-30
-6x3e,2021-03-17,2020-05-21
-1x39,2005-12-20,2005-05-02
-6x3o,2020-07-22,2020-05-21
-4x3j,2014-12-24,2014-11-30
-4x3k,2015-03-04,2014-12-01
-8x3r,2024-05-29,2023-11-14
-3x35,2015-07-15,2015-01-14
-8x3a,2024-04-03,2023-11-12
-6x3c,2020-11-18,2020-05-21
-4x35,2015-06-10,2014-11-27
-5x3r,2018-01-24,2017-02-07
-5x35,2017-05-31,2017-02-04
-6x3s,2020-09-09,2020-05-21
-6x3p,2020-07-22,2020-05-21
-6x3z,2020-09-09,2020-05-21
-3x31,2016-01-13,2015-01-13
-3x30,2016-02-17,2015-01-07
-6x33,2021-01-13,2020-05-21
-2x32,2010-03-23,2010-01-19
-3x32,2015-07-15,2015-01-14
-1x3z,2005-06-14,2005-05-11
-4x3n,2015-09-16,2014-12-01
-4x3u,2015-03-04,2014-12-01
-2x3b,2011-02-02,2010-01-22
-5x38,2017-05-31,2017-02-04
-3x3z,2015-08-19,2015-03-10
-1x38,2005-12-20,2005-05-02
-8x3s,2024-05-29,2023-11-14
-1x3s,2005-11-10,2005-05-10
-6x3b,2021-05-26,2020-05-21
-4x3m,2015-11-11,2014-12-01
-7x3o,2023-03-08,2022-03-01
-4x3v,2015-11-11,2014-12-01
-7qgs,2022-05-11,2021-12-10
-3qgo,2012-01-04,2011-01-24
-1qgj,2000-03-08,1999-04-29
-1qgd,2003-06-17,1999-04-23
-1qg4,1999-06-11,1999-04-20
-5qgk,2019-03-27,2018-05-15
-1qgl,1999-05-20,1999-04-30
-5qga,2018-10-10,2018-08-30
-3qgk,2011-08-10,2011-01-24
-3qgy,2011-06-22,2011-01-25
-1qga,1999-04-27,1999-04-18
-3qge,2011-04-20,2011-01-24
-7qg4,2022-10-12,2021-12-07
-2qg4,2007-07-10,2007-06-28
-5qg2,2018-10-10,2018-08-30
-7qgk,2022-03-23,2021-12-08
-7qgt,2022-10-19,2021-12-10
-1qgu,1999-11-01,1999-05-06
-6qgi,2019-02-27,2019-01-11
-6qgr,2019-10-23,2019-01-12
-7qgi,2022-01-26,2021-12-08
-7qg5,2022-05-04,2021-12-07
-4qg8,2015-02-25,2014-05-22
-5qgh,2019-03-27,2018-05-15
-3qga,2011-08-10,2011-01-24
-4qgf,2014-06-11,2014-05-22
-4qgn,2015-05-27,2014-05-23
-3qgi,2011-04-20,2011-01-24
-2qgy,2007-07-24,2007-06-29
-3qgg,2011-04-20,2011-01-24
-5qgp,2019-03-27,2018-05-15
-4qgr,2014-06-18,2014-05-23
-4qgt,2015-04-08,2014-05-25
-4qgz,2014-07-30,2014-05-26
-2qgh,2008-05-27,2007-06-28
-2qga,2007-07-24,2007-06-28
-5qg6,2018-10-10,2018-08-30
-3qg9,2011-03-23,2011-01-24
-7qgz,2022-05-04,2021-12-10
-1qge,1999-05-06,1999-04-27
-7qgl,2022-02-16,2021-12-08
-4qgi,2014-07-16,2014-05-22
-7qgw,2022-12-21,2021-12-10
-4qga,2014-06-11,2014-05-22
-3qg2,2011-06-29,2011-01-24
-6qgf,2019-01-23,2019-01-11
-4qgc,2015-02-25,2014-05-22
-7qgd,2022-10-19,2021-12-08
-2qgw,2008-03-18,2007-06-29
-5qgr,2019-03-27,2018-05-15
-7qgm,2022-02-16,2021-12-08
-5qgv,2019-03-27,2018-05-15
-5qgy,2019-03-27,2018-05-15
-4qgl,2014-06-18,2014-05-23
-5qg5,2018-10-10,2018-08-30
-1qgh,2000-01-14,1999-04-27
-3qgn,2011-07-06,2011-01-24
-2qgi,2008-01-22,2007-06-29
-1qgy,2004-03-09,1999-05-10
-7qgc,2022-09-28,2021-12-08
-2qg8,2007-07-24,2007-06-28
-7qga,2022-02-16,2021-12-07
-4qg6,2015-02-25,2014-05-22
-7qg1,2022-05-04,2021-12-07
-5qgu,2019-03-27,2018-05-15
-4qgm,2014-06-18,2014-05-23
-3qgp,2011-07-20,2011-01-24
-4qg0,2014-10-15,2014-05-22
-5qg8,2018-10-10,2018-08-30
-2qgf,2008-02-19,2007-06-28
-4qg7,2014-06-11,2014-05-22
-6qg7,2019-05-22,2019-01-10
-7qgy,2022-05-04,2021-12-10
-5qgd,2018-10-10,2018-08-30
-3qgw,2011-06-22,2011-01-25
-5qgb,2018-10-10,2018-08-30
-6qga,2019-04-03,2019-01-10
-5qg7,2018-10-10,2018-08-30
-1qg8,2000-04-21,1999-04-21
-4qgp,2014-07-02,2014-05-23
-4qg5,2015-05-27,2014-05-22
-4qgd,2014-06-18,2014-05-22
-5qg1,2018-10-10,2018-08-30
-5qgf,2018-10-10,2018-08-30
-6qgd,2019-06-12,2019-01-11
-4qgh,2014-06-11,2014-05-22
-3qgl,2011-03-16,2011-01-24
-7qgx,2022-05-04,2021-12-10
-6qg9,2019-04-03,2019-01-10
-7qgo,2022-02-16,2021-12-09
-5qg0,2018-10-10,2018-08-30
-4qg1,2014-10-15,2014-05-22
-2qg9,2008-02-19,2007-06-28
-7qg3,2022-05-04,2021-12-07
-4qgg,2014-06-11,2014-05-22
-6qgt,2019-10-23,2019-01-12
-5qgn,2019-03-27,2018-05-15
-6qgj,2019-06-12,2019-01-11
-5qgc,2018-10-10,2018-08-30
-8qg1,2024-04-03,2023-09-05
-3qgd,2011-04-20,2011-01-24
-1qgi,1999-10-25,1999-04-28
-6qgv,2020-02-05,2019-01-13
-1qg2,1999-06-11,1999-04-20
-1qgf,1999-12-29,1999-04-27
-4qgv,2015-01-28,2014-05-25
-3qgj,2012-02-01,2011-01-24
-6qgu,2020-02-05,2019-01-13
-5qgx,2019-03-27,2018-05-15
-5qg3,2018-10-10,2018-08-30
-2qgs,2007-07-17,2007-06-29
-1qgx,2000-01-04,1999-05-10
-2qg2,2008-07-01,2007-06-28
-5qgq,2019-03-27,2018-05-15
-6qgg,2019-06-12,2019-01-11
-2qg6,2007-10-02,2007-06-28
-3qg7,2011-03-23,2011-01-24
-5qgt,2019-03-27,2018-05-15
-7qg7,2021-12-15,2021-12-07
-5qgz,2019-03-27,2018-05-15
-7qgj,2022-02-09,2021-12-08
-2qgd,2008-02-05,2007-06-28
-5qg4,2018-10-10,2018-08-30
-5qgi,2019-03-27,2018-05-15
-5qgg,2019-03-27,2018-05-15
-1qgw,1999-05-19,1999-05-10
-2qgg,2007-07-17,2007-06-28
-4qge,2014-12-10,2014-05-22
-1qg0,1999-04-27,1999-04-18
-1qgs,2000-05-04,1999-05-04
-3qgf,2011-04-20,2011-01-24
-3qgh,2011-04-20,2011-01-24
-4qgs,2015-05-06,2014-05-24
-5qgo,2019-03-27,2018-05-15
-4qg4,2014-10-15,2014-05-22
-3qg6,2011-03-23,2011-01-24
-5qgl,2019-03-27,2018-05-15
-4qg9,2015-02-25,2014-05-22
-3qgz,2011-02-16,2011-01-25
-3qgc,2011-03-23,2011-01-24
-5qgw,2019-03-27,2018-05-15
-4qgw,2015-01-28,2014-05-26
-4qgx,2015-01-28,2014-05-26
-6qgh,2019-06-12,2019-01-11
-3qgt,2011-06-29,2011-01-24
-1qgn,1999-08-25,1999-05-02
-2qgc,2008-02-05,2007-06-28
-3qgv,2012-02-01,2011-01-25
-7qgg,2022-10-26,2021-12-08
-7qgb,2022-10-19,2021-12-08
-1qgz,2002-02-27,1999-05-10
-6qgp,2020-02-05,2019-01-12
-5qg9,2018-10-10,2018-08-30
-3qgb,2011-03-23,2011-01-24
-3qg0,2011-09-21,2011-01-24
-6qg4,2019-05-22,2019-01-10
-8qgw,2024-04-03,2023-09-06
-5qge,2018-10-10,2018-08-30
-2qge,2008-02-05,2007-06-28
-7qg2,2022-05-04,2021-12-07
-2qg0,2008-07-01,2007-06-28
-6qge,2019-01-23,2019-01-11
-3qgm,2011-02-09,2011-01-24
-6qgk,2019-06-12,2019-01-11
-6qgb,2019-04-03,2019-01-10
-7qgp,2022-01-26,2021-12-09
-5qgm,2019-03-27,2018-05-15
-5qgj,2019-03-27,2018-05-15
-4qg2,2014-10-15,2014-05-22
-7qge,2022-10-19,2021-12-08
-5qgs,2019-03-27,2018-05-15
-1qgq,2000-05-04,1999-05-04
-1qg6,1999-09-21,1999-04-20
-2qgt,2008-03-18,2007-06-29
-2gg5,2006-06-13,2006-03-23
-7gg2,2023-11-08,2023-08-11
-5ggc,2017-04-19,2016-06-15
-3ggu,2009-08-11,2009-03-02
-7ggi,2023-11-08,2023-08-11
-7ggf,2023-11-08,2023-08-11
-1ggj,2000-08-30,2000-08-21
-6ggv,2018-06-13,2018-05-04
-7ggh,2023-11-08,2023-08-11
-8gg0,2024-03-06,2023-03-08
-2ggc,2006-06-13,2006-03-23
-8ggc,2024-03-06,2023-03-08
-7gge,2023-11-08,2023-08-11
-4gg2,2013-09-25,2012-08-04
-8gg6,2024-03-06,2023-03-08
-2gg0,2006-06-13,2006-03-23
-6ggo,2018-08-29,2018-05-03
-1gg2,1997-02-12,1996-11-13
-6ggk,2018-10-10,2018-05-03
-7ggw,2023-11-08,2023-08-11
-3ggd,2009-03-31,2009-02-27
-2ggq,2007-03-24,2006-03-24
-7ggu,2023-11-08,2023-08-11
-1ggn,2000-09-13,2000-08-29
-6ggc,2019-05-22,2018-05-03
-3gg0,2009-06-23,2009-02-27
-6ggh,2019-05-22,2018-05-03
-7gg7,2023-11-08,2023-08-11
-1ggq,2001-03-14,2000-09-14
-2ggu,2006-05-02,2006-03-24
-5ggm,2016-09-28,2016-06-16
-6gg8,2019-01-09,2018-05-03
-8ggx,2024-03-06,2023-03-08
-4ggk,2012-10-10,2012-08-06
-7ggv,2023-11-08,2023-08-11
-1ggy,1999-02-16,1998-07-23
-6gg7,2019-05-08,2018-05-02
-5ggz,2017-03-08,2016-06-16
-1ggd,2000-09-20,2000-08-14
-6ggg,2019-01-09,2018-05-03
-7ggs,2023-11-08,2023-08-11
-1ggh,2000-08-30,2000-08-21
-3ggg,2009-03-10,2009-02-27
-6gg3,2019-09-04,2018-05-02
-5ggb,2017-04-19,2016-06-15
-4gg9,2013-09-04,2012-08-06
-3ggs,2009-04-14,2009-03-02
-3ggw,2009-03-31,2009-03-02
-2ggm,2006-04-25,2006-03-24
-2ggx,2006-05-02,2006-03-24
-7gga,2023-11-08,2023-08-11
-8ggq,2024-03-06,2023-03-08
-6ggn,2018-09-26,2018-05-03
-5ggj,2016-08-10,2016-06-16
-8gg5,2024-03-06,2023-03-08
-4ggz,2013-06-19,2012-08-07
-5ggx,2017-02-22,2016-06-16
-8ggz,2024-03-06,2023-03-08
-8ggw,2024-03-06,2023-03-08
-6ggd,2019-05-22,2018-05-03
-5gg8,2017-04-19,2016-06-15
-2gg9,2006-06-13,2006-03-23
-4gg5,2012-10-03,2012-08-05
-5ggk,2016-08-10,2016-06-16
-3gg1,2009-06-23,2009-02-27
-7ggg,2023-11-08,2023-08-11
-2ggh,2006-04-11,2006-03-24
-8gg7,2024-03-06,2023-03-08
-7gg9,2023-11-08,2023-08-11
-7ggq,2023-11-08,2023-08-11
-6ggm,2018-08-08,2018-05-03
-6gg6,2018-05-23,2018-05-02
-7ggm,2023-11-08,2023-08-11
-4gg8,2012-10-24,2012-08-06
-5gg4,2017-03-22,2016-06-15
-7ggp,2023-11-08,2023-08-11
-7ggy,2023-11-08,2023-08-11
-8ggr,2024-03-06,2023-03-08
-6ggl,2018-10-10,2018-05-03
-3ggp,2009-03-10,2009-03-01
-2gg2,2006-06-13,2006-03-23
-4ggl,2013-02-13,2012-08-06
-2ggd,2006-08-22,2006-03-23
-2gg6,2006-08-22,2006-03-23
-4gg7,2012-10-03,2012-08-06
-7gg5,2023-11-08,2023-08-11
-7gg4,2023-11-08,2023-08-11
-1gg6,2000-09-20,2000-07-31
-8gg8,2024-03-06,2023-03-08
-7gg1,2023-11-08,2023-08-11
-4ggm,2012-10-03,2012-08-06
-4ggd,2012-11-07,2012-08-06
-1gg5,2001-09-12,2000-07-12
-5ggl,2016-08-10,2016-06-16
-1ggf,2000-08-30,2000-08-21
-8gge,2024-03-06,2023-03-08
-5ggn,2016-08-10,2016-06-16
-6gg2,2018-09-19,2018-05-02
-7ggo,2023-11-08,2023-08-11
-1ggi,1993-10-31,1993-04-02
-6gg4,2018-05-23,2018-05-02
-8ggu,2024-03-06,2023-03-08
-3ggf,2009-03-24,2009-02-27
-2gg7,2006-06-13,2006-03-23
-4ggv,2013-07-17,2012-08-07
-7ggc,2023-11-08,2023-08-11
-3ggv,2009-05-26,2009-03-02
-5gg9,2017-04-19,2016-06-15
-7ggn,2023-11-08,2023-08-11
-7gg6,2023-11-08,2023-08-11
-8gg4,2024-03-06,2023-03-08
-6gge,2019-05-22,2018-05-03
-5ggi,2016-08-10,2016-06-16
-2gga,2006-08-22,2006-03-23
-7gg0,2023-11-08,2023-08-11
-4ggh,2012-09-05,2012-08-06
-8ggo,2024-03-06,2023-03-08
-7ggl,2023-11-08,2023-08-11
-1ggz,2002-06-05,2000-10-13
-8ggt,2024-03-06,2023-03-08
-8gga,2024-03-06,2023-03-08
-4gg6,2012-10-24,2012-08-06
-8ggv,2024-03-06,2023-03-08
-8ggn,2024-03-06,2023-03-08
-2gge,2006-04-18,2006-03-23
-2ggp,2006-08-08,2006-03-24
-2ggb,2006-06-13,2006-03-23
-6gga,2019-05-22,2018-05-03
-5gg7,2017-04-19,2016-06-15
-8ggs,2024-03-06,2023-03-08
-7ggj,2023-11-08,2023-08-11
-5ggp,2016-08-10,2016-06-16
-7ggz,2023-11-08,2023-08-11
-5ggo,2016-08-10,2016-06-16
-2ggt,2006-05-16,2006-03-24
-8ggl,2024-03-06,2023-03-08
-6ggf,2019-05-22,2018-05-03
-1gg9,2000-08-23,2000-08-11
-7ggr,2023-11-08,2023-08-11
-1gg1,2000-10-04,2000-08-04
-8gg1,2024-03-06,2023-03-08
-6gg5,2018-05-23,2018-05-02
-4ggg,2013-02-06,2012-08-06
-6ggi,2018-10-10,2018-05-03
-8ggm,2024-03-06,2023-03-08
-8ggi,2024-03-06,2023-03-08
-7gg8,2023-11-08,2023-08-11
-4gg1,2013-05-22,2012-08-04
-4ggf,2013-02-20,2012-08-06
-8ggy,2024-03-06,2023-03-08
-5ggd,2017-04-19,2016-06-15
-8gg2,2024-03-06,2023-03-08
-8ggp,2024-03-06,2023-03-08
-3gga,2009-05-26,2009-02-27
-8gg3,2024-03-06,2023-03-08
-4ggq,2012-08-15,2012-08-07
-6gg1,2019-05-15,2018-05-02
-3ggj,2009-08-18,2009-02-28
-7ggb,2023-11-08,2023-08-11
-4ggb,2012-08-29,2012-08-06
-6gg9,2018-07-25,2018-05-03
-1ggk,2000-08-30,2000-08-21
-2ggn,2006-06-13,2006-03-24
-3gg2,2009-03-24,2009-02-27
-2gg3,2006-06-13,2006-03-23
-8ggg,2024-03-13,2023-03-08
-3ggx,2009-05-26,2009-03-02
-8ggk,2024-03-06,2023-03-08
-5gg6,2017-04-19,2016-06-15
-1ggm,1999-01-28,1999-01-27
-2gg8,2006-06-13,2006-03-23
-2ggz,2006-05-23,2006-03-24
-7gg3,2023-11-08,2023-08-11
-3ggl,2009-03-31,2009-02-28
-8ggf,2024-03-06,2023-03-08
-8ggb,2024-03-06,2023-03-08
-1gg8,2000-08-23,2000-07-30
-1ggu,1999-09-16,1998-07-22
-5gga,2017-04-19,2016-06-15
-6ggj,2018-10-10,2018-05-03
-1gge,2000-08-30,2000-08-16
-3ggo,2009-03-10,2009-03-01
-8gg9,2024-03-06,2023-03-08
-4ggj,2012-10-10,2012-08-06
-8ggj,2024-03-06,2023-03-08
-7ggk,2023-11-08,2023-08-11
-7ggx,2023-11-08,2023-08-11
-3ggc,2009-08-18,2009-02-27
-3gg7,2009-03-24,2009-02-27
-7ggt,2023-11-08,2023-08-11
-6ggb,2019-05-22,2018-05-03
-2ggs,2007-03-24,2006-03-24
-7ggd,2023-11-08,2023-08-11
-4q74,2014-07-23,2014-04-24
-1q72,2003-08-26,2003-08-15
-6q79,2019-03-20,2018-12-13
-7q77,2022-11-16,2021-11-09
-6q70,2019-04-24,2018-12-12
-5q7c,2018-08-08,2017-05-25
-1q74,2003-12-02,2003-08-15
-6q7v,2019-11-20,2018-12-13
-7q7q,2022-06-22,2021-11-09
-6q7a,2019-11-27,2018-12-13
-2q7j,2007-07-24,2007-06-07
-7q7p,2022-06-22,2021-11-09
-6q7m,2020-02-12,2018-12-13
-4q7f,2014-05-07,2014-04-24
-6q7j,2019-06-05,2018-12-13
-3q73,2011-08-03,2011-01-04
-8q7r,2024-02-21,2023-08-16
-5q7a,2018-08-08,2017-05-25
-7q7o,2022-11-16,2021-11-09
-8q7v,2024-04-17,2023-08-17
-4q7p,2015-03-11,2014-04-25
-4q7n,2014-05-21,2014-04-25
-4q7r,2014-07-09,2014-04-25
-8q7q,2024-04-17,2023-08-16
-6q7w,2019-11-20,2018-12-13
-2q7v,2008-07-08,2007-06-07
-2q72,2007-08-21,2007-06-05
-3q7i,2011-02-02,2011-01-04
-7q7j,2022-11-16,2021-11-09
-1q7b,2004-02-17,2003-08-17
-7q7g,2022-11-16,2021-11-09
-3q7c,2011-02-09,2011-01-04
-7q7s,2022-06-15,2021-11-09
-4q7i,2014-10-22,2014-04-25
-2q7u,2008-05-20,2007-06-07
-6q72,2019-04-24,2018-12-12
-7q7k,2022-02-02,2021-11-09
-4q7c,2014-05-28,2014-04-24
-5q7w,2018-08-08,2017-05-25
-6q7o,2019-06-05,2018-12-13
-3q72,2011-09-21,2011-01-04
-7q7m,2022-11-16,2021-11-09
-3q7e,2011-06-22,2011-01-04
-4q7s,2015-03-11,2014-04-25
-7q7l,2022-02-02,2021-11-09
-2q7t,2008-05-20,2007-06-07
-6q7l,2020-02-12,2018-12-13
-5q7s,2018-08-08,2017-05-25
-5q7u,2018-08-08,2017-05-25
-7q7a,2022-11-16,2021-11-09
-5q7o,2018-08-08,2017-05-25
-1q7a,2004-05-11,2003-08-17
-5q77,2018-08-08,2017-05-25
-7q79,2022-11-16,2021-11-09
-7q7n,2022-11-16,2021-11-09
-2q7i,2007-07-24,2007-06-06
-1q7e,2003-09-30,2003-08-18
-7q7c,2022-11-16,2021-11-09
-2q71,2007-06-19,2007-06-05
-3q76,2011-05-11,2011-01-04
-3q7b,2011-02-09,2011-01-04
-5q7e,2018-08-08,2017-05-25
-5q72,2018-08-08,2017-05-25
-1q7h,2004-01-20,2003-08-18
-6q7n,2019-06-05,2018-12-13
-6q7p,2019-06-05,2018-12-13
-2q7m,2007-08-21,2007-06-07
-5q7h,2018-08-08,2017-05-25
-1q7y,2003-10-07,2003-08-20
-4q7v,2015-03-11,2014-04-25
-5q73,2018-08-08,2017-05-25
-5q7i,2018-08-08,2017-05-25
-6q7k,2019-03-27,2018-12-13
-6q7t,2019-06-26,2018-12-13
-4q79,2014-12-17,2014-04-24
-6q7b,2020-01-15,2018-12-13
-5q75,2018-08-08,2017-05-25
-5q79,2018-08-08,2017-05-25
-6q7r,2019-06-05,2018-12-13
-2q7e,2007-07-24,2007-06-06
-1q7g,2003-10-21,2003-08-18
-8q7i,2023-12-13,2023-08-16
-7q78,2022-11-16,2021-11-09
-3q7p,2011-09-21,2011-01-05
-2q7a,2007-09-18,2007-06-06
-5q7k,2018-08-08,2017-05-25
-3q78,2011-08-03,2011-01-04
-7q7v,2022-06-15,2021-11-09
-6q7c,2020-01-15,2018-12-13
-1q7c,2004-02-17,2003-08-17
-7q7r,2022-06-15,2021-11-09
-2q7h,2007-07-24,2007-06-06
-7q7f,2022-11-16,2021-11-09
-5q78,2018-08-08,2017-05-25
-3q7a,2011-08-03,2011-01-04
-3q71,2011-01-26,2011-01-04
-6q7u,2019-11-20,2018-12-13
-6q7d,2020-01-15,2018-12-13
-5q7y,2018-08-08,2017-05-25
-2q70,2007-08-07,2007-06-05
-4q71,2014-08-06,2014-04-23
-5q76,2018-08-08,2017-05-25
-7q7e,2022-11-16,2021-11-09
-2q7g,2007-07-24,2007-06-06
-2q7w,2007-09-04,2007-06-07
-2q7q,2007-07-31,2007-06-07
-7q7t,2022-06-15,2021-11-09
-4q7w,2015-03-11,2014-04-25
-7q7w,2022-02-02,2021-11-09
-5q7r,2018-08-08,2017-05-25
-6q7g,2020-01-15,2018-12-13
-7q7d,2022-11-16,2021-11-09
-7q7b,2022-11-16,2021-11-09
-3q7h,2011-01-12,2011-01-04
-3q7f,2011-08-03,2011-01-04
-2q73,2007-10-09,2007-06-05
-6q73,2018-12-26,2018-12-12
-6q7e,2020-01-15,2018-12-13
-8q70,2023-11-29,2023-08-15
-5q7t,2018-08-08,2017-05-25
-4q7l,2015-05-20,2014-04-25
-4q7y,2014-09-03,2014-04-25
-2q7s,2007-06-19,2007-06-07
-2q7k,2007-07-24,2007-06-07
-4q7d,2014-07-23,2014-04-24
-2q7d,2007-07-03,2007-06-06
-1q7z,2004-03-23,2003-08-20
-5q7j,2018-08-08,2017-05-25
-5q7n,2018-08-08,2017-05-25
-5q7g,2018-08-08,2017-05-25
-6q7f,2020-01-15,2018-12-13
-6q7h,2019-11-27,2018-12-13
-3q7t,2011-07-20,2011-01-05
-5q7v,2018-08-08,2017-05-25
-8q77,2023-12-06,2023-08-15
-3q7q,2011-09-21,2011-01-05
-4q7x,2014-09-03,2014-04-25
-5q71,2018-08-08,2017-05-25
-7q7h,2022-11-16,2021-11-09
-7q7i,2022-02-02,2021-11-09
-1q79,2004-09-07,2003-08-16
-5q7b,2018-08-08,2017-05-25
-5q7x,2018-08-08,2017-05-25
-4q72,2014-08-06,2014-04-23
-7q75,2022-11-16,2021-11-09
-7q7u,2022-06-15,2021-11-09
-5q7f,2018-08-08,2017-05-25
-8q71,2023-12-06,2023-08-15
-2q7r,2007-08-21,2007-06-07
-8q7w,2024-04-17,2023-08-17
-3q7u,2011-05-04,2011-01-05
-8q7x,2024-04-17,2023-08-17
-2q7n,2007-07-31,2007-06-07
-2q7o,2008-01-15,2007-06-07
-5q74,2018-08-08,2017-05-25
-3q7d,2011-11-09,2011-01-04
-2q78,2007-06-19,2007-06-06
-8q72,2024-01-31,2023-08-15
-3q7z,2011-07-06,2011-01-05
-6q77,2019-03-20,2018-12-12
-3q77,2011-05-11,2011-01-04
-8q7h,2024-04-17,2023-08-16
-7q76,2022-11-16,2021-11-09
-2q7l,2007-07-24,2007-06-07
-4q7h,2015-05-27,2014-04-25
-2q7y,2008-04-01,2007-06-07
-4q70,2015-05-06,2014-04-23
-1q78,2004-09-07,2003-08-16
-5q7d,2018-08-08,2017-05-25
-1q7l,2004-01-20,2003-08-19
-5q7p,2018-08-08,2017-05-25
-5q7m,2018-08-08,2017-05-25
-6q7i,2019-06-05,2018-12-13
-3q7j,2011-07-27,2011-01-05
-5q7l,2018-08-08,2017-05-25
-6q71,2019-04-24,2018-12-12
-5q7q,2018-08-08,2017-05-25
-4q7z,2014-09-03,2014-04-25
-3q70,2012-01-04,2011-01-04
-5q70,2018-08-08,2017-05-25
-4q73,2014-08-06,2014-04-23
-3q75,2011-08-03,2011-01-04
-4q7b,2015-06-10,2014-04-24
-5q7z,2018-08-08,2017-05-25
-3q79,2011-08-03,2011-01-04
-6q74,2018-12-26,2018-12-12
-8qy6,2024-02-21,2023-10-25
-4qyh,2014-12-17,2014-07-24
-7qy5,2022-11-16,2022-01-27
-3qy0,2011-03-30,2011-03-02
-6qya,2019-04-10,2019-03-08
-7qyl,2022-11-23,2022-01-28
-6qyq,2019-04-17,2019-03-09
-6qy4,2019-09-25,2019-03-08
-6qyn,2019-08-07,2019-03-09
-7qy2,2022-04-20,2022-01-27
-4qyy,2014-11-12,2014-07-26
-3qyp,2011-04-13,2011-03-03
-6qy5,2019-10-16,2019-03-08
-6qy3,2019-05-08,2019-03-08
-1qyp,1997-12-24,1997-08-19
-3qys,2011-08-17,2011-03-03
-2qyo,2008-08-26,2007-08-15
-3qyn,2011-04-06,2011-03-03
-7qy7,2023-02-08,2022-01-27
-5qyi,2020-06-10,2020-02-12
-7qyu,2022-09-28,2022-01-29
-5qy4,2020-06-10,2020-02-12
-6qyb,2019-07-10,2019-03-08
-5qyc,2020-06-10,2020-02-12
-7qym,2022-07-13,2022-01-28
-6qyp,2019-08-07,2019-03-09
-5qy5,2020-06-10,2020-02-12
-7qye,2022-09-28,2022-01-28
-1qyz,2004-09-28,2003-09-12
-8qyp,2023-12-13,2023-10-26
-2qyk,2008-04-08,2007-08-15
-3qy6,2011-06-08,2011-03-03
-3qyl,2012-01-18,2011-03-03
-1qy6,2004-02-17,2003-09-09
-6qy9,2019-04-17,2019-03-08
-3qyo,2012-01-18,2011-03-03
-4qyi,2014-08-27,2014-07-24
-7qyn,2022-04-27,2022-01-28
-2qym,2008-04-08,2007-08-15
-8qyt,2024-02-07,2023-10-26
-4qy6,2015-08-12,2014-07-23
-5qyd,2020-06-10,2020-02-12
-3qyh,2011-03-23,2011-03-03
-4qyk,2014-12-10,2014-07-24
-3qy7,2011-06-08,2011-03-03
-6qyo,2019-08-07,2019-03-09
-7qy6,2022-07-13,2022-01-27
-8qyw,2024-02-07,2023-10-26
-5qy0,2020-04-08,2020-03-09
-4qy0,2015-01-28,2014-07-23
-7qy0,2022-04-20,2022-01-27
-1qyx,2004-08-03,2003-09-12
-2qyf,2008-01-29,2007-08-14
-2qyl,2008-04-08,2007-08-15
-5qye,2020-06-10,2020-02-12
-6qyc,2020-04-22,2019-03-08
-8qy5,2024-02-21,2023-10-25
-7qy8,2022-12-07,2022-01-27
-7qyv,2022-09-28,2022-01-29
-1qyv,2004-08-03,2003-09-12
-5qy2,2020-06-10,2020-02-12
-7qyz,2022-08-03,2022-01-30
-7qyq,2022-08-03,2022-01-28
-2qyi,2008-08-19,2007-08-15
-8qy4,2024-02-21,2023-10-25
-7qyc,2022-08-03,2022-01-27
-8qyu,2023-12-13,2023-10-26
-4qya,2015-06-03,2014-07-24
-5qy8,2020-06-10,2020-02-12
-7qyo,2022-09-28,2022-01-28
-3qyy,2011-11-30,2011-03-04
-3qyg,2011-03-23,2011-03-03
-5qyg,2020-06-10,2020-02-12
-2qyn,2008-04-08,2007-08-15
-8qyq,2023-12-13,2023-10-26
-3qyt,2012-03-14,2011-03-03
-1qyy,2004-03-02,2003-09-12
-6qyg,2020-03-25,2019-03-08
-3qyw,2011-08-24,2011-03-04
-1qye,2003-11-11,2003-09-10
-1qy8,2003-11-11,2003-09-09
-4qyg,2014-12-17,2014-07-24
-4qyp,2014-12-10,2014-07-25
-5qyk,2020-06-10,2020-02-12
-7qy9,2022-12-07,2022-01-27
-1qyw,2004-08-03,2003-09-12
-1qyf,2003-09-30,2003-09-10
-6qy1,2019-09-25,2019-03-08
-1qy1,2004-02-24,2003-09-09
-4qye,2014-12-17,2014-07-24
-7qyx,2022-07-13,2022-01-29
-4qy1,2015-01-28,2014-07-23
-4qyn,2014-12-31,2014-07-24
-4qyf,2014-12-17,2014-07-24
-5qya,2020-06-10,2020-02-12
-7qyy,2023-02-08,2022-01-29
-6qyl,2019-08-07,2019-03-09
-4qy5,2015-08-12,2014-07-23
-5qy1,2020-06-10,2020-02-12
-8qyb,2024-01-17,2023-10-25
-8qyr,2023-12-13,2023-10-26
-4qy2,2015-01-28,2014-07-23
-4qym,2014-08-13,2014-07-24
-5qy7,2020-06-10,2020-02-12
-1qy7,2003-09-23,2003-09-09
-4qyt,2014-08-06,2014-07-25
-8qy9,2024-01-17,2023-10-25
-8qya,2024-01-17,2023-10-25
-8qyg,2024-05-08,2023-10-26
-1qy0,2004-02-24,2003-09-09
-4qyz,2014-09-03,2014-07-26
-7qyk,2023-03-22,2022-01-28
-6qy2,2019-09-25,2019-03-08
-3qy1,2011-03-16,2011-03-02
-5qy6,2020-06-10,2020-02-12
-3qyq,2011-03-30,2011-03-03
-8qyf,2024-01-17,2023-10-26
-1qy4,2003-12-09,2003-09-09
-3qyf,2011-03-23,2011-03-03
-7qy4,2022-08-03,2022-01-27
-2qyv,2007-08-28,2007-08-15
-5qyb,2020-06-10,2020-02-12
-6qyk,2019-08-07,2019-03-09
-6qy8,2020-03-25,2019-03-08
-6qyf,2020-03-25,2019-03-08
-3qyk,2012-03-07,2011-03-03
-6qy0,2019-09-25,2019-03-08
-7qy3,2022-03-09,2022-01-27
-1qyb,2004-03-30,2003-09-10
-3qym,2011-04-06,2011-03-03
-6qyh,2019-06-12,2019-03-09
-7qys,2022-10-05,2022-01-29
-5qyj,2020-06-10,2020-02-12
-5qyh,2020-06-10,2020-02-12
-3qyx,2011-09-14,2011-03-04
-7qy1,2022-04-20,2022-01-27
-4qy9,2014-11-05,2014-07-24
-7qyw,2022-09-28,2022-01-29
-4qy4,2014-08-27,2014-07-23
-4qy3,2014-12-03,2014-07-23
-3qy8,2011-06-08,2011-03-03
-7qyt,2022-09-28,2022-01-29
-4qyd,2014-09-24,2014-07-24
-3qyz,2011-08-24,2011-03-04
-7qyr,2022-10-05,2022-01-29
-2qyq,2008-07-15,2007-08-15
-7qya,2023-02-08,2022-01-27
-6qy7,2020-03-25,2019-03-08
-7qyh,2022-06-29,2022-01-28
-5qyf,2020-06-10,2020-02-12
-5qy3,2020-06-10,2020-02-12
-5qy9,2020-06-10,2020-02-12
-1qyg,2003-09-23,2003-09-10
-7qyb,2023-02-08,2022-01-27
-4qys,2015-02-18,2014-07-25
-1qy2,2004-02-24,2003-09-09
-6qyi,2019-06-12,2019-03-09
-5i90,2016-05-11,2016-02-19
-2i9g,2006-10-24,2006-09-05
-6i91,2019-12-04,2018-11-22
-1i9h,2001-09-12,2001-03-20
-3i9f,2009-07-28,2009-07-10
-8i91,2023-09-27,2023-02-06
-4i9j,2013-04-10,2012-12-05
-4i9o,2013-03-06,2012-12-05
-2i94,2006-10-10,2006-09-05
-8i9w,2023-05-17,2023-02-07
-3i9j,2009-07-28,2009-07-12
-1i9c,2002-03-19,2001-03-19
-3i90,2009-09-08,2009-07-10
-4i94,2013-08-14,2012-12-04
-6i9k,2019-07-03,2018-11-23
-1i9q,2001-03-28,2001-03-20
-6i9t,2019-05-22,2018-11-25
-8i9c,2024-02-07,2023-02-06
-8i90,2024-02-14,2023-02-06
-4i9z,2014-01-01,2012-12-05
-4i9c,2013-11-20,2012-12-05
-6i9x,2019-12-18,2018-11-26
-5i9p,2016-03-09,2016-02-20
-2i9w,2006-09-19,2006-09-06
-1i9s,2001-05-23,2001-03-20
-8i9a,2023-10-18,2023-02-06
-4i9u,2013-01-23,2012-12-05
-8i94,2024-02-14,2023-02-06
-5i9y,2016-11-09,2016-02-21
-8i9o,2024-02-14,2023-02-07
-5i95,2017-03-01,2016-02-19
-3i9v,2009-09-15,2009-07-13
-4i9x,2013-04-03,2012-12-05
-6i9y,2019-05-01,2018-11-26
-6i9d,2019-04-24,2018-11-23
-3i9z,2009-11-17,2009-07-13
-1i9m,2001-03-28,2001-03-20
-5i9o,2016-03-23,2016-02-20
-2i9p,2006-09-26,2006-09-06
-2i9u,2006-09-19,2006-09-06
-8i9u,2024-01-17,2023-02-07
-4i9f,2013-07-10,2012-12-05
-3i9o,2009-07-28,2009-07-12
-4i9i,2013-02-06,2012-12-05
-5i9z,2016-11-09,2016-02-21
-6i9r,2020-07-08,2018-11-25
-3i98,2009-08-18,2009-07-10
-4i9w,2013-01-23,2012-12-05
-4i9a,2013-05-01,2012-12-05
-6i92,2019-10-16,2018-11-22
-8i9p,2023-05-17,2023-02-07
-5i9i,2016-06-15,2016-02-20
-8i9d,2024-02-07,2023-02-06
-3i92,2009-07-28,2009-07-10
-6i9p,2019-05-22,2018-11-24
-5i93,2016-03-09,2016-02-19
-5i92,2016-03-23,2016-02-19
-1i9p,2001-03-28,2001-03-20
-5i9q,2016-05-04,2016-02-20
-1i91,2001-03-28,2001-03-16
-2i91,2006-10-17,2006-09-04
-3i97,2010-03-02,2009-07-10
-2i9b,2007-01-02,2006-09-05
-4i9b,2013-02-20,2012-12-05
-1i9a,2001-03-28,2001-03-18
-6i9s,2019-03-13,2018-11-25
-8i92,2023-09-27,2023-02-06
-5i9k,2017-07-12,2016-02-20
-1i9l,2001-03-28,2001-03-20
-4i9h,2013-01-23,2012-12-05
-1i9e,2001-12-05,2001-03-19
-4i9n,2013-01-23,2012-12-05
-8i9i,2023-04-19,2023-02-07
-6i90,2019-10-16,2018-11-22
-4i9q,2013-10-09,2012-12-05
-1i9d,2001-12-05,2001-03-19
-6i9h,2019-05-01,2018-11-23
-8i9v,2023-05-17,2023-02-07
-6i9m,2019-12-04,2018-11-23
-5i96,2017-03-08,2016-02-19
-8i9e,2024-02-07,2023-02-06
-5i9l,2017-02-22,2016-02-20
-8i9y,2023-05-17,2023-02-07
-6i9w,2019-08-21,2018-11-26
-6i99,2020-05-27,2018-11-22
-1i9b,2001-05-16,2001-03-18
-1i9r,2002-03-20,2001-03-20
-1i9o,2001-03-28,2001-03-20
-6i9n,2019-12-04,2018-11-24
-3i9g,2009-09-29,2009-07-10
-3i99,2009-10-20,2009-07-10
-6i96,2019-08-28,2018-11-22
-3i9l,2009-07-28,2009-07-12
-5i9n,2017-02-22,2016-02-20
-8i9g,2024-02-07,2023-02-06
-8i9f,2024-02-07,2023-02-06
-8i9r,2023-05-17,2023-02-07
-1i9t,2001-05-23,2001-03-20
-4i9d,2013-04-17,2012-12-05
-5i91,2016-03-09,2016-02-19
-3i9k,2009-07-28,2009-07-12
-6i98,2019-08-28,2018-11-22
-4i97,2013-12-04,2012-12-04
-5i9e,2016-07-27,2016-02-20
-8i9t,2023-05-17,2023-02-07
-6i97,2019-08-28,2018-11-22
-4i9r,2013-10-09,2012-12-05
-5i9x,2016-11-09,2016-02-21
-5i9t,2016-10-26,2016-02-20
-6i94,2019-10-16,2018-11-22
-5i9v,2016-11-09,2016-02-21
-2i96,2007-09-04,2006-09-05
-2i9v,2007-02-06,2006-09-06
-4i9t,2013-04-10,2012-12-05
-3i9t,2010-05-19,2009-07-13
-3i91,2009-09-08,2009-07-10
-6i93,2019-10-16,2018-11-22
-5i9b,2016-10-26,2016-02-19
-8i9z,2023-05-17,2023-02-07
-1i90,2001-03-28,2001-03-16
-3i9h,2009-12-01,2009-07-11
-8i9x,2023-05-17,2023-02-07
-1i9g,2001-09-26,2001-03-20
-3i9u,2010-05-19,2009-07-13
-1i9j,2002-03-20,2001-03-20
-8i95,2023-10-18,2023-02-06
-4i9g,2013-07-10,2012-12-05
-6i9a,2019-03-13,2018-11-22
-6i95,2019-10-16,2018-11-22
-6i9l,2019-12-04,2018-11-23
-1i9n,2001-03-28,2001-03-20
-4i9e,2013-11-20,2012-12-05
-8i9b,2024-02-07,2023-02-06
-3i94,2009-10-27,2009-07-10
-2i99,2007-02-27,2006-09-05
-1i9z,2001-05-16,2001-03-21
-5i9w,2016-11-09,2016-02-21
-2i9k,2006-10-10,2006-09-05
-3i9m,2009-07-28,2009-07-12
-5i9m,2017-02-22,2016-02-20
-6i9z,2019-12-18,2018-11-26
-4i91,2013-07-03,2012-12-04
-2i9f,2007-05-01,2006-09-05
-8i9h,2024-02-07,2023-02-06
-1i94,2001-04-12,2001-03-18
-3i93,2009-11-24,2009-07-10
-4i9l,2013-10-09,2012-12-05
-5i94,2016-05-11,2016-02-19
-8i98,2023-09-20,2023-02-06
-3i95,2009-10-27,2009-07-10
-4i9s,2013-10-09,2012-12-05
-3i9n,2009-07-28,2009-07-12
-8i93,2023-09-27,2023-02-06
-103m,1998-04-08,1997-12-16
-6tzo,2019-11-06,2019-08-12
-6tz6,2019-09-18,2019-08-10
-1tz2,2004-11-02,2004-07-09
-7tza,2022-08-31,2022-02-15
-7tzv,2022-06-01,2022-02-16
-6tzf,2020-06-24,2019-08-12
-5tzl,2017-06-28,2016-11-21
-8tzh,2023-12-06,2023-08-26
-3tz6,2012-05-30,2011-09-27
-1tzn,2004-08-17,2004-07-10
-6tz7,2019-09-18,2019-08-10
-4tze,2015-07-29,2014-07-10
-1tzm,2004-11-02,2004-07-10
-5tzt,2017-03-15,2016-11-22
-4tzw,2014-09-10,2014-07-11
-3tz3,2011-10-19,2011-09-26
-3tzs,2011-10-12,2011-09-27
-5tzn,2017-05-24,2016-11-22
-1tzz,2004-10-05,2004-07-12
-5tzh,2017-02-22,2016-11-21
-6tzg,2020-06-24,2019-08-12
-7tz2,2022-05-11,2022-02-15
-4tzr,2014-08-27,2014-07-10
-6tzm,2019-11-06,2019-08-12
-8tz8,2024-03-13,2023-08-26
-6tzu,2019-12-04,2019-08-13
-5tzf,2017-04-19,2016-11-21
-7tzf,2022-03-23,2022-02-15
-4tzk,2014-08-20,2014-07-10
-8tz3,2024-03-13,2023-08-26
-8tzk,2023-12-20,2023-08-27
-3tz7,2012-10-10,2011-09-27
-4tzn,2014-11-19,2014-07-10
-7tze,2022-05-11,2022-02-15
-8tzd,2024-03-13,2023-08-26
-7tzx,2023-03-15,2022-02-16
-1tzl,2004-10-19,2004-07-10
-7tzn,2023-03-15,2022-02-16
-8tz7,2024-03-13,2023-08-26
-7tzw,2023-03-15,2022-02-16
-1tz6,2004-10-12,2004-07-09
-5tz3,2017-02-22,2016-11-21
-1tzf,2004-09-07,2004-07-09
-7tz9,2022-08-31,2022-02-15
-3tzl,2011-10-05,2011-09-27
-5tzk,2017-01-04,2016-11-21
-4tzh,2015-06-03,2014-07-10
-8tze,2023-12-06,2023-08-26
-7tz7,2022-05-18,2022-02-15
-3tze,2011-10-12,2011-09-27
-8tzz,2024-05-01,2023-08-28
-1tze,1997-07-07,1996-06-06
-7tz6,2023-02-22,2022-02-15
-5tzx,2017-02-22,2016-11-22
-1tzj,2004-11-02,2004-07-10
-5tzd,2017-04-19,2016-11-21
-5tz2,2017-03-15,2016-11-21
-1tzo,2004-08-17,2004-07-10
-6tzk,2019-10-23,2019-08-12
-4tz2,2014-10-29,2014-07-09
-8tzr,2023-10-18,2023-08-27
-3tzb,2011-11-02,2011-09-27
-8tz6,2024-03-13,2023-08-26
-8tz9,2024-03-13,2023-08-26
-3tzv,2012-04-25,2011-09-27
-3tz4,2012-10-03,2011-09-27
-3tzm,2012-05-23,2011-09-27
-6tzy,2020-03-18,2019-08-13
-3tzx,2012-08-29,2011-09-28
-5tzr,2017-06-07,2016-11-22
-3tz0,2012-10-03,2011-09-26
-5tza,2017-02-22,2016-11-21
-7tzp,2022-03-02,2022-02-16
-5tzj,2017-01-04,2016-11-21
-6tz8,2019-09-18,2019-08-10
-4tzc,2014-08-06,2014-07-10
-3tzw,2012-08-29,2011-09-28
-1tzs,2005-07-12,2004-07-12
-6tzv,2020-08-19,2019-08-13
-6tzp,2021-02-17,2019-08-12
-3tzo,2012-01-18,2011-09-27
-5tze,2017-01-04,2016-11-21
-8tzu,2024-05-01,2023-08-27
-3tz2,2012-10-03,2011-09-26
-6tzi,2020-06-24,2019-08-12
-8tzc,2023-12-06,2023-08-26
-3tzf,2012-03-14,2011-09-27
-1tzc,2004-07-20,2004-07-09
-3tz5,2012-10-03,2011-09-27
-6tzd,2020-08-19,2019-08-12
-8tzg,2023-12-06,2023-08-26
-7tzy,2023-03-15,2022-02-16
-5tzu,2017-03-15,2016-11-22
-8tza,2024-03-13,2023-08-26
-7tzg,2022-05-11,2022-02-15
-7tzm,2023-03-15,2022-02-16
-8tz1,2024-03-13,2023-08-26
-8tzj,2023-12-20,2023-08-27
-4tz3,2015-03-18,2014-07-09
-3tzy,2012-08-29,2011-09-28
-3tzi,2012-04-25,2011-09-27
-1tz8,2004-10-12,2004-07-09
-5tzc,2017-02-22,2016-11-21
-5tzb,2017-07-12,2016-11-21
-5tz1,2017-03-15,2016-11-21
-6tzj,2020-06-24,2019-08-12
-6tzb,2019-10-30,2019-08-12
-1tz3,2004-10-12,2004-07-09
-7tzb,2022-09-14,2022-02-15
-8tz2,2024-03-13,2023-08-26
-4tz5,2015-03-18,2014-07-09
-7tzh,2022-05-11,2022-02-15
-4tzu,2014-08-06,2014-07-10
-4tz4,2014-08-06,2014-07-09
-6tzh,2020-06-24,2019-08-12
-1tzg,2005-03-01,2004-07-09
-3tzz,2012-08-29,2011-09-28
-1tzk,2004-11-02,2004-07-10
-4tz8,2014-10-29,2014-07-09
-8tzf,2023-12-06,2023-08-26
-3tz8,2012-10-10,2011-09-27
-5tzg,2017-04-19,2016-11-21
-4tz0,2014-12-31,2014-07-09
-5tzv,2016-12-07,2016-11-22
-8tzb,2023-12-06,2023-08-26
-5tzw,2017-02-22,2016-11-22
-4tz6,2015-01-28,2014-07-09
-4tz9,2015-07-29,2014-07-09
-8tz4,2024-03-13,2023-08-26
-4tzd,2015-07-22,2014-07-10
-5tzy,2017-06-07,2016-11-22
-3tz1,2013-01-23,2011-09-26
-5tzo,2017-10-04,2016-11-22
-7tzj,2022-03-02,2022-02-15
-5tzz,2017-02-22,2016-11-22
-4tzb,2015-07-22,2014-07-09
-5tz6,2017-01-11,2016-11-21
-8tz5,2024-03-13,2023-08-26
-4tzf,2015-07-29,2014-07-10
-3tzc,2011-10-19,2011-09-27
-6tz1,2019-11-20,2019-08-09
-8tzo,2023-10-18,2023-08-27
-6tz2,2019-11-20,2019-08-09
-6tzz,2020-03-18,2019-08-13
-6tzc,2019-11-20,2019-08-12
-3tz9,2012-10-10,2011-09-27
-3tza,2011-10-26,2011-09-27
-4tzt,2014-08-20,2014-07-10
-6tzw,2020-05-13,2019-08-13
-6tzx,2019-11-06,2019-08-13
-7tz4,2022-05-18,2022-02-15
-8tzl,2023-12-20,2023-08-27
-7tzz,2022-06-01,2022-02-16
-1tzw,2004-08-31,2004-07-12
-1tzd,2004-09-21,2004-07-09
-4tz1,2015-03-18,2014-07-09
-7tzc,2022-05-18,2022-02-15
-451c,1981-10-02,1981-07-20
-351c,1981-10-02,1981-07-20
-7zh2,2023-02-15,2022-04-05
-6zhh,2021-05-19,2020-06-23
-5zhn,2019-03-27,2018-03-13
-2zhf,2009-02-10,2008-02-04
-3zhb,2013-07-17,2012-12-20
-6zhv,2021-05-05,2020-06-23
-1zh8,2005-05-10,2005-04-22
-6zhd,2020-07-29,2020-06-22
-1zhw,2005-09-06,2005-04-26
-5zhs,2018-11-21,2018-03-13
-5zhk,2019-03-06,2018-03-13
-1zhx,2005-09-06,2005-04-26
-5zh5,2018-06-27,2018-03-11
-7zh5,2023-02-15,2022-04-05
-4zhb,2015-05-06,2015-04-24
-1zhb,2005-06-14,2005-04-25
-6zhf,2021-05-19,2020-06-23
-1zho,2006-05-09,2005-04-26
-6zhz,2020-10-21,2020-06-24
-3zhu,2013-11-13,2012-12-24
-1zhy,2005-09-06,2005-04-26
-3zh8,2013-02-27,2012-12-20
-4zhx,2016-03-09,2015-04-27
-1zhn,2005-07-19,2005-04-26
-5zhf,2018-09-05,2018-03-13
-7zhc,2023-03-15,2022-04-06
-7zhd,2022-11-09,2022-04-06
-2zhi,2009-02-10,2008-02-06
-7zh6,2022-11-09,2022-04-05
-1zh4,2005-12-13,2005-04-22
-4zh4,2015-08-05,2015-04-24
-3zhw,2013-03-06,2012-12-30
-4zhg,2015-08-05,2015-04-24
-2zhj,2009-02-10,2008-02-06
-5zh2,2018-06-27,2018-03-11
-5zhl,2019-03-06,2018-03-13
-4zhc,2015-08-05,2015-04-24
-1zh5,2006-01-17,2005-04-22
-4zh8,2016-01-13,2015-04-24
-4zha,2016-01-13,2015-04-24
-3zhy,2013-10-09,2012-12-30
-1zht,2005-09-06,2005-04-26
-3zhv,2013-11-13,2012-12-24
-4zhq,2016-07-27,2015-04-26
-6zhg,2021-05-19,2020-06-23
-7zho,2023-04-19,2022-04-06
-4zhl,2015-09-16,2015-04-25
-4zh1,2016-01-13,2015-04-24
-7zhp,2023-04-19,2022-04-06
-6zhc,2020-08-05,2020-06-22
-4zhf,2015-08-05,2015-04-24
-6zhl,2021-06-30,2020-06-23
-4zhi,2016-06-22,2015-04-24
-6zhw,2020-12-09,2020-06-23
-3zht,2013-11-13,2012-12-24
-1zh1,2005-05-24,2005-04-22
-5zho,2018-04-11,2018-03-13
-3zhz,2013-10-09,2012-12-30
-5zh4,2018-06-27,2018-03-11
-3zhq,2013-11-13,2012-12-24
-7zhh,2022-12-07,2022-04-06
-3zhr,2013-11-13,2012-12-24
-6zh5,2021-04-28,2020-06-21
-5zhm,2019-03-06,2018-03-13
-2zh6,2008-08-05,2008-02-01
-1zhm,2005-09-20,2005-04-26
-6zh8,2020-10-21,2020-06-21
-7zhv,2022-12-14,2022-04-07
-1zhf,2006-08-01,2005-04-25
-2zhp,2009-02-17,2008-02-06
-6zh7,2021-04-14,2020-06-21
-3zhg,2014-01-15,2012-12-21
-3zhm,2013-12-25,2012-12-22
-2zhm,2008-12-30,2008-02-06
-7zh8,2022-11-09,2022-04-05
-2zhn,2008-12-30,2008-02-06
-2zhe,2009-02-10,2008-02-04
-6zhj,2021-01-27,2020-06-23
-7zhb,2022-04-20,2022-04-06
-1zhj,2005-12-13,2005-04-25
-5zhw,2018-09-05,2018-03-13
-6zhp,2021-05-05,2020-06-23
-1zh9,2006-05-23,2005-04-23
-1zh2,2005-12-13,2005-04-22
-7zhy,2022-12-14,2022-04-07
-6zhm,2021-06-30,2020-06-23
-4zh5,2016-06-29,2015-04-24
-5zht,2018-11-21,2018-03-13
-7zhs,2023-07-26,2022-04-07
-5zha,2018-10-03,2018-03-12
-7zhg,2022-06-29,2022-04-06
-4zhk,2015-05-27,2015-04-25
-5zhr,2018-11-21,2018-03-13
-7zhz,2022-12-14,2022-04-07
-7zhw,2022-12-14,2022-04-07
-1zhl,2005-05-17,2005-04-26
-7zhq,2023-04-19,2022-04-06
-7zh3,2022-10-12,2022-04-05
-1zha,2005-09-27,2005-04-25
-7zhi,2022-08-24,2022-04-06
-7zhm,2022-11-23,2022-04-06
-6zhk,2020-07-01,2020-06-23
-3zho,2013-08-28,2012-12-23
-5zh1,2018-08-22,2018-03-10
-7zh1,2023-02-15,2022-04-05
-7zhn,2023-04-19,2022-04-06
-5zh6,2018-08-01,2018-03-11
-4zhn,2015-12-23,2015-04-25
-2zhk,2008-12-30,2008-02-06
-6zhy,2020-12-23,2020-06-24
-4zhz,2015-05-13,2015-04-27
-1zhz,2005-09-06,2005-04-26
-6zho,2020-07-15,2020-06-23
-7zhu,2022-12-14,2022-04-07
-3zhf,2013-07-10,2012-12-21
-2zhw,2009-02-10,2008-02-08
-1zh0,2006-04-04,2005-04-22
-2zhl,2008-12-30,2008-02-06
-5zhx,2018-09-05,2018-03-13
-7zha,2022-11-09,2022-04-05
-2zhz,2008-07-29,2008-02-12
-1zhp,2005-09-20,2005-04-26
-2zhc,2008-02-26,2008-02-04
-7zhx,2022-12-14,2022-04-07
-7zhe,2022-11-09,2022-04-06
-5zhv,2018-10-17,2018-03-13
-6zhx,2020-12-23,2020-06-24
-3zhs,2013-11-13,2012-12-24
-5zhz,2018-04-04,2018-03-13
-1zhs,2005-06-07,2005-04-26
-2zhr,2008-04-22,2008-02-08
-3zhx,2013-10-09,2012-12-30
-2zhd,2009-02-10,2008-02-04
-6zhi,2020-09-09,2020-06-23
-7zhf,2023-10-25,2022-04-06
-7zhl,2022-11-23,2022-04-06
-6zhb,2021-01-27,2020-06-22
-4zhm,2015-09-16,2015-04-25
-7zh4,2022-10-12,2022-04-05
-4zh3,2015-08-05,2015-04-24
-2zhq,2009-01-13,2008-02-08
-7zh9,2022-08-31,2022-04-05
-7zhk,2023-10-25,2022-04-06
-5zhp,2018-11-28,2018-03-13
-4zht,2016-06-01,2015-04-27
-6zh0,2022-06-01,2020-06-20
-2zha,2008-08-05,2008-02-01
-4zhh,2015-08-05,2015-04-24
-5zhj,2019-03-06,2018-03-13
-5zh3,2018-06-27,2018-03-11
-3zha,2013-01-09,2012-12-20
-4zhd,2015-08-05,2015-04-24
-1zhk,2005-05-17,2005-04-26
-1zh6,2006-04-04,2005-04-22
-3zh0,2013-03-27,2012-12-19
-6zhu,2022-01-12,2020-06-23
-4zh2,2015-08-05,2015-04-24
-4zh7,2015-08-19,2015-04-24
-7p2j,2021-09-08,2021-07-06
-8p2i,2024-04-24,2023-05-16
-1p2h,2003-11-25,2003-04-15
-4p2z,2014-06-04,2014-03-05
-3p2u,2011-01-05,2010-10-04
-2p2f,2007-05-29,2007-03-07
-3p2a,2010-10-13,2010-10-01
-7p2x,2022-07-20,2021-07-06
-4p2t,2014-07-16,2014-03-04
-2p2z,2007-09-11,2007-03-08
-1p2p,1983-09-15,1983-06-27
-2p2t,2008-01-15,2007-03-07
-8p2d,2023-09-13,2023-05-15
-2p2s,2007-03-20,2007-03-07
-6p23,2019-10-16,2019-05-20
-7p2y,2022-02-02,2021-07-06
-6p22,2020-05-27,2019-05-20
-6p20,2020-05-27,2019-05-20
-2p2n,2007-05-15,2007-03-07
-6p27,2019-10-16,2019-05-21
-2p28,2007-08-14,2007-03-07
-6p2s,2019-10-16,2019-05-22
-1p28,2003-08-05,2003-04-15
-3p2z,2011-04-27,2010-10-04
-2p26,2007-08-14,2007-03-06
-6p2t,2020-01-08,2019-05-22
-1p2r,2003-10-07,2003-04-15
-6p2n,2019-07-31,2019-05-21
-6p2u,2019-06-19,2019-05-22
-1p2g,2003-09-02,2003-04-15
-2p2x,2007-09-11,2007-03-08
-6p2a,2020-05-27,2019-05-21
-1p2y,2003-10-28,2003-04-16
-7p2q,2021-10-06,2021-07-06
-2p2a,2007-06-19,2007-03-07
-4p26,2014-04-02,2014-03-01
-6p2d,2020-06-03,2019-05-21
-3p2x,2011-11-23,2010-10-04
-2p2i,2007-03-20,2007-03-07
-2p2b,2007-05-29,2007-03-07
-3p24,2010-12-29,2010-10-01
-6p26,2020-11-18,2019-05-21
-7p26,2022-06-29,2021-07-04
-2p2q,2007-05-29,2007-03-07
-8p2f,2024-05-01,2023-05-16
-7p2g,2022-05-04,2021-07-05
-7p2s,2022-07-27,2021-07-06
-7p2t,2022-07-20,2021-07-06
-8p2a,2023-07-19,2023-05-15
-3p2e,2010-11-17,2010-10-02
-5p2p,1991-10-15,1990-09-01
-2p2m,2007-05-29,2007-03-07
-7p2e,2022-07-27,2021-07-05
-1p2i,2004-04-20,2003-04-15
-6p29,2019-08-07,2019-05-21
-6p2o,2019-07-31,2019-05-21
-1p2k,2004-04-20,2003-04-15
-1p2l,2003-10-07,2003-04-15
-1p2e,2003-11-25,2003-04-15
-2p2j,2007-05-29,2007-03-07
-1p2v,2003-08-05,2003-04-16
-7p2k,2022-03-23,2021-07-06
-7p2z,2022-07-13,2021-07-06
-4p2h,2014-06-25,2014-03-04
-3p23,2011-02-23,2010-10-01
-6p2f,2019-10-16,2019-05-21
-7p2f,2021-10-13,2021-07-05
-8p29,2023-11-22,2023-05-15
-8p23,2023-08-30,2023-05-14
-8p2l,2023-09-06,2023-05-16
-3p2r,2010-10-20,2010-10-03
-4p2p,1992-01-15,1991-10-22
-5p21,1992-01-15,1990-04-30
-7p25,2022-07-13,2021-07-03
-8p2q,2024-06-05,2023-05-16
-1p29,2003-09-02,2003-04-15
-2p2v,2007-07-10,2007-03-07
-7p2r,2022-05-11,2021-07-06
-6p2m,2019-07-31,2019-05-21
-8p2b,2023-07-19,2023-05-15
-6p2i,2019-07-24,2019-05-21
-7p2i,2021-09-08,2021-07-06
-8p2v,2024-04-03,2023-05-16
-8p2c,2023-09-13,2023-05-15
-4p2y,2015-03-11,2014-03-05
-3p27,2010-11-17,2010-10-01
-4p2x,2014-09-17,2014-03-05
-4p2v,2014-09-17,2014-03-04
-4p25,2014-04-02,2014-03-01
-6p2b,2020-04-01,2019-05-21
-2p2r,2007-06-12,2007-03-07
-4p2n,2014-04-02,2014-03-04
-3p2n,2011-03-02,2010-10-03
-4p2o,2014-05-21,2014-03-04
-6p2g,2019-07-24,2019-05-21
-7p2c,2022-04-27,2021-07-05
-8p2j,2023-08-30,2023-05-16
-7p2l,2021-09-08,2021-07-06
-2p20,2007-05-29,2007-03-06
-3p2l,2010-10-20,2010-10-02
-7p2u,2022-07-20,2021-07-06
-1p2u,2003-08-05,2003-04-16
-4p2l,2014-06-25,2014-03-04
-8p2g,2024-05-01,2023-05-16
-7p2w,2022-07-20,2021-07-06
-3p2v,2011-08-24,2010-10-04
-3p2o,2010-10-13,2010-10-03
-8p2s,2023-09-13,2023-05-16
-2p2h,2007-03-20,2007-03-07
-7p2h,2021-09-08,2021-07-06
-8p28,2023-08-30,2023-05-15
-3p2b,2011-08-17,2010-10-01
-6p24,2020-11-18,2019-05-20
-1p2j,2004-04-20,2003-04-15
-7p2n,2022-07-20,2021-07-06
-7p2m,2022-07-20,2021-07-06
-3p2y,2010-10-13,2010-10-04
-7p2d,2022-05-04,2021-07-05
-4p2a,2014-09-03,2014-03-03
-2p2k,2007-10-23,2007-03-07
-7p23,2022-07-13,2021-07-03
-7p24,2022-06-29,2021-07-03
-1p2s,2003-08-05,2003-04-16
-6p25,2019-07-10,2019-05-21
-1p2d,2003-09-02,2003-04-15
-3p2k,2010-11-17,2010-10-02
-2p27,2007-03-13,2007-03-07
-8p22,2024-05-08,2023-05-14
-6p2l,2019-07-31,2019-05-21
-2p2l,2007-05-01,2007-03-07
-1p2a,2003-07-15,2003-04-15
-4p2q,2014-05-21,2014-03-04
-1p2t,2003-08-05,2003-04-16
-7p2v,2022-07-20,2021-07-06
-3p2p,1990-01-15,1989-11-29
-6p2k,2019-07-31,2019-05-21
-4p2e,2014-04-09,2014-03-03
-6p2r,2019-07-10,2019-05-21
-8p20,2023-12-06,2023-05-14
-8p27,2023-08-30,2023-05-15
-4p2r,2014-05-21,2014-03-04
-7p2p,2021-10-06,2021-07-06
-8p2h,2024-05-01,2023-05-16
-6p2c,2019-10-16,2019-05-21
-6p2v,2020-05-27,2019-05-22
-4p27,2014-08-06,2014-03-02
-3p2h,2011-07-06,2010-10-02
-1p2b,2003-09-02,2003-04-15
-6jap,2019-10-30,2019-01-24
-4ja1,2013-02-27,2013-02-18
-5jah,2016-05-25,2016-04-12
-3jae,2015-09-09,2015-06-08
-3jay,2015-08-12,2015-07-06
-6jas,2020-01-29,2019-01-25
-2ja6,2007-02-20,2006-11-23
-3jab,2015-06-10,2015-05-26
-4jav,2013-09-04,2013-02-19
-2jap,2007-02-20,2006-11-29
-2jau,2007-12-11,2006-11-30
-5jac,2016-10-05,2016-04-12
-3jaa,2015-12-23,2015-05-19
-3jaj,2015-08-05,2015-06-16
-1jaf,1998-01-21,1997-06-24
-2jav,2006-12-04,2006-11-30
-8jaw,2024-05-15,2023-05-07
-2ja7,2007-02-20,2006-11-23
-5jai,2016-05-25,2016-04-12
-3jat,2015-08-12,2015-06-20
-1jak,2001-11-21,2001-05-30
-6jai,2019-10-30,2019-01-24
-4jap,2013-04-24,2013-02-19
-5ja8,2017-04-05,2016-04-12
-8jao,2023-11-01,2023-05-06
-3jaf,2015-09-09,2015-06-08
-4jan,2013-04-03,2013-02-18
-1jax,2001-12-21,2001-06-01
-8ja9,2023-10-04,2023-05-05
-6jag,2019-10-30,2019-01-24
-8jad,2023-09-27,2023-05-05
-4jay,2013-07-17,2013-02-19
-2jao,2007-11-20,2006-11-29
-3jan,2015-08-05,2015-06-17
-5jaj,2016-06-01,2016-04-12
-8jak,2024-05-15,2023-05-06
-2jaq,2007-01-03,2006-11-30
-1jaw,1999-04-06,1997-12-22
-2ja8,2007-02-20,2006-11-23
-6jau,2020-01-29,2019-01-25
-5jaz,2016-08-24,2016-04-12
-2jac,2006-12-11,2006-11-27
-3jad,2015-09-09,2015-06-08
-5jad,2016-05-25,2016-04-12
-4jaf,2013-07-17,2013-02-18
-2jaj,2007-02-13,2006-11-29
-5jan,2016-05-25,2016-04-12
-8jay,2024-03-20,2023-05-07
-3jao,2015-08-05,2015-06-18
-1jap,1996-07-11,1996-03-11
-3jag,2015-08-12,2015-06-10
-3jas,2015-08-12,2015-06-19
-6jax,2019-05-15,2019-01-25
-5jax,2017-04-19,2016-04-12
-1jai,1997-07-23,1996-12-15
-6jah,2019-10-30,2019-01-24
-2ja5,2007-02-20,2006-11-23
-1jah,1997-07-23,1996-12-15
-6jam,2019-10-30,2019-01-24
-5ja5,2017-07-05,2016-04-12
-5jao,2016-05-25,2016-04-12
-3jal,2015-08-12,2015-06-16
-2ja1,2007-01-23,2006-11-17
-8jab,2023-09-27,2023-05-05
-2jae,2007-01-30,2006-11-27
-4jaa,2014-02-19,2013-02-18
-8ja5,2024-05-08,2023-05-05
-5ja2,2016-09-14,2016-04-11
-4jaw,2013-03-20,2013-02-19
-4jag,2013-07-17,2013-02-18
-8jaf,2023-12-27,2023-05-05
-8ja6,2024-05-08,2023-05-05
-5jar,2016-05-25,2016-04-12
-3jai,2015-08-12,2015-06-10
-2jaz,2007-04-03,2006-12-01
-3jak,2015-08-12,2015-06-16
-8jaz,2024-05-08,2023-05-07
-8jaa,2023-10-04,2023-05-05
-8ja8,2023-09-27,2023-05-05
-6jan,2019-10-30,2019-01-24
-5jab,2016-07-13,2016-04-12
-8ja2,2024-02-07,2023-05-05
-5ja1,2016-09-14,2016-04-11
-8jai,2024-01-31,2023-05-06
-4ja2,2013-09-04,2013-02-18
-3jaw,2015-08-12,2015-06-30
-5jav,2016-04-27,2016-04-12
-5ja7,2016-11-30,2016-04-12
-1jac,1997-06-05,1996-05-22
-2ja3,2007-01-04,2006-11-21
-3jar,2015-08-12,2015-06-19
-8jaq,2023-10-18,2023-05-06
-3jah,2015-08-12,2015-06-10
-2jai,2007-02-13,2006-11-29
-2jar,2007-11-20,2006-11-30
-5jaq,2016-05-25,2016-04-12
-5jas,2016-05-25,2016-04-12
-2jag,2006-12-14,2006-11-28
-2jah,2007-02-20,2006-11-28
-2jaw,2007-11-20,2006-11-30
-5ja3,2016-08-24,2016-04-11
-4jae,2013-07-17,2013-02-18
-4ja8,2013-04-10,2013-02-18
-1jay,2001-12-21,2001-06-01
-2jam,2007-03-13,2006-11-29
-6jad,2019-10-30,2019-01-24
-8jau,2023-10-18,2023-05-07
-5ja0,2017-01-25,2016-04-11
-8jat,2023-06-21,2023-05-07
-4jac,2013-11-27,2013-02-18
-1jae,1998-11-04,1997-09-30
-8jav,2023-10-18,2023-05-07
-1jaz,2003-09-09,2001-06-01
-5jaw,2017-05-10,2016-04-12
-1jan,1996-07-11,1996-03-11
-4jas,2013-09-04,2013-02-19
-4ja4,2013-05-01,2013-02-18
-3ja8,2015-08-05,2015-05-09
-6jaw,2019-05-15,2019-01-25
-8jah,2024-03-13,2023-05-06
-1ja8,2001-06-06,2001-05-29
-4jaz,2014-02-12,2013-02-19
-8ja4,2024-05-08,2023-05-05
-4jau,2013-09-04,2013-02-19
-8ja1,2024-02-07,2023-05-05
-6jao,2019-10-30,2019-01-24
-8jae,2024-05-08,2023-05-05
-8jac,2023-09-27,2023-05-05
-1ja7,2001-06-15,2001-05-29
-1ja1,2001-08-22,2001-05-29
-6jaq,2019-10-30,2019-01-24
-6jaz,2019-10-30,2019-01-25
-8jax,2023-08-02,2023-05-07
-8jas,2023-10-18,2023-05-07
-5jam,2016-05-25,2016-04-12
-5jap,2016-05-25,2016-04-12
-6jay,2019-05-15,2019-01-25
-1ja0,2001-08-22,2001-05-29
-3jam,2015-08-12,2015-06-17
-3ja1,2015-07-01,2015-03-30
-4jal,2013-07-31,2013-02-18
-8jar,2023-10-18,2023-05-07
-2jal,2007-01-03,2006-11-29
-5jat,2016-05-25,2016-04-12
-1ja9,2001-09-19,2001-05-30
-6jar,2019-10-30,2019-01-24
-2jaf,2006-12-14,2006-11-28
-4jai,2013-05-22,2013-02-18
-3jap,2015-08-12,2015-06-18
-5jal,2016-05-25,2016-04-12
-2jat,2007-01-03,2006-11-30
-2jas,2007-01-03,2006-11-30
-4ja7,2014-02-19,2013-02-18
-6jav,2019-05-15,2019-01-25
-8jal,2023-10-18,2023-05-06
-5jau,2016-05-25,2016-04-12
-4ja9,2014-02-19,2013-02-18
-8ja7,2023-09-27,2023-05-05
-4jaq,2013-04-24,2013-02-19
-4ja3,2013-05-01,2013-02-18
-6jat,2020-01-29,2019-01-25
-4jaj,2013-05-22,2013-02-18
-7ju4,2020-12-16,2020-08-19
-1jut,2001-09-19,2001-08-27
-5ju8,2016-07-20,2016-05-10
-5juu,2016-10-05,2016-05-10
-7ju8,2021-08-04,2020-08-19
-5juo,2016-10-05,2016-05-10
-7ju6,2020-11-11,2020-08-19
-8juy,2023-10-18,2023-06-27
-6ju9,2020-05-13,2019-04-13
-4jua,2013-04-17,2013-03-24
-1jui,2002-08-24,2001-08-24
-7juz,2020-09-30,2020-08-20
-6juq,2020-02-19,2019-04-15
-8jus,2024-06-05,2023-06-27
-7juy,2020-10-07,2020-08-20
-7juq,2020-09-30,2020-08-20
-3ju6,2009-09-29,2009-09-14
-4jum,2014-05-07,2013-03-25
-1jub,2003-09-09,2001-08-24
-4jug,2013-05-01,2013-03-24
-3juo,2009-09-29,2009-09-15
-7ju3,2021-03-24,2020-08-19
-6jue,2020-04-22,2019-04-13
-1juh,2002-05-22,2001-08-24
-1ju6,2001-09-19,2001-08-23
-7juo,2021-09-01,2020-08-20
-7juh,2021-02-03,2020-08-19
-3jue,2010-09-22,2009-09-15
-5jus,2016-10-05,2016-05-10
-8ju0,2024-03-27,2023-06-23
-2jul,2008-04-22,2007-08-30
-8ju6,2024-05-08,2023-06-24
-5ju6,2016-07-13,2016-05-10
-6ju8,2020-05-13,2019-04-13
-4jud,2013-04-17,2013-03-24
-6jux,2020-04-15,2019-04-15
-7jub,2021-02-03,2020-08-19
-6jut,2019-07-24,2019-04-15
-4ju6,2013-11-27,2013-03-24
-6jus,2020-02-19,2019-04-15
-4ju2,2013-07-03,2013-03-24
-7jup,2021-03-31,2020-08-20
-6juo,2020-02-19,2019-04-15
-7juu,2020-09-30,2020-08-20
-4jun,2014-05-07,2013-03-25
-4ju0,2013-05-01,2013-03-24
-5juz,2017-03-15,2016-05-10
-1jug,1997-04-21,1996-10-13
-8jug,2023-11-01,2023-06-26
-6ju4,2020-05-13,2019-04-13
-7ju7,2020-09-09,2020-08-19
-7jue,2021-02-03,2020-08-19
-8jul,2023-11-15,2023-06-26
-2jup,2007-11-06,2007-09-01
-5juv,2017-04-19,2016-05-10
-8juf,2023-11-01,2023-06-26
-5jur,2017-03-01,2016-05-10
-6jub,2020-05-13,2019-04-13
-8ju9,2024-01-17,2023-06-25
-7juv,2020-09-30,2020-08-20
-6juh,2019-11-06,2019-04-13
-5juc,2017-05-24,2016-05-10
-3jup,2009-09-29,2009-09-15
-3jul,2009-10-06,2009-09-15
-6jur,2020-02-19,2019-04-15
-7ju5,2020-11-11,2020-08-19
-7jua,2021-09-22,2020-08-19
-7jug,2021-02-03,2020-08-19
-8jue,2023-10-11,2023-06-26
-4ju4,2013-11-27,2013-03-24
-8juz,2023-10-18,2023-06-27
-7jus,2020-09-30,2020-08-20
-6ju7,2020-05-13,2019-04-13
-5jun,2017-05-17,2016-05-10
-7juc,2021-02-03,2020-08-19
-1jus,2001-12-12,2001-08-27
-8juw,2023-10-18,2023-06-27
-5jum,2016-09-07,2016-05-10
-8ju5,2024-05-08,2023-06-24
-7juf,2021-02-03,2020-08-19
-7jut,2020-09-30,2020-08-20
-5ju7,2017-04-26,2016-05-10
-8jua,2023-11-15,2023-06-26
-5jut,2016-10-05,2016-05-10
-3jun,2009-09-29,2009-09-15
-6jud,2020-05-13,2019-04-13
-3jut,2010-02-02,2009-09-15
-7juj,2021-08-25,2020-08-19
-1juq,2002-02-27,2001-08-26
-3juk,2010-03-31,2009-09-15
-4juk,2014-05-07,2013-03-25
-5juy,2016-10-19,2016-05-10
-7jud,2021-02-03,2020-08-19
-1jup,2001-12-12,2001-08-24
-3juc,2010-02-09,2009-09-15
-3ju9,2010-12-08,2009-09-14
-4ju3,2013-11-27,2013-03-24
-4ju1,2013-07-03,2013-03-24
-3ju4,2010-02-02,2009-09-14
-2ju0,2007-08-28,2007-08-11
-6ju5,2020-05-13,2019-04-13
-3juh,2009-10-20,2009-09-15
-4juf,2013-05-01,2013-03-24
-5jup,2016-10-05,2016-05-10
-6juw,2020-03-25,2019-04-15
-7jur,2020-09-30,2020-08-20
-3ju2,2009-09-22,2009-09-14
-1ju2,2002-09-04,2001-08-23
-6jun,2020-02-19,2019-04-15
-1ju3,2001-12-21,2001-08-23
-5jul,2017-02-22,2016-05-10
-1juy,1997-06-24,1996-09-25
-5ju9,2016-11-16,2016-05-10
-1ju9,2001-09-19,2001-08-24
-3ju5,2009-09-29,2009-09-14
-7ju0,2020-08-26,2020-08-18
-3juq,2009-09-29,2009-09-15
-5jua,2017-03-08,2016-05-10
-5jud,2017-05-24,2016-05-10
-6juj,2020-05-13,2019-04-14
-4juz,2013-08-28,2013-03-25
-3jus,2010-03-02,2009-09-15
-5juh,2017-07-19,2016-05-10
-4juo,2013-08-28,2013-03-25
-4jub,2013-05-08,2013-03-24
-1jum,2001-12-12,2001-08-24
-2jun,2008-03-04,2007-08-31
-8jud,2023-11-01,2023-06-26
-6juu,2020-04-22,2019-04-15
-4juh,2013-05-01,2013-03-24
-6juz,2020-01-15,2019-04-15
-1juj,2001-09-19,2001-08-24
-4ju8,2013-04-17,2013-03-24
-6juc,2020-05-13,2019-04-13
-7juw,2020-09-30,2020-08-20
-6ju1,2019-11-06,2019-04-12
-7jux,2020-09-30,2020-08-20
-5juw,2016-06-22,2016-05-10
-4jul,2014-05-07,2013-03-25
-6jup,2020-02-19,2019-04-15
-4ju7,2013-11-27,2013-03-24
-8jup,2024-01-24,2023-06-27
-8juc,2024-02-28,2023-06-26
-5jub,2016-10-26,2016-05-10
-4jui,2013-05-22,2013-03-24
-3jux,2009-10-20,2009-09-15
-5jug,2016-11-16,2016-05-10
-1juf,2002-03-20,2001-08-24
-3ju7,2009-11-10,2009-09-14
-6jum,2020-02-19,2019-04-15
-4juj,2013-05-01,2013-03-25
-6jul,2020-02-19,2019-04-15
-4ju9,2013-04-17,2013-03-24
-1juv,2003-12-23,2001-08-28
-3ju8,2009-09-22,2009-09-14
-1jue,2003-09-09,2001-08-24
-3jum,2009-09-29,2009-09-15
-4juc,2013-04-17,2013-03-24
-8juv,2024-01-24,2023-06-27
-5jui,2017-03-15,2016-05-10
-8jun,2023-11-15,2023-06-26
-3juv,2010-03-02,2009-09-15
-6juk,2020-05-13,2019-04-14
-8jub,2023-10-11,2023-06-26
-6jua,2020-05-13,2019-04-13
-4juq,2014-04-30,2013-03-25
-7bht,2021-04-21,2021-01-11
-4bhf,2014-03-12,2013-04-02
-1bhn,1999-02-16,1998-06-10
-8bhs,2023-11-01,2022-10-31
-7bhl,2021-07-21,2021-01-11
-6bh9,2018-02-21,2017-10-30
-7bhm,2021-07-21,2021-01-11
-7bh9,2021-02-17,2021-01-11
-3bhe,2008-12-09,2007-11-28
-3bhd,2007-12-11,2007-11-28
-7bhi,2022-07-20,2021-01-11
-7bhw,2021-04-21,2021-01-11
-6bhp,2018-11-07,2017-10-31
-4bhg,2014-04-16,2013-04-02
-1bhx,1998-11-04,1998-06-10
-4bhl,2013-09-04,2013-04-03
-2bha,2005-09-29,2005-01-08
-7bhn,2021-07-21,2021-01-11
-2bh7,2006-06-22,2005-01-07
-3bhi,2008-10-21,2007-11-28
-1bhg,1997-09-17,1996-03-04
-8bhr,2023-11-01,2022-10-31
-7bhr,2021-04-21,2021-01-11
-1bho,1998-11-04,1998-06-10
-6bhn,2018-04-18,2017-10-31
-8bhu,2023-11-15,2022-11-01
-6bh4,2018-03-28,2017-10-29
-1bh5,1998-11-04,1998-06-13
-8bhf,2023-09-06,2022-10-31
-6bhq,2018-02-14,2017-10-31
-3bh7,2008-03-25,2007-11-28
-4bhn,2013-07-03,2013-04-04
-4bh4,2013-04-24,2013-03-29
-3bhk,2008-02-26,2007-11-28
-3bhm,2008-10-21,2007-11-28
-2bh9,2005-04-25,2005-01-08
-7bhd,2022-07-20,2021-01-11
-7bhb,2021-04-21,2021-01-11
-4bh1,2013-04-24,2013-03-29
-3bh9,2008-10-21,2007-11-28
-2bhp,2006-03-09,2005-01-16
-2bhb,2005-09-29,2005-01-08
-7bhh,2022-03-02,2021-01-11
-3bh3,2008-12-23,2007-11-27
-8bhx,2023-09-27,2022-11-01
-6bhy,2018-02-14,2017-10-31
-1bh9,1999-06-22,1998-06-16
-6bh3,2018-03-28,2017-10-29
-8bh9,2023-11-15,2022-10-30
-6bh0,2018-03-28,2017-10-29
-2bhw,2006-05-23,2005-01-19
-7bhx,2021-04-21,2021-01-11
-4bhv,2014-04-09,2013-04-08
-2bh4,2005-05-11,2005-01-07
-6bhb,2018-11-07,2017-10-30
-2bhe,2005-03-09,2005-01-10
-8bh5,2022-11-23,2022-10-29
-2bhc,2005-09-29,2005-01-10
-3bhj,2008-10-21,2007-11-28
-3bhu,2008-02-12,2007-11-29
-3bht,2008-02-12,2007-11-29
-2bhd,2005-09-29,2005-01-10
-2bhs,2005-06-22,2005-01-18
-2bhq,2006-03-09,2005-01-16
-2bhy,2005-03-31,2005-01-20
-2bh5,2005-05-11,2005-01-07
-7bh2,2021-01-27,2021-01-09
-7bh6,2021-07-21,2021-01-10
-6bhk,2019-01-23,2017-10-30
-7bhp,2021-02-03,2021-01-11
-7bhj,2022-03-02,2021-01-11
-4bh5,2013-07-03,2013-03-29
-3bhy,2007-12-25,2007-11-29
-6bhd,2017-12-06,2017-10-30
-3bho,2008-02-19,2007-11-28
-3bhh,2007-12-11,2007-11-28
-8bhq,2023-11-01,2022-10-31
-6bhj,2018-10-31,2017-10-30
-2bhu,2005-03-31,2005-01-18
-4bhm,2014-04-23,2013-04-04
-7bhu,2021-04-21,2021-01-11
-6bhl,2019-01-23,2017-10-30
-8bho,2023-11-01,2022-10-31
-1bh6,1998-11-04,1998-06-15
-2bhx,2005-05-19,2005-01-20
-6bho,2018-04-18,2017-10-31
-6bh2,2018-03-28,2017-10-29
-7bh5,2021-07-21,2021-01-10
-3bh6,2008-03-25,2007-11-28
-1bhf,1998-10-21,1998-06-08
-3bhf,2008-02-26,2007-11-28
-7bhs,2021-04-21,2021-01-11
-3bh4,2008-12-09,2007-11-28
-2bht,2005-06-22,2005-01-18
-1bh2,1998-11-04,1998-06-12
-4bh7,2014-04-16,2013-03-30
-1bhy,1998-11-04,1998-06-10
-8bht,2023-01-11,2022-10-31
-8bhd,2023-01-25,2022-10-31
-7bhc,2021-04-21,2021-01-11
-7bhv,2021-04-21,2021-01-11
-6bha,2018-02-21,2017-10-30
-3bhv,2008-02-12,2007-11-29
-2bhl,2005-04-25,2005-01-13
-4bhq,2013-11-20,2013-04-05
-2bhh,2005-03-09,2005-01-11
-4bh8,2014-04-16,2013-03-30
-2bh2,2005-03-30,2005-01-06
-2bhz,2005-03-31,2005-01-20
-8bhg,2023-11-15,2022-10-31
-8bha,2023-11-01,2022-10-30
-8bhb,2023-11-01,2022-10-30
-6bh1,2018-03-28,2017-10-29
-7bh1,2021-01-27,2021-01-09
-2bhj,2005-03-31,2005-01-12
-8bhk,2023-11-01,2022-10-31
-6bh8,2018-08-15,2017-10-30
-6bhu,2017-12-27,2017-10-31
-8bhh,2023-07-05,2022-10-31
-6bh5,2018-03-28,2017-10-29
-3bhl,2008-12-02,2007-11-28
-4bh3,2013-04-24,2013-03-29
-4bhz,2013-05-22,2013-04-09
-1bhq,1998-11-04,1998-06-10
-8bhi,2023-11-01,2022-10-31
-8bh0,2023-03-08,2022-10-28
-7bha,2021-04-21,2021-01-11
-8bh8,2023-11-08,2022-10-30
-4bh2,2013-04-24,2013-03-29
-2bhf,2005-10-26,2005-01-10
-8bhy,2023-06-07,2022-11-01
-4bh0,2013-04-24,2013-03-29
-2bho,2005-07-06,2005-01-15
-6bh7,2019-01-23,2017-10-30
-2bh3,2005-09-29,2005-01-07
-6bhv,2018-02-28,2017-10-31
-8bhm,2023-11-01,2022-10-31
-2bh1,2005-05-13,2005-01-06
-4bhi,2014-03-12,2013-04-03
-4bhw,2013-08-14,2013-04-08
-7bhk,2021-07-21,2021-01-11
-3bhr,2008-12-02,2007-11-28
-7bh8,2022-04-13,2021-01-10
-3bhx,2008-01-08,2007-11-29
-4pfk,1989-01-09,1988-01-25
-1pfi,1995-01-26,1994-04-06
-6pf1,2019-10-23,2019-06-21
-1pfq,2003-07-01,2003-05-27
-7pfq,2022-08-24,2021-08-11
-6pf7,2019-10-02,2019-06-21
-8pf5,2024-04-03,2023-06-15
-2pfo,2007-05-15,2007-04-05
-7pf1,2022-01-26,2021-08-11
-2pfe,2007-07-03,2007-04-04
-3pfi,2010-11-10,2010-10-28
-1pfr,1997-03-12,1996-12-03
-1pft,1996-08-17,1996-03-27
-7pfj,2021-12-08,2021-08-11
-3pfj,2011-11-02,2010-10-28
-1pfe,2004-06-08,2003-05-26
-7pfp,2022-03-16,2021-08-11
-8pfh,2023-12-06,2023-06-16
-1pfg,2003-06-10,2003-05-27
-4pfz,2014-11-19,2014-05-01
-6pfy,2019-11-20,2019-06-23
-6pf6,2019-10-16,2019-06-21
-6pfb,2019-10-02,2019-06-21
-7pf9,2021-12-08,2021-08-11
-6pfa,2019-10-02,2019-06-21
-1pf7,2004-06-01,2003-05-24
-3pf9,2011-08-31,2010-10-28
-4pfy,2014-09-17,2014-05-01
-7pfm,2022-08-24,2021-08-11
-2pfn,2007-05-15,2007-04-05
-1pfv,2004-02-17,2003-05-27
-7pfb,2021-12-08,2021-08-11
-7pfr,2022-01-19,2021-08-12
-6pf4,2019-10-02,2019-06-21
-3pfh,2010-12-15,2010-10-28
-8pfp,2024-04-24,2023-06-16
-2pf4,2007-08-07,2007-04-03
-4pf8,2014-05-14,2014-04-28
-7pfy,2022-08-24,2021-08-12
-2pfp,2007-05-15,2007-04-05
-3pft,2011-11-02,2010-10-29
-2pfj,2007-10-30,2007-04-05
-6pfj,2019-11-13,2019-06-21
-7pf8,2021-12-08,2021-08-11
-3pf5,2011-09-21,2010-10-27
-1pfy,2004-02-17,2003-05-27
-8pfu,2023-07-19,2023-06-16
-8pf9,2023-11-08,2023-06-15
-7pf7,2021-12-08,2021-08-11
-3pf2,2011-03-02,2010-10-27
-8pf8,2024-01-24,2023-06-15
-8pfy,2023-07-19,2023-06-16
-7pfl,2022-08-24,2021-08-11
-3pfe,2010-11-17,2010-10-28
-6pfv,2019-11-13,2019-06-22
-4pfu,2014-09-17,2014-04-30
-6pfz,2020-07-01,2019-06-23
-7pfo,2021-11-10,2021-08-11
-4pff,2014-12-17,2014-04-29
-1pf5,2003-12-09,2003-05-23
-4pft,2014-09-17,2014-04-30
-3pf7,2011-06-01,2010-10-28
-2pfz,2007-06-12,2007-04-06
-6pfc,2019-10-16,2019-06-21
-8pfo,2024-04-24,2023-06-16
-1pf9,2003-11-04,2003-05-24
-4pf7,2015-06-17,2014-04-28
-6pfh,2019-10-02,2019-06-21
-3pfo,2010-11-10,2010-10-28
-3pfv,2010-12-08,2010-10-29
-3pfx,2011-11-02,2010-10-29
-8pfv,2023-07-19,2023-06-16
-2pfg,2007-09-25,2007-04-04
-2pf2,1994-01-31,1991-12-08
-1pfw,2004-02-17,2003-05-27
-8pfl,2024-04-24,2023-06-16
-4pfw,2014-09-17,2014-04-30
-3pfs,2010-11-10,2010-10-29
-3pfq,2011-02-02,2010-10-28
-3pfp,2011-03-16,2010-10-28
-3pfr,2011-11-02,2010-10-29
-4pfa,2015-10-21,2014-04-28
-4pfo,2015-04-29,2014-04-30
-3pfd,2010-11-10,2010-10-28
-7pfk,2021-12-08,2021-08-11
-2pfh,2007-04-17,2007-04-05
-6pf5,2019-10-02,2019-06-21
-4pfj,2014-10-01,2014-04-29
-8pfg,2024-04-24,2023-06-15
-3pfb,2011-08-31,2010-10-28
-2pfy,2007-06-12,2007-04-06
-8pf4,2024-04-03,2023-06-15
-6pf3,2019-10-02,2019-06-21
-3pfz,2011-11-02,2010-10-29
-1pfx,1996-08-17,1995-07-19
-6pfd,2019-10-02,2019-06-21
-6pfo,2020-02-12,2019-06-21
-8pft,2023-07-19,2023-06-16
-4pfn,2014-12-17,2014-04-30
-3pfg,2010-12-15,2010-10-28
-3pff,2011-10-12,2010-10-28
-7pfs,2022-01-26,2021-08-12
-6pfn,2019-07-03,2019-06-21
-6pfe,2019-10-02,2019-06-21
-4pf9,2015-06-17,2014-04-28
-8pfw,2023-07-19,2023-06-16
-1pfu,2004-02-17,2003-05-27
-3pf3,2011-06-22,2010-10-27
-4pf5,2014-12-17,2014-04-28
-3pfw,2010-12-15,2010-10-29
-4pfq,2014-07-02,2014-04-30
-4pf0,2015-03-18,2014-04-25
-4pfc,2015-06-17,2014-04-28
-8pfe,2023-08-02,2023-06-15
-2pfl,1999-12-15,1999-05-26
-4pfi,2014-05-14,2014-04-29
-8pfj,2024-04-24,2023-06-16
-4pf4,2014-05-14,2014-04-28
-7pfi,2021-12-08,2021-08-11
-6pf9,2019-10-02,2019-06-21
-4pfb,2014-05-14,2014-04-28
-6pfm,2019-07-17,2019-06-21
-2pfq,2007-05-15,2007-04-05
-8pfz,2024-01-10,2023-06-17
-8pfx,2023-07-19,2023-06-16
-2pf8,2007-04-17,2007-04-04
-4pfm,2015-05-06,2014-04-30
-4pfx,2014-07-23,2014-04-30
-1pfk,1989-01-09,1988-01-25
-3pfc,2011-08-31,2010-10-28
-6pff,2019-10-02,2019-06-21
-6pfi,2019-10-02,2019-06-21
-4pf3,2014-11-26,2014-04-28
-4pfh,2014-10-22,2014-04-29
-8pfc,2023-07-05,2023-06-15
-3pf4,2011-09-21,2010-10-27
-1pf3,2003-06-24,2003-05-23
-8pfi,2023-08-16,2023-06-16
-8pf3,2024-04-03,2023-06-15
-7pfn,2022-08-24,2021-08-11
-7pfz,2022-09-14,2021-08-12
-7pfh,2021-12-08,2021-08-11
-8pff,2023-11-08,2023-06-15
-4pfd,2015-10-21,2014-04-28
-6pf8,2019-10-02,2019-06-21
-6pfk,1996-07-11,1996-01-04
-3pfl,2000-05-31,1999-05-14
-7pfg,2021-12-08,2021-08-11
-6pfg,2019-10-02,2019-06-21
-1pf8,2003-12-23,2003-05-24
-3pf8,2011-08-31,2010-10-28
-4pfp,2015-04-29,2014-04-30
-4fkg,2013-05-08,2012-06-13
-6fk5,2018-10-31,2018-01-23
-7fkt,2022-11-02,2022-08-26
-3fk0,2009-02-17,2008-12-15
-4fkl,2013-05-08,2012-06-13
-7fka,2022-11-02,2022-08-26
-4fkz,2013-05-08,2012-06-14
-2fk0,2006-05-02,2006-01-03
-6fkq,2018-03-21,2018-01-24
-1fkd,1994-01-31,1992-12-02
-5fks,2015-11-25,2015-10-19
-7fk4,2022-11-02,2022-08-26
-6fkn,2019-02-06,2018-01-24
-6fkk,2019-02-06,2018-01-24
-6fk8,2018-04-04,2018-01-23
-2fk2,2007-01-16,2006-01-03
-5fk0,2015-11-11,2015-10-14
-3fkw,2009-03-24,2008-12-17
-1fkh,1994-01-31,1993-08-05
-2fko,2007-01-16,2006-01-05
-8fkp,2023-07-12,2022-12-21
-7fku,2022-11-02,2022-08-26
-5fky,2016-01-27,2015-10-20
-8fkw,2023-07-12,2022-12-21
-8fkq,2023-07-12,2022-12-21
-5fkk,2016-04-06,2015-10-17
-5fkb,2016-02-10,2015-10-15
-6fkw,2018-03-21,2018-01-24
-8fk5,2023-05-31,2022-12-20
-8fkr,2023-07-12,2022-12-21
-4fk5,2012-07-25,2012-06-12
-4fke,2012-10-17,2012-06-13
-6fkm,2019-02-06,2018-01-24
-5fkr,2015-11-25,2015-10-19
-4fk3,2012-08-08,2012-06-12
-1fkg,1994-01-31,1993-08-05
-1fko,2000-11-03,2000-08-10
-1fkn,2000-10-09,2000-08-09
-6fkz,2018-05-16,2018-01-25
-4fkb,2013-06-19,2012-06-13
-4fks,2013-05-08,2012-06-13
-6fk2,2019-02-06,2018-01-23
-3fk7,2009-11-03,2008-12-16
-2fkb,2006-02-21,2006-01-04
-7fk6,2022-11-02,2022-08-26
-4fka,2013-02-13,2012-06-13
-8fkg,2024-04-17,2022-12-21
-7fk5,2022-11-02,2022-08-26
-5fkt,2015-11-04,2015-10-19
-7fk7,2022-11-02,2022-08-26
-1fkw,1996-08-01,1996-02-29
-4fkj,2013-05-08,2012-06-13
-7fke,2022-11-02,2022-08-26
-7fks,2022-11-02,2022-08-26
-6fkr,2018-03-28,2018-01-24
-1fkp,2000-11-03,2000-08-10
-7fk3,2022-11-02,2022-08-26
-7fkp,2022-11-02,2022-08-26
-6fke,2018-10-31,2018-01-23
-7fkk,2022-11-02,2022-08-26
-4fk8,2012-06-20,2012-06-12
-3fk1,2009-02-17,2008-12-15
-1fkf,1991-07-15,1991-05-07
-5fkl,2016-04-06,2015-10-17
-6fkt,2018-08-08,2018-01-24
-2fkw,2006-03-28,2006-01-05
-5fka,2016-05-25,2015-10-15
-7fkb,2022-11-02,2022-08-26
-3fku,2009-02-24,2008-12-17
-5fkc,2016-02-10,2015-10-15
-8fks,2023-07-12,2022-12-21
-7fkg,2022-11-02,2022-08-26
-6fka,2018-04-04,2018-01-23
-1fki,1994-01-31,1993-08-05
-7fkc,2022-11-02,2022-08-26
-7fk0,2022-11-02,2022-08-26
-8fkd,2024-04-17,2022-12-21
-8fkt,2023-07-12,2022-12-21
-4fkp,2013-05-08,2012-06-13
-4fki,2013-05-08,2012-06-13
-1fkx,1996-08-01,1996-02-29
-7fky,2022-11-02,2022-08-26
-5fk7,2016-02-10,2015-10-15
-4fkk,2012-10-17,2012-06-13
-2fkh,2006-02-21,2006-01-04
-8fkc,2024-04-17,2022-12-21
-4fkw,2013-05-08,2012-06-13
-5fki,2016-03-16,2015-10-16
-4fk9,2013-06-26,2012-06-13
-2fk4,2006-01-24,2006-01-04
-7fki,2022-11-02,2022-08-26
-5fkq,2015-11-04,2015-10-19
-4fku,2013-05-08,2012-06-13
-3fkb,2009-09-29,2008-12-16
-2fk8,2006-01-17,2006-01-04
-3fkh,2009-01-13,2008-12-16
-3fko,2009-12-22,2008-12-17
-4fk4,2012-12-19,2012-06-12
-7fk1,2022-11-02,2022-08-26
-5fkj,2016-03-16,2015-10-16
-4fky,2012-06-27,2012-06-13
-3fkn,2009-12-22,2008-12-17
-7fkm,2022-11-02,2022-08-26
-5fko,2016-04-06,2015-10-17
-5fkn,2016-04-06,2015-10-17
-7fko,2022-11-02,2022-08-26
-8fkf,2024-04-17,2022-12-21
-4fkv,2013-05-08,2012-06-13
-2fk1,2007-01-16,2006-01-03
-7fkn,2022-11-02,2022-08-26
-6fkx,2018-02-28,2018-01-24
-6fkp,2018-03-21,2018-01-24
-4fkt,2013-05-08,2012-06-13
-8fkb,2023-03-29,2022-12-21
-7fkl,2022-11-02,2022-08-26
-8fky,2023-07-12,2022-12-21
-6fk9,2018-04-04,2018-01-23
-1fk9,2000-11-03,2000-08-09
-7fkw,2022-11-02,2022-08-26
-5fkp,2016-03-30,2015-10-18
-5fkm,2016-04-06,2015-10-17
-7fkj,2022-11-02,2022-08-26
-4fk1,2012-08-08,2012-06-12
-7fkx,2022-11-02,2022-08-26
-6fkh,2018-05-23,2018-01-24
-6fkf,2018-05-23,2018-01-24
-8fku,2023-07-12,2022-12-21
-8fko,2023-04-05,2022-12-21
-6fkj,2018-03-21,2018-01-24
-4fkc,2012-11-07,2012-06-13
-2fke,1994-01-31,1993-01-27
-7fkv,2022-11-02,2022-08-26
-6fky,2018-03-21,2018-01-25
-1fk7,2001-06-06,2000-08-09
-8fkv,2023-07-12,2022-12-21
-4fkd,2013-01-23,2012-06-13
-6fkb,2018-04-04,2018-01-23
-2fkm,2006-04-04,2006-01-04
-3fkv,2009-03-24,2008-12-17
-3fkq,2009-01-06,2008-12-17
-6fko,2019-06-26,2018-01-24
-6fkc,2018-04-04,2018-01-23
-6fk6,2018-04-04,2018-01-23
-6fks,2018-08-08,2018-01-24
-2fky,2006-02-07,2006-01-05
-1fkb,1993-10-31,1992-07-02
-1fk8,2001-01-17,2000-08-09
-2fkc,2006-02-21,2006-01-04
-4fk0,2012-12-19,2012-06-12
-7fkq,2022-11-02,2022-08-26
-4fk2,2012-12-19,2012-06-12
-4fko,2013-05-08,2012-06-13
-7fk9,2022-11-02,2022-08-26
-4fk6,2012-11-07,2012-06-12
-6fki,2018-05-23,2018-01-24
-2fkn,2007-01-02,2006-01-05
-6fku,2018-09-26,2018-01-24
-5fk8,2016-02-10,2015-10-15
-8fke,2024-04-17,2022-12-21
-1fkl,1995-12-07,1995-08-18
-3fkt,2009-01-20,2008-12-17
-7fk2,2022-11-02,2022-08-26
-2fka,2006-05-23,2006-01-04
-7fkz,2022-11-02,2022-08-26
-6fkl,2018-03-21,2018-01-24
-1fkj,1995-12-07,1995-08-18
-2fkf,2006-04-04,2006-01-04
-4fkh,2012-10-17,2012-06-13
-1fkq,2001-02-14,2000-08-10
-7fk8,2022-11-02,2022-08-26
-3fkg,2009-12-22,2008-12-16
-4fkr,2013-05-08,2012-06-13
-7fkr,2022-11-02,2022-08-26
-8fkz,2023-07-12,2022-12-21
-8fkx,2023-07-12,2022-12-21
-3fkr,2010-02-02,2008-12-17
-7fkd,2022-11-02,2022-08-26
-1fkv,2001-02-14,2000-08-10
-8fkl,2023-05-17,2022-12-21
-6fk7,2018-04-04,2018-01-23
-4fkx,2012-06-27,2012-06-13
-8fk4,2023-05-17,2022-12-20
-7fkh,2022-11-02,2022-08-26
-3fkl,2009-12-22,2008-12-17
-6fkd,2018-04-04,2018-01-23
-7fkf,2022-11-02,2022-08-26
-2fk3,2007-01-16,2006-01-04
-4fkq,2013-05-08,2012-06-13
-2fkz,2006-04-04,2006-01-05
-2fk6,2006-03-21,2006-01-04
-3fki,2009-03-10,2008-12-16
-5apr,1991-04-15,1989-08-03
-3apx,2011-02-23,2010-10-21
-7ap9,2021-10-06,2020-10-16
-8apd,2022-10-26,2022-08-09
-8apb,2022-10-26,2022-08-09
-3ap6,2011-01-26,2010-10-12
-8apf,2022-10-26,2022-08-09
-7ap4,2020-12-09,2020-10-15
-2apg,2005-10-04,2005-08-16
-5apg,2016-04-27,2015-09-15
-7apm,2020-10-28,2020-10-18
-3apw,2011-02-23,2010-10-21
-6apt,2018-03-14,2017-08-17
-3ap2,2011-10-26,2010-10-09
-4ap1,2012-05-30,2012-03-30
-8apj,2022-10-26,2022-08-09
-2aph,2006-06-27,2005-08-16
-4ap7,2012-09-26,2012-03-30
-1apy,1996-12-23,1995-06-14
-8apu,2023-06-14,2022-08-10
-7apq,2021-11-10,2020-10-19
-5apn,2015-12-16,2015-09-17
-8ap2,2022-12-14,2022-08-09
-5apf,2016-01-13,2015-09-15
-8apc,2022-10-26,2022-08-09
-6apl,2017-12-20,2017-08-17
-6ap1,2017-12-06,2017-08-16
-7apl,2020-10-28,2020-10-18
-6apj,2017-12-20,2017-08-17
-5ap4,2015-09-23,2015-09-14
-6ap7,2018-03-21,2017-08-17
-1ap5,1998-01-28,1997-07-24
-7aps,2021-11-03,2020-10-19
-6ap6,2018-03-21,2017-08-17
-4ap3,2012-05-30,2012-03-30
-4apx,2012-11-07,2012-04-07
-5ap9,2016-09-28,2015-09-15
-7api,1990-10-15,1988-09-08
-6aps,2018-03-14,2017-08-17
-1apx,1996-03-08,1995-02-01
-7ap5,2021-11-17,2020-10-15
-6apv,2018-03-14,2017-08-18
-4aph,2012-10-17,2012-04-03
-7apf,2020-12-02,2020-10-16
-6apq,2017-10-11,2017-08-17
-1apu,1994-01-31,1991-12-16
-4apb,2012-04-25,2012-03-31
-5apj,2015-11-25,2015-09-16
-6apg,2018-04-04,2017-08-17
-4apz,2013-04-24,2012-04-11
-5ape,2016-01-13,2015-09-15
-7apg,2020-12-02,2020-10-16
-6apw,2018-02-07,2017-08-18
-4apu,2012-04-25,2012-04-06
-8apw,2023-06-14,2022-08-10
-7apy,2021-01-13,2020-10-20
-8apk,2022-10-26,2022-08-09
-5ap6,2015-09-23,2015-09-14
-3apr,1988-01-16,1987-06-22
-3ap9,2011-02-02,2010-10-12
-7apr,2020-12-30,2020-10-19
-8apo,2023-06-21,2022-08-10
-1ap4,1998-07-15,1997-07-24
-8apz,2022-11-16,2022-08-11
-2aps,1999-02-25,1999-02-11
-4apy,2013-02-27,2012-04-09
-8ap5,2024-01-17,2022-08-09
-5ap0,2015-09-23,2015-09-14
-8ap1,2023-08-23,2022-08-09
-8ape,2022-10-26,2022-08-09
-6apb,2018-03-21,2017-08-17
-8apm,2022-11-09,2022-08-10
-7apw,2021-11-10,2020-10-20
-5ap5,2015-09-23,2015-09-14
-7apo,2021-08-04,2020-10-19
-2apo,2005-11-15,2005-08-16
-4apt,2013-03-27,2012-04-05
-4ap4,2012-07-25,2012-03-30
-4apm,2012-12-05,2012-04-04
-5ap2,2015-09-23,2015-09-14
-6aph,2017-08-30,2017-08-17
-8apn,2022-11-16,2022-08-10
-4apo,2013-01-23,2012-04-04
-6ap4,2017-12-20,2017-08-16
-1apb,1992-01-15,1991-11-15
-4ap6,2012-08-08,2012-03-30
-6apr,1991-04-15,1989-08-03
-5apa,2015-09-23,2015-09-15
-7apz,2021-11-03,2020-10-20
-3apc,2011-04-13,2010-10-14
-1apt,1994-01-31,1991-12-16
-4apn,2013-04-17,2012-04-04
-7apt,2021-11-10,2020-10-19
-8apx,2023-05-03,2022-08-10
-7app,2021-03-03,2020-10-19
-3apy,2011-09-14,2010-10-21
-5apc,2016-01-13,2015-09-15
-4ap5,2012-08-08,2012-03-30
-8apa,2022-10-26,2022-08-09
-2ap9,2005-08-30,2005-08-15
-1ap8,1998-01-28,1997-07-25
-3apt,2011-09-14,2010-10-20
-7apu,2022-03-02,2020-10-19
-7ap6,2020-12-02,2020-10-16
-2apc,2006-06-27,2005-08-16
-1ap6,1998-01-28,1997-07-24
-7aph,2020-12-02,2020-10-16
-8ap7,2022-10-26,2022-08-09
-8apq,2023-01-11,2022-08-10
-7ap2,2020-10-28,2020-10-15
-8aph,2022-10-26,2022-08-09
-8apv,2023-06-14,2022-08-10
-1apw,1994-01-31,1991-12-16
-3ap3,2011-10-26,2010-10-09
-1ap9,1998-09-16,1997-07-26
-3ap1,2011-10-26,2010-10-09
-5apk,2015-11-25,2015-09-16
-7ap1,2020-11-11,2020-10-15
-7apv,2020-12-23,2020-10-20
-5apw,2016-01-27,2015-09-17
-4apq,2013-04-24,2012-04-05
-3apf,2011-04-13,2010-10-14
-2apr,1987-07-16,1987-03-19
-8apg,2022-10-26,2022-08-09
-2ap1,2005-09-27,2005-08-15
-5ap7,2015-09-23,2015-09-14
-8api,1990-10-15,1988-09-08
-4aps,2012-06-13,2012-04-05
-4app,2012-06-06,2012-04-04
-8aps,2023-09-20,2022-08-10
-8apt,2023-06-14,2022-08-10
-6ap8,2018-03-21,2017-08-17
-8ap0,2022-09-07,2022-08-09
-7apn,2021-03-03,2020-10-19
-6ap9,2018-08-22,2017-08-17
-3ap7,2011-01-26,2010-10-12
-6apm,2018-04-04,2017-08-17
-7ap3,2020-10-28,2020-10-15
-3apv,2011-02-23,2010-10-21
-6apu,2018-03-14,2017-08-18
-3ap4,2011-01-26,2010-10-11
-4apj,2012-10-17,2012-04-03
-4apr,1991-04-15,1989-08-03
-9api,1990-10-15,1988-09-08
-5apd,2016-01-13,2015-09-15
-8ap6,2022-12-07,2022-08-09
-6apz,2018-08-22,2017-08-18
-7ap8,2021-10-06,2020-10-16
-8ap9,2022-10-26,2022-08-09
-1apz,1996-12-23,1995-06-14
-5aph,2015-11-25,2015-09-16
-5ap1,2015-09-23,2015-09-14
-5apo,2015-12-16,2015-09-17
-6ape,2017-09-13,2017-08-17
-1apv,1994-01-31,1991-12-16
-3apd,2011-04-13,2010-10-14
-7ape,2021-04-28,2020-10-16
-5ap3,2015-09-23,2015-09-14
-4ap0,2012-09-26,2012-03-30
-5y62,2017-09-20,2017-08-10
-1y67,2004-12-21,2004-12-03
-5y6q,2018-01-24,2017-08-13
-6y66,2020-07-08,2020-02-26
-2y6a,2011-10-12,2011-01-20
-5y6z,2017-12-27,2017-08-15
-1y64,2005-01-18,2004-12-03
-7y6n,2023-06-21,2022-06-21
-6y60,2020-07-08,2020-02-26
-4y6q,2016-01-06,2015-02-13
-2y6l,2012-03-07,2011-01-24
-6y6v,2020-03-11,2020-02-27
-7y6l,2023-06-21,2022-06-21
-2y6h,2012-03-07,2011-01-21
-4y6n,2015-07-15,2015-02-13
-1y60,2005-01-11,2004-12-03
-6y6j,2021-03-31,2020-02-26
-2y62,2011-12-14,2011-01-19
-1y65,2004-12-14,2004-12-03
-7y65,2023-03-01,2022-06-18
-6y6n,2021-01-13,2020-02-26
-2y6r,2011-03-23,2011-01-25
-2y65,2011-08-24,2011-01-19
-2y69,2011-02-23,2011-01-20
-8y6b,2024-02-14,2024-02-02
-1y6v,2005-06-21,2004-12-07
-1y66,2005-03-15,2004-12-03
-4y6m,2015-12-09,2015-02-13
-1y6p,2005-03-22,2004-12-06
-7y6y,2023-07-05,2022-06-21
-6y6k,2020-04-08,2020-02-26
-4y6k,2015-03-18,2015-02-13
-2y6g,2012-03-07,2011-01-21
-4y64,2015-09-16,2015-02-12
-6y6z,2020-06-24,2020-02-27
-7y6p,2023-07-05,2022-06-21
-1y6f,2005-08-30,2004-12-06
-5y6k,2018-01-24,2017-08-12
-2y6i,2011-09-28,2011-01-21
-1y6o,2005-03-22,2004-12-06
-5y61,2017-09-20,2017-08-10
-6y6f,2020-03-11,2020-02-26
-7y6f,2023-07-05,2022-06-20
-5y6m,2018-07-04,2017-08-12
-5y65,2018-12-05,2017-08-10
-7y6s,2022-08-03,2022-06-21
-7y6t,2022-08-03,2022-06-21
-2y68,2011-06-08,2011-01-20
-7y67,2023-03-01,2022-06-18
-1y6b,2005-06-07,2004-12-05
-6y6t,2021-01-13,2020-02-27
-4y6a,2015-06-17,2015-02-12
-7y63,2023-06-21,2022-06-18
-2y6n,2011-05-11,2011-01-25
-7y6k,2023-07-19,2022-06-20
-7y6m,2022-07-20,2022-06-21
-2y6d,2011-05-04,2011-01-20
-4y6o,2016-01-06,2015-02-13
-1y6r,2005-03-01,2004-12-06
-2y6k,2012-03-07,2011-01-24
-6y6d,2020-07-22,2020-02-26
-7y68,2023-06-21,2022-06-18
-6y6q,2020-10-14,2020-02-27
-6y62,2020-10-14,2020-02-26
-2y6b,2011-10-12,2011-01-20
-5y66,2017-12-27,2017-08-10
-5y6d,2018-01-24,2017-08-11
-6y63,2020-07-08,2020-02-26
-4y67,2015-04-01,2015-02-12
-2y6z,2011-12-07,2011-01-27
-6y6y,2021-01-27,2020-02-27
-4y6s,2015-04-01,2015-02-13
-4y62,2015-09-16,2015-02-12
-2y6p,2011-08-24,2011-01-25
-4y6u,2015-07-15,2015-02-13
-8y6o,2024-03-20,2024-02-02
-8y6h,2024-04-17,2024-02-02
-4y6p,2015-04-01,2015-02-13
-2y60,2012-02-08,2011-01-19
-4y6v,2015-06-17,2015-02-13
-7y6z,2023-07-05,2022-06-21
-2y6j,2012-03-07,2011-01-24
-2y6q,2011-03-23,2011-01-25
-5y6n,2018-07-04,2017-08-12
-6y64,2020-07-08,2020-02-26
-1y6w,2005-03-01,2004-12-07
-1y6a,2005-06-07,2004-12-05
-4y63,2015-09-16,2015-02-12
-6y6i,2021-03-31,2020-02-26
-2y61,2011-12-14,2011-01-19
-1y6h,2004-12-21,2004-12-06
-2y6f,2011-08-31,2011-01-21
-5y60,2018-01-17,2017-08-10
-5y64,2018-12-05,2017-08-10
-7y6x,2023-07-05,2022-06-21
-6y6h,2020-03-11,2020-02-26
-6y6p,2020-10-14,2020-02-27
-4y6z,2015-06-17,2015-02-13
-6y6b,2021-02-03,2020-02-26
-6y68,2020-10-14,2020-02-26
-5y6e,2018-01-24,2017-08-11
-4y6g,2016-02-10,2015-02-13
-5y6f,2018-07-18,2017-08-11
-2y66,2011-10-19,2011-01-20
-2y6e,2011-04-06,2011-01-20
-6y6u,2020-06-24,2020-02-27
-7y6c,2022-07-20,2022-06-18
-5y6g,2018-07-18,2017-08-11
-7y6i,2022-11-23,2022-06-20
-7y6o,2023-05-24,2022-06-21
-4y6r,2015-04-01,2015-02-13
-2y6o,2011-11-02,2011-01-25
-4y69,2015-06-17,2015-02-12
-1y63,2005-01-04,2004-12-03
-6y6s,2021-01-13,2020-02-27
-2y63,2011-12-14,2011-01-19
-4y6d,2015-09-30,2015-02-12
-7y6d,2023-06-07,2022-06-20
-2y64,2012-03-07,2011-01-19
-7y6w,2023-07-05,2022-06-21
-1y6q,2005-03-01,2004-12-06
-2y67,2011-10-19,2011-01-20
-4y6l,2016-01-06,2015-02-13
-6y6a,2020-07-08,2020-02-26
-6y6o,2021-02-03,2020-02-26
-6y6x,2020-07-08,2020-02-27
-6y6c,2021-02-17,2020-02-26
-7y6v,2022-08-03,2022-06-21
-7y66,2023-03-01,2022-06-18
-8y6i,2024-04-17,2024-02-02
-7y6g,2023-07-05,2022-06-20
-7y6u,2022-08-03,2022-06-21
-7y69,2023-06-21,2022-06-18
-4y61,2015-06-03,2015-02-12
-2y6c,2011-05-04,2011-01-20
-1y6g,2005-08-30,2004-12-06
-7dz8,2021-06-30,2021-01-23
-3dz2,2009-03-10,2008-07-29
-5dze,2016-09-21,2015-09-25
-8dzo,2022-11-30,2022-08-08
-3dzg,2008-11-04,2008-07-29
-6dzm,2018-09-12,2018-07-05
-3dz6,2009-03-10,2008-07-29
-3dzo,2008-09-16,2008-07-30
-2dza,2007-03-27,2006-09-27
-4dzw,2013-01-16,2012-03-01
-5dzx,2016-05-04,2015-09-26
-4dzi,2012-03-21,2012-03-01
-8dzv,2023-07-26,2022-08-08
-8dzj,2023-07-12,2022-08-07
-7dz1,2022-01-26,2021-01-23
-8dz1,2022-10-05,2022-08-06
-5dzq,2015-10-14,2015-09-26
-8dzk,2022-08-24,2022-08-08
-3dzw,2009-08-11,2008-07-30
-4dz9,2013-03-27,2012-02-29
-1dzj,2000-12-06,2000-03-01
-5dz0,2016-05-04,2015-09-25
-8dzy,2022-08-24,2022-08-08
-5dzw,2016-05-04,2015-09-26
-6dzy,2019-04-24,2018-07-05
-1dzz,2000-06-02,2000-03-07
-8dzm,2023-08-16,2022-08-08
-3dza,2008-08-12,2008-07-29
-1dz0,2000-07-04,2000-02-11
-6dzf,2018-09-19,2018-07-03
-1dz8,2000-03-31,2000-02-18
-5dzo,2015-11-25,2015-09-25
-4dz8,2012-08-01,2012-02-29
-2dze,2007-10-16,2006-09-28
-6dzg,2019-07-10,2018-07-03
-6dzv,2019-04-24,2018-07-05
-6dz2,2019-03-20,2018-07-02
-6dzs,2018-07-18,2018-07-05
-4dzs,2012-04-25,2012-03-01
-5dz3,2016-05-04,2015-09-25
-1dz4,2000-07-20,2000-02-16
-8dza,2022-10-05,2022-08-06
-3dz4,2009-03-10,2008-07-29
-5dzp,2016-10-05,2015-09-25
-5dzc,2015-10-14,2015-09-25
-6dz8,2018-12-19,2018-07-03
-1dzi,2001-03-01,2000-03-01
-8dzs,2023-05-03,2022-08-08
-1dzu,2000-06-02,2000-03-07
-6dzq,2018-11-07,2018-07-05
-5dzu,2015-10-21,2015-09-26
-4dz3,2012-03-28,2012-02-29
-3dzf,2008-11-04,2008-07-29
-4dzz,2012-06-13,2012-03-01
-6dz0,2019-03-20,2018-07-02
-6dzl,2018-09-12,2018-07-05
-3dzh,2008-11-04,2008-07-29
-1dz9,2000-03-30,2000-02-18
-7dzn,2022-01-26,2021-01-25
-4dz1,2012-03-21,2012-02-29
-1dzp,2000-12-06,2000-03-06
-1dzx,2000-06-02,2000-03-07
-6dz3,2019-03-20,2018-07-02
-3dzm,2008-12-23,2008-07-30
-7dz2,2022-08-03,2021-01-23
-6dz1,2018-11-14,2018-07-02
-4dzy,2013-03-27,2012-03-01
-7dz6,2022-08-03,2021-01-23
-8dzf,2022-10-26,2022-08-07
-1dzw,2000-06-02,2000-03-07
-6dzo,2019-07-10,2018-07-05
-3dzl,2008-12-30,2008-07-30
-7dz3,2022-08-03,2021-01-23
-1dzn,2000-03-07,2000-03-05
-8dzh,2022-08-31,2022-08-07
-3dzq,2008-08-26,2008-07-30
-6dzz,2019-04-24,2018-07-05
-1dzh,2000-05-26,2000-02-28
-8dzb,2023-04-05,2022-08-06
-7dzz,2022-02-02,2021-01-26
-7dzd,2021-07-14,2021-01-25
-3dz7,2009-03-10,2008-07-29
-3dzc,2008-08-12,2008-07-29
-1dzv,2000-06-02,2000-03-07
-1dzt,2000-04-18,2000-03-07
-5dzv,2016-05-04,2015-09-26
-4dzt,2012-03-28,2012-03-01
-5dzh,2016-05-04,2015-09-25
-3dzy,2008-10-28,2008-07-30
-3dzv,2008-08-19,2008-07-30
-5dzf,2016-09-21,2015-09-25
-8dzt,2022-11-30,2022-08-08
-8dz7,2022-09-07,2022-08-06
-1dzy,2000-06-02,2000-03-07
-6dzw,2019-04-24,2018-07-05
-7dz7,2021-06-30,2021-01-23
-8dzr,2023-05-03,2022-08-08
-4dz7,2013-03-27,2012-02-29
-1dz6,2000-03-30,2000-02-18
-6dzh,2019-07-10,2018-07-04
-8dz9,2022-08-24,2022-08-06
-8dzz,2023-08-30,2022-08-08
-5dzj,2016-10-05,2015-09-25
-5dzt,2015-10-14,2015-09-26
-5dzy,2016-05-04,2015-09-26
-3dzi,2008-11-04,2008-07-29
-8dzp,2023-05-03,2022-08-08
-5dzk,2016-02-17,2015-09-25
-4dz5,2013-03-06,2012-02-29
-1dzm,2000-12-06,2000-03-03
-4dzr,2012-03-14,2012-03-01
-8dzg,2022-10-26,2022-08-07
-5dzi,2016-05-04,2015-09-25
-3dze,2008-08-19,2008-07-29
-4dz0,2013-01-23,2012-02-29
-3dzk,2008-11-04,2008-07-29
-4dzh,2012-03-21,2012-03-01
-3dz8,2008-08-12,2008-07-29
-5dzg,2016-09-21,2015-09-25
-3dz5,2009-03-10,2008-07-29
-4dz4,2012-03-28,2012-02-29
-7dz0,2022-01-26,2021-01-23
-4dz6,2012-03-14,2012-02-29
-6dz4,2019-07-10,2018-07-02
-5dz2,2015-12-09,2015-09-25
-8dz0,2022-10-05,2022-08-06
-1dzg,2000-05-26,2000-02-28
-1dze,2000-08-16,2000-02-25
-8dzq,2023-05-03,2022-08-08
-8dzi,2022-08-31,2022-08-07
-3dzz,2008-08-12,2008-07-30
-8dzd,2023-08-09,2022-08-06
-3dzu,2008-10-28,2008-07-30
-1dzq,2000-06-22,2000-03-07
-8dzc,2023-04-05,2022-08-06
-2dzb,2007-03-27,2006-09-27
-8dzn,2023-08-16,2022-08-08
-8dzl,2023-07-19,2022-08-08
-7dzm,2022-01-26,2021-01-25
-7dz4,2022-08-03,2021-01-23
-8dzx,2022-08-24,2022-08-08
-8dze,2022-10-26,2022-08-07
-5dz1,2016-05-04,2015-09-25
-3dzj,2008-11-04,2008-07-29
-3dzd,2008-11-25,2008-07-29
-8dz6,2022-10-05,2022-08-06
-6dzx,2019-07-10,2018-07-05
-1dzk,2000-12-06,2000-03-01
-6dz5,2018-10-10,2018-07-03
-4dz2,2012-03-28,2012-02-29
-8dzu,2022-08-24,2022-08-08
-8dz2,2022-10-05,2022-08-06
-7dz5,2022-08-03,2021-01-23
-3dz3,2009-03-10,2008-07-29
-6dzd,2019-09-11,2018-07-03
-2dz9,2007-03-26,2006-09-26
-7dz9,2022-03-16,2021-01-25
-5ero,2016-01-20,2015-11-14
-8er6,2022-12-28,2022-10-11
-6er5,2018-10-31,2017-10-17
-5erd,2016-06-22,2015-11-13
-3ero,2008-11-04,2008-10-02
-8er8,2022-11-09,2022-10-11
-2erz,2005-11-08,2005-10-25
-2erq,2006-06-20,2005-10-25
-2er8,2006-04-04,2005-10-24
-7er1,2022-05-11,2021-05-05
-6er3,2018-05-02,2017-10-16
-1ero,2000-05-10,2000-04-06
-5erk,2016-03-02,2015-11-14
-6eri,2018-04-18,2017-10-18
-6erh,2018-10-17,2017-10-18
-7erb,2022-01-19,2021-05-06
-8ern,2023-10-18,2022-10-12
-5eru,2016-05-04,2015-11-15
-3erz,2008-10-21,2008-10-03
-6erk,2018-09-26,2017-10-18
-7er2,2022-04-20,2021-05-05
-4erg,2012-08-22,2012-04-20
-1erm,2000-05-10,2000-04-06
-6erc,2017-12-27,2017-10-17
-7erh,2021-11-24,2021-05-06
-5er8,2016-01-20,2015-11-13
-3erh,2009-03-31,2008-10-02
-2er6,1991-01-15,1990-10-13
-5erp,2016-06-15,2015-11-14
-5err,2016-05-04,2015-11-15
-6er9,2018-09-26,2017-10-17
-2err,2006-01-10,2005-10-25
-5er4,2016-06-08,2015-11-13
-7er7,2022-01-19,2021-05-06
-5ere,2016-08-10,2015-11-14
-7erc,2022-01-19,2021-05-06
-6era,2018-09-26,2017-10-17
-7er8,2022-01-19,2021-05-06
-5erc,2015-12-30,2015-11-13
-5erg,2016-09-14,2015-11-14
-6ern,2018-11-07,2017-10-18
-2er0,1991-01-15,1990-10-20
-5erl,2016-05-11,2015-11-14
-2er9,1991-01-15,1990-10-20
-2ere,2006-04-04,2005-10-24
-5ers,2016-05-04,2015-11-15
-5er7,2016-01-27,2015-11-13
-6erg,2018-10-17,2017-10-18
-5er3,2015-11-25,2015-11-13
-8er1,2023-04-26,2022-10-11
-5erv,2016-05-04,2015-11-15
-8erq,2022-10-26,2022-10-12
-1err,1998-09-16,1997-09-08
-4era,2012-08-22,2012-04-19
-5ert,2016-05-04,2015-11-15
-3erq,2008-11-04,2008-10-02
-4er7,2012-05-16,2012-04-19
-8er7,2022-12-28,2022-10-11
-3er9,2009-06-16,2008-10-01
-3erx,2009-10-13,2008-10-03
-7era,2022-01-19,2021-05-06
-6erw,2018-10-31,2017-10-19
-3ern,2009-08-25,2008-10-02
-3erd,1999-04-08,1999-03-31
-4erd,2012-06-20,2012-04-19
-2erm,2006-10-03,2005-10-25
-2erg,2006-04-04,2005-10-24
-8erp,2023-04-26,2022-10-12
-6ert,2018-10-31,2017-10-19
-5er0,2016-04-13,2015-11-13
-4erw,2012-08-22,2012-04-20
-4erp,2012-07-04,2012-04-20
-5erw,2016-11-16,2015-11-15
-8err,2022-10-26,2022-10-12
-4eru,2012-06-06,2012-04-20
-2ero,2006-06-20,2005-10-25
-4ero,2013-05-29,2012-04-20
-3erc,2009-06-16,2008-10-01
-2er7,1991-01-15,1990-11-12
-7erk,2021-11-24,2021-05-06
-1erq,2000-05-10,2000-04-06
-7ern,2022-05-11,2021-05-06
-3err,2008-11-25,2008-10-03
-2erx,2005-11-01,2005-10-25
-3erg,2009-10-13,2008-10-02
-1erx,2000-05-03,2000-04-06
-3ert,1999-04-08,1999-03-30
-5er5,2016-06-08,2015-11-13
-7er9,2022-01-19,2021-05-06
-1ere,1998-09-16,1997-09-08
-3er8,2009-06-16,2008-10-01
-3ery,2008-11-25,2008-10-03
-6erm,2018-11-07,2017-10-18
-2erb,2005-12-13,2005-10-24
-7erj,2021-11-24,2021-05-06
-4erf,2012-05-23,2012-04-20
-4ere,2012-05-23,2012-04-20
-7er6,2022-01-19,2021-05-06
-1er8,1991-10-15,1989-10-16
-5er9,2016-11-23,2015-11-13
-5erm,2016-01-20,2015-11-14
-8erx,2023-01-25,2022-10-13
-7erm,2022-05-11,2021-05-06
-7erx,2021-12-08,2021-05-08
-4er4,1991-04-15,1991-01-05
-5er1,1991-01-15,1990-11-07
-3erp,2008-11-04,2008-10-02
-2erp,2006-06-20,2005-10-25
-7erd,2022-01-19,2021-05-06
-4erm,2012-07-04,2012-04-20
-5erj,2016-03-02,2015-11-14
-7ere,2022-01-19,2021-05-06
-8era,2022-12-28,2022-10-11
-7eri,2021-11-24,2021-05-06
-8erd,2023-10-18,2022-10-11
-4erk,1999-07-22,1998-07-09
-8erb,2023-10-18,2022-10-11
-8erj,2023-10-25,2022-10-12
-4er6,2012-05-16,2012-04-19
-3er5,1991-04-15,1991-01-05
-8er4,2023-02-22,2022-10-11
-7ero,2022-05-11,2021-05-06
-1erb,1994-01-31,1993-10-01
-4ert,2012-06-13,2012-04-20
-8ers,2022-11-09,2022-10-12
-4ers,2012-08-29,2012-04-20
-3erk,1999-07-22,1998-07-09
-8ero,2023-04-26,2022-10-12
-4eri,2012-08-22,2012-04-20
-8er0,2023-04-26,2022-10-11
-4er2,1991-01-15,1990-10-20
-3eri,2009-03-31,2008-10-02
-7er3,2022-05-18,2021-05-05
-6er4,2018-05-02,2017-10-16
-2erv,2006-04-11,2005-10-25
-2ery,2005-11-08,2005-10-25
-2erj,2006-02-21,2005-10-25
-4er1,1991-01-15,1990-10-14
-4er8,2012-08-15,2012-04-19
-4px9,2015-03-11,2014-03-22
-3px0,2011-10-19,2010-12-09
-3pxn,2011-12-21,2010-12-10
-3pxt,2011-03-23,2010-12-10
-6pxj,2019-12-18,2019-07-26
-1px4,2004-06-15,2003-07-02
-1pxe,2004-02-10,2003-07-03
-6px5,2019-09-04,2019-07-24
-5px1,2017-03-22,2017-02-08
-8pxs,2023-10-18,2023-07-24
-7pxq,2022-01-19,2021-10-08
-5pxa,2017-03-22,2017-02-08
-6px9,2020-01-29,2019-07-25
-5pxh,2017-03-22,2017-02-08
-2px1,2007-05-29,2007-05-14
-5px4,2017-03-22,2017-02-08
-5px3,2017-03-22,2017-02-08
-6pxq,2019-12-18,2019-07-26
-5pxw,2017-03-22,2017-02-08
-6pxz,2019-08-28,2019-07-28
-4pxf,2014-09-17,2014-03-23
-1px6,2003-07-22,2003-07-02
-2pxc,2007-05-29,2007-05-14
-7pxj,2022-08-24,2021-10-08
-7px0,2022-11-16,2021-10-07
-6pxs,2019-10-16,2019-07-26
-1px8,2003-12-23,2003-07-03
-6pxr,2020-07-29,2019-07-26
-8pxl,2023-10-25,2023-07-23
-6pxd,2021-02-10,2019-07-25
-6pxx,2019-10-09,2019-07-28
-1px0,2003-10-07,2003-07-02
-4pxl,2015-03-18,2014-03-24
-4px3,2015-05-13,2014-03-21
-6pxi,2020-07-29,2019-07-26
-3pxz,2011-02-16,2010-12-10
-7pxu,2022-08-24,2021-10-08
-4pxg,2015-03-25,2014-03-24
-2pxa,2007-05-29,2007-05-14
-1pxx,2003-09-09,2003-07-07
-5pxg,2017-03-22,2017-02-08
-1pxn,2004-04-13,2003-07-04
-5pxy,2017-03-22,2017-02-08
-2px0,2007-09-25,2007-05-14
-3px2,2010-12-22,2010-12-09
-7px4,2022-03-02,2021-10-07
-3px6,2011-10-19,2010-12-09
-8pxj,2023-10-25,2023-07-23
-5pxd,2017-03-22,2017-02-08
-8pxk,2023-10-25,2023-07-23
-5pxz,2017-03-22,2017-02-08
-4pxh,2014-07-23,2014-03-24
-7pxe,2021-12-15,2021-10-08
-7pxf,2021-12-15,2021-10-08
-1px2,2004-03-23,2003-07-02
-7px6,2022-05-11,2021-10-08
-5pxf,2017-03-22,2017-02-08
-4pxk,2014-12-17,2014-03-24
-1pxi,2003-12-09,2003-07-04
-4pxo,2014-04-09,2014-03-24
-1pxm,2004-04-13,2003-07-04
-3px9,2011-06-22,2010-12-09
-1px3,2004-06-15,2003-07-02
-5pxp,2017-03-22,2017-02-08
-4pxd,2014-07-23,2014-03-23
-7px7,2022-05-11,2021-10-08
-3pxd,2011-04-20,2010-12-09
-5pxe,2017-03-22,2017-02-08
-4pxn,2015-03-18,2014-03-24
-6pxf,2020-07-29,2019-07-25
-7pxb,2022-01-19,2021-10-08
-8pxm,2023-10-04,2023-07-23
-7pxp,2022-04-06,2021-10-08
-1pxp,2004-04-13,2003-07-04
-3pxy,2011-02-16,2010-12-10
-5pxi,2017-03-22,2017-02-08
-4pxc,2014-07-23,2014-03-23
-3px8,2011-06-22,2010-12-09
-7pxx,2022-04-06,2021-10-08
-7px5,2022-11-02,2021-10-07
-4px5,2015-05-13,2014-03-21
-7pxa,2022-01-19,2021-10-08
-6pxl,2020-07-29,2019-07-26
-5px6,2017-03-22,2017-02-08
-8px0,2023-10-25,2023-07-22
-4pxs,2015-03-18,2014-03-24
-5px8,2017-03-22,2017-02-08
-4pxm,2015-04-08,2014-03-24
-7pxc,2022-01-19,2021-10-08
-5pxc,2017-03-22,2017-02-08
-2pxh,2008-02-05,2007-05-14
-5pxj,2017-03-22,2017-02-08
-3pxk,2011-12-21,2010-12-10
-4px2,2015-05-13,2014-03-21
-7pxi,2022-08-24,2021-10-08
-5pxx,2017-03-22,2017-02-08
-1pxr,2003-12-16,2003-07-06
-5px2,2017-03-22,2017-02-08
-3pxo,2011-03-09,2010-12-10
-1pxo,2004-04-13,2003-07-04
-5px9,2017-03-22,2017-02-08
-8pxn,2023-11-08,2023-07-23
-3pxv,2010-12-29,2010-12-10
-6px2,2019-12-25,2019-07-24
-8px2,2023-10-18,2023-07-22
-7pxl,2022-08-24,2021-10-08
-3pxl,2011-02-16,2010-12-10
-2px4,2007-05-29,2007-05-14
-3pxw,2011-03-23,2010-12-10
-3pxa,2011-04-20,2010-12-09
-8pxv,2024-02-28,2023-07-24
-7pxd,2022-01-19,2021-10-08
-3pxs,2011-03-23,2010-12-10
-4pxx,2015-06-10,2014-03-25
-7pxn,2022-08-24,2021-10-08
-6pxu,2019-09-25,2019-07-27
-3pxu,2010-12-22,2010-12-10
-2px6,2007-07-10,2007-05-14
-1pxs,2003-12-16,2003-07-06
-6pxh,2019-09-25,2019-07-26
-2pxx,2007-05-22,2007-05-14
-7pxg,2021-12-15,2021-10-08
-3pxx,2010-12-29,2010-12-10
-8pxa,2023-10-18,2023-07-22
-7px1,2022-11-02,2021-10-07
-8px9,2023-10-25,2023-07-22
-1px7,2003-07-22,2003-07-02
-7pxm,2022-08-24,2021-10-08
-6pxa,2019-09-25,2019-07-25
-2px5,2007-05-29,2007-05-14
-5pxb,2017-03-22,2017-02-08
-1pxb,1995-02-27,1994-09-27
-5pxn,2017-03-22,2017-02-08
-6pxy,2020-03-18,2019-07-28
-1pxh,2003-08-12,2003-07-04
-7pxr,2022-08-24,2021-10-08
-5pxs,2017-03-22,2017-02-08
-2px8,2007-05-29,2007-05-14
-1pxj,2003-12-09,2003-07-04
-3pxq,2011-02-16,2010-12-10
-3pxc,2011-04-20,2010-12-09
-6px3,2019-08-28,2019-07-24
-1pxk,2003-12-09,2003-07-04
-7px9,2022-01-19,2021-10-08
-3pxe,2011-04-20,2010-12-09
-4pxa,2015-03-11,2014-03-22
-4px6,2014-04-23,2014-03-21
-5pxt,2017-03-22,2017-02-08
-7pxo,2022-11-16,2021-10-08
-5px5,2017-03-22,2017-02-08
-2pxi,2008-01-08,2007-05-14
-2pxz,2008-04-22,2007-05-14
-5pxq,2017-03-22,2017-02-08
-3px3,2010-12-22,2010-12-09
-7pxv,2022-08-24,2021-10-08
-5pxm,2017-03-22,2017-02-08
-8px8,2023-10-18,2023-07-22
-7pxt,2022-08-24,2021-10-08
-1pxg,2003-09-09,2003-07-04
-2pxy,2007-10-09,2007-05-14
-3pxb,2011-04-20,2010-12-09
-4pxz,2014-04-30,2014-03-25
-8pxc,2023-10-25,2023-07-23
-2pxj,2007-06-12,2007-05-14
-4pxv,2015-03-25,2014-03-25
-2px2,2007-05-29,2007-05-14
-1pxl,2003-12-09,2003-07-04
-5pxr,2017-03-22,2017-02-08
-6pxk,2020-07-29,2019-07-26
-7pxk,2022-08-24,2021-10-08
-5px7,2017-03-22,2017-02-08
-2px3,2007-09-25,2007-05-14
-3pxf,2011-02-16,2010-12-09
-8pxt,2024-02-28,2023-07-24
-3px4,2011-10-19,2010-12-09
-5pxu,2017-03-22,2017-02-08
-7pxh,2021-12-15,2021-10-08
-5px0,2017-03-22,2017-02-08
-2pxr,2007-09-25,2007-05-14
-5pxv,2017-03-22,2017-02-08
-7pxy,2022-04-27,2021-10-08
-1pxc,1995-02-27,1994-09-27
-7pxw,2022-08-24,2021-10-08
-4pxy,2014-04-23,2014-03-25
-5pxk,2017-03-22,2017-02-08
-1pxa,1995-02-27,1994-09-27
-7pxs,2022-08-24,2021-10-08
-4pxb,2014-07-23,2014-03-23
-3px1,2012-01-25,2010-12-09
-5pxl,2017-03-22,2017-02-08
-3px7,2011-04-20,2010-12-09
-4pxe,2014-07-23,2014-03-23
-5pxo,2017-03-22,2017-02-08
-3r3b,2012-03-28,2011-03-15
-7r3s,2022-05-18,2022-02-07
-7r3b,2022-07-13,2022-02-07
-1r3y,2003-12-09,2003-10-03
-3r3l,2011-09-14,2011-03-16
-6r3u,2019-06-19,2019-03-21
-7r31,2023-02-15,2022-02-06
-6r37,2020-04-08,2019-03-19
-8r3r,2024-05-22,2023-11-10
-4r3a,2014-12-03,2014-08-14
-6r33,2019-08-28,2019-03-19
-3r3d,2012-03-28,2011-03-15
-7r3u,2023-02-22,2022-02-07
-3r30,2011-05-25,2011-03-15
-1r30,2004-01-13,2003-09-30
-7r37,2023-02-15,2022-02-06
-3r3u,2011-05-04,2011-03-16
-2r3p,2008-01-22,2007-08-29
-1r3i,2003-11-25,2003-10-02
-2r3h,2008-01-22,2007-08-29
-8r34,2024-04-24,2023-11-08
-1r3c,2004-01-20,2003-10-01
-6r3z,2019-07-31,2019-03-21
-4r3j,2014-09-17,2014-08-15
-7r3y,2022-07-27,2022-02-08
-6r3o,2019-08-28,2019-03-20
-6r3w,2020-04-08,2019-03-21
-8r3s,2024-05-22,2023-11-10
-6r3j,2019-08-28,2019-03-20
-6r3x,2020-02-19,2019-03-21
-6r3t,2019-04-10,2019-03-21
-3r3s,2011-03-30,2011-03-16
-3r33,2012-01-25,2011-03-15
-3r3g,2011-05-11,2011-03-15
-7r38,2023-02-15,2022-02-06
-7r3c,2022-04-27,2022-02-07
-4r3v,2015-01-07,2014-08-18
-4r3b,2015-01-21,2014-08-14
-6r38,2020-04-08,2019-03-19
-7r3h,2022-12-14,2022-02-07
-7r35,2022-09-14,2022-02-06
-2r3x,2007-12-18,2007-08-30
-2r36,2008-09-02,2007-08-29
-2r3g,2008-01-22,2007-08-29
-1r3n,2003-11-11,2003-10-02
-7r3i,2022-12-14,2022-02-07
-7r3d,2022-10-19,2022-02-07
-8r3d,2024-03-06,2023-11-08
-6r3d,2020-04-08,2019-03-20
-4r3r,2015-08-12,2014-08-17
-2r3n,2008-01-22,2007-08-29
-2r3b,2007-09-11,2007-08-29
-4r36,2015-05-06,2014-08-14
-7r39,2023-02-15,2022-02-06
-4r39,2014-12-03,2014-08-14
-1r3j,2003-11-25,2003-10-02
-1r34,2004-11-02,2003-09-30
-7r36,2022-09-14,2022-02-06
-3r3y,2011-05-04,2011-03-16
-2r3f,2008-01-22,2007-08-29
-2r3a,2007-09-11,2007-08-29
-6r34,2019-08-28,2019-03-19
-6r3f,2019-08-28,2019-03-20
-4r37,2015-05-06,2014-08-14
-8r3f,2024-03-06,2023-11-08
-2r34,2008-09-02,2007-08-29
-3r3o,2011-03-30,2011-03-16
-6r3k,2019-04-03,2019-03-20
-3r3q,2011-05-04,2011-03-16
-8r3k,2024-02-21,2023-11-09
-3r37,2012-03-28,2011-03-15
-7r3a,2023-02-15,2022-02-06
-7r30,2023-02-15,2022-02-06
-3r34,2012-03-28,2011-03-15
-7r3e,2022-12-14,2022-02-07
-7r3j,2022-12-14,2022-02-07
-6r30,2019-08-28,2019-03-19
-6r3q,2019-05-08,2019-03-20
-6r3v,2019-05-08,2019-03-21
-4r38,2014-12-03,2014-08-14
-2r3q,2008-01-22,2007-08-29
-3r35,2012-03-28,2011-03-15
-4r3n,2014-12-10,2014-08-16
-4r3w,2014-12-10,2014-08-18
-2r38,2008-09-02,2007-08-29
-2r3l,2008-01-22,2007-08-29
-2r35,2008-09-02,2007-08-29
-6r3m,2020-02-05,2019-03-20
-6r32,2019-08-28,2019-03-19
-6r35,2019-06-12,2019-03-19
-6r31,2020-02-05,2019-03-19
-3r3z,2011-05-04,2011-03-16
-2r3r,2008-01-22,2007-08-29
-1r3q,2003-12-09,2003-10-03
-1r3t,2003-12-09,2003-10-03
-3r3v,2011-05-04,2011-03-16
-6r3r,2019-06-19,2019-03-21
-3r3f,2012-03-28,2011-03-15
-3r3r,2011-03-30,2011-03-16
-4r33,2014-09-17,2014-08-14
-2r3j,2008-01-22,2007-08-29
-3r3c,2012-03-28,2011-03-15
-8r37,2024-01-24,2023-11-08
-4r3d,2015-08-19,2014-08-15
-2r3t,2008-09-02,2007-08-30
-6r3y,2020-04-08,2019-03-21
-1r3s,2003-12-09,2003-10-03
-1r3k,2003-11-25,2003-10-02
-7r3f,2022-12-14,2022-02-07
-3r3x,2011-05-04,2011-03-16
-1r3v,2003-12-09,2003-10-03
-1r33,2004-11-02,2003-09-30
-7r34,2022-09-14,2022-02-06
-6r3g,2019-08-28,2019-03-20
-4r3c,2015-02-25,2014-08-14
-1r35,2004-10-05,2003-09-30
-1r37,2004-02-10,2003-09-30
-2r3w,2008-09-02,2007-08-30
-7r3x,2022-07-27,2022-02-08
-7r33,2022-09-14,2022-02-06
-7r3z,2023-01-25,2022-02-08
-1r38,2004-10-12,2003-09-30
-7r3g,2022-12-14,2022-02-07
-4r3u,2015-03-11,2014-08-18
-6r3e,2020-04-08,2019-03-20
-4r3k,2015-03-18,2014-08-16
-6r3s,2020-04-08,2019-03-21
-3r3e,2012-03-14,2011-03-15
-4r34,2014-09-17,2014-08-14
-3r3k,2011-11-16,2011-03-16
-2r3o,2008-01-22,2007-08-29
-8r3v,2024-03-06,2023-11-10
-3r3t,2011-03-30,2011-03-16
-3r32,2012-03-28,2011-03-15
-6r3n,2019-08-28,2019-03-20
-1r3l,2003-11-25,2003-10-02
-1r3u,2004-10-19,2003-10-03
-3r3a,2012-03-28,2011-03-15
-4r3m,2014-11-05,2014-08-16
-1r31,2003-10-14,2003-09-30
-2r3k,2008-01-22,2007-08-29
-2r37,2007-09-11,2007-08-29
-8r3q,2024-05-22,2023-11-10
-1r3w,2003-12-09,2003-10-03
-2r3c,2007-10-02,2007-08-29
-4r3p,2015-08-12,2014-08-17
-6r39,2020-04-08,2019-03-19
-7r32,2023-02-15,2022-02-06
-7r3o,2023-01-25,2022-02-07
-4r3l,2015-03-18,2014-08-16
-6r3i,2019-08-28,2019-03-20
-6r3l,2019-08-28,2019-03-20
-2r3i,2008-01-22,2007-08-29
-8r3p,2024-05-22,2023-11-10
-7r3n,2022-05-04,2022-02-07
-7r3k,2023-02-22,2022-02-07
-3r3w,2011-05-04,2011-03-16
-8r3o,2024-05-22,2023-11-10
-7r3l,2023-01-25,2022-02-07
-7r3v,2022-08-10,2022-02-07
-2r3y,2007-11-27,2007-08-30
-2r3m,2008-01-22,2007-08-29
-5t8t,2016-09-28,2016-09-08
-8t8q,2023-10-11,2023-06-23
-3t8s,2011-09-07,2011-08-01
-7t85,2021-12-29,2021-12-15
-1t87,2004-05-25,2004-05-11
-7t8x,2023-01-25,2021-12-17
-3t8d,2012-08-01,2011-08-01
-1t88,2004-05-25,2004-05-11
-1t84,2004-07-13,2004-05-11
-3t8j,2012-05-16,2011-08-01
-7t88,2021-12-22,2021-12-15
-7t8d,2023-01-11,2021-12-16
-7t8r,2022-06-22,2021-12-16
-5t85,2017-03-08,2016-09-06
-8t8m,2023-10-11,2023-06-22
-5t8w,2017-11-01,2016-09-08
-5t88,2017-09-06,2016-09-06
-8t8w,2023-11-15,2023-06-23
-7t84,2022-12-07,2021-12-15
-8t8n,2023-08-09,2023-06-22
-1t8u,2004-08-31,2004-05-13
-8t8y,2023-11-15,2023-06-23
-1t83,2004-09-28,2004-05-11
-5t8u,2017-05-31,2016-09-08
-6t8l,2020-02-26,2019-10-24
-6t8o,2019-11-20,2019-10-24
-3t8g,2012-08-01,2011-08-01
-5t8j,2017-04-26,2016-09-07
-3t88,2011-08-24,2011-08-01
-6t82,2020-08-19,2019-10-23
-8t8v,2023-11-15,2023-06-23
-6t8m,2020-09-23,2019-10-24
-6t8u,2020-03-04,2019-10-25
-1t8q,2004-08-03,2004-05-13
-1t8i,2005-05-31,2004-05-12
-5t8q,2017-01-11,2016-09-08
-6t89,2020-11-18,2019-10-24
-5t8f,2017-01-11,2016-09-07
-6t81,2020-10-14,2019-10-23
-6t8k,2020-02-26,2019-10-24
-6t80,2020-11-18,2019-10-23
-1t8s,2004-08-17,2004-05-13
-7t8e,2023-01-25,2021-12-16
-5t8h,2017-03-01,2016-09-07
-7t80,2022-12-21,2021-12-15
-5t8o,2017-01-11,2016-09-08
-6t8w,2020-03-04,2019-10-25
-6t8z,2020-11-18,2019-10-25
-7t8p,2023-07-05,2021-12-16
-5t8g,2016-10-26,2016-09-07
-8t82,2023-11-29,2023-06-21
-6t8a,2020-11-18,2019-10-24
-7t89,2023-02-15,2021-12-16
-5t8s,2016-09-28,2016-09-08
-3t8c,2012-08-01,2011-08-01
-1t80,2004-12-21,2004-05-11
-8t85,2024-01-17,2023-06-21
-7t8n,2022-08-03,2021-12-16
-8t8g,2024-03-13,2023-06-22
-3t8q,2011-08-17,2011-08-01
-6t86,2021-03-03,2019-10-24
-7t8y,2022-09-07,2021-12-17
-8t89,2023-11-29,2023-06-22
-1t86,2004-05-25,2004-05-11
-3t8a,2011-08-24,2011-08-01
-7t8q,2023-07-05,2021-12-16
-1t8k,2004-09-07,2004-05-13
-6t88,2021-03-03,2019-10-24
-3t84,2011-10-19,2011-08-01
-5t8z,2016-10-12,2016-09-08
-3t87,2012-08-01,2011-08-01
-8t84,2023-11-29,2023-06-21
-6t8n,2019-11-27,2019-10-24
-6t8f,2020-01-29,2019-10-24
-8t8u,2023-11-15,2023-06-23
-1t8e,2004-10-12,2004-05-12
-6t8e,2020-01-29,2019-10-24
-3t8x,2011-10-26,2011-08-02
-3t8m,2011-11-16,2011-08-01
-5t8y,2016-09-28,2016-09-08
-3t8v,2011-09-28,2011-08-01
-3t8f,2012-08-01,2011-08-01
-5t89,2017-02-01,2016-09-07
-6t8t,2020-08-19,2019-10-24
-3t8o,2012-06-06,2011-08-01
-5t80,2017-03-08,2016-09-06
-1t89,2004-09-14,2004-05-11
-8t81,2024-05-08,2023-06-21
-7t8z,2022-09-07,2021-12-17
-3t80,2011-09-14,2011-07-31
-8t8c,2023-07-19,2023-06-22
-3t85,2011-10-19,2011-08-01
-3t8h,2012-08-01,2011-08-01
-5t8i,2016-12-28,2016-09-07
-6t8g,2019-11-20,2019-10-24
-8t88,2024-03-06,2023-06-22
-6t87,2021-03-03,2019-10-24
-7t86,2023-01-11,2021-12-15
-7t8s,2023-02-15,2021-12-17
-5t8p,2017-01-11,2016-09-08
-5t8e,2017-04-26,2016-09-07
-7t8h,2023-01-25,2021-12-16
-8t8x,2023-11-15,2023-06-23
-7t8m,2022-06-22,2021-12-16
-8t86,2023-11-29,2023-06-21
-6t8r,2020-08-19,2019-10-24
-6t8b,2019-11-20,2019-10-24
-3t8w,2011-09-28,2011-08-01
-1t8h,2004-05-18,2004-05-12
-6t85,2021-03-03,2019-10-24
-6t8h,2020-03-04,2019-10-24
-8t8z,2023-11-15,2023-06-23
-5t8d,2017-05-03,2016-09-07
-3t83,2011-10-19,2011-08-01
-6t8v,2020-03-04,2019-10-25
-3t8i,2012-05-16,2011-08-01
-3t8y,2011-09-14,2011-08-02
-6t8q,2020-03-04,2019-10-24
-8t8l,2023-08-30,2023-06-22
-6t8y,2020-11-18,2019-10-25
-7t8f,2023-01-25,2021-12-16
-8t8b,2023-07-19,2023-06-22
-5t8k,2016-09-28,2016-09-07
-5t8r,2017-04-05,2016-09-08
-3t8n,2011-11-23,2011-08-01
-3t82,2011-10-19,2011-08-01
-1t8x,2005-06-14,2004-05-13
-6t8x,2021-05-12,2019-10-25
-3t81,2011-11-02,2011-08-01
-1t8t,2004-08-31,2004-05-13
-7t8v,2022-05-04,2021-12-17
-7t8t,2022-12-21,2021-12-17
-6t8p,2020-03-04,2019-10-24
-7t8g,2023-01-25,2021-12-16
-8t87,2024-03-06,2023-06-22
-1t85,2004-06-01,2004-05-11
-4lm3,2014-02-26,2013-07-09
-6lm0,2020-10-21,2019-12-24
-3lmw,2010-08-18,2010-02-01
-1lm3,2002-05-15,2002-04-30
-7lmg,2021-08-11,2021-02-05
-4lm8,2015-02-11,2013-07-10
-7lmm,2021-02-17,2021-02-05
-3lmi,2010-03-16,2010-01-30
-4lmf,2013-08-07,2013-07-10
-3lm9,2010-03-09,2010-01-29
-1lmh,2002-06-12,2002-05-01
-3lm1,2010-09-22,2010-01-29
-5lm4,2017-04-19,2016-07-29
-5lmt,2016-10-05,2016-08-01
-3lmx,2011-02-16,2010-02-01
-4lmj,2013-10-30,2013-07-10
-4lmb,2014-06-04,2013-07-10
-7lm6,2021-09-29,2021-02-05
-2lm5,2012-02-15,2011-11-22
-5lmf,2017-08-16,2016-07-30
-7lmn,2021-05-19,2021-02-05
-5lmz,2016-08-24,2016-08-02
-3lmy,2011-02-16,2010-02-01
-5lmg,2017-08-16,2016-07-30
-7lmf,2021-08-11,2021-02-05
-7lm2,2021-04-21,2021-02-05
-6lmr,2020-07-22,2019-12-26
-4lmp,2013-11-06,2013-07-10
-7lms,2022-08-10,2021-02-05
-1lmq,1996-01-01,1994-10-25
-3lmk,2010-02-16,2010-01-30
-5lmu,2016-10-05,2016-08-01
-7lmw,2021-07-28,2021-02-06
-6lm1,2020-10-21,2019-12-24
-5lmp,2016-10-05,2016-08-01
-4lmy,2014-04-02,2013-07-11
-4lma,2014-06-04,2013-07-10
-1lm1,2002-07-31,2002-04-30
-3lmg,2010-04-21,2010-01-30
-3lm0,2010-03-16,2010-01-29
-4lm5,2014-02-12,2013-07-10
-5lmo,2016-10-05,2016-08-01
-4lm1,2014-02-26,2013-07-09
-5lm9,2017-04-05,2016-07-29
-3lm5,2010-03-16,2010-01-29
-3lmm,2010-02-16,2010-01-31
-3lm7,2010-02-23,2010-01-29
-5lmb,2016-09-14,2016-07-29
-4lmx,2014-06-18,2013-07-11
-4lmg,2014-03-05,2013-07-10
-5lmn,2016-10-05,2016-08-01
-7lmj,2021-08-11,2021-02-05
-7lm8,2021-03-31,2021-02-05
-3lmc,2010-02-16,2010-01-29
-7lme,2021-08-11,2021-02-05
-6lm2,2020-07-08,2019-12-24
-7lmd,2021-08-11,2021-02-05
-1lmp,1996-01-01,1994-10-25
-1lmw,1996-01-29,1995-07-26
-4lms,2014-06-18,2013-07-11
-4lm4,2014-02-26,2013-07-10
-7lmh,2021-08-11,2021-02-05
-4lmk,2013-10-30,2013-07-10
-3lmp,2010-04-14,2010-01-31
-1lmo,1996-01-01,1994-10-25
-5lmr,2016-10-05,2016-08-01
-4lmu,2014-02-12,2013-07-11
-1lm6,2003-06-24,2002-04-30
-7lm7,2021-09-29,2021-02-05
-3lmh,2010-03-16,2010-01-30
-7lmi,2021-08-11,2021-02-05
-5lmd,2016-10-19,2016-07-29
-5lme,2017-12-20,2016-07-30
-7lmp,2021-05-19,2021-02-05
-1lmc,1996-01-01,1994-11-14
-7lma,2021-05-12,2021-02-05
-5lm3,2016-11-30,2016-07-29
-5lmk,2017-01-25,2016-08-01
-5lmm,2017-08-16,2016-08-01
-2lml,2012-01-25,2011-12-05
-1lms,2003-03-18,2002-05-02
-5lm6,2017-02-15,2016-07-29
-6lmq,2020-09-23,2019-12-26
-7lmq,2021-05-19,2021-02-05
-3lm8,2010-03-23,2010-01-29
-7lmy,2021-09-15,2021-02-06
-7lm0,2021-09-22,2021-02-04
-7lmt,2021-03-10,2021-02-05
-6lmi,2020-09-23,2019-12-25
-6lmt,2020-07-29,2019-12-26
-1lmj,2003-04-29,2002-05-02
-1lmt,1995-03-31,1995-01-13
-4lm6,2014-06-18,2013-07-10
-4lmh,2014-04-16,2013-07-10
-7lm5,2021-09-29,2021-02-05
-5lmx,2017-03-22,2016-08-02
-1lm4,2003-06-24,2002-04-30
-4lmt,2014-07-16,2013-07-11
-5lmc,2016-10-19,2016-07-29
-7lmb,2021-05-12,2021-02-05
-4lmz,2014-07-16,2013-07-11
-7lm3,2021-06-30,2021-02-05
-7lm9,2021-03-31,2021-02-05
-7lmr,2021-05-19,2021-02-05
-4lm2,2014-02-26,2013-07-09
-3lm4,2010-02-23,2010-01-29
-4lm0,2014-02-26,2013-07-09
-7lmk,2021-02-17,2021-02-05
-7lmc,2021-04-14,2021-02-05
-4lm7,2014-05-28,2013-07-10
-2lmv,2012-08-22,2011-12-12
-4lmn,2013-08-07,2013-07-10
-7lmz,2021-09-15,2021-02-06
-2lmt,2012-08-22,2011-12-12
-4lm9,2014-05-28,2013-07-10
-4lmc,2014-05-28,2013-07-10
-7lm4,2022-02-09,2021-02-05
-1lml,1997-09-17,1997-03-13
-5lmv,2016-10-05,2016-08-01
-3lms,2010-02-16,2010-02-01
-2lms,2012-12-05,2011-12-12
-5lmq,2016-10-05,2016-08-01
-5lm8,2017-05-03,2016-07-29
-7lml,2021-12-15,2021-02-05
-2lmu,2012-08-22,2011-12-12
-7lmo,2021-05-19,2021-02-05
-5lma,2016-09-14,2016-07-29
-1lm2,2002-07-31,2002-04-30
-5lms,2016-10-05,2016-08-01
-4ptz,2014-06-18,2014-03-11
-1pt5,2003-09-09,2003-06-23
-3ptl,2010-12-22,2010-12-03
-2ptz,2007-11-20,2007-05-08
-3ptq,2011-05-18,2010-12-03
-6pta,2019-07-24,2019-07-15
-6ptz,2019-09-04,2019-07-16
-5pt7,2017-03-29,2017-02-07
-6pth,2019-08-07,2019-07-15
-3pt1,2010-12-15,2010-12-02
-6ptp,2020-06-10,2019-07-16
-2pt2,2007-07-10,2007-05-07
-6ptb,2019-09-04,2019-07-15
-4pth,2014-05-14,2014-03-10
-5ptn,2017-03-29,2017-02-07
-1ptg,1996-07-11,1995-05-24
-6ptq,2019-10-09,2019-07-16
-6ptk,2019-09-25,2019-07-16
-7ptr,2021-12-15,2021-09-27
-5pt3,2017-03-29,2017-02-07
-4ptc,2015-04-08,2014-03-10
-1ptk,1994-01-31,1993-04-07
-5pth,2017-03-29,2017-02-07
-7pt3,2022-02-02,2021-09-25
-6pt8,2020-07-22,2019-07-15
-4ptf,2014-04-30,2014-03-10
-5pty,2017-03-29,2017-02-07
-1ptw,2003-11-11,2003-06-23
-2ptw,2007-11-20,2007-05-08
-8pt2,2023-12-27,2023-07-13
-5ptm,2017-03-29,2017-02-07
-5ptl,2017-03-29,2017-02-07
-5ptw,2017-03-29,2017-02-07
-6pt2,2019-12-11,2019-07-14
-4ptk,2014-10-22,2014-03-11
-7ptu,2021-12-15,2021-09-27
-7pt7,2022-06-08,2021-09-26
-8pth,2023-12-27,2023-07-14
-5pto,2017-03-29,2017-02-07
-6pt7,2020-07-22,2019-07-15
-1pt3,2004-03-30,2003-06-22
-6pt0,2020-02-12,2019-07-14
-5ptk,2017-03-29,2017-02-07
-8ptc,2024-01-31,2023-07-14
-8ptg,2024-04-17,2023-07-14
-1pt9,2003-10-07,2003-06-23
-3pta,2010-12-29,2010-12-02
-6pt5,2020-01-22,2019-07-14
-2ptx,2007-11-20,2007-05-08
-6ptv,2019-08-07,2019-07-16
-3pty,2010-12-15,2010-12-03
-8pt6,2023-12-27,2023-07-13
-5pt0,2017-03-29,2017-02-07
-6pte,2019-09-04,2019-07-15
-1ptm,2003-11-04,2003-06-23
-7ptv,2022-08-10,2021-09-27
-4ptg,2015-04-08,2014-03-10
-6ptr,2019-08-07,2019-07-16
-8ptq,2024-01-31,2023-07-14
-7ptg,2022-10-05,2021-09-27
-5ptp,1997-07-07,1997-03-31
-6pts,2020-05-13,2019-07-16
-3pt8,2011-12-07,2010-12-02
-5ptx,2017-03-29,2017-02-07
-3ptg,2011-03-02,2010-12-02
-5pta,2017-03-29,2017-02-07
-5pte,2017-03-29,2017-02-07
-4ptj,2014-05-14,2014-03-10
-3pt9,2010-12-29,2010-12-02
-1pt6,2004-04-13,2003-06-23
-7pth,2022-08-03,2021-09-27
-4ptn,2014-12-03,2014-03-11
-5ptt,2017-03-29,2017-02-07
-7pt2,2022-02-02,2021-09-25
-2pt3,2007-05-22,2007-05-08
-3pt7,2011-12-07,2010-12-02
-7pt4,2022-02-02,2021-09-25
-8ptx,2024-04-17,2023-07-16
-2ptm,2007-06-19,2007-05-08
-4ptb,2014-04-30,2014-03-10
-8ptm,2024-04-17,2023-07-14
-7pt1,2022-02-02,2021-09-25
-5pt1,2017-03-29,2017-02-07
-6pt4,2019-09-25,2019-07-14
-1pt8,2003-09-09,2003-06-23
-5ptr,2017-03-29,2017-02-07
-8ptk,2024-03-27,2023-07-14
-5pt5,2017-03-29,2017-02-07
-7ptf,2022-10-05,2021-09-27
-5pt2,2017-03-29,2017-02-07
-1pt2,2003-10-14,2003-06-22
-2ptf,2007-05-15,2007-05-08
-5ptv,2017-03-29,2017-02-07
-2pty,2007-11-20,2007-05-08
-4ptm,2014-04-02,2014-03-11
-8pty,2024-04-17,2023-07-16
-8pte,2024-01-10,2023-07-14
-4ptv,2014-09-24,2014-03-11
-3ptk,2011-05-18,2010-12-03
-3ptz,2011-06-15,2010-12-03
-7pt6,2022-06-08,2021-09-26
-8pto,2024-04-17,2023-07-14
-5ptg,2017-03-29,2017-02-07
-2ptq,2007-07-03,2007-05-08
-6ptu,2020-01-22,2019-07-16
-2pt9,2008-04-01,2007-05-08
-1ptq,1995-07-31,1995-05-11
-1pto,1995-09-15,1994-03-22
-3pt2,2011-01-19,2010-12-02
-1ptt,1996-08-01,1995-04-21
-5pts,2017-03-29,2017-02-07
-6pt1,2020-01-22,2019-07-14
-6pto,2019-11-20,2019-07-16
-2ptc,1983-01-18,1982-09-27
-6ptn,2019-11-20,2019-07-16
-1ptr,1995-07-31,1995-05-11
-3pt6,2010-12-29,2010-12-02
-4pte,2015-04-08,2014-03-10
-1ptj,2003-10-07,2003-06-23
-8ptj,2023-12-27,2023-07-14
-7ptz,2022-03-16,2021-09-27
-2ptr,2007-07-03,2007-05-08
-7ptj,2022-08-03,2021-09-27
-5ptz,2017-03-29,2017-02-07
-1pty,1998-01-21,1997-01-16
-5ptu,2017-03-29,2017-02-07
-8ptr,2024-01-31,2023-07-14
-5pt8,2017-03-29,2017-02-07
-8pt7,2023-12-27,2023-07-13
-3ptn,1982-03-04,1981-10-26
-5ptq,2017-03-29,2017-02-07
-6pt9,2019-09-25,2019-07-15
-3ptm,2011-05-18,2010-12-03
-5ptj,2017-03-29,2017-02-07
-6pt3,2019-12-11,2019-07-14
-4ptw,2014-09-24,2014-03-11
-1pth,1996-04-11,1995-04-11
-5pt9,2017-03-29,2017-02-07
-6pt6,2019-09-25,2019-07-15
-6ptx,2019-10-09,2019-07-16
-1ptz,2003-09-09,2003-06-23
-5ptb,2017-03-29,2017-02-07
-5ptc,2017-03-29,2017-02-07
-5pt6,2017-03-29,2017-02-07
-2pt6,2008-04-01,2007-05-08
-8ptz,2024-04-17,2023-07-16
-4ptu,2015-03-04,2014-03-11
-1ptu,1996-08-01,1995-04-21
-4pt5,2014-05-21,2014-03-10
-4ptx,2014-09-24,2014-03-11
-2ptn,1982-03-04,1981-10-26
-5pt4,2017-03-29,2017-02-07
-3ptb,1983-01-18,1982-09-27
-5ptf,2017-03-29,2017-02-07
-6ptw,2020-05-13,2019-07-16
-1ptv,1996-08-01,1995-04-21
-7ptm,2022-01-19,2021-09-27
-8dbj,2023-02-15,2022-06-14
-5dbi,2015-11-04,2015-08-21
-7dbn,2021-08-04,2020-10-21
-8dbv,2023-01-25,2022-06-14
-4db1,2012-01-25,2012-01-13
-3dbe,2008-10-07,2008-05-31
-8db9,2022-09-07,2022-06-14
-5db0,2016-03-30,2015-08-20
-4dbf,2012-11-28,2012-01-15
-8dbb,2023-03-08,2022-06-14
-7dbk,2021-10-20,2020-10-20
-6dbo,2018-08-01,2018-05-03
-3dby,2008-07-29,2008-06-02
-1dbg,2000-01-12,1999-11-02
-2db4,2006-12-05,2005-12-15
-4db7,2012-03-28,2012-01-13
-1dbj,1994-01-31,1993-08-24
-8dbw,2023-01-25,2022-06-14
-8dbm,2023-02-15,2022-06-14
-6dbq,2018-08-01,2018-05-03
-6dbc,2019-11-13,2018-05-03
-5db5,2016-08-24,2015-08-20
-5db9,2015-11-11,2015-08-21
-7dbl,2021-04-28,2020-10-20
-6db6,2018-07-11,2018-05-02
-5db2,2016-03-30,2015-08-20
-1dbq,1996-12-07,1996-02-13
-8dbu,2023-01-25,2022-06-14
-7db6,2021-08-18,2020-10-19
-2dbr,2006-06-16,2005-12-16
-1db1,2000-01-31,1999-11-02
-8dbh,2023-02-15,2022-06-14
-8db0,2022-09-28,2022-06-14
-4dbh,2012-11-28,2012-01-15
-3dbg,2009-06-02,2008-05-31
-1dbi,1999-11-18,1999-11-02
-6dbj,2018-08-01,2018-05-03
-7db1,2021-02-10,2020-10-18
-4dbr,2013-01-30,2012-01-16
-8dbr,2023-01-25,2022-06-14
-3dba,2008-07-01,2008-05-30
-4dbs,2012-03-28,2012-01-16
-2dbx,2006-04-18,2005-12-16
-3dbj,2008-11-11,2008-06-01
-5dby,2015-12-23,2015-08-22
-2dbw,2006-04-18,2005-12-16
-3dbh,2008-08-12,2008-05-31
-1dbt,2000-03-06,1999-11-03
-3dbu,2009-03-03,2008-06-02
-3dbf,2008-10-07,2008-05-31
-1dbb,1993-10-31,1992-11-11
-4dbn,2012-04-11,2012-01-16
-3dbx,2008-11-25,2008-06-02
-3dbd,2008-10-07,2008-05-31
-5db8,2015-11-11,2015-08-21
-8db5,2022-06-22,2022-06-14
-4dbz,2013-01-16,2012-01-16
-2db3,2006-05-02,2005-12-14
-2dbq,2006-06-16,2005-12-16
-6dbd,2018-07-18,2018-05-03
-5dba,2015-11-11,2015-08-21
-6dbb,2018-08-29,2018-05-02
-5dbb,2015-11-11,2015-08-21
-5db6,2015-11-11,2015-08-20
-4dbw,2013-03-06,2012-01-16
-2dby,2006-06-16,2005-12-16
-7dbm,2021-08-04,2020-10-21
-7dbj,2021-10-20,2020-10-20
-3dbz,2008-08-05,2008-06-02
-1dbo,2000-01-12,1999-11-03
-1dbp,1994-05-31,1994-01-31
-8dbg,2023-02-15,2022-06-14
-8db6,2022-09-07,2022-06-14
-4dbc,2012-12-05,2012-01-14
-3dbl,2008-08-12,2008-06-01
-8db1,2022-09-28,2022-06-14
-6dbi,2018-08-01,2018-05-03
-8db4,2023-01-25,2022-06-14
-5dbv,2016-03-16,2015-08-22
-1dbn,2000-06-14,1999-11-03
-4dbk,2012-01-25,2012-01-16
-8dbo,2023-02-15,2022-06-14
-8db2,2023-02-01,2022-06-14
-8dbs,2023-01-25,2022-06-14
-1dbr,1997-12-03,1996-02-13
-6dbk,2018-08-29,2018-05-03
-3db7,2008-10-28,2008-05-30
-7dbe,2021-09-01,2020-10-20
-8db7,2022-09-07,2022-06-14
-6dbs,2018-09-19,2018-05-03
-1dbv,1997-07-07,1996-12-20
-3dbv,1997-07-07,1997-01-06
-5dbr,2017-02-22,2015-08-21
-5dbm,2016-04-20,2015-08-21
-2dbl,1994-03-07,1994-02-08
-3dbo,2008-07-15,2008-06-02
-7dbt,2021-10-06,2020-10-21
-8dbl,2023-02-15,2022-06-14
-7db9,2021-10-20,2020-10-19
-3dbm,2008-09-23,2008-06-01
-5dbx,2015-09-23,2015-08-22
-1db4,1999-11-12,1999-11-02
-3dbs,2008-06-17,2008-06-02
-4dbq,2013-01-30,2012-01-16
-6db2,2018-05-16,2018-05-02
-8db3,2023-03-22,2022-06-14
-5dbg,2015-11-04,2015-08-21
-2dbv,1997-07-07,1996-12-19
-3dbn,2009-06-23,2008-06-02
-1dbk,1994-01-31,1993-08-24
-4db8,2012-05-16,2012-01-13
-1db5,1999-11-12,1999-11-02
-4dbv,1997-07-07,1997-01-06
-6dbz,2018-09-19,2018-05-03
-3db6,2008-08-19,2008-05-30
-5db3,2016-03-30,2015-08-20
-6dbr,2018-08-01,2018-05-03
-5dbh,2015-09-09,2015-08-21
-3dbc,2008-10-07,2008-05-31
-7dbc,2021-10-20,2020-10-19
-7db0,2021-02-10,2020-10-18
-7db8,2021-01-13,2020-10-19
-7dbg,2021-09-29,2020-10-20
-5dbs,2016-03-23,2015-08-21
-4db3,2012-01-25,2012-01-13
-8dbq,2023-01-25,2022-06-14
-8dbk,2023-02-15,2022-06-14
-5db7,2015-11-11,2015-08-21
-6dbx,2018-08-01,2018-05-03
-3dbp,2009-06-23,2008-06-02
-6dbh,2019-05-08,2018-05-03
-6dby,2018-09-19,2018-05-03
-2dbz,2006-06-16,2005-12-16
-6db3,2018-11-28,2018-05-02
-5db1,2016-03-30,2015-08-20
-8db8,2022-09-07,2022-06-14
-8dbf,2023-02-15,2022-06-14
-4dbu,2012-03-28,2012-01-16
-5dbf,2015-11-04,2015-08-21
-7db2,2021-02-10,2020-10-18
-5db4,2016-08-24,2015-08-20
-4dbp,2013-01-30,2012-01-16
-7db7,2021-01-13,2020-10-19
-3dbk,2009-07-07,2008-06-01
-8dbn,2023-02-15,2022-06-14
-6dbt,2018-08-01,2018-05-03
-8dba,2023-03-22,2022-06-14
-6db4,2018-11-28,2018-05-02
-6dbu,2018-08-01,2018-05-03
-5dbc,2015-11-11,2015-08-21
-8dbe,2023-02-15,2022-06-14
-7dbs,2021-04-14,2020-10-21
-5dbj,2015-10-07,2015-08-21
-4dbe,2013-01-16,2012-01-14
-1dbm,1994-01-31,1993-08-24
-6db0,2019-11-13,2018-05-02
-7dbu,2021-10-06,2020-10-21
-4dbm,2012-03-21,2012-01-16
-3db3,2008-09-16,2008-05-30
-2db6,2006-06-15,2005-12-15
-6dbw,2018-08-01,2018-05-03
-5dbe,2015-09-09,2015-08-21
-7dbd,2021-10-20,2020-10-19
-6dbn,2018-08-29,2018-05-03
-7dbf,2021-09-29,2020-10-20
-8dbi,2023-02-15,2022-06-14
-7db3,2021-02-10,2020-10-18
-1dbu,2000-06-14,1999-11-03
-8dbp,2023-01-25,2022-06-14
-3dbr,2008-08-12,2008-06-02
-7dbb,2021-10-20,2020-10-19
-8dbt,2023-01-25,2022-06-14
-6dbm,2018-08-29,2018-05-03
-3db8,2008-10-07,2008-05-30
-6dbv,2018-08-01,2018-05-03
-7db4,2021-02-10,2020-10-18
-6dbl,2018-08-01,2018-05-03
-7dba,2021-10-20,2020-10-19
-3ezq,2008-12-23,2008-10-23
-2ez2,2006-07-25,2005-11-10
-6ezs,2018-12-12,2017-11-16
-3ez8,2009-08-04,2008-10-22
-7eze,2022-06-08,2021-06-01
-7ezq,2022-06-01,2021-06-01
-8ezg,2023-07-19,2022-10-31
-8ezc,2024-02-14,2022-10-31
-8ez5,2023-03-22,2022-10-31
-2ez7,2006-07-18,2005-11-10
-4ezr,2013-04-17,2012-05-03
-6ezl,2018-12-12,2017-11-15
-5ezy,2017-01-11,2015-11-27
-8ezm,2023-08-16,2022-11-01
-7ezr,2022-06-01,2021-06-01
-5ezh,2016-02-03,2015-11-26
-1ezz,2000-11-22,2000-05-12
-3ezv,2009-02-03,2008-10-23
-5ezo,2017-01-11,2015-11-26
-8ezx,2023-03-15,2022-11-01
-2ezt,2006-04-25,2005-11-10
-6ezf,2018-04-04,2017-11-15
-2ez1,2006-07-25,2005-11-10
-6eza,2018-09-26,2017-11-14
-6ezh,2018-11-21,2017-11-15
-5ezz,2016-02-24,2015-11-27
-5ezr,2017-05-10,2015-11-26
-7ezc,2022-04-13,2021-06-01
-1ezl,2000-08-09,2000-05-11
-1ez4,2001-12-28,2000-05-10
-5ezl,2017-01-11,2015-11-26
-1ezv,2001-05-16,2000-05-12
-6ez6,2017-12-27,2017-11-14
-1ezm,1993-10-31,1992-01-13
-8ezb,2023-06-14,2022-10-31
-4ez6,2013-07-24,2012-05-02
-8ezp,2023-03-15,2022-11-01
-6ezj,2018-02-07,2017-11-15
-8ezi,2023-01-25,2022-10-31
-4ezl,2013-04-17,2012-05-02
-8ezo,2023-03-15,2022-11-01
-1ezu,2000-06-23,2000-05-11
-8ezl,2023-08-16,2022-11-01
-4ezk,2013-04-17,2012-05-02
-5ez4,2015-12-09,2015-11-26
-7ezl,2021-06-23,2021-06-01
-4ezm,2012-07-18,2012-05-03
-6ezb,2018-09-26,2017-11-14
-4ezo,2013-04-17,2012-05-03
-6ezn,2018-01-17,2017-11-16
-7ezm,2021-08-25,2021-06-01
-4ez7,2012-08-22,2012-05-02
-5ezd,2016-05-18,2015-11-26
-5ez6,2016-12-07,2015-11-26
-5ezw,2016-11-09,2015-11-27
-7ezk,2021-08-25,2021-06-01
-8ez2,2023-01-18,2022-10-31
-4ezc,2012-06-27,2012-05-02
-4ezn,2013-04-17,2012-05-03
-7ezf,2022-06-01,2021-06-01
-7ezt,2022-11-02,2021-06-02
-6ez2,2018-12-12,2017-11-14
-6ezc,2018-09-26,2017-11-14
-4ezq,2013-04-17,2012-05-03
-5ezv,2016-03-09,2015-11-26
-2ezu,2006-04-25,2005-11-10
-3ezt,2008-12-30,2008-10-23
-8ezh,2023-01-25,2022-10-31
-7ezw,2022-06-08,2021-06-02
-6ezi,2018-09-26,2017-11-15
-6ezx,2018-04-11,2017-11-16
-3ez6,2009-06-02,2008-10-22
-8ezf,2023-01-25,2022-10-31
-7ezp,2022-06-01,2021-06-01
-5ezb,2015-12-16,2015-11-26
-3ez9,2009-06-02,2008-10-22
-7ezg,2022-01-12,2021-06-01
-4ez5,2013-02-06,2012-05-02
-6ezq,2017-12-13,2017-11-16
-6ezu,2018-12-12,2017-11-16
-6eze,2018-08-22,2017-11-15
-5ezx,2016-02-24,2015-11-27
-4ezt,2013-04-17,2012-05-03
-2ezv,2006-01-24,2005-11-10
-6ezp,2018-04-11,2017-11-16
-6ezz,2018-08-29,2017-11-16
-6ez9,2018-12-12,2017-11-14
-5ezg,2016-02-03,2015-11-26
-1ezf,2000-10-18,2000-05-10
-4ez3,2012-08-22,2012-05-02
-8ezz,2023-10-11,2022-11-01
-4ez9,2013-07-24,2012-05-02
-4ezw,2013-04-17,2012-05-03
-6ezg,2018-11-21,2017-11-15
-2ez8,2006-04-25,2005-11-10
-5ezp,2016-01-27,2015-11-26
-5ezm,2016-02-17,2015-11-26
-1ez1,2000-08-02,2000-05-09
-1ez0,2000-05-24,2000-05-09
-5ez3,2015-12-09,2015-11-26
-7ezh,2021-08-25,2021-06-01
-8ez4,2023-01-18,2022-10-31
-7ezb,2022-06-08,2021-06-01
-3ezw,2008-11-04,2008-10-23
-7ezd,2022-06-08,2021-06-01
-1ezr,2000-05-24,2000-05-11
-4ezd,2012-06-27,2012-05-02
-5ezi,2017-01-25,2015-11-26
-8ezu,2023-03-15,2022-11-01
-5ezs,2016-04-13,2015-11-26
-1ezq,2000-09-20,2000-05-11
-3ez5,2009-11-10,2008-10-22
-5ez0,2016-06-08,2015-11-26
-8ez8,2023-11-08,2022-10-31
-1ezj,2000-09-20,2000-05-11
-4ezp,2013-04-17,2012-05-03
-4ezx,2013-04-17,2012-05-03
-7ezi,2021-06-23,2021-06-01
-1ez2,2000-12-20,2000-05-09
-7ezj,2022-04-13,2021-06-01
-6ezo,2018-03-28,2017-11-16
-8ez7,2023-11-08,2022-10-31
-5ezt,2016-07-20,2015-11-26
-3ezp,2008-12-30,2008-10-23
-4ez1,2013-05-08,2012-05-02
-6ezm,2018-02-07,2017-11-15
-4ezy,2013-04-17,2012-05-03
-5ezj,2017-01-25,2015-11-26
-8ez3,2023-11-08,2022-10-31
-2ez6,2006-02-07,2005-11-10
-4ezj,2013-04-17,2012-05-02
-3ez3,2008-12-02,2008-10-22
-7ezz,2021-06-23,2021-06-02
-1ez9,2002-01-30,2000-05-10
-8eza,2023-06-14,2022-10-31
-5ez1,2016-03-16,2015-11-26
-1ezs,2000-06-23,2000-05-11
-2ez4,2006-04-25,2005-11-10
-5ez7,2016-02-17,2015-11-26
-5ez5,2016-12-07,2015-11-26
-4eze,2012-07-25,2012-05-02
-3ezx,2009-12-15,2008-10-23
-1ezw,2000-09-06,2000-05-12
-7ezx,2022-09-28,2021-06-02
-8ezv,2023-10-11,2022-11-01
-4ez4,2012-08-08,2012-05-02
-5ez2,2016-09-28,2015-11-26
-2ez9,2006-04-25,2005-11-10
-3ez2,2009-06-02,2008-10-22
-8ez1,2023-02-22,2022-10-30
-4ezs,2013-04-24,2012-05-03
-3ezr,2009-02-03,2008-10-23
-6ezy,2018-08-15,2017-11-16
-8ezj,2023-11-15,2022-11-01
-4ezh,2012-08-08,2012-05-02
-4ezz,2013-04-17,2012-05-03
-4ez8,2013-05-08,2012-05-02
-6uaz,2020-05-20,2019-09-11
-4ua1,2015-07-22,2014-08-07
-3uaz,2012-02-29,2011-10-22
-3uar,2011-11-02,2011-10-21
-4uam,2014-09-17,2014-08-11
-3ua9,2012-01-25,2011-10-21
-6uac,2019-09-25,2019-09-10
-1uae,1997-09-04,1996-09-30
-7uaw,2022-10-05,2022-03-14
-7uaz,2022-08-31,2022-03-14
-3uac,2012-04-11,2011-10-21
-4ua7,2015-06-24,2014-08-08
-6uai,2020-09-16,2019-09-10
-4uas,2014-12-31,2014-08-11
-6uaw,2020-05-20,2019-09-11
-1ua4,2004-02-27,2003-02-27
-5uan,2017-10-18,2016-12-19
-6uaf,2019-09-18,2019-09-10
-6uaj,2020-03-25,2019-09-10
-3ua5,2012-09-12,2011-10-21
-6uaq,2020-05-20,2019-09-11
-7ua6,2022-03-23,2022-03-11
-5uab,2017-05-31,2016-12-19
-5ual,2017-01-11,2016-12-19
-3ua8,2012-01-11,2011-10-21
-4ua4,2014-09-17,2014-08-08
-4uav,2014-12-31,2014-08-11
-7ua5,2022-08-03,2022-03-11
-7uas,2022-05-04,2022-03-14
-4uaa,2015-06-24,2014-08-08
-4uay,2014-11-12,2014-08-11
-7uap,2022-04-27,2022-03-13
-3uag,2000-02-25,1999-02-24
-5uav,2017-03-15,2016-12-20
-3ua1,2011-12-14,2011-10-20
-1uaz,2003-04-15,2003-03-26
-6ua5,2020-03-25,2019-09-10
-8uab,2024-02-07,2023-09-20
-4ua6,2015-06-24,2014-08-08
-4uac,2014-12-10,2014-08-08
-1ual,2003-06-17,2003-03-11
-8uac,2024-02-07,2023-09-20
-8uaf,2023-12-27,2023-09-20
-3ua3,2011-12-14,2011-10-20
-6uau,2020-05-20,2019-09-11
-7uay,2022-08-31,2022-03-14
-6uab,2020-09-16,2019-09-10
-5uac,2017-01-18,2016-12-19
-7uab,2022-11-02,2022-03-12
-6uat,2020-05-20,2019-09-11
-6ua2,2020-03-25,2019-09-10
-4uat,2014-12-31,2014-08-11
-7ua3,2022-08-03,2022-03-11
-6uap,2019-10-30,2019-09-11
-1uaq,2003-04-29,2003-03-14
-1uas,2003-07-01,2003-03-18
-8uap,2023-12-13,2023-09-21
-4uak,2014-10-22,2014-08-10
-7ua7,2023-03-15,2022-03-11
-7ua9,2022-08-03,2022-03-11
-8uaq,2023-12-13,2023-09-21
-1uat,2004-03-30,2003-03-19
-5uah,2017-01-11,2016-12-19
-8uae,2023-12-27,2023-09-20
-7ua4,2022-08-03,2022-03-11
-4ua9,2015-06-24,2014-08-08
-5uam,2017-03-29,2016-12-19
-4uau,2014-12-31,2014-08-11
-3ua7,2012-07-25,2011-10-21
-4uap,2015-10-07,2014-08-11
-6uad,2020-09-16,2019-09-10
-5uao,2017-01-25,2016-12-19
-4uah,2015-08-26,2014-08-09
-7uad,2023-07-26,2022-03-12
-5uat,2017-03-15,2016-12-20
-3uaa,2012-04-11,2011-10-21
-1uad,2003-07-15,2003-03-09
-6uak,2019-12-04,2019-09-10
-1ua2,2004-12-07,2004-08-11
-3uaj,2011-12-14,2011-10-21
-2uag,2000-02-25,1999-02-23
-6uar,2020-05-20,2019-09-11
-7ual,2022-09-14,2022-03-13
-3uae,2012-04-11,2011-10-21
-6uao,2020-09-16,2019-09-11
-7uaf,2022-11-02,2022-03-12
-3ual,2012-01-25,2011-10-21
-3ua6,2012-07-25,2011-10-21
-3uay,2012-02-29,2011-10-22
-5uaq,2017-01-11,2016-12-19
-5uap,2017-04-12,2016-12-19
-7uac,2022-11-02,2022-03-12
-7uat,2022-03-23,2022-03-14
-7uao,2022-07-13,2022-03-13
-7uau,2022-03-23,2022-03-14
-7uaj,2023-03-15,2022-03-13
-4ua3,2015-01-28,2014-08-07
-1ua5,2004-06-29,2003-02-28
-4uax,2014-09-17,2014-08-11
-4uaz,2014-11-12,2014-08-11
-6uae,2020-09-16,2019-09-10
-3uax,2012-02-29,2011-10-22
-6uag,2020-08-05,2019-09-10
-1uag,1998-03-18,1997-03-13
-3uad,2012-04-11,2011-10-21
-7uai,2022-11-02,2022-03-13
-5uag,2017-02-08,2016-12-19
-5uau,2017-03-15,2016-12-20
-3uaw,2012-02-29,2011-10-22
-7uam,2022-07-13,2022-03-13
-5uas,2017-03-29,2016-12-20
-7uar,2022-04-27,2022-03-13
-1ua3,2003-10-14,2003-02-27
-1ua7,2004-05-18,2003-03-03
-1uak,2003-06-17,2003-03-11
-5uaj,2017-01-11,2016-12-19
-6ua4,2020-03-25,2019-09-10
-7uaq,2022-04-27,2022-03-13
-8uak,2024-01-24,2023-09-21
-6uas,2020-05-20,2019-09-11
-7uah,2023-03-15,2022-03-12
-7uae,2022-11-02,2022-03-12
-4uan,2015-08-26,2014-08-11
-7ua1,2022-08-03,2022-03-11
-4uai,2014-11-12,2014-08-09
-4uaj,2015-08-05,2014-08-10
-5uad,2017-05-31,2016-12-19
-1ua0,2004-09-28,2004-08-11
-4uaw,2014-11-12,2014-08-11
-7uaa,2022-08-31,2022-03-11
-6uax,2020-05-20,2019-09-11
-1uam,2003-06-17,2003-03-11
-4ua8,2014-12-03,2014-08-08
-7uan,2022-07-13,2022-03-13
-3uab,2012-04-11,2011-10-21
-3uas,2013-01-09,2011-10-21
-6uah,2019-09-18,2019-09-10
-1ua1,2004-09-28,2004-08-11
-1uay,2003-04-15,2003-03-25
-4ual,2014-10-22,2014-08-10
-2xx3,2011-12-07,2010-11-08
-1xx4,2004-11-23,2004-11-03
-1xx9,2004-11-16,2004-11-04
-5xxk,2017-12-27,2017-07-04
-4xx3,2015-02-18,2015-01-29
-6xx7,2020-04-15,2020-01-27
-5xxo,2017-12-13,2017-07-04
-4xxs,2015-04-01,2015-01-30
-7xx3,2023-12-13,2022-05-28
-2xx7,2011-04-06,2010-11-09
-2xx2,2011-11-16,2010-11-08
-4xxi,2015-12-16,2015-01-30
-4xx0,2015-08-12,2015-01-29
-4xxa,2016-01-27,2015-01-30
-5xxw,2018-10-10,2017-07-05
-2xx9,2011-04-06,2010-11-09
-1xx6,2004-12-21,2004-11-04
-1xxj,2005-03-22,2004-11-05
-6xx2,2020-04-22,2020-01-26
-4xx5,2015-08-05,2015-01-29
-2xxl,2011-02-09,2010-11-10
-7xxy,2023-04-12,2022-05-31
-1xx1,2005-01-18,2004-11-03
-8xxl,2024-05-01,2024-01-18
-5xxj,2018-08-08,2017-07-04
-4xxd,2015-04-29,2015-01-30
-8xxm,2024-05-01,2024-01-18
-1xxt,2004-12-07,2004-11-08
-2xxj,2010-11-24,2010-11-10
-1xxa,1996-03-08,1995-11-03
-2xxi,2011-04-06,2010-11-10
-2xxk,2011-11-23,2010-11-10
-7xx5,2023-05-31,2022-05-28
-4xxf,2015-02-25,2015-01-30
-5xx9,2018-07-11,2017-07-01
-7xxd,2023-05-31,2022-05-29
-7xxm,2023-05-31,2022-05-30
-2xxr,2011-02-09,2010-11-11
-2xxt,2011-02-09,2010-11-12
-4xxh,2015-02-11,2015-01-30
-5xxs,2018-01-03,2017-07-04
-5xxv,2018-10-10,2017-07-05
-4xxg,2015-12-30,2015-01-30
-2xxa,2011-03-02,2010-11-09
-6xxh,2020-04-15,2020-01-27
-1xxx,2006-02-14,2004-11-09
-5xxi,2017-10-25,2017-07-04
-4xxp,2015-02-11,2015-01-30
-2xx0,2011-05-18,2010-11-07
-1xxp,2005-03-22,2004-11-07
-7xxp,2023-05-31,2022-05-30
-4xxo,2015-04-29,2015-01-30
-7xx6,2023-05-31,2022-05-28
-2xx4,2011-11-16,2010-11-08
-2xxq,2011-10-19,2010-11-11
-6xxf,2021-02-10,2020-01-27
-7xxr,2023-05-31,2022-05-30
-7xxt,2023-02-22,2022-05-30
-6xx5,2020-05-27,2020-01-26
-6xxj,2020-04-15,2020-01-27
-4xxl,2015-04-15,2015-01-30
-4xxb,2015-08-12,2015-01-30
-7xxb,2022-08-10,2022-05-29
-6xxy,2020-02-26,2020-01-28
-7xxf,2022-11-16,2022-05-30
-8xx9,2024-02-07,2024-01-18
-7xx4,2023-06-14,2022-05-28
-5xxh,2018-06-13,2017-07-04
-4xx9,2015-10-21,2015-01-29
-7xx0,2023-05-31,2022-05-27
-1xxb,1996-03-08,1995-11-03
-7xxl,2022-09-14,2022-05-30
-1xxi,2004-12-07,2004-11-05
-7xxv,2023-04-12,2022-05-31
-5xxf,2017-12-20,2017-07-03
-5xxe,2017-12-20,2017-07-03
-1xxh,2004-12-07,2004-11-05
-8xxa,2024-02-07,2024-01-18
-2xxp,2011-10-19,2010-11-11
-2xxf,2011-05-18,2010-11-10
-2xxb,2010-11-17,2010-11-09
-6xxg,2021-01-20,2020-01-27
-7xxh,2023-06-07,2022-05-30
-5xxl,2017-12-13,2017-07-04
-1xxf,2004-11-16,2004-11-04
-1xxe,2004-11-23,2004-11-04
-4xx4,2015-02-18,2015-01-29
-5xxt,2018-10-10,2017-07-05
-6xx3,2020-04-22,2020-01-26
-7xxk,2022-06-29,2022-05-30
-2xx1,2011-05-18,2010-11-07
-7xxc,2023-05-31,2022-05-29
-6xx4,2020-04-22,2020-01-26
-4xxw,2016-05-04,2015-01-31
-1xxm,2005-01-18,2004-11-07
-4xxn,2015-02-18,2015-01-30
-6xx6,2020-04-15,2020-01-27
-2xxv,2011-02-09,2010-11-12
-6xxc,2020-11-18,2020-01-27
-5xxm,2017-12-13,2017-07-04
-4xxc,2015-04-08,2015-01-30
-2xxm,2011-10-12,2010-11-10
-7xx1,2023-02-08,2022-05-27
-6xxq,2020-04-15,2020-01-28
-2xx5,2011-11-16,2010-11-08
-4xxv,2015-02-25,2015-01-31
-5xxx,2018-10-10,2017-07-05
-2xxw,2011-02-09,2010-11-12
-2xxg,2011-05-18,2010-11-10
-7xxn,2023-02-22,2022-05-30
-2xx8,2011-04-27,2010-11-09
-7xx2,2022-11-02,2022-05-28
-6xxr,2020-11-04,2020-01-28
-4xx6,2015-02-11,2015-01-29
-6xxt,2020-06-03,2020-01-28
-6xxl,2020-04-15,2020-01-27
-4xxr,2015-03-18,2015-01-30
-2xxh,2011-04-06,2010-11-10
-5xxd,2018-08-29,2017-07-03
-5xxg,2018-08-08,2017-07-03
-4xx1,2015-07-29,2015-01-29
-1xxw,2005-03-15,2004-11-09
-2xxy,2011-02-09,2010-11-12
-2xxx,2011-02-09,2010-11-12
-2xxz,2010-11-24,2010-11-12
-1xxv,2005-03-22,2004-11-08
-5xxz,2018-08-08,2017-07-05
-6xxi,2020-04-15,2020-01-27
-2xxu,2011-02-09,2010-11-12
-6xxx,2021-02-10,2020-01-28
-4xxk,2015-12-16,2015-01-30
-5xxn,2017-12-13,2017-07-04
-8xxn,2024-05-01,2024-01-18
-1xxr,2005-10-25,2004-11-08
-7xxi,2023-06-07,2022-05-30
-5xxr,2018-01-03,2017-07-04
-8do5,2022-12-28,2022-07-12
-3doe,2009-03-03,2008-07-04
-6doh,2018-08-15,2018-06-09
-8dou,2022-09-21,2022-07-14
-8dov,2023-01-25,2022-07-14
-4do7,2012-02-29,2012-02-09
-1dod,1994-11-30,1994-09-06
-7dol,2021-03-17,2020-12-14
-3dol,2008-08-12,2008-07-04
-1doc,1994-11-30,1994-09-06
-8do0,2023-05-24,2022-07-12
-6dok,2018-08-15,2018-06-09
-4doq,2013-08-14,2012-02-10
-1dot,1996-03-08,1995-08-03
-8dow,2023-07-19,2022-07-14
-7dok,2021-12-15,2020-12-14
-6do0,2019-02-06,2018-06-08
-7dog,2021-05-05,2020-12-14
-2doj,2006-05-23,2006-04-30
-4dod,2013-02-20,2012-02-09
-8do1,2023-05-24,2022-07-12
-6do3,2018-12-19,2018-06-08
-2do2,2006-05-16,2006-04-27
-5dow,2016-08-10,2015-09-11
-1do3,2000-01-05,1999-12-18
-6dod,2018-08-15,2018-06-09
-8do3,2023-05-24,2022-07-12
-8dos,2022-07-27,2022-07-14
-1do6,2000-03-24,1999-12-19
-7don,2021-12-22,2020-12-14
-5doq,2016-05-04,2015-09-11
-8doc,2023-05-24,2022-07-12
-4doh,2012-07-18,2012-02-09
-5doz,2015-11-18,2015-09-11
-7dob,2021-12-22,2020-12-13
-3dod,2009-06-23,2008-07-03
-4do6,2012-10-10,2012-02-09
-1dob,1994-11-30,1994-09-06
-5do2,2015-10-14,2015-09-10
-7doo,2020-12-23,2020-12-15
-5doh,2016-09-28,2015-09-11
-5doc,2015-11-25,2015-09-11
-7dow,2022-02-02,2020-12-17
-8doi,2022-11-02,2022-07-13
-1doz,2000-01-12,1999-12-22
-6dox,2018-08-15,2018-06-09
-5dob,2015-11-25,2015-09-11
-1do0,2000-02-18,1999-12-18
-1do2,2000-02-18,1999-12-18
-1dog,1994-01-31,1993-01-12
-4doz,2012-03-21,2012-02-12
-3dog,2008-09-30,2008-07-04
-1doi,1996-08-01,1996-04-08
-2dor,1998-08-12,1998-05-11
-3dox,2008-09-09,2008-07-07
-6dou,2018-08-15,2018-06-09
-6doa,2018-08-15,2018-06-09
-4do4,2012-10-10,2012-02-09
-7do7,2021-02-03,2020-12-12
-6dov,2018-08-15,2018-06-09
-4doe,2013-02-20,2012-02-09
-8doy,2022-08-24,2022-07-14
-3doo,2009-05-05,2008-07-05
-8dor,2022-07-27,2022-07-14
-5dot,2015-12-09,2015-09-11
-6doq,2018-08-15,2018-06-09
-4do1,2012-08-15,2012-02-09
-1do4,2000-01-05,1999-12-18
-8dod,2023-04-05,2022-07-12
-4do3,2013-01-23,2012-02-09
-6doi,2018-08-22,2018-06-09
-3doc,2008-07-29,2008-07-03
-1do5,2000-12-18,1999-12-18
-5doy,2015-12-30,2015-09-11
-7do6,2021-02-03,2020-12-12
-3do3,2009-07-21,2008-07-03
-6do2,2019-06-12,2018-06-08
-7dop,2021-03-24,2020-12-15
-3doy,2009-05-05,2008-07-07
-1doh,2001-06-06,1999-12-20
-5doo,2016-08-10,2015-09-11
-8doh,2022-11-02,2022-07-13
-5do4,2016-09-14,2015-09-10
-4don,2013-02-13,2012-02-09
-6do4,2018-12-19,2018-06-08
-1do8,2000-03-06,1999-12-19
-8dof,2022-08-17,2022-07-13
-8dop,2022-07-27,2022-07-14
-4do0,2012-03-14,2012-02-09
-8dox,2022-09-21,2022-07-14
-1do7,2000-01-05,1999-12-19
-3doz,2009-05-05,2008-07-07
-6dow,2018-08-15,2018-06-09
-6doy,2018-08-15,2018-06-09
-5dos,2016-07-20,2015-09-11
-6do5,2018-12-19,2018-06-08
-4doo,2012-05-09,2012-02-09
-6doj,2018-08-15,2018-06-09
-7doz,2021-10-27,2020-12-17
-4doc,2012-06-13,2012-02-09
-2dob,2006-07-25,2006-04-28
-8do2,2023-05-24,2022-07-12
-5dor,2015-12-02,2015-09-11
-3dou,2008-09-02,2008-07-06
-4dok,2012-05-09,2012-02-09
-5dog,2016-09-28,2015-09-11
-5dox,2015-12-30,2015-09-11
-7doy,2022-02-02,2020-12-17
-7doi,2021-12-15,2020-12-14
-4dou,2012-02-29,2012-02-10
-3do2,2009-07-07,2008-07-03
-6dor,2018-08-15,2018-06-09
-6dos,2018-08-15,2018-06-09
-6dot,2018-08-15,2018-06-09
-6do9,2018-08-15,2018-06-09
-1doe,1994-11-30,1994-09-06
-1dor,1997-04-21,1997-01-14
-6doo,2018-08-15,2018-06-09
-1do9,2000-01-05,1999-12-20
-3do0,2009-07-07,2008-07-03
-3dow,2009-02-24,2008-07-07
-5do9,2016-01-20,2015-09-10
-5doe,2015-11-25,2015-09-11
-6doc,2018-08-15,2018-06-09
-6don,2018-08-15,2018-06-09
-8dok,2023-07-19,2022-07-13
-2doq,2006-06-27,2006-05-03
-6dof,2018-08-15,2018-06-09
-6dog,2018-08-15,2018-06-09
-8do8,2022-11-23,2022-07-12
-3dof,2009-03-03,2008-07-04
-6do8,2018-08-15,2018-06-09
-7do4,2021-09-22,2020-12-11
-6doe,2018-08-15,2018-06-09
-3do1,2009-07-07,2008-07-03
-8dog,2022-11-02,2022-07-13
-4doa,2012-06-13,2012-02-09
-1dos,1997-07-07,1996-06-24
-4do9,2012-06-13,2012-02-09
-6dob,2018-08-15,2018-06-09
-7doh,2021-10-27,2020-12-14
-6dol,2018-08-15,2018-06-09
-6dop,2018-08-15,2018-06-09
-1doj,2000-11-03,1999-12-21
-6doz,2018-08-15,2018-06-09
-5do8,2015-09-30,2015-09-10
-4do5,2012-10-10,2012-02-09
-3dok,2008-08-12,2008-07-04
-2doo,2006-11-28,2006-05-01
-7dor,2021-10-27,2020-12-16
-5dou,2015-12-09,2015-09-11
-8doj,2022-11-02,2022-07-13
-7dox,2022-02-02,2020-12-17
-6dom,2018-08-15,2018-06-09
-6do1,2019-01-30,2018-06-08
-4dob,2012-06-13,2012-02-09
-3dop,2008-10-28,2008-07-05
-1do1,2000-01-05,1999-12-18
-1doa,2000-02-09,1999-12-20
-5dok,2015-11-25,2015-09-11
-4xug,2016-01-27,2015-01-25
-4xux,2015-04-01,2015-01-26
-7xul,2023-05-24,2022-05-18
-2xu1,2011-01-12,2010-10-14
-6xuh,2020-07-29,2020-01-20
-6xum,2021-02-03,2020-01-20
-1xua,2004-11-09,2004-10-26
-1xuh,1998-11-11,1997-10-10
-5xuj,2018-03-14,2017-06-23
-2xue,2011-12-28,2010-10-19
-4xuh,2016-07-27,2015-01-25
-2xup,2010-12-08,2010-10-19
-8xuo,2024-05-22,2024-01-13
-5xu5,2018-06-27,2017-06-22
-6xup,2021-02-03,2020-01-20
-2xuo,2010-12-08,2010-10-19
-6xuu,2021-02-03,2020-01-21
-6xu3,2020-12-09,2020-01-17
-2xuz,2011-08-10,2010-10-22
-7xug,2022-08-10,2022-05-18
-4xus,2016-02-03,2015-01-26
-5xun,2017-07-19,2017-06-23
-7xu0,2022-07-20,2022-05-18
-7xuo,2023-04-26,2022-05-19
-6xut,2021-02-03,2020-01-21
-7xu5,2022-07-20,2022-05-18
-7xue,2022-08-10,2022-05-18
-7xuq,2022-09-28,2022-05-19
-1xu5,2005-05-03,2004-10-25
-6xu4,2020-04-15,2020-01-17
-6xuy,2020-10-28,2020-01-21
-4xuf,2015-04-15,2015-01-25
-1xu4,2004-11-16,2004-10-25
-5xul,2018-06-27,2017-06-23
-4xu1,2015-09-02,2015-01-24
-4xu5,2015-10-14,2015-01-25
-7xu6,2022-07-20,2022-05-18
-8xuv,2024-05-22,2024-01-14
-6xub,2020-04-22,2020-01-17
-1xu2,2004-11-09,2004-10-25
-1xuz,2004-11-02,2004-10-26
-6xuj,2021-03-03,2020-01-20
-7xui,2022-08-10,2022-05-18
-4xu6,2015-10-14,2015-01-25
-2xuk,2010-12-08,2010-10-19
-5xut,2017-08-09,2017-06-26
-2xug,2010-12-08,2010-10-19
-4xuz,2015-04-01,2015-01-26
-4xu0,2015-09-02,2015-01-24
-1xu3,2005-05-10,2004-10-25
-4xu2,2015-09-02,2015-01-24
-4xun,2015-06-03,2015-01-26
-7xuj,2023-05-24,2022-05-18
-6xuv,2021-02-03,2020-01-21
-6xuz,2020-07-08,2020-01-21
-7xu8,2022-06-15,2022-05-18
-2xui,2010-12-08,2010-10-19
-7xua,2023-03-29,2022-05-18
-5xu8,2018-02-28,2017-06-22
-4xul,2016-02-03,2015-01-26
-5xu9,2018-06-27,2017-06-22
-4xuo,2015-06-03,2015-01-26
-7xu1,2022-07-20,2022-05-18
-7xur,2022-12-07,2022-05-19
-1xui,1998-11-11,1997-10-10
-1xu7,2004-11-02,2004-10-25
-6xug,2020-04-22,2020-01-19
-1xud,2005-10-26,2004-10-26
-2xu9,2011-10-26,2010-10-15
-6xuk,2021-02-03,2020-01-20
-5xuu,2017-08-09,2017-06-26
-4xui,2015-03-11,2015-01-26
-6xui,2020-07-29,2020-01-20
-5xuq,2018-06-27,2017-06-24
-4xum,2015-11-04,2015-01-26
-1xuk,1998-11-11,1997-10-10
-6xu0,2021-01-27,2020-01-17
-2xuf,2010-12-08,2010-10-19
-5xup,2017-11-01,2017-06-24
-2xum,2010-12-22,2010-10-19
-5xuf,2018-04-25,2017-06-23
-5xuw,2018-06-27,2017-06-26
-2xu0,2011-04-06,2010-10-14
-7xu3,2022-07-20,2022-05-18
-7xu4,2022-07-20,2022-05-18
-1xuq,2005-07-19,2004-10-26
-6xue,2020-04-22,2020-01-19
-2xu5,2011-01-12,2010-10-14
-2xul,2010-11-03,2010-10-19
-7xuc,2023-03-29,2022-05-18
-4xue,2015-04-15,2015-01-25
-5xux,2018-07-04,2017-06-26
-1xur,2005-10-26,2004-10-26
-6xuq,2020-04-22,2020-01-20
-2xu3,2011-01-12,2010-10-14
-4xud,2015-04-15,2015-01-25
-1xug,1998-12-16,1997-10-10
-2xuu,2011-11-02,2010-10-21
-1xuu,2004-11-02,2004-10-26
-2xud,2010-12-08,2010-10-19
-1xuj,1998-11-11,1997-10-10
-4xub,2015-03-11,2015-01-25
-6xuc,2020-04-22,2020-01-17
-4xua,2015-03-11,2015-01-25
-7xud,2023-03-29,2022-05-18
-6xu2,2020-04-22,2020-01-17
-1xuo,2005-10-26,2004-10-26
-2xu4,2011-01-12,2010-10-14
-5xuk,2018-06-27,2017-06-23
-7xuh,2023-08-02,2022-05-18
-7xum,2023-05-03,2022-05-19
-6xuf,2021-01-27,2020-01-19
-6xun,2021-02-03,2020-01-20
-5xui,2018-03-14,2017-06-23
-1xu1,2004-11-09,2004-10-25
-1xuf,1998-12-16,1997-10-10
-7xub,2023-03-29,2022-05-18
-4xuq,2015-06-03,2015-01-26
-6xux,2021-01-13,2020-01-21
-7xuf,2022-11-09,2022-05-18
-5xuz,2017-08-09,2017-06-26
-1xuc,2005-10-26,2004-10-26
-5xug,2018-06-27,2017-06-23
-4xut,2015-06-03,2015-01-26
-5xu1,2018-01-24,2017-06-22
-5xu2,2018-06-27,2017-06-22
-5xuh,2018-06-27,2017-06-23
-1xu9,2004-11-02,2004-10-25
-5xus,2017-08-09,2017-06-26
-7xu2,2022-07-20,2022-05-18
-6xuo,2020-01-29,2020-01-20
-4xup,2015-06-03,2015-01-26
-2xuq,2010-12-08,2010-10-20
-2xua,2011-01-26,2010-10-17
-6xu1,2020-06-24,2020-01-17
-2xuh,2010-12-08,2010-10-19
-4xu3,2015-09-02,2015-01-24
-4xuc,2015-04-15,2015-01-25
-2xuj,2010-12-08,2010-10-19
-4xuk,2015-10-21,2015-01-26
-4xur,2015-06-03,2015-01-26
-2xuc,2010-10-27,2010-10-18
-8xuq,2024-05-22,2024-01-14
-6f30,2018-08-01,2017-11-27
-4f31,2012-05-30,2012-05-08
-8f3d,2023-01-11,2022-11-09
-5f3m,2015-12-23,2015-12-03
-7f3p,2021-10-27,2021-06-16
-3f3z,2008-12-23,2008-10-31
-1f3l,2001-03-14,2000-06-05
-4f3a,2012-10-03,2012-05-09
-3f3a,2008-12-23,2008-10-30
-4f3s,2012-05-23,2012-05-09
-7f3v,2021-12-29,2021-06-17
-1f3x,2001-10-03,2000-06-06
-6f3b,2018-10-10,2017-11-28
-4f3i,2012-09-12,2012-05-09
-2f34,2006-04-04,2005-11-18
-2f3c,2006-12-05,2005-11-20
-3f35,2009-07-14,2008-10-30
-2f3y,2005-12-27,2005-11-22
-8f3l,2023-07-05,2022-11-10
-5f3f,2016-12-07,2015-12-02
-1f3d,2000-09-13,2000-06-02
-4f32,2012-05-23,2012-05-08
-4f35,2012-10-24,2012-05-08
-4f3c,2013-05-01,2012-05-09
-5f3c,2016-01-20,2015-12-02
-1f3b,2000-10-18,2000-06-01
-3f3c,2008-12-23,2008-10-30
-8f3p,2023-07-05,2022-11-10
-6f34,2018-02-14,2017-11-27
-2f3d,2006-04-25,2005-11-21
-7f3b,2022-04-27,2021-06-16
-6f35,2019-03-13,2017-11-28
-2f3z,2005-12-27,2005-11-22
-4f3z,2012-07-04,2012-05-09
-1f35,2001-08-15,2000-05-31
-7f3g,2021-08-18,2021-06-16
-4f3v,2012-06-06,2012-05-09
-6f39,2018-01-24,2017-11-28
-2f32,2006-04-25,2005-11-18
-5f38,2016-07-13,2015-12-02
-5f3z,2016-02-24,2015-12-03
-7f3q,2022-06-22,2021-06-16
-3f38,2009-07-14,2008-10-30
-2f38,2006-10-31,2005-11-18
-2f3p,2006-05-09,2005-11-22
-1f3t,2000-11-22,2000-06-06
-6f3j,2018-02-28,2017-11-28
-5f3w,2016-03-02,2015-12-03
-6f3n,2018-08-08,2017-11-28
-5f3g,2016-01-20,2015-12-02
-4f3d,2012-10-03,2012-05-09
-6f3h,2018-01-17,2017-11-28
-5f32,2016-01-20,2015-12-02
-8f3i,2023-07-05,2022-11-10
-3f3e,2008-12-23,2008-10-30
-3f37,2009-07-14,2008-10-30
-8f3u,2023-07-05,2022-11-10
-3f34,2009-07-14,2008-10-30
-6f3k,2018-03-14,2017-11-28
-7f3o,2021-07-28,2021-06-16
-2f3u,2006-05-09,2005-11-22
-6f3a,2018-01-17,2017-11-28
-3f3r,2009-10-20,2008-10-31
-6f33,2018-08-01,2017-11-27
-5f3d,2016-08-31,2015-12-02
-2f35,2006-04-04,2005-11-18
-2f3b,2006-04-25,2005-11-20
-3f32,2009-07-14,2008-10-30
-1f3p,2001-06-06,2000-06-06
-3f3t,2009-03-03,2008-10-31
-6f3g,2018-05-23,2017-11-28
-6f3m,2018-08-08,2017-11-28
-4f3o,2013-07-24,2012-05-09
-4f3h,2012-11-14,2012-05-09
-6f37,2018-12-12,2017-11-28
-4f30,2012-10-03,2012-05-08
-8f3s,2023-07-05,2022-11-10
-3f3v,2009-06-02,2008-10-31
-1f31,2000-11-01,2000-05-31
-6f3r,2018-02-28,2017-11-28
-4f39,2012-05-30,2012-05-09
-3f3d,2008-12-23,2008-10-30
-7f3w,2021-07-28,2021-06-17
-5f31,2016-03-09,2015-12-02
-7f3h,2021-07-28,2021-06-16
-7f36,2021-12-22,2021-06-15
-1f3h,2000-12-06,2000-06-03
-3f3w,2009-06-02,2008-10-31
-4f3r,2012-07-04,2012-05-09
-6f3d,2018-05-23,2017-11-28
-6f32,2018-09-19,2017-11-27
-4f3b,2012-05-30,2012-05-09
-3f3y,2009-09-15,2008-10-31
-3f3q,2009-10-20,2008-10-31
-8f3c,2023-06-21,2022-11-09
-5f36,2016-12-14,2015-12-02
-4f3g,2012-05-30,2012-05-09
-8f3g,2023-07-05,2022-11-10
-8f3y,2023-11-15,2022-11-10
-5f3t,2016-02-24,2015-12-03
-6f3i,2018-05-23,2017-11-28
-3f39,2009-07-14,2008-10-30
-1f3r,2000-06-15,2000-06-06
-5f39,2016-01-20,2015-12-02
-2f3m,2006-04-25,2005-11-21
-5f3i,2016-01-20,2015-12-02
-3f3s,2008-11-25,2008-10-31
-6f3o,2018-08-08,2017-11-28
-5f3a,2016-12-14,2015-12-02
-6f3u,2018-02-28,2017-11-28
-5f35,2016-08-31,2015-12-02
-1f3f,2000-09-13,2000-06-02
-6f38,2018-01-17,2017-11-28
-4f38,2012-05-23,2012-05-09
-2f36,2006-04-04,2005-11-18
-7f3j,2022-06-22,2021-06-16
-2f3s,2006-05-09,2005-11-22
-8f3t,2023-07-05,2022-11-10
-1f3o,2001-07-25,2000-06-05
-6f3p,2018-08-08,2017-11-28
-3f33,2009-07-14,2008-10-30
-1f3j,2000-09-20,2000-06-04
-5f3r,2016-12-07,2015-12-03
-8f3n,2023-07-05,2022-11-10
-1f3z,1998-01-28,1997-10-09
-7f3m,2022-01-12,2021-06-16
-6f3e,2018-05-23,2017-11-28
-8f38,2023-12-13,2022-11-09
-7f3l,2022-06-22,2021-06-16
-2f3k,2006-11-21,2005-11-21
-4f3k,2013-05-01,2012-05-09
-7f3y,2021-09-22,2021-06-17
-7f3t,2021-06-30,2021-06-17
-7f3x,2021-12-01,2021-06-17
-2f3x,2006-10-31,2005-11-22
-4f3y,2012-06-06,2012-05-09
-6f3f,2017-12-27,2017-11-28
-7f30,2022-04-27,2021-06-15
-1f3e,2000-06-15,2000-06-02
-4f3x,2012-05-30,2012-05-09
-2f3q,2006-05-09,2005-11-22
-2f3r,2006-05-30,2005-11-22
-3f3m,2009-10-20,2008-10-31
-6f3l,2018-02-28,2017-11-28
-5f33,2016-09-07,2015-12-02
-2f3e,2006-09-05,2005-11-21
-4f3w,2012-05-23,2012-05-09
-1f30,2003-06-17,2000-05-31
-1f3a,2000-10-18,2000-06-01
-5f37,2016-01-20,2015-12-02
-6f3q,2018-08-08,2017-11-28
-5f3e,2016-01-20,2015-12-02
-2f3t,2006-05-30,2005-11-22
-7f3k,2022-06-22,2021-06-16
-2f3f,2006-09-05,2005-11-21
-7f3i,2022-06-22,2021-06-16
-7f35,2021-12-29,2021-06-15
-6f3s,2018-02-28,2017-11-28
-8f39,2024-02-07,2022-11-09
-1f3w,2001-10-03,2000-06-06
-5f3o,2016-12-28,2015-12-03
-3f36,2009-07-14,2008-10-30
-8f3w,2023-11-15,2022-11-10
-3f3u,2009-03-03,2008-10-31
-7f3z,2021-09-22,2021-06-17
-6rux,2019-11-13,2019-05-29
-3rud,2011-05-25,2011-05-05
-5ru8,2020-12-16,2020-09-28
-1rug,1995-11-14,1995-06-09
-5ru3,2020-12-16,2020-09-28
-4rux,2015-04-22,2014-11-23
-5rup,2020-12-16,2020-09-28
-5ru9,2020-12-16,2020-09-28
-1ru2,2004-02-24,2003-12-10
-5rum,2020-12-16,2020-09-28
-5ruy,2020-12-16,2020-09-28
-4ruu,2014-12-10,2014-11-21
-7ru2,2022-08-24,2021-08-16
-5ruu,2020-12-16,2020-09-28
-5ruj,2020-12-16,2020-09-28
-4ru5,2015-11-18,2014-11-18
-4ru9,2015-08-05,2014-11-18
-4rua,2015-08-05,2014-11-18
-3ru7,2011-05-25,2011-05-04
-7rux,2022-11-09,2021-08-18
-7rug,2022-08-24,2021-08-17
-8ru0,2024-04-10,2024-01-29
-3ruu,2011-09-21,2011-05-05
-5ruq,2020-12-16,2020-09-28
-1ru4,2004-04-13,2003-12-11
-7ruy,2022-11-09,2021-08-18
-3ruc,2011-05-25,2011-05-04
-5ruh,2020-12-16,2020-09-28
-5ru5,2020-12-16,2020-09-28
-4rud,2016-05-18,2014-11-18
-8ru2,2024-04-10,2024-01-29
-3ruq,2012-01-04,2011-05-05
-4rul,2015-11-04,2014-11-20
-3rug,2011-08-03,2011-05-05
-4ru4,2015-11-18,2014-11-18
-7ru3,2022-08-24,2021-08-16
-8ruf,2024-04-17,2024-01-30
-6ruo,2019-12-11,2019-05-28
-7ruu,2021-11-24,2021-08-18
-6ru4,2019-07-31,2019-05-27
-4ru2,2015-02-04,2014-11-17
-3ruh,2011-05-25,2011-05-05
-7ru7,2022-08-17,2021-08-16
-7ru5,2022-08-24,2021-08-16
-4ruz,2015-04-22,2014-11-23
-5rur,2020-12-16,2020-09-28
-7ru8,2022-08-24,2021-08-16
-1rur,2004-03-02,2003-12-11
-6rul,2020-02-12,2019-05-28
-5ru4,2020-12-16,2020-09-28
-6rus,2019-08-21,2019-05-29
-8ruu,2024-04-24,2024-01-31
-4ru3,2015-11-18,2014-11-18
-3ruv,2012-01-04,2011-05-05
-5ruw,2020-12-16,2020-09-28
-5ruo,2020-12-16,2020-09-28
-6rui,2019-12-11,2019-05-28
-5rut,2020-12-16,2020-09-28
-1ruy,2004-03-30,2003-12-12
-1run,1997-01-10,1996-05-26
-3ru2,2011-07-27,2011-05-04
-2ruw,2015-04-08,2015-01-26
-3run,2012-06-06,2011-05-05
-7rue,2021-11-17,2021-08-16
-5rug,2020-12-16,2020-09-28
-1ru1,2004-02-24,2003-12-10
-3ruo,2011-09-07,2011-05-05
-2ru3,2014-08-13,2013-11-12
-3ruk,2012-01-25,2011-05-05
-7ru0,2022-11-23,2021-08-16
-5ruf,2020-12-16,2020-09-28
-2rut,2015-04-08,2015-01-26
-5rud,2020-12-16,2020-09-28
-3rux,2011-12-14,2011-05-05
-6ru5,2019-08-21,2019-05-27
-3ruw,2012-01-04,2011-05-05
-1ruc,1995-11-14,1995-06-09
-6ru2,2020-03-18,2019-05-27
-7ru1,2022-08-24,2021-08-16
-6rue,2020-07-15,2019-05-28
-2ruv,2015-04-08,2015-01-26
-7rut,2021-11-24,2021-08-18
-7rup,2022-08-24,2021-08-18
-4ruf,2014-12-17,2014-11-19
-5ru0,2020-12-16,2020-09-28
-1ruv,1997-04-01,1995-07-27
-7ruc,2021-12-15,2021-08-16
-4rur,2014-12-10,2014-11-21
-2rui,2015-09-09,2014-06-22
-6ruj,2020-07-08,2019-05-28
-5run,2020-12-16,2020-09-28
-7rui,2022-08-24,2021-08-17
-4ruq,2015-04-08,2014-11-21
-7ru9,2021-12-15,2021-08-16
-4ruw,2014-12-24,2014-11-23
-4rue,2014-12-17,2014-11-19
-3ru9,2011-05-25,2011-05-04
-7ruq,2022-08-24,2021-08-18
-6ruz,2019-09-25,2019-05-29
-1rut,2004-10-12,2003-12-11
-3ru0,2011-05-18,2011-05-04
-7ruj,2023-01-25,2021-08-17
-5rus,2020-12-16,2020-09-28
-8ru1,2024-03-06,2024-01-29
-6ruq,2020-06-24,2019-05-28
-7rua,2021-12-15,2021-08-16
-5rul,2020-12-16,2020-09-28
-2rux,2015-04-08,2015-01-26
-4rup,2015-10-07,2014-11-21
-3ru1,2011-08-31,2011-05-04
-6ru8,2020-05-13,2019-05-27
-9rub,1993-01-15,1990-11-28
-5ru7,2020-12-16,2020-09-28
-3rue,2011-05-25,2011-05-05
-6ru7,2020-05-13,2019-05-27
-7ruz,2022-11-09,2021-08-18
-3rul,2012-06-06,2011-05-05
-4ru1,2014-12-17,2014-11-17
-3ru3,2011-06-22,2011-05-04
-5rua,2020-12-16,2020-09-28
-5ruv,2020-12-16,2020-09-28
-6ruf,2020-07-15,2019-05-28
-3rub,1992-10-15,1990-05-25
-3ruz,2011-06-15,2011-05-05
-7ru6,2022-08-24,2021-08-16
-3rur,2011-05-18,2011-05-05
-1rue,1995-11-14,1995-06-09
-6rua,2020-01-22,2019-05-27
-5ruc,2020-12-16,2020-09-28
-1ruz,2004-03-30,2003-12-12
-1rud,1995-11-14,1995-06-09
-6ru1,2020-03-18,2019-05-27
-2ruy,2015-04-08,2015-01-26
-2ruz,2015-04-08,2015-01-26
-2ruu,2015-04-08,2015-01-26
-6rur,2019-08-21,2019-05-29
-3rua,2011-05-25,2011-05-04
-5ru6,2020-12-16,2020-09-28
-4ruy,2015-04-22,2014-11-23
-7ruv,2021-11-24,2021-08-18
-6rup,2019-10-09,2019-05-28
-5rux,2020-12-16,2020-09-28
-6rum,2020-02-12,2019-05-28
-3rum,2012-06-06,2011-05-05
-2rus,1991-10-15,1991-10-11
-7rud,2021-11-17,2021-08-16
-5rue,2020-12-16,2020-09-28
-1ruo,1997-01-10,1996-05-26
-5rui,2020-12-16,2020-09-28
-7ruw,2022-11-09,2021-08-18
-4rui,2015-01-28,2014-11-19
-5ruz,2020-12-16,2020-09-28
-6ruu,2020-09-09,2019-05-29
-6ruc,2019-09-04,2019-05-28
-5ru2,2020-12-16,2020-09-28
-7run,2022-01-19,2021-08-17
-3rup,2011-05-18,2011-05-05
-4ruh,2015-11-25,2014-11-19
-1ruq,2004-03-02,2003-12-11
-1rui,1995-11-14,1995-06-09
-7ruh,2022-08-24,2021-08-17
-6ru9,2019-09-04,2019-05-27
-3ru5,2011-11-23,2011-05-04
-3ru4,2012-08-29,2011-05-04
-3rui,2011-11-23,2011-05-05
-8rue,2024-04-17,2024-01-30
-5ruk,2020-12-16,2020-09-28
-3ruf,2011-05-25,2011-05-05
-4rus,2015-04-08,2014-11-21
-4rut,2015-02-11,2014-11-21
-4ruo,2015-10-07,2014-11-21
-8ruc,1996-08-01,1996-02-22
-6ruv,2019-08-21,2019-05-29
-6ru6,2020-05-13,2019-05-27
-7ru4,2022-08-24,2021-08-16
-4ruk,2015-11-25,2014-11-20
-4rub,1992-10-15,1990-05-25
-3rus,2012-01-04,2011-05-05
-4ruc,2015-08-05,2014-11-18
-1ru3,2003-12-23,2003-12-11
-1ruh,1995-11-14,1995-06-09
-3rut,2011-09-21,2011-05-05
-4ruj,2015-10-07,2014-11-20
-5ru1,2020-12-16,2020-09-28
-182l,1995-07-10,1995-04-19
-7nk8,2021-12-01,2021-02-17
-1nk9,2004-03-30,2003-01-02
-1nkt,2003-03-04,2003-01-03
-4nkl,2013-11-20,2013-11-12
-6nkm,2019-10-09,2019-01-07
-7nkh,2021-10-27,2021-02-18
-5nkw,2017-11-01,2017-04-03
-5nkd,2017-06-07,2017-03-31
-3nks,2011-04-20,2010-06-21
-1nk7,2004-03-30,2003-01-02
-7nkc,2021-12-01,2021-02-17
-7nky,2021-07-07,2021-02-19
-7nk2,2021-12-01,2021-02-17
-7nkx,2021-08-25,2021-02-19
-5nku,2018-02-28,2017-04-03
-6nkn,2019-03-20,2019-01-07
-7nkf,2021-06-16,2021-02-17
-4nka,2013-12-18,2013-11-12
-3nk8,2010-11-10,2010-06-18
-1nks,1998-12-09,1998-07-16
-7nk6,2021-12-01,2021-02-17
-5nkf,2017-06-07,2017-03-31
-5nkq,2017-04-26,2017-03-31
-4nk3,2014-02-19,2013-11-12
-3nkx,2010-09-15,2010-06-21
-4nkv,2014-10-22,2013-11-13
-3nkm,2011-01-19,2010-06-20
-7nke,2022-03-02,2021-02-17
-5nk5,2017-06-07,2017-03-31
-6nk0,2019-05-01,2019-01-04
-6nkx,2020-01-08,2019-01-07
-6nkk,2019-10-09,2019-01-07
-4nke,2014-11-19,2013-11-12
-5nki,2017-06-07,2017-03-31
-6nkp,2019-05-01,2019-01-07
-4nkx,2014-10-22,2013-11-13
-5nk3,2017-06-07,2017-03-31
-6nks,2020-01-08,2019-01-07
-5nkn,2018-04-04,2017-03-31
-3nk1,2011-03-23,2010-06-18
-5nkc,2017-06-07,2017-03-31
-5nkg,2017-06-07,2017-03-31
-7nk3,2021-06-09,2021-02-17
-3nkq,2011-01-19,2010-06-20
-5nk8,2017-06-07,2017-03-31
-6nkr,2020-01-08,2019-01-07
-5nkl,2017-06-28,2017-03-31
-1nk8,2004-03-30,2003-01-02
-6nkq,2019-01-23,2019-01-07
-5nke,2017-06-07,2017-03-31
-5nky,2017-05-24,2017-04-03
-5nkv,2018-01-31,2017-04-03
-3nk7,2010-07-21,2010-06-18
-5nkk,2017-04-19,2017-03-31
-4nkb,2014-08-27,2013-11-12
-6nk7,2019-05-22,2019-01-04
-1nkg,2004-05-25,2003-01-03
-3nkv,2010-08-04,2010-06-21
-4nk2,2014-09-24,2013-11-12
-5nkh,2017-06-07,2017-03-31
-4nk1,2014-09-24,2013-11-12
-1nkf,1999-02-16,1998-03-09
-4nks,2013-12-18,2013-11-13
-3nk2,2011-03-23,2010-06-18
-4nku,2013-12-18,2013-11-13
-7nkr,2021-12-01,2021-02-18
-7nk5,2021-06-09,2021-02-17
-7nku,2021-06-23,2021-02-19
-1nkm,2003-02-11,2003-01-03
-7nkt,2021-05-12,2021-02-18
-3nkr,2011-01-19,2010-06-20
-1nkb,2004-03-30,2003-01-02
-3nk3,2010-11-10,2010-06-18
-7nkj,2021-10-27,2021-02-18
-6nku,2020-01-08,2019-01-07
-1nkq,2004-06-15,2003-01-03
-6nka,2020-01-15,2019-01-07
-4nkq,2015-09-23,2013-11-13
-1nke,2004-03-30,2003-01-02
-5nk1,2017-06-07,2017-03-31
-4nkc,2015-03-04,2013-11-12
-4nkt,2013-12-18,2013-11-13
-6nk1,2019-05-01,2019-01-04
-1nkh,2003-01-14,2003-01-03
-7nka,2021-12-01,2021-02-17
-5nk2,2017-06-07,2017-03-31
-1nkc,2004-03-30,2003-01-02
-6nki,2019-10-09,2019-01-07
-6nk2,2019-05-01,2019-01-04
-7nkz,2021-09-22,2021-02-19
-1nki,2004-01-13,2003-01-03
-6nk8,2019-08-07,2019-01-05
-3nko,2011-01-19,2010-06-20
-4nkf,2014-11-19,2013-11-12
-3nky,2011-05-25,2010-06-21
-1nk6,2004-03-30,2003-01-02
-7nk0,2022-01-12,2021-02-17
-7nki,2021-12-01,2021-02-18
-6nky,2020-01-08,2019-01-07
-6nkf,2020-01-22,2019-01-07
-1nkx,2003-09-02,2003-01-06
-6nkt,2020-01-08,2019-01-07
-6nkb,2020-01-15,2019-01-07
-5nk6,2017-06-07,2017-03-31
-7nk7,2021-10-27,2021-02-17
-4nkz,2014-10-22,2013-11-13
-5nka,2017-06-07,2017-03-31
-3nk9,2011-06-29,2010-06-18
-3nk4,2010-11-10,2010-06-18
-5nk9,2017-06-07,2017-03-31
-6nk6,2019-05-22,2019-01-04
-6nkw,2020-01-08,2019-01-07
-6nkj,2019-01-16,2019-01-07
-1nk0,2004-03-30,2003-01-02
-5nk0,2017-06-07,2017-03-31
-5nk7,2017-06-07,2017-03-31
-7nk4,2021-12-01,2021-02-17
-3nkp,2011-01-19,2010-06-20
-1nkz,2003-02-25,2003-01-06
-1nkk,2003-02-11,2003-01-03
-7nkg,2021-05-19,2021-02-18
-6nk5,2019-05-22,2019-01-04
-3nkk,2010-11-10,2010-06-20
-5nk4,2017-06-07,2017-03-31
-4nkw,2014-10-22,2013-11-13
-4nk5,2014-02-12,2013-11-12
-3nk0,2011-03-23,2010-06-18
-1nk4,2004-03-30,2003-01-02
-1nk5,2004-03-30,2003-01-02
-6nkz,2020-01-08,2019-01-07
-1nku,2003-06-03,2003-01-03
-6nk4,2020-01-15,2019-01-04
-4nky,2014-10-22,2013-11-13
-5nkb,2017-06-07,2017-03-31
-4nk9,2013-12-18,2013-11-12
-3nkt,2011-07-13,2010-06-21
-7nks,2021-06-23,2021-02-18
-3nkn,2011-01-19,2010-06-20
-6nkv,2020-01-08,2019-01-07
-7nk1,2021-12-01,2021-02-17
-6wnc,2020-06-17,2020-04-22
-4wnb,2014-10-29,2014-10-11
-2wno,2010-09-01,2009-07-13
-8wnu,2024-05-08,2023-10-06
-6wni,2021-04-28,2020-04-22
-5wnl,2018-05-09,2017-08-01
-1wn6,2005-10-25,2004-07-27
-2wnf,2009-10-13,2009-07-09
-6wnx,2020-05-06,2020-04-23
-6wnb,2020-06-17,2020-04-22
-5wn4,2018-02-28,2017-07-31
-3wnz,2014-05-14,2013-12-19
-4wn2,2015-09-30,2014-10-10
-3wnk,2014-02-05,2013-12-10
-8wny,2024-05-15,2023-10-06
-6wnm,2021-04-07,2020-04-22
-3wni,2014-12-10,2013-12-10
-6wnp,2020-05-06,2020-04-23
-7wnw,2022-04-06,2022-01-19
-3wnw,2015-01-28,2013-12-17
-7wn6,2022-05-18,2022-01-17
-6wnz,2021-06-16,2020-04-23
-4wnh,2015-09-30,2014-10-11
-5wnv,2018-02-21,2017-08-01
-7wn4,2022-05-18,2022-01-17
-8wnp,2024-05-08,2023-10-06
-5wns,2018-02-21,2017-08-01
-7wnm,2022-12-21,2022-01-18
-4wnt,2015-01-14,2014-10-14
-2wn9,2009-09-01,2009-07-07
-2wny,2010-09-01,2009-07-21
-7wna,2022-08-10,2022-01-17
-2wn7,2009-08-18,2009-07-07
-4wnx,2016-02-10,2014-10-14
-5wn1,2018-02-28,2017-07-31
-1wn2,2005-07-19,2004-07-26
-7wnv,2023-01-25,2022-01-19
-1wng,2005-07-19,2004-08-02
-3wng,2013-12-25,2013-12-09
-4wnl,2014-12-24,2014-10-13
-1wnt,2005-07-19,2004-08-09
-2wn3,2010-05-26,2009-07-07
-6wnu,2021-04-28,2020-04-23
-7wnx,2022-08-03,2022-01-20
-3wn5,2014-11-19,2013-12-05
-6wng,2020-04-29,2020-04-22
-5wnz,2017-09-13,2017-08-01
-4wnm,2016-01-20,2014-10-13
-6wna,2021-09-15,2020-04-22
-6wn9,2020-05-06,2020-04-22
-4wnr,2014-11-05,2014-10-14
-6wn3,2020-06-17,2020-04-22
-6wnl,2020-07-01,2020-04-22
-2wnh,2010-04-28,2009-07-09
-5wno,2018-01-31,2017-08-01
-1wne,2004-08-31,2004-07-31
-3wn4,2014-02-19,2013-12-02
-4wno,2015-01-14,2014-10-14
-7wn1,2023-02-01,2022-01-17
-2wn2,2010-05-26,2009-07-07
-3wn2,2014-02-05,2013-11-29
-2wnj,2009-09-01,2009-07-09
-3wnb,2014-12-10,2013-12-08
-6wn6,2020-06-10,2020-04-22
-2wnd,2009-11-03,2009-07-08
-4wnk,2015-06-10,2014-10-13
-7wn3,2022-05-25,2022-01-17
-1wnl,2005-08-16,2004-08-05
-5wn2,2018-02-28,2017-07-31
-7wni,2022-08-10,2022-01-18
-1wno,2005-03-15,2004-08-07
-7wnl,2023-01-25,2022-01-18
-8wnf,2024-02-14,2023-10-05
-3wn0,2014-02-05,2013-11-29
-1wnw,2004-11-09,2004-08-10
-4wn3,2015-12-23,2014-10-10
-5wnp,2018-02-21,2017-08-01
-5wnt,2018-02-21,2017-08-01
-8wnw,2024-05-29,2023-10-06
-2wnn,2010-08-25,2009-07-13
-4wn1,2014-12-31,2014-10-10
-6wnk,2021-04-28,2020-04-22
-2wn6,2009-08-18,2009-07-07
-2wne,2010-01-26,2009-07-09
-6wn7,2020-09-30,2020-04-22
-6wnr,2020-06-03,2020-04-23
-5wnw,2017-08-16,2017-08-01
-4wnp,2015-01-14,2014-10-14
-8wng,2024-02-14,2023-10-05
-1wn1,2005-08-09,2004-07-26
-1wnz,2005-10-25,2004-08-11
-1wnd,2004-10-05,2004-07-29
-5wne,2018-08-01,2017-07-31
-3wne,2013-12-25,2013-12-09
-2wnc,2009-09-01,2009-07-08
-2wnt,2009-08-25,2009-07-20
-5wnx,2017-09-13,2017-08-01
-7wnb,2023-04-19,2022-01-18
-5wn5,2018-02-28,2017-07-31
-3wnl,2014-02-05,2013-12-10
-7wno,2022-04-20,2022-01-19
-8wns,2024-05-15,2023-10-06
-6wnn,2021-04-28,2020-04-22
-7wnj,2023-01-25,2022-01-18
-1wn3,2005-07-05,2004-07-27
-3wnp,2014-02-05,2013-12-10
-5wn8,2017-12-06,2017-07-31
-2wnv,2010-05-26,2009-07-20
-7wn2,2023-04-19,2022-01-17
-7wnn,2022-04-06,2022-01-19
-1wnu,2005-07-26,2004-08-09
-6wnd,2020-06-17,2020-04-22
-4wnc,2014-12-03,2014-10-11
-1wn5,2005-10-25,2004-07-27
-5wnb,2018-03-14,2017-07-31
-1wn7,2005-08-02,2004-07-28
-2wnb,2009-10-13,2009-07-08
-5wni,2018-05-09,2017-08-01
-6wny,2020-06-03,2020-04-23
-2wnx,2009-12-29,2009-07-20
-3wnq,2014-07-16,2013-12-15
-3wnt,2014-03-05,2013-12-16
-5wnm,2018-05-09,2017-08-01
-7wnk,2023-01-25,2022-01-18
-3wnf,2013-12-25,2013-12-09
-3wnx,2014-01-15,2013-12-18
-5wn3,2018-02-28,2017-07-31
-3wnn,2014-02-05,2013-12-10
-5wnq,2018-02-21,2017-08-01
-6wnh,2020-05-13,2020-04-22
-3wns,2014-03-05,2013-12-16
-4wn0,2016-01-20,2014-10-10
-3wnh,2013-12-25,2013-12-10
-2wns,2009-08-11,2009-07-19
-8wni,2024-02-14,2023-10-06
-7wn8,2023-01-25,2022-01-17
-2wnp,2009-12-22,2009-07-16
-7wnt,2023-01-25,2022-01-19
-3wn6,2014-09-10,2013-12-05
-1wnb,2004-10-05,2004-07-29
-3wnj,2014-12-10,2013-12-10
-6wn0,2020-05-13,2020-04-22
-4wni,2014-12-03,2014-10-12
-6wn8,2020-05-06,2020-04-22
-5wnr,2018-02-21,2017-08-01
-3wnc,2014-12-10,2013-12-08
-7wnh,2023-01-25,2022-01-18
-4wns,2015-08-05,2014-10-14
-6wn2,2020-09-02,2020-04-22
-3wnm,2014-02-05,2013-12-10
-5wnh,2018-08-01,2017-07-31
-5wny,2017-09-13,2017-08-01
-2wnl,2009-09-01,2009-07-09
-3wnr,2014-03-05,2013-12-16
-1wnv,2004-11-09,2004-08-10
-7wnu,2023-01-25,2022-01-19
-6wnq,2020-06-03,2020-04-23
-1wnx,2004-11-09,2004-08-10
-4wnu,2015-01-14,2014-10-14
-8wn8,2024-05-08,2023-10-05
-7wn5,2022-08-10,2022-01-17
-5wnn,2017-08-30,2017-08-01
-7wnp,2022-04-20,2022-01-19
-4wnj,2015-08-05,2014-10-13
-2wng,2009-07-21,2009-07-09
-4wnv,2015-01-14,2014-10-14
-5wng,2018-08-01,2017-07-31
-8wnj,2024-02-14,2023-10-06
-3wno,2014-02-05,2013-12-10
-8wnt,2024-05-15,2023-10-06
-2wnu,2010-05-26,2009-07-20
-1wni,2004-08-17,2004-08-04
-5wnk,2018-05-09,2017-08-01
-3wn1,2014-02-05,2013-11-29
-5wnf,2018-08-01,2017-07-31
-4wnw,2015-01-14,2014-10-14
-3wnu,2014-03-12,2013-12-17
-4wnn,2015-10-21,2014-10-13
-5wnj,2018-05-09,2017-08-01
-2pck,2007-10-02,2007-03-30
-2pcx,2008-04-08,2007-03-30
-8pc2,2023-11-15,2023-06-09
-1pcr,1995-02-07,1994-11-10
-6pc1,2019-11-20,2019-06-15
-6pcx,2019-11-13,2019-06-18
-2pcb,1993-07-15,1993-04-14
-7pcu,2022-12-07,2021-08-04
-7pcf,2022-04-13,2021-08-03
-2pcm,2007-10-02,2007-03-30
-6pcb,2020-05-27,2019-06-17
-1pcs,1997-12-17,1997-06-17
-3pcn,1998-02-25,1997-08-19
-4pc7,2015-05-06,2014-04-14
-7pc4,2022-04-20,2021-08-03
-8pc7,2023-07-19,2023-06-09
-3pc3,2010-12-01,2010-10-21
-3pcq,2011-02-02,2010-10-21
-6pcp,2019-11-06,2019-06-17
-7pch,2022-04-13,2021-08-03
-4pcz,2015-04-01,2014-04-17
-6pcd,2020-05-27,2019-06-17
-3pco,2011-03-02,2010-10-21
-6pc5,2020-06-17,2019-06-16
-4pca,2014-06-18,2014-04-14
-3pcd,1998-05-27,1997-11-24
-1pc8,2004-06-22,2003-05-16
-7pc6,2022-03-23,2021-08-03
-5pcy,1987-01-15,1986-09-02
-1pcg,2003-10-28,2003-05-16
-1pcq,2003-10-14,2003-05-16
-3pc0,2011-09-21,2010-10-21
-4pc6,2015-05-06,2014-04-14
-3pcx,2011-02-23,2010-10-22
-7pcn,2022-08-10,2021-08-03
-8pch,1998-12-09,1997-11-07
-2pcc,1993-07-15,1993-04-14
-7pc2,2022-02-23,2021-08-03
-2pch,2007-10-02,2007-03-29
-7pcl,2022-08-10,2021-08-03
-3pcg,1998-04-29,1997-04-29
-4pce,2014-05-07,2014-04-15
-4pc1,2015-05-06,2014-04-14
-2pcl,2007-10-02,2007-03-30
-3pci,1998-01-21,1997-07-02
-3pcj,1998-01-21,1997-07-18
-1pck,2004-02-17,2003-05-16
-2pc4,2007-04-17,2007-03-29
-7pcm,2022-08-10,2021-08-03
-6pc3,2019-11-20,2019-06-15
-2pc8,2008-04-01,2007-03-29
-7pcb,2022-04-20,2021-08-03
-7pcw,2021-12-15,2021-08-04
-3pcu,2011-11-16,2010-10-22
-1pcx,2003-08-19,2003-05-18
-2pcq,2007-10-02,2007-03-30
-7pc8,2022-04-20,2021-08-03
-1pca,1993-10-31,1991-10-28
-2pc2,2008-04-01,2007-03-29
-7pco,2022-08-10,2021-08-03
-6pcl,2020-04-29,2019-06-17
-7pcs,2022-06-15,2021-08-04
-4pcn,2015-05-06,2014-04-16
-4pc2,2015-05-06,2014-04-14
-6pcw,2019-07-24,2019-06-18
-2pcf,1998-04-08,1997-12-22
-3pcb,1998-04-29,1997-04-25
-1pcw,2004-02-17,2003-05-17
-4pc3,2015-05-06,2014-04-14
-4pcr,2015-04-22,2014-04-16
-4pcw,2015-04-01,2014-04-16
-4pcy,1987-01-15,1986-09-02
-7pcp,2021-10-13,2021-08-03
-7pc3,2022-04-20,2021-08-03
-7pcv,2022-08-17,2021-08-04
-3pce,1998-04-29,1997-04-29
-3pc2,2010-12-01,2010-10-21
-2pcd,1994-12-20,1994-06-21
-2pci,2007-10-02,2007-03-29
-7pcg,2022-08-10,2021-08-03
-2pcg,2007-10-02,2007-03-29
-4pcl,2014-06-18,2014-04-15
-6pcc,2020-05-27,2019-06-17
-3pc8,2011-06-15,2010-10-21
-2pc5,2008-02-12,2007-03-29
-8pc0,2023-11-01,2023-06-09
-3pca,1998-01-21,1997-07-18
-7pci,2022-08-10,2021-08-03
-4pcg,2014-08-06,2014-04-15
-3pck,1998-01-21,1997-07-18
-4pcu,2014-09-24,2014-04-16
-3pcm,1998-01-21,1997-07-18
-8pc3,2023-07-12,2023-06-09
-2pc9,2007-10-02,2007-03-29
-8pc8,2023-07-12,2023-06-10
-4pc0,2014-06-11,2014-04-14
-4pcs,2014-07-09,2014-04-16
-3pcw,2011-10-19,2010-10-22
-7pc9,2022-04-20,2021-08-03
-7pce,2022-08-10,2021-08-03
-6pcy,1987-01-15,1986-09-02
-6pci,2020-03-11,2019-06-17
-4pc9,2014-05-21,2014-04-14
-7pct,2022-08-10,2021-08-04
-6pcz,2020-03-18,2019-06-18
-7pcc,2022-08-10,2021-08-03
-3pcl,1998-01-21,1997-07-18
-2pc0,2007-06-26,2007-03-29
-3pcc,1998-04-29,1997-04-29
-1pcm,2004-01-20,2003-05-16
-1pcj,2004-01-20,2003-05-16
-2pca,2007-10-02,2007-03-29
-4pct,2014-07-02,2014-04-16
-2pcp,1999-01-27,1998-06-02
-7pc7,2022-04-20,2021-08-03
-2pc6,2007-04-10,2007-03-29
-3pcv,2011-03-16,2010-10-22
-3pcy,1986-01-21,1985-12-10
-6pc4,2020-04-22,2019-06-15
-3pcf,1998-01-07,1997-06-27
-7pc5,2022-04-20,2021-08-03
-6pc9,2020-05-20,2019-06-17
-4pc8,2015-04-22,2014-04-14
-7pcq,2022-04-13,2021-08-03
-9pcy,1993-10-31,1991-03-18
-4pcd,2014-05-07,2014-04-15
-3pcr,2011-01-05,2010-10-21
-7pcy,1990-07-15,1989-09-22
-7pcj,2022-07-13,2021-08-03
-2pcu,2007-04-17,2007-03-30
-6pck,2020-04-29,2019-06-17
-7pc0,2022-02-09,2021-08-03
-3pch,1998-01-07,1997-07-01
-4pcp,2015-05-06,2014-04-16
-7pcx,2021-12-15,2021-08-04
-8pcx,2023-07-12,2023-06-11
-7pcd,2022-07-27,2021-08-03
-4pci,2014-05-14,2014-04-15
-6pc2,2019-11-20,2019-06-15
-3pc4,2010-12-01,2010-10-21
-3zg9,2014-01-15,2012-12-17
-6zgt,2021-10-20,2020-06-19
-3zgc,2013-06-12,2012-12-17
-6zgx,2020-07-29,2020-06-20
-7zgt,2022-12-28,2022-04-04
-7zg1,2022-11-23,2022-04-01
-7zg5,2023-10-11,2022-04-01
-5zgp,2018-08-22,2018-03-10
-1zgw,2005-10-18,2005-04-22
-4zgl,2015-05-27,2015-04-23
-3zg8,2013-05-29,2012-12-17
-2zgv,2008-07-01,2008-01-26
-1zgd,2005-06-28,2005-04-21
-5zgy,2018-08-22,2018-03-10
-2zgg,2008-02-05,2008-01-21
-5zge,2018-08-22,2018-03-08
-2zgo,2009-01-20,2008-01-23
-4zg3,2016-03-09,2015-04-22
-2zgi,2008-07-22,2008-01-22
-4zg9,2015-10-14,2015-04-22
-6zgf,2020-07-01,2020-06-18
-7zg0,2022-11-02,2022-04-01
-7zgy,2022-07-13,2022-04-04
-2zgd,2008-02-05,2008-01-21
-6zg4,2021-10-06,2020-06-18
-3zga,2013-05-29,2012-12-17
-6zge,2020-07-01,2020-06-18
-4zg8,2016-06-29,2015-04-22
-5zgw,2018-08-22,2018-03-10
-2zgh,2009-01-27,2008-01-22
-3zgv,2013-03-13,2012-12-19
-7zg2,2022-11-23,2022-04-01
-2zg0,2009-01-20,2008-01-16
-5zgb,2018-04-25,2018-03-08
-3zgj,2013-10-30,2012-12-18
-7zga,2023-01-25,2022-04-03
-2zgm,2009-01-20,2008-01-23
-7zgl,2023-04-19,2022-04-04
-6zgr,2021-10-20,2020-06-19
-6zgz,2020-07-29,2020-06-20
-7zgv,2022-10-26,2022-04-04
-5zgc,2019-04-03,2018-03-08
-3zg0,2013-10-09,2012-12-13
-1zg7,2005-07-12,2005-04-20
-5zgm,2018-08-01,2018-03-09
-3zg1,2013-10-23,2012-12-13
-1zgf,2006-05-23,2005-04-21
-4zgk,2016-10-19,2015-04-23
-4zgn,2015-09-30,2015-04-23
-3zgd,2013-06-12,2012-12-17
-1zga,2006-08-01,2005-04-20
-3zgz,2013-01-30,2012-12-19
-7zg3,2023-08-16,2022-04-01
-4zgy,2015-09-02,2015-04-24
-1zgc,2005-08-16,2005-04-21
-6zgp,2020-11-18,2020-06-19
-2zgw,2008-02-05,2008-01-28
-6zgo,2021-06-30,2020-06-19
-1zgj,2006-08-01,2005-04-21
-4zgj,2015-07-01,2015-04-23
-2zga,2009-02-03,2008-01-21
-5zg3,2019-01-16,2018-03-07
-3zgg,2014-01-15,2012-12-17
-6zgi,2020-07-01,2020-06-18
-6zg9,2021-10-06,2020-06-18
-1zg8,2005-07-12,2005-04-20
-5zgq,2018-08-22,2018-03-10
-5zgh,2018-04-11,2018-03-09
-2zgx,2008-12-16,2008-01-28
-5zg2,2019-01-16,2018-03-07
-2zg7,2008-08-26,2008-01-18
-2zgj,2009-01-27,2008-01-22
-7zg8,2023-02-22,2022-04-02
-7zgp,2022-05-25,2022-04-04
-6zgs,2021-10-20,2020-06-19
-7zgd,2023-01-25,2022-04-03
-2zgz,2008-02-12,2008-01-30
-5zgz,2018-08-22,2018-03-10
-2zg9,2008-08-26,2008-01-18
-3zgn,2013-01-09,2012-12-18
-6zgy,2020-07-29,2020-06-20
-7zgm,2022-09-07,2022-04-04
-3zgf,2013-01-23,2012-12-17
-1zgy,2005-07-26,2005-04-22
-2zg1,2008-02-05,2008-01-17
-6zgb,2021-01-27,2020-06-18
-4zg4,2016-03-23,2015-04-22
-2zgn,2009-01-20,2008-01-23
-3zg5,2013-10-09,2012-12-14
-4zgs,2015-12-02,2015-04-23
-4zga,2015-10-14,2015-04-22
-5zgs,2018-05-23,2018-03-10
-5zgg,2019-03-13,2018-03-08
-5zgf,2018-08-22,2018-03-08
-4zgd,2015-07-01,2015-04-22
-3zg2,2013-09-25,2012-12-14
-5zgx,2018-08-22,2018-03-10
-5zg0,2019-01-16,2018-03-07
-3zgb,2013-02-27,2012-12-17
-5zg6,2019-03-20,2018-03-07
-4zgf,2015-05-06,2015-04-22
-5zgr,2018-08-22,2018-03-10
-3zg6,2013-04-03,2012-12-15
-7zg7,2022-11-23,2022-04-02
-7zgo,2022-10-05,2022-04-04
-6zgu,2021-10-20,2020-06-19
-3zgo,2013-03-20,2012-12-18
-5zgi,2018-08-22,2018-03-09
-3zg3,2013-09-25,2012-12-14
-4zgr,2016-03-23,2015-04-23
-4zg7,2015-10-14,2015-04-22
-2zgb,2008-12-16,2008-01-21
-7zgs,2022-08-24,2022-04-04
-1zgi,2005-09-27,2005-04-21
-4zgp,2015-10-14,2015-04-23
-6zgc,2020-07-29,2020-06-18
-7zgb,2023-01-25,2022-04-03
-7zgc,2023-01-25,2022-04-03
-4zgx,2015-10-07,2015-04-24
-7zg9,2023-01-25,2022-04-03
-1zge,2006-05-23,2005-04-21
-6zgm,2020-09-02,2020-06-19
-7zgu,2022-05-18,2022-04-04
-3zgl,2013-01-09,2012-12-18
-1zgn,2005-11-01,2005-04-21
-3zgp,2013-04-24,2012-12-18
-1zgv,2005-09-27,2005-04-22
-7zgz,2023-04-19,2022-04-05
-5zg1,2019-01-16,2018-03-07
-1zgs,2005-10-11,2005-04-22
-5zgu,2018-08-22,2018-03-10
-7zgr,2022-05-25,2022-04-04
-4zg5,2015-05-06,2015-04-22
-1zg9,2005-07-12,2005-04-20
-7zg4,2022-04-20,2022-04-01
-4zg6,2015-10-14,2015-04-22
-5zgv,2018-08-22,2018-03-10
-6zga,2021-02-17,2020-06-18
-4zge,2015-07-01,2015-04-22
-3zge,2013-02-27,2012-12-17
-1zg3,2006-08-01,2005-04-20
-1zgb,2005-08-16,2005-04-21
-6zgw,2020-07-29,2020-06-20
-5zgt,2018-08-22,2018-03-10
-2zgy,2008-02-12,2008-01-30
-2zg3,2008-02-05,2008-01-17
-2zg8,2008-08-26,2008-01-18
-6zgv,2020-07-29,2020-06-20
-185d,1995-02-07,1994-08-10
-185l,1995-07-10,1995-04-19
-5gje,2017-01-18,2016-06-29
-5gji,2016-12-14,2016-06-30
-1gjf,2001-05-30,2001-05-11
-5gjs,2016-12-07,2016-07-01
-8gj5,2024-01-24,2023-03-14
-5gja,2017-05-10,2016-06-28
-7gju,2023-11-08,2023-08-11
-7gjn,2023-11-08,2023-08-11
-4gj9,2013-02-13,2012-08-09
-8gj8,2023-08-16,2023-03-15
-5gjw,2016-09-14,2016-07-02
-6gj8,2019-07-31,2018-05-16
-4gja,2013-02-13,2012-08-09
-6gjo,2019-03-27,2018-05-16
-5gjb,2016-07-20,2016-06-28
-8gjz,2023-07-05,2023-03-16
-1gj6,2002-04-27,2001-04-27
-1gj8,2002-04-27,2001-04-27
-2gja,2006-07-04,2006-03-30
-3gjo,2009-08-04,2009-03-09
-8gje,2023-10-18,2023-03-15
-1gjb,2002-04-27,2001-04-27
-2gje,2006-09-05,2006-03-30
-5gjo,2017-05-10,2016-07-01
-4gj6,2013-03-06,2012-08-09
-3gjn,2009-09-15,2009-03-09
-8gjh,2023-08-02,2023-03-15
-5gjc,2016-07-20,2016-06-28
-7gjv,2023-11-08,2023-08-11
-7gjk,2023-11-08,2023-08-11
-2gjv,2006-04-11,2006-03-31
-6gjd,2019-01-02,2018-05-16
-5gjx,2017-05-10,2016-07-02
-7gjo,2023-11-08,2023-08-11
-3gj3,2009-08-04,2009-03-07
-3gjc,2009-04-28,2009-03-08
-5gjh,2016-12-14,2016-06-30
-6gjn,2018-11-07,2018-05-16
-3gj7,2009-08-04,2009-03-07
-2gj6,2006-10-03,2006-03-30
-7gj2,2023-11-08,2023-08-11
-7gjb,2023-11-08,2023-08-11
-3gj4,2009-08-04,2009-03-07
-6gj9,2019-11-27,2018-05-16
-3gjt,2009-03-24,2009-03-09
-2gj7,2006-05-30,2006-03-30
-2gj5,2007-10-02,2006-03-30
-6gjp,2018-11-07,2018-05-16
-6gjm,2018-11-07,2018-05-16
-6gja,2019-11-27,2018-05-16
-5gjy,2017-05-10,2016-07-02
-6gjk,2019-01-16,2018-05-16
-1gjc,2002-04-27,2001-04-27
-2gjm,2006-05-02,2006-03-31
-8gj2,2024-03-27,2023-03-14
-7gj6,2023-11-08,2023-08-11
-2gj8,2006-07-04,2006-03-30
-5gjd,2016-11-16,2016-06-29
-7gjs,2023-11-08,2023-08-11
-4gjt,2012-10-10,2012-08-10
-7gji,2023-11-08,2023-08-11
-5gjg,2016-11-16,2016-06-29
-8gjc,2024-01-17,2023-03-15
-6gjj,2018-11-07,2018-05-16
-8gju,2023-08-09,2023-03-16
-2gju,2006-10-10,2006-03-31
-2gjl,2006-05-16,2006-03-31
-1gja,2002-04-27,2001-04-27
-3gj8,2009-08-04,2009-03-07
-1gj9,2002-04-27,2001-04-30
-3gjf,2009-04-28,2009-03-08
-8gjn,2023-04-05,2023-03-16
-5gjr,2016-09-07,2016-07-01
-3gjd,2009-04-28,2009-03-08
-6gjr,2018-11-07,2018-05-16
-7gjw,2023-11-08,2023-08-11
-3gj9,2009-12-15,2009-03-08
-7gj1,2023-11-08,2023-08-11
-7gjt,2023-11-08,2023-08-11
-5gju,2017-05-31,2016-07-02
-2gjs,2006-04-11,2006-03-31
-8gj0,2024-03-27,2023-03-14
-7gjm,2023-11-08,2023-08-11
-7gjc,2023-11-08,2023-08-11
-8gj7,2023-11-15,2023-03-15
-7gje,2023-11-08,2023-08-11
-6gj5,2019-07-31,2018-05-16
-8gj9,2023-08-16,2023-03-15
-2gjk,2007-01-09,2006-03-31
-7gj5,2023-11-08,2023-08-11
-1gjr,2002-06-27,2001-08-01
-4gj7,2013-03-06,2012-08-09
-2gjp,2006-09-05,2006-03-31
-1gj5,2002-04-27,2001-04-27
-2gj3,2007-03-06,2006-03-30
-6gjf,2019-06-12,2018-05-16
-6gji,2018-11-07,2018-05-16
-3gjs,2009-03-24,2009-03-09
-6gjw,2019-05-29,2018-05-17
-6gjq,2019-06-19,2018-05-16
-6gj7,2019-07-31,2018-05-16
-3gjb,2009-04-14,2009-03-08
-7gjl,2023-11-08,2023-08-11
-4gjj,2012-12-12,2012-08-09
-2gj2,2006-09-19,2006-03-30
-4gjz,2012-09-05,2012-08-10
-4gjf,2013-02-06,2012-08-09
-1gjw,2001-09-06,2001-08-03
-6gjb,2019-01-02,2018-05-16
-6gj6,2019-07-31,2018-05-16
-7gj4,2023-11-08,2023-08-11
-4gjg,2013-02-06,2012-08-09
-4gj2,2013-05-29,2012-08-09
-5gjq,2016-08-17,2016-07-01
-4gjc,2013-02-13,2012-08-09
-1gjp,2001-08-02,2001-08-01
-4gjw,2014-02-12,2012-08-10
-7gj9,2023-11-08,2023-08-11
-3gjq,2009-03-24,2009-03-09
-4gj5,2013-03-06,2012-08-09
-7gj3,2023-11-08,2023-08-11
-6gjh,2019-05-29,2018-05-16
-5gjp,2016-11-23,2016-07-01
-7gj0,2023-11-08,2023-08-11
-7gjp,2023-11-08,2023-08-11
-8gjm,2023-04-05,2023-03-16
-2gj4,2007-02-13,2006-03-30
-8gja,2023-08-16,2023-03-15
-8gjd,2024-01-17,2023-03-15
-5gjv,2016-09-14,2016-07-02
-6gjc,2018-09-05,2018-05-16
-7gjj,2023-11-08,2023-08-11
-2gjr,2006-09-05,2006-03-31
-6gj4,2018-12-05,2018-05-16
-8gj1,2024-03-27,2023-03-14
-5gj3,2017-06-28,2016-06-26
-8gj3,2024-03-27,2023-03-14
-3gju,2009-03-17,2009-03-09
-7gj7,2023-11-08,2023-08-11
-8gjt,2023-06-07,2023-03-16
-7gj8,2023-11-08,2023-08-11
-3gjx,2009-05-26,2009-03-09
-7gjy,2023-11-08,2023-08-11
-7gjx,2023-11-08,2023-08-11
-2gjx,2006-06-20,2006-03-31
-5gjn,2016-11-23,2016-07-01
-4gji,2012-12-12,2012-08-09
-1gjd,2002-05-03,2001-05-03
-8gjx,2023-07-05,2023-03-16
-7gjr,2023-11-08,2023-08-11
-8gjl,2023-05-31,2023-03-16
-1gjv,2001-10-11,2001-08-03
-1gjg,2001-05-30,2001-05-11
-1gjq,2002-08-01,2001-08-01
-1gj4,2002-04-27,2001-04-27
-6gjg,2018-09-19,2018-05-16
-5gjf,2016-11-16,2016-06-29
-4gjb,2013-02-13,2012-08-09
-4gjp,2012-10-03,2012-08-10
-3gjr,2009-03-24,2009-03-09
-8gjk,2023-05-31,2023-03-16
-7gja,2023-11-08,2023-08-11
-6gj2,2019-11-27,2018-05-15
-7gjq,2023-11-08,2023-08-11
-6gjl,2018-11-07,2018-05-16
-6gj0,2018-10-17,2018-05-15
-6gjt,2018-07-25,2018-05-17
-8gjb,2024-03-20,2023-03-15
-2gjz,2007-02-06,2006-03-31
-7gjf,2023-11-08,2023-08-11
-4gjd,2013-02-13,2012-08-09
-3gj5,2009-08-04,2009-03-07
-3gjw,2010-03-09,2009-03-09
-3gj0,2009-08-04,2009-03-07
-2gj9,2006-07-04,2006-03-30
-7gjd,2023-11-08,2023-08-11
-5gjt,2016-12-07,2016-07-01
-4gjy,2012-09-05,2012-08-10
-6gjy,2018-11-07,2018-05-17
-1gj7,2002-04-27,2001-04-27
-7gjz,2023-11-08,2023-08-11
-2gjn,2006-05-16,2006-03-31
-6gjs,2019-06-26,2018-05-16
-4gje,2013-02-06,2012-08-09
-7gjg,2023-11-08,2023-08-11
-4gj8,2013-02-13,2012-08-09
-1gjn,2002-03-01,2001-07-27
-3gj6,2009-08-04,2009-03-07
-4gj3,2013-05-29,2012-08-09
-6gjz,2018-11-21,2018-05-17
-7gjh,2023-11-08,2023-08-11
-5gj9,2017-05-10,2016-06-28
-2gjw,2006-09-12,2006-03-31
-5azg,2015-12-30,2015-10-05
-2az9,2006-02-28,2005-09-09
-7az7,2021-12-01,2020-11-16
-1azm,1994-04-30,1993-11-28
-4aze,2012-09-05,2012-06-25
-6azm,2017-12-13,2017-09-11
-1az1,1998-03-18,1997-11-24
-4az2,2012-08-15,2012-06-22
-5az7,2016-01-13,2015-09-27
-9az9,2024-03-20,2024-03-10
-4az3,2012-09-26,2012-06-22
-6azl,2017-12-13,2017-09-11
-2azq,2005-10-04,2005-09-12
-2az3,2005-12-20,2005-09-09
-4azf,2012-09-05,2012-06-25
-1azr,1993-07-15,1993-03-04
-3azu,1993-07-15,1991-01-11
-7azo,2022-06-01,2020-11-17
-1azt,1998-02-25,1997-11-20
-3az6,2012-05-09,2011-05-20
-6az1,2017-12-06,2017-09-09
-2azx,2006-08-01,2005-09-12
-9azq,2024-05-29,2024-03-11
-7aze,2021-12-01,2020-11-16
-5azr,2016-01-20,2015-10-21
-5azi,2016-10-19,2015-10-08
-7azn,2021-01-13,2020-11-16
-3azf,2011-09-21,2011-05-25
-8aze,2023-09-20,2022-09-06
-8azp,2024-03-20,2022-09-06
-7azk,2021-12-01,2020-11-16
-2azr,2005-12-06,2005-09-12
-7azt,2021-08-18,2020-11-17
-4az6,2013-07-10,2012-06-23
-8azd,2023-09-13,2022-09-05
-8azo,2024-03-20,2022-09-06
-2az8,2006-02-28,2005-09-09
-8azm,2024-03-20,2022-09-06
-4azu,1994-01-31,1993-06-23
-6azq,2018-02-21,2017-09-11
-7azy,2021-05-19,2020-11-17
-9az4,2024-05-29,2024-03-10
-7az4,2021-07-28,2020-11-16
-3az3,2011-11-02,2011-05-20
-2azb,2006-02-28,2005-09-09
-1az2,1998-03-18,1997-11-24
-5az3,2015-11-18,2015-09-18
-4azl,2013-07-03,2012-06-26
-3aze,2011-09-21,2011-05-25
-4az7,2013-07-10,2012-06-23
-6az0,2017-11-15,2017-09-09
-7az8,2021-12-01,2020-11-16
-5azq,2016-01-20,2015-10-21
-3azn,2011-09-21,2011-05-25
-6azk,2017-12-13,2017-09-11
-7az2,2021-06-16,2020-11-14
-3azb,2012-02-29,2011-05-21
-5aze,2015-11-11,2015-10-02
-6azy,2018-10-03,2017-09-13
-7azd,2021-12-01,2020-11-16
-2azh,2005-09-20,2005-09-10
-7az5,2021-12-01,2020-11-16
-4az0,2012-09-26,2012-06-22
-2azm,2006-01-31,2005-09-12
-2azy,2006-11-14,2005-09-12
-3az1,2011-11-02,2011-05-20
-1azu,1980-09-26,1980-08-04
-7azq,2021-12-01,2020-11-17
-3azj,2011-09-21,2011-05-25
-5az5,2016-10-05,2015-09-27
-1azl,1998-05-20,1997-11-18
-6aze,2018-09-19,2017-09-11
-4azy,2012-10-17,2012-06-27
-4azv,2012-09-26,2012-06-26
-3azi,2011-09-21,2011-05-25
-3azk,2011-09-21,2011-05-25
-1azv,1998-02-25,1997-11-21
-9azp,2024-05-29,2024-03-11
-5az8,2016-01-13,2015-09-27
-8azi,2024-03-20,2022-09-06
-7azv,2021-12-01,2020-11-17
-3az7,2012-05-09,2011-05-20
-3az5,2012-05-09,2011-05-20
-3azl,2011-09-21,2011-05-25
-1azb,1993-10-31,1992-12-16
-5azj,2016-10-19,2015-10-08
-4azm,2013-08-07,2012-06-26
-8azg,2023-09-13,2022-09-06
-9azi,2024-05-01,2024-03-11
-4azk,2013-05-01,2012-06-26
-7azu,2021-01-27,2020-11-17
-3aza,2012-02-29,2011-05-21
-4azg,2013-07-10,2012-06-25
-4azi,2013-07-10,2012-06-26
-6azp,2017-12-27,2017-09-11
-2azz,2006-11-14,2005-09-12
-3az9,2012-02-29,2011-05-21
-1azp,1999-01-13,1997-11-19
-6azt,2018-02-07,2017-09-13
-5azf,2015-12-30,2015-10-05
-5az1,2016-02-10,2015-09-15
-4azb,2013-07-10,2012-06-25
-5azu,1994-01-31,1993-06-23
-4az5,2013-07-10,2012-06-22
-3azx,2011-11-23,2011-06-03
-3az2,2011-11-02,2011-05-20
-1azd,1998-04-29,1997-11-16
-7az1,2021-06-16,2020-11-14
-6azu,2018-03-21,2017-09-13
-7azl,2021-12-01,2020-11-16
-7aza,2021-07-28,2020-11-16
-7azc,2021-12-01,2020-11-16
-7azr,2021-12-01,2020-11-17
-7az6,2021-12-01,2020-11-16
-4az4,2012-08-22,2012-06-22
-7az0,2022-06-01,2020-11-13
-3azq,2011-07-27,2011-05-27
-6azw,2018-03-21,2017-09-13
-8azf,2023-09-13,2022-09-06
-2az1,2005-12-20,2005-09-09
-2azd,2005-09-20,2005-09-10
-6azj,2018-09-12,2017-09-11
-1azn,1994-10-15,1994-05-27
-8azw,2023-06-07,2022-09-06
-3azz,2011-11-23,2011-06-03
-4aza,2012-08-08,2012-06-25
-3azm,2011-09-21,2011-05-25
-5az0,2016-02-10,2015-09-15
-1azs,1998-02-25,1997-11-20
-2azc,2006-02-28,2005-09-10
-4azw,2012-09-26,2012-06-26
-8aza,2022-10-26,2022-09-05
-7azs,2022-06-08,2020-11-17
-3azg,2011-09-21,2011-05-25
-3azr,2011-08-10,2011-05-30
-6azr,2017-12-27,2017-09-11
-8azv,2023-06-07,2022-09-06
-8azl,2024-03-20,2022-09-06
-1az0,1998-06-19,1997-11-24
-7az9,2021-07-28,2020-11-16
-5azp,2016-06-08,2015-10-21
-8azz,2023-06-21,2022-09-06
-3azy,2011-11-23,2011-06-03
-2az5,2005-11-29,2005-09-09
-9az7,2024-03-20,2024-03-10
-5az6,2016-01-13,2015-09-27
-3azh,2011-09-21,2011-05-25
-8az8,2022-11-23,2022-09-05
-2azu,1993-07-15,1991-01-11
-8azx,2023-06-07,2022-09-06
-7az3,2021-07-28,2020-11-16
-5azh,2015-12-30,2015-10-05
-3azs,2011-08-10,2011-05-30
-4azj,2013-05-01,2012-06-26
-5aza,2016-01-13,2015-09-27
-6azv,2018-03-21,2017-09-13
-6az3,2017-12-06,2017-09-09
-4azs,2012-09-26,2012-06-26
-3az4,2012-05-09,2011-05-20
-1azc,1993-10-31,1992-12-16
-7azf,2021-12-01,2020-11-16
-4azt,2012-09-26,2012-06-26
-2aza,1987-01-15,1986-10-14
-4azc,2013-07-10,2012-06-25
-8azy,2023-06-07,2022-09-06
-3azt,2011-08-10,2011-05-30
-4azh,2013-07-10,2012-06-26
-2az4,2005-10-25,2005-09-09
-1azi,1998-02-25,1997-10-11
-1azq,1999-01-13,1997-11-20
-6azs,2018-02-21,2017-09-11
-2azn,2006-08-29,2005-09-12
-3az8,2012-02-29,2011-05-20
-8azr,2023-06-07,2022-09-06
-7azg,2021-12-01,2020-11-16
-1az8,1999-01-13,1997-11-26
-8azn,2024-03-20,2022-09-06
-6cml,2019-03-13,2018-03-05
-1cm0,1999-07-06,1999-05-12
-3cm5,2008-12-30,2008-03-21
-4cmi,2015-01-21,2014-01-16
-1cm4,1998-03-04,1997-09-23
-6cm1,2018-12-12,2018-03-02
-6cmk,2019-03-13,2018-03-05
-1cma,1993-10-31,1992-08-24
-4cmv,2014-02-19,2014-01-18
-4cmp,2014-02-12,2014-01-16
-3cmx,2008-05-20,2008-03-24
-7cmi,2020-12-23,2020-07-27
-5cm0,2016-09-14,2015-07-16
-4cmk,2015-01-21,2014-01-16
-8cm4,2023-09-27,2023-02-17
-2cmf,2006-09-04,2006-05-08
-2cm8,2006-08-17,2006-05-04
-6cmi,2018-04-18,2018-03-05
-7cm4,2021-01-20,2020-07-24
-4cm3,2015-01-21,2014-01-15
-7cmq,2020-08-12,2020-07-28
-6cm2,2019-06-19,2018-03-02
-3cmy,2009-02-17,2008-03-24
-7cmc,2020-09-02,2020-07-27
-4cmn,2014-04-16,2014-01-16
-5cmf,2016-07-20,2015-07-16
-2cmw,2006-06-15,2006-05-15
-4cmt,2014-05-28,2014-01-17
-6cm4,2018-03-14,2018-03-02
-4cma,2015-01-21,2014-01-15
-5cmx,2016-01-13,2015-07-17
-5cms,2015-11-04,2015-07-17
-8cms,2023-11-15,2023-02-21
-1cmq,1994-01-31,1993-11-23
-4cmd,2014-03-26,2014-01-16
-7cm0,2021-12-22,2020-07-23
-8cma,2024-02-28,2023-02-18
-5cmp,2015-08-12,2015-07-17
-2cm7,2006-08-17,2006-05-04
-2cm5,2006-12-04,2006-05-04
-3cmb,2008-04-01,2008-03-21
-4cmo,2014-05-28,2014-01-16
-8cmw,2024-03-06,2023-02-21
-4cmf,2014-03-26,2014-01-16
-1cm8,2000-05-17,1999-05-17
-5cmn,2015-08-12,2015-07-17
-8cml,2023-09-27,2023-02-20
-8cmz,2024-03-06,2023-02-21
-2cmo,2006-06-06,2006-05-11
-1cmt,1995-07-10,1995-04-11
-5cmj,2016-07-20,2015-07-16
-3cmw,2008-05-20,2008-03-24
-1cmy,1993-10-31,1992-09-18
-2cml,2007-06-05,2006-05-10
-8cmq,2024-03-06,2023-02-20
-5cm7,2015-08-26,2015-07-16
-4cm0,2014-03-05,2014-01-15
-4cm6,2015-01-21,2014-01-15
-7cmj,2021-08-04,2020-07-27
-4cme,2015-01-21,2014-01-16
-7cmm,2021-02-03,2020-07-28
-8cmy,2023-03-22,2023-02-21
-4cmm,2014-02-26,2014-01-16
-2cm3,2006-08-17,2006-05-04
-7cms,2021-08-04,2020-07-28
-7cmv,2021-03-10,2020-07-29
-5cmb,2016-07-20,2015-07-16
-7cmf,2021-09-15,2020-07-27
-1cm1,1998-03-04,1997-09-23
-1cmc,1993-10-31,1992-08-28
-7cm8,2020-08-19,2020-07-25
-3cmc,2008-06-17,2008-03-21
-5cmv,2015-09-16,2015-07-17
-7cm7,2020-10-21,2020-07-25
-5cmg,2016-07-20,2015-07-16
-7cmw,2020-12-16,2020-07-29
-6cmo,2018-06-20,2018-03-05
-7cm3,2020-11-11,2020-07-24
-4cm7,2015-01-21,2014-01-15
-6cms,2018-11-14,2018-03-06
-6cme,2019-04-10,2018-03-04
-4cmu,2014-05-28,2014-01-17
-6cmj,2018-04-04,2018-03-05
-7cmp,2021-08-04,2020-07-28
-2cmk,1999-09-20,1998-09-19
-3cmp,2009-05-12,2008-03-24
-8cm9,2023-10-04,2023-02-18
-5cm2,2015-10-21,2015-07-16
-3cm7,2008-10-28,2008-03-21
-5cmm,2016-07-20,2015-07-16
-2cmc,2006-08-17,2006-05-04
-3cmd,2009-01-13,2008-03-21
-2cmy,2007-05-22,2006-05-16
-3cme,2008-09-23,2008-03-21
-4cml,2014-04-16,2014-01-16
-8cm6,2023-09-27,2023-02-17
-2cm4,2007-05-01,2006-05-04
-4cmy,2014-11-26,2014-01-18
-6cmw,2018-03-14,2018-03-06
-8cm2,2024-02-28,2023-02-17
-5cmq,2015-09-09,2015-07-17
-2cm6,2006-12-04,2006-05-04
-3cmt,2008-05-20,2008-03-24
-5cm4,2015-08-12,2015-07-16
-3cma,2008-09-23,2008-03-21
-7cm9,2021-05-19,2020-07-25
-7cmu,2021-03-10,2020-07-29
-7cma,2021-06-02,2020-07-26
-4cm4,2015-01-21,2014-01-15
-7cme,2021-09-15,2020-07-27
-3cmq,2008-07-01,2008-03-24
-5cm6,2015-07-29,2015-07-16
-7cmy,2021-08-04,2020-07-29
-4cmj,2015-01-21,2014-01-16
-5cmh,2016-07-20,2015-07-16
-2cmb,2006-08-17,2006-05-04
-1cmp,1994-01-31,1993-11-23
-4cm9,2015-01-21,2014-01-15
-7cm6,2020-10-21,2020-07-25
-7cmb,2021-07-28,2020-07-26
-3cmr,2008-07-29,2008-03-24
-8cm8,2024-02-28,2023-02-17
-1cmu,1995-07-10,1995-04-10
-3cm2,2008-10-28,2008-03-20
-3cmm,2008-08-05,2008-03-23
-8cm5,2023-09-27,2023-02-17
-2cm9,2007-05-01,2006-05-04
-3cmj,2008-10-07,2008-03-22
-3cm6,2008-12-30,2008-03-21
-2cm1,2007-06-12,2006-05-03
-4cmq,2014-02-12,2014-01-17
-6cmx,2018-07-25,2018-03-06
-5cmk,2016-07-20,2015-07-16
-1cml,1999-08-18,1999-03-30
-4cm5,2015-01-21,2014-01-15
-4cmc,2015-01-21,2014-01-16
-7cmr,2020-08-12,2020-07-28
-2cmm,1994-01-31,1993-12-24
-3cmu,2008-05-20,2008-03-24
-7cmh,2020-12-23,2020-07-27
-3cmv,2008-05-20,2008-03-24
-3cmf,2008-04-08,2008-03-21
-5cmc,2016-07-20,2015-07-16
-7cmn,2020-08-12,2020-07-28
-5cmr,2015-09-09,2015-07-17
-4cm1,2015-01-21,2014-01-15
-8cm7,2023-09-27,2023-02-17
-4cmx,2014-02-19,2014-01-18
-2cmn,2007-05-15,2006-05-11
-4cmb,2015-01-21,2014-01-16
-6cmg,2018-04-18,2018-03-05
-6cm3,2018-10-17,2018-03-02
-7cmz,2021-03-17,2020-07-29
-6cmz,2018-03-21,2018-03-06
-4cmg,2015-01-21,2014-01-16
-1cm5,1999-12-08,1999-05-14
-8cmk,2024-03-06,2023-02-20
-1cmn,2000-03-22,1999-05-07
-2cma,2006-08-17,2006-05-04
-4cm8,2015-01-21,2014-01-15
-8cmj,2023-09-20,2023-02-20
-6cm9,2018-08-08,2018-03-03
-7cm1,2020-11-18,2020-07-23
-6cmr,2018-11-14,2018-03-06
-7cmd,2020-09-02,2020-07-27
-8cmo,2024-03-06,2023-02-20
-6cmm,2018-03-21,2018-03-05
-1cmj,2000-03-22,1999-05-07
-8ip4,2023-06-14,2023-03-14
-5ip0,2017-01-25,2016-03-09
-6iph,2019-05-29,2018-11-03
-1ipb,2002-05-08,2001-05-08
-6ip5,2019-05-29,2018-11-02
-8ip9,2024-02-21,2023-03-14
-3ipa,2010-07-14,2009-08-17
-4ipn,2013-04-24,2013-01-10
-3ipp,2009-12-08,2009-08-18
-3ipx,2010-08-18,2009-08-18
-5ipa,2017-03-29,2016-03-09
-5ipg,2016-09-21,2016-03-09
-6ipw,2019-10-16,2018-11-05
-3ipc,2010-07-14,2009-08-17
-6ipj,2019-05-29,2018-11-03
-3ip8,2009-10-06,2009-08-17
-4ip0,2014-08-13,2013-01-09
-1ipw,1997-08-20,1996-03-04
-5ipm,2016-03-30,2016-03-09
-3ip1,2009-09-29,2009-08-15
-6ipk,2019-05-29,2018-11-03
-3ipn,2010-02-02,2009-08-18
-6ipn,2019-05-29,2018-11-03
-8ipl,2024-01-03,2023-03-14
-3ip6,2010-07-14,2009-08-17
-3ips,2010-06-02,2009-08-18
-1ipj,2002-05-16,2001-05-16
-4iph,2013-09-11,2013-01-09
-6ipi,2019-05-29,2018-11-03
-3ipv,2009-09-08,2009-08-18
-5ip7,2016-05-11,2016-03-09
-8ipz,2023-12-13,2023-03-15
-2ipp,2006-12-12,2006-10-12
-3ipt,2010-01-12,2009-08-18
-8ipm,2024-01-03,2023-03-14
-4ipz,2013-11-06,2013-01-10
-1iph,1997-09-04,1995-12-31
-2iph,2007-10-23,2006-10-12
-8ip3,2023-06-14,2023-03-14
-3ipk,2010-03-31,2009-08-17
-3ipu,2010-06-02,2009-08-18
-5ipl,2016-03-30,2016-03-09
-2ipm,2007-03-20,2006-10-12
-8ipx,2023-08-09,2023-03-15
-5ipy,2017-01-18,2016-03-10
-4ip2,2013-07-10,2013-01-09
-1ip7,2001-11-14,2001-04-20
-8ipy,2023-08-09,2023-03-15
-8ipb,2024-02-21,2023-03-14
-5ip3,2017-03-22,2016-03-09
-1ipp,1998-09-02,1998-03-19
-6ip8,2019-05-29,2018-11-02
-6ipq,2019-03-13,2018-11-03
-1ipe,2003-06-03,2001-05-09
-2ipn,2007-03-20,2006-10-12
-1ips,1998-03-25,1997-03-21
-3ipq,2010-06-02,2009-08-18
-5ipe,2017-03-15,2016-03-09
-8ip5,2023-06-14,2023-03-14
-6ipm,2019-05-29,2018-11-03
-2ips,2006-10-24,2006-10-12
-4ip5,2013-12-04,2013-01-09
-8ips,2023-06-14,2023-03-14
-5iph,2016-09-21,2016-03-09
-6ipe,2019-05-29,2018-11-03
-5ipd,2017-03-15,2016-03-09
-5ip6,2017-03-29,2016-03-09
-2ipj,2007-06-19,2006-10-12
-4ip4,2013-12-04,2013-01-09
-2ipi,2007-01-23,2006-10-12
-1ipc,2002-05-08,2001-05-08
-8ipa,2024-02-21,2023-03-14
-5ipz,2017-03-29,2016-03-10
-8ipr,2023-06-14,2023-03-14
-8ip8,2024-02-21,2023-03-14
-2ipg,2007-06-19,2006-10-12
-5ip2,2017-03-22,2016-03-09
-4ip7,2013-01-30,2013-01-09
-3ipy,2010-08-18,2009-08-18
-4ipf,2013-02-20,2013-01-09
-6ipg,2019-05-29,2018-11-03
-3ip7,2010-07-14,2009-08-17
-5ipp,2017-08-02,2016-03-09
-6ipp,2019-03-13,2018-11-03
-2ipu,2007-10-09,2006-10-12
-6ipo,2019-03-13,2018-11-03
-3ipe,2010-11-17,2009-08-17
-3ipb,2010-11-17,2009-08-17
-3ip5,2010-07-14,2009-08-17
-6ipd,2019-05-29,2018-11-03
-5ipc,2017-03-15,2016-03-09
-4ipp,2014-01-15,2013-01-10
-5ip9,2016-05-11,2016-03-09
-1ip3,2001-11-14,2001-04-20
-3ipo,2009-12-08,2009-08-18
-2ipl,2007-03-20,2006-10-12
-6ipu,2020-01-15,2018-11-04
-6ip6,2019-05-29,2018-11-02
-4ipm,2013-06-12,2013-01-10
-2ipo,2007-08-28,2006-10-12
-3ip9,2010-07-14,2009-08-17
-2ipx,2006-10-24,2006-10-12
-3ipr,2009-09-15,2009-08-18
-8ipd,2023-08-09,2023-03-14
-4ipi,2013-04-10,2013-01-09
-1ipf,2003-06-03,2001-05-09
-4ipj,2013-04-10,2013-01-09
-4ips,2013-05-01,2013-01-10
-3ipj,2009-10-20,2009-08-17
-5ipj,2016-06-22,2016-03-09
-4ipw,2013-05-01,2013-01-10
-4ipe,2014-01-22,2013-01-09
-8ipw,2024-03-20,2023-03-15
-8ipt,2023-06-14,2023-03-14
-5ipn,2016-03-30,2016-03-09
-8ipk,2024-01-03,2023-03-14
-6ip0,2019-04-10,2018-11-01
-2ipf,2007-06-19,2006-10-12
-6ipf,2019-05-29,2018-11-03
-6ip2,2019-04-24,2018-11-01
-3ip0,2009-08-25,2009-08-15
-2ipw,2006-11-28,2006-10-12
-8ipj,2024-03-20,2023-03-14
-6ip9,2019-02-20,2018-11-02
-3iph,2009-11-24,2009-08-17
-5ipf,2017-03-15,2016-03-09
-6ipl,2019-05-29,2018-11-03
-6ip4,2019-04-10,2018-11-02
-3ip4,2009-11-24,2009-08-17
-2cy3,1994-10-15,1994-07-01
-8cyi,2023-04-12,2022-05-23
-5cyr,2015-11-11,2015-07-30
-6cyy,2019-04-17,2018-04-07
-6cyg,2019-04-10,2018-04-05
-5cy8,2016-08-03,2015-07-30
-7cy1,2021-01-27,2020-09-03
-6cyj,2019-04-17,2018-04-05
-4cyk,2014-05-21,2014-04-11
-4cyi,2014-06-11,2014-04-11
-1cyy,2000-03-08,1999-08-31
-3cyr,1998-01-28,1997-07-24
-2cyp,1986-01-21,1985-08-27
-3cyh,1996-07-11,1996-02-27
-6cyl,2018-10-10,2018-04-06
-5cyz,2016-08-03,2015-07-31
-6cyh,2019-04-10,2018-04-05
-2cyc,2005-11-22,2005-07-06
-4cyd,2014-12-17,2014-04-10
-1cy4,2000-03-08,1999-08-31
-4cyv,2014-06-11,2014-04-15
-1cy6,2000-03-08,1999-08-31
-2cyy,2006-09-19,2005-07-08
-6cyq,2018-10-10,2018-04-06
-3cyu,2008-05-27,2008-04-26
-1cyo,1994-11-30,1994-08-03
-6cyc,2018-09-19,2018-04-05
-5cyi,2015-09-16,2015-07-30
-1cyg,1995-02-27,1993-02-03
-8cyo,2024-01-17,2022-05-24
-3cyz,2009-04-28,2008-04-27
-7cy8,2020-12-30,2020-09-03
-8cy1,2023-01-11,2022-05-22
-3cy1,2008-09-23,2008-04-25
-1cy5,1999-09-13,1999-08-31
-4cyq,2014-10-01,2014-04-14
-2cy4,2006-01-04,2005-07-04
-3cyj,2008-05-06,2008-04-25
-3cy4,2008-05-13,2008-04-25
-7cy7,2020-12-30,2020-09-03
-4cyn,2014-10-01,2014-04-14
-1cy0,2000-03-08,1999-08-31
-5cyv,2015-08-12,2015-07-30
-6cyi,2019-04-10,2018-04-05
-6cyb,2018-09-19,2018-04-05
-1cy7,2000-03-08,1999-08-31
-4cyu,2015-01-28,2014-04-15
-5cym,2015-12-30,2015-07-30
-6cym,2018-05-09,2018-04-06
-4cyo,2014-10-01,2014-04-14
-6cyd,2018-09-19,2018-04-05
-5cyo,2016-08-03,2015-07-30
-4cyg,2014-12-10,2014-04-11
-7cyn,2021-01-06,2020-09-03
-8cy7,2022-07-06,2022-05-23
-6cyp,2018-10-10,2018-04-06
-7cy3,2020-09-30,2020-09-03
-6cyv,2019-01-09,2018-04-06
-1cy8,2000-03-08,1999-08-31
-7cyi,2021-09-15,2020-09-03
-5cy3,2015-09-23,2015-07-30
-6cyx,2018-10-10,2018-04-06
-4cyf,2014-12-10,2014-04-11
-3cy0,2008-09-23,2008-04-25
-7cyf,2021-06-23,2020-09-03
-7cyp,2021-06-09,2020-09-04
-2cyh,1996-07-11,1996-02-27
-5cy4,2015-08-19,2015-07-30
-4cym,2014-06-04,2014-04-13
-5cyt,1989-07-12,1988-01-14
-3cyx,2008-05-27,2008-04-27
-2cyz,2006-01-09,2005-07-09
-1cyc,1976-10-06,1976-08-01
-7cyc,2020-12-23,2020-09-03
-7cy9,2020-09-30,2020-09-03
-7cya,2021-06-16,2020-09-03
-3cyt,1980-09-16,1980-07-01
-7cyd,2020-12-23,2020-09-03
-2cy6,2006-06-13,2005-07-05
-2cy0,2005-07-12,2005-07-01
-3cy3,2008-07-15,2008-04-25
-3cyw,2008-05-27,2008-04-27
-3cy2,2008-07-15,2008-04-25
-2cy2,2006-01-04,2005-07-04
-6cy5,2018-05-02,2018-04-04
-2cy5,2006-01-04,2005-07-04
-8cyb,2022-07-06,2022-05-23
-8cy5,2023-01-11,2022-05-22
-6cyu,2018-10-10,2018-04-06
-7cyw,2020-09-23,2020-09-04
-8cya,2022-07-06,2022-05-23
-1cyi,1996-01-29,1995-05-09
-6cys,2018-10-10,2018-04-06
-6cy7,2019-03-13,2018-04-04
-8cy0,2023-01-11,2022-05-22
-1cy1,2000-03-03,1999-08-31
-6cy9,2018-12-05,2018-04-05
-2cyd,2006-06-27,2005-07-06
-8cyu,2023-08-30,2022-05-24
-7cyv,2021-09-15,2020-09-04
-6cyz,2018-04-18,2018-04-07
-2cye,2006-01-06,2005-07-06
-2cym,1994-04-30,1993-09-29
-3cyl,2009-05-05,2008-04-25
-4cyr,2015-04-29,2014-04-14
-4cy3,2014-05-14,2014-04-10
-5cyb,2016-09-14,2015-07-30
-4cyw,2014-06-11,2014-04-15
-7cy6,2020-12-30,2020-09-03
-3cy5,2009-04-28,2008-04-25
-4cys,2015-04-29,2014-04-14
-4cyz,2014-06-11,2014-04-16
-5cyp,2016-08-03,2015-07-30
-6cyw,2019-04-10,2018-04-06
-7cy4,2020-12-30,2020-09-03
-7cy5,2020-12-30,2020-09-03
-3cyq,2008-07-08,2008-04-26
-4cyh,1996-07-11,1996-02-27
-3cye,2008-08-05,2008-04-25
-1cyj,1996-01-29,1995-05-09
-8cy3,2023-01-11,2022-05-22
-1cyq,1999-11-19,1999-08-31
-1cyd,1996-10-14,1995-09-01
-6cy6,2018-04-18,2018-04-04
-3cym,2008-05-27,2008-04-25
-4cyb,2014-06-25,2014-04-10
-2cyb,2005-11-22,2005-07-06
-7cyy,2021-09-08,2020-09-05
-7cyq,2020-12-09,2020-09-04
-3cys,1994-08-31,1994-02-28
-5cyx,2016-11-02,2015-07-31
-4cy8,2015-03-18,2014-04-10
-8cy2,2023-01-11,2022-05-22
-8cyh,2023-06-07,2022-05-23
-5cy7,2016-08-03,2015-07-30
-1cy2,2000-03-08,1999-08-31
-6cyt,2018-12-12,2018-04-06
-7cyx,2020-10-14,2020-09-05
-1cyn,1996-01-29,1995-05-22
-3cyy,2008-09-23,2008-04-27
-7cyk,2021-01-13,2020-09-03
-6cy8,2019-01-16,2018-04-05
-5cyh,1996-07-11,1996-02-27
-7cym,2021-08-18,2020-09-03
-4cy5,2014-05-14,2014-04-10
-6cy3,2018-04-18,2018-04-04
-4cyp,2014-10-22,2014-04-14
-5cyq,2015-12-30,2015-07-30
-8cyz,2023-08-30,2022-05-24
-2cyf,2006-06-13,2005-07-06
-3cyi,2008-07-01,2008-04-25
-5cy9,2016-01-13,2015-07-30
-8cy4,2023-01-11,2022-05-22
-4cyy,2014-12-10,2014-04-16
-4cyj,2014-06-11,2014-04-11
-1cyf,1995-12-07,1995-07-03
-4cy2,2014-05-14,2014-04-09
-7cu5,2020-10-14,2020-08-21
-5cuj,2016-07-27,2015-07-24
-3cu4,2008-10-21,2008-04-15
-3cun,2008-06-24,2008-04-16
-4cuc,2014-08-20,2014-03-17
-3cuw,2009-04-21,2008-04-17
-3cur,2008-08-05,2008-04-17
-5cud,2015-09-09,2015-07-24
-5cuc,2015-09-09,2015-07-24
-6cu0,2018-05-09,2018-03-23
-7cup,2020-12-16,2020-08-23
-2cup,2005-11-27,2005-05-27
-4cut,2014-04-02,2014-03-21
-2cuz,2006-09-05,2005-05-31
-5cup,2016-03-23,2015-07-24
-3cu8,2009-05-05,2008-04-16
-8cuo,2023-04-05,2022-05-17
-6cub,2019-03-27,2018-03-25
-5cuh,2016-02-10,2015-07-24
-7cuu,2021-06-23,2020-08-24
-6cu5,2018-04-04,2018-03-23
-6cuk,2018-06-27,2018-03-26
-8cu6,2022-08-31,2022-05-16
-6cu9,2019-03-27,2018-03-24
-3cu2,2008-04-29,2008-04-15
-5cu4,2016-07-27,2015-07-24
-5cu1,2016-08-17,2015-07-24
-4cub,2014-08-20,2014-03-17
-3cuj,2009-04-21,2008-04-16
-4cuq,2014-04-02,2014-03-21
-5cua,2015-09-09,2015-07-24
-1cu4,2000-04-17,1999-08-20
-3cus,2008-08-05,2008-04-17
-7cu1,2020-11-25,2020-08-20
-5cu2,2016-11-30,2015-07-24
-1cur,1996-11-08,1996-04-19
-4cu4,2014-04-09,2014-03-17
-1cu1,2000-08-23,1999-08-20
-8cu3,2023-07-26,2022-05-16
-5cub,2015-09-09,2015-07-24
-4cu8,2014-08-20,2014-03-17
-2cu0,2006-05-24,2005-05-24
-2cuu,2006-08-15,2005-05-28
-6cue,2018-07-11,2018-03-26
-6cuo,2019-02-06,2018-03-26
-8cup,2023-04-05,2022-05-17
-3cup,2009-04-21,2008-04-16
-5cu3,2016-07-27,2015-07-24
-7cuw,2021-08-25,2020-08-25
-7cu0,2020-11-25,2020-08-20
-4cua,2014-08-20,2014-03-17
-5cuy,2016-03-02,2015-07-25
-4cup,2014-04-02,2014-03-21
-4cuo,2014-07-23,2014-03-20
-7cu9,2021-08-25,2020-08-21
-6cun,2018-06-27,2018-03-26
-8cu1,2023-07-26,2022-05-16
-5cuu,2016-03-02,2015-07-25
-3cut,2009-04-21,2008-04-17
-1cuo,2000-08-23,1999-08-21
-7cuq,2021-08-25,2020-08-24
-6cuz,2018-09-26,2018-03-27
-4cu7,2014-08-20,2014-03-17
-4cu0,2014-05-07,2014-03-15
-8cur,2023-04-05,2022-05-17
-2cu3,2006-05-23,2005-05-25
-7cum,2020-11-11,2020-08-23
-5cus,2015-10-14,2015-07-25
-5cuv,2016-03-02,2015-07-25
-8cuh,2022-11-23,2022-05-17
-6cup,2019-02-06,2018-03-26
-3cui,2009-04-21,2008-04-16
-4cuu,2014-04-02,2014-03-21
-3cu9,2009-04-21,2008-04-16
-2cua,1999-05-28,1999-02-18
-5cu5,2015-09-23,2015-07-24
-2cuq,2005-11-27,2005-05-27
-7cuf,2020-11-25,2020-08-22
-5cug,2015-09-09,2015-07-24
-2cur,2005-11-27,2005-05-27
-8cu2,2023-07-26,2022-05-16
-3cu0,2008-05-06,2008-04-15
-3cuz,2008-11-11,2008-04-17
-4cus,2014-04-02,2014-03-21
-8cuc,2023-05-24,2022-05-17
-3cuf,2009-04-21,2008-04-16
-4cuf,2014-05-14,2014-03-18
-4cud,2014-05-21,2014-03-18
-4cu9,2014-08-20,2014-03-17
-7cu3,2020-11-18,2020-08-20
-8cu0,2022-08-31,2022-05-16
-7cun,2020-11-25,2020-08-23
-2cul,2006-01-24,2005-05-26
-3cuu,2009-04-21,2008-04-17
-4cum,2014-05-28,2014-03-20
-6cul,2019-02-06,2018-03-26
-8cua,2023-05-10,2022-05-17
-6cuv,2018-09-26,2018-03-26
-7cux,2021-08-25,2020-08-25
-5cu0,2016-11-30,2015-07-24
-8cu4,2023-07-26,2022-05-16
-4cu1,2014-05-07,2014-03-15
-8cuq,2023-04-05,2022-05-17
-5cu8,2015-09-09,2015-07-24
-4cug,2014-04-16,2014-03-18
-4cuz,2014-04-16,2014-03-22
-2cu8,2005-11-25,2005-05-25
-7cu2,2020-11-25,2020-08-20
-3cuh,2009-04-21,2008-04-16
-5cue,2015-09-09,2015-07-24
-4cur,2014-04-02,2014-03-21
-8cum,2023-04-05,2022-05-17
-7cue,2021-07-07,2020-08-22
-3cug,2009-04-21,2008-04-16
-3cu3,2008-04-29,2008-04-15
-7cuc,2020-11-25,2020-08-22
-6cud,2018-05-16,2018-03-25
-5cu6,2016-07-27,2015-07-24
-7cug,2020-11-25,2020-08-23
-8cul,2023-04-05,2022-05-17
-3cuv,2009-04-21,2008-04-17
-6cur,2019-02-06,2018-03-26
-4cuk,2015-05-27,2014-03-19
-6cuu,2018-07-25,2018-03-26
-4cun,2014-05-28,2014-03-20
-5cum,2016-07-27,2015-07-24
-3cuk,2008-07-22,2008-04-16
-6cut,2018-09-26,2018-03-26
-6cuf,2018-07-25,2018-03-26
-7cut,2021-06-23,2020-08-24
-6cu6,2019-09-25,2018-03-23
-8cu7,2022-08-31,2022-05-16
-5cuo,2016-03-23,2015-07-24
-6cua,2019-03-27,2018-03-24
-5cur,2015-11-04,2015-07-24
-8cu8,2023-05-24,2022-05-16
-6cux,2018-07-25,2018-03-26
-3cux,2008-11-11,2008-04-17
-8cuy,2023-02-15,2022-05-17
-1cul,2001-01-10,1999-08-20
-4cue,2014-05-21,2014-03-18
-4cul,2014-05-28,2014-03-20
-7cub,2021-08-25,2020-08-22
-6cug,2019-01-16,2018-03-26
-5cuq,2016-02-03,2015-07-24
-6cu2,2019-02-20,2018-03-23
-8cub,2022-08-31,2022-05-17
-3cu7,2008-06-10,2008-04-16
-6hfn,2018-10-24,2018-08-21
-6hfr,2018-10-24,2018-08-21
-1hfu,2001-12-06,2000-12-08
-8hfn,2022-12-07,2022-11-11
-8hfp,2023-11-22,2022-11-11
-5hfj,2016-11-16,2016-01-07
-8hfz,2023-08-30,2022-11-13
-8hf1,2023-09-06,2022-11-09
-5hf6,2016-06-22,2016-01-06
-6hfc,2018-08-29,2018-08-21
-8hfs,2023-02-08,2022-11-12
-6hfw,2018-09-19,2018-08-21
-1hfw,2001-08-07,2000-12-08
-2hf7,2008-03-04,2006-06-23
-6hft,2019-03-27,2018-08-21
-4hfh,2013-04-17,2012-10-05
-8hf4,2023-10-04,2022-11-09
-1hf6,2001-11-29,2000-11-29
-5hf2,2017-01-18,2016-01-06
-8hfi,2024-05-15,2022-11-10
-5hfa,2016-06-22,2016-01-06
-3hfv,2009-07-21,2009-05-12
-8hfh,2023-03-08,2022-11-10
-5hfi,2016-10-26,2016-01-07
-4hf8,2013-11-06,2012-10-05
-1hfy,1997-07-07,1996-06-13
-4hfi,2013-02-20,2012-10-05
-4hfc,2013-04-17,2012-10-05
-1hf4,2001-01-07,2000-11-29
-8hff,2024-05-15,2022-11-10
-2hfn,2006-12-19,2006-06-24
-4hfd,2013-04-17,2012-10-05
-5hfs,2016-04-06,2016-01-07
-8hfy,2023-08-30,2022-11-13
-8hf5,2023-10-04,2022-11-09
-2hf4,2006-08-29,2006-06-22
-1hfp,1998-01-28,1997-11-04
-2hf5,2007-05-01,2006-06-23
-6hfu,2018-10-24,2018-08-21
-8hfo,2022-12-07,2022-11-11
-8hfm,2022-12-07,2022-11-11
-4hfp,2013-03-13,2012-10-05
-3hf5,2009-09-29,2009-05-11
-2hf8,2006-07-04,2006-06-23
-1hfa,2001-02-12,2000-11-30
-5hf0,2017-01-18,2016-01-06
-6hf3,2018-08-29,2018-08-21
-3hf3,2010-02-23,2009-05-11
-1hf3,2001-05-31,2000-11-27
-6hfp,2018-10-24,2018-08-21
-3hfp,2010-05-19,2009-05-12
-4hf5,2013-02-13,2012-10-04
-2hf1,2006-08-22,2006-06-22
-6hfj,2018-10-24,2018-08-21
-6hfq,2018-10-24,2018-08-21
-6hfh,2018-10-24,2018-08-21
-8hfk,2023-06-07,2022-11-10
-8hfr,2023-04-12,2022-11-12
-3hfy,2009-08-18,2009-05-13
-3hf8,2010-04-21,2009-05-11
-6hfe,2018-10-24,2018-08-21
-3hf4,2010-05-19,2009-05-11
-5hf1,2016-11-16,2016-01-06
-8hfq,2023-11-08,2022-11-11
-8hfa,2023-05-31,2022-11-10
-5hf8,2016-06-22,2016-01-06
-1hfq,1998-01-28,1997-11-04
-6hf5,2018-12-05,2018-08-21
-3hfz,2009-07-21,2009-05-13
-2hfz,2007-02-06,2006-06-26
-8hfl,2024-05-15,2022-11-11
-2hf9,2006-07-04,2006-06-23
-3hfx,2010-03-31,2009-05-13
-6hfs,2018-10-24,2018-08-21
-5hfb,2016-11-16,2016-01-06
-4hf3,2013-10-23,2012-10-04
-8hf8,2023-09-06,2022-11-09
-2hfj,2006-09-19,2006-06-24
-6hfx,2019-04-24,2018-08-22
-2hf3,2006-08-29,2006-06-22
-8hfb,2023-03-08,2022-11-10
-3hfw,2010-05-26,2009-05-13
-4hf4,2012-12-12,2012-10-04
-8hf6,2023-10-04,2022-11-09
-1hfz,1997-07-29,1996-06-13
-5hf9,2016-06-22,2016-01-06
-6hfi,2018-10-24,2018-08-21
-6hf4,2019-04-24,2018-08-21
-3hf2,2009-06-30,2009-05-10
-2hfu,2007-04-17,2006-06-26
-4hfm,2013-01-30,2012-10-05
-4hfn,2013-01-30,2012-10-05
-1hfx,1997-07-07,1996-06-13
-8hfv,2023-12-13,2022-11-12
-1hfr,1998-01-28,1997-11-04
-8hfd,2023-10-18,2022-11-10
-3hfg,2009-09-29,2009-05-11
-8hfx,2023-08-30,2022-11-13
-6hfa,2020-07-08,2018-08-21
-6hff,2018-10-24,2018-08-21
-2hfe,2006-09-12,2006-06-23
-5hfu,2016-03-30,2016-01-07
-4hfb,2013-04-17,2012-10-05
-8hfc,2023-11-22,2022-11-10
-2hfo,2006-12-19,2006-06-24
-8hf9,2023-05-31,2022-11-10
-2hfw,2007-05-08,2006-06-26
-6hfm,2019-03-27,2018-08-21
-1hfc,1995-01-26,1994-09-13
-2hfc,2007-03-27,2006-06-23
-3hft,2009-06-23,2009-05-12
-3hfk,2009-09-29,2009-05-12
-6hfl,2018-10-24,2018-08-21
-8hf3,2023-11-22,2022-11-09
-6hfd,2018-10-24,2018-08-21
-8hfg,2024-05-15,2022-11-10
-6hf7,2019-06-19,2018-08-21
-3hfj,2009-09-08,2009-05-11
-1hfs,1998-02-18,1997-02-13
-6hf0,2018-08-29,2018-08-21
-8hfj,2023-06-07,2022-11-10
-3hff,2009-06-16,2009-05-11
-2hfk,2006-09-19,2006-06-24
-4hfe,2013-04-17,2012-10-05
-3hfb,2010-04-21,2009-05-11
-5hff,2016-11-16,2016-01-06
-3hf1,2009-10-13,2009-05-10
-5hfe,2017-01-11,2016-01-06
-6hfv,2018-09-19,2018-08-21
-1hfe,1999-04-20,1998-11-11
-3hf6,2009-11-24,2009-05-11
-6hfb,2019-06-12,2018-08-21
-6hf6,2019-06-19,2018-08-21
-3hf7,2009-05-26,2009-05-11
-2hfp,2006-09-19,2006-06-25
-5hf3,2016-01-27,2016-01-06
-3hfr,2009-06-09,2009-05-12
-5hfk,2016-02-10,2016-01-07
-6hfy,2018-08-29,2018-08-22
-4hfr,2012-10-17,2012-10-05
-5hfc,2016-11-16,2016-01-06
-5hf5,2016-07-27,2016-01-06
-4hfu,2013-02-13,2012-10-05
-6hfk,2018-10-24,2018-08-21
-6hf2,2019-04-24,2018-08-21
-1kqf,2002-03-15,2002-01-05
-6kqx,2020-09-30,2019-08-20
-4kqu,2014-04-30,2013-05-15
-5kqs,2016-09-14,2016-07-06
-1kqu,2003-11-11,2002-01-07
-6kqk,2020-03-25,2019-08-18
-4kqa,2013-06-26,2013-05-14
-4kqp,2013-09-11,2013-05-15
-3kq7,2009-12-01,2009-11-17
-5kqc,2017-08-02,2016-07-06
-5kq2,2017-04-26,2016-07-05
-6kq4,2020-03-25,2019-08-16
-4kq5,2014-04-30,2013-05-14
-3kqf,2009-11-24,2009-11-17
-7kq8,2021-11-17,2020-11-13
-1kqb,2002-02-13,2002-01-04
-6kq1,2020-08-19,2019-08-16
-7kqh,2020-12-16,2020-11-16
-3kqq,2010-09-29,2009-11-17
-7kq6,2020-12-09,2020-11-13
-3kqg,2010-02-23,2009-11-17
-4kq2,2013-12-11,2013-05-14
-3kqi,2010-02-02,2009-11-17
-5kq4,2016-10-05,2016-07-05
-6kqy,2021-01-27,2019-08-20
-5kqg,2016-10-12,2016-07-06
-4kqg,2014-03-12,2013-05-15
-3kqy,2010-09-29,2009-11-17
-1kqp,2002-06-28,2002-01-07
-3kqk,2010-01-26,2009-11-17
-5kqy,2016-09-21,2016-07-06
-6kqd,2020-03-11,2019-08-17
-4kq1,2013-12-11,2013-05-14
-4kqq,2013-11-06,2013-05-15
-1kqw,2002-08-28,2002-01-08
-5kq3,2017-04-26,2016-07-05
-3kq0,2010-02-02,2009-11-17
-3kqb,2010-02-23,2009-11-17
-1kq0,2003-12-09,2002-01-03
-5kqi,2017-04-26,2016-07-06
-5kqn,2017-07-12,2016-07-06
-3kqa,2010-04-28,2009-11-17
-3kqx,2010-02-02,2009-11-17
-2kq9,2009-11-17,2009-11-02
-1kq9,2003-12-09,2002-01-04
-7kqd,2021-04-21,2020-11-14
-1kqg,2002-03-15,2002-01-05
-1kq3,2002-02-27,2002-01-03
-6kqi,2019-10-23,2019-08-17
-1kqe,2002-11-27,2002-01-05
-6kqq,2020-09-02,2019-08-18
-6kqh,2020-03-11,2019-08-17
-7kq5,2021-04-28,2020-11-13
-3kqr,2010-12-08,2009-11-17
-6kqs,2020-06-10,2019-08-18
-7kqr,2021-03-31,2020-11-17
-5kqv,2017-07-19,2016-07-06
-3kq6,2010-02-23,2009-11-17
-4kqk,2014-03-12,2013-05-15
-4kqs,2014-04-30,2013-05-15
-7kq9,2021-11-17,2020-11-13
-7kqj,2021-02-24,2020-11-16
-4kq4,2014-03-26,2013-05-14
-4kqb,2013-06-26,2013-05-14
-5kqw,2017-07-12,2016-07-06
-4kqv,2014-01-15,2013-05-15
-4kqj,2014-03-12,2013-05-15
-1kqd,2002-02-13,2002-01-04
-3kqc,2010-02-23,2009-11-17
-7kqu,2021-03-31,2020-11-17
-2kqc,2010-01-19,2009-11-04
-6kqn,2020-03-11,2019-08-18
-3kqw,2010-09-29,2009-11-17
-2kqt,2010-02-09,2009-11-18
-5kqq,2017-07-12,2016-07-06
-7kqz,2020-12-16,2020-11-18
-7kqt,2021-03-31,2020-11-17
-5kq5,2016-08-17,2016-07-05
-2kqb,2010-01-19,2009-11-04
-5kqf,2016-09-07,2016-07-06
-4kqw,2013-06-26,2013-05-15
-3kqp,2010-09-29,2009-11-17
-3kqd,2010-02-23,2009-11-17
-1kqn,2003-01-07,2002-01-07
-3kqs,2010-09-29,2009-11-17
-3kql,2010-01-26,2009-11-17
-3kqu,2010-01-26,2009-11-17
-5kq0,2017-04-26,2016-07-05
-1kqk,2002-04-17,2002-01-07
-7kqb,2021-05-26,2020-11-14
-5kq8,2016-08-31,2016-07-05
-7kqi,2020-12-16,2020-11-16
-1kqr,2002-03-27,2002-01-07
-1kqc,2002-02-13,2002-01-04
-7kqn,2022-03-23,2020-11-17
-1kqa,2002-04-10,2002-01-04
-4kqi,2014-03-12,2013-05-15
-3kqz,2010-02-02,2009-11-17
-2kq0,2010-11-03,2009-10-23
-7kq3,2021-04-07,2020-11-13
-3kqe,2010-02-23,2009-11-17
-4kq7,2013-07-17,2013-05-14
-3kqt,2010-09-29,2009-11-17
-1kqy,2002-01-23,2002-01-08
-7kqg,2020-12-16,2020-11-16
-1kqm,2002-11-20,2002-01-07
-7kqf,2021-11-24,2020-11-15
-4kqn,2014-05-21,2013-05-15
-6kqp,2020-09-02,2019-08-18
-6kqm,2020-03-11,2019-08-18
-6kqu,2020-08-19,2019-08-18
-5kqk,2017-04-26,2016-07-06
-4kqx,2013-06-26,2013-05-15
-1kq4,2002-02-27,2002-01-03
-3kqo,2010-09-29,2009-11-17
-5kqu,2017-07-12,2016-07-06
-4kqr,2013-11-06,2013-05-15
-6kq8,2020-03-25,2019-08-16
-2kqe,2010-01-19,2009-11-04
-4kqo,2013-11-06,2013-05-15
-3kqm,2010-09-29,2009-11-17
-5kql,2016-10-12,2016-07-06
-6kqf,2020-03-11,2019-08-17
-5kqa,2017-07-05,2016-07-06
-4kq8,2013-08-21,2013-05-14
-6kqe,2020-03-11,2019-08-17
-5kqt,2017-07-12,2016-07-06
-3kqj,2010-04-28,2009-11-17
-3kqv,2010-09-29,2009-11-17
-4kql,2014-10-15,2013-05-15
-1kqs,2002-02-22,2002-01-07
-4kqz,2013-07-10,2013-05-15
-6kqt,2020-06-10,2019-08-18
-4kqf,2014-03-12,2013-05-15
-6kql,2020-03-11,2019-08-18
-5kq6,2017-04-26,2016-07-05
-4kq6,2013-05-29,2013-05-14
-1kq2,2002-07-05,2002-01-03
-6kqj,2020-03-25,2019-08-18
-1kqo,2003-01-07,2002-01-07
-3kq4,2010-03-09,2009-11-17
-4kqm,2013-12-11,2013-05-15
-5kqz,2016-09-21,2016-07-06
-3kqn,2010-01-26,2009-11-17
-2kqd,2010-01-19,2009-11-04
-5kqr,2016-09-14,2016-07-06
-7kqs,2021-03-31,2020-11-17
-1kqz,2002-01-23,2002-01-08
-5kqb,2017-08-02,2016-07-06
-6kqg,2020-03-11,2019-08-17
-7kqp,2020-12-09,2020-11-17
-5kqh,2017-04-26,2016-07-06
-5kqx,2016-09-21,2016-07-06
-1kqv,2002-01-16,2002-01-08
-6kqo,2020-03-25,2019-08-18
-3kqh,2010-01-26,2009-11-17
-8dqp,2023-01-11,2022-07-19
-5dq4,2016-09-28,2015-09-14
-7dq5,2021-03-03,2020-12-22
-5dq9,2016-03-09,2015-09-14
-6dqa,2018-11-21,2018-06-10
-4dqi,2012-06-06,2012-02-15
-8dqi,2022-12-07,2022-07-19
-4dqu,2012-10-03,2012-02-16
-4dqy,2012-05-30,2012-02-16
-5dq8,2015-11-25,2015-09-14
-5dqc,2016-02-17,2015-09-14
-4dqm,2012-10-03,2012-02-16
-6dqv,2018-08-01,2018-06-11
-6dqx,2019-04-17,2018-06-11
-7dqu,2021-10-27,2020-12-24
-8dq0,2022-12-07,2022-07-18
-6dql,2019-05-15,2018-06-11
-3dqs,2009-03-31,2008-07-09
-8dqm,2023-04-26,2022-07-19
-5dq1,2016-09-28,2015-09-14
-3dqr,2009-03-31,2008-07-09
-6dqo,2019-01-09,2018-06-11
-6dqc,2019-06-12,2018-06-10
-5dql,2016-09-14,2015-09-14
-5dqf,2015-12-23,2015-09-14
-8dqg,2022-12-07,2022-07-19
-2dqb,2007-01-23,2006-05-25
-2dqz,2006-08-29,2006-06-02
-6dqt,2018-11-28,2018-06-11
-1dq6,2000-01-19,1999-12-30
-6dqn,2018-08-01,2018-06-11
-6dq6,2018-11-21,2018-06-10
-8dqr,2023-01-11,2022-07-19
-8dqf,2022-12-14,2022-07-19
-8dq3,2023-07-26,2022-07-18
-6dqs,2018-08-01,2018-06-11
-2dqt,2006-06-20,2006-05-30
-8dq9,2022-07-27,2022-07-18
-8dqn,2023-04-26,2022-07-19
-8dq6,2023-07-26,2022-07-18
-1dqp,2000-07-26,2000-01-04
-8dqx,2022-08-24,2022-07-20
-7dqe,2021-12-29,2020-12-23
-4dq2,2012-04-18,2012-02-14
-8dq1,2022-12-07,2022-07-18
-6dq3,2019-05-01,2018-06-10
-5dqi,2016-08-10,2015-09-14
-5dq5,2016-09-28,2015-09-14
-8dqh,2022-12-07,2022-07-19
-4dqb,2012-03-07,2012-02-15
-5dqw,2016-04-27,2015-09-15
-2dqn,2006-07-18,2006-05-29
-4dqr,2012-06-06,2012-02-16
-1dqb,2000-03-06,2000-01-03
-4dqh,2012-03-07,2012-02-15
-4dqf,2012-03-07,2012-02-15
-1dqa,2000-03-08,1999-12-30
-4dqd,2012-02-29,2012-02-15
-1dq5,2000-01-19,1999-12-30
-5dqv,2016-04-27,2015-09-15
-2dqk,2006-06-20,2006-05-29
-6dqq,2018-11-28,2018-06-11
-4dqs,2012-06-06,2012-02-16
-6dqf,2019-06-12,2018-06-10
-5dq0,2016-09-28,2015-09-14
-8dqb,2022-07-27,2022-07-18
-4dql,2012-03-07,2012-02-16
-8dqd,2024-01-17,2022-07-18
-6dq8,2018-11-21,2018-06-10
-8dqq,2023-01-11,2022-07-19
-3dqx,2008-09-23,2008-07-09
-8dq2,2023-06-07,2022-07-18
-7dq0,2021-12-29,2020-12-22
-2dq4,2007-06-12,2006-05-19
-1dqk,2000-05-10,2000-01-04
-3dqt,2009-03-31,2008-07-09
-5dqn,2015-11-18,2015-09-15
-6dq5,2018-11-21,2018-06-10
-7dqf,2021-10-27,2020-12-23
-5dqh,2016-08-10,2015-09-14
-5dqe,2015-11-25,2015-09-14
-8dq8,2023-07-26,2022-07-18
-3dq0,2009-07-14,2008-07-09
-7dq6,2021-03-03,2020-12-22
-5dqz,2015-11-11,2015-09-15
-6dq9,2018-11-21,2018-06-10
-7dqd,2021-12-29,2020-12-23
-2dq7,2006-07-04,2006-05-23
-8dq4,2023-07-26,2022-07-18
-5dqb,2016-07-27,2015-09-14
-1dq1,2000-01-19,1999-12-29
-6dqj,2018-08-01,2018-06-11
-7dqo,2021-12-01,2020-12-24
-2dq0,2007-06-05,2006-05-18
-6dqy,2018-12-12,2018-06-11
-2dqm,2006-08-01,2006-05-29
-7dqg,2021-12-29,2020-12-23
-7dqq,2021-12-15,2020-12-24
-7dqn,2022-02-02,2020-12-24
-4dqj,2013-01-02,2012-02-16
-1dqn,2000-07-26,2000-01-04
-4dq6,2012-02-29,2012-02-15
-2dq6,2006-08-01,2006-05-22
-6dq1,2018-10-17,2018-06-10
-6dq4,2018-11-21,2018-06-10
-4dqo,2013-03-06,2012-02-16
-7dqa,2021-12-29,2020-12-22
-2dqa,2007-06-12,2006-05-24
-7dqs,2021-10-27,2020-12-24
-6dqr,2018-11-28,2018-06-11
-1dq8,2000-03-08,1999-12-30
-7dql,2021-10-27,2020-12-24
-1dqr,2000-02-09,2000-01-05
-1dqi,2000-05-10,2000-01-04
-3dqb,2008-09-23,2008-07-09
-5dqd,2016-03-09,2015-09-14
-2dqu,2006-06-20,2006-05-30
-8dqz,2022-08-24,2022-07-20
-2dqy,2006-08-29,2006-06-02
-4dqe,2012-03-07,2012-02-15
-6dq7,2019-06-12,2018-06-10
-1dqo,2000-05-10,2000-01-04
-1dq3,2000-07-05,1999-12-30
-5dqq,2016-03-09,2015-09-15
-8dqs,2022-09-14,2022-07-19
-6dqd,2019-06-12,2018-06-10
-8dqv,2023-01-04,2022-07-20
-6dqb,2018-11-21,2018-06-10
-8dq5,2023-07-26,2022-07-18
-6dq0,2018-10-17,2018-06-10
-7dqw,2021-10-27,2020-12-24
-1dqx,2000-03-20,2000-01-05
-3dqw,2008-09-23,2008-07-09
-4dqk,2012-03-07,2012-02-16
-7dqj,2021-10-27,2020-12-24
-7dqi,2021-10-27,2020-12-23
-8dqj,2022-12-07,2022-07-19
-4dqq,2012-06-06,2012-02-16
-6dqu,2018-11-28,2018-06-11
-7dqh,2021-10-27,2020-12-23
-5dqg,2016-08-10,2015-09-14
-6dqz,2018-08-01,2018-06-11
-2dq3,2007-06-05,2006-05-18
-7dq8,2021-12-29,2020-12-22
-3dqv,2008-09-30,2008-07-09
-5dq2,2016-09-28,2015-09-14
-4dq9,2013-03-13,2012-02-15
-7dqm,2021-10-27,2020-12-24
-2dq5,2007-04-03,2006-05-20
-4dqc,2012-03-07,2012-02-15
-1dqs,1999-07-26,1998-04-09
-8dq7,2023-07-26,2022-07-18
-8dqt,2023-06-21,2022-07-19
-7dqv,2021-03-24,2020-12-24
-6dqe,2019-06-12,2018-06-10
-5dqr,2016-04-20,2015-09-15
-8dqo,2023-01-11,2022-07-19
-2dqv,2006-06-13,2006-05-31
-1dq4,2000-01-19,1999-12-30
-6dqh,2019-06-19,2018-06-11
-4dq5,2013-01-02,2012-02-15
-4dqw,2013-03-06,2012-02-16
-2dqs,2007-06-05,2006-05-29
-1dqv,2000-01-19,2000-01-05
-7dqx,2022-01-26,2020-12-24
-8dqc,2022-07-27,2022-07-18
-4dq1,2012-03-21,2012-02-14
-4dqp,2012-06-06,2012-02-16
-8dqw,2022-08-17,2022-07-20
-6xru,2021-03-10,2020-07-13
-7xra,2023-03-15,2022-05-09
-6xra,2020-07-22,2020-07-11
-4xr4,2016-01-27,2015-01-20
-2xrh,2011-09-28,2010-09-15
-2xrq,2010-12-08,2010-09-19
-4xrg,2016-01-27,2015-01-21
-2xry,2011-09-14,2010-09-24
-1xrm,2005-07-12,2004-10-15
-2xrx,2010-11-24,2010-09-23
-4xrd,2016-01-27,2015-01-21
-6xrk,2020-10-28,2020-07-13
-1xr9,2005-04-14,2004-10-14
-8xr4,2024-04-10,2024-01-06
-4xry,2015-05-20,2015-01-21
-6xrs,2020-09-23,2020-07-13
-7xrp,2022-10-05,2022-05-11
-1xr8,2005-04-14,2004-10-14
-1xro,2005-07-12,2004-10-15
-4xrx,2015-12-09,2015-01-21
-7xru,2023-03-15,2022-05-11
-5xr9,2018-06-20,2017-06-08
-8xrt,2024-04-10,2024-01-08
-4xrp,2015-04-22,2015-01-21
-4xrh,2016-02-24,2015-01-21
-2xr7,2011-09-21,2010-09-11
-2xrg,2011-01-19,2010-09-14
-7xri,2023-05-17,2022-05-10
-4xra,2016-01-20,2015-01-20
-2xrm,2011-03-16,2010-09-20
-2xr6,2011-10-19,2010-09-10
-1xrz,2004-11-30,2004-10-17
-4xrq,2015-07-15,2015-01-21
-6xro,2020-09-16,2020-07-13
-7xrs,2022-12-21,2022-05-11
-2xrp,2010-11-24,2010-09-18
-5xrr,2018-04-04,2017-06-09
-1xrf,2005-07-05,2004-10-14
-6xrm,2020-09-16,2020-07-13
-8xru,2024-04-10,2024-01-08
-7xrm,2023-03-29,2022-05-10
-6xrn,2021-11-03,2020-07-13
-5xru,2018-06-13,2017-06-09
-1xrc,1996-03-08,1995-10-26
-2xrf,2010-09-29,2010-09-14
-7xr9,2023-04-05,2022-05-09
-5xre,2018-07-04,2017-06-08
-2xr8,2010-11-24,2010-09-12
-1xrt,2005-07-05,2004-10-15
-7xr1,2023-05-17,2022-05-09
-5xrz,2018-04-25,2017-06-11
-1xrp,2005-07-12,2004-10-15
-1xr6,2004-10-26,2004-10-13
-6xr0,2021-01-20,2020-07-10
-1xry,2005-09-27,2004-10-17
-2xr9,2011-01-19,2010-09-13
-1xrl,2005-07-12,2004-10-15
-2xrs,2010-12-08,2010-09-20
-1xr2,2005-03-01,2004-10-13
-8xrx,2024-04-10,2024-01-08
-7xr5,2022-10-19,2022-05-09
-5xr5,2018-06-20,2017-06-07
-7xrr,2022-11-23,2022-05-11
-1xrv,2004-11-02,2004-10-16
-6xrh,2021-02-03,2020-07-12
-7xrk,2023-03-29,2022-05-10
-5xr8,2017-07-12,2017-06-07
-1xr1,2004-11-09,2004-10-13
-6xrv,2020-10-14,2020-07-13
-2xrz,2011-09-14,2010-09-24
-4xrz,2015-05-20,2015-01-21
-5xrb,2018-07-04,2017-06-08
-4xrj,2015-08-12,2015-01-21
-5xrt,2018-07-25,2017-06-09
-1xrb,1996-03-08,1995-10-26
-6xr5,2020-09-23,2020-07-11
-5xrv,2018-06-13,2017-06-09
-2xrc,2011-07-13,2010-09-13
-7xrt,2023-11-22,2022-05-11
-6xrp,2020-09-16,2020-07-13
-5xrd,2019-05-22,2017-06-08
-1xrk,2005-01-11,2004-10-15
-6xrc,2020-10-28,2020-07-11
-5xra,2017-07-12,2017-06-08
-4xrf,2016-02-10,2015-01-21
-5xry,2018-04-25,2017-06-10
-2xre,2010-10-06,2010-09-14
-2xru,2010-09-29,2010-09-22
-1xrs,2004-11-09,2004-10-15
-2xr1,2010-10-06,2010-09-08
-5xr2,2017-11-01,2017-06-07
-7xrx,2023-05-17,2022-05-12
-4xr6,2016-01-27,2015-01-20
-4xrn,2016-02-03,2015-01-21
-7xr7,2023-03-15,2022-05-09
-5xrs,2018-07-25,2017-06-09
-1xrx,2005-05-10,2004-10-16
-7xrg,2023-05-17,2022-05-10
-6xrl,2020-09-16,2020-07-13
-7xr6,2022-06-22,2022-05-09
-7xry,2022-12-21,2022-05-12
-7xrn,2023-03-29,2022-05-10
-1xru,2005-04-05,2004-10-15
-5xr7,2018-06-13,2017-06-07
-2xrl,2011-10-05,2010-09-16
-2xr5,2011-10-19,2010-09-10
-7xr4,2022-06-22,2022-05-09
-4xrc,2015-07-15,2015-01-20
-8xrv,2024-04-10,2024-01-08
-6xrt,2020-10-07,2020-07-13
-1xrn,2005-07-12,2004-10-15
-7xrl,2023-03-29,2022-05-10
-7xrd,2023-11-15,2022-05-10
-1xr5,2004-10-26,2004-10-13
-6xrx,2021-03-24,2020-07-14
-5xrf,2018-06-13,2017-06-08
-1xrj,2005-03-15,2004-10-14
-2xri,2010-09-29,2010-09-15
-7xro,2023-05-17,2022-05-10
-1xrq,2005-07-12,2004-10-15
-7xre,2023-02-15,2022-05-10
-6xr8,2020-07-22,2020-07-11
-7xr0,2023-05-17,2022-05-09
-7xrf,2023-02-15,2022-05-10
-7xrv,2023-11-22,2022-05-11
-6xr3,2020-08-19,2020-07-10
-2xro,2010-12-01,2010-09-17
-1xra,1996-03-08,1995-10-26
-1xr3,2005-09-27,2004-10-13
-5xr4,2018-06-13,2017-06-07
-4xrl,2016-03-23,2015-01-21
-1xrr,2005-07-12,2004-10-15
-2xrw,2011-09-28,2010-09-23
-4xrb,2016-02-24,2015-01-20
-4xre,2015-02-25,2015-01-21
-6xre,2021-03-24,2020-07-12
-4xru,2015-04-22,2015-01-21
-4xr8,2016-02-03,2015-01-20
-4xr9,2015-02-11,2015-01-20
-5xr6,2018-06-13,2017-06-07
-1xre,2005-07-19,2004-10-14
-6i0b,2019-03-27,2018-10-25
-2i0f,2007-08-14,2006-08-10
-2i0g,2006-10-24,2006-08-10
-2i0i,2007-02-20,2006-08-10
-3i0d,2010-08-11,2009-06-25
-3i0j,2010-08-11,2009-06-25
-4i0f,2013-03-06,2012-11-16
-2i0o,2006-10-24,2006-08-10
-8i01,2023-11-22,2023-01-10
-6i08,2018-12-19,2018-10-25
-4i02,2013-10-30,2012-11-16
-6i0y,2018-12-05,2018-10-26
-5i0b,2016-12-14,2016-02-03
-2i0z,2006-08-22,2006-08-11
-5i0c,2016-02-24,2016-02-03
-8i0d,2023-09-20,2023-01-10
-2i07,2006-10-24,2006-08-10
-8i0m,2024-01-24,2023-01-11
-5i00,2017-02-15,2016-02-03
-5i0j,2016-10-26,2016-02-04
-5i0g,2016-12-14,2016-02-03
-3i0s,2009-08-25,2009-06-25
-3i0e,2010-08-11,2009-06-25
-5i0d,2016-12-14,2016-02-03
-4i0p,2012-12-26,2012-11-18
-5i0e,2016-12-14,2016-02-03
-3i0k,2010-08-11,2009-06-25
-6i0r,2019-03-20,2018-10-26
-2i0v,2006-11-28,2006-08-11
-1i06,2001-02-14,2001-01-28
-6i0u,2018-12-05,2018-10-26
-6i0a,2019-11-13,2018-10-25
-3i08,2009-09-01,2009-06-24
-4i0u,2013-03-06,2012-11-19
-1i0s,2001-05-02,2001-01-29
-3i0p,2009-07-14,2009-06-25
-3i0i,2010-08-11,2009-06-25
-4i0k,2012-12-05,2012-11-16
-3i0q,2010-01-19,2009-06-25
-4i0g,2013-03-06,2012-11-16
-5i0n,2016-03-09,2016-02-04
-3i0a,2010-06-09,2009-06-24
-3i02,2010-01-12,2009-06-24
-5i09,2017-02-15,2016-02-03
-1i05,2001-02-14,2001-01-28
-1i0l,2002-05-29,2001-01-29
-4i06,2013-03-20,2012-11-16
-5i0x,2017-02-08,2016-02-04
-1i08,2001-02-28,2001-01-29
-8i05,2023-11-22,2023-01-10
-4i05,2014-02-05,2012-11-16
-6i0p,2019-03-20,2018-10-26
-3i0r,2009-08-25,2009-06-25
-6i0t,2018-12-05,2018-10-26
-2i0c,2006-11-21,2006-08-10
-1i0d,2001-04-04,2001-01-29
-2i0k,2007-12-11,2006-08-10
-3i06,2009-12-15,2009-06-24
-8i04,2023-11-22,2023-01-10
-1i0r,2001-05-02,2001-01-29
-4i01,2013-10-30,2012-11-16
-5i07,2017-02-15,2016-02-03
-2i0j,2006-10-24,2006-08-10
-5i0f,2016-12-14,2016-02-03
-5i0r,2016-12-14,2016-02-04
-2i0u,2007-09-11,2006-08-11
-5i01,2016-02-17,2016-02-03
-4i0b,2013-10-30,2012-11-16
-6i09,2019-11-13,2018-10-25
-6i0c,2019-03-27,2018-10-25
-5i06,2017-02-15,2016-02-03
-6i02,2019-04-03,2018-10-24
-2i0t,2007-04-24,2006-08-11
-8i0k,2024-05-01,2023-01-11
-6i0s,2018-12-05,2018-10-26
-6i0m,2019-01-30,2018-10-26
-1i0h,2001-02-28,2001-01-29
-4i0t,2013-10-30,2012-11-19
-5i02,2017-02-15,2016-02-03
-8i08,2023-11-22,2023-01-10
-2i0b,2006-11-21,2006-08-10
-4i0w,2013-04-03,2012-11-19
-8i0e,2023-09-20,2023-01-10
-4i0h,2013-03-06,2012-11-16
-5i0t,2016-12-14,2016-02-04
-8i0b,2024-02-07,2023-01-10
-5i04,2017-06-07,2016-02-03
-8i03,2023-05-03,2023-01-10
-1i00,2001-05-09,2001-01-27
-6i01,2019-04-03,2018-10-24
-1i0u,2001-08-15,2001-01-29
-2i08,2007-08-21,2006-08-10
-5i0w,2017-02-08,2016-02-04
-2i0a,2006-12-19,2006-08-10
-5i03,2017-02-15,2016-02-03
-2i04,2007-02-20,2006-08-09
-5i0y,2017-02-08,2016-02-04
-8i0z,2023-05-17,2023-01-12
-5i0m,2016-10-26,2016-02-04
-4i08,2012-12-12,2012-11-16
-2i0s,2007-04-24,2006-08-11
-6i0z,2019-02-27,2018-10-27
-6i0l,2019-11-20,2018-10-26
-3i03,2010-05-12,2009-06-24
-6i0o,2019-01-30,2018-10-26
-5i0l,2016-07-06,2016-02-04
-3i0l,2010-08-11,2009-06-25
-4i0d,2013-10-09,2012-11-16
-3i0o,2010-01-19,2009-06-25
-4i0a,2013-10-30,2012-11-16
-3i01,2009-09-01,2009-06-24
-1i0b,2001-04-04,2001-01-29
-5i0s,2016-12-14,2016-02-04
-2i03,2006-12-12,2006-08-09
-5i0v,2017-02-08,2016-02-04
-2i0e,2006-11-14,2006-08-10
-4i0z,2013-03-06,2012-11-19
-2i0d,2006-12-19,2006-08-10
-2i0h,2006-10-17,2006-08-10
-6i0w,2019-11-20,2018-10-26
-2i0m,2006-09-19,2006-08-10
-4i03,2013-04-24,2012-11-16
-4i0n,2013-03-20,2012-11-16
-6i0d,2020-09-02,2018-10-25
-8i0l,2024-01-24,2023-01-11
-8i06,2023-11-22,2023-01-10
-4i00,2013-11-13,2012-11-16
-8i0g,2023-12-20,2023-01-10
-4i09,2013-10-30,2012-11-16
-1i0x,2001-02-14,2001-01-30
-3i0f,2010-08-11,2009-06-25
-8i0q,2023-05-17,2023-01-11
-3i04,2009-09-01,2009-06-24
-1i0i,2002-05-29,2001-01-29
-8i0c,2023-09-20,2023-01-10
-5i0p,2016-02-17,2016-02-04
-4i0j,2013-03-06,2012-11-16
-4i0r,2013-10-30,2012-11-19
-1i0z,2001-03-28,2001-01-30
-8i02,2023-05-03,2023-01-10
-6i0n,2019-11-13,2018-10-26
-4i0i,2013-11-20,2012-11-16
-5i0i,2016-09-07,2016-02-04
-6i0k,2019-03-20,2018-10-26
-3i0g,2010-08-11,2009-06-25
-2i0y,2006-11-28,2006-08-11
-3i0x,2009-09-29,2009-06-25
-4i0s,2013-10-30,2012-11-19
-6i0j,2019-11-20,2018-10-26
-2i02,2006-08-29,2006-08-09
-6i0v,2018-12-05,2018-10-26
-8i07,2023-11-22,2023-01-10
-8i0n,2023-05-17,2023-01-11
-6i03,2019-11-20,2018-10-24
-4i0e,2013-03-06,2012-11-16
-6i0x,2019-01-23,2018-10-26
-5i0k,2017-08-09,2016-02-04
-5i0h,2016-09-07,2016-02-04
-1i0v,2001-02-14,2001-01-30
-2i0l,2007-02-20,2006-08-10
-8i09,2023-11-22,2023-01-10
-3i0w,2009-09-29,2009-06-25
-8i0y,2023-12-20,2023-01-11
-5i0u,2017-02-22,2016-02-04
-102m,1998-04-08,1997-12-15
-5e1e,2015-11-25,2015-09-29
-6e12,2018-07-25,2018-07-09
-7e12,2022-04-27,2021-01-28
-1e1k,2000-09-24,2000-05-09
-4e1i,2013-03-06,2012-03-06
-8e1l,2022-08-24,2022-08-10
-8e1a,2022-09-14,2022-08-10
-7e1z,2022-06-15,2021-02-04
-1e18,2000-06-11,2000-04-28
-5e1d,2015-10-28,2015-09-29
-3e1z,2009-01-27,2008-08-05
-3e1f,2009-06-09,2008-08-04
-8e14,2023-04-26,2022-08-09
-7e1r,2021-12-01,2021-02-03
-4e1g,2012-04-25,2012-03-06
-8e1i,2022-11-30,2022-08-10
-6e10,2018-08-22,2018-07-08
-1e1t,2000-07-28,2000-05-10
-8e19,2022-11-09,2022-08-10
-7e1v,2021-10-13,2021-02-03
-3e11,2008-08-19,2008-08-01
-5e19,2016-05-04,2015-09-29
-2e1m,2007-11-13,2006-10-26
-8e17,2023-03-29,2022-08-09
-1e1v,2001-05-10,2000-05-11
-3e18,2008-08-12,2008-08-02
-2e16,2007-04-24,2006-10-18
-5e17,2016-03-09,2015-09-29
-1e1h,2003-06-19,2000-05-08
-4e1k,2013-05-29,2012-03-06
-1e1l,2000-06-02,2000-05-09
-7e19,2021-06-23,2021-02-01
-3e1v,2009-06-02,2008-08-04
-7e17,2021-12-22,2021-02-01
-5e18,2016-03-09,2015-09-29
-5e16,2015-11-04,2015-09-29
-1e19,2000-07-04,2000-04-28
-1e1a,2001-06-06,2000-04-28
-8e1u,2023-06-07,2022-08-11
-5e1f,2015-10-14,2015-09-29
-7e13,2022-02-02,2021-01-29
-6e1p,2018-09-19,2018-07-10
-4e11,2012-06-27,2012-03-05
-3e1l,2009-05-05,2008-08-04
-7e1g,2022-02-16,2021-02-01
-2e1q,2007-09-18,2006-10-27
-2e1a,2007-09-18,2006-10-19
-4e1e,2013-01-16,2012-03-06
-4e1z,2012-10-03,2012-03-07
-5e1n,2015-11-25,2015-09-29
-5e1x,2016-10-05,2015-09-30
-5e1j,2015-12-16,2015-09-29
-3e1q,2009-08-18,2008-08-04
-8e1g,2023-06-28,2022-08-10
-8e1x,2022-11-23,2022-08-11
-2e1z,2007-09-18,2006-11-04
-8e1f,2022-09-14,2022-08-10
-5e1i,2016-10-12,2015-09-29
-1e1r,2000-06-28,2000-05-10
-3e1p,2009-05-05,2008-08-04
-6e1x,2019-07-10,2018-07-10
-5e1q,2016-10-05,2015-09-30
-3e16,2008-09-09,2008-08-01
-3e1o,2009-05-05,2008-08-04
-2e1s,2006-11-14,2006-10-27
-5e1r,2016-08-10,2015-09-30
-5e1c,2016-05-04,2015-09-29
-7e14,2021-07-07,2021-01-30
-4e1h,2013-03-06,2012-03-06
-5e1p,2015-11-25,2015-09-29
-6e17,2019-02-27,2018-07-09
-8e1j,2022-11-30,2022-08-10
-2e1r,2006-11-14,2006-10-27
-8e1w,2023-01-11,2022-08-11
-4e1o,2012-07-18,2012-03-06
-8e1d,2023-06-21,2022-08-10
-6e1k,2018-09-19,2018-07-10
-4e13,2012-11-14,2012-03-05
-4e1d,2012-08-29,2012-03-06
-7e1w,2021-10-27,2021-02-03
-7e1q,2021-12-01,2021-02-03
-6e1n,2018-09-19,2018-07-10
-1e1m,2000-09-24,2000-05-09
-8e1p,2023-06-21,2022-08-11
-1e14,2000-06-02,2000-04-18
-7e1x,2021-10-27,2021-02-03
-7e11,2022-04-27,2021-01-28
-8e1v,2022-11-30,2022-08-11
-4e1j,2012-03-21,2012-03-06
-5e1z,2016-10-05,2015-09-30
-3e1w,2009-06-02,2008-08-04
-4e1m,2012-04-25,2012-03-06
-6e1a,2019-07-10,2018-07-09
-1e1q,2000-06-28,2000-05-10
-3e15,2008-08-19,2008-08-01
-1e1x,2001-05-10,2000-05-11
-6e1r,2019-07-17,2018-07-10
-3e1n,2009-05-05,2008-08-04
-4e1f,2012-10-10,2012-03-06
-7e1c,2022-02-16,2021-02-01
-6e13,2019-05-22,2018-07-09
-3e12,2009-05-12,2008-08-01
-8e15,2023-04-12,2022-08-09
-3e1y,2009-05-19,2008-08-05
-1e1c,2000-05-07,2000-04-30
-5e1k,2015-11-25,2015-09-29
-6e1c,2019-07-17,2018-07-09
-7e1a,2022-02-09,2021-02-01
-1e1f,2001-02-19,2000-05-03
-8e1s,2022-11-30,2022-08-11
-4e1b,2012-03-14,2012-03-06
-6e1q,2018-10-24,2018-07-10
-1e1y,2000-05-17,2000-05-11
-3e1j,2009-05-05,2008-08-04
-8e1y,2022-08-24,2022-08-11
-2e1p,2007-01-16,2006-10-27
-3e13,2009-08-11,2008-08-01
-4e1v,2013-03-06,2012-03-07
-7e1e,2022-10-19,2021-02-01
-4e1c,2012-08-29,2012-03-06
-4e19,2013-03-06,2012-03-06
-1e1z,2001-05-10,2000-05-12
-3e1i,2009-01-13,2008-08-04
-7e1t,2021-10-27,2021-02-03
-7e1n,2022-02-02,2021-02-02
-1e1n,2000-09-24,2000-05-09
-1e1o,2000-07-28,2000-05-09
-4e10,2013-02-13,2012-03-05
-2e15,2007-04-24,2006-10-18
-2e18,2007-04-24,2006-10-18
-6e11,2018-08-22,2018-07-08
-8e1o,2023-08-16,2022-08-10
-7e1s,2021-12-01,2021-02-03
-4e14,2012-06-27,2012-03-05
-5e1g,2016-10-12,2015-09-29
-8e1q,2022-09-14,2022-08-11
-6e1h,2018-08-29,2018-07-09
-8e13,2023-07-26,2022-08-09
-3e1t,2009-02-24,2008-08-04
-6e1y,2019-03-13,2018-07-10
-3e10,2008-08-12,2008-08-01
-5e14,2016-05-04,2015-09-29
-6e1z,2019-03-13,2018-07-10
-6e1j,2019-05-08,2018-07-09
-2e1b,2007-03-06,2006-10-20
-5e1a,2016-07-13,2015-09-29
-5e13,2015-11-18,2015-09-29
-1e12,2000-06-02,2000-04-14
-8e1h,2022-11-30,2022-08-10
-8e1k,2022-08-24,2022-08-10
-3e1u,2008-10-07,2008-08-04
-2e1t,2007-04-10,2006-10-28
-5e15,2016-05-04,2015-09-29
-2e1w,2006-11-07,2006-10-30
-7e18,2021-06-23,2021-02-01
-4e1n,2012-04-25,2012-03-06
-2e1x,2007-06-05,2006-11-03
-5e1s,2015-10-14,2015-09-30
-6e18,2018-11-07,2018-07-09
-2e17,2007-04-24,2006-10-18
-6e1m,2018-09-19,2018-07-10
-7e1h,2022-02-09,2021-02-01
-7e1p,2021-12-15,2021-02-03
-6e1o,2019-02-06,2018-07-10
-8e1t,2022-11-30,2022-08-11
-3e1m,2009-05-05,2008-08-04
-1ef3,2001-02-07,2000-02-06
-5efi,2016-03-30,2015-10-23
-8efe,2023-01-11,2022-09-08
-8efy,2023-05-10,2022-09-10
-8efg,2023-02-22,2022-09-08
-7efn,2021-09-01,2021-03-22
-7ef3,2021-06-30,2021-03-20
-5efn,2016-07-27,2015-10-24
-3ef7,2008-12-02,2008-09-08
-5efh,2016-07-27,2015-10-23
-6efv,2019-02-27,2018-08-17
-3efu,2008-12-09,2008-09-10
-2efx,2007-03-06,2007-02-26
-1efi,2000-02-23,2000-02-08
-2efu,2007-03-06,2007-02-26
-1efa,2000-03-06,2000-02-07
-4efu,2012-06-27,2012-03-30
-3efr,2009-06-09,2008-09-10
-3efv,2008-11-04,2008-09-10
-6ef3,2018-10-17,2018-08-15
-5ef7,2016-07-27,2015-10-23
-7efw,2021-11-17,2021-03-23
-3ef1,2008-12-02,2008-09-07
-4ef3,2013-05-22,2012-03-29
-4ef2,2012-04-25,2012-03-28
-1efv,1997-12-03,1996-10-16
-8ef9,2022-12-14,2022-09-08
-5efq,2015-12-30,2015-10-24
-3efj,2008-10-07,2008-09-09
-6efb,2020-02-19,2018-08-16
-8efi,2022-11-23,2022-09-08
-1efr,1997-02-12,1996-05-24
-8efl,2022-11-09,2022-09-08
-5efc,2015-11-18,2015-10-23
-4efq,2012-08-29,2012-03-30
-5eff,2016-10-26,2015-10-23
-1ef0,2000-06-07,2000-02-04
-3ef6,2009-03-10,2008-09-08
-8eff,2023-06-28,2022-09-08
-3eft,2009-09-08,2008-09-10
-1efc,1999-03-18,1998-11-24
-6ef8,2019-04-10,2018-08-16
-7efr,2021-11-24,2021-03-23
-7ef2,2021-06-30,2021-03-20
-6efh,2018-08-29,2018-08-16
-3ef2,2009-06-30,2008-09-08
-3efs,2009-06-09,2008-09-10
-6eff,2020-02-19,2018-08-16
-5efb,2016-07-27,2015-10-23
-4efj,2012-05-02,2012-03-29
-3ef0,2008-12-02,2008-09-07
-4efm,2012-05-16,2012-03-30
-7ef6,2021-11-03,2021-03-21
-8efc,2022-12-14,2022-09-08
-6efg,2018-08-29,2018-08-16
-4ef9,2012-12-12,2012-03-29
-8ef0,2023-08-30,2022-09-07
-6efi,2020-02-19,2018-08-16
-7efl,2021-09-01,2021-03-22
-6efc,2020-02-19,2018-08-16
-8efn,2023-07-05,2022-09-08
-6ef0,2018-10-17,2018-08-15
-3efl,2009-09-15,2008-09-09
-4ef6,2013-03-13,2012-03-29
-3ef5,2009-03-24,2008-09-08
-4eft,2012-06-27,2012-03-30
-8ef5,2022-11-09,2022-09-08
-2efg,1999-09-30,1998-09-23
-4ef1,2012-04-25,2012-03-28
-7ef1,2021-06-30,2021-03-20
-1efl,2000-03-08,2000-02-09
-7efc,2021-04-28,2021-03-21
-4efp,2012-08-29,2012-03-30
-4efh,2012-04-11,2012-03-29
-6efa,2020-02-19,2018-08-16
-4ef8,2012-12-12,2012-03-29
-5ef3,2016-05-04,2015-10-23
-4ef4,2012-05-16,2012-03-29
-3efx,2008-09-23,2008-09-10
-7ef0,2021-06-30,2021-03-20
-2efh,2008-02-26,2007-02-22
-4efn,2012-05-16,2012-03-30
-2eff,2007-10-02,2007-02-22
-8ef8,2023-07-19,2022-09-08
-6efd,2020-02-19,2018-08-16
-2eft,2007-06-12,2007-02-24
-5ef8,2016-07-27,2015-10-23
-2efn,2008-02-26,2007-02-23
-6ef6,2018-10-17,2018-08-16
-3efw,2008-12-23,2008-09-10
-7efv,2021-11-17,2021-03-23
-2efc,2008-02-26,2007-02-22
-5efd,2016-10-26,2015-10-23
-5efw,2016-07-20,2015-10-26
-8efv,2023-05-10,2022-09-09
-3efo,2008-10-21,2008-09-09
-3ef4,2008-12-30,2008-09-08
-6efj,2019-04-17,2018-08-16
-7efo,2022-03-02,2021-03-22
-6efn,2018-10-24,2018-08-16
-7efx,2022-02-16,2021-03-23
-1ef8,2000-05-24,2000-02-07
-7efq,2021-05-12,2021-03-23
-1efk,2000-03-08,2000-02-09
-7ef9,2021-06-23,2021-03-21
-6efk,2019-07-31,2018-08-16
-2ef9,2007-04-24,2007-02-22
-8efh,2023-01-11,2022-09-08
-1eft,1994-08-31,1993-08-24
-5ef0,2016-05-04,2015-10-23
-3efq,2009-05-05,2008-09-09
-5efv,2016-05-25,2015-10-26
-6ef7,2020-02-19,2018-08-16
-7efj,2022-02-16,2021-03-21
-4efe,2013-04-03,2012-03-29
-8efk,2022-12-14,2022-09-08
-5ef2,2016-05-04,2015-10-23
-5efk,2016-07-27,2015-10-23
-3ef8,2008-09-30,2008-09-08
-2ef0,2007-04-13,2007-02-19
-3efk,2008-10-07,2008-09-09
-4efz,2012-05-09,2012-03-30
-1efh,2000-09-06,2000-02-08
-1efq,2001-02-09,2000-02-09
-1efy,2001-01-17,2000-02-10
-6efx,2018-09-05,2018-08-17
-6ef9,2020-02-19,2018-08-16
-5efo,2016-11-09,2015-10-24
-2efp,2008-02-26,2007-02-23
-2efo,2008-02-26,2007-02-23
-4efd,2012-05-30,2012-03-29
-3efp,2009-04-07,2008-09-09
-4efx,2013-03-06,2012-03-30
-6ef1,2018-10-17,2018-08-15
-1ef2,2000-03-09,2000-02-05
-4efc,2013-02-13,2012-03-29
-7ef8,2021-06-23,2021-03-21
-8ef6,2022-11-09,2022-09-08
-4efg,2012-12-26,2012-03-29
-6efy,2018-11-28,2018-08-17
-8efo,2022-11-09,2022-09-08
-2efe,2008-02-26,2007-02-22
-2efb,2007-03-06,2007-02-22
-1efx,2000-06-14,2000-02-10
-5efa,2015-11-18,2015-10-23
-5efj,2016-07-27,2015-10-23
-2efj,2007-05-01,2007-02-22
-7efd,2021-04-28,2021-03-21
-7efm,2021-09-01,2021-03-22
-8efj,2023-09-20,2022-09-08
-7ef7,2021-11-03,2021-03-21
-5ef1,2016-05-04,2015-10-23
-1efp,1999-08-09,1998-12-18
-2ef5,2007-04-14,2007-02-20
-1efz,2000-03-01,2000-02-11
-4efk,2013-03-13,2012-03-29
-6efz,2018-11-28,2018-08-17
-8efr,2023-06-28,2022-09-09
-1ef4,2000-06-14,2000-02-07
-8efm,2023-07-05,2022-09-08
-2efq,2008-03-04,2007-02-23
-6ef2,2018-10-17,2018-08-15
-8efb,2022-11-09,2022-09-08
-1ef9,2000-05-24,2000-02-07
-6efw,2018-09-05,2018-08-17
-8efq,2022-11-09,2022-09-08
-7efp,2021-11-24,2021-03-22
-3efi,2008-09-30,2008-09-09
-5efu,2016-10-26,2015-10-26
-4efb,2013-04-03,2012-03-29
-5efg,2016-07-27,2015-10-23
-2ef6,2007-10-30,2007-02-21
-4efl,2012-05-16,2012-03-30
-6ef5,2019-10-30,2018-08-16
-4efs,2012-06-20,2012-03-30
-2efy,2008-02-26,2007-02-26
-3ef3,2009-07-28,2008-09-08
-2ef2,2007-10-02,2007-02-20
-5dw6,2016-05-04,2015-09-22
-5dw3,2015-11-11,2015-09-22
-3dwq,2008-11-04,2008-07-22
-2dwj,2006-08-29,2006-08-15
-3dwr,2008-09-09,2008-07-22
-8dw5,2022-08-10,2022-07-31
-4dwc,2012-05-23,2012-02-24
-7dwz,2021-03-31,2021-01-18
-6dwy,2018-09-19,2018-06-28
-5dw0,2015-11-11,2015-09-22
-3dw9,2008-08-19,2008-07-21
-3dwl,2008-08-26,2008-07-22
-5dw8,2015-12-09,2015-09-22
-7dwy,2021-03-31,2021-01-18
-8dwg,2022-11-02,2022-08-01
-6dwa,2018-08-29,2018-06-26
-2dwi,2006-09-05,2006-08-13
-3dws,2008-09-09,2008-07-22
-8dwf,2023-08-09,2022-08-01
-6dwz,2018-09-19,2018-06-28
-1dwl,1999-12-10,1999-12-08
-8dwe,2023-08-09,2022-08-01
-6dwm,2018-10-03,2018-06-26
-2dwd,2007-02-20,2006-08-10
-1dw2,2000-06-28,2000-01-24
-6dw3,2018-10-10,2018-06-26
-4dwu,2013-02-27,2012-02-26
-6dwv,2018-10-03,2018-06-28
-8dw6,2023-06-14,2022-07-31
-2dw2,2007-07-10,2006-08-02
-2dwp,2007-07-03,2006-08-16
-7dw6,2022-01-19,2021-01-15
-4dwb,2013-01-16,2012-02-24
-1dwv,2000-02-06,1999-12-14
-6dw2,2018-08-29,2018-06-26
-1dwg,2000-03-03,1999-12-05
-1dwk,2000-05-16,1999-12-07
-3dwj,2008-09-30,2008-07-22
-1dw1,2000-06-28,2000-01-24
-7dwa,2021-06-02,2021-01-15
-8dwz,2023-03-22,2022-08-02
-6dw5,2018-10-10,2018-06-26
-3dw3,2009-07-07,2008-07-21
-6dwd,2018-10-10,2018-06-26
-3dwi,2008-09-23,2008-07-22
-4dwm,2012-03-07,2012-02-25
-4dw3,2012-05-23,2012-02-24
-7dwr,2021-12-22,2021-01-17
-3dwp,2008-11-04,2008-07-22
-2dwl,2006-11-07,2006-08-15
-4dwv,2012-04-11,2012-02-26
-1dws,2000-03-03,1999-12-11
-8dwa,2022-12-07,2022-08-01
-6dww,2018-09-19,2018-06-28
-7dw7,2022-01-19,2021-01-15
-1dwr,2000-03-03,1999-12-11
-7dwx,2021-03-31,2021-01-18
-4dw6,2013-03-27,2012-02-24
-3dww,2009-07-28,2008-07-23
-5dwz,2016-02-03,2015-09-23
-5dwk,2016-03-23,2015-09-22
-6dws,2019-07-03,2018-06-27
-4dwo,2012-03-28,2012-02-26
-5dwj,2016-05-04,2015-09-22
-6dwi,2018-08-29,2018-06-26
-5dwn,2015-10-28,2015-09-22
-2dwb,2007-07-31,2006-08-10
-1dwq,2000-12-07,1999-12-10
-8dwl,2023-02-15,2022-08-01
-3dwd,2008-08-05,2008-07-22
-4dw4,2012-05-23,2012-02-24
-4dwg,2013-01-16,2012-02-24
-2dwm,2006-11-07,2006-08-15
-4dwj,2012-03-07,2012-02-24
-2dw5,2006-10-17,2006-08-04
-6dwg,2019-06-26,2018-06-26
-6dwj,2018-10-24,2018-06-26
-6dw7,2018-10-10,2018-06-26
-4dwq,2012-09-05,2012-02-26
-1dww,2000-02-06,1999-12-14
-4dwr,2012-09-05,2012-02-26
-8dw4,2022-11-30,2022-07-31
-6dwh,2019-01-30,2018-06-26
-1dw6,2000-07-26,2000-01-24
-7dwg,2021-08-04,2021-01-17
-4dw0,2012-04-25,2012-02-24
-8dwy,2023-05-31,2022-08-02
-3dwc,2008-09-09,2008-07-22
-2dw4,2007-09-04,2006-08-02
-2dw1,2007-07-10,2006-08-02
-3dwz,2009-03-10,2008-07-23
-8dw7,2022-11-30,2022-07-31
-8dw8,2023-01-11,2022-07-31
-4dwx,2012-08-15,2012-02-27
-5dw2,2016-06-22,2015-09-22
-8dwj,2023-06-14,2022-08-01
-6dwr,2019-07-03,2018-06-27
-7dw0,2022-01-19,2021-01-15
-4dwt,2013-02-27,2012-02-26
-6dwo,2019-10-30,2018-06-26
-8dwh,2022-11-02,2022-08-01
-2dwt,2006-12-05,2006-08-17
-2dwx,2007-04-17,2006-08-21
-8dwm,2023-01-11,2022-08-01
-5dwi,2016-05-04,2015-09-22
-6dw4,2018-10-10,2018-06-26
-1dwh,2000-03-03,1999-12-05
-2dws,2006-12-05,2006-08-16
-7dw9,2021-07-21,2021-01-15
-1dwe,1994-01-31,1992-08-19
-8dwr,2023-08-02,2022-08-01
-6dwn,2018-10-03,2018-06-26
-4dw7,2012-05-23,2012-02-24
-4dww,2012-03-14,2012-02-27
-2dwo,2007-07-03,2006-08-16
-8dwx,2023-05-31,2022-08-02
-7dw1,2021-07-21,2021-01-15
-1dwd,1994-01-31,1992-08-19
-1dwc,1994-01-31,1992-08-19
-5dwl,2016-09-21,2015-09-22
-3dw1,2009-07-07,2008-07-21
-1dwt,2000-03-03,1999-12-12
-5dwr,2015-11-11,2015-09-22
-2dw7,2006-12-19,2006-08-07
-3dwg,2008-09-23,2008-07-22
-4dwz,2013-01-16,2012-02-27
-2dwe,2007-02-20,2006-08-10
-2dw6,2006-12-19,2006-08-07
-4dw8,2012-03-28,2012-02-24
-6dw0,2018-08-08,2018-06-26
-3dwb,2008-11-25,2008-07-22
-1dwa,2000-03-03,1999-12-05
-1dwi,2000-03-03,1999-12-05
-7dwq,2021-06-02,2021-01-17
-4dwa,2012-05-23,2012-02-24
-2dw0,2007-07-10,2006-08-02
-7dw8,2021-06-02,2021-01-15
-1dw3,2000-06-28,2000-01-24
-8dw2,2022-12-07,2022-07-30
-4dwk,2013-04-03,2012-02-24
-8dwk,2023-02-15,2022-08-01
-8dwb,2022-12-21,2022-08-01
-2dwa,2006-08-29,2006-08-09
-4dwd,2012-03-14,2012-02-24
-7dw4,2021-08-04,2021-01-15
-6dwk,2018-10-10,2018-06-26
-2dwh,2006-09-05,2006-08-12
-1dw0,2000-06-28,2000-01-24
-4dw1,2012-04-25,2012-02-24
-4dwp,2013-02-13,2012-02-26
-2dwc,2007-02-10,2006-08-10
-1dwj,2000-03-03,1999-12-05
-5dw1,2016-06-22,2015-09-22
-8dww,2023-05-31,2022-08-02
-4dwi,2013-03-27,2012-02-24
-1dwx,2000-02-06,1999-12-14
-2dwu,2007-06-19,2006-08-17
-8dwd,2023-08-09,2022-08-01
-8dw1,2023-01-11,2022-07-30
-5dwg,2016-05-04,2015-09-22
-6dwq,2019-07-03,2018-06-27
-7dwm,2021-05-05,2021-01-17
-5dwe,2016-05-04,2015-09-22
-6dw1,2018-08-08,2018-06-26
-7dwe,2021-08-04,2021-01-17
-3dw8,2008-10-07,2008-07-21
-5dw5,2016-05-04,2015-09-22
-3dwf,2009-08-11,2008-07-22
-4dw5,2012-05-23,2012-02-24
-5dwq,2015-11-25,2015-09-22
-1dwf,2000-03-03,1999-12-05
-5dwu,2015-12-30,2015-09-23
-8dw3,2022-12-07,2022-07-30
-2dwn,2006-11-07,2006-08-15
-6dwe,2018-07-11,2018-06-26
-5dwv,2016-09-28,2015-09-23
-7dws,2021-06-02,2021-01-17
-8dw0,2022-11-30,2022-07-30
-3dwe,2009-07-07,2008-07-22
-1bwk,1998-09-30,1998-09-24
-2bw5,2005-08-17,2005-07-12
-8bw9,2024-02-21,2022-12-06
-6bwp,2018-01-03,2017-12-15
-2bwi,2005-08-17,2005-07-14
-3bwv,2008-01-22,2008-01-10
-7bwl,2020-12-02,2020-04-14
-1bws,1999-01-13,1998-09-25
-2bw4,2005-08-17,2005-07-12
-4bwe,2013-12-18,2013-07-01
-5bw2,2015-06-24,2015-06-05
-8bwu,2023-10-11,2022-12-07
-2bwc,2005-12-21,2005-07-13
-3bwx,2008-01-22,2008-01-10
-2bwu,2006-01-25,2005-07-19
-7bwp,2020-05-13,2020-04-15
-2bwa,2005-12-21,2005-07-13
-6bwu,2018-01-03,2017-12-15
-7bwd,2021-04-14,2020-04-14
-1bwn,1999-06-15,1998-09-25
-5bwz,2016-06-08,2015-06-08
-7bwh,2020-06-10,2020-04-14
-5bwx,2015-07-01,2015-06-08
-7bwt,2021-02-24,2020-04-16
-4bwi,2013-10-30,2013-07-03
-7bwr,2020-05-27,2020-04-15
-5bwr,2015-07-01,2015-06-08
-6bwz,2018-04-04,2017-12-15
-1bwc,1999-07-20,1998-09-23
-4bw3,2013-09-11,2013-06-29
-8bwy,2023-05-10,2022-12-07
-4bwb,2014-01-29,2013-07-01
-6bw2,2018-01-31,2017-12-14
-1bwo,1999-08-27,1998-09-25
-5bwv,2015-07-01,2015-06-08
-8bw2,2022-12-21,2022-12-06
-6bw8,2018-01-31,2017-12-14
-2bwm,2006-01-23,2005-07-15
-8bws,2023-04-05,2022-12-07
-5bwo,2016-07-13,2015-06-08
-5bwu,2015-07-01,2015-06-08
-4bwa,2013-07-31,2013-07-01
-3bw2,2009-01-13,2008-01-08
-5bwg,2015-10-28,2015-06-08
-5bwk,2015-10-14,2015-06-08
-3bwn,2008-04-29,2008-01-10
-7bww,2021-04-21,2020-04-16
-2bwt,2006-01-25,2005-07-19
-6bwj,2018-05-02,2017-12-15
-6bw1,2018-07-04,2017-12-14
-4bw1,2013-09-11,2013-06-29
-3bw4,2009-01-13,2008-01-08
-6bwc,2018-01-17,2017-12-14
-6bwl,2018-01-17,2017-12-15
-8bwv,2024-01-24,2022-12-07
-3bwi,2008-04-22,2008-01-09
-5bwd,2015-08-05,2015-06-07
-5bwb,2015-09-09,2015-06-07
-4bw4,2013-09-11,2013-06-29
-1bwa,1998-10-30,1998-09-22
-5bwi,2015-10-28,2015-06-08
-3bwd,2008-03-11,2008-01-09
-3bwc,2008-04-01,2008-01-09
-4bwk,2013-08-21,2013-07-04
-3bwl,2008-01-15,2008-01-09
-8bw5,2023-07-19,2022-12-06
-7bwv,2021-04-21,2020-04-16
-3bwh,2008-10-07,2008-01-09
-4bwr,2013-07-24,2013-07-04
-1bwb,1998-09-30,1998-09-22
-2bwj,2005-07-21,2005-07-14
-5bww,2015-07-01,2015-06-08
-4bw7,2014-01-15,2013-06-30
-4bwz,2013-08-28,2013-07-05
-5bwe,2015-08-05,2015-06-07
-8bwq,2023-08-30,2022-12-07
-5bw4,2016-04-20,2015-06-05
-8bwp,2023-08-30,2022-12-07
-3bwk,2009-01-20,2008-01-09
-1bwf,1999-05-18,1998-09-23
-4bww,2014-06-11,2013-07-04
-7bw9,2021-04-14,2020-04-14
-6bwn,2018-12-19,2017-12-15
-4bwj,2013-09-18,2013-07-03
-6bwr,2018-06-20,2017-12-15
-5bwa,2015-12-09,2015-06-07
-6bwm,2018-05-02,2017-12-15
-8bw1,2023-12-20,2022-12-06
-2bwd,2005-08-17,2005-07-13
-4bwl,2014-02-19,2013-07-03
-7bw1,2020-08-05,2020-04-13
-5bwl,2016-07-13,2015-06-08
-5bwh,2015-10-28,2015-06-08
-8bw0,2024-01-24,2022-12-06
-8bw6,2023-02-15,2022-12-06
-2bw1,2006-09-27,2005-07-07
-3bwf,2008-06-24,2008-01-09
-3bw3,2009-01-13,2008-01-08
-4bwc,2013-09-18,2013-07-01
-6bw5,2018-02-21,2017-12-14
-5bwn,2016-07-13,2015-06-08
-4bw9,2013-07-31,2013-07-01
-5bwm,2015-06-24,2015-06-08
-8bwg,2023-09-27,2022-12-06
-2bwv,2006-01-25,2005-07-19
-6bwy,2018-04-18,2017-12-15
-7bw4,2020-05-27,2020-04-13
-8bwf,2023-10-11,2022-12-06
-4bwu,2014-07-16,2013-07-04
-6bwi,2018-12-19,2017-12-15
-2bwh,2005-07-28,2005-07-14
-5bwc,2015-09-09,2015-06-07
-2bwg,2005-07-20,2005-07-13
-6bwh,2018-12-19,2017-12-15
-4bw2,2013-09-11,2013-06-29
-1bw8,1998-11-25,1998-09-30
-6bw6,2018-02-21,2017-12-14
-4bwt,2014-07-16,2013-07-04
-2bwx,2006-01-25,2005-07-19
-3bww,2008-01-22,2008-01-10
-3bwy,2008-06-03,2008-01-10
-6bwq,2018-06-20,2017-12-15
-3bwj,2009-02-03,2008-01-09
-8bwz,2023-08-02,2022-12-07
-8bwo,2023-08-30,2022-12-07
-5bw8,2015-10-14,2015-06-06
-1bwl,1998-09-30,1998-09-24
-5bwj,2015-07-29,2015-06-08
-5bw6,2016-02-10,2015-06-06
-2bwo,2005-09-27,2005-07-15
-2bwr,2006-01-23,2005-07-18
-1bwu,1999-01-20,1998-09-28
-6bwd,2018-08-15,2017-12-14
-2bww,2006-01-25,2005-07-19
-1bw9,1999-05-18,1998-10-01
-8bwj,2023-08-02,2022-12-06
-3bwr,2008-03-04,2008-01-10
-8bwh,2024-05-01,2022-12-06
-4bw8,2014-01-15,2013-06-30
-8bw4,2022-12-21,2022-12-06
-2bwp,2005-09-27,2005-07-15
-4bw5,2013-07-31,2013-06-30
-4bwp,2013-08-21,2013-07-03
-8bw3,2022-12-21,2022-12-06
-8bwx,2023-08-02,2022-12-07
-8bwr,2023-08-30,2022-12-07
-2bw7,2005-07-20,2005-07-12
-4bwm,2013-09-18,2013-07-03
-3bwm,2008-06-03,2008-01-09
-2bw9,2005-07-13,2005-07-13
-6bw0,2018-07-04,2017-12-14
-2bwy,2006-01-25,2005-07-19
-7bwj,2020-06-03,2020-04-14
-2bws,2006-01-25,2005-07-19
-1bwv,1999-09-27,1998-09-29
-8bw7,2023-07-19,2022-12-06
-4bwx,2013-08-21,2013-07-04
-7bwu,2021-04-21,2020-04-16
-3bwa,2008-04-22,2008-01-08
-5bwt,2015-07-01,2015-06-08
-6bww,2018-12-19,2017-12-15
-2bwn,2005-09-27,2005-07-15
-5bw7,2015-10-14,2015-06-06
-8bwe,2024-05-01,2022-12-06
-7bwc,2020-11-04,2020-04-14
-3bw7,2008-07-15,2008-01-08
-8htb,2023-09-20,2022-12-21
-6hts,2018-11-07,2018-10-04
-2ht9,2006-08-29,2006-07-25
-6ht9,2019-03-13,2018-10-03
-1htn,1997-12-03,1997-05-28
-6htn,2019-01-23,2018-10-04
-5htp,2016-06-08,2016-01-27
-3htt,2009-08-11,2009-06-12
-5htv,2016-06-08,2016-01-27
-3htr,2009-07-07,2009-06-12
-8htr,2024-05-15,2022-12-21
-1htq,2002-07-24,2001-01-01
-6htp,2019-01-30,2018-10-04
-3htb,2009-11-03,2009-06-11
-3ht6,2009-11-03,2009-06-11
-8htv,2023-08-30,2022-12-21
-5ht4,2017-02-01,2016-01-26
-6ht6,2018-10-10,2018-10-03
-2htv,2006-09-05,2006-07-26
-4htv,2012-11-28,2012-11-01
-3ht8,2009-11-03,2009-06-11
-2hty,2006-09-05,2006-07-26
-3htx,2009-09-29,2009-06-12
-4htn,2013-05-15,2012-11-01
-3htq,2009-08-11,2009-06-12
-8ht9,2023-12-20,2022-12-20
-3hti,2010-07-14,2009-06-11
-6htr,2019-01-30,2018-10-04
-6ht8,2018-10-31,2018-10-03
-6htw,2019-10-23,2018-10-04
-1ht8,2001-04-11,2000-12-29
-6htg,2018-10-31,2018-10-04
-3ht1,2009-10-13,2009-06-11
-5htb,2016-05-11,2016-01-26
-6htk,2018-11-21,2018-10-04
-3hth,2010-07-14,2009-06-11
-2hte,2006-08-08,2006-07-25
-1htp,1995-03-31,1995-01-11
-1ht5,2001-04-11,2000-12-28
-8htz,2024-04-03,2022-12-22
-6htt,2018-10-31,2018-10-04
-4hth,2012-11-28,2012-11-01
-4htc,1994-01-31,1993-06-25
-3ht2,2009-10-13,2009-06-11
-8hte,2023-11-22,2022-12-21
-8htg,2023-12-20,2022-12-21
-3hto,2009-08-11,2009-06-12
-2htx,2007-05-22,2006-07-26
-3ht5,2009-12-01,2009-06-11
-4ht9,2013-04-17,2012-11-01
-5ht5,2017-02-01,2016-01-26
-2htu,2006-09-05,2006-07-26
-6htc,2019-01-30,2018-10-03
-5hto,2016-10-19,2016-01-27
-5ht0,2016-03-02,2016-01-26
-3htd,2009-11-03,2009-06-11
-2htw,2006-09-05,2006-07-26
-1htb,1995-12-07,1995-08-10
-1ht9,2001-05-09,2000-12-29
-6htj,2019-10-16,2018-10-04
-5htl,2016-10-05,2016-01-27
-3ht0,2010-06-23,2009-06-11
-4ht8,2013-04-17,2012-11-01
-4htp,2012-12-26,2012-11-01
-4htu,2012-12-19,2012-11-01
-3htn,2009-06-30,2009-06-12
-1htt,1997-01-27,1996-03-09
-5htz,2016-11-09,2016-01-27
-4htk,2013-05-15,2012-11-01
-3htw,2009-06-30,2009-06-12
-4ht0,2013-04-10,2012-10-31
-1ht3,2001-06-27,2000-12-27
-5htk,2016-11-16,2016-01-27
-1ht2,2001-11-14,2000-12-27
-4htb,2013-11-20,2012-11-01
-3ht9,2009-11-03,2009-06-11
-1htw,2002-08-07,2001-01-01
-6hte,2018-11-21,2018-10-04
-3htf,2009-11-03,2009-06-11
-4htg,2013-02-27,2012-11-01
-5htc,2016-03-16,2016-01-26
-2ht8,2006-09-05,2006-07-25
-4htf,2012-11-21,2012-11-01
-2ht5,2006-09-05,2006-07-25
-5ht8,2017-02-01,2016-01-26
-8ht4,2024-01-17,2022-12-20
-1htf,1994-07-31,1994-04-29
-6htv,2019-09-11,2018-10-04
-1htg,1994-07-31,1994-04-29
-5hti,2017-02-01,2016-01-26
-3htk,2009-10-20,2009-06-11
-4htr,2013-01-16,2012-11-01
-8htu,2023-08-02,2022-12-21
-8htt,2023-12-27,2022-12-21
-1htv,2001-05-23,2001-01-01
-1ht1,2001-11-14,2000-12-27
-3htp,2009-08-11,2009-06-12
-2ht6,2006-10-31,2006-07-25
-2hti,2006-08-01,2006-07-25
-6hti,2018-10-31,2018-10-04
-4htm,2012-12-05,2012-11-01
-6hty,2019-12-04,2018-10-05
-8hti,2023-12-20,2022-12-21
-2ht1,2006-11-14,2006-07-24
-2htn,2006-11-21,2006-07-26
-6ht7,2020-04-29,2018-10-03
-6ht1,2018-10-17,2018-10-02
-6htl,2019-06-05,2018-10-04
-6htz,2018-10-31,2018-10-05
-5ht2,2016-04-27,2016-01-26
-6ht0,2018-10-17,2018-10-02
-4htq,2013-05-15,2012-11-01
-3htl,2009-09-15,2009-06-11
-1htm,1995-02-14,1994-11-02
-8hts,2024-05-15,2022-12-21
-6htd,2019-01-30,2018-10-03
-4htz,2013-08-28,2012-11-02
-4hte,2013-01-30,2012-11-01
-4ht3,2014-01-01,2012-10-31
-1htd,1995-09-15,1994-01-20
-3htj,2010-07-14,2009-06-11
-3ht7,2009-11-03,2009-06-11
-6hto,2018-11-21,2018-10-04
-1ht6,2003-07-08,2000-12-29
-1hte,1994-07-31,1994-04-29
-6hth,2018-10-31,2018-10-04
-5ht7,2017-02-01,2016-01-26
-3ht3,2010-07-14,2009-06-11
-5ht9,2017-02-08,2016-01-26
-2ht7,2006-09-05,2006-07-25
-2htq,2006-09-05,2006-07-26
-4ht4,2013-01-30,2012-10-31
-1hti,1995-01-26,1994-10-12
-8ht1,2023-12-20,2022-12-20
-2htr,2006-09-05,2006-07-26
-5htx,2016-06-08,2016-01-27
-1hto,2002-07-24,2001-01-01
-4htx,2013-08-28,2012-11-02
-1ht0,2001-01-10,2000-12-27
-3htg,2009-11-03,2009-06-11
-1hty,2002-01-02,2001-01-02
-6htm,2018-11-21,2018-10-04
-4ht2,2013-04-10,2012-10-31
-8htf,2023-11-22,2022-12-21
-6htb,2019-01-30,2018-10-03
-8d8g,2023-05-10,2022-06-08
-8d8c,2023-05-10,2022-06-08
-5d8r,2015-09-23,2015-08-17
-6d83,2018-08-08,2018-04-25
-2d8s,2006-06-08,2005-12-08
-4d86,2013-03-13,2012-01-10
-1d8u,2001-01-10,1999-10-26
-5d8q,2015-09-23,2015-08-17
-6d8b,2018-05-30,2018-04-26
-8d8z,2023-06-14,2022-06-09
-6d8c,2018-09-19,2018-04-26
-8d8d,2023-05-10,2022-06-08
-7d8n,2021-06-02,2020-10-08
-7d8j,2020-12-23,2020-10-08
-5d8p,2015-09-23,2015-08-17
-4d8z,2012-03-28,2012-01-11
-3d8w,2009-03-03,2008-05-26
-8d8y,2023-06-14,2022-06-09
-8d8f,2023-05-10,2022-06-08
-5d87,2016-02-03,2015-08-15
-2d8q,2006-06-08,2005-12-08
-7d8g,2021-03-17,2020-10-08
-8d8a,2023-05-10,2022-06-08
-8d8o,2022-09-28,2022-06-08
-2d80,2006-01-31,2005-11-30
-5d86,2016-02-03,2015-08-15
-3d8n,2008-08-12,2008-05-23
-2d81,2006-01-31,2005-11-30
-4d8v,2012-09-26,2012-01-11
-7d8p,2021-02-24,2020-10-08
-6d8d,2018-05-30,2018-04-26
-1d8c,1999-11-10,1999-10-22
-8d88,2022-11-16,2022-06-08
-7d87,2021-07-28,2020-10-07
-6d8i,2018-06-06,2018-04-26
-8d85,2023-03-29,2022-06-07
-2d82,2006-04-04,2005-12-01
-1d8y,1999-12-02,1999-10-26
-6d80,2018-07-11,2018-04-25
-8d8q,2022-10-19,2022-06-08
-5d8z,2016-06-29,2015-08-18
-5d8b,2015-10-14,2015-08-17
-7d8q,2021-03-17,2020-10-09
-8d82,2023-03-29,2022-06-07
-7d8i,2021-03-17,2020-10-08
-3d83,2008-07-22,2008-05-22
-1d8f,2000-10-23,1999-10-22
-7d85,2021-04-07,2020-10-07
-3d8b,2008-08-26,2008-05-23
-8d8l,2022-12-14,2022-06-08
-8d8r,2022-10-19,2022-06-08
-4d87,2012-06-20,2012-01-10
-4d8c,2012-11-21,2012-01-10
-5d8u,2016-03-16,2015-08-18
-2d8w,2006-07-11,2005-12-08
-2d8v,2006-06-08,2005-12-08
-3d8x,2008-12-09,2008-05-26
-6d8w,2018-05-09,2018-04-27
-4d8f,2012-02-15,2012-01-10
-1d8d,2000-02-09,1999-10-22
-3d80,2008-09-23,2008-05-22
-4d85,2012-11-21,2012-01-10
-3d8p,2008-10-28,2008-05-23
-7d8f,2021-05-26,2020-10-08
-5d84,2016-02-03,2015-08-15
-1d8e,2000-03-20,1999-10-22
-4d8e,2012-06-06,2012-01-10
-7d8d,2021-05-26,2020-10-08
-2d8t,2006-06-08,2005-12-08
-7d8x,2021-01-27,2020-10-11
-8d8n,2022-08-31,2022-06-08
-2d8y,2006-06-08,2005-12-08
-4d8a,2012-04-04,2012-01-10
-5d8g,2015-12-09,2015-08-17
-7d8v,2021-10-13,2020-10-10
-1d8a,1999-10-28,1999-10-21
-8d87,2022-08-31,2022-06-08
-5d88,2015-12-02,2015-08-15
-4d8w,2012-05-30,2012-01-11
-8d8k,2022-12-21,2022-06-08
-5d85,2016-02-03,2015-08-15
-8d86,2023-06-28,2022-06-07
-6d8f,2018-07-25,2018-04-26
-7d8h,2021-02-24,2020-10-08
-8d8j,2022-12-21,2022-06-08
-6d8p,2018-07-25,2018-04-26
-3d8g,2009-01-06,2008-05-23
-8d8h,2023-05-10,2022-06-08
-7d8m,2021-08-18,2020-10-08
-7d89,2021-08-18,2020-10-07
-1d8t,2000-10-25,1999-10-25
-4d88,2012-11-21,2012-01-10
-8d81,2022-07-20,2022-06-07
-7d8e,2021-12-08,2020-10-08
-7d8u,2020-12-02,2020-10-10
-2d8l,2006-11-14,2005-12-06
-2d8a,2006-06-02,2005-12-02
-7d8z,2020-12-30,2020-10-11
-5d8s,2015-09-23,2015-08-17
-7d8a,2021-07-28,2020-10-07
-2d8r,2006-06-08,2005-12-08
-3d8d,2008-06-10,2008-05-23
-5d8h,2016-08-24,2015-08-17
-8d84,2023-07-05,2022-06-07
-3d8c,2008-08-12,2008-05-23
-6d84,2018-08-08,2018-04-25
-6d8a,2018-07-25,2018-04-26
-6d88,2018-09-12,2018-04-26
-3d8v,2009-03-10,2008-05-25
-4d8g,2012-02-15,2012-01-10
-8d89,2022-11-02,2022-06-08
-6d8g,2018-10-17,2018-04-26
-5d8y,2015-09-23,2015-08-18
-3d8y,2009-02-10,2008-05-26
-4d8s,2013-02-13,2012-01-11
-8d8p,2023-05-17,2022-06-08
-3d82,2008-06-10,2008-05-22
-5d8x,2015-09-23,2015-08-18
-7d86,2021-07-28,2020-10-07
-3d8a,2008-09-09,2008-05-22
-6d8x,2019-05-01,2018-04-27
-7d83,2021-01-13,2020-10-07
-5d8o,2015-09-23,2015-08-17
-3d81,2008-09-30,2008-05-22
-6d8v,2019-04-17,2018-04-27
-7d8c,2021-05-19,2020-10-07
-7d88,2021-08-18,2020-10-07
-1d8w,2000-09-27,1999-10-26
-8d8e,2023-05-10,2022-06-08
-7d8l,2021-03-17,2020-10-08
-4d82,2015-11-25,2014-12-02
-6d8e,2018-07-18,2018-04-26
-8d8b,2023-05-10,2022-06-08
-8d80,2022-07-20,2022-06-07
-8d8m,2023-06-28,2022-06-08
-4d83,2012-11-21,2012-01-10
-2d8x,2006-06-08,2005-12-08
-4d89,2012-11-21,2012-01-10
-4d81,2015-11-25,2014-12-02
-4d8n,2012-03-21,2012-01-11
-5d8f,2016-08-17,2015-08-17
-3d84,2008-09-23,2008-05-22
-3d87,2008-09-02,2008-05-22
-5d8n,2016-05-11,2015-08-17
-2d8z,2006-06-08,2005-12-08
-2d8u,2006-06-08,2005-12-08
-8d8i,2022-12-14,2022-06-08
-1d8m,2000-10-25,1999-10-25
-3d8z,2009-02-10,2008-05-26
-4d8i,2012-06-06,2012-01-10
-1d8h,1999-11-29,1999-10-24
-6d8j,2018-06-06,2018-04-26
-8d8x,2023-06-14,2022-06-09
-5uew,2017-05-10,2017-01-03
-3uee,2012-03-07,2011-10-30
-1uej,2004-05-04,2003-05-16
-6ueg,2019-11-13,2019-09-20
-6ue7,2020-02-19,2019-09-20
-7ued,2023-02-01,2022-03-21
-6uec,2019-11-13,2019-09-20
-4ue6,2015-03-25,2014-12-16
-5ueo,2017-06-14,2017-01-03
-7ueo,2023-03-29,2022-03-22
-5uen,2017-03-01,2017-01-03
-1ueh,2003-08-12,2003-05-15
-4ueq,2015-03-25,2014-12-18
-6ue4,2020-05-27,2019-09-20
-6ueb,2020-02-05,2019-09-20
-6ued,2019-11-13,2019-09-20
-7uec,2022-03-30,2022-03-21
-3ue9,2011-11-16,2011-10-28
-5ue1,2017-01-18,2016-12-29
-7uet,2023-03-29,2022-03-22
-7uea,2022-10-05,2022-03-21
-1ue8,2004-07-13,2003-05-09
-7uem,2022-06-29,2022-03-22
-3ueg,2012-03-07,2011-10-30
-3uet,2012-04-04,2011-10-31
-1uei,2004-05-04,2003-05-16
-1uet,2003-12-02,2003-05-21
-1ueu,2003-12-02,2003-05-21
-4ueh,2015-08-26,2014-12-17
-6ue3,2020-03-04,2019-09-20
-4ue7,2015-08-26,2014-12-16
-5ueh,2018-01-17,2017-01-02
-3ue6,2012-04-11,2011-10-28
-7ue5,2023-03-29,2022-03-21
-7ueu,2023-03-29,2022-03-22
-6uex,2020-01-29,2019-09-23
-5uej,2017-02-01,2017-01-02
-7uey,2023-03-29,2022-03-22
-5ue3,2017-09-13,2016-12-29
-6uez,2020-06-10,2019-09-23
-4uee,2016-01-20,2014-12-17
-4ueo,2015-07-15,2014-12-18
-7ue1,2023-03-22,2022-03-21
-5uey,2017-05-10,2017-01-03
-8uee,2023-12-27,2023-10-01
-5uem,2018-01-10,2017-01-02
-6ueh,2020-03-11,2019-09-21
-5ues,2017-06-28,2017-01-03
-3ueo,2013-07-03,2011-10-31
-4ueg,2014-12-24,2014-12-17
-7uer,2023-03-29,2022-03-22
-7ue2,2023-03-29,2022-03-21
-6ue9,2020-02-19,2019-09-20
-5uep,2017-06-14,2017-01-03
-7uei,2022-03-30,2022-03-21
-6ueu,2020-09-30,2019-09-23
-8uel,2023-12-13,2023-10-01
-6uek,2020-01-15,2019-09-21
-7ueb,2022-10-05,2022-03-21
-5uer,2017-06-14,2017-01-03
-6uee,2019-11-13,2019-09-20
-7uev,2023-03-29,2022-03-22
-7ues,2023-03-29,2022-03-22
-5uez,2017-05-10,2017-01-03
-3ue0,2011-12-14,2011-10-28
-6uej,2019-11-13,2019-09-21
-5uec,2017-04-12,2016-12-30
-6uei,2019-11-13,2019-09-21
-7ueq,2023-03-29,2022-03-22
-7uep,2023-03-29,2022-03-22
-5ue4,2017-09-13,2016-12-29
-6uel,2020-03-18,2019-09-21
-1ue1,2004-02-10,2003-05-08
-3ueq,2012-01-11,2011-10-31
-1ue5,2004-02-10,2003-05-09
-7ue7,2023-03-29,2022-03-21
-3ue5,2012-02-15,2011-10-28
-6ue8,2020-02-19,2019-09-20
-3ue1,2011-12-14,2011-10-28
-3ued,2012-03-07,2011-10-30
-5ue7,2017-02-01,2016-12-29
-7uen,2022-06-29,2022-03-22
-4ueu,2015-02-18,2014-12-18
-1uef,2004-05-25,2003-05-14
-7uel,2022-06-29,2022-03-22
-3uey,2012-12-12,2011-10-31
-1uev,2003-12-02,2003-05-21
-4uez,2016-01-20,2014-12-22
-5ue9,2017-09-06,2016-12-29
-3uel,2012-05-23,2011-10-30
-7ue3,2023-03-29,2022-03-21
-7ue6,2023-04-05,2022-03-21
-7uex,2023-03-29,2022-03-22
-1uer,2004-05-20,2003-05-20
-3uei,2012-03-07,2011-10-30
-3ueh,2012-03-07,2011-10-30
-5ue8,2017-02-15,2016-12-29
-5uex,2017-05-10,2017-01-03
-4ue3,2014-12-24,2014-12-15
-3uer,2012-01-11,2011-10-31
-7ue4,2023-03-29,2022-03-21
-3uef,2012-03-07,2011-10-30
-4uec,2015-02-25,2014-12-16
-1ued,2003-12-09,2003-05-11
-4ue2,2015-03-25,2014-12-15
-4uek,2015-07-15,2014-12-18
-1uea,1998-10-14,1997-06-06
-7ue8,2023-03-29,2022-03-21
-3ue4,2012-04-18,2011-10-28
-7uej,2022-03-30,2022-03-21
-5ue6,2017-02-01,2016-12-29
-7uee,2022-03-30,2022-03-21
-3ue8,2012-02-01,2011-10-28
-1ues,2004-05-20,2003-05-20
-7ue0,2022-08-17,2022-03-20
-4uej,2015-07-15,2014-12-18
-4ue1,2016-01-13,2014-12-14
-5uev,2017-06-14,2017-01-03
-5uet,2017-06-14,2017-01-03
-4uew,2015-03-25,2014-12-20
-5ueq,2017-06-14,2017-01-03
-1ue0,2004-03-23,2003-05-08
-4uer,2015-02-11,2014-12-18
-6ue5,2019-12-18,2019-09-20
-3ues,2012-04-04,2011-10-31
-7uef,2022-03-30,2022-03-21
-3uec,2012-03-07,2011-10-30
-5ueu,2017-05-10,2017-01-03
-3uez,2012-08-22,2011-10-31
-3uej,2012-12-12,2011-10-30
-8uej,2024-05-15,2023-10-01
-6uea,2020-02-19,2019-09-20
-4ue8,2015-02-25,2014-12-16
-6pb4,2020-03-18,2019-06-13
-8pbt,2023-11-01,2023-06-09
-6pbj,2020-04-08,2019-06-13
-3pb6,2011-02-02,2010-10-20
-1pbb,1994-09-30,1994-07-06
-5pbe,2017-03-15,2017-02-03
-7pbr,2022-09-14,2021-08-02
-7pb6,2022-08-10,2021-07-31
-6pb0,2020-02-12,2019-06-12
-7pb1,2022-06-01,2021-07-30
-5pb0,2017-06-21,2016-11-10
-7pbd,2022-02-09,2021-08-02
-3pbt,2010-12-22,2010-10-20
-5pb2,2017-06-21,2016-11-16
-4pb2,2014-08-13,2014-04-11
-3pb8,2011-02-02,2010-10-20
-5pb1,2017-06-21,2016-11-10
-4pbu,2014-07-16,2014-04-13
-7pbj,2021-11-24,2021-08-02
-7pb5,2021-10-13,2021-07-30
-7pbl,2022-09-14,2021-08-02
-4pbx,2014-11-12,2014-04-14
-7pbe,2022-04-27,2021-08-02
-1pbx,1992-10-15,1991-11-04
-8pbk,2023-11-01,2023-06-09
-8pbm,2023-11-01,2023-06-09
-3pbk,2010-12-22,2010-10-20
-7pbs,2022-09-14,2021-08-02
-6pbd,2019-10-23,2019-06-13
-2pbd,2007-11-13,2007-03-28
-3pbs,2010-12-22,2010-10-20
-1pby,2003-09-02,2003-05-15
-3pb3,2010-11-24,2010-10-20
-6pbc,2020-01-08,2019-06-13
-2pb6,2007-10-02,2007-03-28
-6pbr,2019-06-26,2019-06-14
-5pbb,2017-03-15,2017-02-03
-1pbo,1997-07-23,1996-07-15
-8pbc,2023-11-15,2023-06-09
-2pbk,2007-12-25,2007-03-28
-8pbo,2024-05-15,2023-06-09
-8pbg,2023-11-01,2023-06-09
-1pb5,2003-06-17,2003-05-14
-6pbf,2019-11-06,2019-06-13
-1pbd,1994-09-30,1994-07-06
-4pb5,2015-03-11,2014-04-11
-4pb4,2015-03-11,2014-04-11
-7pbz,2022-02-09,2021-08-03
-1pbj,2003-12-16,2003-05-14
-8pbr,2023-11-01,2023-06-09
-7pbo,2022-09-14,2021-08-02
-4pbp,2015-03-25,2014-04-13
-7pbm,2022-09-14,2021-08-02
-7pbp,2022-09-14,2021-08-02
-6pb5,2020-03-18,2019-06-13
-8pbl,2023-10-25,2023-06-09
-8pbe,2023-11-01,2023-06-09
-1pbz,2003-12-09,2003-05-15
-3pbj,2011-11-30,2010-10-20
-2pbw,2007-07-03,2007-03-29
-5pbc,2017-03-15,2017-02-03
-6pb6,2020-03-18,2019-06-13
-4pbt,2014-07-23,2014-04-13
-5pb3,2017-06-21,2016-11-16
-4pbs,2014-07-23,2014-04-13
-8pbs,2023-11-01,2023-06-09
-1pbe,1994-09-30,1994-07-06
-1pb0,2004-05-25,2003-05-14
-7pby,2021-10-13,2021-08-02
-6pbo,2019-10-23,2019-06-14
-6pbw,2020-03-04,2019-06-14
-2pb4,2007-10-02,2007-03-28
-5pb9,2017-03-15,2017-02-03
-4pbf,2015-05-06,2014-04-12
-8pb5,2024-04-03,2023-06-08
-4pb1,2014-08-13,2014-04-11
-7pbc,2022-08-03,2021-08-02
-7pbf,2022-08-10,2021-08-02
-8pbh,2023-11-01,2023-06-09
-5pbf,2017-03-15,2017-02-03
-8pb3,2024-04-03,2023-06-08
-7pbi,2021-09-29,2021-08-02
-1pb7,2003-06-24,2003-05-14
-2pb0,2007-12-25,2007-03-28
-7pbg,2021-09-29,2021-08-02
-3pb7,2011-02-02,2010-10-20
-3pba,2011-06-08,2010-10-20
-8pbq,2023-11-01,2023-06-09
-5pba,2017-03-15,2017-02-03
-1pbf,1994-09-30,1994-07-06
-8pbu,2023-11-01,2023-06-09
-6pbm,2019-10-30,2019-06-14
-5pb5,2017-06-21,2016-11-16
-3pb5,2011-10-19,2010-10-20
-4pbw,2014-11-12,2014-04-14
-7pbw,2021-11-24,2021-08-02
-8pbn,2023-11-01,2023-06-09
-3pbe,2011-02-02,2010-10-20
-3pbd,2011-10-19,2010-10-20
-2pb5,2007-10-02,2007-03-28
-5pb8,2017-03-15,2017-02-03
-6pbi,2020-05-06,2019-06-13
-6pbp,2019-10-30,2019-06-14
-1pb9,2003-06-24,2003-05-14
-8pb9,2023-12-13,2023-06-08
-3pbu,2011-09-21,2010-10-21
-2pb1,2007-04-10,2007-03-28
-7pb3,2022-08-10,2021-07-30
-7pb0,2022-06-01,2021-07-30
-3pb4,2011-02-02,2010-10-20
-7pba,2021-10-13,2021-08-01
-8pbf,2023-11-08,2023-06-09
-2pbf,2007-04-10,2007-03-28
-6pbn,2019-10-30,2019-06-14
-4pbv,2014-11-12,2014-04-14
-5pb6,2017-06-21,2016-11-16
-5pbd,2017-03-15,2017-02-03
-5pb7,2017-03-15,2017-02-03
-3pbb,2011-02-02,2010-10-20
-2pb8,2007-04-17,2007-03-28
-8pb1,2024-02-07,2023-06-08
-8pb4,2024-04-03,2023-06-08
-8pb6,2024-04-03,2023-06-08
-4pbg,1997-07-23,1997-02-21
-7pbn,2022-09-14,2021-08-02
-7pbx,2021-11-24,2021-08-02
-2pbl,2007-04-17,2007-03-28
-3pb9,2011-02-02,2010-10-20
-8pbd,2023-11-15,2023-06-09
-8pb7,2024-04-03,2023-06-08
-2pb2,2007-12-25,2007-03-28
-3pbz,2011-10-19,2010-10-21
-4pbe,2015-05-06,2014-04-12
-3pbr,2010-12-22,2010-10-20
-7pbt,2022-09-14,2021-08-02
-3pbw,2011-09-21,2010-10-21
-7pbq,2022-09-14,2021-08-02
-1pbq,2003-07-29,2003-05-14
-5pb4,2017-06-21,2016-11-16
-3pbm,2010-12-22,2010-10-20
-8pbp,2023-11-01,2023-06-09
-6pbh,2019-12-11,2019-06-13
-6pbk,2019-11-20,2019-06-14
-8pbj,2023-11-01,2023-06-09
-7pb7,2022-08-10,2021-07-31
-6pbe,2019-11-06,2019-06-13
-1pbk,1996-10-14,1995-09-01
-8pb8,2024-04-03,2023-06-08
-3pbq,2010-12-22,2010-10-20
-4pbr,2014-07-23,2014-04-13
-3pbl,2010-11-03,2010-10-20
-4pb3,2015-03-11,2014-04-11
-3pbo,2010-12-22,2010-10-20
-8pbi,2023-11-01,2023-06-09
-6pbs,2020-05-13,2019-06-14
-2pbj,2008-02-12,2007-03-28
-8pbz,2023-11-01,2023-06-09
-3pbv,2011-09-21,2010-10-21
-3pby,2011-09-21,2010-10-21
-6pbt,2019-10-30,2019-06-14
-2pbz,2007-04-10,2007-03-29
-4pbq,2014-05-07,2014-04-13
-1pb8,2003-06-24,2003-05-14
-1pbc,1994-09-30,1994-07-06
-3pbf,2010-11-03,2010-10-20
-7pbb,2021-10-13,2021-08-01
-6pb1,2020-02-12,2019-06-12
-7cx8,2021-09-08,2020-09-01
-3cxc,2009-04-28,2008-04-24
-5cxy,2016-09-07,2015-07-29
-4cxg,2014-07-16,2014-04-07
-6cxe,2019-04-10,2018-04-02
-2cxg,1998-10-14,1998-05-08
-5cxb,2015-11-04,2015-07-28
-7cxm,2020-11-04,2020-09-02
-5cxk,2015-12-09,2015-07-29
-7cx4,2021-05-05,2020-09-01
-2cxr,2006-05-23,2005-06-30
-1cxf,1995-12-15,1995-07-28
-5cxm,2016-08-03,2015-07-29
-8cxt,2023-01-11,2022-05-22
-3cxk,2008-05-27,2008-04-24
-1cxp,2000-04-24,1999-08-30
-6cxb,2019-02-20,2018-04-02
-1cxc,1995-09-15,1994-02-14
-7cxb,2021-09-01,2020-09-01
-6cxl,2019-02-20,2018-04-03
-1cxi,1995-12-15,1995-07-31
-5cxj,2016-08-03,2015-07-29
-4cxp,2014-07-23,2014-04-08
-1cx4,2001-03-07,1999-08-28
-4cxm,2014-10-08,2014-04-07
-4cxq,2014-04-23,2014-04-08
-7cxu,2021-07-14,2020-09-02
-4cx4,2014-08-13,2014-04-03
-2cxs,2006-05-23,2005-06-30
-8cxn,2022-07-06,2022-05-22
-8cxs,2023-01-11,2022-05-22
-5cxl,2015-09-02,2015-07-29
-1cxe,1995-12-15,1995-07-28
-6cxk,2019-01-09,2018-04-03
-8cx8,2024-03-06,2022-05-20
-3cxi,2009-05-05,2008-04-24
-3cx7,2008-10-28,2008-04-23
-6cxs,2019-04-17,2018-04-04
-5cx6,2015-11-11,2015-07-28
-8cxv,2023-01-11,2022-05-22
-1cx9,1999-12-29,1999-08-29
-2cxo,2006-05-23,2005-06-30
-8cxa,2022-07-27,2022-05-20
-4cxu,2015-04-22,2014-04-08
-6cx7,2019-04-10,2018-04-02
-7cxz,2020-11-25,2020-09-02
-4cx9,2015-04-08,2014-04-04
-6cxt,2019-01-16,2018-04-04
-6cxc,2019-07-31,2018-04-02
-6cxg,2019-02-20,2018-04-03
-5cx9,2016-11-30,2015-07-28
-6cxu,2018-06-27,2018-04-04
-3cxq,2008-09-16,2008-04-25
-7cx2,2021-05-05,2020-09-01
-3cx5,2008-05-13,2008-04-23
-1cxk,1999-05-03,1999-02-24
-6cxy,2019-04-10,2018-04-04
-4cxh,2014-07-16,2014-04-07
-4cxw,2014-10-01,2014-04-09
-8cx2,2023-02-15,2022-05-19
-7cxc,2021-09-01,2020-09-01
-3cx8,2008-10-28,2008-04-23
-1cxa,1995-07-10,1994-02-14
-4cxo,2014-07-23,2014-04-08
-2cxv,2005-12-27,2005-07-01
-3cx6,2008-10-28,2008-04-23
-7cxt,2021-04-14,2020-09-02
-1cxx,1999-09-08,1999-08-31
-6cx6,2018-06-27,2018-04-02
-8cxl,2022-08-31,2022-05-21
-3cxv,2008-09-23,2008-04-25
-2cxt,2006-05-23,2005-06-30
-7cxo,2021-09-08,2020-09-02
-5cxa,2016-08-10,2015-07-28
-7cxn,2020-11-04,2020-09-02
-8cxy,2023-01-11,2022-05-22
-5cxh,2015-09-23,2015-07-29
-2cx8,2005-12-28,2005-06-28
-7cx1,2021-09-01,2020-09-01
-5cxr,2015-12-30,2015-07-29
-3cx3,2008-08-05,2008-04-23
-4cxs,2015-05-13,2014-04-08
-7cx9,2020-09-16,2020-09-01
-3cxw,2008-07-15,2008-04-25
-4cxt,2014-06-18,2014-04-08
-4cxa,2014-05-21,2014-04-04
-8cxx,2023-01-11,2022-05-22
-3cxz,2008-09-23,2008-04-25
-8cx0,2023-02-15,2022-05-19
-6cx9,2019-04-10,2018-04-02
-5cxi,2016-02-17,2015-07-29
-3cxy,2008-09-23,2008-04-25
-1cxv,2000-08-30,1999-08-30
-8cxi,2023-06-07,2022-05-21
-5cxp,2016-08-10,2015-07-29
-6cxv,2018-06-27,2018-04-04
-6cx5,2019-04-10,2018-04-02
-7cx7,2021-09-01,2020-09-01
-2cxx,2006-01-01,2005-07-01
-2cxq,2006-05-23,2005-06-30
-4cxv,2014-07-23,2014-04-09
-8cxu,2023-01-11,2022-05-22
-5cxd,2015-08-05,2015-07-28
-3cxm,2008-05-06,2008-04-24
-6cxa,2019-04-10,2018-04-02
-3cxo,2008-09-23,2008-04-24
-5cxx,2016-04-27,2015-07-29
-5cxw,2016-05-04,2015-07-29
-5cx7,2016-06-29,2015-07-28
-3cxx,2008-09-23,2008-04-25
-1cxh,1995-12-15,1995-07-31
-8cx4,2022-12-07,2022-05-19
-4cx6,2014-08-13,2014-04-03
-4cx1,2014-08-13,2014-04-03
-4cx7,2014-08-13,2014-04-03
-7cxd,2021-09-01,2020-09-01
-8cxo,2022-08-03,2022-05-22
-6cxh,2018-05-16,2018-04-03
-7cx6,2021-09-08,2020-09-01
-7cx3,2021-05-05,2020-09-01
-6cxo,2018-09-05,2018-04-03
-7cx0,2021-09-01,2020-09-01
-4cxr,2014-04-23,2014-04-08
-1cx8,1999-09-09,1999-08-28
-7cxa,2021-09-01,2020-09-01
-3cxa,2008-05-20,2008-04-24
-5cx8,2015-10-21,2015-07-28
-3cxl,2008-08-05,2008-04-24
-5cx0,2016-08-03,2015-07-28
-8cx3,2023-02-01,2022-05-19
-5cxv,2016-03-09,2015-07-29
-8cxd,2022-12-07,2022-05-20
-8cx1,2023-02-15,2022-05-19
-4cxx,2014-10-01,2014-04-09
-1cx2,1997-12-24,1996-12-17
-4cxy,2014-10-01,2014-04-09
-3cxd,2008-10-14,2008-04-24
-7cxy,2021-03-31,2020-09-02
-4cx3,2014-08-13,2014-04-03
-6cx8,2018-04-18,2018-04-02
-6cx0,2018-09-19,2018-04-02
-4cx0,2014-08-13,2014-04-03
-8cx5,2022-08-31,2022-05-19
-5cxf,2015-10-28,2015-07-28
-6cxf,2019-04-10,2018-04-02
-5cxz,2015-09-16,2015-07-29
-6cxm,2018-04-11,2018-04-03
-2cxp,2006-05-23,2005-06-30
-1cxy,1999-09-10,1999-08-31
-8cxz,2023-01-11,2022-05-22
-1cxz,1999-10-08,1999-08-31
-1cxl,1999-05-03,1999-02-27
-2cxb,1995-10-15,1994-04-21
-4cxk,2015-04-22,2014-04-07
-3cx4,2009-04-28,2008-04-23
-3cxh,2008-05-13,2008-04-24
-5cxt,2015-10-14,2015-07-29
-4cx2,2014-08-13,2014-04-03
-8cx9,2023-01-25,2022-05-20
-6cxx,2018-04-25,2018-04-04
-8cxw,2023-01-11,2022-05-22
-4cx5,2014-08-13,2014-04-03
-1n5k,2003-04-15,2002-11-06
-5n5o,2018-03-07,2017-02-14
-6n59,2019-12-25,2018-11-21
-3n5v,2011-02-09,2010-05-25
-1n5q,2003-01-14,2002-11-07
-7n5h,2021-11-03,2021-06-05
-1n57,2003-03-18,2002-11-04
-5n5e,2018-01-24,2017-02-13
-6n50,2019-01-23,2018-11-20
-7n5y,2021-09-08,2021-06-07
-4n56,2015-01-21,2013-10-09
-5n57,2018-03-07,2017-02-13
-1n59,2003-01-07,2002-11-05
-7n5x,2021-09-08,2021-06-07
-3n5e,2011-06-08,2010-05-25
-5n5i,2018-03-07,2017-02-14
-4n5m,2013-12-11,2013-10-10
-3n5k,2011-06-08,2010-05-25
-5n5g,2018-03-07,2017-02-14
-7n59,2022-04-13,2021-06-05
-5n56,2018-03-07,2017-02-13
-4n5n,2013-12-11,2013-10-10
-7n57,2023-01-25,2021-06-04
-3n5w,2011-02-09,2010-05-25
-1n5n,2003-06-24,2002-11-06
-6n5w,2019-03-13,2018-11-22
-6n57,2020-02-26,2018-11-21
-5n5z,2017-04-05,2017-02-14
-5n55,2017-05-17,2017-02-13
-7n5r,2021-09-08,2021-06-06
-7n5s,2021-08-25,2021-06-06
-3n5p,2011-02-09,2010-05-25
-6n51,2019-01-23,2018-11-20
-3n58,2010-06-02,2010-05-24
-7n5c,2022-07-20,2021-06-05
-4n5k,2013-12-18,2013-10-10
-5n5m,2018-03-07,2017-02-14
-3n5j,2010-08-18,2010-05-25
-6n5x,2019-09-18,2018-11-22
-1n5m,2003-02-04,2002-11-06
-1n51,2003-12-16,2002-11-03
-5n53,2017-04-05,2017-02-12
-4n5g,2014-05-14,2013-10-09
-3n5h,2010-08-18,2010-05-25
-6n5a,2019-06-26,2018-11-21
-1n50,1999-06-15,1998-09-04
-1n5x,2003-03-18,2002-11-07
-5n58,2017-05-17,2017-02-13
-7n55,2022-06-08,2021-06-04
-4n5h,2014-10-15,2013-10-09
-3n5y,2011-02-09,2010-05-25
-1n5d,2002-11-13,2002-11-05
-5n5y,2017-04-05,2017-02-14
-7n5p,2022-07-20,2021-06-06
-4n57,2014-12-17,2013-10-09
-6n5e,2019-06-05,2018-11-21
-5n52,2018-02-28,2017-02-11
-7n5o,2021-09-08,2021-06-06
-4n5x,2013-12-18,2013-10-10
-3n5q,2011-02-09,2010-05-25
-2n5k,2016-03-16,2015-07-18
-4n5s,2015-01-21,2013-10-10
-5n5l,2018-03-07,2017-02-14
-3n5a,2010-09-29,2010-05-24
-4n5i,2014-04-16,2013-10-09
-3n5u,2010-08-11,2010-05-25
-3n55,2010-06-02,2010-05-24
-4n5p,2014-04-02,2013-10-10
-3n5f,2011-05-25,2010-05-25
-1n56,2004-02-24,2002-11-04
-1n5a,2003-01-07,2002-11-05
-7n53,2022-06-29,2021-06-04
-1n5j,2003-04-15,2002-11-06
-3n5b,2010-09-01,2010-05-24
-3n5t,2011-02-09,2010-05-25
-4n5r,2013-11-27,2013-10-10
-3n5c,2010-08-18,2010-05-25
-5n5d,2017-09-20,2017-02-13
-6n5g,2019-11-20,2018-11-21
-4n5d,2013-12-18,2013-10-09
-1n55,2003-01-21,2002-11-04
-6n5u,2019-07-24,2018-11-22
-6n5f,2019-11-20,2018-11-21
-1n5y,2003-01-28,2002-11-07
-7n5a,2022-04-13,2021-06-05
-5n5f,2018-01-24,2017-02-13
-4n5e,2015-08-19,2013-10-09
-5n5n,2017-11-01,2017-02-14
-3n56,2010-11-17,2010-05-24
-4n5y,2013-11-20,2013-10-10
-3n59,2010-07-21,2010-05-24
-1n5t,2003-01-14,2002-11-07
-6n5v,2019-11-27,2018-11-22
-7n5v,2022-06-08,2021-06-06
-6n53,2019-11-27,2018-11-21
-2n5i,2015-09-16,2015-07-17
-1n5l,2003-04-15,2002-11-06
-3n5s,2011-02-09,2010-05-25
-1n5r,2003-02-04,2002-11-07
-5n5q,2018-03-07,2017-02-14
-4n5j,2013-12-18,2013-10-10
-3n51,2010-07-21,2010-05-24
-5n5h,2018-03-07,2017-02-14
-6n5i,2019-10-09,2018-11-21
-5n5k,2017-11-01,2017-02-14
-1n5w,2002-12-23,2002-11-07
-3n5x,2011-02-09,2010-05-25
-5n5w,2017-07-19,2017-02-14
-4n5v,2014-04-23,2013-10-10
-7n54,2022-06-29,2021-06-04
-1n5v,2003-01-14,2002-11-07
-5n5r,2017-07-19,2017-02-14
-4n5z,2013-11-20,2013-10-10
-3n5r,2011-02-09,2010-05-25
-6n52,2019-01-23,2018-11-20
-2n5h,2015-09-16,2015-07-17
-3n5d,2010-06-30,2010-05-25
-7n5u,2022-06-08,2021-06-06
-1n5o,2002-12-25,2002-11-06
-3n5z,2011-02-09,2010-05-25
-7n5w,2022-06-08,2021-06-06
-6n54,2019-11-27,2018-11-21
-7n5b,2022-04-13,2021-06-05
-5n5u,2018-02-14,2017-02-14
-7n5t,2021-08-25,2021-06-06
-5n5p,2018-02-28,2017-02-14
-1n5u,2003-06-24,2002-11-07
-5n5s,2017-08-09,2017-02-14
-4n54,2015-04-15,2013-10-09
-7n5q,2022-07-20,2021-06-06
-6n55,2019-11-27,2018-11-21
-3n57,2010-11-17,2010-05-24
-4n5t,2013-11-20,2013-10-10
-5n5j,2017-11-01,2017-02-14
-5n50,2018-02-28,2017-02-11
-1n5i,2003-04-08,2002-11-06
-3n5o,2010-06-16,2010-05-25
-6n5b,2019-06-05,2018-11-21
-6n58,2020-02-26,2018-11-21
-1n52,2003-02-18,2002-11-04
-5n5t,2017-07-19,2017-02-14
-6n5c,2019-08-21,2018-11-21
-6n5h,2019-11-20,2018-11-21
-5n51,2018-02-28,2017-02-11
-1n5s,2003-01-14,2002-11-07
-3k5l,2010-02-02,2009-10-07
-4k5x,2013-04-24,2013-04-15
-7k5i,2020-10-14,2020-09-16
-1k53,2001-12-05,2001-10-09
-4k5k,2013-09-18,2013-04-14
-6k54,2020-06-03,2019-05-28
-5k55,2017-06-07,2016-05-23
-5k5s,2016-08-03,2016-05-23
-1k5p,2003-08-26,2001-10-12
-5k51,2016-11-09,2016-05-22
-3k5m,2010-02-02,2009-10-07
-4k5s,2013-10-09,2013-04-15
-3k57,2010-02-09,2009-10-06
-8k53,2023-12-06,2023-07-21
-4k5l,2013-06-12,2013-04-14
-3k5f,2010-05-05,2009-10-07
-6k5k,2019-06-12,2019-05-29
-5k5m,2016-08-24,2016-05-23
-7k5f,2020-12-16,2020-09-16
-4k5w,2013-04-24,2013-04-15
-7k51,2021-07-28,2020-09-16
-6k52,2020-06-03,2019-05-28
-7k58,2021-09-29,2020-09-16
-4k5p,2013-06-12,2013-04-15
-1k5g,2002-02-13,2001-10-10
-1k51,2001-12-05,2001-10-09
-8k5c,2023-11-22,2023-07-21
-8k5q,2024-04-17,2023-07-23
-5k5i,2017-05-24,2016-05-23
-4k5i,2013-09-18,2013-04-14
-4k5r,2013-10-09,2013-04-15
-6k5j,2019-09-25,2019-05-29
-3k5y,2009-11-03,2009-10-08
-3k5e,2009-10-20,2009-10-07
-6k58,2020-03-18,2019-05-28
-3k59,2010-02-09,2009-10-06
-4k5h,2013-09-18,2013-04-14
-5k56,2017-06-07,2016-05-23
-3k5d,2010-05-05,2009-10-07
-4k5v,2013-04-24,2013-04-15
-5k5b,2016-10-26,2016-05-23
-4k5e,2013-09-18,2013-04-14
-5k5p,2016-06-01,2016-05-23
-7k52,2021-07-28,2020-09-16
-5k53,2016-09-07,2016-05-23
-3k5g,2010-05-05,2009-10-07
-3k5x,2010-01-12,2009-10-08
-6k53,2020-06-03,2019-05-28
-3k5i,2009-10-20,2009-10-07
-6k5z,2019-12-18,2019-05-31
-5k5t,2016-08-03,2016-05-23
-3k56,2010-05-05,2009-10-06
-1k52,2001-12-05,2001-10-09
-4k5u,2013-06-26,2013-04-15
-1k5d,2002-02-13,2001-10-10
-5k5c,2017-06-07,2016-05-23
-5k58,2016-06-22,2016-05-23
-8k5k,2023-12-06,2023-07-21
-5k50,2017-11-15,2016-05-22
-8k5d,2023-11-22,2023-07-21
-8k5p,2024-01-31,2023-07-23
-3k5z,2009-11-03,2009-10-08
-8k5w,2023-12-06,2023-07-24
-4k5m,2013-06-12,2013-04-14
-1k5c,2002-06-05,2001-10-10
-4k5y,2013-07-17,2013-04-15
-8k5v,2023-12-06,2023-07-24
-5k5z,2016-06-22,2016-05-24
-6k5q,2020-05-27,2019-05-30
-3k5s,2010-03-02,2009-10-07
-6k5l,2019-07-03,2019-05-29
-2k5t,2008-07-22,2008-06-30
-5k5l,2017-05-24,2016-05-23
-7k5h,2020-12-16,2020-09-16
-6k55,2020-06-03,2019-05-28
-1k5w,2002-01-23,2001-10-12
-5k5j,2017-05-24,2016-05-23
-2k5u,2009-01-27,2008-06-30
-6k5o,2019-07-24,2019-05-29
-7k5n,2021-08-18,2020-09-17
-5k5k,2017-06-07,2016-05-23
-7k5a,2021-09-22,2020-09-16
-3k55,2011-01-26,2009-10-06
-3k52,2010-05-05,2009-10-06
-5k5w,2016-12-07,2016-05-24
-7k54,2021-07-28,2020-09-16
-7k5v,2021-12-01,2020-09-17
-8k5x,2023-12-06,2023-07-24
-4k5j,2013-09-18,2013-04-14
-3k5c,2010-03-02,2009-10-07
-6k5h,2019-06-12,2019-05-28
-3k5h,2009-10-20,2009-10-07
-7k5z,2020-09-30,2020-09-17
-8k5i,2023-12-06,2023-07-21
-1k5q,2003-09-02,2001-10-12
-1k5s,2003-09-02,2001-10-12
-4k5g,2013-09-18,2013-04-14
-8k5j,2023-12-06,2023-07-21
-5k5h,2017-05-24,2016-05-23
-7k5t,2021-03-03,2020-09-17
-8k5b,2023-11-22,2023-07-21
-7k5g,2020-12-16,2020-09-16
-3k5q,2009-11-03,2009-10-07
-4k5f,2013-09-18,2013-04-14
-7k5k,2020-12-16,2020-09-17
-7k5l,2021-04-21,2020-09-17
-7k5b,2021-09-29,2020-09-16
-1k5n,2002-10-30,2001-10-11
-2k5c,2008-08-26,2008-06-26
-7k5q,2021-03-03,2020-09-17
-4k55,2013-07-24,2013-04-13
-7k5j,2021-04-28,2020-09-16
-3k58,2010-02-09,2009-10-06
-4k5o,2013-06-12,2013-04-15
-1k54,2001-11-07,2001-10-10
-3k54,2010-01-19,2009-10-06
-4k5z,2013-05-29,2013-04-15
-8k5n,2024-01-03,2023-07-22
-3k5u,2010-10-13,2009-10-08
-4k5d,2013-09-18,2013-04-14
-7k5d,2021-04-21,2020-09-16
-7k55,2021-07-28,2020-09-16
-7k5m,2021-07-28,2020-09-17
-8k5r,2023-12-06,2023-07-24
-8k5h,2023-12-27,2023-07-21
-3k5v,2010-01-19,2009-10-08
-3k5t,2010-02-09,2009-10-08
-7k5e,2020-12-16,2020-09-16
-4k5n,2013-06-12,2013-04-15
-6k5p,2019-09-11,2019-05-30
-8k5y,2023-12-06,2023-07-24
-5k5n,2016-09-21,2016-05-23
-5k5e,2016-07-27,2016-05-23
-6hmw,2019-08-14,2018-09-13
-5hm4,2016-11-23,2016-01-15
-8hmt,2023-12-13,2022-12-05
-6hmb,2019-03-27,2018-09-12
-1hm2,2001-05-02,2000-12-04
-4hmp,2013-09-04,2012-10-18
-5hm3,2016-08-03,2016-01-15
-6hmu,2019-02-27,2018-09-12
-3hmg,1991-01-15,1989-09-11
-8hms,2023-01-11,2022-12-05
-4hmk,2013-05-08,2012-10-18
-8hmg,2023-12-06,2022-12-03
-5hm8,2016-01-27,2016-01-15
-5hmd,2016-11-02,2016-01-16
-2hmn,2006-10-10,2006-07-11
-3hmk,2010-01-26,2009-05-29
-3hmf,2009-06-23,2009-05-29
-6hmg,2018-09-26,2018-09-12
-5hmp,2016-09-07,2016-01-16
-5hm0,2016-02-10,2016-01-15
-2hm9,2007-06-05,2006-07-11
-5hmj,2016-03-02,2016-01-16
-5hmm,2016-06-01,2016-01-16
-6hm4,2018-10-17,2018-09-12
-5hmv,2016-05-18,2016-01-17
-1hmu,2001-05-02,2000-12-05
-2hmc,2006-09-05,2006-07-11
-8hmn,2023-12-06,2022-12-05
-5hmc,2016-02-03,2016-01-15
-6hm1,2019-03-06,2018-09-11
-8hmr,2023-01-11,2022-12-05
-2hmf,2006-10-17,2006-07-11
-6hmf,2019-01-30,2018-09-12
-4hm2,2013-10-30,2012-10-17
-4hmu,2013-08-07,2012-10-18
-4hm8,2013-10-30,2012-10-17
-5hmr,2016-07-27,2016-01-16
-6hm2,2018-12-26,2018-09-12
-4hmh,2012-10-31,2012-10-18
-6hmd,2019-03-27,2018-09-12
-6hm3,2018-10-17,2018-09-12
-6hmk,2018-11-14,2018-09-12
-3hmq,2009-06-16,2009-05-29
-2hms,2006-09-26,2006-07-11
-4hmd,2013-05-01,2012-10-18
-6hma,2018-11-14,2018-09-12
-4hmr,2013-05-15,2012-10-18
-1hm8,2001-11-30,2000-12-05
-3hmb,2010-06-09,2009-05-29
-2hmt,2006-09-26,2006-07-11
-4hm4,2013-10-30,2012-10-17
-2hma,2006-08-08,2006-07-11
-5hml,2016-06-01,2016-01-16
-1hmk,1999-11-26,1998-11-26
-4hmi,2012-10-31,2012-10-18
-4hma,2013-04-24,2012-10-18
-8hm3,2023-11-29,2022-12-02
-5hm7,2017-07-26,2016-01-15
-1hmw,2001-05-02,2000-12-05
-4hmm,2013-05-15,2012-10-18
-3hm9,2009-10-06,2009-05-28
-1hm0,2001-11-30,2000-12-04
-3hmw,2010-06-09,2009-05-29
-6hmx,2018-11-07,2018-09-13
-6hm0,2019-01-16,2018-09-11
-6hmn,2018-11-14,2018-09-12
-6hml,2018-11-14,2018-09-12
-4hmy,2013-03-06,2012-10-18
-6hme,2019-03-27,2018-09-12
-8hmf,2023-06-14,2022-12-03
-8hmm,2023-12-06,2022-12-05
-5hmw,2016-03-30,2016-01-17
-4hmx,2013-08-07,2012-10-18
-3hml,2010-05-12,2009-05-29
-5hmh,2016-04-06,2016-01-16
-4hm3,2013-10-30,2012-10-17
-2hmv,2006-09-26,2006-07-11
-3hm3,2009-08-25,2009-05-28
-3hmm,2009-06-23,2009-05-29
-3hm7,2009-06-09,2009-05-28
-5hmx,2016-03-30,2016-01-17
-4hmq,2013-09-04,2012-10-18
-6hmq,2019-03-27,2018-09-12
-6hmj,2019-08-28,2018-09-12
-6hmm,2018-11-14,2018-09-12
-4hm0,2013-10-30,2012-10-17
-4hmz,2012-11-21,2012-10-18
-4hmv,2013-08-07,2012-10-18
-4hmg,1991-01-15,1989-09-11
-6hmr,2019-09-11,2018-09-12
-2hmk,2006-10-10,2006-07-11
-3hmo,2010-02-02,2009-05-29
-8hmu,2023-01-11,2022-12-05
-6hm5,2018-10-17,2018-09-12
-8hmd,2023-06-14,2022-12-03
-6hm7,2018-10-10,2018-09-12
-5hmn,2016-02-17,2016-01-16
-8hmh,2023-12-27,2022-12-03
-3hmy,2009-07-14,2009-05-29
-3hmn,2010-02-02,2009-05-29
-2hm1,2007-01-23,2006-07-10
-2hmj,2006-10-10,2006-07-11
-4hm7,2013-10-30,2012-10-17
-3hmj,2009-09-01,2009-05-29
-8hme,2023-06-14,2022-12-03
-6hmp,2019-09-11,2018-09-12
-2hmo,2006-10-10,2006-07-11
-8hmo,2023-12-06,2022-12-05
-5hmq,2016-10-19,2016-01-16
-4hme,2013-05-01,2012-10-18
-1hm9,2001-11-30,2000-12-05
-1hmp,1995-06-03,1994-06-03
-6hmz,2018-11-21,2018-09-13
-5hma,2016-02-10,2016-01-15
-4hm5,2013-10-30,2012-10-17
-5hmy,2016-03-30,2016-01-17
-2hmm,2006-10-10,2006-07-11
-2hmg,1991-01-15,1989-09-11
-5hmf,2016-11-02,2016-01-16
-8hmp,2023-06-21,2022-12-05
-1hmy,1993-10-31,1993-08-05
-2hmw,2006-09-26,2006-07-11
-3hmz,2009-06-30,2009-05-29
-4hmt,2013-08-07,2012-10-18
-5hmk,2016-04-06,2016-01-16
-1hml,1995-01-26,1994-09-29
-8hmq,2023-01-11,2022-12-05
-5hme,2016-11-02,2016-01-16
-2hmy,1999-03-19,1999-02-08
-5hmi,2016-04-06,2016-01-16
-3hm8,2009-08-11,2009-05-28
-4hmn,2013-11-13,2012-10-18
-2hmp,2006-09-19,2006-07-11
-4hmb,2012-11-07,2012-10-18
-6hmc,2019-03-27,2018-09-12
-6hmt,2019-02-27,2018-09-12
-4hmc,2013-05-01,2012-10-18
-3hmv,2010-06-09,2009-05-29
-5hms,2016-01-27,2016-01-17
-2hmu,2006-09-26,2006-07-11
-3hmx,2010-06-09,2009-05-29
-3hmp,2010-02-02,2009-05-29
-5hmg,1991-01-15,1989-09-11
-4hm6,2013-10-30,2012-10-17
-4hm1,2013-10-30,2012-10-17
-2hml,2006-10-10,2006-07-11
-6hmy,2019-08-14,2018-09-13
-1hm3,2001-05-02,2000-12-04
-6hm6,2018-10-10,2018-09-12
-3hm2,2009-07-07,2009-05-28
-4hmj,2012-10-31,2012-10-18
-8hmc,2023-06-14,2022-12-03
-8hm9,2024-01-31,2022-12-02
-6hmh,2018-09-26,2018-09-12
-3hmi,2009-07-07,2009-05-29
-3hm1,2010-06-02,2009-05-28
-8hmx,2023-12-13,2022-12-06
-1hmv,1995-03-31,1994-12-15
-5hmz,2016-03-30,2016-01-17
-4hms,2013-08-07,2012-10-18
-4hmw,2013-08-07,2012-10-18
-3hm5,2009-06-16,2009-05-28
-1g63,2001-05-03,2000-11-03
-1g60,2002-05-01,2000-11-02
-8g6p,2023-04-05,2023-02-15
-5g6v,2016-11-23,2016-08-16
-6g6w,2018-11-07,2018-04-03
-4g61,2013-07-24,2012-07-18
-6g6x,2019-04-10,2018-04-03
-5g66,2016-09-21,2016-06-18
-2g6e,2006-04-18,2006-02-24
-3g64,2009-03-03,2009-02-06
-5g6h,2016-09-21,2016-06-18
-1g6r,2000-11-15,2000-11-07
-2g6b,2006-03-14,2006-02-24
-5g6j,2016-09-21,2016-06-18
-6g60,2019-04-10,2018-03-30
-2g6w,2006-04-25,2006-02-26
-1g6s,2001-02-07,2000-11-07
-5g6i,2016-09-21,2016-06-18
-4g68,2012-08-22,2012-07-18
-1g67,2001-09-26,2000-11-03
-5g6l,2016-09-21,2016-06-18
-5g6s,2017-05-31,2016-06-23
-3g61,2009-03-24,2009-02-05
-2g6j,2006-08-08,2006-02-24
-4g6w,2013-07-24,2012-07-19
-8g6d,2024-01-10,2023-02-15
-1g6i,2003-06-24,2000-11-06
-1g6o,2001-01-24,2000-11-07
-1g6c,2001-09-26,2000-11-03
-4g69,2012-12-12,2012-07-18
-1g6k,2003-08-12,2000-11-06
-6g6v,2019-04-10,2018-04-03
-8g6a,2023-04-26,2023-02-14
-2g6k,2006-08-08,2006-02-24
-5g6m,2016-09-21,2016-06-18
-4g6o,2012-09-19,2012-07-19
-5g6q,2016-09-21,2016-06-18
-3g6x,2009-05-12,2009-02-09
-5g60,2017-01-18,2016-06-10
-6g63,2018-10-03,2018-03-31
-1g64,2000-12-20,2000-11-03
-6g6r,2019-04-10,2018-04-02
-5g69,2016-09-21,2016-06-18
-3g6y,2009-05-12,2009-02-09
-8g62,2023-02-22,2023-02-14
-2g6q,2006-07-11,2006-02-24
-2g6i,2006-08-08,2006-02-24
-4g6z,2012-08-01,2012-07-19
-2g6o,2006-08-08,2006-02-24
-6g6z,2018-08-08,2018-04-04
-2g6p,2006-06-20,2006-02-24
-8g6i,2023-05-24,2023-02-15
-3g60,2009-03-24,2009-02-05
-5g67,2016-09-21,2016-06-18
-8g60,2023-04-19,2023-02-14
-3g6n,2009-03-03,2009-02-07
-8g64,2023-08-09,2023-02-14
-3g6o,2009-09-22,2009-02-07
-8g63,2023-10-11,2023-02-14
-8g6r,2023-03-29,2023-02-15
-8g6u,2023-11-08,2023-02-16
-3g6g,2009-03-24,2009-02-06
-2g6n,2006-08-08,2006-02-24
-3g6h,2009-03-24,2009-02-06
-8g67,2023-04-26,2023-02-14
-5g6d,2016-09-21,2016-06-18
-3g6q,2009-04-21,2009-02-08
-1g6n,2000-12-15,2000-11-07
-4g67,2012-08-01,2012-07-18
-2g6h,2006-08-08,2006-02-24
-8g6c,2024-02-21,2023-02-14
-8g68,2023-04-26,2023-02-14
-2g6d,2006-04-04,2006-02-24
-2g6l,2006-08-08,2006-02-24
-5g6t,2017-05-17,2016-07-15
-8g6t,2024-02-21,2023-02-15
-8g6z,2023-06-21,2023-02-16
-3g6p,2009-04-21,2009-02-07
-5g6b,2016-09-21,2016-06-18
-6g6t,2019-03-13,2018-04-03
-8g66,2023-12-13,2023-02-14
-5g64,2017-05-03,2016-06-14
-3g6z,2009-06-30,2009-02-09
-8g6y,2023-04-05,2023-02-16
-5g6a,2016-09-21,2016-06-18
-1g6h,2001-07-18,2000-11-06
-5g61,2017-01-18,2016-06-10
-3g6t,2009-04-21,2009-02-08
-8g6e,2023-12-20,2023-02-15
-5g62,2017-01-18,2016-06-10
-3g6k,2009-05-26,2009-02-06
-3g6e,2009-04-28,2009-02-06
-4g6i,2014-03-12,2012-07-19
-5g6r,2017-05-31,2016-06-23
-5g6c,2016-09-21,2016-06-18
-5g6f,2016-09-21,2016-06-18
-2g6m,2006-08-08,2006-02-24
-8g61,2023-04-19,2023-02-14
-8g6f,2023-12-20,2023-02-15
-3g6v,2009-05-12,2009-02-09
-5g6g,2016-09-21,2016-06-18
-8g69,2023-04-26,2023-02-14
-4g6g,2012-10-24,2012-07-19
-6g6y,2018-08-08,2018-04-03
-5g68,2016-09-21,2016-06-18
-4g6h,2012-10-24,2012-07-19
-8g65,2023-04-26,2023-02-14
-1g6t,2001-02-07,2000-11-07
-8g6x,2023-03-22,2023-02-16
-1g6g,2000-12-13,2000-11-06
-2g63,2006-07-04,2006-02-24
-1g69,2001-09-26,2000-11-03
-5g6e,2016-09-21,2016-06-18
-8g6w,2023-04-05,2023-02-16
-2g64,2006-03-14,2006-02-24
-5g6u,2018-02-21,2016-07-21
-3g6r,2009-04-21,2009-02-08
-5g6p,2016-09-21,2016-06-18
-5g6k,2016-09-21,2016-06-18
-5g65,2016-09-21,2016-06-18
-5g6n,2016-09-21,2016-06-18
-1g6v,2000-11-22,2000-11-08
-3g6m,2010-02-16,2009-02-06
-4g6n,2012-09-19,2012-07-19
-1g65,2000-11-27,2000-11-03
-8g6j,2023-04-19,2023-02-15
-3g6w,2009-09-01,2009-02-09
-3g6u,2009-04-21,2009-02-08
-4g6u,2012-12-12,2012-07-19
-5g6o,2016-09-21,2016-06-18
-3g6j,2009-03-10,2009-02-06
-4gza,2012-10-17,2012-09-06
-2gzw,2007-05-15,2006-05-12
-1gz4,2002-07-25,2002-05-15
-5gz3,2017-04-12,2016-09-26
-5gz9,2017-03-29,2016-09-27
-5gz7,2016-10-26,2016-09-26
-4gz2,2012-10-31,2012-09-05
-4gzf,2013-10-30,2012-09-06
-4gzn,2012-10-17,2012-09-06
-2gze,2008-03-18,2006-05-11
-8gz5,2022-12-07,2022-09-25
-6gze,2020-01-22,2018-07-04
-5gza,2016-12-07,2016-09-27
-6gzw,2019-05-22,2018-07-05
-3gz4,2009-04-14,2009-04-06
-8gzc,2023-01-11,2022-09-26
-8gzg,2023-04-19,2022-09-27
-4gz6,2012-10-31,2012-09-06
-4gz1,2012-10-31,2012-09-05
-1gz9,2002-06-21,2002-05-17
-3gzk,2009-10-13,2009-04-07
-1gz8,2003-06-12,2002-05-17
-5gzc,2016-12-21,2016-09-28
-4gzt,2012-10-17,2012-09-06
-8gz9,2023-09-20,2022-09-26
-1gzr,2002-07-25,2002-05-28
-1gz5,2003-02-07,2002-05-15
-4gzo,2012-10-17,2012-09-06
-5gzt,2016-12-28,2016-10-01
-1gzf,2002-08-29,2002-05-21
-6gzy,2019-01-30,2018-07-05
-2gzs,2006-09-05,2006-05-12
-5gzv,2016-12-28,2016-10-01
-4gzl,2012-12-12,2012-09-06
-3gz6,2009-06-09,2009-04-06
-2gzx,2006-07-11,2006-05-12
-2gz1,2006-08-15,2006-05-10
-8gzb,2023-09-27,2022-09-26
-2gz5,2006-05-23,2006-05-10
-5gzl,2018-01-17,2016-09-29
-3gz5,2009-06-09,2009-04-06
-2gzm,2007-05-29,2006-05-11
-4gzz,2013-02-13,2012-09-06
-2gz7,2006-08-29,2006-05-11
-2gz3,2006-08-15,2006-05-10
-8gzr,2023-08-02,2022-09-27
-5gzh,2017-03-15,2016-09-28
-6gz3,2018-12-05,2018-07-03
-3gz0,2009-07-21,2009-04-06
-6gza,2018-12-05,2018-07-03
-1gzw,2004-01-08,2002-06-07
-8gz0,2022-11-09,2022-09-24
-8gzy,2023-07-19,2022-09-27
-1gzy,2002-07-25,2002-06-10
-5gzm,2018-01-17,2016-09-29
-3gz3,2010-04-28,2009-04-06
-4gz8,2012-10-17,2012-09-06
-8gzv,2023-07-19,2022-09-27
-4gz7,2013-09-11,2012-09-06
-4gzk,2013-07-24,2012-09-06
-8gzp,2023-08-02,2022-09-27
-7gz7,2024-05-15,2024-01-23
-1gzt,2002-11-19,2002-06-06
-4gzs,2012-10-17,2012-09-06
-1gzg,2002-06-27,2002-05-21
-3gzj,2009-08-18,2009-04-07
-4gz5,2012-10-31,2012-09-06
-4gzq,2012-10-17,2012-09-06
-4gzv,2012-11-07,2012-09-06
-2gzi,2008-03-18,2006-05-11
-5gzz,2017-02-15,2016-10-02
-6gzu,2018-11-14,2018-07-05
-4gzx,2012-10-17,2012-09-06
-6gz5,2018-12-05,2018-07-03
-1gz6,2003-01-24,2002-05-16
-8gzq,2023-08-02,2022-09-27
-3gzl,2009-04-21,2009-04-07
-6gzt,2018-11-14,2018-07-05
-5gzk,2017-03-15,2016-09-28
-8gz3,2022-12-21,2022-09-24
-4gzg,2013-09-11,2012-09-06
-2gzg,2008-03-18,2006-05-11
-5gzi,2018-01-17,2016-09-28
-5gz6,2017-04-12,2016-09-26
-1gza,1997-03-12,1996-11-13
-4gzy,2013-02-13,2012-09-06
-6gzv,2019-06-05,2018-07-05
-3gza,2009-04-21,2009-04-06
-3gzu,2009-07-14,2009-04-07
-5gzf,2016-12-21,2016-09-28
-1gzb,1997-03-12,1996-11-13
-4gzw,2012-10-17,2012-09-06
-1gz3,2003-05-22,2002-05-14
-4gz3,2012-10-31,2012-09-05
-3gzo,2009-10-13,2009-04-07
-8gzw,2023-07-19,2022-09-27
-3gzc,2009-04-28,2009-04-07
-3gzx,2010-05-05,2009-04-08
-4gzm,2012-12-12,2012-09-06
-3gzt,2009-07-14,2009-04-07
-3gzd,2009-04-28,2009-04-07
-6gz9,2018-12-26,2018-07-03
-3gzh,2009-08-25,2009-04-07
-2gzd,2006-08-15,2006-05-11
-5gzw,2017-10-11,2016-10-02
-1gze,2002-08-29,2002-05-21
-5gz4,2017-09-27,2016-09-26
-2gzl,2006-11-14,2006-05-11
-1gz7,2003-06-12,2002-05-17
-5gzj,2018-01-17,2016-09-28
-4gz0,2012-10-31,2012-09-05
-3gz8,2009-06-09,2009-04-06
-1gz1,2003-02-12,2002-05-13
-8gzx,2023-07-19,2022-09-27
-5gzs,2017-08-16,2016-10-01
-5gzp,2017-10-04,2016-09-30
-6gz4,2018-12-05,2018-07-03
-6gzh,2018-08-29,2018-07-04
-5gze,2016-12-21,2016-09-28
-2gzj,2008-03-18,2006-05-11
-6gzo,2019-07-17,2018-07-04
-2gzf,2007-07-03,2006-05-11
-5gzg,2016-12-21,2016-09-28
-2gz8,2006-08-29,2006-05-11
-1gzl,2002-10-10,2002-05-23
-4gzj,2013-01-02,2012-09-06
-4gzi,2013-01-02,2012-09-06
-3gz9,2009-06-30,2009-04-06
-8gzh,2023-04-19,2022-09-27
-2gzh,2006-08-15,2006-05-11
-5gzd,2016-12-21,2016-09-28
-3gze,2009-06-23,2009-04-07
-8gz1,2023-03-08,2022-09-24
-1gzu,2002-07-05,2002-06-06
-8gz8,2023-09-20,2022-09-26
-8gzu,2023-06-14,2022-09-27
-3gzm,2009-04-21,2009-04-07
-6gz8,2018-10-10,2018-07-03
-8gzf,2023-05-31,2022-09-26
-6gzm,2018-08-29,2018-07-04
-1gzc,2002-06-21,2002-05-17
-5gz2,2017-09-27,2016-09-26
-1gzv,2002-10-31,2002-06-06
-8gze,2023-05-31,2022-09-26
-4gzp,2012-10-17,2012-09-06
-6gzd,2018-08-29,2018-07-03
-8gzi,2023-09-27,2022-09-27
-1gzh,2002-06-27,2002-05-22
-5gzx,2017-10-04,2016-10-02
-1gzm,2003-11-20,2002-05-24
-4gz9,2012-10-17,2012-09-06
-3gzy,2010-05-05,2009-04-08
-1gzx,2002-07-08,2002-06-07
-5gz5,2017-09-27,2016-09-26
-2gz2,2006-08-15,2006-05-10
-3gzn,2010-02-02,2009-04-07
-1gzz,2002-07-25,2002-06-10
-8gz2,2023-03-08,2022-09-24
-6jh8,2020-02-19,2019-02-17
-4jhq,2013-11-20,2013-03-05
-6jh5,2019-04-03,2019-02-17
-2jh9,2007-04-10,2007-02-21
-6jha,2019-11-27,2019-02-17
-8jh0,2023-11-01,2023-05-22
-5jhr,2016-08-03,2016-04-21
-4jhz,2013-08-28,2013-03-05
-1jhy,2001-10-18,2001-06-28
-2jh7,2007-05-22,2007-02-20
-7jhg,2021-07-21,2020-07-20
-6jhi,2019-03-06,2019-02-18
-2jh6,2007-05-08,2007-02-20
-7jhi,2020-11-18,2020-07-20
-4jh0,2013-09-04,2013-03-04
-1jh9,2002-02-08,2001-06-27
-5jhy,2016-06-22,2016-04-21
-8jhy,2023-09-06,2023-05-25
-8jhr,2024-01-10,2023-05-25
-7jhl,2020-11-18,2020-07-20
-1jhv,2001-10-18,2001-06-28
-1jha,2001-09-26,2001-06-27
-1jhw,2002-06-28,2001-06-28
-6jhb,2019-11-27,2019-02-17
-2jhn,2007-04-10,2007-02-22
-8jhn,2024-03-06,2023-05-24
-8jh5,2024-05-29,2023-05-22
-7jh7,2020-10-28,2020-07-20
-6jhg,2019-03-06,2019-02-18
-7jhz,2021-07-28,2020-07-21
-2jhh,2007-10-09,2007-02-22
-8jh3,2023-11-29,2023-05-22
-2jhg,2007-04-24,2007-02-22
-6jhc,2020-02-19,2019-02-18
-1jh1,2001-12-27,2001-06-27
-8jh2,2023-11-29,2023-05-22
-2jha,2007-04-10,2007-02-21
-8jh9,2024-04-17,2023-05-22
-7jh6,2020-12-09,2020-07-20
-8jh6,2024-05-29,2023-05-22
-8jhe,2023-10-04,2023-05-23
-8jh4,2023-11-29,2023-05-22
-2jhc,2007-04-10,2007-02-21
-4jhd,2013-06-19,2013-03-04
-7jhj,2021-07-07,2020-07-20
-5jhs,2016-08-03,2016-04-21
-5jh2,2016-11-09,2016-04-20
-5jhn,2016-07-06,2016-04-21
-1jhm,2001-10-18,2001-06-28
-5jhz,2016-06-22,2016-04-21
-7jhw,2021-07-28,2020-07-21
-6jhu,2020-04-08,2019-02-19
-2jhr,2009-01-13,2008-03-25
-8jhl,2024-01-31,2023-05-23
-7jhh,2021-07-21,2020-07-20
-6jhy,2019-07-24,2019-02-19
-6jhz,2020-03-25,2019-02-19
-5jh7,2016-06-29,2016-04-20
-7jhp,2020-08-05,2020-07-21
-4jh3,2013-10-02,2013-03-04
-5jhq,2016-09-21,2016-04-21
-6jh9,2020-02-19,2019-02-17
-2jho,2007-04-03,2007-02-23
-4jhv,2014-04-23,2013-03-05
-8jhv,2024-05-29,2023-05-25
-1jhz,2002-02-08,2001-06-28
-8jh1,2023-12-13,2023-05-22
-1jhu,2001-10-18,2001-06-28
-1jho,2001-10-18,2001-06-28
-5jhp,2017-07-05,2016-04-21
-6jhx,2020-02-19,2019-02-19
-4jh7,2013-10-02,2013-03-04
-6jhf,2019-03-06,2019-02-18
-5jh9,2016-06-29,2016-04-20
-8jhf,2023-11-15,2023-05-23
-1jht,2001-09-14,2001-06-28
-1jhp,2001-10-18,2001-06-28
-5jha,2017-03-15,2016-04-20
-1jhq,2001-10-18,2001-06-28
-4jh9,2013-10-02,2013-03-04
-5jhd,2017-03-01,2016-04-20
-2jh0,2007-05-08,2007-02-19
-5jht,2016-05-11,2016-04-21
-4jh1,2013-10-02,2013-03-04
-4jh8,2013-10-02,2013-03-04
-1jhn,2001-10-10,2001-06-28
-7jh4,2020-09-16,2020-07-20
-2jhp,2007-04-10,2007-02-23
-2jhf,2007-04-24,2007-02-22
-7jhx,2021-03-17,2020-07-21
-4jh4,2013-10-02,2013-03-04
-8jho,2023-09-27,2023-05-25
-2jhj,2007-04-10,2007-02-22
-1jh0,2001-09-05,2001-06-27
-5jhb,2017-03-15,2016-04-20
-4jhu,2014-04-23,2013-03-05
-2jhl,2007-10-09,2007-02-22
-2jhm,2007-10-09,2007-02-22
-1jhj,2001-10-24,2001-06-28
-5jh6,2017-02-15,2016-04-20
-7jhk,2020-11-18,2020-07-20
-8jh8,2024-04-17,2023-05-22
-7jhq,2021-12-01,2020-07-21
-1jhr,2001-10-18,2001-06-28
-2jh8,2007-04-10,2007-02-21
-4jhi,2013-12-04,2013-03-05
-4jhh,2013-12-04,2013-03-05
-2jhk,2007-10-09,2007-02-22
-1jh8,2001-09-26,2001-06-27
-5jhk,2017-05-24,2016-04-21
-1jh7,2002-02-06,2001-06-27
-7jhe,2020-08-26,2020-07-20
-8jhw,2024-05-29,2023-05-25
-4jh5,2013-10-02,2013-03-04
-4jhx,2013-03-20,2013-03-05
-4jhg,2013-03-20,2013-03-05
-8jhz,2024-03-20,2023-05-25
-5jhu,2016-05-25,2016-04-21
-5jh8,2016-05-25,2016-04-20
-7jhn,2020-11-18,2020-07-21
-2jh5,2007-05-08,2007-02-20
-4jh6,2013-10-02,2013-03-04
-2jht,2007-05-08,2007-02-23
-6jhj,2019-04-03,2019-02-18
-5jhv,2016-05-11,2016-04-21
-2jhi,2007-10-09,2007-02-22
-5jhf,2016-08-03,2016-04-21
-7jh2,2020-08-12,2020-07-20
-6jhn,2019-12-11,2019-02-18
-7jho,2020-11-18,2020-07-21
-1jhg,1997-03-12,1996-07-19
-5jhx,2016-06-22,2016-04-21
-4jh2,2013-10-02,2013-03-04
-7jhd,2020-11-25,2020-07-20
-6jh6,2019-12-11,2019-02-17
-5jhh,2017-04-26,2016-04-21
-4jht,2013-06-26,2013-03-05
-7jhm,2020-11-18,2020-07-20
-6jhh,2019-03-06,2019-02-18
-8jhg,2023-11-22,2023-05-23
-2jhd,2007-05-22,2007-02-21
-6ra0,2019-08-14,2019-04-05
-2raq,2007-10-16,2007-09-17
-4ra7,2014-09-24,2014-09-09
-7raj,2021-12-15,2021-07-01
-3rae,2012-04-25,2011-03-28
-5raa,2020-04-22,2020-03-16
-1ra7,2004-08-17,2003-10-31
-3rav,2011-05-11,2011-03-28
-1ra5,2004-10-05,2003-10-31
-1rab,1994-01-31,1992-08-14
-5rak,2020-04-22,2020-03-16
-3ra0,2011-09-28,2011-03-26
-8ra6,2024-01-31,2023-12-01
-5ra0,2020-07-22,2020-03-04
-1raq,1993-10-31,1992-08-25
-2ray,2008-03-18,2007-09-17
-5rap,2020-04-22,2020-03-16
-7rai,2021-11-17,2021-07-01
-7rau,2021-09-08,2021-07-02
-7rak,2021-08-11,2021-07-01
-4rao,2015-01-07,2014-09-10
-4raw,2014-11-26,2014-09-11
-8rab,2024-01-31,2023-12-01
-3rax,2011-06-15,2011-03-28
-4raf,2015-08-26,2014-09-10
-3ras,2011-05-25,2011-03-28
-5raz,2020-04-22,2020-03-16
-2rav,2008-04-22,2007-09-17
-7ra5,2021-11-03,2021-06-30
-5ral,2020-04-22,2020-03-16
-4rac,2015-01-07,2014-09-10
-4rag,2015-08-26,2014-09-10
-1rah,1994-01-31,1992-08-14
-6ra9,2020-06-03,2019-04-05
-6ra6,2020-03-11,2019-04-05
-2rap,1998-06-17,1998-05-06
-4ra3,2015-09-09,2014-09-09
-6ray,2019-09-11,2019-04-08
-3ra9,2011-09-21,2011-03-27
-4ra5,2014-10-08,2014-09-09
-7ran,2022-07-06,2021-07-02
-5rav,2020-04-22,2020-03-16
-7rax,2023-07-05,2021-07-04
-2ra0,2008-01-29,2007-09-14
-6rak,2019-07-31,2019-04-06
-6raa,2019-04-24,2019-04-05
-8ra9,2024-01-31,2023-12-01
-4rak,2014-12-31,2014-09-10
-5rah,2020-04-22,2020-03-16
-2rar,2008-04-22,2007-09-17
-5ras,2020-04-22,2020-03-16
-5ra8,2020-07-22,2020-03-04
-6raj,2019-07-31,2019-04-06
-2rao,2008-09-09,2007-09-17
-6ra4,2019-05-08,2019-04-05
-4rai,2015-07-01,2014-09-10
-8ra2,2024-01-31,2023-12-01
-5ra1,2020-07-22,2020-03-04
-8ra5,2024-01-31,2023-12-01
-1rad,1994-01-31,1992-08-14
-5ra2,2020-07-22,2020-03-04
-8ra1,2024-01-31,2023-12-01
-5rao,2020-04-22,2020-03-16
-4rap,2014-10-29,2014-09-10
-2rax,2007-10-30,2007-09-17
-4rad,2015-01-07,2014-09-10
-2raz,2008-03-18,2007-09-17
-6rav,2019-04-17,2019-04-08
-3rai,2012-08-08,2011-03-28
-8ra7,2024-01-31,2023-12-01
-3ra4,2011-09-21,2011-03-27
-2raw,2007-10-30,2007-09-17
-7raf,2022-07-27,2021-07-01
-1rac,1994-01-31,1992-08-14
-5raf,2020-04-22,2020-03-16
-1rao,2004-11-09,2003-10-31
-8ra8,2024-01-31,2023-12-01
-5raw,2020-04-22,2020-03-16
-4ra0,2014-09-24,2014-09-09
-2ra3,2007-12-11,2007-09-14
-1raz,1993-10-31,1993-04-02
-7ral,2021-08-04,2021-07-01
-5ray,2020-04-22,2020-03-16
-7rab,2021-10-20,2021-06-30
-8ras,2024-03-06,2023-12-01
-5rag,2020-04-22,2020-03-16
-7rad,2022-06-08,2021-07-01
-6ra1,2019-11-27,2019-04-05
-5ra9,2020-07-22,2020-03-04
-4ral,2015-05-13,2014-09-10
-1ra0,2004-10-05,2003-10-31
-6ras,2019-07-10,2019-04-07
-8rae,2024-01-31,2023-12-01
-3ray,2011-04-20,2011-03-28
-1rae,1994-01-31,1992-08-14
-3rac,2011-09-14,2011-03-27
-3raf,2012-03-28,2011-03-28
-4ra1,2015-08-19,2014-09-09
-2rag,2007-10-02,2007-09-14
-3rar,2011-04-27,2011-03-28
-3raa,2011-09-21,2011-03-27
-3rah,2012-10-31,2011-03-28
-1ra9,1996-12-23,1996-10-28
-6raf,2019-07-31,2019-04-06
-7ra4,2021-08-04,2021-06-30
-4ras,2014-10-15,2014-09-11
-2rac,1998-10-07,1998-10-02
-4raq,2015-01-07,2014-09-10
-1rar,1993-10-31,1993-03-02
-3ra7,2011-07-20,2011-03-27
-6rag,2019-07-31,2019-04-06
-5ra5,2020-07-22,2020-03-04
-5ra3,2020-07-22,2020-03-04
-4ram,2014-09-24,2014-09-10
-6ra5,2020-05-06,2019-04-05
-8rac,2024-01-31,2023-12-01
-1ra8,1997-03-12,1996-11-21
-6rad,2019-08-21,2019-04-05
-1ras,1993-10-31,1993-03-02
-5ram,2020-04-22,2020-03-16
-3raq,2011-06-15,2011-03-28
-1rag,1994-01-31,1992-08-14
-6rax,2019-09-11,2019-04-08
-7rah,2021-09-15,2021-07-01
-8raf,2023-12-27,2023-12-01
-6ra7,2019-11-06,2019-04-05
-2ra9,2007-10-16,2007-09-14
-6ra8,2020-05-06,2019-04-05
-5rau,2020-04-22,2020-03-16
-3rap,1999-12-08,1999-05-31
-2ran,1994-11-30,1994-09-01
-2rah,2007-09-25,2007-09-15
-6rai,2019-07-31,2019-04-06
-3ral,2012-10-31,2011-03-28
-6raw,2019-09-11,2019-04-08
-7rav,2023-01-11,2021-07-02
-7rag,2021-09-08,2021-07-01
-4raz,2015-07-15,2014-09-12
-8ra3,2024-01-31,2023-12-01
-2rak,2007-12-11,2007-09-16
-1rak,2004-10-05,2003-10-31
-8rai,2023-12-27,2023-12-01
-4rab,2015-01-07,2014-09-10
-1ra1,1996-12-23,1996-10-30
-6rau,2019-07-10,2019-04-08
-1raa,1994-01-31,1992-08-14
-5ran,2020-04-22,2020-03-16
-8raa,2024-01-31,2023-12-01
-5ra7,2020-07-22,2020-03-04
-3ra3,2012-08-08,2011-03-27
-5ra6,2020-07-22,2020-03-04
-3rab,1999-04-16,1998-11-16
-3raw,2011-05-04,2011-03-28
-6raz,2019-09-18,2019-04-08
-4ra4,2014-10-08,2014-09-09
-5rac,2020-04-22,2020-03-16
-5ra4,2020-07-22,2020-03-04
-1raf,1994-01-31,1992-08-14
-3ram,2011-05-25,2011-03-28
-5rae,2020-04-22,2020-03-16
-6rah,2019-07-31,2019-04-06
-6ral,2019-07-31,2019-04-06
-1rap,1993-10-31,1992-08-25
-5rad,2020-04-22,2020-03-16
-3rag,2011-09-14,2011-03-28
-8rad,2024-01-31,2023-12-01
-5raj,2020-04-22,2020-03-16
-7rae,2022-07-27,2021-07-01
-2rau,2007-10-09,2007-09-17
-4ra2,2015-05-13,2014-09-09
-7raa,2022-03-16,2021-06-30
-1ray,1993-10-31,1993-04-02
-3ran,1998-12-02,1998-10-19
-6ram,2019-07-31,2019-04-06
-4ran,2015-01-07,2014-09-10
-7ras,2021-09-08,2021-07-02
-6rar,2019-07-10,2019-04-07
-5raq,2020-04-22,2020-03-16
-1rai,1994-01-31,1992-08-14
-5rai,2020-04-22,2020-03-16
-7ra8,2021-08-04,2021-06-30
-3rak,2012-10-31,2011-03-28
-1ra3,1996-12-23,1996-10-28
-3ra8,2011-09-21,2011-03-27
-5rar,2020-04-22,2020-03-16
-2rab,2008-02-19,2007-09-14
-2ra6,2007-11-20,2007-09-14
-6ra3,2019-07-03,2019-04-05
-7rac,2021-10-20,2021-06-30
-5rab,2020-04-22,2020-03-16
-1ra2,1996-12-23,1996-10-28
-8ra4,2024-01-31,2023-12-01
-5rax,2020-04-22,2020-03-16
-7ra0,2022-01-12,2021-06-29
-2raf,2007-10-02,2007-09-14
-3rad,2012-04-25,2011-03-28
-1hqa,1996-03-08,1995-11-30
-3hqf,2009-09-22,2009-06-06
-6hqk,2019-07-03,2018-09-25
-3hqd,2009-12-08,2009-06-05
-6hqs,2019-07-03,2018-09-25
-8hq9,2024-01-10,2022-12-13
-3hqz,2009-08-04,2009-06-08
-2hq9,2006-08-29,2006-07-18
-5hq1,2016-05-18,2016-01-21
-6hqi,2019-03-20,2018-09-25
-8hqq,2023-12-27,2022-12-14
-5hqm,2017-01-25,2016-01-21
-6hqu,2019-10-09,2018-09-25
-5hqc,2017-01-11,2016-01-21
-1hq5,2001-04-04,2000-12-14
-8hqj,2023-12-20,2022-12-13
-5hq8,2016-03-30,2016-01-21
-8hq7,2023-12-20,2022-12-13
-3hqh,2009-10-20,2009-06-06
-6hqd,2018-12-12,2018-09-24
-6hqm,2019-07-03,2018-09-25
-2hqy,2006-09-19,2006-07-19
-1hqy,2001-11-14,2000-12-20
-2hqz,2008-04-08,2006-07-19
-1hqr,2001-01-03,2000-12-19
-3hqr,2009-07-28,2009-06-08
-4hqj,2013-10-02,2012-10-25
-1hqp,2001-01-17,2000-12-19
-6hq5,2019-07-31,2018-09-24
-3hq9,2009-09-22,2009-06-05
-6hq8,2019-06-12,2018-09-24
-2hqk,2007-01-02,2006-07-18
-3hq2,2009-06-30,2009-06-05
-1hqm,2001-02-07,2000-12-18
-8hq8,2023-09-06,2022-12-13
-6hqy,2018-10-31,2018-09-25
-1hqw,2003-10-07,2000-12-20
-8hqx,2023-12-20,2022-12-14
-5hq0,2016-03-02,2016-01-21
-4hqn,2012-12-26,2012-10-25
-5hqa,2017-01-11,2016-01-21
-3hq4,2010-06-23,2009-06-05
-5hq4,2017-01-11,2016-01-21
-6hqx,2019-10-09,2018-09-25
-3hq6,2009-09-22,2009-06-05
-8hqg,2023-12-20,2022-12-13
-8hq2,2023-12-13,2022-12-13
-8hqn,2023-10-11,2022-12-13
-1hqf,2001-04-04,2000-12-16
-2hqu,2007-07-24,2006-07-19
-2hqp,2007-06-05,2006-07-19
-1hqj,2001-03-14,2000-12-18
-5hqx,2016-07-27,2016-01-22
-5hql,2017-01-25,2016-01-21
-1hql,2002-01-16,2000-12-18
-6hql,2019-07-03,2018-09-25
-4hqr,2013-09-11,2012-10-26
-8hqf,2024-01-31,2022-12-13
-2hq0,2007-07-31,2006-07-18
-6hqt,2019-07-03,2018-09-25
-6hqp,2019-07-03,2018-09-25
-8hqh,2023-12-20,2022-12-13
-3hqm,2009-10-20,2009-06-07
-3hqq,2010-02-16,2009-06-08
-6hqq,2019-07-03,2018-09-25
-5hqj,2016-03-02,2016-01-21
-8hq3,2023-10-25,2022-12-13
-1hqd,2001-08-22,2000-12-15
-6hqo,2019-07-03,2018-09-25
-2hq8,2006-09-12,2006-07-18
-4hqp,2013-07-17,2012-10-25
-2hqm,2007-06-12,2006-07-19
-1hqg,2001-04-04,2000-12-16
-8hqi,2023-12-20,2022-12-13
-4hqs,2013-12-25,2012-10-26
-4hqb,2013-09-04,2012-10-25
-6hqf,2019-10-09,2018-09-24
-5hqw,2017-01-25,2016-01-22
-1hqu,2001-05-30,2000-12-19
-5hqd,2016-02-10,2016-01-21
-6hqr,2019-07-03,2018-09-25
-3hqo,2010-02-16,2009-06-08
-6hq3,2019-07-31,2018-09-24
-4hql,2012-12-26,2012-10-25
-5hq6,2017-01-25,2016-01-21
-8hq1,2023-12-13,2022-12-13
-5hqb,2017-01-11,2016-01-21
-6hqh,2018-10-31,2018-09-25
-8hq5,2023-12-20,2022-12-13
-3hqy,2009-08-04,2009-06-08
-6hqv,2020-05-06,2018-09-25
-8hqt,2023-12-20,2022-12-14
-3hq8,2009-09-22,2009-06-05
-5hqo,2016-04-20,2016-01-21
-5hq5,2017-01-25,2016-01-21
-3hqt,2009-10-20,2009-06-08
-4hqv,2012-11-21,2012-10-26
-3hqn,2010-02-16,2009-06-08
-5hqy,2017-01-25,2016-01-22
-3hql,2009-10-20,2009-06-07
-6hqw,2018-12-12,2018-09-25
-5hqe,2016-07-27,2016-01-21
-4hqo,2012-12-26,2012-10-25
-8hqv,2023-12-20,2022-12-14
-1hqh,2001-04-04,2000-12-16
-6hqg,2018-12-12,2018-09-25
-1hqc,2001-02-21,2000-12-15
-5hq7,2017-01-25,2016-01-21
-3hqj,2009-09-15,2009-06-07
-3hq1,2010-05-19,2009-06-05
-2hqh,2007-08-21,2006-07-18
-3hqw,2009-08-04,2009-06-08
-3hqi,2009-10-20,2009-06-07
-1hq4,2003-06-03,2000-12-14
-2hqw,2007-11-13,2006-07-19
-3hqu,2009-07-28,2009-06-08
-1hq2,2003-04-15,2000-12-13
-1hqq,2003-09-16,2000-12-19
-4hqm,2013-03-06,2012-10-25
-8hqr,2023-12-27,2022-12-14
-3hq7,2009-09-22,2009-06-05
-6hq4,2019-07-31,2018-09-24
-5hqz,2017-01-25,2016-01-22
-8hq4,2023-12-20,2022-12-13
-6hq7,2019-07-31,2018-09-24
-4hq1,2013-05-29,2012-10-25
-6hqn,2019-07-03,2018-09-25
-5hqn,2016-07-06,2016-01-21
-3hqp,2010-02-16,2009-06-08
-3hq5,2010-03-02,2009-06-05
-1hqt,2001-05-16,2000-12-19
-1hqv,2001-05-02,2000-12-19
-3hq0,2009-10-20,2009-06-05
-8hq6,2023-10-25,2022-12-13
-6hqb,2019-01-16,2018-09-24
-1hqx,2001-06-06,2000-12-20
-2kx6,2011-06-15,2010-04-27
-4kxu,2013-08-21,2013-05-28
-3kxh,2010-11-17,2009-12-03
-2kxn,2011-03-16,2010-05-10
-7kxi,2021-12-15,2020-12-03
-7kxr,2021-07-14,2020-12-04
-4kxw,2013-08-21,2013-05-28
-5kxo,2016-09-07,2016-07-20
-3kxz,2010-06-23,2009-12-04
-7kxg,2021-12-08,2020-12-03
-6kx2,2020-08-19,2019-09-09
-5kxs,2016-09-07,2016-07-20
-7kx5,2020-12-16,2020-12-03
-1kxg,2002-03-20,2002-01-31
-6kxf,2020-05-06,2019-09-10
-7kx9,2021-07-14,2020-12-03
-6kxm,2020-09-16,2019-09-12
-3kxd,2010-04-21,2009-12-02
-7kxe,2021-01-20,2020-12-03
-5kxm,2016-09-07,2016-07-20
-7kxw,2021-09-22,2020-12-05
-3kx1,2010-03-02,2009-12-02
-1kx1,2002-07-05,2002-01-30
-3kxu,2010-02-09,2009-12-04
-3kxi,2010-05-26,2009-12-03
-5kxc,2016-09-14,2016-07-20
-5kxe,2016-09-14,2016-07-20
-1kx2,2002-02-13,2002-01-30
-7kxz,2022-01-19,2020-12-06
-6kxa,2020-08-26,2019-09-10
-3kx4,2010-05-19,2009-12-02
-4kxj,2014-05-28,2013-05-27
-4kxl,2014-02-05,2013-05-27
-5kx7,2016-08-17,2016-07-20
-7kxk,2021-02-03,2020-12-04
-5kxq,2017-05-17,2016-07-20
-7kxb,2021-02-17,2020-12-03
-7kxl,2021-05-19,2020-12-04
-1kx5,2002-12-25,2002-01-31
-5kxh,2017-05-17,2016-07-20
-4kxq,2013-10-23,2013-05-27
-7kxm,2021-05-19,2020-12-04
-5kxd,2016-09-14,2016-07-20
-4kxm,2014-02-05,2013-05-27
-4kx9,2013-07-31,2013-05-24
-7kxs,2021-12-08,2020-12-04
-3kxw,2010-03-16,2009-12-04
-4kxp,2013-07-24,2013-05-27
-7kx8,2021-09-22,2020-12-03
-4kxb,2013-07-31,2013-05-24
-3kxg,2010-11-17,2009-12-03
-1kxh,2002-06-19,2002-01-31
-7kxj,2021-02-03,2020-12-04
-6kxl,2020-09-16,2019-09-12
-7kx6,2021-09-22,2020-12-03
-5kxi,2016-09-28,2016-07-20
-5kxz,2016-09-07,2016-07-20
-5kxw,2016-09-07,2016-07-20
-1kxt,2002-06-19,2002-02-01
-6kxi,2020-02-19,2019-09-11
-7kxf,2021-01-20,2020-12-03
-1kx4,2002-12-25,2002-01-31
-3kx2,2010-01-26,2009-12-02
-4kx3,2013-06-05,2013-05-24
-6kxs,2020-02-05,2019-09-12
-5kxj,2016-08-03,2016-07-20
-5kxr,2016-09-07,2016-07-20
-3kxo,2010-09-01,2009-12-03
-6kxu,2020-09-16,2019-09-12
-6kx8,2020-04-01,2019-09-10
-7kxo,2021-05-19,2020-12-04
-6kxb,2020-08-26,2019-09-10
-6kx3,2020-08-19,2019-09-09
-6kxy,2020-05-20,2019-09-14
-6kxn,2020-09-16,2019-09-12
-4kxa,2013-07-31,2013-05-24
-5kx8,2016-08-17,2016-07-20
-4kxh,2013-10-02,2013-05-26
-4kxc,2013-07-31,2013-05-25
-4kxi,2014-05-28,2013-05-27
-6kx6,2020-04-01,2019-09-10
-1kxq,2002-06-19,2002-02-01
-6kxo,2020-02-19,2019-09-12
-5kxv,2017-06-07,2016-07-20
-6kx1,2020-07-29,2019-09-09
-4kxn,2014-02-05,2013-05-27
-7kxa,2020-12-16,2020-12-03
-2kxv,2010-12-22,2010-05-13
-6kxk,2020-09-16,2019-09-12
-4kxv,2013-08-21,2013-05-28
-5kxx,2016-09-07,2016-07-20
-7kx7,2021-07-14,2020-12-03
-4kxf,2013-07-24,2013-05-25
-5kxt,2016-09-07,2016-07-20
-3kxa,2010-01-19,2009-12-02
-1kxp,2002-06-19,2002-02-01
-5kxu,2017-06-07,2016-07-20
-5kx5,2016-12-28,2016-07-20
-3kx5,2010-05-19,2009-12-02
-5kxb,2016-09-14,2016-07-20
-1kxn,2002-03-06,2002-02-01
-4kx4,2014-05-28,2013-05-24
-7kxh,2021-12-08,2020-12-03
-4kx8,2013-07-31,2013-05-24
-6kx9,2020-04-01,2019-09-10
-1kxr,2002-03-20,2002-02-01
-7kxc,2021-12-15,2020-12-03
-4kx6,2013-07-17,2013-05-24
-6kxh,2020-09-16,2019-09-11
-1kx7,2002-02-13,2002-01-31
-6kxx,2020-05-20,2019-09-14
-5kxa,2016-11-09,2016-07-20
-1kx3,2002-12-25,2002-01-31
-6kx5,2020-04-01,2019-09-10
-5kxp,2016-09-07,2016-07-20
-4kxx,2013-08-21,2013-05-28
-7kx1,2021-12-08,2020-12-02
-7kxd,2021-01-20,2020-12-03
-3kxm,2010-11-17,2009-12-03
-5kxn,2016-09-07,2016-07-20
-1kxm,2002-03-06,2002-02-01
-3kxt,2010-06-09,2009-12-03
-4kxd,2013-07-31,2013-05-25
-4kx7,2013-07-31,2013-05-24
-5kxk,2016-09-07,2016-07-20
-5kx6,2016-09-28,2016-07-20
-5kxl,2016-09-07,2016-07-20
-1kx0,2002-07-05,2002-01-30
-5kxy,2016-09-07,2016-07-20
-7kxn,2021-05-19,2020-12-04
-4kxy,2013-08-21,2013-05-28
-6kx7,2020-04-01,2019-09-10
-7kxp,2021-05-19,2020-12-04
-3kxn,2010-11-17,2009-12-03
-7kx0,2021-09-08,2020-12-02
-7kxq,2021-05-19,2020-12-04
-3kx3,2010-05-19,2009-12-02
-4kx5,2013-06-12,2013-05-24
-7l8o,2021-12-01,2020-12-31
-1l8l,2003-04-01,2002-03-21
-5l86,2017-03-01,2016-06-07
-3l8v,2010-05-05,2010-01-04
-5l8o,2016-08-24,2016-06-08
-7l8v,2022-07-06,2021-01-01
-7l8c,2021-08-04,2020-12-31
-4l8e,2013-06-26,2013-06-17
-7l87,2021-08-04,2020-12-31
-5l8z,2016-06-22,2016-06-09
-7l8a,2021-08-04,2020-12-31
-7l8u,2021-08-04,2021-01-01
-5l8w,2016-09-28,2016-06-08
-1l8x,2002-11-20,2002-03-22
-7l86,2021-08-04,2020-12-31
-7l8e,2021-08-04,2020-12-31
-4l8z,2014-06-18,2013-06-18
-7l8h,2021-09-22,2020-12-31
-3l8z,2011-01-05,2010-01-04
-6l84,2020-07-08,2019-11-04
-3l8h,2010-02-02,2009-12-31
-5l8t,2016-10-26,2016-06-08
-7l8j,2021-09-22,2020-12-31
-1l8t,2002-06-19,2002-03-21
-1l8o,2003-04-01,2002-03-21
-1l8s,2002-12-25,2002-03-21
-6l8j,2020-06-10,2019-11-06
-6l8i,2020-06-10,2019-11-06
-4l8m,2013-10-30,2013-06-17
-7l82,2021-03-03,2020-12-30
-1l8n,2003-03-21,2002-03-21
-7l8t,2021-08-04,2020-12-31
-6l8o,2020-11-11,2019-11-06
-5l8r,2017-03-15,2016-06-08
-5l81,2017-01-11,2016-06-06
-5l8h,2016-09-28,2016-06-07
-3l8l,2010-07-28,2009-12-31
-5l8d,2017-03-29,2016-06-07
-3l8f,2010-02-02,2009-12-31
-4l80,2013-12-04,2013-06-15
-4l8p,2013-08-21,2013-06-17
-5l87,2017-03-08,2016-06-07
-7l8b,2021-08-04,2020-12-31
-7l8n,2022-01-19,2020-12-31
-4l8u,2013-07-24,2013-06-17
-7l89,2021-08-04,2020-12-31
-1l8d,2002-08-28,2002-03-20
-6l8k,2020-01-29,2019-11-06
-7l81,2021-03-03,2020-12-30
-3l8e,2010-02-02,2009-12-31
-6l8h,2020-06-10,2019-11-06
-4l8g,2013-11-27,2013-06-17
-5l83,2016-08-03,2016-06-06
-4l8h,2013-10-02,2013-06-17
-5l8u,2016-10-26,2016-06-08
-4l89,2013-07-10,2013-06-16
-3l8m,2010-02-09,2009-12-31
-5l8l,2016-07-20,2016-06-08
-3l8y,2011-01-05,2010-01-04
-7l8z,2021-08-04,2021-01-01
-1l8j,2002-06-26,2002-03-20
-3l8p,2010-10-06,2010-01-03
-6l8z,2020-04-01,2019-11-07
-5l8m,2016-10-26,2016-06-08
-4l8n,2013-06-26,2013-06-17
-5l89,2016-08-31,2016-06-07
-2l8e,2011-12-21,2011-01-11
-6l8n,2020-11-11,2019-11-06
-6l89,2020-09-16,2019-11-05
-4l8w,2014-05-14,2013-06-18
-3l89,2010-04-14,2009-12-30
-3l81,2010-06-02,2009-12-29
-3l85,2011-01-12,2009-12-29
-7l8w,2021-08-04,2021-01-01
-5l8p,2016-12-21,2016-06-08
-5l88,2016-08-03,2016-06-07
-7l8p,2022-06-15,2020-12-31
-2l8r,2011-02-23,2011-01-22
-3l8w,2010-06-02,2010-01-04
-1l8q,2002-09-25,2002-03-21
-7l8y,2021-08-04,2021-01-01
-5l8b,2016-08-31,2016-06-07
-5l8f,2017-06-21,2016-06-07
-7l8x,2021-08-04,2021-01-01
-5l8n,2016-08-24,2016-06-08
-7l8i,2021-09-22,2020-12-31
-4l82,2013-06-26,2013-06-15
-3l8q,2010-05-05,2010-01-03
-4l8f,2014-05-14,2013-06-17
-1l8c,2002-04-10,2002-03-19
-5l8g,2016-08-31,2016-06-07
-6l8u,2019-12-25,2019-11-07
-6l8l,2020-11-11,2019-11-06
-5l8c,2018-03-14,2016-06-07
-2l84,2011-01-19,2011-01-03
-3l88,2010-04-14,2009-12-30
-4l8v,2013-09-04,2013-06-18
-4l8o,2013-08-21,2013-06-17
-3l87,2011-01-05,2009-12-30
-2l85,2011-01-19,2011-01-04
-5l8y,2018-03-14,2016-06-08
-3l8x,2010-03-02,2010-01-04
-5l8a,2017-03-08,2016-06-07
-2l8m,2011-02-16,2011-01-19
-7l88,2021-08-04,2020-12-31
-3l8d,2010-01-12,2009-12-30
-1l8a,2002-07-24,2002-03-19
-4l8b,2013-10-16,2013-06-16
-3l8g,2010-02-02,2009-12-31
-6l85,2020-09-16,2019-11-04
-5l8j,2016-07-20,2016-06-08
-6l8a,2020-11-11,2019-11-05
-1l8i,2003-06-24,2002-03-20
-6l86,2020-03-04,2019-11-05
-1l8b,2002-06-12,2002-03-19
-3l86,2011-01-05,2009-12-30
-7l8s,2021-08-04,2020-12-31
-4l8a,2013-07-10,2013-06-16
-3l8s,2010-03-09,2010-01-03
-6l8s,2020-05-27,2019-11-07
-1l8p,2002-04-03,2002-03-21
-1l8h,2003-06-24,2002-03-20
-2l80,2011-12-14,2010-12-28
-3l8a,2011-01-12,2009-12-30
-4l87,2013-10-02,2013-06-16
-4l8q,2014-05-21,2013-06-17
-5l8q,2017-03-29,2016-06-08
-5l8k,2016-07-20,2016-06-08
-4l8d,2013-10-16,2013-06-16
-6l88,2020-02-12,2019-11-05
-3l8k,2010-02-09,2009-12-31
-7l8d,2021-08-04,2020-12-31
-7l8g,2021-08-04,2020-12-31
-4l8c,2013-10-16,2013-06-16
-7l8f,2021-08-04,2020-12-31
-6l8q,2019-12-04,2019-11-07
-1l8g,2002-05-08,2002-03-20
-3qq7,2011-06-22,2011-02-15
-7qqh,2022-08-31,2022-01-07
-5qqz,2019-08-07,2019-05-22
-5qqd,2019-12-18,2019-05-03
-2qqs,2007-12-11,2007-07-26
-8qqy,2023-11-22,2023-10-06
-7qqb,2023-06-21,2022-01-07
-5qqv,2019-08-07,2019-05-22
-6qqn,2019-07-24,2019-02-18
-5qq4,2020-04-29,2019-04-04
-5qq6,2020-04-29,2019-03-12
-7qqf,2022-08-31,2022-01-07
-3qqj,2012-08-08,2011-02-15
-1qqt,2000-01-01,1999-06-08
-2qqh,2007-09-25,2007-07-26
-2qq9,2007-10-30,2007-07-26
-6qq6,2019-09-11,2019-02-17
-3qqh,2012-08-08,2011-02-15
-4qq6,2014-08-06,2014-06-26
-5qqg,2019-12-18,2019-05-03
-5qqn,2019-12-18,2019-05-03
-2qqa,2007-10-30,2007-07-26
-5qqc,2020-04-29,2019-03-14
-4qqp,2015-04-15,2014-06-27
-1qq0,1999-06-24,1999-06-10
-5qq9,2020-04-29,2019-03-12
-7qqq,2022-10-26,2022-01-10
-7qql,2022-04-20,2022-01-10
-5qqi,2019-12-18,2019-05-03
-4qqs,2015-03-11,2014-06-29
-2qqu,2008-04-22,2007-07-27
-1qqd,1999-12-08,1999-06-03
-4qq7,2014-07-16,2014-06-26
-4qq1,2015-04-01,2014-06-26
-3qqs,2012-08-22,2011-02-16
-4qqw,2014-08-27,2014-06-30
-4qqf,2015-07-01,2014-06-27
-2qqd,2008-03-18,2007-07-26
-1qqc,1999-10-14,1999-06-02
-1qqu,2000-06-14,1999-06-09
-3qq3,2011-12-28,2011-02-15
-3qqc,2011-03-23,2011-02-15
-3qqp,2012-02-22,2011-02-16
-4qq8,2015-03-11,2014-06-26
-2qqb,2007-10-30,2007-07-26
-6qq3,2019-03-06,2019-02-17
-8qqk,2024-04-24,2023-10-05
-3qqi,2011-03-09,2011-02-15
-3qqa,2011-03-16,2011-02-15
-4qqv,2014-09-03,2014-06-30
-6qq5,2019-09-11,2019-02-17
-2qqv,2008-04-22,2007-07-27
-1qqj,2000-06-07,1999-06-07
-3qqx,2012-02-29,2011-02-16
-3qq4,2011-12-28,2011-02-15
-6qq2,2019-11-06,2019-02-16
-5qqm,2019-12-18,2019-05-03
-6qqt,2019-09-18,2019-02-19
-8qqo,2023-10-18,2023-10-05
-6qqx,2020-03-18,2019-02-19
-5qq1,2020-04-29,2019-03-12
-5qqp,2019-09-18,2019-05-20
-4qqq,2015-07-22,2014-06-27
-7qqx,2022-10-26,2022-01-10
-5qqy,2019-08-07,2019-05-22
-5qq3,2020-04-29,2019-03-12
-3qqv,2011-03-02,2011-02-16
-1qqw,1999-06-14,1999-06-09
-8qq3,2024-02-07,2023-10-03
-7qq1,2022-03-02,2022-01-05
-7qqs,2022-10-26,2022-01-10
-1qqs,2000-04-21,1999-06-07
-3qqy,2011-07-20,2011-02-16
-8qqc,2023-11-08,2023-10-04
-4qqh,2015-04-15,2014-06-27
-7qqt,2022-10-26,2022-01-10
-4qqx,2014-08-20,2014-06-30
-2qqw,2008-04-22,2007-07-27
-6qqh,2019-06-19,2019-02-18
-3qqf,2012-08-08,2011-02-15
-7qq0,2022-12-14,2022-01-05
-2qq4,2008-07-29,2007-07-26
-5qq5,2020-04-29,2019-03-12
-5qqx,2019-08-07,2019-05-22
-5qqr,2019-08-07,2019-05-22
-1qqm,1999-09-15,1999-06-07
-8qq5,2024-05-08,2023-10-03
-6qqp,2020-03-18,2019-02-18
-2qqm,2007-11-20,2007-07-26
-6qq0,2019-11-06,2019-02-16
-5qqw,2019-08-07,2019-05-22
-3qqk,2012-10-31,2011-02-15
-7qqg,2022-08-31,2022-01-07
-7qq4,2023-04-19,2022-01-06
-8qqg,2024-01-24,2023-10-04
-3qqq,2011-04-27,2011-02-16
-3qqz,2011-03-09,2011-02-16
-5qqo,2019-09-18,2019-05-20
-6qqk,2019-06-19,2019-02-18
-8qq1,2024-05-08,2023-10-03
-8qq0,2024-01-31,2023-10-03
-6qqq,2019-09-18,2019-02-19
-6qqu,2019-09-18,2019-02-19
-3qqo,2011-03-09,2011-02-15
-4qqd,2014-08-06,2014-06-27
-5qqu,2019-08-07,2019-05-22
-5qq7,2020-04-29,2019-03-12
-1qqb,1999-06-09,1999-06-01
-7qqv,2022-10-26,2022-01-10
-7qqy,2022-03-09,2022-01-10
-4qqo,2015-04-22,2014-06-27
-5qq8,2020-04-29,2019-03-12
-5qql,2019-12-18,2019-05-03
-4qqn,2014-09-17,2014-06-27
-2qqt,2007-08-07,2007-07-27
-6qqr,2019-09-18,2019-02-19
-2qqk,2007-11-20,2007-07-26
-4qq2,2015-04-15,2014-06-26
-2qqg,2007-10-09,2007-07-26
-3qql,2012-08-08,2011-02-15
-6qqz,2019-09-18,2019-02-19
-7qqu,2022-10-26,2022-01-10
-4qqz,2014-08-27,2014-06-30
-5qq2,2020-04-29,2019-03-12
-7qq8,2022-07-13,2022-01-06
-3qqe,2011-03-09,2011-02-15
-5qqb,2020-04-29,2019-03-12
-3qqd,2011-03-09,2011-02-15
-1qq9,2000-05-03,1999-06-12
-4qqc,2014-10-29,2014-06-27
-5qqq,2019-08-07,2019-05-22
-7qq7,2023-01-18,2022-01-06
-4qqr,2015-07-01,2014-06-28
-7qqn,2022-04-20,2022-01-10
-5qqa,2020-04-29,2019-03-12
-6qqm,2019-11-06,2019-02-18
-8qq7,2024-05-08,2023-10-04
-5qqe,2019-12-18,2019-05-03
-1qqa,1999-06-09,1999-06-01
-2qqp,2009-01-20,2007-07-26
-3qqr,2011-04-27,2011-02-16
-6qqv,2019-09-18,2019-02-19
-6qq1,2019-11-06,2019-02-16
-7qqk,2022-06-15,2022-01-09
-3qq0,2011-04-13,2011-02-14
-6qqo,2020-03-18,2019-02-18
-6qqj,2019-06-19,2019-02-18
-6qql,2019-03-06,2019-02-18
-7qqw,2022-10-26,2022-01-10
-5qqt,2019-08-07,2019-05-22
-3qqb,2011-03-09,2011-02-15
-7qqm,2022-04-20,2022-01-10
-5qq0,2020-04-29,2019-03-12
-4qq5,2014-10-29,2014-06-26
-5qqj,2019-12-18,2019-05-03
-2qqo,2007-11-20,2007-07-26
-6qqs,2020-03-18,2019-02-19
-6qqi,2019-06-19,2019-02-18
-7qqr,2022-10-26,2022-01-10
-8qq4,2023-12-06,2023-10-03
-7qq3,2023-01-18,2022-01-06
-4qq3,2014-07-16,2014-06-26
-4qqy,2014-08-27,2014-06-30
-2qqc,2008-03-18,2007-07-26
-7qq6,2022-03-02,2022-01-06
-5qqh,2019-12-18,2019-05-03
-2qq0,2007-10-16,2007-07-25
-5qqs,2019-08-07,2019-05-22
-2qq7,2008-03-11,2007-07-26
-2qqf,2007-10-09,2007-07-26
-6qqy,2020-03-18,2019-02-19
-7qqd,2023-01-18,2022-01-07
-2qq6,2007-08-14,2007-07-26
-3qqu,2011-04-20,2011-02-16
-7qqe,2023-01-18,2022-01-07
-4qql,2015-04-22,2014-06-27
-5qqf,2019-12-18,2019-05-03
-3qqg,2012-08-08,2011-02-15
-2qqe,2007-10-16,2007-07-26
-7qq2,2023-01-18,2022-01-06
-3qqt,2011-11-23,2011-02-16
-1qq3,2000-05-24,1999-06-10
-7qqp,2022-10-26,2022-01-10
-7qqa,2022-06-22,2022-01-07
-4qqu,2015-01-14,2014-06-29
-7qqz,2022-10-26,2022-01-10
-7qqo,2022-10-26,2022-01-10
-6qqw,2019-09-18,2019-02-19
-5qqk,2019-12-18,2019-05-03
-1qqn,1999-09-15,1999-06-07
-1qqo,1999-09-15,1999-06-07
-5ok8,2017-12-06,2017-07-25
-8ok8,2023-09-13,2023-03-27
-4okr,2014-03-19,2014-01-22
-4oki,2015-08-05,2014-01-22
-7ok2,2021-10-13,2021-05-17
-4okp,2014-05-28,2014-01-22
-6okv,2019-11-20,2019-04-15
-1okw,2003-12-11,2003-07-31
-8okb,2024-01-17,2023-03-28
-7oky,2021-07-14,2021-05-18
-8okf,2024-04-10,2023-03-28
-4okt,2014-08-20,2014-01-22
-4ok2,2014-01-29,2014-01-21
-2ok4,2007-05-01,2007-01-16
-8okk,2023-05-03,2023-03-28
-4oko,2014-09-24,2014-01-22
-4okk,2014-05-21,2014-01-22
-7okw,2021-09-22,2021-05-18
-7okk,2021-12-08,2021-05-17
-7ok8,2022-06-01,2021-05-17
-8ok5,2023-09-13,2023-03-27
-7okc,2021-10-06,2021-05-17
-1oky,2004-07-29,2003-08-01
-3okj,2011-06-08,2010-08-25
-1ok8,2004-01-29,2003-07-19
-2okq,2007-02-06,2007-01-17
-1okq,2003-09-11,2003-07-28
-6ok4,2019-04-24,2019-04-12
-6okk,2019-05-22,2019-04-13
-7okp,2021-10-27,2021-05-18
-7okx,2021-07-14,2021-05-18
-2ok2,2007-04-10,2007-01-15
-2ok0,2007-06-12,2007-01-15
-8okc,2024-01-17,2023-03-28
-4ok9,2014-03-19,2014-01-22
-6ok1,2019-06-26,2019-04-12
-4oka,2014-11-05,2014-01-22
-7oks,2022-04-27,2021-05-18
-8ok3,2023-10-25,2023-03-27
-8okq,2024-04-10,2023-03-29
-2ok8,2007-02-13,2007-01-16
-5oks,2017-10-18,2017-07-25
-4okz,2014-06-11,2014-01-23
-8oko,2024-04-10,2023-03-28
-4okg,2014-09-24,2014-01-22
-1ok9,2004-01-07,2003-07-21
-8ok0,2023-11-01,2023-03-26
-4okn,2014-12-03,2014-01-22
-4ok3,2014-03-05,2014-01-21
-3ok5,2011-09-07,2010-08-24
-6ok8,2019-05-08,2019-04-12
-7ok6,2021-06-09,2021-05-17
-3oku,2011-07-06,2010-08-25
-1okc,2003-11-07,2003-07-21
-8okg,2024-04-24,2023-03-28
-4okb,2014-08-20,2014-01-22
-3okl,2011-04-06,2010-08-25
-5ok6,2018-08-08,2017-07-25
-7oka,2021-10-13,2021-05-17
-5ok2,2018-08-29,2017-07-25
-5okn,2017-08-23,2017-07-25
-1okg,2003-09-11,2003-07-24
-8oke,2024-04-10,2023-03-28
-1oke,2003-07-24,2003-07-22
-7ok7,2021-06-09,2021-05-17
-8ok9,2024-01-24,2023-03-27
-8oki,2024-04-24,2023-03-28
-7ok0,2021-08-25,2021-05-17
-1oko,2003-12-04,2003-07-28
-8okm,2023-05-03,2023-03-28
-7oku,2022-06-22,2021-05-18
-4okw,2014-08-20,2014-01-23
-4okd,2014-07-02,2014-01-22
-1okj,2004-09-16,2003-07-26
-7okl,2021-12-08,2021-05-17
-3okw,2010-10-13,2010-08-25
-2okc,2007-01-30,2007-01-16
-2okg,2007-01-30,2007-01-16
-4ok4,2014-01-29,2014-01-21
-5ok0,2018-08-29,2017-07-25
-2okk,2007-03-27,2007-01-17
-8ok4,2023-09-13,2023-03-27
-6okd,2020-04-15,2019-04-12
-8okj,2024-04-10,2023-03-28
-4ok1,2014-08-20,2014-01-21
-8okx,2024-02-14,2023-03-29
-8okt,2024-04-10,2023-03-29
-2okx,2007-11-13,2007-01-17
-3okv,2011-07-06,2010-08-25
-7okz,2022-06-01,2021-05-18
-7okf,2021-12-08,2021-05-17
-7ok5,2022-12-14,2021-05-17
-6okh,2019-05-08,2019-04-12
-3oks,2010-10-27,2010-08-25
-8oku,2024-01-10,2023-03-29
-1okk,2004-01-19,2003-07-26
-2ok9,2008-09-23,2007-01-16
-7ok4,2022-08-03,2021-05-17
-8okv,2023-09-20,2023-03-29
-8ok6,2023-09-13,2023-03-27
-4okj,2014-05-21,2014-01-22
-5okl,2017-12-06,2017-07-25
-2ok1,2007-02-06,2007-01-15
-3okf,2010-09-08,2010-08-24
-3oke,2011-04-06,2010-08-24
-1okx,2003-10-24,2003-07-31
-6okc,2020-04-15,2019-04-12
-7okb,2021-10-06,2021-05-17
-4okx,2014-08-20,2014-01-23
-7okr,2022-06-01,2021-05-18
-3okn,2011-04-06,2010-08-25
-2okn,2007-02-20,2007-01-17
-7okt,2022-04-27,2021-05-18
-4okh,2014-05-28,2014-01-22
-5okg,2017-10-18,2017-07-25
-4oke,2014-05-21,2014-01-22
-3ok9,2010-09-22,2010-08-24
-4okq,2014-03-19,2014-01-22
-7okm,2021-12-08,2021-05-17
-5ok3,2018-08-08,2017-07-25
-8okp,2024-04-10,2023-03-28
-4ok5,2014-03-05,2014-01-21
-6okp,2019-06-05,2019-04-14
-2okz,2007-01-30,2007-01-18
-4ok6,2014-03-05,2014-01-21
-3oki,2010-12-29,2010-08-25
-3okc,2010-09-15,2010-08-24
-6ok2,2019-11-20,2019-04-12
-6okf,2020-04-22,2019-04-12
-1okv,2003-12-11,2003-07-30
-3okx,2010-09-08,2010-08-25
-7oke,2021-12-08,2021-05-17
-5okz,2017-08-30,2017-07-26
-3ok0,2011-03-02,2010-08-24
-7okg,2021-12-08,2021-05-17
-7okj,2021-12-08,2021-05-17
-2okl,2008-01-15,2007-01-17
-2ok3,2008-01-22,2007-01-15
-7ok3,2022-08-03,2021-05-17
-8okr,2023-08-02,2023-03-29
-1okm,1997-01-11,1996-06-25
-4oks,2014-03-05,2014-01-22
-1okn,1997-01-11,1996-06-25
-3okk,2011-04-06,2010-08-25
-6okg,2020-04-22,2019-04-12
-2okv,2007-01-30,2007-01-17
-1okl,1997-01-11,1996-06-25
-2ok5,2007-02-27,2007-01-16
-5okd,2018-02-28,2017-07-25
-3okd,2011-04-06,2010-08-24
-7oko,2021-12-08,2021-05-18
-2oke,2007-05-01,2007-01-16
-7okv,2022-07-06,2021-05-18
-2okj,2007-03-27,2007-01-17
-3oko,2011-04-06,2010-08-25
-5ok1,2018-08-29,2017-07-25
-4oku,2014-03-19,2014-01-22
-3okh,2010-12-29,2010-08-25
-6okz,2020-10-28,2019-04-15
-2oko,2007-10-30,2007-01-17
-7ok9,2021-11-03,2021-05-17
-1okz,2004-07-29,2003-08-01
-5okf,2017-10-11,2017-07-25
-5okk,2017-10-18,2017-07-25
-8ok7,2023-09-13,2023-03-27
-6oko,2019-07-17,2019-04-14
-3oky,2010-10-13,2010-08-25
-7okh,2021-12-08,2021-05-17
-5okr,2017-10-18,2017-07-25
-2ok7,2007-02-13,2007-01-16
-4okm,2014-06-11,2014-01-22
-5oke,2017-10-18,2017-07-25
-3oka,2010-09-15,2010-08-24
-5okt,2018-04-25,2017-07-25
-3okp,2010-09-15,2010-08-25
-8okn,2023-05-03,2023-03-28
-7ok1,2021-10-13,2021-05-17
-7okd,2021-12-08,2021-05-17
-8oka,2024-04-10,2023-03-28
-5ok4,2018-05-16,2017-07-25
-7oki,2021-12-08,2021-05-17
-3okt,2010-10-13,2010-08-25
-5okq,2017-10-18,2017-07-25
-5oku,2017-11-08,2017-07-25
-8okl,2023-05-03,2023-03-28
-1ok7,2004-07-15,2003-07-18
-8q9r,2024-04-17,2023-08-20
-5q9h,2018-08-08,2017-05-25
-8q9v,2024-03-06,2023-08-21
-2q9m,2007-08-21,2007-06-13
-1q9l,2004-01-27,2003-08-25
-8q9u,2024-03-06,2023-08-21
-7q9e,2022-10-19,2021-11-12
-7q92,2022-11-09,2021-11-11
-4q9m,2014-10-15,2014-05-01
-1q9h,2004-11-09,2003-08-25
-7q9v,2022-11-30,2021-11-15
-8q9p,2024-04-17,2023-08-20
-1q9d,2003-12-02,2003-08-25
-4q9c,2014-07-02,2014-04-30
-5q9y,2018-08-08,2017-05-25
-7q9m,2021-12-15,2021-11-12
-1q9s,2003-12-16,2003-08-25
-5q96,2018-08-08,2017-05-25
-1q9m,2003-09-02,2003-08-25
-1q9y,2004-04-27,2003-08-26
-5q9j,2018-08-08,2017-05-25
-3q94,2011-01-26,2011-01-07
-3q9f,2011-03-02,2011-01-07
-2q91,2008-02-26,2007-06-12
-1q90,2003-12-09,2003-08-22
-5q98,2018-08-08,2017-05-25
-6q9o,2019-05-15,2018-12-18
-5q95,2018-08-08,2017-05-25
-3q9j,2011-06-08,2011-01-07
-7q9n,2022-11-23,2021-11-12
-6q9h,2019-05-15,2018-12-18
-7q9f,2021-12-15,2021-11-12
-7q96,2022-03-16,2021-11-12
-3q9x,2012-01-11,2011-01-10
-3q9g,2011-06-08,2011-01-07
-5q9t,2018-08-08,2017-05-25
-8q9t,2023-11-29,2023-08-21
-2q9z,2007-10-30,2007-06-14
-4q9f,2014-05-28,2014-05-01
-6q9n,2019-11-27,2018-12-18
-4q9d,2015-04-29,2014-04-30
-5q9w,2018-08-08,2017-05-25
-7q9u,2022-01-26,2021-11-14
-5q9e,2018-08-08,2017-05-25
-2q9g,2008-06-17,2007-06-12
-2q9b,2007-07-03,2007-06-12
-6q9t,2019-09-18,2018-12-18
-1q9u,2004-03-02,2003-08-25
-6q9k,2019-06-26,2018-12-18
-2q9n,2007-08-21,2007-06-13
-1q94,2004-06-01,2003-08-22
-8q9y,2023-09-13,2023-08-22
-5q9u,2018-08-08,2017-05-25
-6q97,2019-03-13,2018-12-17
-3q9l,2011-01-26,2011-01-08
-3q9b,2011-03-02,2011-01-07
-5q9f,2018-08-08,2017-05-25
-5q9c,2018-08-08,2017-05-25
-7q9h,2022-11-23,2021-11-12
-2q9d,2007-06-26,2007-06-12
-7q9j,2021-12-15,2021-11-12
-4q93,2014-12-17,2014-04-28
-7q9k,2021-12-15,2021-11-12
-4q9s,2014-07-02,2014-05-01
-4q9e,2014-05-21,2014-05-01
-4q98,2014-06-04,2014-04-29
-6q90,2019-01-23,2018-12-16
-3q9y,2012-01-11,2011-01-10
-5q97,2018-08-08,2017-05-25
-4q9y,2015-03-11,2014-05-02
-5q9o,2018-08-08,2017-05-25
-5q94,2018-08-08,2017-05-25
-8q9x,2023-09-13,2023-08-22
-4q9k,2015-03-04,2014-05-01
-5q9k,2018-08-08,2017-05-25
-2q9c,2007-07-03,2007-06-12
-7q9l,2022-11-23,2021-11-12
-6q94,2019-04-24,2018-12-17
-2q96,2008-01-01,2007-06-12
-7q9s,2022-01-19,2021-11-14
-7q9w,2022-11-30,2021-11-15
-2q94,2008-01-01,2007-06-12
-3q9a,2011-05-18,2011-01-07
-7q9z,2022-11-23,2021-11-15
-7q9p,2021-12-15,2021-11-12
-7q93,2022-11-23,2021-11-11
-6q99,2020-01-15,2018-12-17
-2q93,2008-01-01,2007-06-12
-5q99,2018-08-08,2017-05-25
-4q92,2014-05-07,2014-04-28
-4q90,2015-03-11,2014-04-28
-3q9z,2012-01-11,2011-01-10
-7q91,2022-11-09,2021-11-11
-1q92,2004-04-20,2003-08-22
-6q9j,2019-06-26,2018-12-18
-5q9l,2018-08-08,2017-05-25
-7q9g,2021-12-15,2021-11-12
-1q9k,2004-01-27,2003-08-25
-5q9v,2018-08-08,2017-05-25
-1q9i,2004-05-04,2003-08-25
-5q9a,2018-08-08,2017-05-25
-6q96,2019-05-15,2018-12-17
-3q9c,2011-03-02,2011-01-07
-3q9n,2011-04-27,2011-01-09
-5q9d,2018-08-08,2017-05-25
-6q9f,2020-01-15,2018-12-18
-6q9b,2019-08-21,2018-12-17
-6q9v,2020-01-15,2018-12-18
-2q9e,2007-06-26,2007-06-12
-3q96,2011-03-23,2011-01-07
-2q9p,2007-09-11,2007-06-13
-6q92,2019-12-11,2018-12-17
-8q9s,2023-12-06,2023-08-21
-3q9o,2012-01-04,2011-01-09
-3q9i,2011-06-08,2011-01-07
-2q95,2008-01-01,2007-06-12
-1q9x,2004-04-27,2003-08-26
-6q9y,2019-05-15,2018-12-18
-4q99,2015-03-11,2014-04-29
-6q9q,2019-05-15,2018-12-18
-4q9x,2014-05-21,2014-05-02
-5q9n,2018-08-08,2017-05-25
-5q90,2018-08-08,2017-05-25
-6q9s,2019-05-15,2018-12-18
-2q9i,2007-12-11,2007-06-12
-3q9u,2011-04-20,2011-01-10
-7q9o,2022-11-23,2021-11-12
-6q93,2019-02-27,2018-12-17
-5q9x,2018-08-08,2017-05-25
-6q9g,2019-06-26,2018-12-18
-4q9o,2014-10-15,2014-05-01
-6q91,2019-01-23,2018-12-17
-8q91,2024-03-27,2023-08-19
-6q9w,2019-05-15,2018-12-18
-3q92,2012-01-18,2011-01-07
-3q9t,2011-09-21,2011-01-09
-6q95,2019-02-27,2018-12-17
-2q9u,2007-12-11,2007-06-14
-4q9z,2014-07-02,2014-05-02
-4q9i,2015-03-04,2014-05-01
-5q9i,2018-08-08,2017-05-25
-8q9q,2024-04-17,2023-08-20
-6q9d,2019-08-21,2018-12-18
-3q95,2012-01-11,2011-01-07
-6q9u,2019-05-15,2018-12-18
-4q94,2014-06-18,2014-04-29
-7q9i,2021-12-15,2021-11-12
-6q98,2019-02-27,2018-12-17
-7q9q,2022-01-19,2021-11-14
-4q9j,2015-03-04,2014-05-01
-2q92,2008-01-01,2007-06-12
-2q9o,2008-03-25,2007-06-13
-3q9h,2011-06-08,2011-01-07
-7q90,2022-03-09,2021-11-11
-5q9g,2018-08-08,2017-05-25
-1q99,2003-09-23,2003-08-22
-5q9p,2018-08-08,2017-05-25
-3q99,2011-05-18,2011-01-07
-1q9o,2004-01-27,2003-08-25
-6q9p,2019-12-11,2018-12-18
-1q97,2003-09-23,2003-08-22
-6q9e,2019-08-21,2018-12-18
-4q9l,2015-03-04,2014-05-01
-2q97,2007-10-16,2007-06-12
-2q9f,2008-06-17,2007-06-12
-1q9w,2004-01-27,2003-08-26
-1q95,2004-06-08,2003-08-22
-4q9n,2014-06-25,2014-05-01
-5q9b,2018-08-08,2017-05-25
-5q9m,2018-08-08,2017-05-25
-7q9x,2022-11-23,2021-11-15
-5q93,2018-08-08,2017-05-25
-2q9y,2008-04-22,2007-06-14
-2q9l,2007-10-09,2007-06-13
-5q9z,2018-08-08,2017-05-25
-3q9e,2011-03-02,2011-01-07
-6q9l,2019-05-15,2018-12-18
-7q9c,2022-11-23,2021-11-12
-5q91,2018-08-08,2017-05-25
-4q95,2014-10-29,2014-04-29
-6q9a,2019-04-17,2018-12-17
-5q9s,2018-08-08,2017-05-25
-7q9r,2022-01-19,2021-11-14
-3q9w,2012-01-11,2011-01-10
-5q9q,2018-08-08,2017-05-25
-1q91,2004-04-20,2003-08-22
-5q92,2018-08-08,2017-05-25
-5q9r,2018-08-08,2017-05-25
-6q9c,2019-06-26,2018-12-17
-4y1b,2015-09-23,2015-02-07
-2y1v,2011-11-09,2010-12-10
-7y1z,2023-07-12,2022-06-09
-1y1f,2005-05-31,2004-11-18
-1y1e,2005-05-31,2004-11-18
-1y1k,2005-05-17,2004-11-18
-6y1p,2021-02-24,2020-02-13
-5y1b,2018-01-24,2017-07-20
-5y1z,2017-10-25,2017-07-22
-2y1h,2010-12-29,2010-12-08
-4y15,2015-04-08,2015-02-06
-7y1h,2023-07-05,2022-06-08
-6y1u,2021-06-09,2020-02-13
-2y1f,2011-06-29,2010-12-08
-5y1x,2018-08-01,2017-07-21
-1y18,2005-04-05,2004-11-17
-8y1c,2024-05-01,2024-01-24
-1y13,2005-01-04,2004-11-17
-5y11,2017-09-13,2017-07-19
-7y1s,2023-07-05,2022-06-08
-5y19,2018-08-01,2017-07-19
-4y1s,2015-09-02,2015-02-09
-5y17,2018-07-25,2017-07-19
-4y1v,2016-04-06,2015-02-09
-7y1j,2023-06-14,2022-06-08
-4y13,2015-04-08,2015-02-06
-1y1o,2004-12-07,2004-11-19
-4y1d,2015-05-13,2015-02-07
-1y1q,2005-11-22,2004-11-19
-8y1g,2024-05-01,2024-01-24
-4y1y,2016-04-06,2015-02-09
-5y1f,2017-11-15,2017-07-20
-8y1b,2024-05-01,2024-01-24
-1y1g,2005-05-31,2004-11-18
-5y1e,2017-11-15,2017-07-20
-6y1t,2021-06-16,2020-02-13
-8y1f,2024-05-01,2024-01-24
-4y17,2015-04-08,2015-02-06
-2y1x,2011-03-23,2010-12-10
-7y10,2023-05-31,2022-06-06
-6y12,2020-09-09,2020-02-11
-1y1n,2005-05-24,2004-11-18
-6y1b,2020-02-19,2020-02-11
-1y1d,2005-07-26,2004-11-18
-1y1v,2004-12-28,2004-11-19
-4y1x,2016-04-06,2015-02-09
-4y1u,2016-04-06,2015-02-09
-2y1m,2012-01-18,2010-12-08
-7y1g,2022-09-28,2022-06-08
-4y19,2015-09-23,2015-02-07
-7y1f,2023-05-24,2022-06-08
-6y18,2020-11-18,2020-02-11
-8y1m,2024-05-22,2024-01-25
-7y1a,2023-01-18,2022-06-07
-4y16,2015-06-03,2015-02-06
-6y1w,2020-06-17,2020-02-14
-1y1m,2005-07-12,2004-11-18
-6y1i,2021-06-30,2020-02-12
-5y13,2018-06-06,2017-07-19
-1y1h,2005-05-31,2004-11-18
-2y1w,2011-03-23,2010-12-10
-6y1n,2020-09-23,2020-02-12
-7y1k,2023-06-14,2022-06-08
-4y12,2015-05-20,2015-02-06
-2y1k,2011-06-29,2010-12-08
-7y1t,2022-08-31,2022-06-08
-1y10,2005-05-24,2004-11-16
-5y1s,2018-08-01,2017-07-21
-4y1q,2015-08-12,2015-02-08
-8y1d,2024-05-01,2024-01-24
-6y1z,2020-03-04,2020-02-14
-7y1m,2023-06-14,2022-06-08
-7y1l,2023-06-14,2022-06-08
-8y19,2024-05-01,2024-01-24
-7y1y,2023-07-12,2022-06-09
-6y1e,2020-03-11,2020-02-12
-4y11,2015-06-24,2015-02-06
-5y1r,2018-08-01,2017-07-21
-6y1c,2020-02-19,2020-02-11
-5y1q,2018-08-01,2017-07-21
-4y1c,2015-02-25,2015-02-07
-8y1a,2024-05-01,2024-01-24
-5y1j,2018-10-31,2017-07-20
-4y1t,2015-09-02,2015-02-09
-5y1t,2018-08-01,2017-07-21
-4y14,2015-08-05,2015-02-06
-1y1x,2004-12-07,2004-11-19
-6y1r,2021-02-24,2020-02-13
-6y11,2020-09-02,2020-02-10
-5y1u,2018-04-18,2017-07-21
-1y1a,2005-05-03,2004-11-17
-1y1j,2005-05-31,2004-11-18
-6y17,2020-12-02,2020-02-11
-5y1k,2018-08-01,2017-07-20
-1y1i,2005-05-31,2004-11-18
-7y1p,2023-12-13,2022-06-08
-4y18,2016-01-27,2015-02-06
-2y1t,2011-02-23,2010-12-10
-2y1d,2011-06-29,2010-12-08
-1y1s,2005-11-22,2004-11-19
-5y12,2018-06-06,2017-07-19
-8y1j,2024-05-22,2024-01-24
-4y1a,2015-09-23,2015-02-07
-5y1w,2018-08-01,2017-07-21
-5y1h,2018-08-01,2017-07-20
-1y1p,2005-09-06,2004-11-19
-6y10,2020-02-19,2020-02-10
-6y1j,2020-03-04,2020-02-12
-2y1n,2012-01-18,2010-12-08
-6y1l,2020-09-23,2020-02-12
-5y10,2017-09-13,2017-07-19
-6y1v,2021-06-09,2020-02-13
-6y15,2020-02-19,2020-02-11
-7y1w,2023-07-05,2022-06-09
-2y1a,2011-02-16,2010-12-07
-5y1y,2017-11-15,2017-07-21
-7y11,2023-04-19,2022-06-06
-7y12,2022-07-20,2022-06-06
-5y1i,2017-09-13,2017-07-20
-8y1e,2024-05-01,2024-01-24
-7y1r,2022-08-31,2022-06-08
-5y1v,2018-08-01,2017-07-21
-2y1l,2011-12-28,2010-12-08
-1y1z,2005-07-12,2004-11-19
-2y1o,2011-12-28,2010-12-09
-8y1h,2024-05-01,2024-01-24
-4y1p,2016-03-09,2015-02-08
-1y1l,2004-11-30,2004-11-18
-2y1g,2011-06-29,2010-12-08
-1y17,2006-03-07,2004-11-17
-4y1z,2016-04-06,2015-02-09
-7y1n,2023-06-14,2022-06-08
-4y10,2015-06-24,2015-02-06
-2y1c,2011-06-29,2010-12-08
-2y1e,2011-06-29,2010-12-08
-7y1u,2023-07-05,2022-06-08
-7y14,2022-07-20,2022-06-06
-5y1g,2017-11-15,2017-07-20
-1y1r,2005-11-22,2004-11-19
-1y1w,2005-01-04,2004-11-19
-6y1d,2020-11-18,2020-02-12
-6lj5,2020-12-16,2019-12-13
-6lj3,2020-11-11,2019-12-13
-2ljx,2012-04-04,2011-09-30
-6lj6,2020-12-16,2019-12-13
-5lj2,2016-08-31,2016-07-17
-7lj2,2022-02-09,2021-01-28
-3ljr,1999-03-23,1998-03-08
-4lj5,2014-02-12,2013-07-04
-7ljx,2021-05-12,2021-02-01
-5ljj,2016-10-12,2016-07-18
-1ljy,2003-03-18,2002-04-23
-3lj9,2010-09-08,2010-01-26
-7ljb,2021-06-30,2021-01-28
-5ljq,2017-06-21,2016-07-19
-3lj6,2010-06-09,2010-01-25
-4ljz,2013-11-13,2013-07-05
-7ljs,2021-04-07,2021-01-30
-5lj7,2017-11-15,2016-07-18
-1ljt,2002-11-27,2002-04-22
-3ljq,2010-11-24,2010-01-26
-5lj3,2016-08-03,2016-07-17
-6lj1,2020-12-16,2019-12-13
-6ljx,2020-04-15,2019-12-17
-7lj4,2021-06-30,2021-01-28
-7ljd,2021-03-03,2021-01-28
-3lj7,2010-06-09,2010-01-25
-7lja,2021-06-30,2021-01-28
-1lj2,2002-07-05,2002-04-18
-7ljj,2022-02-09,2021-01-29
-4ljr,2014-01-01,2013-07-05
-5ljz,2016-09-14,2016-07-20
-6ljd,2020-01-01,2019-12-14
-3ljt,2010-03-31,2010-01-26
-3ljm,2010-09-15,2010-01-26
-1ljw,2002-05-01,2002-04-22
-3ljf,2010-09-08,2010-01-26
-3ljz,2011-02-02,2010-01-26
-5lje,2017-01-18,2016-07-18
-5ljd,2017-01-18,2016-07-18
-3ljj,2010-10-06,2010-01-26
-5ljx,2016-09-14,2016-07-20
-7ljc,2021-03-03,2021-01-28
-5lj0,2016-08-31,2016-07-17
-3ljw,2010-05-19,2010-01-26
-7lju,2021-04-07,2021-01-30
-4lj6,2014-02-12,2013-07-04
-6ljr,2020-10-14,2019-12-17
-3lj2,2010-05-12,2010-01-25
-1lj1,2002-11-06,2002-04-18
-7lji,2021-12-08,2021-01-29
-3ljp,2010-03-16,2010-01-26
-2ljc,2011-11-16,2011-09-10
-5ljy,2016-09-14,2016-07-20
-5ljv,2016-11-16,2016-07-21
-6ljt,2020-04-15,2019-12-17
-4ljp,2013-10-16,2013-07-05
-6lja,2020-12-23,2019-12-13
-6lj7,2020-12-16,2019-12-13
-7ljg,2022-02-09,2021-01-29
-3ljo,2010-10-06,2010-01-26
-7ljl,2021-06-02,2021-01-29
-4lj3,2014-01-29,2013-07-04
-5lj1,2016-08-31,2016-07-17
-6ljc,2020-01-01,2019-12-14
-6ljl,2020-12-23,2019-12-17
-5ljc,2017-01-18,2016-07-18
-7ljf,2021-05-05,2021-01-29
-6lj8,2020-12-16,2019-12-13
-2ljz,2012-04-04,2011-09-30
-5lj6,2017-11-15,2016-07-18
-3ljg,2010-09-01,2010-01-26
-4ljy,2013-12-11,2013-07-05
-5ljb,2017-01-18,2016-07-18
-5ljt,2017-06-21,2016-07-19
-3lj0,2010-05-12,2010-01-25
-5ljf,2017-08-02,2016-07-18
-6lje,2020-01-01,2019-12-14
-1ljn,2002-06-05,2002-04-22
-3lj1,2010-05-12,2010-01-25
-4lj0,2013-10-09,2013-07-04
-6ljw,2020-04-15,2019-12-17
-6lj4,2020-12-16,2019-12-13
-5ljp,2017-08-02,2016-07-19
-1lj0,2002-11-20,2002-04-18
-6ljj,2020-11-11,2019-12-16
-6ljk,2020-12-23,2019-12-17
-7ljm,2021-06-02,2021-01-29
-6ljq,2020-10-14,2019-12-17
-7lje,2021-03-17,2021-01-29
-3lj3,2010-04-14,2010-01-25
-6lj2,2020-12-16,2019-12-13
-1ljl,2002-08-07,2002-04-21
-1lj8,2002-11-15,2002-04-19
-3lju,2010-11-24,2010-01-26
-5lj5,2016-08-31,2016-07-17
-2ljy,2012-04-04,2011-09-30
-6lj0,2020-12-16,2019-12-13
-6ljn,2020-10-28,2019-12-17
-7lj9,2021-03-31,2021-01-28
-4ljo,2013-10-16,2013-07-05
-4ljn,2013-10-16,2013-07-05
-7lj5,2021-06-30,2021-01-28
-4ljh,2013-10-30,2013-07-04
-6ljg,2020-12-16,2019-12-15
-4lja,2014-02-12,2013-07-04
-7ljo,2021-06-02,2021-01-29
-5lji,2016-08-31,2016-07-18
-6lju,2020-04-15,2019-12-17
-6ljs,2020-04-15,2019-12-17
-5ljn,2016-08-24,2016-07-18
-1lju,2002-08-07,2002-04-22
-4ljq,2013-10-16,2013-07-05
-7lj1,2021-07-14,2021-01-28
-6ljf,2020-01-01,2019-12-14
-7ljn,2021-06-02,2021-01-29
-5ljh,2017-01-18,2016-07-18
-1ljr,1999-03-23,1998-03-08
-6ljm,2020-10-28,2019-12-17
-4lj8,2014-02-12,2013-07-04
-3lja,2010-04-14,2010-01-26
-1ljo,2002-07-03,2002-04-22
-6ljh,2020-12-23,2019-12-16
-4lj7,2014-02-12,2013-07-04
-7ljt,2021-04-07,2021-01-30
-4lji,2013-08-28,2013-07-04
-5ljw,2016-11-16,2016-07-20
-6ljv,2020-04-15,2019-12-17
-4lj9,2014-02-12,2013-07-04
-7ljh,2021-12-08,2021-01-29
-5ljk,2017-01-18,2016-07-18
-7lj0,2021-04-07,2021-01-28
-3ljk,2010-03-16,2010-01-26
-6fs0,2018-12-26,2018-02-18
-8fsg,2024-01-17,2023-01-09
-8fsj,2023-07-19,2023-01-10
-1fs9,2001-01-17,2000-09-08
-8fsm,2024-01-17,2023-01-10
-5fsk,2016-07-20,2016-01-06
-4fsz,2012-08-22,2012-06-27
-6fsa,2018-07-25,2018-02-19
-6fso,2019-03-20,2018-02-20
-7fsb,2023-04-12,2022-12-18
-4fsm,2012-08-22,2012-06-27
-6fs1,2018-12-26,2018-02-18
-1fsg,2000-12-06,2000-09-08
-7fs9,2023-04-12,2022-12-18
-4fsw,2012-08-22,2012-06-27
-7fsv,2023-02-15,2023-01-24
-4fsk,2013-07-03,2012-06-27
-5fsa,2017-03-15,2016-01-02
-5fsb,2017-03-29,2016-01-04
-5fsg,2016-04-06,2016-01-05
-5fsm,2016-07-20,2016-01-06
-8fsz,2023-12-27,2023-01-11
-3fsj,2009-01-27,2009-01-09
-8fss,2024-02-07,2023-01-11
-4fsl,2012-10-10,2012-06-27
-4fsu,2012-08-22,2012-06-27
-3fsy,2009-06-23,2009-01-12
-6fsg,2018-07-11,2018-02-19
-7fsk,2023-02-15,2023-01-24
-7fsy,2023-02-15,2023-01-24
-2fsh,2007-01-16,2006-01-23
-8fsh,2024-01-17,2023-01-09
-3fsu,2009-08-25,2009-01-12
-5fst,2016-10-26,2016-01-07
-2fsv,2006-02-28,2006-01-23
-8fsa,2024-01-17,2023-01-09
-7fsi,2023-02-15,2023-01-24
-1fsl,1996-06-26,1995-12-12
-6fsi,2018-07-11,2018-02-19
-8fs3,2023-06-14,2023-01-09
-8fsp,2023-12-27,2023-01-10
-7fso,2023-02-15,2023-01-24
-8fsf,2024-01-17,2023-01-09
-7fs2,2023-04-12,2022-12-18
-6fsl,2019-03-13,2018-02-19
-4fso,2013-07-24,2012-06-27
-4fsf,2012-10-17,2012-06-27
-3fsl,2009-01-27,2009-01-09
-5fs5,2016-11-30,2015-12-30
-3fsc,2009-02-17,2009-01-09
-2fs5,2006-08-01,2006-01-20
-4fs0,2012-08-22,2012-06-26
-7fst,2023-02-15,2023-01-24
-4fs3,2012-09-19,2012-06-26
-1fsx,2001-06-06,2000-09-11
-8fsx,2024-01-17,2023-01-11
-7fs1,2023-04-12,2022-12-18
-8fsr,2024-02-07,2023-01-11
-6fse,2018-10-31,2018-02-19
-4fse,2012-10-10,2012-06-27
-6fsm,2018-05-02,2018-02-19
-8fsv,2024-01-17,2023-01-11
-2fsu,2007-03-27,2006-01-23
-3fsi,2009-05-19,2009-01-09
-8fs4,2023-06-14,2023-01-09
-1fsr,2001-01-17,2000-09-11
-4fsr,2012-08-22,2012-06-27
-7fsn,2023-02-15,2023-01-24
-6fsh,2018-05-23,2018-02-19
-8fsq,2024-04-17,2023-01-11
-2fs9,2006-03-07,2006-01-21
-7fs6,2023-04-12,2022-12-18
-3fs4,2009-03-31,2009-01-09
-7fsm,2023-02-15,2023-01-24
-3fsr,2010-01-19,2009-01-11
-7fsl,2023-02-15,2023-01-24
-2fsi,2007-01-16,2006-01-23
-7fsj,2023-02-15,2023-01-24
-1fsy,2001-03-14,2000-09-11
-4fsy,2012-08-22,2012-06-27
-8fs6,2023-06-14,2023-01-09
-6fsy,2018-04-18,2018-02-20
-3fs8,2009-02-17,2009-01-09
-7fsx,2023-02-15,2023-01-24
-3fsf,2009-12-22,2009-01-09
-4fs4,2012-10-10,2012-06-26
-1fs7,2001-01-17,2000-09-08
-7fse,2023-05-10,2023-01-04
-6fs9,2018-07-11,2018-02-19
-2fs4,2006-06-13,2006-01-20
-3fst,2009-08-25,2009-01-12
-4fsq,2012-08-22,2012-06-27
-7fs7,2023-04-12,2022-12-18
-5fsi,2016-07-11,2016-01-06
-3fs9,2009-03-10,2009-01-09
-8fst,2024-01-17,2023-01-11
-3fsn,2009-09-29,2009-01-11
-1fsu,1998-02-04,1996-07-29
-3fsb,2009-02-17,2009-01-09
-2fsa,2006-07-11,2006-01-21
-7fs5,2023-04-12,2022-12-18
-7fsc,2023-04-12,2022-12-18
-5fs6,2016-05-11,2015-12-30
-7fsr,2023-02-15,2023-01-24
-7fsd,2023-04-12,2022-12-18
-7fsu,2023-02-15,2023-01-24
-5fse,2016-03-23,2016-01-04
-3fsx,2009-06-23,2009-01-12
-6fs2,2018-12-26,2018-02-18
-2fs6,2006-09-19,2006-01-21
-4fsh,2013-01-30,2012-06-27
-1fsj,2003-06-17,2000-09-11
-4fsn,2012-08-22,2012-06-27
-7fsp,2023-02-15,2023-01-24
-8fs5,2023-06-14,2023-01-09
-3fsw,2009-03-10,2009-01-12
-6fs3,2019-03-20,2018-02-19
-8fs2,2023-05-10,2023-01-09
-7fsa,2023-04-12,2022-12-18
-8fsc,2024-01-17,2023-01-09
-5fsy,2016-04-20,2016-01-08
-2fsn,2006-04-18,2006-01-23
-5fsl,2016-07-20,2016-01-06
-8fsi,2023-05-24,2023-01-10
-1fsw,2001-03-14,2000-09-11
-6fsq,2018-08-08,2018-02-20
-7fsg,2023-02-15,2023-01-24
-4fsj,2012-08-01,2012-06-27
-4fs2,2012-08-29,2012-06-26
-8fsu,2024-01-17,2023-01-11
-3fsz,2009-03-10,2009-01-12
-6fsb,2018-07-11,2018-02-19
-2fsz,2006-07-11,2006-01-23
-4fst,2012-08-22,2012-06-27
-8fs0,2024-01-17,2023-01-09
-1fsz,1998-06-24,1997-06-24
-3fs7,2010-01-19,2009-01-09
-5fs8,2016-05-11,2015-12-31
-6fsd,2018-10-31,2018-02-19
-1fsa,1997-09-04,1996-08-24
-7fs4,2023-04-12,2022-12-18
-4fsx,2012-10-17,2012-06-27
-3fs1,2009-10-27,2009-01-08
-1fs4,2000-10-04,2000-09-08
-5fsx,2016-04-20,2016-01-08
-2fsg,2007-01-16,2006-01-23
-3fsm,2010-01-05,2009-01-10
-8fsd,2023-10-18,2023-01-09
-4fs9,2013-03-06,2012-06-27
-3fs6,2009-08-18,2009-01-09
-3fsv,2009-03-10,2009-01-12
-5fs9,2016-05-11,2015-12-31
-8fs8,2023-06-14,2023-01-09
-4fsb,2013-06-26,2012-06-27
-4fsd,2012-07-11,2012-06-27
-5fsj,2016-10-26,2016-01-06
-2fs8,2006-03-21,2006-01-21
-6fs7,2018-07-11,2018-02-19
-5fsc,2017-03-29,2016-01-04
-8fsw,2024-01-17,2023-01-11
-6fsn,2019-03-20,2018-02-19
-5fsn,2016-07-20,2016-01-06
-1fs8,2001-01-17,2000-09-08
-8fsy,2024-01-17,2023-01-11
-8fsb,2023-12-27,2023-01-09
-7fsq,2023-02-15,2023-01-24
-4fs1,2012-08-29,2012-06-26
-5fso,2017-01-18,2016-01-06
-7fsh,2023-02-15,2023-01-24
-5fs0,2016-03-30,2015-12-23
-7fsf,2023-05-10,2023-01-04
-5fs7,2016-05-11,2015-12-30
-6fs6,2018-07-11,2018-02-19
-7fss,2023-02-15,2023-01-24
-1fss,1996-03-08,1995-10-25
-5fsp,2016-10-26,2016-01-06
-8fs7,2023-06-14,2023-01-09
-8fsn,2024-01-17,2023-01-10
-8fs1,2023-05-10,2023-01-09
-7fs0,2023-04-12,2022-12-18
-7fsz,2023-02-15,2023-01-24
-5fss,2016-10-26,2016-01-07
-7fs8,2023-04-12,2022-12-18
-6fs8,2018-07-11,2018-02-19
-4fsa,2013-07-24,2012-06-27
-5fsh,2016-01-27,2016-01-06
-1fs5,2002-01-04,2000-09-08
-7fsw,2023-02-15,2023-01-24
-8fs9,2024-01-17,2023-01-09
-5fsd,2016-03-23,2016-01-04
-4fs8,2012-07-11,2012-06-27
-1fsq,2001-01-17,2000-09-11
-3fsk,2009-12-22,2009-01-09
-3fsa,2009-03-10,2009-01-09
-7fs3,2023-04-12,2022-12-18
-6fsk,2018-12-26,2018-02-19
-1tu4,2004-10-05,2004-06-24
-3tus,2011-10-19,2011-09-18
-4tua,2015-05-13,2014-06-24
-6tuo,2021-01-27,2020-01-07
-5tuz,2017-02-22,2016-11-07
-8tul,2023-09-13,2023-08-16
-6tuz,2020-10-28,2020-01-08
-1tu3,2004-10-05,2004-06-24
-5tu5,2016-11-30,2016-11-04
-4tu9,2014-11-26,2014-06-24
-3tuh,2012-09-19,2011-09-16
-1tu7,2005-01-11,2004-06-24
-4tuj,2015-07-15,2014-06-24
-7tu2,2022-06-01,2022-02-02
-1tu9,2004-08-10,2004-06-24
-4tud,2015-05-13,2014-06-24
-4tuo,2015-07-15,2014-06-24
-5tuq,2017-06-28,2016-11-07
-3tui,2011-11-30,2011-09-16
-5tur,2017-10-11,2016-11-07
-6tu2,2020-05-06,2020-01-01
-5tuw,2017-06-07,2016-11-07
-1tu2,2005-03-01,2004-06-24
-6tux,2020-09-16,2020-01-08
-4tur,2014-10-01,2014-06-24
-5tuf,2017-05-10,2016-11-06
-6tu9,2020-01-22,2020-01-04
-7tux,2022-12-07,2022-02-03
-4tub,2015-05-13,2014-06-24
-3tu6,2012-05-30,2011-09-16
-8tun,2024-04-17,2023-08-16
-7tub,2022-12-28,2022-02-02
-1tu5,2005-02-22,2004-06-24
-1tu8,2005-01-11,2004-06-24
-4tuh,2014-10-15,2014-06-24
-1tui,1997-06-05,1996-05-23
-5tuk,2017-05-10,2016-11-06
-8tu9,2024-02-07,2023-08-15
-1tub,1998-10-07,1997-09-23
-1tuj,2005-09-20,2004-06-25
-4tu8,2014-11-26,2014-06-24
-7tu5,2022-06-01,2022-02-02
-4tuq,2014-10-01,2014-06-24
-6tuu,2021-01-27,2020-01-08
-7tuo,2023-02-15,2022-02-03
-4tup,2014-10-01,2014-06-24
-4tun,2014-07-09,2014-06-24
-4tu0,2014-07-09,2014-06-23
-3tuv,2011-10-26,2011-09-19
-7tuv,2023-01-11,2022-02-03
-7tut,2022-10-19,2022-02-03
-3tub,2012-08-29,2011-09-16
-5tui,2017-05-10,2016-11-06
-7tud,2022-09-07,2022-02-02
-3tuy,2011-11-23,2011-09-19
-7tuf,2022-09-07,2022-02-02
-8tuh,2024-03-13,2023-08-16
-7tug,2022-09-07,2022-02-02
-5tu0,2016-11-16,2016-11-04
-4tuc,2015-05-13,2014-06-24
-1tum,1997-05-15,1996-12-05
-5tua,2017-01-18,2016-11-05
-7tuq,2022-07-06,2022-02-03
-3tut,2011-12-28,2011-09-18
-5tuo,2017-09-13,2016-11-06
-7tu4,2022-06-01,2022-02-02
-3tud,2012-08-29,2011-09-16
-4tu5,2015-07-08,2014-06-23
-3tu5,2012-09-26,2011-09-15
-1tuu,2005-01-18,2004-06-25
-6tuh,2020-11-25,2020-01-07
-1tuy,2005-01-11,2004-06-25
-6tu4,2021-01-13,2020-01-02
-8tui,2023-12-06,2023-08-16
-7tuy,2022-04-13,2022-02-03
-3tuc,2012-08-29,2011-09-16
-6tuc,2021-01-27,2020-01-06
-6tu5,2020-04-15,2020-01-02
-7tuc,2022-09-07,2022-02-02
-5tum,2017-05-10,2016-11-06
-4tuk,2015-07-15,2014-06-24
-1tu6,2004-09-21,2004-06-24
-4tus,2014-10-01,2014-06-24
-6tu7,2021-01-13,2020-01-03
-4tux,2014-07-16,2014-06-25
-1tu0,2004-07-20,2004-06-23
-5tux,2017-06-07,2016-11-07
-7tuw,2023-02-15,2022-02-03
-3tu7,2011-10-12,2011-09-16
-7tu3,2022-06-01,2022-02-02
-3tur,2012-12-05,2011-09-17
-8tug,2024-01-24,2023-08-16
-6tut,2020-02-19,2020-01-08
-8tuc,2023-12-13,2023-08-16
-7tun,2023-02-15,2022-02-03
-7tu7,2022-06-01,2022-02-02
-7tus,2022-06-08,2022-02-03
-7tuu,2022-08-03,2022-02-03
-3tu1,2011-11-02,2011-09-15
-1tuv,2005-01-11,2004-06-25
-6tu1,2020-03-04,2019-12-31
-4tue,2015-05-13,2014-06-24
-5tu4,2016-11-30,2016-11-04
-4tu7,2014-11-26,2014-06-24
-7tur,2022-09-28,2022-02-03
-4tug,2014-10-15,2014-06-24
-5tud,2017-07-26,2016-11-05
-7tu6,2022-06-01,2022-02-02
-6tuk,2020-11-18,2020-01-07
-1tuf,2004-07-20,2004-06-24
-7tu0,2022-06-01,2022-02-02
-3tu0,2012-01-04,2011-09-15
-1tup,1995-07-11,1995-07-11
-4tuv,2015-02-18,2014-06-24
-4tuy,2014-08-27,2014-06-25
-5tus,2017-08-02,2016-11-07
-3tuz,2011-11-30,2011-09-19
-6tu6,2020-04-01,2020-01-02
-4tul,2015-07-15,2014-06-24
-6tug,2020-02-26,2020-01-07
-6tup,2020-02-26,2020-01-08
-5tuy,2017-02-22,2016-11-07
-5tu6,2016-11-30,2016-11-04
-5tue,2017-05-10,2016-11-05
-4tuw,2014-07-23,2014-06-25
-8tub,2024-03-13,2023-08-16
-6tuy,2021-07-21,2020-01-08
-1tug,2004-07-20,2004-06-24
-7tui,2023-02-15,2022-02-02
-7tuz,2022-04-13,2022-02-03
-6tuw,2020-09-16,2020-01-08
-7tu9,2023-03-22,2022-02-02
-8tua,2024-04-10,2023-08-15
-6tuf,2021-01-27,2020-01-07
-3tux,2011-12-28,2011-09-19
-4tu4,2014-12-24,2014-06-23
-8tup,2023-09-13,2023-08-16
-3tu9,2011-10-12,2011-09-16
-7tu8,2022-06-01,2022-02-02
-4tuz,2015-01-28,2014-06-25
-5cts,1990-10-15,1989-11-16
-3ctl,2009-02-24,2008-04-14
-7ctc,2021-08-18,2020-08-18
-3ct0,2008-07-01,2008-04-11
-6ctn,2018-06-20,2018-03-23
-5ctu,2016-02-03,2015-07-24
-2ct7,2005-11-23,2005-05-23
-7cty,2021-03-31,2020-08-20
-2cth,1997-12-24,1997-06-18
-1cta,1993-10-31,1992-11-12
-3ctn,1998-05-13,1997-05-08
-6ctd,2018-10-10,2018-03-22
-6ct3,2018-08-01,2018-03-22
-4cte,2015-01-14,2014-03-13
-8ctu,2023-06-14,2022-05-16
-3ct5,2008-07-01,2008-04-11
-8cta,2023-02-22,2022-05-13
-3ctr,2008-07-29,2008-04-14
-4ct8,2014-10-15,2014-03-12
-6ct8,2019-02-20,2018-03-22
-3ct2,2008-04-29,2008-04-11
-8cte,2022-07-20,2022-05-14
-8ctr,2022-06-01,2022-05-16
-7cth,2021-12-01,2020-08-19
-3ct1,2008-07-01,2008-04-11
-4ctv,2014-05-07,2014-03-15
-5cta,2015-11-04,2015-07-23
-8ctb,2022-10-05,2022-05-13
-8ctm,2023-06-28,2022-05-16
-7ct4,2020-11-11,2020-08-18
-1cty,1993-07-15,1993-02-15
-5ct5,2015-11-04,2015-07-23
-6ctx,2018-06-20,2018-03-23
-6ctz,2019-03-27,2018-03-23
-2ctd,2005-11-24,2005-05-24
-7cts,2021-02-03,2020-08-20
-6ctk,2018-06-20,2018-03-23
-4cto,2014-08-06,2014-03-15
-5ct6,2015-11-04,2015-07-23
-1ctj,1996-06-10,1995-08-08
-4ctx,2014-05-07,2014-03-15
-2ctb,1994-01-31,1993-04-02
-8ctv,2023-06-14,2022-05-16
-7cte,2021-01-06,2020-08-18
-8ct7,2023-02-15,2022-05-13
-6cta,2018-07-18,2018-03-22
-4ctq,2014-05-07,2014-03-15
-6ct5,2019-02-06,2018-03-22
-2ctt,2005-11-24,2005-05-24
-6ct6,2019-03-27,2018-03-22
-8ctw,2023-06-14,2022-05-16
-5ct9,2015-11-04,2015-07-23
-2ct1,2005-11-23,2005-05-23
-8cty,2022-08-31,2022-05-16
-5ct3,2015-08-12,2015-07-23
-6ctj,2018-06-20,2018-03-23
-8ct4,2022-05-25,2022-05-13
-7ctt,2020-09-02,2020-08-20
-1ct8,1999-11-10,1999-08-20
-7ctf,2021-01-06,2020-08-18
-3ctq,2008-05-27,2008-04-14
-1ctq,1999-11-15,1999-08-20
-3ctj,2008-06-10,2008-04-14
-4ct2,2014-05-28,2014-03-11
-5ctv,2016-06-15,2015-07-24
-1ct5,1999-09-02,1999-08-18
-3cty,2009-02-24,2008-04-14
-5cty,2016-02-03,2015-07-24
-2ct5,2005-11-23,2005-05-23
-1ctl,1995-06-03,1995-01-06
-6ctv,2018-06-20,2018-03-23
-7ctw,2021-04-28,2020-08-20
-7ct5,2020-11-18,2020-08-18
-8ctf,2022-12-21,2022-05-14
-6ctc,2018-10-24,2018-03-22
-4ctr,2014-05-07,2014-03-15
-7ctl,2021-09-01,2020-08-19
-8ctc,2023-05-10,2022-05-13
-7ctv,2022-04-27,2020-08-20
-5ctw,2016-02-03,2015-07-24
-8ct2,2022-07-20,2022-05-13
-6ctm,2018-06-20,2018-03-23
-5ct7,2015-09-09,2015-07-23
-2ctc,1994-01-31,1993-04-02
-2ctu,2005-11-24,2005-05-24
-2ctv,1993-10-31,1993-08-10
-6cts,1990-10-15,1989-11-16
-7ct3,2021-01-27,2020-08-17
-7ctq,2021-02-17,2020-08-20
-6ct2,2018-08-01,2018-03-22
-4cth,2014-08-13,2014-03-13
-5ctc,2015-10-14,2015-07-23
-1ctd,1993-10-31,1992-11-12
-1ctz,1993-07-15,1993-02-15
-3ct7,2008-08-26,2008-04-11
-4ctk,2014-04-16,2014-03-14
-4cty,2014-05-07,2014-03-15
-2ctn,1998-05-06,1997-05-06
-4ctu,2014-05-07,2014-03-15
-6ctu,2018-06-20,2018-03-23
-1cte,1995-07-31,1995-05-03
-8ctn,2023-06-14,2022-05-16
-6cto,2018-06-20,2018-03-23
-8cth,2022-12-07,2022-05-14
-4ct4,2014-05-07,2014-03-12
-4ctz,2014-05-07,2014-03-15
-3cts,1984-07-20,1984-01-27
-1ct9,1999-12-15,1999-08-20
-3ctt,2009-02-24,2008-04-14
-4cta,2014-10-15,2014-03-12
-5ctn,2015-11-25,2015-07-24
-4ctp,2014-05-07,2014-03-15
-4ct0,2014-06-04,2014-03-11
-8ctd,2023-05-10,2022-05-14
-5ctp,2016-11-30,2015-07-24
-5ctl,2016-01-13,2015-07-24
-2ct2,2005-11-23,2005-05-23
-2ct9,2005-07-05,2005-05-23
-6ctq,2018-06-20,2018-03-23
-2cts,1984-07-20,1984-01-27
-7ctx,2022-04-27,2020-08-20
-4ctc,2014-05-28,2014-03-12
-6ctf,2018-10-10,2018-03-23
-4ct3,2014-08-06,2014-03-12
-5ctx,2016-02-03,2015-07-24
-8ctx,2023-06-14,2022-05-16
-4ctj,2014-04-16,2014-03-14
-5ctb,2015-10-14,2015-07-23
-8ctt,2023-06-14,2022-05-16
-2ctz,2005-11-24,2005-05-24
-6ct9,2018-07-18,2018-03-22
-1ct1,1997-10-15,1997-06-03
-8ct0,2023-05-17,2022-05-13
-8ct6,2023-04-19,2022-05-13
-6cty,2018-04-04,2018-03-23
-4ctm,2014-08-06,2014-03-15
-8ctz,2022-08-31,2022-05-16
-7ct7,2021-08-18,2020-08-18
-6cti,2018-06-20,2018-03-23
-5ct0,2016-11-30,2015-07-23
-6ctl,2018-06-20,2018-03-23
-6cth,2018-04-11,2018-03-23
-7ctz,2022-02-23,2020-08-20
-1ctu,1995-05-08,1995-02-11
-3ctz,2008-05-27,2008-04-15
-7cta,2021-03-03,2020-08-18
-4ctb,2014-05-28,2014-03-12
-8cts,2023-06-14,2022-05-16
-5ct4,2015-11-04,2015-07-23
-3ct4,2008-10-21,2008-04-11
-5cte,2015-10-14,2015-07-23
-4ctn,2014-08-06,2014-03-15
-1ctt,1995-05-08,1995-02-11
-6ctt,2018-06-20,2018-03-23
-2ct0,2005-11-23,2005-05-23
-3ct8,2008-04-29,2008-04-11
-4ct1,2014-05-28,2014-03-11
-4ct7,2014-05-07,2014-03-12
-1ctm,1994-05-31,1994-01-02
-6ctw,2018-06-20,2018-03-23
-4ct9,2015-01-21,2014-03-12
-1ctr,1994-12-20,1994-09-21
-7ctm,2021-09-01,2020-08-19
-4cts,1984-07-20,1984-01-27
-3cth,2008-06-10,2008-04-14
-2ct8,2005-09-20,2005-05-23
-8ct3,2022-07-20,2022-05-13
-7ct9,2021-03-03,2020-08-18
-6ctp,2018-06-20,2018-03-23
-4ctw,2014-05-07,2014-03-15
-4ctt,2014-05-07,2014-03-15
-3ctp,2008-05-06,2008-04-14
-6ctr,2018-06-20,2018-03-23
-7ctg,2021-01-06,2020-08-18
-5lyx,2017-08-16,2016-09-29
-3lye,2010-06-16,2010-02-26
-7ly3,2021-04-14,2021-03-05
-4lys,2014-01-15,2013-07-31
-4lyf,2013-11-27,2013-07-31
-3ly1,2010-03-31,2010-02-25
-4lyx,2014-08-06,2013-07-31
-4lyn,2013-10-02,2013-07-31
-4lyc,2015-02-25,2013-07-30
-5lyb,2016-11-23,2016-09-26
-1ly8,2002-06-14,2002-06-07
-5lyn,2017-10-25,2016-09-28
-6lyb,2020-07-08,2020-02-13
-7lyu,2022-06-15,2021-03-08
-6lyk,2021-02-17,2020-02-14
-1ly3,2002-08-28,2002-06-06
-4ly3,2013-08-14,2013-07-30
-5lyr,2017-01-11,2016-09-28
-7lyy,2021-11-24,2021-03-08
-7lyq,2021-03-31,2021-03-07
-4ly1,2013-08-21,2013-07-30
-5lyl,2016-10-26,2016-09-28
-6lyy,2020-12-23,2020-02-16
-6lym,2021-02-17,2020-02-14
-1lyl,1995-10-15,1995-05-03
-7ly9,2021-08-18,2021-03-06
-7ly5,2022-02-02,2021-03-05
-7ly8,2022-03-09,2021-03-06
-3lyb,2010-03-23,2010-02-26
-5ly8,2017-03-22,2016-09-26
-5ly3,2016-11-30,2016-09-23
-4ly5,2014-06-04,2013-07-30
-7lyh,2021-03-17,2021-03-07
-6ly6,2020-07-08,2020-02-13
-6lyr,2021-01-06,2020-02-15
-6ly3,2020-07-08,2020-02-13
-3lyd,2010-03-09,2010-02-26
-9lyz,1980-02-27,1979-12-06
-5lyj,2017-01-18,2016-09-28
-7lyp,2021-03-31,2021-03-07
-7lyn,2021-03-31,2021-03-07
-4ly0,2013-08-14,2013-07-30
-7ly2,2021-04-14,2021-03-05
-7lyx,2022-08-17,2021-03-08
-6lya,2020-07-08,2020-02-13
-7lyk,2021-03-31,2021-03-07
-4lyb,2015-02-25,2013-07-30
-3lyr,2010-03-16,2010-02-28
-7ly0,2021-04-14,2021-03-05
-5lyi,2016-10-26,2016-09-28
-6ly5,2020-10-21,2020-02-13
-4lyu,2014-08-06,2013-07-31
-6ly8,2020-09-09,2020-02-13
-1lyx,2003-01-28,2002-06-10
-1ly4,2002-08-28,2002-06-06
-5ly7,2017-05-17,2016-09-25
-6lyn,2021-02-24,2020-02-14
-7lyi,2021-03-17,2021-03-07
-5lyd,2016-10-26,2016-09-27
-3ly5,2010-05-12,2010-02-26
-4lya,2015-02-04,2013-07-30
-6ly7,2020-07-08,2020-02-13
-4lyj,2013-11-27,2013-07-31
-6lyh,2020-03-04,2020-02-14
-4lyi,2014-01-15,2013-07-31
-6lyf,2020-08-12,2020-02-14
-1lya,1994-01-31,1993-04-22
-1lyb,1994-01-31,1993-04-22
-6lyc,2020-07-01,2020-02-14
-6ly4,2020-04-29,2020-02-13
-4lyh,2013-11-27,2013-07-31
-6lyg,2020-10-07,2020-02-14
-5ly0,2017-10-25,2016-09-23
-5ly9,2017-09-20,2016-09-26
-4ly9,2013-11-20,2013-07-30
-3ly0,2010-03-09,2010-02-25
-7lyt,2021-08-04,2021-03-08
-7lym,2021-03-31,2021-03-07
-7lyo,2021-03-31,2021-03-07
-5lyq,2017-04-26,2016-09-28
-2ly0,2013-01-09,2012-09-10
-1ly2,2002-07-05,2002-06-06
-6lyo,2021-02-17,2020-02-15
-2lyb,2013-02-13,2012-09-14
-6lyl,2021-02-17,2020-02-14
-7lyb,2021-07-28,2021-03-06
-1lyc,2002-06-14,2002-06-07
-7lyd,2021-11-24,2021-03-06
-1ly9,2002-06-14,2002-06-07
-3ly2,2010-04-28,2010-02-26
-3ly6,2010-08-18,2010-02-26
-7lyl,2021-03-31,2021-03-07
-3ly4,2011-03-02,2010-02-26
-7ly4,2022-02-02,2021-03-05
-7ly1,2021-09-01,2021-03-05
-5ly1,2017-04-12,2016-09-23
-4lyw,2014-01-15,2013-07-31
-7ly7,2022-02-02,2021-03-05
-4lye,2013-10-09,2013-07-31
-7ly6,2022-02-02,2021-03-05
-5lyw,2017-08-16,2016-09-28
-4ly4,2013-08-28,2013-07-30
-4lyk,2014-01-29,2013-07-31
-7lye,2021-05-19,2021-03-06
-5lyf,2016-10-26,2016-09-28
-5lyh,2016-12-21,2016-09-28
-1lyk,2002-06-14,2002-06-07
-5ly2,2017-04-12,2016-09-23
-3lyi,2010-03-16,2010-02-26
-4lyq,2014-08-06,2013-07-31
-5lyy,2016-12-21,2016-09-29
-3w0r,2013-08-07,2012-11-02
-5w0z,2017-08-16,2017-06-01
-2w0u,2009-11-10,2008-10-10
-1w03,2005-05-04,2004-06-01
-3w0g,2013-10-09,2012-10-30
-5w0i,2018-03-07,2017-05-30
-3w09,2013-05-01,2012-10-25
-1w0e,2004-07-22,2004-06-03
-6w0j,2020-07-08,2020-02-29
-8w0y,2024-03-27,2024-02-14
-6w0i,2020-07-08,2020-02-29
-8w0c,2024-02-21,2024-02-13
-5w0l,2018-03-07,2017-05-31
-2w0f,2009-11-17,2008-08-14
-2w0q,2008-12-16,2008-08-20
-3w0y,2013-11-13,2012-11-05
-5w0w,2018-01-17,2017-06-01
-7w0g,2022-02-02,2021-11-18
-5w0q,2018-03-07,2017-05-31
-2w0v,2009-11-17,2008-10-10
-2w0a,2009-01-20,2008-08-12
-3w07,2013-02-20,2012-10-22
-2w0o,2008-08-26,2008-08-20
-8w0v,2024-03-27,2024-02-14
-2w05,2008-10-14,2008-08-08
-7w0k,2022-03-02,2021-11-18
-6w0l,2020-04-22,2020-03-01
-7w01,2022-04-27,2021-11-17
-2w0p,2008-09-30,2008-08-20
-1w0o,2004-07-08,2004-06-09
-3w0u,2013-11-06,2012-11-02
-2w0s,2008-10-21,2008-10-08
-6w00,2020-07-29,2020-02-28
-8w0w,2024-03-27,2024-02-14
-6w0w,2020-09-23,2020-03-03
-7w0e,2022-04-27,2021-11-18
-7w0d,2022-04-27,2021-11-18
-7w0y,2023-03-22,2021-11-18
-1w0p,2004-07-08,2004-06-09
-1w0j,2004-07-08,2004-06-08
-7w0t,2022-08-10,2021-11-18
-8w0l,2024-02-21,2024-02-13
-6w0n,2020-09-23,2020-03-02
-2w0x,2009-11-24,2008-10-10
-3w0t,2013-11-06,2012-11-02
-2w0t,2009-01-20,2008-10-10
-2w0h,2009-04-28,2008-08-18
-7w0m,2022-07-27,2021-11-18
-6w06,2020-12-16,2020-02-29
-6w0u,2021-03-03,2020-03-02
-3w0l,2013-07-17,2012-10-31
-2w02,2009-01-13,2008-08-08
-2w03,2009-01-13,2008-08-08
-6w03,2020-04-15,2020-02-28
-8w0b,2024-02-21,2024-02-13
-6w0z,2020-09-23,2020-03-03
-1w06,2005-05-04,2004-06-01
-3w0f,2013-01-16,2012-10-30
-6w0a,2020-07-08,2020-02-29
-5w0u,2017-08-16,2017-05-31
-6w02,2020-03-11,2020-02-28
-5w0m,2017-06-28,2017-05-31
-3w0s,2013-08-07,2012-11-02
-6w0d,2020-07-08,2020-02-29
-6w0m,2020-09-23,2020-03-02
-7w02,2022-04-20,2021-11-17
-5w0a,2018-05-30,2017-05-30
-1w05,2005-05-04,2004-06-01
-7w0h,2022-12-14,2021-11-18
-2w0j,2009-02-10,2008-08-18
-1w07,2004-12-15,2004-06-01
-8w0x,2024-03-27,2024-02-14
-5w0n,2017-06-28,2017-05-31
-6w08,2020-03-11,2020-02-29
-7w06,2022-10-26,2021-11-17
-3w0c,2013-11-13,2012-10-29
-6w07,2020-12-16,2020-02-29
-7w07,2022-10-26,2021-11-17
-6w0c,2020-07-08,2020-02-29
-8w0j,2024-02-21,2024-02-13
-7w0r,2022-12-14,2021-11-18
-5w0o,2017-06-28,2017-05-31
-1w0f,2004-07-22,2004-06-03
-1w0k,2004-07-08,2004-06-08
-1w0z,2008-05-20,2004-06-15
-5w0v,2017-11-01,2017-05-31
-2w0c,2008-09-23,2008-08-13
-2w0w,2009-11-17,2008-10-10
-2w06,2008-09-23,2008-08-08
-7w0l,2022-07-27,2021-11-18
-1w0y,2005-01-21,2004-05-27
-2w0z,2009-05-26,2008-10-13
-6w0r,2020-09-23,2020-03-02
-7w00,2022-12-14,2021-11-17
-7w0j,2022-11-23,2021-11-18
-2w0m,2009-05-19,2008-08-19
-6w0e,2020-07-08,2020-02-29
-6w0x,2020-09-23,2020-03-03
-5w08,2018-02-14,2017-05-30
-1w0n,2004-10-27,2004-06-09
-3w0q,2013-08-07,2012-11-02
-1w0c,2004-09-30,2004-06-02
-5w0b,2017-06-28,2017-05-30
-3w00,2012-12-26,2012-10-17
-6w0q,2020-06-10,2020-03-02
-5w0c,2017-09-13,2017-05-30
-1w0x,2005-01-14,2004-06-14
-3w0i,2013-10-09,2012-10-30
-7w0z,2022-03-02,2021-11-18
-6w0f,2020-07-08,2020-02-29
-3w0j,2013-10-09,2012-10-30
-5w0r,2017-08-16,2017-05-31
-6w0s,2020-11-11,2020-03-02
-2w08,2009-04-14,2008-08-12
-3w0n,2013-08-07,2012-11-02
-5w0e,2018-02-21,2017-05-30
-3w0a,2013-11-13,2012-10-25
-2w0d,2009-03-03,2008-08-13
-5w0g,2018-04-11,2017-05-30
-3w0p,2013-08-07,2012-11-02
-8w0m,2024-02-21,2024-02-13
-8w0h,2024-02-21,2024-02-13
-3w08,2013-02-20,2012-10-24
-2w09,2009-01-20,2008-08-12
-2w00,2008-12-16,2008-08-08
-3w0h,2013-10-09,2012-10-30
-8w0d,2024-02-21,2024-02-13
-1w0i,2004-11-10,2004-06-04
-2w0b,2009-01-20,2008-08-12
-5w0f,2018-03-07,2017-05-30
-7w0s,2022-08-10,2021-11-18
-6w0h,2020-07-08,2020-02-29
-5w0p,2017-08-09,2017-05-31
-6w05,2020-07-29,2020-02-29
-1w0v,2005-03-07,2004-06-14
-3w0o,2013-08-07,2012-11-02
-1w0h,2004-09-30,2004-06-04
-8w09,2024-04-17,2024-02-13
-1w0w,2005-03-07,2004-06-14
-1w04,2005-05-04,2004-06-01
-6w04,2020-03-18,2020-02-29
-5w0d,2018-02-14,2017-05-30
-6w0t,2021-01-13,2020-03-02
-1w0g,2004-07-22,2004-06-03
-6w0y,2020-09-23,2020-03-03
-7w05,2022-11-23,2021-11-17
-6w0b,2020-07-08,2020-02-29
-7w0c,2022-04-27,2021-11-18
-6w0g,2020-07-08,2020-02-29
-1xfu,2005-05-03,2004-09-15
-5xfa,2017-08-23,2017-04-09
-2xfs,2011-06-29,2010-05-26
-1xff,2004-09-28,2004-09-14
-7xf7,2022-04-13,2022-04-01
-1xfc,2005-08-16,2004-09-14
-1xf8,2005-05-31,2004-09-14
-1xfi,2004-09-28,2004-09-14
-4xf3,2016-04-06,2014-12-25
-1xf9,2004-12-28,2004-09-14
-4xfi,2016-02-24,2014-12-26
-5xfe,2017-08-30,2017-04-10
-7xfz,2023-08-09,2022-04-02
-1xfv,2005-05-03,2004-09-15
-5xff,2018-09-05,2017-04-10
-1xfg,2004-09-28,2004-09-14
-7xfw,2022-05-11,2022-04-02
-1xfo,2004-10-05,2004-09-15
-6xfj,2020-09-16,2020-06-15
-5xfd,2017-08-30,2017-04-10
-2xf2,2010-06-16,2010-05-20
-2xfy,2010-12-01,2010-05-28
-1xf1,2005-11-22,2004-09-13
-4xf7,2015-06-03,2014-12-26
-6xfs,2020-07-15,2020-06-16
-4xfb,2016-02-24,2014-12-26
-4xfa,2016-02-24,2014-12-26
-4xf1,2016-04-06,2014-12-25
-6xfn,2020-06-24,2020-06-15
-5xfp,2017-09-13,2017-04-11
-2xfg,2011-06-22,2010-05-24
-1xfa,2004-12-28,2004-09-14
-1xfe,2004-11-02,2004-09-14
-1xf0,2004-10-26,2004-09-13
-8xf3,2024-05-22,2023-12-13
-2xf0,2010-06-30,2010-05-19
-4xf0,2016-03-16,2014-12-25
-2xfq,2010-10-06,2010-05-26
-2xfi,2010-07-07,2010-05-24
-6xfp,2021-03-10,2020-06-16
-1xfx,2005-05-03,2004-09-15
-4xf5,2015-01-28,2014-12-26
-7xfg,2023-04-12,2022-04-01
-2xff,2010-12-01,2010-05-28
-6xfv,2020-08-12,2020-06-16
-1xf6,2004-11-30,2004-09-14
-1xfy,2005-05-03,2004-09-15
-6xf4,2021-02-17,2020-06-15
-2xf3,2011-06-29,2010-05-20
-6xfa,2021-02-24,2020-06-15
-8xfq,2024-05-15,2023-12-14
-5xf1,2017-05-24,2017-04-06
-1xfw,2005-05-03,2004-09-15
-5xfi,2017-10-18,2017-04-10
-1xf5,2005-05-31,2004-09-14
-5xfq,2017-09-13,2017-04-11
-2xfk,2010-07-07,2010-05-24
-2xf8,2011-06-08,2010-05-20
-2xfu,2010-06-09,2010-05-26
-4xfz,2015-06-10,2014-12-29
-5xfc,2017-08-30,2017-04-10
-7xfx,2022-05-11,2022-04-02
-2xfw,2010-09-22,2010-05-28
-4xfc,2016-02-24,2014-12-26
-2xfn,2010-10-06,2010-05-26
-7xf3,2023-02-08,2022-03-31
-4xfw,2015-08-05,2014-12-29
-1xf2,2005-04-12,2004-09-13
-6xf9,2021-02-24,2020-06-15
-6xfr,2021-06-23,2020-06-16
-4xfp,2016-01-13,2014-12-28
-5xfm,2018-02-28,2017-04-10
-6xfi,2021-04-21,2020-06-15
-2xfd,2010-06-16,2010-05-21
-6xf5,2020-09-02,2020-06-15
-4xf9,2016-02-24,2014-12-26
-5xfo,2017-09-13,2017-04-11
-5xfh,2017-10-18,2017-04-10
-6xf6,2020-09-02,2020-06-15
-7xfy,2022-05-11,2022-04-02
-4xfn,2015-10-21,2014-12-27
-4xfo,2015-10-21,2014-12-27
-8xfd,2024-05-15,2023-12-13
-5xfr,2017-09-13,2017-04-11
-1xfz,2005-05-03,2004-09-15
-4xfe,2015-01-28,2014-12-26
-2xfj,2010-07-07,2010-05-24
-8xfr,2024-05-15,2023-12-14
-5xfv,2018-04-25,2017-04-11
-8xf0,2024-05-22,2023-12-13
-4xfk,2015-03-11,2014-12-27
-6xf3,2021-02-17,2020-06-15
-6xfo,2020-06-24,2020-06-15
-8xf1,2024-05-22,2023-12-13
-4xfh,2016-02-24,2014-12-26
-4xfg,2016-02-24,2014-12-26
-1xfq,2005-08-16,2004-09-15
-2xfp,2010-10-06,2010-05-26
-1xf7,2004-12-14,2004-09-14
-7xfa,2022-10-12,2022-04-01
-4xff,2016-02-24,2014-12-26
-2xfe,2010-06-16,2010-05-21
-2xfo,2010-10-06,2010-05-26
-7xf0,2023-07-26,2022-03-31
-5xfj,2018-08-08,2017-04-10
-1xfn,2005-08-16,2004-09-15
-2xfh,2010-09-29,2010-05-24
-2xfm,2011-01-26,2010-05-27
-4xfj,2015-01-14,2014-12-27
-1xfd,2004-10-26,2004-09-14
-7xft,2023-04-05,2022-04-02
-5xf9,2017-08-23,2017-04-09
-8xf2,2024-05-22,2023-12-13
-4xf6,2015-06-03,2014-12-26
-2xf4,2010-07-28,2010-05-20
-5xfn,2017-09-13,2017-04-11
-7xf8,2022-04-13,2022-04-01
-4xf4,2016-03-16,2014-12-26
-2xfv,2010-06-23,2010-05-27
-2lh7,1983-01-20,1982-04-23
-5lht,2017-07-05,2016-07-12
-2lh5,1983-01-20,1982-04-23
-4lhy,2013-10-09,2013-07-01
-1lh1,1983-01-20,1982-04-23
-5lhl,2017-08-16,2016-07-12
-5lhs,2017-06-28,2016-07-12
-1lh7,1983-01-20,1982-04-23
-4lhc,2013-10-16,2013-07-01
-3lhc,2010-02-09,2010-01-21
-2lhb,1986-01-21,1985-08-16
-7lha,2022-02-09,2021-01-21
-6lh4,2020-12-09,2019-12-06
-4lhk,2014-09-24,2013-07-01
-2lh3,1983-01-20,1982-04-23
-1lhw,2002-10-23,2002-04-17
-4lho,2013-07-24,2013-07-01
-1lht,1995-06-03,1995-02-01
-3lhd,2010-05-19,2010-01-22
-2lh8,2011-09-14,2011-08-05
-7lhj,2021-02-10,2021-01-25
-3lht,2010-06-16,2010-01-23
-4lhi,2014-07-02,2013-07-01
-3lhm,1992-04-15,1991-10-02
-6lhf,2020-12-09,2019-12-08
-5lhh,2017-02-22,2016-07-11
-6lhd,2021-03-31,2019-12-07
-1lh3,1983-01-20,1982-04-23
-1lhr,2003-02-11,2002-04-17
-7lhf,2021-06-02,2021-01-22
-5lhp,2017-06-28,2016-07-12
-2lhy,2012-04-04,2011-08-18
-7lh8,2022-07-06,2021-01-21
-3lhu,2010-06-16,2010-01-23
-5lha,2017-03-22,2016-07-10
-7lht,2021-06-16,2021-01-26
-6lhn,2020-01-22,2019-12-09
-6lh9,2020-12-09,2019-12-07
-4lh4,2013-12-25,2013-06-30
-6lhg,2020-12-09,2019-12-08
-7lhw,2021-06-16,2021-01-26
-1lhd,1996-11-08,1994-12-27
-4lhv,2013-10-09,2013-07-01
-5lhq,2017-06-28,2016-07-12
-2lhw,2012-04-04,2011-08-18
-5lh8,2016-08-10,2016-07-08
-7lhp,2021-08-11,2021-01-26
-7lhb,2021-04-14,2021-01-21
-3lhw,2010-06-16,2010-01-23
-1lhe,1996-11-08,1994-12-27
-4lh5,2013-12-25,2013-06-30
-2lhn,2012-06-27,2011-08-12
-1lhg,1996-11-08,1994-12-27
-2lhx,2012-04-04,2011-08-18
-6lhh,2020-12-09,2019-12-08
-4lhh,2014-04-02,2013-07-01
-7lhn,2021-04-14,2021-01-25
-3lhl,2010-02-23,2010-01-22
-7lhm,2021-04-14,2021-01-25
-5lhf,2016-11-09,2016-07-11
-3lhv,2010-06-16,2010-01-23
-5lhk,2016-10-05,2016-07-12
-5lh9,2017-03-22,2016-07-10
-2lh1,1983-01-20,1982-04-23
-6lhe,2020-09-16,2019-12-07
-6lhj,2020-11-11,2019-12-09
-7lho,2021-04-14,2021-01-26
-5lhu,2017-06-21,2016-07-12
-1lh0,2002-05-08,2002-04-16
-4lhw,2013-10-09,2013-07-01
-4lh7,2013-12-25,2013-06-30
-4lht,2013-07-24,2013-07-01
-6lh7,2020-12-02,2019-12-06
-3lhz,2010-06-16,2010-01-23
-7lh7,2021-06-23,2021-01-21
-1lhc,1996-11-08,1994-12-27
-4lh8,2014-05-21,2013-07-01
-7lhu,2021-07-07,2021-01-26
-3lhj,2010-04-14,2010-01-22
-2lh6,1983-01-20,1982-04-23
-4lh6,2013-12-25,2013-06-30
-5lh4,2018-01-17,2016-07-08
-3lho,2010-03-09,2010-01-22
-6lhi,2020-12-09,2019-12-09
-4lhz,2013-10-09,2013-07-01
-1lh5,1983-01-20,1982-04-23
-4lhm,2014-04-09,2013-07-01
-3lhh,2010-02-02,2010-01-22
-4lh3,2013-08-28,2013-06-30
-7lh5,2021-06-02,2021-01-21
-3lhr,2010-05-12,2010-01-22
-5lhd,2017-04-05,2016-07-11
-7lhs,2021-07-07,2021-01-26
-5lhe,2016-11-09,2016-07-11
-5lhv,2017-08-02,2016-07-13
-1lhv,2002-10-23,2002-04-17
-1lh2,1983-01-20,1982-04-23
-2lhz,2012-04-04,2011-08-18
-3lhy,2010-06-16,2010-01-23
-3lhs,2010-02-09,2010-01-23
-1lhn,2002-10-23,2002-04-17
-3lhg,2010-04-21,2010-01-22
-4lhl,2014-09-24,2013-07-01
-4lhd,2013-10-16,2013-07-01
-2lhh,2012-08-29,2011-08-10
-4lhu,2013-10-02,2013-07-01
-7lhx,2021-03-17,2021-01-26
-6lhr,2021-01-20,2019-12-09
-7lhy,2021-09-08,2021-01-26
-7lhe,2021-06-02,2021-01-22
-5lhi,2017-02-22,2016-07-12
-3lh0,2010-03-23,2010-01-21
-7lh2,2021-08-25,2021-01-21
-1lh6,1983-01-20,1982-04-23
-1lho,2002-10-23,2002-04-17
-1lhf,1996-11-08,1994-12-27
-2lh2,1983-01-20,1982-04-23
-7lhz,2021-05-12,2021-01-26
-5lhg,2017-02-22,2016-07-11
-4lhn,2014-09-24,2013-07-01
-1lhs,1995-06-03,1995-02-01
-2lhi,2012-08-29,2011-08-10
-1lhu,2002-10-23,2002-04-17
-5lhm,2017-05-24,2016-07-12
-3lhb,1999-01-20,1999-01-12
-5lhb,2016-10-12,2016-07-10
-5onh,2017-11-15,2017-08-03
-5onq,2018-08-29,2017-08-04
-8on8,2024-02-14,2023-04-01
-8on2,2023-12-06,2023-03-31
-3onb,2011-08-17,2010-08-28
-5on3,2017-11-15,2017-08-02
-8onn,2023-08-30,2023-04-03
-6ona,2019-05-01,2019-04-20
-7on3,2022-03-02,2021-05-25
-3onn,2011-03-02,2010-08-30
-1on3,2003-05-20,2003-02-26
-5onx,2017-11-29,2017-08-04
-6on9,2019-05-15,2019-04-20
-8onl,2023-08-30,2023-04-03
-7onk,2021-08-04,2021-05-25
-3onz,2011-09-07,2010-08-30
-1ony,2003-05-20,2003-03-02
-1on8,2003-04-22,2003-02-27
-8on0,2023-12-06,2023-03-31
-2onk,2007-03-06,2007-01-24
-6on3,2019-06-26,2019-04-19
-7onn,2021-08-04,2021-05-25
-2onx,2007-02-06,2007-01-24
-8onv,2023-06-07,2023-04-04
-5one,2017-09-06,2017-08-03
-3onr,2011-03-16,2010-08-30
-5onw,2017-11-22,2017-08-04
-5on5,2017-12-13,2017-08-02
-5onp,2018-08-29,2017-08-04
-7on9,2022-01-26,2021-05-25
-8on3,2023-12-06,2023-03-31
-5on4,2017-12-13,2017-08-02
-7onw,2021-08-04,2021-05-26
-4onc,2014-04-02,2014-01-28
-3oni,2010-10-06,2010-08-29
-4on1,2014-04-09,2014-01-28
-2onm,2007-03-06,2007-01-24
-1on6,2003-04-22,2003-02-27
-5onn,2018-08-22,2017-08-04
-3one,2011-08-31,2010-08-28
-8onx,2024-02-14,2023-04-04
-6on6,2019-05-15,2019-04-20
-6on4,2020-07-08,2019-04-19
-5on8,2017-12-13,2017-08-03
-5ont,2018-08-29,2017-08-04
-8onj,2023-08-30,2023-04-03
-6onb,2019-05-15,2019-04-20
-6onz,2019-09-11,2019-04-22
-6onh,2019-10-23,2019-04-22
-4onf,2014-06-11,2014-01-28
-6onr,2019-09-25,2019-04-22
-5onj,2018-08-29,2017-08-03
-1one,1997-01-11,1995-12-05
-3onf,2011-08-31,2010-08-28
-7onm,2021-12-01,2021-05-25
-2ong,2007-03-06,2007-01-23
-5on0,2017-12-13,2017-08-02
-8oni,2024-04-10,2023-04-03
-7on2,2022-03-02,2021-05-25
-7ong,2022-12-14,2021-05-25
-6one,2019-10-23,2019-04-22
-4ond,2014-10-29,2014-01-28
-6onm,2019-09-04,2019-04-22
-4onj,2014-06-04,2014-01-28
-5on2,2017-11-15,2017-08-02
-1on9,2003-05-20,2003-02-27
-1onw,2003-05-06,2003-03-02
-2onc,2008-03-04,2007-01-23
-1onp,2003-03-18,2003-02-28
-7on4,2022-03-02,2021-05-25
-4onk,2014-07-02,2014-01-28
-5on1,2017-12-13,2017-08-02
-6oni,2020-03-04,2019-04-22
-6onf,2019-10-23,2019-04-22
-1on7,2003-07-29,2003-02-27
-2onw,2007-02-06,2007-01-24
-2oni,2007-04-17,2007-01-24
-7on0,2021-06-23,2021-05-24
-8on7,2024-02-14,2023-04-01
-4ono,2014-10-08,2014-01-28
-7onq,2021-12-01,2021-05-25
-2ony,2007-10-09,2007-01-24
-8onm,2024-04-10,2023-04-03
-8onq,2023-08-02,2023-04-03
-3onw,2010-11-24,2010-08-30
-8ony,2024-02-21,2023-04-04
-4on3,2014-09-24,2014-01-28
-5on6,2018-02-28,2017-08-03
-7ond,2021-07-21,2021-05-25
-1ono,2003-03-18,2003-02-28
-2on5,2007-08-07,2007-01-23
-8on9,2024-02-14,2023-04-01
-6onk,2019-09-11,2019-04-22
-2onv,2007-02-06,2007-01-24
-4onu,2014-04-30,2014-01-29
-2on3,2007-07-17,2007-01-23
-8onh,2023-09-13,2023-04-03
-5onz,2018-08-29,2017-08-04
-6onj,2020-03-04,2019-04-22
-6ong,2019-09-11,2019-04-22
-5ons,2018-05-23,2017-08-04
-2ons,2007-03-06,2007-01-24
-7onr,2021-09-15,2021-05-25
-2on6,2007-05-22,2007-01-23
-4ona,2014-03-19,2014-01-28
-1ons,2004-01-20,2003-02-28
-2on9,2007-01-30,2007-01-23
-1ong,2003-12-09,2003-02-27
-6onq,2019-05-08,2019-04-22
-7ons,2021-09-15,2021-05-25
-5onl,2018-08-29,2017-08-03
-5ond,2018-06-06,2017-08-03
-1onf,2003-05-06,2003-02-27
-4onx,2014-03-05,2014-01-29
-5ony,2017-11-29,2017-08-04
-6onc,2019-07-24,2019-04-21
-7ono,2021-08-04,2021-05-25
-6onv,2019-10-23,2019-04-22
-4onh,2014-10-08,2014-01-28
-2one,1998-01-14,1997-09-08
-5onk,2018-08-29,2017-08-03
-4onv,2015-01-14,2014-01-29
-7onb,2021-08-04,2021-05-25
-4onn,2015-05-06,2014-01-28
-1on2,2003-07-15,2003-02-26
-2onj,2007-03-13,2007-01-24
-4onr,2014-07-09,2014-01-28
-8ond,2023-10-25,2023-04-02
-7oni,2021-09-15,2021-05-25
-6on1,2019-06-26,2019-04-19
-4onm,2015-05-06,2014-01-28
-7onp,2021-12-01,2021-05-25
-4ong,2014-06-11,2014-01-28
-3ony,2011-05-11,2010-08-30
-5onr,2018-08-29,2017-08-04
-6ont,2020-03-25,2019-04-22
-7onj,2021-09-01,2021-05-25
-2onp,2007-03-06,2007-01-24
-1on1,2003-07-15,2003-02-26
-6on2,2019-05-01,2019-04-19
-2onh,2007-03-06,2007-01-24
-6ony,2020-01-29,2019-04-22
-2ona,2007-01-30,2007-01-23
-2onb,2007-04-10,2007-01-23
-6onx,2019-09-25,2019-04-22
-5onm,2018-08-22,2017-08-04
-7onf,2022-04-06,2021-05-25
-5ono,2018-08-22,2017-08-04
-1ona,1997-09-17,1996-07-07
-1onz,2003-05-20,2003-03-02
-1onq,2003-08-05,2003-02-28
-3onc,2011-08-17,2010-08-28
-3ond,2011-08-31,2010-08-28
-8ona,2024-02-14,2023-04-01
-7onv,2021-12-01,2021-05-26
-1onx,2003-05-06,2003-03-02
-2onf,2007-02-06,2007-01-23
-8on1,2023-12-06,2023-03-31
-2onr,2007-03-06,2007-01-24
-5onv,2018-06-13,2017-08-04
-5ong,2017-11-22,2017-08-03
-2onz,2007-10-09,2007-01-25
-1onk,2004-02-28,2003-02-28
-6on5,2019-10-16,2019-04-20
-7onu,2021-08-11,2021-05-26
-5oni,2017-12-27,2017-08-03
-8one,2023-07-19,2023-04-02
-5on9,2017-12-13,2017-08-03
-3on4,2010-09-22,2010-08-27
-1onh,2003-12-09,2003-02-27
-4onq,2014-06-04,2014-01-28
-7ont,2021-09-15,2021-05-25
-7ona,2022-12-14,2021-05-25
-6ond,2019-07-24,2019-04-21
-4ont,2014-11-26,2014-01-29
-5on7,2018-03-07,2017-08-03
-3mnk,2010-07-14,2010-04-21
-6mn8,2018-10-17,2018-10-01
-7mn8,2021-11-10,2021-04-30
-1mnp,1995-09-15,1995-01-27
-3mns,2010-05-05,2010-04-22
-5mnh,2018-01-17,2016-12-13
-3mn0,2010-08-11,2010-04-20
-5mn6,2016-12-21,2016-12-12
-7mnx,2022-06-15,2021-05-01
-1mn0,2002-09-18,2002-09-04
-3mna,2011-04-20,2010-04-21
-1mnf,2003-10-07,2002-09-05
-1mn7,2002-10-02,2002-09-05
-7mnw,2022-06-15,2021-05-01
-5mnl,2018-01-17,2016-12-13
-5mna,2017-05-24,2016-12-13
-7mnh,2021-11-24,2021-04-30
-6mn5,2018-10-24,2018-10-01
-1mnk,1995-04-20,1995-01-11
-3mnq,2011-04-27,2010-04-22
-6mn0,2018-10-24,2018-10-01
-5mnr,2017-06-21,2016-12-13
-5mnf,2018-01-17,2016-12-13
-3mnd,2011-09-28,2010-04-21
-6mn1,2018-10-24,2018-10-01
-2mnz,2014-08-06,2014-04-16
-6mnh,2019-03-27,2018-10-01
-4mnq,2013-11-13,2013-09-11
-3mn5,2010-06-02,2010-04-21
-5mn2,2017-12-13,2016-12-12
-3mn7,2010-05-26,2010-04-21
-6mnc,2019-04-03,2018-10-01
-1mnv,2002-11-22,2002-09-06
-6mnp,2019-04-17,2018-10-02
-4mny,2014-02-05,2013-09-11
-5mnj,2017-05-31,2016-12-13
-1mne,1996-08-17,1995-04-20
-3mnb,2010-05-05,2010-04-21
-6mnx,2020-04-15,2018-10-03
-5mnw,2018-06-13,2016-12-13
-5mn8,2017-01-11,2016-12-12
-4mnc,2013-09-25,2013-09-10
-7mn6,2021-10-27,2021-04-30
-5mno,2018-01-17,2016-12-13
-7mny,2022-06-15,2021-05-01
-5mnu,2017-07-12,2016-12-13
-1mny,2002-11-13,2002-09-06
-4mna,2013-12-04,2013-09-10
-3mnc,2010-05-05,2010-04-21
-4mnt,2014-03-05,2013-09-11
-7mnb,2022-05-18,2021-04-30
-5mnc,2017-05-24,2016-12-13
-7mnq,2022-06-15,2021-05-01
-6mn3,2018-10-24,2018-10-01
-1mng,1994-10-15,1994-07-13
-4mni,2013-09-25,2013-09-10
-4mnm,2014-09-17,2013-09-11
-1mnh,1995-05-08,1995-01-11
-5mn4,2016-12-21,2016-12-12
-3mnn,2011-04-06,2010-04-22
-2mnr,1994-01-31,1993-07-06
-4mn9,2014-10-08,2013-09-10
-5mn7,2017-01-11,2016-12-12
-4mnp,2014-07-09,2013-09-11
-3mne,2010-09-15,2010-04-21
-5mnq,2018-01-17,2016-12-13
-4mn8,2013-12-04,2013-09-10
-5mnz,2018-01-17,2016-12-13
-5mnk,2018-01-17,2016-12-13
-3mnz,2010-11-17,2010-04-22
-5mn1,2017-05-24,2016-12-12
-7mnr,2022-06-15,2021-05-01
-7mnz,2022-06-15,2021-05-01
-5mny,2017-05-24,2016-12-13
-6mnf,2018-10-31,2018-10-01
-2mny,2014-08-06,2014-04-16
-3mnx,2010-05-05,2010-04-22
-4mnv,2014-02-05,2013-09-11
-4mnd,2014-07-02,2013-09-10
-7mnt,2022-06-15,2021-05-01
-3mnr,2010-08-11,2010-04-22
-1mn1,1997-09-04,1997-04-26
-7mnf,2022-05-18,2021-04-30
-6mn7,2019-03-06,2018-10-01
-5mnn,2018-01-17,2016-12-13
-4mn7,2014-08-06,2013-09-10
-6mni,2019-10-16,2018-10-01
-1mnj,1995-04-20,1995-01-11
-4mng,2013-12-18,2013-09-10
-1mnu,1999-05-06,1999-04-30
-3mn8,2010-07-28,2010-04-21
-5mng,2018-01-17,2016-12-13
-5mnv,2018-02-28,2016-12-13
-1mn2,1997-09-04,1997-04-26
-7mn7,2022-05-18,2021-04-30
-3mnh,2010-07-14,2010-04-21
-4mns,2015-03-11,2013-09-11
-7mng,2021-05-12,2021-04-30
-4mne,2014-06-18,2013-09-10
-3mno,2010-09-15,2010-04-22
-3mnp,2010-09-15,2010-04-22
-4mn3,2014-04-02,2013-09-09
-3mnj,2010-07-14,2010-04-21
-4mnf,2014-06-18,2013-09-10
-3mn6,2010-06-02,2010-04-21
-6mn2,2018-10-24,2018-10-01
-1mnz,2002-09-25,2002-09-06
-6mny,2019-01-30,2018-10-03
-7mna,2022-05-18,2021-04-30
-7mnv,2022-06-15,2021-05-01
-1mno,1998-08-19,1998-08-13
-7mnp,2022-06-15,2021-05-01
-5mnb,2017-05-24,2016-12-13
-1mni,1995-04-20,1995-01-11
-5mn0,2017-08-02,2016-12-12
-4mn5,2014-09-10,2013-09-10
-2mna,2014-12-17,2014-04-02
-1mnc,1995-02-07,1994-01-12
-6mnv,2019-07-31,2018-10-03
-5mnp,2018-01-17,2016-12-13
-3mnu,2010-06-16,2010-04-22
-4mn6,2014-09-10,2013-09-10
-5mn3,2017-12-20,2016-12-12
-5mns,2018-02-28,2016-12-13
-3mn9,2010-05-26,2010-04-21
-1mnd,1996-08-17,1995-04-15
-6mne,2019-04-03,2018-10-01
-5mnm,2018-01-17,2016-12-13
-4mnw,2014-02-05,2013-09-11
-7mnd,2022-05-18,2021-04-30
-7mnu,2022-06-15,2021-05-01
-4mnk,2014-10-22,2013-09-11
-4mn0,2013-10-16,2013-09-09
-5mn5,2016-12-21,2016-12-12
-5mne,2018-01-17,2016-12-13
-3mni,2010-07-14,2010-04-21
-4mnx,2014-02-05,2013-09-11
-7mn5,2021-10-27,2021-04-30
-5mnx,2017-05-24,2016-12-13
-6mn4,2018-10-24,2018-10-01
-1mn9,2003-03-18,2002-09-05
-1mns,1993-10-31,1993-07-06
-4mnl,2014-10-22,2013-09-11
-4mnr,2013-09-25,2013-09-11
-7mns,2022-06-15,2021-05-01
-7d3f,2020-12-09,2020-09-19
-5d3k,2015-12-09,2015-08-06
-2d3s,2006-01-17,2005-10-01
-3d3n,2008-06-10,2008-05-12
-3d3l,2008-09-09,2008-05-12
-7d3b,2021-03-03,2020-09-18
-4d33,2014-12-24,2014-10-20
-4d3x,2016-01-20,2014-10-24
-2d3d,2006-02-14,2005-09-27
-8d3q,2022-11-02,2022-06-01
-8d3w,2022-09-21,2022-06-01
-4d32,2014-12-24,2014-10-20
-2d38,2006-05-30,2005-09-26
-7d34,2021-04-28,2020-09-18
-8d37,2023-05-24,2022-05-31
-6d3o,2019-04-24,2018-04-16
-6d3r,2018-10-17,2018-04-16
-4d3b,2014-12-24,2014-10-20
-4d3t,2015-01-14,2014-10-23
-4d3d,2015-04-01,2014-10-21
-2d3u,2006-08-01,2005-10-02
-4d3n,2015-01-14,2014-10-23
-5d3g,2015-09-30,2015-08-06
-8d3j,2023-11-08,2022-06-01
-4d3k,2015-01-14,2014-10-22
-8d3e,2023-11-08,2022-06-01
-3d3v,2009-06-16,2008-05-12
-2d3k,2006-03-29,2005-09-29
-1d3s,2000-07-07,1999-09-30
-6d3g,2019-04-24,2018-04-16
-8d38,2022-12-14,2022-05-31
-1d3t,2000-10-04,1999-09-30
-6d3v,2018-05-09,2018-04-17
-2d3q,2006-09-30,2005-09-30
-3d32,2008-08-05,2008-05-09
-5d3n,2016-01-20,2015-08-06
-8d3l,2022-11-02,2022-06-01
-3d3t,2008-07-08,2008-05-12
-3d3x,2008-07-08,2008-05-13
-4d3j,2015-01-14,2014-10-22
-6d3e,2019-02-27,2018-04-15
-5d3f,2016-03-16,2015-08-06
-2d3n,2006-03-14,2005-09-29
-8d3s,2023-06-14,2022-06-01
-7d3c,2021-11-03,2020-09-18
-7d3x,2021-10-06,2020-09-21
-7d3v,2021-10-06,2020-09-21
-3d34,2009-02-17,2008-05-09
-8d35,2023-03-01,2022-05-31
-6d3i,2018-08-15,2018-04-16
-8d32,2023-05-10,2022-05-31
-3d3p,2009-05-19,2008-05-12
-4d37,2014-12-24,2014-10-20
-5d3t,2016-01-20,2015-08-06
-6d3k,2019-07-10,2018-04-16
-3d3f,2009-04-28,2008-05-10
-4d34,2014-12-24,2014-10-20
-8d3u,2022-09-21,2022-06-01
-8d3t,2023-03-15,2022-06-01
-3d3i,2008-06-03,2008-05-12
-6d3h,2018-08-15,2018-04-16
-8d3d,2022-07-06,2022-06-01
-5d3c,2016-08-17,2015-08-06
-8d3g,2023-11-08,2022-06-01
-2d32,2006-11-14,2005-09-25
-7d30,2021-02-17,2020-09-17
-4d39,2014-12-24,2014-10-20
-2d3l,2006-03-14,2005-09-29
-1d3d,2000-10-04,1999-09-29
-4d3o,2015-01-14,2014-10-23
-7d3d,2020-11-18,2020-09-18
-5d3l,2016-01-20,2015-08-06
-7d3z,2021-06-09,2020-09-21
-6d3w,2018-05-09,2018-04-17
-4d36,2014-12-24,2014-10-20
-5d3e,2016-03-16,2015-08-06
-1d3c,1999-12-22,1999-09-29
-8d3o,2023-11-08,2022-06-01
-2d31,2006-03-14,2005-09-23
-5d3p,2016-01-20,2015-08-06
-5d3d,2015-08-19,2015-08-06
-5d3u,2016-06-22,2015-08-06
-5d3r,2016-01-20,2015-08-06
-5d3m,2016-04-06,2015-08-06
-8d3k,2023-11-08,2022-06-01
-1d3g,2000-09-13,1999-09-29
-3d39,2009-06-16,2008-05-09
-2d39,2006-12-12,2005-09-26
-1d3a,2000-03-20,1999-09-28
-1d3v,1999-11-17,1999-10-01
-8d3i,2023-11-08,2022-06-01
-6d3j,2018-08-15,2018-04-16
-7d3i,2020-10-07,2020-09-19
-6d31,2018-09-05,2018-04-14
-2d3z,2006-08-01,2005-10-04
-2d3a,2006-07-18,2005-09-26
-6d36,2018-06-20,2018-04-14
-6d3a,2018-06-20,2018-04-15
-7d3a,2021-03-03,2020-09-18
-4d3m,2015-01-14,2014-10-23
-2d3m,2006-10-24,2005-09-29
-5d3z,2015-12-09,2015-08-06
-6d3b,2019-01-23,2018-04-15
-3d3e,2008-07-01,2008-05-09
-4d3y,2016-01-20,2014-10-24
-4d3h,2014-12-24,2014-10-22
-7d3w,2021-10-06,2020-09-21
-3d3z,2009-06-02,2008-05-13
-6d3u,2018-06-06,2018-04-16
-5d3j,2016-01-20,2015-08-06
-4d30,2014-12-24,2014-10-20
-1d3y,1999-11-05,1999-10-01
-5d3i,2015-08-19,2015-08-06
-8d3z,2023-03-15,2022-06-01
-2d3y,2006-10-17,2005-10-04
-6d3m,2018-08-15,2018-04-16
-8d3c,2022-07-06,2022-06-01
-1d3h,2000-08-13,1999-09-29
-4d3w,2015-07-01,2014-10-24
-3d3s,2008-07-15,2008-05-12
-5d3q,2015-12-02,2015-08-06
-7d3e,2020-12-09,2020-09-19
-5d3y,2016-04-20,2015-08-06
-4d38,2014-12-24,2014-10-20
-4d35,2014-12-24,2014-10-20
-2d33,2006-11-14,2005-09-25
-5d3s,2016-01-20,2015-08-06
-6d3s,2018-10-17,2018-04-16
-8d3m,2022-11-02,2022-06-01
-3d3h,2008-07-22,2008-05-11
-4d3u,2015-01-14,2014-10-23
-4d3z,2016-01-20,2014-10-24
-3d3w,2009-04-21,2008-05-12
-6d35,2018-05-23,2018-04-14
-5d3x,2016-04-20,2015-08-06
-3d38,2008-07-08,2008-05-09
-4d31,2014-12-24,2014-10-20
-2d3i,2005-11-29,2005-09-28
-7d38,2021-03-03,2020-09-18
-8d3n,2023-11-08,2022-06-01
-4d3f,2015-04-01,2014-10-21
-6d30,2018-09-05,2018-04-14
-6d32,2018-05-23,2018-04-14
-6d3q,2019-11-27,2018-04-16
-4d3a,2014-12-24,2014-10-20
-4d3v,2015-01-14,2014-10-23
-2d3b,2006-07-18,2005-09-26
-1d3p,2000-10-04,1999-09-30
-2d36,2006-05-30,2005-09-26
-7d36,2021-07-28,2020-09-18
-8d33,2023-05-24,2022-05-31
-8d3r,2023-05-24,2022-06-01
-8d39,2023-01-04,2022-06-01
-3d36,2009-01-13,2008-05-09
-2d3c,2006-07-18,2005-09-26
-8d3p,2022-11-02,2022-06-01
-3d3d,2008-09-09,2008-05-09
-4d3i,2015-01-14,2014-10-22
-8d3h,2023-11-08,2022-06-01
-2d3p,2005-11-10,2005-09-30
-2d3t,2006-02-21,2005-10-01
-4d3l,2016-01-20,2014-10-22
-1d3q,2000-10-04,1999-09-30
-2d37,2006-05-30,2005-09-26
-1d3k,2000-03-01,1999-09-29
-5d3h,2016-01-20,2015-08-06
-2d3r,2005-11-10,2005-09-30
-7d39,2021-03-03,2020-09-18
-2d30,2006-09-19,2005-09-21
-4w1p,2015-08-19,2014-08-14
-3w1f,2013-06-26,2012-11-14
-6w13,2020-09-23,2020-03-03
-7w1g,2021-12-29,2021-11-19
-2w13,2009-06-16,2008-10-14
-3w1x,2013-11-27,2012-11-22
-4w1x,2015-02-04,2014-08-13
-1w1v,2005-01-10,2004-06-24
-1w1t,2005-01-10,2004-06-24
-1w1m,2004-07-02,2004-06-22
-5w14,2017-11-29,2017-06-01
-2w1l,2008-10-28,2008-10-17
-1w1z,2004-09-02,2004-06-24
-6w18,2020-08-12,2020-03-03
-7w18,2022-08-17,2021-11-19
-4w1v,2015-02-04,2014-08-13
-1w1p,2005-01-10,2004-06-23
-6w1k,2020-06-24,2020-03-04
-4w1s,2015-08-19,2014-08-14
-6w1y,2021-01-13,2020-03-04
-7w1t,2023-01-18,2021-11-20
-8w1e,2024-05-29,2024-02-15
-2w17,2008-11-04,2008-10-15
-8w1d,2024-05-29,2024-02-15
-6w17,2020-08-12,2020-03-03
-3w1b,2013-04-03,2012-11-14
-6w1d,2020-03-18,2020-03-04
-2w1f,2009-01-27,2008-10-17
-5w1b,2018-06-06,2017-06-02
-7w1l,2022-11-23,2021-11-19
-6w1z,2020-05-06,2020-03-04
-7w1q,2022-11-23,2021-11-19
-3w1m,2013-11-20,2012-11-16
-7w1h,2022-03-02,2021-11-19
-6w1v,2020-06-03,2020-03-04
-4w1r,2015-08-19,2014-08-14
-2w1y,2008-11-25,2008-10-21
-3w1o,2013-04-10,2012-11-19
-6w1i,2020-07-29,2020-03-04
-7w1a,2023-04-26,2021-11-19
-6w1o,2020-05-20,2020-03-04
-6w1q,2020-05-20,2020-03-04
-5w16,2018-06-06,2017-06-01
-1w13,2008-05-20,2004-06-15
-2w1b,2008-12-09,2008-10-17
-3w16,2014-02-05,2012-11-07
-3w1u,2013-11-27,2012-11-21
-7w1y,2023-02-08,2021-11-21
-7w13,2022-08-17,2021-11-19
-7w1i,2022-11-23,2021-11-19
-2w1c,2009-01-27,2008-10-17
-6w1g,2020-06-24,2020-03-04
-7w1u,2023-01-18,2021-11-20
-1w1b,2005-04-22,2004-06-18
-2w1q,2009-05-05,2008-10-20
-1w1l,2004-07-02,2004-06-22
-1w1a,2005-01-10,2004-06-18
-5w1d,2018-06-06,2017-06-02
-5w1w,2017-10-04,2017-06-05
-1w1d,2004-11-19,2004-06-21
-7w1b,2022-03-02,2021-11-19
-3w18,2014-02-05,2012-11-09
-3w1n,2013-11-20,2012-11-19
-3w1t,2013-11-27,2012-11-21
-5w1s,2017-06-14,2017-06-04
-5w1j,2017-11-22,2017-06-03
-7w1o,2022-12-21,2021-11-19
-1w10,2008-05-20,2004-06-15
-7w1p,2022-12-28,2021-11-19
-5w1k,2018-05-30,2017-06-03
-2w12,2009-06-16,2008-10-14
-2w1w,2009-01-20,2008-10-21
-6w1u,2020-05-20,2020-03-04
-5w12,2017-11-29,2017-06-01
-5w13,2017-11-29,2017-06-01
-3w1g,2013-04-03,2012-11-15
-7w12,2022-11-16,2021-11-19
-6w1h,2020-06-24,2020-03-04
-7w1j,2022-11-23,2021-11-19
-1w1g,2004-11-19,2004-06-21
-8w1o,2024-04-24,2024-02-16
-2w1e,2009-01-27,2008-10-17
-8w1f,2024-05-29,2024-02-15
-7w1v,2023-01-18,2021-11-20
-4w1q,2015-08-19,2014-08-14
-1w1r,2004-08-26,2004-06-23
-2w1m,2008-11-04,2008-10-17
-3w1r,2013-11-20,2012-11-20
-5w1l,2017-11-22,2017-06-03
-1w1u,2004-08-19,2004-06-24
-7w1x,2022-07-06,2021-11-21
-3w12,2013-01-09,2012-11-06
-5w1t,2017-06-14,2017-06-04
-3w1v,2013-06-12,2012-11-21
-2w1a,2009-07-07,2008-10-16
-5w1c,2017-08-16,2017-06-02
-1w11,2008-05-20,2004-06-15
-3w1w,2013-10-09,2012-11-21
-6w1t,2020-05-13,2020-03-04
-7w1f,2022-03-23,2021-11-19
-2w1i,2009-01-27,2008-10-17
-3w1q,2013-11-20,2012-11-20
-4w1t,2015-08-26,2014-08-14
-3w1p,2013-11-20,2012-11-19
-5w18,2017-08-09,2017-06-02
-3w11,2013-01-09,2012-11-06
-7w15,2023-04-26,2021-11-19
-3w1a,2013-11-13,2012-11-13
-6w16,2020-06-03,2020-03-03
-7w1w,2022-07-06,2021-11-21
-3w10,2014-02-05,2012-11-06
-1w1x,2006-01-25,2004-06-24
-6w1n,2021-01-06,2020-03-04
-3w13,2013-01-09,2012-11-06
-6w1r,2020-05-13,2020-03-04
-2w1g,2009-01-27,2008-10-17
-7w1e,2022-05-18,2021-11-19
-1w15,2004-08-13,2004-06-16
-2w14,2009-06-16,2008-10-14
-5w1f,2017-06-14,2017-06-03
-1w1k,2004-07-02,2004-06-22
-2w1s,2009-05-05,2008-10-20
-4w1o,2014-11-05,2014-08-14
-6w1j,2021-01-13,2020-03-04
-6w1m,2021-01-13,2020-03-04
-2w16,2009-05-12,2008-10-14
-7w11,2022-03-02,2021-11-19
-1w1w,2004-09-30,2004-06-24
-3w1j,2013-06-05,2012-11-15
-7w1m,2023-05-31,2021-11-19
-1w1j,2004-07-02,2004-06-22
-1w16,2004-08-13,2004-06-16
-2w1u,2009-05-05,2008-10-20
-5w10,2017-06-28,2017-06-01
-5w19,2018-06-06,2017-06-02
-6w11,2021-03-10,2020-03-03
-1w19,2005-03-02,2004-06-03
-5w1q,2017-06-21,2017-06-04
-5w1v,2017-10-04,2017-06-04
-3w1i,2013-06-05,2012-11-15
-3w1l,2013-11-20,2012-11-16
-1w12,2008-05-20,2004-06-15
-6w1p,2020-05-13,2020-03-04
-2w15,2009-06-16,2008-10-14
-1w1y,2005-01-10,2004-06-24
-1w1o,2004-08-26,2004-06-23
-5w15,2017-06-14,2017-06-01
-1w1s,2004-08-26,2004-06-23
-7w19,2022-12-07,2021-11-19
-3w15,2013-07-03,2012-11-06
-4w1w,2015-02-04,2014-08-13
-1w1q,2004-08-26,2004-06-23
-7w16,2022-08-17,2021-11-19
-6w15,2020-05-06,2020-03-03
-5w1m,2018-05-30,2017-06-03
-7w1z,2023-01-18,2021-11-21
-2w1d,2009-01-27,2008-10-17
-1w1i,2004-09-02,2004-06-22
-6w12,2021-03-10,2020-03-03
-7w10,2022-03-02,2021-11-18
-5w11,2017-12-13,2017-06-01
-2w1x,2008-11-04,2008-10-21
-1w14,2008-05-20,2004-06-15
-2w1h,2009-01-27,2008-10-17
-5z88,2019-02-06,2018-01-31
-4z84,2015-12-02,2015-04-08
-7z80,2022-09-21,2022-03-16
-6z8q,2021-06-09,2020-06-02
-1z84,2005-04-19,2005-03-29
-6z8n,2021-02-10,2020-06-02
-4z8m,2015-09-23,2015-04-09
-6z8c,2021-02-03,2020-06-02
-5z8u,2019-02-06,2018-02-01
-5z8j,2019-02-06,2018-01-31
-5z8g,2019-02-06,2018-01-31
-7z83,2022-09-21,2022-03-16
-6z8l,2020-12-02,2020-06-02
-6z8k,2020-07-29,2020-06-02
-2z8e,2008-03-18,2007-09-05
-4z8w,2016-07-06,2015-04-09
-6z8a,2020-11-25,2020-06-02
-7z8n,2022-07-13,2022-03-17
-7z8q,2023-02-08,2022-03-18
-8z8x,2024-05-29,2024-04-22
-7z8i,2022-08-17,2022-03-17
-8z8n,2024-05-29,2024-04-22
-4z89,2015-08-05,2015-04-08
-2z82,2007-10-02,2007-08-30
-7z88,2023-01-18,2022-03-16
-4z8g,2015-10-21,2015-04-08
-5z89,2018-07-25,2018-01-31
-5z8x,2018-10-10,2018-02-01
-6z8u,2021-06-09,2020-06-02
-1z8q,2005-04-12,2005-03-31
-5z8r,2019-02-06,2018-02-01
-2z87,2008-09-16,2007-09-03
-7z86,2022-07-13,2022-03-16
-1z82,2005-04-12,2005-03-29
-2z8s,2007-10-16,2007-09-10
-2z80,2007-09-25,2007-08-30
-4z8i,2015-10-14,2015-04-09
-6z8j,2020-09-09,2020-06-02
-4z8n,2015-12-16,2015-04-09
-4z83,2015-12-02,2015-04-08
-1z8c,2006-03-21,2005-03-30
-7z87,2023-01-18,2022-03-16
-7z8t,2023-04-19,2022-03-18
-7z8m,2022-07-27,2022-03-17
-1z83,2005-04-26,2005-03-29
-7z8r,2023-04-19,2022-03-18
-4z8d,2016-05-04,2015-04-08
-2z85,2007-11-27,2007-09-02
-5z8n,2018-07-25,2018-01-31
-4z8l,2015-06-17,2015-04-09
-7z8f,2022-07-27,2022-03-17
-5z86,2018-08-15,2018-01-31
-5z84,2018-08-15,2018-01-31
-4z8k,2015-08-12,2015-04-09
-1z8l,2005-04-19,2005-03-30
-5z8s,2019-02-06,2018-02-01
-5z8k,2019-01-16,2018-01-31
-6z8m,2020-09-09,2020-06-02
-6z8w,2021-01-27,2020-06-02
-6z82,2020-12-02,2020-06-02
-2z8y,2008-03-11,2007-09-12
-7z8a,2023-02-01,2022-03-16
-6z8i,2020-11-18,2020-06-02
-6z8p,2020-10-21,2020-06-02
-6z85,2020-12-09,2020-06-02
-2z8p,2007-12-18,2007-09-07
-4z8j,2016-02-24,2015-04-09
-4z8f,2015-06-24,2015-04-08
-7z8o,2023-06-28,2022-03-18
-6z8o,2020-09-09,2020-06-02
-7z8v,2023-04-19,2022-03-18
-1z8j,2005-05-17,2005-03-30
-6z8h,2021-03-17,2020-06-02
-2z8x,2007-10-30,2007-09-11
-4z8c,2015-05-20,2015-04-08
-6z83,2020-07-29,2020-06-02
-1z8r,2006-02-14,2005-03-31
-1z8g,2005-05-03,2005-03-30
-6z80,2020-12-09,2020-06-02
-1z8i,2005-05-17,2005-03-30
-4z8x,2015-05-06,2015-04-09
-2z81,2007-10-02,2007-08-30
-1z89,2006-03-14,2005-03-30
-7z84,2022-09-21,2022-03-16
-2z8f,2008-03-18,2007-09-05
-1z8n,2006-01-17,2005-03-31
-4z8b,2015-07-22,2015-04-08
-5z8t,2019-02-06,2018-02-01
-6z8r,2021-06-09,2020-06-02
-1z88,2006-04-04,2005-03-30
-6z89,2020-12-09,2020-06-02
-7z8l,2022-07-27,2022-03-17
-4z8y,2015-10-14,2015-04-09
-7z8p,2022-03-30,2022-03-18
-5z8a,2019-01-16,2018-01-31
-6z8x,2021-01-27,2020-06-02
-4z88,2015-08-05,2015-04-08
-2z8g,2007-12-18,2007-09-05
-1z8d,2006-03-21,2005-03-30
-5z8h,2019-02-06,2018-01-31
-4z87,2015-11-25,2015-04-08
-2z8z,2007-10-30,2007-09-13
-7z85,2022-07-13,2022-03-16
-7z8g,2022-07-27,2022-03-17
-8z8j,2024-05-29,2024-04-22
-2z8l,2007-11-27,2007-09-06
-2z8d,2008-03-18,2007-09-05
-2z8r,2007-10-16,2007-09-10
-7z8e,2023-02-22,2022-03-17
-7z8h,2022-07-27,2022-03-17
-7z8d,2023-03-29,2022-03-17
-6z8s,2021-06-09,2020-06-02
-1z8u,2005-06-14,2005-03-31
-6z86,2020-12-09,2020-06-02
-2z8i,2008-06-24,2007-09-05
-1z8o,2005-04-12,2005-03-31
-5z8y,2018-10-10,2018-02-01
-4z80,2015-12-30,2015-04-08
-5z8z,2019-02-06,2018-02-01
-7z8x,2022-04-06,2022-03-18
-6z87,2020-12-09,2020-06-02
-2z86,2008-09-16,2007-09-03
-1z8p,2005-04-12,2005-03-31
-5z8l,2018-07-25,2018-01-31
-5z87,2019-02-06,2018-01-31
-6z81,2021-02-10,2020-06-02
-7z8b,2022-08-24,2022-03-17
-7z8y,2023-09-27,2022-03-19
-2z8c,2008-08-12,2007-09-05
-7z8u,2022-03-30,2022-03-18
-5z85,2018-08-15,2018-01-31
-4z8s,2016-03-23,2015-04-09
-6z8v,2021-01-27,2020-06-02
-2z8k,2008-06-24,2007-09-05
-2z8j,2008-06-24,2007-09-05
-6z88,2020-12-09,2020-06-02
-1z8a,2006-03-14,2005-03-30
-4z82,2016-06-01,2015-04-08
-2z8a,2007-11-27,2007-09-04
-6z8t,2021-06-09,2020-06-02
-5z83,2019-01-16,2018-01-30
-6z8g,2021-03-17,2020-06-02
-7z8w,2022-03-30,2022-03-18
-8z85,2024-05-29,2024-04-21
-6z84,2020-07-29,2020-06-02
-2vd7,2007-11-27,2007-10-01
-6vd0,2020-02-26,2019-12-23
-7vd6,2022-03-02,2021-09-06
-5vdu,2017-09-27,2017-04-03
-3vdp,2012-12-19,2012-01-05
-2vdn,2008-09-02,2007-10-10
-6vdf,2020-08-26,2019-12-25
-6vd1,2020-02-26,2019-12-23
-5vdk,2017-08-23,2017-04-03
-6vdl,2020-12-30,2019-12-27
-3vd2,2012-04-18,2012-01-04
-5vd7,2018-04-04,2017-04-01
-3vdr,2012-02-08,2012-01-06
-5vdq,2017-09-27,2017-04-03
-3vd1,2012-04-18,2012-01-04
-3vdb,2012-04-11,2012-01-04
-2vdy,2008-05-13,2007-10-13
-3vda,2012-04-11,2012-01-04
-6vdz,2021-03-10,2019-12-27
-3vd4,2012-04-11,2012-01-04
-5vdb,2017-07-26,2017-04-01
-2vdr,2008-09-02,2007-10-10
-6vds,2020-12-30,2019-12-27
-1vdn,2005-06-28,2004-03-24
-3vdc,2012-04-11,2012-01-04
-6vdy,2020-12-30,2019-12-27
-7vd8,2021-12-29,2021-09-06
-3vd7,2012-04-11,2012-01-04
-2vdq,2008-09-02,2007-10-10
-2vd9,2008-05-20,2007-10-01
-7vdh,2021-12-01,2021-09-07
-5vdv,2017-09-27,2017-04-03
-3vdz,2012-11-28,2012-01-06
-5vdw,2017-09-27,2017-04-03
-6vdr,2020-12-30,2019-12-27
-2vdl,2008-09-02,2007-10-10
-1vdc,1997-03-12,1996-09-22
-5vdn,2017-04-19,2017-04-03
-5vdr,2017-09-27,2017-04-03
-2vdt,2008-07-15,2007-10-11
-2vdd,2008-04-22,2007-10-04
-6vd3,2020-12-23,2019-12-23
-5vdp,2017-09-27,2017-04-03
-2vdp,2008-09-02,2007-10-10
-3vd9,2012-04-11,2012-01-04
-2vdc,2008-01-15,2007-10-04
-7vdl,2021-12-01,2021-09-07
-5vd9,2018-04-04,2017-04-01
-2vdx,2008-05-06,2007-10-13
-5vda,2018-04-04,2017-04-01
-7vd4,2022-09-14,2021-09-06
-6vdw,2020-12-30,2019-12-27
-3vdu,2012-12-19,2012-01-06
-6vd5,2020-12-23,2019-12-23
-2vdi,2008-11-04,2007-10-09
-6vdk,2020-02-05,2019-12-27
-1vd4,2004-10-05,2004-03-18
-3vdf,2012-01-18,2012-01-05
-3vd8,2013-01-16,2012-01-04
-5vdt,2017-09-27,2017-04-03
-6vdv,2020-12-30,2019-12-27
-6vda,2020-06-24,2019-12-23
-2vd5,2007-11-06,2007-09-30
-7vdr,2022-03-09,2021-09-07
-6vde,2020-02-12,2019-12-24
-6vdc,2020-02-12,2019-12-24
-1vd5,2004-07-13,2004-03-18
-8vdw,2024-01-24,2023-12-18
-7vdv,2022-05-18,2021-09-07
-6vdd,2020-02-12,2019-12-24
-2vdk,2008-09-02,2007-10-10
-2vdv,2007-12-18,2007-10-11
-5vd6,2017-07-26,2017-04-01
-5vdo,2017-09-27,2017-04-03
-7vdq,2022-03-09,2021-09-07
-6vdn,2020-12-30,2019-12-27
-6vd8,2020-06-24,2019-12-23
-3vd3,2012-04-11,2012-01-04
-5vd5,2018-04-04,2017-04-01
-2vd8,2008-05-20,2007-10-01
-6vdm,2020-12-30,2019-12-27
-6vdp,2021-03-10,2019-12-27
-1vdv,2004-12-21,2004-03-25
-6vdt,2020-12-30,2019-12-27
-2vdg,2008-03-11,2007-10-08
-5vd4,2018-04-04,2017-04-01
-3vdg,2012-01-25,2012-01-05
-6vd4,2020-12-23,2019-12-23
-2vdj,2008-01-22,2007-10-10
-5vd8,2018-04-04,2017-04-01
-6vd2,2020-02-26,2019-12-23
-2vdm,2008-09-02,2007-10-10
-6vdx,2020-12-30,2019-12-27
-7vdt,2022-05-18,2021-09-07
-6vd9,2020-06-24,2019-12-23
-7vdu,2022-03-09,2021-09-07
-3vdk,2012-05-09,2012-01-05
-3vdd,2012-09-12,2012-01-05
-1vd1,2005-04-26,2004-03-17
-5vd3,2017-08-23,2017-04-01
-5vd2,2017-08-23,2017-04-01
-5vd1,2017-08-23,2017-04-01
-2vd6,2007-10-23,2007-09-30
-5vd0,2017-08-23,2017-04-01
-8vda,2024-02-14,2023-12-14
-2vd3,2008-11-04,2007-09-28
-8vdn,2024-05-22,2023-12-16
-3vdq,2012-02-29,2012-01-06
-3vd0,2012-04-18,2012-01-04
-6vd6,2020-12-23,2019-12-23
-5vdc,2017-05-24,2017-04-01
-5vde,2018-02-07,2017-04-02
-3vd5,2012-04-11,2012-01-04
-2vd1,2008-04-15,2007-09-28
-3vdn,2013-01-09,2012-01-05
-3vdy,2012-03-14,2012-01-06
-2vdw,2008-05-13,2007-10-12
-7vdp,2022-03-09,2021-09-07
-2vdh,2008-11-04,2007-10-09
-2vd4,2008-01-15,2007-09-28
-2vd0,2008-04-15,2007-09-28
-2vdo,2008-09-02,2007-10-10
-7vdo,2022-05-11,2021-09-07
-7vds,2022-03-09,2021-09-07
-2vdb,2008-02-26,2007-10-04
-6vdo,2020-12-30,2019-12-27
-5vds,2017-09-27,2017-04-03
-5vdf,2018-02-07,2017-04-02
-7vd5,2022-03-02,2021-09-06
-3vdi,2012-01-25,2012-01-05
-7vdf,2021-12-29,2021-09-06
-3vd6,2013-01-16,2012-01-04
-1vd3,2005-04-26,2004-03-18
-7vdm,2021-12-01,2021-09-07
-7vdn,2022-09-14,2021-09-07
-7vde,2021-12-29,2021-09-06
-5vdh,2017-05-24,2017-04-03
-1vdd,2004-05-18,2004-03-20
-6vdj,2020-01-29,2019-12-27
-5vdi,2017-05-24,2017-04-03
-7vd9,2021-12-29,2021-09-06
-6vdu,2020-12-30,2019-12-27
-6vdq,2021-03-10,2019-12-27
-3bt9,2008-08-12,2007-12-28
-3bt1,2008-03-25,2007-12-27
-4btj,2013-09-25,2013-06-18
-8bte,2022-12-14,2022-11-28
-4btl,2013-09-11,2013-06-18
-6btf,2018-09-26,2017-12-06
-3btf,2000-03-13,1999-03-10
-8bt7,2022-12-14,2022-11-28
-8bt5,2022-12-14,2022-11-27
-5btn,2016-03-02,2015-06-03
-6bt6,2018-06-13,2017-12-05
-5bta,2016-03-02,2015-06-02
-7btz,2021-04-07,2020-04-03
-2bt3,2005-09-05,2005-05-26
-1bte,1999-02-09,1998-09-01
-2btm,1999-01-13,1999-01-04
-7bt5,2020-09-30,2020-03-31
-6btl,2018-06-06,2017-12-06
-4bt2,2013-09-11,2013-06-12
-6btk,2018-01-17,2017-12-06
-8btw,2023-07-05,2022-12-02
-4btx,2013-12-18,2013-06-19
-3bti,2008-08-12,2007-12-28
-6bt9,2019-03-06,2017-12-05
-3btg,2000-03-13,1999-03-10
-6bt4,2018-03-21,2017-12-05
-1btm,1996-04-03,1995-11-11
-4bts,2013-07-17,2013-06-19
-5bt9,2015-07-29,2015-06-02
-7btf,2020-04-08,2020-04-01
-8btp,2024-02-21,2022-11-29
-6btm,2018-05-09,2017-12-07
-5btl,2016-03-02,2015-06-03
-1bt0,1998-12-30,1998-09-02
-3btq,2000-03-15,1999-03-10
-8btv,2023-07-05,2022-12-02
-5btd,2016-03-02,2015-06-03
-8btk,2023-05-24,2022-11-29
-7btb,2020-10-28,2020-04-01
-3btc,2008-08-12,2007-12-28
-2btr,2005-11-09,2005-06-06
-1bt5,1999-09-02,1998-09-02
-3btj,2008-08-12,2007-12-28
-1btw,1995-10-15,1995-05-17
-6btw,2017-12-20,2017-12-07
-8bt6,2023-04-05,2022-11-27
-6bte,2018-09-26,2017-12-06
-8bty,2023-11-15,2022-11-30
-2bty,2005-12-13,2005-06-08
-7bti,2020-05-20,2020-04-01
-6bt2,2018-05-16,2017-12-04
-2btd,2006-06-22,2005-05-27
-5btc,2016-03-02,2015-06-02
-1bt4,1998-09-09,1998-09-02
-1bt7,1999-06-22,1998-09-01
-4btt,2013-12-18,2013-06-19
-4bt5,2013-09-11,2013-06-12
-7btn,2020-10-21,2020-04-02
-6bt0,2018-02-28,2017-12-04
-2bte,2005-09-15,2005-05-31
-6btg,2018-07-04,2017-12-06
-1btg,1996-03-08,1995-08-29
-3bt6,2008-05-27,2007-12-27
-3bta,1999-10-01,1998-08-12
-1bty,1995-10-15,1995-05-17
-6bto,2018-08-08,2017-12-07
-2bt4,2006-02-13,2005-05-26
-8bt9,2023-09-06,2022-11-28
-5btg,2016-03-02,2015-06-03
-5btv,2016-07-20,2015-06-03
-8bta,2022-12-14,2022-11-28
-4btw,2013-12-18,2013-06-19
-8btt,2023-12-13,2022-11-30
-8bt8,2022-12-28,2022-11-28
-7btl,2021-02-03,2020-04-01
-8btq,2024-05-01,2022-11-29
-2btf,1994-06-22,1994-01-18
-4bt3,2013-09-11,2013-06-12
-3btl,2008-08-12,2007-12-28
-4btv,2013-09-18,2013-06-19
-3bt2,2008-03-25,2007-12-27
-7btj,2021-04-07,2020-04-01
-3btd,2000-03-13,1999-03-11
-3btk,2000-03-13,1999-03-10
-8bt2,2022-12-14,2022-11-27
-7bt9,2021-02-03,2020-03-31
-8btl,2023-12-13,2022-11-29
-6btn,2018-08-08,2017-12-07
-4btu,2013-12-18,2013-06-19
-2btw,2005-12-14,2005-06-07
-5bt3,2015-07-01,2015-06-02
-1bto,1997-04-01,1996-11-08
-2btq,2005-06-14,2005-06-06
-1btc,1993-10-31,1993-02-18
-4bt4,2013-09-11,2013-06-12
-6btd,2018-07-04,2017-12-06
-4bt1,2013-07-03,2013-06-12
-1btu,1999-02-16,1998-09-01
-2btp,2005-06-28,2005-06-05
-3btw,2000-03-13,1999-03-11
-1btp,1996-01-29,1995-08-11
-8bth,2022-12-14,2022-11-28
-6btp,2018-08-08,2017-12-07
-8bt0,2022-12-14,2022-11-27
-3bte,2000-03-15,1999-03-11
-7bt7,2020-05-20,2020-03-31
-6btq,2018-08-08,2017-12-07
-4bt6,2013-09-11,2013-06-12
-4bte,2013-11-06,2013-06-14
-2bts,2005-11-09,2005-06-06
-7bt2,2020-07-15,2020-03-31
-5bt4,2015-07-01,2015-06-02
-2bt7,2005-11-03,2005-05-26
-4bt9,2013-10-09,2013-06-14
-3btx,2008-04-22,2007-12-31
-7bt6,2020-10-28,2020-03-31
-8btc,2022-12-14,2022-11-28
-7btk,2021-03-03,2020-04-01
-2bt9,2005-06-02,2005-05-27
-4bt7,2013-09-11,2013-06-12
-3btm,2000-03-13,1999-03-10
-7btv,2020-11-11,2020-04-03
-4bta,2013-10-09,2013-06-14
-8bti,2022-12-14,2022-11-28
-8bto,2024-02-21,2022-11-29
-7btc,2020-06-17,2020-04-01
-1btk,1997-09-17,1997-07-01
-8btj,2023-10-11,2022-11-29
-4btm,2013-09-25,2013-06-18
-7btt,2021-04-07,2020-04-02
-3bts,2008-03-04,2007-12-30
-8bt4,2023-11-01,2022-11-27
-4btk,2013-09-25,2013-06-18
-2bt1,2005-09-15,2005-05-24
-5bti,2016-03-02,2015-06-03
-7bte,2020-05-20,2020-04-01
-5btf,2016-03-02,2015-06-03
-5bte,2015-07-22,2015-06-03
-2bt0,2005-06-02,2005-05-24
-8btg,2024-02-14,2022-11-28
-4bty,2013-12-18,2013-06-19
-7bt8,2021-02-03,2020-03-31
-5bt5,2015-07-01,2015-06-02
-2bto,2005-06-23,2005-06-04
-3bth,2000-03-13,1999-03-10
-2btc,2000-01-19,1998-12-11
-7btd,2020-06-17,2020-04-01
-4bti,2013-12-25,2013-06-18
-2bt6,2006-01-25,2005-05-26
-1bt8,1999-06-15,1998-09-01
-6bt5,2018-02-07,2017-12-05
-5btr,2015-07-08,2015-06-03
-6bt1,2018-05-16,2017-12-04
-5btx,2015-08-26,2015-06-03
-7bta,2020-06-17,2020-03-31
-4bt0,2013-07-03,2013-06-12
-1btz,1995-10-15,1995-05-17
-3bto,1997-03-12,1996-11-08
-3btt,2000-03-13,1999-03-10
-1btn,1996-03-08,1995-08-23
-7bts,2020-12-02,2020-04-02
-2btn,2005-12-07,2005-06-03
-6btx,2018-09-19,2017-12-08
-5btq,2016-06-08,2015-06-03
-4btb,2013-10-09,2013-06-14
-8e3e,2023-02-08,2022-08-17
-3e3h,2008-10-07,2008-08-07
-6e3s,2019-02-13,2018-07-15
-1e31,2001-01-03,2000-06-04
-3e3u,2009-01-20,2008-08-08
-8e3w,2023-03-29,2022-08-17
-4e35,2012-12-26,2012-03-09
-4e34,2012-12-26,2012-03-09
-8e3s,2023-04-26,2022-08-17
-4e3j,2012-09-26,2012-03-09
-8e3f,2022-09-07,2022-08-17
-4e3m,2012-09-26,2012-03-09
-2e30,2006-12-19,2006-11-19
-7e3h,2022-02-16,2021-02-08
-1e3w,2001-05-25,2000-06-26
-1e3j,2001-02-04,2000-06-19
-4e3n,2012-09-26,2012-03-09
-1e3v,2001-03-12,2000-06-24
-7e3g,2021-12-15,2021-02-08
-1e3b,2000-10-22,2000-06-08
-8e3p,2023-02-22,2022-08-17
-6e3u,2019-02-13,2018-07-15
-6e33,2018-10-24,2018-07-13
-5e37,2016-06-22,2015-10-02
-1e3k,2001-06-14,2000-06-19
-2e3t,2007-09-25,2006-11-28
-5e3u,2016-07-20,2015-10-04
-3e3k,2008-09-16,2008-08-07
-5e3t,2016-07-20,2015-10-04
-3e3q,2008-11-04,2008-08-07
-1e3c,2001-03-05,2000-06-13
-5e3c,2016-04-13,2015-10-02
-4e36,2012-08-29,2012-03-09
-5e3d,2016-05-25,2015-10-02
-7e3v,2022-02-23,2021-02-09
-4e31,2012-04-25,2012-03-09
-7e3b,2021-09-01,2021-02-08
-8e3m,2023-06-28,2022-08-17
-2e39,2007-03-20,2006-11-22
-5e3h,2015-11-18,2015-10-02
-4e3h,2012-06-27,2012-03-09
-6e3o,2019-07-17,2018-07-14
-3e3b,2009-03-03,2008-08-07
-8e3o,2023-06-28,2022-08-17
-5e35,2015-12-02,2015-10-01
-4e3i,2012-09-26,2012-03-09
-1e3t,2000-10-03,2000-06-22
-1e3l,2000-09-12,2000-06-19
-7e3k,2021-09-15,2021-02-09
-4e3k,2012-09-26,2012-03-09
-3e3i,2009-08-18,2008-08-07
-5e3i,2015-11-04,2015-10-02
-1e32,2001-05-31,2000-06-05
-2e3a,2007-03-20,2006-11-22
-7e3l,2021-09-15,2021-02-09
-2e37,2007-11-27,2006-11-21
-3e3o,2009-08-18,2008-08-07
-5e3r,2015-11-04,2015-10-03
-7e3m,2022-03-23,2021-02-09
-4e3f,2012-06-27,2012-03-09
-6e3e,2019-07-17,2018-07-13
-3e3t,2008-10-28,2008-08-08
-5e3a,2016-04-13,2015-10-02
-3e3s,2008-10-28,2008-08-08
-5e3e,2015-11-25,2015-10-02
-5e30,2015-12-02,2015-10-01
-6e3m,2019-07-17,2018-07-14
-3e3g,2009-08-18,2008-08-07
-1e38,2000-10-18,2000-06-06
-4e3w,2012-07-25,2012-03-10
-4e3a,2012-03-21,2012-03-09
-7e33,2021-04-14,2021-02-07
-4e3l,2012-09-26,2012-03-09
-6e36,2019-07-17,2018-07-13
-2e3x,2007-12-11,2006-11-30
-6e3l,2019-02-27,2018-07-14
-6e3t,2019-02-13,2018-07-15
-3e32,2009-03-10,2008-08-06
-4e32,2012-04-25,2012-03-09
-5e34,2015-12-02,2015-10-01
-4e3y,2013-05-08,2012-03-11
-7e3f,2021-12-15,2021-02-08
-6e3n,2019-07-17,2018-07-14
-7e34,2021-04-14,2021-02-08
-4e3b,2012-12-26,2012-03-09
-4e3q,2012-10-10,2012-03-10
-3e30,2009-03-10,2008-08-06
-6e34,2018-12-26,2018-07-13
-6e3f,2019-07-17,2018-07-13
-6e3v,2019-04-03,2018-07-15
-7e3u,2022-02-16,2021-02-09
-5e3g,2016-05-25,2015-10-02
-1e3d,2001-06-14,2000-06-14
-6e39,2018-12-26,2018-07-13
-1e34,2000-10-18,2000-06-06
-4e3d,2012-06-27,2012-03-09
-1e3s,2001-05-25,2000-06-22
-3e3y,2008-08-26,2008-08-08
-2e33,2007-03-20,2006-11-20
-3e38,2008-10-07,2008-08-06
-4e3g,2012-06-27,2012-03-09
-7e3x,2021-09-29,2021-02-09
-6e3g,2019-06-12,2018-07-13
-3e34,2009-03-10,2008-08-06
-1e3g,2001-06-14,2000-06-14
-1e36,2000-10-18,2000-06-06
-7e35,2021-03-17,2021-02-08
-5e3k,2016-10-26,2015-10-02
-6e3z,2019-09-11,2018-07-16
-8e3h,2022-09-07,2022-08-17
-6e37,2019-11-06,2018-07-13
-8e3n,2023-03-15,2022-08-17
-1e37,2000-10-18,2000-06-06
-4e37,2013-03-20,2012-03-09
-5e3q,2015-11-04,2015-10-03
-4e33,2012-04-25,2012-03-09
-1e30,2000-07-28,2000-06-02
-1e3e,2000-09-12,2000-06-14
-7e3y,2022-02-16,2021-02-09
-6e3h,2018-09-26,2018-07-14
-3e37,2009-03-10,2008-08-06
-3e3c,2009-04-07,2008-08-07
-4e3t,2013-01-23,2012-03-10
-3e33,2009-03-10,2008-08-06
-7e36,2021-03-10,2021-02-08
-3e3n,2009-08-18,2008-08-07
-7e3q,2022-02-16,2021-02-09
-4e3u,2012-07-25,2012-03-10
-3e35,2009-06-23,2008-08-06
-7e3d,2022-02-16,2021-02-08
-7e37,2021-12-15,2021-02-08
-6e3r,2019-04-03,2018-07-14
-1e3z,2001-06-21,2000-06-27
-5e32,2015-12-02,2015-10-01
-8e3l,2023-06-28,2022-08-17
-8e3j,2023-02-22,2022-08-17
-7e3c,2021-09-01,2021-02-08
-6e35,2018-07-25,2018-07-13
-5e3b,2016-09-28,2015-10-02
-5e3f,2015-10-14,2015-10-02
-8e3k,2023-07-05,2022-08-17
-5e3x,2016-02-10,2015-10-05
-5e33,2016-04-13,2015-10-01
-1e3m,2000-11-01,2000-06-19
-6e3p,2019-07-17,2018-07-14
-1e3q,2000-07-03,2000-06-21
-1e3i,2000-09-12,2000-06-16
-8e3q,2023-01-18,2022-08-17
-7e32,2021-04-21,2021-02-07
-4e3v,2012-07-25,2012-03-10
-4e3r,2012-10-10,2012-03-10
-6e3d,2019-09-11,2018-07-13
-4e3x,2012-07-25,2012-03-10
-4e3o,2012-09-26,2012-03-09
-7e3n,2022-02-16,2021-02-09
-1e3x,2001-06-21,2000-06-26
-1e3r,2001-03-05,2000-06-22
-1e3a,2000-11-29,2000-06-07
-3e39,2008-08-19,2008-08-06
-4e3s,2012-05-23,2012-03-10
-6e3w,2019-04-03,2018-07-15
-3e3z,2008-08-26,2008-08-08
-8e3i,2023-01-18,2022-08-17
-1e33,2001-05-25,2000-06-06
-6e3a,2019-03-20,2018-07-13
-8e3d,2023-02-08,2022-08-17
-1e35,2000-10-18,2000-06-06
-3e3j,2008-11-04,2008-08-07
-6e3x,2019-04-03,2018-07-15
-3e3f,2009-08-18,2008-08-07
-1e39,2000-09-18,2000-06-07
-3e3r,2008-08-26,2008-08-07
-2e3b,2007-03-20,2006-11-22
-7e3j,2021-04-07,2021-02-08
-7e39,2021-09-01,2021-02-08
-4e30,2012-04-25,2012-03-09
-3e31,2009-08-18,2008-08-05
-7e38,2021-12-15,2021-02-08
-7e3e,2021-12-15,2021-02-08
-7e3w,2022-02-23,2021-02-09
-6e3k,2019-02-27,2018-07-14
-8je2,2024-02-28,2023-05-15
-6jer,2020-02-12,2019-02-07
-2jev,2007-06-05,2007-01-23
-5je3,2016-05-04,2016-04-17
-4je9,2013-08-21,2013-02-26
-6jex,2020-02-12,2019-02-07
-4jej,2014-06-25,2013-02-27
-1jec,2001-11-14,2001-06-17
-1jex,2001-07-11,2001-06-19
-5jep,2017-01-11,2016-04-18
-6jef,2019-12-11,2019-02-05
-2je7,2007-10-30,2007-01-15
-2jej,2007-03-13,2007-01-17
-8je9,2023-10-25,2023-05-15
-6jen,2020-03-11,2019-02-06
-6jew,2020-02-12,2019-02-07
-4jey,2014-03-26,2013-02-27
-4jew,2014-03-26,2013-02-27
-5jej,2016-06-15,2016-04-18
-5jeg,2017-01-11,2016-04-18
-5jeb,2016-09-07,2016-04-18
-1jed,2001-11-14,2001-06-17
-6jez,2020-02-12,2019-02-07
-1je1,2001-10-26,2001-06-15
-8jee,2024-05-15,2023-05-15
-4jed,2013-03-13,2013-02-26
-1jet,1997-05-15,1996-07-03
-5jez,2016-11-30,2016-04-19
-4jeb,2013-08-21,2013-02-26
-2je3,2007-07-03,2007-01-13
-4jec,2013-07-24,2013-02-26
-6jev,2020-02-12,2019-02-07
-5jen,2016-09-07,2016-04-18
-5je7,2017-01-11,2016-04-17
-4jem,2013-09-11,2013-02-27
-8jeb,2023-10-25,2023-05-15
-2jep,2007-03-20,2007-01-18
-1jep,2001-12-12,2001-06-18
-5je5,2016-05-04,2016-04-17
-5jes,2017-01-11,2016-04-18
-4jes,2013-04-24,2013-02-27
-8je4,2023-11-08,2023-05-15
-4je5,2013-09-11,2013-02-26
-6je0,2020-05-20,2019-02-02
-2jeq,2007-03-20,2007-01-18
-1jeb,2002-01-23,2001-06-17
-4jex,2014-03-26,2013-02-27
-6jea,2019-03-13,2019-02-04
-4jer,2013-04-24,2013-02-27
-6jem,2020-03-11,2019-02-06
-2jes,2007-03-27,2007-01-21
-5jee,2016-10-19,2016-04-18
-6jes,2020-02-12,2019-02-07
-2jed,2008-02-05,2007-01-16
-2jeb,2007-04-03,2007-01-16
-5jeh,2017-01-11,2016-04-18
-2jen,2007-03-20,2007-01-18
-5je4,2016-05-04,2016-04-17
-8jek,2023-10-25,2023-05-16
-6je8,2019-03-13,2019-02-04
-6je2,2020-05-20,2019-02-02
-1jeh,2001-07-11,2001-06-18
-8jer,2024-03-06,2023-05-16
-2jeg,2007-03-13,2007-01-17
-8je1,2024-02-28,2023-05-15
-4je8,2014-02-26,2013-02-26
-6jee,2019-12-11,2019-02-05
-1jeu,1997-05-15,1996-07-03
-1jea,1997-11-26,1997-05-20
-2jef,2007-03-13,2007-01-17
-4je7,2014-02-26,2013-02-26
-5je8,2016-05-11,2016-04-18
-2je5,2007-08-14,2007-01-15
-4jez,2014-03-26,2013-02-27
-1je5,2001-08-22,2001-06-15
-4jea,2013-08-21,2013-02-26
-6jeb,2019-03-13,2019-02-05
-6jed,2019-08-07,2019-02-05
-8jea,2023-10-25,2023-05-15
-2je2,2007-07-03,2007-01-13
-6je1,2020-05-20,2019-02-02
-6jeu,2020-02-12,2019-02-07
-1jee,2001-11-14,2001-06-17
-4jet,2013-04-24,2013-02-27
-8jem,2024-05-15,2023-05-16
-5je0,2016-05-04,2016-04-17
-4jev,2014-03-26,2013-02-27
-2je4,2007-08-28,2007-01-15
-5je2,2016-05-11,2016-04-17
-1jev,1997-05-15,1996-07-03
-4je6,2014-02-26,2013-02-26
-6jeo,2019-11-13,2019-02-06
-2je9,2007-10-30,2007-01-16
-5jex,2016-11-30,2016-04-19
-2jey,2007-07-03,2007-01-25
-2jei,2007-03-13,2007-01-17
-5jei,2017-02-22,2016-04-18
-1jef,1997-10-15,1997-04-23
-2jea,2007-04-03,2007-01-16
-6jet,2020-02-12,2019-02-07
-5jey,2016-11-30,2016-04-19
-5je1,2016-05-04,2016-04-17
-6jeq,2019-02-20,2019-02-07
-5jea,2016-07-13,2016-04-18
-2jew,2007-11-20,2007-01-24
-8je0,2024-03-20,2023-05-15
-4je0,2013-06-19,2013-02-25
-8jew,2024-05-22,2023-05-16
-2jec,2007-10-30,2007-01-16
-2jez,2007-07-03,2007-01-25
-8jex,2024-04-17,2023-05-16
-8jej,2023-10-25,2023-05-16
-1jer,1997-02-12,1996-08-21
-3ghc,2009-09-22,2009-03-03
-3ghu,2009-03-24,2009-03-04
-7ghu,2023-11-08,2023-08-11
-1ghz,2002-01-22,2001-01-22
-1ghv,2002-01-22,2001-01-22
-4gh6,2012-10-03,2012-08-07
-7ghz,2023-11-08,2023-08-11
-4ghl,2012-11-28,2012-08-07
-8ghd,2023-08-09,2023-03-09
-3ghv,2009-09-22,2009-03-04
-7gh4,2023-11-08,2023-08-11
-3ght,2009-03-24,2009-03-04
-1ghx,2002-01-22,2001-01-22
-6ghw,2019-03-06,2018-05-09
-5ghy,2017-01-25,2016-06-21
-5gh9,2017-06-21,2016-06-19
-6ghj,2018-09-19,2018-05-08
-6ghv,2019-09-11,2018-05-09
-2ghd,2006-06-13,2006-03-27
-2ghs,2006-04-11,2006-03-27
-4ghw,2012-10-10,2012-08-08
-1gha,1994-06-22,1994-04-06
-6gh4,2018-08-08,2018-05-04
-7gh3,2023-11-08,2023-08-11
-7ghp,2023-11-08,2023-08-11
-7ghe,2023-11-08,2023-08-11
-6ghp,2018-08-01,2018-05-08
-5gha,2017-05-03,2016-06-19
-5gho,2017-01-04,2016-06-20
-8ghb,2023-08-09,2023-03-09
-5ghv,2016-07-06,2016-06-20
-4gh1,2013-09-04,2012-08-07
-7ghb,2023-11-08,2023-08-11
-6ghm,2019-02-27,2018-05-08
-3ghs,2009-03-24,2009-03-04
-6ghc,2018-08-08,2018-05-07
-3gh5,2009-07-07,2009-03-03
-7gh5,2023-11-08,2023-08-11
-2ghg,2007-03-27,2006-03-27
-8ghp,2023-08-30,2023-03-10
-4ghc,2012-10-31,2012-08-07
-7gh1,2023-11-08,2023-08-11
-8ghv,2023-05-24,2023-03-12
-1gh4,2001-05-09,2000-11-09
-4gh5,2013-03-27,2012-08-07
-7ghv,2023-11-08,2023-08-11
-6ghs,2018-08-29,2018-05-08
-2gh4,2006-08-29,2006-03-25
-6ghl,2019-05-08,2018-05-08
-7ghh,2023-11-08,2023-08-11
-5ghf,2017-05-24,2016-06-19
-3ghz,2009-03-17,2009-03-04
-8ghe,2023-08-09,2023-03-09
-3gh7,2009-07-07,2009-03-03
-7ghx,2023-11-08,2023-08-11
-7gh9,2023-11-08,2023-08-11
-7gh7,2023-11-08,2023-08-11
-7ghd,2023-11-08,2023-08-11
-7ghr,2023-11-08,2023-08-11
-8ghz,2023-11-08,2023-03-13
-6gh9,2018-09-26,2018-05-06
-5ghn,2017-01-04,2016-06-20
-3ghq,2009-10-06,2009-03-04
-2gh5,2006-09-26,2006-03-25
-2ghm,2006-05-02,2006-03-27
-7gh6,2023-11-08,2023-08-11
-5ghz,2017-01-25,2016-06-21
-2gh0,2006-06-27,2006-03-24
-1ghw,2002-01-22,2001-01-22
-8gh4,2023-08-30,2023-03-09
-6ghr,2019-05-08,2018-05-08
-1ghb,1994-06-22,1994-04-06
-6gh7,2018-10-10,2018-05-04
-7ghn,2023-11-08,2023-08-11
-7ghc,2023-11-08,2023-08-11
-8gh1,2024-03-06,2023-03-08
-5gh0,2016-06-29,2016-06-17
-8ght,2023-06-21,2023-03-12
-7ghy,2023-11-08,2023-08-11
-2ght,2006-12-05,2006-03-27
-1ghm,2001-04-04,2000-12-19
-5ghi,2017-01-04,2016-06-20
-8ghr,2023-08-02,2023-03-10
-8ghu,2023-04-12,2023-03-12
-3ghr,2009-03-24,2009-03-04
-6gh3,2018-06-13,2018-05-04
-6ghg,2018-09-12,2018-05-07
-3gh3,2010-03-16,2009-03-02
-8ghj,2023-09-20,2023-03-10
-8ghy,2023-05-17,2023-03-13
-4ghm,2012-09-05,2012-08-08
-2ghe,2006-06-13,2006-03-27
-7gha,2023-11-08,2023-08-11
-1gh0,2001-06-06,2000-10-29
-5ghm,2017-01-04,2016-06-20
-4ght,2013-06-26,2012-08-08
-2gh6,2007-03-20,2006-03-26
-4ghd,2012-10-31,2012-08-07
-4ghf,2012-10-31,2012-08-07
-2ghq,2006-12-05,2006-03-27
-7ghs,2023-11-08,2023-08-11
-2ghc,2006-06-13,2006-03-27
-6ghh,2018-06-20,2018-05-07
-2gh7,2006-04-18,2006-03-26
-7ghm,2023-11-08,2023-08-11
-2ghh,2006-06-13,2006-03-27
-3gh8,2009-05-12,2009-03-03
-6ghx,2019-02-06,2018-05-09
-3ghh,2010-03-16,2009-03-03
-8gh0,2024-03-06,2023-03-08
-2ghk,2006-06-13,2006-03-27
-7ghl,2023-11-08,2023-08-11
-5ghj,2017-01-04,2016-06-20
-7ghi,2023-11-08,2023-08-11
-6gh2,2018-06-13,2018-05-04
-2gh9,2007-02-06,2006-03-27
-7ghg,2023-11-08,2023-08-11
-1ghp,2001-04-04,2000-12-21
-7gh0,2023-11-08,2023-08-11
-7gh8,2023-11-08,2023-08-11
-3ghg,2009-05-19,2009-03-03
-3ghb,2009-12-01,2009-03-03
-8gh6,2023-04-05,2023-03-09
-7ghk,2023-11-08,2023-08-11
-6ghn,2018-08-08,2018-05-08
-4ghg,2012-10-31,2012-08-07
-7gho,2023-11-08,2023-08-11
-6gh1,2018-08-08,2018-05-04
-7ght,2023-11-08,2023-08-11
-5ghq,2017-01-04,2016-06-20
-4ghe,2012-10-31,2012-08-07
-4gh3,2013-09-04,2012-08-07
-8ghc,2023-08-09,2023-03-09
-4ghi,2013-02-27,2012-08-07
-7ghq,2023-11-08,2023-08-11
-7ghj,2023-11-08,2023-08-11
-1ghg,2001-02-12,2000-12-13
-1gh7,2001-11-28,2000-11-27
-2ghf,2006-04-11,2006-03-27
-3ghm,2009-10-27,2009-03-04
-5ghp,2017-01-04,2016-06-20
-3ghw,2009-09-22,2009-03-04
-8gh7,2023-07-05,2023-03-09
-2gha,2007-02-06,2006-03-27
-3ghn,2009-10-27,2009-03-04
-4ghh,2012-10-31,2012-08-07
-6ghb,2019-04-24,2018-05-06
-2gh2,2006-04-11,2006-03-24
-7gh2,2023-11-08,2023-08-11
-6ghk,2019-05-22,2018-05-08
-1ghq,2001-06-13,2001-01-11
-7ghf,2023-11-08,2023-08-11
-2ghz,2006-07-04,2006-03-28
-7ghw,2023-11-08,2023-08-11
-4gh8,2013-06-05,2012-08-07
-6gha,2018-09-26,2018-05-06
-4gh2,2012-10-03,2012-08-07
-6gh8,2018-07-25,2018-05-06
-3gh6,2010-03-09,2009-03-03
-4ghr,2013-09-04,2012-08-08
-1ghy,2002-01-22,2001-01-22
-8ghf,2023-05-10,2023-03-10
-1ghe,2003-01-14,2000-12-13
-5ghg,2017-05-24,2016-06-20
-2ghl,2006-04-11,2006-03-27
-1ri2,2004-02-03,2003-11-16
-6ri7,2019-07-03,2019-04-23
-7ri2,2022-03-30,2021-07-19
-6rii,2019-05-01,2019-04-24
-4riw,2014-12-10,2014-10-07
-6rik,2019-05-01,2019-04-24
-7ris,2023-01-11,2021-07-20
-3rir,2012-04-18,2011-04-14
-8ri0,2024-01-10,2023-12-18
-1rir,2004-12-28,2003-11-17
-7rib,2022-05-18,2021-07-19
-2rid,2008-01-15,2007-10-10
-6rij,2020-07-22,2019-04-24
-7riq,2022-01-12,2021-07-20
-6riv,2020-03-04,2019-04-25
-3ri7,2012-02-08,2011-04-13
-4ri1,2015-04-01,2014-10-04
-6rin,2019-07-03,2019-04-24
-6ril,2019-05-01,2019-04-24
-7riv,2021-08-25,2021-07-20
-1ri1,2004-02-03,2003-11-16
-4rik,2015-08-26,2014-10-06
-8riy,2024-05-01,2023-12-19
-7rim,2022-01-12,2021-07-20
-6ri8,2019-05-01,2019-04-23
-4ri7,2015-01-21,2014-10-05
-1riv,2003-12-02,2003-11-18
-6ri0,2019-05-01,2019-04-23
-3ril,2012-03-14,2011-04-13
-3rid,2012-02-15,2011-04-13
-4ri9,2014-12-10,2014-10-05
-7riz,2023-01-11,2021-07-20
-4ric,2014-12-03,2014-10-05
-2ri7,2007-12-11,2007-10-10
-7riy,2022-01-12,2021-07-20
-4riz,2014-11-12,2014-10-07
-1ri4,2004-02-03,2003-11-16
-2rif,2008-06-17,2007-10-10
-1rif,2003-11-25,2003-11-17
-4ri3,2015-08-12,2014-10-05
-6rip,2019-07-03,2019-04-24
-1rio,2004-01-27,2003-11-17
-6rim,2019-05-29,2019-04-24
-4rib,2014-12-03,2014-10-05
-3rig,2011-11-23,2011-04-13
-7ri3,2022-04-20,2021-07-19
-2riq,2008-01-08,2007-10-12
-3ri1,2011-05-04,2011-04-12
-4ri2,2015-08-12,2014-10-05
-2rix,2008-02-05,2007-10-13
-4rix,2014-12-10,2014-10-07
-7ri1,2022-03-30,2021-07-19
-2ri1,2008-03-25,2007-10-10
-6riq,2019-06-19,2019-04-24
-7rip,2022-01-12,2021-07-20
-4rig,2015-01-28,2014-10-06
-4rih,2015-01-28,2014-10-06
-6rie,2019-12-18,2019-04-23
-3rik,2012-03-14,2011-04-13
-3rix,2011-12-07,2011-04-14
-2ri9,2008-03-25,2007-10-10
-6ri9,2019-07-03,2019-04-23
-2rip,2008-03-18,2007-10-12
-3riw,2011-05-11,2011-04-14
-1rit,2004-12-28,2003-11-17
-4ri8,2014-12-03,2014-10-05
-6ric,2019-12-18,2019-04-23
-3riz,2011-06-22,2011-04-14
-3rih,2011-04-20,2011-04-13
-4rii,2015-01-28,2014-10-06
-3rit,2011-04-27,2011-04-14
-6rid,2019-12-18,2019-04-23
-2ri0,2008-03-25,2007-10-10
-7rie,2022-09-14,2021-07-19
-1ri3,2004-02-03,2003-11-16
-3ri3,2011-06-29,2011-04-12
-1riw,2004-11-09,2003-11-18
-3rin,2012-02-29,2011-04-14
-7ria,2022-05-18,2021-07-19
-2rib,2008-01-15,2007-10-10
-7riu,2021-08-25,2021-07-20
-7rig,2023-05-10,2021-07-19
-3rii,2011-11-09,2011-04-13
-4riu,2015-02-04,2014-10-07
-4rif,2015-01-28,2014-10-06
-7riw,2022-01-12,2021-07-20
-3rib,2011-07-20,2011-04-13
-6rir,2020-01-29,2019-04-25
-3ri5,2011-05-25,2011-04-12
-4ri6,2015-01-21,2014-10-05
-2ric,2008-01-15,2007-10-10
-2rin,2008-09-30,2007-10-12
-3rif,2011-05-25,2011-04-13
-2rir,2007-10-23,2007-10-12
-7rio,2021-08-25,2021-07-20
-6ris,2019-12-18,2019-04-25
-2ri6,2007-11-06,2007-10-10
-6ri2,2019-05-01,2019-04-23
-3riy,2011-11-23,2011-04-14
-6ri4,2019-05-01,2019-04-23
-2ria,2008-01-15,2007-10-10
-2riu,2008-01-29,2007-10-12
-1rin,1993-10-31,1993-01-27
-4riv,2015-02-04,2014-10-07
-2riy,2008-02-05,2007-10-13
-2rie,2008-01-15,2007-10-10
-3rie,2012-04-25,2011-04-13
-3riv,2011-05-11,2011-04-14
-1riu,2003-12-02,2003-11-18
-6rit,2020-04-15,2019-04-25
-2rio,2008-01-29,2007-10-12
-6rig,2020-05-13,2019-04-24
-6ri6,2019-05-01,2019-04-23
-7rix,2022-01-12,2021-07-20
-6ri5,2019-06-26,2019-04-23
-6riw,2020-08-26,2019-04-25
-4rio,2014-12-24,2014-10-07
-4riy,2014-12-10,2014-10-07
-3rim,2012-02-29,2011-04-14
-2ri8,2008-03-25,2007-10-10
-7ri0,2022-03-16,2021-07-19
-6rih,2019-08-07,2019-04-24
-2ri4,2008-10-14,2007-10-10
-3ria,2011-05-25,2011-04-13
-4ria,2014-12-10,2014-10-05
-2riw,2008-10-14,2007-10-12
-7bab,2021-07-07,2020-12-15
-1bao,1993-10-31,1993-05-19
-6bao,2018-09-19,2017-10-14
-4bax,2013-03-27,2012-09-16
-6baz,2018-10-24,2017-10-16
-4bae,2013-10-30,2012-09-13
-7baz,2021-10-20,2020-12-16
-6bak,2018-09-19,2017-10-13
-7bar,2022-01-12,2020-12-16
-2bai,2006-01-24,2005-10-14
-3bax,2008-03-25,2007-11-08
-7bad,2021-03-17,2020-12-15
-8baw,2023-07-12,2022-10-12
-4bau,2013-10-02,2012-09-16
-2baq,2005-12-06,2005-10-14
-6bag,2018-10-17,2017-10-12
-4ba1,2012-10-03,2012-09-10
-7ba7,2021-07-07,2020-12-15
-6baf,2018-09-19,2017-10-12
-3bae,2008-04-15,2007-11-07
-6ba2,2018-08-01,2017-10-11
-8ba3,2023-02-01,2022-10-11
-6baa,2017-11-01,2017-10-12
-6bat,2018-01-17,2017-10-15
-2bag,2006-08-29,2005-10-14
-3bay,2008-03-25,2007-11-08
-6bax,2018-10-24,2017-10-16
-3bar,2008-01-29,2007-11-08
-4bay,2013-11-27,2012-09-17
-7baa,2021-07-07,2020-12-15
-6ba4,2018-08-01,2017-10-12
-8bah,2023-01-11,2022-10-11
-4ba2,2012-10-03,2012-09-10
-7ba1,2022-01-12,2020-12-15
-7baf,2021-03-17,2020-12-15
-8bax,2023-07-12,2022-10-12
-4bas,2012-12-12,2012-09-15
-6bah,2018-09-05,2017-10-12
-8bav,2024-04-03,2022-10-12
-8bar,2023-07-12,2022-10-11
-8bak,2023-02-01,2022-10-11
-2bab,2006-01-31,2005-10-14
-2bax,2005-10-25,2005-10-15
-3ba2,2008-11-11,2007-11-07
-3baj,2008-03-25,2007-11-07
-8bai,2023-10-25,2022-10-11
-6baq,2018-05-09,2017-10-15
-7bam,2021-12-01,2020-12-16
-1bab,1994-01-31,1992-05-06
-1bai,1999-01-13,1998-04-17
-1baf,1994-01-31,1992-01-16
-8baq,2023-07-12,2022-10-11
-4baf,2012-11-14,2012-09-14
-4ba9,2013-09-25,2012-09-12
-3bab,2008-11-11,2007-11-07
-8bay,2022-11-02,2022-10-12
-7ba8,2021-07-07,2020-12-15
-8bau,2023-07-12,2022-10-11
-3ba9,2008-11-11,2007-11-07
-6bap,2018-09-19,2017-10-14
-8bao,2022-11-30,2022-10-11
-7bag,2022-01-12,2020-12-15
-6bau,2018-01-17,2017-10-15
-8bap,2023-10-25,2022-10-11
-4bar,2012-11-14,2012-09-14
-7bah,2022-01-12,2020-12-15
-1ba1,1998-07-15,1998-04-21
-2bat,1994-01-31,1992-08-10
-7bai,2022-01-12,2020-12-15
-3bac,2008-11-11,2007-11-07
-4bah,2013-01-16,2012-09-14
-4bac,2012-10-10,2012-09-12
-2bam,1999-10-31,1998-08-19
-4baq,2013-01-16,2012-09-14
-6bav,2018-01-17,2017-10-16
-7ba0,2021-03-17,2020-12-15
-7baq,2022-01-12,2020-12-16
-6ba0,2018-10-17,2017-10-11
-3bam,1999-01-13,1998-08-19
-8baj,2022-11-16,2022-10-11
-1bag,1998-10-21,1998-01-30
-8ba0,2023-01-18,2022-10-10
-2ba1,2005-11-22,2005-10-13
-6bad,2018-10-17,2017-10-12
-8bac,2023-03-01,2022-10-11
-4ba5,2013-03-27,2012-09-11
-1baw,1999-03-02,1998-04-19
-8bal,2023-01-11,2022-10-11
-8ba8,2023-12-27,2022-10-11
-8ba5,2022-11-23,2022-10-11
-7ba9,2021-07-07,2020-12-15
-2bak,2005-12-06,2005-10-14
-8ba6,2022-11-16,2022-10-11
-2baw,2006-01-24,2005-10-15
-4bag,2013-04-17,2012-09-14
-6ba1,2018-10-17,2017-10-11
-2bac,2006-01-31,2005-10-14
-2ba9,2006-01-31,2005-10-14
-3bal,2007-11-27,2007-11-08
-4bam,2013-01-16,2012-09-14
-8bam,2023-10-25,2022-10-11
-3baz,2008-11-11,2007-11-09
-8ba2,2023-02-01,2022-10-11
-3ba8,2008-11-11,2007-11-07
-1ba0,1998-07-15,1998-04-21
-3ba0,2008-07-29,2007-11-07
-7bax,2021-11-10,2020-12-16
-4bal,2012-11-14,2012-09-14
-6baw,2018-04-18,2017-10-16
-3bai,2008-03-25,2007-11-07
-6bay,2018-09-19,2017-10-16
-3baf,2008-11-11,2007-11-07
-7bap,2022-01-12,2020-12-16
-7ban,2022-01-12,2020-12-16
-2baj,2005-12-06,2005-10-14
-4bak,2013-01-16,2012-09-14
-4bap,2012-11-14,2012-09-14
-1ba9,1998-09-16,1998-04-24
-7ba4,2021-09-29,2020-12-15
-4ba0,2012-11-14,2012-09-09
-8ba9,2023-12-27,2022-10-11
-3ba6,2007-12-18,2007-11-07
-3baw,2008-03-25,2007-11-08
-3baa,2008-11-11,2007-11-07
-6bab,2017-11-29,2017-10-12
-7bao,2022-01-12,2020-12-16
-1bav,1997-04-01,1996-11-14
-6bae,2018-09-05,2017-10-12
-7ba6,2021-07-07,2020-12-15
-7bac,2022-01-12,2020-12-15
-8bad,2022-12-14,2022-10-11
-2ban,2005-12-06,2005-10-14
-8ba4,2023-02-01,2022-10-11
-8bab,2023-02-01,2022-10-11
-1bap,1992-01-15,1991-11-15
-1ba8,1999-04-27,1998-04-23
-7ba5,2021-07-07,2020-12-15
-6ba7,2018-09-05,2017-10-12
-4bad,2012-11-14,2012-09-13
-4ban,2013-01-16,2012-09-14
-3bak,2008-03-25,2007-11-08
-7ba3,2021-07-07,2020-12-15
-4ba3,2013-01-09,2012-09-11
-8ban,2024-04-03,2022-10-11
-2bal,2005-12-06,2005-10-14
-8baz,2023-10-25,2022-10-12
-4bao,2013-01-16,2012-09-14
-8bas,2023-07-12,2022-10-11
-8rng,2024-05-08,2024-01-10
-3rn1,2012-04-25,2011-04-21
-7rnu,2021-08-11,2021-07-29
-6rna,2019-07-17,2019-05-08
-1rnl,1996-11-08,1996-04-17
-7rn0,2021-08-11,2021-07-28
-6rny,2019-09-25,2019-05-09
-4rn7,2014-11-05,2014-10-23
-3rn8,2011-05-25,2011-04-22
-4rnw,2015-01-14,2014-10-26
-3rnx,2011-05-18,2011-04-24
-4rn1,2015-04-08,2014-10-22
-9rnt,1993-01-15,1991-09-25
-5rnt,1993-01-15,1991-03-28
-6rn3,2019-07-03,2019-05-07
-6rni,2019-08-28,2019-05-08
-1rnc,1994-01-31,1991-10-21
-4rnx,2015-01-14,2014-10-26
-6rn5,2019-06-19,2019-05-08
-8rny,2024-02-07,2024-01-11
-6rn4,2019-07-03,2019-05-08
-7rn1,2021-09-08,2021-07-28
-4rnv,2015-01-14,2014-10-26
-7rn7,2022-01-05,2021-07-29
-6rno,2020-04-15,2019-05-09
-6rng,2020-04-15,2019-05-08
-1rny,1996-11-08,1996-04-23
-7rny,2022-06-08,2021-07-30
-3rnm,2011-05-04,2011-04-22
-7rnn,2021-08-11,2021-07-29
-4rn6,2014-11-05,2014-10-23
-6rn9,2019-08-28,2019-05-08
-3rna,2011-08-17,2011-04-22
-6rne,2019-08-28,2019-05-08
-8rnh,2024-05-08,2024-01-10
-3rnf,2011-08-17,2011-04-22
-6rn6,2019-08-28,2019-05-08
-1rnt,1987-10-16,1987-07-10
-3rnc,2011-08-17,2011-04-22
-6rnp,2020-04-15,2019-05-09
-1rnm,1996-04-03,1995-11-08
-7rn8,2022-01-05,2021-07-29
-6rnt,1993-01-15,1991-08-20
-7rn5,2021-09-08,2021-07-29
-1rnb,1992-07-15,1991-03-19
-3rnj,2011-05-04,2011-04-22
-7rnm,2022-08-03,2021-07-29
-2rnb,2007-12-18,2007-12-08
-1rni,2004-01-27,2003-12-01
-6rnj,2019-07-17,2019-05-08
-6rn8,2019-07-17,2019-05-08
-1rnd,1994-01-31,1991-10-21
-6rnb,2019-10-02,2019-05-08
-7rnk,2021-11-10,2021-07-29
-7rnt,1993-01-15,1991-08-20
-3rne,2011-08-17,2011-04-22
-7rni,2021-09-08,2021-07-29
-7rnp,2022-08-03,2021-07-29
-8rnv,2024-01-24,2024-01-11
-6rnf,2019-10-02,2019-05-08
-4rnn,2015-02-18,2014-10-24
-3rn4,2011-11-23,2011-04-21
-4rnz,2015-03-11,2014-10-27
-4rn3,2014-11-26,2014-10-22
-3rny,2012-04-25,2011-04-24
-4rno,2015-02-18,2014-10-24
-4rny,2015-03-11,2014-10-27
-4rna,2015-03-25,2014-10-23
-3rnt,1989-10-15,1989-05-31
-1rn8,2004-09-07,2003-12-01
-4rnq,2015-05-06,2014-10-24
-7rn4,2021-11-10,2021-07-29
-8rnw,2024-01-24,2024-01-11
-7rnh,2021-11-10,2021-07-29
-2rnf,1999-11-10,1998-11-03
-6rnc,2019-10-02,2019-05-08
-7rnr,2021-11-24,2021-07-29
-4rn5,2015-10-28,2014-10-23
-7rn9,2022-01-05,2021-07-29
-4rn0,2015-04-08,2014-10-22
-1rnr,1994-01-31,1993-04-26
-3rn6,2011-08-24,2011-04-22
-1rne,1993-10-31,1991-12-12
-4rnm,2015-02-18,2014-10-24
-6rnr,2020-04-15,2019-05-09
-3rn9,2011-08-17,2011-04-22
-7rnw,2022-03-16,2021-07-30
-4rnr,2014-11-19,2014-10-24
-4rn4,2015-01-28,2014-10-22
-7rne,2022-01-05,2021-07-29
-2rnt,1989-10-15,1988-07-06
-7rna,2022-06-01,2021-07-29
-6rn2,2019-07-03,2019-05-07
-7rnf,2022-01-05,2021-07-29
-6rnk,2019-08-14,2019-05-08
-4rn2,2015-04-08,2014-10-22
-7rn2,2022-08-03,2021-07-28
-7rng,2022-06-01,2021-07-29
-6rnw,2019-10-30,2019-05-09
-7rnc,2022-06-15,2021-07-29
-7rn6,2021-11-03,2021-07-29
-3rno,2012-05-09,2011-04-22
-1rnj,2004-09-07,2003-12-01
-7rnl,2021-11-24,2021-07-29
-7rnq,2022-08-03,2021-07-29
-8rnx,2024-01-24,2024-01-11
-3rnd,2011-08-03,2011-04-22
-8rnt,1993-01-15,1991-09-23
-1rnn,1996-04-03,1995-11-08
-6rnu,2019-10-02,2019-05-09
-7rnb,2022-01-05,2021-07-29
-4rnu,2015-01-14,2014-10-26
-6rnm,2020-04-15,2019-05-09
-7rnz,2022-06-08,2021-07-30
-7rnv,2021-08-11,2021-07-29
-6rnd,2019-10-02,2019-05-08
-3rn0,2011-10-05,2011-04-21
-6rn7,2019-08-28,2019-05-08
-3rnn,2011-05-25,2011-04-22
-6rnq,2019-11-27,2019-05-09
-3rnl,2011-06-29,2011-04-22
-4rnh,2014-11-19,2014-10-24
-3rng,2011-08-17,2011-04-22
-7rnd,2022-01-05,2021-07-29
-3rnb,2011-08-17,2011-04-22
-3rni,2012-10-31,2011-04-22
-7rno,2022-05-11,2021-07-29
-7rns,2021-08-11,2021-07-29
-8by3,2023-04-12,2022-12-11
-7byv,2020-11-04,2020-04-24
-5byb,2015-07-22,2015-06-10
-5byz,2016-05-04,2015-06-11
-7by9,2021-03-24,2020-04-22
-7byx,2020-11-04,2020-04-24
-5by3,2015-07-22,2015-06-10
-2byi,2005-10-12,2005-08-02
-6byv,2018-07-18,2017-12-21
-5byd,2016-06-15,2015-06-10
-7byr,2020-06-10,2020-04-24
-1by2,1999-05-18,1998-10-23
-2bya,2006-02-06,2005-07-29
-8byq,2023-05-03,2022-12-14
-2bym,2005-11-09,2005-08-03
-8byg,2023-08-30,2022-12-12
-4by7,2013-09-11,2013-07-18
-3by0,2008-09-09,2008-01-15
-5byt,2016-07-20,2015-06-11
-7byi,2021-09-15,2020-04-23
-8byd,2023-08-02,2022-12-12
-5byy,2016-05-04,2015-06-11
-2by0,2006-02-06,2005-07-28
-1byp,1999-10-19,1998-10-19
-4byj,2013-11-20,2013-07-19
-5bye,2016-06-15,2015-06-10
-2by3,2006-02-06,2005-07-28
-1byn,1998-10-21,1998-10-18
-5byn,2015-11-18,2015-06-10
-4by0,2014-01-22,2013-07-16
-7byn,2020-12-02,2020-04-23
-2byh,2005-10-12,2005-08-02
-3byo,2008-12-30,2008-01-16
-8byb,2023-08-02,2022-12-12
-5bym,2015-09-23,2015-06-10
-6byk,2018-05-09,2017-12-20
-5byi,2015-08-05,2015-06-10
-8byh,2023-01-11,2022-12-12
-4byz,2014-04-23,2013-07-22
-3byj,2008-02-12,2008-01-16
-2byp,2005-10-05,2005-08-03
-3byz,2008-02-12,2008-01-16
-8by1,2023-12-20,2022-12-11
-6byx,2018-02-07,2017-12-21
-1byf,1999-07-23,1998-10-14
-8by6,2024-01-24,2022-12-12
-1byc,1994-07-31,1994-01-25
-4by5,2014-08-13,2013-07-17
-7byf,2021-03-24,2020-04-22
-5by4,2015-09-16,2015-06-10
-2by1,2006-02-06,2005-07-28
-2byc,2005-08-24,2005-07-29
-4byi,2013-11-20,2013-07-19
-8byk,2023-02-22,2022-12-13
-6by2,2018-05-09,2017-12-19
-2by9,2006-02-06,2005-07-29
-6bym,2018-01-17,2017-12-20
-1by5,1999-01-13,1998-10-23
-2byb,2005-08-09,2005-07-29
-2byt,2005-09-15,2005-08-04
-8byo,2023-08-02,2023-01-18
-3bya,2009-01-20,2008-01-15
-6by1,2019-02-27,2017-12-19
-8byi,2023-07-12,2022-12-13
-6byp,2018-02-07,2017-12-21
-4byg,2014-08-06,2013-07-19
-1byu,1998-12-02,1998-10-18
-5byc,2016-06-15,2015-06-10
-7byw,2020-05-27,2020-04-24
-4by4,2014-08-13,2013-07-17
-8byj,2023-09-20,2022-12-13
-3byx,2009-01-20,2008-01-16
-3by6,2008-02-19,2008-01-15
-5byj,2015-09-30,2015-06-10
-8by2,2023-12-27,2022-12-11
-8by9,2023-08-02,2022-12-12
-2by8,2006-02-06,2005-07-29
-2byo,2006-03-22,2005-08-03
-2by4,2006-04-07,2005-07-28
-5byu,2015-06-24,2015-06-11
-4bya,2014-06-18,2013-07-18
-8byn,2023-01-11,2022-12-13
-3by9,2008-08-12,2008-01-15
-5by0,2015-07-29,2015-06-09
-6by8,2018-11-28,2017-12-20
-6by3,2018-05-09,2017-12-19
-1byg,1999-10-14,1998-10-14
-1byb,1994-07-31,1994-01-25
-2byq,2005-10-05,2005-08-03
-6byt,2018-02-07,2017-12-21
-3byn,2008-02-12,2008-01-16
-7by4,2021-02-17,2020-04-21
-3byu,2008-09-16,2008-01-16
-7by5,2021-02-17,2020-04-21
-6byr,2019-04-03,2017-12-21
-2bys,2005-10-05,2005-08-04
-2by7,2006-02-06,2005-07-29
-8byf,2023-08-02,2022-12-12
-1bye,1998-10-21,1998-10-14
-7by1,2020-08-26,2020-04-21
-4by6,2013-10-16,2013-07-18
-2by5,2006-02-06,2005-07-29
-2byn,2005-10-05,2005-08-03
-2byj,2005-09-07,2005-08-02
-3bys,2008-09-16,2008-01-16
-6byu,2018-01-17,2017-12-21
-6byl,2018-05-09,2017-12-20
-7byq,2021-04-28,2020-04-24
-7byd,2021-03-31,2020-04-22
-8bye,2023-08-02,2022-12-12
-6by0,2018-01-24,2017-12-19
-5byr,2015-11-11,2015-06-10
-7bya,2021-03-24,2020-04-22
-6byg,2018-07-18,2017-12-20
-7byl,2020-12-02,2020-04-23
-4by1,2013-09-11,2013-07-17
-6bya,2018-01-17,2017-12-20
-3bym,2008-09-16,2008-01-16
-7bym,2020-12-02,2020-04-23
-5byf,2016-06-15,2015-06-10
-6bye,2018-07-18,2017-12-20
-1byh,1993-10-31,1992-12-31
-6byj,2018-05-09,2017-12-20
-4bym,2013-09-18,2013-07-20
-6byz,2019-04-03,2017-12-21
-5byg,2015-09-23,2015-06-10
-5byl,2016-05-25,2015-06-10
-1byd,1994-07-31,1994-01-25
-1by4,2000-01-12,1998-10-22
-8byc,2023-08-02,2022-12-12
-1byv,1998-10-28,1998-10-16
-8byz,2023-08-02,2022-12-14
-2by6,2006-02-06,2005-07-29
-3byk,2008-02-12,2008-01-16
-2byl,2005-09-07,2005-08-03
-8byy,2023-08-02,2022-12-14
-1byq,1998-10-28,1998-10-19
-6byi,2018-07-18,2017-12-20
-3byr,2008-09-23,2008-01-16
-3byw,2008-02-19,2008-01-16
-3byc,2009-01-27,2008-01-15
-6byb,2018-01-24,2017-12-20
-8by0,2023-12-20,2022-12-11
-7bys,2020-11-04,2020-04-24
-7byt,2020-11-04,2020-04-24
-5byk,2015-09-30,2015-06-10
-2by2,2006-02-06,2005-07-28
-1byo,1999-10-15,1998-10-19
-6byw,2018-02-14,2017-12-21
-7by6,2020-11-04,2020-04-21
-5by6,2015-06-17,2015-06-10
-5byq,2015-11-11,2015-06-10
-8by5,2023-08-16,2022-12-12
-2byr,2005-10-05,2005-08-03
-4by3,2014-05-28,2013-07-17
-3byv,2008-01-29,2008-01-16
-4byf,2014-03-26,2013-07-19
-5bys,2015-11-11,2015-06-10
-5bya,2015-07-22,2015-06-10
-4wf2,2014-10-22,2014-09-11
-5wfj,2017-10-04,2017-07-12
-4wfg,2014-12-03,2014-09-15
-5wfz,2017-12-27,2017-07-13
-4wf9,2015-10-21,2014-09-14
-8wfl,2024-04-03,2023-09-19
-8wfk,2024-04-03,2023-09-19
-8wfi,2024-04-03,2023-09-19
-2wft,2009-06-30,2009-04-15
-1wfl,2004-11-26,2004-05-26
-4wff,2014-12-03,2014-09-15
-8wfq,2023-11-22,2023-09-20
-3wf7,2014-08-06,2013-07-17
-6wf2,2020-06-17,2020-04-03
-4wf0,2014-12-24,2014-09-11
-7wfy,2022-12-07,2021-12-27
-4wfx,2014-10-22,2014-09-17
-8wfv,2023-10-04,2023-09-20
-3wf9,2014-08-06,2013-07-17
-2wf8,2010-05-26,2009-04-03
-4wf4,2015-01-21,2014-09-12
-6wft,2020-06-24,2020-04-04
-2wfx,2009-06-30,2009-04-15
-3wfc,2014-05-28,2013-07-18
-3wf3,2014-04-23,2013-07-16
-3wf1,2014-04-23,2013-07-16
-2wfq,2009-06-30,2009-04-14
-6wfk,2020-07-01,2020-04-03
-6wf1,2020-11-25,2020-04-03
-3wf5,2014-08-06,2013-07-17
-2wfg,2009-05-19,2009-04-05
-3wf4,2014-04-16,2013-07-16
-5wfv,2018-09-19,2017-07-12
-4wf7,2014-12-24,2014-09-13
-4wfa,2015-10-21,2014-09-14
-3wfh,2014-07-23,2013-07-19
-1wfe,2004-11-26,2004-05-26
-6wf6,2020-07-08,2020-04-03
-2wf5,2009-09-15,2009-04-03
-5wfw,2018-01-03,2017-07-12
-2wf9,2010-05-26,2009-04-03
-2wf6,2010-05-26,2009-04-03
-3wfg,2013-08-21,2013-07-19
-3wfx,2014-08-06,2013-07-24
-4wfe,2014-12-03,2014-09-15
-4wf5,2015-01-21,2014-09-12
-7wfc,2022-12-28,2021-12-26
-3wfr,2014-01-01,2013-07-23
-1wfx,2004-11-27,2004-05-27
-2wfo,2009-06-16,2009-04-09
-3wfe,2014-05-28,2013-07-18
-6wf4,2021-04-07,2020-04-03
-6wfn,2020-07-01,2020-04-03
-8wfu,2023-10-04,2023-09-20
-3wfb,2014-05-28,2013-07-18
-8wft,2023-10-04,2023-09-20
-6wf3,2020-07-01,2020-04-03
-2wfr,2009-06-30,2009-04-14
-6wfv,2021-04-14,2020-04-04
-6wf5,2020-07-01,2020-04-03
-6wfj,2020-09-09,2020-04-03
-6wfh,2020-07-08,2020-04-03
-6wfs,2020-06-03,2020-04-03
-3wfa,2014-07-16,2013-07-18
-5wf7,2018-06-27,2017-07-11
-2wf3,2009-05-19,2009-04-02
-5wfo,2018-05-23,2017-07-12
-2wfz,2009-08-11,2009-04-15
-5wfn,2017-08-30,2017-07-12
-1wfp,2004-11-26,2004-05-26
-7wfx,2022-09-14,2021-12-27
-8wfy,2023-11-22,2023-09-20
-4wfk,2014-12-24,2014-09-15
-5wf5,2018-02-21,2017-07-11
-3wf0,2014-04-23,2013-07-16
-6wf7,2020-07-08,2020-04-03
-5wfp,2018-05-23,2017-07-12
-5wfs,2018-05-02,2017-07-12
-5wf0,2018-05-02,2017-07-11
-2wf4,2009-05-12,2009-04-02
-2wf7,2010-05-19,2009-04-03
-4wf1,2014-11-05,2014-09-11
-3wfz,2013-10-09,2013-07-25
-5wfk,2018-05-02,2017-07-12
-8wfw,2023-10-04,2023-09-20
-3wf8,2014-08-06,2013-07-17
-5wfq,2018-05-23,2017-07-12
-5wfd,2018-06-27,2017-07-11
-7wfe,2022-03-16,2021-12-26
-2wfi,2009-06-16,2009-04-06
-3wfd,2014-05-28,2013-07-18
-2wfa,2010-05-26,2009-04-03
-5wfi,2018-08-01,2017-07-12
-5wfr,2018-05-23,2017-07-12
-6wf0,2020-11-25,2020-04-03
-3wfl,2014-07-23,2013-07-19
-1wfk,2004-11-26,2004-05-26
-1wf3,2004-11-25,2004-05-25
-5wf6,2018-02-21,2017-07-11
-5wfg,2019-01-16,2017-07-11
-8wfj,2024-04-03,2023-09-19
-1wfh,2004-11-26,2004-05-26
-1wff,2004-11-26,2004-05-26
-2wfj,2009-06-16,2009-04-06
-4wfh,2014-12-03,2014-09-15
-6wfx,2020-07-29,2020-04-04
-4wfd,2014-10-29,2014-09-14
-6wfl,2020-07-08,2020-04-03
-7wfr,2022-08-03,2021-12-27
-5wf3,2018-01-03,2017-07-11
-3wft,2014-12-03,2013-07-23
-7wfw,2022-08-03,2021-12-27
-7wfd,2022-03-16,2021-12-26
-7wf5,2022-03-02,2021-12-26
-4wf6,2015-09-09,2014-09-12
-4wf8,2014-10-08,2014-09-13
-5wfm,2018-01-03,2017-07-12
-2wfk,2009-11-24,2009-04-07
-7wf4,2022-02-09,2021-12-25
-3wff,2013-08-21,2013-07-19
-4wfn,2015-12-23,2014-09-16
-4wfj,2014-12-24,2014-09-15
-3wfw,2014-08-06,2013-07-24
-6wfw,2020-07-29,2020-04-04
-1wfz,2004-11-27,2004-05-27
-5wfc,2018-06-27,2017-07-11
-2wf2,2009-05-19,2009-04-02
-3wfj,2014-07-23,2013-07-19
-2wfy,2009-06-09,2009-04-15
-7wf3,2022-02-09,2021-12-25
-4wfb,2015-10-21,2014-09-14
-3wf2,2014-04-16,2013-07-16
-3wfu,2014-12-03,2013-07-23
-4wfs,2015-10-07,2014-09-17
-4wfz,2014-10-22,2014-09-17
-4wfr,2015-09-30,2014-09-17
-6wfi,2020-07-08,2020-04-03
-6wfo,2020-07-01,2020-04-03
-2wf1,2009-05-19,2009-04-02
-3wf6,2014-08-06,2013-07-17
-4wfo,2015-09-30,2014-09-16
-6wfg,2020-07-01,2020-04-03
-2wf0,2009-05-19,2009-04-02
-6yko,2020-12-02,2020-04-06
-4ykn,2015-06-17,2015-03-04
-5ykw,2018-10-24,2017-10-16
-1ykg,2005-07-05,2005-01-18
-4ykr,2016-03-09,2015-03-04
-1ykn,2005-08-16,2005-01-18
-6yk3,2020-06-03,2020-04-05
-7yka,2023-08-02,2022-07-22
-2ykc,2011-10-19,2011-05-26
-1yk4,2006-01-17,2005-01-17
-6yks,2020-12-02,2020-04-06
-4ykq,2016-03-09,2015-03-04
-1ykp,2005-08-16,2005-01-18
-1ykj,2005-07-26,2005-01-18
-1ykf,1998-01-14,1996-03-25
-1ykz,2005-07-05,2005-01-18
-4ykt,2016-03-09,2015-03-04
-2yk2,2011-10-19,2011-05-25
-4yku,2016-03-09,2015-03-04
-7yk9,2023-01-25,2022-07-22
-7yk5,2023-06-21,2022-07-21
-2yk3,2011-06-15,2011-05-25
-6ykf,2020-12-23,2020-04-06
-4yko,2016-03-09,2015-03-04
-4yki,2015-10-21,2015-03-04
-5ykb,2017-10-25,2017-10-13
-7ykn,2022-12-21,2022-07-23
-4yky,2016-03-09,2015-03-04
-5ykc,2018-10-17,2017-10-13
-5ykd,2018-02-21,2017-10-14
-7ykb,2023-01-25,2022-07-22
-1ykx,2005-07-05,2005-01-18
-5ykp,2018-10-17,2017-10-15
-1ykk,2005-08-16,2005-01-18
-5yka,2018-09-05,2017-10-12
-2yk7,2011-08-31,2011-05-25
-7ykz,2022-12-14,2022-07-25
-6ykq,2020-12-02,2020-04-06
-6yke,2020-07-15,2020-04-06
-1yk8,2005-07-19,2005-01-17
-2ykk,2011-06-22,2011-05-27
-4ykw,2016-03-09,2015-03-04
-1ykc,2005-01-25,2005-01-17
-1ykd,2005-02-22,2005-01-17
-6ykx,2020-12-02,2020-04-06
-6ykb,2021-02-17,2020-04-06
-6ykn,2020-12-02,2020-04-06
-2ykx,2012-05-30,2011-05-30
-2yki,2011-10-19,2011-05-27
-2yk6,2011-08-31,2011-05-25
-2ykl,2011-11-16,2011-05-27
-6yk5,2020-06-03,2020-04-05
-2yky,2012-05-30,2011-05-30
-6ykj,2020-07-15,2020-04-06
-1ykl,2005-08-16,2005-01-18
-1yki,2005-02-08,2005-01-18
-1yko,2005-08-16,2005-01-18
-2ykj,2011-10-19,2011-05-27
-4yke,2015-06-03,2015-03-04
-5ykn,2017-12-27,2017-10-15
-6yk6,2020-06-03,2020-04-05
-7ykv,2023-07-26,2022-07-24
-5yku,2018-10-24,2017-10-16
-4ykg,2015-07-15,2015-03-04
-2yk1,2011-11-16,2011-05-25
-6yku,2020-12-02,2020-04-06
-5ykj,2018-10-24,2017-10-14
-2yk4,2011-08-31,2011-05-25
-7ykt,2022-12-14,2022-07-23
-7yk7,2023-03-01,2022-07-21
-4ykm,2016-03-09,2015-03-04
-6ykv,2020-12-02,2020-04-06
-2ykg,2011-10-26,2011-05-27
-6ykg,2021-04-14,2020-04-06
-2ykz,2011-10-05,2011-05-30
-7yk1,2023-08-02,2022-07-21
-4ykx,2016-03-09,2015-03-04
-2yk9,2011-10-26,2011-05-26
-1yky,2005-07-05,2005-01-18
-6ykl,2020-12-02,2020-04-06
-5ykx,2018-10-24,2017-10-16
-4ykk,2015-10-21,2015-03-04
-7ykl,2022-12-14,2022-07-22
-1ykm,2005-08-16,2005-01-18
-7yke,2022-11-30,2022-07-22
-6ykd,2020-07-01,2020-04-06
-7yk4,2023-08-09,2022-07-21
-4ykl,2015-06-03,2015-03-04
-1yk0,2006-04-18,2005-01-16
-6ykw,2020-12-02,2020-04-06
-1ykt,2006-04-25,2005-01-18
-1ykb,2005-07-12,2005-01-17
-7yk6,2023-03-01,2022-07-21
-5yk4,2017-11-22,2017-10-12
-8yk5,2024-04-03,2024-03-04
-6yk8,2021-02-10,2020-04-05
-4ykj,2015-10-21,2015-03-04
-1ykr,2006-01-24,2005-01-18
-5yko,2017-12-27,2017-10-15
-6yk7,2020-04-15,2020-04-05
-6ykk,2020-12-02,2020-04-06
-4yk0,2016-04-20,2015-03-03
-1yk7,2005-03-22,2005-01-17
-6yki,2020-07-15,2020-04-06
-5ykf,2018-04-18,2017-10-14
-5yk2,2018-02-07,2017-10-11
-5yk0,2018-02-07,2017-10-11
-2yke,2011-10-19,2011-05-26
-6yky,2020-09-23,2020-04-06
-4ykf,2015-07-15,2015-03-04
-2yku,2012-05-30,2011-05-30
-5yke,2018-04-18,2017-10-14
-6yk2,2020-06-03,2020-04-05
-4ykh,2015-09-09,2015-03-04
-4ykp,2015-10-21,2015-03-04
-5yki,2018-03-14,2017-10-14
-2ykm,2011-08-17,2011-05-28
-5yky,2018-09-26,2017-10-16
-2yk0,2012-05-30,2011-05-25
-2ykb,2011-10-19,2011-05-26
-1yk5,2006-01-17,2005-01-17
-6yk9,2021-02-17,2020-04-06
-2ykn,2011-08-17,2011-05-28
-5yk1,2018-02-07,2017-10-11
-7ykd,2023-04-19,2022-07-22
-4yk5,2015-07-15,2015-03-04
-6yk4,2020-06-03,2020-04-05
-5ykg,2018-04-18,2017-10-14
-2yk5,2011-08-31,2011-05-25
-6yk1,2021-04-14,2020-04-05
-6ykz,2020-07-15,2020-04-06
-5ykt,2018-09-26,2017-10-16
-2ykv,2012-05-30,2011-05-30
-6ykt,2020-12-02,2020-04-06
-1yk1,2006-04-18,2005-01-16
-4yka,2016-01-27,2015-03-04
-6yk0,2021-04-14,2020-04-05
-7ykk,2022-12-14,2022-07-22
-4yk4,2015-05-27,2015-03-03
-4ykz,2016-03-09,2015-03-04
-3pan,2010-12-22,2010-10-19
-4pao,2014-07-30,2014-04-09
-5pa3,2017-11-22,2016-10-19
-5pam,2017-06-21,2016-11-10
-7pac,2022-06-08,2021-07-29
-4pan,2014-07-30,2014-04-09
-6pay,2019-09-18,2019-06-12
-6pa7,2020-06-17,2019-06-11
-6pah,1999-04-27,1998-08-20
-4pam,2014-07-30,2014-04-09
-8pag,2024-03-27,2023-06-07
-4pad,1977-04-12,1976-11-01
-7pav,2021-11-17,2021-07-30
-6pa1,2020-12-16,2019-06-11
-3pak,2010-11-03,2010-10-19
-4pa0,2015-07-08,2014-04-06
-5pa0,2017-11-22,2016-10-19
-4pae,2015-01-14,2014-04-08
-7pad,2022-06-08,2021-07-29
-5pat,2017-06-21,2016-11-10
-7paz,1997-08-20,1997-02-21
-6par,2020-06-24,2019-06-11
-3pa1,2011-05-11,2010-10-18
-2pas,1994-06-22,1994-03-22
-2pau,2008-03-04,2007-03-27
-5pa9,2017-06-21,2016-11-10
-2pax,1998-05-27,1997-11-25
-6paz,1997-08-20,1997-02-21
-5pae,2017-06-21,2016-11-10
-6pa5,2019-09-04,2019-06-11
-4pa7,2014-06-04,2014-04-07
-5pa7,2017-11-22,2016-10-19
-4pa3,2014-06-04,2014-04-07
-7pa3,2022-08-10,2021-07-28
-4paw,2015-05-06,2014-04-10
-7pa0,2022-08-10,2021-07-28
-3pah,1999-04-27,1998-08-20
-3paa,2010-12-01,2010-10-19
-6pau,2020-03-11,2019-06-11
-2pak,2007-04-24,2007-03-27
-5pan,2017-06-21,2016-11-10
-4pag,2014-04-30,2014-04-08
-5pah,1999-04-27,1998-08-20
-5pav,2017-06-21,2016-11-10
-5pay,2017-06-21,2016-11-10
-5pau,2017-06-21,2016-11-10
-7paw,2021-11-17,2021-07-30
-2pa2,2008-03-11,2007-03-27
-3pab,2011-10-19,2010-10-19
-4pa5,2015-09-30,2014-04-07
-1pah,1999-01-13,1997-10-25
-5pak,2017-06-21,2016-11-10
-3pat,1994-07-31,1994-03-22
-6pat,2019-10-23,2019-06-11
-6paa,2019-09-04,2019-06-11
-1pax,1997-05-15,1996-05-06
-6pab,2019-09-04,2019-06-11
-7pae,2022-06-08,2021-07-29
-2paf,2007-06-19,2007-03-27
-3pav,2011-10-19,2010-10-19
-3pa5,2010-12-08,2010-10-18
-8pai,2023-06-14,2023-06-07
-5paa,2017-06-21,2016-11-10
-6pac,2019-09-04,2019-06-11
-5paw,2017-06-21,2016-11-10
-2pae,2007-04-24,2007-03-27
-2pad,1977-04-12,1976-11-01
-3pae,2011-01-19,2010-10-19
-1pa9,2003-11-04,2003-05-13
-1pad,1977-04-12,1976-11-01
-7pal,2022-05-25,2021-07-30
-8pa9,2023-06-14,2023-06-07
-3pa8,2010-12-15,2010-10-18
-4pa9,2014-06-04,2014-04-07
-6pav,2020-03-11,2019-06-12
-5paq,2017-06-21,2016-11-10
-8pat,2024-03-13,2023-06-08
-6paw,2020-06-17,2019-06-12
-6pak,2019-10-23,2019-06-11
-5pac,2017-06-21,2016-11-10
-8pae,2024-03-27,2023-06-07
-1pam,1997-01-11,1996-07-08
-4pal,1992-01-15,1990-11-08
-5paj,2017-06-21,2016-11-10
-4pab,2014-06-18,2014-04-07
-6pa3,2019-09-04,2019-06-11
-3pa9,2010-12-01,2010-10-19
-3pao,2010-12-22,2010-10-19
-4paz,1997-08-20,1997-02-20
-8pab,2024-03-27,2023-06-07
-2pam,2007-04-24,2007-03-27
-8pa6,2023-06-14,2023-06-07
-4pa6,2014-06-04,2014-04-07
-8paq,2024-02-07,2023-06-08
-5paz,1997-08-20,1997-02-21
-5paf,2017-06-21,2016-11-10
-6pa6,2019-09-04,2019-06-11
-6pa4,2019-09-04,2019-06-11
-5pas,2017-06-21,2016-11-10
-2pal,1992-01-15,1990-11-08
-2pag,2007-04-03,2007-03-27
-6pa2,2019-09-04,2019-06-11
-6pag,2020-12-16,2019-06-11
-6pae,2019-09-04,2019-06-11
-5pa1,2017-11-22,2016-10-19
-4pay,2014-06-25,2014-04-10
-1pau,1997-07-07,1996-06-06
-5pa5,2017-11-22,2016-10-19
-6pai,2019-09-18,2019-06-11
-3pal,1992-01-15,1990-11-08
-2paj,2007-04-03,2007-03-27
-3pag,2011-01-19,2010-10-19
-3pa3,2010-12-08,2010-10-18
-4paq,2014-07-30,2014-04-09
-6pao,2020-06-24,2019-06-11
-6pam,2020-06-24,2019-06-11
-1pag,1994-01-31,1992-10-19
-2pav,2007-10-23,2007-03-27
-4pak,2014-05-07,2014-04-09
-5pag,2017-06-21,2016-11-10
-4pai,2014-05-07,2014-04-09
-4pa4,2014-06-04,2014-04-07
-5par,2017-06-21,2016-11-10
-2paa,2007-11-27,2007-03-27
-6pas,2019-10-23,2019-06-11
-3pau,2011-10-19,2010-10-19
-3paj,2010-11-03,2010-10-19
-2pah,1999-10-06,1998-05-26
-2pa0,2007-10-02,2007-03-27
-5pal,1993-10-31,1991-09-25
-6pa9,2019-09-04,2019-06-11
-5pa6,2017-11-22,2016-10-19
-6pad,1977-04-12,1976-11-01
-4paa,2014-06-18,2014-04-07
-3pa4,2010-12-08,2010-10-18
-5pa8,2017-06-21,2016-11-10
-6pan,2020-06-24,2019-06-11
-2pac,1993-10-31,1993-05-05
-3pa7,2012-02-29,2010-10-18
-1pal,1992-01-15,1990-11-08
-1pa2,2000-11-15,1999-05-18
-3pa2,2011-05-11,2010-10-18
-7pax,2022-06-01,2021-07-30
-4pa8,2015-04-01,2014-04-07
-8paf,2023-06-14,2023-06-07
-3paz,1997-08-20,1997-02-20
-5pad,1977-04-12,1976-11-01
-1paz,1988-10-09,1988-06-28
-7pab,2022-01-19,2021-07-29
-2pan,2008-01-01,2007-03-27
-5pax,2017-06-21,2016-11-10
-2pa4,2007-04-10,2007-03-27
-5pa2,2017-11-22,2016-10-19
-7pag,2022-02-16,2021-07-29
-5pab,2017-06-21,2016-11-10
-7pa4,2021-10-13,2021-07-28
-6paf,2020-01-15,2019-06-11
-5pai,2017-06-21,2016-11-10
-1pa1,2003-08-05,2003-05-13
-1paa,1994-10-15,1994-07-15
-7pay,2022-06-01,2021-07-30
-4pax,1998-05-27,1997-11-25
-5pao,2017-06-21,2016-11-10
-7pa2,2022-08-10,2021-07-28
-8pay,2024-03-13,2023-06-08
-2par,2008-03-04,2007-03-27
-8paz,1997-08-20,1997-02-24
-2pa3,2007-04-24,2007-03-27
-2pa7,2007-04-24,2007-03-27
-6pa8,2019-09-04,2019-06-11
-4pah,1999-04-27,1998-08-20
-5pa4,2017-11-22,2016-10-19
-3par,2010-11-03,2010-10-19
-6pa0,2019-08-07,2019-06-11
-6paq,2020-06-24,2019-06-11
-3pax,1998-05-27,1997-11-25
-7pa1,2022-08-10,2021-07-28
-3paq,2010-11-03,2010-10-19
-3png,2011-10-05,2010-11-18
-1pnn,1996-03-08,1995-10-13
-5pnj,2017-03-15,2017-02-07
-5pnm,2017-03-15,2017-02-07
-5pnr,2017-03-15,2017-02-07
-5pn8,2017-03-15,2017-02-07
-2pnk,2007-05-08,2007-04-24
-8pn3,2024-03-06,2023-06-29
-5pn2,2017-03-15,2017-02-07
-5pnq,2017-03-15,2017-02-07
-7pnf,2022-02-23,2021-09-06
-5pn3,2017-03-15,2017-02-07
-7pn5,2023-01-25,2021-09-06
-5pnb,2017-03-15,2017-02-07
-3pnu,2010-12-01,2010-11-19
-1pnl,1996-03-16,1995-03-16
-8pnw,2023-10-25,2023-07-03
-7pnw,2022-06-15,2021-09-08
-6pnd,2020-04-29,2019-07-02
-7pni,2021-10-27,2021-09-07
-5pn4,2017-03-15,2017-02-07
-4pnv,2014-03-05,2014-02-21
-2pnr,2007-08-21,2007-04-25
-6pna,2020-04-29,2019-07-02
-2pnc,2008-02-26,2007-04-24
-5pnc,2017-03-15,2017-02-07
-3pn6,2011-06-08,2010-11-18
-4pne,2015-02-18,2014-05-23
-7pnt,2022-06-15,2021-09-08
-6pnb,2020-04-29,2019-07-02
-1pnc,1994-01-31,1993-09-22
-5pna,2017-03-15,2017-02-07
-7pn4,2023-01-25,2021-09-06
-1pnd,1994-01-31,1993-09-22
-2pnn,2007-07-03,2007-04-24
-3pnb,2011-06-22,2010-11-18
-6pnf,2020-04-29,2019-07-02
-4pnu,2014-03-05,2014-02-21
-4pn2,2014-10-08,2014-05-22
-3pni,2011-04-13,2010-11-19
-7pn6,2023-01-25,2021-09-06
-4pnn,2014-10-15,2014-05-24
-6pnr,2020-07-08,2019-07-03
-5pnv,2017-03-15,2017-02-07
-6pnz,2020-07-08,2019-07-03
-3pnc,2011-02-02,2010-11-18
-8pn7,2023-11-29,2023-06-30
-6pn9,2020-04-29,2019-07-02
-7pn9,2023-01-25,2021-09-06
-6pnm,2019-07-24,2019-07-02
-1pnk,1996-03-16,1995-03-16
-4pn1,2014-11-12,2014-05-22
-5pn9,2017-03-15,2017-02-07
-1pn4,2004-04-13,2003-06-12
-7pnz,2022-06-15,2021-09-08
-5pnp,2017-03-15,2017-02-07
-6pnj,2020-02-12,2019-07-02
-8pnv,2024-04-03,2023-07-02
-5pnu,2017-03-15,2017-02-07
-1pnr,1995-11-20,1995-03-29
-6pno,2019-07-24,2019-07-02
-2pnx,2008-04-15,2007-04-25
-6pn3,2020-04-29,2019-07-02
-7pnx,2022-06-15,2021-09-08
-5pny,2017-03-15,2017-02-07
-8pnd,2023-11-01,2023-06-30
-5pn5,2017-03-15,2017-02-07
-1pno,2003-11-11,2003-06-12
-4pnr,2014-10-15,2014-05-24
-2pnz,2008-03-18,2007-04-25
-6pn7,2020-04-29,2019-07-02
-3pnl,2011-01-12,2010-11-19
-6pnx,2020-01-22,2019-07-03
-6pn8,2020-04-29,2019-07-02
-1pnf,1996-03-08,1995-10-11
-7pnh,2021-10-27,2021-09-07
-4pnt,2014-10-15,2014-05-25
-5pnd,2017-03-15,2017-02-07
-3pnq,2011-01-12,2010-11-19
-6pn1,2020-04-29,2019-07-02
-6pnv,2019-07-17,2019-07-03
-6pnh,2020-04-29,2019-07-02
-3pn2,2011-06-08,2010-11-18
-8pny,2023-10-25,2023-07-03
-6pne,2020-04-29,2019-07-02
-1pn0,2003-09-23,2003-06-12
-4pnc,2014-07-23,2014-05-23
-3pnd,2011-01-05,2010-11-18
-1pnv,2003-08-12,2003-06-13
-3pnr,2011-07-27,2010-11-19
-3pnh,2011-10-05,2010-11-18
-7pn7,2023-01-25,2021-09-06
-4pnf,2015-05-27,2014-05-23
-2pny,2007-05-29,2007-04-25
-7pnm,2022-04-20,2021-09-07
-5pn1,2017-03-15,2017-02-07
-8pnq,2024-02-21,2023-06-30
-2pno,2007-08-07,2007-04-24
-2pnu,2007-09-11,2007-04-25
-5pnk,2017-03-15,2017-02-07
-6pn2,2020-04-29,2019-07-02
-8pn9,2024-05-08,2023-06-30
-5pnh,2017-03-15,2017-02-07
-3pna,2011-02-09,2010-11-18
-2pn5,2007-07-24,2007-04-23
-6png,2020-04-29,2019-07-02
-6pnc,2020-04-29,2019-07-02
-3pn3,2011-06-08,2010-11-18
-4pny,2014-03-12,2014-02-22
-3pn1,2011-01-12,2010-11-18
-2pnq,2007-08-21,2007-04-25
-5pno,2017-03-15,2017-02-07
-8pnt,2024-01-17,2023-07-01
-4pnk,2014-10-08,2014-05-23
-4pn6,2014-07-23,2014-05-23
-4pnm,2014-10-15,2014-05-23
-3pnf,2011-11-02,2010-11-18
-5pnx,2017-03-15,2017-02-07
-7pn8,2023-01-25,2021-09-06
-7pnv,2022-06-15,2021-09-08
-5pns,2017-03-15,2017-02-07
-3pn7,2011-01-05,2010-11-18
-7pnd,2022-09-14,2021-09-06
-7pny,2022-06-15,2021-09-08
-5png,2017-03-15,2017-02-07
-3pnx,2010-12-15,2010-11-19
-7pns,2022-09-21,2021-09-07
-4pnw,2014-03-05,2014-02-21
-4pnx,2014-03-12,2014-02-22
-5pnf,2017-03-15,2017-02-07
-6pnn,2019-07-24,2019-07-02
-3pnp,1999-03-30,1998-03-27
-6pn4,2020-04-29,2019-07-02
-4pnz,2014-04-09,2014-02-22
-7pn0,2021-09-29,2021-09-04
-1pn3,2003-08-12,2003-06-12
-6pnl,2020-07-08,2019-07-02
-8pnu,2024-04-03,2023-07-02
-6pn6,2020-04-29,2019-07-02
-2pn6,2008-04-29,2007-04-23
-5pn7,2017-03-15,2017-02-07
-4pno,2014-11-19,2014-05-24
-1pnq,2003-11-11,2003-06-12
-6pn0,2020-04-29,2019-07-02
-8pn5,2024-03-06,2023-06-29
-6pn5,2020-04-29,2019-07-02
-4pnl,2014-10-15,2014-05-23
-8pnz,2024-06-05,2023-07-03
-7pnq,2022-04-20,2021-09-07
-3pns,2010-12-15,2010-11-19
-5pnw,2017-03-15,2017-02-07
-7pnk,2022-08-17,2021-09-07
-4pnq,2014-10-15,2014-05-24
-3pn4,2011-06-08,2010-11-18
-8pn2,2024-04-17,2023-06-29
-1pn9,2003-12-09,2003-06-12
-4png,2015-05-27,2014-05-23
-3pnz,2011-11-23,2010-11-20
-5pnn,2017-03-15,2017-02-07
-5pni,2017-03-15,2017-02-07
-3pne,2011-11-02,2010-11-18
-5pn6,2017-03-15,2017-02-07
-5pnl,2017-03-15,2017-02-07
-7pnu,2022-06-15,2021-09-08
-8pn8,2023-11-29,2023-06-30
-7pnc,2022-09-14,2021-09-06
-7pnb,2022-09-14,2021-09-06
-4pnj,2014-11-05,2014-05-23
-8pn1,2024-04-17,2023-06-29
-2pnj,2007-10-02,2007-04-24
-5pn0,2017-03-15,2017-02-07
-3pn5,2011-06-08,2010-11-18
-4pni,2014-10-08,2014-05-23
-1pnm,1996-03-16,1995-03-16
-7pna,2023-01-25,2021-09-06
-5pnz,2017-03-15,2017-02-07
-4pns,2014-10-15,2014-05-25
-5pne,2017-03-15,2017-02-07
-4bbv,2012-11-14,2012-09-28
-8bbs,2023-03-08,2022-10-14
-6bbz,2018-02-28,2017-10-20
-1bbp,1991-10-15,1990-09-19
-7bb9,2022-07-13,2020-12-17
-3bb6,2007-11-20,2007-11-09
-7bbp,2021-03-03,2020-12-18
-2bbv,1994-08-31,1994-06-06
-8bb5,2022-11-09,2022-10-12
-4bbq,2012-10-10,2012-09-27
-4bbm,2012-10-17,2012-09-26
-2bb0,2006-09-26,2005-10-16
-4bby,2012-11-07,2012-09-28
-7bbu,2022-01-12,2020-12-18
-8bbh,2022-12-21,2022-10-13
-6bba,2018-07-11,2017-10-17
-8bbv,2023-01-11,2022-10-14
-2bbo,2005-11-01,2005-10-17
-2bb9,2005-11-15,2005-10-17
-6bbd,2018-05-23,2017-10-18
-3bb8,2008-09-16,2007-11-09
-7bbn,2022-01-19,2020-12-18
-4bb6,2012-11-28,2012-09-20
-4bbg,2013-05-15,2012-09-22
-1bb6,1999-05-04,1998-04-29
-4bb3,2013-04-17,2012-09-19
-3bb3,2008-04-01,2007-11-09
-7bb2,2021-03-03,2020-12-16
-7bbo,2021-03-03,2020-12-18
-6bbu,2018-01-17,2017-10-19
-7bbd,2021-01-27,2020-12-17
-1bb0,1999-04-27,1998-04-28
-2bbt,2005-11-01,2005-10-17
-7bbg,2021-10-27,2020-12-17
-7bbt,2021-10-20,2020-12-18
-3bbx,2008-10-21,2007-11-11
-8bbt,2023-07-12,2022-10-14
-3bbh,2008-02-05,2007-11-09
-8bbz,2023-10-25,2022-10-14
-6bb0,2018-10-24,2017-10-16
-7bbr,2021-03-24,2020-12-18
-2bbn,1994-01-31,1992-07-16
-7bb1,2021-10-20,2020-12-16
-2bbs,2005-11-01,2005-10-17
-4bbt,2012-11-14,2012-09-27
-1bbh,1994-01-31,1992-05-18
-4bb0,2013-10-09,2012-09-17
-3bbp,2008-02-05,2007-11-09
-3bbb,2008-09-23,2007-11-09
-7bbj,2021-12-29,2020-12-17
-3bby,2007-11-20,2007-11-11
-2bbh,2005-12-13,2005-10-17
-4bbo,2013-10-16,2012-09-27
-6bbt,2018-10-24,2017-10-19
-1bb5,1998-08-12,1998-04-28
-8bbj,2024-04-03,2022-10-13
-8bb7,2023-05-03,2022-10-12
-3bb4,2008-04-01,2007-11-09
-6bbs,2018-02-28,2017-10-19
-6bbv,2018-01-17,2017-10-19
-6bbe,2018-05-23,2017-10-18
-6bb5,2018-01-10,2017-10-16
-4bbp,2013-10-16,2012-09-27
-7bb4,2021-03-17,2020-12-16
-2bbb,2005-11-15,2005-10-17
-2bb7,2006-01-24,2005-10-17
-8bb8,2023-04-19,2022-10-12
-4bbj,2013-12-11,2012-09-25
-1bbb,1993-10-31,1992-04-29
-4bbe,2012-11-21,2012-09-21
-8bb4,2022-11-09,2022-10-12
-6bb3,2018-10-24,2017-10-16
-4bb5,2012-11-28,2012-09-20
-6bbr,2018-02-28,2017-10-19
-4bbh,2012-12-05,2012-09-23
-8bbo,2023-03-22,2022-10-14
-4bbr,2012-11-14,2012-09-27
-4bbx,2013-10-16,2012-09-28
-3bbd,2008-02-05,2007-11-09
-3bb1,2008-04-01,2007-11-09
-2bba,2006-07-18,2005-10-17
-3bbt,2008-02-12,2007-11-11
-8bbd,2023-10-25,2022-10-12
-8bb3,2022-11-09,2022-10-12
-2bbm,1994-01-31,1992-07-16
-3bbf,2008-09-23,2007-11-09
-8bby,2023-07-12,2022-10-14
-6bbo,2018-01-10,2017-10-19
-2bbc,2006-04-04,2005-10-17
-8bbb,2023-10-25,2022-10-12
-6bbp,2018-01-10,2017-10-19
-8bbu,2023-02-08,2022-10-14
-8bba,2023-10-25,2022-10-12
-4bbu,2012-11-14,2012-09-27
-7bb8,2022-07-13,2020-12-17
-2bbq,1994-01-31,1992-09-16
-7bbc,2021-03-24,2020-12-17
-6bb4,2018-05-02,2017-10-16
-7bbv,2022-07-13,2020-12-18
-4bb9,2013-05-15,2012-09-21
-8bbk,2023-08-30,2022-10-13
-2bb6,2006-04-04,2005-10-17
-1bb7,1999-05-04,1998-04-29
-2bbw,2005-12-06,2005-10-17
-1bbo,1993-10-31,1992-05-01
-1bbu,2000-11-10,1998-04-24
-8bbi,2023-10-25,2022-10-13
-6bb1,2018-10-24,2017-10-16
-6bbn,2018-05-23,2017-10-19
-6bb7,2018-10-17,2017-10-17
-8bbc,2023-10-25,2022-10-12
-6bbm,2019-03-06,2017-10-18
-7bb0,2022-01-12,2020-12-16
-3bbr,2007-12-04,2007-11-11
-8bb9,2023-10-25,2022-10-12
-6bbx,2018-07-04,2017-10-19
-6bbw,2018-10-24,2017-10-19
-6bb2,2018-10-24,2017-10-16
-7bbh,2020-12-30,2020-12-17
-8bbq,2023-09-20,2022-10-14
-1bbz,1998-11-25,1998-04-28
-6bbq,2018-01-10,2017-10-19
-4bb2,2012-12-26,2012-09-19
-4bbs,2012-11-14,2012-09-27
-2bb3,2005-11-29,2005-10-17
-8bb2,2022-11-09,2022-10-12
-2bb4,2006-05-30,2005-10-17
-8bbr,2023-09-20,2022-10-14
-8bb0,2023-10-25,2022-10-12
-2bb5,2006-04-04,2005-10-17
-8bbx,2023-12-20,2022-10-14
-2bbf,2007-04-24,2005-10-17
-4bb4,2013-02-27,2012-09-19
-4bbf,2012-11-21,2012-09-21
-6z6p,2021-02-17,2020-05-28
-6z6s,2020-07-22,2020-05-29
-1z6y,2005-04-05,2005-03-23
-1z6x,2005-04-12,2005-03-23
-5z6t,2018-12-05,2018-01-25
-5z65,2019-01-02,2018-01-22
-7z6u,2023-02-01,2022-03-14
-2z6s,2007-11-06,2007-08-08
-5z62,2019-02-27,2018-01-22
-7z68,2023-09-20,2022-03-11
-7z63,2023-01-18,2022-03-10
-2z66,2007-09-18,2007-07-22
-7z6z,2022-06-22,2022-03-14
-2z6d,2008-07-29,2007-07-29
-4z67,2016-04-13,2015-04-03
-2z6n,2007-08-28,2007-08-04
-5z66,2019-01-23,2018-01-22
-6z6r,2021-03-17,2020-05-29
-1z6d,2005-08-16,2005-03-22
-1z69,2005-06-21,2005-03-22
-4z69,2016-01-27,2015-04-04
-5z6f,2018-09-19,2018-01-22
-1z6h,2006-03-22,2005-03-22
-7z6a,2022-10-26,2022-03-11
-1z6o,2005-05-24,2005-03-22
-2z63,2007-09-18,2007-07-22
-4z6l,2015-08-26,2015-04-06
-1z62,2006-03-07,2005-03-21
-4z62,2016-03-02,2015-04-03
-2z6o,2007-09-25,2007-08-06
-5z6o,2018-02-28,2018-01-24
-5z6m,2018-09-19,2018-01-23
-6z6n,2020-07-29,2020-05-28
-7z6v,2022-07-13,2022-03-14
-4z6s,2015-08-26,2015-04-06
-4z6n,2015-08-26,2015-04-06
-7z6k,2022-10-26,2022-03-11
-7z6e,2023-02-22,2022-03-11
-4z63,2016-03-02,2015-04-03
-7z6t,2023-03-22,2022-03-14
-2z6f,2008-07-29,2007-07-31
-4z6m,2015-08-26,2015-04-06
-1z67,2005-05-03,2005-03-21
-4z6f,2016-04-13,2015-04-04
-2z62,2007-09-18,2007-07-22
-1z6j,2005-05-03,2005-03-22
-1z6i,2005-07-19,2005-03-22
-6z6m,2020-07-29,2020-05-28
-1z6z,2005-04-05,2005-03-23
-7z6r,2022-03-23,2022-03-14
-2z6j,2008-04-01,2007-08-01
-2z6i,2008-04-01,2007-08-01
-5z6k,2018-09-19,2018-01-23
-5z6j,2018-09-19,2018-01-23
-1z6q,2005-04-12,2005-03-23
-6z65,2021-05-26,2020-05-27
-1z6c,2005-06-21,2005-03-22
-6z6q,2021-03-17,2020-05-29
-4z6c,2016-04-13,2015-04-04
-6z6c,2021-04-07,2020-05-28
-7z6q,2023-02-08,2022-03-14
-5z6b,2019-01-23,2018-01-22
-2z65,2007-09-18,2007-07-22
-7z6l,2022-09-07,2022-03-12
-1z6u,2005-05-03,2005-03-23
-6z68,2020-12-30,2020-05-28
-6z6l,2020-07-29,2020-05-28
-4z61,2016-03-02,2015-04-03
-4z6o,2015-08-26,2015-04-06
-6z6v,2020-06-10,2020-05-29
-6z61,2021-05-26,2020-05-27
-2z6t,2007-11-06,2007-08-08
-4z6x,2016-04-20,2015-04-06
-6z63,2020-09-02,2020-05-27
-7z61,2022-07-13,2022-03-10
-4z6a,2015-12-30,2015-04-04
-6z67,2020-09-02,2020-05-28
-7z6b,2022-11-23,2022-03-11
-6z6g,2020-07-29,2020-05-28
-7z6g,2023-03-22,2022-03-11
-1z6p,2005-04-12,2005-03-23
-4z64,2016-03-02,2015-04-03
-7z67,2022-03-23,2022-03-11
-7z60,2022-05-18,2022-03-10
-4z6h,2015-05-20,2015-04-05
-6z6j,2020-07-29,2020-05-28
-5z6e,2019-01-23,2018-01-22
-1z68,2005-04-12,2005-03-21
-4z6v,2015-08-26,2015-04-06
-6z6h,2021-02-17,2020-05-28
-2z6r,2007-08-28,2007-08-08
-6z6k,2020-07-29,2020-05-28
-4z6d,2016-04-13,2015-04-04
-4z6k,2016-04-13,2015-04-05
-4z6r,2015-08-26,2015-04-06
-4z6e,2016-04-13,2015-04-04
-5z6l,2018-09-19,2018-01-23
-1z6s,2005-08-16,2005-03-23
-1z6l,2005-09-27,2005-03-22
-6z69,2020-12-30,2020-05-28
-7z6d,2023-03-22,2022-03-11
-7z62,2023-01-18,2022-03-10
-1z6f,2005-06-21,2005-03-22
-7z6i,2023-06-14,2022-03-11
-4z6z,2015-08-26,2015-04-06
-2z6q,2007-08-28,2007-08-08
-2z6m,2008-07-22,2007-08-04
-4z6q,2015-08-26,2015-04-06
-6z6i,2020-12-02,2020-05-28
-1z6r,2005-06-14,2005-03-23
-2z68,2007-08-28,2007-07-24
-2z64,2007-09-18,2007-07-22
-4z6p,2015-08-26,2015-04-06
-4z65,2015-10-14,2015-04-03
-5z68,2018-04-18,2018-01-22
-7z6h,2022-05-04,2022-03-11
-2z6b,2008-04-15,2007-07-28
-6z64,2021-05-26,2020-05-27
-2z60,2007-09-18,2007-07-21
-1z6t,2005-04-19,2005-03-23
-6z6a,2020-12-30,2020-05-28
-4z6t,2015-08-26,2015-04-06
-6z6z,2021-06-09,2020-05-29
-2z6u,2007-11-20,2007-08-09
-6z6y,2020-12-30,2020-05-29
-7z6c,2022-10-12,2022-03-11
-7z6s,2022-05-11,2022-03-14
-1z6n,2005-05-03,2005-03-22
-7z6f,2023-09-20,2022-03-11
-5z69,2018-10-17,2018-01-22
-6z6f,2021-02-17,2020-05-28
-7z6j,2023-03-22,2022-03-11
-2z6w,2008-04-29,2007-08-09
-5z6r,2019-01-30,2018-01-25
-6z6o,2021-02-17,2020-05-28
-5z6s,2018-10-17,2018-01-25
-6z6u,2020-06-24,2020-05-29
-2z67,2008-04-29,2007-07-23
-1z60,2005-04-12,2005-03-21
-1z6a,2005-05-03,2005-03-22
-4z6w,2015-08-26,2015-04-06
-6z6b,2020-07-29,2020-05-28
-4z6u,2015-08-26,2015-04-06
-1z6k,2005-05-03,2005-03-22
-7z64,2024-01-17,2022-03-10
-2z6a,2007-08-21,2007-07-25
-4z60,2016-04-13,2015-04-03
-1z6e,2006-03-28,2005-03-22
-2z6c,2008-07-29,2007-07-29
-7z6m,2022-08-10,2022-03-13
-5z6w,2018-03-14,2018-01-25
-4z6i,2015-05-20,2015-04-05
-5npu,2018-03-07,2017-04-19
-2np8,2006-12-26,2006-10-26
-2np5,2006-11-28,2006-10-26
-5np4,2017-09-27,2017-04-13
-5nps,2018-05-16,2017-04-18
-6npe,2019-03-13,2019-01-17
-1npe,2003-08-12,2003-01-17
-1npz,2003-04-15,2003-01-20
-4npl,2014-02-19,2013-11-21
-6np8,2019-04-10,2019-01-17
-3npy,2010-11-17,2010-06-29
-2np9,2007-05-22,2006-10-26
-3nps,2011-07-06,2010-06-29
-7npx,2021-05-19,2021-02-28
-5np7,2017-05-03,2017-04-13
-2np7,2007-11-13,2006-10-26
-7npc,2021-06-02,2021-02-26
-1nps,2000-02-04,1999-02-01
-1npm,1999-03-23,1998-01-07
-5npb,2017-08-09,2017-04-16
-1npo,1997-02-12,1996-02-01
-6npb,2019-03-06,2019-01-17
-6npi,2019-03-20,2019-01-17
-5npe,2017-08-09,2017-04-16
-5npr,2018-05-16,2017-04-18
-7npy,2021-07-21,2021-02-28
-5npq,2018-05-30,2017-04-18
-6npl,2019-07-31,2019-01-17
-6np1,2019-09-25,2019-01-17
-6npu,2019-03-13,2019-01-18
-4npt,2014-10-08,2013-11-22
-4npp,2013-12-25,2013-11-22
-7np5,2021-06-02,2021-02-26
-1np4,1998-08-05,1998-07-29
-3np0,2010-12-22,2010-06-27
-5npp,2017-07-12,2017-04-18
-3np1,1998-05-27,1998-01-22
-6npx,2019-04-10,2019-01-18
-1npj,2003-04-29,2003-01-18
-1npt,2003-04-22,2003-01-20
-6npz,2019-01-30,2019-01-18
-7npz,2021-07-21,2021-02-28
-5npl,2018-05-30,2017-04-17
-7np1,2021-11-17,2021-02-26
-2npv,2006-11-28,2006-10-30
-6npd,2019-03-06,2019-01-17
-7npm,2022-03-23,2021-02-27
-6np2,2019-09-25,2019-01-17
-1nph,2003-05-13,2003-01-17
-4npv,2014-07-16,2013-11-22
-1np1,1998-05-27,1998-01-19
-4np1,1998-11-11,1998-06-26
-4np5,2013-12-04,2013-11-20
-2npf,2006-11-14,2006-10-27
-4np9,2013-12-25,2013-11-21
-3np3,2010-10-13,2010-06-27
-5np8,2018-05-16,2017-04-13
-4npm,2014-02-19,2013-11-21
-5npc,2017-08-09,2017-04-16
-4np3,2014-04-16,2013-11-20
-1np8,2003-11-18,2003-01-17
-3np4,2010-10-13,2010-06-27
-7npf,2021-10-06,2021-02-26
-3npe,2010-11-10,2010-06-28
-1np0,2003-04-29,2003-01-16
-4np8,2013-12-18,2013-11-20
-6np3,2019-09-25,2019-01-17
-6npf,2019-11-27,2019-01-17
-1npn,2003-04-29,2003-01-18
-3npl,2010-08-25,2010-06-28
-5npz,2018-05-02,2017-04-19
-3np7,2011-06-08,2010-06-28
-7npb,2022-01-12,2021-02-26
-5np9,2018-05-30,2017-04-13
-1npd,2003-01-28,2003-01-17
-5npi,2017-05-24,2017-04-16
-6npm,2019-03-20,2019-01-17
-4npw,2014-07-16,2013-11-22
-2npi,2006-12-19,2006-10-27
-4npb,2013-12-25,2013-11-21
-7npa,2022-03-23,2021-02-26
-1npg,2003-11-11,2003-01-17
-7npi,2021-09-15,2021-02-26
-7np0,2021-06-30,2021-02-26
-5npo,2017-12-20,2017-04-18
-3npa,2011-06-08,2010-06-28
-5npk,2017-07-12,2017-04-17
-1npf,2003-11-11,2003-01-17
-2np0,2006-12-26,2006-10-26
-5npf,2017-08-09,2017-04-16
-1npa,2004-01-27,2003-01-17
-1npq,2003-04-29,2003-01-18
-1npw,2003-02-04,2003-01-20
-3npc,2010-08-11,2010-06-28
-6npa,2019-03-06,2019-01-17
-6nph,2019-07-31,2019-01-17
-1npc,1993-10-31,1992-01-08
-4npj,2014-01-29,2013-11-21
-7npk,2021-04-07,2021-02-27
-1npl,1998-12-23,1998-12-17
-7npl,2021-04-07,2021-02-27
-7npj,2021-06-30,2021-02-27
-4npi,2014-12-24,2013-11-21
-3np8,2011-06-29,2010-06-28
-7npp,2022-03-23,2021-02-28
-7nph,2021-06-30,2021-02-26
-6np4,2019-09-25,2019-01-17
-2npx,1994-01-31,1992-05-29
-6np5,2019-09-25,2019-01-17
-4np2,2014-04-16,2013-11-20
-2npm,2006-11-07,2006-10-27
-2nph,2006-12-19,2006-10-27
-6npt,2019-05-22,2019-01-18
-7np4,2021-08-11,2021-02-26
-7npg,2022-01-12,2021-02-26
-2np1,1998-05-27,1998-01-19
-6np0,2019-07-24,2019-01-17
-4npe,2014-10-08,2013-11-21
-1npv,2003-02-04,2003-01-20
-2np6,2007-11-13,2006-10-26
-6npc,2019-03-06,2019-01-17
-4np7,2014-09-24,2013-11-20
-6npp,2019-03-20,2019-01-18
-5nph,2017-05-24,2017-04-16
-1npx,1994-01-31,1991-08-02
-3np2,2010-12-22,2010-06-27
-2npp,2006-12-12,2006-10-28
-7npe,2021-07-21,2021-02-26
-3npr,2010-12-22,2010-06-28
-3np5,2010-12-29,2010-06-27
-6npw,2019-04-24,2019-01-18
-4npd,2014-10-08,2013-11-21
-6npo,2019-02-06,2019-01-18
-4npk,2014-01-29,2013-11-21
-5npd,2017-08-09,2017-04-16
-2npn,2006-11-28,2006-10-27
-6npv,2019-03-13,2019-01-18
-1np7,2003-01-28,2003-01-17
-6npn,2019-02-20,2019-01-18
-2npa,2007-10-30,2006-10-26
-7np2,2022-01-12,2021-02-26
-5npj,2017-05-24,2017-04-16
-6npy,2019-06-19,2019-01-18
-3np9,2011-06-08,2010-06-28
-7np6,2021-06-02,2021-02-26
-7np8,2022-03-23,2021-02-26
-5u73,2017-09-27,2016-12-11
-7u75,2022-05-04,2022-03-07
-1u71,2005-02-01,2004-08-02
-3u78,2012-01-25,2011-10-13
-4u71,2015-03-25,2014-07-30
-6u78,2020-05-06,2019-08-31
-5u7j,2017-06-28,2016-12-12
-4u7h,2015-02-11,2014-07-30
-6u7u,2020-04-22,2019-09-03
-6u7x,2020-04-22,2019-09-03
-5u7i,2017-06-28,2016-12-12
-6u7c,2020-04-15,2019-09-02
-5u7m,2017-08-30,2016-12-12
-7u7w,2022-05-04,2022-03-07
-7u7o,2023-03-29,2022-03-07
-4u72,2015-09-02,2014-07-30
-6u7f,2019-11-13,2019-09-02
-3u7l,2012-06-27,2011-10-14
-4u7g,2015-02-11,2014-07-30
-7u7y,2022-05-04,2022-03-07
-1u7s,2005-07-19,2004-08-04
-8u7q,2024-01-31,2023-09-15
-6u7h,2019-11-13,2019-09-02
-1u72,2005-02-01,2004-08-02
-6u7a,2020-05-06,2019-09-01
-6u7t,2019-10-02,2019-09-03
-3u75,2012-04-25,2011-10-13
-6u7l,2019-11-06,2019-09-03
-8u7m,2024-01-31,2023-09-15
-7u74,2022-05-04,2022-03-07
-3u7h,2011-12-14,2011-10-13
-6u7o,2019-10-09,2019-09-03
-7u7t,2022-05-04,2022-03-07
-5u7g,2017-06-21,2016-12-12
-3u7j,2011-11-16,2011-10-13
-3u7r,2012-10-24,2011-10-14
-1u7x,2005-05-24,2004-08-04
-7u73,2022-05-04,2022-03-07
-3u7k,2012-06-27,2011-10-14
-5u7w,2017-05-31,2016-12-12
-1u75,2004-09-28,2004-08-02
-1u74,2004-09-28,2004-08-02
-1u7j,2005-03-01,2004-08-04
-6u7k,2019-09-18,2019-09-03
-7u7m,2022-08-31,2022-03-07
-5u7d,2017-06-28,2016-12-12
-3u7f,2011-12-14,2011-10-13
-5u7r,2017-03-29,2016-12-12
-5u7c,2017-01-11,2016-12-12
-5u7k,2017-06-28,2016-12-12
-8u7y,2024-04-24,2023-09-15
-8u7w,2024-01-03,2023-09-15
-3u73,2012-04-18,2011-10-13
-5u7l,2017-06-28,2016-12-12
-7u7c,2022-05-04,2022-03-07
-5u7a,2017-01-11,2016-12-12
-5u7x,2017-05-31,2016-12-12
-4u74,2015-09-02,2014-07-30
-6u74,2020-08-19,2019-08-31
-4u73,2015-03-25,2014-07-30
-8u7e,2024-02-07,2023-09-15
-6u7p,2019-10-09,2019-09-03
-3u7c,2013-02-13,2011-10-13
-5u77,2017-10-18,2016-12-11
-3u7n,2012-06-27,2011-10-14
-6u72,2020-08-19,2019-08-31
-5u7v,2017-05-31,2016-12-12
-6u71,2020-08-19,2019-08-31
-4u7t,2014-11-12,2014-07-31
-7u7i,2022-05-04,2022-03-07
-3u7y,2011-11-16,2011-10-14
-8u7h,2024-01-31,2023-09-15
-4u75,2015-03-25,2014-07-30
-4u7q,2015-03-25,2014-07-31
-7u79,2022-05-04,2022-03-07
-5u7n,2017-11-22,2016-12-12
-6u75,2020-10-28,2019-08-31
-1u7p,2004-10-19,2004-08-04
-7u7j,2022-05-04,2022-03-07
-7u7k,2022-05-04,2022-03-07
-5u74,2017-10-11,2016-12-11
-4u7w,2015-08-12,2014-07-31
-7u7v,2022-05-04,2022-03-07
-6u7n,2020-08-12,2019-09-03
-8u7x,2024-01-03,2023-09-15
-3u7b,2012-07-18,2011-10-13
-7u7u,2022-05-04,2022-03-07
-5u7h,2017-06-21,2016-12-12
-7u7r,2022-05-04,2022-03-07
-1u7w,2004-11-30,2004-08-04
-7u7s,2022-05-04,2022-03-07
-5u7s,2016-12-28,2016-12-12
-5u75,2017-08-02,2016-12-11
-7u7h,2023-01-18,2022-03-07
-7u70,2023-03-22,2022-03-07
-5u7o,2017-08-30,2016-12-12
-3u7g,2011-12-14,2011-10-13
-3u7e,2011-12-14,2011-10-13
-5u72,2017-02-08,2016-12-10
-4u76,2015-03-25,2014-07-30
-6u7w,2020-04-22,2019-09-03
-5u7z,2018-03-28,2016-12-13
-7u7l,2022-05-04,2022-03-07
-6u7g,2019-11-13,2019-09-02
-5u7b,2017-01-11,2016-12-12
-1u7z,2004-11-30,2004-08-04
-3u72,2011-11-02,2011-10-13
-1u7t,2004-10-05,2004-08-04
-6u77,2020-03-18,2019-08-31
-1u7r,2005-07-19,2004-08-04
-5u7f,2017-06-21,2016-12-12
-1u7h,2004-11-09,2004-08-03
-4u7c,2016-01-27,2014-07-30
-4u7d,2015-01-21,2014-07-30
-4u7f,2015-02-11,2014-07-30
-8u7v,2024-01-31,2023-09-15
-4u7l,2015-04-08,2014-07-31
-3u7u,2012-08-29,2011-10-14
-8u7l,2024-01-31,2023-09-15
-4u7p,2014-11-12,2014-07-31
-4u7z,2014-09-24,2014-07-31
-7u76,2022-05-04,2022-03-07
-7u7e,2022-05-04,2022-03-07
-6u7j,2019-10-30,2019-09-03
-5u79,2017-01-11,2016-12-12
-7u77,2022-05-04,2022-03-07
-7u7b,2022-05-04,2022-03-07
-7u7a,2022-05-04,2022-03-07
-8u78,2024-03-06,2023-09-14
-7u7g,2022-05-04,2022-03-07
-7u7f,2022-05-04,2022-03-07
-7u7z,2022-05-04,2022-03-07
-3u7w,2011-11-16,2011-10-14
-7u78,2022-05-04,2022-03-07
-4u7o,2015-09-02,2014-07-31
-3u7m,2012-06-27,2011-10-14
-7u71,2023-03-15,2022-03-07
-6u7e,2019-11-13,2019-09-02
-3u7s,2012-01-18,2011-10-14
-3u7d,2012-09-12,2011-10-13
-3u79,2012-07-04,2011-10-13
-4u7m,2015-04-08,2014-07-31
-7u72,2022-05-04,2022-03-07
-1u7m,2005-03-01,2004-08-04
-3u7z,2011-11-02,2011-10-14
-4u7v,2015-03-25,2014-07-31
-6u7b,2019-12-25,2019-09-02
-4u7k,2015-03-11,2014-07-31
-4u70,2015-03-25,2014-07-30
-7u7x,2022-05-04,2022-03-07
-4u7x,2014-09-03,2014-07-31
-4u79,2014-10-08,2014-07-30
-3u74,2012-04-18,2011-10-13
-7u7d,2022-05-04,2022-03-07
-3u70,2011-12-07,2011-10-13
-1u70,2005-02-01,2004-08-02
-7u7n,2022-05-25,2022-03-07
-621p,1994-01-31,1991-06-06
-521p,1994-01-31,1991-06-06
-121p,1994-01-31,1991-06-06
-421p,1994-01-31,1991-06-06
-721p,1994-01-31,1991-06-06
-821p,1994-01-31,1993-03-29
-221p,1994-01-31,1991-06-06
-256b,1991-01-15,1990-01-16
-456c,1999-08-06,1998-08-06
-7m0m,2021-04-07,2021-03-11
-6m0k,2020-04-29,2020-02-22
-7m02,2021-03-24,2021-03-10
-4m0n,2013-10-16,2013-08-01
-3m0o,2010-04-21,2010-03-03
-3m08,2010-07-14,2010-03-02
-4m0c,2013-08-14,2013-08-01
-5m0n,2017-01-11,2016-10-05
-7m0w,2021-04-21,2021-03-11
-5m02,2017-12-20,2016-10-03
-1m0o,2002-10-23,2002-06-13
-4m00,2014-06-18,2013-08-01
-7m0t,2021-04-21,2021-03-11
-7m00,2021-03-24,2021-03-10
-6m0j,2020-03-18,2020-02-21
-4m03,2014-06-18,2013-08-01
-1m00,2002-11-27,2002-06-11
-5m0z,2016-12-07,2016-10-06
-1m0m,2002-09-11,2002-06-13
-6m01,2020-07-08,2020-02-19
-6m0t,2021-04-21,2020-02-22
-1m0k,2002-09-11,2002-06-13
-5m0o,2017-01-11,2016-10-05
-5m0m,2017-08-16,2016-10-05
-1m0n,2002-10-23,2002-06-13
-7m0b,2022-03-16,2021-03-10
-1m0v,2002-07-24,2002-06-14
-4m0e,2013-10-16,2013-08-01
-1m0u,2003-02-11,2002-06-14
-2m0v,2013-04-24,2012-11-06
-1m01,2003-01-21,2002-06-11
-7m0v,2021-04-21,2021-03-11
-6m08,2020-12-30,2020-02-20
-5m0d,2017-08-16,2016-10-04
-6m0v,2020-09-09,2020-02-22
-3m02,2010-07-07,2010-03-02
-1m0j,2003-05-06,2002-06-13
-3m0a,2010-04-28,2010-03-02
-5m0c,2018-06-06,2016-10-04
-7m0z,2021-04-21,2021-03-11
-5m0s,2017-08-16,2016-10-05
-6m0f,2021-02-17,2020-02-21
-1m08,2002-12-11,2002-06-12
-3m0k,2010-06-16,2010-03-03
-1m0q,2002-10-23,2002-06-13
-3m0f,2010-03-16,2010-03-03
-7m0n,2022-03-02,2021-03-11
-6m0a,2020-12-16,2020-02-20
-7m0y,2021-04-21,2021-03-11
-4m0v,2014-02-26,2013-08-02
-5m04,2017-03-01,2016-10-03
-5m09,2017-01-11,2016-10-03
-3m01,2010-07-07,2010-03-02
-4m0j,2013-10-02,2013-08-01
-3m04,2011-05-25,2010-03-02
-3m0v,2010-11-10,2010-03-03
-6m0z,2021-02-17,2020-02-24
-4m05,2014-01-15,2013-08-01
-7m0u,2021-04-21,2021-03-11
-1m07,2003-01-21,2002-06-12
-7m03,2021-03-24,2021-03-10
-4m01,2014-06-18,2013-08-01
-7m0o,2021-04-14,2021-03-11
-1m03,2002-12-11,2002-06-11
-5m0l,2018-06-06,2016-10-05
-3m07,2010-03-16,2010-03-02
-3m0w,2010-05-12,2010-03-03
-3m0c,2011-03-16,2010-03-02
-3m0h,2010-11-10,2010-03-03
-7m0i,2021-06-30,2021-03-11
-5m0b,2018-06-06,2016-10-04
-7m05,2021-03-17,2021-03-10
-2m0u,2013-04-24,2012-11-06
-1m0g,2003-05-06,2002-06-13
-1m04,2002-12-11,2002-06-11
-6m0q,2021-03-10,2020-02-22
-7m01,2021-03-24,2021-03-10
-5m00,2017-12-20,2016-10-03
-5m01,2017-10-25,2016-10-03
-7m0f,2022-08-31,2021-03-10
-4m07,2014-01-15,2013-08-01
-7m0k,2021-04-07,2021-03-11
-7m0e,2022-03-16,2021-03-10
-5m07,2017-01-11,2016-10-03
-1m0l,2002-09-11,2002-06-13
-5m06,2017-01-11,2016-10-03
-7m0h,2022-08-31,2021-03-10
-4m0z,2014-04-02,2013-08-02
-7m09,2022-03-16,2021-03-10
-3m0e,2010-11-03,2010-03-02
-2m0k,2013-10-30,2012-10-29
-1m0p,2002-10-23,2002-06-13
-4m0x,2014-07-09,2013-08-02
-1m0w,2002-12-11,2002-06-14
-1m0d,2002-07-10,2002-06-12
-6m06,2020-12-30,2020-02-20
-7m0x,2021-04-21,2021-03-11
-3m09,2010-07-14,2010-03-02
-5m0j,2017-01-18,2016-10-05
-7m08,2022-03-16,2021-03-10
-2m0e,2012-11-14,2012-10-24
-4m06,2014-01-15,2013-08-01
-6m00,2021-02-24,2020-02-19
-5m0y,2017-09-06,2016-10-06
-6m07,2020-12-30,2020-02-20
-3m0b,2010-04-14,2010-03-02
-2m0d,2012-11-14,2012-10-24
-4m0a,2014-02-05,2013-08-01
-7m0r,2021-05-05,2021-03-11
-4m0y,2014-04-02,2013-08-02
-4m0f,2013-10-16,2013-08-01
-5m0e,2017-08-16,2016-10-04
-3m00,2010-07-07,2010-03-02
-6m0w,2020-09-09,2020-02-23
-4m08,2014-01-15,2013-08-01
-5m0t,2016-12-07,2016-10-05
-6m0r,2020-11-04,2020-02-22
-3m0j,2010-06-16,2010-03-03
-6m0x,2020-09-09,2020-02-23
-4m02,2014-06-18,2013-08-01
-5m0i,2017-01-18,2016-10-05
-4m04,2014-02-05,2013-08-01
-7m0l,2021-04-07,2021-03-11
-3m0n,2010-04-07,2010-03-03
-5m05,2016-11-16,2016-10-03
-1m0e,2002-09-18,2002-06-12
-7m07,2022-03-16,2021-03-10
-3m0d,2010-04-28,2010-03-02
-3m0i,2011-03-09,2010-03-03
-6m0p,2021-03-10,2020-02-22
-7m0c,2022-03-16,2021-03-10
-3m0x,2010-11-10,2010-03-03
-7m0a,2022-03-16,2021-03-10
-2m0p,2013-01-09,2012-11-01
-4m0k,2013-08-14,2013-08-01
-4m09,2014-01-15,2013-08-01
-2m0f,2012-11-14,2012-10-24
-6m0e,2020-08-12,2020-02-21
-7m04,2021-03-24,2021-03-10
-5m03,2017-01-11,2016-10-03
-5m0x,2016-11-09,2016-10-06
-4m0l,2013-08-28,2013-08-01
-6m0u,2021-02-24,2020-02-22
-4m0r,2014-05-21,2013-08-02
-3m0m,2010-11-10,2010-03-03
-7m06,2022-03-16,2021-03-10
-2m0j,2013-10-30,2012-10-29
-1m0b,2004-01-13,2002-06-12
-5m0p,2017-01-11,2016-10-05
-6m0d,2020-08-12,2020-02-21
-3m0l,2010-11-10,2010-03-03
-7m0d,2022-03-16,2021-03-10
-1m05,2003-09-02,2002-06-11
-4m0w,2014-02-12,2013-08-02
-2m0z,2013-07-03,2012-11-09
-3m0y,2010-11-10,2010-03-03
-193l,1995-12-07,1995-09-01
-193d,1995-02-27,1994-09-30
-6soy,2019-11-06,2019-08-30
-5soj,2022-07-13,2022-06-09
-6sod,2019-10-02,2019-08-29
-5soy,2022-07-13,2022-06-09
-8sog,2023-08-09,2023-04-28
-7sop,2022-08-03,2021-11-01
-3sop,2012-11-28,2011-06-30
-6son,2020-01-29,2019-08-29
-8soq,2023-12-27,2023-04-29
-8so1,2023-08-02,2023-04-28
-8so2,2023-08-02,2023-04-28
-6sou,2019-10-02,2019-08-29
-6so2,2019-10-02,2019-08-28
-1soo,1997-09-04,1996-05-07
-5so2,2023-12-20,2022-05-30
-5sop,2022-07-13,2022-06-09
-1so5,2004-06-08,2004-03-12
-1so0,2004-03-30,2004-03-12
-7sog,2022-04-20,2021-10-30
-1soj,2004-05-11,2004-03-15
-5soq,2022-07-13,2022-06-09
-3sob,2011-09-21,2011-06-30
-7sou,2022-08-03,2021-11-01
-5soo,2022-07-13,2022-06-09
-8son,2024-05-22,2023-04-28
-3soq,2011-09-21,2011-06-30
-3so3,2012-06-20,2011-06-29
-3soc,2011-07-20,2011-06-30
-5sob,2023-12-20,2022-05-30
-5sow,2022-07-13,2022-06-09
-5soz,2022-07-13,2022-06-09
-3sox,2011-08-03,2011-06-30
-5so6,2023-12-20,2022-05-30
-1son,1997-09-04,1996-05-07
-5soc,2023-12-20,2022-05-30
-8soa,2024-04-03,2023-04-28
-5sod,2023-12-20,2022-05-30
-5so5,2023-12-20,2022-05-30
-7soq,2022-08-03,2021-11-01
-7sod,2021-11-17,2021-10-29
-7soo,2022-08-03,2021-11-01
-5sos,2022-07-13,2022-06-09
-1sos,1993-04-15,1992-02-11
-8sou,2023-08-09,2023-04-30
-7soz,2021-11-10,2021-11-01
-8soc,2024-04-03,2023-04-28
-5sog,2023-12-20,2022-05-30
-1so3,2004-06-08,2004-03-12
-1soi,2004-05-11,2004-03-15
-3sos,2012-04-11,2011-06-30
-5soa,2023-12-20,2022-05-30
-8sod,2024-04-03,2023-04-28
-5son,2022-07-13,2022-06-09
-7so9,2021-11-17,2021-10-29
-5so0,2023-12-20,2022-05-30
-8soe,2024-04-03,2023-04-28
-7soi,2022-11-09,2021-10-31
-8so0,2023-10-25,2023-04-28
-6sox,2020-09-09,2019-08-30
-8sor,2023-06-21,2023-04-29
-6soz,2019-11-06,2019-08-30
-3sor,2012-04-11,2011-06-30
-1so8,2004-05-11,2004-03-13
-5sol,2022-07-13,2022-06-09
-5so4,2023-12-20,2022-05-30
-7sof,2021-11-17,2021-10-29
-7so3,2022-03-16,2021-10-29
-1sog,2004-07-13,2004-03-14
-6soo,2020-01-29,2019-08-29
-5sot,2022-07-13,2022-06-09
-3so0,2011-11-16,2011-06-29
-7so4,2022-03-16,2021-10-29
-5so1,2023-12-20,2022-05-30
-7so8,2022-11-02,2021-10-29
-7sov,2022-08-03,2021-11-01
-6so1,2019-10-02,2019-08-28
-1sof,2005-04-05,2004-03-14
-7soe,2021-11-17,2021-10-29
-3son,2011-08-17,2011-06-30
-5so3,2023-12-20,2022-05-30
-6sok,2020-09-09,2019-08-29
-1so4,2004-06-08,2004-03-12
-1so6,2004-06-08,2004-03-12
-8soj,2023-06-07,2023-04-28
-7soj,2022-11-02,2021-10-31
-5sor,2022-07-13,2022-06-09
-3so7,2011-12-07,2011-06-30
-8sok,2023-06-07,2023-04-28
-7sow,2022-11-09,2021-11-01
-7sot,2022-08-03,2021-11-01
-7sos,2022-08-03,2021-11-01
-1sox,1998-04-29,1997-12-31
-7soa,2021-11-17,2021-10-29
-5som,2022-07-13,2022-06-09
-5so7,2023-12-20,2022-05-30
-6so4,2019-09-11,2019-08-29
-7soc,2021-11-17,2021-10-29
-5sox,2022-07-13,2022-06-09
-7so1,2022-03-16,2021-10-28
-5so9,2023-12-20,2022-05-30
-8so3,2023-09-06,2023-04-28
-6sov,2019-10-02,2019-08-30
-7sob,2021-11-17,2021-10-29
-3sou,2011-08-03,2011-06-30
-5sof,2023-12-20,2022-05-30
-1sow,2005-03-15,2004-03-15
-6soq,2020-01-29,2019-08-29
-7so2,2022-03-16,2021-10-29
-7sol,2022-11-02,2021-10-31
-1soz,2004-06-08,2004-03-16
-5soi,2022-07-13,2022-06-09
-6sot,2019-10-02,2019-08-29
-3sow,2011-08-03,2011-06-30
-5sok,2022-07-13,2022-06-09
-1so2,2004-05-11,2004-03-12
-7som,2022-04-13,2021-11-01
-5sov,2022-07-13,2022-06-09
-1som,1999-06-25,1999-03-17
-7sor,2022-08-03,2021-11-01
-3soa,2011-08-31,2011-06-30
-5soh,2023-12-20,2022-05-30
-3sov,2011-09-21,2011-06-30
-3sod,1993-04-15,1990-06-26
-7so6,2022-03-16,2021-10-29
-3so9,2011-10-12,2011-06-30
-7sok,2022-11-02,2021-10-31
-3som,2011-07-27,2011-06-30
-3sog,2011-07-13,2011-06-30
-6soi,2019-10-02,2019-08-29
-8sos,2023-12-13,2023-04-29
-5soe,2023-12-20,2022-05-30
-8sov,2023-08-09,2023-04-30
-5sou,2022-07-13,2022-06-09
-6sos,2020-09-09,2019-08-29
-5so8,2023-12-20,2022-05-30
-6sor,2020-01-29,2019-08-29
-3so1,2011-11-16,2011-06-29
-6so5,2020-09-09,2019-08-29
-8sob,2024-04-03,2023-04-28
-5cgm,2015-12-09,2015-07-09
-2cgv,2006-04-05,2006-03-09
-6cgc,2019-01-16,2018-02-19
-1cgv,1995-02-27,1994-08-05
-5cgg,2015-11-25,2015-07-09
-4cgp,2014-07-09,2013-11-25
-4cgt,1998-08-12,1998-06-06
-7cgd,2020-09-23,2020-07-01
-8cgy,2024-02-21,2023-02-06
-4cgz,2013-12-11,2013-11-27
-2cgu,2006-04-05,2006-03-09
-2cgx,2006-04-05,2006-03-09
-6cg2,2018-04-18,2018-02-19
-1cgw,1995-02-07,1994-08-05
-7cgr,2020-07-29,2020-07-02
-2cg1,2007-05-01,2006-02-27
-1cgm,1994-04-30,1993-11-17
-9cgt,1998-10-14,1998-09-27
-2cg2,2006-04-26,2006-02-27
-2cgn,2006-12-13,2006-03-09
-7cgk,2021-07-07,2020-07-01
-6cgg,2018-04-11,2018-02-20
-1cgh,1997-07-07,1996-06-26
-6cgs,2018-05-09,2018-02-20
-4cgu,2014-05-14,2013-11-26
-8cg0,2024-02-21,2023-02-03
-5cgv,2016-03-23,2015-07-09
-5cg2,2015-12-09,2015-07-09
-8cgr,2023-07-26,2023-02-06
-8cgo,2023-06-14,2023-02-06
-1cg0,1999-06-17,1999-03-26
-8cg5,2024-02-21,2023-02-03
-1cg8,1999-04-01,1999-03-26
-2cgz,2007-05-01,2006-03-10
-2cgl,2006-05-31,2006-03-09
-8cgs,2023-07-12,2023-02-06
-5cgk,2015-07-22,2015-07-09
-7cgl,2021-07-07,2020-07-01
-6cgy,2018-08-15,2018-02-21
-6cgj,2018-07-18,2018-02-20
-4cg6,2014-02-05,2013-11-21
-7cgz,2021-07-07,2020-07-03
-4cgg,2013-12-04,2013-11-25
-5cgs,2016-02-03,2015-07-09
-3cgt,1998-05-27,1998-01-22
-1cgx,1995-02-07,1994-08-05
-3cg4,2008-03-11,2008-03-04
-6cgu,2018-05-09,2018-02-20
-6cgi,2018-02-28,2018-02-20
-7cgh,2021-07-07,2020-07-01
-8cgb,2023-04-26,2023-02-03
-5cg1,2015-12-09,2015-07-09
-8cgw,2024-01-31,2023-02-06
-8cgd,2023-07-26,2023-02-03
-5cge,2016-03-23,2015-07-09
-1cg6,1999-07-05,1999-03-27
-7cgj,2021-07-07,2020-07-01
-3cg7,2008-12-30,2008-03-05
-7cgw,2021-04-07,2020-07-02
-1cg4,1999-06-17,1999-03-26
-1cgk,1999-09-03,1999-03-25
-6cgf,2018-08-01,2018-02-20
-3cgd,2008-04-22,2008-03-05
-2cg5,2006-03-01,2006-02-27
-5cga,2016-03-23,2015-07-09
-6cgq,2019-02-27,2018-02-20
-8cgi,2023-07-26,2023-02-04
-8cgv,2023-08-02,2023-02-06
-5cgp,2016-04-20,2015-07-09
-1cg1,1999-06-17,1999-03-26
-8cgc,2023-05-24,2023-02-03
-4cgh,2013-12-04,2013-11-25
-7cgs,2021-04-21,2020-07-02
-3cgo,2008-06-03,2008-03-06
-3cgh,2008-03-18,2008-03-05
-1cgo,1995-07-31,1995-05-01
-8cgk,2023-07-19,2023-02-05
-6cgd,2018-04-11,2018-02-20
-2cg4,2006-04-04,2006-02-27
-4cgv,2014-05-14,2013-11-26
-1cg3,1999-06-17,1999-03-26
-7cgv,2020-10-28,2020-07-02
-4cg0,2014-04-09,2013-11-19
-5cgt,1998-08-12,1998-06-06
-6cgp,2018-06-13,2018-02-20
-3cgb,2008-04-22,2008-03-05
-2cgo,2006-12-13,2006-03-09
-8cg2,2024-02-21,2023-02-03
-2cgw,2006-04-05,2006-03-09
-5cg6,2015-10-14,2015-07-09
-2cg3,2006-04-26,2006-02-27
-5cgb,2016-07-20,2015-07-09
-8cgn,2023-09-20,2023-02-06
-8cg8,2023-09-20,2023-02-03
-8cg7,2023-12-13,2023-02-03
-8cge,2023-08-09,2023-02-03
-1cgu,1994-01-31,1992-06-10
-4cg9,2014-01-15,2013-11-21
-4cgi,2013-12-04,2013-11-25
-6cgl,2018-05-09,2018-02-20
-2cg9,2006-04-12,2006-03-01
-1cgp,1994-01-31,1991-08-12
-8cgq,2024-02-21,2023-02-06
-6cgn,2018-05-09,2018-02-20
-5cg9,2015-09-09,2015-07-09
-8cgj,2023-07-26,2023-02-05
-1cg9,2003-11-18,1999-03-25
-4cg8,2014-01-15,2013-11-21
-5cgq,2016-07-13,2015-07-09
-7cgy,2020-11-18,2020-07-03
-7cgi,2021-07-07,2020-07-01
-6cg0,2018-04-25,2018-02-19
-6cge,2019-01-16,2018-02-20
-3cgy,2008-05-13,2008-03-06
-4cgf,2013-12-04,2013-11-23
-3cge,2008-04-22,2008-03-05
-1cgn,1995-07-31,1995-05-01
-8cgp,2024-01-31,2023-02-06
-3cgl,2008-07-01,2008-03-05
-4cgk,2014-05-21,2013-11-25
-2cgy,2007-03-13,2006-03-10
-8cg1,2024-02-21,2023-02-03
-4cgy,2014-02-12,2013-11-27
-5cgx,2016-02-03,2015-07-09
-5cg5,2015-10-14,2015-07-09
-3cg9,2008-04-01,2008-03-05
-3cgm,2009-03-10,2008-03-06
-3cg8,2009-01-06,2008-03-05
-1cg5,1999-04-01,1999-03-26
-4cgo,2014-07-09,2013-11-25
-4cgm,2014-07-09,2013-11-25
-6cg6,2018-05-09,2018-02-19
-3cga,2008-09-30,2008-03-05
-5cgw,2016-02-03,2015-07-09
-4cga,2014-01-15,2013-11-21
-3cgc,2008-04-22,2008-03-05
-7cgg,2021-07-07,2020-07-01
-6cgt,1998-10-14,1998-06-06
-5cg8,2015-09-09,2015-07-09
-8cg9,2024-02-21,2023-02-03
-7cgm,2021-07-07,2020-07-01
-7cgu,2021-07-07,2020-07-02
-2cgr,1994-05-31,1993-11-23
-1cgt,1994-01-31,1992-06-10
-8cgu,2023-07-26,2023-02-06
-4cgd,2013-12-04,2013-11-22
-3cg5,2008-05-27,2008-03-04
-1cg2,1997-12-24,1996-12-20
-2cgp,1998-02-04,1997-01-31
-6cgk,2018-07-18,2018-02-20
-1cgf,1995-03-31,1994-02-03
-5cgf,2015-11-25,2015-07-09
-7cgc,2020-09-23,2020-07-01
-8cga,2024-05-15,2023-02-03
-4cgj,2013-12-04,2013-11-25
-4cgn,2014-07-09,2013-11-25
-5cg0,2015-12-09,2015-07-08
-1cgz,1999-08-18,1999-03-26
-7cgt,1998-08-12,1998-06-06
-5cgi,2015-11-25,2015-07-09
-2cgj,2006-05-31,2006-03-09
-5cgz,2016-02-17,2015-07-09
-3cgf,2008-06-03,2008-03-05
-1cge,1995-03-31,1994-02-03
-6cg7,2018-05-09,2018-02-19
-4cgl,2014-07-09,2013-11-25
-4cgb,2014-12-10,2013-11-21
-6cgz,2018-08-15,2018-02-21
-8cgt,1998-10-14,1998-09-27
-2cgf,2006-11-29,2006-03-02
-5cgd,2015-08-12,2015-07-09
-6cgb,2018-05-09,2018-02-19
-7cgq,2020-07-29,2020-07-02
-7cgn,2020-09-09,2020-07-01
-4cgq,2014-12-17,2013-11-26
-8cg6,2024-02-21,2023-02-03
-7cgf,2021-07-07,2020-07-01
-1cgy,1995-02-07,1994-08-05
-5cgj,2015-10-21,2015-07-09
-5cgc,2015-08-12,2015-07-09
-2cg0,2007-05-01,2006-02-27
-5cgh,2015-12-02,2015-07-09
-4cgw,2014-05-14,2013-11-26
-6cg1,2018-04-18,2018-02-19
-5ndz,2017-05-03,2017-03-09
-4ndf,2013-12-18,2013-10-26
-6ndg,2019-01-23,2018-12-13
-1ndi,2003-01-28,2002-12-09
-4ndu,2014-12-10,2013-10-27
-5ndf,2017-11-01,2017-03-08
-7ndp,2021-04-07,2021-02-02
-1nd0,2003-05-13,2002-12-05
-1nd1,2003-11-04,2002-12-06
-5ndv,2017-12-13,2017-03-09
-1ndo,1999-03-23,1998-01-11
-3nde,2011-12-14,2010-06-07
-3nd1,2011-06-08,2010-06-06
-5ndd,2017-05-03,2017-03-08
-4ndq,2014-08-13,2013-10-27
-6nd5,2019-03-20,2018-12-13
-7ndg,2021-03-31,2021-02-01
-5nd4,2017-10-04,2017-03-07
-7nde,2022-03-02,2021-02-01
-6ndb,2019-01-23,2018-12-13
-1ndc,1994-06-22,1994-04-27
-6nd9,2019-01-23,2018-12-13
-4nd2,2014-12-17,2013-10-25
-6nd6,2019-02-20,2018-12-13
-5ndx,2018-07-11,2017-03-09
-7ndu,2022-01-26,2021-02-02
-6nds,2019-12-18,2018-12-14
-3ndg,2011-12-14,2010-06-07
-3ndk,2011-01-26,2010-06-07
-7ndz,2021-07-21,2021-02-02
-5ndw,2017-12-13,2017-03-09
-7nd4,2021-03-03,2021-01-30
-6nd2,2019-09-25,2018-12-13
-5nde,2018-01-17,2017-03-08
-3nd7,2011-06-22,2010-06-07
-5ndj,2018-05-02,2017-03-08
-1nda,1994-09-30,1993-07-02
-7nda,2021-03-03,2021-01-30
-7ndh,2021-05-19,2021-02-01
-7ndw,2021-07-21,2021-02-02
-4ndi,2013-12-18,2013-10-26
-1nd2,2003-12-16,2002-12-06
-2ndo,2017-02-08,2016-08-22
-4ndv,2014-12-10,2013-10-27
-4nda,2014-03-19,2013-10-25
-5nd2,2017-10-04,2017-03-07
-1ndv,2003-12-09,2002-12-09
-7ndm,2021-09-22,2021-02-02
-1ndu,2004-04-06,2002-12-09
-7nd7,2021-03-03,2021-01-30
-1ndw,2003-12-09,2002-12-09
-3ndq,2011-05-18,2010-06-07
-4nd7,2014-03-19,2013-10-25
-5ndk,2017-12-13,2017-03-08
-7ndc,2021-03-03,2021-01-30
-1ndy,2003-12-09,2002-12-09
-6ndd,2018-12-26,2018-12-13
-7ndd,2021-03-03,2021-01-30
-6nd7,2019-12-18,2018-12-13
-1ndp,1994-04-30,1993-11-29
-1nd4,2003-09-16,2002-12-06
-6ndn,2019-12-25,2018-12-14
-5nd0,2018-03-21,2017-03-07
-3ndi,2010-06-30,2010-06-07
-3ndm,2010-12-08,2010-06-07
-3nd6,2011-06-22,2010-06-07
-4ndr,2014-08-13,2013-10-27
-4nd1,2014-12-17,2013-10-25
-6ndf,2019-01-23,2018-12-13
-6nd8,2018-12-26,2018-12-13
-1nd5,2002-12-20,2002-12-07
-6ndh,2019-01-23,2018-12-13
-4nd3,2014-12-17,2013-10-25
-6ndl,2019-12-18,2018-12-13
-4nd4,2014-12-17,2013-10-25
-3ndj,2010-06-30,2010-06-07
-3ndh,2010-07-28,2010-06-07
-7ndj,2021-05-19,2021-02-01
-3ndz,2011-06-29,2010-06-08
-7ndk,2021-05-19,2021-02-01
-7ndo,2021-08-25,2021-02-02
-5ndu,2018-03-21,2017-03-09
-6nde,2019-01-23,2018-12-13
-7nd6,2021-03-03,2021-01-30
-6ndy,2019-08-21,2018-12-14
-5nd5,2017-06-07,2017-03-07
-7ndv,2021-04-07,2021-02-02
-5ndb,2018-01-17,2017-03-08
-4ndx,2013-11-13,2013-10-28
-5nd7,2017-10-04,2017-03-07
-4ndp,2014-08-13,2013-10-27
-4ndo,2014-08-13,2013-10-27
-1nds,1997-07-07,1997-01-23
-7ndl,2021-03-10,2021-02-02
-4ndb,2014-10-29,2013-10-25
-5ndt,2018-05-16,2017-03-09
-6ndr,2018-12-26,2018-12-14
-3ndt,2011-07-20,2010-06-08
-4ndd,2014-10-29,2013-10-25
-7nd3,2021-03-03,2021-01-30
-3ndu,2011-07-20,2010-06-08
-1ndt,1998-11-04,1998-10-28
-6nd3,2019-01-16,2018-12-13
-1ndf,2003-01-28,2002-12-09
-1nd3,2003-12-16,2002-12-06
-6ndc,2019-01-23,2018-12-13
-4nds,2014-12-10,2013-10-27
-1ndz,2003-12-09,2002-12-09
-5ndg,2017-12-13,2017-03-08
-3ndx,2011-07-20,2010-06-08
-4ndg,2013-12-18,2013-10-26
-1ndq,2004-04-06,2002-12-09
-7ndq,2022-01-26,2021-02-02
-7nds,2021-11-03,2021-02-02
-5ndc,2017-08-23,2017-03-08
-7ndi,2021-05-19,2021-02-01
-4ndz,2014-03-19,2013-10-28
-1nde,2002-12-18,2002-12-09
-7nd5,2021-03-03,2021-01-30
-7nd9,2021-03-03,2021-01-30
-3ndv,2011-09-28,2010-06-08
-4ndn,2014-07-16,2013-10-27
-1ndh,1995-02-14,1994-10-31
-3ndc,2011-06-15,2010-06-07
-7ndb,2021-03-03,2021-01-30
-6ndo,2019-12-18,2018-12-14
-6ndp,2019-12-18,2018-12-14
-7nd1,2021-06-16,2021-01-29
-4ndh,2013-12-18,2013-10-26
-6nda,2018-12-26,2018-12-13
-1nd6,2002-12-20,2002-12-07
-7nd8,2021-03-03,2021-01-30
-3ndw,2011-07-20,2010-06-08
-4ndc,2014-10-29,2013-10-25
-7ndt,2022-01-26,2021-02-02
-1ndr,1997-07-07,1997-01-23
-6ndk,2019-02-27,2018-12-13
-1ndj,2003-09-02,2002-12-09
-3ndr,2011-06-08,2010-06-08
-6yqz,2021-03-24,2020-04-18
-2yql,2008-03-18,2007-03-30
-6yq4,2021-03-24,2020-04-16
-6yqt,2020-07-01,2020-04-18
-6yq7,2020-06-10,2020-04-16
-4yqp,2016-03-16,2015-03-13
-1yql,2005-04-05,2005-02-02
-2yq5,2012-11-21,2012-11-05
-4yql,2016-03-16,2015-03-13
-6yq3,2020-09-16,2020-04-16
-1yqw,2005-04-19,2005-02-02
-1yqt,2005-04-19,2005-02-02
-2yqb,2013-04-03,2012-11-07
-1yqs,2005-06-28,2005-02-02
-7yq8,2024-01-03,2022-08-05
-5yqm,2018-10-17,2017-11-07
-6yqk,2020-10-14,2020-04-17
-6yqr,2021-03-24,2020-04-18
-6yqm,2020-04-29,2020-04-17
-6yqi,2020-10-14,2020-04-17
-7yqv,2022-10-19,2022-08-08
-1yq2,2005-10-04,2005-02-01
-2yqj,2007-05-22,2007-03-30
-4yq0,2016-03-16,2015-03-13
-1yq7,2005-02-22,2005-02-01
-6yq8,2021-01-20,2020-04-16
-7yqr,2024-02-14,2022-08-08
-4yqm,2016-10-12,2015-03-13
-7yqf,2023-07-12,2022-08-06
-7yq1,2023-01-18,2022-08-05
-4yqc,2016-03-16,2015-03-13
-6yqb,2021-02-10,2020-04-16
-6yqw,2021-04-14,2020-04-18
-4yqg,2016-03-16,2015-03-13
-1yq3,2005-12-20,2005-02-01
-7yqx,2022-10-19,2022-08-08
-4yqs,2016-03-16,2015-03-13
-4yqf,2016-03-16,2015-03-13
-4yqq,2016-03-16,2015-03-13
-6yq0,2020-09-16,2020-04-16
-5yq0,2018-06-27,2017-11-04
-5yq2,2018-11-07,2017-11-04
-4yqj,2016-03-16,2015-03-13
-2yqp,2007-10-02,2007-03-30
-1yqo,2006-01-31,2005-02-02
-1yqk,2005-04-05,2005-02-01
-4yqt,2016-03-16,2015-03-13
-5yqs,2018-11-14,2017-11-07
-6yqj,2020-10-14,2020-04-17
-7yqy,2022-10-19,2022-08-08
-6yqn,2020-05-06,2020-04-17
-7yqs,2023-08-09,2022-08-08
-4yq4,2016-03-16,2015-03-13
-1yqn,2005-07-12,2005-02-02
-5yqn,2018-10-17,2017-11-07
-5yqa,2019-02-27,2017-11-06
-1yqp,2006-01-31,2005-02-02
-2yq9,2013-07-10,2012-11-07
-2yqs,2007-05-22,2007-03-30
-7yq0,2023-01-18,2022-08-05
-7yqa,2023-02-15,2022-08-05
-1yqu,2005-04-19,2005-02-02
-4yqa,2016-03-16,2015-03-13
-4yqh,2015-04-29,2015-03-13
-4yqn,2016-03-16,2015-03-13
-2yqq,2007-10-02,2007-03-30
-5yqt,2018-06-27,2017-11-07
-5yq5,2018-04-25,2017-11-05
-5yqb,2018-11-14,2017-11-06
-4yqr,2016-03-16,2015-03-13
-1yqz,2006-05-09,2005-02-02
-2yq3,2013-01-16,2012-11-04
-4yqv,2016-10-12,2015-03-13
-6yq9,2021-02-10,2020-04-16
-1yqm,2005-04-05,2005-02-02
-5yql,2018-10-17,2017-11-07
-4yqb,2016-03-16,2015-03-13
-6yqh,2021-01-27,2020-04-17
-7yqt,2022-10-19,2022-08-08
-7yq7,2022-11-30,2022-08-05
-5yqh,2019-02-27,2017-11-06
-7yqz,2022-10-19,2022-08-08
-6yqs,2021-03-24,2020-04-18
-4yqo,2016-03-16,2015-03-13
-4yq7,2016-03-16,2015-03-13
-6yqc,2021-02-10,2020-04-16
-6yqg,2021-01-20,2020-04-17
-7yqg,2023-06-07,2022-08-06
-2yqc,2007-05-22,2007-03-30
-4yqy,2015-03-25,2015-03-13
-4yq9,2016-03-16,2015-03-13
-1yqx,2005-07-12,2005-02-02
-5yqx,2018-11-28,2017-11-08
-5yqw,2018-02-21,2017-11-08
-7yq2,2022-11-30,2022-08-05
-1yqy,2005-05-31,2005-02-02
-2yqh,2007-05-22,2007-03-30
-2yqu,2008-04-01,2007-03-31
-4yq6,2016-03-16,2015-03-13
-1yqq,2005-04-19,2005-02-02
-5yq7,2018-05-02,2017-11-05
-6yqv,2021-04-28,2020-04-18
-6yqu,2020-07-01,2020-04-18
-7yqw,2022-10-19,2022-08-08
-6yqd,2020-04-29,2020-04-16
-4yqd,2015-11-11,2015-03-13
-2yqz,2007-10-02,2007-04-01
-7yq9,2023-01-18,2022-08-05
-4yqw,2015-05-13,2015-03-13
-4yq2,2016-03-16,2015-03-13
-5yqo,2018-10-17,2017-11-07
-6yq2,2020-09-23,2020-04-16
-4yqe,2016-05-25,2015-03-13
-2yqm,2007-10-02,2007-03-30
-6yqa,2021-02-24,2020-04-16
-4yqu,2016-10-12,2015-03-13
-6yq1,2021-02-10,2020-04-16
-1yq9,2005-04-19,2005-02-01
-1yq4,2005-12-20,2005-02-01
-1yqj,2005-04-26,2005-02-01
-4yq3,2016-03-16,2015-03-13
-6yqq,2020-05-20,2020-04-18
-1yqd,2005-07-12,2005-02-01
-4yq8,2016-03-16,2015-03-13
-4yq1,2016-03-16,2015-03-13
-1yqr,2005-04-05,2005-02-02
-5yqz,2018-01-17,2017-11-08
-4yqi,2016-03-16,2015-03-13
-4yqk,2016-03-16,2015-03-13
-7yqq,2024-02-14,2022-08-08
-6yqo,2020-05-06,2020-04-17
-2yq2,2013-01-16,2012-11-04
-7yqu,2022-10-19,2022-08-08
-7yqn,2023-03-29,2022-08-08
-4yq5,2016-03-16,2015-03-13
-4yqx,2015-07-01,2015-03-13
-6yqp,2020-05-27,2020-04-17
-5yq1,2018-11-07,2017-11-04
-2v83,2007-12-11,2007-08-02
-7v81,2021-10-06,2021-08-22
-3v80,2012-03-14,2011-12-22
-2v8h,2007-10-02,2007-08-08
-1v8r,2005-02-22,2004-01-14
-3v8s,2012-02-08,2011-12-23
-5v87,2017-04-19,2017-03-21
-1v8x,2004-05-18,2004-01-15
-5v8k,2017-09-06,2017-03-22
-6v8b,2020-04-01,2019-12-10
-5v8p,2017-07-26,2017-03-22
-4v88,2014-07-09,2011-10-11
-3v8d,2013-01-09,2011-12-22
-8v8h,2024-03-20,2023-12-05
-7v84,2021-10-06,2021-08-22
-4v82,2014-07-09,2010-11-30
-2v8m,2008-08-19,2007-08-09
-4v8u,2014-07-09,2012-08-28
-6v8r,2020-08-12,2019-12-11
-6v80,2020-09-16,2019-12-10
-3v81,2012-01-18,2011-12-22
-7v80,2021-10-06,2021-08-22
-6v8s,2020-12-16,2019-12-12
-4v8g,2014-07-09,2011-12-11
-4v8f,2014-07-09,2011-12-07
-5v80,2018-04-18,2017-03-21
-7v89,2021-10-06,2021-08-22
-8v88,2024-02-21,2023-12-05
-8v8x,2023-12-13,2023-12-06
-5v84,2017-06-14,2017-03-21
-4v8r,2014-07-09,2012-03-28
-2v8f,2007-12-18,2007-08-07
-3v8e,2012-01-25,2011-12-22
-6v8d,2020-12-16,2019-12-10
-4v8z,2014-07-09,2013-07-20
-7v8j,2022-09-07,2021-08-23
-4v8i,2014-07-09,2011-12-12
-7v8u,2022-08-31,2021-08-23
-3v8m,2012-03-14,2011-12-23
-4v8c,2014-07-09,2011-12-07
-8v8m,2024-05-29,2023-12-05
-5v8u,2017-07-26,2017-03-22
-4v85,2014-07-09,2011-06-13
-2v8p,2007-08-21,2007-08-13
-1v8d,2004-07-12,2004-01-05
-6v8y,2021-04-14,2019-12-12
-1v8v,2004-10-19,2004-01-15
-6v8x,2020-02-05,2019-12-12
-3v8p,2012-03-14,2011-12-23
-8v8i,2024-03-20,2023-12-05
-6v8c,2020-12-16,2019-12-10
-4v87,2014-07-09,2011-09-20
-3v8w,2012-05-02,2011-12-23
-8v89,2024-02-21,2023-12-05
-8v8a,2024-02-21,2023-12-05
-6v86,2020-02-19,2019-12-10
-1v8s,2004-10-19,2004-01-14
-4v8y,2014-07-09,2013-07-20
-1v8z,2005-02-22,2004-01-15
-7v8y,2022-08-24,2021-08-23
-4v8n,2014-07-09,2013-02-13
-6v8k,2020-04-01,2019-12-11
-2v8t,2007-09-11,2007-08-14
-4v84,2014-07-09,2010-12-13
-1v8n,2004-10-19,2004-01-12
-1v8l,2004-10-19,2004-01-10
-2v8k,2007-09-18,2007-08-08
-3v8x,2012-02-29,2011-12-23
-4v83,2014-07-09,2010-12-13
-4v8q,2014-07-09,2011-12-10
-6v82,2020-12-16,2019-12-10
-8v8g,2024-05-29,2023-12-05
-6v8u,2020-04-15,2019-12-12
-7v82,2021-10-06,2021-08-22
-8v83,2024-05-01,2023-12-04
-6v8v,2020-04-22,2019-12-12
-5v8v,2017-10-18,2017-03-22
-4v8d,2014-07-09,2011-12-07
-7v86,2021-10-06,2021-08-22
-3v83,2012-02-15,2011-12-22
-6v8t,2019-12-25,2019-12-12
-8v84,2024-05-01,2023-12-04
-2v8c,2007-12-18,2007-08-06
-6v8z,2020-02-05,2019-12-12
-4v8o,2014-07-09,2011-07-26
-1v8m,2004-10-19,2004-01-12
-7v8q,2022-08-31,2021-08-23
-1v8b,2004-10-26,2004-01-03
-7v8o,2022-07-06,2021-08-23
-4v8h,2014-07-09,2011-12-11
-3v8t,2012-05-02,2011-12-23
-3v8n,2012-03-14,2011-12-23
-2v8g,2007-10-02,2007-08-07
-5v8c,2018-04-11,2017-03-21
-8v8u,2024-03-20,2023-12-06
-4v89,2014-07-09,2011-11-17
-7v88,2021-10-06,2021-08-22
-2v8w,2007-08-28,2007-08-16
-6v81,2020-05-06,2019-12-10
-1v8w,2004-10-19,2004-01-15
-1v8k,2004-03-02,2004-01-09
-6v8j,2020-12-16,2019-12-11
-5v8o,2017-09-27,2017-03-22
-7v8b,2021-10-06,2021-08-22
-3v8g,2012-02-15,2011-12-22
-8v8v,2024-03-20,2023-12-06
-2v8u,2007-09-25,2007-08-14
-8v8y,2023-12-13,2023-12-06
-7v85,2021-10-06,2021-08-22
-6v87,2019-12-25,2019-12-10
-3v8k,2012-12-26,2011-12-23
-5v85,2018-11-21,2017-03-21
-4v8w,2014-07-09,2013-04-18
-3v8f,2012-02-15,2011-12-22
-5v8x,2018-02-28,2017-03-22
-2v85,2007-12-11,2007-08-02
-4v8t,2014-07-09,2012-08-07
-8v8d,2024-02-21,2023-12-05
-5v88,2017-05-24,2017-03-21
-6v8i,2020-03-04,2019-12-11
-7v8k,2022-09-07,2021-08-23
-1v8u,2004-10-19,2004-01-15
-1v8t,2004-10-19,2004-01-14
-6v8a,2021-02-03,2019-12-10
-2v82,2007-08-14,2007-08-02
-8v8p,2024-05-29,2023-12-05
-5v8e,2017-10-18,2017-03-21
-3v8l,2012-12-26,2011-12-23
-2v8y,2007-08-28,2007-08-16
-4v8b,2014-07-09,2011-12-06
-2v87,2007-12-11,2007-08-02
-6v89,2021-02-03,2019-12-10
-3v8c,2012-02-22,2011-12-22
-5v8t,2018-03-14,2017-03-22
-4v8k,2014-07-09,2013-11-22
-6v8n,2020-04-01,2019-12-11
-4v8j,2014-07-09,2011-12-20
-4v8v,2014-07-09,2013-04-18
-2v8b,2008-08-26,2007-08-06
-7v8c,2021-10-06,2021-08-22
-5v8f,2017-05-10,2017-03-21
-8v86,2024-02-21,2023-12-04
-3v8z,2012-01-25,2011-12-23
-5v8i,2018-03-28,2017-03-22
-3v8v,2012-02-29,2011-12-23
-5v8q,2017-05-24,2017-03-22
-6v8g,2020-11-18,2019-12-11
-6v83,2020-04-22,2019-12-10
-2v8v,2007-10-02,2007-08-15
-4v8e,2014-07-09,2011-12-07
-7v87,2021-10-06,2021-08-22
-7v8r,2022-07-06,2021-08-23
-2v89,2007-12-11,2007-08-03
-7v8i,2022-08-31,2021-08-23
-7v83,2021-10-06,2021-08-22
-8v8e,2024-05-29,2023-12-05
-2v8d,2007-10-02,2007-08-07
-7v8g,2022-03-30,2021-08-23
-3v8r,2012-03-14,2011-12-23
-6v8o,2020-01-15,2019-12-11
-2v88,2007-12-11,2007-08-03
-8v80,2024-02-21,2023-12-04
-8v82,2024-02-21,2023-12-04
-3v8o,2013-07-17,2011-12-23
-2v8a,2007-12-11,2007-08-06
-5v8y,2018-02-28,2017-03-22
-2v8j,2007-09-18,2007-08-08
-1v8j,2004-03-02,2004-01-09
-6v84,2021-02-03,2019-12-10
-1v8y,2004-10-19,2004-01-15
-2v8l,2008-08-19,2007-08-09
-5v82,2017-05-10,2017-03-21
-6v8q,2020-03-18,2019-12-11
-5v8m,2017-05-03,2017-03-22
-8v8c,2024-02-21,2023-12-05
-6v85,2020-02-19,2019-12-10
-5v8r,2017-07-26,2017-03-22
-2v8q,2007-09-25,2007-08-13
-8v8j,2024-03-20,2023-12-05
-2v86,2007-12-11,2007-08-02
-2v8x,2007-08-28,2007-08-16
-7v8a,2021-10-06,2021-08-22
-1v83,2004-05-25,2003-12-27
-1v84,2004-05-25,2003-12-27
-8v87,2024-05-01,2023-12-04
-5v8l,2017-05-03,2017-03-22
-1v87,2004-06-29,2003-12-29
-3v8q,2012-03-14,2011-12-23
-4v8l,2014-07-09,2012-12-06
-7v8z,2022-08-24,2021-08-23
-7v8f,2022-03-30,2021-08-22
-6v8m,2020-12-16,2019-12-11
-8v8w,2023-12-13,2023-12-06
-4v81,2014-07-09,2010-10-17
-5v83,2017-05-24,2017-03-21
-5v86,2017-05-24,2017-03-21
-4v8x,2014-07-09,2013-07-19
-4v8s,2014-07-09,2012-07-12
-7v8s,2022-07-06,2021-08-23
-6kr6,2020-02-19,2019-08-21
-3krk,2010-05-12,2009-11-18
-1krc,1995-10-15,1995-06-20
-1krv,2002-04-10,2002-01-10
-7krs,2021-03-24,2020-11-20
-6krc,2020-07-01,2019-08-21
-6kr5,2020-09-09,2019-08-21
-2kr5,2010-03-02,2009-12-03
-4kr7,2014-04-23,2013-05-16
-3kra,2010-02-23,2009-11-18
-5krc,2017-02-15,2016-07-07
-3krf,2010-02-23,2009-11-18
-7kr4,2021-02-03,2020-11-18
-7kra,2020-12-02,2020-11-19
-7krm,2020-12-30,2020-11-20
-5kra,2017-02-15,2016-07-07
-2kr1,2009-12-22,2009-11-27
-3krc,2010-02-23,2009-11-18
-5krt,2016-09-28,2016-07-07
-4kro,2013-08-28,2013-05-16
-3krv,2010-01-05,2009-11-19
-7kr6,2021-05-19,2020-11-18
-6krv,2020-01-22,2019-08-22
-7kro,2021-04-21,2020-11-20
-3krw,2010-02-16,2009-11-19
-7kri,2021-07-21,2020-11-20
-7krz,2021-02-24,2020-11-20
-1krf,2002-02-20,2002-01-09
-5krv,2017-07-12,2016-07-07
-5krf,2017-02-15,2016-07-07
-1krr,2002-04-10,2002-01-10
-7krf,2021-01-13,2020-11-19
-1krj,2002-01-23,2002-01-09
-1krh,2002-05-15,2002-01-09
-5kr1,2016-09-21,2016-07-06
-3kr4,2010-02-02,2009-11-17
-4kr5,2013-09-11,2013-05-16
-3krl,2010-12-01,2009-11-18
-5kr6,2017-07-12,2016-07-07
-5kr5,2017-07-12,2016-07-07
-7kru,2021-09-15,2020-11-20
-3krd,2010-09-29,2009-11-18
-7kr8,2021-11-24,2020-11-19
-7kr5,2020-12-09,2020-11-18
-6krh,2020-08-26,2019-08-21
-7krg,2022-02-23,2020-11-19
-6kro,2020-04-01,2019-08-22
-7krx,2020-12-02,2020-11-20
-4kr4,2014-05-28,2013-05-16
-5kre,2016-07-20,2016-07-07
-7krn,2021-04-21,2020-11-20
-4kra,2014-05-28,2013-05-16
-4krs,2013-08-28,2013-05-17
-3kru,2009-12-08,2009-11-19
-5kr4,2017-07-12,2016-07-06
-7krc,2021-01-13,2020-11-19
-4krl,2013-08-28,2013-05-16
-1kr7,2002-05-15,2002-01-09
-5kr9,2017-02-15,2016-07-07
-5krl,2017-01-18,2016-07-07
-1kr2,2003-01-08,2002-01-08
-2kr2,2010-07-14,2009-11-30
-6krn,2020-06-17,2019-08-22
-1krp,1998-02-25,1997-08-19
-3krz,2009-12-08,2009-11-20
-3kr7,2009-12-15,2009-11-18
-4kri,2013-09-25,2013-05-16
-5kru,2016-07-27,2016-07-07
-7kr7,2021-11-24,2020-11-18
-3kro,2010-02-23,2009-11-19
-6kr2,2020-04-01,2019-08-20
-5kr3,2017-07-12,2016-07-06
-5kro,2017-01-18,2016-07-07
-6krf,2020-07-01,2019-08-21
-7krq,2021-03-31,2020-11-20
-6krt,2020-08-26,2019-08-22
-3krq,2010-05-26,2009-11-19
-4krm,2013-08-28,2013-05-16
-7krw,2021-09-15,2020-11-20
-1kr0,2002-01-23,2002-01-08
-6krl,2020-06-17,2019-08-22
-4krc,2013-09-18,2013-05-16
-5kri,2017-01-18,2016-07-07
-1krb,1995-10-15,1995-06-20
-7kr9,2021-12-01,2020-11-19
-7krp,2021-04-21,2020-11-20
-5kr7,2016-08-17,2016-07-07
-1kr5,2002-02-08,2002-01-08
-3kry,2010-10-06,2009-11-19
-3krx,2010-02-16,2009-11-19
-5krj,2017-01-18,2016-07-07
-4kr6,2014-04-23,2013-05-16
-2kri,2010-03-31,2009-12-18
-3kr1,2010-09-29,2009-11-17
-5kr0,2016-09-21,2016-07-06
-7krj,2022-01-12,2020-11-20
-1kre,2002-02-20,2002-01-09
-5krr,2017-07-12,2016-07-07
-3kr2,2010-09-29,2009-11-17
-1kr3,2003-01-08,2002-01-08
-4krz,2014-11-19,2013-05-17
-6kr3,2020-04-01,2019-08-20
-4krr,2013-07-10,2013-05-16
-5krb,2016-11-09,2016-07-07
-4kr3,2014-05-21,2013-05-16
-3kr5,2010-02-02,2009-11-17
-1krm,2003-01-14,2002-01-10
-3krg,2010-02-09,2009-11-18
-4kr2,2014-05-21,2013-05-16
-5kr2,2016-09-21,2016-07-06
-7krv,2021-09-15,2020-11-20
-4kr0,2013-07-10,2013-05-15
-1kro,2003-01-10,2002-01-10
-3krr,2010-07-21,2009-11-19
-4krp,2013-08-28,2013-05-16
-6kr7,2021-01-27,2019-08-21
-7kry,2021-12-01,2020-11-20
-3kr8,2009-12-15,2009-11-18
-1kr1,2002-01-23,2002-01-08
-2krj,2010-02-23,2009-12-18
-4kru,2014-04-02,2013-05-17
-1kr6,2003-01-09,2002-01-09
-3krj,2010-12-01,2009-11-18
-3krs,2009-12-01,2009-11-19
-5krk,2017-01-18,2016-07-07
-4kr8,2014-05-28,2013-05-16
-7krr,2021-03-24,2020-11-20
-7krt,2021-09-15,2020-11-20
-6kru,2020-01-22,2019-08-22
-6kri,2020-07-01,2019-08-21
-7kre,2021-01-13,2020-11-19
-3krp,2010-02-23,2009-11-19
-1kru,2002-04-10,2002-01-10
-4krv,2013-08-28,2013-05-17
-2krd,2010-02-16,2009-12-16
-3kr0,2010-09-29,2009-11-17
-4krg,2013-09-25,2013-05-16
-3kr6,2010-04-28,2009-11-17
-5krd,2017-02-15,2016-07-07
-5krq,2016-11-02,2016-07-07
-5krm,2017-01-18,2016-07-07
-6krg,2020-09-09,2019-08-21
-6krz,2020-08-19,2019-08-22
-5krh,2017-02-15,2016-07-07
-4krh,2013-09-25,2013-05-16
-7krd,2021-01-13,2020-11-19
-5krs,2016-09-28,2016-07-07
-5kr8,2016-09-07,2016-07-07
-7kr3,2021-02-03,2020-11-18
-1bd0,1998-10-14,1998-05-12
-1bdw,1998-10-14,1998-05-11
-1bdb,1997-11-12,1997-05-10
-4bdk,2013-06-26,2012-10-05
-6bdh,2017-12-13,2017-10-23
-7bd9,2022-01-12,2020-12-21
-8bdy,2022-12-07,2022-10-20
-7bdm,2021-07-28,2020-12-22
-8bdo,2023-02-15,2022-10-19
-1bdo,1996-08-01,1995-11-21
-2bd1,2006-07-04,2005-10-19
-4bd7,2013-02-13,2012-10-05
-8bdj,2023-02-15,2022-10-19
-8bdx,2023-02-15,2022-10-20
-4bdm,2013-04-10,2012-10-05
-2bdy,2006-10-24,2005-10-21
-2bdl,2006-03-21,2005-10-20
-3bdk,2008-11-18,2007-11-15
-8bd5,2022-12-28,2022-10-18
-3bdz,2008-02-12,2007-11-15
-2bd5,2006-05-30,2005-10-20
-1bdq,1998-08-12,1998-05-10
-4bd1,2013-01-16,2012-10-04
-2bdr,2005-11-15,2005-10-20
-1bdh,1997-04-21,1996-07-25
-7bdq,2021-03-03,2020-12-22
-6bd7,2017-12-13,2017-10-21
-4bdo,2013-04-10,2012-10-05
-7bdx,2021-07-07,2020-12-22
-6bdj,2018-11-14,2017-10-23
-4bdy,2012-10-31,2012-10-08
-8bd4,2022-12-28,2022-10-18
-2bd3,2006-05-30,2005-10-20
-8bd2,2023-11-08,2022-10-18
-6bdq,2018-10-03,2017-10-24
-8bd6,2022-12-28,2022-10-18
-4bdq,2013-04-10,2012-10-05
-4bde,2013-06-26,2012-10-05
-7bdl,2021-06-09,2020-12-21
-7bd6,2022-01-12,2020-12-21
-7bd0,2021-07-28,2020-12-21
-4bdf,2013-06-26,2012-10-05
-2bdi,2006-10-03,2005-10-20
-2bd0,2005-11-29,2005-10-19
-8bdc,2023-11-01,2022-10-19
-8bdg,2023-03-22,2022-10-19
-4bdz,2012-10-31,2012-10-08
-4bd8,2013-02-13,2012-10-05
-8bde,2023-03-22,2022-10-19
-8bd3,2023-08-09,2022-10-18
-6bdm,2017-12-13,2017-10-23
-6bd1,2018-10-24,2017-10-20
-1bd4,1999-05-18,1998-05-12
-3bdj,2008-11-25,2007-11-14
-2bdz,2006-10-03,2005-10-21
-4bdd,2013-06-26,2012-10-05
-3bdm,2008-04-08,2007-11-15
-6bdk,2017-12-13,2017-10-23
-4bdc,2013-06-26,2012-10-05
-6bdr,2018-10-03,2017-10-24
-4bd0,2013-01-09,2012-10-04
-8bdf,2023-03-22,2022-10-19
-2bdc,2006-05-30,2005-10-20
-6bd8,2017-12-13,2017-10-21
-4bdt,2013-05-29,2012-10-06
-6bd4,2018-08-22,2017-10-21
-6bdt,2018-02-07,2017-10-24
-4bdv,2013-05-15,2012-10-08
-6bdd,2018-05-30,2017-10-22
-3bdc,2008-11-04,2007-11-14
-6bdo,2018-05-16,2017-10-23
-7bdc,2022-01-12,2020-12-21
-3bd8,2008-11-18,2007-11-14
-4bdp,1999-01-13,1997-11-17
-7bd4,2022-01-12,2020-12-21
-7bdn,2022-01-12,2020-12-22
-7bd5,2022-01-12,2020-12-21
-7bdg,2022-01-12,2020-12-21
-2bdg,2006-10-03,2005-10-20
-1bdu,1998-07-01,1997-06-27
-3bd9,2008-01-29,2007-11-14
-7bdo,2021-03-03,2020-12-22
-7bd8,2022-01-12,2020-12-21
-8bd8,2022-12-07,2022-10-18
-3bdh,2008-11-18,2007-11-14
-4bdh,2013-06-26,2012-10-05
-7bdb,2022-01-12,2020-12-21
-1bda,1999-05-11,1998-05-07
-6bd0,2018-10-24,2017-10-20
-2bdp,1999-01-13,1997-11-17
-3bd5,2008-04-01,2007-11-14
-6bdv,2018-02-14,2017-10-24
-2bd9,2006-05-30,2005-10-20
-1bdg,1999-05-11,1998-05-08
-1bdi,1997-04-21,1996-07-25
-7bd3,2022-01-12,2020-12-21
-8bdd,2023-08-30,2022-10-19
-7bdp,2021-06-16,2020-12-22
-4bdr,2013-04-10,2012-10-05
-4bdb,2013-06-26,2012-10-05
-4bd9,2013-07-17,2012-10-05
-6bda,2018-10-24,2017-10-22
-8bdl,2023-02-15,2022-10-19
-3bd4,2008-04-01,2007-11-14
-7bda,2022-01-12,2020-12-21
-2bdo,1999-04-27,1999-03-03
-6bds,2018-10-03,2017-10-24
-4bdj,2013-06-26,2012-10-05
-7bdv,2021-03-03,2020-12-22
-2bd2,2006-05-30,2005-10-20
-7bdd,2022-01-12,2020-12-21
-7bdy,2021-06-16,2020-12-22
-2bdh,2006-10-03,2005-10-20
-7bd2,2022-01-12,2020-12-21
-6bde,2018-05-30,2017-10-22
-8bdi,2023-02-15,2022-10-19
-2bd7,2006-05-30,2005-10-20
-8bdn,2023-02-15,2022-10-19
-8bdb,2023-06-14,2022-10-19
-1bd2,1998-08-19,1998-05-12
-6bdn,2019-04-10,2017-10-23
-2bdf,2006-10-24,2005-10-20
-7bdj,2021-06-09,2020-12-21
-2bd4,2006-05-30,2005-10-20
-8bds,2023-02-15,2022-10-20
-7bdh,2022-01-12,2020-12-21
-1bdm,1994-12-20,1993-02-16
-7bd7,2021-03-17,2020-12-21
-1bdr,1998-10-14,1998-05-10
-6bd3,2017-11-08,2017-10-21
-7bdk,2021-06-09,2020-12-21
-7bdw,2021-11-10,2020-12-22
-7bde,2021-07-28,2020-12-21
-8bdm,2023-02-15,2022-10-19
-7bdi,2021-06-09,2020-12-21
-7bdt,2021-06-16,2020-12-22
-4bda,2013-06-26,2012-10-05
-3bda,2008-11-18,2007-11-14
-2bdx,2006-01-17,2005-10-21
-8bdr,2022-12-28,2022-10-19
-6bd9,2017-11-08,2017-10-22
-7bdz,2021-02-24,2020-12-22
-2bdj,2006-10-24,2005-10-20
-2bdm,2005-12-27,2005-10-20
-6bdy,2018-05-23,2017-10-24
-6bdz,2017-12-27,2017-10-24
-7bdf,2022-01-12,2020-12-21
-6bdp,2018-10-03,2017-10-24
-3bd7,2008-11-18,2007-11-14
-7bdr,2022-01-12,2020-12-22
-6bd5,2017-12-13,2017-10-21
-6bd6,2017-12-13,2017-10-21
-2bd8,2006-05-30,2005-10-20
-2bdb,2006-05-30,2005-10-20
-2bda,2006-05-30,2005-10-20
-4bdi,2013-06-26,2012-10-05
-6bdi,2017-12-13,2017-10-23
-1bdl,1998-08-12,1998-05-10
-8bd9,2022-12-07,2022-10-18
-3bdv,2007-11-27,2007-11-15
-8bdt,2023-02-15,2022-10-20
-4bdl,2013-04-10,2012-10-05
-3bd6,2008-11-18,2007-11-14
-4bdg,2013-06-26,2012-10-05
-4bdn,2013-04-10,2012-10-05
-8woz,2023-12-13,2023-10-08
-2woc,2009-08-11,2009-07-23
-6woo,2020-09-23,2020-04-25
-1wog,2004-09-07,2004-08-18
-1wo3,2005-03-08,2004-08-12
-1wop,2004-09-07,2004-08-24
-2won,2010-08-11,2009-07-27
-3woq,2014-09-03,2013-12-29
-4wop,2015-04-08,2014-10-16
-4wo9,2015-02-18,2014-10-15
-7wou,2022-11-30,2022-01-22
-2wot,2009-09-22,2009-07-28
-2woy,2010-02-16,2009-07-31
-4wot,2015-05-06,2014-10-16
-7wo5,2022-07-20,2022-01-20
-4woq,2015-10-21,2014-10-16
-6woj,2020-05-06,2020-04-24
-8woy,2023-12-13,2023-10-08
-1wov,2005-03-22,2004-08-26
-1woa,2004-10-26,2004-08-12
-1woy,2005-09-13,2004-08-27
-1wo2,2005-03-15,2004-08-11
-6wo5,2020-08-19,2020-04-24
-6woe,2021-03-03,2020-04-24
-4woz,2015-10-21,2014-10-17
-8wo4,2024-05-08,2023-10-06
-7woc,2022-07-20,2022-01-21
-2wok,2009-12-08,2009-07-26
-3wov,2014-01-22,2014-01-05
-3wol,2014-09-03,2013-12-29
-6wot,2020-08-05,2020-04-25
-2wom,2010-08-11,2009-07-27
-8wow,2024-05-15,2023-10-08
-7wo1,2022-04-13,2022-01-20
-3woa,2015-04-29,2013-12-25
-3woj,2014-09-03,2013-12-29
-2wo7,2010-07-21,2009-07-22
-6wof,2021-03-03,2020-04-24
-5wob,2018-04-18,2017-08-01
-2wos,2009-10-20,2009-07-27
-2wox,2010-08-25,2009-07-30
-6wo4,2020-08-19,2020-04-24
-2woj,2009-08-11,2009-07-26
-1wo5,2005-03-08,2004-08-12
-4wo6,2015-02-18,2014-10-15
-2wog,2010-08-04,2009-07-23
-7wof,2022-04-13,2022-01-21
-1wo6,2005-03-08,2004-08-12
-3wom,2014-09-03,2013-12-29
-3wo4,2014-12-17,2013-12-19
-1wo7,2005-03-08,2004-08-12
-8wo3,2024-02-14,2023-10-06
-5woc,2017-10-04,2017-08-01
-5wo8,2017-09-13,2017-08-01
-5wo6,2017-09-13,2017-08-01
-4wo5,2014-12-03,2014-10-15
-3won,2014-09-03,2013-12-29
-7wo2,2022-12-28,2022-01-20
-7wo3,2022-04-13,2022-01-20
-3wo7,2014-04-23,2013-12-20
-8wom,2024-03-13,2023-10-07
-6wo3,2020-08-19,2020-04-24
-2woa,2009-09-08,2009-07-22
-4wo1,2015-06-03,2014-10-15
-4wok,2014-11-26,2014-10-15
-6woc,2021-03-03,2020-04-24
-2wo0,2010-05-05,2009-07-21
-4woi,2015-08-05,2014-10-15
-8wox,2023-12-13,2023-10-08
-2woo,2009-08-11,2009-07-27
-4wov,2015-03-18,2014-10-16
-4wo0,2015-08-05,2014-10-15
-7wo7,2022-07-20,2022-01-20
-7wob,2022-07-20,2022-01-21
-8wo0,2024-05-08,2023-10-06
-3woi,2014-09-03,2013-12-29
-4wou,2015-11-04,2014-10-16
-1wox,2005-03-22,2004-08-26
-8wo8,2024-02-14,2023-10-06
-2wow,2010-08-04,2009-07-30
-5wol,2017-08-16,2017-08-02
-2woi,2010-08-04,2009-07-24
-1woo,2004-09-07,2004-08-24
-2wob,2009-12-29,2009-07-22
-2wo6,2009-08-18,2009-07-22
-2wo3,2009-10-27,2009-07-21
-6wov,2020-08-05,2020-04-25
-5wo7,2017-09-13,2017-08-01
-3woo,2014-09-03,2013-12-29
-7wor,2022-11-30,2022-01-22
-3wo3,2014-12-17,2013-12-19
-8wo7,2024-01-10,2023-10-06
-3wop,2014-09-03,2013-12-29
-6woy,2020-06-10,2020-04-26
-4woj,2015-10-21,2014-10-15
-6wok,2020-07-01,2020-04-24
-1woi,2004-09-07,2004-08-18
-6woi,2021-03-03,2020-04-24
-2woe,2009-08-18,2009-07-23
-6wog,2021-03-03,2020-04-24
-3wor,2014-09-03,2013-12-29
-2wof,2010-05-05,2009-07-23
-4wol,2015-06-03,2014-10-16
-6woa,2021-03-03,2020-04-24
-1woz,2005-10-04,2004-08-27
-1wok,2005-03-15,2004-08-20
-2wov,2010-08-04,2009-07-30
-8wos,2024-03-20,2023-10-07
-8wor,2024-03-20,2023-10-07
-2wo4,2009-12-29,2009-07-21
-2wo2,2009-10-27,2009-07-21
-3wok,2014-09-03,2013-12-29
-7wox,2022-04-13,2022-01-22
-7wov,2022-11-30,2022-01-22
-6wox,2020-06-10,2020-04-26
-6wo2,2020-09-02,2020-04-24
-5wo0,2017-09-13,2017-08-01
-1wor,2004-09-07,2004-08-24
-4woh,2015-02-18,2014-10-15
-5wo2,2017-08-16,2017-08-01
-3wo0,2014-05-14,2013-12-19
-4woe,2015-04-15,2014-10-15
-7woq,2022-11-30,2022-01-22
-3wo6,2014-04-23,2013-12-20
-6wo8,2021-03-03,2020-04-24
-2wop,2009-12-08,2009-07-27
-8wop,2024-05-08,2023-10-07
-7wos,2022-11-30,2022-01-22
-1woq,2004-09-28,2004-08-24
-3wod,2014-03-12,2013-12-26
-8wo2,2024-02-14,2023-10-06
-5wo1,2017-08-16,2017-08-01
-6wo7,2021-03-03,2020-04-24
-2wo9,2009-09-08,2009-07-22
-6wo9,2021-03-03,2020-04-24
-3wo1,2014-05-14,2013-12-19
-1wo4,2005-03-08,2004-08-12
-5woa,2017-10-04,2017-08-01
-2woh,2010-05-05,2009-07-23
-2woq,2009-10-27,2009-07-27
-6woq,2020-08-19,2020-04-25
-3wow,2015-02-04,2014-01-06
-6wo1,2020-07-15,2020-04-23
-6wo0,2020-07-01,2020-04-23
-7woa,2022-07-20,2022-01-21
-5wo9,2017-09-13,2017-08-01
-7wo4,2022-07-20,2022-01-20
-5wo4,2017-12-06,2017-08-01
-2wou,2009-09-22,2009-07-28
-6wol,2021-09-15,2020-04-24
-6wod,2021-03-03,2020-04-24
-4woa,2015-02-18,2014-10-15
-7woh,2022-04-13,2022-01-21
-2wo8,2009-09-08,2009-07-22
-1wow,2005-03-22,2004-08-26
-6wob,2021-03-03,2020-04-24
-1wof,2005-08-30,2004-08-18
-8woo,2024-03-13,2023-10-07
-4wor,2014-10-29,2014-10-16
-6wou,2020-08-05,2020-04-25
-5wog,2018-01-10,2017-08-02
-5wo3,2017-08-16,2017-08-01
-2wod,2009-08-11,2009-07-23
-8wot,2024-03-20,2023-10-07
-4wod,2015-04-15,2014-10-15
-4wo4,2014-11-26,2014-10-15
-8woq,2024-03-20,2023-10-07
-7won,2022-07-13,2022-01-22
-5woh,2018-01-10,2017-08-02
-8wov,2024-05-15,2023-10-07
-3wog,2014-04-09,2013-12-26
-5wou,2018-02-28,2017-08-03
-2wor,2009-10-20,2009-07-27
-3jsj,2009-09-22,2009-09-10
-6jsf,2019-08-28,2019-04-08
-1jso,2001-09-26,2001-08-17
-1jsn,2001-09-26,2001-08-17
-3jsu,2010-07-28,2009-09-11
-4jsp,2013-05-01,2013-03-22
-2jst,2008-05-27,2007-07-12
-5jsm,2016-09-14,2016-05-08
-5js9,2016-07-13,2016-05-07
-5jsj,2017-05-24,2016-05-08
-2jsc,2007-07-31,2007-07-02
-6jst,2020-04-08,2019-04-08
-4jsz,2013-06-19,2013-03-22
-5jsq,2016-11-09,2016-05-09
-4jsx,2013-05-08,2013-03-22
-3jsr,2009-09-22,2009-09-10
-8jsp,2023-11-15,2023-06-20
-6js9,2019-11-20,2019-04-08
-5jsc,2016-06-08,2016-05-07
-4jsi,2013-08-07,2013-03-22
-7js3,2020-11-04,2020-08-13
-1js8,2001-10-03,2001-08-16
-1js6,2001-10-26,2001-08-16
-3jsi,2009-12-01,2009-09-10
-1jsd,2001-09-26,2001-08-17
-3jsw,2009-12-01,2009-09-11
-5js3,2016-12-21,2016-05-07
-3jsz,2010-02-02,2009-09-11
-4jsg,2013-08-07,2013-03-22
-1jsl,2002-01-09,2001-08-17
-3jsf,2009-11-10,2009-09-10
-3js8,2010-02-09,2009-09-09
-7jsi,2020-12-16,2020-08-14
-7jse,2020-12-09,2020-08-14
-5js5,2017-03-08,2016-05-07
-5jsh,2017-03-22,2016-05-08
-4jsw,2013-06-19,2013-03-22
-5jss,2016-12-21,2016-05-09
-4js0,2014-03-05,2013-03-22
-8jsc,2024-03-13,2023-06-19
-4jsy,2013-08-28,2013-03-22
-1js9,2002-04-03,2001-08-16
-3js5,2009-09-22,2009-09-09
-4jse,2013-08-07,2013-03-22
-3jsq,2010-08-25,2009-09-10
-4jst,2013-08-28,2013-03-22
-2jsd,2007-11-20,2007-07-03
-5jsa,2016-07-13,2016-05-07
-5jsg,2017-05-10,2016-05-08
-6jsn,2019-08-28,2019-04-08
-4jsq,2013-05-01,2013-03-22
-4js6,2013-06-19,2013-03-22
-3jsx,2010-01-12,2009-09-11
-5jsp,2017-02-22,2016-05-09
-6jsb,2019-11-20,2019-04-08
-4jsv,2013-05-01,2013-03-22
-6jsg,2019-08-28,2019-04-08
-4jsc,2013-07-24,2013-03-22
-4js9,2014-04-23,2013-03-22
-6jsz,2019-08-28,2019-04-08
-5jsl,2017-03-08,2016-05-08
-3jsm,2009-09-29,2009-09-10
-1jsw,1997-06-16,1997-02-19
-8jsm,2023-09-27,2023-06-20
-4js8,2014-03-26,2013-03-22
-4js3,2014-03-26,2013-03-22
-1jst,1997-01-11,1996-07-03
-6jse,2019-08-28,2019-04-08
-3jsd,2010-09-15,2009-09-10
-4jsu,2013-05-01,2013-03-22
-5jse,2017-03-08,2016-05-08
-6jss,2020-04-08,2019-04-08
-8js9,2024-05-01,2023-06-19
-4jsf,2013-08-07,2013-03-22
-5jsw,2017-05-24,2016-05-09
-4jsr,2013-04-24,2013-03-22
-4jsm,2013-08-07,2013-03-22
-6jsu,2020-04-08,2019-04-08
-5jsr,2017-02-22,2016-05-09
-7js5,2021-04-28,2020-08-13
-5js6,2016-07-13,2016-05-07
-5jsk,2017-03-22,2016-05-08
-7js7,2021-04-28,2020-08-13
-3jsa,2009-09-22,2009-09-09
-7jsk,2021-02-24,2020-08-14
-1js3,2001-10-26,2001-08-16
-1jsz,2002-07-10,2001-08-19
-5jsf,2016-07-13,2016-05-08
-8jso,2023-11-15,2023-06-20
-5jsv,2017-05-24,2016-05-09
-8jsl,2023-09-27,2023-06-20
-7jsp,2021-08-25,2020-08-15
-1jsr,2002-01-09,2001-08-17
-1jsa,1997-10-15,1997-06-04
-1js4,1997-09-17,1997-05-30
-4jsl,2013-08-07,2013-03-22
-4jsd,2013-10-09,2013-03-22
-3js4,2009-09-22,2009-09-09
-6js8,2020-03-18,2019-04-07
-8jsw,2023-11-29,2023-06-20
-1jsv,2001-08-29,2001-08-19
-1jsm,2001-09-26,2001-08-17
-8jsx,2024-05-08,2023-06-20
-7jsn,2020-10-21,2020-08-15
-5jsu,2017-03-22,2016-05-09
-1jsc,2002-01-16,2001-08-17
-5jsd,2017-03-08,2016-05-08
-1jsi,2001-09-26,2001-08-17
-3js2,2010-02-23,2009-09-09
-6jsa,2019-11-20,2019-04-08
-8jsn,2023-09-27,2023-06-20
-4jss,2013-06-19,2013-03-22
-7jso,2021-06-23,2020-08-15
-5jst,2017-03-22,2016-05-09
-7jsd,2021-08-25,2020-08-14
-4jsj,2013-08-07,2013-03-22
-4js1,2013-07-31,2013-03-22
-8js8,2024-05-01,2023-06-19
-3jsg,2009-11-10,2009-09-10
-4js2,2013-07-31,2013-03-22
-4jso,2013-10-09,2013-03-22
-5jsy,2017-03-22,2016-05-09
-5jso,2017-02-22,2016-05-09
-4jsk,2013-08-07,2013-03-22
-4jsa,2013-06-19,2013-03-22
-7jsj,2021-02-24,2020-08-14
-6jsj,2020-02-19,2019-04-08
-3js3,2009-09-22,2009-09-09
-1jsh,2001-09-26,2001-08-17
-4jsh,2013-08-07,2013-03-22
-5js1,2016-07-20,2016-05-07
-6jsc,2019-11-20,2019-04-08
-7jsu,2021-03-10,2020-08-16
-5jsx,2017-05-24,2016-05-09
-3jsk,2010-09-29,2009-09-10
-7js8,2021-08-11,2020-08-14
-5js2,2016-07-20,2016-05-07
-2izr,2006-08-01,2006-07-26
-6iz6,2019-05-01,2018-12-18
-1izo,2003-03-18,2002-10-10
-8izj,2024-04-10,2023-04-07
-5izz,2017-01-18,2016-03-26
-6izx,2019-12-25,2018-12-20
-5ize,2016-06-29,2016-03-25
-5izm,2016-10-12,2016-03-25
-8izy,2023-11-29,2023-04-09
-6iz2,2019-05-15,2018-12-18
-4iz8,2013-02-06,2013-01-29
-2izt,2006-08-01,2006-07-26
-4izu,2014-02-12,2013-01-30
-2izi,1998-09-16,1997-08-13
-4izk,2013-02-27,2013-01-30
-2iz0,2007-01-23,2006-07-23
-5iz4,2016-05-04,2016-03-24
-2izo,2006-09-06,2006-07-25
-5izj,2016-07-20,2016-03-25
-2izq,2007-01-23,2006-07-26
-4izt,2014-02-12,2013-01-30
-8iz4,2024-04-10,2023-04-06
-8izz,2024-04-10,2023-04-09
-6izy,2019-12-25,2018-12-20
-5izq,2016-08-10,2016-03-25
-8izm,2024-04-17,2023-04-07
-1iz7,2002-10-16,2002-09-30
-4izc,2013-06-05,2013-01-29
-2izz,2006-08-01,2006-07-31
-1izi,2002-12-23,2002-10-02
-1izh,2002-12-23,2002-10-02
-5izc,2017-04-05,2016-03-25
-2iz1,2007-01-23,2006-07-23
-1izj,2003-07-29,2002-10-03
-5izo,2017-08-02,2016-03-25
-5izk,2016-10-12,2016-03-25
-8ize,2023-09-13,2023-04-07
-8izt,2024-04-17,2023-04-08
-5iz9,2017-07-05,2016-03-25
-4izy,2013-12-18,2013-01-30
-1iz2,2003-02-11,2002-09-19
-5iza,2017-07-05,2016-03-25
-1izd,2003-03-04,2002-10-02
-5izr,2016-06-08,2016-03-25
-2izs,2006-08-01,2006-07-26
-4izw,2014-02-12,2013-01-30
-5izl,2016-10-12,2016-03-25
-2izf,1998-09-16,1997-08-13
-8iza,2024-04-10,2023-04-06
-4izs,2014-02-12,2013-01-30
-6izn,2019-03-27,2018-12-20
-6izh,2019-01-02,2018-12-19
-2izc,1998-09-16,1997-08-13
-4iz9,2013-02-20,2013-01-29
-6izf,2019-05-01,2018-12-19
-3iz0,2010-10-13,2010-08-09
-5izf,2016-07-20,2016-03-25
-6izm,2019-03-27,2018-12-20
-8izg,2023-09-13,2023-04-07
-8iz9,2024-04-10,2023-04-06
-4izd,2013-06-05,2013-01-29
-8izc,2024-04-10,2023-04-06
-8iz7,2024-04-10,2023-04-06
-6izq,2019-12-25,2018-12-20
-6izz,2019-12-25,2018-12-20
-5iz6,2017-07-05,2016-03-25
-6iz1,2019-05-01,2018-12-18
-2izv,2006-08-02,2006-07-26
-4izg,2013-02-13,2013-01-29
-6izw,2019-10-16,2018-12-20
-8izl,2024-04-17,2023-04-07
-4izn,2014-02-05,2013-01-30
-2izu,2006-08-01,2006-07-26
-5iz2,2016-07-27,2016-03-24
-1izk,2003-07-29,2002-10-03
-2ize,1998-09-16,1997-08-13
-5izd,2017-04-05,2016-03-25
-4iz5,2013-04-10,2013-01-29
-4iz7,2013-04-10,2013-01-29
-4iz0,2013-04-17,2013-01-29
-4iz6,2013-07-31,2013-01-29
-2izj,1998-09-16,1997-08-13
-6izv,2019-06-19,2018-12-20
-1izc,2003-04-01,2002-10-01
-6iz0,2019-05-01,2018-12-18
-1ize,2003-03-04,2002-10-02
-4izj,2013-02-27,2013-01-30
-1izb,1993-10-31,1992-10-16
-2izk,1998-09-16,1997-08-13
-2izh,1998-09-16,1997-08-13
-4izm,2013-04-10,2013-01-30
-2izl,1998-09-16,1997-08-13
-1izl,2003-01-14,2002-10-04
-4izx,2013-11-20,2013-01-30
-2izg,1998-09-16,1997-08-13
-5iz0,2016-06-15,2016-03-24
-6izr,2019-06-19,2018-12-20
-5iz7,2016-05-25,2016-03-25
-1iz8,2002-10-16,2002-09-30
-8izu,2024-04-17,2023-04-08
-8izb,2023-11-01,2023-04-06
-4izv,2014-02-12,2013-01-30
-2izx,2006-11-08,2006-07-27
-5iz8,2017-07-05,2016-03-25
-4hnp,2014-01-29,2012-10-20
-6hn4,2018-11-21,2018-09-14
-3hnc,2011-02-23,2009-05-31
-2hnd,2006-09-05,2006-07-12
-2hne,2006-07-25,2006-07-12
-2hnk,2007-09-04,2006-07-13
-8hnd,2023-09-13,2022-12-07
-3hnf,2011-02-23,2009-05-31
-2hnu,2007-04-24,2006-07-13
-2hn2,2006-08-29,2006-07-11
-6hn8,2019-10-09,2018-09-14
-3hn8,2010-02-23,2009-05-30
-2hn1,2006-08-29,2006-07-11
-4hnf,2012-11-14,2012-10-19
-1hn2,2001-12-05,2000-12-05
-3hn1,2009-07-14,2009-05-29
-4hn2,2012-10-31,2012-10-18
-8hn3,2023-07-05,2022-12-07
-5hn4,2016-12-07,2016-01-18
-6hny,2019-08-07,2018-09-17
-4hnn,2013-09-04,2012-10-19
-3hn3,2009-12-01,2009-05-29
-1hni,1995-06-03,1995-02-28
-8hn8,2023-12-20,2022-12-07
-4hnb,2013-01-16,2012-10-19
-8hny,2023-04-26,2022-12-09
-4hnc,2013-10-30,2012-10-19
-3hns,2009-07-21,2009-06-01
-1hnn,2001-12-07,2000-12-07
-6hn2,2019-02-27,2018-09-13
-5hnk,2016-06-01,2016-01-18
-5hnv,2017-01-25,2016-01-19
-1hn0,2003-04-08,2000-12-05
-8hnh,2023-09-13,2022-12-07
-6hnd,2019-02-20,2018-09-14
-2hn9,2007-07-17,2006-07-12
-3hnv,2009-07-21,2009-06-01
-1hnb,1994-01-31,1993-10-15
-5hn3,2016-12-07,2016-01-18
-3hnb,2010-01-19,2009-05-31
-3hnd,2011-02-23,2009-05-31
-6hnx,2018-12-26,2018-09-17
-5hn5,2016-12-07,2016-01-18
-3hnh,2010-05-12,2009-05-31
-5hnx,2016-08-10,2016-01-19
-8hnl,2023-11-29,2022-12-08
-4hnl,2012-11-07,2012-10-19
-3hng,2009-06-30,2009-05-31
-1hnj,2000-12-27,2000-12-07
-5hn6,2016-12-07,2016-01-18
-4hns,2013-10-02,2012-10-21
-6hnw,2019-08-07,2018-09-17
-6hni,2019-08-28,2018-09-15
-8hnz,2023-04-19,2022-12-09
-3hne,2011-02-23,2009-05-31
-5hnm,2016-02-10,2016-01-18
-1hnx,2001-02-21,2000-12-08
-3hni,2010-02-09,2009-05-31
-4hnz,2013-07-10,2012-10-22
-8hnc,2023-09-13,2022-12-07
-2hny,2006-09-05,2006-07-13
-6hnq,2018-10-24,2018-09-17
-5hne,2016-05-04,2016-01-18
-3hnl,2010-02-09,2009-05-31
-4hno,2013-01-23,2012-10-20
-5hnt,2017-03-15,2016-01-18
-5hni,2016-11-23,2016-01-18
-5hn0,2016-03-30,2016-01-17
-8hn9,2023-05-10,2022-12-07
-2hn7,2006-11-28,2006-07-12
-1hn1,2001-12-12,2000-12-05
-6hn1,2019-10-09,2018-09-13
-5hnr,2016-01-27,2016-01-18
-4hn5,2012-12-12,2012-10-18
-2hnz,2006-09-05,2006-07-13
-2hnc,2006-12-19,2006-07-12
-5hny,2016-08-10,2016-01-19
-8hnn,2023-11-29,2022-12-08
-2hnv,2007-04-24,2006-07-13
-8hnk,2023-11-29,2022-12-08
-6hns,2019-01-02,2018-09-17
-6hnr,2019-05-08,2018-09-17
-6hn0,2019-10-09,2018-09-13
-4hn1,2012-11-21,2012-10-18
-4hna,2013-06-12,2012-10-19
-8hn4,2023-12-27,2022-12-07
-3hnz,2010-02-09,2009-06-01
-4hn6,2012-12-12,2012-10-18
-5hn9,2016-09-07,2016-01-18
-1hnv,1995-07-10,1995-03-30
-1hnh,2000-12-27,2000-12-07
-3hnt,2009-07-21,2009-06-01
-5hnw,2016-08-10,2016-01-19
-8hnj,2023-07-19,2022-12-08
-2hnf,2006-09-19,2006-07-12
-1hnw,2001-02-21,2000-12-08
-8hn7,2023-05-17,2022-12-07
-3hnk,2010-02-09,2009-05-31
-8hnq,2023-12-20,2022-12-08
-4hni,2012-11-14,2012-10-19
-5hnu,2017-01-25,2016-01-18
-5hnb,2016-04-27,2016-01-18
-1hne,1989-10-15,1989-04-10
-6hn5,2018-11-21,2018-09-14
-4hnt,2013-01-16,2012-10-21
-4hnh,2012-10-31,2012-10-19
-8hnb,2023-09-13,2022-12-07
-1hn4,2001-12-05,2000-12-06
-4hnd,2014-04-09,2012-10-19
-5hn8,2016-09-07,2016-01-18
-4hnq,2013-10-02,2012-10-21
-5hng,2016-06-08,2016-01-18
-1hnl,1995-02-14,1994-12-22
-1hny,1996-03-08,1995-06-28
-4hnu,2013-01-16,2012-10-21
-6hnu,2019-02-20,2018-09-17
-5hna,2016-09-07,2016-01-18
-4hn4,2013-12-25,2012-10-18
-1hnc,1994-01-31,1993-10-15
-3hnj,2010-02-09,2009-05-31
-1hnz,2001-02-21,2000-12-08
-6hnv,2019-02-20,2018-09-17
-1hnd,2000-12-27,2000-12-07
-6hnz,2018-12-26,2018-09-17
-1hnf,1995-02-07,1994-08-10
-6hno,2019-07-31,2018-09-17
-5hns,2016-02-10,2016-01-18
-2hnl,2007-07-17,2006-07-13
-3hnm,2009-07-07,2009-05-31
-5hnz,2016-08-10,2016-01-19
-4hnx,2014-03-26,2012-10-21
-3hna,2009-06-09,2009-05-30
-5hn7,2016-09-07,2016-01-18
-4hnv,2013-01-16,2012-10-21
-8hnm,2023-11-29,2022-12-08
-4hne,2014-04-09,2012-10-19
-1hna,1994-01-31,1993-10-15
-6hnc,2019-05-08,2018-09-14
-4rq7,2015-04-15,2014-10-31
-1rqa,2005-01-04,2003-12-04
-1rqp,2004-03-02,2003-12-06
-4rqi,2016-02-10,2014-11-03
-2rqz,2010-10-13,2010-02-26
-6rqb,2020-04-22,2019-05-15
-3rql,2012-05-02,2011-04-28
-1rqg,2004-05-25,2003-12-05
-3rqt,2011-05-11,2011-04-28
-6rqt,2019-12-11,2019-05-16
-6rqz,2020-07-08,2019-05-16
-4rq8,2015-04-15,2014-10-31
-7rq8,2021-10-13,2021-08-06
-6rq5,2020-04-22,2019-05-15
-1rqn,2004-04-20,2003-12-05
-3rq4,2011-06-01,2011-04-27
-4rqe,2015-11-04,2014-11-03
-4rq5,2015-04-15,2014-10-31
-6rq1,2020-04-22,2019-05-15
-7rqy,2022-06-01,2021-08-08
-6rqf,2019-11-13,2019-05-15
-2rqb,2009-05-05,2009-03-17
-1rqe,2004-09-07,2003-12-05
-1rqk,2004-04-27,2003-12-05
-4rqx,2015-04-01,2014-11-05
-7rqs,2021-12-08,2021-08-07
-1rqb,2004-09-07,2003-12-04
-6rqg,2019-11-13,2019-05-15
-3rqz,2011-05-18,2011-04-28
-3rq0,2011-05-11,2011-04-27
-4rqs,2014-12-31,2014-11-05
-6rqi,2020-04-15,2019-05-15
-1rqf,2004-10-05,2003-12-05
-1rq4,2003-12-23,2003-12-04
-7rq6,2022-04-20,2021-08-05
-4rq1,2015-04-15,2014-10-31
-1rq7,2004-08-31,2003-12-04
-6rqq,2019-09-11,2019-05-16
-4rqk,2014-12-17,2014-11-03
-1rqr,2004-03-02,2003-12-07
-6rq6,2020-04-22,2019-05-15
-4rqu,2014-12-17,2014-11-05
-3rqw,2012-03-07,2011-04-28
-6rq3,2020-04-22,2019-05-15
-4rq6,2015-04-15,2014-10-31
-6rqw,2019-09-11,2019-05-16
-3rqo,2012-05-02,2011-04-28
-4rq0,2015-04-15,2014-10-31
-6rq9,2020-04-22,2019-05-15
-7rqu,2022-06-01,2021-08-08
-1rq1,2004-06-08,2003-12-04
-7rqw,2022-06-01,2021-08-08
-4rqf,2015-11-04,2014-11-03
-6rqd,2020-04-22,2019-05-15
-4rq4,2015-04-15,2014-10-31
-7rqx,2022-06-01,2021-08-08
-8rqf,2024-03-27,2024-01-18
-2rqc,2009-08-04,2009-04-09
-6rq7,2019-07-10,2019-05-15
-6rqj,2020-01-08,2019-05-15
-3rqk,2012-05-02,2011-04-28
-6rqy,2020-09-02,2019-05-16
-6rq0,2020-04-22,2019-05-15
-8rq0,2024-05-22,2024-01-17
-8rq2,2024-05-22,2024-01-17
-7rq9,2021-10-13,2021-08-06
-8rqh,2024-05-15,2024-01-18
-6rqp,2019-07-17,2019-05-16
-7rqd,2022-01-26,2021-08-06
-1rqh,2004-09-07,2003-12-05
-4rqw,2015-08-12,2014-11-05
-1rqd,2004-07-13,2003-12-04
-6rqe,2020-04-22,2019-05-15
-7rqr,2022-03-02,2021-08-06
-3rq2,2011-07-27,2011-04-27
-4rq2,2015-04-15,2014-10-31
-4rqa,2014-11-26,2014-10-31
-8rqu,2024-02-14,2024-01-19
-3rqd,2011-08-24,2011-04-28
-8rqb,2024-03-13,2024-01-17
-4rqt,2014-12-17,2014-11-05
-7rqz,2022-06-01,2021-08-08
-3rqi,2011-05-11,2011-04-28
-7rqv,2022-06-01,2021-08-08
-3rq8,2011-07-27,2011-04-27
-3rqq,2011-07-27,2011-04-28
-7rq0,2022-08-10,2021-08-05
-4rqv,2014-12-17,2014-11-05
-2rqa,2009-05-05,2009-03-17
-3rqx,2011-07-27,2011-04-28
-6rq4,2019-12-04,2019-05-15
-3rqp,2012-05-02,2011-04-28
-4rqr,2015-04-01,2014-11-04
-7rqq,2022-03-02,2021-08-06
-7rqe,2022-01-26,2021-08-06
-7rqb,2022-01-26,2021-08-06
-6rqn,2019-09-11,2019-05-16
-6rq8,2020-04-22,2019-05-15
-1rq5,2004-03-30,2003-12-04
-4rqn,2016-01-27,2014-11-03
-6rqo,2019-07-17,2019-05-16
-6rqu,2019-10-16,2019-05-16
-1rq3,2003-12-23,2003-12-04
-7rqc,2022-01-26,2021-08-06
-8rq4,2024-02-14,2024-01-17
-4rq3,2015-04-15,2014-10-31
-6rqc,2019-11-20,2019-05-15
-3rq7,2011-07-20,2011-04-27
-3rqn,2012-05-02,2011-04-28
-3rq1,2011-05-18,2011-04-27
-4rql,2015-01-28,2014-11-03
-3rqh,2011-07-27,2011-04-28
-3rq6,2011-07-27,2011-04-27
-4rqm,2016-01-27,2014-11-03
-3rq5,2011-07-27,2011-04-27
-7rqa,2022-01-26,2021-08-06
-3rqm,2012-05-02,2011-04-28
-1rqc,2004-01-20,2003-12-04
-1rqi,2004-03-02,2003-12-05
-4rqz,2015-03-11,2014-11-05
-1rql,2004-04-20,2003-12-05
-4rq9,2016-05-11,2014-10-31
-6rqk,2019-08-28,2019-05-16
-1rq9,2004-12-07,2003-12-04
-6rqa,2019-08-14,2019-05-15
-6rqx,2019-12-18,2019-05-16
-2rqf,2010-05-05,2009-04-27
-3rqj,2012-05-02,2011-04-28
-1rqj,2004-03-02,2003-12-05
-1rqq,2003-12-30,2003-12-06
-1rqx,2004-08-17,2003-12-07
-2wue,2009-10-20,2009-10-02
-2wuv,2010-12-08,2009-10-09
-4wuw,2016-02-10,2014-11-03
-8wuc,2024-03-27,2023-10-20
-7wu1,2023-02-08,2022-02-05
-6wuw,2020-05-20,2020-05-05
-3wus,2015-06-24,2014-05-02
-8wug,2023-11-22,2023-10-20
-1wut,2005-12-08,2004-12-08
-8wul,2024-05-01,2023-10-20
-1wuw,2005-01-11,2004-12-09
-7wuz,2023-02-15,2022-02-09
-4wu3,2015-12-09,2014-10-30
-7wuy,2023-02-15,2022-02-09
-6wur,2020-07-01,2020-05-05
-1wu5,2005-02-22,2004-12-01
-4wud,2015-04-08,2014-10-31
-1wug,2005-08-16,2004-12-07
-4wu1,2015-06-10,2014-10-30
-5wu4,2017-05-31,2016-12-16
-7wua,2022-08-10,2022-02-07
-5wuk,2017-05-03,2016-12-19
-3wui,2014-07-16,2014-04-25
-4wu9,2015-09-02,2014-10-31
-2wu7,2009-10-20,2009-09-30
-4wu7,2015-05-06,2014-10-31
-4wuy,2015-04-08,2014-11-04
-4wur,2014-11-26,2014-11-03
-1wum,2005-08-16,2004-12-08
-5wum,2017-01-25,2016-12-19
-3wuh,2014-09-17,2014-04-24
-4wuh,2015-05-06,2014-10-31
-7wuw,2022-09-07,2022-02-09
-4wun,2014-11-19,2014-11-02
-4wu5,2015-05-06,2014-10-31
-2wuc,2009-12-15,2009-10-01
-2wuz,2009-10-20,2009-10-11
-7wuk,2023-02-08,2022-02-08
-6wu9,2020-11-04,2020-05-04
-3wua,2014-07-30,2014-04-23
-7wu0,2022-10-19,2022-02-05
-3wup,2015-06-17,2014-05-01
-1wu6,2005-02-22,2004-12-01
-3wuw,2014-05-28,2014-05-06
-1wuh,2005-12-07,2004-12-07
-6wui,2020-05-20,2020-05-04
-5wuw,2018-02-28,2016-12-21
-1wur,2005-07-19,2004-12-08
-7wu7,2022-12-21,2022-02-07
-6wue,2020-08-26,2020-05-04
-5wuc,2017-07-12,2016-12-17
-4wut,2014-12-17,2014-11-03
-3wu8,2014-07-30,2014-04-23
-2wu4,2009-10-20,2009-09-28
-1wu8,2005-11-29,2004-12-02
-4wua,2015-09-16,2014-10-31
-7wud,2023-02-08,2022-02-08
-6wuu,2020-05-20,2020-05-05
-7wul,2023-02-08,2022-02-08
-1wu4,2005-02-22,2004-12-01
-1wuf,2004-12-21,2004-12-07
-4wub,2015-04-08,2014-10-31
-3wuc,2015-04-08,2014-04-23
-5wuf,2017-08-09,2016-12-17
-4wu8,2015-09-02,2014-10-31
-7wu5,2022-04-27,2022-02-05
-3wun,2015-05-27,2014-04-28
-6wuv,2021-02-17,2020-05-05
-3wul,2014-11-05,2014-04-28
-1wuy,2005-12-09,2004-12-09
-2wuw,2010-12-08,2009-10-09
-3wug,2014-10-29,2014-04-23
-2wu5,2010-08-25,2009-09-29
-6wuq,2020-12-09,2020-05-05
-7wum,2023-02-08,2022-02-08
-2wu6,2009-10-20,2009-09-30
-1wuu,2004-12-28,2004-12-08
-7wun,2023-02-08,2022-02-08
-6wug,2020-05-20,2020-05-04
-5wu6,2017-05-31,2016-12-16
-5wud,2017-06-21,2016-12-17
-6wuf,2020-05-20,2020-05-04
-3wuf,2014-10-29,2014-04-23
-2wul,2009-10-20,2009-10-06
-5wu3,2017-05-31,2016-12-16
-4wu2,2015-11-04,2014-10-30
-1wuk,2005-12-07,2004-12-07
-1wup,2005-03-29,2004-12-08
-7wue,2022-03-16,2022-02-08
-4wuv,2014-11-26,2014-11-03
-1wul,2005-12-07,2004-12-07
-7wu4,2022-04-27,2022-02-05
-5wu2,2017-05-31,2016-12-16
-7wub,2022-03-23,2022-02-08
-3wud,2015-04-08,2014-04-23
-2wu1,2009-10-06,2009-09-25
-6wu6,2021-02-03,2020-05-04
-4wuz,2014-11-19,2014-11-04
-4wup,2015-07-01,2014-11-03
-4wux,2016-02-10,2014-11-03
-1wuv,2006-04-18,2004-12-09
-1wun,2005-12-08,2004-12-08
-1wuq,2005-07-19,2004-12-08
-2wuu,2009-12-01,2009-10-09
-8wuw,2024-03-27,2023-10-21
-2wug,2009-10-20,2009-10-02
-3wu2,2014-09-03,2014-04-21
-6wud,2021-06-23,2020-05-04
-5wu0,2017-03-01,2016-12-15
-5wuq,2017-03-29,2016-12-20
-7wux,2022-09-07,2022-02-09
-4wuu,2015-12-30,2014-11-03
-1wub,2004-12-21,2004-12-03
-6wu8,2021-03-17,2020-05-04
-8wux,2024-03-27,2023-10-21
-8wuy,2024-01-24,2023-10-21
-6wuk,2020-05-20,2020-05-04
-6wu5,2021-06-23,2020-05-04
-6wua,2020-11-04,2020-05-04
-2wu2,2010-08-25,2009-09-28
-1wu1,2005-11-29,2004-11-29
-6wuz,2021-02-24,2020-05-05
-4wuq,2015-07-01,2014-11-03
-1wui,2005-12-07,2004-12-07
-2wub,2009-12-15,2009-10-01
-7wuh,2022-03-23,2022-02-08
-4wuo,2014-11-12,2014-11-03
-6wu7,2021-06-23,2020-05-04
-3wu7,2014-07-30,2014-04-23
-3wu9,2014-07-30,2014-04-23
-3wue,2014-10-29,2014-04-23
-3wub,2014-10-29,2014-04-23
-2wuf,2009-10-20,2009-10-02
-2wu3,2009-10-20,2009-09-28
-5wuu,2017-04-12,2016-12-21
-1wuj,2005-12-07,2004-12-07
-1wuo,2005-03-29,2004-12-08
-8wu1,2024-03-20,2023-10-19
-4wuj,2015-01-14,2014-10-31
-5wun,2017-01-25,2016-12-19
-4wuc,2015-04-08,2014-10-31
-3wum,2014-11-05,2014-04-28
-6wuy,2021-02-17,2020-05-05
-2cl5,2006-06-28,2006-04-26
-4clx,2015-01-21,2014-01-15
-5cls,2016-01-13,2015-07-16
-4cl2,2015-01-28,2014-01-11
-8clu,2024-02-21,2023-02-17
-2cl4,2006-06-06,2006-04-25
-6clr,2018-05-16,2018-03-02
-2cl7,2006-05-24,2006-04-26
-6cly,2019-03-06,2018-03-02
-2cl8,2007-05-15,2006-04-26
-1clm,1993-10-31,1993-01-23
-8clc,2023-12-13,2023-02-16
-5clw,2015-10-07,2015-07-16
-8cld,2023-12-13,2023-02-16
-2cl6,2006-05-24,2006-04-26
-3clr,2008-04-08,2008-03-20
-6clq,2018-05-16,2018-03-02
-1clu,1999-05-28,1999-05-03
-2cla,1990-07-15,1990-04-05
-4cls,2014-03-05,2014-01-15
-7cl1,2021-02-24,2020-07-20
-7cl0,2021-02-24,2020-07-20
-6clt,2018-05-16,2018-03-02
-5clc,2015-10-28,2015-07-16
-4cl3,2014-02-05,2014-01-11
-3cli,2008-08-19,2008-03-19
-8cl5,2023-12-13,2023-02-16
-6clf,2018-05-16,2018-03-02
-5cli,2016-07-27,2015-07-16
-7cl7,2021-07-21,2020-07-20
-7clt,2021-01-06,2020-07-22
-1cl4,1999-05-11,1999-05-06
-3cl5,2008-06-03,2008-03-18
-8clf,2023-12-13,2023-02-16
-4clz,2014-03-05,2014-01-15
-2clc,2006-05-24,2006-04-27
-1cll,1993-10-31,1992-09-29
-8clj,2023-06-21,2023-02-16
-7clh,2021-05-12,2020-07-21
-7cl8,2021-07-21,2020-07-20
-2clt,2006-08-09,2006-04-29
-3cln,1988-07-16,1988-05-11
-2clv,2006-06-14,2006-05-02
-3cl0,2008-05-20,2008-03-18
-4cln,1992-07-15,1991-06-24
-5cl9,2015-10-28,2015-07-16
-4cl1,2014-04-02,2014-01-10
-7cl4,2021-01-13,2020-07-20
-5clm,2015-09-30,2015-07-16
-4clh,2015-01-21,2014-01-14
-7cll,2021-07-28,2020-07-21
-2clu,2006-12-13,2006-05-02
-2cl0,2006-05-31,2006-04-25
-3clc,2008-07-29,2008-03-18
-6cle,2018-05-16,2018-03-02
-5cl1,2015-08-12,2015-07-16
-6cli,2018-05-16,2018-03-02
-6clh,2018-05-16,2018-03-02
-5cl8,2015-10-28,2015-07-16
-8cly,2023-08-09,2023-02-17
-5cle,2015-10-28,2015-07-16
-7cle,2021-11-10,2020-07-20
-8clg,2023-12-13,2023-02-16
-8clw,2024-02-28,2023-02-17
-6cln,2018-05-16,2018-03-02
-6cl0,2019-03-06,2018-03-01
-7clk,2022-01-26,2020-07-21
-5cl4,2015-10-28,2015-07-16
-4cl7,2015-01-28,2014-01-13
-8cl6,2023-12-13,2023-02-16
-7cl9,2021-07-21,2020-07-20
-5cl5,2015-10-28,2015-07-16
-7cl5,2021-01-13,2020-07-20
-5clj,2016-07-27,2015-07-16
-6clc,2018-05-16,2018-03-02
-3cl1,2008-08-05,2008-03-18
-6cll,2018-05-16,2018-03-02
-4cla,1992-01-15,1990-10-23
-5cla,2015-10-28,2015-07-16
-5clp,2016-07-27,2015-07-16
-5clk,2016-07-20,2015-07-16
-1clv,2000-05-03,1999-05-04
-1cl6,2000-03-22,1999-05-06
-7cl3,2021-01-13,2020-07-20
-7clj,2020-09-02,2020-07-21
-3clt,2008-04-08,2008-03-20
-8cll,2023-06-21,2023-02-16
-3clv,2008-07-15,2008-03-20
-3cly,2009-02-03,2008-03-20
-4cl8,2015-01-21,2014-01-13
-2cld,2006-05-31,2006-04-27
-8cle,2023-12-13,2023-02-16
-5cl6,2015-10-28,2015-07-16
-1cl2,1998-09-09,1997-09-04
-8clz,2023-08-09,2023-02-17
-2clq,2006-05-09,2006-04-28
-5clq,2015-09-09,2015-07-16
-4clk,2014-03-05,2014-01-15
-5cl7,2015-10-28,2015-07-16
-4clo,2015-01-21,2014-01-15
-3clu,2008-04-08,2008-03-20
-1clq,1999-10-28,1999-04-30
-5clt,2015-08-12,2015-07-16
-3cla,1990-10-15,1990-07-09
-3clh,2009-03-24,2008-03-19
-4cl9,2014-12-24,2014-01-13
-3cl4,2008-06-03,2008-03-18
-3cl2,2008-05-20,2008-03-18
-8cla,2024-02-28,2023-02-16
-3cl8,2008-06-10,2008-03-18
-8clv,2024-02-28,2023-02-17
-6cl5,2018-06-27,2018-03-01
-4clw,2014-03-05,2014-01-15
-6clp,2018-05-16,2018-03-02
-4clr,2015-01-21,2014-01-15
-6clj,2018-05-16,2018-03-02
-2clx,2006-11-01,2006-05-02
-2clz,2006-06-14,2006-05-03
-7clf,2021-07-28,2020-07-20
-4cli,2014-05-28,2014-01-14
-7cld,2021-07-07,2020-07-20
-5clo,2016-03-09,2015-07-16
-2clb,2006-07-17,2006-04-26
-8cli,2023-06-21,2023-02-16
-2clp,2006-05-12,2006-04-28
-8cl9,2023-12-13,2023-02-16
-6clv,2018-08-22,2018-03-02
-6clg,2018-05-16,2018-03-02
-6clk,2018-05-16,2018-03-02
-6clo,2018-05-16,2018-03-02
-2cl2,2006-10-25,2006-04-25
-6cl1,2019-03-06,2018-03-01
-4cld,2015-01-21,2014-01-14
-6cls,2018-05-16,2018-03-02
-3cls,2008-04-08,2008-03-20
-1cl0,1999-12-03,1999-05-04
-5cll,2015-09-09,2015-07-16
-3cl7,2008-06-10,2008-03-18
-3cld,2008-06-24,2008-03-18
-1clz,1996-08-01,1995-03-15
-4clv,2014-10-01,2014-01-15
-2cli,2007-06-12,2006-04-27
-5cl2,2015-12-16,2015-07-16
-7cl6,2021-01-13,2020-07-20
-1cld,1995-09-15,1995-06-06
-4clp,2014-03-05,2014-01-15
-3cl9,2009-01-06,2008-03-18
-5cl0,2016-03-16,2015-07-15
-4clu,2014-03-05,2014-01-15
-1cly,1996-08-01,1995-03-15
-1clc,1995-06-03,1995-01-19
-5clb,2015-10-28,2015-07-16
-1cle,1996-03-08,1995-02-08
-3clx,2008-10-28,2008-03-20
-6cld,2018-05-16,2018-03-02
-2clf,2007-06-26,2006-04-27
-8clq,2024-02-28,2023-02-17
-1cla,1990-07-15,1989-10-16
-3clp,2008-08-05,2008-03-19
-6clm,2018-05-16,2018-03-02
-6clx,2019-03-06,2018-03-02
-4clj,2014-05-28,2014-01-14
-4clt,2014-03-05,2014-01-15
-4cl6,2015-01-21,2014-01-13
-4cl0,2015-03-25,2014-01-10
-6cl2,2019-03-06,2018-03-01
-2cle,2007-06-12,2006-04-27
-8clh,2023-12-13,2023-02-16
-1clk,2000-05-03,1999-04-29
-5clu,2015-11-11,2015-07-16
-7cl2,2021-01-13,2020-07-20
-3clb,2009-01-06,2008-03-18
-1cls,1996-10-14,1995-08-29
-8clb,2023-12-13,2023-02-16
-2cls,2006-05-04,2006-04-28
-8cl8,2023-12-13,2023-02-16
-5cld,2015-10-28,2015-07-16
-1clx,1996-06-20,1995-08-31
-8cl7,2023-12-13,2023-02-16
-4cle,2015-01-21,2014-01-14
-2clm,2007-06-12,2006-04-28
-3clo,2008-04-01,2008-03-19
-4clm,2014-11-05,2014-01-15
-7clz,2020-10-07,2020-07-22
-2clh,2007-06-12,2006-04-27
-4clb,2014-12-24,2014-01-13
-2cll,2007-06-12,2006-04-28
-6clz,2018-12-12,2018-03-02
-2clk,2007-06-12,2006-04-27
-2clo,2007-06-12,2006-04-28
-6cl6,2018-06-27,2018-03-01
-1g17,2000-12-11,2000-10-10
-7g1s,2023-06-14,2023-04-27
-2g1l,2006-02-28,2006-02-14
-2g12,2006-07-04,2006-02-13
-2g1y,2006-06-13,2006-02-15
-1g16,2000-12-11,2000-10-10
-5g12,2016-12-07,2016-03-23
-2g1q,2006-10-03,2006-02-14
-5g1x,2016-11-16,2016-03-31
-5g1a,2017-04-12,2016-03-24
-5g1d,2016-11-23,2016-03-25
-2g11,2006-07-04,2006-02-13
-6g12,2018-11-07,2018-03-20
-1g1a,2001-03-21,2000-10-11
-7g15,2023-06-14,2023-04-27
-3g1r,2009-06-09,2009-01-30
-2g1s,2006-06-13,2006-02-14
-7g1r,2023-06-14,2023-04-27
-8g1n,2023-05-31,2023-02-02
-6g1i,2018-08-15,2018-03-21
-4g1h,2012-12-05,2012-07-10
-7g1e,2023-06-14,2023-04-27
-2g19,2006-06-13,2006-02-14
-7g1i,2023-06-14,2023-04-27
-2g1n,2006-06-13,2006-02-14
-1g1i,2001-01-10,2000-10-11
-7g17,2023-06-14,2023-04-27
-2g10,2006-07-04,2006-02-13
-6g1x,2018-11-21,2018-03-22
-5g1n,2016-06-22,2016-03-29
-2g1u,2006-03-28,2006-02-14
-2g1p,2006-11-21,2006-02-14
-2g1k,2006-07-18,2006-02-14
-7g1d,2023-06-14,2023-04-27
-6g1m,2019-03-27,2018-03-21
-8g1m,2024-02-14,2023-02-02
-6g1u,2018-04-04,2018-03-22
-6g1g,2018-08-15,2018-03-21
-3g1c,2009-02-17,2009-01-29
-4g1f,2013-02-27,2012-07-10
-7g1k,2023-06-14,2023-04-27
-6g1w,2018-04-04,2018-03-22
-4g1x,2012-09-05,2012-07-11
-3g1f,2009-06-23,2009-01-29
-8g10,2024-05-22,2023-02-01
-3g1x,2009-06-23,2009-01-30
-8g1z,2023-12-13,2023-02-03
-1g1d,2000-11-08,2000-10-11
-1g1f,2001-01-17,2000-10-11
-7g1t,2023-06-14,2023-04-27
-4g11,2012-11-14,2012-07-10
-6g1k,2018-05-02,2018-03-21
-7g1u,2023-06-14,2023-04-27
-5g1f,2017-03-08,2016-03-25
-4g16,2013-05-22,2012-07-10
-6g17,2018-08-29,2018-03-20
-6g1v,2018-04-04,2018-03-22
-3g1l,2009-07-21,2009-01-30
-1g1s,2001-10-13,2000-10-13
-6g1p,2018-11-28,2018-03-21
-1g1l,2000-12-27,2000-10-12
-8g18,2023-03-01,2023-02-01
-7g1z,2023-06-14,2023-04-27
-3g1z,2009-03-10,2009-01-30
-4g1z,2012-09-26,2012-07-11
-6g19,2018-11-21,2018-03-20
-4g1e,2012-12-12,2012-07-10
-4g1y,2012-09-26,2012-07-11
-7g1h,2023-06-14,2023-04-27
-6g18,2018-06-06,2018-03-20
-3g19,2009-04-28,2009-01-29
-7g16,2023-06-14,2023-04-27
-7g1c,2023-06-14,2023-04-27
-7g1w,2023-06-14,2023-04-27
-8g1q,2023-07-26,2023-02-02
-6g1b,2018-12-05,2018-03-21
-4g1d,2012-09-26,2012-07-10
-1g1t,2001-10-13,2000-10-13
-2g1a,2007-04-24,2006-02-14
-3g1t,2009-02-10,2009-01-30
-7g1j,2023-06-14,2023-04-27
-3g1p,2009-03-03,2009-01-30
-7g14,2023-06-14,2023-04-27
-7g18,2023-06-14,2023-04-27
-7g13,2023-06-14,2023-04-27
-3g1o,2009-07-21,2009-01-30
-4g10,2012-10-03,2012-07-10
-6g1y,2018-11-28,2018-03-22
-3g1v,2009-06-23,2009-01-30
-4g19,2012-09-26,2012-07-10
-4g1a,2012-12-05,2012-07-10
-4g1m,2012-12-12,2012-07-10
-2g18,2006-12-26,2006-02-13
-7g11,2023-06-14,2023-04-27
-6g13,2019-02-27,2018-03-20
-1g18,2000-12-11,2000-10-11
-8g1s,2023-06-21,2023-02-02
-3g1n,2009-02-17,2009-01-30
-1g1h,2001-01-17,2000-10-11
-5g18,2016-11-09,2016-03-23
-4g17,2013-05-22,2012-07-10
-1g1y,2001-03-14,2000-10-16
-4g1w,2013-07-17,2012-07-11
-7g12,2023-06-14,2023-04-27
-1g15,2001-03-14,2000-10-10
-3g13,2009-02-10,2009-01-29
-7g1m,2023-06-14,2023-04-27
-3g1m,2009-07-21,2009-01-30
-5g10,2016-11-30,2016-03-23
-5g13,2016-12-07,2016-03-23
-3g1a,2009-06-23,2009-01-29
-7g1o,2023-06-14,2023-04-27
-1g1j,2001-01-10,2000-10-11
-3g10,2009-03-31,2009-01-29
-8g1w,2024-02-07,2023-02-03
-7g19,2023-06-14,2023-04-27
-5g17,2017-04-12,2016-03-23
-7g1q,2023-06-14,2023-04-27
-2g1t,2006-05-23,2006-02-14
-5g15,2018-03-14,2016-03-23
-3g1d,2009-06-23,2009-01-29
-3g1b,2009-04-28,2009-01-29
-8g1l,2024-02-14,2023-02-02
-4g1q,2013-02-06,2012-07-11
-6g1e,2019-04-10,2018-03-21
-4g1k,2012-07-25,2012-07-10
-5g1u,2017-01-11,2016-03-30
-1g12,2001-03-14,2000-10-10
-6g1h,2019-03-27,2018-03-21
-2g1r,2006-06-13,2006-02-14
-8g1e,2023-05-10,2023-02-02
-3g1q,2009-10-06,2009-01-30
-8g1u,2023-08-23,2023-02-03
-3g11,2009-03-17,2009-01-29
-5g1c,2016-11-23,2016-03-24
-6g1o,2018-08-01,2018-03-21
-7g1n,2023-06-14,2023-04-27
-7g1f,2023-06-14,2023-04-27
-5g1w,2017-01-11,2016-03-30
-5g11,2016-11-30,2016-03-23
-3g1h,2009-06-23,2009-01-29
-2g1o,2006-06-13,2006-02-14
-8g1y,2023-02-15,2023-02-03
-1g1r,2001-10-13,2000-10-13
-7g10,2023-06-14,2023-04-27
-7g1g,2023-06-14,2023-04-27
-4g1c,2012-08-15,2012-07-10
-3g1u,2009-02-10,2009-01-30
-8g1j,2024-05-22,2023-02-02
-6g1q,2018-11-28,2018-03-21
-6g14,2018-11-07,2018-03-20
-4g1p,2013-07-17,2012-07-11
-5g1z,2017-02-15,2016-04-06
-1g1q,2001-10-13,2000-10-13
-2g14,2006-07-04,2006-02-13
-2g1m,2006-06-13,2006-02-14
-7g1v,2023-06-14,2023-04-27
-3g1k,2010-03-09,2009-01-30
-7g1l,2023-06-14,2023-04-27
-8g1f,2023-05-10,2023-02-02
-6g1s,2018-11-21,2018-03-21
-1g1g,2001-01-17,2000-10-11
-5g1b,2017-04-12,2016-03-24
-4g1v,2012-11-14,2012-07-11
-7g1y,2023-06-14,2023-04-27
-7g1b,2023-06-14,2023-04-27
-7g1a,2023-06-14,2023-04-27
-4g1r,2013-07-17,2012-07-11
-8g1p,2023-07-26,2023-02-02
-4g1b,2012-11-14,2012-07-10
-6g1d,2018-12-05,2018-03-21
-6g1z,2018-11-28,2018-03-22
-6g15,2018-11-07,2018-03-20
-7g1p,2023-06-14,2023-04-27
-8g1a,2023-07-05,2023-02-01
-6g1j,2019-04-10,2018-03-21
-4g1n,2012-10-10,2012-07-10
-2opg,2007-02-13,2007-01-29
-2opq,2007-05-22,2007-01-30
-6opn,2020-10-21,2019-04-25
-7opm,2022-02-02,2021-06-01
-5opr,2017-10-25,2017-08-10
-5op6,2017-10-18,2017-08-09
-6ope,2020-06-24,2019-04-24
-7opw,2022-06-08,2021-06-01
-2op0,2007-07-17,2007-01-26
-2opo,2007-02-06,2007-01-29
-1opk,2003-04-08,2003-03-06
-1opm,1999-09-29,1999-05-25
-7op7,2022-02-02,2021-05-29
-3op2,2010-09-15,2010-08-31
-6opu,2019-09-04,2019-04-25
-1opl,2003-04-08,2003-03-06
-3opr,2011-07-13,2010-09-01
-6op6,2019-10-23,2019-04-24
-5opc,2017-10-18,2017-08-09
-2opp,2007-05-22,2007-01-30
-8ope,2024-01-24,2023-04-07
-3op5,2010-09-22,2010-08-31
-3opq,2010-11-17,2010-09-01
-3opz,2011-11-09,2010-09-02
-4opp,2014-03-05,2014-02-06
-6opo,2020-10-21,2019-04-25
-5opm,2018-06-13,2017-08-10
-5opp,2018-06-13,2017-08-10
-7ops,2021-07-21,2021-06-01
-1opb,1993-10-31,1992-12-09
-6opa,2020-04-01,2019-04-24
-1op0,2004-05-25,2003-03-04
-1opr,1996-01-06,1995-01-06
-7opk,2022-07-06,2021-06-01
-3opm,2011-10-19,2010-09-01
-6opi,2019-07-31,2019-04-25
-7opd,2021-10-06,2021-05-31
-4op1,2014-07-30,2014-02-04
-6opy,2019-09-04,2019-04-25
-3opo,2011-04-27,2010-09-01
-5opg,2017-08-23,2017-08-09
-2ops,2007-05-22,2007-01-30
-7opc,2021-10-13,2021-05-31
-7op0,2022-04-06,2021-05-28
-2opm,2007-12-11,2007-01-29
-5opa,2018-03-28,2017-08-09
-4op9,2014-03-19,2014-02-05
-7op5,2021-06-30,2021-05-29
-7opj,2021-07-14,2021-05-31
-8opr,2023-11-08,2023-04-07
-5opd,2018-08-29,2017-08-09
-6opw,2019-09-04,2019-04-25
-1op2,2004-05-25,2003-03-04
-4opd,2014-07-09,2014-02-05
-7opa,2022-05-04,2021-05-31
-6opt,2019-09-04,2019-04-25
-5opb,2017-10-25,2017-08-09
-2op3,2007-05-22,2007-01-26
-5opu,2017-10-25,2017-08-10
-3opd,2010-10-13,2010-08-31
-7op2,2021-06-23,2021-05-28
-3oph,2011-07-13,2010-09-01
-2opa,2008-02-05,2007-01-28
-7op9,2022-05-04,2021-05-31
-7op6,2022-05-18,2021-05-29
-5opz,2018-01-17,2017-08-10
-7opy,2022-02-16,2021-06-02
-5op2,2017-10-25,2017-08-09
-5op8,2017-10-18,2017-08-09
-8opn,2023-08-02,2023-04-07
-6opg,2019-07-31,2019-04-25
-6opq,2020-10-21,2019-04-25
-2opz,2007-02-20,2007-01-30
-7opq,2022-04-06,2021-06-01
-8op9,2023-08-30,2023-04-06
-5op3,2018-08-29,2017-08-09
-8op1,2023-09-27,2023-04-06
-7op8,2021-06-30,2021-05-31
-2opx,2007-02-20,2007-01-30
-2opn,2007-10-02,2007-01-29
-4op0,2014-04-30,2014-02-04
-7opl,2021-11-10,2021-06-01
-4op5,2015-05-20,2014-02-05
-4opg,2014-07-09,2014-02-05
-3ope,2011-01-12,2010-08-31
-2opc,2007-03-06,2007-01-29
-6op9,2019-08-21,2019-04-24
-6op7,2019-10-23,2019-04-24
-4opb,2015-01-28,2014-02-05
-2oph,2007-05-08,2007-01-29
-7opi,2021-08-04,2021-05-31
-1opj,2003-04-08,2003-03-06
-5opl,2018-06-13,2017-08-10
-4opc,2014-07-09,2014-02-05
-8opx,2024-01-24,2023-04-10
-3ops,2010-09-15,2010-09-01
-6opx,2019-09-04,2019-04-25
-8opu,2024-01-24,2023-04-10
-7opt,2022-06-08,2021-06-01
-5op9,2018-03-28,2017-08-09
-8opv,2024-01-24,2023-04-10
-6opz,2019-09-04,2019-04-25
-4opx,2014-07-02,2014-02-06
-5opf,2017-12-13,2017-08-09
-4opq,2015-05-20,2014-02-06
-4op2,2014-07-30,2014-02-04
-7opr,2022-04-06,2021-06-01
-3opu,2011-01-19,2010-09-02
-3opl,2011-07-13,2010-09-01
-4opl,2014-07-09,2014-02-05
-3op0,2010-10-20,2010-08-31
-1ope,2004-04-27,2003-03-05
-2op9,2007-07-17,2007-01-27
-6opk,2019-07-31,2019-04-25
-5opj,2018-02-28,2017-08-10
-7opp,2022-04-06,2021-06-01
-6op5,2019-06-12,2019-04-24
-7oph,2022-06-08,2021-05-31
-2opy,2007-02-20,2007-01-30
-4op3,2014-07-30,2014-02-04
-3opx,2011-03-02,2010-09-02
-8opl,2024-01-24,2023-04-07
-4opy,2015-05-20,2014-02-07
-8opc,2024-01-24,2023-04-07
-2opb,2007-10-09,2007-01-28
-3opk,2010-10-06,2010-09-01
-3opy,2010-10-06,2010-09-02
-6opv,2019-09-04,2019-04-25
-4opi,2014-07-09,2014-02-05
-4opn,2015-02-11,2014-02-06
-5opk,2018-06-13,2017-08-10
-8opy,2024-01-24,2023-04-10
-4opr,2015-05-20,2014-02-06
-4opt,2014-07-09,2014-02-06
-5op5,2017-10-25,2017-08-09
-5op4,2017-10-25,2017-08-09
-5op7,2017-10-25,2017-08-09
-5ops,2017-10-25,2017-08-10
-7op1,2021-06-30,2021-05-28
-6opj,2020-09-02,2019-04-25
-6oph,2019-07-31,2019-04-25
-1opo,2003-04-01,2003-03-06
-6ops,2019-09-04,2019-04-25
-6op0,2019-12-25,2019-04-23
-6opl,2020-04-29,2019-04-25
-6opm,2020-02-12,2019-04-25
-2op1,2007-07-17,2007-01-26
-5opv,2017-10-25,2017-08-10
-8opm,2023-08-02,2023-04-07
-4op7,2014-12-17,2014-02-05
-7opn,2021-09-01,2021-06-01
-3opt,2010-12-22,2010-09-02
-6opc,2019-07-10,2019-04-24
-7opo,2022-02-02,2021-06-01
-6opd,2019-09-04,2019-04-24
-6op8,2019-08-07,2019-04-24
-6opp,2020-10-21,2019-04-25
-7opz,2022-02-16,2021-06-02
-2opr,2007-05-22,2007-01-30
-3opp,2011-07-13,2010-09-01
-4opo,2014-12-17,2014-02-06
-5opx,2018-01-10,2017-08-10
-3op4,2010-09-22,2010-08-31
-4op8,2015-05-20,2014-02-05
-2opf,2008-02-26,2007-01-29
-2opl,2007-02-13,2007-01-29
-4opz,2015-05-20,2014-02-07
-4op6,2014-03-19,2014-02-05
-4op4,2014-04-23,2014-02-04
-5opo,2018-06-13,2017-08-10
-8opo,2023-08-02,2023-04-07
-4opu,2014-07-09,2014-02-06
-7opg,2021-07-21,2021-05-31
-4ops,2014-12-17,2014-02-06
-8opw,2024-01-24,2023-04-10
-3m85,2010-04-28,2010-03-17
-7m8x,2021-06-30,2021-03-30
-4m8e,2014-01-22,2013-08-13
-4m84,2013-10-02,2013-08-12
-7m8b,2021-06-02,2021-03-29
-3m8z,2010-12-29,2010-03-19
-1m8x,2002-09-25,2002-07-26
-5m8h,2017-09-06,2016-10-28
-5m81,2017-12-20,2016-10-28
-3m8p,2010-05-19,2010-03-18
-6m8y,2018-10-24,2018-08-22
-6m8u,2020-02-26,2018-08-22
-5m8o,2017-07-12,2016-10-29
-4m87,2013-10-02,2013-08-13
-3m82,2010-05-26,2010-03-17
-6m84,2019-09-04,2018-08-21
-5m8i,2017-10-11,2016-10-28
-6m89,2019-01-23,2018-08-21
-7m8m,2021-06-30,2021-03-30
-5m8g,2017-02-22,2016-10-28
-6m83,2019-03-13,2018-08-21
-7m83,2021-06-02,2021-03-29
-5m8m,2017-07-12,2016-10-29
-7m8h,2022-04-06,2021-03-29
-2m85,2013-08-14,2013-05-07
-6m8q,2019-11-27,2018-08-22
-5m8n,2017-07-12,2016-10-29
-7m8k,2021-05-05,2021-03-29
-7m86,2021-06-02,2021-03-29
-6m87,2019-07-03,2018-08-21
-4m83,2013-09-11,2013-08-12
-1m8f,2003-07-15,2002-07-24
-6m8d,2019-01-23,2018-08-21
-4m82,2014-06-25,2013-08-12
-1m8e,2002-08-07,2002-07-24
-1m8r,2003-02-11,2002-07-25
-4m8l,2013-10-02,2013-08-13
-5m8u,2017-07-12,2016-10-30
-5m86,2017-06-14,2016-10-28
-4m8u,2013-09-25,2013-08-13
-5m8e,2017-05-10,2016-10-28
-7m8l,2021-11-10,2021-03-30
-5m8t,2017-07-12,2016-10-29
-4m8y,2014-05-07,2013-08-14
-3m8c,2010-04-14,2010-03-17
-7m84,2021-06-02,2021-03-29
-6m8w,2018-10-24,2018-08-22
-4m89,2013-10-02,2013-08-13
-1m8d,2002-08-14,2002-07-24
-5m8d,2017-03-22,2016-10-28
-7m81,2021-06-02,2021-03-29
-4m8x,2014-05-07,2013-08-14
-6m8r,2019-02-27,2018-08-22
-1m8s,2003-02-11,2002-07-25
-3m8q,2010-05-19,2010-03-18
-2m8d,2013-07-10,2013-05-17
-3m8b,2010-09-15,2010-03-17
-6m8b,2019-01-23,2018-08-21
-5m8y,2017-07-12,2016-10-30
-5m8r,2017-07-12,2016-10-29
-3m8w,2010-12-29,2010-03-19
-1m8k,2003-07-15,2002-07-25
-4m81,2014-06-25,2013-08-12
-3m8s,2010-07-07,2010-03-19
-1m8g,2003-07-15,2002-07-24
-5m84,2017-12-20,2016-10-28
-6m8t,2020-02-26,2018-08-22
-7m8t,2021-06-23,2021-03-30
-1m85,2002-08-14,2002-07-24
-7m82,2021-06-02,2021-03-29
-3m8d,2010-09-15,2010-03-17
-3m89,2010-07-07,2010-03-17
-6m8h,2019-08-21,2018-08-21
-7m8v,2021-06-16,2021-03-30
-7m8w,2021-08-25,2021-03-30
-4m8t,2014-10-22,2013-08-13
-7m8i,2021-05-26,2021-03-29
-4m8h,2014-01-22,2013-08-13
-1m8h,2002-08-07,2002-07-24
-3m8y,2010-12-29,2010-03-19
-3m8u,2010-07-14,2010-03-19
-1m8v,2003-02-11,2002-07-26
-6m8m,2019-09-04,2018-08-22
-7m89,2021-06-02,2021-03-29
-1m8i,2002-08-07,2002-07-24
-7m8a,2021-06-02,2021-03-29
-5m8q,2017-07-12,2016-10-29
-4m8n,2013-10-09,2013-08-13
-3m84,2010-07-14,2010-03-17
-7m8r,2021-07-28,2021-03-30
-7m8e,2021-08-18,2021-03-29
-7m80,2021-06-02,2021-03-29
-3m8r,2010-07-07,2010-03-19
-1m83,2002-12-18,2002-07-24
-4m8o,2013-11-27,2013-08-13
-6m8f,2019-01-23,2018-08-21
-7m8z,2021-06-30,2021-03-30
-7m8o,2021-06-30,2021-03-30
-4m8i,2013-09-04,2013-08-13
-7m8p,2021-06-30,2021-03-30
-6m8a,2019-01-23,2018-08-21
-5m8x,2017-07-12,2016-10-30
-6m81,2019-03-13,2018-08-21
-5m80,2017-12-20,2016-10-28
-7m88,2021-06-02,2021-03-29
-7m8q,2021-07-28,2021-03-30
-5m8w,2017-07-12,2016-10-30
-6m88,2019-01-23,2018-08-21
-6m8p,2019-12-18,2018-08-22
-3m8m,2010-04-14,2010-03-18
-5m85,2017-12-20,2016-10-28
-5m8b,2017-05-10,2016-10-28
-7m8y,2021-06-30,2021-03-30
-6m82,2019-03-13,2018-08-21
-3m81,2010-04-21,2010-03-17
-4m8d,2014-06-18,2013-08-13
-6m8v,2020-02-26,2018-08-22
-7m8n,2021-06-30,2021-03-30
-6m8c,2019-01-23,2018-08-21
-1m8p,2002-11-27,2002-07-25
-7m85,2021-06-02,2021-03-29
-5m87,2017-01-11,2016-10-28
-7m8c,2021-06-02,2021-03-29
-5m82,2017-12-20,2016-10-28
-7m8u,2021-06-23,2021-03-30
-5m8s,2018-01-31,2016-10-29
-6m86,2019-09-04,2018-08-21
-4m8j,2013-10-09,2013-08-13
-5m83,2017-12-20,2016-10-28
-6m8n,2018-10-03,2018-08-22
-1m8t,2003-09-02,2002-07-26
-6m85,2019-09-04,2018-08-21
-6m8e,2019-01-23,2018-08-21
-1m8j,2003-07-15,2002-07-25
-5m8l,2017-07-12,2016-10-29
-5m8p,2017-07-12,2016-10-29
-7m87,2021-06-02,2021-03-29
-3m83,2010-05-12,2010-03-17
-5m8z,2017-07-12,2016-10-30
-3m8a,2010-04-28,2010-03-17
-7m8d,2021-06-02,2021-03-29
-1m8w,2002-09-25,2002-07-26
-4wxx,2015-07-15,2014-11-14
-1wx1,2005-02-01,2005-01-19
-1wxg,2005-02-15,2005-01-23
-4wxi,2015-01-28,2014-11-13
-2wxi,2010-01-12,2009-11-09
-7wx5,2023-02-22,2022-02-14
-2wxv,2010-02-23,2009-11-10
-6wxu,2020-09-02,2020-05-12
-6wxp,2020-11-25,2020-05-11
-3wxy,2015-01-14,2014-08-13
-5wx2,2018-01-17,2017-01-06
-5wxp,2018-07-11,2017-01-08
-6wxk,2020-07-15,2020-05-11
-5wxb,2017-05-17,2017-01-07
-1wxo,2005-07-26,2005-01-27
-4wxw,2015-11-18,2014-11-14
-2wxd,2010-02-09,2009-11-09
-5wx6,2017-04-26,2017-01-06
-6wxr,2020-09-02,2020-05-11
-1wxi,2005-02-15,2005-01-23
-4wxq,2015-04-01,2014-11-14
-4wxl,2015-11-18,2014-11-14
-4wxe,2014-11-26,2014-11-13
-7wx3,2022-04-06,2022-02-14
-4wxh,2015-07-29,2014-11-13
-7wx6,2022-09-14,2022-02-14
-5wxh,2017-08-16,2017-01-07
-6wxa,2021-05-12,2020-05-10
-2wxj,2010-01-12,2009-11-09
-2wxm,2010-01-12,2009-11-09
-6wxv,2020-09-02,2020-05-12
-2wxq,2010-01-12,2009-11-09
-7wxp,2022-08-10,2022-02-15
-8wx4,2023-12-13,2023-10-27
-5wxr,2018-07-11,2017-01-08
-6wxb,2020-05-20,2020-05-10
-7wxx,2022-10-05,2022-02-15
-7wxi,2022-03-30,2022-02-14
-1wx5,2006-01-31,2005-01-19
-3wxo,2015-01-21,2014-08-04
-5wxk,2018-02-28,2017-01-07
-4wxj,2015-04-29,2014-11-13
-3wxj,2014-12-31,2014-08-01
-6wxl,2021-06-09,2020-05-11
-2wxp,2010-01-12,2009-11-09
-1wxh,2005-02-15,2005-01-23
-4wx6,2015-01-14,2014-11-13
-6wx4,2020-05-20,2020-05-09
-2wxy,2010-10-20,2009-11-11
-2wx5,2010-02-09,2009-11-02
-7wxg,2022-03-30,2022-02-14
-5wxu,2018-05-23,2017-01-09
-5wxf,2018-07-11,2017-01-07
-3wxb,2015-07-29,2014-07-29
-4wxp,2015-12-23,2014-11-14
-6wx6,2020-05-20,2020-05-09
-3wxm,2014-09-03,2014-08-04
-6wx2,2021-03-17,2020-05-09
-5wxg,2017-08-16,2017-01-07
-5wxz,2018-01-17,2017-01-09
-4wxu,2015-04-01,2014-11-14
-2wx9,2011-01-26,2009-11-05
-1wxy,2005-08-16,2005-02-02
-1wxz,2005-08-16,2005-02-02
-2wxt,2009-11-17,2009-11-10
-6wxg,2021-01-20,2020-05-10
-4wx4,2015-01-14,2014-11-13
-3wx1,2014-08-06,2014-07-10
-5wxo,2018-07-11,2017-01-08
-3wxt,2014-11-05,2014-08-08
-2wxh,2010-01-12,2009-11-09
-1wx2,2006-01-31,2005-01-19
-3wxl,2014-12-24,2014-08-01
-4wx0,2014-12-24,2014-11-13
-1wxj,2005-02-01,2005-01-24
-3wx9,2014-09-24,2014-07-28
-6wxe,2021-01-20,2020-05-10
-4wx2,2015-11-18,2014-11-13
-8wxe,2024-05-08,2023-10-28
-4wxs,2015-04-01,2014-11-14
-6wxz,2020-10-14,2020-05-12
-5wx7,2017-04-26,2017-01-06
-5wxi,2018-02-28,2017-01-07
-4wxg,2015-02-04,2014-11-13
-2wxf,2010-01-12,2009-11-09
-5wx3,2017-04-26,2017-01-06
-3wxx,2015-10-14,2014-08-12
-7wx2,2022-06-08,2022-02-14
-2wxn,2010-01-12,2009-11-09
-3wxc,2014-10-15,2014-07-29
-6wxf,2021-01-20,2020-05-10
-6wxx,2020-12-30,2020-05-12
-4wxv,2015-07-22,2014-11-14
-3wxp,2015-11-18,2014-08-04
-3wx7,2014-12-03,2014-07-18
-2wxg,2010-01-12,2009-11-09
-6wx5,2021-02-10,2020-05-09
-6wx3,2021-03-10,2020-05-09
-2wxl,2010-01-12,2009-11-09
-2wxu,2009-11-17,2009-11-10
-4wxk,2015-11-18,2014-11-14
-7wx0,2023-02-15,2022-02-14
-3wx2,2014-08-06,2014-07-10
-6wxn,2021-05-19,2020-05-11
-7wxs,2023-02-22,2022-02-15
-5wxt,2018-07-11,2017-01-08
-1wx4,2006-01-31,2005-01-19
-7wx7,2023-02-22,2022-02-14
-1wxx,2005-08-02,2005-02-02
-6wxy,2020-12-30,2020-05-12
-4wxf,2015-02-04,2014-11-13
-4wx1,2014-12-03,2014-11-13
-2wx1,2009-11-24,2009-10-30
-2wxo,2010-01-12,2009-11-09
-3wxa,2015-03-11,2014-07-29
-6wxc,2020-05-20,2020-05-10
-2wx2,2009-11-10,2009-10-31
-2wxk,2010-01-12,2009-11-09
-1wxe,2005-02-15,2005-01-23
-5wxc,2018-01-17,2017-01-07
-8wxy,2024-01-24,2023-10-30
-2wx0,2009-11-24,2009-10-30
-7wx1,2023-02-15,2022-02-14
-4wxr,2015-12-23,2014-11-14
-4wxb,2015-02-04,2014-11-13
-5wxy,2018-01-17,2017-01-09
-5wxs,2018-07-11,2017-01-08
-3wxu,2014-11-05,2014-08-08
-4wx7,2015-01-14,2014-11-13
-6wxj,2021-02-10,2020-05-10
-5wxq,2018-07-11,2017-01-08
-6wxq,2021-11-17,2020-05-11
-1x7q,2005-08-02,2004-08-16
-7x7w,2022-09-07,2022-03-10
-4x7y,2015-03-04,2014-12-09
-4x7f,2014-12-31,2014-12-09
-6x7x,2021-06-02,2020-05-31
-6x7f,2020-09-02,2020-05-29
-6x7h,2021-06-02,2020-05-30
-4x7n,2015-01-28,2014-12-09
-1x7p,2005-01-25,2004-08-16
-2x7j,2010-07-14,2010-03-01
-7x75,2022-08-03,2022-03-09
-6x73,2020-09-30,2020-05-29
-2x7r,2010-05-26,2010-03-03
-8x7u,2024-01-17,2023-11-25
-2x7b,2010-07-21,2010-02-25
-4x7o,2015-01-28,2014-12-09
-1x7z,2004-11-23,2004-08-16
-6x7o,2020-06-10,2020-05-30
-5x7z,2017-08-09,2017-02-28
-1x70,2005-01-18,2004-08-12
-4x71,2015-06-10,2014-12-09
-6x7j,2021-06-02,2020-05-30
-7x76,2022-08-03,2022-03-09
-7x7u,2022-08-17,2022-03-10
-6x7a,2021-06-02,2020-05-29
-1x7d,2004-11-09,2004-08-13
-8x79,2024-03-06,2023-11-23
-8x70,2023-12-27,2023-11-22
-1x7x,2004-11-23,2004-08-16
-1x7e,2005-03-01,2004-08-13
-4x7q,2015-02-11,2014-12-09
-2x7e,2010-07-14,2010-02-26
-1x7b,2005-03-01,2004-08-13
-2x7h,2010-12-08,2010-02-26
-4x7m,2015-03-04,2014-12-09
-6x7p,2020-06-10,2020-05-30
-4x7w,2015-03-04,2014-12-09
-5x73,2017-10-04,2017-02-23
-2x71,2010-07-14,2010-02-22
-7x7n,2022-04-27,2022-03-10
-4x7h,2015-02-04,2014-12-09
-1x7i,2005-03-01,2004-08-14
-5x7s,2017-07-26,2017-02-27
-6x74,2020-09-30,2020-05-29
-1x7h,2004-12-14,2004-08-13
-7x78,2022-04-13,2022-03-09
-7x74,2022-08-03,2022-03-09
-2x7g,2010-04-14,2010-02-26
-5x7p,2017-07-26,2017-02-27
-5x7r,2017-07-26,2017-02-27
-6x7v,2020-07-01,2020-05-30
-7x7v,2022-08-17,2022-03-10
-2x77,2010-03-02,2010-02-24
-7x7j,2023-01-18,2022-03-09
-1x7n,2004-10-12,2004-08-16
-7x7t,2022-08-17,2022-03-10
-2x7p,2011-03-16,2010-03-03
-6x77,2020-09-30,2020-05-29
-5x74,2017-10-04,2017-02-23
-2x7a,2010-04-28,2010-02-25
-7x79,2023-06-14,2022-03-09
-7x7k,2023-01-18,2022-03-09
-5x7b,2017-09-13,2017-02-24
-4x7k,2015-01-28,2014-12-09
-7x70,2022-08-10,2022-03-08
-2x7m,2010-06-09,2010-03-01
-6x7r,2021-06-02,2020-05-30
-6x75,2020-09-30,2020-05-29
-2x7d,2010-07-14,2010-02-26
-5x7g,2017-04-26,2017-02-26
-6x70,2020-09-30,2020-05-29
-6x7b,2020-08-05,2020-05-29
-6x76,2020-09-30,2020-05-29
-7x73,2022-12-21,2022-03-09
-2x7s,2010-03-31,2010-03-03
-2x75,2010-03-09,2010-02-23
-4x7j,2015-01-28,2014-12-09
-5x7q,2017-07-26,2017-02-27
-6x72,2020-09-30,2020-05-29
-1x7y,2004-11-23,2004-08-16
-4x7z,2015-03-04,2014-12-09
-5x7m,2018-01-10,2017-02-27
-4x7i,2014-12-24,2014-12-09
-1x77,2004-08-24,2004-08-13
-5x7u,2018-02-28,2017-02-27
-5x7h,2017-04-26,2017-02-26
-8x7a,2024-03-06,2023-11-23
-6x7w,2021-06-02,2020-05-30
-5x70,2018-02-28,2017-02-23
-2x7y,2011-03-23,2010-03-04
-5x7f,2017-03-29,2017-02-25
-6x7m,2020-06-10,2020-05-30
-2x7w,2010-09-08,2010-03-03
-5x71,2018-02-28,2017-02-23
-5x72,2017-10-04,2017-02-23
-8x72,2023-12-27,2023-11-22
-7x7x,2022-09-07,2022-03-10
-1x7r,2005-03-01,2004-08-16
-2x7f,2010-07-14,2010-02-26
-5x7x,2017-04-19,2017-02-27
-2x7q,2011-03-23,2010-03-03
-6x7n,2020-06-10,2020-05-30
-5x79,2017-09-13,2017-02-24
-2x76,2010-06-09,2010-02-24
-7x7l,2022-06-01,2022-03-09
-7x72,2023-08-16,2022-03-08
-2x7c,2010-07-14,2010-02-26
-6x7k,2020-09-02,2020-05-30
-6x71,2020-09-30,2020-05-29
-6x78,2021-06-02,2020-05-29
-1x71,2005-01-18,2004-08-12
-6x7q,2021-06-02,2020-05-30
-6x79,2020-08-19,2020-05-29
-4x7b,2015-06-10,2014-12-09
-6x7u,2020-07-01,2020-05-30
-5x7o,2017-07-26,2017-02-27
-1x7g,2004-12-14,2004-08-13
-4x7x,2015-03-11,2014-12-09
-7x7a,2022-11-16,2022-03-09
-5x7d,2017-08-16,2017-02-25
-6x7d,2020-08-05,2020-05-29
-4x7v,2015-03-04,2014-12-09
-6x7c,2020-08-05,2020-05-29
-6x7t,2021-06-02,2020-05-30
-2x7o,2010-10-20,2010-03-03
-2x7x,2010-07-21,2010-03-04
-2x7t,2010-03-31,2010-03-03
-6x7z,2021-06-02,2020-06-01
-1x76,2005-03-01,2004-08-13
-2x7v,2010-09-08,2010-03-03
-7x7h,2023-03-15,2022-03-09
-1x78,2005-03-01,2004-08-13
-4x7u,2015-03-04,2014-12-09
-2x70,2010-12-08,2010-02-22
-7x7i,2023-01-18,2022-03-09
-5x7j,2018-03-07,2017-02-27
-1x7a,2005-08-16,2004-08-13
-5x7n,2018-01-10,2017-02-27
-2x72,2011-03-16,2010-02-22
-8x77,2024-05-29,2023-11-23
-6x7e,2020-09-16,2020-05-29
-4x7g,2016-01-20,2014-12-09
-6x7l,2020-06-10,2020-05-30
-7x7r,2022-11-16,2022-03-10
-6x7y,2021-06-02,2020-05-31
-5x7e,2017-05-10,2017-02-25
-1x7w,2004-11-23,2004-08-16
-4x7l,2015-01-28,2014-12-09
-1x7j,2005-03-01,2004-08-14
-2x7u,2010-03-31,2010-03-03
-3f0e,2008-11-04,2008-10-24
-7f0u,2021-10-20,2021-06-07
-1f0y,2000-09-01,2000-05-17
-3f0m,2009-10-13,2008-10-25
-4f0o,2013-05-08,2012-05-04
-7f08,2022-06-15,2021-06-03
-3f0x,2009-10-06,2008-10-27
-8f0r,2023-04-12,2022-11-03
-1f0r,2000-09-20,2000-05-17
-7f0v,2022-06-15,2021-06-07
-3f0b,2009-03-24,2008-10-24
-4f06,2012-08-15,2012-05-03
-7f03,2022-11-09,2021-06-03
-7f0w,2021-06-23,2021-06-07
-8f07,2023-03-15,2022-11-01
-8f0b,2023-03-15,2022-11-02
-8f0s,2023-04-12,2022-11-03
-1f0x,2000-08-23,2000-05-17
-2f03,2007-01-16,2005-11-11
-6f02,2018-12-12,2017-11-17
-6f0u,2018-01-10,2017-11-20
-4f0e,2012-09-05,2012-05-04
-2f0z,2006-11-21,2005-11-14
-5f02,2016-02-24,2015-11-27
-3f03,2008-12-16,2008-10-24
-4f0x,2013-03-20,2012-05-05
-8f0i,2023-09-13,2022-11-03
-1f0s,2000-09-20,2000-05-17
-5f0g,2017-04-05,2015-11-27
-4f0k,2012-11-14,2012-05-04
-6f08,2018-02-14,2017-11-17
-4f02,2012-08-08,2012-05-03
-1f0u,2000-09-20,2000-05-17
-2f02,2005-11-22,2005-11-10
-5f05,2016-12-07,2015-11-27
-9f0g,2024-04-24,2024-04-16
-3f00,2009-09-08,2008-10-24
-5f0q,2016-03-23,2015-11-28
-1f0j,2000-07-26,2000-05-16
-5f0f,2016-02-03,2015-11-27
-5f0c,2016-02-03,2015-11-27
-5f01,2016-02-24,2015-11-27
-3f0i,2008-11-11,2008-10-24
-1f04,2000-06-21,2000-05-14
-7f04,2022-11-09,2021-06-03
-4f07,2013-05-08,2012-05-03
-7f0l,2021-11-10,2021-06-05
-9f0f,2024-04-24,2024-04-16
-6f0c,2018-12-12,2017-11-17
-1f0l,2000-11-16,2000-05-16
-4f0b,2013-06-12,2012-05-04
-6f0j,2018-01-10,2017-11-20
-5f0w,2017-01-18,2015-11-28
-7f0f,2022-05-11,2021-06-03
-7f0m,2022-02-16,2021-06-05
-1f0p,2001-01-24,2000-05-16
-4f0y,2012-05-16,2012-05-05
-3f0p,2008-11-11,2008-10-25
-7f0j,2021-10-13,2021-06-04
-4f08,2012-07-04,2012-05-03
-3f0s,2009-10-06,2008-10-25
-8f0o,2023-11-08,2022-11-03
-5f09,2016-06-01,2015-11-27
-6f0w,2018-10-03,2017-11-20
-7f0r,2022-07-27,2021-06-06
-4f0z,2013-03-06,2012-05-05
-8f03,2023-03-15,2022-11-01
-4f0c,2013-06-12,2012-05-04
-6f09,2018-03-07,2017-11-17
-2f0a,2005-11-22,2005-11-12
-4f0p,2012-08-08,2012-05-04
-6f0e,2018-01-17,2017-11-20
-4f0d,2012-06-13,2012-05-04
-8f0v,2023-08-23,2022-11-04
-4f0q,2012-08-08,2012-05-04
-5f0p,2016-12-07,2015-11-27
-5f0a,2015-12-16,2015-11-27
-7f0t,2022-06-15,2021-06-07
-6f05,2018-08-15,2017-11-17
-7f09,2021-07-21,2021-06-03
-6f01,2018-08-15,2017-11-17
-6f0x,2018-05-02,2017-11-20
-8f05,2023-03-15,2022-11-01
-6f0b,2018-12-12,2017-11-17
-7f0i,2022-04-13,2021-06-04
-8f06,2023-03-15,2022-11-01
-8f0y,2023-08-23,2022-11-04
-1f03,2000-06-21,2000-05-14
-3f0u,2009-03-24,2008-10-26
-7f0n,2022-06-08,2021-06-06
-3f0l,2009-10-13,2008-10-25
-3f0f,2008-11-04,2008-10-24
-8f0h,2023-05-03,2022-11-02
-8f00,2023-03-15,2022-11-01
-8f0m,2023-07-19,2022-11-03
-1f0o,2000-11-06,2000-05-16
-7f0b,2022-05-11,2021-06-03
-5f06,2016-12-07,2015-11-27
-6f0a,2017-12-27,2017-11-17
-5f00,2016-02-24,2015-11-27
-5f0s,2016-03-23,2015-11-28
-3f07,2008-12-30,2008-10-24
-2f0y,2006-11-14,2005-11-14
-2f06,2005-12-27,2005-11-11
-4f0n,2013-05-08,2012-05-04
-6f0z,2018-01-10,2017-11-21
-3f0d,2008-11-04,2008-10-24
-4f0m,2012-11-14,2012-05-04
-4f0s,2012-06-06,2012-05-04
-5f0h,2016-02-03,2015-11-27
-7f0d,2022-06-29,2021-06-03
-8f01,2023-03-15,2022-11-01
-3f0g,2008-11-04,2008-10-24
-4f0t,2013-03-06,2012-05-05
-7f0y,2022-04-20,2021-06-07
-1f06,2001-05-14,2000-05-14
-7f06,2022-09-28,2021-06-03
-1f0q,2001-05-23,2000-05-17
-4f04,2012-07-11,2012-05-03
-5f0z,2016-11-30,2015-11-28
-3f01,2009-10-06,2008-10-24
-7f05,2022-06-08,2021-06-03
-8f0g,2023-05-03,2022-11-02
-4f0l,2012-07-25,2012-05-04
-3f0q,2009-10-06,2008-10-25
-5f07,2016-12-07,2015-11-27
-8f0j,2023-08-02,2022-11-03
-8f0k,2023-08-02,2022-11-03
-3f0a,2008-11-11,2008-10-24
-5f0e,2016-07-27,2015-11-27
-6f0d,2017-11-29,2017-11-19
-6f0l,2017-12-06,2017-11-20
-6f06,2018-04-11,2017-11-17
-8f0z,2023-02-15,2022-11-04
-5f0x,2016-06-15,2015-11-28
-6f0k,2018-05-09,2017-11-20
-3f05,2009-10-06,2008-10-24
-4f09,2012-07-04,2012-05-03
-6f0r,2018-01-10,2017-11-20
-5f0b,2016-10-19,2015-11-27
-4f0a,2012-06-13,2012-05-03
-2f00,2006-10-24,2005-11-10
-6f0v,2018-01-10,2017-11-20
-2f01,2005-11-29,2005-11-10
-4f0f,2012-06-27,2012-05-04
-8f02,2023-10-11,2022-11-01
-5f04,2016-02-03,2015-11-27
-3f06,2008-12-30,2008-10-24
-8f0q,2023-04-12,2022-11-03
-3f0r,2008-12-30,2008-10-25
-6f0n,2018-01-10,2017-11-20
-1f0v,2001-02-21,2000-05-17
-6f0p,2018-01-10,2017-11-20
-4f00,2013-04-17,2012-05-03
-5f03,2016-02-24,2015-11-27
-4f0u,2013-03-06,2012-05-05
-5f08,2016-02-03,2015-11-27
-8f0p,2023-04-12,2022-11-03
-4f0r,2012-06-06,2012-05-04
-3f0v,2009-10-06,2008-10-26
-6f03,2018-12-05,2017-11-17
-7f02,2022-11-09,2021-06-03
-6f0m,2018-01-10,2017-11-20
-6f07,2017-12-13,2017-11-17
-8f0f,2023-02-15,2022-11-02
-6f0i,2018-01-10,2017-11-20
-1f0t,2000-09-20,2000-05-17
-5f0u,2017-01-18,2015-11-28
-7f0c,2022-05-11,2021-06-03
-8f0l,2023-03-29,2022-11-03
-3f0t,2009-11-03,2008-10-26
-2cnh,2006-09-27,2006-05-21
-7cnp,2021-06-16,2020-08-03
-5cnc,2015-09-16,2015-07-17
-3cn6,2009-02-24,2008-03-25
-5cno,2015-07-29,2015-07-17
-2cn2,2006-05-22,2006-05-17
-3cni,2008-04-08,2008-03-25
-3cn3,2008-10-28,2008-03-24
-8cno,2024-03-06,2023-02-23
-8cnh,2023-04-26,2023-02-23
-5cne,2015-09-16,2015-07-17
-6cn8,2019-06-05,2018-03-07
-2cnb,2006-06-12,2006-05-18
-3cn4,2008-10-28,2008-03-24
-4cnr,2015-02-04,2014-01-24
-7cnd,2021-06-09,2020-07-31
-2cns,2007-06-19,2006-05-23
-3cn2,2008-10-28,2008-03-24
-4cnn,2015-02-18,2014-01-23
-6cnp,2018-03-28,2018-03-08
-1cnk,1995-07-10,1995-04-03
-2cnw,2006-10-11,2006-05-24
-6cna,2018-10-03,2018-03-07
-6cno,2018-05-02,2018-03-08
-8cne,2024-01-10,2023-02-22
-5cnf,2015-09-16,2015-07-17
-3cno,2008-06-24,2008-03-26
-8cn2,2024-01-10,2023-02-21
-5cnk,2015-09-09,2015-07-17
-3cnq,2008-05-06,2008-03-26
-2cn6,2006-12-13,2006-05-18
-2cn5,2006-06-28,2006-05-18
-4cns,2014-06-18,2014-01-24
-5cn9,2015-09-16,2015-07-17
-6cnb,2018-08-22,2018-03-08
-2cne,2006-09-27,2006-05-21
-7cnm,2021-08-04,2020-08-02
-1cnf,1995-04-20,1995-02-01
-7cno,2021-08-04,2020-08-02
-7cn1,2021-01-20,2020-07-29
-4cn0,2014-04-02,2014-01-20
-4cng,2014-07-02,2014-01-22
-6cnx,2018-04-04,2018-03-09
-5cnn,2015-07-29,2015-07-17
-3cnm,2008-12-30,2008-03-26
-4cnc,2014-02-26,2014-01-21
-8cnt,2023-08-23,2023-02-24
-5cnv,2016-01-20,2015-07-18
-7cn3,2020-12-16,2020-07-30
-4cnm,2014-02-26,2014-01-23
-6cn2,2018-03-21,2018-03-07
-6cnd,2018-08-22,2018-03-08
-1cny,1995-11-14,1995-07-21
-8cnm,2024-03-13,2023-02-23
-3cn0,2008-10-28,2008-03-24
-5cnu,2016-01-20,2015-07-18
-7cns,2021-06-16,2020-08-03
-2cnl,2007-05-22,2006-05-22
-4cn2,2015-02-18,2014-01-21
-1cnz,1999-06-01,1999-05-24
-4cnh,2014-05-28,2014-01-22
-7cn7,2020-10-14,2020-07-30
-7cn4,2021-03-03,2020-07-30
-7cnw,2021-03-24,2020-08-03
-6cn6,2018-09-05,2018-03-07
-8cna,2024-03-06,2023-02-22
-6cnl,2019-02-13,2018-03-08
-2cn8,2006-06-28,2006-05-18
-8cnj,2023-09-27,2023-02-23
-5cnx,2016-07-20,2015-07-18
-7cn0,2021-01-20,2020-07-29
-5cn7,2015-09-16,2015-07-17
-2cna,1977-03-16,1975-04-01
-3cnn,2008-06-24,2008-03-26
-8cns,2023-04-19,2023-02-24
-5cnd,2015-09-16,2015-07-17
-6cnc,2018-08-22,2018-03-08
-4cnp,2015-02-18,2014-01-23
-7cn9,2020-08-26,2020-07-30
-7cnv,2021-08-04,2020-08-03
-5cnb,2015-09-16,2015-07-17
-3cn8,2008-04-22,2008-03-25
-7cn8,2021-03-03,2020-07-30
-7cnu,2021-08-11,2020-08-03
-1cne,1995-04-20,1995-02-01
-7cnq,2021-06-16,2020-08-03
-2cnt,2007-06-19,2006-05-23
-2cnu,2006-06-07,2006-05-24
-7cny,2021-03-24,2020-08-03
-5cng,2015-09-16,2015-07-17
-4cnj,2014-10-15,2014-01-23
-5cnm,2015-09-09,2015-07-17
-6cn5,2018-09-05,2018-03-07
-2cnx,2006-07-03,2006-05-25
-3cng,2008-04-08,2008-03-25
-4cno,2014-10-08,2014-01-23
-7cn6,2020-10-14,2020-07-30
-8cnc,2024-03-06,2023-02-22
-6cny,2018-03-21,2018-03-09
-2cnk,2007-05-22,2006-05-22
-4cnx,2015-02-04,2014-01-25
-8cnb,2024-03-06,2023-02-22
-4cne,2014-07-02,2014-01-22
-5cna,1994-05-31,1994-02-11
-6cnf,2018-08-22,2018-03-08
-4cn4,2014-05-21,2014-01-21
-4cnk,2014-10-15,2014-01-23
-3cnd,2008-04-22,2008-03-25
-5cnp,2015-07-29,2015-07-17
-2cnc,2006-06-14,2006-05-19
-6cn1,2018-03-21,2018-03-06
-8cn5,2024-01-10,2023-02-22
-3cnl,2008-06-24,2008-03-26
-7cna,2021-01-13,2020-07-30
-8cn4,2024-01-10,2023-02-21
-6cnv,2018-11-14,2018-03-09
-2cng,2006-09-27,2006-05-21
-6cnj,2018-05-02,2018-03-08
-5cnj,2015-09-09,2015-07-17
-4cnv,2015-02-04,2014-01-25
-3cnz,2008-06-17,2008-03-26
-8cnr,2023-04-19,2023-02-24
-2cnd,1995-04-20,1995-02-01
-4cn3,2015-02-18,2014-01-21
-5cn0,2015-09-16,2015-07-17
-3cns,2008-04-22,2008-03-26
-3cn1,2008-10-28,2008-03-24
-5cni,2015-09-09,2015-07-17
-6cnn,2018-05-02,2018-03-08
-5cn4,2015-09-16,2015-07-17
-2cnm,2007-05-22,2006-05-22
-7cnl,2021-04-28,2020-08-01
-5cnq,2015-12-30,2015-07-17
-1cnj,1995-07-10,1995-04-03
-2cn0,2006-11-06,2006-05-17
-1cni,1995-07-10,1995-04-03
-3cne,2008-04-15,2008-03-25
-3cnj,2008-04-29,2008-03-25
-2cni,2006-09-27,2006-05-21
-2cn7,2006-12-13,2006-05-18
-4cn9,2014-03-12,2014-01-21
-5cny,2015-08-26,2015-07-18
-6cnm,2018-05-02,2018-03-08
-8cnd,2024-03-06,2023-02-22
-8cn3,2023-08-02,2023-02-21
-2cnv,2006-06-08,2006-05-24
-3cnx,2008-04-08,2008-03-26
-4cnt,2014-06-18,2014-01-24
-8cn9,2023-12-27,2023-02-22
-2cnf,2006-09-27,2006-05-21
-1cno,1999-07-22,1998-08-03
-6cni,2019-02-13,2018-03-08
-1cnh,1995-07-10,1995-04-03
-7cnt,2020-12-16,2020-08-03
-3cnh,2008-04-08,2008-03-25
-2cn4,2006-05-26,2006-05-18
-1cng,1995-07-10,1995-04-03
-5cn5,2015-09-16,2015-07-17
-6cnk,2018-05-02,2018-03-08
-4cnf,2014-07-02,2014-01-22
-3cnp,2008-04-22,2008-03-26
-1cnx,1995-11-14,1995-07-21
-8cnn,2023-09-27,2023-02-23
-8cng,2024-01-10,2023-02-22
-4cn1,2014-05-21,2014-01-21
-4cn7,2015-02-18,2014-01-21
-1cnt,1997-03-26,1996-06-06
-2cnq,2006-06-08,2006-05-23
-6cng,2019-07-03,2018-03-08
-4cn5,2015-02-18,2014-01-21
-8cn0,2024-03-06,2023-02-21
-8cn1,2023-08-02,2023-02-21
-5cnt,2016-01-20,2015-07-18
-8cnp,2024-03-06,2023-02-24
-8cn7,2024-01-10,2023-02-22
-3cnt,2008-04-22,2008-03-26
-2cnn,2007-05-22,2006-05-22
-2cn3,2006-05-22,2006-05-17
-1cnw,1995-11-14,1995-07-21
-7cnn,2021-08-04,2020-08-02
-6cnh,2018-03-28,2018-03-08
-1cnq,1999-05-28,1999-05-21
-4cnw,2015-02-04,2014-01-25
-4cn6,2014-05-21,2014-01-21
-3cna,1976-10-11,1976-09-15
-1cnc,1994-10-15,1994-06-13
-5cn6,2015-09-16,2015-07-17
-2cno,2007-05-22,2006-05-22
-4cnz,2014-05-28,2014-01-25
-1cnm,1999-05-27,1999-05-20
-5cn8,2015-09-16,2015-07-17
-8cnf,2024-03-06,2023-02-22
-5cns,2016-01-20,2015-07-18
-4hsz,2013-01-30,2012-10-31
-6hs1,2019-02-27,2018-09-28
-4hsn,2013-09-11,2012-10-30
-3hsd,2010-06-23,2009-06-10
-5hs3,2016-02-24,2016-01-25
-3hsk,2010-02-02,2009-06-10
-6hsc,,2018-09-29
-1hsz,2001-01-10,2000-12-27
-4hsq,2013-11-13,2012-10-30
-1hsk,2001-03-14,2000-12-27
-4hsd,2012-11-14,2012-10-30
-5hsi,2016-09-21,2016-01-25
-6hs4,2019-02-27,2018-09-28
-1hsy,1995-02-27,1994-12-12
-2hsj,2006-09-19,2006-07-21
-4hsu,2013-02-13,2012-10-30
-2hs1,2006-10-03,2006-07-20
-6hso,2019-01-16,2018-10-01
-4hsr,2013-02-27,2012-10-30
-4hsi,2013-03-27,2012-10-30
-3hsc,1995-07-10,1995-03-24
-3hs0,2009-07-07,2009-06-10
-2hse,2007-07-17,2006-07-21
-5hsj,2016-09-14,2016-01-25
-6hs9,2019-10-23,2018-09-29
-8hsa,2023-12-27,2022-12-18
-1hsj,2001-06-06,2000-12-26
-1hso,2001-01-10,2000-12-27
-5hsu,2017-02-01,2016-01-26
-3hsn,2009-10-20,2009-06-10
-8hso,2023-12-20,2022-12-20
-8hsh,2023-05-03,2022-12-19
-4hsg,2012-12-05,2012-10-30
-8hs7,2024-01-17,2022-12-17
-1hsh,1996-04-03,1995-03-31
-1hsg,1996-04-03,1995-03-31
-3hst,2010-04-28,2009-06-10
-2hs0,2007-01-09,2006-07-20
-5hsg,2016-03-02,2016-01-25
-1hsr,1998-07-01,1997-07-01
-5hsq,2016-08-03,2016-01-26
-4hsh,2012-11-28,2012-10-30
-2hsd,1994-08-31,1994-03-28
-3hsv,2009-10-20,2009-06-10
-1hsl,1994-05-31,1994-01-03
-5hs1,2016-06-01,2016-01-24
-4hse,2013-01-30,2012-10-30
-4hs4,2012-12-26,2012-10-29
-5hsa,2016-03-09,2016-01-25
-4hsf,2013-10-30,2012-10-30
-6hsg,2018-10-31,2018-10-01
-2hs2,2006-10-03,2006-07-20
-4hs3,2014-05-07,2012-10-29
-4hso,2013-09-11,2012-10-30
-5hs6,2016-07-13,2016-01-25
-6hsn,2019-01-16,2018-10-01
-6hs5,2018-11-21,2018-09-28
-3hs6,2010-05-12,2009-06-10
-8hs4,2023-12-27,2022-12-17
-8hsg,2023-05-03,2022-12-19
-8hsw,2023-12-20,2022-12-20
-6hsx,2019-10-23,2018-10-02
-3hsr,2009-07-07,2009-06-10
-8hsi,2023-12-27,2022-12-19
-8hsj,2023-05-03,2022-12-19
-5hsx,2016-02-10,2016-01-26
-1hsb,1993-10-31,1993-03-30
-3hs4,2009-12-08,2009-06-10
-3hsu,2009-06-30,2009-06-10
-8hsp,2024-04-03,2022-12-20
-4hst,2013-02-27,2012-10-30
-2hs4,2007-01-09,2006-07-21
-3hsb,2010-06-23,2009-06-10
-6hsk,2018-10-31,2018-10-01
-4hsw,2013-05-01,2012-10-31
-6hsz,2018-10-31,2018-10-02
-3hsw,2009-06-30,2009-06-11
-6hsj,2019-01-02,2018-10-01
-8hsm,2023-12-20,2022-12-20
-4hsl,2013-11-27,2012-10-30
-3hsg,2010-06-23,2009-06-10
-3hsy,2010-06-16,2009-06-11
-4hsj,2015-05-06,2012-10-30
-4hsx,2013-05-01,2012-10-31
-4hsa,2013-05-22,2012-10-29
-4hs9,2013-05-22,2012-10-29
-8hsr,2023-05-03,2022-12-20
-2hsi,2006-08-08,2006-07-21
-5hss,2016-04-27,2016-01-26
-3hs5,2010-05-12,2009-06-10
-5hsv,2017-08-16,2016-01-26
-2hs3,2007-01-09,2006-07-21
-2hs8,2006-09-12,2006-07-21
-6hsf,2018-10-31,2018-10-01
-8hsl,2023-05-03,2022-12-19
-6hs2,2019-02-27,2018-09-28
-2hs6,2006-09-12,2006-07-21
-3hss,2010-05-26,2009-06-10
-6hsp,2019-01-02,2018-10-01
-1hsa,1992-10-15,1992-08-11
-1hse,1997-03-12,1996-12-11
-5hsr,2017-02-01,2016-01-26
-6hs0,2019-02-27,2018-09-28
-3hs7,2010-05-12,2009-06-10
-6hsh,2018-10-31,2018-10-01
-4hss,2013-11-13,2012-10-30
-8hs0,2024-01-17,2022-12-16
-3hsp,2009-10-20,2009-06-10
-8hs5,2023-12-27,2022-12-17
-5hsp,2016-11-30,2016-01-26
-2hsa,2006-09-12,2006-07-21
-6hsa,2019-10-23,2018-09-29
-1hs6,2001-06-24,2000-12-24
-6hsm,2019-01-30,2018-10-01
-5hs2,2016-11-23,2016-01-24
-3hso,2009-10-20,2009-06-10
-4hs7,2012-11-07,2012-10-29
-5ium,2016-12-21,2016-03-18
-6iut,2019-01-16,2018-11-30
-4iut,2013-05-01,2013-01-21
-4iuv,2013-05-01,2013-01-21
-4iun,2013-02-06,2013-01-21
-1iu6,2002-08-27,2002-02-27
-3iu8,2010-01-12,2009-08-30
-4iuw,2013-03-20,2013-01-21
-8iuh,2023-05-24,2023-03-24
-6iu6,2019-02-06,2018-11-27
-2iu2,2006-12-13,2006-05-26
-8iue,2023-05-24,2023-03-24
-8iuv,2024-03-27,2023-03-25
-2iub,2006-08-03,2006-06-01
-4iub,2014-04-02,2013-01-20
-3iub,2009-10-13,2009-08-31
-4iu0,2013-01-30,2013-01-19
-8ius,2024-03-27,2023-03-25
-3iu1,2009-09-15,2009-08-29
-5iuk,2016-12-21,2016-03-18
-3iuq,2010-05-05,2009-08-31
-4iue,2013-06-26,2013-01-21
-6iug,2019-11-06,2018-11-28
-3iuo,2009-09-08,2009-08-31
-3iu6,2009-09-22,2009-08-30
-5iul,2016-12-21,2016-03-18
-3iut,2010-03-02,2009-08-31
-3iu9,2010-01-12,2009-08-30
-5iu6,2017-04-05,2016-03-17
-1iud,1997-06-05,1996-05-29
-5iug,2016-05-18,2016-03-18
-4iuc,2014-04-02,2013-01-20
-2iuu,2006-08-29,2006-06-07
-5iuc,2016-04-13,2016-03-17
-2iuw,2006-07-26,2006-06-07
-4iuf,2014-01-29,2013-01-21
-3iux,2009-10-27,2009-08-31
-2iuf,2006-07-10,2006-06-02
-1iuv,1996-06-20,1995-11-22
-5iu7,2016-06-29,2016-03-17
-8iuz,2024-04-24,2023-03-25
-5iux,2017-03-29,2016-03-18
-4iug,2013-07-31,2013-01-21
-1iuz,1997-08-20,1996-10-06
-3iu7,2010-01-12,2009-08-30
-8iuy,2024-04-24,2023-03-25
-8iu0,2023-09-06,2023-03-23
-3iu3,2010-01-26,2009-08-29
-8iuk,2023-07-12,2023-03-24
-8iui,2024-04-03,2023-03-24
-8iu1,2024-03-27,2023-03-23
-6iuj,2019-01-30,2018-11-28
-8ium,2023-07-12,2023-03-24
-2iuh,2006-06-06,2006-06-03
-4iuq,2013-05-01,2013-01-21
-2iuq,2006-09-20,2006-06-07
-3iuk,2009-10-27,2009-08-31
-4iur,2013-05-01,2013-01-21
-1iup,2002-09-18,2002-03-06
-8iuc,2023-06-14,2023-03-24
-2iu0,2007-02-20,2006-05-26
-5iuy,2016-07-06,2016-03-18
-6iuy,2019-12-04,2018-12-01
-2iuz,2006-06-12,2006-06-08
-1iuu,1996-04-03,1995-11-22
-8iug,2023-11-22,2023-03-24
-4iu3,2013-04-24,2013-01-19
-6iun,2018-12-19,2018-11-29
-5iu9,2016-11-02,2016-03-17
-2iu8,2007-02-20,2006-05-30
-3iud,2010-02-02,2009-08-31
-4iup,2013-05-01,2013-01-21
-5iui,2016-05-18,2016-03-18
-3iuc,2009-09-22,2009-08-31
-2iuk,2006-10-11,2006-06-05
-4ium,2013-02-13,2013-01-21
-6iud,2019-02-13,2018-11-28
-8iu7,2024-04-24,2023-03-23
-8iul,2023-07-12,2023-03-24
-5iua,2016-06-29,2016-03-17
-6iuv,2019-01-16,2018-11-30
-6iu4,2019-02-06,2018-11-27
-1iut,1996-04-03,1995-11-22
-3iu2,2009-09-15,2009-08-29
-6iuo,2019-10-23,2018-11-29
-1ius,1996-04-03,1995-11-22
-3iuu,2009-09-15,2009-08-31
-3iuf,2009-11-03,2009-08-31
-3iui,2010-02-02,2009-08-31
-5iuw,2017-10-25,2016-03-18
-4iu1,2013-01-30,2013-01-19
-1iu5,2002-08-27,2002-02-27
-8iu2,2024-03-27,2023-03-23
-6iuc,2019-02-13,2018-11-28
-3iuy,2009-10-20,2009-08-31
-1iux,1996-07-11,1995-11-22
-2iuj,2006-10-11,2006-06-05
-5iu8,2016-06-29,2016-03-17
-4iui,2013-03-27,2013-01-21
-6iu8,2019-02-06,2018-11-27
-5iub,2016-06-29,2016-03-17
-5iuz,2016-06-08,2016-03-18
-2iuc,2006-11-28,2006-06-01
-8iua,2023-06-14,2023-03-24
-8iuw,2024-03-27,2023-03-25
-2iu3,2007-02-20,2006-05-27
-8iuf,2024-02-28,2023-03-24
-8iux,2024-04-24,2023-03-25
-5iuf,2017-08-02,2016-03-17
-3iue,2009-10-13,2009-08-31
-2iun,2007-06-19,2006-06-06
-2iut,2006-08-29,2006-06-07
-5iut,2016-06-08,2016-03-18
-4iuu,2013-05-01,2013-01-21
-1iu9,2003-09-09,2002-02-28
-1iu7,2003-02-04,2002-02-28
-3iuh,2010-02-02,2009-08-31
-3iur,2010-05-05,2009-08-31
-6iub,2019-02-13,2018-11-28
-5iu4,2016-06-29,2016-03-17
-5iu2,2016-08-24,2016-03-17
-1iub,2003-09-30,2002-03-01
-1iuc,2003-09-30,2002-03-01
-8iun,2023-12-06,2023-03-24
-5iuj,2016-12-21,2016-03-18
-2iu9,2007-02-20,2006-05-30
-1iue,2003-09-30,2002-03-04
-6iup,2019-11-06,2018-11-29
-6iuf,2019-04-10,2018-11-28
-8iuu,2024-03-27,2023-03-25
-4iuo,2013-01-30,2013-01-21
-6iu5,2019-02-06,2018-11-27
-8iuj,2024-02-28,2023-03-24
-5iuq,2017-03-29,2016-03-18
-6iu9,2019-02-06,2018-11-27
-8iu9,2023-06-14,2023-03-24
-5iuv,2017-10-25,2016-03-18
-3iup,2009-09-15,2009-08-31
-4iu6,2013-05-01,2013-01-19
-8iut,,2023-03-25
-2iu7,2006-06-06,2006-05-30
-5iuh,2016-05-18,2016-03-18
-4iud,2014-04-02,2013-01-20
-4iu7,2013-03-27,2013-01-20
-2iul,2006-10-25,2006-06-06
-8iub,2023-06-14,2023-03-24
-5iue,2017-06-14,2016-03-17
-6iux,2019-12-04,2018-12-01
-6iuq,2018-12-12,2018-11-29
-5iu0,2017-07-12,2016-03-17
-2iux,2006-10-25,2006-06-07
-6iu3,2019-02-06,2018-11-27
-4iu5,2013-01-30,2013-01-19
-1iuw,1996-07-11,1995-11-22
-4iu4,2013-01-30,2013-01-19
-4iu2,2013-04-24,2013-01-19
-1iuj,2003-09-09,2002-03-05
-184l,1995-07-10,1995-04-19
-5lx7,2017-05-31,2016-09-20
-6lxx,2021-02-17,2020-02-12
-7lxz,2021-04-14,2021-03-05
-7lxy,2021-04-14,2021-03-05
-6lx5,2020-11-11,2020-02-10
-5lx1,2017-05-31,2016-09-19
-7lx0,2021-07-28,2021-03-02
-6lxy,2020-11-25,2020-02-12
-5lxv,2016-10-19,2016-09-22
-3lxd,2010-06-23,2010-02-25
-4lxb,2014-06-11,2013-07-29
-4lxw,2013-12-18,2013-07-30
-3lxi,2010-06-23,2010-02-25
-1lxk,2002-08-07,2002-06-05
-3lxk,2010-06-02,2010-02-25
-4lxa,2013-08-28,2013-07-29
-3lxl,2010-06-02,2010-02-25
-2lxw,2013-09-04,2012-09-03
-5lxp,2016-12-21,2016-09-22
-4lxc,2014-07-09,2013-07-29
-6lx4,2020-11-11,2020-02-10
-5lx5,2017-10-25,2016-09-20
-1lx5,2003-04-01,2002-06-04
-6lxj,2020-12-02,2020-02-11
-3lxx,2010-03-09,2010-02-25
-7lxr,2022-11-16,2021-03-04
-5lx4,2017-05-31,2016-09-20
-6lxd,2020-04-15,2020-02-10
-5lxm,2016-11-02,2016-09-22
-5lxz,2017-07-26,2016-09-23
-2lxd,2012-09-12,2012-08-20
-6lxv,2021-02-17,2020-02-12
-3lx8,2010-03-09,2010-02-24
-6lxk,2020-12-02,2020-02-11
-7lxu,2021-09-22,2021-03-05
-4lxh,2013-09-18,2013-07-29
-7lxi,2021-03-17,2021-03-03
-3lxa,2010-05-05,2010-02-25
-3lxe,2010-07-21,2010-02-25
-1lxi,2003-04-01,2002-06-05
-3lx3,2010-03-09,2010-02-24
-1lxy,2004-01-20,2002-06-06
-3lxs,2010-10-20,2010-02-25
-5lxa,2017-03-22,2016-09-20
-5lxq,2016-12-07,2016-09-22
-4lxu,2013-08-14,2013-07-30
-7lxa,2021-08-25,2021-03-03
-4lxo,2014-08-06,2013-07-30
-1lxf,2002-12-11,2002-06-05
-6lxi,2020-12-02,2020-02-11
-3lxc,2010-05-05,2010-02-25
-3lxh,2010-06-23,2010-02-25
-6lxs,2020-04-22,2020-02-11
-5lx2,2016-11-16,2016-09-19
-4lxs,2014-04-09,2013-07-30
-7lxb,2021-09-08,2021-03-03
-6lxc,2020-11-11,2020-02-10
-4lx0,2013-11-20,2013-07-29
-3lx0,2011-02-16,2010-02-24
-3lxr,2010-03-31,2010-02-25
-2lxy,2013-02-27,2012-09-06
-3lx9,2010-05-05,2010-02-25
-7lxx,2021-04-14,2021-03-05
-4lxj,2014-01-29,2013-07-29
-5lx9,2017-03-22,2016-09-20
-4lxy,2013-08-14,2013-07-30
-4lxd,2013-08-14,2013-07-29
-4lxf,2013-08-21,2013-07-29
-4lxt,2013-08-14,2013-07-30
-2lxp,2013-08-28,2012-08-30
-7lxj,2021-11-17,2021-03-03
-7lx9,2021-05-19,2021-03-03
-5lx6,2017-01-11,2016-09-20
-3lxp,2010-06-02,2010-02-25
-6lxt,2020-02-26,2020-02-11
-1lxc,2002-09-04,2002-06-05
-7lxt,2021-09-22,2021-03-05
-5lxd,2016-10-26,2016-09-20
-7lxv,2021-09-22,2021-03-05
-4lx9,2013-08-21,2013-07-29
-2lxh,2013-08-28,2012-08-27
-7lxl,2021-04-28,2021-03-04
-4lxr,2014-04-09,2013-07-30
-3lxo,2010-04-28,2010-02-25
-3lxv,2011-03-09,2010-02-25
-4lxx,2013-08-14,2013-07-30
-4lxm,2013-08-28,2013-07-30
-5lxs,2017-09-20,2016-09-22
-4lxz,2013-08-21,2013-07-30
-3lxn,2010-06-02,2010-02-25
-7lxh,2021-11-17,2021-03-03
-3lxy,2010-03-09,2010-02-25
-3lx5,2010-03-09,2010-02-24
-3lxg,2010-05-19,2010-02-25
-7lx7,2021-05-19,2021-03-03
-4lxi,2013-10-09,2013-07-29
-6lx1,2020-08-26,2020-02-10
-4lxq,2013-08-14,2013-07-30
-6lxe,2020-04-15,2020-02-10
-6lxb,2020-11-11,2020-02-10
-5lxw,2016-10-05,2016-09-22
-1lx6,2002-09-04,2002-06-04
-5lxr,2016-12-14,2016-09-22
-3lxb,2010-05-05,2010-02-25
-4lx8,2013-10-09,2013-07-29
-6lx2,2020-08-26,2020-02-10
-7lx3,2022-03-09,2021-03-03
-7lxn,2022-03-09,2021-03-04
-4lxv,2014-02-26,2013-07-30
-5lxi,2017-02-08,2016-09-21
-7lx8,2021-05-19,2021-03-03
-5lxg,2017-03-22,2016-09-21
-5lxb,2016-10-12,2016-09-20
-7lx6,2021-09-29,2021-03-03
-5lx3,2017-10-25,2016-09-20
-4lxl,2014-07-30,2013-07-30
-5lx0,2017-05-31,2016-09-19
-5lx8,2016-12-14,2016-09-20
-7lx2,2022-03-09,2021-03-03
-5lxc,2016-10-26,2016-09-20
-7lxw,2021-04-14,2021-03-05
-7lxm,2022-03-09,2021-03-04
-5lxt,2017-03-01,2016-09-22
-4lxk,2013-08-28,2013-07-30
-1lxm,2002-10-30,2002-06-05
-7lx1,2022-03-02,2021-03-02
-1lxt,1997-02-12,1996-07-28
-2nse,1999-05-25,1998-08-13
-2nsy,1999-01-13,1998-07-14
-4ns5,2014-04-09,2013-11-28
-7nsd,2021-06-02,2021-03-05
-3nsn,2010-11-24,2010-07-02
-7nsa,2021-06-02,2021-03-05
-6ns4,2019-03-27,2019-01-24
-3ns7,2011-08-17,2010-07-01
-7ns4,2021-05-05,2021-03-05
-6nsv,2019-07-31,2019-01-25
-3nst,2011-07-13,2010-07-02
-4ns2,2014-12-24,2013-11-27
-4nsk,2014-01-01,2013-11-28
-5nst,2017-10-04,2017-04-26
-1ns6,2003-10-14,2003-01-27
-4nsq,2014-03-05,2013-11-28
-4nsy,2014-04-23,2013-11-29
-1nsi,2000-01-07,1999-01-10
-6nsx,2019-06-05,2019-01-25
-1ns8,2003-02-11,2003-01-27
-9nse,2000-10-25,1999-01-13
-5ns8,2018-08-08,2017-04-25
-5nsx,2018-03-07,2017-04-27
-2ns8,2007-07-24,2006-11-03
-4ns3,2015-01-14,2013-11-27
-5nsg,2017-07-05,2017-04-26
-7nsp,2021-08-11,2021-03-08
-4ns0,2013-12-25,2013-11-27
-7ns5,2021-05-05,2021-03-05
-3nsq,2010-11-17,2010-07-02
-2nsf,2007-04-10,2006-11-04
-3ns4,2010-09-15,2010-07-01
-7nsj,2021-06-02,2021-03-07
-6nsl,2020-01-29,2019-01-25
-3nse,1999-05-18,1998-09-23
-6nsw,2019-05-01,2019-01-25
-1nsr,2003-02-11,2003-01-28
-1nss,2003-02-11,2003-01-28
-4nsv,2014-04-23,2013-11-29
-3ns0,2011-05-11,2010-07-01
-1nsv,2003-02-11,2003-01-28
-1ns9,2003-10-14,2003-01-27
-1nsz,2003-02-11,2003-01-28
-6nsy,2019-05-01,2019-01-27
-7nsn,2022-09-21,2021-03-08
-5nsq,2017-08-02,2017-04-26
-5nsl,2018-11-07,2017-04-26
-2ns1,2006-12-26,2006-11-02
-4nsg,2014-10-15,2013-11-28
-7nso,2021-07-14,2021-03-08
-2nsh,2007-04-24,2006-11-04
-6ns0,2019-02-06,2019-01-24
-7nsv,2021-06-16,2021-03-08
-2nsr,2007-11-06,2006-11-06
-5nsw,2017-09-20,2017-04-27
-7ns3,2021-05-05,2021-03-05
-6nsf,2019-04-24,2019-01-24
-3nsc,2011-08-17,2010-07-01
-5nsm,2017-08-02,2017-04-26
-2nsj,2007-04-24,2006-11-04
-6nsa,2019-04-24,2019-01-24
-3nsb,2011-05-11,2010-07-01
-1ns0,2003-02-11,2003-01-27
-1nsf,1998-11-25,1998-06-26
-6ns3,2019-03-27,2019-01-24
-7nsf,2021-06-02,2021-03-05
-2nsi,2000-01-07,1999-01-11
-6nsg,2019-04-24,2019-01-24
-4nsi,2014-10-15,2013-11-28
-6nsb,2019-04-24,2019-01-24
-7nsx,2021-05-19,2021-03-08
-2nsp,2007-09-18,2006-11-06
-1ns7,2003-02-11,2003-01-27
-3nsy,2011-08-17,2010-07-02
-1nsu,2003-02-11,2003-01-28
-5nsp,2017-11-29,2017-04-26
-5ns5,2017-05-31,2017-04-25
-4nst,2014-03-26,2013-11-29
-3nsd,2011-08-17,2010-07-01
-2nsm,2007-04-24,2006-11-05
-7nsk,2022-06-22,2021-03-08
-6nsp,2019-05-22,2019-01-25
-3ns2,2010-07-21,2010-07-01
-1nsm,2003-02-11,2003-01-28
-4nsb,2013-12-11,2013-11-28
-1nsg,1998-03-18,1997-07-01
-1nsy,1997-07-23,1996-07-22
-5ns2,2017-05-31,2017-04-25
-7nse,2002-05-29,1999-01-13
-3nsj,2010-11-03,2010-07-01
-5ns4,2017-12-20,2017-04-25
-6nse,2002-05-29,1999-01-13
-2nst,2007-09-18,2006-11-06
-3nsz,2010-12-15,2010-07-02
-4nsn,2013-12-25,2013-11-28
-1nst,1999-09-16,1998-09-07
-6ns2,2019-03-27,2019-01-24
-7nsr,2021-09-01,2021-03-08
-5nsc,2017-07-05,2017-04-26
-6ns1,2019-02-06,2019-01-24
-3ns9,2010-12-08,2010-07-01
-1ns4,2003-02-11,2003-01-27
-4nse,1999-05-18,1998-10-07
-1nsc,1993-10-31,1993-05-24
-2nso,2007-12-04,2006-11-06
-7nsi,2021-06-02,2021-03-07
-7nsz,2021-05-19,2021-03-08
-3ns1,2010-07-14,2010-07-01
-4nsl,2014-12-03,2013-11-28
-6nsi,2019-10-30,2019-01-24
-6ns9,2019-04-24,2019-01-24
-6nsd,2019-04-24,2019-01-24
-5nse,2002-05-29,1999-01-13
-7nsw,2021-10-06,2021-03-08
-2ns6,2007-02-06,2006-11-03
-6ns5,2019-03-27,2019-01-24
-6nsc,2019-04-24,2019-01-24
-6nss,2019-05-22,2019-01-25
-1nse,1999-05-18,1998-05-14
-7nsh,2021-05-05,2021-03-07
-3nss,2010-09-22,2010-07-02
-2nsl,2007-04-24,2006-11-04
-5ns9,2017-09-13,2017-04-25
-1ns2,2003-02-11,2003-01-27
-6ns6,2019-03-27,2019-01-24
-5nsj,2017-08-02,2017-04-26
-5nsd,2018-02-14,2017-04-26
-4nsj,2014-10-15,2013-11-28
-1nsa,1997-12-24,1997-07-25
-3nsh,2010-09-22,2010-07-01
-5nsf,2019-01-16,2017-04-26
-7nsq,2021-07-14,2021-03-08
-6nsq,2019-06-19,2019-01-25
-1nsb,1993-10-31,1991-08-08
-1nsx,2003-02-11,2003-01-28
-4ns1,2013-12-25,2013-11-27
-7ns9,2021-06-02,2021-03-05
-6nsh,2020-10-14,2019-01-24
-5nsa,2017-09-27,2017-04-25
-6nsz,2019-05-01,2019-01-27
-2nsd,2007-09-18,2006-11-03
-5ns1,2017-05-31,2017-04-25
-1nsd,1993-10-31,1993-05-24
-2nsx,2006-12-26,2006-11-06
-1ns3,1998-04-08,1997-04-05
-6nsu,2019-08-21,2019-01-25
-8nse,2001-11-21,1999-01-14
-7ns6,2022-02-02,2021-03-05
-4nsd,2014-02-26,2013-11-28
-4nsh,2014-10-15,2013-11-28
-7nsg,2022-03-16,2021-03-05
-2nss,2007-11-06,2006-11-06
-5ys1,2018-10-17,2017-11-12
-1ysb,2005-05-17,2005-02-08
-1ys7,2006-02-07,2005-02-07
-5ysi,2018-08-29,2017-11-14
-5ysg,2018-11-14,2017-11-14
-4ysy,2015-08-05,2015-03-17
-5ysu,2018-11-21,2017-11-15
-5ysf,2018-05-02,2017-11-14
-6ysi,2020-09-16,2020-04-22
-7ys6,2023-03-29,2022-08-11
-4ysd,2016-02-24,2015-03-17
-4yss,2016-02-24,2015-03-17
-4ysa,2016-02-24,2015-03-17
-4ysp,2016-02-24,2015-03-17
-7ysi,2023-03-15,2022-08-12
-7ysa,2023-08-16,2022-08-11
-7yso,2023-10-18,2022-08-12
-6ysr,2020-08-19,2020-04-23
-7yst,2023-08-16,2022-08-13
-4ysl,2015-06-24,2015-03-17
-5ysz,2018-08-22,2017-11-16
-1ysn,2005-06-07,2005-02-08
-6ys9,2020-12-09,2020-04-21
-2yso,2007-10-09,2007-04-03
-5ysw,2018-07-04,2017-11-15
-6ys1,2021-04-21,2020-04-20
-2ys6,2007-10-09,2007-04-03
-4ysc,2016-03-09,2015-03-17
-1ys4,2005-11-01,2005-02-07
-6ysp,2021-03-03,2020-04-23
-4ysr,2016-02-24,2015-03-17
-6ysq,2020-06-24,2020-04-23
-6yso,2020-11-04,2020-04-22
-2ysl,2007-10-09,2007-04-03
-4ysu,2016-02-24,2015-03-17
-5ysq,2018-05-16,2017-11-14
-2ysp,2007-10-09,2007-04-03
-6ys5,2020-09-16,2020-04-21
-5ysd,2018-05-02,2017-11-14
-5ysp,2018-05-16,2017-11-14
-1yst,1995-02-27,1994-12-07
-6ys2,2021-04-21,2020-04-20
-6ysy,2021-03-03,2020-04-23
-6ysx,2021-05-12,2020-04-23
-7yse,2023-02-01,2022-08-12
-4ysw,2015-04-22,2015-03-17
-5ys0,2018-01-31,2017-11-11
-4ys2,2016-04-27,2015-03-16
-6ysu,2020-08-19,2020-04-23
-1ys2,2005-05-17,2005-02-06
-4ys0,2015-06-03,2015-03-16
-6ysw,2021-05-12,2020-04-23
-2ysj,2007-10-09,2007-04-03
-1ysl,2005-11-08,2005-02-08
-7ysn,2023-10-18,2022-08-12
-5ysb,2018-05-02,2017-11-13
-5ysy,2018-04-11,2017-11-16
-4ys1,2016-03-23,2015-03-16
-2ysa,2007-10-09,2007-04-03
-6ys0,2021-05-12,2020-04-20
-4ysq,2016-02-24,2015-03-17
-7ysp,2023-10-18,2022-08-12
-5ysc,2018-09-19,2017-11-13
-2ysm,2007-10-09,2007-04-03
-4yst,2016-02-24,2015-03-17
-7ysm,2023-08-16,2022-08-12
-5ysn,2018-09-19,2017-11-14
-7ysu,2023-04-19,2022-08-13
-5ys5,2018-10-17,2017-11-13
-1ysz,2005-06-14,2005-02-09
-4ys7,2015-04-29,2015-03-16
-4ys6,2015-04-08,2015-03-16
-7ys8,2023-08-16,2022-08-11
-6ysc,2020-10-14,2020-04-22
-4ysx,2015-08-05,2015-03-17
-4yso,2016-02-24,2015-03-17
-5yse,2018-05-02,2017-11-14
-6ys6,2021-03-03,2020-04-21
-7ysr,2023-10-18,2022-08-12
-4ysj,2016-04-06,2015-03-17
-7ysz,2023-08-16,2022-08-13
-7ysx,2023-07-12,2022-08-13
-1ysi,2005-06-07,2005-02-08
-1ysd,2005-05-17,2005-02-08
-1ys1,2005-05-17,2005-02-06
-1ys6,2006-02-07,2005-02-07
-1ysj,2005-03-22,2005-02-08
-5yso,2018-12-26,2017-11-14
-5ysr,2018-09-19,2017-11-14
-1ysw,2005-06-07,2005-02-09
-4ysk,2015-06-24,2015-03-17
-4ys4,2015-10-14,2015-03-16
-5ys9,2018-02-28,2017-11-13
-4ysf,2016-07-20,2015-03-17
-5yst,2018-11-21,2017-11-15
-6ysk,2020-09-16,2020-04-22
-6ysn,2020-12-02,2020-04-22
-4yse,2016-03-09,2015-03-17
-1ysg,2005-06-07,2005-02-08
-6ys4,2021-05-12,2020-04-21
-4ysn,2016-04-20,2015-03-17
-5ysm,2018-07-04,2017-11-14
-1ysx,2005-06-07,2005-02-09
-4ysz,2015-08-05,2015-03-17
-5ysh,2018-09-19,2017-11-14
-4ysi,2016-02-03,2015-03-17
-2ys2,2007-10-09,2007-04-03
-1yso,1996-06-10,1995-12-21
-2ysv,2007-10-09,2007-04-04
-4ysb,2015-06-24,2015-03-17
-5yss,2018-10-31,2017-11-15
-7ys9,2023-08-16,2022-08-11
-7ysq,2023-10-18,2022-08-12
-7ysw,2023-06-14,2022-08-13
-4ysh,2016-03-23,2015-03-17
-6ysj,2021-05-12,2020-04-22
-6ysa,2020-07-29,2020-04-21
-1ysc,1994-06-22,1994-03-08
-7ysg,2023-02-01,2022-08-12
-4ys9,2016-03-09,2015-03-16
-6yst,2020-08-19,2020-04-23
-7ysf,2023-08-16,2022-08-12
-4ysm,2016-04-06,2015-03-17
-7ysy,2023-08-16,2022-08-13
-6yss,2020-08-19,2020-04-23
-8ysa,2024-05-08,2024-03-22
-4bu5,2013-10-30,2013-06-20
-4bu3,2013-10-30,2013-06-20
-1bu5,1999-02-09,1998-09-12
-2buq,2006-09-05,2005-06-17
-1buw,1998-09-16,1998-09-06
-2bua,2006-01-23,2005-06-09
-4bue,2013-10-30,2013-06-20
-2bu5,2006-02-02,2005-06-08
-5bu4,1998-09-23,1998-09-15
-3bud,2008-07-01,2008-01-02
-4bu8,2013-10-30,2013-06-20
-4buv,2013-10-30,2013-06-24
-5buv,2015-08-05,2015-06-04
-6bu6,2017-12-20,2017-12-08
-5bue,2015-07-15,2015-06-03
-7bu7,2020-12-02,2020-04-04
-8bul,2023-09-13,2022-11-30
-7bu4,2021-04-07,2020-04-04
-4bup,2013-10-02,2013-06-21
-8buj,2023-09-13,2022-11-30
-2buz,2006-11-01,2005-06-20
-2bu4,1998-09-23,1998-09-14
-8bu0,2023-12-13,2022-11-30
-3buf,2008-03-11,2008-01-02
-3buq,2008-07-01,2008-01-03
-5but,2016-01-27,2015-06-04
-5bu2,2015-08-26,2015-06-03
-3buc,2008-04-22,2008-01-02
-4bu2,2014-05-14,2013-06-19
-5bu3,2016-02-24,2015-06-03
-2bux,2006-10-26,2005-06-20
-8bu7,2023-09-13,2022-11-30
-2bu9,2005-09-15,2005-06-09
-4bu9,2013-10-30,2013-06-20
-2buj,2005-07-05,2005-06-13
-7bui,2021-04-07,2020-04-06
-7bub,2020-05-13,2020-04-06
-1bug,1999-09-02,1998-09-03
-6buu,2018-08-22,2017-12-11
-2bup,1998-09-16,1998-09-08
-3buy,2008-03-25,2008-01-03
-7bur,2020-08-19,2020-04-08
-4bud,2013-10-30,2013-06-20
-3bu1,2008-04-01,2007-12-31
-3bul,2008-04-01,2008-01-03
-3bus,2008-03-25,2008-01-03
-8bub,2023-09-13,2022-11-30
-7buy,2020-04-29,2020-04-08
-8bud,2023-09-13,2022-11-30
-4bua,2013-10-30,2013-06-20
-5bur,2015-08-26,2015-06-04
-8bux,2023-12-13,2022-12-01
-8bu3,2023-09-13,2022-11-30
-8buz,2023-12-13,2022-12-01
-3bur,2008-04-01,2008-01-03
-3bum,2008-02-26,2008-01-03
-6bu7,2018-06-06,2017-12-08
-4bus,2013-10-30,2013-06-24
-4buz,2013-07-17,2013-06-24
-8buq,2023-09-13,2022-11-30
-2bu7,2006-02-02,2005-06-08
-8buk,2023-09-13,2022-11-30
-4buq,2014-02-19,2013-06-23
-1bu7,1998-09-23,1998-09-14
-3bux,2008-02-26,2008-01-03
-3bug,2008-03-11,2008-01-02
-2buu,2006-10-26,2005-06-17
-2bub,2006-01-23,2005-06-09
-2buo,2005-07-21,2005-06-17
-8buu,2023-04-05,2022-11-30
-6bup,2019-06-12,2017-12-11
-5bu8,2015-11-25,2015-06-03
-8buw,2023-12-13,2022-12-01
-6buy,2018-01-10,2017-12-11
-5bu6,2015-07-29,2015-06-03
-3bu7,2008-08-12,2008-01-02
-3buz,2008-05-13,2008-01-04
-7bu1,2021-04-07,2020-04-03
-5bul,2016-03-09,2015-06-04
-6bun,2019-06-12,2017-12-11
-2bue,2008-09-02,2008-03-20
-2buw,2006-10-26,2005-06-20
-4bu7,2013-10-30,2013-06-20
-4buu,2013-10-30,2013-06-24
-5bud,2015-07-08,2015-06-03
-7buz,2021-04-14,2020-04-08
-5buo,2016-07-13,2015-06-04
-8bu4,2023-09-13,2022-11-30
-6buo,2019-06-12,2017-12-11
-8buo,2023-09-13,2022-11-30
-8bus,2023-09-13,2022-11-30
-8bue,2023-09-13,2022-11-30
-1buv,1999-09-02,1998-09-07
-7bu6,2020-12-02,2020-04-04
-6buq,2019-06-12,2017-12-11
-4bub,2013-07-17,2013-06-20
-7bu8,2020-05-13,2020-04-05
-5buk,2016-03-09,2015-06-03
-3bup,2008-07-01,2008-01-03
-8bum,2023-09-20,2022-11-30
-3buv,2008-04-01,2008-01-03
-4buw,2013-10-30,2013-06-24
-6bul,2018-12-12,2017-12-10
-6bu1,2018-09-05,2017-12-08
-5bui,2015-07-15,2015-06-03
-8bun,2023-09-13,2022-11-30
-6bu3,2018-06-13,2017-12-08
-3bun,2008-02-26,2008-01-03
-2bun,2005-12-07,2005-06-15
-8buc,2023-09-13,2022-11-30
-1bud,1999-09-07,1998-09-03
-3bu5,2008-02-19,2007-12-31
-1bux,1999-04-27,1998-09-07
-4buo,2014-01-29,2013-06-21
-2buc,2006-01-23,2005-06-09
-1bu3,1999-08-10,1998-08-30
-8buh,2023-09-13,2022-11-30
-4bui,2013-10-30,2013-06-20
-2bui,2005-06-16,2005-06-13
-1bui,1999-09-02,1998-09-04
-5bus,2015-08-26,2015-06-04
-5buh,2016-06-08,2015-06-03
-5buu,2016-02-17,2015-06-04
-7bud,2020-05-13,2020-04-06
-5buq,2015-08-26,2015-06-04
-7bu9,2020-10-14,2020-04-05
-4bul,2013-08-07,2013-06-20
-2buy,2006-10-26,2005-06-20
-1bu4,1999-02-16,1998-09-11
-7bu5,2021-04-07,2020-04-04
-3buk,2008-07-15,2008-01-02
-8bu5,2023-09-13,2022-11-30
-8bu6,2023-09-13,2022-11-30
-5bua,2016-07-06,2015-06-03
-2bur,2006-09-05,2005-06-17
-4bu6,2013-10-30,2013-06-20
-7buh,2021-04-07,2020-04-06
-8bua,2023-09-13,2022-11-30
-2buk,2005-08-18,2005-06-14
-8bug,2023-09-13,2022-11-30
-5buj,2015-07-15,2015-06-03
-2bu6,2006-02-02,2005-06-08
-3bu4,1998-09-23,1998-09-14
-2buf,2005-12-13,2005-06-12
-7bu2,2020-05-13,2020-04-03
-1buc,1995-04-20,1994-09-06
-1bup,1998-09-09,1998-09-03
-2bum,2006-09-05,2005-06-14
-2buv,2006-09-04,2005-06-17
-3buw,2008-02-26,2008-01-03
-6bur,2019-06-12,2017-12-11
-4but,2013-10-30,2013-06-24
-1bu8,1998-12-23,1998-09-14
-4buf,2013-10-30,2013-06-20
-7buj,2020-09-02,2020-04-07
-1bul,1998-12-30,1998-09-04
-7buq,2020-09-02,2020-04-07
-3bub,2008-07-01,2008-01-02
-3bu0,2008-04-22,2007-12-31
-3buj,2008-04-29,2008-01-02
-8bui,2023-09-13,2022-11-30
-8bu1,2023-09-13,2022-11-30
-1buq,1999-01-20,1998-09-04
-8bu2,2023-09-13,2022-11-30
-5buc,2016-06-15,2015-06-03
-2but,2006-09-05,2005-06-17
-4bu4,1998-09-23,1998-09-14
-7buc,2020-11-11,2020-04-06
-2bug,2006-03-16,2005-06-13
-4bur,2014-07-09,2013-06-23
-6bux,2018-07-18,2017-12-11
-7bug,2021-04-07,2020-04-06
-3bui,2008-07-01,2008-01-02
-4bux,2013-10-30,2013-06-24
-6buw,2018-11-14,2017-12-11
-8buv,2023-12-13,2022-11-30
-6bum,2019-06-12,2017-12-11
-2bu8,2006-02-02,2005-06-08
-8bu9,2023-09-13,2022-11-30
-7bu3,2020-05-13,2020-04-03
-2bu2,2006-02-02,2005-06-08
-8buf,2023-09-13,2022-11-30
-1bun,1996-04-03,1995-10-15
-5bu5,2015-06-24,2015-06-03
-2bu3,2005-12-14,2005-06-08
-8bup,2023-09-13,2022-11-30
-5bu7,2016-06-08,2015-06-03
-3buh,2008-03-11,2008-01-02
-7bua,2020-05-13,2020-04-06
-4buy,2013-10-30,2013-06-24
-8but,2023-09-13,2022-11-30
-8bur,2023-09-13,2022-11-30
-7bum,2020-09-02,2020-04-07
-7buk,2021-04-07,2020-04-07
-6buv,2018-12-12,2017-12-11
-1f55,2003-07-15,2000-06-13
-3f5f,2008-12-16,2008-11-03
-4f50,2013-01-02,2012-05-11
-6f51,2018-06-06,2017-11-30
-8f5q,2023-09-27,2022-11-15
-7f5d,2022-06-29,2021-06-21
-4f5x,2012-10-24,2012-05-13
-1f5f,2000-09-06,2000-06-14
-2f5s,2006-03-07,2005-11-26
-8f5t,2023-05-24,2022-11-15
-1f5n,2000-09-27,2000-06-15
-2f5v,2006-06-13,2005-11-28
-6f58,2017-12-13,2017-12-01
-7f51,2022-03-16,2021-06-21
-3f5x,2009-02-03,2008-11-04
-3f5l,2009-11-03,2008-11-04
-5f55,2016-06-15,2015-12-04
-2f58,1999-02-09,1998-10-23
-4f5c,2012-08-22,2012-05-13
-8f5v,2023-04-05,2022-11-15
-8f5y,2024-02-21,2022-11-15
-5f59,2016-02-24,2015-12-04
-2f56,2006-04-25,2005-11-25
-4f56,2012-06-20,2012-05-11
-2f5z,2006-01-17,2005-11-28
-9f5f,2024-05-08,2024-04-28
-7f5x,2022-04-06,2021-06-23
-7f53,2021-11-03,2021-06-21
-6f5s,2018-12-12,2017-12-02
-8f5m,2024-01-17,2022-11-14
-6f5h,2018-04-11,2017-12-01
-2f5h,2006-05-30,2005-11-25
-7f5h,2022-06-29,2021-06-22
-1f5r,2001-07-04,2000-06-15
-1f5l,2001-06-15,2000-06-15
-1f5e,2001-09-28,2000-06-14
-2f5n,2006-03-07,2005-11-26
-2f5o,2006-03-07,2005-11-26
-7f50,2022-06-29,2021-06-21
-8f55,2023-02-01,2022-11-11
-2f53,2006-04-25,2005-11-25
-8f5k,2023-01-04,2022-11-14
-4f5p,2012-12-12,2012-05-13
-1f5a,2000-09-13,2000-06-13
-8f58,2023-02-01,2022-11-12
-8f5x,2023-11-29,2022-11-15
-3f53,2009-07-28,2008-11-03
-1f5p,2000-06-28,2000-06-15
-4f5w,2012-06-27,2012-05-13
-2f5x,2006-01-24,2005-11-28
-8f5z,2023-06-28,2022-11-15
-6f5w,2018-01-31,2017-12-04
-7f5t,2022-05-18,2021-06-22
-6f56,2019-03-20,2017-11-30
-8f5s,2023-07-05,2022-11-15
-7f5c,2022-06-29,2021-06-21
-3f5v,2009-02-10,2008-11-04
-1f5y,2000-08-30,2000-06-18
-8f5w,2023-02-01,2022-11-15
-5f5q,2016-10-26,2015-12-04
-6f57,2018-01-31,2017-12-01
-8f5i,2023-10-11,2022-11-14
-5f52,2016-04-06,2015-12-04
-1f5s,2001-06-20,2000-06-15
-5f5a,2015-12-16,2015-12-04
-5f5e,2016-02-24,2015-12-04
-2f5f,2006-03-07,2005-11-25
-8f5l,2023-01-04,2022-11-14
-1f5o,2000-08-30,2000-06-15
-3f5p,2008-12-30,2008-11-04
-7f5p,2022-06-29,2021-06-22
-2f5b,2003-07-08,1999-04-09
-7f5g,2022-05-25,2021-06-22
-5f5w,2016-05-11,2015-12-04
-6f5n,2018-12-12,2017-12-01
-7f5r,2022-06-22,2021-06-22
-6f59,2017-12-13,2017-12-01
-5f5c,2015-12-30,2015-12-04
-8f5f,2023-07-05,2022-11-14
-7f5q,2022-06-29,2021-06-22
-1f5t,2000-09-25,2000-06-15
-6f5k,2018-12-12,2017-12-01
-4f51,2013-05-15,2012-05-11
-4f5n,2012-12-12,2012-05-13
-2f55,2005-12-06,2005-11-25
-4f5y,2012-06-27,2012-05-13
-9f5e,2024-05-08,2024-04-28
-6f5z,2018-07-11,2017-12-04
-8f5j,2023-07-05,2022-11-14
-9f5k,2024-05-08,2024-04-29
-5f5g,2016-04-06,2015-12-04
-7f56,2021-09-29,2021-06-21
-9f5c,2024-05-08,2024-04-28
-5f5b,2016-02-17,2015-12-04
-6f5m,2018-08-08,2017-12-01
-9f54,2024-05-08,2024-04-28
-3f5w,2010-05-19,2008-11-04
-8f51,2023-02-01,2022-11-11
-2f54,2006-04-25,2005-11-25
-2f5t,2006-02-21,2005-11-27
-3f5g,2009-03-24,2008-11-03
-3f5j,2009-11-03,2008-11-03
-9f5g,2024-05-08,2024-04-28
-1f56,2000-11-01,2000-06-13
-5f5i,2015-12-30,2015-12-04
-2f5p,2006-03-07,2005-11-26
-5f5n,2016-12-21,2015-12-04
-7f58,2021-11-03,2021-06-21
-5f53,2016-12-14,2015-12-04
-8f5o,2022-12-21,2022-11-14
-6f5l,2018-12-12,2017-12-01
-3f5m,2008-11-25,2008-11-04
-8f5b,2023-11-22,2022-11-13
-7f5f,2022-01-19,2021-06-22
-3f5a,2009-07-28,2008-11-03
-4f53,2012-07-11,2012-05-11
-7f59,2021-09-29,2021-06-21
-8f57,2023-02-01,2022-11-12
-1f50,2000-08-09,2000-06-10
-1f5v,2001-02-14,2000-06-17
-6f5p,2018-09-19,2017-12-02
-2f5d,2006-03-07,2005-11-25
-8f5p,2022-12-21,2022-11-14
-6f5u,2018-01-03,2017-12-03
-9f53,2024-05-08,2024-04-28
-1f51,2000-08-23,2000-06-11
-5f56,2016-06-15,2015-12-04
-7f5i,2022-05-04,2021-06-22
-1f57,2000-09-06,2000-06-13
-2f57,2005-12-13,2005-11-25
-5f5k,2016-02-10,2015-12-04
-3f5h,2009-01-27,2008-11-03
-6f5r,2018-12-12,2017-12-02
-5f5j,2016-02-10,2015-12-04
-7f57,2021-09-29,2021-06-21
-4f5r,2012-12-12,2012-05-13
-7f5e,2022-06-29,2021-06-21
-5f5r,2016-03-02,2015-12-04
-7f55,2021-11-03,2021-06-21
-4f5d,2012-06-27,2012-05-13
-7f54,2021-11-03,2021-06-21
-2f5q,2006-03-07,2005-11-26
-7f5s,2022-06-22,2021-06-22
-7f5j,2022-06-29,2021-06-22
-4f5q,2012-12-12,2012-05-13
-7f5b,2021-09-29,2021-06-21
-1f52,2000-06-28,2000-06-12
-5f5z,2017-04-05,2015-12-04
-2f59,2006-11-28,2005-11-25
-4f5o,2012-12-12,2012-05-13
-2f5w,2006-04-25,2005-11-28
-6f5q,2018-12-12,2017-12-02
-5f5x,2015-12-30,2015-12-04
-3f5b,2008-11-18,2008-11-03
-6f5v,2019-03-13,2017-12-03
-5f54,2016-06-15,2015-12-04
-8f5a,2024-05-22,2022-11-12
-4f52,2012-09-19,2012-05-11
-3f5u,2009-03-24,2008-11-04
-3f5k,2009-11-03,2008-11-03
-7f5a,2021-09-29,2021-06-21
-8f5n,2023-03-08,2022-11-14
-4f5b,2012-10-03,2012-05-12
-9f50,2024-05-08,2024-04-28
-3f5o,2009-08-18,2008-11-04
-8f5u,2023-05-24,2022-11-15
-6f5t,2018-12-12,2017-12-02
-6f5d,2018-02-21,2017-12-01
-2f5e,2006-03-07,2005-11-25
-3f5e,2009-07-28,2008-11-03
-2f5c,2006-03-07,2005-11-25
-5f58,2016-12-07,2015-12-04
-3f58,1999-02-09,1998-10-23
-5wa0,2017-10-25,2017-06-24
-4wag,2015-05-20,2014-08-29
-3wab,2013-10-02,2013-05-01
-8wak,2023-12-06,2023-09-07
-4wak,2014-12-31,2014-08-29
-4wad,2015-02-25,2014-08-29
-3wav,2013-07-31,2013-05-09
-3wax,2013-07-31,2013-05-09
-8wa7,2024-01-24,2023-09-07
-2waj,2009-03-31,2009-02-08
-4wa5,2015-01-14,2014-08-28
-1wad,1997-01-27,1996-01-10
-4wa3,2015-01-14,2014-08-28
-1wa3,2005-01-26,2004-10-22
-8wap,2023-12-06,2023-09-08
-5way,2017-07-05,2017-06-27
-1wa5,2004-12-13,2004-10-23
-7wan,2022-02-02,2021-12-14
-1wat,1994-12-20,1993-03-09
-5wad,2017-12-06,2017-06-26
-5wap,2018-01-03,2017-06-26
-1wao,2005-02-22,2004-10-27
-8wa8,2024-01-24,2023-09-07
-5wai,2018-03-14,2017-06-26
-7wah,2022-06-15,2021-12-14
-1wap,1995-06-03,1995-02-03
-2wa8,2009-04-28,2009-02-03
-8wao,2023-12-06,2023-09-07
-1wax,2005-01-27,2004-10-28
-5wa7,2018-01-03,2017-06-25
-5wam,2017-12-06,2017-06-26
-6waq,2020-04-01,2020-03-25
-7wao,2022-12-21,2021-12-14
-3wad,2014-06-04,2013-05-02
-7waa,2022-03-16,2021-12-13
-8was,2023-12-06,2023-09-08
-5wal,2017-09-06,2017-06-26
-2war,2010-02-09,2009-02-13
-8wa5,2023-11-29,2023-09-07
-3wag,2014-06-04,2013-05-02
-1way,2005-01-27,2004-10-28
-3was,2013-09-04,2013-05-08
-5wa8,2017-10-18,2017-06-26
-3wae,2014-05-21,2013-05-02
-3wa8,2014-04-30,2013-04-28
-4wal,2014-12-17,2014-08-29
-4wan,2014-12-17,2014-08-29
-3wak,2013-10-30,2013-05-03
-4wa2,2015-01-14,2014-08-28
-4wam,2014-12-31,2014-08-29
-7waj,2022-12-21,2021-12-14
-4waf,2014-12-31,2014-08-29
-6wa8,2020-09-16,2020-03-24
-6wau,2020-08-26,2020-03-26
-7wae,2022-09-07,2021-12-14
-5wa6,2018-05-02,2017-06-25
-4wa4,2015-01-14,2014-08-28
-4wa9,2015-02-11,2014-08-28
-8wa1,2024-03-13,2023-09-06
-2wad,2009-02-24,2009-02-05
-1wa0,2005-01-04,2004-10-22
-8waz,2023-12-06,2023-09-08
-4wa6,2015-03-04,2014-08-28
-8waw,2023-12-06,2023-09-08
-1wam,2006-05-24,2004-10-27
-8wax,2023-12-06,2023-09-08
-7wa3,2022-08-17,2021-12-11
-3way,2013-07-31,2013-05-09
-7wa1,2022-08-17,2021-12-11
-5wan,2017-07-19,2017-06-26
-8wau,2023-12-06,2023-09-08
-5wae,2017-12-06,2017-06-26
-8wal,2023-12-06,2023-09-07
-4wat,2014-10-22,2014-09-01
-5waw,2017-11-08,2017-06-27
-7waq,2022-12-21,2021-12-14
-2wag,2009-06-23,2009-02-06
-3wah,2014-01-29,2013-05-02
-8wat,2023-12-06,2023-09-08
-3wat,2013-09-04,2013-05-08
-7wam,2022-02-02,2021-12-14
-8wav,2023-12-06,2023-09-08
-6wad,2020-09-02,2020-03-25
-4wa1,2015-01-14,2014-08-28
-4wai,2014-12-10,2014-08-29
-5wa9,2017-10-18,2017-06-26
-7wak,2022-12-21,2021-12-14
-7wab,2022-01-12,2021-12-14
-4wa7,2015-06-10,2014-08-28
-7was,2022-12-21,2021-12-14
-2wa2,2009-08-04,2009-02-02
-1wae,2004-10-28,2004-10-26
-6wab,2021-04-07,2020-03-25
-7wal,2022-12-21,2021-12-14
-4wab,2014-12-10,2014-08-29
-2wat,2009-08-25,2009-02-15
-3waw,2013-07-31,2013-05-09
-6was,2021-03-31,2020-03-26
-6wak,2021-03-31,2020-03-25
-7war,2022-12-21,2021-12-14
-1wav,1997-02-28,1996-02-28
-5wa5,2018-07-04,2017-06-24
-8waq,2023-12-06,2023-09-08
-5wat,2018-02-07,2017-06-27
-1wa6,2005-10-26,2004-10-25
-1wa2,2005-01-04,2004-10-22
-7waf,2022-09-07,2021-12-14
-2wa4,2010-04-21,2009-02-02
-4wa0,2015-03-04,2014-08-28
-6waa,2020-07-15,2020-03-24
-3wa2,2013-09-11,2013-04-22
-3wa3,2013-09-11,2013-04-22
-1war,2005-07-06,2004-10-28
-6wao,2021-08-04,2020-03-25
-7wa0,2022-06-15,2021-12-11
-5wau,2017-08-09,2017-06-27
-5waf,2017-12-06,2017-06-26
-5wa4,2017-11-22,2017-06-24
-5wac,2017-12-06,2017-06-26
-2wab,2009-03-24,2009-02-04
-8wa0,2024-03-13,2023-09-06
-5wag,2017-12-06,2017-06-26
-5wak,2018-03-14,2017-06-26
-3war,2013-10-30,2013-05-07
-3wa4,2014-02-26,2013-04-23
-8way,2023-12-06,2023-09-08
-4wae,2015-05-20,2014-08-29
-2wae,2009-02-24,2009-02-05
-1waf,1998-01-14,1997-04-13
-8wam,2023-09-27,2023-09-07
-8war,2023-12-06,2023-09-08
-3waj,2013-10-30,2013-05-03
-2wap,2009-05-05,2009-02-11
-1waa,2006-07-05,2004-10-25
-8waa,2024-01-24,2023-09-07
-3wa5,2013-10-02,2013-04-26
-7wad,2022-09-07,2021-12-14
-2waq,2009-05-19,2009-02-11
-7wa4,2022-04-27,2021-12-12
-6war,2020-04-08,2020-03-25
-4wav,2015-09-23,2014-09-02
-2waz,2010-03-31,2009-02-19
-8wan,2023-12-06,2023-09-07
-1waj,1998-01-14,1997-04-13
-3wau,2013-09-04,2013-05-08
-2wao,2009-10-06,2009-02-10
-2wah,2009-03-10,2009-02-06
-4was,2015-03-18,2014-08-31
-1waw,2005-01-28,2004-10-28
-4waj,2014-12-31,2014-08-29
-5wav,2017-11-08,2017-06-27
-2wa9,2009-04-28,2009-02-03
-3waz,2014-01-29,2013-05-10
-6wan,2020-06-17,2020-03-25
-8wa9,2024-01-24,2023-09-07
-7wa2,2022-06-15,2021-12-11
-8wa2,2024-04-10,2023-09-06
-6wa2,2021-03-31,2020-03-24
-2wa3,2010-04-21,2009-02-02
-1wa1,2005-01-04,2004-10-22
-2gnu,2006-11-07,2006-04-11
-3gn1,2009-12-29,2009-03-16
-6gnf,2018-07-25,2018-05-30
-3gnw,2009-10-20,2009-03-18
-6gn7,2018-10-17,2018-05-30
-4gnd,2013-01-02,2012-08-17
-7gn6,2023-11-08,2023-08-11
-4gnl,2013-07-03,2012-08-17
-8gne,2023-03-22,2022-08-23
-5gn7,2017-07-26,2016-07-19
-8gn0,2023-07-05,2022-08-22
-4gna,2013-04-10,2012-08-17
-2gnt,2006-07-25,2006-04-11
-2gnv,2006-04-25,2006-04-11
-3gnc,2009-07-07,2009-03-16
-7gnr,2023-11-08,2023-08-11
-5gnx,2017-04-12,2016-07-25
-1gnw,1997-09-17,1996-09-15
-6gnm,2018-07-11,2018-05-31
-4gn9,2013-04-10,2012-08-17
-1gnf,1999-06-08,1998-10-12
-1gnp,1995-07-31,1995-05-11
-7gnh,2023-11-08,2023-08-11
-1gn6,2001-10-05,2001-10-03
-4gn7,2013-04-10,2012-08-17
-4gno,2013-07-03,2012-08-17
-3gnr,2009-07-21,2009-03-17
-7gno,2023-11-08,2023-08-11
-2gna,2006-05-09,2006-04-09
-7gnl,2023-11-08,2023-08-11
-4gne,2013-01-02,2012-08-17
-3gn8,2009-09-22,2009-03-16
-2gnh,2006-05-23,2006-04-10
-7gna,2023-11-08,2023-08-11
-4gn0,2013-09-11,2012-08-16
-2gn3,2006-07-25,2006-04-09
-7gn3,2023-11-08,2023-08-11
-3gns,2009-10-20,2009-03-18
-6gna,2018-12-12,2018-05-30
-7gnx,2023-11-29,2023-08-24
-3gn7,2010-03-16,2009-03-16
-7gn7,2023-11-08,2023-08-11
-7gn9,2023-11-08,2023-08-11
-6gng,2018-07-25,2018-05-30
-5gnk,2017-04-05,2016-07-21
-7gnd,2023-11-08,2023-08-11
-4gnf,2013-01-02,2012-08-17
-6gnk,2018-09-26,2018-05-31
-7gns,2023-11-08,2023-08-11
-8gn3,2023-08-30,2022-08-22
-1gnz,2001-11-29,2001-10-11
-8gng,2023-03-22,2022-08-23
-1gno,1996-11-08,1996-05-04
-4gnm,2013-07-03,2012-08-17
-7gnv,2023-11-29,2023-08-24
-4gnk,2013-02-06,2012-08-17
-6gnd,2018-12-12,2018-05-30
-7gnq,2023-11-08,2023-08-11
-7gnw,2023-11-29,2023-08-24
-1gn4,2001-10-05,2001-10-02
-2gn6,2006-05-09,2006-04-09
-4gnw,2013-09-18,2012-08-17
-3gn0,2010-02-23,2009-03-15
-4gn8,2013-04-10,2012-08-17
-1gnm,1996-11-08,1996-05-04
-7gnp,2023-11-08,2023-08-11
-2gnw,2006-04-25,2006-04-11
-1gn2,2001-10-05,2001-10-02
-1gn8,2002-01-17,2001-10-03
-4gnc,2013-04-10,2012-08-17
-2gn8,2006-05-09,2006-04-09
-5gnl,2017-05-17,2016-07-22
-5gnd,2016-09-21,2016-07-20
-2gnb,2006-07-25,2006-04-09
-6gnv,2018-10-10,2018-05-31
-5gnm,2017-05-17,2016-07-22
-5gn8,2016-12-14,2016-07-19
-5gnr,2016-11-23,2016-07-24
-6gn6,2018-12-26,2018-05-30
-6gnh,2018-09-26,2018-05-30
-2gnn,2006-05-09,2006-04-10
-2gn2,2006-11-07,2006-04-09
-6gnr,2018-07-11,2018-05-31
-1gnh,1997-01-27,1996-03-01
-7gn4,2023-11-08,2023-08-11
-1gne,1994-11-30,1994-06-16
-7gnc,2023-11-08,2023-08-11
-8gni,2023-01-18,2022-08-24
-7gn8,2023-11-08,2023-08-11
-7gnn,2023-11-08,2023-08-11
-8gnk,2023-05-31,2022-08-24
-6gnt,2018-09-26,2018-05-31
-5gnw,2017-06-14,2016-07-25
-4gnr,2012-09-05,2012-08-17
-2gnk,1999-07-23,1998-07-14
-7gnz,2023-11-29,2023-08-24
-2gn9,2006-05-09,2006-04-09
-1gn3,2001-10-05,2001-10-02
-5gn9,2017-07-26,2016-07-19
-6gnn,2018-09-26,2018-05-31
-8gn9,2022-12-07,2022-08-23
-1gnq,1995-07-31,1995-05-11
-2gn4,2006-05-09,2006-04-09
-6gns,2018-09-26,2018-05-31
-4gnb,2013-04-10,2012-08-17
-2gnf,2006-05-23,2006-04-10
-6gnu,2018-09-26,2018-05-31
-7gng,2023-11-08,2023-08-11
-2gni,2006-05-23,2006-04-10
-8gn4,2023-08-30,2022-08-22
-4gny,2013-02-13,2012-08-17
-5gn5,2017-07-26,2016-07-19
-7gne,2023-11-08,2023-08-11
-7gn5,2023-11-08,2023-08-11
-1gny,2001-11-29,2001-10-10
-7gnf,2023-11-08,2023-08-11
-4gng,2013-01-02,2012-08-17
-2gn1,2006-11-07,2006-04-09
-1gn1,2002-06-18,2001-10-01
-7gnm,2023-11-08,2023-08-11
-2gnd,2006-07-25,2006-04-10
-3gn6,2009-03-31,2009-03-16
-6gne,2018-07-25,2018-05-30
-7gn2,2023-11-08,2023-08-11
-4gnq,2013-07-03,2012-08-17
-6gnw,2018-07-11,2018-05-31
-2gnl,2006-05-23,2006-04-10
-6gnq,2019-06-12,2018-05-31
-5gnt,2016-11-23,2016-07-24
-7gnu,2023-11-08,2023-08-11
-7gn1,2023-11-08,2023-08-11
-3gn4,2009-09-08,2009-03-16
-6gnj,2018-09-26,2018-05-31
-5gn6,2017-07-26,2016-07-19
-2gns,2006-04-25,2006-04-11
-1gnx,2002-10-17,2001-10-10
-3gn5,2010-01-12,2009-03-16
-2gn0,2006-11-07,2006-04-09
-8gnj,2023-01-18,2022-08-24
-1gnr,1995-07-31,1995-05-11
-6gnp,2018-07-11,2018-05-31
-7gnj,2023-11-08,2023-08-11
-8gn1,2023-07-05,2022-08-22
-4gnx,2013-02-20,2012-08-17
-2gnj,2006-05-23,2006-04-10
-3gni,2009-06-16,2009-03-17
-7gnt,2023-11-08,2023-08-11
-4gnz,2013-01-23,2012-08-17
-7gn0,2023-11-08,2023-08-11
-7gny,2023-11-29,2023-08-24
-3gnq,2009-03-24,2009-03-17
-8gna,2023-01-18,2022-08-23
-3gn2,2009-12-29,2009-03-16
-2gn7,2006-07-25,2006-04-09
-8gnh,2023-08-30,2022-08-23
-6gni,2018-10-17,2018-05-30
-6gno,2018-07-11,2018-05-31
-5gnf,2016-09-21,2016-07-20
-3gnd,2009-09-08,2009-03-17
-7gnb,2023-11-08,2023-08-11
-8gn2,2023-07-05,2022-08-22
-3gn9,2009-07-28,2009-03-16
-6gn1,2018-06-20,2018-05-29
-7gnk,2023-11-08,2023-08-11
-3gnv,2009-10-20,2009-03-18
-3gnz,2009-06-09,2009-03-18
-5gns,2016-12-07,2016-07-24
-2gno,2006-04-18,2006-04-10
-2gnm,2006-07-25,2006-04-10
-1gn0,2001-11-29,2001-10-01
-5gnb,2017-06-07,2016-07-20
-6gnb,2018-12-12,2018-05-30
-4gni,2012-12-05,2012-08-17
-5gny,2017-04-12,2016-07-25
-1gnu,2001-12-03,2001-10-09
-4gnp,2013-07-03,2012-08-17
-5gnz,2017-04-12,2016-07-25
-6gnc,2018-12-12,2018-05-30
-4gnv,2012-08-29,2012-08-17
-8gn7,2023-08-30,2022-08-23
-1gnn,1996-11-08,1996-05-04
-5gne,2017-08-30,2016-07-20
-3gnx,2010-03-23,2009-03-18
-7gni,2023-11-08,2023-08-11
-4gnj,2013-09-11,2012-08-17
-4pzi,2014-06-04,2014-03-31
-4pz0,2014-04-09,2014-03-28
-4pzt,2014-06-11,2014-03-31
-8pzm,2023-11-15,2023-07-27
-7pza,2022-11-02,2021-10-11
-2pzy,2007-07-31,2007-05-18
-4pzh,2015-01-28,2014-03-31
-5pz3,2017-03-22,2017-02-08
-1pz5,2003-11-18,2003-07-09
-5pzt,2019-01-09,2017-04-18
-2pz0,2008-04-01,2007-05-17
-7pzn,2021-12-08,2021-10-12
-5pza,2017-03-22,2017-02-08
-4pzl,2014-04-16,2014-03-31
-2pzk,2007-10-02,2007-05-18
-8pz6,2024-04-24,2023-07-27
-6pzq,2020-08-05,2019-08-01
-8pz4,2023-10-25,2023-07-26
-7pz7,2022-08-24,2021-10-11
-2pzf,2007-10-09,2007-05-18
-2pzj,2007-10-02,2007-05-18
-7pz1,2022-11-02,2021-10-11
-4pzk,2014-04-16,2014-03-31
-5pze,2017-03-22,2017-02-08
-8pz7,2023-08-30,2023-07-27
-4pz8,2014-06-25,2014-03-28
-7pzb,2022-11-02,2021-10-11
-5pz1,2017-03-22,2017-02-08
-6pzv,2020-07-15,2019-08-01
-2pz5,2007-09-25,2007-05-17
-8pzb,2024-04-24,2023-07-27
-3pzc,2011-10-19,2010-12-14
-8pz5,2023-10-25,2023-07-27
-3pz3,2011-05-11,2010-12-14
-5pz6,2017-03-22,2017-02-08
-1pz8,2004-04-13,2003-07-10
-5pzj,2017-03-22,2017-02-08
-4pze,2015-04-22,2014-03-29
-7pzi,2021-12-08,2021-10-12
-6pzd,2019-12-04,2019-07-31
-7pzw,2022-11-02,2021-10-13
-5pzf,2017-03-22,2017-02-08
-5pzp,2017-05-10,2017-02-27
-5pzi,2017-03-22,2017-02-08
-2pzm,2007-10-02,2007-05-18
-5pzo,2017-05-10,2017-02-27
-8pzo,2024-01-17,2023-07-27
-6pzw,2019-12-04,2019-08-01
-5pzm,2017-05-10,2017-02-27
-7pzl,2021-12-08,2021-10-12
-1pzm,2004-07-27,2003-07-11
-5pzl,2017-05-10,2017-02-27
-7pzc,2022-01-26,2021-10-12
-4pz3,2014-09-17,2014-03-28
-2pzg,2007-10-09,2007-05-18
-7pzh,2022-05-25,2021-10-12
-7pz5,2022-08-24,2021-10-11
-7pz3,2022-08-24,2021-10-11
-4pzr,2014-06-11,2014-03-31
-7pzm,2021-12-08,2021-10-12
-7pzv,2022-11-02,2021-10-13
-1pza,1994-11-30,1994-09-06
-1pz7,2004-04-13,2003-07-10
-3pzs,2011-03-16,2010-12-14
-5pz0,2017-03-22,2017-02-08
-5pzw,2019-01-09,2017-04-16
-7pz0,2022-08-24,2021-10-11
-3pz4,2011-05-11,2010-12-14
-5pzg,2017-03-22,2017-02-08
-5pz8,2017-03-22,2017-02-08
-6pz1,2020-01-01,2019-07-31
-6pz4,2019-10-23,2019-07-31
-5pzu,2019-01-09,2017-04-18
-6pz8,2019-10-09,2019-07-31
-2pzr,2007-09-25,2007-05-18
-5pz4,2017-03-22,2017-02-08
-7pzf,2022-07-06,2021-10-12
-1pzb,1994-11-30,1994-08-03
-5pzk,2017-05-10,2017-02-27
-2pza,2007-07-31,2007-05-17
-4pzz,2014-09-10,2014-03-31
-5pz5,2017-03-22,2017-02-08
-5pzq,2019-01-09,2017-04-16
-6pzz,2019-12-04,2019-08-01
-7pzy,2022-05-18,2021-10-13
-1pzo,2004-03-09,2003-07-14
-5pzy,2019-01-09,2017-04-18
-3pzi,2011-12-28,2010-12-14
-5pzv,2019-01-09,2017-04-11
-1pzp,2004-03-09,2003-07-14
-5pzs,2019-01-09,2017-04-11
-4pzf,2014-04-23,2014-03-30
-3pzb,2012-01-04,2010-12-14
-6pzf,2019-12-04,2019-07-31
-7pzs,2022-11-02,2021-10-13
-3pzq,2011-12-28,2010-12-14
-3pzo,2011-12-28,2010-12-14
-5pzh,2017-03-22,2017-02-08
-2pzi,2007-07-24,2007-05-18
-5pz7,2017-03-22,2017-02-08
-6pzp,2020-08-05,2019-08-01
-3pze,2011-12-14,2010-12-14
-6pz9,2019-08-14,2019-07-31
-6pza,2019-08-14,2019-07-31
-5pzc,2017-03-22,2017-02-08
-7pz4,2022-08-24,2021-10-11
-8pz9,2023-08-30,2023-07-27
-1pzk,2004-03-09,2003-07-11
-6pzs,2020-02-05,2019-08-01
-2pz8,2007-07-31,2007-05-17
-1pzj,2004-03-09,2003-07-11
-4pz1,2015-03-11,2014-03-28
-6pzy,2019-12-04,2019-08-01
-5pzb,2017-03-22,2017-02-08
-3pz1,2011-05-11,2010-12-14
-3pz2,2011-05-11,2010-12-14
-3pzl,2011-01-19,2010-12-14
-7pz8,2022-08-24,2021-10-11
-1pzy,2003-09-02,2003-07-14
-1pz0,2004-03-30,2003-07-09
-8pzh,2024-01-17,2023-07-27
-8pzy,2023-11-15,2023-07-27
-7pzk,2021-12-08,2021-10-12
-4pzv,2014-07-16,2014-03-31
-3pza,2011-06-22,2010-12-14
-4pz6,2014-06-25,2014-03-28
-3pzh,2011-12-21,2010-12-14
-2pze,2007-10-09,2007-05-17
-4pz2,2015-03-18,2014-03-28
-1pz1,2004-03-30,2003-07-09
-3pzr,2012-01-04,2010-12-14
-1pzw,2003-11-04,2003-07-14
-1pzf,2004-02-24,2003-07-10
-5pzr,2019-01-09,2017-04-11
-4pzd,2015-02-11,2014-03-29
-6pzi,2019-08-14,2019-07-31
-5pzx,2019-01-09,2017-04-18
-7pzg,2022-05-25,2021-10-12
-8pz0,2023-11-15,2023-07-26
-2pzp,2007-09-25,2007-05-18
-1pzh,2004-02-24,2003-07-10
-3pzt,2011-09-14,2010-12-14
-4pzx,2014-05-14,2014-03-31
-2pzn,2008-05-27,2007-05-18
-7pzu,2022-11-02,2021-10-13
-3pzj,2011-01-19,2010-12-14
-8pzk,2024-01-03,2023-07-27
-1pz2,2003-10-07,2003-07-09
-7pzx,2022-11-23,2021-10-13
-5pzz,2019-01-09,2017-04-28
-8pz8,2024-04-24,2023-07-27
-6pzo,2020-02-05,2019-08-01
-7pzj,2022-03-02,2021-10-12
-3pzw,2011-01-19,2010-12-14
-6pz3,2019-11-20,2019-07-31
-5pz9,2017-03-22,2017-02-08
-6pz0,2021-02-03,2019-07-31
-1pzs,2004-07-27,2003-07-14
-7pz6,2022-08-24,2021-10-11
-2pzs,2007-07-17,2007-05-18
-6pze,2019-12-04,2019-07-31
-3pzp,2011-12-28,2010-12-14
-5pzd,2017-03-22,2017-02-08
-4pzs,2014-06-11,2014-03-31
-3pzz,2011-10-12,2010-12-14
-5pzn,2017-05-10,2017-02-27
-2pzl,2007-10-02,2007-05-18
-5pz2,2017-03-22,2017-02-08
-6pz2,2019-11-27,2019-07-31
-4pzy,2014-09-10,2014-03-31
-6pzu,2020-02-05,2019-08-01
-1pzg,2004-02-24,2003-07-10
-1pzi,2004-03-09,2003-07-11
-4pzw,2014-05-14,2014-03-31
-6pzr,2020-02-05,2019-08-01
-3pz0,2011-08-24,2010-12-13
-6pz5,2019-11-27,2019-07-31
-3uii,2012-02-01,2011-11-04
-1uis,2003-10-21,2003-07-21
-5uik,2017-03-22,2017-01-14
-6uig,2020-10-07,2019-09-30
-8ui1,2024-05-15,2023-10-09
-3uiq,2012-04-18,2011-11-05
-1ui7,2004-04-20,2003-07-15
-5uit,2017-05-24,2017-01-14
-5uii,2018-01-31,2017-01-14
-4uip,2015-11-25,2015-03-31
-7ui3,2024-02-21,2022-03-28
-5uiv,2017-08-09,2017-01-15
-7ui4,2023-02-22,2022-03-28
-5uiq,2017-05-24,2017-01-14
-7uin,2022-11-23,2022-03-29
-8uii,2024-05-29,2023-10-10
-1ui0,2003-10-14,2003-07-14
-7uiw,2022-11-09,2022-03-29
-4uiv,2015-04-22,2015-04-03
-5uil,2017-03-22,2017-01-14
-1uio,1997-06-24,1996-08-30
-1uin,2003-11-18,2003-07-17
-3uig,2012-02-01,2011-11-04
-6uiq,2020-08-12,2019-10-01
-4uir,2015-07-01,2015-04-02
-4uiw,2015-04-22,2015-04-03
-6uit,2019-12-25,2019-10-01
-8uin,2024-05-08,2023-10-10
-5uih,2017-11-22,2017-01-14
-3ui5,2011-12-07,2011-11-04
-4uia,2015-06-03,2015-03-27
-6ui9,2019-12-25,2019-09-30
-3uij,2012-02-01,2011-11-04
-4ui2,2015-05-06,2015-03-27
-6uik,2020-04-15,2019-10-01
-4uiy,2015-04-22,2015-04-03
-1ui8,2004-04-20,2003-07-15
-5uim,2017-03-22,2017-01-14
-3ui7,2011-12-21,2011-11-04
-8uiw,2024-04-10,2023-10-10
-3ui0,2011-12-28,2011-11-03
-1uik,2004-07-16,2003-07-16
-6uij,2019-12-04,2019-10-01
-6uiy,2020-05-06,2019-10-01
-5uiu,2017-05-24,2017-01-14
-5ui2,2017-01-25,2017-01-12
-7uih,2023-01-11,2022-03-29
-7uii,2023-04-12,2022-03-29
-5ui1,2018-01-17,2017-01-12
-3uix,2012-04-11,2011-11-06
-6ui4,2020-03-25,2019-09-30
-5uig,2017-02-08,2017-01-13
-5ui4,2018-01-17,2017-01-12
-4uib,2015-06-03,2015-03-27
-5uin,2017-03-22,2017-01-14
-4ui9,2015-06-17,2015-03-27
-6uip,2020-03-04,2019-10-01
-3uih,2012-02-01,2011-11-04
-4ui7,2016-04-13,2015-03-27
-5ui3,2018-01-17,2017-01-12
-5uid,2017-02-01,2017-01-13
-4uix,2015-04-22,2015-04-03
-7ui7,2023-03-08,2022-03-28
-6uif,2020-04-15,2019-09-30
-1uib,1997-11-26,1996-11-26
-6uia,2019-12-25,2019-09-30
-1uih,1997-11-26,1996-11-26
-7uio,2023-03-01,2022-03-29
-5ui0,2017-02-22,2017-01-12
-8ui0,2024-03-20,2023-10-09
-3ui6,2012-11-07,2011-11-04
-1uim,2003-11-18,2003-07-17
-6uiu,2020-05-06,2019-10-01
-3uim,2012-05-23,2011-11-05
-6uii,2019-12-04,2019-10-01
-4ui8,2016-04-13,2015-03-27
-1uiw,2003-08-12,2003-07-23
-7uiz,2022-11-09,2022-03-29
-3uic,2012-06-06,2011-11-04
-5uir,2017-05-24,2017-01-14
-5uij,2017-03-22,2017-01-14
-8ui6,2024-05-15,2023-10-10
-7ui5,2022-10-26,2022-03-28
-8ui9,2024-05-29,2023-10-10
-4ui3,2016-04-13,2015-03-27
-4ui4,2016-04-13,2015-03-27
-5ui9,2017-02-01,2017-01-13
-6ui2,2020-01-15,2019-09-30
-1uip,1997-06-24,1996-08-30
-6ui5,2020-10-07,2019-09-30
-5uip,2017-11-22,2017-01-14
-7uia,2023-04-05,2022-03-28
-8ui8,2024-05-29,2023-10-10
-8uis,2024-03-20,2023-10-10
-4uiu,2015-04-22,2015-04-03
-6uis,2019-12-25,2019-10-01
-7uib,2023-04-05,2022-03-29
-1uiv,2004-02-03,2003-07-22
-4ui5,2016-04-13,2015-03-27
-5ui8,2017-02-22,2017-01-13
-4uiz,2015-04-22,2015-04-03
-5uie,2017-04-12,2017-01-13
-7ui6,2023-03-08,2022-03-28
-3uik,2012-02-01,2011-11-04
-5uiz,2017-02-01,2017-01-16
-7uik,2023-03-01,2022-03-29
-4uil,2015-09-02,2015-03-30
-7uid,2023-04-05,2022-03-29
-5uio,2017-11-22,2017-01-14
-8uia,2024-02-14,2023-10-10
-4uii,2016-04-13,2015-03-30
-3uiw,2013-03-27,2011-11-06
-4ui6,2016-04-13,2015-03-27
-4uio,2015-07-15,2015-03-30
-7uix,2022-11-09,2022-03-29
-8uiq,2024-02-21,2023-10-10
-5uiw,2017-06-28,2017-01-15
-4uin,2015-09-02,2015-03-30
-7uiv,2022-11-09,2022-03-29
-6uio,2020-07-01,2019-10-01
-4uiq,2016-04-13,2015-03-31
-8uiv,2024-02-21,2023-10-10
-3uiv,2012-11-07,2011-11-06
-3uib,2012-09-19,2011-11-04
-6uil,2019-12-04,2019-10-01
-6uib,2020-07-15,2019-09-30
-6uir,2019-12-25,2019-10-01
-7uiy,2022-10-26,2022-03-29
-7uir,2022-04-06,2022-03-29
-8ui7,2024-05-29,2023-10-10
-6uim,2019-12-04,2019-10-01
-4uie,2016-04-13,2015-03-27
-4uit,2015-04-22,2015-04-03
-5uib,2017-01-25,2017-01-13
-5uia,2017-02-01,2017-01-13
-3uie,2012-01-25,2011-11-04
-5uis,2017-05-24,2017-01-14
-2enb,1994-05-31,1994-03-23
-3ens,2008-12-30,2008-09-25
-6enx,2017-11-01,2017-10-06
-8en7,2022-12-21,2022-09-28
-1en2,2000-06-21,2000-03-20
-2env,2008-04-08,2007-03-28
-6ent,2017-12-13,2017-10-06
-6eni,2019-02-06,2017-10-04
-9enz,2024-05-22,2024-03-14
-1ena,1994-05-31,1994-02-14
-1enc,1994-05-31,1994-02-14
-4enq,2012-05-02,2012-04-13
-5en1,2016-11-09,2015-11-09
-7enl,1992-04-15,1990-11-13
-4end,2013-07-17,2012-04-13
-4en4,2012-05-02,2012-04-12
-3ene,2008-10-14,2008-09-25
-2en9,2007-10-02,2007-03-28
-6enq,2018-03-14,2017-10-06
-8eni,2022-11-30,2022-09-30
-2enh,2007-10-02,2007-03-28
-6enc,2017-12-13,2017-10-04
-1en6,2001-06-27,2000-03-20
-3eni,2009-05-12,2008-09-25
-5enc,2016-04-27,2015-11-09
-3eno,2008-10-28,2008-09-25
-3en4,2008-10-14,2008-09-25
-5en2,2015-12-30,2015-11-09
-3env,2009-09-29,2008-09-26
-7en2,2021-12-22,2021-04-15
-4en0,2012-05-09,2012-04-12
-4en9,2012-06-06,2012-04-12
-7enu,2021-05-19,2021-04-19
-7enf,2022-04-06,2021-04-16
-2enz,2008-04-01,2007-03-28
-2eni,2007-10-02,2007-03-28
-1enu,2000-04-19,2000-03-21
-4enz,2013-04-17,2012-04-13
-1en7,2000-02-07,1999-02-07
-5enw,2016-11-09,2015-11-09
-6en9,2018-04-18,2017-10-04
-2ent,2008-04-01,2007-03-28
-8enp,2023-10-18,2022-09-30
-5eng,2016-11-23,2015-11-09
-7en5,2022-04-20,2021-04-16
-6end,2017-12-13,2017-10-04
-2enx,2007-05-29,2007-03-28
-4enw,2012-05-02,2012-04-13
-5eni,2016-04-27,2015-11-09
-6enu,2017-11-22,2017-10-06
-3enw,2009-09-29,2008-09-26
-8enh,2024-03-27,2022-09-30
-3ena,2009-08-11,2008-09-25
-1en5,2001-06-27,2000-03-20
-6en4,2018-06-20,2017-10-04
-6en5,2017-12-20,2017-10-04
-5enq,2016-04-06,2015-11-09
-4eng,1997-06-16,1996-10-17
-8ens,2024-01-31,2022-09-30
-7enj,2021-05-19,2021-04-17
-3enr,2000-09-18,1999-02-11
-7end,2022-07-20,2021-04-16
-7ena,2021-05-26,2021-04-16
-2enc,2007-10-02,2007-03-28
-7enb,2021-07-14,2021-04-16
-2en4,2007-10-02,2007-03-28
-9enp,2024-05-29,2024-03-13
-6enb,2017-12-13,2017-10-04
-3en1,2009-03-17,2008-09-25
-3en8,2008-10-07,2008-09-25
-7enq,2022-05-04,2021-04-19
-7enn,2021-07-14,2021-04-18
-5enj,2016-04-27,2015-11-09
-5en3,2016-04-20,2015-11-09
-7ene,2022-07-20,2021-04-16
-5env,2015-11-25,2015-11-09
-4en8,2012-06-06,2012-04-12
-2enf,2007-10-02,2007-03-28
-4ene,2012-12-26,2012-04-13
-1eno,1996-10-14,1995-10-18
-1ens,1996-08-17,1996-03-20
-4en3,2012-10-31,2012-04-12
-6enz,2018-01-03,2017-10-07
-5enm,2016-10-05,2015-11-09
-2en8,2007-10-02,2007-03-28
-6enh,2019-04-10,2017-10-04
-2en5,2007-10-02,2007-03-28
-2en1,2007-10-02,2007-03-28
-4eny,2012-08-08,2012-04-13
-8enw,2024-01-31,2022-09-30
-7ent,2022-02-16,2021-04-19
-4enl,1992-04-15,1990-11-13
-1enq,1996-08-17,1996-03-20
-8en9,2022-11-02,2022-09-29
-8ene,2023-05-03,2022-09-29
-2enn,2008-04-01,2007-03-28
-5ene,2016-04-27,2015-11-09
-7en8,2022-07-20,2021-04-16
-4enx,2012-08-08,2012-04-13
-5enp,2016-04-06,2015-11-09
-6enp,2018-10-24,2017-10-05
-5enr,2016-04-06,2015-11-09
-2enr,1999-02-16,1998-07-14
-8enj,2023-10-18,2022-09-30
-6env,2017-12-13,2017-10-06
-1enz,1996-01-29,1995-01-27
-7en1,2021-12-22,2021-04-15
-2en2,2007-10-02,2007-03-28
-2en0,2007-10-02,2007-03-28
-7en3,2022-04-27,2021-04-15
-4env,2012-05-02,2012-04-13
-3enk,2008-10-28,2008-09-25
-1en4,2001-06-27,2000-03-20
-3eng,1997-06-16,1996-10-17
-8en8,2024-03-27,2022-09-29
-1enp,1996-10-14,1995-10-18
-7ens,2022-02-16,2021-04-19
-3enj,2009-02-03,2008-09-25
-7en9,2022-07-20,2021-04-16
-5enl,1992-04-15,1990-11-13
-5en4,2016-11-23,2015-11-09
-6enk,2018-05-02,2017-10-05
-3en3,2009-05-19,2008-09-25
-4ens,2012-05-02,2012-04-13
-7en7,2022-04-20,2021-04-16
-5enh,2016-04-27,2015-11-09
-6enl,1992-04-15,1990-11-13
-2en3,2007-10-02,2007-03-28
-3en9,2008-11-04,2008-09-25
-6enj,2017-11-22,2017-10-05
-2ena,2007-10-02,2007-03-28
-8enu,2023-08-09,2022-09-30
-1eny,1996-01-29,1995-01-27
-5enf,2016-04-27,2015-11-09
-5enk,2016-07-06,2015-11-09
-4ent,2012-05-02,2012-04-13
-4enr,2012-05-02,2012-04-13
-8enk,2023-08-16,2022-09-30
-4enh,2012-08-22,2012-04-13
-7enc,2021-05-26,2021-04-16
-5enz,2016-04-27,2015-11-09
-6en3,2018-06-13,2017-10-04
-9enq,2024-05-29,2024-03-13
-6en6,2018-03-07,2017-10-04
-8enc,2022-11-23,2022-09-29
-4en6,2012-06-06,2012-04-12
-7enh,2022-04-20,2021-04-17
-5eno,2016-04-06,2015-11-09
-8eng,2023-07-05,2022-09-29
-1enr,1996-08-17,1996-03-20
-4en7,2012-06-06,2012-04-12
-7eng,2022-04-06,2021-04-16
-4enp,2012-05-09,2012-04-13
-2ene,2007-10-02,2007-03-28
-6enn,2019-02-06,2017-10-05
-7enz,2022-03-09,2021-04-21
-7env,2022-03-09,2021-04-19
-6eng,2019-04-10,2017-10-04
-5en0,2016-08-10,2015-11-08
-6enm,2018-05-16,2017-10-05
-2en6,2007-10-02,2007-03-28
-5ens,2016-04-06,2015-11-09
-3en7,2008-10-14,2008-09-25
-6enw,2017-12-13,2017-10-06
-3enz,2009-08-04,2008-09-26
-3en5,2008-10-14,2008-09-25
-2en7,2007-10-02,2007-03-28
-4enu,2012-05-02,2012-04-13
-3en6,2008-10-14,2008-09-25
-5enn,2016-11-16,2015-11-09
-5ent,2016-04-06,2015-11-09
-3en2,2008-10-07,2008-09-25
-8ent,2023-06-28,2022-09-30
-6eny,2017-11-29,2017-10-07
-1enm,2000-06-21,2000-03-21
-5enb,2016-04-27,2015-11-09
-5ulh,2017-06-07,2017-01-24
-6ul9,2020-10-14,2019-10-07
-6ulw,2020-02-19,2019-10-08
-1ulf,2004-04-20,2003-09-12
-5ulv,2017-02-08,2017-01-25
-5uld,2017-05-17,2017-01-24
-3ul8,2012-04-04,2011-11-10
-7ul7,2022-06-15,2022-04-04
-6uli,2020-05-27,2019-10-08
-1uli,2004-09-28,2003-09-12
-6ula,2020-10-14,2019-10-07
-5ulj,2017-05-17,2017-01-24
-1ul1,2005-03-01,2003-09-05
-3ulu,2012-05-23,2011-11-11
-6ulg,2019-11-20,2019-10-08
-1ulj,2004-09-28,2003-09-12
-5ulb,2018-09-12,2017-01-24
-6ul8,2019-12-04,2019-10-07
-1uld,2004-04-20,2003-09-12
-6ulr,2020-05-27,2019-10-08
-4ulv,2015-04-08,2014-05-14
-1ul3,2003-12-16,2003-09-09
-3uld,2012-11-14,2011-11-10
-5uls,2017-09-27,2017-01-25
-1ulx,2004-08-31,2003-09-16
-7ulj,2023-04-12,2022-04-05
-7ul0,2023-03-08,2022-04-03
-3ul4,2012-11-28,2011-11-10
-3ulv,2012-05-23,2011-11-11
-5ult,2017-05-03,2017-01-25
-5ule,2017-05-17,2017-01-24
-5ul7,2017-05-17,2017-01-24
-5ulu,2018-01-31,2017-01-25
-7ul2,2022-06-29,2022-04-03
-7ulz,2022-04-27,2022-04-05
-5uln,2017-10-11,2017-01-25
-7ulv,2023-08-30,2022-04-05
-6ulb,2020-10-21,2019-10-07
-6ult,2021-02-24,2019-10-08
-1ul5,2004-03-09,2003-09-09
-1ulm,2003-12-23,2003-09-12
-7ult,2022-04-13,2022-04-05
-7ulf,2023-04-12,2022-04-04
-1ulv,2003-12-09,2003-09-16
-7ula,2022-12-14,2022-04-04
-7ul4,2022-06-29,2022-04-03
-3ulf,2012-04-11,2011-11-10
-6ulv,2020-12-02,2019-10-08
-6uly,2020-02-19,2019-10-08
-5ul5,2017-05-17,2017-01-24
-3ul7,2012-04-04,2011-11-10
-6ulc,2020-04-29,2019-10-07
-6uln,2020-05-27,2019-10-08
-3ul5,2012-11-28,2011-11-10
-6ul7,2021-04-07,2019-10-07
-8uld,2024-02-14,2023-10-16
-6ul2,2019-12-25,2019-10-06
-3ulq,2012-01-04,2011-11-11
-1ulw,2004-10-05,2003-09-16
-6ul5,2020-02-05,2019-10-06
-3ul9,2012-05-23,2011-11-10
-1ulb,1993-01-15,1991-11-05
-7uld,2023-04-12,2022-04-04
-5ull,1997-03-12,1997-01-09
-5ulx,2017-04-19,2017-01-25
-7ulu,2023-08-30,2022-04-05
-7ule,2023-04-12,2022-04-04
-6ulj,2020-10-14,2019-10-08
-3ulk,2012-10-17,2011-11-11
-7ul1,2023-03-08,2022-04-03
-7ulc,2022-12-21,2022-04-04
-6ulm,2021-03-17,2019-10-08
-3ul2,2012-11-14,2011-11-10
-5ulg,2017-05-17,2017-01-24
-5ul4,2017-04-19,2017-01-24
-7ull,2023-04-12,2022-04-05
-5ula,2017-03-22,2017-01-24
-7ul3,2022-06-29,2022-04-03
-6ulu,2020-03-04,2019-10-08
-5ul0,2017-02-15,2017-01-23
-3ule,2013-02-13,2011-11-10
-5uly,2018-08-08,2017-01-25
-3ula,2012-04-04,2011-11-10
-6uld,2019-10-16,2019-10-07
-1ule,2004-04-20,2003-09-12
-1ulc,2004-04-20,2003-09-12
-5ul9,2017-05-17,2017-01-24
-5ulp,2017-05-17,2017-01-25
-5ul1,2017-05-10,2017-01-23
-5ulk,2017-06-07,2017-01-24
-8ulg,2024-01-17,2023-10-16
-6ulx,2020-02-19,2019-10-08
-7ulk,2023-04-12,2022-04-05
-6ul0,2020-08-19,2019-10-06
-7ulx,2023-08-30,2022-04-05
-3ulg,2012-10-24,2011-11-10
-3uli,2013-08-14,2011-11-10
-1ulg,2004-04-20,2003-09-12
-1ul4,2004-03-09,2003-09-09
-5ulw,2017-04-19,2017-01-25
-6ulp,2020-08-19,2019-10-08
-5ul3,2017-04-19,2017-01-24
-6ulz,2020-02-19,2019-10-08
-6ull,2020-01-08,2019-10-08
-6ulq,2020-08-19,2019-10-08
-5uli,2017-05-17,2017-01-24
-5ybz,2018-10-03,2017-09-05
-1ybg,2005-02-15,2004-12-20
-6yb3,2021-02-24,2020-03-15
-7ybp,2022-11-16,2022-06-29
-2ybs,2011-03-30,2011-03-10
-2ybq,2011-06-01,2011-03-09
-7ybb,2023-07-05,2022-06-29
-4ybm,2015-06-24,2015-02-18
-6yb9,2020-07-08,2020-03-16
-1ybw,2005-02-15,2004-12-21
-6ybk,2020-11-18,2020-03-17
-6ybf,2020-08-12,2020-03-17
-1ybq,2005-04-26,2004-12-21
-8ybg,2024-02-28,2024-02-14
-2ybd,2011-03-16,2011-03-03
-5ybi,2018-06-20,2017-09-05
-6yb8,2020-07-08,2020-03-16
-7ybu,2023-07-05,2022-06-29
-2ybb,2011-10-19,2011-03-02
-5ybp,2018-01-24,2017-09-05
-2yb7,2011-08-17,2011-03-02
-5ybg,2018-01-17,2017-09-04
-2yb9,2011-05-25,2011-03-02
-1yb5,2004-12-28,2004-12-20
-6yba,2021-03-10,2020-03-16
-2ybk,2011-04-06,2011-03-08
-7yb2,2023-06-07,2022-06-28
-2ybp,2011-03-30,2011-03-09
-7ybr,2023-05-03,2022-06-29
-5ybl,2018-01-24,2017-09-05
-7ybg,2023-07-19,2022-06-29
-4ybz,2016-01-27,2015-02-19
-1ybh,2006-01-10,2004-12-20
-5yby,2018-10-03,2017-09-05
-4ybi,2015-04-01,2015-02-18
-6ybi,2020-08-12,2020-03-17
-5yb6,2018-02-07,2017-09-03
-6yb5,2021-02-24,2020-03-15
-1yb6,2005-12-20,2004-12-20
-2ybe,2011-04-27,2011-03-07
-6yb1,2021-04-07,2020-03-15
-5yba,2018-07-18,2017-09-04
-6ybs,2020-09-16,2020-03-17
-4yb7,2016-03-09,2015-02-18
-1ybk,2005-01-18,2004-12-21
-6ybz,2020-04-08,2020-03-18
-4ybh,2016-03-02,2015-02-18
-4ybj,2016-03-02,2015-02-18
-5ybo,2018-01-24,2017-09-05
-5ybt,2018-01-24,2017-09-05
-6ybj,2020-11-18,2020-03-17
-7ybx,2022-11-16,2022-06-30
-6ybw,2020-09-16,2020-03-18
-2ybf,2011-04-20,2011-03-08
-4ybr,2016-02-03,2015-02-19
-7ybc,2023-07-05,2022-06-29
-7ybl,2023-08-09,2022-06-29
-8ybh,2024-02-28,2024-02-14
-1ybm,2005-01-18,2004-12-21
-1ybo,2006-01-10,2004-12-21
-5yb7,2018-02-07,2017-09-03
-4yb4,2016-03-09,2015-02-18
-5ybn,2018-01-24,2017-09-05
-1yb1,2004-12-28,2004-12-18
-2ybg,2011-05-04,2011-03-08
-4ybn,2015-10-21,2015-02-18
-5ybr,2018-01-24,2017-09-05
-2ybu,2011-06-08,2011-03-10
-4ybg,2015-04-29,2015-02-18
-5yb1,2018-09-05,2017-09-02
-1ybu,2005-02-15,2004-12-21
-7ybi,2023-07-12,2022-06-29
-6ybo,2020-08-12,2020-03-17
-6yb6,2021-03-31,2020-03-16
-4ybk,2016-03-02,2015-02-18
-6ybh,2021-03-31,2020-03-17
-4ybu,2016-02-24,2015-02-19
-7ybm,2023-08-09,2022-06-29
-5ybb,2017-11-29,2017-09-04
-4ybp,2016-02-24,2015-02-19
-1yba,2005-04-26,2004-12-20
-5ybd,2018-11-14,2017-09-04
-6ybp,2020-10-28,2020-03-17
-7yb8,2023-07-05,2022-06-29
-6ybx,2020-08-12,2020-03-18
-1yb7,2005-12-20,2004-12-20
-7yb9,2023-07-05,2022-06-29
-6ybr,2020-08-12,2020-03-17
-4yb6,2016-03-09,2015-02-18
-2yb1,2011-03-16,2011-02-25
-6ybl,2020-11-18,2020-03-17
-5yb5,2018-09-05,2017-09-03
-5ybh,2018-06-20,2017-09-05
-4yb8,2016-01-27,2015-02-18
-4yb5,2016-03-09,2015-02-18
-7yb1,2023-06-07,2022-06-28
-7yb7,2023-11-15,2022-06-29
-6yb4,2020-05-06,2020-03-15
-4ybb,2015-03-18,2015-02-18
-7ybk,2023-09-06,2022-06-29
-5ybq,2018-01-24,2017-09-05
-7yba,2023-07-05,2022-06-29
-1yb0,2005-08-23,2004-12-18
-8ybe,2024-03-06,2024-02-13
-7ybh,2023-08-09,2022-06-29
-6ybg,2020-11-18,2020-03-17
-4ybt,2015-06-24,2015-02-19
-6ybu,2021-02-24,2020-03-17
-2ybo,2011-06-01,2011-03-08
-5yb8,2018-02-07,2017-09-03
-5ybf,2018-01-17,2017-09-04
-5ybs,2018-01-24,2017-09-05
-2yb0,2011-03-16,2011-02-25
-6ybq,2020-10-28,2020-03-17
-2yb5,2012-01-25,2011-03-01
-7ybo,2022-11-16,2022-06-29
-6ybb,2021-02-24,2020-03-16
-5yb0,2018-10-31,2017-09-02
-4ybs,2015-06-24,2015-02-19
-6yby,2020-04-08,2020-03-18
-1ybv,1997-10-15,1996-09-23
-2ybt,2011-06-08,2011-03-10
-7p3q,2022-05-11,2021-07-08
-7p3w,2022-02-02,2021-07-08
-2p3o,2007-08-28,2007-03-09
-1p3u,2003-12-09,2003-04-18
-4p3r,2014-05-14,2014-03-10
-6p3s,2020-05-27,2019-05-24
-4p3x,2014-04-02,2014-03-10
-3p3e,2011-01-05,2010-10-04
-4p3p,2015-03-11,2014-03-09
-6p3r,2020-05-27,2019-05-24
-4p3c,2014-12-17,2014-03-06
-7p3b,2021-12-22,2021-07-07
-2p3a,2007-04-24,2007-03-08
-4p3h,2014-07-23,2014-03-07
-8p36,2024-04-03,2023-05-17
-4p3v,2015-04-15,2014-03-10
-2p33,2007-06-19,2007-03-08
-3p3b,2011-06-29,2010-10-04
-4p3e,2014-04-16,2014-03-07
-4p31,2014-03-26,2014-03-05
-2p3d,2007-04-24,2007-03-08
-6p39,2020-05-27,2019-05-23
-6p3y,2020-02-12,2019-05-25
-6p3n,2019-08-14,2019-05-24
-1p39,1997-09-17,1996-12-16
-7p3n,2022-02-02,2021-07-08
-3p3h,2011-09-28,2010-10-04
-3p3u,2011-08-24,2010-10-05
-3p33,2011-11-23,2010-10-04
-2p3c,2007-04-24,2007-03-08
-2p34,2008-01-22,2007-03-08
-6p3m,2019-08-14,2019-05-24
-2p3n,2007-04-24,2007-03-09
-7p3c,2021-12-08,2021-07-07
-7p3s,2021-09-15,2021-07-08
-7p3f,2022-05-11,2021-07-07
-7p30,2022-02-02,2021-07-06
-7p3v,2021-11-03,2021-07-08
-3p3i,2010-10-20,2010-10-04
-1p3d,2003-07-15,2003-04-17
-1p3n,2003-10-07,2003-04-17
-4p3i,2014-04-02,2014-03-07
-6p3a,2020-05-27,2019-05-23
-7p3t,2021-12-15,2021-07-08
-3p3r,2011-08-24,2010-10-05
-4p35,2014-04-09,2014-03-05
-4p33,2014-03-26,2014-03-05
-1p33,2003-09-02,2003-04-16
-4p3w,2015-08-12,2014-03-10
-2p3b,2007-04-24,2007-03-08
-7p3h,2021-09-15,2021-07-07
-4p3k,2014-12-17,2014-03-08
-7p3l,2022-07-20,2021-07-08
-4p3q,2014-05-14,2014-03-10
-3p3l,2011-02-16,2010-10-05
-3p36,2011-04-27,2010-10-04
-4p3j,2014-06-04,2014-03-08
-3p3c,2011-01-05,2010-10-04
-3p32,2010-11-10,2010-10-04
-6p3u,2019-09-04,2019-05-24
-3p3q,2010-11-10,2010-10-05
-1p3t,2003-12-09,2003-04-18
-2p3g,2007-06-12,2007-03-08
-8p3e,2024-03-06,2023-05-17
-8p39,2023-09-13,2023-05-17
-4p32,2014-03-26,2014-03-05
-2p3t,2008-01-22,2007-03-09
-8p3l,2023-05-31,2023-05-18
-3p3z,2011-02-16,2010-10-05
-7p3d,2021-07-28,2021-07-07
-7p37,2022-05-11,2021-07-07
-2p3z,2007-03-20,2007-03-10
-4p38,2014-04-30,2014-03-06
-1p37,2003-10-07,2003-04-16
-2p3l,2007-08-28,2007-03-09
-6p35,2020-05-27,2019-05-22
-6p3h,2019-07-31,2019-05-23
-1p3v,2003-12-09,2003-04-18
-7p3i,2022-04-06,2021-07-07
-4p3o,2015-03-11,2014-03-09
-3p3o,2011-02-16,2010-10-05
-2p35,2007-04-10,2007-03-08
-2p3s,2008-01-22,2007-03-09
-3p3s,2011-08-24,2010-10-05
-3p3n,2010-11-24,2010-10-05
-3p3x,2011-02-16,2010-10-05
-2p3u,2007-09-11,2007-03-09
-6p3j,2019-07-31,2019-05-23
-2p3j,2008-03-11,2007-03-09
-3p35,2011-04-27,2010-10-04
-6p3w,2019-07-31,2019-05-24
-7p3e,2021-07-28,2021-07-07
-1p3y,2003-08-05,2003-04-19
-2p3p,2007-04-10,2007-03-09
-4p36,2014-04-09,2014-03-05
-2p3k,2008-03-11,2007-03-09
-4p3y,2014-06-18,2014-03-10
-3p3g,2011-01-05,2010-10-04
-7p36,2021-07-21,2021-07-07
-7p38,2021-11-03,2021-07-07
-7p39,2021-11-03,2021-07-07
-6p3z,2020-02-12,2019-05-25
-3p3j,2011-09-21,2010-10-05
-3p37,2011-04-27,2010-10-04
-1p3w,2003-07-22,2003-04-18
-8p3b,2024-04-03,2023-05-17
-2p3q,2007-08-28,2007-03-09
-4p30,2014-06-04,2014-03-05
-7p3u,2022-07-20,2021-07-08
-4p3n,2015-03-11,2014-03-09
-7p3j,2021-12-08,2021-07-07
-3p3t,2011-08-24,2010-10-05
-6p3t,2019-09-04,2019-05-24
-1p3j,2004-05-04,2003-04-17
-6p38,2020-05-27,2019-05-23
-8p37,2024-03-27,2023-05-17
-2p3i,2008-03-11,2007-03-09
-3p3y,2010-11-03,2010-10-05
-6p3p,2019-07-03,2019-05-24
-1p31,2003-07-15,2003-04-16
-2p3f,2007-11-06,2007-03-08
-8p3m,2023-06-07,2023-05-18
-7p3k,2021-10-27,2021-07-08
-3p3p,2010-11-24,2010-10-05
-6p3i,2019-06-05,2019-05-23
-7p31,2021-07-14,2021-07-06
-1p3h,2003-07-15,2003-04-17
-7p3g,2021-12-08,2021-07-07
-1p36,2003-10-07,2003-04-16
-8p3a,2023-07-05,2023-05-17
-6p3d,2020-09-23,2019-05-23
-6p3x,2020-02-12,2019-05-25
-7p32,2022-07-13,2021-07-06
-6p3v,2019-09-04,2019-05-24
-6p3o,2019-08-14,2019-05-24
-4p3d,2014-12-17,2014-03-07
-2p37,2007-11-06,2007-03-08
-7p35,2021-07-21,2021-07-07
-4p3l,2014-04-02,2014-03-09
-3p34,2011-04-27,2010-10-04
-7wmm,2023-01-18,2022-01-15
-5wmi,2018-08-08,2017-07-28
-7wmf,2022-04-27,2022-01-14
-4wmz,2015-07-01,2014-10-09
-7wmt,2022-08-31,2022-01-17
-5wmo,2018-06-06,2017-07-30
-3wml,2014-09-24,2013-11-21
-8wmy,2023-10-25,2023-10-05
-8wmw,2024-05-29,2023-10-04
-5wmj,2018-03-28,2017-07-28
-6wmv,2020-05-27,2020-04-21
-8wmc,2024-05-29,2023-10-03
-7wme,2022-04-13,2022-01-14
-1wmo,2005-08-02,2004-07-13
-1wm0,2004-09-07,2004-07-01
-1wma,2005-04-26,2004-07-06
-6wmo,2020-12-02,2020-04-21
-5wm4,2018-05-23,2017-07-28
-1wmr,2005-07-19,2004-07-15
-3wmp,2015-01-14,2013-11-22
-3wmq,2015-01-14,2013-11-22
-2wmc,2010-09-01,2009-06-30
-5wm7,2018-05-23,2017-07-28
-6wm1,2020-09-02,2020-04-20
-2wmh,2009-07-14,2009-06-30
-6wmp,2020-11-11,2020-04-21
-4wmq,2015-07-01,2014-10-09
-6wmq,2021-02-17,2020-04-21
-7wmi,2022-04-27,2022-01-14
-6wmg,2020-12-02,2020-04-21
-6wml,2021-02-03,2020-04-21
-4wmi,2015-09-30,2014-10-09
-2wmb,2010-09-01,2009-06-30
-1wmn,2005-08-02,2004-07-13
-8wm0,2024-03-27,2023-10-01
-8wmn,2024-06-05,2023-10-04
-3wmy,2014-02-05,2013-11-29
-7wmu,2022-08-10,2022-01-17
-5wm1,2017-10-25,2017-07-28
-5wmr,2018-06-06,2017-07-31
-8wmj,2024-05-29,2023-10-03
-7wmd,2022-09-07,2022-01-14
-8wmk,2023-12-06,2023-10-03
-2wmq,2009-07-28,2009-07-03
-4wmw,2015-05-06,2014-10-09
-7wmh,2022-05-18,2022-01-14
-2wmy,2009-07-21,2009-07-03
-2wme,2009-08-04,2009-06-30
-2wmz,2011-01-26,2009-07-03
-6wmn,2020-12-02,2020-04-21
-1wmq,2005-03-15,2004-07-14
-6wme,2020-12-02,2020-04-21
-4wm9,2014-12-03,2014-10-08
-6wmt,2020-11-11,2020-04-21
-6wm0,2020-07-15,2020-04-20
-2wms,2009-07-28,2009-07-03
-6wmc,2020-12-23,2020-04-21
-3wmv,2014-12-03,2013-11-27
-3wms,2014-11-12,2013-11-24
-6wmm,2020-12-02,2020-04-21
-2wm1,2009-11-03,2009-06-29
-5wmp,2018-06-06,2017-07-30
-4wmt,2015-05-06,2014-10-09
-8wmv,2024-05-29,2023-10-04
-4wmv,2015-05-06,2014-10-09
-2wm5,2009-10-06,2009-06-30
-1wmy,2004-09-07,2004-07-22
-5wm3,2018-05-23,2017-07-28
-6wms,2021-02-17,2020-04-21
-7wmj,2022-05-18,2022-01-14
-6wma,2020-12-23,2020-04-21
-2wm0,2010-03-16,2009-06-29
-7wm6,2022-06-29,2022-01-14
-6wm5,2020-05-27,2020-04-20
-7wm2,2023-01-25,2022-01-14
-7wm1,2023-01-25,2022-01-14
-4wmu,2015-05-06,2014-10-09
-6wmd,2020-12-02,2020-04-21
-4wm5,2015-04-08,2014-10-08
-1wmp,2005-08-02,2004-07-13
-3wmm,2014-04-09,2013-11-22
-7wm4,2023-01-25,2022-01-14
-2wm3,2009-08-04,2009-06-29
-3wmf,2014-03-19,2013-11-18
-6wmf,2020-12-02,2020-04-21
-1wm1,2004-07-20,2004-07-01
-8wmd,2024-04-24,2023-10-03
-4wm0,2015-09-30,2014-10-08
-7wm0,2022-08-17,2022-01-14
-5wmq,2018-06-06,2017-07-31
-2wmo,2009-09-22,2009-07-02
-3wmz,2014-02-05,2013-11-29
-2wmt,2009-07-28,2009-07-03
-2wm4,2009-10-06,2009-06-30
-1wms,2004-09-14,2004-07-16
-2wmv,2009-07-28,2009-07-03
-8wmm,2024-06-05,2023-10-04
-2wmn,2009-09-22,2009-07-02
-5wmx,2017-12-06,2017-07-31
-1wme,2004-09-14,2004-07-08
-7wmc,2022-08-31,2022-01-14
-8wm6,2024-05-29,2023-10-03
-2wmx,2009-07-28,2009-07-03
-7wmz,2023-01-25,2022-01-17
-6wmu,2020-11-11,2020-04-21
-7wmk,2022-09-07,2022-01-15
-3wmb,2014-11-05,2013-11-16
-3wmw,2014-02-26,2013-11-29
-2wmr,2009-07-28,2009-07-03
-6wmb,2020-12-23,2020-04-21
-4wm4,2015-04-08,2014-10-08
-2wmd,2009-07-28,2009-06-30
-3wmt,2014-08-06,2013-11-25
-3wmg,2014-04-30,2013-11-18
-5wmm,2018-03-14,2017-07-30
-5wm6,2018-05-23,2017-07-28
-8wmi,2024-05-29,2023-10-03
-4wm1,2015-04-08,2014-10-08
-1wmd,2004-09-14,2004-07-08
-4wmc,2014-12-03,2014-10-08
-4wm6,2015-04-08,2014-10-08
-5wmv,2017-12-06,2017-07-31
-8wmf,2024-04-24,2023-10-03
-4wmk,2015-09-30,2014-10-09
-6wmr,2020-11-11,2020-04-21
-3wme,2014-03-19,2013-11-18
-4wmb,2015-09-30,2014-10-08
-5wmg,2018-08-01,2017-07-28
-8wmg,2023-12-06,2023-10-03
-2wm2,2010-01-26,2009-06-29
-2wmk,2009-07-14,2009-06-30
-8wmq,2024-01-17,2023-10-04
-6wmi,2020-12-09,2020-04-21
-8wm4,2024-05-29,2023-10-02
-2wmi,2009-07-14,2009-06-30
-5wmd,2018-08-01,2017-07-28
-4wmo,2016-01-20,2014-10-09
-8wml,2024-05-29,2023-10-03
-6wm3,2020-11-11,2020-04-20
-2wmw,2009-07-28,2009-07-03
-5wm5,2018-05-23,2017-07-28
-5wm2,2018-05-23,2017-07-28
-5wmu,2017-12-06,2017-07-31
-7wmg,2022-05-18,2022-01-14
-2wmj,2009-07-14,2009-06-30
-7wmb,2023-01-25,2022-01-14
-7wml,2022-05-18,2022-01-15
-6wm4,2020-11-11,2020-04-20
-5wms,2019-01-23,2017-07-31
-2wmu,2009-07-28,2009-07-03
-4wml,2015-12-23,2014-10-09
-4wm2,2015-04-08,2014-10-08
-3wmc,2014-11-05,2013-11-16
-4wmr,2015-05-06,2014-10-09
-4wm7,2015-01-14,2014-10-08
-1wmu,2004-08-03,2004-07-21
-4wm3,2015-04-08,2014-10-08
-1wmf,2004-09-14,2004-07-08
-5wmn,2018-06-06,2017-07-30
-4wmy,2015-07-01,2014-10-09
-1wmb,2005-09-06,2004-07-06
-7wmq,2022-08-10,2022-01-16
-7wm7,2022-04-27,2022-01-14
-5wmw,2017-12-06,2017-07-31
-2wma,2010-09-01,2009-06-30
-2wmg,2009-07-14,2009-06-30
-4wmx,2015-05-06,2014-10-09
-8wm7,2024-02-28,2023-10-03
-7wmo,2022-05-18,2022-01-15
-4wms,2015-05-06,2014-10-09
-3wmx,2014-02-26,2013-11-29
-6wm2,2020-11-11,2020-04-20
-1wm9,2005-07-19,2004-07-05
-7wmv,2022-11-16,2022-01-17
-4wma,2015-09-30,2014-10-08
-3wmh,2014-11-19,2013-11-19
-5wmb,2017-10-25,2017-07-28
-5wmt,2018-04-18,2017-07-31
-1wmz,2004-09-07,2004-07-22
-5wml,2018-08-08,2017-07-29
-5wmh,2018-08-08,2017-07-28
-5wma,2018-08-01,2017-07-28
-5wm8,2017-10-25,2017-07-28
-7wmn,2022-05-18,2022-01-15
-186l,1995-07-10,1995-04-19
-7gf8,2023-11-08,2023-08-11
-7gft,2023-11-08,2023-08-11
-4gf5,2012-08-22,2012-08-02
-2gf6,2006-04-18,2006-03-21
-7gfd,2023-11-08,2023-08-11
-7gfh,2023-11-08,2023-08-11
-7gf6,2023-11-08,2023-08-11
-7gfx,2023-11-08,2023-08-11
-4gf6,2012-08-29,2012-08-03
-4gf7,2013-08-07,2012-08-03
-7gff,2023-11-08,2023-08-11
-8gfd,2023-05-24,2023-03-08
-7gfn,2023-11-08,2023-08-11
-3gfd,2009-05-12,2009-02-26
-2gfx,2006-05-23,2006-03-23
-3gfs,2009-09-22,2009-02-27
-2gf4,2006-04-18,2006-03-21
-7gf3,2023-11-08,2023-08-11
-3gfx,2009-06-23,2009-02-27
-8gfv,2024-03-06,2023-03-08
-4gfm,2013-06-19,2012-08-03
-1gfi,1995-03-31,1994-11-11
-6gfh,2018-09-12,2018-04-30
-7gfl,2023-11-08,2023-08-11
-3gf2,2009-08-25,2009-02-26
-6gfk,2018-09-19,2018-04-30
-6gfe,2019-05-15,2018-04-30
-4gfo,2013-06-19,2012-08-03
-3gfr,2009-09-22,2009-02-27
-3gfv,2009-05-12,2009-02-27
-7gfj,2023-11-08,2023-08-11
-8gf4,2024-03-13,2023-03-07
-7gf2,2023-11-08,2023-08-11
-6gfm,2019-04-24,2018-05-01
-7gf7,2023-11-08,2023-08-11
-7gf4,2023-11-08,2023-08-11
-4gfv,2013-10-23,2012-08-04
-2gfo,2006-04-04,2006-03-22
-6gfw,2018-07-04,2018-05-02
-4gfh,2012-10-03,2012-08-03
-2gfs,2006-04-18,2006-03-23
-7gfv,2023-11-08,2023-08-11
-3gfj,2009-08-25,2009-02-27
-3gfm,2009-08-25,2009-02-27
-4gfr,2013-08-21,2012-08-03
-6gff,2018-11-07,2018-04-30
-6gfr,2019-05-08,2018-05-01
-7gfo,2023-11-08,2023-08-11
-8gfo,2023-07-12,2023-03-08
-4gf9,2012-09-26,2012-08-03
-6gf3,2019-05-08,2018-04-29
-8gfh,2023-05-24,2023-03-08
-2gfk,2007-03-27,2006-03-22
-7gfp,2023-11-08,2023-08-11
-6gfn,2018-09-19,2018-05-01
-8gfe,2023-05-24,2023-03-08
-2gfg,2006-05-02,2006-03-21
-7gfm,2023-11-08,2023-08-11
-1gfy,2000-07-04,2000-06-26
-4gfj,2012-12-05,2012-08-03
-7gf5,2023-11-08,2023-08-11
-3gfe,2009-07-14,2009-02-26
-4gfu,2013-08-07,2012-08-04
-3gfa,2009-03-17,2009-02-26
-4gfi,2012-08-29,2012-08-03
-2gft,2006-06-13,2006-03-23
-8gfp,2023-05-24,2023-03-08
-4gfy,2012-08-22,2012-08-04
-3gft,2009-03-10,2009-02-27
-7gfq,2023-11-08,2023-08-11
-8gfy,2024-03-06,2023-03-08
-2gfd,2007-04-03,2006-03-21
-3gf4,2009-06-09,2009-02-26
-6gfz,2018-07-11,2018-05-02
-2gfe,2006-08-22,2006-03-21
-2gfa,2006-05-02,2006-03-21
-7gfe,2023-11-08,2023-08-11
-8gf0,2023-05-24,2023-03-07
-7gf1,2023-11-08,2023-08-11
-6gfa,2019-05-08,2018-04-29
-4gfb,2013-04-10,2012-08-03
-7gfw,2023-11-08,2023-08-11
-8gfw,2024-03-06,2023-03-08
-3gfz,2009-06-23,2009-02-27
-8gfl,2023-05-24,2023-03-08
-2gfq,2006-04-25,2006-03-22
-8gfn,2023-07-12,2023-03-08
-7gfz,2023-11-08,2023-08-11
-6gfq,2019-05-08,2018-05-01
-3gfh,2009-07-21,2009-02-26
-7gfu,2023-11-08,2023-08-11
-4gfg,2013-08-14,2012-08-03
-7gfy,2023-11-08,2023-08-11
-8gfb,2023-05-24,2023-03-08
-2gfh,2006-04-18,2006-03-21
-6gfb,2018-05-09,2018-04-29
-3gf3,2009-07-28,2009-02-26
-7gfg,2023-11-08,2023-08-11
-7gfi,2023-11-08,2023-08-11
-2gf9,2006-05-02,2006-03-21
-1gfw,2000-06-23,2000-06-16
-3gfw,2009-03-17,2009-02-27
-6gf8,2019-06-19,2018-04-29
-4gfs,2012-08-15,2012-08-03
-6gfy,2018-07-11,2018-05-02
-8gfc,2023-05-24,2023-03-08
-6gfp,2019-05-08,2018-05-01
-8gfa,2023-05-10,2023-03-07
-8gfm,2023-05-24,2023-03-08
-8gf5,2023-06-28,2023-03-07
-8gfx,2024-03-06,2023-03-08
-7gfb,2023-11-08,2023-08-11
-8gfq,2023-05-24,2023-03-08
-8gf9,2023-05-10,2023-03-07
-8gff,2023-05-24,2023-03-08
-6gfu,2019-05-22,2018-05-02
-8gfu,2023-07-12,2023-03-08
-3gfb,2009-10-06,2009-02-26
-8gfs,2023-05-24,2023-03-08
-4gfn,2013-02-13,2012-08-03
-4gfd,2012-10-24,2012-08-03
-3gf0,2009-03-10,2009-02-26
-8gft,2023-05-03,2023-03-08
-2gf0,2006-04-04,2006-03-21
-6gf7,2019-06-19,2018-04-29
-6gfo,2019-05-08,2018-05-01
-6gfj,2019-03-13,2018-04-30
-8gf2,2023-08-23,2023-03-07
-8gf1,2023-05-24,2023-03-07
-8gfr,2023-07-12,2023-03-08
-3gfl,2009-08-25,2009-02-27
-7gfc,2023-11-08,2023-08-11
-3gfq,2009-09-22,2009-02-27
-3gfy,2009-06-23,2009-02-27
-7gfa,2023-11-08,2023-08-11
-7gf9,2023-11-08,2023-08-11
-7gf0,2023-11-08,2023-08-11
-2gfi,2007-03-27,2006-03-22
-7gfs,2023-11-08,2023-08-11
-6gf6,2019-06-19,2018-04-29
-8gfi,2023-05-24,2023-03-08
-2gf3,2007-02-06,2006-03-21
-8gf7,2023-11-08,2023-03-07
-4gf0,2012-08-29,2012-08-02
-8gfg,2023-05-24,2023-03-08
-2gfj,2007-03-27,2006-03-22
-8gfz,2024-03-06,2023-03-08
-8gf8,2023-05-10,2023-03-07
-7gfk,2023-11-08,2023-08-11
-1gfz,2000-07-26,2000-06-29
-7gfr,2023-11-08,2023-08-11
-2vbi,2008-04-08,2007-09-14
-6vb0,2020-11-25,2019-12-18
-2vb3,2007-12-18,2007-09-06
-2vbx,2007-11-06,2007-09-18
-5vbo,2018-04-04,2017-03-30
-7vbv,2022-02-16,2021-09-01
-1vbj,2005-04-12,2004-02-27
-7vb7,2022-04-06,2021-08-30
-6vbv,2020-01-29,2019-12-19
-2vbu,2007-11-20,2007-09-16
-6vb8,2020-12-23,2019-12-18
-1vbn,2005-01-25,2004-02-27
-3vbj,2012-01-25,2012-01-02
-1vbc,1996-07-11,1996-01-02
-5vbs,2018-03-07,2017-03-30
-2vbe,2008-04-22,2007-09-12
-1vbt,1999-01-13,1998-06-16
-5vbp,2018-04-04,2017-03-30
-1vbb,1996-07-11,1996-01-02
-3vbv,2012-03-21,2012-01-02
-1vby,2004-05-18,2004-03-03
-1vba,1996-07-11,1996-01-02
-6vbw,2020-01-29,2019-12-19
-7vbw,2021-12-15,2021-09-01
-6vbg,2020-11-25,2019-12-18
-7vbc,2022-02-16,2021-08-31
-2vbs,2007-11-20,2007-09-16
-6vb3,2020-11-25,2019-12-18
-1vb6,2005-04-19,2004-02-24
-8vbw,2024-05-01,2023-12-12
-2vbw,2007-11-06,2007-09-18
-6vbr,2021-02-10,2019-12-19
-3vbq,2012-03-21,2012-01-02
-1vbs,1999-01-13,1998-06-16
-6vb9,2020-12-30,2019-12-18
-1vbl,2005-04-19,2004-02-27
-7vba,2022-02-16,2021-08-31
-6vbz,2020-07-08,2019-12-19
-2vbd,2008-09-23,2007-09-10
-3vbt,2012-03-21,2012-01-02
-1vbw,2005-03-22,2004-03-03
-5vb5,2017-06-07,2017-03-28
-3vbl,2012-01-25,2012-01-02
-1vb4,2004-11-23,2004-02-21
-1vbm,2005-01-25,2004-02-27
-6vbs,2020-12-30,2019-12-19
-3vbk,2012-01-25,2012-01-02
-7vb9,2022-05-04,2021-08-30
-2vbn,2008-10-28,2007-09-14
-1vbi,2005-04-19,2004-02-27
-5vb9,2018-02-14,2017-03-28
-7vbx,2022-02-16,2021-09-01
-5vbc,2017-04-19,2017-03-29
-7vb4,2022-02-16,2021-08-30
-6vb5,2020-11-25,2019-12-18
-7vbn,2022-04-06,2021-08-31
-3vbb,2012-02-29,2012-01-02
-3vb7,2012-12-12,2011-12-31
-3vbe,2012-09-12,2012-01-02
-3vbi,2012-01-25,2012-01-02
-1vbo,2004-06-15,2004-02-28
-5vbz,2017-10-25,2017-03-30
-7vbb,2022-03-02,2021-08-31
-3vbd,2012-04-04,2012-01-02
-6vbb,2019-12-25,2019-12-18
-6vb1,2020-11-25,2019-12-18
-2vbk,2008-04-01,2007-09-14
-6vbf,2019-12-25,2019-12-18
-3vb6,2012-12-12,2011-12-31
-2vbv,2007-11-20,2007-09-16
-7vbq,2022-04-20,2021-09-01
-3vbn,2012-01-25,2012-01-02
-3vbw,2012-03-21,2012-01-02
-5vb3,2017-06-07,2017-03-28
-1vbd,1996-07-11,1996-01-02
-1vbh,2005-03-08,2004-02-26
-5vb0,2017-08-30,2017-03-28
-2vbg,2007-11-27,2007-09-12
-1vbe,1996-07-11,1996-01-02
-6vb7,2020-11-25,2019-12-18
-5vb6,2017-06-07,2017-03-28
-7vb5,2022-02-09,2021-08-30
-2vba,2007-12-25,2007-09-06
-6vbn,2020-05-06,2019-12-19
-5vbm,2017-10-25,2017-03-29
-6vbu,2020-01-29,2019-12-19
-6vb4,2020-11-25,2019-12-18
-2vbl,2008-10-28,2007-09-14
-2vbt,2007-11-20,2007-09-16
-3vbx,2012-03-21,2012-01-02
-2vbb,2008-07-29,2007-09-07
-6vba,2021-03-03,2019-12-18
-7vb8,2022-09-07,2021-08-30
-3vby,2012-03-21,2012-01-02
-7vb3,2022-02-09,2021-08-30
-2vbo,2008-10-28,2007-09-14
-1vbp,2004-06-15,2004-02-28
-1vbg,2005-03-08,2004-02-26
-3vbf,2012-02-29,2012-01-02
-6vbi,2021-01-20,2019-12-18
-7vbz,2022-04-06,2021-09-01
-2vb8,2007-12-25,2007-09-06
-2vb2,2007-12-18,2007-09-06
-1vbr,2005-06-28,2004-03-02
-7vbo,2022-09-07,2021-09-01
-2vbp,2008-11-04,2007-09-14
-2vbf,2007-12-18,2007-09-12
-6vby,2020-05-06,2019-12-19
-3vb0,2013-04-03,2011-12-30
-2vbj,2008-10-28,2007-09-14
-1vb3,2005-06-21,2004-02-21
-1vb9,2005-03-08,2004-02-25
-5vb7,2017-06-07,2017-03-28
-2vbq,2008-01-08,2007-09-14
-2vby,2007-11-06,2007-09-18
-6vb6,2020-11-25,2019-12-18
-5vbr,2018-04-04,2017-03-30
-7vbu,2022-02-16,2021-09-01
-6vb2,2020-11-25,2019-12-18
-3vbg,2012-06-27,2012-01-02
-5vbl,2017-05-31,2017-03-29
-3vbo,2012-02-29,2012-01-02
-3vbh,2012-02-29,2012-01-02
-7vb0,2022-07-13,2021-08-30
-3vb4,2012-12-12,2011-12-31
-2vbz,2007-11-06,2007-09-18
-5vbn,2017-08-02,2017-03-29
-7vbl,2022-04-06,2021-08-31
-7vb6,2022-02-09,2021-08-30
-5vbi,2018-06-20,2017-03-29
-3vb5,2012-12-12,2011-12-31
-2vbm,2008-04-22,2007-09-14
-2vb6,2007-12-11,2007-09-06
-3vbp,2012-01-25,2012-01-02
-3vbm,2012-01-25,2012-01-02
-5vbx,2017-11-01,2017-03-30
-7vbt,2022-07-06,2021-09-01
-7vbp,2022-04-06,2021-09-01
-5vbu,2017-05-31,2017-03-30
-8vbv,2024-05-01,2023-12-12
-8vbu,2024-05-01,2023-12-12
-6vbt,2020-12-30,2019-12-19
-6vbd,2020-04-15,2019-12-18
-3vb9,2012-05-23,2011-12-31
-5vbe,2017-10-25,2017-03-29
-5vbq,2018-04-04,2017-03-30
-4dle,2012-11-28,2012-02-06
-5dlo,2016-09-28,2015-09-07
-2dln,1995-11-01,1994-07-18
-8dll,2022-08-31,2022-07-08
-5dl1,2015-11-25,2015-09-04
-3dlz,2008-07-15,2008-06-30
-8dlw,2022-08-31,2022-07-08
-3dlc,2008-08-26,2008-06-27
-7dl1,2021-09-29,2020-11-25
-4dl4,2012-05-09,2012-02-05
-7dl3,2021-09-29,2020-11-25
-8dly,2022-08-31,2022-07-08
-4dlq,2012-02-22,2012-02-06
-7dlv,2021-12-01,2020-11-30
-8dln,2022-08-31,2022-07-08
-6dld,2019-04-10,2018-06-01
-1dlr,1995-04-20,1995-01-25
-1dlk,2000-05-03,1999-12-10
-5dlm,2015-10-28,2015-09-07
-3dl7,2008-12-02,2008-06-26
-1dlw,2000-09-20,1999-12-13
-7dli,2021-06-23,2020-11-27
-7dlb,2021-12-01,2020-11-26
-8dlj,2022-08-31,2022-07-08
-5dl7,2016-02-03,2015-09-04
-8dl3,2022-12-21,2022-07-06
-4dli,2013-01-23,2012-02-06
-8dlo,2022-08-31,2022-07-08
-1dly,2000-09-20,1999-12-13
-7dld,2022-04-06,2020-11-27
-4dls,2012-08-08,2012-02-06
-1dlq,2000-05-23,1999-12-11
-4dlu,2012-08-08,2012-02-06
-8dlb,2023-05-17,2022-07-07
-1dlv,2000-04-24,1999-12-12
-6dle,2019-04-10,2018-06-01
-1dl2,2000-02-18,1999-12-08
-4dl5,2012-05-09,2012-02-05
-7dlk,2021-11-03,2020-11-27
-2dlc,2007-06-12,2006-04-18
-8dli,2022-08-31,2022-07-08
-7dlc,2022-02-02,2020-11-27
-2dlo,2006-10-20,2006-04-20
-6dli,2019-06-05,2018-06-01
-4dld,2012-10-10,2012-02-06
-7dls,2021-07-14,2020-11-30
-1dls,1995-04-20,1995-01-25
-6dlj,2018-09-05,2018-06-01
-8dlk,2022-08-31,2022-07-08
-4dlg,2012-11-28,2012-02-06
-6dll,2018-06-13,2018-06-01
-2dlq,2006-10-20,2006-04-20
-8dlm,2022-08-31,2022-07-08
-4dlt,2012-08-08,2012-02-06
-1dl5,2000-12-08,1999-12-08
-5dls,2015-10-14,2015-09-07
-8dla,2023-08-09,2022-07-07
-4dlo,2012-02-22,2012-02-06
-8dlu,2022-08-31,2022-07-08
-7dlq,2020-12-16,2020-11-29
-4dlp,2012-02-15,2012-02-06
-6dlx,2018-08-22,2018-06-04
-5dld,2015-09-30,2015-09-04
-5dlr,2016-05-04,2015-09-07
-5dly,2015-09-30,2015-09-07
-4dlm,2012-02-29,2012-02-06
-5dlw,2016-04-13,2015-09-07
-3dl2,2008-07-15,2008-06-26
-8dle,2023-07-12,2022-07-07
-5dlt,2016-04-13,2015-09-07
-3dla,2009-03-10,2008-06-26
-5dlp,2016-03-30,2015-09-07
-3dll,2008-09-16,2008-06-27
-6dlu,2018-08-01,2018-06-02
-6dlz,2018-08-22,2018-06-04
-7dl0,2021-09-29,2020-11-25
-3dl6,2008-08-19,2008-06-26
-8dlz,2022-08-31,2022-07-08
-5dl0,2016-01-27,2015-09-04
-3dlb,2008-09-02,2008-06-26
-8dl9,2023-05-17,2022-07-07
-4dlw,2012-08-08,2012-02-06
-3dle,2008-08-12,2008-06-27
-7dlw,2021-09-29,2020-11-30
-4dlb,2012-12-26,2012-02-06
-2dlk,2006-10-20,2006-04-20
-4dl6,2012-05-09,2012-02-05
-4dlz,2012-08-08,2012-02-06
-5dlh,2015-11-18,2015-09-04
-3dls,2008-08-26,2008-06-29
-1dlm,2000-05-23,1999-12-11
-6dl7,2019-05-08,2018-05-31
-4dlc,2013-08-07,2012-02-06
-1dlh,1994-06-22,1994-02-15
-3dln,2008-11-25,2008-06-27
-8dl8,2022-12-07,2022-07-07
-3dlt,2009-06-30,2008-06-29
-4dlj,2013-01-23,2012-02-06
-8dlp,2022-08-31,2022-07-08
-3dlh,2008-09-02,2008-06-27
-3dlg,2008-08-12,2008-06-27
-1dl7,2000-12-13,1999-12-08
-8dl4,2022-08-17,2022-07-06
-8dlx,2022-08-31,2022-07-08
-7dlr,2021-12-01,2020-11-30
-5dlf,2016-08-10,2015-09-04
-8dlv,2022-08-31,2022-07-08
-7dly,2021-09-29,2020-11-30
-6dl2,2019-04-17,2018-05-31
-1dl6,2000-10-18,1999-12-08
-7dl6,2021-12-01,2020-11-26
-4dl9,2012-12-26,2012-02-06
-5dlz,2016-06-01,2015-09-07
-6dly,2019-06-12,2018-06-04
-5dll,2015-09-16,2015-09-07
-1dlt,2000-05-23,1999-12-12
-1dlj,2000-05-31,1999-12-09
-4dl1,2012-03-21,2012-02-05
-3dlp,2009-04-21,2008-06-28
-4dl7,2012-05-09,2012-02-05
-4dlk,2013-02-06,2012-02-06
-5dlg,2016-08-10,2015-09-04
-5dlq,2016-06-22,2015-09-07
-4dlv,2012-08-08,2012-02-06
-4dl8,2013-08-07,2012-02-06
-8dl1,2023-05-24,2022-07-06
-7dlh,2021-12-01,2020-11-27
-7dl4,2021-12-01,2020-11-26
-6dlh,2018-10-03,2018-06-01
-3dl5,2008-08-19,2008-06-26
-3dlr,2008-12-09,2008-06-29
-5dlx,2016-06-01,2015-09-07
-4dlx,2012-08-08,2012-02-06
-1dll,2000-03-24,1999-12-10
-5dlb,2015-09-23,2015-09-04
-4dly,2012-08-08,2012-02-06
-5dl4,2016-05-04,2015-09-04
-6dlf,2019-04-10,2018-06-01
-6dl9,2018-09-05,2018-05-31
-7dl7,2021-09-29,2020-11-26
-6dlw,2018-09-12,2018-06-03
-2dld,1996-03-14,1995-10-28
-3dl0,2009-06-09,2008-06-26
-8dlr,2022-08-31,2022-07-08
-5dlv,2016-04-13,2015-09-07
-4dl3,2012-05-09,2012-02-05
-8dls,2022-08-31,2022-07-08
-4dla,2012-12-26,2012-02-06
-5dl8,2016-02-03,2015-09-04
-3dl9,2008-08-05,2008-06-26
-8dl6,2023-01-25,2022-07-07
-4dl2,2012-05-09,2012-02-05
-8dlt,2022-08-31,2022-07-08
-7dll,2022-04-06,2020-11-28
-6dlp,2019-01-09,2018-06-02
-4dlr,2012-08-08,2012-02-06
-7dln,2021-12-01,2020-11-28
-7dl5,2021-12-01,2020-11-26
-8dlq,2022-08-31,2022-07-08
-1dli,2000-05-31,1999-12-09
-8dl2,2023-05-24,2022-07-06
-7dlm,2022-04-06,2020-11-28
-7xnq,2022-07-13,2022-04-29
-1xnq,2004-12-14,2004-10-05
-6xng,2021-11-10,2020-07-02
-4xna,2016-03-02,2015-01-15
-4xnd,2016-03-02,2015-01-15
-7xnx,2023-04-05,2022-04-30
-1xnz,2004-11-02,2004-10-05
-5xnv,2017-11-01,2017-05-24
-6xn0,2020-12-02,2020-07-02
-5xnl,2017-09-20,2017-05-23
-7xnc,2023-03-01,2022-04-28
-7xnn,2022-12-14,2022-04-29
-6xnw,2021-03-24,2020-07-04
-6xnn,2020-08-26,2020-07-03
-7xno,2022-05-25,2022-04-29
-7xnk,2022-12-14,2022-04-29
-5xnk,2018-05-30,2017-05-23
-5xn8,2017-06-07,2017-05-19
-4xnx,2015-05-13,2015-01-16
-6xnx,2020-08-26,2020-07-05
-1xnk,2005-05-10,2004-10-05
-7xnr,2022-07-13,2022-04-29
-2xn4,2010-08-18,2010-07-30
-1xnr,2004-12-14,2004-10-05
-6xnd,2021-03-03,2020-07-02
-7xn7,2022-09-07,2022-04-28
-7xn6,2022-12-14,2022-04-28
-1xnj,2005-08-30,2004-10-05
-4xn4,2016-03-02,2015-01-15
-2xne,2010-09-22,2010-08-02
-4xnz,2015-04-29,2015-01-16
-5xnz,2018-03-14,2017-05-25
-4xnf,2016-01-27,2015-01-15
-4xn9,2016-03-02,2015-01-15
-6xnl,2021-07-07,2020-07-03
-4xnw,2015-04-01,2015-01-16
-5xnn,2017-09-20,2017-05-23
-2xn8,2010-11-10,2010-07-30
-1xny,2004-11-09,2004-10-05
-2xnc,2011-02-23,2010-08-02
-6xnc,2021-02-03,2020-07-02
-4xnh,2016-07-20,2015-01-15
-7xnz,2022-05-25,2022-04-30
-1xn3,2005-03-22,2004-10-04
-2xna,2010-11-24,2010-07-31
-7xns,2022-07-13,2022-04-29
-7xn1,2023-03-01,2022-04-27
-2xn7,2011-02-16,2010-07-30
-5xnh,2017-10-04,2017-05-22
-2xn3,2011-02-16,2010-07-30
-2xnj,2011-02-23,2010-08-03
-6xn8,2021-07-07,2020-07-02
-6xnk,2021-07-07,2020-07-03
-2xnb,2010-11-10,2010-08-01
-5xn1,2018-02-07,2017-05-17
-6xny,2020-08-26,2020-07-05
-4xnb,2016-03-02,2015-01-15
-4xn3,2016-01-27,2015-01-15
-5xne,2018-08-01,2017-05-22
-4xnq,2015-07-15,2015-01-15
-4xnm,2015-07-15,2015-01-15
-8xn6,2024-01-24,2023-12-29
-1xnx,2005-01-04,2004-10-05
-7xn2,2023-03-08,2022-04-27
-7xng,2022-06-01,2022-04-28
-4xnv,2015-04-01,2015-01-16
-4xnk,2015-06-03,2015-01-15
-2xns,2011-06-08,2010-08-05
-5xno,2017-09-20,2017-05-23
-7xn4,2022-12-14,2022-04-28
-6xnj,2020-08-12,2020-07-03
-1xnn,2005-10-11,2004-10-05
-2xnd,2010-09-15,2010-08-02
-7xn9,2022-08-03,2022-04-28
-5xnf,2018-08-15,2017-05-22
-5xni,2018-05-30,2017-05-23
-4xnc,2015-08-12,2015-01-15
-4xne,2015-08-12,2015-01-15
-4xn7,2016-03-02,2015-01-15
-5xnj,2018-05-30,2017-05-23
-1xn0,2004-12-14,2004-10-04
-4xn1,2016-03-02,2015-01-15
-2xno,2011-03-30,2010-08-05
-4xnu,2015-05-13,2015-01-16
-5xnm,2017-09-20,2017-05-23
-7xnm,2023-05-17,2022-04-29
-6xnb,2020-08-12,2020-07-02
-4xnl,2015-06-03,2015-01-15
-6xnf,2021-07-07,2020-07-02
-5xnq,2018-01-24,2017-05-24
-4xn8,2016-03-02,2015-01-15
-2xn0,2011-08-10,2010-07-30
-6xn2,2020-12-02,2020-07-02
-2xnu,2011-08-24,2010-08-06
-2xn5,2011-02-16,2010-07-30
-5xnd,2017-12-27,2017-05-22
-5xnx,2017-07-19,2017-05-24
-6xnm,2021-07-07,2020-07-03
-7xna,2022-08-03,2022-04-28
-5xnp,2018-01-24,2017-05-24
-2xn9,2010-11-24,2010-07-31
-8xn8,2024-01-24,2023-12-29
-2xng,2010-09-22,2010-08-02
-6xnv,2020-09-09,2020-07-04
-7xn5,2022-12-14,2022-04-28
-6xne,2021-07-07,2020-07-02
-2xnp,2011-03-30,2010-08-05
-5xn9,2017-07-26,2017-05-19
-1xn2,2005-03-22,2004-10-04
-4xn0,2016-01-27,2015-01-15
-4xn2,2016-03-02,2015-01-15
-1xn1,2005-09-27,2004-10-04
-5xnr,2018-06-13,2017-05-24
-6xn6,2021-01-06,2020-07-02
-5xnc,2018-08-15,2017-05-22
-7xny,2023-04-05,2022-04-30
-5xna,2017-07-26,2017-05-19
-7xnl,2022-12-14,2022-04-29
-2xnm,2011-03-30,2010-08-05
-2xnn,2011-03-30,2010-08-05
-7xnt,2022-12-14,2022-04-29
-7xne,2022-07-06,2022-04-28
-5xn3,2017-06-14,2017-05-17
-4xn5,2016-02-10,2015-01-15
-6xnz,2020-08-26,2020-07-05
-5xn0,2018-02-07,2017-05-17
-2xnr,2010-09-08,2010-08-05
-2xnv,2011-08-24,2010-08-06
-2xn6,2011-02-16,2010-07-30
-4xny,2015-04-29,2015-01-16
-2xnt,2011-08-24,2010-08-06
-2xn2,2011-08-10,2010-07-30
-6xn1,2020-12-02,2020-07-02
-1xng,2005-04-05,2004-10-05
-5xnt,2018-04-04,2017-05-24
-5xn2,2018-02-07,2017-05-17
-2xni,2011-08-17,2010-08-02
-6xnp,2020-08-26,2020-07-03
-5ei9,2016-02-17,2015-10-29
-7ein,2021-07-07,2021-03-31
-8eid,2023-02-22,2022-09-14
-3eia,2008-10-14,2008-09-15
-8eib,2023-10-25,2022-09-14
-2ei8,2008-03-18,2007-03-12
-1eiz,2000-08-30,2000-02-29
-8eis,2023-04-12,2022-09-15
-7eip,2021-08-25,2021-03-31
-8ei8,2023-10-25,2022-09-14
-8eic,2023-10-25,2022-09-14
-5eia,2016-01-20,2015-10-29
-4ei7,2012-08-15,2012-04-05
-8ei7,2023-10-25,2022-09-14
-6eiu,2018-05-02,2017-09-19
-7eiy,2022-04-06,2021-04-01
-2eid,2007-04-24,2007-03-12
-6eip,2018-08-29,2017-09-19
-2eik,2007-05-29,2007-03-13
-1ei1,2000-03-31,2000-02-23
-2eir,2007-09-11,2007-03-13
-6eid,2017-12-06,2017-09-19
-3ei5,2008-10-14,2008-09-15
-7eii,2021-08-11,2021-03-31
-7eib,2021-10-13,2021-03-30
-1eii,2000-08-09,2000-02-25
-5eil,2016-11-16,2015-10-30
-1ei6,2003-11-25,2000-02-24
-2eit,2007-09-18,2007-03-13
-5eiw,2016-10-26,2015-10-30
-5eit,2016-05-04,2015-10-30
-3ei8,2008-10-14,2008-09-15
-8ei2,2023-10-25,2022-09-14
-8eie,2023-09-20,2022-09-14
-2ein,2007-05-29,2007-03-13
-8eif,2023-09-27,2022-09-14
-2eib,2007-04-24,2007-03-12
-3eim,2009-10-06,2008-09-16
-1eiq,2001-02-28,2000-02-28
-5eie,2016-01-20,2015-10-29
-7eiv,2021-08-11,2021-03-31
-7eix,2022-04-06,2021-04-01
-3eiu,2009-02-10,2008-09-17
-5ei5,2016-11-09,2015-10-29
-5eik,2016-10-05,2015-10-30
-5eih,2016-01-20,2015-10-29
-7ei4,2022-04-06,2021-03-30
-5ei8,2016-04-20,2015-10-29
-7eir,2021-08-25,2021-03-31
-3eif,2009-02-24,2008-09-15
-5eiv,2015-11-25,2015-10-30
-6eiq,2018-08-29,2017-09-19
-8eik,2023-09-20,2022-09-15
-8ein,2023-03-08,2022-09-15
-7eik,2022-04-06,2021-03-31
-6eiy,2018-05-02,2017-09-19
-6eii,2018-02-28,2017-09-19
-8ei0,2023-10-25,2022-09-14
-4eiw,2012-06-06,2012-04-06
-8eip,2023-03-08,2022-09-15
-5eiy,2016-03-09,2015-10-30
-2eic,2007-04-24,2007-03-12
-3eih,2008-09-30,2008-09-15
-6eis,2018-08-29,2017-09-19
-3eib,2008-10-14,2008-09-15
-2ei4,2008-01-01,2007-03-11
-5eiu,2016-06-15,2015-10-30
-2eij,2007-05-29,2007-03-13
-4ei9,2012-08-15,2012-04-05
-4eir,2012-05-23,2012-04-05
-2ei6,2008-03-18,2007-03-12
-4ei5,2012-07-25,2012-04-04
-5ei2,2016-04-20,2015-10-29
-7eim,2021-11-10,2021-03-31
-2eim,2007-05-29,2007-03-13
-3ei9,2008-10-14,2008-09-15
-3eic,2009-06-16,2008-09-15
-1eil,2001-02-26,2000-02-26
-1ei9,2000-04-26,2000-02-24
-4ei2,2012-12-19,2012-04-04
-8ei9,2023-10-25,2022-09-14
-5ei4,2016-01-20,2015-10-29
-7eiz,2021-09-22,2021-04-01
-7ei0,2022-04-06,2021-03-30
-8eix,2023-02-01,2022-09-15
-7eil,2022-04-06,2021-03-31
-2eix,2007-04-17,2007-03-14
-2eiy,2008-03-18,2007-03-14
-3eii,2009-10-27,2008-09-16
-2ei3,2008-02-19,2007-03-10
-7eih,2021-08-11,2021-03-31
-6eif,2018-08-29,2017-09-19
-4eic,2013-04-10,2012-04-05
-4eik,2013-04-10,2012-04-05
-2ei7,2008-03-18,2007-03-12
-8ei3,2023-10-25,2022-09-14
-5eix,2016-04-13,2015-10-30
-8eiq,2022-10-19,2022-09-15
-6ei5,2018-05-30,2017-09-17
-6ei2,2017-10-11,2017-09-16
-4eid,2013-04-10,2012-04-05
-3eip,1999-11-10,1999-03-29
-5eij,2016-11-09,2015-10-29
-4eil,2013-10-09,2012-04-05
-8eiu,2023-02-01,2022-09-15
-5eig,2016-11-09,2015-10-29
-6eiv,2018-08-29,2017-09-19
-5eic,2016-11-16,2015-10-29
-6eij,2018-08-29,2017-09-19
-7eij,2021-08-11,2021-03-31
-3ei6,2008-10-14,2008-09-15
-6eim,2017-11-01,2017-09-19
-2eil,2007-05-29,2007-03-13
-2eiw,2007-09-18,2007-03-13
-4eiq,2012-08-08,2012-04-05
-7eis,2021-08-25,2021-03-31
-6ei9,2018-01-17,2017-09-18
-5ein,2016-03-23,2015-10-30
-4ein,2013-04-10,2012-04-05
-2eis,2008-03-18,2007-03-13
-3eid,2008-10-21,2008-09-15
-2eih,2008-03-18,2007-03-13
-1eix,2000-03-15,2000-02-29
-7eig,2022-04-06,2021-03-31
-8eii,2023-09-20,2022-09-15
-8eia,2023-10-25,2022-09-14
-5eis,2016-01-20,2015-10-30
-5eir,2016-09-07,2015-10-30
-1eir,2001-02-28,2000-02-28
-4ei4,2012-07-04,2012-04-04
-6eil,2018-08-29,2017-09-19
-5eif,2016-10-26,2015-10-29
-3ein,2009-09-01,2008-09-17
-5eio,2016-03-23,2015-10-30
-3eig,2009-05-26,2008-09-15
-7eiw,2022-04-06,2021-04-01
-8eiy,2023-02-01,2022-09-15
-1eib,2001-02-25,2000-02-25
-6eir,2018-08-29,2017-09-19
-8eih,2023-09-20,2022-09-15
-6ei4,2018-04-25,2017-09-17
-6ein,2018-05-02,2017-09-19
-5ei6,2016-04-20,2015-10-29
-7ei2,2022-03-30,2021-03-30
-8ei5,2023-10-25,2022-09-14
-4eip,2012-08-08,2012-04-05
-7eic,2022-04-06,2021-03-30
-8eim,2023-03-15,2022-09-15
-2eie,2007-04-24,2007-03-12
-8ei1,2023-10-25,2022-09-14
-2eiq,2007-09-11,2007-03-13
-4eix,2012-04-25,2012-04-06
-8eiz,2023-04-12,2022-09-15
-4eis,2012-05-23,2012-04-05
-4eiy,2012-07-25,2012-04-06
-1eio,2000-05-31,2000-02-27
-8eio,2022-10-19,2022-09-15
-7eiq,2021-08-25,2021-03-31
-5ei3,2016-09-07,2015-10-29
-8eij,2023-09-20,2022-09-15
-4eie,2013-04-10,2012-04-05
-7eiu,2022-04-06,2021-03-31
-6eih,2018-02-14,2017-09-19
-3eio,2008-11-04,2008-09-17
-3eiy,2008-09-30,2008-09-17
-8eiw,2023-02-01,2022-09-15
-8ei6,2023-10-25,2022-09-14
-6eiz,2018-07-11,2017-09-19
-8eig,2022-10-19,2022-09-15
-2eig,2008-03-04,2007-03-13
-2ei0,2008-02-19,2007-03-10
-2eii,2007-09-18,2007-03-13
-5eib,2016-10-26,2015-10-29
-2ei1,2008-02-19,2007-03-10
-5eim,2016-01-27,2015-10-30
-5ei1,2016-05-04,2015-10-29
-4eib,2012-12-12,2012-04-05
-2ei2,2008-02-19,2007-03-10
-8ei4,2023-10-25,2022-09-14
-4eif,2013-04-10,2012-04-05
-6eix,2017-09-27,2017-09-19
-5a6m,2016-10-19,2015-06-30
-3a6p,2009-12-08,2009-09-07
-7a6k,2022-02-23,2020-08-25
-7a63,2021-02-24,2020-08-24
-5a6n,2015-10-21,2015-06-30
-7a6i,2022-02-23,2020-08-25
-3a6v,2009-10-27,2009-09-09
-4a6g,2012-11-14,2011-11-02
-6a6d,2018-07-11,2018-06-27
-2a6x,2006-01-31,2005-07-04
-4a6a,2012-10-10,2011-11-01
-3a66,2010-09-01,2009-08-21
-5a68,2015-08-05,2015-06-24
-3a6o,2009-09-22,2009-09-07
-8a6h,2023-04-26,2022-06-17
-5a6y,2016-05-25,2015-07-02
-5a67,2015-08-05,2015-06-24
-5a64,2015-08-05,2015-06-24
-1a6g,1998-10-21,1998-02-25
-6a6k,2019-04-10,2018-06-28
-8a62,2023-04-26,2022-06-16
-5a66,2015-08-05,2015-06-24
-4a6c,2012-05-09,2011-11-01
-6a6a,2018-09-05,2018-06-27
-4a6j,2012-11-21,2011-11-04
-5a6h,2016-05-25,2015-06-26
-3a6g,2010-02-09,2009-08-31
-4a6s,2012-10-17,2011-11-08
-4a6x,2012-11-21,2011-11-10
-4a6z,2012-10-17,2011-11-10
-3a6t,2009-10-27,2009-09-09
-5a6b,2015-09-23,2015-06-24
-5a63,2015-08-05,2015-06-24
-8a6v,2023-05-31,2022-06-20
-8a6f,2023-04-26,2022-06-17
-8a6l,2022-11-09,2022-06-18
-4a6o,2012-04-04,2011-11-07
-8a6t,2023-02-15,2022-06-19
-8a65,2023-04-26,2022-06-16
-4a68,2012-01-25,2011-10-31
-8a6u,2023-05-31,2022-06-20
-7a6s,2022-03-23,2020-08-26
-4a6n,2012-11-21,2011-11-07
-1a6a,1998-05-27,1998-02-22
-5a69,2015-09-23,2015-06-24
-5a6i,2016-02-24,2015-06-26
-7a62,2020-12-16,2020-08-24
-4a6w,2012-06-13,2011-11-09
-2a62,2006-04-25,2005-07-01
-2a66,2005-12-06,2005-07-01
-2a6d,2006-06-13,2005-07-02
-1a6e,1999-03-23,1998-02-24
-2a6e,2005-09-20,2005-07-02
-5a6x,2016-05-25,2015-07-02
-3a6z,2010-05-26,2009-09-10
-4a69,2012-01-11,2011-11-01
-3a6f,2010-02-09,2009-08-31
-1a6w,1998-07-15,1998-03-03
-7a6x,2021-03-17,2020-08-27
-8a64,2023-04-05,2022-06-16
-4a6u,2012-01-25,2011-11-08
-8a6c,2023-03-29,2022-06-17
-2a6n,2005-10-18,2005-07-03
-5a6z,2016-05-25,2015-07-02
-5a61,2015-08-05,2015-06-23
-1a6f,1999-03-23,1998-02-24
-7a6c,2020-10-14,2020-08-25
-5a6t,2015-12-02,2015-07-01
-7a6v,2021-10-06,2020-08-26
-4a65,2012-11-07,2011-10-31
-4a60,2011-11-09,2011-10-31
-1a61,1998-06-17,1998-03-05
-7a6r,2021-08-25,2020-08-26
-6a6e,2019-10-09,2018-06-27
-3a62,2009-10-27,2009-08-18
-5a6l,2016-10-19,2015-06-30
-4a6b,2012-05-09,2011-11-01
-3a6q,2010-09-01,2009-09-08
-4a63,2011-12-21,2011-10-31
-6a68,2019-03-13,2018-06-26
-7a69,2020-10-21,2020-08-25
-7a6e,2020-10-14,2020-08-25
-1a6m,1999-04-06,1998-02-26
-4a6v,2012-06-13,2011-11-09
-4a66,2012-01-25,2011-10-31
-6a6g,2019-10-09,2018-06-27
-7a60,2021-02-24,2020-08-24
-7a6y,2021-08-25,2020-08-27
-5a6v,2015-10-21,2015-07-01
-7a6p,2021-03-10,2020-08-26
-4a6h,2012-06-13,2011-11-03
-4a6l,2012-01-25,2011-11-04
-6a63,2018-12-26,2018-06-26
-4a67,2012-01-25,2011-10-31
-1a6k,1999-04-06,1998-02-26
-1a6v,1998-07-15,1998-03-03
-2a6k,2006-06-13,2005-07-03
-6a6p,2019-07-10,2018-06-29
-3a6e,2010-02-09,2009-08-31
-6a69,2018-09-19,2018-06-27
-2a6i,2006-06-13,2005-07-02
-7a6d,2021-06-16,2020-08-25
-8a6d,2023-03-29,2022-06-17
-7a6q,2021-02-17,2020-08-26
-3a6d,2010-02-09,2009-08-31
-7a6h,2021-02-03,2020-08-25
-2a6v,2006-01-31,2005-07-04
-2a68,2005-09-20,2005-07-01
-2a6r,2005-08-23,2005-07-04
-3a60,2009-10-27,2009-08-17
-5a6q,2016-05-25,2015-06-30
-1a6y,1998-10-21,1998-03-04
-5a60,2015-08-05,2015-06-23
-6a6t,2019-05-15,2018-06-29
-6a6q,2019-01-23,2018-06-29
-8a66,2022-07-20,2022-06-16
-8a6x,2024-01-10,2022-06-20
-4a6f,2012-06-13,2011-11-02
-6a6s,2019-05-15,2018-06-29
-8a67,2023-02-15,2022-06-16
-1a6b,1999-08-23,1998-02-23
-8a63,2022-11-02,2022-06-16
-6a6l,2019-06-19,2018-06-28
-7a68,2020-10-21,2020-08-25
-3a68,2009-12-08,2009-08-26
-3a6r,2010-09-01,2009-09-08
-6a6r,2019-05-15,2018-06-29
-6a6h,2019-07-03,2018-06-28
-8a6w,2023-07-05,2022-06-20
-7a6b,2020-09-02,2020-08-25
-4a61,2012-11-07,2011-10-31
-3a6j,2010-02-09,2009-09-02
-3a65,2010-09-01,2009-08-21
-7a6j,2022-02-23,2020-08-25
-4a6e,2012-11-07,2011-11-01
-6a62,2018-12-26,2018-06-26
-3a6u,2009-10-27,2009-09-09
-4a62,2012-11-07,2011-10-31
-1a69,1998-10-14,1998-03-08
-8a68,2023-04-26,2022-06-16
-2a6l,2005-10-18,2005-07-03
-3a6h,2010-02-09,2009-08-31
-7a6a,2020-09-02,2020-08-25
-7a6w,2021-03-17,2020-08-27
-8a6e,2023-03-29,2022-06-17
-1a6q,1998-05-27,1998-02-27
-6a67,2018-08-29,2018-06-26
-6a6n,2019-01-16,2018-06-28
-2a65,2005-08-02,2005-07-01
-1a6n,1999-04-06,1998-02-26
-6a6m,2019-02-20,2018-06-28
-8a6z,2023-05-31,2022-06-20
-7a65,2020-10-14,2020-08-25
-5a65,2015-08-05,2015-06-24
-4a6k,2012-06-13,2011-11-04
-3a6l,2010-02-09,2009-09-02
-3a64,2009-09-01,2009-08-21
-7a6t,2022-03-23,2020-08-26
-2a6h,2005-09-20,2005-07-02
-6a64,2018-12-26,2018-06-26
-5a6a,2015-09-23,2015-06-24
-6a6f,2019-10-09,2018-06-27
-4a6d,2012-11-07,2011-11-01
-2a69,2005-09-20,2005-07-02
-3a6n,2010-05-26,2009-09-04
-7a6f,2020-10-14,2020-08-25
-6a6j,2019-06-19,2018-06-28
-6a6v,2019-05-15,2018-06-29
-7a61,2021-02-24,2020-08-24
-6a6u,2019-05-15,2018-06-29
-3a6s,2009-10-27,2009-09-09
-4a6r,2012-01-25,2011-11-08
-1a65,1999-03-30,1998-03-05
-4a6t,2012-01-25,2011-11-08
-3a6k,2010-02-09,2009-09-02
-6a60,2018-10-10,2018-06-25
-5a6k,2015-09-23,2015-06-26
-3a61,2009-10-27,2009-08-18
-7lig,2021-08-11,2021-01-27
-3lir,2010-09-01,2010-01-25
-3li6,2010-02-02,2010-01-24
-7li1,2022-02-23,2021-01-26
-1li6,2002-05-08,2002-04-17
-2li2,2012-04-04,2011-08-18
-3lik,2010-09-01,2010-01-25
-5lia,2016-11-09,2016-07-14
-3li1,2010-06-16,2010-01-23
-5lip,1998-08-19,1997-09-02
-7lir,2021-11-24,2021-01-27
-4li6,2013-08-14,2013-07-02
-5liy,2016-10-12,2016-07-15
-4liq,2014-06-18,2013-07-03
-3liz,2010-12-15,2010-01-25
-5li7,2016-12-21,2016-07-14
-7li8,2021-12-15,2021-01-26
-2li0,2012-04-04,2011-08-18
-5li3,2016-11-23,2016-07-14
-4liz,2014-07-23,2013-07-04
-6lig,2020-12-16,2019-12-10
-4li0,2013-10-09,2013-07-01
-7lim,2022-02-09,2021-01-27
-1li4,2003-05-20,2002-04-17
-7liw,2021-05-19,2021-01-28
-4li7,2013-08-14,2013-07-02
-3li2,2010-02-09,2010-01-23
-2liq,2012-06-06,2011-08-30
-7lij,2022-02-09,2021-01-27
-5lie,2016-12-21,2016-07-14
-7li5,2022-02-02,2021-01-26
-4lip,1998-08-19,1997-08-18
-7liz,2021-04-07,2021-01-28
-7lix,2021-04-07,2021-01-28
-6li2,2020-02-26,2019-12-10
-3liq,2010-07-14,2010-01-25
-6lis,2020-11-11,2019-12-12
-3lit,2010-07-14,2010-01-25
-2lig,1995-09-15,1995-04-18
-7li4,2021-06-16,2021-01-26
-3lil,2010-09-01,2010-01-25
-3lie,2010-05-05,2010-01-24
-2lit,2011-12-07,2011-08-31
-7lin,2021-04-14,2021-01-27
-6lio,2020-09-30,2019-12-12
-3lii,2010-03-16,2010-01-25
-1li9,2002-09-11,2002-04-17
-6li1,2020-02-26,2019-12-10
-6lik,2020-08-05,2019-12-11
-7lio,2021-04-14,2021-01-27
-1li0,2002-09-11,2002-04-17
-6lit,2020-10-07,2019-12-13
-7lik,2022-02-09,2021-01-27
-4li8,2013-08-14,2013-07-02
-6lih,2020-12-16,2019-12-11
-5lih,2016-09-14,2016-07-14
-6li7,2020-08-05,2019-12-10
-5lif,2016-12-21,2016-07-14
-7lil,2022-02-09,2021-01-27
-4lii,2013-09-04,2013-07-02
-6lij,2020-12-16,2019-12-11
-3lip,1997-06-16,1997-04-18
-3lin,2010-07-14,2010-01-25
-4lil,2013-12-11,2013-07-02
-4lik,2013-12-11,2013-07-02
-3lih,2010-05-12,2010-01-24
-4li5,2013-08-28,2013-07-02
-3li0,2010-06-16,2010-01-23
-7li6,2021-12-15,2021-01-26
-2liw,2011-12-21,2011-09-01
-5lik,2016-07-27,2016-07-14
-5li8,2016-12-21,2016-07-14
-6lin,2020-09-30,2019-12-12
-3lij,2010-02-02,2010-01-25
-7li7,2021-12-15,2021-01-26
-2li8,2011-12-07,2011-08-25
-6li4,2020-09-16,2019-12-10
-4lin,2014-02-12,2013-07-02
-1lia,1997-07-29,1996-01-29
-5li9,2016-09-14,2016-07-14
-3liw,2010-04-07,2010-01-25
-3liv,2010-07-14,2010-01-25
-7lit,2022-02-09,2021-01-27
-1lin,1996-03-08,1995-10-11
-1lii,2002-05-15,2002-04-17
-3lib,2010-05-05,2010-01-24
-2lip,1997-03-12,1996-12-13
-6li0,2020-02-26,2019-12-10
-7lid,2021-08-11,2021-01-27
-2li9,2012-01-18,2011-08-25
-5liu,2016-07-27,2016-07-15
-6liz,2020-12-16,2019-12-13
-4li1,2013-08-07,2013-07-02
-4lit,2014-05-14,2013-07-03
-5lid,2016-10-26,2016-07-14
-7li9,2021-12-15,2021-01-26
-5lil,2017-11-15,2016-07-15
-5liv,2016-11-23,2016-07-15
-6lil,2020-09-30,2019-12-12
-3liy,2010-07-14,2010-01-25
-3li5,2010-04-07,2010-01-24
-1li7,2002-04-26,2002-04-17
-2li1,2012-04-04,2011-08-18
-5li0,2016-12-28,2016-07-13
-5lix,2016-07-27,2016-07-15
-4li4,2014-05-28,2013-07-02
-4lis,2013-10-23,2013-07-03
-3li4,2010-04-07,2010-01-24
-6lid,2020-04-29,2019-12-10
-4li3,2014-07-09,2013-07-02
-1lih,1995-09-15,1995-04-18
-5liw,2016-07-27,2016-07-15
-7li0,2022-02-23,2021-01-26
-3lio,2010-09-08,2010-01-25
-5li1,2016-09-14,2016-07-13
-7lis,2022-02-09,2021-01-27
-7li3,2021-06-16,2021-01-26
-6lim,2020-12-16,2019-12-12
-6li9,2020-04-29,2019-12-10
-4liv,2014-05-14,2013-07-03
-7lia,2021-12-15,2021-01-26
-1li3,2002-05-08,2002-04-17
-4lim,2013-12-18,2013-07-02
-3lix,2010-07-14,2010-01-25
-5li6,2016-12-21,2016-07-14
-1lij,2002-05-15,2002-04-17
-2lir,2011-12-07,2011-08-31
-1liq,2002-05-29,2002-04-18
-1li5,2002-04-26,2002-04-17
-1lik,2002-05-15,2002-04-17
-6lip,2020-12-16,2019-12-12
-7liy,2021-04-07,2021-01-28
-7lii,2022-02-09,2021-01-27
-3li3,2010-04-07,2010-01-24
-4lix,2013-10-02,2013-07-04
-6li6,2020-09-16,2019-12-10
-4o1k,2014-03-05,2013-12-16
-7o1p,2021-05-26,2021-03-30
-7o1x,2021-09-15,2021-03-30
-1o1v,2003-02-18,2003-02-10
-6o12,2019-06-26,2019-02-17
-3o1c,2010-08-04,2010-07-21
-6o1x,2020-02-26,2019-02-22
-2o12,2008-04-08,2006-11-28
-7o1l,2021-08-25,2021-03-29
-7o1t,2021-05-26,2021-03-30
-7o1u,2021-09-01,2021-03-30
-5o1d,2018-05-09,2017-05-18
-2o11,2008-04-08,2006-11-28
-7o1s,2021-05-26,2021-03-30
-5o1f,2018-05-09,2017-05-18
-3o1m,2010-11-17,2010-07-21
-4o1r,2014-03-19,2013-12-16
-1o1i,2002-12-18,2002-11-19
-7o14,2022-04-13,2021-03-28
-3o1d,2011-07-06,2010-07-21
-7o1b,2022-02-02,2021-03-29
-5o1g,2018-05-09,2017-05-18
-2o17,2007-11-20,2006-11-28
-4o1m,2014-02-05,2013-12-16
-5o17,2017-11-15,2017-05-18
-2o1y,2007-02-27,2006-11-29
-3o1u,2010-11-17,2010-07-22
-4o15,2014-10-22,2013-12-15
-3o1s,2010-11-17,2010-07-22
-3o1h,2011-12-21,2010-07-21
-2o13,2007-12-11,2006-11-28
-2o1h,2007-02-06,2006-11-28
-6o11,2019-06-26,2019-02-17
-5o1a,2018-05-09,2017-05-18
-3o1x,2010-08-04,2010-07-22
-6o1g,2019-03-06,2019-02-19
-3o1a,2010-11-03,2010-07-21
-6o1c,2020-02-19,2019-02-19
-4o1o,2014-02-05,2013-12-16
-5o1e,2018-05-09,2017-05-18
-2o10,2007-12-11,2006-11-28
-3o1e,2011-07-06,2010-07-21
-5o12,2017-11-01,2017-05-17
-4o1g,2014-11-26,2013-12-15
-2o1e,2006-12-12,2006-11-28
-7o1c,2021-09-01,2021-03-29
-2o1k,2006-12-26,2006-11-29
-2o1d,2007-11-20,2006-11-28
-1o1h,2002-11-27,2002-11-07
-3o1n,2010-08-11,2010-07-21
-7o1v,2021-09-01,2021-03-30
-5o1l,2017-08-02,2017-05-18
-4o1b,2014-10-22,2013-12-15
-7o1f,2022-04-13,2021-03-29
-6o1a,2020-02-19,2019-02-18
-6o1h,2020-02-19,2019-02-19
-4o1f,2015-01-21,2013-12-15
-3o18,2010-11-03,2010-07-21
-5o1m,2017-08-02,2017-05-18
-7o1z,2021-09-15,2021-03-30
-4o13,2014-10-22,2013-12-15
-2o14,2006-12-12,2006-11-28
-3o14,2010-09-08,2010-07-20
-3o1r,2010-11-17,2010-07-21
-3o1t,2010-11-17,2010-07-22
-5o1o,2017-06-28,2017-05-18
-7o10,2022-04-13,2021-03-28
-7o1r,2021-09-15,2021-03-30
-7o1a,2021-09-01,2021-03-29
-7o1i,2021-08-25,2021-03-29
-1o1p,2002-12-18,2002-11-17
-5o1n,2017-05-31,2017-05-18
-4o1z,2014-01-22,2013-12-16
-5o1s,2018-05-30,2017-05-19
-6o13,2019-07-03,2019-02-17
-3o15,2011-07-27,2010-07-20
-7o18,2021-10-13,2021-03-28
-7o16,2022-04-13,2021-03-28
-1o1k,2002-12-18,2002-11-17
-6o19,2019-04-24,2019-02-18
-2o1q,2007-01-23,2006-11-29
-5o1k,2017-11-15,2017-05-18
-1o1z,2003-04-01,2003-02-12
-6o15,2019-11-27,2019-02-17
-6o1e,2019-03-20,2019-02-19
-2o1x,2006-12-26,2006-11-29
-1o1r,2003-05-06,2003-01-14
-7o1w,2021-09-01,2021-03-30
-3o1o,2010-11-17,2010-07-21
-1o16,2003-11-04,2002-10-25
-7o1o,2021-05-26,2021-03-30
-2o1j,2006-12-26,2006-11-29
-5o13,2017-11-01,2017-05-17
-2o1o,2006-12-12,2006-11-29
-1o1l,2002-12-18,2002-11-17
-3o1p,2010-11-17,2010-07-21
-7o17,2022-04-13,2021-03-28
-5o1h,2018-05-09,2017-05-18
-7o15,2022-04-13,2021-03-28
-4o16,2014-10-22,2013-12-15
-5o1b,2018-05-09,2017-05-18
-2o1v,2007-10-23,2006-11-29
-4o1y,2014-01-29,2013-12-16
-4o1l,2014-11-26,2013-12-16
-5o1u,2017-10-25,2017-05-19
-2o18,2006-12-05,2006-11-28
-6o1v,2019-06-26,2019-02-21
-1o1j,2002-12-18,2002-11-17
-4o1t,2014-06-18,2013-12-16
-5o10,2018-03-28,2017-05-17
-2o1g,2007-02-06,2006-11-28
-4o1p,2014-02-05,2013-12-16
-6o1w,2020-02-26,2019-02-22
-4o1w,2014-04-23,2013-12-16
-2o19,2007-04-03,2006-11-28
-5o18,2017-11-15,2017-05-18
-1o1s,2003-05-06,2003-01-14
-4o12,2014-06-18,2013-12-14
-5o1c,2018-05-09,2017-05-18
-4o1q,2014-04-30,2013-12-16
-6o1t,2019-03-13,2019-02-21
-2o1b,2006-12-12,2006-11-28
-4o1j,2014-03-05,2013-12-16
-1o12,2002-12-18,2002-10-15
-3o1v,2010-11-17,2010-07-22
-6o1s,2019-03-06,2019-02-21
-7o13,2022-11-02,2021-03-28
-6o1j,2020-02-26,2019-02-20
-2o1s,2006-12-26,2006-11-29
-3o1y,2012-01-25,2010-07-22
-5o11,2017-11-01,2017-05-17
-5o1j,2018-03-14,2017-05-18
-6o1y,2020-02-26,2019-02-22
-2o1l,2006-12-19,2006-11-29
-5o1y,2017-08-02,2017-05-19
-7o11,2022-04-13,2021-03-28
-7o1y,2021-09-01,2021-03-30
-4o1v,2014-04-30,2013-12-16
-2o1u,2007-10-23,2006-11-29
-7o19,2021-09-01,2021-03-29
-2o1z,2006-12-12,2006-11-29
-4o11,2014-01-15,2013-12-14
-4o10,2014-06-18,2013-12-14
-2o1f,2007-02-06,2006-11-28
-1o1m,2002-12-18,2002-11-17
-5o1z,2017-08-02,2017-05-19
-3o1g,2010-10-06,2010-07-21
-1o1n,2002-12-18,2002-11-17
-5o1i,2018-05-09,2017-05-18
-2o1n,2006-12-19,2006-11-29
-1o1t,2003-05-06,2003-01-14
-6o10,2019-06-26,2019-02-17
-7o12,2022-04-13,2021-03-28
-4o1e,2015-01-21,2013-12-15
-1o1o,2002-12-18,2002-11-17
-4o1d,2014-10-22,2013-12-15
-6t31,2020-11-18,2019-10-10
-8t3k,2023-11-29,2023-06-07
-3t3w,2011-09-14,2011-07-25
-3t3i,2012-02-15,2011-07-25
-8t3o,2024-01-17,2023-06-07
-3t3z,2011-12-07,2011-07-25
-1t3d,2004-07-13,2004-04-26
-6t38,2020-08-19,2019-10-10
-6t3f,2019-11-27,2019-10-10
-5t3n,2016-10-12,2016-08-26
-3t3e,2012-02-15,2011-07-25
-8t3s,2024-01-24,2023-06-07
-7t3v,2022-06-29,2021-12-08
-1t32,2005-03-01,2004-04-23
-3t3q,2011-12-07,2011-07-25
-5t38,2017-09-06,2016-08-25
-8t3v,2024-01-24,2023-06-07
-3t33,2013-04-17,2011-07-24
-3t3s,2011-12-07,2011-07-25
-5t3v,2017-05-17,2016-08-26
-7t3a,2022-04-06,2021-12-07
-6t3c,2020-01-01,2019-10-10
-1t3i,2004-09-21,2004-04-26
-6t35,2020-11-18,2019-10-10
-1t37,2004-05-04,2004-04-25
-3t3g,2012-02-15,2011-07-25
-6t37,2020-08-19,2019-10-10
-8t3y,2023-10-18,2023-06-08
-3t39,2011-08-24,2011-07-25
-6t3w,2020-11-18,2019-10-11
-3t3r,2011-12-07,2011-07-25
-3t3c,2012-06-20,2011-07-25
-7t3n,2022-12-14,2021-12-08
-1t3e,2004-07-27,2004-04-26
-1t3q,2004-09-14,2004-04-27
-5t3o,2017-06-14,2016-08-26
-8t3t,2023-10-18,2023-06-07
-6t3b,2020-01-01,2019-10-10
-7t3r,2022-03-23,2021-12-08
-7t3u,2022-03-23,2021-12-08
-1t36,2004-09-21,2004-04-24
-6t3l,2020-04-08,2019-10-11
-5t3z,2016-10-05,2016-08-26
-6t3u,2020-04-08,2019-10-11
-3t3h,2012-02-15,2011-07-25
-7t32,2022-08-10,2021-12-06
-3t3d,2012-02-15,2011-07-25
-7t3m,2022-08-24,2021-12-08
-3t3v,2012-03-14,2011-07-25
-7t3p,2022-03-23,2021-12-08
-8t31,2024-05-22,2023-06-07
-7t33,2022-02-23,2021-12-06
-8t3l,2024-05-08,2023-06-07
-8t3u,2024-05-22,2023-06-07
-5t37,2017-03-01,2016-08-24
-7t37,2022-05-04,2021-12-07
-8t3p,2023-11-08,2023-06-07
-1t3t,2004-09-14,2004-04-27
-7t3e,2022-12-14,2021-12-07
-5t3x,2016-10-05,2016-08-26
-7t3l,2022-09-21,2021-12-08
-5t3d,2016-09-21,2016-08-25
-3t3u,2012-03-14,2011-07-25
-6t3v,2020-11-18,2019-10-11
-6t32,2020-11-18,2019-10-10
-7t3t,2022-03-23,2021-12-08
-5t3q,2016-09-21,2016-08-26
-5t3r,2016-12-14,2016-08-26
-7t3z,2021-12-22,2021-12-09
-5t33,2016-09-07,2016-08-24
-7t36,2022-01-19,2021-12-07
-3t37,2012-08-15,2011-07-25
-6t3e,2020-05-13,2019-10-10
-7t3b,2022-04-06,2021-12-07
-5t3s,2016-09-28,2016-08-26
-3t31,2011-08-17,2011-07-24
-1t3c,2004-06-29,2004-04-26
-3t35,2012-06-06,2011-07-24
-7t3q,2022-03-23,2021-12-08
-3t3p,2012-03-28,2011-07-25
-3t3y,2012-03-07,2011-07-25
-1t3z,2004-08-03,2004-04-28
-7t3s,2022-12-21,2021-12-08
-6t3g,2020-09-02,2019-10-10
-7t3y,2021-12-22,2021-12-09
-8t3w,2023-10-18,2023-06-07
-6t30,2020-11-18,2019-10-10
-6t36,2021-01-20,2019-10-10
-1t3n,2004-07-20,2004-04-27
-5t36,2017-03-01,2016-08-24
-5t30,2017-05-17,2016-08-24
-6t34,2019-11-13,2019-10-10
-8t3m,2024-05-08,2023-06-07
-3t34,2012-06-06,2011-07-24
-5t35,2017-03-08,2016-08-24
-1t3m,2004-07-13,2004-04-27
-7t3c,2022-04-06,2021-12-07
-5t39,2017-09-06,2016-08-25
-3t3n,2011-10-19,2011-07-25
-6t3d,2020-06-24,2019-10-10
-3t3o,2011-10-19,2011-07-25
-6t3q,2020-05-13,2019-10-11
-5t31,2018-02-21,2016-08-24
-7t3d,2022-01-12,2021-12-07
-8t33,2024-05-22,2023-06-07
-1t31,2005-03-01,2004-04-23
-7t30,2022-03-16,2021-12-06
-8t32,2024-05-22,2023-06-07
-3t3f,2012-02-15,2011-07-25
-1t3k,2004-09-07,2004-04-27
-1t3r,2005-05-03,2004-04-27
-1t3s,2004-05-25,2004-04-27
-6t3m,2020-11-18,2019-10-11
-7t3i,2022-03-02,2021-12-08
-5t3h,2016-11-30,2016-08-25
-7t3f,2022-08-31,2021-12-07
-7t39,2021-12-22,2021-12-07
-1t34,2004-08-03,2004-04-23
-8t3r,2024-05-22,2023-06-07
-3t3m,2012-03-28,2011-07-25
-6t3p,2020-11-18,2019-10-11
-1t3a,2004-06-29,2004-04-26
-3q49,2011-03-16,2010-12-23
-4q48,2015-05-20,2014-04-14
-5q4x,2018-08-08,2017-05-25
-2q4h,2007-06-19,2007-05-31
-6q4c,2019-03-20,2018-12-05
-5q4g,2018-08-08,2017-05-25
-2q4z,2007-06-19,2007-05-31
-5q4a,2018-08-08,2017-05-25
-3q43,2011-03-16,2010-12-22
-6q4v,2019-02-27,2018-12-06
-5q4m,2018-08-08,2017-05-25
-6q4i,2019-03-20,2018-12-05
-3q4p,2011-01-12,2010-12-24
-2q4r,2007-06-19,2007-05-31
-4q47,2015-05-20,2014-04-14
-5q4p,2018-08-08,2017-05-25
-6q4n,2019-11-13,2018-12-06
-3q4t,2011-02-09,2010-12-24
-1q4j,2003-11-25,2003-08-04
-5q4u,2018-08-08,2017-05-25
-3q45,2011-02-16,2010-12-22
-3q4a,2011-03-16,2010-12-23
-5q4c,2018-08-08,2017-05-25
-2q4v,2007-06-19,2007-05-31
-4q40,2014-07-16,2014-04-12
-5q4l,2018-08-08,2017-05-25
-5q4s,2018-08-08,2017-05-25
-5q49,2018-08-08,2017-05-25
-7q4f,2022-02-23,2021-10-30
-7q44,2022-11-16,2021-10-29
-1q45,2003-11-25,2003-08-01
-4q4s,2014-07-09,2014-04-15
-6q4f,2019-03-20,2018-12-05
-2q40,2007-06-19,2007-05-31
-3q4j,2011-12-28,2010-12-23
-1q4w,2004-04-13,2003-08-04
-8q49,2024-06-05,2023-08-05
-6q4u,2019-02-27,2018-12-06
-2q46,2007-06-19,2007-05-31
-2q4x,2007-06-19,2007-05-31
-4q4m,2015-06-10,2014-04-15
-7q4l,2022-05-04,2021-10-31
-4q4q,2014-07-09,2014-04-15
-1q4q,2003-11-04,2003-08-04
-4q4r,2014-07-09,2014-04-15
-8q4v,2023-12-06,2023-08-07
-6q4b,2019-03-20,2018-12-05
-5q47,2018-08-08,2017-05-25
-4q4a,2014-07-16,2014-04-14
-8q42,2023-11-22,2023-08-04
-5q4e,2018-08-08,2017-05-25
-6q4m,2019-12-25,2018-12-06
-5q41,2018-08-08,2017-05-25
-5q43,2018-08-08,2017-05-25
-2q42,2007-06-19,2007-05-31
-3q4g,2011-01-26,2010-12-23
-8q41,2023-11-22,2023-08-04
-4q4f,2014-07-30,2014-04-14
-7q4u,2022-11-16,2021-11-02
-8q48,2024-06-05,2023-08-05
-8q43,2023-11-22,2023-08-04
-6q48,2019-03-20,2018-12-05
-3q40,2011-06-22,2010-12-22
-4q4u,2014-09-03,2014-04-15
-8q45,2024-06-05,2023-08-05
-1q43,2003-09-09,2003-08-01
-1q47,2004-08-03,2003-08-01
-6q40,2019-10-16,2018-12-05
-3q46,2012-01-04,2010-12-23
-8q4t,2023-12-06,2023-08-07
-8q4p,2023-12-06,2023-08-07
-4q4w,2014-11-05,2014-04-15
-4q43,2015-05-06,2014-04-13
-7q41,2022-11-16,2021-10-29
-4q4k,2014-07-16,2014-04-14
-6q4x,2019-09-18,2018-12-06
-1q4n,2004-03-16,2003-08-04
-3q4q,2011-05-18,2010-12-24
-4q4x,2014-11-05,2014-04-15
-4q4b,2014-07-30,2014-04-14
-4q45,2015-05-06,2014-04-13
-8q4q,2023-12-06,2023-08-07
-4q4d,2014-08-06,2014-04-14
-6q4j,2019-03-20,2018-12-05
-8q44,2023-11-22,2023-08-04
-6q4y,2019-09-18,2018-12-06
-4q4o,2014-07-09,2014-04-15
-3q4r,2011-05-18,2010-12-24
-5q42,2018-08-08,2017-05-25
-7q4k,2022-11-16,2021-10-31
-6q4r,2019-04-10,2018-12-06
-7q4p,2022-03-30,2021-11-01
-5q4o,2018-08-08,2017-05-25
-6q4a,2019-03-20,2018-12-05
-5q4t,2018-08-08,2017-05-25
-4q44,2015-05-06,2014-04-13
-5q48,2018-08-08,2017-05-25
-6q4d,2019-03-20,2018-12-05
-3q41,2011-03-23,2010-12-22
-1q41,2003-10-21,2003-08-01
-4q4z,2014-07-30,2014-04-15
-4q4y,2014-11-05,2014-04-15
-8q4h,2023-10-18,2023-08-07
-7q4d,2022-07-20,2021-10-30
-4q4l,2014-04-30,2014-04-14
-7q4g,2022-02-23,2021-10-30
-6q4t,2019-02-27,2018-12-06
-4q49,2015-02-25,2014-04-14
-5q45,2018-08-08,2017-05-25
-2q4a,2007-06-19,2007-05-31
-3q4i,2011-07-13,2010-12-23
-1q4r,2003-11-25,2003-08-04
-7q47,2021-11-17,2021-10-29
-6q4o,2019-11-13,2018-12-06
-2q4l,2007-06-19,2007-05-31
-6q4k,2019-03-20,2018-12-05
-8q4m,2023-12-06,2023-08-07
-1q4v,2003-08-19,2003-08-04
-5q4q,2018-08-08,2017-05-25
-2q4w,2007-06-19,2007-05-31
-1q4u,2003-09-23,2003-08-04
-7q4a,2022-08-03,2021-10-29
-7q42,2022-11-16,2021-10-29
-4q4e,2015-04-15,2014-04-14
-3q4z,2011-12-21,2010-12-26
-3q4l,2011-12-28,2010-12-23
-7q4e,2022-07-20,2021-10-30
-8q46,2024-06-05,2023-08-05
-3q47,2011-03-16,2010-12-23
-1q4k,2003-11-11,2003-08-04
-7q4i,2022-04-13,2021-10-31
-7q4o,2022-03-30,2021-11-01
-8q4a,2024-06-05,2023-08-05
-6q4g,2019-03-20,2018-12-05
-3q4y,2011-01-26,2010-12-26
-5q4r,2018-08-08,2017-05-25
-3q4b,2011-11-30,2010-12-23
-5q4v,2018-08-08,2017-05-25
-5q46,2018-08-08,2017-05-25
-4q4c,2014-08-06,2014-04-14
-5q4f,2018-08-08,2017-05-25
-4q4p,2014-07-09,2014-04-15
-8q47,2024-06-05,2023-08-05
-3q4k,2011-12-28,2010-12-23
-3q4u,2011-02-09,2010-12-24
-5q4b,2018-08-08,2017-05-25
-7q4r,2022-02-02,2021-11-02
-8q4n,2023-12-06,2023-08-07
-7q4x,2023-05-17,2021-11-02
-5q44,2018-08-08,2017-05-25
-7q4c,2022-07-20,2021-10-30
-5q40,2018-08-08,2017-05-25
-6q4z,2019-09-25,2018-12-06
-5q4h,2018-08-08,2017-05-25
-4q41,2014-07-16,2014-04-12
-5q4d,2018-08-08,2017-05-25
-6q4p,2019-11-13,2018-12-06
-5q4j,2018-08-08,2017-05-25
-6q4h,2019-03-20,2018-12-05
-5q4y,2018-08-08,2017-05-25
-6q49,2019-03-20,2018-12-05
-1q4g,2004-01-06,2003-08-03
-4q42,2014-07-16,2014-04-12
-2q4y,2007-06-19,2007-05-31
-3q4d,2011-02-16,2010-12-23
-5q4k,2018-08-08,2017-05-25
-6q45,2019-07-10,2018-12-05
-7q45,2022-11-16,2021-10-29
-2q4s,2007-06-19,2007-05-31
-8q4r,2023-12-06,2023-08-07
-3q44,2011-03-16,2010-12-22
-3q4c,2011-03-02,2010-12-23
-7q49,2022-07-20,2021-10-29
-4q46,2015-02-25,2014-04-13
-5q4z,2018-08-08,2017-05-25
-5q4w,2018-08-08,2017-05-25
-7q4w,2023-02-15,2021-11-02
-2q4b,2007-06-19,2007-05-31
-4q4i,2015-04-15,2014-04-14
-3q4w,2012-01-04,2010-12-24
-5q4n,2018-08-08,2017-05-25
-7q4t,2022-02-23,2021-11-02
-3q4o,2011-05-18,2010-12-24
-8q40,2023-11-22,2023-08-04
-1q4t,2003-09-23,2003-08-04
-2q4o,2007-06-19,2007-05-31
-5q4i,2018-08-08,2017-05-25
-7q46,2022-11-16,2021-10-29
-7q4v,2023-02-22,2021-11-02
-6q4e,2019-03-20,2018-12-05
-1q4x,2004-02-03,2003-08-04
-8q4u,2023-12-06,2023-08-07
-1q4l,2003-10-14,2003-08-04
-7q43,2022-11-16,2021-10-29
-1q4s,2003-09-23,2003-08-04
-8q4w,2023-12-06,2023-08-07
-1cce,1994-07-31,1994-05-04
-6cck,2018-03-14,2018-02-07
-3ccg,2008-03-11,2008-02-25
-4ccq,2014-11-05,2013-10-24
-3ccz,2008-06-17,2008-02-26
-3cc2,2008-05-20,2008-02-23
-4ccz,2013-11-27,2013-10-29
-4cck,2014-05-14,2013-10-23
-4ccw,2014-01-22,2013-10-29
-4ccv,2014-02-19,2013-10-29
-6cc7,2019-02-13,2018-02-06
-5ccm,2015-09-09,2015-07-02
-2cci,2006-05-03,2006-01-16
-3cce,2008-05-20,2008-02-25
-2cct,2006-02-22,2006-01-18
-1cch,1994-04-30,1994-02-25
-7ccz,2021-03-17,2020-06-18
-3ccs,2008-05-20,2008-02-26
-2ccu,2006-02-22,2006-01-18
-8ccm,2024-02-07,2023-01-27
-8ccd,2023-04-26,2023-01-27
-8cc4,2023-12-06,2023-01-26
-7cci,2021-06-23,2020-06-17
-6ccf,2018-03-07,2018-02-07
-4ccp,1991-07-15,1990-02-28
-6ccv,2018-08-15,2018-02-07
-8cc5,2023-08-30,2023-01-26
-7ccn,2021-04-28,2020-06-17
-2ccp,1991-07-15,1990-02-28
-1cc0,2000-01-07,1999-03-03
-2cc0,2006-01-23,2006-01-10
-2ccd,2006-01-19,2006-01-16
-4ccy,2014-01-22,2013-10-29
-7ccc,2021-02-03,2020-06-16
-2ccv,2006-05-15,2006-01-18
-1cc3,1999-12-23,1999-03-03
-4ccc,2013-12-11,2013-10-21
-1cc1,1999-06-01,1999-03-03
-5ccr,2016-07-20,2015-07-02
-3ccw,2008-06-17,2008-02-26
-6ccl,2018-03-14,2018-02-07
-8cca,2023-04-26,2023-01-27
-4cco,2014-05-14,2013-10-23
-4ccd,2013-12-11,2013-10-21
-7ccv,2021-01-20,2020-06-18
-2ccg,2006-03-08,2006-01-16
-6ccx,2018-09-05,2018-02-07
-5ccn,2016-07-20,2015-07-02
-5cc8,2015-09-02,2015-07-01
-6cc0,2018-02-28,2018-02-05
-7ccx,2021-03-17,2020-06-18
-7ccf,2021-03-17,2020-06-17
-6ccb,2018-04-04,2018-02-06
-2cc2,2007-03-20,2006-01-11
-4cc6,2014-06-18,2013-10-18
-4ccr,2014-11-05,2013-10-25
-8ccc,2023-04-26,2023-01-27
-5ccd,2016-11-23,2015-07-01
-3ccu,2008-05-20,2008-02-26
-3ccn,2008-04-29,2008-02-26
-3cc7,2008-05-20,2008-02-25
-2cc7,2006-02-01,2006-01-13
-8cck,2024-02-07,2023-01-27
-5cc1,2015-12-23,2015-07-01
-7cco,2021-04-28,2020-06-17
-6cch,2018-08-29,2018-02-07
-3ccc,2008-10-21,2008-02-25
-5ccu,2015-09-02,2015-07-02
-4ccx,1995-07-10,1995-03-17
-4cc7,2013-10-30,2013-10-18
-5cc7,2016-08-10,2015-07-01
-6cco,2018-03-14,2018-02-07
-2ccw,2006-01-30,2006-01-18
-3ccj,2008-05-20,2008-02-26
-4cce,2013-12-11,2013-10-21
-8cci,2023-07-26,2023-01-27
-2cc9,2006-01-31,2006-01-13
-8ccq,2023-07-12,2023-01-27
-4cc1,2013-11-27,2013-10-17
-8ccr,2023-08-09,2023-01-27
-2ccj,2006-03-08,2006-01-16
-1ccw,2000-03-01,1999-03-01
-2cch,2006-05-03,2006-01-16
-4cc5,2014-06-18,2013-10-18
-5ccv,2016-02-03,2015-07-02
-8cc7,2023-10-11,2023-01-26
-1cc5,1984-10-29,1984-08-10
-4ccl,2014-04-30,2013-10-23
-1cct,1995-02-07,1994-12-09
-3ccr,2008-05-20,2008-02-26
-1cc6,1999-03-12,1999-03-04
-5ccz,2016-08-10,2015-07-02
-6ccq,2018-03-14,2018-02-07
-5cc3,2016-08-10,2015-07-01
-4cc0,2013-11-27,2013-10-17
-3ccm,2008-05-20,2008-02-26
-4ccu,2014-01-29,2013-10-28
-4ccg,2014-01-08,2013-10-22
-8ccl,2024-02-07,2023-01-27
-5cc4,2015-07-15,2015-07-01
-1ccl,1998-11-25,1998-01-02
-5ccy,2016-03-16,2015-07-02
-1cc8,1999-12-12,1999-03-04
-8ccb,2023-04-26,2023-01-27
-8cce,2023-04-26,2023-01-27
-2ccl,2007-02-13,2006-01-16
-5ccc,2015-08-05,2015-07-01
-4ccn,2014-05-14,2013-10-23
-6ccs,2018-03-14,2018-02-07
-8ccg,2023-04-26,2023-01-27
-5cc2,2015-12-30,2015-07-01
-7cct,2021-06-23,2020-06-17
-1cca,1993-10-31,1993-01-04
-6ccu,2018-03-07,2018-02-07
-7cc9,2020-07-08,2020-06-16
-8ccj,2024-02-07,2023-01-27
-3ccp,1991-07-15,1990-02-28
-1ccu,1995-02-07,1994-12-09
-3cc8,2008-03-04,2008-02-25
-3ccq,2008-05-20,2008-02-26
-2ccr,2006-03-21,2006-01-18
-3cc6,2008-03-11,2008-02-25
-5ccx,2015-11-04,2015-07-02
-2ccb,2006-01-31,2006-01-13
-7ccp,1993-10-31,1993-06-07
-2ccy,1986-01-21,1985-08-27
-5ccs,2016-07-20,2015-07-02
-8ccz,2023-05-10,2023-01-28
-5cc5,2016-08-10,2015-07-01
-8cc0,2023-05-10,2023-01-26
-8cco,2023-03-01,2023-01-27
-8cc2,2024-02-07,2023-01-26
-3cch,2009-03-10,2008-02-25
-2ccs,2006-02-22,2006-01-18
-2ccc,2006-01-31,2006-01-13
-6cc6,2018-02-14,2018-02-06
-1ccp,1991-07-15,1990-02-28
-3cc9,2008-03-25,2008-02-25
-7cc2,2021-06-09,2020-06-16
-5cce,2016-11-16,2015-07-02
-1ccc,1993-10-31,1993-01-04
-7ccu,2021-01-20,2020-06-18
-5cc6,2016-08-10,2015-07-01
-5ccl,2015-09-09,2015-07-02
-2cca,2006-01-19,2006-01-16
-2cc6,2006-02-15,2006-01-12
-1ccj,1997-07-23,1997-01-22
-8ccs,2023-09-20,2023-01-27
-7cc7,2021-01-20,2020-06-16
-7ccw,2021-01-20,2020-06-18
-1ccz,1999-04-05,1999-03-02
-1cc4,1999-03-12,1999-03-04
-1cci,1997-07-07,1996-12-18
-8ccy,2024-02-07,2023-01-28
-1ccb,1993-10-31,1993-01-04
-3ccl,2008-05-20,2008-02-26
-8cct,2024-02-07,2023-01-27
-8cc1,2023-05-10,2023-01-26
-5cc0,2015-12-23,2015-07-01
-3ccv,2008-05-20,2008-02-26
-4ccb,2014-01-29,2013-10-21
-8ccw,2023-05-10,2023-01-27
-6ccp,1993-10-31,1993-06-07
-8ccv,2023-04-19,2023-01-27
-8cch,2023-04-26,2023-01-27
-2ccm,2006-01-26,2006-01-16
-6ccm,2018-03-14,2018-02-07
-5ccq,2016-07-20,2015-07-02
-3cc5,2009-03-03,2008-02-24
-2cc8,2006-01-31,2006-01-13
-8ccf,2023-04-26,2023-01-27
-6cct,2018-03-07,2018-02-07
-5ccg,2015-08-12,2015-07-02
-1cck,1998-11-25,1998-01-02
-6cce,2018-08-15,2018-02-07
-7cc3,2021-04-28,2020-06-16
-5cch,2015-08-12,2015-07-02
-6cci,2019-02-20,2018-02-07
-4ccs,2014-04-09,2013-10-25
-8ccu,2024-02-07,2023-01-27
-7cca,2020-11-25,2020-06-16
-4ccm,2014-05-14,2013-10-23
-3ccx,1995-07-10,1995-03-17
-8ccx,2023-12-13,2023-01-27
-1cc2,1999-03-11,1999-03-03
-6cc9,2018-09-05,2018-02-06
-8cc6,2023-10-11,2023-01-26
-7ccy,2021-03-17,2020-06-18
-6ccy,2018-05-02,2018-02-07
-5cci,2015-08-12,2015-07-02
-7cc4,2020-07-15,2020-06-16
-3cct,2008-06-17,2008-02-26
-5cc9,2015-08-05,2015-07-01
-1ccs,1995-02-07,1994-12-09
-5ccb,2015-11-04,2015-07-01
-3cc4,2008-05-20,2008-02-24
-4cc9,2013-12-11,2013-10-19
-5cco,2016-05-11,2015-07-02
-5cct,2016-05-11,2015-07-02
-5ccp,1993-10-31,1993-06-07
-3ccb,2008-10-21,2008-02-25
-1ccg,1994-07-31,1994-05-04
-6ccn,2018-03-14,2018-02-07
-7ccj,2020-07-08,2020-06-17
-8cc3,2023-08-30,2023-01-26
-1ccr,1983-04-21,1983-03-14
-8ccn,2023-02-22,2023-01-27
-7ccg,2020-09-09,2020-06-17
-6c0h,2018-09-05,2017-12-31
-1c0i,2002-02-27,1999-07-16
-3c0z,2008-02-19,2008-01-21
-2c0q,2006-01-09,2005-09-07
-4c0k,2013-10-09,2013-08-05
-8c05,2023-07-19,2022-12-15
-7c0u,2021-03-10,2020-05-01
-5c0w,2015-07-29,2015-06-12
-5c0p,2015-07-01,2015-06-12
-4c0b,2014-02-19,2013-08-01
-7c0k,2021-03-10,2020-05-01
-6c0r,2018-08-01,2018-01-02
-5c0i,2016-05-04,2015-06-12
-5c0j,2016-05-04,2015-06-12
-7c0s,2021-03-10,2020-05-01
-2c0i,2006-09-20,2005-09-03
-2c04,2007-02-13,2005-08-25
-8c0c,2023-04-26,2022-12-16
-6c07,2019-01-16,2017-12-28
-5c03,2015-09-16,2015-06-12
-7c0y,2021-03-10,2020-05-01
-6c0d,2018-03-21,2017-12-29
-5c0o,2015-07-08,2015-06-12
-2c0g,2006-08-29,2005-09-02
-8c03,2023-03-22,2022-12-15
-4c0c,2014-08-20,2013-08-01
-8c07,2023-08-23,2022-12-16
-5c0x,2015-08-05,2015-06-12
-6c0y,2018-09-05,2018-01-03
-1c0w,2000-07-22,1999-07-22
-3c0a,2009-01-20,2008-01-19
-6c0k,2018-08-01,2018-01-01
-6c0f,2018-03-14,2017-12-29
-2c0t,2006-09-20,2005-09-07
-4c04,2014-07-30,2013-07-31
-3c01,2008-04-22,2008-01-18
-3c0p,2008-07-15,2008-01-21
-4c0s,2014-08-27,2013-08-07
-4c0x,2013-10-30,2013-08-08
-7c0o,2021-03-10,2020-05-01
-1c0k,2000-11-22,1999-07-16
-7c0f,2021-03-10,2020-05-01
-7c0w,2021-03-10,2020-05-01
-6c0e,2018-02-07,2017-12-29
-2c02,2006-01-18,2005-08-24
-2c03,2007-02-13,2005-08-25
-5c08,2016-05-04,2015-06-12
-5c0t,2016-02-03,2015-06-12
-6c04,2018-03-28,2017-12-27
-5c0g,2016-05-04,2015-06-12
-7c0j,2020-12-16,2020-05-01
-4c06,2014-07-30,2013-07-31
-6c0t,2018-05-30,2018-01-02
-4c0n,2014-05-14,2013-08-06
-2c01,2006-01-18,2005-08-24
-2c0u,2006-02-01,2005-09-07
-8c0g,2023-12-27,2022-12-16
-5c09,2016-05-04,2015-06-12
-8c0h,,2022-12-16
-8c06,2023-08-23,2022-12-16
-7c0t,2021-03-10,2020-05-01
-7c04,2020-07-08,2020-04-30
-1c0t,2000-07-19,1999-07-19
-6c0n,2018-08-01,2018-01-01
-5c0u,2016-02-03,2015-06-12
-3c0h,2008-04-29,2008-01-20
-7c0z,2021-03-10,2020-05-01
-6c0g,2018-09-05,2017-12-31
-6c0l,2018-08-01,2018-01-01
-8c0v,2023-10-04,2022-12-19
-5c0k,2015-08-12,2015-06-12
-1c0r,1999-07-30,1999-07-20
-2c0p,2006-01-09,2005-09-07
-2c0b,2005-10-14,2005-08-30
-4c0w,2013-10-30,2013-08-08
-8c0f,2022-12-28,2022-12-16
-4c09,2014-08-20,2013-07-31
-4c0o,2014-01-22,2013-08-06
-8c0q,2023-03-08,2022-12-19
-4c0j,2013-10-09,2013-08-05
-1c0a,1999-11-23,1999-07-15
-5c0q,2015-09-16,2015-06-12
-7c0l,2021-03-10,2020-05-01
-6c0j,2018-08-01,2018-01-01
-3c0w,2008-05-06,2008-01-21
-4c07,2014-07-30,2013-07-31
-5c0r,2015-09-02,2015-06-12
-3c0b,2008-02-26,2008-01-19
-7c0i,2020-12-16,2020-05-01
-4c0l,2013-10-09,2013-08-05
-8c0z,2023-05-31,2022-12-19
-7c0n,2020-10-07,2020-05-01
-3c0i,2008-04-29,2008-01-20
-7c0m,2020-09-16,2020-05-01
-6c0o,2018-08-01,2018-01-01
-6c0p,2018-08-01,2018-01-01
-5c02,2016-05-04,2015-06-12
-6c02,2018-05-02,2017-12-27
-7c0r,2021-03-10,2020-05-01
-2c0c,2005-09-12,2005-08-30
-2c0k,2005-11-09,2005-09-05
-7c01,2020-05-27,2020-04-29
-5c0y,2015-08-05,2015-06-12
-1c0p,2000-11-22,1999-07-19
-1c09,2001-02-21,1999-07-15
-5c0z,2016-09-21,2015-06-12
-6c0u,2018-05-30,2018-01-02
-7c0v,2021-03-10,2020-05-01
-7c06,2020-09-30,2020-04-30
-7c0x,2021-03-10,2020-05-01
-1c0l,2000-11-22,1999-07-16
-7c00,2020-09-16,2020-04-29
-6c01,2018-05-02,2017-12-27
-2c0r,2006-03-22,2005-09-07
-7c0p,2020-12-09,2020-05-01
-5c07,2016-05-04,2015-06-12
-5c0e,2016-05-04,2015-06-12
-5c0l,2015-08-12,2015-06-12
-4c0q,2014-01-22,2013-08-06
-5c0c,2016-05-04,2015-06-12
-8c01,2022-12-28,2022-12-15
-4c01,2013-10-30,2013-07-30
-8c0j,2023-06-14,2022-12-17
-7c05,2020-07-08,2020-04-30
-2c0o,2006-09-20,2005-09-06
-6c09,2018-03-21,2017-12-28
-8c0t,2023-11-15,2022-12-19
-1c0u,2000-07-19,1999-07-19
-1c0f,2000-03-01,1999-07-16
-1c0n,2000-07-17,1999-07-17
-8c04,2023-08-02,2022-12-15
-2c05,2006-01-18,2005-08-25
-3c0v,2008-05-20,2008-01-21
-3c0j,2008-09-23,2008-01-21
-3c04,2008-09-09,2008-01-18
-6c0s,2018-03-07,2018-01-02
-1c0q,1999-07-30,1999-07-20
-6c0v,2018-01-31,2018-01-02
-7c07,2020-09-30,2020-04-30
-3c06,2009-01-20,2008-01-18
-5c0b,2016-05-04,2015-06-12
-8c0a,2023-12-27,2022-12-16
-3c0x,2008-05-06,2008-01-21
-6c05,2018-03-28,2017-12-27
-2c0n,2005-09-29,2005-09-06
-6c08,2018-06-20,2017-12-28
-6c0m,2018-06-27,2018-01-01
-4c05,2014-07-30,2013-07-31
-4c08,2014-07-30,2013-07-31
-4c0r,2013-08-21,2013-08-07
-3c0o,2008-02-12,2008-01-21
-5c0f,2016-05-04,2015-06-12
-8c0i,2023-05-03,2022-12-16
-8c08,2023-12-27,2022-12-16
-4c0a,2013-09-25,2013-08-01
-4c03,2014-07-30,2013-07-31
-5c0a,2016-05-04,2015-06-12
-6c0z,2019-01-16,2018-01-03
-3c0y,2008-02-19,2008-01-21
-4c02,2013-08-07,2013-07-31
-1c0g,2000-03-01,1999-07-16
-7c08,2020-09-30,2020-04-30
-2c06,2006-02-08,2005-08-25
-6c0b,2018-05-16,2017-12-28
-3c0q,2008-12-09,2008-01-21
-8c0r,2023-03-08,2022-12-19
-8c0k,2023-08-02,2022-12-17
-1c07,2000-07-19,1999-07-14
-6c06,2018-03-28,2017-12-27
-8c0u,2023-09-20,2022-12-19
-3c09,2008-04-15,2008-01-18
-3c0s,2008-12-09,2008-01-21
-8c0w,2023-10-04,2022-12-19
-3c03,2008-04-22,2008-01-18
-7c02,2020-07-29,2020-04-30
-3c0g,2008-04-29,2008-01-20
-6ub4,2020-05-20,2019-09-11
-6ubz,2019-10-23,2019-09-13
-1ubj,2003-04-29,2003-04-04
-1ubt,2003-04-29,2003-04-04
-7ub0,2022-04-20,2022-03-14
-4ubd,2015-06-24,2014-08-12
-6ub9,2019-09-25,2019-09-11
-4ubh,2015-02-11,2014-08-13
-1ubx,1997-03-12,1996-10-14
-5ubj,2017-09-27,2016-12-20
-7ubt,2023-02-15,2022-03-15
-7uba,2023-03-29,2022-03-14
-5ub9,2017-12-20,2016-12-20
-3ubv,2012-03-28,2011-10-25
-5ub7,2018-01-10,2016-12-20
-1ubd,1996-12-23,1996-10-04
-5ubx,2017-09-20,2016-12-21
-2ubp,1999-11-08,1998-11-04
-4ub9,2015-06-24,2014-08-12
-5ubh,2017-12-20,2016-12-20
-1uby,1997-03-12,1996-10-14
-4ub6,2014-12-03,2014-08-12
-4ub1,2014-11-12,2014-08-11
-1ubf,2003-07-22,2003-04-04
-4ubt,2014-12-17,2014-08-13
-1ub3,2003-04-08,2003-03-28
-6ubn,2019-10-23,2019-09-12
-7ub6,2022-04-20,2022-03-14
-7ubz,2022-08-24,2022-03-15
-1ub2,2004-03-28,2003-03-28
-1ubh,2003-04-29,2003-04-04
-7ubn,2022-09-28,2022-03-15
-3ubm,2012-03-21,2011-10-24
-6ubp,2021-02-03,2019-09-12
-5ubu,2017-01-04,2016-12-21
-3ubh,2011-12-21,2011-10-24
-6ub1,2020-05-20,2019-09-11
-4ub7,2015-07-01,2014-08-12
-6ub7,2020-05-20,2019-09-11
-7ub5,2022-04-20,2022-03-14
-7ubr,2022-08-17,2022-03-15
-8ubx,2024-03-27,2023-09-25
-5ubq,2017-05-10,2016-12-21
-7ubp,2022-03-23,2022-03-15
-5ub8,2017-01-11,2016-12-20
-7ubq,2022-03-23,2022-03-15
-6ube,2020-09-16,2019-09-11
-4ub2,2014-11-12,2014-08-11
-3ubd,2012-09-05,2011-10-24
-1ubb,2003-09-02,2003-04-03
-4ub4,2014-11-12,2014-08-11
-5ubk,2017-03-01,2016-12-20
-4ub8,2014-12-03,2014-08-12
-6ubb,2020-05-20,2019-09-11
-3ubf,2011-12-21,2011-10-24
-6ub3,2020-05-20,2019-09-11
-3uba,2011-12-28,2011-10-24
-4ubm,2015-08-19,2014-08-13
-3ubg,2011-12-21,2011-10-24
-1ubp,1999-03-02,1998-01-21
-3uby,2011-12-28,2011-10-25
-4ubb,2014-11-12,2014-08-12
-7ubk,2022-09-28,2022-03-15
-3ubb,2012-06-13,2011-10-24
-3ubt,2012-10-03,2011-10-24
-4ubc,2014-11-12,2014-08-12
-6ubi,2020-03-18,2019-09-11
-3ub5,2012-04-25,2011-10-23
-1ubm,2003-04-29,2003-04-04
-3ubc,2012-03-28,2011-10-24
-5ubt,2017-02-08,2016-12-21
-7ubl,2022-09-28,2022-03-15
-4ub3,2014-11-12,2014-08-11
-7ub8,2022-03-23,2022-03-14
-4ubg,2014-11-26,2014-08-13
-7ub4,2022-03-30,2022-03-14
-3ubn,2011-11-23,2011-10-24
-4ubw,2014-12-17,2014-08-13
-1ubl,2003-04-29,2003-04-04
-4ubp,2000-03-06,1999-02-25
-3ubq,2011-11-23,2011-10-24
-8uby,2024-03-27,2023-09-25
-5ubr,2017-02-08,2016-12-21
-1ubo,2003-04-29,2003-04-04
-6ubw,2020-02-12,2019-09-13
-4uba,2015-07-01,2014-08-12
-3ubr,2012-04-25,2011-10-24
-6ub0,2020-05-20,2019-09-11
-7ubo,2022-06-08,2022-03-15
-6ub5,2020-05-20,2019-09-11
-3ubw,2012-01-25,2011-10-25
-6ubs,2020-07-29,2019-09-12
-5ubo,2017-12-20,2016-12-21
-1ubn,1999-06-08,1999-06-02
-5ubi,2017-12-20,2016-12-20
-1ubr,2003-04-29,2003-04-04
-6ubt,2020-07-29,2019-09-12
-6ubq,2020-09-23,2019-09-12
-4ubj,2015-08-19,2014-08-13
-6ubr,2019-10-23,2019-09-12
-4ubq,2014-12-24,2014-08-13
-1ub5,2004-04-20,2003-03-30
-4ubl,2015-08-19,2014-08-13
-5ubv,2017-12-27,2016-12-21
-1ubu,2003-04-29,2003-04-04
-6ub6,2020-05-20,2019-09-11
-7uby,2022-11-16,2022-03-15
-4ubv,2014-12-17,2014-08-13
-6ubh,2020-07-29,2019-09-11
-5ubg,2017-12-20,2016-12-20
-7ubm,2022-09-28,2022-03-15
-4ubu,2014-12-17,2014-08-13
-5uba,2017-02-22,2016-12-20
-4ubz,2015-05-27,2014-08-13
-4ubi,2015-08-19,2014-08-13
-6ubv,2020-09-16,2019-09-13
-8ubz,2024-03-27,2023-09-25
-8ubr,2024-02-21,2023-09-24
-3ubx,2011-11-16,2011-10-25
-4ub5,2014-11-12,2014-08-11
-7ubj,2022-09-28,2022-03-15
-6uby,2020-01-01,2019-09-13
-1ube,2003-07-22,2003-04-04
-1ubs,1996-03-08,1995-12-14
-3ubj,2011-11-23,2011-10-24
-4ube,2014-09-24,2014-08-12
-5ub5,2017-08-09,2016-12-20
-1ubw,1997-03-12,1996-10-14
-1ubk,2003-04-29,2003-04-04
-6ubo,2020-09-16,2019-09-12
-4ubs,2014-11-05,2014-08-13
-4ubo,2015-08-19,2014-08-13
-4ubn,2015-08-19,2014-08-13
-4ubk,2015-08-19,2014-08-13
-4ubf,2015-05-06,2014-08-12
-7ubu,2022-06-08,2022-03-15
-6uba,2020-05-20,2019-09-11
-5ubm,2017-11-08,2016-12-20
-3ubp,1999-12-17,1998-12-16
-3ubo,2011-11-09,2011-10-24
-4uby,2015-05-27,2014-08-13
-1ubz,2003-04-22,2003-04-07
-8ubw,2024-03-27,2023-09-25
-3ube,2011-11-23,2011-10-24
-1ubg,2003-07-22,2003-04-04
-8dhm,2022-11-23,2022-06-27
-8dhd,2022-10-12,2022-06-27
-8dhl,2023-05-17,2022-06-27
-6dhd,2018-07-25,2018-05-19
-1dht,1999-09-25,1998-03-25
-8dhh,2022-08-17,2022-06-27
-1dh3,2000-11-27,1999-11-27
-6dhu,2019-05-29,2018-05-21
-7dhn,2021-11-17,2020-11-16
-6dhb,2018-12-12,2018-05-19
-4dhy,2012-02-08,2012-01-30
-7dhr,2020-12-16,2020-11-17
-3dhc,2008-07-29,2008-06-17
-1dhr,1993-07-15,1992-03-30
-5dhj,2015-10-28,2015-08-31
-1dhp,1997-02-12,1995-02-09
-6dh9,2019-05-22,2018-05-18
-6dh5,2018-12-26,2018-05-18
-3dhr,2009-06-30,2008-06-18
-4dh5,2012-06-27,2012-01-27
-7dh0,2022-05-18,2020-11-12
-4dhf,2012-07-18,2012-01-27
-6dhy,2018-07-25,2018-05-21
-6dhp,2018-11-21,2018-05-20
-5dhu,2016-09-14,2015-08-31
-6dht,2019-04-03,2018-05-21
-3dht,2009-06-30,2008-06-18
-6dha,2019-03-13,2018-05-18
-1dhs,1998-02-25,1997-10-28
-7dhs,2021-09-15,2020-11-17
-4dh1,2012-06-27,2012-01-27
-5dha,2015-09-16,2015-08-30
-7dhx,2021-09-29,2020-11-17
-6dhk,2018-07-25,2018-05-20
-3dhf,2009-08-18,2008-06-17
-3dh0,2008-07-15,2008-06-16
-5dh5,2016-01-27,2015-08-29
-8dh4,2023-02-01,2022-06-24
-2dh5,2007-04-24,2006-03-23
-8dhf,2022-08-17,2022-06-27
-2dhn,1999-04-20,1998-03-31
-3dhz,2008-07-01,2008-06-19
-7dhc,2021-11-17,2020-11-13
-6dh4,2018-12-26,2018-05-18
-5dhq,2016-09-14,2015-08-31
-5dhp,2016-09-14,2015-08-31
-4dho,2013-07-31,2012-01-30
-3dhp,2008-07-01,2008-06-18
-5dhi,2015-09-16,2015-08-31
-4dh7,2012-06-27,2012-01-27
-6dh0,2018-12-26,2018-05-18
-7dh1,2022-02-02,2020-11-12
-7dho,2021-11-17,2020-11-16
-4dhr,2013-07-31,2012-01-30
-7dh6,2020-12-02,2020-11-13
-1dhj,1994-01-31,1993-10-29
-6dh1,2018-12-26,2018-05-18
-3dh2,2009-06-16,2008-06-16
-4dhn,2013-07-31,2012-01-30
-4dht,2013-07-31,2012-01-30
-6dhz,2018-07-25,2018-05-21
-4dhm,2013-07-31,2012-01-30
-7dhk,2021-11-17,2020-11-16
-2dh4,2006-04-04,2006-03-22
-3dhi,2008-12-30,2008-06-17
-4dh3,2012-06-27,2012-01-27
-4dhp,2013-07-31,2012-01-30
-8dhu,2024-01-17,2022-06-28
-1dhf,1990-07-15,1989-10-25
-6dh8,2018-12-26,2018-05-18
-2dho,2007-06-05,2006-03-24
-6dhf,2018-11-21,2018-05-20
-2dh3,2007-03-27,2006-03-21
-8dhk,2023-07-19,2022-06-27
-8dh0,2023-02-01,2022-06-24
-6dhn,2018-07-25,2018-05-20
-6dhm,2018-07-25,2018-05-20
-6dh3,2018-12-26,2018-05-18
-4dh6,2012-04-18,2012-01-27
-4dhu,2013-07-31,2012-01-30
-6dhh,2018-11-21,2018-05-20
-5dhh,2015-10-21,2015-08-31
-8dhg,2022-08-17,2022-06-27
-3dhh,2008-12-30,2008-06-17
-5dh3,2016-08-31,2015-08-29
-3dhv,2008-11-04,2008-06-18
-6dho,2018-11-21,2018-05-20
-2dhr,2006-06-27,2006-03-24
-8dht,2022-11-30,2022-06-28
-5dhf,2015-09-16,2015-08-30
-4dhs,2013-07-31,2012-01-30
-6dhq,2018-07-25,2018-05-20
-8dhb,2022-09-28,2022-06-25
-3dh1,2008-09-09,2008-06-16
-3dhb,2008-07-29,2008-06-17
-4dh8,2012-06-27,2012-01-27
-3dhe,1999-09-25,1998-03-25
-4dhl,2012-12-12,2012-01-29
-5dhg,2015-10-21,2015-08-30
-3dha,2008-07-29,2008-06-17
-7dhe,2021-01-20,2020-11-14
-5dh4,2016-01-27,2015-08-29
-6dhg,2018-11-21,2018-05-20
-6dhl,2018-07-25,2018-05-20
-1dhk,1997-12-24,1996-10-14
-3dho,2009-09-22,2008-06-18
-5dhs,2016-09-14,2015-08-31
-3dh4,2008-08-05,2008-06-16
-7dhl,2021-02-03,2020-11-16
-4dhq,2013-07-31,2012-01-30
-3dhq,2009-01-06,2008-06-18
-3dhk,2009-05-19,2008-06-18
-8dh5,2023-02-01,2022-06-24
-8dh2,2023-02-01,2022-06-24
-7dhi,2020-12-16,2020-11-15
-7dhw,2021-05-19,2020-11-17
-7dhy,2021-03-03,2020-11-18
-5dhk,2015-09-16,2015-08-31
-2dhf,1990-07-15,1989-10-25
-5dh9,2015-09-16,2015-08-30
-1dhi,1994-01-31,1993-10-29
-3dhg,2008-12-30,2008-06-17
-7dh7,2021-06-09,2020-11-13
-6dhe,2018-11-21,2018-05-20
-6dh2,2018-12-26,2018-05-18
-7dhv,2021-11-17,2020-11-17
-7dhj,2021-11-24,2020-11-15
-8dh1,2023-02-01,2022-06-24
-8dhy,2022-12-07,2022-06-28
-8dh3,2023-02-01,2022-06-24
-8dhw,2023-05-17,2022-06-28
-1dhy,1995-10-15,1995-07-07
-8dha,2023-04-19,2022-06-25
-3dhy,2008-09-09,2008-06-19
-5dht,2016-09-14,2015-08-31
-5dhr,2016-09-14,2015-08-31
-3dh9,2009-06-16,2008-06-17
-3dh7,2008-09-23,2008-06-17
-7dh8,2021-06-09,2020-11-13
-7dhz,2021-03-03,2020-11-18
-6dhc,2018-07-25,2018-05-19
-4dh0,2012-02-15,2012-01-27
-4dhw,2012-02-29,2012-01-30
-4dh2,2012-11-28,2012-01-27
-6dh6,2018-12-26,2018-05-18
-1dhg,1999-07-09,1999-03-22
-7dh9,2021-11-17,2020-11-13
-8dh6,2022-07-20,2022-06-25
-7dh3,2021-11-17,2020-11-12
-7dhh,2021-11-17,2020-11-14
-3dh8,2009-06-23,2008-06-17
-6dh7,2018-12-26,2018-05-18
-7dh5,2021-08-04,2020-11-12
-3dhd,2009-08-18,2008-06-17
-8dhn,2022-12-21,2022-06-27
-6jt7,2020-03-04,2019-04-10
-5jt4,2017-03-08,2016-05-09
-7jt6,2021-09-08,2020-08-17
-1jtx,2001-12-07,2001-08-22
-3jta,2010-01-12,2009-09-11
-5jtu,2016-08-24,2016-05-09
-8jtz,2024-03-27,2023-06-22
-3jtk,2009-09-22,2009-09-12
-7jt8,2021-09-01,2020-08-17
-4jtj,2013-06-26,2013-03-23
-4jta,2013-06-12,2013-03-23
-3jt6,2010-01-12,2009-09-11
-2jt2,2007-12-04,2007-07-18
-6jtj,2020-05-13,2019-04-11
-6jtp,2020-04-15,2019-04-11
-6jt6,2019-11-13,2019-04-09
-3jtu,2009-11-10,2009-09-14
-1jte,2002-07-10,2001-08-20
-1jtg,2001-10-17,2001-08-20
-1jtd,2001-10-03,2001-08-20
-4jtf,2013-06-26,2013-03-23
-6jt8,2020-03-04,2019-04-10
-1jt6,2001-12-12,2001-08-20
-7jt0,2021-03-10,2020-08-16
-4jt8,2013-04-24,2013-03-22
-6jt2,2019-09-04,2019-04-08
-4jtc,2013-06-12,2013-03-23
-6jtb,2019-10-02,2019-04-10
-5jtg,2017-01-25,2016-05-09
-4jtb,2013-04-17,2013-03-23
-5jtb,2017-05-31,2016-05-09
-6jtz,2020-04-15,2019-04-12
-5jt5,2017-05-24,2016-05-09
-6jt5,2019-11-06,2019-04-09
-6jtl,2020-05-13,2019-04-11
-6jtf,2020-04-15,2019-04-10
-5jte,2016-07-20,2016-05-09
-4jtd,2013-06-12,2013-03-23
-7jt7,2021-03-17,2020-08-17
-8jt6,2024-02-28,2023-06-21
-7jt5,2021-09-08,2020-08-17
-4jt0,2013-05-01,2013-03-22
-7jtg,2021-03-10,2020-08-17
-2jti,2008-07-22,2007-08-01
-5jtt,2016-08-24,2016-05-09
-6jt4,2020-01-15,2019-04-08
-1jtf,2002-07-10,2001-08-20
-6jtt,2020-04-15,2019-04-12
-5jt6,2017-05-24,2016-05-09
-5jtc,2017-05-24,2016-05-09
-8jt5,2024-05-08,2023-06-21
-5jt9,2016-12-21,2016-05-09
-1jty,2001-12-12,2001-08-22
-8jt9,2023-11-29,2023-06-21
-3jtb,2009-11-17,2009-09-11
-7jty,2021-10-13,2020-08-18
-4jtn,2013-06-26,2013-03-23
-4jtw,2013-07-10,2013-03-24
-8jtc,2023-11-29,2023-06-21
-1jt2,2002-03-27,2001-08-20
-6jtc,2019-10-02,2019-04-10
-7jtl,2020-08-26,2020-08-18
-5jtd,2016-10-12,2016-05-09
-6jta,2020-03-04,2019-04-10
-6jtk,2020-05-13,2019-04-11
-6jtg,2020-04-22,2019-04-11
-1jtv,2003-06-24,2001-08-22
-4jt5,2013-05-08,2013-03-22
-7jtm,2020-09-16,2020-08-18
-4jto,2013-06-26,2013-03-23
-3jti,2010-07-21,2009-09-12
-4jtq,2014-04-02,2013-03-24
-4jtv,2013-05-01,2013-03-24
-2jtn,2008-06-17,2007-08-03
-6jt1,2019-08-28,2019-04-08
-1jtt,2001-12-05,2001-08-22
-3jtz,2009-10-06,2009-09-14
-5jt2,2016-09-14,2016-05-09
-3jt4,2010-01-12,2009-09-11
-6jtu,2020-04-15,2019-04-12
-5jtj,2016-08-10,2016-05-09
-4jty,2013-07-03,2013-03-24
-1jtu,2001-09-19,2001-08-22
-3jt7,2010-01-12,2009-09-11
-3jt3,2010-01-12,2009-09-11
-5jt8,2017-05-24,2016-05-09
-8jt1,2024-02-07,2023-06-21
-8jtd,2023-10-25,2023-06-21
-4jte,2013-06-26,2013-03-23
-4jt4,2013-08-28,2013-03-22
-8jtt,2024-03-27,2023-06-22
-8jtj,2024-06-05,2023-06-21
-3jtc,2011-04-06,2009-09-11
-3jtd,2009-12-01,2009-09-11
-8jts,2024-03-27,2023-06-22
-4jtk,2013-06-26,2013-03-23
-6jtd,2019-06-19,2019-04-10
-1jtp,2001-12-05,2001-08-21
-3jt5,2010-01-12,2009-09-11
-5jt1,2017-03-22,2016-05-09
-8jta,2023-11-29,2023-06-21
-6jt0,2019-08-28,2019-04-08
-4jt2,2013-08-28,2013-03-22
-4jtr,2014-04-02,2013-03-24
-7jtt,2021-08-25,2020-08-18
-8jtv,2024-03-27,2023-06-22
-4jtx,2013-05-01,2013-03-24
-4jtu,2014-03-26,2013-03-24
-4jt3,2014-03-26,2013-03-22
-5jtw,2016-08-10,2016-05-09
-8jt3,2023-08-02,2023-06-21
-8jtm,2023-10-25,2023-06-22
-7jtc,2021-08-25,2020-08-17
-3jt2,2009-11-17,2009-09-11
-1jtq,2001-09-19,2001-08-21
-8jtb,2024-05-08,2023-06-21
-4jtt,2014-03-26,2013-03-24
-4jtz,2013-07-03,2013-03-24
-4jtp,2013-04-17,2013-03-24
-4jtg,2013-06-26,2013-03-23
-7jtz,2021-03-24,2020-08-18
-7jtw,2021-02-03,2020-08-18
-4jth,2013-06-26,2013-03-23
-5jt0,2017-05-24,2016-05-09
-3jt1,2010-02-02,2009-09-11
-7jto,2021-10-06,2020-08-18
-5jth,2017-07-19,2016-05-09
-6jt9,2020-03-04,2019-04-10
-5jt7,2017-05-24,2016-05-09
-4jt6,2013-05-08,2013-03-22
-3jt8,2010-01-12,2009-09-11
-7jtv,2020-12-16,2020-08-18
-3jtx,2009-09-22,2009-09-14
-3jt9,2010-01-12,2009-09-11
-8jt8,2024-02-28,2023-06-21
-4jts,2014-03-26,2013-03-24
-7jtr,2021-05-05,2020-08-18
-2jt6,2008-02-19,2007-07-23
-1jtb,1997-07-07,1996-12-03
-2jtg,2007-12-11,2007-07-31
-1jtk,2002-04-10,2001-08-21
-4jt9,2013-04-24,2013-03-22
-6jt3,2019-10-30,2019-04-08
-1jt1,2003-01-21,2001-08-20
-3jts,2010-09-15,2009-09-14
-3jtf,2009-12-22,2009-09-11
-2jt5,2008-02-19,2007-07-20
-7jtp,2021-10-06,2020-08-18
-8jtn,2023-08-09,2023-06-22
-5jty,2016-09-21,2016-05-10
-3jtt,2010-09-15,2009-09-14
-7jtj,2021-10-06,2020-08-17
-3ko2,2010-05-19,2009-11-13
-7kot,2021-01-27,2020-11-09
-4kod,2013-11-13,2013-05-11
-4koc,2014-05-14,2013-05-11
-2kop,2010-08-18,2009-09-29
-7kou,2021-11-17,2020-11-10
-4kos,2013-06-05,2013-05-12
-6ko9,2019-10-09,2019-08-08
-4kot,2013-06-05,2013-05-12
-6kof,2020-03-25,2019-08-09
-3kob,2009-12-08,2009-11-13
-3ko8,2010-11-17,2009-11-13
-4kow,2013-06-05,2013-05-12
-4koe,2014-11-26,2013-05-11
-7koj,2020-11-18,2020-11-09
-5kos,2016-11-16,2016-07-01
-5ko7,2017-02-15,2016-06-29
-3koi,2010-08-25,2009-11-13
-4kol,2013-11-06,2013-05-12
-5kok,2016-09-07,2016-06-30
-3koc,2009-12-08,2009-11-13
-5kob,2016-07-13,2016-06-30
-1kog,2002-04-26,2001-12-20
-1ko5,2002-05-29,2001-12-20
-4ko8,2013-11-13,2013-05-11
-3kox,2010-01-26,2009-11-14
-5ko1,2016-11-16,2016-06-29
-6kou,2020-03-25,2019-08-13
-4kor,2013-06-05,2013-05-12
-7kol,2020-11-18,2020-11-09
-1kou,2002-04-03,2001-12-22
-7ko8,2021-04-28,2020-11-06
-7kos,2021-11-17,2020-11-09
-3ko9,2009-12-01,2009-11-13
-4ko4,2013-07-10,2013-05-11
-5koz,2017-07-05,2016-07-01
-2koo,2010-08-18,2009-09-29
-5ko5,2017-08-09,2016-06-29
-1kof,2002-05-29,2001-12-20
-7koo,2021-03-17,2020-11-09
-5ko8,2017-02-15,2016-06-29
-3ko1,2010-11-03,2009-11-12
-3ko4,2009-12-01,2009-11-13
-4koy,2013-06-05,2013-05-12
-4ko1,2013-07-10,2013-05-11
-1koq,1998-12-09,1998-03-22
-3koo,2010-04-28,2009-11-13
-7koh,2022-03-09,2020-11-09
-1kok,2002-10-02,2001-12-20
-5kow,2016-09-07,2016-07-01
-3kon,2010-08-25,2009-11-13
-7koa,2020-11-18,2020-11-07
-3ko5,2009-12-01,2009-11-13
-7ko6,2022-05-04,2020-11-06
-7kox,2021-03-17,2020-11-10
-4koa,2013-08-07,2013-05-11
-6ko0,2020-04-01,2019-08-07
-7kop,2021-11-10,2020-11-09
-5koy,2016-12-14,2016-07-01
-2ko8,2010-09-22,2009-09-12
-1ko2,2003-09-02,2001-12-20
-7koz,2021-05-05,2020-11-10
-7ko2,2021-09-15,2020-11-06
-6kod,2020-02-05,2019-08-09
-3ko7,2009-12-01,2009-11-13
-2ko7,2009-09-29,2009-09-11
-4ko3,2013-07-10,2013-05-11
-7kov,2021-03-03,2020-11-10
-6ko6,2019-11-06,2019-08-08
-4kov,2013-06-05,2013-05-12
-3koz,2010-01-26,2009-11-14
-5koc,2016-09-07,2016-06-30
-4ko2,2013-07-10,2013-05-11
-1kob,1997-03-12,1996-06-28
-6koy,2020-01-22,2019-08-13
-4kox,2013-06-05,2013-05-12
-3kol,2009-11-24,2009-11-13
-6kop,2020-03-11,2019-08-12
-4ko0,2013-08-14,2013-05-10
-7koq,2021-03-17,2020-11-09
-5kov,2016-11-09,2016-07-01
-3koy,2010-01-26,2009-11-14
-3ko0,2010-05-26,2009-11-12
-1kor,2002-04-03,2001-12-22
-3ko6,2010-11-17,2009-11-13
-6kob,2020-01-15,2019-08-09
-4kon,2013-11-06,2013-05-12
-6koz,2020-01-22,2019-08-13
-4kom,2013-11-06,2013-05-12
-5kor,2016-10-12,2016-07-01
-4kou,2013-06-05,2013-05-12
-1ko8,2002-05-29,2001-12-20
-5kom,2016-08-03,2016-06-30
-5kox,2016-09-07,2016-07-01
-1koi,2002-01-09,2001-05-03
-3kok,2010-08-25,2009-11-13
-7ko0,2021-10-20,2020-11-06
-5ko3,2017-01-25,2016-06-29
-6ko5,2020-08-12,2019-08-08
-7kom,2021-11-17,2020-11-09
-4ko9,2014-05-14,2013-05-11
-1ko6,2002-09-04,2001-12-20
-5kof,2018-01-24,2016-06-30
-6koc,2020-01-15,2019-08-09
-6ko2,2020-08-12,2019-08-07
-6kot,2019-12-04,2019-08-13
-5koq,2016-11-02,2016-07-01
-2koi,2009-11-03,2009-09-22
-7kok,2020-11-18,2020-11-09
-5ko2,2016-11-30,2016-06-29
-5koe,2016-09-28,2016-06-30
-4koo,2013-11-13,2013-05-12
-6koq,2020-03-11,2019-08-12
-6ko8,2019-10-09,2019-08-08
-3koa,2010-07-07,2009-11-13
-7ko1,2021-11-17,2020-11-06
-4ko7,2014-05-14,2013-05-11
-2kor,2010-08-18,2009-09-29
-7koc,2021-11-17,2020-11-08
-2koq,2010-08-18,2009-09-29
-3kou,2010-10-27,2009-11-13
-3kow,2010-01-26,2009-11-14
-4ko5,2014-05-14,2013-05-11
-6kol,2020-01-29,2019-08-12
-3ko3,2009-12-08,2009-11-13
-7ko3,2021-11-17,2020-11-06
-3kod,2009-12-08,2009-11-13
-6ko7,2019-10-09,2019-08-08
-2ko0,2010-01-19,2009-09-08
-1ko3,2003-09-02,2001-12-20
-3koq,2009-12-01,2009-11-13
-5ko6,2017-08-09,2016-06-29
-6kon,2020-03-11,2019-08-12
-1koj,2002-05-03,2001-12-20
-6koo,2020-03-11,2019-08-12
-6koe,2020-01-15,2019-08-09
-3koh,2010-05-12,2009-11-13
-4ko6,2014-05-14,2013-05-11
-6koj,2020-07-08,2019-08-11
-1kop,1998-12-09,1998-03-22
-5kot,2017-07-05,2016-07-01
-5kod,2016-11-16,2016-06-30
-1kol,2002-12-11,2001-12-21
-2kos,2010-08-18,2009-09-29
-5koi,2016-07-13,2016-06-30
-6kok,2020-07-08,2019-08-11
-4kob,2014-05-14,2013-05-11
-6ko1,2020-04-01,2019-08-07
-2kot,2010-03-09,2009-09-30
-7koe,2021-01-20,2020-11-08
-1ko0,2003-11-11,2001-12-19
-2xei,2010-09-08,2010-05-14
-4xes,2015-07-29,2014-12-24
-2xem,2010-10-13,2010-05-17
-2xez,2010-07-07,2010-05-19
-5xey,2018-05-02,2017-04-06
-7xea,2023-03-22,2022-03-30
-7xem,2022-08-17,2022-03-31
-1xe6,2005-08-23,2004-09-09
-6xet,2021-08-25,2020-06-13
-4xec,2015-07-22,2014-12-23
-5xe0,2017-06-28,2017-03-30
-7xeq,2023-04-05,2022-03-31
-4xea,2015-03-18,2014-12-23
-7xep,2023-04-05,2022-03-31
-1xea,2004-09-28,2004-09-09
-5xea,2017-10-04,2017-04-03
-6xe8,2021-12-15,2020-06-12
-6xeu,2021-09-01,2020-06-13
-4xej,2015-02-25,2014-12-23
-2xe0,2010-09-29,2010-05-10
-1xe5,2005-08-23,2004-09-09
-2xe7,2011-01-19,2010-05-11
-5xeb,2017-10-04,2017-04-03
-4xe9,2016-01-13,2014-12-23
-6xec,2020-08-12,2020-06-12
-7xey,2022-07-13,2022-03-31
-5xev,2017-10-18,2017-04-06
-7xe4,2023-03-29,2022-03-29
-2xeg,2010-09-08,2010-05-14
-6xer,2021-08-25,2020-06-13
-1xem,2005-03-29,2004-09-10
-7xee,2023-01-18,2022-03-31
-6xeb,2020-08-12,2020-06-12
-2xev,2010-09-15,2010-05-18
-2xe4,2010-10-06,2010-05-11
-7xer,2022-08-17,2022-03-31
-6xex,2020-12-23,2020-06-14
-4xen,2015-04-08,2014-12-24
-4xee,2015-07-29,2014-12-23
-7xet,2023-04-05,2022-03-31
-1xet,2006-04-11,2004-09-12
-7xe9,2023-03-22,2022-03-30
-4xer,2015-09-09,2014-12-24
-1xef,2005-06-07,2004-09-10
-1xe8,2005-01-11,2004-09-09
-2xel,2011-06-15,2010-05-16
-4xed,2015-05-13,2014-12-23
-2xef,2010-09-08,2010-05-14
-1xes,2006-04-11,2004-09-12
-6xeg,2021-12-15,2020-06-12
-5xe9,2017-06-28,2017-04-03
-4xeq,2015-01-28,2014-12-24
-4xem,2016-02-17,2014-12-24
-6xe1,2020-07-01,2020-06-11
-7xeu,2022-08-17,2022-03-31
-4xez,2016-03-16,2014-12-25
-7xe0,2022-09-28,2022-03-29
-2xeu,2010-07-28,2010-05-18
-7xej,2023-04-05,2022-03-31
-4xeu,2015-01-21,2014-12-24
-7xeb,2022-06-29,2022-03-30
-4xe3,2015-11-04,2014-12-22
-1xe7,2005-01-11,2004-09-09
-7xe6,2023-03-22,2022-03-30
-5xeq,2017-07-12,2017-04-05
-1xe4,2005-05-31,2004-09-09
-6xe3,2021-03-10,2020-06-11
-5xej,2018-07-25,2017-04-05
-5xez,2017-05-24,2017-04-06
-4xe5,2016-03-09,2014-12-22
-1xeg,2005-09-27,2004-09-10
-6xed,2021-12-15,2020-06-12
-5xem,2018-04-11,2017-04-05
-5xe1,2017-05-03,2017-03-31
-2xey,2010-06-30,2010-05-19
-6xez,2020-07-29,2020-06-14
-7xe3,2022-09-14,2022-03-29
-5xek,2018-05-02,2017-04-05
-7xes,2023-04-05,2022-03-31
-5xet,2018-07-11,2017-04-06
-2xej,2010-09-08,2010-05-14
-4xe6,2016-01-20,2014-12-23
-4xeo,2015-12-30,2014-12-24
-4xe1,2015-03-18,2014-12-21
-2xex,2010-07-14,2010-05-19
-5xen,2018-04-11,2017-04-05
-1xev,2005-09-20,2004-09-13
-7xe2,2022-09-14,2022-03-29
-2xec,2010-08-18,2010-05-13
-1xed,2004-11-23,2004-09-10
-4xey,2015-04-01,2014-12-25
-5xed,2017-08-09,2017-04-04
-2xe8,2011-01-19,2010-05-11
-4xep,2015-09-09,2014-12-24
-1xen,2005-03-29,2004-09-10
-6xea,2021-12-15,2020-06-12
-4xew,2015-07-08,2014-12-25
-7xen,2023-04-05,2022-03-31
-6xe6,2020-07-08,2020-06-12
-4xe8,2016-03-16,2014-12-23
-6xev,2021-09-01,2020-06-14
-5xeo,2018-04-11,2017-04-05
-4xe0,2015-02-04,2014-12-20
-6xef,2021-12-15,2020-06-12
-4xel,2015-02-11,2014-12-24
-5xec,2017-08-09,2017-04-04
-1xel,1997-02-12,1996-01-25
-7xev,2022-08-17,2022-03-31
-7xek,2023-04-05,2022-03-31
-5xe5,2018-05-02,2017-04-01
-7xez,2023-04-12,2022-03-31
-8xe7,2024-05-22,2023-12-11
-7xe5,2023-03-22,2022-03-30
-4xet,2016-04-06,2014-12-24
-6xe7,2020-12-02,2020-06-12
-7xec,2023-03-29,2022-03-30
-1xeo,2005-03-29,2004-09-10
-2xes,2010-06-16,2010-05-17
-4xeb,2016-06-22,2014-12-23
-6xey,2020-07-22,2020-06-14
-4xe4,2015-02-04,2014-12-22
-2xe5,2010-05-26,2010-05-11
-2xea,2010-06-30,2010-05-12
-6xew,2020-12-23,2020-06-14
-6xes,2021-08-25,2020-06-13
-5xeg,2018-06-13,2017-04-05
-7xe1,2022-09-14,2022-03-29
-1xey,2004-10-05,2004-09-13
-7xef,2023-01-18,2022-03-31
-1xer,1997-09-04,1996-08-28
-1xec,2004-11-02,2004-09-09
-6xe4,2020-07-22,2020-06-11
-6xep,2020-06-24,2020-06-12
-1xex,2004-12-07,2004-09-13
-7m2l,2021-09-22,2021-03-16
-4m2v,2013-11-06,2013-08-05
-4m27,2014-06-25,2013-08-05
-5m27,2017-04-05,2016-10-12
-3m2x,2011-05-25,2010-03-08
-7m2y,2021-05-12,2021-03-17
-6m2z,2021-03-03,2020-03-02
-6m2b,2021-03-03,2020-02-27
-3m2f,2010-05-12,2010-03-07
-6m2h,2021-01-13,2020-02-27
-7m23,2022-02-02,2021-03-16
-5m25,2017-06-28,2016-10-11
-4m22,2013-11-27,2013-08-05
-1m2x,2003-07-29,2002-06-26
-4m20,2014-02-12,2013-08-05
-5m2k,2017-07-19,2016-10-13
-5m2v,2017-01-11,2016-10-13
-7m2i,2021-10-27,2021-03-16
-3m2j,2011-03-16,2010-03-07
-4m24,2014-12-31,2013-08-05
-1m2t,2003-06-24,2002-06-25
-4m2p,2013-11-13,2013-08-05
-6m2i,2021-01-06,2020-02-27
-5m2f,2017-02-15,2016-10-12
-4m26,2014-06-25,2013-08-05
-3m2w,2010-07-28,2010-03-08
-3m25,2010-05-12,2010-03-06
-4m2z,2013-12-11,2013-08-05
-4m25,2014-06-25,2013-08-05
-4m2f,2014-06-25,2013-08-05
-1m21,2002-10-16,2002-06-21
-5m2b,2017-01-25,2016-10-12
-1m26,2002-10-12,2002-06-21
-4m2o,2013-11-13,2013-08-05
-7m2j,2021-10-27,2021-03-16
-4m2x,2014-11-12,2013-08-05
-3m2a,2010-05-12,2010-03-06
-5m2h,2017-07-19,2016-10-13
-4m2a,2014-01-29,2013-08-05
-3m2e,2010-05-12,2010-03-07
-4m2m,2014-06-18,2013-08-05
-5m2o,2017-07-05,2016-10-13
-5m2q,2017-03-01,2016-10-13
-1m2h,2003-04-08,2002-06-24
-4m2w,2013-11-06,2013-08-05
-2m2u,2014-04-02,2013-01-03
-7m2d,2021-11-24,2021-03-16
-3m29,2010-05-12,2010-03-06
-7m2h,2021-10-27,2021-03-16
-6m2g,2021-01-13,2020-02-27
-6m28,2021-01-13,2020-02-26
-6m2j,2020-07-08,2020-02-27
-4m2j,2014-06-18,2013-08-05
-7m2k,2021-11-03,2021-03-16
-5m2a,2017-04-05,2016-10-12
-1m2z,2003-07-15,2002-06-26
-6m2c,2021-04-07,2020-02-27
-1m2q,2003-06-17,2002-06-25
-3m28,2010-05-12,2010-03-06
-5m2g,2017-07-12,2016-10-12
-4m2g,2014-06-25,2013-08-05
-7m2f,2021-07-07,2021-03-16
-7m2w,2021-05-12,2021-03-17
-6m2n,2020-04-15,2020-02-28
-5m2s,2017-07-05,2016-10-13
-6m24,2020-07-08,2020-02-26
-7m2e,2022-02-16,2021-03-16
-1m24,2002-11-06,2002-06-21
-1m2j,2003-04-08,2002-06-24
-4m2e,2014-06-25,2013-08-05
-5m23,2017-06-28,2016-10-11
-3m2y,2011-05-25,2010-03-08
-5m29,2017-02-08,2016-10-12
-3m2z,2011-07-06,2010-03-08
-1m2a,2002-09-18,2002-06-22
-6m22,2020-11-04,2020-02-26
-4m2i,2014-06-25,2013-08-05
-6m2l,2020-09-09,2020-02-27
-6m2k,2020-07-08,2020-02-27
-2m28,2014-05-07,2012-12-17
-1m2m,2003-03-18,2002-06-24
-3m2d,2010-05-12,2010-03-06
-4m2k,2014-06-18,2013-08-05
-1m2g,2003-04-08,2002-06-24
-3m2p,2010-04-07,2010-03-08
-5m2z,2018-06-06,2016-10-13
-7m2z,2021-05-12,2021-03-17
-5m21,2017-09-27,2016-10-11
-1m2o,2002-09-20,2002-06-24
-4m2u,2013-11-06,2013-08-05
-6m2e,2021-01-13,2020-02-27
-4m2t,2013-11-13,2013-08-05
-6m2t,2021-03-03,2020-02-29
-1m2p,2003-06-17,2002-06-25
-6m2f,2021-01-13,2020-02-27
-7m2u,2021-07-28,2021-03-17
-3m26,2010-05-12,2010-03-06
-1m2k,2003-04-08,2002-06-24
-5m2x,2018-06-06,2016-10-13
-3m2t,2010-04-07,2010-03-08
-7m22,2021-08-11,2021-03-15
-6m20,2020-09-09,2020-02-26
-3m2c,2010-05-12,2010-03-06
-1m2w,2002-11-15,2002-06-25
-5m28,2017-07-05,2016-10-12
-3m23,2010-05-12,2010-03-06
-1m2v,2002-09-20,2002-06-25
-1m2i,2003-03-18,2002-06-24
-3m2v,2010-09-15,2010-03-08
-4m2b,2014-01-29,2013-08-05
-7m20,2021-09-08,2021-03-15
-7m2t,2021-12-15,2021-03-17
-3m2u,2010-09-15,2010-03-08
-6m2d,2021-04-07,2020-02-27
-6m2r,2021-02-17,2020-02-28
-7m2v,2021-12-15,2021-03-17
-2m2w,2014-04-02,2013-01-03
-3m27,2010-05-12,2010-03-06
-4m21,2013-11-27,2013-08-05
-6m2u,2021-01-13,2020-02-29
-3m2m,2010-07-21,2010-03-07
-7m2m,2021-10-20,2021-03-17
-3m2r,2010-09-15,2010-03-08
-3m2i,2010-05-12,2010-03-07
-3m2h,2010-05-12,2010-03-07
-7m2o,2021-07-14,2021-03-17
-6m27,2021-01-13,2020-02-26
-5m26,2017-09-27,2016-10-12
-1m2n,2003-04-08,2002-06-24
-7m26,2022-02-02,2021-03-16
-4m2s,2013-11-13,2013-08-05
-6m2w,2020-09-02,2020-03-01
-7m2p,2021-08-25,2021-03-17
-1m2r,2003-06-17,2002-06-25
-7m2x,2021-05-12,2021-03-17
-4m2r,2013-11-06,2013-08-05
-3m2b,2010-05-12,2010-03-06
-3m2k,2011-03-16,2010-03-07
-2m29,2014-05-07,2012-12-17
-6m29,2021-01-13,2020-02-26
-7m24,2022-02-02,2021-03-16
-4m2q,2013-11-13,2013-08-05
-4m28,2014-01-29,2013-08-05
-4m2c,2014-06-25,2013-08-05
-5m24,2017-09-20,2016-10-11
-3m2n,2011-02-16,2010-03-08
-5m22,2017-09-27,2016-10-11
-6m2y,2021-03-03,2020-03-02
-5m2t,2017-11-15,2016-10-13
-7m2n,2021-07-14,2021-03-17
-4m2y,2014-01-22,2013-08-05
-3m2g,2010-05-12,2010-03-07
-6m23,2020-11-04,2020-02-26
-1m20,2002-09-11,2002-06-20
-4lwc,2013-12-11,2013-07-26
-4lwm,2014-06-11,2013-07-27
-4lwe,2014-07-30,2013-07-27
-4lw6,2013-09-25,2013-07-26
-3lwp,2010-07-14,2010-02-24
-7lw4,2021-05-05,2021-02-27
-7lwe,2022-03-09,2021-03-01
-5lwp,2016-11-16,2016-09-19
-7lwb,2021-03-10,2021-02-28
-5lwr,2017-08-09,2016-09-19
-5lww,2017-05-03,2016-09-19
-1lwg,2003-05-20,2002-05-31
-4lwx,2013-08-28,2013-07-29
-7lwz,2021-03-10,2021-03-02
-4lw9,2014-07-16,2013-07-26
-4lw3,2013-09-25,2013-07-26
-1lwo,2002-06-19,2002-06-01
-1lwl,2002-12-18,2002-05-31
-6lw0,2020-11-11,2020-02-06
-7lwf,2022-03-09,2021-03-01
-5lw0,2016-10-26,2016-09-14
-7lwu,2021-03-31,2021-03-01
-1lwv,2003-02-25,2002-06-03
-5lwt,2017-08-09,2016-09-19
-4lw4,2013-08-07,2013-07-26
-2lww,2013-09-11,2012-08-07
-7lwj,2021-03-31,2021-03-01
-7lwa,2021-07-14,2021-02-28
-4lwy,2014-07-16,2013-07-29
-1lwd,2002-11-13,2002-05-31
-4lwp,2014-02-19,2013-07-28
-7lw1,2022-01-26,2021-02-27
-7lwn,2021-03-31,2021-03-01
-1lwc,2002-10-30,2002-05-31
-1lw6,2002-08-21,2002-05-30
-3lwo,2010-07-14,2010-02-24
-1lw9,2003-05-20,2002-05-30
-4lwb,2013-10-23,2013-07-26
-7lw3,2021-05-05,2021-02-27
-4lwd,2013-10-16,2013-07-26
-3lw7,2010-03-09,2010-02-23
-3lwh,2010-05-26,2010-02-23
-4lwa,2013-10-23,2013-07-26
-7lw2,2022-08-31,2021-02-27
-6lw1,2020-11-11,2020-02-06
-6lwu,2021-02-10,2020-02-09
-5lwd,2016-12-21,2016-09-15
-5lwm,2016-10-26,2016-09-18
-4lwt,2014-07-16,2013-07-28
-5lwe,2016-12-07,2016-09-16
-3lwq,2010-07-14,2010-02-24
-3lwd,2010-04-07,2010-02-23
-5lwn,2016-10-26,2016-09-18
-3lw6,2010-03-16,2010-02-23
-3lw0,2010-09-29,2010-02-23
-3lw5,2010-08-18,2010-02-23
-1lw4,2002-12-11,2002-05-30
-6lw2,2020-05-13,2020-02-07
-7lwv,2021-03-31,2021-03-01
-1lwf,2002-10-30,2002-05-31
-4lwf,2014-07-30,2013-07-27
-5lw1,2017-12-13,2016-09-15
-3lw1,2010-03-23,2010-02-23
-7lwp,2021-03-31,2021-03-01
-1lwx,1997-08-20,1997-04-30
-3lwi,2010-05-26,2010-02-23
-7lwt,2021-03-31,2021-03-01
-7lwo,2021-03-31,2021-03-01
-1lwe,2002-10-30,2002-05-31
-1lw7,2002-08-07,2002-05-30
-3lwl,2010-05-05,2010-02-24
-4lwz,2013-11-20,2013-07-29
-5lwy,2017-03-22,2016-09-19
-5lwo,2017-03-08,2016-09-18
-4lwv,2014-07-02,2013-07-28
-4lww,2013-12-25,2013-07-28
-3lwn,2010-03-31,2010-02-24
-5lwh,2017-04-12,2016-09-16
-5lws,2017-08-09,2016-09-19
-6lw8,2021-02-10,2020-02-07
-1lwh,2002-07-03,2002-05-31
-1lw5,2002-12-11,2002-05-30
-1lwi,1996-12-07,1996-02-24
-4lwg,2014-07-30,2013-07-27
-5lw9,2016-09-28,2016-09-15
-2lwr,2013-06-12,2012-08-06
-7lwm,2021-03-31,2021-03-01
-4lw7,2014-07-30,2013-07-26
-1lww,2003-02-25,2002-06-03
-5lwb,2016-10-26,2016-09-15
-5lwx,2017-05-03,2016-09-19
-7lw9,2021-07-14,2021-02-28
-5lwv,2017-07-12,2016-09-19
-6lw5,2020-03-25,2020-02-07
-7lws,2021-03-31,2021-03-01
-2lwi,2013-05-22,2012-08-01
-7lwi,2021-03-31,2021-03-01
-5lw3,2017-10-25,2016-09-15
-7lww,2021-03-31,2021-03-01
-4lwi,2014-07-30,2013-07-27
-3lwu,2010-03-23,2010-02-24
-6lwr,2021-06-09,2020-02-07
-4lwh,2014-07-30,2013-07-27
-7lwl,2021-03-31,2021-03-01
-7lwq,2021-03-31,2021-03-01
-1lwn,2002-06-19,2002-06-01
-4lw2,2013-08-07,2013-07-26
-5lwk,2017-06-28,2016-09-18
-4lwu,2014-07-16,2013-07-28
-1lws,2002-09-27,2002-06-03
-1lwu,2002-08-23,2002-06-03
-7lwk,2021-03-31,2021-03-01
-3lwm,2010-05-05,2010-02-24
-3lwa,2010-03-02,2010-02-23
-5lwq,2017-04-12,2016-09-19
-3lwr,2010-07-14,2010-02-24
-3lw8,2010-03-31,2010-02-23
-7lw6,2021-05-26,2021-02-27
-1lw2,2002-10-30,2002-05-30
-4lw1,2013-12-11,2013-07-26
-5lwz,2017-05-31,2016-09-19
-7lwd,2021-08-11,2021-03-01
-1lw0,2002-10-30,2002-05-30
-1lwj,2002-08-14,2002-05-31
-3lwv,2010-07-14,2010-02-24
-5c1h,2015-09-23,2015-06-13
-8c10,2023-04-19,2022-12-19
-3c16,2009-02-03,2008-01-22
-6c1q,2018-05-30,2018-01-05
-3c1s,2008-12-09,2008-01-24
-8c18,2023-04-05,2022-12-20
-6c1h,2018-01-31,2018-01-04
-8c11,2023-12-27,2022-12-19
-6c13,2018-08-15,2018-01-03
-2c1h,2005-12-02,2005-09-14
-1c1j,2002-07-05,1999-07-22
-5c1l,2015-09-23,2015-06-14
-2c1b,2005-11-02,2005-09-12
-6c12,2018-03-07,2018-01-03
-8c1p,2023-08-30,2022-12-21
-2c1z,2006-01-09,2005-09-22
-8c14,2024-01-10,2022-12-20
-6c1m,2018-05-16,2018-01-04
-7c1l,2020-11-25,2020-05-05
-2c1x,2006-01-09,2005-09-22
-8c1j,2024-01-10,2022-12-20
-4c1i,2014-08-27,2013-08-12
-3c1t,2008-02-19,2008-01-24
-3c1u,2008-08-05,2008-01-24
-2c18,2006-06-20,2005-09-11
-5c1u,2016-06-01,2015-06-15
-4c1y,2014-08-27,2013-08-14
-7c1x,2020-11-18,2020-05-06
-6c17,2018-07-25,2018-01-04
-5c18,2016-01-13,2015-06-13
-6c1j,2018-07-25,2018-01-04
-6c1p,2018-05-16,2018-01-05
-5c1x,2016-06-01,2015-06-15
-8c13,2022-12-28,2022-12-20
-2c1c,2005-10-19,2005-09-12
-1c1c,2000-07-21,1999-07-21
-1c1e,2000-03-01,1999-07-22
-7c18,2021-05-05,2020-05-02
-8c1t,2024-01-10,2022-12-21
-5c1d,2015-08-05,2015-06-13
-1c1p,2000-07-26,1999-07-21
-3c17,2008-04-01,2008-01-22
-8c16,2023-07-12,2022-12-20
-1c1r,2000-07-26,1999-07-21
-3c10,2008-02-19,2008-01-21
-5c1p,2016-03-02,2015-06-15
-4c1o,2014-05-14,2013-08-13
-2c15,2006-06-20,2005-09-11
-4c13,2013-10-02,2013-08-09
-4c1k,2013-11-20,2013-08-13
-6c15,2018-03-21,2018-01-03
-4c16,2014-08-20,2013-08-09
-1c1l,1999-10-08,1999-03-03
-4c1q,2013-10-16,2013-08-13
-3c1n,2008-03-25,2008-01-23
-4c1u,2013-10-30,2013-08-13
-2c10,2006-09-20,2005-09-09
-1c12,1999-08-14,1999-07-20
-2c1q,2007-02-20,2005-09-19
-6c10,2018-08-15,2018-01-03
-3c1q,2009-02-03,2008-01-24
-7c1r,2020-11-25,2020-05-05
-3c1k,2008-03-18,2008-01-23
-5c1r,2016-07-20,2015-06-15
-6c1c,2019-01-16,2018-01-04
-5c1t,2016-04-27,2015-06-15
-8c1k,2024-01-10,2022-12-20
-5c1o,2016-03-02,2015-06-15
-4c1n,2014-08-13,2013-08-13
-4c1x,2014-09-10,2013-08-14
-8c1b,2023-03-29,2022-12-20
-7c1e,2021-05-05,2020-05-03
-5c1y,2016-06-01,2015-06-15
-3c15,2009-02-03,2008-01-22
-3c14,2009-02-03,2008-01-22
-4c1e,2014-08-27,2013-08-12
-8c15,2024-01-10,2022-12-20
-1c1t,2000-07-26,1999-07-21
-2c1p,2006-01-25,2005-09-19
-1c1x,2000-08-30,1999-07-22
-5c1b,2016-01-13,2015-06-13
-2c1j,2005-11-02,2005-09-15
-3c1y,2008-05-06,2008-01-24
-8c1q,2023-08-30,2022-12-21
-2c1v,2006-01-13,2005-09-21
-7c1s,2020-11-25,2020-05-05
-1c14,2000-07-20,1999-07-20
-1c1o,2000-07-26,1999-07-21
-4c1l,2013-11-20,2013-08-13
-4c1c,2014-08-27,2013-08-12
-6c1s,2018-06-27,2018-01-05
-1c1u,2000-07-26,1999-07-21
-3c1e,2008-11-04,2008-01-23
-3c1x,2008-03-18,2008-01-24
-5c15,2015-10-21,2015-06-12
-4c1f,2014-08-27,2013-08-12
-4c14,2013-10-30,2013-08-09
-4c11,2013-08-21,2013-08-09
-3c11,2008-07-29,2008-01-21
-1c1v,2000-07-26,1999-07-21
-5c1q,2015-12-16,2015-06-15
-7c14,2021-03-10,2020-05-02
-2c1e,2006-09-20,2005-09-14
-8c1u,2023-11-01,2022-12-21
-7c1z,2020-11-18,2020-05-06
-2c14,2006-06-20,2005-09-11
-7c19,2021-03-10,2020-05-02
-1c1m,1999-07-28,1999-07-22
-1c1d,2000-08-30,1999-07-21
-1c1y,1999-08-02,1999-07-22
-3c1m,2008-03-25,2008-01-23
-8c1e,2024-01-10,2022-12-20
-1c1w,2000-07-26,1999-07-21
-8c1y,2024-05-01,2022-12-21
-5c1z,2015-07-29,2015-06-15
-2c19,2006-06-20,2005-09-11
-5c1g,2015-09-23,2015-06-13
-8c1r,2023-08-30,2022-12-21
-2c1f,2007-02-13,2005-09-14
-8c1g,2024-01-10,2022-12-20
-6c1d,2018-01-31,2018-01-04
-2c1a,2005-11-02,2005-09-12
-8c1i,2024-01-10,2022-12-20
-7c1j,2020-11-04,2020-05-04
-4c1t,2013-10-30,2013-08-13
-8c1h,2024-01-10,2022-12-20
-3c1v,2008-04-01,2008-01-24
-6c1k,2018-05-16,2018-01-04
-2c13,2006-06-20,2005-09-11
-1c10,1999-07-22,1999-07-16
-2c1d,2005-10-06,2005-09-13
-3c13,2008-02-12,2008-01-22
-5c11,2015-11-25,2015-06-12
-6c1e,2018-05-16,2018-01-04
-1c1b,2000-07-21,1999-07-21
-6c1g,2018-01-31,2018-01-04
-5c12,2015-10-21,2015-06-12
-2c16,2006-06-20,2005-09-11
-4c1m,2013-11-13,2013-08-13
-8c1l,2024-01-10,2022-12-20
-5c17,2016-02-03,2015-06-13
-1c1k,2000-02-16,1999-07-22
-7c15,2021-03-10,2020-05-02
-8c1d,2024-01-10,2022-12-20
-8c19,2023-03-08,2022-12-20
-7c1o,2021-05-12,2020-05-05
-4c1w,2014-08-27,2013-08-14
-5c1s,2016-04-27,2015-06-15
-8c17,2023-03-15,2022-12-20
-2c1u,2006-01-13,2005-09-21
-5c1v,2016-02-03,2015-06-15
-2c1n,2005-11-02,2005-09-16
-5c1a,2016-01-13,2015-06-13
-6c18,2019-01-16,2018-01-04
-1c1n,2000-07-26,1999-07-21
-7c17,2020-09-30,2020-05-02
-4c12,2013-10-02,2013-08-09
-5c13,2015-11-25,2015-06-12
-8c1f,2024-01-10,2022-12-20
-2c12,2006-02-01,2005-09-10
-1c1h,2000-03-17,1999-07-22
-5c14,2016-01-06,2015-06-12
-2c1s,2007-02-13,2005-09-19
-8c1c,2023-03-29,2022-12-20
-6c1i,2018-12-12,2018-01-04
-5c1m,2015-08-05,2015-06-15
-4c1g,2014-08-27,2013-08-12
-8c1a,2023-03-08,2022-12-20
-1c1q,2000-07-26,1999-07-21
-4c1r,2013-11-13,2013-08-13
-6c1x,2018-07-25,2018-01-05
-6c1w,2018-03-14,2018-01-05
-5c1e,2015-07-01,2015-06-13
-2c1i,2005-09-20,2005-09-15
-8c1m,2024-01-10,2022-12-20
-6c1b,2019-01-16,2018-01-04
-1c1s,2000-07-26,1999-07-21
-1c1z,1999-11-19,1999-07-22
-6c1r,2018-05-30,2018-01-05
-3c1p,2009-01-27,2008-01-23
-5c1w,2015-09-30,2015-06-15
-3c1o,2008-05-06,2008-01-23
-6c19,2019-01-16,2018-01-04
-3c1f,2008-11-04,2008-01-23
-4c1d,2014-08-27,2013-08-12
-4c1p,2014-05-14,2013-08-13
-4c1h,2014-08-27,2013-08-12
-2c1g,2005-09-15,2005-09-14
-2c11,2006-09-20,2005-09-09
-6c1o,2019-01-16,2018-01-05
-8c1v,2023-04-19,2022-12-21
-4c10,2014-02-05,2013-08-08
-7c16,2021-03-10,2020-05-02
-7c1y,2020-11-18,2020-05-06
-316d,1997-11-05,1997-03-05
-6yt1,2020-09-02,2020-04-23
-7ytp,2023-11-15,2022-08-15
-2ytk,2007-10-09,2007-04-05
-4ytb,2015-07-01,2015-03-17
-2ytf,2007-10-09,2007-04-05
-2ytq,2007-10-09,2007-04-05
-5yts,2018-12-05,2017-11-20
-4yti,2015-08-12,2015-03-17
-1ytg,1997-03-12,1996-08-01
-4ytg,2015-07-01,2015-03-17
-6ytm,2020-05-27,2020-04-24
-1yt9,2005-04-12,2005-02-10
-7ytd,2023-02-01,2022-08-14
-4ytv,2015-08-12,2015-03-18
-5ytl,2018-08-22,2017-11-19
-2ytd,2007-10-09,2007-04-05
-4yty,2015-04-22,2015-03-18
-2yta,2007-10-09,2007-04-05
-6ytd,2020-07-15,2020-04-24
-7ytl,2023-08-23,2022-08-15
-1ytk,2005-03-08,2005-02-10
-1ytz,2005-04-12,2005-02-11
-5ytq,2018-11-21,2017-11-19
-4yt0,2015-08-05,2015-03-17
-1yt3,2005-08-09,2005-02-09
-6yt6,2021-02-10,2020-04-23
-5ytv,2018-12-05,2017-11-20
-6yt2,2020-06-10,2020-04-23
-6ytb,2020-10-14,2020-04-24
-4yts,2016-03-23,2015-03-18
-2ytp,2007-10-09,2007-04-05
-1ytj,1997-03-12,1996-08-01
-4ytt,2016-03-23,2015-03-18
-7ytx,2023-09-27,2022-08-16
-5ytc,2018-11-21,2017-11-17
-7ytw,2023-05-03,2022-08-16
-6yta,2020-07-15,2020-04-24
-4yt5,2015-07-01,2015-03-17
-7ytc,2023-02-01,2022-08-14
-5ytx,2018-12-05,2017-11-20
-5yt7,2018-08-08,2017-11-17
-5yta,2018-11-21,2017-11-17
-6ytg,2020-07-15,2020-04-24
-8yts,2024-04-24,2024-03-26
-7ytq,2022-09-07,2022-08-16
-1ytv,2005-04-12,2005-02-11
-4yt7,2015-04-29,2015-03-17
-4ytm,2015-08-05,2015-03-18
-6yt3,2020-12-09,2020-04-23
-2yti,2007-10-09,2007-04-05
-4ytr,2016-03-23,2015-03-18
-2yte,2007-10-09,2007-04-05
-5yt6,2018-07-11,2017-11-17
-4ytz,2015-04-22,2015-03-18
-2yto,2007-10-09,2007-04-05
-5ytg,2018-11-21,2017-11-17
-8ytr,2024-04-24,2024-03-26
-2yt9,2007-10-09,2007-04-05
-6ytp,2021-05-12,2020-04-24
-1yt0,2005-06-14,2005-02-09
-1yt7,2005-07-19,2005-02-10
-5ytt,2018-12-05,2017-11-20
-2ytm,2007-10-09,2007-04-05
-5yty,2018-05-23,2017-11-20
-1ytm,2006-01-24,2005-02-10
-5ytd,2018-11-21,2017-11-17
-2ytr,2007-10-09,2007-04-05
-5yth,2018-11-21,2017-11-17
-6ytw,2020-07-15,2020-04-24
-2yts,2007-10-09,2007-04-05
-2ytn,2007-10-09,2007-04-05
-2ytt,2007-10-09,2007-04-05
-8yt5,2024-05-08,2024-03-25
-6yt7,2020-10-14,2020-04-24
-1yty,2006-01-17,2005-02-11
-1yth,1997-03-12,1996-08-01
-1ytt,1996-06-10,1995-11-09
-8yti,2024-04-03,2024-03-26
-5ytm,2018-08-22,2017-11-19
-4ytp,2015-08-05,2015-03-18
-4yt6,2015-04-29,2015-03-17
-1ytc,1996-03-08,1995-07-03
-5ytf,2018-11-21,2017-11-17
-7yt0,2023-08-16,2022-08-13
-5ytu,2018-11-21,2017-11-20
-6yt9,2020-09-16,2020-04-24
-7ytv,2023-06-28,2022-08-16
-5yt9,2018-11-21,2017-11-17
-4yt1,2016-03-02,2015-03-17
-2ytb,2007-10-09,2007-04-05
-4ytq,2016-03-23,2015-03-18
-5yt3,2018-11-21,2017-11-16
-6ytt,2020-11-04,2020-04-24
-7ytf,2023-06-21,2022-08-14
-5yt8,2018-11-21,2017-11-17
-8ytq,2024-04-24,2024-03-26
-4ytu,2016-03-23,2015-03-18
-6yty,2020-07-15,2020-04-24
-5yti,2018-01-17,2017-11-18
-1yti,1997-03-12,1996-08-01
-4ytf,2015-08-12,2015-03-17
-6ytr,2021-05-12,2020-04-24
-2ytg,2007-10-09,2007-04-05
-5yto,2018-11-21,2017-11-19
-4yt9,2015-07-15,2015-03-17
-1ytu,2005-04-05,2005-02-11
-5ytn,2018-08-22,2017-11-19
-7yta,2022-10-12,2022-08-13
-6yti,2020-07-15,2020-04-24
-5ytb,2018-11-21,2017-11-17
-5yte,2018-11-21,2017-11-17
-6ytz,2021-02-03,2020-04-25
-2yth,2007-10-09,2007-04-05
-2ytj,2007-10-09,2007-04-05
-2yt5,2008-04-15,2007-04-05
-6yt4,2020-06-17,2020-04-23
-2ytz,2007-10-09,2007-04-05
-4ytn,2015-08-05,2015-03-18
-4yth,2015-08-12,2015-03-17
-1yte,2005-03-08,2005-02-10
-6ytf,2020-09-16,2020-04-24
-5yt0,2018-06-27,2017-11-16
-4yt3,2016-02-24,2015-03-17
-6yte,2020-07-15,2020-04-24
-4yta,2015-05-27,2015-03-17
-5yt2,2018-04-11,2017-11-16
-5ytz,2018-05-23,2017-11-20
-5ytk,2017-12-27,2017-11-18
-7ytb,2023-03-15,2022-08-14
-4ytc,2015-08-12,2015-03-17
-4boj,2014-05-28,2013-05-21
-6boo,2018-11-28,2017-11-20
-8bo5,2023-09-13,2022-11-14
-3bo7,2008-02-19,2007-12-17
-5bon,2015-08-05,2015-05-27
-3bol,2008-03-11,2007-12-17
-4bo4,2013-09-18,2013-05-18
-3bos,2008-01-15,2007-12-17
-6bod,2018-09-26,2017-11-19
-7bon,2021-01-27,2020-03-19
-5bo5,2015-09-16,2015-05-27
-3boe,2008-01-22,2007-12-17
-5boa,2016-05-04,2015-05-27
-7bop,2020-09-09,2020-03-19
-2bo8,2005-06-06,2005-04-08
-7bo7,2022-03-02,2021-01-24
-7bof,2021-07-07,2021-01-25
-6bon,2018-11-28,2017-11-20
-8boe,2023-11-29,2022-11-15
-7boh,2021-12-08,2021-01-25
-5boj,2015-08-05,2015-05-27
-6boi,2018-04-11,2017-11-20
-2boz,2005-05-20,2005-04-15
-3bom,2008-01-08,2007-12-17
-2boi,2006-05-25,2005-04-12
-5boc,2015-06-17,2015-05-27
-1bow,1999-08-06,1998-08-06
-6boj,2018-08-22,2017-11-20
-3bod,2008-03-25,2007-12-17
-1boo,1998-08-12,1998-07-31
-5bot,2015-06-17,2015-05-27
-2bov,2005-04-15,2005-04-14
-3boc,2008-01-22,2007-12-17
-2bog,2005-10-05,2005-04-10
-2bob,2005-04-27,2005-04-09
-6bof,2019-05-22,2017-11-20
-3bo5,2008-01-22,2007-12-17
-5bo9,2015-07-15,2015-05-27
-7bo2,2022-03-02,2021-01-23
-8bo6,2023-09-13,2022-11-14
-4bol,2013-07-17,2013-05-21
-1boz,1998-08-12,1998-08-06
-8boi,2023-03-08,2022-11-15
-8bow,2023-11-29,2022-11-15
-6bo2,2018-05-16,2017-11-17
-3box,2008-01-01,2007-12-18
-2bo7,2005-06-06,2005-04-08
-7bo1,2022-03-02,2021-01-23
-8bo3,2023-09-13,2022-11-14
-7bok,2021-03-24,2020-03-19
-1bo7,1998-08-19,1998-08-10
-8bog,2023-03-08,2022-11-15
-4bo0,2013-09-18,2013-05-17
-6boz,2019-05-01,2017-11-21
-3bow,2008-11-25,2007-12-17
-5bof,2015-12-09,2015-05-27
-5bo6,2015-07-15,2015-05-27
-2boj,2006-02-22,2005-04-12
-8bok,2023-03-08,2022-11-15
-8boq,2023-06-14,2022-11-15
-6boh,2018-05-23,2017-11-20
-8bo9,2023-09-27,2022-11-15
-2bow,1999-08-06,1998-08-06
-7bom,2021-01-27,2020-03-19
-5bod,2015-06-17,2015-05-27
-1bob,1999-04-20,1998-07-02
-6boy,2018-05-30,2017-11-21
-7bor,2020-05-13,2020-03-19
-6bo7,2017-12-13,2017-11-18
-7bot,2021-03-24,2020-03-19
-3bov,2008-07-15,2007-12-17
-4bo9,2013-09-18,2013-05-18
-8boh,2023-03-08,2022-11-15
-2boy,2006-08-24,2005-04-15
-6bo1,2018-05-16,2017-11-17
-5boe,2015-12-09,2015-05-27
-2bou,2006-10-18,2005-04-14
-1bo4,1998-10-07,1998-08-08
-8bom,2023-03-08,2022-11-15
-8bo8,2023-11-29,2022-11-15
-1bo5,1999-01-13,1998-08-10
-1bou,1999-05-04,1998-08-06
-7bov,2020-05-13,2020-03-20
-7bo8,2021-05-19,2021-01-24
-5bo2,2016-06-01,2015-05-27
-6bo6,2018-07-25,2017-11-18
-8bor,2023-06-28,2022-11-15
-5boy,2015-06-17,2015-05-27
-2bo6,2005-06-06,2005-04-08
-5bo3,2016-06-01,2015-05-27
-2bo2,2006-08-09,2005-04-07
-2box,2006-10-18,2005-04-14
-4bo5,2013-09-18,2013-05-18
-4bo1,2013-09-18,2013-05-18
-6bok,2018-05-23,2017-11-20
-7boi,2021-07-07,2021-01-25
-3boo,2008-05-20,2007-12-17
-7boo,2020-09-09,2020-03-19
-7bog,2021-07-07,2021-01-25
-2bof,2005-10-05,2005-04-10
-8bol,2023-11-29,2022-11-15
-8boy,2023-02-22,2022-11-15
-8bo1,2023-09-20,2022-11-14
-8boc,2023-11-29,2022-11-15
-1boa,1999-08-01,1998-08-01
-4bo8,2013-09-18,2013-05-18
-5bom,2015-08-19,2015-05-27
-5bou,2015-08-19,2015-05-27
-5bok,2016-07-27,2015-05-27
-4boh,2013-09-04,2013-05-20
-7bo0,2022-07-13,2021-01-23
-4bow,2013-12-18,2013-05-22
-8bof,2023-03-08,2022-11-15
-2bos,1999-10-20,1998-10-20
-7bo4,2022-03-02,2021-01-23
-5bo8,2015-07-15,2015-05-27
-2bop,1994-01-31,1994-01-13
-2bon,2006-10-18,2005-04-12
-8bod,2023-03-08,2022-11-15
-2bo0,2006-10-18,2005-04-06
-2boq,2005-11-02,2005-04-13
-6boc,2018-09-19,2017-11-19
-4boc,2013-09-25,2013-05-18
-1bo8,1998-08-19,1998-08-10
-8boz,2023-02-08,2022-11-15
-8bon,2023-06-28,2022-11-15
-3bob,2008-01-22,2007-12-17
-4bos,2013-07-24,2013-05-22
-3bo8,2008-12-23,2007-12-17
-3boh,2008-01-22,2007-12-17
-1bos,1999-02-02,1998-01-13
-7bos,2021-03-24,2020-03-19
-8bo4,2023-09-13,2022-11-14
-4bo2,2013-09-18,2013-05-18
-3bof,2008-03-11,2007-12-17
-8bos,2023-11-29,2022-11-15
-4boe,2014-05-28,2013-05-19
-1bor,1997-04-01,1995-09-27
-7boe,2021-12-08,2021-01-25
-2bod,2005-10-05,2005-04-10
-7bod,2021-07-07,2021-01-25
-8bo7,2023-09-13,2022-11-14
-4bo6,2013-09-18,2013-05-18
-4boy,2014-06-11,2013-05-22
-2boa,2005-12-13,2005-04-08
-8bob,2023-10-18,2022-11-15
-1bo6,1999-08-10,1998-08-10
-6bol,2018-11-28,2017-11-20
-5boo,2015-07-29,2015-05-27
-8bop,2024-06-05,2022-11-15
-3boy,2008-01-15,2007-12-18
-6box,2018-07-25,2017-11-21
-2bok,2005-06-16,2005-04-12
-2boh,2006-04-05,2005-04-11
-7bo5,2022-03-02,2021-01-23
-2boc,2005-04-27,2005-04-09
-4bo3,2013-09-18,2013-05-18
-6boe,2018-09-26,2017-11-19
-7bo3,2022-03-02,2021-01-23
-5bol,2015-08-19,2015-05-27
-3bon,2008-05-20,2007-12-17
-5bo7,2015-07-15,2015-05-27
-7bo6,2021-08-11,2021-01-24
-2bo9,2005-04-15,2005-04-08
-4bo7,2013-09-18,2013-05-18
-8box,2024-06-05,2022-11-15
-1bog,1999-03-23,1998-08-04
-1bof,1999-01-06,1998-08-04
-2e8w,2007-06-12,2007-01-24
-8e8v,2022-10-05,2022-08-25
-8e8f,2023-02-01,2022-08-25
-2e85,2008-01-22,2007-01-18
-5e8z,2016-05-11,2015-10-14
-6e8y,2019-01-30,2018-07-31
-8e8u,2022-10-05,2022-08-25
-5e8m,2015-11-18,2015-10-14
-7e8z,2021-10-13,2021-03-03
-5e8b,2016-11-09,2015-10-14
-2e86,2008-01-22,2007-01-19
-3e8r,2008-10-21,2008-08-20
-1e8m,2001-01-16,2000-09-27
-3e80,2008-12-30,2008-08-19
-3e8z,2008-12-02,2008-08-20
-1e83,2000-11-06,2000-09-15
-3e84,2008-11-04,2008-08-19
-5e8f,2015-11-18,2015-10-14
-4e81,2012-05-30,2012-03-19
-1e8e,2001-09-20,2000-09-20
-3e8l,2009-07-28,2008-08-20
-1e8u,2001-04-03,2000-10-01
-5e8j,2016-07-13,2015-10-14
-1e8h,2000-09-21,2000-09-20
-4e89,2012-10-17,2012-03-19
-8e89,2023-02-01,2022-08-25
-6e8p,2019-04-03,2018-07-30
-3e86,2008-12-23,2008-08-19
-3e8b,2008-12-23,2008-08-19
-1e8g,2000-09-21,2000-09-20
-2e88,2008-01-22,2007-01-19
-8e8c,2023-02-01,2022-08-25
-4e8w,2012-12-26,2012-03-20
-6e8x,2019-03-27,2018-07-31
-5e8q,2016-09-21,2015-10-14
-7e8d,2021-11-10,2021-03-01
-3e81,2008-11-04,2008-08-19
-5e84,2016-01-27,2015-10-13
-5e8a,2016-08-24,2015-10-13
-5e8g,2015-12-09,2015-10-14
-7e8o,2022-03-02,2021-03-02
-4e8h,2013-04-24,2012-03-20
-8e8g,2023-02-01,2022-08-25
-1e82,2000-10-19,2000-09-15
-8e8h,2023-02-01,2022-08-25
-2e8v,2007-06-12,2007-01-23
-8e87,2023-02-01,2022-08-25
-4e8g,2012-05-02,2012-03-20
-7e8m,2021-05-26,2021-03-02
-1e8a,2001-01-08,2000-09-18
-5e83,2016-07-20,2015-10-13
-2e8y,2008-02-19,2007-01-24
-3e8s,2008-09-02,2008-08-20
-2e8h,2007-07-24,2007-01-19
-5e8c,2015-12-23,2015-10-14
-2e80,2007-01-30,2007-01-15
-8e8d,2023-02-01,2022-08-25
-2e8x,2007-06-12,2007-01-24
-5e88,2016-08-24,2015-10-13
-8e8j,2023-02-01,2022-08-25
-6e85,2018-08-08,2018-07-27
-4e84,2012-12-26,2012-03-19
-8e8a,2023-02-01,2022-08-25
-8e8w,2023-08-30,2022-08-25
-4e8y,2012-12-26,2012-03-20
-8e80,2023-02-22,2022-08-25
-8e8e,2023-02-01,2022-08-25
-3e8h,2008-12-23,2008-08-19
-1e8w,2000-11-17,2000-10-03
-7e8p,2021-07-21,2021-03-02
-3e87,2008-10-14,2008-08-19
-2e82,2007-03-06,2007-01-16
-1e8d,2001-08-17,2000-09-19
-6e8o,2019-08-21,2018-07-30
-5e8e,2015-10-28,2015-10-14
-3e8d,2008-10-14,2008-08-19
-8e86,2023-02-01,2022-08-25
-6e87,2019-04-17,2018-07-27
-1e87,2000-09-26,2000-09-18
-5e8w,2016-05-11,2015-10-14
-5e80,2016-05-04,2015-10-13
-2e89,2007-11-13,2007-01-19
-8e8i,2023-07-26,2022-08-25
-3e89,2008-12-23,2008-08-19
-8e8b,2023-02-01,2022-08-25
-1e88,2000-10-09,2000-09-18
-1e84,2000-11-06,2000-09-15
-6e8q,2018-09-05,2018-07-30
-8e8q,2023-11-08,2022-08-25
-2e84,2008-01-15,2007-01-17
-6e8f,2019-07-31,2018-07-29
-3e8c,2008-11-18,2008-08-19
-6e8i,2018-11-14,2018-07-29
-8e82,2023-03-22,2022-08-25
-3e8t,2008-12-09,2008-08-20
-1e8t,2001-04-03,2000-10-01
-8e8o,2023-02-08,2022-08-25
-6e86,2018-09-19,2018-07-27
-2e8s,2007-07-24,2007-01-23
-8e81,2023-02-22,2022-08-25
-3e8w,2008-12-09,2008-08-20
-1e8z,2000-11-17,2000-10-03
-1e8x,2000-10-26,2000-10-03
-1e8v,2001-04-03,2000-10-01
-5e8o,2016-02-03,2015-10-14
-6e88,2018-10-10,2018-07-27
-2e8r,2007-07-24,2007-01-23
-1e85,2000-11-06,2000-09-15
-3e8u,2009-07-07,2008-08-20
-3e88,2008-10-14,2008-08-19
-5e89,2016-08-24,2015-10-13
-5e8y,2016-05-11,2015-10-14
-5e81,2016-01-27,2015-10-13
-7e8q,2021-07-21,2021-03-02
-1e80,2000-09-26,2000-09-15
-5e8n,2016-02-03,2015-10-14
-3e8f,2008-12-23,2008-08-19
-8e8k,2023-02-01,2022-08-25
-2e8u,2007-06-12,2007-01-23
-2e8a,2008-01-22,2007-01-19
-2e8t,2007-06-12,2007-01-23
-8e88,2023-02-01,2022-08-25
-3e83,2008-12-23,2008-08-19
-2e83,2008-01-15,2007-01-17
-6e8m,2018-11-14,2018-07-30
-8e83,2022-11-30,2022-08-25
-4e8c,2012-05-30,2012-03-20
-1e86,2000-11-06,2000-09-15
-4e80,2012-07-04,2012-03-19
-2e81,2007-01-30,2007-01-15
-6e8z,2019-01-30,2018-07-31
-3e85,2009-03-03,2008-08-19
-3e8e,2008-11-18,2008-08-19
-3e8g,2008-12-23,2008-08-19
-5e8p,2016-02-03,2015-10-14
-8e85,2023-02-01,2022-08-25
-3e8q,2008-12-02,2008-08-20
-1e81,2000-10-19,2000-09-15
-6e83,2018-09-19,2018-07-27
-2e87,2007-07-24,2007-01-19
-5e8x,2016-05-11,2015-10-14
-1e8n,2001-01-16,2000-09-27
-3e8n,2009-09-01,2008-08-20
-1e8c,2001-09-13,2000-09-19
-2e8q,2007-07-24,2007-01-23
-1e8b,2000-10-15,2000-09-18
-6e8k,2018-11-14,2018-07-30
-3e8x,2008-09-02,2008-08-20
-8e8m,2023-03-22,2022-08-25
-4e8z,2012-12-26,2012-03-20
-3e8m,2008-11-04,2008-08-20
-1e8k,2001-09-20,2000-09-25
-2e8z,2008-02-19,2007-01-24
-3e8v,2008-09-02,2008-08-20
-4fxb,2012-11-14,2012-07-03
-6fxh,2019-03-06,2018-03-09
-5fxd,2016-07-27,2016-03-01
-5fxt,2017-08-16,2016-03-02
-1fx7,2001-03-07,2000-09-25
-5fxm,2016-03-16,2016-03-02
-1fxq,2001-04-21,2000-09-26
-4fxo,2012-08-22,2012-07-03
-8fx0,2023-07-19,2023-01-23
-1fxo,2000-12-27,2000-09-26
-7fxs,2023-06-14,2023-04-27
-4fx9,2013-04-10,2012-07-02
-5fxf,2016-07-27,2016-03-01
-4fxs,2012-07-25,2012-07-03
-8fx2,2023-07-19,2023-01-23
-3fx2,1993-10-31,1991-10-17
-2fx3,2006-03-28,2006-02-03
-8fxi,2023-06-14,2023-01-24
-6fx1,2018-07-11,2018-03-08
-6fxy,2018-08-22,2018-03-09
-8fx5,2023-09-13,2023-01-23
-8fx3,2023-07-19,2023-01-23
-7fxz,2023-06-14,2023-04-27
-7fxx,2023-06-14,2023-04-27
-7fxp,2023-06-14,2023-04-27
-7fxn,2023-06-14,2023-04-27
-4fxr,2013-05-22,2012-07-03
-7fxg,2023-06-14,2023-04-27
-7fx0,2023-06-14,2023-04-27
-3fxi,2009-03-03,2009-01-21
-2fxm,2006-11-21,2006-02-06
-2fx6,2006-02-14,2006-02-03
-7fxf,2023-06-14,2023-04-27
-7fxe,2023-06-14,2023-04-27
-7fxw,2023-06-14,2023-04-27
-3fxg,2009-02-03,2009-01-20
-7fxv,2023-06-14,2023-04-27
-2fxd,2007-02-20,2006-02-04
-7fxy,2023-06-14,2023-04-27
-7fxj,2023-06-14,2023-04-27
-7fxa,2023-06-14,2023-04-27
-7fx6,2023-06-14,2023-04-27
-2fxe,2007-02-20,2006-02-05
-6fxv,2019-03-20,2018-03-09
-7fx4,2023-06-14,2023-04-27
-7fxr,2023-06-14,2023-04-27
-6fx8,2018-05-16,2018-03-08
-4fxd,2013-02-27,2012-07-03
-3fxx,2009-02-03,2009-01-21
-8fxd,2024-02-07,2023-01-24
-6fx3,2018-07-11,2018-03-08
-6fx6,2018-08-08,2018-03-08
-3fxv,2009-04-14,2009-01-21
-3fx5,2009-03-24,2009-01-20
-6fx7,2019-09-25,2018-03-08
-1fxu,2000-10-18,2000-09-27
-5fx8,2016-06-22,2016-02-25
-8fxq,2023-02-08,2023-01-25
-6fx9,2018-05-16,2018-03-08
-4fxj,2013-03-27,2012-07-03
-4fx6,2013-05-22,2012-07-02
-4fx3,2013-05-15,2012-07-02
-4fxf,2013-03-27,2012-07-03
-3fxo,2010-01-26,2009-01-21
-6fx0,2018-05-23,2018-03-08
-3fxw,2010-01-26,2009-01-21
-3fxp,2010-02-09,2009-01-21
-2fxi,2006-08-08,2006-02-06
-1fxw,2001-12-12,2000-09-27
-8fx1,2023-07-19,2023-01-23
-5fxn,2016-03-16,2016-03-02
-2fxl,2006-05-23,2006-02-06
-7fx7,2023-06-14,2023-04-27
-7fxi,2023-06-14,2023-04-27
-6fxt,2018-08-22,2018-03-09
-1fxy,1998-06-17,1998-04-22
-7fx9,2023-06-14,2023-04-27
-3fxk,2010-01-26,2009-01-21
-3fxl,2010-01-26,2009-01-21
-5fxx,2016-03-16,2016-03-03
-1fx4,2001-02-28,2000-09-25
-4fx5,2012-07-18,2012-07-02
-4fxz,2012-08-08,2012-07-03
-7fxk,2023-06-14,2023-04-27
-2fx2,1993-10-31,1991-10-17
-8fxs,2023-06-21,2023-01-25
-1fx5,2001-01-17,2000-09-25
-7fx1,2023-06-14,2023-04-27
-7fxd,2023-06-14,2023-04-27
-4fx8,2013-06-19,2012-07-02
-8fxe,2024-02-07,2023-01-24
-5fxv,2016-03-16,2016-03-03
-5fxz,2016-03-16,2016-03-03
-1fx1,1985-01-02,1984-10-15
-7fxt,2023-06-14,2023-04-27
-5fxe,2016-07-27,2016-03-01
-3fxu,2010-01-26,2009-01-21
-5fxu,2016-05-18,2016-03-02
-6fxk,2018-08-22,2018-03-09
-4fxy,2013-11-13,2012-07-03
-3fx4,2009-12-22,2009-01-20
-8fxc,2023-10-04,2023-01-24
-7fxh,2023-06-14,2023-04-27
-4fx2,1993-10-31,1991-10-17
-6fxp,2019-03-20,2018-03-09
-6fxm,2018-08-22,2018-03-09
-3fx6,2009-08-25,2009-01-20
-8fxa,2024-02-07,2023-01-24
-5fxs,2016-10-19,2016-03-02
-8fx6,2023-06-21,2023-01-24
-3fxb,2009-05-26,2009-01-20
-3fxs,2010-02-09,2009-01-21
-3fxm,2010-01-26,2009-01-21
-6fx2,2018-07-11,2018-03-08
-6fxg,2019-03-20,2018-03-09
-2fxf,2006-02-14,2006-02-05
-6fxe,2019-03-20,2018-03-08
-6fxi,2019-03-20,2018-03-09
-6fxj,2019-07-10,2018-03-09
-5fxw,2016-03-16,2016-03-03
-6fxx,2018-08-22,2018-03-09
-4fxq,2012-09-26,2012-07-03
-5fxc,2016-06-29,2016-02-29
-6fxq,2019-07-10,2018-03-09
-7fxc,2023-06-14,2023-04-27
-3fxz,2009-02-17,2009-01-21
-1fx9,2001-09-25,2000-09-25
-1fxx,2000-12-06,2000-09-27
-7fxb,2023-06-14,2023-04-27
-7fx2,2023-06-14,2023-04-27
-3fxj,2010-01-26,2009-01-21
-4fxp,2012-07-25,2012-07-03
-4fxa,2012-07-25,2012-07-03
-2fxr,2006-02-09,2006-02-06
-5fx3,2017-01-18,2016-02-22
-1fxs,1999-08-26,1998-09-01
-1fxh,2001-03-28,2000-09-26
-7fxq,2023-06-14,2023-04-27
-6fxr,2018-08-22,2018-03-09
-8fxt,2023-08-30,2023-01-25
-1fxl,2001-02-05,2000-09-26
-8fx7,2023-06-21,2023-01-24
-7fxm,2023-06-14,2023-04-27
-5fxq,2016-10-19,2016-03-02
-7fx8,2023-06-14,2023-04-27
-5fxp,2016-07-27,2016-03-02
-7fx5,2023-06-14,2023-04-27
-2fx4,2006-02-14,2006-02-03
-5fx2,1993-10-31,1991-10-17
-5fx6,2016-06-22,2016-02-24
-2fxs,2007-02-06,2006-02-06
-8fxo,2024-02-07,2023-01-25
-5fxl,2016-03-16,2016-03-02
-8fxv,2023-06-21,2023-01-25
-8fxn,2024-02-07,2023-01-25
-1fxv,2001-03-28,2000-09-27
-5fx5,2016-06-22,2016-02-24
-3fxr,2010-01-26,2009-01-21
-1fxf,2001-09-25,2000-09-25
-5fxr,2016-10-19,2016-03-02
-7fxu,2023-06-14,2023-04-27
-2fxv,2006-06-20,2006-02-06
-8fx4,2023-07-12,2023-01-23
-1fxp,2001-04-21,2000-09-26
-8fxb,2023-10-04,2023-01-24
-2fxu,2006-03-07,2006-02-06
-4fxl,2012-08-15,2012-07-03
-8fxu,2023-08-30,2023-01-25
-8q2q,2023-12-06,2023-08-03
-1q2r,2003-09-09,2003-07-25
-5q2e,2018-08-08,2017-05-25
-5q2w,2018-08-08,2017-05-25
-3q2q,2011-01-12,2010-12-20
-3q2r,2011-10-05,2010-12-20
-8q2w,2023-12-06,2023-08-03
-3q23,2011-02-16,2010-12-19
-7q2p,2022-05-11,2021-10-25
-5q2d,2018-08-08,2017-05-25
-5q20,2018-08-08,2017-05-15
-1q2s,2003-09-09,2003-07-25
-6q2u,2019-11-20,2019-08-08
-5q26,2018-08-08,2017-05-15
-8q2e,2023-11-01,2023-08-02
-6q2w,2019-05-29,2018-12-03
-5q2k,2018-08-08,2017-05-25
-7q24,2022-02-16,2021-10-23
-3q2n,2011-02-23,2010-12-20
-7q29,2022-02-16,2021-10-23
-5q2l,2018-08-08,2017-05-25
-5q2n,2018-08-08,2017-05-25
-6q21,1992-07-28,1992-07-27
-7q21,2022-02-02,2021-10-22
-2q2v,2007-10-30,2007-05-29
-8q29,2024-03-13,2023-08-01
-4q29,2014-05-07,2014-04-07
-5q2c,2018-08-08,2017-05-25
-3q26,2011-06-01,2010-12-19
-1q2p,2004-09-14,2003-07-25
-7q2a,2022-04-06,2021-10-25
-1q2b,2003-11-25,2003-07-24
-6q2c,2020-10-21,2019-08-07
-3q2l,2011-02-23,2010-12-20
-3q2m,2011-05-18,2010-12-20
-4q2c,2014-11-19,2014-04-07
-8q2y,2023-12-06,2023-08-03
-5q2s,2018-08-08,2017-05-25
-5q2h,2018-08-08,2017-05-25
-6q27,2020-01-22,2019-08-07
-5q2u,2018-08-08,2017-05-25
-7q2c,2022-02-02,2021-10-25
-5q2f,2018-08-08,2017-05-25
-3q2o,2011-10-26,2010-12-20
-1q25,2004-06-29,2003-07-23
-2q27,2008-06-03,2007-05-26
-6q28,2020-01-22,2019-08-07
-6q2o,2019-10-02,2019-08-08
-7q2n,2022-05-11,2021-10-25
-7q2h,2022-02-02,2021-10-25
-3q2f,2011-01-26,2010-12-20
-5q29,2018-08-08,2017-05-15
-1q21,1992-07-15,1991-09-25
-2q2a,2008-01-15,2007-05-26
-6q2q,2020-01-22,2019-08-08
-3q2g,2011-03-30,2010-12-20
-7q2s,2022-09-21,2021-10-26
-8q2t,2023-12-06,2023-08-03
-4q24,2014-10-08,2014-04-07
-7q2e,2022-02-02,2021-10-25
-3q2a,2011-12-21,2010-12-19
-7q2o,2022-05-11,2021-10-25
-5q2i,2018-08-08,2017-05-25
-5q28,2018-08-08,2017-05-15
-5q25,2018-08-08,2017-05-15
-5q22,2018-08-08,2017-05-15
-3q2k,2011-01-19,2010-12-20
-7q2t,2022-11-16,2021-10-26
-7q26,2022-02-16,2021-10-23
-6q2t,2019-11-13,2019-08-08
-4q22,2014-04-23,2014-04-05
-3q28,2011-06-01,2010-12-19
-1q2d,2004-08-03,2003-07-24
-7q2r,2022-09-21,2021-10-26
-6q2a,2020-06-17,2019-08-07
-8q2u,2023-12-06,2023-08-03
-3q2i,2011-01-19,2010-12-20
-2q21,1992-07-15,1991-09-25
-2q2c,2008-01-15,2007-05-28
-8q2p,2024-05-15,2023-08-03
-1q20,2003-11-11,2003-07-23
-6q20,2019-10-23,2019-08-06
-3q22,2011-02-16,2010-12-19
-4q21,1992-07-15,1991-09-25
-4q27,2015-10-07,2014-04-07
-6q2k,2020-08-12,2019-08-08
-5q2q,2018-08-08,2017-05-25
-5q2t,2018-08-08,2017-05-25
-7q2x,2022-03-23,2021-10-26
-3q2j,2011-05-18,2010-12-20
-7q2l,2022-11-09,2021-10-25
-8q2v,2023-12-06,2023-08-03
-3q2t,2011-02-16,2010-12-20
-4q2g,2014-07-02,2014-04-08
-2q28,2008-06-03,2007-05-26
-3q2z,2011-12-21,2010-12-21
-6q29,2020-08-12,2019-08-07
-5q2a,2018-08-08,2017-05-25
-5q2m,2018-08-08,2017-05-25
-4q2k,2014-07-23,2014-04-09
-8q2o,2024-05-15,2023-08-03
-7q2b,2022-02-02,2021-10-25
-4q2x,2014-07-23,2014-04-10
-5q2o,2018-08-08,2017-05-25
-2q2z,2007-09-18,2007-05-29
-6q2f,2019-11-27,2019-08-07
-7q22,2022-09-21,2021-10-22
-7q25,2022-02-16,2021-10-23
-3q27,2011-06-01,2010-12-19
-5q24,2018-08-08,2017-05-15
-5q23,2018-08-08,2017-05-15
-2q2q,2007-10-30,2007-05-29
-7q2g,2022-02-02,2021-10-25
-3q2v,2011-04-06,2010-12-20
-4q2e,2014-07-02,2014-04-08
-2q2n,2008-04-22,2007-05-29
-1q2l,2005-05-17,2003-07-25
-6q23,2019-10-23,2019-08-06
-5q2x,2018-08-08,2017-05-25
-2q2l,2008-03-25,2007-05-29
-7q2i,2022-11-09,2021-10-25
-8q2s,2023-12-06,2023-08-03
-8q2x,2023-12-06,2023-08-03
-6q2l,2020-08-12,2019-08-08
-7q2k,2022-11-09,2021-10-25
-5q2z,2018-08-08,2017-05-25
-2q2y,2007-09-18,2007-05-29
-4q23,2015-03-18,2014-04-05
-4q2v,2015-04-15,2014-04-10
-7q20,2022-02-02,2021-10-22
-3q2h,2011-03-30,2010-12-20
-4q2t,2014-07-23,2014-04-09
-5q2j,2018-08-08,2017-05-25
-8q25,2024-06-05,2023-08-01
-7q2q,2022-09-21,2021-10-26
-7q2w,2022-04-06,2021-10-26
-8q2a,2024-03-13,2023-08-01
-5q2g,2018-08-08,2017-05-25
-4q2l,2014-07-09,2014-04-09
-7q2v,2022-11-09,2021-10-26
-3q2x,2011-10-12,2010-12-20
-3q2d,2011-02-09,2010-12-20
-5q2v,2018-08-08,2017-05-25
-6q2e,2019-10-16,2019-08-07
-4q2f,2015-10-07,2014-04-08
-2q29,2008-06-03,2007-05-26
-7q2y,2022-03-23,2021-10-26
-7q2j,2021-11-24,2021-10-25
-3q25,2011-06-01,2010-12-19
-6q2j,2019-10-02,2019-08-08
-6q2r,2019-10-02,2019-08-08
-3q2p,2011-04-06,2010-12-20
-3q24,2011-02-16,2010-12-19
-7q2m,2022-11-23,2021-10-25
-6q2n,2019-10-02,2019-08-08
-6q2s,2019-10-02,2019-08-08
-8q2r,2023-12-06,2023-08-03
-4q2m,2014-07-09,2014-04-09
-5q2r,2018-08-08,2017-05-25
-1q2o,2004-01-13,2003-07-25
-8q28,2024-03-13,2023-08-01
-2q2r,2007-10-16,2007-05-29
-6q2m,2019-10-16,2019-08-08
-4q26,2015-10-07,2014-04-07
-7q27,2022-02-16,2021-10-23
-2q2t,2007-07-10,2007-05-29
-7q2f,2022-02-02,2021-10-25
-7q23,2022-09-21,2021-10-22
-6q2p,2020-01-22,2019-08-08
-2q2o,2008-06-17,2007-05-29
-7q2d,2022-02-02,2021-10-25
-7q28,2022-02-16,2021-10-23
-1q2q,2004-09-14,2003-07-25
-5q2y,2018-08-08,2017-05-25
-1q2e,2003-11-25,2003-07-24
-1q2c,2004-08-03,2003-07-24
-5q2b,2018-08-08,2017-05-25
-3q2y,2011-06-15,2010-12-20
-5q2p,2018-08-08,2017-05-25
-4q2d,2014-11-19,2014-04-07
-6q2y,2019-04-24,2018-12-03
-3q29,2011-06-01,2010-12-19
-1q23,2004-08-03,2003-07-23
-3q2w,2011-02-23,2010-12-20
-1q24,2003-08-19,2003-07-23
-1q22,2003-11-11,2003-07-23
-5q27,2018-08-08,2017-05-15
-2h3p,2006-08-01,2006-05-22
-7h3y,2024-04-24,2024-04-04
-8h38,2023-10-11,2022-10-08
-7h3p,2024-04-24,2024-04-04
-8h35,2023-10-11,2022-10-08
-4h3f,2012-11-07,2012-09-13
-2h39,2006-06-13,2006-05-22
-1h31,2002-11-07,2002-08-21
-3h3q,2010-03-02,2009-04-17
-6h3a,2019-06-26,2018-07-17
-1h38,2002-11-20,2002-08-24
-7h3h,2024-04-24,2024-04-04
-7h36,2024-04-24,2024-04-04
-5h3h,2017-01-11,2016-10-24
-6h34,2018-12-19,2018-07-17
-4h3k,2012-10-31,2012-09-13
-1h3c,2003-08-21,2002-08-25
-1h30,2003-01-30,2002-08-21
-5h3q,2017-02-22,2016-10-26
-1h3m,2003-08-01,2002-09-10
-4h3x,2013-04-24,2012-09-14
-7h3r,2024-04-24,2024-04-04
-7h3v,2024-04-24,2024-04-04
-7h3n,2024-04-24,2024-04-04
-1h33,2002-11-07,2002-08-21
-8h3j,2023-05-17,2022-10-08
-2h3t,2006-09-12,2006-05-23
-4h3d,2012-09-26,2012-09-13
-2h3w,2006-08-01,2006-05-23
-2h35,2006-11-14,2006-05-22
-4h31,2012-09-26,2012-09-13
-4h3a,2012-12-19,2012-09-13
-5h3a,2017-01-18,2016-10-21
-1h3v,2003-01-23,2002-09-19
-7h38,2024-04-24,2024-04-04
-2h3x,2006-11-21,2006-05-23
-1h3g,2003-08-14,2002-09-03
-4h3o,2012-09-26,2012-09-14
-8h3n,2023-05-10,2022-10-09
-7h3w,2024-04-24,2024-04-04
-7h3l,2024-04-24,2024-04-04
-6h33,2018-12-19,2018-07-17
-6h3v,2019-02-27,2018-07-19
-4h3g,2012-11-07,2012-09-13
-4h36,2012-11-21,2012-09-13
-6h3d,2019-04-10,2018-07-18
-1h3e,2002-10-27,2002-08-28
-5h3f,2017-08-30,2016-10-23
-2h3h,2007-05-22,2006-05-22
-7h37,2024-04-24,2024-04-04
-3h3g,2009-08-11,2009-04-16
-3h36,2009-05-12,2009-04-15
-4h3i,2012-11-07,2012-09-13
-2h3u,2006-08-01,2006-05-23
-6h3r,2019-09-18,2018-07-19
-3h3c,2009-05-26,2009-04-16
-1h3j,2003-06-12,2002-09-05
-7h3c,2024-04-24,2024-04-04
-8h3a,2023-10-11,2022-10-08
-5h37,2016-11-30,2016-10-20
-6h3k,2018-09-19,2018-07-19
-7h3m,2024-04-24,2024-04-04
-7h3g,2024-04-24,2024-04-04
-6h37,2018-12-19,2018-07-17
-7h33,2024-04-24,2024-04-04
-3h39,2009-10-13,2009-04-16
-1h3d,2003-10-03,2002-08-27
-4h3h,2012-10-31,2012-09-13
-6h3t,2019-02-27,2018-07-19
-1h36,2003-08-21,2002-08-24
-3h3j,2010-04-28,2009-04-16
-8h3g,2023-10-11,2022-10-08
-2h3e,2006-10-17,2006-05-22
-4h3s,2013-04-24,2012-09-14
-7h34,2024-04-24,2024-04-04
-6h3z,2018-11-07,2018-07-19
-8h3y,2023-02-08,2022-10-09
-5h3j,2017-01-11,2016-10-25
-3h32,2009-07-28,2009-04-15
-6h3e,2019-07-24,2018-07-18
-5h3z,2017-03-01,2016-10-28
-8h3e,2023-03-22,2022-10-08
-8h3m,2023-05-10,2022-10-09
-8h3d,2023-03-22,2022-10-08
-1h3t,2003-01-23,2002-09-19
-3h3p,2010-01-19,2009-04-16
-2h3q,2006-07-25,2006-05-22
-4h3y,2012-10-03,2012-09-14
-2h34,2006-07-18,2006-05-22
-4h3j,2012-10-17,2012-09-13
-6h35,2019-12-04,2018-07-17
-6h3u,2019-02-27,2018-07-19
-8h33,2023-10-11,2022-10-07
-8h3k,2023-10-11,2022-10-08
-2h3s,2006-09-12,2006-05-23
-3h3x,2009-07-21,2009-04-17
-1h3b,2003-08-21,2002-08-25
-3h3v,2009-06-16,2009-04-17
-1h39,2003-08-21,2002-08-24
-8h3x,2023-02-08,2022-10-09
-8h3l,2023-10-11,2022-10-08
-5h3t,2016-12-28,2016-10-27
-3h30,2009-05-12,2009-04-15
-4h32,2013-07-10,2012-09-13
-7h3b,2024-04-24,2024-04-04
-4h3z,2012-10-03,2012-09-14
-1h3a,2003-08-21,2002-08-24
-8h39,2023-02-22,2022-10-08
-6h3s,2019-02-27,2018-07-19
-4h33,2012-11-07,2012-09-13
-1h35,2003-08-21,2002-08-24
-3h3k,2009-10-13,2009-04-16
-8h3q,2023-10-11,2022-10-09
-7h3z,2024-04-24,2024-04-04
-7h3s,2024-04-24,2024-04-04
-7h3j,2024-04-24,2024-04-04
-8h36,2023-10-11,2022-10-08
-8h3h,2023-10-18,2022-10-08
-2h3d,2006-06-20,2006-05-22
-8h34,2023-10-11,2022-10-07
-6h3g,2018-10-10,2018-07-18
-1h3f,2002-09-12,2002-08-28
-7h3a,2024-04-24,2024-04-04
-7h32,2024-04-24,2024-04-04
-2h3v,2006-07-25,2006-05-23
-4h35,2012-12-12,2012-09-13
-6h3c,2019-07-10,2018-07-18
-1h3y,2003-01-23,2002-09-19
-2h32,2007-04-24,2006-05-22
-1h3w,2003-01-23,2002-09-19
-4h3q,2013-02-27,2012-09-14
-8h37,2023-10-11,2022-10-08
-3h3u,2010-02-02,2009-04-17
-4h38,2012-12-19,2012-09-13
-6h3q,2019-07-17,2018-07-19
-1h3x,2003-11-20,2002-09-19
-5h3u,2016-12-28,2016-10-27
-3h33,2009-12-29,2009-04-15
-6h3o,2018-10-10,2018-07-19
-3h3a,2009-10-13,2009-04-16
-6h39,2018-11-07,2018-07-17
-2h3z,2006-07-25,2006-05-23
-7h35,2024-04-24,2024-04-04
-4h3l,2012-10-31,2012-09-14
-4h3u,2012-10-03,2012-09-14
-4h37,2012-11-07,2012-09-13
-4h3c,2012-12-19,2012-09-13
-6h38,2018-12-19,2018-07-17
-5h39,2017-01-18,2016-10-21
-1h3u,2003-01-23,2002-09-19
-1h3i,2002-11-11,2002-09-04
-5h35,2017-01-11,2016-10-20
-3h3f,2009-09-15,2009-04-16
-7h3u,2024-04-24,2024-04-04
-6h3w,2019-02-27,2018-07-19
-3h3r,2010-03-02,2009-04-17
-8h3f,2023-10-11,2022-10-08
-7h30,2024-04-24,2024-04-04
-1h3n,2002-09-27,2002-09-11
-4h3e,2012-09-26,2012-09-13
-6h3f,2019-04-10,2018-07-18
-6h36,2018-12-19,2018-07-17
-1h32,2002-11-07,2002-08-21
-4h30,2013-04-24,2012-09-13
-7h3i,2024-04-24,2024-04-04
-7h3o,2024-04-24,2024-04-04
-5h3e,2017-08-30,2016-10-23
-3h3e,2009-07-14,2009-04-16
-8h3r,2023-10-11,2022-10-09
-7h3k,2024-04-24,2024-04-04
-4h3p,2013-02-27,2012-09-14
-5h3o,2017-01-25,2016-10-26
-3h34,2009-12-29,2009-04-15
-6h3x,2019-02-27,2018-07-19
-1h37,2003-08-21,2002-08-24
-7h39,2024-04-24,2024-04-04
-5n1x,2017-05-17,2017-02-06
-6n12,2019-05-01,2018-11-08
-5n1y,2017-02-15,2017-02-06
-4n1i,2014-01-15,2013-10-04
-7n1u,2021-07-07,2021-05-28
-6n1c,2018-12-19,2018-11-08
-4n1z,2014-12-10,2013-10-04
-5n1f,2018-02-28,2017-02-06
-3n1e,2010-07-14,2010-05-15
-5n17,2017-05-31,2017-02-05
-4n14,2014-08-20,2013-10-03
-3n1c,2010-12-08,2010-05-15
-4n12,2014-03-05,2013-10-03
-3n15,2010-08-04,2010-05-15
-5n1o,2018-02-28,2017-02-06
-7n1q,2021-07-07,2021-05-28
-5n10,2017-05-24,2017-02-04
-1n1f,2003-02-04,2002-10-17
-3n1r,2010-06-02,2010-05-16
-5n1t,2018-02-28,2017-02-06
-7n15,2022-03-16,2021-05-27
-6n1x,2019-08-21,2018-11-12
-5n1d,2018-02-28,2017-02-06
-4n1u,2014-04-16,2013-10-04
-5n1p,2018-02-21,2017-02-06
-4n1b,2014-02-19,2013-10-03
-3n1a,2010-08-04,2010-05-15
-5n14,2017-04-12,2017-02-05
-5n1w,2017-03-15,2017-02-06
-7n1r,2022-01-12,2021-05-28
-7n1i,2021-10-13,2021-05-27
-3n17,2010-08-04,2010-05-15
-3n12,2010-08-04,2010-05-15
-3n10,2010-06-23,2010-05-14
-7n1p,2021-07-14,2021-05-28
-3n1t,2010-10-20,2010-05-17
-6n1k,2019-05-22,2018-11-08
-7n1x,2021-07-07,2021-05-28
-7n1w,2021-07-07,2021-05-28
-2n14,2016-01-27,2015-03-20
-4n16,2014-06-18,2013-10-03
-3n1w,2010-08-18,2010-05-17
-5n1k,2018-02-28,2017-02-06
-5n12,2018-05-30,2017-02-04
-6n16,2019-07-31,2018-11-08
-3n1x,2010-10-13,2010-05-17
-7n1s,2022-06-01,2021-05-28
-1n15,1999-06-15,1998-09-04
-3n1l,2010-08-11,2010-05-15
-6n1e,2019-05-01,2018-11-08
-6n10,2019-07-17,2018-11-07
-2n1u,2015-11-25,2015-04-23
-6n13,2018-11-28,2018-11-08
-5n1r,2017-12-27,2017-02-06
-4n1o,2015-08-12,2013-10-04
-6n1s,2019-01-23,2018-11-11
-1n1t,2003-01-07,2002-10-20
-5n1g,2018-02-28,2017-02-06
-4n1m,2015-08-12,2013-10-04
-5n1m,2018-02-28,2017-02-06
-3n14,2010-09-22,2010-05-15
-7n1y,2021-07-07,2021-05-28
-3n1g,2010-06-02,2010-05-15
-1n1i,2003-02-25,2002-10-17
-1n1b,2002-11-27,2002-10-17
-1n1g,2003-10-28,2002-10-17
-6n17,2019-07-03,2018-11-08
-3n1v,2010-08-18,2010-05-17
-5n1z,2017-05-17,2017-02-06
-1n1p,2003-10-28,2002-10-18
-4n1t,2014-04-16,2013-10-04
-3n1q,2010-06-02,2010-05-16
-7n1e,2021-07-28,2021-05-27
-3n1p,2010-06-02,2010-05-16
-5n1u,2017-03-15,2017-02-06
-2n18,2015-05-13,2015-03-24
-4n1p,2015-08-12,2013-10-04
-5n18,2017-05-31,2017-02-05
-7n18,2022-07-06,2021-05-27
-5n1h,2018-02-28,2017-02-06
-1n1l,2003-10-21,2002-10-18
-5n1l,2018-02-28,2017-02-06
-1n18,2002-11-27,2002-10-16
-5n1b,2017-05-24,2017-02-06
-3n1j,2010-08-11,2010-05-15
-6n1y,2019-06-05,2018-11-12
-7n14,2022-02-02,2021-05-26
-4n1n,2015-08-12,2013-10-04
-3n18,2010-08-04,2010-05-15
-6n1t,2019-01-23,2018-11-11
-3n1y,2010-10-13,2010-05-17
-3n1f,2010-06-02,2010-05-15
-6n1d,2019-04-03,2018-11-08
-5n1q,2017-06-14,2017-02-06
-3n1z,2010-10-13,2010-05-17
-7n1b,2021-07-28,2021-05-27
-5n19,2018-02-28,2017-02-05
-7n1a,2021-07-28,2021-05-27
-3n1s,2010-10-20,2010-05-17
-3n19,2010-09-22,2010-05-15
-3n1i,2010-08-11,2010-05-15
-5n16,2017-05-31,2017-02-05
-5n1j,2018-02-21,2017-02-06
-6n1v,2019-07-24,2018-11-12
-4n1s,2015-08-12,2013-10-04
-2n1o,2015-10-28,2015-04-13
-5n11,2017-03-22,2017-02-04
-7n12,2021-10-06,2021-05-26
-4n15,2013-10-16,2013-10-03
-3n1o,2010-06-02,2010-05-16
-4n1a,2015-02-11,2013-10-03
-6n1w,2019-07-24,2018-11-12
-3n1n,2010-07-14,2010-05-16
-7n16,2022-03-16,2021-05-27
-4n17,2013-10-16,2013-10-03
-1n1d,2003-11-11,2002-10-17
-3n1m,2010-06-02,2010-05-15
-7n10,2021-07-28,2021-05-26
-7n1o,2021-06-09,2021-05-27
-1n13,2003-03-25,2002-10-16
-7n13,2021-11-03,2021-05-26
-6n19,2019-07-03,2018-11-08
-4n1q,2015-08-12,2013-10-04
-3n1k,2010-08-11,2010-05-15
-1n19,2002-11-27,2002-10-16
-4n1r,2015-08-12,2013-10-04
-1n1v,2003-01-07,2002-10-21
-5n1v,2017-05-17,2017-02-06
-3n13,2010-08-04,2010-05-15
-7n1t,2021-07-07,2021-05-28
-6n1a,2019-06-12,2018-11-08
-4n1g,2014-02-19,2013-10-04
-3n1u,2010-07-21,2010-05-17
-7n1v,2021-07-07,2021-05-28
-5n1n,2018-02-28,2017-02-06
-3n1d,2010-06-23,2010-05-15
-7n1h,2021-10-13,2021-05-27
-5n1e,2018-02-14,2017-02-06
-6n1b,2019-06-12,2018-11-08
-6n1f,2018-12-19,2018-11-08
-1n1y,2003-01-07,2002-10-21
-7n1f,2021-07-28,2021-05-27
-1n10,2003-01-28,2002-10-16
-1n1z,2002-11-27,2002-10-21
-2n1a,2016-05-04,2015-03-26
-6n1o,2019-10-23,2018-11-09
-1n1e,2003-05-27,2002-10-17
-4n1x,2013-10-30,2013-10-04
-4n1f,2014-02-19,2013-10-04
-7n19,2021-08-18,2021-05-27
-5n1s,2017-12-27,2017-02-06
-1n1m,2002-12-27,2002-10-18
-1n1h,2002-12-25,2002-10-17
-2bch,2006-07-04,2005-10-19
-8bcf,2023-03-08,2022-10-15
-2bcq,2006-03-07,2005-10-19
-2bcr,2006-03-07,2005-10-19
-4bcf,2013-01-09,2012-10-02
-3bcr,2008-11-18,2007-11-13
-8bc0,2022-11-16,2022-10-14
-1bcc,1998-08-19,1998-03-23
-6bck,2018-05-23,2017-10-20
-4bci,2013-01-09,2012-10-02
-2bcx,2006-10-31,2005-10-19
-3bc5,2008-11-18,2007-11-12
-8bce,2023-03-08,2022-10-15
-6bcb,2017-12-13,2017-10-20
-6bcc,2018-02-28,2017-10-20
-2bc1,2006-10-31,2005-10-18
-2bcg,2006-01-17,2005-10-19
-6bca,2017-12-13,2017-10-20
-1bcu,1998-10-14,1998-05-02
-8bcj,2022-11-30,2022-10-16
-3bcs,2008-11-18,2007-11-13
-2bcv,2006-03-07,2005-10-19
-1bcz,1998-11-25,1998-05-04
-4bc6,2012-10-10,2012-10-01
-2bcu,2006-03-07,2005-10-19
-6bcm,2017-11-08,2017-10-20
-1bc2,1998-10-14,1997-04-11
-8bc4,2023-01-18,2022-10-14
-8bc5,2023-07-12,2022-10-15
-6bc2,2018-02-28,2017-10-20
-1bcd,1993-10-31,1993-08-31
-4bcb,2013-03-13,2012-10-01
-8bc3,2023-01-18,2022-10-14
-7bcn,2021-04-14,2020-12-21
-7bc2,2021-10-20,2020-12-18
-4bcn,2013-03-06,2012-10-02
-7bcc,2022-01-12,2020-12-19
-7bcu,2021-07-28,2020-12-21
-1bcf,1994-12-20,1993-12-06
-8bc6,2023-01-11,2022-10-15
-8bcg,2023-03-08,2022-10-15
-8bch,2023-03-08,2022-10-15
-8bcd,2023-03-08,2022-10-15
-8bcx,2023-08-30,2022-10-17
-4bc4,2012-11-28,2012-10-01
-7bc8,2022-01-12,2020-12-18
-4bcw,2013-02-06,2012-10-03
-8bcv,2023-11-01,2022-10-17
-7bcx,2021-07-28,2020-12-21
-3bcc,1998-08-19,1998-03-23
-1bcp,1997-06-05,1995-11-21
-8bck,2023-07-12,2022-10-16
-7bcf,2022-01-12,2020-12-19
-4bcg,2013-04-17,2012-10-02
-7bcs,2021-09-22,2020-12-21
-8bc1,2022-11-16,2022-10-14
-1bck,1998-09-16,1998-04-30
-4bch,2013-01-09,2012-10-02
-8bcr,2023-03-22,2022-10-17
-3bcx,2007-11-27,2007-11-13
-4bcj,2013-01-09,2012-10-02
-2bcp,2006-10-31,2005-10-19
-3bc1,2008-09-02,2007-11-12
-4bcc,2013-03-13,2012-10-01
-1bc5,1998-11-25,1998-05-05
-3bcd,2008-04-22,2007-11-12
-4bcp,2013-04-17,2012-10-02
-7bck,2022-01-12,2020-12-19
-1bch,1998-06-17,1998-04-30
-6bcz,2017-12-13,2017-10-20
-4bcm,2013-03-06,2012-10-02
-7bcw,2022-01-12,2020-12-21
-1bcw,1998-11-25,1998-05-04
-1bc8,1998-12-01,1998-05-05
-4bc7,2012-11-07,2012-10-01
-8bcc,2023-03-08,2022-10-15
-6bc3,2018-02-28,2017-10-20
-6bcn,2018-10-24,2017-10-20
-7bci,2022-01-12,2020-12-19
-6bcj,2017-12-13,2017-10-20
-8bc7,2023-01-11,2022-10-15
-2bcd,2006-01-17,2005-10-19
-4bcs,2013-10-16,2012-10-03
-8bcw,2023-11-01,2022-10-17
-6bcu,2017-12-20,2017-10-20
-6bce,2018-10-24,2017-10-20
-4bc5,2012-11-28,2012-10-01
-1bcy,1998-11-25,1998-05-04
-4bcy,2013-02-27,2012-10-03
-7bcm,2021-03-03,2020-12-20
-6bci,2018-10-24,2017-10-20
-3bcu,2008-11-18,2007-11-13
-3bcq,2008-10-07,2007-11-13
-2bcs,2006-03-07,2005-10-19
-2bcc,1999-08-02,1998-09-18
-4bcx,2013-07-10,2012-10-03
-3bc2,1999-04-20,1997-09-09
-1bc1,1998-11-25,1998-05-04
-3bc3,2008-03-18,2007-11-12
-6bct,2018-10-24,2017-10-20
-8bcb,2023-03-08,2022-10-15
-7bc1,2022-01-12,2020-12-18
-1bcx,1994-10-15,1994-04-01
-2bcn,2006-02-28,2005-10-19
-7bch,2022-01-12,2020-12-19
-2bcj,2005-12-20,2005-10-19
-4bcu,2013-01-23,2012-10-03
-7bcz,2021-11-10,2020-12-21
-3bce,2008-02-12,2007-11-12
-2bc5,2006-09-26,2005-10-18
-6bcx,2017-12-20,2017-10-20
-4bc0,2013-02-06,2012-09-30
-6bcq,2017-12-13,2017-10-20
-6bcg,2018-10-24,2017-10-20
-7bc4,2021-05-19,2020-12-18
-1bcr,1996-03-08,1995-11-03
-2bc4,2006-05-23,2005-10-18
-6bcr,2018-10-24,2017-10-20
-8bc8,2023-03-08,2022-10-15
-7bc9,2022-01-12,2020-12-18
-8bcy,2023-05-10,2022-10-17
-7bcl,2022-01-12,2020-12-19
-4bc2,2012-11-28,2012-10-01
-4bcd,2013-03-13,2012-10-01
-6bc9,2018-02-28,2017-10-20
-6bc5,2018-02-28,2017-10-20
-1bc3,1998-11-25,1998-05-04
-4bcr,2013-05-29,2012-10-02
-2bck,2006-01-10,2005-10-19
-6bcy,2018-10-24,2017-10-20
-2bco,2005-10-25,2005-10-19
-6bc6,2018-02-28,2017-10-20
-7bco,2021-04-07,2020-12-21
-6bc7,2018-02-28,2017-10-20
-4bcl,1998-09-16,1998-04-17
-6bcf,2018-10-24,2017-10-20
-9bcz,2024-05-15,2024-04-10
-1bci,1998-11-25,1998-04-30
-2bc9,2006-03-07,2005-10-19
-8bc9,2023-03-08,2022-10-15
-2bc2,1999-04-20,1997-09-09
-3bc4,2008-09-02,2007-11-12
-4bca,2012-11-07,2012-10-01
-4bco,2013-01-09,2012-10-02
-6bco,2017-12-13,2017-10-20
-7bc7,2021-05-12,2020-12-18
-6bc0,2017-12-13,2017-10-20
-7bcd,2022-01-12,2020-12-19
-8bca,2023-03-08,2022-10-15
-1bc0,1998-11-25,1998-05-04
-7bcp,2021-04-07,2020-12-21
-6bcl,2017-12-13,2017-10-20
-7bcq,2021-09-22,2020-12-21
-4bc1,2013-02-06,2012-09-30
-2bc0,2006-10-31,2005-10-18
-6bc4,2018-02-28,2017-10-20
-1bcj,1998-06-17,1998-04-30
-7bcr,2021-04-07,2020-12-21
-4bc9,2012-11-07,2012-10-01
-3bcf,2008-04-22,2007-11-12
-6bc1,2017-12-13,2017-10-20
-3bcj,2008-04-08,2007-11-13
-1bcs,1996-03-08,1995-11-03
-3bc9,2008-04-22,2007-11-12
-3bcn,2007-11-27,2007-11-13
-5bca,2000-03-15,1999-03-12
-4bck,2013-03-06,2012-10-02
-4bcq,2013-01-09,2012-10-02
-7vpl,2021-12-29,2021-10-17
-2vp0,2008-04-29,2008-02-26
-6vph,2020-08-05,2020-02-03
-2vpx,2008-06-10,2008-03-09
-7vpk,2021-12-29,2021-10-17
-7vpq,2022-03-16,2021-10-17
-5vpm,2017-10-18,2017-05-05
-1vp3,1997-09-17,1996-11-21
-5vpx,2018-04-11,2017-05-06
-3vpd,2013-02-27,2012-02-29
-2vpe,2008-06-17,2008-02-27
-3vpo,2013-03-06,2012-03-05
-2vpy,2008-06-10,2008-03-09
-1vph,2004-11-16,2004-11-03
-2vpo,2008-08-26,2008-03-03
-1vpo,2004-11-23,2004-11-15
-5vp2,2017-06-28,2017-05-04
-2vpq,2008-09-09,2008-03-03
-5vpc,2017-09-06,2017-05-04
-3vpq,2013-03-06,2012-03-08
-3vpk,2012-05-23,2012-03-05
-2vpb,2008-06-17,2008-02-27
-5vpn,2017-06-21,2017-05-05
-1vpp,1999-02-23,1998-10-09
-7vp8,2022-08-24,2021-10-15
-5vpo,2018-09-26,2017-05-05
-2vpr,2008-03-11,2008-03-03
-6vpj,2020-08-05,2020-02-03
-3vpn,2013-03-06,2012-03-05
-5vph,2017-05-24,2017-05-05
-3vpe,2013-02-13,2012-02-29
-6vpq,2020-04-08,2020-02-04
-6vpp,2020-02-19,2020-02-04
-3vp4,2012-06-13,2012-02-23
-7vpi,2021-12-29,2021-10-17
-1vp4,2004-10-26,2004-10-08
-5vp3,2018-05-09,2017-05-04
-2vp1,2008-03-25,2008-02-26
-3vpb,2013-02-27,2012-02-29
-3vpc,2013-02-27,2012-02-29
-2vp4,2008-04-29,2008-02-26
-2vp5,2008-04-18,2008-02-26
-5vpk,2017-05-24,2017-05-05
-6vpo,2020-02-19,2020-02-04
-7vpu,2022-08-24,2021-10-18
-7vpj,2021-12-29,2021-10-17
-3vp6,2013-01-16,2012-02-27
-1vpa,2004-11-02,2004-10-14
-6vp9,2020-09-23,2020-02-02
-2vpn,2008-08-26,2008-03-03
-3vps,2012-04-18,2012-03-12
-6vpr,2020-04-08,2020-02-04
-5vpa,2017-09-06,2017-05-04
-5vpf,2017-09-06,2017-05-04
-1vp6,2004-10-26,2004-10-14
-2vpa,2008-08-19,2008-02-27
-2vp7,2008-06-17,2008-02-26
-5vp9,2017-06-21,2017-05-04
-2vpd,2008-06-17,2008-02-27
-6vpv,2021-08-04,2020-02-04
-6vp6,2020-08-26,2020-02-01
-7vpd,2022-08-03,2021-10-15
-6vp4,2021-02-03,2020-02-01
-6vpx,2020-04-22,2020-02-04
-6vp0,2020-05-13,2020-02-01
-2vp9,2008-04-29,2008-02-27
-2vpp,2009-03-24,2008-03-03
-3vp5,2012-07-25,2012-02-23
-7vpp,2022-03-16,2021-10-17
-7vpn,2022-03-30,2021-10-17
-5vpd,2017-09-06,2017-05-04
-1vpt,1996-08-17,1996-03-20
-5vp8,2018-04-11,2017-05-04
-2vpl,2008-09-23,2008-03-01
-1vpy,2004-12-07,2004-11-23
-5vpp,2018-09-26,2017-05-05
-7vpb,2022-10-19,2021-10-15
-1vpm,2004-12-14,2004-11-11
-1vp5,2004-10-26,2004-10-13
-6vpl,2020-08-05,2020-02-03
-7vp9,2022-06-08,2021-10-15
-5vp7,2017-12-06,2017-05-04
-7vpz,2022-08-03,2021-10-18
-1vpw,1998-06-17,1998-02-27
-2vpt,2008-05-06,2008-03-04
-5vpi,2017-12-06,2017-05-05
-6vp5,2021-02-03,2020-02-01
-3vp3,2012-06-13,2012-02-23
-6vpi,2020-08-05,2020-02-03
-5vpy,2017-12-06,2017-05-06
-7vpf,2021-12-29,2021-10-16
-2vpw,2008-06-10,2008-03-09
-2vpg,2008-06-17,2008-02-27
-2vp2,2008-04-29,2008-02-26
-7vpx,2023-05-03,2021-10-18
-5vpz,2017-12-06,2017-05-06
-7vph,2022-01-19,2021-10-17
-3vpm,2013-03-06,2012-03-05
-1vp9,1997-09-17,1996-11-23
-1vpe,1998-06-17,1997-05-06
-7vpe,2022-10-19,2021-10-16
-6vpf,2020-09-16,2020-02-03
-3vph,2013-03-06,2012-03-01
-5vpl,2017-05-24,2017-05-05
-6vpb,2020-07-22,2020-02-02
-3vp1,2012-06-13,2012-02-23
-5vpu,2017-05-24,2017-05-05
-5vpe,2017-09-06,2017-05-04
-7vpr,2022-09-07,2021-10-17
-3vp2,2012-06-13,2012-02-23
-3vpl,2013-03-06,2012-03-05
-2vp3,1997-09-17,1996-12-16
-5vp0,2017-08-23,2017-05-03
-3vpp,2012-04-25,2012-03-07
-7vpw,2022-04-20,2021-10-18
-1vps,1997-05-15,1997-03-07
-6vpm,2020-08-05,2020-02-03
-6vpc,2020-07-29,2020-02-03
-2vp6,2008-04-29,2008-02-26
-5vp5,2017-05-17,2017-05-04
-2vpz,2008-06-10,2008-03-09
-5vp1,2017-12-27,2017-05-03
-5vpt,2018-04-11,2017-05-05
-3vp0,2012-06-13,2012-02-23
-5vps,2017-05-24,2017-05-05
-7vp0,2022-08-31,2021-10-15
-5vpg,2017-05-24,2017-05-05
-1vp8,2004-10-26,2004-10-14
-6vpg,2020-08-05,2020-02-03
-4uzh,2014-11-19,2014-09-05
-1uzk,2006-05-24,2004-03-13
-1uzv,2004-12-08,2004-03-17
-3uzo,2012-12-12,2011-12-07
-7uzb,2022-12-07,2022-05-08
-4uz3,2015-01-14,2014-09-04
-6uzm,2020-11-18,2019-11-15
-8uz5,2024-03-06,2023-11-14
-2uzs,2007-07-17,2007-05-01
-7uzc,2023-01-11,2022-05-08
-6uzi,2020-01-15,2019-11-15
-8uzu,2024-04-03,2023-11-16
-2uzv,2007-06-05,2007-05-01
-2uzl,2007-06-26,2007-04-30
-3uza,2012-03-21,2011-12-07
-7uz5,2022-12-07,2022-05-08
-3uzb,2012-12-12,2011-12-07
-2uz9,2007-05-08,2007-04-26
-8uzd,2024-01-10,2023-11-14
-7uz9,2022-12-07,2022-05-08
-5uzh,2017-04-05,2017-02-26
-7uzg,2023-11-22,2022-05-09
-6uz8,2020-03-18,2019-11-14
-2uz0,2007-10-23,2007-04-23
-1uzl,2005-03-23,2004-03-14
-2uzd,2007-06-26,2007-04-27
-8uzn,2023-12-06,2023-11-15
-6uzx,2020-01-29,2019-11-15
-6uz6,2020-01-29,2019-11-14
-2uzp,2007-05-29,2007-04-30
-8uz1,2024-01-31,2023-11-14
-2uze,2007-06-26,2007-04-27
-1uzy,2004-06-22,2004-03-19
-7uzx,2022-07-06,2022-05-09
-2uzo,2007-06-26,2007-04-30
-2uzh,2007-11-06,2007-04-27
-2uzb,2007-06-26,2007-04-27
-6uz1,2020-10-28,2019-11-14
-2uz1,2007-07-24,2007-04-23
-1uz0,2004-03-11,2004-03-03
-3uzy,2012-03-21,2011-12-07
-3uz5,2012-06-06,2011-12-07
-7uze,2022-07-20,2022-05-09
-6uzn,2020-11-18,2019-11-15
-3uzs,2012-07-11,2011-12-07
-2uzg,2007-05-08,2007-04-27
-4uz1,2015-02-25,2014-09-04
-3uzc,2012-03-21,2011-12-07
-7uzr,2023-05-10,2022-05-09
-7uzq,2022-07-20,2022-05-09
-2uzi,2007-06-26,2007-04-27
-7uz4,2022-12-07,2022-05-08
-4uzv,2014-09-17,2014-09-09
-6uzq,2020-11-18,2019-11-15
-2uz4,2008-06-03,2007-04-25
-3uzt,2012-07-11,2011-12-07
-7uzj,2023-11-22,2022-05-09
-6uz7,2020-01-15,2019-11-14
-4uzj,2015-02-25,2014-09-05
-2uzz,2008-01-22,2007-05-03
-6uz3,2020-01-01,2019-11-14
-1uz4,2004-11-03,2004-03-04
-7uzf,2023-11-22,2022-05-09
-3uzj,2012-06-06,2011-12-07
-4uzi,2015-01-14,2014-09-05
-2uzw,2007-06-05,2007-05-01
-5uzv,2017-05-24,2017-02-27
-8uzh,2024-03-27,2023-11-15
-7uz7,2022-12-07,2022-05-08
-6uzw,2020-01-29,2019-11-15
-1uzf,2004-07-16,2004-03-11
-6uzr,2020-01-29,2019-11-15
-5uzj,2018-03-07,2017-02-26
-1uzd,2005-05-31,2004-03-11
-2uza,2008-05-20,2007-04-27
-6uze,2020-03-04,2019-11-15
-1uzn,2005-03-23,2004-03-14
-8uz6,2024-03-06,2023-11-14
-5uzu,2017-07-26,2017-02-27
-7uz2,2023-04-05,2022-05-08
-5uz0,2018-01-10,2017-02-24
-1uzj,2004-04-08,2004-03-12
-3uzr,2011-12-21,2011-12-07
-6uzv,2020-09-16,2019-11-15
-3uzz,2012-03-21,2011-12-07
-7uz1,2023-04-05,2022-05-08
-4uz5,2015-02-25,2014-09-04
-2uzn,2007-06-26,2007-04-30
-8uzm,2023-12-06,2023-11-15
-7uzo,2022-10-19,2022-05-09
-5uz4,2017-04-19,2017-02-24
-1uzp,2004-04-08,2004-03-15
-1uzu,2004-05-27,2004-03-16
-8uzx,2024-03-06,2023-11-16
-2uzt,2007-06-05,2007-05-01
-1uz1,2004-11-23,2004-03-03
-1uzr,2004-07-08,2004-03-15
-8uzk,2023-12-06,2023-11-15
-8uzo,2023-12-06,2023-11-15
-7uz6,2022-12-07,2022-05-08
-1uzm,2005-03-23,2004-03-14
-5uzp,2018-03-07,2017-02-27
-8uzj,2024-02-21,2023-11-15
-1uze,2004-07-16,2004-03-11
-5uzx,2017-03-15,2017-02-27
-5uzs,2017-03-22,2017-02-27
-1uzh,2005-05-31,2004-03-12
-6uzs,2020-11-18,2019-11-15
-5uzc,2017-03-22,2017-02-26
-6uzz,2019-12-04,2019-11-16
-1uz8,2004-06-29,2004-03-05
-7uzn,2022-08-17,2022-05-09
-7uz3,2022-07-20,2022-05-08
-4uzq,2015-02-25,2014-09-07
-7uzk,2023-11-22,2022-05-09
-1uz9,2005-03-03,2004-03-08
-2uzu,2007-06-05,2007-05-01
-5uze,2017-03-22,2017-02-26
-5uzw,2017-05-31,2017-02-27
-5uzk,2018-03-07,2017-02-26
-6uzu,2020-10-21,2019-11-15
-3uzd,2012-03-21,2011-12-07
-3uzx,2012-03-21,2011-12-07
-2uz2,2008-06-03,2007-04-24
-6uzk,2020-11-18,2019-11-15
-4uzl,2015-02-25,2014-09-05
-1uzz,2004-06-22,2004-03-20
-6uz0,2020-01-01,2019-11-14
-1uzg,2005-03-15,2004-03-11
-2uz6,2007-08-07,2007-04-25
-8uz0,2024-01-31,2023-11-14
-8uz7,2023-12-06,2023-11-14
-4uzk,2015-02-25,2014-09-05
-2uzf,2007-11-13,2007-04-27
-6uzp,2020-11-18,2019-11-15
-4uzu,2015-01-14,2014-09-09
-7uzi,2023-11-22,2022-05-09
-7uza,2022-12-07,2022-05-08
-7uz8,2022-12-07,2022-05-08
-7uzh,2023-11-22,2022-05-09
-6uzd,2020-03-04,2019-11-14
-3uzw,2012-03-21,2011-12-07
-3uzp,2012-01-11,2011-12-07
-6uzb,2020-03-04,2019-11-14
-7uzp,2022-10-19,2022-05-09
-8uzy,2024-03-06,2023-11-16
-2uz3,2007-05-29,2007-04-24
-7uzd,2023-01-11,2022-05-08
-6uza,2020-03-18,2019-11-14
-4uzd,2014-11-19,2014-09-05
-4uza,2015-02-25,2014-09-04
-1uzw,2004-06-10,2004-03-17
-6uzo,2020-11-18,2019-11-15
-2uzj,2009-09-08,2008-09-16
-8uz8,2023-12-06,2023-11-14
-5uz8,2018-02-28,2017-02-25
-6uzg,2020-01-29,2019-11-15
-4uzg,2015-05-13,2014-09-05
-1uza,2004-10-19,2004-03-05
-4alb,2012-08-22,2012-03-02
-7ale,2022-04-20,2020-10-06
-2al1,2006-01-24,2005-08-04
-6alc,2018-08-08,2017-08-07
-1ala,1993-10-31,1993-01-14
-1aln,1997-09-17,1997-06-02
-4alw,2013-01-16,2012-03-05
-5alz,2015-05-13,2015-03-08
-3al0,2010-09-29,2010-07-19
-1al7,1997-11-12,1997-06-12
-5alg,2015-05-13,2015-03-08
-7alb,2021-10-13,2020-10-06
-5al2,2015-07-29,2015-03-06
-7all,2021-10-13,2020-10-06
-5ala,2015-05-20,2015-03-07
-4alp,2012-09-05,2012-03-05
-1ali,1995-11-14,1995-06-02
-8alh,2023-12-13,2022-08-01
-7al7,2022-04-20,2020-10-05
-4alx,2012-08-29,2012-03-06
-3alq,2010-11-17,2010-08-06
-8alm,2023-12-13,2022-08-01
-6alp,2017-09-06,2017-08-08
-7alc,2021-10-13,2020-10-06
-3alg,2011-03-23,2010-08-03
-5al8,2015-10-21,2015-03-06
-2alz,2005-10-25,2005-08-08
-8alk,2023-04-12,2022-08-01
-5als,2015-05-13,2015-03-08
-4alu,2013-01-16,2012-03-05
-6alm,2017-09-06,2017-08-08
-7alz,2021-08-04,2020-10-07
-5ald,2015-05-13,2015-03-08
-5alv,2015-05-13,2015-03-08
-3alr,2011-02-02,2010-08-06
-2alm,2005-08-30,2005-08-07
-5alu,2015-05-13,2015-03-08
-7aln,2021-04-28,2020-10-06
-6alh,2017-08-16,2017-08-07
-1al4,1998-03-04,1997-06-11
-8all,2023-03-22,2022-08-01
-4alg,2012-07-04,2012-03-03
-4all,2012-05-09,2012-03-04
-5alo,2015-05-13,2015-03-08
-8alt,2023-09-20,2022-08-01
-4ale,2013-02-27,2012-03-02
-8aly,2022-11-16,2022-08-01
-6al8,2018-03-07,2017-08-07
-5alt,2015-05-13,2015-03-08
-5alq,2015-05-13,2015-03-08
-7aly,2021-10-20,2020-10-07
-5alm,2015-05-13,2015-03-08
-3al8,2010-10-06,2010-07-28
-2alv,2006-08-08,2005-08-08
-5alh,2015-05-13,2015-03-08
-3alz,2011-01-12,2010-08-11
-3al4,2010-08-04,2010-07-22
-4al1,2013-02-06,2012-02-29
-3als,2011-01-19,2010-08-07
-1alj,1995-11-14,1995-06-02
-6ale,2018-08-08,2017-08-07
-1alz,1998-03-04,1997-06-06
-1al8,1997-09-17,1997-06-12
-3aln,2010-10-27,2010-08-04
-3alw,2011-01-12,2010-08-09
-5alj,2015-05-13,2015-03-08
-5al5,2015-07-29,2015-03-06
-4al4,2012-03-21,2012-03-01
-4alk,2012-05-09,2012-03-04
-2alf,2005-08-23,2005-08-05
-7alp,2021-04-21,2020-10-07
-8aln,2022-12-14,2022-08-01
-5alp,2015-05-13,2015-03-08
-7alj,2021-08-04,2020-10-06
-7alk,2021-08-04,2020-10-06
-6ald,2000-01-05,1998-12-23
-5ali,2015-05-13,2015-03-08
-4al9,2013-03-20,2012-03-02
-1alh,1995-02-27,1994-08-23
-2alw,2006-07-04,2005-08-08
-4alv,2013-01-16,2012-03-05
-5alc,2015-04-01,2015-03-07
-6alr,2017-09-06,2017-08-08
-4alj,2012-05-09,2012-03-04
-1al1,1991-10-15,1990-07-02
-5al1,2015-07-29,2015-03-06
-2all,2006-07-18,2005-08-05
-6ala,2018-07-18,2017-08-07
-7al8,2021-10-13,2020-10-05
-3alu,2011-01-19,2010-08-07
-8als,2022-11-02,2022-08-01
-7alq,2021-10-20,2020-10-07
-5al0,2015-10-21,2015-03-05
-3alo,2010-10-27,2010-08-04
-4alf,2013-03-13,2012-03-02
-4al2,2012-04-04,2012-02-29
-2alx,2005-11-29,2005-08-08
-3alt,2011-01-19,2010-08-07
-5alr,2015-05-13,2015-03-08
-6alz,2017-11-29,2017-08-08
-7alv,2021-10-20,2020-10-07
-5alx,2015-05-13,2015-03-08
-2al0,2006-07-18,2005-08-04
-3alc,2000-05-15,1999-03-11
-6alq,2017-09-06,2017-08-08
-7al4,2020-12-30,2020-10-05
-1alk,1994-01-31,1993-03-03
-1alx,1998-03-04,1997-06-05
-7alr,2021-03-03,2020-10-07
-4al0,2013-02-06,2012-02-29
-5alb,2015-04-01,2015-03-07
-4ald,1999-03-02,1998-07-26
-4al3,2012-04-04,2012-02-29
-5alk,2015-05-13,2015-03-08
-6alb,2018-10-17,2017-08-07
-3ala,2010-12-15,2010-07-29
-8alr,2023-09-20,2022-08-01
-6alv,2018-07-18,2017-08-08
-7alx,2021-07-14,2020-10-07
-4als,2013-02-27,2012-03-05
-1al6,1997-12-24,1997-06-12
-7als,2021-11-03,2020-10-07
-1al2,1997-11-19,1997-06-09
-8ali,2023-08-16,2022-08-01
-1alc,1989-10-15,1989-08-14
-2al4,2005-10-25,2005-08-04
-6alj,2018-01-10,2017-08-08
-2al2,2006-01-24,2005-08-04
-8alw,2023-09-20,2022-08-01
-2aly,2005-12-27,2005-08-04
-7ala,2021-10-13,2020-10-06
-6aln,2017-09-06,2017-08-08
-6alg,2017-08-16,2017-08-07
-8alj,2023-08-16,2022-08-01
-8alv,2023-09-20,2022-08-01
-5aln,2015-05-13,2015-03-08
-7alo,2021-06-16,2020-10-07
-2al7,2005-08-23,2005-08-04
-6al9,2018-11-07,2017-08-07
-1alw,1998-06-10,1997-06-04
-5aly,2015-05-13,2015-03-08
-6al7,2018-03-07,2017-08-07
-6al5,2018-03-28,2017-08-07
-7alt,2021-08-04,2020-10-07
-3alj,2011-08-10,2010-08-04
-4alh,2012-04-11,2012-03-03
-4alc,2013-02-27,2012-03-02
-6alf,2017-08-16,2017-08-07
-5al9,2015-05-20,2015-03-07
-8alz,2023-03-08,2022-08-01
-2ale,2006-10-03,2005-08-05
-4ali,2012-05-09,2012-03-04
-5ale,2015-05-13,2015-03-08
-1all,1996-07-11,1995-03-01
-5alw,2015-05-13,2015-03-08
-3alx,2011-01-12,2010-08-09
-1alv,1998-06-03,1997-06-03
-7al9,2021-10-13,2020-10-06
-5alf,2015-05-13,2015-03-08
-2al5,2005-10-25,2005-08-04
-3all,2011-08-10,2010-08-04
-2alu,2005-09-20,2005-08-08
-3al5,2010-11-24,2010-07-26
-4alt,2013-02-27,2012-03-05
-4alo,2012-08-08,2012-03-05
-5al4,2015-07-29,2015-03-06
-6alo,2017-09-06,2017-08-08
-3alm,2011-08-10,2010-08-04
-8alx,2023-08-16,2022-08-01
-5all,2015-05-13,2015-03-08
-6alw,2018-11-21,2017-08-08
-4alr,2013-02-27,2012-03-05
-5al6,2015-06-03,2015-03-06
-5al3,2015-07-29,2015-03-06
-6al6,2018-03-07,2017-08-07
-3al6,2010-12-01,2010-07-26
-3al9,2010-10-06,2010-07-28
-2alc,2000-01-21,1999-01-20
-4alq,2013-02-27,2012-03-05
-5zwn,2018-08-29,2018-05-16
-5zwi,2018-07-18,2018-05-15
-6zw2,2021-08-11,2020-07-27
-5zwp,2018-06-13,2018-05-16
-2zw9,2009-06-02,2008-12-01
-2zw4,2009-11-03,2008-12-01
-7zw0,2022-10-05,2022-05-17
-7zwi,2022-06-22,2022-05-19
-6zwm,2020-11-18,2020-07-28
-7zwe,2023-05-31,2022-05-19
-4zwx,2015-10-28,2015-05-19
-7zwt,2022-11-16,2022-05-19
-3zwk,2011-10-19,2011-08-01
-2zw7,2009-11-03,2008-12-01
-7zw7,2023-05-31,2022-05-19
-4zwn,2016-04-27,2015-05-19
-7zwo,2022-11-16,2022-05-19
-7zwp,2022-11-16,2022-05-19
-3zwn,2011-11-30,2011-08-02
-4zwm,2015-06-03,2015-05-19
-6zwk,2021-07-21,2020-07-28
-5zwb,2019-05-29,2018-05-14
-3zw3,2011-09-28,2011-07-28
-1zwn,2006-10-17,2005-06-03
-5zw7,2018-09-05,2018-05-14
-5zwr,2019-03-13,2018-05-16
-7zwv,2022-11-16,2022-05-19
-3zwe,2011-12-21,2011-07-29
-2zwe,2009-12-15,2008-12-03
-2zwz,2009-12-08,2008-12-19
-6zwc,2020-12-23,2020-07-28
-2zwr,2009-10-06,2008-12-17
-7zwm,2022-06-22,2022-05-19
-5zw8,2018-09-05,2018-05-14
-5zwe,2018-07-18,2018-05-15
-4zw1,2016-06-22,2015-05-19
-1zwp,2005-07-26,2005-06-04
-2zwn,2009-04-07,2008-12-17
-7zwk,2023-03-22,2022-05-19
-1zww,2005-08-02,2005-06-06
-2zwo,2009-06-23,2008-12-17
-6zwi,2021-06-09,2020-07-28
-4zw6,2016-03-30,2015-05-19
-4zwy,2015-08-05,2015-05-19
-1zwi,2006-03-07,2005-06-03
-7zwh,2022-07-13,2022-05-19
-7zw8,2023-02-22,2022-05-19
-5zwf,2018-07-18,2018-05-15
-6zw8,2021-06-09,2020-07-27
-3zww,2011-11-30,2011-08-03
-6zw1,2021-08-04,2020-07-27
-1zwl,2005-06-14,2005-06-03
-5zwm,2018-08-29,2018-05-16
-3zw1,2011-11-16,2011-07-28
-4zw5,2016-03-30,2015-05-19
-2zwp,2009-06-23,2008-12-17
-6zwb,2020-12-23,2020-07-28
-2zwj,2009-01-13,2008-12-13
-1zw1,2006-06-06,2005-06-03
-7zwd,2022-11-30,2022-05-19
-2zwf,2009-12-15,2008-12-03
-7zwb,2023-05-31,2022-05-19
-3zwh,2012-04-04,2011-07-31
-5zwj,2018-07-25,2018-05-15
-7zwn,2022-11-16,2022-05-19
-4zw8,2016-03-30,2015-05-19
-4zwe,2015-09-02,2015-05-19
-5zw4,2018-07-11,2018-05-14
-3zwd,2011-10-19,2011-07-28
-4zw7,2016-03-30,2015-05-19
-2zwu,2009-02-17,2008-12-18
-1zw9,2006-06-13,2005-06-03
-2zw5,2009-11-03,2008-12-01
-1zw8,2006-01-10,2005-06-03
-5zwk,2019-05-15,2018-05-15
-2zwg,2009-12-15,2008-12-03
-6zwv,2020-08-05,2020-07-28
-7zwu,2022-11-16,2022-05-19
-3zw0,2011-12-21,2011-07-28
-5zw2,2018-09-05,2018-05-14
-6zwp,2020-08-12,2020-07-28
-7zw5,2023-05-31,2022-05-18
-3zw9,2012-08-08,2011-07-28
-1zwh,2006-06-13,2005-06-03
-1zw6,2006-03-14,2005-06-03
-3zwp,2011-11-30,2011-08-02
-3zws,2012-06-27,2011-08-02
-3zw7,2011-10-19,2011-07-28
-1zw5,2005-06-28,2005-06-03
-5zw3,2018-07-11,2018-05-14
-2zwv,2009-12-22,2008-12-18
-5zwy,2019-05-22,2018-05-17
-4zwl,2015-05-27,2015-05-19
-2zwd,2009-12-15,2008-12-03
-7zws,2022-11-16,2022-05-19
-4zwb,2015-07-22,2015-05-19
-6zw0,2021-06-09,2020-07-27
-6zwy,2022-02-23,2020-07-29
-4zwp,2015-10-14,2015-05-19
-5zwh,2018-07-18,2018-05-15
-6zwr,2020-08-12,2020-07-28
-5zwa,2019-05-29,2018-05-14
-3zwc,2012-08-08,2011-07-28
-3zw2,2011-11-16,2011-07-28
-5zw6,2018-09-05,2018-05-14
-3zwi,2012-08-08,2011-07-31
-6zwo,2020-11-18,2020-07-28
-4zw3,2016-03-30,2015-05-19
-7zwq,2022-11-16,2022-05-19
-7zwc,2022-11-30,2022-05-19
-7zww,2022-11-16,2022-05-19
-4zwz,2015-08-05,2015-05-19
-4zwu,2015-10-14,2015-05-19
-2zwt,2009-02-17,2008-12-18
-7zwz,2022-11-16,2022-05-19
-7zwg,2023-05-31,2022-05-19
-3zwt,2012-06-27,2011-08-02
-3zwx,2012-08-22,2011-08-03
-7zwx,2022-11-16,2022-05-19
-4zw9,2015-07-22,2015-05-19
-7zwy,2022-11-16,2022-05-19
-6zwe,2021-06-09,2020-07-28
-4zwi,2015-08-26,2015-05-19
-7zwf,2022-06-22,2022-05-19
-3zwo,2011-11-30,2011-08-02
-4zwo,2015-10-14,2015-05-19
-2zwi,2009-06-09,2008-12-05
-2zwl,2009-01-20,2008-12-16
-3zwv,2011-11-30,2011-08-03
-5zwq,2019-03-13,2018-05-16
-4zwg,2015-09-02,2015-05-19
-4zwc,2015-07-22,2015-05-19
-6zww,2021-06-30,2020-07-29
-3zwu,2012-08-08,2011-08-02
-7zw9,2022-09-07,2022-05-19
-3zwf,2011-08-10,2011-07-29
-2zwa,2009-06-02,2008-12-01
-1zwj,2005-06-14,2005-06-03
-5zw9,2019-05-29,2018-05-14
-7zwr,2022-11-16,2022-05-19
-7zw3,2023-03-29,2022-05-18
-2zws,2009-03-03,2008-12-17
-3zwy,2012-08-22,2011-08-03
-5zwo,2018-08-29,2018-05-16
-7zwl,2023-11-29,2022-05-19
-3zwm,2011-11-30,2011-08-02
-2zwh,2009-01-20,2008-12-05
-4a7n,2012-08-01,2011-11-14
-4a7a,2012-04-25,2011-11-11
-8a7l,2023-05-31,2022-06-21
-2a7a,2005-07-19,2005-07-05
-1a7x,1998-06-17,1998-03-18
-6a7i,2019-01-16,2018-07-03
-8a7u,2023-05-31,2022-06-21
-2a74,2005-09-27,2005-07-04
-4a7s,2012-12-05,2011-11-14
-4a7y,2012-03-21,2011-11-15
-1a7w,1999-03-23,1998-03-18
-5a7o,2016-01-13,2015-07-09
-3a7z,2010-09-29,2009-10-05
-4a7j,2012-01-11,2011-11-14
-5a79,2015-09-02,2015-07-03
-6a72,2019-04-03,2018-07-01
-4a7q,2012-10-24,2011-11-14
-5a7e,2016-05-25,2015-07-03
-5a7x,2015-08-05,2015-07-10
-2a7l,2005-09-06,2005-07-05
-2a7c,2005-07-19,2005-07-05
-7a74,2021-05-19,2020-08-27
-7a73,2021-10-06,2020-08-27
-7a7a,2021-01-27,2020-08-27
-6a71,2019-04-03,2018-06-30
-3a7r,2010-01-19,2009-10-01
-3a75,2010-03-09,2009-09-14
-4a7k,2012-03-21,2011-11-14
-2a7p,2006-07-11,2005-07-05
-3a7e,2010-09-15,2009-09-26
-4a7i,2012-02-01,2011-11-14
-5a7q,2016-01-13,2015-07-09
-3a74,2010-09-22,2009-09-13
-5a71,2015-10-21,2015-07-02
-3a70,2010-05-26,2009-09-10
-2a7f,2005-07-19,2005-07-05
-6a7p,2018-10-24,2018-07-03
-3a78,2010-10-13,2009-09-18
-4a78,2012-11-07,2011-11-11
-4a7z,2012-03-21,2011-11-15
-1a79,1999-06-01,1998-03-23
-5a7c,2016-03-16,2015-07-03
-4a7t,2012-11-28,2011-11-14
-6a7w,2018-11-07,2018-07-04
-8a76,2022-12-14,2022-06-20
-4a7d,2011-11-30,2011-11-14
-4a7w,2012-06-27,2011-11-15
-3a7j,2010-02-02,2009-09-27
-1a72,1998-06-17,1998-03-19
-7a7e,2021-07-07,2020-08-28
-8a7b,2023-05-31,2022-06-20
-3a72,2010-09-15,2009-09-11
-2a7j,2005-07-19,2005-07-05
-1a7k,1998-06-17,1998-03-16
-5a7n,2016-01-13,2015-07-09
-6a7t,2019-03-20,2018-07-04
-1a74,1998-06-22,1998-03-19
-2a79,2005-07-12,2005-07-05
-4a7f,2012-08-01,2011-11-14
-3a79,2009-11-24,2009-09-20
-4a7p,2012-11-21,2011-11-14
-4a75,2012-09-05,2011-11-11
-4a7b,2011-12-21,2011-11-11
-1a73,1998-10-14,1998-03-19
-5a74,2015-09-23,2015-07-02
-2a7g,2005-07-19,2005-07-05
-5a76,2015-10-28,2015-07-02
-5a7r,2015-07-22,2015-07-09
-8a7e,2022-11-02,2022-06-20
-8a7f,2024-01-10,2022-06-21
-3a7a,2010-01-19,2009-09-20
-8a78,2023-05-31,2022-06-20
-3a7y,2010-09-29,2009-10-05
-6a75,2018-07-18,2018-07-02
-5a7p,2016-01-13,2015-07-09
-8a7z,2023-03-22,2022-06-21
-1a77,1999-08-03,1998-03-20
-5a7j,2016-04-13,2015-07-06
-5a70,2016-07-27,2015-07-02
-4a7g,2012-10-24,2011-11-14
-4a7m,2012-11-07,2011-11-14
-1a7t,1998-06-17,1998-03-17
-8a7s,2023-04-05,2022-06-21
-2a7m,2005-08-16,2005-07-05
-6a7d,2018-07-18,2018-07-02
-5a7b,2015-09-30,2015-07-03
-5a7f,2016-01-13,2015-07-03
-5a7w,2016-01-13,2015-07-10
-7a72,2021-07-07,2020-08-27
-5a7y,2016-01-13,2015-07-10
-8a7i,2022-08-10,2022-06-21
-3a7v,2010-09-29,2009-10-05
-2a7d,2005-07-19,2005-07-05
-8a74,2023-05-31,2022-06-20
-4a7v,2012-11-28,2011-11-14
-1a7i,1998-05-27,1998-03-15
-7a7c,2021-01-27,2020-08-27
-2a7n,2006-07-11,2005-07-05
-7a7g,2021-08-04,2020-08-28
-2a7h,2005-07-19,2005-07-05
-8a7a,2023-05-31,2022-06-20
-3a7k,2009-12-15,2009-09-27
-2a73,2005-09-27,2005-07-04
-5a7u,2015-09-16,2015-07-10
-6a7s,2019-03-20,2018-07-04
-1a78,1998-10-14,1998-03-20
-1a7v,1998-06-17,1998-03-18
-3a7b,2009-11-24,2009-09-20
-5a7v,2015-08-26,2015-07-10
-8a7h,2024-01-10,2022-06-21
-2a7q,2006-01-24,2005-07-05
-3a7q,2010-03-23,2009-10-01
-4a79,2012-04-25,2011-11-11
-6a7j,2019-01-16,2018-07-03
-4a71,2012-10-17,2011-11-10
-5a78,2015-09-23,2015-07-03
-8a7r,2023-05-31,2022-06-21
-7a7b,2020-12-30,2020-08-27
-1a71,1998-06-17,1998-03-19
-1a7s,1999-03-23,1998-03-17
-6a7e,2019-04-10,2018-07-02
-3a7h,2010-02-02,2009-09-26
-1a76,1999-08-03,1998-03-20
-4a7u,2012-11-28,2011-11-14
-8a7d,2022-11-02,2022-06-20
-3a7d,2010-09-15,2009-09-26
-8a7n,2022-10-05,2022-06-21
-8a7j,2023-05-31,2022-06-21
-6a7c,2019-04-10,2018-07-02
-3a73,2010-01-19,2009-09-11
-6a7x,2019-07-24,2018-07-05
-3a7x,2010-09-29,2009-10-05
-4a7c,2012-02-15,2011-11-12
-7a76,2020-12-30,2020-08-27
-4a72,2012-01-25,2011-11-10
-1a7l,1998-06-17,1998-03-16
-5a72,2015-09-23,2015-07-02
-8a73,2023-05-31,2022-06-20
-2a7x,2006-02-21,2005-07-06
-4a7x,2012-06-27,2011-11-15
-4a7h,2012-08-01,2011-11-14
-6a7a,2019-07-03,2018-07-02
-7a70,2021-01-13,2020-08-27
-8a7x,2023-02-01,2022-06-21
-4a76,2012-09-05,2011-11-11
-2a78,2005-10-11,2005-07-05
-5a7m,2016-08-10,2015-07-08
-1a7c,1999-03-23,1998-03-12
-5a77,2015-09-23,2015-07-03
-5a7s,2016-01-13,2015-07-09
-5a7a,2015-09-02,2015-07-03
-6a7b,2019-07-03,2018-07-02
-2a75,2005-11-22,2005-07-04
-3a7w,2010-09-29,2009-10-05
-3a7t,2010-09-29,2009-10-05
-2a7b,2005-07-19,2005-07-05
-5a7g,2016-01-13,2015-07-04
-8a70,2023-05-31,2022-06-20
-4a7l,2012-08-01,2011-11-14
-8a7c,2023-05-31,2022-06-20
-2a7r,2006-01-31,2005-07-05
-7a7h,2021-08-04,2020-08-28
-1a7a,1999-04-20,1998-03-10
-3a7c,2009-11-24,2009-09-20
-3a7i,2010-02-02,2009-09-26
-8a7k,2023-05-31,2022-06-21
-1a75,1998-06-17,1998-03-19
-6ioh,2019-09-04,2018-10-30
-5ioc,2016-03-23,2016-03-08
-8iog,2024-04-17,2023-03-11
-8io3,2024-04-10,2023-03-10
-3io1,2009-08-25,2009-08-13
-6ioq,2019-03-06,2018-10-31
-2io6,2007-09-18,2006-10-10
-5iop,2016-10-26,2016-03-08
-5ior,2016-06-08,2016-03-08
-1ion,2001-09-26,2001-03-21
-3io9,2009-09-01,2009-08-14
-2iod,2007-09-11,2006-10-10
-1io9,2001-03-07,2001-02-08
-6iox,2019-04-24,2018-10-31
-2ioh,2007-08-07,2006-10-10
-2iof,2007-07-17,2006-10-10
-5ios,2016-06-08,2016-03-08
-5ioy,2017-03-29,2016-03-09
-8io8,2023-06-28,2023-03-10
-8iok,2024-03-13,2023-03-11
-1iop,1998-04-08,1997-12-12
-1ioe,2003-09-23,2001-03-08
-3ioq,2010-02-16,2009-08-14
-3io3,2009-12-22,2009-08-13
-2iom,2006-12-05,2006-10-10
-4ioa,2013-03-06,2013-01-07
-6ioi,2019-09-04,2018-10-30
-3io6,2009-10-27,2009-08-13
-1iow,1997-02-12,1996-09-20
-8ioc,2023-09-20,2023-03-10
-5io8,2017-03-15,2016-03-08
-4iom,2013-04-10,2013-01-08
-8io6,2023-06-28,2023-03-10
-1ioc,2002-10-09,2001-02-27
-3iol,2009-10-27,2009-08-14
-6io4,2019-07-03,2018-10-29
-4io3,2013-02-20,2013-01-07
-3iov,2009-09-29,2009-08-14
-6iom,2020-01-15,2018-10-30
-1io0,2002-11-27,2000-12-14
-3ioi,2010-04-07,2009-08-14
-1iod,2001-06-27,2001-02-27
-3ior,2009-09-29,2009-08-14
-1io3,2001-04-18,2001-01-06
-1io7,2001-02-28,2001-02-08
-4io7,2013-02-20,2013-01-07
-2iot,2008-04-08,2006-10-10
-3iod,2009-12-01,2009-08-14
-1ioa,1996-12-23,1996-10-02
-3iob,2009-12-01,2009-08-14
-4io5,2013-02-20,2013-01-07
-8ioy,2023-04-26,2023-03-13
-2io9,2006-12-12,2006-10-10
-2iou,2007-10-23,2006-10-10
-5iot,2016-06-08,2016-03-08
-4iof,2013-07-24,2013-01-07
-3iou,2009-09-29,2009-08-14
-8iod,2023-09-20,2023-03-10
-4ioi,2013-10-09,2013-01-07
-8iow,2024-03-20,2023-03-13
-4io2,2013-02-20,2013-01-07
-5io2,2016-09-21,2016-03-08
-5io1,2016-06-08,2016-03-08
-6iou,2019-03-06,2018-10-31
-3ioc,2009-12-01,2009-08-14
-4ioq,2013-10-02,2013-01-08
-1io8,2001-03-07,2001-02-08
-5iok,2016-04-20,2016-03-08
-8iov,2023-05-24,2023-03-13
-6ioa,2019-07-24,2018-10-29
-5ion,2016-03-30,2016-03-08
-6ion,2020-01-15,2018-10-30
-5ioq,2016-06-08,2016-03-08
-5iou,2016-04-20,2016-03-09
-4iop,2013-07-17,2013-01-08
-3ioj,2010-04-07,2009-08-14
-6ioz,2018-11-28,2018-11-01
-4io6,2013-02-20,2013-01-07
-6iob,2019-07-24,2018-10-29
-6io1,2019-05-22,2018-10-29
-2ior,2006-11-21,2006-10-10
-1io4,2001-03-12,2001-01-10
-2io8,2006-12-12,2006-10-10
-6iot,2019-03-20,2018-10-31
-8ioe,2023-06-28,2023-03-11
-2ioy,2007-03-20,2006-10-11
-2ioc,2007-02-20,2006-10-10
-2io7,2006-12-12,2006-10-10
-2iop,2006-11-21,2006-10-10
-3ioe,2009-12-01,2009-08-14
-3ion,2010-02-09,2009-08-14
-8ios,2023-05-24,2023-03-13
-6ioc,2019-07-24,2018-10-29
-4iou,2013-05-29,2013-01-08
-5io0,2016-09-21,2016-03-08
-3iog,2010-06-23,2009-08-14
-5iod,2016-03-23,2016-03-08
-6ios,2019-03-06,2018-10-31
-5ioo,2016-11-09,2016-03-08
-4io0,2014-02-12,2013-01-07
-6io0,2019-10-30,2018-10-29
-3iok,2009-11-10,2009-08-14
-4io8,2013-12-18,2013-01-07
-8iof,2024-03-27,2023-03-11
-2ioi,2006-12-05,2006-10-10
-4iol,2013-04-10,2013-01-08
-1iov,1997-02-12,1996-09-20
-2ioa,2006-12-12,2006-10-10
-5iov,2016-04-20,2016-03-09
-3io4,2009-10-27,2009-08-13
-8iot,2023-05-24,2023-03-13
-4iov,2014-04-02,2013-01-08
-1ioo,2002-05-08,2001-03-26
-3iof,2010-06-23,2009-08-14
-4iok,2013-04-10,2013-01-08
-8io7,2023-06-28,2023-03-10
-3iox,2010-04-14,2009-08-14
-6ior,2019-03-20,2018-10-31
-4ioc,2013-03-06,2013-01-07
-2io4,2008-04-08,2006-10-09
-6iov,2019-11-06,2018-10-31
-8ioo,2024-03-20,2023-03-13
-3iot,2009-09-29,2009-08-14
-8iox,2024-03-13,2023-03-13
-8iou,2023-05-24,2023-03-13
-1ioz,2001-10-03,2001-04-18
-2iog,2007-10-09,2006-10-10
-2ioo,2006-12-05,2006-10-10
-4ioo,2013-10-02,2013-01-08
-3iom,2011-01-12,2009-08-14
-4io4,2013-02-20,2013-01-07
-1iol,1997-07-07,1996-06-20
-4io9,2013-03-06,2013-01-07
-8ioa,2023-06-28,2023-03-10
-3io8,2009-09-01,2009-08-14
-5ioz,2017-03-29,2016-03-09
-8io9,2023-06-28,2023-03-10
-2iok,2007-10-09,2006-10-10
-3iow,2009-09-29,2009-08-14
-6iop,2019-03-20,2018-10-31
-6io6,2019-07-03,2018-10-29
-3io2,2009-11-24,2009-08-13
-5iow,2016-09-21,2016-03-09
-3io7,2009-11-10,2009-08-13
-3iop,2010-02-16,2009-08-14
-3w29,2013-04-03,2012-11-27
-3w2m,2013-12-04,2012-11-30
-5w2j,2018-10-17,2017-06-06
-6w2s,2020-04-22,2020-03-08
-3w21,2013-07-17,2012-11-26
-5w2u,2018-02-21,2017-06-06
-3w26,2013-04-03,2012-11-27
-8w21,2024-03-13,2024-02-19
-5w2o,2018-12-05,2017-06-06
-8w2o,2024-05-15,2024-02-20
-8w2r,2024-04-17,2024-02-21
-1w2b,2004-09-02,2004-07-01
-6w25,2020-04-29,2020-03-04
-7w20,2023-01-18,2021-11-21
-5w2w,2018-02-21,2017-06-07
-5w2q,2018-12-05,2017-06-06
-6w20,2020-05-06,2020-03-04
-1w2o,2004-09-30,2004-07-07
-3w2c,2014-02-05,2012-11-28
-2w2d,2009-03-24,2008-10-29
-6w2m,2020-07-22,2020-03-06
-6w2q,2020-04-15,2020-03-08
-3w2t,2013-05-15,2012-12-04
-1w2k,2005-06-20,2004-07-06
-5w24,2017-12-06,2017-06-05
-1w2h,2005-01-12,2004-07-06
-6w2j,2021-01-13,2020-03-05
-7w2d,2022-03-16,2021-11-23
-5w2h,2017-09-13,2017-06-06
-2w2q,2008-11-18,2008-11-03
-6w2k,2021-03-10,2020-03-06
-3w2g,2013-07-17,2012-11-28
-5w26,2018-02-21,2017-06-05
-5w21,2018-01-24,2017-06-05
-2w24,2009-11-17,2008-10-24
-1w22,2004-09-24,2004-06-25
-8w26,2024-05-22,2024-02-20
-2w2m,2008-11-18,2008-11-03
-6w2x,2020-07-01,2020-03-08
-6w2l,2020-08-19,2020-03-06
-6w29,2021-03-10,2020-03-05
-3w2z,2013-01-30,2012-12-06
-2w2l,2009-11-17,2008-11-02
-7w2a,2022-12-07,2021-11-23
-6w21,2020-05-13,2020-03-04
-2w2o,2008-11-18,2008-11-03
-2w2i,2009-01-20,2008-10-31
-6w2t,2020-04-22,2020-03-08
-1w2v,2004-09-30,2004-07-09
-7w2l,2023-02-01,2021-11-24
-5w2v,2018-01-03,2017-06-07
-7w2j,2022-11-30,2021-11-24
-3w2n,2013-12-04,2012-12-03
-3w2u,2013-12-11,2012-12-05
-6w2n,2021-03-10,2020-03-06
-5w27,2018-06-06,2017-06-05
-5w23,2017-12-06,2017-06-05
-3w2q,2013-01-16,2012-12-03
-1w2t,2005-10-26,2004-07-08
-7w2g,2022-03-16,2021-11-23
-3w2k,2013-12-04,2012-11-29
-2w2c,2008-12-23,2008-10-28
-6w23,2020-05-06,2020-03-04
-3w2x,2013-12-11,2012-12-06
-2w22,2008-12-16,2008-10-23
-7w2c,2022-03-16,2021-11-23
-7w2i,2022-07-06,2021-11-23
-6w2c,2020-03-25,2020-03-05
-7w2s,2022-04-06,2021-11-24
-3w2f,2013-07-17,2012-11-28
-7w28,2022-10-05,2021-11-22
-2w2h,2008-12-09,2008-10-30
-7w2r,2023-02-01,2021-11-24
-3w27,2013-04-03,2012-11-27
-5w2c,2017-10-18,2017-06-06
-7w2v,2022-04-06,2021-11-24
-1w29,2005-03-03,2004-07-01
-3w2e,2013-07-17,2012-11-28
-2w2t,2009-05-05,2008-11-04
-1w2c,2004-09-09,2004-07-01
-5w2m,2017-12-13,2017-06-06
-1w20,2006-01-25,2004-06-24
-3w22,2013-11-27,2012-11-26
-1w2z,2004-11-17,2004-07-11
-7w2k,2023-01-25,2021-11-24
-7w29,2022-10-05,2021-11-23
-6w24,2020-05-06,2020-03-04
-4w29,2014-10-01,2014-07-02
-1w2p,2004-09-30,2004-07-07
-3w2y,2013-12-11,2012-12-06
-3w2h,2013-07-17,2012-11-28
-3w2r,2013-01-16,2012-12-03
-5w2s,2018-12-05,2017-06-06
-7w2u,2023-02-01,2021-11-24
-3w2s,2013-01-16,2012-12-03
-6w2p,2020-06-10,2020-03-06
-2w23,2009-01-20,2008-10-23
-3w2j,2013-12-04,2012-11-28
-5w2l,2017-11-29,2017-06-06
-3w2l,2013-12-04,2012-11-29
-7w2y,2023-02-01,2021-11-24
-2w2f,2010-02-09,2008-10-29
-4w2r,2017-12-27,2017-09-25
-5w2y,2018-02-21,2017-06-07
-3w2p,2013-01-16,2012-12-03
-1w2y,2004-09-16,2004-07-09
-7w2z,2022-01-19,2021-11-24
-7w2h,2022-03-16,2021-11-23
-2w2p,2008-11-18,2008-11-03
-2w26,2008-11-11,2008-10-24
-4w2e,2014-10-01,2014-06-04
-7w2f,2022-03-16,2021-11-23
-5w2i,2017-09-13,2017-06-06
-6w2b,2020-03-25,2020-03-05
-2w2x,2009-05-05,2008-11-04
-1w2a,2004-09-30,2004-07-01
-1w2x,2004-09-09,2004-07-09
-4w2p,2017-10-11,2017-08-17
-1w2l,2005-01-19,2004-07-06
-5w2e,2017-08-16,2017-06-06
-6w2a,2020-08-12,2020-03-05
-1w2n,2004-09-30,2004-07-07
-6w2z,2020-03-25,2020-03-08
-5w2a,2017-10-18,2017-06-06
-5w2r,2018-01-03,2017-06-06
-6w2y,2020-07-01,2020-03-08
-1w21,2006-01-25,2004-06-25
-7w2t,2022-04-06,2021-11-24
-5w22,2017-12-06,2017-06-05
-3w2w,2013-10-16,2012-12-06
-8w2l,2024-04-17,2024-02-20
-1w2m,2005-09-29,2004-07-07
-3w2i,2013-07-17,2012-11-28
-6w22,2020-04-29,2020-03-04
-7w2b,2022-03-16,2021-11-23
-5w25,2017-06-14,2017-06-05
-5w2z,2018-01-03,2017-06-07
-2w2n,2008-11-18,2008-11-03
-2w27,2009-02-24,2008-10-24
-3w2v,2013-10-16,2012-12-06
-1w25,2004-11-18,2004-06-28
-1w2u,2004-09-16,2004-07-08
-3w25,2013-04-03,2012-11-27
-3w23,2013-11-27,2012-11-26
-3w2o,2013-01-16,2012-12-03
-3w28,2013-04-03,2012-11-27
-2w2v,2009-05-05,2008-11-04
-7w2w,2022-04-06,2021-11-24
-3w20,2013-07-17,2012-11-26
-6w26,2020-07-08,2020-03-05
-5w2p,2018-12-05,2017-06-06
-7w2x,2022-04-06,2021-11-24
-1w2d,2004-09-09,2004-07-01
-1w2g,2005-01-12,2004-07-06
-1w23,2004-12-22,2004-06-25
-8t6g,2023-10-11,2023-06-15
-3t6s,2011-12-21,2011-07-29
-6t6w,2020-08-19,2019-10-19
-3t6a,2011-11-23,2011-07-28
-1t6x,2004-08-10,2004-05-07
-7t6v,2022-03-30,2021-12-14
-3t6q,2011-11-09,2011-07-28
-6t6f,2020-01-15,2019-10-18
-1t69,2004-07-27,2004-05-05
-5t69,2017-01-25,2016-09-01
-5t6d,2016-11-23,2016-09-01
-5t6c,2017-09-13,2016-09-01
-5t6k,2016-11-02,2016-09-01
-1t65,2005-01-25,2004-05-05
-8t66,2024-01-10,2023-06-15
-8t6d,2023-10-11,2023-06-15
-3t6y,2012-08-29,2011-07-29
-3t63,2012-08-01,2011-07-28
-3t6e,2011-11-23,2011-07-28
-5t6r,2017-02-08,2016-09-01
-6t62,2020-11-18,2019-10-17
-5t66,2017-02-15,2016-09-01
-5t6b,2016-09-14,2016-09-01
-3t6u,2011-08-24,2011-07-29
-7t6h,2022-03-02,2021-12-13
-7t61,2022-07-06,2021-12-13
-3t66,2011-08-17,2011-07-28
-5t6s,2017-01-04,2016-09-01
-3t6j,2012-04-04,2011-07-28
-3t6c,2011-08-31,2011-07-28
-6t6i,2020-07-22,2019-10-18
-1t6j,2004-10-12,2004-05-06
-8t6z,2024-05-08,2023-06-19
-6t65,2020-11-18,2019-10-17
-7t67,2022-08-24,2021-12-13
-5t6f,2016-11-23,2016-09-01
-6t6r,2020-03-18,2019-10-18
-6t6j,2020-07-22,2019-10-18
-6t6z,2020-07-15,2019-10-20
-1t61,2004-09-21,2004-05-05
-1t67,2004-07-27,2004-05-05
-5t6h,2017-09-13,2016-09-01
-5t6e,2017-09-13,2016-09-01
-8t65,2024-01-10,2023-06-15
-7t68,2022-05-04,2021-12-13
-3t6z,2012-04-18,2011-07-29
-5t6i,2016-11-02,2016-09-01
-6t6n,2020-11-18,2019-10-18
-7t6f,2022-03-16,2021-12-13
-5t65,2017-09-13,2016-09-01
-5t6u,2017-01-18,2016-09-01
-6t6m,2020-11-18,2019-10-18
-6t6k,2020-11-18,2019-10-18
-5t67,2016-09-14,2016-09-01
-1t6c,2004-08-03,2004-05-06
-8t6x,2024-05-01,2023-06-19
-7t63,2022-07-13,2021-12-13
-6t6v,2020-04-01,2019-10-19
-5t6g,2016-11-23,2016-09-01
-6t6h,2020-07-15,2019-10-18
-5t6z,2017-03-01,2016-09-02
-5t6m,2016-12-21,2016-09-01
-3t6p,2011-11-02,2011-07-28
-1t66,2004-05-18,2004-05-05
-7t6u,2022-03-30,2021-12-14
-5t6n,2017-01-04,2016-09-01
-7t60,2022-07-06,2021-12-13
-6t69,2020-11-18,2019-10-18
-7t65,2022-07-20,2021-12-13
-3t65,2011-08-17,2011-07-28
-5t63,2017-01-25,2016-09-01
-7t66,2022-05-04,2021-12-13
-3t64,2012-08-29,2011-07-28
-3t6x,2012-04-18,2011-07-29
-5t68,2016-10-26,2016-09-01
-6t6a,2019-12-04,2019-10-18
-8t6l,2024-03-06,2023-06-16
-1t68,2005-05-17,2004-05-05
-7t6q,2022-05-04,2021-12-14
-3t6v,2012-04-18,2011-07-29
-1t6o,2004-08-03,2004-05-06
-1t6z,2004-08-10,2004-05-07
-6t6l,2021-07-14,2019-10-18
-3t60,2012-08-29,2011-07-28
-8t6b,2023-11-01,2023-06-15
-3t6w,2012-04-18,2011-07-29
-6t6b,2019-12-11,2019-10-18
-7t6e,2023-01-25,2021-12-13
-1t6m,2005-08-16,2004-05-06
-1t6u,2004-07-13,2004-05-07
-6t6g,2020-01-01,2019-10-18
-7t6s,2022-03-30,2021-12-14
-3t6b,2012-04-04,2011-07-28
-8t60,2024-02-28,2023-06-14
-8t6j,2023-10-11,2023-06-16
-8t6u,2023-09-13,2023-06-18
-3t6d,2011-11-23,2011-07-28
-7t6i,2022-12-07,2021-12-13
-1t63,2005-01-25,2004-05-05
-6t66,2021-04-28,2019-10-17
-6t6c,2019-11-20,2019-10-18
-7t6c,2022-03-02,2021-12-13
-7t64,2022-07-20,2021-12-13
-8t69,2023-11-01,2023-06-15
-3t67,2012-08-01,2011-07-28
-6t6e,2020-07-22,2019-10-18
-5t6p,2017-01-11,2016-09-01
-5t61,2016-10-19,2016-09-01
-7t6t,2022-03-30,2021-12-14
-5t62,2017-02-08,2016-09-01
-7t6w,2022-05-04,2021-12-14
-6t6y,2020-07-15,2019-10-20
-7t6x,2022-11-02,2021-12-14
-6t6o,2020-11-18,2019-10-18
-6t6x,2020-07-15,2019-10-20
-1t6y,2004-08-10,2004-05-07
-1t64,2004-07-27,2004-05-05
-8t67,2024-05-08,2023-06-15
-1t6b,2004-07-20,2004-05-05
-1t6w,2005-02-15,2004-05-07
-6t6d,2019-10-30,2019-10-18
-7t6m,2022-05-04,2021-12-14
-3t6i,2012-08-01,2011-07-28
-8t6v,2023-09-13,2023-06-18
-5t6q,2017-02-15,2016-09-01
-8t6s,2024-05-01,2023-06-18
-3t6r,2011-11-23,2011-07-29
-3t6f,2011-12-21,2011-07-28
-5t6a,2016-11-02,2016-09-01
-1t60,2004-09-21,2004-05-05
-5t64,2016-09-14,2016-09-01
-8t6a,2023-11-01,2023-06-15
-4dca,2012-02-01,2012-01-17
-8dcc,2022-07-06,2022-06-16
-4dc4,2013-01-23,2012-01-17
-7dcp,2021-01-06,2020-10-26
-4dco,2012-12-12,2012-01-18
-1dce,2000-03-24,1999-11-04
-7dcl,2021-03-03,2020-10-26
-1dct,1995-09-15,1995-05-17
-2dc3,2006-05-23,2005-12-21
-4dch,2012-02-08,2012-01-17
-6dc9,2019-03-20,2018-05-04
-3dc1,2008-07-29,2008-06-03
-1dc4,2000-08-23,1999-11-04
-8dco,2022-06-29,2022-06-17
-7dcm,2021-11-03,2020-10-26
-1dcy,1999-11-12,1999-11-05
-5dcg,2016-12-07,2015-08-24
-7dck,2021-10-27,2020-10-26
-3dcw,2009-03-03,2008-06-04
-3dcc,2009-03-03,2008-06-03
-7dcu,2021-07-14,2020-10-27
-6dcu,2019-05-15,2018-05-08
-3dcs,2009-03-03,2008-06-04
-2dcf,2007-01-09,2006-01-06
-3dci,2008-09-30,2008-06-03
-8dcf,2022-10-12,2022-06-16
-8dc7,2022-10-12,2022-06-15
-8dcz,2022-07-13,2022-06-17
-3dc8,2009-04-21,2008-06-03
-2dct,2006-01-24,2006-01-12
-4dct,2012-11-14,2012-01-18
-1dck,1999-11-26,1999-11-05
-2dc6,2006-01-24,2005-12-28
-8dcd,2022-10-12,2022-06-16
-8dc9,2022-10-12,2022-06-16
-6dch,2018-06-27,2018-05-07
-3dct,2008-08-12,2008-06-04
-4dce,2012-02-08,2012-01-17
-2dcn,2006-01-31,2006-01-10
-3dc9,2009-03-03,2008-06-03
-2dcb,2006-01-24,2006-01-01
-5dch,2016-10-05,2015-08-24
-3dcq,2009-01-13,2008-06-04
-7dcb,2021-10-27,2020-10-23
-4dc0,2013-01-16,2012-01-16
-2dcm,2006-09-19,2006-01-09
-7dc4,2021-04-28,2020-10-23
-7dcn,2021-11-03,2020-10-26
-6dcf,2018-09-05,2018-05-06
-5dc7,2016-02-03,2015-08-23
-7dct,2021-07-14,2020-10-27
-3dc2,2008-07-22,2008-06-03
-4dc3,2012-11-28,2012-01-17
-6dc2,2018-10-03,2018-05-04
-4dcu,2012-11-14,2012-01-18
-6dcb,2018-12-19,2018-05-04
-3dc0,2008-06-17,2008-06-03
-1dcd,1999-07-09,1999-03-20
-6dcq,2018-06-27,2018-05-08
-5dc5,2016-02-03,2015-08-23
-5dcr,2015-09-09,2015-08-24
-5dcy,2015-10-28,2015-08-24
-7dc6,2021-06-16,2020-10-23
-3dcr,2008-08-19,2008-06-04
-1dci,1999-03-30,1998-02-13
-4dcs,2012-11-14,2012-01-18
-8dcs,2022-07-27,2022-06-17
-2dc1,2006-12-26,2005-12-19
-7dc7,2021-01-13,2020-10-23
-4dcd,2012-09-05,2012-01-17
-8dcy,2022-12-07,2022-06-17
-7dcf,2021-02-10,2020-10-26
-2dcl,2006-07-08,2006-01-08
-8dcl,2022-06-29,2022-06-16
-8dcr,2022-07-27,2022-06-17
-2dcc,2006-01-24,2006-01-01
-6dcd,2019-03-20,2018-05-05
-4dc8,2013-01-23,2012-01-17
-1dc6,2000-08-23,1999-11-04
-2dcx,2006-02-28,2006-01-17
-5dce,2016-08-24,2015-08-24
-5dc2,2016-10-05,2015-08-23
-3dc7,2008-08-05,2008-06-03
-4dc1,2013-01-16,2012-01-16
-4dc2,2012-07-11,2012-01-17
-1dcq,1999-12-22,1999-11-05
-6dc5,2019-07-10,2018-05-04
-1dcm,2000-11-08,1999-11-05
-3dc5,2009-06-09,2008-06-03
-1dcb,1993-07-15,1993-03-10
-7dcy,2021-03-17,2020-10-27
-5dcu,2015-10-28,2015-08-24
-3dcp,2008-07-29,2008-06-04
-1dcn,1999-04-27,1998-10-29
-8dcb,2022-10-12,2022-06-16
-3dcl,2008-08-05,2008-06-03
-4dcx,2012-05-09,2012-01-18
-2dcd,2006-01-24,2006-01-01
-5dc8,2016-02-03,2015-08-23
-3dc4,2009-02-10,2008-06-03
-6dcz,2018-11-07,2018-05-08
-3dcj,2009-05-12,2008-06-03
-8dct,2022-08-17,2022-06-17
-4dcn,2012-06-13,2012-01-18
-8dck,2022-09-14,2022-06-16
-7dcw,2021-10-27,2020-10-27
-1dca,1993-07-15,1992-12-18
-8dcm,2023-04-05,2022-06-16
-5dcc,2016-09-28,2015-08-23
-7dcs,2021-07-14,2020-10-27
-7dc1,2021-10-27,2020-10-23
-6dcm,2019-05-15,2018-05-07
-2dcu,2006-07-25,2006-01-16
-6dc3,2019-07-10,2018-05-04
-3dc6,2009-06-09,2008-06-03
-8dcv,2022-08-17,2022-06-17
-5dc6,2016-02-03,2015-08-23
-2dc7,2006-01-24,2005-12-31
-3dcv,2008-08-19,2008-06-04
-7dc9,2021-09-29,2020-10-23
-8dc8,2022-10-12,2022-06-15
-4dcp,2012-12-12,2012-01-18
-1dcp,1996-12-07,1996-05-16
-3dcm,2008-12-09,2008-06-04
-2dcj,2007-03-20,2006-01-07
-2dca,2006-01-24,2006-01-01
-6dcc,2018-12-19,2018-05-04
-3dco,2009-02-10,2008-06-04
-6dc6,2018-10-10,2018-05-04
-8dc6,2022-10-12,2022-06-15
-6dc1,2018-08-01,2018-05-03
-7dcz,2021-03-10,2020-10-27
-4dcc,2012-02-22,2012-01-17
-7dco,2021-03-17,2020-10-26
-8dcu,2022-08-17,2022-06-17
-3dcu,2008-08-12,2008-06-04
-4dck,2012-06-27,2012-01-17
-8dch,2022-10-05,2022-06-16
-7dcg,2021-08-11,2020-10-26
-6dca,2019-03-20,2018-05-04
-1dcc,1994-08-31,1994-06-01
-5dcd,2016-08-24,2015-08-24
-5dcx,2015-09-23,2015-08-24
-3dcb,2009-02-10,2008-06-03
-7dch,2021-08-11,2020-10-26
-5dcz,2016-09-07,2015-08-24
-7dc8,2021-01-13,2020-10-23
-8dcw,2022-08-17,2022-06-17
-6dcw,2018-06-06,2018-05-08
-5dc3,2016-06-01,2015-08-23
-7dca,2021-09-29,2020-10-23
-8dca,2022-10-12,2022-06-16
-6dcr,2018-09-05,2018-05-08
-8dcg,2022-10-12,2022-06-16
-6dcg,2018-08-08,2018-05-06
-7dcj,2021-07-14,2020-10-26
-7dci,2021-07-14,2020-10-26
-6dcy,2018-11-07,2018-05-08
-5dcb,2016-08-24,2015-08-23
-5dcs,2015-09-09,2015-08-24
-2dc8,2006-01-24,2005-12-31
-3dc3,2009-03-03,2008-06-03
-4dcm,2012-08-01,2012-01-17
-3dck,2008-08-19,2008-06-03
-4dcg,1999-07-22,1998-07-13
-2dc9,2006-01-24,2005-12-31
-4dcv,2012-11-14,2012-01-18
-8dc4,2022-10-12,2022-06-15
-5dco,2015-09-09,2015-08-24
-8dcq,2023-01-11,2022-06-17
-8dc5,2022-12-14,2022-06-15
-6dc8,2019-03-20,2018-05-04
-4dcj,2012-12-12,2012-01-17
-2dck,2007-03-20,2006-01-07
-4dc7,2013-01-23,2012-01-17
-106m,1998-04-08,1997-12-21
-2cag,1996-12-07,1996-06-12
-7can,2020-06-24,2020-06-09
-2ca5,2006-08-07,2005-12-16
-5cay,2015-12-09,2015-06-30
-7ca3,2020-11-11,2020-06-08
-1caq,1999-07-07,1999-02-23
-4ca2,1992-10-31,1991-06-08
-8cah,2023-05-24,2023-01-24
-3ca0,2008-11-25,2008-02-19
-1caj,1993-10-31,1992-09-17
-5cah,2016-08-10,2015-06-29
-1cah,1993-10-31,1992-06-25
-4ca6,2013-12-11,2013-10-07
-8ca7,2023-08-02,2023-01-24
-6cay,2018-02-28,2018-02-01
-7ca0,2021-06-09,2020-06-08
-4ca5,2013-12-11,2013-10-07
-4caq,2014-02-19,2013-10-08
-8caw,2024-01-24,2023-01-24
-4cam,2014-02-19,2013-10-08
-1ca3,1992-10-15,1991-11-18
-3caq,2008-12-09,2008-02-20
-3caw,2008-03-04,2008-02-20
-3cas,2008-12-09,2008-02-20
-6cav,2018-04-11,2018-02-01
-2ca4,2007-02-20,2005-12-16
-3cah,2008-11-25,2008-02-20
-5cax,2016-02-24,2015-06-30
-7cap,2020-08-19,2020-06-09
-4ca1,2013-10-16,2013-10-04
-5cas,2015-10-28,2015-06-29
-5caq,2015-10-28,2015-06-29
-3cak,2008-10-21,2008-02-20
-5ca9,2015-09-23,2015-06-29
-7cag,2020-12-02,2020-06-08
-8ca3,2023-12-20,2023-01-24
-7cat,1985-04-01,1984-11-15
-8ca5,2023-12-20,2023-01-24
-4caf,2014-04-02,2013-10-08
-7cax,2021-06-16,2020-06-10
-1ca8,1999-04-27,1998-04-27
-1ca1,1999-05-04,1998-04-22
-3ca6,2008-11-25,2008-02-19
-8ca0,2024-02-07,2023-01-24
-6ca1,2018-02-28,2018-01-29
-7caj,2021-04-07,2020-06-08
-4caw,2014-09-17,2013-10-09
-7car,2021-04-28,2020-06-10
-5ca0,2015-11-04,2015-06-29
-3ca5,2008-11-25,2008-02-19
-6ca3,2018-02-28,2018-01-29
-8cai,2023-07-26,2023-01-24
-4cak,2013-10-30,2013-10-08
-7cas,2021-04-28,2020-06-10
-4ca4,2014-10-29,2013-10-06
-5ca2,1992-10-31,1991-06-08
-1cay,1993-10-31,1993-02-26
-1ca5,2000-02-23,1999-02-23
-2caj,2006-07-17,2005-12-21
-4ca7,2013-12-11,2013-10-07
-7caf,2020-12-02,2020-06-08
-6cax,2019-02-13,2018-02-01
-2can,1998-06-03,1997-05-29
-8caa,2023-04-12,2023-01-24
-6caq,2018-07-25,2018-01-31
-2cab,1984-02-02,1983-10-05
-1can,1994-01-31,1992-07-02
-1cal,1993-10-31,1992-09-17
-5ca1,2015-11-04,2015-06-29
-8can,2023-10-04,2023-01-24
-8cak,2023-09-27,2023-01-24
-4cac,1994-01-31,1991-09-05
-9ca2,1992-07-15,1991-07-09
-6caz,2018-02-14,2018-02-01
-3cav,2008-07-29,2008-02-20
-4cap,2014-02-19,2013-10-08
-7cai,2020-09-23,2020-06-08
-1caa,1993-10-31,1992-05-18
-8cal,2023-09-27,2023-01-24
-5cau,2015-10-28,2015-06-29
-1cak,1993-10-31,1992-09-17
-8cag,2023-02-01,2023-01-24
-7cak,2020-09-23,2020-06-08
-6cad,2018-02-21,2018-01-30
-3cap,2008-06-24,2008-02-20
-3caj,2008-04-08,2008-02-20
-3ca4,2008-11-25,2008-02-19
-4caj,2014-10-15,2013-10-08
-1ca6,2000-02-23,1999-02-23
-7cab,2020-12-16,2020-06-08
-1cad,1993-10-31,1992-05-18
-6ca4,2018-05-02,2018-01-29
-5ca7,2016-02-24,2015-06-29
-3ca9,2009-03-03,2008-02-19
-5ca3,2016-08-10,2015-06-29
-1ca9,1999-04-12,1999-02-25
-1caz,1993-10-31,1993-02-26
-5ca8,2015-09-16,2015-06-29
-6cae,2018-04-18,2018-01-30
-3cag,2008-03-18,2008-02-19
-3ca1,2008-11-25,2008-02-19
-5cac,1994-01-31,1991-09-05
-6cas,2018-07-25,2018-01-31
-6cam,2018-05-09,2018-01-31
-8cat,1985-04-01,1984-11-15
-7cav,2021-04-28,2020-06-10
-4cab,2014-07-09,2013-10-08
-4cav,2014-09-17,2013-10-09
-6ca0,2018-02-28,2018-01-29
-7cac,2021-02-24,2020-06-08
-2caq,2006-06-21,2005-12-22
-6cac,2018-10-17,2018-01-30
-2ca2,1990-01-15,1989-02-06
-8cap,2023-09-27,2023-01-24
-1cai,1993-10-31,1992-09-17
-6ca2,1992-07-15,1991-07-09
-1ca7,1999-06-30,1999-02-25
-1ca2,1990-01-15,1989-02-06
-8ca9,2023-10-04,2023-01-24
-4cao,2014-02-19,2013-10-08
-6cao,2018-07-25,2018-01-31
-8cav,2023-06-14,2023-01-24
-8cas,2023-05-24,2023-01-24
-4caz,2014-10-29,2013-10-09
-4can,2014-02-19,2013-10-08
-2cad,2006-07-17,2005-12-20
-3cao,2000-07-23,1998-11-17
-4car,2014-02-19,2013-10-08
-4cax,2014-09-17,2013-10-09
-5cad,2016-04-06,2015-06-29
-2ca3,2007-02-20,2005-12-16
-2ca0,2006-12-13,2005-12-15
-8cay,2024-01-24,2023-01-24
-5can,2015-10-28,2015-06-29
-6caw,2018-02-28,2018-02-01
-7ca1,2021-06-09,2020-06-08
-5caw,2015-07-22,2015-06-30
-7ca2,1992-07-15,1991-07-09
-3ca3,2008-11-25,2008-02-19
-4cat,1983-09-06,1983-02-24
-4ca8,2013-12-11,2013-10-07
-8ca4,2023-12-20,2023-01-24
-8cad,2023-10-04,2023-01-24
-6cau,2018-03-07,2018-01-31
-8caz,2023-07-26,2023-01-24
-3car,2000-07-23,1998-11-17
-7ca8,2021-04-07,2020-06-08
-3ca2,1990-01-15,1989-10-02
-2cal,2006-01-05,2005-12-21
-4cas,2013-12-25,2013-10-09
-5cav,2015-10-28,2015-06-30
-6caj,2018-04-11,2018-01-31
-1cam,1993-10-31,1992-09-17
-8ca2,1992-07-15,1991-07-09
-4cae,2014-04-02,2013-10-08
-2cak,2006-03-08,2005-12-21
-1cao,1994-01-31,1992-07-02
-2cah,1997-01-11,1996-07-01
-5cao,2015-10-28,2015-06-29
-4cag,2014-10-15,2013-10-08
-8cau,2023-10-11,2023-01-24
-2ca8,2006-06-26,2005-12-20
-8ca1,2023-12-20,2023-01-24
-5cap,2015-10-28,2015-06-29
-8cao,2023-09-27,2023-01-24
-5cal,2015-10-28,2015-06-29
-6cap,2018-07-25,2018-01-31
-6car,2018-07-25,2018-01-31
-5cak,2016-08-10,2015-06-29
-8cam,2023-07-26,2023-01-24
-5cae,2016-06-29,2015-06-29
-5yjw,2018-02-14,2017-10-11
-7yj0,2023-05-10,2022-07-18
-2yjg,2012-05-30,2011-05-19
-2yjd,2011-08-03,2011-05-19
-8yjx,2024-04-17,2024-03-03
-6yjf,2021-04-14,2020-04-03
-4yjf,2016-04-06,2015-03-03
-5yjg,2018-05-23,2017-10-10
-5yj3,2017-12-06,2017-10-07
-5yj9,2018-07-25,2017-10-09
-2yj3,2012-05-30,2011-05-18
-7yjh,2023-05-24,2022-07-20
-7yjp,2023-02-01,2022-07-20
-4yjt,2015-09-30,2015-03-03
-7yj3,2023-07-19,2022-07-19
-6yjo,2021-03-03,2020-04-04
-2yjj,2011-06-29,2011-05-19
-7yj9,2022-08-24,2022-07-19
-1yjk,2005-11-15,2005-01-14
-7yjo,2023-04-05,2022-07-20
-6yjq,2020-08-05,2020-04-04
-6yj4,2020-08-12,2020-04-02
-7yjj,2023-07-26,2022-07-20
-5yjs,2018-10-10,2017-10-11
-4yjz,2015-05-27,2015-03-03
-1yjp,2005-06-14,2005-01-15
-2yjp,2011-12-14,2011-05-23
-1yj1,2005-06-14,2005-01-13
-5yja,2018-10-10,2017-10-09
-6yj9,2021-04-14,2020-04-02
-5yjy,2018-02-14,2017-10-11
-2yjb,2011-11-23,2011-05-19
-4yjh,2016-04-06,2015-03-03
-6yjt,2020-08-05,2020-04-04
-4yjp,2015-09-30,2015-03-03
-6yjb,2020-12-23,2020-04-02
-7yja,2022-08-24,2022-07-19
-1yjs,2005-05-31,2005-01-15
-1yj2,2005-02-15,2005-01-13
-5yjd,2018-10-17,2017-10-10
-6yjd,2021-02-24,2020-04-03
-1yj9,2005-04-26,2005-01-13
-7yj1,2023-07-05,2022-07-19
-2yje,2011-07-06,2011-05-19
-1yj3,2005-07-05,2005-01-13
-1yjy,2005-05-31,2005-01-16
-5yjl,2018-05-30,2017-10-11
-2yj4,2012-05-30,2011-05-18
-2yj7,2012-05-30,2011-05-19
-5yj2,2018-10-10,2017-10-07
-6yj7,2021-04-14,2020-04-02
-4yjo,2015-09-30,2015-03-03
-4yjg,2016-04-06,2015-03-03
-4yj2,2015-05-27,2015-03-03
-7yjb,2022-08-24,2022-07-19
-5yji,2018-03-21,2017-10-10
-6yju,2020-08-05,2020-04-04
-7yjg,2023-05-24,2022-07-20
-7yj2,2023-07-05,2022-07-19
-5yjx,2018-02-14,2017-10-11
-2yjw,2011-10-19,2011-05-24
-4yjd,2016-04-06,2015-03-03
-5yjj,2018-01-31,2017-10-10
-6yji,2021-03-03,2020-04-03
-7yje,2023-05-24,2022-07-20
-4yj3,2015-05-27,2015-03-03
-4yji,2015-11-04,2015-03-03
-4yj1,2015-08-12,2015-03-03
-1yj6,2005-02-01,2005-01-13
-7yj8,2022-08-24,2022-07-19
-7yjm,2023-04-05,2022-07-20
-7yjk,2023-04-05,2022-07-20
-5yj1,2018-02-07,2017-10-06
-4yjx,2016-01-27,2015-03-03
-1yjv,2006-01-03,2005-01-15
-7yj6,2022-08-24,2022-07-19
-5yjo,2018-10-17,2017-10-11
-7yjc,2022-12-07,2022-07-19
-2yjc,2011-11-23,2011-05-19
-1yjn,2005-04-26,2005-01-14
-4yjr,2015-09-30,2015-03-03
-5yj8,2018-05-02,2017-10-09
-6yjm,2021-04-14,2020-04-03
-6yjx,2020-07-22,2020-04-05
-4yjn,2015-11-25,2015-03-03
-1yjb,1996-07-11,1996-01-16
-2yj9,2011-11-23,2011-05-19
-4yjj,2016-03-09,2015-03-03
-6yjp,2020-07-29,2020-04-04
-2yjz,2012-05-30,2011-05-24
-4yjk,2015-03-11,2015-03-03
-5yjh,2018-05-23,2017-10-10
-1yjd,2005-02-15,2005-01-14
-1yj0,2005-03-08,2005-01-11
-4yjv,2015-10-14,2015-03-03
-7yjq,2023-02-01,2022-07-20
-2yjx,2011-10-19,2011-05-24
-2yjl,2011-08-10,2011-05-20
-6yjn,2020-06-10,2020-04-03
-2yjk,2011-06-01,2011-05-19
-7yjt,2023-02-01,2022-07-20
-6yjv,2020-08-05,2020-04-04
-1yjo,2005-06-14,2005-01-15
-6yje,2021-04-14,2020-04-03
-2yj2,2011-11-23,2011-05-18
-6yj1,2020-09-09,2020-04-02
-7yj5,2022-08-24,2022-07-19
-7yjn,2023-04-05,2022-07-20
-7yjs,2023-02-01,2022-07-20
-1yjf,2005-02-15,2005-01-14
-2yjq,2011-06-15,2011-05-23
-5yjp,2017-12-27,2017-10-11
-5yjf,2018-03-21,2017-10-10
-1yjq,2005-06-28,2005-01-15
-2yjf,2011-07-06,2011-05-19
-6yjy,2020-07-01,2020-04-05
-6yjc,2020-07-15,2020-04-02
-5yj7,2018-10-10,2017-10-09
-4yj0,2015-05-27,2015-03-02
-1yja,1996-07-11,1996-01-16
-1yjw,2005-04-26,2005-01-15
-6yjh,2021-04-14,2020-04-03
-1yjm,2005-03-15,2005-01-14
-6yja,2021-04-14,2020-04-02
-1yjc,1996-07-11,1996-01-16
-2yj0,2011-10-12,2011-05-17
-6yjr,2020-08-05,2020-04-04
-1yjh,2005-12-27,2005-01-14
-2yja,2011-08-03,2011-05-19
-7yjr,2023-02-01,2022-07-20
-6yjs,2020-08-05,2020-04-04
-1yjt,2006-01-03,2005-01-15
-5yjb,2018-07-04,2017-10-10
-7yj7,2022-08-24,2022-07-19
-5yj0,2018-02-07,2017-10-06
-2yj5,2012-05-30,2011-05-18
-4yj5,2016-03-09,2015-03-03
-2yj6,2012-05-30,2011-05-18
-2yj8,2011-11-23,2011-05-19
-4yjs,2015-09-30,2015-03-03
-1yjz,2005-06-14,2005-01-16
-7yjf,2023-05-24,2022-07-20
-5yjk,2017-12-06,2017-10-11
-4yjq,2015-09-30,2015-03-03
-7yjd,2023-07-26,2022-07-19
-6yjw,2020-07-22,2020-04-05
-5yjm,2017-12-27,2017-10-11
-4yju,2015-09-30,2015-03-03
-5pm6,2017-03-15,2017-02-07
-7pmx,2021-10-20,2021-09-03
-5pmw,2017-03-15,2017-02-07
-1pm5,2004-07-27,2003-06-10
-4pmt,2014-06-18,2014-05-22
-5pmz,2017-03-15,2017-02-07
-5pmt,2017-03-15,2017-02-07
-6pmp,2020-07-08,2019-07-02
-4pm1,2014-10-08,2014-05-20
-3pm8,2010-12-08,2010-11-16
-6pmh,2020-07-08,2019-07-01
-7pml,2021-12-22,2021-09-02
-1pmh,2004-06-22,2003-06-11
-5pms,2017-03-15,2017-02-07
-2pmp,2007-09-18,2007-04-23
-6pm2,2021-02-10,2019-07-01
-8pm1,2023-07-05,2023-06-27
-6pm4,2021-02-10,2019-07-01
-7pmk,2021-11-10,2021-09-02
-1pm9,2003-12-16,2003-06-10
-7pm8,2021-12-22,2021-09-02
-6pm6,2021-02-10,2019-07-01
-1pmn,2003-09-09,2003-06-11
-5pm8,2017-03-15,2017-02-07
-5pmi,2017-03-15,2017-02-07
-4pmm,2014-06-18,2014-05-22
-7pmn,2021-11-10,2021-09-02
-4pmz,2014-10-08,2014-05-22
-6pm1,2021-02-10,2019-07-01
-5pmk,2017-03-15,2017-02-07
-2pmj,2007-05-01,2007-04-23
-3pmx,2011-01-12,2010-11-18
-8pme,2024-04-17,2023-06-28
-5pmj,2017-03-15,2017-02-07
-3pm6,2010-12-15,2010-11-16
-8pmq,2024-01-03,2023-06-29
-6pmw,2020-04-29,2019-07-02
-7pmt,2022-09-14,2021-09-02
-5pm0,2017-03-15,2017-02-07
-7pmw,2021-10-20,2021-09-03
-1pmi,1997-03-01,1996-04-03
-3pmw,2011-01-12,2010-11-18
-2pmd,2007-11-06,2007-04-21
-8pm2,2023-08-09,2023-06-28
-1pmm,2004-02-17,2003-06-11
-5pmf,2017-03-15,2017-02-07
-7pm0,2021-12-22,2021-09-01
-5pmv,2017-03-15,2017-02-07
-4pm0,2014-12-03,2014-05-20
-3pmn,2011-02-02,2010-11-17
-7pmc,2021-12-22,2021-09-02
-4pmx,2014-10-08,2014-05-22
-2pmi,2007-12-11,2007-04-23
-5pmb,2017-03-15,2017-02-07
-2pmn,2008-01-22,2007-04-23
-4pms,2014-06-18,2014-05-22
-8pmj,2023-11-29,2023-06-28
-4pmy,2014-10-08,2014-05-22
-7pmq,2022-09-14,2021-09-02
-7pmv,2022-02-23,2021-09-02
-4pml,2014-10-15,2014-05-22
-2pml,2008-01-22,2007-04-23
-3pmp,2011-11-23,2010-11-17
-3pm1,2011-07-13,2010-11-15
-6pm5,2021-02-10,2019-07-01
-4pmc,2014-06-11,2014-05-20
-8pm9,2024-05-08,2023-06-28
-4pme,2014-10-08,2014-05-21
-7pmi,2021-12-22,2021-09-02
-6pm0,2021-02-10,2019-07-01
-6pmb,2020-02-26,2019-07-01
-4pm5,2014-12-31,2014-05-20
-6pma,2020-02-26,2019-07-01
-6pm9,2019-09-18,2019-07-01
-3pmg,1995-12-07,1995-03-02
-3pmb,2011-07-20,2010-11-16
-2pmo,2008-01-22,2007-04-23
-6pmy,2020-04-29,2019-07-02
-3pmf,2011-11-16,2010-11-16
-7pm1,2021-12-22,2021-09-01
-7pm4,2022-08-10,2021-09-01
-1pme,1999-06-08,1998-06-08
-5pmg,2017-03-15,2017-02-07
-4pm9,2014-12-31,2014-05-20
-5pmc,2017-03-15,2017-02-07
-2pm8,2007-09-25,2007-04-20
-6pmc,2020-02-26,2019-07-01
-5pm1,2017-03-15,2017-02-07
-6pmd,2019-11-06,2019-07-01
-3pmq,2011-05-25,2010-11-17
-3pmz,2011-10-05,2010-11-18
-5pmq,2017-03-15,2017-02-07
-7pm2,2021-12-22,2021-09-01
-8pml,2024-04-17,2023-06-29
-4pmf,2014-10-08,2014-05-21
-3pm5,2011-06-01,2010-11-16
-4pmr,2014-10-08,2014-05-22
-5pm5,2017-03-15,2017-02-07
-8pm0,2024-02-21,2023-06-27
-7pmz,2022-05-11,2021-09-04
-8pma,2024-05-08,2023-06-28
-6pml,2019-11-06,2019-07-02
-7pm3,2021-12-22,2021-09-01
-5pme,2017-03-15,2017-02-07
-4pm3,2014-07-30,2014-05-20
-7pma,2021-12-22,2021-09-02
-4pmo,2014-10-08,2014-05-22
-5pml,2017-03-15,2017-02-07
-8pms,2023-11-15,2023-06-29
-3pmu,2011-11-02,2010-11-18
-5pm7,2017-03-15,2017-02-07
-4pmd,2015-06-24,2014-05-21
-4pmw,2014-07-30,2014-05-22
-5pmd,2017-03-15,2017-02-07
-7pm7,2021-12-22,2021-09-02
-1pm1,2004-06-22,2003-06-09
-1pmb,1990-01-15,1989-11-27
-3pm9,2010-12-15,2010-11-16
-6pmz,2020-04-29,2019-07-02
-5pmu,2017-03-15,2017-02-07
-7pmf,2021-12-22,2021-09-02
-4pm7,2014-12-31,2014-05-20
-3pm4,2011-11-02,2010-11-16
-1pmt,1999-04-20,1998-03-23
-8pmo,2024-05-08,2023-06-29
-8pmd,2023-11-22,2023-06-28
-1pmo,2004-02-17,2003-06-11
-6pmf,2019-11-06,2019-07-01
-3pmv,2011-01-12,2010-11-18
-2pmv,2007-10-30,2007-04-23
-5pmx,2017-03-15,2017-02-07
-8pm8,2024-05-08,2023-06-28
-7pmh,2021-12-22,2021-09-02
-3pmy,2011-11-02,2010-11-18
-7pmj,2021-12-22,2021-09-02
-6pmg,2020-04-29,2019-07-01
-4pmb,2014-06-11,2014-05-20
-5pm2,2017-03-15,2017-02-07
-1pmv,2003-09-09,2003-06-11
-5pm9,2017-03-15,2017-02-07
-3pm0,2010-12-08,2010-11-15
-7pm6,2021-12-22,2021-09-02
-2pmt,1999-04-27,1998-04-28
-7pmy,2021-10-20,2021-09-04
-8pm6,2023-11-22,2023-06-28
-1pmu,2003-09-09,2003-06-11
-7pmd,2021-12-22,2021-09-02
-8pmm,2024-04-17,2023-06-29
-7pme,2021-12-22,2021-09-02
-6pm3,2021-02-10,2019-07-01
-6pmv,2020-04-29,2019-07-02
-5pmp,2017-03-15,2017-02-07
-1pmy,1994-07-31,1994-01-28
-3pml,2011-01-26,2010-11-17
-5pm4,2017-03-15,2017-02-07
-6pm7,2020-05-20,2019-07-01
-8pmr,2023-11-15,2023-06-29
-8pmg,2024-04-17,2023-06-28
-7pmm,2022-09-14,2021-09-02
-8pmi,2024-04-17,2023-06-28
-5pmo,2017-03-15,2017-02-07
-5pmh,2017-03-15,2017-02-07
-5pm3,2017-03-15,2017-02-07
-6pmu,2020-07-08,2019-07-02
-1pm2,2004-01-13,2003-06-09
-5pmm,2017-03-15,2017-02-07
-4pmj,2014-06-11,2014-05-21
-6pmx,2020-04-29,2019-07-02
-2pmz,2008-02-12,2007-04-23
-3pmj,2011-11-23,2010-11-17
-2pmh,2008-04-22,2007-04-22
-4pmp,2014-06-18,2014-05-22
-7pm5,2021-12-22,2021-09-02
-3pm3,2011-12-07,2010-11-16
-2pms,2007-06-19,2007-04-23
-1pmj,2004-06-22,2003-06-11
-7pmo,2022-02-02,2021-09-02
-3pmd,2011-01-19,2010-11-16
-8pm3,2023-09-20,2023-06-28
-2pmc,2008-01-15,2007-04-20
-3pmh,2011-06-01,2010-11-16
-2pmq,2007-05-08,2007-04-23
-5pma,2017-03-15,2017-02-07
-7pmg,2021-12-22,2021-09-02
-2pmy,2007-05-08,2007-04-23
-7pm9,2021-12-22,2021-09-02
-2pmk,2008-02-05,2007-04-23
-5pmn,2017-03-15,2017-02-07
-6pme,2020-02-26,2019-07-01
-5pmr,2017-03-15,2017-02-07
-7pmb,2021-12-22,2021-09-02
-8pmp,2024-01-17,2023-06-29
-5pmy,2017-03-15,2017-02-07
-6pmt,2020-07-08,2019-07-02
-4n6g,2014-01-01,2013-10-11
-7n6w,2021-09-22,2021-06-09
-1n6o,2002-11-27,2002-11-11
-7n6s,2021-06-23,2021-06-09
-5n6b,2017-10-18,2017-02-14
-1n60,2002-12-18,2002-11-08
-5n6s,2017-03-01,2017-02-16
-4n6w,2013-11-27,2013-10-14
-1n68,2003-06-24,2002-11-08
-5n6q,2017-05-17,2017-02-15
-6n6f,2019-06-12,2018-11-26
-5n6p,2018-03-07,2017-02-15
-7n66,2021-10-06,2021-06-07
-5n6c,2017-11-22,2017-02-14
-6n6q,2019-06-05,2018-11-26
-4n63,2013-12-18,2013-10-11
-1n6y,2003-03-04,2002-11-12
-6n69,2019-03-27,2018-11-26
-7n62,2021-08-04,2021-06-07
-7n6r,2021-09-15,2021-06-08
-6n6b,2019-07-03,2018-11-26
-6n61,2019-01-09,2018-11-24
-1n6e,2002-12-30,2002-11-10
-1n6r,2002-11-27,2002-11-11
-4n6f,2014-05-14,2013-10-11
-5n6n,2017-11-01,2017-02-15
-6n6n,2019-10-09,2018-11-26
-6n62,2019-01-09,2018-11-24
-1n6b,2003-06-03,2002-11-09
-7n61,2022-05-18,2021-06-07
-4n65,2014-06-11,2013-10-11
-5n6v,2018-03-07,2017-02-16
-7n6l,2021-06-23,2021-06-08
-3n6c,2011-02-09,2010-05-25
-7n6n,2021-06-16,2021-06-08
-7n6m,2021-06-23,2021-06-08
-5n64,2017-09-20,2017-02-14
-6n6k,2019-06-12,2018-11-26
-4n6p,2013-10-30,2013-10-14
-2n6j,2016-01-13,2015-08-24
-4n69,2013-11-13,2013-10-11
-1n6p,2002-11-27,2002-11-11
-7n60,2022-06-15,2021-06-07
-7n6g,2022-05-18,2021-06-08
-5n6a,2017-08-09,2017-02-14
-6n6g,2019-06-12,2018-11-26
-1n6d,2002-12-30,2002-11-10
-1n6x,2003-03-04,2002-11-12
-2n6a,2015-08-26,2015-08-14
-7n6q,2021-09-22,2021-06-08
-3n68,2011-02-09,2010-05-25
-4n6n,2015-02-18,2013-10-14
-3n6h,2010-07-21,2010-05-25
-1n67,2003-03-04,2002-11-08
-6n60,2019-01-09,2018-11-23
-1n6h,2002-11-27,2002-11-11
-7n64,2021-08-04,2021-06-07
-1n61,2002-12-18,2002-11-08
-7n67,2021-06-23,2021-06-07
-6n6x,2018-12-19,2018-11-27
-4n64,2013-12-18,2013-10-11
-1n6c,2003-02-04,2002-11-09
-3n67,2011-02-09,2010-05-25
-5n6x,2017-04-19,2017-02-16
-5n61,2017-04-05,2017-02-14
-6n6h,2019-06-12,2018-11-26
-7n68,2022-06-08,2021-06-07
-3n6w,2010-07-21,2010-05-26
-7n65,2021-07-28,2021-06-07
-6n6p,2019-12-25,2018-11-26
-3n62,2011-02-09,2010-05-25
-5n69,2017-08-16,2017-02-14
-1n6q,2003-01-14,2002-11-11
-1n6i,2002-11-27,2002-11-11
-1n63,2002-12-18,2002-11-08
-3n6g,2011-02-09,2010-05-25
-4n62,2013-12-18,2013-10-11
-6n6j,2019-06-12,2018-11-26
-5n66,2017-09-20,2017-02-14
-1n6l,2002-11-27,2002-11-11
-4n66,2014-04-02,2013-10-11
-5n67,2017-09-20,2017-02-14
-6n6v,2018-12-19,2018-11-27
-3n6d,2011-02-09,2010-05-25
-6n6e,2019-06-12,2018-11-26
-5n6i,2017-09-13,2017-02-15
-3n64,2011-02-09,2010-05-25
-3n6e,2011-02-09,2010-05-25
-6n6d,2019-06-12,2018-11-26
-5n6y,2017-07-26,2017-02-16
-7n6i,2021-07-28,2021-06-08
-6n6y,2018-12-19,2018-11-27
-3n6r,2010-08-25,2010-05-26
-1n6a,2003-02-04,2002-11-09
-3n6i,2011-12-14,2010-05-25
-7n6u,2021-09-22,2021-06-09
-4n6o,2015-02-11,2013-10-14
-4n60,2013-12-18,2013-10-11
-4n6s,2014-01-22,2013-10-14
-3n6m,2011-06-15,2010-05-26
-1n6f,2002-12-30,2002-11-10
-3n66,2011-02-09,2010-05-25
-3n61,2011-02-09,2010-05-25
-4n61,2013-12-18,2013-10-11
-7n6x,2021-09-08,2021-06-09
-4n6h,2013-12-25,2013-10-12
-2n63,2016-03-23,2015-08-11
-3n6l,2011-06-15,2010-05-26
-5n63,2017-09-20,2017-02-14
-7n6d,2021-07-28,2021-06-08
-4n6z,2013-11-06,2013-10-14
-5n62,2018-03-07,2017-02-14
-7n6e,2021-07-28,2021-06-08
-6n6i,2019-06-12,2018-11-26
-3n65,2011-02-09,2010-05-25
-1n6m,2003-10-28,2002-11-11
-5n60,2017-04-05,2017-02-14
-7n6o,2022-08-17,2021-06-08
-7n6v,2021-09-08,2021-06-09
-3n6b,2011-02-09,2010-05-25
-3n6n,2011-06-15,2010-05-26
-3n60,2011-02-09,2010-05-25
-3n6u,2011-06-01,2010-05-26
-3n6q,2011-06-15,2010-05-26
-6n63,2019-07-17,2018-11-24
-3n6k,2010-08-18,2010-05-26
-3n63,2011-02-09,2010-05-25
-1n62,2002-12-18,2002-11-08
-6n6c,2019-06-12,2018-11-26
-5n6t,2017-03-01,2017-02-16
-6n67,2019-07-03,2018-11-26
-4n6y,2013-11-06,2013-10-14
-5n68,2017-09-20,2017-02-14
-3n6f,2011-02-09,2010-05-25
-1n6n,2002-11-27,2002-11-11
-3n69,2011-02-09,2010-05-25
-7n6f,2022-07-27,2021-06-08
-5n6o,2017-12-27,2017-02-15
-1n6k,2002-11-27,2002-11-11
-5n6g,2017-05-17,2017-02-15
-5n6u,2017-04-12,2017-02-16
-5n6f,2018-03-07,2017-02-15
-6n6u,2018-12-19,2018-11-27
-4n6b,2013-11-13,2013-10-11
-7n6k,2021-06-23,2021-06-08
-1n65,2003-11-18,2002-11-08
-5n65,2017-09-20,2017-02-14
-6n6o,2019-05-15,2018-11-26
-6n6a,2019-06-12,2018-11-26
-4n67,2014-09-24,2013-10-11
-4n6k,2013-11-13,2013-10-13
-3n6a,2011-02-09,2010-05-25
-7n63,2021-06-23,2021-06-07
-1xil,2005-03-08,2004-09-21
-7xiy,2022-07-13,2022-04-14
-4xia,1990-04-15,1989-07-05
-1xis,1992-07-15,1991-03-25
-1xif,1994-06-22,1994-03-07
-1xik,1997-03-12,1996-08-06
-2xio,2010-07-14,2010-06-30
-7xix,2022-07-13,2022-04-14
-1xie,1994-06-22,1994-03-07
-4xi6,2015-03-18,2015-01-06
-2xig,2011-01-19,2010-06-29
-5xiq,2018-03-07,2017-04-26
-5xi5,2017-10-18,2017-04-26
-1xib,1994-06-22,1994-03-07
-1xiu,2005-09-13,2004-09-22
-1xi1,2004-12-07,2004-09-21
-7xi0,2022-07-27,2022-04-11
-6xih,2020-08-12,2020-06-19
-4xi2,2015-02-25,2015-01-06
-4xin,2015-03-04,2015-01-07
-6xin,2021-06-23,2020-06-20
-2xib,2010-07-21,2010-06-28
-4xis,1992-07-15,1991-03-25
-6xid,2020-11-18,2020-06-19
-4xi7,2015-03-18,2015-01-06
-4xiu,2015-01-21,2015-01-07
-6xiz,2021-03-10,2020-06-22
-4xid,2015-11-25,2015-01-06
-7xij,2022-06-08,2022-04-13
-6xic,2020-11-18,2020-06-19
-7xid,2022-06-15,2022-04-12
-2xif,2010-07-07,2010-06-29
-5xip,2018-03-07,2017-04-26
-2xix,2011-02-23,2010-07-01
-7xih,2022-06-15,2022-04-13
-2xi4,2011-03-23,2010-06-28
-5xij,2018-03-07,2017-04-26
-2xiy,2011-02-23,2010-07-01
-6xij,2020-09-02,2020-06-20
-6xim,1993-07-15,1992-04-03
-9xim,1993-07-15,1992-04-03
-8xif,2024-05-01,2023-12-19
-1xig,1994-06-22,1994-03-07
-3xim,1993-04-15,1991-05-29
-5xin,1993-07-15,1992-04-06
-4xi5,2015-05-13,2015-01-06
-6xi1,2020-10-14,2020-06-19
-8xia,1991-10-15,1990-10-11
-4xix,2015-02-11,2015-01-08
-5xil,2018-03-07,2017-04-26
-4xig,2016-01-13,2015-01-07
-7xiz,2022-07-13,2022-04-14
-5xi3,2018-05-02,2017-04-25
-7xin,2023-04-19,2022-04-13
-4xic,2015-11-25,2015-01-06
-5xis,2018-03-07,2017-04-27
-6xio,2021-01-20,2020-06-20
-8xim,1993-07-15,1992-04-01
-7xiu,2022-04-27,2022-04-14
-2xiz,2011-02-23,2010-07-01
-7xiw,2022-07-13,2022-04-14
-6xii,2020-09-02,2020-06-20
-4xir,2015-03-04,2015-01-07
-1xic,1994-06-22,1994-03-07
-6xi9,2020-07-15,2020-06-19
-5xic,2017-12-06,2017-04-26
-4xiq,2015-03-04,2015-01-07
-1xih,1994-06-22,1994-03-07
-7xic,2022-06-15,2022-04-12
-2xim,1993-04-15,1991-05-29
-7xib,2022-11-30,2022-04-12
-5xiw,2018-04-18,2017-04-27
-2xiu,2011-02-09,2010-07-01
-3xis,1992-07-15,1991-03-25
-5xib,2017-12-06,2017-04-26
-6xi8,2021-04-28,2020-06-19
-1xim,1993-04-15,1991-05-29
-5xi7,2017-10-18,2017-04-26
-6xie,2020-11-18,2020-06-19
-1xi2,2005-08-30,2004-09-21
-2xij,2010-09-29,2010-06-30
-2xi3,2010-08-04,2010-06-25
-2xiq,2010-09-29,2010-06-30
-6xib,2020-11-18,2020-06-19
-4xiy,2015-04-22,2015-01-07
-5xio,2018-03-07,2017-04-26
-7xig,2022-06-15,2022-04-13
-2xi7,2010-10-06,2010-06-28
-2xil,2010-07-14,2010-06-30
-5xih,2018-03-07,2017-04-26
-4xif,2015-08-05,2015-01-06
-6xi7,2021-01-13,2020-06-19
-5xit,2018-03-07,2017-04-27
-4xip,2015-03-04,2015-01-07
-6xiw,2020-07-29,2020-06-22
-6xiq,2020-08-26,2020-06-21
-8xig,2024-05-01,2023-12-19
-8xiy,2024-02-07,2023-12-20
-7xit,2022-04-27,2022-04-14
-4xi3,2016-01-13,2015-01-06
-2xi5,2010-10-06,2010-06-28
-6xir,2020-08-26,2020-06-21
-1xiv,2005-06-21,2004-09-22
-4xim,1993-07-15,1992-03-11
-7xi9,2022-11-30,2022-04-12
-6xif,2020-11-18,2020-06-19
-4xil,2016-01-20,2015-01-07
-1xid,1994-06-22,1994-03-07
-4xiv,2015-11-04,2015-01-07
-6xi0,2020-12-30,2020-06-19
-4xib,2015-03-18,2015-01-06
-2xih,2010-07-07,2010-06-29
-1xi9,2004-11-23,2004-09-21
-5xii,2018-03-07,2017-04-26
-5xi2,2018-05-02,2017-04-25
-2xir,2011-04-13,2010-06-30
-5xim,1993-07-15,1992-03-30
-1xin,1993-07-15,1992-04-06
-6xi2,2021-04-21,2020-06-19
-6xi3,2020-10-14,2020-06-19
-5xia,1990-04-15,1989-07-05
-2xin,1993-07-15,1992-04-06
-1xi3,2004-09-28,2004-09-21
-4xiw,2015-02-11,2015-01-07
-7xif,2022-06-15,2022-04-13
-8xi6,2024-04-24,2023-12-19
-5xik,2018-03-07,2017-04-26
-1xio,2004-10-05,2004-09-21
-7xii,2022-06-15,2022-04-13
-6xiy,2021-03-31,2020-06-22
-1xii,1994-06-22,1994-03-07
-2xik,2010-07-14,2010-06-30
-7xil,2023-04-26,2022-04-13
-7xi7,2022-06-29,2022-04-12
-9xia,1991-10-15,1990-10-11
-2xi6,2010-07-14,2010-06-29
-5xie,2017-12-06,2017-04-26
-5xi4,2018-05-02,2017-04-25
-4xii,2015-07-08,2015-01-07
-6xit,2020-10-07,2020-06-21
-1xij,1994-06-22,1994-03-07
-2xii,2010-07-21,2010-06-30
-4xi9,2015-08-05,2015-01-06
-4xit,2015-03-04,2015-01-07
-5xig,2018-03-07,2017-04-26
-7xis,2022-04-27,2022-04-14
-2xis,1992-07-15,1991-03-25
-1d1k,2000-09-20,1999-09-17
-7d1e,2021-04-14,2020-09-14
-5d1t,2015-11-11,2015-08-04
-8d1r,2022-09-14,2022-05-27
-3d1z,2008-05-27,2008-05-07
-2d1f,2006-09-05,2005-08-20
-7d1h,2021-04-14,2020-09-14
-5d1v,2016-08-10,2015-08-04
-5d13,2016-08-17,2015-08-03
-6d14,2018-04-25,2018-04-11
-8d14,2022-09-07,2022-05-26
-4d1w,2014-06-25,2014-05-05
-3d1x,2008-06-03,2008-05-06
-8d1f,2022-07-13,2022-05-27
-3d1e,2008-07-29,2008-05-05
-5d1f,2016-02-24,2015-08-04
-6d1f,2019-04-17,2018-04-11
-3d1g,2008-07-29,2008-05-05
-4d1b,2014-07-02,2014-05-01
-3d1v,2009-07-14,2008-05-06
-6d1z,2018-05-02,2018-04-12
-1d1g,2000-03-31,1999-09-16
-2d1e,2006-01-24,2005-08-17
-4d13,2014-10-29,2014-05-01
-2d1j,2006-08-24,2005-08-24
-7d1d,2021-04-14,2020-09-14
-1d1v,2001-07-25,1999-09-21
-1d1u,2000-04-02,1999-09-21
-8d13,2022-09-07,2022-05-26
-5d1d,2015-10-21,2015-08-04
-4d1t,2014-06-25,2014-05-05
-5d1k,2015-10-28,2015-08-04
-5d10,2015-09-02,2015-08-03
-5d1p,2016-03-09,2015-08-04
-7d1p,2021-04-14,2020-09-15
-4d17,2014-11-05,2014-05-01
-5d1n,2016-04-20,2015-08-04
-8d1h,2022-07-13,2022-05-27
-5d1r,2015-09-30,2015-08-04
-5d1o,2016-03-09,2015-08-04
-6d19,2019-04-17,2018-04-11
-4d1j,2014-05-28,2014-05-02
-6d17,2019-04-17,2018-04-11
-4d1q,2014-07-30,2014-05-04
-5d1j,2015-08-12,2015-08-04
-5d1m,2015-10-28,2015-08-04
-1d1w,2000-10-25,1999-09-21
-2d1x,2006-04-25,2005-09-01
-4d1c,2014-07-02,2014-05-01
-2d1k,2006-09-12,2005-08-26
-8d1v,2022-11-02,2022-05-27
-4d1l,2014-08-27,2014-05-02
-8d1l,2022-07-13,2022-05-27
-2d1t,2006-03-21,2005-08-31
-2d1n,2006-06-27,2005-08-29
-7d1n,2021-04-14,2020-09-15
-6d1c,2019-04-17,2018-04-11
-8d1s,2023-05-31,2022-05-27
-3d1r,2008-12-23,2008-05-06
-6d1a,2019-04-17,2018-04-11
-8d1e,2022-07-13,2022-05-27
-3d1i,2009-05-12,2008-05-06
-8d1w,2023-05-31,2022-05-27
-3d1f,2008-07-29,2008-05-05
-8d1k,2022-07-13,2022-05-27
-6d1k,2019-04-17,2018-04-11
-4d1v,2014-06-25,2014-05-05
-5d1s,2015-11-11,2015-08-04
-1d1y,2001-07-25,1999-09-21
-8d1q,2023-05-31,2022-05-27
-8d10,2022-12-07,2022-05-26
-6d1e,2019-04-17,2018-04-11
-4d1d,2014-07-02,2014-05-01
-3d1a,2009-05-12,2008-05-05
-3d18,2009-05-05,2008-05-05
-7d1x,2021-09-22,2020-09-15
-3d10,2009-04-14,2008-05-02
-5d15,2016-08-10,2015-08-03
-4d1n,2014-10-15,2014-05-02
-6d15,2019-04-17,2018-04-11
-6d1j,2019-04-17,2018-04-11
-5d1b,2015-10-21,2015-08-04
-4d12,2014-10-29,2014-05-01
-8d1y,2023-05-31,2022-05-27
-3d17,2008-06-03,2008-05-05
-8d11,2022-12-07,2022-05-26
-4d1m,2014-08-27,2014-05-02
-7d1v,2021-07-28,2020-09-15
-6d1i,2019-04-17,2018-04-11
-3d1m,2008-09-23,2008-05-06
-7d18,2021-04-14,2020-09-14
-3d1k,2008-08-05,2008-05-06
-2d1y,2006-03-02,2005-09-02
-4d11,2014-05-28,2014-05-01
-4d1p,2014-10-15,2014-05-02
-6d16,2019-04-17,2018-04-11
-1d1s,1999-09-29,1999-09-21
-7d1t,2021-03-31,2020-09-15
-5d1c,2015-10-21,2015-08-04
-7d1c,2021-01-27,2020-09-14
-6d1u,2018-09-05,2018-04-12
-1d1q,2000-03-08,1999-09-20
-6d1g,2019-04-17,2018-04-11
-1d1i,2000-09-20,1999-09-17
-5d18,2015-10-07,2015-08-04
-6d1y,2018-05-02,2018-04-12
-8d15,2022-09-07,2022-05-26
-2d1c,2006-10-10,2005-08-15
-3d14,2008-08-26,2008-05-04
-8d1c,2023-03-01,2022-05-27
-8d16,2022-09-07,2022-05-26
-5d1u,2015-11-11,2015-08-04
-8d1t,2023-02-01,2022-05-27
-6d1d,2019-04-17,2018-04-11
-3d1l,2008-07-08,2008-05-06
-7d1y,2021-04-14,2020-09-15
-6d1h,2019-04-17,2018-04-11
-3d15,2009-05-12,2008-05-04
-3d1y,2008-05-27,2008-05-06
-4d1o,2014-10-15,2014-05-02
-4d1z,2015-03-18,2014-05-05
-7d11,2021-09-15,2020-09-12
-5d1l,2015-10-28,2015-08-04
-7d1f,2021-09-15,2020-09-14
-5d12,2015-09-09,2015-08-03
-8d1i,2022-07-13,2022-05-27
-2d1s,2006-03-21,2005-08-31
-7d1b,2021-04-14,2020-09-14
-6d1l,2018-06-13,2018-04-12
-4d1u,2014-06-25,2014-05-05
-4d1x,2015-03-18,2014-05-05
-4d19,2014-10-29,2014-05-01
-6d1b,2019-04-17,2018-04-11
-4d18,2014-07-23,2014-05-01
-8d1x,2022-06-08,2022-05-27
-5d11,2015-09-09,2015-08-03
-6d1p,2018-10-17,2018-04-12
-8d12,2022-12-07,2022-05-26
-6d18,2019-04-17,2018-04-11
-7d1m,2020-10-28,2020-09-14
-7d17,2021-04-14,2020-09-14
-4d10,2014-07-23,2014-04-30
-8d18,2022-09-07,2022-05-26
-4d1i,2014-05-28,2014-05-02
-4d1a,2014-07-02,2014-05-01
-4d1s,2014-07-23,2014-05-05
-2d1w,2006-05-02,2005-09-01
-8d1p,2023-05-31,2022-05-27
-7d1o,2020-09-23,2020-09-15
-4d1y,2014-10-22,2014-05-05
-2d1r,2006-03-21,2005-08-31
-8d19,2023-01-25,2022-05-26
-6d1x,2018-05-02,2018-04-12
-7d19,2021-01-27,2020-09-14
-2d1o,2006-06-27,2005-08-30
-7d1u,2021-03-31,2020-09-15
-8d1n,2022-07-13,2022-05-27
-6d1w,2018-06-27,2018-04-12
-8d1j,2022-07-13,2022-05-27
-3d12,2008-08-19,2008-05-02
-8d1u,2022-06-15,2022-05-27
-6d1v,2018-05-23,2018-04-12
-7d1g,2021-03-17,2020-09-14
-3d19,2008-07-08,2008-05-05
-8d1o,2022-07-13,2022-05-27
-8d1g,2022-07-13,2022-05-27
-2d16,2006-10-31,2005-08-14
-6d1m,2018-06-13,2018-04-12
-8d17,2022-09-07,2022-05-26
-1d1t,1999-09-29,1999-09-21
-1d1x,2001-07-25,1999-09-21
-3d11,2008-08-19,2008-05-02
-2d1q,2006-03-21,2005-08-31
-8d1d,2022-09-21,2022-05-27
-6z2q,2020-09-30,2020-05-18
-7z2g,2022-07-20,2022-02-26
-6z2o,2020-09-30,2020-05-18
-4z2a,2016-05-04,2015-03-29
-4z2s,2015-07-01,2015-03-30
-4z2j,2015-07-01,2015-03-30
-1z2b,2005-05-31,2005-03-08
-6z2x,2020-11-11,2020-05-18
-7z2k,2023-03-22,2022-02-28
-6z2v,2020-07-29,2020-05-18
-6z2d,2020-09-30,2020-05-15
-7z2v,2022-11-30,2022-02-28
-4z26,2015-05-13,2015-03-28
-6z2n,2021-01-20,2020-05-18
-4z2w,2016-01-13,2015-03-30
-2z2z,2007-12-04,2007-05-29
-7z2u,2022-11-30,2022-02-28
-1z2n,2005-04-19,2005-03-08
-4z2t,2015-08-19,2015-03-30
-4z2k,2015-07-01,2015-03-30
-5z2f,2018-06-27,2018-01-02
-5z2b,2019-01-02,2018-01-02
-5z2l,2018-03-07,2018-01-03
-6z24,2020-12-23,2020-05-14
-6z2z,2021-06-02,2020-05-19
-6z2s,2021-06-09,2020-05-18
-2z2a,2007-10-09,2007-05-17
-2z27,2007-10-09,2007-05-17
-7z2y,2022-03-16,2022-03-01
-2z29,2007-10-09,2007-05-17
-1z2a,2005-07-26,2005-03-07
-2z23,2007-10-30,2007-05-17
-4z28,2015-07-15,2015-03-29
-7z2l,2023-03-22,2022-02-28
-1z2w,2005-06-21,2005-03-10
-1z2c,2005-05-10,2005-03-08
-6z23,2020-12-23,2020-05-14
-5z21,2018-09-19,2017-12-28
-5z2v,2019-01-02,2018-01-04
-5z25,2018-03-07,2017-12-28
-4z24,2015-04-15,2015-03-28
-7z2c,2022-10-19,2022-02-26
-4z2r,2015-08-19,2015-03-30
-1z25,2005-04-05,2005-03-07
-6z2w,2020-11-11,2020-05-18
-6z2h,2021-05-26,2020-05-15
-5z2x,2019-01-02,2018-01-04
-7z2i,2022-05-25,2022-02-27
-1z22,2005-07-26,2005-03-07
-7z2j,2022-11-02,2022-02-28
-2z2x,2007-12-04,2007-05-29
-7z25,2022-05-25,2022-02-25
-1z2i,2005-03-15,2005-03-08
-5z2w,2019-01-02,2018-01-04
-2z24,2007-10-09,2007-05-17
-7z2z,2023-04-05,2022-03-01
-1z24,2005-04-05,2005-03-07
-7z2n,2022-08-31,2022-02-28
-2z2f,2008-05-27,2007-05-21
-4z2g,2015-07-01,2015-03-30
-4z25,2015-06-03,2015-03-28
-1z2m,2005-05-24,2005-03-08
-4z2q,2015-07-01,2015-03-30
-6z2m,2020-06-03,2020-05-17
-2z26,2007-10-09,2007-05-17
-6z2b,2021-03-17,2020-05-15
-2z25,2007-10-09,2007-05-17
-1z2u,2005-03-22,2005-03-09
-2z2p,2007-06-19,2007-05-25
-7z2e,2022-07-20,2022-02-26
-6z2k,2020-07-08,2020-05-16
-6z2p,2020-09-30,2020-05-18
-4z20,2016-03-30,2015-03-27
-5z28,2018-05-02,2017-12-30
-4z2h,2015-07-01,2015-03-30
-5z22,2019-01-30,2017-12-28
-7z2b,2022-11-16,2022-02-26
-6z27,2020-12-02,2020-05-15
-7z2o,2023-01-25,2022-02-28
-2z2c,2008-05-20,2007-05-17
-7z2h,2022-07-20,2022-02-27
-4z2l,2015-07-01,2015-03-30
-5z27,2019-01-02,2017-12-29
-7z2a,2022-10-19,2022-02-26
-7z29,2022-07-20,2022-02-26
-5z2c,2018-08-22,2018-01-02
-4z2d,2016-09-14,2015-03-29
-4z22,2016-01-13,2015-03-28
-2z2y,2007-12-04,2007-05-29
-6z2f,2021-05-26,2020-05-15
-6z2a,2021-05-26,2020-05-15
-5z20,2018-09-19,2017-12-28
-4z2y,2015-07-22,2015-03-30
-7z2d,2022-07-20,2022-02-26
-6z28,2020-05-27,2020-05-15
-7z2p,2022-08-31,2022-02-28
-2z2d,2007-11-20,2007-05-18
-7z24,2022-07-20,2022-02-25
-4z2c,2016-09-14,2015-03-29
-5z2e,2018-06-27,2018-01-02
-1z2l,2005-03-22,2005-03-08
-2z2m,2007-09-04,2007-05-23
-7z26,2022-03-16,2022-02-25
-2z2b,2007-10-09,2007-05-17
-7z28,2022-07-27,2022-02-26
-5z2m,2018-08-08,2018-01-03
-2z2s,2008-02-05,2007-05-26
-5z2p,2018-11-28,2018-01-03
-5z2r,2018-11-28,2018-01-03
-6z2e,2020-06-17,2020-05-15
-7z2s,2022-03-16,2022-02-28
-4z2i,2015-07-01,2015-03-30
-2z2w,2008-05-06,2007-05-29
-6z2c,2021-05-26,2020-05-15
-5z2u,2018-11-28,2018-01-04
-4z2e,2016-09-14,2015-03-29
-1z2p,2005-04-19,2005-03-08
-1z28,2006-05-30,2005-03-07
-5z2k,2018-10-03,2018-01-02
-1z2o,2005-04-19,2005-03-08
-1z29,2006-05-30,2005-03-07
-2z20,2007-07-17,2007-05-17
-6z2j,2020-07-08,2020-05-16
-2z28,2007-10-09,2007-05-17
-6z25,2020-12-23,2020-05-14
-4z2u,2015-08-19,2015-03-30
-5z2g,2018-06-20,2018-01-02
-4z2b,2015-06-17,2015-03-29
-7z2q,2023-01-25,2022-02-28
-1r7o,2003-11-11,2003-10-22
-7r78,2022-02-23,2021-06-24
-1r76,2004-06-01,2003-10-20
-2r71,2007-10-02,2007-09-07
-3r7c,2012-03-28,2011-03-22
-8r74,2024-06-05,2023-11-23
-7r7e,2022-07-06,2021-06-24
-7r7n,2021-07-21,2021-06-25
-1r79,2004-04-21,2003-10-21
-3r7l,2011-06-08,2011-03-22
-3r73,2012-08-08,2011-03-22
-2r7y,2008-05-06,2007-09-10
-1r7u,2004-02-10,2003-10-22
-4r7p,2015-04-22,2014-08-28
-7r71,2022-03-09,2021-06-24
-2r79,2007-10-09,2007-09-07
-3r77,2011-03-30,2011-03-22
-3r7y,2012-08-08,2011-03-23
-7r7r,2022-06-29,2021-06-25
-6r7y,2019-05-01,2019-03-29
-5r7x,2020-04-22,2020-03-16
-3r7r,2011-08-03,2011-03-22
-2r7k,2007-12-04,2007-09-09
-4r7u,2014-09-24,2014-08-28
-5r7y,2020-03-11,2020-03-03
-6r79,2020-04-01,2019-03-28
-3r7m,2012-05-02,2011-03-22
-3r7q,2011-08-03,2011-03-22
-4r7y,2014-10-08,2014-08-28
-7r75,2021-10-27,2021-06-24
-3r7v,2012-08-08,2011-03-23
-1r7v,2004-02-10,2003-10-22
-3r7o,2012-02-01,2011-03-22
-2r7v,2008-07-29,2007-09-10
-7r72,2022-11-09,2021-06-24
-2r7e,2008-04-15,2007-09-07
-7r73,2022-03-30,2021-06-24
-7r7j,2022-04-13,2021-06-24
-6r7i,2019-08-28,2019-03-28
-4r7i,2015-08-12,2014-08-27
-3r7b,2011-07-27,2011-03-22
-4r78,2015-08-12,2014-08-27
-6r7k,2019-07-03,2019-03-29
-6r7x,2019-05-01,2019-03-29
-7r7s,2021-08-04,2021-06-25
-7r7p,2023-02-15,2021-06-25
-6r7v,2019-11-13,2019-03-29
-3r71,2012-08-08,2011-03-22
-4r7o,2014-09-10,2014-08-28
-4r79,2015-04-22,2014-08-27
-2r7t,2008-07-29,2007-09-10
-6r77,2019-07-03,2019-03-28
-4r7g,2015-01-21,2014-08-27
-4r74,2015-08-12,2014-08-26
-6r7j,2019-07-03,2019-03-29
-2r7a,2007-10-09,2007-09-07
-6r7u,2020-02-05,2019-03-29
-2r7p,2007-10-23,2007-09-09
-7r7d,2021-10-27,2021-06-24
-7r7f,2022-07-06,2021-06-24
-7r7a,2022-11-09,2021-06-24
-4r73,2015-08-12,2014-08-26
-3r76,2011-03-30,2011-03-22
-1r7t,2004-02-10,2003-10-22
-4r7c,2015-07-01,2014-08-27
-2r72,2007-11-27,2007-09-07
-2r74,2007-11-20,2007-09-07
-4r75,2015-08-12,2014-08-26
-4r7l,2015-11-25,2014-08-27
-4r7h,2015-08-12,2014-08-27
-2r7x,2008-07-29,2007-09-10
-6r7b,2019-10-02,2019-03-28
-6r7w,2019-11-13,2019-03-29
-1r78,2004-01-20,2003-10-20
-2r7w,2008-07-29,2007-09-10
-8r7g,2024-04-03,2023-11-24
-2r7g,2007-10-02,2007-09-07
-2r7u,2008-07-29,2007-09-10
-3r79,2011-04-06,2011-03-22
-7r7g,2022-07-06,2021-06-24
-5r7z,2020-03-11,2020-03-03
-1r7m,2004-10-26,2003-10-21
-6r78,2020-04-01,2019-03-28
-3r7w,2011-08-24,2011-03-23
-7r7k,2022-06-29,2021-06-24
-3r7e,2012-08-08,2011-03-22
-2r7z,2007-11-20,2007-09-10
-6r71,2020-04-08,2019-03-28
-3r7u,2012-08-08,2011-03-23
-4r7t,2014-10-01,2014-08-28
-6r7s,2020-04-08,2019-03-29
-7r7w,2022-06-29,2021-06-25
-2r7d,2007-10-02,2007-09-07
-2r7m,2007-12-04,2007-09-09
-4r7z,2014-10-08,2014-08-28
-4r7j,2014-09-17,2014-08-27
-7r7y,2022-06-29,2021-06-25
-1r7x,2004-02-10,2003-10-22
-6r7n,2019-08-28,2019-03-29
-2r7l,2007-12-04,2007-09-09
-6r73,2020-03-25,2019-03-28
-4r70,2015-07-15,2014-08-26
-3r7i,2012-08-08,2011-03-22
-4r7m,2014-10-29,2014-08-28
-7r74,2022-03-30,2021-06-24
-4r7w,2014-09-17,2014-08-28
-7r76,2022-02-23,2021-06-24
-6r7r,2019-04-17,2019-03-29
-4r7f,2014-12-17,2014-08-27
-2r7b,2008-09-09,2007-09-07
-2r7s,2008-07-29,2007-09-10
-6r7q,2019-07-10,2019-03-29
-6r7p,2019-06-26,2019-03-29
-7r7x,2022-06-29,2021-06-25
-4r7e,2015-05-13,2014-08-27
-4r76,2014-10-29,2014-08-27
-2r75,2008-07-22,2007-09-07
-7r7i,2021-10-27,2021-06-24
-4r7a,2015-01-14,2014-08-27
-6r72,2020-05-06,2019-03-28
-7r70,2022-03-09,2021-06-24
-2r7n,2007-12-04,2007-09-09
-6r7d,2019-08-28,2019-03-28
-1r7r,2003-12-16,2003-10-22
-3r7p,2011-07-20,2011-03-22
-7r7o,2022-06-29,2021-06-25
-7r7t,2021-08-04,2021-06-25
-3r7n,2011-07-27,2011-03-22
-7r7l,2021-10-27,2021-06-24
-3r7x,2011-05-18,2011-03-23
-1r7y,2004-02-10,2003-10-22
-3r72,2012-04-04,2011-03-22
-8r7m,2024-01-17,2023-11-26
-3r75,2011-03-30,2011-03-22
-6r7a,2019-07-03,2019-03-28
-7r7h,2021-09-01,2021-06-24
-7r7v,2022-06-29,2021-06-25
-7r77,2022-02-23,2021-06-24
-2r7r,2008-07-29,2007-09-09
-3r7k,2011-04-13,2011-03-22
-2bmr,2005-05-04,2005-03-15
-4bmm,2014-06-11,2013-05-09
-3bm9,2008-07-08,2007-12-12
-5bms,2015-07-01,2015-05-22
-5bmi,2016-04-06,2015-05-22
-6bm2,2018-02-28,2017-11-13
-1bma,1995-12-07,1995-05-01
-6bm9,2018-11-21,2017-11-13
-1bm1,1999-04-27,1998-07-28
-7bmu,2021-10-06,2021-01-20
-6bma,2017-11-29,2017-11-14
-4bm4,2014-01-15,2013-05-05
-3bmy,2008-07-08,2007-12-13
-8bms,2023-08-02,2022-11-10
-7bmt,2021-10-06,2021-01-20
-7bmc,2022-03-02,2021-01-19
-7bmr,2021-10-06,2021-01-20
-2bmb,2006-01-17,2005-03-11
-6bm7,2018-01-03,2017-11-13
-7bmp,2021-10-06,2021-01-20
-3bmo,2008-12-16,2007-12-13
-2bm2,2005-03-22,2005-03-09
-1bmk,1999-07-23,1998-07-23
-7bm7,2022-03-02,2021-01-19
-2bme,2005-04-25,2005-03-13
-1bmd,1994-07-31,1992-11-10
-5bml,2015-06-10,2015-05-22
-2bmi,1998-09-23,1998-09-17
-5bmm,2016-09-21,2015-05-22
-2bmh,1994-07-31,1994-05-17
-6bm5,2018-05-23,2017-11-13
-3bm6,2009-02-17,2007-12-12
-7bmo,2021-10-06,2021-01-20
-8bm2,2023-11-22,2022-11-10
-7bmv,2021-10-06,2021-01-20
-4bm9,2013-06-12,2013-05-07
-5bmg,2016-04-06,2015-05-22
-1bmo,1997-10-15,1997-03-25
-1bm6,1999-07-29,1998-07-29
-8bmz,2023-08-16,2022-11-11
-4bmr,2014-03-19,2013-05-10
-6bmf,2017-12-06,2017-11-14
-5bmw,2015-07-29,2015-05-23
-7bmf,2022-08-03,2021-01-20
-7bmq,2021-10-06,2021-01-20
-1bm7,1998-08-05,1998-07-29
-4bmx,2013-09-11,2013-05-12
-7bms,2021-10-06,2021-01-20
-2bmu,2005-07-25,2005-03-16
-8bmu,2023-11-22,2022-11-11
-7bm0,2022-03-02,2021-01-19
-4bmv,2014-03-19,2013-05-10
-4bmq,2014-03-19,2013-05-10
-6bme,2017-12-20,2017-11-14
-8bmd,2023-08-09,2022-11-10
-1bmb,1998-07-29,1998-07-23
-6bmn,2018-01-24,2017-11-15
-8bm3,2023-11-22,2022-11-10
-3bm1,2008-01-01,2007-12-12
-2bmm,2005-07-20,2005-03-15
-2bm6,2005-06-07,2005-03-09
-7bmx,2021-10-06,2021-01-20
-5bmp,2016-06-01,2015-05-22
-3bm4,2008-05-20,2007-12-12
-6bmx,2018-01-17,2017-11-15
-2bmd,2005-04-25,2005-03-13
-4bm2,2014-01-15,2013-05-05
-7bm9,2022-03-02,2021-01-19
-8bmo,2023-08-09,2022-11-10
-2bml,2005-03-30,2005-03-15
-3bm5,2008-04-01,2007-12-12
-7bmi,2021-06-02,2021-01-20
-4bmo,2014-03-19,2013-05-10
-7bmg,2021-04-07,2021-01-20
-6bmz,2018-09-19,2017-11-15
-6bmb,2017-12-20,2017-11-14
-4bm1,2014-01-15,2013-05-05
-8bmy,2023-08-16,2022-11-11
-4bmz,2013-09-11,2013-05-12
-4bmb,2014-03-19,2013-05-07
-4bmj,2013-11-20,2013-05-09
-6bmy,2018-01-17,2017-11-15
-8bm8,2024-06-05,2022-11-10
-8bm0,2023-08-09,2022-11-10
-6bmw,2018-01-17,2017-11-15
-2bmg,2006-03-08,2005-03-14
-4bm3,2014-01-15,2013-05-05
-3bmc,2008-12-16,2007-12-13
-5bmh,2016-04-06,2015-05-22
-2bm0,2005-05-04,2005-03-09
-7bm4,2022-03-02,2021-01-19
-5bmx,2015-07-29,2015-05-24
-7bmd,2022-03-02,2021-01-20
-5bmo,2015-06-10,2015-05-22
-6bmq,2018-09-26,2017-11-15
-2bmy,2005-06-16,2005-03-17
-8bmt,2023-08-09,2022-11-10
-3bmx,2008-12-16,2007-12-13
-8bmq,2023-08-02,2022-11-10
-1bmt,1995-06-03,1994-09-02
-6bmu,2018-01-17,2017-11-15
-4bmt,2014-03-19,2013-05-10
-6bm6,2018-05-23,2017-11-13
-6bmc,2018-10-03,2017-11-14
-7bm3,2022-03-02,2021-01-19
-7bm8,2021-04-28,2021-01-19
-6bms,2018-01-10,2017-11-15
-6bm8,2018-05-16,2017-11-13
-4bmk,2013-09-04,2013-05-09
-7bmy,2021-10-06,2021-01-20
-7bm6,2021-07-14,2021-01-19
-7bmj,2021-06-02,2021-01-20
-5bmy,2016-10-26,2015-05-25
-1bmm,1996-12-07,1995-11-14
-2bmk,2006-03-03,2005-03-14
-3bmw,2008-05-27,2007-12-13
-4bmu,2014-03-19,2013-05-10
-1bmf,1996-12-07,1996-03-13
-8bm1,2023-08-09,2022-11-10
-4bm8,2014-05-21,2013-05-07
-2bmq,2005-05-04,2005-03-15
-5bmf,2015-07-29,2015-05-22
-2bm1,2005-05-04,2005-03-09
-4bm7,2013-07-03,2013-05-07
-3bmv,2008-05-27,2007-12-13
-4bme,2014-03-19,2013-05-07
-2bmz,2005-06-16,2005-03-17
-2bmw,2006-06-22,2005-03-16
-2bmo,2005-05-04,2005-03-15
-6bm4,2018-02-28,2017-11-13
-7bmk,2021-09-29,2021-01-20
-4bm0,2014-01-15,2013-05-05
-6bmg,2017-11-29,2017-11-14
-4bms,2014-03-19,2013-05-10
-7bm1,2022-03-02,2021-01-19
-8bm5,2023-03-29,2022-11-10
-1bmn,1996-12-07,1995-11-14
-6bml,2018-01-24,2017-11-15
-6bmr,2018-01-17,2017-11-15
-7bmb,2022-03-02,2021-01-19
-3bmq,2008-12-16,2007-12-13
-6bmk,2018-01-31,2017-11-15
-2bmc,2005-03-17,2005-03-11
-6bmi,2018-01-17,2017-11-14
-6bmv,2018-01-17,2017-11-15
-6bmh,2018-01-31,2017-11-14
-1bmq,1998-07-29,1998-07-24
-3bm8,2008-06-17,2007-12-12
-8bmp,2023-08-02,2022-11-10
-6bmm,2018-01-24,2017-11-15
-1bm2,1998-08-05,1998-07-27
-2bm9,2006-03-09,2005-03-10
-5bmv,2016-07-13,2015-05-23
-7bmz,2021-10-06,2021-01-20
-3bmn,2008-12-16,2007-12-13
-7bmw,2021-10-06,2021-01-20
-6bmt,2018-01-03,2017-11-15
-5bmn,2016-06-01,2015-05-22
-1bmc,1996-08-28,1995-06-16
-4bmp,2014-03-19,2013-05-10
-6n41,2018-12-05,2018-11-16
-3n42,2010-12-01,2010-05-21
-1n4h,2003-09-23,2002-10-31
-7n47,2022-06-08,2021-06-03
-3n4f,2010-06-09,2010-05-21
-6n4u,2019-02-06,2018-11-20
-4n4d,2014-09-17,2013-10-08
-7n4p,2022-06-15,2021-06-04
-3n4p,2010-10-06,2010-05-22
-4n4m,2013-12-11,2013-10-08
-4n4e,2014-04-02,2013-10-08
-1n40,2003-02-04,2002-10-30
-7n4f,2022-06-15,2021-06-04
-4n4f,2014-02-19,2013-10-08
-7n4i,2021-10-06,2021-06-04
-7n4e,2022-06-15,2021-06-04
-1n45,2002-11-13,2002-10-30
-4n4h,2014-03-05,2013-10-08
-5n4n,2018-02-28,2017-02-11
-7n4m,2021-11-10,2021-06-04
-5n4l,2017-12-13,2017-02-11
-7n41,2021-12-29,2021-06-03
-4n47,2014-01-15,2013-10-08
-1n4q,2003-11-18,2002-11-01
-7n4x,2021-09-01,2021-06-04
-4n4x,2014-09-17,2013-10-08
-3n41,2010-12-01,2010-05-21
-5n4w,2017-06-07,2017-02-11
-1n4k,2002-12-25,2002-10-31
-4n4k,2013-12-11,2013-10-08
-1n4w,2004-04-27,2002-11-01
-5n4s,2017-05-17,2017-02-11
-1n47,2003-02-25,2002-10-30
-6n4l,2019-02-13,2018-11-19
-5n4a,2018-02-28,2017-02-10
-3n4a,2011-05-25,2010-05-21
-1n4r,2003-11-18,2002-11-01
-1n4s,2003-11-18,2002-11-01
-7n42,2021-06-09,2021-06-03
-4n4g,2014-03-05,2013-10-08
-1n42,2003-02-04,2002-10-30
-6n4p,2019-11-20,2018-11-19
-4n4o,2013-12-11,2013-10-08
-6n4b,2019-01-30,2018-11-18
-6n43,2019-04-17,2018-11-16
-6n4n,2019-09-11,2018-11-19
-4n4b,2014-01-15,2013-10-08
-5n4t,2017-05-17,2017-02-11
-4n49,2014-01-22,2013-10-08
-1n46,2003-04-22,2002-10-30
-3n4b,2011-03-09,2010-05-21
-1n4a,2003-03-11,2002-10-30
-6n4t,2019-10-02,2018-11-20
-6n4w,2019-10-02,2018-11-20
-7n4y,2021-11-10,2021-06-04
-4n4j,2013-12-11,2013-10-08
-7n4w,2022-06-29,2021-06-04
-1n4u,2004-04-27,2002-11-01
-7n4j,2021-10-06,2021-06-04
-4n41,2014-01-15,2013-10-08
-5n4r,2018-02-28,2017-02-11
-5n4z,2018-02-28,2017-02-11
-4n4l,2013-12-11,2013-10-08
-1n4f,2003-05-06,2002-10-31
-4n4z,2014-02-05,2013-10-08
-1n4v,2004-04-27,2002-11-01
-4n4t,2013-12-11,2013-10-08
-1n44,2003-02-04,2002-10-30
-7n44,2021-07-21,2021-06-03
-5n4x,2018-02-28,2017-02-11
-3n4l,2010-11-24,2010-05-21
-6n4z,2019-10-02,2018-11-20
-3n4k,2010-06-23,2010-05-21
-1n4p,2003-11-18,2002-11-01
-7n4g,2022-06-15,2021-06-04
-3n40,2010-12-01,2010-05-21
-3n4q,2010-10-13,2010-05-22
-3n4c,2011-04-06,2010-05-21
-6n4m,2019-02-13,2018-11-19
-4n4r,2014-06-25,2013-10-08
-4n4s,2014-04-16,2013-10-08
-3n49,2010-08-18,2010-05-21
-6n48,2019-06-26,2018-11-17
-1n41,2003-02-04,2002-10-30
-3n4w,2010-12-01,2010-05-23
-4n4w,2014-01-22,2013-10-08
-5n49,2017-05-03,2017-02-10
-4n4y,2014-10-08,2013-10-08
-5n4o,2018-02-28,2017-02-11
-5n4u,2018-02-28,2017-02-11
-4n4v,2013-12-11,2013-10-08
-7n4k,2022-07-20,2021-06-04
-7n46,2023-07-05,2021-06-03
-6n4x,2019-01-23,2018-11-20
-6n4e,2019-03-27,2018-11-19
-6n4d,2019-01-30,2018-11-19
-6n42,2019-04-17,2018-11-16
-5n4i,2018-02-28,2017-02-10
-6n4y,2019-01-23,2018-11-20
-7n4s,2022-05-18,2021-06-04
-3n4e,2010-06-09,2010-05-21
-1n4g,2003-02-04,2002-10-31
-5n4y,2018-02-28,2017-02-11
-3n43,2010-12-01,2010-05-21
-7n4u,2021-09-01,2021-06-04
-4n48,2014-01-22,2013-10-08
-3n4m,2011-05-25,2010-05-21
-1n43,2003-09-02,2002-10-30
-6n47,2019-11-13,2018-11-17
-4n4i,2014-03-05,2013-10-08
-7n4r,2022-05-18,2021-06-04
-7n4z,2022-06-29,2021-06-04
-7n4q,2022-05-18,2021-06-04
-1n49,2003-01-07,2002-10-30
-1n48,2004-02-24,2002-10-30
-7n4v,2021-09-01,2021-06-04
-5n4v,2018-02-28,2017-02-11
-3n45,2010-08-18,2010-05-21
-3n46,2010-08-18,2010-05-21
-3n44,2010-12-01,2010-05-21
-4n4n,2013-12-11,2013-10-08
-7n4n,2021-10-06,2021-06-04
-8fo3,2023-05-24,2022-12-29
-1fob,2003-06-03,2000-08-27
-5fob,2016-04-06,2015-11-18
-2foi,2007-01-16,2006-01-13
-6foi,2019-01-30,2018-02-07
-5fox,2016-03-30,2015-11-26
-3fo0,2009-11-10,2008-12-27
-5fok,2016-05-11,2015-11-23
-8foh,2023-05-31,2022-12-30
-4fo9,2012-07-18,2012-06-20
-8foa,2023-05-24,2022-12-30
-3foz,2009-01-20,2009-01-02
-3fob,2009-01-06,2008-12-29
-4fo6,2012-07-11,2012-06-20
-4fof,2013-01-16,2012-06-20
-2foh,2006-04-18,2006-01-13
-7fog,2022-11-02,2022-08-26
-2fo4,2006-11-14,2006-01-12
-1fol,2001-07-20,2000-08-28
-6fop,2019-03-13,2018-02-08
-7fon,2022-11-02,2022-08-26
-1fo3,2001-01-17,2000-08-24
-8for,2024-01-10,2023-01-03
-3fow,2009-12-29,2009-01-02
-8fof,2023-05-31,2022-12-30
-7fox,2022-11-02,2022-08-26
-7foz,2022-11-02,2022-08-26
-7fot,2022-11-02,2022-08-26
-7foe,2022-11-02,2022-08-26
-6foq,2018-05-02,2018-02-08
-7fo8,2022-11-02,2022-08-26
-1fop,2001-07-20,2000-08-28
-3fo7,2009-01-20,2008-12-29
-4foa,2013-08-07,2012-06-20
-7foi,2022-11-02,2022-08-26
-3fo3,2009-12-29,2008-12-27
-8foz,2023-04-19,2023-01-03
-8fon,2023-03-29,2023-01-02
-2fob,2006-04-18,2006-01-13
-2fot,2006-09-05,2006-01-13
-7fok,2022-11-02,2022-08-26
-2foc,2006-04-18,2006-01-13
-7fo2,2022-11-02,2022-08-26
-1foo,2001-07-20,2000-08-28
-7fov,2022-11-02,2022-08-26
-5fot,2016-03-30,2015-11-26
-7foj,2022-11-02,2022-08-26
-8foq,2024-01-10,2023-01-03
-3fo1,2009-11-10,2008-12-27
-6foz,2019-08-21,2018-02-08
-7foo,2022-11-02,2022-08-26
-1fo6,2001-08-29,2000-08-25
-4fob,2012-07-11,2012-06-20
-2foa,2006-04-18,2006-01-13
-7fo9,2022-11-02,2022-08-26
-5fov,2016-03-30,2015-11-26
-7fou,2022-11-02,2022-08-26
-2fo9,2006-04-18,2006-01-13
-3fo9,2009-12-22,2008-12-29
-5foh,2016-12-07,2015-11-18
-2fof,2006-04-18,2006-01-13
-8fo6,2023-05-03,2022-12-29
-2fou,2006-04-04,2006-01-14
-4fox,2013-08-07,2012-06-21
-7fo7,2022-11-02,2022-08-26
-5fol,2016-08-03,2015-11-24
-2foz,2006-10-10,2006-01-15
-6fob,2018-05-16,2018-02-06
-4fow,2012-10-31,2012-06-21
-4fo0,2012-09-26,2012-06-20
-8foi,2023-09-20,2022-12-30
-2fov,2006-04-04,2006-01-14
-8fo7,2024-01-17,2022-12-29
-5foz,2016-10-05,2015-11-26
-3fog,2009-01-27,2008-12-30
-4fog,2013-08-07,2012-06-20
-7fol,2022-11-02,2022-08-26
-3for,2010-01-12,2008-12-31
-4fos,2012-12-26,2012-06-21
-3fod,2009-05-19,2008-12-29
-3foj,2009-01-20,2008-12-30
-4fon,2012-08-22,2012-06-20
-4fo8,2013-07-03,2012-06-20
-8fo9,2024-01-03,2022-12-30
-8fol,2023-05-24,2022-12-31
-5fow,2016-03-30,2015-11-26
-1foj,2001-11-16,2000-08-28
-3fol,2010-01-12,2008-12-30
-6fod,2018-05-16,2018-02-07
-2fos,2006-04-04,2006-01-13
-6fo0,2018-02-28,2018-02-05
-4for,2012-07-04,2012-06-21
-6fon,2019-01-30,2018-02-07
-6fow,2018-05-02,2018-02-08
-5fo8,2016-04-06,2015-11-18
-7foy,2022-11-02,2022-08-26
-7foh,2022-11-02,2022-08-26
-8fo2,2024-01-03,2022-12-29
-8fo0,2023-05-24,2022-12-29
-8fob,2023-05-24,2022-12-30
-7fos,2022-11-02,2022-08-26
-6fol,2019-01-30,2018-02-07
-2fo0,2006-03-21,2006-01-12
-7for,2022-11-02,2022-08-26
-4fok,2013-03-27,2012-06-20
-4foi,2013-07-03,2012-06-20
-8fos,2024-01-10,2023-01-03
-4foy,2012-10-31,2012-06-21
-3fof,2009-02-24,2008-12-30
-1foc,2000-11-08,2000-08-27
-7foq,2022-11-02,2022-08-26
-2fop,2006-02-14,2006-01-13
-4fom,2012-08-22,2012-06-20
-4fo4,2012-07-18,2012-06-20
-1fo0,2000-10-02,2000-08-24
-2fog,2006-04-18,2006-01-13
-3foo,2009-07-14,2008-12-30
-1fo4,2000-10-25,2000-08-24
-5foi,2016-07-27,2015-11-22
-6foy,2019-08-21,2018-02-08
-1foh,1998-06-17,1998-03-26
-7fo4,2022-11-02,2022-08-26
-6fof,2018-07-18,2018-02-07
-6fox,2019-08-21,2018-02-08
-7fow,2022-11-02,2022-08-26
-4foe,2013-07-03,2012-06-20
-2fo5,2006-07-18,2006-01-12
-3fom,2010-01-12,2008-12-30
-6fo2,2018-02-28,2018-02-05
-6fog,2018-11-07,2018-02-07
-7fo3,2022-11-02,2022-08-26
-2for,2006-01-31,2006-01-13
-2foy,2006-04-04,2006-01-14
-8fo4,2023-05-24,2022-12-29
-1fof,2000-10-09,2000-08-28
-4fo2,2012-11-21,2012-06-20
-6foc,2019-01-23,2018-02-06
-8fo8,2024-01-03,2022-12-29
-5foq,2016-03-02,2015-11-25
-7fom,2022-11-02,2022-08-26
-8fom,2023-03-29,2023-01-02
-4foj,2013-03-27,2012-06-20
-3fou,2009-10-20,2009-01-02
-7fop,2022-11-02,2022-08-26
-7fob,2022-11-02,2022-08-26
-2fol,2006-01-31,2006-01-13
-3foe,2009-02-24,2008-12-30
-4fo7,2013-07-03,2012-06-20
-7foc,2022-11-02,2022-08-26
-6foh,2018-11-07,2018-02-07
-8fog,2023-05-03,2022-12-30
-2fod,2006-04-18,2006-01-13
-5fog,2016-08-03,2015-11-20
-7fo0,2022-11-02,2022-08-26
-2fon,2006-05-23,2006-01-13
-7fo1,2022-11-02,2022-08-26
-1fo2,2001-01-17,2000-08-24
-5foo,2016-02-17,2015-11-24
-6fo8,2018-05-16,2018-02-06
-5foe,2016-01-27,2015-11-19
-1foi,2001-07-20,2000-08-28
-7fo5,2022-11-02,2022-08-26
-2foq,2006-02-28,2006-01-13
-6fo5,2018-06-20,2018-02-06
-3fo2,2009-11-10,2008-12-27
-2fo7,2006-03-07,2006-01-12
-6fo6,2018-02-28,2018-02-06
-8fo5,2023-05-24,2022-12-29
-6foo,2018-08-08,2018-02-08
-6fok,2019-03-13,2018-02-07
-2fox,1997-03-12,1997-01-08
-5fo7,2016-04-06,2015-11-18
-8fow,2023-05-31,2023-01-03
-6fo7,2018-05-16,2018-02-06
-2foe,2006-04-18,2006-01-13
-7fo6,2022-11-02,2022-08-26
-3fop,2009-07-14,2008-12-30
-1foa,2001-05-16,2000-08-26
-2foj,2006-02-14,2006-01-13
-7fod,2022-11-02,2022-08-26
-7fof,2022-11-02,2022-08-26
-5fou,2016-03-30,2015-11-26
-4foc,2012-07-11,2012-06-20
-5fo5,2016-06-08,2015-11-18
-4fod,2012-07-11,2012-06-20
-3fon,2010-01-12,2008-12-30
-6foa,2018-05-02,2018-02-06
-7foa,2022-11-02,2022-08-26
-4fou,2013-03-27,2012-06-21
-6fo1,2018-04-04,2018-02-05
-2foo,2006-02-14,2006-01-13
-6fos,2018-04-11,2018-02-08
-5fo9,2016-04-06,2015-11-18
-6fo9,2018-05-16,2018-02-06
-8fov,2023-08-30,2023-01-03
-6p08,2020-01-29,2019-05-16
-4p02,2014-04-09,2014-02-20
-1p0p,2003-08-05,2003-04-10
-8p07,2023-05-17,2023-05-09
-6p06,2020-01-29,2019-05-16
-6p0p,2020-03-25,2019-05-17
-3p0n,2010-10-20,2010-09-29
-6p0n,2020-03-04,2019-05-17
-6p0m,2020-03-04,2019-05-17
-6p02,2020-02-05,2019-05-16
-8p0b,2024-05-22,2023-05-10
-1p0d,2003-09-30,2003-04-10
-2p0h,2007-03-27,2007-02-28
-1p0b,2003-09-30,2003-04-10
-1p0f,2003-04-22,2003-04-10
-2p0r,2007-03-20,2007-03-01
-2p0m,2007-10-09,2007-02-28
-7p0w,2022-07-13,2021-06-30
-7p05,2021-11-10,2021-06-29
-6p0j,2020-03-04,2019-05-17
-8p0j,2024-05-22,2023-05-10
-7p01,2021-10-06,2021-06-29
-1p0y,2003-07-01,2003-04-11
-3p0e,2011-09-07,2010-09-28
-8p0o,2023-09-06,2023-05-10
-2p05,2007-06-05,2007-02-28
-1p03,1990-04-15,1989-04-24
-3p0q,2010-10-20,2010-09-29
-7p04,2021-11-10,2021-06-29
-1p0w,2003-12-09,2003-04-11
-3p0k,2011-12-07,2010-09-29
-7p0m,2021-08-11,2021-06-30
-3p0g,2011-01-19,2010-09-28
-4p0x,2014-07-02,2014-02-23
-7p0b,2021-08-11,2021-06-29
-6p0z,2019-07-31,2019-05-17
-4p00,2014-04-09,2014-02-19
-4p0a,2014-05-07,2014-02-20
-2p0x,2007-08-07,2007-03-01
-2p06,2007-03-27,2007-02-28
-7p0j,2022-07-13,2021-06-29
-7p0c,2022-02-09,2021-06-29
-6p07,2019-06-12,2019-05-16
-6p0c,2019-12-11,2019-05-16
-7p07,2021-10-06,2021-06-29
-1p0n,2003-06-17,2003-04-10
-7p0k,2022-07-13,2021-06-29
-7p02,2021-12-15,2021-06-29
-8p0m,2024-04-10,2023-05-10
-4p01,2014-03-19,2014-02-19
-6p0e,2019-12-11,2019-05-16
-2p0d,2007-03-27,2007-02-28
-7p0p,2022-05-25,2021-06-30
-7p0i,2022-06-15,2021-06-29
-3p0p,2010-10-20,2010-09-29
-7p0h,2022-04-06,2021-06-29
-1p0e,2003-09-30,2003-04-10
-3p0x,2010-10-27,2010-09-29
-1p0s,2003-08-26,2003-04-10
-8p0z,2023-09-27,2023-05-11
-8p0g,2024-05-22,2023-05-10
-6p0i,2020-03-04,2019-05-17
-2p0e,2007-05-08,2007-02-28
-8p09,2024-03-20,2023-05-09
-1p0v,2003-12-09,2003-04-11
-2p02,2007-03-13,2007-02-28
-8p0d,2024-02-21,2023-05-10
-6p0y,2019-08-21,2019-05-17
-3p0v,2011-10-19,2010-09-29
-4p0s,2014-05-28,2014-02-22
-3p0m,2011-09-28,2010-09-29
-6p0g,2019-12-18,2019-05-17
-7p0x,2022-04-06,2021-06-30
-8p08,2023-05-17,2023-05-09
-6p0b,2019-12-11,2019-05-16
-2p0u,2007-03-13,2007-03-01
-4p0d,2014-08-27,2014-02-20
-2p0w,2007-03-13,2007-03-01
-8p0t,2024-05-22,2023-05-10
-6p09,2019-12-11,2019-05-16
-3p0z,2010-10-20,2010-09-29
-6p0r,2019-05-29,2019-05-17
-8p03,2024-03-20,2023-05-09
-8p02,2024-06-05,2023-05-09
-4p0g,2015-03-18,2014-02-21
-7p0q,2022-07-13,2021-06-30
-3p0j,2011-03-23,2010-09-28
-1p0z,2003-08-19,2003-04-11
-2p0c,2007-05-08,2007-02-28
-6p0d,2019-12-11,2019-05-16
-1p0h,2003-09-09,2003-04-10
-1p0c,2003-04-22,2003-04-10
-1p0m,2003-08-05,2003-04-10
-6p0o,2020-03-04,2019-05-17
-7p0f,2022-06-15,2021-06-29
-2p0a,2007-03-27,2007-02-28
-6p0k,2020-03-04,2019-05-17
-8p04,2023-05-17,2023-05-09
-2p0b,2007-08-07,2007-02-28
-8p0e,2024-01-17,2023-05-10
-8p0u,2024-05-22,2023-05-10
-1p05,1990-04-15,1989-04-24
-8p0f,2023-05-31,2023-05-10
-3p0h,2011-03-23,2010-09-28
-7p00,2021-12-15,2021-06-29
-6p04,2020-01-29,2019-05-16
-1p0x,2003-12-09,2003-04-11
-3p0w,2010-10-13,2010-09-29
-7p0r,2021-12-29,2021-06-30
-2p0s,2007-04-03,2007-03-01
-4p0p,2014-05-28,2014-02-22
-6p05,2020-05-20,2019-05-16
-8p0k,2024-05-22,2023-05-10
-4p0v,2014-07-02,2014-02-23
-7p0o,2022-05-25,2021-06-30
-7p0t,2022-03-23,2021-06-30
-8p01,2023-07-26,2023-05-09
-4p0b,2014-05-07,2014-02-20
-7p09,2021-08-11,2021-06-29
-7p0d,2022-02-09,2021-06-29
-3p0i,2011-03-23,2010-09-28
-4p06,2014-03-26,2014-02-20
-4p05,2014-03-26,2014-02-20
-7p0a,2022-03-23,2021-06-29
-4p0n,2014-10-01,2014-02-21
-6p00,2020-05-27,2019-05-16
-7p0l,2021-12-01,2021-06-29
-7p0n,2021-12-29,2021-06-30
-1p04,1990-04-15,1989-04-24
-7p0g,2022-02-09,2021-06-29
-3p0y,2011-10-26,2010-09-29
-1p0q,2003-08-05,2003-04-10
-3p0f,2011-09-07,2010-09-28
-1p06,1990-04-15,1989-04-24
-6p01,2020-01-29,2019-05-16
-6p0l,2020-03-04,2019-05-17
-8p0p,2023-09-06,2023-05-10
-2p0o,2007-03-27,2007-02-28
-8p0q,2023-09-06,2023-05-10
-2p09,2007-06-05,2007-02-28
-7p06,2021-11-10,2021-06-29
-2p0n,2007-03-27,2007-02-28
-8p0n,2024-05-22,2023-05-10
-1p02,1990-04-15,1989-04-24
-8p0l,2023-11-29,2023-05-10
-8p05,2023-05-17,2023-05-09
-1p0i,2003-08-05,2003-04-10
-6p0a,2019-12-11,2019-05-16
-8p06,2023-06-21,2023-05-09
-4p0w,2014-07-02,2014-02-23
-5rf2,2020-03-25,2020-03-15
-7rf8,2021-11-10,2021-07-13
-2rfs,2007-11-06,2007-10-01
-6rfe,2020-04-08,2019-04-13
-7rfw,2021-11-10,2021-07-14
-5rf0,2020-03-25,2020-03-15
-4rfz,2014-12-24,2014-09-29
-7rf7,2021-11-10,2021-07-13
-3rfa,2011-05-11,2011-04-05
-5rfc,2020-03-25,2020-03-15
-5rfs,2020-03-25,2020-03-15
-4rf5,2015-09-30,2014-09-24
-7rfs,2021-11-10,2021-07-14
-2rf7,2008-03-25,2007-09-28
-1rf7,1997-03-12,1996-10-24
-1rfu,2004-04-27,2003-11-10
-4rfm,2015-04-29,2014-09-26
-6rfw,2019-07-24,2019-04-16
-2rfh,2008-04-22,2007-09-29
-5rfw,2020-03-25,2020-03-15
-5rf3,2020-03-25,2020-03-15
-8rfm,2024-05-29,2023-12-13
-6rfb,2019-04-24,2019-04-12
-5rfg,2020-03-25,2020-03-15
-6rfd,2020-05-13,2019-04-12
-2rfg,2007-10-23,2007-09-29
-1rf1,2004-03-16,2003-11-07
-1rfq,2003-12-16,2003-11-10
-7rf6,2021-11-10,2021-07-13
-3rfc,2011-05-04,2011-04-06
-4rfr,2016-04-06,2014-09-27
-1rf0,2004-03-16,2003-11-07
-1rf9,2004-11-16,2003-11-07
-3rf7,2011-12-07,2011-04-05
-7rf1,2021-11-10,2021-07-13
-8rfg,2024-03-20,2023-12-12
-3rfs,2012-03-14,2011-04-06
-3rfr,2011-11-23,2011-04-06
-8rfh,2024-01-10,2023-12-12
-6rfi,2019-10-30,2019-04-15
-5rfp,2020-03-25,2020-03-15
-1rfn,1999-09-01,1999-04-19
-6rf1,2019-04-24,2019-04-12
-6rf3,2019-04-24,2019-04-12
-1rfv,2004-04-27,2003-11-10
-4rfu,2015-10-07,2014-09-27
-4rfn,2015-07-15,2014-09-26
-6rfh,2020-05-13,2019-04-15
-1rf4,2004-02-17,2003-11-07
-6rft,2019-07-10,2019-04-16
-6rfc,2019-04-24,2019-04-12
-4rf7,2015-04-08,2014-09-25
-1rff,2004-03-02,2003-11-08
-4rf2,2015-09-30,2014-09-24
-5rff,2020-03-25,2020-03-15
-5rf4,2020-03-25,2020-03-15
-5rfn,2020-03-25,2020-03-15
-4rf1,2014-10-22,2014-09-24
-3rfv,2011-06-15,2011-04-07
-4rf3,2015-09-30,2014-09-24
-5rf1,2020-03-25,2020-03-15
-5rf7,2020-03-25,2020-03-15
-5rfx,2020-03-25,2020-03-15
-4rfd,2015-04-15,2014-09-25
-4rfb,2014-10-08,2014-09-25
-7rf4,2021-11-10,2021-07-13
-2rfi,2007-10-23,2007-09-30
-5rfy,2020-03-25,2020-03-15
-2rfk,2008-02-05,2007-09-30
-3rfe,2011-12-21,2011-04-06
-5rfb,2020-03-25,2020-03-15
-6rfs,2019-12-11,2019-04-16
-5rf9,2020-03-25,2020-03-15
-4rfw,2015-09-16,2014-09-28
-5rfl,2020-03-25,2020-03-15
-2rfz,2008-09-16,2007-10-02
-6rf5,2019-04-24,2019-04-12
-6rf6,2019-04-24,2019-04-12
-6rfk,2019-06-12,2019-04-15
-2rft,2008-02-05,2007-10-01
-2rfx,2008-07-08,2007-10-02
-6rf9,2019-04-24,2019-04-12
-7rfh,2022-01-12,2021-07-14
-1rfh,2005-06-14,2003-11-09
-6rfn,2019-07-24,2019-04-15
-5rf8,2020-03-25,2020-03-15
-6rff,2020-04-08,2019-04-14
-1rfg,2004-12-14,2003-11-09
-6rf4,2019-04-24,2019-04-12
-5rfq,2020-03-25,2020-03-15
-2rfc,2008-01-29,2007-09-28
-6rfz,2020-07-01,2019-04-16
-4rf9,2015-04-08,2014-09-25
-8rf0,2024-03-20,2023-12-12
-2rfy,2008-09-16,2007-10-02
-4rfo,2015-07-15,2014-09-26
-5rfa,2020-03-25,2020-03-15
-7rft,2022-04-13,2021-07-14
-5rfv,2020-03-25,2020-03-15
-7rfb,2022-01-12,2021-07-14
-3rfx,2011-06-15,2011-04-07
-6rfq,2019-12-11,2019-04-16
-7rfe,2022-01-12,2021-07-14
-5rfu,2020-03-25,2020-03-15
-5rfd,2020-03-25,2020-03-15
-5rft,2020-03-25,2020-03-15
-7rfc,2022-01-12,2021-07-14
-3rf5,2011-10-12,2011-04-05
-2rfb,2008-01-29,2007-09-28
-5rfz,2020-03-25,2020-03-15
-8rfe,2024-03-20,2023-12-12
-6rf8,2020-04-15,2019-04-12
-3rfn,2011-11-09,2011-04-06
-7rf2,2021-11-10,2021-07-13
-5rfe,2020-03-25,2020-03-15
-2rfu,2008-02-05,2007-10-01
-6rfv,2020-02-19,2019-04-16
-2rf5,2007-10-09,2007-09-28
-6rfl,2019-12-11,2019-04-15
-5rf5,2020-03-25,2020-03-15
-7rf5,2021-11-10,2021-07-13
-3rfu,2011-06-29,2011-04-07
-3rfm,2011-09-07,2011-04-06
-7rfg,2022-01-12,2021-07-14
-4rfl,2015-07-22,2014-09-26
-2rf2,2008-01-01,2007-09-27
-6rfr,2019-12-11,2019-04-16
-3rfb,2012-04-11,2011-04-06
-4rf4,2015-09-30,2014-09-24
-6rf7,2019-04-24,2019-04-12
-7rf0,2023-01-18,2021-07-13
-7rf3,2021-11-10,2021-07-13
-4rfq,2014-10-08,2014-09-26
-3rf4,2011-10-12,2011-04-05
-5rfi,2020-03-25,2020-03-15
-7rfu,2021-11-10,2021-07-14
-7rfn,2021-09-15,2021-07-14
-7rfi,2022-01-12,2021-07-14
-8rfn,2024-05-29,2023-12-13
-6rf2,2020-05-13,2019-04-12
-5rfo,2020-03-25,2020-03-15
-1rft,2004-04-27,2003-11-10
-7rfr,2021-11-10,2021-07-14
-3rfq,2011-05-04,2011-04-06
-5rfm,2020-03-25,2020-03-15
-7rf9,2021-10-06,2021-07-13
-4rf8,2015-04-08,2014-09-25
-1rfj,2004-06-29,2003-11-10
-1rf2,2004-10-26,2003-11-07
-6rf0,2019-04-24,2019-04-12
-7rfm,2021-09-15,2021-07-14
-2rfn,2007-11-06,2007-10-01
-5rfh,2020-03-25,2020-03-15
-4rf0,2014-10-22,2014-09-24
-6rfj,2019-10-30,2019-04-15
-4rfc,2015-04-15,2014-09-25
-1rfi,2004-03-02,2003-11-10
-6rfa,2019-04-24,2019-04-12
-5rfk,2020-03-25,2020-03-15
-7rfl,2021-09-15,2021-07-14
-1rf8,2003-12-23,2003-11-07
-5rfj,2020-03-25,2020-03-15
-7rfk,2021-09-15,2021-07-14
-4rfy,2014-12-24,2014-09-29
-2rfm,2008-03-11,2007-10-01
-3rf6,2011-06-01,2011-04-05
-1rf6,2004-02-17,2003-11-07
-5rf6,2020-03-25,2020-03-15
-6rfu,2020-02-19,2019-04-16
-5rfr,2020-03-25,2020-03-15
-1lca,1995-10-15,1995-06-22
-3lc3,2010-02-23,2010-01-09
-1lcs,2003-04-08,2002-04-06
-7lcz,2021-03-10,2021-01-12
-5lcx,2016-08-31,2016-06-22
-7lcu,2022-01-12,2021-01-11
-7lcm,2021-04-07,2021-01-11
-5lct,2018-01-17,2016-06-22
-7lc7,2022-01-12,2021-01-09
-6lcr,2020-04-29,2019-11-19
-4lcz,2014-05-07,2013-06-24
-3lce,2010-03-09,2010-01-10
-4lc9,2013-09-04,2013-06-21
-3lc6,2010-04-21,2010-01-09
-4lci,2014-06-25,2013-06-21
-4lcc,2013-10-16,2013-06-21
-3lcv,2010-06-02,2010-01-11
-7lc0,2021-06-09,2021-01-09
-6lcx,2020-02-19,2019-11-20
-1lck,1995-10-15,1994-12-12
-7lcl,2021-09-01,2021-01-11
-1lc7,2002-06-28,2002-04-05
-7lcd,2022-02-09,2021-01-10
-6lc1,2019-12-18,2019-11-16
-6lc5,2020-09-30,2019-11-17
-5lcf,2017-02-15,2016-06-21
-3lcm,2011-01-12,2010-01-11
-3lcs,2010-08-04,2010-01-11
-4lc1,2013-09-25,2013-06-21
-7lco,2021-07-07,2021-01-11
-3lcj,2010-07-21,2010-01-11
-3lcb,2010-04-21,2010-01-10
-7lcq,2021-05-12,2021-01-11
-2lcq,2011-12-14,2011-05-05
-6lcl,2020-09-30,2019-11-19
-1lc8,2002-06-28,2002-04-05
-7lcf,2022-01-12,2021-01-10
-6lck,2020-07-01,2019-11-19
-4lcu,2013-10-30,2013-06-23
-5lcq,2018-01-17,2016-06-22
-3lcd,2010-03-02,2010-01-10
-6lcf,2020-04-22,2019-11-18
-7lc4,2021-04-28,2021-01-09
-4lcd,2013-08-14,2013-06-21
-7lcg,2021-09-01,2021-01-11
-5lcj,2016-07-20,2016-06-22
-1lc3,2002-07-17,2002-04-05
-3lco,2010-09-15,2010-01-11
-1lcb,1995-10-15,1995-06-22
-5lck,2016-07-20,2016-06-22
-7lch,2021-09-01,2021-01-11
-1lcp,1995-07-31,1995-05-12
-5lcv,2016-07-06,2016-06-22
-2lcp,2012-02-01,2011-05-05
-6lce,2020-04-22,2019-11-18
-3lct,2010-08-04,2010-01-11
-6lcs,2020-11-25,2019-11-19
-4lcn,2014-01-22,2013-06-22
-1lcv,2002-11-06,2002-04-07
-2lce,2011-05-18,2011-04-28
-4lcq,2013-09-18,2013-06-22
-7lcs,2021-07-07,2021-01-11
-5lch,2017-02-15,2016-06-21
-1lcc,1994-01-31,1993-03-25
-4lca,2013-07-03,2013-06-21
-2lcf,2011-09-28,2011-04-28
-5lca,2017-02-15,2016-06-20
-7lc6,2021-01-27,2021-01-09
-4lcs,2013-09-18,2013-06-23
-3lcu,2010-06-02,2010-01-11
-1lco,1995-09-15,1995-03-30
-3lc0,2010-01-19,2010-01-08
-1lcf,1994-08-31,1994-01-11
-4lc8,2013-07-03,2013-06-21
-4lcf,2013-08-21,2013-06-21
-1lcw,2002-11-06,2002-04-07
-7lci,2021-01-20,2021-01-11
-1lct,1993-10-31,1993-06-19
-5lcb,2016-07-27,2016-06-20
-3lc8,2011-02-16,2010-01-10
-1lcu,2002-05-01,2002-04-06
-3lcp,2010-01-26,2010-01-11
-5lc0,2016-07-06,2016-06-18
-4lck,2013-07-31,2013-06-21
-3lc2,2010-08-18,2010-01-09
-5lc1,2016-07-27,2016-06-18
-4lc6,2013-07-03,2013-06-21
-4lcx,2013-11-06,2013-06-24
-1lc1,2003-06-03,2002-04-04
-6lc8,2020-04-22,2019-11-18
-4lc0,2013-09-11,2013-06-21
-4lcv,2013-09-11,2013-06-23
-5lcm,2017-05-10,2016-06-22
-6lcp,2020-04-29,2019-11-19
-7lc3,2021-01-27,2021-01-09
-7lcr,2022-12-07,2021-01-11
-3lc5,2010-02-23,2010-01-09
-1lce,1995-10-15,1995-06-22
-5lc5,2016-09-07,2016-06-19
-6lc9,2020-04-22,2019-11-18
-4lc5,2014-01-22,2013-06-21
-1lcd,1994-01-31,1993-03-25
-6lco,2019-12-04,2019-11-19
-3lca,2010-12-22,2010-01-10
-7lca,2021-09-01,2021-01-10
-4lco,2014-01-22,2013-06-22
-7lc1,2021-08-04,2021-01-09
-4lcr,2013-09-18,2013-06-22
-7lct,2021-07-07,2021-01-11
-1lc2,2003-06-03,2002-04-04
-7lc2,2021-07-28,2021-01-09
-7lcb,2022-05-04,2021-01-10
-7lck,2021-01-20,2021-01-11
-5lcu,2018-01-17,2016-06-22
-3lcc,2010-05-19,2010-01-10
-6lcd,2020-07-01,2019-11-18
-1lcz,2002-11-06,2002-04-08
-5lcp,2018-01-17,2016-06-22
-5lcz,2016-09-21,2016-06-23
-3lcz,2010-02-23,2010-01-12
-5lcl,2017-05-10,2016-06-22
-4lc7,2013-09-18,2013-06-21
-4lce,2014-03-19,2013-06-21
-3lcw,2011-01-19,2010-01-12
-3lc4,2010-05-12,2010-01-09
-4lcg,2013-08-21,2013-06-21
-3lc1,2010-08-18,2010-01-09
-4lc4,2013-07-03,2013-06-21
-7lc5,2021-11-03,2021-01-09
-4lcp,2014-01-22,2013-06-22
-3lcn,2010-05-12,2010-01-11
-4lcj,2014-03-19,2013-06-21
-7lcp,2021-05-12,2021-01-11
-4lcy,2014-06-25,2013-06-24
-5lce,2017-07-26,2016-06-21
-7lcj,2021-01-20,2021-01-11
-5lc8,2017-01-25,2016-06-20
-4lcw,2013-10-02,2013-06-24
-7lcc,2021-08-25,2021-01-10
-6lcb,2020-11-25,2019-11-18
-2lc5,2011-06-08,2011-04-23
-5lcr,2018-01-17,2016-06-22
-5lcd,2017-06-21,2016-06-21
-7lce,2021-06-09,2021-01-10
-6lcw,2020-02-19,2019-11-20
-4lch,2013-08-21,2013-06-21
-7lcn,2021-01-27,2021-01-11
-6eyj,2018-11-21,2017-11-13
-9ey5,2024-05-22,2024-04-09
-3eyh,2009-02-03,2008-10-20
-8eyp,2024-02-14,2022-10-28
-1eye,2000-10-11,2000-05-05
-4eyw,2013-04-24,2012-05-02
-4eyg,2012-05-30,2012-05-01
-5eyp,2016-07-20,2015-11-25
-4ey4,2012-10-17,2012-05-01
-9ey7,2024-05-22,2024-04-09
-5eyk,2016-08-17,2015-11-25
-1eyr,2001-02-14,2000-05-08
-8eyk,2023-05-24,2022-10-27
-4ey7,2012-10-17,2012-05-01
-6ey2,2018-08-08,2017-11-10
-8eya,2023-07-05,2022-10-26
-4eyp,2013-05-01,2012-05-01
-7eyc,2022-06-01,2021-05-30
-6eyf,2018-11-21,2017-11-12
-1eyf,2003-09-09,2000-05-06
-6eya,2018-05-30,2017-11-11
-6eyk,2018-11-21,2017-11-13
-4eyf,2012-08-08,2012-05-01
-4eym,2012-12-19,2012-05-01
-8ey3,2023-11-08,2022-10-26
-3eyv,2009-11-03,2008-10-22
-7eyi,2021-09-01,2021-05-31
-4eyb,2012-08-15,2012-05-01
-1eyq,2000-09-06,2000-05-08
-3eym,2009-01-13,2008-10-21
-6ey7,2018-10-03,2017-11-10
-5eyh,2015-12-23,2015-11-25
-6ey8,2018-05-30,2017-11-11
-8eym,2023-05-17,2022-10-27
-8eyc,2023-08-16,2022-10-26
-7eys,2022-04-20,2021-06-01
-5eyw,2016-09-28,2015-11-25
-3ey7,2009-01-13,2008-10-20
-5eyn,2016-11-30,2015-11-25
-3eyg,2009-02-03,2008-10-20
-5eyj,2016-10-19,2015-11-25
-6eyi,2018-11-21,2017-11-13
-5ey0,2016-09-14,2015-11-24
-1eyw,2000-12-20,2000-05-09
-1eyz,2000-08-02,2000-05-09
-5eyy,2016-03-16,2015-11-25
-4eyv,2013-05-15,2012-05-02
-3eya,2008-11-04,2008-10-20
-7ey2,2022-06-01,2021-05-29
-7ey3,2022-12-14,2021-05-29
-6ey9,2018-05-30,2017-11-11
-4ey1,2013-05-01,2012-05-01
-2ey4,2006-01-24,2005-11-09
-8eyl,2023-02-22,2022-10-27
-8eyi,2023-05-24,2022-10-27
-7ey4,2021-09-08,2021-05-29
-8eyj,2022-11-16,2022-10-27
-3eyy,2009-06-09,2008-10-22
-4eyu,2012-08-08,2012-05-01
-3eyi,2009-01-13,2008-10-21
-6eyd,2018-12-12,2017-11-11
-1ey2,2000-11-05,2000-05-05
-6eyp,2018-11-21,2017-11-13
-3eyx,2009-09-15,2008-10-22
-6eyl,2018-11-21,2017-11-13
-5eyr,2016-02-03,2015-11-25
-8ey4,2023-11-08,2022-10-26
-8eyd,2023-01-18,2022-10-26
-6eyh,2018-11-21,2017-11-13
-5ey3,2016-12-07,2015-11-24
-3eyu,2009-05-12,2008-10-21
-6eyc,2018-06-20,2017-11-11
-1eys,2000-12-13,2000-05-08
-4eyd,2013-05-01,2012-05-01
-6eyz,2017-12-20,2017-11-13
-5ey1,2016-09-14,2015-11-24
-3eyl,2008-11-25,2008-10-21
-6eyu,2017-12-13,2017-11-13
-4eyq,2012-05-30,2012-05-01
-8eyg,2023-11-01,2022-10-27
-3eyz,2009-11-10,2008-10-22
-9ey8,2024-05-01,2024-04-09
-4ey8,2012-10-17,2012-05-01
-6eyo,2018-08-15,2017-11-13
-8eye,2023-01-18,2022-10-26
-6eye,2017-11-29,2017-11-12
-3eys,2009-05-12,2008-10-21
-7eyr,2022-04-20,2021-06-01
-4eyo,2012-05-30,2012-05-01
-8ey7,2023-11-01,2022-10-26
-5ey7,2016-11-30,2015-11-24
-8ey0,2023-11-08,2022-10-26
-5eym,2016-08-17,2015-11-25
-4ey9,2013-05-01,2012-05-01
-3ey9,2008-11-04,2008-10-20
-7ey1,2022-06-01,2021-05-29
-3ey4,2008-11-11,2008-10-17
-7eyo,2022-05-25,2021-05-31
-5eyx,2016-03-16,2015-11-25
-4eyl,2012-08-08,2012-05-01
-1eyx,2000-11-22,2000-05-09
-8eyo,2023-02-08,2022-10-28
-8ey1,2024-05-29,2022-10-26
-3eyk,2009-01-13,2008-10-21
-6ey1,2018-10-03,2017-11-10
-5eyd,2016-02-10,2015-11-24
-4eys,2012-07-18,2012-05-01
-8eyh,2023-11-01,2022-10-27
-6eym,2018-09-12,2017-11-13
-1eyy,2000-05-24,2000-05-09
-5eya,2016-08-17,2015-11-24
-4ey5,2012-10-17,2012-05-01
-9ey6,2024-05-22,2024-04-09
-1ey3,2002-02-27,2000-05-05
-6eyb,2018-05-30,2017-11-11
-7eya,2021-09-08,2021-05-30
-6eyt,2018-02-28,2017-11-13
-7eyd,2021-10-06,2021-05-30
-5eyg,2015-12-23,2015-11-25
-8ey8,2023-11-01,2022-10-26
-1eyk,2000-08-09,2000-05-07
-4eyj,2012-12-19,2012-05-01
-7eyu,2022-04-20,2021-06-01
-6ey5,2018-02-07,2017-11-10
-8ey5,2022-11-09,2022-10-26
-8eyf,2023-01-18,2022-10-26
-4eyn,2013-05-01,2012-05-01
-7eyt,2022-04-20,2021-06-01
-7eyx,2021-06-16,2021-06-01
-4eyr,2013-01-30,2012-05-01
-5eys,2016-10-19,2015-11-25
-4eyh,2013-01-09,2012-05-01
-4eyi,2013-01-09,2012-05-01
-8ey9,2024-05-29,2022-10-26
-8ey6,2023-11-01,2022-10-26
-1eyi,2000-08-09,2000-05-06
-6eyv,2018-08-01,2017-11-13
-3eyd,2009-02-10,2008-10-20
-4ey2,2012-08-08,2012-05-01
-1eyn,2000-06-09,2000-05-07
-5eyf,2015-12-16,2015-11-24
-8eyz,2022-11-23,2022-10-29
-7eyw,2022-04-20,2021-06-01
-4ey6,2012-10-17,2012-05-01
-3eyw,2009-06-30,2008-10-22
-1eyj,2000-08-09,2000-05-07
-5eyu,2015-12-09,2015-11-25
-5eyt,2016-11-30,2015-11-25
-8eyb,2023-07-05,2022-10-26
-5ey5,2016-04-27,2015-11-24
-5eyz,2016-06-08,2015-11-26
-5eyc,2016-02-10,2015-11-24
-5ey4,2016-06-15,2015-11-24
-7z0v,2023-03-08,2022-02-23
-2z02,2007-11-06,2007-05-06
-4z0o,2015-04-08,2015-03-26
-1z0m,2005-10-25,2005-03-02
-1z0w,2005-08-02,2005-03-02
-2z0x,2007-11-13,2007-05-07
-6z0r,2021-05-19,2020-05-10
-5z0g,2018-12-26,2017-12-19
-7z02,2022-03-30,2022-02-21
-6z0d,2020-05-20,2020-05-08
-4z0y,2016-04-06,2015-03-26
-1z0a,2005-07-26,2005-03-01
-5z0u,2018-02-21,2017-12-21
-5z0f,2018-12-26,2017-12-19
-6z07,2020-09-16,2020-05-07
-5z09,2018-10-31,2017-12-19
-5z0h,2018-12-26,2017-12-19
-5z01,2018-04-25,2017-12-18
-2z0a,2008-05-13,2007-05-07
-6z0e,2021-05-19,2020-05-08
-5z0q,2018-11-07,2017-12-20
-7z0g,2022-04-13,2022-02-22
-1z0b,2005-08-02,2005-03-01
-5z0x,2018-12-26,2017-12-22
-2z00,2007-11-06,2007-05-06
-1z0i,2005-07-26,2005-03-01
-1z0f,2005-07-26,2005-03-01
-4z0g,2015-11-25,2015-03-26
-4z0q,2015-08-26,2015-03-26
-7z0w,2022-07-20,2022-02-23
-7z01,2022-03-30,2022-02-21
-6z0c,2021-03-17,2020-05-08
-5z02,2018-01-03,2017-12-18
-4z0r,2015-04-08,2015-03-26
-5z0j,2018-12-26,2017-12-19
-4z0n,2015-04-15,2015-03-26
-1z07,2005-07-26,2005-03-01
-5z0a,2018-10-31,2017-12-19
-6z0p,2021-04-14,2020-05-10
-6z08,2020-12-09,2020-05-08
-1z0d,2005-07-26,2005-03-01
-1z06,2005-07-26,2005-03-01
-7z0t,2022-09-28,2022-02-23
-4z02,2015-04-22,2015-03-25
-5z0d,2018-12-26,2017-12-19
-5z0e,2018-12-26,2017-12-19
-6z02,2020-12-02,2020-05-07
-7z04,2022-11-23,2022-02-22
-1z0u,2005-04-19,2005-03-02
-2z08,2007-11-13,2007-05-07
-4z05,2015-12-23,2015-03-25
-2z06,2007-11-06,2007-05-06
-1z08,2005-07-26,2005-03-01
-7z0f,2022-04-13,2022-02-22
-7z05,2022-09-28,2022-02-22
-6z06,2020-12-30,2020-05-07
-4z0p,2015-04-08,2015-03-26
-5z0c,2018-01-17,2017-12-19
-5z0m,2018-12-26,2017-12-19
-7z0u,2022-06-22,2022-02-23
-4z0k,2015-05-20,2015-03-26
-7z00,2022-11-02,2022-02-21
-6z0u,2020-10-14,2020-05-11
-2z0k,2007-11-13,2007-05-07
-1z0s,2005-04-19,2005-03-02
-4z0v,2015-06-17,2015-03-26
-5z0k,2018-12-26,2017-12-19
-7z0i,2023-03-08,2022-02-23
-4z07,2016-04-13,2015-03-25
-4z0c,2015-10-07,2015-03-26
-1z03,2005-05-24,2005-03-01
-6z0q,2021-05-19,2020-05-10
-4z0i,2016-01-13,2015-03-26
-1z01,2005-05-24,2005-03-01
-4z0h,2016-04-13,2015-03-26
-1z0z,2005-04-26,2005-03-02
-1z0j,2005-07-26,2005-03-01
-7z0e,2022-05-18,2022-02-22
-7z0y,2022-04-13,2022-02-23
-2z0y,2007-11-13,2007-05-07
-6z0l,2021-03-17,2020-05-09
-5z0i,2018-12-26,2017-12-19
-2z0j,2007-11-13,2007-05-07
-6z0m,2021-03-17,2020-05-09
-4z03,2015-12-23,2015-03-25
-4z0z,2016-04-06,2015-03-26
-6z0j,2021-03-10,2020-05-09
-6z0k,2021-03-10,2020-05-09
-2z09,2007-11-13,2007-05-07
-5z0s,2018-12-26,2017-12-20
-6z00,2020-12-30,2020-05-07
-7z0p,2022-04-27,2022-02-23
-7z0s,2022-09-28,2022-02-23
-6z0v,2020-10-14,2020-05-11
-7z0l,2022-07-27,2022-02-23
-4z06,2015-12-23,2015-03-25
-5z06,2018-05-30,2017-12-18
-5z0b,2018-12-19,2017-12-19
-7z0r,2022-06-22,2022-02-23
-1z05,2005-03-08,2005-03-01
-4z0u,2015-04-29,2015-03-26
-5z0t,2018-02-21,2017-12-21
-5z0v,2018-04-11,2017-12-21
-5z05,2018-01-31,2017-12-18
-5z0l,2018-12-26,2017-12-19
-7z03,2022-08-17,2022-02-21
-2z0p,2008-05-13,2007-05-07
-1z02,2005-05-24,2005-03-01
-5z0r,2018-04-11,2017-12-20
-7z0h,2023-04-05,2022-02-22
-6z0z,2021-05-19,2020-05-11
-4z04,2015-04-22,2015-03-25
-1z0n,2005-10-25,2005-03-02
-7z0x,2022-04-13,2022-02-23
-1z0k,2005-07-26,2005-03-01
-6dvz,2018-09-05,2018-06-25
-5dvx,2016-08-03,2015-09-21
-8dvo,2022-09-28,2022-07-29
-5dv4,2016-10-26,2015-09-21
-2dvb,2006-11-07,2006-07-30
-1dve,2000-04-12,2000-01-20
-6dvr,2018-07-25,2018-06-25
-6dvd,2019-02-20,2018-06-23
-7dvb,2022-01-19,2021-01-13
-8dvq,2023-03-22,2022-07-29
-5dvn,2016-03-30,2015-09-21
-7dv0,2022-01-19,2021-01-12
-6dvn,2018-08-29,2018-06-24
-1dvw,2003-12-23,2000-01-22
-8dvz,2024-01-17,2022-07-30
-4dvr,2013-02-27,2012-02-23
-8dv5,2022-11-09,2022-07-28
-4dv7,2013-02-27,2012-02-22
-1dvp,2000-03-06,2000-01-21
-4dvs,2013-02-27,2012-02-23
-6dvy,2018-09-05,2018-06-25
-6dvi,2018-10-03,2018-06-23
-8dv1,2022-08-31,2022-07-27
-1dvh,1995-06-03,1995-02-24
-8dvf,2023-06-14,2022-07-28
-1dvx,2001-01-23,2000-01-23
-8dvb,2022-11-16,2022-07-28
-6dvb,2019-02-20,2018-06-23
-8dvp,2022-11-30,2022-07-29
-3dv0,2009-01-13,2008-07-18
-8dvu,2022-11-16,2022-07-29
-3dv5,2009-02-24,2008-07-18
-1dv2,2000-06-09,2000-01-19
-8dvh,2022-11-09,2022-07-29
-4dv4,2013-02-27,2012-02-22
-6dve,2019-02-20,2018-06-23
-1dv3,2000-03-08,2000-01-19
-8dv3,2023-04-12,2022-07-28
-3dvs,2009-07-07,2008-07-20
-2dv5,2007-01-28,2006-07-28
-5dvc,2016-09-21,2015-09-21
-4dv9,2013-01-16,2012-02-23
-7dv5,2022-01-19,2021-01-12
-4dve,2012-08-29,2012-02-23
-2dv4,2007-01-28,2006-07-28
-7dvo,2021-05-19,2021-01-14
-8dvx,2023-07-19,2022-07-30
-6dvv,2018-07-18,2018-06-25
-4dvn,2012-05-23,2012-02-23
-1dv6,2000-03-08,2000-01-19
-4dvw,2013-02-27,2012-02-23
-2dvi,2006-11-14,2006-07-31
-2dvz,2006-11-07,2006-08-01
-6dv0,2018-10-31,2018-06-22
-8dv7,2022-11-09,2022-07-28
-8dvv,2024-01-31,2022-07-29
-5dv8,2016-09-21,2015-09-21
-1dvu,2001-01-22,2000-01-22
-4dvl,2012-05-23,2012-02-23
-2dvx,2006-09-19,2006-08-01
-3dvq,2009-07-07,2008-07-20
-7dv3,2021-12-22,2021-01-12
-3dv6,2008-12-02,2008-07-18
-1dvy,2001-01-23,2000-01-23
-6dvc,2019-02-20,2018-06-23
-2dvs,2007-08-07,2006-08-01
-4dvt,2013-02-27,2012-02-23
-6dvx,2018-10-10,2018-06-25
-8dve,2023-05-31,2022-07-28
-2dvg,2006-11-07,2006-07-31
-4dv2,2013-02-27,2012-02-22
-2dvh,1998-06-17,1998-03-25
-4dv0,2013-02-27,2012-02-22
-3dvp,2009-01-20,2008-07-18
-5dvm,2016-03-30,2015-09-21
-7dvk,2021-08-18,2021-01-13
-2dv3,2007-01-28,2006-07-28
-2dva,2006-11-07,2006-07-30
-8dvy,2022-11-30,2022-07-30
-3dvb,2008-11-11,2008-07-18
-4dvv,2013-02-27,2012-02-23
-8dv8,2022-11-09,2022-07-28
-6dvm,2018-08-29,2018-06-24
-8dvi,2023-06-14,2022-07-29
-2dvq,2007-08-07,2006-08-01
-5dvv,2016-05-04,2015-09-21
-5dvl,2016-03-30,2015-09-21
-5dv3,2016-09-21,2015-09-21
-7dvr,2021-09-29,2021-01-15
-4dv3,2013-02-27,2012-02-22
-5dv6,2016-09-21,2015-09-21
-8dv2,2022-08-31,2022-07-27
-6dv9,2019-02-20,2018-06-23
-2dvl,2007-01-31,2006-07-31
-2dvn,2007-09-04,2006-07-31
-3dva,2009-01-13,2008-07-18
-1dvf,1996-08-17,1996-04-13
-8dv4,2023-04-19,2022-07-28
-7dvd,2021-08-04,2021-01-13
-2dv0,2006-10-03,2006-07-28
-8dvc,2023-06-14,2022-07-28
-6dvl,2018-08-29,2018-06-24
-5dvj,2016-02-17,2015-09-21
-4dvi,2012-04-04,2012-02-23
-5dvr,2015-09-30,2015-09-21
-3dv9,2008-08-05,2008-07-18
-8dvs,2022-11-16,2022-07-29
-8dvw,2024-01-17,2022-07-30
-1dvr,1996-04-03,1995-12-14
-1dvb,2000-11-17,2000-01-20
-1dv8,2000-07-26,2000-01-20
-2dvr,2007-08-07,2006-08-01
-5dvs,2016-05-04,2015-09-21
-3dve,2008-11-04,2008-07-18
-5dv2,2016-05-18,2015-09-21
-3dvj,2008-11-04,2008-07-18
-1dvt,2001-01-22,2000-01-22
-7dva,2022-01-19,2021-01-13
-7dvq,2021-03-31,2021-01-14
-7dv1,2022-01-19,2021-01-12
-5dva,2016-06-01,2015-09-21
-8dvr,2022-11-02,2022-07-29
-6dv4,2018-10-31,2018-06-22
-7dvu,2021-09-29,2021-01-15
-1dva,2000-05-12,2000-01-20
-3dv4,2008-12-02,2008-07-18
-8dvn,2023-03-29,2022-07-29
-2dvd,2006-11-07,2006-07-31
-1dvs,2001-01-22,2000-01-22
-8dvl,2023-03-29,2022-07-29
-5dvz,2016-02-03,2015-09-21
-7dvt,2021-09-29,2021-01-15
-3dvr,2009-07-07,2008-07-20
-4dvq,2013-01-30,2012-02-23
-3dvm,2008-11-04,2008-07-18
-7dvl,2021-04-28,2021-01-13
-2dv7,2007-01-28,2006-07-28
-4dvx,2013-02-27,2012-02-23
-6dvo,2018-08-29,2018-06-24
-3dv1,2009-02-24,2008-07-18
-7dve,2021-09-08,2021-01-13
-8dvd,2022-11-16,2022-07-28
-2dvf,2006-11-07,2006-07-31
-5dvp,2016-09-28,2015-09-21
-2dvo,2007-09-04,2006-07-31
-4dv8,2012-03-14,2012-02-22
-3dvd,2008-11-11,2008-07-18
-4dvf,2013-01-16,2012-02-23
-7dv6,2021-06-16,2021-01-12
-3dvl,2009-07-28,2008-07-18
-1dvg,2000-04-12,2000-01-20
-3dvc,2008-11-11,2008-07-18
-2dvu,2006-09-19,2006-08-01
-1dvv,2000-11-29,2000-01-22
-2dve,2007-01-31,2006-07-31
-4dv6,2013-02-27,2012-02-22
-2dv6,2007-02-20,2006-07-28
-5dvk,2016-03-30,2015-09-21
-2dv9,2006-11-07,2006-07-30
-3dv3,2009-07-21,2008-07-18
-5dvi,2016-02-24,2015-09-21
-3dvo,2008-08-19,2008-07-18
-4dvk,2012-05-23,2012-02-23
-4dvo,2012-08-29,2012-02-23
-3dvk,2008-11-04,2008-07-18
-3dv7,2008-11-11,2008-07-18
-2dvt,2006-09-19,2006-08-01
-4dvh,2013-03-27,2012-02-23
-4dv1,2013-02-27,2012-02-22
-1dvi,1998-05-27,1997-05-15
-7dvw,2022-01-19,2021-01-15
-8dvm,2023-03-29,2022-07-29
-2dvc,2006-08-15,2006-07-31
-2dvm,2007-10-02,2006-07-31
-1dvz,2001-01-23,2000-01-23
-6dvh,2018-10-03,2018-06-23
-1dvj,2000-04-05,2000-03-30
-4dv5,2013-02-27,2012-02-22
-7dvj,2021-06-02,2021-01-13
-4dvg,2012-11-14,2012-02-23
-5sxc,2017-02-15,2016-08-09
-5sxf,2017-02-15,2016-08-09
-7sxj,2023-06-14,2021-11-23
-7sxy,2021-12-29,2021-11-24
-5sxr,2016-09-07,2016-08-10
-7sx8,2022-08-31,2021-11-22
-8sx0,2024-05-29,2023-05-19
-5sxd,2017-02-15,2016-08-09
-1sx3,2005-03-01,2004-03-30
-7sxh,2023-06-14,2021-11-23
-5sxg,2017-12-27,2016-08-09
-3sxv,2011-08-17,2011-07-15
-1sxb,1995-06-03,1995-03-17
-3sx5,2012-02-29,2011-07-14
-3sxb,2012-02-29,2011-07-14
-8sxd,2024-04-24,2023-05-21
-7sxx,2021-12-29,2021-11-24
-5sxe,2017-02-15,2016-08-09
-6sxx,2020-07-29,2019-09-26
-8sx2,2023-11-08,2023-05-19
-7sxc,2022-04-06,2021-11-22
-8sxn,2024-02-14,2023-05-22
-8sx3,2024-05-22,2023-05-19
-1sx5,2004-04-06,2004-03-30
-7sxl,2022-10-26,2021-11-23
-6sx8,2021-07-14,2019-09-25
-8sx8,2024-01-17,2023-05-20
-3sx8,2012-02-29,2011-07-14
-1sxy,2004-06-08,2004-03-31
-7sxa,2022-08-31,2021-11-22
-6sxr,2020-02-26,2019-09-26
-1sxj,2004-06-22,2004-03-30
-3sxe,2012-02-29,2011-07-14
-8sxr,2023-08-30,2023-05-23
-5sxb,2017-02-15,2016-08-09
-3sx4,2011-10-26,2011-07-14
-3sxi,2012-05-16,2011-07-14
-3sxp,2012-02-08,2011-07-15
-5sxk,2017-02-15,2016-08-09
-3sx2,2011-08-03,2011-07-14
-3sx3,2012-02-29,2011-07-14
-6sx7,2021-02-03,2019-09-25
-3sxc,2012-02-29,2011-07-14
-1sxu,2004-06-08,2004-03-31
-3sxs,2011-09-21,2011-07-15
-3sxf,2012-03-14,2011-07-14
-5sxj,2017-02-15,2016-08-09
-1sxq,2004-06-22,2004-03-31
-6sxf,2021-02-03,2019-09-25
-3sxt,2012-07-25,2011-07-15
-3sx7,2012-02-29,2011-07-14
-7sxq,2022-10-19,2021-11-24
-6sxg,2021-02-03,2019-09-25
-7sxo,2022-01-12,2021-11-24
-3sxu,2011-09-21,2011-07-15
-7sxu,2021-12-29,2021-11-24
-5sx3,2016-08-31,2016-08-09
-7sxs,2021-12-29,2021-11-24
-1sx8,2004-04-06,2004-03-30
-8sxz,2024-05-01,2023-05-24
-1sxa,1995-06-03,1995-03-17
-7sxr,2021-12-29,2021-11-24
-3sx6,2012-05-16,2011-07-14
-8sxb,2024-01-17,2023-05-20
-1sxg,2004-10-19,2004-03-30
-3sxn,2012-05-23,2011-07-15
-5sxn,2016-11-02,2016-08-09
-7sxf,2023-06-14,2021-11-23
-3sx9,2012-03-14,2011-07-14
-8sxt,2024-01-10,2023-05-24
-5sx1,2016-09-07,2016-08-09
-8sxx,2023-12-27,2023-05-24
-1sx4,2005-03-01,2004-03-30
-5sxm,2016-09-07,2016-08-09
-5sx2,2016-09-07,2016-08-09
-5sx8,2017-02-15,2016-08-09
-6sxy,2021-04-07,2019-09-26
-8sxw,2023-09-13,2023-05-24
-3sxh,2011-07-27,2011-07-14
-6sxc,2021-02-03,2019-09-25
-1sx2,2004-11-23,2004-03-30
-5sx0,2016-08-24,2016-08-09
-7sxt,2021-12-29,2021-11-24
-1sxk,2004-04-13,2004-03-31
-8sxm,2023-08-23,2023-05-22
-1sxi,2004-10-19,2004-03-30
-5sxh,2017-12-27,2016-08-09
-5sxi,2017-02-15,2016-08-09
-1sx7,2004-11-30,2004-03-30
-7sxe,2022-07-13,2021-11-22
-5sxx,2016-09-07,2016-08-10
-7sx6,2022-11-30,2021-11-22
-8sx7,2024-01-17,2023-05-20
-7sxm,2022-04-06,2021-11-23
-3sxa,2012-02-29,2011-07-14
-1sx6,2004-08-31,2004-03-30
-7sxz,2021-12-29,2021-11-24
-5sxt,2016-09-07,2016-08-10
-6sxs,2020-02-26,2019-09-26
-8sxy,2023-09-13,2023-05-24
-7sxv,2021-12-29,2021-11-24
-1sxx,2004-06-08,2004-03-31
-1sxz,1998-09-30,1998-09-22
-5sxq,2016-08-31,2016-08-10
-3sxg,2012-02-29,2011-07-14
-1sx1,2004-07-06,2004-03-30
-5sxa,2017-02-15,2016-08-09
-1sxs,1998-09-30,1998-09-24
-7sx7,2022-11-30,2021-11-22
-3sxr,2011-09-21,2011-07-15
-7sx4,2021-12-29,2021-11-22
-6sx5,2021-02-03,2019-09-25
-7sxg,2023-06-14,2021-11-23
-1sxn,1998-03-18,1997-09-17
-5sx7,2016-08-31,2016-08-09
-3sxq,2012-09-26,2011-07-15
-5sxs,2016-09-07,2016-08-10
-6sx9,2020-10-07,2019-09-25
-5sx9,2017-02-15,2016-08-09
-5sx6,2016-08-31,2016-08-09
-1sxc,1995-06-03,1995-03-17
-6sxt,2020-02-26,2019-09-26
-3sxk,2011-11-16,2011-07-15
-1sxw,2004-06-08,2004-03-31
-7sx3,2021-12-29,2021-11-22
-3sxj,2011-09-07,2011-07-14
-8sx4,2023-06-21,2023-05-19
-6sxv,2020-02-26,2019-09-26
-3sxd,2012-02-29,2011-07-14
-6sxu,2020-02-26,2019-09-26
-7sxw,2021-12-29,2021-11-24
-3sxx,2012-05-02,2011-07-15
-5sxw,2016-09-07,2016-08-10
-7sx9,2022-08-31,2021-11-22
-7sxn,2022-10-05,2021-11-23
-1sxt,1997-11-19,1996-11-14
-7sx5,2022-07-13,2021-11-22
-6sxe,2021-02-03,2019-09-25
-7v3a,2021-12-15,2021-08-10
-4v3i,2014-12-17,2014-10-19
-2v3d,2007-08-14,2007-06-17
-1v33,2004-03-23,2003-10-25
-2v3p,2007-10-30,2007-06-19
-6v3a,2020-02-05,2019-11-25
-5v3h,2018-04-25,2017-03-07
-3v3l,2012-02-15,2011-12-13
-6v3j,2020-05-20,2019-11-25
-4v3w,2014-12-24,2014-10-20
-4v3k,2015-04-08,2014-10-20
-6v3i,2020-02-26,2019-11-25
-6v3q,2020-01-15,2019-11-26
-1v3t,2004-07-13,2003-11-05
-3v3y,2012-03-14,2011-12-14
-6v33,2020-01-08,2019-11-25
-7v3x,2022-04-27,2021-08-11
-2v3o,2008-06-24,2007-06-19
-5v36,2017-03-22,2017-03-06
-7v3m,2022-03-02,2021-08-10
-1v3d,2004-02-03,2003-10-30
-7v3n,2023-02-15,2021-08-10
-5v3w,2017-07-05,2017-03-08
-4v35,2015-08-19,2014-10-16
-4v32,2014-12-17,2014-10-15
-6v37,2020-02-26,2019-11-25
-4v3u,2014-12-24,2014-10-20
-2v3h,2008-06-24,2007-06-18
-6v3b,2020-02-05,2019-11-25
-2v3s,2007-07-03,2007-06-21
-5v3d,2017-08-30,2017-03-07
-4v3x,2014-12-24,2014-10-20
-1v3j,2004-08-03,2003-11-03
-3v3r,2012-09-26,2011-12-14
-5v3v,2017-04-12,2017-03-08
-4v30,2014-12-17,2014-10-15
-2v3w,2008-01-22,2007-06-25
-8v30,2024-05-01,2023-11-25
-7v3r,2022-08-17,2021-08-11
-3v3g,2012-06-20,2011-12-13
-5v3o,2017-05-03,2017-03-07
-5v3y,2017-07-05,2017-03-08
-5v3j,2018-03-07,2017-03-07
-3v36,2012-08-29,2011-12-13
-7v3v,2022-04-13,2021-08-11
-1v35,2004-09-28,2003-10-28
-7v3b,2021-12-15,2021-08-10
-6v3k,2020-02-12,2019-11-25
-6v3d,2020-02-05,2019-11-25
-7v30,2022-03-02,2021-08-10
-7v34,2023-02-15,2021-08-10
-6v3y,2021-05-26,2019-11-26
-2v3i,2008-07-01,2007-06-18
-1v34,2004-03-23,2003-10-25
-6v38,2019-12-25,2019-11-25
-1v3m,2004-08-03,2003-11-03
-2v3x,2007-11-20,2007-06-25
-6v34,2020-12-02,2019-11-25
-3v3z,2012-03-14,2011-12-14
-4v3c,2015-04-08,2014-10-17
-7v36,2023-02-15,2021-08-10
-3v3q,2012-09-26,2011-12-14
-3v3b,2012-01-18,2011-12-13
-3v3n,2013-01-02,2011-12-13
-4v3q,2016-01-13,2014-10-20
-5v3t,2017-04-12,2017-03-08
-4v3j,2016-01-20,2014-10-20
-7v37,2021-12-15,2021-08-10
-2v3z,2007-11-20,2007-06-25
-7v3k,2022-08-17,2021-08-10
-7v3o,2023-02-15,2021-08-10
-4v3d,2014-12-17,2014-10-17
-4v33,2015-04-08,2014-10-16
-7v3h,2021-12-29,2021-08-10
-7v3c,2021-12-15,2021-08-10
-1v3q,2004-01-20,2003-11-04
-2v3b,2007-08-14,2007-06-14
-1v3s,2004-11-23,2003-11-05
-7v32,2022-03-02,2021-08-10
-5v3m,2018-03-07,2017-03-07
-3v3f,2012-06-20,2011-12-13
-7v3z,2021-11-24,2021-08-12
-4v3v,2014-12-24,2014-10-20
-1v3c,2004-02-03,2003-10-30
-2v3k,2007-07-10,2007-06-18
-2v3g,2007-09-18,2007-06-18
-1v3v,2004-07-13,2003-11-06
-6v36,2020-02-26,2019-11-25
-1v3e,2004-02-03,2003-10-30
-7v3s,2022-08-17,2021-08-11
-5v35,2017-07-26,2017-03-06
-6v39,2020-02-05,2019-11-25
-4v3y,2014-12-24,2014-10-20
-3v3h,2012-06-20,2011-12-13
-7v3d,2022-07-06,2021-08-10
-5v3q,2017-12-20,2017-03-07
-2v3a,2007-08-14,2007-06-14
-3v34,2012-05-23,2011-12-12
-3v3i,2012-06-20,2011-12-13
-5v32,2017-08-16,2017-03-06
-3v38,2012-12-19,2011-12-13
-4v3e,2014-12-17,2014-10-17
-2v3r,2008-07-01,2007-06-21
-1v3x,2004-11-07,2003-11-07
-7v3g,2021-12-29,2021-08-10
-5v33,2017-04-12,2017-03-06
-2v3f,2008-04-08,2007-06-17
-3v3j,2012-06-20,2011-12-13
-4v31,2014-12-17,2014-10-15
-3v35,2012-08-29,2011-12-13
-2v3t,2007-08-07,2007-06-22
-1v39,1997-09-17,1996-12-16
-4v3z,2014-12-24,2014-10-20
-6v35,2019-12-25,2019-11-25
-4v3o,2016-01-13,2014-10-20
-1v3b,2004-02-03,2003-10-30
-5v3g,2017-08-23,2017-03-07
-6v3x,2021-05-26,2019-11-26
-7v3w,2022-04-06,2021-08-11
-3v3c,2012-10-03,2011-12-13
-5v3u,2017-04-26,2017-03-08
-6v3m,2020-12-09,2019-11-26
-7v31,2022-03-02,2021-08-10
-6v3f,2020-07-01,2019-11-25
-2v30,2007-07-24,2007-06-10
-6v3c,2020-02-26,2019-11-25
-1v3z,2004-11-30,2003-11-07
-5v3c,2018-05-16,2017-03-07
-4v3l,2015-04-08,2014-10-20
-3v3v,2012-12-05,2011-12-14
-4v3b,2015-04-08,2014-10-17
-3v31,2012-04-04,2011-12-12
-7v3f,2021-12-29,2021-08-10
-7v3p,2022-08-17,2021-08-11
-2v3y,2007-11-20,2007-06-25
-2v35,2008-06-24,2007-06-12
-2v38,2007-06-26,2007-06-13
-3v3w,2012-01-11,2011-12-14
-2v3n,2007-10-30,2007-06-19
-1v3k,2004-08-03,2003-11-03
-5v37,2018-03-07,2017-03-06
-8v3k,2024-01-24,2023-11-28
-1v3w,2003-11-18,2003-11-07
-1v3h,2004-06-22,2003-11-02
-6v3t,2020-02-05,2019-11-26
-7v3e,2023-02-15,2021-08-10
-2v34,2007-06-26,2007-06-11
-5v34,2017-08-16,2017-03-06
-4v3r,2016-01-13,2014-10-20
-1v3i,2004-06-22,2003-11-02
-7v3u,2022-04-13,2021-08-11
-3v3o,2013-01-30,2011-12-13
-5v31,2017-08-16,2017-03-06
-4v36,2015-08-19,2014-10-16
-5v3x,2017-07-05,2017-03-08
-6v3u,2020-01-15,2019-11-26
-1v3l,2004-08-03,2003-11-03
-3v3x,2012-08-29,2011-12-14
-2v3e,2007-08-21,2007-06-17
-5v39,2018-03-14,2017-03-06
-7v33,2022-03-02,2021-08-10
-3v3m,2013-01-16,2011-12-13
-7v38,2021-12-15,2021-08-10
-6v3w,2020-12-16,2019-11-26
-4v37,2016-01-20,2014-10-16
-6v3h,2020-07-01,2019-11-25
-6v3r,2020-02-26,2019-11-26
-2v3u,2007-08-07,2007-06-22
-5v3a,2017-05-24,2017-03-06
-7v39,2021-12-15,2021-08-10
-3s0n,2011-07-20,2011-05-13
-4s01,2015-08-05,2014-12-27
-6s0j,2020-07-15,2019-06-16
-7s0q,2022-07-06,2021-08-30
-1s0c,2004-03-16,2003-12-30
-4s04,2015-11-11,2014-12-30
-7s0f,2021-11-17,2021-08-30
-7s0b,2021-10-06,2021-08-30
-6s0r,2020-07-08,2019-06-18
-1s0p,2004-01-27,2004-01-01
-7s0u,2022-01-26,2021-08-31
-6s0b,2019-09-04,2019-06-14
-1s01,1990-10-15,1989-08-21
-7s04,2021-11-03,2021-08-28
-1s00,2004-04-13,2003-12-29
-6s0o,2019-07-17,2019-06-17
-6s0u,2020-07-08,2019-06-18
-6s05,2019-06-26,2019-06-13
-6s0l,2020-07-15,2019-06-17
-7s0t,2022-03-09,2021-08-31
-1s0f,2004-03-16,2003-12-30
-3s0j,2011-08-31,2011-05-13
-6s00,2019-11-06,2019-06-13
-3s0z,2011-06-01,2011-05-13
-6s0s,2020-07-08,2019-06-18
-4s0g,2015-03-11,2014-12-31
-6s0c,2020-04-22,2019-06-14
-4s0n,2015-05-27,2015-01-02
-3s0t,2012-04-11,2011-05-13
-5s00,2020-11-11,2020-10-30
-1s0x,2004-02-10,2004-01-05
-1s0b,2004-03-16,2003-12-30
-6s0f,2019-11-06,2019-06-14
-7s0k,2022-07-06,2021-08-30
-1s0z,2004-04-13,2004-01-05
-1s02,1992-01-15,1991-02-20
-7s06,2022-03-30,2021-08-30
-6s0v,2020-07-08,2019-06-18
-7s0m,2021-10-13,2021-08-30
-3s0o,2012-10-31,2011-05-13
-8s03,2024-04-17,2024-02-13
-3s0b,2011-11-30,2011-05-13
-7s02,2021-12-29,2021-08-28
-4s0t,2015-02-04,2015-01-05
-7s0g,2021-11-17,2021-08-30
-7s0z,2021-09-08,2021-08-31
-6s0t,2020-07-08,2019-06-18
-1s0e,2004-03-16,2003-12-30
-6s0m,2019-08-28,2019-06-17
-1s08,2004-03-23,2003-12-30
-7s0p,2021-10-27,2021-08-30
-1s0a,2004-03-23,2003-12-30
-6s09,2020-07-15,2019-06-14
-4s0f,2015-07-22,2014-12-30
-6s0w,2020-07-08,2019-06-18
-1s0o,2004-03-30,2003-12-31
-6s07,2019-06-26,2019-06-14
-7s01,2022-07-06,2021-08-28
-1s0r,2005-01-18,2004-01-02
-6s0p,2020-07-15,2019-06-17
-6s0d,2020-04-22,2019-06-14
-6s0a,2019-09-04,2019-06-14
-4s0x,2015-02-11,2015-01-07
-4s0q,2015-11-18,2015-01-04
-1s09,2004-03-23,2003-12-30
-1s0h,2005-02-01,2003-12-31
-4s05,2015-11-11,2014-12-30
-6s0q,2020-07-15,2019-06-18
-6s03,2020-06-03,2019-06-13
-6s02,2019-10-02,2019-06-13
-1s0i,2004-05-18,2003-12-31
-3s0p,2012-06-27,2011-05-13
-1s03,2004-05-25,2003-12-29
-3s0m,2012-04-25,2011-05-13
-7s0s,2022-03-30,2021-08-31
-3s04,2011-10-05,2011-05-13
-6s0z,2019-08-21,2019-06-18
-7s05,2022-03-30,2021-08-30
-4s0m,2015-02-11,2015-01-02
-7s0c,2021-10-06,2021-08-30
-3s0d,2011-11-30,2011-05-13
-1s0u,2004-01-20,2004-01-04
-7s0i,2021-12-08,2021-08-30
-6s0k,2019-10-09,2019-06-17
-1s0n,2004-03-30,2003-12-31
-7s00,2022-07-06,2021-08-28
-1s0m,2004-03-30,2003-12-31
-7s07,2022-11-09,2021-08-30
-1s0w,2004-02-10,2004-01-05
-1s0j,2004-05-18,2003-12-31
-6s06,2020-07-15,2019-06-14
-6s04,2019-11-06,2019-06-13
-7s0w,2022-05-04,2021-08-31
-1s07,2004-03-23,2003-12-30
-3s0e,2011-11-30,2011-05-13
-1s0d,2004-03-16,2003-12-30
-4s0v,2015-01-14,2015-01-06
-7s0v,2021-11-10,2021-08-31
-1s06,2004-03-23,2003-12-30
-3s00,2012-10-31,2011-05-12
-6s0e,2019-11-06,2019-06-14
-6s0i,2020-07-15,2019-06-14
-4s00,2015-08-05,2014-12-27
-1s05,2004-01-20,2003-12-30
-6s0h,2020-04-01,2019-06-14
-1s0q,2005-01-18,2004-01-02
-7s0y,2021-09-08,2021-08-31
-6s0g,2020-01-29,2019-06-14
-1s0v,2004-02-24,2004-01-05
-6s08,2019-09-04,2019-06-14
-4s0r,2015-03-04,2015-01-04
-3s0k,2012-02-08,2011-05-13
-2cdu,2006-07-17,2006-01-28
-4cd5,2014-04-02,2013-10-30
-7cdw,2021-09-22,2020-06-20
-5cdn,2015-12-16,2015-07-04
-7cdy,2021-06-23,2020-06-21
-8cdk,2023-04-19,2023-01-31
-2cd2,2000-03-29,1999-03-15
-2cdq,2006-05-30,2006-01-26
-3cd8,2008-04-29,2008-02-26
-2cdo,2006-02-16,2006-01-25
-3cdw,2008-07-22,2008-02-27
-1cdr,1994-09-30,1994-06-01
-6cdl,2018-05-30,2018-02-08
-4cd8,2014-04-02,2013-10-30
-7cdp,2021-03-10,2020-06-20
-7cdd,2021-06-23,2020-06-19
-7cdf,2021-06-23,2020-06-19
-7cdh,2020-12-30,2020-06-19
-5cdw,2016-05-25,2015-07-05
-1cdo,1996-03-08,1995-09-29
-7cd0,2021-03-17,2020-06-18
-6cdu,2018-08-22,2018-02-09
-4cdw,2014-02-12,2013-11-06
-8cdz,2024-02-21,2023-02-01
-2cdn,2006-05-10,2006-01-25
-2cd7,2006-06-28,2006-01-23
-2cdy,2006-02-13,2006-01-31
-4cdr,2013-12-04,2013-11-05
-1cde,1993-10-31,1992-05-15
-8cdr,2023-09-20,2023-01-31
-6cdz,2018-05-16,2018-02-09
-2cdr,2007-03-20,2006-01-27
-8cd1,2024-01-24,2023-01-29
-3cd2,2000-03-29,1999-03-16
-6cdg,2018-03-07,2018-02-08
-3cd7,2008-06-17,2008-02-26
-3cdq,2009-02-17,2008-02-27
-5cd1,2015-11-04,2015-07-02
-7cdt,2021-03-10,2020-06-20
-8cdw,2023-08-16,2023-02-01
-6cde,2018-05-16,2018-02-08
-5cd5,2016-04-06,2015-07-03
-7cdx,2020-07-15,2020-06-20
-1cd2,2000-03-06,1999-03-05
-2cdv,1984-02-02,1983-11-15
-5cdm,2015-12-16,2015-07-04
-4cdq,2014-02-12,2013-11-05
-8cdg,2023-12-06,2023-01-30
-8cdq,2023-06-21,2023-01-31
-6cd6,2018-03-07,2018-02-08
-8cdl,2023-09-20,2023-01-31
-1cds,1994-09-30,1994-06-01
-6cdd,2018-07-04,2018-02-08
-1cd9,2000-03-08,1999-03-08
-4cdx,2014-02-12,2013-11-07
-8cd8,2023-03-22,2023-01-30
-1cdg,1994-01-31,1993-08-02
-5cdr,2015-12-16,2015-07-04
-8cd3,2024-01-31,2023-01-30
-4cde,2014-03-19,2013-10-31
-4cdz,2014-11-26,2013-11-08
-4cdm,2014-05-21,2013-11-01
-5cd6,2015-07-29,2015-07-03
-5cdq,2015-12-16,2015-07-04
-7cdm,2021-03-10,2020-06-20
-1cdp,1990-10-15,1990-01-24
-4cd1,2014-02-12,2013-10-29
-7cd4,2021-03-03,2020-06-18
-4cdd,2014-03-19,2013-10-31
-7cd5,2021-01-13,2020-06-18
-7cdj,2020-11-18,2020-06-19
-7cdn,2021-03-10,2020-06-20
-4cdy,2014-05-21,2013-11-07
-6cd4,2018-08-29,2018-02-08
-2cdz,2006-02-08,2006-01-31
-3cds,2008-12-30,2008-02-27
-6cd3,2018-06-06,2018-02-07
-8cdf,2023-05-31,2023-01-30
-5cde,2016-09-14,2015-07-03
-2cd8,2007-02-20,2006-01-20
-7cdr,2021-03-10,2020-06-20
-4cdn,2014-05-21,2013-11-01
-6cdb,2018-07-11,2018-02-08
-4cdu,2014-02-12,2013-11-06
-4cdf,2014-03-19,2013-10-31
-4cdv,2014-05-21,2013-11-06
-4cdh,2014-11-12,2013-10-31
-8cd0,2024-02-07,2023-01-29
-3cd0,2008-06-17,2008-02-26
-3cdb,2008-06-17,2008-02-26
-6cdm,2018-05-16,2018-02-08
-3cda,2008-06-17,2008-02-26
-4cd3,2014-02-12,2013-10-29
-6cdf,2018-05-09,2018-02-08
-3cd3,2008-03-25,2008-02-26
-4cdc,2014-03-19,2013-10-31
-7cdq,2021-03-10,2020-06-20
-8cdx,2024-02-21,2023-02-01
-4cda,2014-05-21,2013-10-30
-4cd4,2014-04-02,2013-10-30
-4cd0,2014-01-29,2013-10-29
-7cde,2021-06-23,2020-06-19
-6cdy,2020-07-01,2018-02-09
-6cdr,2018-05-09,2018-02-09
-6cd1,2018-05-23,2018-02-07
-1cdl,1994-08-31,1993-10-08
-5cdg,2015-07-15,2015-07-03
-3cd6,2008-05-20,2008-02-26
-4cdt,2014-02-19,2013-11-05
-5cdp,2015-12-16,2015-07-04
-6cda,2018-07-11,2018-02-08
-6cd8,2018-03-07,2018-02-08
-5cdt,2015-07-15,2015-07-04
-3cdg,2008-04-22,2008-02-26
-6cds,2018-07-18,2018-02-09
-3cde,2009-03-03,2008-02-26
-4cdl,2014-11-12,2013-11-01
-7cdi,2020-11-18,2020-06-19
-6cdw,2018-07-18,2018-02-09
-7cdl,2021-06-23,2020-06-20
-5cds,2015-07-15,2015-07-04
-6cd7,2018-02-28,2018-02-08
-5cd2,2015-07-22,2015-07-02
-4cd6,2014-04-02,2013-10-30
-4cdp,2013-11-13,2013-11-05
-6cdh,2018-07-04,2018-02-08
-2cdp,2006-02-08,2006-01-26
-8cdo,2024-01-24,2023-01-31
-8cdm,2024-02-21,2023-01-31
-6cdo,2018-05-16,2018-02-08
-6cdp,2018-05-16,2018-02-08
-3cd5,2008-06-17,2008-02-26
-6cdq,2018-02-21,2018-02-09
-7cdg,2021-06-23,2020-06-19
-5cdl,2016-08-10,2015-07-04
-5cd4,2015-08-26,2015-07-03
-7cdo,2021-03-10,2020-06-20
-2cdb,2006-03-22,2006-01-23
-7cda,2021-06-23,2020-06-19
-5cdu,2015-07-15,2015-07-04
-8cdu,2023-12-20,2023-02-01
-3cdp,2009-01-13,2008-02-27
-7cd9,2021-04-07,2020-06-19
-7cdc,2021-06-23,2020-06-19
-6cd5,2019-01-16,2018-02-08
-2cdc,2006-03-22,2006-01-23
-7cd6,2021-01-13,2020-06-18
-6cdj,2018-05-30,2018-02-08
-4cdb,2014-04-23,2013-10-30
-2cd9,2006-03-22,2006-01-23
-4cdg,2013-11-13,2013-10-31
-7cds,2021-03-10,2020-06-20
-5cdv,2016-08-10,2015-07-05
-5cdo,2015-12-16,2015-07-04
-6cdi,2018-05-16,2018-02-08
-7cdu,2021-03-10,2020-06-20
-4cd2,2000-03-29,1999-03-18
-1cdk,1995-10-15,1994-07-04
-7cdk,2021-03-10,2020-06-20
-3cdz,2008-04-01,2008-02-27
-3cdx,2008-03-11,2008-02-27
-8cd9,2024-02-21,2023-01-30
-1cdm,1994-08-31,1993-10-08
-4cd7,2014-04-02,2013-10-30
-6cdn,2018-07-04,2018-02-08
-2cda,2006-03-22,2006-01-23
-8cdb,2023-03-22,2023-01-30
-1vln,1997-04-01,1996-04-03
-8vl0,2024-05-08,2024-01-11
-1vlb,2004-07-27,2004-07-20
-7vl4,2022-03-09,2021-10-01
-5vl8,2018-04-18,2017-04-25
-5vlc,2017-09-20,2017-04-25
-2vl6,2008-04-29,2008-01-08
-2vly,2008-01-29,2008-01-20
-7vla,2022-03-23,2021-10-02
-7vl5,2022-03-09,2021-10-01
-7vls,2022-05-18,2021-10-05
-6vlg,2020-02-26,2020-01-23
-3vlu,2012-01-25,2011-12-05
-7vln,2022-07-06,2021-10-05
-1vlt,1997-05-15,1996-09-17
-8vl8,2024-04-03,2024-01-11
-6vlt,2020-09-30,2020-01-25
-1vlx,1997-03-12,1996-10-08
-3vlc,2012-06-20,2011-11-30
-2vlc,2009-02-10,2008-01-11
-1vlg,2004-08-17,2004-07-23
-3vll,2012-12-05,2011-12-01
-3vlx,2012-09-26,2011-12-05
-5vl2,2018-04-25,2017-04-24
-5vld,2017-09-20,2017-04-25
-2vlx,2009-02-10,2008-01-20
-6vlu,2020-05-06,2020-01-27
-3vla,2012-04-18,2011-11-30
-7vlx,2021-12-01,2021-10-05
-1vlj,2004-08-17,2004-07-28
-5vlr,2017-06-07,2017-04-26
-7vl7,2022-03-09,2021-10-01
-1vl0,2004-08-17,2004-06-30
-5vlg,2018-06-27,2017-04-25
-6vll,2021-02-24,2020-01-24
-3vl3,2012-02-29,2011-11-29
-2vl8,2008-06-17,2008-01-09
-7vl0,2022-03-09,2021-10-01
-5vll,2017-08-16,2017-04-25
-2vlr,2008-01-22,2008-01-15
-7vlc,2022-05-18,2021-10-02
-7vly,2021-12-01,2021-10-05
-6vlm,2020-05-13,2020-01-24
-6vlv,2020-05-06,2020-01-27
-7vlh,2022-08-10,2021-10-02
-1vl3,2004-07-20,2004-07-05
-7vlt,2022-05-18,2021-10-05
-6vl4,2020-12-02,2020-01-22
-5vlx,2017-12-27,2017-04-26
-2vlj,2008-01-22,2008-01-15
-3vlh,2012-12-05,2011-12-01
-1vli,2004-09-21,2004-07-27
-6vlb,2020-11-11,2020-01-23
-3vl6,2012-02-29,2011-11-29
-7vlq,2022-04-06,2021-10-05
-2vl4,2008-04-01,2008-01-08
-7vl9,2022-03-23,2021-10-02
-3vl7,2012-02-29,2011-11-29
-8vlb,2024-03-13,2024-01-11
-3vl2,2012-02-29,2011-11-29
-5vlm,2018-06-27,2017-04-25
-3vlk,2012-12-05,2011-12-01
-2vla,2008-05-06,2008-01-11
-5vlb,2017-09-20,2017-04-25
-7vl1,2022-03-09,2021-10-01
-2vlz,2008-01-29,2008-01-20
-2vli,2008-06-17,2008-01-15
-2vlk,2008-01-22,2008-01-15
-5vlk,2017-08-16,2017-04-25
-7vl3,2022-03-09,2021-10-01
-7vlr,2022-05-18,2021-10-05
-7vlb,2022-10-05,2021-10-02
-6vl7,2020-04-08,2020-01-22
-7vlo,2022-04-06,2021-10-05
-5vl0,2017-05-03,2017-04-24
-5vl1,2017-05-10,2017-04-24
-6vly,2020-04-29,2020-01-27
-2vlf,2008-08-19,2008-01-14
-6vlk,2020-07-15,2020-01-24
-6vl1,2020-04-08,2020-01-22
-2vle,2008-08-19,2008-01-13
-7vle,2022-05-18,2021-10-02
-7vlj,2021-11-17,2021-10-03
-3vly,2012-09-26,2011-12-05
-5vl3,2017-10-11,2017-04-24
-6vl5,2020-08-12,2020-01-22
-5vlq,2017-05-31,2017-04-25
-1vlm,2004-08-24,2004-08-04
-2vlh,2008-08-19,2008-01-14
-3vl4,2012-02-29,2011-11-29
-5vli,2017-09-27,2017-04-25
-5vle,2017-11-08,2017-04-25
-6vlw,2020-12-09,2020-01-27
-7vlz,2022-10-19,2021-10-05
-1vl8,2004-08-17,2004-07-14
-7vld,2022-05-18,2021-10-02
-7vl6,2022-03-09,2021-10-01
-7vli,2022-08-10,2021-10-02
-1vly,2004-08-31,2004-08-20
-3vlz,2012-09-26,2011-12-05
-5vlp,2017-08-16,2017-04-25
-1vl9,2004-10-19,2004-07-15
-2vl1,2008-05-13,2008-01-07
-3vlj,2012-12-05,2011-12-01
-5vlh,2017-08-16,2017-04-25
-3vli,2012-12-05,2011-12-01
-5vla,2017-08-16,2017-04-25
-6vlh,2021-01-27,2020-01-24
-6vlo,2020-03-04,2020-01-24
-7vlu,2022-05-18,2021-10-05
-1vlh,2004-08-17,2004-07-23
-7vl2,2022-03-09,2021-10-01
-3vln,2012-05-16,2011-12-02
-7vl8,2022-03-23,2021-10-02
-6vl3,2021-02-10,2020-01-22
-7vlm,2021-12-01,2021-10-04
-5vlo,2017-08-23,2017-04-25
-6vlz,2020-08-05,2020-01-27
-7vlf,2022-05-18,2021-10-02
-7vlg,2022-08-10,2021-10-02
-3vl9,2012-04-18,2011-11-30
-6vlr,2020-06-24,2020-01-24
-3vlv,2012-01-25,2011-12-05
-3vlm,2012-12-05,2011-12-01
-7vlp,2022-04-06,2021-10-05
-6vl0,2020-04-08,2020-01-22
-5vl5,2018-04-18,2017-04-24
-2vll,2008-01-22,2008-01-15
-6vld,2020-02-26,2020-01-23
-6vlc,2020-11-11,2020-01-23
-3vlw,2012-01-25,2011-12-05
-6ftm,2019-03-20,2018-02-22
-6ftj,2018-03-21,2018-02-22
-7ftk,2024-02-21,2023-02-08
-2ftl,2006-02-14,2006-01-24
-3ft4,2009-04-28,2009-01-12
-7ft4,2023-02-15,2023-01-24
-6ftx,2018-08-08,2018-02-25
-5fti,2016-02-03,2016-01-13
-5ftw,2016-10-05,2016-01-18
-8fty,2024-01-17,2023-01-14
-7ftn,2024-02-21,2023-02-08
-3ftk,2009-06-30,2009-01-13
-3ftg,2009-12-29,2009-01-12
-6ftc,2018-06-06,2018-02-21
-7fts,2024-02-21,2023-02-08
-3ft0,2009-03-10,2009-01-12
-2ft0,2006-08-01,2006-01-23
-6fty,2018-06-06,2018-02-26
-2ftx,2006-06-13,2006-01-25
-3ft3,2009-04-28,2009-01-12
-4ftt,2012-08-22,2012-06-28
-6ftf,2019-04-03,2018-02-21
-1ftl,2000-11-01,2000-09-12
-3fth,2009-06-30,2009-01-13
-5ft9,2016-01-27,2016-01-12
-7ft8,2023-02-15,2023-01-24
-5ftl,2016-01-27,2016-01-14
-5fty,2017-02-22,2016-01-18
-1ftk,2000-11-01,2000-09-12
-7ftm,2024-02-21,2023-02-08
-2ftp,2006-03-14,2006-01-24
-5ft2,2016-03-02,2016-01-09
-3ftr,2009-06-30,2009-01-13
-4ft7,2012-08-22,2012-06-27
-6ft2,2018-03-28,2018-02-20
-1ft2,1998-11-04,1998-06-02
-3fts,2009-07-28,2009-01-13
-8ftq,2024-03-27,2023-01-13
-1ft7,2000-10-04,2000-09-11
-3ftf,2009-03-24,2009-01-12
-4fts,2012-08-01,2012-06-28
-6ftp,2018-05-23,2018-02-22
-7ftq,2024-02-21,2023-02-08
-5ftn,2016-01-27,2016-01-14
-5ftm,2016-01-27,2016-01-14
-5ftx,2017-02-22,2016-01-18
-5ft3,2017-02-22,2016-01-11
-7ft5,2023-02-15,2023-01-24
-7ft1,2023-02-15,2023-01-24
-6fta,2019-03-20,2018-02-20
-7fti,2024-02-21,2023-02-08
-7ftj,2024-02-21,2023-02-08
-6ftz,2018-06-06,2018-02-26
-6ftw,2019-03-20,2018-02-24
-8ft0,2024-01-17,2023-01-11
-4ftq,2012-08-22,2012-06-27
-3ftz,2010-01-05,2009-01-13
-4fti,2012-08-22,2012-06-27
-8ft8,2023-03-01,2023-01-11
-2ft9,2006-04-11,2006-01-24
-1ft9,2000-10-09,2000-09-12
-8ftg,2023-06-07,2023-01-12
-7ftt,2024-02-21,2023-02-08
-5ft0,2016-08-03,2016-01-08
-3ftu,2009-07-28,2009-01-13
-7fta,2023-02-15,2023-01-24
-7ft6,2023-02-15,2023-01-24
-1ft4,2001-10-12,2000-09-11
-1ft5,2000-09-20,2000-09-11
-1ftn,1998-03-18,1997-03-13
-4ftr,2012-08-22,2012-06-27
-6ft7,2018-05-16,2018-02-20
-8fto,2023-08-02,2023-01-12
-5ftk,2016-01-27,2016-01-14
-7ftl,2024-02-21,2023-02-08
-2fto,2006-05-02,2006-01-24
-4ft8,2013-12-18,2012-06-27
-3ftw,2009-07-28,2009-01-13
-1ftq,2000-10-04,2000-09-13
-4ftj,2012-08-22,2012-06-27
-1ftm,2000-11-01,2000-09-12
-5fth,2016-02-03,2016-01-13
-7ft9,2023-02-15,2023-01-24
-7ftw,2024-02-21,2023-02-08
-4ftw,2012-10-03,2012-06-28
-1fty,2000-10-04,2000-09-13
-5fts,2017-02-22,2016-01-14
-6ft9,2018-05-16,2018-02-20
-1ftj,2000-11-01,2000-09-12
-8ftc,2023-12-06,2023-01-11
-7ft2,2023-02-15,2023-01-24
-2ft3,2006-03-28,2006-01-23
-2ftw,2006-03-14,2006-01-25
-1ft6,2000-09-20,2000-09-11
-6ft0,2019-03-20,2018-02-20
-6ftl,2018-06-27,2018-02-22
-6ft8,2018-05-16,2018-02-20
-6ft4,2018-04-18,2018-02-20
-2ftd,2007-01-30,2006-01-24
-6ftv,2018-08-15,2018-02-23
-5ft8,2016-11-23,2016-01-11
-4ftn,2012-08-22,2012-06-27
-8ft4,2023-11-22,2023-01-11
-5ftz,2016-04-27,2016-01-19
-3ftx,2009-07-28,2009-01-13
-7fto,2024-02-21,2023-02-08
-4ft3,2012-08-22,2012-06-27
-8ftr,2023-11-01,2023-01-13
-4fte,2012-08-01,2012-06-27
-8ftv,2023-11-01,2023-01-13
-5fto,2016-04-06,2016-01-14
-8ftl,2024-01-17,2023-01-12
-4ftm,2012-08-22,2012-06-27
-8ft7,2023-01-25,2023-01-11
-7ft3,2023-02-15,2023-01-24
-7ft7,2023-02-15,2023-01-24
-7fth,2024-02-21,2023-02-08
-2fty,2006-03-14,2006-01-25
-4ft5,2012-08-22,2012-06-27
-4ftb,2012-08-01,2012-06-27
-5ft1,2016-08-03,2016-01-08
-3fty,2009-07-28,2009-01-13
-1ftx,2003-01-14,2000-09-13
-4ft9,2012-08-22,2012-06-27
-6fte,2019-01-09,2018-02-21
-4fto,2012-08-22,2012-06-27
-7ftb,2023-02-15,2023-01-24
-7ftr,2024-02-21,2023-02-08
-1fth,2001-09-12,2000-09-12
-8ftd,2024-01-10,2023-01-11
-1ft1,1998-03-18,1997-03-17
-8ftp,2023-10-11,2023-01-12
-8fth,2023-10-25,2023-01-12
-3ftv,2009-07-28,2009-01-13
-5ft4,2016-12-21,2016-01-11
-8ftm,2023-10-25,2023-01-12
-2ft7,2006-04-11,2006-01-24
-8ft5,2023-11-22,2023-01-11
-5ftc,2016-02-03,2016-01-12
-2ftm,2006-02-14,2006-01-24
-6ft3,2018-04-18,2018-02-20
-2ft6,2006-04-11,2006-01-24
-5fte,2016-02-03,2016-01-12
-5ftg,2016-03-23,2016-01-13
-2ft2,2006-07-25,2006-01-23
-3ft5,2009-05-05,2009-01-12
-7ftf,2024-02-21,2023-02-08
-6ft1,2018-07-11,2018-02-20
-4ft0,2012-08-22,2012-06-27
-6fti,2018-03-21,2018-02-22
-6ftg,2018-03-21,2018-02-22
-1fta,1995-11-14,1993-09-27
-7fty,2024-02-21,2023-02-08
-7ft0,2023-02-15,2023-01-24
-8ft2,2024-01-17,2023-01-11
-4ftu,2012-08-22,2012-06-28
-5fta,2016-02-17,2016-01-12
-8ft3,2024-01-17,2023-01-11
-4ft6,2013-07-24,2012-06-27
-5ft5,2016-11-23,2016-01-11
-7ftd,2023-02-15,2023-01-24
-7ftu,2024-02-21,2023-02-08
-6ftb,2018-06-27,2018-02-20
-4ftf,2012-11-28,2012-06-27
-7ftv,2024-02-21,2023-02-08
-5ftq,2016-04-06,2016-01-14
-4ftc,2012-08-22,2012-06-27
-7ftg,2024-02-21,2023-02-08
-4ftv,2013-07-03,2012-06-28
-5ftv,2017-02-22,2016-01-18
-3ft2,2009-04-28,2009-01-12
-5ftf,2016-02-03,2016-01-13
-5ftb,2016-02-03,2016-01-12
-3ftn,2010-01-26,2009-01-13
-7ftp,2024-02-21,2023-02-08
-6ftn,2018-06-20,2018-02-22
-7ftz,2024-02-21,2023-02-08
-4ftk,2012-08-22,2012-06-27
-2ft8,2006-04-11,2006-01-24
-5ftt,2016-05-04,2016-01-15
-2fta,2006-04-11,2006-01-24
-6ft6,2018-03-28,2018-02-20
-4ft2,2012-10-17,2012-06-27
-5ftj,2016-01-27,2016-01-14
-4ft4,2012-10-17,2012-06-27
-5ft6,2016-11-23,2016-01-11
-6ftt,2018-10-24,2018-02-23
-5ftu,2016-05-04,2016-01-15
-4fta,2012-08-22,2012-06-27
-2ftk,2006-07-18,2006-01-24
-8fts,2023-11-01,2023-01-13
-6ftd,2018-07-18,2018-02-21
-6ftr,2018-10-10,2018-02-23
-3ft8,2009-06-30,2009-01-12
-7ftx,2024-02-21,2023-02-08
-8ft1,2024-01-17,2023-01-11
-4ftl,2012-08-22,2012-06-27
-3ftq,2009-09-22,2009-01-13
-3ftl,2009-06-30,2009-01-13
-1ftw,2000-10-04,2000-09-13
-8fta,2024-01-24,2023-01-11
-7ftc,2023-02-15,2023-01-24
-6t20,2020-03-04,2019-10-07
-7t29,2021-12-15,2021-12-03
-5t2l,2017-04-19,2016-08-23
-8t27,2023-10-04,2023-06-05
-3t26,2011-12-28,2011-07-22
-5t2v,2017-02-15,2016-08-24
-6t2b,2020-02-26,2019-10-08
-6t2q,2020-07-08,2019-10-09
-5t25,2017-03-01,2016-08-23
-1t2f,2004-05-11,2004-04-21
-7t2k,2023-06-14,2021-12-05
-6t24,2020-03-04,2019-10-07
-6t25,2020-03-04,2019-10-07
-5t21,2017-08-23,2016-08-23
-1t2d,2004-05-11,2004-04-21
-5t22,2017-08-23,2016-08-23
-6t2e,2020-01-29,2019-10-08
-1t24,2004-05-11,2004-04-20
-3t2t,2011-12-28,2011-07-23
-1t2n,2004-11-23,2004-04-22
-5t26,2016-10-05,2016-08-23
-6t2a,2021-04-14,2019-10-08
-5t2z,2017-01-11,2016-08-24
-1t2a,2004-05-10,2004-04-20
-7t2j,2023-06-14,2021-12-05
-6t2z,2020-11-18,2019-10-10
-1t2v,2004-05-11,2004-04-22
-7t2u,2022-09-14,2021-12-06
-3t2a,2011-12-28,2011-07-22
-8t24,2023-10-04,2023-06-05
-7t28,2022-04-20,2021-12-03
-1t26,2004-05-11,2004-04-20
-6t2h,2020-01-01,2019-10-08
-6t2s,2020-07-08,2019-10-09
-7t2a,2022-12-28,2021-12-03
-7t2p,2022-10-19,2021-12-06
-3t2i,2011-12-28,2011-07-22
-7t21,2023-01-18,2021-12-02
-1t2s,2004-06-01,2004-04-22
-8t2r,2023-11-22,2023-06-06
-7t20,2022-12-14,2021-12-02
-3t27,2011-12-28,2011-07-22
-7t25,2022-12-14,2021-12-03
-7t2q,2022-10-26,2021-12-06
-3t2g,2011-10-26,2011-07-22
-5t2h,2017-05-03,2016-08-23
-3t2d,2011-10-26,2011-07-22
-7t2x,2022-06-22,2021-12-06
-8t2u,2023-07-26,2023-06-06
-7t2c,2022-12-28,2021-12-03
-7t2z,2022-02-23,2021-12-06
-1t2b,2005-04-26,2004-04-20
-1t20,2005-09-06,2004-04-19
-3t2q,2012-01-18,2011-07-22
-7t22,2023-01-18,2021-12-02
-6t2p,2020-07-08,2019-10-09
-6t27,2020-10-21,2019-10-08
-7t2h,2022-12-07,2021-12-04
-3t25,2011-12-28,2011-07-22
-6t28,2019-11-13,2019-10-08
-5t2y,2017-02-22,2016-08-24
-6t2k,2020-01-01,2019-10-08
-1t2u,2004-05-11,2004-04-22
-3t2f,2011-10-26,2011-07-22
-5t2u,2017-02-15,2016-08-24
-5t2m,2017-04-19,2016-08-23
-7t2i,2022-01-19,2021-12-04
-1t2e,2004-05-11,2004-04-21
-3t2z,2011-08-17,2011-07-23
-6t2o,2020-07-08,2019-10-09
-1t25,2004-05-11,2004-04-20
-6t26,2020-10-21,2019-10-07
-6t2w,2020-01-01,2019-10-09
-1t2x,2004-05-18,2004-04-23
-6t2t,2020-01-29,2019-10-09
-6t2m,2020-08-26,2019-10-09
-5t23,2017-04-19,2016-08-23
-1t2t,2004-09-07,2004-04-22
-8t2v,2023-07-26,2023-06-06
-3t2y,2012-05-16,2011-07-23
-7t2r,2022-03-16,2021-12-06
-6t2f,2020-01-29,2019-10-08
-5t20,2016-09-14,2016-08-22
-5t2o,2017-05-03,2016-08-23
-3t2e,2011-10-26,2011-07-22
-3t2k,2012-05-16,2011-07-22
-1t2w,2004-09-07,2004-04-23
-3t2b,2011-10-26,2011-07-22
-1t22,2005-09-06,2004-04-19
-6t2n,2020-07-08,2019-10-09
-6t29,2019-11-13,2019-10-08
-5t27,2017-04-19,2016-08-23
-3t2s,2012-01-25,2011-07-23
-3t2w,2012-04-11,2011-07-23
-8t2h,2024-05-15,2023-06-06
-7t2l,2023-06-14,2021-12-05
-5t2t,2017-09-13,2016-08-24
-6t2x,2020-08-19,2019-10-10
-5t2k,2017-01-18,2016-08-23
-5t2n,2017-05-03,2016-08-23
-8t26,2023-10-04,2023-06-05
-7t2g,2022-12-07,2021-12-04
-5t28,2017-04-12,2016-08-23
-5t2g,2017-04-19,2016-08-23
-5t2s,2016-10-12,2016-08-24
-7t2b,2022-12-28,2021-12-03
-6t2i,2020-08-19,2019-10-08
-8t2t,2023-11-22,2023-06-06
-3t2m,2011-10-05,2011-07-22
-6t2l,2020-10-14,2019-10-09
-1t21,2005-09-06,2004-04-19
-7t23,2023-01-18,2021-12-02
-3t28,2011-12-28,2011-07-22
-3t29,2011-12-28,2011-07-22
-5t2d,2017-04-19,2016-08-23
-3t2h,2011-12-28,2011-07-22
-1t2r,2004-06-01,2004-04-22
-5t2i,2017-04-19,2016-08-23
-5t2b,2017-04-19,2016-08-23
-3t2j,2011-12-28,2011-07-22
-7t2m,2023-06-14,2021-12-05
-6t2y,2020-11-18,2019-10-10
-6t2d,2020-01-29,2019-10-08
-6t23,2020-03-04,2019-10-07
-7t2d,2022-12-28,2021-12-03
-3t2o,2012-01-18,2011-07-22
-3t2c,2011-10-26,2011-07-22
-6t2c,2020-04-15,2019-10-08
-1t2c,2004-05-11,2004-04-21
-7t27,2022-04-20,2021-12-03
-5t2p,2017-02-22,2016-08-24
-8t23,2023-10-25,2023-06-05
-3t2p,2012-01-18,2011-07-22
-3t2v,2011-08-10,2011-07-23
-111m,1998-04-08,1997-12-24
-2xyf,2011-12-07,2010-11-17
-1xye,2004-11-30,2004-11-09
-1xy0,2004-12-07,2004-11-09
-2xyv,2011-10-26,2010-11-19
-7xy9,2023-06-07,2022-06-01
-5xyk,2018-07-11,2017-07-09
-7xy7,2023-05-03,2022-05-31
-6xys,2020-03-18,2020-01-31
-6xyu,2020-03-18,2020-01-31
-6xyc,2021-01-27,2020-01-30
-2xy9,2011-05-11,2010-11-16
-6xyy,2020-03-18,2020-01-31
-1xya,1994-05-31,1994-01-03
-6xyd,2020-06-10,2020-01-30
-5xy4,2018-07-18,2017-07-06
-4xyn,2015-05-13,2015-02-02
-2xyu,2011-11-30,2010-11-19
-6xyl,2021-02-10,2020-01-30
-4xyc,2015-03-25,2015-02-02
-7xy3,2023-09-13,2022-05-31
-4xy7,2015-09-23,2015-02-02
-1xyc,1994-05-31,1994-01-03
-1xy3,2005-03-22,2004-11-09
-4xy9,2015-03-11,2015-02-02
-4xye,2015-07-08,2015-02-02
-4xyf,2015-03-11,2015-02-02
-2xy4,2011-04-27,2010-11-15
-2xys,2011-03-23,2010-11-19
-5xya,2018-08-08,2017-07-06
-7xyj,2023-06-07,2022-06-01
-4xyd,2016-05-25,2015-02-02
-2xyn,2010-12-01,2010-11-18
-1xym,1994-05-31,1993-12-07
-7xyb,2022-07-20,2022-06-01
-5xyy,2018-01-17,2017-07-11
-4xyp,2015-06-24,2015-02-02
-2xyq,2011-10-19,2010-11-18
-7xye,2023-05-31,2022-06-01
-7xyo,2023-06-07,2022-06-02
-6xy7,2020-02-26,2020-01-29
-7xyy,2023-07-12,2022-06-02
-2xyt,2011-03-23,2010-11-19
-1xyd,2005-06-07,2004-11-09
-6xyt,2020-02-12,2020-01-31
-2xyl,1998-03-18,1997-11-20
-2xyo,2011-03-23,2010-11-18
-6xy5,2020-11-18,2020-01-29
-1xyv,2004-12-07,2004-11-11
-6xyf,2021-02-10,2020-01-30
-5xyr,2018-08-08,2017-07-10
-2xyk,2010-12-01,2010-11-18
-7xy6,2023-05-03,2022-05-31
-2xya,2011-04-27,2010-11-16
-4xyl,2016-01-27,2015-02-02
-1xyl,1994-05-31,1993-12-07
-6xya,2020-04-08,2020-01-30
-4xyj,2015-05-20,2015-02-02
-7xyq,2023-04-12,2022-06-02
-7xyd,2023-12-06,2022-06-01
-7xyl,2023-05-31,2022-06-01
-6xy2,2020-12-09,2020-01-29
-7xyk,2023-06-07,2022-06-01
-6xyb,2020-06-10,2020-01-30
-1xyi,2005-02-08,2004-11-10
-6xyx,2020-12-02,2020-01-31
-2xyh,2011-08-17,2010-11-17
-2xy7,2011-07-27,2010-11-15
-2xy3,2011-02-23,2010-11-12
-4xy8,2015-03-11,2015-02-02
-4xya,2015-03-11,2015-02-02
-2xy8,2011-06-29,2010-11-16
-4xyb,2015-07-08,2015-02-02
-2xyw,2011-02-23,2010-11-19
-6xyr,2020-12-09,2020-01-31
-6xyg,2021-02-10,2020-01-30
-5xyz,2018-05-23,2017-07-11
-5xyx,2018-01-17,2017-07-11
-8xyb,2024-04-03,2024-01-19
-4xy2,2015-06-17,2015-02-02
-2xyr,2011-10-26,2010-11-18
-4xyx,2016-02-10,2015-02-03
-6xy3,2021-02-10,2020-01-29
-7xyr,2023-07-05,2022-06-02
-5xym,2017-09-27,2017-07-09
-2xy5,2011-07-27,2010-11-15
-2xyg,2011-08-17,2010-11-17
-4xyk,2015-05-06,2015-02-02
-8xy7,2024-04-03,2024-01-19
-5xyn,2017-11-08,2017-07-09
-4xym,2016-01-27,2015-02-02
-2xyc,2011-02-23,2010-11-17
-1xyb,1994-05-31,1994-01-03
-1xyy,2004-12-07,2004-11-11
-6xyk,2021-01-27,2020-01-30
-8xy0,2024-05-22,2024-01-19
-6xym,2021-02-10,2020-01-30
-2xye,2011-12-07,2010-11-17
-1xyn,1995-08-08,1994-08-09
-5xyu,2017-09-27,2017-07-10
-7xyz,2023-07-12,2022-06-02
-7xy4,2023-09-13,2022-05-31
-2xy2,2011-02-23,2010-11-12
-2xy1,2011-02-23,2010-11-12
-2xyj,2011-02-23,2010-11-18
-2xyx,2011-02-23,2010-11-19
-8xya,2024-04-03,2024-01-19
-2xyb,2011-11-30,2010-11-17
-7xyh,2023-01-18,2022-06-01
-7xya,2022-07-20,2022-06-01
-2xyd,2011-05-11,2010-11-17
-2xyp,2011-08-17,2010-11-18
-5xy1,2017-08-02,2017-07-05
-3n7b,2010-11-24,2010-05-26
-5n7m,2017-05-24,2017-02-20
-4n7j,2013-12-18,2013-10-15
-1n7i,2003-12-23,2002-11-15
-3n7u,2010-06-09,2010-05-27
-1n7s,2002-12-27,2002-11-16
-1n73,2003-01-07,2002-11-12
-1n7r,2002-12-31,2002-11-16
-4n7u,2014-04-23,2013-10-16
-6n7h,2019-05-29,2018-11-27
-5n7u,2018-03-21,2017-02-21
-7n77,2021-11-10,2021-06-09
-3n7z,2010-06-16,2010-05-27
-1n7j,2003-12-23,2002-11-15
-3n7a,2011-05-11,2010-05-26
-3n7r,2010-09-15,2010-05-27
-4n76,2014-01-15,2013-10-15
-6n7y,2019-11-06,2018-11-28
-6n77,2019-04-24,2018-11-27
-5n77,2017-07-12,2017-02-20
-7n7n,2021-06-30,2021-06-10
-1n7v,2003-04-08,2002-11-18
-7n7k,2021-06-30,2021-06-10
-6n7n,2019-03-06,2018-11-27
-5n75,2017-07-19,2017-02-19
-5n7p,2018-03-14,2017-02-21
-1n7g,2003-01-07,2002-11-14
-5n7d,2017-11-08,2017-02-20
-3n7w,2011-12-14,2010-05-27
-6n78,2019-04-24,2018-11-27
-4n71,2013-11-27,2013-10-14
-4n79,2014-11-26,2013-10-15
-1n7x,2003-03-18,2002-11-18
-4n7p,2014-04-02,2013-10-16
-5n7f,2017-11-08,2017-02-20
-7n7h,2021-07-07,2021-06-10
-1n7t,2003-01-28,2002-11-16
-3n76,2011-05-11,2010-05-26
-5n7j,2017-06-28,2017-02-20
-7n72,2021-11-10,2021-06-09
-4n7l,2014-01-22,2013-10-15
-7n7l,2021-06-30,2021-06-10
-4n7s,2014-04-23,2013-10-16
-3n7y,2011-01-12,2010-05-27
-6n7f,2018-12-12,2018-11-27
-1n75,2003-02-25,2002-11-12
-4n7k,2014-02-05,2013-10-15
-6n7i,2019-03-06,2018-11-27
-3n79,2010-10-06,2010-05-26
-6n7d,2019-04-24,2018-11-27
-7n7o,2021-06-30,2021-06-10
-6n7w,2019-03-06,2018-11-28
-1n7u,2003-04-08,2002-11-18
-5n7v,2017-05-31,2017-02-21
-3n7h,2011-06-08,2010-05-27
-5n7q,2017-12-27,2017-02-21
-7n7m,2021-06-30,2021-06-10
-1n7h,2003-01-07,2002-11-14
-7n70,2021-11-10,2021-06-09
-3n7o,2010-07-21,2010-05-27
-5n78,2017-07-12,2017-02-20
-4n7t,2013-11-06,2013-10-16
-6n7z,2019-11-06,2018-11-28
-3n75,2011-02-16,2010-05-26
-6n7t,2019-03-06,2018-11-28
-4n73,2014-06-04,2013-10-14
-3n78,2010-11-24,2010-05-26
-6n7c,2019-04-24,2018-11-27
-5n7l,2018-03-14,2017-02-20
-7n7b,2021-06-23,2021-06-10
-7n7v,2022-07-06,2021-06-11
-1n7m,2003-02-04,2002-11-15
-4n7n,2014-04-02,2013-10-16
-7n7g,2022-07-27,2021-06-10
-7n7i,2021-06-30,2021-06-10
-7n7j,2021-06-30,2021-06-10
-2n7c,2016-10-12,2015-09-08
-2n79,2015-10-28,2015-09-06
-3n7x,2010-11-17,2010-05-27
-4n7m,2013-12-18,2013-10-15
-5n7t,2017-06-14,2017-02-21
-6n7v,2019-03-06,2018-11-28
-6n7k,2019-05-29,2018-11-27
-4n7o,2014-04-02,2013-10-16
-2n7b,2016-07-06,2015-09-07
-5n74,2017-06-14,2017-02-18
-1n70,2004-09-28,2002-11-12
-1n76,2003-02-18,2002-11-12
-4n7e,2014-01-22,2013-10-15
-7n7c,2021-06-23,2021-06-10
-5n7y,2018-02-28,2017-02-21
-7n74,2021-11-10,2021-06-09
-7n7r,2021-09-08,2021-06-11
-4n7q,2013-11-13,2013-10-16
-4n7b,2013-11-20,2013-10-15
-6n7q,2019-01-30,2018-11-28
-6n7g,2019-05-29,2018-11-27
-2n7l,2016-07-27,2015-09-14
-1n77,2003-02-25,2002-11-13
-5n7o,2017-04-26,2017-02-21
-7n7w,2021-09-08,2021-06-11
-6n7s,2019-03-06,2018-11-28
-7n73,2021-11-10,2021-06-09
-1n7f,2003-08-12,2002-11-14
-7n7x,2021-09-15,2021-06-11
-4n7h,2014-01-08,2013-10-15
-1n7q,2002-12-31,2002-11-16
-4n7i,2014-04-23,2013-10-15
-6n7e,2019-12-04,2018-11-27
-6n7b,2019-04-24,2018-11-27
-7n7y,2021-09-08,2021-06-11
-3n71,2010-10-13,2010-05-26
-3n7e,2011-06-01,2010-05-27
-6n7r,2019-09-18,2018-11-28
-5n7g,2017-11-08,2017-02-20
-1n7w,2003-03-18,2002-11-18
-7n7u,2021-09-08,2021-06-11
-5n7b,2018-06-27,2017-02-20
-4n78,2014-02-05,2013-10-15
-1n7d,2003-01-21,2002-11-13
-6n7p,2019-09-18,2018-11-27
-5n7x,2017-10-04,2017-02-21
-6n79,2019-04-24,2018-11-27
-6n7l,2018-12-12,2018-11-27
-5n7c,2018-03-14,2017-02-20
-4n7c,2014-05-21,2013-10-15
-1n71,2003-03-18,2002-11-12
-6n7a,2019-04-24,2018-11-27
-7n78,2021-11-10,2021-06-09
-3n7d,2011-06-01,2010-05-27
-1n78,2003-02-25,2002-11-13
-7n7p,2021-09-01,2021-06-10
-3n7s,2010-09-15,2010-05-27
-4n70,2013-11-06,2013-10-14
-4mw3,2013-11-27,2013-09-24
-1mwb,2002-12-04,2002-09-27
-1mw3,2002-12-18,2002-09-27
-4mwp,2014-04-02,2013-09-25
-3mwn,2010-06-30,2010-05-06
-7mww,2021-09-15,2021-05-17
-5mwu,2017-02-22,2017-01-20
-1mw2,2002-12-18,2002-09-27
-6mw5,2019-10-09,2018-10-29
-4mw7,2014-04-30,2013-09-24
-2mwx,2015-02-11,2014-12-02
-4mwj,2013-11-20,2013-09-25
-4mw0,2014-04-30,2013-09-24
-3mw1,2011-04-27,2010-05-05
-3mwt,2010-12-01,2010-05-06
-4mwc,2014-04-30,2013-09-24
-4mw4,2014-04-30,2013-09-24
-1mwe,1998-03-04,1997-08-27
-7mw8,2022-05-18,2021-05-15
-4mwu,2013-11-20,2013-09-25
-4mw5,2014-04-30,2013-09-24
-5mwe,2017-06-28,2017-01-18
-3mws,2011-03-23,2010-05-06
-3mwc,2010-05-19,2010-05-05
-4mw1,2014-04-30,2013-09-24
-4mws,2014-03-12,2013-09-25
-3mww,2010-10-27,2010-05-06
-6mwl,2019-04-03,2018-10-29
-3mw3,2010-07-28,2010-05-05
-5mwd,2017-10-04,2017-01-18
-7mw5,2022-03-16,2021-05-15
-5mwk,2017-03-22,2017-01-18
-7mwg,2021-09-29,2021-05-17
-1mw0,2002-12-18,2002-09-27
-5mw7,2017-06-14,2017-01-18
-7mwx,2021-09-15,2021-05-17
-5mw8,2017-05-10,2017-01-18
-7mwz,2021-07-21,2021-05-17
-4mw9,2014-04-30,2013-09-24
-3mwa,2011-04-06,2010-05-05
-5mwh,2018-02-14,2017-01-18
-1mwo,2003-06-10,2002-09-30
-1mwu,2002-11-06,2002-10-01
-5mw4,2017-03-22,2017-01-18
-3mw4,2010-07-28,2010-05-05
-1mwt,2002-11-06,2002-10-01
-5mwz,2018-02-14,2017-01-20
-7mwu,2022-01-19,2021-05-17
-5mwj,2017-04-05,2017-01-18
-5mwc,2018-02-14,2017-01-18
-5mwm,2017-05-10,2017-01-18
-4mwy,2013-11-20,2013-09-25
-6mww,2019-04-03,2018-10-30
-1mwh,2002-12-18,2002-09-29
-1mwc,1998-08-19,1998-08-12
-3mwk,2011-03-23,2010-05-06
-2mwk,2015-09-02,2014-11-12
-5mwa,2018-02-28,2017-01-18
-1mw1,2002-12-18,2002-09-27
-5mwf,2017-06-14,2017-01-18
-4mwf,2013-12-11,2013-09-24
-4mwd,2014-04-30,2013-09-24
-6mw7,2019-09-11,2018-10-29
-1mwd,1998-08-19,1998-08-11
-4mwq,2013-11-20,2013-09-25
-1mwr,2002-11-06,2002-10-01
-5mwg,2018-02-14,2017-01-18
-6mwk,2019-11-06,2018-10-29
-1mwz,2002-11-06,2002-10-01
-4mw8,2013-11-27,2013-09-24
-6mwz,2019-04-03,2018-10-30
-3mwe,2010-06-16,2010-05-05
-3mwy,2010-09-29,2010-05-06
-4mwx,2013-11-20,2013-09-25
-1mwn,2002-12-18,2002-09-30
-3mwp,2010-12-01,2010-05-06
-7mw7,2021-08-18,2021-05-15
-6mw8,2019-10-09,2018-10-29
-6mwr,2019-12-18,2018-10-30
-4mwv,2013-11-20,2013-09-25
-1mw8,2003-10-14,2002-09-27
-5mw6,2017-10-04,2017-01-18
-3mwi,2011-06-01,2010-05-06
-4mwi,2013-12-04,2013-09-25
-4mwe,2014-04-30,2013-09-24
-5mwx,2018-02-28,2017-01-20
-4mwh,2013-11-20,2013-09-24
-6mwf,2019-11-06,2018-10-29
-3mw7,2011-04-06,2010-05-05
-7mw1,2022-06-15,2021-05-15
-4mww,2013-11-20,2013-09-25
-7mwn,2022-06-01,2021-05-17
-4mw2,2014-04-30,2013-09-24
-3mw2,2010-07-28,2010-05-05
-1mwq,2003-11-25,2002-09-30
-7mw6,2022-03-16,2021-05-15
-4mwz,2014-10-01,2013-09-25
-5mwl,2017-05-10,2017-01-18
-5mwo,2017-05-31,2017-01-18
-5mw9,2017-06-28,2017-01-18
-3mwl,2011-03-23,2010-05-06
-6mwe,2018-11-21,2018-10-29
-3mwu,2010-07-21,2010-05-06
-7mwt,2022-01-19,2021-05-17
-1mws,2002-11-06,2002-10-01
-5mw3,2017-03-22,2017-01-18
-7mw2,2022-03-16,2021-05-15
-3mwb,2010-06-30,2010-05-05
-1mww,2003-11-18,2002-10-01
-6mwh,2019-04-03,2018-10-29
-4mwl,2013-11-20,2013-09-25
-2mwg,2016-05-25,2014-11-07
-5mwb,2017-06-14,2017-01-18
-4mwo,2014-09-10,2013-09-25
-5mw0,2017-06-28,2017-01-17
-7mw4,2022-03-16,2021-05-15
-6mwi,2019-11-06,2018-10-29
-4mw6,2014-04-30,2013-09-24
-1mwm,2003-01-28,2002-09-30
-4mwb,2014-04-30,2013-09-24
-3mwm,2011-03-16,2010-05-06
-2mwj,2015-09-02,2014-11-12
-5mw2,2017-10-04,2017-01-18
-5mwy,2018-03-07,2017-01-20
-4mwt,2014-03-12,2013-09-25
-3mwf,2010-09-01,2010-05-05
-5mw5,2017-06-14,2017-01-18
-7mwv,2022-01-19,2021-05-17
-7mw3,2022-03-16,2021-05-15
-5mwt,2018-02-14,2017-01-19
-3mw0,2011-02-09,2010-05-05
-5mw1,2017-02-08,2017-01-17
-3mwo,2010-06-09,2010-05-06
-4mwr,2013-11-20,2013-09-25
-6mw3,2019-06-19,2018-10-29
-6mwj,2019-11-06,2018-10-29
-5mwp,2018-03-07,2017-01-19
-1mwa,2002-11-27,2002-09-27
-7jpj,2021-06-16,2020-08-08
-6jpb,2019-06-12,2019-03-26
-1jp6,2002-01-16,2001-08-01
-5jpt,2017-02-22,2016-05-04
-8jp7,2024-04-17,2023-06-10
-4jp1,2014-04-02,2013-03-19
-4jpm,2013-12-04,2013-03-19
-4jpa,2014-03-05,2013-03-19
-7jpp,2020-09-09,2020-08-09
-1jp4,2001-08-08,2001-08-01
-8jp5,2024-04-17,2023-06-10
-4jpu,2013-07-31,2013-03-19
-8jpz,2023-12-20,2023-06-13
-4jpc,2013-04-10,2013-03-19
-8jpc,2023-08-09,2023-06-11
-4jpk,2013-04-10,2013-03-19
-6jpt,2019-05-29,2019-03-27
-3jpy,2009-12-08,2009-09-04
-8jpn,2024-05-22,2023-06-12
-7jpz,2020-12-23,2020-08-10
-3jpu,2009-10-13,2009-09-04
-6jp3,2020-01-29,2019-03-25
-1jpm,2001-12-21,2001-08-02
-6jp9,2020-04-22,2019-03-26
-7jpk,2020-11-18,2020-08-09
-1jpn,2002-02-02,2001-08-02
-5jpd,2016-05-11,2016-05-03
-5jpm,2016-08-10,2016-05-03
-1jpb,2002-01-16,2001-08-01
-1jpc,1997-01-27,1996-07-30
-6jpl,2019-10-02,2019-03-27
-4jpz,2014-04-16,2013-03-19
-6jpr,2019-06-26,2019-03-27
-2jpa,2007-10-30,2007-05-01
-3jpr,2010-06-02,2009-09-04
-5jpx,2017-08-09,2016-05-04
-6jp5,2019-06-12,2019-03-25
-1jpj,2002-02-02,2001-08-02
-3jpp,2010-06-02,2009-09-04
-3jps,2010-06-02,2009-09-04
-8jp2,2024-04-24,2023-06-10
-8jp4,2024-04-17,2023-06-10
-1jpf,2001-10-24,2001-08-02
-8jp1,2024-04-24,2023-06-10
-7jpl,2020-11-18,2020-08-09
-4jpe,2013-04-10,2013-03-19
-8jp9,2024-04-17,2023-06-10
-8jpq,2023-08-23,2023-06-12
-8jp8,2024-04-17,2023-06-10
-8jpb,2023-08-09,2023-06-11
-4jpf,2014-04-02,2013-03-19
-7jph,2021-04-07,2020-08-08
-5jp9,2017-03-15,2016-05-03
-7jpr,2020-09-09,2020-08-09
-4jpy,2013-08-07,2013-03-19
-8jpg,2024-04-17,2023-06-12
-6jpj,2019-05-15,2019-03-27
-4jpt,2013-07-31,2013-03-19
-1jpy,2001-09-28,2001-08-03
-3jpv,2009-10-27,2009-09-04
-7jpq,2020-09-02,2020-08-09
-7jps,2020-09-09,2020-08-09
-1jpr,2001-08-15,2001-08-03
-6jp4,2019-10-30,2019-03-25
-4jp8,2014-01-29,2013-03-19
-5jp7,2017-03-08,2016-05-03
-5jpu,2016-06-15,2016-05-04
-3jpo,2010-06-02,2009-09-04
-5jpr,2016-12-21,2016-05-04
-7jpe,2020-08-26,2020-08-07
-4jpx,2013-08-07,2013-03-19
-8jpd,2023-08-09,2023-06-11
-4jps,2014-04-02,2013-03-19
-8jp0,2024-01-03,2023-06-09
-1jpu,2001-10-03,2001-08-03
-6jpe,2020-05-06,2019-03-26
-7jp3,2021-10-27,2020-08-07
-5jpv,2017-06-14,2016-05-04
-7jpt,2020-12-09,2020-08-09
-2jp9,2007-10-30,2007-04-30
-3jpt,2010-06-02,2009-09-04
-4jpw,2013-04-17,2013-03-19
-3jpn,2010-06-02,2009-09-04
-4jpl,2013-07-31,2013-03-19
-8jpw,2023-08-09,2023-06-13
-4jph,2013-07-24,2013-03-19
-4jpg,2013-05-22,2013-03-19
-8jpf,2023-08-09,2023-06-11
-6jpa,2019-06-12,2019-03-26
-7jpv,2020-11-18,2020-08-10
-1jpg,2001-10-24,2001-08-02
-8jpx,2024-01-31,2023-06-13
-1jp5,2001-10-12,2001-08-01
-7jpn,2022-02-09,2020-08-09
-5jph,2016-06-29,2016-05-03
-8jpe,2023-08-09,2023-06-11
-1jpz,2001-11-09,2001-08-03
-6jpw,2019-06-26,2019-03-28
-6jph,2019-10-30,2019-03-27
-4jpd,2013-03-27,2013-03-19
-1jp3,2001-08-15,2001-07-31
-4jpj,2013-04-10,2013-03-19
-4jpv,2013-04-17,2013-03-19
-7jpw,2020-11-18,2020-08-10
-6jpn,2019-10-30,2019-03-27
-1jpa,2001-10-03,2001-08-01
-5jpi,2016-05-18,2016-05-03
-5jpn,2016-08-10,2016-05-03
-3jpx,2009-10-20,2009-09-04
-2jpr,2007-10-09,2007-05-22
-4jp9,2013-04-10,2013-03-19
-3jpw,2009-12-08,2009-09-04
-6jp7,2020-02-05,2019-03-26
-5jpc,2016-11-16,2016-05-03
-5jp2,2016-06-08,2016-05-03
-1jpl,2002-02-27,2001-08-02
-7jpx,2020-11-18,2020-08-10
-6jp8,2019-06-12,2019-03-26
-8jpr,2023-09-20,2023-06-12
-6jp1,2019-05-29,2019-03-25
-5jp6,2016-06-01,2016-05-03
-4jp4,2014-03-05,2013-03-19
-1jp9,2002-01-16,2001-08-01
-5jpf,2016-08-31,2016-05-03
-8jpo,2023-09-20,2023-06-12
-7jpo,2020-09-02,2020-08-09
-3jpq,2010-06-02,2009-09-04
-7jp0,2021-10-13,2020-08-07
-8jp6,2024-04-17,2023-06-10
-1jp8,2002-01-16,2001-08-01
-7jpi,2021-04-07,2020-08-08
-7jpd,2021-10-06,2020-08-07
-5jpg,2017-05-24,2016-05-03
-5jp0,2016-08-10,2016-05-03
-2r8y,2008-09-23,2007-09-11
-2r84,2007-12-04,2007-09-10
-2r8k,2007-12-11,2007-09-11
-5r87,2020-04-22,2020-03-03
-2r85,2007-12-04,2007-09-10
-6r8g,2020-04-15,2019-04-01
-6r87,2019-06-26,2019-03-31
-8r8a,2023-12-27,2023-11-28
-8r8d,2023-12-13,2023-11-29
-6r8c,2020-05-06,2019-04-01
-5r8d,2020-04-22,2020-03-03
-1r8a,2003-12-16,2003-10-23
-4r8p,2014-11-05,2014-09-02
-4r8c,2015-07-01,2014-09-01
-5r85,2020-04-22,2020-03-03
-7r8o,2021-08-04,2021-06-26
-3r8z,2012-10-31,2011-03-24
-2r8h,2008-07-22,2007-09-10
-5r8i,2020-04-22,2020-03-03
-4r8d,2015-09-02,2014-09-01
-8r8g,2024-01-31,2023-11-29
-5r8c,2020-04-22,2020-03-03
-4r88,2014-09-17,2014-08-29
-7r8n,2021-08-04,2021-06-26
-6r8r,2019-05-08,2019-04-02
-2r8z,2008-09-23,2007-09-11
-5r89,2020-04-22,2020-03-03
-4r8n,2014-09-17,2014-09-02
-3r88,2012-09-26,2011-03-23
-5r80,2020-03-11,2020-03-03
-6r8n,2019-08-14,2019-04-02
-1r8m,2004-01-20,2003-10-27
-5r8p,2020-04-22,2020-03-03
-7r8w,2021-10-06,2021-06-27
-1r8s,2004-01-20,2003-10-28
-2r8p,2007-12-11,2007-09-11
-1r87,2004-07-20,2003-10-23
-5r8v,2020-07-22,2020-03-04
-5r81,2020-03-11,2020-03-03
-6r84,2019-06-26,2019-03-31
-6r8o,2019-11-27,2019-04-02
-5r82,2020-03-11,2020-03-03
-8r8h,2024-01-31,2023-11-29
-5r88,2020-04-22,2020-03-03
-5r8o,2020-04-22,2020-03-03
-1r8b,2003-12-16,2003-10-23
-6r8j,2020-05-13,2019-04-02
-8r8w,2024-01-31,2023-11-30
-3r8d,2011-08-17,2011-03-23
-1r8e,2004-08-17,2003-10-23
-7r8p,2022-09-14,2021-06-27
-5r8u,2020-07-22,2020-03-04
-2r8o,2007-12-11,2007-09-11
-5r8n,2020-04-22,2020-03-03
-4r87,2015-03-25,2014-08-29
-1r86,2005-07-19,2003-10-23
-7r8v,2021-07-28,2021-06-27
-2r8v,2008-01-15,2007-09-11
-2r8f,2007-10-23,2007-09-10
-7r8q,2022-09-14,2021-06-27
-6r8q,2019-05-08,2019-04-02
-7r8r,2022-09-21,2021-06-27
-5r8z,2020-07-22,2020-03-04
-7r81,2021-12-01,2021-06-25
-7r8a,2021-09-08,2021-06-26
-7r8s,2022-06-29,2021-06-27
-6r8a,2020-01-01,2019-04-01
-1r82,2004-02-10,2003-10-22
-2r8q,2007-12-18,2007-09-11
-5r8m,2020-04-22,2020-03-03
-7r8e,2021-09-08,2021-06-26
-4r82,2014-10-01,2014-08-29
-5r8h,2020-04-22,2020-03-03
-8r8r,2024-04-10,2023-11-29
-4r83,2014-12-03,2014-08-29
-1r81,2004-02-10,2003-10-22
-5r8x,2020-07-22,2020-03-04
-7r80,2022-06-29,2021-06-25
-3r8f,2011-09-28,2011-03-23
-5r8e,2020-04-22,2020-03-03
-7r8l,2021-08-04,2021-06-26
-1r8l,2004-11-02,2003-10-27
-3r8l,2012-08-08,2011-03-24
-1r85,2004-07-20,2003-10-23
-5r8g,2020-04-22,2020-03-03
-3r8u,2012-10-31,2011-03-24
-1r80,2004-02-10,2003-10-22
-2r8e,2008-09-23,2007-09-10
-3r8b,2011-04-06,2011-03-23
-7r8m,2021-08-04,2021-06-26
-7r8d,2021-09-08,2021-06-26
-2r8i,2008-07-22,2007-09-10
-5r8y,2020-07-22,2020-03-04
-6r8p,2019-05-08,2019-04-02
-3r8i,2012-01-11,2011-03-24
-6r85,2020-01-01,2019-03-31
-3r8m,2012-08-08,2011-03-24
-6r8l,2019-11-27,2019-04-02
-3r8x,2011-04-13,2011-03-24
-5r8l,2020-04-22,2020-03-03
-7r8x,2021-10-06,2021-06-27
-6r8w,2019-11-27,2019-04-02
-2r8d,2007-11-13,2007-09-10
-4r8m,2015-03-11,2014-09-02
-4r85,2014-09-17,2014-08-29
-5r83,2020-03-11,2020-03-03
-4r84,2014-12-03,2014-08-29
-4r8u,2015-01-14,2014-09-03
-5r84,2020-03-11,2020-03-03
-2r8t,2008-08-19,2007-09-11
-4r8l,2014-10-22,2014-09-02
-8r8i,2024-01-31,2023-11-29
-4r8s,2014-10-15,2014-09-02
-5r8f,2020-04-22,2020-03-03
-6r86,2019-07-31,2019-03-31
-8r8z,2024-01-31,2023-11-30
-2r8g,2008-07-22,2007-09-10
-5r8b,2020-04-22,2020-03-03
-8r8f,2024-01-31,2023-11-29
-3r8p,2012-08-08,2011-03-24
-5r8a,2020-04-22,2020-03-03
-7r8y,2022-06-29,2021-06-27
-3r8y,2011-04-20,2011-03-24
-6r88,2020-01-01,2019-04-01
-2r8j,2007-12-11,2007-09-11
-5r8j,2020-04-22,2020-03-03
-8r8x,2024-03-06,2023-11-30
-8r8y,2024-01-31,2023-11-30
-6r8u,2020-02-05,2019-04-02
-5r8w,2020-07-22,2020-03-04
-4r8q,2014-11-12,2014-09-02
-5r86,2020-04-22,2020-03-03
-4r89,2014-10-29,2014-08-30
-2r86,2007-12-04,2007-09-10
-5r8q,2020-04-22,2020-03-03
-4r8h,2015-07-22,2014-09-02
-7r89,2021-09-08,2021-06-26
-7r86,2021-11-10,2021-06-26
-4r8i,2015-04-29,2014-09-02
-7r8t,2022-06-29,2021-06-27
-3r83,2012-08-08,2011-03-23
-6r8t,2020-05-06,2019-04-02
-8r8q,2024-05-01,2023-11-29
-6r81,2020-05-06,2019-03-30
-6r8b,2020-02-05,2019-04-01
-1r89,2003-12-16,2003-10-23
-2r87,2007-12-04,2007-09-10
-8r8l,2024-05-22,2023-11-29
-7r8i,2022-11-09,2021-06-26
-3r8v,2012-10-31,2011-03-24
-1r8u,2004-03-23,2003-10-28
-4r8z,2015-03-04,2014-09-03
-2r80,2008-09-30,2007-09-10
-4r8w,2015-08-26,2014-09-03
-5r8k,2020-04-22,2020-03-03
-4r81,2014-11-19,2014-08-29
-7r84,2021-11-10,2021-06-26
-3r8a,2012-03-14,2011-03-23
-6r8s,2020-05-06,2019-04-02
-1r84,2003-11-11,2003-10-23
-8r8j,2024-01-31,2023-11-29
-6r8i,2019-10-16,2019-04-02
-1r8k,2003-11-11,2003-10-27
-1r8q,2004-01-20,2003-10-28
-7r8b,2021-09-08,2021-06-26
-4r8y,2014-11-05,2014-09-03
-1r8c,2003-12-16,2003-10-23
-6r89,2020-01-01,2019-04-01
-7r85,2021-11-10,2021-06-26
-3r8h,2012-05-02,2011-03-24
-3r8g,2012-05-02,2011-03-24
-8r8c,2023-12-27,2023-11-28
-6r8f,2019-06-05,2019-04-01
-1sfo,2004-03-02,2004-02-20
-6sff,2020-08-26,2019-08-01
-6sfb,2019-09-25,2019-08-01
-6sfo,2019-09-11,2019-08-01
-3sf0,2011-09-28,2011-06-12
-5sff,2022-10-12,2022-01-21
-3sff,2011-07-20,2011-06-13
-6sf8,2020-08-26,2019-08-01
-1sfc,1998-10-28,1998-08-24
-5sfo,2022-10-12,2022-01-21
-8sf8,2024-02-21,2023-04-10
-1sfq,2004-06-08,2004-02-20
-8sfz,2024-05-22,2023-04-11
-5sfx,2022-10-12,2022-01-21
-1sfy,2004-08-10,2004-02-21
-6sfi,2019-09-11,2019-08-01
-5sfa,2022-10-12,2022-01-21
-3sfc,2011-08-31,2011-06-13
-7sf5,2021-12-01,2021-10-03
-5sfc,2022-10-12,2022-01-21
-1sfk,2004-08-09,2004-02-19
-1sfv,1996-07-11,1996-02-20
-5sf0,2022-10-12,2022-01-21
-3sfg,2012-05-09,2011-06-13
-3sfz,2011-08-24,2011-06-14
-3sfi,2011-12-07,2011-06-13
-8sf0,2023-05-24,2023-04-10
-6sfk,2019-09-11,2019-08-01
-1sff,2004-09-14,2004-02-19
-1sf4,2004-03-02,2004-02-19
-3sfh,2011-07-20,2011-06-13
-6sfr,2020-08-26,2019-08-02
-5sf5,2022-10-12,2022-01-21
-8sf7,2024-05-22,2023-04-10
-5sfy,2022-10-12,2022-01-21
-5sfe,2022-10-19,2022-01-21
-8sfk,2024-04-17,2023-04-11
-7sfb,2022-10-05,2021-10-03
-1sfu,2004-08-17,2004-02-20
-7sf1,2022-10-05,2021-10-02
-3sf6,2011-06-29,2011-06-12
-7sfl,2022-09-28,2021-10-04
-1sfi,1999-07-09,1998-12-16
-5sfr,2022-10-12,2022-01-21
-6sfa,2020-08-26,2019-08-01
-5sfn,2022-10-12,2022-01-21
-7sf3,2022-10-05,2021-10-02
-8sf1,2024-03-13,2023-04-10
-6sfg,2020-04-15,2019-08-01
-5sf4,2022-10-12,2022-01-21
-7sfe,2022-03-30,2021-10-03
-1sf3,2004-07-27,2004-02-19
-5sfw,2022-10-12,2022-01-21
-8sf3,2023-04-19,2023-04-10
-5sfh,2022-10-12,2022-01-21
-8sfy,2023-09-13,2023-04-11
-5sfd,2022-10-12,2022-01-21
-1sfd,2004-07-27,2004-02-19
-7sf6,2021-12-15,2021-10-03
-1sfh,2004-07-27,2004-02-19
-3sfe,2011-09-07,2011-06-13
-7sfv,2022-03-16,2021-10-04
-8sfm,2024-04-17,2023-04-11
-5sf2,2022-10-12,2022-01-21
-7sfz,2022-10-26,2021-10-04
-7sf4,2021-12-01,2021-10-03
-7sfi,2022-10-05,2021-10-03
-5sfz,2022-10-12,2022-02-01
-6sf2,2020-04-08,2019-07-31
-5sfv,2022-10-12,2022-01-21
-5sfj,2022-10-12,2022-01-21
-5sfs,2022-10-12,2022-01-21
-3sfx,2011-08-03,2011-06-14
-8sff,2023-10-25,2023-04-11
-3sfk,2011-07-06,2011-06-13
-5sfp,2022-10-12,2022-01-21
-6sfu,2020-08-26,2019-08-02
-7sfk,2021-12-01,2021-10-04
-8sfv,2024-05-22,2023-04-11
-7sfw,2022-03-16,2021-10-04
-8sfb,2024-04-17,2023-04-10
-6sf0,2019-12-25,2019-07-30
-6sfj,2019-09-11,2019-08-01
-7sfo,2022-10-12,2021-10-04
-6sfe,2020-04-15,2019-08-01
-1sfb,2004-03-02,2004-02-19
-3sfv,2012-04-18,2011-06-14
-5sft,2022-10-12,2022-01-21
-1sf7,2004-03-02,2004-02-19
-8sfx,2024-05-22,2023-04-11
-8sfc,2024-04-17,2023-04-10
-8sfe,2023-10-25,2023-04-10
-5sfb,2022-10-12,2022-01-21
-1sf9,2004-02-24,2004-02-19
-3sfy,2011-08-03,2011-06-14
-1sft,1997-02-12,1996-09-20
-5sf6,2022-10-12,2022-01-21
-5sf1,2022-10-12,2022-01-21
-6sf5,2019-08-28,2019-08-01
-7sff,2022-03-30,2021-10-03
-7sfq,2022-03-02,2021-10-04
-3sfd,2011-09-07,2011-06-13
-5sfm,2022-10-12,2022-01-21
-5sf8,2022-10-12,2022-01-21
-5sfk,2022-10-12,2022-01-21
-1sf5,2004-07-27,2004-02-19
-1sfw,1996-07-11,1996-02-23
-8sfu,2023-09-13,2023-04-11
-6sfh,2020-04-15,2019-08-01
-7sfg,2022-03-30,2021-10-03
-2sfp,1999-02-24,1999-02-16
-5sfu,2022-10-12,2022-01-21
-8sfs,2024-05-22,2023-04-11
-8sfd,2024-04-17,2023-04-10
-3sfu,2012-05-09,2011-06-14
-7sfc,2022-03-30,2021-10-03
-1sfj,2004-10-12,2004-02-19
-8sft,2024-04-17,2023-04-11
-8sf9,2024-04-17,2023-04-10
-1sf6,2004-03-02,2004-02-19
-5sfl,2022-10-12,2022-01-21
-6sf9,2020-08-26,2019-08-01
-1sf2,2004-09-14,2004-02-19
-8sf6,2023-12-27,2023-04-10
-8sf2,2024-04-17,2023-04-10
-7sfj,2021-12-01,2021-10-04
-6sfq,2020-08-26,2019-08-02
-5sf7,2022-10-12,2022-01-21
-6sf1,2020-04-08,2019-07-30
-7sf2,2021-11-03,2021-10-02
-7sfu,2022-03-16,2021-10-04
-1sf8,2004-06-15,2004-02-19
-5sf9,2022-10-12,2022-01-21
-5sf3,2022-10-12,2022-01-21
-3sfp,2011-06-29,2011-06-13
-5sfq,2022-10-12,2022-01-21
-8sfw,2024-04-17,2023-04-11
-6sfc,2019-09-25,2019-08-01
-5sfg,2022-10-12,2022-01-21
-3sfw,2012-06-20,2011-06-14
-7sfh,2022-10-05,2021-10-03
-5sfi,2022-10-12,2022-01-21
-8sfa,2024-04-17,2023-04-10
-7sfr,2022-10-12,2021-10-04
-6sft,2020-06-10,2019-08-02
-1sfg,2004-03-02,2004-02-19
-7sfx,2021-12-29,2021-10-04
-7sf0,2022-03-30,2021-10-02
-7sfd,2022-03-30,2021-10-03
-3sfj,2012-12-12,2011-06-13
-5di9,2015-09-16,2015-08-31
-5din,2015-10-14,2015-09-01
-3di3,2009-01-27,2008-06-19
-4di2,2012-10-10,2012-01-30
-6diy,2018-10-31,2018-05-24
-1di9,2000-11-29,1999-11-29
-8dih,2023-06-28,2022-06-29
-2di4,2006-06-27,2006-03-28
-8di4,2023-02-08,2022-06-28
-1dib,2000-07-05,1999-11-29
-7dim,2021-11-24,2020-11-19
-7diw,2021-11-24,2020-11-19
-6did,2018-09-05,2018-05-23
-5dit,2015-10-14,2015-09-01
-7dil,2021-11-24,2020-11-19
-6dix,2018-10-31,2018-05-23
-4di9,2012-10-03,2012-01-11
-3div,2009-06-23,2008-06-21
-6di1,2018-10-17,2018-05-22
-1did,1993-07-15,1992-06-04
-8dic,2023-06-28,2022-06-29
-2dio,2006-11-21,2006-03-30
-6dir,2019-07-31,2018-05-23
-3die,2009-03-24,2008-06-20
-7dih,2021-01-20,2020-11-19
-5div,2016-03-23,2015-09-01
-4dip,2012-02-22,2012-01-31
-5di8,2016-03-30,2015-08-31
-2dif,2006-09-29,2006-03-29
-4dir,2013-02-13,2012-01-31
-7diq,2021-11-24,2020-11-19
-3din,2008-10-07,2008-06-20
-6div,2019-07-31,2018-05-23
-8dip,2023-03-29,2022-06-29
-5dis,2015-11-04,2015-09-01
-7dir,2021-11-24,2020-11-19
-5dif,2015-09-16,2015-08-31
-6di7,2018-08-22,2018-05-22
-5dir,2016-03-02,2015-09-01
-2did,2006-09-29,2006-03-29
-3diw,2008-10-21,2008-06-21
-6dic,2019-01-30,2018-05-23
-5di3,2015-11-18,2015-08-31
-1dii,1999-12-08,1999-11-29
-7die,2021-05-26,2020-11-19
-8di5,2022-08-24,2022-06-28
-5di7,2016-05-04,2015-08-31
-8dik,2022-11-09,2022-06-29
-3di4,2008-07-01,2008-06-19
-7diy,2021-05-19,2020-11-19
-1die,1993-07-15,1992-06-04
-4di8,2012-10-03,2012-01-11
-1di8,2000-11-29,1999-11-29
-4dih,2012-07-18,2012-01-31
-1diu,1995-11-14,1995-08-01
-8dif,2023-06-28,2022-06-29
-8dil,2022-07-13,2022-06-29
-1dih,1995-09-15,1994-09-14
-1di5,1999-12-08,1999-11-29
-1dic,1999-07-22,1998-07-08
-1diw,2000-03-24,1999-11-30
-4die,2012-02-08,2012-01-30
-1dit,1996-06-10,1995-07-20
-1di3,1999-12-08,1999-11-28
-6dim,2019-05-29,2018-05-23
-6dio,2018-09-26,2018-05-23
-4di0,2012-02-08,2012-01-30
-8dig,2023-06-28,2022-06-29
-6di4,2018-09-05,2018-05-22
-6diq,2019-07-31,2018-05-23
-5diz,2015-12-30,2015-09-01
-7dii,2021-04-07,2020-11-19
-4dij,2012-05-02,2012-01-31
-4diq,2012-03-07,2012-01-31
-5diy,2015-10-28,2015-09-01
-6di0,2018-10-17,2018-05-22
-8dii,2023-06-28,2022-06-29
-7din,2021-11-24,2020-11-19
-5die,2016-05-04,2015-08-31
-7di7,2021-12-01,2020-11-18
-7dij,2021-12-01,2020-11-19
-3di1,2008-08-12,2008-06-19
-5dip,2015-10-14,2015-09-01
-8dis,2023-06-07,2022-06-29
-5diu,2016-03-23,2015-09-01
-6diw,2019-07-31,2018-05-23
-4dig,2012-02-15,2012-01-31
-7dix,2021-04-07,2020-11-19
-6diu,2019-07-31,2018-05-23
-8div,2023-10-25,2022-06-29
-5dig,2016-05-04,2015-09-01
-7div,2021-11-24,2020-11-19
-3did,2008-07-22,2008-06-20
-8did,2023-07-05,2022-06-29
-7dis,2021-11-24,2020-11-19
-1di4,1999-12-08,1999-11-29
-8diq,2023-01-18,2022-06-29
-7dif,2021-01-27,2020-11-19
-6die,2019-05-29,2018-05-23
-6dis,2019-07-31,2018-05-23
-6di3,2018-09-05,2018-05-22
-2dip,2006-09-30,2006-03-30
-4dit,2012-02-15,2012-01-31
-1dig,2000-07-05,1999-11-29
-1dif,1996-03-08,1995-10-09
-6dig,2019-05-08,2018-05-23
-8dim,2022-11-16,2022-06-29
-1diq,1999-12-08,1999-11-29
-2die,2007-02-13,2006-03-29
-7dic,2021-03-17,2020-11-18
-1dil,1996-12-07,1996-04-23
-6di9,2018-09-05,2018-05-23
-6dit,2019-07-31,2018-05-23
-5diq,2015-09-30,2015-09-01
-7dip,2021-11-24,2020-11-19
-1dia,2000-07-05,1999-11-29
-1dio,2000-01-30,1999-01-27
-1dim,1996-12-07,1996-04-23
-7di8,2020-12-09,2020-11-18
-1diy,2000-09-22,1999-11-30
-7di3,2021-07-14,2020-11-18
-4dii,2012-07-18,2012-01-31
-2di3,2007-03-28,2006-03-28
-7diu,2021-11-24,2020-11-19
-1diz,2000-03-20,1999-11-30
-7did,2021-03-17,2020-11-18
-7dio,2021-11-24,2020-11-19
-5did,2016-05-04,2015-08-31
-6dil,2018-10-17,2018-05-23
-4din,2012-07-04,2012-01-31
-6di5,2018-09-05,2018-05-22
-4di5,2012-02-29,2012-01-30
-8diu,2022-12-14,2022-06-29
-2di2,2007-03-13,2006-03-27
-5dib,2015-10-14,2015-08-31
-7dit,2021-11-24,2020-11-19
-8die,2023-06-28,2022-06-29
-5dia,2015-10-28,2015-08-31
-2dij,1998-12-09,1998-05-27
-1dis,1995-11-14,1995-08-01
-1dir,1994-07-31,1994-04-18
-4dif,2013-02-13,2012-01-30
-8din,2023-05-10,2022-06-29
-6dik,2018-10-03,2018-05-23
-6dia,2019-01-30,2018-05-23
-4did,2012-02-29,2012-01-30
-8dio,2024-01-17,2022-06-29
-7dia,2021-12-01,2020-11-18
-8dir,2023-05-10,2022-06-29
-8dib,2023-06-28,2022-06-29
-6dih,2019-05-29,2018-05-23
-3di6,2008-08-19,2008-06-19
-3di5,2008-08-19,2008-06-19
-7dik,2021-11-24,2020-11-19
-5di1,2016-01-13,2015-08-31
-6dif,2018-10-17,2018-05-23
-3phe,2010-11-17,2010-11-03
-6ph4,2020-12-30,2019-06-25
-7phi,2022-03-02,2021-08-17
-4phg,2014-05-28,2014-05-06
-3pht,2011-11-23,2010-11-04
-8ph4,2024-01-31,2023-06-18
-3ph5,2011-09-21,2010-11-03
-6ph2,2020-12-30,2019-06-25
-6phz,2019-09-18,2019-06-25
-2phf,2007-07-10,2007-04-11
-6phw,2019-10-02,2019-06-25
-3ph7,2010-11-17,2010-11-03
-2pht,2007-07-10,2007-04-12
-7phz,2022-09-07,2021-08-19
-3phz,2011-07-06,2010-11-04
-6phx,2019-10-02,2019-06-25
-3phx,2011-02-02,2010-11-04
-8phf,2024-01-24,2023-06-19
-5phw,2017-03-15,2017-02-07
-8pha,2024-03-27,2023-06-19
-5phc,2017-03-15,2017-02-07
-3phd,2011-02-23,2010-11-03
-5phz,2017-03-15,2017-02-07
-1phn,1997-09-17,1995-06-21
-5phs,2017-03-15,2017-02-07
-5pht,2017-03-15,2017-02-07
-5ph4,2017-03-15,2017-02-07
-6ph7,2020-07-01,2019-06-25
-7phr,2022-08-31,2021-08-18
-3pha,2010-11-24,2010-11-03
-5ph9,2017-03-15,2017-02-07
-3ph4,2011-04-13,2010-11-03
-1phm,1998-11-11,1997-10-10
-5phu,2017-03-15,2017-02-07
-8phd,2023-08-16,2023-06-19
-3phc,2011-11-09,2010-11-03
-2phb,2008-03-25,2007-04-10
-8ph7,2023-09-13,2023-06-19
-5phf,2017-03-15,2017-02-07
-2phk,1999-01-13,1998-06-18
-4ph4,2014-10-29,2014-05-04
-7phl,2022-03-02,2021-08-17
-1php,1994-06-22,1994-04-12
-5ph5,2017-03-15,2017-02-07
-1phc,1993-10-31,1992-07-27
-1phe,1993-10-31,1992-07-27
-3phi,2011-11-09,2010-11-04
-6phr,2019-09-18,2019-06-25
-2ph9,2007-07-03,2007-04-10
-1phq,2004-07-13,2003-05-29
-4phz,2014-06-25,2014-05-07
-1phh,1988-04-16,1987-11-04
-2ph5,2007-05-15,2007-04-10
-7phw,2022-02-09,2021-08-18
-8ph5,2023-09-13,2023-06-19
-2phr,2007-07-10,2007-04-12
-2phw,2007-07-10,2007-04-12
-1ph2,2003-06-17,2003-05-29
-4phe,2015-05-06,2014-05-06
-5phy,2017-03-15,2017-02-07
-4phk,2014-08-13,2014-05-06
-7ph0,2022-05-11,2021-08-16
-4phs,2014-08-06,2014-05-06
-2ph6,2007-06-05,2007-04-10
-7phe,2022-09-07,2021-08-17
-8phv,2023-08-16,2023-06-20
-3ph6,2011-09-21,2010-11-03
-4phf,2014-05-28,2014-05-06
-7ph4,2022-08-24,2021-08-16
-2pho,2007-05-08,2007-04-11
-5phg,2017-03-15,2017-02-07
-4phd,2014-09-24,2014-05-06
-4phm,2014-08-13,2014-05-06
-3ph3,2011-06-22,2010-11-03
-8phj,2023-12-13,2023-06-20
-1phd,1993-10-31,1992-07-27
-6ph5,2019-12-11,2019-06-25
-7phk,2022-03-02,2021-08-17
-3phm,1999-09-29,1999-05-25
-6pht,2019-09-18,2019-06-25
-3phy,1998-05-27,1998-02-06
-5pho,2017-03-15,2017-02-07
-5ph0,2017-03-15,2017-02-07
-5ph3,2017-03-15,2017-02-07
-4ph9,2014-11-26,2014-05-05
-8phl,2024-03-06,2023-06-20
-5ph6,2017-03-15,2017-02-07
-2phu,2007-07-10,2007-04-12
-5phm,2017-03-15,2017-02-07
-1phb,1993-10-31,1992-07-27
-2phl,1994-09-30,1994-07-07
-6ph9,2020-02-12,2019-06-25
-4phi,2015-01-14,2014-05-06
-4pha,2014-09-24,2014-05-05
-4phw,2014-08-06,2014-05-07
-2phy,1995-10-15,1995-04-12
-7ph1,2022-03-30,2021-08-16
-4phn,2014-08-13,2014-05-06
-7phx,2021-10-06,2021-08-18
-5ph2,2017-03-15,2017-02-07
-7phn,2022-09-07,2021-08-17
-5php,2017-03-15,2017-02-07
-1phg,1993-10-31,1992-07-27
-8phk,2024-04-24,2023-06-20
-3phh,2011-11-09,2010-11-04
-5phx,2017-03-15,2017-02-07
-8ph8,2023-09-13,2023-06-19
-4phv,1993-10-31,1991-10-04
-7phd,2022-09-07,2021-08-17
-2phm,1999-04-30,1998-11-11
-5ph8,2017-03-15,2017-02-07
-5phe,2017-03-15,2017-02-07
-3pho,2011-05-18,2010-11-04
-6ph3,2020-12-30,2019-06-25
-4phb,2014-08-27,2014-05-06
-4phr,2014-08-06,2014-05-06
-7phj,2022-09-07,2021-08-17
-4phh,2014-05-28,2014-05-06
-7pho,2023-03-01,2021-08-17
-8phw,2023-09-27,2023-06-20
-5phr,2017-03-15,2017-02-07
-5phb,2017-03-15,2017-02-07
-2phn,2007-05-15,2007-04-11
-6ph6,2019-12-11,2019-06-25
-6phn,2020-07-01,2019-06-25
-1phf,1993-10-31,1992-07-27
-5ph1,2017-03-15,2017-02-07
-7phf,2022-09-07,2021-08-17
-2phx,2007-07-10,2007-04-12
-4pht,2014-11-26,2014-05-06
-8ph6,2023-09-13,2023-06-19
-6phy,2019-10-02,2019-06-25
-7phh,2022-03-02,2021-08-17
-5phn,2017-03-15,2017-02-07
-5phd,2017-03-15,2017-02-07
-3ph2,2011-02-09,2010-11-03
-4ph5,2015-05-06,2014-05-04
-5phv,2017-03-15,2017-02-07
-4phu,2014-07-16,2014-05-07
-4phl,2015-05-20,2014-05-06
-8phi,2024-02-21,2023-06-19
-5pha,2017-03-15,2017-02-07
-7ph2,2022-08-24,2021-08-16
-6phv,2019-10-02,2019-06-25
-1ph0,2003-07-29,2003-05-29
-1pha,1993-10-31,1992-07-27
-3phj,2011-11-09,2010-11-04
-3phb,2011-11-09,2010-11-03
-7ph7,2022-08-24,2021-08-16
-2ph8,2008-04-22,2007-04-10
-5phk,2017-03-15,2017-02-07
-5phq,2017-03-15,2017-02-07
-2phd,2008-04-22,2007-04-11
-8ph9,2024-04-24,2023-06-19
-5ph7,2017-03-15,2017-02-07
-5phh,2017-03-15,2017-02-07
-7phb,2022-05-25,2021-08-16
-2phi,1993-07-15,1993-04-08
-4php,2015-05-06,2014-05-06
-5phl,2017-03-15,2017-02-07
-4phc,2014-08-27,2014-05-06
-2pha,2007-05-08,2007-04-10
-5phj,2017-03-15,2017-02-07
-4phj,2014-08-13,2014-05-06
-1phk,1996-08-17,1996-03-15
-1phz,1999-04-30,1998-11-11
-2phh,1990-10-15,1989-06-19
-2ph1,2007-04-24,2007-04-10
-5phi,2017-03-15,2017-02-07
-7ph3,2022-08-24,2021-08-16
-5xsv,2018-05-02,2017-06-15
-4xsz,2015-07-22,2015-01-22
-1xsn,2005-01-18,2004-10-19
-6xsi,2020-08-19,2020-07-15
-6xs3,2020-10-14,2020-07-14
-2xsj,2011-08-24,2010-09-29
-7xsq,2022-11-09,2022-05-15
-4xsg,2015-06-24,2015-01-22
-6xsf,2020-08-19,2020-07-15
-6xsc,2020-08-19,2020-07-15
-6xsz,2021-02-03,2020-07-16
-6xsk,2021-07-21,2020-07-15
-1xs1,2004-12-21,2004-10-18
-7xsu,2023-11-29,2022-05-15
-5xsb,2018-04-25,2017-06-13
-4xsv,2016-03-16,2015-01-22
-6xsn,2021-07-21,2020-07-15
-7xse,2022-09-07,2022-05-13
-5xsx,2018-05-02,2017-06-15
-1xs5,2004-11-23,2004-10-18
-2xs2,2011-10-05,2010-09-24
-4xs3,2016-07-27,2015-01-21
-6xsp,2021-08-11,2020-07-15
-6xsw,2021-07-21,2020-07-16
-6xsv,2020-10-14,2020-07-16
-4xsm,2016-01-27,2015-01-22
-2xs7,2011-10-05,2010-09-24
-6xs7,2021-07-14,2020-07-15
-6xsa,2021-07-14,2020-07-15
-4xsp,2016-01-13,2015-01-22
-5xsp,2018-01-31,2017-06-15
-5xst,2018-04-25,2017-06-15
-4xsc,2015-12-16,2015-01-22
-2xsn,2010-11-17,2010-10-29
-6xsj,2020-10-14,2020-07-15
-2xsx,2010-11-10,2010-09-30
-6xse,2020-08-19,2020-07-15
-6xs8,2021-07-14,2020-07-15
-5xsy,2017-08-09,2017-06-15
-6xsr,2020-12-30,2020-07-16
-7xs6,2023-05-17,2022-05-12
-5xs8,2018-01-17,2017-06-12
-1xse,2004-11-16,2004-10-19
-2xs3,2010-11-03,2010-09-24
-1xsk,2004-11-10,2004-10-19
-7xs3,2023-05-17,2022-05-12
-2xsp,2011-10-12,2010-09-29
-5xs2,2017-08-09,2017-06-12
-7xss,2022-11-09,2022-05-15
-5xsj,2017-08-02,2017-06-14
-1xs4,2004-12-21,2004-10-18
-2xsv,2010-10-13,2010-09-30
-2xsu,2010-10-13,2010-09-30
-6xsd,2021-07-21,2020-07-15
-7xsz,2022-09-07,2022-05-15
-6xsq,2021-08-11,2020-07-16
-1xsl,2005-01-18,2004-10-19
-1xsp,2005-01-18,2004-10-19
-1xsm,1997-01-11,1996-07-03
-2xso,2010-11-24,2010-09-29
-6xs5,2021-07-14,2020-07-15
-4xsd,2015-12-16,2015-01-22
-4xst,2015-06-10,2015-01-22
-1xs6,2004-12-21,2004-10-18
-7xsp,2022-11-09,2022-05-15
-5xsf,2018-06-20,2017-06-14
-5xsa,2018-04-25,2017-06-13
-6xsg,2020-08-19,2020-07-15
-4xs2,2015-05-13,2015-01-21
-4xsh,2015-06-24,2015-01-22
-1xsc,2004-12-21,2004-10-18
-1xs7,2004-12-21,2004-10-18
-5xsw,2018-05-02,2017-06-15
-4xs6,2016-01-27,2015-01-21
-7xso,2023-03-22,2022-05-15
-5xss,2017-08-02,2017-06-15
-7xst,2022-11-23,2022-05-15
-5xs0,2018-04-25,2017-06-11
-5xsn,2018-01-31,2017-06-14
-7xsf,2023-01-18,2022-05-14
-7xs4,2022-09-21,2022-05-12
-4xss,2015-06-10,2015-01-22
-4xsx,2015-07-22,2015-01-22
-5xsr,2018-04-25,2017-06-15
-2xsb,2011-03-23,2010-09-27
-2xsq,2010-11-17,2010-09-29
-4xs0,2015-06-03,2015-01-21
-5xsu,2018-04-25,2017-06-15
-2xsr,2010-12-08,2010-09-30
-2xs8,2010-11-03,2010-09-24
-4xsu,2016-01-13,2015-01-22
-5xs6,2018-04-25,2017-06-12
-2xs0,2011-09-28,2010-09-24
-2xs5,2011-10-05,2010-09-24
-7xsh,2023-01-18,2022-05-14
-1xso,1995-07-10,1995-03-14
-4xs9,2016-01-27,2015-01-22
-4xsy,2015-07-22,2015-01-22
-6xso,2020-11-18,2020-07-15
-7xsr,2022-11-09,2022-05-15
-6xsh,2020-08-19,2020-07-15
-2xsi,2010-11-10,2010-10-29
-7xsx,2022-09-07,2022-05-15
-6xs9,2021-07-21,2020-07-15
-7xsv,2022-07-13,2022-05-15
-7xsg,2023-01-18,2022-05-14
-4xsl,2016-01-27,2015-01-22
-2xsh,2010-11-24,2010-09-29
-1xs2,2004-11-02,2004-10-18
-7xs8,2023-04-26,2022-05-13
-5xsm,2018-04-25,2017-06-14
-5xsi,2018-01-31,2017-06-14
-6xsy,2021-07-21,2020-07-16
-2xs4,2010-11-03,2010-09-24
-7xsw,2023-01-11,2022-05-15
-2xsz,2011-10-05,2010-10-01
-4xs4,2016-01-27,2015-01-21
-6xst,2021-07-21,2020-07-16
-4xs1,2016-01-27,2015-01-21
-5xs3,2017-09-13,2017-06-12
-6xsb,2020-08-19,2020-07-15
-2xsg,2011-10-12,2010-09-29
-1xss,2005-03-15,2004-10-20
-2xsc,2010-10-13,2010-09-27
-4xsr,2016-01-13,2015-01-22
-2gez,2006-07-25,2006-03-21
-1ge6,2001-03-14,2000-10-11
-1geg,2001-02-28,2000-11-10
-8gep,1998-01-14,1997-07-11
-7ge4,2023-11-08,2023-08-11
-8ges,2024-02-14,2023-03-07
-3ge5,2009-03-17,2009-02-25
-8get,2024-03-20,2023-03-07
-3gey,2009-03-24,2009-02-26
-3geh,2009-10-27,2009-02-25
-8ge7,2024-03-06,2023-03-06
-2geq,2006-05-23,2006-03-20
-6gep,1998-01-14,1997-07-10
-1gee,2003-08-12,2000-11-07
-4ge7,2012-11-07,2012-08-01
-8geq,2024-02-14,2023-03-07
-4gep,1998-01-14,1997-07-10
-8ge1,2024-03-06,2023-03-06
-1get,1994-11-01,1994-01-18
-6ge0,2018-05-30,2018-04-25
-3gen,2010-01-19,2009-02-25
-7ge5,2023-11-08,2023-08-11
-2gej,2007-04-03,2006-03-20
-7gew,2023-11-08,2023-08-11
-8ge3,2024-03-06,2023-03-06
-3gee,2009-10-27,2009-02-25
-3geq,2009-04-28,2009-02-25
-3ge3,2009-07-28,2009-02-24
-8gen,2024-02-14,2023-03-07
-3ge1,2009-03-24,2009-02-24
-7ged,2023-11-08,2023-08-11
-3ge4,2009-03-03,2009-02-25
-8ger,2024-03-20,2023-03-07
-7gei,2023-11-08,2023-08-11
-7geb,2023-11-08,2023-08-11
-1ger,1994-11-01,1994-01-18
-7gey,2023-11-08,2023-08-11
-8ged,2024-03-06,2023-03-06
-4gem,2012-10-17,2012-08-02
-6ged,2018-05-16,2018-04-26
-8ge9,2024-03-06,2023-03-06
-4ge1,2013-01-02,2012-08-01
-2ge3,2006-04-18,2006-03-17
-4gee,2013-02-13,2012-08-01
-8ge2,2024-03-06,2023-03-06
-7gep,1998-01-14,1997-07-11
-6gej,2018-10-17,2018-04-26
-7ge0,2023-11-08,2023-08-11
-1gei,2000-11-29,2000-11-13
-8gev,2023-10-04,2023-03-07
-7get,2023-11-08,2023-08-11
-6ge8,2019-05-08,2018-04-25
-4ge5,2012-10-31,2012-08-01
-6gey,2019-04-03,2018-04-27
-4ge6,2012-10-31,2012-08-01
-3geu,2009-03-10,2009-02-26
-4ge3,2012-08-15,2012-08-01
-8ge6,2024-03-06,2023-03-06
-8gei,2024-03-06,2023-03-06
-1gew,2001-04-18,2000-11-30
-7gex,2023-11-08,2023-08-11
-7geu,2023-11-08,2023-08-11
-7ges,2023-11-08,2023-08-11
-6gex,2019-04-03,2018-04-27
-7gea,2023-11-08,2023-08-11
-2get,2006-06-06,2006-03-20
-7gez,2023-11-08,2023-08-11
-7ge8,2023-11-08,2023-08-11
-7ge7,2023-11-08,2023-08-11
-6gew,2018-09-19,2018-04-27
-7gee,2023-11-08,2023-08-11
-4ge4,2012-11-07,2012-08-01
-7gec,2023-11-08,2023-08-11
-1geu,1994-11-01,1994-01-18
-6gev,2019-01-09,2018-04-27
-3ge7,2009-12-15,2009-02-25
-7ge3,2023-11-08,2023-08-11
-3gez,2009-08-25,2009-02-26
-7ge9,2023-11-08,2023-08-11
-7geh,2023-11-08,2023-08-11
-3ged,2009-03-17,2009-02-25
-4ge8,2012-08-29,2012-08-01
-4gel,2012-10-17,2012-08-02
-6gen,2018-10-17,2018-04-27
-6gem,2019-05-08,2018-04-26
-8gea,2024-03-06,2023-03-06
-4ge0,2012-08-15,2012-08-01
-1ged,2000-11-22,2000-11-02
-4geb,2013-03-20,2012-08-01
-7geq,2023-11-08,2023-08-11
-4ged,2012-10-24,2012-08-01
-3geo,1998-01-14,1997-07-10
-1gen,1996-08-17,1995-07-19
-6ges,2019-02-27,2018-04-27
-2gek,2007-04-03,2006-03-20
-8gej,2024-03-06,2023-03-06
-2gew,2006-05-02,2006-03-20
-8ge4,2024-03-06,2023-03-06
-7gek,2023-11-08,2023-08-11
-7gef,2023-11-08,2023-08-11
-7ge6,2023-11-08,2023-08-11
-6geh,2018-11-21,2018-04-26
-2gev,2006-06-06,2006-03-20
-4gey,2012-10-24,2012-08-02
-2geh,2006-06-20,2006-03-20
-1gek,2000-12-06,2000-11-13
-8gez,2023-05-24,2023-03-07
-5gep,1998-01-14,1997-07-10
-8geo,2024-03-20,2023-03-07
-4gez,2012-09-26,2012-08-02
-7gel,2023-11-08,2023-08-11
-3gei,2009-10-27,2009-02-25
-3gep,2009-08-18,2009-02-25
-3ge6,2009-03-10,2009-02-25
-4gev,2012-08-29,2012-08-02
-1ge5,2001-03-14,2000-10-11
-2geu,2006-06-06,2006-03-20
-4gej,2013-02-27,2012-08-02
-8gec,2024-03-06,2023-03-06
-7geg,2023-11-08,2023-08-11
-3ge8,2009-07-28,2009-02-25
-6geq,2019-08-07,2018-04-27
-8gey,2023-10-04,2023-03-07
-1gec,1995-12-07,1995-05-25
-2ge5,2006-07-04,2006-03-17
-8ge8,2024-03-06,2023-03-06
-8geh,2024-03-06,2023-03-06
-7geo,2023-11-08,2023-08-11
-7ger,2023-11-08,2023-08-11
-4ge9,2012-11-07,2012-08-01
-6geo,2019-08-07,2018-04-27
-7gej,2023-11-08,2023-08-11
-8gef,2024-03-06,2023-03-06
-6ge9,2018-05-02,2018-04-25
-7ge1,2023-11-08,2023-08-11
-6gez,2019-08-21,2018-04-27
-2ges,2006-06-06,2006-03-20
-8ge5,2024-03-06,2023-03-06
-1gey,2001-04-18,2000-11-30
-1ges,1994-11-01,1994-01-18
-6gel,2019-08-21,2018-04-26
-7gen,2023-11-08,2023-08-11
-8geg,2024-03-06,2023-03-06
-1gex,2001-04-18,2000-11-30
-3geb,2009-04-07,2009-02-25
-2geb,2007-04-03,2006-03-19
-4gek,2012-10-10,2012-08-02
-3geg,2009-03-17,2009-02-25
-8geb,2024-03-06,2023-03-06
-2gep,1998-01-14,1997-07-10
-7gev,2023-11-08,2023-08-11
-8gem,2023-10-04,2023-03-07
-1geb,2000-11-15,2000-11-01
-8ge0,2024-03-13,2023-03-06
-1gej,2000-12-06,2000-11-13
-3ge2,2009-03-17,2009-02-24
-4ge2,2012-10-31,2012-08-01
-7gem,2023-11-08,2023-08-11
-4ger,2013-01-02,2012-08-02
-8gee,2024-03-06,2023-03-06
-1gem,2000-12-06,2000-11-13
-8geu,2023-10-11,2023-03-07
-7ge2,2023-11-08,2023-08-11
-1ge7,2001-03-14,2000-10-11
-6re8,2019-07-03,2019-04-12
-7rec,2021-07-21,2021-07-12
-6ret,2019-07-03,2019-04-12
-8ref,2024-05-15,2023-12-11
-4rep,2015-07-15,2014-09-23
-5red,2020-03-25,2020-03-15
-7rel,2021-07-21,2021-07-13
-7rep,2021-11-17,2021-07-13
-1rek,2004-02-24,2003-11-06
-2reh,2008-06-03,2007-09-26
-2rew,2007-11-27,2007-09-27
-8rea,2024-01-17,2023-12-10
-1rej,2004-02-24,2003-11-06
-5rek,2020-03-25,2020-03-15
-4ret,2015-01-28,2014-09-23
-7re8,2022-07-27,2021-07-12
-7ren,2022-05-25,2021-07-13
-6re0,2019-07-03,2019-04-12
-6rex,2019-04-24,2019-04-12
-3rep,2011-04-27,2011-04-04
-3rem,2011-07-27,2011-04-04
-4re0,2015-02-25,2014-09-20
-5ret,2020-03-25,2020-03-15
-2ren,1994-01-31,1992-02-05
-5rec,2020-03-25,2020-03-15
-4re9,2015-09-30,2014-09-22
-5rex,2020-03-25,2020-03-15
-5rej,2020-03-25,2020-03-15
-4ref,2015-09-09,2014-09-22
-2ret,2008-02-05,2007-09-27
-6rez,2019-04-24,2019-04-12
-2reo,2007-10-09,2007-09-26
-8red,2024-01-17,2023-12-10
-1ref,1997-01-11,1995-12-21
-1rep,2000-02-09,1999-04-29
-3ren,2011-05-18,2011-04-04
-5reh,2020-03-25,2020-03-15
-5rep,2020-03-25,2020-03-15
-7rer,2022-01-12,2021-07-13
-7rei,2021-09-15,2021-07-12
-5reo,2020-03-25,2020-03-15
-8rec,2024-01-17,2023-12-10
-7re7,2022-07-27,2021-07-12
-5rel,2020-03-25,2020-03-15
-3red,2012-06-20,2011-04-04
-5re4,2020-03-25,2020-03-15
-4reo,2015-03-18,2014-09-23
-8re4,2024-01-17,2023-12-10
-6re5,2019-07-03,2019-04-12
-3ref,2011-09-28,2011-04-04
-1rec,1994-01-31,1993-10-29
-7reg,2022-07-27,2021-07-12
-6ree,2019-07-03,2019-04-12
-5rer,2020-03-25,2020-03-15
-5re9,2020-03-25,2020-03-15
-6rei,2020-05-13,2019-04-12
-2req,1998-01-28,1997-09-22
-3rew,2012-01-18,2011-04-05
-4re6,2015-01-28,2014-09-22
-1re2,1999-05-05,1998-11-05
-4req,1999-01-13,1998-06-17
-1re1,2004-05-11,2003-11-06
-3rej,2012-03-14,2011-04-04
-7reo,2021-11-17,2021-07-13
-5re5,2020-03-25,2020-03-15
-6ren,2019-07-31,2019-04-12
-6re7,2019-07-03,2019-04-12
-7re5,2022-06-08,2021-07-12
-5req,1998-08-12,1998-08-03
-6ref,2019-07-03,2019-04-12
-7re3,2021-11-24,2021-07-12
-4rew,2014-12-10,2014-09-24
-1re4,2004-05-25,2003-11-06
-2re9,2007-10-09,2007-09-25
-4rek,2015-04-15,2014-09-23
-1rev,1996-10-14,1995-09-17
-8rev,2024-05-29,2023-12-12
-6re6,2019-07-03,2019-04-12
-3rer,2011-10-19,2011-04-05
-1rey,1997-02-12,1996-08-21
-8ree,2024-01-17,2023-12-10
-3re3,2011-04-27,2011-04-02
-3reu,2011-08-17,2011-04-05
-1reo,2004-05-04,2003-11-07
-7reb,2022-07-27,2021-07-12
-4rer,2014-12-10,2014-09-23
-3ret,2011-07-27,2011-04-05
-1red,1997-01-11,1995-12-21
-3re8,2011-05-25,2011-04-03
-4rel,2015-01-21,2014-09-23
-1re9,2004-11-16,2003-11-06
-3res,2011-10-19,2011-04-05
-6rer,2019-07-03,2019-04-12
-1ree,1997-01-11,1995-12-21
-6reh,2019-07-31,2019-04-12
-8re3,2024-01-31,2023-12-10
-5rem,2020-03-25,2020-03-15
-5ren,2020-03-25,2020-03-15
-7ree,2021-09-01,2021-07-12
-5rea,2020-03-25,2020-03-15
-6rev,2020-05-13,2019-04-12
-5re7,2020-03-25,2020-03-15
-5ref,2020-03-25,2020-03-15
-4ree,2015-09-09,2014-09-22
-8re2,2024-01-31,2023-12-10
-4rei,2015-05-13,2014-09-23
-7rez,2023-01-18,2021-07-13
-5rew,2020-03-25,2020-03-15
-6req,1999-09-09,1998-09-03
-3rey,2011-09-07,2011-04-05
-6reg,2019-07-31,2019-04-12
-6re2,2019-07-03,2019-04-12
-3re7,2012-04-04,2011-04-02
-5reb,2020-03-25,2020-03-15
-6reb,2019-07-03,2019-04-12
-4reb,2014-12-24,2014-09-22
-2re8,2008-01-15,2007-09-25
-4re5,2015-01-28,2014-09-22
-1re0,2003-12-16,2003-11-06
-3rez,2012-02-15,2011-04-05
-5rei,2020-03-25,2020-03-15
-7rey,2023-01-18,2021-07-13
-4reu,2014-10-22,2014-09-24
-7re2,2021-12-01,2021-07-12
-1req,1997-01-27,1996-01-19
-3rek,2012-03-14,2011-04-04
-6re4,2019-07-03,2019-04-12
-6reu,2019-07-03,2019-04-12
-7req,1998-09-16,1998-09-10
-4re2,2015-09-16,2014-09-21
-6rea,2019-07-03,2019-04-12
-3reo,2012-03-14,2011-04-04
-5ree,2020-03-25,2020-03-15
-7reu,2021-07-28,2021-07-13
-1re8,2004-02-24,2003-11-06
-5re6,2020-03-25,2020-03-15
-8reb,2024-01-17,2023-12-10
-5rez,2020-03-25,2020-03-15
-2re1,2007-10-09,2007-09-25
-5re3,2020-06-03,2020-03-24
-5re8,2020-03-25,2020-03-15
-4ren,2015-01-21,2014-09-23
-6rel,2020-05-13,2019-04-12
-6re9,2019-07-03,2019-04-12
-3rei,2012-03-14,2011-04-04
-2ref,2007-11-20,2007-09-26
-6re3,2019-07-03,2019-04-12
-6red,2019-07-03,2019-04-12
-3reh,2012-03-14,2011-04-04
-7reh,2022-02-02,2021-07-12
-3req,1998-03-18,1997-12-04
-7red,2021-11-17,2021-07-12
-4res,2015-01-28,2014-09-23
-5reu,2020-03-25,2020-03-15
-6res,2019-07-03,2019-04-12
-1rer,2004-01-27,2003-11-07
-1rez,1997-02-12,1996-08-21
-7rek,2021-07-21,2021-07-13
-6re1,2019-07-03,2019-04-12
-7rem,2021-07-21,2021-07-13
-5rey,2020-03-25,2020-03-15
-3rel,2012-03-14,2011-04-04
-6rek,2019-07-31,2019-04-12
-4rez,2014-10-22,2014-09-24
-4re3,2015-09-16,2014-09-21
-2reu,2008-09-30,2007-09-27
-1re7,1996-12-23,1996-11-01
-5reg,2020-03-25,2020-03-15
-5rev,2020-03-25,2020-03-15
-7rev,2022-08-03,2021-07-13
-7re1,2021-12-01,2021-07-12
-3rex,2011-08-17,2011-04-05
-3re4,2012-05-09,2011-04-02
-6rej,2019-07-31,2019-04-12
-7res,2022-01-12,2021-07-13
-6rep,2019-07-03,2019-04-12
-4rem,2015-01-21,2014-09-23
-6rec,2019-07-03,2019-04-12
-1re3,2004-05-25,2003-11-06
-7re0,2021-12-01,2021-07-12
-3reg,2011-09-28,2011-04-04
-4re8,2015-09-09,2014-09-22
-5res,2020-03-25,2020-03-15
-1rem,1998-07-15,1998-01-14
-4re4,2015-09-16,2014-09-21
-7kzo,2021-01-20,2020-12-10
-5kzl,2017-07-26,2016-07-25
-4kz0,2013-07-17,2013-05-29
-6kzd,2019-10-09,2019-09-23
-3kzb,2010-03-09,2009-12-08
-5kzj,2017-07-05,2016-07-25
-6kzg,2020-09-30,2019-09-24
-7kzp,2021-03-10,2020-12-10
-6kzt,2020-09-23,2019-09-25
-1kzi,2002-07-03,2002-02-06
-6kzx,2020-05-06,2019-09-25
-1kzc,2002-07-05,2002-02-06
-5kzz,2016-08-17,2016-07-25
-6kzy,2019-11-06,2019-09-25
-6kzc,2019-10-09,2019-09-23
-3kzo,2010-03-31,2009-12-08
-5kzt,2016-08-10,2016-07-25
-7kzi,2021-05-12,2020-12-10
-3kzq,2010-02-02,2009-12-08
-7kzq,2021-03-10,2020-12-10
-1kza,2002-07-05,2002-02-06
-6kzu,2019-10-16,2019-09-25
-1kzl,2002-11-06,2002-02-07
-6kzv,2020-05-06,2019-09-25
-4kzl,2013-10-30,2013-05-30
-6kzq,2020-09-30,2019-09-25
-7kz7,2020-12-23,2020-12-10
-6kzk,2020-09-23,2019-09-24
-3kz7,2010-12-15,2009-12-08
-3kzw,2010-01-12,2009-12-08
-6kz5,2020-10-14,2019-09-23
-4kz5,2014-05-21,2013-05-29
-3kz0,2010-05-05,2009-12-07
-4kz9,2014-05-21,2013-05-29
-5kzx,2017-07-26,2016-07-25
-4kza,2014-05-21,2013-05-29
-6kzp,2019-12-18,2019-09-25
-1kze,2002-07-05,2002-02-06
-4kzi,2013-12-18,2013-05-30
-3kzk,2010-03-31,2009-12-08
-7kzu,2021-05-12,2020-12-10
-6kzn,2020-02-19,2019-09-24
-1kz8,2002-10-16,2002-02-06
-1kzo,2002-10-16,2002-02-07
-5kzc,2016-08-10,2016-07-24
-4kzn,2014-06-04,2013-05-30
-7kzy,2021-05-19,2020-12-10
-7kzm,2021-01-20,2020-12-10
-5kz8,2017-05-31,2016-07-23
-4kzq,2013-10-30,2013-05-30
-5kzq,2016-12-28,2016-07-25
-7kzd,2021-05-26,2020-12-10
-1kzm,2002-10-09,2002-02-07
-7kzs,2021-03-10,2020-12-10
-4kzv,2013-08-28,2013-05-30
-2kz2,2011-04-20,2010-06-10
-3kzp,2009-12-22,2009-12-08
-7kz2,2021-12-15,2020-12-09
-1kzu,1997-04-01,1996-08-31
-7kz4,2021-05-19,2020-12-09
-5kz0,2016-08-17,2016-07-22
-7kzt,2021-03-10,2020-12-10
-3kzz,2010-12-15,2009-12-09
-3kz4,2010-03-02,2009-12-07
-3kz1,2010-04-28,2009-12-07
-3kzh,2009-12-22,2009-12-08
-3kzl,2009-12-22,2009-12-08
-7kzl,2020-12-23,2020-12-10
-7kz0,2021-11-10,2020-12-09
-5kzi,2016-11-09,2016-07-25
-6kzs,2020-09-23,2019-09-25
-4kzo,2013-07-17,2013-05-30
-6kzb,2020-12-09,2019-09-23
-1kzy,2002-03-20,2002-02-08
-4kz3,2014-05-21,2013-05-29
-4kzk,2013-06-26,2013-05-30
-3kze,2010-04-21,2009-12-08
-2kzz,1999-12-14,1998-07-07
-5kzn,2016-12-28,2016-07-25
-6kzh,2020-09-30,2019-09-24
-3kzi,2010-06-16,2009-12-08
-6kzz,2020-05-06,2019-09-25
-1kzp,2002-10-16,2002-02-07
-7kze,2022-06-15,2020-12-10
-7kz9,2021-03-17,2020-12-10
-4kz4,2014-05-21,2013-05-29
-5kzu,2016-11-02,2016-07-25
-7kz5,2021-05-26,2020-12-10
-7kz6,2021-05-26,2020-12-10
-1kzk,2002-04-03,2002-02-06
-6kz9,2019-10-30,2019-09-23
-7kzb,2021-02-03,2020-12-10
-3kzn,2010-03-31,2009-12-08
-1kzj,2002-07-03,2002-02-06
-5kzp,2017-07-05,2016-07-25
-4kz8,2014-05-21,2013-05-29
-4kzb,2014-05-21,2013-05-29
-2kzm,1999-02-16,1998-07-03
-4kzc,2013-07-17,2013-05-29
-1kzn,2002-06-19,2002-02-07
-3kzy,2010-12-15,2009-12-09
-6kze,2020-09-30,2019-09-24
-6kzo,2019-12-18,2019-09-25
-6kzl,2020-02-19,2019-09-24
-7kzh,2021-12-15,2020-12-10
-4kzt,2014-04-16,2013-05-30
-7kzg,2021-11-10,2020-12-10
-1kzd,2002-07-05,2002-02-06
-7kzz,2021-01-06,2020-12-10
-7kz1,2021-11-10,2020-12-09
-7kza,2021-02-24,2020-12-10
-5kzd,2017-01-11,2016-07-25
-4kzd,2014-06-18,2013-05-29
-1kzb,2002-07-05,2002-02-06
-5kzk,2017-08-02,2016-07-25
-5kzy,2016-08-17,2016-07-25
-4kz7,2014-05-21,2013-05-29
-5kzm,2016-08-10,2016-07-25
-4kz6,2014-05-21,2013-05-29
-7kzv,2021-03-10,2020-12-10
-5kzw,2017-07-26,2016-07-25
-5kz6,2016-08-03,2016-07-22
-5kz7,2017-05-31,2016-07-23
-6kz8,2019-11-13,2019-09-23
-7kz3,2021-05-26,2020-12-09
-6kzi,2020-03-04,2019-09-24
-7kzr,2021-03-10,2020-12-10
-3kz8,2010-03-31,2009-12-08
-4kzu,2013-10-30,2013-05-30
-6kzr,2020-03-25,2019-09-25
-4kzw,2013-08-28,2013-05-30
-5kzv,2016-08-17,2016-07-25
-6kz6,2019-11-13,2019-09-23
-2kzy,2011-07-06,2010-06-28
-6tnh,2020-12-16,2019-12-08
-1tni,1994-11-30,1994-07-21
-7tnj,2022-04-20,2022-01-21
-3tnh,2012-02-15,2011-09-01
-8tnd,2024-04-24,2023-08-01
-7tno,2022-04-20,2022-01-21
-4tnc,1988-07-16,1987-09-28
-8tng,2024-05-08,2023-08-01
-4tni,2014-07-09,2014-06-04
-7tnc,2023-01-25,2022-01-20
-4tnn,2014-06-25,2014-06-04
-5tnj,2017-10-11,2016-10-14
-8tn8,2023-11-15,2023-08-01
-7tnv,2023-04-12,2022-01-21
-4tnt,2014-09-17,2014-06-04
-5tno,2017-04-26,2016-10-14
-4tnq,2014-10-01,2014-06-04
-3tn7,2012-08-15,2011-09-01
-5tnb,2017-02-15,2016-10-13
-3tny,2012-09-05,2011-09-02
-3tnq,2012-02-01,2011-09-01
-1tnq,1995-10-15,1995-07-07
-5tn6,2017-01-18,2016-10-13
-3tnf,2011-11-02,2011-09-01
-7tnk,2022-04-20,2022-01-21
-5tni,2017-10-11,2016-10-14
-6tnu,2020-04-22,2019-12-10
-4tnk,2014-07-09,2014-06-04
-1tnk,1994-11-30,1994-07-21
-1tn7,2004-11-02,2004-06-11
-5tnx,2016-11-09,2016-10-15
-7tny,2022-11-02,2022-01-22
-8tn6,2024-04-24,2023-08-01
-6tn2,2020-10-14,2019-12-05
-8tnb,2024-04-24,2023-08-01
-7tnn,2022-04-20,2022-01-21
-7tn1,2023-07-12,2022-01-20
-6tnn,2020-09-30,2019-12-09
-1tnz,2004-11-02,2004-06-11
-3tns,2012-09-05,2011-09-01
-3tn8,2012-02-15,2011-09-01
-6tn5,2020-10-14,2019-12-05
-8tnk,2023-10-25,2023-08-02
-7tnu,2023-01-04,2022-01-21
-4tnw,2014-08-13,2014-06-05
-3tn5,2012-09-12,2011-09-01
-8tnl,2024-05-15,2023-08-02
-7tnd,2023-01-04,2022-01-20
-5tnt,2017-04-26,2016-10-14
-6tnz,2019-12-18,2019-12-10
-4tn5,2015-06-10,2014-06-03
-6tn4,2020-10-14,2019-12-05
-5tn5,2017-01-18,2016-10-13
-8tnx,2024-05-22,2023-08-02
-3tne,2012-03-07,2011-09-01
-6tnj,2020-12-02,2019-12-08
-4tnd,2015-06-10,2014-06-04
-6tn0,2020-10-14,2019-12-05
-5tn9,2017-02-15,2016-10-13
-1tn5,2004-10-19,2004-06-11
-6tnp,2020-11-18,2019-12-09
-4tns,2015-04-08,2014-06-04
-6tns,2020-01-01,2019-12-10
-4tnx,2014-10-01,2014-06-05
-5tnk,2017-10-11,2016-10-14
-6tn3,2020-04-01,2019-12-05
-1tn3,1998-05-06,1997-11-06
-6tn1,2020-06-10,2019-12-05
-4tnu,2014-07-30,2014-06-05
-2tn4,1998-04-08,1997-09-18
-7tn9,2023-01-25,2022-01-20
-6tn9,2020-05-13,2019-12-06
-3tnl,2011-09-28,2011-09-01
-1tnb,2004-11-02,2004-06-11
-3tn0,2011-12-14,2011-09-01
-8tn9,2023-10-04,2023-08-01
-5tnc,1988-10-09,1988-05-27
-3tnb,2012-09-12,2011-09-01
-4tnl,2014-07-09,2014-06-04
-4tn3,2014-07-16,2014-06-03
-6tn8,2019-12-18,2019-12-06
-1tnd,1994-07-31,1994-03-31
-8tni,2024-05-08,2023-08-01
-4tnv,2014-08-13,2014-06-05
-4tn7,2015-05-13,2014-06-03
-5tn3,2017-01-18,2016-10-13
-1tnh,1994-11-30,1994-07-21
-5tng,2017-10-11,2016-10-14
-1tn8,2004-11-02,2004-06-11
-5tnl,2017-10-11,2016-10-14
-3tnj,2011-09-14,2011-09-01
-8tnq,2024-03-13,2023-08-02
-6tnb,2020-05-13,2019-12-06
-4tn1,2014-09-24,2014-06-02
-5tne,2017-10-11,2016-10-14
-8tnt,2024-03-27,2023-08-02
-1tno,2004-11-02,2004-06-11
-7tnx,2022-11-02,2022-01-22
-4tnz,2014-10-01,2014-06-05
-7tnm,2022-04-20,2022-01-21
-3tno,2011-09-14,2011-09-01
-6tnk,2019-12-18,2019-12-09
-4tny,2014-10-01,2014-06-05
-1tny,2004-11-02,2004-06-11
-8tnh,2024-05-08,2023-08-01
-6tnc,2020-05-13,2019-12-06
-4tnr,2014-10-01,2014-06-04
-3tnw,2012-02-15,2011-09-02
-1tnu,2004-11-02,2004-06-11
-4tnj,2014-07-09,2014-06-04
-5tnp,2017-10-11,2016-10-14
-3tn2,2012-09-05,2011-09-01
-8tnc,2024-04-24,2023-08-01
-8tnp,2024-03-13,2023-08-02
-5tnn,2017-10-11,2016-10-14
-5tnm,2017-10-11,2016-10-14
-5tnd,2017-10-11,2016-10-14
-3tnd,2011-11-02,2011-09-01
-4tn4,2015-03-25,2014-06-03
-7tni,2022-05-04,2022-01-21
-5tnz,2017-10-25,2016-10-15
-7tnp,2022-04-20,2022-01-21
-5tn8,2017-01-18,2016-10-13
-7tnf,2023-01-04,2022-01-21
-3tn4,2012-09-19,2011-09-01
-5tn4,2017-01-18,2016-10-13
-6tnm,2020-03-25,2019-12-09
-4tnp,2014-10-01,2014-06-04
-7tne,2022-09-14,2022-01-20
-5tns,2017-10-11,2016-10-14
-7tn0,2022-02-02,2022-01-20
-7tnl,2022-04-20,2022-01-21
-6tnr,2020-01-01,2019-12-10
-6tnd,2020-05-13,2019-12-06
-6tny,2019-12-18,2019-12-10
-4tn2,2014-09-17,2014-06-02
-7tnh,2022-08-24,2022-01-21
-5tn7,2017-01-18,2016-10-13
-7tnw,2022-02-16,2022-01-21
-4tn6,2015-08-12,2014-06-03
-4tnb,2015-06-10,2014-06-03
-1tn4,1998-04-08,1997-09-18
-7tn4,2022-06-15,2022-01-20
-4tnh,2014-07-09,2014-06-04
-3tn6,2012-09-12,2011-09-01
-8tnv,2024-04-10,2023-08-02
-1tng,1994-11-30,1994-07-21
-8tn3,2023-11-22,2023-08-01
-4tn0,2014-10-08,2014-06-02
-7tnz,2022-11-02,2022-01-22
-1tn0,2004-10-12,2004-06-11
-6tnq,2021-01-13,2019-12-10
-3tn3,2012-09-12,2011-09-01
-6tn6,2020-04-29,2019-12-06
-1tn6,2004-11-02,2004-06-11
-8tnn,2024-03-27,2023-08-02
-6tno,2020-12-16,2019-12-09
-3tnz,2012-02-29,2011-09-02
-5tnq,2017-10-11,2016-10-14
-3tng,2011-09-21,2011-09-01
-1tnj,1994-11-30,1994-07-21
-3tnt,2012-09-05,2011-09-02
-7tnb,2022-08-24,2022-01-20
-8tnr,2024-03-13,2023-08-02
-1tnl,1994-11-30,1994-07-21
-5tnv,2016-11-09,2016-10-14
-6tnt,2021-01-13,2019-12-10
-5tn1,2017-01-18,2016-10-13
-5oo8,2017-08-23,2017-08-06
-3oo0,2011-08-31,2010-08-30
-5ooe,2018-06-13,2017-08-07
-1ooq,2003-04-02,2003-03-04
-6ooa,2019-09-11,2019-04-22
-7oo9,2021-06-30,2021-05-26
-2ooh,2007-06-05,2007-01-25
-5oo5,2017-08-23,2017-08-05
-2ood,2007-02-20,2007-01-25
-3ool,2010-11-17,2010-08-31
-6oos,2019-08-21,2019-04-23
-4ood,2014-11-26,2014-01-31
-7oow,2021-08-04,2021-05-28
-5ooh,2018-03-07,2017-08-07
-5oo4,2017-08-23,2017-08-05
-5oo1,2018-08-29,2017-08-04
-1oon,2003-04-08,2003-03-04
-4oor,2014-10-29,2014-02-03
-1ooj,2003-03-25,2003-03-03
-3oob,2011-08-17,2010-08-30
-4oo9,2014-07-02,2014-01-31
-4ooq,2015-07-22,2014-02-03
-7ooa,2021-09-01,2021-05-27
-8oon,2024-01-24,2023-04-05
-2oof,2007-02-20,2007-01-25
-6ooo,2020-03-11,2019-04-23
-8oo2,2023-08-02,2023-04-04
-8oor,2023-07-26,2023-04-05
-4ooj,2014-02-26,2014-02-03
-4oof,2014-06-18,2014-01-31
-5oo2,2018-08-29,2017-08-05
-6oou,2019-08-21,2019-04-23
-1ooy,2004-04-27,2003-03-04
-5oof,2018-06-13,2017-08-07
-3oo3,2011-01-05,2010-08-30
-8ooc,2023-08-02,2023-04-05
-2ooy,2007-02-06,2007-01-26
-1ook,2003-07-22,2003-03-03
-6ool,2020-04-29,2019-04-23
-6oop,2019-09-04,2019-04-23
-6oo7,2019-05-29,2019-04-22
-4ool,2014-05-07,2014-02-03
-2oow,2007-06-05,2007-01-26
-2oo0,2007-07-17,2007-01-25
-2oo4,2007-04-03,2007-01-25
-4ooe,2014-06-18,2014-01-31
-5oow,2018-04-25,2017-08-09
-5ood,2018-06-13,2017-08-07
-5oop,2017-10-25,2017-08-08
-7ooe,2021-06-02,2021-05-27
-4oo1,2014-07-02,2014-01-29
-5ooc,2018-06-13,2017-08-07
-6oot,2019-08-21,2019-04-23
-8oo3,2023-07-12,2023-04-04
-5oon,2018-03-21,2017-08-08
-6ooj,2020-07-01,2019-04-23
-7oo3,2021-10-06,2021-05-26
-5oot,2017-10-25,2017-08-08
-1oow,2004-02-17,2003-03-04
-3ooz,2011-08-31,2010-08-31
-3oo5,2011-09-07,2010-08-30
-4oot,2014-12-17,2014-02-04
-7oox,2021-08-04,2021-05-28
-8ooy,2023-08-09,2023-04-06
-2oo8,2007-03-20,2007-01-25
-5oom,2017-09-13,2017-08-08
-7oop,2021-10-06,2021-05-28
-4oo6,2014-02-12,2014-01-30
-8ooz,2024-01-24,2023-04-06
-6oo1,2020-07-22,2019-04-22
-8oo7,2023-07-26,2023-04-04
-8oo1,2024-04-10,2023-04-04
-2oog,2007-02-06,2007-01-25
-8ooj,2023-12-20,2023-04-05
-6oog,2020-01-08,2019-04-23
-6oox,2020-04-29,2019-04-23
-1oo0,2003-05-27,2003-03-02
-1oo4,2003-03-25,2003-03-03
-6oo3,2019-05-29,2019-04-22
-2ooz,2007-06-05,2007-01-26
-2ooq,2007-02-20,2007-01-26
-8oo9,2023-07-26,2023-04-04
-8oo5,2023-05-24,2023-04-04
-6ooi,2020-01-08,2019-04-23
-5oo0,2018-03-14,2017-08-04
-2ool,2007-07-10,2007-01-25
-7ood,2022-05-25,2021-05-27
-3oog,2011-08-31,2010-08-31
-6ook,2020-07-01,2019-04-23
-8oos,2023-07-26,2023-04-05
-3oor,2010-11-17,2010-08-31
-7ooy,2022-05-04,2021-05-28
-7oo7,2022-04-20,2021-05-26
-7ook,2022-06-08,2021-05-27
-6ooy,2019-12-25,2019-04-23
-2oo7,2008-02-05,2007-01-25
-4oo2,2014-02-12,2014-01-29
-4oom,2014-05-07,2014-02-03
-7oob,2021-10-13,2021-05-27
-7ooj,2022-05-18,2021-05-27
-3ook,2011-01-19,2010-08-31
-3ood,2011-11-02,2010-08-31
-3oom,2010-10-13,2010-08-31
-1ooh,2003-09-02,2003-03-03
-6oo4,2019-05-29,2019-04-22
-5ool,2017-09-13,2017-08-08
-8ooi,2024-01-31,2023-04-05
-5ook,2018-06-20,2017-08-08
-2ooi,2007-02-27,2007-01-25
-4ooo,2014-06-18,2014-02-03
-6oor,2019-07-17,2019-04-23
-5oog,2018-03-07,2017-08-07
-8ool,2024-01-24,2023-04-05
-8ooo,2024-01-24,2023-04-05
-8oof,2023-07-26,2023-04-05
-8oop,2023-07-26,2023-04-05
-8ood,2023-05-24,2023-04-05
-6oo5,2019-05-29,2019-04-22
-4ooy,2014-08-20,2014-02-04
-5ooi,2017-12-27,2017-08-07
-8oo8,2024-04-10,2023-04-04
-6oo2,2019-08-21,2019-04-22
-6oo9,2019-09-11,2019-04-22
-6oo6,2019-09-25,2019-04-22
-7oor,2022-06-08,2021-05-28
-8oov,2023-06-07,2023-04-06
-4ook,2015-02-04,2014-02-03
-8oo4,2023-07-12,2023-04-04
-7ooh,,2021-05-27
-7oo4,2021-07-21,2021-05-26
-5oo9,2017-08-23,2017-08-06
-7oou,2022-06-08,2021-05-28
-6oo8,2020-04-29,2019-04-22
-2oov,2007-04-10,2007-01-26
-8oog,2023-07-12,2023-04-05
-2oo1,2007-02-13,2007-01-25
-1oo6,2003-04-08,2003-03-03
-1oo2,2004-01-20,2003-03-03
-5oo3,2018-08-29,2017-08-05
-4oop,2015-04-08,2014-02-03
-7oo5,2021-10-13,2021-05-26
-3oo6,2010-12-29,2010-08-30
-8oo0,2024-02-21,2023-04-04
-2oo5,2007-03-13,2007-01-25
-4oon,2014-05-07,2014-02-03
-3ooy,2010-11-17,2010-08-31
-8oot,2023-07-26,2023-04-05
-5ooa,2017-08-23,2017-08-06
-8oom,2024-04-17,2023-04-05
-2oox,2007-02-06,2007-01-26
-8oo6,2023-08-09,2023-04-04
-6oof,2020-07-01,2019-04-23
-1ooz,2004-04-27,2003-03-04
-6ooh,2020-07-01,2019-04-23
-4oog,2014-04-16,2014-02-02
-8oow,2024-01-24,2023-04-06
-7oon,2022-01-26,2021-05-28
-2oos,2007-07-17,2007-01-26
-6ooq,2019-09-04,2019-04-23
-5oob,2017-11-15,2017-08-07
-6ooz,2019-12-25,2019-04-23
-2oot,2007-03-20,2007-01-26
-4ooz,2014-08-06,2014-02-04
-3oo2,2010-10-06,2010-08-30
-7oof,2022-06-08,2021-05-27
-7ooc,2022-05-25,2021-05-27
-3ooi,2010-12-22,2010-08-31
-7oog,2021-06-02,2021-05-27
-8ooq,2024-01-24,2023-04-05
-6oom,2019-09-04,2019-04-23
-2oor,2007-03-13,2007-01-26
-7ooz,2022-05-04,2021-05-28
-3oot,2010-10-27,2010-08-31
-6ooe,2020-07-01,2019-04-23
-3oo4,2011-09-07,2010-08-30
-5oor,2017-10-25,2017-08-08
-3oo1,2011-08-31,2010-08-30
-6oob,2019-09-11,2019-04-22
-1oo5,2003-04-08,2003-03-03
-7oov,2021-08-04,2021-05-28
-6oow,2020-04-29,2019-04-23
-8oox,2024-01-24,2023-04-06
-3ooj,2011-10-19,2010-08-31
-3oof,2011-01-19,2010-08-31
-5oo6,2017-11-15,2017-08-06
-2bvs,2006-10-25,2005-07-04
-7bv5,2020-11-18,2020-04-09
-3bvb,2008-04-01,2008-01-05
-2bvj,2006-07-03,2005-06-28
-8bvk,2023-11-01,2022-12-04
-7bvu,2021-04-14,2020-04-11
-3bvk,2009-01-13,2008-01-07
-7bvj,2020-12-02,2020-04-10
-6bvl,2018-10-24,2017-12-13
-6bv5,2019-06-12,2017-12-12
-5bvd,2015-09-09,2015-06-05
-2bvd,2005-06-30,2005-06-27
-3bv8,2008-02-05,2008-01-04
-6bvi,2018-10-24,2017-12-13
-3bv6,2008-01-29,2008-01-04
-8bvl,2023-01-18,2022-12-04
-1bvy,1999-02-23,1998-09-21
-6bvr,2018-06-06,2017-12-13
-5bvc,2015-09-16,2015-06-05
-7bvb,2020-04-22,2020-04-10
-4bv4,2013-12-04,2013-06-24
-5bv9,2015-09-30,2015-06-04
-3bvj,2008-11-18,2008-01-07
-2bvt,2005-09-26,2005-07-04
-3bv0,2008-02-05,2008-01-04
-2bvf,2005-08-17,2005-06-28
-6bvj,2018-10-24,2017-12-13
-6bv0,2018-01-17,2017-12-12
-2bv0,2006-10-26,2005-06-20
-1bv9,1998-09-30,1998-09-22
-3bvo,2008-01-15,2008-01-07
-4bvb,2013-07-17,2013-06-25
-5bvf,2015-09-09,2015-06-05
-6bv4,2018-01-10,2017-12-12
-6bve,2018-12-19,2017-12-12
-8bvf,2023-02-22,2022-12-03
-5bva,2016-03-09,2015-06-04
-2bvm,2005-08-03,2005-06-30
-3bvv,2008-07-01,2008-01-07
-4bv5,2014-07-09,2013-06-25
-8bv0,2022-12-21,2022-12-01
-3bvh,2008-09-02,2008-01-07
-5bv5,2016-02-03,2015-06-04
-5bvr,2016-03-23,2015-06-05
-7bve,2020-04-29,2020-04-10
-6bvh,2018-12-19,2017-12-13
-2bvl,2005-08-03,2005-06-30
-8bve,2023-02-22,2022-12-03
-4bvr,2013-07-17,2013-06-28
-7bvf,2020-04-29,2020-04-10
-6bv9,2019-06-12,2017-12-12
-6bvg,2018-05-23,2017-12-12
-2bvw,2000-02-25,1999-02-18
-6bvm,2018-10-24,2017-12-13
-2bv3,2005-08-10,2005-06-22
-6bvc,2017-12-27,2017-12-12
-7bvr,2021-04-14,2020-04-11
-7bv3,2021-03-03,2020-04-09
-1bvv,1999-06-08,1998-09-18
-4bvs,2013-07-17,2013-06-28
-8bvd,2023-02-15,2022-12-03
-7bvt,2020-12-02,2020-04-11
-2bvr,2006-10-25,2005-07-04
-8bv7,2023-12-13,2022-12-02
-4bv9,2014-02-05,2013-06-25
-6bv2,2018-01-17,2017-12-12
-7bvy,2020-10-14,2020-04-12
-1bve,1996-08-17,1996-01-16
-6bv6,2019-06-12,2017-12-12
-7bvl,2020-11-18,2020-04-11
-4bvd,2014-07-16,2013-06-25
-3bvi,2009-01-13,2008-01-07
-8bvs,2023-07-19,2022-12-05
-1bva,1998-12-23,1998-09-15
-5bv2,2015-06-24,2015-06-04
-7bvd,2020-05-06,2020-04-10
-2bv8,2006-08-16,2005-06-23
-5bv6,2016-01-20,2015-06-04
-4bvf,2013-07-17,2013-06-25
-7bvp,2020-06-24,2020-04-11
-6bvp,2018-06-06,2017-12-13
-1bvc,1995-07-31,1994-12-16
-4bv3,2013-07-17,2013-06-24
-5bvu,2016-05-18,2015-06-05
-4bvh,2013-07-17,2013-06-25
-2bve,2006-07-19,2005-06-27
-1bvw,1999-09-18,1998-09-19
-5bvz,2015-06-24,2015-06-05
-3bvu,2008-07-01,2008-01-07
-3bv7,2008-04-01,2008-01-04
-3bvg,2009-01-27,2008-01-07
-7bvw,2021-04-14,2020-04-12
-5bve,2015-09-09,2015-06-05
-8bv4,2023-07-05,2022-12-01
-4bvv,2014-07-16,2013-06-28
-8bv2,2023-06-07,2022-12-01
-4bvn,2014-04-02,2013-06-26
-6bv1,2018-01-17,2017-12-12
-3bvt,2008-07-01,2008-01-07
-8bv1,2023-07-05,2022-12-01
-3bvl,2009-01-13,2008-01-07
-3bvw,2008-07-01,2008-01-07
-4bvp,2014-02-12,2013-06-27
-6bvq,2018-06-06,2017-12-13
-6bvk,2018-10-24,2017-12-13
-7bvz,2020-10-14,2020-04-12
-1bvb,1999-05-18,1998-09-16
-4bvj,2013-09-18,2013-06-26
-9bv0,2024-05-29,2024-05-18
-6bv8,2019-06-12,2017-12-12
-1bv3,1999-09-28,1998-09-22
-7bvg,2020-04-29,2020-04-10
-2bvc,2005-07-07,2005-06-23
-5bv7,2015-12-16,2015-06-04
-8bvw,2023-05-03,2022-12-20
-4bv0,2014-01-29,2013-06-24
-4bvo,2014-02-12,2013-06-27
-3bvz,2009-05-12,2008-01-07
-6bvn,2018-02-07,2017-12-13
-2bvx,2006-10-25,2005-07-04
-7bvi,2021-04-14,2020-04-10
-6bv3,2018-01-17,2017-12-12
-2bvg,2005-08-17,2005-06-28
-7bvs,2021-04-14,2020-04-11
-3bvc,2008-02-12,2008-01-06
-5bvb,2015-10-28,2015-06-04
-2bvp,2005-09-07,2005-07-01
-4bv8,2014-02-05,2013-06-25
-3bvd,2008-05-20,2008-01-07
-8bv5,2024-01-17,2023-01-04
-2bv2,2005-09-29,2005-06-21
-7bvn,2020-11-18,2020-04-11
-5bvw,2015-08-05,2015-06-05
-3bvm,2009-05-12,2008-01-07
-4bva,2014-02-05,2013-06-25
-2bv4,2006-05-25,2005-06-22
-3bva,2008-04-01,2008-01-05
-7bvh,2020-04-29,2020-04-10
-3bvq,2008-01-22,2008-01-07
-4bvc,2014-07-09,2013-06-25
-6bvs,2018-06-06,2017-12-13
-8bv3,2023-12-13,2022-12-01
-1bvn,1998-09-23,1998-09-16
-1bvt,1998-09-23,1998-09-18
-5bvo,2015-08-05,2015-06-05
-1bvd,1995-07-31,1994-12-16
-2bvq,2005-09-07,2005-07-01
-7bva,2020-04-22,2020-04-10
-8bvx,2024-05-15,2022-12-05
-3bv9,2008-03-04,2008-01-05
-6bvf,2018-02-07,2017-12-12
-5bvk,2015-08-05,2015-06-05
-3bv3,2008-04-15,2008-01-04
-8bvt,2023-07-19,2022-12-06
-1bvi,1998-09-23,1998-09-15
-3bvx,2008-07-01,2008-01-07
-1bvg,1996-08-17,1996-01-16
-7bvk,2020-12-02,2020-04-11
-6bvd,2018-05-09,2017-12-12
-7bvq,2020-12-02,2020-04-11
-3bvf,2009-01-13,2008-01-07
-4bv2,2013-07-17,2013-06-24
-1bv7,1998-09-30,1998-09-22
-4bvw,2014-07-16,2013-06-28
-5bvn,2015-08-12,2015-06-05
-8bva,2023-12-13,2022-12-02
-4bv6,2014-09-17,2013-06-25
-3bvn,2009-02-03,2008-01-07
-7bv2,2020-04-22,2020-04-09
-2bvh,2005-08-17,2005-06-28
-3bv2,2008-04-08,2008-01-04
-2bvn,2005-09-01,2005-06-30
-4bvq,2013-07-17,2013-06-28
-4bve,2013-07-17,2013-06-25
-4bvt,2013-07-17,2013-06-28
-5bv3,2015-08-12,2015-06-04
-4bvg,2013-07-17,2013-06-25
-1bvr,1999-09-17,1998-09-17
-4bv7,2014-07-09,2013-06-25
-7bv1,2020-04-22,2020-04-09
-7bvc,2020-04-29,2020-04-10
-6lke,2020-12-23,2019-12-19
-6lk9,2020-12-23,2019-12-18
-6lkd,2020-12-23,2019-12-19
-6lks,2020-10-21,2019-12-20
-5lkt,2016-11-02,2016-07-24
-4lkf,2013-12-18,2013-07-07
-2lk5,2012-01-25,2011-10-06
-1lka,2002-08-28,2002-04-24
-6lk2,2020-07-29,2019-12-17
-5lks,2017-04-26,2016-07-23
-7lks,2021-02-17,2021-02-02
-4lkg,2013-11-06,2013-07-07
-4lkj,2013-11-06,2013-07-07
-3lku,2010-06-23,2010-01-27
-4lkl,2013-12-11,2013-07-08
-6lkp,2020-03-25,2019-12-19
-2lki,2011-11-16,2011-10-11
-2lk0,2011-12-28,2011-09-30
-6lk4,2020-03-18,2019-12-18
-3lkq,2010-07-07,2010-01-27
-4lk8,2014-07-16,2013-07-07
-7lkh,2021-06-30,2021-02-02
-7lkj,2021-06-23,2021-02-02
-3lkt,2011-02-23,2010-01-27
-5lk3,2016-09-14,2016-07-20
-7lk7,2022-02-09,2021-02-01
-3lkk,2010-06-02,2010-01-27
-6lkm,2020-12-23,2019-12-19
-1lkv,2002-07-10,2002-04-25
-1lkb,2002-08-28,2002-04-24
-4lka,2013-10-16,2013-07-07
-7lkv,2021-02-17,2021-02-02
-6lkx,2020-05-27,2019-12-20
-7lkt,2021-02-17,2021-02-02
-7lkq,2021-08-11,2021-02-02
-7lk1,2022-02-16,2021-02-01
-7lkl,2022-02-02,2021-02-02
-4lkd,2013-12-18,2013-07-07
-5lkg,2017-05-24,2016-07-22
-3lkj,2011-02-02,2010-01-27
-4lks,2014-12-24,2013-07-08
-6lkr,2020-03-25,2019-12-20
-5lk0,2016-09-14,2016-07-20
-6lkg,2020-12-02,2019-12-19
-7lk0,2022-02-16,2021-02-01
-3lko,2010-07-07,2010-01-27
-4lk6,2013-10-30,2013-07-06
-3lkz,2010-08-04,2010-01-28
-7lk8,2021-05-26,2021-02-01
-7lky,2021-12-15,2021-02-03
-3lkm,2010-03-16,2010-01-27
-4lkh,2013-11-06,2013-07-07
-5lkc,2017-05-24,2016-07-22
-1lk9,2002-12-11,2002-04-24
-6lkq,2020-05-06,2019-12-20
-4lkq,2014-02-26,2013-07-08
-3lki,2010-03-09,2010-01-27
-1lkx,2002-06-26,2002-04-26
-6lkb,2020-12-16,2019-12-18
-3lk9,2011-01-12,2010-01-27
-4lkv,2014-07-09,2013-07-08
-1lkk,1996-03-08,1995-11-10
-1lk7,2002-07-03,2002-04-24
-4lk0,2013-11-13,2013-07-05
-3lkp,2010-07-07,2010-01-27
-4lkm,2013-12-11,2013-07-08
-3lkw,2010-03-02,2010-01-28
-3lkn,2010-07-07,2010-01-27
-7lkw,2021-02-17,2021-02-02
-5lkz,2016-11-02,2016-07-25
-4lk7,2013-10-30,2013-07-06
-7lki,2021-08-04,2021-02-02
-6lky,2020-12-23,2019-12-21
-4lki,2013-11-06,2013-07-07
-2lko,2011-10-26,2011-10-17
-3lks,2010-07-07,2010-01-27
-5lkr,2016-12-14,2016-07-23
-5lk2,2016-09-14,2016-07-20
-4lke,2013-12-18,2013-07-07
-1lkd,2002-11-27,2002-04-24
-4lk1,2013-11-13,2013-07-05
-5lk5,2016-08-31,2016-07-21
-5lkx,2016-11-02,2016-07-25
-5lk1,2016-09-14,2016-07-20
-7lkp,2021-03-03,2021-02-02
-4lk9,2013-10-16,2013-07-07
-1lk0,2002-08-07,2002-04-23
-5lk9,2017-08-02,2016-07-21
-5lkk,2017-05-24,2016-07-22
-6lkj,2020-12-02,2019-12-19
-5lkw,2017-08-16,2016-07-25
-1lk2,2003-11-11,2002-04-23
-2lkd,2012-02-15,2011-10-10
-6lkk,2020-12-02,2019-12-19
-4lk3,2013-08-07,2013-07-05
-3lka,2010-05-12,2010-01-27
-7lkk,2021-06-23,2021-02-02
-5lku,2016-11-02,2016-07-25
-1lke,2003-06-17,2002-04-25
-7lku,2021-02-17,2021-02-02
-3lkv,2010-03-02,2010-01-27
-6lkn,2020-06-10,2019-12-19
-3lkh,2010-03-23,2010-01-27
-6lkh,2021-03-17,2019-12-19
-3lk1,2010-12-29,2010-01-26
-1lkp,2002-09-18,2002-04-25
-5lkj,2017-08-16,2016-07-22
-3lkb,2010-02-09,2010-01-27
-3lk8,2010-10-06,2010-01-27
-1lko,2002-09-18,2002-04-25
-4lk2,2013-12-11,2013-07-05
-6lkc,2020-12-23,2019-12-19
-7lkr,2021-02-17,2021-02-02
-1lkc,2002-05-01,2002-04-24
-3lk0,2010-12-29,2010-01-26
-1lk6,2003-06-03,2002-04-24
-4lko,2013-09-04,2013-07-08
-1lkl,1996-03-08,1995-11-10
-2lk6,2012-01-25,2011-10-07
-6lko,2020-10-07,2019-12-19
-3lkf,1999-07-28,1998-07-28
-3lk6,2011-05-25,2010-01-27
-4lkk,2013-11-06,2013-07-07
-5lkv,2017-08-16,2016-07-25
-5lkd,2016-10-26,2016-07-22
-1lkm,2002-09-18,2002-04-25
-4lkx,2014-01-29,2013-07-09
-1lk5,2002-07-03,2002-04-24
-2lk1,2011-12-28,2011-09-30
-7lkx,2021-02-17,2021-02-02
-3lkr,2010-07-07,2010-01-27
-5lkm,2017-06-07,2016-07-22
-7lkf,2021-06-30,2021-02-02
-6lka,2020-06-17,2019-12-18
-7lkz,2021-03-03,2021-02-03
-1nt0,2003-05-20,2003-01-28
-6nt2,2019-07-10,2019-01-28
-7nto,2022-01-19,2021-03-10
-7nti,2021-04-07,2021-03-09
-3nth,2010-09-15,2010-07-05
-6nt1,2019-05-01,2019-01-27
-7ntl,2021-08-11,2021-03-10
-7ntc,2021-04-28,2021-03-09
-2nty,2007-01-23,2006-11-08
-7nty,2022-08-31,2021-03-11
-7nt1,2021-06-16,2021-03-08
-3ntm,2010-11-17,2010-07-05
-1ntp,1988-01-16,1987-09-16
-2nt9,2007-09-18,2006-11-07
-1nto,2003-08-26,2003-01-30
-5ntj,2018-05-30,2017-04-28
-5nt4,2018-03-07,2017-04-27
-1nt5,2003-02-11,2003-01-28
-2nt7,2007-04-17,2006-11-07
-6ntd,2020-03-04,2019-01-28
-4ntr,2014-04-02,2013-12-02
-5ntc,2018-05-30,2017-04-27
-4ntx,2014-02-19,2013-12-02
-3nti,2010-09-15,2010-07-05
-4ntl,2013-12-11,2013-12-02
-7nt2,2021-06-16,2021-03-08
-4ntd,2014-03-05,2013-12-02
-6ntb,2019-09-18,2019-01-28
-3ntn,2011-07-06,2010-07-05
-7ntn,2022-01-19,2021-03-10
-6ntc,2020-03-04,2019-01-28
-6ntp,2020-01-22,2019-01-30
-6nt8,2019-03-06,2019-01-28
-4ntj,2014-03-26,2013-12-02
-6ntn,2020-07-01,2019-01-29
-2nt1,2006-12-26,2006-11-06
-6ntj,2019-09-25,2019-01-29
-3ntg,2010-10-27,2010-07-04
-7ntk,2021-06-16,2021-03-10
-5nti,2017-06-21,2017-04-28
-6nta,2020-10-14,2019-01-28
-7ntg,2021-08-18,2021-03-09
-6nt0,2019-05-01,2019-01-27
-3nt4,2010-09-15,2010-07-02
-7nt3,2021-06-16,2021-03-08
-2ntr,2007-11-13,2006-11-08
-4ntb,2015-01-14,2013-12-02
-1nt2,2003-04-01,2003-01-28
-6ntl,2020-07-01,2019-01-29
-3nt0,2011-08-17,2010-07-02
-4nte,2014-03-05,2013-12-02
-6ntm,2020-07-29,2019-01-29
-1ntd,1996-11-08,1995-07-03
-4nty,2014-02-19,2013-12-02
-2ntw,2006-12-26,2006-11-08
-2ntb,2007-09-18,2006-11-07
-4nt1,2014-02-05,2013-11-29
-5nth,2017-08-02,2017-04-27
-1nt4,2004-01-13,2003-01-28
-5ntn,2017-06-21,2017-04-28
-4nt6,2014-07-23,2013-12-01
-2nto,2007-09-25,2006-11-08
-2ntk,2007-04-24,2006-11-07
-7ntd,2021-10-06,2021-03-09
-6ntk,2020-07-01,2019-01-29
-3ntp,2012-01-04,2010-07-05
-6nto,2020-07-01,2019-01-29
-3nte,2010-12-01,2010-07-03
-7ntu,2021-04-28,2021-03-10
-3ntb,2010-09-01,2010-07-03
-3nt6,2010-12-08,2010-07-02
-7ntb,2022-03-16,2021-03-09
-2nth,2007-06-12,2006-11-07
-6nt7,2019-03-06,2019-01-28
-2nt8,2006-11-21,2006-11-07
-5ntw,2017-06-21,2017-04-28
-3nta,2010-12-08,2010-07-03
-4ntc,2014-03-05,2013-12-02
-7ntt,2022-03-02,2021-03-10
-7ntj,2021-06-16,2021-03-10
-2nta,2007-04-17,2006-11-07
-7ntq,2022-03-02,2021-03-10
-7nth,2021-04-07,2021-03-09
-2ntj,2007-01-30,2006-11-07
-6ntu,2020-02-05,2019-01-30
-2ntp,2007-09-18,2006-11-08
-4ntp,2014-04-02,2013-12-02
-2nti,2007-12-18,2006-11-07
-6nth,2020-07-01,2019-01-29
-6nts,2020-05-06,2019-01-30
-6nti,2019-09-25,2019-01-29
-4nt9,2014-11-12,2013-12-02
-4ntk,2014-07-16,2013-12-02
-1nt1,2003-09-02,2003-01-28
-4nt5,2014-01-01,2013-12-01
-5ntd,2017-08-02,2017-04-27
-6ntf,2019-09-18,2019-01-29
-5ntg,2017-08-02,2017-04-27
-4nt0,2013-12-18,2013-11-29
-7nta,2021-04-28,2021-03-09
-3ntd,2010-12-08,2010-07-03
-7ntv,2021-06-16,2021-03-10
-5ntp,2017-06-21,2017-04-28
-3ntz,2011-05-25,2010-07-06
-4nt8,2014-12-03,2013-12-02
-5ntt,2017-07-26,2017-04-28
-3nty,2011-04-13,2010-07-06
-6ntg,2020-07-01,2019-01-29
-4ntf,2015-01-14,2013-12-02
-7ntm,2022-10-12,2021-03-10
-7ntz,2022-08-31,2021-03-11
-1ntk,2003-10-07,2003-01-30
-6ntw,2019-03-20,2019-01-30
-6ntt,2019-03-20,2019-01-30
-1nt6,2003-02-11,2003-01-28
-7nt0,2021-05-19,2021-03-08
-2ntv,2007-01-30,2006-11-08
-3ntu,2011-07-27,2010-07-05
-3ntr,2010-09-15,2010-07-05
-3nt1,2010-09-01,2010-07-02
-4ntt,2014-10-15,2013-12-02
-2ntq,2007-09-18,2006-11-08
-6ntz,2019-03-20,2019-01-30
-1ntm,2003-10-07,2003-01-30
-7ntw,2022-03-02,2021-03-11
-2ntl,2007-04-24,2006-11-07
-6nt3,2019-02-20,2019-01-28
-4ntw,2014-02-19,2013-12-02
-2nt6,2007-09-18,2006-11-07
-5nt0,2018-03-07,2017-04-27
-1ntv,2003-04-15,2003-01-30
-3ntl,2011-07-27,2010-07-05
-4ntm,2014-07-16,2013-12-02
-5ntq,2017-06-21,2017-04-28
-7nt4,2022-02-02,2021-03-09
-6nt9,2019-03-06,2019-01-28
-1ntz,2003-10-07,2003-01-30
-7nte,2021-10-06,2021-03-09
-7ntr,2022-09-21,2021-03-10
-2ntg,2007-06-12,2006-11-07
-3ntq,2010-09-15,2010-07-05
-3nt2,2010-09-15,2010-07-02
-5ntk,2017-06-21,2017-04-28
-2ntf,2007-05-08,2006-11-07
-7nt9,2021-04-28,2021-03-09
-3nt5,2010-09-15,2010-07-02
-3ntt,2011-12-07,2010-07-05
-2nt0,2006-12-26,2006-11-06
-6nt4,2019-02-20,2019-01-28
-4ntn,2014-07-16,2013-12-02
-1ntf,2004-03-16,2003-01-29
-2ntu,2006-12-26,2006-11-08
-3tj9,2011-11-02,2011-08-24
-7tj5,2022-10-26,2022-01-14
-3tjd,2011-11-30,2011-08-24
-5tjx,2016-12-21,2016-10-05
-8tj4,2024-02-14,2023-07-20
-1tj3,2005-06-14,2004-06-03
-6tjw,2020-10-21,2019-11-27
-1tjm,2004-09-28,2004-06-06
-1tj1,2004-10-26,2004-06-03
-3tju,2011-12-28,2011-08-25
-8tja,2024-02-14,2023-07-20
-7tjv,2022-04-20,2022-01-17
-1tjp,2005-12-27,2004-06-07
-5tj2,2017-02-01,2016-10-03
-8tjj,2023-12-13,2023-07-22
-3tje,2012-05-09,2011-08-24
-8tjk,2023-12-13,2023-07-22
-6tj9,2020-07-08,2019-11-25
-3tjc,2011-11-30,2011-08-24
-8tj6,2024-02-14,2023-07-20
-7tj8,2022-03-30,2022-01-14
-7tjf,2023-01-18,2022-01-16
-6tjy,2020-10-21,2019-11-27
-1tjg,2004-10-05,2004-06-04
-6tjq,2020-06-10,2019-11-26
-5tj7,2017-05-31,2016-10-03
-5tj4,2017-02-01,2016-10-03
-1tjk,2004-06-15,2004-06-06
-6tj0,2020-07-29,2019-11-23
-5tj9,2016-10-19,2016-10-04
-7tjo,2023-01-25,2022-01-16
-7tjh,2022-10-05,2022-01-16
-1tj2,2004-10-26,2004-06-03
-5tjh,2016-11-02,2016-10-04
-6tjt,2020-12-16,2019-11-26
-7tjs,2022-04-20,2022-01-17
-7tjc,2022-11-23,2022-01-16
-7tj0,2022-05-04,2022-01-14
-6tjv,2020-02-19,2019-11-27
-8tjb,2024-02-14,2023-07-20
-3tjs,2012-03-07,2011-08-24
-7tjq,2022-09-14,2022-01-16
-5tjo,2017-06-14,2016-10-04
-3tji,2011-09-14,2011-08-24
-6tj1,2020-04-29,2019-11-23
-7tji,2022-10-05,2022-01-16
-5tje,2017-11-01,2016-10-04
-3tj8,2011-11-02,2011-08-24
-4tjw,2014-10-15,2014-05-25
-7tja,2022-04-20,2022-01-15
-5tjz,2018-01-10,2016-10-05
-6tjj,2020-06-10,2019-11-26
-1tjb,2004-08-03,2004-06-03
-4tju,2014-10-15,2014-05-25
-3tjq,2012-05-16,2011-08-24
-7tj6,2022-10-26,2022-01-14
-7tjx,2022-04-20,2022-01-17
-5tj3,2016-11-16,2016-10-03
-6tjl,2020-12-09,2019-11-26
-5tj6,2016-12-14,2016-10-03
-1tjo,2004-10-19,2004-06-07
-6tjn,2020-12-16,2019-11-26
-5tjk,2017-06-14,2016-10-04
-7tj9,2022-03-30,2022-01-14
-6tj8,2020-07-08,2019-11-25
-5tj8,2017-06-07,2016-10-03
-6tj7,2020-10-21,2019-11-25
-7tj4,2022-07-06,2022-01-14
-8tj7,2024-02-14,2023-07-20
-3tjv,2011-12-28,2011-08-25
-5tjg,2017-06-21,2016-10-04
-4tjy,2014-10-15,2014-05-25
-3tjh,2011-12-07,2011-08-24
-1tj9,2004-06-08,2004-06-03
-8tje,2023-08-23,2023-07-20
-8tj0,2023-08-02,2023-07-20
-6tjk,2020-06-10,2019-11-26
-7tjj,2022-10-05,2022-01-16
-1tj4,2005-06-14,2004-06-03
-7tj1,2022-01-26,2022-01-14
-1tjw,2004-09-07,2004-06-07
-7tjp,2023-01-25,2022-01-16
-3tj2,2012-09-12,2011-08-23
-5tjy,2017-10-18,2016-10-05
-8tj8,2024-02-14,2023-07-20
-5tjn,2017-06-14,2016-10-04
-3tj7,2011-08-31,2011-08-23
-5tjr,2017-01-11,2016-10-05
-8tj9,2024-02-14,2023-07-20
-7tju,2022-04-20,2022-01-17
-1tjl,2004-09-07,2004-06-06
-3tjx,2012-09-12,2011-08-25
-8tjl,2024-02-14,2023-07-22
-1tj5,2005-06-14,2004-06-03
-3tjl,2012-07-11,2011-08-24
-7tjt,2022-04-20,2022-01-17
-3tjt,2012-08-29,2011-08-25
-6tj5,2020-10-21,2019-11-25
-7tjk,2022-10-05,2022-01-16
-3tjz,2012-02-22,2011-08-25
-1tjx,2004-11-23,2004-06-07
-7tj3,2022-11-23,2022-01-14
-1tjy,2004-09-28,2004-06-07
-5tjl,2017-06-14,2016-10-04
-3tjp,2012-08-29,2011-08-24
-6tjr,2020-08-19,2019-11-26
-5tjf,2017-05-24,2016-10-04
-7tjw,2022-04-20,2022-01-17
-4tjx,2014-12-10,2014-05-25
-6tjm,2020-04-29,2019-11-26
-8tjc,2023-12-06,2023-07-20
-8tjg,2024-03-06,2023-07-21
-8tj1,2023-08-02,2023-07-20
-1tj0,2004-10-26,2004-06-02
-1gqw,2002-04-18,2001-12-05
-4gqi,2013-07-10,2012-08-23
-3gq3,2009-11-10,2009-03-23
-7gq0,2023-11-29,2023-08-24
-6gqu,2018-10-03,2018-06-08
-2gql,2006-06-06,2006-04-21
-8gqd,2024-03-06,2022-08-30
-7gqk,2023-11-29,2023-08-24
-6gql,2018-09-19,2018-06-07
-3gqc,2009-05-19,2009-03-24
-4gqe,2013-05-15,2012-08-22
-2gqe,2007-04-10,2006-04-20
-7gq6,2023-11-29,2023-08-24
-2gqn,2007-03-06,2006-04-21
-7gqp,2023-11-29,2023-08-24
-1gql,2002-09-26,2001-11-26
-7gqh,2023-11-29,2023-08-24
-4gqk,2013-09-25,2012-08-23
-6gq1,2018-07-11,2018-06-07
-1gq7,2002-06-06,2001-11-20
-6gqn,2019-01-23,2018-06-07
-4gqb,2012-10-17,2012-08-22
-6gqc,2019-06-19,2018-06-07
-8gqb,2023-06-21,2022-08-29
-2gqg,2006-11-21,2006-04-20
-7gqe,2023-11-29,2023-08-24
-7gq7,2023-11-29,2023-08-24
-7gq9,2023-11-29,2023-08-24
-1gqa,2002-12-19,2001-11-22
-5gqm,2017-02-15,2016-08-07
-6gqp,2018-09-19,2018-06-07
-2gqk,2006-06-06,2006-04-21
-5gqq,2016-11-02,2016-08-08
-5gqw,2017-02-22,2016-08-08
-5gqe,2017-08-09,2016-08-07
-1gqs,2002-03-15,2001-12-04
-7gq2,2023-11-29,2023-08-24
-2gqw,2007-05-22,2006-04-22
-6gqi,2018-12-12,2018-06-07
-3gq1,2009-05-05,2009-03-23
-3gq9,2009-05-26,2009-03-24
-4gql,2013-02-06,2012-08-23
-2gqm,2006-06-06,2006-04-21
-3gqg,2009-10-13,2009-03-24
-1gqt,2002-01-28,2001-12-05
-6gqq,2018-09-19,2018-06-07
-1gq6,2002-06-06,2001-11-20
-7gq1,2023-11-29,2023-08-24
-6gqb,2018-07-11,2018-06-07
-2gq3,2006-08-15,2006-04-19
-6gq6,2018-10-03,2018-06-07
-7gqj,2023-11-29,2023-08-24
-3gqp,2010-03-02,2009-03-24
-5gqj,2017-02-15,2016-08-07
-8gqw,2023-01-11,2022-08-31
-7gql,2023-11-29,2023-08-24
-6gq4,2018-09-19,2018-06-07
-6gqs,2018-10-03,2018-06-08
-5gq9,2017-08-09,2016-08-06
-2gqp,2007-04-03,2006-04-21
-6gqv,2018-07-11,2018-06-08
-5gqd,2017-08-09,2016-08-07
-3gqt,2009-04-28,2009-03-24
-2gq9,2006-07-25,2006-04-20
-2gqs,2006-05-16,2006-04-21
-7gqd,2023-11-29,2023-08-24
-3gqz,2009-04-14,2009-03-24
-4gq7,2013-01-16,2012-08-22
-5gqi,2017-02-15,2016-08-07
-7gqg,2023-11-29,2023-08-24
-1gq2,2002-05-23,2001-11-19
-4gqu,2013-08-28,2012-08-24
-7gqb,2023-11-29,2023-08-24
-1gqg,2002-06-21,2001-11-23
-4gq0,2013-08-28,2012-08-22
-1gqm,2002-02-28,2001-11-26
-7gqa,2023-11-29,2023-08-24
-8gqz,2023-04-26,2022-08-31
-8gqn,2024-03-13,2022-08-30
-8gqp,2023-09-13,2022-08-30
-5gqu,2017-02-22,2016-08-08
-8gqm,2024-03-13,2022-08-30
-7gqq,2023-11-29,2023-08-24
-3gq8,2009-05-26,2009-03-24
-5gql,2017-02-15,2016-08-07
-4gqp,2013-10-02,2012-08-23
-6gqd,2018-07-18,2018-06-07
-3gql,2009-08-18,2009-03-24
-5gqc,2017-04-19,2016-08-07
-5gqz,2017-08-16,2016-08-08
-7gqn,2023-11-29,2023-08-24
-4gqg,2013-08-28,2012-08-23
-6gq3,2019-09-18,2018-06-07
-3gqo,2009-07-21,2009-03-24
-7gq5,2023-11-29,2023-08-24
-8gq0,2023-01-18,2022-08-27
-6gqx,2019-02-06,2018-06-08
-3gqk,2009-05-26,2009-03-24
-5gqg,2017-04-19,2016-08-07
-7gqc,2023-11-29,2023-08-24
-7gqu,2024-05-01,2023-10-19
-7gqf,2023-11-29,2023-08-24
-2gqt,2006-12-19,2006-04-21
-4gqt,2012-09-05,2012-08-23
-7gqi,2023-11-29,2023-08-24
-3gqa,2009-05-26,2009-03-24
-7gqo,2023-11-29,2023-08-24
-3gq7,2009-05-26,2009-03-24
-1gqy,2003-06-13,2001-12-06
-1gqh,2002-06-21,2001-11-23
-6gqm,2018-09-19,2018-06-07
-2gq8,2006-07-25,2006-04-20
-1gqk,2002-09-26,2001-11-26
-8gq9,2023-06-21,2022-08-29
-5gq1,2017-05-17,2016-08-05
-4gqy,2013-07-24,2012-08-24
-3gqr,2010-03-02,2009-03-24
-1gq9,2002-02-11,2001-11-21
-6gq7,2018-06-20,2018-06-07
-7gqs,2024-05-01,2023-10-19
-6gqk,2018-09-19,2018-06-07
-2gqu,2006-12-19,2006-04-21
-7gq3,2023-11-29,2023-08-24
-1gq1,2002-11-28,2001-11-19
-7gq8,2023-11-29,2023-08-24
-6gq8,2018-06-20,2018-06-07
-2gq2,2006-06-27,2006-04-19
-3gq4,2009-11-10,2009-03-23
-2gqf,2006-05-30,2006-04-20
-1gqr,2002-03-15,2001-12-04
-4gqn,2014-03-12,2012-08-23
-5gqx,2017-02-22,2016-08-08
-4gqs,2012-11-14,2012-08-23
-5gqr,2016-12-14,2016-08-08
-8gqt,2023-08-30,2022-08-30
-6gqy,2019-02-06,2018-06-08
-3gq5,2009-11-10,2009-03-23
-7gq4,2023-11-29,2023-08-24
-3gqf,2009-04-07,2009-03-24
-8gqa,2023-06-21,2022-08-29
-1gqc,2002-02-11,2001-11-21
-6gqw,2019-02-06,2018-06-08
-5gqf,2017-04-19,2016-08-07
-7gqm,2023-11-29,2023-08-24
-1gqi,2002-09-26,2001-11-26
-6gqh,2018-12-19,2018-06-07
-8gqv,2023-01-11,2022-08-31
-2gqj,2006-10-21,2006-04-21
-3gqi,2009-08-18,2009-03-24
-2gqx,2007-04-17,2006-04-22
-7gqr,2023-11-29,2023-08-24
-6gqr,2018-10-03,2018-06-08
-8gq6,2023-09-06,2022-08-29
-5gqy,2017-08-16,2016-08-08
-6gqo,2018-09-19,2018-06-07
-5gqb,2017-01-11,2016-08-06
-5gqo,2016-10-12,2016-08-08
-4gqq,2012-10-24,2012-08-23
-8gqr,2023-03-29,2022-08-30
-5gqv,2017-02-22,2016-08-08
-6gqj,2018-09-19,2018-06-07
-6gqf,2018-09-26,2018-06-07
-1gqj,2002-09-26,2001-11-26
-7gqt,2024-05-01,2023-10-19
-6gqt,2019-02-06,2018-06-08
-4gqr,2012-10-24,2012-08-23
-2gqr,2006-05-16,2006-04-21
-3gqv,2009-04-07,2009-03-24
-3gqy,2009-04-07,2009-03-24
-8gqu,2023-07-05,2022-08-30
-6gqg,2018-12-19,2018-06-07
-2gqa,2006-07-25,2006-04-20
-7yyw,2023-02-22,2022-02-18
-5yye,2018-09-05,2017-12-08
-1yyr,2005-03-29,2005-02-25
-2yyx,2008-05-06,2007-05-02
-7yy9,2022-06-29,2022-02-17
-6yyt,2020-05-13,2020-05-06
-4yya,2016-04-13,2015-03-23
-1yyl,2005-05-03,2005-02-25
-1yy9,2005-04-26,2005-02-24
-6yyc,2021-05-12,2020-05-04
-2yyl,2007-09-04,2007-04-30
-2yyy,2007-11-06,2007-05-02
-5yyd,2018-09-05,2017-12-08
-5yy6,2019-01-16,2017-12-08
-4yy1,2016-03-23,2015-03-23
-7yyy,2023-02-22,2022-02-18
-7yy4,2022-06-29,2022-02-17
-6yy5,2020-07-29,2020-05-04
-7yyp,2022-06-29,2022-02-18
-5yyl,2018-08-08,2017-12-10
-6yyb,2021-05-12,2020-05-04
-5yyc,2019-01-02,2017-12-08
-1yyy,1999-06-08,1998-06-03
-1yyg,2005-05-10,2005-02-24
-1yyn,2005-03-15,2005-02-25
-7yy5,2022-06-29,2022-02-17
-5yy5,2018-08-01,2017-12-08
-4yyj,2015-09-16,2015-03-23
-6yy7,2021-05-12,2020-05-04
-2yy2,2007-10-30,2007-04-27
-6yyg,2021-05-12,2020-05-05
-4yyo,2016-06-01,2015-03-24
-6yy9,2021-05-12,2020-05-04
-5yy7,2019-01-16,2017-12-08
-7yyg,2023-03-01,2022-02-17
-2yy7,2008-04-29,2007-04-27
-6yyw,2021-03-17,2020-05-06
-4yy2,2015-12-16,2015-03-23
-7yyc,2022-06-29,2022-02-17
-2yy5,2008-04-29,2007-04-27
-5yyb,2018-10-24,2017-12-08
-6yys,2020-11-04,2020-05-05
-2yy1,2008-04-29,2007-04-27
-6yyz,2020-05-13,2020-05-06
-6yyy,2021-03-17,2020-05-06
-2yye,2008-04-29,2007-04-29
-7yy3,2022-06-29,2022-02-17
-1yyf,2005-07-12,2005-02-24
-6yyk,2021-05-12,2020-05-05
-4yye,2016-01-06,2015-03-23
-4yyl,2015-04-29,2015-03-24
-4yyi,2015-09-16,2015-03-23
-1yyu,2005-03-29,2005-02-25
-2yyu,2007-11-06,2007-05-02
-4yyz,2016-02-03,2015-03-24
-7yy6,2022-06-29,2022-02-17
-1yyd,2005-05-10,2005-02-24
-6yy8,2021-05-12,2020-05-04
-4yyf,2015-04-08,2015-03-23
-6yyn,2021-05-12,2020-05-05
-6yyu,2021-03-17,2020-05-06
-6yye,2021-02-17,2020-05-04
-7yyo,2023-01-25,2022-02-18
-6yy0,2020-09-09,2020-05-04
-7yya,2022-06-29,2022-02-17
-1yy4,2006-02-28,2005-02-23
-2yy8,2008-03-18,2007-04-27
-6yyi,2020-12-02,2020-05-05
-2yyi,2007-09-04,2007-04-30
-7yy0,2022-06-29,2022-02-17
-4yyk,2015-09-16,2015-03-24
-6yyq,2021-05-12,2020-05-05
-4yy9,2016-04-13,2015-03-23
-6yyf,2021-05-12,2020-05-05
-5yy1,2018-04-18,2017-12-07
-6yyj,2021-01-20,2020-05-05
-7yyv,2023-02-22,2022-02-18
-4yyy,2016-03-09,2015-03-24
-7yy7,2022-06-29,2022-02-17
-5yy4,2018-07-18,2017-12-07
-6yya,2021-05-12,2020-05-04
-6yyo,2021-05-12,2020-05-05
-1yys,2005-03-29,2005-02-25
-1yyq,2005-03-29,2005-02-25
-6yyd,2021-05-12,2020-05-04
-7yyz,2023-02-22,2022-02-18
-4yy7,2016-03-23,2015-03-23
-4yy3,2016-07-06,2015-03-23
-4yym,2015-09-16,2015-03-24
-7yyb,2022-06-29,2022-02-17
-4yy0,2016-03-23,2015-03-23
-5yyf,2018-11-07,2017-12-09
-6yyv,2021-03-17,2020-05-06
-6yyx,2021-03-17,2020-05-06
-7yy8,2022-06-29,2022-02-17
-7yy1,2022-06-29,2022-02-17
-2yyk,2007-09-04,2007-04-30
-6yyp,2021-05-12,2020-05-05
-8yyo,2024-04-17,2024-04-04
-5yy0,2018-06-20,2017-12-07
-7yyk,2022-05-25,2022-02-18
-6yyr,2021-05-12,2020-05-05
-1yyt,2005-03-29,2005-02-25
-7yyq,2023-02-22,2022-02-18
-1yyz,2005-03-15,2005-02-25
-4yyt,2016-02-03,2015-03-24
-1yy5,2005-03-08,2005-02-23
-4yyg,2015-09-16,2015-03-23
-7yyx,,2022-02-18
-2yyj,2007-09-04,2007-04-30
-5yym,2018-12-12,2017-12-10
-6yy3,2020-09-30,2020-05-04
-1yy6,2005-04-05,2005-02-23
-6yy6,2021-05-12,2020-05-04
-2yym,2007-09-04,2007-04-30
-8yyn,2024-04-17,2024-04-04
-2yyr,2008-05-06,2007-05-01
-2yyw,2008-05-06,2007-05-02
-7yy2,2022-06-29,2022-02-17
-5yy2,2018-08-01,2017-12-07
-1yya,2005-03-15,2005-02-24
-1yym,2005-05-03,2005-02-25
-1yye,2006-02-28,2005-02-24
-4yyh,2015-09-16,2015-03-23
-4yyb,2016-04-13,2015-03-23
-5f79,2016-12-07,2015-12-07
-7f7r,2021-12-08,2021-06-30
-7f7f,2022-03-23,2021-06-29
-6f79,2018-08-15,2017-12-07
-2f7n,2006-11-14,2005-12-01
-5f7x,2016-12-14,2015-12-08
-3f7v,2010-05-19,2008-11-10
-7f7g,2022-02-23,2021-06-29
-4f7e,2012-11-14,2012-05-15
-7f7b,2022-07-06,2021-06-28
-7f7a,2022-07-06,2021-06-28
-7f7l,2022-07-06,2021-06-30
-1f7n,2000-09-06,2000-06-27
-8f78,2023-12-13,2022-11-18
-6f7r,2019-03-13,2017-12-11
-5f76,2016-12-14,2015-12-07
-6f75,2018-08-15,2017-12-07
-8f73,2023-11-29,2022-11-17
-6f72,2018-01-10,2017-12-07
-5f7n,2016-01-20,2015-12-08
-2f71,2005-12-13,2005-11-29
-5f7u,2016-09-21,2015-12-08
-8f7u,2023-02-08,2022-11-20
-6f76,2018-08-08,2017-12-07
-2f7r,2006-12-12,2005-12-01
-7f7y,2022-06-01,2021-06-30
-6f7g,2018-12-19,2017-12-08
-3f7z,2009-03-10,2008-11-10
-8f7o,2023-04-12,2022-11-20
-3f7j,2008-11-25,2008-11-09
-3f7i,2009-03-17,2008-11-09
-5f7r,2016-09-07,2015-12-08
-3f7y,2010-05-19,2008-11-10
-8f7m,2024-06-05,2022-11-18
-5f7w,2016-01-20,2015-12-08
-6f73,2018-01-10,2017-12-07
-7f7j,2022-07-06,2021-06-30
-2f74,2006-02-14,2005-11-30
-6f7k,2018-12-19,2017-12-11
-2f7a,2006-10-31,2005-11-30
-7f75,2021-10-13,2021-06-28
-3f7l,2009-02-10,2008-11-09
-3f78,2009-06-23,2008-11-07
-8f71,2023-11-22,2022-11-17
-2f7e,2006-06-27,2005-11-30
-8f7v,2023-02-08,2022-11-20
-2f7z,2006-06-27,2005-12-01
-5f7g,2016-12-14,2015-12-08
-4f75,2013-05-15,2012-05-15
-5f75,2016-12-14,2015-12-07
-2f70,2005-12-13,2005-11-29
-1f7z,2001-07-04,2000-06-28
-4f7a,2012-05-30,2012-05-15
-3f70,2009-01-06,2008-11-07
-7f7m,2022-07-06,2021-06-30
-3f7g,2009-03-17,2008-11-09
-5f77,2016-12-14,2015-12-07
-1f7d,2000-09-06,2000-06-26
-6f7b,2018-12-19,2017-12-08
-1f7p,2000-09-06,2000-06-27
-3f7p,2009-03-10,2008-11-10
-6f7l,2018-09-19,2017-12-11
-7f7c,2022-07-06,2021-06-28
-6f7v,2018-09-19,2017-12-12
-4f76,2013-05-15,2012-05-15
-4f7x,2012-06-13,2012-05-16
-4f73,2013-05-15,2012-05-15
-1f74,2000-11-22,2000-06-26
-7f71,2022-05-11,2021-06-26
-7f7o,2022-07-06,2021-06-30
-5f7p,2016-09-07,2015-12-08
-1f7u,2001-06-27,2000-06-28
-1f7k,2000-09-06,2000-06-27
-8f7w,2022-12-14,2022-11-20
-6f71,2018-06-06,2017-12-07
-8f7l,2023-11-29,2022-11-18
-8f7a,2023-07-26,2022-11-18
-4f7n,2013-05-01,2012-05-16
-6f7f,2019-03-27,2017-12-08
-8f72,2023-12-20,2022-11-17
-4f71,2012-06-20,2012-05-15
-4f78,2012-05-23,2012-05-15
-5f7y,2016-01-20,2015-12-08
-2f7d,2006-03-07,2005-11-30
-2f7t,2006-03-28,2005-12-01
-3f7c,2008-11-25,2008-11-07
-4f7c,2012-11-14,2012-05-15
-5f7a,2016-03-16,2015-12-07
-7f7i,2022-04-06,2021-06-29
-4f7l,2013-05-01,2012-05-16
-6f78,2018-04-04,2017-12-07
-7f72,2022-07-13,2021-06-27
-8f7p,2023-04-12,2022-11-20
-3f72,2009-04-07,2008-11-07
-4f7o,2013-01-23,2012-05-16
-5f7d,2016-12-21,2015-12-07
-8f70,2023-03-08,2022-11-17
-2f7c,2006-10-31,2005-11-30
-4f7v,2012-07-11,2012-05-16
-4f7t,2012-10-10,2012-05-16
-7f7q,2021-12-08,2021-06-30
-2f7p,2006-07-04,2005-12-01
-1f7l,2001-06-27,2000-06-27
-6f7q,2018-09-05,2017-12-11
-4f7s,2013-05-01,2012-05-16
-2f7o,2006-07-04,2005-12-01
-7f76,2022-05-11,2021-06-28
-8f7q,2022-12-14,2022-11-20
-8f7k,2023-08-30,2022-11-18
-9f7h,2024-05-15,2024-05-03
-2f7i,2005-12-13,2005-11-30
-6f7x,2018-05-30,2017-12-12
-5f7m,2016-01-20,2015-12-08
-5f74,2016-03-23,2015-12-07
-6f74,2018-01-10,2017-12-07
-2f7s,2005-12-20,2005-12-01
-3f79,2009-11-24,2008-11-07
-7f74,2022-06-29,2021-06-27
-5f7q,2016-09-07,2015-12-08
-3f7k,2009-02-10,2008-11-09
-6f7t,2018-10-31,2017-12-11
-4f72,2012-06-20,2012-05-15
-1f7r,2000-09-06,2000-06-27
-6f7i,2019-01-02,2017-12-09
-3f7b,2009-09-22,2008-11-07
-5f7o,2016-12-14,2015-12-08
-1f73,2000-11-22,2000-06-25
-8f7r,2022-12-14,2022-11-20
-1f7b,2000-11-22,2000-06-26
-1f7y,2000-11-22,2000-06-28
-9f7f,2024-05-15,2024-05-03
-3f7n,2009-09-22,2008-11-09
-6f7w,2018-05-30,2017-12-12
-2f7f,2005-12-13,2005-11-30
-4f74,2013-05-15,2012-05-15
-4f7b,2013-10-09,2012-05-15
-2f7v,2006-09-26,2005-12-01
-3f7f,2009-08-18,2008-11-08
-3f74,2009-06-23,2008-11-07
-7f79,2021-07-21,2021-06-28
-1f7q,2000-09-06,2000-06-27
-3f7o,2009-11-17,2008-11-10
-5f7t,2016-06-15,2015-12-08
-6f70,2018-06-06,2017-12-07
-3f7u,2009-09-22,2008-11-10
-8f7n,2023-07-05,2022-11-19
-7f7e,2022-02-02,2021-06-29
-2f7q,2006-12-12,2005-12-01
-4f7j,2013-05-01,2012-05-16
-7f7k,2022-07-06,2021-06-30
-4f79,2012-06-13,2012-05-15
-5f7v,2016-09-07,2015-12-08
-2f7x,2006-06-27,2005-12-01
-5f7j,2016-12-14,2015-12-08
-7f7w,2022-03-30,2021-06-30
-5f7h,2016-02-03,2015-12-08
-6f7u,2018-03-14,2017-12-12
-1f7t,2001-06-27,2000-06-27
-5f7s,2015-12-30,2015-12-08
-4f7p,2012-10-10,2012-05-16
-3f7h,2009-03-17,2008-11-09
-1f7a,2001-06-27,2000-06-26
-5f7k,2016-01-20,2015-12-08
-7f7d,2022-07-06,2021-06-28
-1f76,2002-10-16,2000-06-26
-3f73,2008-12-16,2008-11-07
-6f7c,2018-12-19,2017-12-08
-5f7b,2016-03-16,2015-12-07
-8f7s,2022-12-14,2022-11-20
-4f7i,2012-06-13,2012-05-16
-8f7t,2023-09-27,2022-11-20
-5f71,2016-02-03,2015-12-07
-4f70,2013-05-01,2012-05-15
-8f7z,2023-11-01,2022-11-21
-6f77,2019-03-13,2017-12-07
-3hyk,2009-06-30,2009-06-22
-4hy4,2013-01-30,2012-11-12
-3hyf,2009-10-20,2009-06-22
-4hyt,2013-06-26,2012-11-14
-3hyw,2009-07-14,2009-06-23
-1hyb,2001-03-14,2001-01-18
-3hyz,2010-07-14,2009-06-23
-3hy0,2009-12-15,2009-06-22
-6hy8,2019-10-30,2018-10-19
-4hy1,2013-02-13,2012-11-12
-3hyy,2010-07-14,2009-06-23
-4hyp,2013-02-13,2012-11-13
-6hyx,2018-12-19,2018-10-22
-3hyv,2009-07-14,2009-06-23
-8hyj,2023-06-21,2023-01-06
-3hys,2010-06-02,2009-06-23
-8hyi,2023-08-30,2023-01-06
-5hyf,2017-02-01,2016-02-01
-5hy9,2017-02-01,2016-02-01
-1hye,2001-04-18,2001-01-19
-2hyo,2006-12-26,2006-08-07
-6hy3,2019-03-13,2018-10-19
-6hyc,2019-06-05,2018-10-19
-5hy1,2017-02-01,2016-02-01
-8hy5,2023-01-25,2023-01-05
-3hyx,2009-07-14,2009-06-23
-3hyc,2009-09-01,2009-06-22
-2hyw,2006-09-05,2006-08-07
-5hy7,2016-10-26,2016-02-01
-3hy7,2009-07-07,2009-06-22
-6hyg,2019-03-13,2018-10-21
-4hy2,2013-04-03,2012-11-12
-1hyh,1995-10-15,1995-06-05
-6hyz,2018-12-19,2018-10-22
-5hym,2017-02-01,2016-02-01
-1hy2,2003-06-17,2001-01-17
-2hys,2006-10-24,2006-08-07
-8hy1,2023-11-01,2023-01-05
-5hyq,2016-06-15,2016-02-01
-4hys,2013-10-30,2012-11-14
-3hyo,2009-06-30,2009-06-22
-2hyz,2008-02-19,2006-08-08
-3hy5,2009-10-20,2009-06-22
-3hy9,2009-07-07,2009-06-22
-6hy2,2019-01-23,2018-10-19
-3hyj,2009-09-01,2009-06-22
-1hyt,1994-07-31,1994-05-04
-5hy5,2016-02-17,2016-02-01
-8hyb,2024-01-24,2023-01-06
-3hyt,2009-08-25,2009-06-23
-4hyf,2013-03-20,2012-11-13
-5hyk,2016-11-23,2016-02-01
-8hyf,2024-01-17,2023-01-06
-8hy7,2023-08-23,2023-01-06
-5hyr,2016-05-25,2016-02-01
-8hys,2023-12-20,2023-01-07
-1hy7,2002-01-18,2001-01-18
-2hyj,2006-09-05,2006-08-06
-1hyv,2001-04-04,2001-01-22
-1hyi,2001-03-14,2001-01-19
-4hyv,2013-09-11,2012-11-14
-4hy8,2013-03-20,2012-11-13
-2hyd,2006-09-05,2006-08-05
-3hyu,2010-06-23,2009-06-23
-6hyt,2019-08-28,2018-10-22
-1hyz,2001-04-04,2001-01-22
-2hyq,2007-04-24,2006-08-07
-3hyd,2009-10-06,2009-06-22
-6hyj,2019-06-12,2018-10-22
-2hyy,2007-01-16,2006-08-08
-5hyv,2017-02-08,2016-02-02
-6hyv,2018-12-19,2018-10-22
-8hy0,2023-09-27,2023-01-05
-6hys,2019-08-28,2018-10-22
-5hys,2016-06-01,2016-02-01
-4hyk,2013-01-02,2012-11-13
-3hyp,2010-01-12,2009-06-22
-5hyi,2017-02-01,2016-02-01
-8hyh,2023-04-05,2023-01-06
-4hy7,2013-03-27,2012-11-13
-1hyo,2001-02-14,2001-01-21
-3hy6,2009-07-14,2009-06-22
-8hye,2023-04-05,2023-01-06
-3hyi,2009-09-01,2009-06-22
-2hyi,2006-08-15,2006-08-06
-6hyi,2019-11-13,2018-10-22
-5hye,2017-02-01,2016-02-01
-5hyg,2016-06-08,2016-02-01
-1hy3,2002-06-19,2001-01-17
-6hyh,2019-05-01,2018-10-21
-6hyp,2018-12-12,2018-10-22
-8hy3,2024-05-08,2023-01-05
-2hyr,2007-04-24,2006-08-07
-8hy9,2024-01-10,2023-01-06
-5hyh,2016-06-08,2016-02-01
-1hyu,2001-02-14,2001-01-22
-6hy1,2019-10-30,2018-10-19
-8hyp,2023-12-20,2023-01-07
-8hy6,2023-11-01,2023-01-05
-4hym,2013-02-13,2012-11-13
-1hyf,2001-02-14,2001-01-19
-4hy5,2013-01-30,2012-11-13
-5hyl,2016-10-26,2016-02-01
-3hy1,2009-12-15,2009-06-22
-5hy8,2017-02-01,2016-02-01
-3hye,2009-09-15,2009-06-22
-1hyg,2001-04-25,2001-01-19
-8hyo,2023-12-20,2023-01-07
-2hy1,2006-12-26,2006-08-04
-4hyi,2013-03-06,2012-11-13
-8hym,2023-12-20,2023-01-07
-3hyl,2009-06-30,2009-06-22
-4hyx,2013-03-20,2012-11-14
-3hy8,2009-07-28,2009-06-22
-8hyk,2023-07-05,2023-01-06
-4hyh,2013-03-06,2012-11-13
-3hy3,2009-07-14,2009-06-22
-4hyu,2013-10-30,2012-11-14
-3hy4,2009-07-14,2009-06-22
-4hyb,2013-04-17,2012-11-13
-8hy2,2023-11-01,2023-01-05
-5hyx,2017-01-11,2016-02-02
-3hyg,2009-07-07,2009-06-22
-6hyw,2018-12-19,2018-10-22
-4hy9,2013-04-17,2012-11-13
-5hya,2016-05-11,2016-02-01
-6hyq,2019-11-13,2018-10-22
-4hyj,2013-07-17,2012-11-13
-4hyw,2013-09-11,2012-11-14
-3hy2,2009-10-06,2009-06-22
-1hyj,2001-03-14,2001-01-19
-4hyo,2012-12-26,2012-11-13
-6hyb,2019-10-30,2018-10-19
-4hy6,2013-05-15,2012-11-13
-5hyn,2016-05-11,2016-02-01
-6hy5,2018-12-19,2018-10-19
-2hyp,2006-12-26,2006-08-07
-8hyd,2023-11-01,2023-01-06
-6hyu,2019-08-28,2018-10-22
-2hy8,2006-11-07,2006-08-04
-2hyk,2007-10-02,2006-08-07
-6hyy,2019-06-12,2018-10-22
-2hy0,2007-06-19,2006-08-04
-2hyu,2006-09-05,2006-08-07
-2hye,2006-10-03,2006-08-05
-4hy0,2013-01-30,2012-11-12
-6hy7,2019-05-22,2018-10-19
-5rws,2020-11-11,2020-10-30
-3rwc,2012-03-21,2011-05-09
-4rw7,2015-04-29,2014-12-01
-3rwh,2012-03-21,2011-05-09
-1rwj,2004-08-03,2003-12-16
-5rwb,2020-11-11,2020-10-30
-6rw0,2020-05-20,2019-06-03
-7rwx,2022-06-29,2021-08-20
-1rwq,2004-12-17,2003-12-17
-1rwi,2004-04-27,2003-12-16
-7rw0,2022-07-20,2021-08-19
-7rwh,2022-03-23,2021-08-19
-3rwb,2012-05-09,2011-05-08
-4rwg,2015-05-20,2014-12-03
-1rwc,2004-04-13,2003-12-16
-4rww,2014-12-17,2014-12-07
-7rwv,2022-06-29,2021-08-20
-7rwe,2022-08-24,2021-08-19
-6rwh,2020-06-17,2019-06-05
-5rw1,2020-11-25,2020-10-27
-7rwp,2022-08-24,2021-08-20
-4rw2,2015-05-20,2014-12-01
-6rwv,2019-12-18,2019-06-06
-8rw3,2024-05-15,2024-02-02
-1rwn,2004-12-28,2003-12-16
-6rw2,2020-04-08,2019-06-03
-5rwa,2020-11-11,2020-10-30
-4rwy,2015-07-01,2014-12-08
-7rwg,2022-03-23,2021-08-19
-5rw9,2020-11-11,2020-10-30
-7rwm,2021-11-10,2021-08-20
-4rwk,2015-04-15,2014-12-04
-4rwo,2015-05-20,2014-12-05
-4rwm,2015-08-12,2014-12-05
-4rwt,2015-10-14,2014-12-05
-1rw9,2004-04-13,2003-12-16
-3rwl,2012-04-18,2011-05-09
-7rws,2021-11-10,2021-08-20
-4rwa,2015-01-14,2014-12-01
-6rwn,2020-02-05,2019-06-05
-4rw3,2015-06-03,2014-12-01
-4rw6,2015-04-29,2014-12-01
-3rwg,2012-03-21,2011-05-09
-1rwx,2004-12-28,2003-12-17
-4rw1,2015-05-20,2014-12-01
-4rwf,2015-05-20,2014-12-03
-5rwz,2020-11-11,2020-10-30
-8rwz,2024-03-06,2024-02-05
-7rwq,2022-08-24,2021-08-20
-5rwk,2020-11-11,2020-10-30
-1rwp,2004-12-28,2003-12-16
-5rwu,2020-11-11,2020-10-30
-6rwo,2020-02-05,2019-06-05
-7rwf,2022-08-24,2021-08-19
-4rw0,2015-01-28,2014-11-30
-7rw1,2022-07-20,2021-08-19
-1rwy,2004-05-11,2003-12-17
-6rwi,2020-06-17,2019-06-05
-5rwv,2020-11-11,2020-10-30
-6rwz,2020-07-15,2019-06-07
-4rwn,2015-05-20,2014-12-05
-3rwj,2012-03-21,2011-05-09
-1rwm,2004-12-28,2003-12-16
-4rwd,2015-01-14,2014-12-02
-6rwt,2019-09-18,2019-06-06
-4rwl,2015-04-15,2014-12-04
-5rww,2020-11-11,2020-10-30
-5rwd,2020-11-11,2020-10-30
-3rw8,2011-05-25,2011-05-08
-6rw5,2020-06-03,2019-06-03
-7rwu,2022-06-29,2021-08-20
-1rwk,2004-12-28,2003-12-16
-7rwk,2021-11-10,2021-08-20
-7rwo,2022-08-24,2021-08-20
-4rw9,2015-04-29,2014-12-01
-3rwu,2011-06-29,2011-05-09
-1rww,2004-12-28,2003-12-17
-7rw5,2022-03-23,2021-08-19
-5rwr,2020-11-11,2020-10-30
-6rw3,2020-01-29,2019-06-03
-5rwi,2020-11-11,2020-10-30
-5rw0,2020-11-25,2020-10-27
-3rwn,2011-06-08,2011-05-09
-3rwp,2011-11-16,2011-05-09
-1rwl,2004-04-27,2003-12-16
-3rwf,2012-03-21,2011-05-09
-6rwj,2020-12-09,2019-06-05
-1rwv,2004-12-28,2003-12-17
-1rwg,2004-04-13,2003-12-16
-5rwm,2020-11-11,2020-10-30
-4rw4,2015-04-29,2014-12-01
-5rw8,2020-11-11,2020-10-30
-3rwt,2011-06-15,2011-05-09
-5rwq,2020-11-11,2020-10-30
-3rwk,2012-07-18,2011-05-09
-5rwp,2020-11-11,2020-10-30
-6rwf,2019-11-06,2019-06-04
-3rwo,2011-10-26,2011-05-09
-5rwy,2020-11-11,2020-10-30
-7rw3,2023-01-25,2021-08-19
-5rwf,2020-11-11,2020-10-30
-5rw6,2020-11-11,2020-10-30
-1rwt,2004-03-30,2003-12-17
-5rwl,2020-11-11,2020-10-30
-1rwf,2004-04-13,2003-12-16
-5rwg,2020-11-11,2020-10-30
-1rwb,2003-12-30,2003-12-16
-4rwj,2015-04-22,2014-12-04
-6rwe,2019-12-11,2019-06-04
-6rw7,2019-10-09,2019-06-04
-5rwt,2020-11-11,2020-10-30
-6rwd,2019-06-19,2019-06-04
-7rwn,2022-08-24,2021-08-20
-6rwm,2020-02-05,2019-06-05
-5rw3,2020-11-11,2020-10-30
-5rwj,2020-11-11,2020-10-30
-5rw5,2020-11-11,2020-10-30
-1rw8,2005-02-01,2003-12-16
-5rwo,2020-11-11,2020-10-30
-6rws,2020-06-17,2019-06-06
-5rwc,2020-11-11,2020-10-30
-4rw5,2015-06-03,2014-12-01
-6rw1,2019-08-28,2019-06-03
-5rwh,2020-11-11,2020-10-30
-7rwa,2022-03-30,2021-08-19
-7rww,2022-06-29,2021-08-20
-5rwe,2020-11-11,2020-10-30
-5rw2,2020-11-11,2020-10-30
-1rwe,2005-02-15,2003-12-16
-7rwi,2022-03-02,2021-08-19
-7rwy,2022-06-29,2021-08-20
-1rwo,2004-12-28,2003-12-16
-3rwq,2011-11-16,2011-05-09
-5rw4,2020-11-11,2020-10-30
-6rwu,2020-06-17,2019-06-06
-5rwx,2020-11-11,2020-10-30
-4rw8,2015-04-29,2014-12-01
-3rwm,2011-10-26,2011-05-09
-1rwh,2004-04-13,2003-12-16
-3rwe,2012-03-21,2011-05-09
-5rw7,2020-11-11,2020-10-30
-6rwl,2020-02-05,2019-06-05
-7rw2,2021-09-01,2021-08-19
-7rw7,2022-03-23,2021-08-19
-7rwj,2022-05-18,2021-08-20
-6rwg,2020-05-20,2019-06-05
-3rw9,2011-09-21,2011-05-08
-1rwa,2004-04-13,2003-12-16
-7rw6,2022-04-27,2021-08-19
-5rwn,2020-11-11,2020-10-30
-6rw4,2020-06-03,2019-06-03
-2vr4,2008-04-08,2008-03-25
-6vr5,2020-06-17,2020-02-06
-2vr5,2008-07-29,2008-03-26
-3vrv,2012-05-23,2012-04-14
-1vrn,2005-03-22,2005-02-23
-7vrg,2022-03-02,2021-10-22
-3vrf,2012-11-07,2012-04-09
-2vrl,2008-04-22,2008-04-09
-3vra,2013-04-10,2012-04-07
-2vrj,2008-10-14,2008-04-09
-7vrq,2023-02-01,2021-10-23
-5vrt,2017-08-16,2017-05-11
-6vre,2020-05-06,2020-02-07
-3vrd,2012-09-12,2012-04-09
-6vry,2020-12-30,2020-02-10
-6vr4,2020-07-29,2020-02-06
-1vrk,1999-04-27,1997-09-24
-1vrb,2005-03-15,2005-02-18
-2vrt,2008-07-22,2008-04-14
-3vrk,2013-02-27,2012-04-11
-1vrw,2005-07-05,2005-06-30
-7vrd,2022-07-06,2021-10-22
-6vrq,2021-02-17,2020-02-08
-5vro,2017-11-15,2017-05-11
-3vry,2013-05-01,2012-04-21
-5vrf,2018-03-14,2017-05-10
-2vrr,2008-08-19,2008-04-13
-5vr7,2017-11-15,2017-05-10
-6vrn,2020-06-17,2020-02-08
-1vr0,2005-02-15,2005-01-26
-1vru,1996-04-03,1995-04-19
-5vra,2017-12-13,2017-05-10
-6vrz,2020-06-03,2020-02-10
-3vrp,2013-03-06,2012-04-13
-2vra,2008-04-08,2008-03-28
-7vrj,2022-05-04,2021-10-23
-2vrz,2008-08-26,2008-04-17
-6vrm,2020-06-17,2020-02-08
-6vrf,2020-06-03,2020-02-07
-3vr8,2012-07-11,2012-04-07
-7vru,2022-11-30,2021-10-25
-6vru,2020-11-04,2020-02-10
-6vr2,2021-06-02,2020-02-06
-3vrb,2012-07-11,2012-04-07
-6vr1,2020-06-10,2020-02-06
-6vrv,2020-11-04,2020-02-10
-2vr6,2008-04-15,2008-03-28
-6vra,2020-12-16,2020-02-07
-7vr4,2022-10-26,2021-10-21
-1vrl,2005-03-22,2005-03-08
-5vrh,2017-07-12,2017-05-10
-7vrz,2023-02-01,2021-10-25
-1vr3,2005-02-15,2005-01-28
-6vr3,2021-06-02,2020-02-06
-7vro,2023-02-01,2021-10-23
-2vr8,2008-04-08,2008-03-28
-1vrp,2005-05-03,2005-04-25
-3vru,2012-05-23,2012-04-14
-3vr3,2013-01-16,2012-04-03
-7vrv,2022-06-22,2021-10-25
-6vrx,2020-12-16,2020-02-10
-3vrn,2013-03-06,2012-04-13
-3vro,2013-03-06,2012-04-13
-3vrw,2012-05-23,2012-04-16
-2vrs,2009-01-13,2008-04-14
-1vrf,1999-04-01,1999-03-25
-7vrm,2023-02-01,2021-10-23
-2vrb,2008-09-23,2008-03-31
-3vre,2012-11-07,2012-04-09
-5vrw,2017-07-19,2017-05-11
-7vr9,2022-02-16,2021-10-22
-7vrh,2023-02-01,2021-10-22
-3vrc,2012-09-12,2012-04-09
-5vrk,2018-01-10,2017-05-10
-3vrh,2013-03-13,2012-04-10
-5vri,2017-12-20,2017-05-10
-5vrx,2017-07-19,2017-05-11
-3vr1,2012-09-05,2012-04-03
-6vrt,2020-04-29,2020-02-09
-5vr0,2018-05-02,2017-05-09
-5vrz,2017-07-19,2017-05-11
-3vrt,2012-05-23,2012-04-14
-2vr2,2008-04-01,2008-03-25
-1vrh,1997-02-12,1996-02-26
-3vrz,2013-05-01,2012-04-21
-5vry,2017-07-19,2017-05-11
-2vrm,2008-04-22,2008-04-09
-8vr7,2024-01-31,2024-01-20
-7vr7,2022-08-10,2021-10-22
-7vrl,2022-10-26,2021-10-23
-6vr7,2021-02-10,2020-02-06
-6vrg,2020-09-09,2020-02-07
-2vr0,2008-06-03,2008-03-24
-2vrp,2008-07-08,2008-04-09
-7vrs,2022-06-08,2021-10-24
-1vre,1999-04-02,1999-03-25
-6vrh,2020-03-11,2020-02-07
-5vrj,2018-04-11,2017-05-10
-2vrx,2008-07-01,2008-04-16
-2vry,2008-05-06,2008-04-16
-3vrj,2012-05-30,2012-04-11
-3vr0,2013-04-03,2012-04-02
-5vr8,2017-07-19,2017-05-10
-7vr5,2022-09-07,2021-10-21
-7vri,2023-02-01,2021-10-23
-6vri,2020-12-02,2020-02-07
-2vrg,2008-07-15,2008-04-04
-5vrp,2017-10-18,2017-05-11
-6vrs,2020-02-19,2020-02-09
-1vrg,2005-03-08,2005-02-22
-8vr0,2024-01-31,2024-01-19
-2vrn,2008-10-28,2008-04-09
-8vr1,2024-01-31,2024-01-19
-6vrk,2020-03-11,2020-02-07
-6vr8,2021-08-11,2020-02-06
-2vro,2008-04-22,2008-04-09
-1vrq,2005-07-05,2005-04-27
-3vrg,2012-11-07,2012-04-09
-7vra,2022-06-08,2021-10-22
-7vrk,2023-02-01,2021-10-23
-1vrt,1996-04-03,1995-04-19
-3vr9,2013-04-10,2012-04-07
-3vrr,2013-03-06,2012-04-13
-2vr1,2008-09-09,2008-03-24
-2vrq,2008-07-01,2008-04-09
-7vr8,2022-08-10,2021-10-22
-1vr5,2005-03-08,2005-02-11
-2vrd,2008-04-08,2008-03-31
-6vr6,2020-08-05,2020-02-06
-7vrw,2022-06-22,2021-10-25
-7vrf,2022-10-26,2021-10-22
-8vrx,2024-02-07,2024-01-22
-5vrg,2017-07-12,2017-05-10
-3vr6,2013-01-16,2012-04-03
-7vre,2022-06-08,2021-10-22
-3vrm,2013-04-17,2012-04-12
-8vr6,2024-01-31,2024-01-20
-3vrq,2013-03-06,2012-04-13
-3vri,2012-05-30,2012-04-11
-2vrw,2008-06-17,2008-04-16
-8vr2,2024-01-31,2024-01-20
-6vrw,2020-03-11,2020-02-10
-5vrb,2017-05-17,2017-05-10
-2vr7,2008-04-15,2008-03-28
-6vrl,2020-03-11,2020-02-07
-6w4n,2021-03-17,2020-03-11
-4w4g,2015-10-21,2014-08-14
-8w48,2023-11-22,2023-08-23
-3w45,2014-01-22,2013-01-04
-7w4c,2023-02-01,2021-11-27
-4w4u,2015-07-01,2014-08-15
-2w44,2009-12-22,2008-11-21
-6w4z,2020-09-02,2020-03-12
-6w42,2021-03-10,2020-03-09
-7w4x,2022-03-16,2021-11-29
-1w48,2004-10-29,2004-07-22
-1w4r,2005-02-01,2004-07-27
-8w47,2023-11-22,2023-08-23
-4w4v,2015-02-11,2014-08-15
-7w4y,2022-03-16,2021-11-29
-7w41,2023-02-22,2021-11-26
-2w4j,2009-12-22,2008-11-27
-5w4y,2018-06-13,2017-06-13
-2w49,2010-05-05,2008-11-24
-6w4u,2020-04-08,2020-03-11
-5w4r,2017-12-27,2017-06-12
-5w4t,2018-06-20,2017-06-12
-1w4w,2005-01-19,2004-08-03
-4w4y,2015-02-11,2014-08-15
-1w4n,2005-12-08,2004-07-27
-7w46,2022-10-19,2021-11-26
-2w4k,2009-12-22,2008-11-27
-7w4o,2022-06-01,2021-11-28
-8w4r,2023-11-22,2023-08-24
-5w4v,2017-12-27,2017-06-13
-5w4l,2017-11-15,2017-06-12
-8w42,2023-11-22,2023-08-23
-5w4f,2018-06-13,2017-06-10
-7w4p,2022-06-01,2021-11-28
-1w49,2004-10-29,2004-07-22
-7w4f,2023-01-25,2021-11-27
-5w4b,2017-06-28,2017-06-09
-7w4g,2023-01-25,2021-11-27
-5w40,2017-08-09,2017-06-08
-1w4l,2004-11-25,2004-07-25
-5w4w,2017-06-28,2017-06-13
-2w4y,2009-07-14,2008-12-02
-2w4r,2009-02-24,2008-12-01
-2w4l,2009-01-13,2008-11-28
-2w4d,2009-12-22,2008-11-25
-7w4n,2023-01-25,2021-11-28
-6w4e,2020-04-15,2020-03-10
-5w45,2018-03-14,2017-06-09
-3w4u,2013-02-06,2013-01-16
-8w4p,2023-12-20,2023-08-24
-8w4t,2023-11-22,2023-08-24
-1w4a,2004-10-29,2004-07-22
-6w4h,2020-03-18,2020-03-10
-4w4q,2014-11-05,2014-08-15
-2w4i,2008-12-09,2008-11-25
-4w4o,2015-04-29,2014-08-15
-2w4x,2009-02-24,2008-12-02
-6w4g,2020-11-04,2020-03-10
-6w4i,2020-06-17,2020-03-10
-6w4m,2020-08-05,2020-03-11
-8w4q,2023-11-22,2023-08-24
-5w42,2018-07-25,2017-06-08
-8w4s,2023-11-22,2023-08-24
-4w4w,2015-02-11,2014-08-15
-3w44,2014-01-22,2013-01-04
-5w4u,2018-06-20,2017-06-13
-5w49,2017-06-28,2017-06-09
-7w49,2022-01-05,2021-11-26
-8w43,2023-11-22,2023-08-23
-2w4m,2008-12-23,2008-11-28
-4w4s,2015-01-14,2014-08-15
-2w42,2008-12-09,2008-11-19
-8w41,2024-02-21,2023-08-23
-1w4y,2005-01-19,2004-08-03
-8w4v,2024-04-17,2023-08-25
-2w46,2009-01-27,2008-11-21
-3w42,2014-01-22,2013-01-04
-6w4x,2020-04-08,2020-03-11
-5w41,2018-06-13,2017-06-08
-5w4m,2017-10-25,2017-06-12
-6w43,2020-06-10,2020-03-10
-7w4b,2023-03-08,2021-11-26
-7w4j,2023-01-25,2021-11-28
-4w4n,2015-04-29,2014-08-15
-6w4y,2020-07-01,2020-03-11
-1w4o,2005-02-02,2004-07-27
-5w44,2018-01-10,2017-06-09
-3w4y,2013-03-20,2013-01-17
-2w4o,2009-01-20,2008-11-28
-6w49,2021-04-07,2020-03-10
-7w40,2023-02-22,2021-11-26
-1w4x,2004-09-02,2004-08-03
-2w4z,2009-07-14,2008-12-02
-4w4x,2015-02-11,2014-08-15
-6w41,2020-03-25,2020-03-09
-1w46,2004-11-04,2004-07-22
-4w4z,2014-10-08,2014-08-15
-7w4d,2023-02-01,2021-11-27
-6w45,2021-05-12,2020-03-10
-1w4b,2004-11-04,2004-07-22
-3w4r,2014-02-12,2013-01-10
-5w4c,2018-06-13,2017-06-09
-1w47,2004-11-04,2004-07-22
-3w41,2014-01-22,2013-01-04
-6w4c,2021-05-12,2020-03-10
-6w4f,2020-04-29,2020-03-10
-3w43,2014-01-22,2013-01-04
-1w4q,2005-02-02,2004-07-27
-7w45,2022-03-09,2021-11-26
-1w4z,2004-12-10,2004-08-03
-1w44,2004-10-29,2004-07-22
-2w4q,2009-01-20,2008-11-30
-7w4z,2022-10-26,2021-11-29
-7w4k,2023-01-25,2021-11-28
-7w48,2022-01-05,2021-11-26
-7w4q,2023-01-25,2021-11-28
-7w4a,2022-03-02,2021-11-26
-2w41,2008-12-02,2008-11-18
-5w46,2017-07-05,2017-06-09
-7w4e,2023-02-01,2021-11-27
-8w4o,2023-12-20,2023-08-24
-8w4u,2023-12-13,2023-08-25
-5w4k,2017-08-30,2017-06-12
-2w47,2009-01-27,2008-11-21
-5w4z,2018-06-13,2017-06-13
-6w4r,2021-03-17,2020-03-11
-5w4e,2018-06-27,2017-06-10
-3w40,2014-01-22,2013-01-04
-3w4j,2013-05-29,2013-01-09
-6w44,2021-05-12,2020-03-10
-8w46,2023-11-22,2023-08-23
-8w45,2023-11-22,2023-08-23
-1w4p,2005-02-02,2004-07-27
-6w4k,2020-10-21,2020-03-11
-8w44,2023-11-22,2023-08-23
-3w4k,2013-05-29,2013-01-09
-7w4l,2023-01-25,2021-11-28
-7w47,2022-01-05,2021-11-26
-7w4m,2023-01-25,2021-11-28
-3w4i,2013-05-29,2013-01-09
-5w4s,2018-04-25,2017-06-12
-5jd7,2017-08-09,2016-04-15
-3jd3,2016-04-27,2016-03-28
-6jd4,2019-12-04,2019-01-31
-6jdl,2019-11-27,2019-02-01
-1jdj,2002-06-14,2001-06-14
-2jd5,2007-02-06,2007-01-04
-8jdw,1999-02-09,1998-10-12
-4jd2,2013-07-17,2013-02-22
-8jde,2023-10-18,2023-05-13
-5jda,2016-05-18,2016-04-15
-1jdb,1998-06-17,1997-03-25
-1jdl,2001-11-07,2001-06-14
-6jd7,2019-05-15,2019-01-31
-8jdf,2023-10-18,2023-05-13
-4jdp,2013-03-06,2013-02-25
-1jdo,1998-05-27,1998-02-10
-2jdu,2007-06-12,2007-01-12
-1jdc,1997-10-15,1997-06-16
-4jdz,2013-06-19,2013-02-25
-8jdo,2023-10-18,2023-05-15
-8jdc,2023-10-18,2023-05-13
-1jdr,2001-06-27,2001-06-14
-2jdt,2007-02-13,2007-01-12
-4jdd,2013-05-15,2013-02-25
-6jdg,2019-12-11,2019-02-01
-4jd1,2013-03-20,2013-02-22
-6jdd,2019-03-06,2019-02-01
-5jdo,2016-04-27,2016-04-17
-8jdg,2023-10-18,2023-05-14
-1jdf,2001-09-05,2001-06-13
-2jdd,2007-02-13,2007-01-06
-3jd2,2016-04-27,2016-03-28
-6jde,2019-06-26,2019-02-01
-6jdu,2020-02-05,2019-02-02
-2jdo,2007-02-13,2007-01-11
-2jd4,2007-02-27,2007-01-04
-4jdb,2014-02-26,2013-02-24
-4jd0,2013-09-18,2013-02-22
-5jdm,2016-05-11,2016-04-17
-6jdi,2019-11-27,2019-02-01
-2jdh,2007-07-24,2007-01-09
-1jdv,2001-10-26,2001-06-15
-2jdk,2007-07-24,2007-01-10
-2jds,2007-02-13,2007-01-12
-5jdl,2016-05-11,2016-04-17
-2jdv,2007-02-13,2007-01-12
-3jd8,2016-06-01,2016-05-01
-5jds,2017-04-12,2016-04-17
-6jdt,2020-05-20,2019-02-02
-8jdu,2023-10-18,2023-05-15
-5jdg,2016-05-11,2016-04-16
-1jdx,1999-02-09,1998-10-12
-2jdr,2007-02-13,2007-01-12
-1jdy,1997-03-12,1996-07-11
-3jd4,2016-04-27,2016-03-28
-8jdn,2023-10-18,2023-05-15
-5jdv,2017-01-11,2016-04-17
-6jd9,2019-07-24,2019-01-31
-2jd1,2007-05-08,2007-01-04
-6jdp,2019-03-20,2019-02-02
-1jd0,2001-08-17,2001-06-11
-6jd5,2019-12-04,2019-01-31
-5jdz,2016-05-04,2016-04-17
-8jd4,2023-06-21,2023-05-12
-6jd0,2020-02-05,2019-01-30
-1jdn,2001-09-05,2001-06-14
-4jdt,2013-03-20,2013-02-25
-8jdk,2023-12-06,2023-05-14
-8jdm,2023-12-06,2023-05-14
-8jdt,2023-10-18,2023-05-15
-1jd6,2001-12-05,2001-06-12
-1jdd,1997-10-15,1997-06-16
-5jdu,2016-07-13,2016-04-17
-6jda,2020-02-05,2019-01-31
-8jdy,2023-10-18,2023-05-15
-1jd2,2002-02-13,2001-06-12
-2jdz,2007-10-30,2007-01-12
-1jd7,2002-09-18,2001-06-13
-4jdh,2014-01-29,2013-02-25
-4jd6,2013-10-23,2013-02-23
-1jdt,2001-10-26,2001-06-15
-8jdl,2023-12-06,2023-05-14
-5jdc,2016-08-17,2016-04-16
-6jdr,2020-02-05,2019-02-02
-4jdo,2013-06-05,2013-02-25
-8jdj,2023-12-06,2023-05-14
-6jdy,2020-05-20,2019-02-02
-3jdw,1998-01-28,1997-01-24
-5jdn,2016-05-11,2016-04-17
-1jd5,2001-12-05,2001-06-12
-8jd5,2023-06-21,2023-05-12
-3jd0,2016-04-27,2016-03-28
-8jdr,2023-10-18,2023-05-15
-5jdt,2016-09-28,2016-04-17
-1jda,1997-10-15,1997-06-16
-2jdp,2007-06-12,2007-01-11
-6jdz,2020-05-20,2019-02-02
-6jdv,2019-11-06,2019-02-02
-4jdr,2013-04-24,2013-02-25
-6jdc,2020-02-05,2019-02-01
-2jdc,2007-02-13,2007-01-05
-3jd1,2016-04-27,2016-03-28
-8jd1,2023-06-21,2023-05-12
-5jdi,2016-08-17,2016-04-16
-4jdw,1998-01-28,1997-01-24
-2jdi,2007-03-13,2007-01-09
-1jdz,2001-10-26,2001-06-15
-6jdo,2020-02-05,2019-02-02
-2jdn,2007-06-12,2007-01-11
-4jda,2013-07-24,2013-02-24
-8jds,2023-10-18,2023-05-15
-5jdj,2016-08-17,2016-04-16
-1jd9,2002-09-18,2001-06-13
-7jdw,1999-02-09,1998-10-12
-6jdb,2020-02-05,2019-02-01
-2jd8,2007-02-27,2007-01-05
-8jdv,2023-10-18,2023-05-15
-4jdg,2014-02-26,2013-02-25
-2jd9,2007-01-16,2007-01-05
-2jd6,2007-02-27,2007-01-05
-8jdx,2023-10-18,2023-05-15
-4jdc,2013-12-18,2013-02-24
-2jd0,2007-05-08,2007-01-04
-4jd4,2014-02-26,2013-02-23
-2jda,2007-01-16,2007-01-05
-1jdp,2001-09-05,2001-06-14
-5jd2,2016-11-16,2016-04-15
-6jdk,2019-04-10,2019-02-01
-6jds,2020-02-05,2019-02-02
-6jdw,1999-02-09,1998-10-12
-6jdh,2020-02-05,2019-02-01
-5jdh,2016-05-11,2016-04-16
-6jd2,2019-08-14,2019-01-30
-5jdy,2016-05-04,2016-04-17
-2jdy,2007-06-12,2007-01-12
-8jdd,2023-10-18,2023-05-13
-2jd2,2007-05-08,2007-01-04
-8jd0,2023-06-21,2023-05-12
-8jdb,2023-10-18,2023-05-13
-2jd7,2007-02-27,2007-01-05
-2jdm,2007-06-12,2007-01-11
-4jdu,2013-03-27,2013-02-25
-5jdf,2016-05-11,2016-04-16
-1jdi,2002-01-23,2001-06-13
-8jdq,2023-10-18,2023-05-15
-5jdx,2017-08-23,2016-04-17
-8jd2,2023-06-21,2023-05-12
-4jdi,2014-01-29,2013-02-25
-4jdk,2014-01-29,2013-02-25
-8jd6,2023-06-21,2023-05-12
-5jdw,1999-02-09,1998-10-07
-6jd1,2019-04-17,2019-01-30
-4jd5,2013-05-22,2013-02-23
-2jdl,2008-02-05,2007-01-11
-4jd3,2013-04-24,2013-02-22
-4jdn,2013-06-05,2013-02-25
-8jd3,2023-06-21,2023-05-12
-8jdz,2023-10-18,2023-05-15
-4jdj,2014-01-29,2013-02-25
-5jd9,2016-05-18,2016-04-15
-5jdq,2016-05-11,2016-04-17
-8jdp,2023-10-18,2023-05-15
-1jd4,2001-12-05,2001-06-12
-8jd8,2023-12-27,2023-05-12
-9jdw,1999-02-09,1998-10-12
-10mh,1999-02-09,1998-08-10
-4yu5,2015-10-28,2015-03-18
-7yu5,2022-10-05,2022-08-16
-7yu7,2022-10-05,2022-08-16
-7yu6,2022-10-05,2022-08-16
-6yu1,2020-07-15,2020-04-25
-4yuw,2015-09-09,2015-03-19
-6yut,2021-05-12,2020-04-27
-2yu4,2007-10-09,2007-04-05
-5yuz,2018-11-14,2017-11-23
-7yui,2023-08-30,2022-08-17
-5yuc,2017-12-27,2017-11-21
-5yui,2018-08-01,2017-11-22
-6yu2,2020-07-15,2020-04-25
-5yuh,2018-05-02,2017-11-22
-4yu0,2016-01-13,2015-03-18
-2yu8,2007-10-09,2007-04-06
-4yus,2016-06-01,2015-03-19
-6yux,2021-02-03,2020-04-27
-1yuh,1996-07-11,1996-01-30
-5yuj,2018-08-01,2017-11-22
-4yuv,2015-09-09,2015-03-19
-7yuw,2023-10-25,2022-08-18
-6yuh,2021-01-13,2020-04-27
-5yux,2018-12-19,2017-11-23
-7yue,2023-02-08,2022-08-17
-7yu3,2022-10-05,2022-08-16
-6yu3,2020-07-15,2020-04-25
-6yuq,2020-08-19,2020-04-27
-6yu6,2020-07-15,2020-04-25
-5yu6,2018-08-29,2017-11-20
-7yux,2023-10-25,2022-08-18
-6yus,2020-08-19,2020-04-27
-1yu2,2005-09-20,2005-02-11
-7yuj,2023-08-30,2022-08-17
-1yuk,2005-07-19,2005-02-14
-5yuw,2018-11-07,2017-11-23
-6yuw,2020-05-06,2020-04-27
-1yu9,2005-07-26,2005-02-13
-5yu0,2018-05-02,2017-11-20
-1yux,2005-06-21,2005-02-14
-1yu1,2005-09-20,2005-02-11
-6yuc,2020-07-22,2020-04-26
-7yuv,2023-10-25,2022-08-17
-4yu6,2015-10-28,2015-03-18
-6yum,2020-07-01,2020-04-27
-6yud,2020-08-19,2020-04-27
-6yur,2021-03-24,2020-04-27
-1yu0,2005-09-20,2005-02-11
-5yum,2018-09-19,2017-11-22
-4yu4,2015-09-23,2015-03-18
-4yu9,2015-08-05,2015-03-18
-6yuo,2020-08-19,2020-04-27
-6yu5,2020-07-15,2020-04-25
-6yu8,2021-02-17,2020-04-25
-1yun,2005-11-08,2005-02-14
-7yul,2023-04-26,2022-08-17
-1yum,2005-11-08,2005-02-14
-4yur,2015-06-17,2015-03-19
-6yub,2020-07-22,2020-04-26
-5yu3,2018-05-02,2017-11-20
-5yut,2018-09-05,2017-11-23
-6yup,2021-01-20,2020-04-27
-5yub,2017-12-27,2017-11-21
-5yu9,2017-12-27,2017-11-21
-5yud,2018-01-03,2017-11-21
-6yug,2020-09-30,2020-04-27
-4yut,2016-06-01,2015-03-19
-4yu3,2015-09-23,2015-03-18
-4yua,2015-05-13,2015-03-18
-2yu2,2007-04-24,2007-04-05
-5yuy,2018-10-17,2017-11-23
-6yuf,2020-08-19,2020-04-27
-7yuy,2023-03-29,2022-08-18
-4yuy,2015-09-09,2015-03-19
-1yui,1997-12-31,1996-12-31
-2yut,2007-10-09,2007-04-06
-6yu7,2020-07-15,2020-04-25
-5yu8,2018-05-23,2017-11-21
-6yuu,2021-03-24,2020-04-27
-4yux,2015-09-09,2015-03-19
-8yu6,2024-04-24,2024-03-26
-5yuu,2019-01-02,2017-11-23
-1yu3,2005-09-20,2005-02-11
-2yu9,2007-04-24,2007-04-06
-4yu2,2015-03-25,2015-03-18
-5yu1,2018-05-02,2017-11-20
-8yu5,2024-04-24,2024-03-26
-5yuf,2018-04-11,2017-11-22
-5yua,2017-12-27,2017-11-21
-2yu5,2007-10-09,2007-04-05
-7yud,2023-09-06,2022-08-17
-6yuy,2020-05-06,2020-04-27
-1yuz,2005-06-21,2005-02-14
-4yuz,2015-09-09,2015-03-19
-1yu4,2005-09-20,2005-02-11
-6yul,2020-07-01,2020-04-27
-1yuj,1997-12-31,1996-12-31
-1yu6,2005-05-03,2005-02-11
-4yu1,2016-03-23,2015-03-18
-5yun,2018-10-10,2017-11-22
-6yu4,2020-07-15,2020-04-25
-5yuv,2018-10-03,2017-11-23
-1yuu,2005-10-18,2005-02-14
-5yur,2018-08-29,2017-11-23
-2yuu,2008-04-08,2007-04-06
-5yuk,2018-08-01,2017-11-22
-2yur,2008-04-08,2007-04-06
-5yul,2018-11-21,2017-11-22
-7yu4,2022-10-05,2022-08-16
-4yu8,2015-03-25,2015-03-18
-6yua,2020-11-04,2020-04-26
-8yud,2024-04-10,2024-03-27
-4yu7,2015-08-05,2015-03-18
-4yuu,2016-01-20,2015-03-19
-7yua,2023-07-26,2022-08-16
-4yuq,2016-04-06,2015-03-19
-7yu8,2022-10-05,2022-08-16
-7yu1,2023-03-01,2022-08-16
-1yut,2005-10-18,2005-02-14
-5yu4,2018-05-02,2017-11-20
-5yus,2018-11-07,2017-11-23
-2yu1,2007-04-24,2007-04-05
-2yuc,2008-04-08,2007-04-06
-7yu0,2023-03-01,2022-08-16
-5yug,2018-05-02,2017-11-22
-7yuz,2023-07-26,2022-08-18
-6yuz,2021-01-20,2020-04-27
-4yuc,2016-03-30,2015-03-18
-8yuu,2024-06-05,2024-03-27
-1z3z,2006-01-03,2005-03-14
-6z3c,2020-06-03,2020-05-19
-4z36,2015-06-03,2015-03-30
-1z3c,2005-03-22,2005-03-11
-5z3i,2019-01-02,2018-01-08
-1z3t,2005-04-26,2005-03-14
-2z3u,2007-07-03,2007-06-06
-2z3e,2007-07-03,2007-06-04
-1z35,2005-03-29,2005-03-10
-2z3b,2008-03-25,2007-06-03
-5z3f,2019-05-15,2018-01-05
-1z38,2005-03-29,2005-03-10
-1z36,2005-03-29,2005-03-10
-5z3s,2018-02-14,2018-01-08
-2z31,2007-10-09,2007-05-30
-6z3s,2021-06-02,2020-05-21
-1z3w,2005-04-26,2005-03-14
-2z3c,2007-07-03,2007-06-04
-4z3u,2015-11-11,2015-03-31
-7z31,2023-04-05,2022-03-01
-7z38,2022-09-14,2022-03-01
-7z3g,2023-09-13,2022-03-02
-4z3e,2016-04-13,2015-03-31
-2z3d,2007-07-03,2007-06-04
-2z3t,2007-07-03,2007-06-06
-7z3r,2023-03-22,2022-03-02
-1z37,2005-03-29,2005-03-10
-7z3u,2023-03-22,2022-03-02
-2z36,2007-08-21,2007-06-02
-4z3k,2015-11-18,2015-03-31
-4z3b,2015-10-21,2015-03-31
-5z3u,2019-05-22,2018-01-08
-7z3o,2023-04-12,2022-03-02
-6z3a,2020-11-11,2020-05-19
-2z3n,2007-10-23,2007-06-04
-1z3j,2005-04-19,2005-03-13
-7z3v,2022-06-29,2022-03-02
-5z39,2018-10-17,2018-01-05
-1z39,2005-03-29,2005-03-10
-4z33,2016-06-29,2015-03-30
-7z3z,2022-05-04,2022-03-03
-6z3e,2021-12-01,2020-05-20
-6z3i,2021-06-30,2020-05-20
-6z3m,2020-07-01,2020-05-21
-7z30,2023-04-05,2022-03-01
-4z3s,2015-06-03,2015-03-31
-4z38,2016-04-13,2015-03-31
-1z3n,2006-03-14,2005-03-14
-6z3o,2021-01-27,2020-05-21
-5z34,2019-02-20,2018-01-05
-5z3v,2019-05-22,2018-01-08
-7z3x,2022-11-09,2022-03-02
-6z30,2020-08-19,2020-05-19
-1z3h,2005-05-10,2005-03-12
-1z3u,2005-07-12,2005-03-14
-6z33,2020-07-29,2020-05-19
-7z3b,2023-09-13,2022-03-02
-5z3q,2018-09-12,2018-01-08
-2z3p,2007-10-23,2007-06-04
-2z32,2008-03-11,2007-05-31
-5z36,2018-12-12,2018-01-05
-2z3f,2008-03-11,2007-06-04
-2z3g,2007-10-23,2007-06-04
-5z30,2018-07-18,2018-01-05
-7z3a,2022-08-10,2022-03-02
-7z32,2022-03-16,2022-03-01
-7z3j,2022-07-20,2022-03-02
-4z35,2015-06-03,2015-03-30
-2z3y,2008-01-01,2007-06-08
-1z3v,2005-04-26,2005-03-14
-7z3f,2023-09-13,2022-03-02
-4z3h,2016-04-13,2015-03-31
-7z3p,2023-03-22,2022-03-02
-5z3w,2019-01-16,2018-01-09
-7z36,2022-11-02,2022-03-01
-4z3f,2016-04-13,2015-03-31
-5z3n,2018-11-21,2018-01-08
-1z34,2005-03-29,2005-03-10
-2z3m,2007-10-23,2007-06-04
-7z3i,2023-09-13,2022-03-02
-2z3o,2007-10-23,2007-06-04
-7z34,2022-09-21,2022-03-01
-7z3y,2023-03-22,2022-03-02
-6z3x,2021-03-31,2020-05-22
-1z3a,2006-02-21,2005-03-10
-4z3d,2015-10-14,2015-03-31
-6z3f,2021-06-02,2020-05-20
-2z3h,2007-10-23,2007-06-04
-6z31,2020-08-19,2020-05-19
-6z3t,2020-07-22,2020-05-21
-4z3t,2015-11-04,2015-03-31
-2z3i,2007-10-23,2007-06-04
-7z39,2022-10-12,2022-03-01
-7z3k,2023-01-25,2022-03-02
-2z3j,2007-10-23,2007-06-04
-2z30,2007-12-04,2007-05-29
-4z3p,2016-01-13,2015-03-31
-6z3n,2021-06-09,2020-05-21
-6z3v,2020-09-16,2020-05-22
-6z3b,2020-07-22,2020-05-19
-6z3r,2020-06-24,2020-05-21
-4z34,2015-06-03,2015-03-30
-1z3i,2005-04-05,2005-03-12
-6z3j,2020-07-01,2020-05-20
-4z3m,2015-09-02,2015-03-31
-1z32,2005-05-31,2005-03-10
-4z3v,2015-07-01,2015-03-31
-4z3g,2016-04-13,2015-03-31
-6z36,2020-05-27,2020-05-19
-5z3j,2019-01-02,2018-01-08
-6z32,2020-08-19,2020-05-19
-2z3l,2007-10-23,2007-06-04
-4z3o,2016-09-14,2015-03-31
-7z3l,2023-01-25,2022-03-02
-2z3z,2008-02-19,2007-06-09
-2z3k,2007-10-23,2007-06-04
-4z3c,2015-04-29,2015-03-31
-1z3s,2005-07-12,2005-03-14
-7z37,2022-09-14,2022-03-01
-7z3n,2023-04-12,2022-03-02
-5z3o,2019-04-03,2018-01-08
-3w3g,2013-04-03,2012-12-21
-6w32,2020-11-25,2020-03-08
-3w3d,2013-01-30,2012-12-20
-1w3t,2004-09-02,2004-07-19
-7w3i,2022-05-18,2021-11-25
-2w3w,2009-11-17,2008-11-16
-2w3d,2009-03-10,2008-11-12
-5w38,2017-10-18,2017-06-07
-8w34,2024-04-17,2024-02-21
-6w3r,2020-05-20,2020-03-09
-2w3m,2009-11-17,2008-11-13
-6w30,2021-05-26,2020-03-08
-5w3v,2017-10-25,2017-06-08
-3w3z,2013-04-10,2012-12-28
-1w3n,2004-09-02,2004-07-17
-1w34,2005-10-19,2004-07-13
-7w3p,2022-12-07,2021-11-25
-1w3p,2004-10-18,2004-07-17
-6w3u,2020-06-10,2020-03-09
-7w3x,2022-06-22,2021-11-26
-6w3s,2020-05-20,2020-03-09
-5w3h,2017-07-19,2017-06-07
-2w3i,2009-04-07,2008-11-12
-3w3j,2013-04-03,2012-12-22
-7w3c,2022-05-04,2021-11-25
-5w3x,2017-08-09,2017-06-08
-7w3d,2022-09-07,2021-11-25
-5w3q,2017-08-09,2017-06-08
-3w3o,2014-01-01,2012-12-27
-2w3q,2008-12-30,2008-11-14
-3w3m,2013-04-03,2012-12-22
-2w3j,2009-01-20,2008-11-12
-3w3s,2013-02-13,2012-12-27
-3w33,2013-03-06,2012-12-07
-1w3o,2004-10-18,2004-07-17
-2w3g,2009-03-10,2008-11-12
-5w3k,2017-10-25,2017-06-08
-2w35,2009-01-20,2008-11-06
-6w3n,2020-06-10,2020-03-09
-7w31,2023-02-01,2021-11-24
-1w35,2005-07-26,2004-07-13
-7w3s,2022-04-06,2021-11-26
-5w3y,2017-08-09,2017-06-08
-7w3o,2022-12-07,2021-11-25
-2w31,2009-01-13,2008-11-05
-6w3a,2020-12-09,2020-03-09
-7w39,2022-05-04,2021-11-25
-3w34,2013-12-11,2012-12-10
-5w3z,2018-01-10,2017-06-08
-7w3k,2022-05-04,2021-11-25
-6w3e,2020-12-09,2020-03-09
-5w3c,2018-01-03,2017-06-07
-1w3m,2005-07-27,2004-07-16
-1w37,2004-09-02,2004-07-13
-3w38,2013-05-29,2012-12-13
-2w3z,2008-12-02,2008-11-17
-2w3b,2009-11-17,2008-11-11
-5w3i,2017-12-27,2017-06-07
-7w3v,2022-06-22,2021-11-26
-7w37,2022-05-04,2021-11-25
-1w3x,2005-12-07,2004-07-20
-7w3r,2022-06-01,2021-11-26
-5w30,2018-01-03,2017-06-07
-1w31,2005-08-23,2004-07-11
-7w3a,2022-05-04,2021-11-25
-7w3g,2022-05-04,2021-11-25
-1w3l,2004-09-08,2004-07-16
-6w3x,2020-05-20,2020-03-09
-6w3l,2020-06-10,2020-03-09
-6w3y,2020-05-20,2020-03-09
-2w3t,2009-12-15,2008-11-14
-2w3x,2009-04-07,2008-11-17
-3w3k,2013-04-03,2012-12-22
-7w38,2022-05-04,2021-11-25
-6w35,2020-07-08,2020-03-09
-2w37,2009-11-17,2008-11-06
-7w33,2023-05-31,2021-11-25
-2w3o,2009-02-03,2008-11-13
-5w39,2018-01-03,2017-06-07
-6w3o,2020-05-20,2020-03-09
-1w3f,2005-02-01,2004-07-15
-2w39,2009-07-21,2008-11-07
-2w3k,2009-04-07,2008-11-12
-2w3a,2009-11-17,2008-11-10
-6w3v,2020-05-20,2020-03-09
-6w3h,2020-06-10,2020-03-09
-2w3f,2009-03-10,2008-11-12
-3w3l,2013-04-03,2012-12-22
-5w3u,2017-12-20,2017-06-08
-1w3s,2005-02-23,2004-07-18
-1w3c,2004-12-09,2004-07-14
-1w3a,2005-02-01,2004-07-14
-5w34,2018-03-28,2017-06-07
-5w35,2018-03-28,2017-06-07
-3w3a,2013-05-15,2012-12-14
-5w3s,2017-10-11,2017-06-08
-6w3z,2020-11-04,2020-03-09
-1w3w,2005-01-18,2004-07-20
-2w3e,2009-03-10,2008-11-12
-7w3b,2022-05-04,2021-11-25
-7w3m,2022-05-18,2021-11-25
-2w3u,2009-12-15,2008-11-14
-1w3k,2004-09-08,2004-07-16
-5w36,2018-03-28,2017-06-07
-1w36,2004-11-04,2004-07-13
-5w3j,2017-07-19,2017-06-07
-5w3a,2018-01-03,2017-06-07
-7w32,2023-02-01,2021-11-24
-7w3h,2022-05-04,2021-11-25
-7w34,2023-05-31,2021-11-25
-7w3f,2022-05-04,2021-11-25
-2w3v,2009-11-17,2008-11-16
-5w3f,2017-07-19,2017-06-07
-1w3v,2005-12-07,2004-07-20
-1w3h,2004-09-30,2004-07-15
-1w3i,2004-09-02,2004-07-15
-1w3g,2005-02-01,2004-07-15
-6w39,2020-12-09,2020-03-09
-3w39,2013-02-13,2012-12-13
-1w3y,2004-08-26,2004-07-21
-7w3l,2022-09-14,2021-11-25
-7w3e,2022-12-07,2021-11-25
-5w32,2018-01-03,2017-06-07
-7w35,2023-02-01,2021-11-25
-2w3s,2008-12-23,2008-11-14
-1w32,2004-09-30,2004-07-12
-7w3u,2022-06-01,2021-11-26
-3w32,2013-03-06,2012-12-07
-7w3j,2022-05-04,2021-11-25
-3w3y,2013-04-10,2012-12-28
-5w3w,2018-01-10,2017-06-08
-3w37,2013-05-29,2012-12-13
-1w3j,2004-09-08,2004-07-16
-1w3r,2004-10-18,2004-07-17
-6w3k,2020-12-09,2020-03-09
-7w3t,2022-06-22,2021-11-26
-2w3h,2009-03-10,2008-11-12
-7w3q,2022-12-07,2021-11-25
-2w3r,2008-12-23,2008-11-14
-6w3t,2020-05-20,2020-03-09
-1w3u,2004-12-22,2004-07-20
-2w3n,2008-12-30,2008-11-13
-1w3b,2004-09-09,2004-07-14
-2w3l,2008-12-09,2008-11-13
-3w3n,2013-04-03,2012-12-22
-6w3p,2020-05-20,2020-03-09
-5w3d,2017-12-20,2017-06-07
-2w36,2009-01-20,2008-11-06
-8hpt,2023-10-18,2022-12-13
-5hpr,2017-01-25,2016-01-21
-4hp1,2012-12-05,2012-10-23
-4hp3,2012-12-05,2012-10-23
-4hpk,2012-12-12,2012-10-24
-6hpf,2019-03-06,2018-09-20
-1hpx,1996-03-08,1995-05-18
-8hpx,2023-12-13,2022-12-13
-5hpi,2016-09-07,2016-01-20
-6hpd,2019-07-24,2018-09-20
-3hpt,2009-11-17,2009-06-04
-8hpf,2023-12-20,2022-12-12
-1hpu,2002-03-20,2000-12-13
-2hpp,1994-01-31,1993-04-28
-6hpr,2018-12-12,2018-09-21
-5hp4,2016-06-01,2016-01-20
-1hpg,1995-07-10,1993-04-28
-8hpd,2023-09-06,2022-12-12
-5hpj,2016-12-07,2016-01-20
-8hpw,2023-12-13,2022-12-13
-5hp5,2016-07-27,2016-01-20
-2hpt,2006-08-15,2006-07-17
-3hph,2009-07-28,2009-06-04
-5hp3,2016-04-13,2016-01-20
-8hpc,2023-12-20,2022-12-12
-8hpi,2023-12-13,2022-12-12
-5hp6,2017-02-01,2016-01-20
-5hp0,2016-03-16,2016-01-19
-6hpp,2019-10-09,2018-09-21
-1hpc,1995-05-08,1994-02-17
-2hph,2007-03-20,2006-07-17
-4hpc,2013-03-20,2012-10-23
-1hpz,2001-05-30,2000-12-13
-4hpb,2013-03-20,2012-10-23
-3hpg,2009-07-28,2009-06-04
-8hpl,2023-09-06,2022-12-12
-1hpl,1994-05-31,1993-01-27
-5hpz,2016-05-04,2016-01-21
-3hpj,2010-06-23,2009-06-04
-6hpe,2019-04-24,2018-09-20
-8hpo,2023-05-03,2022-12-12
-8hps,2023-09-06,2022-12-12
-6hp5,2019-02-20,2018-09-19
-8hpu,2023-12-20,2022-12-13
-6hph,2019-01-23,2018-09-20
-4hpw,2013-10-30,2012-10-24
-6hpo,2019-06-05,2018-09-21
-6hpg,2018-10-03,2018-09-20
-4hpg,2013-11-27,2012-10-23
-2hpc,2007-05-29,2006-07-17
-3hpo,2010-06-23,2009-06-04
-5hpm,2016-06-15,2016-01-20
-3hp5,2009-09-29,2009-06-03
-6hpz,2018-11-28,2018-09-22
-8hpy,2023-12-13,2022-12-13
-6hpu,2019-01-23,2018-09-21
-2hp1,2006-08-22,2006-07-17
-3hpx,2010-05-19,2009-06-05
-5hp1,2016-06-01,2016-01-19
-4hpp,2012-12-26,2012-10-24
-8hp9,2024-01-31,2022-12-12
-3hp9,2010-01-19,2009-06-03
-5hpb,2017-01-25,2016-01-20
-8hp3,2023-12-13,2022-12-11
-6hpq,2019-01-23,2018-09-21
-3hpz,2010-05-19,2009-06-05
-2hps,2007-01-09,2006-07-17
-3hpi,2010-02-09,2009-06-04
-5hph,2016-08-10,2016-01-20
-6hp0,2019-09-11,2018-09-19
-6hps,2019-10-23,2018-09-21
-5hpe,2016-07-27,2016-01-20
-3hpr,2009-11-03,2009-06-04
-3hp2,2009-09-29,2009-06-03
-8hpr,2023-09-06,2022-12-12
-8hpv,2024-01-31,2022-12-13
-4hpa,2013-03-20,2012-10-23
-3hpv,2009-10-20,2009-06-05
-1hpo,1997-04-21,1996-12-10
-5hpy,2016-07-13,2016-01-21
-1hp5,2001-04-04,2000-12-12
-4hpu,2013-03-20,2012-10-24
-5hp8,2016-10-12,2016-01-20
-4hpo,2013-02-06,2012-10-24
-5hpd,2016-03-16,2016-01-20
-8hpn,2023-09-06,2022-12-12
-2hpy,2006-08-22,2006-07-18
-3hpa,2009-06-16,2009-06-03
-4hpj,2013-12-25,2012-10-23
-6hpj,2020-11-18,2018-09-21
-3hpy,2009-10-20,2009-06-05
-2hpl,2007-05-29,2006-07-17
-1hps,1994-08-31,1994-05-24
-3hp3,2010-01-26,2009-06-03
-1hp0,2001-12-12,2000-12-12
-3hpl,2010-06-23,2009-06-04
-1hpv,1995-03-31,1994-11-18
-4hpt,2013-03-20,2012-10-24
-1hp7,2001-03-14,2000-12-12
-4hpd,2013-03-20,2012-10-23
-1hpm,1995-07-31,1995-03-24
-4hp0,2013-01-16,2012-10-23
-8hp6,2023-06-21,2022-12-12
-2hp5,2007-07-03,2006-07-17
-2hp2,2006-08-22,2006-07-17
-8hp4,2024-01-17,2022-12-11
-5hpo,2017-01-25,2016-01-20
-4hph,2013-10-16,2012-10-23
-6hp8,2019-07-31,2018-09-19
-6hp9,2019-01-30,2018-09-19
-5hpu,2017-01-25,2016-01-21
-1hp1,2002-03-20,2000-12-12
-4hp2,2013-10-02,2012-10-23
-3hps,2010-05-19,2009-06-04
-2hpv,2006-09-12,2006-07-17
-2hpa,1998-09-16,1998-09-11
-1hpk,1997-03-12,1996-08-14
-3hpf,2009-12-22,2009-06-04
-8hp7,2023-06-21,2022-12-12
-8hpm,2023-09-06,2022-12-12
-5hpw,2016-04-20,2016-01-21
-2hpq,1994-01-31,1993-04-28
-4hpn,2012-11-07,2012-10-24
-3hp6,2010-06-23,2009-06-03
-5hp2,2016-04-13,2016-01-20
-6hp2,2019-10-09,2018-09-19
-6hpv,2019-02-20,2018-09-22
-3hp1,2009-06-16,2009-06-03
-8hpq,2024-01-31,2022-12-12
-4hp5,2013-11-13,2012-10-23
-4hp8,2012-11-07,2012-10-23
-8hpk,2023-02-15,2022-12-12
-6hpy,2018-11-28,2018-09-22
-6hpx,2018-11-28,2018-09-22
-4hpi,2013-01-16,2012-10-23
-2hpm,2006-09-19,2006-07-17
-2hpo,2006-08-15,2006-07-17
-6hpw,2018-11-28,2018-09-22
-3hp8,2009-06-23,2009-06-03
-2hpz,2006-08-01,2006-07-18
-3hpq,2009-11-03,2009-06-04
-2hpi,2006-09-19,2006-07-17
-4hpx,2013-12-18,2012-10-24
-2hpd,1993-10-31,1993-09-16
-5hpp,2016-08-10,2016-01-20
-6cse,2019-01-30,2018-03-20
-8cst,2022-12-14,2022-05-13
-2csm,1996-12-23,1995-11-24
-8csb,2022-11-09,2022-05-12
-1csy,1996-11-08,1995-10-03
-4csm,1998-01-14,1997-07-14
-7csw,2021-01-13,2020-08-17
-4csc,1991-04-15,1990-05-07
-2cs7,2006-02-14,2005-05-20
-3cs8,2008-06-03,2008-04-09
-5cs5,2015-08-12,2015-07-23
-3csh,2008-07-01,2008-04-09
-5csz,2015-08-12,2015-07-23
-7cs1,2021-06-23,2020-08-14
-8csu,2022-12-14,2022-05-13
-7cs7,2021-06-09,2020-08-14
-8cso,2022-06-08,2022-05-13
-7cs4,2021-06-09,2020-08-14
-7csz,2021-02-03,2020-08-17
-6csw,2018-04-04,2018-03-21
-8csc,2022-11-09,2022-05-12
-1csu,1995-01-26,1994-10-04
-3csy,2008-07-08,2008-04-10
-2cs8,2005-11-20,2005-05-20
-8csq,2022-12-14,2022-05-13
-4cs3,2014-04-30,2014-03-04
-3cs6,2008-05-27,2008-04-09
-2csh,2005-11-21,2005-05-21
-3csd,2009-04-14,2008-04-09
-3csq,2008-07-01,2008-04-10
-6css,2018-05-30,2018-03-21
-8csj,2023-05-17,2022-05-12
-6cs8,2018-08-22,2018-03-19
-2csb,2006-01-31,2005-05-21
-1cs1,1999-09-27,1998-09-23
-3cst,2008-05-20,2008-04-10
-4cst,2015-02-25,2014-03-10
-1csn,1995-07-31,1995-04-25
-3csw,2008-04-22,2008-04-10
-6csr,2018-05-30,2018-03-21
-8csp,2022-12-14,2022-05-13
-1csi,1994-04-30,1994-03-07
-2csz,2005-11-23,2005-05-23
-1csm,1995-09-15,1994-08-22
-5cs3,2015-08-12,2015-07-23
-8csd,2022-11-09,2022-05-12
-7csh,2021-06-09,2020-08-14
-5css,2016-06-08,2015-07-23
-5cs6,2016-07-27,2015-07-23
-4cs9,2014-05-28,2014-03-05
-3csv,2008-04-22,2008-04-10
-4cs7,2014-05-28,2014-03-05
-2cs3,2005-11-20,2005-05-20
-2cs2,2005-11-20,2005-05-20
-8cs9,2022-07-20,2022-05-12
-5csy,2015-11-04,2015-07-23
-7csa,2021-06-09,2020-08-14
-6cso,2018-09-05,2018-03-21
-7cs8,2021-06-09,2020-08-14
-3cs7,2008-07-08,2008-04-09
-5csp,2016-07-27,2015-07-23
-6cs2,2018-04-11,2018-03-19
-6csc,1997-12-24,1997-06-19
-3csz,2008-07-01,2008-04-10
-5csu,2015-11-04,2015-07-23
-6csf,2019-01-30,2018-03-20
-6cs9,2018-07-25,2018-03-20
-1cs4,2001-01-10,1999-08-16
-5cst,2015-08-12,2015-07-23
-1csb,1996-04-03,1994-12-09
-3cso,2009-04-14,2008-04-10
-5csm,1998-01-14,1997-07-14
-4csf,2014-04-09,2014-03-07
-1cse,1988-07-16,1988-06-03
-4csd,2014-10-08,2014-03-06
-6cst,2019-01-30,2018-03-21
-4csp,2014-07-30,2014-03-09
-6csd,2019-03-27,2018-03-20
-4csy,2014-09-24,2014-03-11
-1csv,1995-01-26,1994-10-04
-7csb,2021-06-09,2020-08-14
-8csz,2022-06-15,2022-05-13
-5cse,2015-11-04,2015-07-23
-8csr,2022-12-14,2022-05-13
-7csc,2021-06-09,2020-08-14
-4csw,2014-04-09,2014-03-11
-6csp,2018-05-30,2018-03-21
-4cs8,2014-05-28,2014-03-05
-5csh,2016-07-27,2015-07-23
-2csc,1991-04-15,1990-05-07
-3csm,1998-01-14,1997-07-10
-4csi,2014-09-10,2014-03-07
-8css,2022-12-14,2022-05-13
-1cs3,1999-08-27,1999-08-16
-5csl,2015-10-28,2015-07-23
-7cs3,2021-06-09,2020-08-14
-7cs5,2021-06-09,2020-08-14
-2csv,2005-11-23,2005-05-23
-3cs4,2008-05-27,2008-04-09
-5csx,2016-03-09,2015-07-23
-5csf,2015-11-11,2015-07-23
-3csk,2008-06-10,2008-04-10
-4csh,2014-08-06,2014-03-07
-5cs8,2016-01-13,2015-07-23
-3csf,2008-05-27,2008-04-09
-3csx,2008-06-10,2008-04-10
-1csh,1994-04-30,1994-03-07
-7csf,2021-06-09,2020-08-14
-3csc,1991-04-15,1990-05-07
-8csx,2022-07-20,2022-05-13
-4css,2015-02-25,2014-03-10
-3cs9,2008-04-22,2008-04-09
-6csl,2018-06-13,2018-03-20
-2csy,2005-11-23,2005-05-23
-1csc,1991-04-15,1990-05-07
-3cs2,2009-02-17,2008-04-08
-4cs4,2014-04-30,2014-03-04
-6csn,2018-09-05,2018-03-21
-5csw,2016-03-09,2015-07-23
-8csg,2022-10-05,2022-05-12
-5cso,2015-08-12,2015-07-23
-1cs0,1999-12-10,1999-08-16
-4csz,2014-07-30,2014-03-11
-8cse,2022-11-09,2022-05-12
-5csv,2016-07-27,2015-07-23
-1csw,1995-01-26,1994-10-04
-1csr,1995-10-15,1995-08-04
-2cst,1994-11-30,1994-09-06
-3csb,2008-07-22,2008-04-09
-3cse,2008-11-25,2008-04-09
-8csf,2022-11-09,2022-05-12
-6csq,2018-05-30,2018-03-21
-4csa,2014-05-28,2014-03-05
-7csj,2021-06-23,2020-08-14
-4csj,2014-05-07,2014-03-07
-5csi,2015-11-11,2015-07-23
-3csj,2008-07-01,2008-04-09
-6csm,2018-09-05,2018-03-21
-1css,1995-10-15,1995-08-04
-5cs2,2015-10-28,2015-07-23
-7csi,2021-06-23,2020-08-14
-1csx,1995-01-26,1994-10-04
-7csd,2021-06-09,2020-08-14
-3csl,2009-01-20,2008-04-10
-5csj,2015-11-11,2015-07-23
-7cse,2021-06-09,2020-08-14
-2csg,2005-07-05,2005-05-21
-6cs1,2018-04-11,2018-03-19
-6cs0,2018-04-11,2018-03-19
-4csv,2015-03-04,2014-03-10
-3csi,2008-07-01,2008-04-09
-7cs6,2021-06-09,2020-08-14
-4cse,2014-05-14,2014-03-07
-3csu,1999-05-11,1999-04-22
-6csb,2019-03-27,2018-03-20
-7cs0,2021-06-23,2020-08-14
-4cs0,2015-03-25,2014-03-02
-2csn,1996-03-08,1995-10-11
-5csn,2015-11-11,2015-07-23
-1csz,1996-11-08,1995-10-03
-5i4m,2016-03-02,2016-02-12
-6i4i,2019-06-26,2018-11-09
-3i4m,2009-09-08,2009-07-02
-1i4a,2001-04-25,2001-02-20
-6i4g,2019-06-26,2018-11-09
-6i46,2019-12-18,2018-11-09
-1i4w,2001-10-03,2001-02-23
-6i4r,2019-11-20,2018-11-10
-5i43,2016-07-06,2016-02-11
-3i44,2009-07-14,2009-07-01
-8i4z,2023-02-22,2023-01-21
-2i4o,2006-10-24,2006-08-22
-4i4h,2013-04-24,2012-11-27
-2i4n,2006-10-24,2006-08-22
-4i4w,2013-01-02,2012-11-28
-3i4l,2010-01-12,2009-07-01
-1i4g,2001-02-28,2001-02-21
-6i43,2019-09-18,2018-11-08
-5i4o,2016-07-06,2016-02-12
-6i4k,2019-06-26,2018-11-09
-3i4k,2009-07-14,2009-07-01
-2i4c,2006-12-19,2006-08-21
-6i40,2019-09-11,2018-11-08
-1i48,2001-09-05,2001-02-20
-4i4t,2013-01-23,2012-11-28
-6i4p,2019-11-20,2018-11-10
-4i4s,2013-04-24,2012-11-28
-6i4d,2019-06-26,2018-11-09
-5i4e,2017-09-13,2016-02-11
-5i4k,2016-02-24,2016-02-12
-2i40,2006-10-10,2006-08-21
-3i49,2009-08-25,2009-07-01
-1i4p,2001-03-14,2001-02-22
-3i4n,2009-09-08,2009-07-02
-4i45,2013-02-27,2012-11-27
-5i49,2016-11-09,2016-02-11
-8i4k,2023-11-01,2023-01-19
-8i4d,2024-01-24,2023-01-19
-2i4z,2007-04-17,2006-08-23
-4i4u,2013-04-24,2012-11-28
-4i4l,2013-05-15,2012-11-27
-5i4l,2016-06-22,2016-02-12
-3i4q,2009-07-28,2009-07-02
-8i4a,2023-05-24,2023-01-19
-3i48,2010-07-14,2009-07-01
-3i4c,2009-07-21,2009-07-01
-1i4q,2001-03-14,2001-02-22
-6i4j,2019-06-26,2018-11-09
-3i4v,2010-01-12,2009-07-03
-3i4d,2010-12-01,2009-07-01
-2i44,2006-08-29,2006-08-21
-3i4i,2010-07-21,2009-07-01
-2i4g,2006-08-29,2006-08-21
-5i4z,2016-10-26,2016-02-13
-5i4r,2017-06-28,2016-02-12
-8i4p,2024-01-24,2023-01-20
-4i4x,2013-04-24,2012-11-28
-6i4t,2019-11-20,2018-11-10
-4i48,2013-10-02,2012-11-27
-1i4r,2001-03-14,2001-02-22
-6i4e,2019-06-26,2018-11-09
-5i46,2016-06-22,2016-02-11
-6i4z,2019-11-20,2018-11-12
-4i4v,2013-04-24,2012-11-28
-5i4v,2016-06-29,2016-02-12
-5i40,2016-10-12,2016-02-11
-8i4c,2023-05-24,2023-01-19
-4i4g,2013-04-24,2012-11-27
-6i41,2019-05-08,2018-11-08
-8i4s,2023-11-29,2023-01-21
-5i4f,2016-12-21,2016-02-12
-1i4l,2001-05-16,2001-02-22
-4i4f,2013-02-06,2012-11-27
-4i49,2013-01-09,2012-11-27
-1i41,2001-09-05,2001-02-19
-5i4n,2016-04-13,2016-02-12
-2i4v,2007-08-28,2006-08-22
-6i4h,2019-06-26,2018-11-09
-8i4q,2023-07-26,2023-01-20
-8i4o,2023-11-29,2023-01-20
-4i4z,2013-05-08,2012-11-28
-1i4t,2001-05-16,2001-02-23
-1i4m,2002-02-27,2001-02-22
-2i4b,2006-12-19,2006-08-21
-5i4j,2017-02-01,2016-02-12
-6i47,2019-12-18,2018-11-09
-8i4t,2023-09-13,2023-01-21
-8i40,2024-01-31,2023-01-18
-2i4d,2007-08-21,2006-08-21
-4i42,2013-05-08,2012-11-27
-1i4h,2001-02-28,2001-02-21
-3i4b,2010-01-12,2009-07-01
-6i49,2019-12-18,2018-11-09
-3i4a,2009-08-25,2009-07-01
-1i4d,2001-05-16,2001-02-20
-3i46,2010-07-14,2009-07-01
-4i40,2013-11-27,2012-11-27
-8i4y,2023-02-22,2023-01-21
-8i4i,2023-04-12,2023-01-19
-2i4m,2006-10-24,2006-08-22
-2i4j,2007-04-17,2006-08-22
-4i41,2013-12-11,2012-11-27
-5i48,2016-07-06,2016-02-11
-6i4l,2019-06-26,2018-11-09
-6i4m,2019-06-26,2018-11-09
-2i47,2006-12-05,2006-08-21
-2i4t,2007-06-05,2006-08-22
-4i4y,2013-04-24,2012-11-28
-6i4v,2019-11-20,2018-11-12
-1i40,2001-12-05,2001-02-19
-6i4u,2019-11-20,2018-11-10
-6i4f,2019-06-26,2018-11-09
-8i49,2024-01-24,2023-01-18
-2i4w,2007-08-28,2006-08-22
-1i4x,2001-03-14,2001-02-23
-6i4a,2019-12-18,2018-11-09
-6i4b,2018-12-19,2018-11-09
-3i45,2009-07-14,2009-07-01
-4i4e,2013-03-06,2012-11-27
-6i48,2019-12-18,2018-11-09
-6i45,2020-02-26,2018-11-09
-2i4p,2007-04-17,2006-08-22
-3i4p,2009-07-28,2009-07-02
-4i4c,2013-10-09,2012-11-27
-2i4h,2006-08-29,2006-08-21
-2i4q,2006-10-24,2006-08-22
-4i4b,2013-07-17,2012-11-27
-3i4y,2010-01-12,2009-07-03
-2i4x,2007-08-28,2006-08-22
-1i43,2001-09-05,2001-02-19
-5i4u,2017-02-22,2016-02-12
-5i42,2016-06-01,2016-02-11
-2i4u,2007-08-28,2006-08-22
-3i4x,2009-09-01,2009-07-03
-6i4s,2019-11-20,2018-11-10
-6i4y,2019-03-20,2018-11-12
-6i44,2019-03-06,2018-11-09
-6i4q,2019-11-20,2018-11-10
-3i4z,2009-09-01,2009-07-03
-1i44,2001-03-07,2001-02-19
-4i47,2012-12-12,2012-11-27
-5i4b,2016-07-06,2016-02-11
-6i4x,2019-05-29,2018-11-12
-2i4i,2006-09-05,2006-08-22
-5i4d,2016-02-24,2016-02-11
-8i4r,2024-01-24,2023-01-20
-1gxw,2002-12-05,2002-04-12
-8gxp,2023-06-07,2022-09-20
-8gxq,2022-11-02,2022-09-21
-3gxl,2009-04-21,2009-04-02
-3gxr,2009-10-20,2009-04-02
-5gxp,2016-11-02,2016-09-19
-3gxo,2010-04-21,2009-04-02
-5gxv,2017-07-19,2016-09-20
-6gxw,2018-08-15,2018-06-27
-2gxa,2006-07-25,2006-05-08
-3gxe,2010-04-07,2009-04-02
-4gx4,2013-09-04,2012-09-03
-5gxz,2017-09-27,2016-09-21
-4gxu,2012-12-19,2012-09-04
-3gxk,2009-10-20,2009-04-02
-5gx4,2017-01-04,2016-09-15
-6gxo,2018-08-15,2018-06-27
-2gx2,2007-05-08,2006-05-08
-2gx6,2007-03-20,2006-05-08
-5gx3,2017-01-04,2016-09-15
-6gx1,2019-07-10,2018-06-26
-3gxa,2009-10-13,2009-04-02
-4gxi,2013-01-16,2012-09-04
-4gxr,2012-10-24,2012-09-04
-2gx4,2007-05-08,2006-05-08
-1gx6,2002-04-10,2002-03-27
-5gx1,2017-01-04,2016-09-15
-8gx3,2023-09-20,2022-09-18
-4gx5,2012-12-26,2012-09-03
-5gxe,2017-09-20,2016-09-17
-5gxg,2017-01-18,2016-09-17
-3gx0,2009-07-07,2009-04-01
-3gxp,2009-05-05,2009-04-02
-4gxw,2012-09-12,2012-09-04
-6gxk,2019-05-08,2018-06-27
-8gx9,2022-10-12,2022-09-19
-4gxe,2013-03-06,2012-09-04
-8gx2,2023-09-20,2022-09-18
-1gx1,2002-04-03,2002-03-26
-3gxz,2009-04-14,2009-04-03
-6gxn,2018-08-15,2018-06-27
-6gxm,2018-08-22,2018-06-27
-1gx5,2002-04-09,2002-03-27
-8gxg,2023-09-27,2022-09-20
-3gxn,2009-05-05,2009-04-02
-8gx4,2023-09-20,2022-09-18
-1gxr,2002-06-13,2002-04-10
-8gxz,2023-01-25,2022-09-21
-3gxm,2009-05-05,2009-04-02
-3gxt,2009-05-26,2009-04-02
-6gxz,2018-08-08,2018-06-27
-3gxf,2009-05-05,2009-04-02
-6gxd,2018-10-17,2018-06-27
-6gxu,2018-08-15,2018-06-27
-6gxj,2019-02-06,2018-06-27
-6gxv,2019-01-23,2018-06-27
-1gx0,2003-03-20,2002-03-26
-1gxb,2003-04-03,2002-04-02
-8gxf,2022-10-19,2022-09-20
-5gx6,2017-07-26,2016-09-15
-4gxm,2012-10-03,2012-09-04
-4gxq,2012-10-24,2012-09-04
-6gx3,2018-08-15,2018-06-26
-8gxk,2022-10-12,2022-09-20
-8gxu,2023-01-25,2022-09-21
-6gx2,2019-07-10,2018-06-26
-8gxh,2023-09-27,2022-09-20
-8gxd,2023-04-26,2022-09-19
-1gxs,2002-10-01,2002-04-11
-5gx8,2017-07-19,2016-09-15
-4gx1,2012-12-26,2012-09-03
-4gxf,2012-09-19,2012-09-04
-4gxj,2013-01-16,2012-09-04
-4gxn,2013-02-06,2012-09-04
-4gxk,2013-01-16,2012-09-04
-6gxx,2019-07-10,2018-06-27
-1gxd,2002-07-09,2002-04-02
-8gxs,2022-11-02,2022-09-21
-2gx5,2007-04-17,2006-05-08
-3gxd,2009-05-05,2009-04-02
-8gxc,2023-01-18,2022-09-19
-5gxu,2017-01-25,2016-09-20
-1gxc,2002-06-13,2002-04-02
-1gxf,2004-05-06,2002-04-04
-1gx4,2003-03-27,2002-03-27
-1gx8,2002-06-13,2002-03-29
-5gxo,2017-08-09,2016-09-19
-6gxb,2019-05-08,2018-06-27
-3gxi,2009-05-05,2009-04-02
-6gx6,2018-09-05,2018-06-26
-5gx7,2017-07-19,2016-09-15
-4gx3,2013-09-04,2012-09-03
-1gxz,2002-09-26,2002-04-15
-8gxw,2023-01-25,2022-09-21
-5gx2,2017-01-04,2016-09-15
-5gx9,2017-08-30,2016-09-16
-4gx0,2012-12-26,2012-09-03
-4gx7,2013-01-02,2012-09-04
-1gx9,2002-06-13,2002-03-29
-8gxn,2023-09-20,2022-09-20
-8gxv,2023-09-27,2022-09-21
-1gx2,2003-03-28,2002-03-26
-1gx7,2003-07-31,2002-03-28
-6gx8,2018-08-22,2018-06-26
-5gxt,2017-07-19,2016-09-20
-5gxd,2017-09-20,2016-09-17
-2gxb,2007-05-01,2006-05-08
-6gx4,2018-12-05,2018-06-26
-6gx0,2019-07-10,2018-06-26
-6gx9,2019-03-13,2018-06-26
-6gxc,2018-11-14,2018-06-27
-6gx7,2019-04-24,2018-06-26
-6gxa,2018-08-15,2018-06-27
-4gx2,2012-12-26,2012-09-03
-8gxi,2023-09-27,2022-09-20
-4gx6,2013-09-04,2012-09-03
-6gxy,2019-01-16,2018-06-27
-3gxb,2009-05-05,2009-04-02
-5gxy,2017-09-27,2016-09-21
-2gx8,2006-05-16,2006-05-08
-6gxt,2018-10-17,2018-06-27
-3gxy,2009-05-05,2009-04-03
-3gxw,2009-05-26,2009-04-03
-1gxo,2002-10-04,2002-04-08
-6gxq,2019-07-10,2018-06-27
-5gx5,2017-01-04,2016-09-15
-8gxb,2023-01-18,2022-09-19
-8gxx,2023-01-25,2022-09-21
-6gxp,2018-08-15,2018-06-27
-6gxg,2019-01-16,2018-06-27
-2gxq,2006-08-22,2006-05-09
-2gxs,2006-08-22,2006-05-09
-8gxo,2023-09-13,2022-09-20
-4gxs,2012-10-17,2012-09-04
-6gxe,2019-05-08,2018-06-27
-5gxx,2017-09-27,2016-09-21
-4gxx,2012-12-19,2012-09-04
-3gx9,2009-05-26,2009-04-02
-2o2r,2007-03-06,2006-11-30
-5o2x,2017-09-20,2017-05-23
-3o2x,2011-08-10,2010-07-22
-1o2v,2003-09-02,2003-03-06
-7o27,2021-09-15,2021-03-30
-1o2n,2003-05-13,2003-03-06
-2o2m,2007-02-27,2006-11-30
-3o28,2010-09-15,2010-07-22
-2o2z,2006-12-19,2006-11-30
-7o26,2021-05-26,2021-03-30
-1o2e,2003-09-09,2003-03-05
-2o2n,2007-02-27,2006-11-30
-7o2a,2021-07-07,2021-03-30
-4o2d,2014-01-22,2013-12-17
-7o2l,2022-04-13,2021-03-30
-5o2y,2017-10-18,2017-05-23
-5o27,2017-11-15,2017-05-19
-2o2y,2006-12-26,2006-11-30
-1o2k,2003-05-13,2003-03-06
-1o2a,2003-06-24,2003-02-18
-5o2d,2017-11-08,2017-05-20
-1o2y,2003-09-02,2003-03-06
-3o2g,2010-09-15,2010-07-22
-2o2u,2007-02-27,2006-11-30
-5o2n,2018-03-14,2017-05-22
-7o2t,2022-04-13,2021-03-31
-1o2s,2003-09-02,2003-03-06
-4o2l,2014-03-26,2013-12-17
-7o2c,2021-07-07,2021-03-30
-3o2j,2011-03-09,2010-07-22
-6o25,2020-07-01,2019-02-22
-2o28,2006-12-12,2006-11-29
-1o2q,2003-09-02,2003-03-06
-3o2m,2011-01-12,2010-07-22
-2o2q,2007-03-06,2006-11-30
-4o24,2014-01-15,2013-12-16
-2o21,2007-02-27,2006-11-29
-2o2l,2007-08-14,2006-11-30
-5o2b,2017-06-28,2017-05-19
-1o2d,2003-06-10,2003-02-27
-6o2q,2019-05-22,2019-02-24
-7o20,2021-09-01,2021-03-30
-6o2a,2020-07-01,2019-02-22
-3o2q,2010-10-06,2010-07-22
-7o2r,2021-10-27,2021-03-31
-1o2p,2003-05-13,2003-03-06
-7o23,2022-06-29,2021-03-30
-1o2j,2003-05-13,2003-03-06
-1o2w,2003-09-02,2003-03-06
-4o2r,2014-03-26,2013-12-17
-5o2o,2018-06-13,2017-05-22
-7o2y,2022-04-13,2021-03-31
-3o20,2012-01-25,2010-07-22
-1o2l,2003-05-13,2003-03-06
-4o2z,2014-01-22,2013-12-17
-4o2i,2014-01-15,2013-12-17
-7o2s,2022-04-13,2021-03-31
-6o2z,2019-06-26,2019-02-25
-2o23,2006-12-12,2006-11-29
-5o2z,2017-11-08,2017-05-23
-3o29,2010-09-15,2010-07-22
-1o2t,2003-09-02,2003-03-06
-1o25,2003-06-24,2003-02-20
-3o2w,2011-07-20,2010-07-22
-6o2p,2019-06-26,2019-02-24
-4o27,2014-12-03,2013-12-16
-4o2b,2014-03-05,2013-12-17
-7o2u,2022-04-13,2021-03-31
-1o26,2003-06-24,2003-02-18
-6o2r,2019-05-22,2019-02-24
-5o2s,2017-07-26,2017-05-22
-5o2t,2017-07-26,2017-05-22
-4o29,2014-01-15,2013-12-17
-4o21,2014-05-28,2013-12-16
-7o2i,2021-04-14,2021-03-30
-1o2i,2003-05-13,2003-03-06
-7o29,2021-09-01,2021-03-30
-7o2x,2021-04-07,2021-03-31
-7o2v,2021-10-20,2021-03-31
-5o2f,2018-12-26,2017-05-20
-1o2r,2003-09-02,2003-03-06
-6o20,2019-04-24,2019-02-22
-2o2c,2007-11-13,2006-11-29
-7o2g,2021-09-15,2021-03-30
-1o2z,2003-09-02,2003-03-06
-1o28,2003-06-24,2003-02-18
-1o2g,2003-05-13,2003-03-06
-3o2c,2010-11-03,2010-07-22
-7o2b,2021-07-07,2021-03-30
-1o2u,2003-09-02,2003-03-06
-1o27,2003-06-24,2003-02-18
-7o2m,2022-04-06,2021-03-30
-5o22,2018-02-28,2017-05-19
-1o2m,2003-05-13,2003-03-06
-3o23,2011-05-04,2010-07-22
-3o2n,2011-08-03,2010-07-22
-5o2w,2017-09-20,2017-05-23
-3o2e,2010-10-13,2010-07-22
-2o26,2007-03-13,2006-11-29
-5o2l,2018-05-23,2017-05-22
-2o2s,2006-12-26,2006-11-30
-3o2b,2011-12-14,2010-07-22
-6o21,2019-03-13,2019-02-22
-2o2f,2007-02-27,2006-11-29
-1o2x,2003-09-02,2003-03-06
-4o28,2014-10-22,2013-12-17
-7o2f,2021-09-01,2021-03-30
-7o25,2021-05-26,2021-03-30
-4o25,2014-03-26,2013-12-16
-1o2h,2003-05-13,2003-03-06
-7o2h,2021-09-15,2021-03-30
-5o2r,2017-07-26,2017-05-22
-5o20,2017-08-02,2017-05-19
-5o2e,2018-12-26,2017-05-20
-7o2o,2022-04-13,2021-03-31
-4o23,2014-01-15,2013-12-16
-4o2f,2014-07-23,2013-12-17
-2o22,2007-02-27,2006-11-29
-3o2k,2010-12-08,2010-07-22
-1o2o,2003-05-13,2003-03-06
-4o2w,2014-01-15,2013-12-17
-4o2g,2014-06-18,2013-12-17
-2o2i,2007-11-13,2006-11-29
-6o2t,2019-05-22,2019-02-24
-7o2p,2021-10-27,2021-03-31
-3o21,2011-03-09,2010-07-22
-1o2b,2003-06-24,2003-02-18
-3o2f,2011-10-05,2010-07-22
-3o26,2010-12-15,2010-07-22
-6o2s,2019-05-22,2019-02-24
-7o28,2021-09-15,2021-03-30
-7o2d,2021-09-15,2021-03-30
-1o29,2003-06-24,2003-02-18
-1o23,2003-02-25,2003-01-29
-4o2a,2014-03-05,2013-12-17
-5o26,2017-06-28,2017-05-19
-4o2e,2014-07-23,2013-12-17
-4o2p,2015-03-04,2013-12-17
-3o2a,2010-09-15,2010-07-22
-5o25,2017-10-25,2017-05-19
-7o22,2021-09-01,2021-03-30
-6o2y,2019-06-26,2019-02-25
-7o2e,2021-09-01,2021-03-30
-7o2z,2021-07-07,2021-04-01
-5kir,2016-09-28,2016-06-16
-7ki7,2021-10-27,2020-10-23
-7kig,2021-12-01,2020-10-23
-7kio,2020-11-25,2020-10-24
-2kii,2009-11-17,2009-05-05
-5kit,2016-08-31,2016-06-17
-4ki1,2014-03-05,2013-05-01
-5kiy,2017-12-20,2016-06-17
-2ki5,1999-03-04,1999-02-12
-2kib,2009-09-08,2009-05-01
-3ki1,2010-10-27,2009-10-31
-8ki5,2023-10-04,2023-08-22
-5kiw,2018-03-07,2016-06-17
-3kiv,1999-05-18,1998-09-08
-6kig,2020-02-12,2019-07-18
-5kic,2017-04-26,2016-06-16
-7kir,2020-11-25,2020-10-24
-6kid,2021-01-27,2019-07-18
-6kik,2019-09-25,2019-07-18
-4ki4,2013-10-09,2013-05-01
-7ki6,2021-05-05,2020-10-23
-5kiq,2017-05-24,2016-06-16
-2ki7,2009-09-15,2009-04-28
-1ki3,1999-05-18,1998-05-15
-6kiz,2019-09-11,2019-07-20
-4kiw,2014-05-14,2013-05-02
-1kit,1997-06-05,1996-06-21
-7kia,2021-02-10,2020-10-23
-6kif,2020-02-12,2019-07-18
-1kij,2002-06-03,2001-12-03
-7kiw,2021-01-13,2020-10-25
-1ki2,1998-12-02,1998-05-15
-4kit,2013-06-05,2013-05-02
-7ki8,2021-07-07,2020-10-23
-6kiw,2019-09-11,2019-07-20
-5kij,2017-05-10,2016-06-16
-4kis,2013-07-10,2013-05-02
-5kis,2017-08-09,2016-06-16
-5kia,2017-02-15,2016-06-16
-4kif,2014-05-07,2013-05-02
-7kid,2021-04-21,2020-10-23
-6kiv,2019-09-11,2019-07-20
-7ki4,2021-05-05,2020-10-23
-6kij,2019-08-07,2019-07-18
-1ki4,1998-12-02,1998-05-18
-3ki8,2010-11-24,2009-10-31
-1kif,1996-07-11,1996-01-19
-6kie,2021-01-27,2019-07-18
-8kih,2023-10-04,2023-08-23
-1kil,2002-03-13,2001-12-03
-7kil,2021-07-07,2020-10-23
-7ki9,2021-07-07,2020-10-23
-7kip,2020-11-11,2020-10-24
-4kig,2014-05-07,2013-05-02
-1kic,2002-05-15,2001-12-03
-6kiy,2019-09-25,2019-07-20
-3kif,2010-04-28,2009-11-02
-7kik,2021-11-17,2020-10-23
-4kiq,2013-06-12,2013-05-02
-7kij,2021-11-17,2020-10-23
-2kid,2009-07-21,2009-05-01
-4ki2,2013-09-04,2013-05-01
-4ki8,2013-07-17,2013-05-01
-6kix,2019-09-11,2019-07-20
-3kic,2010-04-28,2009-11-01
-1kiz,2002-03-13,2001-12-03
-3ki9,2010-07-07,2009-11-01
-5kid,2017-04-26,2016-06-16
-4ki7,2014-05-14,2013-05-01
-7kim,2021-04-21,2020-10-23
-7kie,2021-02-10,2020-10-23
-6kii,2020-07-22,2019-07-18
-2kik,2009-11-10,2009-05-06
-3ki7,2010-10-27,2009-10-31
-3ki6,2010-10-27,2009-10-31
-1ki6,1998-12-02,1998-05-18
-5kim,2017-04-12,2016-06-16
-6kia,2020-05-20,2019-07-17
-7kit,2021-01-13,2020-10-24
-4kiu,2014-05-14,2013-05-02
-6kih,2020-05-27,2019-07-18
-7kiv,2021-01-13,2020-10-24
-4kii,2013-09-04,2013-05-02
-3ki3,2010-10-27,2009-10-31
-1kiu,2002-06-05,2001-12-03
-8ki0,2024-03-27,2023-08-22
-3kin,1998-10-14,1997-08-25
-8ki1,2024-03-27,2023-08-22
-7ki0,2021-08-04,2020-10-22
-3kia,2010-11-03,2009-11-01
-7kic,2021-04-21,2020-10-23
-7kin,2021-04-21,2020-10-23
-1ki7,1998-12-02,1998-05-15
-7ki3,2021-10-06,2020-10-22
-6ki3,2020-05-27,2019-07-17
-4kip,2013-06-12,2013-05-02
-6ki8,2019-10-02,2019-07-17
-7kib,2021-04-21,2020-10-23
-1kib,2002-07-03,2001-12-03
-4kib,2014-05-07,2013-05-02
-4kir,2014-05-07,2013-05-02
-1kia,2003-06-10,2001-12-02
-4kik,2013-06-26,2013-05-02
-5kiv,2016-07-13,2016-06-17
-5kik,2017-04-26,2016-06-16
-7ki5,2021-08-18,2020-10-23
-3kih,2010-04-28,2009-11-02
-3ki4,2010-10-27,2009-10-31
-1kim,1998-05-20,1997-11-12
-7kii,2021-11-17,2020-10-23
-1ki8,1998-12-02,1998-05-15
-5kix,2016-06-29,2016-06-17
-4kil,2013-05-29,2013-05-02
-2kin,1998-04-08,1997-04-28
-6ki6,2019-09-11,2019-07-17
-3ki5,2010-10-27,2009-10-31
-3kig,2010-11-17,2009-11-02
-1kix,2002-02-22,2001-12-03
-4ki0,2013-10-23,2013-05-01
-7kiq,2021-07-07,2020-10-24
-4kic,2014-05-07,2013-05-02
-4kio,2013-08-21,2013-05-02
-6kiu,2019-09-11,2019-07-20
-6ki1,2019-11-20,2019-07-17
-4kin,2013-06-12,2013-05-02
-4ki6,2013-10-09,2013-05-01
-5kil,2017-04-26,2016-06-16
-7kif,2021-04-21,2020-10-23
-2kil,2009-11-17,2009-05-06
-3kii,2010-10-27,2009-11-02
-7kiu,2021-12-01,2020-10-24
-1kie,2002-05-15,2001-12-03
-2kiz,2010-05-19,2009-05-13
-3ki0,2010-10-27,2009-10-31
-3kie,2010-04-28,2009-11-01
-7kis,2021-01-13,2020-10-24
-6kis,2020-07-22,2019-07-19
-8kif,2024-04-17,2023-08-23
-6ki0,2020-07-22,2019-07-16
-4kij,2014-05-14,2013-05-02
-8ki3,2024-05-01,2023-08-22
-3ki2,2010-10-27,2009-10-31
-3kid,2009-12-01,2009-11-01
-2rt5,2013-12-04,2013-04-22
-3rtb,2011-07-27,2011-05-03
-3rtk,2011-08-10,2011-05-03
-3rt6,2011-05-18,2011-05-03
-6rtu,2019-12-18,2019-05-26
-2rti,1998-10-14,1997-09-11
-7rte,2022-08-24,2021-08-13
-7rt2,2021-12-22,2021-08-12
-2rtn,1998-10-14,1997-09-11
-3rtv,2012-05-30,2011-05-04
-7rt1,2021-12-22,2021-08-12
-5rt0,2020-12-16,2020-09-28
-1rta,1993-10-31,1992-08-28
-5rt2,2020-12-16,2020-09-28
-7rt0,2021-08-25,2021-08-12
-6rt3,2019-06-05,2019-05-22
-3rt4,2011-06-15,2011-05-03
-6rt8,2020-03-04,2019-05-22
-6rto,2020-01-08,2019-05-24
-6rt5,2019-11-27,2019-05-22
-5rt7,2020-12-16,2020-09-28
-6rtj,2020-01-08,2019-05-24
-4rtp,2015-04-15,2014-11-15
-3rtn,2011-08-31,2011-05-03
-3rtl,2011-05-18,2011-05-03
-5rtq,2020-12-16,2020-09-28
-4rtf,2014-12-10,2014-11-14
-1rt1,1997-04-21,1996-03-16
-7rt3,2021-12-22,2021-08-12
-1rt2,1997-04-21,1996-03-16
-2rtk,1998-10-14,1997-09-11
-6rtm,2020-01-08,2019-05-24
-2rtj,1998-10-14,1997-09-11
-7rtf,2022-11-23,2021-08-13
-7rtu,2021-08-25,2021-08-15
-5rtf,2020-12-16,2020-09-28
-3rt5,2011-06-15,2011-05-03
-3rtc,2011-06-22,2011-05-03
-1rtg,1996-06-10,1995-12-21
-4rtr,2015-04-15,2014-11-15
-4rtb,2015-01-28,2014-11-14
-5rtp,2020-12-16,2020-09-28
-4rtx,2015-10-28,2014-11-16
-8rtz,2024-04-03,2024-01-29
-7rtr,2021-10-13,2021-08-14
-6rt1,2019-05-29,2019-05-22
-5rtg,2020-12-16,2020-09-28
-7rtt,2021-08-25,2021-08-15
-4rti,2015-03-11,2014-11-15
-1rte,2004-07-27,2003-12-10
-6rtv,2020-03-18,2019-05-27
-6rt2,2020-04-08,2019-05-22
-2rth,1998-10-14,1997-09-11
-1rtz,2004-02-24,2003-12-10
-4rts,2015-04-15,2014-11-15
-2rte,1998-10-14,1997-09-11
-4rt6,2016-05-18,2014-11-13
-2rtq,1998-10-14,1997-09-11
-4rtv,2015-10-28,2014-11-16
-1rtx,2004-04-20,2003-12-10
-5rty,2020-12-16,2020-09-28
-6rtd,2019-06-19,2019-05-23
-5rtb,2020-12-16,2020-09-28
-7rtm,2021-09-29,2021-08-13
-5rt9,2020-12-16,2020-09-28
-7rtp,2022-02-16,2021-08-13
-3rt8,2011-05-18,2011-05-03
-3rtd,2011-06-22,2011-05-03
-7rtq,2021-11-24,2021-08-13
-3rtx,2011-06-29,2011-05-04
-4rt2,2015-07-01,2014-11-12
-1rt9,2005-02-22,2003-12-10
-5rtw,2020-12-16,2020-09-28
-2rtg,1998-10-14,1997-09-11
-1rt7,1999-07-29,1998-07-29
-6rt4,2019-11-27,2019-05-22
-6rt6,2019-11-27,2019-05-22
-2rt9,2014-07-16,2013-07-05
-5rth,2020-12-16,2020-09-28
-7rt5,2021-12-22,2021-08-12
-5rts,2020-12-16,2020-09-28
-4rtj,2015-04-15,2014-11-15
-3rt9,2011-06-22,2011-05-03
-5rti,2020-12-16,2020-09-28
-4rtq,2015-04-15,2014-11-15
-5rtn,2020-12-16,2020-09-28
-5rtl,2020-12-16,2020-09-28
-7rtj,2022-11-23,2021-08-13
-5rt1,2020-12-16,2020-09-28
-5rtz,2020-12-16,2020-09-28
-3rt1,2011-08-10,2011-05-02
-3rtt,2012-07-04,2011-05-04
-5rtm,2020-12-16,2020-09-28
-7rtd,2021-10-13,2021-08-13
-3rto,2011-05-18,2011-05-03
-5rtv,2020-12-16,2020-09-28
-2rtb,1998-10-14,1997-09-11
-8rty,2024-04-10,2024-01-29
-1rtm,1995-02-07,1994-11-21
-1rt3,1999-02-16,1998-06-29
-1rth,1996-04-03,1995-05-03
-8rt2,2024-03-27,2024-01-25
-6rts,2019-12-18,2019-05-26
-4rt5,2014-12-03,2014-11-13
-1rtk,2004-12-14,2003-12-10
-3rtg,2011-06-22,2011-05-03
-6rtw,2019-10-02,2019-05-27
-6rta,2019-06-26,2019-05-22
-6rte,2019-06-19,2019-05-23
-3rti,2011-08-31,2011-05-03
-1rtf,1997-01-11,1995-11-10
-3rts,2012-07-04,2011-05-04
-5rt4,2020-12-16,2020-09-28
-1rt5,1999-07-29,1998-07-29
-6rt9,2019-06-05,2019-05-22
-5rto,2020-12-16,2020-09-28
-5rtr,2020-12-16,2020-09-28
-6rti,2020-06-10,2019-05-24
-4rt7,2015-04-22,2014-11-13
-3rt0,2011-06-22,2011-05-02
-4rtm,2015-04-15,2014-11-15
-6rtx,2019-10-02,2019-05-27
-2rtf,1998-10-14,1997-09-11
-1rti,1996-04-03,1995-05-03
-8rt3,2024-03-27,2024-01-25
-3rtm,2011-08-31,2011-05-03
-7rtk,2021-08-25,2021-08-13
-4rt0,2015-04-08,2014-11-12
-1rtp,1994-01-31,1993-05-14
-5rtc,2020-12-16,2020-09-28
-3rtf,2011-05-18,2011-05-03
-5rtu,2020-12-16,2020-09-28
-2rtr,1998-10-14,1997-09-11
-5rt3,2020-12-16,2020-09-28
-1rts,1999-02-16,1998-06-19
-7rtw,2021-08-25,2021-08-15
-7rty,2021-09-15,2021-08-16
-3rth,2011-08-31,2011-05-03
-6rty,2019-10-02,2019-05-27
-3rtj,2011-08-31,2011-05-03
-6rtp,2019-09-04,2019-05-24
-5rte,2020-12-16,2020-09-28
-5rtt,2020-12-16,2020-09-28
-1rtd,1998-12-09,1998-08-26
-2rto,1998-10-14,1997-09-11
-5rt5,2020-12-16,2020-09-28
-3rtr,2011-07-20,2011-05-03
-7rtv,2021-09-22,2021-08-15
-1rt6,1999-07-29,1998-07-29
-5rt6,2020-12-16,2020-09-28
-4rto,2015-04-15,2014-11-15
-3rt7,2011-06-22,2011-05-03
-7rt4,2021-12-22,2021-08-12
-3rta,2011-06-22,2011-05-03
-2rtl,1998-10-14,1997-09-11
-6rtt,2019-12-18,2019-05-26
-6rtn,2019-09-11,2019-05-24
-2rtp,1998-10-14,1997-09-11
-1rtl,2004-12-14,2003-12-10
-4rtz,2015-10-28,2014-11-16
-3rte,2011-06-22,2011-05-03
-4rtk,2015-04-15,2014-11-15
-5rt8,2020-12-16,2020-09-28
-4rt1,2015-04-08,2014-11-12
-5rtk,2020-12-16,2020-09-28
-5rtd,2020-12-16,2020-09-28
-1rtq,2004-02-10,2003-12-10
-2rtd,1998-10-14,1997-09-11
-3rtw,2011-05-18,2011-05-04
-4rtw,2015-10-28,2014-11-16
-8rth,2024-04-17,2024-01-26
-1rtw,2004-01-13,2003-12-10
-3rtp,2013-05-08,2011-05-03
-5rtx,2020-12-16,2020-09-28
-7rtg,2022-01-12,2021-08-13
-2rtm,1998-10-14,1997-09-11
-6rt7,2019-11-27,2019-05-22
-7rtc,2021-09-01,2021-08-13
-6rtg,2020-03-18,2019-05-23
-5rta,2020-12-16,2020-09-28
-1rt4,1999-07-29,1998-07-29
-8rtt,2024-04-10,2024-01-29
-4rt3,2015-07-01,2014-11-12
-4rtl,2015-04-15,2014-11-15
-3rtq,2012-02-22,2011-05-03
-4rtn,2015-04-15,2014-11-15
-7w9x,2022-12-07,2021-12-11
-3w9z,2013-07-31,2013-04-19
-2w9b,2009-05-12,2009-01-22
-6w9e,2021-09-01,2020-03-22
-3w9f,2014-04-09,2013-04-04
-1w9v,2005-01-10,2004-10-19
-1w9l,2006-03-16,2004-10-13
-3w99,2013-08-28,2013-04-01
-8w9m,2024-02-28,2023-09-05
-3w9t,2014-03-19,2013-04-16
-2w94,2010-03-31,2009-01-21
-1w9d,2005-05-19,2004-10-08
-1w9k,2006-03-16,2004-10-13
-1w9t,2004-11-03,2004-10-18
-4w9g,2014-09-10,2014-08-27
-6w9l,2020-11-04,2020-03-23
-3w9j,2013-07-03,2013-04-04
-2w9l,2009-03-17,2009-01-26
-2w95,2010-03-31,2009-01-21
-5w9h,2017-08-16,2017-06-23
-6w98,2020-05-13,2020-03-22
-2w9g,2009-03-24,2009-01-23
-4w9n,2014-10-15,2014-08-27
-2w98,2009-04-07,2009-01-22
-4w96,2014-12-31,2014-08-27
-1w9e,2006-03-22,2004-10-09
-5w9a,2018-10-10,2017-06-22
-8w9t,2024-02-14,2023-09-05
-4w9k,2014-09-10,2014-08-27
-5w9d,2017-10-11,2017-06-23
-5w9e,2017-08-02,2017-06-23
-8w9a,2024-04-17,2023-09-05
-3w9c,2013-08-21,2013-04-03
-4w9l,2014-09-10,2014-08-27
-7w9m,2022-05-25,2021-12-10
-1w9s,2004-11-03,2004-10-18
-5w9i,2017-08-16,2017-06-23
-8w9c,2024-05-15,2023-09-05
-7w97,2022-12-14,2021-12-09
-3w9e,2013-10-02,2013-04-03
-8w9d,2024-05-15,2023-09-05
-5w94,2017-10-04,2017-06-22
-7w9w,2022-02-02,2021-12-11
-4w9o,2014-12-03,2014-08-27
-7w9r,2022-12-14,2021-12-10
-4w9z,2015-09-09,2014-08-28
-1w96,2005-01-04,2004-10-06
-1w9x,2005-02-09,2004-10-20
-4w97,2014-11-26,2014-08-27
-8w9f,2024-05-15,2023-09-05
-2w9h,2009-03-24,2009-01-23
-3w95,2013-09-04,2013-03-27
-8w9z,2024-03-13,2023-09-06
-8w9e,2024-05-15,2023-09-05
-5w90,2018-06-20,2017-06-22
-6w9k,2020-11-04,2020-03-23
-7w9u,2022-12-21,2021-12-10
-7w9y,2022-12-07,2021-12-11
-6w9h,2020-04-29,2020-03-23
-6w9c,2020-04-01,2020-03-22
-6w91,2021-01-13,2020-03-21
-6w9i,2020-04-29,2020-03-23
-7w9s,2022-11-16,2021-12-10
-5w9c,2018-06-13,2017-06-23
-4w9w,2014-09-10,2014-08-28
-7w9p,2022-05-25,2021-12-10
-5w97,2017-08-09,2017-06-22
-7w9l,2022-06-01,2021-12-10
-4w9c,2014-09-10,2014-08-27
-5w99,2017-11-22,2017-06-22
-4w9e,2014-09-10,2014-08-27
-8w9n,2024-02-14,2023-09-05
-6w9t,2020-12-09,2020-03-23
-8w9o,2024-02-14,2023-09-05
-8w9w,2024-02-28,2023-09-06
-3w97,2013-08-28,2013-04-01
-5w92,2018-02-07,2017-06-22
-5w9g,2017-12-27,2017-06-23
-2w9s,2009-03-24,2009-01-28
-7w9j,2022-12-14,2021-12-09
-4w9f,2014-09-10,2014-08-27
-4w9h,2014-09-10,2014-08-27
-5w9q,2017-10-18,2017-06-23
-6w9m,2020-11-04,2020-03-23
-2w92,2009-01-27,2009-01-21
-4w93,2015-07-15,2014-08-27
-7w9z,2022-12-07,2021-12-11
-4w9q,2014-12-03,2014-08-27
-2w9m,2009-02-10,2009-01-27
-4w9y,2015-09-23,2014-08-28
-3w9r,2014-04-09,2013-04-13
-1w9j,2006-03-16,2004-10-13
-1w9i,2006-03-16,2004-10-13
-2w93,2009-02-03,2009-01-21
-6w9n,2020-12-23,2020-03-23
-4w9s,2014-10-01,2014-08-27
-4w9x,2014-09-10,2014-08-28
-1w9b,2005-05-19,2004-10-08
-3w98,2013-08-28,2013-04-01
-5w91,2017-08-30,2017-06-22
-7w9t,2022-05-25,2021-12-10
-2w9a,2009-05-12,2009-01-22
-3w93,2014-02-12,2013-03-24
-4w9m,2015-01-14,2014-08-27
-5w96,2018-04-18,2017-06-22
-2w9c,2009-05-12,2009-01-22
-4w9j,2014-09-10,2014-08-27
-1w9u,2004-11-17,2004-10-19
-7w9k,2022-06-01,2021-12-09
-2w97,2010-03-31,2009-01-22
-6w9d,2020-05-20,2020-03-22
-1w9q,2006-03-22,2004-10-15
-4w9p,2014-12-03,2014-08-27
-6w9a,2020-05-20,2020-03-22
-1w9h,2005-01-13,2004-10-13
-3w9h,2013-07-03,2013-04-04
-7w9d,2022-12-14,2021-12-09
-7w9q,2022-12-14,2021-12-10
-3w9s,2013-07-24,2013-04-15
-5w9r,2017-08-02,2017-06-23
-7w9h,2022-12-14,2021-12-09
-6w9x,2021-03-24,2020-03-24
-1w9o,2006-03-22,2004-10-15
-3w96,2013-08-28,2013-04-01
-2w9n,2009-04-28,2009-01-27
-2w9d,2009-02-03,2009-01-23
-8w9v,2024-02-14,2023-09-05
-8w9b,2024-04-17,2023-09-05
-4w9i,2014-09-10,2014-08-27
-6w9g,2020-12-23,2020-03-23
-1w9w,2004-11-03,2004-10-19
-1w92,2004-11-02,2004-10-05
-5w9s,2017-10-18,2017-06-23
-3w92,2014-02-12,2013-03-24
-4w9d,2014-09-10,2014-08-27
-4w94,2014-12-31,2014-08-27
-7w93,2022-06-22,2021-12-09
-2w90,2009-04-07,2009-01-20
-6w9u,2020-08-05,2020-03-23
-1w90,2005-03-18,2004-10-01
-17gs,1998-12-30,1997-12-07
-7xg2,2023-08-09,2022-04-02
-1xge,2005-04-26,2004-09-17
-2xgi,2010-12-01,2010-06-04
-4xg8,2015-12-30,2014-12-30
-5xg3,2017-06-07,2017-04-11
-1xgn,1998-02-25,1997-11-17
-2xgz,2010-08-25,2010-06-08
-7xgn,2023-03-22,2022-04-05
-5xgw,2018-06-20,2017-04-18
-4xgn,2015-01-14,2014-12-31
-7xgj,2022-06-29,2022-04-05
-5xgu,2017-10-18,2017-04-17
-6xgy,2020-07-15,2020-06-18
-2xg4,2010-07-14,2010-05-30
-5xg5,2017-07-12,2017-04-12
-6xgv,2021-01-13,2020-06-18
-1xg5,2004-10-05,2004-09-16
-2xgt,2010-12-15,2010-06-07
-4xg1,2016-03-09,2014-12-30
-5xgx,2018-02-28,2017-04-18
-4xgu,2015-05-06,2015-01-02
-6xgu,2021-01-13,2020-06-18
-5xg4,2017-07-26,2017-04-11
-7xg0,2023-08-09,2022-04-02
-5xgd,2017-12-20,2017-04-13
-1xgy,2005-09-27,2004-09-17
-6xgc,2021-03-10,2020-06-17
-8xgc,2024-02-14,2023-12-15
-7xg5,2022-12-14,2022-04-03
-1xgs,1997-07-07,1997-04-25
-2xgs,2010-08-25,2010-06-07
-4xg4,2015-12-30,2014-12-30
-4xgi,2015-01-14,2014-12-30
-6xg3,2020-06-24,2020-06-16
-4xg7,2015-12-30,2014-12-30
-4xgc,2015-04-01,2014-12-30
-7xg4,2023-08-09,2022-04-02
-4xgv,2015-12-16,2015-01-02
-7xg9,2023-04-12,2022-04-04
-2xgl,2010-11-17,2010-06-07
-4xgm,2015-05-13,2014-12-31
-6xgf,2020-09-02,2020-06-17
-7xg1,2023-08-02,2022-04-02
-5xgf,2017-05-31,2017-04-13
-2xgb,2010-12-01,2010-06-02
-4xgq,2015-08-12,2015-01-02
-7xgd,2023-04-12,2022-04-04
-5xgj,2018-04-25,2017-04-13
-7xgt,2023-04-12,2022-04-06
-2xg7,2010-10-13,2010-05-31
-7xgk,2022-08-31,2022-04-05
-5xgk,2018-09-19,2017-04-14
-4xg3,2015-12-30,2014-12-30
-7xgl,2023-03-22,2022-04-05
-4xgl,2015-05-13,2014-12-31
-5xgz,2018-05-02,2017-04-19
-4xgp,2015-09-09,2015-01-01
-2xgx,2010-08-18,2010-06-08
-7xgi,2023-04-12,2022-04-04
-7xgo,2022-08-31,2022-04-05
-4xgk,2015-08-12,2014-12-31
-4xgo,2015-04-01,2015-01-01
-7xga,2022-12-07,2022-04-04
-7xgp,2022-09-07,2022-04-05
-1xgi,2005-05-03,2004-09-17
-2xg9,2010-12-01,2010-06-02
-2xgm,2010-08-25,2010-06-07
-5xgi,2018-04-25,2017-04-13
-4xgw,2015-12-16,2015-01-02
-6xg6,2020-09-30,2020-06-17
-2xgo,2010-08-25,2010-06-07
-5xgv,2018-04-25,2017-04-18
-2xga,2010-12-01,2010-06-02
-1xg0,2004-11-30,2004-09-16
-4xg9,2015-12-30,2014-12-30
-2xg3,2010-10-13,2010-05-30
-5xgn,2017-10-11,2017-04-14
-7xgm,2023-03-22,2022-04-05
-5xgm,2017-10-11,2017-04-14
-4xg6,2015-12-30,2014-12-30
-2xge,2010-09-22,2010-06-03
-6xg5,2021-03-24,2020-06-16
-2xgw,2010-08-11,2010-06-08
-5xge,2017-12-20,2017-04-13
-2xgq,2010-11-03,2010-06-07
-4xgr,2015-08-12,2015-01-02
-5xgr,2017-05-10,2017-04-16
-7xgy,2022-11-09,2022-04-07
-1xgk,2004-12-14,2004-09-17
-1xgz,2005-05-24,2004-09-17
-7xgc,2022-04-20,2022-04-04
-2xg5,2010-07-14,2010-05-30
-4xgx,2015-12-16,2015-01-02
-7xg3,2023-08-09,2022-04-02
-4xgb,2015-09-09,2014-12-30
-4xga,2016-01-20,2014-12-30
-2xgf,2010-11-03,2010-06-03
-1xg4,2005-03-01,2004-09-16
-7xgx,2023-04-12,2022-04-07
-2xgj,2010-06-23,2010-06-04
-1xg3,2005-03-01,2004-09-16
-1xgm,1998-02-25,1997-11-17
-5xgh,2018-04-25,2017-04-13
-6xg4,2021-03-24,2020-06-16
-2xgp,2010-11-03,2010-06-07
-1xgj,2005-05-03,2004-09-17
-3ox7,2011-08-10,2010-09-21
-3oxo,2010-11-10,2010-09-21
-5oxd,2018-05-16,2017-09-06
-4oxd,2014-05-21,2014-02-05
-3ox3,2011-05-25,2010-09-21
-2oxm,2007-10-30,2007-02-20
-2oxt,2007-05-15,2007-02-21
-3ox5,2010-12-22,2010-09-21
-2oxd,2007-09-25,2007-02-20
-6oxd,2019-11-13,2019-05-13
-5oxq,2018-02-21,2017-09-07
-1oxa,1995-12-07,1995-07-14
-4oxs,2014-06-04,2014-02-06
-5oxn,2018-02-21,2017-09-07
-4oxq,2014-10-29,2014-02-06
-2ox9,2007-04-03,2007-02-20
-4oxi,2014-12-31,2014-02-05
-5ox4,2018-02-28,2017-09-05
-3oxk,2010-10-06,2010-09-21
-3oxx,2011-09-28,2010-09-22
-8oxe,2024-03-27,2023-05-02
-7oxo,2021-12-22,2021-06-22
-4oxn,2014-04-30,2014-02-05
-8oxu,2023-07-12,2023-05-02
-6oxs,2019-08-21,2019-05-14
-1oxq,2003-08-26,2003-04-03
-3oxl,2011-02-23,2010-09-21
-7ox9,2021-09-15,2021-06-22
-6oxv,2019-08-21,2019-05-14
-8oxo,2023-09-27,2023-05-02
-7ox8,2021-09-15,2021-06-22
-1ox0,2003-04-22,2003-03-31
-1oxy,1995-02-27,1995-01-06
-7oxy,2021-12-01,2021-06-23
-6oxh,2019-07-03,2019-05-13
-7ox4,2022-12-28,2021-06-22
-6ox3,2019-08-21,2019-05-13
-7oxu,2022-07-13,2021-06-23
-2oxw,2007-03-06,2007-02-21
-2oxp,2007-03-20,2007-02-20
-1oxn,2003-08-26,2003-04-03
-6ox2,2019-08-21,2019-05-13
-4oxx,2014-04-16,2014-02-07
-8ox7,2023-11-29,2023-05-01
-6oxx,2019-08-21,2019-05-14
-3oxi,2011-05-04,2010-09-21
-8oxn,2024-01-17,2023-05-02
-8oxq,2023-09-27,2023-05-02
-5ox2,2018-01-10,2017-09-05
-2ox6,2007-04-03,2007-02-19
-4oxf,2015-03-04,2014-02-05
-3oxg,2011-02-23,2010-09-21
-8oxm,2023-09-27,2023-05-02
-5oxg,2017-09-20,2017-09-06
-7oxn,2022-06-29,2021-06-22
-7oxq,2021-12-08,2021-06-22
-2ox8,2007-04-03,2007-02-20
-4ox2,2014-06-11,2014-02-04
-1ox9,2003-08-26,2003-04-01
-6oxi,2019-08-21,2019-05-13
-2oxb,2008-01-22,2007-02-20
-3ox1,2011-05-25,2010-09-21
-6oxn,2020-05-20,2019-05-13
-1ox4,2003-06-17,2003-04-01
-7oxh,2022-03-16,2021-06-22
-4oxr,2014-10-29,2014-02-06
-3oxv,2011-09-28,2010-09-22
-5oxu,2018-12-26,2017-09-07
-5ox5,2017-10-18,2017-09-06
-1oxh,2003-04-22,2003-04-02
-1oxu,2003-06-17,2003-04-03
-3oxq,2010-11-03,2010-09-21
-8ox9,2023-11-29,2023-05-01
-6oxo,2019-08-21,2019-05-14
-6oxj,2019-07-03,2019-05-13
-5ox7,2018-10-10,2017-09-06
-7oxx,2022-07-13,2021-06-23
-3ox2,2011-05-25,2010-09-21
-6oxt,2019-08-21,2019-05-14
-1ox5,2003-06-17,2003-04-01
-6oxu,2019-08-21,2019-05-14
-4oxv,2015-03-18,2014-02-07
-4ox9,2014-04-09,2014-02-04
-5oxw,2018-10-10,2017-09-07
-8ox8,2023-11-29,2023-05-01
-5oxm,2018-02-21,2017-09-07
-5oxt,2019-04-17,2017-09-07
-7oxj,2022-03-16,2021-06-22
-5ox6,2017-10-18,2017-09-06
-6ox4,2019-08-21,2019-05-13
-7oxb,2021-10-20,2021-06-22
-7oxe,2022-07-13,2021-06-22
-6oxp,2019-08-21,2019-05-14
-3oxh,2011-10-19,2010-09-21
-1oxc,2003-09-09,2003-04-02
-3oxz,2010-12-15,2010-09-22
-5oxl,2018-02-21,2017-09-07
-7oxz,2021-09-01,2021-06-23
-3oxw,2011-09-28,2010-09-22
-4ox3,2014-06-11,2014-02-04
-2ox4,2007-03-06,2007-02-19
-2ox0,2007-03-13,2007-02-19
-1oxp,1996-06-10,1995-12-23
-5oxk,2018-02-21,2017-09-07
-1oxl,2004-04-06,2003-04-02
-2oxe,2007-03-27,2007-02-20
-3oxc,2010-11-10,2010-09-21
-8oxt,2024-01-17,2023-05-02
-4oxy,2014-04-30,2014-02-09
-8ox6,2023-11-29,2023-05-01
-5ox0,2018-02-28,2017-09-05
-5oxf,2018-09-05,2017-09-06
-1oxm,1997-05-15,1996-10-26
-6oxq,2019-08-21,2019-05-14
-4oxk,2014-04-30,2014-02-05
-6oxz,2019-08-21,2019-05-14
-1oxr,2004-04-27,2003-04-03
-3oxt,2011-09-28,2010-09-22
-2oxz,2007-03-06,2007-02-21
-8ox4,2023-11-29,2023-05-01
-5oxo,2018-02-21,2017-09-07
-7oxd,2021-12-01,2021-06-22
-8oxc,2023-11-29,2023-05-01
-2ox3,2007-03-06,2007-02-19
-3oxf,2011-02-23,2010-09-21
-4ox5,2014-05-21,2014-02-04
-5oxr,2018-06-20,2017-09-07
-1oxv,2003-06-17,2003-04-03
-1ox6,2003-06-17,2003-04-01
-6ox5,2019-08-21,2019-05-13
-1ox1,2004-05-18,2003-03-31
-6oxw,2019-08-21,2019-05-14
-5oxs,2018-06-20,2017-09-07
-1oxo,1996-06-10,1995-12-23
-5ox1,2018-02-28,2017-09-05
-6oxr,2019-08-21,2019-05-14
-3ox6,2010-12-22,2010-09-21
-6oxa,2019-08-21,2019-05-13
-8ox5,2023-11-29,2023-05-01
-6oxc,2019-11-13,2019-05-13
-2oxr,2007-04-24,2007-02-21
-4oxc,2015-02-11,2014-02-05
-2oxu,2007-03-06,2007-02-21
-8oxb,2023-11-29,2023-05-01
-8oxp,2023-09-27,2023-05-02
-6ox1,2019-08-21,2019-05-13
-8oxa,2023-11-29,2023-05-01
-6oxy,2019-08-21,2019-05-14
-2oxc,2007-02-27,2007-02-20
-7oxa,2021-09-15,2021-06-22
-6ox0,2019-08-21,2019-05-13
-7ox7,2021-09-15,2021-06-22
-8oxv,2023-10-18,2023-05-02
-1ox7,2003-08-19,2003-04-01
-8oxw,2023-10-18,2023-05-02
-2oxn,2007-06-12,2007-02-20
-2oxx,2007-09-25,2007-02-21
-2oxi,1994-01-31,1993-11-08
-8oxg,2024-04-10,2023-05-02
-3ox4,2011-02-16,2010-09-21
-2oxs,2007-03-13,2007-02-21
-2oxy,2007-09-25,2007-02-21
-5ox3,2018-02-28,2017-09-05
-7oxl,2022-07-13,2021-06-22
-8oxx,2023-10-18,2023-05-02
-5oxj,2017-11-29,2017-09-06
-2uyi,2007-05-22,2007-04-07
-7uy6,2022-07-13,2022-05-06
-1uyz,2004-03-11,2004-03-03
-7uyw,2022-08-24,2022-05-07
-7uyd,2023-05-24,2022-05-06
-1uyf,2004-07-01,2004-03-02
-7uyk,2022-12-28,2022-05-06
-2uyq,2007-08-07,2007-04-11
-2uy5,2007-04-24,2007-04-02
-6uyb,2020-06-24,2019-11-12
-6uy5,2020-03-25,2019-11-11
-2uyu,2008-01-15,2007-04-20
-7uyf,2022-10-05,2022-05-06
-1uyg,2004-07-01,2004-03-02
-4uyn,2014-11-19,2014-09-02
-8uyd,2024-03-06,2023-11-13
-2uyv,2008-01-15,2007-04-20
-6uy4,2020-05-27,2019-11-11
-6uyc,2020-06-24,2019-11-12
-7uyb,2023-05-24,2022-05-06
-5uyu,2017-05-17,2017-02-24
-1uyc,2004-07-01,2004-03-02
-5uyp,2017-06-07,2017-02-24
-1uym,2004-08-17,2004-03-02
-4uy1,2014-10-15,2014-08-28
-5uyj,2017-04-26,2017-02-24
-5uyr,2018-02-28,2017-02-24
-6uyg,2020-04-22,2019-11-13
-4uyq,2015-04-15,2014-09-02
-6uy0,2020-06-10,2019-11-09
-5uyk,2017-06-07,2017-02-24
-7uyu,2022-08-24,2022-05-07
-4uyp,2015-04-15,2014-09-02
-3uy7,2012-06-27,2011-12-06
-4uy8,2014-10-29,2014-08-29
-3uyv,2012-02-29,2011-12-06
-6uye,2020-03-11,2019-11-13
-7uys,2022-08-24,2022-05-07
-2uym,2007-05-22,2007-04-10
-4uym,2015-08-19,2014-09-02
-7uyt,2022-08-24,2022-05-07
-3uy4,2011-12-28,2011-12-05
-6uy9,2020-06-17,2019-11-12
-6uyh,2019-11-27,2019-11-13
-6uyf,2020-04-22,2019-11-13
-3uyk,2012-02-15,2011-12-06
-1uyp,2004-03-22,2004-03-02
-7uy5,2022-07-13,2022-05-06
-7uyz,2023-05-10,2022-05-07
-5uy5,2017-07-12,2017-02-23
-4uy2,2014-10-01,2014-08-28
-5uy0,2017-07-12,2017-02-23
-1uyj,2004-08-05,2004-03-02
-1uyd,2004-07-01,2004-03-02
-5uym,2017-06-07,2017-02-24
-3uyt,2012-01-11,2011-12-06
-4uy4,2014-09-24,2014-08-28
-8uyi,2024-01-31,2023-11-13
-1uy7,2004-07-01,2004-03-02
-2uy8,2007-08-21,2007-04-03
-2uyc,2008-05-27,2007-04-03
-7uya,2023-05-24,2022-05-06
-3uy9,2012-12-12,2011-12-06
-1uyh,2004-07-01,2004-03-02
-1uy8,2004-07-01,2004-03-02
-1uy9,2004-07-01,2004-03-02
-2uy4,2007-04-24,2007-04-02
-5uyg,2017-07-12,2017-02-24
-4uy7,2014-10-08,2014-08-29
-5uya,2017-07-12,2017-02-23
-7uyy,2023-02-15,2022-05-07
-2uyk,2007-05-29,2007-04-10
-1uy6,2004-07-01,2004-03-02
-5uyf,2017-07-12,2017-02-23
-3uyr,2012-07-25,2011-12-06
-1uy3,2004-06-18,2004-03-01
-4uyd,2014-09-17,2014-08-30
-5uy9,2017-04-26,2017-02-23
-6uyn,2020-09-02,2019-11-13
-4uy6,2014-10-08,2014-08-29
-5uyy,2017-03-08,2017-02-24
-5uys,2018-02-28,2017-02-24
-1uye,2004-07-01,2004-03-02
-4uyh,2014-10-08,2014-08-31
-2uyh,2008-05-27,2007-04-06
-1uys,2004-03-29,2004-03-02
-7uy2,2022-12-28,2022-05-06
-1uyy,2004-03-11,2004-03-03
-7uy3,2022-12-28,2022-05-06
-4uyu,2015-02-25,2014-09-03
-2uyx,2007-05-08,2007-04-20
-6uym,2020-04-22,2019-11-13
-2uyy,2007-07-03,2007-04-20
-7uyc,2023-05-24,2022-05-06
-5uyq,2017-06-07,2017-02-24
-1uyu,2005-03-07,2004-03-02
-5uyw,2017-07-12,2017-02-24
-2uyb,2007-08-21,2007-04-03
-8uyh,2024-01-31,2023-11-13
-5uyv,2017-07-12,2017-02-24
-1uy1,2004-06-18,2004-03-01
-2uyn,2007-05-29,2007-04-11
-3uyn,2012-02-01,2011-12-06
-1uyk,2004-07-01,2004-03-02
-4uyf,2014-10-08,2014-08-31
-4uya,2015-09-30,2014-08-29
-7uy4,2023-05-10,2022-05-06
-6uyx,2019-11-27,2019-11-14
-7uy1,2022-10-05,2022-05-06
-4uyz,2015-02-25,2014-09-03
-5uyc,2017-07-12,2017-02-23
-4uys,2015-08-12,2014-09-03
-5uyx,2017-07-05,2017-02-24
-5uy6,2017-03-29,2017-02-23
-5uyz,2017-07-05,2017-02-24
-6uy1,2019-12-04,2019-11-09
-5uyb,2017-07-12,2017-02-23
-7uy8,2022-07-13,2022-05-06
-1uyq,2005-03-03,2004-03-02
-2uyd,2007-12-25,2007-04-04
-7uyv,2022-08-24,2022-05-07
-4uyo,2015-09-30,2014-09-02
-3uyy,2012-12-12,2011-12-07
-2uya,2007-08-21,2007-04-03
-2uyz,2007-06-12,2007-04-21
-5uyn,2017-06-07,2017-02-24
-2uy3,2007-04-24,2007-04-02
-4uye,2014-09-17,2014-08-30
-4uyl,2015-08-19,2014-09-01
-1uy0,2004-03-11,2004-03-01
-1uy2,2004-06-18,2004-03-01
-6uyo,2019-11-27,2019-11-14
-3uyq,2011-12-21,2011-12-06
-3uyj,2011-12-21,2011-12-06
-7uyr,2022-08-24,2022-05-07
-5uy8,2018-01-10,2017-02-23
-5uyh,2017-07-12,2017-02-24
-7uyq,2023-05-10,2022-05-07
-5uyl,2017-06-14,2017-02-24
-7uyi,2023-04-19,2022-05-06
-6uya,2019-11-20,2019-11-12
-5uye,2017-07-12,2017-02-23
-2uy0,2008-05-20,2007-04-02
-1uyi,2004-07-01,2004-03-02
-2uyw,2008-05-27,2007-04-20
-4uyw,2015-02-25,2014-09-03
-7uy0,2022-12-28,2022-05-06
-7uyn,2023-05-10,2022-05-06
-4uyg,2014-10-08,2014-08-31
-5uy4,2017-07-12,2017-02-23
-6uy3,2020-11-18,2019-11-11
-2uyt,2007-06-26,2007-04-13
-6uyz,2019-11-27,2019-11-14
-6uyd,2020-04-22,2019-11-13
-1uy4,2004-06-18,2004-03-01
-1uyx,2004-03-11,2004-03-03
-7uyj,2022-12-28,2022-05-06
-1uyr,2004-03-29,2004-03-02
-2uyr,2008-05-27,2007-04-12
-7uy7,2022-07-13,2022-05-06
-5uyd,2017-07-12,2017-02-23
-6uyy,2019-11-27,2019-11-14
-4uyr,2015-08-12,2014-09-03
-4uyt,2015-08-12,2014-09-03
-3uyl,2012-02-15,2011-12-06
-2uy9,2007-08-21,2007-04-03
-8xj6,2024-05-01,2023-12-20
-1xje,2005-10-11,2004-09-23
-4xju,2016-01-13,2015-01-09
-4xjw,2016-01-13,2015-01-09
-4xja,2016-01-20,2015-01-08
-4xjj,2015-06-24,2015-01-08
-4xjp,2016-01-20,2015-01-08
-6xji,2020-10-14,2020-06-23
-7xji,2022-05-04,2022-04-18
-2xjr,2010-12-15,2010-07-06
-7xjb,2023-05-31,2022-04-15
-5xjb,2017-09-13,2017-04-30
-4xjc,2015-03-18,2015-01-08
-4xjh,2015-06-03,2015-01-08
-2xj1,2011-02-23,2010-07-01
-4xjm,2016-01-20,2015-01-08
-1xjh,2004-10-05,2004-09-23
-2xjy,2010-07-21,2010-07-06
-4xj2,2016-01-27,2015-01-08
-4xjg,2015-06-03,2015-01-08
-2xjq,2010-12-15,2010-07-06
-4xj0,2015-09-16,2015-01-08
-2xj5,2010-07-14,2010-07-02
-8xjg,2024-05-22,2023-12-21
-7xj7,2022-04-27,2022-04-15
-6xju,2021-01-27,2020-06-24
-7xjn,2023-04-26,2022-04-18
-8xj8,2024-05-01,2023-12-20
-1xji,2005-04-19,2004-09-23
-7xj5,2022-04-27,2022-04-15
-2xja,2010-08-18,2010-07-03
-7xj4,2022-04-27,2022-04-15
-4xjt,2015-08-26,2015-01-09
-6xj4,2020-11-18,2020-06-22
-2xjo,2010-11-24,2010-07-06
-4xjf,2015-06-03,2015-01-08
-2xj2,2011-02-23,2010-07-01
-4xjx,2016-01-20,2015-01-09
-2xjk,2010-09-01,2010-07-07
-2xjc,2011-03-16,2010-07-03
-1xjo,1997-04-01,1996-10-09
-2xjs,2010-12-15,2010-07-06
-8xjo,2024-02-28,2023-12-21
-2xjd,2011-04-27,2010-07-04
-4xj3,2015-04-29,2015-01-08
-7xj0,2022-11-09,2022-04-14
-7xjo,2022-06-29,2022-04-18
-4xj9,2016-01-20,2015-01-08
-2xjv,2010-12-15,2010-07-06
-1xjn,2005-12-06,2004-09-23
-5xj6,2017-12-06,2017-04-30
-5xjf,2017-11-01,2017-05-01
-4xjk,2015-04-15,2015-01-08
-4xji,2015-06-03,2015-01-08
-1xj4,2005-03-29,2004-09-22
-8xj7,2024-05-01,2023-12-20
-2xjh,2011-02-02,2010-07-06
-8xj4,2024-02-28,2023-12-20
-6xjs,2021-01-27,2020-06-24
-1xjl,2004-11-09,2004-09-23
-2xj9,2011-07-13,2010-07-02
-2xjx,2010-08-11,2010-07-06
-6xjo,2021-06-30,2020-06-24
-1xj3,2005-03-29,2004-09-22
-7xj8,2023-04-19,2022-04-15
-2xjb,2011-03-16,2010-07-03
-2xjf,2011-03-16,2010-07-04
-1xjz,2005-10-25,2004-09-26
-7xjv,2023-05-31,2022-04-18
-5xje,2017-11-01,2017-05-01
-7xje,2023-03-01,2022-04-16
-4xjb,2015-06-03,2015-01-08
-1xjb,2005-06-21,2004-09-23
-6xj3,2020-07-01,2020-06-22
-1xjf,2005-12-20,2004-09-23
-6xjk,2020-11-25,2020-06-24
-2xj6,2010-07-14,2010-07-02
-2xjp,2010-12-15,2010-07-06
-8xjl,2024-02-28,2023-12-21
-5xjy,2017-06-07,2017-05-04
-2xjl,2010-09-01,2010-07-07
-5xj0,2017-12-20,2017-04-28
-4xjo,2016-01-20,2015-01-08
-7xjc,2023-03-01,2022-04-16
-1xjd,2004-10-19,2004-09-23
-1xj2,2005-03-29,2004-09-22
-5xjn,2017-07-12,2017-05-03
-4xjd,2015-06-03,2015-01-08
-6xj0,2021-03-10,2020-06-22
-2xjz,2010-07-21,2010-07-06
-7xjf,2023-05-31,2022-04-16
-6xjp,2021-01-27,2020-06-24
-6xjm,2020-11-18,2020-06-24
-2xji,2011-02-02,2010-07-06
-4xj4,2015-04-29,2015-01-08
-1xj6,2005-03-29,2004-09-22
-5xjc,2017-07-05,2017-04-30
-4xj5,2015-04-29,2015-01-08
-7xjp,2022-07-20,2022-04-18
-4xjr,2015-02-11,2015-01-08
-5xj7,2017-12-06,2017-04-30
-7xjg,2022-09-14,2022-04-17
-6xjr,2021-01-27,2020-06-24
-2xju,2010-12-15,2010-07-06
-2xjm,2010-11-24,2010-07-06
-7xj2,2022-11-09,2022-04-14
-1xjm,2005-12-20,2004-09-23
-6xjh,2020-10-14,2020-06-23
-2xjt,2010-12-15,2010-07-06
-7xj1,2022-11-09,2022-04-14
-2xje,2011-03-16,2010-07-04
-7xjh,2022-05-04,2022-04-18
-1xj9,2005-02-22,2004-09-23
-4xj7,2015-09-09,2015-01-08
-1xjk,2005-11-22,2004-09-23
-2xj0,2011-02-23,2010-07-01
-6xjn,2021-06-30,2020-06-24
-1xj0,2005-05-10,2004-09-22
-4xjs,2015-08-26,2015-01-09
-2xjn,2010-11-24,2010-07-06
-1xjg,2005-12-20,2004-09-23
-5xjd,2018-01-24,2017-05-01
-4xjn,2015-03-18,2015-01-08
-5xj2,2017-11-01,2017-04-28
-5xj5,2017-12-06,2017-04-30
-4xje,2016-01-20,2015-01-08
-8xjm,2024-02-28,2023-12-21
-5xjm,2018-07-11,2017-05-02
-7xjd,2023-03-22,2022-04-16
-2xjg,2010-08-11,2010-07-06
-1xjj,2005-12-20,2004-09-23
-4xjl,2016-01-20,2015-01-08
-4xjq,2015-02-11,2015-01-08
-2xj8,2010-07-14,2010-07-02
-5xjp,2017-08-30,2017-05-03
-6xjt,2021-01-27,2020-06-24
-6xj5,2021-06-30,2020-06-22
-1xjs,2005-01-04,2004-09-24
-6xjj,2021-06-02,2020-06-24
-4xj6,2015-04-29,2015-01-08
-7xj6,2023-04-19,2022-04-15
-6xje,2020-11-18,2020-06-23
-7xjw,2023-05-31,2022-04-18
-5xja,2017-09-13,2017-04-30
-6xjd,2020-09-16,2020-06-23
-1xjw,2005-05-24,2004-09-25
-2xjw,2011-01-26,2010-07-06
-2xj7,2010-09-29,2010-07-02
-1xjq,2005-08-30,2004-09-24
-1xj7,2005-01-25,2004-09-22
-2xjj,2010-08-11,2010-07-06
-6xj8,2020-12-09,2020-06-23
-4j82,2013-03-27,2013-02-14
-3j80,2014-11-05,2014-08-28
-8j8n,2024-05-15,2023-05-02
-5j81,2016-10-05,2016-04-07
-8j83,2023-10-11,2023-04-29
-4j8g,2013-03-27,2013-02-14
-2j8g,2007-07-03,2006-10-25
-5j8g,2017-05-17,2016-04-07
-6j81,2019-02-27,2019-01-18
-6j8q,2019-07-17,2019-01-21
-1j8h,2002-03-13,2001-05-21
-4j8l,2014-03-05,2013-02-14
-5j87,2017-04-19,2016-04-07
-4j83,2014-01-08,2013-02-14
-4j8r,2013-05-22,2013-02-14
-8j8e,2024-05-01,2023-05-01
-1j83,2001-12-12,2001-05-20
-5j89,2016-04-27,2016-04-07
-5j8q,2016-07-27,2016-04-08
-5j88,2016-07-06,2016-04-07
-6j8h,2019-02-27,2019-01-19
-5j8h,2016-09-07,2016-04-07
-1j8e,2001-12-19,2001-05-21
-5j8l,2016-04-27,2016-04-08
-8j8r,2023-12-27,2023-05-02
-3j81,2014-11-05,2014-08-29
-5j8c,2016-07-20,2016-04-07
-5j8k,2016-09-21,2016-04-08
-1j8v,2002-06-12,2001-05-22
-6j80,2019-08-28,2019-01-18
-6j85,2019-08-07,2019-01-18
-2j8y,2007-11-27,2006-10-31
-8j8j,2024-02-07,2023-05-01
-1j87,2001-08-29,2001-05-20
-4j8o,2014-01-08,2013-02-14
-1j8r,2001-06-22,2001-05-22
-3j8h,2014-12-10,2014-10-26
-6j8e,2019-02-27,2019-01-18
-8j8g,2024-05-08,2023-05-01
-2j8d,2007-07-03,2006-10-24
-1j89,2001-08-29,2001-05-20
-5j8p,2016-05-18,2016-04-08
-6j8m,2019-06-26,2019-01-20
-1j8t,2002-05-22,2001-05-22
-1j8u,2002-05-22,2001-05-22
-8j8z,2023-12-27,2023-05-02
-5j8s,2016-10-05,2016-04-08
-2j87,2006-11-13,2006-10-23
-2j8r,2007-02-06,2006-10-27
-1j88,2001-08-29,2001-05-20
-4j8p,2013-03-13,2013-02-14
-5j84,2017-06-21,2016-04-07
-2j8w,2007-11-06,2006-10-30
-8j8w,2024-05-08,2023-05-02
-6j84,2019-08-07,2019-01-18
-2j8t,2007-05-29,2006-10-27
-6j8f,2019-06-19,2019-01-18
-2j8f,2007-07-03,2006-10-25
-6j83,2019-08-07,2019-01-18
-8j80,2023-09-20,2023-04-28
-8j8t,2023-12-13,2023-05-02
-5j8n,2016-04-27,2016-04-08
-5j8f,2016-07-20,2016-04-07
-5j8m,2017-12-06,2016-04-08
-5j8d,2017-05-17,2016-04-07
-4j8b,2013-03-27,2013-02-14
-1j86,2001-08-29,2001-05-20
-2j8u,2007-10-16,2006-10-27
-5j8b,2016-05-25,2016-04-07
-6j8w,2019-04-17,2019-01-21
-2j80,2007-10-23,2006-10-18
-5j8z,2016-06-29,2016-04-08
-3j8y,2014-12-10,2014-11-20
-6j8v,2019-04-17,2019-01-21
-1j84,2001-12-12,2001-05-20
-3j8a,2014-12-10,2014-10-08
-2j86,2007-11-06,2006-10-19
-2j83,2006-12-19,2006-10-18
-3j8x,2014-12-10,2014-11-20
-3j82,2015-05-20,2014-09-25
-1j8q,2001-09-05,2001-05-22
-8j86,2024-05-01,2023-04-30
-8j81,2024-05-01,2023-04-28
-4j8t,2013-06-26,2013-02-14
-5j8u,2017-12-06,2016-04-08
-6j88,2019-08-07,2019-01-18
-5j8w,2016-10-05,2016-04-08
-6j8j,2019-02-27,2019-01-19
-8j8h,2024-03-06,2023-05-01
-5j82,2017-12-06,2016-04-07
-4j8f,2013-07-03,2013-02-14
-3j8i,2015-01-14,2014-11-06
-1j8a,2001-09-12,2001-05-21
-5j8t,2017-05-10,2016-04-08
-4j86,2013-03-27,2013-02-14
-8j85,2023-08-30,2023-04-30
-2j8z,2006-11-06,2006-10-31
-8j8f,2024-05-08,2023-05-01
-6j8g,2019-02-27,2019-01-19
-5j8i,2017-02-15,2016-04-07
-2j82,2007-11-06,2006-10-18
-5j8o,2016-04-27,2016-04-08
-4j8m,2014-09-10,2013-02-14
-4j84,2013-03-27,2013-02-14
-5j85,2017-06-21,2016-04-07
-6j82,2019-08-07,2019-01-18
-6j8o,2020-01-22,2019-01-20
-2j8c,2007-07-03,2006-10-24
-1j8f,2001-07-06,2001-05-21
-3j8f,2015-02-11,2014-10-20
-6j87,2019-08-07,2019-01-18
-5j8a,2016-07-06,2016-04-07
-4j81,2013-03-27,2013-02-14
-6j8i,2019-02-27,2019-01-19
-8j8k,2024-02-07,2023-05-01
-8j8o,2024-02-07,2023-05-02
-6j8r,2019-07-17,2019-01-21
-5j86,2017-12-06,2016-04-07
-6j86,2019-08-07,2019-01-18
-5j8x,2016-08-17,2016-04-08
-8j8x,2024-05-08,2023-05-02
-1ahr,1997-06-16,1997-04-10
-1ahb,1994-06-22,1994-01-07
-4ah4,2013-02-20,2012-02-03
-7ahu,2021-07-07,2020-09-25
-2aho,2006-01-31,2005-07-28
-2ahk,2006-01-31,2005-07-28
-5ahw,2015-04-01,2015-02-10
-5ahn,2015-07-15,2015-02-06
-8ahc,2023-06-21,2022-07-21
-7ahj,2020-10-14,2020-09-24
-5ahu,2015-10-28,2015-02-09
-2ahx,2005-09-27,2005-07-28
-1ah0,1998-04-15,1997-04-11
-5ahb,2015-05-06,2015-02-05
-5aho,2015-02-18,2015-02-06
-7ahh,2020-11-25,2020-09-24
-3ahs,2010-07-07,2010-04-29
-4ahu,2012-12-19,2012-02-07
-7aho,2020-11-25,2020-09-25
-3ahu,2011-07-13,2010-04-29
-1ahp,1997-10-15,1997-04-10
-6ahy,2019-05-01,2018-08-21
-4ah3,2012-02-15,2012-02-03
-6ahi,2018-09-05,2018-08-19
-8ahm,2022-11-16,2022-07-22
-5ahs,2015-06-03,2015-02-06
-6ahg,2018-11-21,2018-08-18
-7ah0,2021-10-06,2020-09-23
-2ahj,1999-01-27,1997-12-24
-8ahy,2023-12-13,2022-07-25
-5ah7,2015-02-18,2015-02-05
-1ah7,1997-12-10,1997-04-14
-5ah1,2015-11-11,2015-02-04
-4aht,2012-12-19,2012-02-07
-7ahy,2021-01-20,2020-09-25
-5ahk,2016-03-02,2015-02-06
-1ahv,1997-10-15,1997-04-10
-1ah4,1998-04-15,1997-04-12
-8ahs,2023-03-22,2022-07-22
-7ahb,2020-12-09,2020-09-24
-4ahv,2012-12-19,2012-02-07
-6ahd,2018-11-14,2018-08-17
-2ah2,2005-08-23,2005-07-27
-5ahm,2015-07-15,2015-02-06
-2ahy,2006-02-07,2005-07-28
-4ahr,2012-12-19,2012-02-07
-5ahr,2015-02-18,2015-02-06
-3ah2,2010-04-28,2010-04-13
-3ahc,2010-08-25,2010-04-22
-3ahm,2010-08-25,2010-04-25
-2ahg,2006-08-15,2005-07-28
-5ahe,2015-09-02,2015-02-05
-5ahj,2015-02-18,2015-02-06
-7ahr,2021-10-06,2020-09-25
-2ahw,2005-11-01,2005-07-28
-7ahq,2021-01-27,2020-09-25
-7ah5,2021-02-17,2020-09-24
-6ahf,2019-02-13,2018-08-17
-1ah3,1998-04-15,1997-04-12
-8ahf,2022-09-14,2022-07-21
-4ah9,2012-12-19,2012-02-06
-5ah5,2016-02-17,2015-02-05
-6ah0,2018-11-14,2018-08-15
-5ahi,2016-03-02,2015-02-06
-6ahe,2019-08-21,2018-08-17
-2ah9,2005-10-04,2005-07-27
-5ah3,2016-03-02,2015-02-04
-3ah7,2011-04-20,2010-04-20
-2ahs,2005-08-09,2005-07-28
-3ahi,2010-08-25,2010-04-22
-3ahg,2010-08-25,2010-04-22
-5ah2,2015-06-03,2015-02-04
-6ahu,2018-12-05,2018-08-20
-1ahu,1997-10-15,1997-04-10
-5ah8,2015-05-06,2015-02-05
-8ahv,2023-08-02,2022-07-22
-8aho,2023-08-02,2022-07-22
-8aht,2023-03-22,2022-07-22
-3ahe,2010-08-25,2010-04-22
-6ahh,2019-08-28,2018-08-18
-4ahz,2012-10-03,2012-02-07
-7ah3,2021-10-06,2020-09-24
-7ahm,2021-03-31,2020-09-24
-6ah3,2018-10-17,2018-08-16
-3ahr,2010-12-22,2010-04-26
-4ahx,2013-01-30,2012-02-07
-7ahz,2021-01-20,2020-09-25
-8ahi,2022-09-14,2022-07-21
-2ahr,2005-09-13,2005-07-28
-5ah9,2015-05-06,2015-02-05
-1ahg,1995-09-15,1995-02-22
-8ah3,2023-08-16,2022-07-20
-3aht,2010-06-02,2010-04-29
-1ahi,1996-10-14,1995-08-25
-7ah8,2021-08-04,2020-09-24
-7ahe,2020-11-25,2020-09-24
-6ah5,2019-06-12,2018-08-16
-1ahh,1996-10-14,1995-08-25
-8ahg,2022-09-14,2022-07-21
-7ahk,2020-11-18,2020-09-24
-7ahv,2021-07-07,2020-09-25
-3aho,2010-09-01,2010-04-25
-1aha,1994-06-22,1994-01-07
-3ahq,2010-12-22,2010-04-26
-7ah6,2021-02-17,2020-09-24
-1ahx,1995-09-15,1995-02-21
-1ahj,1998-04-08,1997-04-05
-3ahn,2010-08-25,2010-04-25
-6ah7,2019-09-18,2018-08-17
-1ahy,1995-09-15,1995-02-21
-7ah4,2021-02-17,2020-09-24
-5ahy,2015-04-22,2015-02-11
-7ahd,2020-11-25,2020-09-24
-3ah1,2010-04-28,2010-04-13
-3ahd,2010-08-25,2010-04-22
-7ah2,2021-01-20,2020-09-24
-1ah1,1998-04-15,1997-04-11
-6ahl,2019-08-28,2018-08-19
-6ah8,2019-09-18,2018-08-17
-5aha,2015-05-06,2015-02-05
-5ah6,2015-05-06,2015-02-05
-2ah7,2006-07-18,2005-07-27
-5ahg,2015-08-26,2015-02-06
-4ahy,2012-10-03,2012-02-07
-8ahq,2023-03-15,2022-07-22
-7ahn,2021-01-27,2020-09-24
-5ahz,2015-04-22,2015-02-11
-5ahf,2015-09-02,2015-02-05
-3ahh,2010-08-25,2010-04-22
-1ahf,1995-09-15,1995-02-22
-6ah9,2019-08-21,2018-08-17
-8ahn,2023-05-24,2022-07-22
-1ah5,1997-10-15,1997-04-13
-4aha,2013-02-20,2012-02-06
-2ahi,2006-07-11,2005-07-28
-5ah0,2015-11-04,2015-02-04
-5ahc,2015-05-06,2015-02-05
-2ahv,2005-11-01,2005-07-28
-2ahz,2006-02-07,2005-07-28
-7ahx,2021-01-13,2020-09-25
-8ahx,2023-11-01,2022-07-24
-3ahv,2010-06-02,2010-04-30
-3ah5,2011-04-20,2010-04-14
-1ahn,1997-12-10,1997-04-07
-3ahw,2010-07-07,2010-05-04
-8ahh,2022-09-14,2022-07-21
-2ahl,2006-01-31,2005-07-28
-3ahj,2010-08-25,2010-04-22
-8ahu,2022-08-31,2022-07-22
-1aht,1996-03-17,1995-03-17
-3ah4,2010-04-28,2010-04-13
-1ahz,1997-10-15,1997-04-10
-4ahs,2012-12-19,2012-02-07
-2ahc,2006-01-31,2005-07-27
-8ahr,2022-08-03,2022-07-22
-6ah4,2019-06-12,2018-08-16
-3ahf,2010-08-25,2010-04-22
-5ahl,2015-07-15,2015-02-06
-2ah4,2006-05-16,2005-07-26
-8ahe,2022-09-14,2022-07-21
-3ah8,2010-07-21,2010-04-20
-2ah0,2006-04-25,2005-07-27
-6ahr,2018-12-05,2018-08-20
-1ahe,1995-09-15,1995-02-22
-5ah4,2015-06-03,2015-02-04
-4ahw,2012-10-03,2012-02-07
-6ahs,2019-01-02,2018-08-20
-5y5k,2017-12-06,2017-08-09
-6y5m,2020-11-18,2020-02-25
-4y5l,2016-03-02,2015-02-11
-2y5q,2011-02-23,2011-01-17
-4y5r,2015-06-17,2015-02-11
-5y5f,2017-12-06,2017-08-09
-4y55,2015-03-25,2015-02-11
-1y55,2005-05-24,2004-12-02
-2y5m,2011-05-11,2011-01-14
-1y5y,2005-01-11,2004-12-03
-1y5w,2005-12-13,2004-12-03
-2y57,2011-06-15,2011-01-12
-4y5s,2015-11-04,2015-02-12
-1y57,2005-06-21,2004-12-02
-7y5b,2022-11-23,2022-06-16
-2y56,2011-06-15,2011-01-12
-2y5n,2012-02-01,2011-01-15
-6y5t,2020-06-17,2020-02-25
-2y5h,2011-12-28,2011-01-13
-6y5e,2020-09-23,2020-02-25
-6y5o,2020-08-19,2020-02-25
-7y5h,2022-12-14,2022-06-17
-5y5b,2018-08-08,2017-08-08
-7y5g,2022-12-14,2022-06-17
-5y5i,2017-12-06,2017-08-09
-6y5d,2020-09-23,2020-02-25
-5y53,2018-08-15,2017-08-07
-6y5w,2020-10-14,2020-02-26
-2y54,2011-06-15,2011-01-12
-2y5w,2011-08-24,2011-01-18
-1y5k,2004-12-14,2004-12-02
-5y5j,2017-12-06,2017-08-09
-4y5u,2016-02-17,2015-02-12
-1y56,2005-07-26,2004-12-02
-5y5p,2017-12-06,2017-08-09
-5y5h,2017-12-06,2017-08-09
-4y5f,2015-05-20,2015-02-11
-5y5r,2018-08-15,2017-08-09
-4y5h,2015-05-06,2015-02-11
-4y5e,2016-03-02,2015-02-11
-7y5i,2023-07-05,2022-06-17
-5y5m,2018-08-08,2017-08-09
-1y52,2005-05-24,2004-12-02
-6y5v,2020-07-15,2020-02-25
-2y5z,2012-02-01,2011-01-19
-2y5a,2011-10-12,2011-01-12
-5y5e,2018-06-20,2017-08-08
-7y5q,2023-01-11,2022-06-17
-6y5f,2020-10-14,2020-02-25
-4y57,2016-03-02,2015-02-11
-4y5d,2015-09-23,2015-02-11
-2y5k,2011-05-18,2011-01-14
-1y5u,2005-12-13,2004-12-03
-6y50,2020-07-01,2020-02-24
-1y5l,2005-03-08,2004-12-02
-1y5j,2004-12-14,2004-12-02
-4y53,2016-03-02,2015-02-11
-6y5j,2020-06-10,2020-02-25
-7y52,2024-01-17,2022-06-16
-6y5h,2020-06-10,2020-02-25
-4y56,2016-03-02,2015-02-11
-1y5m,2005-05-17,2004-12-02
-4y5i,2016-01-13,2015-02-11
-6y58,2020-11-18,2020-02-25
-2y5i,2011-07-27,2011-01-13
-5y5s,2018-04-11,2017-08-09
-2y53,2011-06-01,2011-01-11
-4y5q,2015-02-25,2015-02-11
-2y5y,2011-06-15,2011-01-19
-4y58,2016-03-02,2015-02-11
-2y5l,2011-05-18,2011-01-14
-5y5l,2017-12-06,2017-08-09
-4y5m,2016-03-02,2015-02-11
-5y56,2017-09-13,2017-08-07
-1y59,2005-12-13,2004-12-02
-5y59,2017-12-20,2017-08-08
-5y5n,2017-09-06,2017-08-09
-4y50,2016-03-02,2015-02-11
-6y5a,2020-12-23,2020-02-25
-1y5b,2005-12-13,2004-12-02
-7y5z,2022-11-02,2022-06-18
-5y5g,2017-12-06,2017-08-09
-7y5f,2023-07-05,2022-06-17
-6y5c,2020-08-19,2020-02-25
-7y53,2023-10-18,2022-06-16
-7y5c,2022-11-23,2022-06-16
-7y51,2022-08-31,2022-06-16
-1y5x,2005-12-13,2004-12-03
-6y5s,2020-06-17,2020-02-25
-2y58,2011-06-15,2011-01-12
-4y5t,2015-11-04,2015-02-12
-1y5r,2005-05-17,2004-12-02
-6y5l,2020-06-10,2020-02-25
-6y5x,2020-07-08,2020-02-26
-6y55,2020-08-19,2020-02-24
-4y51,2016-03-02,2015-02-11
-5y5y,2018-01-24,2017-08-10
-5y5t,2018-06-27,2017-08-09
-6y5p,2020-09-30,2020-02-25
-7y59,2023-10-18,2022-06-16
-5y5z,2018-01-17,2017-08-10
-1y54,2005-03-29,2004-12-02
-7y5t,2022-11-02,2022-06-17
-7y55,2022-12-07,2022-06-16
-7y5a,2022-11-23,2022-06-16
-7y5p,2023-07-05,2022-06-17
-5y5x,2018-01-17,2017-08-10
-2y5e,2011-01-26,2011-01-13
-2y50,2011-09-28,2011-01-11
-7y5n,2023-01-11,2022-06-17
-4y5c,2016-03-02,2015-02-11
-4y5b,2016-03-02,2015-02-11
-6y5y,2020-07-22,2020-02-26
-6y5k,2020-06-10,2020-02-25
-2y5f,2011-12-28,2011-01-13
-2y5b,2012-01-25,2011-01-12
-2y5p,2011-02-23,2011-01-17
-6y5g,2020-06-10,2020-02-25
-6y5r,2020-03-11,2020-02-25
-4y52,2015-07-15,2015-02-11
-4y5k,2016-03-02,2015-02-11
-4y5a,2016-03-02,2015-02-11
-2y59,2011-07-27,2011-01-12
-2y5d,2011-06-01,2011-01-12
-1y5a,2005-12-13,2004-12-02
-1y5i,2005-03-08,2004-12-02
-6y5n,2020-09-30,2020-02-25
-4y5n,2016-03-02,2015-02-11
-7y5x,2022-11-02,2022-06-17
-1y5n,2005-03-08,2004-12-02
-1y5v,2005-12-13,2004-12-03
-2y5g,2011-12-28,2011-01-13
-4y54,2016-03-02,2015-02-11
-5y5w,2017-10-11,2017-08-10
-2y5s,2011-01-26,2011-01-17
-4y5g,2016-03-02,2015-02-11
-6y57,2020-04-15,2020-02-25
-4y5p,2016-03-02,2015-02-11
-5y5q,2017-12-06,2017-08-09
-6y54,2020-10-07,2020-02-24
-5y5u,2018-06-27,2017-08-09
-5y52,2018-08-08,2017-08-07
-6y5i,2020-06-10,2020-02-25
-1y5f,2004-12-14,2004-12-02
-2y55,2011-07-27,2011-01-12
-4y59,2015-09-23,2015-02-11
-3hv7,2009-11-17,2009-06-15
-5hvq,2016-10-26,2016-01-28
-2hvn,2006-10-03,2006-07-29
-8hvt,2024-01-03,2022-12-27
-2hv6,2006-08-22,2006-07-27
-7hvp,1993-07-15,1990-09-13
-4hvk,2012-12-05,2012-11-06
-1hvh,1998-12-30,1997-12-13
-4hvy,2014-01-01,2012-11-07
-4hva,2013-03-20,2012-11-05
-6hv5,2019-01-30,2018-10-10
-8hv1,2023-12-13,2022-12-26
-5hvf,2016-06-22,2016-01-28
-2hv7,2006-08-22,2006-07-27
-8hvc,2023-12-27,2022-12-26
-6hv9,2018-12-12,2018-10-10
-5hvg,2016-06-22,2016-01-28
-6hv4,2019-01-30,2018-10-10
-2hv4,2006-09-26,2006-07-27
-1hv9,2001-02-21,2001-01-08
-5hvd,2017-03-01,2016-01-28
-4hv8,2013-02-27,2012-11-05
-4hvw,2013-05-01,2012-11-07
-2hvy,2006-09-12,2006-07-31
-1hvl,1994-04-30,1994-01-26
-4hvx,2012-12-26,2012-11-07
-1hvx,2001-01-31,2001-01-08
-3hvd,2009-08-25,2009-06-15
-3hvf,2010-05-26,2009-06-16
-1hvf,1995-03-31,1994-06-29
-8hv8,2023-12-13,2022-12-26
-6hv7,2019-01-30,2018-10-10
-6hvs,2019-01-30,2018-10-11
-5hv9,2016-07-13,2016-01-28
-1hvj,1994-04-30,1994-01-26
-4hvv,2013-05-01,2012-11-07
-4hvh,2013-01-16,2012-11-06
-6hvv,2019-01-30,2018-10-11
-5hvk,2016-05-04,2016-01-28
-5hv8,2016-03-09,2016-01-28
-4hv6,2012-11-21,2012-11-05
-6hvf,2019-10-23,2018-10-10
-6hvq,2019-09-04,2018-10-11
-8hvb,2023-12-27,2022-12-26
-1hvo,1994-01-31,1992-12-08
-1hvq,1995-12-02,1994-10-13
-8hvd,2023-12-27,2022-12-26
-4hv4,2012-11-21,2012-11-05
-2hvo,2006-10-03,2006-07-29
-2hve,2006-09-19,2006-07-28
-8hva,2023-12-13,2022-12-26
-5hvj,2016-05-04,2016-01-28
-4hv7,2012-12-26,2012-11-05
-8hvx,2024-01-17,2022-12-28
-2hvb,2007-01-28,2006-07-28
-2hvs,2006-10-17,2006-07-30
-6hvj,2018-11-14,2018-10-11
-8hv4,2023-12-13,2022-12-26
-4hvi,2013-01-16,2012-11-06
-5hvs,2016-06-29,2016-01-28
-6hv0,2019-02-27,2018-10-09
-6hvl,2019-06-05,2018-10-11
-3hvh,2009-10-13,2009-06-16
-5hvl,2017-05-03,2016-01-28
-3hvi,2009-10-13,2009-06-16
-1hvk,1994-04-30,1994-01-26
-2hv9,2006-09-19,2006-07-27
-6hvt,2019-01-30,2018-10-11
-8hvq,2023-12-27,2022-12-27
-8hv5,2023-12-13,2022-12-26
-8hvl,2023-12-27,2022-12-27
-4hv5,2012-11-14,2012-11-05
-8hvn,2023-12-27,2022-12-27
-8hvk,2023-12-27,2022-12-27
-3hvk,2009-10-13,2009-06-16
-4hvq,2013-11-27,2012-11-06
-8hvr,2023-12-27,2022-12-27
-3hvo,2009-08-04,2009-06-16
-1hvc,1994-10-15,1994-06-22
-5hvn,2016-02-10,2016-01-28
-1hvi,1994-04-30,1994-01-26
-1hve,1995-03-31,1994-06-29
-8hvi,2023-10-11,2022-12-26
-2hvk,2007-02-20,2006-07-28
-5hvb,2017-02-01,2016-01-28
-8hvw,2024-01-17,2022-12-28
-5hve,2017-02-01,2016-01-28
-3hvq,2010-03-23,2009-06-16
-5hvo,2017-05-03,2016-01-28
-3hvu,2009-06-23,2009-06-16
-6hvh,2018-11-14,2018-10-11
-4hvd,2013-01-16,2012-11-06
-8hvm,2023-12-27,2022-12-27
-6hv2,2019-01-30,2018-10-10
-1hvb,2001-02-07,2001-01-08
-4hvg,2013-01-16,2012-11-06
-5hvm,2017-05-03,2016-01-28
-8hv2,2023-12-13,2022-12-26
-2hv5,2006-10-03,2006-07-27
-3hvy,2009-06-30,2009-06-16
-6hvx,2019-01-30,2018-10-11
-5hvh,2016-06-22,2016-01-28
-1hvr,1995-01-26,1994-02-14
-8hv3,2023-12-13,2022-12-26
-6hvi,2018-11-14,2018-10-11
-8hvv,2024-01-17,2022-12-28
-3hvl,2009-08-04,2009-06-16
-8hvp,1993-10-31,1990-10-26
-5hva,2016-10-26,2016-01-28
-6hvy,2019-01-30,2018-10-11
-5hv7,2016-06-08,2016-01-28
-4hvu,2013-05-01,2012-11-07
-2hv8,2006-11-21,2006-07-27
-3hv6,2009-11-17,2009-06-15
-2hvw,2007-09-11,2006-07-31
-3hv8,2009-08-18,2009-06-15
-3hvr,2009-10-06,2009-06-16
-3hv0,2009-06-30,2009-06-15
-4hvs,2013-03-27,2012-11-06
-3hvc,2009-06-30,2009-06-15
-1hv6,2001-05-02,2001-01-08
-2hvd,2006-09-19,2006-07-28
-2hvq,2006-10-17,2006-07-30
-2hvf,2007-06-12,2006-07-28
-8hv9,2023-12-13,2022-12-26
-5hvp,1991-10-15,1990-04-30
-1hvy,2001-01-31,2001-01-08
-1hv4,2001-01-17,2001-01-07
-8hvu,2024-01-17,2022-12-28
-2hvi,2006-12-12,2006-07-28
-5hvy,2016-04-20,2016-01-28
-3hv5,2009-11-17,2009-06-15
-5hv4,2016-05-04,2016-01-28
-4hvj,2012-11-28,2012-11-06
-5hv0,2016-05-04,2016-01-28
-4hvc,2013-01-02,2012-11-06
-2hvh,2006-12-12,2006-07-28
-3hvj,2009-10-13,2009-06-16
-6hvw,2019-01-30,2018-10-11
-4hvp,1990-04-15,1989-08-08
-2hvv,2007-09-11,2006-07-31
-3hvt,1994-10-15,1994-07-25
-1hvs,1995-02-14,1994-11-17
-8hv6,2023-12-13,2022-12-26
-4hvo,2013-11-27,2012-11-06
-5hvw,2016-08-17,2016-01-28
-5hvt,2016-06-29,2016-01-28
-6hvd,2018-10-17,2018-10-10
-1hv5,2001-03-28,2001-01-08
-3hv4,2009-11-17,2009-06-15
-5hvx,2017-03-01,2016-01-28
-4hvr,2013-11-27,2012-11-06
-3hv3,2009-11-17,2009-06-15
-1hvd,1995-03-31,1994-06-29
-6hv8,2018-12-12,2018-10-10
-8hvz,2024-01-17,2022-12-28
-6hvu,2019-01-30,2018-10-11
-6hvm,2019-06-05,2018-10-11
-6hvg,2019-02-27,2018-10-11
-5hv3,2016-03-30,2016-01-28
-6hvn,2019-06-05,2018-10-11
-2hvc,2007-07-31,2006-07-28
-8hvy,2024-01-17,2022-12-28
-4hvl,2013-05-08,2012-11-06
-6hve,2019-10-23,2018-10-10
-4hv3,2012-12-26,2012-11-05
-6hv3,2019-01-30,2018-10-10
-6hva,2019-01-30,2018-10-10
-8hvo,2023-12-27,2022-12-27
-5hv1,2016-03-30,2016-01-28
-3hvg,2009-11-03,2009-06-16
-1hv7,2001-01-17,2001-01-08
-1hvn,1994-01-31,1992-12-08
-6hvr,2019-01-30,2018-10-11
-4hvb,2013-11-20,2012-11-05
-8hv7,2023-12-13,2022-12-26
-3hvn,2010-03-02,2009-06-16
-5hvu,2017-02-08,2016-01-28
-2hvj,2007-02-20,2006-07-28
-2hvx,2007-06-12,2006-07-31
-2gak,2006-07-11,2006-03-09
-8gas,2023-04-19,2023-02-23
-4gap,2012-09-05,2012-07-25
-1gat,1993-10-31,1993-06-28
-2ga0,2006-06-27,2006-03-07
-6gar,2018-09-05,2018-04-12
-9gac,2000-06-16,1999-06-15
-6ga4,2019-04-24,2018-04-11
-3gan,2009-03-03,2009-02-17
-6gau,2019-02-20,2018-04-12
-3gay,2009-03-31,2009-02-18
-1gaq,2001-02-07,2000-05-08
-3ga6,2010-03-09,2009-02-16
-1ga5,2001-11-16,2000-11-29
-6gah,2019-04-24,2018-04-11
-4gah,2012-08-29,2012-07-25
-2gag,2006-08-08,2006-03-08
-6gad,2019-04-24,2018-04-11
-7ga4,2023-07-26,2023-07-03
-6ga1,2019-04-24,2018-04-11
-3gam,2009-03-24,2009-02-17
-2gat,1998-01-28,1997-11-07
-2gab,2006-03-21,2006-03-08
-1gag,2001-01-17,2000-11-29
-7gaz,2023-11-08,2023-08-11
-8gar,2023-07-05,2023-02-23
-4ga9,2013-08-07,2012-07-25
-9gaf,2000-06-16,1999-06-15
-6gab,2019-04-24,2018-04-11
-1gae,1996-03-08,1995-10-24
-8gau,2024-02-28,2023-02-23
-6gas,2018-09-05,2018-04-12
-6gaf,2019-04-24,2018-04-11
-4gal,1998-11-04,1998-07-13
-2ga3,2006-10-10,2006-03-07
-6gaw,2018-08-22,2018-04-13
-7gay,2023-11-08,2023-08-11
-8gat,2024-02-28,2023-02-23
-4ga8,2013-08-07,2012-07-25
-1ga6,2000-12-13,2000-11-29
-6gaz,2018-08-08,2018-04-13
-1ga7,2001-05-02,2000-11-29
-1gad,1996-03-08,1995-10-24
-1gaf,1996-07-11,1996-02-06
-3gaz,2009-03-03,2009-02-18
-1gan,1997-09-04,1996-11-06
-6gaa,2019-04-24,2018-04-11
-1gar,1995-07-10,1994-12-08
-6gax,2018-07-18,2018-04-13
-7ga5,2023-07-26,2023-07-03
-2ga8,2007-03-20,2006-03-08
-1gac,1996-08-17,1995-05-24
-7ga2,2023-07-26,2023-07-03
-3ga3,2009-02-24,2009-02-16
-4gad,2013-03-13,2012-07-25
-2gah,2006-08-08,2006-03-08
-7gav,2023-11-08,2023-08-11
-8gao,2023-06-07,2023-02-23
-5gah,2016-01-27,2015-11-26
-5gad,2016-01-27,2015-11-24
-7ga1,2023-07-26,2023-07-03
-8gak,2023-07-19,2023-02-23
-5gae,2016-01-27,2015-11-25
-3gaj,2009-07-07,2009-02-17
-6gac,2019-04-24,2018-04-11
-6gal,2019-02-27,2018-04-11
-6gae,2019-04-24,2018-04-11
-1gau,1993-10-31,1993-06-28
-3gal,1998-11-04,1998-07-13
-6ga2,2019-04-24,2018-04-11
-2ga9,2006-05-16,2006-03-08
-5gak,2016-02-24,2015-12-09
-8ga8,2023-07-12,2023-02-22
-1ga4,2000-12-13,2000-11-29
-3ga8,2010-01-12,2009-02-16
-6gat,1998-01-28,1997-11-07
-8gae,2023-04-26,2023-02-22
-3gat,1998-01-28,1997-11-07
-2ga7,2006-08-01,2006-03-08
-8gap,2023-06-28,2023-02-23
-1ga0,2001-06-06,2000-11-28
-4ga6,2013-05-15,2012-07-25
-6ga8,2019-04-24,2018-04-11
-1gah,1996-08-17,1996-03-06
-7gat,1998-01-28,1997-11-07
-3gac,2009-12-29,2009-02-17
-7ga3,2023-07-26,2023-07-03
-4gaz,2013-08-14,2012-07-26
-4gab,2013-03-20,2012-07-25
-1ga9,2001-07-25,2000-11-29
-5gal,1998-11-04,1998-07-14
-2ga4,2006-07-11,2006-03-07
-6ga5,2019-04-24,2018-04-11
-2gao,2006-03-21,2006-03-09
-3gah,2009-07-07,2009-02-17
-8ga2,2024-02-28,2023-02-22
-1ga2,2003-07-22,2000-11-29
-7ga6,2023-07-26,2023-07-03
-8gal,2023-07-19,2023-02-23
-4gaa,2013-06-12,2012-07-25
-3gak,2009-03-31,2009-02-17
-3gag,2009-03-10,2009-02-17
-1ga8,2001-02-14,2000-11-29
-2ga2,2007-03-13,2006-03-07
-4gat,1998-01-28,1997-11-07
-7gax,2023-11-08,2023-08-11
-5gat,1998-01-28,1997-11-07
-6ga0,2018-05-09,2018-04-11
-2gam,2006-07-11,2006-03-09
-6gam,2019-02-20,2018-04-11
-6ga6,2019-04-24,2018-04-11
-6gay,2018-07-18,2018-04-13
-2ga6,2006-08-15,2006-03-08
-2gal,1998-11-04,1998-07-13
-5gam,2016-02-03,2015-12-15
-1gax,2000-12-06,2000-06-23
-5gag,2016-01-27,2015-11-26
-4ga3,2013-05-08,2012-07-24
-6gag,2019-04-24,2018-04-11
-6gai,2019-04-24,2018-04-11
-2gaz,2006-09-26,2006-03-09
-8gav,2024-02-28,2023-02-23
-6gan,2019-02-20,2018-04-11
-6ga7,2019-04-24,2018-04-11
-3gai,2009-07-07,2009-02-17
-5gan,2016-01-27,2015-12-15
-4gae,2013-02-06,2012-07-25
-6ga3,2019-04-24,2018-04-11
-7gaw,2023-11-08,2023-08-11
-7ga0,2023-07-26,2023-07-03
-3gas,2010-02-23,2009-02-18
-4gam,2013-02-06,2012-07-25
-7ga7,2023-07-26,2023-07-03
-6gaq,2018-09-05,2018-04-12
-1ga1,2000-12-13,2000-11-29
-3ga9,2009-06-16,2009-02-16
-8gag,2024-02-28,2023-02-22
-6ga9,2019-04-24,2018-04-11
-1gai,1996-08-17,1996-03-06
-4gaf,2013-02-20,2012-07-25
-3ga5,2009-04-14,2009-02-16
-1gaw,2001-02-07,2000-05-17
-1gal,1993-10-31,1992-08-27
-5gaf,2016-02-03,2015-11-25
-4gav,2012-09-05,2012-07-25
-4rpm,2015-09-09,2014-10-30
-7rp8,2022-07-06,2021-08-03
-3rpg,2011-08-17,2011-04-26
-6rpc,2020-07-08,2019-05-14
-1rpz,2004-02-17,2003-12-03
-7rpw,2021-11-17,2021-08-04
-6rpy,2020-03-25,2019-05-15
-7rpi,2021-10-27,2021-08-03
-5rpa,2021-05-26,2020-09-23
-5rpc,2021-05-26,2020-09-23
-6rpg,2019-07-24,2019-05-14
-2rpc,2009-03-31,2008-05-14
-5rp7,2021-05-26,2020-09-23
-6rp9,2020-01-15,2019-05-14
-1rpj,1999-02-16,1999-02-04
-5rph,2021-05-26,2020-09-23
-1rp0,2005-02-22,2003-12-02
-7rpf,2022-07-06,2021-08-03
-6rpn,2020-03-25,2019-05-14
-1rpi,2004-12-07,2003-12-03
-7rph,2021-10-27,2021-08-03
-4rpj,2015-01-21,2014-10-30
-6rph,2019-07-17,2019-05-14
-7rpy,2022-04-13,2021-08-04
-4rpp,2015-02-25,2014-10-31
-5rpk,2021-05-26,2020-09-23
-1rpk,2005-06-07,2003-12-03
-1rps,2003-12-23,2003-12-03
-4rpy,2015-04-15,2014-10-31
-6rp5,2019-12-25,2019-05-13
-3rpc,2011-05-11,2011-04-26
-5rp9,2021-05-26,2020-09-23
-1rp7,2004-03-16,2003-12-03
-1rpa,1994-05-31,1993-06-12
-7rpz,2021-12-22,2021-08-05
-7rpx,2021-11-17,2021-08-04
-6rp1,2020-03-11,2019-05-13
-3rp8,2012-05-16,2011-04-26
-7rpk,2021-10-27,2021-08-03
-7rp9,2022-07-06,2021-08-03
-3rpr,2012-10-31,2011-04-27
-7rpo,2021-11-17,2021-08-03
-6rpa,2020-01-15,2019-05-14
-4rp8,2015-03-04,2014-10-29
-7rp4,2022-03-16,2021-08-03
-3rph,2011-07-27,2011-04-26
-3rpm,2011-10-26,2011-04-27
-1rpq,2004-07-20,2003-12-03
-6rpe,2020-09-02,2019-05-14
-5rpd,2021-05-26,2020-09-23
-6rp6,2020-06-17,2019-05-14
-7rpv,2021-12-15,2021-08-04
-1rp4,2004-06-08,2003-12-03
-7rpe,2022-07-06,2021-08-03
-2rpz,2009-12-22,2008-12-11
-3rpy,2012-10-31,2011-04-27
-5rpg,2021-05-26,2020-09-23
-3rpq,2012-05-02,2011-04-27
-7rpc,2022-07-06,2021-08-03
-4rpv,2015-02-04,2014-10-31
-3rpd,2011-08-31,2011-04-26
-7rp2,2022-03-16,2021-08-03
-3rpz,2011-07-27,2011-04-27
-6rp3,2019-10-09,2019-05-13
-3rpo,2012-08-08,2011-04-27
-2rpr,2009-08-04,2008-07-24
-6rpb,2020-01-15,2019-05-14
-6rpu,2019-08-28,2019-05-14
-7rpd,2022-07-06,2021-08-03
-7rpg,2022-07-06,2021-08-03
-6rps,2019-11-13,2019-05-14
-7rpb,2022-07-06,2021-08-03
-3rpv,2012-10-31,2011-04-27
-4rpl,2015-01-21,2014-10-30
-1rpn,2004-02-24,2003-12-03
-4rpq,2015-11-18,2014-10-31
-4rpk,2015-01-21,2014-10-30
-1rp8,2005-06-07,2003-12-03
-5rpj,2021-05-26,2020-09-23
-1rp9,2005-06-07,2003-12-03
-7rpj,2021-10-27,2021-08-03
-8rpm,2024-02-21,2024-01-16
-3rpi,2011-07-20,2011-04-26
-4rp6,2016-01-13,2014-10-29
-5rp6,2021-05-26,2020-09-23
-6rp7,2020-04-15,2019-05-14
-8rpz,2024-05-22,2024-01-17
-6rp4,2020-10-07,2019-05-13
-4rp7,2016-01-13,2014-10-29
-6rp0,2020-04-15,2019-05-13
-4rpo,2014-11-26,2014-10-30
-4rpu,2015-12-09,2014-10-31
-5rpl,2021-05-26,2020-09-23
-1rpf,1994-12-20,1994-08-29
-4rpa,2015-01-21,2014-10-30
-7rpa,2022-07-06,2021-08-03
-4rpg,2015-01-21,2014-10-30
-2rpp,2009-05-12,2008-06-24
-7rp3,2022-03-16,2021-08-03
-1rpg,1994-12-20,1994-08-29
-1rp1,1998-06-17,1998-04-02
-5rpm,2021-05-26,2020-09-23
-4rpx,2015-04-15,2014-10-31
-4rph,2015-01-21,2014-10-30
-4rp9,2015-03-04,2014-10-29
-4rpe,2015-11-04,2014-10-30
-8rpy,2024-05-22,2024-01-17
-1rpw,2004-06-01,2003-12-03
-3rp7,2012-05-16,2011-04-26
-3rpl,2012-05-02,2011-04-26
-1rpt,1994-05-31,1993-11-29
-3rps,2011-06-08,2011-04-27
-4rpz,2015-04-15,2014-10-31
-3rpe,2011-05-04,2011-04-26
-3rpn,2011-07-13,2011-04-27
-6rpd,2020-09-02,2019-05-14
-6rpj,2020-07-08,2019-05-14
-6rp2,2020-03-25,2019-05-13
-4rp3,2014-11-26,2014-10-29
-7rp0,2021-10-27,2021-08-02
-2rpv,2009-09-15,2008-10-28
-4rpn,2014-11-26,2014-10-30
-3rp6,2012-05-16,2011-04-26
-5uuo,2018-02-28,2017-02-17
-7uur,2023-01-04,2022-04-28
-7uua,2023-01-25,2022-04-28
-8uub,2024-04-17,2023-10-31
-2uua,2007-05-15,2007-03-01
-1uux,2004-08-09,2004-01-12
-6uuz,2020-01-01,2019-11-01
-5uu8,2017-03-08,2017-02-16
-3uuo,2012-01-25,2011-11-28
-7uu3,2023-01-11,2022-04-28
-5uu3,2018-02-21,2017-02-16
-7uux,2023-05-03,2022-04-29
-8uu9,2024-02-28,2023-10-31
-7uuj,2023-04-19,2022-04-28
-2uuu,2007-06-26,2007-03-07
-4uuu,2014-08-13,2014-07-31
-4uui,2015-08-12,2014-07-29
-6uua,2020-08-26,2019-10-30
-6uup,2020-11-04,2019-10-31
-6uuy,2020-02-19,2019-11-01
-4uuq,2015-01-21,2014-07-30
-7uu4,2023-01-11,2022-04-28
-4uua,2014-08-20,2014-07-25
-1uuo,2004-04-01,2004-01-08
-7uug,2023-10-11,2022-04-28
-8uun,2023-11-29,2023-11-01
-2uuk,2007-09-04,2007-03-03
-5uua,2017-03-08,2017-02-16
-6uud,2020-07-15,2019-10-30
-1uut,2004-02-19,2004-01-10
-6uu8,2020-08-26,2019-10-30
-4uuh,2015-07-08,2014-07-28
-8uul,2023-11-29,2023-11-01
-2uu9,2007-05-15,2007-03-01
-4uug,2014-11-26,2014-07-28
-7uuw,2023-01-18,2022-04-29
-4uu1,2014-10-01,2014-07-24
-7uup,2023-10-11,2022-04-28
-2uuh,2007-07-17,2007-03-02
-2uuy,2007-04-10,2007-03-08
-6uu1,2020-08-26,2019-10-30
-5uuz,2017-03-08,2017-02-17
-5uuh,2017-07-19,2017-02-16
-3uu9,2012-01-25,2011-11-28
-7uub,2023-01-25,2022-04-28
-4uu7,2014-08-20,2014-07-24
-2uun,2008-05-13,2007-03-05
-3uu5,2012-05-16,2011-11-28
-3uus,2011-12-21,2011-11-28
-5uuu,2017-07-26,2017-02-17
-3uug,2012-11-28,2011-11-28
-4uu2,2015-06-10,2014-07-24
-6uu5,2020-08-26,2019-10-30
-6uum,2020-09-23,2019-10-30
-2uuj,2007-09-04,2007-03-03
-5uut,2018-01-17,2017-02-17
-2uu8,2007-07-31,2007-03-01
-1uu2,2004-03-18,2003-12-13
-7uuh,2022-11-02,2022-04-28
-3uue,2012-04-25,2011-11-28
-8uu5,2024-02-28,2023-10-31
-4uup,2015-08-12,2014-07-29
-6uuc,2020-08-26,2019-10-30
-3uuz,2012-12-05,2011-11-29
-8uuh,2024-04-03,2023-11-01
-1uu3,2004-03-04,2003-12-15
-3uul,2012-09-19,2011-11-28
-1uuf,2004-01-29,2003-12-18
-2uub,2007-05-15,2007-03-01
-5uun,2018-02-28,2017-02-17
-2uuc,2007-05-22,2007-03-01
-8uu4,2024-02-28,2023-10-31
-1uu4,2004-09-16,2003-12-15
-1uu8,2004-03-04,2003-12-16
-8uuv,2024-04-03,2023-11-02
-7uum,2022-11-02,2022-04-28
-7uuq,2023-05-10,2022-04-28
-2uuv,2007-06-26,2007-03-07
-5uuv,2017-03-01,2017-02-17
-1uuy,2004-08-09,2004-01-12
-4uun,2015-08-12,2014-07-29
-6uu7,2020-08-26,2019-10-30
-5uud,2017-03-08,2017-02-16
-6uub,2020-08-26,2019-10-30
-6uu6,2020-08-26,2019-10-30
-1uu1,2004-03-18,2003-12-12
-1uup,2004-08-12,2004-01-08
-4uuj,2014-08-27,2014-07-29
-8uuo,2023-11-29,2023-11-01
-3uum,2012-09-19,2011-11-28
-7uul,2022-11-02,2022-04-28
-2uu7,2007-10-16,2007-02-28
-3uuf,2012-04-25,2011-11-28
-8uux,2024-01-17,2023-11-02
-2uuo,2008-03-25,2007-03-06
-1uu6,2004-09-16,2003-12-15
-5uuf,2017-07-19,2017-02-16
-4uux,2014-10-15,2014-07-31
-5uuc,2017-03-08,2017-02-16
-8uuy,2024-04-03,2023-11-02
-5uub,2017-03-08,2017-02-16
-6uuq,2020-09-09,2019-10-31
-3uu7,2012-08-22,2011-11-28
-7uui,2023-03-15,2022-04-28
-5uu4,2018-02-21,2017-02-16
-5uu7,2017-03-08,2017-02-16
-4uur,2015-06-10,2014-07-31
-7uu0,2023-05-03,2022-04-28
-1uuv,2005-02-09,2004-01-11
-4uu5,2015-01-14,2014-07-24
-6uuo,2020-06-03,2019-10-30
-7uue,2023-01-25,2022-04-28
-8uug,2024-04-03,2023-11-01
-6uu2,2020-08-26,2019-10-30
-2uur,2007-06-05,2007-03-07
-3uub,2012-05-16,2011-11-28
-1uu5,2004-09-16,2003-12-15
-8uuk,2024-02-07,2023-11-01
-3uu6,2012-05-16,2011-11-28
-8uu7,2024-02-28,2023-10-31
-6uuh,2020-09-23,2019-10-30
-4uu8,2014-08-20,2014-07-24
-7uuu,2022-08-24,2022-04-29
-8uuf,2024-04-03,2023-11-01
-3uu0,2012-02-01,2011-11-27
-3uua,2012-08-22,2011-11-28
-5uue,2017-03-08,2017-02-16
-5uug,2017-07-19,2017-02-16
-6uu3,2020-08-26,2019-10-30
-4uub,2014-08-20,2014-07-25
-2uue,2007-03-27,2007-03-02
-8uuw,2024-04-03,2023-11-02
-1uum,2004-04-01,2004-01-06
-8uua,2024-02-28,2023-10-31
-6uul,2020-09-23,2019-10-30
-8uu8,2024-02-28,2023-10-31
-2uuq,2007-12-18,2007-03-07
-7uut,2022-05-11,2022-04-28
-1uu9,2004-03-04,2003-12-16
-3uuc,2012-08-22,2011-11-28
-1uuw,2005-02-09,2004-01-11
-7uuc,2023-01-25,2022-04-28
-5uuy,2017-10-04,2017-02-17
-6uu4,2020-08-26,2019-10-30
-5uu9,2017-03-08,2017-02-16
-7uuk,2023-04-19,2022-04-28
-8uuu,2024-04-03,2023-11-02
-1uu7,2004-03-04,2003-12-16
-6uu0,2020-08-26,2019-10-30
-5uum,2017-06-21,2017-02-17
-7uuo,2022-11-02,2022-04-28
-7uu5,2023-01-11,2022-04-28
-4uu0,2014-10-01,2014-07-24
-2uui,2007-07-17,2007-03-02
-7uun,2022-11-02,2022-04-28
-6uux,2020-02-19,2019-11-01
-5uu1,2017-03-01,2017-02-15
-2uup,2008-03-25,2007-03-06
-2uuf,2007-09-04,2007-03-02
-3uu8,2012-05-16,2011-11-28
-7uud,2023-01-25,2022-04-28
-7uus,2023-01-04,2022-04-28
-3uud,2012-08-22,2011-11-28
-6uu9,2020-08-26,2019-10-30
-8uum,2023-11-29,2023-11-01
-8uu6,2024-02-28,2023-10-31
-6uuw,2019-12-25,2019-11-01
-2uud,2007-04-03,2007-03-02
-4uuw,2014-10-15,2014-07-31
-3uu1,2012-12-12,2011-11-27
-2uum,2008-05-27,2007-03-04
-5uu6,2017-03-01,2017-02-16
-2uul,2008-05-27,2007-03-04
-5uui,2017-08-02,2017-02-16
-7uuz,2022-12-21,2022-04-29
-5osc,2017-10-11,2017-08-17
-7osn,2022-06-22,2021-06-09
-5osy,2018-05-02,2017-08-18
-6osz,2024-05-01,2019-05-02
-7os6,2021-11-24,2021-06-07
-3os0,2010-11-17,2010-09-08
-4osw,2014-05-28,2014-02-13
-3os4,2010-09-22,2010-09-08
-2osd,2007-02-20,2007-02-05
-6osa,2019-07-10,2019-05-01
-2os0,2008-03-04,2007-02-05
-1oss,2003-08-19,2003-03-20
-3os8,2010-11-10,2010-09-08
-7osq,2021-11-03,2021-06-09
-7oso,2022-06-22,2021-06-09
-8osc,2023-08-30,2023-04-18
-7ose,2021-11-17,2021-06-08
-3osd,2010-10-13,2010-09-08
-2osx,2007-02-27,2007-02-06
-2ost,2007-03-20,2007-02-06
-2osw,2007-02-27,2007-02-06
-3os5,2010-12-15,2010-09-08
-1os7,2003-09-23,2003-03-18
-2os9,2007-05-08,2007-02-05
-4os2,2014-09-24,2014-02-12
-5osd,2017-11-01,2017-08-17
-7osf,2022-06-22,2021-06-08
-1os5,2004-03-18,2003-03-18
-7os3,2021-11-24,2021-06-07
-2os3,2008-03-04,2007-02-05
-6osq,2019-06-26,2019-05-02
-1osg,2003-05-27,2003-03-19
-7osh,2022-06-22,2021-06-08
-4os1,2014-09-24,2014-02-12
-5osr,2018-09-05,2017-08-18
-7osx,2021-12-08,2021-06-09
-1ose,1997-04-01,1996-03-20
-3osu,2010-09-29,2010-09-09
-5osa,2017-10-11,2017-08-17
-1osf,2003-05-27,2003-03-19
-4osx,2014-03-05,2014-02-13
-7osg,2022-06-22,2021-06-08
-7osy,2021-07-28,2021-06-09
-6os9,2019-07-10,2019-05-01
-3osr,2011-10-26,2010-09-09
-5os8,2018-02-28,2017-08-17
-6osp,2020-04-29,2019-05-01
-8osz,2024-05-01,2023-04-20
-4osq,2014-05-28,2014-02-13
-3osh,2010-11-17,2010-09-09
-8osw,2023-08-09,2023-04-20
-2os2,2007-03-13,2007-02-05
-4osd,2015-02-18,2014-02-12
-1os6,2004-02-03,2003-03-18
-5osp,2018-09-05,2017-08-18
-7oss,2021-12-08,2021-06-09
-4osf,2014-03-12,2014-02-12
-3osa,2010-11-10,2010-09-08
-4osp,2014-10-01,2014-02-13
-1os9,2003-08-05,2003-03-19
-8ose,2023-07-12,2023-04-18
-3osl,2010-09-29,2010-09-09
-1os1,2003-09-23,2003-03-18
-7os4,2021-10-27,2021-06-07
-3osi,2011-05-25,2010-09-09
-1osh,2003-09-23,2003-03-19
-8osx,2023-05-31,2023-04-20
-3os1,2010-11-17,2010-09-08
-7osk,2021-09-29,2021-06-08
-3osk,2010-12-08,2010-09-09
-5os7,2018-02-28,2017-08-17
-6ost,2019-06-19,2019-05-02
-3osq,2011-10-26,2010-09-09
-7ost,2021-07-21,2021-06-09
-5osx,2018-05-02,2017-08-18
-8osm,2024-05-08,2023-04-19
-4os4,2014-09-24,2014-02-12
-4os6,2014-09-24,2014-02-12
-5osz,2018-02-28,2017-08-18
-2os8,2007-05-29,2007-02-05
-5os0,2017-11-01,2017-08-16
-7osp,2021-12-08,2021-06-09
-6osy,2019-07-24,2019-05-02
-1os2,2003-08-05,2003-03-18
-6osi,2020-10-14,2019-05-01
-3os2,2010-11-17,2010-09-08
-5osb,2017-10-11,2017-08-17
-4os7,2014-09-24,2014-02-12
-8osv,2024-05-01,2023-04-20
-8osf,2023-09-06,2023-04-18
-5ost,2018-04-11,2017-08-18
-5os5,2017-11-01,2017-08-16
-5osl,2018-02-28,2017-08-17
-1os8,2003-08-19,2003-03-18
-2osv,2007-04-17,2007-02-06
-6os6,2019-07-17,2019-05-01
-3oss,2011-08-03,2010-09-09
-6osk,2019-06-26,2019-05-01
-5os6,2017-11-01,2017-08-16
-2osf,2008-05-27,2007-02-05
-2osc,2007-03-20,2007-02-05
-5os3,2017-11-01,2017-08-16
-3osz,2010-10-06,2010-09-10
-4osg,2014-12-03,2014-02-12
-5ose,2017-11-01,2017-08-17
-5os4,2017-11-01,2017-08-16
-7os5,2021-11-24,2021-06-07
-4osu,2014-08-13,2014-02-13
-6os5,2019-07-17,2019-05-01
-4os5,2014-09-24,2014-02-12
-8osi,2023-05-24,2023-04-19
-5osk,2017-12-20,2017-08-17
-3os3,2011-07-27,2010-09-08
-3osj,2010-10-06,2010-09-09
-2osu,2007-03-06,2007-02-06
-6os2,2020-02-19,2019-05-01
-2oso,2007-02-20,2007-02-06
-5osn,2017-08-30,2017-08-17
-1os3,2003-07-29,2003-03-18
-1os4,2003-07-29,2003-03-18
-4osy,2014-03-05,2014-02-13
-2os6,2008-02-12,2007-02-05
-7osj,2022-06-22,2021-06-08
-5os2,2017-11-01,2017-08-16
-7osi,2022-06-22,2021-06-08
-7osa,2021-12-08,2021-06-08
-1os0,2003-03-25,2003-03-18
-2osy,2007-02-27,2007-02-06
-5osu,2018-09-05,2017-08-18
-5osj,2018-03-14,2017-08-17
-4oso,2014-10-01,2014-02-13
-5osm,2018-03-14,2017-08-17
-5osw,2017-11-08,2017-08-18
-8osg,2023-09-06,2023-04-18
-7osm,2021-12-08,2021-06-09
-5oss,2018-04-11,2017-08-18
-3osp,2011-04-13,2010-09-09
-5os1,2017-11-01,2017-08-16
-5osi,2017-12-13,2017-08-17
-1osv,2004-03-23,2003-03-20
-4osl,2014-05-28,2014-02-13
-8oso,2024-05-08,2023-04-19
-8osn,2024-05-08,2023-04-19
-5osf,2017-11-01,2017-08-17
-2osb,2008-01-15,2007-02-05
-6os1,2020-02-19,2019-05-01
-3oso,2011-09-21,2010-09-09
-7osz,2021-07-28,2021-06-09
-6osr,2019-05-15,2019-05-02
-3os9,2010-11-10,2010-09-08
-1osz,1999-01-13,1998-06-18
-1osa,1993-10-31,1993-08-11
-5osq,2017-09-06,2017-08-18
-8os6,2023-11-29,2023-04-18
-2osm,2008-02-12,2007-02-06
-3osw,2011-05-25,2010-09-10
-6os0,2020-02-19,2019-05-01
-2os1,2008-03-04,2007-02-05
-1osn,2003-06-10,2003-03-20
-6os4,2020-04-08,2019-05-01
-1nj6,2003-03-04,2002-12-30
-6nj2,2019-10-02,2019-01-02
-5njr,2017-10-18,2017-03-29
-5njd,2018-01-03,2017-03-28
-7njq,2021-10-27,2021-02-17
-3njf,2010-07-07,2010-06-17
-7nj5,2021-12-01,2021-02-16
-1njg,2003-04-01,2002-12-30
-5nj1,2018-05-16,2017-03-27
-6njl,2019-04-24,2019-01-03
-3njl,2010-07-21,2010-06-17
-3njr,2011-06-08,2010-06-17
-3nj0,2010-08-18,2010-06-16
-6njy,2019-07-10,2019-01-04
-3nji,2010-09-22,2010-06-17
-7njm,2021-10-27,2021-02-17
-4njk,2013-12-25,2013-11-10
-6nj3,2019-10-02,2019-01-02
-7njs,2021-10-27,2021-02-17
-5njx,2017-11-08,2017-03-30
-3njs,2010-07-14,2010-06-18
-7njo,2021-10-27,2021-02-17
-7nj7,2021-12-01,2021-02-16
-6njc,2019-01-16,2019-01-03
-5njz,2017-06-07,2017-03-31
-5njv,2018-01-24,2017-03-29
-3njx,2010-10-06,2010-06-18
-6nj7,2019-07-24,2019-01-02
-5njg,2017-06-07,2017-03-28
-6njs,2019-12-04,2019-01-04
-5njh,2017-06-21,2017-03-28
-5njf,2017-10-04,2017-03-28
-7njg,2021-06-16,2021-02-16
-3nj9,2011-06-22,2010-06-17
-1nje,1996-07-11,1996-01-23
-5njc,2017-10-04,2017-03-28
-5nj3,2017-06-07,2017-03-28
-6njt,2020-01-08,2019-01-04
-6njz,2019-05-01,2019-01-04
-5njp,2017-10-18,2017-03-29
-6njw,2019-08-07,2019-01-04
-4njg,2013-12-25,2013-11-10
-7nj9,2021-06-09,2021-02-16
-6njn,2019-04-24,2019-01-03
-4njd,2014-05-21,2013-11-09
-5nju,2018-01-24,2017-03-29
-1njx,2004-03-30,2003-01-02
-7njk,2021-10-27,2021-02-17
-6nj4,2019-10-02,2019-01-02
-7njc,2021-07-21,2021-02-16
-1njr,2004-08-17,2003-01-02
-1nj9,2004-02-17,2002-12-30
-1njj,2003-08-26,2002-12-31
-6nju,2020-01-08,2019-01-04
-1nji,2003-07-22,2002-12-31
-4njo,2014-10-08,2013-11-11
-4nj4,2014-01-15,2013-11-08
-6njd,2019-05-22,2019-01-03
-7njb,2021-06-09,2021-02-16
-1nj2,2003-03-04,2002-12-30
-7njv,2021-10-27,2021-02-17
-1nj3,2003-04-22,2002-12-30
-1njy,2004-03-30,2003-01-02
-1nj1,2003-03-04,2002-12-30
-3nj4,2011-05-04,2010-06-17
-7njn,2021-10-27,2021-02-17
-4njb,2013-11-27,2013-11-09
-3njn,2010-07-21,2010-06-17
-1njw,2004-03-30,2003-01-02
-7njl,2021-10-27,2021-02-17
-1njz,2004-03-30,2003-01-02
-6nj0,2019-04-10,2019-01-02
-5njb,2017-10-04,2017-03-28
-5nj8,2017-06-28,2017-03-28
-3nj3,2011-05-04,2010-06-16
-7nj3,2021-12-01,2021-02-15
-1njb,1996-10-14,1996-01-23
-3njh,2010-07-14,2010-06-17
-4nj9,2014-11-12,2013-11-08
-3njq,2011-08-17,2010-06-17
-4nje,2014-12-10,2013-11-09
-4nj3,2013-11-27,2013-11-08
-6nj5,2019-10-02,2019-01-02
-6njh,2019-05-08,2019-01-03
-5nji,2017-05-31,2017-03-28
-1njt,2003-02-11,2003-01-02
-7njz,2021-07-21,2021-02-17
-7nj8,2021-06-16,2021-02-16
-4njj,2013-12-25,2013-11-10
-7njr,2021-10-27,2021-02-17
-6nje,2019-01-16,2019-01-03
-4njq,2014-04-02,2013-11-11
-5nj4,2017-08-16,2017-03-28
-1njs,2003-06-10,2003-01-02
-6njv,2019-08-07,2019-01-04
-4njs,2014-04-02,2013-11-11
-4njh,2013-12-25,2013-11-10
-4nju,2014-04-02,2013-11-11
-7njf,2021-06-16,2021-02-16
-4njr,2014-04-02,2013-11-11
-3nju,2010-07-14,2010-06-18
-3njv,2010-10-06,2010-06-18
-5njs,2017-10-18,2017-03-29
-3njp,2010-10-13,2010-06-17
-6nj8,2019-08-07,2019-01-02
-6njm,2019-04-24,2019-01-03
-5njw,2017-09-27,2017-03-29
-3njz,2011-07-13,2010-06-18
-5nj5,2017-10-04,2017-03-28
-1njd,1996-07-11,1996-01-23
-5nja,2017-10-04,2017-03-28
-6nji,2019-05-08,2019-01-03
-5nj7,2018-05-16,2017-03-28
-7njp,2021-10-27,2021-02-17
-1njc,1996-07-11,1996-01-23
-3njg,2010-07-14,2010-06-17
-4nji,2013-12-25,2013-11-10
-3nj1,2010-08-18,2010-06-16
-3njj,2010-07-21,2010-06-17
-3njy,2010-12-08,2010-06-18
-1njf,2003-04-08,2002-12-30
-6njj,2019-05-08,2019-01-03
-5njj,2017-12-13,2017-03-29
-6nja,2019-06-05,2019-01-02
-5nj0,2017-11-15,2017-03-27
-5njk,2017-12-13,2017-03-29
-3njo,2010-08-18,2010-06-17
-7nj6,2021-06-16,2021-02-16
-5nj9,2017-10-04,2017-03-28
-4nja,2014-11-12,2013-11-08
-4njv,2014-04-02,2013-11-11
-3nj8,2010-09-29,2010-06-17
-4nj5,2014-01-22,2013-11-08
-6nj9,2019-02-20,2019-01-02
-6njr,2019-02-27,2019-01-04
-6njo,2019-02-20,2019-01-03
-1nj5,2003-03-04,2002-12-30
-6njx,2019-08-07,2019-01-04
-5nje,2018-05-16,2017-03-28
-4njt,2014-04-02,2013-11-11
-7nj4,2021-12-01,2021-02-16
-6njp,2019-02-20,2019-01-03
-1njq,2003-03-04,2003-01-02
-5njq,2017-10-18,2017-03-29
-1nju,2003-02-11,2003-01-02
-1nja,1996-07-11,1996-01-23
-7nja,2021-06-16,2021-02-16
-6nj6,2019-10-02,2019-01-02
-1dtt,2000-04-02,2000-01-13
-1dtl,2000-05-12,2000-01-12
-6dtd,2019-02-20,2018-06-15
-4dtc,2013-02-27,2012-02-21
-8dt1,2022-08-17,2022-07-25
-5dte,2015-10-07,2015-09-18
-3dtr,2009-06-30,2008-07-15
-6dts,2018-09-19,2018-06-18
-7dtt,2021-03-10,2021-01-06
-4dtb,2012-03-07,2012-02-20
-8dt9,2024-02-07,2022-07-25
-4dtt,2013-02-27,2012-02-21
-2dtj,2007-05-01,2006-07-12
-4dtl,2012-08-29,2012-02-21
-8dtz,2024-01-31,2022-07-26
-7dt1,2022-01-12,2021-01-04
-7dtd,2021-04-07,2021-01-04
-1dt6,2000-09-27,2000-01-11
-8dtc,2022-08-10,2022-07-25
-6dtg,2018-11-28,2018-06-16
-8dtu,2023-02-01,2022-07-26
-4dtw,2012-06-13,2012-02-21
-8dto,2023-04-19,2022-07-26
-5dtt,2016-05-25,2015-09-18
-7dtv,2021-03-10,2021-01-06
-3dtx,2009-05-05,2008-07-16
-8dt8,2023-06-14,2022-07-25
-4dte,2013-03-27,2012-02-21
-2dts,2007-03-13,2006-07-14
-7dtm,2021-08-04,2021-01-06
-3dt1,2008-10-14,2008-07-14
-8dt6,2022-08-10,2022-07-25
-5dtr,2016-06-15,2015-09-18
-7dtn,2021-08-04,2021-01-06
-7dt5,2021-10-13,2021-01-04
-6dtu,2018-09-19,2018-06-18
-2dt2,2006-07-25,2006-07-09
-5dtk,2016-05-25,2015-09-18
-4dt3,2012-09-12,2012-02-20
-2dtx,2007-03-27,2006-07-18
-7dt6,2021-10-13,2021-01-04
-7dtz,2021-04-14,2021-01-07
-2dtt,2007-01-15,2006-07-15
-6dti,2019-04-24,2018-06-16
-3dtk,2009-02-17,2008-07-15
-5dtf,2016-02-17,2015-09-18
-3dty,2008-08-05,2008-07-16
-6dt1,2018-09-19,2018-06-14
-8dte,2022-08-10,2022-07-25
-1dtq,2000-03-20,2000-01-13
-5dtu,2016-05-04,2015-09-18
-6dt4,2018-06-27,2018-06-15
-5dtv,2016-05-04,2015-09-18
-4dtf,2012-08-29,2012-02-21
-4dtu,2012-06-06,2012-02-21
-7dt0,2022-01-12,2021-01-04
-7dta,2021-07-21,2021-01-04
-7dts,2021-11-24,2021-01-06
-4dts,2012-06-06,2012-02-21
-3dt9,2009-05-12,2008-07-14
-8dt7,2022-11-02,2022-07-25
-8dtm,2022-09-07,2022-07-26
-3dta,2009-06-30,2008-07-14
-5dt2,2016-06-15,2015-09-17
-6dt8,2018-07-11,2018-06-15
-4dta,2012-03-07,2012-02-20
-8dt4,2022-11-02,2022-07-25
-4dt6,2012-04-11,2012-02-20
-8dti,2023-03-08,2022-07-25
-2dt5,2007-01-02,2006-07-11
-4dtr,2012-06-06,2012-02-21
-7dt2,2021-06-09,2021-01-04
-2dtw,2006-11-07,2006-07-18
-2dt3,2006-08-01,2006-07-09
-2dtr,1997-08-20,1996-07-26
-3dt3,2008-09-09,2008-07-14
-6dtc,2019-06-19,2018-06-15
-6dtw,2019-07-31,2018-06-18
-1dtu,2000-03-06,2000-01-13
-8dt5,2022-11-02,2022-07-25
-8dtq,2023-08-02,2022-07-26
-5dto,2015-11-25,2015-09-18
-5dt3,2016-07-20,2015-09-17
-4dtk,2012-07-11,2012-02-21
-3dtb,2008-08-26,2008-07-14
-8dtb,2023-05-31,2022-07-25
-2dti,2007-01-12,2006-07-12
-3dt7,2008-08-26,2008-07-14
-4dty,2012-06-13,2012-02-21
-4dth,2012-08-29,2012-02-21
-3dt2,2008-08-26,2008-07-14
-6dtk,2019-06-19,2018-06-17
-4dtz,2012-06-13,2012-02-21
-3dti,2009-02-10,2008-07-15
-7dtb,2021-01-20,2021-01-04
-5dt0,2016-07-20,2015-09-17
-1dti,2000-01-30,2000-01-12
-6dth,2018-11-28,2018-06-16
-3dt0,2009-06-23,2008-07-14
-2dty,2006-11-07,2006-07-19
-5dtj,2015-10-21,2015-09-18
-7dtc,2021-03-24,2021-01-04
-2dt8,2007-06-19,2006-07-11
-6dta,2018-07-11,2018-06-15
-1dtg,2000-01-21,2000-01-12
-8dtj,2023-03-08,2022-07-25
-8dtw,2022-09-21,2022-07-26
-6dtf,2018-11-28,2018-06-16
-8dtd,2023-08-02,2022-07-25
-6dtx,2019-07-31,2018-06-18
-4dtx,2012-06-06,2012-02-21
-4dto,2012-06-06,2012-02-21
-3dtg,2009-06-23,2008-07-15
-1dtw,2000-03-27,2000-01-13
-4dtp,2012-06-06,2012-02-21
-1dtn,1996-10-14,1996-03-28
-8dta,2023-07-05,2022-07-25
-1dty,2000-02-18,2000-01-13
-7dty,2021-08-04,2021-01-06
-3dtw,2008-09-09,2008-07-16
-6dtn,2019-04-03,2018-06-18
-4dt9,2012-03-07,2012-02-20
-5dt1,2015-10-21,2015-09-17
-5dt4,2016-07-20,2015-09-17
-2dt9,2007-07-17,2006-07-11
-1dt7,2000-07-26,2000-01-11
-2dth,2007-01-12,2006-07-12
-3dtt,2008-08-12,2008-07-15
-4dtj,2012-06-06,2012-02-21
-1dt1,2000-02-18,2000-01-10
-8dtk,2023-08-02,2022-07-25
-7dt3,2021-10-13,2021-01-04
-2dte,2007-03-27,2006-07-12
-4dtm,2012-06-06,2012-02-21
-3dt4,2008-08-26,2008-07-14
-5dt9,2015-09-30,2015-09-17
-6dtp,2018-09-12,2018-06-18
-4dt8,2012-03-07,2012-02-20
-8dty,2024-01-31,2022-07-26
-1dt0,2000-12-20,2000-01-10
-3dtn,2008-09-09,2008-07-15
-7dtu,2021-03-10,2021-01-06
-7dte,2021-10-20,2021-01-04
-4dt2,2012-09-19,2012-02-20
-6dtq,2018-09-19,2018-06-18
-4dti,2012-10-03,2012-02-21
-7dt9,2022-01-12,2021-01-04
-3dtc,2009-03-31,2008-07-14
-1dth,1997-02-12,1996-02-12
-5dts,2016-05-25,2015-09-18
-6dt0,2018-07-11,2018-06-14
-5dt6,2016-09-28,2015-09-17
-1dtm,2000-02-07,2000-01-12
-6dte,2019-04-24,2018-06-15
-6dt7,2018-07-11,2018-06-15
-2dto,2007-01-13,2006-07-13
-4dt7,2012-05-09,2012-02-20
-3dts,2009-06-30,2008-07-15
-8dts,2024-01-31,2022-07-26
-7dtf,2021-01-20,2021-01-04
-3dt5,2008-07-29,2008-07-14
-8dt3,2022-08-03,2022-07-25
-4dtn,2012-06-06,2012-02-21
-8dtp,2023-06-14,2022-07-26
-2dt1,2006-08-01,2006-07-09
-7dtw,2021-03-10,2021-01-06
-5dtb,2016-09-28,2015-09-17
-1dtd,2000-07-12,2000-01-12
-5dtm,2016-06-15,2015-09-18
-7dt8,2021-10-13,2021-01-04
-1dtp,1994-11-01,1994-09-08
-2dt0,2006-07-25,2006-07-09
-8dtn,2023-02-01,2022-07-26
-5dtq,2016-06-15,2015-09-18
-3dtu,2008-09-16,2008-07-15
-4o6w,2014-12-03,2013-12-23
-5o6q,2017-12-13,2017-06-07
-4o6d,2014-02-19,2013-12-20
-6o6c,2019-06-26,2019-03-05
-5o6p,2018-06-20,2017-06-07
-6o6z,2019-07-31,2019-03-07
-3o6r,2011-08-17,2010-07-29
-5o6y,2018-06-20,2017-06-07
-3o6j,2011-08-17,2010-07-29
-4o6s,2014-03-26,2013-12-23
-6o6e,2020-04-08,2019-03-06
-4o6n,2014-05-14,2013-12-22
-4o6j,2014-05-21,2013-12-20
-5o6t,2017-11-01,2017-06-07
-4o6h,2014-06-11,2013-12-20
-4o6a,2014-02-05,2013-12-20
-4o68,2014-02-05,2013-12-20
-4o6b,2014-02-19,2013-12-20
-7o65,2021-10-13,2021-04-09
-1o6e,2002-11-14,2002-09-13
-6o61,2019-07-10,2019-03-05
-4o6i,2014-06-11,2013-12-20
-1o69,2003-11-11,2003-10-23
-7o67,2021-10-13,2021-04-09
-1o6r,2003-10-17,2002-10-13
-7o6i,2021-06-09,2021-04-11
-3o65,2010-11-24,2010-07-28
-6o62,2019-04-03,2019-03-05
-4o6u,2014-03-26,2013-12-23
-7o66,2021-10-13,2021-04-09
-7o6y,2021-11-10,2021-04-12
-3o6i,2010-09-15,2010-07-29
-3o69,2011-05-11,2010-07-28
-6o6r,2019-09-18,2019-03-07
-5o60,2017-07-12,2017-06-02
-1o6b,2003-11-25,2003-11-03
-2o60,2007-12-25,2006-12-06
-3o6t,2010-11-10,2010-07-29
-4o66,2014-05-14,2013-12-20
-7o6o,2021-06-09,2021-04-11
-6o6v,2019-07-31,2019-03-07
-4o6z,2014-06-11,2013-12-24
-7o6a,2021-10-13,2021-04-09
-5o61,2017-07-12,2017-06-03
-4o6c,2014-02-19,2013-12-20
-4o6p,2014-12-10,2013-12-23
-5o6n,2017-12-13,2017-06-07
-2o6w,2007-12-18,2006-12-08
-2o69,2007-04-03,2006-12-07
-6o67,2019-11-06,2019-03-05
-5o6j,2018-05-16,2017-06-06
-7o6x,2022-01-12,2021-04-12
-4o6l,2014-12-24,2013-12-22
-4o6e,2014-05-21,2013-12-20
-3o6g,2010-09-15,2010-07-29
-5o6r,2018-06-20,2017-06-07
-6o68,2019-11-06,2019-03-05
-3o6h,2010-09-15,2010-07-29
-4o62,2014-03-26,2013-12-20
-1o6t,2002-12-23,2002-10-15
-5o63,2017-08-02,2017-06-05
-1o6v,2002-12-23,2002-10-16
-2o6a,2007-04-03,2006-12-07
-3o6m,2010-11-10,2010-07-29
-4o6q,2014-03-26,2013-12-23
-1o6g,2002-11-18,2002-09-15
-7o6r,2022-05-04,2021-04-12
-7o6s,2022-04-20,2021-04-12
-5o6m,2018-03-21,2017-06-06
-7o6t,2022-11-09,2021-04-12
-2o6m,2007-10-30,2006-12-07
-1o68,2003-11-11,2003-10-23
-6o66,2019-05-29,2019-03-05
-2o68,2007-04-03,2006-12-07
-3o64,2011-04-20,2010-07-28
-4o64,2014-04-16,2013-12-20
-4o65,2014-04-02,2013-12-20
-6o6x,2019-07-31,2019-03-07
-6o6y,2019-07-31,2019-03-07
-2o6e,2006-12-26,2006-12-07
-7o68,2021-10-13,2021-04-09
-5o6z,2018-06-06,2017-06-07
-4o6y,2014-02-05,2013-12-24
-7o6c,2021-10-13,2021-04-09
-7o6h,2022-04-20,2021-04-11
-7o6z,2021-09-01,2021-04-12
-7o6k,2021-06-09,2021-04-11
-5o6v,2018-02-07,2017-06-07
-2o6p,2007-02-06,2006-12-08
-5o6a,2018-02-07,2017-06-06
-7o6g,2021-06-09,2021-04-11
-7o6m,2021-06-09,2021-04-11
-3o6p,2010-09-22,2010-07-29
-7o63,2021-10-13,2021-04-09
-4o6m,2014-05-14,2013-12-22
-3o6d,2010-08-11,2010-07-28
-3o61,2011-05-11,2010-07-28
-5o6h,2018-05-16,2017-06-06
-6o60,2019-06-26,2019-03-04
-2o65,2007-02-13,2006-12-06
-1o6f,2002-11-18,2002-09-15
-5o64,2017-08-16,2017-06-05
-6o6j,2019-09-11,2019-03-06
-1o6k,2002-11-19,2002-10-08
-6o6g,2019-05-15,2019-03-06
-2o6i,2006-12-19,2006-12-07
-4o6r,2014-01-22,2013-12-23
-5o6e,2017-12-20,2017-06-06
-1o6h,2003-10-02,2002-10-03
-4o6t,2014-03-26,2013-12-23
-4o63,2014-09-24,2013-12-20
-3o6z,2011-05-11,2010-07-29
-6o65,2019-06-05,2019-03-05
-5o6c,2018-04-18,2017-06-06
-4o6o,2014-12-10,2013-12-23
-2o6n,2007-10-23,2006-12-07
-2o63,2007-02-13,2006-12-06
-2o6d,2006-12-26,2006-12-07
-3o6o,2010-08-18,2010-07-29
-1o6p,2003-04-24,2002-10-10
-1o6q,2003-10-17,2002-10-13
-1o6o,2003-10-17,2002-10-10
-5o65,2017-08-23,2017-06-05
-5o6g,2017-12-06,2017-06-06
-5o6x,2018-06-06,2017-06-07
-2o6h,2007-08-14,2006-12-07
-6o6l,2019-07-31,2019-03-07
-7o6d,2021-10-13,2021-04-09
-5o6o,2018-06-06,2017-06-07
-5o6d,2017-12-13,2017-06-06
-1o6s,2002-12-13,2002-10-13
-6o69,2019-05-01,2019-03-05
-2o64,2007-02-13,2006-12-06
-7o69,2021-10-13,2021-04-09
-4o6f,2014-03-26,2013-12-20
-6o6a,2019-09-18,2019-03-05
-6o6q,2019-04-03,2019-03-07
-7o6j,2021-06-09,2021-04-11
-1o61,2003-11-11,2003-10-23
-1o6l,2002-11-19,2002-10-08
-6o6b,2020-03-11,2019-03-05
-3o6x,2011-03-09,2010-07-29
-7o6f,2021-06-09,2021-04-11
-5o6b,2017-12-13,2017-06-06
-3o6n,2010-09-22,2010-07-29
-6o6m,2019-07-31,2019-03-07
-1o6z,2003-02-06,2002-10-22
-4o67,2014-02-05,2013-12-20
-7o64,2021-10-13,2021-04-09
-5o6i,2017-12-06,2017-06-06
-4o69,2014-02-05,2013-12-20
-1o6y,2003-01-30,2002-10-21
-6o6f,2019-05-15,2019-03-06
-7gb2,2023-11-08,2023-08-11
-6gb9,2018-07-18,2018-04-13
-4gbp,2013-12-25,2012-07-27
-2gbp,1990-07-15,1989-02-23
-2gba,2006-08-01,2006-03-10
-2gbx,2007-03-20,2006-03-12
-4gbr,2012-10-24,2012-07-27
-4gb9,2012-08-22,2012-07-26
-4gb0,2013-07-10,2012-07-26
-7gbu,2023-11-08,2023-08-11
-3gbo,2009-09-22,2009-02-20
-4gbu,2012-08-29,2012-07-28
-8gb7,2023-05-24,2023-02-24
-6gbl,2018-10-24,2018-04-15
-3gbm,2009-03-10,2009-02-20
-8gbh,2023-11-15,2023-02-26
-7gbr,2023-11-08,2023-08-11
-7gbk,2023-11-08,2023-08-11
-7gbm,2023-11-08,2023-08-11
-4gbk,2013-06-12,2012-07-27
-7gb3,2023-11-08,2023-08-11
-2gbz,2007-01-16,2006-03-12
-4gb1,2012-09-26,2012-07-26
-3gb4,2009-07-28,2009-02-18
-4gbj,2012-09-05,2012-07-27
-6gb3,2018-07-18,2018-04-13
-2gb5,2006-03-28,2006-03-09
-6gby,2019-01-30,2018-04-16
-1gbl,1996-01-29,1995-09-06
-6gb8,2019-01-30,2018-04-13
-1gbb,1996-01-29,1995-09-06
-8gbk,2024-04-24,2023-02-26
-7gbs,2023-11-08,2023-08-11
-4gby,2012-10-17,2012-07-28
-2gb4,2006-09-19,2006-03-09
-7gbo,2023-11-08,2023-08-11
-7gbh,2023-11-08,2023-08-11
-2gbv,2007-01-02,2006-03-11
-2gbr,2006-05-16,2006-03-10
-6gb4,2018-07-18,2018-04-13
-2gby,2008-04-08,2006-03-12
-7gbl,2023-11-08,2023-08-11
-6gb5,2019-03-06,2018-04-13
-6gbc,2018-07-18,2018-04-13
-7gb0,2023-11-08,2023-08-11
-1gbd,1996-01-29,1995-09-06
-1gbi,1996-01-29,1995-09-06
-3gb9,2009-04-14,2009-02-19
-3gb2,2010-03-02,2009-02-18
-4gbl,2013-06-12,2012-07-27
-7gb8,2023-11-08,2023-08-11
-1gbu,1997-01-11,1996-01-04
-2gbf,2006-07-04,2006-03-10
-3gbp,1991-07-15,1990-01-25
-7gbc,2023-11-08,2023-08-11
-4gbe,2014-02-26,2012-07-27
-8gb2,2023-06-07,2023-02-24
-6gb0,2018-07-18,2018-04-13
-6gbn,2018-08-08,2018-04-15
-7gbi,2023-11-08,2023-08-11
-7gbd,2023-11-08,2023-08-11
-3gbj,2009-03-03,2009-02-19
-3gbr,2009-12-15,2009-02-20
-7gbg,2023-11-08,2023-08-11
-7gbv,2023-11-08,2023-08-11
-8gb6,2023-05-24,2023-02-24
-7gbw,2023-11-08,2023-08-11
-4gba,2012-11-28,2012-07-26
-2gbi,2006-07-04,2006-03-10
-8gbu,2023-09-06,2023-02-28
-7gbf,2023-11-08,2023-08-11
-1gbg,1995-12-07,1995-08-25
-4gbi,2013-06-12,2012-07-27
-7gb1,2023-11-08,2023-08-11
-8gbn,2024-06-05,2023-02-26
-3gbv,2009-03-10,2009-02-20
-8gbq,2023-07-19,2023-02-27
-2gbc,2006-07-04,2006-03-10
-4gbm,2012-10-17,2012-07-27
-1gbc,1996-01-29,1995-09-06
-7gbb,2023-11-08,2023-08-11
-4gbc,2013-06-12,2012-07-27
-7gbn,2023-11-08,2023-08-11
-6gbj,2018-10-24,2018-04-15
-3gbf,2009-06-09,2009-02-19
-7gbz,2023-11-08,2023-08-11
-1gbv,1997-01-11,1995-12-20
-7gb9,2023-11-08,2023-08-11
-3gbb,2009-03-17,2009-02-19
-6gbi,2018-08-15,2018-04-14
-6gb7,2019-03-06,2018-04-13
-2gbm,2006-05-16,2006-03-10
-8gbl,2024-06-05,2023-02-26
-7gbq,2023-11-08,2023-08-11
-7gb7,2023-11-08,2023-08-11
-7gbe,2023-11-08,2023-08-11
-3gbu,2009-03-10,2009-02-20
-4gbn,2013-06-12,2012-07-27
-3gb6,2009-03-31,2009-02-18
-3gba,2009-03-17,2009-02-19
-8gbo,2023-11-15,2023-02-26
-8gb5,2023-05-24,2023-02-24
-1gbh,1996-01-29,1995-09-06
-7gbp,2023-11-08,2023-08-11
-6gbx,2018-09-19,2018-04-16
-8gb1,2023-06-07,2023-02-24
-1gbm,1996-01-29,1995-09-06
-1gbk,1996-01-29,1995-09-06
-4gbd,2013-06-12,2012-07-27
-1gbf,1996-01-29,1995-09-06
-2gb7,2006-06-20,2006-03-10
-8gbm,2023-11-15,2023-02-26
-2gb2,2006-08-01,2006-03-09
-4gbz,2012-10-17,2012-07-28
-7gbj,2023-11-08,2023-08-11
-2gbl,2007-01-23,2006-03-10
-3gbk,2009-12-29,2009-02-19
-7gbt,2023-11-08,2023-08-11
-7gbx,2023-11-08,2023-08-11
-8gbi,2023-11-15,2023-02-26
-6gbt,2019-04-24,2018-04-16
-6gbv,2018-07-18,2018-04-16
-4gbx,2013-01-16,2012-07-28
-3gb5,2009-05-12,2009-02-18
-4gb2,2013-07-31,2012-07-26
-8gbt,2023-09-20,2023-02-28
-7gb4,2023-11-08,2023-08-11
-4gbv,2013-08-21,2012-07-28
-6gbw,2019-04-24,2018-04-16
-8gbj,2023-06-21,2023-02-26
-3gbn,2009-03-10,2009-02-20
-2gb8,2006-11-21,2006-03-10
-2gbw,2007-03-20,2006-03-12
-6gbb,2019-01-30,2018-04-13
-1gbz,2000-07-27,2000-06-26
-7gby,2023-11-08,2023-08-11
-8gb4,2024-03-13,2023-02-24
-6gb2,2018-08-08,2018-04-13
-7gb5,2023-11-08,2023-08-11
-4gbf,2012-10-17,2012-07-27
-7gb6,2023-11-08,2023-08-11
-8gbf,2024-02-28,2023-02-25
-6gbf,2018-07-18,2018-04-13
-4gbg,2012-08-22,2012-07-27
-6gb6,2019-03-06,2018-04-13
-2gb0,2006-03-21,2006-03-09
-8gb9,2023-11-15,2023-02-24
-1gbn,1998-06-03,1997-05-29
-8gb8,2023-05-24,2023-02-24
-8gba,2023-11-15,2023-02-24
-1gbt,1994-01-31,1991-09-17
-3gbe,2009-05-26,2009-02-19
-6gba,2018-07-18,2018-04-13
-6gbp,2018-10-10,2018-04-16
-2gbg,2006-07-04,2006-03-10
-3gb7,2009-11-17,2009-02-18
-7gba,2023-11-08,2023-08-11
-3gbh,2009-03-03,2009-02-19
-4gbt,2013-02-27,2012-07-27
-6gbk,2018-10-24,2018-04-15
-4gbw,2013-08-21,2012-07-28
-2gbt,2007-01-02,2006-03-11
-7m7o,2021-06-02,2021-03-28
-4m7t,2013-10-02,2013-08-12
-3m7j,2011-03-23,2010-03-16
-7m7k,2021-08-25,2021-03-28
-7m7d,2021-09-01,2021-03-27
-7m7f,2021-11-17,2021-03-28
-4m7a,2013-11-13,2013-08-12
-5m7z,2017-12-20,2016-10-28
-1m7i,2003-07-22,2002-07-19
-7m7v,2022-02-16,2021-03-29
-2m7v,2014-01-01,2013-05-01
-5m7g,2017-02-22,2016-10-27
-1m7j,2003-02-25,2002-07-22
-5m7e,2017-02-22,2016-10-27
-3m7u,2011-02-09,2010-03-17
-6m7o,2018-09-12,2018-08-20
-1m7a,2003-03-04,2002-07-19
-1m72,2004-01-20,2002-07-18
-6m72,2020-10-14,2020-03-16
-4m76,2013-10-02,2013-08-12
-3m7p,2010-06-23,2010-03-17
-6m79,2020-10-14,2020-03-18
-3m7v,2010-04-07,2010-03-17
-4m7j,2014-04-09,2013-08-12
-5m73,2016-12-07,2016-10-26
-7m7u,2021-06-02,2021-03-28
-6m7h,2019-08-28,2018-08-20
-7m7l,2021-06-02,2021-03-28
-5m70,2017-05-17,2016-10-26
-7m7t,2021-06-02,2021-03-28
-6m73,2021-03-17,2020-03-16
-3m7n,2010-04-28,2010-03-16
-1m7z,2002-10-30,2002-07-23
-4m7r,2013-10-30,2013-08-12
-5m72,2016-12-07,2016-10-26
-4m7e,2013-10-16,2013-08-12
-4m7d,2013-11-13,2013-08-12
-5m7s,2017-03-29,2016-10-28
-7m7a,2021-04-28,2021-03-27
-5m7p,2017-01-25,2016-10-28
-7m7z,2021-06-02,2021-03-29
-5m71,2018-06-06,2016-10-26
-5m78,2017-12-20,2016-10-27
-2m7n,2013-06-19,2013-04-26
-6m7d,2021-03-24,2020-03-18
-4m7m,2013-10-09,2013-08-12
-7m76,2021-11-24,2021-03-26
-4m7k,2014-03-26,2013-08-12
-1m7g,2002-11-27,2002-07-19
-1m75,2004-02-03,2002-07-18
-1m74,2002-09-20,2002-07-16
-5m7i,2016-11-30,2016-10-27
-4m71,2014-06-25,2013-08-12
-7m72,2021-11-10,2021-03-26
-1m7p,2002-11-29,2002-07-22
-7m7y,2021-06-02,2021-03-29
-5m7j,2017-02-08,2016-10-28
-5m7h,2017-12-20,2016-10-27
-1m7d,2003-07-22,2002-07-19
-7m7w,2021-05-05,2021-03-29
-1m7b,2002-08-07,2002-07-19
-4m7f,2013-12-11,2013-08-12
-4m7h,2013-12-11,2013-08-12
-6m7t,2018-09-12,2018-08-21
-2m7a,2013-06-12,2013-04-18
-3m7w,2010-04-07,2010-03-17
-4m7v,2014-03-05,2013-08-12
-4m7b,2014-03-12,2013-08-12
-6m7v,2018-09-12,2018-08-21
-1m70,2003-09-16,2002-07-18
-5m7u,2017-03-29,2016-10-28
-5m7y,2016-11-30,2016-10-28
-3m7o,2010-06-09,2010-03-17
-1m78,2003-03-04,2002-07-19
-7m7m,2021-06-02,2021-03-28
-5m7m,2017-08-30,2016-10-28
-5m7a,2017-11-29,2016-10-27
-4m7p,2013-09-11,2013-08-12
-4m7y,2014-09-03,2013-08-12
-5m7t,2017-03-29,2016-10-28
-2m7u,2014-01-01,2013-05-01
-7m7s,2021-06-02,2021-03-28
-1m76,2004-02-03,2002-07-18
-1m79,2003-03-04,2002-07-19
-1m7v,2002-10-30,2002-07-22
-6m7g,2019-04-24,2018-08-20
-3m7r,2010-05-05,2010-03-17
-5m7o,2017-01-25,2016-10-28
-2m7y,2013-10-23,2013-05-02
-3m7k,2010-04-21,2010-03-16
-7m7q,2021-06-02,2021-03-28
-3m79,2010-06-16,2010-03-16
-5m7b,2017-11-29,2016-10-27
-5m79,2017-11-29,2016-10-27
-6m7x,2018-11-21,2018-08-21
-7m7i,2021-11-17,2021-03-28
-5m7w,2017-12-20,2016-10-28
-4m7z,2014-04-09,2013-08-12
-7m7n,2021-06-02,2021-03-28
-7m75,2021-11-24,2021-03-26
-7m74,2021-12-15,2021-03-26
-4m7i,2014-09-03,2013-08-12
-1m7h,2002-11-27,2002-07-19
-4m74,2014-06-25,2013-08-12
-1m7e,2003-08-05,2002-07-19
-5m7l,2017-02-08,2016-10-28
-1m7q,2002-12-11,2002-07-22
-4m7u,2014-03-05,2013-08-12
-6m7u,2018-09-12,2018-08-21
-4m73,2014-06-25,2013-08-12
-5m7x,2017-11-29,2016-10-28
-2m7p,2013-08-14,2013-04-29
-5m7q,2016-11-09,2016-10-28
-6m74,2021-03-17,2020-03-16
-6m7p,2018-09-12,2018-08-20
-6m7e,2020-04-15,2020-03-18
-5m77,2017-08-09,2016-10-26
-6m7j,2018-11-21,2018-08-20
-5m7c,2017-11-29,2016-10-27
-5m75,2018-06-06,2016-10-26
-5m7d,2017-11-29,2016-10-27
-3m7i,2010-04-07,2010-03-16
-3m7s,2010-05-05,2010-03-17
-6m7i,2019-04-17,2018-08-20
-4m7x,2014-09-03,2013-08-12
-1m7y,2002-12-23,2002-07-23
-6m7l,2019-05-22,2018-08-20
-2m7m,2013-06-19,2013-04-26
-1m7s,2002-08-28,2002-07-22
-5m7n,2017-01-25,2016-10-28
-5m7f,2017-11-15,2016-10-27
-6m77,2020-05-20,2020-03-17
-7m7r,2021-06-02,2021-03-28
-7m78,2021-11-24,2021-03-26
-7m7b,2021-05-26,2021-03-27
-5m7k,2017-02-08,2016-10-28
-2m7q,2013-12-04,2013-04-29
-6m75,2021-03-17,2020-03-17
-4m72,2014-06-25,2013-08-12
-2m7b,2013-06-12,2013-04-18
-7m71,2021-05-26,2021-03-26
-7m7p,2021-06-02,2021-03-28
-6m7k,2019-02-20,2018-08-20
-5m7v,2017-12-20,2016-10-28
-5cfb,2015-09-30,2015-07-08
-7cf6,2020-12-30,2020-06-24
-8cfc,2024-02-21,2023-02-03
-6cff,2019-03-13,2018-02-14
-8cfo,2024-02-21,2023-02-03
-1cfa,1997-09-17,1996-09-21
-4cfw,2013-12-18,2013-11-19
-8cfi,2024-02-21,2023-02-03
-4cfq,2014-05-07,2013-11-19
-4cf0,2013-11-20,2013-11-13
-1cft,1999-03-31,1999-03-19
-2cfd,2007-05-01,2006-02-20
-5cfv,2016-07-13,2015-07-08
-6cfl,2018-03-07,2018-02-15
-2cfr,2007-02-27,2006-02-23
-5cf6,2015-08-26,2015-07-08
-7cfw,2020-11-04,2020-06-29
-7cfs,2020-10-21,2020-06-28
-2cft,2007-02-27,2006-02-23
-6cfg,2019-02-13,2018-02-14
-8cfg,2024-02-21,2023-02-03
-7cfk,2021-04-21,2020-06-25
-8cf6,2023-07-05,2023-02-02
-5cfe,2016-07-06,2015-07-08
-8cf0,2024-02-21,2023-02-02
-7cfq,2021-07-07,2020-06-27
-7cfm,2020-09-09,2020-06-27
-4cfh,2013-12-25,2013-11-18
-2cfw,2007-05-01,2006-02-24
-2cf4,2006-09-14,2006-02-15
-3cf9,2008-12-09,2008-03-03
-4cfs,2013-12-04,2013-11-19
-1cf5,1999-06-07,1999-03-24
-2cfu,2006-04-26,2006-02-23
-2cfk,2007-05-01,2006-02-21
-3cfx,2009-03-10,2008-03-04
-3cf6,2008-07-29,2008-03-02
-3cfr,2009-03-10,2008-03-04
-6cfd,2018-05-16,2018-02-14
-8cfy,2024-02-21,2023-02-03
-5cfq,2015-08-26,2015-07-08
-6cf5,2018-04-04,2018-02-13
-6cf0,2018-05-02,2018-02-13
-2cfg,2007-05-01,2006-02-21
-4cf8,2013-12-11,2013-11-14
-6cfr,2018-05-09,2018-02-17
-1cf9,1999-04-06,1999-03-24
-7cfp,2021-07-07,2020-06-27
-6cft,2018-05-09,2018-02-17
-3cfd,2008-03-18,2008-03-03
-8cfx,2024-02-21,2023-02-03
-7cfn,2020-09-09,2020-06-27
-4cfv,2014-12-10,2013-11-19
-1cf4,1999-06-18,1999-03-23
-4cf6,2014-08-27,2013-11-13
-8cfu,2024-02-21,2023-02-03
-8cfb,2024-02-21,2023-02-03
-5cf5,2015-08-26,2015-07-08
-8cfq,2024-02-21,2023-02-03
-5cf4,2015-08-26,2015-07-08
-4cf7,2014-12-03,2013-11-13
-8cfm,2024-02-21,2023-02-03
-3cfl,2008-03-18,2008-03-04
-8cfd,2024-02-21,2023-02-03
-3cfo,2009-03-10,2008-03-04
-6cfk,2018-03-07,2018-02-15
-2cfo,2006-08-16,2006-02-22
-6cf1,2019-02-27,2018-02-13
-1cfb,1994-11-30,1994-08-27
-1cfv,1997-10-15,1997-04-11
-1cfw,1999-07-09,1999-03-22
-4cfo,2014-07-23,2013-11-19
-6cfu,2018-05-09,2018-02-17
-6cfc,2018-05-30,2018-02-14
-2cfm,2006-07-12,2006-02-22
-1cf3,1999-03-26,1999-03-23
-8cft,2024-02-21,2023-02-03
-8cf9,2024-02-21,2023-02-03
-4cfd,2013-11-27,2013-11-14
-6cfo,2018-07-11,2018-02-15
-7cfg,2021-02-24,2020-06-25
-3cfk,2008-04-15,2008-03-04
-2cfs,2007-02-27,2006-02-23
-3cft,2009-03-03,2008-03-04
-7cft,2020-10-21,2020-06-28
-8cfv,2024-02-21,2023-02-03
-2cfl,2007-05-01,2006-02-22
-2cfq,2006-03-13,2006-02-22
-5cfm,2015-08-26,2015-07-08
-8cfn,2024-02-21,2023-02-03
-3cf4,2008-07-22,2008-03-01
-8cf1,2023-07-26,2023-02-02
-8cff,2023-07-12,2023-02-03
-6cfj,2018-03-07,2018-02-15
-4cf1,2013-12-18,2013-11-13
-2cfa,2006-05-16,2006-02-17
-3cfn,2009-03-03,2008-03-04
-7cff,2021-02-24,2020-06-25
-1cff,1999-09-24,1999-03-18
-8cf5,2023-09-20,2023-02-02
-6cfq,2018-02-28,2018-02-16
-4cfx,2014-12-10,2013-11-19
-4cfb,2013-11-27,2013-11-14
-5cfn,2015-08-26,2015-07-08
-3cf5,2008-06-17,2008-03-02
-5cfu,2016-07-20,2015-07-08
-8cf7,2023-07-05,2023-02-02
-7cfc,2021-06-02,2020-06-25
-4cfl,2014-01-15,2013-11-18
-2cfc,2006-07-26,2006-02-19
-5cfa,2015-09-23,2015-07-08
-7cfe,2021-06-30,2020-06-25
-3cfw,2008-03-18,2008-03-04
-7cfi,2021-02-24,2020-06-25
-4cfk,2014-01-15,2013-11-18
-6cfw,2018-05-23,2018-02-17
-1cfj,1999-06-25,1999-03-19
-7cfo,2021-01-06,2020-06-27
-1cf8,1999-07-28,1999-03-24
-5cfs,2016-03-16,2015-07-08
-5cfw,2016-04-20,2015-07-08
-5cf3,2015-09-23,2015-07-08
-5cf9,2015-07-22,2015-07-08
-4cfm,2014-12-10,2013-11-18
-1cfz,2000-03-22,1999-03-23
-2cf7,2006-09-28,2006-02-16
-8cfh,2024-02-21,2023-02-03
-8cfs,2024-02-21,2023-02-03
-1cf2,2000-03-29,1999-03-24
-2cfb,2006-03-29,2006-02-17
-6cfn,2018-09-26,2018-02-15
-8cfw,2024-02-21,2023-02-03
-3cf3,2008-04-22,2008-03-01
-2cfp,2006-03-13,2006-02-22
-7cfu,2021-06-30,2020-06-28
-2cf6,2007-02-20,2006-02-16
-2cf5,2007-02-20,2006-02-16
-8cfj,2024-02-21,2023-02-03
-4cft,2014-02-19,2013-11-19
-4cfu,2014-12-10,2013-11-19
-8cfp,2024-02-21,2023-02-03
-8cfk,2024-02-21,2023-02-03
-4cfa,2013-11-27,2013-11-14
-8cfr,2024-02-21,2023-02-03
-4cff,2013-12-25,2013-11-14
-4cfe,2013-12-25,2013-11-14
-1cfn,1999-03-30,1999-03-19
-6cfm,2018-03-07,2018-02-15
-6cf3,2019-02-13,2018-02-13
-8cf8,2023-08-02,2023-02-03
-3cfs,2008-06-10,2008-03-04
-5cf0,2016-07-13,2015-07-08
-4cf2,2013-11-20,2013-11-13
-4cfn,2013-12-18,2013-11-19
-8cfl,2024-02-21,2023-02-03
-4cfc,2013-11-27,2013-11-14
-3cf2,2008-04-22,2008-03-01
-3cf1,2008-04-22,2008-03-01
-3cf0,2008-04-22,2008-03-01
-6cfs,2018-05-09,2018-02-17
-5cf8,2015-08-26,2015-07-08
-4cfy,2014-04-09,2013-11-19
-6cfv,2018-05-09,2018-02-17
-2cf9,2006-06-14,2006-02-17
-5cfy,2016-04-20,2015-07-08
-7cf9,2020-09-02,2020-06-24
-8cfe,2024-02-21,2023-02-03
-4cfp,2014-07-23,2013-11-19
-2cfv,2006-03-09,2006-02-23
-4cf9,2013-11-27,2013-11-14
-2cfy,2006-03-09,2006-02-26
-5cfr,2015-08-26,2015-07-08
-6cfp,2018-04-11,2018-02-15
-1cfs,1999-03-31,1999-03-19
-5cft,2016-03-16,2015-07-08
-1cfm,1999-04-27,1998-09-18
-4cfz,2014-04-09,2013-11-19
-5cfl,2015-08-26,2015-07-08
-1cf0,1999-07-06,1999-03-23
-3cfp,2009-03-10,2008-03-04
-4cfr,2014-05-07,2013-11-19
-7cfx,2021-06-30,2020-06-29
-5cfp,2015-08-26,2015-07-08
-2cfi,2006-03-14,2006-02-21
-2cfz,2006-04-26,2006-02-26
-6cf4,2018-05-23,2018-02-13
-7cfd,2021-06-02,2020-06-25
-3cfb,2008-03-18,2008-03-03
-5cfg,2016-07-06,2015-07-08
-6cf7,2019-02-13,2018-02-13
-2cf8,2006-06-14,2006-02-17
-2cfe,2006-02-22,2006-02-20
-3cf8,2008-12-09,2008-03-03
-3cfq,2009-03-03,2008-03-04
-3cfv,2008-06-10,2008-03-04
-6vza,2020-11-11,2020-02-28
-6vz0,2020-11-25,2020-02-27
-7vzt,2023-05-31,2021-11-16
-5vzj,2017-08-02,2017-05-28
-7vzr,2022-12-28,2021-11-16
-2vzt,2008-10-14,2008-08-05
-6vzr,2020-08-12,2020-02-28
-2vzb,2009-11-17,2008-07-31
-2vzo,2008-10-14,2008-08-05
-3vze,2013-10-16,2012-10-11
-5vzf,2017-07-05,2017-05-27
-6vzz,2020-03-25,2020-02-28
-6vzl,2021-03-03,2020-02-28
-5vzw,2017-08-09,2017-05-29
-2vzy,2009-04-07,2008-08-07
-1vzd,1997-03-12,1996-09-18
-7vze,2022-03-02,2021-11-16
-5vzh,2017-07-05,2017-05-27
-2vzq,2009-01-13,2008-08-05
-3vzd,2013-05-01,2012-10-11
-8vz8,2024-04-10,2024-02-11
-6vz8,2020-07-15,2020-02-27
-5vz8,2017-07-05,2017-05-27
-5vzt,2018-01-17,2017-05-29
-1vzg,2004-08-27,2004-05-19
-5vz9,2017-07-05,2017-05-27
-7vzv,2022-12-14,2021-11-16
-5vze,2017-07-05,2017-05-27
-6vzb,2020-11-11,2020-02-28
-5vz2,2017-06-21,2017-05-26
-1vz4,2004-11-15,2004-05-14
-7vzb,2022-05-18,2021-11-15
-5vz6,2018-05-30,2017-05-26
-5vzc,2017-07-05,2017-05-27
-3vzm,2013-05-08,2012-10-15
-7vza,2022-11-16,2021-11-15
-8vzl,2024-05-22,2024-02-11
-2vz6,2008-08-26,2008-07-30
-3vzu,2013-03-13,2012-10-15
-2vzs,2008-10-14,2008-08-05
-6vz7,2020-09-02,2020-02-27
-6vzg,2020-12-02,2020-02-28
-5vzp,2018-06-06,2017-05-29
-2vzz,2009-04-07,2008-08-07
-2vzu,2008-10-14,2008-08-05
-6vzh,2020-03-11,2020-02-28
-1vz0,2004-07-19,2004-05-12
-3vzs,2013-08-28,2012-10-15
-7vz6,2022-11-16,2021-11-15
-2vzr,2009-01-13,2008-08-05
-1vzu,2004-07-08,2004-05-27
-2vzp,2009-01-13,2008-08-05
-2vz7,2008-08-12,2008-07-30
-5vz7,2017-07-05,2017-05-27
-5vz0,2017-08-16,2017-05-26
-1vzc,1997-03-12,1996-09-18
-7vzz,2022-11-16,2021-11-17
-3vz3,2013-07-10,2012-10-09
-6vzw,2020-08-12,2020-02-28
-5vzs,2018-05-30,2017-05-29
-7vz8,2022-12-28,2021-11-15
-3vzy,2012-12-26,2012-10-17
-7vzn,2022-11-16,2021-11-16
-1vzy,2004-10-06,2004-05-29
-2vz1,2008-09-16,2008-07-29
-1vzx,2004-07-08,2004-05-28
-2vzv,2008-10-14,2008-08-05
-6vz4,2020-12-02,2020-02-27
-5vzu,2018-01-17,2017-05-29
-1vzt,2005-05-26,2004-05-26
-3vzn,2013-05-08,2012-10-15
-2vz0,2009-09-22,2008-07-29
-5vzg,2017-07-05,2017-05-27
-2vz2,2008-12-16,2008-07-29
-6vzu,2020-08-12,2020-02-28
-1vzq,2005-06-20,2004-05-24
-6vzs,2020-08-12,2020-02-28
-3vzo,2013-05-08,2012-10-15
-1vze,1997-03-12,1996-09-18
-3vzx,2012-12-26,2012-10-17
-3vzf,2013-10-16,2012-10-11
-1vzb,1997-03-12,1996-09-18
-6vz2,2020-09-02,2020-02-27
-7vzg,2023-02-22,2021-11-16
-1vzm,2004-09-10,2004-05-21
-3vzw,2012-11-07,2012-10-17
-8vz4,2024-04-17,2024-02-09
-7vzp,2022-11-16,2021-11-16
-2vz9,2008-09-09,2008-07-31
-7vzw,2022-12-14,2021-11-16
-6vzj,2020-09-02,2020-02-28
-7vzq,2022-11-16,2021-11-16
-3vzv,2013-02-06,2012-10-16
-6vzq,2020-08-12,2020-02-28
-1vzh,2004-08-27,2004-05-19
-6vz9,2020-03-18,2020-02-28
-3vzt,2012-11-07,2012-10-15
-8vzm,2024-05-22,2024-02-11
-5vz1,2018-06-27,2017-05-26
-2vz5,2008-08-12,2008-07-30
-2vzw,2009-03-17,2008-08-06
-5vzd,2017-07-05,2017-05-27
-7vzu,2022-11-16,2021-11-16
-8vz9,2024-04-10,2024-02-11
-7vzy,2022-11-16,2021-11-17
-2vze,2008-10-14,2008-07-31
-7vz1,2022-12-28,2021-11-15
-3vzc,2013-05-08,2012-10-11
-6vz3,2020-09-02,2020-02-27
-1vzi,2004-08-27,2004-05-19
-6vzm,2021-03-03,2020-02-28
-5vzb,2017-07-05,2017-05-27
-6vz6,2020-03-11,2020-02-27
-5vzo,2018-06-06,2017-05-29
-6vzt,2020-08-12,2020-02-28
-1vza,1997-03-12,1996-09-18
-5vzq,2018-06-06,2017-05-29
-5vzn,2018-06-06,2017-05-29
-6vzi,2020-04-15,2020-02-28
-2vzm,2008-08-12,2008-08-01
-6vzv,2020-08-12,2020-02-28
-6vzk,2020-04-22,2020-02-28
-5vzv,2017-08-09,2017-05-29
-6vz5,2020-09-02,2020-02-27
-3vzz,2012-12-26,2012-10-17
-3vzg,2013-10-16,2012-10-11
-5vza,2017-07-05,2017-05-27
-7vzs,2022-11-16,2021-11-16
-5vzi,2017-07-05,2017-05-27
-2vz3,2008-09-16,2008-07-29
-2vzl,2009-04-21,2008-07-28
-6vzy,2021-01-13,2020-02-28
-6nxg,2020-01-01,2019-02-08
-2nxa,2007-05-22,2006-11-17
-5nxw,2018-01-17,2017-05-11
-5nx7,2017-09-20,2017-05-09
-6nx1,2020-02-12,2019-02-07
-3nxw,2011-07-20,2010-07-14
-3nxn,2011-11-02,2010-07-14
-3nxx,2010-12-15,2010-07-14
-4nxr,2015-05-13,2013-12-09
-1nxc,2004-05-04,2003-02-10
-7nxl,2021-09-08,2021-03-18
-7nxn,2022-11-02,2021-03-19
-4nxw,2013-12-25,2013-12-09
-1nx8,2003-06-17,2003-02-10
-1nxy,2003-08-26,2003-02-11
-7nxa,2021-04-07,2021-03-17
-2nxt,2007-04-24,2006-11-19
-1nx7,2004-06-15,2003-02-10
-3nxu,2010-10-20,2010-07-14
-1nx9,2004-03-09,2003-02-10
-7nx8,2021-04-07,2021-03-17
-7nxx,2022-09-28,2021-03-19
-1nxg,2003-04-08,2003-02-10
-6nxz,2019-05-29,2019-02-10
-5nxx,2018-03-28,2017-05-11
-5nxc,2017-05-24,2017-05-10
-4nxm,2014-05-21,2013-12-09
-3nxy,2010-12-15,2010-07-14
-4nxc,2014-09-24,2013-12-09
-7nxb,2021-04-07,2021-03-17
-7nxw,2021-06-09,2021-03-19
-3nx9,2010-08-04,2010-07-13
-5nxo,2018-01-17,2017-05-10
-5nxn,2018-02-21,2017-05-10
-2nxx,2007-10-02,2006-11-20
-7nxs,2021-06-09,2021-03-19
-1nxd,2004-03-30,2003-02-10
-6nxd,2019-08-07,2019-02-08
-3nxq,2010-09-08,2010-07-14
-3nxl,2010-07-28,2010-07-14
-2nx1,2007-04-24,2006-11-16
-1nxk,2003-10-14,2003-02-10
-3nxp,2010-11-10,2010-07-14
-2nxs,2007-04-24,2006-11-19
-1nx1,2003-08-19,2003-02-07
-7nxo,2022-11-02,2021-03-19
-2nxz,2007-02-06,2006-11-20
-3nx3,2010-08-25,2010-07-12
-4nx2,2014-09-24,2013-12-08
-5nxp,2018-01-17,2017-05-10
-2nxf,2006-12-12,2006-11-17
-7nx6,2021-04-07,2021-03-17
-7nx3,2021-10-27,2021-03-17
-6nxs,2020-02-12,2019-02-09
-6nxi,2019-03-13,2019-02-08
-3nx7,2010-07-28,2010-07-13
-3nxo,2010-12-01,2010-07-14
-5nxm,2018-05-30,2017-05-10
-7nxf,2021-11-17,2021-03-18
-4nxf,2014-09-24,2013-12-09
-5nx2,2017-06-14,2017-05-09
-2nxb,2006-12-12,2006-11-17
-2nxq,2007-08-21,2006-11-18
-4nxe,2014-09-24,2013-12-09
-5nxf,2017-07-12,2017-05-10
-5nxa,2018-05-30,2017-05-09
-7nxd,2021-08-25,2021-03-18
-6nxj,2019-03-13,2019-02-08
-2nxr,2007-04-24,2006-11-19
-4nxz,2014-04-16,2013-12-09
-7nxu,2022-02-23,2021-03-19
-3nxv,2010-12-01,2010-07-14
-7nxe,2021-06-09,2021-03-18
-2nxe,2006-12-26,2006-11-17
-2nx0,2007-05-08,2006-11-16
-2nxp,2007-01-09,2006-11-17
-2nxm,2007-09-18,2006-11-17
-2nxl,2007-09-18,2006-11-17
-3nxr,2010-12-01,2010-07-14
-5nxu,2018-02-21,2017-05-10
-2nx9,2006-12-26,2006-11-17
-4nxv,2013-12-25,2013-12-09
-4nx1,2014-01-22,2013-12-08
-5nxl,2017-06-07,2017-05-10
-4nxu,2013-12-25,2013-12-09
-7nxv,2021-09-29,2021-03-19
-6nx3,2019-07-17,2019-02-07
-7nx4,2021-10-27,2021-03-17
-3nxt,2010-12-01,2010-07-14
-3nxz,2010-08-25,2010-07-14
-5nxv,2018-01-17,2017-05-11
-2nx8,2007-08-21,2006-11-17
-7nxj,2021-05-12,2021-03-18
-7nx0,2021-10-27,2021-03-17
-6nxx,2020-02-19,2019-02-10
-4nxn,2014-05-21,2013-12-09
-4nx6,2014-01-15,2013-12-08
-4nxa,2014-09-24,2013-12-09
-6nxy,2020-02-19,2019-02-10
-2nxg,2007-04-24,2006-11-17
-7nxy,2021-06-09,2021-03-19
-4nxi,2014-10-22,2013-12-09
-5nxe,2018-03-21,2017-05-10
-7nx7,2021-04-07,2021-03-17
-6nxr,2020-02-19,2019-02-09
-1nx4,2003-06-17,2003-02-08
-3nxs,2010-07-28,2010-07-14
-5nx9,2018-05-30,2017-05-09
-4nx8,2014-07-23,2013-12-08
-1nx3,2003-08-19,2003-02-07
-1nx2,2003-08-19,2003-02-07
-3nxe,2011-11-02,2010-07-13
-2nx3,2007-04-24,2006-11-16
-4nxb,2014-09-24,2013-12-09
-3nx4,2010-08-04,2010-07-12
-4nxq,2015-05-13,2013-12-09
-6nxc,2019-08-07,2019-02-08
-1nxf,2003-08-26,2003-02-10
-3nxd,2010-11-17,2010-07-13
-5nx5,2017-09-20,2017-05-09
-5nxr,2018-02-21,2017-05-10
-4nx7,2014-01-15,2013-12-08
-4nx4,2014-02-26,2013-12-08
-5nx6,2017-09-20,2017-05-09
-4nxx,2013-12-25,2013-12-09
-7nx9,2021-04-07,2021-03-17
-7nx1,2021-10-27,2021-03-17
-2nxd,2007-09-18,2006-11-17
-5nxi,2018-01-17,2017-05-10
-6nx0,2019-03-20,2019-02-07
-5nxd,2017-05-24,2017-05-10
-1nxq,2003-04-15,2003-02-11
-2nxw,2007-05-29,2006-11-20
-4nx5,2013-12-25,2013-12-08
-7nxc,2021-04-07,2021-03-17
-2nxy,2007-02-06,2006-11-20
-5nxy,2018-03-14,2017-05-11
-7nxt,2021-06-09,2021-03-19
-6nxq,2020-02-19,2019-02-09
-4nxs,2014-06-11,2013-12-09
-5nxb,2017-05-24,2017-05-09
-1nx0,2003-08-19,2003-02-07
-7nxm,2021-09-08,2021-03-18
-3nx2,2011-02-16,2010-07-12
-7nxk,2021-05-12,2021-03-18
-1nxt,2004-02-17,2003-02-11
-4nxo,2015-10-07,2013-12-09
-5nxg,2018-01-17,2017-05-10
-4nxg,2014-09-24,2013-12-09
-5qt4,2020-10-07,2019-08-07
-7qto,2022-04-06,2022-01-15
-2qtg,2008-04-01,2007-08-02
-3qtw,2012-10-31,2011-02-23
-7qtk,2022-08-03,2022-01-14
-7qt0,2023-05-24,2022-01-14
-7qt9,2022-05-04,2022-01-14
-1qti,1999-12-29,1999-06-28
-6qtm,2019-09-18,2019-02-25
-5qtd,2020-10-07,2019-08-09
-5qtu,2019-12-25,2019-10-16
-5qtl,2019-12-25,2019-10-31
-4qt1,2015-05-27,2014-07-07
-7qth,2023-01-18,2022-01-14
-5qtq,2019-12-25,2019-08-14
-2qto,2007-09-25,2007-08-02
-2qts,2007-09-25,2007-08-02
-5qth,2020-10-07,2019-08-09
-4qtg,2014-08-20,2014-07-07
-6qtw,2019-07-10,2019-02-25
-6qt0,2019-06-26,2019-02-22
-3qtu,2012-10-31,2011-02-23
-2qta,2007-08-14,2007-08-01
-2qtm,2008-07-15,2007-08-02
-6qta,2019-08-07,2019-02-22
-5qtt,2019-12-25,2019-10-16
-5qt6,2020-10-07,2019-08-07
-3qtt,2011-03-23,2011-02-23
-7qtj,2022-08-03,2022-01-14
-7qtt,2023-05-10,2022-01-15
-1qtq,1998-05-27,1998-01-28
-4qtf,2015-07-29,2014-07-07
-3qt6,2011-05-11,2011-02-22
-2qt6,2007-11-20,2007-08-01
-3qt2,2012-02-01,2011-02-22
-5qt0,2019-08-21,2019-05-26
-1qtx,2003-06-24,1999-06-29
-7qtb,2022-11-09,2022-01-14
-2qtb,2007-11-06,2007-08-01
-5qtz,2020-02-05,2019-11-19
-5qt7,2020-10-07,2019-08-07
-4qtq,2015-06-17,2014-07-08
-7qt2,2023-05-24,2022-01-14
-7qty,2022-02-09,2022-01-17
-5qtr,2019-12-25,2019-10-31
-7qtz,2023-01-25,2022-01-17
-5qt8,2020-10-07,2019-08-07
-4qta,2014-07-23,2014-07-07
-3qtp,2011-07-13,2011-02-23
-7qta,2022-11-09,2022-01-14
-4qte,2014-07-23,2014-07-07
-7qt3,2023-05-24,2022-01-14
-6qtp,2019-03-13,2019-02-25
-4qtu,2014-12-24,2014-07-09
-4qtb,2014-07-23,2014-07-07
-5qte,2020-10-07,2019-08-09
-5qtb,2020-10-07,2019-08-07
-2qt9,2007-11-06,2007-08-01
-3qta,2011-04-06,2011-02-22
-2qt5,2008-06-03,2007-08-01
-8qtf,2023-11-22,2023-10-12
-5qto,2019-12-25,2019-08-14
-7qtq,2022-05-04,2022-01-15
-7qt6,2022-05-04,2022-01-14
-2qty,2008-03-04,2007-08-03
-7qtd,2023-01-18,2022-01-14
-5qtf,2020-10-07,2019-08-09
-4qto,2014-07-16,2014-07-08
-2qtc,2007-08-14,2007-08-01
-5qtn,2019-12-25,2019-08-14
-5qtj,2020-10-07,2019-08-09
-7qte,2023-01-25,2022-01-14
-4qtn,2014-10-08,2014-07-08
-6qtz,2019-06-26,2019-02-26
-5qtk,2020-10-07,2019-08-09
-4qtt,2014-12-24,2014-07-09
-6qts,2019-07-10,2019-02-25
-5qtg,2020-10-07,2019-08-09
-7qtp,2022-04-06,2022-01-15
-8qtk,2024-01-24,2023-10-12
-5qtp,2019-12-25,2019-08-14
-2qt3,2007-09-11,2007-08-01
-7qt8,2022-05-04,2022-01-14
-5qt5,2020-10-07,2019-08-07
-3qti,2011-07-06,2011-02-22
-6qtt,2019-07-10,2019-02-25
-5qty,2020-01-29,2019-11-13
-6qtq,2019-07-10,2019-02-25
-5qtx,2020-01-29,2019-11-13
-6qtv,2019-07-10,2019-02-25
-7qt1,2022-10-12,2022-01-14
-5qt3,2019-08-07,2019-06-28
-2qtt,2008-04-01,2007-08-02
-5qt9,2020-10-07,2019-08-07
-3qto,2012-02-29,2011-02-23
-6qty,2020-03-18,2019-02-26
-6qtu,2019-07-10,2019-02-25
-7qtv,2022-11-23,2022-01-16
-5qta,2020-10-07,2019-08-07
-7qt4,2023-05-24,2022-01-14
-2qtr,2008-07-15,2007-08-02
-4qt3,2015-06-10,2014-07-07
-1qt1,2000-06-29,1999-06-29
-8qtt,2023-11-15,2023-10-13
-4qtd,2014-07-23,2014-07-07
-3qt1,2011-03-23,2011-02-22
-3qt7,2011-05-11,2011-02-22
-8qtc,2023-11-15,2023-10-12
-7qtg,2023-01-18,2022-01-14
-2qt7,2007-12-11,2007-08-01
-7qtc,2022-07-13,2022-01-14
-3qt0,2012-02-29,2011-02-22
-5qtw,2020-01-29,2019-11-13
-8qtj,2024-01-10,2023-10-12
-4qt7,2014-12-24,2014-07-07
-3qtz,2012-10-31,2011-02-23
-2qtl,2007-11-13,2007-08-02
-8qth,2024-01-10,2023-10-12
-5qti,2020-10-07,2019-08-09
-8qtl,2024-04-03,2023-10-12
-3qtq,2012-10-31,2011-02-23
-4qt2,2015-06-10,2014-07-07
-2qt0,2007-08-14,2007-07-31
-4qt8,2014-09-17,2014-07-07
-7qti,2022-08-03,2022-01-14
-4qty,2014-11-05,2014-07-09
-2qtz,2007-11-13,2007-08-02
-2qtw,2007-09-18,2007-08-02
-1qte,1999-08-31,1999-06-27
-4qtx,2014-11-05,2014-07-09
-6qtk,2019-03-13,2019-02-25
-7qt7,2022-05-04,2022-01-14
-2qtv,2008-01-15,2007-08-02
-4qtc,2014-07-23,2014-07-07
-2qtu,2007-10-30,2007-08-02
-6qtl,2019-04-10,2019-02-25
-2qth,2008-08-19,2007-08-02
-2qtf,2008-08-19,2007-08-02
-6qto,2019-07-10,2019-02-25
-3qtv,2012-02-29,2011-02-23
-7qtl,2022-12-28,2022-01-14
-7qtf,2023-01-18,2022-01-14
-1qtm,1999-08-16,1999-06-28
-3qtf,2011-04-06,2011-02-22
-4qt0,2014-12-03,2014-07-06
-6qtj,2020-03-18,2019-02-25
-1qtn,2000-09-20,1999-06-28
-7qtu,2022-04-06,2022-01-16
-7qtm,2023-01-25,2022-01-14
-6qtb,2019-08-07,2019-02-22
-1qtk,1999-07-06,1999-06-28
-3qtb,2011-03-30,2011-02-22
-2qtn,2008-07-15,2007-08-02
-6qti,2019-08-28,2019-02-25
-3qt9,2011-03-09,2011-02-22
-3qtx,2012-10-31,2011-02-23
-6qtc,2020-07-15,2019-02-24
-5qtv,2020-01-29,2019-11-13
-8qtg,2024-01-10,2023-10-12
-6qtx,2019-07-10,2019-02-25
-4qtl,2015-04-15,2014-07-08
-1qtw,1999-08-31,1999-06-29
-6qtn,2019-04-03,2019-02-25
-3qtc,2011-05-25,2011-02-22
-6qtg,2020-03-18,2019-02-25
-7qt5,2022-05-04,2022-01-14
-3qtr,2012-10-31,2011-02-23
-4qts,2014-12-24,2014-07-09
-5qts,2019-12-25,2019-08-14
-3qts,2012-10-31,2011-02-23
-3qt8,2011-05-11,2011-02-22
-5qtm,2019-12-25,2019-08-14
-7t4p,2022-03-30,2021-12-10
-5t40,2017-05-17,2016-08-27
-3t4j,2011-10-05,2011-07-26
-8t4r,2024-02-14,2023-06-09
-1t4g,2004-08-17,2004-04-29
-5t4u,2017-02-08,2016-08-30
-7t4g,2022-10-19,2021-12-09
-7t4b,2021-12-22,2021-12-09
-7t4u,2023-06-14,2021-12-10
-7t4s,2022-03-23,2021-12-10
-7t41,2021-12-22,2021-12-09
-6t4j,2020-11-18,2019-10-14
-5t46,2016-10-26,2016-08-29
-3t4h,2012-03-07,2011-07-26
-7t4t,2023-06-14,2021-12-10
-1t4c,2004-08-03,2004-04-29
-1t4b,2004-07-13,2004-04-29
-1t48,2004-07-20,2004-04-28
-3t4p,2012-08-01,2011-07-26
-8t4b,2024-05-08,2023-06-08
-7t4r,2022-03-23,2021-12-10
-8t47,2024-05-22,2023-06-08
-7t48,2021-12-22,2021-12-09
-3t4k,2011-10-05,2011-07-26
-5t4v,2017-02-08,2016-08-30
-6t4c,2020-01-15,2019-10-13
-1t4s,2004-10-12,2004-04-30
-3t4s,2011-10-05,2011-07-26
-7t44,2021-12-22,2021-12-09
-6t4v,2020-09-30,2019-10-15
-7t4o,2022-03-30,2021-12-10
-3t4q,2011-10-05,2011-07-26
-1t46,2004-06-15,2004-04-28
-1t44,2004-09-07,2004-04-28
-3t4g,2012-10-31,2011-07-26
-5t4o,2016-12-28,2016-08-29
-6t42,2019-10-23,2019-10-11
-1t4r,2005-04-12,2004-04-30
-7t4x,2021-12-22,2021-12-10
-7t4i,2022-12-07,2021-12-10
-1t47,2004-06-15,2004-04-28
-7t45,2021-12-22,2021-12-09
-3t40,2012-08-08,2011-07-25
-6t4g,2020-11-25,2019-10-14
-6t4p,2020-10-14,2019-10-14
-6t4k,2020-11-18,2019-10-14
-8t42,2024-05-08,2023-06-08
-8t41,2024-04-17,2023-06-08
-5t4l,2017-03-29,2016-08-29
-7t4q,2022-03-23,2021-12-10
-5t4k,2017-03-29,2016-08-29
-3t4n,2011-11-09,2011-07-26
-6t4e,2020-08-19,2019-10-13
-1t4t,2005-04-12,2004-04-30
-7t40,2021-12-22,2021-12-09
-6t4d,2020-11-18,2019-10-13
-1t40,2004-08-03,2004-04-28
-5t4i,2017-05-17,2016-08-29
-1t43,2004-06-29,2004-04-28
-3t4r,2013-01-30,2011-07-26
-1t4f,2005-02-08,2004-04-29
-5t4s,2016-10-26,2016-08-30
-1t4u,2005-03-22,2004-04-30
-8t4l,2024-05-08,2023-06-09
-6t4o,2020-10-14,2019-10-14
-7t49,2021-12-22,2021-12-09
-7t4j,2022-12-07,2021-12-10
-8t49,2024-05-08,2023-06-08
-5t4q,2017-01-04,2016-08-29
-1t4e,2005-02-08,2004-04-29
-7t4a,2021-12-22,2021-12-09
-5t4a,2017-06-28,2016-08-29
-6t4t,2020-11-18,2019-10-15
-8t4k,2024-05-08,2023-06-09
-6t4n,2020-10-14,2019-10-14
-6t4i,2020-11-18,2019-10-14
-3t4d,2011-10-05,2011-07-25
-6t49,2020-08-19,2019-10-13
-5t4g,2017-06-28,2016-08-29
-8t4v,2024-03-13,2023-06-10
-3t45,2011-12-21,2011-07-25
-6t4w,2020-11-18,2019-10-15
-7t4h,2022-09-14,2021-12-09
-5t45,2016-11-16,2016-08-29
-7t42,2021-12-22,2021-12-09
-8t4o,2024-02-21,2023-06-09
-7t47,2022-03-16,2021-12-09
-3t4t,2011-10-05,2011-07-26
-5t4n,2017-02-22,2016-08-29
-8t44,2024-05-22,2023-06-08
-1t4j,2004-07-20,2004-04-29
-6t4y,2020-11-18,2019-10-15
-6t4q,2019-12-25,2019-10-14
-5t4c,2017-06-28,2016-08-29
-7t4v,2023-06-14,2021-12-10
-1t4v,2005-03-22,2004-04-30
-3t44,2012-08-08,2011-07-25
-8t48,2024-03-13,2023-06-08
-6t44,2019-10-23,2019-10-12
-6t4h,2020-11-18,2019-10-14
-5t41,2016-11-16,2016-08-28
-3t4v,2012-03-07,2011-07-26
-8t4s,2023-10-04,2023-06-09
-1t49,2004-07-20,2004-04-28
-1t4w,2004-07-20,2004-04-30
-6t4s,2020-08-19,2019-10-14
-5t4y,2016-12-14,2016-08-30
-7t4w,2023-06-14,2021-12-10
-3t41,2011-08-17,2011-07-25
-5t4e,2016-10-05,2016-08-29
-5t4m,2017-02-22,2016-08-29
-3t46,2011-11-23,2011-07-25
-3t4m,2011-10-26,2011-07-26
-6t46,2020-06-24,2019-10-12
-1t41,2004-08-03,2004-04-28
-5t4f,2016-10-05,2016-08-29
-3t4e,2011-08-17,2011-07-25
-7t43,2021-12-22,2021-12-09
-1t4p,2005-04-12,2004-04-30
-5t4p,2016-12-28,2016-08-29
-5t4h,2016-10-05,2016-08-29
-5t4j,2017-03-29,2016-08-29
-8t4p,2024-02-21,2023-06-09
-5t4d,2016-11-02,2016-08-29
-1t4m,2004-11-23,2004-04-30
-3t42,2011-10-05,2011-07-25
-6t4a,2020-05-13,2019-10-13
-7t46,2021-12-22,2021-12-09
-6t48,2020-01-15,2019-10-12
-6t41,2020-01-01,2019-10-11
-5t4b,2016-10-05,2016-08-29
-1t4k,2004-11-02,2004-04-29
-6t4x,2020-11-18,2019-10-15
-3t4u,2012-08-01,2011-07-26
-3t4o,2011-10-05,2011-07-26
-3t4z,2011-10-05,2011-07-26
-5t48,2016-10-26,2016-08-29
-8t4d,2024-05-08,2023-06-09
-6t40,2020-08-19,2019-10-11
-6t4u,2020-11-18,2019-10-15
-8t4a,2024-05-08,2023-06-08
-3t4y,2011-08-03,2011-07-26
-5t4z,2017-03-08,2016-08-30
-8t45,2024-05-22,2023-06-08
-3t4l,2011-10-05,2011-07-26
-2po1,2008-03-18,2007-04-25
-2pod,2007-06-05,2007-04-26
-4po0,2014-06-04,2014-02-23
-4pof,2014-04-09,2014-02-25
-7poq,2022-09-14,2021-09-09
-5pof,2017-03-15,2017-02-07
-1pok,2004-06-22,2003-06-15
-7pov,2022-02-16,2021-09-10
-1po1,1997-12-03,1997-01-08
-7poe,2022-12-21,2021-09-08
-3pos,2011-03-09,2010-11-23
-4poc,2015-01-14,2014-02-25
-2pok,2007-05-08,2007-04-26
-7pot,2021-09-29,2021-09-09
-6poh,2019-11-06,2019-07-03
-2pov,2007-07-24,2007-04-27
-7po9,2021-12-08,2021-09-08
-7poi,2022-05-11,2021-09-09
-2poq,2007-07-31,2007-04-27
-6pog,2020-05-06,2019-07-03
-5poz,2017-03-15,2017-02-07
-7pox,2022-05-04,2021-09-10
-6po8,2020-04-29,2019-07-03
-3po0,2011-03-30,2010-11-21
-2po7,2007-10-02,2007-04-25
-7po5,2022-04-20,2021-09-08
-3poc,2011-01-26,2010-11-22
-8pow,2023-11-15,2023-07-05
-1poj,2004-06-22,2003-06-15
-3poo,2011-11-16,2010-11-23
-7por,2021-09-29,2021-09-09
-4poj,2014-06-18,2014-02-25
-8po3,2024-06-05,2023-07-03
-3po2,2011-03-02,2010-11-21
-5pot,2017-03-15,2017-02-07
-5pok,2017-03-15,2017-02-07
-3pov,2011-09-21,2010-11-23
-4pov,2014-09-17,2014-02-26
-6pow,2020-04-29,2019-07-05
-6poi,2019-11-06,2019-07-04
-2por,1993-07-15,1992-04-24
-3pox,2012-03-07,2010-11-23
-6pox,2020-04-29,2019-07-05
-7pob,2022-09-21,2021-09-08
-4po2,2014-08-20,2014-02-24
-6po9,2020-04-29,2019-07-03
-3po6,2011-04-06,2010-11-22
-6po1,2020-03-11,2019-07-03
-5pow,2017-03-15,2017-02-07
-1po9,2004-06-22,2003-06-15
-5pov,2017-03-15,2017-02-07
-2poi,2007-07-03,2007-04-26
-4poe,2014-12-24,2014-02-25
-6pop,2019-10-02,2019-07-04
-1poo,2000-04-19,1999-04-16
-3poy,2011-06-08,2010-11-23
-4pok,2014-10-29,2014-02-25
-7po4,2022-06-15,2021-09-08
-6po3,2020-03-11,2019-07-03
-4pop,2014-09-17,2014-02-26
-1poc,1993-10-31,1992-09-07
-5poa,2017-03-15,2017-02-07
-4pog,2014-04-09,2014-02-25
-8poj,2023-11-22,2023-07-05
-1pop,1993-10-31,1993-06-24
-4pob,2014-03-05,2014-02-25
-6pov,2020-04-29,2019-07-05
-5po9,2017-03-15,2017-02-07
-2poc,2007-09-11,2007-04-26
-6poz,2020-04-29,2019-07-05
-7pol,2022-09-14,2021-09-09
-4pos,2014-04-09,2014-02-26
-1po2,1997-12-03,1997-01-08
-3poz,2011-03-30,2010-11-23
-2po3,2007-08-14,2007-04-25
-3po7,2011-01-12,2010-11-22
-7pod,2022-09-21,2021-09-08
-6poc,2020-04-29,2019-07-03
-1po8,2004-05-04,2003-06-14
-1poa,1993-10-31,1992-09-07
-5po0,2017-03-15,2017-02-07
-1pob,1993-10-31,1992-09-07
-2poj,2007-12-04,2007-04-26
-3po4,2011-06-15,2010-11-22
-5po5,2017-03-15,2017-02-07
-8poa,2023-08-02,2023-07-04
-8po4,2024-06-05,2023-07-03
-1pox,1994-01-31,1993-11-09
-5pou,2017-03-15,2017-02-07
-5po6,2017-03-15,2017-02-07
-7pou,2022-09-14,2021-09-09
-5po8,2017-03-15,2017-02-07
-5pog,2017-03-15,2017-02-07
-4po5,2014-10-29,2014-02-24
-1poi,1998-03-18,1997-01-24
-8poi,2023-08-23,2023-07-04
-8pof,2023-12-27,2023-07-04
-8pov,2023-11-01,2023-07-05
-5poe,2017-03-15,2017-02-07
-2pop,2007-07-03,2007-04-27
-7poh,2021-12-08,2021-09-09
-3poj,2011-08-24,2010-11-22
-2pom,2007-07-03,2007-04-26
-6poy,2020-04-29,2019-07-05
-2pog,2007-09-11,2007-04-26
-8pou,2023-11-01,2023-07-05
-6pot,2020-04-29,2019-07-05
-2po5,2007-10-02,2007-04-25
-5po3,2017-03-15,2017-02-07
-4por,2014-04-09,2014-02-26
-4poq,2014-04-09,2014-02-26
-8po7,2024-05-08,2023-07-03
-5poq,2017-03-15,2017-02-07
-8po8,2024-05-08,2023-07-03
-5po1,2017-03-15,2017-02-07
-6pos,2020-03-11,2019-07-05
-6po5,2020-04-29,2019-07-03
-2po0,2008-03-18,2007-04-25
-4pot,2014-04-09,2014-02-26
-3pot,2011-04-13,2010-11-23
-5pol,2017-03-15,2017-02-07
-8po0,2024-06-05,2023-07-03
-6poe,2019-12-25,2019-07-03
-7pog,2021-12-08,2021-09-08
-3pow,2011-03-09,2010-11-23
-7pow,2021-12-08,2021-09-10
-4poh,2014-06-18,2014-02-25
-6poa,2020-04-29,2019-07-03
-8po2,2024-06-05,2023-07-03
-4po3,2014-06-11,2014-02-24
-5pom,2017-03-15,2017-02-07
-3pop,2011-05-11,2010-11-23
-5po4,2017-03-15,2017-02-07
-3poa,2011-01-26,2010-11-22
-5pos,2017-03-15,2017-02-07
-4po7,2014-07-23,2014-02-25
-1pow,1994-01-31,1993-11-09
-6po4,2019-07-17,2019-07-03
-2po6,2007-07-03,2007-04-25
-6pob,2020-04-29,2019-07-03
-5poh,2017-03-15,2017-02-07
-8po5,2024-01-17,2023-07-03
-6pod,2020-03-11,2019-07-03
-5poo,2017-03-15,2017-02-07
-2po2,2008-03-18,2007-04-25
-3pog,2011-08-24,2010-11-22
-8po9,2023-10-04,2023-07-03
-7po1,2022-06-15,2021-09-08
-7po3,2022-06-15,2021-09-08
-4pod,2015-01-14,2014-02-25
-5poj,2017-03-15,2017-02-07
-7pop,2021-09-29,2021-09-09
-7poa,2022-09-21,2021-09-08
-5pob,2017-03-15,2017-02-07
-5poi,2017-03-15,2017-02-07
-1poe,1993-10-31,1992-09-07
-7pok,2021-12-08,2021-09-09
-5po2,2017-03-15,2017-02-07
-2pob,2008-03-18,2007-04-26
-5po7,2017-03-15,2017-02-07
-7poy,2022-07-20,2021-09-10
-8pon,2023-11-22,2023-07-05
-3po3,2011-03-02,2010-11-21
-5pop,2017-03-15,2017-02-07
-3po1,2011-11-23,2010-11-21
-4pow,2014-10-22,2014-02-26
-5poc,2017-03-15,2017-02-07
-7po7,2022-12-21,2021-09-08
-2pot,2007-10-30,2007-04-27
-8po1,2024-06-05,2023-07-03
-4po9,2015-03-18,2014-02-25
-8poh,2024-02-21,2023-07-04
-4pom,2014-10-29,2014-02-26
-2poo,2000-04-19,1999-04-16
-5pod,2017-03-15,2017-02-07
-8pol,2024-03-06,2023-07-05
-7po2,2022-06-15,2021-09-08
-1po3,2003-11-18,2003-06-13
-6po7,2020-04-29,2019-07-03
-8pom,2023-11-22,2023-07-05
-3po5,2011-06-15,2010-11-22
-6pol,2020-05-06,2019-07-04
-5pon,2017-03-15,2017-02-07
-3pob,2011-08-24,2010-11-22
-7pom,2022-01-12,2021-09-09
-7poj,2022-05-11,2021-09-09
-7poo,2022-09-14,2021-09-09
-1po7,2004-11-23,2003-06-13
-7poz,2022-08-31,2021-09-10
-3poi,2011-08-24,2010-11-22
-5por,2017-03-15,2017-02-07
-1pod,1993-10-31,1992-09-07
-1po5,2003-10-07,2003-06-13
-2poy,2007-05-08,2007-04-27
-3poe,2011-08-24,2010-11-22
-5poy,2017-03-15,2017-02-07
-2pou,2007-07-24,2007-04-27
-7poc,2022-09-21,2021-09-08
-3po9,2011-11-23,2010-11-22
-7po0,2022-06-15,2021-09-08
-2pow,2007-07-24,2007-04-27
-7pos,2021-09-29,2021-09-09
-4pol,2014-10-29,2014-02-26
-3pof,2011-08-24,2010-11-22
-4poo,2014-04-02,2014-02-26
-6pou,2020-04-29,2019-07-05
-5pox,2017-03-15,2017-02-07
-6po0,2020-05-20,2019-07-03
-6poq,2019-11-06,2019-07-04
-8pok,2024-03-06,2023-07-05
-2pos,2008-03-18,2007-04-27
-5p90,2017-08-30,2016-08-29
-1p9u,2003-05-20,2003-05-12
-5p91,2017-08-30,2016-08-29
-7p9y,2022-08-10,2021-07-28
-2p9p,2007-05-29,2007-03-26
-3p93,2011-10-19,2010-10-15
-7p9l,2022-08-10,2021-07-27
-3p9s,2010-12-22,2010-10-18
-6p9d,2020-06-17,2019-06-10
-7p93,2022-04-06,2021-07-23
-1p9b,2004-02-03,2003-05-10
-5p96,2017-08-30,2016-08-30
-1p9w,2003-10-14,2003-05-12
-4p9g,2014-09-10,2014-04-03
-6p9u,2019-09-04,2019-06-10
-5p9j,2017-05-24,2016-09-20
-7p9q,2022-03-02,2021-07-27
-5p9o,2017-11-22,2016-10-19
-6p9s,2020-03-11,2019-06-10
-6p9n,2019-10-23,2019-06-10
-5p9b,2017-08-30,2016-08-30
-2p97,2007-04-17,2007-03-23
-6p9a,2020-04-15,2019-06-10
-5p9e,2017-08-30,2016-08-30
-5p9r,2017-11-22,2016-10-19
-2p9y,2007-10-02,2007-03-26
-7p97,2022-02-02,2021-07-26
-5p9v,2017-11-22,2016-10-19
-7p9x,2022-07-13,2021-07-28
-5p9z,2017-11-22,2016-10-19
-4p9z,2014-06-18,2014-04-06
-7p99,2022-03-02,2021-07-26
-2p9d,2007-09-25,2007-03-25
-2p94,2007-07-24,2007-03-23
-8p9h,2023-07-05,2023-06-06
-7p9r,2021-10-13,2021-07-27
-8p9k,2023-07-05,2023-06-06
-7p9p,2022-08-10,2021-07-27
-6p9t,2020-03-11,2019-06-10
-6p9v,2020-04-22,2019-06-10
-5p93,2017-08-30,2016-08-29
-4p94,2015-04-22,2014-04-02
-2p9s,2007-05-29,2007-03-26
-3p9k,2011-01-12,2010-10-17
-6p99,2019-08-07,2019-06-10
-8p98,2023-08-16,2023-06-05
-2p9a,2007-11-20,2007-03-24
-5p94,2017-08-30,2016-08-29
-6p97,2019-08-07,2019-06-10
-6p94,2020-01-01,2019-06-09
-4p9k,2014-05-07,2014-04-04
-3p96,2010-11-10,2010-10-15
-1p9a,2003-07-22,2003-05-09
-6p96,2019-08-07,2019-06-10
-2p99,2007-11-20,2007-03-24
-3p9c,2011-01-12,2010-10-17
-2p9g,2007-04-24,2007-03-25
-8p9f,2023-07-05,2023-06-06
-2p9u,2007-05-29,2007-03-26
-2p98,2007-11-20,2007-03-24
-4p9h,2014-05-21,2014-04-04
-5p9l,2017-05-24,2016-09-20
-3p95,2011-08-31,2010-10-15
-1p91,2004-03-30,2003-05-08
-5p9g,2017-05-24,2016-09-20
-7p98,2022-07-13,2021-07-26
-7p9u,2021-11-17,2021-07-28
-3p9t,2011-08-10,2010-10-18
-5p9t,2017-11-22,2016-10-19
-7p9n,2021-10-13,2021-07-27
-3p9f,2011-09-28,2010-10-17
-5p99,2017-08-30,2016-08-30
-8p9v,2024-04-10,2023-06-06
-5p9d,2017-08-30,2016-08-30
-8p9l,2023-07-05,2023-06-06
-7p9a,2022-07-13,2021-07-26
-2p9e,2007-04-24,2007-03-25
-2p9h,2007-06-19,2007-03-26
-7p9o,2022-05-25,2021-07-27
-7p9e,2022-01-19,2021-07-27
-4p90,2014-09-10,2014-04-01
-6p9m,2020-04-01,2019-06-10
-2p9c,2007-04-24,2007-03-24
-6p9c,2019-08-07,2019-06-10
-7p9d,2022-01-12,2021-07-27
-7p9z,2022-08-10,2021-07-28
-5p9w,2017-11-22,2016-10-19
-3p92,2011-08-31,2010-10-15
-6p9f,2019-07-17,2019-06-10
-3p9q,2010-12-22,2010-10-18
-6p9z,2019-10-23,2019-06-10
-6p91,2019-08-21,2019-06-09
-4p9m,2014-05-21,2014-04-04
-5p95,2017-08-30,2016-08-30
-5p9k,2017-05-24,2016-09-20
-4p9v,2014-06-18,2014-04-06
-6p9b,2020-04-15,2019-06-10
-5p9h,2017-05-24,2016-09-20
-4p91,2014-04-30,2014-04-01
-5p9a,2017-08-30,2016-08-30
-4p9c,2014-11-26,2014-04-03
-2p9i,2007-05-29,2007-03-26
-4p9e,2014-11-26,2014-04-03
-3p9r,2010-12-22,2010-10-18
-4p9d,2014-11-26,2014-04-03
-3p9y,2010-12-15,2010-10-18
-6p93,2020-01-01,2019-06-09
-3p9l,2011-10-19,2010-10-18
-5p9y,2017-11-22,2016-10-19
-8p9j,2023-07-05,2023-06-06
-8p9g,2023-07-05,2023-06-06
-5p9q,2017-11-22,2016-10-19
-1p9l,2003-08-26,2003-05-12
-7p92,2022-09-14,2021-07-23
-4p9x,2014-08-27,2014-04-06
-8p9u,2024-04-10,2023-06-06
-1p9e,2004-05-25,2003-05-11
-5p9x,2017-11-22,2016-10-19
-4p9o,2014-06-04,2014-04-04
-5p9u,2017-11-22,2016-10-19
-4p9y,2014-08-27,2014-04-06
-3p9u,2011-04-27,2010-10-18
-6p9r,2020-03-11,2019-06-10
-5p9s,2017-11-22,2016-10-19
-7p91,2022-09-14,2021-07-23
-2p9k,2007-05-29,2007-03-26
-3p9o,2011-08-31,2010-10-18
-7p9w,2022-08-10,2021-07-28
-5p9n,2017-11-22,2016-10-19
-6p9e,2019-06-26,2019-06-10
-1p9r,2003-10-14,2003-05-12
-5p9p,2017-11-22,2016-10-19
-6p9p,2020-03-11,2019-06-10
-7p9v,2021-11-17,2021-07-28
-6p95,2019-09-11,2019-06-09
-5p9f,2017-05-24,2016-09-20
-5p92,2017-08-30,2016-08-29
-8p9y,2023-09-27,2023-06-06
-6p9l,2020-04-01,2019-06-10
-4p9p,2014-06-04,2014-04-04
-4p9s,2014-06-18,2014-04-04
-2p93,2007-07-24,2007-03-23
-1p99,2004-01-20,2003-05-09
-3p9i,2011-01-12,2010-10-17
-7p9t,2021-10-13,2021-07-27
-1p9p,2004-05-18,2003-05-12
-8p94,2024-01-03,2023-06-05
-3p9m,2011-10-19,2010-10-18
-6p9q,2020-03-11,2019-06-10
-3p9p,2010-12-22,2010-10-18
-5p9i,2017-05-24,2016-09-20
-2p9n,2007-05-29,2007-03-26
-7p9j,2022-05-04,2021-07-27
-8p9i,2023-07-05,2023-06-06
-6p98,2019-08-07,2019-06-10
-8p9r,2023-09-06,2023-06-06
-5p98,2017-08-30,2016-08-30
-4p9w,2014-08-27,2014-04-06
-5p97,2017-08-30,2016-08-30
-2p9z,2007-10-02,2007-03-26
-2p9x,2007-10-02,2007-03-26
-8p99,2023-09-27,2023-06-05
-7p90,2022-08-03,2021-07-23
-3p9j,2011-03-23,2010-10-17
-5p9c,2017-08-30,2016-08-30
-3p97,2010-12-08,2010-10-16
-6p9k,2020-04-01,2019-06-10
-4p99,2014-06-18,2014-04-02
-8p97,2023-08-16,2023-06-05
-5p9m,2017-05-24,2016-09-20
-3p99,2011-11-30,2010-10-16
-1p93,2003-07-08,2003-05-09
-2p95,2007-07-24,2007-03-23
-7p9i,2022-06-01,2021-07-27
-6lbc,2020-11-25,2019-11-14
-1lbs,1995-10-15,1995-07-11
-1lb5,2002-07-31,2002-04-02
-6lbb,2020-09-30,2019-11-14
-3lb4,2010-11-24,2010-01-07
-7lbr,2021-02-24,2021-01-08
-7lb2,2021-07-14,2021-01-07
-3lba,2011-01-12,2010-01-08
-4lbr,2014-04-30,2013-06-21
-3lbl,2010-03-16,2010-01-08
-6lb5,2020-11-18,2019-11-13
-3lb2,2010-11-24,2010-01-07
-4lbd,1999-03-02,1998-02-04
-3lbd,1999-03-02,1998-02-04
-7lbn,2021-02-24,2021-01-08
-4lb4,2014-04-30,2013-06-20
-6lb4,2020-11-18,2019-11-13
-3lbs,2011-02-16,2010-01-08
-3lbc,2011-01-19,2010-01-08
-5lbq,2016-09-21,2016-06-16
-2lb9,2011-06-29,2011-03-23
-6lbl,2020-02-19,2019-11-14
-1lbx,2002-05-22,2002-04-04
-4lb2,2013-07-24,2013-06-20
-3lb3,2010-11-24,2010-01-07
-1lby,2002-05-22,2002-04-04
-5lbt,2016-07-27,2016-06-17
-1lbz,2002-05-22,2002-04-04
-7lbp,2022-01-12,2021-01-08
-2lbm,2011-06-29,2011-04-08
-6lbe,2020-11-04,2019-11-14
-3lb8,2010-02-23,2010-01-07
-6lbm,2021-02-10,2019-11-14
-6lb6,2020-11-18,2019-11-13
-5lb7,2017-04-26,2016-06-15
-5lba,2016-07-06,2016-06-15
-5lbe,2016-08-31,2016-06-15
-4lbo,2014-01-22,2013-06-20
-5lbg,2017-01-18,2016-06-16
-6lb2,2020-04-22,2019-11-13
-6lb7,2020-07-15,2019-11-13
-7lba,2021-03-31,2021-01-07
-7lb7,2021-01-20,2021-01-07
-1lbk,2002-04-17,2002-04-04
-2lb5,2011-06-29,2011-03-23
-5lbx,2017-05-10,2016-06-17
-4lbe,2013-10-30,2013-06-20
-1lbb,2002-06-05,2002-04-02
-7lbk,2022-01-12,2021-01-08
-1lb6,2002-07-31,2002-04-02
-2lb3,2011-07-06,2011-03-22
-7lbl,2021-01-20,2021-01-08
-2lbd,1997-11-12,1997-08-19
-3lbh,2010-03-02,2010-01-08
-3lb1,2010-11-24,2010-01-07
-7lbd,2022-01-12,2021-01-07
-2lbu,2011-06-01,2011-04-07
-7lbf,2021-03-10,2021-01-07
-5lbf,2016-08-31,2016-06-16
-5lbr,2016-10-26,2016-06-17
-3lbf,2010-09-08,2010-01-08
-7lbv,2021-12-08,2021-01-09
-5lb1,2017-01-18,2016-06-15
-5lbz,2017-11-29,2016-06-17
-4lb9,2013-07-24,2013-06-20
-5lb9,2017-05-10,2016-06-15
-4lbj,2014-01-22,2013-06-20
-7lbz,2021-09-01,2021-01-09
-4lbm,2014-01-22,2013-06-20
-1lbc,2002-05-29,2002-04-02
-5lb8,2016-07-06,2016-06-15
-4lbk,2014-01-22,2013-06-20
-7lbq,2022-01-12,2021-01-08
-1lb3,2003-01-28,2002-04-02
-6lbx,2020-11-18,2019-11-15
-4lb0,2013-07-17,2013-06-20
-4lb6,2013-09-18,2013-06-20
-4lbv,2013-09-11,2013-06-21
-7lb3,2022-01-12,2021-01-07
-1lba,1994-04-30,1993-12-22
-1lbu,1996-11-08,1996-03-16
-6lbv,2020-09-30,2019-11-15
-5lbv,2016-07-06,2016-06-17
-4lbw,2013-09-11,2013-06-21
-7lbc,2022-02-09,2021-01-07
-3lby,2011-01-12,2010-01-08
-4lbx,2013-07-03,2013-06-21
-7lb0,2021-07-14,2021-01-07
-3lbn,2010-03-02,2010-01-08
-7lb1,2021-07-14,2021-01-07
-4lbz,2013-09-11,2013-06-21
-1lbf,2002-06-12,2002-04-03
-7lbg,2021-03-10,2021-01-07
-3lbg,2010-06-02,2010-01-08
-3lbk,2010-03-16,2010-01-08
-3lbj,2010-03-16,2010-01-08
-7lbt,2021-07-14,2021-01-08
-2lba,2011-09-14,2011-03-28
-5lbh,2017-04-26,2016-06-16
-4lbt,2014-04-02,2013-06-21
-5lby,2017-11-29,2016-06-17
-7lbo,2022-01-12,2021-01-08
-4lbu,2014-12-24,2013-06-21
-5lb6,2016-08-31,2016-06-15
-1lbt,1995-10-15,1995-07-11
-7lbs,2021-02-24,2021-01-08
-5lb3,2016-07-06,2016-06-15
-3lbw,2010-07-28,2010-01-08
-1lb2,2002-09-06,2002-04-01
-2lbv,2012-02-22,2011-04-07
-6lbd,2020-11-25,2019-11-14
-5lbb,2016-08-31,2016-06-15
-5lb5,2016-07-06,2016-06-15
-3lbo,2010-12-15,2010-01-08
-7lbx,2022-01-19,2021-01-09
-4lbn,2014-01-22,2013-06-20
-3lb6,2010-03-16,2010-01-07
-5lbu,2016-07-27,2016-06-17
-7lbe,2021-03-10,2021-01-07
-7lbm,2021-03-24,2021-01-08
-4lbg,2013-07-03,2013-06-20
-3lbe,2011-01-12,2010-01-08
-5lbo,2018-03-14,2016-06-16
-1lbl,2002-09-18,2002-04-04
-7lb4,2021-07-14,2021-01-07
-1lb9,2002-06-05,2002-04-02
-4lbs,2014-04-30,2013-06-21
-6lb9,2020-03-25,2019-11-13
-4lby,2013-09-11,2013-06-21
-4lbp,2013-08-28,2013-06-20
-1lbh,1996-07-11,1996-02-17
-5lbw,2017-11-29,2016-06-17
-3lbz,2010-04-28,2010-01-08
-3lbi,2010-03-02,2010-01-08
-1lb8,2002-06-05,2002-04-02
-1lbm,2002-12-18,2002-04-04
-4lbl,2014-01-22,2013-06-20
-5lbi,2016-10-26,2016-06-16
-4lb3,2014-04-30,2013-06-20
-5lbc,2016-08-31,2016-06-15
-6t5d,2020-08-19,2019-10-16
-3t5g,2011-10-26,2011-07-27
-6t5i,2021-10-27,2019-10-16
-3t5o,2012-02-01,2011-07-27
-5t5h,2016-10-12,2016-08-31
-3t5z,2012-06-20,2011-07-28
-3t53,2012-06-20,2011-07-26
-3t5d,2011-08-24,2011-07-27
-6t5b,2020-02-26,2019-10-15
-6t55,2020-11-18,2019-10-15
-1t5l,2004-06-22,2004-05-04
-6t5c,2020-10-14,2019-10-15
-7t54,2022-02-02,2021-12-11
-6t59,2019-11-27,2019-10-15
-3t58,2012-05-30,2011-07-27
-7t5r,2022-07-06,2021-12-13
-3t5q,2012-01-11,2011-07-27
-6t52,2020-11-18,2019-10-15
-6t54,2020-11-18,2019-10-15
-1t5a,2005-07-12,2004-05-03
-7t5i,2022-12-14,2021-12-12
-8t5m,2024-01-10,2023-06-14
-8t56,2023-12-27,2023-06-12
-6t5x,2020-11-18,2019-10-17
-7t5z,2022-07-06,2021-12-13
-6t50,2020-11-18,2019-10-15
-5t57,2016-09-14,2016-08-30
-5t5n,2016-11-30,2016-08-31
-7t55,2022-02-02,2021-12-11
-3t59,2012-05-30,2011-07-27
-7t5t,2022-09-14,2021-12-13
-5t5t,2017-03-29,2016-08-31
-3t5l,2012-02-15,2011-07-27
-6t5m,2020-09-30,2019-10-16
-1t5b,2004-08-03,2004-05-03
-6t5g,2020-11-18,2019-10-16
-6t56,2020-11-18,2019-10-15
-5t5c,2017-05-17,2016-08-30
-7t5y,2022-03-02,2021-12-13
-8t5r,2024-01-10,2023-06-14
-3t5f,2012-08-01,2011-07-27
-8t5u,2024-06-05,2023-06-14
-1t5c,2005-05-10,2004-05-04
-5t5p,2016-12-28,2016-08-31
-7t5x,2022-07-06,2021-12-13
-3t5n,2012-01-11,2011-07-27
-8t5g,2024-01-10,2023-06-13
-3t5t,2012-08-01,2011-07-28
-6t5u,2020-02-19,2019-10-17
-8t5l,2023-07-12,2023-06-13
-8t5y,2023-11-01,2023-06-14
-7t5m,2022-12-14,2021-12-12
-1t5p,2004-08-24,2004-05-05
-7t5k,2022-03-02,2021-12-12
-7t5d,2022-12-28,2021-12-11
-1t5g,2004-10-12,2004-05-04
-5t55,2016-12-28,2016-08-30
-3t5i,2011-11-02,2011-07-27
-7t56,2022-02-09,2021-12-11
-1t5z,2005-01-25,2004-05-05
-3t55,2012-08-08,2011-07-26
-7t5f,2021-12-29,2021-12-12
-7t5e,2022-12-28,2021-12-11
-6t5r,2020-08-19,2019-10-16
-6t5z,2020-01-15,2019-10-17
-3t50,2012-06-13,2011-07-26
-5t54,2016-12-28,2016-08-30
-6t5y,2020-11-18,2019-10-17
-3t5p,2011-09-07,2011-07-27
-6t5q,2020-10-14,2019-10-16
-8t5p,2023-11-29,2023-06-14
-5t5m,2016-10-19,2016-08-31
-7t5c,2022-12-28,2021-12-11
-1t5f,2005-05-17,2004-05-04
-3t51,2012-06-20,2011-07-26
-1t5h,2004-08-03,2004-05-04
-7t5q,2023-06-14,2021-12-13
-6t5v,2020-02-19,2019-10-17
-1t5e,2004-05-18,2004-05-04
-7t57,2022-02-02,2021-12-11
-3t5u,2012-06-20,2011-07-28
-5t5q,2016-11-09,2016-08-31
-5t5o,2016-12-28,2016-08-31
-1t57,2004-08-03,2004-05-03
-6t57,2020-11-18,2019-10-15
-1t5d,2004-08-03,2004-05-04
-1t5s,2004-06-15,2004-05-05
-6t5e,2020-11-18,2019-10-16
-1t5j,2004-05-11,2004-05-04
-8t5q,2023-11-29,2023-06-14
-5t5v,2017-09-06,2016-08-31
-5t5u,2017-09-13,2016-08-31
-5t53,2016-11-09,2016-08-30
-6t5j,2020-07-29,2019-10-16
-5t52,2016-12-28,2016-08-30
-5t56,2017-07-12,2016-08-30
-8t5c,2024-01-03,2023-06-13
-3t5w,2012-08-01,2011-07-28
-6t5l,2020-05-27,2019-10-16
-1t5k,2004-07-27,2004-05-04
-5t50,2016-12-28,2016-08-30
-6t5f,2020-11-18,2019-10-16
-8t5s,2024-05-15,2023-06-14
-6t58,2020-05-27,2019-10-15
-8t5i,2023-08-09,2023-06-13
-8t57,2023-12-27,2023-06-12
-3t56,2012-06-20,2011-07-26
-3t5h,2012-02-15,2011-07-27
-8t5n,2023-06-28,2023-06-14
-7t5s,2022-07-06,2021-12-13
-6t5p,2020-10-14,2019-10-16
-7t5j,2022-12-14,2021-12-12
-3t5j,2012-02-15,2011-07-27
-3t54,2011-12-07,2011-07-26
-8t5z,2024-05-08,2023-06-14
-5t5w,2017-03-29,2016-08-31
-6t53,2020-11-18,2019-10-15
-8t5k,2023-07-12,2023-06-13
-3t5k,2012-02-15,2011-07-27
-6t5w,2020-05-13,2019-10-17
-6t5t,2020-11-18,2019-10-17
-5t5j,2016-12-28,2016-08-31
-1t5t,2004-06-15,2004-05-05
-8t5j,2023-06-28,2023-06-13
-3t5m,2011-09-07,2011-07-27
-8t55,2023-07-05,2023-06-12
-5t5l,2016-12-28,2016-08-31
-5t5i,2016-10-19,2016-08-31
-6t5k,2020-05-27,2019-10-16
-4b56,2012-09-19,2012-08-02
-7b5f,2022-01-12,2020-12-03
-6b5d,2018-05-23,2017-09-29
-7b5c,2021-02-10,2020-12-03
-3b55,2007-11-06,2007-10-25
-6b5a,2018-09-05,2017-09-28
-6b53,2018-10-10,2017-09-27
-2b56,2005-11-22,2005-09-27
-3b57,2007-11-06,2007-10-25
-8b5i,2022-11-30,2022-09-22
-1b55,1999-06-15,1999-01-12
-1b5t,1999-01-20,1999-01-07
-7b51,2021-03-10,2020-12-03
-5b5v,2016-07-06,2016-05-24
-1b5q,2000-01-07,1999-01-07
-4b5h,2012-10-17,2012-08-03
-1b5h,1998-11-18,1998-11-13
-8b5p,2023-03-29,2022-09-23
-7b57,2022-06-22,2020-12-03
-4b52,2013-01-09,2012-08-02
-4b5q,2013-04-03,2012-08-07
-5b5p,2017-01-18,2016-05-13
-2b53,2005-10-11,2005-09-27
-6b5g,2018-01-10,2017-09-29
-6b5i,2018-01-10,2017-09-29
-1b5p,2003-09-02,1999-01-07
-8b54,2023-03-29,2022-09-21
-8b5a,2023-01-11,2022-09-22
-5b5h,2016-09-28,2016-05-06
-3b56,2008-01-15,2007-10-25
-6b52,2018-10-10,2017-09-27
-1b5e,1999-01-13,1999-01-06
-6b59,2018-09-05,2017-09-28
-8b5y,2023-01-18,2022-09-25
-5b5u,2017-05-31,2016-05-23
-1b5a,1998-06-17,1998-04-06
-7b5k,2021-05-26,2020-12-03
-1b5g,1998-05-27,1998-03-05
-7b5o,2021-02-10,2020-12-05
-4b55,2013-01-16,2012-08-02
-5b57,2016-11-16,2016-04-25
-5b5k,2016-07-06,2016-05-11
-2b5v,2006-04-04,2005-09-29
-2b59,2005-10-11,2005-09-27
-4b5t,2012-08-29,2012-08-07
-8b5s,2023-10-04,2022-09-24
-4b5u,2012-08-29,2012-08-07
-7b5a,2021-10-13,2020-12-03
-3b5i,2008-01-15,2007-10-26
-5b5t,2016-09-28,2016-05-18
-8b5q,2023-10-04,2022-09-24
-5b5l,2017-05-31,2016-05-12
-8b5m,2023-10-04,2022-09-23
-4b5o,2012-10-24,2012-08-07
-7b5z,2022-02-23,2020-12-07
-3b5q,2007-11-13,2007-10-26
-2b5t,2006-09-19,2005-09-29
-2b5w,2006-04-04,2005-09-29
-8b5b,2023-01-11,2022-09-22
-7b5n,2021-02-10,2020-12-05
-5b53,2017-04-26,2016-04-22
-8b5f,2023-10-04,2022-09-22
-1b51,1999-01-20,1999-01-11
-5b5o,2017-01-18,2016-05-13
-7b56,2022-06-22,2020-12-03
-8b55,2022-10-19,2022-09-21
-7b5y,2021-08-11,2020-12-07
-5b5w,2016-07-06,2016-05-24
-5b5e,2017-02-01,2016-05-02
-7b5q,2021-02-10,2020-12-05
-8b53,2023-09-20,2022-09-21
-3b52,2007-12-11,2007-10-25
-8b5l,2023-03-01,2022-09-23
-1b59,2000-01-14,1999-01-13
-4b5v,2012-08-29,2012-08-07
-4b5k,2013-04-10,2012-08-03
-4b5l,2012-08-15,2012-08-05
-5b5x,2016-12-07,2016-05-24
-1b57,2000-01-07,1999-01-12
-6b5s,2018-03-21,2017-09-29
-5b50,2017-03-01,2016-04-20
-8b5v,2022-10-05,2022-09-24
-4b5n,2013-08-21,2012-08-07
-4b5s,2012-08-29,2012-08-07
-2b52,2005-10-11,2005-09-27
-6b54,2018-10-10,2017-09-27
-2b50,2006-02-14,2005-09-27
-8b5g,2022-11-30,2022-09-22
-6b5o,2018-03-21,2017-09-29
-3b50,2007-11-13,2007-10-25
-6b50,2018-10-10,2017-09-27
-2b51,2005-11-22,2005-09-27
-6b5h,2018-01-10,2017-09-29
-4b5i,2012-10-17,2012-08-03
-7b5e,2021-02-10,2020-12-03
-5b5b,2016-06-29,2016-05-02
-1b5d,1999-01-13,1999-01-06
-2b54,2005-10-11,2005-09-27
-7b58,2021-10-13,2020-12-03
-7b50,2022-01-12,2020-12-03
-5b5y,2016-12-07,2016-05-24
-5b5z,2016-12-07,2016-05-24
-8b56,2023-08-09,2022-09-21
-8b51,2023-10-04,2022-09-21
-3b5g,2008-11-04,2007-10-25
-6b5q,2018-02-28,2017-09-29
-8b5h,2022-11-30,2022-09-22
-5b55,2017-04-26,2016-04-22
-8b5w,2023-10-04,2022-09-24
-5b5g,2017-03-01,2016-05-04
-1b58,1999-01-20,1999-01-12
-8b57,2023-12-20,2022-09-22
-4b5m,2012-10-17,2012-08-06
-2b5o,2005-10-11,2005-09-29
-1b52,1999-01-20,1999-01-11
-7b59,2021-10-13,2020-12-03
-2b5i,2005-11-29,2005-09-28
-3b5r,2008-09-09,2007-10-26
-6b58,2018-01-24,2017-09-28
-6b5e,2018-02-21,2017-09-29
-8b52,2023-10-04,2022-09-21
-4b5b,2012-10-31,2012-08-03
-3b53,2007-12-11,2007-10-25
-5b5f,2017-03-01,2016-05-04
-5b5s,2016-11-16,2016-05-16
-8b5d,2023-10-04,2022-09-22
-6b5y,2018-06-27,2017-09-29
-3b51,2007-12-11,2007-10-25
-5b59,2016-09-14,2016-04-28
-2b5j,2005-12-06,2005-09-28
-8b5x,2023-10-04,2022-09-25
-2b5e,2006-01-24,2005-09-28
-2b55,2005-10-11,2005-09-27
-6b5z,2018-10-03,2017-10-01
-1b54,1999-01-27,1999-01-12
-5b5m,2017-03-22,2016-05-12
-8b50,2023-10-04,2022-09-21
-1b5j,1999-01-13,1999-01-06
-8b5j,2022-11-30,2022-09-22
-8b58,2023-02-01,2022-09-22
-3b5j,2008-01-15,2007-10-26
-7b5u,2021-08-11,2020-12-07
-1b5m,1997-03-12,1996-11-07
-7b5s,2021-02-10,2020-12-07
-2b58,2006-01-24,2005-09-27
-1b5b,1998-06-17,1998-04-06
-1b5i,1999-01-13,1999-01-06
-7b5m,2021-02-17,2020-12-05
-1b5f,1999-01-13,1999-01-06
-7b5l,2021-02-10,2020-12-04
-8b5e,2023-10-04,2022-09-22
-3b5b,2007-12-25,2007-10-25
-4b5w,2012-08-29,2012-08-07
-2b5h,2006-04-11,2005-09-28
-3b59,2007-11-06,2007-10-25
-6b5k,2018-02-21,2017-09-29
-1b5o,2003-09-02,1999-01-07
-6b5v,2017-12-27,2017-09-29
-2b5l,2006-02-28,2005-09-28
-5b51,2017-03-01,2016-04-20
-4b5d,2012-09-26,2012-08-03
-2b5z,2006-10-03,2005-09-29
-6b51,2018-10-10,2017-09-27
-6b5j,2018-04-04,2017-09-29
-5b5n,2017-03-22,2016-05-12
-6b56,2018-10-03,2017-09-28
-4b5p,2012-10-24,2012-08-07
-5vxx,2017-07-12,2017-05-24
-1vxb,1996-08-01,1996-01-09
-5vxc,2017-11-01,2017-05-23
-2vx5,2008-09-16,2008-07-01
-6vxr,2020-07-29,2020-02-24
-1vxd,1996-08-01,1996-01-09
-6vxj,2020-05-13,2020-02-22
-2vx0,2008-10-28,2008-06-30
-7vxu,2022-11-23,2021-11-13
-7vx8,2022-05-18,2021-11-12
-2vxh,2009-03-03,2008-07-04
-6vxu,2021-03-03,2020-02-24
-7vxy,2022-09-14,2021-11-13
-2vx1,2008-10-28,2008-06-30
-7vx5,2021-12-01,2021-11-12
-6vxh,2020-05-13,2020-02-21
-6vxx,2020-03-11,2020-02-25
-2vxy,2008-09-30,2008-07-15
-5vx0,2017-11-15,2017-05-23
-6vxi,2020-05-13,2020-02-21
-1vxe,1996-08-01,1996-01-09
-3vxj,2012-11-07,2012-09-14
-5vxz,2017-06-21,2017-05-24
-3vxw,2012-10-03,2012-09-21
-2vxl,2008-09-23,2008-07-07
-7vx6,2022-11-23,2021-11-12
-3vxm,2013-10-23,2012-09-20
-5vx6,2017-11-22,2017-05-23
-8vxy,2024-03-13,2024-02-06
-3vx0,2013-09-11,2012-09-06
-2vxx,2009-11-17,2008-07-14
-6vxe,2020-04-08,2020-02-21
-5vx9,2018-07-18,2017-05-23
-1vxh,1996-08-01,1996-01-09
-1vxg,1996-08-01,1996-01-09
-2vxb,2008-08-12,2008-07-03
-6vxy,2020-07-01,2020-02-25
-5vxi,2017-10-25,2017-05-23
-7vx0,2022-11-16,2021-11-12
-7vxx,2022-09-14,2021-11-13
-3vxe,2013-09-04,2012-09-12
-2vxj,2008-09-16,2008-07-04
-1vxa,1996-08-01,1996-01-09
-2vxn,2009-07-14,2008-07-08
-1vxc,1996-08-01,1996-01-09
-6vxg,2021-02-24,2020-02-21
-2vxi,2008-11-04,2008-07-04
-2vxk,2008-07-15,2008-07-05
-7vxg,2022-03-23,2021-11-12
-5vxg,2017-10-25,2017-05-23
-2vxa,2009-02-17,2008-07-01
-1vxo,1999-11-15,1999-04-21
-8vxc,2024-03-13,2024-02-04
-1vxf,1996-08-01,1996-01-09
-3vx3,2013-02-27,2012-09-09
-3vx4,2013-04-17,2012-09-11
-6vx6,2020-04-08,2020-02-21
-5vxo,2017-11-01,2017-05-23
-5vx5,2018-07-18,2017-05-23
-7vxt,2023-08-16,2021-11-13
-6vxk,2020-04-29,2020-02-22
-5vxe,2017-10-25,2017-05-23
-7vxs,2022-11-23,2021-11-13
-6vx2,2021-02-24,2020-02-21
-2vx3,2008-09-16,2008-06-30
-6vx7,2020-04-08,2020-02-21
-7vx3,2022-11-23,2021-11-12
-7vxp,2022-11-23,2021-11-13
-3vxc,2013-09-18,2012-09-11
-5vxt,2017-06-14,2017-05-24
-2vx6,2008-09-16,2008-07-01
-7vxq,2022-02-09,2021-11-13
-3vx1,2013-09-11,2012-09-06
-2vxo,2008-08-12,2008-07-08
-2vx4,2008-09-16,2008-07-01
-3vxi,2012-11-07,2012-09-14
-7vxr,2023-08-16,2021-11-13
-2vx7,2008-09-16,2008-07-01
-6vxv,2020-11-11,2020-02-24
-5vxa,2018-05-23,2017-05-23
-1vxr,1999-11-15,1999-04-21
-6vxz,2020-11-11,2020-02-25
-7vx4,2021-12-01,2021-11-12
-6vxq,2020-12-16,2020-02-23
-2vx9,2009-02-17,2008-07-01
-2vxt,2009-06-23,2008-07-10
-2vxc,2008-08-12,2008-07-03
-183l,1995-07-10,1995-04-19
-7fz9,2023-06-14,2023-04-27
-6fzf,2019-02-13,2018-03-14
-8fzv,2023-07-19,2023-01-30
-1fzo,2001-03-28,2000-10-03
-3fzh,2009-03-17,2009-01-26
-2fze,2006-06-13,2006-02-09
-3fza,2009-02-24,2009-01-24
-7fzj,2023-06-14,2023-04-27
-6fzm,2019-02-20,2018-03-15
-4fzy,2013-07-03,2012-07-08
-1fz3,2001-02-21,2000-10-03
-7fzq,2023-06-14,2023-04-27
-2fz9,2006-10-03,2006-02-09
-5fz8,2017-03-22,2016-03-11
-5fzb,2016-03-30,2016-03-12
-7fzv,2023-06-14,2023-04-27
-1fzj,2001-03-28,2000-10-03
-4fzi,2012-07-18,2012-07-06
-2fzi,2006-12-26,2006-02-09
-6fze,2019-03-27,2018-03-14
-2fzs,2006-05-23,2006-02-10
-4fzb,2013-05-22,2012-07-06
-3fzt,2009-03-31,2009-01-26
-2fz8,2006-10-03,2006-02-09
-2fzz,2006-06-27,2006-02-10
-1fz1,2001-02-21,2000-10-03
-5fz3,2016-03-23,2016-03-10
-4fzj,2013-06-26,2012-07-06
-3fzi,2010-03-09,2009-01-26
-7fz4,2023-06-14,2023-04-27
-2fz6,2006-08-15,2006-02-09
-3fz5,2009-02-03,2009-01-23
-6fza,2018-10-17,2018-03-14
-2fzc,2006-08-29,2006-02-09
-6fzb,2018-06-13,2018-03-14
-2fzw,2006-06-13,2006-02-10
-1fzd,1998-08-19,1998-06-22
-7fz1,2023-06-14,2023-04-27
-7fz0,2023-06-14,2023-04-27
-3fz8,2009-02-03,2009-01-23
-1fzc,1998-10-14,1998-05-19
-4fzc,2012-10-24,2012-07-06
-1fz7,2001-02-28,2000-10-03
-7fzd,2023-06-14,2023-04-27
-6fzv,2018-07-04,2018-03-15
-4fzl,2012-10-03,2012-07-06
-1fz6,2001-04-27,2000-10-03
-6fzw,2018-07-11,2018-03-15
-6fzi,2019-03-27,2018-03-14
-6fzx,2018-09-05,2018-03-15
-8fzr,2023-04-26,2023-01-29
-3fzq,2009-02-10,2009-01-26
-3fzx,2009-02-03,2009-01-26
-6fz5,2019-03-27,2018-03-14
-5fz4,2016-03-23,2016-03-10
-1fz2,2001-02-21,2000-10-03
-6fzd,2018-10-17,2018-03-14
-5fzp,2016-08-10,2016-03-15
-6fz1,2018-10-17,2018-03-13
-7fzy,2023-06-14,2023-04-27
-1fzh,2001-04-27,2000-10-03
-4fzx,2013-07-03,2012-07-08
-3fzp,2009-03-31,2009-01-26
-3fzm,2009-03-17,2009-01-26
-5fz1,2016-05-04,2016-03-10
-7fzo,2023-06-14,2023-04-27
-5fzc,2016-03-30,2016-03-14
-3fzn,2009-05-05,2009-01-26
-4fz8,2013-07-10,2012-07-06
-5fz9,2016-03-30,2016-03-12
-5fz6,2016-03-23,2016-03-11
-7fz3,2023-06-14,2023-04-27
-4fz3,2013-03-20,2012-07-06
-6fzg,2019-02-13,2018-03-14
-4fz7,2013-07-10,2012-07-06
-6fz6,2019-04-10,2018-03-14
-7fz2,2023-06-14,2023-04-27
-1fzz,2001-10-04,2000-10-04
-5fz5,2016-05-18,2016-03-10
-7fz8,2023-06-14,2023-04-27
-5fzi,2017-03-29,2016-03-14
-8fzq,2023-03-29,2023-01-29
-4fzz,2013-07-03,2012-07-08
-2fzb,2006-10-03,2006-02-09
-6fzs,2019-10-02,2018-03-15
-7fz5,2023-06-14,2023-04-27
-7fzc,2023-06-14,2023-04-27
-1fzf,1999-06-08,1998-12-28
-1fzb,1997-12-03,1997-08-05
-8fzk,2023-02-08,2023-01-29
-3fz4,2009-02-10,2009-01-23
-1fz4,2001-02-28,2000-10-03
-3fzf,2009-03-17,2009-01-26
-2fzj,2006-12-26,2006-02-09
-8fzu,2023-07-19,2023-01-30
-7fzw,2023-06-14,2023-04-27
-6fzt,2019-10-02,2018-03-15
-2fzn,2006-12-26,2006-02-09
-7fzu,2023-06-14,2023-04-27
-7fzr,2023-06-14,2023-04-27
-2fzd,2006-10-03,2006-02-09
-1fz0,2001-02-21,2000-10-03
-5fze,2017-03-29,2016-03-14
-8fz4,2023-03-01,2023-01-27
-3fzk,2009-03-17,2009-01-26
-2fzm,2007-04-03,2006-02-09
-7fzp,2023-06-14,2023-04-27
-1fzq,2000-12-06,2000-10-04
-8fz8,2024-02-07,2023-01-27
-5fzj,2016-04-13,2016-03-14
-2fzv,2006-02-21,2006-02-10
-6fzn,2018-10-17,2018-03-15
-5fzn,2016-04-13,2016-03-15
-3fzw,2009-06-02,2009-01-26
-7fzh,2023-06-14,2023-04-27
-4fz0,2012-08-01,2012-07-05
-5fz0,2016-04-06,2016-03-10
-5fz7,2016-03-23,2016-03-11
-6fz3,2019-03-27,2018-03-13
-6fz2,2019-03-27,2018-03-13
-3fzc,2010-02-09,2009-01-24
-7fzi,2023-06-14,2023-04-27
-3fzs,2009-03-31,2009-01-26
-6fz8,2018-10-17,2018-03-14
-1fz9,2001-04-27,2000-10-03
-2fz5,2006-03-14,2006-02-09
-7fzz,2023-06-14,2023-04-27
-7fzm,2023-06-14,2023-04-27
-3fz3,2009-11-10,2009-01-23
-1fzk,2001-03-28,2000-10-03
-1fzi,2001-04-27,2000-10-03
-6fz9,2018-10-17,2018-03-14
-2fzu,2006-03-14,2006-02-10
-7fza,2023-06-14,2023-04-27
-7fz7,2023-06-14,2023-04-27
-3fzl,2009-03-17,2009-01-26
-1fzu,2000-10-25,2000-10-04
-6fzq,2019-02-20,2018-03-15
-5fzf,2017-03-29,2016-03-14
-7fzb,2023-06-14,2023-04-27
-3fzg,2009-08-11,2009-01-26
-7fzl,2023-06-14,2023-04-27
-1fz5,2001-02-28,2000-10-03
-6fzu,2018-07-18,2018-03-15
-6fzp,2019-02-13,2018-03-15
-3fz6,2009-02-03,2009-01-23
-8fz1,2024-02-07,2023-01-27
-5fzk,2016-04-06,2016-03-14
-3fz0,2010-01-26,2009-01-23
-5fzo,2016-03-30,2016-03-15
-4fzh,2012-09-05,2012-07-06
-3fz9,2009-02-24,2009-01-24
-4fz6,2013-01-30,2012-07-06
-4fzm,2012-10-03,2012-07-06
-1fza,1997-12-03,1997-08-05
-4fzg,2012-10-24,2012-07-06
-5fza,2016-03-30,2016-03-12
-5fzg,2017-03-29,2016-03-14
-6fzr,2019-02-20,2018-03-15
-2fzh,2006-12-26,2006-02-09
-4fzd,2013-03-06,2012-07-06
-6fz7,2018-10-17,2018-03-14
-1fze,1999-06-08,1998-12-23
-7fzx,2023-06-14,2023-04-27
-3fz1,2009-04-07,2009-01-23
-3fzr,2009-03-31,2009-01-26
-5fzm,2017-03-29,2016-03-14
-4fzf,2013-03-06,2012-07-06
-1fzg,1999-06-08,1999-01-01
-5fzd,2017-03-22,2016-03-14
-7fzt,2023-06-14,2023-04-27
-2fzg,2006-08-29,2006-02-09
-6fzc,2018-10-17,2018-03-14
-5fzh,2016-05-25,2016-03-14
-8fzb,2023-06-21,2023-01-28
-4fz9,2012-08-15,2012-07-06
-4fzv,2012-10-03,2012-07-08
-7fzs,2023-06-14,2023-04-27
-6fzh,2019-03-27,2018-03-14
-1fz8,2001-04-27,2000-10-03
-6fz4,2019-01-23,2018-03-14
-2fzk,2006-08-29,2006-02-09
-7fzf,2023-06-14,2023-04-27
-8fz7,2023-10-11,2023-01-27
-6fzj,2019-02-13,2018-03-14
-7fz6,2023-06-14,2023-04-27
-1fzm,2001-03-28,2000-10-03
-2fz2,2006-02-21,2006-02-08
-4fz1,2012-08-01,2012-07-05
-7fzn,2023-06-14,2023-04-27
-5fzl,2016-04-06,2016-03-14
-4j54,2013-05-15,2013-02-07
-4j5e,2014-02-19,2013-02-08
-5j53,2016-11-30,2016-04-01
-2j51,2006-10-03,2006-09-08
-6j5j,2019-06-26,2019-01-11
-4j51,2013-07-24,2013-02-07
-1j58,2002-07-03,2002-02-25
-2j59,2007-02-20,2006-09-13
-8j5p,2023-09-20,2023-04-24
-1j5u,2002-07-31,2002-07-03
-4j5t,2013-04-03,2013-02-09
-1j54,2002-10-16,2002-01-22
-5j5x,2016-07-20,2016-04-04
-2j5a,2006-10-25,2006-09-13
-4j5r,2013-03-27,2013-02-09
-2j5w,2007-02-06,2006-09-19
-4j5y,2013-07-31,2013-02-11
-1j5y,2002-07-31,2002-07-05
-6j5l,2019-07-17,2019-01-11
-2j56,2007-01-23,2006-09-12
-2j5m,2006-12-06,2006-09-18
-8j5u,2024-04-03,2023-04-24
-2j5x,2006-09-21,2006-09-20
-1j5c,2002-04-10,2002-04-02
-6j5t,2019-03-20,2019-01-12
-8j5f,2024-04-24,2023-04-22
-6j5w,2019-04-03,2019-01-12
-1j5i,2002-09-11,2002-05-02
-5j58,2017-01-25,2016-04-01
-2j5s,2007-01-08,2006-09-19
-4j5f,2013-06-26,2013-02-08
-4j5s,2013-03-27,2013-02-09
-2j5f,2007-02-27,2006-09-14
-1j5m,2002-05-22,2002-05-16
-2j5z,2007-01-23,2006-09-21
-5j54,2016-11-30,2016-04-01
-5j5d,2016-08-17,2016-04-02
-6j5z,2019-09-25,2019-01-12
-5j5q,2017-07-26,2016-04-03
-4j56,2013-07-10,2013-02-08
-1j51,2002-01-23,2002-01-05
-1j59,2002-03-01,2002-03-01
-6j5s,2019-09-25,2019-01-11
-4j5c,2014-02-19,2013-02-08
-5j5n,2017-04-12,2016-04-03
-8j5g,2024-04-24,2023-04-22
-3j5v,2014-03-26,2013-11-20
-8j56,2024-02-28,2023-04-21
-4j5b,2014-02-19,2013-02-08
-5j5r,2016-10-19,2016-04-03
-5j5o,2017-05-10,2016-04-03
-8j59,2024-04-24,2023-04-21
-6j5v,2019-04-03,2019-01-12
-8j5w,2023-09-20,2023-04-24
-2j5b,2007-09-25,2006-09-13
-4j5n,2013-07-24,2013-02-08
-5j5y,2017-05-10,2016-04-04
-4j5j,2013-05-15,2013-02-08
-1j53,2002-10-16,2002-01-22
-5j5z,2017-11-15,2016-04-04
-8j5k,2023-12-20,2023-04-23
-4j57,2013-07-10,2013-02-08
-4j58,2014-02-19,2013-02-08
-6j53,2019-09-25,2019-01-10
-4j5h,2013-06-26,2013-02-08
-6j5x,2019-12-18,2019-01-12
-1j5k,2002-07-10,2002-05-13
-5j51,2016-12-14,2016-04-01
-1j5l,2002-05-22,2002-05-16
-5j5s,2016-06-01,2016-04-03
-5j5p,2017-07-26,2016-04-03
-8j51,2023-07-26,2023-04-21
-8j5e,2024-04-24,2023-04-22
-5j5g,2017-03-08,2016-04-02
-5j5j,2016-06-22,2016-04-02
-8j57,2024-05-01,2023-04-21
-5j50,2017-02-08,2016-04-01
-2j5v,2007-03-06,2006-09-19
-1j52,2003-11-11,2002-01-08
-2j57,2007-01-23,2006-09-12
-6j5k,2019-06-26,2019-01-11
-1j5d,2002-04-10,2002-04-02
-8j52,2023-07-26,2023-04-21
-6j5i,2019-06-26,2019-01-11
-1j55,2003-01-07,2002-01-25
-4j52,2013-05-29,2013-02-07
-4j5d,2014-02-19,2013-02-08
-8j5o,2023-09-20,2023-04-24
-4j59,2014-02-19,2013-02-08
-6j55,2019-07-17,2019-01-10
-2j5t,2007-03-06,2006-09-19
-8j5a,2023-07-12,2023-04-21
-8j5h,2024-04-24,2023-04-22
-2j55,2007-01-23,2006-09-12
-8j5x,2023-09-20,2023-04-24
-5j5k,2017-04-05,2016-04-03
-5j5a,2017-01-25,2016-04-01
-1j5p,2002-07-10,2002-06-27
-5j59,2017-01-25,2016-04-01
-6j5y,2019-12-18,2019-01-12
-4j55,2013-05-15,2013-02-07
-5j5f,2017-03-08,2016-04-02
-6j58,2019-09-25,2019-01-10
-4j5x,2013-08-21,2013-02-10
-5j5t,2016-10-26,2016-04-03
-8j54,2024-01-17,2023-04-21
-5j5i,2017-03-08,2016-04-02
-6j50,2019-02-20,2019-01-10
-2j50,2006-11-06,2006-09-08
-5j5c,2016-09-28,2016-04-02
-2j5n,2007-10-16,2006-09-19
-4j5p,2013-05-01,2013-02-08
-8j5s,2024-04-03,2023-04-24
-5j5h,2017-03-08,2016-04-02
-3j5l,2014-03-26,2013-10-23
-5j5b,2016-07-27,2016-04-01
-5j55,2016-11-30,2016-04-01
-4j5w,2013-08-21,2013-02-10
-6j5u,2019-04-03,2019-01-12
-8j5j,2023-11-22,2023-04-23
-4j5i,2013-02-20,2013-02-08
-1j5e,2002-04-12,2002-04-08
-4j53,2013-05-29,2013-02-07
-4j5a,2014-02-19,2013-02-08
-6j51,2019-02-20,2019-01-10
-8j5t,2024-04-03,2023-04-24
-7tw7,2022-09-07,2022-02-06
-6twi,2020-10-21,2020-01-13
-6twa,2020-02-19,2020-01-12
-6twu,2020-04-01,2020-01-13
-4twb,2014-07-30,2014-06-30
-7tww,2022-02-23,2022-02-07
-4twj,2014-12-03,2014-06-30
-1tw5,2004-12-14,2004-06-30
-4twn,2015-05-13,2014-07-01
-1twx,2005-04-19,2004-07-01
-5twk,2017-05-03,2016-11-14
-8tw3,2024-01-24,2023-08-19
-3twx,2011-12-07,2011-09-22
-7tw0,2022-06-08,2022-02-06
-4twe,2015-03-18,2014-06-30
-7twa,2022-04-13,2022-02-07
-3twp,2012-09-26,2011-09-22
-3twt,2011-12-07,2011-09-22
-5tw4,2018-05-16,2016-11-11
-6twt,2020-05-13,2020-01-13
-4twv,2016-05-04,2014-07-02
-6tw1,2020-04-15,2020-01-11
-7tw8,2022-09-07,2022-02-06
-6tw7,2021-07-21,2020-01-12
-7tw2,2022-06-08,2022-02-06
-1tw3,2004-09-14,2004-06-30
-5twz,2017-11-22,2016-11-15
-8twu,2023-09-20,2023-08-21
-4twc,2014-10-08,2014-06-30
-7twk,2022-11-02,2022-02-07
-7twz,2022-02-23,2022-02-07
-4tws,2014-08-20,2014-07-01
-3tws,2011-12-07,2011-09-22
-7twm,2022-11-02,2022-02-07
-1twh,2004-11-16,2004-06-30
-6tw6,2021-07-21,2020-01-12
-8tw1,2024-03-27,2023-08-18
-1twz,2004-09-14,2004-07-01
-4tw6,2014-11-26,2014-06-30
-1twf,2004-11-16,2004-06-30
-3tw7,2011-10-12,2011-09-21
-5tw7,2016-11-23,2016-11-11
-8two,2024-02-28,2023-08-21
-3twc,2011-10-19,2011-09-21
-5twg,2017-04-12,2016-11-13
-4tw9,2014-07-30,2014-06-30
-7twu,2023-02-15,2022-02-07
-5twx,2017-09-27,2016-11-15
-8twj,2024-02-28,2023-08-21
-4twf,2014-09-24,2014-06-30
-6tw3,2021-01-27,2020-01-12
-3twv,2011-12-07,2011-09-22
-3twd,2011-10-19,2011-09-21
-4tw3,2014-10-15,2014-06-29
-3tw3,2011-12-28,2011-09-21
-1twb,2004-11-16,2004-06-30
-5twj,2017-05-03,2016-11-14
-6twf,2020-02-19,2020-01-13
-4tww,2015-02-18,2014-07-02
-5twb,2017-10-04,2016-11-12
-4tw0,2015-07-08,2014-06-29
-1tw4,2004-11-23,2004-06-30
-5tw1,2017-01-18,2016-11-10
-3two,2011-10-12,2011-09-22
-6tws,2020-10-21,2020-01-13
-3tw2,2011-11-02,2011-09-21
-5tws,2017-07-05,2016-11-14
-3tww,2011-12-07,2011-09-22
-1twi,2004-07-27,2004-07-01
-1tw6,2004-11-02,2004-06-30
-6twq,2020-04-01,2020-01-13
-6twe,2020-07-29,2020-01-13
-6twb,2020-05-13,2020-01-13
-6tw0,2020-02-19,2020-01-10
-6twz,2020-05-06,2020-01-13
-1twy,2004-12-21,2004-07-01
-8twi,2023-11-01,2023-08-21
-5twt,2017-01-25,2016-11-14
-3twy,2011-11-02,2011-09-22
-7twt,2022-02-23,2022-02-07
-5twn,2017-03-15,2016-11-14
-8tws,2024-02-28,2023-08-21
-6twh,2020-10-21,2020-01-13
-3twj,2012-08-22,2011-09-21
-5twv,2017-01-25,2016-11-14
-4twi,2014-12-03,2014-06-30
-5twp,2017-07-05,2016-11-14
-4twl,2015-04-01,2014-07-01
-5twh,2017-04-12,2016-11-13
-5tw6,2017-06-28,2016-11-11
-3twz,2012-02-29,2011-09-22
-5twl,2017-11-22,2016-11-14
-5tw5,2017-09-20,2016-11-11
-4twp,2015-02-11,2014-07-01
-7twy,2022-02-23,2022-02-07
-5tw2,2017-09-20,2016-11-11
-6tw9,2021-01-27,2020-01-12
-6tw2,2020-02-05,2020-01-12
-1twa,2004-11-16,2004-06-30
-1tw8,2004-08-10,2004-06-30
-3twh,2012-10-03,2011-09-21
-4twk,2014-08-06,2014-06-30
-6tw8,2021-07-21,2020-01-12
-5twm,2017-03-15,2016-11-14
-6tw4,2021-01-27,2020-01-12
-5twc,2017-10-04,2016-11-12
-5two,2017-02-08,2016-11-14
-1twq,2004-12-14,2004-07-01
-3twf,2012-03-14,2011-09-21
-6twx,2020-04-01,2020-01-13
-7twx,2022-02-23,2022-02-07
-4twr,2014-10-08,2014-07-01
-7twl,2022-11-02,2022-02-07
-6twk,2020-05-20,2020-01-13
-3twa,2011-10-26,2011-09-21
-7tw9,2022-09-07,2022-02-06
-1twg,2004-11-16,2004-06-30
-6tww,2020-06-03,2020-01-13
-3tw6,2011-10-19,2011-09-21
-5twr,2017-07-05,2016-11-14
-4tw7,2014-11-26,2014-06-30
-4two,2015-05-13,2014-07-01
-3tw4,2011-11-23,2011-09-21
-5twe,2017-06-28,2016-11-12
-3tw0,2013-03-27,2011-09-21
-1twc,2004-11-16,2004-06-30
-5tw8,2018-05-16,2016-11-11
-6twy,2020-04-01,2020-01-13
-5twy,2017-11-22,2016-11-15
-4twd,2014-09-24,2014-06-30
-4tw2,2015-07-08,2014-06-29
-4tw8,2014-11-26,2014-06-30
-1tww,2004-09-14,2004-07-01
-5tw3,2017-03-15,2016-11-11
-1tw1,2004-12-14,2004-06-30
-7twe,2022-02-16,2022-02-07
-4twu,2016-05-04,2014-07-02
-4twt,2015-02-04,2014-07-01
-8twq,2024-04-17,2023-08-21
-6twm,2020-05-20,2020-01-13
-6twv,2020-10-21,2020-01-13
-3twb,2011-10-26,2011-09-21
-5twf,2017-04-12,2016-11-13
-3tw1,2012-02-01,2011-09-21
-5twq,2017-07-05,2016-11-14
-1tw2,2004-09-14,2004-06-30
-1twn,2005-07-05,2004-07-01
-7twc,2022-02-16,2022-02-07
-6twc,2020-05-20,2020-01-13
-4twy,2015-02-18,2014-07-02
-7twv,2022-02-23,2022-02-07
-4twz,2015-07-08,2014-07-02
-6tw5,2021-07-21,2020-01-12
-1twr,2005-07-05,2004-07-01
-1tw7,2005-07-19,2004-06-30
-3myr,2010-08-04,2010-05-11
-1my3,2003-06-10,2002-10-03
-3myg,2010-07-21,2010-05-10
-1my4,2003-06-10,2002-10-03
-5myy,2017-07-12,2017-01-30
-3my1,2010-09-29,2010-05-09
-6myx,2019-06-19,2018-11-02
-4my2,2013-11-13,2013-09-27
-4my4,2013-10-16,2013-09-27
-4myp,2014-10-22,2013-09-27
-5myr,2017-10-25,2017-01-27
-4my8,2013-11-13,2013-09-27
-6myy,2018-11-14,2018-11-02
-6myz,2019-11-06,2018-11-02
-3myv,2010-06-02,2010-05-11
-4myw,2014-10-01,2013-09-28
-7myc,2021-09-29,2021-05-20
-5my7,2017-06-21,2017-01-25
-2mye,1994-01-31,1993-08-04
-7mya,2021-09-29,2021-05-20
-4myu,2014-08-06,2013-09-28
-1myj,1994-01-31,1992-02-27
-7myz,2021-09-08,2021-05-22
-6myq,2019-11-06,2018-11-02
-3myh,2010-05-26,2010-05-10
-7my1,2022-06-01,2021-05-19
-1myp,1994-01-31,1992-04-15
-7my2,2021-06-16,2021-05-20
-3myj,2010-08-18,2010-05-10
-5my4,2017-06-28,2017-01-25
-3myw,2010-12-29,2010-05-11
-4my6,2014-10-15,2013-09-27
-5mys,2017-10-25,2017-01-27
-5mya,2017-04-26,2017-01-26
-2myd,1994-01-31,1993-08-04
-3my6,2010-08-04,2010-05-10
-5mye,2017-03-22,2017-01-26
-5myd,2017-09-06,2017-01-26
-4myt,2014-08-06,2013-09-28
-6mya,2018-11-14,2018-11-01
-1myi,1994-01-31,1992-02-27
-7mym,2022-06-01,2021-05-21
-3myk,2010-05-26,2010-05-10
-5my6,2017-08-09,2017-01-25
-7myp,2021-07-28,2021-05-21
-4myd,2014-04-23,2013-09-27
-1myf,1995-02-27,1994-12-02
-1my1,2003-06-10,2002-10-03
-6myd,2019-05-01,2018-11-01
-5my5,2017-08-02,2017-01-25
-4myq,2014-01-01,2013-09-27
-7my3,2021-06-16,2021-05-20
-6myw,2019-06-26,2018-11-02
-5my2,2018-02-21,2017-01-25
-1my6,2003-07-29,2002-10-03
-4my7,2014-09-17,2013-09-27
-6myp,2019-11-06,2018-11-02
-4mya,2014-01-01,2013-09-27
-5myk,2017-06-28,2017-01-26
-7mys,2021-06-09,2021-05-21
-4myx,2014-07-23,2013-09-28
-7my6,2022-08-24,2021-05-20
-1myz,2003-08-19,2002-10-04
-5myi,2017-09-06,2017-01-26
-5myc,2017-03-01,2017-01-26
-5myl,2017-10-25,2017-01-27
-3my9,2010-07-07,2010-05-10
-7myb,2021-09-29,2021-05-20
-2my1,2015-03-11,2015-01-19
-1myt,1993-10-31,1991-05-06
-5myq,2018-02-14,2017-01-27
-1myh,1994-01-31,1992-02-27
-6myl,2019-11-06,2018-11-01
-7myi,2021-07-21,2021-05-21
-3myn,2011-04-20,2010-05-10
-5myv,2017-05-10,2017-01-29
-5myg,2017-08-09,2017-01-26
-6myo,2019-11-06,2018-11-02
-6myu,2019-11-06,2018-11-02
-6myr,2019-10-16,2018-11-02
-1myg,1994-01-31,1992-02-27
-5my9,2017-03-01,2017-01-26
-4my1,2014-01-01,2013-09-26
-4mye,2014-10-01,2013-09-27
-3myt,2011-11-23,2010-05-11
-4my9,2014-06-11,2013-09-27
-7myl,2022-06-01,2021-05-21
-6myk,2019-02-13,2018-11-01
-7myd,2022-05-25,2021-05-20
-6mys,2019-11-06,2018-11-02
-7my0,2022-06-01,2021-05-19
-4mys,2014-04-23,2013-09-28
-4my0,2013-11-06,2013-09-26
-3myu,2010-10-20,2010-05-11
-7my5,2022-05-25,2021-05-20
-3myy,2011-05-11,2010-05-11
-5myt,2017-10-25,2017-01-27
-6myt,2019-11-06,2018-11-02
-3myl,2010-05-26,2010-05-10
-6myn,2019-08-07,2018-11-01
-7myo,2021-11-10,2021-05-21
-3my5,2010-09-29,2010-05-09
-5myw,2017-10-25,2017-01-30
-7my9,2021-09-29,2021-05-20
-4myf,2013-11-27,2013-09-27
-4myv,2014-10-01,2013-09-28
-7myr,2021-07-14,2021-05-21
-2myb,1994-01-31,1993-08-04
-1mym,1994-01-31,1993-10-14
-5myn,2017-10-25,2017-01-27
-4myo,2013-10-16,2013-09-27
-5my0,2018-01-24,2017-01-25
-3my0,2010-07-21,2010-05-08
-6myj,2019-02-13,2018-11-01
-4myn,2013-11-27,2013-09-27
-1myr,1997-06-16,1997-03-23
-5my1,2017-04-26,2017-01-25
-3mym,2011-04-20,2010-05-10
-1my0,2003-06-10,2002-10-03
-5myb,2017-04-26,2017-01-26
-2myc,1994-01-31,1993-08-04
-5my8,2017-05-10,2017-01-25
-2mya,1994-01-31,1993-08-04
-3myz,2010-09-08,2010-05-11
-6myv,2019-10-02,2018-11-02
-1my8,2003-03-04,2002-10-03
-2my5,2016-01-20,2015-01-20
-7myy,2021-07-28,2021-05-22
-7myj,2022-06-29,2021-05-21
-7myv,2022-03-30,2021-05-21
-4myk,2013-11-27,2013-09-27
-3myq,2011-02-02,2010-05-11
-7myu,2021-07-21,2021-05-21
-5mym,2017-10-25,2017-01-27
-6myi,2019-02-13,2018-11-01
-4myh,2014-03-26,2013-09-27
-1my2,2003-06-10,2002-10-03
-6mym,2019-05-15,2018-11-01
-7o30,2021-07-07,2021-04-01
-6o3f,2019-03-27,2019-02-26
-1o31,2003-09-02,2003-03-06
-3o37,2010-12-15,2010-07-23
-3o35,2010-12-15,2010-07-23
-6o3i,2019-07-17,2019-02-26
-5o31,2018-01-17,2017-05-23
-3o3c,2010-10-06,2010-07-23
-3o3r,2011-01-19,2010-07-26
-1o38,2003-09-02,2003-03-06
-7o3q,2021-06-09,2021-04-02
-6o3r,2019-09-25,2019-02-27
-4o3m,2014-03-12,2013-12-18
-6o3m,2020-10-14,2019-02-26
-1o3o,2003-09-02,2003-03-06
-3o3g,2010-12-08,2010-07-24
-6o39,2019-04-03,2019-02-26
-1o3f,2003-09-02,2003-03-06
-3o3o,2011-03-16,2010-07-25
-5o3h,2018-02-14,2017-05-23
-3o34,2010-12-15,2010-07-23
-1o3l,2003-09-02,2003-03-06
-5o3w,2018-02-07,2017-05-25
-2o3p,2007-02-13,2006-12-01
-1o3r,2003-04-08,2003-03-18
-6o3z,2020-03-04,2019-02-27
-4o3c,2014-04-16,2013-12-18
-1o3p,2003-09-02,2003-03-06
-5o3j,2017-07-05,2017-05-24
-6o33,2020-02-26,2019-02-25
-4o3o,2014-04-30,2013-12-18
-2o3q,2006-12-12,2006-12-01
-2o3r,2006-12-12,2006-12-01
-5o3q,2018-05-16,2017-05-24
-7o3y,2021-06-30,2021-04-03
-1o3b,2003-09-02,2003-03-06
-5o3c,2018-02-14,2017-05-23
-7o36,2022-04-13,2021-04-01
-5o3n,2017-09-13,2017-05-24
-6o3a,2019-04-03,2019-02-26
-5o3i,2018-02-14,2017-05-23
-1o3c,2003-09-02,2003-03-06
-6o3o,2019-07-10,2019-02-27
-2o3z,2007-02-27,2006-12-02
-1o35,2003-09-02,2003-03-06
-1o3h,2003-09-02,2003-03-06
-1o36,2003-09-02,2003-03-06
-7o3f,2021-06-09,2021-04-01
-7o33,2021-07-07,2021-04-01
-2o3c,2007-12-11,2006-12-01
-2o36,2007-01-23,2006-11-30
-2o35,2007-01-02,2006-11-30
-5o38,2018-02-14,2017-05-23
-1o3t,2003-04-08,2003-03-18
-7o37,2021-10-13,2021-04-01
-1o3i,2003-09-02,2003-03-06
-3o32,2011-08-10,2010-07-23
-5o3r,2018-05-16,2017-05-24
-3o3l,2011-12-07,2010-07-25
-7o3x,2021-06-30,2021-04-03
-1o30,2003-09-02,2003-03-06
-1o3n,2003-09-02,2003-03-06
-3o3e,2010-12-08,2010-07-23
-5o35,2017-06-28,2017-05-23
-2o3s,2006-12-12,2006-12-01
-7o34,2021-06-09,2021-04-01
-1o3s,2003-04-08,2003-03-18
-6o3v,2020-03-04,2019-02-27
-1o3j,2003-09-02,2003-03-06
-6o3y,2019-06-05,2019-02-27
-3o3f,2010-12-08,2010-07-24
-5o3e,2018-02-14,2017-05-23
-4o3s,2014-04-30,2013-12-18
-2o34,2006-12-12,2006-11-30
-5o3f,2018-02-14,2017-05-23
-6o38,2019-07-24,2019-02-26
-4o3r,2014-04-30,2013-12-18
-4o33,2014-10-29,2013-12-18
-6o3u,2019-12-04,2019-02-27
-2o3h,2007-12-11,2006-12-01
-6o3b,2019-04-03,2019-02-26
-6o3x,2019-06-05,2019-02-27
-7o3h,2021-10-13,2021-04-01
-2o39,2007-01-09,2006-12-01
-4o3u,2014-06-04,2013-12-18
-3o3a,2010-12-08,2010-07-23
-2o3b,2006-12-19,2006-12-01
-1o3d,2003-09-02,2003-03-06
-3o31,2011-06-08,2010-07-23
-1o3y,2003-05-20,2003-05-08
-4o3q,2014-04-30,2013-12-18
-3o3u,2010-10-13,2010-07-26
-4o34,2014-06-11,2013-12-18
-4o3b,2014-04-16,2013-12-18
-7o35,2022-04-13,2021-04-01
-2o3t,2006-12-19,2006-12-01
-5o3a,2018-02-14,2017-05-23
-6o3p,2019-05-29,2019-02-27
-7o31,2021-07-07,2021-04-01
-3o3h,2010-12-08,2010-07-24
-5o39,2018-02-14,2017-05-23
-5o3g,2018-02-14,2017-05-23
-7o3c,2021-10-13,2021-04-01
-1o3q,2003-04-08,2003-03-18
-1o3w,2003-07-15,2003-04-14
-1o37,2003-09-02,2003-03-06
-5o3b,2018-02-14,2017-05-23
-3o3n,2011-03-16,2010-07-25
-4o3f,2014-10-29,2013-12-18
-3o3p,2010-11-03,2010-07-25
-2o3e,2007-01-23,2006-12-01
-3o38,2010-08-11,2010-07-23
-7o3z,2021-06-30,2021-04-03
-1o33,2003-09-02,2003-03-06
-3o3b,2010-12-08,2010-07-23
-5o3v,2018-02-07,2017-05-25
-3o39,2011-02-16,2010-07-23
-1o3g,2003-09-02,2003-03-06
-1o3k,2003-09-02,2003-03-06
-3o3j,2011-06-08,2010-07-24
-4o3n,2014-04-30,2013-12-18
-1o39,2003-09-02,2003-03-06
-1o32,2003-09-02,2003-03-06
-7o3u,2022-02-09,2021-04-03
-6o36,2020-02-26,2019-02-26
-5o3y,2018-06-13,2017-05-25
-4o3t,2014-06-04,2013-12-18
-7o3e,2021-10-13,2021-04-01
-7o3s,2021-06-09,2021-04-02
-7o3p,2021-06-09,2021-04-02
-2o3k,2007-10-16,2006-12-01
-6o34,2020-02-26,2019-02-25
-7o3k,2022-04-13,2021-04-01
-5o3d,2018-02-14,2017-05-23
-1o3m,2003-09-02,2003-03-06
-7o3w,2021-06-30,2021-04-03
-4o3a,2014-04-16,2013-12-18
-5o32,2017-06-28,2017-05-23
-3o33,2010-12-15,2010-07-23
-4o35,2014-06-18,2013-12-18
-3o3d,2010-12-08,2010-07-23
-1o3e,2003-09-02,2003-03-06
-6o3c,2019-07-03,2019-02-26
-7o38,2021-10-13,2021-04-01
-2o3u,2006-12-19,2006-12-01
-3o36,2010-12-15,2010-07-23
-1o3a,2003-09-02,2003-03-06
-7o3r,2021-06-09,2021-04-02
-1o34,2003-09-02,2003-03-06
-6o3j,2019-12-04,2019-02-26
-5o33,2017-05-31,2017-05-23
-4o3p,2014-04-30,2013-12-18
-7o3a,2021-06-09,2021-04-01
-4o30,2014-03-26,2013-12-17
-5o3k,2018-03-28,2017-05-24
-3mgh,2010-05-19,2010-04-06
-5mgy,2016-12-14,2016-11-22
-1mgv,2002-11-27,2002-08-16
-6mgs,2019-06-19,2018-09-14
-7mgs,2021-06-23,2021-04-13
-4mg7,2014-09-03,2013-08-28
-1mgy,2003-07-07,2002-08-16
-5mg0,2017-02-22,2016-11-20
-3mgb,2010-06-09,2010-04-05
-5mgj,2017-04-12,2016-11-21
-5mgn,2016-12-28,2016-11-21
-6mg5,2019-04-10,2018-09-12
-4mgj,2014-08-13,2013-08-28
-3mgi,2010-05-19,2010-04-06
-1mgo,2002-11-13,2002-08-15
-7mgu,2021-09-08,2021-04-13
-6mgy,2018-10-03,2018-09-16
-7mga,2021-06-16,2021-04-12
-6mgg,2018-09-26,2018-09-13
-6mgk,2019-01-23,2018-09-14
-2mgu,2014-02-12,2013-11-07
-6mgc,2019-03-27,2018-09-13
-3mgw,2010-05-05,2010-04-07
-7mg1,2021-06-16,2021-04-12
-5mgu,2017-05-03,2016-11-22
-1mgw,2003-02-04,2002-08-16
-3mg0,2011-05-18,2010-04-05
-5mgk,2017-04-12,2016-11-21
-2mgt,2014-11-12,2013-11-06
-6mgr,2018-10-24,2018-09-14
-4mgy,2014-09-03,2013-08-29
-2mgl,1994-01-31,1993-05-10
-5mgr,2018-06-06,2016-11-22
-4mg9,2014-09-03,2013-08-28
-5mgl,2017-04-12,2016-11-21
-5mg7,2018-06-13,2016-11-21
-2mg9,2014-04-02,2013-10-30
-2mgy,2014-04-02,2013-11-11
-3mg7,2011-05-18,2010-04-05
-3mgc,2010-06-09,2010-04-05
-7mg8,2021-06-16,2021-04-12
-7mg6,2021-06-16,2021-04-12
-2mgk,1994-01-31,1993-05-10
-6mgx,2018-10-03,2018-09-16
-7mg2,2021-06-16,2021-04-12
-6mgp,2018-11-14,2018-09-14
-2mge,1994-01-31,1993-05-10
-5mg5,2017-12-20,2016-11-20
-3mgp,2010-06-16,2010-04-07
-6mgh,2018-12-19,2018-09-13
-3mg3,2010-04-14,2010-04-05
-6mg8,2018-11-28,2018-09-13
-4mgg,2013-10-16,2013-08-28
-4mgc,2014-09-03,2013-08-28
-5mg1,2017-02-22,2016-11-20
-7mgc,2021-06-16,2021-04-12
-4mgh,2013-12-11,2013-08-28
-5mgt,2018-06-06,2016-11-22
-7mgz,2021-10-13,2021-04-14
-7mgn,2021-07-21,2021-04-12
-6mgt,2019-06-19,2018-09-14
-3mgs,2010-06-16,2010-04-07
-2mgf,1994-01-31,1993-05-10
-3mgq,2010-06-16,2010-04-07
-7mg3,2021-06-16,2021-04-12
-6mga,2019-09-18,2018-09-13
-4mgi,2014-09-03,2013-08-28
-7mgd,2021-06-16,2021-04-12
-3mgu,2010-07-14,2010-04-07
-4mgq,2014-08-20,2013-08-28
-5mgd,2017-04-19,2016-11-21
-5mgp,2016-12-14,2016-11-21
-5mgc,2017-04-19,2016-11-21
-6mg7,2019-09-25,2018-09-13
-1mg3,2002-12-11,2002-08-14
-6mgf,2019-09-18,2018-09-13
-7mg7,2021-06-16,2021-04-12
-7mg5,2021-06-16,2021-04-12
-7mgq,2022-04-20,2021-04-13
-7mgj,2021-11-10,2021-04-12
-7mgm,2022-01-19,2021-04-12
-7mgo,2021-07-21,2021-04-13
-4mgb,2014-09-03,2013-08-28
-4mgx,2014-02-05,2013-08-29
-4mg2,2014-02-26,2013-08-28
-2mgj,1994-01-31,1993-05-10
-7mgw,2021-12-15,2021-04-13
-4mg6,2014-09-03,2013-08-28
-2mgb,1994-01-31,1993-05-10
-5mgs,2018-05-23,2016-11-22
-3mga,2010-04-21,2010-04-05
-2mgi,1994-01-31,1993-05-10
-7mgt,2021-12-08,2021-04-13
-5mgh,2017-05-03,2016-11-21
-3mgr,2010-06-16,2010-04-07
-6mgj,2019-01-23,2018-09-14
-4mgr,2013-10-30,2013-08-28
-3mg2,2010-04-14,2010-04-05
-1mgn,1994-01-31,1993-10-29
-6mgu,2018-10-24,2018-09-14
-7mg4,2021-06-16,2021-04-12
-3mg6,2011-05-18,2010-04-05
-7mg9,2021-06-16,2021-04-12
-1mg1,1999-04-06,1999-03-01
-5mgi,2018-03-14,2016-11-21
-7mge,2021-06-23,2021-04-12
-7mgk,2021-11-10,2021-04-12
-3mg8,2011-05-18,2010-04-05
-1mg5,2003-10-14,2002-08-14
-4mgk,2014-09-03,2013-08-28
-7mgx,2022-03-02,2021-04-13
-7mgr,2021-06-23,2021-04-13
-6mgb,2019-03-27,2018-09-13
-4mgt,2014-02-26,2013-08-28
-2mgm,1994-01-31,1993-05-10
-7mg0,2022-04-13,2021-04-12
-3mgx,2010-06-02,2010-04-07
-7mgy,2021-07-14,2021-04-13
-7mgb,2021-06-16,2021-04-12
-2mgh,1994-01-31,1993-05-10
-4mg3,2014-03-26,2013-08-28
-4mgz,2014-09-03,2013-08-29
-6mgi,2019-09-18,2018-09-13
-5mg2,2017-05-03,2016-11-20
-1mg0,2002-11-13,2002-08-14
-6mgl,2019-01-23,2018-09-14
-5mgm,2017-04-12,2016-11-21
-3mgn,2011-03-02,2010-04-07
-5mgx,2017-03-22,2016-11-22
-4mgd,2014-09-03,2013-08-28
-6mgq,2019-12-18,2018-09-14
-1mg2,2002-12-11,2002-08-14
-3mg5,2010-05-26,2010-04-05
-2mgd,1994-01-31,1993-05-10
-6mg0,2019-11-20,2018-09-12
-3mg1,2010-04-14,2010-04-05
-6mgz,2018-10-03,2018-09-16
-5mg9,2017-05-03,2016-11-21
-5mgg,2017-04-12,2016-11-21
-4mgu,2013-10-30,2013-08-28
-2mga,1994-01-31,1993-05-10
-4mga,2014-09-03,2013-08-28
-5mge,2017-04-12,2016-11-21
-5mgf,2017-04-12,2016-11-21
-4mgv,2013-12-04,2013-08-29
-4mg8,2014-09-03,2013-08-28
-5mgb,2016-12-21,2016-11-21
-3mg4,2011-04-27,2010-04-05
-5mgz,2017-01-18,2016-11-22
-6mgo,2018-11-21,2018-09-14
-2mgc,1994-01-31,1993-05-10
-3mg9,2010-06-09,2010-04-05
-5mgw,2017-05-03,2016-11-22
-2mgg,1994-01-31,1993-05-10
-3mgd,2010-04-28,2010-04-05
-5mga,2017-06-21,2016-11-21
-7mgl,2021-06-16,2021-04-12
-7mgv,2021-06-23,2021-04-13
-6pvh,2020-01-22,2019-07-20
-5pvt,2017-03-29,2017-02-07
-2pvr,2007-06-26,2007-05-10
-4pv0,2014-05-21,2014-03-14
-6pvb,2020-08-19,2019-07-20
-5pvy,2017-03-29,2017-02-07
-1pvb,1995-02-27,1995-01-05
-5pvg,2017-03-29,2017-02-07
-5pvk,2017-03-29,2017-02-07
-4pv6,2015-01-21,2014-03-15
-6pvf,2020-01-22,2019-07-20
-6pvi,2020-01-22,2019-07-20
-2pvu,2008-01-15,2007-05-10
-6pvs,2019-11-27,2019-07-21
-7pvm,2022-07-06,2021-10-05
-7pvx,2022-09-14,2021-10-05
-4pvi,2014-09-24,2014-03-17
-8pvf,2023-11-29,2023-07-17
-3pvu,2011-06-01,2010-12-07
-2pvy,2007-09-25,2007-05-10
-6pvg,2020-01-22,2019-07-20
-5pvv,2017-03-29,2017-02-07
-5pvi,2017-03-29,2017-02-07
-3pvn,2012-01-11,2010-12-07
-7pvg,2022-10-05,2021-10-02
-6pv9,2020-01-01,2019-07-19
-7pv7,2022-12-14,2021-10-01
-1pvy,2003-11-04,2003-06-29
-5pv1,2017-03-29,2017-02-07
-4pvq,2014-03-26,2014-03-18
-6pv7,2019-09-11,2019-07-19
-8pvz,2024-05-08,2023-07-18
-7pvn,2022-08-31,2021-10-05
-8pvp,2023-09-20,2023-07-18
-6pvm,2019-10-23,2019-07-21
-6pv4,2019-09-11,2019-07-19
-2pvc,2007-08-14,2007-05-09
-8pv3,2023-11-15,2023-07-17
-3pvz,2011-01-12,2010-12-07
-7pvf,2022-10-05,2021-10-02
-6pva,2020-08-19,2019-07-20
-4pv3,2014-09-03,2014-03-14
-4pvj,2014-04-02,2014-03-17
-5pvw,2017-03-29,2017-02-07
-5pvx,2017-03-29,2017-02-07
-5pv7,2017-03-29,2017-02-07
-4pvb,2014-06-25,2014-03-16
-3pvx,2011-08-10,2010-12-07
-2pv2,2007-10-02,2007-05-09
-4pvt,2014-11-19,2014-03-18
-2pvk,2008-05-13,2007-05-09
-5pv9,2017-03-29,2017-02-07
-5pvs,2017-03-29,2017-02-07
-8pv6,2023-11-15,2023-07-17
-5pv5,2017-03-29,2017-02-07
-1pv8,2003-09-09,2003-06-26
-7pvu,2023-05-17,2021-10-05
-3pv6,2011-03-16,2010-12-06
-1pv4,2003-07-22,2003-06-26
-5pvu,2017-03-29,2017-02-07
-2pvq,2008-01-15,2007-05-10
-7pv5,2023-04-19,2021-10-01
-2pvv,2007-05-22,2007-05-10
-8pvs,2024-02-28,2023-07-18
-2pvz,2007-08-21,2007-05-10
-3pvr,2011-01-19,2010-12-07
-3pvt,2011-01-19,2010-12-07
-7pvl,2023-04-19,2021-10-04
-2pvx,2007-12-18,2007-05-10
-6pvz,2019-12-25,2019-07-21
-5pv2,2017-03-29,2017-02-07
-1pv7,2003-08-12,2003-06-26
-6pve,2019-11-27,2019-07-20
-5pvf,2017-03-29,2017-02-07
-7pvs,2022-09-14,2021-10-05
-2pvf,2007-09-25,2007-05-09
-2pvh,2008-05-13,2007-05-09
-8pvo,2023-09-20,2023-07-18
-4pve,2014-04-02,2014-03-17
-4pv4,2014-04-02,2014-03-14
-2pve,2007-12-18,2007-05-09
-5pva,2017-03-29,2017-02-07
-3pvb,2011-02-02,2010-12-06
-5pvp,2017-03-29,2017-02-07
-8pvd,2023-11-29,2023-07-17
-4pvu,2015-02-11,2014-03-18
-2pvw,2007-05-22,2007-05-10
-8pvb,2023-11-29,2023-07-17
-6pv0,2020-06-24,2019-07-19
-2pvj,2008-05-13,2007-05-09
-7pvj,2022-04-06,2021-10-04
-6pv8,2019-09-11,2019-07-19
-6pv1,2020-06-24,2019-07-19
-3pvk,2011-12-07,2010-12-07
-3pvc,2011-04-13,2010-12-06
-1pv9,2004-03-23,2003-06-27
-6pvc,2020-04-01,2019-07-20
-1pvg,2003-08-26,2003-06-27
-1pvj,2004-09-28,2003-06-27
-4pvr,2014-03-26,2014-03-18
-3pvh,2011-10-26,2010-12-07
-4pvk,2014-04-02,2014-03-17
-5pve,2017-03-29,2017-02-07
-2pv3,2007-10-02,2007-05-09
-1pvf,2004-07-06,2003-06-27
-5pvj,2017-03-29,2017-02-07
-5pv8,2017-03-29,2017-02-07
-5pv4,2017-03-29,2017-02-07
-8pvt,2024-05-08,2023-07-18
-5pvl,2017-03-29,2017-02-07
-7pvo,2022-11-16,2021-10-05
-4pv8,2014-04-23,2014-03-15
-2pvs,2007-12-18,2007-05-10
-1pvo,2003-07-22,2003-06-27
-2pv1,2007-10-02,2007-05-09
-8pva,2023-11-29,2023-07-17
-5pvr,2017-03-29,2017-02-07
-2pv0,2007-08-14,2007-05-09
-1pvc,1995-09-15,1995-03-30
-3pvd,2011-08-03,2010-12-06
-4pvx,2015-04-15,2014-03-18
-3pvw,2011-06-01,2010-12-07
-6pvd,2020-04-01,2019-07-20
-4pvv,2014-11-26,2014-03-18
-7pvt,2022-09-14,2021-10-05
-2pv9,2007-07-10,2007-05-09
-7pvc,2021-10-13,2021-10-01
-5pvo,2017-03-29,2017-02-07
-1pva,1995-03-31,1995-01-16
-4pvo,2014-11-19,2014-03-18
-5pvd,2017-03-29,2017-02-07
-3pvf,2011-04-27,2010-12-07
-5pvz,2017-03-29,2017-02-07
-3pv4,2011-06-15,2010-12-06
-4pv5,2015-03-18,2014-03-15
-5pvq,2017-03-29,2017-02-07
-5pv3,2017-03-29,2017-02-07
-8pv2,2023-11-15,2023-07-17
-6pvj,2020-01-22,2019-07-20
-2pvm,2008-05-13,2007-05-09
-1pvm,2004-01-20,2003-06-27
-6pvy,2019-12-25,2019-07-21
-3pvo,2012-01-11,2010-12-07
-5pvh,2017-03-29,2017-02-07
-2pvn,2008-05-13,2007-05-09
-8pv7,2023-11-15,2023-07-17
-7pvk,2022-12-14,2021-10-04
-2pv7,2007-05-22,2007-05-09
-8pvl,2023-12-06,2023-07-17
-6pv2,2020-06-24,2019-07-19
-4pv9,2014-04-23,2014-03-15
-8pvv,2024-01-24,2023-07-18
-4pv2,2014-09-03,2014-03-14
-5pv6,2017-03-29,2017-02-07
-6pv3,2020-06-24,2019-07-19
-7pvi,2022-04-20,2021-10-04
-8pv1,2023-11-15,2023-07-17
-7pv8,2022-01-26,2021-10-01
-6pvv,2019-11-06,2019-07-21
-1pvs,2004-06-08,2003-06-28
-6pvw,2019-11-06,2019-07-21
-1pvn,2003-07-22,2003-06-27
-5pv0,2017-03-29,2017-02-07
-6pv6,2020-08-12,2019-07-19
-1pvw,2003-11-04,2003-06-29
-6pvl,2019-10-23,2019-07-21
-8pvc,2023-11-29,2023-07-17
-8pv5,2023-11-15,2023-07-17
-4pvg,2015-04-15,2014-03-17
-5pvb,2017-03-29,2017-02-07
-8pv8,2024-01-10,2023-07-17
-4pv1,2014-08-20,2014-03-14
-2pvb,1998-10-07,1998-10-02
-3pv8,2011-10-19,2010-12-06
-4pvs,2014-03-26,2014-03-18
-4pvh,2014-04-02,2014-03-17
-3pv7,2011-03-16,2010-12-06
-6pvx,2019-11-06,2019-07-21
-3pvm,2011-01-19,2010-12-07
-5pvm,2017-03-29,2017-02-07
-7pv6,2022-04-06,2021-10-01
-4pvp,2014-03-26,2014-03-18
-5pvc,2017-03-29,2017-02-07
-3pvy,2011-01-19,2010-12-07
-5pvn,2017-03-29,2017-02-07
-7pv0,2022-09-07,2021-10-01
-7pve,2022-10-05,2021-10-02
-1pvd,1995-07-31,1995-04-20
-4pv7,2015-03-18,2014-03-15
-6pvn,2019-10-23,2019-07-21
-2pvl,2008-05-13,2007-05-09
-7pvd,2021-12-29,2021-10-02
-8pv4,2023-11-15,2023-07-17
-4pvd,2014-10-22,2014-03-17
-8pvk,2023-12-06,2023-07-17
-7pva,2022-12-14,2021-10-01
-4pvy,2015-04-15,2014-03-18
-3pvg,2010-12-15,2010-12-07
-8pvm,2023-11-29,2023-07-18
-3pv0,2011-05-18,2010-12-06
-2n9j,2016-02-17,2015-11-24
-4n9r,2015-12-30,2013-10-21
-4n9f,2014-01-08,2013-10-21
-5n9b,2018-06-13,2017-02-24
-7n9d,2021-12-22,2021-06-17
-6n9v,2019-03-06,2018-12-04
-5n9c,2017-06-14,2017-02-24
-5n97,2017-04-19,2017-02-24
-6n9d,2019-05-15,2018-12-03
-4n95,2013-11-06,2013-10-19
-4n9a,2013-11-06,2013-10-19
-4n9c,2014-02-19,2013-10-20
-6n91,2018-12-19,2018-11-30
-2n9i,2016-02-17,2015-11-24
-4n94,2013-11-06,2013-10-19
-5n9r,2017-12-06,2017-02-27
-4n9e,2014-02-19,2013-10-20
-1n9k,2004-02-03,2002-11-25
-6n9e,2018-12-12,2018-12-03
-6n9u,2019-03-06,2018-12-04
-7n9g,2022-04-27,2021-06-17
-3n9k,2010-09-15,2010-05-30
-2n9p,2016-05-25,2015-12-01
-4n9v,2014-02-05,2013-10-21
-5n9k,2018-02-28,2017-02-25
-5n9f,2018-03-21,2017-02-24
-3n9v,2010-07-28,2010-05-31
-4n9i,2014-07-09,2013-10-21
-1n95,2003-01-07,2002-11-22
-6n9w,2019-03-06,2018-12-04
-6n9t,2019-01-16,2018-12-04
-3n9q,2010-06-30,2010-05-31
-4n9s,2014-02-05,2013-10-21
-3n9r,2010-11-17,2010-05-31
-3n9h,2010-08-25,2010-05-30
-5n9i,2018-02-21,2017-02-24
-4n91,2013-11-13,2013-10-18
-5n96,2018-03-14,2017-02-24
-3n92,2010-10-27,2010-05-28
-5n9u,2017-03-08,2017-02-27
-5n9x,2017-07-26,2017-02-27
-5n9z,2018-03-14,2017-02-27
-3n9d,2010-08-11,2010-05-28
-4n9z,2014-01-29,2013-10-21
-6n96,2019-04-10,2018-11-30
-3n9s,2010-11-17,2010-05-31
-1n9l,2003-06-17,2002-11-25
-4n98,2013-11-06,2013-10-19
-4n9q,2014-06-11,2013-10-21
-1n9m,2003-09-02,2002-11-25
-7n91,2022-07-06,2021-06-16
-4n9w,2014-11-12,2013-10-21
-6n9q,2019-04-03,2018-12-03
-7n93,2022-07-06,2021-06-16
-2n94,2016-05-11,2015-11-05
-7n9j,2022-06-22,2021-06-18
-3n9m,2010-06-30,2010-05-31
-2n95,2016-05-11,2015-11-06
-7n9k,2021-12-29,2021-06-18
-3n9b,2010-08-11,2010-05-28
-3n9p,2010-06-30,2010-05-31
-3n9n,2010-06-30,2010-05-31
-3n94,2011-06-08,2010-05-28
-6n99,2019-12-04,2018-12-01
-6n9f,2018-12-12,2018-12-03
-4n9u,2014-10-22,2013-10-21
-7n9z,2021-09-01,2021-06-19
-3n9j,2011-05-11,2010-05-30
-6n92,2019-04-10,2018-11-30
-5n9t,2017-12-06,2017-02-27
-3n93,2010-10-20,2010-05-28
-6n95,2019-04-10,2018-11-30
-1n94,2003-01-07,2002-11-22
-3n95,2010-10-20,2010-05-28
-3n9t,2010-08-04,2010-05-31
-1n90,1999-06-15,1998-09-04
-2n9o,2016-05-25,2015-12-01
-6n9a,2019-05-22,2018-12-01
-3n9l,2010-06-30,2010-05-31
-1n9e,2004-01-13,2002-11-24
-4n9y,2014-01-29,2013-10-21
-1n9o,2003-06-17,2002-11-25
-5n98,2018-03-14,2017-02-24
-1n9c,2003-02-04,2002-11-23
-3n9i,2010-07-21,2010-05-30
-4n9b,2014-02-19,2013-10-20
-5n9s,2017-05-31,2017-02-27
-3n98,2010-10-27,2010-05-28
-1n9f,2003-06-10,2002-11-25
-5n99,2017-10-04,2017-02-24
-6n97,2019-04-10,2018-11-30
-3n96,2010-10-20,2010-05-28
-5n92,2017-09-06,2017-02-24
-1n9n,2003-06-17,2002-11-25
-1n9a,2003-01-07,2002-11-22
-6n98,2019-12-04,2018-12-01
-4n9k,2014-09-10,2013-10-21
-5n9p,2017-06-14,2017-02-26
-1n92,2003-02-04,2002-11-21
-5n9m,2018-03-14,2017-02-25
-3n91,2010-07-28,2010-05-28
-6n9m,2019-02-06,2018-12-03
-1n9h,2003-06-10,2002-11-25
-5n94,2018-03-14,2017-02-24
-5n9e,2018-03-21,2017-02-24
-4n9d,2014-02-19,2013-10-20
-3n9z,2011-06-08,2010-05-31
-5n9g,2017-06-14,2017-02-24
-1n9b,2003-04-08,2002-11-22
-1n9i,2003-06-10,2002-11-25
-4n9p,2013-12-04,2013-10-21
-4n9m,2014-02-05,2013-10-21
-5n9n,2018-02-28,2017-02-25
-5n9a,2018-03-14,2017-02-24
-5n91,2017-06-28,2017-02-24
-1n9g,2003-12-09,2002-11-25
-6n9r,2019-04-03,2018-12-03
-6n93,2019-04-10,2018-11-30
-1n9z,2003-05-20,2002-11-26
-6n9x,2019-03-06,2018-12-04
-6n9p,2019-02-06,2018-12-03
-4n99,2013-11-06,2013-10-19
-6n9i,2019-04-03,2018-12-03
-4n90,2014-09-03,2013-10-18
-6n94,2019-04-10,2018-11-30
-4n96,2013-11-06,2013-10-19
-4n9l,2014-09-10,2013-10-21
-3n9o,2010-06-30,2010-05-31
-7n9o,2022-07-06,2021-06-18
-5n93,2017-05-31,2017-02-24
-5n9h,2018-02-21,2017-02-24
-6n9h,2019-12-18,2018-12-03
-4n9t,2013-10-30,2013-10-21
-6n9l,2019-05-01,2018-12-03
-5n90,2018-03-14,2017-02-24
-4n97,2013-11-06,2013-10-19
-1n9x,2003-06-10,2002-11-26
-5n9l,2018-02-28,2017-02-25
-1n97,2003-02-25,2002-11-22
-2n91,2016-09-21,2015-11-02
-6n9j,2019-12-11,2018-12-03
-4n93,2014-04-23,2013-10-19
-3n9y,2011-06-08,2010-05-31
-7n9l,2021-12-29,2021-06-18
-6th6,2020-07-29,2019-11-18
-7thk,2022-03-02,2022-01-11
-8the,2024-01-31,2023-07-15
-1th8,2004-06-15,2004-06-01
-8thl,2023-08-16,2023-07-17
-6thy,2020-01-29,2019-11-21
-5thb,2017-04-05,2016-09-29
-5ths,2016-12-21,2016-09-30
-4thn,1999-06-15,1998-09-18
-3the,2011-09-14,2011-08-18
-7thw,2022-01-26,2022-01-12
-3th7,2011-09-14,2011-08-18
-6th5,2020-11-25,2019-11-18
-5the,2018-03-14,2016-09-29
-6thk,2020-03-04,2019-11-20
-8thk,2023-08-16,2023-07-17
-6th0,2020-06-24,2019-11-18
-3th2,2012-08-22,2011-08-18
-6thx,2020-10-28,2019-11-21
-3thc,2011-12-07,2011-08-18
-3th0,2012-08-29,2011-08-18
-8th4,2024-05-22,2023-07-13
-5th2,2016-10-26,2016-09-28
-3th8,2012-07-04,2011-08-18
-7th5,2023-01-18,2022-01-10
-7thv,2022-02-16,2022-01-12
-1tha,1994-01-31,1991-11-21
-5th5,2017-01-18,2016-09-29
-3tht,2011-11-02,2011-08-19
-7thm,2022-03-16,2022-01-11
-7tho,2022-08-17,2022-01-11
-8thn,2024-01-17,2023-07-17
-5th4,2017-04-26,2016-09-29
-3thm,2012-05-09,2011-08-19
-3thn,2011-10-12,2011-08-19
-3thj,2011-09-14,2011-08-19
-7thd,2022-08-24,2022-01-10
-1th3,2005-07-05,2004-06-01
-1thm,1994-01-31,1992-02-24
-3thq,2012-05-02,2011-08-19
-5thp,2017-08-02,2016-09-30
-6thp,2020-02-12,2019-11-21
-6thf,2020-04-22,2019-11-20
-5thk,2016-10-12,2016-09-29
-6th2,2020-11-25,2019-11-18
-1tho,1993-10-31,1993-01-28
-7thi,2022-01-26,2022-01-11
-8thp,2024-04-17,2023-07-17
-1the,1996-03-10,1995-09-15
-5thy,2016-10-19,2016-09-30
-3thy,2011-12-21,2011-08-19
-7th1,2022-08-24,2022-01-10
-6tho,2020-12-02,2019-11-20
-6thb,2019-12-18,2019-11-19
-8th5,2024-03-20,2023-07-13
-5thz,2016-10-19,2016-09-30
-1th4,2005-07-05,2004-06-01
-7thx,2022-03-09,2022-01-12
-3thk,2011-11-23,2011-08-19
-4thi,1998-10-14,1998-10-05
-3thb,2011-11-23,2011-08-18
-5thc,2017-04-05,2016-09-29
-1thn,2004-06-15,2004-06-01
-5thj,2017-04-26,2016-09-29
-8th3,2024-05-22,2023-07-13
-3thp,2011-11-02,2011-08-19
-5th6,2017-03-01,2016-09-29
-8th1,2023-12-27,2023-07-13
-8thd,2024-05-22,2023-07-14
-1thy,1993-10-31,1993-04-02
-5th1,2017-04-05,2016-09-28
-8th9,2023-11-01,2023-07-14
-7th4,2023-01-18,2022-01-10
-3thd,2011-12-07,2011-08-18
-8thb,2024-05-22,2023-07-14
-5thg,2017-05-03,2016-09-29
-8thg,2023-11-22,2023-07-16
-6the,2020-04-22,2019-11-20
-1th2,2005-07-05,2004-06-01
-3th4,2012-08-22,2011-08-18
-5thr,2016-11-16,2016-09-30
-3th1,2012-08-22,2011-08-18
-7thc,2022-08-24,2022-01-10
-7th6,2022-08-24,2022-01-10
-5th3,2016-12-21,2016-09-29
-5thn,2017-04-26,2016-09-29
-6th7,2020-03-04,2019-11-18
-7tha,2023-04-12,2022-01-10
-1thj,1996-10-14,1996-04-02
-7thz,2022-12-28,2022-01-12
-5th0,2017-04-05,2016-09-28
-1thp,1999-03-03,1999-01-26
-8thm,2023-08-09,2023-07-17
-6thj,2020-12-02,2019-11-20
-8thj,2023-11-22,2023-07-16
-3tho,2011-10-12,2011-08-19
-7thj,2022-02-16,2022-01-11
-3thw,2011-12-21,2011-08-19
-5thx,2016-10-19,2016-09-30
-6thv,2020-07-15,2019-11-21
-6thq,2020-09-30,2019-11-21
-1thz,2004-09-07,2004-06-01
-8thc,2024-05-22,2023-07-14
-5thi,2017-04-26,2016-09-29
-6thz,2020-10-28,2019-11-21
-7tht,2022-02-16,2022-01-12
-5thq,2016-11-09,2016-09-30
-3th9,2011-09-28,2011-08-18
-6thw,2020-10-28,2019-11-21
-3thx,2011-12-21,2011-08-19
-7th7,2022-08-24,2022-01-10
-8thh,2023-11-22,2023-07-16
-7thf,2022-08-24,2022-01-10
-6th4,2021-12-01,2019-11-18
-5thv,2016-12-21,2016-09-30
-1ths,1994-01-31,1993-06-16
-5th9,2017-03-15,2016-09-29
-3th3,2012-08-22,2011-08-18
-5thh,2017-05-17,2016-09-29
-1th9,2005-01-25,2004-06-01
-1thb,1991-01-15,1990-01-23
-6thh,2020-10-28,2019-11-20
-5tho,2017-01-11,2016-09-30
-5thu,2016-12-21,2016-09-30
-7thu,2022-03-30,2022-01-12
-1th6,2004-06-15,2004-06-01
-7thg,2023-04-12,2022-01-10
-1thc,1993-07-15,1992-04-20
-3thz,2011-12-21,2011-08-19
-1thk,2005-01-25,2004-06-01
-3thr,2011-11-16,2011-08-19
-7ths,2023-01-18,2022-01-12
-2thf,1999-03-07,1999-01-26
-6thc,2020-11-25,2019-11-19
-3thh,2011-09-14,2011-08-19
-7thq,2022-11-30,2022-01-11
-7thr,2023-01-25,2022-01-11
-1thg,1993-10-31,1992-07-28
-7thy,2022-12-28,2022-01-12
-8thr,2023-10-25,2023-07-17
-8thi,2023-11-22,2023-07-16
-6thg,2019-12-18,2019-11-20
-3th5,2012-07-18,2011-08-18
-5thf,2017-04-05,2016-09-29
-6thn,2020-12-09,2019-11-20
-5thw,2016-11-09,2016-09-30
-7thn,2022-11-30,2022-01-11
-5tht,2016-12-21,2016-09-30
-7the,2022-02-16,2022-01-10
-7naa,2021-08-04,2021-06-21
-3nai,2011-06-08,2010-06-02
-6na4,2020-03-18,2018-12-05
-5nan,2017-09-06,2017-02-28
-5na7,2017-11-15,2017-02-27
-6nag,2019-12-11,2018-12-05
-1naz,2003-06-10,2002-11-30
-3nae,2010-09-15,2010-06-01
-4naa,2016-10-26,2013-10-22
-5na0,2017-05-31,2017-02-27
-4na9,2014-02-12,2013-10-21
-7na9,2021-12-22,2021-06-20
-6nak,2023-04-26,2018-12-05
-5nap,2018-05-02,2017-02-28
-4nax,2013-11-06,2013-10-22
-5nau,2018-05-02,2017-02-28
-1na3,2003-06-03,2002-11-26
-6na3,2019-12-11,2018-12-05
-1naq,2003-11-25,2002-11-28
-4nas,2013-11-13,2013-10-22
-4nat,2014-03-12,2013-10-22
-3na5,2011-02-16,2010-06-01
-7na7,2021-12-15,2021-06-20
-4naw,2013-11-06,2013-10-22
-5nad,2017-05-31,2017-02-27
-7nas,2021-07-07,2021-01-25
-2nax,2016-11-23,2016-01-12
-4nay,2014-02-26,2013-10-22
-3nan,2010-06-30,2010-06-02
-7nac,2022-11-09,2021-06-21
-7nat,2021-12-08,2021-01-25
-5na9,2017-08-16,2017-02-27
-4nam,2014-01-22,2013-10-22
-4nab,2013-12-18,2013-10-22
-3na8,2011-06-01,2010-06-01
-6na6,2019-12-11,2018-12-05
-3nab,2010-08-18,2010-06-01
-6nab,2019-01-30,2018-12-05
-5nah,2017-06-21,2017-02-27
-7na8,2021-12-15,2021-06-20
-6naf,2019-12-18,2018-12-05
-1nam,2003-03-11,2002-11-28
-4na0,2014-01-29,2013-10-21
-4nap,2013-11-13,2013-10-22
-3nal,2010-06-30,2010-06-02
-1nai,1996-12-23,1995-11-22
-6nax,2019-03-13,2018-12-06
-4naj,2014-10-29,2013-10-22
-7nal,2022-03-23,2021-06-21
-6nae,2019-12-11,2018-12-05
-1nav,2003-06-17,2002-11-29
-3naa,2010-08-18,2010-06-01
-6naq,2019-11-13,2018-12-06
-3na1,2011-06-08,2010-05-31
-3na0,2010-09-08,2010-05-31
-7na4,2021-11-10,2021-06-19
-6na5,2019-12-11,2018-12-05
-5naw,2017-06-28,2017-02-28
-5nar,2017-06-28,2017-02-28
-7nax,2021-12-08,2021-01-25
-7nab,2021-12-08,2021-06-21
-4na8,2014-02-12,2013-10-21
-7naj,2022-03-23,2021-06-21
-6nah,2019-11-13,2018-12-05
-2nab,2016-03-09,2015-12-22
-7na0,2021-09-22,2021-06-19
-1na1,2003-12-16,2002-11-26
-5nak,2017-06-21,2017-02-28
-5nas,2017-03-29,2017-02-28
-7na2,2021-11-10,2021-06-19
-6nad,2019-05-08,2018-12-05
-5naj,2017-05-24,2017-02-28
-7nar,2021-12-08,2021-01-25
-7nag,2022-03-23,2021-06-21
-3nay,2010-11-24,2010-06-02
-4nan,2014-01-29,2013-10-22
-6nac,2019-12-11,2018-12-05
-4nau,2014-03-12,2013-10-22
-7nah,2022-03-23,2021-06-21
-4naz,2014-02-26,2013-10-22
-6naj,2019-12-11,2018-12-05
-4nah,2014-03-12,2013-10-22
-4nai,2014-01-29,2013-10-22
-3nat,2010-07-28,2010-06-02
-7nay,2021-02-10,2021-01-25
-3nag,2011-06-08,2010-06-02
-7naf,2022-11-09,2021-06-21
-2na5,2016-09-21,2015-12-21
-5na8,2017-11-15,2017-02-27
-7na3,2021-11-10,2021-06-19
-5na5,2017-06-21,2017-02-27
-5nab,2017-06-21,2017-02-27
-4nao,2014-01-15,2013-10-22
-5nat,2018-03-21,2017-02-28
-5na1,2018-01-10,2017-02-27
-4na4,2014-01-29,2013-10-21
-2naa,2016-03-09,2015-12-22
-4na7,2014-02-12,2013-10-21
-6nas,2020-01-29,2018-12-06
-4nak,2014-01-29,2013-10-22
-2nap,1999-09-19,1998-09-18
-5nag,2017-06-21,2017-02-27
-7nam,2022-06-29,2021-06-21
-5nal,2017-05-10,2017-02-28
-3na6,2010-07-28,2010-06-01
-7nae,2022-06-29,2021-06-21
-6nao,2018-12-19,2018-12-06
-1naa,2003-01-14,2002-11-27
-3nax,2010-11-24,2010-06-02
-3nak,2010-07-28,2010-06-02
-3nam,2010-06-30,2010-06-02
-3na9,2010-08-18,2010-06-01
-7na1,2021-11-10,2021-06-19
-7na5,2022-06-22,2021-06-19
-1na0,2003-06-03,2002-11-26
-5na6,2017-11-15,2017-02-27
-5nai,2017-05-17,2017-02-28
-3nac,2010-08-18,2010-06-01
-1nas,1999-03-30,1998-03-26
-7nau,2021-12-08,2021-01-25
-4naq,2013-12-04,2013-10-22
-1nax,2003-06-17,2002-11-29
-1nah,1996-12-23,1995-11-22
-7nav,2021-12-08,2021-01-25
-5na4,2018-01-10,2017-02-27
-1nan,2003-03-11,2002-11-28
-7nai,2022-03-23,2021-06-21
-4nae,2014-06-25,2013-10-22
-3na7,2010-09-22,2010-06-01
-7nak,2022-03-23,2021-06-21
-2nad,1995-01-26,1994-07-06
-4nal,2014-01-29,2013-10-22
-5nae,2017-06-21,2017-02-27
-6naz,2019-12-18,2018-12-06
-7nad,2022-11-09,2021-06-21
-1nae,2003-03-18,2002-11-27
-5s3n,2021-01-13,2020-11-02
-3s32,2011-06-08,2011-05-17
-7s3w,2021-09-22,2021-09-08
-6s3o,2021-01-13,2019-06-25
-1s3x,2004-01-20,2004-01-14
-4s39,2015-04-29,2015-01-26
-6s36,2019-08-07,2019-06-24
-1s3h,2004-09-07,2004-01-13
-5s39,2021-01-13,2020-11-02
-3s3w,2012-05-23,2011-05-18
-4s37,2016-01-27,2015-01-26
-6s30,2020-01-08,2019-06-23
-7s3u,2021-09-22,2021-09-08
-5s38,2021-01-13,2020-11-02
-1s3v,2004-03-30,2004-01-14
-7s3x,2022-09-14,2021-09-08
-4s3g,2015-07-01,2015-01-26
-3s3q,2011-08-10,2011-05-18
-1s3y,2004-03-30,2004-01-14
-3s3p,2012-06-06,2011-05-18
-6s3a,2021-01-13,2019-06-24
-1s30,2004-06-22,2004-01-12
-3s3s,2012-06-06,2011-05-18
-5s3f,2021-01-13,2020-11-02
-7s35,2022-07-13,2021-09-04
-4s35,2016-01-27,2015-01-26
-5s32,2021-01-13,2020-11-02
-3s3v,2011-09-28,2011-05-18
-7s3z,2022-09-14,2021-09-08
-1s3b,2004-03-30,2004-01-13
-3s3x,2012-05-23,2011-05-18
-6s3z,2020-04-29,2019-06-26
-1s3s,2004-03-30,2004-01-14
-3s3i,2012-04-04,2011-05-18
-1s3p,2004-09-07,2004-01-13
-5s3y,2021-01-13,2020-11-02
-5s33,2021-01-13,2020-11-02
-1s3u,2004-03-30,2004-01-14
-5s3h,2021-01-13,2020-11-02
-5s3z,2021-01-13,2020-11-02
-5s3i,2021-01-13,2020-11-02
-5s36,2021-01-13,2020-11-02
-3s3d,2012-05-23,2011-05-18
-6s35,2020-02-26,2019-06-24
-5s3x,2021-01-13,2020-11-02
-5s3g,2021-01-13,2020-11-02
-5s3m,2021-01-13,2020-11-02
-6s3x,2020-07-08,2019-06-26
-6s3n,2021-01-13,2019-06-25
-4s34,2016-01-27,2015-01-26
-1s3z,2004-05-18,2004-01-14
-6s37,2020-10-21,2019-06-24
-7s3l,2022-05-11,2021-09-07
-4s3r,2015-07-08,2015-03-26
-7s3j,2022-11-09,2021-09-07
-3s3e,2011-11-02,2011-05-18
-3s3g,2012-04-04,2011-05-18
-3s3y,2011-08-03,2011-05-18
-1s3k,2004-07-13,2004-01-13
-4s3a,2015-05-06,2015-01-26
-7s3g,2021-12-15,2021-09-06
-1s3c,2005-02-15,2004-01-13
-1s36,2004-10-05,2004-01-12
-5s31,2021-01-13,2020-11-02
-5s3p,2021-01-13,2020-11-02
-1s3t,2004-04-06,2004-01-14
-5s3d,2021-01-13,2020-11-02
-7s3b,2022-05-25,2021-09-05
-5s3a,2021-01-13,2020-11-02
-7s3p,2023-01-11,2021-09-07
-5s3e,2021-01-13,2020-11-02
-7s3s,2021-09-15,2021-09-08
-1s3n,2004-08-10,2004-01-13
-5s3k,2021-01-13,2020-11-02
-6s38,2020-10-21,2019-06-24
-4s3e,2015-04-29,2015-01-26
-1s3e,2004-03-30,2004-01-13
-5s3c,2021-01-13,2020-11-02
-1s38,2004-07-27,2004-01-12
-6s31,2020-01-29,2019-06-23
-7s3a,2022-05-25,2021-09-05
-3s3n,2011-07-13,2011-05-18
-6s3p,2021-01-13,2019-06-25
-1s3w,2004-03-30,2004-01-14
-1s32,2004-05-11,2004-01-12
-3s3m,2011-07-13,2011-05-18
-4s38,2015-04-29,2015-01-26
-6s3v,2019-10-09,2019-06-26
-8s3e,2024-04-10,2024-02-20
-7s33,2022-07-13,2021-09-04
-3s3h,2011-11-02,2011-05-18
-5s3t,2021-01-13,2020-11-02
-6s3m,2021-01-13,2019-06-25
-1s3m,2004-08-10,2004-01-13
-3s3b,2012-05-23,2011-05-18
-6s3b,2020-10-21,2019-06-24
-7s32,2022-07-13,2021-09-04
-5s3b,2021-01-13,2020-11-02
-6s39,2020-06-17,2019-06-24
-5s3o,2021-01-13,2020-11-02
-6s3i,2021-01-13,2019-06-25
-5s35,2021-01-13,2020-11-02
-5s3u,2021-01-13,2020-11-02
-6s3k,2020-02-12,2019-06-25
-3s38,2012-05-23,2011-05-17
-7s3t,2022-10-05,2021-09-08
-1s3d,2005-02-15,2004-01-13
-4s3q,2015-07-08,2015-03-26
-4s33,2016-01-27,2015-01-26
-3s3j,2012-06-06,2011-05-18
-6s3c,2020-06-17,2019-06-25
-4s3c,2015-05-06,2015-01-26
-5s3v,2021-01-13,2020-11-02
-4s32,2016-01-27,2015-01-26
-5s3q,2021-01-13,2020-11-02
-4s3b,2015-04-29,2015-01-26
-3s3f,2011-11-02,2011-05-18
-4s3s,2015-07-01,2015-06-19
-4s3m,2015-03-11,2015-02-19
-5s34,2021-01-13,2020-11-02
-7s3y,2022-09-14,2021-09-08
-5s3s,2021-01-13,2020-11-02
-3s3z,2011-08-03,2011-05-18
-7s30,2022-07-13,2021-09-04
-7s34,2022-07-13,2021-09-04
-7s3k,2021-09-15,2021-09-07
-5s3w,2021-01-13,2020-11-02
-5s3j,2021-01-13,2020-11-02
-3s3o,2011-07-13,2011-05-18
-1s3q,2005-04-12,2004-01-13
-3s3r,2011-08-10,2011-05-18
-3s3k,2011-11-02,2011-05-18
-4s3o,2015-07-15,2015-03-23
-1s39,2004-11-16,2004-01-12
-3s39,2012-05-23,2011-05-17
-4s3f,2015-04-29,2015-01-26
-3s3t,2011-06-08,2011-05-18
-3s30,2011-06-08,2011-05-17
-6s3t,2019-11-13,2019-06-26
-7s31,2022-07-13,2021-09-04
-6s3q,2020-07-08,2019-06-25
-5s30,2021-01-13,2020-11-02
-8s32,2024-02-28,2024-02-19
-6s3j,2019-10-09,2019-06-25
-5s37,2021-01-13,2020-11-02
-6s3h,2021-01-13,2019-06-25
-1s3g,2004-05-04,2004-01-13
-3s33,2012-05-23,2011-05-17
-6s32,2020-01-29,2019-06-24
-4s36,2016-01-27,2015-01-26
-7s3d,2021-11-24,2021-09-05
-6s3g,2019-10-09,2019-06-25
-1s3f,2004-03-30,2004-01-13
-5s3l,2021-01-13,2020-11-02
-3s3c,2012-05-23,2011-05-18
-3s3a,2012-05-23,2011-05-18
-7s3f,2021-12-15,2021-09-06
-5s3r,2021-01-13,2020-11-02
-7s3c,2022-05-25,2021-09-05
-3s35,2011-08-24,2011-05-17
-4h2y,2013-03-06,2012-09-13
-1h2r,2000-01-05,1999-06-14
-6h2z,2018-12-19,2018-07-17
-4h2x,2013-03-06,2012-09-13
-6h23,2018-08-29,2018-07-13
-1h21,2003-02-20,2002-07-30
-2h2g,2006-11-28,2006-05-18
-3h2q,2010-05-05,2009-04-14
-3h2l,2009-12-08,2009-04-14
-4h2c,2013-02-13,2012-09-12
-2h2e,2006-05-30,2006-05-18
-2h2a,2006-08-08,2006-05-18
-5h2o,2016-12-21,2016-10-15
-8h2f,2023-09-13,2022-10-05
-6h21,2018-09-26,2018-07-12
-4h2l,2013-04-10,2012-09-12
-5h2h,2016-12-21,2016-10-15
-6h2u,2019-07-31,2018-07-16
-5h2n,2016-12-21,2016-10-15
-1h2l,2002-11-28,2002-08-12
-2h26,2006-07-04,2006-05-18
-2h21,2006-05-30,2006-05-17
-3h2c,2009-12-08,2009-04-14
-2h2n,2006-07-18,2006-05-19
-1h2y,2002-11-11,2002-08-20
-1h24,2003-02-01,2002-07-31
-3h2n,2009-12-08,2009-04-14
-1h2m,2002-11-28,2002-08-12
-7h2j,2024-05-08,2024-04-03
-5h2j,2016-12-21,2016-10-15
-4h2b,2012-11-28,2012-09-12
-6h2i,2019-01-23,2018-07-13
-7h23,2024-05-08,2024-04-03
-6h29,2018-09-05,2018-07-13
-8h29,2023-08-16,2022-10-05
-7h2c,2024-05-08,2024-04-03
-6h2t,2018-07-25,2018-07-16
-8h20,2023-08-16,2022-10-04
-5h20,2017-03-08,2016-10-13
-4h2w,2013-03-06,2012-09-13
-3h2s,2009-04-28,2009-04-14
-1h28,2003-02-01,2002-07-31
-6h2v,2019-07-31,2018-07-16
-5h24,2017-01-25,2016-10-14
-2h29,2006-08-08,2006-05-18
-4h2a,2013-09-25,2012-09-12
-7h2i,2024-05-08,2024-04-03
-5h2f,2017-03-22,2016-10-15
-2h2q,2008-04-08,2006-05-19
-7h2o,2024-05-08,2024-04-03
-1h2b,2003-08-28,2002-08-02
-2h2f,2006-12-05,2006-05-18
-5h2i,2016-12-21,2016-10-15
-5h2r,2017-11-01,2016-10-17
-3h2e,2009-12-08,2009-04-14
-4h2u,2013-03-06,2012-09-13
-8h2w,2023-10-11,2022-10-07
-7h2g,2024-05-08,2024-04-03
-3h2z,2009-06-16,2009-04-15
-4h2f,2012-11-28,2012-09-12
-1h27,2003-02-01,2002-07-31
-4h2q,2013-09-18,2012-09-13
-1h2u,2002-10-17,2002-08-16
-1h2g,2003-07-17,2002-08-08
-3h21,2009-12-08,2009-04-14
-6h2h,2019-01-23,2018-07-13
-5h22,2017-10-11,2016-10-13
-8h2c,2022-11-09,2022-10-05
-8h2b,2023-10-18,2022-10-05
-1h26,2003-02-01,2002-07-31
-6h22,2019-07-31,2018-07-12
-2h28,2006-07-18,2006-05-18
-8h28,2023-10-11,2022-10-05
-2h23,2006-05-30,2006-05-17
-5h21,2017-07-05,2016-10-13
-7h2l,2024-05-08,2024-04-03
-1h23,2002-12-23,2002-07-30
-4h2m,2012-12-19,2012-09-12
-2h2h,2006-12-05,2006-05-18
-7h2t,2024-04-24,2024-04-04
-4h2i,2012-11-28,2012-09-12
-3h2b,2009-04-28,2009-04-14
-7h2y,2024-04-24,2024-04-04
-5h2q,2017-11-01,2016-10-17
-1h2z,2002-11-11,2002-08-20
-1h2c,2003-04-10,2002-08-05
-5h29,2017-11-22,2016-10-14
-5h2m,2016-12-21,2016-10-15
-4h2r,2013-09-18,2012-09-13
-3h22,2009-12-08,2009-04-14
-4h2t,2013-03-06,2012-09-13
-4h2n,2013-09-18,2012-09-12
-8h26,2023-01-18,2022-10-05
-8h2v,2023-10-11,2022-10-07
-4h2h,2012-10-10,2012-09-12
-5h2l,2016-12-21,2016-10-15
-3h2w,2009-10-13,2009-04-14
-5h2d,2017-05-10,2016-10-14
-8h2t,2023-06-14,2022-10-07
-7h2z,2024-04-24,2024-04-04
-3h2a,2009-12-08,2009-04-14
-8h24,2023-08-23,2022-10-04
-2h2d,2006-09-19,2006-05-18
-5h2u,2017-01-04,2016-10-18
-4h2k,2012-11-21,2012-09-12
-8h21,2023-08-16,2022-10-04
-4h2j,2012-12-19,2012-09-12
-8h2a,2023-10-18,2022-10-05
-3h24,2009-12-08,2009-04-14
-4h24,2013-06-26,2012-09-11
-1h2k,2002-11-28,2002-08-12
-3h26,2009-12-08,2009-04-14
-8h2j,2023-02-22,2022-10-06
-1h2t,2002-10-17,2002-08-16
-1h22,2002-12-23,2002-07-30
-5h25,2017-01-25,2016-10-14
-6h2s,2019-07-31,2018-07-16
-1h29,2002-10-02,2002-08-01
-4h2v,2013-03-06,2012-09-13
-5h2p,2016-12-21,2016-10-15
-4h2s,2013-03-06,2012-09-13
-4h2d,2013-04-17,2012-09-12
-3h2f,2009-12-08,2009-04-14
-4h26,2013-10-16,2012-09-12
-8h27,2023-01-25,2022-10-05
-4h2g,2012-11-28,2012-09-12
-2h2k,2007-05-22,2006-05-19
-4h2p,2013-09-18,2012-09-13
-4h25,2013-10-16,2012-09-12
-4h2o,2012-12-19,2012-09-13
-4h2z,2013-04-10,2012-09-13
-5h2v,2016-12-14,2016-10-18
-1h2h,2002-08-15,2002-08-08
-6h2g,2019-01-23,2018-07-13
-7h29,2024-05-08,2024-04-03
-3h23,2009-12-08,2009-04-14
-1h2d,2003-04-10,2002-08-06
-7h22,2024-05-08,2024-04-03
-7h2a,2024-05-08,2024-04-03
-1h2s,2002-10-10,2002-08-15
-6h2b,2018-10-31,2018-07-13
-3h2p,2010-05-05,2009-04-14
-8h2g,2023-10-11,2022-10-06
-7h2r,2024-05-08,2024-04-03
-2h2u,2006-07-18,2006-05-19
-6h2m,2019-03-13,2018-07-13
-6h2c,2019-01-23,2018-07-13
-3h2m,2009-12-08,2009-04-14
-6h20,2018-08-01,2018-07-12
-6h2q,2018-08-15,2018-07-14
-1h2j,2002-08-15,2002-08-09
-4h23,2013-06-26,2012-09-11
-8h2u,2023-06-14,2022-10-07
-2h2t,2006-06-20,2006-05-19
-4h2e,2013-04-24,2012-09-12
-8h2n,2023-10-11,2022-10-06
-7h25,2024-05-08,2024-04-03
-5h2k,2016-12-21,2016-10-15
-1h2a,1999-02-09,1997-10-17
-6h2k,2019-01-23,2018-07-13
-2h2j,2006-05-30,2006-05-18
-6h2j,2018-08-08,2018-07-13
-5h2z,2017-03-01,2016-10-19
-3h2y,2009-06-16,2009-04-15
-2h2i,2006-12-05,2006-05-18
-1h2n,2002-11-28,2002-08-12
-7h2d,2024-05-08,2024-04-03
-6h2p,2018-08-29,2018-07-14
-3h2o,2009-12-08,2009-04-14
-6h2n,2018-09-26,2018-07-13
-6h25,2018-08-15,2018-07-13
-4y3f,2016-02-17,2015-02-10
-6y3r,2020-10-14,2020-02-18
-1y3y,2005-12-06,2004-11-26
-6y3w,2020-11-18,2020-02-19
-4y3z,2016-02-17,2015-02-10
-4y3n,2016-02-17,2015-02-10
-6y3a,2020-02-26,2020-02-17
-4y3m,2016-02-17,2015-02-10
-4y3s,2016-02-17,2015-02-10
-1y3v,2005-12-06,2004-11-26
-8y3x,2024-05-08,2024-01-29
-5y36,2017-12-06,2017-07-27
-4y3q,2016-02-17,2015-02-10
-7y3w,2022-09-21,2022-06-13
-1y3q,2005-04-12,2004-11-26
-6y34,2020-07-01,2020-02-17
-4y35,2016-03-02,2015-02-10
-2y3g,2011-03-30,2010-12-20
-5y3q,2018-01-10,2017-07-29
-5y3k,2018-04-18,2017-07-29
-2y3p,2010-12-29,2010-12-22
-4y3g,2016-02-17,2015-02-10
-4y3p,2016-02-17,2015-02-10
-4y32,2015-12-23,2015-02-10
-2y37,2011-04-13,2010-12-19
-6y33,2020-07-01,2020-02-17
-6y3j,2020-09-02,2020-02-18
-2y3a,2011-03-16,2010-12-20
-4y3y,2016-02-17,2015-02-10
-2y31,2011-03-09,2010-12-17
-2y30,2011-03-09,2010-12-17
-2y3c,2011-08-31,2010-12-20
-2y3q,2011-02-16,2010-12-22
-7y3f,2023-03-01,2022-06-10
-6y3q,2020-07-01,2020-02-18
-6y3u,2020-04-22,2020-02-18
-2y3s,2011-06-29,2010-12-23
-5y3l,2018-04-18,2017-07-29
-5y3s,2018-08-01,2017-07-30
-6y3e,2020-03-04,2020-02-18
-2y35,2011-03-16,2010-12-18
-5y37,2018-04-18,2017-07-28
-1y3g,2006-01-17,2004-11-24
-5y34,2017-08-16,2017-07-27
-1y3d,2005-05-17,2004-11-24
-4y36,2016-02-17,2015-02-10
-1y34,2005-05-17,2004-11-23
-4y3h,2016-02-17,2015-02-10
-4y3w,2016-02-17,2015-02-10
-1y33,2005-05-17,2004-11-23
-1y38,2005-05-03,2004-11-24
-7y3s,2023-07-05,2022-06-12
-1y3j,2005-03-08,2004-11-25
-1y37,2006-02-28,2004-11-23
-2y3r,2011-06-29,2010-12-22
-7y3k,2022-10-26,2022-06-11
-4y37,2016-02-17,2015-02-10
-6y3s,2020-10-14,2020-02-18
-5y3m,2018-04-18,2017-07-29
-2y3b,2011-03-30,2010-12-20
-1y3u,2005-12-06,2004-11-26
-4y3e,2016-02-17,2015-02-10
-4y3a,2016-02-17,2015-02-10
-2y3d,2011-03-30,2010-12-20
-5y35,2018-08-08,2017-07-27
-7y3m,2022-10-26,2022-06-11
-1y3i,2005-01-18,2004-11-25
-7y3n,2023-12-27,2022-06-11
-5y31,2018-05-02,2017-07-27
-4y3l,2016-02-17,2015-02-10
-5y3n,2017-08-30,2017-07-29
-6y3o,2020-10-14,2020-02-18
-4y34,2015-04-01,2015-02-10
-1y3c,2005-05-17,2004-11-24
-5y3z,2018-04-11,2017-07-31
-6y3d,2020-12-30,2020-02-18
-6y3m,2020-10-14,2020-02-18
-1y3w,2005-12-06,2004-11-26
-4y38,2016-03-02,2015-02-10
-6y3z,2020-04-29,2020-02-19
-7y3v,2023-04-05,2022-06-13
-5y3j,2018-04-18,2017-07-29
-2y3f,2011-02-16,2010-12-20
-1y3a,2005-07-12,2004-11-24
-6y3y,2020-04-08,2020-02-19
-2y36,2011-12-28,2010-12-18
-7y3u,2022-06-29,2022-06-13
-5y3i,2018-08-08,2017-07-28
-5y3e,2018-01-10,2017-07-28
-7y3i,2022-10-26,2022-06-10
-4y3d,2016-02-17,2015-02-10
-4y30,2015-04-22,2015-02-10
-2y34,2010-12-29,2010-12-18
-4y3b,2015-12-23,2015-02-10
-4y3o,2015-10-07,2015-02-10
-2y38,2011-02-23,2010-12-19
-4y3i,2015-05-20,2015-02-10
-6y3b,2020-07-08,2020-02-18
-2y3y,2011-08-17,2011-01-04
-5y3o,2017-08-30,2017-07-29
-6y32,2020-09-23,2020-02-17
-7y3x,2022-09-21,2022-06-13
-6y3v,2020-10-14,2020-02-19
-2y3l,2011-11-02,2010-12-21
-8y33,2024-02-28,2024-01-28
-1y3b,2005-05-17,2004-11-24
-2y39,2011-03-30,2010-12-20
-4y3u,2015-02-25,2015-02-10
-2y3k,2011-11-02,2010-12-21
-4y3j,2016-02-17,2015-02-10
-7y3h,2023-06-14,2022-06-10
-4y3r,2016-02-17,2015-02-10
-1y3n,2005-04-12,2004-11-26
-1y3f,2005-05-17,2004-11-24
-7y38,2022-12-14,2022-06-10
-4y3t,2016-02-17,2015-02-10
-7y3y,2022-09-21,2022-06-13
-7y3l,2022-10-26,2022-06-11
-2y3n,2012-01-11,2010-12-22
-2y3j,2011-11-02,2010-12-21
-2y3i,2011-04-27,2010-12-21
-4y3x,2016-02-17,2015-02-10
-1y3p,2005-04-12,2004-11-26
-5y32,2017-08-16,2017-07-27
-7y3o,2023-12-27,2022-06-11
-6y3c,2020-02-26,2020-02-18
-5y3r,2017-09-06,2017-07-29
-1y30,2005-08-30,2004-11-23
-1y3x,2005-12-06,2004-11-26
-1y3t,2005-01-18,2004-11-26
-1y31,2004-12-07,2004-11-23
-4y33,2015-10-07,2015-02-10
-4y39,2016-02-17,2015-02-10
-2y33,2010-12-29,2010-12-18
-1y35,2004-12-07,2004-11-23
-6ff5,2018-03-21,2018-01-03
-1ff0,2001-06-01,2000-07-24
-6ff4,2018-08-29,2018-01-03
-2ffa,2006-08-08,2005-12-19
-2ffr,2006-06-20,2005-12-20
-4ffn,2012-09-19,2012-06-01
-3ff5,2008-12-30,2008-12-01
-3ffa,2009-10-06,2008-12-02
-6ff9,2018-04-25,2018-01-04
-2ff6,2006-03-21,2005-12-19
-3ffu,2009-03-24,2008-12-04
-1ffo,2002-12-11,2000-07-25
-4ff4,2012-12-12,2012-05-31
-8ff0,2023-07-05,2022-12-07
-4ffw,2012-12-12,2012-06-01
-5ff0,2016-04-06,2015-12-17
-8ffi,2023-08-23,2022-12-08
-6ffz,2018-02-14,2018-01-09
-3ffw,2009-09-22,2008-12-04
-4ff2,2012-12-12,2012-05-30
-8ffw,2023-11-01,2022-12-10
-3ff3,2009-08-25,2008-12-01
-4ffd,2013-02-13,2012-05-31
-1ffp,2002-12-11,2000-07-25
-8fft,2023-04-12,2022-12-10
-6ffb,2019-01-30,2018-01-05
-2ffb,2006-08-08,2005-12-19
-4ff6,2012-07-04,2012-05-31
-2ffu,2006-01-31,2005-12-20
-7ffp,2021-09-08,2021-07-23
-1ff5,2000-08-23,2000-07-25
-8ffo,2023-11-01,2022-12-09
-6ffx,2018-02-14,2018-01-09
-2ffy,2006-03-28,2005-12-20
-4ffk,2012-06-27,2012-06-01
-4ff3,2012-12-12,2012-05-30
-5ffe,2016-09-07,2015-12-18
-4ffi,2012-07-18,2012-06-01
-4ffs,2012-09-26,2012-06-01
-6fft,2019-01-02,2018-01-09
-5ffo,2017-01-25,2015-12-18
-8ffv,2023-11-01,2022-12-10
-5ffl,2016-08-31,2015-12-18
-6fff,2019-01-30,2018-01-07
-7fft,2021-09-15,2021-07-23
-6ff7,2019-03-13,2018-01-03
-3ffi,2009-12-15,2008-12-03
-4ffl,2012-09-19,2012-06-01
-8ffc,2023-03-08,2022-12-08
-3ffg,2009-12-08,2008-12-03
-7ff8,2022-07-27,2021-07-22
-8ff7,2023-02-01,2022-12-07
-7ffn,2021-10-20,2021-07-23
-8ffe,2023-03-08,2022-12-08
-2ffz,2006-03-28,2005-12-20
-4ff9,2013-09-04,2012-05-31
-2ffl,2006-01-24,2005-12-19
-1ff1,2000-11-01,2000-07-24
-6ffm,2018-11-14,2018-01-08
-6ffy,2018-08-01,2018-01-09
-7ffu,2022-06-22,2021-07-23
-6ff8,2019-01-30,2018-01-04
-2ff5,2006-12-19,2005-12-19
-1ffu,2000-09-15,2000-07-26
-7ffl,2021-10-20,2021-07-23
-6ffd,2019-01-30,2018-01-06
-4ff7,2012-08-22,2012-05-31
-5ff2,2016-04-06,2015-12-17
-7ffw,2021-09-15,2021-07-23
-8ffb,2023-03-08,2022-12-08
-5ffs,2016-07-06,2015-12-18
-5ffv,2015-12-30,2015-12-19
-2ffh,1999-07-16,1999-06-29
-2ff1,2006-05-23,2005-12-18
-5ffy,2015-12-30,2015-12-19
-5ff7,2017-02-15,2015-12-18
-1ffw,2001-01-17,2000-07-26
-5ffn,2016-05-18,2015-12-18
-2ffq,2006-07-04,2005-12-20
-5ff5,2016-04-27,2015-12-17
-1ffv,2000-09-15,2000-07-26
-3ffb,2009-10-06,2008-12-02
-1ffm,1999-06-16,1999-02-19
-2ffw,2006-05-09,2005-12-20
-6ffn,2018-02-21,2018-01-08
-8ff8,2023-06-07,2022-12-08
-8ff4,2023-08-09,2022-12-07
-1fft,2000-10-18,2000-07-26
-6ffe,2019-01-30,2018-01-07
-8ffu,2023-04-12,2022-12-10
-5ffg,2017-01-25,2015-12-18
-8ffn,2024-02-07,2022-12-09
-3ffx,2009-09-22,2008-12-04
-2ffx,2006-07-11,2005-12-20
-8ffz,2023-06-21,2022-12-11
-7ff7,2022-11-16,2021-07-22
-1ffq,2003-02-11,2000-07-26
-5ff6,2016-10-26,2015-12-17
-3ffo,2009-12-22,2008-12-04
-1ffy,2000-08-07,2000-07-26
-1fff,2001-06-01,2000-07-25
-4fft,2012-08-22,2012-06-01
-2ff0,2006-04-11,2005-12-17
-1ffx,2000-09-27,2000-07-26
-8ffd,2023-03-08,2022-12-08
-5fff,2016-06-08,2015-12-18
-7fff,2021-10-20,2021-07-23
-6ffg,2019-01-30,2018-01-07
-1ffg,2001-01-17,2000-07-25
-3ffc,2009-01-27,2008-12-03
-7ffx,2022-07-27,2021-07-24
-5ff3,2016-04-06,2015-12-17
-5ffh,2016-12-21,2015-12-18
-4ff8,2013-03-13,2012-05-31
-2ffv,2006-01-31,2005-12-20
-3ffk,2009-10-06,2008-12-03
-4ffb,2012-08-15,2012-05-31
-2ff2,2006-05-23,2005-12-18
-1ffr,2001-09-26,2000-07-26
-2ffd,2006-07-04,2005-12-19
-6ffi,2018-03-07,2018-01-08
-8ffy,2023-08-23,2022-12-11
-6ff1,2019-01-30,2018-01-03
-6ffl,2018-01-24,2018-01-08
-6ffc,2018-04-11,2018-01-06
-5ffz,2016-12-21,2015-12-19
-1ffi,2001-06-01,2000-07-25
-5ff4,2016-04-06,2015-12-17
-2fff,2006-06-20,2005-12-19
-5ffd,2016-09-07,2015-12-18
-3ffp,2009-08-18,2008-12-04
-3ffz,2008-12-16,2008-12-04
-4ffr,2012-09-19,2012-06-01
-1ffn,2002-12-11,2000-07-25
-8ffs,2023-04-05,2022-12-09
-6ffw,2019-03-13,2018-01-09
-3fft,2009-09-22,2008-12-04
-3ff8,2009-07-28,2008-12-02
-5ffc,2016-09-07,2015-12-18
-1ff7,1999-06-16,1999-02-19
-6ffh,2018-03-07,2018-01-08
-3ff1,2009-02-03,2008-12-01
-6ff2,2019-01-30,2018-01-03
-1ffh,1997-12-31,1996-12-30
-8ff9,2023-03-08,2022-12-08
-7ff9,2022-07-27,2021-07-23
-8ff6,2023-02-01,2022-12-07
-7ffm,2022-06-22,2021-07-23
-6ffs,2018-02-21,2018-01-09
-7ff6,2022-07-27,2021-07-22
-4ffp,2012-09-19,2012-06-01
-8ffx,2023-04-26,2022-12-10
-4ffg,2012-07-18,2012-06-01
-5fft,2016-07-06,2015-12-18
-6ffk,2018-11-28,2018-01-08
-2ff7,2006-08-08,2005-12-19
-5ff9,2016-06-08,2015-12-18
-8ffm,2024-02-07,2022-12-09
-4ffh,2012-07-18,2012-06-01
-2ffn,2006-12-05,2005-12-20
-4ffm,2012-09-19,2012-06-01
-5ffr,2016-07-06,2015-12-18
-3ff6,2009-05-19,2008-12-02
-2ffc,2006-01-17,2005-12-19
-1ffs,2001-01-17,2000-07-26
-2ff3,2006-03-21,2005-12-19
-7ff0,2022-07-27,2021-07-22
-5ff1,2016-01-13,2015-12-17
-4ffo,2012-09-19,2012-06-01
-8ffq,2024-02-07,2022-12-09
-2ff4,2006-01-24,2005-12-19
-3ffr,2008-12-23,2008-12-04
-6mqi,2019-01-09,2018-10-09
-4mq9,2014-05-07,2013-09-16
-4mqi,2013-10-02,2013-09-16
-6mqd,2019-03-20,2018-10-09
-1mq6,2003-01-28,2002-09-13
-6mqk,2019-11-20,2018-10-10
-7mql,2022-07-06,2021-05-05
-1mql,2003-08-26,2002-09-16
-6mqf,2019-03-20,2018-10-09
-2mqq,2015-12-23,2014-06-24
-3mqs,2010-08-25,2010-04-28
-7mqo,2022-03-16,2021-05-06
-1mqq,2003-09-17,2002-09-17
-7mqc,2021-09-15,2021-05-05
-7mqi,2021-09-15,2021-05-05
-5mq6,2017-01-11,2016-12-20
-5mqt,2017-11-22,2016-12-20
-7mqt,2022-04-20,2021-05-06
-3mqh,2010-05-12,2010-04-28
-2mqp,2015-12-23,2014-06-24
-3mq6,2010-11-10,2010-04-27
-2mq1,2014-08-06,2014-06-11
-4mqr,2014-03-05,2013-09-16
-3mqo,2010-06-23,2010-04-28
-1mqm,2003-08-26,2002-09-16
-6mqb,2019-10-16,2018-10-09
-6mqv,2019-09-11,2018-10-10
-7mqx,2021-08-11,2021-05-06
-3mq3,2011-05-18,2010-04-27
-1mqf,2002-10-02,2002-09-16
-3mq4,2010-06-09,2010-04-27
-6mqr,2019-07-31,2018-10-10
-6mq1,2018-10-17,2018-10-09
-7mqk,2022-07-06,2021-05-05
-4mqa,2015-03-18,2013-09-16
-4mq5,2014-08-27,2013-09-15
-7mqr,2022-03-16,2021-05-06
-5mqj,2017-11-22,2016-12-20
-7mqv,2021-05-19,2021-05-06
-7mq7,2021-09-08,2021-05-05
-4mqq,2014-03-05,2013-09-16
-7mqh,2021-09-15,2021-05-05
-3mqq,2010-06-23,2010-04-28
-4mqf,2013-12-11,2013-09-16
-6mql,2019-11-20,2018-10-10
-1mqn,2003-08-26,2002-09-16
-4mq7,2013-12-18,2013-09-15
-5mqm,2017-03-22,2016-12-20
-1mqw,2003-08-05,2002-09-17
-5mqv,2017-04-05,2016-12-20
-6mqw,2019-01-09,2018-10-11
-7mqq,2022-02-16,2021-05-06
-6mq6,2018-11-07,2018-10-09
-1mqd,2003-07-01,2002-09-16
-5mqp,2017-04-05,2016-12-20
-1mq9,2003-01-14,2002-09-15
-7mqe,2021-09-15,2021-05-05
-2mqo,2015-12-23,2014-06-24
-4mq1,2013-12-11,2013-09-15
-7mqu,2022-05-11,2021-05-06
-6mqx,2019-01-09,2018-10-11
-6mqy,2019-01-09,2018-10-11
-1mq5,2003-01-28,2002-09-13
-5mqy,2017-03-22,2016-12-21
-4mqe,2013-12-11,2013-09-16
-3mqe,2010-10-27,2010-04-28
-6mq9,2019-11-20,2018-10-09
-4mqc,2013-10-02,2013-09-16
-5mq4,2017-01-25,2016-12-20
-4mqk,2013-10-30,2013-09-16
-4mqp,2014-03-05,2013-09-16
-4mq4,2014-10-15,2013-09-15
-7mqp,2022-05-11,2021-05-06
-1mq2,2003-01-28,2002-09-13
-2mqv,2014-09-17,2014-06-27
-5mqx,2018-07-04,2016-12-21
-4mq6,2014-08-27,2013-09-15
-6mqc,2019-07-31,2018-10-09
-7mq3,2022-03-09,2021-05-05
-6mqs,2019-07-31,2018-10-10
-3mq7,2010-10-27,2010-04-27
-4mqt,2013-11-27,2013-09-16
-5mqg,2017-04-19,2016-12-20
-5mq1,2018-01-17,2016-12-19
-5mqn,2017-03-22,2016-12-20
-6mqq,2019-10-16,2018-10-10
-3mqt,2010-05-12,2010-04-28
-3mqy,2010-11-24,2010-04-28
-6mqt,2020-04-15,2018-10-10
-7mq9,2021-09-22,2021-05-05
-5mqr,2017-03-22,2016-12-20
-4mqs,2013-11-27,2013-09-16
-4mqh,2013-10-02,2013-09-16
-3mqg,2010-05-12,2010-04-28
-3mqi,2010-05-26,2010-04-28
-7mqg,2021-09-15,2021-05-05
-6mqz,2019-01-09,2018-10-11
-4mq0,2014-12-17,2013-09-14
-5mql,2017-11-22,2016-12-20
-4mqw,2014-04-09,2013-09-16
-1mqe,2003-08-05,2002-09-16
-7mq8,2021-09-22,2021-05-05
-1mqg,2003-08-05,2002-09-16
-1mqh,2003-08-05,2002-09-16
-5mq0,2017-01-18,2016-12-19
-4mqj,2013-10-02,2013-09-16
-1mqb,2003-09-16,2002-09-16
-6mqm,2019-07-31,2018-10-10
-6mq3,2019-04-03,2018-10-09
-1mq0,2003-11-04,2002-09-13
-4mqy,2013-10-23,2013-09-17
-6mq8,2019-10-23,2018-10-09
-3mq2,2010-12-08,2010-04-27
-1mq4,2003-09-16,2002-09-13
-7mqd,2021-09-15,2021-05-05
-3mql,2010-08-25,2010-04-28
-6mqn,2019-07-31,2018-10-10
-5mqe,2017-04-19,2016-12-20
-6mqj,2019-01-09,2018-10-09
-1mqv,2002-11-20,2002-09-17
-3mqf,2011-01-05,2010-04-28
-4mqu,2014-05-07,2013-09-16
-5mq5,2017-11-15,2016-12-20
-7mqm,2022-07-06,2021-05-05
-5mqk,2017-04-19,2016-12-20
-5mqs,2017-03-22,2016-12-20
-3mqk,2010-12-29,2010-04-28
-6mqe,2019-07-31,2018-10-09
-4mq2,2013-12-11,2013-09-15
-7mqj,2021-09-22,2021-05-05
-6mqg,2019-07-31,2018-10-09
-1mq8,2003-01-14,2002-09-15
-3mqd,2010-06-09,2010-04-28
-7mq6,2021-09-08,2021-05-05
-1mq3,2003-01-28,2002-09-13
-7mqa,2021-09-22,2021-05-05
-5mqw,2017-06-21,2016-12-21
-3mqr,2010-08-25,2010-04-28
-7mqb,2021-09-15,2021-05-05
-1mqo,2004-05-18,2002-09-17
-7mqf,2021-09-15,2021-05-05
-6mq0,2018-10-17,2018-10-09
-4mqg,2013-10-02,2013-09-16
-1mqi,2003-08-05,2002-09-16
-1mqj,2003-08-05,2002-09-16
-3qdy,2011-02-23,2011-01-19
-1qd2,2000-04-24,1999-07-09
-3qdl,2012-01-18,2011-01-18
-2qdg,2007-08-21,2007-06-20
-7qdt,2022-01-26,2021-11-30
-1qdb,1999-08-18,1999-05-19
-5qdc,2020-06-03,2017-12-01
-1qd1,2000-01-12,1999-07-08
-5qdf,2018-10-10,2018-08-30
-4qdh,2014-06-11,2014-05-13
-4qde,2015-05-13,2014-05-13
-6qd4,2019-04-24,2018-12-31
-6qdi,2019-06-12,2019-01-01
-4qdw,2014-09-03,2014-05-14
-5qdl,2018-10-10,2018-08-30
-5qdk,2018-10-10,2018-08-30
-3qdh,2011-08-24,2011-01-18
-6qdt,2020-01-29,2019-01-02
-8qd2,2024-03-13,2023-08-28
-1qd8,1999-08-16,1999-07-15
-8qdy,2024-03-20,2023-08-30
-3qd4,2011-03-09,2011-01-17
-5qdz,2018-10-10,2018-08-30
-6qdd,2020-05-06,2019-01-01
-6qdh,2020-05-06,2019-01-01
-4qd3,2014-06-25,2014-05-13
-5qdd,2020-06-03,2017-12-01
-4qdm,2015-05-20,2014-05-14
-2qd6,2008-04-22,2007-06-20
-2qd1,2007-10-30,2007-06-20
-3qdg,2011-07-06,2011-01-18
-6qdg,2020-05-06,2019-01-01
-4qd9,2015-05-13,2014-05-13
-2qde,2007-07-03,2007-06-20
-8qd3,2024-03-13,2023-08-28
-5qdy,2018-10-10,2018-08-30
-5qdh,2018-10-10,2018-08-30
-3qdc,2011-09-14,2011-01-18
-5qdo,2018-10-10,2018-08-30
-3qd9,2012-05-30,2011-01-18
-1qds,2000-12-13,1999-07-10
-3qdd,2012-07-18,2011-01-18
-1qdt,2000-01-24,1999-07-10
-7qd2,2022-07-06,2021-11-26
-4qdp,2014-09-03,2014-05-14
-7qdn,2022-03-30,2021-11-27
-8qdz,2024-03-20,2023-08-30
-5qdx,2018-10-10,2018-08-30
-7qdz,2022-02-09,2021-12-01
-3qdk,2011-02-09,2011-01-18
-1qd6,1999-10-25,1999-07-09
-3qd3,2011-03-09,2011-01-17
-3qdq,2011-08-24,2011-01-19
-4qdj,2014-08-06,2014-05-14
-4qdc,2014-07-30,2014-05-13
-3qdf,2011-02-02,2011-01-18
-5qd3,2020-06-03,2017-12-01
-5qdr,2018-10-10,2018-08-30
-7qdp,2022-12-14,2021-11-27
-6qdz,2020-01-29,2019-01-03
-2qd5,2007-10-30,2007-06-20
-6qdx,2019-03-27,2019-01-03
-6qdc,2020-05-06,2019-01-01
-2qdt,2007-08-28,2007-06-21
-6qd1,2019-04-24,2018-12-31
-6qdj,2019-10-30,2019-01-02
-5qdm,2018-10-10,2018-08-30
-1qdc,1999-10-14,1998-07-14
-4qdi,2015-04-01,2014-05-13
-1qdo,1999-10-14,1999-05-24
-3qdt,2011-02-23,2011-01-19
-6qdb,2020-05-06,2019-01-01
-2qd2,2007-10-30,2007-06-20
-5qdq,2018-10-10,2018-08-30
-7qdx,2023-06-14,2021-11-30
-4qd2,2014-06-25,2014-05-13
-6qdf,2020-05-06,2019-01-01
-3qdv,2011-02-23,2011-01-19
-1qdd,1999-05-28,1999-05-20
-3qdj,2011-07-06,2011-01-18
-5qdu,2018-10-10,2018-08-30
-6qd8,2019-10-02,2019-01-01
-2qd9,2007-08-21,2007-06-20
-1qd9,1999-11-26,1999-07-09
-5qdj,2018-10-10,2018-08-30
-4qd6,2015-01-14,2014-05-13
-2qdh,2007-08-21,2007-06-20
-3qdu,2011-02-23,2011-01-19
-2qdf,2007-09-04,2007-06-20
-7qdk,2022-04-27,2021-11-27
-6qd0,2019-04-24,2018-12-31
-2qd4,2007-10-30,2007-06-20
-6qd5,2019-01-09,2018-12-31
-7qdl,2022-12-14,2021-11-27
-5qd0,2020-06-03,2017-12-01
-6qdy,2019-11-13,2019-01-03
-2qdv,2007-12-11,2007-06-21
-5qda,2020-06-03,2017-12-01
-5qd2,2020-06-03,2017-12-01
-2qdy,2008-05-13,2007-06-22
-5qd7,2020-06-03,2017-12-01
-3qdw,2011-02-23,2011-01-19
-2qd7,2008-04-22,2007-06-20
-8qd5,2024-03-13,2023-08-28
-6qd3,2019-04-24,2018-12-31
-5qdi,2018-10-10,2018-08-30
-7qdg,2022-05-25,2021-11-27
-4qdv,2015-05-20,2014-05-14
-7qdh,2022-05-25,2021-11-27
-3qdx,2011-02-23,2011-01-19
-5qd4,2020-06-03,2017-12-01
-7qdq,2022-10-05,2021-11-29
-2qd8,2008-04-22,2007-06-20
-4qdd,2014-07-30,2014-05-13
-5qds,2018-10-10,2018-08-30
-4qdg,2014-06-11,2014-05-13
-1qdq,2000-07-10,1999-07-10
-5qdb,2020-06-03,2017-12-01
-5qdg,2018-10-10,2018-08-30
-7qdy,2022-02-09,2021-12-01
-7qd3,2022-12-14,2021-11-26
-1qdu,2000-07-10,1999-07-10
-3qdz,2011-06-29,2011-01-19
-6qda,2020-05-06,2019-01-01
-6qds,2020-01-29,2019-01-02
-2qds,2007-07-17,2007-06-21
-7qdd,2022-10-26,2021-11-26
-5qdw,2018-10-10,2018-08-30
-2qdx,2007-10-30,2007-06-21
-5qd9,2020-06-03,2017-12-01
-5qd1,2020-06-03,2017-12-01
-5qd8,2020-06-03,2017-12-01
-2qd3,2007-10-30,2007-06-20
-5qdt,2018-10-10,2018-08-30
-7qd0,2022-07-06,2021-11-25
-6qd2,2019-04-24,2018-12-31
-4qdk,2014-08-06,2014-05-14
-6qdr,2020-01-29,2019-01-02
-5qd5,2020-06-03,2017-12-01
-3qd0,2011-03-09,2011-01-17
-8qd9,2024-03-13,2023-08-28
-6qde,2020-05-06,2019-01-01
-2qdw,2007-12-11,2007-06-21
-6qd9,2020-05-06,2019-01-01
-5qd6,2020-06-03,2017-12-01
-8qd6,2024-03-13,2023-08-28
-3qd6,2011-02-02,2011-01-18
-6qd7,2019-10-02,2019-01-01
-8qd8,2024-03-13,2023-08-28
-7qd1,2022-07-06,2021-11-26
-6qdu,2020-01-29,2019-01-02
-1qdr,2000-01-24,1999-07-10
-1qd0,2000-07-19,1999-07-08
-5qdp,2018-10-10,2018-08-30
-4qdf,2014-07-30,2014-05-13
-6qdv,2019-02-20,2019-01-03
-4qd8,2015-05-13,2014-05-13
-5qde,2018-10-10,2018-08-30
-5qdv,2018-10-10,2018-08-30
-5qdn,2018-10-10,2018-08-30
-3qdn,2011-02-09,2011-01-18
-1tbh,2005-08-16,2004-05-20
-5tba,2017-01-11,2016-09-11
-8tbu,2023-12-27,2023-06-29
-7tbk,2022-06-15,2021-12-22
-5tbs,2017-10-11,2016-09-13
-5tb1,2016-10-12,2016-09-10
-7tb2,2022-06-22,2021-12-21
-8tb2,2024-05-08,2023-06-28
-5tbx,2017-04-12,2016-09-13
-6tbc,2020-04-01,2019-11-01
-1tbj,2005-08-16,2004-05-20
-3tba,2012-04-04,2011-08-05
-5tbt,2017-10-11,2016-09-13
-5tbu,2017-10-11,2016-09-13
-5tb7,2017-02-01,2016-09-11
-6tb0,2020-07-15,2019-10-31
-3tb6,2012-01-25,2011-08-05
-3tb4,2012-08-29,2011-08-05
-3tbj,2012-08-22,2011-08-07
-3tbb,2012-08-29,2011-08-05
-6tbe,2020-11-18,2019-11-01
-6tbh,2020-08-19,2019-11-01
-1tbt,2005-01-25,2004-05-20
-5tbm,2016-09-21,2016-09-12
-6tb1,2020-07-15,2019-10-31
-1tbb,2004-08-03,2004-05-19
-1tbw,2004-08-24,2004-05-20
-5tb0,2016-10-12,2016-09-10
-3tbv,2012-08-08,2011-08-08
-7tb8,2022-03-30,2021-12-21
-3tbs,2012-08-08,2011-08-08
-8tbj,2024-02-07,2023-06-28
-7tb0,2022-12-28,2021-12-21
-7tba,2022-10-19,2021-12-21
-8tbw,2024-01-10,2023-06-29
-7tbe,2022-05-04,2021-12-21
-5tbn,2016-10-12,2016-09-12
-7tbz,2022-01-26,2021-12-22
-8tb6,2023-10-18,2023-06-28
-3tby,2012-08-08,2011-08-08
-1tb3,2005-02-01,2004-05-19
-6tbo,2020-08-19,2019-11-02
-6tbq,2020-03-18,2019-11-04
-3tbt,2012-08-08,2011-08-08
-2tbv,1984-07-20,1984-06-22
-1tbz,1998-05-27,1998-02-05
-5tb6,2016-10-12,2016-09-11
-7tbd,2022-05-04,2021-12-21
-6tb9,2020-07-22,2019-11-01
-5tb4,2016-10-12,2016-09-11
-1tbf,2004-08-03,2004-05-20
-6tbj,2020-08-19,2019-11-01
-3tbc,2012-08-29,2011-08-05
-3tbk,2011-10-26,2011-08-07
-5tb2,2016-10-12,2016-09-11
-7tbc,2022-05-04,2021-12-21
-8tbt,2023-12-27,2023-06-29
-7tbm,2022-06-15,2021-12-22
-1tbn,1998-04-29,1997-04-15
-7tbg,2022-02-02,2021-12-22
-6tbg,2020-08-19,2019-11-01
-6tb5,2020-11-18,2019-10-31
-5tbo,2016-09-28,2016-09-12
-1tb0,2005-01-25,2004-05-19
-5tbv,2017-10-11,2016-09-13
-8tbq,2024-03-20,2023-06-29
-7tb4,2022-01-12,2021-12-21
-8tbm,2024-02-07,2023-06-28
-7tbj,2022-06-22,2021-12-22
-6tbl,2020-07-29,2019-11-01
-7tbr,2023-01-25,2021-12-22
-5tb3,2016-10-12,2016-09-11
-7tbw,2022-01-26,2021-12-22
-8tbl,2024-02-07,2023-06-28
-6tbt,2021-10-13,2019-11-04
-2tbs,1994-04-30,1994-01-14
-8tbp,2024-02-21,2023-06-29
-1tb5,2004-08-03,2004-05-19
-8tbx,2023-07-26,2023-06-29
-7tbf,2022-03-30,2021-12-21
-6tbn,2020-07-29,2019-11-01
-8tbg,2024-02-07,2023-06-28
-8tbv,2024-01-17,2023-06-29
-8tbn,2024-02-07,2023-06-28
-8tbe,2023-08-09,2023-06-28
-7tbu,2022-03-16,2021-12-22
-7tb1,2022-07-27,2021-12-21
-6tbb,2020-04-01,2019-11-01
-6tby,2020-05-06,2019-11-04
-5tbb,2017-01-11,2016-09-11
-8tb5,2023-10-18,2023-06-28
-5tbp,2017-08-09,2016-09-12
-5tbj,2017-09-20,2016-09-12
-5tbw,2017-07-26,2016-09-13
-6tbp,2020-08-19,2019-11-03
-8tb7,2023-10-04,2023-06-28
-1tbo,1998-04-29,1997-04-15
-7tbl,2022-06-22,2021-12-22
-8tbi,2024-02-07,2023-06-28
-5tb9,2017-01-11,2016-09-11
-6tbu,2020-06-03,2019-11-04
-3tb3,2012-02-22,2011-08-05
-6tbz,2019-11-20,2019-11-04
-5tb5,2016-11-02,2016-09-11
-5tbi,2017-09-20,2016-09-12
-3tbh,2012-08-01,2011-08-06
-5tbh,2017-09-20,2016-09-12
-6tbw,2020-11-18,2019-11-04
-6tb3,2020-04-22,2019-10-31
-8tbs,2023-12-27,2023-06-29
-5tb8,2017-01-11,2016-09-11
-3tbw,2012-08-08,2011-08-08
-7tbb,2022-05-04,2021-12-21
-3tbd,2011-11-02,2011-08-05
-1tb6,2004-08-17,2004-05-19
-6tbr,2020-03-18,2019-11-04
-7tbv,2022-03-16,2021-12-22
-6tbk,2020-08-19,2019-11-01
-5tbc,2017-01-11,2016-09-11
-6tb2,2019-12-18,2019-10-31
-8tbk,2024-02-07,2023-06-28
-6tbx,2020-06-03,2019-11-04
-3tbg,2012-08-08,2011-08-05
-6tb8,2020-04-08,2019-11-01
-5tbe,2017-04-19,2016-09-12
-1tb7,2004-08-03,2004-05-19
-7tbq,2023-07-05,2021-12-22
-3tb9,2012-04-04,2011-08-05
-3tb0,2012-10-17,2011-08-04
-8tbf,2024-02-07,2023-06-28
-7tby,2022-01-26,2021-12-22
-1tbl,2005-08-16,2004-05-20
-6tbi,2020-08-19,2019-11-01
-6tbf,2020-08-19,2019-11-01
-3tbe,2011-10-26,2011-08-05
-8tbh,2024-02-07,2023-06-28
-7tbi,2022-06-15,2021-12-22
-5rh9,2020-05-27,2020-05-15
-4rhg,2015-03-11,2014-10-02
-6rh0,2020-02-19,2019-04-18
-6rh9,2019-07-17,2019-04-19
-1rhr,2004-05-11,2003-11-14
-1rhl,1998-10-14,1998-10-09
-2rhr,2008-08-19,2007-10-09
-2rhi,2007-12-11,2007-10-09
-2rh6,2007-10-30,2007-10-06
-7rhg,2021-11-03,2021-07-17
-3rht,2011-04-27,2011-04-12
-1rhy,2004-05-04,2003-11-14
-6rhv,2019-12-18,2019-04-23
-5rhj,2020-06-10,2020-05-25
-5rhm,2020-06-10,2020-05-25
-1rhj,2004-05-11,2003-11-14
-1rhc,2004-03-30,2003-11-14
-5rh8,2020-05-27,2020-05-15
-6rhx,2019-05-01,2019-04-23
-4rhz,2015-10-28,2014-10-03
-7rhv,2022-03-16,2021-07-19
-5rh2,2020-05-27,2020-05-15
-2rhd,2007-10-23,2007-10-09
-5rhg,2020-06-10,2020-05-25
-7rh1,2022-07-13,2021-07-16
-5rh4,2020-05-27,2020-05-15
-6rh4,2020-04-15,2019-04-18
-8rhq,2024-05-15,2023-12-16
-5rhp,2020-06-10,2020-05-25
-5rhw,2020-06-10,2020-05-25
-2rhy,2007-12-11,2007-10-09
-5rhb,2020-06-10,2020-05-16
-6rhs,2020-02-12,2019-04-22
-3rhr,2011-04-27,2011-04-12
-5rhh,2020-06-10,2020-05-25
-2rh4,2008-08-19,2007-10-05
-5rht,2020-06-10,2020-05-25
-5rh6,2020-05-27,2020-05-15
-4rhu,2015-05-20,2014-10-03
-3rhx,2011-05-04,2011-04-12
-4rhl,2014-12-31,2014-10-02
-4rh2,2015-11-11,2014-10-01
-6rhk,2020-05-13,2019-04-22
-7rh0,2022-07-13,2021-07-16
-6rhu,2019-05-01,2019-04-22
-8rhf,2024-04-17,2023-12-15
-5rhr,2020-06-10,2020-05-25
-6rhz,2020-02-19,2019-04-23
-5rhf,2020-06-10,2020-05-16
-8rhi,2024-04-17,2023-12-15
-7rhh,2021-11-03,2021-07-17
-4rhh,2015-10-14,2014-10-02
-2rht,2007-11-13,2007-10-09
-5rhi,2020-06-10,2020-05-25
-4rhx,2015-05-20,2014-10-03
-7rh5,2021-08-04,2021-07-16
-4rh5,2015-03-11,2014-10-01
-4rh7,2014-12-10,2014-10-01
-7rhi,2021-11-03,2021-07-17
-3rhy,2011-06-15,2011-04-12
-4rhs,2014-10-29,2014-10-02
-3rhh,2011-05-18,2011-04-11
-7rh6,2021-08-04,2021-07-16
-3rhb,2011-06-01,2011-04-11
-6rhm,2019-08-21,2019-04-22
-1rh7,2004-06-08,2003-11-13
-5rhv,2020-06-10,2020-05-25
-5rhd,2020-06-10,2020-05-16
-1rhf,2004-03-23,2003-11-14
-1rhu,2004-05-11,2003-11-14
-7rh3,2022-07-13,2021-07-16
-7rhp,2022-11-09,2021-07-18
-6rh8,2020-02-19,2019-04-19
-6rhh,2019-05-01,2019-04-20
-6rhc,2020-06-17,2019-04-19
-7rh8,2021-07-28,2021-07-16
-2rhw,2007-11-13,2007-10-09
-3rhs,2012-04-11,2011-04-12
-7rh4,2022-07-13,2021-07-16
-1rhi,1997-03-12,1996-06-17
-5rh5,2020-05-27,2020-05-15
-6rh2,2020-02-19,2019-04-18
-8rhz,2024-04-17,2023-12-17
-7rhk,2021-11-03,2021-07-17
-7rhn,2022-07-27,2021-07-17
-6rhp,2019-05-01,2019-04-22
-2rhl,2008-10-21,2007-10-09
-5rhl,2020-06-10,2020-05-25
-5rhn,1997-06-16,1997-02-26
-8rhr,2024-04-17,2023-12-16
-6rhg,2019-05-15,2019-04-19
-5rhs,2020-06-10,2020-05-25
-7rh7,2021-08-04,2021-07-16
-5rh0,2020-05-27,2020-05-15
-6rhr,2019-05-01,2019-04-22
-3rhd,2011-05-18,2011-04-11
-3rhc,2011-06-01,2011-04-11
-4rh1,2014-10-22,2014-10-01
-6rhw,2019-12-18,2019-04-23
-3rha,2011-05-04,2011-04-11
-4rhe,2015-02-18,2014-10-02
-2rhu,2007-12-11,2007-10-09
-6rh1,2020-02-19,2019-04-18
-2rhx,2007-12-11,2007-10-09
-1rhm,2004-05-11,2003-11-14
-4rhn,1997-06-16,1997-02-26
-3rhj,2011-04-27,2011-04-11
-3rhn,1997-06-16,1997-02-11
-2rhj,2008-10-21,2007-10-09
-5rhk,2020-06-10,2020-05-25
-2rhc,2008-08-19,2007-10-08
-2rhg,2007-11-20,2007-10-09
-3rh4,2011-07-06,2011-04-11
-6rho,2019-05-01,2019-04-22
-1rhq,2004-05-11,2003-11-14
-4rht,2015-05-20,2014-10-03
-6rht,2020-02-12,2019-04-22
-6rhl,2019-08-21,2019-04-22
-3rh7,2011-06-08,2011-04-11
-6rhd,2020-03-25,2019-04-19
-5rhe,2020-06-10,2020-05-16
-2rhs,2007-11-06,2007-10-09
-4rh9,2015-03-11,2014-10-01
-4rhm,2014-12-31,2014-10-02
-4rh4,2015-01-14,2014-10-01
-6rhj,2020-05-13,2019-04-21
-3rhl,2011-04-27,2011-04-11
-5rha,2020-05-27,2020-05-15
-7rhj,2021-11-03,2021-07-17
-2rh1,2007-10-30,2007-10-05
-2rhk,2008-07-01,2007-10-09
-5rh3,2020-05-27,2020-05-15
-5rhx,2020-06-10,2020-05-25
-3rho,2011-04-27,2011-04-11
-5rhq,2020-06-10,2020-05-25
-1rh3,1997-03-12,1996-11-27
-3rhk,2011-04-27,2011-04-11
-3rhw,2011-05-25,2011-04-12
-7rhw,2022-03-16,2021-07-19
-1rhk,2004-05-11,2003-11-14
-3rh6,2011-07-06,2011-04-11
-7rhs,2022-03-02,2021-07-18
-1rh0,2004-03-02,2003-11-13
-5rho,2020-06-10,2020-05-25
-6rhq,2019-07-17,2019-04-22
-6rhe,2019-12-25,2019-04-19
-6rh3,2019-07-03,2019-04-18
-3rh5,2011-07-06,2011-04-11
-2rhp,2008-05-27,2007-10-09
-8rhe,2024-04-17,2023-12-15
-3rhg,2011-04-27,2011-04-11
-5rhu,2020-06-10,2020-05-25
-2rhq,2007-11-06,2007-10-09
-6rhf,2019-05-15,2019-04-19
-5rh7,2020-05-27,2020-05-15
-3rh8,2011-09-21,2011-04-11
-4rhy,2015-05-20,2014-10-03
-5rh1,2020-05-27,2020-05-15
-6rhb,2020-03-25,2019-04-19
-4rh0,2014-10-22,2014-10-01
-8rhl,2024-05-01,2023-12-15
-3rhq,2011-05-04,2011-04-12
-2rh9,2007-11-06,2007-10-08
-6rha,2020-03-25,2019-04-19
-4rh3,2015-06-24,2014-10-01
-2rho,2008-10-21,2007-10-09
-6rhi,2019-05-01,2019-04-20
-7rhq,2022-03-02,2021-07-18
-3rhz,2011-06-01,2011-04-12
-6rh7,2020-02-19,2019-04-18
-7rhr,2022-03-02,2021-07-18
-4rhb,2015-08-26,2014-10-01
-5rhc,2020-06-10,2020-05-16
-1lrh,2002-06-19,2002-05-15
-5lrg,2016-09-21,2016-08-19
-6lra,2020-08-26,2020-01-15
-4lr6,2013-08-07,2013-07-19
-1lrj,2002-07-26,2002-05-15
-7lrb,2022-02-23,2021-02-16
-4lr2,2013-12-18,2013-07-19
-5lr1,2017-08-23,2016-08-18
-5lrc,2017-06-14,2016-08-18
-2lri,2012-10-17,2012-04-03
-4lrg,2013-08-07,2013-07-19
-6lrk,2020-06-24,2020-01-16
-1lrn,2002-11-27,2002-05-15
-3lrs,2010-06-09,2010-02-11
-7lrn,2021-07-21,2021-02-16
-4lrm,2014-01-15,2013-07-20
-3lrf,2010-03-31,2010-02-11
-5lrs,2016-12-07,2016-08-19
-7lr7,2021-04-07,2021-02-16
-3lrt,2011-02-16,2010-02-11
-4lrz,2014-01-29,2013-07-21
-7lr6,2021-04-07,2021-02-16
-7lry,2022-02-23,2021-02-17
-7lrd,2021-06-09,2021-02-16
-5lrn,2016-12-07,2016-08-19
-3lrn,2010-06-02,2010-02-11
-2lrp,2013-02-06,2012-04-11
-6lru,2020-11-25,2020-01-16
-3lrq,2010-03-23,2010-02-11
-7lrt,2021-07-14,2021-02-17
-5lra,2017-05-03,2016-08-18
-4lr3,2014-04-30,2013-07-19
-7lra,2022-02-23,2021-02-16
-3lrk,2010-06-30,2010-02-11
-7lro,2022-08-10,2021-02-17
-4lrw,2013-11-27,2013-07-21
-7lrk,2022-08-10,2021-02-16
-1lro,2002-11-27,2002-05-15
-1lrl,2002-07-26,2002-05-15
-6lrj,2020-06-24,2020-01-16
-5lri,2016-11-09,2016-08-19
-3lre,2010-11-10,2010-02-11
-6lrb,2020-04-08,2020-01-15
-1lrw,2003-08-12,2002-05-16
-7lr5,2022-02-23,2021-02-15
-1lr5,2002-06-19,2002-05-14
-3lr1,2010-03-16,2010-02-10
-5lrf,2017-06-14,2016-08-18
-5lr0,2017-08-30,2016-08-18
-7lr2,2021-04-07,2021-02-15
-6lrc,2020-06-24,2020-01-15
-1lry,2002-07-24,2002-05-16
-5lrm,2016-12-07,2016-08-19
-5lrj,2016-09-21,2016-08-19
-5lrr,2016-12-07,2016-08-19
-1lrk,2002-07-26,2002-05-15
-5lr6,2016-08-31,2016-08-18
-1lrm,2002-06-12,2002-05-15
-7lrl,2021-08-25,2021-02-16
-4lrf,2013-07-31,2013-07-19
-4lr9,2013-07-31,2013-07-19
-7lrx,2022-02-23,2021-02-17
-6lrt,2021-07-28,2020-01-16
-3lrl,2010-06-30,2010-02-11
-6lrh,2020-04-01,2020-01-16
-1lri,2002-05-29,2002-05-15
-5lrt,2017-02-01,2016-08-19
-4lra,2013-07-31,2013-07-19
-1lrq,2002-11-27,2002-05-15
-5lrk,2016-09-21,2016-08-19
-4lr8,2013-07-31,2013-07-19
-4lrt,2013-09-04,2013-07-20
-6lrd,2020-08-26,2020-01-16
-5lr8,2017-05-03,2016-08-18
-6lr4,2021-01-27,2020-01-15
-1lrt,2003-07-07,2002-05-15
-6lrg,2020-04-01,2020-01-16
-3lr9,2010-07-07,2010-02-10
-5lre,2017-05-31,2016-08-18
-4lrs,2013-09-04,2013-07-20
-5lrl,2017-08-23,2016-08-19
-7lrv,2022-02-23,2021-02-17
-2lrr,2012-10-24,2012-04-12
-6lri,2020-06-24,2020-01-16
-4lr7,2013-07-31,2013-07-19
-2lro,2013-02-06,2012-04-11
-4lrc,2013-07-31,2013-07-19
-7lr0,2021-04-21,2021-02-15
-7lrs,2021-07-14,2021-02-17
-1lra,1994-01-31,1993-10-01
-3lr7,2010-07-07,2010-02-10
-7lrr,2022-02-23,2021-02-17
-3lrm,2010-06-30,2010-02-11
-5lr7,2017-08-23,2016-08-18
-3lr4,2010-06-16,2010-02-10
-6lrl,2020-06-24,2020-01-16
-4lrd,2013-07-31,2013-07-19
-1lr6,2002-09-04,2002-05-15
-4lrj,2014-01-22,2013-07-19
-7lr8,2021-04-07,2021-02-16
-4lre,2013-07-31,2013-07-19
-7lrc,2021-06-09,2021-02-16
-5lrd,2017-06-14,2016-08-18
-6lr9,2021-01-13,2020-01-15
-5lrz,2017-09-13,2016-08-22
-5lrq,2017-08-30,2016-08-19
-7lr9,2022-08-10,2021-02-16
-5lry,2017-09-13,2016-08-22
-6lrx,2020-11-25,2020-01-16
-4lrb,2013-07-31,2013-07-19
-5lrp,2017-07-05,2016-08-19
-6lr6,2020-03-25,2020-01-15
-4lro,2013-08-07,2013-07-20
-6lrz,2020-08-05,2020-01-16
-1lr0,2002-05-29,2002-05-14
-7lrm,2022-02-23,2021-02-16
-4lrr,2013-11-06,2013-07-20
-5lrb,2017-05-03,2016-08-18
-1lru,2002-07-24,2002-05-16
-6lr8,2020-05-13,2020-01-15
-6lre,2020-06-24,2020-01-16
-3lrr,2010-06-02,2010-02-11
-7lri,2022-02-23,2021-02-16
-7lre,2021-06-09,2021-02-16
-3lrp,2010-11-10,2010-02-11
-4lrl,2013-11-20,2013-07-19
-6lrm,2021-04-14,2020-01-16
-4lrh,2013-07-31,2013-07-19
-4y77,2015-06-17,2015-02-13
-6y71,2021-01-27,2020-02-27
-2y7q,2011-04-20,2011-02-01
-7y7h,2023-10-25,2022-06-22
-4y7e,2015-09-23,2015-02-14
-2y73,2011-06-15,2011-01-28
-4y7r,2015-04-15,2015-02-16
-7y7b,2023-04-12,2022-06-22
-7y7w,2023-04-26,2022-06-22
-2y7k,2011-07-20,2011-01-31
-5y7x,2018-08-01,2017-08-18
-5y7j,2019-03-20,2017-08-17
-2y7p,2011-07-20,2011-02-01
-5y7a,2017-12-27,2017-08-16
-7y70,2023-07-05,2022-06-21
-4y7u,2015-03-18,2015-02-16
-4y78,2015-06-17,2015-02-13
-6y78,2020-07-29,2020-02-28
-2y76,2011-08-17,2011-01-28
-2y7h,2011-02-09,2011-01-31
-4y70,2015-06-17,2015-02-13
-4y7x,2015-06-17,2015-02-16
-2y79,2011-02-16,2011-01-30
-5y7z,2018-08-29,2017-08-18
-1y7l,2005-04-26,2004-12-09
-4y7f,2015-07-15,2015-02-14
-1y7g,2004-12-14,2004-12-08
-5y7k,2019-03-20,2017-08-17
-7y7j,2023-02-22,2022-06-22
-5y7w,2017-11-15,2017-08-18
-2y7z,2011-03-16,2011-02-02
-2y7j,2011-02-09,2011-01-31
-1y7p,2005-02-01,2004-12-09
-6y7w,2020-03-11,2020-03-02
-4y7o,2015-08-05,2015-02-15
-5y7h,2019-03-20,2017-08-17
-6y7h,2021-03-31,2020-03-01
-1y7z,2004-12-21,2004-12-10
-1y77,2005-01-04,2004-12-08
-4y7v,2015-03-18,2015-02-16
-5y7r,2018-01-24,2017-08-17
-6y7u,2020-04-22,2020-03-02
-1y7o,2005-02-08,2004-12-09
-7y7o,2023-03-08,2022-06-22
-4y79,2015-09-30,2015-02-13
-5y7d,2018-08-22,2017-08-17
-4y75,2015-06-17,2015-02-13
-2y7f,2011-06-01,2011-01-31
-2y7d,2011-06-01,2011-01-31
-1y75,2005-05-03,2004-12-08
-5y7q,2018-03-14,2017-08-17
-5y7f,2017-09-27,2017-08-17
-6y76,2020-07-22,2020-02-28
-2y7w,2011-07-20,2011-02-02
-6y7r,2020-04-22,2020-03-02
-4y7y,2015-06-17,2015-02-16
-7y7s,2022-09-28,2022-06-22
-7y77,2023-07-12,2022-06-21
-4y74,2015-06-17,2015-02-13
-4y7a,2015-09-30,2015-02-13
-6y7x,2020-03-11,2020-03-02
-1y7i,2004-12-21,2004-12-08
-7y7c,2023-10-25,2022-06-22
-4y7n,2015-07-15,2015-02-15
-4y7s,2016-08-03,2015-02-16
-6y7j,2021-03-31,2020-03-01
-7y7v,2023-04-26,2022-06-22
-6y74,2020-08-05,2020-02-28
-6y77,2021-01-27,2020-02-28
-2y7i,2011-05-11,2011-01-31
-6y7l,2021-03-31,2020-03-01
-7y71,2023-08-02,2022-06-21
-6y7t,2021-03-31,2020-03-02
-2y7g,2011-06-01,2011-01-31
-7y7f,2023-10-25,2022-06-22
-4y7c,2016-02-24,2015-02-13
-4y7d,2015-02-25,2015-02-14
-6y7y,2020-03-11,2020-03-02
-6y7d,2021-01-27,2020-02-28
-5y7t,2018-01-24,2017-08-18
-2y7e,2011-06-01,2011-01-31
-5y7c,2018-07-18,2017-08-16
-2y77,2011-08-17,2011-01-28
-6y7m,2020-03-18,2020-03-01
-1y7b,2005-01-25,2004-12-08
-4y72,2015-08-12,2015-02-13
-7y7t,2022-09-28,2022-06-22
-7y7z,2023-04-26,2022-06-22
-2y74,2011-06-15,2011-01-28
-4y7w,2015-06-17,2015-02-16
-5y72,2018-07-18,2017-08-16
-1y7w,2005-05-03,2004-12-10
-6y75,2021-02-03,2020-02-28
-6y72,2021-01-27,2020-02-27
-1y7a,2005-06-21,2004-12-08
-4y76,2015-09-30,2015-02-13
-5y77,2017-12-27,2017-08-16
-1y7d,2004-12-14,2004-12-08
-5y7p,2018-08-22,2017-08-17
-6y7a,2021-03-31,2020-02-28
-8y7e,2024-03-13,2024-02-04
-1y7m,2005-03-01,2004-12-09
-2y7a,2012-02-15,2011-01-31
-1y7c,2004-12-14,2004-12-08
-6y79,2020-10-28,2020-02-28
-5y7g,2018-03-14,2017-08-17
-7y7l,2023-06-28,2022-06-22
-5y7n,2018-08-29,2017-08-17
-6y7b,2021-03-31,2020-02-28
-7y7u,2022-08-31,2022-06-22
-6y7g,2021-03-31,2020-02-29
-7y7d,2023-10-25,2022-06-22
-4y7b,2015-09-30,2015-02-13
-6y7z,2020-03-11,2020-03-02
-7y7p,2022-09-28,2022-06-22
-7y7r,2022-09-28,2022-06-22
-2y71,2011-08-17,2011-01-28
-2y7x,2011-03-16,2011-02-02
-4y71,2015-09-30,2015-02-13
-6y7e,2021-01-27,2020-02-28
-7y7g,2023-10-25,2022-06-22
-7y75,2022-11-30,2022-06-21
-7y76,2023-01-04,2022-06-21
-6y7v,2021-02-10,2020-03-02
-4y7l,2015-08-05,2015-02-15
-6y7k,2021-03-31,2020-03-01
-4y73,2015-05-20,2015-02-13
-7y74,2023-07-12,2022-06-21
-6y7f,2020-05-13,2020-02-28
-4y7g,2015-07-15,2015-02-14
-6y7i,2021-03-31,2020-03-01
-2y7l,2011-10-05,2011-01-31
-1y7t,2005-08-02,2004-12-10
-1y7v,2005-04-12,2004-12-10
-7y7y,2023-04-26,2022-06-22
-7y7q,2022-09-28,2022-06-22
-1y79,2005-05-24,2004-12-08
-1y7u,2005-01-25,2004-12-10
-7y7e,2023-10-25,2022-06-22
-3eaf,2008-09-09,2008-08-25
-3eat,2008-10-14,2008-08-26
-8eab,2023-05-03,2022-08-28
-4ea9,2012-04-04,2012-03-22
-5eas,1997-10-15,1997-06-19
-7ea9,2021-03-31,2021-03-06
-5eaa,2000-10-27,1998-12-29
-4eai,2012-06-06,2012-03-22
-2eau,2007-03-27,2007-02-02
-1ea1,2000-11-06,2000-11-02
-8ea9,2023-05-03,2022-08-28
-8ea1,2022-11-30,2022-08-27
-5ea9,2016-10-19,2015-10-15
-8ea8,2023-05-03,2022-08-28
-3eao,2008-12-02,2008-08-26
-6eac,2018-10-03,2018-08-02
-4eac,2013-03-27,2012-03-22
-2ea6,2007-07-31,2007-01-30
-6eav,2019-08-07,2018-08-03
-5eak,2016-02-17,2015-10-16
-2eax,2007-10-02,2007-02-03
-6ea1,2018-12-26,2018-08-02
-3ea5,2008-10-21,2008-08-24
-6ean,2019-08-07,2018-08-03
-2eab,2007-04-24,2007-01-31
-2ea4,2008-02-05,2007-01-30
-8eac,2023-01-18,2022-08-28
-5eac,2016-02-10,2015-10-16
-3eai,2008-10-07,2008-08-25
-6eai,2019-08-07,2018-08-03
-2eav,2007-09-18,2007-02-03
-1eah,1998-09-16,1997-07-22
-6ead,2019-08-07,2018-08-03
-8eaz,2023-01-18,2022-08-30
-4eal,2012-06-06,2012-03-22
-3ea2,2009-04-14,2008-08-24
-8ea7,2023-05-03,2022-08-28
-3ea0,2008-09-23,2008-08-24
-4ea7,2012-04-04,2012-03-22
-7eax,2022-02-16,2021-03-08
-2ea2,2008-02-05,2007-01-30
-1eak,2002-08-22,2001-07-12
-3eah,2008-10-07,2008-08-25
-6eau,2019-08-07,2018-08-03
-1eac,1993-10-31,1992-12-16
-7ean,2021-03-31,2021-03-07
-6ea2,2018-12-26,2018-08-02
-3ean,2008-12-02,2008-08-26
-3ea3,2009-04-14,2008-08-24
-6eaq,2018-11-07,2018-08-03
-5ea5,2015-12-09,2015-10-15
-6eat,2019-03-13,2018-08-03
-4ean,2012-06-13,2012-03-22
-7ea4,2022-01-26,2021-03-06
-6eak,2019-08-07,2018-08-03
-7eas,2021-08-04,2021-03-08
-5eaw,2015-11-18,2015-10-17
-2eat,2007-03-27,2007-02-02
-2eae,2007-04-24,2007-01-31
-1ear,2002-01-04,2001-07-16
-2eaq,2007-07-31,2007-01-31
-4eaq,2012-04-11,2012-03-22
-1eab,1993-10-31,1992-12-16
-5eab,2016-02-10,2015-10-16
-4ea0,2012-04-25,2012-03-21
-6eaa,2018-12-26,2018-08-02
-4eak,2012-06-06,2012-03-22
-3ea6,2009-06-30,2008-08-24
-2ea0,2008-02-26,2007-01-29
-4ea3,2012-04-25,2012-03-22
-5ean,2015-11-18,2015-10-16
-6eaw,2019-08-07,2018-08-03
-6eag,2019-08-07,2018-08-03
-5eag,2016-02-10,2015-10-16
-8ea4,2022-11-30,2022-08-27
-6eam,2019-08-07,2018-08-03
-7eaw,2022-03-16,2021-03-08
-5eae,2016-02-10,2015-10-16
-6ea9,2019-02-06,2018-08-02
-4eag,2012-06-06,2012-03-22
-2eal,2007-09-25,2007-01-31
-4ea8,2012-04-04,2012-03-22
-4eaj,2012-06-06,2012-03-22
-1eag,1996-12-23,1996-05-31
-4eaw,2013-03-27,2012-03-22
-5ea2,2016-02-10,2015-10-15
-2ea1,2008-01-22,2007-01-29
-1eau,1995-02-07,1994-11-22
-5eat,1997-11-12,1997-07-24
-1eas,1995-02-07,1994-11-22
-4ea2,2012-04-25,2012-03-21
-8ear,2022-11-23,2022-08-29
-6ea4,2019-12-18,2018-08-02
-5eah,2016-02-10,2015-10-16
-4eaa,2012-04-04,2012-03-22
-6eaf,2019-08-07,2018-08-03
-8ea5,2023-05-03,2022-08-28
-1eat,1995-02-07,1994-11-22
-3ea4,2009-03-31,2008-08-24
-8ead,2022-09-07,2022-08-29
-5eaf,2016-02-10,2015-10-16
-7ead,2022-03-09,2021-03-07
-5ear,2015-11-04,2015-10-16
-8eaa,2023-05-03,2022-08-28
-5eax,2015-11-18,2015-10-17
-7eat,2021-08-04,2021-03-08
-2eac,2007-04-24,2007-01-31
-7eaz,2021-06-23,2021-03-08
-4eab,2012-04-04,2012-03-22
-4eae,2012-04-04,2012-03-22
-6eax,2019-08-07,2018-08-03
-1eap,1994-12-20,1994-08-10
-4ea1,2012-04-25,2012-03-21
-2ea7,2008-02-05,2007-01-30
-3eax,2009-07-07,2008-08-26
-3eau,2008-09-23,2008-08-26
-7ea0,2021-08-04,2021-03-05
-5ea7,2015-12-09,2015-10-15
-2eak,2007-09-25,2007-01-31
-5eaj,2016-09-21,2015-10-16
-8eae,2023-10-25,2022-08-29
-7ea5,2021-07-14,2021-03-06
-8ea6,2023-05-03,2022-08-28
-4eay,2013-03-27,2012-03-23
-3ea1,2009-04-14,2008-08-24
-6ea3,2019-08-07,2018-08-02
-6ea8,2019-02-06,2018-08-02
-5ea6,2015-12-09,2015-10-15
-6eab,2018-12-26,2018-08-02
-7eam,2021-03-17,2021-03-07
-7ea8,2021-07-14,2021-03-06
-7ea1,2022-06-15,2021-03-05
-8ea0,2022-11-30,2022-08-27
-3ead,2009-09-08,2008-08-25
-6ea5,2018-09-19,2018-08-02
-5eau,1998-04-08,1997-12-11
-2ead,2007-04-24,2007-01-31
-5ea4,2015-12-09,2015-10-15
-6ea7,2018-09-19,2018-08-02
-1ea5,2000-11-08,2000-11-06
-1ea6,2001-11-23,2001-07-10
-8eaq,2022-11-23,2022-08-29
-1eae,1993-10-31,1992-12-16
-2ea5,2007-07-31,2007-01-30
-8ea3,2022-11-30,2022-08-27
-4ead,2013-03-27,2012-03-22
-5ead,2016-02-10,2015-10-16
-1ea7,2002-07-04,2001-07-10
-1ead,1993-10-31,1992-12-16
-4ear,2013-02-06,2012-03-22
-7eap,2022-03-16,2021-03-08
-5ea3,2015-12-09,2015-10-15
-2eaa,2008-02-05,2007-01-31
-7ea7,2021-12-22,2021-03-06
-6eay,2018-10-10,2018-08-03
-6eas,2018-08-22,2018-08-03
-5eai,2016-02-17,2015-10-16
-1eam,1999-06-14,1999-01-26
-6eah,2019-08-07,2018-08-03
-1ea0,2001-11-01,2000-11-02
-2ear,2007-03-27,2007-02-02
-4eah,2012-12-12,2012-03-22
-2wk3,2009-11-03,2009-06-05
-5wkb,2018-05-23,2017-07-24
-1wk9,2005-06-28,2004-05-30
-2wks,2009-11-24,2009-06-17
-6wk9,2020-10-28,2020-04-15
-3wkg,2013-12-25,2013-10-21
-6wkj,2020-08-26,2020-04-16
-1wkw,2005-06-10,2004-06-10
-3wk1,2013-12-04,2013-10-17
-5wkg,2017-11-01,2017-07-25
-8wkj,2023-12-06,2023-09-27
-3wk6,2014-04-16,2013-10-17
-7wkj,2022-03-02,2022-01-10
-4wkr,2015-03-18,2014-10-03
-6wk2,2020-06-17,2020-04-15
-3wk8,2014-04-16,2013-10-17
-5wkp,2017-11-15,2017-07-25
-2wko,2009-11-24,2009-06-16
-8wko,2024-02-14,2023-09-28
-2wk9,2009-07-21,2009-06-08
-4wko,2015-11-25,2014-10-02
-2wk2,2010-03-16,2009-06-04
-3wka,2014-04-16,2013-10-18
-3wku,2014-04-30,2013-10-31
-7wkv,2022-03-30,2022-01-11
-1wky,2005-06-15,2004-06-15
-4wk7,2014-12-10,2014-10-01
-5wk0,2018-02-21,2017-07-24
-3wkc,2014-04-16,2013-10-18
-5wkx,2018-08-08,2017-07-25
-5wkm,2018-04-04,2017-07-25
-4wki,2014-12-10,2014-10-02
-5wk9,2017-09-06,2017-07-24
-5wkv,2018-03-14,2017-07-25
-5wkr,2018-05-09,2017-07-25
-2wky,2009-07-21,2009-06-18
-1wkl,2005-08-23,2004-06-01
-8wkr,2024-02-14,2023-09-28
-1wk8,2005-09-27,2004-05-30
-1wkv,2005-06-28,2004-06-09
-3wki,2013-12-25,2013-10-21
-4wk9,2015-07-08,2014-10-02
-6wkd,2020-08-26,2020-04-16
-2wkz,2009-12-15,2009-06-19
-4wkp,2015-11-25,2014-10-02
-1wkg,2005-09-27,2004-05-31
-6wkb,2021-04-21,2020-04-15
-6wk8,2020-10-28,2020-04-15
-4wkh,2015-07-08,2014-10-02
-5wk4,2017-12-13,2017-07-24
-1wkk,2005-08-23,2004-06-01
-6wkp,2020-04-29,2020-04-16
-6wkn,2021-04-21,2020-04-16
-3wk2,2013-12-04,2013-10-17
-6wk0,2021-04-21,2020-04-15
-2wke,2009-12-01,2009-06-10
-4wke,2014-12-10,2014-10-02
-4wk4,2014-12-03,2014-10-01
-2wkl,2009-09-22,2009-06-15
-6wkv,2021-04-21,2020-04-17
-3wk7,2014-04-16,2013-10-17
-4wkc,2015-08-19,2014-10-02
-6wkc,2020-08-26,2020-04-16
-5wks,2018-05-09,2017-07-25
-2wku,2009-11-03,2009-06-18
-2wkr,2009-08-18,2009-06-16
-2wkv,2009-11-03,2009-06-18
-7wky,2022-08-10,2022-01-12
-3wky,2014-04-23,2013-11-02
-3wke,2014-04-16,2013-10-18
-4wk6,2014-11-12,2014-10-01
-1wkr,2004-09-07,2004-06-02
-6wkq,2020-04-29,2020-04-16
-6wks,2020-05-06,2020-04-16
-5wkl,2018-04-04,2017-07-25
-6wkh,2020-08-26,2020-04-16
-3wk5,2014-04-16,2013-10-17
-2wkq,2009-08-18,2009-06-16
-6wk1,2020-06-17,2020-04-15
-4wkt,2014-11-12,2014-10-03
-2wk1,2009-12-15,2009-06-03
-2wkw,2009-06-30,2009-06-18
-4wk2,2014-12-03,2014-10-01
-5wkj,2018-04-04,2017-07-25
-6wkf,2020-08-26,2020-04-16
-4wkm,2014-12-17,2014-10-02
-5wkk,2018-04-04,2017-07-25
-1wkh,2005-09-27,2004-05-31
-4wkb,2015-08-19,2014-10-02
-6wka,2021-02-24,2020-04-15
-4wk1,2014-11-26,2014-10-01
-1wkf,1997-07-07,1996-08-06
-6wkr,2021-02-03,2020-04-16
-4wk0,2014-12-03,2014-10-01
-7wku,2022-05-25,2022-01-11
-4wkv,2014-11-12,2014-10-03
-4wkf,2015-07-08,2014-10-02
-5wki,2017-11-01,2017-07-25
-6wk3,2020-07-08,2020-04-15
-3wkh,2013-12-25,2013-10-21
-2wkt,2009-11-03,2009-06-18
-6wk6,2021-01-06,2020-04-15
-3wk4,2014-04-16,2013-10-17
-7wkz,2022-12-28,2022-01-12
-1wkq,2004-07-13,2004-06-01
-5wkt,2017-12-13,2017-07-25
-3wkz,2014-04-09,2013-11-05
-2wka,2009-07-21,2009-06-08
-6wkx,2020-12-02,2020-04-17
-4wkn,2015-11-25,2014-10-02
-5wku,2018-03-14,2017-07-25
-6wkz,2020-08-19,2020-04-17
-3wk9,2014-04-16,2013-10-18
-2wkk,2010-01-19,2009-06-14
-2wkp,2009-08-18,2009-06-16
-7wkw,2022-08-10,2022-01-11
-3wkb,2014-04-16,2013-10-18
-5wke,2017-11-01,2017-07-25
-3wk3,2013-12-04,2013-10-17
-1wkm,2005-02-22,2004-06-01
-3wkd,2014-04-16,2013-10-18
-3wkt,2014-01-29,2013-10-31
-2wkj,2009-12-01,2009-06-11
-2wk6,2009-07-07,2009-06-05
-4wkq,2014-11-05,2014-10-03
-3wkn,2014-10-29,2013-10-29
-5wky,2018-08-08,2017-07-25
-2wkm,2010-08-25,2009-06-15
-8wkl,2024-02-28,2023-09-28
-7wkm,2023-01-25,2022-01-10
-3wk0,2013-12-04,2013-10-17
-3wkq,2013-12-11,2013-10-29
-7wkl,2023-01-25,2022-01-10
-7wkd,2022-06-15,2022-01-09
-5wkc,2018-02-14,2017-07-25
-2wkx,2010-01-12,2009-06-18
-2wkh,2010-08-25,2009-06-11
-4wkz,2015-12-23,2014-10-05
-5wk7,2017-09-06,2017-07-24
-3wkp,2013-12-11,2013-10-29
-2wk8,2009-07-21,2009-06-08
-1wke,1997-07-07,1996-08-06
-7wk0,2022-07-13,2022-01-08
-4wks,2014-11-12,2014-10-03
-6wkw,2020-12-02,2020-04-17
-3wkx,2014-04-30,2013-11-01
-4wkx,2015-10-07,2014-10-03
-2wkn,2010-09-01,2009-06-16
-1wkd,1997-07-07,1996-08-06
-2wk0,2009-12-01,2009-06-03
-4wku,2014-11-12,2014-10-03
-5wkd,2018-04-18,2017-07-25
-1h17,2002-11-01,2002-07-03
-7h1j,2024-05-08,2024-04-03
-5h1c,2016-12-21,2016-10-08
-3h15,2009-07-14,2009-04-10
-2h10,2007-01-30,2006-05-15
-2h11,2006-11-21,2006-05-15
-4h18,2013-09-25,2012-09-10
-8h1o,2023-08-02,2022-10-03
-8h16,2022-11-09,2022-09-30
-3h1v,2009-10-06,2009-04-14
-6h1j,2018-09-26,2018-07-11
-3h1m,2009-05-19,2009-04-13
-2h1h,2007-05-22,2006-05-16
-4h1w,2013-03-06,2012-09-11
-8h14,2022-10-19,2022-09-30
-6h1e,2019-05-22,2018-07-11
-5h1e,2017-01-11,2016-10-08
-5h1u,2017-02-22,2016-10-11
-5h1w,2017-03-15,2016-10-12
-6h15,2019-01-30,2018-07-11
-3h1f,2010-03-09,2009-04-12
-1h19,2002-08-08,2002-07-04
-1h1r,2002-09-19,2002-07-21
-8h15,2022-11-09,2022-09-30
-6h1d,2019-05-22,2018-07-11
-5h1v,2017-02-22,2016-10-11
-1h1b,2002-08-29,2002-07-05
-3h1g,2010-03-09,2009-04-12
-1h18,2002-11-01,2002-07-04
-5h1l,2016-11-23,2016-10-10
-6h11,2020-01-29,2018-07-10
-8h1q,2023-08-16,2022-10-03
-3h1i,2009-04-28,2009-04-12
-6h1c,2019-07-31,2018-07-11
-6h1o,2019-02-20,2018-07-12
-1h1d,2003-07-17,2002-07-12
-4h1t,2013-09-11,2012-09-11
-1h1a,2003-07-04,2002-07-05
-8h18,2023-09-13,2022-10-01
-4h19,2012-10-31,2012-09-10
-4h12,2012-10-03,2012-09-10
-5h1z,2017-01-11,2016-10-13
-6h1i,2018-11-28,2018-07-11
-7h1y,2024-05-08,2024-04-03
-7h1h,2024-05-08,2024-04-03
-7h1n,2024-05-08,2024-04-03
-3h1e,2010-03-09,2009-04-12
-3h1x,2009-06-09,2009-04-14
-4h1l,2012-11-14,2012-09-10
-1h12,2003-03-13,2002-07-02
-3h1s,2009-05-05,2009-04-13
-2h1w,2007-01-16,2006-05-17
-1h1x,2003-10-23,2002-07-25
-3h1k,2009-04-28,2009-04-12
-8h1g,2023-08-16,2022-10-03
-4h1y,2012-11-28,2012-09-11
-3h1q,2009-05-19,2009-04-13
-1h1i,2002-11-28,2002-07-15
-5h14,2017-01-25,2016-10-08
-5h1t,2017-02-22,2016-10-11
-7h1t,2024-05-08,2024-04-03
-2h12,2006-09-26,2006-05-15
-4h1e,2012-10-17,2012-09-10
-6h1t,2019-02-20,2018-07-12
-6h1p,2019-06-26,2018-07-12
-6h1m,2018-12-12,2018-07-12
-1h1w,2003-07-17,2002-07-23
-6h16,2019-01-30,2018-07-11
-6h12,2019-05-15,2018-07-10
-5h1b,2016-12-21,2016-10-08
-3h10,2009-07-07,2009-04-10
-7h1o,2024-05-08,2024-04-03
-3h11,2009-04-28,2009-04-10
-6h10,2020-01-29,2018-07-10
-2h13,2006-07-11,2006-05-15
-8h1b,2023-01-25,2022-10-01
-4h1n,2013-01-16,2012-09-10
-6h14,2019-05-15,2018-07-10
-6h1s,2019-02-20,2018-07-12
-8h10,2022-10-19,2022-09-30
-8h1e,2023-08-16,2022-10-03
-1h1z,2003-01-30,2002-07-25
-6h1l,2019-02-20,2018-07-12
-2h1u,2006-05-30,2006-05-17
-1h1p,2002-09-19,2002-07-21
-2h1v,2007-01-16,2006-05-17
-1h1m,2002-11-28,2002-07-19
-7h1x,2024-05-08,2024-04-03
-8h1y,2023-08-16,2022-10-04
-6h1x,2018-11-07,2018-07-12
-1h1o,2003-07-17,2002-07-19
-4h13,2013-02-13,2012-09-10
-3h1h,2009-04-28,2009-04-12
-5h18,2017-09-27,2016-10-08
-2h1l,2006-09-12,2006-05-16
-8h1n,2023-07-12,2022-10-03
-1h1t,2003-07-07,2002-07-21
-6h1h,2018-11-28,2018-07-11
-1h1s,2002-09-19,2002-07-21
-1h11,2002-08-08,2002-07-01
-6h1u,2018-08-01,2018-07-12
-2h1j,2006-06-13,2006-05-16
-1h1q,2002-09-19,2002-07-21
-6h19,2019-03-27,2018-07-11
-6h1z,2018-08-22,2018-07-12
-4h1q,2013-04-24,2012-09-11
-5h19,2017-01-25,2016-10-08
-6h13,2019-05-15,2018-07-10
-8h1i,2023-10-18,2022-10-03
-8h1l,2023-07-12,2022-10-03
-3h1w,2009-05-19,2009-04-14
-8h11,2022-11-09,2022-09-30
-2h1p,1998-01-28,1997-11-12
-8h1j,2023-04-12,2022-10-03
-1h1l,2002-07-29,2002-07-18
-2h1n,2006-06-13,2006-05-16
-4h14,2012-10-31,2012-09-10
-4h16,2012-09-19,2012-09-10
-2h1c,2006-09-26,2006-05-16
-2h16,2006-06-13,2006-05-16
-6h1v,2019-04-24,2018-07-12
-7h1k,2024-05-08,2024-04-03
-3h1j,2009-04-28,2009-04-12
-5h10,2017-10-11,2016-10-07
-4h1d,2013-05-01,2012-09-10
-4h15,2012-09-19,2012-09-10
-3h12,2009-04-21,2009-04-10
-8h12,2022-11-09,2022-09-30
-1h1h,2002-10-03,2002-07-15
-6h17,2019-11-27,2018-07-11
-3h1y,2009-05-19,2009-04-14
-8h17,2023-04-26,2022-09-30
-2h15,2007-03-27,2006-05-16
-4h1g,2012-10-10,2012-09-10
-4h1j,2012-11-28,2012-09-10
-6h1b,2018-09-05,2018-07-11
-5h1m,2016-11-23,2016-10-10
-4h1z,2012-09-26,2012-09-11
-1h16,2002-11-01,2002-07-03
-1h1v,2003-01-24,2002-07-23
-6h1a,2019-03-27,2018-07-11
-8h13,2022-10-19,2022-09-30
-7h1i,2024-05-08,2024-04-03
-1h10,2003-06-27,2002-07-01
-3h1u,2009-05-05,2009-04-14
-1h1c,2004-03-19,2002-07-08
-1h15,2002-10-03,2002-07-02
-4h1v,2013-08-21,2012-09-11
-2h1f,2007-05-22,2006-05-16
-4h1s,2012-10-03,2012-09-11
-5h15,2017-01-25,2016-10-08
-5h1y,2017-01-18,2016-10-13
-8h1f,2023-08-16,2022-10-03
-4h1p,2012-10-24,2012-09-11
-3h1l,2010-01-05,2009-04-12
-6h18,2019-03-27,2018-07-11
-3h1p,2009-06-30,2009-04-13
-5h17,2017-01-25,2016-10-08
-4h1m,2012-11-28,2012-09-10
-7h1p,2024-05-08,2024-04-03
-2h1i,2006-05-30,2006-05-16
-5h13,2017-01-25,2016-10-08
-4f8b,2012-07-11,2012-05-17
-1f81,2000-10-18,2000-06-28
-1f8f,2003-07-08,2000-06-30
-5f8n,2016-06-22,2015-12-09
-8f8k,2023-11-29,2022-11-22
-6f84,2019-03-13,2017-12-12
-7f83,2022-01-19,2021-07-01
-3f8u,2009-01-13,2008-11-13
-7f8d,2022-02-23,2021-07-02
-6f85,2018-03-14,2017-12-12
-6f86,2019-06-26,2017-12-12
-2f81,2006-03-07,2005-12-01
-3f8y,2009-08-18,2008-11-13
-3f8p,2009-01-13,2008-11-13
-5f84,2016-07-20,2015-12-09
-1f8q,2000-07-26,2000-07-03
-6f87,2018-04-25,2017-12-12
-8f81,2023-12-13,2022-11-21
-8f8z,2023-01-18,2022-11-22
-1f8e,2001-04-11,2000-06-30
-6f8z,2018-05-02,2017-12-13
-5f8a,2016-11-09,2015-12-09
-1f86,2001-06-29,2000-06-29
-8f8x,2023-03-29,2022-11-22
-5f8k,2016-02-03,2015-12-09
-5f8y,2016-04-06,2015-12-09
-1f80,2001-06-28,2000-06-28
-5f85,2016-07-20,2015-12-09
-8f82,2023-12-13,2022-11-21
-5f8e,2016-06-29,2015-12-09
-5f83,2016-09-07,2015-12-09
-6f8w,2018-05-16,2017-12-13
-2f8e,2006-03-28,2005-12-02
-8f8e,2023-03-01,2022-11-21
-2f8z,2006-02-28,2005-12-02
-8f80,2023-12-13,2022-11-21
-8f8w,2023-03-29,2022-11-22
-8f8o,2022-11-30,2022-11-22
-1f8h,2000-11-01,2000-06-30
-4f84,2012-10-31,2012-05-17
-5f81,2016-02-10,2015-12-08
-3f85,2009-08-11,2008-11-11
-6f8a,2018-03-14,2017-12-12
-6f81,2019-03-13,2017-12-12
-1f8i,2000-12-30,2000-06-30
-5f8b,2016-04-20,2015-12-09
-5f87,2016-07-20,2015-12-09
-7f8x,2021-12-29,2021-07-02
-5f8m,2016-06-22,2015-12-09
-5f8u,2015-12-23,2015-12-09
-2f8j,2006-02-21,2005-12-02
-5f8z,2016-12-14,2015-12-09
-7f8y,2021-10-13,2021-07-02
-4f8n,2013-05-22,2012-05-17
-4f8x,2012-05-30,2012-05-18
-4f8f,2013-05-22,2012-05-17
-1f8v,2000-12-06,2000-07-05
-6f8c,2018-03-14,2017-12-12
-3f83,2009-08-11,2008-11-11
-1f8z,2000-10-18,2000-07-05
-3f8v,2009-02-17,2008-11-13
-5f8j,2016-06-22,2015-12-09
-1f8u,2001-01-17,2000-07-05
-7f8c,2022-01-12,2021-07-01
-7f8k,2021-09-08,2021-07-02
-1f8g,2001-06-30,2000-06-30
-6f8o,2019-03-13,2017-12-13
-8f86,2023-04-05,2022-11-21
-1f8b,2001-04-11,2000-06-30
-2f8i,2005-12-20,2005-12-02
-2f80,2006-03-07,2005-12-01
-2f8q,2006-09-26,2005-12-03
-7f8g,2021-12-29,2021-07-02
-8f8s,2023-06-07,2022-11-22
-6f8b,2018-03-28,2017-12-12
-8f8r,2023-06-07,2022-11-22
-4f8d,2013-04-10,2012-05-17
-7f82,2022-02-09,2021-06-30
-5f8x,2016-12-14,2015-12-09
-8f85,2023-12-13,2022-11-21
-4f8m,2012-06-13,2012-05-17
-7f8b,2022-01-12,2021-07-01
-7f8p,2022-05-11,2021-07-02
-2f8b,2006-08-08,2005-12-02
-7f80,2022-07-06,2021-06-30
-5f8g,2016-06-22,2015-12-09
-1f8s,2000-08-24,2000-07-04
-5f8r,2016-01-20,2015-12-09
-1f8n,2001-07-04,2000-06-30
-7f86,2022-04-13,2021-07-01
-6f8u,2018-05-16,2017-12-13
-8f8m,2023-11-29,2022-11-22
-5f8f,2016-06-29,2015-12-09
-3f8c,2008-12-30,2008-11-12
-4f8j,2012-09-26,2012-05-17
-5f8i,2016-06-22,2015-12-09
-3f8z,2009-08-18,2008-11-13
-2f8l,2006-01-17,2005-12-02
-4f8p,2013-05-22,2012-05-17
-1f8d,2001-04-11,2000-06-30
-8f84,2023-12-13,2022-11-21
-3f8k,2009-05-26,2008-11-12
-3f8a,2009-11-10,2008-11-12
-6f8v,2018-05-16,2017-12-13
-3f88,2009-03-10,2008-11-11
-3f8s,2009-06-23,2008-11-13
-6f8n,2018-07-04,2017-12-13
-1f8a,2000-08-23,2000-06-29
-5f88,2016-10-26,2015-12-09
-8f8q,2023-06-07,2022-11-22
-2f8g,2006-03-07,2005-12-02
-3f8e,2009-10-06,2008-11-12
-2f8p,2006-02-14,2005-12-03
-4f8z,2013-05-22,2012-05-18
-6f88,2018-03-14,2017-12-12
-4f8y,2012-06-06,2012-05-18
-4f8r,2013-08-07,2012-05-17
-7f87,2022-07-06,2021-07-01
-1f82,2000-08-16,2000-06-28
-7f8h,2021-12-29,2021-07-02
-3f82,2009-03-31,2008-11-11
-5f8w,2016-04-06,2015-12-09
-3f8n,2009-06-16,2008-11-13
-7f8u,2021-10-13,2021-07-02
-8f8l,2023-11-29,2022-11-22
-4f8e,2013-05-22,2012-05-17
-8f88,2023-07-05,2022-11-21
-1f8m,2000-12-30,2000-06-30
-8f8p,2023-06-07,2022-11-22
-6f89,2018-04-25,2017-12-12
-3f8w,2009-11-24,2008-11-13
-6f8r,2018-05-16,2017-12-13
-1f8w,2001-02-05,2000-07-05
-2f8c,2006-02-28,2005-12-02
-6f8g,2018-11-28,2017-12-13
-3f80,2008-12-02,2008-11-10
-5f8t,2016-12-14,2015-12-09
-3f8d,2009-01-13,2008-11-12
-3f8h,2008-11-25,2008-11-12
-6f8j,2019-06-26,2017-12-13
-5f8h,2016-06-22,2015-12-09
-5f8l,2016-06-22,2015-12-09
-6f82,2019-03-13,2017-12-12
-1f88,2000-08-04,2000-06-29
-2f8f,2006-07-04,2005-12-02
-1f8c,2001-04-11,2000-06-30
-7f8l,2022-01-19,2021-07-02
-4f8l,2013-05-22,2012-05-17
-3f8r,2009-01-13,2008-11-13
-8f8f,2023-11-29,2022-11-22
-8f87,2023-11-29,2022-11-21
-1f8r,2000-08-24,2000-07-04
-4f86,2012-10-31,2012-05-17
-6f8t,2018-05-16,2017-12-13
-3f8f,2008-12-30,2008-11-12
-4f8h,2012-08-29,2012-05-17
-8f8t,2023-06-07,2022-11-22
-2f89,2006-02-28,2005-12-02
-4f8o,2013-05-22,2012-05-17
-3f81,2009-11-10,2008-11-11
-6f8x,2018-05-16,2017-12-13
-6f83,2019-01-30,2017-12-12
-8f8y,2023-01-18,2022-11-22
-8f83,2023-12-13,2022-11-21
-6f8y,2018-04-25,2017-12-13
-1f8y,2000-08-09,2000-07-05
-7f8t,2022-03-09,2021-07-02
-5f8p,2016-12-14,2015-12-09
-4dus,2012-10-10,2012-02-22
-2duo,2007-07-24,2006-07-25
-1dui,2000-01-28,2000-01-17
-4duo,2012-08-29,2012-02-22
-5dub,2016-01-20,2015-09-18
-2du8,2006-11-21,2006-07-20
-2du5,2007-03-13,2006-07-20
-8du8,2022-11-09,2022-07-27
-1du3,2000-09-27,2000-01-14
-7duw,2021-04-21,2021-01-12
-3duq,2009-06-30,2008-07-17
-5dux,2016-02-17,2015-09-21
-5dut,2015-12-16,2015-09-20
-2du0,2006-11-07,2006-07-19
-4dur,2012-03-28,2012-02-22
-6duq,2018-09-05,2018-06-21
-8dul,2023-07-05,2022-07-27
-6dux,2018-07-04,2018-06-22
-4du7,2012-07-11,2012-02-21
-7duy,2022-01-19,2021-01-12
-8duo,2023-06-14,2022-07-27
-8dua,2022-10-26,2022-07-27
-4duh,2012-08-01,2012-02-22
-7dui,2022-01-12,2021-01-09
-7dut,2021-12-22,2021-01-11
-3duh,2008-08-19,2008-07-17
-6du2,2018-09-26,2018-06-19
-8duh,2022-11-09,2022-07-27
-1dut,1997-01-27,1996-09-15
-7dua,2022-01-12,2021-01-08
-8du3,2022-08-10,2022-07-26
-4dum,2012-04-11,2012-02-22
-7due,2022-01-19,2021-01-08
-8due,2023-06-14,2022-07-27
-2duz,2006-10-03,2006-07-27
-2du2,2006-12-05,2006-07-19
-5du9,2016-03-30,2015-09-18
-8duk,2023-07-05,2022-07-27
-8du0,2022-08-10,2022-07-26
-4duv,2013-04-03,2012-02-22
-3du2,2009-06-30,2008-07-16
-1dud,1996-11-08,1996-04-30
-7dub,2022-01-19,2021-01-08
-2duv,2007-01-27,2006-07-27
-6duf,2018-08-01,2018-06-20
-5duf,2016-01-20,2015-09-18
-1dul,2000-02-28,2000-01-17
-8du9,2022-11-09,2022-07-27
-6dug,2018-08-01,2018-06-20
-5duq,2016-08-31,2015-09-20
-5duj,2016-09-28,2015-09-18
-6duk,2019-06-05,2018-06-21
-6dur,2018-10-10,2018-06-21
-4du3,2012-05-23,2012-02-21
-3duu,2008-12-02,2008-07-17
-5duh,2016-05-04,2015-09-18
-6dus,2018-07-18,2018-06-21
-6du3,2018-09-26,2018-06-19
-8dui,2022-11-09,2022-07-27
-6du7,2019-01-16,2018-06-19
-4duf,2012-06-13,2012-02-21
-2duj,2006-08-08,2006-07-23
-7duk,2022-01-12,2021-01-09
-4duk,2013-02-27,2012-02-22
-2du6,2007-03-13,2006-07-20
-8dub,2022-11-16,2022-07-27
-7du8,2022-02-02,2021-01-08
-5due,2016-05-04,2015-09-18
-1duk,2000-02-07,2000-01-17
-3du7,2008-10-21,2008-07-17
-6duv,2019-06-26,2018-06-22
-5dul,2015-09-30,2015-09-18
-4duw,2013-03-20,2012-02-22
-6duc,2019-06-26,2018-06-20
-6dui,2019-06-26,2018-06-20
-3duw,2008-08-05,2008-07-18
-7dux,2022-01-19,2021-01-12
-2dux,2006-10-03,2006-07-27
-6du9,2019-07-03,2018-06-20
-5du5,2016-05-04,2015-09-18
-5du4,2016-01-20,2015-09-18
-8dus,2022-11-09,2022-07-27
-1duz,2000-02-04,2000-01-19
-4du2,2012-06-13,2012-02-21
-6duj,2019-06-26,2018-06-20
-4dua,2012-06-13,2012-02-21
-2dur,2007-07-24,2006-07-25
-3du8,2009-03-03,2008-07-17
-2duq,2007-07-24,2006-07-25
-7du2,2021-03-17,2021-01-07
-4dug,2012-03-14,2012-02-21
-1duv,2000-07-04,2000-01-18
-4dub,2012-06-13,2012-02-21
-3dur,2008-12-02,2008-07-17
-1duc,1998-06-03,1997-11-29
-3du0,2008-11-18,2008-07-16
-5dug,2016-05-04,2015-09-18
-7du3,2022-03-09,2021-01-07
-4dun,2012-03-14,2012-02-22
-5du6,2016-01-20,2015-09-18
-1duy,2000-02-04,2000-01-19
-5duv,2016-02-17,2015-09-21
-5duc,2016-01-20,2015-09-18
-8duj,2023-05-31,2022-07-27
-5dus,2016-01-13,2015-09-20
-6du6,2019-01-30,2018-06-19
-4du8,2012-07-11,2012-02-21
-4du1,2012-05-23,2012-02-21
-3dux,2009-06-23,2008-07-18
-3dug,2008-08-05,2008-07-17
-4duz,2013-02-27,2012-02-22
-4duy,2013-02-27,2012-02-22
-8dug,2022-11-09,2022-07-27
-3duy,2009-02-24,2008-07-18
-6dum,2019-05-01,2018-06-21
-3duf,2009-01-06,2008-07-17
-3duz,2008-09-16,2008-07-18
-1dub,1997-07-07,1996-06-10
-7du1,2022-01-19,2021-01-07
-4du9,2012-03-07,2012-02-21
-3dut,2009-08-04,2008-07-17
-7duc,2022-01-19,2021-01-08
-6due,2018-10-31,2018-06-20
-5duw,2016-02-17,2015-09-21
-1duo,2000-02-07,2000-01-18
-5dur,2015-12-16,2015-09-20
-6dup,2018-08-29,2018-06-21
-5du8,2016-01-20,2015-09-18
-6dud,2018-11-28,2018-06-20
-8dud,2022-11-09,2022-07-27
-4due,2012-06-13,2012-02-21
-7duq,2021-07-14,2021-01-11
-4duq,2012-03-07,2012-02-22
-8du5,2023-05-31,2022-07-26
-3du3,2009-06-30,2008-07-16
-8du1,2022-08-10,2022-07-26
-2du1,2006-11-07,2006-07-19
-7dug,2022-01-12,2021-01-09
-2dub,1998-04-29,1997-04-28
-5duo,2015-11-11,2015-09-20
-3dus,2008-12-02,2008-07-17
-2dup,2007-07-24,2006-07-25
-7dul,2022-01-26,2021-01-09
-4du4,2012-05-23,2012-02-21
-4du6,2012-03-21,2012-02-21
-2du3,2007-03-13,2006-07-20
-8dun,2023-07-05,2022-07-27
-7duu,2022-02-02,2021-01-11
-5dua,2016-03-30,2015-09-18
-2dua,2006-10-03,2006-07-21
-7duz,2022-01-19,2021-01-12
-4dud,2012-06-13,2012-02-21
-7du9,2022-01-12,2021-01-08
-7duf,2021-08-25,2021-01-08
-8duz,2023-07-05,2022-07-27
-4dux,2013-03-20,2012-02-22
-6du8,2018-07-25,2018-06-20
-3du4,2009-06-23,2008-07-16
-6duh,2018-08-01,2018-06-20
-7dur,2021-08-11,2021-01-11
-7duj,2022-01-12,2021-01-09
-4duc,2012-06-13,2012-02-21
-8du6,2022-11-09,2022-07-27
-1dug,2000-02-02,2000-01-17
-1duw,2001-03-21,2000-01-19
-8duc,2022-11-09,2022-07-27
-5dum,2015-12-16,2015-09-19
-7duh,2022-01-26,2021-01-09
-9f4w,2024-05-08,2024-04-28
-6f4q,2018-04-04,2017-11-29
-4f4f,2012-06-27,2012-05-10
-9f4j,2024-05-08,2024-04-28
-5f4p,2016-03-30,2015-12-03
-8f4f,2023-03-22,2022-11-10
-6f4f,2018-06-06,2017-11-29
-7f4z,2022-06-29,2021-06-21
-4f4b,2013-05-15,2012-05-10
-3f49,2008-12-16,2008-10-31
-8f4q,2023-12-13,2022-11-11
-4f4t,2013-05-15,2012-05-11
-4f4c,2012-09-26,2012-05-10
-7f4a,2022-03-16,2021-06-18
-1f4x,2000-08-02,2000-06-10
-5f4t,2016-06-15,2015-12-03
-7f4y,2021-07-14,2021-06-21
-8f4k,2023-03-22,2022-11-10
-7f4x,2022-06-29,2021-06-21
-7f42,2022-06-22,2021-06-17
-8f4e,2023-03-22,2022-11-10
-8f45,2022-11-23,2022-11-10
-2f4f,2005-12-13,2005-11-23
-7f4c,2022-06-22,2021-06-18
-6f4b,2018-06-06,2017-11-29
-8f4p,2023-11-15,2022-11-11
-9f4p,2024-05-08,2024-04-28
-2f48,2006-11-28,2005-11-22
-8f4b,2023-03-22,2022-11-10
-1f4e,2000-06-22,2000-06-07
-5f4w,2017-02-01,2015-12-03
-1f4z,2000-08-09,2000-06-10
-6f41,2018-01-17,2017-11-29
-6f48,2018-04-25,2017-11-29
-3f4d,2009-08-18,2008-10-31
-7f4q,2022-06-15,2021-06-21
-7f4w,2021-08-25,2021-06-21
-1f4p,2001-04-04,2000-06-08
-4f45,2013-04-03,2012-05-10
-9f4v,2024-05-08,2024-04-28
-4f4z,2013-01-02,2012-05-11
-6f4k,2018-06-06,2017-11-29
-8f41,2023-01-11,2022-11-10
-9f4d,2024-05-08,2024-04-27
-1f4m,2001-01-10,2000-06-08
-6f45,2018-08-01,2017-11-29
-2f47,2006-04-25,2005-11-22
-3f45,2009-07-07,2008-10-31
-7f4b,2022-06-22,2021-06-18
-9f40,2024-05-29,2024-04-26
-1f4y,2000-08-02,2000-06-10
-8f4t,2023-02-01,2022-11-11
-7f43,2022-06-22,2021-06-17
-1f4c,2000-06-22,2000-06-07
-5f4s,2016-12-28,2015-12-03
-3f47,2009-02-10,2008-10-31
-6f42,2018-01-17,2017-11-29
-9f4h,2024-05-08,2024-04-27
-6f4u,2018-12-12,2017-11-30
-8f47,2023-12-13,2022-11-10
-6f4s,2018-04-04,2017-11-30
-4f4w,2013-01-02,2012-05-11
-8f4w,2023-02-01,2022-11-11
-3f4n,2008-11-25,2008-11-01
-9f4e,2024-05-08,2024-04-27
-3f4v,2009-11-03,2008-11-03
-7f4g,2021-07-07,2021-06-18
-1f4g,2000-06-22,2000-06-07
-5f4o,2016-01-13,2015-12-03
-4f46,2013-04-03,2012-05-10
-4f4p,2012-12-12,2012-05-11
-6f40,2018-01-17,2017-11-29
-5f4n,2016-05-25,2015-12-03
-7f4p,2022-06-15,2021-06-21
-8f46,2022-11-23,2022-11-10
-1f4j,2000-06-21,2000-06-07
-3f4f,2008-11-11,2008-10-31
-5f4b,2016-03-09,2015-12-03
-5f4q,2016-06-15,2015-12-03
-5f4z,2016-02-17,2015-12-03
-7f46,2022-03-23,2021-06-17
-6f4l,2018-04-25,2017-11-29
-7f4h,2021-09-08,2021-06-18
-4f42,2013-05-15,2012-05-09
-1f4s,2001-09-28,2000-06-09
-8f4c,2023-03-22,2022-11-10
-3f46,2009-02-10,2008-10-31
-4f4s,2012-08-15,2012-05-11
-3f4x,2009-03-17,2008-11-03
-6f4w,2018-02-14,2017-11-30
-3f4j,2008-12-23,2008-10-31
-5f4u,2016-03-30,2015-12-03
-7f4e,2022-03-16,2021-06-18
-5f4v,2016-06-15,2015-12-03
-7f4n,2022-06-15,2021-06-21
-3f4b,2010-03-02,2008-10-31
-6f4v,2018-12-12,2017-11-30
-4f4v,2013-05-15,2012-05-11
-1f40,2000-11-08,2000-06-07
-7f4m,2022-06-15,2021-06-21
-1f4o,2000-09-27,2000-06-08
-9f4s,2024-05-08,2024-04-28
-9f4y,2024-05-08,2024-04-28
-8f4g,2023-03-22,2022-11-10
-4f4u,2012-06-20,2012-05-11
-9f4z,2024-05-08,2024-04-28
-8f4a,2023-02-08,2022-11-10
-6f4o,2018-04-04,2017-11-29
-1f4u,2000-10-23,2000-06-09
-8f4v,2023-02-22,2022-11-11
-1f4v,2001-01-17,2000-06-10
-7f41,2022-06-22,2021-06-17
-6f44,2018-01-17,2017-11-29
-4f4q,2012-09-05,2012-05-11
-7f4v,2022-04-06,2021-06-21
-4f4o,2012-08-29,2012-05-11
-5f49,2015-12-16,2015-12-03
-6f4d,2018-04-25,2017-11-29
-8f4r,2022-12-28,2022-11-11
-8f44,2022-11-23,2022-11-10
-2f4j,2006-01-24,2005-11-23
-6f4p,2018-04-04,2017-11-29
-1f45,2001-06-20,2000-06-07
-6f4a,2018-01-17,2017-11-29
-4f4y,2013-01-02,2012-05-11
-5f4e,2016-06-15,2015-12-03
-9f4r,2024-05-15,2024-04-28
-9f4t,2024-05-08,2024-04-28
-2f4b,2006-02-14,2005-11-23
-1f4t,2000-10-23,2000-06-09
-1f4n,2001-01-10,2000-06-08
-3f4c,2009-09-15,2008-10-31
-5f4l,2016-03-30,2015-12-03
-2f4m,2006-03-07,2005-11-23
-9f4u,2024-05-08,2024-04-28
-3f48,2008-12-23,2008-10-31
-9f4n,2024-05-08,2024-04-28
-1f4r,2000-12-11,2000-06-08
-8f4s,2023-10-18,2022-11-11
-1f48,2000-09-13,2000-06-07
-1f4l,2001-03-21,2000-06-08
-1f4f,2000-06-22,2000-06-07
-8f4y,2023-10-18,2022-11-11
-2f44,2006-02-07,2005-11-22
-9f4x,2024-05-08,2024-04-28
-5f48,2015-12-30,2015-12-03
-4f4d,2012-09-12,2012-05-10
-8f4u,2023-02-08,2022-11-11
-9f41,2024-05-29,2024-04-26
-4f4k,2013-07-24,2012-05-10
-4f4x,2013-01-02,2012-05-11
-9f4g,2024-05-08,2024-04-27
-6f4x,2018-02-14,2017-11-30
-8f4d,2023-03-22,2022-11-10
-2f4v,2006-07-04,2005-11-24
-6f47,2018-03-14,2017-11-29
-4f44,2013-05-15,2012-05-10
-5f4r,2016-03-30,2015-12-03
-8f4j,2023-03-22,2022-11-10
-7f4d,2021-09-08,2021-06-18
-1f42,2001-06-13,2000-06-07
-1f4d,2000-06-22,2000-06-07
-7f4f,2021-09-08,2021-06-18
-2f4i,2006-02-07,2005-11-23
-1f4a,2001-02-21,2000-06-07
-1f4h,2001-02-21,2000-06-07
-3f4i,2008-12-23,2008-10-31
-2f43,2006-03-07,2005-11-22
-4f4r,2012-06-27,2012-05-11
-4f49,2012-09-05,2012-05-10
-5f47,2015-12-30,2015-12-03
-2f4o,2006-03-07,2005-11-23
-8f4z,2023-02-01,2022-11-11
-5f41,2016-02-24,2015-12-03
-2f4y,2006-04-25,2005-11-24
-7f4t,2022-06-15,2021-06-21
-6f4n,2018-04-04,2017-11-29
-8f4i,2023-03-22,2022-11-10
-6f4t,2018-04-04,2017-11-30
-8f4h,2023-03-22,2022-11-10
-2f4l,2005-12-06,2005-11-23
-4f48,2012-11-14,2012-05-10
-2f49,2006-03-28,2005-11-22
-9f4l,2024-05-08,2024-04-28
-7f44,2022-06-22,2021-06-17
-7f4i,2021-09-08,2021-06-18
-6f4r,2018-04-04,2017-11-30
-6f43,2018-06-06,2017-11-29
-4f4a,2012-05-30,2012-05-10
-7wzu,2023-01-04,2022-02-19
-4wzf,2015-12-09,2014-11-19
-1wzd,2006-02-21,2005-03-04
-2wzi,2010-01-26,2009-11-30
-6wz7,2020-09-16,2020-05-13
-5wzn,2017-06-07,2017-01-18
-2wzg,2009-12-08,2009-11-29
-4wzm,2015-05-06,2014-11-20
-4wzi,2015-03-11,2014-11-19
-3wzd,2015-05-27,2014-09-24
-2wz0,2010-12-08,2009-11-20
-2wzw,2010-07-14,2009-12-03
-1wza,2006-04-11,2005-03-03
-3wzm,2014-11-26,2014-10-01
-7wzm,2023-02-22,2022-02-18
-5wz3,2017-03-08,2017-01-16
-6wzv,2021-04-14,2020-05-14
-7wzc,2023-02-22,2022-02-17
-7wzx,2022-12-28,2022-02-19
-4wz6,2015-11-11,2014-11-18
-4wzd,2015-06-10,2014-11-19
-6wz0,2020-09-16,2020-05-13
-5wzq,2017-06-07,2017-01-18
-5wz1,2017-03-08,2017-01-16
-4wzv,2015-08-26,2014-11-20
-2wz6,2010-12-08,2009-11-23
-5wz2,2017-03-08,2017-01-16
-5wzt,2018-01-24,2017-01-18
-2wze,2010-08-25,2009-11-27
-5wzr,2017-06-07,2017-01-18
-4wzu,2014-12-03,2014-11-20
-4wzl,2014-12-17,2014-11-20
-6wz4,2020-10-14,2020-05-13
-2wz7,2010-09-15,2009-11-24
-7wza,2023-02-22,2022-02-17
-1wzk,2005-03-22,2005-03-06
-2wzy,2010-03-02,2009-12-03
-4wzo,2015-06-10,2014-11-20
-4wzh,2015-05-13,2014-11-19
-4wze,2014-12-17,2014-11-19
-3wzi,2015-07-15,2014-09-25
-4wzz,2014-12-17,2014-11-20
-3wzj,2015-02-11,2014-09-29
-5wzz,2017-08-16,2017-01-19
-4wzt,2014-12-17,2014-11-20
-3wze,2015-05-27,2014-09-24
-4wz5,2015-08-05,2014-11-18
-4wzq,2015-05-06,2014-11-20
-3wzx,2015-10-14,2014-10-08
-1wzm,2005-03-22,2005-03-06
-6wzp,2021-05-19,2020-05-14
-2wz5,2010-12-08,2009-11-23
-6wza,2020-09-16,2020-05-13
-3wzo,2015-02-18,2014-10-01
-6wzw,2021-04-07,2020-05-14
-6wzx,2020-06-17,2020-05-14
-6wzc,2020-09-16,2020-05-13
-2wzx,2010-01-12,2009-12-03
-5wzy,2017-04-05,2017-01-19
-4wz9,2015-06-17,2014-11-19
-7wz3,2023-02-22,2022-02-16
-1wzy,2005-12-20,2005-03-10
-1wzc,2006-02-28,2005-03-04
-1wzl,2005-03-22,2005-03-06
-2wzf,2009-12-08,2009-11-29
-6wz2,2020-09-16,2020-05-13
-5wzu,2018-01-24,2017-01-18
-6wz6,2020-10-14,2020-05-13
-3wz7,2015-08-05,2014-09-19
-7wzf,2023-02-22,2022-02-18
-3wzu,2015-01-14,2014-10-07
-8wzq,2024-04-17,2023-11-02
-3wz8,2015-08-05,2014-09-19
-7wzl,2023-02-22,2022-02-18
-3wzy,2015-10-14,2014-10-08
-6wzu,2020-05-27,2020-05-14
-4wz8,2014-12-10,2014-11-18
-1wzi,2006-03-14,2005-03-05
-3wzq,2015-02-18,2014-10-01
-2wzh,2010-01-26,2009-11-30
-6wz1,2020-09-16,2020-05-13
-2wzv,2010-07-14,2009-12-03
-4wzc,2016-02-10,2014-11-19
-1wzg,2006-02-21,2005-03-04
-2wz8,2010-07-14,2009-11-25
-3wzk,2015-02-11,2014-09-29
-2wzz,2010-01-12,2009-12-03
-5wze,2018-01-17,2017-01-17
-5wzo,2018-01-24,2017-01-18
-2wzd,2010-04-14,2009-11-27
-7wz2,2022-07-20,2022-02-16
-2wza,2010-02-16,2009-11-26
-4wzy,2015-02-11,2014-11-20
-4wzx,2015-06-03,2014-11-20
-3wzp,2015-02-18,2014-10-01
-1wzo,2006-02-21,2005-03-08
-2wzm,2010-02-16,2009-11-30
-3wzh,2015-07-15,2014-09-25
-7wzb,2023-03-01,2022-02-17
-4wz4,2015-08-05,2014-11-18
-6wzb,2021-02-17,2020-05-13
-5wzp,2017-06-07,2017-01-18
-7wz5,2023-02-08,2022-02-17
-2wzb,2010-04-14,2009-11-27
-6wzk,2020-11-25,2020-05-14
-4wzk,2014-12-17,2014-11-20
-1wz1,2006-01-31,2005-02-21
-5wzs,2018-01-24,2017-01-18
-5wzx,2018-01-03,2017-01-19
-3wzn,2015-02-18,2014-10-01
-2wzs,2009-12-29,2009-12-02
-6wz3,2020-09-16,2020-05-13
-7wz1,2022-07-27,2022-02-16
-3wz6,2015-08-05,2014-09-19
-8wzp,2024-04-17,2023-11-02
-5wzw,2018-01-24,2017-01-18
-3wz1,2014-11-19,2014-09-12
-3wzv,2015-10-14,2014-10-07
-1wze,2006-03-14,2005-03-04
-1wzn,2006-03-14,2005-03-08
-2wzn,2010-11-03,2009-12-01
-5wzv,2018-01-24,2017-01-18
-2wzc,2010-04-14,2009-11-27
-3wzw,2015-10-14,2014-10-08
-7wzz,2023-05-03,2022-02-20
-5wzm,2018-01-24,2017-01-18
-7wzv,2022-12-28,2022-02-19
-7wz0,2022-04-27,2022-02-16
-1wzf,2006-02-21,2005-03-04
-7wzn,2023-02-22,2022-02-18
-6wzt,2021-03-10,2020-05-14
-7wzg,2023-02-22,2022-02-18
-4lsr,2013-08-21,2013-07-23
-3lsi,2010-08-25,2010-02-12
-5ls2,2017-08-23,2016-08-22
-7lsn,2022-02-23,2021-02-18
-4ls0,2014-07-23,2013-07-21
-5lsm,2016-09-14,2016-09-04
-5ls4,2017-07-05,2016-08-22
-1lss,2002-07-03,2002-05-18
-4lse,2013-10-23,2013-07-22
-7lsz,2021-03-03,2021-02-18
-1lsu,2002-07-03,2002-05-18
-7ls2,2021-11-03,2021-02-17
-6ls5,2020-05-27,2020-01-17
-7ls1,2021-11-03,2021-02-17
-4lss,2013-08-21,2013-07-23
-4ls1,2014-07-23,2013-07-21
-7lsq,2022-01-12,2021-02-18
-4lsl,2013-12-25,2013-07-22
-1lsv,2002-11-20,2002-05-19
-7lsv,2022-01-26,2021-02-18
-6lsv,2021-02-10,2020-01-20
-1lst,1994-06-22,1993-02-25
-6ls1,2021-01-20,2020-01-16
-5lsc,2016-11-09,2016-08-25
-3lst,2010-03-02,2010-02-12
-4ls5,2014-04-02,2013-07-22
-7lss,2021-03-17,2021-02-18
-4lsu,2013-08-21,2013-07-23
-5lsq,2017-04-19,2016-09-05
-4lsn,2013-12-25,2013-07-22
-1lsx,2002-11-20,2002-05-20
-6lsg,2020-04-29,2020-01-17
-4lsx,2013-09-04,2013-07-23
-3lsu,2011-02-23,2010-02-12
-4lsm,2013-08-07,2013-07-22
-1lsp,1996-01-01,1995-02-09
-5lsx,2016-10-05,2016-09-05
-6ls0,2021-01-20,2020-01-16
-7ls3,2021-08-25,2021-02-17
-7ls0,2021-11-24,2021-02-17
-5lso,2016-10-26,2016-09-05
-4ls3,2014-01-22,2013-07-22
-1ls1,2002-11-16,2002-05-16
-4lsi,2013-10-23,2013-07-22
-7lsa,2021-07-14,2021-02-18
-4lsq,2013-08-21,2013-07-23
-1ls6,2003-08-05,2002-05-17
-4lsc,2013-09-04,2013-07-22
-3lsj,2010-08-04,2010-02-12
-4lsv,2013-08-21,2013-07-23
-6lsa,2020-06-17,2020-01-17
-5ls1,2017-08-02,2016-08-22
-5lsg,2017-08-09,2016-08-26
-5ls6,2017-02-22,2016-08-22
-4ls2,2014-07-23,2013-07-21
-3lsn,2010-03-02,2010-02-12
-3ls7,2011-02-23,2010-02-12
-5lsp,2017-09-13,2016-09-05
-7lsk,2022-02-23,2021-02-18
-3lsx,2011-03-16,2010-02-13
-4ls7,2014-04-02,2013-07-22
-6lsz,2021-01-27,2020-01-20
-7lsd,2022-02-23,2021-02-18
-3lsk,2010-08-25,2010-02-12
-4lsa,2013-09-04,2013-07-22
-4lsk,2014-08-06,2013-07-22
-4ls9,2014-07-16,2013-07-22
-3lsw,2010-03-16,2010-02-13
-4lsj,2014-01-29,2013-07-22
-3lsh,2010-08-25,2010-02-12
-6lsd,2020-11-18,2020-01-17
-4lsp,2013-09-04,2013-07-23
-5lst,2017-07-05,2016-09-05
-7lsj,2022-02-23,2021-02-18
-6ls8,2020-05-06,2020-01-17
-3lse,2010-05-05,2010-02-12
-5lsf,2018-08-01,2016-08-26
-3lsm,2010-08-25,2010-02-12
-5lse,2016-11-09,2016-08-25
-5ls7,2017-09-13,2016-08-22
-6lsm,2021-01-20,2020-01-17
-7ls9,2021-03-17,2021-02-17
-6ls9,2020-06-17,2020-01-17
-3ls6,2010-09-15,2010-02-12
-7lsc,2022-02-23,2021-02-18
-6ls4,2021-01-20,2020-01-17
-5lsu,2016-10-05,2016-09-05
-5lsz,2016-10-05,2016-09-05
-3lsz,2010-03-23,2010-02-14
-3ls1,2010-03-31,2010-02-12
-2lsv,2013-05-22,2012-05-07
-1ls3,2003-02-04,2002-05-16
-3ls8,2010-03-23,2010-02-12
-1lsj,2004-02-03,2002-05-17
-7lst,2021-07-14,2021-02-18
-7lsr,2021-07-14,2021-02-18
-1lsw,2002-11-20,2002-05-20
-3lsl,2010-03-16,2010-02-12
-1lsl,2002-12-18,2002-05-17
-6ls6,2020-11-18,2020-01-17
-6lsn,2021-01-20,2020-01-17
-7lsf,2021-04-07,2021-02-18
-3ls9,2010-07-21,2010-02-12
-3lsy,2010-06-16,2010-02-14
-5lsv,2017-01-18,2016-09-05
-5lsh,2017-06-21,2016-08-26
-1lso,2004-02-03,2002-05-17
-6ls3,2021-01-20,2020-01-16
-7lsl,2022-02-23,2021-02-18
-6lss,2020-08-26,2020-01-20
-7lsm,2021-12-29,2021-02-18
-3lsq,2010-03-02,2010-02-12
-4lsh,2013-10-23,2013-07-22
-3lsf,2010-03-16,2010-02-12
-4lsb,2013-08-14,2013-07-22
-5ls0,2017-09-13,2016-08-22
-1ls5,2002-06-12,2002-05-16
-3lsc,2010-07-21,2010-02-12
-5lsy,2016-10-12,2016-09-05
-3lsb,2010-07-21,2010-02-12
-6lse,2020-04-29,2020-01-17
-6lsr,2020-08-26,2020-01-20
-7lsu,2021-07-14,2021-02-18
-4lst,2013-08-21,2013-07-23
-5lsa,2016-09-07,2016-08-24
-4ls8,2014-04-02,2013-07-22
-7ls4,2021-08-25,2021-02-17
-6lsb,2020-11-18,2020-01-17
-5lss,2016-10-05,2016-09-05
-5ls9,2016-11-30,2016-08-23
-6lsf,2020-04-29,2020-01-17
-1ls9,2002-12-25,2002-05-17
-4lsy,2014-02-05,2013-07-23
-1lsz,1995-01-26,1994-09-27
-6lsh,2020-04-29,2020-01-17
-4ls6,2014-04-02,2013-07-22
-4lsg,2013-07-31,2013-07-22
-3ls4,2010-06-02,2010-02-12
-3lss,2010-03-02,2010-02-12
-5ls3,2017-03-15,2016-08-22
-5wp1,2018-08-08,2017-08-03
-7wpd,2022-03-16,2022-01-23
-2wpw,2009-12-29,2009-08-11
-4wpz,2015-04-22,2014-10-21
-5wpj,2018-04-25,2017-08-04
-4wpo,2015-01-28,2014-10-20
-5wp2,2018-05-30,2017-08-03
-5wpq,2017-10-18,2017-08-07
-6wpt,2020-05-27,2020-04-27
-8wpg,2023-11-22,2023-10-10
-1wp4,2005-08-30,2004-08-30
-6wpp,2020-08-26,2020-04-27
-6wp6,2020-10-07,2020-04-26
-7wps,2022-05-25,2022-01-24
-8wp5,2024-05-22,2023-10-08
-6wp4,2020-09-30,2020-04-26
-3wpk,2014-07-30,2014-01-12
-3wpc,2015-02-11,2014-01-11
-5wpx,2018-02-07,2016-11-21
-7wp9,2022-03-09,2022-01-23
-3wpn,2015-01-21,2014-01-14
-5wpy,2017-11-29,2016-11-21
-5wpn,2017-12-06,2017-08-05
-4wpf,2015-01-14,2014-10-18
-8wpe,2023-11-29,2023-10-10
-7wpn,2022-04-27,2022-01-24
-2wpc,2010-10-13,2009-08-05
-7wpy,2023-02-01,2022-01-24
-4wph,2015-06-17,2014-10-18
-7wpx,2022-04-27,2022-01-24
-3wph,2015-02-11,2014-01-11
-7wpg,2023-01-25,2022-01-23
-7wp0,2022-07-20,2022-01-22
-2wpn,2010-01-12,2009-08-07
-7wpa,2022-03-09,2022-01-23
-4wp8,2015-09-02,2014-10-17
-1wpn,2004-11-23,2004-09-09
-6wpe,2021-03-10,2020-04-27
-5wph,2018-10-10,2017-08-04
-2wp6,2010-10-13,2009-08-03
-2wp4,2010-09-01,2009-08-03
-2wpk,2009-12-22,2009-08-06
-3wpg,2015-02-11,2014-01-11
-5wpz,2017-02-15,2016-11-22
-6wpr,2020-06-10,2020-04-27
-2wpb,2010-08-25,2009-08-03
-4wpk,2015-07-15,2014-10-20
-4wpn,2015-02-11,2014-10-20
-1wp6,2004-11-30,2004-08-31
-3wpf,2015-02-11,2014-01-11
-1wpy,2005-10-04,2004-09-17
-4wpa,2015-09-02,2014-10-17
-3wpd,2015-02-11,2014-01-11
-1wpw,2004-10-05,2004-09-14
-7wpc,2022-03-09,2022-01-23
-7wpz,2022-11-30,2022-01-24
-7wp2,2022-07-20,2022-01-22
-5wpt,2017-10-18,2017-08-07
-3wpl,2014-07-30,2014-01-12
-7wp8,2023-03-08,2022-01-23
-6wpg,2020-08-12,2020-04-27
-2wpd,2010-07-07,2009-08-05
-7wpq,2022-05-25,2022-01-24
-5wpv,2017-10-18,2017-08-07
-1wpk,2005-09-13,2004-09-07
-8wpu,2023-11-22,2023-10-10
-7wpb,2022-03-09,2022-01-23
-3wp6,2014-03-19,2014-01-09
-7wpu,2023-01-25,2022-01-24
-6wpj,2020-11-04,2020-04-27
-1wpc,2004-11-30,2004-09-01
-3wpb,2015-02-11,2014-01-11
-5wp5,2017-11-15,2017-08-03
-7wpm,2022-04-27,2022-01-24
-4wp7,2015-02-11,2014-10-17
-6wpq,2020-08-19,2020-04-27
-5wps,2018-04-04,2017-08-07
-4wpu,2015-11-04,2014-10-21
-4wpv,2015-11-04,2014-10-21
-7wp3,2022-06-15,2022-01-22
-2wph,2009-12-22,2009-08-06
-7wpe,2022-03-23,2022-01-23
-7wp5,2022-07-13,2022-01-22
-3wpi,2015-02-11,2014-01-11
-7wp1,2022-07-13,2022-01-22
-5wpu,2018-03-07,2017-08-07
-6wpf,2020-11-04,2020-04-27
-6wph,2020-11-04,2020-04-27
-6wp9,2020-07-22,2020-04-26
-2wpm,2009-12-22,2009-08-06
-6wp8,2020-07-29,2020-04-26
-2wpe,2010-10-13,2009-08-06
-7wpt,2022-04-27,2022-01-24
-5wpm,2018-01-03,2017-08-05
-3wpm,2014-04-30,2014-01-14
-7wpp,2022-05-25,2022-01-24
-7wpk,2022-04-27,2022-01-24
-2wp1,2009-09-22,2009-08-02
-1wpv,2005-03-15,2004-09-14
-6wp2,2020-08-19,2020-04-26
-8wpk,2023-11-29,2023-10-10
-2wpx,2009-12-29,2009-08-11
-5wpl,2018-01-03,2017-08-05
-7wpf,2022-03-16,2022-01-23
-2wpj,2009-12-22,2009-08-06
-2wpf,2010-10-13,2009-08-06
-5wp9,2018-06-20,2017-08-03
-2wpl,2009-12-22,2009-08-06
-1wpg,2004-10-05,2004-09-02
-5wp4,2017-11-15,2017-08-03
-8wp0,2024-03-13,2023-10-08
-7wpl,2022-04-27,2022-01-24
-3wpe,2015-02-11,2014-01-11
-7wpi,2022-04-27,2022-01-24
-6wp3,2020-10-07,2020-04-26
-6wp5,2020-09-30,2020-04-26
-2wp5,2010-10-13,2009-08-03
-5wpp,2018-03-07,2017-08-07
-2wp0,2009-11-17,2009-07-31
-6wpu,2020-06-17,2020-04-27
-7wph,2022-03-30,2022-01-23
-6wpm,2021-05-12,2020-04-27
-1wpp,2004-11-23,2004-09-09
-1wpu,2005-08-30,2004-09-13
-5wpb,2017-08-23,2017-08-04
-2wpv,2010-01-26,2009-08-11
-1wpl,2004-09-28,2004-09-08
-4wpl,2015-07-15,2014-10-20
-1wpq,2006-04-11,2004-09-10
-2wpi,2009-12-22,2009-08-06
-6wpl,2020-07-01,2020-04-27
-7wpo,2022-11-30,2022-01-24
-2wpa,2010-02-23,2009-08-03
-7wpr,2022-05-25,2022-01-24
-5wpr,2018-03-07,2017-08-07
-1wpx,2005-03-01,2004-09-14
-8wpf,2023-11-29,2023-10-10
-4wpd,2015-02-18,2014-10-17
-7wp6,2023-03-01,2022-01-23
-6wps,2020-05-27,2020-04-27
-2wpo,1999-08-04,1998-08-04
-2wp9,2010-08-25,2009-08-03
-4wp9,2015-09-02,2014-10-17
-5xtl,2018-04-25,2017-06-20
-1xtr,2005-03-08,2004-10-24
-4xt0,2016-02-03,2015-01-22
-1xtv,2005-02-08,2004-10-24
-5xts,2017-12-27,2017-06-20
-5xtc,2017-08-30,2017-06-19
-2xt3,2011-12-14,2010-10-04
-5xt6,2017-12-20,2017-06-17
-1xtl,2005-10-04,2004-10-22
-7xtw,2023-03-29,2022-05-18
-5xti,2017-09-13,2017-06-19
-7xtn,2022-09-28,2022-05-17
-6xta,2020-10-28,2020-01-15
-7xt2,2023-03-29,2022-05-15
-4xtz,2015-09-02,2015-01-24
-6xt0,2021-02-03,2020-07-16
-4xt2,2015-12-09,2015-01-22
-2xtz,2011-02-16,2010-10-13
-7xtu,2023-03-29,2022-05-18
-7xtc,2022-07-27,2022-05-16
-5xtx,2018-06-27,2017-06-21
-6xtl,2021-01-27,2020-01-16
-7xtd,2022-09-07,2022-05-16
-6xtq,2021-01-27,2020-01-16
-4xtx,2015-09-02,2015-01-24
-5xtt,2018-06-27,2017-06-20
-6xty,2020-05-27,2020-01-16
-7xta,2022-07-27,2022-05-16
-4xt4,2016-02-24,2015-01-22
-6xt2,2020-08-05,2020-07-16
-6xte,2020-04-22,2020-01-16
-5xtv,2018-04-25,2017-06-21
-4xty,2015-09-02,2015-01-24
-7xt7,2022-10-12,2022-05-16
-5xt2,2018-05-23,2017-06-16
-5xtk,2018-06-20,2017-06-19
-6xts,2021-01-27,2020-01-16
-1xtp,2004-11-09,2004-10-22
-7xtg,2023-06-07,2022-05-17
-7xtz,2022-07-20,2022-05-18
-5xto,2017-09-13,2017-06-20
-4xtm,2016-01-27,2015-01-23
-7xtx,2023-05-24,2022-05-18
-4xtr,2015-03-18,2015-01-23
-5xtu,2018-10-10,2017-06-21
-1xt6,2004-12-21,2004-10-21
-2xtj,2010-11-03,2010-10-10
-4xtt,2015-05-20,2015-01-24
-7xtt,2023-03-29,2022-05-18
-6xtn,2021-01-27,2020-01-16
-7xto,2023-01-25,2022-05-17
-4xtq,2015-12-09,2015-01-23
-5xtm,2018-02-07,2017-06-20
-2xto,2010-10-20,2010-10-11
-2xtl,2011-07-06,2010-10-11
-6xt3,2021-08-11,2020-07-17
-4xt7,2016-02-24,2015-01-23
-5xt4,2018-06-20,2017-06-16
-2xt6,2011-06-15,2010-10-05
-5xt5,2017-12-20,2017-06-17
-4xtl,2015-04-01,2015-01-23
-7xtj,2023-03-15,2022-05-17
-6xtg,2021-01-27,2020-01-16
-1xtb,2005-03-22,2004-10-21
-6xtz,2020-07-29,2020-01-16
-5xt3,2018-01-31,2017-06-16
-4xtj,2015-04-08,2015-01-23
-5xtn,2017-09-13,2017-06-20
-7xtp,2022-07-27,2022-05-17
-5xtd,2017-08-30,2017-06-19
-4xt6,2016-02-24,2015-01-23
-5xte,2017-08-30,2017-06-19
-4xto,2015-04-01,2015-01-23
-5xtr,2017-09-13,2017-06-20
-1xtt,2005-02-08,2004-10-24
-5xtw,2017-12-27,2017-06-21
-6xtx,2020-05-27,2020-01-16
-5xt0,2018-06-20,2017-06-16
-7xt6,2022-08-31,2022-05-16
-6xtf,2021-07-28,2020-01-16
-6xt1,2021-02-03,2020-07-16
-4xtn,2015-04-01,2015-01-23
-6xto,2021-01-27,2020-01-16
-4xt8,2016-02-24,2015-01-23
-4xt1,2015-03-04,2015-01-22
-7xt4,2022-11-09,2022-05-16
-4xtp,2016-01-27,2015-01-23
-2xtn,2010-10-20,2010-10-11
-1xtq,2005-03-08,2004-10-24
-7xts,2023-03-29,2022-05-18
-4xt9,2015-08-12,2015-01-23
-4xtd,2015-07-22,2015-01-23
-4xti,2015-07-22,2015-01-23
-1xts,2005-03-08,2004-10-24
-7xtr,2023-03-29,2022-05-18
-7xt9,2022-07-27,2022-05-16
-5xt8,2018-04-18,2017-06-17
-5xtq,2017-09-13,2017-06-20
-4xt3,2015-03-04,2015-01-22
-6xtv,2020-10-07,2020-01-16
-4xtw,2015-09-02,2015-01-24
-4xtv,2015-09-02,2015-01-24
-1xt8,2005-08-23,2004-10-21
-4xtc,2016-03-02,2015-01-23
-6xt6,2020-11-11,2020-07-17
-2xta,2011-06-15,2010-10-05
-2xts,2010-12-08,2010-10-12
-7xti,2022-10-12,2022-05-17
-7xtv,2023-03-29,2022-05-18
-2xtm,2010-10-20,2010-10-11
-7xty,2023-05-17,2022-05-18
-1xtf,2004-12-21,2004-10-21
-5xth,2017-09-13,2017-06-19
-6xtk,2020-05-13,2020-01-16
-5xtg,2017-08-09,2017-06-19
-5xtb,2017-08-30,2017-06-18
-5xtp,2017-09-13,2017-06-20
-4xt5,2016-02-24,2015-01-22
-2xti,2010-12-15,2010-10-10
-2xtb,2011-06-29,2010-10-05
-7xtq,2022-07-06,2022-05-17
-6xtm,2021-01-27,2020-01-16
-2xtt,2010-11-10,2010-10-12
-1xtm,2005-10-04,2004-10-22
-2xtk,2011-10-26,2010-10-11
-1xto,2004-11-09,2004-10-22
-1xt4,2005-03-22,2004-10-21
-4xta,2015-11-11,2015-01-23
-7xt8,2022-07-27,2022-05-16
-6xtr,2021-01-27,2020-01-16
-6xtw,2021-01-27,2020-01-16
-1xtj,2004-12-14,2004-10-22
-1xtg,2004-12-21,2004-10-21
-7xtb,2022-07-27,2022-05-16
-6xtp,2021-01-27,2020-01-16
-1xtu,2005-02-08,2004-10-24
-4xtu,2016-01-13,2015-01-24
-1dge,1994-09-30,1994-06-29
-1dgh,2000-02-17,1999-11-24
-7dg2,2021-05-26,2020-11-10
-5dga,2016-06-08,2015-08-27
-6dgx,2018-12-26,2018-05-18
-8dg0,2022-12-07,2022-06-23
-3dg3,2009-03-03,2008-06-12
-8dg1,2022-12-07,2022-06-23
-6dgp,2019-05-22,2018-05-17
-8dgs,2023-07-05,2022-06-24
-2dg1,2006-12-12,2006-03-07
-8dgm,2023-06-07,2022-06-24
-5dgc,2016-03-09,2015-08-27
-3dgm,2009-06-30,2008-06-13
-8dg8,2023-02-22,2022-06-23
-1dg8,2000-03-09,1999-11-23
-6dg8,2018-11-07,2018-05-17
-1dg6,2000-01-26,1999-11-23
-1dgj,2000-03-22,1999-11-24
-5dgq,2015-12-09,2015-08-28
-4dgn,2012-08-01,2012-01-26
-7dgb,2021-11-24,2020-11-11
-5dgf,2016-12-14,2015-08-27
-7dg7,2021-09-29,2020-11-11
-6dgo,2019-05-22,2018-05-17
-8dgy,2022-07-06,2022-06-24
-8dge,2023-05-24,2022-06-23
-4dgc,2012-02-08,2012-01-25
-6dg5,2019-01-16,2018-05-16
-2dgm,2006-06-20,2006-03-14
-7dgq,2022-05-18,2020-11-12
-4dg9,2012-05-02,2012-01-25
-5dg3,2015-09-16,2015-08-27
-8dgn,2023-06-07,2022-06-24
-5dgm,2016-07-13,2015-08-28
-2dg4,2006-04-25,2006-03-08
-1dgd,1994-09-30,1994-06-29
-6dgy,2018-12-26,2018-05-18
-5dg2,2016-09-14,2015-08-27
-5dgr,2015-12-09,2015-08-28
-8dg9,2023-02-22,2022-06-23
-6dgq,2019-05-22,2018-05-17
-7dgj,2021-02-17,2020-11-12
-6dge,2018-07-25,2018-05-17
-5dge,2017-01-25,2015-08-27
-4dgm,2012-08-01,2012-01-26
-5dgt,2015-09-23,2015-08-28
-3dgl,2009-06-30,2008-06-13
-5dgb,2016-06-08,2015-08-27
-3dgn,2009-06-30,2008-06-13
-5dg0,2015-10-14,2015-08-27
-4dg0,2012-06-06,2012-01-24
-8dgo,2023-06-07,2022-06-24
-7dgr,2022-05-18,2020-11-12
-8dgc,2022-08-03,2022-06-23
-5dgn,2015-09-30,2015-08-28
-6dgt,2018-08-01,2018-05-18
-7dg0,2021-11-17,2020-11-10
-4dg1,2012-06-20,2012-01-24
-5dgj,2016-02-10,2015-08-27
-7dgk,2021-02-17,2020-11-12
-1dgg,2000-02-17,1999-11-24
-4dg8,2012-05-02,2012-01-25
-3dg6,2009-03-03,2008-06-12
-6dgr,2019-05-22,2018-05-18
-3dgr,2009-08-18,2008-06-15
-3dg8,2009-01-27,2008-06-13
-4dgz,2012-02-08,2012-01-27
-2dgn,2006-09-15,2006-03-15
-1dgb,2000-02-11,1999-11-23
-6dgs,2019-05-29,2018-05-18
-5dgk,2016-08-24,2015-08-27
-7dgo,2021-02-17,2020-11-12
-4dgu,2012-02-15,2012-01-26
-2dgk,2006-06-20,2006-03-14
-4dgv,2012-05-23,2012-01-26
-1dgf,2000-02-11,1999-11-24
-5dgx,2015-09-16,2015-08-28
-6dg7,2018-11-07,2018-05-17
-6dgm,2018-06-06,2018-05-17
-4dgg,2012-10-10,2012-01-25
-1dgm,2000-11-29,1999-11-24
-3dgc,2008-07-15,2008-06-13
-8dgb,2022-07-13,2022-06-23
-8dgp,2023-06-07,2022-06-24
-8dgf,2022-08-03,2022-06-23
-8dg5,2022-11-16,2022-06-23
-1dg5,2000-03-09,1999-11-23
-4dg4,2012-09-12,2012-01-24
-7dgs,2022-05-18,2020-11-12
-3dga,2009-01-27,2008-06-13
-5dgz,2015-10-28,2015-08-29
-5dgh,2016-08-10,2015-08-27
-5dgd,2015-09-16,2015-08-27
-7dg9,2021-09-29,2020-11-11
-1dgk,2000-03-08,1999-11-24
-1dg1,1999-12-01,1999-11-22
-4dgt,2012-02-08,2012-01-26
-7dg4,2021-11-10,2020-11-10
-5dg1,2016-09-14,2015-08-27
-8dg6,2022-11-02,2022-06-23
-7dgz,2022-05-18,2020-11-12
-4dgi,2012-10-31,2012-01-26
-4dgh,2012-02-08,2012-01-25
-3dgv,2008-07-22,2008-06-16
-4dgb,2012-02-08,2012-01-25
-5dgs,2016-07-13,2015-08-28
-7dgc,2022-02-02,2020-11-11
-6dgj,2019-01-02,2018-05-17
-1dgz,1999-12-08,1999-11-27
-5dgi,2016-08-10,2015-08-27
-4dgl,2012-05-02,2012-01-26
-4dg3,2013-02-13,2012-01-24
-3dgz,2009-06-16,2008-06-16
-1dg7,2000-03-09,1999-11-23
-5dgv,2016-12-14,2015-08-28
-4dgr,2012-05-16,2012-01-26
-8dg2,2022-12-07,2022-06-23
-2dg3,2006-04-25,2006-03-08
-7dgm,2021-02-17,2020-11-12
-5dgw,2015-10-28,2015-08-28
-3dgi,2009-06-16,2008-06-13
-5dgu,2015-10-28,2015-08-28
-6dgf,2019-02-13,2018-05-17
-5dg8,2016-06-08,2015-08-27
-5dg6,2016-02-10,2015-08-27
-2dge,2006-07-04,2006-03-11
-6dg3,2019-05-22,2018-05-16
-3dg1,2008-07-01,2008-06-12
-8dgt,2023-07-05,2022-06-24
-6dg0,2019-08-21,2018-05-16
-3dgt,2008-09-02,2008-06-16
-2dg9,2006-04-25,2006-03-09
-3dgh,2009-06-16,2008-06-13
-5dg5,2016-08-31,2015-08-27
-6dgd,2018-09-05,2018-05-17
-7dge,2021-09-22,2020-11-11
-7dgh,2021-11-24,2020-11-11
-3dgd,2008-07-22,2008-06-13
-3dgo,2009-06-30,2008-06-13
-7dgn,2021-02-17,2020-11-12
-8dgd,2023-03-01,2022-06-23
-8dgz,2023-07-05,2022-06-24
-3dgg,2008-08-12,2008-06-13
-3dgj,2008-07-01,2008-06-13
-7dgg,2021-11-24,2020-11-11
-1dgs,2000-11-27,1999-11-25
-3dg7,2009-03-03,2008-06-12
-1dgp,2001-02-07,1999-11-24
-4dg6,2012-06-13,2012-01-25
-6dgl,2019-05-22,2018-05-17
-3dge,2009-07-07,2008-06-13
-8dg7,2022-11-16,2022-06-23
-2dgl,2006-06-20,2006-03-14
-7dgi,2021-11-24,2020-11-11
-6dgz,2018-12-26,2018-05-18
-8dga,2022-11-16,2022-06-23
-5dg7,2016-06-08,2015-08-27
-5dg9,2016-06-08,2015-08-27
-3dgb,2009-03-03,2008-06-13
-1dgl,1999-06-01,1998-02-10
-7dgl,2021-02-17,2020-11-12
-8dgg,2022-08-17,2022-06-23
-7dgf,2021-11-24,2020-11-11
-3dgq,2009-04-21,2008-06-15
-2dg5,2006-04-18,2006-03-08
-3dgy,2009-06-16,2008-06-16
-6dgi,2018-05-30,2018-05-17
-4dgw,2012-05-02,2012-01-26
-7nm5,2021-09-22,2021-02-23
-1nm6,2003-09-02,2003-01-09
-6nm0,2020-01-15,2019-01-10
-3nm3,2010-11-10,2010-06-21
-6nm5,2019-07-24,2019-01-10
-7nma,2022-01-12,2021-02-23
-7nmw,2022-01-12,2021-02-23
-4nmq,2014-10-01,2013-11-15
-6nme,2019-06-12,2019-01-10
-7nm4,2021-09-22,2021-02-23
-7nmf,2022-09-07,2021-02-23
-5nmw,2018-03-14,2017-04-07
-5nm3,2018-04-18,2017-04-05
-6nmk,2020-01-15,2019-01-11
-3nm5,2010-11-24,2010-06-21
-3nmn,2010-08-25,2010-06-22
-1nmo,2004-01-20,2003-01-10
-7nm8,2021-06-30,2021-02-23
-7nm9,2021-06-09,2021-02-23
-2nmv,2007-01-16,2006-10-23
-2nmn,2007-03-06,2006-10-23
-7nmh,2021-09-15,2021-02-23
-5nm1,2018-02-14,2017-04-05
-1nmd,2003-02-04,2003-01-09
-3nmq,2010-12-22,2010-06-22
-2nmx,2007-04-24,2006-10-23
-7nm6,2022-03-02,2021-02-23
-5nmg,2017-11-15,2017-04-05
-7nmj,2021-04-07,2021-02-23
-1nm1,2003-01-21,2003-01-08
-4nmn,2014-01-29,2013-11-15
-5nm4,2017-09-27,2017-04-05
-7nme,2022-09-07,2021-02-23
-3nmb,2010-08-18,2010-06-22
-5nmx,2018-03-14,2017-04-07
-5nmy,2018-05-16,2017-04-07
-4nmd,2014-02-19,2013-11-14
-3nma,2011-05-25,2010-06-22
-5nmi,2017-06-14,2017-04-05
-7nmg,2022-09-07,2021-02-23
-6nm4,2019-02-13,2019-01-10
-2nm3,2007-09-04,2006-10-20
-3nmi,2010-11-24,2010-06-22
-1nmc,1998-09-23,1997-12-21
-1nm0,2004-01-20,2003-01-08
-1nmy,2003-03-18,2003-01-12
-7nm0,2021-06-30,2021-02-23
-5nmc,2017-05-03,2017-04-05
-5nm0,2017-06-07,2017-04-05
-6nmp,2019-03-13,2019-01-11
-7nm2,2021-09-22,2021-02-23
-1nma,1995-09-15,1994-05-06
-5nmr,2017-12-06,2017-04-07
-6nmd,2019-06-12,2019-01-10
-4nmc,2014-02-19,2013-11-14
-5nmj,2018-02-14,2017-04-06
-5nmn,2018-01-24,2017-04-06
-6nmo,2020-01-15,2019-01-11
-3nm6,2010-11-24,2010-06-21
-4nmk,2014-11-19,2013-11-15
-4nm2,2014-01-22,2013-11-14
-5nmm,2018-02-21,2017-04-06
-1nmm,2003-01-21,2003-01-10
-7nmd,2022-09-07,2021-02-23
-1nmk,2003-04-01,2003-01-10
-4nmx,2013-12-04,2013-11-15
-6nml,2020-01-15,2019-01-11
-1nme,2003-03-11,2003-01-09
-4nm6,2013-12-18,2013-11-14
-4nm8,2013-12-25,2013-11-14
-3nms,2010-08-04,2010-06-22
-1nm9,2004-01-20,2003-01-09
-6nm6,2019-02-27,2019-01-10
-3nm7,2010-10-06,2010-06-22
-6nm9,2019-06-12,2019-01-10
-4nmf,2014-02-19,2013-11-14
-1nmb,1995-09-15,1995-01-17
-6nmi,2019-03-13,2019-01-10
-6nmm,2020-01-15,2019-01-11
-3nmh,2010-08-25,2010-06-22
-4nmt,2014-10-01,2013-11-15
-7nmi,2022-03-02,2021-02-23
-3nm0,2011-01-19,2010-06-21
-5nme,2017-11-15,2017-04-05
-4nms,2014-10-01,2013-11-15
-3nmm,2010-07-14,2010-06-22
-1nmu,2003-02-18,2003-01-10
-5nm8,2017-09-13,2017-04-05
-4nm0,2014-03-26,2013-11-14
-3nmj,2010-11-24,2010-06-22
-6nmb,2019-03-06,2019-01-10
-1nm2,2003-01-21,2003-01-08
-1nms,2003-03-11,2003-01-10
-4nme,2014-02-19,2013-11-14
-5nmh,2017-11-15,2017-04-05
-5nmk,2017-11-15,2017-04-06
-7nmp,2021-07-21,2021-02-23
-5nml,2017-06-07,2017-04-06
-4nmj,2014-11-19,2013-11-15
-5nm2,2017-09-27,2017-04-05
-4nmp,2014-10-01,2013-11-15
-6nma,2019-06-12,2019-01-10
-2nmp,2006-11-07,2006-10-23
-4nm9,2014-02-19,2013-11-14
-1nmi,2003-02-04,2003-01-10
-6nmy,2020-01-22,2019-01-13
-4nm3,2014-03-26,2013-11-14
-6nm8,2019-02-20,2019-01-10
-6nmn,2020-01-15,2019-01-11
-3nmr,2010-10-27,2010-06-22
-3nmt,2010-08-25,2010-06-22
-4nmm,2014-06-04,2013-11-15
-5nm9,2017-11-15,2017-04-05
-6nmc,2019-06-12,2019-01-10
-7nm3,2021-06-09,2021-02-23
-4nmy,2013-12-04,2013-11-15
-3nmk,2010-11-24,2010-06-22
-4nmb,2014-02-19,2013-11-14
-4nmr,2014-10-01,2013-11-15
-4nmz,2013-12-11,2013-11-15
-1nml,2004-01-13,2003-01-10
-3nml,2010-07-14,2010-06-22
-3nm8,2010-11-17,2010-06-22
-1nm5,2004-01-13,2003-01-09
-6nmz,2020-01-22,2019-01-14
-2nmt,1999-01-06,1998-07-14
-1nmx,2003-03-18,2003-01-12
-6nm7,2019-02-20,2019-01-10
-5nm5,2017-09-27,2017-04-05
-7nmk,2021-09-22,2021-02-23
-4nm7,2014-03-26,2013-11-14
-2nmb,1998-11-04,1998-10-29
-4nmh,2014-03-26,2013-11-15
-7nm1,2021-06-09,2021-02-23
-1nmp,2004-01-20,2003-01-10
-2nmz,2007-03-13,2006-10-23
-3nmp,2010-08-25,2010-06-22
-3nm1,2010-11-10,2010-06-21
-7nml,2022-03-02,2021-02-23
-4nm1,2014-01-22,2013-11-14
-5nma,2017-05-24,2017-04-05
-3nmu,2011-05-25,2010-06-22
-5nmp,2018-05-16,2017-04-06
-2nmy,2007-03-13,2006-10-23
-1nmq,2003-03-11,2003-01-10
-6nmx,2019-03-13,2019-01-12
-7nmu,2021-03-10,2021-02-23
-5nm7,2018-02-14,2017-04-05
-4nmu,2013-12-18,2013-11-15
-7nmx,2022-01-12,2021-02-23
-5nmf,2017-11-15,2017-04-05
-4nmv,2014-10-01,2013-11-15
-5nmb,2017-05-24,2017-04-05
-4nm5,2014-03-26,2013-11-14
-4nma,2014-02-19,2013-11-14
-2nmo,2007-03-06,2006-10-23
-6nmq,2019-04-24,2019-01-11
-3nmv,2010-08-25,2010-06-22
-6nmf,2019-03-13,2019-01-10
-5nmt,2017-11-29,2017-04-07
-4nmo,2014-10-01,2013-11-15
-2nm2,2007-09-04,2006-10-20
-1nmz,2003-03-18,2003-01-12
-4nhy,2014-11-19,2013-11-05
-1nhz,2003-05-06,2002-12-20
-6nhp,2020-04-15,2018-12-23
-6nh8,2019-03-13,2018-12-21
-6nhh,2019-06-19,2018-12-21
-5nhl,2017-04-19,2017-03-21
-3nh9,2010-08-25,2010-06-14
-3nha,2010-08-25,2010-06-14
-4nh0,2015-02-11,2013-11-03
-6nh1,2019-03-13,2018-12-21
-6nhf,2019-03-13,2018-12-21
-7nhm,2021-05-05,2021-02-10
-5nh6,2017-11-01,2017-03-21
-1nhw,2003-02-25,2002-12-19
-3nhb,2010-08-25,2010-06-14
-1nhx,2003-09-30,2002-12-19
-3nhz,2010-08-11,2010-06-14
-7nh2,2021-07-21,2021-02-09
-5nhj,2017-04-19,2017-03-21
-4nhz,2013-11-20,2013-11-05
-1nh6,2003-03-18,2002-12-18
-1nhp,1995-02-14,1994-12-09
-4nhp,2014-09-17,2013-11-05
-4nhv,2014-05-14,2013-11-05
-6nhl,2019-01-16,2018-12-23
-7nhi,2021-09-01,2021-02-10
-7nhl,2021-05-05,2021-02-10
-3nhq,2011-11-30,2010-06-14
-4nh8,2014-01-15,2013-11-04
-4nh4,2014-11-05,2013-11-04
-5nh3,2017-11-15,2017-03-21
-1nh0,2004-04-13,2002-12-18
-5nh4,2017-11-01,2017-03-21
-4nhs,2014-09-17,2013-11-05
-1nhj,2003-06-10,2002-12-19
-4nht,2014-09-17,2013-11-05
-3nhw,2012-01-11,2010-06-14
-3nhy,2012-01-11,2010-06-14
-7nh8,2022-02-23,2021-02-10
-7nhc,2021-12-01,2021-02-10
-1nhq,1995-02-14,1994-12-09
-6nh3,2019-03-13,2018-12-21
-1nh8,2003-02-11,2002-12-18
-5nh8,2017-11-01,2017-03-21
-3nhu,2012-01-11,2010-06-14
-3nh3,2011-03-23,2010-06-14
-6nh2,2019-03-13,2018-12-21
-3nh8,2010-10-20,2010-06-14
-5nhd,2017-11-01,2017-03-21
-7nhj,2021-10-20,2021-02-10
-4nhk,2014-11-19,2013-11-05
-7nhw,2022-03-02,2021-02-11
-7nh5,2021-09-08,2021-02-10
-5nh7,2017-11-01,2017-03-21
-5nhe,2017-11-01,2017-03-21
-7nh4,2021-09-08,2021-02-10
-5nhn,2018-09-26,2017-03-22
-7nh7,2021-06-23,2021-02-10
-6nh7,2019-03-13,2018-12-21
-5nho,2017-04-19,2017-03-22
-4nhc,2014-12-03,2013-11-04
-5nhb,2017-11-01,2017-03-21
-7nh6,2022-02-23,2021-02-10
-6nh6,2019-03-13,2018-12-21
-5nht,2018-05-16,2017-03-22
-3nhf,2012-01-11,2010-06-14
-3nhe,2010-06-30,2010-06-14
-4nh7,2014-01-15,2013-11-04
-6nh4,2019-03-13,2018-12-21
-3nhs,2012-01-11,2010-06-14
-1nhr,1995-02-14,1994-12-09
-7nhk,2021-05-05,2021-02-10
-3nht,2010-12-29,2010-06-14
-5nh5,2017-11-01,2017-03-21
-6nhx,2019-02-13,2018-12-24
-3nho,2011-03-23,2010-06-14
-7nht,2021-09-01,2021-02-11
-4nhe,2013-11-27,2013-11-04
-6nhc,2019-03-13,2018-12-21
-3nhj,2012-01-11,2010-06-14
-3nhc,2010-08-04,2010-06-14
-6nh5,2019-03-13,2018-12-21
-4nhd,2013-12-25,2013-11-04
-4nhb,2013-11-20,2013-11-04
-5nhf,2017-04-19,2017-03-21
-1nht,1997-10-08,1997-01-12
-3nhr,2012-01-11,2010-06-14
-3nhl,2012-01-11,2010-06-14
-1nhk,1995-03-31,1994-12-09
-5nhk,2018-05-16,2017-03-21
-5nhu,2017-06-14,2017-03-22
-7nhx,2021-12-01,2021-02-11
-4nhl,2014-11-19,2013-11-05
-7nho,2021-05-05,2021-02-11
-4nh9,2014-01-22,2013-11-04
-3nh0,2011-02-16,2010-06-14
-7nhg,2021-10-20,2021-02-10
-1nhb,1995-07-10,1995-02-24
-3nh2,2011-02-16,2010-06-14
-5nhp,2017-04-19,2017-03-22
-5nhz,2017-04-26,2017-03-22
-3nhd,2010-08-04,2010-06-14
-3nh4,2010-10-20,2010-06-14
-6nhk,2019-04-17,2018-12-23
-5nh0,2018-05-16,2017-03-21
-5nhc,2017-11-01,2017-03-21
-7nha,2021-12-01,2021-02-10
-4nhf,2014-03-05,2013-11-04
-5nhv,2017-04-19,2017-03-22
-1nhi,2003-06-10,2002-12-19
-1nhe,2003-01-07,2002-12-19
-4nhw,2013-11-20,2013-11-05
-1nhh,2003-06-10,2002-12-19
-3nhg,2011-01-26,2010-06-14
-5nhh,2017-04-19,2017-03-21
-5nh9,2017-11-01,2017-03-21
-4nhm,2014-11-19,2013-11-05
-4nhq,2014-09-17,2013-11-05
-5nh2,2018-05-16,2017-03-21
-6nhr,2020-04-15,2018-12-23
-3nhk,2012-01-11,2010-06-14
-6nhd,2019-03-13,2018-12-21
-7nhn,2021-05-05,2021-02-10
-1nhc,2003-11-25,2002-12-19
-1nhu,2003-03-18,2002-12-19
-4nho,2014-06-18,2013-11-05
-4nhx,2014-11-19,2013-11-05
-7nhv,2021-10-20,2021-02-11
-5nha,2017-11-01,2017-03-21
-7nhh,2021-10-20,2021-02-10
-3nh5,2010-10-20,2010-06-14
-5nhg,2018-05-16,2017-03-21
-3nhh,2010-06-30,2010-06-14
-7nhe,2021-12-22,2021-02-10
-7nhp,2021-05-05,2021-02-11
-6nhb,2019-03-13,2018-12-21
-1nhs,1995-02-14,1994-12-09
-3nh1,2011-02-16,2010-06-14
-7nhq,2021-05-05,2021-02-11
-6nh0,2019-03-13,2018-12-21
-1nhg,2003-02-25,2002-12-19
-4nh1,2014-03-12,2013-11-04
-6nhq,2020-04-15,2018-12-23
-6nhg,2019-06-19,2018-12-21
-3nhx,2011-11-23,2010-06-14
-5nhy,2017-07-19,2017-03-22
-6nhz,2019-02-13,2018-12-24
-1nhv,2003-03-18,2002-12-19
-6nhe,2019-03-13,2018-12-21
-1nh7,2003-02-11,2002-12-18
-3nhp,2012-01-11,2010-06-14
-5frb,2017-04-26,2015-12-16
-4fr6,2013-07-24,2012-06-26
-3frl,2009-06-16,2009-01-08
-2fr1,2006-04-04,2006-01-18
-4frh,2013-12-25,2012-06-26
-4frl,2013-12-25,2012-06-26
-5fr0,2016-03-30,2015-12-14
-5fr3,2016-01-27,2015-12-15
-7frq,2022-11-23,2022-10-24
-1fr7,2001-01-17,2000-09-07
-7fra,2022-11-09,2022-10-20
-5frm,2016-02-17,2015-12-18
-1frt,1995-02-14,1994-11-11
-7fr3,2022-11-09,2022-10-20
-4fri,2012-09-12,2012-06-26
-8fr6,2023-04-19,2023-01-06
-2fr6,2006-07-11,2006-01-19
-4fru,2012-11-14,2012-06-26
-3fre,2010-01-12,2009-01-08
-1frq,1998-10-14,1998-10-10
-1frf,1998-07-29,1998-07-21
-6fr1,2019-03-13,2018-02-15
-8fru,2024-01-31,2023-01-08
-8frn,2024-01-03,2023-01-07
-8frc,2023-03-08,2023-01-06
-8frx,2023-12-27,2023-01-09
-3frb,2010-01-12,2009-01-08
-3frf,2010-01-12,2009-01-08
-7frp,2022-11-23,2022-10-24
-8frd,2023-03-15,2023-01-06
-3fr1,2009-06-30,2009-01-08
-7frz,2023-04-12,2022-12-18
-2frj,2006-05-30,2006-01-19
-3frk,2009-02-17,2009-01-08
-4frk,2012-09-12,2012-06-26
-7fr0,2022-11-09,2022-10-20
-3frj,2009-06-16,2009-01-08
-4fry,2012-07-11,2012-06-26
-1frb,1996-10-14,1995-08-08
-2fr3,2006-09-19,2006-01-18
-5frq,2016-08-17,2015-12-21
-6frq,2018-10-03,2018-02-16
-3frh,2009-08-11,2009-01-08
-2fr0,2006-04-04,2006-01-18
-6frp,2019-03-13,2018-02-16
-5fr1,2016-01-13,2015-12-15
-4frs,2012-08-08,2012-06-26
-8frm,2024-01-03,2023-01-07
-1frw,2001-01-10,2000-09-07
-4fre,2013-12-25,2012-06-26
-2fre,2006-03-07,2006-01-19
-8fra,2023-03-08,2023-01-06
-3fr7,2009-04-14,2009-01-08
-8frr,2024-01-17,2023-01-08
-8frj,2023-07-26,2023-01-07
-1fro,1997-06-16,1997-02-25
-3frq,2009-03-24,2009-01-08
-1fr4,2001-01-17,2000-09-07
-8fr4,2023-02-01,2023-01-06
-5frv,2016-03-30,2015-12-23
-6frx,2019-03-13,2018-02-16
-6frw,2019-02-06,2018-02-16
-2fri,2006-05-30,2006-01-19
-3fri,2009-08-11,2009-01-08
-4frv,2012-11-14,2012-06-26
-7frh,2022-11-23,2022-10-24
-7frk,2022-11-23,2022-10-24
-8frg,2023-03-15,2023-01-06
-8fr9,2023-03-15,2023-01-06
-7frr,2022-11-23,2022-10-25
-6frj,2019-02-20,2018-02-16
-3frp,2009-04-28,2009-01-08
-7frl,2022-11-23,2022-10-24
-4fro,2013-12-25,2012-06-26
-3frx,2009-02-17,2009-01-08
-4fr0,2012-07-11,2012-06-26
-4frr,2013-10-16,2012-06-26
-2fr8,2006-02-28,2006-01-19
-2frc,1997-07-29,1996-07-02
-3fr0,2009-02-17,2009-01-08
-4frm,2013-12-25,2012-06-26
-8frz,2023-12-27,2023-01-09
-4fra,2013-12-25,2012-06-26
-3frd,2010-01-12,2009-01-08
-5fra,2016-07-20,2015-12-16
-7fr4,2022-11-09,2022-10-20
-5frc,2016-10-26,2015-12-16
-6fr0,2018-08-29,2018-02-15
-8fr2,2023-02-01,2023-01-06
-7frx,2023-04-12,2022-12-18
-5frd,2016-05-25,2015-12-17
-4frb,2013-12-25,2012-06-26
-2fr7,2007-01-16,2006-01-19
-4fr1,2013-07-24,2012-06-26
-1frp,1994-11-30,1994-08-26
-7fro,2022-11-23,2022-10-24
-1frn,1995-07-10,1995-03-31
-1frv,1996-11-08,1996-03-28
-2frq,2006-07-25,2006-01-19
-7fr7,2022-11-09,2022-10-20
-3fro,2010-01-12,2009-01-08
-3frz,2009-03-10,2009-01-08
-5fr9,2016-03-02,2015-12-16
-4fr3,2013-05-08,2012-06-26
-3fr9,2010-01-26,2009-01-08
-3frg,2010-01-12,2009-01-08
-3fr4,2009-03-10,2009-01-08
-6fry,2019-03-13,2018-02-16
-8fro,2024-01-03,2023-01-07
-5frx,2016-03-30,2015-12-23
-6frd,2019-03-13,2018-02-15
-5frz,2016-03-30,2015-12-23
-7frm,2022-11-23,2022-10-24
-3fr6,2010-01-26,2009-01-08
-2frd,2006-02-28,2006-01-19
-3frm,2009-01-27,2009-01-08
-7fri,2022-11-23,2022-10-24
-8fr0,2024-02-28,2023-01-06
-7frc,2022-11-09,2022-10-20
-2frf,2006-05-30,2006-01-19
-4frj,2012-09-12,2012-06-26
-2frs,2006-09-19,2006-01-20
-4fr7,2013-06-26,2012-06-26
-3fra,2010-01-12,2009-01-08
-4frp,2013-12-25,2012-06-26
-6fro,2018-10-03,2018-02-16
-7fr1,2022-11-09,2022-10-20
-1fr9,2001-01-10,2000-09-07
-5frf,2016-08-03,2015-12-17
-8fry,2024-01-17,2023-01-09
-7frw,2023-04-12,2022-12-18
-8frw,2023-12-27,2023-01-09
-7fr2,2022-11-09,2022-10-20
-5fri,2016-07-27,2015-12-17
-7frf,2022-11-23,2022-10-24
-6frv,2018-05-09,2018-02-16
-4frd,2013-12-25,2012-06-26
-4frq,2013-12-25,2012-06-26
-8frb,2023-03-08,2023-01-06
-4fr2,2013-06-05,2012-06-26
-7fr5,2022-11-09,2022-10-20
-4frc,2013-07-17,2012-06-26
-3fr3,2010-01-26,2009-01-08
-7fr9,2022-11-09,2022-10-20
-6frn,2018-10-03,2018-02-16
-4fr5,2012-12-26,2012-06-26
-7frj,2022-11-23,2022-10-24
-4fr8,2012-09-26,2012-06-26
-1fr6,2001-01-17,2000-09-07
-3fr5,2009-03-10,2009-01-08
-5fru,2016-03-30,2015-12-23
-3fru,1998-06-10,1997-12-22
-7frv,2023-04-12,2022-12-18
-2fra,2006-07-25,2006-01-19
-7frn,2022-11-23,2022-10-24
-7fr6,2022-11-09,2022-10-20
-3fr8,2009-04-14,2009-01-08
-5fre,2016-07-20,2015-12-17
-1fre,1997-02-12,1996-01-31
-2fr5,2006-07-11,2006-01-19
-7frg,2022-11-23,2022-10-24
-5fro,2016-02-17,2015-12-18
-8fr5,2023-12-27,2023-01-06
-6fr2,2018-09-12,2018-02-15
-7fry,2023-04-12,2022-12-18
-8frl,2024-01-03,2023-01-07
-5fry,2016-05-18,2015-12-23
-6frf,2018-08-29,2018-02-15
-6frk,2018-03-28,2018-02-16
-6frz,2019-03-13,2018-02-18
-1frz,2002-01-04,2000-09-07
-5fr2,2016-01-13,2015-12-15
-1fr2,2003-06-17,2000-09-07
-6frm,2018-10-31,2018-02-16
-4frz,2013-07-10,2012-06-26
-5frw,2016-04-06,2015-12-23
-8fr1,2023-02-01,2023-01-06
-8frk,2023-07-26,2023-01-07
-2frz,2007-01-16,2006-01-20
-2frh,2006-01-31,2006-01-19
-8fr7,2023-10-04,2023-01-06
-2frv,1998-06-17,1997-06-10
-8fr3,2023-09-20,2023-01-06
-7frb,2022-11-09,2022-10-20
-5frn,2016-02-17,2015-12-18
-3frc,2010-01-26,2009-01-08
-4fr4,2012-07-18,2012-06-26
-7fr8,2022-11-09,2022-10-20
-7frd,2022-11-09,2022-10-20
-3fr2,2009-03-10,2009-01-08
-1fr8,2000-09-20,2000-09-07
-2frk,2006-05-30,2006-01-19
-6xq5,2021-07-14,2020-07-09
-6xqt,2020-07-22,2020-07-10
-6xq2,2021-05-19,2020-07-09
-5xql,2017-06-28,2017-06-07
-1xqn,2004-11-02,2004-10-13
-2xqq,2011-05-04,2010-09-07
-6xqj,2021-11-17,2020-07-09
-1xqy,2005-07-12,2004-10-13
-1xq6,2004-10-19,2004-10-11
-6xq9,2021-07-14,2020-07-09
-5xq3,2018-03-21,2017-06-06
-1xqh,2004-11-23,2004-10-12
-2xq1,2011-06-22,2010-08-31
-6xqm,2021-02-10,2020-07-09
-6xqd,2020-08-05,2020-07-09
-2xqn,2011-01-26,2010-09-03
-1xq0,2005-05-17,2004-10-11
-1xqc,2005-02-01,2004-10-12
-5xqe,2018-06-20,2017-06-07
-1xqd,2004-10-26,2004-10-12
-7xqg,2023-01-25,2022-05-07
-5xqd,2018-06-20,2017-06-07
-7xqp,2023-04-26,2022-05-08
-2xq4,2010-11-10,2010-09-01
-4xq9,2016-01-27,2015-01-19
-7xqv,2022-07-13,2022-05-09
-4xq8,2016-02-24,2015-01-19
-2xqa,2010-11-10,2010-09-01
-4xqc,2016-01-27,2015-01-19
-7xqy,2023-05-17,2022-05-09
-6xqu,2020-07-22,2020-07-10
-6xq7,2021-07-14,2020-07-09
-7xqe,2023-05-31,2022-05-07
-7xq0,2022-10-05,2022-05-06
-7xq1,2022-10-05,2022-05-06
-4xq6,2016-01-20,2015-01-19
-4xqf,2016-01-27,2015-01-19
-6xqa,2021-04-14,2020-07-09
-6xqp,2020-08-26,2020-07-10
-7xqm,2022-12-21,2022-05-08
-2xqx,2010-11-03,2010-09-07
-7xqu,2023-11-08,2022-05-08
-5xqj,2018-04-04,2017-06-07
-5xq2,2017-10-04,2017-06-06
-6xql,2021-02-10,2020-07-09
-6xq3,2021-07-14,2020-07-09
-2xqu,2010-10-27,2010-09-07
-1xql,2005-01-18,2004-10-12
-4xq5,2015-04-01,2015-01-19
-1xq7,2004-12-21,2004-10-11
-6xq0,2021-05-19,2020-07-09
-7xq7,2023-03-01,2022-05-06
-6xqf,2021-02-10,2020-07-09
-7xq2,2022-10-05,2022-05-06
-6xqb,2020-07-29,2020-07-09
-4xqb,2015-07-29,2015-01-19
-6xq1,2021-07-14,2020-07-09
-5xqa,2018-06-06,2017-06-06
-2xq9,2010-11-10,2010-09-01
-7xqt,2023-11-08,2022-05-08
-7xq8,2022-08-17,2022-05-07
-5xqk,2018-06-13,2017-06-07
-7xql,2023-05-17,2022-05-07
-7xqf,2023-02-22,2022-05-07
-2xqj,2011-03-23,2010-09-02
-6xqh,2021-02-10,2020-07-09
-7xqs,2023-11-08,2022-05-08
-4xqu,2015-04-01,2015-01-20
-5xqo,2018-03-21,2017-06-07
-4xqo,2015-04-01,2015-01-19
-5xqz,2018-08-29,2017-06-07
-1xqs,2005-03-01,2004-10-13
-2xq0,2010-12-29,2010-08-31
-2xq7,2010-11-10,2010-09-01
-6xqv,2021-07-21,2020-07-10
-5xqg,2018-03-21,2017-06-07
-2xqs,2010-10-27,2010-09-07
-1xqx,2005-07-12,2004-10-13
-2xq5,2010-11-10,2010-09-01
-2xqy,2010-12-22,2010-09-08
-2xqr,2010-10-06,2010-09-07
-7xqx,2023-05-17,2022-05-09
-5xqx,2017-08-09,2017-06-07
-6xqo,2020-07-29,2020-07-09
-1xq5,2004-11-16,2004-10-11
-1xqk,2005-01-18,2004-10-12
-7xqb,2023-02-01,2022-05-07
-6xqi,2021-08-11,2020-07-09
-6xq4,2021-05-19,2020-07-09
-7xqd,2023-02-22,2022-05-07
-2xqv,2011-04-27,2010-09-07
-2xq8,2010-11-10,2010-09-01
-6xq6,2021-07-14,2020-07-09
-4xqs,2016-01-20,2015-01-20
-4xqa,2015-07-29,2015-01-19
-6xqg,2021-02-10,2020-07-09
-6xqr,2021-12-15,2020-07-10
-4xqe,2016-01-27,2015-01-19
-6xq8,2021-07-14,2020-07-09
-7xqz,2023-03-15,2022-05-09
-1xqp,2004-11-16,2004-10-13
-2xq6,2010-11-10,2010-09-01
-7xqw,2023-08-09,2022-05-09
-4xqm,2015-07-22,2015-01-19
-1xqa,2004-11-23,2004-10-11
-2xqt,2010-10-27,2010-09-07
-6xqs,2020-07-22,2020-07-10
-1xqw,2005-07-12,2004-10-13
-4xq0,2015-03-04,2015-01-18
-1xq3,2004-11-16,2004-10-11
-5xqw,2018-04-18,2017-06-07
-6xqn,2020-07-29,2020-07-09
-4xqk,2015-09-16,2015-01-19
-4xqg,2016-01-27,2015-01-19
-7xqa,2023-05-31,2022-05-07
-4xq1,2015-04-29,2015-01-18
-4xqt,2016-01-20,2015-01-20
-2xqc,2010-10-13,2010-09-01
-6xqe,2020-08-05,2020-07-09
-2xqo,2011-03-02,2010-09-06
-5bsb,2015-09-16,2015-06-01
-1bsx,1999-08-26,1998-08-31
-2bsy,2005-09-15,2005-05-24
-3bsa,2008-12-23,2007-12-23
-3bsb,2008-04-08,2007-12-23
-2bsp,1998-08-12,1998-07-31
-1bsm,1999-06-15,1998-08-28
-6bse,2018-12-05,2017-12-02
-5bsu,2016-05-11,2015-06-02
-3bs4,2008-01-15,2007-12-21
-2bs9,2005-10-12,2005-05-19
-2bs0,2006-03-22,2005-05-13
-1bsi,1999-05-18,1998-08-28
-1bss,1998-09-02,1998-08-30
-6bsz,2018-02-07,2017-12-04
-2bsl,2006-08-29,2005-05-23
-4bs9,2013-11-06,2013-06-09
-4bsb,2013-07-03,2013-06-10
-7bsn,2021-02-03,2020-03-31
-2bsm,2005-06-02,2005-05-23
-3bss,2008-07-22,2007-12-26
-2bs8,2005-08-19,2005-05-18
-6bsj,2018-01-03,2017-12-03
-3bsy,2008-07-29,2007-12-26
-8bsy,2023-12-13,2022-11-26
-4bs5,2013-11-27,2013-06-07
-8bsi,2023-03-15,2022-11-25
-1bsz,1999-08-26,1998-09-01
-8bsu,2023-12-13,2022-11-26
-6bsd,2018-12-05,2017-12-02
-4bsi,2013-07-03,2013-06-10
-3bsd,2008-01-22,2007-12-23
-5bsv,2016-05-11,2015-06-02
-7bsm,2021-02-03,2020-03-31
-1bs3,1999-06-15,1998-08-31
-2bsc,2006-05-24,2005-05-20
-6bsr,2018-10-31,2017-12-04
-2bsa,2005-10-19,2005-05-20
-6bs6,2018-01-24,2017-12-01
-6bss,2018-08-15,2017-12-04
-2bs7,2006-05-24,2005-05-18
-4bsc,2013-07-03,2013-06-10
-8bse,2023-05-17,2022-11-25
-1bs2,1999-08-27,1998-08-31
-4bsv,2013-08-21,2013-06-11
-2bsr,2005-05-24,2005-05-23
-4bsq,2013-11-27,2013-06-11
-4bs0,2013-10-16,2013-06-06
-8bsq,2022-12-14,2022-11-26
-7bs0,2020-08-26,2020-03-30
-7bsa,2020-08-26,2020-03-30
-7bsx,2021-10-06,2020-03-31
-6bs5,2019-05-15,2017-12-01
-7bs7,2020-08-26,2020-03-30
-2bsf,2005-11-03,2005-05-20
-7bsj,2021-02-10,2020-03-30
-6bsn,2018-01-03,2017-12-04
-3bsn,2008-01-08,2007-12-26
-5bsk,2015-09-23,2015-06-02
-8bsf,2023-05-17,2022-11-25
-5bsz,2015-07-29,2015-06-02
-4bst,2013-06-19,2013-06-11
-7bs8,2020-08-26,2020-03-30
-4bse,2013-07-03,2013-06-10
-3bs8,2008-12-23,2007-12-22
-1bso,1999-09-02,1998-08-29
-2bs4,2005-12-13,2005-05-14
-5bsg,2015-11-11,2015-06-02
-2bs2,2006-10-25,2005-05-14
-6bsf,2018-12-05,2017-12-02
-5bs0,2016-03-02,2015-06-01
-6bs0,2018-08-22,2017-12-01
-1bsj,2000-04-15,1998-08-28
-3bso,2008-01-08,2007-12-26
-5bs1,2015-08-05,2015-06-01
-2bst,2005-05-24,2005-05-23
-6bsk,2018-03-21,2017-12-03
-4bsk,2013-07-31,2013-06-10
-7bsw,2020-09-30,2020-03-31
-2bsb,2006-05-24,2005-05-20
-1bs6,1999-08-27,1998-09-01
-8bsd,2022-12-07,2022-11-24
-1bs1,1999-01-13,1998-08-31
-7bs6,2020-08-26,2020-03-30
-2bsw,2005-06-08,2005-05-24
-5bsh,2015-11-11,2015-06-02
-6bs2,2018-06-27,2017-12-01
-8bsk,2023-01-18,2022-11-25
-6bs3,2019-05-15,2017-12-01
-8bsg,2023-02-08,2022-11-25
-6bsv,2018-05-23,2017-12-04
-7bs1,2020-08-26,2020-03-30
-5bsf,2015-11-11,2015-06-02
-3bsg,2008-08-26,2007-12-24
-4bss,2013-06-19,2013-06-11
-8bsz,2022-12-14,2022-11-27
-4bsw,2013-08-21,2013-06-11
-5bsr,2016-05-11,2015-06-02
-4bs1,2013-07-03,2013-06-06
-8bs3,2023-07-12,2022-11-24
-4bsj,2013-07-31,2013-06-10
-7bsq,2020-09-30,2020-03-31
-8bsx,2023-12-13,2022-11-26
-2bs3,2005-12-13,2005-05-14
-4bsd,2013-07-03,2013-06-10
-1bs4,1999-08-27,1998-09-01
-4bsf,2013-07-03,2013-06-10
-1bsw,1999-08-26,1998-08-31
-7bs5,2020-08-26,2020-03-30
-4bs6,2014-06-18,2013-06-07
-8bsh,2023-01-18,2022-11-25
-1bs7,1999-08-27,1998-09-01
-7bsp,2020-09-30,2020-03-31
-6bsx,2018-02-28,2017-12-04
-6bsh,2018-01-03,2017-12-03
-1bs5,1999-08-27,1998-09-01
-6bsw,2018-05-23,2017-12-04
-8bs9,2023-07-12,2022-11-24
-8bsl,2023-01-18,2022-11-25
-7bss,2020-09-30,2020-03-31
-6bsm,2018-08-08,2017-12-04
-8bsn,2023-01-18,2022-11-25
-3bsh,2008-08-26,2007-12-24
-3bsf,2009-02-24,2007-12-23
-8bsr,2022-12-14,2022-11-26
-6bs4,2019-05-15,2017-12-01
-5bs2,2015-08-05,2015-06-01
-8bsp,2022-12-14,2022-11-26
-2bs6,2005-05-19,2005-05-18
-7bs4,2020-08-26,2020-03-30
-7bsk,2021-02-10,2020-03-30
-6bsi,2018-01-03,2017-12-03
-7bs3,2020-08-26,2020-03-30
-5bsm,2016-05-11,2015-06-02
-4bsg,2013-07-03,2013-06-10
-2bs5,2005-05-19,2005-05-18
-7bsr,2020-07-15,2020-03-31
-2bsx,2005-08-18,2005-05-24
-5bst,2016-05-11,2015-06-02
-3bsx,2008-04-08,2007-12-26
-6bsu,2018-05-23,2017-12-04
-3bsz,2008-11-11,2007-12-27
-7bs9,2020-08-26,2020-03-30
-8bso,2023-09-27,2022-11-25
-8bsb,2023-06-07,2022-11-24
-7bsu,2020-09-30,2020-03-31
-4bsr,2013-06-19,2013-06-11
-1bsu,1998-09-09,1998-08-30
-8bsw,2023-12-13,2022-11-29
-8bst,2023-12-13,2022-11-26
-3bs1,2008-04-08,2007-12-21
-6bsl,2018-08-08,2017-12-04
-1bsk,2000-04-15,1998-08-28
-3bsc,2008-12-23,2007-12-23
-8bsa,2023-06-07,2022-11-24
-1bs8,1999-08-27,1998-09-01
-5bs8,2016-03-02,2015-06-01
-5bs3,2015-06-17,2015-06-01
-7bsl,2021-02-10,2020-03-30
-5bs4,2015-09-09,2015-06-01
-3bsu,2008-03-25,2007-12-26
-4bsa,2013-07-03,2013-06-10
-7bs2,2020-08-26,2020-03-30
-4bsu,2013-06-26,2013-06-11
-4bsh,2013-07-03,2013-06-10
-4bs4,2013-10-30,2013-06-07
-6bsg,2018-01-03,2017-12-03
-7bsv,2020-09-30,2020-03-31
-8bsc,2023-05-03,2022-11-24
-5bsw,2016-05-11,2015-06-02
-3bs6,2008-02-12,2007-12-22
-6bs1,2018-08-22,2017-12-01
-8bsm,2023-01-18,2022-11-25
-1bsv,1999-08-26,1998-08-31
-8bsv,2023-12-13,2022-11-29
-1vs1,2006-05-16,2006-03-09
-6vsg,2020-07-15,2020-02-11
-5vsk,2017-12-20,2017-05-11
-6vs3,2021-02-17,2020-02-10
-1vsr,1999-10-27,1999-02-13
-5vs7,2017-05-31,2017-05-11
-5vsm,2017-06-14,2017-05-11
-3vsl,2012-10-31,2012-04-25
-7vsj,2022-11-02,2021-10-26
-3vs3,2013-05-01,2012-04-21
-5vs2,2017-07-19,2017-05-11
-3vs8,2013-04-24,2012-04-23
-3vs1,2013-05-01,2012-04-21
-6vs6,2020-07-15,2020-02-10
-5vs0,2017-07-19,2017-05-11
-5vsf,2017-07-12,2017-05-11
-2vsh,2008-12-30,2008-04-23
-5vs5,2017-11-15,2017-05-11
-5vsl,2017-06-14,2017-05-11
-2vs7,2008-11-11,2008-04-21
-2vs8,2008-11-11,2008-04-21
-5vst,2017-05-24,2017-05-12
-6vs8,2020-07-15,2020-02-10
-3vs6,2013-05-01,2012-04-21
-2vs0,2008-08-26,2008-04-17
-2vsc,2008-08-12,2008-04-22
-7vsp,2022-03-02,2021-10-27
-7vsi,2021-12-15,2021-10-26
-3vsj,2013-01-16,2012-04-25
-7vsr,2023-02-15,2021-10-27
-2vsy,2008-11-18,2008-05-01
-8vsy,2024-02-07,2024-01-24
-7vsd,2022-03-02,2021-10-26
-2vs2,2008-05-27,2008-04-17
-3vsq,2013-05-08,2012-05-02
-6vs2,2020-06-03,2020-02-10
-8vsw,2024-03-27,2024-01-24
-6vsl,2021-02-17,2020-02-11
-7vs0,2023-02-01,2021-10-25
-3vsi,2013-01-16,2012-04-25
-5vsg,2018-06-27,2017-05-11
-6vsw,2020-05-13,2020-02-12
-3vsb,1998-03-25,1997-09-25
-5vsa,2018-01-10,2017-05-11
-2vs5,2008-07-15,2008-04-18
-6vsf,2020-07-15,2020-02-11
-3vso,2013-05-01,2012-04-30
-1vsg,1992-01-15,1990-10-22
-2vsx,2008-06-24,2008-04-30
-2vso,2008-06-24,2008-04-28
-5vsj,2017-05-31,2017-05-11
-6vsz,2021-02-17,2020-02-12
-3vs2,2013-05-01,2012-04-21
-3vsu,2013-02-27,2012-05-09
-5vsb,2017-12-20,2017-05-11
-6vs5,2020-07-15,2020-02-10
-1vsn,2007-04-24,2007-03-19
-5vs3,2017-07-19,2017-05-11
-7vs9,2022-08-31,2021-10-26
-2vst,2008-08-19,2008-04-29
-7vso,2022-02-16,2021-10-27
-7vsf,2023-02-01,2021-10-26
-3vs0,2013-05-01,2012-04-21
-1vs0,2006-02-28,2006-01-27
-3vsz,2012-12-05,2012-05-18
-3vsv,2013-02-27,2012-05-09
-7vs8,2022-08-31,2021-10-26
-2vs3,2008-07-15,2008-04-18
-6vse,2020-07-15,2020-02-11
-2vsn,2008-06-10,2008-04-28
-3vse,2013-04-10,2012-04-25
-6vst,2020-08-12,2020-02-11
-1vs2,2006-06-27,1986-10-21
-1vsj,1997-05-15,1997-03-04
-3vs7,2013-05-01,2012-04-21
-7vsg,2021-12-29,2021-10-26
-1vso,2007-07-03,2007-03-29
-6vs4,2020-03-11,2020-02-10
-2vsi,2008-12-30,2008-04-23
-6vs9,2020-07-15,2020-02-10
-3vsx,2012-07-25,2012-05-11
-2vsf,2008-07-08,2008-04-23
-2vsm,2008-05-20,2008-04-25
-3vsd,2012-05-16,2012-04-24
-6vs7,2020-08-26,2020-02-10
-7vse,2022-03-02,2021-10-26
-5vsw,2017-06-14,2017-05-12
-2vs4,2008-07-15,2008-04-18
-5vs4,2017-07-19,2017-05-11
-6vs1,2020-06-03,2020-02-10
-2vs1,2008-08-05,2008-04-17
-7vsh,2021-12-29,2021-10-26
-7vsl,2022-11-02,2021-10-26
-3vss,2012-08-22,2012-05-08
-2vsl,2008-09-02,2008-04-24
-5vsv,2017-05-24,2017-05-12
-6vss,2020-08-12,2020-02-11
-3vsh,2013-01-16,2012-04-25
-2vss,2008-05-27,2008-04-29
-6vsd,2020-07-15,2020-02-11
-7vsk,2022-06-22,2021-10-26
-6vs0,2020-06-03,2020-02-10
-1vst,2009-09-01,2009-02-09
-2vsr,2008-08-19,2008-04-29
-3vsc,2012-05-16,2012-04-24
-8vsp,2024-05-08,2024-01-24
-3vs4,2013-05-01,2012-04-21
-1vsh,1997-05-15,1997-03-04
-1vsv,2009-03-24,2008-03-11
-5vsd,2017-07-12,2017-05-11
-7vsc,2022-03-02,2021-10-26
-3vs9,2013-04-24,2012-04-23
-1vsf,1996-04-03,1995-11-29
-7vsa,2022-03-02,2021-10-26
-5vsc,2017-07-12,2017-05-11
-3vsp,2013-05-01,2012-04-30
-7vs7,2022-08-03,2021-10-26
-6vsu,2020-08-12,2020-02-11
-6vsj,2020-03-04,2020-02-11
-8vsi,2024-04-10,2024-01-24
-7vs4,2022-11-30,2021-10-25
-1vsl,1998-09-23,1998-09-18
-6vsp,2020-12-23,2020-02-11
-7vs6,2023-02-01,2021-10-25
-3vsa,2012-05-16,2012-04-24
-3vs5,2013-05-01,2012-04-21
-5vse,2017-07-19,2017-05-11
-1vsi,1997-05-15,1997-03-04
-2vsd,2008-07-29,2008-04-22
-7vsb,2022-03-02,2021-10-26
-5vsr,2017-11-15,2017-05-12
-2vsu,2008-05-27,2008-04-29
-2vsq,2008-07-08,2008-04-29
-1vsd,1996-04-03,1995-11-29
-5vsq,2017-11-15,2017-05-12
-7vs1,2023-02-01,2021-10-25
-6vsn,2021-02-17,2020-02-11
-3vsw,2012-07-25,2012-05-11
-5vsn,2018-05-23,2017-05-12
-5vs6,2017-12-20,2017-05-11
-7vsq,2022-03-02,2021-10-27
-5vs1,2017-07-19,2017-05-11
-6vsb,2020-02-26,2020-02-10
-8fhk,2023-11-15,2022-12-14
-8fhq,2023-02-15,2022-12-14
-6fhx,2019-01-30,2018-01-16
-5fhs,2016-03-23,2015-12-22
-7fh0,2022-08-03,2021-07-28
-1fh0,2001-07-30,2000-07-30
-8fhf,2024-03-20,2022-12-14
-5fhe,2016-03-30,2015-12-22
-8fhc,2023-12-20,2022-12-13
-4fhd,2012-07-18,2012-06-06
-8fh2,2023-04-12,2022-12-13
-3fhi,2009-04-14,2008-12-09
-1fh7,2000-08-23,2000-07-31
-3fhx,2008-12-23,2008-12-10
-2fhc,2006-06-13,2005-12-23
-7fhn,2021-12-01,2021-07-29
-4fhg,2012-07-18,2012-06-06
-5fhz,2016-11-02,2015-12-22
-6fhb,2019-01-30,2018-01-12
-3fh9,2009-02-10,2008-12-09
-4fhz,2012-10-03,2012-06-07
-4fhk,2013-04-10,2012-06-06
-7fh5,2022-08-03,2021-07-29
-1fhh,2001-03-14,2000-08-01
-5fh7,2016-06-01,2015-12-21
-5fh1,2016-12-28,2015-12-21
-2fh8,2006-06-13,2005-12-23
-1fhe,1998-07-29,1997-07-24
-1fhm,2001-03-14,2000-08-02
-8fhe,2024-03-20,2022-12-14
-1fha,1992-07-15,1990-12-20
-6fh6,2018-05-30,2018-01-12
-8fht,2023-02-15,2022-12-15
-6fhl,2018-06-13,2018-01-15
-8fhs,2023-12-13,2022-12-15
-2fh5,2006-01-31,2005-12-23
-5fh8,2016-06-01,2015-12-21
-8fhu,2023-06-28,2022-12-15
-4fhi,2012-09-19,2012-06-06
-2fhk,2006-03-07,2005-12-25
-6fhj,2018-08-29,2018-01-14
-3fhp,2009-10-20,2008-12-09
-5fht,2016-09-07,2015-12-22
-1fhv,2000-08-23,2000-08-02
-1fhf,2001-02-14,2000-08-01
-3fh4,2009-11-17,2008-12-08
-4fhf,2012-07-18,2012-06-06
-8fh4,2023-04-05,2022-12-13
-4fhc,2012-07-18,2012-06-06
-4fh4,2012-09-26,2012-06-05
-3fh5,2010-01-05,2008-12-08
-7fha,2021-12-01,2021-07-29
-7fhb,2022-06-22,2021-07-29
-2fha,1997-09-04,1997-03-03
-4fha,2013-09-18,2012-06-06
-8fhr,2023-02-15,2022-12-14
-6fhv,2018-05-09,2018-01-15
-4fh6,2013-03-27,2012-06-05
-8fhd,2023-02-08,2022-12-14
-3fhb,2009-01-06,2008-12-09
-3fht,2009-02-17,2008-12-10
-5fhd,2016-03-30,2015-12-22
-5fh0,2016-11-09,2015-12-21
-3fh3,2009-01-06,2008-12-08
-5fhi,2016-04-20,2015-12-22
-8fhy,2024-01-17,2022-12-15
-5fhr,2016-02-03,2015-12-22
-6fht,2018-04-18,2018-01-15
-7fhs,2022-03-23,2021-07-30
-5fhy,2016-10-05,2015-12-22
-1fh9,2000-08-23,2000-07-31
-3fh0,2008-12-23,2008-12-08
-3fhz,2009-03-24,2008-12-10
-4fhh,2012-09-19,2012-06-06
-6fhc,2018-08-08,2018-01-14
-4fh2,2012-09-26,2012-06-05
-8fhp,2023-02-15,2022-12-14
-3fhw,2008-12-30,2008-12-10
-6fh2,2019-02-06,2018-01-12
-3fhj,2009-02-03,2008-12-09
-1fhw,2000-08-23,2000-08-02
-6fh8,2018-08-22,2018-01-12
-5fh4,2016-11-09,2015-12-21
-2fh6,2006-06-13,2005-12-23
-7fh6,2022-02-16,2021-07-29
-7fh1,2021-12-01,2021-07-29
-2fh1,2006-06-13,2005-12-23
-7fht,2022-03-23,2021-07-30
-5fhh,2016-03-30,2015-12-22
-8fhh,2023-11-01,2022-12-14
-2fhr,2006-01-17,2005-12-26
-2fh2,2006-06-13,2005-12-23
-2fh3,2006-06-13,2005-12-23
-5fhn,2016-03-02,2015-12-22
-4fhy,2012-08-29,2012-06-07
-5fh3,2016-11-09,2015-12-21
-8fh9,2023-12-20,2022-12-13
-7fho,2021-12-01,2021-07-29
-8fhb,2023-12-20,2022-12-13
-1fhb,1995-09-15,1995-06-16
-8fh5,2023-12-20,2022-12-13
-4fhv,2012-08-29,2012-06-06
-8fh1,2023-04-12,2022-12-13
-8fhn,2023-02-15,2022-12-14
-6fho,2018-04-25,2018-01-15
-6fh7,2018-05-30,2018-01-12
-5fh2,2016-11-09,2015-12-21
-2fhn,2006-03-21,2005-12-26
-8fhm,2023-12-20,2022-12-14
-4fh7,2013-03-27,2012-06-05
-8fhj,2023-05-03,2022-12-14
-3fhe,2010-01-05,2008-12-09
-6fhw,2018-05-09,2018-01-15
-8fho,2023-02-15,2022-12-14
-1fh8,2000-08-23,2000-07-31
-1fhr,2000-10-18,2000-08-02
-3fhv,2009-10-27,2008-12-10
-5fhf,2016-03-30,2015-12-22
-1fhi,1998-06-17,1997-12-11
-3fhr,2009-12-15,2008-12-10
-3fha,2009-04-28,2008-12-09
-8fh7,2023-12-20,2022-12-13
-3fh7,2010-01-05,2008-12-08
-3fhm,2009-01-13,2008-12-09
-6fhd,2018-08-08,2018-01-14
-6fhn,2018-08-29,2018-01-15
-2fhi,1998-06-17,1998-04-01
-2fhx,2006-01-17,2005-12-27
-3fhd,2009-11-24,2008-12-09
-3fhy,2008-12-23,2008-12-10
-5fhw,2017-01-11,2015-12-22
-7fh3,2021-12-01,2021-07-29
-2fhe,1998-10-28,1998-10-21
-4fhx,2012-08-29,2012-06-07
-5fhm,2016-03-02,2015-12-22
-7fh2,2022-08-03,2021-07-29
-7fh9,2022-07-06,2021-07-29
-6fh4,2019-02-27,2018-01-12
-4fhb,2013-04-24,2012-06-06
-8fhw,2023-12-20,2022-12-15
-8fh0,2023-04-12,2022-12-13
-6fhy,2019-01-30,2018-01-16
-3fhq,2009-05-05,2008-12-10
-8fh6,2023-12-20,2022-12-13
-6fhh,2019-01-30,2018-01-14
-3fhh,2009-07-14,2008-12-09
-1fhj,2001-08-01,2000-08-01
-1fhx,2000-08-23,2000-08-02
-8fhl,2023-06-28,2022-12-14
-7fh4,2022-07-06,2021-07-29
-5fho,2016-03-02,2015-12-22
-7fh7,2022-02-16,2021-07-29
-4fhj,2012-07-18,2012-06-06
-6fhf,2018-07-25,2018-01-14
-6fhg,2019-01-30,2018-01-14
-2fhy,2006-02-21,2005-12-27
-8fhi,2023-11-01,2022-12-14
-2fhh,2006-02-28,2005-12-23
-2fhb,2006-06-13,2005-12-23
-3fhl,2008-12-23,2008-12-09
-6fhq,2018-03-21,2018-01-15
-6fhu,2018-03-21,2018-01-15
-2fhf,2006-06-13,2005-12-23
-4fhp,2012-08-29,2012-06-06
-7fhr,2021-12-15,2021-07-30
-8fh8,2023-12-20,2022-12-13
-5fh6,2016-06-01,2015-12-21
-4fhe,2012-07-18,2012-06-06
-2fhl,2006-03-21,2005-12-26
-4fh5,2012-08-29,2012-06-05
-7fhl,2021-12-01,2021-07-29
-6fhs,2018-04-25,2018-01-15
-8fhg,2024-03-20,2022-12-14
-6fhi,2019-01-30,2018-01-14
-7fh8,2022-02-16,2021-07-29
-2fhj,2006-03-07,2005-12-25
-6fh3,2019-02-27,2018-01-12
-6fhk,2018-10-24,2018-01-14
-4fhw,2012-08-29,2012-06-06
-3fh8,2010-01-05,2008-12-09
-8fh3,2023-02-22,2022-12-13
-5fhq,2016-02-03,2015-12-22
-7fhk,2021-12-01,2021-07-29
-6fh5,2019-01-30,2018-01-12
-5fh5,2016-11-09,2015-12-21
-1fhd,2000-08-23,2000-07-31
-3zxe,2011-11-30,2011-08-10
-7zx4,2023-03-29,2022-05-20
-6zxw,2020-09-23,2020-07-30
-1zxq,1997-09-04,1997-03-04
-5zxb,2018-09-26,2018-05-18
-3zxt,2012-07-25,2011-08-15
-6zxb,2021-03-31,2020-07-29
-3zx2,2011-11-30,2011-08-04
-7zx7,2022-11-30,2022-05-20
-2zx8,2009-12-08,2008-12-19
-2zxt,2009-08-04,2009-01-07
-2zxn,2009-02-17,2009-01-04
-2zxp,2010-01-05,2009-01-05
-5zx5,2018-10-17,2018-05-18
-6zxd,2020-12-02,2020-07-29
-2zxy,2009-08-04,2009-01-09
-7zx9,2022-06-15,2022-05-20
-2zxg,2009-08-25,2008-12-24
-1zxv,2005-07-05,2005-06-08
-5zxl,2019-03-20,2018-05-21
-2zxm,2009-02-17,2009-01-04
-3zxz,2011-08-31,2011-08-16
-2zx2,2009-06-30,2008-12-19
-5zxd,2018-07-25,2018-05-18
-4zxb,2016-02-24,2015-05-20
-1zxn,2005-08-23,2005-06-08
-1zxy,2006-05-23,2005-06-09
-4zxx,2015-07-22,2015-05-20
-4zxu,2015-06-17,2015-05-20
-3zxh,2011-10-19,2011-08-10
-6zxg,2020-12-02,2020-07-29
-4zxs,2015-11-11,2015-05-20
-3zxk,2012-04-18,2011-08-11
-2zxa,2009-12-08,2008-12-22
-4zxi,2015-12-30,2015-05-20
-4zxy,2015-07-22,2015-05-20
-2zx6,2009-12-08,2008-12-19
-7zxk,2022-11-02,2022-05-21
-6zxm,2021-03-31,2020-07-29
-4zx1,2015-10-28,2015-05-20
-3zx7,2012-09-19,2011-08-08
-6zxs,2021-07-07,2020-07-30
-1zxc,2005-09-27,2005-06-07
-5zxw,2018-06-13,2018-05-22
-2zxe,2009-05-19,2008-12-22
-5zxu,2019-04-03,2018-05-21
-4zxc,2015-09-02,2015-05-20
-6zxv,2020-09-23,2020-07-30
-2zxr,2010-01-05,2009-01-05
-6zx1,2022-02-23,2020-07-29
-2zx9,2009-12-08,2008-12-22
-2zxu,2009-05-26,2009-01-07
-4zxw,2015-06-17,2015-05-20
-3zxd,2012-09-19,2011-08-09
-6zx3,2022-02-23,2020-07-29
-6zxh,2020-12-16,2020-07-29
-3zxw,2012-08-29,2011-08-16
-7zxc,2023-03-15,2022-05-20
-3zxs,2012-02-15,2011-08-15
-6zx0,2022-02-23,2020-07-29
-7zx1,2022-10-12,2022-05-19
-7zxs,2022-09-28,2022-05-22
-3zx4,2011-10-19,2011-08-07
-2zxw,2009-02-24,2009-01-08
-5zxh,2019-05-22,2018-05-21
-4zx9,2016-03-30,2015-05-20
-2zxc,2009-02-03,2008-12-22
-1zxm,2005-08-23,2005-06-08
-7zxz,2022-06-15,2022-05-23
-1zxi,2005-10-11,2005-06-08
-3zx0,2011-11-30,2011-08-04
-6zxu,2020-09-16,2020-07-30
-7zxl,2023-03-15,2022-05-21
-3zxi,2011-11-16,2011-08-11
-2zxi,2009-05-19,2008-12-24
-7zxg,2022-06-22,2022-05-20
-6zxq,2021-08-11,2020-07-30
-6zxc,2021-03-31,2020-07-29
-1zx9,2005-07-05,2005-06-07
-6zxi,2021-08-11,2020-07-29
-4zx3,2016-03-30,2015-05-20
-1zxz,2005-09-27,2005-06-09
-4zx2,2016-04-27,2015-05-19
-6zxe,2020-12-02,2020-07-29
-5zx3,2019-03-20,2018-05-17
-5zxf,2018-08-22,2018-05-19
-4zx8,2016-03-30,2015-05-20
-2zxl,2009-05-05,2008-12-29
-3zxv,2012-04-04,2011-08-16
-7zx5,2023-03-15,2022-05-20
-2zxd,2009-12-08,2008-12-22
-2zx3,2009-06-30,2008-12-19
-6zxn,2020-09-23,2020-07-30
-3zxo,2011-08-24,2011-08-13
-7zxn,2023-05-31,2022-05-21
-6zxa,2021-02-24,2020-07-29
-7zxy,2022-07-06,2022-05-23
-1zxb,2006-06-13,2005-06-07
-2zxh,2009-05-19,2008-12-24
-5zxg,2018-09-12,2018-05-20
-4zx4,2016-03-30,2015-05-20
-7zxf,2022-06-22,2022-05-20
-6zxt,2020-11-04,2020-07-30
-2zxz,2009-08-11,2009-01-09
-2zxq,2009-06-16,2009-01-05
-3zx1,2011-12-14,2011-08-04
-7zxb,2023-11-29,2022-05-20
-6zx9,2021-07-21,2020-07-29
-2zx7,2009-12-08,2008-12-19
-4zxq,2015-08-26,2015-05-20
-2zxk,2009-05-05,2008-12-29
-4zxn,2016-05-11,2015-05-20
-3zxr,2012-04-04,2011-08-15
-6zx2,2022-02-23,2020-07-29
-4zxl,2015-09-23,2015-05-20
-1zx8,2005-07-26,2005-06-07
-7zxj,2023-03-15,2022-05-21
-7zxd,2023-04-05,2022-05-20
-7zxu,2022-06-29,2022-05-23
-6zxf,2020-12-02,2020-07-29
-5zx2,2019-03-20,2018-05-17
-7zx2,2022-11-23,2022-05-20
-7zxa,2023-05-31,2022-05-20
-2zx4,2009-06-30,2008-12-19
-2zxf,2009-08-25,2008-12-23
-6zxx,2020-09-16,2020-07-30
-1zxl,2006-06-13,2005-06-08
-7zx6,2023-03-15,2022-05-20
-5zxk,2019-04-03,2018-05-21
-1zx1,2005-06-14,2005-06-06
-4zxo,2016-06-29,2015-05-20
-5zxe,2019-07-24,2018-05-19
-4zxh,2015-12-30,2015-05-20
-3zxu,2012-03-14,2011-08-15
-4zx0,2015-10-28,2015-05-19
-7zx8,2022-12-07,2022-05-20
-5zxi,2019-04-03,2018-05-21
-5zxm,2019-05-22,2018-05-21
-1zx5,2005-07-19,2005-06-06
-2zxb,2009-12-08,2008-12-22
-2zx5,2009-12-08,2008-12-19
-4zx5,2016-03-30,2015-05-20
-5zxa,2019-05-29,2018-05-18
-7zxe,2022-11-30,2022-05-20
-7zxw,2022-11-30,2022-05-23
-7zx0,2022-10-12,2022-05-19
-4zxa,2015-09-02,2015-05-20
-6zxo,2021-05-19,2020-07-30
-3zx3,2011-11-30,2011-08-04
-4zx6,2016-03-30,2015-05-20
-3zx5,2011-10-19,2011-08-07
-7zxv,2023-02-01,2022-05-23
-6sr1,2020-04-22,2019-09-04
-3sre,2012-03-21,2011-07-07
-2srt,1995-07-10,1995-03-22
-8sr1,2023-11-15,2023-05-05
-5sr8,2022-07-06,2022-06-09
-6srz,2020-04-01,2019-09-06
-5srx,2022-07-06,2022-06-09
-3srk,2012-07-18,2011-07-07
-6sre,2020-07-15,2019-09-05
-1sri,1994-11-01,1994-02-17
-1srf,1994-11-01,1994-02-17
-1srd,1994-01-31,1993-04-15
-5sru,2022-07-06,2022-06-09
-6sr2,2020-04-22,2019-09-04
-5srk,2022-07-06,2022-06-09
-7sr2,2021-11-17,2021-11-07
-3srf,2012-08-08,2011-07-07
-6sr6,2020-03-25,2019-09-05
-1sr7,2004-06-22,2004-03-22
-5src,2022-07-06,2022-06-09
-3sr0,2012-10-10,2011-07-06
-6sr9,2020-09-30,2019-09-05
-5srv,2022-07-06,2022-06-09
-5srf,2022-07-06,2022-06-09
-5srz,2022-07-06,2022-06-09
-3srg,2012-03-21,2011-07-07
-6sr4,2020-04-22,2019-09-04
-3srw,2011-08-31,2011-07-07
-3sr4,2011-10-05,2011-07-06
-5sri,2022-07-06,2022-06-09
-5sr2,2022-07-06,2022-06-09
-8sr6,2024-03-13,2023-05-05
-5sro,2022-07-06,2022-06-09
-5srl,2022-07-06,2022-06-09
-6srg,2020-07-15,2019-09-05
-5srs,2022-07-06,2022-06-09
-5sr5,2022-07-06,2022-06-09
-8srx,2023-12-27,2023-05-07
-8srj,2024-05-15,2023-05-05
-5sry,2022-07-06,2022-06-09
-3srx,2011-07-20,2011-07-07
-8src,2024-05-08,2023-05-05
-5srg,2022-07-06,2022-06-09
-2src,1999-07-22,1998-12-29
-8sr2,2023-11-15,2023-05-05
-5srj,2022-07-06,2022-06-09
-3srb,2011-09-21,2011-07-07
-3srd,2012-08-08,2011-07-07
-7sr9,2021-12-08,2021-11-08
-8srl,2024-05-15,2023-05-05
-8srd,2024-05-15,2023-05-05
-5srm,2022-07-06,2022-06-09
-7srr,2022-09-21,2021-11-08
-3sr5,2011-08-31,2011-07-06
-5srq,2022-07-06,2022-06-09
-8sr9,2024-05-08,2023-05-05
-3srr,2011-08-31,2011-07-07
-6sr3,2020-04-22,2019-09-04
-3srv,2011-09-21,2011-07-07
-1sr0,2004-05-25,2004-03-22
-5srh,2022-07-06,2022-06-09
-7srs,2022-09-21,2021-11-08
-1srp,1995-02-14,1994-11-02
-7srv,2022-06-29,2021-11-08
-7sr8,2022-06-08,2021-11-08
-3srj,2012-07-11,2011-07-07
-6sra,2020-09-30,2019-09-05
-5sr6,2022-07-06,2022-06-09
-1sr6,2004-06-15,2004-03-22
-8sr7,2024-05-08,2023-05-05
-6srw,2020-04-01,2019-09-06
-1srg,1994-12-20,1994-02-17
-1sra,1996-03-08,1995-08-21
-8srk,2024-05-15,2023-05-05
-5sra,2022-07-06,2022-06-09
-3srq,2011-08-31,2011-07-07
-6srf,2020-07-15,2019-09-05
-6srd,2020-05-27,2019-09-05
-3sru,2011-08-31,2011-07-07
-6sr5,2020-04-22,2019-09-04
-1sr9,2004-05-18,2004-03-22
-8sra,2024-05-08,2023-05-05
-3sr1,2011-07-27,2011-07-06
-7srq,2022-09-21,2021-11-08
-8srb,2024-05-08,2023-05-05
-6sr8,2020-09-30,2019-09-05
-6srt,2020-09-30,2019-09-06
-8srf,2024-05-15,2023-05-05
-5srw,2022-07-06,2022-06-09
-1srh,1994-11-01,1994-02-17
-8sre,2024-05-15,2023-05-05
-8sr5,2023-11-29,2023-05-05
-6srh,2019-09-18,2019-09-05
-7sr6,2022-07-20,2021-11-08
-3src,2011-09-21,2011-07-07
-1srj,1994-11-01,1994-02-17
-8sr8,2024-05-08,2023-05-05
-5srt,2022-07-06,2022-06-09
-5sr9,2022-07-06,2022-06-09
-5sre,2022-07-06,2022-06-09
-1sr5,2004-08-17,2004-03-22
-5srb,2022-07-06,2022-06-09
-3sr6,2011-07-27,2011-07-07
-8srg,2024-05-15,2023-05-05
-8sr4,2023-11-15,2023-05-05
-3srz,2012-02-01,2011-07-07
-6sry,2020-04-01,2019-09-06
-3srs,2011-08-31,2011-07-07
-5srd,2022-07-06,2022-06-09
-1srk,2004-09-21,2004-03-22
-6srn,2020-09-30,2019-09-05
-6sr0,2020-04-22,2019-09-04
-1sre,1994-11-01,1994-02-17
-5srn,2022-07-06,2022-06-09
-8srs,2024-05-01,2023-05-06
-5srr,2022-07-06,2022-06-09
-5sr4,2022-07-06,2022-06-09
-8sr0,2023-09-06,2023-05-05
-5sr1,2022-07-06,2022-06-09
-6srb,2020-09-30,2019-09-05
-8sri,2024-05-15,2023-05-05
-5sr7,2022-07-06,2022-06-09
-5sr0,2022-07-06,2022-06-09
-5srp,2022-07-06,2022-06-09
-5sr3,2022-07-06,2022-06-09
-1srr,1997-04-21,1996-04-10
-8srh,2024-05-15,2023-05-05
-7wdi,2022-12-28,2021-12-21
-5wdq,2017-07-19,2017-07-05
-3wd1,2013-09-18,2013-06-06
-1wd3,2004-09-14,2004-05-11
-3wdy,2014-07-09,2013-06-25
-2wdv,2009-08-25,2009-03-26
-2wd7,2009-06-30,2009-03-20
-3wdh,2014-06-18,2013-06-18
-8wd2,2023-10-04,2023-09-14
-6wdo,2020-05-27,2020-04-01
-5wdj,2018-04-18,2017-07-05
-3wdj,2014-04-30,2013-06-18
-3wd6,2014-07-16,2013-06-07
-1wd2,2004-07-20,2004-05-11
-4wda,2015-09-23,2014-09-08
-4wd1,2015-01-28,2014-09-05
-8wdu,2024-02-21,2023-09-16
-2wd8,2009-06-30,2009-03-20
-7wdg,2022-12-28,2021-12-21
-2wdu,2010-04-21,2009-03-26
-1wdm,2004-07-27,2004-05-17
-6wda,2020-07-08,2020-03-31
-6wd9,2020-07-08,2020-03-31
-2wdy,2010-04-21,2009-03-27
-3wd3,2013-09-18,2013-06-06
-8wdv,2024-02-21,2023-09-16
-3wd7,2013-09-04,2013-06-10
-2wdw,2010-04-07,2009-03-27
-1wdn,1998-05-06,1997-05-17
-7wd2,2022-12-21,2021-12-20
-2wdz,2010-03-31,2009-03-27
-1wdk,2004-07-27,2004-05-17
-1wdy,2004-10-05,2004-05-19
-5wdu,2018-04-04,2017-07-06
-7wdd,2022-12-28,2021-12-21
-6wdy,2020-07-22,2020-04-01
-5wdw,2018-01-03,2017-07-06
-3wdr,2014-03-05,2013-06-20
-7wdw,2022-06-01,2021-12-22
-2wd1,2009-04-28,2009-03-19
-6wdv,2020-07-22,2020-04-01
-1wds,2005-04-05,2004-05-17
-4wd4,2015-09-09,2014-09-06
-5wdx,2017-11-08,2017-07-06
-2wdd,2009-06-16,2009-03-24
-4wd8,2014-10-01,2014-09-08
-7wd6,2022-12-21,2021-12-21
-4wdr,2015-12-23,2014-09-09
-7wdn,2023-01-04,2021-12-22
-8wd3,2023-11-22,2023-09-14
-7wda,2022-05-18,2021-12-21
-3wdd,2013-09-18,2013-06-14
-7wdq,2022-06-01,2021-12-22
-7wdu,2022-12-28,2021-12-22
-7wdt,2022-12-28,2021-12-22
-7wdv,2022-11-02,2021-12-22
-4wdu,2015-04-15,2014-09-09
-2wds,2010-04-21,2009-03-26
-4wdt,2015-04-15,2014-09-09
-6wd3,2020-07-08,2020-03-31
-5wdl,2018-07-11,2017-07-05
-3wdu,2014-07-09,2013-06-25
-7wdc,2022-07-20,2021-12-21
-2wdr,2009-08-25,2009-03-25
-3wd4,2013-09-18,2013-06-06
-1wdt,2005-05-17,2004-05-17
-3wd2,2013-09-18,2013-06-06
-8wdg,2023-10-04,2023-09-15
-3wds,2014-06-25,2013-06-22
-6wd5,2020-07-08,2020-03-31
-4wdq,2015-12-23,2014-09-09
-2wdo,2010-04-21,2009-03-25
-1wdl,2004-07-27,2004-05-17
-5wd6,2018-07-11,2017-07-04
-3wdk,2014-04-02,2013-06-19
-3wde,2013-09-18,2013-06-14
-2wda,2010-04-21,2009-03-23
-5wdr,2017-07-19,2017-07-05
-5wdt,2018-04-25,2017-07-06
-8wdx,2023-12-27,2023-09-16
-3wdm,2014-04-02,2013-06-19
-4wdb,2015-09-23,2014-09-08
-4wdx,2015-04-15,2014-09-09
-6wd4,2020-07-08,2020-03-31
-7wde,2022-12-28,2021-12-21
-2wd3,2010-02-23,2009-03-19
-6wdu,2021-03-10,2020-04-01
-4wdf,2015-09-23,2014-09-08
-2wd2,2010-03-31,2009-03-19
-6wd8,2020-07-08,2020-03-31
-6wdx,2020-07-22,2020-04-01
-7wd1,2022-12-21,2021-12-20
-4wd5,2016-05-04,2014-09-07
-4wd6,2014-09-17,2014-09-07
-6wd6,2020-07-08,2020-03-31
-7wdh,2022-12-28,2021-12-21
-5wds,2017-07-19,2017-07-05
-5wdy,2017-08-16,2017-07-06
-6wd2,2020-07-08,2020-03-31
-5wdh,2017-08-09,2017-07-05
-2wd9,2009-04-21,2009-03-21
-7wd3,2022-12-14,2021-12-21
-8wd8,2024-01-31,2023-09-14
-3wdi,2014-06-04,2013-06-18
-5wdp,2017-07-19,2017-07-05
-2wd4,2009-04-07,2009-03-19
-8wd4,2023-12-20,2023-09-14
-2wde,2009-06-16,2009-03-24
-3wdl,2014-04-02,2013-06-19
-1wdq,2005-04-05,2004-05-17
-5wdo,2017-07-19,2017-07-05
-8wdt,2024-01-17,2023-09-16
-1wda,2004-07-13,2004-05-12
-7wdb,2022-04-13,2021-12-21
-6wdw,2020-07-22,2020-04-01
-6wdq,2021-02-24,2020-04-01
-7wds,2022-11-02,2021-12-22
-1wd9,2004-07-13,2004-05-12
-1wdw,2005-07-12,2004-05-19
-5wdg,2018-07-11,2017-07-05
-4wdi,2015-06-24,2014-09-08
-6wdz,2020-12-16,2020-04-01
-7wdo,2022-11-02,2021-12-22
-2wd6,2009-07-28,2009-03-20
-2wdb,2009-05-05,2009-03-23
-7wdr,2022-11-02,2021-12-22
-3wdc,2013-09-18,2013-06-14
-5wdk,2018-07-11,2017-07-05
-1wdc,1996-07-11,1996-01-19
-3wd9,2013-10-23,2013-06-11
-4wdw,2015-04-15,2014-09-09
-3wdx,2014-07-09,2013-06-25
-8wdh,2023-11-29,2023-09-15
-2wdc,2009-06-16,2009-03-24
-4wdg,2015-09-23,2014-09-08
-2wdf,2009-06-16,2009-03-24
-4wd7,2014-10-01,2014-09-08
-5wda,2017-10-25,2017-07-04
-5wdn,2018-01-03,2017-07-05
-3wdv,2014-07-09,2013-06-25
-1wdd,2004-11-13,2004-05-13
-1wdr,2005-04-05,2004-05-17
-2wd0,2010-04-21,2009-03-18
-7wdp,2022-11-02,2021-12-22
-2wdq,2009-08-25,2009-03-25
-1wd4,2004-09-14,2004-05-11
-3wdq,2014-03-05,2013-06-20
-5wdc,2018-01-03,2017-07-04
-6wi1,2020-07-15,2020-04-08
-5wi5,2017-08-02,2017-07-18
-5wiy,2018-09-26,2017-07-20
-2wih,2009-07-28,2009-05-13
-3wig,2014-06-04,2013-09-12
-6wi4,2020-08-26,2020-04-08
-4wi4,2015-09-30,2014-09-25
-4wi9,2015-09-30,2014-09-25
-3wiq,2014-02-05,2013-09-24
-3wif,2014-09-17,2013-09-12
-6wib,2021-09-15,2020-04-09
-3wiu,2014-10-01,2013-09-25
-7wi0,2022-06-22,2022-01-01
-6wic,2020-10-07,2020-04-09
-6wif,2020-04-22,2020-04-09
-5wik,2018-08-01,2017-07-19
-2wif,2009-05-19,2009-05-11
-7wi7,2023-01-25,2022-01-03
-4wis,2014-11-12,2014-09-26
-1wir,2004-11-28,2004-05-28
-5wia,2018-04-25,2017-07-18
-4wio,2015-12-02,2014-09-26
-5wiu,2017-10-18,2017-07-20
-3wiv,2014-10-01,2013-09-25
-6wi0,2020-07-15,2020-04-08
-7wiv,2023-01-25,2022-01-05
-2wi9,2009-10-27,2009-05-08
-3wi6,2013-12-18,2013-09-06
-4wiu,2014-10-22,2014-09-26
-2wig,2009-05-19,2009-05-11
-7wic,2022-06-01,2022-01-03
-5wip,2017-11-15,2017-07-19
-7wi8,2022-03-16,2022-01-03
-2wid,2009-05-19,2009-05-11
-2wic,2010-05-19,2009-05-09
-4wi3,2015-09-30,2014-09-25
-7wiy,2022-10-05,2022-01-05
-6wiw,2020-06-17,2020-04-10
-2wiq,2009-08-11,2009-05-15
-2wis,2009-08-11,2009-05-15
-3wij,2014-09-17,2013-09-13
-6wis,2020-06-24,2020-04-10
-5wiz,2019-01-23,2017-07-21
-4wiv,2014-10-29,2014-09-26
-5wiw,2017-12-20,2017-07-20
-5wis,2018-02-14,2017-07-20
-5wii,2017-11-15,2017-07-19
-7wih,2022-03-16,2022-01-03
-6wid,2020-10-07,2020-04-09
-7wig,2022-06-01,2022-01-03
-6wi7,2021-04-14,2020-04-08
-7wi6,2022-03-16,2022-01-03
-2wik,2009-05-19,2009-05-12
-3wia,2014-07-23,2013-09-09
-4wi5,2015-09-30,2014-09-25
-8wiu,2024-01-03,2023-09-25
-5wi1,2018-01-10,2017-07-18
-1wim,2004-11-28,2004-05-28
-2wil,2009-05-26,2009-05-12
-6wi3,2021-04-21,2020-04-08
-2wi3,2009-07-28,2009-05-08
-2wiu,2009-07-28,2009-05-17
-4wi2,2015-09-30,2014-09-25
-4wif,2015-09-09,2014-09-25
-7wiz,2023-01-11,2022-01-05
-1wil,2004-11-28,2004-05-28
-6wia,2020-04-29,2020-04-09
-1wig,2004-11-28,2004-05-28
-3wio,2013-10-23,2013-09-22
-2win,2009-06-09,2009-05-13
-5wi3,2017-12-27,2017-07-18
-2wia,2010-05-19,2009-05-09
-4wiz,2015-10-07,2014-09-28
-4wie,2014-10-22,2014-09-25
-6wi2,2020-04-22,2020-04-08
-5wi7,2017-12-27,2017-07-18
-5win,2018-08-01,2017-07-19
-6wiz,2020-07-01,2020-04-11
-1wiy,2004-11-28,2004-05-28
-8wil,2024-01-17,2023-09-24
-3wie,2014-05-14,2013-09-10
-7wik,2022-12-21,2022-01-03
-3wiy,2013-11-27,2013-09-26
-5wid,2018-08-08,2017-07-19
-5wim,2018-08-01,2017-07-19
-2wi4,2009-07-28,2009-05-08
-2wi7,2009-07-28,2009-05-08
-2wi1,2009-07-28,2009-05-08
-7wiw,2023-01-25,2022-01-05
-2wiy,2009-08-18,2009-05-18
-3wis,2014-02-19,2013-09-25
-3wiz,2013-11-27,2013-09-26
-2wi2,2009-07-28,2009-05-08
-5wig,2017-10-18,2017-07-19
-5wij,2018-08-01,2017-07-19
-8wim,2024-01-17,2023-09-24
-5wir,2017-10-18,2017-07-20
-4wib,2014-12-03,2014-09-25
-4wi8,2015-09-30,2014-09-25
-5wi6,2018-04-25,2017-07-18
-6wix,2020-11-25,2020-04-10
-6wie,2020-10-07,2020-04-09
-5wio,2017-11-15,2017-07-19
-3wi9,2014-07-23,2013-09-09
-3wi1,2013-12-18,2013-09-04
-6wiv,2020-07-01,2020-04-10
-4wiw,2014-10-08,2014-09-26
-2wiv,2009-08-18,2009-05-18
-4wi6,2015-09-30,2014-09-25
-6wij,2021-04-14,2020-04-10
-2wib,2010-05-19,2009-05-09
-6wit,2021-04-14,2020-04-10
-5wiq,2018-04-18,2017-07-19
-3wid,2014-05-14,2013-09-10
-5wih,2017-10-18,2017-07-19
-5wi9,2018-07-25,2017-07-18
-5wiv,2017-10-18,2017-07-20
-2wi6,2009-07-28,2009-05-08
-7wi1,2023-01-18,2022-01-01
-5wi8,2017-12-20,2017-07-18
-2wip,2009-07-28,2009-05-14
-3wi2,2013-12-11,2013-09-04
-5wi0,2018-01-10,2017-07-18
-3wir,2014-02-05,2013-09-24
-4wi7,2015-09-30,2014-09-25
-2wi0,2010-05-12,2009-05-07
-2wii,2009-06-09,2009-05-12
-7wit,2022-11-16,2022-01-04
-2wi5,2009-07-28,2009-05-08
-5wie,2017-08-30,2017-07-19
-6wii,2020-07-29,2020-04-09
-5wif,2017-08-02,2017-07-19
-5wib,2017-12-27,2017-07-19
-1wii,2004-11-28,2004-05-28
-2wim,2010-08-25,2009-05-13
-4wi0,2015-10-07,2014-09-24
-6wih,2020-05-13,2020-04-09
-3wil,2014-09-24,2013-09-18
-7wid,2022-11-16,2022-01-03
-7wi4,2022-06-01,2022-01-02
-2wio,2009-07-21,2009-05-14
-3wic,2014-05-14,2013-09-10
-5wic,2017-11-15,2017-07-19
-5wil,2018-08-01,2017-07-19
-5wit,2018-02-14,2017-07-20
-7wis,2022-11-16,2022-01-04
-4wi1,2016-05-04,2014-09-25
-7wix,2023-01-25,2022-01-05
-4wig,2015-08-12,2014-09-25
-2wie,2009-09-29,2009-05-11
-8wik,2024-05-08,2023-09-24
-3wip,2014-04-23,2013-09-24
-6wi8,2021-04-14,2020-04-09
-3wik,2014-11-05,2013-09-18
-4wit,2014-11-12,2014-09-26
-3wi8,2014-03-26,2013-09-09
-2wij,2009-05-19,2009-05-12
-3wix,2013-11-27,2013-09-26
-7wir,2022-11-16,2022-01-04
-4auu,2012-06-27,2012-05-22
-8aue,2023-03-01,2022-08-25
-4aui,2012-10-10,2012-05-17
-2aup,2006-03-28,2005-08-28
-8aug,2023-03-01,2022-08-25
-8aun,2023-03-01,2022-08-25
-6aub,2018-09-12,2017-08-31
-5aus,2015-10-21,2015-06-08
-7aud,2020-12-16,2020-11-02
-5aur,2015-10-21,2015-06-08
-2auq,2006-03-28,2005-08-28
-7aux,2021-07-21,2020-11-03
-6aus,2018-07-11,2017-09-01
-1au2,1998-10-14,1997-09-10
-3aun,2012-02-15,2011-02-10
-6au6,2018-05-09,2017-08-30
-6aux,2018-07-11,2017-09-01
-8auu,2023-09-06,2022-08-25
-4aum,2013-02-27,2012-05-18
-2aur,2006-03-28,2005-08-28
-5aum,2016-08-10,2015-04-30
-8auq,2023-03-01,2022-08-25
-5auz,2015-10-07,2015-06-10
-5auu,2015-10-07,2015-06-10
-7auv,2021-10-06,2020-11-03
-2au6,2006-08-29,2005-08-27
-3au6,2012-01-25,2011-01-28
-4aue,2013-02-27,2012-05-17
-8aut,2022-11-02,2022-08-25
-4auo,2012-07-11,2012-05-18
-6aum,2018-02-07,2017-09-01
-1aus,1995-10-15,1995-06-21
-4au1,2012-09-19,2012-05-11
-8au9,2023-03-01,2022-08-25
-8auj,2023-03-01,2022-08-25
-4auc,2013-05-29,2012-05-16
-4auj,2013-05-29,2012-05-17
-5aux,2015-10-07,2015-06-10
-7au9,2021-08-11,2020-11-02
-7auz,2021-02-17,2020-11-03
-8au3,2023-09-06,2022-08-25
-3au1,2011-10-12,2011-01-28
-6au2,2017-10-11,2017-08-30
-5aut,2015-10-07,2015-06-10
-6au9,2018-09-05,2017-08-31
-8auz,2023-04-19,2022-08-26
-4au7,2013-05-22,2012-05-14
-6auc,2018-02-28,2017-08-31
-3auy,2011-05-25,2011-02-18
-1aut,1997-08-20,1996-06-08
-7au0,2021-08-11,2020-11-02
-8aui,2023-03-01,2022-08-25
-3au8,2011-08-10,2011-02-01
-6auu,2018-07-11,2017-09-01
-4auw,2013-06-05,2012-05-22
-3au0,2011-05-04,2011-01-28
-3auo,2012-01-25,2011-02-11
-7auf,2021-08-11,2020-11-03
-7aun,2021-05-19,2020-11-03
-1au3,1998-10-14,1997-09-10
-1auj,1998-10-14,1997-08-28
-7auc,2020-12-16,2020-11-02
-7aul,2021-05-19,2020-11-03
-3auu,2012-02-22,2011-02-16
-6auo,2018-02-28,2017-09-01
-6aut,2018-07-11,2017-09-01
-7au5,2021-07-07,2020-11-02
-5aun,2015-06-24,2015-05-27
-1auk,1998-03-04,1997-08-29
-2au0,2006-01-10,2005-08-26
-8auo,2023-03-01,2022-08-25
-4auy,2012-06-27,2012-05-22
-6auq,2018-07-11,2017-09-01
-5aul,2016-05-25,2015-04-28
-2aut,2006-09-05,2005-08-29
-4auq,2012-08-15,2012-05-21
-4aun,2013-02-27,2012-05-18
-6auv,2018-07-11,2017-09-01
-1au4,1998-10-14,1997-09-10
-7au2,2022-05-18,2020-11-02
-7aup,2021-05-19,2020-11-03
-8aub,2023-03-01,2022-08-25
-8auw,2023-02-15,2022-08-25
-7au7,2021-11-10,2020-11-02
-3aut,2012-02-22,2011-02-16
-2auu,2006-08-29,2005-08-29
-7auw,2021-04-14,2020-11-03
-7auq,2021-05-19,2020-11-03
-7aum,2021-05-19,2020-11-03
-3aur,2011-09-14,2011-02-15
-7au8,2021-08-11,2020-11-02
-8auv,2023-06-07,2022-08-25
-7auj,2021-05-19,2020-11-03
-8au6,2023-01-18,2022-08-25
-4au9,2012-12-26,2012-05-14
-7auu,2021-05-19,2020-11-03
-9auc,2024-04-24,2024-02-28
-3auk,2012-02-08,2011-02-08
-1auq,1998-10-14,1997-09-01
-8au2,2023-09-20,2022-08-25
-4aul,2013-02-27,2012-05-18
-6aue,2018-02-28,2017-08-31
-1aux,1998-03-18,1997-09-06
-1aui,1997-12-03,1997-08-27
-6aua,2018-09-12,2017-08-31
-1au0,1998-10-14,1997-09-09
-2aux,2006-08-08,2005-08-29
-6aul,2018-02-28,2017-09-01
-8aus,2023-09-20,2022-08-25
-7auy,2021-03-03,2020-11-03
-3aua,2011-08-10,2011-02-01
-8au8,2023-03-01,2022-08-25
-8auy,2023-09-20,2022-08-26
-8aua,2023-03-01,2022-08-25
-7aus,2021-05-19,2020-11-03
-4aua,2013-02-06,2012-05-15
-6auw,2018-07-11,2017-09-01
-5auv,2015-10-07,2015-06-10
-6aur,2018-07-11,2017-09-01
-3au7,2011-10-19,2011-01-31
-7aut,2021-05-19,2020-11-03
-8auh,2023-03-01,2022-08-25
-7auh,2021-08-11,2020-11-03
-6au5,2017-12-13,2017-08-30
-5auo,2015-06-24,2015-05-27
-7au3,2021-12-01,2020-11-02
-8auf,2023-03-01,2022-08-25
-8aum,2023-03-01,2022-08-25
-4aux,2012-05-30,2012-05-22
-8aul,2023-03-01,2022-08-25
-3auq,2011-09-14,2011-02-15
-2auh,2005-11-01,2005-08-27
-6au0,2019-01-16,2017-08-29
-7aue,2021-04-28,2020-11-02
-6aud,2017-11-15,2017-08-31
-3au2,2012-01-25,2011-01-28
-6aug,2018-09-12,2017-08-31
-6au3,2017-09-27,2017-08-30
-7au1,2021-08-11,2020-11-02
-2au9,2006-08-29,2005-08-27
-8au5,2023-09-06,2022-08-25
-7auk,2021-05-19,2020-11-03
-1au1,1998-06-17,1997-09-09
-6auy,2018-07-11,2017-09-01
-7au6,2021-12-01,2020-11-02
-7aub,2021-08-11,2020-11-02
-7aua,2022-05-18,2020-11-02
-1au9,1997-12-31,1997-09-12
-5aup,2015-06-24,2015-05-27
-5auy,2015-10-07,2015-06-10
-7auo,2021-05-19,2020-11-03
-7aug,2021-10-27,2020-11-03
-4aub,2012-06-06,2012-05-16
-4au8,2013-03-27,2012-05-14
-2auy,2006-08-08,2005-08-29
-7au4,2022-02-23,2020-11-02
-6aui,2018-04-18,2017-09-01
-2auo,2006-03-28,2005-08-28
-2aus,2006-07-11,2005-08-29
-3au9,2011-08-10,2011-02-01
-3auj,2012-02-22,2011-02-07
-3aux,2011-05-25,2011-02-17
-3auz,2011-05-25,2011-02-18
-1au8,1998-10-14,1997-09-12
-2au8,2006-08-29,2005-08-27
-5auw,2015-10-07,2015-06-10
-2auz,2006-08-08,2005-08-29
-3auw,2011-10-05,2011-02-17
-2au7,2006-08-29,2005-08-27
-8auk,2023-02-15,2022-08-25
-6auh,2018-02-28,2017-09-01
-4au0,2013-01-23,2012-05-11
-2au3,2005-11-15,2005-08-26
-6auf,2018-09-12,2017-08-31
-4aut,2012-09-05,2012-05-21
-6auz,2018-07-11,2017-09-01
-7aur,2021-05-19,2020-11-03
-5yi3,2017-12-06,2017-10-01
-1yie,2005-01-18,2005-01-11
-7yiv,2023-07-19,2022-07-18
-7yid,2023-04-05,2022-07-16
-7yi3,2023-06-14,2022-07-14
-6yi6,2021-04-14,2020-04-01
-6yin,2020-04-15,2020-04-01
-4yi7,2015-09-02,2015-02-28
-4yiy,2015-08-12,2015-03-02
-7yia,2023-05-31,2022-07-15
-6yiw,2020-12-02,2020-04-01
-6yib,2021-04-14,2020-04-01
-2yix,2011-11-30,2011-05-17
-5yia,2018-07-11,2017-10-03
-2yi7,2012-05-16,2011-05-10
-2yi6,2012-05-16,2011-05-10
-7yi4,2023-06-14,2022-07-14
-7yih,2023-04-05,2022-07-16
-7yif,2023-04-05,2022-07-16
-2yid,2011-06-15,2011-05-11
-6yif,2020-05-13,2020-04-01
-5yiv,2018-03-21,2017-10-06
-1yi8,2005-02-22,2005-01-11
-1yic,1997-07-23,1997-02-18
-7yi0,2023-06-14,2022-07-14
-4yih,2015-09-09,2015-03-02
-2yi9,2011-07-20,2011-05-11
-6yik,2020-04-15,2020-04-01
-1yil,2005-02-08,2005-01-12
-2yiv,2012-03-28,2011-05-16
-5yic,2018-07-11,2017-10-03
-5yig,2018-09-05,2017-10-04
-7yit,2023-04-12,2022-07-18
-4yip,2016-01-13,2015-03-02
-1yiq,2005-08-16,2005-01-12
-4yij,2015-03-18,2015-03-02
-5yix,2018-03-21,2017-10-06
-1yi1,2006-01-17,2005-01-10
-6yiv,2020-12-02,2020-04-01
-2yi1,2012-02-29,2011-05-10
-4yiw,2016-08-10,2015-03-02
-6yix,2020-12-02,2020-04-01
-6yi7,2020-12-16,2020-04-01
-4yix,2015-08-12,2015-03-02
-6yit,2020-12-02,2020-04-01
-7yi7,2022-12-07,2022-07-15
-4yiz,2015-05-20,2015-03-02
-6yi4,2020-04-08,2020-03-31
-1yit,2005-04-26,2005-01-13
-4yig,2015-06-10,2015-03-02
-6yid,2020-06-17,2020-04-01
-2yis,2011-11-30,2011-05-16
-1yia,2005-02-22,2005-01-11
-2yip,2011-11-02,2011-05-16
-4yil,2016-01-20,2015-03-02
-7yiy,2023-07-05,2022-07-18
-2yiy,2012-05-23,2011-05-17
-6yiu,2020-12-02,2020-04-01
-1yiy,2005-05-10,2005-01-13
-6yis,2020-12-02,2020-04-01
-7yis,2023-05-03,2022-07-18
-5yir,2018-05-23,2017-10-06
-6yig,2021-04-14,2020-04-01
-6yim,2020-04-15,2020-04-01
-1yi4,2005-01-25,2005-01-11
-2yi5,2012-05-16,2011-05-10
-2yiu,2011-10-26,2011-05-16
-2yi8,2011-07-20,2011-05-11
-1yip,2005-11-15,2005-01-12
-1yik,2005-02-08,2005-01-12
-6yi0,2020-04-29,2020-03-31
-6yii,2020-06-17,2020-04-01
-4yio,2016-01-13,2015-03-02
-5yif,2018-08-29,2017-10-04
-6yil,2020-04-15,2020-04-01
-4yit,2016-03-23,2015-03-02
-1yix,2005-01-25,2005-01-13
-5yiq,2018-05-23,2017-10-06
-1yin,2005-07-26,2005-01-12
-4yi8,2015-12-02,2015-02-28
-4yis,2016-03-23,2015-03-02
-5yie,2018-07-11,2017-10-04
-6yiy,2020-12-02,2020-04-01
-7yi6,2023-08-30,2022-07-15
-6yia,2021-04-14,2020-04-01
-4yiv,2015-05-20,2015-03-02
-1yih,2005-01-18,2005-01-11
-7yiw,2023-07-19,2022-07-18
-6yi5,2021-03-24,2020-03-31
-2yik,2012-02-29,2011-05-16
-2yi0,2012-05-16,2011-05-10
-6yih,2020-05-13,2020-04-01
-2yim,2012-03-28,2011-05-16
-7yi5,2023-06-14,2022-07-14
-7yi8,2023-01-18,2022-07-15
-7yi2,2023-06-14,2022-07-14
-7yiu,2023-07-05,2022-07-18
-4yik,2015-09-09,2015-03-02
-2yiq,2011-09-07,2011-05-16
-7yij,2023-04-05,2022-07-16
-8yib,2024-06-05,2024-02-29
-1yim,2005-07-26,2005-01-12
-2yir,2011-09-07,2011-05-16
-7yie,2023-04-05,2022-07-16
-2yih,2011-06-08,2011-05-13
-5yi2,2017-12-06,2017-10-01
-7yig,2023-04-05,2022-07-16
-1yio,2005-09-27,2005-01-12
-2yiw,2011-11-30,2011-05-17
-1yi2,2005-04-26,2005-01-11
-7yix,2023-08-16,2022-07-18
-4yic,2015-04-01,2015-03-01
-5yib,2018-07-11,2017-10-03
-5yid,2018-07-11,2017-10-04
-7yi9,2023-01-18,2022-07-15
-5yij,2018-05-30,2017-10-05
-1yij,2005-04-26,2005-01-12
-1yi3,2005-01-25,2005-01-11
-2yic,2011-06-15,2011-05-11
-1yid,2005-08-02,2005-01-11
-6yiz,2021-04-14,2020-04-01
-4yia,2016-03-02,2015-03-01
-2yio,2011-11-02,2011-05-16
-1yiw,2005-06-14,2005-01-13
-6yi1,2020-07-01,2020-03-31
-4yi3,2015-11-18,2015-02-27
-1yi9,2005-11-15,2005-01-11
-5yi0,2017-12-06,2017-10-01
-5yiz,2018-02-07,2017-10-06
-1yii,2005-03-08,2005-01-11
-6yi8,2020-09-30,2020-04-01
-2yig,2011-06-29,2011-05-13
-4yi5,2015-11-18,2015-02-27
-6yij,2020-04-15,2020-04-01
-2yit,2011-09-07,2011-05-16
-2yiz,2011-10-12,2011-05-17
-6yie,2020-05-13,2020-04-01
-6yiq,2020-04-15,2020-04-01
-2yia,2011-07-20,2011-05-11
-6yic,2021-04-14,2020-04-01
-1yi0,2006-01-17,2005-01-10
-4yi9,2015-12-02,2015-02-28
-5yih,2017-10-25,2017-10-04
-1yi7,2005-02-22,2005-01-11
-4xz9,2015-09-30,2015-02-04
-2xzv,2011-02-09,2010-12-01
-1xzx,2004-12-07,2004-11-12
-1xzo,2005-03-01,2004-11-12
-4xzv,2016-01-20,2015-02-05
-6xzk,2021-02-17,2020-02-04
-7xzh,2023-06-07,2022-06-02
-7xzg,2023-06-07,2022-06-02
-2xzi,2011-01-19,2010-11-26
-4xz0,2015-06-17,2015-02-03
-1xzv,2004-12-07,2004-11-12
-1xzm,1996-11-30,1995-11-28
-2xz9,2011-06-15,2010-11-24
-5xz8,2019-02-27,2017-07-11
-1xzq,2005-01-04,2004-11-12
-7xzt,2022-12-21,2022-06-03
-2xz4,2011-04-13,2010-11-23
-1xz8,2005-03-01,2004-11-11
-4xzp,2016-03-02,2015-02-04
-4xzn,2015-11-18,2015-02-04
-4xzj,2015-09-23,2015-02-04
-4xzk,2016-01-20,2015-02-04
-5xzm,2018-07-18,2017-07-12
-7xz4,2023-01-25,2022-06-02
-4xzw,2016-02-10,2015-02-05
-4xz4,2016-02-03,2015-02-03
-2xz2,2011-01-26,2010-11-22
-4xz6,2015-08-19,2015-02-04
-5xzf,2018-07-25,2017-07-12
-7xzk,2023-06-07,2022-06-02
-5xzo,2018-01-17,2017-07-13
-6xzf,2021-02-17,2020-02-04
-4xzs,2016-01-20,2015-02-04
-2xz5,2010-12-08,2010-11-23
-5xzu,2018-05-02,2017-07-14
-5xzb,2017-08-09,2017-07-12
-2xzq,2011-12-28,2010-12-01
-4xz2,2015-06-03,2015-02-03
-8xzj,2024-03-20,2024-01-21
-6xzh,2021-02-17,2020-02-04
-2xz1,2011-09-07,2010-11-22
-4xzd,2015-08-12,2015-02-04
-6xza,2020-11-04,2020-02-03
-4xz1,2015-07-29,2015-02-03
-4xzl,2015-11-18,2015-02-04
-5xz7,2019-03-13,2017-07-11
-1xzu,2004-12-07,2004-11-12
-5xzi,2017-12-20,2017-07-12
-5xz9,2019-03-13,2017-07-12
-7xzr,2022-10-26,2022-06-03
-6xz0,2020-04-15,2020-01-31
-7xzs,2022-12-21,2022-06-03
-5xzv,2017-10-11,2017-07-14
-1xzw,2004-12-14,2004-11-12
-2xzw,2010-12-08,2010-11-29
-2xz0,2011-09-07,2010-11-22
-6xzv,2021-02-17,2020-02-05
-6xz7,2020-07-22,2020-02-03
-2xz8,2011-04-13,2010-11-24
-1xzk,1996-11-30,1995-11-28
-2xzf,2011-10-05,2010-11-25
-6xz8,2020-06-24,2020-02-03
-1xz2,2004-11-30,2004-11-11
-8xzf,2024-03-20,2024-01-21
-5xzj,2017-12-20,2017-07-12
-6xz9,2020-06-24,2020-02-03
-5xz2,2018-07-18,2017-07-11
-7xz1,2023-07-12,2022-06-02
-1xzn,2005-03-01,2004-11-12
-8xzh,2024-03-20,2024-01-21
-5xza,2019-03-13,2017-07-12
-2xz6,2010-12-08,2010-11-23
-1xz7,2004-11-30,2004-11-11
-1xz0,2005-03-01,2004-11-11
-1xzl,1996-11-30,1995-11-28
-7xzp,2023-06-07,2022-06-03
-5xzn,2018-07-18,2017-07-13
-1xz3,2005-05-10,2004-11-11
-7xzi,2023-01-11,2022-06-02
-6xzo,2020-09-23,2020-02-05
-7xzo,2023-06-07,2022-06-03
-6xzs,2020-09-23,2020-02-05
-6xzb,2020-11-04,2020-02-03
-6xzi,2021-02-17,2020-02-04
-7xz6,2022-08-24,2022-06-02
-1xz5,2004-12-07,2004-11-11
-2xzj,2011-01-19,2010-11-26
-2xzo,2011-03-30,2010-11-26
-7xz0,2023-07-12,2022-06-02
-2xzs,2011-12-07,2010-11-29
-2xzu,2011-10-05,2010-11-29
-6xzj,2021-02-17,2020-02-04
-7xzu,2022-12-21,2022-06-03
-4xzu,2015-12-09,2015-02-05
-5xze,2017-10-11,2017-07-12
-1xz6,2004-12-07,2004-11-11
-2xzc,2011-09-21,2010-11-24
-6xze,2020-09-23,2020-02-04
-1xz1,2005-05-10,2004-11-11
-5xzr,2017-12-13,2017-07-13
-4xz3,2016-01-27,2015-02-03
-6xzy,2020-09-23,2020-02-05
-1xz4,2004-11-30,2004-11-11
-6xzx,2020-09-23,2020-02-05
-2xzk,2011-01-19,2010-11-26
-1xzc,1996-10-14,1995-11-28
-4xzh,2015-11-18,2015-02-04
-6xzz,2020-12-02,2020-02-05
-6xz2,2021-02-10,2020-01-31
-4xz5,2015-07-29,2015-02-03
-2xzl,2011-03-30,2010-11-26
-7xzw,2022-12-21,2022-06-03
-7xzq,2022-10-26,2022-06-03
-5xzh,2018-07-25,2017-07-12
-4xzi,2015-11-18,2015-02-04
-2xz3,2011-03-02,2010-11-22
-2xzg,2011-08-17,2010-11-25
-4xzm,2015-11-18,2015-02-04
-5xzg,2017-10-11,2017-07-12
-5xz6,2019-02-27,2017-07-11
-2xz7,2011-06-15,2010-11-23
-7xz2,2023-07-12,2022-06-02
-8f6m,2023-05-24,2022-11-16
-5f6r,2015-12-23,2015-12-06
-8f6z,2023-06-07,2022-11-17
-8f60,2023-05-24,2022-11-15
-1f6d,2000-12-13,2000-06-21
-3f6u,2008-11-25,2008-11-06
-4f6u,2013-05-01,2012-05-15
-5f6t,2015-12-16,2015-12-06
-4f65,2012-06-06,2012-05-14
-6f6z,2019-01-30,2017-12-06
-3f6e,2008-12-09,2008-11-05
-7f6v,2022-02-16,2021-06-25
-8f6x,2023-08-02,2022-11-17
-3f64,2009-11-10,2008-11-05
-1f63,2000-07-19,2000-06-20
-8f6c,2022-11-30,2022-11-16
-2f6f,2005-12-06,2005-11-29
-4f6s,2013-05-01,2012-05-15
-2f6j,2006-07-11,2005-11-29
-8f6i,2023-02-08,2022-11-16
-2f6s,2006-01-10,2005-11-29
-7f6p,2021-12-01,2021-06-25
-8f6h,2023-02-08,2022-11-16
-5f6y,2016-04-27,2015-12-07
-5f6z,2016-09-28,2015-12-07
-4f6n,2012-09-05,2012-05-15
-6f66,2018-06-06,2017-12-05
-1f61,2000-08-30,2000-06-19
-3f6g,2009-04-21,2008-11-06
-3f69,2008-12-02,2008-11-05
-6f6s,2018-01-03,2017-12-06
-4f6d,2012-05-30,2012-05-14
-6f6l,2018-12-19,2017-12-05
-5f60,2017-02-08,2015-12-04
-4f6z,2013-03-27,2012-05-15
-3f61,2008-12-02,2008-11-05
-3f6r,2009-06-09,2008-11-06
-6f6b,2018-12-19,2017-12-05
-7f6t,2021-12-01,2021-06-25
-3f6v,2008-11-25,2008-11-06
-3f68,2009-10-20,2008-11-05
-4f6x,2012-06-20,2012-05-15
-4f60,2013-01-23,2012-05-14
-6f6j,2018-11-14,2017-12-05
-8f65,2023-12-13,2022-11-16
-2f69,2006-01-17,2005-11-28
-4f66,2012-06-13,2012-05-14
-2f64,2005-12-06,2005-11-28
-2f6k,2006-01-10,2005-11-29
-7f6z,2022-06-29,2021-06-26
-7f6m,2022-06-29,2021-06-25
-3f6k,2008-12-30,2008-11-06
-6f6u,2018-05-16,2017-12-06
-7f6o,2021-12-01,2021-06-25
-4f6w,2013-05-01,2012-05-15
-6f6m,2018-12-19,2017-12-05
-6f6q,2018-08-15,2017-12-06
-7f6n,2021-12-01,2021-06-25
-7f6y,2022-06-29,2021-06-26
-4f6t,2012-07-18,2012-05-15
-4f6b,2012-05-30,2012-05-14
-6f6a,2018-06-06,2017-12-05
-4f68,2012-05-30,2012-05-14
-8f6p,2023-04-12,2022-11-16
-4f6r,2012-07-18,2012-05-15
-6f69,2018-06-06,2017-12-05
-6f6e,2018-07-04,2017-12-05
-6f6r,2018-05-02,2017-12-06
-5f6c,2016-12-14,2015-12-05
-3f6j,2009-11-17,2008-11-06
-8f6e,2023-02-08,2022-11-16
-1f6t,2000-09-13,2000-06-23
-3f63,2009-10-27,2008-11-05
-2f6r,2005-12-27,2005-11-29
-5f6d,2016-04-27,2015-12-05
-6f6d,2018-10-17,2017-12-05
-2f6d,2006-05-23,2005-11-29
-4f63,2012-06-06,2012-05-14
-6f6c,2018-07-04,2017-12-05
-7f6q,2021-12-01,2021-06-25
-2f6z,2005-12-13,2005-11-29
-7f6e,2021-12-01,2021-06-25
-5f63,2017-02-08,2015-12-04
-5f6l,2016-02-24,2015-12-06
-1f66,2000-11-27,2000-06-20
-6f65,2018-12-19,2017-12-05
-1f6n,2001-04-18,2000-06-22
-2f67,2005-12-06,2005-11-28
-4f6v,2012-06-13,2012-05-15
-6f6h,2018-07-04,2017-12-05
-4f6h,2013-03-27,2012-05-14
-8f6j,2023-02-08,2022-11-16
-7f6x,2022-03-16,2021-06-26
-6f60,2018-04-25,2017-12-04
-1f6m,2000-08-30,2000-06-22
-4f6g,2012-05-30,2012-05-14
-1f6a,2000-07-20,2000-06-20
-5f62,2017-02-08,2015-12-04
-1f62,2000-12-27,2000-06-19
-4f6j,2012-05-30,2012-05-14
-8f61,2023-02-01,2022-11-15
-1f6u,2000-10-09,2000-06-23
-8f6n,2023-02-01,2022-11-16
-2f6y,2005-12-13,2005-11-29
-3f6b,2008-12-09,2008-11-05
-3f66,2008-12-23,2008-11-05
-8f6k,2023-02-08,2022-11-16
-8f6t,2023-04-05,2022-11-17
-1f6b,2002-01-09,2000-06-21
-4f6m,2012-09-05,2012-05-15
-3f6s,2009-06-09,2008-11-06
-8f6f,2023-02-08,2022-11-16
-4f6i,2012-05-30,2012-05-14
-7f6g,2023-03-29,2021-06-25
-6f68,2018-06-06,2017-12-05
-5f6k,2016-02-24,2015-12-06
-6f6f,2018-07-04,2017-12-05
-5f6v,2016-04-27,2015-12-07
-4f6p,2013-03-27,2012-05-15
-5f6u,2016-04-27,2015-12-07
-4f6o,2012-07-11,2012-05-15
-6f6y,2018-12-19,2017-12-06
-7f6i,2022-01-05,2021-06-25
-6f67,2018-06-06,2017-12-05
-7f61,2022-10-26,2021-06-23
-4f69,2012-05-30,2012-05-14
-8f6y,2023-06-07,2022-11-17
-7f6f,2021-12-01,2021-06-25
-5f6w,2016-04-27,2015-12-07
-7f60,2022-09-14,2021-06-23
-8f68,2022-11-30,2022-11-16
-7f6h,2022-01-05,2021-06-25
-5f6m,2016-01-06,2015-12-06
-7f6w,2022-02-16,2021-06-26
-2f6w,2005-12-13,2005-11-29
-5f61,2017-02-08,2015-12-04
-6f6t,2019-06-26,2017-12-06
-7f6u,2021-12-01,2021-06-25
-2f6t,2005-12-13,2005-11-29
-2f62,2005-12-06,2005-11-28
-3f6q,2008-12-02,2008-11-06
-2f6x,2006-01-24,2005-11-29
-5f6q,2015-12-23,2015-12-06
-4f6e,2013-06-12,2012-05-14
-7f68,2022-06-29,2021-06-24
-6f6k,2018-07-04,2017-12-05
-4f64,2012-06-06,2012-05-14
-1f6h,2000-07-21,2000-06-21
-6f6g,2018-07-04,2017-12-05
-6f6i,2018-01-03,2017-12-05
-3f6d,2009-10-27,2008-11-05
-5f6x,2016-04-27,2015-12-07
-7f6s,2021-12-01,2021-06-25
-3f6h,2009-04-21,2008-11-06
-6f6w,2018-12-19,2017-12-06
-2f6v,2005-12-13,2005-11-29
-2f6m,2006-04-18,2005-11-29
-1f6s,2000-12-13,2000-06-23
-2f6n,2006-07-11,2005-11-29
-4f61,2012-07-18,2012-05-14
-6f6n,2018-01-03,2017-12-05
-5f6b,2016-12-07,2015-12-05
-1f6o,2000-12-11,2000-06-22
-3f6x,2008-12-09,2008-11-06
-4f6f,2012-05-30,2012-05-14
-2f61,2005-12-27,2005-11-28
-3f6y,2008-11-18,2008-11-07
-2f6p,2006-10-31,2005-11-29
-8f6g,2024-05-22,2022-11-16
-2f6c,2006-06-13,2005-11-29
-7f6j,2022-02-23,2021-06-25
-1f65,2000-07-19,2000-06-20
-6rdw,2019-07-03,2019-04-12
-6rdd,2019-07-03,2019-04-12
-3rda,2012-03-21,2011-04-01
-6rdo,2019-07-03,2019-04-12
-4rdc,2014-10-01,2014-09-18
-4rdh,2015-08-05,2014-09-19
-1rdd,1993-10-31,1993-06-23
-2rd5,2007-10-02,2007-09-21
-1rd4,2004-03-30,2003-11-05
-7rdk,2021-11-10,2021-07-09
-7rdw,2022-05-25,2021-07-12
-2rd9,2007-10-09,2007-09-21
-5rdj,2020-06-03,2020-03-24
-3rdz,2011-07-06,2011-04-02
-2rdg,2007-12-18,2007-09-24
-6rdj,2019-07-03,2019-04-12
-6rd1,2019-09-25,2019-04-12
-4rd3,2015-05-27,2014-09-18
-5rd8,2020-06-03,2020-03-24
-4rdv,2014-10-08,2014-09-19
-6rdz,2019-07-03,2019-04-12
-2rds,2007-10-16,2007-09-24
-6rd8,2019-07-03,2019-04-12
-3rde,2012-04-18,2011-04-01
-4rdl,2015-01-14,2014-09-19
-4rdz,2015-02-25,2014-09-20
-7rdz,2021-11-24,2021-07-12
-6rdx,2019-07-03,2019-04-12
-7rd0,2022-03-23,2021-07-08
-2rdw,2008-02-26,2007-09-25
-3rdk,2012-04-04,2011-04-01
-5rd0,2020-06-03,2020-03-24
-5rdd,2020-06-03,2020-03-24
-1rdm,1996-03-08,1995-09-05
-8rdv,2024-02-21,2023-12-08
-7rd2,2023-02-22,2021-07-09
-3rdh,2011-09-28,2011-04-01
-7rd1,2021-12-15,2021-07-08
-4rd6,2015-07-29,2014-09-18
-7rdn,2022-07-27,2021-07-09
-7rdm,2021-11-10,2021-07-09
-6rdm,2019-07-03,2019-04-12
-6rd7,2019-07-03,2019-04-12
-5rd1,2020-06-03,2020-03-24
-4rd2,2015-05-27,2014-09-18
-1rdi,1996-03-08,1995-09-05
-2rdq,2007-10-16,2007-09-24
-7rdq,2022-02-02,2021-07-10
-6rdu,2019-07-03,2019-04-12
-1rdr,1998-09-16,1998-04-28
-7rdo,2022-07-13,2021-07-10
-1rdx,1997-01-11,1996-05-17
-6rdv,2019-07-03,2019-04-12
-4rdn,2014-12-24,2014-09-19
-3rdv,2011-06-29,2011-04-01
-5rdf,2020-06-03,2020-03-24
-6rdn,2019-07-03,2019-04-12
-3rdo,2011-07-06,2011-04-01
-8rdq,2024-04-10,2023-12-08
-6rd0,2020-02-19,2019-04-12
-5rdl,2020-06-03,2020-03-24
-4rdi,2015-08-05,2014-09-19
-1rdl,1996-03-08,1995-09-05
-1rdj,1996-03-08,1995-09-05
-4rd1,2015-05-27,2014-09-18
-1rd7,1996-12-23,1996-11-01
-3rdi,2012-05-02,2011-04-01
-8rdj,2024-03-13,2023-12-08
-6rd4,2019-07-03,2019-04-12
-6rdp,2019-07-03,2019-04-12
-7rdu,2022-07-13,2021-07-11
-1rdz,1997-01-11,1996-05-17
-6rde,2019-07-03,2019-04-12
-6rdb,2019-07-03,2019-04-12
-1rd9,2004-10-26,2003-11-05
-4rdx,2015-03-25,2014-09-20
-7rd8,2021-09-29,2021-07-09
-8rdw,2024-02-21,2023-12-08
-7rd7,2021-09-29,2021-07-09
-2rdd,2007-12-11,2007-09-22
-6rdc,2019-07-03,2019-04-12
-2rd6,2008-09-23,2007-09-21
-1rdv,1999-05-18,1998-09-30
-2rd4,2007-10-09,2007-09-21
-7rde,2022-05-04,2021-07-09
-3rdp,2011-08-03,2011-04-01
-1rdk,1996-03-08,1995-09-05
-2rdr,2007-10-16,2007-09-24
-6rdq,2019-07-03,2019-04-12
-8rdk,2024-03-06,2023-12-08
-5rd5,2020-06-03,2020-03-24
-7rd6,2021-09-29,2021-07-09
-1rd8,2004-03-23,2003-11-05
-5rdn,2020-06-03,2020-03-24
-1rdw,2003-12-16,2003-11-06
-3rd9,2012-03-21,2011-04-01
-2rdp,2007-11-13,2007-09-24
-6rd3,2019-09-11,2019-04-12
-1rd3,2004-05-04,2003-11-05
-3rdd,2012-03-21,2011-04-01
-5rdb,2020-06-03,2020-03-24
-4rd0,2015-05-27,2014-09-18
-7rdx,2021-11-24,2021-07-12
-6rdg,2019-07-03,2019-04-12
-6rdf,2019-07-03,2019-04-12
-6rdi,2019-07-03,2019-04-12
-1rdn,1996-03-08,1995-09-05
-1rdq,2004-04-13,2003-11-05
-3rdb,2012-03-21,2011-04-01
-4rdt,2015-08-19,2014-09-19
-6rd9,2019-07-03,2019-04-12
-1rdp,2004-10-26,2003-11-05
-4rd4,2015-05-27,2014-09-18
-2rdz,2008-03-25,2007-09-25
-4rdk,2015-01-14,2014-09-19
-4rdw,2014-10-08,2014-09-19
-3rdr,2011-08-10,2011-04-01
-4rdd,2015-07-01,2014-09-18
-1rdy,1997-01-11,1996-05-17
-6rdy,2019-07-03,2019-04-12
-1rdg,1989-04-19,1988-03-17
-5rd3,2020-06-03,2020-03-24
-2rdn,2007-10-16,2007-09-24
-3rdq,2011-07-06,2011-04-01
-6rds,2019-07-03,2019-04-12
-5rdk,2020-06-03,2020-03-24
-6rd5,2019-07-03,2019-04-12
-2rd2,2008-01-15,2007-09-20
-1rds,1993-10-31,1993-05-14
-1rdt,2004-11-09,2003-11-06
-5rdc,2020-06-03,2020-03-24
-6rdl,2019-07-03,2019-04-12
-6rdh,2019-07-03,2019-04-12
-2rdv,1999-05-18,1998-10-07
-1rdf,2004-08-31,2003-11-05
-2rde,2007-10-30,2007-09-22
-2rdu,2008-02-26,2007-09-25
-2rdt,2008-02-26,2007-09-25
-3rdm,2011-07-06,2011-04-01
-7rdp,2022-07-13,2021-07-10
-4rds,2015-01-14,2014-09-19
-5rd6,2020-06-03,2020-03-24
-2rdl,2007-10-30,2007-09-24
-7rdf,2021-12-22,2021-07-09
-4rdr,2015-08-19,2014-09-19
-3rdc,2012-03-21,2011-04-01
-7rdv,2022-07-27,2021-07-11
-3rd0,2011-05-11,2011-03-31
-2rdj,2008-06-24,2007-09-24
-2rdx,2007-10-09,2007-09-25
-2rdb,2007-12-18,2007-09-21
-7rdy,2021-12-01,2021-07-12
-6rda,2019-07-03,2019-04-12
-6rd2,2020-05-13,2019-04-12
-2rdk,2008-05-06,2007-09-24
-7rdg,2023-01-25,2021-07-09
-1rdo,1996-03-08,1995-09-05
-2rdh,2007-12-18,2007-09-24
-4rdq,2014-10-22,2014-09-19
-7rdh,2022-05-04,2021-07-09
-6rdk,2019-07-03,2019-04-12
-4rdy,2015-02-25,2014-09-20
-6rdr,2019-07-03,2019-04-12
-6rdt,2019-07-03,2019-04-12
-6fcb,2019-01-30,2017-12-20
-6fcd,2019-01-30,2017-12-20
-8fcm,2023-06-21,2022-12-01
-5fc2,2016-03-30,2015-12-14
-8fcq,2023-06-21,2022-12-01
-1fcp,1999-01-13,1998-10-14
-2fcp,1999-01-13,1998-10-15
-2fcv,2006-03-21,2005-12-12
-3fca,2009-02-17,2008-11-21
-5fc1,2016-01-27,2015-12-14
-3fc5,2009-11-03,2008-11-21
-7fcw,2022-04-06,2021-07-15
-8fc2,2023-07-12,2022-12-01
-3fce,2009-04-14,2008-11-21
-1fcj,2000-10-18,2000-07-18
-7fcz,2022-01-19,2021-07-15
-7fcx,2022-07-20,2021-07-15
-3fcw,2009-08-11,2008-11-23
-7fcg,2022-07-20,2021-07-14
-2fc0,2006-04-25,2005-12-10
-7fc5,2022-06-22,2021-07-13
-8fcr,2023-06-21,2022-12-01
-5fc6,2016-01-27,2015-12-15
-3fcj,2009-11-03,2008-11-21
-6fci,2018-08-15,2017-12-20
-4fcw,2012-07-18,2012-05-25
-8fc3,2023-07-12,2022-12-01
-3fc8,2009-02-17,2008-11-21
-8fcl,2023-06-21,2022-12-01
-7fcv,2022-11-09,2021-07-15
-7fc0,2022-03-16,2021-07-13
-4fcn,2012-10-24,2012-05-25
-8fc1,2023-07-12,2022-12-01
-3fcz,2008-12-09,2008-11-24
-1fck,2001-01-17,2000-07-18
-3fcs,2009-01-20,2008-11-22
-8fcu,2023-08-09,2022-12-01
-6fcg,2018-12-26,2017-12-20
-8fc8,2023-07-12,2022-12-01
-8fc7,2023-07-12,2022-12-01
-8fc5,2023-07-26,2022-12-01
-3fcx,2008-12-09,2008-11-24
-5fcf,2016-12-07,2015-12-15
-7fc6,2022-07-13,2021-07-13
-8fcx,2023-08-09,2022-12-01
-2fco,2006-11-21,2005-12-12
-5fcx,2016-07-27,2015-12-15
-4fc8,2012-07-25,2012-05-24
-8fc4,2023-07-26,2022-12-01
-4fc7,2012-07-04,2012-05-24
-3fcy,2009-11-17,2008-11-24
-1fcv,2001-10-01,2000-07-19
-3fc2,2009-05-12,2008-11-21
-4fcq,2012-10-24,2012-05-25
-4fce,2012-07-11,2012-05-24
-5fci,2016-05-11,2015-12-15
-3fco,2009-12-01,2008-11-21
-3fc3,2009-03-31,2008-11-21
-3fcm,2008-12-09,2008-11-21
-6fcs,2018-04-18,2017-12-21
-5fc7,2016-01-27,2015-12-15
-7fcb,2022-04-20,2021-07-14
-2fcw,2006-05-16,2005-12-12
-6fcr,2018-04-18,2017-12-21
-4fcm,2013-06-05,2012-05-25
-4fci,2012-06-20,2012-05-25
-4fcb,2012-09-05,2012-05-24
-5fck,2016-10-26,2015-12-15
-8fcz,2023-08-30,2022-12-01
-6fc8,2018-01-17,2017-12-20
-3fct,1999-06-23,1999-06-13
-5fc4,2016-03-02,2015-12-14
-2fc1,2006-04-04,2005-12-10
-8fcy,2023-06-21,2022-12-01
-6fca,2018-10-24,2017-12-20
-1fc2,1981-10-02,1981-05-21
-4fch,2012-08-29,2012-05-24
-1fcd,1994-11-01,1994-08-18
-8fc9,2023-07-12,2022-12-01
-4fcp,2012-10-24,2012-05-25
-7fc9,2022-02-02,2021-07-14
-7fcr,2022-07-20,2021-07-15
-7fcu,2022-04-13,2021-07-15
-6fc1,2018-06-27,2017-12-20
-1fcx,2000-09-11,2000-07-19
-1fce,1999-07-22,1998-07-06
-2fcq,2006-01-31,2005-12-12
-8fcd,2023-02-01,2022-12-01
-3fck,2009-04-28,2008-11-21
-1fc5,2001-07-25,2000-07-17
-1fc0,2000-08-25,2000-07-17
-2fcu,2006-03-21,2005-12-12
-4fc3,2013-05-29,2012-05-24
-4fck,2012-06-20,2012-05-25
-6fc7,2019-01-30,2017-12-20
-5fcc,2017-01-25,2015-12-15
-7fc3,2021-09-22,2021-07-13
-3fc9,2009-08-25,2008-11-21
-7fc4,2022-07-13,2021-07-13
-7fcm,2022-07-20,2021-07-15
-4fcd,2012-09-05,2012-05-24
-8fci,2023-12-13,2022-12-01
-4fca,2012-06-06,2012-05-24
-7fce,2022-01-26,2021-07-14
-7fcp,2022-06-15,2021-07-15
-6fcp,2018-03-14,2017-12-20
-6fch,2018-08-15,2017-12-20
-1fcm,2000-12-04,2000-07-18
-6fct,2018-10-24,2017-12-21
-3fcb,2009-02-17,2008-11-21
-6fcu,2018-04-18,2017-12-21
-5fcu,2016-03-16,2015-12-15
-8fcw,2023-08-09,2022-12-01
-2fcm,2006-01-31,2005-12-12
-7fcs,2022-07-20,2021-07-15
-4fc6,2012-07-04,2012-05-24
-6fcy,2018-10-24,2017-12-21
-1fcs,1993-10-31,1993-04-20
-5fcz,2016-10-26,2015-12-15
-2fct,2006-03-21,2005-12-12
-8fcp,2023-06-21,2022-12-01
-3fcc,2009-04-14,2008-11-21
-8fcn,2023-06-21,2022-12-01
-7fco,2022-03-16,2021-07-15
-3fcp,2008-12-02,2008-11-22
-2fc6,2006-06-12,2005-12-12
-7fcq,2022-06-15,2021-07-15
-4fco,2013-05-29,2012-05-25
-4fcr,2012-10-24,2012-05-25
-8fc6,2023-07-26,2022-12-01
-3fc6,2009-02-10,2008-11-21
-4fc0,2014-01-08,2012-05-23
-6fcw,2018-10-24,2017-12-21
-4fcf,2012-12-26,2012-05-24
-6fc3,2018-06-27,2017-12-20
-2fca,2006-08-15,2005-12-12
-2fcn,2006-01-31,2005-12-12
-5fca,2016-01-27,2015-12-15
-5fct,2016-10-26,2015-12-15
-3fc1,2008-12-09,2008-11-20
-1fch,2000-12-06,2000-07-18
-3fcq,2009-12-08,2008-11-22
-1fco,2000-12-04,2000-07-19
-3fcr,2009-01-13,2008-11-22
-1fc4,2001-05-02,2000-07-17
-8fco,2023-06-21,2022-12-01
-8fce,2023-02-01,2022-12-01
-4fcx,2012-06-20,2012-05-25
-2fc2,2006-08-22,2005-12-10
-5fcj,2016-05-11,2015-12-15
-5fc9,2016-05-11,2015-12-15
-1fcz,2000-09-11,2000-07-19
-4fcs,2012-10-24,2012-05-25
-6fcl,2018-08-15,2017-12-20
-3fc4,2009-10-06,2008-11-21
-5fc3,2016-03-30,2015-12-14
-5fch,2016-12-07,2015-12-15
-6fcx,2018-05-16,2017-12-21
-8fcc,2023-02-01,2022-12-01
-3fci,2009-04-28,2008-11-21
-4fc5,2012-09-12,2012-05-24
-6fc6,2018-04-11,2017-12-20
-8fcb,2023-07-12,2022-12-01
-5fcb,2016-01-27,2015-12-15
-3fcl,2009-04-28,2008-11-21
-1fcn,2000-12-04,2000-07-18
-5fcy,2016-07-27,2015-12-15
-2fcr,1992-03-04,1992-02-03
-8fcv,2023-08-09,2022-12-01
-5fc5,2016-01-27,2015-12-14
-3fcv,2009-08-11,2008-11-23
-2fc7,2006-06-12,2005-12-12
-7fcn,2022-07-20,2021-07-15
-5fcw,2016-10-26,2015-12-15
-7fcy,2022-07-20,2021-07-15
-1fcb,1991-01-15,1990-01-16
-7fct,2023-01-25,2021-07-15
-6fcj,2019-01-30,2017-12-20
-1fcy,2000-09-11,2000-07-19
-8fca,2023-07-12,2022-12-01
-1fc1,1981-10-02,1981-05-21
-3fcf,2009-04-28,2008-11-21
-6fcf,2018-01-17,2017-12-20
-7fcd,2022-01-26,2021-07-14
-7fc8,2022-07-20,2021-07-14
-6fcq,2018-04-18,2017-12-21
-3fcu,2009-01-20,2008-11-22
-7fc7,2023-01-18,2021-07-14
-4fcv,2012-07-18,2012-05-25
-8fct,2023-06-21,2022-12-01
-6fck,2018-01-17,2017-12-20
-2fcs,2006-01-31,2005-12-12
-6fc2,2018-06-27,2017-12-20
-8beg,2022-11-30,2022-10-21
-4be3,2013-06-26,2013-03-05
-3ber,2007-12-04,2007-11-20
-7bej,2021-03-03,2020-12-23
-8bem,2022-11-09,2022-10-21
-8beq,2022-12-28,2022-10-21
-7ben,2021-03-03,2020-12-24
-8beh,2023-01-11,2022-10-21
-6be1,2018-02-07,2017-10-24
-8be6,2023-04-26,2022-10-21
-3beo,2008-02-19,2007-11-19
-8bej,2023-11-01,2022-10-21
-7be5,2021-03-03,2020-12-22
-1be6,1998-10-14,1998-05-20
-1bem,1998-10-21,1998-05-16
-8beo,2023-11-08,2022-10-21
-3beq,2008-09-30,2007-11-19
-3be4,2007-12-18,2007-11-16
-3ben,2008-09-30,2007-11-19
-2be9,2006-10-31,2005-10-23
-3beu,2008-03-11,2007-11-20
-1bej,1998-10-21,1998-05-16
-1beq,1998-10-21,1998-05-16
-3bes,2008-02-12,2007-11-20
-2be2,2005-12-06,2005-10-21
-6be0,2018-08-01,2017-10-24
-4bem,2014-03-26,2013-03-11
-6bek,2018-10-31,2017-10-25
-3bep,2008-01-29,2007-11-19
-7bel,2021-03-03,2020-12-23
-4beq,2014-01-15,2013-03-12
-4beb,2014-03-26,2013-03-07
-8beb,2023-02-15,2022-10-21
-2be5,2005-11-08,2005-10-22
-3bej,2008-03-18,2007-11-19
-6bej,2018-10-31,2017-10-25
-2beu,2006-02-16,2004-11-30
-7beb,2021-02-24,2020-12-23
-3bel,2008-07-01,2007-11-19
-1bek,1998-10-21,1998-05-16
-7bet,2022-01-12,2020-12-24
-2bec,2006-06-27,2005-10-24
-4bet,2013-04-24,2013-03-12
-2bes,2004-12-03,2004-11-30
-8bev,2023-03-08,2022-10-21
-3be9,2008-11-18,2007-11-16
-1bes,1998-10-21,1998-05-16
-7bed,2021-12-08,2020-12-23
-6bed,2018-07-18,2017-10-25
-7be2,2021-02-24,2020-12-22
-8bek,2022-12-28,2022-10-21
-8be7,2023-04-26,2022-10-21
-8bep,2023-01-11,2022-10-21
-8bet,2022-12-28,2022-10-21
-2bet,2004-12-03,2004-11-30
-7be1,2021-02-24,2020-12-22
-4bez,2013-04-24,2013-03-12
-6bea,2019-04-10,2017-10-25
-4bey,2013-05-08,2013-03-12
-6beh,2018-07-18,2017-10-25
-2be6,2005-11-15,2005-10-23
-2bej,2005-01-12,2004-11-25
-2bex,2005-03-17,2004-12-01
-8bef,2023-01-11,2022-10-21
-3beh,2008-01-15,2007-11-18
-4be2,2012-10-31,2012-10-08
-1be3,1999-01-13,1998-05-19
-7be7,2021-03-03,2020-12-22
-2bev,2006-02-16,2004-11-30
-7bea,2021-06-09,2020-12-22
-1be8,1998-10-28,1998-05-20
-8be0,2022-12-28,2022-10-20
-2ber,2005-04-04,2004-11-30
-1bep,1998-10-21,1998-05-16
-4be7,2014-03-26,2013-03-06
-4bep,2013-04-24,2013-03-12
-3bet,2008-10-07,2007-11-20
-8bee,2023-01-11,2022-10-21
-1be9,1998-10-21,1998-05-20
-2beo,2005-04-14,2004-11-26
-1beu,1998-08-12,1998-05-18
-7be3,2021-04-21,2020-12-22
-3beb,2008-08-26,2007-11-16
-2be1,2005-12-13,2005-10-21
-3bea,2008-07-15,2007-11-16
-7beo,2021-03-03,2020-12-24
-7bes,2022-01-12,2020-12-24
-8bew,2023-02-15,2022-10-22
-7beu,2022-01-12,2020-12-28
-4bec,2014-03-26,2013-03-07
-7bem,2021-03-03,2020-12-24
-3beg,2008-04-01,2007-11-18
-3bef,2008-01-01,2007-11-17
-7be8,2022-01-12,2020-12-22
-7be6,2021-03-03,2020-12-22
-4bew,2014-02-19,2013-03-12
-1be7,1998-09-23,1998-05-20
-7be4,2021-03-03,2020-12-22
-7bek,2021-03-03,2020-12-23
-2bel,2004-12-06,2004-11-25
-8bel,2023-01-11,2022-10-21
-7bez,2021-07-14,2021-01-06
-2bew,2006-02-16,2004-11-30
-2beh,2005-11-01,2005-10-24
-8beu,2022-12-28,2022-10-21
-6be6,2017-12-27,2017-10-24
-4be9,2014-03-26,2013-03-06
-1ben,1996-07-11,1996-02-15
-4beu,2014-01-15,2013-03-12
-8be3,2023-11-01,2022-10-21
-6be3,2018-02-21,2017-10-24
-6bem,2018-10-31,2017-10-25
-4be4,2014-03-19,2013-03-05
-2bei,2005-11-01,2005-10-24
-8be8,2023-04-26,2022-10-21
-4ber,2013-04-24,2013-03-12
-7bex,2022-01-12,2020-12-29
-7beh,2021-03-03,2020-12-23
-4be6,2013-12-18,2013-03-06
-7be0,2021-02-24,2020-12-22
-4ben,2013-03-20,2013-03-11
-8bed,2023-01-11,2022-10-21
-1bex,1998-10-14,1998-05-18
-7bec,2021-02-24,2020-12-23
-2bem,2004-12-08,2004-11-26
-4be5,2013-12-18,2013-03-06
-4bek,2013-06-19,2013-03-11
-3be1,2008-11-18,2007-11-15
-8bec,2023-11-01,2022-10-21
-6bee,2018-07-18,2017-10-25
-3be2,2008-04-08,2007-11-16
-3bei,2007-12-25,2007-11-19
-3bem,2007-12-04,2007-11-19
-7bew,2022-01-12,2020-12-29
-2bek,2005-01-12,2004-11-25
-3be7,2007-11-27,2007-11-16
-6beb,2018-07-18,2017-10-25
-2be7,2006-10-31,2005-10-23
-4be1,2012-10-31,2012-10-08
-4bea,2013-12-11,2013-03-07
-7bep,2021-03-03,2020-12-24
-3be0,2008-02-12,2007-11-15
-4bes,2013-04-24,2013-03-12
-8bes,2022-12-28,2022-10-21
-7bei,2021-03-03,2020-12-23
-6bef,2018-07-18,2017-10-25
-4bev,2014-04-02,2013-03-12
-3bec,2008-08-26,2007-11-16
-3bex,2008-06-24,2007-11-20
-3be8,2008-01-29,2007-11-16
-6bec,2018-07-18,2017-10-25
-2bed,2006-08-08,2005-10-24
-2bef,1998-08-12,1998-05-26
-6be4,2018-02-21,2017-10-24
-6bel,2018-10-31,2017-10-25
-4be0,2012-10-31,2012-10-08
-1be4,1999-01-13,1998-05-19
-3be6,2008-10-28,2007-11-16
-8jfl,2024-04-03,2023-05-18
-4jfq,2013-05-29,2013-02-28
-5jf7,2016-11-30,2016-04-19
-1jfs,2002-02-08,2001-06-21
-5jf0,2016-11-30,2016-04-19
-5jf6,2016-11-30,2016-04-19
-1jf8,2001-10-03,2001-06-20
-1jfh,1998-12-02,1997-09-19
-7jfn,2020-07-29,2020-07-17
-4jfl,2013-08-28,2013-02-28
-4jfa,2014-01-29,2013-02-28
-4jfs,2013-09-18,2013-02-28
-2jfy,2008-02-19,2007-02-06
-5jf3,2016-11-30,2016-04-19
-4jfj,2013-08-28,2013-02-28
-2jfa,2007-02-20,2007-01-29
-5jf2,2016-11-30,2016-04-19
-2jf4,2007-02-13,2007-01-25
-8jfv,2024-04-24,2023-05-19
-5jf1,2016-11-30,2016-04-19
-4jfx,2013-09-25,2013-02-28
-1jfz,2001-12-19,2001-06-22
-5jfe,2017-04-26,2016-04-19
-8jfh,2023-11-15,2023-05-18
-8jfm,2023-11-15,2023-05-18
-7jfr,2020-09-16,2020-07-17
-8jf1,2024-05-22,2023-05-16
-2jfo,2007-07-03,2007-02-03
-1jfk,2001-12-19,2001-06-21
-1jfc,2001-12-20,2001-06-20
-2jff,2007-05-15,2007-02-01
-6jfk,2019-11-13,2019-02-10
-4jfm,2013-08-28,2013-02-28
-5jfp,2016-09-21,2016-04-19
-6jf3,2020-02-12,2019-02-08
-1jf9,2001-07-04,2001-06-20
-8jf4,2024-02-14,2023-05-17
-2jfz,2007-07-03,2007-02-06
-6jff,2020-02-12,2019-02-08
-6jfm,2019-11-13,2019-02-10
-4jfk,2013-08-28,2013-02-28
-2jfn,2007-07-03,2007-02-03
-5jfg,2016-10-26,2016-04-19
-5jft,2016-10-26,2016-04-19
-5jfy,2017-04-26,2016-04-19
-1jf5,2002-05-22,2001-06-20
-4jfu,2013-09-18,2013-02-28
-1jfg,2001-11-30,2001-06-20
-2jfl,2007-02-27,2007-02-02
-1jf3,2002-06-20,2001-06-20
-8jfs,2023-06-14,2023-05-18
-4jfp,2013-05-29,2013-02-28
-4jf7,2013-09-04,2013-02-27
-6jfd,2020-02-12,2019-02-08
-5jfw,2017-03-01,2016-04-19
-5jfr,2016-05-25,2016-04-19
-1jfp,2001-10-05,2001-06-21
-1jf1,2001-09-14,2001-06-19
-5jfx,2017-03-01,2016-04-19
-5jfv,2017-03-01,2016-04-19
-6jfs,2020-02-12,2019-02-11
-2jfh,2007-05-15,2007-02-01
-4jfw,2013-09-18,2013-02-28
-5jfi,2017-03-29,2016-04-19
-5jfo,2016-08-10,2016-04-19
-6jf7,2020-02-12,2019-02-08
-6jfr,2020-02-12,2019-02-11
-4jfo,2013-05-29,2013-02-28
-4jf4,2013-09-25,2013-02-27
-4jfz,2013-08-28,2013-02-28
-4jfr,2013-03-13,2013-02-28
-8jf3,2024-02-14,2023-05-17
-6jfx,2019-02-20,2019-02-12
-6jf0,2020-02-12,2019-02-07
-6jfb,2020-04-01,2019-02-08
-4jfg,2013-10-02,2013-02-28
-1jf7,2002-02-13,2001-06-20
-2jfq,2007-07-03,2007-02-04
-6jf4,2020-02-12,2019-02-08
-6jfq,2020-02-12,2019-02-11
-8jfb,2023-08-23,2023-05-17
-4jfi,2013-08-28,2013-02-28
-4jfe,2013-05-29,2013-02-28
-2jfs,2007-07-24,2007-02-04
-2jfc,2007-05-29,2007-01-31
-7jfp,2021-03-10,2020-07-17
-5jfm,2017-03-01,2016-04-19
-2jf3,2007-04-24,2007-01-25
-5jfk,2017-03-29,2016-04-19
-7jfy,2021-07-21,2020-07-17
-2jf9,2007-02-20,2007-01-29
-8jfg,2023-11-15,2023-05-18
-1jf0,2001-07-11,2001-06-19
-5jf5,2016-11-30,2016-04-19
-8jfz,2023-08-09,2023-05-19
-8jfc,2023-08-23,2023-05-17
-5jfs,2017-03-01,2016-04-19
-7jfs,2021-02-03,2020-07-17
-7jfz,2020-10-28,2020-07-17
-2jf6,2008-02-05,2007-01-26
-1jf6,2002-05-22,2001-06-20
-4jfv,2013-09-18,2013-02-28
-2jfk,2007-03-13,2007-02-02
-8jf5,2024-05-22,2023-05-17
-2jfg,2007-05-15,2007-02-01
-6jf5,2020-02-12,2019-02-08
-5jf4,2016-11-30,2016-04-19
-5jf8,2016-11-30,2016-04-19
-2jfx,2007-07-03,2007-02-06
-6jf8,2020-02-12,2019-02-08
-1jf4,2002-06-20,2001-06-20
-2jfe,2007-06-19,2007-01-31
-8jfn,2023-11-15,2023-05-18
-5jfd,2017-05-24,2016-04-19
-6jf9,2020-02-12,2019-02-08
-4jfn,2014-07-23,2013-02-28
-4jf6,2013-09-25,2013-02-27
-5jfu,2016-09-21,2016-04-19
-2jft,2007-07-24,2007-02-04
-2jf5,2008-02-05,2007-01-26
-4jf0,2014-03-26,2013-02-27
-6jf6,2020-02-12,2019-02-08
-2jf0,2007-07-03,2007-01-25
-6jfn,2020-03-04,2019-02-11
-1jff,2001-09-19,2001-06-20
-8jfk,2024-04-03,2023-05-18
-2jfr,2007-07-24,2007-02-04
-6jf1,2019-07-10,2019-02-07
-6jfc,2020-02-12,2019-02-08
-6jfe,2020-02-12,2019-02-08
-8jfi,2023-11-15,2023-05-18
-8jfd,2023-08-23,2023-05-17
-1jfv,2001-10-03,2001-06-22
-1jfb,2001-12-20,2001-06-20
-5jfn,2017-03-01,2016-04-19
-5jfl,2017-03-01,2016-04-19
-6jfl,2019-11-13,2019-02-10
-4jft,2013-09-18,2013-02-28
-8jfa,2023-11-15,2023-05-17
-4jfd,2013-05-29,2013-02-28
-5jfc,2017-04-12,2016-04-19
-1jf2,2001-07-11,2001-06-19
-6jfg,2020-02-12,2019-02-08
-6jfj,2019-02-20,2019-02-09
-2jfp,2007-07-03,2007-02-03
-1jft,2002-02-08,2001-06-21
-6jfo,2020-02-12,2019-02-11
-4jf1,2014-03-26,2013-02-27
-6jfa,2020-02-12,2019-02-08
-6jfp,2020-02-12,2019-02-11
-4pie,2014-09-10,2014-05-08
-4pi3,2014-11-12,2014-05-08
-1piy,2004-01-13,2003-05-30
-7pin,2022-08-17,2021-08-22
-4pix,2016-02-17,2014-05-09
-2pil,1998-05-27,1998-03-02
-3pi7,2010-11-17,2010-11-05
-7pi0,2022-08-17,2021-08-19
-5pib,2017-03-15,2017-02-07
-1pin,1998-10-14,1998-06-21
-3pic,2011-06-01,2010-11-05
-5pii,2017-03-15,2017-02-07
-8pib,2024-04-24,2023-06-21
-3pip,2011-02-23,2010-11-07
-5piz,2017-03-15,2017-02-07
-1pip,1993-10-31,1992-10-03
-5pif,2017-03-15,2017-02-07
-8pi5,2023-11-08,2023-06-21
-6pi7,2019-07-24,2019-06-26
-7pie,2022-09-21,2021-08-19
-5pit,2017-03-15,2017-02-07
-8pi2,2023-07-05,2023-06-20
-8pif,2023-07-12,2023-06-21
-3pif,2011-02-09,2010-11-06
-1pim,2003-06-17,2003-05-30
-1pi6,2003-07-15,2003-05-29
-4pi7,2015-10-14,2014-05-08
-2pi8,2007-05-08,2007-04-13
-1piu,2003-06-17,2003-05-30
-5pi4,2017-03-15,2017-02-07
-5piq,2017-03-15,2017-02-07
-7pil,2021-10-13,2021-08-20
-4pi0,2014-06-25,2014-05-07
-5pir,2017-03-15,2017-02-07
-2pin,2008-02-26,2007-04-13
-7pi4,2021-09-29,2021-08-19
-2piz,2008-01-22,2007-04-15
-4pi2,2014-06-25,2014-05-07
-7piw,2022-08-17,2021-08-23
-6piw,2020-03-04,2019-06-27
-3pi8,2010-11-24,2010-11-05
-5pie,2017-03-15,2017-02-07
-3pi1,2011-11-09,2010-11-05
-3pi3,2011-11-09,2010-11-05
-5pi9,2017-03-15,2017-02-07
-4pid,2014-09-10,2014-05-08
-4pih,2014-10-29,2014-05-08
-2pio,2007-09-25,2007-04-13
-5pid,2017-03-15,2017-02-07
-3pia,2010-11-24,2010-11-05
-7pig,2022-09-21,2021-08-19
-2piu,2007-09-25,2007-04-13
-7pi3,2022-02-09,2021-08-19
-3piv,2011-07-20,2010-11-08
-6pit,2019-10-16,2019-06-27
-2pig,2007-04-24,2007-04-13
-2pia,1993-04-15,1993-02-15
-8pid,2024-04-24,2023-06-21
-5piv,2017-03-15,2017-02-07
-8piq,2023-07-26,2023-06-22
-1pi3,2004-11-23,2003-05-29
-6pib,2020-02-12,2019-06-26
-1pic,1997-09-17,1997-06-23
-3pij,2011-04-27,2010-11-06
-4pig,2014-10-29,2014-05-08
-5pig,2017-03-15,2017-02-07
-6piy,2020-03-04,2019-06-27
-4piu,2015-11-04,2014-05-09
-1pir,1995-06-03,1994-12-22
-3pix,2011-01-12,2010-11-08
-1pi5,2004-02-24,2003-05-29
-1pie,2003-09-23,2003-05-30
-2pid,2007-10-23,2007-04-13
-1pif,1996-12-07,1996-06-15
-5pi1,2017-03-15,2017-02-07
-1pi4,2004-02-24,2003-05-29
-7pi5,2022-08-17,2021-08-19
-8pi1,2023-11-01,2023-06-20
-3pit,2011-03-09,2010-11-08
-3pir,2011-03-09,2010-11-07
-5pic,2017-03-15,2017-02-07
-4pip,2014-12-03,2014-05-09
-6pia,2019-09-18,2019-06-26
-8piz,2024-04-03,2023-06-22
-1pig,1996-12-07,1996-06-15
-3pi9,2010-11-24,2010-11-05
-2pi6,2007-05-01,2007-04-13
-7piv,2021-11-17,2021-08-23
-2piy,2008-01-22,2007-04-15
-4pio,2014-12-03,2014-05-09
-5pi7,2017-03-15,2017-02-07
-8pim,2024-04-24,2023-06-22
-5pih,2017-03-15,2017-02-07
-7pim,2021-12-22,2021-08-20
-3pih,2011-01-19,2010-11-06
-6pic,2019-09-18,2019-06-26
-5pia,2017-03-15,2017-02-07
-7pif,2022-09-21,2021-08-19
-4pir,2014-08-06,2014-05-09
-5pi6,2017-03-15,2017-02-07
-4piy,2016-02-17,2014-05-09
-1pi1,2003-09-30,2003-05-29
-2piq,2007-09-25,2007-04-13
-6pii,2019-11-13,2019-06-26
-3pi5,2011-03-23,2010-11-05
-4piq,2014-09-10,2014-05-09
-5pi0,2017-03-15,2017-02-07
-4pik,2015-11-04,2014-05-08
-4piv,2014-07-23,2014-05-09
-4pi9,2015-10-14,2014-05-08
-7pib,2022-05-25,2021-08-19
-7pih,2022-09-21,2021-08-19
-1piw,2004-08-10,2003-05-30
-4pib,2014-07-02,2014-05-08
-1pis,1995-06-03,1994-12-22
-6piu,2020-03-04,2019-06-27
-6pim,2019-10-09,2019-06-26
-6pi6,2019-11-13,2019-06-26
-5pik,2017-03-15,2017-02-07
-6piz,2020-03-04,2019-06-27
-5pi8,2017-03-15,2017-02-07
-4piz,2016-02-17,2014-05-09
-5pij,2017-03-15,2017-02-07
-2pip,2007-09-25,2007-04-13
-3pi0,2011-11-02,2010-11-05
-3pi4,2011-11-09,2010-11-05
-6pix,2020-03-04,2019-06-27
-4pin,2014-12-03,2014-05-09
-6piv,2020-03-04,2019-06-27
-2piv,2007-09-25,2007-04-13
-3piz,2011-01-12,2010-11-08
-1piv,1995-06-03,1995-02-02
-5piy,2017-03-15,2017-02-07
-2pir,2007-09-25,2007-04-13
-2pi4,2007-06-19,2007-04-12
-5pip,2017-03-15,2017-02-07
-6pi1,2019-09-18,2019-06-25
-2pit,2007-09-25,2007-04-13
-7pid,2022-09-21,2021-08-19
-8pil,2024-04-24,2023-06-22
-3pio,2011-02-23,2010-11-07
-4pis,2014-09-10,2014-05-09
-1piz,2004-01-13,2003-05-30
-5pix,2017-03-15,2017-02-07
-6pis,2019-12-25,2019-06-27
-6pi5,2019-11-13,2019-06-26
-4pi8,2015-10-14,2014-05-08
-2pix,2007-09-25,2007-04-13
-8pij,2024-04-03,2023-06-21
-3pi2,2011-11-09,2010-11-05
-5pio,2017-03-15,2017-02-07
-6pid,2019-09-18,2019-06-26
-5piw,2017-03-15,2017-02-07
-6piq,2020-07-01,2019-06-26
-7pi1,2022-09-07,2021-08-19
-5pim,2017-03-15,2017-02-07
-2piw,2007-09-25,2007-04-13
-2pie,2007-12-11,2007-04-13
-7piu,2021-11-17,2021-08-23
-3pii,2011-11-09,2010-11-06
-3piu,2010-12-15,2010-11-08
-5pi5,2017-03-15,2017-02-07
-6pi8,2019-09-18,2019-06-26
-4pit,2015-11-04,2014-05-09
-3piy,2011-01-12,2010-11-08
-6pi9,2019-07-10,2019-06-26
-5pis,2017-03-15,2017-02-07
-5pi3,2017-03-15,2017-02-07
-6pi0,2019-10-02,2019-06-25
-5pil,2017-03-15,2017-02-07
-6pij,2019-10-02,2019-06-26
-5pi2,2017-03-15,2017-02-07
-5piu,2017-03-15,2017-02-07
-5pin,2017-03-15,2017-02-07
-2h5z,2007-06-05,2006-05-29
-2h5u,2007-05-29,2006-05-27
-1h58,2002-06-18,2001-05-20
-2h5j,2006-09-19,2006-05-26
-6h59,2019-05-15,2018-07-24
-6h5o,2019-08-14,2018-07-25
-6h5t,2019-02-27,2018-07-25
-1h5d,2002-05-27,2001-05-21
-3h57,2009-05-05,2009-04-21
-3h50,2009-05-05,2009-04-21
-8h5f,2023-10-11,2022-10-13
-6h52,2019-06-12,2018-07-23
-5h53,2017-01-18,2016-11-04
-3h58,2009-05-05,2009-04-21
-4h50,2013-10-09,2012-09-18
-1h5q,2001-06-21,2001-05-24
-8h57,2023-10-11,2022-10-12
-4h52,2013-02-20,2012-09-18
-2h5i,2006-09-19,2006-05-26
-6h5a,2019-05-15,2018-07-24
-8h5l,2023-10-25,2022-10-13
-3h5n,2009-06-16,2009-04-22
-2h5a,2006-08-08,2006-05-25
-3h5z,2009-05-12,2009-04-22
-5h5u,2017-01-25,2016-11-09
-1h5c,2002-06-18,2001-05-21
-1h51,2003-10-03,2001-05-17
-5h5f,2017-01-18,2016-11-05
-2h57,2006-07-25,2006-05-25
-2h51,2008-03-11,2006-05-25
-6h5d,2019-07-24,2018-07-24
-8h5y,2023-10-18,2022-10-14
-5h5s,2016-12-07,2016-11-09
-8h51,2023-10-11,2022-10-11
-3h52,2009-12-01,2009-04-21
-7h52,2024-04-24,2024-04-04
-8h52,2022-11-09,2022-10-11
-4h5i,2012-11-07,2012-09-18
-2h59,2006-09-05,2006-05-25
-6h5q,2019-03-13,2018-07-25
-2h5f,2006-08-29,2006-05-26
-4h5r,2014-03-19,2012-09-18
-5h5l,2017-09-20,2016-11-07
-5h5a,2017-11-08,2016-11-04
-7h54,2024-04-24,2024-04-04
-1h55,2002-06-18,2001-05-18
-2h55,2006-10-03,2006-05-25
-6h54,2019-08-14,2018-07-23
-1h5n,2002-05-17,2001-05-22
-5h5o,2017-05-24,2016-11-08
-1h5f,2002-05-27,2001-05-21
-2h5m,2006-11-28,2006-05-26
-4h5e,2012-12-26,2012-09-18
-3h5r,2009-06-16,2009-04-22
-4h5c,2012-12-26,2012-09-18
-1h5k,2002-05-27,2001-05-22
-1h5h,2002-06-21,2001-05-22
-8h53,2023-10-25,2022-10-12
-1h5x,2002-05-23,2001-05-29
-3h5i,2009-05-05,2009-04-22
-1h5t,2001-11-23,2001-05-25
-3h5k,2009-10-13,2009-04-22
-6h5e,2018-09-05,2018-07-24
-7h53,2024-04-24,2024-04-04
-1h5j,2002-05-27,2001-05-22
-7h51,2024-04-24,2024-04-04
-8h5a,2023-10-25,2022-10-12
-8h5p,2023-10-11,2022-10-13
-4h5t,2014-03-19,2012-09-18
-4h5b,2013-01-30,2012-09-18
-4h58,2013-02-27,2012-09-18
-2h5d,2006-09-26,2006-05-25
-2h5k,2006-08-15,2006-05-26
-5h52,2017-11-08,2016-11-04
-4h55,2012-10-31,2012-09-18
-5h5g,2017-05-24,2016-11-05
-4h5g,2012-10-03,2012-09-18
-4h5j,2012-11-07,2012-09-18
-5h5r,2016-12-07,2016-11-09
-5h59,2017-02-01,2016-11-04
-4h5v,2014-03-19,2012-09-18
-3h55,2009-10-20,2009-04-21
-6h5b,2019-11-27,2018-07-24
-5h5i,2017-05-24,2016-11-05
-2h5n,2006-07-25,2006-05-26
-1h5v,2002-05-23,2001-05-28
-1h5m,2002-05-27,2001-05-22
-6h51,2019-06-12,2018-07-23
-8h5j,2023-10-25,2022-10-13
-1h5s,2001-11-23,2001-05-25
-6h5m,2019-08-07,2018-07-25
-1h5r,2001-11-23,2001-05-25
-3h5q,2009-05-26,2009-04-22
-6h5k,2019-08-07,2018-07-25
-3h5x,2009-05-19,2009-04-22
-1h5l,2002-06-21,2001-05-22
-7h55,2024-04-24,2024-04-04
-8h5d,2023-10-18,2022-10-12
-3h5g,2009-07-14,2009-04-22
-3h56,2010-02-02,2009-04-21
-3h5v,2009-06-09,2009-04-22
-3h5a,2009-06-16,2009-04-21
-4h5w,2014-03-19,2012-09-19
-1h50,2001-07-05,2001-05-17
-1h54,2001-09-05,2001-05-18
-1h5u,2001-06-28,2001-05-25
-8h5z,2023-10-18,2022-10-14
-6h5z,2019-04-10,2018-07-25
-5h5e,2017-01-18,2016-11-05
-3h5u,2009-09-08,2009-04-22
-3h59,2009-09-08,2009-04-21
-2h54,2008-03-11,2006-05-25
-1h57,2002-06-17,2001-05-20
-4h54,2013-07-03,2012-09-18
-8h5e,2022-12-07,2022-10-13
-1h56,2003-08-07,2001-05-20
-6h5x,2018-11-07,2018-07-25
-3h53,2009-10-20,2009-04-21
-2h5l,2007-04-10,2006-05-26
-3h5y,2009-05-19,2009-04-22
-6h5j,2019-07-24,2018-07-24
-1h5i,2002-05-27,2001-05-22
-6h5c,2019-07-24,2018-07-24
-6h57,2019-06-19,2018-07-24
-1h5g,2002-05-27,2001-05-21
-8h5m,2023-10-25,2022-10-13
-8h5c,2023-07-19,2022-10-12
-6h5s,2019-06-12,2018-07-25
-5h5j,2017-02-01,2016-11-05
-5h5k,2017-06-28,2016-11-06
-8h5u,2023-10-18,2022-10-13
-4h5d,2012-12-26,2012-09-18
-5h5d,2017-01-18,2016-11-05
-6h5w,2018-11-07,2018-07-25
-3h5s,2009-09-08,2009-04-22
-1h5z,2003-10-03,2001-05-31
-6h5y,2019-08-14,2018-07-25
-3h5b,2009-06-16,2009-04-21
-6h5u,2019-08-07,2018-07-25
-4h5f,2012-10-03,2012-09-18
-3h54,2009-10-20,2009-04-21
-4h5n,2014-03-19,2012-09-18
-1h5a,2002-06-18,2001-05-21
-5h5h,2017-05-24,2016-11-05
-5h5q,2016-12-07,2016-11-09
-6h50,2019-06-12,2018-07-23
-4h53,2013-02-20,2012-09-18
-5h5x,2017-05-10,2016-11-10
-3h5c,2010-04-28,2009-04-21
-2h5e,2007-05-15,2006-05-26
-8h5t,2023-10-18,2022-10-13
-1h5e,2002-05-27,2001-05-21
-2h5o,2006-08-22,2006-05-26
-5h5z,2017-11-22,2016-11-10
-6h5g,2019-07-24,2018-07-24
-8h58,2023-10-25,2022-10-12
-8h59,2023-02-08,2022-10-12
-3h5f,2009-07-14,2009-04-22
-6h56,2019-07-24,2018-07-23
-6h5l,2019-04-10,2018-07-25
-5h56,2017-06-28,2016-11-04
-2h5s,2006-10-17,2006-05-27
-3mzi,2011-08-31,2010-05-12
-5mzm,2018-03-21,2017-02-01
-7mz0,2022-05-25,2021-05-23
-1mz6,2002-10-16,2002-10-05
-6mzb,2019-03-06,2018-11-04
-1mzf,2002-11-20,2002-10-07
-5mzi,2017-04-19,2017-01-31
-3mzb,2011-02-09,2010-05-12
-7mzb,2021-09-22,2021-05-24
-1mzv,2003-10-28,2002-10-10
-3mz9,2011-02-09,2010-05-12
-3mzc,2011-03-09,2010-05-12
-2mzi,2016-09-28,2015-02-12
-5mzo,2017-07-26,2017-02-01
-1mzy,2004-09-28,2002-10-10
-7mz6,2021-09-22,2021-05-24
-1mzo,2002-12-11,2002-10-09
-4mzs,2014-08-20,2013-09-30
-3mzw,2010-07-28,2010-05-13
-7mzh,2021-10-06,2021-05-24
-1mzu,2003-02-25,2002-10-09
-4mz4,2013-12-11,2013-09-29
-1mzb,2003-10-07,2002-10-07
-7mz1,2022-05-25,2021-05-23
-4mz6,2013-11-13,2013-09-29
-1mzz,2004-09-28,2002-10-10
-1mzn,2002-10-23,2002-10-09
-5mzl,2018-02-14,2017-02-01
-2mze,2015-11-11,2015-02-11
-4mzx,2015-04-01,2013-09-30
-6mze,2018-11-28,2018-11-05
-5mzg,2018-01-10,2017-01-31
-1mz8,2002-12-23,2002-10-07
-1mzp,2003-01-21,2002-10-09
-6mzg,2018-11-28,2018-11-05
-5mzz,2017-05-31,2017-02-02
-3mz4,2010-06-23,2010-05-11
-6mzq,2019-01-16,2018-11-05
-1mz4,2003-09-23,2002-10-05
-7mz9,2021-09-22,2021-05-24
-6mz2,2019-11-20,2018-11-03
-3mz8,2010-09-29,2010-05-12
-3mzt,2010-09-08,2010-05-13
-7mzi,2021-10-06,2021-05-24
-4mzv,2014-08-27,2013-09-30
-4mze,2013-11-06,2013-09-30
-7mze,2021-09-22,2021-05-24
-5mzn,2017-04-19,2017-02-01
-3mzg,2010-09-29,2010-05-12
-6mzj,2018-11-14,2018-11-05
-4mz8,2014-07-16,2013-09-29
-5mze,2018-01-10,2017-01-31
-7mzq,2022-07-06,2021-05-24
-3mz3,2010-06-23,2010-05-11
-4mz7,2013-11-20,2013-09-29
-6mzz,2019-03-27,2018-11-06
-4mzo,2014-09-10,2013-09-30
-7mz7,2021-09-22,2021-05-24
-7mzs,2022-07-06,2021-05-24
-5mzk,2017-04-19,2017-01-31
-7mzf,2021-10-06,2021-05-24
-5mza,2017-03-22,2017-01-31
-5mz3,2017-11-15,2017-01-30
-5mzq,2018-02-28,2017-02-01
-3mz5,2011-03-23,2010-05-11
-7mzt,2021-09-29,2021-05-24
-3mze,2011-03-16,2010-05-12
-1mz5,2002-10-16,2002-10-05
-7mz2,2022-05-25,2021-05-23
-3mz2,2010-07-07,2010-05-11
-3mz7,2010-06-23,2010-05-11
-5mzy,2017-05-31,2017-02-02
-3mzh,2011-06-08,2010-05-12
-5mzp,2017-07-26,2017-02-01
-4mzw,2013-10-16,2013-09-30
-4mzg,2014-03-26,2013-09-30
-3mzf,2011-03-16,2010-05-12
-4mzq,2014-03-26,2013-09-30
-3mzd,2011-03-16,2010-05-12
-2mzh,2015-11-18,2015-02-12
-7mzm,2021-10-06,2021-05-24
-2mzc,2016-04-13,2015-02-11
-1mz0,2003-07-29,2002-10-04
-7mzc,2021-09-22,2021-05-24
-5mzr,2018-02-14,2017-02-01
-1mzs,2002-11-13,2002-10-09
-1mze,2002-11-20,2002-10-07
-5mz2,2018-02-14,2017-01-30
-5mzx,2017-05-31,2017-02-02
-1mzj,2002-12-11,2002-10-08
-3mz0,2010-09-29,2010-05-11
-5mzv,2018-01-03,2017-02-01
-1mz9,2003-01-28,2002-10-07
-4mzk,2013-11-06,2013-09-30
-4mzi,2014-01-15,2013-09-30
-2mz1,2015-04-08,2015-02-05
-2mz9,2016-02-10,2015-02-08
-7mzr,2022-07-06,2021-05-24
-7mzn,2021-10-06,2021-05-24
-4mzn,2014-04-02,2013-09-30
-7mzl,2021-10-06,2021-05-24
-7mz3,2022-06-01,2021-05-24
-5mzj,2017-07-26,2017-01-31
-4mzh,2014-03-26,2013-09-30
-7mza,2021-09-22,2021-05-24
-4mzu,2013-10-09,2013-09-30
-3mzs,2010-12-15,2010-05-12
-7mzd,2021-09-22,2021-05-24
-7mzj,2021-10-06,2021-05-24
-4mzj,2013-11-06,2013-09-30
-7mzg,2021-10-06,2021-05-24
-4mzr,2014-01-15,2013-09-30
-2mzw,2016-01-27,2015-02-25
-6mzk,2019-05-15,2018-11-05
-3mz6,2010-06-23,2010-05-11
-6mzw,2019-01-16,2018-11-05
-4mzf,2014-03-26,2013-09-30
-5mzc,2017-04-19,2017-01-31
-4mz5,2013-11-13,2013-09-29
-6mzf,2018-11-28,2018-11-05
-2mzp,2015-06-03,2015-02-20
-7mz8,2022-06-01,2021-05-24
-5mzt,2018-02-14,2017-02-01
-1mzc,2003-07-08,2002-10-07
-4mz0,2014-01-29,2013-09-28
-6mz0,2019-11-06,2018-11-02
-4mz1,2014-01-01,2013-09-28
-7mz5,2021-09-22,2021-05-24
-2mzz,2015-05-13,2015-02-28
-6mz1,2019-11-20,2018-11-03
-4mza,2013-11-06,2013-09-29
-7mz4,2022-06-01,2021-05-24
-3mzo,2010-05-26,2010-05-12
-7mzk,2021-10-06,2021-05-24
-3mpq,2010-12-01,2010-04-27
-4mpm,2014-01-15,2013-09-13
-4mp7,2014-01-01,2013-09-12
-3mpa,2010-09-15,2010-04-26
-5mpg,2017-07-05,2016-12-16
-3mp3,2010-06-16,2010-04-24
-6mpy,2018-10-17,2018-10-09
-4mpp,2015-03-18,2013-09-13
-5mpr,2017-07-19,2016-12-18
-5mpa,2017-03-08,2016-12-16
-3mp6,2011-05-04,2010-04-25
-1mpy,1999-05-18,1998-10-20
-3mpi,2010-08-18,2010-04-27
-1mpq,1998-03-25,1997-03-24
-5mpl,2017-07-05,2016-12-16
-2mpa,1999-06-23,1999-06-09
-5mpq,2017-03-29,2016-12-17
-4mp0,2014-03-26,2013-09-12
-6mps,2018-10-17,2018-10-08
-5mpn,2018-01-17,2016-12-16
-5mps,2017-01-18,2016-12-18
-7mpl,2021-09-15,2021-05-04
-4mpv,2015-03-18,2013-09-13
-5mp1,2018-05-02,2016-12-15
-7mph,2021-09-22,2021-05-04
-3mph,2010-09-08,2010-04-27
-5mpc,2017-03-08,2016-12-16
-4mpe,2014-01-01,2013-09-12
-7mpf,2022-05-04,2021-05-04
-1mp4,2002-10-09,2002-09-11
-6mpt,2018-10-17,2018-10-08
-5mpt,2017-02-22,2016-12-19
-7mpo,2021-09-15,2021-05-04
-7mpk,2021-12-29,2021-05-04
-6mp3,2019-10-16,2018-10-05
-4mpu,2015-03-18,2013-09-13
-4mpy,2013-10-09,2013-09-14
-5mpb,2017-03-08,2016-12-16
-3mp8,2011-05-04,2010-04-26
-7mpn,2021-09-15,2021-05-04
-5mpz,2017-05-10,2016-12-19
-3mpu,2010-07-21,2010-04-27
-1mpt,1994-06-22,1994-04-13
-2mpj,2015-08-05,2014-05-23
-6mp7,2019-01-30,2018-10-05
-1mpo,1997-03-12,1996-01-11
-5mpk,2018-01-17,2016-12-16
-4mph,2013-09-25,2013-09-12
-4mpj,2015-03-18,2013-09-12
-7mpg,2021-09-08,2021-05-04
-7mpi,2022-05-11,2021-05-04
-6mpg,2019-07-24,2018-10-06
-3mp1,2011-05-04,2010-04-24
-7mp9,2021-12-01,2021-05-04
-6mp5,2019-04-10,2018-10-05
-3mpt,2010-07-07,2010-04-27
-1mpl,2003-02-25,2002-09-12
-4mpk,2013-11-06,2013-09-13
-7mpb,2021-05-12,2021-05-04
-3mpz,2010-05-19,2010-04-27
-3mpb,2010-07-21,2010-04-26
-7mpq,2021-09-15,2021-05-04
-1mpx,2003-04-15,2002-09-13
-3mpn,2010-12-01,2010-04-27
-6mpz,2019-02-06,2018-10-09
-4mpn,2014-01-01,2013-09-13
-6mpf,2019-04-24,2018-10-05
-7mpd,2021-09-22,2021-05-04
-5mp9,2017-03-08,2016-12-16
-7mpj,2022-05-11,2021-05-04
-5mp8,2017-05-24,2016-12-16
-6mp6,2019-11-06,2018-10-05
-3mp5,2010-06-16,2010-04-24
-4mpt,2013-12-11,2013-09-13
-6mp9,2018-11-21,2018-10-05
-6mpb,2019-11-06,2018-10-05
-6mp0,2018-11-07,2018-10-05
-3mpm,2010-06-02,2010-04-27
-4mp6,2014-03-05,2013-09-12
-6mpq,2019-02-27,2018-10-08
-3mpv,2010-09-22,2010-04-27
-6mp4,2019-11-13,2018-10-05
-6mpa,2019-01-30,2018-10-05
-7mpp,2021-09-15,2021-05-04
-4mpx,2015-03-18,2013-09-13
-3mp2,2010-09-08,2010-04-24
-4mp8,2014-03-05,2013-09-12
-4mpr,2014-08-27,2013-09-13
-1mpj,1996-01-29,1995-09-13
-2mpr,1997-04-01,1997-02-07
-1mpm,1997-03-12,1996-01-11
-5mpy,2017-02-22,2016-12-19
-4mp2,2014-01-01,2013-09-12
-7mpm,2021-09-15,2021-05-04
-6mph,2019-07-24,2018-10-06
-4mpb,2013-09-25,2013-09-12
-5mpj,2017-05-24,2016-12-16
-1mpw,2002-10-09,2002-09-13
-1mps,1998-10-14,1998-03-09
-1mpr,1997-03-12,1996-12-18
-3mpg,2010-11-10,2010-04-26
-1mpd,1995-10-15,1995-07-25
-4mpo,2014-01-22,2013-09-13
-4mpc,2014-01-01,2013-09-12
-3mps,2011-06-22,2010-04-27
-1mpa,1997-09-04,1997-02-26
-1mp0,2002-09-25,2002-09-10
-6mpk,2019-01-09,2018-10-07
-6mpd,2019-10-16,2018-10-05
-6mp1,2018-11-07,2018-10-05
-4mpd,2014-03-05,2013-09-12
-4mps,2013-09-25,2013-09-13
-7mp4,2022-05-11,2021-05-04
-5mpm,2018-01-17,2016-12-16
-7mp3,2022-02-02,2021-05-04
-6mp8,2018-11-21,2018-10-05
-1mp5,2002-10-09,2002-09-11
-6mpi,2019-04-24,2018-10-07
-7mpt,2021-09-15,2021-05-04
-4mpw,2015-03-18,2013-09-13
-3mpj,2010-08-18,2010-04-27
-5mp5,2018-05-02,2016-12-15
-1mp8,2003-09-16,2002-09-11
-4mpg,2013-09-25,2013-09-12
-1mp3,2002-10-09,2002-09-11
-2mpm,2014-12-10,2014-05-26
-7mpu,2021-09-15,2021-05-04
-5mp3,2018-05-02,2016-12-15
-1mpn,1997-03-12,1996-01-11
-6yom,2020-06-24,2020-04-14
-4yoi,2015-08-05,2015-03-11
-4yof,2016-03-23,2015-03-11
-7yo1,2024-03-06,2022-08-01
-7yop,2023-08-16,2022-08-01
-2yoh,2013-07-24,2012-10-24
-1yo1,2005-09-20,2005-01-26
-6yo0,2020-09-30,2020-04-14
-1yob,2005-10-18,2005-01-27
-4yov,2015-07-15,2015-03-12
-6yo9,2020-05-20,2020-04-14
-6yoj,2021-02-10,2020-04-14
-6yot,2021-04-28,2020-04-15
-7yo0,2024-03-06,2022-08-01
-1yow,2005-05-10,2005-01-28
-6yoy,2020-09-23,2020-04-15
-4yog,2015-08-05,2015-03-11
-6yo5,2021-04-28,2020-04-14
-4yoj,2015-08-05,2015-03-11
-2yoe,2012-10-31,2012-10-23
-6you,2021-04-28,2020-04-15
-5yoe,2017-12-27,2017-10-27
-6yoq,2020-07-15,2020-04-14
-5yof,2018-03-21,2017-10-27
-4yoc,2015-05-27,2015-03-11
-6yob,2020-11-04,2020-04-14
-4you,2015-07-15,2015-03-12
-6yoz,2020-09-16,2020-04-15
-7yoq,2023-08-02,2022-08-02
-2yor,2013-10-23,2012-10-26
-7yom,2023-08-02,2022-08-01
-5yoi,2018-11-07,2017-10-27
-5yo1,2018-11-07,2017-10-26
-4yox,2015-07-15,2015-03-12
-1yog,1996-12-07,1996-06-14
-4yor,2015-07-15,2015-03-12
-2yoo,2013-02-27,2012-10-25
-5yo2,2018-11-07,2017-10-26
-2yob,2013-10-30,2012-10-22
-6yoe,2020-11-04,2020-04-14
-5yox,2018-11-21,2017-10-31
-8you,2024-03-27,2024-03-13
-7yor,2023-08-02,2022-08-02
-4yow,2015-07-15,2015-03-12
-7yo5,2024-03-06,2022-08-01
-6yo1,2020-11-04,2020-04-14
-2yoc,2013-11-06,2012-10-23
-1yo2,2005-09-20,2005-01-26
-4yo7,2015-03-25,2015-03-11
-7yo6,2023-08-09,2022-08-01
-7yol,2023-08-02,2022-08-01
-5yog,2018-03-14,2017-10-27
-1yol,2006-01-27,2005-01-27
-7yoi,2023-08-02,2022-08-01
-6yo3,2020-12-30,2020-04-14
-2yoz,2013-07-10,2012-10-29
-1yo0,2005-09-20,2005-01-26
-5yoc,2017-12-27,2017-10-27
-5yoh,2018-11-07,2017-10-27
-6yod,2020-11-04,2020-04-14
-6yon,2021-04-28,2020-04-14
-4yo9,2015-08-05,2015-03-11
-5yoq,2018-02-07,2017-10-30
-5yov,2018-11-07,2017-10-31
-2yoi,2013-08-21,2012-10-24
-2yof,2013-07-24,2012-10-24
-1yoh,1996-12-07,1996-06-14
-7yos,2023-08-02,2022-08-02
-4yoa,2015-07-08,2015-03-11
-5yot,2018-11-07,2017-10-31
-7yod,2023-08-02,2022-08-01
-4yot,2015-07-15,2015-03-12
-4yo4,2015-05-06,2015-03-11
-1yov,2005-03-08,2005-01-28
-5yok,2018-07-18,2017-10-29
-1you,2005-03-15,2005-01-28
-1yoe,2006-01-17,2005-01-27
-4yo1,2015-06-24,2015-03-11
-5yoj,2018-07-11,2017-10-29
-2yoj,2013-10-09,2012-10-24
-4yo6,2015-05-20,2015-03-11
-4yok,2015-03-25,2015-03-11
-4yoz,2015-06-24,2015-03-12
-6yow,2020-09-23,2020-04-15
-6yox,2020-09-23,2020-04-15
-1yoa,2005-07-27,2005-01-27
-1yoi,1996-12-07,1996-06-14
-6yoa,2020-05-13,2020-04-14
-1yo8,2005-09-27,2005-01-26
-2yox,2013-04-10,2012-10-29
-5you,2018-11-07,2017-10-31
-5yow,2017-11-22,2017-10-31
-1yoo,1999-02-02,1998-06-26
-5yo9,2018-12-05,2017-10-27
-6yoo,2021-04-28,2020-04-14
-4yo8,2015-11-25,2015-03-11
-1yon,2006-04-18,2005-01-28
-4yoq,2015-05-27,2015-03-11
-7yo3,2023-08-30,2022-08-01
-2yok,2012-11-14,2012-10-25
-2yoa,2013-03-20,2012-10-22
-4yop,2015-12-23,2015-03-12
-7yo7,2023-08-09,2022-08-01
-2yoy,2013-04-10,2012-10-29
-1yom,2006-01-27,2005-01-27
-5yob,2017-12-27,2017-10-27
-6yoh,2021-02-24,2020-04-14
-2yol,2013-03-27,2012-10-25
-5yoa,2018-12-05,2017-10-27
-4yoy,2015-07-15,2015-03-12
-7yoh,2023-08-02,2022-08-01
-1yo7,2005-02-15,2005-01-26
-6yoc,2020-11-04,2020-04-14
-4yoe,2015-06-10,2015-03-11
-2yog,2013-07-24,2012-10-24
-1yop,2005-04-05,2005-01-28
-5yol,2017-11-08,2017-10-29
-4chi,2014-04-30,2013-12-02
-2chu,2006-08-14,2006-03-16
-8ch1,2024-01-24,2023-02-06
-6ch8,2018-05-02,2018-02-22
-3chl,2009-01-06,2008-03-10
-6chq,2018-04-04,2018-02-22
-1ch1,1999-04-09,1999-03-31
-4chz,2013-12-18,2013-12-05
-6chf,2019-02-27,2018-02-22
-5chv,2016-09-28,2015-07-10
-2ch4,2006-04-18,2006-03-10
-8chp,2023-09-06,2023-02-08
-5ch9,2015-09-09,2015-07-10
-8ch9,2024-02-21,2023-02-07
-8chr,2023-09-06,2023-02-08
-3chc,2008-03-25,2008-03-09
-7chp,2021-05-19,2020-07-06
-3cht,2008-05-27,2008-03-10
-3chs,2008-04-22,2008-03-10
-1ch8,1999-12-29,1999-03-31
-2ch5,2006-09-18,2006-03-13
-6cht,2019-02-27,2018-02-22
-3ch3,2008-03-25,2008-03-07
-6chl,2018-04-04,2018-02-22
-6ch7,2018-05-02,2018-02-22
-8ch6,2023-05-10,2023-02-07
-8chu,2024-02-21,2023-02-08
-7chi,2020-11-25,2020-07-05
-6chu,2018-08-01,2018-02-23
-6chi,2018-06-06,2018-02-22
-8chc,2024-01-24,2023-02-07
-5chz,2016-07-20,2015-07-10
-1ch7,1999-04-09,1999-03-31
-6chh,2018-06-13,2018-02-22
-1ch3,1999-04-09,1999-03-31
-7ch6,2021-08-04,2020-07-05
-3chv,2008-04-01,2008-03-10
-3chf,2008-03-25,2008-03-09
-1ch4,1999-04-27,1998-06-11
-8ch0,2024-02-21,2023-02-06
-2chx,2006-05-22,2006-03-16
-8ch4,2023-07-05,2023-02-07
-6ch9,2018-05-02,2018-02-22
-5ch5,2016-06-15,2015-07-10
-7chw,2020-08-12,2020-07-06
-4chv,2014-01-15,2013-12-04
-7ch3,2021-10-20,2020-07-04
-2chz,2006-05-22,2006-03-16
-2chm,2006-06-08,2006-03-15
-8chl,2023-09-06,2023-02-08
-4cho,2013-12-11,2013-12-04
-5chy,1996-12-07,1996-08-29
-4ch5,2014-03-19,2013-11-28
-6chn,2018-04-04,2018-02-22
-8chf,2024-02-21,2023-02-07
-6chd,2018-03-07,2018-02-22
-1ch5,1999-04-09,1999-03-31
-2chq,2006-06-06,2006-03-16
-5chb,2015-07-22,2015-07-10
-6ch0,2018-08-15,2018-02-21
-6chg,2018-08-22,2018-02-22
-5chk,2016-03-23,2015-07-10
-4chp,2013-12-11,2013-12-04
-3che,2008-03-25,2008-03-09
-2ch7,2006-04-18,2006-03-13
-8chd,2024-02-21,2023-02-07
-7chv,2021-07-14,2020-07-06
-5chr,2016-04-27,2015-07-10
-5chq,2016-04-27,2015-07-10
-8cha,2024-05-22,2023-02-07
-8ch2,2024-01-24,2023-02-06
-5cha,1985-04-01,1985-01-22
-4chy,2013-12-18,2013-12-04
-6cho,2018-04-04,2018-02-22
-7ch0,2020-09-09,2020-07-03
-3chp,2008-04-22,2008-03-10
-5chu,2016-08-03,2015-07-10
-2chh,2006-03-16,2006-03-15
-6ch5,2019-01-16,2018-02-21
-2che,1994-04-30,1994-01-17
-5ch7,2016-03-09,2015-07-10
-7ch1,2020-08-26,2020-07-03
-1chw,1999-08-18,1999-03-30
-3cho,2008-04-22,2008-03-10
-8chy,2024-02-21,2023-02-08
-4ch1,2014-09-03,2013-11-28
-3ch5,2008-07-01,2008-03-07
-7chm,2021-05-12,2020-07-06
-7cho,2021-05-19,2020-07-06
-6chp,2018-04-04,2018-02-22
-3ch1,2009-03-31,2008-03-06
-3chd,2008-03-25,2008-03-09
-3ch2,2008-03-25,2008-03-07
-7chh,2020-09-16,2020-07-05
-7chl,2021-10-20,2020-07-06
-7chs,2021-05-19,2020-07-06
-1chj,1994-12-20,1994-06-01
-4ch2,2013-12-11,2013-11-28
-2chi,2006-12-13,2006-03-15
-2chn,2006-05-08,2006-03-15
-2cht,1994-07-31,1994-04-08
-4chx,2014-07-23,2013-12-04
-7chj,2020-11-25,2020-07-05
-3chk,2009-01-06,2008-03-10
-1ch2,1999-04-09,1999-03-31
-3chx,2008-07-15,2008-03-10
-8chs,2024-02-21,2023-02-08
-2ch6,2006-09-18,2006-03-13
-5chj,2016-08-03,2015-07-10
-1chh,1994-12-20,1994-06-01
-6chz,2018-03-21,2018-02-23
-2cho,2006-06-19,2006-03-16
-2chb,1997-12-03,1997-06-03
-2chg,2006-06-06,2006-03-14
-5cht,2016-06-29,2015-07-10
-2ch8,2006-05-31,2006-03-13
-8chn,2023-09-06,2023-02-08
-3chj,2009-01-06,2008-03-10
-2chw,2006-05-22,2006-03-16
-7cht,2021-05-12,2020-07-06
-1chn,1994-07-31,1994-04-20
-3chr,2008-04-22,2008-03-10
-2cha,1977-01-18,1975-01-01
-4chl,2014-12-17,2013-12-03
-1chc,1994-04-30,1994-02-02
-8ch8,2024-02-21,2023-02-07
-4chg,2014-11-12,2013-12-02
-1ch0,1999-12-22,1999-03-30
-4ch9,2014-01-08,2013-11-29
-1ch9,1999-04-09,1999-03-31
-8chi,2023-09-06,2023-02-08
-3ch9,2008-03-25,2008-03-09
-3chm,2008-10-28,2008-03-10
-3chb,1998-08-12,1998-03-24
-5chc,2016-03-09,2015-07-10
-2chr,1995-07-31,1995-02-24
-2ch2,2006-03-28,2006-03-10
-4chq,2013-12-11,2013-12-04
-2ch1,2006-03-28,2006-03-10
-7ch8,2021-10-06,2020-07-05
-8chk,2023-09-06,2023-02-08
-5chi,2016-08-10,2015-07-10
-7cha,2021-05-19,2020-07-05
-1chm,1994-04-30,1993-07-19
-6chw,2018-03-21,2018-02-23
-3chq,2008-04-22,2008-03-10
-4chn,2013-12-11,2013-12-04
-3ch8,2009-03-31,2008-03-08
-6chk,2018-03-07,2018-02-22
-5chs,2015-07-22,2015-07-10
-6cha,1987-04-16,1987-02-06
-2chl,2006-03-22,2006-03-15
-3chg,2008-08-12,2008-03-09
-7chb,2020-09-16,2020-07-05
-4chw,2014-01-15,2013-12-04
-5chm,2016-08-03,2015-07-10
-2ch9,2006-04-04,2006-03-13
-4ch3,2014-03-19,2013-11-28
-3ch6,2008-06-10,2008-03-07
-3chw,2008-08-19,2008-03-10
-5chg,2016-02-24,2015-07-10
-7chn,2021-05-12,2020-07-06
-6chs,2018-07-04,2018-02-22
-5ch8,2016-04-20,2015-07-10
-4ch8,2013-12-11,2013-11-29
-8ch3,2024-01-24,2023-02-06
-6chm,2018-04-04,2018-02-22
-4ch6,2014-03-19,2013-11-28
-8chx,2023-06-21,2023-02-08
-5chp,2016-10-19,2015-07-10
-4chs,2014-12-17,2013-12-04
-8chq,2023-09-06,2023-02-08
-1chi,1994-12-20,1994-06-01
-6ch4,2018-04-11,2018-02-21
-8chm,2023-09-06,2023-02-08
-5cho,2016-06-29,2015-07-10
-8chj,2023-09-06,2023-02-08
-4cht,2014-02-12,2013-12-04
-4ch4,2014-03-26,2013-11-28
-6ch6,2019-01-16,2018-02-22
-4fvl,2013-08-21,2012-06-29
-3fvz,2009-09-01,2009-01-16
-5fvw,2016-04-20,2016-02-10
-6fvo,2019-04-10,2018-03-04
-7fvs,2023-06-28,2023-04-18
-5fv3,2016-02-17,2016-02-02
-5fvp,2016-04-20,2016-02-10
-6fvz,2018-04-25,2018-03-05
-6fvg,2019-06-19,2018-03-02
-6fvj,2018-10-24,2018-03-03
-8fvd,2023-05-24,2023-01-18
-5fvq,2016-04-20,2016-02-10
-3fvh,2009-08-04,2009-01-15
-3fv8,2009-04-07,2009-01-15
-1fv0,2002-08-28,2000-09-18
-5fv8,2017-06-07,2016-02-03
-4fvo,2013-07-03,2012-06-29
-4fvr,2012-07-25,2012-06-29
-5fv0,2016-03-02,2016-02-01
-2fvl,2006-02-21,2006-01-31
-8fv3,2024-01-17,2023-01-18
-6fvw,2018-08-29,2018-03-05
-4fvw,2013-05-15,2012-06-29
-2fv7,2006-02-28,2006-01-30
-7fvd,2023-03-29,2023-03-09
-5fvz,2016-04-20,2016-02-10
-8fvb,2023-05-24,2023-01-18
-7fvt,2023-06-28,2023-04-18
-7fvx,2023-06-14,2023-04-27
-5fvs,2016-04-20,2016-02-10
-3fv4,2010-02-09,2009-01-15
-1fvv,2001-01-17,2000-09-20
-2fvd,2006-10-10,2006-01-30
-8fvi,2023-09-06,2023-01-19
-2fv0,2006-05-30,2006-01-28
-7fvj,2023-03-29,2023-03-09
-7fvi,2023-03-29,2023-03-09
-7fve,2023-03-29,2023-03-09
-3fv9,2009-01-27,2009-01-15
-5fva,2016-03-09,2016-02-03
-7fv4,2023-03-29,2023-03-09
-6fvr,2018-05-16,2018-03-05
-8fvy,2024-01-24,2023-01-20
-6fvu,2018-08-22,2018-03-05
-4fvq,2012-07-25,2012-06-29
-4fvc,2013-07-03,2012-06-29
-1fvu,2001-02-14,2000-09-20
-5fvu,2016-04-20,2016-02-10
-7fvf,2023-03-29,2023-03-09
-7fvm,2023-03-29,2023-03-09
-8fv7,2023-05-24,2023-01-18
-7fvr,2023-03-29,2023-03-09
-2fvf,2006-04-11,2006-01-30
-3fv2,2010-01-19,2009-01-15
-5fve,2017-02-22,2016-02-05
-1fv5,2000-10-04,2000-09-18
-3fvm,2009-09-01,2009-01-16
-8fv4,2024-01-17,2023-01-18
-8fvs,2024-01-24,2023-01-19
-3fv7,2010-02-02,2009-01-15
-2fvk,2006-03-14,2006-01-31
-7fvh,2023-03-29,2023-03-09
-1fv3,2001-09-05,2000-09-18
-2fv8,2006-02-28,2006-01-30
-8fve,2023-05-24,2023-01-18
-8fv6,2023-05-24,2023-01-18
-3fvn,2010-01-19,2009-01-16
-5fvy,2016-04-20,2016-02-10
-5fvt,2016-04-20,2016-02-10
-5fv9,2016-03-09,2016-02-03
-4fvf,2012-08-15,2012-06-29
-7fv6,2023-03-29,2023-03-09
-1fv9,2000-10-18,2000-09-19
-1fvi,2000-11-22,2000-09-20
-4fv9,2012-08-29,2012-06-29
-7fv0,2023-03-29,2023-03-09
-3fvo,2010-01-19,2009-01-16
-8fv8,2023-05-24,2023-01-18
-3fvp,2010-02-09,2009-01-16
-4fv6,2012-08-29,2012-06-29
-7fvc,2023-03-29,2023-03-09
-5fvn,2016-08-10,2016-02-09
-5fvo,2016-04-20,2016-02-10
-7fvk,2023-03-29,2023-03-09
-6fvv,2018-08-22,2018-03-05
-7fvn,2023-03-29,2023-03-09
-8fv2,2024-02-07,2023-01-18
-5fv7,2016-08-17,2016-02-03
-8fvk,2024-02-07,2023-01-19
-3fvj,2010-03-16,2009-01-15
-7fvy,2023-06-14,2023-04-27
-1fvp,1995-10-15,1995-07-07
-2fv1,2006-05-30,2006-01-28
-2fvm,2006-03-14,2006-01-31
-2fva,2006-04-11,2006-01-30
-5fvx,2016-04-20,2016-02-10
-6fvh,2018-06-06,2018-03-02
-7fvz,2023-06-14,2023-04-27
-7fv5,2023-03-29,2023-03-09
-7fvv,2023-06-14,2023-04-27
-4fv2,2012-08-29,2012-06-29
-4fvn,2013-07-17,2012-06-29
-3fvg,2010-01-19,2009-01-15
-1fv2,2001-09-05,2000-09-18
-1fvt,2001-01-17,2000-09-20
-7fv8,2023-03-29,2023-03-09
-7fvu,2023-06-14,2023-04-27
-8fvw,2023-04-05,2023-01-19
-7fvp,2023-03-29,2023-03-09
-3fvc,2009-03-17,2009-01-15
-7fvq,2023-03-29,2023-03-09
-3fvi,2010-03-16,2009-01-15
-7fv1,2023-03-29,2023-03-09
-1fvm,2000-11-01,2000-09-20
-2fvx,1997-03-12,1996-12-19
-6fvm,2019-04-10,2018-03-04
-3fvu,2009-05-19,2009-01-16
-2fvj,2006-05-16,2006-01-31
-8fva,2023-05-24,2023-01-18
-3fvy,2009-02-03,2009-01-16
-6fv1,2019-03-20,2018-02-28
-7fvg,2023-03-29,2023-03-09
-4fva,2012-10-31,2012-06-29
-4fv0,2012-08-22,2012-06-28
-4fv4,2012-08-29,2012-06-29
-4fv5,2012-08-29,2012-06-29
-3fv1,2010-01-19,2009-01-15
-7fvb,2023-03-29,2023-03-09
-3fv5,2010-01-26,2009-01-15
-4fvk,2012-09-19,2012-06-29
-2fvy,2007-02-06,2006-01-31
-6fvf,2019-06-19,2018-03-02
-6fvx,2018-08-22,2018-03-05
-2fvc,2007-01-16,2006-01-30
-5fvv,2016-04-20,2016-02-10
-8fvu,2024-01-03,2023-01-19
-4fvt,2012-08-15,2012-06-29
-6fv2,2019-03-20,2018-02-28
-7fvw,2023-06-14,2023-04-27
-4fvv,2012-10-24,2012-06-29
-8fvv,2024-01-31,2023-01-19
-1fvs,2001-03-14,2000-09-20
-5fvb,2016-06-29,2016-02-05
-3fvk,2010-01-19,2009-01-15
-8fvr,2023-04-05,2023-01-19
-3fva,2009-06-30,2009-01-15
-6fvs,2018-05-16,2018-03-05
-2fv9,2006-03-14,2006-01-30
-7fv2,2023-03-29,2023-03-09
-5fvr,2016-04-20,2016-02-10
-3fvf,2009-05-05,2009-01-15
-5fvj,2016-06-01,2016-02-08
-3fvd,2009-01-27,2009-01-15
-4fvu,2012-09-19,2012-06-29
-4fvy,2013-05-15,2012-06-29
-1fvx,1997-03-12,1996-12-12
-2fv5,2006-07-04,2006-01-30
-3fvq,2009-08-25,2009-01-16
-6fv9,2019-03-20,2018-03-01
-6fv4,2018-05-16,2018-03-01
-4fv8,2012-08-29,2012-06-29
-6fv3,2018-05-16,2018-02-28
-2fv2,2007-01-09,2006-01-28
-3fvl,2010-01-12,2009-01-16
-3fvx,2009-05-19,2009-01-16
-4fv3,2012-08-29,2012-06-29
-7fv3,2023-03-29,2023-03-09
-6fvl,2019-04-10,2018-03-04
-8fvc,2023-05-24,2023-01-18
-8fv9,2023-05-24,2023-01-18
-8fvj,2023-09-06,2023-01-19
-4fv7,2012-08-29,2012-06-29
-5fv6,2017-02-22,2016-02-03
-4fvz,2013-05-15,2012-06-29
-3fvb,2009-02-03,2009-01-15
-6fvy,2018-08-22,2018-03-05
-6fve,2018-06-06,2018-03-02
-3fv3,2009-05-19,2009-01-15
-4fvd,2013-06-19,2012-06-29
-4fv1,2012-08-22,2012-06-28
-4fvx,2013-05-15,2012-06-29
-3fvs,2009-05-19,2009-01-16
-8fvf,2024-02-07,2023-01-18
-4fvg,2012-08-15,2012-06-29
-7fv7,2023-03-29,2023-03-09
-7fvo,2023-03-29,2023-03-09
-6fvt,2018-08-22,2018-03-05
-6fvn,2019-04-10,2018-03-04
-6fv5,2018-06-13,2018-03-01
-4fvb,2013-06-19,2012-06-29
-7fv9,2023-03-29,2023-03-09
-7fva,2023-03-29,2023-03-09
-7fvl,2023-03-29,2023-03-09
-4g3j,2013-07-17,2012-07-14
-2g37,2007-02-27,2006-02-17
-5g39,2016-08-10,2016-04-24
-3g31,2009-03-24,2009-02-01
-5g38,2016-08-10,2016-04-24
-8g39,2023-02-15,2023-02-07
-8g38,2023-12-06,2023-02-07
-5g36,2016-08-31,2016-04-20
-4g34,2012-08-08,2012-07-13
-1g3y,2001-10-25,2000-10-25
-6g3r,2018-10-17,2018-03-26
-8g32,2024-02-07,2023-02-06
-8g3h,2023-06-28,2023-02-07
-2g30,2006-03-14,2006-02-17
-8g3m,2023-05-31,2023-02-08
-4g38,2012-12-26,2012-07-13
-1g30,2001-10-23,2000-10-23
-5g3m,2016-09-14,2016-04-29
-8g3y,2023-05-17,2023-02-08
-8g3z,2023-05-31,2023-02-08
-3g34,2009-03-24,2009-02-01
-8g35,2023-05-17,2023-02-06
-1g35,2001-06-06,2000-10-23
-4g3q,2013-08-07,2012-07-15
-3g3y,2010-03-09,2009-02-03
-6g3n,2019-04-10,2018-03-26
-3g37,2010-11-03,2009-02-02
-1g3l,2000-12-27,2000-10-24
-2g3h,2006-10-03,2006-02-20
-5g3w,2016-11-23,2016-05-02
-5g3h,2017-06-21,2016-04-26
-1g3q,2001-04-21,2000-10-25
-1g31,1998-08-26,1998-03-27
-8g3q,2023-05-31,2023-02-08
-2g35,2006-05-02,2006-02-17
-5g3g,2017-06-21,2016-04-26
-1g33,2001-10-03,2000-10-23
-8g36,2023-05-17,2023-02-06
-2g3f,2006-09-26,2006-02-19
-4g3r,2012-08-01,2012-07-15
-3g3v,2009-05-05,2009-02-02
-6g39,2018-04-18,2018-03-24
-6g30,2019-04-10,2018-03-23
-4g31,2012-08-08,2012-07-13
-4g35,2012-12-05,2012-07-13
-6g3f,2018-05-16,2018-03-25
-1g3z,2000-11-08,2000-10-25
-6g3a,2018-04-18,2018-03-24
-4g32,2013-11-06,2012-07-13
-3g3r,2009-05-05,2009-02-02
-3g30,2009-03-24,2009-02-01
-6g35,2018-04-18,2018-03-24
-5g3n,2016-09-14,2016-04-29
-6g3j,2019-02-20,2018-03-26
-1g32,2001-10-23,2000-10-23
-1g3d,2001-01-17,2000-10-23
-6g38,2018-04-18,2018-03-24
-6g3y,2018-11-28,2018-03-26
-5g3r,2017-05-17,2016-04-30
-6g3k,2019-09-04,2018-03-26
-3g3n,2009-04-28,2009-02-02
-3g3d,2009-03-03,2009-02-02
-4g3i,2013-08-07,2012-07-14
-5g3l,2016-09-14,2016-04-29
-1g3c,2001-01-17,2000-10-23
-1g36,2001-10-23,2000-10-23
-5g34,2016-06-01,2016-04-18
-3g3p,2010-03-09,2009-02-02
-6g3w,2018-04-04,2018-03-26
-8g3x,2023-05-17,2023-02-08
-5g31,2017-03-15,2016-04-18
-4g3m,2013-02-20,2012-07-15
-5g32,2016-06-01,2016-04-18
-5g3c,2017-06-07,2016-04-25
-6g3u,2018-08-01,2018-03-26
-6g3x,2018-11-28,2018-03-26
-8g3w,2023-05-17,2023-02-08
-5g35,2016-06-01,2016-04-18
-3g3w,2009-05-05,2009-02-02
-3g35,2009-03-24,2009-02-01
-1g38,2001-03-05,2000-10-23
-5g3s,2016-08-03,2016-05-01
-2g3j,2007-03-06,2006-02-20
-3g3k,2009-06-02,2009-02-02
-6g3i,2018-05-16,2018-03-25
-1g3r,2001-04-21,2000-10-25
-2g38,2006-03-14,2006-02-17
-5g3u,2016-08-03,2016-05-01
-8g3p,2023-05-31,2023-02-08
-5g3f,2017-05-24,2016-04-25
-8g3c,2023-06-28,2023-02-07
-8g3j,2023-06-14,2023-02-08
-3g3h,2009-06-02,2009-02-02
-8g3r,2023-05-31,2023-02-08
-6g3z,2018-06-27,2018-03-26
-4g3d,2012-08-15,2012-07-13
-1g37,2001-04-21,2000-10-23
-8g3u,2023-05-17,2023-02-08
-4g3h,2012-08-01,2012-07-13
-6g3m,2019-04-10,2018-03-26
-1g3e,2001-01-17,2000-10-23
-1g3u,2001-10-25,2000-10-25
-3g3f,2009-06-02,2009-02-02
-8g3i,2023-06-14,2023-02-08
-4g37,2012-08-15,2012-07-13
-3g3c,2010-03-09,2009-02-02
-4g3p,2013-08-07,2012-07-15
-3g38,2010-03-09,2009-02-02
-5g3t,2016-08-03,2016-05-01
-6g3c,2019-03-27,2018-03-24
-6g3e,2018-05-16,2018-03-25
-6g31,2018-10-17,2018-03-24
-5g3b,2017-05-24,2016-04-25
-8g30,2023-05-31,2023-02-06
-8g3s,2023-05-17,2023-02-08
-3g3i,2009-06-02,2009-02-02
-3g3e,2009-06-23,2009-02-02
-6g37,2018-04-18,2018-03-24
-4g3g,2012-08-08,2012-07-13
-6g3s,2018-10-17,2018-03-26
-3g3m,2009-03-03,2009-02-02
-4g3e,2012-08-15,2012-07-13
-8g3v,2023-05-31,2023-02-08
-2g3y,2006-04-18,2006-02-21
-5g3y,2016-12-28,2016-05-03
-5g3p,2017-04-12,2016-04-29
-5g33,2016-06-01,2016-04-18
-4g36,2012-08-15,2012-07-13
-8g3o,2023-05-31,2023-02-08
-8g3e,2023-06-28,2023-02-07
-4g3x,2013-07-17,2012-07-15
-2g3d,2006-04-18,2006-02-17
-2g36,2006-03-28,2006-02-17
-6g36,2018-04-18,2018-03-24
-5g3z,2016-12-28,2016-05-03
-1g3f,2001-01-10,2000-10-24
-5g3a,2016-08-10,2016-04-25
-3g32,2009-03-24,2009-02-01
-1g3k,2000-11-22,2000-10-24
-3g3j,2009-06-02,2009-02-02
-5g3e,2017-05-24,2016-04-25
-6g3o,2018-06-27,2018-03-26
-4g3s,2013-08-07,2012-07-15
-6g3q,2018-11-28,2018-03-26
-3g3x,2009-05-05,2009-02-02
-6g3v,2018-11-28,2018-03-26
-1g3w,2001-10-25,2000-10-25
-8g3t,2023-05-17,2023-02-08
-4g3f,2012-08-08,2012-07-13
-1g3m,2003-07-22,2000-10-24
-5g3j,2017-02-15,2016-04-27
-6g33,2018-04-18,2018-03-24
-4g39,2012-12-26,2012-07-13
-1g3i,2000-11-22,2000-10-24
-5g3d,2017-05-24,2016-04-25
-1g3b,2001-01-17,2000-10-23
-3g3s,2009-02-10,2009-02-02
-6g34,2018-04-18,2018-03-24
-8g3n,2023-05-31,2023-02-08
-6g3h,2018-05-16,2018-03-25
-4g33,2013-11-06,2012-07-13
-3g3g,2009-06-02,2009-02-02
-6q8s,2020-01-15,2018-12-16
-1q86,2003-10-07,2003-08-20
-6q8w,2020-09-02,2018-12-16
-6q87,2019-03-20,2018-12-14
-7q8d,2022-11-23,2021-11-11
-4q89,2015-04-29,2014-04-26
-7q8k,2022-11-23,2021-11-11
-7q8l,2022-11-23,2021-11-11
-1q84,2004-02-10,2003-08-20
-4q8k,2014-09-17,2014-04-28
-4q8r,2014-11-05,2014-04-28
-5q84,2018-08-08,2017-05-25
-3q8l,2011-04-27,2011-01-06
-6q8n,2019-06-05,2018-12-15
-4q8e,2014-07-02,2014-04-26
-7q8w,2022-03-09,2021-11-11
-5q89,2018-08-08,2017-05-25
-7q8z,2022-03-09,2021-11-11
-7q8j,2022-11-23,2021-11-11
-1q8q,2004-02-10,2003-08-22
-1q81,2003-10-07,2003-08-20
-1q85,2004-03-23,2003-08-20
-1q8m,2003-12-09,2003-08-21
-7q8a,2022-11-09,2021-11-10
-4q8u,2015-05-20,2014-04-28
-5q8t,2018-08-08,2017-05-25
-2q8w,2008-06-17,2007-06-12
-6q8c,2019-04-17,2018-12-14
-6q89,2019-04-17,2018-12-14
-5q8o,2018-08-08,2017-05-25
-4q8z,2015-03-11,2014-04-28
-7q8m,2022-11-23,2021-11-11
-6q8k,2019-02-20,2018-12-14
-1q8p,2004-02-10,2003-08-22
-1q8t,2003-12-16,2003-08-22
-6q8q,2020-01-15,2018-12-16
-2q8m,2007-06-19,2007-06-11
-3q8e,2012-02-15,2011-01-06
-5q8e,2018-08-08,2017-05-25
-4q80,2014-09-03,2014-04-25
-3q85,2011-09-21,2011-01-06
-3q80,2011-05-04,2011-01-05
-3q86,2011-07-27,2011-01-06
-2q8j,2007-06-19,2007-06-11
-2q8x,2008-05-20,2007-06-12
-2q8q,2007-07-31,2007-06-11
-1q8h,2003-11-11,2003-08-21
-7q8t,2021-11-24,2021-11-11
-4q8g,2014-06-04,2014-04-27
-4q8b,2015-04-29,2014-04-26
-7q8y,2022-03-09,2021-11-11
-5q8x,2018-08-08,2017-05-25
-6q8p,2019-02-20,2018-12-15
-3q8m,2011-04-27,2011-01-06
-5q8j,2018-08-08,2017-05-25
-7q8e,2023-05-24,2021-11-11
-6q8j,2019-05-22,2018-12-14
-2q8i,2007-07-24,2007-06-10
-5q87,2018-08-08,2017-05-25
-4q8q,2015-05-20,2014-04-28
-2q80,2007-06-19,2007-06-08
-4q8t,2015-05-20,2014-04-28
-1q83,2004-02-10,2003-08-20
-5q83,2018-08-08,2017-05-25
-1q8c,2003-09-30,2003-08-20
-4q8n,2015-05-20,2014-04-28
-6q8d,2019-03-20,2018-12-14
-3q8y,2011-07-27,2011-01-07
-3q8i,2011-08-03,2011-01-06
-6q8y,2019-03-13,2018-12-16
-5q81,2018-08-08,2017-05-25
-2q8p,2007-07-31,2007-06-11
-6q84,2019-05-01,2018-12-14
-3q8n,2011-02-09,2011-01-06
-4q8v,2015-05-20,2014-04-28
-4q8l,2014-09-17,2014-04-28
-1q8s,2004-02-10,2003-08-22
-7q8c,2022-05-18,2021-11-11
-5q8a,2018-08-08,2017-05-25
-3q8x,2011-03-09,2011-01-07
-1q8w,2003-12-16,2003-08-22
-2q8z,2008-01-29,2007-06-12
-1q8a,2004-03-23,2003-08-20
-4q85,2014-08-13,2014-04-25
-6q82,2019-05-01,2018-12-14
-6q8r,2020-01-15,2018-12-16
-4q83,2015-03-11,2014-04-25
-3q8b,2012-02-15,2011-01-06
-1q8f,2004-05-11,2003-08-21
-3q8v,2011-07-27,2011-01-07
-6q86,2019-03-20,2018-12-14
-7q89,2022-01-26,2021-11-10
-7q8p,2022-11-23,2021-11-11
-6q81,2018-12-26,2018-12-13
-2q83,2007-06-26,2007-06-08
-5q8c,2018-08-08,2017-05-25
-6q8h,2019-03-20,2018-12-14
-6q8m,2019-06-05,2018-12-15
-4q8y,2015-03-11,2014-04-28
-3q84,2012-02-22,2011-01-06
-7q8i,2022-11-23,2021-11-11
-5q8l,2018-08-08,2017-05-25
-5q88,2018-08-08,2017-05-25
-6q8b,2019-04-17,2018-12-14
-3q8u,2011-07-27,2011-01-07
-2q8d,2007-07-03,2007-06-10
-6q8u,2019-07-03,2018-12-16
-5q8y,2018-08-08,2017-05-25
-5q85,2018-08-08,2017-05-25
-4q84,2014-08-13,2014-04-25
-4q8w,2015-05-20,2014-04-28
-7q8q,2022-11-23,2021-11-11
-3q8h,2011-01-19,2011-01-06
-4q8x,2015-03-11,2014-04-28
-5q8k,2018-08-08,2017-05-25
-4q8f,2014-07-02,2014-04-26
-2q89,2008-01-01,2007-06-09
-3q8d,2011-05-04,2011-01-06
-6q8g,2019-03-20,2018-12-14
-1q8v,2004-02-10,2003-08-22
-6q8x,2020-09-02,2018-12-16
-6q8e,2019-01-02,2018-12-14
-3q82,2011-07-20,2011-01-05
-7q87,2022-01-26,2021-11-10
-2q8e,2007-07-03,2007-06-10
-5q8r,2018-08-08,2017-05-25
-3q81,2011-07-20,2011-01-05
-4q81,2015-03-11,2014-04-25
-4q8h,2014-06-04,2014-04-27
-5q86,2018-08-08,2017-05-25
-2q85,2007-06-26,2007-06-08
-4q86,2014-08-13,2014-04-25
-7q8r,2022-03-16,2021-11-11
-3q8c,2012-02-15,2011-01-06
-5q8m,2018-08-08,2017-05-25
-2q88,2008-01-01,2007-06-09
-4q8i,2014-08-20,2014-04-27
-2q8f,2007-07-24,2007-06-10
-7q86,2022-03-02,2021-11-10
-5q8u,2018-08-08,2017-05-25
-3q88,2011-01-19,2011-01-06
-1q8j,2004-03-23,2003-08-21
-4q87,2015-03-11,2014-04-25
-4q8o,2015-05-20,2014-04-28
-1q8y,2003-09-23,2003-08-22
-6q85,2019-03-20,2018-12-14
-3q8w,2011-03-16,2011-01-07
-7q8s,2022-05-18,2021-11-11
-6q8a,2019-04-17,2018-12-14
-5q8i,2018-08-08,2017-05-25
-5q8p,2018-08-08,2017-05-25
-3q8f,2012-02-15,2011-01-06
-3q8p,2011-02-23,2011-01-06
-3q8q,2011-02-23,2011-01-06
-7q8o,2022-11-23,2021-11-11
-5q8v,2018-08-08,2017-05-25
-1q8u,2003-12-16,2003-08-22
-5q8g,2018-08-08,2017-05-25
-1q8o,2004-02-10,2003-08-22
-2q86,2008-04-01,2007-06-08
-4q8s,2014-05-21,2014-04-28
-5q80,2018-08-08,2017-05-25
-5q8d,2018-08-08,2017-05-25
-3q8k,2011-04-27,2011-01-06
-2q8y,2007-12-11,2007-06-12
-5q8w,2018-08-08,2017-05-25
-7q8n,2022-11-23,2021-11-11
-3q89,2011-07-27,2011-01-06
-3q8a,2012-01-18,2011-01-06
-5q8q,2018-08-08,2017-05-25
-7q8v,2022-03-09,2021-11-11
-8q8h,2024-05-15,2023-08-18
-5q8n,2018-08-08,2017-05-25
-4q8p,2015-05-20,2014-04-28
-2q8s,2008-10-14,2007-06-11
-7q8g,2022-11-23,2021-11-11
-5q8b,2018-08-08,2017-05-25
-1q82,2003-10-07,2003-08-20
-3q8s,2011-02-23,2011-01-06
-5q8s,2018-08-08,2017-05-25
-5q8h,2018-08-08,2017-05-25
-7q85,2022-10-19,2021-11-10
-5q8z,2018-08-08,2017-05-25
-3q87,2011-05-18,2011-01-06
-6q8z,2019-01-23,2018-12-16
-2q8g,2007-07-24,2007-06-10
-4q8m,2015-05-20,2014-04-28
-3q8r,2011-02-23,2011-01-06
-2q8h,2007-07-24,2007-06-10
-2q8c,2007-07-03,2007-06-10
-5q8f,2018-08-08,2017-05-25
-6q8o,2020-09-02,2018-12-15
-5q82,2018-08-08,2017-05-25
-7q8b,2022-05-18,2021-11-11
-5b7y,2017-03-15,2016-06-10
-3b7y,2007-11-27,2007-10-31
-8b7z,2022-11-23,2022-10-03
-8b72,2022-10-19,2022-09-28
-8b7r,2022-11-23,2022-10-02
-7b7u,2021-05-19,2020-12-11
-2b7f,2005-12-06,2005-10-04
-8b76,2023-11-01,2022-09-28
-7b7n,2020-12-30,2020-12-11
-4b7n,2012-10-03,2012-08-21
-7b7c,2021-03-17,2020-12-10
-5b7u,2017-06-14,2016-06-09
-7b7a,2022-06-22,2020-12-10
-5b76,2016-10-26,2016-06-05
-5b7p,2016-12-14,2016-06-08
-4b7i,2012-10-17,2012-08-20
-8b78,2023-07-12,2022-09-29
-7b7d,2021-03-10,2020-12-10
-8b7p,2023-10-11,2022-09-30
-4b7q,2012-10-03,2012-08-21
-7b7p,2021-04-28,2020-12-11
-3b71,2008-01-01,2007-10-30
-5b7g,2017-01-25,2016-06-07
-6b7f,2017-12-27,2017-10-03
-2b7q,2006-02-21,2005-10-05
-7b7g,2021-10-20,2020-12-10
-3b75,2008-10-14,2007-10-30
-3b7d,2007-11-20,2007-10-30
-4b7g,2013-08-28,2012-08-20
-3b70,2008-09-16,2007-10-29
-2b7r,2006-05-23,2005-10-05
-3b7s,2008-09-16,2007-10-31
-2b76,2006-02-21,2005-10-03
-4b78,2013-06-26,2012-08-16
-4b71,2012-10-03,2012-08-16
-8b7b,2023-08-23,2022-09-29
-4b73,2012-10-03,2012-08-16
-6b7o,2018-04-18,2017-10-04
-6b7n,2017-10-25,2017-10-04
-7b7f,2021-03-17,2020-12-10
-7b77,2022-02-23,2020-12-09
-6b79,2018-05-30,2017-10-03
-2b7j,2006-04-11,2005-10-04
-3b7i,2007-11-27,2007-10-30
-3b72,2008-09-09,2007-10-30
-8b7y,2023-01-25,2022-10-03
-4b76,2012-10-03,2012-08-16
-5b75,2016-10-26,2016-06-05
-3b7u,2008-09-16,2007-10-31
-5b7x,2017-05-03,2016-06-10
-4b79,2012-08-29,2012-08-16
-8b7e,2023-10-25,2022-09-29
-8b7c,2023-08-23,2022-09-29
-4b7e,2013-01-23,2012-08-17
-2b7z,2006-11-14,2005-10-05
-7b7y,2021-07-21,2020-12-11
-8b7q,2023-04-05,2022-09-30
-7b7x,2021-07-21,2020-12-11
-4b74,2012-10-03,2012-08-16
-4b72,2013-06-26,2012-08-16
-2b7a,2006-01-10,2005-10-04
-1b76,1999-01-28,1999-01-27
-6b76,2018-10-03,2017-10-03
-6b73,2018-01-17,2017-10-03
-2b7s,2006-05-23,2005-10-05
-5b78,2016-10-26,2016-06-05
-1b71,2000-01-26,1999-01-26
-4b7j,2012-10-03,2012-08-20
-4b7z,2013-09-04,2012-08-24
-3b7w,2007-11-27,2007-10-31
-6b77,2018-03-21,2017-10-03
-1b7v,2000-03-27,1999-01-22
-1b70,2000-02-09,1999-01-26
-4b7x,2013-01-09,2012-08-24
-6b74,2018-03-21,2017-10-03
-3b7j,2008-09-02,2007-10-31
-3b7e,2008-10-07,2007-10-30
-8b7u,2022-11-23,2022-10-03
-5b7m,2016-10-19,2016-06-07
-3b7r,2008-09-16,2007-10-31
-2b7n,2006-02-14,2005-10-04
-6b7d,2017-12-27,2017-10-03
-7b7h,2022-01-12,2020-12-10
-4b7v,2013-09-04,2012-08-22
-6b7i,2018-10-10,2017-10-04
-3b7v,2007-12-18,2007-10-31
-7b7s,2021-08-04,2020-12-11
-5b74,2017-06-14,2016-06-05
-7b7w,2021-07-21,2020-12-11
-5b72,2016-07-13,2016-06-03
-2b7d,2006-02-14,2005-10-04
-6b75,2018-10-03,2017-10-03
-6b7a,2017-12-27,2017-10-03
-4b7y,2013-02-06,2012-08-24
-3b7l,2007-11-13,2007-10-31
-8b70,2023-01-18,2022-09-28
-6b71,2018-10-10,2017-10-03
-7b7i,2021-10-20,2020-12-10
-5b77,2016-10-26,2016-06-05
-4b7k,2013-01-23,2012-08-20
-6b7k,2018-06-13,2017-10-04
-8b7l,2022-12-28,2022-09-30
-4b7f,2013-08-28,2012-08-20
-1b7e,1999-04-21,1999-01-22
-1b7y,2000-01-26,1999-01-26
-3b78,2008-06-17,2007-10-30
-6b7h,2018-04-25,2017-10-04
-8b7a,2023-08-23,2022-09-29
-8b7s,2022-11-16,2022-10-03
-5b7i,2016-07-06,2016-06-07
-4b7t,2013-01-30,2012-08-22
-4b7a,2013-09-04,2012-08-17
-8b71,2023-01-18,2022-09-28
-6b7u,2018-07-25,2017-10-05
-2b7b,2006-05-02,2005-10-04
-4b70,2013-06-26,2012-08-16
-7b7z,2021-07-07,2020-12-12
-5b79,2016-10-26,2016-06-05
-2b7k,2006-04-11,2005-10-04
-6b7v,2018-07-25,2017-10-05
-8b7o,2022-12-28,2022-09-30
-9b7e,2024-04-10,2024-03-27
-3b7p,2007-11-20,2007-10-31
-1b7a,1999-01-27,1999-01-21
-5b7z,2017-03-15,2016-06-10
-6b7w,2018-07-25,2017-10-05
-1b7t,1999-05-12,1999-01-15
-4b7d,2013-08-28,2012-08-17
-4b7h,2013-08-28,2012-08-20
-8b7x,2023-07-12,2022-10-03
-4b7r,2012-10-03,2012-08-21
-7b7b,2021-10-20,2020-12-10
-8b7d,2023-07-19,2022-09-29
-5b7e,2016-10-19,2016-06-07
-4b7b,2013-07-31,2012-08-17
-5b7n,2016-12-21,2016-06-08
-4b7p,2013-05-29,2012-08-21
-8b75,2023-03-29,2022-09-28
-7b75,2021-12-29,2020-12-09
-1b74,2000-01-28,1999-01-27
-3b7g,2007-11-13,2007-10-30
-4b75,2012-10-03,2012-08-16
-2b7h,2006-09-12,2005-10-04
-3b76,2007-11-13,2007-10-30
-8b79,2023-10-25,2022-09-29
-6b7c,2017-12-27,2017-10-03
-5b73,2016-11-02,2016-06-03
-2b7o,2005-10-18,2005-10-05
-2b7p,2006-02-14,2005-10-05
-5b7v,2016-06-22,2016-06-09
-7b7r,2021-03-03,2020-12-11
-6b7b,2017-12-27,2017-10-03
-5b7b,2016-07-06,2016-06-06
-2b77,2005-10-11,2005-10-03
-4b7m,2012-10-03,2012-08-21
-6b7q,2018-04-18,2017-10-04
-4b77,2013-06-26,2012-08-16
-5b7c,2016-08-03,2016-06-07
-5b7q,2016-12-14,2016-06-08
-1b7x,1999-03-02,1999-01-25
-3b7t,2008-09-16,2007-10-31
-1b7z,1999-02-02,1999-01-26
-4b7u,2012-10-10,2012-08-22
-7b7t,2022-01-12,2020-12-11
-2b7y,2005-10-18,2005-10-05
-8b77,2023-10-25,2022-09-29
-4b7s,2013-08-28,2012-08-21
-3b7k,2007-11-13,2007-10-31
-7b7v,2021-05-19,2020-12-11
-5b7f,2016-10-19,2016-06-07
-1b7h,1998-11-25,1998-11-16
-9b7f,2024-04-10,2024-03-27
-6b7e,2017-12-27,2017-10-03
-1sk2,2005-02-15,2004-03-04
-8skf,2023-04-26,2023-04-19
-5skt,2022-10-12,2022-02-01
-3sk5,2011-07-06,2011-06-22
-1skj,1998-02-25,1997-09-18
-1skw,2004-07-06,2004-03-05
-6skc,2019-09-25,2019-08-15
-8sko,2023-08-23,2023-04-20
-1skr,2004-07-06,2004-03-05
-3skq,2011-07-27,2011-06-23
-1sk8,2005-02-08,2004-03-04
-6sku,2020-06-10,2019-08-16
-5skw,2022-03-16,2022-03-03
-6sk2,2020-03-18,2019-08-14
-5skj,2022-10-12,2022-02-01
-8sku,2023-10-25,2023-04-20
-5skz,2022-03-16,2022-03-03
-7skh,2022-10-26,2021-10-20
-6skp,2019-09-18,2019-08-16
-6skl,2020-05-06,2019-08-16
-1sk3,2004-07-13,2004-03-04
-5ske,2022-10-12,2022-02-01
-1ska,2004-09-28,2004-03-04
-6sk9,2020-06-17,2019-08-15
-6sk3,2020-03-18,2019-08-14
-3skf,2011-08-31,2011-06-22
-6skv,2020-08-26,2019-08-16
-6skq,2019-09-18,2019-08-16
-8skb,2024-03-13,2023-04-19
-7ski,2022-04-13,2021-10-20
-5sk7,2022-10-12,2022-02-01
-3sko,2012-02-29,2011-06-22
-8skj,2023-11-22,2023-04-19
-3skh,2011-08-31,2011-06-22
-7sk4,2022-07-27,2021-10-19
-8sk7,2023-06-14,2023-04-18
-1sk1,2005-02-15,2004-03-04
-7skg,2023-01-11,2021-10-20
-8skp,2023-08-23,2023-04-20
-5skf,2022-10-12,2022-02-01
-1sk4,2004-07-13,2004-03-04
-5sk9,2022-10-12,2022-02-01
-6skj,2020-03-18,2019-08-15
-3skd,2011-07-20,2011-06-22
-8skr,2024-02-21,2023-04-20
-7sky,2022-04-13,2021-10-21
-5skb,2022-10-12,2022-02-01
-4skn,1999-02-26,1999-02-20
-5sk3,2022-10-12,2022-02-01
-7skf,2023-01-11,2021-10-20
-5skh,2022-10-12,2022-02-01
-7sk3,2022-07-27,2021-10-19
-1sk0,2005-03-15,2004-03-04
-3sk2,2011-08-31,2011-06-22
-8skl,2023-08-02,2023-04-20
-6skf,2020-07-29,2019-08-15
-5skx,2022-03-16,2022-03-03
-3skg,2011-09-07,2011-06-22
-6ska,2020-02-12,2019-08-15
-7sk9,2022-07-27,2021-10-19
-3skk,2011-07-20,2011-06-22
-3sks,2011-07-06,2011-06-23
-3ske,2011-08-31,2011-06-22
-7sk1,2021-11-24,2021-10-19
-3skc,2011-08-17,2011-06-22
-6skg,2020-07-29,2019-08-15
-6ske,2020-02-12,2019-08-15
-5skg,2022-10-12,2022-02-01
-7sk0,2021-11-24,2021-10-19
-1skx,2005-03-08,2004-03-05
-7ska,2022-03-09,2021-10-20
-2ske,1998-12-16,1998-12-11
-6skd,2019-09-25,2019-08-15
-7skr,2022-03-02,2021-10-21
-1skb,2004-09-28,2004-03-04
-5skd,2022-10-12,2022-02-01
-5skl,2022-10-12,2022-02-01
-7ske,2023-01-11,2021-10-20
-5skv,2022-10-12,2022-02-01
-3ska,2011-08-31,2011-06-22
-3sk6,2011-07-06,2011-06-22
-1sks,2004-07-06,2004-03-05
-1sk7,2004-06-22,2004-03-04
-7sku,2022-08-24,2021-10-21
-5sk6,2022-10-12,2022-02-01
-6sky,2019-10-30,2019-08-16
-5sku,2022-10-12,2022-02-01
-7skx,2022-06-08,2021-10-21
-6sk4,2019-09-25,2019-08-14
-6sk5,2019-09-04,2019-08-14
-5sks,2022-10-12,2022-02-01
-7skq,2022-03-02,2021-10-21
-7sko,2022-10-12,2021-10-21
-5skr,2022-10-12,2022-02-01
-5sky,2022-03-16,2022-03-03
-8skh,2023-06-07,2023-04-19
-3sk4,2011-07-06,2011-06-22
-8skn,2023-08-30,2023-04-20
-5sko,2022-10-12,2022-02-01
-8skt,2024-04-24,2023-04-20
-1sku,2004-03-30,2004-03-05
-8sks,2024-02-21,2023-04-20
-8skv,2023-10-25,2023-04-20
-6sk1,2020-01-29,2019-08-14
-7skd,2023-01-11,2021-10-20
-6skt,2020-08-26,2019-08-16
-5skp,2022-10-12,2022-02-01
-5ska,2022-10-12,2022-02-01
-5sk1,2022-10-12,2022-02-01
-7sk7,2022-07-27,2021-10-19
-3skm,2012-02-29,2011-06-22
-6skz,2019-10-30,2019-08-16
-1sk6,2004-06-08,2004-03-04
-5skq,2022-10-12,2022-02-01
-1sk9,2004-09-28,2004-03-04
-8sk4,2023-06-07,2023-04-18
-8ski,2023-09-20,2023-04-19
-5skm,2022-10-12,2022-02-01
-7sk2,2022-06-08,2021-10-19
-5sk5,2022-10-12,2022-02-01
-8sk0,2023-08-09,2023-04-18
-6sk8,2020-03-18,2019-08-14
-5sk0,2022-10-12,2022-02-01
-6skb,2019-09-25,2019-08-15
-7skm,2022-01-26,2021-10-21
-8sk5,2023-08-16,2023-04-18
-1skm,2004-08-24,2004-03-05
-5sk2,2022-10-12,2022-02-01
-8sk2,2023-08-23,2023-04-18
-5skn,2022-10-12,2022-02-01
-5sk8,2022-10-12,2022-02-01
-1skq,2004-07-20,2004-03-05
-7sk5,2022-07-27,2021-10-19
-5skk,2022-10-12,2022-02-01
-5ski,2022-10-12,2022-02-01
-7sk8,2022-07-27,2021-10-19
-7skk,2022-04-13,2021-10-21
-2skd,1998-12-16,1998-12-11
-3sku,2011-10-12,2011-06-23
-5skc,2022-10-12,2022-02-01
-5sk4,2022-10-12,2022-02-01
-6skh,2020-08-26,2019-08-15
-6sks,2020-08-26,2019-08-16
-1skg,2004-04-27,2004-03-04
-8sky,2023-11-01,2023-04-20
-6sko,2020-05-06,2019-08-16
-6skr,2019-09-18,2019-08-16
-2skc,1998-12-16,1998-12-11
-7skl,2022-01-26,2021-10-21
-5fnf,2016-11-23,2015-11-13
-8fnh,2023-08-09,2022-12-27
-4fni,2012-08-22,2012-06-19
-3fnm,2009-05-19,2008-12-25
-2fnn,2006-11-28,2006-01-11
-5fnm,2016-03-02,2015-11-15
-8fnj,2023-08-09,2022-12-27
-2fn0,2006-02-14,2006-01-10
-8fnw,2023-02-01,2022-12-28
-6fnd,2018-11-14,2018-02-02
-2fnk,2006-11-28,2006-01-11
-7fn9,2022-11-02,2022-08-26
-5fni,2016-03-02,2015-11-15
-4fn4,2012-08-15,2012-06-19
-7fne,2022-11-02,2022-08-26
-6fn8,2019-01-30,2018-02-02
-5fn6,2016-03-23,2015-11-10
-6fnh,2018-08-08,2018-02-04
-2fni,2006-01-24,2006-01-11
-7fnn,2022-11-02,2022-08-26
-7fnz,2022-11-02,2022-08-26
-1fng,2001-03-07,2000-08-21
-4fnh,2012-08-22,2012-06-19
-3fn0,2009-06-23,2008-12-22
-5fnp,2016-04-27,2015-11-16
-8fn9,2023-07-12,2022-12-27
-5fns,2016-04-13,2015-11-16
-7fnc,2022-11-02,2022-08-26
-7fnb,2022-11-02,2022-08-26
-2fn3,2006-12-19,2006-01-10
-3fnt,2009-05-12,2008-12-26
-4fn5,2012-09-26,2012-06-19
-1fnv,2000-11-17,2000-08-23
-4fnc,2012-09-19,2012-06-19
-1fnt,2001-04-11,2000-08-23
-5fne,2016-07-13,2015-11-13
-4fnm,2013-12-04,2012-06-20
-7fn5,2022-11-02,2022-08-26
-7fnx,2022-11-02,2022-08-26
-6fnt,2018-06-13,2018-02-05
-6fn1,2018-02-21,2018-02-02
-6fnx,2018-06-20,2018-02-05
-6fn0,2018-08-01,2018-02-02
-6fny,2018-02-28,2018-02-05
-1fnq,2001-04-18,2000-08-23
-6fnn,2018-07-25,2018-02-04
-7fnt,2022-11-02,2022-08-26
-1fny,2001-08-24,2000-08-24
-4fnb,2013-05-29,2012-06-19
-5fnu,2016-04-13,2015-11-16
-7fni,2022-11-02,2022-08-26
-7fnl,2022-11-02,2022-08-26
-8fnv,2023-02-01,2022-12-28
-6fnb,2018-07-04,2018-02-02
-8fn2,2023-11-08,2022-12-26
-2fn4,2006-01-31,2006-01-10
-7fnv,2022-11-02,2022-08-26
-3fnq,2009-02-24,2008-12-26
-5fn1,2015-12-30,2015-11-10
-5fnq,2016-04-13,2015-11-16
-6fnq,2018-06-13,2018-02-05
-6fnr,2018-06-13,2018-02-05
-8fn3,2023-05-03,2022-12-26
-6fns,2018-06-13,2018-02-05
-5fn8,2016-03-23,2015-11-11
-2fnw,2006-10-03,2006-01-11
-5fnh,2016-03-02,2015-11-15
-5fno,2016-01-27,2015-11-16
-8fns,2023-06-07,2022-12-28
-5fnj,2016-03-02,2015-11-15
-8fna,2023-07-12,2022-12-27
-7fnw,2022-11-02,2022-08-26
-6fno,2018-07-25,2018-02-04
-1fnz,2001-08-24,2000-08-24
-4fnu,2012-10-03,2012-06-20
-2fn7,2007-01-23,2006-01-10
-1fnc,1995-04-20,1995-01-05
-8fnr,2023-06-07,2022-12-28
-1fn3,2003-10-07,2000-08-20
-6fnm,2018-08-08,2018-02-04
-1fnn,2000-10-04,2000-08-22
-2fnq,2006-02-28,2006-01-11
-2fnu,2006-01-24,2006-01-11
-1fni,2000-09-13,2000-08-22
-2fn8,2007-01-16,2006-01-10
-7fnh,2022-11-02,2022-08-26
-8fnn,2023-08-09,2022-12-27
-7fn8,2022-11-02,2022-08-26
-8fn8,2023-07-12,2022-12-27
-2fn1,2006-02-14,2006-01-10
-4fnt,2012-10-03,2012-06-20
-8fnq,2023-08-09,2022-12-28
-5fnb,2016-07-13,2015-11-13
-7fna,2022-11-02,2022-08-26
-7fn6,2022-11-02,2022-08-26
-5fng,2016-03-02,2015-11-15
-5fny,2016-04-27,2015-11-17
-8fny,2023-05-03,2022-12-28
-3fnu,2009-05-12,2008-12-26
-5fnc,2016-11-23,2015-11-13
-4fn8,2013-05-29,2012-06-19
-8fng,2023-08-09,2022-12-27
-3fnf,2009-01-20,2008-12-24
-3fna,2009-01-27,2008-12-23
-6fna,2018-07-04,2018-02-02
-7fnu,2022-11-02,2022-08-26
-5fnr,2016-04-13,2015-11-16
-5fnv,2016-05-18,2015-11-16
-6fni,2018-08-08,2018-02-04
-1fnd,1995-04-20,1995-01-05
-3fn8,2009-03-03,2008-12-23
-1fnw,2000-11-17,2000-08-23
-8fn1,2023-03-29,2022-12-26
-5fnn,2016-04-27,2015-11-16
-6fnf,2018-08-08,2018-02-04
-4fn2,2012-08-01,2012-06-19
-2fnc,2007-01-16,2006-01-10
-2fnf,2006-02-07,2006-01-11
-5fn0,2016-01-13,2015-11-10
-6fn4,2018-02-21,2018-02-02
-1fn6,2000-09-13,2000-08-21
-6fnk,2018-08-08,2018-02-04
-7fn7,2022-11-02,2022-08-26
-7fn3,2022-11-02,2022-08-26
-6fnc,2018-07-04,2018-02-02
-6fn2,2018-08-01,2018-02-02
-8fnz,2023-06-28,2022-12-29
-1fno,2002-03-13,2000-08-22
-8fn7,2023-08-09,2022-12-27
-7fn0,2022-11-02,2022-08-26
-8fnd,2023-08-09,2022-12-27
-7fnr,2022-11-02,2022-08-26
-6fnz,2018-04-04,2018-02-05
-2fn2,1998-09-16,1997-08-06
-6fn5,2019-03-13,2018-02-02
-3fnk,2009-06-23,2008-12-25
-7fnm,2022-11-02,2022-08-26
-8fnl,2023-08-09,2022-12-27
-6fnj,2018-08-08,2018-02-04
-1fne,2001-03-07,2000-08-21
-7fnd,2022-11-02,2022-08-26
-1fnl,2000-11-22,2000-08-22
-7fn4,2022-11-02,2022-08-26
-1fn9,2001-03-14,2000-08-21
-1fnu,2000-11-17,2000-08-23
-3fnl,2009-01-27,2008-12-25
-2fna,2006-02-07,2006-01-10
-7fng,2022-11-02,2022-08-26
-5fnt,2016-04-13,2015-11-16
-7fnq,2022-11-02,2022-08-26
-4fnk,2012-09-19,2012-06-19
-2fnx,2006-01-24,2006-01-11
-8fn6,2023-07-19,2022-12-27
-8fno,2023-08-09,2022-12-28
-4fns,2012-10-03,2012-06-20
-4fnz,2012-08-29,2012-06-20
-7fns,2022-11-02,2022-08-26
-6fnu,2018-03-07,2018-02-05
-5fnd,2016-11-23,2015-11-13
-3fnh,2009-01-20,2008-12-24
-4fny,2012-08-29,2012-06-20
-4fn0,2012-08-22,2012-06-18
-2fnm,2006-11-28,2006-01-11
-3fng,2009-01-20,2008-12-24
-7fn1,2022-11-02,2022-08-26
-7fno,2022-11-02,2022-08-26
-7fnp,2022-11-02,2022-08-26
-8fnp,2023-08-09,2022-12-28
-7fn2,2022-11-02,2022-08-26
-3fne,2009-01-20,2008-12-24
-2fnt,2006-09-05,2006-01-11
-4fn9,2012-12-26,2012-06-19
-6fn9,2018-07-04,2018-02-02
-4fne,2012-12-12,2012-06-19
-2fns,2006-09-05,2006-01-11
-5fn7,2016-03-23,2015-11-10
-7fny,2022-11-02,2022-08-26
-1fnb,1995-04-20,1995-01-05
-8fn0,2023-03-29,2022-12-26
-5fnk,2016-03-02,2015-11-15
-7fnj,2022-11-02,2022-08-26
-7fnf,2022-11-02,2022-08-26
-7fnk,2022-11-02,2022-08-26
-3fnn,2009-12-29,2008-12-26
-1fnp,2001-04-18,2000-08-23
-6fne,2019-03-13,2018-02-03
-3fnb,2009-01-06,2008-12-23
-3fns,2009-05-12,2008-12-26
-1fn8,2001-02-07,2000-08-21
-5fnl,2016-09-28,2015-11-15
-6fn3,2018-08-01,2018-02-02
-6fng,2018-08-08,2018-02-04
-8fnm,2023-08-09,2022-12-27
-1fn7,2001-04-21,2000-08-21
-3fn2,2009-01-27,2008-12-23
-1fnm,2000-11-22,2000-08-22
-8fnb,2023-07-12,2022-12-27
-3qrt,2012-08-08,2011-02-18
-8qrg,2024-05-08,2023-10-07
-4qr5,2015-07-01,2014-06-30
-6qrz,2019-04-24,2019-02-20
-4qru,2015-02-04,2014-07-02
-6qrb,2020-03-18,2019-02-19
-6qre,2019-09-18,2019-02-19
-4qrh,2015-02-25,2014-07-01
-1qrv,1999-12-18,1999-06-15
-2qrk,2007-10-30,2007-07-28
-3qr7,2012-02-22,2011-02-17
-6qrj,2020-01-08,2019-02-19
-6qr1,2019-09-18,2019-02-19
-4qrt,2014-07-16,2014-07-02
-5qrm,2019-07-10,2019-05-25
-1qr7,1999-08-31,1999-06-18
-8qrt,2024-02-21,2023-10-09
-5qre,2019-08-07,2019-05-22
-5qrp,2019-07-10,2019-05-25
-1qre,1999-06-25,1999-06-13
-6qrs,2019-07-17,2019-02-19
-4qrf,2014-11-26,2014-06-30
-1qr1,2000-01-01,1999-06-17
-3qr3,2011-11-02,2011-02-16
-5qr4,2019-08-07,2019-05-22
-3qrj,2011-06-01,2011-02-18
-4qrg,2015-08-05,2014-07-01
-2qrh,2008-08-05,2007-07-28
-1qrl,1999-06-25,1999-06-15
-5qrg,2019-07-10,2019-05-25
-8qre,2024-05-15,2023-10-06
-2qr8,2007-12-11,2007-07-27
-5qrj,2019-07-10,2019-05-25
-8qrh,2024-06-05,2023-10-07
-2qr9,2008-03-18,2007-07-27
-3qru,2012-08-08,2011-02-18
-6qri,2019-07-03,2019-02-19
-1qrr,1999-11-10,1999-06-15
-1qrq,1999-10-27,1999-06-15
-4qrz,2014-07-16,2014-07-02
-3qrh,2011-03-23,2011-02-17
-7qrm,2023-01-25,2022-01-11
-7qr9,2023-01-18,2022-01-10
-7qr1,2022-10-26,2022-01-10
-6qr6,2020-03-18,2019-02-19
-3qrk,2011-06-01,2011-02-18
-2qrz,2008-03-18,2007-07-30
-3qro,2012-02-22,2011-02-18
-5qrb,2019-08-07,2019-05-22
-5qrw,2019-07-10,2019-05-25
-6qr7,2019-09-18,2019-02-19
-1qrm,1999-06-25,1999-06-15
-5qrf,2019-07-10,2019-05-25
-4qrb,2015-12-23,2014-06-30
-6qr9,2019-09-18,2019-02-19
-1qrf,1999-06-25,1999-06-13
-4qrr,2014-12-10,2014-07-02
-4qro,2014-08-06,2014-07-01
-7qr6,2022-08-10,2022-01-10
-7qr5,2022-10-26,2022-01-17
-2qra,2007-09-18,2007-07-27
-6qro,2019-03-06,2019-02-19
-4qrs,2014-12-10,2014-07-02
-4qrq,2014-11-12,2014-07-02
-2qr2,1999-08-18,1999-04-19
-6qrl,2020-01-08,2019-02-19
-5qr6,2019-08-07,2019-05-22
-4qry,2015-06-17,2014-07-02
-4qrk,2014-07-23,2014-07-01
-5qrs,2019-07-10,2019-05-25
-5qrd,2019-08-07,2019-05-22
-5qra,2019-08-07,2019-05-22
-1qru,1996-12-07,1996-06-14
-7qr3,2022-10-26,2022-01-10
-4qrc,2014-10-29,2014-06-30
-7qrs,2022-09-07,2022-01-12
-6qrf,2019-09-18,2019-02-19
-4qr4,2015-07-01,2014-06-30
-5qr9,2019-08-07,2019-05-22
-1qrt,1996-12-07,1996-06-14
-5qr5,2019-08-07,2019-05-22
-4qrn,2014-08-06,2014-07-01
-3qrb,2011-05-18,2011-02-17
-2qry,2008-02-05,2007-07-30
-3qr0,2011-08-10,2011-02-16
-6qru,2019-07-17,2019-02-19
-6qrx,2019-07-17,2019-02-19
-7qr7,2022-10-26,2022-01-10
-2qre,2007-10-23,2007-07-28
-2qrv,2007-12-04,2007-07-29
-4qr8,2015-02-25,2014-06-30
-7qrt,2022-09-07,2022-01-12
-6qr5,2020-03-18,2019-02-19
-2qrd,2007-10-23,2007-07-28
-6qrv,2019-07-17,2019-02-19
-3qrx,2011-10-26,2011-02-18
-1qrp,1999-06-18,1999-06-15
-5qrk,2019-07-10,2019-05-25
-5qro,2019-07-10,2019-05-25
-6qrn,2019-06-05,2019-02-19
-3qrf,2011-04-20,2011-02-17
-1qr0,1999-12-10,1999-06-17
-5qrv,2019-07-10,2019-05-25
-6qrc,2019-09-18,2019-02-19
-5qrh,2019-07-10,2019-05-25
-3qr1,2011-08-10,2011-02-16
-6qrd,2019-09-18,2019-02-19
-4qrd,2015-07-29,2014-06-30
-6qrw,2019-07-17,2019-02-19
-1qrs,1996-12-07,1996-06-14
-7qrk,2023-01-25,2022-01-11
-5qr3,2019-08-07,2019-05-22
-5qrz,2019-07-10,2019-05-25
-5qry,2019-07-10,2019-05-25
-6qrr,2019-07-17,2019-02-19
-5qrr,2019-07-10,2019-05-25
-5qr8,2019-08-07,2019-05-22
-5qrl,2019-07-10,2019-05-25
-7qra,2023-01-18,2022-01-10
-3qry,2011-03-09,2011-02-18
-2qrp,2008-07-29,2007-07-28
-7qr8,2022-10-26,2022-01-10
-3qrp,2011-05-25,2011-02-18
-3qre,2011-03-02,2011-02-17
-4qrv,2015-08-12,2014-07-02
-6qry,2019-07-17,2019-02-19
-2qrb,2007-08-14,2007-07-28
-6qrm,2020-03-18,2019-02-19
-1qr3,2000-06-21,1999-06-18
-6qrt,2019-07-17,2019-02-19
-2qr1,2007-10-23,2007-07-27
-6qr3,2019-09-18,2019-02-19
-1qr2,1999-08-18,1999-04-15
-8qrf,2024-05-08,2023-10-06
-7qri,2023-05-03,2022-01-11
-2qrg,2008-08-05,2007-07-28
-2qro,2007-12-11,2007-07-28
-6qr0,2019-09-18,2019-02-19
-6qrg,2019-09-18,2019-02-19
-5qru,2019-07-10,2019-05-25
-5qr7,2019-08-07,2019-05-22
-4qra,2015-12-23,2014-06-30
-5qrx,2019-07-10,2019-05-25
-7qrc,2022-11-23,2022-01-10
-4qrp,2014-11-12,2014-07-02
-2qrc,2007-10-23,2007-07-28
-5qrq,2019-07-10,2019-05-25
-6qr8,2020-03-18,2019-02-19
-5qrt,2019-07-10,2019-05-25
-5qr2,2019-08-07,2019-05-22
-4qre,2015-07-29,2014-06-30
-1qrd,1996-10-14,1995-07-28
-1qrg,1999-06-25,1999-06-13
-5qr1,2019-08-07,2019-05-22
-2qrq,2008-07-29,2007-07-28
-2qr7,2007-12-11,2007-07-27
-7qrb,2023-01-18,2022-01-10
-1qrn,1999-10-14,1999-06-14
-6qr2,2019-09-18,2019-02-19
-2qrn,2007-12-11,2007-07-28
-4qr7,2015-07-29,2014-06-30
-5qrc,2019-08-07,2019-05-22
-2qrm,2008-07-29,2007-07-28
-5qrn,2019-07-10,2019-05-25
-4qr3,2015-07-01,2014-06-30
-3qrs,2012-02-22,2011-02-18
-2qrf,2009-04-21,2007-07-28
-4qr6,2015-08-12,2014-06-30
-1qr6,1999-07-05,1999-06-18
-3qri,2011-06-01,2011-02-18
-2qrw,2007-11-06,2007-07-30
-5qri,2019-07-10,2019-05-25
-6qr4,2019-09-18,2019-02-19
-6qra,2019-09-18,2019-02-19
-5qr0,2019-08-07,2019-05-22
-3qrm,2012-02-22,2011-02-18
-7qrd,2022-12-28,2022-01-11
-3qrw,2011-05-25,2011-02-18
-1qrk,1999-07-02,1999-06-14
-7qr0,2022-10-26,2022-01-10
-1qra,1999-11-05,1999-06-12
-4nff,2014-10-29,2013-10-31
-1nfp,1995-06-03,1995-02-27
-4nfn,2014-02-05,2013-10-31
-5nfs,2018-05-16,2017-03-15
-5nfk,2018-10-10,2017-03-14
-3nfl,2011-08-24,2010-06-10
-7nfd,2021-04-21,2021-02-06
-4nfv,2014-05-28,2013-11-01
-7nf6,2022-01-19,2021-02-05
-5nfx,2018-04-18,2017-03-16
-7nf2,2021-08-04,2021-02-05
-1nfd,1998-01-28,1997-08-04
-7nfb,2021-08-25,2021-02-05
-5nf6,2017-07-26,2017-03-13
-4nf2,2013-11-13,2013-10-30
-5nfg,2017-10-11,2017-03-14
-1nfb,2004-01-27,2002-12-13
-4nfz,2013-12-18,2013-11-01
-3nf8,2011-04-27,2010-06-09
-1nfz,2003-06-24,2002-12-16
-5nfm,2018-10-10,2017-03-14
-5nfu,2018-05-16,2017-03-16
-7nfv,2021-02-24,2021-02-07
-6nfi,2019-03-13,2018-12-20
-4nf6,2014-03-12,2013-10-30
-5nfh,2017-10-11,2017-03-14
-1nft,1999-01-13,1999-01-07
-3nfd,2011-01-05,2010-06-10
-3nfm,2010-06-30,2010-06-10
-6nfo,2019-01-23,2018-12-20
-6nfv,2019-08-07,2018-12-20
-4nfl,2014-09-10,2013-10-31
-4nfr,2014-07-30,2013-10-31
-7nf0,2021-08-04,2021-02-05
-1nf7,2004-01-27,2002-12-13
-1nff,2002-12-30,2002-12-14
-5nft,2017-10-04,2017-03-15
-6nfc,2019-11-06,2018-12-19
-4nfu,2013-12-11,2013-11-01
-3nf3,2010-07-21,2010-06-09
-6nfx,2019-01-30,2018-12-21
-1nfw,2003-02-25,2002-12-16
-7nf5,2021-04-07,2021-02-05
-7nf9,2021-12-29,2021-02-05
-1nf6,2003-04-01,2002-12-13
-4nf9,2014-03-19,2013-10-31
-4nfs,2013-11-13,2013-10-31
-5nfj,2018-05-16,2017-03-14
-3nf7,2011-04-27,2010-06-09
-1nfr,2002-12-30,2002-12-16
-1nf4,2003-04-01,2002-12-13
-7nf7,2022-01-19,2021-02-05
-6nfu,2019-08-07,2018-12-20
-5nfo,2018-03-14,2017-03-14
-6nfe,2019-01-02,2018-12-19
-4nfi,2014-12-31,2013-10-31
-4nfk,2014-12-31,2013-10-31
-3nfe,2010-07-07,2010-06-10
-1nf5,2002-12-25,2002-12-13
-7nf1,2021-08-04,2021-02-05
-6nf1,2019-12-25,2018-12-18
-6nfy,2019-05-01,2018-12-21
-1nfq,2002-12-30,2002-12-15
-4nfh,2013-11-13,2013-10-31
-1nfu,2003-02-25,2002-12-16
-7nf3,2021-08-04,2021-02-05
-6nfa,2019-12-25,2018-12-19
-3nfa,2011-04-27,2010-06-10
-5nfp,2017-10-04,2017-03-15
-7nf8,2022-01-19,2021-02-05
-6nf2,2019-07-24,2018-12-18
-5nfz,2017-10-25,2017-03-16
-6nft,2019-01-02,2018-12-20
-3nf4,2010-06-23,2010-06-09
-6nfq,2019-04-24,2018-12-20
-3nf6,2011-04-27,2010-06-09
-5nf7,2017-06-21,2017-03-13
-3nfr,2012-01-11,2010-06-10
-5nf2,2018-02-07,2017-03-13
-6nf6,2019-06-05,2018-12-18
-4nfw,2014-05-14,2013-11-01
-6nfh,2019-03-13,2018-12-20
-5nfa,2017-06-21,2017-03-13
-6nf5,2019-11-06,2018-12-18
-1nfs,2003-06-24,2002-12-16
-3nfu,2010-06-23,2010-06-10
-5nfb,2017-06-21,2017-03-13
-5nfl,2018-10-10,2017-03-14
-6nfn,2019-11-20,2018-12-20
-1nfx,2003-02-25,2002-12-16
-3nfk,2011-08-24,2010-06-10
-5nff,2017-04-19,2017-03-14
-6nfp,2019-01-02,2018-12-20
-1nf8,2003-06-17,2002-12-13
-4nfd,2014-05-28,2013-10-31
-6nf7,2019-12-25,2018-12-19
-1nfv,2003-04-01,2002-12-16
-4nfj,2014-12-31,2013-10-31
-6nfz,2019-05-01,2018-12-21
-5nf5,2017-07-26,2017-03-13
-3nfz,2010-10-20,2010-06-10
-7nfy,2021-02-24,2021-02-08
-6nff,2019-10-02,2018-12-20
-1nfg,2003-07-15,2002-12-14
-4nf8,2014-03-12,2013-10-30
-5nfn,2018-03-14,2017-03-14
-3nfb,2011-09-28,2010-06-10
-6nf4,2019-06-05,2018-12-18
-5nf9,2017-06-21,2017-03-13
-6nfg,2019-01-23,2018-12-20
-1nfy,2003-02-25,2002-12-16
-6nfl,2019-12-25,2018-12-20
-5nfy,2018-01-10,2017-03-16
-5nf3,2018-02-07,2017-03-13
-1nf2,2003-09-16,2002-12-12
-7nfx,2021-06-02,2021-02-08
-4nf4,2014-03-12,2013-10-30
-5nf0,2017-09-13,2017-03-13
-4nf5,2014-03-12,2013-10-30
-5nfv,2017-06-14,2017-03-16
-4nf1,2014-11-12,2013-10-30
-6nf0,2019-05-01,2018-12-18
-3nf9,2011-04-27,2010-06-10
-7nfw,2021-02-17,2021-02-08
-1nf3,2003-03-04,2002-12-12
-7nf4,2021-08-04,2021-02-05
-7nfz,2022-03-02,2021-02-08
-2pda,1999-04-23,1998-11-10
-3pd2,2010-12-08,2010-10-22
-6pdn,2019-07-24,2019-06-19
-6pdy,2020-02-12,2019-06-19
-2pdr,2007-06-05,2007-04-01
-6pdu,2020-06-24,2019-06-19
-1pd9,2003-12-09,2003-05-19
-6pd8,2020-04-01,2019-06-18
-4pdn,2015-03-04,2014-04-19
-8pdu,2023-11-08,2023-06-12
-7pd5,2023-02-15,2021-08-04
-8pd1,2024-01-10,2023-06-11
-4pdg,2015-04-01,2014-04-18
-3pdv,2011-09-07,2010-10-25
-7pdf,2022-01-26,2021-08-05
-4pdm,2014-07-09,2014-04-19
-2pdh,2008-04-01,2007-03-31
-3pdn,2010-11-17,2010-10-23
-4pd8,2014-08-13,2014-04-17
-3pdg,2011-11-23,2010-10-22
-6pdv,2020-03-11,2019-06-19
-8pdd,2024-01-31,2023-06-12
-6pd6,2019-11-13,2019-06-18
-4pd5,2014-08-13,2014-04-17
-3pdf,2011-10-26,2010-10-22
-8pdp,2023-12-06,2023-06-12
-4pd7,2014-08-13,2014-04-17
-8pdy,2024-04-24,2023-06-13
-3pdu,2012-01-11,2010-10-25
-6pdt,2020-03-11,2019-06-19
-4pdy,2014-05-07,2014-04-22
-6pdh,2020-05-06,2019-06-19
-4pda,2014-08-13,2014-04-17
-6pde,2020-04-01,2019-06-18
-2pdf,2008-04-01,2007-03-31
-7pd3,2021-11-17,2021-08-04
-6pdi,2019-07-24,2019-06-19
-8pdf,2023-11-15,2023-06-12
-7pda,2022-08-24,2021-08-05
-8pdq,2023-12-06,2023-06-12
-6pdq,2019-11-13,2019-06-19
-2pdn,2008-04-01,2007-04-01
-7pdb,2022-02-02,2021-08-05
-3pdh,2011-01-19,2010-10-22
-3pdm,2011-01-12,2010-10-22
-2pdl,2008-04-01,2007-04-01
-6pd4,2019-11-27,2019-06-18
-2pd5,2008-04-01,2007-03-31
-6pdb,2020-04-01,2019-06-18
-2pdq,2008-04-01,2007-04-01
-2pd9,2008-04-01,2007-03-31
-1pdt,1996-10-14,1996-03-28
-2pd6,2007-05-08,2007-03-31
-3pd0,2011-02-16,2010-10-22
-2pd4,2007-04-17,2007-03-31
-3pd9,2010-12-29,2010-10-22
-4pdi,2015-04-01,2014-04-18
-6pdo,2019-07-24,2019-06-19
-7pd2,2022-05-11,2021-08-04
-7pdz,2021-09-01,2021-08-09
-7pdy,2022-08-24,2021-08-09
-3pdj,2011-10-05,2010-10-22
-1pd0,2003-08-19,2003-05-18
-4pdv,2014-07-09,2014-04-22
-1pdq,2003-08-26,2003-05-20
-6pdr,2020-06-24,2019-06-19
-2pdm,2008-04-01,2007-04-01
-3pdc,2011-04-06,2010-10-22
-3pd4,2010-12-08,2010-10-22
-4pds,2014-05-28,2014-04-21
-3pds,2011-01-12,2010-10-24
-8pdh,2023-06-28,2023-06-12
-8pd9,2023-11-08,2023-06-12
-6pdf,2020-04-01,2019-06-18
-7pde,2022-01-19,2021-08-05
-7pdv,2022-08-24,2021-08-08
-8pde,2024-04-17,2023-06-12
-6pdp,2019-07-24,2019-06-19
-4pdh,2014-05-14,2014-04-18
-2pdx,2008-04-01,2007-04-01
-2pdw,2008-04-01,2007-04-01
-3pd8,2010-12-29,2010-10-22
-3pd1,2011-02-23,2010-10-22
-6pdd,2020-04-01,2019-06-18
-6pdz,2020-03-04,2019-06-19
-3pdd,2011-11-23,2010-10-22
-2pdg,2008-04-01,2007-03-31
-8pdr,2023-12-06,2023-06-12
-6pd2,2019-08-07,2019-06-18
-7pdq,2022-08-03,2021-08-06
-6pds,2020-06-24,2019-06-19
-3pd3,2010-12-08,2010-10-22
-6pdx,2019-12-18,2019-06-19
-7pdw,2022-08-03,2021-08-09
-4pdz,2014-10-15,2014-04-22
-1pd2,1999-10-13,1998-12-14
-4pd9,2014-08-13,2014-04-17
-7pds,2022-07-13,2021-08-06
-6pd0,2020-03-18,2019-06-18
-2pdc,2008-04-01,2007-03-31
-3pd6,2010-11-10,2010-10-22
-2pdu,2008-04-01,2007-04-01
-8pdm,2023-12-06,2023-06-12
-8pdg,2023-06-28,2023-06-12
-7pd7,2022-08-17,2021-08-04
-7pdt,2022-08-03,2021-08-07
-4pdr,2014-07-09,2014-04-21
-2pdk,2008-04-01,2007-04-01
-7pd9,2021-10-13,2021-08-04
-2pdp,2008-04-01,2007-04-01
-3pdb,2010-11-10,2010-10-22
-6pd9,2020-04-01,2019-06-18
-2pdz,1998-12-30,1997-12-10
-1pd1,2003-08-19,2003-05-18
-7pdr,2022-02-02,2021-08-06
-1pdh,1995-03-31,1994-12-01
-4pdw,2014-07-02,2014-04-22
-2pdi,2008-04-01,2007-04-01
-1pdz,1995-11-14,1995-06-05
-6pdc,2020-04-01,2019-06-18
-8pdn,2023-12-06,2023-06-12
-4pde,2015-05-20,2014-04-18
-7pd1,2022-05-11,2021-08-04
-8pdj,2023-06-28,2023-06-12
-1pd8,2003-12-09,2003-05-19
-2pdy,2008-04-01,2007-04-01
-2pd8,2007-06-05,2007-03-31
-4pdl,2014-07-09,2014-04-19
-7pdo,2023-02-15,2021-08-05
-6pdg,2020-04-01,2019-06-18
-7pd6,2022-02-02,2021-08-04
-6pd1,2019-08-07,2019-06-18
-4pdj,2015-04-15,2014-04-18
-6pdj,2019-10-09,2019-06-19
-8pdl,2023-12-06,2023-06-12
-4pd6,2014-08-13,2014-04-17
-3pdq,2011-03-30,2010-10-23
-8pd6,2024-01-31,2023-06-11
-6pdl,2019-11-27,2019-06-19
-2pdo,2007-04-24,2007-04-01
-6pd7,2020-05-06,2019-06-18
-2pd3,2007-04-17,2007-03-31
-3pdt,2010-11-10,2010-10-24
-4pdd,2014-05-14,2014-04-18
-8pdt,2023-07-12,2023-06-12
-3pd5,2010-12-08,2010-10-22
-2pdb,2008-04-01,2007-03-31
-6pda,2020-04-01,2019-06-18
-8pdi,2023-07-26,2023-06-12
-3pde,2010-11-17,2010-10-22
-8pds,2023-12-06,2023-06-12
-8pdv,2023-11-08,2023-06-12
-1pda,1993-10-31,1992-11-17
-6pd3,2019-11-13,2019-06-18
-2pd7,2007-06-05,2007-03-31
-4pd4,2014-06-11,2014-04-17
-6pdw,2020-02-12,2019-06-19
-8pd8,2023-11-08,2023-06-12
-6pd5,2019-11-13,2019-06-18
-4pd2,2015-04-01,2014-04-17
-2pdj,2008-04-01,2007-04-01
-3nem,2010-08-04,2010-06-09
-5ne5,2017-03-29,2017-03-09
-6nea,2019-06-12,2018-12-17
-4ned,2013-12-11,2013-10-29
-6nev,2019-08-14,2018-12-18
-4neu,2013-11-20,2013-10-30
-4nec,2014-01-15,2013-10-29
-3nef,2010-06-16,2010-06-08
-1nej,2003-12-16,2002-12-11
-6nec,2019-06-05,2018-12-17
-4neh,2014-01-15,2013-10-29
-3nee,2010-11-24,2010-06-08
-7neg,2021-03-03,2021-02-04
-6nee,2019-01-09,2018-12-17
-3nev,2011-04-13,2010-06-09
-4nez,2014-01-15,2013-10-30
-7neu,2021-04-07,2021-02-04
-5ne3,2017-09-13,2017-03-09
-7neo,2022-02-23,2021-02-04
-3nel,2010-08-04,2010-06-09
-6ne1,2019-05-15,2018-12-15
-6ne7,2019-06-05,2018-12-17
-4nen,2014-01-15,2013-10-29
-5ne1,2017-09-13,2017-03-09
-7nez,2021-04-21,2021-02-05
-1nes,1996-01-29,1995-07-31
-1ne7,2003-09-23,2002-12-10
-3new,2010-12-01,2010-06-09
-3neh,2010-06-30,2010-06-08
-5ney,2017-09-13,2017-03-13
-6nef,2019-07-03,2018-12-17
-5ner,2017-06-21,2017-03-11
-3neg,2010-06-16,2010-06-08
-7nes,2021-06-02,2021-02-04
-1ne6,2004-01-13,2002-12-10
-6nes,2019-08-14,2018-12-18
-7nex,2022-03-02,2021-02-05
-6neh,2019-12-18,2018-12-17
-7nel,2021-08-25,2021-02-04
-1ne9,2004-02-10,2002-12-11
-3ne6,2011-01-26,2010-06-08
-7ne3,2022-03-02,2021-02-03
-5nes,2017-09-13,2017-03-11
-6ne6,2019-12-18,2018-12-17
-7neq,2021-04-21,2021-02-04
-4nej,2014-11-19,2013-10-29
-7ned,2021-02-24,2021-02-03
-6neu,2019-08-14,2018-12-18
-1nex,2003-02-18,2002-12-12
-4neb,2014-05-28,2013-10-29
-7nei,2021-06-23,2021-02-04
-5new,2017-10-04,2017-03-12
-1nep,2003-01-28,2002-12-11
-6nel,2019-05-01,2018-12-17
-7nev,2021-03-03,2021-02-05
-6nem,2019-05-01,2018-12-17
-7nem,2022-03-02,2021-02-04
-1nee,2004-03-09,2002-12-11
-4ner,2014-03-12,2013-10-30
-5neg,2018-03-21,2017-03-10
-4nem,2014-11-19,2013-10-29
-6nez,2019-01-23,2018-12-18
-4nei,2014-01-29,2013-10-29
-5net,2017-06-21,2017-03-11
-5nee,2017-12-06,2017-03-10
-3neo,2010-11-24,2010-06-09
-5nea,2017-12-06,2017-03-10
-4ne7,2013-11-20,2013-10-28
-7neh,2021-03-03,2021-02-04
-5ne0,2017-06-14,2017-03-09
-7nef,2021-03-03,2021-02-03
-5neu,2017-06-21,2017-03-11
-5neb,2017-07-26,2017-03-10
-5nek,2018-02-21,2017-03-10
-6neg,2019-12-18,2018-12-17
-5nev,2017-03-29,2017-03-12
-4ne2,2014-02-26,2013-10-28
-5nel,2018-02-21,2017-03-10
-1ne4,2004-01-13,2002-12-10
-6nej,2019-12-18,2018-12-17
-7ne2,2021-04-14,2021-02-03
-3nex,2010-11-24,2010-06-09
-4nex,2014-11-12,2013-10-30
-4nev,2014-05-14,2013-10-30
-7neb,2021-07-07,2021-02-03
-7ney,2021-08-04,2021-02-05
-7ne6,2022-03-02,2021-02-03
-5ne2,2017-09-13,2017-03-09
-3ner,2011-05-25,2010-06-09
-7ne9,2022-03-02,2021-02-03
-7nee,2021-04-07,2021-02-03
-1nen,2003-02-25,2002-12-11
-6ne2,2019-05-15,2018-12-15
-7nec,2021-06-02,2021-02-03
-4new,2014-05-14,2013-10-30
-6ne3,2019-07-17,2018-12-16
-5nem,2017-06-21,2017-03-10
-7new,2021-03-03,2021-02-05
-3ne8,2010-07-14,2010-06-08
-3nes,2010-11-24,2010-06-09
-4ne9,2014-09-10,2013-10-28
-4nes,2014-04-23,2013-10-30
-4nef,2014-04-16,2013-10-29
-3ned,2010-11-24,2010-06-08
-4ne0,2014-06-18,2013-10-28
-6new,2019-12-25,2018-12-18
-5nei,2018-02-21,2017-03-10
-6ne5,2019-04-17,2018-12-17
-4nea,2013-11-06,2013-10-28
-1nek,2003-02-25,2002-12-11
-1nel,1994-01-31,1993-08-20
-4ney,2014-01-15,2013-10-30
-1nec,2000-03-31,1999-03-30
-6net,2019-08-14,2018-12-18
-1new,1998-04-29,1998-02-10
-1nez,2003-04-08,2002-12-12
-3ne7,2010-07-28,2010-06-08
-7ne7,2021-02-17,2021-02-03
-7nea,2021-07-07,2021-02-03
-1qki,2000-03-16,1999-07-20
-5qk7,2018-12-19,2018-10-31
-6qka,2020-02-19,2019-01-28
-5qk2,2018-12-19,2018-10-31
-2qk9,2007-11-13,2007-07-10
-7qk9,2022-04-20,2021-12-17
-8qk5,2024-04-17,2023-09-14
-8qk2,2024-04-17,2023-09-14
-6qkb,2019-08-14,2019-01-28
-5qk0,2018-12-19,2018-10-31
-4qkz,2015-06-17,2014-06-10
-6qki,2019-03-27,2019-01-29
-6qkz,2019-03-27,2019-01-30
-1qka,1999-09-09,1999-07-14
-2qkl,2008-03-25,2007-07-11
-6qk1,2020-02-19,2019-01-28
-2qkm,2008-04-15,2007-07-11
-5qk8,2018-12-19,2018-10-31
-7qk8,2022-04-20,2021-12-17
-6qkw,2019-06-26,2019-01-30
-2qkr,2007-09-04,2007-07-11
-3qk1,2011-03-23,2011-01-31
-1qkt,2000-08-18,1999-08-05
-6qku,2019-06-26,2019-01-30
-6qkx,2019-05-15,2019-01-30
-7qkb,2022-12-28,2021-12-17
-6qk5,2019-12-18,2019-01-28
-1qk3,1999-10-17,1999-07-09
-5qk9,2018-12-19,2018-10-31
-6qkc,2019-03-27,2019-01-28
-8qkb,2023-09-27,2023-09-14
-1qkb,1999-09-09,1999-07-14
-4qku,2014-06-25,2014-06-09
-5qk4,2018-12-19,2018-10-31
-7qkd,2022-12-28,2021-12-17
-3qk5,2011-04-06,2011-01-31
-4qkh,2015-03-11,2014-06-06
-4qkl,2015-11-11,2014-06-06
-2qks,2007-08-28,2007-07-11
-6qk6,2019-12-18,2019-01-28
-3qke,2012-02-01,2011-02-01
-3qk0,2011-03-30,2011-01-31
-2qkc,2008-07-29,2007-07-10
-4qkn,2014-12-03,2014-06-07
-8qkg,2024-03-20,2023-09-15
-3qkg,2012-02-08,2011-02-01
-4qki,2015-03-11,2014-06-06
-7qk5,2022-02-16,2021-12-17
-6qk2,2020-02-19,2019-01-28
-7qk0,2022-06-15,2021-12-17
-4qkb,2014-08-20,2014-06-05
-7qks,2022-10-26,2021-12-18
-1qkn,2000-07-28,1999-07-27
-4qko,2015-06-10,2014-06-07
-1qko,1999-10-24,1999-07-30
-5qkb,2020-04-29,2018-12-07
-4qkf,2014-08-20,2014-06-06
-6qkr,2019-05-15,2019-01-30
-1qk2,1999-09-18,1999-07-09
-7qkn,2022-11-23,2021-12-18
-1qk4,1999-10-17,1999-07-09
-6qkk,2020-02-19,2019-01-29
-4qkj,2015-03-11,2014-06-06
-6qkn,2020-02-19,2019-01-29
-8qkj,2024-03-20,2023-09-15
-6qk0,2020-02-19,2019-01-28
-5qk5,2018-12-19,2018-10-31
-7qkr,2022-10-26,2021-12-18
-8qk9,2024-04-17,2023-09-14
-6qkg,2019-05-15,2019-01-29
-1qkj,1999-07-28,1999-07-22
-8qke,2024-03-20,2023-09-15
-6qkj,2019-03-27,2019-01-29
-3qkm,2011-04-06,2011-02-01
-2qkx,2008-07-15,2007-07-11
-2qki,2007-08-14,2007-07-11
-1qkc,2000-06-05,1999-07-18
-3qkz,2012-02-29,2011-02-02
-2qkh,2007-08-14,2007-07-11
-1qku,2000-08-18,1999-08-05
-6qk7,2019-07-17,2019-01-28
-2qkd,2007-08-07,2007-07-10
-1qks,1999-08-18,1999-08-05
-7qka,2022-12-28,2021-12-17
-4qkd,2014-08-20,2014-06-06
-5qk1,2018-12-19,2018-10-31
-6qkt,2019-06-26,2019-01-30
-2qka,2008-07-29,2007-07-10
-7qk4,2022-04-13,2021-12-17
-1qk0,1999-09-18,1999-07-08
-6qkm,2020-02-19,2019-01-29
-2qkf,2008-07-01,2007-07-11
-3qkl,2011-03-30,2011-02-01
-4qk3,2015-03-04,2014-06-05
-1qk5,1999-10-17,1999-07-09
-3qkd,2011-04-06,2011-01-31
-4qkt,2014-08-13,2014-06-09
-1qkp,1999-10-24,1999-07-30
-6qk8,2019-10-02,2019-01-28
-3qkt,2011-03-30,2011-02-01
-7qko,2022-02-09,2021-12-18
-4qk7,2015-11-11,2014-06-05
-2qky,2008-07-15,2007-07-12
-3qkk,2011-03-30,2011-02-01
-2qk8,2007-08-28,2007-07-10
-4qk2,2015-03-04,2014-06-05
-4qkc,2015-11-11,2014-06-05
-4qkx,2014-07-23,2014-06-10
-2qk4,2007-07-24,2007-07-10
-3qkw,2011-06-08,2011-02-01
-2qk5,2008-03-11,2007-07-10
-4qkm,2015-11-11,2014-06-06
-1qkq,2000-01-18,1999-07-31
-5qka,2018-12-19,2018-10-31
-8qka,2024-04-17,2023-09-14
-5qk3,2018-12-19,2018-10-31
-3qkv,2011-04-27,2011-02-01
-1qkm,2000-07-28,1999-07-27
-2qkn,2008-07-01,2007-07-11
-2qkk,2007-11-13,2007-07-11
-4qkg,2015-03-11,2014-06-06
-5qk6,2018-12-19,2018-10-31
-7qke,2022-12-28,2021-12-17
-3qku,2011-03-30,2011-02-01
-4qk1,2015-03-04,2014-06-05
-1mum,2003-04-29,2002-09-24
-4mug,2014-08-27,2013-09-21
-4muh,2014-08-27,2013-09-21
-1muu,2003-05-06,2002-09-24
-1mud,1999-09-20,1998-08-20
-5mul,2017-04-26,2017-01-13
-1mui,2002-10-23,2002-09-23
-3mul,2010-08-11,2010-05-03
-1mu6,2004-04-06,2002-09-23
-7mub,2022-03-23,2021-05-14
-6muy,2019-03-27,2018-10-24
-6muf,2019-01-16,2018-10-23
-7mu3,2021-08-25,2021-05-14
-1mu8,2004-04-06,2002-09-23
-3muu,2010-11-24,2010-05-03
-7mu1,2021-11-24,2021-05-14
-1muh,2002-09-27,2002-09-23
-4muj,2014-08-27,2013-09-22
-2muc,1999-12-22,1998-10-26
-3mu5,2010-05-12,2010-05-01
-4mul,2014-08-27,2013-09-22
-3muy,2011-03-16,2010-05-03
-4mum,2014-02-26,2013-09-22
-4mu4,2014-09-24,2013-09-20
-1muc,1996-07-11,1995-09-20
-7mu7,2022-05-18,2021-05-14
-5mue,2017-07-19,2017-01-13
-3mu6,2011-11-02,2010-05-01
-4mu7,2013-12-11,2013-09-20
-5mup,2017-04-05,2017-01-13
-3mux,2010-05-12,2010-05-03
-1mup,1994-01-31,1992-09-21
-6mu3,2018-10-31,2018-10-22
-4muy,2014-06-11,2013-09-23
-1muo,2003-04-15,2002-09-24
-6muz,2019-03-27,2018-10-24
-4muv,2014-06-25,2013-09-23
-3mup,2010-11-24,2010-05-03
-1muw,2002-11-06,2002-09-24
-5mu9,2017-07-12,2017-01-12
-3mus,2011-04-13,2010-05-03
-6mul,2019-05-01,2018-10-23
-3muf,2011-05-04,2010-05-03
-3muk,2010-08-11,2010-05-03
-2muq,2014-12-03,2014-09-16
-5muq,2018-05-02,2017-01-13
-6mu4,2019-06-05,2018-10-22
-7mua,2021-06-09,2021-05-14
-4muu,2014-09-17,2013-09-23
-5mu8,2017-03-29,2017-01-12
-6mu8,2019-01-16,2018-10-22
-4mui,2014-08-27,2013-09-22
-6mus,2018-12-12,2018-10-23
-5mu2,2017-07-19,2017-01-12
-4mu0,2014-09-24,2013-09-20
-4mu3,2014-09-24,2013-09-20
-3muc,1999-11-04,1998-10-27
-4mux,2014-06-18,2013-09-23
-4muz,2013-10-02,2013-09-23
-3mun,2011-05-18,2010-05-03
-5muv,2017-03-22,2017-01-14
-4mun,2014-08-27,2013-09-22
-3mug,2010-06-16,2010-05-03
-5muj,2017-04-05,2017-01-13
-6muk,2018-10-31,2018-10-23
-5muo,2018-02-14,2017-01-13
-6muj,2019-02-27,2018-10-23
-4mur,2013-10-02,2013-09-23
-7mu0,2022-02-02,2021-05-14
-1mu0,2002-11-06,2002-09-23
-4mut,2013-10-09,2013-09-23
-2mum,2014-12-24,2014-09-12
-5mug,2017-07-19,2017-01-13
-5mu6,2018-02-14,2017-01-12
-6mur,2018-12-12,2018-10-23
-4mue,2014-08-27,2013-09-21
-4muq,2013-10-09,2013-09-23
-4mua,2013-12-18,2013-09-21
-3mu8,2010-05-12,2010-05-02
-5mu0,2017-07-19,2017-01-11
-6mu6,2019-01-16,2018-10-22
-3muz,2011-03-16,2010-05-03
-5mub,2017-07-19,2017-01-13
-5mut,2017-03-08,2017-01-14
-3muh,2010-06-16,2010-05-03
-4muk,2014-08-27,2013-09-22
-6mud,2019-05-08,2018-10-23
-3mua,2011-06-01,2010-05-02
-6muu,2018-12-19,2018-10-23
-5mu1,2017-07-26,2017-01-11
-5mua,2017-07-12,2017-01-12
-3mu0,2010-05-12,2010-05-01
-5muy,2017-05-17,2017-01-14
-1mu5,2003-01-07,2002-09-23
-6mu7,2019-01-16,2018-10-22
-1muq,2003-07-01,2002-09-24
-1mue,2004-04-06,2002-09-23
-3mui,2011-06-01,2010-05-03
-4muf,2014-08-27,2013-09-21
-1mua,1993-10-31,1993-06-18
-3mu3,2010-06-09,2010-05-01
-7mu5,2022-08-24,2021-05-14
-3mu4,2010-05-12,2010-05-01
-6mum,2019-05-01,2018-10-23
-6mug,2019-01-16,2018-10-23
-5muc,2018-02-14,2017-01-13
-3muo,2011-06-29,2010-05-03
-1mus,2002-09-27,2002-09-24
-6mub,2018-10-31,2018-10-22
-6mue,2019-05-08,2018-10-23
-2mus,2017-02-01,2014-09-16
-5mur,2018-02-14,2017-01-13
-4mub,2013-12-18,2013-09-21
-4muw,2013-10-23,2013-09-23
-2mur,2014-12-03,2014-09-16
-2muw,2014-12-24,2014-09-18
-5muw,2017-03-22,2017-01-14
-3mu1,2010-05-12,2010-05-01
-4mu5,2014-06-18,2013-09-20
-4mu1,2014-09-24,2013-09-20
-4mus,2013-10-09,2013-09-23
-5mui,2017-03-22,2017-01-13
-2muv,2014-12-24,2014-09-18
-7mu8,2022-02-09,2021-05-14
-6mu0,2018-11-14,2018-10-22
-1mux,1998-10-14,1997-09-06
-1muj,2003-02-18,2002-09-23
-4mu8,2014-06-04,2013-09-20
-6mut,2018-12-12,2018-10-23
-6mu1,2018-12-05,2018-10-22
-8sss,2023-08-02,2023-05-08
-6ssd,2020-01-15,2019-09-06
-7sss,2022-11-02,2021-11-11
-7ssy,2022-06-29,2021-11-11
-6ss3,2020-04-01,2019-09-06
-5ss2,2022-07-06,2022-06-09
-8ss9,2023-09-06,2023-05-08
-5ssg,2022-07-06,2022-06-09
-5ssc,2022-07-06,2022-06-09
-5sst,2023-08-23,2022-07-03
-6ssy,2019-12-18,2019-09-09
-8ssu,2023-08-02,2023-05-08
-7ssb,2022-08-24,2021-11-10
-6ss9,2020-07-15,2019-09-06
-7ss5,2021-12-01,2021-11-09
-8ssy,2023-08-16,2023-05-09
-6ss4,2020-06-10,2019-09-06
-8ss5,2023-09-06,2023-05-08
-3ssm,2011-08-24,2011-07-08
-3ss5,2012-01-11,2011-07-07
-5sss,2023-08-23,2022-07-03
-6sse,2020-01-15,2019-09-06
-6ssb,2020-09-30,2019-09-06
-5ssq,2022-07-06,2022-06-09
-5ssi,2022-07-06,2022-06-09
-5ssa,2022-07-06,2022-06-09
-3ss8,2011-08-24,2011-07-08
-6ss2,2020-06-10,2019-09-06
-8ssn,2023-09-06,2023-05-08
-6ssz,2019-12-04,2019-09-09
-7ssx,2022-06-29,2021-11-11
-8ssa,2023-09-06,2023-05-08
-7ssi,2022-11-16,2021-11-11
-5ss5,2022-07-06,2022-06-09
-1sst,2004-06-01,2004-03-24
-5ss4,2022-07-06,2022-06-09
-6ss8,2020-07-15,2019-09-06
-3ss9,2012-01-18,2011-07-08
-5ss6,2022-07-06,2022-06-09
-6ssp,2020-02-12,2019-09-09
-5ssv,2023-08-23,2022-07-03
-8ssr,2023-08-02,2023-05-08
-8ssl,2024-05-08,2023-05-08
-3ssj,2012-05-02,2011-07-08
-5ss8,2022-07-06,2022-06-09
-1ssp,1999-05-06,1999-04-28
-8ss8,2023-09-06,2023-05-08
-5ssl,2022-07-06,2022-06-09
-7ssd,2022-02-23,2021-11-10
-5ssp,2022-07-06,2022-06-09
-8sst,2023-08-02,2023-05-08
-7ssm,2022-02-09,2021-11-11
-8ssb,2023-09-06,2023-05-08
-5ssk,2022-07-06,2022-06-09
-6sss,2021-02-03,2019-09-09
-3ss6,2011-07-20,2011-07-07
-7ssu,2022-03-02,2021-11-11
-3ssb,2011-09-07,2011-07-08
-8ss0,2024-01-17,2023-05-08
-7ssl,2022-02-23,2021-11-11
-7ss1,2022-11-16,2021-11-09
-5ssu,2023-08-23,2022-07-03
-5ssd,2022-07-06,2022-06-09
-8sso,2023-09-06,2023-05-08
-8sse,2023-10-11,2023-05-08
-5ssw,2023-08-23,2022-07-03
-5ssx,2023-08-23,2022-08-12
-5ssr,2022-07-06,2022-06-09
-6ss1,2020-04-01,2019-09-06
-7ssj,2022-11-16,2021-11-11
-3ss7,2012-01-18,2011-07-07
-8ssh,2024-02-14,2023-05-08
-5ssh,2022-07-06,2022-06-09
-8ss6,2023-09-06,2023-05-08
-7ssz,2022-06-29,2021-11-11
-6ssf,2020-01-15,2019-09-06
-5ssy,2023-08-23,2022-08-12
-6ssw,2021-02-03,2019-09-09
-5ss7,2022-07-06,2022-06-09
-1ss9,2004-09-21,2004-03-23
-7ss6,2023-04-12,2021-11-09
-6ssg,2020-01-15,2019-09-06
-1ss4,2004-08-03,2004-03-23
-3ssa,2012-09-05,2011-07-08
-7ssv,2022-06-29,2021-11-11
-8ssk,2024-05-15,2023-05-08
-5ss0,2022-07-06,2022-06-09
-6ssa,2020-07-15,2019-09-06
-5sso,2022-07-06,2022-06-09
-8ss3,2023-09-06,2023-05-08
-7ss7,2023-04-12,2021-11-09
-1ssq,2004-06-01,2004-03-24
-6ss6,2020-06-10,2019-09-06
-5ssz,2023-08-23,2022-08-12
-6ssq,2019-11-20,2019-09-09
-5ssb,2022-07-06,2022-06-09
-8ss2,2023-09-06,2023-05-08
-5ss9,2022-07-06,2022-06-09
-8ssq,2023-08-02,2023-05-08
-1ssg,2004-08-24,2004-03-24
-8ssp,2023-09-06,2023-05-08
-5sse,2022-07-06,2022-06-09
-8ssc,2023-10-18,2023-05-08
-7ssf,2023-10-25,2021-11-10
-7ssr,2023-08-09,2021-11-11
-3ssg,2011-11-30,2011-07-08
-3ss2,2011-12-28,2011-07-07
-7ssk,2022-11-09,2021-11-11
-3ssn,2011-08-24,2011-07-08
-7ssq,2023-08-09,2021-11-11
-8ss7,2023-09-06,2023-05-08
-6ssu,2021-02-03,2019-09-09
-5ssn,2022-07-06,2022-06-09
-5ssf,2022-07-06,2022-06-09
-3ss1,2012-02-01,2011-07-07
-7ss8,2022-11-09,2021-11-10
-3ssv,2012-07-11,2011-07-08
-6ss7,2020-07-15,2019-09-06
-6ssc,2020-09-30,2019-09-06
-7sse,2021-12-15,2021-11-10
-5ss3,2022-07-06,2022-06-09
-5ss1,2022-07-06,2022-06-09
-8ssz,2024-02-07,2023-05-09
-8ssw,2024-05-22,2023-05-09
-5ssj,2022-07-06,2022-06-09
-5ssm,2022-07-06,2022-06-09
-3sso,2011-08-24,2011-07-08
-6ssi,2020-02-12,2019-09-07
-5ex3,2016-03-09,2015-11-23
-6exj,2018-03-07,2017-11-08
-6ex8,2018-04-11,2017-11-07
-5exf,2016-12-07,2015-11-23
-8exk,2023-07-05,2022-10-25
-5exw,2016-06-15,2015-11-24
-7exw,2021-11-17,2021-05-28
-1exv,2000-11-01,2000-05-04
-3exg,2008-11-25,2008-10-16
-4exp,2012-05-30,2012-04-30
-5ex1,2016-06-22,2015-11-23
-5exy,2016-05-25,2015-11-24
-5ex8,2017-01-11,2015-11-23
-2exg,2006-10-17,2005-11-08
-2ex3,2006-03-14,2005-11-07
-6ex4,2018-11-21,2017-11-07
-4exr,2012-06-27,2012-04-30
-1ex9,2000-10-18,2000-05-02
-8exc,2023-02-22,2022-10-25
-4ex6,2013-01-16,2012-04-30
-1exa,2000-06-09,2000-05-02
-5exm,2016-04-13,2015-11-23
-7exd,2021-08-04,2021-05-27
-1exj,2001-01-24,2000-05-02
-7ex4,2022-02-16,2021-05-26
-1exp,1997-01-27,1996-01-11
-8exy,2023-02-01,2022-10-26
-6ex0,2018-01-24,2017-11-07
-1exm,2000-06-07,2000-05-03
-6ex7,2017-12-13,2017-11-07
-6exv,2018-03-21,2017-11-09
-8exj,2023-07-05,2022-10-25
-1ex7,2001-03-16,2000-05-01
-2exm,2005-12-27,2005-11-08
-7ex0,2022-01-26,2021-05-26
-5exl,2016-04-13,2015-11-23
-4exz,2012-12-26,2012-05-01
-6exl,2018-05-02,2017-11-08
-3exb,2009-01-13,2008-10-16
-5exs,2016-01-13,2015-11-24
-2ext,2006-08-01,2005-11-08
-5ex7,2015-12-09,2015-11-23
-3ex4,2009-04-07,2008-10-16
-3ex3,2009-04-07,2008-10-16
-6exo,2018-04-11,2017-11-08
-3exm,2008-12-09,2008-10-16
-7exh,2022-11-30,2021-05-27
-6exm,2018-05-02,2017-11-08
-1exb,2000-07-19,2000-05-02
-5exa,2016-05-04,2015-11-23
-7exs,2021-07-28,2021-05-28
-2exc,2006-11-14,2005-11-08
-7ex3,2022-02-16,2021-05-26
-1ex2,2000-06-14,2000-04-28
-2exr,2005-11-29,2005-11-08
-8ex1,2023-02-01,2022-10-24
-4ex8,2013-01-16,2012-04-30
-1exs,2000-11-15,2000-05-04
-7exz,2021-11-03,2021-05-29
-5exo,2016-10-05,2015-11-23
-7exj,2022-11-30,2021-05-27
-1ex8,2001-05-01,2000-05-01
-8exv,2022-11-30,2022-10-25
-3exs,2009-08-25,2008-10-17
-6ex6,2018-11-21,2017-11-07
-4exs,2012-08-08,2012-04-30
-3ex7,2008-12-09,2008-10-16
-8exb,2023-02-01,2022-10-25
-5ex5,2016-06-15,2015-11-23
-1exx,2000-06-09,2000-05-05
-1exw,2000-08-02,2000-05-04
-5ext,2016-01-13,2015-11-24
-7ext,2021-10-06,2021-05-28
-2exu,2006-11-08,2005-11-08
-8exh,2023-03-22,2022-10-25
-1exq,2000-11-03,2000-05-03
-8ex2,2023-02-01,2022-10-24
-7exv,2021-11-17,2021-05-28
-7exx,2022-06-01,2021-05-28
-1exf,1998-02-25,1996-10-22
-4exh,2012-08-01,2012-04-30
-7exf,2022-11-30,2021-05-27
-8ex3,2023-01-18,2022-10-24
-2ex5,2006-05-23,2005-11-07
-2ex9,2006-06-13,2005-11-08
-4ex9,2013-01-16,2012-04-30
-7exc,2022-06-01,2021-05-26
-3ex2,2009-04-07,2008-10-16
-2ex1,2006-02-28,2005-11-07
-3exe,2008-11-25,2008-10-16
-1exc,2000-06-14,2000-05-02
-5exx,2016-02-10,2015-11-24
-6ex1,2018-10-10,2017-11-07
-8exr,2023-01-11,2022-10-25
-5ex6,2016-08-03,2015-11-23
-1exz,2000-07-06,2000-05-05
-1ext,1997-01-11,1996-07-03
-5exd,2015-12-30,2015-11-23
-6exs,2018-06-27,2017-11-09
-7exk,2022-05-04,2021-05-27
-8exw,2024-02-07,2022-10-25
-6exw,2018-08-08,2017-11-10
-2exl,2006-10-24,2005-11-08
-6exq,2018-04-11,2017-11-08
-4ex1,2013-05-01,2012-04-29
-4ex0,2013-05-01,2012-04-29
-4exn,2012-05-30,2012-04-30
-4exq,2012-05-16,2012-04-30
-7exu,2021-11-17,2021-05-28
-7exo,2022-06-01,2021-05-28
-5ex4,2015-12-02,2015-11-23
-4ex7,2013-01-16,2012-04-30
-7exg,2022-11-30,2021-05-27
-2exf,2007-04-24,2005-11-08
-5exn,2016-04-13,2015-11-23
-3ex1,2009-04-07,2008-10-16
-3exc,2008-11-11,2008-10-16
-5exc,2016-08-03,2015-11-23
-8exn,2023-07-05,2022-10-25
-3ex8,2008-11-04,2008-10-16
-1exi,2001-01-24,2000-05-02
-3exo,2009-02-03,2008-10-16
-5exq,2016-11-30,2015-11-24
-3exn,2009-01-06,2008-10-16
-4exa,2013-01-09,2012-04-30
-5exh,2016-02-03,2015-11-23
-2exh,2006-04-04,2005-11-08
-2exa,2006-06-13,2005-11-08
-2exv,2006-02-07,2005-11-09
-4ex4,2012-05-23,2012-04-29
-2ex8,2006-06-13,2005-11-08
-7ex9,2022-02-16,2021-05-26
-6exk,2018-05-02,2017-11-08
-2exb,2006-06-13,2005-11-08
-1ex1,1999-11-17,1998-11-10
-5exe,2015-12-30,2015-11-23
-1exr,2000-09-20,2000-05-03
-2exx,2006-11-21,2005-11-09
-8exo,2022-11-30,2022-10-25
-3ext,2009-08-25,2008-10-17
-7exq,2022-11-30,2021-05-28
-2ex4,2005-11-15,2005-11-07
-2exi,2006-04-04,2005-11-08
-7exr,2022-11-30,2021-05-28
-5exz,2016-05-25,2015-11-24
-8exs,2023-01-11,2022-10-25
-3exj,2008-12-16,2008-10-16
-7ex6,2022-02-16,2021-05-26
-4exg,2012-10-31,2012-04-30
-2exk,2006-04-04,2005-11-08
-8exl,2022-11-30,2022-10-25
-7exb,2021-11-03,2021-05-26
-1ex0,2003-12-23,2000-04-28
-7ex2,2022-02-16,2021-05-26
-1exd,2000-05-15,2000-05-02
-4exx,2013-05-01,2012-05-01
-3exl,2008-12-16,2008-10-16
-6ex3,2018-11-21,2017-11-07
-8exq,2023-01-11,2022-10-25
-3exx,2009-05-19,2008-10-17
-6exf,2018-11-14,2017-11-08
-6exi,2018-09-19,2017-11-08
-8ext,2023-01-11,2022-10-25
-5ex2,2016-06-22,2015-11-23
-8exm,2023-07-05,2022-10-25
-4exk,2012-08-08,2012-04-30
-3ex6,2009-04-07,2008-10-16
-5exr,2016-03-23,2015-11-24
-2exs,2006-08-01,2005-11-08
-3exi,2008-11-25,2008-10-16
-3exh,2008-11-25,2008-10-16
-4exo,2012-05-30,2012-04-30
-6ex5,2018-11-21,2017-11-07
-5ex9,2017-01-11,2015-11-23
-7exp,2022-01-05,2021-05-28
-6exh,2018-11-14,2017-11-08
-8exu,2022-11-30,2022-10-25
-6exn,2018-01-17,2017-11-08
-7exm,2021-06-16,2021-05-27
-8exp,2023-01-11,2022-10-25
-6ex9,2018-06-06,2017-11-07
-2exj,2006-04-04,2005-11-08
-7ex7,2022-02-16,2021-05-26
-4exy,2012-08-08,2012-05-01
-8exg,2023-02-22,2022-10-25
-2ex6,2006-06-13,2005-11-08
-5exk,2016-08-10,2015-11-23
-1exk,2000-07-26,2000-05-03
-3exf,2008-11-25,2008-10-16
-8ex0,2023-02-01,2022-10-24
-4exl,2012-05-30,2012-04-30
-4ex5,2012-05-09,2012-04-29
-5ex0,2016-03-09,2015-11-23
-7ex8,2022-02-16,2021-05-26
-2cer,2006-09-27,2006-02-10
-7ceg,2021-02-24,2020-06-23
-5ceo,2015-10-14,2015-07-07
-8cer,2023-04-05,2023-02-02
-8ceo,2023-03-08,2023-02-02
-4cej,2014-03-12,2013-11-11
-1cee,1999-06-30,1999-03-08
-2ces,2006-09-27,2006-02-10
-7cei,1999-09-17,1998-09-17
-4ced,2013-11-20,2013-11-11
-4cei,2014-03-12,2013-11-11
-1cet,1999-03-19,1999-03-10
-6ceo,2018-04-18,2018-02-12
-3cej,2008-05-27,2008-02-29
-1ceb,1996-04-03,1995-12-03
-2cev,1999-04-16,1999-03-10
-2cea,2006-02-09,2006-02-03
-3ce9,2008-03-11,2008-02-28
-7ce9,2021-06-30,2020-06-22
-5ce3,2016-07-06,2015-07-06
-1cer,1996-03-08,1995-11-11
-7ceu,2021-06-30,2020-06-24
-4cet,2014-08-27,2013-11-12
-4ces,2013-11-20,2013-11-11
-2ce0,2006-07-05,2006-02-01
-1cev,1999-04-16,1999-03-12
-5ce9,2015-10-28,2015-07-06
-4cee,2013-11-27,2013-11-11
-8cev,2023-04-05,2023-02-02
-2ce8,2006-06-14,2006-02-03
-2ce4,2006-02-13,2006-02-03
-2ceo,2006-08-14,2006-02-08
-5cep,2015-10-14,2015-07-07
-7ces,2021-06-30,2020-06-24
-5ce6,2016-04-13,2015-07-06
-6cex,2018-04-04,2018-02-12
-5ce8,2016-02-24,2015-07-06
-6ceq,2018-05-16,2018-02-12
-6ce2,2018-07-25,2018-02-10
-8cep,2023-07-19,2023-02-02
-1ceh,1995-02-07,1994-11-16
-8ce5,2023-09-06,2023-02-01
-8ce3,2024-02-21,2023-02-01
-4ceq,2013-11-20,2013-11-11
-8cef,2023-08-09,2023-02-01
-1ce1,1999-06-25,1999-03-12
-5cew,2016-08-10,2015-07-07
-4cea,2013-11-20,2013-11-11
-3cei,2008-06-10,2008-02-29
-3cev,1999-04-16,1999-03-15
-3cea,2008-03-11,2008-02-28
-4ce4,2013-12-18,2013-11-08
-5ceg,2015-11-11,2015-07-06
-2cek,2006-04-10,2006-02-08
-8ced,2023-12-20,2023-02-01
-6cea,2018-02-28,2018-02-11
-7ce6,2021-06-30,2020-06-22
-2ceq,2006-09-27,2006-02-10
-8cej,2023-05-31,2023-02-02
-1ce6,1999-03-26,1999-03-17
-6cey,2018-04-11,2018-02-13
-8cew,2024-02-21,2023-02-02
-3cen,2008-05-20,2008-02-29
-5cez,2015-12-23,2015-07-08
-4ce8,2014-11-12,2013-11-10
-8cet,2023-04-05,2023-02-02
-7ceo,2021-06-30,2020-06-24
-3cem,2008-05-27,2008-02-29
-3ce2,2008-03-18,2008-02-28
-7cee,2021-02-24,2020-06-23
-1ces,1997-02-15,1996-02-15
-6cel,1997-12-24,1997-09-24
-7ceb,2021-06-23,2020-06-22
-3cel,1997-03-12,1996-08-24
-6ced,2018-02-28,2018-02-11
-4cev,1999-04-16,1999-03-15
-6ceh,2018-05-23,2018-02-11
-8ces,2023-04-05,2023-02-02
-4ce9,2013-11-20,2013-11-11
-5ceh,2016-05-18,2015-07-06
-8ceh,2023-09-20,2023-02-01
-2ce2,2006-08-23,2006-02-02
-7cec,2021-06-23,2020-06-22
-2ce7,2006-02-09,2006-02-03
-1ce5,1999-03-23,1999-03-16
-4cec,2013-11-20,2013-11-11
-8cec,2023-12-20,2023-02-01
-7cez,2021-06-30,2020-06-24
-4ceg,2015-01-28,2013-11-11
-2cex,2006-05-15,2006-02-10
-6cee,2018-02-28,2018-02-11
-1ce2,1999-03-19,1999-03-13
-4cex,2014-08-27,2013-11-12
-7cek,2021-06-23,2020-06-23
-4ce0,2014-11-26,2013-11-08
-2cei,2006-12-13,2006-02-07
-5cev,1999-04-16,1999-03-16
-4ce1,2014-01-29,2013-11-08
-3ce1,2008-08-26,2008-02-27
-5cee,2016-10-05,2015-07-06
-4cer,2013-11-20,2013-11-11
-3ce3,2008-08-26,2008-02-28
-7cel,1997-12-24,1997-09-24
-7cer,2021-06-30,2020-06-24
-8cey,2024-02-21,2023-02-02
-6cew,2018-04-18,2018-02-12
-5ce1,2016-07-06,2015-07-06
-6cen,2018-05-09,2018-02-12
-8ceu,2023-07-26,2023-02-02
-2cey,2006-05-15,2006-02-11
-1ceg,1996-10-14,1995-01-12
-3cew,2008-03-25,2008-02-29
-6cez,2018-09-12,2018-02-13
-6cep,2018-06-27,2018-02-12
-2cet,2006-09-27,2006-02-10
-6cer,2018-07-11,2018-02-12
-2cep,1994-08-31,1994-05-31
-2cej,2007-02-13,2006-02-07
-8cek,2023-05-31,2023-02-02
-1cea,1996-04-03,1995-12-03
-6ceb,2018-03-14,2018-02-11
-8ceq,2023-04-05,2023-02-02
-2cel,1997-03-12,1996-08-24
-7cet,2021-06-30,2020-06-24
-7ceh,2020-08-26,2020-06-23
-8cex,2024-02-21,2023-02-02
-4ce3,2014-01-29,2013-11-08
-7cen,2021-06-30,2020-06-23
-3cez,2008-03-18,2008-02-29
-1ced,1996-08-17,1996-03-06
-2cem,2007-02-13,2006-02-08
-4ceo,2013-11-20,2013-11-11
-1ce8,1999-07-26,1999-03-18
-4ceu,2014-08-27,2013-11-12
-5cel,1997-12-24,1997-09-24
-8cem,2023-04-05,2023-02-02
-6cek,2018-02-21,2018-02-12
-7ce5,2021-06-30,2020-06-22
-8cen,2023-03-22,2023-02-02
-2cen,2007-02-13,2006-02-08
-3cep,2008-04-01,2008-02-29
-3ce6,2008-09-16,2008-02-28
-7ce8,2021-06-23,2020-06-22
-6cef,2018-02-28,2018-02-11
-6ce9,2018-03-14,2018-02-11
-1cen,1996-04-03,1995-12-04
-1cef,1996-10-14,1995-01-12
-4ce5,2014-02-12,2013-11-08
-4ce2,2014-01-29,2013-11-08
-4cez,2013-11-27,2013-11-13
-6ces,2018-03-28,2018-02-12
-4cew,2014-02-12,2013-11-12
-7cef,2020-08-26,2020-06-23
-5cei,2016-02-10,2015-07-06
-8ce4,2023-10-11,2023-02-01
-4cey,2014-02-12,2013-11-12
-4cef,2013-11-20,2013-11-11
-4ceb,2013-11-20,2013-11-11
-7ce4,2021-05-12,2020-06-22
-5ce5,2015-12-02,2015-07-06
-3ce0,2008-03-11,2008-02-27
-7cep,2021-06-30,2020-06-24
-6ce0,2018-12-05,2018-02-09
-8cee,2023-12-20,2023-02-01
-2ce1,2006-07-05,2006-02-02
-5ceq,2015-10-14,2015-07-07
-1ce7,2000-03-20,1999-03-18
-4cel,1997-03-12,1996-08-24
-5ced,2015-12-09,2015-07-06
-1cel,1994-11-01,1994-05-17
-3ceh,2008-05-27,2008-02-29
-2ce9,2006-06-14,2006-02-03
-5cet,2015-12-23,2015-07-07
-5h6o,2017-11-15,2016-11-14
-2h6f,2006-08-29,2006-05-31
-3h6v,2009-07-28,2009-04-24
-5h6x,2017-11-22,2016-11-15
-8h6p,2023-02-22,2022-10-18
-1h65,2002-01-29,2001-06-06
-1h6l,2001-08-29,2001-06-19
-5h6u,2017-08-09,2016-11-15
-6h6s,2019-01-09,2018-07-30
-5h60,2017-12-20,2016-11-10
-3h6t,2009-07-28,2009-04-24
-3h6w,2009-07-28,2009-04-24
-4h6z,2012-11-07,2012-09-19
-8h6u,2023-08-23,2022-10-18
-8h63,2023-10-04,2022-10-15
-2h6s,2007-06-12,2006-06-01
-8h6f,2023-10-25,2022-10-17
-3h6m,2010-03-09,2009-04-23
-5h6r,2017-04-12,2016-11-14
-8h6t,2023-02-22,2022-10-18
-1h6d,2001-11-28,2001-06-12
-1h6x,2002-06-27,2001-06-29
-1h68,2001-08-28,2001-06-08
-4h6b,2012-10-17,2012-09-19
-4h67,2012-10-17,2012-09-19
-1h69,2001-09-05,2001-06-08
-2h6v,2007-05-15,2006-06-01
-1h6m,2001-08-30,2001-06-19
-8h68,2023-02-22,2022-10-16
-4h69,2012-10-17,2012-09-19
-6h6n,2019-02-13,2018-07-28
-3h60,2009-09-29,2009-04-23
-8h6a,2023-10-18,2022-10-16
-5h6y,2017-11-15,2016-11-15
-6h6o,2019-02-13,2018-07-28
-6h6z,2018-12-19,2018-07-30
-3h65,2009-09-01,2009-04-23
-2h6t,2007-06-12,2006-06-01
-5h6g,2017-09-20,2016-11-11
-6h61,2018-11-21,2018-07-25
-6h6v,2019-02-27,2018-07-30
-8h6l,2024-05-01,2022-10-18
-8h6c,2023-05-03,2022-10-16
-3h6u,2009-07-28,2009-04-24
-1h6b,2001-11-28,2001-06-11
-3h6d,2009-11-24,2009-04-23
-2h6k,2006-07-04,2006-05-31
-3h68,2009-09-29,2009-04-23
-4h60,2013-08-07,2012-09-19
-2h6a,2007-04-17,2006-05-31
-2h6i,2006-08-29,2006-05-31
-5h68,2017-03-15,2016-11-11
-6h6x,2019-02-27,2018-07-30
-3h6h,2009-05-26,2009-04-23
-3h66,2009-09-29,2009-04-23
-1h6n,2003-10-03,2001-06-20
-3h6z,2009-06-16,2009-04-24
-1h6y,2002-06-27,2001-06-29
-5h62,2017-12-27,2016-11-10
-6h6k,2019-04-17,2018-07-27
-8h66,2023-05-03,2022-10-15
-2h6g,2006-08-29,2006-05-31
-6h6c,2019-04-10,2018-07-27
-6h63,2019-09-18,2018-07-26
-5h6q,2017-04-12,2016-11-14
-6h6u,2019-08-14,2018-07-30
-1h6a,2001-11-28,2001-06-11
-8h65,2023-05-03,2022-10-15
-2h6q,2006-07-04,2006-06-01
-7h6y,2024-05-29,2024-04-26
-8h6e,2024-05-01,2022-10-17
-6h6q,2018-08-22,2018-07-30
-2h6o,2006-10-31,2006-05-31
-6h68,2018-08-29,2018-07-26
-8h6s,2022-12-21,2022-10-18
-6h6l,2019-08-14,2018-07-27
-6h65,2018-10-10,2018-07-26
-6h6y,2018-12-19,2018-07-30
-8h6n,2023-10-11,2022-10-18
-8h62,2023-10-04,2022-10-14
-1h6p,2001-09-05,2001-06-20
-1h6g,2001-08-07,2001-06-14
-6h64,2019-08-14,2018-07-26
-3h64,2009-09-29,2009-04-23
-2h6p,2006-09-19,2006-05-31
-7h6l,2024-05-29,2024-04-26
-1h66,2001-09-05,2001-06-06
-7h6p,2024-05-29,2024-04-26
-4h6q,2012-11-28,2012-09-19
-7h6n,2024-05-29,2024-04-26
-1h63,2001-07-05,2001-06-04
-6h6j,2019-04-10,2018-07-27
-8h6i,2023-10-11,2022-10-17
-8h61,2023-10-18,2022-10-14
-5h6b,2017-09-20,2016-11-11
-6h6w,2018-12-05,2018-07-30
-7h6z,2024-05-29,2024-04-26
-1h6v,2001-08-14,2001-06-27
-6h6m,2019-08-14,2018-07-27
-6h6t,2019-08-14,2018-07-30
-2h65,2006-09-19,2006-05-30
-1h60,2001-07-05,2001-06-04
-5h6l,2017-08-09,2016-11-14
-6h66,2018-11-21,2018-07-26
-4h6r,2012-11-28,2012-09-19
-7h6m,2024-05-29,2024-04-26
-4h6p,2012-10-10,2012-09-19
-2h6h,2006-08-29,2006-05-31
-5h6j,2017-08-09,2016-11-14
-2h61,2007-06-05,2006-05-30
-7h6v,2024-05-29,2024-04-26
-7h6k,2024-05-29,2024-04-26
-5h65,2017-05-31,2016-11-10
-5h6s,2017-02-01,2016-11-15
-3h63,2009-09-29,2009-04-23
-2h6e,2007-06-05,2006-05-31
-5h6h,2017-03-15,2016-11-13
-6h62,2019-08-14,2018-07-26
-5h6v,2017-06-14,2016-11-15
-6h67,2018-08-29,2018-07-26
-1h6c,2001-11-28,2001-06-11
-2h6n,2006-07-04,2006-05-31
-5h67,2017-03-15,2016-11-11
-5h63,2017-12-20,2016-11-10
-4h6u,2012-11-07,2012-09-19
-3h62,2009-09-29,2009-04-23
-3h6g,2009-05-26,2009-04-23
-7h6j,2024-05-29,2024-04-26
-7h6x,2024-05-29,2024-04-26
-6h6r,2018-08-22,2018-07-30
-2h6l,2006-07-25,2006-05-31
-8h67,2024-05-01,2022-10-15
-3h6k,2009-12-01,2009-04-23
-6h6p,2019-02-13,2018-07-28
-4h6d,2012-10-17,2012-09-19
-3h61,2009-09-29,2009-04-23
-8h6k,2024-05-01,2022-10-18
-4h6s,2013-03-13,2012-09-19
-3h67,2009-09-29,2009-04-23
-3h6n,2009-05-19,2009-04-23
-7h6q,2024-05-29,2024-04-26
-8h6d,2023-05-03,2022-10-16
-1h61,2001-07-05,2001-06-04
-8h6j,2024-05-01,2022-10-18
-1h6f,2002-04-19,2001-06-13
-4h6k,2013-10-09,2012-09-19
-6h6i,2019-04-10,2018-07-27
-2h63,2006-07-04,2006-05-30
-2h6b,2006-07-04,2006-05-31
-4h6e,2012-11-07,2012-09-19
-2h6m,2006-08-08,2006-05-31
-1h62,2001-07-05,2001-06-04
-1h6h,2001-11-01,2001-06-15
-6h6a,2018-09-26,2018-07-26
-7h6w,2024-05-29,2024-04-26
-4h6o,2013-03-20,2012-09-19
-8h6b,2023-10-18,2022-10-16
-3h69,2009-09-29,2009-04-23
-2zcf,2007-11-20,2007-11-08
-5zc5,2018-12-19,2018-02-15
-6zc8,2021-06-23,2020-06-10
-3zci,2013-10-09,2012-11-20
-5zc6,2018-09-12,2018-02-15
-8zc5,2024-05-15,2024-04-28
-4zcg,2015-06-03,2015-04-15
-3zcq,2013-12-11,2012-11-21
-5zc9,2019-01-16,2018-02-16
-1zcw,2005-06-21,2005-04-13
-2zck,2008-01-29,2007-11-09
-7zco,2022-08-03,2022-03-28
-3zcl,2013-11-27,2012-11-20
-1zc9,2006-01-03,2005-04-11
-8zcl,2024-05-08,2024-04-30
-7zci,2022-09-21,2022-03-28
-8zc2,2024-05-29,2024-04-28
-8zc0,2024-05-15,2024-04-28
-6zcm,2020-07-29,2020-06-11
-3zch,2012-12-19,2012-11-20
-2zc3,2008-04-08,2007-11-02
-3zc7,2013-06-19,2012-11-19
-7zcp,2022-08-03,2022-03-28
-2zcc,2007-11-20,2007-11-08
-3zc1,2013-01-23,2012-11-14
-1zcz,2005-04-26,2005-04-13
-7zcx,2023-06-14,2022-03-29
-4zcs,2016-08-17,2015-04-16
-5zcb,2018-12-26,2018-02-16
-7zcf,2022-10-12,2022-03-28
-2zcj,2007-12-04,2007-11-09
-6zci,2020-12-23,2020-06-11
-6zc7,2021-06-23,2020-06-09
-4zcp,2016-09-14,2015-04-16
-2zcy,2008-04-08,2007-11-15
-6zcd,2021-06-23,2020-06-10
-5zc4,2019-02-27,2018-02-14
-2zcr,2008-03-11,2007-11-11
-2zc5,2008-04-08,2007-11-02
-4zcj,2015-05-13,2015-04-16
-3zc3,2013-11-20,2012-11-15
-5zcd,2018-12-26,2018-02-16
-6zc0,2021-06-23,2020-06-09
-6zcp,2021-06-23,2020-06-11
-6zcc,2021-04-21,2020-06-10
-4zca,2016-06-22,2015-04-15
-6zcz,2020-06-24,2020-06-12
-3zcp,2013-12-11,2012-11-21
-4zcc,2015-07-15,2015-04-15
-6zce,2020-10-07,2020-06-10
-6zcq,2021-06-23,2020-06-11
-6zc3,2021-06-23,2020-06-09
-3zcv,2013-12-11,2012-11-21
-4zcw,2016-07-20,2015-04-16
-4zc6,2015-06-03,2015-04-15
-3zcf,2013-10-23,2012-11-20
-8zck,2024-05-08,2024-04-30
-3zcu,2013-12-11,2012-11-21
-2zcb,2007-11-20,2007-11-08
-3zcx,2013-12-11,2012-11-23
-7zc7,2023-07-05,2022-03-25
-3zcg,2012-12-19,2012-11-20
-6zcv,2020-07-15,2020-06-12
-7zcq,2022-08-03,2022-03-28
-7zcw,2022-12-14,2022-03-29
-6zcl,2021-03-17,2020-06-11
-6zcu,2021-06-23,2020-06-12
-6zc6,2021-06-23,2020-06-09
-8zc3,2024-05-15,2024-04-28
-3zcn,2013-06-19,2012-11-21
-1zco,2005-10-18,2005-04-12
-6zcs,2021-06-23,2020-06-12
-2zce,2008-04-22,2007-11-08
-1zc3,2005-06-14,2005-04-10
-1zct,2005-04-26,2005-04-13
-4zcl,2015-07-29,2015-04-16
-4zcf,2015-07-29,2015-04-15
-5zcg,2019-03-06,2018-02-17
-7zc5,2022-09-21,2022-03-25
-7zcn,2022-08-03,2022-03-28
-4zcd,2015-07-15,2015-04-15
-3zcm,2012-12-05,2012-11-21
-4zcr,2016-09-14,2015-04-16
-7zc9,2023-07-19,2022-03-26
-1zcb,2005-11-15,2005-04-11
-3zcb,2013-06-19,2012-11-19
-5zcu,2019-03-06,2018-02-20
-5zcq,2018-08-15,2018-02-19
-7zc6,2022-09-28,2022-03-25
-5zcl,2019-03-06,2018-02-19
-7zca,2023-02-22,2022-03-26
-5zct,2018-07-25,2018-02-20
-3zc0,2013-01-23,2012-11-14
-7zcu,2022-10-12,2022-03-28
-5zcm,2018-11-07,2018-02-19
-1zch,2005-11-01,2005-04-12
-2zch,2008-01-29,2007-11-08
-5zc0,2018-06-06,2018-02-14
-5zck,2018-04-18,2018-02-18
-2zc6,2008-04-08,2007-11-02
-2zcl,2008-01-29,2007-11-09
-6zc9,2021-07-21,2020-06-10
-6zca,2020-10-14,2020-06-10
-6zct,2020-06-24,2020-06-12
-2zcq,2008-03-11,2007-11-11
-7zcr,2022-08-03,2022-03-28
-1zc4,2005-06-14,2005-04-10
-4zck,2015-07-29,2015-04-16
-4zcm,2015-07-29,2015-04-16
-5zcc,2018-12-26,2018-02-16
-1zcm,2006-01-31,2005-04-12
-3zcz,2013-03-27,2012-11-23
-2zcv,2008-05-27,2007-11-13
-4zcv,2015-07-22,2015-04-16
-5zc7,2019-02-20,2018-02-15
-1zca,2005-11-15,2005-04-11
-7zcl,2022-05-18,2022-03-28
-6zcj,2020-12-02,2020-06-11
-6zcx,2021-06-23,2020-06-12
-8zc4,2024-05-15,2024-04-28
-7zcs,2022-08-03,2022-03-28
-2zc1,2008-11-25,2007-11-02
-2zcs,2008-03-11,2007-11-11
-6zcn,2020-07-29,2020-06-11
-5zch,2019-03-06,2018-02-17
-6zck,2021-03-17,2020-06-11
-6zcr,2021-06-23,2020-06-12
-7zc3,2022-04-06,2022-03-25
-7zcb,2023-07-19,2022-03-26
-5zcr,2018-11-21,2018-02-20
-6zcw,2020-07-15,2020-06-12
-2zc2,2007-12-25,2007-11-02
-7zcc,2023-04-05,2022-03-27
-7zc0,2022-12-07,2022-03-25
-7zcd,2023-04-05,2022-03-27
-3zcj,2013-10-09,2012-11-20
-2zc9,2008-10-28,2007-11-06
-5zcp,2018-08-15,2018-02-19
-2zcz,2008-04-29,2007-11-15
-6zcy,2021-06-23,2020-06-12
-3zcy,2012-12-19,2012-11-23
-5zco,2018-08-15,2018-02-19
-3zcw,2013-01-23,2012-11-23
-3zct,2013-12-11,2012-11-21
-2zcu,2008-05-27,2007-11-13
-7zcm,2023-11-29,2022-03-28
-5zce,2018-12-26,2018-02-16
-5zc2,2018-08-08,2018-02-14
-3zc6,2013-09-25,2012-11-16
-6zc4,2021-06-23,2020-06-09
-3zc5,2013-11-27,2012-11-15
-2zc0,2008-06-17,2007-10-31
-4zcu,2015-07-22,2015-04-16
-8zc6,2024-05-29,2024-04-28
-5zcw,2018-08-22,2018-02-21
-3zcs,2013-12-11,2012-11-21
-5zca,2018-08-15,2018-02-16
-8zcm,2024-05-08,2024-04-30
-7zcz,2022-08-31,2022-03-29
-3zcr,2013-12-11,2012-11-21
-2zc4,2008-04-08,2007-11-02
-4zc9,2015-11-18,2015-04-15
-7zce,2022-10-12,2022-03-28
-7zcy,2023-04-19,2022-03-29
-3e77,2008-08-26,2008-08-18
-5e7h,2016-05-04,2015-10-12
-8e70,2022-09-07,2022-08-23
-8e7w,2023-03-29,2022-08-25
-5e7u,2016-03-23,2015-10-13
-2e7p,2007-09-25,2007-01-12
-1e7a,2001-01-17,2000-08-26
-7e7c,2022-04-06,2021-02-25
-4e7e,2013-03-20,2012-03-16
-4e7k,2012-05-23,2012-03-17
-2e7z,2007-02-27,2007-01-15
-4e7z,2012-09-19,2012-03-19
-3e73,2009-06-30,2008-08-17
-8e7y,2023-03-29,2022-08-25
-5e75,2016-05-04,2015-10-11
-1e7u,2000-11-17,2000-09-08
-4e7d,2013-03-20,2012-03-16
-7e78,2021-07-28,2021-02-25
-5e7r,2016-09-21,2015-10-13
-7e7d,2021-03-24,2021-02-25
-1e7l,2001-05-04,2000-08-29
-5e7o,2016-03-09,2015-10-12
-7e7m,2022-03-02,2021-02-26
-3e7t,2008-10-07,2008-08-18
-6e70,2019-07-31,2018-07-25
-5e7z,2016-06-01,2015-10-13
-3e7z,2009-02-24,2008-08-19
-2e7r,2007-07-17,2007-01-12
-3e7c,2008-11-25,2008-08-18
-3e7y,2009-02-24,2008-08-19
-1e79,2000-11-03,2000-08-25
-4e73,2013-05-29,2012-03-16
-7e7b,2021-03-24,2021-02-25
-3e78,2008-10-21,2008-08-18
-8e71,2023-07-05,2022-08-23
-4e7a,2012-04-18,2012-03-16
-3e7g,2008-10-07,2008-08-18
-8e73,2023-01-11,2022-08-23
-8e7p,2023-07-05,2022-08-24
-4e71,2012-03-28,2012-03-16
-3e7m,2008-10-07,2008-08-18
-2e7j,2007-07-17,2007-01-10
-8e7c,2023-03-29,2022-08-23
-3e70,2008-11-18,2008-08-17
-4e7r,2012-06-20,2012-03-19
-2e7t,2007-06-19,2007-01-13
-1e7b,2001-01-17,2000-08-26
-1e7d,2001-05-04,2000-08-28
-4e7v,2012-04-04,2012-03-19
-6e7s,2019-01-30,2018-07-27
-7e7e,2021-07-14,2021-02-26
-6e72,2019-07-31,2018-07-25
-5e76,2016-05-11,2015-10-11
-1e7v,2000-11-17,2000-09-08
-1e73,2001-01-05,2000-08-23
-8e7n,2023-03-29,2022-08-24
-7e7u,2021-04-14,2021-02-27
-5e7k,2016-01-27,2015-10-12
-5e70,2015-12-16,2015-10-11
-5e7n,2016-01-27,2015-10-12
-4e7u,2012-04-04,2012-03-19
-2e74,2007-06-12,2007-01-05
-6e77,2019-07-31,2018-07-25
-2e7u,2007-07-17,2007-01-14
-6e74,2019-07-31,2018-07-25
-2e77,2007-11-27,2007-01-06
-2e7f,2007-01-30,2007-01-09
-5e7m,2015-12-02,2015-10-12
-8e75,2022-11-23,2022-08-23
-5e79,2017-02-08,2015-10-12
-1e7w,2001-09-06,2000-09-11
-5e7j,2015-12-02,2015-10-12
-3e7f,2009-05-26,2008-08-18
-3e76,2009-08-25,2008-08-17
-7e71,2021-04-07,2021-02-24
-2e7x,2008-01-15,2007-01-15
-2e7y,2007-09-11,2007-01-15
-8e79,2023-03-22,2022-08-23
-8e7m,2022-09-28,2022-08-24
-2e73,2007-12-18,2007-01-05
-3e7i,2008-10-07,2008-08-18
-2e7w,2008-01-15,2007-01-15
-5e7p,2016-08-24,2015-10-12
-6e78,2019-07-31,2018-07-25
-3e7b,2008-11-04,2008-08-18
-6e73,2019-07-31,2018-07-25
-4e7c,2013-03-20,2012-03-16
-6e7h,2019-06-19,2018-07-26
-5e7y,2017-01-25,2015-10-13
-5e7c,2016-02-10,2015-10-12
-6e7r,2019-01-30,2018-07-27
-2e72,2007-07-10,2007-01-05
-6e7t,2019-01-30,2018-07-27
-4e7o,2012-05-23,2012-03-18
-6e7b,2018-10-10,2018-07-25
-1e71,2001-01-05,2000-08-23
-3e7s,2008-10-07,2008-08-18
-7e7q,2021-06-30,2021-02-26
-7e7o,2021-06-30,2021-02-26
-1e7z,2000-11-27,2000-09-13
-3e7l,2008-11-25,2008-08-18
-4e7b,2013-03-20,2012-03-16
-8e7a,2023-05-17,2022-08-23
-5e72,2016-07-06,2015-10-11
-5e7d,2016-10-12,2015-10-12
-7e7v,2021-04-14,2021-02-28
-7e7h,2022-03-02,2021-02-26
-6e7k,2018-12-19,2018-07-26
-4e7j,2012-05-23,2012-03-17
-6e7d,2018-10-24,2018-07-26
-8e7t,2023-08-30,2022-08-24
-1e7m,2000-12-11,2000-08-30
-7e7l,2021-07-28,2021-02-26
-6e7p,2018-11-28,2018-07-27
-8e7u,2023-08-30,2022-08-24
-6e7j,2018-11-07,2018-07-26
-5e7w,2016-10-12,2015-10-13
-4e7l,2012-05-23,2012-03-17
-7e7n,2021-04-14,2021-02-26
-8e74,2023-03-22,2022-08-23
-5e78,2016-09-28,2015-10-12
-6e7x,2019-01-30,2018-07-27
-4e77,2012-04-04,2012-03-16
-8e7x,2023-03-29,2022-08-25
-4e7p,2012-05-23,2012-03-18
-3e7v,2008-10-14,2008-08-19
-1e7s,2000-10-18,2000-09-07
-7e70,2021-04-07,2021-02-24
-3e7o,2008-09-09,2008-08-18
-1e72,2001-01-05,2000-08-23
-6e7z,2018-11-28,2018-07-27
-5e7t,2015-12-30,2015-10-13
-4e7t,2012-04-04,2012-03-19
-1e7c,2001-01-17,2000-08-26
-4e7n,2012-04-04,2012-03-18
-2e75,2007-06-12,2007-01-05
-3e7j,2008-12-30,2008-08-18
-2e7e,2007-06-19,2007-01-09
-8e7r,2023-06-14,2022-08-24
-2e7q,2007-06-19,2007-01-12
-8e7b,2023-05-17,2022-08-23
-7e7t,2021-04-14,2021-02-27
-6e7m,2019-10-16,2018-07-26
-4e7h,2012-05-23,2012-03-17
-8e7s,2023-05-24,2022-08-24
-8e72,2023-06-21,2022-08-23
-6e7v,2019-01-30,2018-07-27
-5e73,2015-10-28,2015-10-11
-6e7g,2019-06-19,2018-07-26
-3e7a,2008-11-04,2008-08-18
-7e7s,2021-09-08,2021-02-27
-1e7q,2000-10-18,2000-09-07
-7e7r,2021-04-14,2021-02-27
-2e7i,2007-07-17,2007-01-10
-5e74,2015-10-21,2015-10-11
-1e7y,2000-12-11,2000-09-12
-7e7f,2022-01-05,2021-02-26
-4e7s,2012-09-19,2012-03-19
-1e70,2001-01-05,2000-08-23
-2e7l,2007-04-24,2007-01-11
-6e7i,2020-01-29,2018-07-26
-3e7x,2008-09-09,2008-08-19
-6e7y,2018-11-28,2018-07-27
-4e78,2012-04-18,2012-03-16
-8e7v,2023-11-08,2022-08-24
-3e79,2008-10-21,2008-08-18
-6e7u,2019-01-30,2018-07-27
-1e7p,2001-04-09,2000-09-01
-8e7f,2023-03-08,2022-08-23
-7e74,2021-07-07,2021-02-25
-1e77,2000-12-11,2000-08-24
-4e7i,2012-05-23,2012-03-17
-4e70,2013-05-01,2012-03-16
-7e7i,2021-06-30,2021-02-26
-3e7w,2008-09-09,2008-08-19
-8e77,2022-11-23,2022-08-23
-6e7w,2019-01-30,2018-07-27
-3e74,2009-02-24,2008-08-17
-4e7f,2013-03-20,2012-03-16
-2e76,2007-06-12,2007-01-05
-1e7r,2000-10-18,2000-09-07
-5e7g,2016-05-04,2015-10-12
-8e7q,2023-06-14,2022-08-24
-6e7c,2018-10-10,2018-07-25
-1kc3,2002-06-28,2001-11-07
-7kcb,2021-03-31,2020-10-05
-5kcz,2016-06-29,2016-06-07
-1kcd,2002-06-05,2001-11-08
-6kcq,2019-07-10,2019-06-28
-7kc1,2021-05-12,2020-10-04
-7kcy,2021-06-30,2020-10-07
-5kc1,2016-10-05,2016-06-04
-6kcw,2020-06-24,2019-06-29
-6kcn,2020-04-08,2019-06-28
-1kcw,1997-02-12,1996-09-25
-5kcr,2016-08-17,2016-06-06
-5kc4,2016-06-29,2016-06-04
-4kcu,2014-01-08,2013-04-24
-4kc4,2013-09-11,2013-04-24
-4kcf,2013-05-22,2013-04-24
-5kce,2016-11-16,2016-06-06
-7kcw,2021-06-30,2020-10-07
-1kce,1997-04-21,1996-10-22
-4kcq,2014-02-12,2013-04-24
-6kcp,2020-07-01,2019-06-28
-8kc2,2024-01-31,2023-08-05
-4kct,2014-01-08,2013-04-24
-3kcu,2009-12-01,2009-10-22
-3kco,2010-06-16,2009-10-21
-7kc7,2021-01-27,2020-10-05
-6kck,2020-02-12,2019-06-28
-5kcx,2017-07-19,2016-06-07
-3kce,2009-12-22,2009-10-21
-1kc7,2002-01-30,2001-11-07
-4kc7,2014-02-05,2013-04-24
-7kcz,2021-10-13,2020-10-07
-8kcz,2023-08-30,2023-08-08
-3kcl,2010-06-16,2009-10-21
-7kc3,2021-10-06,2020-10-05
-5kcf,2016-11-16,2016-06-06
-4kck,2014-02-12,2013-04-24
-3kc2,2009-11-24,2009-10-20
-4kc9,2013-05-29,2013-04-24
-3kcz,2009-11-10,2009-10-22
-1kcz,2001-12-19,2001-11-12
-7kcs,2021-05-19,2020-10-07
-6kc5,2020-04-15,2019-06-27
-6kcd,2020-05-20,2019-06-27
-1kc5,2002-07-24,2001-11-07
-7kcf,2021-04-21,2020-10-05
-6kc0,2020-07-01,2019-06-26
-4kcv,2014-01-08,2013-04-24
-6kcm,2020-02-12,2019-06-28
-5kci,2016-09-21,2016-06-06
-4kca,2014-02-05,2013-04-24
-1kc8,2003-07-22,2001-11-07
-4kci,2014-02-12,2013-04-24
-4kcw,2014-01-08,2013-04-24
-6kcl,2020-02-12,2019-06-28
-7kct,2021-01-27,2020-10-07
-5kc9,2016-07-27,2016-06-05
-4kcs,2014-02-12,2013-04-24
-7kcm,2021-10-13,2020-10-06
-6kc6,2020-04-15,2019-06-27
-1kcs,2002-05-11,2001-11-11
-1kcl,2002-01-16,2001-11-09
-6kc4,2019-09-04,2019-06-27
-5kcu,2016-11-16,2016-06-07
-4kch,2014-02-12,2013-04-24
-7kcp,2020-10-21,2020-10-07
-5kcs,2016-08-17,2016-06-06
-3kc3,2010-01-12,2009-10-20
-7kc2,2021-03-31,2020-10-04
-6kco,2020-07-01,2019-06-28
-5kcd,2016-11-16,2016-06-06
-1kcc,2002-06-05,2001-11-08
-4kcr,2014-02-12,2013-04-24
-3kcx,2010-04-28,2009-10-22
-7kcr,2020-12-16,2020-10-07
-3kcf,2009-12-22,2009-10-21
-7kce,2021-04-21,2020-10-05
-1kc2,2002-04-17,2001-11-07
-5kcp,2016-06-29,2016-06-06
-7kco,2021-04-21,2020-10-06
-4kcl,2014-02-12,2013-04-24
-7kc4,2021-01-06,2020-10-05
-5kcq,2016-12-21,2016-06-06
-4kcm,2014-02-12,2013-04-24
-5kcv,2016-06-29,2016-06-07
-7kcq,2021-03-31,2020-10-07
-5kc8,2016-07-27,2016-06-05
-7kcc,2021-04-21,2020-10-05
-4kcp,2014-02-12,2013-04-24
-1kcb,2003-11-04,2001-11-07
-5kcl,2016-12-21,2016-06-06
-6kcv,2020-06-24,2019-06-29
-1kc6,2001-12-07,2001-11-07
-7kcl,2021-10-13,2020-10-06
-7kc6,2021-10-06,2020-10-05
-7kc5,2021-10-06,2020-10-05
-5kcm,2017-01-11,2016-06-06
-7kch,2021-01-13,2020-10-05
-6kcz,2019-07-17,2019-06-30
-3kc0,2010-02-02,2009-10-20
-7kc0,2020-12-02,2020-10-04
-3kck,2009-11-24,2009-10-21
-4kc1,2013-09-11,2013-04-24
-7kcx,2021-06-30,2020-10-07
-4kcx,2013-09-18,2013-04-24
-6kcx,2020-04-29,2019-06-29
-5kc0,2016-06-29,2016-06-03
-8kcm,2023-11-22,2023-08-08
-4kcg,2014-03-12,2013-04-24
-6kca,2020-05-20,2019-06-27
-5kct,2016-11-16,2016-06-07
-6kcc,2020-05-20,2019-06-27
-4kc3,2013-08-28,2013-04-24
-2kce,1997-11-19,1997-06-09
-6kcj,2019-10-30,2019-06-28
-3kcc,2009-11-17,2009-10-21
-4kcn,2014-02-12,2013-04-24
-5kc6,2016-07-27,2016-06-05
-3kc1,2010-02-02,2009-10-20
-7kcv,2021-06-30,2020-10-07
-1kcq,2002-01-04,2001-11-09
-1kck,2002-01-16,2001-11-09
-5kca,2016-07-27,2016-06-05
-4kcj,2014-02-12,2013-04-24
-5kc5,2016-07-27,2016-06-05
-7kc9,2021-08-04,2020-10-05
-6kct,2020-04-08,2019-06-29
-3kcy,2010-04-28,2009-10-22
-1kc1,2002-06-28,2001-11-07
-7kck,2021-10-13,2020-10-06
-4kco,2014-02-12,2013-04-24
-5kcb,2016-08-24,2016-06-06
-5kcy,2016-12-21,2016-06-07
-4kc8,2014-02-05,2013-04-24
-1kcg,2002-01-09,2001-11-08
-6kcb,2020-05-20,2019-06-27
-5kcc,2016-11-16,2016-06-06
-5kcw,2016-11-16,2016-06-07
-5kcj,2016-07-13,2016-06-06
-3kcp,2010-02-09,2009-10-21
-4kc6,2014-03-12,2013-04-24
-4kc2,2013-09-11,2013-04-24
-7kcu,2021-10-13,2020-10-07
-6kc2,2020-08-05,2019-06-26
-1ori,2003-05-27,2003-03-13
-5or3,2018-05-09,2017-08-15
-3orc,1998-12-02,1998-04-23
-7or7,2022-07-20,2021-06-04
-3or1,2010-09-22,2010-09-06
-3orw,2011-09-21,2010-09-07
-3orm,2010-12-15,2010-09-07
-5or9,2017-09-13,2017-08-15
-7orf,2021-07-21,2021-06-05
-5orl,2017-11-01,2017-08-16
-6or3,2020-05-20,2019-04-29
-2orq,2007-04-17,2007-02-04
-4orv,2014-03-05,2014-02-12
-4orc,2015-05-20,2014-02-11
-3orh,2010-09-15,2010-09-07
-5or8,2017-09-13,2017-08-15
-6or5,2019-05-29,2019-04-29
-2orw,2007-03-27,2007-02-04
-5orh,2018-02-28,2017-08-16
-7orl,2022-02-16,2021-06-06
-5or5,2018-06-27,2017-08-15
-5or6,2018-06-27,2017-08-15
-1orw,2003-05-06,2003-03-16
-8orq,2024-04-24,2023-04-17
-5orx,2017-11-01,2017-08-16
-6orm,2020-05-06,2019-04-30
-2orz,2007-04-03,2007-02-05
-5ork,2018-02-28,2017-08-16
-1or4,2003-09-23,2003-03-11
-5ort,2017-11-01,2017-08-16
-7or5,2022-07-20,2021-06-04
-4or5,2014-04-16,2014-02-10
-3orv,2010-11-10,2010-09-07
-6orh,2019-07-10,2019-04-30
-7org,2022-06-22,2021-06-05
-7ory,2022-06-22,2021-06-06
-1ord,1995-09-15,1995-02-08
-5orn,2017-11-01,2017-08-16
-7ork,2022-02-16,2021-06-06
-6ori,2020-05-13,2019-04-30
-6orr,2019-10-23,2019-04-30
-8orm,2023-08-30,2023-04-14
-3orf,2011-07-27,2010-09-07
-2orr,2007-04-17,2007-02-04
-3orl,2010-12-15,2010-09-07
-7or4,2021-07-07,2021-06-04
-5orp,2017-11-01,2017-08-16
-2ors,2007-04-17,2007-02-04
-7or8,2022-06-22,2021-06-04
-6orq,2019-06-12,2019-04-30
-8ori,2023-08-09,2023-04-14
-7or1,2022-06-22,2021-06-04
-4or4,2015-02-25,2014-02-10
-7orq,2022-06-22,2021-06-06
-6ord,2020-06-24,2019-04-30
-8oro,2024-01-17,2023-04-15
-7or9,2021-07-07,2021-06-04
-5orf,2017-11-15,2017-08-16
-3ord,2011-09-07,2010-09-06
-6or8,2019-10-16,2019-04-29
-8ors,2024-04-17,2023-04-17
-2ori,2008-01-15,2007-02-02
-7orj,2022-02-16,2021-06-06
-5ory,2017-11-01,2017-08-16
-5ors,2017-11-01,2017-08-16
-6ore,2019-06-19,2019-04-30
-8orc,2024-04-24,2023-04-13
-1orr,2003-08-26,2003-03-14
-6oru,2020-07-01,2019-05-01
-8orw,2023-12-20,2023-04-17
-4oro,2015-05-20,2014-02-11
-1orp,2003-07-15,2003-03-14
-3oru,2010-10-13,2010-09-07
-3orj,2010-10-13,2010-09-07
-3orq,2011-07-20,2010-09-07
-6or1,2019-08-28,2019-04-29
-5orw,2017-11-01,2017-08-16
-7oru,2021-10-20,2021-06-06
-3orz,2011-03-23,2010-09-08
-4or7,2014-12-03,2014-02-11
-6org,2019-07-10,2019-04-30
-7orh,2022-06-22,2021-06-05
-7orx,2021-06-16,2021-06-06
-3orp,2010-12-15,2010-09-07
-3orx,2011-03-23,2010-09-08
-7orm,2022-02-16,2021-06-06
-6or7,2019-07-24,2019-04-29
-5oro,2017-11-01,2017-08-16
-7orv,2021-10-20,2021-06-06
-6orf,2019-07-10,2019-04-30
-4or0,2014-06-04,2014-02-10
-4or2,2014-03-19,2014-02-10
-8ork,2023-12-06,2023-04-14
-4ori,2014-06-04,2014-02-11
-8orv,2023-12-20,2023-04-17
-8or7,2024-03-20,2023-04-13
-3ori,2010-12-15,2010-09-07
-6ora,2019-08-21,2019-04-29
-1ork,1999-06-15,1998-05-21
-1orv,2003-05-06,2003-03-16
-2orl,2007-04-24,2007-02-03
-3or6,2011-01-05,2010-09-06
-2orp,2007-04-10,2007-02-04
-4or9,2015-05-20,2014-02-11
-8or1,2023-08-02,2023-04-12
-3oro,2010-12-15,2010-09-07
-1orq,2003-05-06,2003-03-14
-7orc,2021-09-01,2021-06-05
-2ork,2007-05-08,2007-02-02
-7ore,2021-07-21,2021-06-05
-4orh,2014-02-26,2014-02-11
-7or3,2022-06-22,2021-06-04
-5orj,2018-02-28,2017-08-16
-5or7,2018-03-21,2017-08-15
-5org,2017-12-20,2017-08-16
-2orj,2007-05-08,2007-02-02
-1orn,2003-07-15,2003-03-14
-8orp,2023-08-16,2023-04-16
-5orb,2017-09-13,2017-08-15
-6orp,2019-06-12,2019-04-30
-2ord,2007-02-13,2007-02-02
-8or9,2023-08-30,2023-04-13
-3or7,2011-01-05,2010-09-06
-2ore,2007-06-26,2007-02-02
-6orn,2019-06-12,2019-04-30
-4orb,2015-05-20,2014-02-11
-1ore,2004-03-30,2003-03-12
-5or4,2018-05-09,2017-08-15
-1orf,2003-07-01,2003-03-12
-5orz,2017-11-01,2017-08-16
-5orv,2017-11-01,2017-08-16
-1or6,2003-09-23,2003-03-11
-3or2,2010-09-22,2010-09-06
-2oro,2007-04-10,2007-02-04
-4or6,2015-02-25,2014-02-11
-7ori,2022-02-16,2021-06-06
-2orv,2007-03-27,2007-02-04
-5or2,2018-06-27,2017-08-15
-6orl,2019-06-19,2019-04-30
-6orv,2020-01-08,2019-05-01
-8orh,2024-04-17,2023-04-14
-8orl,2023-08-23,2023-04-14
-6or4,2019-07-10,2019-04-29
-7or2,2021-11-03,2021-06-04
-4orm,2014-06-04,2014-02-11
-2or4,2007-06-12,2007-02-01
-7orr,2021-10-20,2021-06-06
-3or3,2010-10-20,2010-09-06
-5orr,2017-11-01,2017-08-16
-3ort,2010-12-15,2010-09-07
-3orn,2011-03-02,2010-09-07
-8or2,2023-06-28,2023-04-12
-8ora,2023-08-30,2023-04-13
-8or3,2023-06-28,2023-04-13
-2ort,2007-04-17,2007-02-04
-8ord,2023-08-02,2023-04-13
-7orp,2022-06-22,2021-06-06
-7orn,2022-02-16,2021-06-06
-8or0,2023-06-28,2023-04-12
-4ore,2015-02-11,2014-02-11
-7ort,2022-06-22,2021-06-06
-8oru,2023-12-06,2023-04-17
-7orb,2021-07-07,2021-06-04
-7ors,2022-06-22,2021-06-06
-7orz,2021-11-03,2021-06-06
-8or6,2023-08-09,2023-04-13
-7ora,2021-07-07,2021-06-04
-3ork,2010-12-15,2010-09-07
-7or0,2022-06-22,2021-06-04
-6orj,2019-06-19,2019-04-30
-7oro,2022-02-16,2021-06-06
-8orr,2024-04-24,2023-04-17
-6oro,2019-06-12,2019-04-30
-4ork,2014-07-02,2014-02-11
-7orw,2021-10-20,2021-06-06
-4ora,2015-05-20,2014-02-11
-4zia,2015-07-29,2015-04-28
-5zie,2018-09-19,2018-03-14
-3ziu,2013-02-27,2013-01-10
-3ziy,2013-03-27,2013-01-14
-3zi0,2013-10-09,2012-12-30
-6zie,2021-04-28,2020-06-25
-7zip,2022-12-21,2022-04-08
-5ziy,2018-10-17,2018-03-18
-2zis,2009-02-24,2008-02-22
-7ziy,2023-02-22,2022-04-08
-7zik,2022-09-07,2022-04-08
-4zi6,2015-12-23,2015-04-27
-4zi2,2015-11-11,2015-04-27
-7zii,2022-09-07,2022-04-08
-7ziu,2023-04-19,2022-04-08
-5zib,2018-08-01,2018-03-14
-3zia,2013-02-13,2013-01-07
-6zi8,2021-01-20,2020-06-25
-2zir,2009-02-24,2008-02-22
-7zin,2022-12-21,2022-04-08
-7zij,2022-09-07,2022-04-08
-1zi1,2005-12-13,2005-04-26
-6zia,2020-12-09,2020-06-25
-3zi6,2013-05-01,2013-01-04
-7zib,2023-06-07,2022-04-07
-4zi7,2016-07-27,2015-04-27
-2zia,2008-07-08,2008-02-13
-4zi1,2016-06-29,2015-04-27
-5zi6,2018-10-24,2018-03-14
-7zih,2022-09-07,2022-04-08
-5zit,2019-04-17,2018-03-17
-3ziq,2013-08-21,2013-01-10
-2zim,2008-03-04,2008-02-19
-3zid,2013-08-14,2013-01-08
-5zia,2018-10-31,2018-03-14
-6zio,2020-08-19,2020-06-26
-5zi8,2018-10-17,2018-03-14
-3zio,2013-08-21,2013-01-10
-2zik,2009-01-06,2008-02-18
-7ziw,2023-04-19,2022-04-08
-1zi5,2005-12-13,2005-04-26
-7zi8,2023-06-07,2022-04-07
-7ziz,2023-02-22,2022-04-08
-4zil,2015-11-18,2015-04-28
-5zix,2019-03-20,2018-03-17
-2zi7,2008-07-08,2008-02-13
-7zi6,2023-06-07,2022-04-07
-4zip,2015-07-15,2015-04-28
-6zif,2022-01-12,2020-06-25
-7zi9,2023-06-07,2022-04-07
-3zim,2013-02-13,2013-01-09
-6zi2,2020-10-21,2020-06-24
-6zij,2021-05-05,2020-06-26
-7zig,2022-09-07,2022-04-08
-2zif,2008-07-29,2008-02-15
-2ziq,2009-01-13,2008-02-20
-3zip,2013-08-21,2013-01-10
-5zi2,2018-10-24,2018-03-14
-7zit,2022-10-26,2022-04-08
-7zix,2023-04-19,2022-04-08
-2zic,2008-06-24,2008-02-14
-6zip,2021-05-05,2020-06-26
-5zid,2019-03-20,2018-03-14
-1zid,1998-03-25,1997-03-25
-4zic,2016-03-02,2015-04-28
-1ziv,2005-07-05,2005-04-27
-1zis,2006-10-03,2005-04-27
-2zi8,2009-02-24,2008-02-13
-7zim,2022-12-21,2022-04-08
-3zin,2013-08-21,2013-01-10
-4ziz,2015-08-19,2015-04-28
-7zi2,2023-06-07,2022-04-07
-1zin,1997-06-16,1996-06-07
-1ziw,2005-06-28,2005-04-27
-4zi8,2015-10-28,2015-04-27
-5zi7,2018-09-19,2018-03-14
-4ziy,2015-05-20,2015-04-28
-3zi4,2014-01-15,2013-01-03
-7zi3,2023-06-07,2022-04-07
-3zir,2013-08-21,2013-01-10
-2ziy,2008-05-06,2008-02-27
-2ziz,2008-09-16,2008-02-29
-7zid,2022-08-31,2022-04-07
-5zim,2018-10-10,2018-03-16
-6zis,2020-07-15,2020-06-26
-4zim,2015-06-03,2015-04-28
-4zij,2016-05-11,2015-04-28
-6zic,2021-07-07,2020-06-25
-5zi4,2018-10-24,2018-03-14
-3zi8,2013-07-31,2013-01-07
-2zi9,2008-07-08,2008-02-13
-1ziz,2005-12-13,2005-04-27
-5ziq,2019-01-02,2018-03-16
-7zia,2023-06-07,2022-04-07
-4zi0,2015-05-13,2015-04-27
-6ziw,2020-07-22,2020-06-26
-4zir,2015-06-10,2015-04-28
-7zi0,2022-06-15,2022-04-07
-4zix,2015-08-12,2015-04-28
-4zi3,2016-03-23,2015-04-27
-6zii,2021-02-17,2020-06-26
-6zi6,2020-12-09,2020-06-24
-4zi4,2015-10-28,2015-04-27
-7zil,2022-12-21,2022-04-08
-6ziv,2020-07-29,2020-06-26
-2zi5,2008-04-22,2008-02-13
-4zib,2016-03-02,2015-04-28
-6zi9,2020-12-09,2020-06-25
-2zij,2009-01-06,2008-02-18
-2zio,2008-12-02,2008-02-19
-5zic,2018-08-01,2018-03-14
-6zid,2020-12-09,2020-06-25
-1zia,1997-04-01,1996-04-09
-7zif,2022-09-07,2022-04-08
-3zi7,2013-05-01,2013-01-04
-7ziv,2023-04-19,2022-04-08
-5zii,2019-03-20,2018-03-15
-2zid,2008-06-24,2008-02-14
-2zi4,2008-04-22,2008-02-13
-1zi3,2005-12-13,2005-04-26
-4zid,2016-02-10,2015-04-28
-4zi5,2016-02-17,2015-04-27
-1zip,1997-08-20,1997-05-07
-6ziz,2020-08-19,2020-06-26
-1ziu,2005-12-20,2005-04-27
-6zi5,2020-12-09,2020-06-24
-6zi3,2020-10-21,2020-06-24
-6zi7,2020-10-21,2020-06-25
-7ziq,2022-12-21,2022-04-08
-2zit,2008-06-24,2008-02-24
-2zi6,2008-04-22,2008-02-13
-7zi1,2023-06-07,2022-04-07
-5zin,2018-10-10,2018-03-16
-5zio,2019-03-20,2018-03-16
-4ziu,2015-06-10,2015-04-28
-7zio,2022-12-21,2022-04-08
-6zix,2021-02-17,2020-06-26
-6zi4,2020-12-09,2020-06-24
-5zil,2018-10-10,2018-03-16
-2zi3,2008-04-22,2008-02-13
-7zi7,2023-06-07,2022-04-07
-4zi9,2015-10-28,2015-04-27
-2zin,2008-12-02,2008-02-19
-1zio,1997-07-07,1996-06-07
-4zit,2016-07-27,2015-04-28
-7zi4,2023-04-19,2022-04-07
-1zi4,2005-12-13,2005-04-26
-6zin,2021-02-10,2020-06-26
-2zil,2009-01-06,2008-02-18
-6ziy,2020-09-02,2020-06-26
-7zic,2023-04-19,2022-04-07
-6zib,2021-07-07,2020-06-25
-1zib,1997-04-01,1996-04-09
-7zi5,2023-06-07,2022-04-07
-2zi2,2009-01-13,2008-02-13
-5zi5,2018-09-19,2018-03-14
-6zir,2020-08-19,2020-06-26
-4ziw,2016-07-27,2015-04-28
-4ziv,2016-07-27,2015-04-28
-12gs,1999-01-13,1997-11-19
-6nnz,2020-01-22,2019-01-15
-4nns,2014-11-19,2013-11-19
-6nna,2019-02-20,2019-01-14
-6nn1,2019-04-10,2019-01-14
-3nnz,2010-10-06,2010-06-24
-6nny,2019-01-30,2019-01-15
-6nnr,2019-01-30,2019-01-15
-7nny,2021-06-30,2021-02-25
-6nns,2019-04-10,2019-01-15
-7nnq,2021-06-30,2021-02-25
-2nng,2007-05-08,2006-10-24
-7nn2,2022-01-12,2021-02-24
-4nnn,2014-02-12,2013-11-18
-5nns,2018-05-16,2017-04-10
-2nns,2007-05-08,2006-10-24
-3nnb,2010-10-06,2010-06-23
-3nn3,2010-07-28,2010-06-23
-1nn1,2003-03-18,2003-01-12
-7nnp,2021-07-28,2021-02-25
-5nnw,2017-12-27,2017-04-10
-7nn8,2021-06-30,2021-02-24
-5nn0,2018-03-14,2017-04-07
-1nn0,2003-03-18,2003-01-12
-4nnw,2014-02-12,2013-11-19
-7nnd,2022-01-12,2021-02-24
-6nn9,1992-07-15,1991-03-28
-7nnb,2021-06-30,2021-02-24
-6nng,2019-07-10,2019-01-15
-6nn4,2019-06-19,2019-01-14
-3nng,2010-08-18,2010-06-23
-1nnw,2003-02-11,2003-01-14
-1nns,2003-03-11,2003-01-14
-1nne,2003-05-20,2003-01-13
-7nnr,2021-06-30,2021-02-25
-3nnl,2010-07-28,2010-06-23
-5nn4,2017-10-25,2017-04-08
-3nns,2010-08-11,2010-06-24
-3nn0,2011-06-15,2010-06-23
-4nnm,2015-01-21,2013-11-18
-3nn1,2010-07-28,2010-06-23
-1nnf,2003-04-01,2003-01-13
-2nnq,2007-06-12,2006-10-24
-4nnt,2014-11-19,2013-11-19
-4nna,2014-03-19,2013-11-17
-7nnk,2022-11-16,2021-02-25
-6nnf,2019-02-27,2019-01-14
-6nnd,2019-07-17,2019-01-14
-1nny,2003-04-08,2003-01-14
-3nne,2010-07-28,2010-06-23
-2nnh,2007-10-23,2006-10-24
-7nne,2022-01-12,2021-02-24
-5nn5,2017-10-25,2017-04-08
-3nnt,2010-07-28,2010-06-24
-6nno,2019-04-10,2019-01-15
-2nno,2007-05-08,2006-10-24
-4nnd,2014-11-19,2013-11-17
-1nn2,1992-07-15,1991-03-28
-1nnb,1994-04-30,1993-03-08
-3nnu,2010-09-15,2010-06-24
-1nnk,2003-03-04,2003-01-14
-1nnc,1996-04-03,1995-03-15
-7nnj,2022-03-23,2021-02-24
-3nn4,2010-07-28,2010-06-23
-3nnq,2010-07-14,2010-06-24
-1nn6,2003-03-04,2003-01-12
-4nnr,2014-02-05,2013-11-18
-3nn9,1992-07-15,1991-03-28
-1nn7,2003-07-15,2003-01-13
-5nnb,2018-05-16,2017-04-08
-3nna,2010-10-27,2010-06-23
-2nnk,2007-03-13,2006-10-24
-3nn2,2010-07-28,2010-06-23
-6nnu,2019-04-10,2019-01-15
-5nn8,2017-10-25,2017-04-08
-4nnj,2014-05-07,2013-11-18
-2nnv,2007-05-08,2006-10-24
-5nn6,2017-10-25,2017-04-08
-2nnj,2007-10-23,2006-10-24
-6nnh,2019-07-17,2019-01-15
-5nnp,2017-06-14,2017-04-10
-2nnd,2007-10-30,2006-10-24
-1nnh,2004-02-03,2003-01-13
-4nn9,1992-07-15,1991-03-28
-5nnj,2017-11-29,2017-04-09
-1nna,1994-04-30,1993-03-08
-3nnw,2010-09-15,2010-06-24
-6nn0,2020-01-22,2019-01-14
-6nnn,2019-04-10,2019-01-15
-3nnn,2010-08-11,2010-06-23
-5nn2,2018-02-21,2017-04-07
-6nnw,2019-10-23,2019-01-15
-6nn2,2019-04-10,2019-01-14
-2nnb,2007-09-11,2006-10-24
-7nng,2021-04-07,2021-02-24
-4nnc,2014-03-19,2013-11-17
-2nne,2007-10-30,2006-10-24
-6nnj,2019-02-27,2019-01-15
-6nnt,2019-04-10,2019-01-15
-1nn3,2003-03-18,2003-01-12
-4nny,2014-11-19,2013-11-19
-6nnp,2019-04-10,2019-01-15
-5nnd,2018-05-16,2017-04-08
-1nn5,2003-03-18,2003-01-12
-1nnt,1994-10-15,1993-09-15
-4nni,2014-12-24,2013-11-18
-4nn5,2014-03-19,2013-11-16
-7nn0,2021-03-24,2021-02-23
-6nnv,2019-02-20,2019-01-15
-1nno,1999-04-27,1998-07-20
-1nnl,2003-06-03,2003-01-14
-5nna,2018-05-16,2017-04-08
-7nn9,1996-04-03,1995-03-15
-7nns,2021-04-07,2021-02-25
-3nno,2010-07-21,2010-06-24
-4nn2,2014-02-26,2013-11-16
-5nnc,2018-05-16,2017-04-08
-4nnb,2014-03-19,2013-11-17
-6nnc,2019-07-17,2019-01-14
-2nnx,2006-11-07,2006-10-24
-6nni,2019-07-17,2019-01-15
-5nn9,1992-07-15,1991-03-28
-1nni,2003-07-29,2003-01-13
-7nnz,2021-06-30,2021-02-25
-4nnl,2015-01-21,2013-11-18
-2nnl,2007-11-13,2006-10-24
-5nni,2017-11-29,2017-04-09
-1nnp,2003-03-11,2003-01-14
-4nno,2014-11-26,2013-11-18
-6nne,2019-07-17,2019-01-14
-5nnt,2018-01-24,2017-04-10
-7nnl,2021-07-28,2021-02-25
-2nni,2007-10-23,2006-10-24
-2nn5,2006-11-21,2006-10-23
-2nn8,2007-03-06,2006-10-24
-4nn3,2013-12-04,2013-11-16
-2nn1,2007-04-24,2006-10-23
-7nnx,2021-07-21,2021-02-25
-3nnf,2010-07-28,2010-06-23
-4nnx,2014-11-19,2013-11-19
-7nn4,2021-06-30,2021-02-24
-5nn3,2017-10-25,2017-04-08
-1nnj,2003-02-11,2003-01-14
-3nn7,2011-05-25,2010-06-23
-3nny,2010-10-06,2010-06-24
-3nn6,2011-03-23,2010-06-23
-1nnr,2004-01-27,2003-01-14
-3nnx,2010-09-15,2010-06-24
-7nn7,2021-06-30,2021-02-24
-2nnp,2007-03-13,2006-10-24
-7nnc,2021-06-30,2021-02-24
-3nnc,2010-10-27,2010-06-23
-2nn7,2007-05-08,2006-10-23
-5nnf,2018-05-16,2017-04-08
-1nnu,2003-02-25,2003-01-14
-7nnw,2021-06-30,2021-02-25
-6nnx,2019-01-30,2019-01-15
-5nno,2017-04-19,2017-04-10
-1nnq,2004-03-02,2003-01-14
-3nnv,2010-09-15,2010-06-24
-6wyh,2020-11-11,2020-05-12
-6wy8,2021-03-24,2020-05-12
-4wy1,2015-03-04,2014-11-14
-8wyf,2024-04-10,2023-10-30
-5wyi,2018-01-17,2017-01-13
-7wyi,2023-02-22,2022-02-16
-3wye,2015-08-26,2014-08-26
-6wyz,2020-10-14,2020-05-13
-4wya,2015-07-15,2014-11-17
-7wyx,2022-04-27,2022-02-16
-3wyj,2015-02-04,2014-08-29
-3wyp,2014-12-24,2014-09-05
-5wyz,2017-12-13,2017-01-16
-4wyb,2015-08-19,2014-11-17
-2wyt,2010-10-27,2009-11-20
-6wy1,2021-11-10,2020-05-12
-6wyr,2020-07-29,2020-05-13
-6wyl,2021-02-17,2020-05-13
-2wyo,2010-01-19,2009-11-17
-3wya,2014-12-24,2014-08-22
-3wy4,2015-06-10,2014-08-18
-2wy0,2010-10-20,2009-11-11
-4wy3,2015-02-18,2014-11-15
-7wyu,2022-04-27,2022-02-16
-4wyz,2015-11-18,2014-11-18
-7wyp,2022-06-22,2022-02-16
-7wyg,2022-12-21,2022-02-16
-4wy2,2014-11-26,2014-11-15
-1wyh,2005-08-14,2005-02-14
-7wyv,2022-04-27,2022-02-16
-1wy9,2006-02-21,2005-02-09
-5wyx,2017-12-13,2017-01-16
-8wyp,2024-05-22,2023-10-31
-4wyc,2015-07-08,2014-11-17
-3wy6,2015-09-16,2014-08-20
-3wyk,2014-11-19,2014-09-01
-7wyz,2022-04-27,2022-02-16
-6wyp,2020-09-02,2020-05-13
-6wyx,2020-10-14,2020-05-13
-6wyj,2021-02-17,2020-05-13
-3wyl,2014-11-19,2014-09-01
-7wym,2022-06-22,2022-02-16
-1wyv,2005-04-05,2005-02-17
-7wyl,2022-06-22,2022-02-16
-3wyc,2015-05-06,2014-08-25
-2wyk,2011-01-26,2009-11-16
-6wyu,2020-09-16,2020-05-13
-3wym,2014-11-19,2014-09-01
-6wyo,2020-09-02,2020-05-13
-3wyg,2014-11-12,2014-08-26
-2wy3,2010-02-02,2009-11-11
-3wy9,2014-12-24,2014-08-22
-3wyo,2014-11-19,2014-09-04
-8wy0,2024-05-08,2023-10-30
-2wyh,2010-02-16,2009-11-16
-8wy3,2024-01-24,2023-10-30
-6wy4,2020-05-27,2020-05-12
-8wy5,2024-02-28,2023-10-30
-2wyw,2010-11-24,2009-11-20
-5wy0,2018-01-17,2017-01-10
-6wyi,2020-07-29,2020-05-13
-4wyp,2015-11-18,2014-11-17
-2wyg,2010-12-01,2009-11-16
-7wyf,2023-02-22,2022-02-16
-1wyg,2005-05-31,2005-02-14
-3wyw,2015-01-14,2014-09-09
-6wyc,2020-11-04,2020-05-12
-2wyp,2011-01-26,2009-11-18
-8wyb,2024-04-10,2023-10-30
-4wy6,2015-03-04,2014-11-15
-5wy5,2017-05-03,2017-01-11
-6wy5,2020-10-14,2020-05-12
-6wyk,2021-02-17,2020-05-13
-3wy1,2015-06-10,2014-08-18
-2wyv,2010-11-24,2009-11-20
-4wyu,2015-10-21,2014-11-18
-2wyr,2010-12-01,2009-11-20
-7wy2,2023-01-04,2022-02-15
-7wy4,2023-01-04,2022-02-15
-4wyy,2015-08-05,2014-11-18
-5wyr,2017-12-20,2017-01-15
-6wyy,2020-10-14,2020-05-13
-6wye,2021-06-09,2020-05-12
-8wy7,2024-01-24,2023-10-30
-4wyg,2015-07-08,2014-11-17
-5wy1,2017-05-24,2017-01-10
-2wys,2010-08-25,2009-11-20
-3wyx,2015-04-08,2014-09-09
-1wyu,2005-04-05,2005-02-17
-2wyu,2010-11-24,2009-11-20
-1wy2,2005-02-22,2005-02-04
-7wy3,2023-01-04,2022-02-15
-3wyf,2014-11-12,2014-08-26
-1wy0,2006-02-14,2005-02-03
-2wyn,2010-09-29,2009-11-17
-1wyx,2005-04-26,2005-02-17
-2wyj,2010-12-01,2009-11-16
-6wyq,2020-09-02,2020-05-13
-8wyg,2024-01-24,2023-10-30
-7wy1,2023-01-04,2022-02-15
-8wyc,2024-04-10,2023-10-30
-2wyc,2009-12-29,2009-11-16
-3wy2,2015-06-10,2014-08-18
-5wya,2017-04-19,2017-01-11
-4wye,2015-07-08,2014-11-17
-2wy6,2009-11-24,2009-11-12
-3wyq,2014-12-24,2014-09-05
-7wyy,2022-04-27,2022-02-16
-2wyz,2010-10-27,2009-11-20
-1wys,2005-08-15,2005-02-15
-3wyr,2015-03-18,2014-09-07
-8wy4,2024-02-28,2023-10-30
-1wy7,2005-12-13,2005-02-08
-6wyw,2020-10-14,2020-05-13
-5wys,2017-12-27,2017-01-15
-7wyo,2022-06-22,2022-02-16
-4wyl,2015-05-06,2014-11-17
-6wya,2020-08-19,2020-05-12
-3wy0,2015-01-14,2014-08-13
-1wy4,2005-05-03,2005-02-04
-3wyn,2014-09-24,2014-09-02
-4wyo,2015-01-14,2014-11-17
-2wym,2010-04-14,2009-11-16
-7wyt,2022-05-04,2022-02-16
-3wy3,2015-06-10,2014-08-18
-6wyg,2020-11-11,2020-05-12
-3wyi,2015-02-04,2014-08-29
-6wyt,2020-07-29,2020-05-13
-5wy8,2017-11-22,2017-01-11
-2wy4,2010-02-16,2009-11-11
-1wyw,2005-06-21,2005-02-17
-4wyf,2015-07-08,2014-11-17
-2wyf,2010-04-21,2009-11-16
-7wys,2022-05-04,2022-02-16
-6wy7,2020-10-14,2020-05-12
-1wy1,2005-02-22,2005-02-04
-6wyd,2020-10-14,2020-05-12
-5wyq,2017-12-20,2017-01-15
-6wy0,2020-10-14,2020-05-12
-7wyj,2023-01-11,2022-02-16
-4wy0,2015-01-14,2014-11-14
-6wyf,2020-11-11,2020-05-12
-3wyy,2015-04-08,2014-09-10
-6wyv,2020-06-17,2020-05-13
-2wyi,2010-02-16,2009-11-16
-4wyd,2015-07-15,2014-11-17
-6wy9,2020-10-28,2020-05-12
-7wyw,2022-04-27,2022-02-16
-5wyf,2017-04-19,2017-01-12
-1i1a,2001-02-14,2001-01-31
-6i1j,2019-09-04,2018-10-28
-1i14,2002-05-29,2001-01-30
-4i1p,2014-07-09,2012-11-21
-5i1w,2017-02-15,2016-02-07
-6i12,2019-02-27,2018-10-27
-4i1f,2013-06-19,2012-11-20
-8i11,2024-01-24,2023-01-12
-1i1y,2000-01-21,1999-04-16
-6i1p,2020-09-02,2018-10-29
-1i1o,2001-04-04,2001-02-02
-2i16,2006-08-29,2006-08-13
-8i1g,2023-03-22,2023-01-13
-5i1f,2016-03-02,2016-02-05
-4i1c,2013-03-06,2012-11-20
-8i1a,2023-03-22,2023-01-13
-1i1c,2001-02-14,2001-01-31
-6i1s,2019-09-11,2018-10-30
-4i1s,2013-01-30,2012-11-21
-2i19,2006-10-17,2006-08-13
-8i1z,2023-04-12,2023-01-13
-1i1f,2000-01-12,1999-04-16
-6i1g,2019-11-20,2018-10-28
-6i1n,2019-11-20,2018-10-29
-1i1e,2001-11-21,2001-02-01
-6i1i,2019-11-20,2018-10-28
-3i1f,2010-06-30,2009-06-26
-8i1y,2023-04-12,2023-01-13
-4i1r,2013-08-28,2012-11-21
-1i19,2001-08-08,2001-01-31
-8i1e,2023-03-22,2023-01-13
-6i1u,2019-11-20,2018-10-30
-8i17,2023-02-22,2023-01-12
-1i1l,2001-07-04,2001-02-02
-4i10,2013-03-06,2012-11-19
-4i1l,2012-12-05,2012-11-21
-2i14,2006-10-10,2006-08-12
-5i12,2016-07-06,2016-02-05
-3i11,2009-12-29,2009-06-25
-6i1h,2019-11-20,2018-10-28
-1i1m,2001-07-04,2001-02-02
-6i17,2019-02-27,2018-10-27
-2i1m,2006-11-28,2006-08-14
-3i1l,2009-09-15,2009-06-26
-4i1i,2012-12-19,2012-11-21
-4i11,2013-03-06,2012-11-19
-1i1n,2002-03-13,2001-02-02
-6i1l,2019-01-23,2018-10-29
-1i18,2001-09-05,2001-01-31
-4i14,2013-08-28,2012-11-20
-8i1m,2023-06-28,2023-01-13
-1i13,2002-05-29,2001-01-30
-6i13,2019-02-27,2018-10-27
-3i1u,2009-11-17,2009-06-28
-8i1f,2023-03-22,2023-01-13
-6i10,2019-02-27,2018-10-27
-6i16,2019-02-27,2018-10-27
-8i1w,2023-04-12,2023-01-13
-2i13,2006-10-03,2006-08-12
-6i18,2019-02-27,2018-10-27
-8i16,2023-08-30,2023-01-12
-8i15,2023-12-20,2023-01-12
-8i1i,2023-03-22,2023-01-13
-8i1j,2023-03-22,2023-01-13
-6i1o,2019-11-20,2018-10-29
-2i1x,2006-10-10,2006-08-15
-5i13,2016-02-17,2016-02-05
-3i12,2009-08-18,2009-06-25
-4i1h,2013-06-19,2012-11-20
-5i1q,2016-06-08,2016-01-09
-8i1d,2023-03-22,2023-01-13
-3i13,2009-12-29,2009-06-25
-8i1o,2023-06-28,2023-01-13
-8i1h,2023-03-22,2023-01-13
-2i1r,2006-10-31,2006-08-14
-2i10,2006-09-12,2006-08-11
-3i14,2009-12-29,2009-06-25
-4i18,2013-11-20,2012-11-20
-3i1y,2009-10-13,2009-06-28
-4i13,2013-11-27,2012-11-19
-6i1d,2019-02-13,2018-10-28
-1i1d,2001-05-16,2001-02-01
-5i1y,2017-02-08,2016-02-07
-4i1o,2013-01-16,2012-11-21
-4i1n,2013-11-27,2012-11-21
-6i1f,2019-11-20,2018-10-28
-1i1q,2001-04-18,2001-02-02
-6i1r,2019-06-05,2018-10-30
-2i17,2006-08-29,2006-08-13
-4i12,2013-03-06,2012-11-19
-1i1h,2001-07-18,2001-02-01
-8i1n,2023-06-28,2023-01-13
-5i14,2016-02-17,2016-02-05
-6i1a,2020-01-29,2018-10-28
-6i14,2019-02-27,2018-10-27
-5i1r,2016-03-30,2016-02-05
-5i1v,2017-02-15,2016-02-07
-8i18,2023-03-22,2023-01-13
-2i18,2006-08-22,2006-08-13
-2i1n,2006-09-05,2006-08-14
-1i10,2001-03-28,2001-01-30
-6i11,2019-02-27,2018-10-27
-8i1c,2023-03-22,2023-01-13
-6i1q,2019-11-13,2018-10-30
-6i1t,2019-11-13,2018-10-30
-8i19,2023-03-22,2023-01-13
-6i1e,2019-11-20,2018-10-28
-3i1j,2009-07-14,2009-06-26
-1i1i,2001-02-28,2001-02-01
-3i1k,2009-09-15,2009-06-26
-4i15,2013-03-13,2012-11-20
-4i1v,2013-01-09,2012-11-21
-6i1k,2019-01-23,2018-10-29
-6i15,2019-02-27,2018-10-27
-5i10,2017-02-08,2016-02-05
-2i1o,2006-08-29,2006-08-14
-2i1q,2006-10-24,2006-08-14
-1i1k,2001-07-04,2001-02-02
-3i16,2009-07-21,2009-06-25
-2i1p,2007-02-13,2006-08-14
-8i10,2023-05-17,2023-01-12
-2i1v,2007-07-03,2006-08-15
-5i1t,2016-05-25,2016-02-05
-4i1w,2014-05-21,2012-11-21
-3i15,2009-12-29,2009-06-25
-1i12,2001-05-16,2001-01-30
-8i1u,2024-01-31,2023-01-13
-8y9p,2024-05-15,2024-02-07
-4y97,2015-04-15,2015-02-17
-7y98,2023-05-03,2022-06-24
-4y90,2015-07-15,2015-02-16
-5y9d,2018-01-03,2017-08-24
-8y9v,2024-02-28,2024-02-07
-6y91,2021-03-31,2020-03-06
-1y93,2005-04-26,2004-12-14
-4y91,2016-03-16,2015-02-16
-5y96,2018-02-28,2017-08-22
-7y9i,2023-07-12,2022-06-24
-6y9u,2021-02-10,2020-03-10
-7y9x,2022-11-09,2022-06-26
-6y9r,2020-05-20,2020-03-10
-7y9j,2023-06-28,2022-06-24
-4y9f,2015-09-09,2015-02-17
-2y9n,2012-02-29,2011-02-15
-6y90,2020-08-26,2020-03-06
-5y9x,2018-10-31,2017-08-29
-7y9p,2023-02-15,2022-06-25
-6y9l,2020-09-30,2020-03-09
-4y99,2016-03-30,2015-02-17
-7y9k,2023-06-28,2022-06-25
-2y98,2012-02-22,2011-02-12
-6y9i,2020-07-08,2020-03-09
-5y97,2018-08-29,2017-08-23
-2y9w,2011-07-06,2011-02-17
-7y94,2023-08-02,2022-06-24
-5y9e,2017-10-25,2017-08-24
-7y9g,2023-06-14,2022-06-24
-4y9h,2016-02-17,2015-02-17
-1y9z,2006-03-21,2004-12-16
-6y9d,2020-11-18,2020-03-06
-4y96,2015-07-15,2015-02-17
-1y9i,2004-12-28,2004-12-15
-1y9m,2004-12-28,2004-12-16
-1y9a,2006-01-17,2004-12-15
-6y9s,2020-05-20,2020-03-10
-6y9c,2021-03-31,2020-03-06
-4y9z,2015-06-17,2015-02-17
-4y9c,2015-09-09,2015-02-17
-6y9p,2020-10-07,2020-03-10
-7y9v,2022-09-07,2022-06-26
-4y94,2015-03-18,2015-02-16
-5y9r,2018-09-05,2017-08-28
-4y9l,2015-06-03,2015-02-17
-7y9y,2022-11-09,2022-06-26
-5y9y,2018-10-31,2017-08-29
-6y9o,2020-10-07,2020-03-10
-4y9b,2015-09-09,2015-02-17
-4y9d,2016-03-09,2015-02-17
-4y93,2015-03-18,2015-02-16
-7y9z,2022-09-21,2022-06-26
-4y9g,2015-09-09,2015-02-17
-8y95,2024-05-29,2024-02-06
-5y94,2018-06-13,2017-08-22
-7y9c,2023-04-12,2022-06-24
-8y93,2024-05-29,2024-02-06
-7y9o,2023-05-03,2022-06-25
-4y9j,2015-06-03,2015-02-17
-5y92,2018-02-28,2017-08-22
-5y91,2017-09-20,2017-08-22
-1y9e,2004-12-21,2004-12-15
-5y93,2018-06-13,2017-08-22
-4y9t,2015-03-11,2015-02-17
-6y92,2020-08-26,2020-03-06
-1y9g,2004-12-21,2004-12-15
-7y9h,2023-06-14,2022-06-24
-6y94,2020-04-29,2020-03-06
-7y97,2023-05-03,2022-06-24
-7y90,2023-11-15,2022-06-24
-7y9s,2022-08-31,2022-06-26
-8y9x,2024-03-13,2024-02-07
-6y9h,2021-03-31,2020-03-09
-5y9m,2018-05-16,2017-08-25
-6y99,2021-03-31,2020-03-06
-7y9u,2022-09-07,2022-06-26
-2y9g,2011-10-12,2011-02-14
-1y98,2005-08-30,2004-12-14
-1y9d,2005-04-05,2004-12-15
-6y9m,2020-09-30,2020-03-10
-6y9j,2020-07-22,2020-03-09
-2y99,2011-08-31,2011-02-12
-1y91,2005-02-08,2004-12-14
-5y9l,2017-11-29,2017-08-25
-7y99,2023-09-27,2022-06-24
-4y9w,2016-11-30,2015-02-17
-6y98,2020-07-22,2020-03-06
-7y9a,2023-05-24,2022-06-24
-1y9t,2005-04-12,2004-12-16
-5y9i,2018-10-31,2017-08-25
-5y9a,2017-09-13,2017-08-23
-5y9t,2018-07-11,2017-08-28
-7y95,2023-05-24,2022-06-24
-2y91,2012-02-22,2011-02-11
-4y9r,2016-03-02,2015-02-17
-4y9e,2015-09-09,2015-02-17
-2y9x,2011-07-06,2011-02-17
-1y9q,2005-01-04,2004-12-16
-7y9l,2023-07-12,2022-06-25
-5y95,2017-10-04,2017-08-22
-1y9r,2005-05-24,2004-12-16
-4y9v,2017-02-01,2015-02-17
-5y9b,2018-08-29,2017-08-24
-5y9z,2018-09-19,2017-08-29
-2y9q,2012-02-29,2011-02-16
-6y9b,2020-05-20,2020-03-06
-7y9m,2023-07-12,2022-06-25
-4y95,2015-03-18,2015-02-16
-4y9y,2015-06-17,2015-02-17
-4y9x,2015-07-15,2015-02-17
-4y9p,2016-03-09,2015-02-17
-4y9u,2016-03-02,2015-02-17
-6y9t,2020-05-27,2020-03-10
-1z9p,2006-09-12,2005-04-04
-7z9n,2022-11-23,2022-03-21
-4z96,2016-10-12,2015-04-09
-1z9k,2005-06-07,2005-04-02
-4z9g,2016-06-29,2015-04-10
-1z9y,2006-05-23,2005-04-05
-5z9l,2018-12-12,2018-02-03
-6z9e,2020-06-24,2020-06-03
-7z9w,2022-12-07,2022-03-21
-8z97,2024-05-29,2024-04-22
-7z9c,2023-02-15,2022-03-21
-2z9i,2008-06-10,2007-09-20
-5z91,2019-02-06,2018-02-01
-4z92,2015-11-18,2015-04-09
-4z94,2015-10-21,2015-04-09
-6z9k,2020-09-16,2020-06-04
-7z9k,2023-03-08,2022-03-21
-7z98,2023-02-22,2022-03-20
-2z9w,2007-11-06,2007-09-26
-7z93,2022-03-30,2022-03-19
-1z97,2005-08-09,2005-03-31
-5z9x,2018-06-27,2018-02-05
-6z91,2021-06-30,2020-06-03
-5z9y,2018-04-11,2018-02-05
-5z9q,2018-12-12,2018-02-04
-6z9x,2021-06-30,2020-06-04
-6z9h,2020-11-18,2020-06-04
-6z9p,2020-11-04,2020-06-04
-5z99,2018-10-24,2018-02-02
-2z90,2008-04-22,2007-09-13
-5z9c,2018-02-14,2018-02-02
-1z9j,2005-06-07,2005-04-02
-7z9h,2022-11-23,2022-03-21
-2z9d,2008-03-11,2007-09-18
-7z9m,2023-02-15,2022-03-21
-1z93,2005-08-09,2005-03-31
-5z9s,2018-03-14,2018-02-05
-6z9n,2021-06-30,2020-06-04
-6z9a,2020-11-18,2020-06-03
-4z9w,2016-03-23,2015-04-12
-4z9v,2016-02-10,2015-04-12
-6z9j,2020-11-18,2020-06-04
-7z9y,2022-12-07,2022-03-21
-5z96,2018-04-18,2018-02-02
-8z90,2024-05-29,2024-04-22
-5z9j,2019-02-06,2018-02-03
-7z9s,2022-11-23,2022-03-21
-5z97,2018-05-02,2018-02-02
-1z95,2005-04-19,2005-03-31
-7z9v,2023-03-29,2022-03-21
-5z9b,2018-12-12,2018-02-02
-1z98,2005-12-20,2005-04-01
-4z9n,2015-06-17,2015-04-10
-5z9f,2018-12-12,2018-02-03
-7z92,2022-03-30,2022-03-19
-6z97,2020-07-01,2020-06-03
-4z9l,2015-05-06,2015-04-10
-2z95,2008-03-18,2007-09-18
-2z9x,2007-11-06,2007-09-26
-2z92,2008-05-06,2007-09-14
-4z9d,2016-10-12,2015-04-10
-6z9l,2020-09-16,2020-06-04
-5z9n,2018-12-12,2018-02-03
-5z9t,2019-03-27,2018-02-05
-6z9y,2021-06-30,2020-06-04
-4z9h,2016-07-20,2015-04-10
-7z97,2023-02-22,2022-03-20
-6z9v,2021-06-30,2020-06-04
-1z9n,2006-09-19,2005-04-03
-6z9t,2020-11-04,2020-06-04
-7z9e,2022-08-10,2022-03-21
-8z9r,2024-05-29,2024-04-23
-6z9z,2021-06-30,2020-06-04
-7z9d,2022-08-10,2022-03-21
-8z9h,2024-05-29,2024-04-23
-2z9b,2008-03-11,2007-09-18
-5z9p,2018-12-12,2018-02-04
-6z9s,2020-11-04,2020-06-04
-7z9t,2023-06-14,2022-03-21
-6z9g,2020-09-09,2020-06-03
-5z9w,2018-10-24,2018-02-05
-5z93,2019-02-06,2018-02-02
-7z9o,2022-11-23,2022-03-21
-2z94,2007-12-25,2007-09-17
-6z9q,2020-11-04,2020-06-04
-4z9r,2016-04-06,2015-04-11
-5z90,2019-02-06,2018-02-01
-1z9g,2005-04-19,2005-04-01
-2z98,2008-03-11,2007-09-18
-6z99,2021-06-30,2020-06-03
-2z97,2008-09-23,2007-09-18
-6z9o,2020-09-09,2020-06-04
-6z9r,2020-11-04,2020-06-04
-5z9m,2018-12-12,2018-02-03
-5z9i,2019-02-06,2018-02-03
-6z9d,2020-09-16,2020-06-03
-7z9i,2022-11-23,2022-03-21
-4z90,2015-09-16,2015-04-09
-4z97,2016-10-12,2015-04-09
-6z9b,2020-07-22,2020-06-03
-5z9e,2018-12-12,2018-02-02
-5z9k,2019-02-06,2018-02-03
-1z9a,2006-01-03,2005-04-01
-4z9i,2016-07-20,2015-04-10
-7z94,2023-02-22,2022-03-19
-6z9i,2020-11-18,2020-06-04
-7z9u,2022-11-23,2022-03-21
-7z9r,2022-07-13,2022-03-21
-6z9f,2020-06-24,2020-06-03
-4z9o,2015-06-03,2015-04-10
-5z95,2018-07-25,2018-02-02
-7z9j,2022-11-23,2022-03-21
-1z9o,2005-07-19,2005-04-03
-6z9c,2020-06-17,2020-06-03
-1z9h,2005-05-17,2005-04-02
-4z91,2015-09-16,2015-04-09
-5z98,2018-08-15,2018-02-02
-7z9g,2023-02-15,2022-03-21
-7z9f,2022-06-29,2022-03-21
-7z99,2023-02-22,2022-03-20
-7z9q,2022-07-13,2022-03-21
-8z98,2024-05-29,2024-04-22
-6z9w,2021-06-30,2020-06-04
-5z94,2019-02-06,2018-02-02
-2z9v,2007-11-06,2007-09-26
-2z9g,2007-12-25,2007-09-19
-2z9k,2007-12-25,2007-09-20
-4z93,2015-07-01,2015-04-09
-4z9b,2015-07-15,2015-04-10
-2z93,2008-05-06,2007-09-14
-4z9k,2016-07-20,2015-04-10
-7z9z,2023-03-29,2022-03-21
-2z9c,2008-03-11,2007-09-18
-6md1,2019-01-09,2018-09-03
-3mdr,2010-07-28,2010-03-30
-4mdz,2014-02-19,2013-08-23
-4mdd,2014-12-03,2013-08-22
-6mdw,2019-04-10,2018-09-05
-4md0,2013-12-04,2013-08-22
-4md1,2014-10-08,2013-08-22
-1md9,2002-09-11,2002-08-07
-4mds,2013-10-02,2013-08-23
-4mdt,2013-10-16,2013-08-23
-7md0,2021-06-23,2021-04-02
-3mds,1994-01-31,1993-10-20
-7md7,2021-04-21,2021-04-03
-3mdj,2011-03-30,2010-03-30
-3mdi,2010-06-02,2010-03-30
-4md5,2013-12-04,2013-08-22
-4mdx,2013-10-23,2013-08-23
-3mdb,2010-08-04,2010-03-30
-4md7,2013-11-20,2013-08-22
-6mdb,2019-02-13,2018-09-04
-1mdv,1999-05-04,1998-09-08
-1md3,2002-08-21,2002-08-06
-6mdp,2018-09-19,2018-09-04
-3mdl,2011-04-13,2010-03-30
-3mdv,2010-07-28,2010-03-30
-6mdn,2018-09-19,2018-09-04
-4mdb,2014-01-22,2013-08-22
-7mdc,2022-09-28,2021-04-03
-4mdq,2013-11-13,2013-08-23
-6mde,2018-12-19,2018-09-04
-7mdf,2022-09-28,2021-04-04
-1mdl,1996-10-14,1996-03-29
-7md9,2021-06-23,2021-04-03
-6md4,2019-01-09,2018-09-03
-3md0,2010-04-21,2010-03-29
-7mdt,2022-01-26,2021-04-06
-3mdg,2010-06-02,2010-03-30
-1mdn,1998-09-30,1998-08-12
-5mds,2017-12-20,2016-11-13
-3md5,2011-05-25,2010-03-29
-5mdx,2017-06-21,2016-11-13
-1md7,2003-08-07,2002-08-07
-2md7,2013-11-13,2013-09-02
-5mdz,2016-12-14,2016-11-13
-7mdu,2022-01-26,2021-04-06
-4mdi,2013-12-04,2013-08-22
-3mdu,2011-03-09,2010-03-30
-7mdw,2021-08-11,2021-04-06
-3mdt,2010-07-28,2010-03-30
-3mdw,2011-03-09,2010-03-30
-4mdh,1989-04-19,1989-04-12
-4md2,2014-10-08,2013-08-22
-6mdu,2019-04-17,2018-09-05
-6md6,2019-05-29,2018-09-04
-6mdx,2019-04-10,2018-09-05
-4mdk,2013-12-11,2013-08-22
-1md4,2002-08-21,2002-08-06
-3mda,2010-04-28,2010-03-30
-1md2,2002-12-11,2002-08-06
-3mdm,2010-07-28,2010-03-30
-1mdo,2002-12-11,2002-08-07
-6md2,2019-01-09,2018-09-03
-1mdz,2002-12-11,2002-08-07
-4mdj,2013-12-04,2013-08-22
-5mdn,2016-12-14,2016-11-12
-6mda,2019-02-13,2018-09-04
-2mdg,2013-09-25,2013-09-10
-4mdn,2013-11-13,2013-08-23
-3mdo,2010-06-02,2010-03-30
-1mdq,1994-11-01,1994-08-10
-7md8,2021-06-23,2021-04-03
-1mdp,1994-11-01,1994-08-10
-7mda,2021-06-23,2021-04-03
-4mda,2014-01-22,2013-08-22
-1mdw,2003-04-29,2002-08-07
-7mds,2021-08-04,2021-04-06
-5mdo,2017-12-20,2016-11-13
-6md8,2019-04-17,2018-09-04
-4mdp,2014-06-25,2013-08-23
-6mdv,2019-02-06,2018-09-05
-1mdt,1994-07-31,1994-03-21
-5mdj,2018-02-21,2016-11-11
-3md7,2010-04-21,2010-03-30
-7mdn,2021-05-05,2021-04-05
-3mdy,2010-05-19,2010-03-31
-3mdc,2010-04-28,2010-03-30
-6mdt,2019-02-27,2018-09-05
-3md4,2011-05-25,2010-03-29
-6md3,2019-01-30,2018-09-03
-4md8,2013-11-20,2013-08-22
-1mda,1993-10-31,1992-03-02
-6mdq,2018-09-26,2018-09-05
-4mde,2013-11-06,2013-08-22
-1mdb,2002-09-11,2002-08-07
-5mdq,2017-12-20,2016-11-13
-6md7,2019-02-13,2018-09-04
-6mdd,2019-02-13,2018-09-04
-5mdh,1999-05-18,1998-10-08
-7mdp,2022-03-16,2021-04-05
-7mdi,2022-01-05,2021-04-05
-5mdl,2018-02-21,2016-11-11
-7mdl,2022-11-09,2021-04-05
-5mdu,2017-04-12,2016-11-13
-6mdf,2018-12-19,2018-09-04
-6mdo,2018-09-19,2018-09-04
-4mdv,2014-02-26,2013-08-23
-6mdc,2019-02-13,2018-09-04
-7md1,2021-06-23,2021-04-02
-4mdf,2013-11-06,2013-08-22
-7mdz,2021-09-01,2021-04-06
-3mdz,2010-06-23,2010-03-31
-7mdb,2021-06-23,2021-04-03
-1mdu,2003-01-07,2002-08-07
-6md9,2019-02-13,2018-09-04
-5mdy,2016-12-21,2016-11-13
-5mdv,2016-12-14,2016-11-13
-3mde,1994-09-30,1994-07-13
-4md4,2013-12-04,2013-08-22
-7md5,2022-02-23,2021-04-03
-7mdh,1999-06-04,1999-02-16
-3mdd,1994-09-30,1994-07-13
-4mdr,2014-03-12,2013-08-23
-4md6,2014-07-09,2013-08-22
-7mdy,2021-08-11,2021-04-06
-7mdm,2021-08-25,2021-04-05
-1mdx,2002-12-11,2002-08-07
-2md8,2013-11-13,2013-09-02
-7mdj,2022-02-16,2021-04-05
-4md9,2013-11-20,2013-08-22
-5mdm,2016-12-14,2016-11-11
-7md6,2021-06-23,2021-04-03
-5mdw,2016-12-14,2016-11-13
-7mdx,2021-08-11,2021-04-06
-7mdo,2021-08-25,2021-04-05
-6mdm,2018-09-19,2018-09-04
-5mdk,2018-02-21,2016-11-11
-5mdr,2017-12-20,2016-11-13
-6mds,2019-02-06,2018-09-05
-1mdr,1994-08-31,1993-11-19
-2aa5,2005-07-26,2005-07-13
-2aa1,2005-08-02,2005-07-13
-5aaa,2016-06-08,2015-07-23
-6aar,2019-07-24,2018-07-19
-9aat,1993-10-31,1991-12-02
-8aaa,2023-06-28,2022-06-30
-8aap,2023-04-26,2022-07-01
-2aa9,2006-02-14,2005-07-13
-2aa6,2005-07-26,2005-07-13
-3aaj,2010-09-08,2009-11-19
-7aar,2021-08-18,2020-09-04
-8aa0,2023-06-07,2022-06-29
-5aal,2016-03-09,2015-07-27
-4aa2,2012-10-31,2011-11-30
-5aa5,2016-01-20,2015-07-23
-5aa4,2016-10-12,2015-07-23
-8aao,2023-04-26,2022-07-01
-2aai,1994-01-31,1993-09-07
-3aag,2009-12-08,2009-11-16
-6aam,2018-08-15,2018-07-18
-6aa9,2019-07-17,2018-07-17
-4aap,2012-02-29,2011-12-05
-4aas,2012-12-12,2011-12-05
-8aaf,2023-03-08,2022-07-01
-6aax,2019-06-05,2018-07-19
-5aa2,2016-10-12,2015-07-23
-3aam,2010-12-01,2009-11-20
-2aaq,2006-04-04,2005-07-14
-8aau,2022-08-10,2022-07-03
-2aa3,2006-01-10,2005-07-13
-2aa0,2006-07-25,2005-07-13
-5aap,2016-03-09,2015-07-27
-5aa9,2016-06-08,2015-07-23
-1aam,1993-10-31,1993-07-13
-6aaz,2019-04-17,2018-07-19
-6aa4,2019-03-06,2018-07-17
-7aap,2020-09-23,2020-09-04
-4aax,2012-04-04,2011-12-05
-2aa4,2005-07-19,2005-07-13
-4aay,2012-12-12,2011-12-05
-7aa4,2021-08-11,2020-09-03
-4aao,2012-10-17,2011-12-05
-2aae,1994-01-31,1992-09-15
-2aaw,2006-01-10,2005-07-14
-6aak,2018-08-15,2018-07-18
-7aa5,2021-08-18,2020-09-03
-2aaz,2005-12-06,2005-07-14
-7aas,2020-12-30,2020-09-04
-7aav,2020-12-09,2020-09-04
-6aah,2018-08-15,2018-07-18
-2aad,1994-01-31,1992-09-15
-2aan,2006-07-11,2005-07-13
-4aa6,2011-12-14,2011-11-30
-5aa7,2015-12-09,2015-07-23
-5aab,2016-06-08,2015-07-23
-4aa9,2012-12-12,2011-11-30
-5aae,2015-09-02,2015-07-24
-5aa0,2015-10-14,2015-07-23
-5aag,2015-09-02,2015-07-24
-8aaj,2023-05-03,2022-07-01
-3aak,2010-09-08,2009-11-19
-6aaw,2019-07-24,2018-07-19
-1aa9,1997-07-29,1997-01-27
-1aaq,1994-06-22,1992-04-13
-3aaq,2010-02-09,2009-11-24
-7aaw,2021-09-15,2020-09-04
-2aa2,2005-07-26,2005-07-13
-6aa8,2018-11-07,2018-07-17
-1aay,1997-04-21,1997-01-18
-3aas,2010-04-07,2009-11-26
-5aaz,2016-07-13,2015-07-31
-3aau,2010-04-07,2009-11-26
-7aa7,2021-06-16,2020-09-03
-4aab,2012-05-02,2011-12-01
-7aat,1993-10-31,1991-12-02
-7aac,2021-01-13,2020-09-04
-7aa1,2021-02-17,2020-09-02
-2aat,1989-10-15,1989-05-30
-5aay,2016-07-13,2015-07-31
-5aar,2016-08-24,2015-07-28
-3aav,2010-04-07,2009-11-26
-5aav,2015-10-14,2015-07-29
-7aaq,2021-08-18,2020-09-04
-7aai,2021-02-24,2020-09-04
-5aaq,2016-07-13,2015-07-28
-1aaz,1993-10-31,1992-04-24
-6aan,2019-04-17,2018-07-18
-3aa6,2010-08-04,2009-11-11
-1aa6,1997-08-20,1997-01-23
-6aaq,2019-04-17,2018-07-18
-5aao,2016-02-03,2015-07-27
-2aa7,2005-07-26,2005-07-13
-5aau,2015-10-14,2015-07-28
-8aam,2023-07-12,2022-07-01
-7aax,2020-10-28,2020-09-05
-8aaz,2023-01-25,2022-07-04
-1aac,1996-03-08,1995-09-07
-8aav,2024-03-20,2022-07-03
-8aai,2023-04-26,2022-07-01
-2aax,2005-07-26,2005-07-14
-4aac,2012-05-16,2011-12-01
-5aaf,2015-09-02,2015-07-24
-2aac,1997-11-12,1996-10-31
-2aay,2006-02-14,2005-07-14
-6aap,2019-04-17,2018-07-18
-5aan,2017-01-25,2015-07-27
-5aac,2016-06-08,2015-07-23
-4aam,2012-10-17,2011-12-05
-4aa4,2012-05-16,2011-11-30
-5aa3,2016-10-12,2015-07-23
-7aaj,2021-02-17,2020-09-04
-8aan,2023-09-27,2022-07-01
-6aa3,2019-03-06,2018-07-17
-5aa1,2016-10-12,2015-07-23
-7aag,2021-10-06,2020-09-04
-4aaq,2012-12-12,2011-12-05
-6aa5,2019-03-06,2018-07-17
-4aa5,2012-05-16,2011-11-30
-4aa7,2012-08-15,2011-11-30
-2aaa,1993-07-15,1991-02-27
-7aak,2021-02-17,2020-09-04
-8aa7,2023-07-12,2022-06-30
-1aax,1998-03-04,1997-01-16
-8aak,2023-04-26,2022-07-01
-4aar,2012-12-12,2011-12-05
-4aal,2012-10-17,2011-12-05
-4aa1,2012-10-31,2011-11-30
-7aaz,2020-11-04,2020-09-05
-8aas,2023-05-03,2022-07-01
-5aas,2015-09-23,2015-07-28
-2aao,2005-12-27,2005-07-13
-6aaj,2018-08-15,2018-07-18
-6aac,2019-04-17,2018-07-18
-3aaw,2010-06-23,2009-11-27
-8aat,1993-10-31,1991-12-02
-7aa2,2021-05-26,2020-09-03
-6aad,2019-04-17,2018-07-18
-4aah,1996-12-07,1996-03-10
-3aal,2010-12-01,2009-11-20
-5aa8,2016-06-08,2015-07-23
-1aa4,1997-07-23,1997-01-22
-1aa1,1997-07-07,1997-01-20
-6aal,2019-06-12,2018-07-18
-4aag,2012-05-02,2011-12-01
-7aa9,2021-06-16,2020-09-03
-1aa0,1997-07-23,1997-01-18
-7aa0,2021-02-17,2020-09-02
-4aaa,2011-12-21,2011-11-30
-7aad,2021-01-13,2020-09-04
-7aab,2021-01-13,2020-09-04
-6aao,2019-04-17,2018-07-18
-7aay,2020-10-28,2020-09-05
-4aa0,2012-05-16,2011-11-30
-8aa1,2023-06-07,2022-06-29
-1aaw,1993-10-31,1993-07-13
-4aan,2012-10-17,2011-12-05
-3aat,1992-01-15,1990-12-06
-8aa3,2023-06-07,2022-06-29
-1aaf,1994-01-31,1992-04-06
-8aa2,2023-06-07,2022-06-29
-5aad,2015-09-02,2015-07-24
-4aau,2012-12-12,2011-12-05
-4aaw,2012-02-15,2011-12-05
-3aa7,2010-08-04,2009-11-11
-3aar,2010-02-09,2009-11-24
-7aau,2020-12-30,2020-09-04
-1aan,1993-10-31,1992-04-09
-6dde,2018-06-13,2018-05-10
-3dd8,2008-08-12,2008-06-05
-1dde,2000-04-07,1999-11-09
-1ddx,2000-05-16,1999-11-11
-5ddq,2015-12-23,2015-08-25
-1ddk,2000-11-13,1999-11-10
-7ddp,2021-05-19,2020-10-29
-7dds,2021-09-08,2020-10-29
-3ddp,2008-07-22,2008-06-06
-7dd3,2021-01-06,2020-10-27
-7ddm,2021-11-03,2020-10-29
-2ddq,2006-07-11,2006-02-02
-5ddc,2016-07-06,2015-08-24
-6ddf,2018-06-13,2018-05-10
-3ddd,2008-06-24,2008-06-05
-1ddo,1997-07-23,1997-01-16
-3ddl,2008-10-14,2008-06-05
-5ddm,2016-02-24,2015-08-25
-3ddu,2008-08-19,2008-06-06
-1dd7,2000-03-29,1999-11-08
-2dd8,2006-04-04,2006-01-24
-5ddr,2015-12-23,2015-08-25
-3dd2,2008-11-11,2008-06-04
-3ddh,2008-09-30,2008-06-05
-8dd3,2022-08-17,2022-06-17
-5ddz,2016-09-07,2015-08-25
-5dda,2015-09-09,2015-08-24
-8ddx,2022-11-02,2022-06-19
-6ddi,2019-11-13,2018-05-10
-2dd5,2007-01-30,2006-01-19
-2ddc,2006-03-07,2006-01-27
-2ddu,2006-09-26,2006-02-03
-3ddc,2008-07-15,2008-06-05
-8dd6,2023-09-27,2022-06-17
-5dde,2015-09-09,2015-08-24
-2dd4,2007-01-30,2006-01-19
-6ddr,2018-10-24,2018-05-10
-2ddr,2006-05-02,2006-02-02
-2dde,2006-02-21,2006-01-27
-6ddu,2019-01-09,2018-05-10
-1dd6,2000-11-08,1999-11-08
-4ddh,2013-02-13,2012-01-18
-4ddl,2012-03-21,2012-01-18
-7dd5,2021-06-16,2020-10-27
-7ddo,2021-05-19,2020-10-29
-2ddf,2006-03-14,2006-01-28
-6ddz,2018-07-04,2018-05-10
-6ddb,2018-07-04,2018-05-09
-6dd6,2018-07-18,2018-05-09
-6dds,2018-05-23,2018-05-10
-2ddh,2006-03-28,2006-01-29
-8dd1,2022-07-13,2022-06-17
-7dd7,2021-06-16,2020-10-27
-5dds,2016-08-10,2015-08-25
-4dd7,2012-04-25,2012-01-18
-8dd9,2022-07-13,2022-06-17
-5ddw,2016-08-10,2015-08-25
-3ddk,2008-09-23,2008-06-05
-3dds,2009-01-27,2008-06-06
-5ddl,2016-10-26,2015-08-25
-4ddr,2012-11-14,2012-01-19
-4ddk,2013-02-13,2012-01-18
-4ddt,2012-12-26,2012-01-19
-6dd4,2018-05-23,2018-05-09
-3ddf,2008-07-01,2008-06-05
-3dd0,2009-03-03,2008-06-04
-5ddd,2015-09-09,2015-08-24
-5dd9,2015-09-09,2015-08-24
-7ddl,2021-01-27,2020-10-29
-1ddm,2000-04-10,1999-11-11
-5ddk,2016-05-04,2015-08-25
-1ddu,1998-07-01,1997-06-26
-8dd0,2022-12-28,2022-06-17
-8dd5,2023-07-05,2022-06-17
-2dds,2006-05-02,2006-02-02
-4dds,2012-03-28,2012-01-19
-6ddt,2019-01-09,2018-05-10
-5ddy,2016-02-24,2015-08-25
-7ddw,2021-04-07,2020-10-30
-1ddz,2000-03-08,1999-11-12
-1ddn,1998-10-14,1998-06-23
-8dds,2022-11-02,2022-06-18
-2ddt,2006-05-02,2006-02-02
-8dde,2022-12-21,2022-06-17
-3ddq,2008-07-22,2008-06-06
-4ddy,2012-03-28,2012-01-19
-6dd1,2019-05-08,2018-05-08
-3dda,2008-09-16,2008-06-05
-4ddo,2012-05-23,2012-01-19
-6ddc,2018-07-04,2018-05-09
-3ddv,2008-10-07,2008-06-06
-8ddr,2022-11-02,2022-06-18
-5dd7,2015-09-16,2015-08-24
-8ddv,2022-11-02,2022-06-19
-8dd2,2022-08-17,2022-06-17
-4ddv,2012-12-26,2012-01-19
-1ddt,1994-07-31,1994-03-01
-6dda,2019-03-20,2018-05-09
-1ddl,2000-10-30,1999-11-10
-4dd8,2012-06-06,2012-01-18
-8ddk,2022-12-14,2022-06-18
-7dd1,2021-04-21,2020-10-27
-4ddm,2013-02-13,2012-01-18
-6dd0,2019-05-08,2018-05-08
-6ddw,2018-05-23,2018-05-10
-7ddc,2021-11-10,2020-10-28
-7ddt,2021-09-08,2020-10-29
-7ddv,2021-11-10,2020-10-29
-6ddh,2018-07-04,2018-05-10
-2ddx,2007-02-13,2006-02-06
-7dde,2021-07-14,2020-10-28
-3ddi,2009-06-16,2008-06-05
-2dda,2007-01-30,2006-01-25
-5ddp,2015-12-23,2015-08-25
-1ddi,2000-11-13,1999-11-10
-4ddn,2012-08-01,2012-01-19
-2ddy,2007-02-06,2006-02-06
-8ddb,2022-12-21,2022-06-17
-3ddr,2009-01-20,2008-06-06
-7ddk,2021-01-27,2020-10-29
-8ddy,2023-04-05,2022-06-19
-7ddr,2021-09-08,2020-10-29
-7ddb,2021-11-03,2020-10-28
-8dd7,2023-02-15,2022-06-17
-1dds,1995-10-15,1995-06-29
-8ddm,2022-08-31,2022-06-18
-3ddt,2008-10-07,2008-06-06
-8ddq,2022-11-02,2022-06-18
-8ddl,2023-06-28,2022-06-18
-4ddx,2012-12-26,2012-01-19
-2ddo,2006-08-15,2006-02-02
-6ddj,2019-11-13,2018-05-10
-8ddt,2022-11-02,2022-06-18
-7ddu,2021-09-08,2020-10-29
-1ddg,2000-11-13,1999-11-10
-3dd4,2008-12-23,2008-06-05
-6ddp,2018-05-23,2018-05-10
-3dd1,2009-04-21,2008-06-04
-2ddb,2007-01-30,2006-01-25
-5ddu,2016-08-10,2015-08-25
-8ddf,2022-09-28,2022-06-18
-7ddi,2021-01-27,2020-10-29
-7ddz,2021-01-27,2020-10-30
-2ddw,2006-08-15,2006-02-03
-8ddg,2022-09-28,2022-06-18
-4ddq,2013-02-13,2012-01-19
-5ddf,2015-09-09,2015-08-24
-8ddh,2022-09-28,2022-06-18
-3ddb,2008-09-16,2008-06-05
-4dd9,2012-04-25,2012-01-18
-4ddu,2012-12-26,2012-01-19
-3ddy,2008-07-01,2008-06-07
-3ddn,2008-07-22,2008-06-05
-2ddd,2006-03-07,2006-01-27
-3ddg,2008-07-01,2008-06-05
-4dda,2012-04-25,2012-01-18
-7dd6,2021-06-16,2020-10-27
-3ddz,2009-06-09,2008-06-07
-7ddq,2021-06-30,2020-10-29
-3ddw,2009-01-27,2008-06-06
-7ddf,2021-01-27,2020-10-29
-1ddv,2000-05-10,1999-11-11
-5ddb,2015-09-09,2015-08-24
-7dd9,2021-07-14,2020-10-28
-8ddu,2022-11-02,2022-06-19
-3dd3,2009-04-21,2008-06-05
-4ddw,2012-12-26,2012-01-19
-7ddh,2021-01-27,2020-10-29
-3ddj,2008-06-24,2008-06-05
-1ddr,1995-10-15,1995-06-29
-6dd5,2018-10-17,2018-05-09
-1dd9,2000-04-07,1999-11-09
-5ddi,2016-08-24,2015-08-24
-7zyh,2022-09-14,2022-05-24
-1zy5,2005-06-21,2005-06-09
-4zyi,2015-07-29,2015-05-21
-4zya,2016-05-25,2015-05-21
-5zyt,2018-09-19,2018-05-28
-3zyr,2012-01-11,2011-08-24
-3zyh,2011-09-21,2011-08-23
-6zy8,2021-05-26,2020-07-30
-5zyn,2018-10-03,2018-05-25
-2zyo,2009-03-31,2009-01-27
-6zyp,2021-01-20,2020-08-02
-3zy5,2011-09-14,2011-08-17
-3zyj,2011-10-05,2011-08-23
-1zyj,2005-11-08,2005-06-10
-7zyo,2022-10-12,2022-05-25
-4zy6,2015-07-01,2015-05-21
-4zyb,2015-10-21,2015-05-21
-6zyf,2021-03-10,2020-07-31
-3zya,2011-12-28,2011-08-18
-2zyl,2009-03-03,2009-01-27
-2zyp,2009-02-17,2009-01-27
-5zyi,2019-02-27,2018-05-25
-2zyu,2009-04-21,2009-01-29
-1zyd,2005-06-21,2005-06-09
-3zyg,2011-10-05,2011-08-22
-6zy9,2020-11-25,2020-07-30
-2zyk,2009-02-10,2009-01-26
-7zy3,2023-06-14,2022-05-23
-3zyp,2012-09-12,2011-08-24
-7zyd,2022-10-12,2022-05-24
-6zyn,2021-01-20,2020-08-02
-4zyj,2015-10-14,2015-05-21
-4zyy,2016-04-20,2015-05-22
-7zyl,2023-06-14,2022-05-25
-6zyk,2020-10-14,2020-08-02
-2zye,2009-03-24,2009-01-20
-1zyq,2005-11-22,2005-06-10
-4zyw,2016-04-20,2015-05-22
-3zyb,2011-09-21,2011-08-19
-2zyv,2009-04-21,2009-01-29
-3zyi,2011-10-05,2011-08-23
-3zy2,2011-09-14,2011-08-17
-7zyu,2022-06-01,2022-05-25
-2zyb,2009-02-03,2009-01-19
-6zys,2021-01-20,2020-08-02
-2zyn,2009-03-31,2009-01-27
-1zyr,2005-09-13,2005-06-10
-6zy6,2021-05-26,2020-07-30
-2zy2,2009-01-27,2009-01-13
-7zy0,2022-10-12,2022-05-23
-7zyg,2023-06-07,2022-05-24
-2zy1,2009-09-01,2009-01-10
-4zyf,2015-07-29,2015-05-21
-4zyz,2016-04-20,2015-05-22
-1zys,2006-06-13,2005-06-10
-3zy6,2011-09-14,2011-08-17
-2zy5,2009-01-27,2009-01-13
-6zyj,2020-12-16,2020-08-01
-5zym,2019-02-27,2018-05-25
-4zyr,2015-07-29,2015-05-22
-3zyn,2011-10-05,2011-08-23
-3zy3,2011-09-14,2011-08-17
-2zyq,2009-03-10,2009-01-28
-2zyr,2009-06-16,2009-01-28
-7zy8,2022-10-12,2022-05-24
-7zyi,2022-07-13,2022-05-24
-6zyw,2021-01-20,2020-08-03
-7zy5,2022-10-12,2022-05-23
-7zyf,2022-07-20,2022-05-24
-1zy2,2005-08-16,2005-06-09
-5zya,2018-06-20,2018-05-23
-6zya,2020-09-02,2020-07-31
-7zy4,2022-09-14,2022-05-23
-6zyy,2021-02-03,2020-08-03
-2zym,2009-03-31,2009-01-27
-7zym,2023-05-03,2022-05-25
-7zyy,2022-10-12,2022-05-25
-1zyx,2005-06-28,2005-06-13
-6zy5,2021-05-26,2020-07-30
-6zyo,2021-01-20,2020-08-02
-5zyk,2019-02-27,2018-05-25
-7zy2,2022-10-12,2022-05-23
-5zyv,2018-09-19,2018-05-28
-6zy0,2020-09-16,2020-07-30
-7zyz,2022-10-12,2022-05-25
-7zy1,2023-03-15,2022-05-23
-1zyt,2006-08-15,2005-06-10
-3zyz,2012-12-12,2011-08-30
-1zy7,2005-09-13,2005-06-09
-7zyc,2023-06-14,2022-05-24
-3zyc,2011-10-12,2011-08-22
-5zyc,2018-11-28,2018-05-24
-4zyc,2015-07-22,2015-05-21
-2zy3,2009-01-27,2009-01-13
-4zy1,2016-03-30,2015-05-21
-3zyu,2011-11-02,2011-08-25
-6zym,2020-10-14,2020-08-02
-4zyn,2015-08-19,2015-05-21
-6zy4,2020-11-25,2020-07-30
-6zyh,2020-12-16,2020-08-01
-5zyr,2019-06-05,2018-05-28
-7zyq,2023-05-03,2022-05-25
-7zyb,2023-06-14,2022-05-24
-2zyi,2009-06-16,2009-01-22
-4zyq,2016-03-30,2015-05-22
-4zy2,2016-03-30,2015-05-21
-5zyh,2019-02-27,2018-05-25
-1zyk,2006-05-23,2005-06-10
-3zyq,2011-09-07,2011-08-24
-7zyw,2023-11-29,2022-05-25
-2zyt,2009-04-21,2009-01-29
-7zyt,2023-06-14,2022-05-25
-1zy1,2005-09-27,2005-06-09
-3zyv,2012-09-05,2011-08-27
-5zys,2019-01-23,2018-05-28
-5zyj,2019-02-27,2018-05-25
-7zy6,2023-02-22,2022-05-24
-4zyx,2016-04-20,2015-05-22
-3zyo,2011-10-05,2011-08-24
-5zy6,2019-05-22,2018-05-22
-4zyu,2016-04-20,2015-05-22
-4zy0,2016-03-30,2015-05-21
-3zyx,2011-12-14,2011-08-29
-7zyv,2023-01-25,2022-05-25
-5zyd,2018-11-28,2018-05-24
-5zyb,2019-06-26,2018-05-23
-4zy5,2015-07-01,2015-05-21
-7zys,2022-07-13,2022-05-25
-5zyw,2018-09-19,2018-05-28
-2zya,2009-09-01,2009-01-19
-6zyq,2021-01-20,2020-08-02
-5zy9,2019-06-12,2018-05-23
-4zyo,2015-06-17,2015-05-21
-5zyu,2018-09-19,2018-05-28
-6zy1,2020-09-16,2020-07-30
-2zyw,2009-04-21,2009-01-29
-4zy4,2015-07-01,2015-05-21
-5zye,2018-11-28,2018-05-24
-2zyh,2009-06-16,2009-01-22
-7zyp,2023-05-03,2022-05-25
-6zy7,2021-05-26,2020-07-30
-6zyt,2021-08-18,2020-08-03
-5zyp,2018-09-26,2018-05-28
-3zyy,2012-04-04,2011-08-30
-4zyt,2016-04-20,2015-05-22
-3zyf,2011-09-21,2011-08-22
-4zyv,2016-04-20,2015-05-22
-2zyd,2009-09-01,2009-01-19
-7zyn,2023-05-03,2022-05-25
-7zy9,2022-08-31,2022-05-24
-2zyf,2009-12-22,2009-01-20
-2zy0,2009-08-11,2009-01-09
-1zyu,2006-07-11,2005-06-11
-6zyr,2021-01-20,2020-08-02
-6zyu,2021-08-11,2020-08-03
-1zy0,2005-09-27,2005-06-09
-6zyi,2020-12-16,2020-08-01
-5zyl,2019-02-27,2018-05-25
-1zyz,2006-03-07,2005-06-13
-4zy3,2016-05-25,2015-05-21
-7zyr,2022-10-12,2022-05-25
-7zyk,2022-12-07,2022-05-25
-7zyj,2022-09-28,2022-05-24
-6zyz,2021-02-17,2020-08-03
-2zy9,2009-12-01,2009-01-19
-2zy4,2009-01-27,2009-01-13
-5zyg,2019-02-27,2018-05-25
-6zyx,2021-01-20,2020-08-03
-2zyj,2009-09-01,2009-01-26
-5su7,2022-11-02,2022-08-26
-6suh,2020-08-05,2019-09-14
-1sua,1998-01-14,1997-01-14
-3sub,2011-11-09,2011-07-11
-8su6,2023-05-24,2023-05-11
-5su5,2022-11-02,2022-08-26
-8suu,2023-11-01,2023-05-13
-7sui,2022-01-12,2021-11-17
-8sun,2023-10-11,2023-05-12
-3sui,2012-09-12,2011-07-11
-8suc,2024-05-08,2023-05-12
-3su0,2012-09-05,2011-07-11
-5suf,2022-11-02,2022-08-26
-8sux,2024-01-10,2023-05-13
-1sui,2005-03-15,2004-03-26
-6suy,2020-01-15,2019-09-17
-5sun,2017-02-08,2016-08-03
-1sus,2005-03-15,2004-03-26
-6su9,2019-10-23,2019-09-13
-7su3,2022-01-12,2021-11-16
-1sud,1994-01-31,1992-06-10
-5su3,2022-11-02,2022-08-26
-6suo,2019-10-30,2019-09-16
-6sul,2020-07-22,2019-09-15
-3suu,2012-06-06,2011-07-11
-1sub,1994-01-31,1992-06-10
-7sup,2022-04-06,2021-11-17
-3suj,2012-07-11,2011-07-11
-7su0,2022-03-02,2021-11-15
-6su2,2020-03-04,2019-09-12
-7su6,2022-12-28,2021-11-16
-3sua,2011-09-07,2011-07-11
-1sup,1995-11-14,1995-08-14
-7suz,2022-08-31,2021-11-18
-8suk,2023-11-01,2023-05-12
-7sum,2022-07-13,2021-11-17
-8su5,2023-07-26,2023-05-11
-3su2,2012-09-05,2011-07-11
-6su0,2020-02-19,2019-09-12
-3suo,2011-11-09,2011-07-11
-3suc,2011-08-03,2011-07-11
-7sux,2022-08-31,2021-11-18
-8suf,2024-05-15,2023-05-12
-3suw,2012-06-06,2011-07-11
-6sud,2020-05-27,2019-09-13
-8sur,2023-09-06,2023-05-13
-7su2,2022-06-29,2021-11-15
-5su1,2022-11-02,2022-08-26
-5su9,2022-11-02,2022-08-26
-1suq,2004-05-11,2004-03-26
-7su4,2022-12-28,2021-11-16
-3su1,2012-09-05,2011-07-11
-5sud,2022-11-02,2022-08-26
-7suc,2022-03-02,2021-11-16
-5suw,2017-04-12,2016-08-04
-6su7,2020-09-30,2019-09-13
-3suf,2012-09-19,2011-07-11
-3suv,2012-06-06,2011-07-11
-3sug,2012-09-19,2011-07-11
-3suq,2011-11-09,2011-07-11
-8sua,2023-11-01,2023-05-11
-5su0,2022-11-02,2022-08-26
-8suw,2024-03-27,2023-05-13
-3su9,2012-03-07,2011-07-11
-7suw,2022-04-06,2021-11-18
-8sui,2023-08-16,2023-05-12
-6suk,2020-05-13,2019-09-15
-7suj,2022-01-12,2021-11-17
-1sue,1998-10-14,1998-02-17
-5sue,2022-11-02,2022-08-26
-6sut,2020-06-03,2019-09-16
-1sux,2004-08-24,2004-03-26
-1suz,2004-04-06,2004-03-26
-3sus,2012-06-06,2011-07-11
-5su2,2022-11-02,2022-08-26
-3sup,2011-11-09,2011-07-11
-7sug,2022-01-12,2021-11-17
-8su8,2023-12-06,2023-05-11
-1suc,1994-01-31,1992-06-10
-5sup,2017-01-18,2016-08-03
-6sug,2020-08-05,2019-09-14
-3su3,2012-09-05,2011-07-11
-6su4,2019-12-11,2019-09-12
-8su4,2023-07-26,2023-05-11
-7suo,2022-03-16,2021-11-17
-6sum,2020-07-22,2019-09-16
-6suw,2020-09-23,2019-09-17
-3sun,2011-11-09,2011-07-11
-5suc,2022-11-02,2022-08-26
-6sup,2019-12-04,2019-09-16
-3sur,2012-06-06,2011-07-11
-5sus,2017-01-11,2016-08-03
-5su8,2022-11-02,2022-08-26
-5su6,2022-11-02,2022-08-26
-1suo,2004-07-20,2004-03-26
-5su4,2022-11-02,2022-08-26
-7suf,2022-01-12,2021-11-17
-5sul,2017-06-14,2016-08-03
-5sur,2017-01-11,2016-08-03
-7sus,2022-07-27,2021-11-18
-6sus,2020-09-16,2019-09-16
-6su8,2019-11-06,2019-09-13
-7suh,2022-01-12,2021-11-17
-3sud,2012-09-19,2011-07-11
-8su3,2023-07-26,2023-05-11
-5suv,2017-09-13,2016-08-04
-7su7,2022-12-28,2021-11-16
-8suv,2024-03-20,2023-05-13
-6sur,2020-08-05,2019-09-16
-3su8,2011-09-28,2011-07-11
-8sub,2023-12-27,2023-05-11
-7su8,2022-12-28,2021-11-16
-6sux,2020-01-22,2019-09-17
-1su3,2004-12-21,2004-03-26
-6su5,2020-09-30,2019-09-13
-7suu,2022-11-30,2021-11-18
-7sut,2023-10-25,2021-11-18
-3su6,2012-09-05,2011-07-11
-1suv,2004-04-13,2004-03-26
-1su5,2004-08-24,2004-03-26
-6su3,2019-12-11,2019-09-12
-1sum,2004-08-24,2004-03-26
-1su0,2004-08-24,2004-03-25
-8sut,2023-11-01,2023-05-13
-1su2,2004-05-11,2004-03-26
-6suv,2020-07-22,2019-09-16
-5sua,2022-11-02,2022-08-26
-3sut,2012-06-06,2011-07-11
-6su6,2020-09-30,2019-09-13
-7su1,2022-03-02,2021-11-15
-7suy,2022-04-06,2021-11-18
-5sub,2022-11-02,2022-08-26
-6sun,2020-07-22,2019-09-16
-1su1,2004-08-17,2004-03-25
-5suk,2017-06-14,2016-08-03
-8su2,2023-07-26,2023-05-11
-8su1,2023-07-26,2023-05-11
-7sud,2022-01-12,2021-11-16
-3sue,2012-09-19,2011-07-11
-7su9,2022-06-08,2021-11-16
-5sug,2022-11-02,2022-08-26
-1su4,2004-05-04,2004-03-26
-3su5,2012-09-05,2011-07-11
-5sux,2017-04-12,2016-08-04
-8su9,2024-03-27,2023-05-11
-1suw,2004-08-24,2004-03-26
-3su4,2012-09-05,2011-07-11
-3sla,2012-02-29,2011-06-24
-8sly,2023-05-31,2023-04-24
-3sli,1999-04-27,1998-10-03
-6sl5,2020-06-24,2019-08-18
-1sl7,2004-12-28,2004-03-05
-1sl8,2004-12-28,2004-03-05
-5sl3,2022-03-16,2022-03-03
-6sl3,2020-08-26,2019-08-18
-3slh,2011-07-20,2011-06-24
-5slh,2022-03-16,2022-03-03
-1slh,2004-03-16,2004-03-05
-7sli,2023-05-03,2021-10-24
-1slv,1996-07-11,1996-02-07
-5sl9,2022-03-16,2022-03-03
-7sls,2022-11-23,2021-10-24
-5slt,2022-03-16,2022-03-03
-3sle,2012-05-02,2011-06-24
-3slu,2012-02-01,2011-06-26
-3sl4,2011-10-26,2011-06-24
-5slv,2022-03-16,2022-03-03
-5slp,2022-03-16,2022-03-03
-3slr,2011-07-20,2011-06-24
-6sl2,2020-08-26,2019-08-18
-1sl6,2004-06-15,2004-03-05
-3slk,2012-05-30,2011-06-24
-7slw,,2021-10-25
-5slo,2022-03-16,2022-03-03
-5sl0,2022-03-16,2022-03-03
-3sl1,2011-07-20,2011-06-23
-5sll,2022-03-16,2022-03-03
-8slg,2023-05-03,2023-04-21
-8sl9,2024-05-01,2023-04-21
-6sl0,2019-10-30,2019-08-16
-8slm,2024-03-13,2023-04-23
-5slq,2022-03-16,2022-03-03
-5sl1,2022-03-16,2022-03-03
-6sln,2020-05-20,2019-08-20
-5sly,2022-03-16,2022-03-03
-6sls,2019-10-16,2019-08-20
-8sln,2024-03-13,2023-04-23
-1sl5,2004-06-15,2004-03-05
-5sl6,2022-03-16,2022-03-03
-8slf,2023-05-03,2023-04-21
-5slf,2022-03-16,2022-03-03
-6sl1,2019-10-30,2019-08-16
-1slc,1995-01-26,1994-03-12
-3sld,2011-07-13,2011-06-24
-1sle,1996-04-03,1995-03-10
-1sl2,2004-07-06,2004-03-05
-6sle,2020-06-24,2019-08-19
-5slk,2022-03-16,2022-03-03
-7sl8,2021-12-15,2021-10-23
-6sl6,2020-03-11,2019-08-18
-8slh,2023-05-03,2023-04-21
-5sl2,2022-03-16,2022-03-03
-8slr,2024-04-03,2023-04-24
-1slw,1996-07-11,1996-02-07
-5slb,2022-03-16,2022-03-03
-6slg,2019-11-20,2019-08-19
-3slf,2011-07-20,2011-06-24
-6slv,2020-06-17,2019-08-20
-8sl7,2023-08-23,2023-04-21
-8sld,2023-05-03,2023-04-21
-7slv,2022-01-12,2021-10-25
-7slx,2022-01-12,2021-10-25
-6sli,2020-05-20,2019-08-19
-5slm,2022-03-16,2022-03-03
-6slw,2020-06-17,2019-08-20
-1slt,1994-01-31,1993-10-20
-8slc,2024-05-22,2023-04-21
-6slz,2020-09-09,2019-08-21
-7sly,2022-01-12,2021-10-25
-5slg,2022-03-16,2022-03-03
-5sli,2022-03-16,2022-03-03
-3sl6,2011-10-26,2011-06-24
-1slg,1996-04-03,1995-03-10
-5slr,2022-03-16,2022-03-03
-7slq,2022-03-30,2021-10-24
-6slt,2019-10-16,2019-08-20
-6slo,2020-09-09,2019-08-20
-5sl7,2022-03-16,2022-03-03
-7slp,2022-03-30,2021-10-24
-8slv,2024-03-20,2023-04-24
-1sld,1996-04-03,1995-03-10
-1sli,1999-04-20,1998-03-28
-5sle,2022-03-16,2022-03-03
-5slw,2022-03-16,2022-03-03
-5slx,2022-03-16,2022-03-03
-2sli,1999-04-27,1998-10-03
-7sla,2021-12-15,2021-10-23
-3sl2,2012-06-27,2011-06-23
-1slm,1996-12-17,1995-08-03
-6slk,2020-01-29,2019-08-20
-1slb,1995-01-26,1994-03-12
-5sln,2022-03-16,2022-03-03
-5sla,2022-03-16,2022-03-03
-3sl5,2011-10-26,2011-06-24
-1sla,1995-01-26,1994-03-12
-1sl9,2005-07-19,2004-03-05
-7slz,2022-01-19,2021-10-25
-6sl4,2020-03-18,2019-08-18
-8slx,2023-05-31,2023-04-24
-6slh,2020-02-12,2019-08-19
-1sly,1996-08-17,1995-08-02
-1slx,1996-07-11,1996-02-07
-3slz,2011-10-12,2011-06-27
-1slu,1996-07-11,1996-02-07
-3slb,2011-07-06,2011-06-24
-6sll,2020-01-29,2019-08-20
-3sl3,2011-10-26,2011-06-24
-5slu,2022-03-16,2022-03-03
-8sl1,2023-11-08,2023-04-20
-1sl4,2004-06-15,2004-03-05
-1sl1,2004-07-06,2004-03-05
-6slj,2020-05-20,2019-08-20
-5slj,2022-03-16,2022-03-03
-3sln,2011-07-13,2011-06-24
-5slz,2022-03-16,2022-03-03
-5sl4,2022-03-16,2022-03-03
-1sln,1996-12-17,1995-08-03
-5sl8,2022-03-16,2022-03-03
-1sl0,2004-07-06,2004-03-05
-8sl3,2024-04-03,2023-04-20
-7slr,2022-11-23,2021-10-24
-8slo,2024-04-03,2023-04-24
-3sl8,2011-10-26,2011-06-24
-5sls,2022-03-16,2022-03-03
-5slc,2022-03-16,2022-03-03
-1sl3,2004-08-03,2004-03-05
-6sl8,2020-01-29,2019-08-19
-3sl0,2011-07-20,2011-06-23
-3slp,2011-07-20,2011-06-24
-6sla,2019-12-11,2019-08-19
-6slm,2020-09-09,2019-08-20
-7slh,2023-05-03,2021-10-24
-6slb,2019-12-11,2019-08-19
-7sl9,2021-12-15,2021-10-23
-4sli,1999-05-25,1998-10-04
-6slx,2020-06-17,2019-08-20
-6slr,2020-09-09,2019-08-20
-5sld,2022-03-16,2022-03-03
-5sl5,2022-03-16,2022-03-03
-6slf,2020-03-11,2019-08-19
-3sls,2012-02-29,2011-06-25
-5plo,2017-03-15,2017-02-07
-3plw,2010-12-29,2010-11-15
-5pl6,2017-03-15,2017-02-07
-2plx,2007-08-07,2007-04-20
-5pln,2017-03-15,2017-02-07
-7plt,2021-12-22,2021-09-01
-4plz,2014-07-02,2014-05-20
-7plo,2021-11-10,2021-09-01
-8plh,2024-01-31,2023-06-27
-7plf,2022-09-07,2021-08-31
-4pla,2014-09-10,2014-05-16
-8plo,2024-01-31,2023-06-27
-4pl3,2014-09-03,2014-05-16
-5pl5,2017-03-15,2017-02-07
-2pll,2007-08-14,2007-04-19
-8plv,2024-01-31,2023-06-27
-4pln,2014-06-18,2014-05-18
-3plr,2011-09-28,2010-11-15
-8plt,2024-01-31,2023-06-27
-3pl3,2011-12-14,2010-11-12
-6plp,2021-02-10,2019-07-01
-8pls,2024-01-31,2023-06-27
-5plh,2017-03-15,2017-02-07
-8plr,2024-01-31,2023-06-27
-6plh,2020-07-08,2019-06-30
-4pl4,2014-09-03,2014-05-16
-4pl9,2014-12-17,2014-05-16
-4plv,2014-07-02,2014-05-19
-8pl2,2024-01-31,2023-06-27
-7plc,2021-11-24,2021-08-30
-2plk,2007-07-10,2007-04-19
-3pln,2011-09-28,2010-11-15
-1pl1,2004-06-22,2003-06-06
-3plz,2011-03-30,2010-11-15
-8pld,2024-01-31,2023-06-27
-6plu,2021-01-06,2019-07-01
-8plk,2024-01-31,2023-06-27
-5plj,2017-03-15,2017-02-07
-6plz,2021-01-06,2019-07-01
-2plt,1993-10-31,1993-05-06
-7pl5,2022-09-07,2021-08-28
-3pl8,2011-04-27,2010-11-14
-1plc,1993-10-31,1992-03-11
-4plh,2014-07-02,2014-05-16
-4pls,2014-12-10,2014-05-19
-4pl5,2014-09-03,2014-05-16
-4pl1,2014-05-28,2014-05-15
-6plw,2021-02-10,2019-07-01
-3plj,2011-04-06,2010-11-15
-4pl0,2014-06-18,2014-05-15
-8pl3,2024-01-31,2023-06-27
-2pl1,2007-05-22,2007-04-18
-3plf,2010-12-01,2010-11-15
-7pl1,2021-09-15,2021-08-27
-4plc,2014-07-02,2014-05-16
-5pl9,2017-03-15,2017-02-07
-8pl4,2024-01-31,2023-06-27
-6plf,2019-07-24,2019-06-30
-6pl1,2019-10-09,2019-06-30
-3pl9,2011-02-09,2010-11-14
-2plw,2007-05-08,2007-04-20
-5pli,2017-03-15,2017-02-07
-5pl0,2017-03-15,2017-02-07
-8plb,2024-01-31,2023-06-27
-3plm,2011-04-06,2010-11-15
-7pl0,2021-10-27,2021-08-27
-6pld,2020-07-01,2019-06-30
-7plh,2021-12-01,2021-08-31
-3pls,2010-11-24,2010-11-15
-2pl3,2007-05-01,2007-04-19
-5plg,2017-03-15,2017-02-07
-4plb,2014-06-18,2014-05-16
-3plh,2011-04-06,2010-11-15
-8plc,2024-01-31,2023-06-27
-3pl1,2011-01-12,2010-11-12
-6pla,2020-11-25,2019-06-30
-3pll,2011-11-02,2010-11-15
-2ply,2007-11-06,2007-04-20
-1pl4,2003-12-16,2003-06-06
-2pl0,2007-10-09,2007-04-18
-4pll,2015-07-22,2014-05-18
-7plz,2021-12-22,2021-09-01
-6plt,2021-01-06,2019-07-01
-5plp,2017-03-15,2017-02-07
-8plq,2024-01-31,2023-06-27
-5plq,2017-03-15,2017-02-07
-4plg,2014-07-02,2014-05-16
-5pl8,2017-03-15,2017-02-07
-8pli,2024-01-31,2023-06-27
-8pl7,2024-01-31,2023-06-27
-5ple,2017-03-15,2017-02-07
-6pl7,2020-07-01,2019-06-30
-1pla,1994-08-31,1994-05-20
-7plu,2021-12-22,2021-09-01
-3ply,2011-02-09,2010-11-15
-6pl9,2020-11-25,2019-06-30
-6plm,2019-11-20,2019-07-01
-5pls,2017-03-15,2017-02-07
-6plj,2020-07-08,2019-07-01
-3pla,2011-01-26,2010-11-15
-7plm,2022-03-23,2021-08-31
-7plv,2021-12-22,2021-09-01
-4pl6,2015-07-22,2014-05-16
-5pl4,2017-03-15,2017-02-07
-5plb,2017-03-15,2017-02-07
-5plc,2017-03-15,2017-02-07
-8plw,2024-01-31,2023-06-27
-6plq,2021-02-10,2019-07-01
-5pl7,2017-03-15,2017-02-07
-8plu,2024-01-31,2023-06-27
-8plj,2024-01-31,2023-06-27
-6pl4,2020-07-01,2019-06-30
-5ply,2017-03-15,2017-02-07
-8pl1,2024-01-31,2023-06-27
-6plv,2021-01-06,2019-07-01
-7plk,2022-09-07,2021-08-31
-6pl2,2019-09-04,2019-06-30
-6plc,2020-04-22,2019-06-30
-7pld,2021-11-24,2021-08-30
-4pli,2015-07-22,2014-05-18
-8ple,2024-01-31,2023-06-27
-8pl0,2024-01-31,2023-06-27
-8plg,2024-01-31,2023-06-27
-1pl7,2004-02-17,2003-06-07
-4pl8,2014-10-22,2014-05-16
-5pl1,2017-03-15,2017-02-07
-6pl8,2020-07-01,2019-06-30
-8pl5,2024-01-31,2023-06-27
-1plj,1994-07-31,1994-03-13
-5plu,2017-03-15,2017-02-07
-5pld,2017-03-15,2017-02-07
-5pll,2017-03-15,2017-02-07
-7plj,2023-03-22,2021-08-31
-3plp,2011-12-07,2010-11-15
-8plf,2024-01-31,2023-06-27
-7plw,2021-12-22,2021-09-01
-7pls,2022-08-10,2021-09-01
-8pla,2024-01-31,2023-06-27
-1pl8,2004-02-17,2003-06-07
-8pll,2024-01-31,2023-06-27
-6plr,2021-01-06,2019-07-01
-1pl6,2004-02-17,2003-06-07
-3pli,2011-04-06,2010-11-15
-3plb,2011-12-07,2010-11-15
-2pli,2007-05-22,2007-04-19
-4plf,2014-07-02,2014-05-16
-6ple,2019-11-06,2019-06-30
-5plf,2017-03-15,2017-02-07
-8pl9,2024-01-31,2023-06-27
-3pl6,2010-12-22,2010-11-13
-6plg,2019-07-24,2019-06-30
-1plu,1999-07-13,1999-06-04
-4plm,2014-06-18,2014-05-18
-1pl0,2004-04-27,2003-06-06
-6plo,2021-01-06,2019-07-01
-6plx,2021-01-06,2019-07-01
-3plq,2010-12-01,2010-11-15
-2plj,2007-07-10,2007-04-19
-8plz,2024-03-20,2023-06-27
-4plp,2015-05-27,2014-05-19
-1plk,1994-07-31,1994-03-13
-4plt,2014-07-02,2014-05-19
-4plr,2014-08-27,2014-05-19
-8ply,2024-01-31,2023-06-27
-4plw,2014-07-02,2014-05-19
-6plb,2020-11-25,2019-06-30
-2pl9,2008-01-15,2007-04-19
-5plx,2017-03-15,2017-02-07
-7ply,2021-12-22,2021-09-01
-6pli,2020-05-06,2019-07-01
-1pll,1994-07-31,1994-03-13
-1pl2,2004-06-22,2003-06-06
-7plx,2021-12-22,2021-09-01
-6pl0,2020-12-30,2019-06-30
-7pl9,2022-07-06,2021-08-29
-8pl6,2024-01-31,2023-06-27
-4ply,2014-07-02,2014-05-19
-5plm,2017-03-15,2017-02-07
-5plw,2017-03-15,2017-02-07
-2plm,2007-07-17,2007-04-20
-5plv,2017-03-15,2017-02-07
-7plp,2022-02-02,2021-09-01
-8pln,2024-01-31,2023-06-27
-8plp,2024-01-31,2023-06-27
-5plz,2017-03-15,2017-02-07
-3plk,2011-12-07,2010-11-15
-5pla,2017-03-15,2017-02-07
-7plb,2021-11-24,2021-08-30
-6pll,2020-07-08,2019-07-01
-3plg,2011-04-06,2010-11-15
-4pl7,2014-10-22,2014-05-16
-8plx,2024-01-31,2023-06-27
-6pls,2021-01-06,2019-07-01
-7plr,2022-09-14,2021-09-01
-6ply,2021-01-06,2019-07-01
-5pl2,2017-03-15,2017-02-07
-3ple,2011-04-06,2010-11-15
-5pl3,2017-03-15,2017-02-07
-5plk,2017-03-15,2017-02-07
-8pl8,2024-01-31,2023-06-27
-2pls,2007-05-22,2007-04-20
-7pli,2022-09-07,2021-08-31
-5plr,2017-03-15,2017-02-07
-1plb,1994-08-31,1994-05-20
-4plu,2015-09-30,2014-05-19
-4plo,2014-06-18,2014-05-18
-1plq,1995-03-31,1995-01-02
-1pl3,2003-07-01,2003-06-06
-2pla,2007-05-01,2007-04-19
-2plh,1996-04-03,1993-07-09
-6pl6,2020-03-18,2019-06-30
-4ple,2015-12-16,2014-05-16
-6pl3,2019-09-04,2019-06-30
-5plt,2017-03-15,2017-02-07
-3pld,2011-11-02,2010-11-15
-8plm,2024-01-31,2023-06-27
-1pl9,2004-07-13,2003-06-08
-7pl3,2022-09-07,2021-08-28
-4blj,2014-05-14,2013-05-03
-8blp,2023-10-04,2022-11-10
-2blb,2005-09-07,2005-03-03
-4bll,2014-01-15,2013-05-03
-2blf,2005-04-28,2005-03-04
-2blv,2005-09-07,2005-03-08
-1bl6,1999-07-26,1998-07-11
-4bls,2013-08-21,2013-05-04
-1bls,1995-05-08,1993-12-17
-6blf,2018-11-14,2017-11-10
-7bl4,2021-05-12,2021-01-18
-6blx,2017-12-20,2017-11-11
-7blw,2022-03-02,2021-01-19
-8bl6,2023-10-04,2022-11-09
-4blw,2013-08-21,2013-05-04
-3blp,2008-11-18,2007-12-11
-4blv,2013-08-21,2013-05-04
-6blq,2017-12-20,2017-11-11
-6blk,2017-11-22,2017-11-10
-3blb,2008-01-08,2007-12-10
-3bl5,2008-06-03,2007-12-10
-3bl0,2008-01-22,2007-12-10
-2blo,2005-09-07,2005-03-08
-7blg,2022-03-02,2021-01-18
-7blc,2022-03-02,2021-01-18
-6bl8,2018-03-07,2017-11-09
-3bll,2008-12-16,2007-12-11
-1blx,1999-06-01,1998-07-21
-2blj,2005-04-06,2005-03-04
-8bls,2023-03-08,2022-11-10
-7bl6,2021-05-12,2021-01-18
-4bl8,2013-11-27,2013-05-02
-2bl0,2005-10-13,2005-02-23
-6bl3,2018-11-14,2017-11-09
-8blt,2023-03-08,2022-11-10
-7bl3,2021-05-12,2021-01-18
-1bll,1994-01-31,1993-03-02
-4bli,2014-05-21,2013-05-03
-1blf,1997-12-03,1997-08-20
-2bl4,2005-07-06,2005-03-01
-2bl6,2006-04-10,2005-03-02
-1bl9,1999-04-27,1998-07-20
-7bl8,2022-03-02,2021-01-18
-7blt,2022-03-02,2021-01-19
-3bl9,2008-10-21,2007-12-10
-7blk,2022-03-02,2021-01-18
-3bls,1998-08-12,1998-06-04
-1bl5,1999-05-04,1998-07-23
-3blu,2008-10-21,2007-12-11
-3blw,2008-02-05,2007-12-11
-7bly,2021-09-22,2021-01-19
-8bl8,2024-05-15,2022-11-09
-6bl4,2018-11-14,2017-11-09
-1bl3,1998-09-30,1998-07-23
-6blw,2018-01-03,2017-11-11
-3bli,2008-11-11,2007-12-11
-7ble,2021-03-17,2021-01-18
-4bl5,2014-05-21,2013-05-01
-6bl0,2018-07-25,2017-11-09
-4bly,2014-01-15,2013-05-05
-2blh,2005-04-06,2005-03-04
-2bl9,2005-09-07,2005-03-02
-3blt,2009-02-10,2007-12-11
-8bl1,2023-11-22,2022-11-09
-8bl0,2023-11-22,2022-11-09
-8blo,2023-10-04,2022-11-10
-8blv,2022-12-21,2022-11-10
-4blb,2013-11-27,2013-05-02
-4blt,2013-08-21,2013-05-04
-3blf,2008-11-11,2007-12-11
-4bl9,2013-11-27,2013-05-02
-4bld,2013-11-27,2013-05-02
-3blo,2008-12-16,2007-12-11
-7bld,2022-03-02,2021-01-18
-2blq,2005-09-07,2005-03-08
-3bld,2008-12-16,2007-12-11
-8ble,2023-08-09,2022-11-09
-2bln,2005-04-08,2005-03-07
-8blf,2023-08-09,2022-11-09
-3bly,2008-12-02,2007-12-11
-4bln,2014-01-15,2013-05-03
-1bl8,1998-07-29,1998-07-23
-3ble,2008-11-11,2007-12-11
-3blq,2008-07-01,2007-12-11
-2blc,2005-09-07,2005-03-03
-8bld,2023-08-09,2022-11-09
-3bl3,2008-12-16,2007-12-10
-7blj,2022-03-02,2021-01-18
-7bl7,2022-03-02,2021-01-18
-1blh,1994-08-31,1993-09-30
-2bli,2005-04-06,2005-03-04
-3bl6,2008-06-10,2007-12-10
-6bl1,2018-07-25,2017-11-09
-1bl4,1998-09-02,1998-07-23
-7blb,2022-03-02,2021-01-18
-7bla,2022-03-02,2021-01-18
-3bl8,2008-02-19,2007-12-10
-6blp,2018-02-28,2017-11-11
-4blk,2014-01-15,2013-05-03
-4bl2,2014-05-21,2013-04-30
-8bl2,2023-08-09,2022-11-09
-7blu,2022-03-02,2021-01-19
-4blx,2014-01-15,2013-05-05
-6blj,2017-12-20,2017-11-10
-1blv,1998-07-29,1998-07-21
-6bln,2018-11-07,2017-11-10
-7blh,2022-03-02,2021-01-18
-7blq,2021-03-03,2021-01-18
-1blc,1994-01-31,1993-09-27
-2bla,2005-09-07,2005-03-02
-2blw,2005-09-07,2005-03-08
-7blf,2022-07-13,2021-01-18
-8bl7,2023-08-09,2022-11-09
-8bly,2023-08-09,2022-11-10
-7bli,2022-03-02,2021-01-18
-8blu,2022-11-30,2022-11-10
-7bl2,2021-05-12,2021-01-18
-8blb,2024-05-15,2022-11-09
-8blr,2024-05-22,2022-11-10
-4blc,1998-10-14,1998-09-27
-8blz,2023-11-22,2022-11-10
-3bla,2008-10-21,2007-12-10
-6bl2,2018-07-25,2017-11-09
-6bld,2018-01-24,2017-11-09
-3blr,2008-07-01,2007-12-11
-8blc,2023-08-09,2022-11-09
-2bl2,2005-04-05,2005-02-25
-3blj,2007-12-25,2007-12-11
-8bla,2024-05-15,2022-11-09
-8blx,2023-11-22,2022-11-10
-1blz,1999-01-13,1998-07-22
-4blr,2013-08-21,2013-05-04
-4blz,2014-01-15,2013-05-05
-3blk,2008-11-25,2007-12-11
-4bl0,2013-09-18,2013-04-30
-7blo,2021-03-03,2021-01-18
-6blb,2017-11-22,2017-11-09
-7blv,2022-03-02,2021-01-19
-4bl3,2014-05-21,2013-04-30
-7bl1,2021-03-03,2021-01-17
-4bl1,2013-05-08,2013-04-30
-6ble,2017-11-29,2017-11-10
-8blw,2023-08-16,2022-11-10
-6blo,2018-02-28,2017-11-10
-7blx,2021-12-15,2021-01-19
-4bl6,2013-06-12,2013-05-02
-7bl5,2021-05-12,2021-01-18
-2ble,2005-03-09,2005-03-03
-8blj,2023-11-22,2022-11-09
-7bl9,2022-03-02,2021-01-18
-1bl7,1999-07-26,1998-07-23
-7bls,2022-03-02,2021-01-18
-4blo,2013-08-21,2013-05-04
-1bli,1999-03-23,1998-01-07
-3bl7,2008-10-21,2007-12-10
-3bl1,2008-07-01,2007-12-10
-7blz,2022-03-02,2021-01-19
-3uh1,2012-02-01,2011-11-03
-3uhy,2011-12-28,2011-11-03
-5uhg,2017-04-12,2017-01-11
-8uh2,2024-05-08,2023-10-06
-3uhd,2011-12-28,2011-11-03
-5uhf,2017-04-12,2017-01-11
-3uhg,2011-12-28,2011-11-03
-3uht,2011-12-28,2011-11-03
-7uh6,2023-03-29,2022-03-25
-8uhg,2024-03-20,2023-10-09
-8uh0,2024-01-10,2023-10-06
-4uhi,2016-06-08,2015-03-24
-3uh4,2012-02-15,2011-11-03
-4uho,2016-04-13,2015-03-25
-7uht,2022-04-13,2022-03-27
-3uha,2012-02-01,2011-11-03
-1uhh,2005-02-08,2003-07-03
-7uhr,2022-04-13,2022-03-27
-1uhj,2005-02-08,2003-07-03
-1uhv,2003-12-23,2003-07-11
-5uhs,2017-08-02,2017-01-11
-8uho,2024-03-13,2023-10-09
-4uh3,2015-07-15,2015-03-23
-1uh3,2004-01-13,2003-06-23
-3uhh,2011-12-28,2011-11-03
-5uhb,2017-04-12,2017-01-11
-5uhw,2017-01-25,2017-01-12
-1uh1,2003-09-23,2003-06-23
-7uhk,2022-04-13,2022-03-27
-4uhv,2016-01-27,2015-03-25
-6uh0,2019-12-18,2019-09-26
-1uh4,2004-01-13,2003-06-24
-8uh9,2023-12-20,2023-10-07
-7uhl,2022-04-13,2022-03-27
-5uh9,2017-04-12,2017-01-11
-4uhg,2016-04-13,2015-03-24
-4uhw,2015-09-02,2015-03-26
-3uhs,2011-12-28,2011-11-03
-5uhv,2017-06-28,2017-01-12
-7uho,2022-07-13,2022-03-27
-8uh4,2023-11-22,2023-10-06
-1uhi,2005-02-08,2003-07-03
-7uhy,2022-07-20,2022-03-27
-5uhc,2017-04-12,2017-01-11
-8uh5,2023-12-13,2023-10-06
-3uhv,2011-12-28,2011-11-03
-7uhh,2022-04-13,2022-03-27
-5uha,2017-04-12,2017-01-11
-4uh6,2015-07-15,2015-03-23
-5uhl,2017-03-29,2017-01-11
-3uhf,2012-05-30,2011-11-03
-6uh8,2020-02-26,2019-09-27
-4uhx,2015-09-02,2015-03-26
-4uhl,2016-06-15,2015-03-24
-6uhx,2020-08-05,2019-09-29
-4uhn,2016-04-13,2015-03-25
-7uhe,2022-08-17,2022-03-26
-1uhl,2004-06-01,2003-07-03
-4uh4,2015-07-15,2015-03-23
-5uho,2017-03-29,2017-01-11
-7uhi,2022-04-13,2022-03-27
-5uh5,2017-04-12,2017-01-10
-5uhe,2017-04-12,2017-01-11
-5uht,2017-12-27,2017-01-12
-7uhx,2022-04-06,2022-03-27
-3uhi,2011-12-28,2011-11-03
-3uhw,2011-12-28,2011-11-03
-7uhn,2022-04-13,2022-03-27
-3uh7,2011-12-28,2011-11-03
-3uhx,2011-12-28,2011-11-03
-4uhq,2015-08-05,2015-03-25
-7uh9,2022-06-15,2022-03-26
-1uhk,2005-02-08,2003-07-03
-1uho,2004-07-09,2003-07-09
-8uhl,2024-06-05,2023-10-09
-5uhz,2017-02-01,2017-01-12
-3uhe,2011-12-28,2011-11-03
-4uh9,2015-07-15,2015-03-23
-7uhg,2022-05-11,2022-03-26
-4uhj,2016-04-13,2015-03-24
-8uhd,2024-03-20,2023-10-08
-5uhu,2017-08-23,2017-01-12
-5uh6,2017-04-12,2017-01-11
-7uhv,2022-04-06,2022-03-27
-3uhj,2011-11-23,2011-11-03
-5uhd,2017-04-12,2017-01-11
-3uh2,2012-02-15,2011-11-03
-4uhm,2016-04-13,2015-03-25
-7uhb,2022-06-08,2022-03-26
-7uha,2022-06-15,2022-03-26
-8uh3,2024-05-01,2023-10-06
-4uh7,2015-07-15,2015-03-23
-3uhk,2011-12-28,2011-11-03
-1uh0,2003-09-23,2003-06-23
-1uh2,2004-01-13,2003-06-23
-4uhs,2016-04-13,2015-03-25
-4uhk,2016-04-13,2015-03-24
-5uhn,2017-02-22,2017-01-11
-6uhh,2020-08-05,2019-09-27
-7uhf,2022-05-11,2022-03-26
-3uh0,2012-02-22,2011-11-03
-8uhi,2024-01-03,2023-10-09
-7uhw,2022-04-06,2022-03-27
-3uhl,2012-03-28,2011-11-03
-7uh8,2022-08-17,2022-03-25
-3uhr,2011-12-28,2011-11-03
-8uhe,2024-01-03,2023-10-09
-8uhz,2024-05-15,2023-10-09
-3uh5,2011-12-28,2011-11-03
-3uhn,2011-12-28,2011-11-03
-5uh8,2017-04-12,2017-01-11
-7uhj,2022-04-13,2022-03-27
-7uhm,2022-06-29,2022-03-27
-3uhq,2011-12-28,2011-11-03
-8uha,2024-03-20,2023-10-08
-4uh2,2015-07-15,2015-03-23
-6uhz,2020-04-15,2019-09-29
-6uh5,2019-11-20,2019-09-26
-6uh4,2020-02-19,2019-09-26
-1uhb,2004-07-27,2003-06-27
-6uh2,2019-10-09,2019-09-26
-3uh3,2011-12-28,2011-11-03
-4uhf,2015-06-10,2015-03-24
-1uhg,2003-07-22,2003-07-03
-4uhd,2015-06-10,2015-03-24
-6uh3,2019-12-04,2019-09-26
-6uhc,2020-07-01,2019-09-27
-7uhc,2022-06-08,2022-03-26
-3uhz,2011-12-28,2011-11-03
-4uh8,2015-07-15,2015-03-23
-3uh6,2011-12-28,2011-11-03
-4uha,2015-07-15,2015-03-23
-4uhr,2015-04-08,2015-03-25
-1uh5,2004-09-28,2003-06-24
-3uhu,2011-12-28,2011-11-03
-7uh3,2023-03-29,2022-03-25
-3uhm,2012-02-01,2011-11-03
-1uha,2004-04-13,2003-06-27
-1uhe,2004-07-13,2003-07-01
-4uh5,2015-07-15,2015-03-23
-3uhb,2011-12-28,2011-11-03
-1uhn,2003-11-04,2003-07-07
-7uhq,2022-04-13,2022-03-27
-4uh0,2015-07-15,2015-03-23
-7uhp,2022-04-13,2022-03-27
-6uhv,2019-12-04,2019-09-28
-5uhi,2017-04-05,2017-01-11
-3uho,2012-05-30,2011-11-03
-8uhb,2024-01-10,2023-10-08
-6uhy,2020-04-15,2019-09-29
-3uhc,2011-12-28,2011-11-03
-4uh1,2015-07-15,2015-03-23
-4cpq,2014-12-17,2014-02-08
-6cpu,2019-02-20,2018-03-14
-1cpd,1994-11-01,1994-08-18
-6cpn,2018-06-06,2018-03-13
-4cp1,2015-02-18,2014-01-31
-8cpx,2023-03-15,2023-03-03
-3cp0,2008-04-15,2008-03-30
-6cpq,2019-03-20,2018-03-13
-8cp8,2024-03-13,2023-03-02
-8cpw,2023-03-15,2023-03-03
-4cpz,2014-05-14,2014-02-09
-7cp1,2021-05-19,2020-08-05
-1cpf,1994-11-01,1994-08-18
-8cpp,1991-07-15,1990-05-18
-4cpm,2014-05-14,2014-02-07
-4cps,2014-12-17,2014-02-08
-4cph,2014-08-06,2014-02-06
-7cpv,2022-02-02,2020-08-08
-3cpl,2008-11-18,2008-03-31
-8cpu,2023-03-15,2023-03-03
-8cp5,2023-07-12,2023-03-01
-3cps,2008-04-15,2008-04-01
-3cp5,2008-10-28,2008-03-31
-5cpb,2015-08-19,2015-07-21
-3cpu,2001-06-30,1999-06-08
-5cp8,2015-08-05,2015-07-21
-4cpk,2014-09-10,2014-02-07
-5cpd,2016-08-03,2015-07-21
-4cp5,2015-02-11,2014-01-31
-7cp4,2021-08-11,2020-08-06
-4cpw,2014-12-17,2014-02-08
-5cpr,2017-01-25,2015-07-21
-4cpt,2014-12-17,2014-02-08
-4cpv,1990-10-15,1989-10-18
-7cpi,2021-06-16,2020-08-07
-7cp0,2021-01-13,2020-08-05
-1cpn,1994-06-22,1994-03-11
-6cpg,2018-06-27,2018-03-13
-8cpi,2023-07-12,2023-03-02
-7cp3,2021-08-11,2020-08-05
-1cp0,1999-06-14,1999-06-07
-5cpt,2015-11-04,2015-07-21
-5cp4,1998-09-16,1998-05-28
-7cpz,2021-07-14,2020-08-08
-4cpd,2014-12-17,2014-02-05
-3cpc,2008-06-17,2008-03-31
-8cpt,2023-03-15,2023-03-03
-8cp2,2023-07-12,2023-03-01
-6cp5,2018-04-11,2018-03-13
-5cph,2016-02-03,2015-07-21
-7cpq,2021-08-11,2020-08-07
-1cp5,1999-06-14,1999-06-07
-6cp6,2018-04-11,2018-03-13
-5cpa,1982-07-29,1982-05-06
-5cpp,1991-07-15,1990-05-18
-7cpc,2021-06-16,2020-08-06
-5cp2,2016-02-24,2015-07-21
-1cph,1993-01-15,1992-10-30
-6cpt,2019-02-20,2018-03-14
-5cp5,2016-01-13,2015-07-21
-3cp9,2008-06-17,2008-03-31
-6cpw,2018-05-23,2018-03-14
-6cpl,2018-06-06,2018-03-13
-4cpa,1982-07-29,1982-03-24
-6cpp,1991-07-15,1990-05-18
-2cpu,2001-06-30,1999-06-08
-3cpm,2008-07-22,2008-03-31
-1cpx,1998-08-05,1998-07-27
-4cpf,2014-08-06,2014-02-06
-1cp7,2000-05-03,1999-06-10
-1cpg,1994-11-01,1994-08-18
-1cpr,1997-01-27,1996-04-09
-3cpp,1990-04-15,1989-07-05
-7cp5,2021-07-21,2020-08-06
-4cp7,2014-12-10,2014-01-31
-7cpo,2021-01-27,2020-08-07
-5cpm,2016-01-20,2015-07-21
-6cpo,2018-06-06,2018-03-13
-7cpy,2021-01-13,2020-08-08
-3cp8,2008-06-24,2008-03-31
-8cp4,2024-01-31,2023-03-01
-2cp4,1993-01-15,1991-06-04
-1cpm,1994-06-22,1994-03-11
-4cpn,2014-05-14,2014-02-08
-7cpx,2021-01-13,2020-08-08
-8cpm,2023-03-15,2023-03-03
-1cpo,1997-02-12,1996-02-10
-7cpd,2021-08-11,2020-08-06
-4cpl,2014-05-14,2014-02-07
-6cpm,2019-01-23,2018-03-13
-7cpp,1991-07-15,1990-05-18
-6cpr,2018-05-09,2018-03-14
-5cpz,2015-10-28,2015-07-21
-7cpr,2021-08-11,2020-08-07
-1cpq,1996-12-07,1995-08-14
-1cp6,1999-06-17,1999-06-08
-6cpa,1991-10-15,1990-02-15
-1cpw,1999-06-14,1999-06-07
-4cp9,2014-10-08,2014-02-04
-8cpa,1994-01-31,1991-05-21
-3cpx,2008-04-29,2008-04-01
-5cps,2015-11-04,2015-07-21
-1cpc,1993-01-15,1990-10-11
-8cp9,2023-09-20,2023-03-02
-5cpl,2016-01-20,2015-07-21
-5cpw,2015-10-28,2015-07-21
-4cp3,2014-03-19,2014-01-31
-6cp4,1998-09-16,1998-05-28
-3cpb,2008-06-17,2008-03-31
-7cp6,2020-12-30,2020-08-06
-7cpu,2022-02-02,2020-08-08
-1cpy,1995-09-15,1995-03-24
-8cp3,2024-01-31,2023-03-01
-4cpb,2014-10-08,2014-02-04
-8cph,2023-07-12,2023-03-02
-5cp0,2016-08-03,2015-07-21
-7cpl,2020-09-02,2020-08-07
-3cpw,2008-07-22,2008-04-01
-4cpo,2014-05-14,2014-02-08
-8cp0,2023-07-19,2023-03-01
-3cp4,1993-01-15,1991-06-04
-5cpn,2016-01-20,2015-07-21
-3cpj,2008-05-06,2008-03-31
-8cpv,2023-03-15,2023-03-03
-3cph,2008-05-06,2008-03-31
-5cpy,2015-10-28,2015-07-21
-4cpp,1991-07-15,1990-05-18
-5cpv,1990-10-15,1990-01-24
-5cpx,2015-10-28,2015-07-21
-4cpu,2014-12-17,2014-02-08
-6cp3,2018-04-11,2018-03-13
-4cpy,2014-05-14,2014-02-09
-8cps,2023-03-15,2023-03-03
-3cpo,2008-09-23,2008-03-31
-1cpu,1999-06-14,1999-06-07
-8cpb,2023-09-20,2023-03-02
-5cpo,2016-01-20,2015-07-21
-4cp4,1993-01-15,1991-06-04
-5cpe,2016-01-13,2015-07-21
-3cp6,2008-04-15,2008-03-31
-4cpx,2014-12-17,2014-02-08
-1cps,1993-10-31,1992-02-18
-5cp3,2015-08-05,2015-07-21
-4cp0,2015-02-18,2014-01-31
-4cp2,2015-02-18,2014-01-31
-1cp9,1999-06-24,1999-06-12
-7cph,2021-06-02,2020-08-07
-5cpf,2015-08-12,2015-07-21
-4cpr,2014-12-17,2014-02-08
-6cpd,2018-10-31,2018-03-13
-3cpe,2009-01-13,2008-03-31
-4cpe,2014-08-06,2014-02-06
-6cpf,2018-06-27,2018-03-13
-1cpt,1994-01-31,1993-11-23
-7cpk,2020-09-02,2020-08-07
-3cpa,1982-07-29,1982-03-24
-2cpo,1997-02-12,1996-02-10
-5cp9,2015-08-12,2015-07-21
-1cpi,1996-03-08,1995-10-16
-1cpe,1994-11-01,1994-08-18
-7cp7,2020-12-30,2020-08-06
-8cp7,2023-12-27,2023-03-02
-1cp3,1997-12-24,1996-12-12
-1cp4,1993-01-15,1991-06-04
-4cpi,2014-08-06,2014-02-06
-2cpp,1987-07-16,1987-04-06
-6cpv,2018-09-12,2018-03-14
-7cpa,1994-01-31,1991-05-21
-7cp8,2021-09-15,2020-08-06
-4r25,2015-03-04,2014-08-08
-2r2b,2008-12-30,2007-08-24
-2r23,2008-12-30,2007-08-24
-2r28,2008-07-01,2007-08-24
-6r2c,2019-09-11,2019-03-15
-5r2d,2020-06-03,2020-02-13
-2r2n,2007-12-04,2007-08-27
-7r2g,2022-06-08,2022-02-04
-4r2n,2015-08-12,2014-08-12
-6r2r,2019-08-28,2019-03-18
-7r2k,2023-08-16,2022-02-04
-6r27,2020-04-01,2019-03-15
-5r24,2020-06-03,2020-02-13
-3r2l,2011-05-25,2011-03-14
-4r29,2014-12-03,2014-08-11
-6r2p,2019-08-28,2019-03-18
-1r27,2004-02-17,2003-09-26
-4r2w,2014-12-10,2014-08-13
-3r2b,2011-05-25,2011-03-14
-6r2o,2020-01-29,2019-03-18
-4r2u,2015-07-01,2014-08-13
-7r29,2023-02-15,2022-02-04
-2r24,2008-12-23,2007-08-24
-5r2b,2020-06-03,2020-02-13
-6r2t,2019-08-28,2019-03-18
-2r2u,2008-07-22,2007-08-27
-1r2n,2003-10-28,2003-09-29
-6r2e,2019-04-10,2019-03-16
-4r2q,2014-10-08,2014-08-12
-2r2d,2007-10-09,2007-08-24
-7r2b,2022-05-18,2022-02-04
-2r2k,2007-09-18,2007-08-26
-7r27,2022-08-03,2022-02-04
-2r2g,2008-01-15,2007-08-24
-7r2z,2023-02-15,2022-02-06
-6r2w,2019-12-11,2019-03-19
-2r2w,2007-10-23,2007-08-28
-1r2f,1999-01-13,1998-08-24
-4r2p,2014-10-08,2014-08-12
-6r2b,2019-09-11,2019-03-15
-6r2q,2020-04-22,2019-03-18
-5r26,2020-06-03,2020-02-13
-5r20,2020-06-03,2020-02-13
-1r2y,2003-10-14,2003-09-30
-4r2e,2014-10-08,2014-08-11
-2r2e,2008-12-30,2007-08-24
-6r2a,2019-09-11,2019-03-15
-5r21,2020-06-03,2020-02-13
-6r2j,2020-01-29,2019-03-18
-7r2l,2023-02-15,2022-02-04
-4r21,2014-12-31,2014-08-08
-1r2j,2003-11-25,2003-09-28
-7r2s,2023-02-15,2022-02-05
-4r2d,2014-10-08,2014-08-11
-4r2b,2014-08-27,2014-08-11
-4r2s,2014-10-08,2014-08-12
-8r2i,2024-01-31,2023-11-06
-7r2j,2023-02-15,2022-02-04
-5r23,2020-06-03,2020-02-13
-2r2t,2008-07-22,2007-08-27
-3r21,2011-08-10,2011-03-11
-3r2c,2011-06-22,2011-03-14
-3r2f,2011-08-31,2011-03-14
-1r2u,2004-06-08,2003-09-29
-1r2r,2003-12-23,2003-09-29
-1r20,2003-11-18,2003-09-25
-3r2r,2011-05-25,2011-03-14
-3r2m,2011-05-25,2011-03-14
-5r29,2020-06-03,2020-02-13
-4r20,2014-12-31,2014-08-08
-2r25,2008-01-15,2007-08-24
-3r2j,2011-08-24,2011-03-14
-3r24,2011-10-26,2011-03-13
-3r2d,2011-06-22,2011-03-14
-4r2h,2016-01-13,2014-08-12
-5r25,2020-06-03,2020-02-13
-2r2m,2008-08-26,2007-08-27
-8r2g,2023-11-22,2023-11-05
-3r2n,2011-03-23,2011-03-14
-3r2a,2011-05-25,2011-03-14
-4r2c,2014-10-08,2014-08-11
-4r2l,2015-02-04,2014-08-12
-7r2m,2023-05-17,2022-02-04
-5r2a,2020-06-03,2020-02-13
-2r2i,2007-12-11,2007-08-25
-4r2k,2015-02-04,2014-08-12
-4r2g,2014-10-08,2014-08-11
-4r2a,2014-10-08,2014-08-11
-7r2u,2023-02-15,2022-02-05
-1r2m,2004-01-13,2003-09-29
-7r2d,2023-02-15,2022-02-04
-3r22,2011-08-10,2011-03-11
-1r2q,2003-12-23,2003-09-29
-1r2z,2003-10-14,2003-09-30
-5r2c,2020-06-03,2020-02-13
-1r22,2004-05-18,2003-09-25
-6r2i,2020-07-15,2019-03-18
-6r29,2019-09-11,2019-03-15
-7r2i,2023-02-15,2022-02-04
-5r27,2020-06-03,2020-02-13
-7r2t,2023-05-17,2022-02-05
-7r2f,2022-04-27,2022-02-04
-4r2j,2015-02-04,2014-08-12
-3r2k,2011-05-25,2011-03-14
-4r2y,2014-10-29,2014-08-13
-2r2v,2008-06-17,2007-08-27
-3r2y,2011-05-25,2011-03-15
-5r22,2020-06-03,2020-02-13
-3r25,2012-03-14,2011-03-13
-7r2x,2023-02-15,2022-02-06
-2r2s,2008-07-22,2007-08-27
-4r23,2014-09-17,2014-08-08
-3r2q,2012-03-14,2011-03-14
-7r2p,2023-02-15,2022-02-05
-3r2x,2011-05-11,2011-03-14
-5r28,2020-06-03,2020-02-13
-2r2z,2007-09-04,2007-08-28
-3r2u,2011-03-23,2011-03-14
-3r2o,2011-05-25,2011-03-14
-7r2y,2023-02-15,2022-02-06
-1r2c,2004-04-27,2003-09-26
-2r2r,2008-07-22,2007-08-27
-6r25,2019-04-24,2019-03-15
-6r2u,2019-09-18,2019-03-18
-3r2h,2011-05-25,2011-03-14
-1r23,2004-05-18,2003-09-25
-6r2z,2019-08-28,2019-03-19
-4r2f,2014-08-27,2014-08-11
-2r26,2008-08-12,2007-08-24
-6r2d,2019-09-11,2019-03-15
-7r2v,2022-03-09,2022-02-06
-6r2l,2020-02-26,2019-03-18
-3r2s,2011-05-25,2011-03-14
-2r2h,2008-12-30,2007-08-25
-4r2m,2015-02-04,2014-08-12
-7r26,2022-05-18,2022-02-04
-7r2w,2022-07-13,2022-02-06
-2r27,2007-12-11,2007-08-24
-2r2l,2008-03-11,2007-08-27
-6r26,2020-04-01,2019-03-15
-7r2o,2023-02-15,2022-02-05
-7r2r,2023-02-15,2022-02-05
-4r2i,2016-01-13,2014-08-12
-7r2c,2023-02-15,2022-02-04
-3r28,2012-08-08,2011-03-14
-4r2r,2014-10-08,2014-08-12
-4abj,2012-03-07,2011-12-08
-1abt,1994-01-31,1993-11-17
-7abt,2021-06-23,2020-09-08
-4abd,2012-02-08,2011-12-08
-6ab9,2019-07-31,2018-07-20
-7abs,2021-08-04,2020-09-08
-4abz,2012-12-26,2011-12-12
-5abe,2015-11-18,2015-08-05
-3abl,2010-01-19,2009-12-16
-7abd,2021-10-06,2020-09-07
-6abw,2019-01-16,2018-07-24
-8abm,2023-01-11,2022-07-04
-8abf,2023-01-11,2022-07-04
-1abr,1995-02-07,1994-11-11
-8ab3,2022-07-27,2022-07-04
-3aba,2010-04-07,2009-12-04
-5aby,2015-09-02,2015-08-09
-2ab6,2005-08-02,2005-07-14
-5abx,2015-09-02,2015-08-09
-4aba,2012-02-08,2011-12-08
-7abg,2020-12-23,2020-09-07
-1abj,1994-01-31,1992-08-24
-2ab3,2005-08-02,2005-07-14
-6ab8,2019-04-17,2018-07-20
-8aby,2022-10-19,2022-07-05
-3abx,2010-01-05,2009-12-24
-2abi,2006-07-25,2005-07-15
-3abr,2010-06-02,2009-12-21
-4ab2,2012-12-12,2011-12-06
-1aby,1998-02-25,1997-01-29
-2abj,2006-06-27,2005-07-15
-3abb,2010-04-07,2009-12-04
-4abh,2012-02-08,2011-12-08
-5abt,2016-09-28,2015-08-08
-6abu,2019-07-31,2018-07-24
-3abk,2010-03-09,2009-12-16
-6ab1,2019-04-17,2018-07-19
-5abh,2015-11-18,2015-08-05
-4abo,2012-06-06,2011-12-09
-8ab2,2022-08-03,2022-07-04
-3abm,2010-01-19,2009-12-16
-8ab5,2023-10-25,2022-07-04
-8abp,1991-10-15,1991-04-25
-6aba,2019-07-31,2018-07-20
-2abm,2005-09-20,2005-07-15
-1abw,1998-06-17,1997-01-29
-6abm,2019-04-17,2018-07-22
-8abk,2023-01-11,2022-07-04
-5abz,2016-03-09,2015-08-10
-3ab1,2010-11-24,2009-11-30
-8abr,2023-07-12,2022-07-04
-2abz,2006-01-31,2005-07-18
-5abq,2015-11-04,2015-08-07
-7ab8,2021-01-13,2020-09-07
-3abt,2010-07-07,2009-12-21
-5abw,2015-08-19,2015-08-10
-8aba,2023-01-11,2022-07-04
-4abk,2012-12-19,2011-12-08
-4abv,2012-09-26,2011-12-11
-3ab6,2010-12-01,2009-12-01
-3abv,2011-02-09,2009-12-22
-1abb,1993-10-31,1992-04-09
-2ab8,2006-07-25,2005-07-14
-8abs,2023-07-12,2022-07-04
-5abg,2015-11-18,2015-08-05
-4ab1,2012-03-07,2011-12-06
-4abf,2012-02-08,2011-12-08
-2abe,2005-10-25,2005-07-15
-5ab0,2015-09-30,2015-07-31
-6ab0,2019-04-17,2018-07-19
-2abb,2005-10-11,2005-07-15
-7ab2,2020-10-28,2020-09-05
-7abj,2021-10-06,2020-09-07
-7abo,2021-04-07,2020-09-08
-4abe,2012-02-08,2011-12-08
-5abp,1992-10-15,1990-12-26
-8ab8,2023-01-11,2022-07-04
-5abu,2015-09-02,2015-08-09
-5abf,2015-11-18,2015-08-05
-2aba,2005-10-11,2005-07-15
-7abb,2020-12-02,2020-09-07
-7abr,2021-10-06,2020-09-08
-1abs,1997-04-01,1997-01-28
-5ab9,2015-12-16,2015-08-04
-8abv,2023-02-01,2022-07-04
-5ab8,2015-11-04,2015-08-04
-7abm,2021-07-07,2020-09-08
-3abo,2010-06-02,2009-12-21
-5ab3,2016-09-28,2015-07-31
-8ab4,2023-07-12,2022-07-04
-4abt,2011-12-28,2011-12-11
-8abh,2023-01-11,2022-07-04
-7abi,2021-02-10,2020-09-07
-6abn,2019-07-24,2018-07-22
-2ab4,2005-12-13,2005-07-14
-7abf,2020-12-09,2020-09-07
-3abu,2010-07-07,2009-12-21
-6abk,2019-04-17,2018-07-22
-8ab7,2023-01-11,2022-07-04
-8ab0,2023-04-26,2022-07-04
-8abe,2023-01-11,2022-07-04
-3abg,2010-08-18,2009-12-10
-3abs,2010-06-02,2009-12-21
-8ab6,2023-01-11,2022-07-04
-7aba,2020-12-02,2020-09-07
-8abx,2022-08-24,2022-07-05
-5ab7,2016-05-04,2015-08-02
-7abp,1991-10-15,1991-04-25
-6aby,2019-03-20,2018-07-24
-6ab6,2019-03-20,2018-07-20
-8abi,2023-01-11,2022-07-04
-7abn,2021-04-07,2020-09-08
-4ab9,2012-02-08,2011-12-08
-4ab7,2012-05-02,2011-12-07
-3abq,2010-06-02,2009-12-21
-3ab3,2010-12-29,2009-11-30
-7abv,2021-07-07,2020-09-08
-8abz,2022-10-19,2022-07-05
-3ab4,2010-06-23,2009-11-30
-5aba,2015-12-16,2015-08-04
-7abz,2021-08-18,2020-09-09
-5ab6,2016-05-04,2015-08-01
-8abt,2023-02-01,2022-07-04
-5abs,2016-07-13,2015-08-07
-4ab3,2012-12-12,2011-12-06
-4abg,2012-02-08,2011-12-08
-1abf,1993-10-31,1992-04-23
-4abw,2012-09-26,2011-12-11
-4ab4,2012-12-19,2011-12-06
-8abw,2023-02-01,2022-07-04
-8abb,2023-01-11,2022-07-04
-4abb,2012-02-08,2011-12-08
-2abs,2006-01-24,2005-07-16
-7ab1,2020-10-28,2020-09-05
-6ab2,2019-04-17,2018-07-19
-7aby,2021-04-21,2020-09-09
-5ab2,2015-09-30,2015-07-31
-8abq,2023-06-21,2022-07-04
-3ab2,2010-06-23,2009-11-30
-7ab7,2021-04-21,2020-09-06
-4abq,2012-09-26,2011-12-10
-5abd,2016-09-28,2015-08-05
-8ab9,2023-01-11,2022-07-04
-3ab9,2010-04-07,2009-12-04
-5abo,2015-11-04,2015-08-07
-3abw,2011-02-02,2009-12-24
-9abp,1992-01-15,1991-11-15
-7abu,2020-12-02,2020-09-08
-8abu,2023-02-01,2022-07-04
-8abl,2023-01-11,2022-07-04
-8abo,2023-07-12,2022-07-04
-7abw,2021-09-01,2020-09-09
-1ab8,1997-05-15,1997-02-04
-4abi,2012-03-07,2011-12-08
-5abn,2015-11-04,2015-08-07
-5abm,2015-09-16,2015-08-07
-6abp,1991-10-31,1991-04-25
-8abg,2023-01-11,2022-07-04
-7abe,2021-10-06,2020-09-07
-8abj,2023-01-11,2022-07-04
-2ab2,2005-07-26,2005-07-14
-4ab8,2012-02-08,2011-12-08
-5abj,2015-09-09,2015-08-06
-1abe,1993-10-31,1992-04-23
-3abi,2009-12-29,2009-12-14
-4abu,2012-09-26,2011-12-11
-2ab7,2005-08-02,2005-07-14
-6abz,2019-07-31,2018-07-24
-1ab9,1997-08-20,1997-02-05
-7ab9,2021-10-06,2020-09-07
-3ab8,2010-12-15,2009-12-01
-7abx,2021-07-28,2020-09-09
-6abl,2019-04-17,2018-07-22
-7ab6,2021-04-21,2020-09-06
-6o7h,2019-07-31,2019-03-07
-6o7i,2019-07-31,2019-03-07
-4o72,2014-03-05,2013-12-24
-4o7i,2014-01-22,2013-12-24
-5o7i,2018-06-20,2017-06-08
-3o78,2010-09-29,2010-07-30
-1o79,2003-10-23,2002-10-27
-7o7j,2021-11-24,2021-04-13
-4o7b,2014-03-05,2013-12-24
-4o70,2014-03-05,2013-12-24
-7o70,2022-04-20,2021-04-12
-7o7k,2021-11-24,2021-04-13
-4o7x,2014-03-19,2013-12-26
-7o7o,2022-04-13,2021-04-13
-5o72,2018-06-06,2017-06-07
-2o7q,2007-11-20,2006-12-11
-2o7u,2007-01-23,2006-12-11
-7o7r,2022-04-13,2021-04-13
-4o7n,2014-12-31,2013-12-26
-4o7a,2014-03-05,2013-12-24
-5o7y,2018-02-14,2017-06-10
-7o72,2021-06-16,2021-04-12
-4o79,2014-02-05,2013-12-24
-4o7u,2014-12-31,2013-12-26
-4o75,2014-03-05,2013-12-24
-5o7u,2018-06-06,2017-06-09
-1o7q,2003-11-06,2002-11-12
-5o7w,2018-06-06,2017-06-09
-3o7b,2011-01-19,2010-07-30
-4o7g,2014-02-05,2013-12-24
-5o70,2017-10-25,2017-06-07
-3o7s,2011-04-20,2010-07-31
-3o73,2011-05-11,2010-07-30
-1o75,2002-11-01,2002-10-23
-2o7i,2007-03-20,2006-12-11
-5o7x,2017-08-02,2017-06-09
-5o7m,2017-11-15,2017-06-09
-7o7l,2022-04-20,2021-04-13
-3o7j,2010-09-08,2010-07-30
-1o7n,2003-02-20,2002-11-11
-1o70,2003-02-13,2002-10-23
-1o72,2003-11-13,2002-10-23
-5o7t,2017-11-29,2017-06-09
-4o7v,2014-12-31,2013-12-26
-2o7s,2007-11-20,2006-12-11
-3o70,2010-09-29,2010-07-29
-4o78,2014-03-05,2013-12-24
-1o7g,2003-02-20,2002-11-05
-4o7l,2014-12-31,2013-12-25
-2o7f,2007-01-16,2006-12-11
-1o76,2002-12-19,2002-10-23
-2o7r,2007-02-27,2006-12-11
-5o74,2017-10-11,2017-06-08
-5o7c,2018-06-06,2017-06-08
-2o7p,2007-02-13,2006-12-11
-4o7t,2014-12-31,2013-12-26
-6o70,2019-07-31,2019-03-07
-6o79,2019-07-31,2019-03-07
-2o78,2007-01-16,2006-12-10
-4o7j,2014-03-12,2013-12-24
-2o7o,2007-05-15,2006-12-11
-4o7p,2014-10-22,2013-12-26
-5o7f,2017-10-25,2017-06-08
-2o73,2007-04-10,2006-12-10
-7o7g,2021-10-06,2021-04-13
-5o79,2018-06-20,2017-06-08
-5o7a,2017-07-05,2017-06-08
-6o7c,2019-09-11,2019-03-07
-6o7y,2019-05-01,2019-03-08
-7o7s,2022-04-13,2021-04-13
-5o7e,2018-01-31,2017-06-08
-4o7c,2014-03-05,2013-12-24
-7o7t,2021-07-28,2021-04-13
-7o7p,2022-04-13,2021-04-13
-1o7d,2003-03-20,2002-10-30
-4o7r,2014-12-31,2013-12-26
-3o7r,2011-04-20,2010-07-31
-3o76,2011-06-15,2010-07-30
-6o71,2019-07-31,2019-03-07
-4o7y,2014-12-31,2013-12-26
-6o77,2019-09-18,2019-03-07
-7o75,2021-06-16,2021-04-13
-7o7n,2022-04-13,2021-04-13
-2o7d,2007-01-16,2006-12-10
-6o7e,2019-07-31,2019-03-07
-3o71,2011-06-15,2010-07-30
-1o7w,2003-02-20,2002-11-14
-2o74,2007-04-10,2006-12-10
-7o7m,2022-04-13,2021-04-13
-1o7l,2003-02-20,2002-11-08
-3o7n,2011-07-13,2010-07-30
-6o75,2019-07-31,2019-03-07
-7o73,2021-06-16,2021-04-12
-3o7l,2010-10-06,2010-07-30
-4o76,2014-03-05,2013-12-24
-3o77,2010-09-29,2010-07-30
-1o7p,2003-02-20,2002-11-11
-6o7b,2019-07-31,2019-03-07
-3o72,2011-03-16,2010-07-30
-7o7q,2022-04-13,2021-04-13
-3o7w,2010-09-08,2010-08-01
-1o7a,2003-10-23,2002-10-29
-6o7g,2019-05-22,2019-03-07
-5o7n,2018-06-20,2017-06-09
-2o72,2007-10-09,2006-12-09
-6o73,2019-07-31,2019-03-07
-3o7a,2010-10-06,2010-07-30
-6o74,2019-07-31,2019-03-07
-4o74,2014-03-05,2013-12-24
-4o7f,2014-03-05,2013-12-24
-4o77,2014-03-05,2013-12-24
-4o7w,2014-12-31,2013-12-26
-5o7v,2018-06-06,2017-06-09
-4o7d,2014-04-16,2013-12-24
-3o7u,2011-06-15,2010-07-31
-2o7b,2007-01-16,2006-12-10
-2o7e,2007-01-16,2006-12-11
-1o7m,2003-02-20,2002-11-11
-4o71,2014-03-05,2013-12-24
-5o7d,2018-06-20,2017-06-08
-2o7n,2007-03-20,2006-12-11
-7o71,2021-11-10,2021-04-12
-4o7z,2014-12-31,2013-12-26
-1o7s,2003-03-30,2002-11-12
-6o7k,2019-05-29,2019-03-08
-1o7o,2003-11-06,2002-11-11
-3o79,2010-11-24,2010-07-30
-3o75,2011-01-12,2010-07-30
-1o7v,2003-03-30,2002-11-14
-4o7s,2014-12-31,2013-12-26
-1o7h,2003-02-20,2002-11-05
-4o7e,2014-03-05,2013-12-24
-6o7z,2019-05-01,2019-03-08
-6o7f,2020-09-09,2019-03-07
-6o72,2019-09-18,2019-03-07
-6o7d,2019-07-31,2019-03-07
-5o7p,2018-05-16,2017-06-09
-5o76,2017-11-01,2017-06-08
-6o78,2019-07-31,2019-03-07
-6rr1,2020-09-02,2019-05-16
-7rry,2021-09-08,2021-08-10
-3rrd,2011-11-09,2011-04-29
-2rra,2011-04-27,2010-06-17
-1rry,2004-03-30,2003-12-09
-7rr4,2022-01-12,2021-08-09
-1rr6,2005-02-22,2003-12-08
-3rrm,2011-05-18,2011-04-29
-6rrj,2020-07-08,2019-05-20
-1rrl,2004-12-21,2003-12-08
-6rry,2020-07-08,2019-05-20
-6rr9,2020-07-08,2019-05-17
-7rrx,2021-09-22,2021-08-10
-3rre,2011-07-27,2011-04-29
-4rrx,2015-04-08,2014-11-06
-3rrf,2011-07-27,2011-04-29
-4rri,2015-07-15,2014-11-06
-4rrb,2015-07-15,2014-11-06
-2rr2,2010-10-13,2010-02-26
-1rr8,2004-07-06,2003-12-08
-7rro,2021-10-27,2021-08-10
-6rr8,2020-09-02,2019-05-17
-6rrh,2020-07-08,2019-05-18
-1rrw,2004-03-30,2003-12-09
-1rrc,2004-02-17,2003-12-08
-6rr6,2020-09-02,2019-05-17
-7rrb,2022-03-16,2021-08-09
-1rrh,2004-12-21,2003-12-08
-6rr4,2020-09-02,2019-05-17
-6rru,2020-07-08,2019-05-20
-6rrx,2020-07-08,2019-05-20
-3rr8,2012-02-15,2011-04-29
-1rr2,2004-09-07,2003-12-08
-1rro,1993-10-31,1992-08-27
-6rrm,2019-08-14,2019-05-20
-1rrq,2004-02-17,2003-12-08
-4rrk,2015-07-15,2014-11-06
-6rra,2019-08-21,2019-05-17
-6rrd,2019-12-11,2019-05-17
-3rrn,2011-05-18,2011-04-29
-4rr4,2015-11-25,2014-11-06
-7rre,2022-08-24,2021-08-09
-7rrz,2021-09-08,2021-08-10
-4rr1,2015-03-11,2014-11-05
-4rrc,2015-07-15,2014-11-06
-6rrw,2020-07-08,2019-05-20
-6rr5,2020-09-02,2019-05-17
-7rr0,2021-10-06,2021-08-08
-3rrr,2011-06-08,2011-04-30
-4rrh,2015-07-15,2014-11-06
-4rrq,2015-07-15,2014-11-06
-1rrp,1999-05-18,1999-01-15
-2rr1,1990-01-15,1988-10-03
-4rru,2015-08-12,2014-11-06
-1rrg,1996-06-20,1995-12-16
-6rr0,2019-09-18,2019-05-16
-1rrm,2004-08-17,2003-12-08
-6rrn,2020-07-08,2019-05-20
-7rrg,2022-03-23,2021-08-09
-3rr4,2012-04-25,2011-04-29
-6rr2,2020-02-19,2019-05-16
-4rrr,2015-07-15,2014-11-06
-3rrb,2011-07-27,2011-04-29
-1rrk,2004-12-14,2003-12-08
-3rr5,2012-04-11,2011-04-29
-4rrd,2015-07-15,2014-11-06
-7rrc,2022-03-16,2021-08-09
-6rr3,2019-08-21,2019-05-16
-7rrn,2023-01-18,2021-08-10
-3rrg,2012-02-15,2011-04-29
-4rr7,2015-07-15,2014-11-06
-1rr7,2004-08-17,2003-12-08
-6rrq,2020-04-15,2019-05-20
-4rr6,2015-07-15,2014-11-06
-4rra,2015-07-15,2014-11-06
-3rr3,2011-11-09,2011-04-28
-4rrs,2014-12-03,2014-11-06
-4rrv,2014-12-17,2014-11-06
-7rr5,2021-11-10,2021-08-09
-7rrp,2021-08-18,2021-08-10
-4rrl,2015-07-15,2014-11-06
-3rra,2011-05-11,2011-04-29
-7rr3,2022-01-12,2021-08-09
-3rrx,2011-12-21,2011-05-01
-3rrw,2011-08-03,2011-05-01
-4rrf,2015-07-15,2014-11-06
-6rri,2020-04-15,2019-05-18
-4rry,2015-04-08,2014-11-06
-6rrg,2020-04-15,2019-05-17
-4rrg,2015-07-15,2014-11-06
-7rrd,2022-08-24,2021-08-09
-4rro,2014-12-03,2014-11-06
-4rrj,2015-07-15,2014-11-06
-3rrh,2012-02-15,2011-04-29
-7rr9,2022-01-19,2021-08-09
-1rri,2004-03-30,2003-12-08
-3rrv,2011-05-11,2011-04-30
-4rr2,2015-01-21,2014-11-05
-4rr8,2015-07-15,2014-11-06
-4rrz,2015-04-08,2014-11-06
-6rrp,2020-04-15,2019-05-20
-4rr9,2015-07-15,2014-11-06
-4rrn,2014-12-03,2014-11-06
-4rrt,2015-01-28,2014-11-06
-2rr4,2010-09-15,2010-03-24
-7rrf,2022-08-24,2021-08-09
-4rrm,2015-07-15,2014-11-06
-3rry,2011-09-21,2011-05-02
-1rrj,2004-07-06,2003-12-08
-3rrj,2011-07-27,2011-04-29
-1rrs,2004-02-17,2003-12-08
-1rrf,1996-06-20,1995-12-16
-6rre,2020-10-07,2019-05-17
-1rru,2004-01-13,2003-12-09
-4rrw,2015-04-08,2014-11-06
-1rrv,2004-05-18,2003-12-09
-3rrz,2011-09-21,2011-05-02
-8i8k,,2023-02-04
-3i8p,2010-07-28,2009-07-09
-8i8x,2023-12-20,2023-02-05
-4i8q,2013-02-20,2012-12-04
-4i85,2013-06-19,2012-12-03
-5i8e,2016-05-25,2016-02-18
-6i8p,2019-07-31,2018-11-20
-5i8b,2016-04-20,2016-02-18
-4i8z,2013-07-24,2012-12-04
-3i8x,2009-07-28,2009-07-10
-8i81,2023-03-01,2023-02-02
-1i82,2001-06-13,2001-03-12
-6i8r,2019-11-27,2018-11-20
-8i8t,2023-03-22,2023-02-05
-4i8g,2012-12-19,2012-12-03
-1i8p,2001-04-04,2001-03-15
-4i8x,2013-01-23,2012-12-04
-5i8s,2016-03-09,2016-02-19
-1i8k,2002-03-14,2001-03-14
-5i8f,2016-05-25,2016-02-18
-4i89,2013-06-19,2012-12-03
-6i81,2019-11-27,2018-11-19
-6i8w,2019-11-27,2018-11-21
-1i8i,2002-03-14,2001-03-14
-6i8m,2019-05-01,2018-11-20
-1i8m,2001-12-07,2001-03-14
-5i8h,2016-05-25,2016-02-18
-3i8v,2009-07-21,2009-07-10
-4i8d,2012-12-19,2012-12-03
-5i85,2016-09-07,2016-02-18
-4i8c,2013-01-30,2012-12-03
-1i8n,2001-08-08,2001-03-15
-3i8a,2010-02-09,2009-07-09
-5i8d,2017-08-23,2016-02-18
-1i80,2001-08-01,2001-03-12
-6i80,2019-11-27,2018-11-19
-6i8t,2019-05-01,2018-11-21
-8i8r,2023-12-20,2023-02-05
-2i80,2006-09-26,2006-08-31
-6i8a,2019-01-30,2018-11-19
-4i8v,2013-02-27,2012-12-04
-1i8u,2001-06-13,2001-03-16
-1i8q,2002-01-16,2001-03-15
-5i8o,2016-03-23,2016-02-19
-8i8g,2024-01-10,2023-02-04
-2i8t,2007-06-19,2006-09-03
-5i88,2016-10-12,2016-02-18
-4i80,2013-03-06,2012-12-01
-3i8b,2009-08-04,2009-07-09
-8i89,2024-01-10,2023-02-03
-6i8b,2018-12-05,2018-11-19
-5i8a,2017-08-09,2016-02-18
-8i86,2024-01-10,2023-02-03
-6i8o,2019-07-31,2018-11-20
-1i8z,2001-03-28,2001-03-16
-2i8u,2007-06-19,2006-09-03
-1i8t,2001-10-03,2001-03-16
-1i8o,2001-04-04,2001-03-15
-4i8l,2012-12-19,2012-12-03
-1i8a,2001-06-13,2001-03-12
-5i89,2016-04-20,2016-02-18
-2i82,2006-11-21,2006-08-31
-8i85,2024-01-10,2023-02-03
-5i8w,2017-02-22,2016-02-19
-8i8l,,2023-02-04
-4i8h,2012-12-19,2012-12-03
-6i83,2020-03-11,2018-11-19
-2i8f,2007-06-05,2006-09-01
-8i82,2024-01-10,2023-02-03
-8i8j,2023-03-01,2023-02-04
-8i8e,2024-02-07,2023-02-04
-6i8d,2019-11-27,2018-11-20
-8i8n,,2023-02-04
-6i8l,2018-12-05,2018-11-20
-5i8x,2017-08-23,2016-02-19
-5i86,2016-04-20,2016-02-18
-8i8f,2024-02-07,2023-02-04
-5i8c,2016-05-25,2016-02-18
-5i8p,2016-06-15,2016-02-19
-1i8l,2001-04-04,2001-03-14
-6i8v,2019-10-30,2018-11-21
-3i8u,2009-10-27,2009-07-10
-6i8e,2019-07-31,2018-11-20
-4i8j,2012-12-19,2012-12-03
-4i8k,2012-12-19,2012-12-03
-6i84,2019-01-02,2018-11-19
-3i81,2009-12-22,2009-07-09
-6i8z,2019-02-20,2018-11-21
-8i84,2024-01-10,2023-02-03
-5i80,2016-10-12,2016-02-18
-6i8q,2019-07-31,2018-11-20
-5i8y,2016-03-09,2016-02-19
-5i8z,2017-02-22,2016-02-19
-5i8q,2017-02-01,2016-02-19
-3i8t,2011-02-23,2009-07-10
-4i81,2013-05-15,2012-12-01
-6i8i,2019-07-31,2018-11-20
-2i89,2006-10-31,2006-09-01
-4i87,2013-06-19,2012-12-03
-8i8h,2024-01-10,2023-02-04
-3i8r,2010-05-19,2009-07-10
-5i83,2016-04-20,2016-02-18
-5i8m,2017-08-23,2016-02-19
-8i8s,2023-03-22,2023-02-05
-5i81,2016-09-07,2016-02-18
-5i8t,2016-03-09,2016-02-19
-5i8g,2016-04-20,2016-02-18
-8i8q,2023-03-01,2023-02-05
-6i8k,2019-07-31,2018-11-20
-6i8j,2019-07-31,2018-11-20
-5i87,2016-04-20,2016-02-18
-1i83,2001-08-08,2001-03-12
-4i8n,2012-12-26,2012-12-03
-2i8c,2006-09-26,2006-09-01
-8i87,2023-07-19,2023-02-03
-6i8y,2018-12-26,2018-11-21
-5i8r,2016-09-07,2016-02-19
-1i8j,2001-06-20,2001-03-14
-8i88,2023-07-05,2023-02-03
-6i82,2020-03-11,2018-11-19
-4i8w,2013-07-24,2012-12-04
-8i8u,2023-03-01,2023-02-05
-4i8p,2013-02-20,2012-12-04
-8i8p,2023-04-12,2023-02-04
-5i8u,2016-10-12,2016-02-19
-8i8d,2024-02-07,2023-02-03
-6i8f,2019-11-27,2018-11-20
-8xbs,2024-06-05,2023-12-07
-2xbl,2010-05-19,2010-04-13
-2xbv,2010-08-04,2010-04-15
-1xbc,2004-11-02,2004-08-30
-6xbu,2021-06-09,2020-06-07
-6xbz,2020-09-09,2020-06-07
-7xba,2023-09-27,2022-03-21
-7xbv,2023-03-01,2022-03-22
-7xbu,2023-03-01,2022-03-22
-7xbk,2023-01-25,2022-03-21
-1xb8,2004-10-19,2004-08-30
-7xbe,2023-03-29,2022-03-21
-4xbt,2015-07-15,2014-12-17
-7xbn,2023-02-15,2022-03-21
-2xbn,2010-05-19,2010-04-13
-2xb5,2010-10-06,2010-04-05
-4xba,2015-06-03,2014-12-16
-2xb6,2010-06-23,2010-04-07
-6xb4,2020-11-25,2020-06-05
-6xbe,2021-03-31,2020-06-05
-4xb2,2015-07-15,2014-12-16
-7xb6,2023-03-22,2022-03-20
-4xbc,2015-03-25,2014-12-16
-1xbx,2005-04-26,2004-08-31
-6xbb,2021-03-17,2020-06-05
-1xb3,2004-10-19,2004-08-27
-2xbm,2010-09-29,2010-04-13
-6xb8,2020-12-09,2020-06-05
-6xbi,2020-06-17,2020-06-06
-6xbg,2020-06-17,2020-06-05
-2xbj,2011-01-12,2010-04-12
-7xb7,2023-09-27,2022-03-21
-2xbu,2011-05-04,2010-04-15
-2xbf,2011-03-23,2010-04-09
-8xbh,2023-12-27,2023-12-06
-4xbg,2016-02-03,2014-12-16
-7xb4,2023-03-22,2022-03-20
-5xb3,2017-06-28,2017-03-15
-5xbt,2018-05-02,2017-03-21
-2xbx,2010-08-04,2010-04-15
-1xbz,2005-04-26,2004-08-31
-5xbi,2018-03-21,2017-03-17
-2xbq,2010-07-21,2010-04-14
-2xb1,2010-07-28,2010-04-01
-6xb1,2020-06-17,2020-06-05
-4xb5,2015-07-15,2014-12-16
-4xb1,2015-07-15,2014-12-16
-1xbo,2004-10-19,2004-08-31
-5xbk,2018-02-14,2017-03-20
-6xbl,2020-09-30,2020-06-06
-6xbq,2020-07-01,2020-06-07
-7xb1,2022-07-06,2022-03-19
-7xbg,2023-01-11,2022-03-21
-4xbv,2015-09-09,2014-12-17
-6xbm,2020-09-30,2020-06-06
-7xbc,2023-03-29,2022-03-21
-4xbj,2015-12-23,2014-12-17
-5xbp,2017-04-19,2017-03-21
-2xbw,2010-08-04,2010-04-15
-8xbi,2023-12-27,2023-12-06
-2xb4,2010-09-22,2010-04-05
-2xb2,2010-05-12,2010-04-03
-7xbo,2023-02-15,2022-03-21
-6xbh,2020-06-17,2020-06-06
-6xbf,2021-03-31,2020-06-05
-6xbr,2020-07-01,2020-06-07
-1xbn,2004-09-07,2004-08-30
-1xb0,2004-11-02,2004-08-27
-2xba,2010-07-28,2010-04-08
-2xb8,2010-09-15,2010-04-08
-7xbx,2022-07-13,2022-03-22
-2xb3,2010-08-25,2010-04-03
-2xb7,2010-07-28,2010-04-08
-4xbl,2015-05-20,2014-12-17
-4xb9,2015-09-09,2014-12-16
-6xbo,2021-06-09,2020-06-06
-5xbx,2018-03-28,2017-03-21
-5xbv,2018-03-28,2017-03-21
-5xbz,2018-03-28,2017-03-21
-4xbr,2015-12-02,2014-12-17
-7xbw,2022-07-13,2022-03-22
-2xbk,2010-08-04,2010-04-12
-2xbp,2010-08-18,2010-04-14
-5xbm,2018-06-27,2017-03-20
-7xb9,2023-09-27,2022-03-21
-7xbf,2023-01-11,2022-03-21
-4xbd,2015-03-25,2014-12-16
-4xbo,2015-12-23,2014-12-17
-1xb6,2004-10-19,2004-08-30
-7xbm,2023-02-15,2022-03-21
-4xbq,2015-05-20,2014-12-17
-4xbb,2015-03-25,2014-12-16
-7xby,2022-06-08,2022-03-22
-1xbv,2005-04-26,2004-08-31
-1xb1,2004-11-02,2004-08-27
-5xbn,2018-03-28,2017-03-20
-2xb9,2010-09-15,2010-04-08
-4xbf,2016-04-27,2014-12-16
-7xbh,2023-01-11,2022-03-21
-5xb2,2017-06-28,2017-03-15
-6xb9,2021-03-03,2020-06-05
-6xb2,2020-06-17,2020-06-05
-6xb3,2020-11-25,2020-06-05
-6xbw,2020-08-19,2020-06-07
-1xbb,2004-11-02,2004-08-30
-7xbb,2022-07-06,2022-03-21
-7xb8,2023-09-27,2022-03-21
-6xbj,2020-09-30,2020-06-06
-1xbt,2004-12-14,2004-08-31
-2xbo,2010-09-22,2010-04-14
-6xbt,2020-07-01,2020-06-07
-1xby,2005-04-26,2004-08-31
-4xby,2015-07-15,2014-12-17
-6xbc,2021-03-17,2020-06-05
-4xb7,2015-12-16,2014-12-16
-7xbi,2023-03-29,2022-03-21
-6xbk,2020-09-30,2020-06-06
-6xby,2020-08-19,2020-06-07
-1xb7,2004-09-14,2004-08-30
-4xbz,2015-08-05,2014-12-17
-7xbt,2023-03-01,2022-03-22
-6xbs,2020-07-01,2020-06-07
-1xbu,2005-10-04,2004-08-31
-4xbm,2015-03-11,2014-12-17
-4xbh,2016-05-25,2014-12-16
-6xb5,2020-11-25,2020-06-05
-4xb4,2015-07-15,2014-12-16
-4xb3,2015-08-26,2014-12-16
-7xb0,2022-07-06,2022-03-19
-4xb8,2015-12-16,2014-12-16
-7xbz,2022-11-16,2022-03-22
-6xbv,2020-07-01,2020-06-07
-4xb6,2015-08-19,2014-12-16
-4xbn,2015-05-20,2014-12-17
-2xby,2010-08-04,2010-04-15
-4xbw,2015-09-09,2014-12-17
-3qee,2011-02-16,2011-01-20
-4qek,2014-07-09,2014-05-16
-7qea,2022-10-12,2021-12-01
-4qeg,2015-07-22,2014-05-16
-5qek,2018-10-10,2018-08-30
-3qe2,2011-08-03,2011-01-19
-5qe0,2018-10-10,2018-08-30
-3qeu,2011-07-06,2011-01-20
-6qe5,2019-03-27,2019-01-04
-5qeo,2018-10-10,2018-08-30
-3qes,2012-01-25,2011-01-20
-5qez,2018-10-10,2018-08-30
-7qej,2022-12-14,2021-12-03
-4qe5,2014-09-03,2014-05-15
-6qea,2019-03-27,2019-01-07
-7qe4,2022-09-14,2021-12-01
-8qez,2023-12-27,2023-09-01
-6qed,2019-05-01,2019-01-07
-3qe5,2011-04-20,2011-01-19
-3qen,2011-03-16,2011-01-20
-8qel,2023-09-13,2023-08-31
-7qep,2022-02-09,2021-12-03
-3qef,2011-02-16,2011-01-20
-5qe5,2018-10-10,2018-08-30
-2qe6,2007-07-03,2007-06-22
-3qeb,2011-04-20,2011-01-20
-5qeu,2018-10-10,2018-08-30
-4qez,2014-06-18,2014-05-19
-7qem,2023-06-14,2021-12-03
-3qe4,2011-02-16,2011-01-19
-3qe6,2012-01-25,2011-01-19
-2qee,2007-07-24,2007-06-25
-4qen,2014-07-30,2014-05-17
-5qeh,2018-10-10,2018-08-30
-1qez,1999-04-14,1999-04-06
-3qed,2011-02-16,2011-01-20
-5qej,2018-10-10,2018-08-30
-3qer,2012-01-25,2011-01-20
-5qem,2018-10-10,2018-08-30
-2qet,2008-02-26,2007-06-26
-8qe2,2024-03-20,2023-08-30
-4qef,2014-10-08,2014-05-15
-5qeb,2018-10-10,2018-08-30
-5qe3,2018-10-10,2018-08-30
-2qei,2007-08-21,2007-06-25
-5qev,2018-10-10,2018-08-30
-3qel,2011-06-15,2011-01-20
-5qe9,2018-10-10,2018-08-30
-3qep,2011-08-31,2011-01-20
-6qe0,2019-03-27,2019-01-03
-4qe7,2014-07-09,2014-05-15
-4qel,2015-05-20,2014-05-16
-1qew,2003-11-18,1999-04-02
-5qeg,2018-10-10,2018-08-30
-4qe8,2015-08-12,2014-05-15
-2qeh,2007-10-09,2007-06-25
-8qe8,2024-05-15,2023-08-30
-6qee,2019-02-27,2019-01-07
-5qe4,2018-10-10,2018-08-30
-3qew,2012-01-25,2011-01-20
-6qep,2019-11-06,2019-01-08
-6qef,2019-05-01,2019-01-07
-4qei,2015-05-20,2014-05-16
-6qe7,2019-06-12,2019-01-07
-7qen,2022-06-15,2021-12-03
-2qea,2007-07-10,2007-06-25
-5qef,2018-10-10,2018-08-30
-8qeu,2023-12-06,2023-09-01
-7qe0,2022-02-09,2021-12-01
-2qeb,2007-10-09,2007-06-25
-3qet,2012-01-25,2011-01-20
-4qec,2014-07-02,2014-05-15
-2qed,2007-10-09,2007-06-25
-5qeq,2018-10-10,2018-08-30
-5qe1,2018-10-10,2018-08-30
-3qe7,2011-03-23,2011-01-20
-5qed,2018-10-10,2018-08-30
-7qe1,2022-10-12,2021-12-01
-6qei,2019-05-01,2019-01-07
-4qeb,2015-05-20,2014-05-15
-7qe7,,2021-12-01
-4qe9,2014-07-09,2014-05-15
-4qev,2014-10-29,2014-05-19
-4qew,2014-10-29,2014-05-19
-5qe8,2018-10-10,2018-08-30
-2qe5,2007-10-02,2007-06-22
-2qe0,2007-12-25,2007-06-22
-2qer,2007-07-17,2007-06-26
-6qej,2019-05-01,2019-01-07
-8qev,2023-12-06,2023-09-01
-6qev,2019-11-06,2019-01-08
-8qed,2023-10-18,2023-08-31
-2qes,2008-02-26,2007-06-26
-2qe4,2007-09-04,2007-06-22
-8qe0,2024-03-20,2023-08-30
-3qei,2012-01-25,2011-01-20
-8qe3,2024-03-20,2023-08-30
-4qeh,2014-09-03,2014-05-16
-6qe8,2019-06-05,2019-01-07
-5qea,2018-10-10,2018-08-30
-1qe3,1999-07-21,1999-07-12
-3qeq,2011-07-06,2011-01-20
-3qe0,2012-01-25,2011-01-19
-3qev,2012-01-25,2011-01-20
-8qey,2024-04-10,2023-09-01
-4qe4,2014-09-03,2014-05-15
-6qeo,2020-04-08,2019-01-08
-5qey,2018-10-10,2018-08-30
-5qel,2018-10-10,2018-08-30
-3qej,2011-03-16,2011-01-20
-6qeb,2019-02-06,2019-01-07
-4qe3,2014-07-09,2014-05-15
-6qe6,2019-03-27,2019-01-04
-3qex,2012-01-25,2011-01-20
-8qeb,2023-10-18,2023-08-31
-7qe2,2022-10-12,2021-12-01
-8qe1,2024-03-20,2023-08-30
-4qe1,2014-09-03,2014-05-15
-5qe2,2018-10-10,2018-08-30
-3qek,2011-06-15,2011-01-20
-6qeh,2019-05-01,2019-01-07
-2qew,2007-08-21,2007-06-26
-4qee,2014-09-03,2014-05-15
-6qex,2019-02-27,2019-01-08
-8qec,2023-10-18,2023-08-31
-8qee,2023-10-18,2023-08-31
-7qez,2022-05-18,2021-12-03
-8qeo,2024-03-20,2023-09-01
-8qer,2024-01-10,2023-09-01
-6qe9,2019-02-27,2019-01-07
-7qe3,2022-09-14,2021-12-01
-5qet,2018-10-10,2018-08-30
-6qe1,2020-01-29,2019-01-03
-5qei,2018-10-10,2018-08-30
-2qe2,2007-10-02,2007-06-22
-2qey,2007-08-21,2007-06-26
-5qee,2018-10-10,2018-08-30
-2qex,2008-09-30,2007-06-26
-8qen,2024-03-20,2023-09-01
-7qek,2022-12-14,2021-12-03
-5qes,2018-10-10,2018-08-30
-1qe5,1999-12-12,1999-07-13
-3qez,2012-01-25,2011-01-20
-2qen,2008-07-01,2007-06-26
-3qeo,2011-03-16,2011-01-20
-2qe9,2007-07-10,2007-06-25
-5qep,2018-10-10,2018-08-30
-6qen,2020-03-25,2019-01-08
-5qex,2018-10-10,2018-08-30
-4qer,2014-06-18,2014-05-18
-5qew,2018-10-10,2018-08-30
-7qel,2022-12-14,2021-12-03
-4qet,2015-05-20,2014-05-19
-7qei,2022-10-12,2021-12-03
-5qe6,2018-10-10,2018-08-30
-4qep,2014-07-30,2014-05-17
-8qef,2023-12-13,2023-08-31
-4qed,2014-07-02,2014-05-15
-5qe7,2018-10-10,2018-08-30
-4qem,2014-06-18,2014-05-17
-4qeo,2014-07-30,2014-05-17
-3qe9,2011-04-20,2011-01-20
-7qee,2022-11-16,2021-12-02
-2qeo,2007-10-09,2007-06-26
-2qej,2007-09-18,2007-06-26
-5qen,2018-10-10,2018-08-30
-5qec,2018-10-10,2018-08-30
-5qer,2018-10-10,2018-08-30
-3qe3,2011-04-27,2011-01-19
-6qeg,2019-05-01,2019-01-07
-3qea,2011-04-20,2011-01-20
-3qem,2011-06-15,2011-01-20
-7qef,2022-10-12,2021-12-02
-43ca,1999-08-18,1999-03-10
-5dkg,2016-05-04,2015-09-03
-1dkx,1996-12-07,1996-06-03
-4dki,2012-08-01,2012-02-03
-8dk9,2023-01-18,2022-07-05
-4dkv,2013-03-20,2012-02-04
-1dka,1994-10-15,1993-06-18
-8dkq,2022-12-14,2022-07-05
-3dks,2009-05-12,2008-06-25
-3dkh,2009-07-07,2008-06-25
-7dk7,2020-12-02,2020-11-23
-3dke,2008-11-25,2008-06-24
-5dk9,2016-05-04,2015-09-03
-8dko,2022-12-14,2022-07-05
-2dkd,2006-05-16,2006-04-07
-5dk4,2015-11-18,2015-09-02
-4dkj,2012-12-05,2012-02-03
-4dkr,2012-05-02,2012-02-03
-2dkn,2006-08-15,2006-04-12
-2dkj,2007-04-24,2006-04-11
-3dkl,2009-08-18,2008-06-25
-4dkq,2012-05-02,2012-02-03
-7dky,2021-06-23,2020-11-25
-8dk6,2023-03-29,2022-07-03
-5dke,2016-05-04,2015-09-03
-1dkz,1996-12-07,1996-06-03
-1dkd,2000-01-12,1999-12-07
-4dk9,2012-04-25,2012-02-03
-3dko,2008-08-19,2008-06-25
-4dkx,2012-10-17,2012-02-04
-7dkt,2021-06-23,2020-11-25
-7dkm,2022-02-02,2020-11-25
-3dkv,2009-06-09,2008-06-26
-8dkn,2022-09-07,2022-07-05
-6dkd,2019-05-08,2018-05-29
-5dk8,2015-12-16,2015-09-03
-7dkz,2021-03-31,2020-11-25
-5dkl,2016-01-13,2015-09-03
-1dk4,2000-11-08,1999-12-06
-6dkh,2018-06-06,2018-05-29
-4dk5,2012-05-16,2012-02-03
-4dka,2012-07-04,2012-02-03
-8dkg,2023-02-08,2022-07-05
-6dk1,2018-10-17,2018-05-28
-3dkt,2008-09-02,2008-06-26
-3dk8,2008-08-05,2008-06-24
-4dkw,2012-06-27,2012-02-04
-5dk0,2016-03-30,2015-09-02
-5dk3,2015-11-18,2015-09-02
-6dkv,2018-08-01,2018-05-30
-5dkc,2015-10-14,2015-09-03
-4dkp,2012-05-02,2012-02-03
-3dk3,2008-07-29,2008-06-24
-5dkp,2016-01-27,2015-09-03
-8dk2,2022-10-05,2022-07-01
-7dkj,2021-11-24,2020-11-24
-3dkk,2008-12-02,2008-06-25
-3dk4,2008-08-05,2008-06-24
-7dke,2021-11-03,2020-11-23
-5dkj,2015-10-28,2015-09-03
-1dky,1996-12-07,1996-06-03
-2dkt,2006-10-14,2006-04-14
-8dkv,2022-09-07,2022-07-06
-5dks,2016-05-04,2015-09-03
-5dky,2016-01-27,2015-09-04
-2dko,2006-07-04,2006-04-12
-3dkp,2008-08-12,2008-06-25
-6dk7,2019-03-20,2018-05-29
-5dkf,2016-03-09,2015-09-03
-8dkp,2022-12-14,2022-07-05
-2dkg,2006-10-11,2006-04-11
-1dk1,2000-04-02,1999-12-06
-7dkx,2021-06-23,2020-11-25
-7dkb,2021-11-03,2020-11-23
-6dkc,2019-05-08,2018-05-29
-1dkm,2000-08-02,1999-12-08
-3dkc,2009-07-07,2008-06-24
-4dku,2013-03-20,2012-02-04
-2dki,2006-10-24,2006-04-11
-6dkb,2018-07-11,2018-05-29
-5dkz,2016-01-27,2015-09-04
-3dkx,2009-06-30,2008-06-26
-3dki,2008-09-16,2008-06-25
-5dku,2016-08-10,2015-09-04
-4dkb,2013-08-07,2012-02-03
-2dkh,2006-10-24,2006-04-11
-2dkf,2006-12-05,2006-04-10
-6dka,2019-05-08,2018-05-29
-6dkw,2018-07-11,2018-05-31
-5dkv,2015-09-30,2015-09-04
-1dkq,2000-08-03,1999-12-08
-3dk9,2008-08-05,2008-06-24
-2dkc,2006-05-16,2006-04-07
-7dkp,2021-12-08,2020-11-25
-5dkw,2016-02-24,2015-09-04
-2dkb,1994-10-15,1994-07-12
-4dk7,2012-03-21,2012-02-03
-7dk2,2021-12-08,2020-11-22
-5dka,2016-07-27,2015-09-03
-3dk7,2008-07-29,2008-06-24
-8dkr,2022-09-07,2022-07-06
-6dkt,2018-09-26,2018-05-30
-5dkr,2016-01-20,2015-09-03
-6dko,2018-09-05,2018-05-30
-7dk8,2020-12-23,2020-11-23
-6dkg,2018-07-11,2018-05-29
-8dk0,2023-01-11,2022-07-01
-3dk1,2009-05-12,2008-06-24
-1dk0,2000-12-27,1999-12-06
-8dks,2022-08-03,2022-07-06
-8dk3,2022-10-05,2022-07-01
-4dke,2012-04-11,2012-02-03
-5dki,2015-10-28,2015-09-03
-3dk6,2008-07-29,2008-06-24
-4dk8,2012-03-21,2012-02-03
-2dkk,2007-04-17,2006-04-12
-5dkd,2015-10-14,2015-09-03
-7dkd,2021-11-03,2020-11-23
-5dk2,2016-03-30,2015-09-02
-6dk9,2019-05-08,2018-05-29
-3dkf,2009-07-07,2008-06-24
-3dkg,2009-07-07,2008-06-24
-6dky,2018-11-07,2018-05-31
-4dkt,2012-02-29,2012-02-04
-3dk5,2009-05-19,2008-06-24
-6dki,2018-07-11,2018-05-29
-7dks,2021-06-23,2020-11-25
-8dky,2022-09-21,2022-07-06
-1dke,2000-05-23,1999-12-07
-1dkf,2000-04-19,1999-12-07
-7dk1,2021-06-30,2020-11-22
-1dkn,2000-08-03,1999-12-08
-8dku,2022-09-21,2022-07-06
-5dk5,2016-08-24,2015-09-03
-3dkd,2009-08-25,2008-06-24
-8dk4,2023-07-05,2022-07-02
-7dkf,2022-05-18,2020-11-24
-4dkc,2012-04-11,2012-02-03
-7dku,2021-06-23,2020-11-25
-3dkj,2009-08-18,2008-06-25
-5dkh,2016-09-14,2015-09-03
-3dky,2009-06-30,2008-06-26
-5dkt,2016-08-10,2015-09-04
-5dkq,2016-01-20,2015-09-03
-6dk4,2018-06-13,2018-05-28
-4dkd,2012-04-11,2012-02-03
-7dkw,2021-06-23,2020-11-25
-4dkl,2012-03-21,2012-02-03
-8dkm,2022-09-21,2022-07-05
-4dkf,2012-04-11,2012-02-03
-5dkb,2016-05-04,2015-09-03
-1dkh,2000-12-27,1999-12-07
-4dky,2013-02-06,2012-02-05
-4dko,2012-05-02,2012-02-03
-1dko,2000-08-03,1999-12-08
-8dkt,2023-01-11,2022-07-06
-5dkn,2016-01-20,2015-09-03
-7dk0,2021-06-09,2020-11-22
-5dk6,2015-11-04,2015-09-03
-7dkg,2021-04-14,2020-11-24
-7dkv,2021-06-23,2020-11-25
-1dku,2000-04-05,1999-12-08
-4dk4,2013-08-07,2012-02-03
-8dkb,2023-01-11,2022-07-05
-3dkq,2008-08-12,2008-06-25
-7dkc,2021-11-03,2020-11-23
-5dkk,2016-01-13,2015-09-03
-1dkp,2000-08-03,1999-12-08
-6dk8,2019-03-20,2018-05-29
-6dks,2019-01-02,2018-05-30
-6dk0,2018-10-17,2018-05-28
-7vqd,2022-08-31,2021-10-19
-7vq6,2022-07-27,2021-10-19
-2vqb,2008-04-22,2008-03-12
-1vq5,2005-11-29,2004-12-16
-1vq1,2005-02-01,2004-12-02
-2vqf,2008-04-29,2008-03-14
-5vqh,2017-06-14,2017-05-08
-3vqq,2013-01-30,2012-03-29
-5vq8,2017-12-06,2017-05-08
-3vqa,2013-01-30,2012-03-20
-1vq0,2004-12-14,2004-11-30
-3vq4,2013-01-30,2012-03-20
-1vqo,2005-11-29,2004-12-16
-2vqa,2008-10-28,2008-03-12
-5vqi,2017-11-01,2017-05-09
-2vqr,2008-09-30,2008-03-18
-2vqu,2008-04-01,2008-03-18
-1vqq,2004-12-28,2004-12-17
-5vqy,2017-08-23,2017-05-09
-2vqz,2008-05-13,2008-03-21
-3vq2,2012-05-09,2012-03-17
-2vq6,2008-05-13,2008-03-11
-3vqw,2013-01-02,2012-04-01
-7vqg,2022-10-26,2021-10-19
-6vq8,2020-03-18,2020-02-04
-5vqt,2017-08-23,2017-05-09
-6vql,2020-06-24,2020-02-05
-1vq2,2004-12-21,2004-12-15
-7vqm,2021-11-24,2021-10-20
-2vqx,2009-05-26,2008-03-20
-2vqe,2008-04-29,2008-03-13
-2vqv,2008-07-22,2008-03-19
-8vqw,2024-01-31,2024-01-19
-3vqt,2012-09-05,2012-03-30
-7vqj,2022-10-26,2021-10-20
-6vqm,2021-02-10,2020-02-05
-8vqz,2024-01-31,2024-01-19
-5vql,2018-05-16,2017-05-09
-2vqk,2008-05-20,2008-03-17
-8vqr,2024-05-01,2024-01-19
-5vqs,2017-08-23,2017-05-09
-1vq7,2005-11-29,2004-12-16
-2vqm,2008-07-08,2008-03-17
-5vqn,2018-04-11,2017-05-09
-6vqs,2021-02-10,2020-02-05
-3vq5,2013-01-30,2012-03-20
-7vqa,2022-08-31,2021-10-19
-6vqt,2020-07-29,2020-02-05
-6vqf,2020-04-08,2020-02-05
-8vq1,2024-02-21,2024-01-17
-5vqq,2017-08-23,2017-05-09
-6vqo,2020-06-17,2020-02-05
-5vq2,2017-12-06,2017-05-07
-3vqm,2012-06-06,2012-03-26
-5vq0,2017-12-06,2017-05-06
-1vq8,2005-11-29,2004-12-16
-3vqc,2013-01-30,2012-03-21
-2vqt,2008-04-08,2008-03-18
-5vqp,2017-11-15,2017-05-09
-1vqp,2005-11-29,2004-12-16
-3vqg,2013-03-27,2012-03-23
-3vqu,2012-06-27,2012-03-30
-6vqn,2021-01-20,2020-02-05
-7vq9,2022-08-31,2021-10-19
-2vq0,2008-05-13,2008-03-10
-2vqg,2008-05-20,2008-03-15
-2vq5,2008-08-05,2008-03-11
-6vq9,2020-03-18,2020-02-04
-7vqp,2022-03-09,2021-10-20
-7vqk,2022-10-26,2021-10-20
-3vqd,2013-01-30,2012-03-21
-1vq4,2005-11-29,2004-12-16
-3vqv,2013-01-02,2012-04-01
-3vqz,2013-02-13,2012-04-02
-2vq1,2009-01-27,2008-03-10
-3vq8,2013-01-30,2012-03-20
-3vqp,2013-01-30,2012-03-29
-3vq9,2013-01-30,2012-03-20
-3vq1,2012-05-09,2012-03-17
-5vq1,2017-12-06,2017-05-07
-3vqj,2013-02-27,2012-03-24
-6vqz,2021-02-10,2020-02-06
-7vqb,2022-08-31,2021-10-19
-5vqa,2017-06-14,2017-05-08
-3vqy,2013-01-02,2012-04-02
-3vq6,2013-01-30,2012-03-20
-3vqe,2013-01-30,2012-03-21
-5vqb,2017-08-16,2017-05-08
-1vql,2005-11-29,2004-12-16
-6vq6,2020-03-18,2020-02-04
-2vqo,2008-07-08,2008-03-18
-3vqx,2013-01-02,2012-04-02
-5vqx,2017-08-23,2017-05-09
-1vq9,2005-11-29,2004-12-16
-6vqa,2020-03-18,2020-02-04
-3vqh,2012-08-15,2012-03-23
-7vqf,2022-09-07,2021-10-19
-1vqk,2005-11-29,2004-12-16
-5vqk,2018-05-16,2017-05-09
-6vqp,2021-02-17,2020-02-05
-7vqu,2022-06-01,2021-10-20
-2vql,2008-05-20,2008-03-17
-7vqn,2022-10-26,2021-10-20
-6vqr,2021-02-03,2020-02-05
-2vqj,2008-07-08,2008-03-17
-2vqq,2008-07-08,2008-03-18
-3vq7,2013-01-30,2012-03-20
-5vq6,2017-12-06,2017-05-08
-2vq7,2008-04-22,2008-03-12
-1vq6,2005-11-29,2004-12-16
-5vqf,2017-11-15,2017-05-08
-5vqw,2017-08-23,2017-05-09
-2vq3,2008-05-06,2008-03-10
-5vqe,2018-01-17,2017-05-08
-1vqm,2005-11-29,2004-12-16
-6vq7,2020-03-18,2020-02-04
-5vqv,2017-08-23,2017-05-09
-2vqs,2008-04-29,2008-03-18
-3vqr,2012-04-25,2012-03-29
-2vqy,2008-09-02,2008-03-20
-6vqy,2021-02-10,2020-02-06
-3vqs,2012-08-08,2012-03-30
-7vqo,2022-07-06,2021-10-20
-7vqt,2022-06-01,2021-10-20
-7vq0,2022-07-20,2021-10-18
-7vqs,2022-06-01,2021-10-20
-2vqw,2008-08-05,2008-03-19
-5vqu,2017-08-23,2017-05-09
-2vqd,2008-09-09,2008-03-13
-2vqh,2008-05-20,2008-03-15
-5vqr,2017-08-23,2017-05-09
-1vqn,2005-11-29,2004-12-16
-6vqd,2021-02-10,2020-02-05
-2vq2,2008-05-27,2008-03-10
-1vqw,2005-01-11,2005-01-05
-5vqz,2017-08-23,2017-05-09
-7vq7,2021-12-01,2021-10-19
-3vqb,2013-01-30,2012-03-21
-6vqb,2020-03-18,2020-02-04
-3sv1,2012-07-11,2011-07-12
-5svi,2016-12-14,2016-08-06
-1svh,2005-03-29,2004-03-29
-6svp,2020-01-15,2019-09-18
-6sv8,2020-01-22,2019-09-18
-3sv4,2012-06-06,2011-07-12
-5svn,2017-02-08,2016-08-06
-3sv7,2012-09-05,2011-07-12
-7svj,2023-01-25,2021-11-19
-6sva,2019-11-20,2019-09-18
-7svf,2023-01-25,2021-11-19
-8svs,2024-05-15,2023-05-17
-1sv5,2004-05-11,2004-03-27
-6sv1,2020-09-23,2019-09-17
-6svv,2020-01-22,2019-09-19
-6svj,2020-01-22,2019-09-18
-6svb,2020-01-22,2019-09-18
-1sv9,2004-04-20,2004-03-29
-1svn,1996-10-14,1995-09-01
-3sv6,2012-09-05,2011-07-12
-7svc,2022-04-06,2021-11-18
-5sv0,2016-09-28,2016-08-04
-5svu,2017-03-08,2016-08-07
-3svl,2012-05-30,2011-07-12
-7sv1,2022-04-06,2021-11-18
-7svn,2022-10-05,2021-11-19
-3svi,2011-08-10,2011-07-12
-3svg,2011-08-10,2011-07-12
-3svf,2011-08-10,2011-07-12
-7svl,2022-10-05,2021-11-19
-7sv7,2022-01-12,2021-11-18
-7svs,2022-02-16,2021-11-19
-1svu,2004-06-29,2004-03-30
-7svh,2023-01-25,2021-11-19
-7sv8,2022-04-06,2021-11-18
-5svy,2016-10-05,2016-08-08
-7svo,2022-10-05,2021-11-19
-5sv5,2016-08-17,2016-08-04
-8sv0,2023-05-31,2023-05-14
-5sva,2016-09-28,2016-08-05
-5svv,2017-03-08,2016-08-07
-8svy,2023-08-09,2023-05-17
-8svq,2024-05-15,2023-05-17
-1sv3,2004-04-13,2004-03-27
-3svj,2011-07-27,2011-07-12
-5svo,2017-02-08,2016-08-06
-7svd,2022-01-12,2021-11-18
-6svn,2020-01-22,2019-09-18
-8sv4,2023-10-04,2023-05-15
-8svo,2024-05-15,2023-05-17
-3svw,2012-05-02,2011-07-12
-7svx,2022-03-02,2021-11-19
-5svw,2017-03-08,2016-08-07
-7svm,2022-10-05,2021-11-19
-8svm,2024-04-24,2023-05-17
-5svb,2017-08-09,2016-08-05
-6svo,2020-01-15,2019-09-18
-7sv4,2022-03-09,2021-11-18
-5svx,2016-10-05,2016-08-08
-8sv5,2023-06-07,2023-05-15
-1svb,1996-06-10,1995-11-27
-8svx,2024-05-15,2023-05-17
-6svz,2020-01-22,2019-09-19
-7svt,2022-11-16,2021-11-19
-8svc,2024-01-24,2023-05-16
-8sv8,2023-10-11,2023-05-15
-6svq,2020-01-15,2019-09-18
-1svz,2005-03-01,2004-03-30
-1sv2,2005-08-09,2004-03-27
-3svv,2011-08-17,2011-07-12
-5svm,2016-09-28,2016-08-06
-1svl,2004-10-19,2004-03-29
-1svm,2004-10-19,2004-03-29
-5svs,2016-09-28,2016-08-07
-7sv0,2022-08-31,2021-11-18
-1svw,2004-05-25,2004-03-30
-6sv0,2020-01-22,2019-09-17
-7sva,2022-11-23,2021-11-18
-7svq,2022-07-13,2021-11-19
-6sv3,2019-12-18,2019-09-17
-5svc,2017-08-09,2016-08-05
-1svo,2004-10-19,2004-03-29
-5sv1,2016-09-28,2016-08-04
-8svt,2024-05-15,2023-05-17
-1svt,2005-03-01,2004-03-29
-1svy,1999-08-10,1998-08-10
-6sv5,2020-07-22,2019-09-17
-5svj,2016-09-28,2016-08-06
-3sv8,2012-09-05,2011-07-12
-6svy,2020-05-13,2019-09-19
-3svp,2011-09-28,2011-07-12
-6svu,2020-01-22,2019-09-19
-3svq,2011-09-28,2011-07-12
-3svt,2011-07-20,2011-07-12
-5sve,2017-01-11,2016-08-05
-5svr,2016-10-05,2016-08-07
-7svg,2023-01-25,2021-11-19
-5svl,2016-10-05,2016-08-06
-7svp,2023-01-25,2021-11-19
-6svm,2020-01-15,2019-09-18
-5svp,2016-09-28,2016-08-07
-3svh,2011-08-10,2011-07-12
-6svi,2020-01-22,2019-09-18
-3sv2,2012-06-20,2011-07-12
-8svl,2024-04-24,2023-05-17
-7sv5,2022-03-09,2021-11-18
-7sv9,2022-03-02,2021-11-18
-6svg,2020-01-22,2019-09-18
-6svd,2020-01-22,2019-09-18
-8sv3,2023-10-04,2023-05-15
-3sv9,2012-09-05,2011-07-12
-1svk,2004-06-01,2004-03-29
-3sv3,2012-06-06,2011-07-12
-6svx,2020-01-22,2019-09-19
-6svw,2020-01-22,2019-09-19
-5svf,2017-02-08,2016-08-05
-1svv,2004-08-17,2004-03-30
-7sv6,2022-03-09,2021-11-18
-7svu,2022-11-23,2021-11-19
-5sv8,2016-09-21,2016-08-05
-1svi,2004-05-25,2004-03-29
-8sv9,2024-03-27,2023-05-15
-7svw,2022-08-10,2021-11-19
-1svg,2005-03-29,2004-03-29
-7svr,2022-01-12,2021-11-19
-1svs,2004-06-01,2004-03-29
-7sv3,2022-03-09,2021-11-18
-7svv,2022-08-10,2021-11-19
-8svp,2024-05-15,2023-05-17
-5svt,2016-09-28,2016-08-07
-6svr,2020-01-22,2019-09-18
-8sv2,2024-05-29,2023-05-15
-5svk,2016-09-28,2016-08-06
-7sv2,2022-05-18,2021-11-18
-5svg,2017-03-08,2016-08-05
-6sv9,2020-01-22,2019-09-18
-6svf,2019-11-20,2019-09-18
-5svq,2016-10-05,2016-08-07
-6sv6,2020-01-22,2019-09-17
-8svr,2024-05-15,2023-05-17
-1sve,2005-03-29,2004-03-29
-1lax,2003-03-04,2002-03-29
-4laj,2013-08-14,2013-06-20
-3law,2010-01-26,2010-01-07
-6lam,2020-04-29,2019-11-12
-1laj,2002-11-27,2002-03-28
-6la8,2020-10-07,2019-11-12
-6la9,2020-10-07,2019-11-12
-1lah,1995-07-10,1993-10-06
-5lau,2017-05-03,2016-06-15
-7lal,2021-04-21,2021-01-06
-6lac,2019-11-27,2019-11-12
-4lag,2014-02-19,2013-06-19
-5lay,2016-11-02,2016-06-15
-4lau,2014-04-30,2013-06-20
-4lab,2013-11-20,2013-06-19
-7lan,2021-04-21,2021-01-06
-1lan,1995-10-15,1995-08-11
-7laz,2021-07-14,2021-01-07
-3la2,2010-07-14,2010-01-06
-3lap,2010-05-05,2010-01-06
-5lat,2016-08-31,2016-06-15
-3laq,2010-02-02,2010-01-06
-3laj,2010-05-05,2010-01-06
-7la8,2021-07-14,2021-01-06
-5lar,2016-07-06,2016-06-14
-4lad,2013-08-28,2013-06-19
-4lap,2014-12-24,2013-06-20
-5la2,2016-08-31,2016-06-13
-6la0,2020-11-11,2019-11-11
-4lae,2014-02-19,2013-06-19
-4laz,2014-04-30,2013-06-20
-3la6,2010-08-25,2010-01-06
-5laa,2016-07-06,2016-06-14
-7lam,2021-04-21,2021-01-06
-5lae,2017-03-15,2016-06-14
-7la9,2022-01-12,2021-01-06
-4laa,2013-08-21,2013-06-19
-4laf,2014-06-25,2013-06-19
-3lae,2010-01-19,2010-01-06
-5la9,2016-08-31,2016-06-14
-3las,2011-01-12,2010-01-07
-3lai,2010-03-16,2010-01-06
-7lab,2021-03-10,2021-01-06
-5law,2016-11-02,2016-06-15
-7lai,2021-08-11,2021-01-06
-7laf,2022-01-19,2021-01-06
-5laj,2017-04-26,2016-06-14
-6lai,2019-11-27,2019-11-12
-4lam,2013-10-02,2013-06-20
-4la0,2013-07-24,2013-06-18
-7lah,2021-08-11,2021-01-06
-1la6,2002-07-31,2002-03-28
-1lam,1995-10-15,1995-08-11
-6laa,2020-06-10,2019-11-12
-4lal,2013-10-02,2013-06-20
-6lah,2020-04-22,2019-11-12
-5lak,2017-07-12,2016-06-14
-5la1,2016-08-31,2016-06-13
-4lao,2013-10-02,2013-06-20
-7las,2021-08-25,2021-01-06
-7lay,2021-07-14,2021-01-07
-5laq,2018-03-14,2016-06-14
-4lay,2013-08-21,2013-06-20
-5lal,2016-11-09,2016-06-14
-4lax,2013-08-21,2013-06-20
-7lau,2021-08-11,2021-01-06
-3lat,2010-03-23,2010-01-07
-3lah,2010-03-16,2010-01-06
-7la4,2022-01-12,2021-01-05
-5la3,2017-06-21,2016-06-13
-5lav,2016-11-02,2016-06-15
-4lak,2013-10-02,2013-06-20
-5lai,2017-04-26,2016-06-14
-3la1,2011-01-12,2010-01-06
-7lad,2021-10-27,2021-01-06
-5la4,2017-05-31,2016-06-13
-1la0,2002-12-11,2002-03-27
-5las,2016-08-31,2016-06-14
-3laf,2011-03-02,2010-01-06
-2lal,1993-10-31,1993-06-10
-3lal,2010-02-23,2010-01-06
-4laq,2014-01-08,2013-06-20
-5la7,2017-05-31,2016-06-13
-5laz,2016-11-02,2016-06-15
-1lag,1995-07-10,1993-10-06
-4la1,2014-07-30,2013-06-18
-4la7,2013-08-07,2013-06-19
-1lau,1996-06-10,1996-01-03
-2lap,2012-02-08,2011-03-16
-3la4,2010-07-28,2010-01-06
-3la3,2010-07-14,2010-01-06
-7lat,2022-01-12,2021-01-06
-1la3,2002-06-19,2002-03-27
-3lam,2010-02-23,2010-01-06
-4la6,2013-07-31,2013-06-19
-4lar,2013-12-11,2013-06-20
-7laj,2021-08-11,2021-01-06
-7lak,2021-07-14,2021-01-06
-1lap,1991-10-15,1990-08-01
-3lau,2010-03-02,2010-01-07
-6lae,2020-02-26,2019-11-12
-4lah,2014-02-19,2013-06-19
-7lar,2021-08-25,2021-01-06
-4la3,2014-01-15,2013-06-19
-1laf,1995-07-10,1993-10-06
-7la5,2022-01-12,2021-01-05
-3lan,2010-02-23,2010-01-06
-7lao,2021-01-20,2021-01-06
-2lan,2012-02-08,2011-03-16
-5la0,2016-08-31,2016-06-13
-3lak,2010-02-23,2010-01-06
-2laz,2011-07-06,2011-03-22
-5la6,2016-07-20,2016-06-13
-3lag,2010-01-19,2010-01-06
-1la2,2002-04-10,2002-03-27
-5lab,2016-08-10,2016-06-14
-1lat,1996-04-03,1995-12-18
-2lay,2011-07-06,2011-03-22
-3lac,2010-01-19,2010-01-06
-4lac,2013-10-09,2013-06-19
-6lab,2021-02-17,2019-11-12
-7lae,2021-04-21,2021-01-06
-2lau,2012-09-26,2011-03-21
-4la2,2014-01-15,2013-06-19
-2lax,2011-07-06,2011-03-22
-3lad,1994-01-31,1991-12-11
-5lap,2016-08-10,2016-06-14
-7lag,2021-04-21,2021-01-06
-4lan,2013-10-02,2013-06-20
-7law,2022-03-09,2021-01-07
-7laa,2021-03-17,2021-01-06
-7laq,2021-04-21,2021-01-06
-4las,2013-12-11,2013-06-20
-7mea,2022-02-16,2021-04-06
-1mew,2003-08-12,2002-08-08
-1me7,2003-01-14,2002-08-08
-6mec,2019-08-14,2018-09-06
-7mec,2022-02-16,2021-04-06
-4men,2013-09-25,2013-08-27
-5me1,2017-01-11,2016-11-14
-5mek,2017-07-05,2016-11-15
-1me4,2002-12-18,2002-08-07
-7meh,2022-02-16,2021-04-06
-6me6,2019-04-24,2018-09-05
-6mea,2019-09-11,2018-09-06
-6mep,2019-09-11,2018-09-06
-1mem,1998-01-14,1997-01-08
-7met,2021-10-06,2021-04-07
-3me2,2010-06-02,2010-03-31
-6me8,2019-04-24,2018-09-05
-3met,2010-04-28,2010-03-31
-6men,2019-09-11,2018-09-06
-3men,2010-04-21,2010-03-31
-4me3,2014-01-08,2013-08-24
-7mek,2021-08-18,2021-04-06
-5mex,2017-07-05,2016-11-16
-1men,2002-12-18,2002-08-08
-6meb,2019-09-11,2018-09-06
-7mey,2021-11-24,2021-04-08
-3meb,2010-04-21,2010-03-31
-1met,1998-04-15,1997-04-11
-1mey,1997-03-12,1996-09-27
-4mew,2014-08-13,2013-08-27
-7med,2022-02-16,2021-04-06
-5meo,2016-12-07,2016-11-16
-5men,2016-12-07,2016-11-16
-7mel,2021-07-14,2021-04-06
-4mes,2014-08-27,2013-08-27
-5mer,2016-12-07,2016-11-16
-7me2,2021-08-25,2021-04-06
-7me8,2021-10-13,2021-04-06
-3me4,2010-06-02,2010-03-31
-4met,2014-03-05,2013-08-27
-4me4,2014-02-19,2013-08-24
-5mes,2017-01-18,2016-11-16
-7meq,2021-04-21,2021-04-07
-1mes,1998-04-15,1997-04-11
-3med,2010-05-12,2010-03-31
-3mel,2010-05-05,2010-03-31
-6mev,2019-09-18,2018-09-07
-5mee,2017-05-31,2016-11-14
-6me3,2019-04-24,2018-09-05
-6me2,2019-04-24,2018-09-05
-1mer,1998-04-15,1997-04-11
-4mep,2013-09-25,2013-08-27
-5mel,2017-01-11,2016-11-15
-4mec,2014-08-27,2013-08-26
-6me9,2019-04-24,2018-09-05
-2mej,2014-04-30,2013-09-25
-3mea,2010-04-28,2010-03-31
-7me3,2021-08-25,2021-04-06
-7meu,2021-04-28,2021-04-07
-7me1,2021-08-25,2021-04-06
-3mes,2010-04-07,2010-03-31
-4me6,2014-02-19,2013-08-25
-6mek,2018-11-21,2018-09-06
-5meh,2016-12-21,2016-11-14
-1med,1993-10-31,1992-11-09
-7mep,2022-01-26,2021-04-07
-1mex,2003-09-02,2002-08-08
-4meq,2013-09-25,2013-08-27
-4mex,2014-05-21,2013-08-27
-5mew,2017-05-10,2016-11-16
-1mee,1992-10-15,1991-04-15
-5mem,2017-11-29,2016-11-15
-5mev,2017-01-18,2016-11-16
-5meq,2016-12-07,2016-11-16
-6meh,2018-11-21,2018-09-06
-6meq,2019-09-04,2018-09-06
-6meo,2018-12-12,2018-09-06
-1meh,2003-08-12,2002-08-08
-7mer,2021-06-09,2021-04-07
-5mej,2017-05-10,2016-11-15
-1me8,2003-01-14,2002-08-08
-3mec,2010-05-12,2010-03-31
-3mev,2010-04-28,2010-03-31
-1meg,1997-01-11,1996-05-04
-5med,2017-05-31,2016-11-14
-6mey,2019-04-17,2018-09-07
-6me4,2019-04-24,2018-09-05
-7mem,2021-07-28,2021-04-06
-3meg,2010-05-12,2010-03-31
-1mei,2003-08-12,2002-08-08
-3meh,2011-03-16,2010-03-31
-6mej,2018-11-21,2018-09-06
-7me4,2021-10-13,2021-04-06
-5mey,2017-11-15,2016-11-16
-6mes,2019-09-18,2018-09-07
-6mei,2018-11-21,2018-09-06
-7me5,2021-10-13,2021-04-06
-7mev,2022-04-13,2021-04-07
-5meg,2017-05-31,2016-11-14
-3me9,2010-04-28,2010-03-31
-4meo,2013-09-25,2013-08-27
-5mef,2017-05-31,2016-11-14
-3meq,2010-04-28,2010-03-31
-1me6,2004-01-20,2002-08-08
-4me5,2013-10-23,2013-08-25
-3mey,2010-07-28,2010-04-01
-5mei,2017-06-28,2016-11-15
-1me9,2003-08-12,2002-08-08
-3mek,2010-04-14,2010-03-31
-7mee,2022-02-16,2021-04-06
-7mef,2022-02-16,2021-04-06
-5me0,2017-01-11,2016-11-14
-6mez,2019-03-13,2018-09-07
-6mer,2019-09-04,2018-09-06
-7mex,2021-11-24,2021-04-08
-7meb,2022-02-16,2021-04-06
-1mea,1993-10-31,1992-11-09
-7meg,2022-02-16,2021-04-06
-1mep,2003-09-02,2002-08-08
-4mej,2014-10-15,2013-08-26
-3me6,2010-09-15,2010-03-31
-1me3,2002-12-18,2002-08-07
-3meu,2010-04-28,2010-03-31
-6met,2018-12-12,2018-09-07
-4mey,2014-05-21,2013-08-27
-7mei,2022-03-02,2021-04-06
-7mes,2021-06-09,2021-04-07
-7mew,2021-10-06,2021-04-08
-5mep,2016-12-07,2016-11-16
-1mez,2002-10-30,2002-08-09
-5me6,2017-08-23,2016-11-14
-3mee,2010-05-12,2010-03-31
-1meu,1998-04-15,1997-04-11
-5mez,2017-11-15,2016-11-16
-6me7,2019-04-24,2018-09-05
-2mes,2014-12-24,2013-09-26
-6me5,2019-04-24,2018-09-05
-6vkm,2020-04-15,2020-01-21
-8vkk,2024-02-14,2024-01-09
-5vke,2017-12-06,2017-04-21
-3vk5,2012-05-09,2011-11-08
-3vk4,2012-09-19,2011-11-07
-1vk1,2004-08-10,2004-04-13
-2vkh,2008-03-18,2007-12-19
-8vkf,2024-05-08,2024-01-09
-1vkp,2004-08-17,2004-06-15
-6vkq,2020-06-17,2020-01-21
-2vkr,2008-03-04,2007-12-23
-5vkt,2017-08-09,2017-04-22
-2vkm,2008-12-16,2007-12-04
-8vk3,2024-01-24,2024-01-08
-7vkn,2021-10-13,2021-09-30
-3vk6,2012-01-25,2011-11-09
-2vkv,2008-07-08,2008-01-02
-6vkd,2020-05-27,2020-01-20
-5vkh,2017-12-06,2017-04-21
-7vkr,2022-07-20,2021-09-30
-2vk5,2008-01-22,2007-12-17
-5vkb,2017-08-16,2017-04-21
-6vk6,2020-08-05,2020-01-18
-2vku,2008-03-25,2007-12-29
-5vk1,2018-04-25,2017-04-20
-6vke,2020-05-27,2020-01-20
-7vkd,2022-10-05,2021-09-29
-7vkx,2022-03-09,2021-10-01
-5vk6,2017-12-06,2017-04-21
-6vkz,2020-04-08,2020-01-22
-7vki,2022-10-05,2021-09-30
-2vkq,2008-01-08,2007-12-21
-2vk1,2009-01-27,2007-12-16
-5vkw,2017-05-24,2017-04-24
-6vko,2020-06-17,2020-01-21
-2vke,2008-07-01,2007-12-18
-7vkq,2022-07-20,2021-09-30
-2vkz,2008-08-12,2008-01-07
-6vkv,2020-10-21,2020-01-22
-8vkn,2024-02-14,2024-01-09
-1vkm,2004-06-29,2004-06-09
-3vkz,2012-02-29,2011-11-28
-8vkp,2024-02-14,2024-01-09
-3vkd,2012-05-09,2011-11-12
-1vko,2004-08-17,2004-06-11
-6vk5,2020-08-05,2020-01-18
-2vk4,2009-01-27,2007-12-17
-3vk3,2012-09-19,2011-11-07
-3vkh,2012-03-14,2011-11-16
-3vkx,2012-03-14,2011-11-26
-2vk2,2009-05-19,2007-12-16
-6vk4,2020-08-05,2020-01-18
-7vkg,2022-10-05,2021-09-29
-6vkt,2020-07-01,2020-01-22
-2vk6,2008-01-22,2007-12-17
-3vks,2012-04-25,2011-11-20
-7vko,2021-10-13,2021-09-30
-2vkf,2008-09-30,2007-12-19
-1vk6,2004-05-11,2004-04-30
-6vks,2020-07-01,2020-01-22
-3vkk,2012-11-21,2011-11-17
-3vkb,2012-05-09,2011-11-11
-5vk2,2017-05-31,2017-04-20
-2vkp,2008-02-12,2007-12-21
-7vke,2022-08-03,2021-09-29
-6vkc,2020-05-27,2020-01-20
-5vkf,2018-04-25,2017-04-21
-5vkj,2017-10-04,2017-04-21
-2vkn,2008-02-05,2007-12-20
-6vkg,2020-03-04,2020-01-20
-3vkg,2012-03-14,2011-11-16
-5vkx,2018-04-18,2017-04-24
-5vkc,2017-05-03,2017-04-21
-8vkt,2024-05-29,2024-01-09
-8vko,2024-02-14,2024-01-09
-2vk0,2008-09-16,2007-12-14
-3vkl,2012-09-12,2011-11-18
-7vka,2022-08-31,2021-09-29
-6vkp,2021-01-27,2020-01-21
-3vkm,2012-09-12,2011-11-18
-2vk8,2009-01-27,2007-12-17
-5vk0,2018-04-25,2017-04-20
-5vkm,2017-10-04,2017-04-21
-7vkt,2022-03-09,2021-10-01
-3vka,2012-05-09,2011-11-11
-6vk8,2020-08-05,2020-01-18
-5vkg,2017-11-15,2017-04-21
-1vkj,2004-06-01,2004-05-25
-1vkq,2004-08-31,2004-06-12
-7vkz,2022-03-09,2021-10-01
-6vkk,2020-06-17,2020-01-21
-8vk4,2024-02-07,2024-01-08
-3vkp,2012-04-25,2011-11-20
-2vkd,2008-03-18,2007-12-18
-5vk4,2017-05-10,2017-04-20
-6vka,2021-01-20,2020-01-19
-5vka,2017-08-16,2017-04-21
-5vk3,2017-06-14,2017-04-20
-2vk7,2008-01-22,2007-12-17
-3vko,2012-09-12,2011-11-18
-1vkg,2004-07-27,2004-05-13
-3vkj,2012-05-30,2011-11-17
-2vka,2008-01-29,2007-12-18
-3vkc,2012-05-09,2011-11-12
-7vkl,2022-10-05,2021-09-30
-3vkf,2012-08-01,2011-11-15
-3vke,2012-02-29,2011-11-15
-2vkg,2008-09-30,2007-12-19
-6vkf,2020-02-05,2020-01-20
-7vkf,2022-10-05,2021-09-29
-6vkn,2020-08-12,2020-01-21
-5vks,2017-11-08,2017-04-22
-5vkr,2017-05-03,2017-04-22
-7vky,2022-03-09,2021-10-01
-1vkl,1997-01-11,1996-07-03
-6vk7,2020-08-05,2020-01-18
-6vkj,2021-01-27,2020-01-21
-3vkr,2012-04-25,2011-11-20
-5vki,2017-11-08,2017-04-21
-8vkm,2024-02-14,2024-01-09
-7vkb,2022-06-29,2021-09-29
-1vk9,2004-05-18,2004-05-06
-7vkh,2022-10-05,2021-09-30
-8vkl,2024-02-14,2024-01-09
-3vkt,2012-04-25,2011-11-20
-3vkq,2012-04-25,2011-11-20
-1ash,1995-02-27,1995-01-06
-6asx,2018-03-28,2017-08-25
-1asc,1994-04-30,1993-08-27
-8asz,2024-03-06,2022-08-22
-8as7,2023-01-18,2022-08-18
-6asu,2018-08-29,2017-08-25
-8as0,2022-11-23,2022-08-17
-4asl,2012-10-17,2012-05-02
-8asd,2023-01-18,2022-08-19
-1as7,1998-02-25,1997-08-13
-6asb,2017-10-18,2017-08-24
-1as8,1998-02-25,1997-08-13
-3asx,2011-12-21,2010-12-22
-7as1,2021-02-24,2020-10-26
-4asr,2012-10-31,2012-05-02
-4as9,2013-04-03,2012-04-30
-1as2,1997-11-12,1997-08-11
-6asp,2018-04-18,2017-08-25
-8asn,2022-09-21,2022-08-19
-4asf,2013-04-03,2012-05-01
-3asp,2012-01-25,2010-12-17
-6as5,2018-08-01,2017-08-23
-7asj,2021-11-24,2020-10-27
-6asq,2018-04-18,2017-08-25
-3asz,2011-06-01,2010-12-22
-8ase,2023-11-29,2022-08-19
-6asr,2018-06-20,2017-08-25
-1asg,1994-04-30,1993-08-27
-2as8,2005-12-06,2005-08-23
-4as4,2012-10-10,2012-04-27
-1asj,1997-12-03,1997-08-11
-8asf,2024-03-06,2022-08-19
-2asv,2005-09-06,2005-08-24
-6asz,2017-12-06,2017-08-27
-8as1,2023-09-20,2022-08-17
-6as8,2018-02-28,2017-08-23
-2as1,2006-04-11,2005-08-22
-7asm,2021-11-17,2020-10-27
-3asi,2011-04-13,2010-12-13
-3as5,2011-07-20,2010-12-10
-2asp,2005-10-11,2005-08-23
-7ask,2021-04-14,2020-10-27
-6asy,2017-12-06,2017-08-26
-6asl,2018-09-12,2017-08-24
-3ase,2011-04-27,2010-12-11
-4as2,2012-08-22,2012-04-27
-7asd,2020-12-30,2020-10-27
-3asr,2012-01-25,2010-12-17
-4asm,2012-07-25,2012-05-02
-8asl,2023-08-16,2022-08-19
-7ass,2020-12-16,2020-10-28
-3asl,2012-01-25,2010-12-16
-6aso,2018-05-09,2017-08-25
-6asa,2018-01-24,2017-08-24
-2ash,2005-09-06,2005-08-23
-7ase,2021-04-14,2020-10-27
-3aso,2011-08-03,2010-12-17
-7as3,2021-02-24,2020-10-26
-1asa,1994-04-30,1993-08-27
-8asu,2023-04-12,2022-08-21
-2as3,2006-04-11,2005-08-22
-1as3,1997-11-12,1997-08-11
-1ast,1994-07-31,1993-04-21
-3ast,2012-01-25,2010-12-17
-8asg,2023-01-18,2022-08-19
-1asm,1994-01-31,1993-09-16
-2asu,2005-11-10,2005-08-24
-3as3,2011-04-20,2010-12-09
-3as1,2011-04-20,2010-12-09
-1asb,1994-04-30,1993-08-27
-1asz,1995-05-08,1995-01-19
-3asv,2011-10-12,2010-12-21
-8as2,2023-06-07,2022-08-18
-7as2,2021-02-24,2020-10-26
-6asg,2018-04-11,2017-08-24
-4ask,2012-07-25,2012-05-01
-2as9,2005-09-06,2005-08-23
-2asm,2005-10-11,2005-08-23
-2asi,1996-08-01,1995-12-09
-2asc,2006-09-05,2005-08-23
-8asp,2023-08-16,2022-08-20
-6as6,2018-08-29,2017-08-23
-3ass,2012-01-25,2010-12-17
-2aso,2005-10-11,2005-08-23
-4asg,2013-04-03,2012-05-01
-4asj,2012-10-31,2012-05-01
-4asx,2012-05-23,2012-05-03
-6asi,2018-08-29,2017-08-24
-4as5,2012-10-10,2012-04-27
-2asd,2006-01-10,2005-08-23
-8asw,2022-12-07,2022-08-21
-1asp,1994-01-31,1992-11-25
-8as3,2023-06-07,2022-08-18
-2asj,2006-01-10,2005-08-23
-3as2,2011-04-20,2010-12-09
-1ase,1994-04-30,1993-08-27
-1asd,1994-04-30,1993-08-27
-1asn,1994-01-31,1993-09-16
-2as5,2006-08-08,2005-08-22
-3asq,2012-01-25,2010-12-17
-6asc,2018-03-07,2017-08-24
-4asd,2012-09-26,2012-04-30
-1asq,1994-01-31,1992-11-25
-8as8,2022-12-14,2022-08-18
-7as0,2021-02-24,2020-10-26
-7asq,2021-11-24,2020-10-28
-6ash,2018-08-29,2017-08-24
-4asb,2013-04-03,2012-04-30
-4asy,2012-10-31,2012-05-03
-2asn,2006-08-01,2005-08-23
-1asf,1994-04-30,1993-08-27
-2asf,2005-10-11,2005-08-23
-1asl,1994-01-31,1993-09-16
-8ass,2023-04-12,2022-08-21
-6asd,2017-10-18,2017-08-24
-7as4,2021-01-20,2020-10-26
-3ask,2012-01-25,2010-12-16
-4as3,2012-08-22,2012-04-27
-3as0,2011-04-20,2010-12-09
-2asl,2006-01-10,2005-08-23
-2as2,2006-04-11,2005-08-22
-6as7,2018-03-14,2017-08-23
-4as7,2013-05-15,2012-04-29
-4asu,2012-06-27,2012-05-03
-3asn,2011-08-03,2010-12-17
-8asi,2023-03-15,2022-08-19
-7asu,2020-12-30,2020-10-28
-2as6,2006-04-11,2005-08-22
-7asb,2021-02-17,2020-10-27
-4ase,2012-09-26,2012-04-30
-4as8,2012-10-31,2012-04-29
-1ass,1997-12-03,1997-08-11
-6asm,2018-08-29,2017-08-25
-4asq,2012-10-31,2012-05-02
-8asa,2023-08-30,2022-08-18
-8asb,2023-01-18,2022-08-18
-7as6,2021-08-18,2020-10-27
-6asw,2018-08-15,2017-08-25
-1as0,1997-11-12,1997-08-11
-8asy,2023-01-11,2022-08-22
-8asj,2023-03-15,2022-08-19
-4asa,2013-04-03,2012-04-30
-2as4,2006-04-11,2005-08-22
-6ase,2018-01-24,2017-08-24
-1as6,1998-02-25,1997-08-13
-4as0,2012-10-03,2012-04-27
-3asj,2011-09-21,2010-12-13
-1aso,1994-01-31,1992-11-25
-5n0e,2017-05-10,2017-02-02
-1n07,2003-02-25,2002-10-11
-3n0a,2010-09-22,2010-05-13
-4n0w,2013-12-11,2013-10-02
-1n0n,2002-11-06,2002-10-14
-5n0r,2018-02-14,2017-02-03
-4n0s,2014-08-27,2013-10-02
-3n01,2010-11-24,2010-05-13
-5n0d,2017-05-10,2017-02-02
-6n0p,2019-09-04,2018-11-07
-4n0r,2013-10-23,2013-10-02
-5n0a,2017-06-07,2017-02-02
-7n0i,2021-06-09,2021-05-25
-4n09,2014-01-15,2013-10-01
-6n0r,2019-11-13,2018-11-07
-5n0g,2018-02-14,2017-02-02
-6n0o,2019-11-13,2018-11-07
-3n0w,2010-06-02,2010-05-14
-1n0i,2003-05-27,2002-10-14
-6n0y,2019-07-17,2018-11-07
-4n0q,2013-11-06,2013-10-02
-3n0q,2010-06-09,2010-05-14
-1n0u,2003-02-11,2002-10-15
-4n0o,2014-01-08,2013-10-02
-7n0u,2021-08-11,2021-05-26
-3n0t,2010-07-21,2010-05-14
-5n04,2017-03-29,2017-02-02
-5n0h,2017-04-05,2017-02-03
-3n06,2010-09-29,2010-05-13
-6n0m,2019-04-10,2018-11-07
-7n0d,2021-07-28,2021-05-25
-4n07,2013-11-20,2013-10-01
-5n0z,2017-05-24,2017-02-03
-7n0m,2022-05-04,2021-05-25
-5n0f,2017-08-09,2017-02-02
-7n02,2021-06-02,2021-05-24
-3n0h,2011-09-28,2010-05-14
-1n08,2003-02-25,2002-10-11
-6n0v,2019-01-09,2018-11-07
-4n01,2013-12-18,2013-09-30
-3n0n,2011-03-16,2010-05-14
-6n08,2019-05-15,2018-11-06
-6n0x,2019-07-17,2018-11-07
-5n0m,2017-05-24,2017-02-03
-4n0u,2014-02-05,2013-10-02
-5n0u,2018-02-14,2017-02-03
-1n0w,2002-11-27,2002-10-15
-7n0z,2021-08-04,2021-05-26
-3n08,2010-07-14,2010-05-13
-5n0b,2017-06-21,2017-02-02
-3n07,2010-08-04,2010-05-13
-5n0w,2018-02-14,2017-02-03
-4n0d,2014-03-12,2013-10-01
-5n0k,2017-12-13,2017-02-03
-7n03,2021-11-03,2021-05-24
-2n0m,2016-01-20,2015-03-10
-4n00,2014-05-14,2013-09-30
-5n0o,2018-02-14,2017-02-03
-1n0t,2003-03-04,2002-10-15
-4n02,2014-07-02,2013-09-30
-4n0g,2013-11-13,2013-10-01
-1n04,2003-09-30,2002-10-11
-3n0g,2010-07-21,2010-05-14
-4n0m,2014-03-05,2013-10-02
-3n0b,2011-05-25,2010-05-13
-3n0y,2010-11-24,2010-05-14
-4n0i,2014-04-16,2013-10-02
-6n02,2019-03-27,2018-11-06
-4n0x,2014-01-29,2013-10-02
-5n0p,2018-02-14,2017-02-03
-3n0z,2010-11-24,2010-05-14
-4n0j,2014-11-12,2013-10-02
-4n0c,2015-08-19,2013-10-01
-5n0i,2017-04-05,2017-02-03
-5n0s,2018-02-14,2017-02-03
-7n0a,2022-06-15,2021-05-25
-4n0e,2014-03-12,2013-10-01
-4n0k,2014-09-10,2013-10-02
-4n0n,2014-01-08,2013-10-02
-7n0c,2021-07-28,2021-05-25
-5n09,2017-06-07,2017-02-02
-1n0x,2004-04-13,2002-10-15
-5n0q,2018-02-14,2017-02-03
-2n02,2015-06-10,2015-03-04
-3n0u,2011-04-06,2010-05-14
-6n03,2019-03-27,2018-11-06
-7n04,2022-03-30,2021-05-25
-5n0t,2018-02-14,2017-02-03
-5n0l,2018-02-14,2017-02-03
-1n0s,2003-08-05,2002-10-15
-6n00,2019-03-27,2018-11-06
-6n0t,2019-01-09,2018-11-07
-6n0b,2019-05-01,2018-11-07
-3n0i,2010-12-29,2010-05-14
-4n0b,2013-10-30,2013-10-01
-5n0y,2017-05-24,2017-02-03
-3n0c,2011-05-25,2010-05-13
-7n06,2021-06-02,2021-05-25
-3n0s,2010-06-09,2010-05-14
-1n06,2003-02-25,2002-10-11
-1n0h,2003-01-07,2002-10-14
-7n0h,2021-06-02,2021-05-25
-6n0n,2019-11-13,2018-11-07
-7n0g,2021-06-02,2021-05-25
-2n0w,2016-01-27,2015-03-17
-6n0u,2018-11-21,2018-11-07
-1n0z,2003-07-22,2002-10-15
-3n0p,2010-09-29,2010-05-14
-4n0l,2013-11-13,2013-10-02
-5n0c,2017-06-21,2017-02-02
-5n0n,2018-02-14,2017-02-03
-7n09,2021-08-11,2021-05-25
-6n0d,2019-11-13,2018-11-07
-3n0m,2010-06-09,2010-05-14
-1n0j,2002-11-06,2002-10-14
-6n0k,2019-07-10,2018-11-07
-6n0a,2019-04-17,2018-11-06
-1n0y,2003-09-30,2002-10-15
-7n0b,2021-07-28,2021-05-25
-2n0u,2016-01-27,2015-03-17
-7n0l,2021-09-15,2021-05-25
-5n05,2017-03-29,2017-02-02
-6n04,2019-11-13,2018-11-06
-6n0j,2019-07-10,2018-11-07
-5n0x,2018-02-14,2017-02-03
-6n0z,2019-07-17,2018-11-07
-2n06,2016-01-27,2015-03-04
-5n0j,2017-11-15,2017-02-03
-5n0v,2018-02-14,2017-02-03
-6n0q,2019-10-23,2018-11-07
-3kpz,2011-10-12,2009-11-17
-5kpl,2018-03-14,2016-07-04
-7kpj,2022-01-19,2020-11-11
-5kp3,2016-09-07,2016-07-01
-7kp2,2021-11-17,2020-11-10
-7kp7,2021-01-13,2020-11-10
-3kpk,2010-04-07,2009-11-16
-3kpm,2009-12-22,2009-11-16
-6kpa,2020-03-25,2019-08-15
-1kp4,2002-09-04,2001-12-28
-3kpy,2010-09-29,2009-11-17
-6kpc,2020-02-12,2019-08-15
-6kpn,2019-10-02,2019-08-15
-1kpu,2003-06-10,2002-01-02
-6kpf,2020-02-12,2019-08-15
-4kpb,2013-07-24,2013-05-13
-6kpk,2020-03-25,2019-08-15
-5kpr,2016-08-31,2016-07-05
-4kpv,2013-05-29,2013-05-14
-4kpd,2014-04-30,2013-05-13
-4kp5,2013-11-06,2013-05-13
-3kpo,2009-12-22,2009-11-16
-4kpu,2014-01-15,2013-05-14
-3kpn,2009-12-22,2009-11-16
-5kp2,2016-07-20,2016-07-01
-5kpo,2016-12-21,2016-07-05
-4kpq,2013-07-03,2013-05-14
-6kps,2020-03-25,2019-08-16
-4kp1,2014-04-23,2013-05-13
-7kpk,2021-04-28,2020-11-11
-6kph,2020-03-25,2019-08-15
-3kp9,2010-02-09,2009-11-16
-7kpu,2021-06-16,2020-11-12
-3kp5,2010-06-09,2009-11-15
-4kpf,2014-11-26,2013-05-13
-3kpx,2010-10-06,2009-11-17
-6kpg,2020-02-12,2019-08-15
-4kp7,2013-10-02,2013-05-13
-4kps,2013-07-03,2013-05-14
-4kpx,2014-10-15,2013-05-14
-4kp8,2013-11-06,2013-05-13
-1kp3,2002-04-17,2001-12-27
-1kpv,2003-06-10,2002-01-02
-7kpb,2021-01-13,2020-11-10
-3kpw,2010-09-29,2009-11-17
-2kpi,2010-02-02,2009-10-15
-3kpq,2009-12-22,2009-11-16
-7kp5,2021-01-27,2020-11-10
-5kpq,2016-12-14,2016-07-05
-5kpk,2018-03-14,2016-07-04
-4kpa,2013-07-24,2013-05-13
-1kp2,2002-04-17,2001-12-27
-4kpz,2014-10-15,2013-05-14
-2kp8,2010-01-19,2009-10-09
-5kpu,2017-08-09,2016-07-05
-5kp4,2016-09-07,2016-07-01
-5kpp,2016-11-30,2016-07-05
-4kpm,2013-06-26,2013-05-14
-1kpg,2002-01-11,2001-12-30
-3kpl,2009-12-22,2009-11-16
-6kpi,2020-03-25,2019-08-15
-3kp4,2010-06-09,2009-11-15
-7kpy,2021-05-19,2020-11-12
-3kpt,2009-11-24,2009-11-16
-5kpm,2018-03-14,2016-07-04
-4kp0,2013-10-30,2013-05-12
-6kpm,2019-10-02,2019-08-15
-4kpy,2014-01-29,2013-05-14
-3kps,2009-12-22,2009-11-16
-7kps,2020-11-25,2020-11-12
-7kpr,2021-08-04,2020-11-12
-5kpc,2016-09-07,2016-07-03
-3kpr,2009-12-22,2009-11-16
-6kp2,2019-12-04,2019-08-14
-7kp9,2021-01-13,2020-11-10
-1kpr,2003-02-25,2002-01-02
-3kp3,2010-06-09,2009-11-15
-3kpp,2009-12-22,2009-11-16
-3kpj,2010-09-29,2009-11-16
-5kp8,2016-08-31,2016-07-02
-3kp0,2010-01-26,2009-11-14
-6kp1,2020-06-24,2019-08-13
-1kpm,2002-07-10,2002-01-01
-6kp7,2019-12-04,2019-08-14
-1kph,2002-01-11,2001-12-30
-4kpo,2013-11-27,2013-05-14
-7kpf,2022-02-02,2020-11-11
-1kpe,1998-03-25,1997-09-25
-5kpz,2016-08-31,2016-07-05
-3kp1,2010-01-26,2009-11-14
-1kpi,2002-01-11,2001-12-30
-7kpq,2021-06-16,2020-11-12
-7kp6,2022-02-09,2020-11-10
-3kpb,2010-01-12,2009-11-16
-6kp0,2020-01-22,2019-08-13
-3kpu,2010-09-29,2009-11-17
-3kpv,2010-09-29,2009-11-17
-6kpe,2020-03-25,2019-08-15
-4kp6,2013-07-10,2013-05-13
-3kp6,2010-09-29,2009-11-15
-1kpf,1998-03-25,1997-09-25
-4kp4,2014-02-12,2013-05-13
-3kpe,2009-12-22,2009-11-16
-6kpq,2020-06-17,2019-08-15
-7kpt,2021-06-16,2020-11-12
-3kpd,2010-01-12,2009-11-16
-3kp2,2010-06-09,2009-11-15
-6kpr,2019-12-04,2019-08-15
-2kpz,2010-11-03,2009-10-23
-6kpj,2020-03-25,2019-08-15
-1kp8,2003-03-25,2001-12-30
-5kpt,2016-08-31,2016-07-05
-7kpe,2021-11-17,2020-11-11
-4kpp,2013-06-26,2013-05-14
-5kpn,2016-12-21,2016-07-05
-5kpg,2016-09-07,2016-07-04
-4kpr,2014-05-14,2013-05-14
-7kpa,2021-01-13,2020-11-10
-3kpc,2010-01-12,2009-11-16
-4kpn,2013-11-27,2013-05-14
-4kpj,2014-04-30,2013-05-13
-3kpf,2010-11-17,2009-11-16
-7kpc,2021-11-17,2020-11-10
-2kpn,2010-01-12,2009-10-16
-5kpf,2017-07-12,2016-07-04
-7kp8,2021-01-13,2020-11-10
-4kpe,2014-11-26,2013-05-13
-7kpm,2021-03-10,2020-11-11
-4kpl,2014-05-14,2013-05-13
-6kpp,2020-08-19,2019-08-15
-6kpt,2020-07-01,2019-08-16
-5kp7,2016-08-31,2016-07-02
-6kpo,2019-10-02,2019-08-15
-5kp1,2016-09-07,2016-07-01
-1iwj,2002-06-05,2002-05-15
-4iwd,2013-12-11,2013-01-23
-1iw1,2003-04-04,2002-04-04
-1iwb,2003-05-01,2002-05-01
-2iw9,2006-09-06,2006-06-27
-5iw8,2016-08-17,2016-03-22
-6iwe,2019-01-02,2018-12-05
-4iw2,2013-04-24,2013-01-23
-2iw3,2006-08-17,2006-06-26
-8iwd,2024-04-03,2023-03-29
-4iwv,2013-04-24,2013-01-24
-3iwk,2010-01-19,2009-09-02
-5iwq,2016-07-20,2016-03-22
-2iw8,2006-09-06,2006-06-27
-2iwe,2007-06-12,2006-06-29
-8iws,2023-12-27,2023-03-31
-1iwh,2002-10-02,2002-05-15
-5iwy,2017-03-29,2016-03-23
-1iwo,2002-08-14,2002-05-26
-2iwb,2006-07-04,2006-06-27
-5iwi,2016-05-25,2016-03-22
-3iwa,2009-10-06,2009-09-02
-3iwf,2009-09-15,2009-09-02
-6iwg,2019-08-14,2018-12-05
-1iwi,2002-06-05,2002-05-15
-8iwo,2023-11-22,2023-03-30
-1iw9,2003-12-23,2002-04-25
-5iwc,2016-08-17,2016-03-22
-8iwh,2023-10-25,2023-03-30
-6iwi,2019-12-11,2018-12-05
-2iww,2006-08-14,2006-07-05
-8iww,2023-12-27,2023-03-31
-2iwx,2006-11-30,2006-07-05
-4iwy,2013-05-08,2013-01-24
-6iwh,2019-08-14,2018-12-05
-2iw2,2006-07-05,2006-06-24
-8iwf,2024-04-03,2023-03-29
-3iw6,2009-11-17,2009-09-02
-3iw8,2009-11-17,2009-09-02
-3iw5,2009-11-17,2009-09-02
-2iwv,2006-08-14,2006-07-04
-8iwz,2023-09-06,2023-03-31
-4iw0,2013-03-13,2013-01-23
-2iwz,2007-02-06,2006-07-05
-5iwd,2016-11-30,2016-03-22
-3iwl,2009-09-22,2009-09-02
-5iwm,2016-05-25,2016-03-22
-1iwq,2003-03-11,2002-05-31
-2iwk,2006-08-16,2006-06-30
-3iw4,2009-11-03,2009-09-02
-3iwt,2009-09-29,2009-09-03
-4iw9,2013-02-06,2013-01-23
-8iw3,2023-08-02,2023-03-29
-2iwa,2006-07-04,2006-06-27
-5iws,2016-05-25,2016-03-22
-1iwk,2002-06-05,2002-05-15
-2iws,2006-11-30,2006-07-04
-1iw6,2002-12-11,2002-04-22
-8iwt,2023-12-27,2023-03-31
-2iwd,2006-07-03,2006-06-27
-5iw3,2017-03-29,2016-03-21
-4iwp,2013-03-13,2013-01-24
-5iwr,2016-06-15,2016-03-22
-2iwg,2007-03-27,2006-06-30
-4iww,2013-08-21,2013-01-24
-1iwe,2002-08-28,2002-05-04
-1iw0,2003-04-08,2002-04-04
-3iwy,2010-04-21,2009-09-03
-4iw8,2013-03-27,2013-01-23
-3iwj,2010-01-19,2009-09-02
-2iwc,2006-07-04,2006-06-27
-6iw6,2019-04-24,2018-12-04
-2iw1,2006-10-11,2006-06-23
-4iw1,2013-04-24,2013-01-23
-2iw4,2006-11-07,2006-06-26
-8iwn,2024-04-10,2023-03-30
-5iwa,2016-04-27,2016-03-22
-3iw2,2009-11-03,2009-09-02
-5iwt,2016-06-15,2016-03-22
-3iw7,2009-11-17,2009-09-02
-8iwk,2024-04-10,2023-03-30
-4iwn,2013-05-29,2013-01-24
-8iwy,2023-09-06,2023-03-31
-6iwr,2019-02-06,2018-12-06
-8iw6,2023-08-02,2023-03-29
-1iwp,2002-10-02,2002-05-28
-6iwk,2019-12-11,2018-12-05
-2iwf,2006-08-16,2006-06-29
-8iwu,2023-12-27,2023-03-31
-5iw5,2016-07-13,2016-03-22
-8iwm,2023-05-31,2023-03-30
-5iw0,2016-07-27,2016-03-21
-2iwh,2006-08-09,2006-06-30
-4iwx,2013-05-08,2013-01-24
-4iw6,2013-03-27,2013-01-23
-5iwg,2016-08-31,2016-03-22
-8iwp,2023-12-27,2023-03-30
-4iwo,2013-03-13,2013-01-24
-3iw0,2009-11-03,2009-09-02
-2iwj,2007-10-09,2006-06-30
-2iw0,2006-07-04,2006-06-23
-2iw6,2006-09-06,2006-06-26
-3iww,2009-11-24,2009-09-03
-3iwe,2009-09-15,2009-09-02
-2iw5,2006-08-09,2006-06-26
-5iw4,2016-07-13,2016-03-22
-6iwd,2019-07-31,2018-12-05
-1iwl,2003-07-15,2002-05-17
-4iwk,2013-03-20,2013-01-23
-6iwq,2019-02-06,2018-12-06
-8iw5,2023-11-08,2023-03-29
-5iwx,2017-03-29,2016-03-23
-5iwe,2017-03-29,2016-03-22
-8iwx,2023-09-06,2023-03-31
-3iw3,2010-09-22,2009-09-02
-5iwf,2016-07-27,2016-03-22
-3iwd,2010-02-09,2009-09-02
-4iw3,2014-01-29,2013-01-23
-8iwr,2023-12-27,2023-03-31
-4iwz,2013-12-11,2013-01-24
-4iwc,2013-03-27,2013-01-23
-2iwu,2006-11-30,2006-07-04
-4iwj,2013-03-20,2013-01-23
-4iwf,2013-03-27,2013-01-23
-5iwk,2016-06-15,2016-03-22
-4iwq,2013-03-13,2013-01-24
-3iwm,2010-07-21,2009-09-02
-5iwl,2016-06-29,2016-03-22
-5iw6,2017-03-29,2016-03-22
-3iw1,2009-11-03,2009-09-02
-8iw7,2023-05-31,2023-03-29
-1iw7,2002-06-26,2002-04-22
-3iwc,2010-02-09,2009-09-02
-6iw7,2020-01-01,2018-12-04
-4iwh,2013-02-13,2013-01-23
-3iwo,2010-02-16,2009-09-03
-5iwp,2016-06-15,2016-03-22
-4qxj,2015-02-04,2014-07-21
-1qxl,2004-09-21,2003-09-08
-5qxw,2020-04-08,2020-02-11
-8qxq,2024-04-03,2023-10-24
-4qxo,2014-09-10,2014-07-21
-3qx5,2012-03-07,2011-03-01
-7qx3,2023-08-16,2022-01-26
-7qxr,2022-12-07,2022-01-27
-6qxp,2020-03-25,2019-03-07
-4qxb,2014-11-05,2014-07-19
-2qxj,2008-01-08,2007-08-11
-1qx2,2004-05-25,2003-09-04
-2qx1,2008-03-18,2007-08-10
-4qxx,2015-03-18,2014-07-22
-4qxh,2014-11-05,2014-07-20
-5qxu,2020-04-08,2020-02-11
-1qxr,2003-12-09,2003-09-08
-4qxg,2015-02-25,2014-07-20
-1qxj,2003-12-09,2003-09-07
-1qxo,2003-12-23,2003-09-08
-4qx5,2014-11-12,2014-07-18
-6qxa,2019-04-10,2019-03-07
-6qxt,2019-05-08,2019-03-08
-5qxo,2020-04-08,2020-02-11
-6qx1,2019-04-17,2019-03-06
-6qxj,2019-08-07,2019-03-07
-5qxs,2020-04-08,2020-03-09
-2qxi,2008-01-08,2007-08-11
-4qx7,2014-11-05,2014-07-18
-4qxe,2014-10-22,2014-07-20
-5qxz,2020-04-08,2020-02-11
-1qxk,2003-10-28,2003-09-08
-2qxw,2008-01-22,2007-08-13
-4qxr,2014-09-10,2014-07-21
-4qxp,2014-09-10,2014-07-21
-5qxk,2020-04-08,2020-02-11
-3qxm,2011-10-26,2011-03-02
-5qxj,2020-04-08,2020-02-11
-7qxz,2022-04-13,2022-01-27
-7qx2,2022-09-28,2022-01-26
-5qxr,2020-04-08,2020-02-11
-6qxr,2020-03-25,2019-03-07
-3qxb,2011-03-23,2011-03-01
-7qxq,2022-12-07,2022-01-27
-8qxn,2024-05-15,2023-10-24
-2qxs,2008-09-02,2007-08-12
-2qxx,2008-02-19,2007-08-13
-7qx1,2022-11-23,2022-01-26
-7qxd,2022-08-31,2022-01-26
-7qx9,2022-09-28,2022-01-26
-6qxy,2019-10-16,2019-03-08
-2qx6,2008-09-09,2007-08-10
-3qx7,2011-04-27,2011-03-01
-6qxw,2019-09-25,2019-03-08
-3qxs,2011-03-30,2011-03-02
-3qxx,2011-03-30,2011-03-02
-3qxj,2011-03-30,2011-03-01
-1qx0,2003-11-25,2003-09-04
-7qxl,2022-09-28,2022-01-26
-4qx4,2015-04-01,2014-07-18
-1qxs,2004-05-11,2003-09-08
-8qxl,2024-05-15,2023-10-24
-5qxp,2020-04-08,2020-02-11
-6qxz,2019-12-04,2019-03-08
-3qx8,2011-04-20,2011-03-01
-3qx9,2011-04-20,2011-03-01
-3qx2,2012-08-08,2011-03-01
-2qx4,2008-09-09,2007-08-10
-4qxd,2014-08-06,2014-07-19
-5qxv,2020-04-08,2020-02-11
-3qxc,2011-03-30,2011-03-01
-3qxh,2011-03-30,2011-03-01
-7qxk,2022-08-03,2022-01-26
-6qxl,2019-09-11,2019-03-07
-5qxl,2020-04-08,2020-02-11
-6qx2,2019-04-17,2019-03-06
-4qxi,2015-07-22,2014-07-21
-7qxt,2022-11-23,2022-01-27
-4qxq,2014-09-10,2014-07-21
-3qxt,2011-07-06,2011-03-02
-7qxn,2023-02-08,2022-01-26
-7qx0,2023-08-16,2022-01-26
-5qxm,2020-04-08,2020-02-11
-5qxn,2020-04-08,2020-02-11
-1qxa,2004-04-06,2003-09-05
-6qxq,2020-03-25,2019-03-07
-5qxx,2020-04-08,2020-02-11
-3qxg,2011-04-27,2011-03-01
-1qxz,2004-03-16,2003-09-09
-6qxg,2019-04-10,2019-03-07
-6qxn,2020-03-25,2019-03-07
-3qxz,2011-03-16,2011-03-02
-2qx0,2007-10-23,2007-08-10
-6qxs,2019-04-10,2019-03-07
-5qxq,2020-04-08,2020-02-11
-3qxo,2012-08-08,2011-03-02
-4qxc,2014-11-05,2014-07-19
-1qxd,2003-09-16,2003-09-05
-1qx1,2003-10-07,2003-09-04
-8qxk,2024-05-15,2023-10-24
-6qx6,2019-08-07,2019-03-07
-1qxy,2004-03-16,2003-09-09
-7qxe,2022-08-31,2022-01-26
-8qxm,2024-05-15,2023-10-24
-6qx3,2019-09-04,2019-03-07
-4qx6,2014-10-15,2014-07-18
-7qxx,2023-02-08,2022-01-27
-6qxh,2019-04-10,2019-03-07
-6qxk,2019-04-24,2019-03-07
-7qxu,2023-02-08,2022-01-27
-3qx3,2011-07-06,2011-03-01
-7qxw,2023-02-08,2022-01-27
-4qxk,2014-11-12,2014-07-21
-5qxi,2020-04-08,2020-02-11
-3qxq,2011-03-30,2011-03-02
-4qx8,2014-11-05,2014-07-19
-1qx4,2004-09-14,2003-09-04
-2qxg,2008-01-08,2007-08-11
-6qxu,2019-08-14,2019-03-08
-7qxo,2022-12-07,2022-01-26
-2qx9,2008-09-02,2007-08-10
-6qxx,2019-10-16,2019-03-08
-3qx4,2012-08-08,2011-03-01
-2qxf,2008-01-22,2007-08-11
-1qxe,2003-09-16,2003-09-05
-4qxm,2015-07-22,2014-07-21
-1qxw,2004-03-16,2003-09-09
-6qx9,2019-04-17,2019-03-07
-2qxm,2008-03-18,2007-08-12
-5qxy,2020-04-08,2020-02-11
-2qxl,2007-10-23,2007-08-12
-8qxo,2024-05-15,2023-10-24
-2qxh,2008-01-08,2007-08-11
-8qxj,2024-05-15,2023-10-24
-1qx6,2004-04-06,2003-09-04
-7qxc,2022-08-31,2022-01-26
-3qxw,2011-07-27,2011-03-02
-4qxs,2015-02-25,2014-07-21
-3qxy,2011-05-25,2011-03-02
-3qxp,2012-10-31,2011-03-02
-6qxf,2019-05-08,2019-03-07
-3qxv,2011-07-27,2011-03-02
-7qxy,2022-04-20,2022-01-27
-6qxv,2019-09-25,2019-03-08
-4qxa,2014-09-10,2014-07-19
-8qx2,2024-04-03,2023-10-20
-3qxe,2011-03-23,2011-03-01
-4qxv,2015-06-03,2014-07-22
-6qxd,2019-06-19,2019-03-07
-8qx5,2024-04-03,2023-10-22
-5qxt,2020-04-08,2020-02-11
-7qxp,2023-02-08,2022-01-26
-2qx8,2008-09-02,2007-08-10
-2qx7,2008-01-15,2007-08-10
-1s7r,2004-05-04,2004-01-30
-5s7p,2021-06-23,2020-12-11
-6s7e,2020-07-22,2019-07-04
-6s7a,2020-03-04,2019-07-04
-3s78,2011-10-19,2011-05-26
-6s7s,2019-09-25,2019-07-05
-1s7q,2004-05-04,2004-01-30
-1s73,2005-06-14,2004-01-28
-7s7l,2022-03-16,2021-09-16
-5s7n,2021-06-23,2020-12-11
-5s7z,2021-06-23,2020-12-11
-6s72,2020-07-15,2019-07-04
-3s72,2011-10-19,2011-05-26
-7s7f,2022-11-02,2021-09-15
-7s73,2022-07-27,2021-09-15
-1s72,2004-06-15,2004-01-28
-3s77,2011-10-19,2011-05-26
-6s7x,2020-01-15,2019-07-07
-3s7w,2011-07-27,2011-05-27
-1s7y,2005-02-08,2004-01-30
-7s76,2022-05-04,2021-09-15
-1s7t,2004-05-04,2004-01-30
-7s79,2022-11-02,2021-09-15
-5s7t,2021-06-23,2020-12-11
-1s7z,2004-02-10,2004-01-30
-3s7x,2011-06-29,2011-05-27
-5s72,2020-11-25,2020-11-13
-3s7p,2011-12-21,2011-05-26
-7s7x,2021-10-13,2021-09-17
-7s7q,2022-03-02,2021-09-17
-3s76,2011-10-19,2011-05-26
-1s7l,2005-03-15,2004-01-29
-3s7q,2012-01-11,2011-05-26
-5s7w,2021-06-23,2020-12-11
-3s74,2011-10-19,2011-05-26
-3s7s,2012-06-06,2011-05-26
-6s7h,2020-07-22,2019-07-04
-6s7b,2020-03-04,2019-07-04
-1s7x,2004-05-04,2004-01-30
-5s7x,2021-06-23,2020-12-11
-5s7y,2021-06-23,2020-12-11
-5s7j,2021-06-23,2020-12-11
-7s7g,2022-09-28,2021-09-15
-3s7d,2011-08-10,2011-05-26
-5s7v,2021-06-23,2020-12-11
-1s7n,2005-03-15,2004-01-29
-5s7h,2021-06-23,2020-12-11
-5s77,2021-06-23,2020-12-11
-6s7w,2019-09-25,2019-07-07
-5s76,2021-06-23,2020-12-11
-7s7e,2022-11-02,2021-09-15
-7s7r,2022-03-02,2021-09-17
-6s79,2020-03-04,2019-07-04
-3s7l,2011-08-31,2011-05-26
-3s7f,2011-08-10,2011-05-26
-5s7k,2021-06-23,2020-12-11
-6s7k,2019-09-25,2019-07-05
-6s7o,2019-12-18,2019-07-05
-7s7i,2022-10-05,2021-09-16
-7s7k,2021-10-27,2021-09-16
-1s7d,2004-08-10,2004-01-29
-6s7z,2019-09-25,2019-07-07
-3s7j,2011-08-10,2011-05-26
-7s71,2022-07-27,2021-09-15
-3s7a,2011-10-05,2011-05-26
-7s72,2022-07-27,2021-09-15
-3s7o,2011-12-21,2011-05-26
-5s7a,2021-06-23,2020-12-11
-6s77,2020-03-04,2019-07-04
-3s79,2012-06-06,2011-05-26
-7s74,2022-07-27,2021-09-15
-7s7c,2022-06-15,2021-09-15
-3s73,2011-12-21,2011-05-26
-6s71,2020-03-04,2019-07-04
-6s7u,2019-09-25,2019-07-06
-7s70,2022-07-27,2021-09-15
-5s7e,2021-06-23,2020-12-11
-3s7k,2011-07-06,2011-05-26
-5s7s,2021-06-23,2020-12-11
-6s7t,2019-12-18,2019-07-05
-5s7r,2021-06-23,2020-12-11
-5s78,2021-06-23,2020-12-11
-1s70,2004-06-22,2004-01-28
-6s73,2020-06-10,2019-07-04
-7s7m,2022-03-16,2021-09-16
-5s71,2020-11-25,2020-11-13
-5s7g,2021-06-23,2020-12-11
-5s7u,2021-06-23,2020-12-11
-1s78,2004-04-27,2004-01-29
-1s76,2004-03-23,2004-01-29
-3s7h,2011-07-06,2011-05-26
-3s75,2011-10-19,2011-05-26
-7s7h,2021-12-29,2021-09-16
-6s7f,2020-07-22,2019-07-04
-1s7u,2004-05-04,2004-01-30
-5s7o,2021-06-23,2020-12-11
-6s70,2020-03-04,2019-07-04
-6s7p,2019-12-25,2019-07-05
-5s7d,2021-06-23,2020-12-11
-1s7s,2004-05-04,2004-01-30
-6s7l,2021-04-14,2019-07-05
-6s7m,2020-07-15,2019-07-05
-6s7g,2019-08-21,2019-07-04
-5s70,2020-11-25,2020-11-13
-3s7n,2011-12-21,2011-05-26
-3s71,2011-10-19,2011-05-26
-1s7v,2004-05-04,2004-01-30
-5s7i,2021-06-23,2020-12-11
-7s7d,2022-11-02,2021-09-15
-5s7q,2021-06-23,2020-12-11
-7s75,2022-07-27,2021-09-15
-6s74,2020-03-04,2019-07-04
-3s7m,2011-08-31,2011-05-26
-3s70,2012-04-11,2011-05-26
-1s77,2004-03-23,2004-01-29
-5s7f,2021-06-23,2020-12-11
-5s79,2021-06-23,2020-12-11
-6s75,2020-06-10,2019-07-04
-5s75,2021-06-23,2020-12-11
-5s7m,2021-06-23,2020-12-11
-5s7l,2021-06-23,2020-12-11
-1s7g,2004-03-23,2004-01-29
-5s7b,2021-06-23,2020-12-11
-6s7r,2020-01-08,2019-07-05
-1s7w,2004-05-04,2004-01-30
-3s7b,2011-08-10,2011-05-26
-6s7q,2019-07-17,2019-07-05
-7s7t,2021-10-13,2021-09-17
-7s7w,2021-10-13,2021-09-17
-7s7j,2022-09-28,2021-09-16
-3s7z,2011-10-05,2011-05-27
-8s7c,2024-04-24,2024-02-29
-7s7b,2022-06-15,2021-09-15
-6s7c,2020-03-04,2019-07-04
-5s7c,2021-06-23,2020-12-11
-7s7a,2022-09-28,2021-09-15
-5knk,2016-09-28,2016-06-28
-5kn1,2016-10-05,2016-06-27
-1knj,2002-06-18,2001-12-18
-4kng,2013-06-19,2013-05-09
-4kn9,2013-07-10,2013-05-09
-4knb,2014-04-30,2013-05-09
-3kn8,2010-09-15,2009-11-12
-7kny,2021-11-10,2020-11-06
-6knt,2019-09-18,2019-08-07
-1knk,2002-06-18,2001-12-18
-6knm,2020-01-29,2019-08-06
-6knv,2019-10-23,2019-08-07
-5knn,2016-09-28,2016-06-28
-1kne,2002-03-20,2001-12-18
-4knw,2013-06-26,2013-05-10
-5kn5,2016-08-31,2016-06-27
-1knr,2002-04-17,2001-12-19
-4knm,2013-11-06,2013-05-10
-2kne,2009-11-24,2009-08-21
-1kny,1996-08-17,1995-07-07
-4knl,2014-03-12,2013-05-10
-4kni,2013-11-06,2013-05-10
-5knr,2017-07-19,2016-06-28
-4knk,2014-03-12,2013-05-10
-5knv,2017-07-19,2016-06-28
-5kn0,2016-10-05,2016-06-27
-3kn4,2010-10-27,2009-11-12
-6knj,2020-08-12,2019-08-05
-6knf,2020-08-12,2019-08-05
-5kne,2016-07-27,2016-06-28
-7kn8,2021-05-26,2020-11-04
-7kno,2020-12-30,2020-11-05
-7kn2,2021-11-17,2020-11-04
-5knu,2017-07-19,2016-06-28
-1kno,1996-01-29,1995-09-11
-5kn9,2017-02-08,2016-06-27
-4kn0,2013-08-07,2013-05-08
-4knn,2013-11-06,2013-05-10
-3kn3,2009-12-01,2009-11-11
-7kng,2021-04-07,2020-11-04
-7knw,2021-12-08,2020-11-06
-4kn2,2013-08-07,2013-05-08
-6knl,2020-08-12,2019-08-05
-4kn1,2013-08-07,2013-05-08
-6kni,2019-11-13,2019-08-05
-6knw,2019-10-23,2019-08-07
-5knb,2016-11-02,2016-06-28
-4knh,2014-02-05,2013-05-09
-4knr,2014-10-15,2013-05-10
-5knq,2017-09-20,2016-06-28
-6kn8,2020-01-15,2019-08-03
-4knf,2013-06-05,2013-05-09
-7knf,2021-04-07,2020-11-04
-6knr,2020-08-12,2019-08-07
-7knh,2020-12-16,2020-11-04
-3knv,2009-11-24,2009-11-12
-5kns,2017-07-19,2016-06-28
-5knt,2017-07-19,2016-06-28
-6kn7,2020-01-15,2019-08-03
-1kn2,2002-03-13,2001-12-18
-6knu,2019-10-23,2019-08-07
-3kn5,2010-04-21,2009-11-12
-7kn1,2020-11-11,2020-11-03
-5kny,2017-09-20,2016-06-28
-5knx,2017-07-19,2016-06-28
-7kn3,2021-09-22,2020-11-04
-5knd,2016-11-02,2016-06-28
-1kn1,2002-12-18,2001-12-18
-4kne,2013-12-25,2013-05-09
-4knv,2013-06-26,2013-05-10
-7kn7,2021-01-20,2020-11-04
-1knz,2002-01-17,2001-12-19
-1knm,2002-06-19,2001-12-19
-6knc,2020-08-05,2019-08-05
-2kn9,2009-09-15,2009-08-20
-5knc,2016-11-02,2016-06-28
-4kn3,2013-09-04,2013-05-08
-6kn9,2020-02-12,2019-08-05
-5kn8,2017-02-08,2016-06-27
-7knk,2021-12-01,2020-11-04
-5knp,2017-09-20,2016-06-28
-1knu,2002-12-19,2001-12-19
-7knj,2022-05-04,2020-11-04
-1kna,2002-03-20,2001-12-18
-1knp,2002-04-17,2001-12-19
-7kna,2021-03-31,2020-11-04
-3kn7,2010-09-15,2009-11-12
-3knr,2010-11-24,2009-11-12
-7knc,2021-05-26,2020-11-04
-7kns,2021-03-24,2020-11-05
-5kn7,2016-09-28,2016-06-27
-3kne,2011-05-18,2009-11-12
-7knd,2022-05-04,2020-11-04
-6kns,2019-09-18,2019-08-07
-4knu,2013-07-24,2013-05-10
-5knm,2017-06-14,2016-06-28
-7kne,2020-12-16,2020-11-04
-7kn6,2021-01-20,2020-11-04
-6knk,2019-11-13,2019-08-05
-4kna,2013-06-05,2013-05-09
-3kn0,2010-01-19,2009-11-11
-1knd,2002-03-27,2001-12-18
-4knj,2013-11-06,2013-05-10
-2knx,2010-04-14,2009-09-07
-7kn5,2021-01-20,2020-11-04
-4kns,2013-07-24,2013-05-10
-6kng,2020-08-12,2019-08-05
-3kn2,2010-01-19,2009-11-11
-2kny,2010-04-14,2009-09-08
-4kn7,2013-05-22,2013-05-08
-1knw,2003-11-11,2001-12-19
-7knp,2020-12-23,2020-11-05
-1knf,2002-03-27,2001-12-18
-6knz,2019-10-23,2019-08-07
-4knt,2013-07-24,2013-05-10
-7knx,2021-12-08,2020-11-06
-5kn3,2016-10-05,2016-06-27
-3knx,2010-10-27,2009-11-12
-4knx,2014-10-15,2013-05-10
-2kn2,2009-08-25,2009-08-12
-7knr,2021-11-10,2020-11-05
-4kn6,2013-08-14,2013-05-08
-7knb,2020-12-09,2020-11-04
-3knt,2010-02-02,2009-11-12
-5knj,2016-11-16,2016-06-28
-7knz,2021-11-17,2020-11-06
-7kn4,2021-09-22,2020-11-04
-7kni,2020-12-16,2020-11-04
-6knb,2020-08-05,2019-08-05
-7kn9,2021-11-17,2020-11-04
-3kna,2010-07-07,2009-11-12
-3kns,2010-11-24,2009-11-12
-4kn4,2013-05-22,2013-05-08
-7knv,2021-02-03,2020-11-06
-5kn2,2016-10-05,2016-06-27
-1kn4,2002-03-13,2001-12-18
-2oc1,2007-07-31,2006-12-20
-1ocd,1997-06-16,1996-07-03
-7ocr,2022-04-20,2021-04-28
-7ocb,2022-05-04,2021-04-26
-7oci,2022-02-16,2021-04-27
-7ocn,2022-04-20,2021-04-28
-2oc7,2007-07-31,2006-12-20
-2oc8,2007-07-31,2006-12-20
-6oc6,2020-05-13,2019-03-21
-2oc2,2007-05-22,2006-12-20
-4oci,2014-12-24,2014-01-09
-4ocm,2014-01-29,2014-01-09
-4oc0,2014-05-21,2014-01-08
-7ocd,2021-06-09,2021-04-26
-4oco,2014-05-14,2014-01-09
-6och,2019-06-26,2019-03-23
-2ocg,2008-02-05,2006-12-20
-5ocb,2018-06-27,2017-06-30
-2oc4,2007-05-22,2006-12-20
-1ocn,2003-05-22,2003-02-09
-6ocj,2020-01-15,2019-03-24
-4ock,2014-05-14,2014-01-09
-7oc4,2021-07-07,2021-04-26
-1ocq,2003-06-26,2003-02-09
-1oc2,2003-10-02,2003-02-04
-4oc1,2014-05-21,2014-01-08
-7ocs,2022-04-27,2021-04-28
-4ocv,2014-05-14,2014-01-09
-3ocx,2010-10-20,2010-08-10
-1oc7,2003-07-10,2003-02-06
-2ocb,2007-01-02,2006-12-20
-2oc5,2007-02-13,2006-12-20
-4ocz,2014-09-24,2014-01-09
-7ocf,2021-06-09,2021-04-26
-1occ,1996-12-07,1996-04-18
-7och,2021-12-01,2021-04-26
-6ocn,2020-02-12,2019-03-25
-3ocg,2010-11-17,2010-08-10
-6oci,2020-01-15,2019-03-24
-4oc2,2014-05-21,2014-01-08
-6ocv,2020-05-06,2019-03-25
-4oc3,2014-05-21,2014-01-08
-6occ,2020-03-25,2019-03-22
-5ocr,2017-10-18,2017-07-03
-5ocn,2017-08-02,2017-07-03
-7ocu,2022-04-27,2021-04-28
-2oci,2008-02-05,2006-12-20
-5ocm,2018-05-16,2017-07-03
-1ocj,2003-07-10,2003-02-07
-5och,2018-07-25,2017-06-30
-5ocj,2018-01-24,2017-07-03
-1ocb,2003-07-10,2003-02-07
-3ocd,2011-05-18,2010-08-09
-1oc4,2003-09-18,2003-02-05
-3ocp,2011-05-11,2010-08-10
-5ocy,2018-07-04,2017-07-04
-1ocz,1999-07-22,1998-07-13
-3och,2010-12-08,2010-08-10
-2ocj,2007-03-06,2006-12-20
-5ocu,2017-10-25,2017-07-03
-7oc1,2021-08-25,2021-04-25
-3oca,2010-09-08,2010-08-09
-3ocu,2010-10-20,2010-08-10
-1oc1,2004-02-02,2003-02-03
-4oca,2014-03-12,2014-01-08
-5occ,2018-07-25,2017-06-30
-5oca,2017-09-20,2017-06-30
-6oc1,2019-11-13,2019-03-21
-4ocj,2014-05-14,2014-01-09
-4ocx,2014-07-02,2014-01-09
-7oc6,2021-07-07,2021-04-26
-3oc4,2010-10-06,2010-08-09
-4oc6,2014-08-13,2014-01-08
-2ocl,2008-02-05,2006-12-20
-4ocl,2014-01-29,2014-01-09
-3ocq,2010-08-18,2010-08-10
-6ocx,2020-03-25,2019-03-25
-2ocv,2007-04-10,2006-12-21
-5oc3,2018-02-28,2017-06-29
-1oce,1999-05-18,1998-06-12
-5oc8,2018-08-22,2017-06-29
-4ocp,2014-05-14,2014-01-09
-2ocf,2007-11-06,2006-12-20
-5oc1,2017-11-01,2017-06-29
-4occ,2014-04-02,2014-01-08
-5oc2,2018-02-28,2017-06-29
-2oc9,2007-05-22,2006-12-20
-3ocv,2010-10-20,2010-08-10
-6ocw,2019-10-09,2019-03-25
-1ocy,2003-07-24,2003-02-11
-7oc5,2021-07-07,2021-04-26
-4ocu,2014-05-14,2014-01-09
-6ocg,2019-06-26,2019-03-23
-4oc4,2014-05-21,2014-01-08
-7ocp,2022-04-20,2021-04-28
-1oco,1999-07-22,1998-07-09
-6ocu,2019-12-11,2019-03-25
-3ocy,2010-10-20,2010-08-10
-7oct,2022-04-20,2021-04-28
-1ocu,2003-12-12,2003-02-10
-6oc0,2019-11-13,2019-03-21
-3ocs,2010-11-03,2010-08-10
-7oc8,2022-03-09,2021-04-26
-6ocl,2020-01-15,2019-03-24
-5oco,2018-08-22,2017-07-03
-6oco,2019-12-11,2019-03-25
-7occ,2021-06-09,2021-04-26
-7oc2,2022-04-06,2021-04-25
-4ocq,2014-05-14,2014-01-09
-5oc0,2018-06-20,2017-06-29
-3oct,2010-11-03,2010-08-10
-3oc1,2010-08-25,2010-08-09
-7oca,2021-06-09,2021-04-26
-2oc0,2007-07-31,2006-12-20
-4oc5,2014-05-21,2014-01-08
-3ocm,2010-10-06,2010-08-10
-5oc7,2017-12-27,2017-06-29
-5oct,2018-08-22,2017-07-03
-4ocg,2014-08-20,2014-01-09
-3ocb,2010-09-15,2010-08-09
-6oc5,2020-05-13,2019-03-21
-5oc9,2018-07-25,2017-06-29
-5ocs,2017-09-06,2017-07-03
-5oce,2017-12-27,2017-06-30
-5ocq,2017-10-18,2017-07-03
-2ocp,2007-01-16,2006-12-21
-2ocz,2007-01-23,2006-12-21
-7ocv,2021-07-28,2021-04-28
-1oc6,2003-07-10,2003-02-06
-6oc3,2019-05-15,2019-03-21
-7oc7,2022-01-19,2021-04-26
-5ocv,2018-03-28,2017-07-03
-7oce,2021-06-09,2021-04-26
-6ocz,2019-10-09,2019-03-25
-4oc7,2014-10-08,2014-01-08
-7ocq,2022-04-20,2021-04-28
-2occ,1999-01-13,1998-05-26
-6ocb,2019-05-29,2019-03-22
-3oc0,2010-08-25,2010-08-09
-2ocu,2007-01-02,2006-12-21
-2ock,2008-02-05,2006-12-20
-5ocw,2017-07-12,2017-07-03
-5oci,2018-05-23,2017-07-03
-6ocd,2020-04-01,2019-03-22
-3occ,2010-11-10,2010-08-09
-3ocl,2010-11-10,2010-08-10
-5ocf,2018-06-27,2017-06-30
-1oc5,2003-07-10,2003-02-06
-1ocr,1999-07-29,1998-07-07
-3ocn,2010-11-10,2010-08-10
-5ocg,2018-08-22,2017-06-30
-6ocq,2019-05-08,2019-03-25
-3oce,2010-08-18,2010-08-09
-3ocw,2010-10-20,2010-08-10
-7oc0,2021-08-25,2021-04-25
-5ocp,2018-08-01,2017-07-03
-3ocz,2011-07-20,2010-08-10
-6ock,2020-01-15,2019-03-24
-7v17,2022-08-03,2022-05-11
-2v18,2007-09-11,2007-05-22
-4v1x,2015-03-11,2014-10-04
-1v11,2004-06-03,2004-04-05
-5v1s,2017-08-30,2017-03-02
-6v16,2020-03-11,2019-11-19
-5v1j,2017-05-10,2017-03-02
-3v17,2012-01-18,2011-12-09
-5v1r,2017-05-10,2017-03-02
-6v1q,2019-12-04,2019-11-20
-5v1i,2017-05-10,2017-03-02
-4v1m,2015-02-04,2014-09-29
-8v14,2024-01-31,2023-11-19
-6v1m,2020-03-25,2019-11-20
-1v1g,2005-01-19,2004-04-15
-5v1u,2018-09-05,2017-03-02
-8v1f,2024-02-07,2023-11-20
-7v1w,2021-11-03,2021-08-06
-7v1f,2022-06-15,2021-08-04
-4v1u,2015-01-14,2014-10-02
-4v1a,2014-10-08,2014-09-25
-6v1o,2020-03-25,2019-11-20
-4v1f,2015-05-20,2014-09-26
-4v1y,2015-03-11,2014-10-04
-7v19,2022-07-20,2022-05-11
-7v1h,2022-06-15,2021-08-04
-2v1e,2007-06-12,2007-05-23
-1v1f,2005-01-19,2004-04-15
-6v1c,2019-12-11,2019-11-20
-6v10,2019-12-11,2019-11-19
-6v1j,2020-03-25,2019-11-20
-2v1a,2007-12-11,2007-05-22
-2v1f,2007-06-12,2007-05-24
-6v1f,2020-03-11,2019-11-20
-3v1u,2012-11-28,2011-12-10
-7v1t,2022-08-10,2021-08-06
-5v1p,2017-05-10,2017-03-02
-6v1s,2020-03-18,2019-11-21
-7v1r,2021-12-29,2021-08-05
-3v1m,2012-03-21,2011-12-09
-7v1x,2021-11-03,2021-08-06
-2v1o,2007-06-26,2007-05-28
-1v13,2004-06-23,2004-04-06
-4v15,2015-03-25,2014-09-24
-2v1s,2007-06-12,2007-05-29
-2v1z,2008-06-24,2007-05-31
-7v12,2022-08-03,2022-05-11
-2v1c,2007-07-03,2007-05-23
-1v1q,2004-10-25,2004-04-22
-5v13,2017-08-09,2017-03-01
-2v1j,2007-06-12,2007-05-24
-2v15,2008-06-10,2007-05-22
-3v1c,2012-01-11,2011-12-09
-7v1j,2022-06-15,2021-08-04
-1v1k,2004-05-04,2004-04-16
-3v14,2012-01-04,2011-12-09
-6v1g,2019-12-11,2019-11-20
-3v1s,2012-02-29,2011-12-10
-3v1y,2012-11-28,2011-12-10
-8v10,2024-05-15,2023-11-19
-2v1p,2008-06-10,2007-05-28
-1v16,2004-06-03,2004-04-07
-6v1b,2020-03-11,2019-11-20
-2v1q,2008-06-03,2007-05-29
-6v1u,2020-03-11,2019-11-21
-2v1i,2007-06-12,2007-05-24
-5v1b,2017-06-21,2017-03-01
-3v1e,2012-01-11,2011-12-09
-8v1l,2024-02-14,2023-11-20
-3v12,2012-12-12,2011-12-09
-7v10,2022-08-03,2022-05-11
-3v16,2012-04-04,2011-12-09
-6v17,2020-03-11,2019-11-19
-2v1u,2007-09-18,2007-05-30
-6v1h,2020-03-11,2019-11-20
-2v1k,2007-06-12,2007-05-24
-3v1w,2012-12-12,2011-12-10
-3v19,2012-12-12,2011-12-09
-5v1n,2017-05-10,2017-03-02
-3v1d,2012-01-11,2011-12-09
-1v1t,2005-06-14,2004-04-23
-3v13,2012-12-12,2011-12-09
-4v1n,2015-02-04,2014-09-29
-7v16,2022-08-03,2022-05-11
-4v1t,2015-01-14,2014-10-02
-2v1x,2007-07-03,2007-05-30
-2v1r,2008-06-03,2007-05-29
-2v1w,2007-06-12,2007-05-30
-2v17,2007-12-25,2007-05-22
-5v1g,2017-05-10,2017-03-02
-7v11,2022-08-03,2022-05-11
-6v1x,2020-06-03,2019-11-21
-7v1i,2022-06-15,2021-08-04
-1v1m,2004-06-03,2004-04-20
-4v1v,2015-01-14,2014-10-02
-6v19,2020-11-25,2019-11-20
-5v1w,2017-06-28,2017-03-02
-2v11,2007-07-03,2007-05-21
-6v11,2020-01-22,2019-11-19
-6v1z,2019-12-11,2019-11-21
-6v15,2020-11-25,2019-11-19
-7v13,2022-08-03,2022-05-11
-7v18,2022-08-03,2022-05-11
-1v1b,2004-04-14,2004-04-13
-7v15,2022-08-03,2022-05-11
-3v1v,2012-04-11,2011-12-10
-4v19,2014-10-08,2014-09-25
-2v1m,2009-09-08,2008-09-16
-4v1h,2016-01-20,2014-09-26
-2v1h,2007-06-12,2007-05-24
-6v1y,2020-06-03,2019-11-21
-7v14,2022-08-03,2022-05-11
-5v1x,2018-03-07,2017-03-02
-1v1j,2005-01-26,2004-04-16
-3v1r,2012-03-14,2011-12-09
-5v19,2017-03-29,2017-03-01
-6v1e,2020-03-11,2019-11-20
-2v16,2008-07-08,2007-05-22
-4v1k,2016-01-20,2014-09-29
-4v12,2015-03-18,2014-09-23
-1v14,2004-06-23,2004-04-06
-6v14,2020-03-11,2019-11-19
-3v11,2012-03-28,2011-12-09
-5v1o,2017-05-10,2017-03-02
-5v1m,2017-08-16,2017-03-02
-3v1f,2012-01-11,2011-12-09
-3v1p,2012-11-21,2011-12-09
-5v1t,2017-08-30,2017-03-02
-6v1k,2020-03-11,2019-11-20
-3v1h,2012-04-04,2011-12-09
-6v18,2020-11-25,2019-11-20
-3v1g,2012-12-12,2011-12-09
-7v1e,2022-06-15,2021-08-04
-5v1d,2018-02-14,2017-03-02
-2v13,2008-07-08,2007-05-21
-2v1b,2007-12-11,2007-05-22
-7v1g,2022-06-15,2021-08-04
-6v1p,2020-03-25,2019-11-20
-6v1a,2020-11-25,2019-11-20
-4v1z,2015-01-14,2014-10-04
-1v15,2004-06-23,2004-04-06
-2v12,2007-07-03,2007-05-21
-7v1y,2022-02-16,2021-08-07
-7v1o,2022-08-10,2021-08-05
-4v11,2015-02-25,2014-09-22
-5v12,2018-03-07,2017-03-01
-5v1h,2017-05-10,2017-03-02
-2v10,2007-07-03,2007-05-21
-7v1u,2022-08-10,2021-08-06
-2v1g,2007-06-12,2007-05-24
-1v10,2004-09-16,2004-04-02
-5v18,2017-06-21,2017-03-01
-7v1q,2021-12-29,2021-08-05
-7v1c,2022-06-15,2021-08-04
-7v1b,2022-06-15,2021-08-04
-7v1v,2021-11-03,2021-08-06
-6v1l,2020-03-11,2019-11-20
-8v15,2023-12-06,2023-11-19
-2v19,2007-09-11,2007-05-22
-4v1o,2015-02-04,2014-09-29
-3v1x,2012-04-11,2011-12-10
-5v1f,2017-05-10,2017-03-02
-1v1r,2004-06-03,2004-04-22
-2v1d,2007-05-29,2007-05-23
-5v1v,2018-09-05,2017-03-02
-8v1p,2023-12-06,2023-11-21
-6v13,2020-11-25,2019-11-19
-1v1a,2004-04-14,2004-04-12
-7v1d,2022-06-15,2021-08-04
-3v1n,2012-03-21,2011-12-09
-6v1r,2020-11-25,2019-11-21
-7edd,2021-05-12,2021-03-15
-1edo,2001-01-31,2000-01-28
-8edz,2022-10-05,2022-09-06
-8edf,2023-09-20,2022-09-04
-3edh,2008-09-16,2008-09-03
-3edz,2008-09-23,2008-09-03
-6ed6,2018-11-14,2018-08-08
-8ede,2023-09-20,2022-09-04
-3edg,2008-09-16,2008-09-03
-4edg,2012-07-25,2012-03-27
-3ede,2009-03-03,2008-09-03
-6ed2,2019-02-13,2018-08-08
-7edf,2021-09-01,2021-03-16
-3eda,2009-02-24,2008-09-03
-8ed4,2023-04-12,2022-09-03
-5edi,2016-03-09,2015-10-21
-1ed4,2000-10-25,2000-01-26
-8ed9,2022-11-09,2022-09-03
-4edq,2013-03-20,2012-03-27
-4ed2,2012-07-11,2012-03-26
-3ed0,2009-07-21,2008-09-02
-6edz,2019-08-14,2018-08-12
-4edf,2012-11-21,2012-03-27
-6edu,2018-10-17,2018-08-11
-3edj,2009-03-03,2008-09-03
-4edj,2012-05-09,2012-03-27
-3edq,2008-10-28,2008-09-03
-5edf,2017-02-01,2015-10-21
-4edy,2012-10-03,2012-03-27
-8edy,2023-09-20,2022-09-06
-3edr,2008-10-28,2008-09-03
-1edm,1996-10-14,1996-03-21
-3edx,2009-07-07,2008-09-03
-5ede,2016-03-09,2015-10-21
-6edw,2019-08-14,2018-08-12
-5eds,2015-12-30,2015-10-21
-5edh,2016-03-09,2015-10-21
-5edt,2016-04-06,2015-10-22
-4edr,2012-07-25,2012-03-27
-4eda,2013-05-22,2012-03-27
-7edh,2021-09-01,2021-03-16
-5edq,2015-12-02,2015-10-21
-1ed6,2001-01-31,2000-01-26
-4ed1,2012-07-11,2012-03-26
-5ed4,2016-04-27,2015-10-20
-6ed1,2019-02-13,2018-08-08
-3ed4,2008-09-16,2008-09-02
-2ed3,2007-08-14,2007-02-14
-8edk,2023-01-11,2022-09-04
-3ed1,2008-11-25,2008-09-02
-4edz,2012-05-16,2012-03-27
-5edd,2016-11-02,2015-10-21
-4ed3,2012-07-11,2012-03-26
-3edy,2008-11-18,2008-09-03
-5edv,2016-01-20,2015-10-22
-6ede,2019-03-20,2018-08-09
-5ed1,2016-04-13,2015-10-20
-6edr,2018-11-21,2018-08-10
-6edk,2018-10-17,2018-08-09
-5edm,2016-01-20,2015-10-21
-7edg,2021-09-01,2021-03-16
-8ed8,2022-11-02,2022-09-03
-5ed8,2016-01-13,2015-10-21
-3edo,2008-09-30,2008-09-03
-7eda,2021-07-07,2021-03-15
-5edk,2016-01-20,2015-10-21
-7ed1,2022-03-16,2021-03-15
-8edc,2023-01-11,2022-09-04
-6edg,2019-02-06,2018-08-09
-5edl,2016-08-17,2015-10-21
-8edj,2023-01-11,2022-09-04
-4edt,2012-07-25,2012-03-27
-1ed8,2000-09-20,2000-01-27
-4edi,2013-03-27,2012-03-27
-8edh,2023-03-01,2022-09-04
-6ed7,2019-08-21,2018-08-08
-5edc,2016-03-09,2015-10-21
-1ed5,2001-01-31,2000-01-26
-7ed9,2022-03-16,2021-03-15
-5edb,2016-03-09,2015-10-21
-3edl,2009-01-20,2008-09-03
-3edd,2009-03-03,2008-09-03
-2ed4,2008-01-15,2007-02-14
-1ed9,2000-09-20,2000-01-27
-4ed8,2012-07-11,2012-03-27
-2ed5,2007-08-14,2007-02-14
-5ed2,2016-04-13,2015-10-20
-5edu,2016-07-27,2015-10-22
-7edj,2021-09-01,2021-03-16
-7edo,2021-08-11,2021-03-16
-7edz,2021-11-24,2021-03-17
-1edh,1997-01-11,1996-05-15
-5edr,2015-12-02,2015-10-21
-6edl,2019-05-01,2018-08-09
-7ed0,2022-03-16,2021-03-15
-3edb,2009-02-24,2008-09-03
-6eda,2018-11-28,2018-08-09
-4ed6,2012-07-11,2012-03-27
-7ed2,2022-03-16,2021-03-15
-7edi,2021-09-01,2021-03-16
-7eds,2022-06-22,2021-03-17
-3ed9,2009-02-24,2008-09-02
-5edw,2016-11-02,2015-10-22
-4ed0,2012-07-11,2012-03-26
-8edw,2022-12-21,2022-09-06
-3edf,2009-03-03,2008-09-03
-4ede,2012-12-26,2012-03-27
-8edi,2023-01-11,2022-09-04
-3edn,2008-10-07,2008-09-03
-7edb,2022-03-16,2021-03-15
-6edv,2018-12-26,2018-08-12
-5ed6,2017-01-25,2015-10-20
-6eds,2019-04-03,2018-08-10
-4ed4,2012-04-04,2012-03-26
-4ed7,2012-07-11,2012-03-27
-3edi,2008-09-16,2008-09-03
-8edd,2023-09-06,2022-09-04
-3edk,2009-03-03,2008-09-03
-6edt,2018-11-21,2018-08-10
-3edv,2009-01-20,2008-09-03
-4edu,2012-09-19,2012-03-27
-8ed7,2022-11-02,2022-09-03
-4edk,2012-07-25,2012-03-27
-5ed3,2017-01-25,2015-10-20
-6edc,2019-05-29,2018-08-09
-7edx,2021-05-05,2021-03-17
-7ed6,2022-03-16,2021-03-15
-7ed5,2022-02-16,2021-03-15
-5edg,2016-03-09,2015-10-21
-6edb,2019-05-29,2018-08-09
-4edv,2012-07-25,2012-03-27
-7edc,2022-03-23,2021-03-15
-4edh,2012-05-23,2012-03-27
-8edg,2023-08-02,2022-09-04
-2ow3,2008-02-19,2007-02-15
-8owg,2023-07-05,2023-04-27
-7ow4,2022-07-20,2021-06-16
-8owt,2024-05-08,2023-04-28
-3owo,2011-02-16,2010-09-20
-2owt,2008-02-26,2007-02-16
-7owj,2022-09-28,2021-06-18
-4ows,2014-04-23,2014-02-03
-1owy,2004-04-13,2003-03-31
-3owh,2011-05-25,2010-09-18
-1ow2,2004-01-20,2003-03-28
-2ow4,2007-10-23,2007-02-15
-2ow0,2007-06-19,2007-02-15
-6owp,2019-05-22,2019-05-10
-5owq,2017-09-13,2017-09-04
-7owb,2022-07-13,2021-06-17
-8ow9,2023-08-02,2023-04-27
-3owl,2010-12-15,2010-09-20
-8ow2,2023-05-24,2023-04-26
-7owk,2022-09-28,2021-06-18
-2owf,2007-08-21,2007-02-16
-8owa,2023-06-21,2023-04-27
-3ow3,2010-11-10,2010-09-17
-6ow0,2019-11-27,2019-05-08
-4owp,2015-08-05,2014-02-03
-2owm,2008-01-29,2007-02-16
-3owp,2011-09-21,2010-09-20
-2ow1,2007-06-19,2007-02-15
-1owi,2003-09-30,2003-03-28
-5owz,2018-02-28,2017-09-05
-4owd,2015-03-18,2014-01-31
-5owa,2018-06-27,2017-08-31
-8own,2023-08-09,2023-04-28
-6owu,2019-10-23,2019-05-11
-5owr,2017-09-13,2017-09-04
-3owm,2011-10-26,2010-09-20
-5owb,2018-07-18,2017-08-31
-2owg,2007-08-21,2007-02-16
-3own,2010-12-15,2010-09-20
-4owl,2014-05-28,2014-02-02
-6owy,2019-05-29,2019-05-12
-8ow5,2024-05-08,2023-04-27
-5owc,2018-08-01,2017-08-31
-2owd,2007-08-21,2007-02-16
-7owq,2022-12-21,2021-06-18
-4owv,2014-04-23,2014-02-04
-4owk,2014-05-28,2014-02-02
-4owo,2014-04-23,2014-02-02
-5owh,2018-07-25,2017-09-01
-4owx,2014-04-16,2014-02-04
-5owe,2018-10-10,2017-08-31
-5owd,2018-02-07,2017-08-31
-1owm,2004-04-13,2003-03-28
-3ow2,2012-06-20,2010-09-17
-7owv,2022-07-13,2021-06-19
-4owm,2014-04-23,2014-02-02
-8owp,2024-05-08,2023-04-28
-5ows,2018-05-02,2017-09-04
-7owf,2022-06-29,2021-06-18
-8ow8,2023-08-30,2023-04-27
-3owj,2010-12-15,2010-09-20
-2ow7,2008-01-08,2007-02-15
-5own,2018-04-11,2017-09-01
-2owu,2007-08-21,2007-02-17
-8owz,2023-11-15,2023-04-28
-3owb,2011-09-21,2010-09-17
-8owv,2024-05-08,2023-04-28
-5ow7,2018-02-07,2017-08-31
-8owo,2023-08-30,2023-04-28
-3ow5,2011-10-26,2010-09-17
-3owc,2010-11-03,2010-09-17
-5ow1,2017-11-22,2017-08-30
-7owl,2022-09-28,2021-06-18
-1owe,2003-09-30,2003-03-28
-6ow4,2019-06-26,2019-05-09
-4owz,2015-03-04,2014-02-04
-1owk,2003-09-30,2003-03-28
-1ow0,2003-05-27,2003-03-27
-7ow2,2022-07-13,2021-06-16
-1ows,2003-05-20,2003-03-30
-5oww,2018-10-10,2017-09-04
-3owa,2010-10-13,2010-09-17
-1own,2004-04-13,2003-03-28
-7owm,2022-12-21,2021-06-18
-6owm,2019-05-22,2019-05-10
-4owb,2014-09-24,2014-01-31
-8ow6,2024-05-15,2023-04-27
-1owd,2003-09-30,2003-03-28
-3owx,2011-05-25,2010-09-20
-8owm,2023-08-09,2023-04-28
-7owx,2022-03-16,2021-06-21
-3ow4,2010-11-10,2010-09-17
-6owi,2020-04-01,2019-05-09
-2owv,2007-08-21,2007-02-17
-8owy,2024-05-08,2023-04-28
-3owy,2011-09-21,2010-09-20
-3ow6,2011-09-21,2010-09-17
-4ow0,2014-04-23,2014-01-28
-3owv,2010-12-22,2010-09-20
-1owh,2003-09-30,2003-03-28
-8owq,2024-05-08,2023-04-28
-8owb,2024-05-08,2023-04-27
-2owk,2007-08-21,2007-02-16
-1owz,2004-04-13,2003-03-31
-5owl,2018-07-25,2017-09-01
-3ows,2011-09-21,2010-09-20
-5owk,2018-08-29,2017-09-01
-5owo,2018-07-11,2017-09-01
-4own,2014-04-23,2014-02-02
-2owo,2007-05-15,2007-02-16
-4owu,2014-04-23,2014-02-03
-3owf,2010-10-20,2010-09-17
-3ow1,2011-09-28,2010-09-17
-8owr,2024-05-08,2023-04-28
-3owd,2011-09-21,2010-09-17
-6owx,2019-05-29,2019-05-12
-7owy,2021-10-13,2021-06-21
-4owf,2014-02-12,2014-01-31
-5owf,2018-03-21,2017-08-31
-7ow7,2022-10-05,2021-06-16
-5owp,2017-12-13,2017-09-02
-6oww,2020-07-08,2019-05-12
-6ow2,2019-06-26,2019-05-09
-1owo,2004-04-13,2003-03-28
-8owf,2023-07-12,2023-04-27
-7own,2022-12-21,2021-06-18
-7owe,2022-09-28,2021-06-18
-2ow9,2007-02-27,2007-02-15
-7owo,2022-12-21,2021-06-18
-6owz,2019-05-29,2019-05-12
-4owq,2014-04-23,2014-02-03
-3owu,2011-09-21,2010-09-20
-7owi,2021-12-22,2021-06-18
-2owb,2007-04-24,2007-02-15
-2owc,2007-04-03,2007-02-16
-1ow3,2003-05-06,2003-03-28
-1owb,2004-05-18,2003-03-28
-7owp,2022-12-21,2021-06-18
-8oww,2024-05-08,2023-04-28
-2ow2,2007-06-19,2007-02-15
-4owa,2014-09-24,2014-01-31
-2owj,2007-06-19,2007-02-16
-4ow3,2014-03-12,2014-01-30
-8owl,2023-06-21,2023-04-28
-7ow3,2022-07-20,2021-06-16
-2ow6,2008-01-08,2007-02-15
-5ow0,2018-10-10,2017-08-30
-5ow8,2018-08-01,2017-08-31
-5ow3,2018-08-22,2017-08-30
-8owx,2024-05-08,2023-04-28
-2oww,2007-04-03,2007-02-17
-8ow3,2023-07-05,2023-04-26
-4owh,2014-09-24,2014-02-02
-7ow9,2021-08-25,2021-06-17
-1owj,2003-09-30,2003-03-28
-5ow9,2018-02-07,2017-08-31
-5owm,2018-10-10,2017-09-01
-2owl,2007-03-20,2007-02-16
-2owa,2007-02-27,2007-02-15
-6ow7,2019-06-26,2019-05-09
-2owh,2007-06-19,2007-02-16
-4owe,2014-09-24,2014-01-31
-6owe,2019-06-26,2019-05-09
-2owz,2007-03-06,2007-02-17
-1owp,2004-04-13,2003-03-28
-7owr,2022-12-21,2021-06-18
-6owh,2020-04-01,2019-05-09
-4owc,2014-09-24,2014-01-31
-3ow9,2011-08-31,2010-09-17
-5owy,2018-02-28,2017-09-05
-3owk,2010-12-15,2010-09-20
-1owl,2004-04-13,2003-03-28
-4oww,2014-04-16,2014-02-04
-5owt,2018-05-02,2017-09-04
-6owc,2019-06-19,2019-05-09
-1ow4,2003-08-05,2003-03-28
-6own,2020-05-13,2019-05-10
-3ow7,2010-11-17,2010-09-17
-8ow7,2023-08-02,2023-04-27
-7ow8,2022-01-19,2021-06-17
-1owq,2004-05-18,2003-03-29
-7owz,2022-07-13,2021-06-21
-6ow3,2019-07-24,2019-05-09
-6owj,2020-02-05,2019-05-10
-7owu,2022-12-21,2021-06-18
-2ows,2008-02-26,2007-02-16
-3c8k,2008-04-15,2008-02-12
-6c8r,2018-02-07,2018-01-25
-6c80,2018-06-20,2018-01-23
-7c8e,2021-06-02,2020-05-30
-8c8e,2023-10-25,2023-01-19
-2c84,2007-03-27,2005-12-01
-2c8w,2006-07-04,2005-12-08
-2c8a,2007-02-27,2005-12-03
-7c89,2020-12-30,2020-05-29
-1c8j,2001-05-09,2000-05-31
-7c82,2020-07-08,2020-05-28
-3c86,2008-02-19,2008-02-10
-1c8r,1999-10-20,1999-07-29
-5c80,2016-07-20,2015-06-25
-1c82,2001-04-05,2000-04-05
-7c8i,2021-06-02,2020-06-01
-1c8q,2001-06-13,2000-06-08
-5c8y,2015-11-04,2015-06-26
-7c8j,2021-01-27,2020-06-01
-7c8w,2020-06-24,2020-06-03
-5c84,2015-08-12,2015-06-25
-8c85,2024-01-17,2023-01-18
-7c8l,2021-06-02,2020-06-02
-6c88,2018-04-18,2018-01-24
-1c8y,1999-11-26,1999-07-30
-7c8d,2020-09-02,2020-05-29
-5c89,2016-07-13,2015-06-25
-6c85,2019-01-30,2018-01-24
-5c8b,2016-01-20,2015-06-25
-4c8k,2013-12-11,2013-10-01
-2c8l,2006-06-13,2005-12-06
-8c88,2023-11-22,2023-01-19
-4c8l,2013-12-11,2013-10-01
-2c81,2006-08-16,2005-11-30
-4c8b,2013-10-16,2013-09-30
-5c8u,2015-07-15,2015-06-26
-4c8o,2013-12-11,2013-10-01
-8c8b,2024-01-31,2023-01-19
-5c8w,2016-01-20,2015-06-26
-3c8b,2008-04-22,2008-02-11
-4c81,2014-01-08,2013-09-27
-5c8g,2015-07-22,2015-06-25
-1c88,2000-05-03,2000-04-16
-8c8u,2023-08-23,2023-01-21
-1c8h,2000-08-09,2000-05-05
-7c8z,2021-01-06,2020-06-04
-5c8c,2015-09-30,2015-06-25
-1c8d,2000-08-09,2000-05-05
-3c85,2008-03-04,2008-02-08
-1c8n,2000-08-30,2000-05-20
-5c8q,2015-08-12,2015-06-25
-1c8v,2000-01-13,1999-07-30
-2c8f,2007-02-27,2005-12-03
-3c84,2008-05-20,2008-02-08
-6c8p,2018-09-05,2018-01-25
-6c8f,2018-02-28,2018-01-24
-5c81,2016-06-29,2015-06-25
-5c8f,2015-09-30,2015-06-25
-3c89,2008-04-22,2008-02-11
-5c8a,2015-09-30,2015-06-25
-8c81,2023-10-11,2023-01-18
-2c8z,2006-07-04,2005-12-08
-5c88,2016-01-13,2015-06-25
-1c87,2000-05-03,2000-04-16
-6c8t,2018-09-05,2018-01-25
-2c80,2006-06-21,2005-11-30
-6c8w,2019-01-30,2018-01-25
-6c89,2018-12-12,2018-01-24
-7c8q,2021-06-09,2020-06-03
-8c8w,2023-08-16,2023-01-21
-4c82,2014-01-08,2013-09-27
-6c8s,2018-02-21,2018-01-25
-5c8l,2016-01-20,2015-06-25
-5c8m,2015-10-28,2015-06-25
-1c8t,2000-07-19,1999-07-29
-8c87,2023-11-22,2023-01-19
-3c8v,2008-02-26,2008-02-13
-8c86,2024-01-17,2023-01-18
-7c8a,2020-12-30,2020-05-29
-2c8k,2006-06-13,2005-12-06
-4c8g,2014-01-08,2013-10-01
-2c8h,2007-02-27,2005-12-03
-7c8b,2020-09-02,2020-05-29
-8c8d,2024-01-31,2023-01-19
-5c85,2016-05-25,2015-06-25
-3c8f,2008-10-28,2008-02-11
-5c8r,2015-09-23,2015-06-26
-1c8l,2000-05-31,2000-05-16
-3c88,2008-04-22,2008-02-11
-1c86,2000-05-03,2000-04-16
-3c8a,2008-04-22,2008-02-11
-5c8t,2015-07-15,2015-06-26
-4c83,2014-02-12,2013-09-29
-5c8e,2015-09-30,2015-06-25
-6c8q,2018-02-14,2018-01-25
-7c8f,2020-10-07,2020-05-30
-4c8r,2014-05-14,2013-10-01
-8c8i,2024-05-01,2023-01-20
-8c8c,2023-04-26,2023-01-19
-1c85,2000-05-03,2000-04-16
-8c8t,2023-07-05,2023-01-21
-4c8z,2013-11-06,2013-10-02
-1c8k,2000-05-24,2000-05-11
-3c8s,2009-02-17,2008-02-13
-6c8z,2018-02-07,2018-01-25
-7c84,2020-07-08,2020-05-28
-6c8g,2018-02-28,2018-01-24
-1c8m,2000-11-22,2000-05-26
-1c8g,2000-08-09,2000-05-05
-6c86,2018-02-28,2018-01-24
-1c84,2000-05-03,2000-04-14
-7c8u,2020-06-24,2020-06-03
-8c8s,2024-01-31,2023-01-20
-7c8v,2020-06-24,2020-06-03
-2c88,2006-06-13,2005-12-02
-5c8k,2015-10-28,2015-06-25
-3c8e,2009-02-24,2008-02-11
-2c8m,2005-12-15,2005-12-06
-4c80,2014-01-15,2013-09-27
-2c8s,2005-12-08,2005-12-06
-4c8d,2013-10-16,2013-09-30
-2c8x,2006-07-04,2005-12-08
-5c8i,2016-07-20,2015-06-25
-3c8q,2009-02-17,2008-02-13
-7c8x,2021-06-09,2020-06-03
-5c8n,2015-10-28,2015-06-25
-1c83,2000-05-03,2000-04-14
-5c8z,2016-06-29,2015-06-26
-5c8x,2016-06-29,2015-06-26
-5c8d,2015-09-30,2015-06-25
-6c8c,2019-06-12,2018-01-24
-1c80,2003-06-10,2000-04-03
-5c8s,2015-07-15,2015-06-26
-5c87,2016-05-25,2015-06-25
-4c8q,2013-10-16,2013-10-01
-3c8c,2008-02-19,2008-02-11
-1c8c,2001-05-04,2000-05-04
-4c8e,2014-01-08,2013-09-30
-8c80,2023-10-11,2023-01-18
-7c85,2020-07-08,2020-05-28
-7c8h,2021-06-02,2020-06-01
-1c8s,1999-10-20,1999-07-29
-8c8j,2023-12-20,2023-01-20
-7c86,2021-04-07,2020-05-28
-6c8h,2018-02-28,2018-01-24
-3c8z,2008-12-30,2008-02-14
-6c83,2019-02-27,2018-01-24
-8c89,2024-01-10,2023-01-19
-7c83,2021-01-27,2020-05-28
-2c8c,2007-02-27,2005-12-03
-8c8v,2023-08-16,2023-01-21
-1c8f,2000-08-09,2000-05-05
-8c82,2023-10-11,2023-01-18
-1c8i,2001-01-17,2000-05-08
-7c8k,2021-01-27,2020-06-02
-2c8v,2006-06-01,2005-12-08
-7c8t,2020-06-17,2020-06-03
-5c8p,2015-08-12,2015-06-25
-3c8y,2008-04-22,2008-02-14
-4c8i,2014-01-08,2013-10-01
-3c87,2008-02-26,2008-02-11
-5c83,2015-08-12,2015-06-25
-2c8n,2005-12-14,2005-12-06
-2c8y,2006-07-04,2005-12-08
-7c8r,2020-06-17,2020-06-03
-1c81,2003-06-10,2000-04-03
-8c8q,2023-03-01,2023-01-20
-8c8h,2024-01-31,2023-01-20
-1udw,2004-05-04,2003-05-07
-6udq,2020-03-25,2019-09-19
-1ud3,2003-07-22,2003-04-28
-1uda,1998-01-14,1997-01-06
-4udm,2016-01-13,2014-12-10
-5udr,2017-08-23,2016-12-28
-3uds,2012-03-14,2011-10-28
-8udk,2024-06-05,2023-09-28
-1udu,2004-05-11,2003-05-06
-6udk,2020-01-29,2019-09-19
-5udu,2017-08-23,2016-12-28
-4udk,2015-05-27,2014-12-10
-6udm,2020-09-23,2019-09-19
-6udr,2020-09-23,2019-09-19
-6ud5,2021-02-03,2019-09-18
-6ud7,2019-12-18,2019-09-18
-3ud5,2012-01-04,2011-10-27
-5udg,2017-03-29,2016-12-27
-4udc,2015-11-25,2014-12-09
-6ud4,2019-12-04,2019-09-18
-6ud2,2019-12-04,2019-09-18
-6udt,2019-12-04,2019-09-19
-3ude,2012-01-04,2011-10-28
-7ud8,2022-03-30,2022-03-18
-3ud4,2012-01-04,2011-10-27
-1udv,2003-08-05,2003-05-07
-5udx,2017-08-23,2016-12-28
-4udb,2015-11-25,2014-12-09
-4ud6,2015-03-25,2014-12-08
-6uda,2019-10-02,2019-09-19
-5ud7,2018-04-04,2016-12-23
-7ud7,2022-03-30,2022-03-18
-7udh,2022-08-17,2022-03-19
-3ud6,2011-11-23,2011-10-27
-8udc,2024-04-17,2023-09-28
-7ud0,2022-08-24,2022-03-17
-3udw,2012-03-14,2011-10-28
-5udt,2017-08-23,2016-12-28
-7udr,2022-03-30,2022-03-20
-4uda,2015-11-25,2014-12-09
-6udx,2019-12-11,2019-09-19
-4ud9,2015-08-26,2014-12-09
-4udw,2015-08-26,2014-12-12
-3ud7,2012-11-28,2011-10-27
-3udv,2012-01-04,2011-10-28
-4udi,2015-05-27,2014-12-10
-5udz,2017-03-22,2016-12-29
-3udk,2012-04-18,2011-10-28
-6udp,2020-03-25,2019-09-19
-3ud2,2012-02-22,2011-10-27
-1udh,1996-03-08,1995-10-30
-5ud6,2017-12-27,2016-12-23
-5ud4,2018-04-11,2016-12-23
-4udg,2015-05-27,2014-12-10
-7ud6,2023-01-11,2022-03-18
-1ud8,2003-07-22,2003-04-28
-6ude,2019-10-16,2019-09-19
-5udy,2017-03-22,2016-12-28
-7udk,2023-03-22,2022-03-20
-7ud5,2022-09-21,2022-03-18
-5ud3,2018-04-11,2016-12-23
-5ud5,2017-10-11,2016-12-23
-5udw,2017-08-23,2016-12-28
-1ud4,2003-07-22,2003-04-28
-4udr,2015-03-18,2014-12-11
-5ud2,2018-04-11,2016-12-23
-1ud5,2003-07-22,2003-04-28
-4udp,2015-03-18,2014-12-11
-6udj,2020-01-29,2019-09-19
-3udm,2012-04-18,2011-10-28
-5ud1,2018-04-11,2016-12-23
-5udl,2017-03-01,2016-12-27
-3udn,2012-04-18,2011-10-28
-8udt,2024-02-07,2023-09-29
-3udq,2012-04-18,2011-10-28
-7udd,2022-04-06,2022-03-18
-7udu,2022-08-03,2022-03-20
-7uda,2023-01-11,2022-03-18
-3uda,2012-11-28,2011-10-27
-8ud6,2024-02-21,2023-09-28
-4udd,2015-11-25,2014-12-09
-5udi,2017-03-01,2016-12-27
-5uda,2017-04-12,2016-12-24
-8udu,2024-02-07,2023-09-29
-4udx,2015-05-13,2014-12-12
-6udl,2020-09-23,2019-09-19
-6udc,2020-09-23,2019-09-19
-5udp,2017-01-11,2016-12-28
-5ud0,2018-04-11,2016-12-23
-7uds,2022-06-15,2022-03-20
-6udu,2019-12-04,2019-09-19
-5uds,2017-08-23,2016-12-28
-4ud0,2015-11-18,2014-12-05
-1udc,1998-01-14,1997-01-06
-2udp,1998-03-18,1997-03-08
-7udf,2023-01-04,2022-03-18
-3udj,2012-04-18,2011-10-28
-4udo,2015-02-11,2014-12-10
-1ud0,2004-05-11,2003-04-24
-3udi,2011-12-14,2011-10-28
-1ud2,2003-07-22,2003-04-28
-7udl,2023-03-22,2022-03-20
-3udg,2012-05-16,2011-10-28
-4udy,2015-05-13,2014-12-12
-4ud7,2016-01-13,2014-12-08
-8ud8,2024-02-21,2023-09-28
-3udl,2011-12-21,2011-10-28
-3udr,2012-04-18,2011-10-28
-3ud9,2012-11-28,2011-10-27
-5udv,2017-08-23,2016-12-28
-7ude,2022-03-30,2022-03-18
-3udh,2012-04-18,2011-10-28
-8ud7,2024-02-21,2023-09-28
-4ud8,2015-06-10,2014-12-09
-3udx,2011-12-14,2011-10-28
-4udv,2014-12-31,2014-12-11
-6udi,2019-12-04,2019-09-19
-5udh,2017-06-14,2016-12-27
-4udj,2015-05-27,2014-12-10
-1ud6,2003-07-22,2003-04-28
-4udq,2015-03-18,2014-12-11
-7udt,2022-08-03,2022-03-20
-8udv,2024-02-07,2023-09-29
-1udt,2004-05-11,2003-05-06
-7udp,2023-01-18,2022-03-20
-3udy,2012-04-18,2011-10-28
-1udy,2003-12-09,2003-05-07
-6ud3,2020-07-29,2019-09-18
-3ud8,2012-11-28,2011-10-27
-6ud8,2019-12-04,2019-09-18
-4ud2,2015-03-25,2014-12-05
-6udy,2019-12-11,2019-09-19
-6udv,2019-12-04,2019-09-19
-1udb,1998-01-14,1997-01-06
-3udd,2012-02-01,2011-10-28
-8ud9,2023-12-20,2023-09-28
-3udt,2012-03-14,2011-10-28
-7udq,2023-01-18,2022-03-20
-4udu,2015-06-24,2014-12-11
-7udj,2023-03-22,2022-03-20
-1ud9,2004-06-15,2003-04-28
-3udp,2012-04-18,2011-10-28
-7udg,2022-08-17,2022-03-19
-6udo,2020-03-25,2019-09-19
-6uv6,2020-11-25,2019-11-01
-4uvq,2014-09-17,2014-08-07
-8uvm,2024-04-03,2023-11-03
-5uvk,2017-05-24,2017-02-20
-1uvn,2004-02-26,2004-01-21
-6uvy,2019-12-11,2019-11-04
-7uvs,2023-02-15,2022-05-02
-4uvn,2015-07-29,2014-08-07
-7uvz,2023-04-19,2022-05-02
-8uvu,2024-03-20,2023-11-04
-6uvj,2020-01-01,2019-11-02
-1uvs,1997-11-19,1996-10-16
-7uvw,2023-04-19,2022-05-02
-6uv4,2020-01-01,2019-11-01
-2uvu,2007-05-08,2007-03-14
-4uv9,2014-09-10,2014-08-05
-7uvn,2023-01-11,2022-05-02
-1uvq,2004-02-05,2004-01-22
-3uvq,2012-12-05,2011-11-30
-7uv7,2023-05-17,2022-04-29
-8uvl,2024-05-29,2023-11-03
-4uvr,2014-11-26,2014-08-08
-5uvp,2017-03-15,2017-02-20
-4uvb,2014-09-10,2014-08-05
-3uvl,2011-12-14,2011-11-30
-5uve,2017-03-08,2017-02-20
-6uvp,2019-12-11,2019-11-04
-7uvd,2023-05-10,2022-04-30
-2uvl,2007-03-27,2007-03-12
-3uvn,2011-12-14,2011-11-30
-4uv7,2015-10-14,2014-08-05
-5uvx,2017-06-21,2017-02-20
-7uv5,2022-05-11,2022-04-29
-6uv2,2020-01-01,2019-11-01
-6uvc,2021-05-05,2019-11-02
-8uvz,2023-11-15,2023-11-05
-3uv6,2012-09-05,2011-11-29
-1uvh,2005-02-09,2004-01-20
-2uvq,2007-03-27,2007-03-13
-2uvx,2007-05-08,2007-03-15
-6uv1,2020-01-01,2019-11-01
-5uvj,2017-05-24,2017-02-20
-5uvb,2018-02-28,2017-02-20
-5uvw,2017-06-21,2017-02-20
-6uv8,2020-11-04,2019-11-01
-6uve,2021-05-05,2019-11-02
-2uvj,2007-05-22,2007-03-10
-3uvr,2012-12-19,2011-11-30
-7uva,2023-02-22,2022-04-29
-1uvx,2004-03-18,2004-01-27
-1uvo,2004-02-10,2004-01-21
-2uv0,2007-03-27,2007-03-08
-4uvh,2015-09-30,2014-08-05
-2uvy,2007-05-08,2007-03-15
-7uvm,2023-01-11,2022-05-02
-6uvb,2020-11-04,2019-11-01
-6uvf,2021-05-05,2019-11-02
-2uvi,2007-03-20,2007-03-10
-5uvy,2017-06-14,2017-02-20
-3uvc,2013-01-02,2011-11-29
-3uv3,2012-09-05,2011-11-29
-2uv8,2007-04-17,2007-03-09
-1uv5,2004-01-29,2004-01-14
-2uvm,2007-04-17,2007-03-12
-4uvd,2015-09-30,2014-08-05
-6uvq,2020-11-25,2019-11-04
-6uvv,2019-12-11,2019-11-04
-2uve,2007-05-08,2007-03-09
-3uvo,2011-12-14,2011-11-30
-7uvv,2023-04-19,2022-05-02
-2uv7,2007-05-08,2007-03-09
-3uv7,2012-09-05,2011-11-29
-7uv0,2022-12-21,2022-04-29
-1uvy,2004-03-18,2004-01-27
-7uvp,2023-05-10,2022-05-02
-7uvu,2023-01-11,2022-05-02
-2uvv,2007-05-08,2007-03-14
-4uvo,2015-07-29,2014-08-07
-5uvv,2017-06-21,2017-02-20
-5uvc,2017-07-26,2017-02-20
-4uvy,2015-07-29,2014-08-08
-3uva,2012-12-05,2011-11-29
-4uvp,2015-07-29,2014-08-07
-6uv3,2020-01-01,2019-11-01
-6uv0,2020-01-01,2019-11-01
-6uvg,2021-05-05,2019-11-02
-2uvp,2007-08-21,2007-03-13
-1uvt,1997-11-19,1996-10-16
-4uvl,2015-07-29,2014-08-07
-7uv9,2023-02-22,2022-04-29
-1uvu,1997-11-19,1996-10-16
-4uvw,2015-07-29,2014-08-08
-7uv6,2023-05-03,2022-04-29
-4uvc,2014-09-10,2014-08-05
-1uvl,2004-02-26,2004-01-21
-4uve,2015-09-30,2014-08-05
-5uvz,2017-06-14,2017-02-20
-2uvn,2007-12-18,2007-03-12
-5uv4,2017-04-26,2017-02-17
-4uvv,2015-07-29,2014-08-08
-1uvk,2004-02-19,2004-01-21
-4uvz,2015-07-29,2014-08-08
-7uvx,2023-04-19,2022-05-02
-2uvo,2008-05-27,2007-03-13
-2uv6,2007-05-08,2007-03-09
-5uvt,2017-06-21,2017-02-20
-2uvw,2007-05-08,2007-03-14
-4uv8,2014-09-10,2014-08-05
-7uvr,2023-01-11,2022-05-02
-7uve,2022-08-10,2022-05-01
-6uvx,2020-05-13,2019-11-04
-2uvr,2007-05-08,2007-03-13
-1uvm,2004-02-19,2004-01-21
-6uvh,2021-05-05,2019-11-02
-8uv3,2024-01-17,2023-11-02
-5uv5,2017-08-16,2017-02-19
-3uvf,2012-02-29,2011-11-29
-8uv0,2024-02-14,2023-11-02
-5uvg,2017-06-28,2017-02-20
-1uvr,2004-03-04,2004-01-22
-3uvp,2012-11-07,2011-11-30
-3uvv,2012-04-18,2011-11-30
-6uvw,2019-12-18,2019-11-04
-1uv4,2005-02-16,2004-01-14
-6uvk,2020-05-06,2019-11-02
-5uv1,2017-03-22,2017-02-17
-6uv5,2019-12-25,2019-11-01
-1uv0,2004-01-14,2004-01-12
-2uvh,2007-03-20,2007-03-10
-5uv2,2017-03-22,2017-02-17
-1uv6,2004-03-25,2004-01-15
-6uvd,2021-05-05,2019-11-02
-5uvl,2017-05-24,2017-02-20
-2uv5,2007-05-08,2007-03-09
-2uv2,2007-03-20,2007-03-08
-7uvb,2023-04-05,2022-04-29
-7uvy,2023-04-19,2022-05-02
-5uvd,2018-01-31,2017-02-20
-5uvi,2017-05-24,2017-02-20
-5uv3,2017-03-29,2017-02-17
-3uvi,2012-11-14,2011-11-30
-1uvj,2004-02-19,2004-01-21
-5uvf,2017-03-22,2017-02-20
-4uvx,2015-07-29,2014-08-08
-2uv4,2007-05-08,2007-03-09
-4uvs,2015-07-29,2014-08-08
-3uvx,2012-01-25,2011-11-30
-4uvt,2015-07-29,2014-08-08
-5uvs,2017-06-21,2017-02-20
-1uvp,2004-02-10,2004-01-21
-5uvu,2017-06-21,2017-02-20
-4uvg,2015-09-30,2014-08-05
-4uvi,2015-09-30,2014-08-05
-5uv6,2018-03-21,2017-02-19
-6uvm,2020-01-01,2019-11-03
-2uvz,2007-05-08,2007-03-15
-4uvu,2015-07-29,2014-08-08
-3uve,2011-12-14,2011-11-29
-1uvi,2004-02-19,2004-01-21
-4uva,2014-09-10,2014-08-05
-2uvf,2007-05-08,2007-03-09
-5uv8,2018-02-07,2017-02-19
-6uvn,2020-01-29,2019-11-03
-6ryk,2020-01-22,2019-06-10
-4ryf,2014-12-31,2014-12-15
-6ry4,2020-07-15,2019-06-10
-6ryw,2019-11-13,2019-06-12
-7ry4,2022-11-09,2021-08-24
-1ry8,2004-11-02,2003-12-19
-5ry8,2020-11-11,2020-10-30
-3rya,2011-06-29,2011-05-11
-5ry7,2020-11-11,2020-10-30
-6ry0,2020-08-12,2019-06-10
-5ryo,2020-11-11,2020-10-30
-5ryi,2020-11-11,2020-10-30
-6ryx,2019-11-13,2019-06-12
-5ry6,2020-11-11,2020-10-30
-6ry5,2020-08-12,2019-06-10
-7ryy,2021-10-27,2021-08-26
-1ry5,2004-04-13,2003-12-19
-4ryt,2015-09-09,2014-12-17
-5rye,2020-11-11,2020-10-30
-5ryj,2020-11-11,2020-10-30
-1ryr,2004-02-10,2003-12-22
-7ry8,2021-09-01,2021-08-24
-1rye,2005-02-15,2003-12-22
-5ry0,2020-11-11,2020-10-30
-3ryv,2011-08-10,2011-05-11
-7ry7,2022-02-02,2021-08-24
-7ryf,2022-02-02,2021-08-25
-5ryr,2020-11-11,2020-10-30
-5ryk,2020-11-11,2020-10-30
-7ryx,2021-09-08,2021-08-26
-5ryt,2020-11-11,2020-10-30
-5ry4,2020-11-11,2020-10-30
-5ry1,2020-11-11,2020-10-30
-4ryu,2015-09-09,2014-12-17
-5ryf,2020-11-11,2020-10-30
-7ry1,2022-05-11,2021-08-24
-6ryo,2020-01-15,2019-06-11
-5ry9,2020-11-11,2020-10-30
-5rya,2020-11-11,2020-10-30
-6ry2,2020-08-12,2019-06-10
-6ry6,2020-08-12,2019-06-10
-4ry5,2014-12-31,2014-12-13
-4ryd,2015-05-27,2014-12-15
-1ryd,2005-02-15,2003-12-22
-6ry7,2020-08-12,2019-06-10
-5ryl,2020-11-11,2020-10-30
-5ryc,2020-11-11,2020-10-30
-5ryq,2020-11-11,2020-10-30
-3ry4,2011-08-31,2011-05-11
-3ryd,2012-01-18,2011-05-11
-1ryi,2005-02-22,2003-12-22
-5ryv,2020-11-11,2020-10-30
-4ryz,2015-05-27,2014-12-17
-3rye,2011-06-01,2011-05-11
-5ryx,2020-11-11,2020-10-30
-7ryb,2021-09-01,2021-08-24
-1ryp,1998-04-15,1997-02-26
-3ryp,2012-05-02,2011-05-11
-3ryy,2011-08-10,2011-05-11
-6ryr,2020-07-15,2019-06-11
-3ryg,2011-12-28,2011-05-11
-8ryk,2024-05-22,2024-02-09
-4ryg,2015-03-25,2014-12-15
-5ryd,2020-11-11,2020-10-30
-7ry9,2021-09-01,2021-08-24
-1rya,2004-06-22,2003-12-20
-5ryy,2020-11-11,2020-10-30
-3ryr,2012-05-02,2011-05-11
-6ry1,2020-08-12,2019-06-10
-6ryj,2019-10-09,2019-06-10
-1ry0,2004-11-02,2003-12-19
-6ryg,2019-10-09,2019-06-10
-3ry2,2011-08-24,2011-05-10
-4ry8,2014-12-24,2014-12-13
-3ryz,2011-08-10,2011-05-11
-3ryb,2011-06-29,2011-05-11
-1ryq,2004-08-10,2003-12-22
-7ry5,2021-12-15,2021-08-24
-4ryl,2015-02-25,2014-12-15
-3ryh,2011-10-05,2011-05-11
-5ryu,2020-11-11,2020-10-30
-3ryo,2012-05-23,2011-05-11
-7ryw,2022-11-09,2021-08-26
-5ryh,2020-11-11,2020-10-30
-5rym,2020-11-11,2020-10-30
-5ry2,2020-11-11,2020-10-30
-5ryw,2020-11-11,2020-10-30
-5ryp,2020-11-11,2020-10-30
-6ryf,2019-12-18,2019-06-10
-5ry3,2020-11-11,2020-10-30
-3ryx,2011-08-10,2011-05-11
-7rya,2021-09-01,2021-08-24
-5ryb,2020-11-11,2020-10-30
-7rys,2022-11-23,2021-08-26
-3ryc,2011-10-05,2011-05-11
-6ryv,2019-11-13,2019-06-12
-4ryk,2015-01-07,2014-12-15
-5ryn,2020-11-11,2020-10-30
-7ryt,2023-02-22,2021-08-26
-5rys,2020-11-11,2020-10-30
-3ryt,2012-01-18,2011-05-11
-4ryx,2015-05-27,2014-12-17
-4ryy,2015-05-27,2014-12-17
-4ry9,2014-12-24,2014-12-13
-1ryw,2004-11-09,2003-12-22
-1ryc,1996-11-08,1996-05-10
-3rys,2011-05-25,2011-05-11
-4ryv,2015-12-09,2014-12-17
-6ryn,2019-10-09,2019-06-10
-4rya,2014-12-24,2014-12-13
-4ry3,2015-01-28,2014-12-13
-1ryh,2004-01-27,2003-12-22
-4ry0,2014-12-24,2014-12-12
-7ryn,2022-05-18,2021-08-25
-1ry2,2004-03-09,2003-12-19
-6rym,2019-10-09,2019-06-10
-5ryz,2020-11-11,2020-10-30
-5ry5,2020-11-11,2020-10-30
-4ryi,2015-01-28,2014-12-15
-3ryf,2011-10-05,2011-05-11
-1ryt,1997-05-15,1996-04-26
-7ryg,2022-02-02,2021-08-25
-3ry9,2011-06-29,2011-05-11
-6ryp,2020-01-15,2019-06-11
-7ryh,2022-02-02,2021-08-25
-4ryc,2015-03-25,2014-12-15
-1ryf,2004-01-27,2003-12-22
-7ryr,2022-11-23,2021-08-26
-6ryu,2020-07-15,2019-06-12
-1rys,2004-02-10,2003-12-22
-3ry6,2011-08-31,2011-05-11
-7ryc,2022-03-09,2021-08-24
-1ryo,2004-05-11,2003-12-22
-3rym,2011-11-23,2011-05-11
-6ryz,2020-04-15,2019-06-12
-7ry3,2022-02-02,2021-08-24
-3ryj,2011-08-10,2011-05-11
-3ryw,2012-05-23,2011-05-11
-7ryz,2021-10-27,2021-08-26
-3ryi,2011-10-05,2011-05-11
-5ryg,2020-11-11,2020-10-30
-3ryk,2011-05-25,2011-05-11
-5kd9,2016-11-16,2016-06-07
-4kd5,2013-05-08,2013-04-24
-4kdx,2013-05-08,2013-04-25
-6kd1,2019-07-17,2019-06-30
-3kdz,2010-07-07,2009-10-23
-5kdv,2017-01-11,2016-06-08
-5kd8,2017-01-11,2016-06-07
-7kdu,2021-08-04,2020-10-09
-7kdb,2021-04-21,2020-10-08
-7kdn,2020-11-04,2020-10-09
-4kd7,2013-10-09,2013-04-24
-7kdy,2022-01-12,2020-10-09
-4kd1,2013-09-18,2013-04-24
-5kdr,2016-08-10,2016-06-08
-7kdk,2020-11-04,2020-10-08
-7kd9,2021-02-17,2020-10-08
-4kdy,2013-05-08,2013-04-25
-5kdp,2016-09-28,2016-06-08
-6kd5,2020-06-24,2019-06-30
-8kd6,2023-09-13,2023-08-09
-6kds,2020-07-08,2019-07-02
-4kdo,2013-07-24,2013-04-25
-3kdu,2010-04-28,2009-10-23
-3kdo,2010-10-06,2009-10-23
-7kdc,2021-07-28,2020-10-08
-3kdn,2010-10-06,2009-10-23
-3kde,2009-12-08,2009-10-22
-5kdu,2017-01-11,2016-06-08
-1kdh,2002-05-13,2001-11-13
-5kdy,2018-02-07,2016-06-08
-5kd6,2016-12-21,2016-06-07
-2kdh,2009-06-16,2009-01-09
-6kdc,2020-07-08,2019-07-02
-6kdr,2020-07-08,2019-07-02
-6kdq,2020-07-08,2019-07-02
-6kdo,2020-03-04,2019-07-02
-6kdn,2020-03-04,2019-07-02
-3kd5,2011-04-13,2009-10-22
-4kd3,2013-05-08,2013-04-24
-6kde,2019-09-25,2019-07-02
-5kde,2016-09-28,2016-06-08
-3kdj,2009-11-10,2009-10-23
-1kdp,2002-01-22,2001-11-13
-6kdd,2020-07-08,2019-07-02
-3kdb,2010-03-02,2009-10-22
-3kdd,2010-03-02,2009-10-22
-1kd2,2003-06-10,2001-11-12
-6kd9,2020-03-18,2019-07-01
-3kd3,2009-12-15,2009-10-22
-3kdm,2010-05-26,2009-10-23
-6kdy,2019-09-25,2019-07-03
-7kde,2020-10-28,2020-10-08
-3kd1,2011-04-13,2009-10-22
-1kdk,2002-05-15,2001-11-13
-1kdo,2002-01-22,2001-11-13
-3kds,2009-12-01,2009-10-23
-3kd7,2010-02-02,2009-10-22
-8kdc,2024-04-24,2023-08-09
-6kdp,2020-02-19,2019-07-02
-1kdr,2002-01-22,2001-11-13
-5kdz,2018-02-07,2016-06-08
-4kdd,2014-03-12,2013-04-24
-3kdc,2010-03-16,2009-10-22
-8kd5,2023-09-13,2023-08-09
-5kdw,2017-01-11,2016-06-08
-7kdx,2022-01-12,2020-10-09
-7kdi,2020-11-04,2020-10-08
-7kdo,2020-12-02,2020-10-09
-7kd8,2021-10-06,2020-10-08
-8kd4,2023-09-13,2023-08-09
-4kdm,2013-07-24,2013-04-25
-7kda,2021-04-21,2020-10-08
-1kdj,1999-05-11,1998-05-08
-5kd0,2016-12-21,2016-06-07
-1kdw,2002-07-17,2001-11-13
-2kdp,2009-03-17,2009-01-14
-7kds,2020-11-11,2020-10-09
-6kd2,2019-07-17,2019-06-30
-5kda,2016-12-21,2016-06-07
-7kdr,2020-12-02,2020-10-09
-6kdk,2020-03-04,2019-07-02
-7kdg,2020-11-04,2020-10-08
-1kdt,2002-01-22,2001-11-13
-4kdv,2013-10-02,2013-04-25
-1kd1,2002-07-19,2001-11-12
-7kd0,2021-08-04,2020-10-07
-3kdt,2010-04-28,2009-10-23
-6kdu,2020-07-01,2019-07-02
-7kdm,2021-08-04,2020-10-08
-7kdw,2020-12-09,2020-10-09
-4kdw,2013-10-02,2013-04-25
-5kdq,2016-06-22,2016-06-08
-7kd7,2021-06-16,2020-10-08
-5kdo,2016-08-03,2016-06-08
-5kd5,2017-01-11,2016-06-07
-5kd1,2017-05-10,2016-06-07
-6kdi,2019-12-18,2019-07-02
-4kdr,2014-04-30,2013-04-25
-3kd0,2010-12-01,2009-10-22
-8kdb,2024-04-24,2023-08-09
-6kda,2020-02-19,2019-07-01
-6kdm,2020-03-04,2019-07-02
-7kd6,2021-10-13,2020-10-08
-6kdl,2020-02-19,2019-07-02
-5kdb,2018-02-07,2016-06-07
-3kdi,2009-11-10,2009-10-22
-1kdg,2002-11-13,2001-11-13
-7kdd,2021-03-17,2020-10-08
-7kd4,2021-09-15,2020-10-08
-6kdz,2019-08-14,2019-07-03
-5kdn,2017-01-11,2016-06-08
-5kdx,2017-01-11,2016-06-08
-3kd6,2009-11-03,2009-10-22
-7kd5,2021-10-06,2020-10-08
-7kdj,2020-11-04,2020-10-08
-4kd4,2013-05-08,2013-04-24
-4kdn,2013-07-24,2013-04-25
-5kd7,2017-10-11,2016-06-07
-5kdh,2017-08-02,2016-06-08
-2kdx,2009-10-20,2009-01-20
-1kds,2002-07-17,2001-11-13
-7kdl,2020-11-04,2020-10-08
-7kdp,2021-03-17,2020-10-09
-4kdq,2013-07-24,2013-04-25
-6kdj,2020-03-04,2019-07-02
-3kdp,2010-02-16,2009-10-23
-1kdn,1997-04-21,1996-09-10
-7kdh,2020-11-04,2020-10-08
-5kdf,2016-09-28,2016-06-08
-6kdt,2020-02-19,2019-07-02
-5kdl,2016-08-03,2016-06-08
-5kd2,2017-01-11,2016-06-07
-8kd3,2023-09-13,2023-08-09
-6kd7,2019-09-11,2019-07-01
-7kdv,2021-03-17,2020-10-09
-1kdq,2003-06-10,2001-11-13
-5kdj,2017-01-11,2016-06-08
-2kdu,2009-12-15,2009-01-19
-7kd2,2021-08-04,2020-10-07
-1kdi,1999-05-11,1998-05-08
-5kdt,2016-07-13,2016-06-08
-7kdz,2020-12-09,2020-10-09
-3kdk,2010-07-21,2009-10-23
-1kdm,2002-05-15,2001-11-13
-6kdx,2019-08-14,2019-07-03
-6kdb,2020-02-19,2019-07-01
-5kds,2017-01-11,2016-06-08
-8jch,2024-01-31,2023-05-11
-3jc6,2016-02-10,2015-11-24
-8jc4,2023-12-27,2023-05-10
-4jch,2014-03-26,2013-02-21
-5jcn,2016-10-12,2016-04-15
-8jco,2024-05-15,2023-05-11
-4jcj,2013-06-19,2013-02-21
-2jca,2007-01-30,2006-12-21
-5jcp,2016-06-22,2016-04-15
-5jcj,2016-08-17,2016-04-15
-6jcv,2019-04-17,2019-01-30
-5jch,2016-06-01,2016-04-15
-2jcq,2007-01-30,2007-01-03
-2jc1,2007-02-13,2006-12-18
-5jcl,2016-10-12,2016-04-15
-8jcw,2023-06-21,2023-05-12
-8jcj,2024-05-15,2023-05-11
-1jca,2001-06-20,2001-06-08
-4jc1,2013-07-31,2013-02-21
-4jcm,2014-02-26,2013-02-22
-1jcx,2002-01-16,2001-06-11
-5jcw,2016-10-12,2016-04-15
-3jct,2016-06-01,2016-03-09
-5jcu,2016-10-12,2016-04-15
-6jcz,2019-04-17,2019-01-30
-5jck,2016-10-12,2016-04-15
-5jcx,2016-08-17,2016-04-15
-4jc7,2014-01-01,2013-02-21
-6jci,2020-02-05,2019-01-28
-8jcv,2023-06-21,2023-05-12
-3jce,2016-01-13,2015-12-01
-1jcc,2003-06-17,2001-06-08
-8jck,2024-05-15,2023-05-11
-8jcy,2023-06-21,2023-05-12
-8jc5,2024-03-27,2023-05-10
-5jcb,2017-09-27,2016-04-14
-5jci,2016-10-12,2016-04-15
-4jcv,2013-08-07,2013-02-22
-3jcf,2016-02-17,2015-12-11
-4jcf,2013-08-14,2013-02-21
-2jcv,2007-05-08,2007-01-04
-2jcm,2007-01-30,2006-12-27
-1jcr,2001-11-02,2001-06-11
-5jcd,2017-02-22,2016-04-15
-1jc9,2001-11-28,2001-06-08
-8jca,2024-03-27,2023-05-10
-5jcq,2017-05-10,2016-04-15
-2jcw,1999-06-08,1998-12-21
-2jc3,2007-01-23,2006-12-19
-4jcz,2014-01-01,2013-02-22
-8jc3,2023-12-27,2023-05-10
-5jcf,2016-06-01,2016-04-15
-4jck,2013-07-31,2013-02-22
-3jc9,2016-03-16,2015-11-24
-6jc8,2020-02-05,2019-01-28
-1jcn,2003-06-17,2001-06-11
-1jcl,2001-10-31,2001-06-09
-5jcr,2017-05-10,2016-04-15
-1jcq,2001-11-02,2001-06-11
-2jc5,2007-03-06,2006-12-19
-5jc8,2016-05-11,2016-04-14
-3jcj,2016-03-09,2015-12-18
-3jck,2016-01-20,2015-12-20
-5jcz,2016-09-28,2016-04-15
-2jcs,2007-02-27,2007-01-03
-6jc3,2019-08-07,2019-01-28
-5jct,2017-01-11,2016-04-15
-8jc7,2023-09-27,2023-05-10
-4jcg,2013-08-14,2013-02-21
-2jc0,2007-02-13,2006-12-18
-4jc3,2013-05-15,2013-02-21
-5jc3,2016-06-01,2016-04-14
-1jcv,1996-03-08,1995-12-07
-6jcx,2019-05-29,2019-01-30
-8jce,2023-11-15,2023-05-11
-4jcw,2014-03-05,2013-02-22
-4jca,2013-03-20,2013-02-21
-5jc9,2016-07-06,2016-04-14
-6jc9,2020-02-05,2019-01-28
-4jci,2013-03-13,2013-02-21
-8jcr,2024-05-22,2023-05-11
-6jcy,2019-05-29,2019-01-30
-1jcg,2001-09-19,2001-06-09
-1jcz,2001-08-17,2001-06-11
-8jcx,2023-06-21,2023-05-12
-1jcm,2002-06-10,2001-06-10
-8jcz,2023-06-21,2023-05-12
-8jcu,2023-06-21,2023-05-12
-4jcl,2014-02-26,2013-02-22
-2jcd,2007-09-11,2006-12-21
-4jco,2013-03-20,2013-02-22
-1jc2,2001-09-14,2001-06-07
-1jcs,2001-11-02,2001-06-11
-2jcb,2007-02-20,2006-12-21
-6jc7,2020-02-05,2019-01-28
-2jc9,2007-01-02,2006-12-21
-5jca,2017-04-12,2016-04-14
-2jch,2007-08-14,2006-12-23
-3jcs,2016-07-20,2016-01-21
-2jc6,2007-02-13,2006-12-19
-3jca,2016-02-17,2015-11-24
-6jcw,2019-04-17,2019-01-30
-1jcy,2002-01-16,2001-06-11
-3jc7,2016-02-10,2015-11-24
-5jc1,2016-08-24,2016-04-14
-2jcj,2007-05-22,2006-12-25
-2jck,2007-05-22,2006-12-26
-5jco,2016-05-04,2016-04-15
-2jcr,2007-01-30,2007-01-03
-1jcj,2001-10-31,2001-06-09
-2jcx,2007-05-08,2007-01-04
-5jc6,2017-05-24,2016-04-14
-2jc4,2007-03-06,2006-12-19
-3jcn,2016-03-09,2016-01-04
-3jcu,2016-05-25,2016-03-10
-4jc5,2013-05-08,2013-02-21
-8jc0,2024-05-08,2023-05-10
-8jcq,2024-05-22,2023-05-11
-4jc6,2013-09-11,2013-02-21
-5jcm,2016-10-12,2016-04-15
-8jcn,2024-05-15,2023-05-11
-1jci,2002-03-06,2001-06-09
-3jcd,2016-01-13,2015-12-01
-5jce,2016-06-08,2016-04-15
-6jcu,2020-02-05,2019-01-30
-1jct,2001-09-05,2001-06-11
-8jcm,2024-05-15,2023-05-11
-2jcg,2007-03-06,2006-12-22
-6jch,2019-06-26,2019-01-28
-6jcj,2019-03-13,2019-01-29
-5jc7,2016-06-01,2016-04-14
-6jcl,2019-12-11,2019-01-29
-8jcl,2024-05-15,2023-05-11
-3jcm,2016-02-24,2015-12-23
-2jcc,2007-10-09,2006-12-21
-4pj9,2014-07-02,2014-05-12
-6pj1,2020-03-04,2019-06-27
-4pjk,2015-04-29,2014-05-12
-3pjl,2011-11-02,2010-11-10
-5pju,2017-03-15,2017-02-07
-1pj8,2003-06-17,2003-06-02
-6pjm,2020-07-01,2019-06-28
-7pjq,2021-10-20,2021-08-24
-7pjf,2021-09-22,2021-08-24
-6pjj,2019-08-28,2019-06-28
-4pjj,2015-04-29,2014-05-12
-7pjp,2021-10-20,2021-08-24
-5pj7,2017-03-15,2017-02-07
-5pjp,2017-03-15,2017-02-07
-4pj3,2015-01-21,2014-05-11
-7pju,2021-11-17,2021-08-24
-5pjc,2017-03-15,2017-02-07
-3pjz,2011-01-19,2010-11-10
-6pjk,2020-07-01,2019-06-28
-2pj9,2008-01-22,2007-04-15
-7pjg,2022-09-07,2021-08-24
-5pjq,2017-03-15,2017-02-07
-4pj2,2015-02-11,2014-05-10
-5pj8,2017-03-15,2017-02-07
-5pja,2017-03-15,2017-02-07
-8pja,2024-03-06,2023-06-23
-3pjn,2011-11-02,2010-11-10
-2pjr,1999-04-08,1999-03-12
-3pj8,2011-04-06,2010-11-09
-1pjl,2003-06-17,2003-06-03
-4pjz,2014-09-10,2014-05-13
-3pjk,2011-04-06,2010-11-10
-3pjd,2011-04-20,2010-11-10
-5pjw,2017-03-15,2017-02-07
-1pjx,2004-06-08,2003-06-04
-6pj4,2019-10-02,2019-06-27
-1pj2,2003-11-11,2003-05-30
-4pjs,2014-12-24,2014-05-12
-6pj0,2020-03-04,2019-06-27
-1pjj,2004-06-08,2003-06-03
-4pjm,2015-04-29,2014-05-12
-4pjd,2014-07-02,2014-05-12
-6pjr,2019-10-02,2019-06-28
-3pje,2011-04-20,2010-11-10
-6pjq,2019-11-27,2019-06-28
-6pj2,2020-03-04,2019-06-27
-7pj2,2022-09-07,2021-08-23
-6pja,2019-10-02,2019-06-28
-6pjw,2020-01-22,2019-06-28
-4pjh,2014-07-02,2014-05-12
-5pj6,2017-03-15,2017-02-07
-1pji,2004-08-03,2003-06-03
-6pj8,2019-10-02,2019-06-28
-4pj1,2015-04-29,2014-05-10
-2pjb,2008-01-22,2007-04-15
-7pjc,2022-09-07,2021-08-23
-5pj2,2017-03-15,2017-02-07
-4pjx,2014-07-02,2014-05-12
-2pj0,2008-01-22,2007-04-15
-3pjr,1999-04-08,1999-03-12
-6pjv,2019-11-13,2019-06-28
-7pj4,2022-09-07,2021-08-23
-6pjd,2020-07-01,2019-06-28
-8pjn,2024-01-03,2023-06-23
-5pjf,2017-03-15,2017-02-07
-7pjb,2021-10-20,2021-08-23
-7pjw,2021-10-20,2021-08-24
-6pj3,2020-02-12,2019-06-27
-3pjg,2011-09-28,2010-11-10
-3pj2,2011-01-12,2010-11-08
-2pjo,2007-11-20,2007-04-16
-5pje,2017-03-15,2017-02-07
-1pjt,2003-12-02,2003-06-03
-2pja,2008-01-22,2007-04-15
-1pj0,2004-01-13,2003-05-30
-1pj1,2004-01-13,2003-05-30
-8pjj,2023-11-22,2023-06-23
-4pj6,2014-12-03,2014-05-12
-5pjr,2017-03-15,2017-02-07
-6pjh,2020-07-01,2019-06-28
-2pj2,2008-01-22,2007-04-15
-3pjf,2011-04-20,2010-11-10
-5pjz,2017-03-15,2017-02-07
-4pj0,2014-10-22,2014-05-10
-5pjh,2017-03-15,2017-02-07
-5pj5,2017-03-15,2017-02-07
-2pj6,2008-01-22,2007-04-15
-8pjk,2024-05-29,2023-06-23
-2pj1,2008-01-22,2007-04-15
-5pjk,2017-03-15,2017-02-07
-2pj5,2008-01-22,2007-04-15
-5pjm,2017-03-15,2017-02-07
-5pj0,2017-03-15,2017-02-07
-6pjx,2020-12-09,2019-06-28
-8pj0,2024-02-21,2023-06-22
-5pjl,2017-03-15,2017-02-07
-7pjr,2022-09-07,2021-08-24
-2pj8,2008-01-22,2007-04-15
-4pjb,2014-07-02,2014-05-12
-2pjc,2008-01-22,2007-04-15
-7pjt,2021-10-20,2021-08-24
-7pjz,2021-10-20,2021-08-24
-5pj1,2017-03-15,2017-02-07
-2pjl,2007-06-12,2007-04-16
-7pj9,2021-10-20,2021-08-23
-5pjs,2017-03-15,2017-02-07
-3pjt,2011-02-09,2010-11-10
-1pj7,2003-10-07,2003-06-01
-2pj4,2008-01-22,2007-04-15
-1pj5,2003-10-07,2003-06-01
-7pjn,2022-07-13,2021-08-24
-7pjv,2021-10-20,2021-08-24
-1pjp,1999-03-02,1998-09-07
-4pjg,2014-07-02,2014-05-12
-6pjo,2020-07-01,2019-06-28
-5pjg,2017-03-15,2017-02-07
-5pjd,2017-03-15,2017-02-07
-4pjl,2015-04-29,2014-05-12
-5pjn,2017-03-15,2017-02-07
-5pjj,2017-03-15,2017-02-07
-4pjf,2014-07-09,2014-05-12
-1pj4,2003-09-30,2003-05-31
-2pj3,2008-01-22,2007-04-15
-5pjo,2017-03-15,2017-02-07
-4pji,2014-07-02,2014-05-12
-7pjm,2022-07-13,2021-08-24
-7pja,2021-10-20,2021-08-23
-6pj5,2019-10-02,2019-06-27
-6pjg,2020-07-01,2019-06-28
-3pj3,2011-01-12,2010-11-08
-4pjn,2015-04-29,2014-05-12
-4pj7,2014-07-02,2014-05-12
-7pji,2022-07-06,2021-08-24
-5pji,2017-03-15,2017-02-07
-6pjn,2020-07-01,2019-06-28
-1pj9,2004-02-03,2003-06-02
-7pjx,2021-10-20,2021-08-24
-3pj0,2010-11-24,2010-11-08
-8pji,2023-11-22,2023-06-23
-6pjc,2020-07-01,2019-06-28
-6pj9,2019-10-02,2019-06-28
-7pj3,2022-09-07,2021-08-23
-6pjp,2019-10-02,2019-06-28
-7pj8,2021-10-20,2021-08-23
-7pjy,2021-10-20,2021-08-24
-4pjr,2014-12-24,2014-05-12
-7pj5,2022-09-07,2021-08-23
-4pj8,2014-07-02,2014-05-12
-2pj7,2008-01-22,2007-04-15
-6pje,2020-07-01,2019-06-28
-1pjk,2003-06-24,2003-06-03
-4pjv,2014-09-24,2014-05-12
-7pjd,2021-12-22,2021-08-23
-1pja,2003-09-02,2003-06-02
-5pjy,2017-03-15,2017-02-07
-2pjt,2008-04-22,2007-04-16
-5pjb,2017-03-15,2017-02-07
-1pjc,1999-07-15,1998-06-05
-4pjc,2014-07-02,2014-05-12
-1pjq,2003-12-02,2003-06-03
-8pjp,2024-04-03,2023-06-23
-4pje,2014-07-02,2014-05-12
-4pjo,2014-12-31,2014-05-12
-2pjs,2007-05-15,2007-04-16
-7pje,2021-09-22,2021-08-24
-7pjs,2021-10-20,2021-08-24
-5pj4,2017-03-15,2017-02-07
-8pj7,2023-11-22,2023-06-22
-3pju,2011-02-09,2010-11-10
-4pj5,2014-07-02,2014-05-12
-5pjx,2017-03-15,2017-02-07
-6pjf,2020-07-01,2019-06-28
-5pj9,2017-03-15,2017-02-07
-6pjl,2020-07-01,2019-06-28
-1pj6,2003-10-07,2003-06-01
-2pjp,2007-10-30,2007-04-16
-6pju,2019-11-27,2019-06-28
-3pj1,2011-01-12,2010-11-08
-6pjb,2020-07-01,2019-06-28
-3pjj,2012-01-18,2010-11-10
-5pj3,2017-03-15,2017-02-07
-3pjc,2010-12-29,2010-11-09
-6pj7,2019-10-02,2019-06-28
-7pj6,2022-09-07,2021-08-23
-8pjb,2023-11-01,2023-06-23
-7pjk,2022-03-16,2021-08-24
-4pjy,2016-02-17,2014-05-12
-4pjt,2014-09-24,2014-05-12
-6pj6,2020-01-22,2019-06-27
-7pj7,2021-10-20,2021-08-23
-6pji,2020-07-01,2019-06-28
-5pjv,2017-03-15,2017-02-07
-3pjq,2011-06-08,2010-11-10
-8pj8,2024-03-06,2023-06-23
-4pja,2014-07-02,2014-05-12
-1pjs,2003-12-02,2003-06-03
-5pjt,2017-03-15,2017-02-07
-1pj3,2003-11-11,2003-05-30
-6i66,2019-07-03,2018-11-15
-6i68,2019-05-08,2018-11-15
-8i68,2023-07-12,2023-01-27
-1i6d,2001-10-17,2001-03-02
-2i65,2006-09-05,2006-08-28
-5i6l,2016-07-13,2016-02-16
-2i6b,2007-01-02,2006-08-28
-2i66,2006-09-05,2006-08-28
-3i6b,2009-09-01,2009-07-06
-2i6u,2007-06-26,2006-08-29
-1i6v,2001-04-18,2001-03-05
-2i6k,2007-06-05,2006-08-29
-5i6n,2016-07-13,2016-02-16
-1i6p,2001-05-09,2001-03-02
-6i6x,2018-12-05,2018-11-15
-6i6f,2019-07-10,2018-11-15
-8i62,2023-07-12,2023-01-27
-8i66,2023-07-12,2023-01-27
-4i62,2012-12-12,2012-11-29
-6i6z,2018-12-12,2018-11-15
-6i65,2019-07-03,2018-11-15
-5i6y,2016-02-24,2016-02-16
-3i6m,2010-01-12,2009-07-07
-6i6r,2018-12-05,2018-11-15
-4i6v,2013-02-06,2012-11-30
-8i6r,2023-06-07,2023-01-29
-6i6h,2019-02-27,2018-11-15
-5i68,2016-08-03,2016-02-16
-3i6d,2009-12-08,2009-07-06
-8i69,2023-07-12,2023-01-27
-6i63,2019-07-03,2018-11-15
-5i6u,2017-02-22,2016-02-16
-1i6n,2002-03-13,2001-03-02
-6i64,2019-07-03,2018-11-15
-1i6x,2003-06-17,2001-03-06
-3i6c,2010-04-21,2009-07-06
-5i6c,2016-04-27,2016-02-16
-8i64,2023-07-12,2023-01-27
-8i6d,2023-07-12,2023-01-27
-1i6o,2001-05-09,2001-03-02
-6i6m,2019-03-27,2018-11-15
-6i6s,2019-11-27,2018-11-15
-4i6f,2013-11-20,2012-11-29
-6i6c,2019-07-10,2018-11-15
-5i6a,2016-03-09,2016-02-16
-3i69,2009-09-01,2009-07-06
-3i6e,2009-07-14,2009-07-07
-5i6s,2017-03-01,2016-02-16
-8i6y,2024-02-07,2023-01-30
-4i68,2013-04-24,2012-11-29
-4i67,2013-04-24,2012-11-29
-5i60,2016-03-23,2016-02-15
-6i6g,2019-11-20,2018-11-15
-5i6k,2016-07-13,2016-02-16
-3i65,2009-07-28,2009-07-06
-1i6q,2001-11-07,2001-03-03
-8i6a,2023-07-12,2023-01-27
-2i6h,2006-09-26,2006-08-28
-6i67,2019-07-03,2018-11-15
-5i6w,2016-02-24,2016-02-16
-8i65,2023-07-12,2023-01-27
-6i6v,2019-07-10,2018-11-15
-8i6n,2024-02-14,2023-01-29
-4i6n,2013-05-29,2012-11-29
-5i6p,2016-07-13,2016-02-16
-1i6k,2001-11-07,2001-03-02
-5i6m,2016-07-13,2016-02-16
-3i62,2009-09-08,2009-07-06
-6i6l,2019-03-27,2018-11-15
-3i60,2010-01-12,2009-07-06
-4i6s,2013-07-31,2012-11-30
-1i6m,2001-11-07,2001-03-02
-8i6m,2024-01-31,2023-01-28
-1i6j,2001-09-07,2001-03-02
-3i61,2009-09-08,2009-07-06
-4i6g,2013-03-13,2012-11-29
-5i6z,2016-04-13,2016-02-16
-2i69,2006-11-21,2006-08-28
-2i67,2006-09-05,2006-08-28
-2i6p,2007-03-13,2006-08-29
-2i6s,2006-10-17,2006-08-29
-3i6a,2009-09-01,2009-07-06
-4i6b,2013-11-20,2012-11-29
-2i6o,2007-03-13,2006-08-29
-2i6q,2006-10-17,2006-08-29
-3i6t,2009-07-21,2009-07-07
-3i6l,2010-07-14,2009-07-07
-1i6h,2001-04-23,2001-03-02
-3i6g,2010-06-16,2009-07-07
-3i6r,2009-07-28,2009-07-07
-8i6j,2024-01-31,2023-01-28
-8i60,2023-07-26,2023-01-26
-2i62,2006-09-12,2006-08-27
-6i6p,2019-07-10,2018-11-15
-4i6y,2013-07-17,2012-11-30
-3i6o,2009-09-29,2009-07-07
-4i6h,2013-08-14,2012-11-29
-3i64,2009-09-01,2009-07-06
-3i6v,2009-07-21,2009-07-07
-1i6e,2001-10-17,2001-03-02
-4i60,2013-08-14,2012-11-29
-4i6q,2013-10-16,2012-11-30
-3i6i,2010-02-23,2009-07-07
-5i69,2016-03-23,2016-02-16
-5i67,2016-04-06,2016-02-16
-8i6c,2023-07-12,2023-01-27
-2i60,2006-10-10,2006-08-26
-8i6v,2023-03-01,2023-01-29
-5i6d,2016-08-17,2016-02-16
-8i67,2023-07-12,2023-01-27
-2i61,2006-12-26,2006-08-27
-3i63,2009-10-13,2009-07-06
-3i6q,2010-02-23,2009-07-07
-1i6t,2001-12-05,2001-03-05
-3i6z,2010-01-12,2009-07-07
-6i6n,2019-03-27,2018-11-15
-5i6o,2016-07-13,2016-02-16
-6i6t,2019-07-10,2018-11-15
-8i6l,2023-03-01,2023-01-28
-1i6l,2001-11-07,2001-03-02
-6i62,2019-07-03,2018-11-15
-3i6s,2010-01-19,2009-07-07
-8i63,2023-07-12,2023-01-27
-8i6b,2023-07-12,2023-01-27
-3i6n,2009-10-13,2009-07-07
-8i6s,2023-06-07,2023-01-29
-6i6k,2019-03-27,2018-11-15
-3i68,2009-07-28,2009-07-06
-1i6i,2001-05-30,2001-03-02
-1i6w,2001-05-23,2001-03-05
-5i63,2017-06-28,2016-02-15
-6i61,2019-07-03,2018-11-15
-5i6x,2016-04-13,2016-02-16
-8i61,2023-07-12,2023-01-27
-4i6w,2013-07-17,2012-11-30
-4i6u,2013-11-13,2012-11-30
-2i6a,2007-01-02,2006-08-28
-2hby,2006-06-27,2006-06-14
-8hb9,2023-05-24,2022-10-27
-4hb0,2013-01-09,2012-09-27
-3hb8,2010-05-26,2009-05-04
-3hb6,2009-05-12,2009-05-04
-5hbt,2017-05-03,2016-01-02
-1hbz,2001-05-24,2001-04-24
-6hbe,2019-01-23,2018-08-10
-8hbh,2023-04-19,2022-10-28
-3hbd,2009-08-11,2009-05-04
-6hbw,1998-09-16,1998-09-10
-6hbv,2019-08-28,2018-08-13
-6hbg,2019-03-20,2018-08-10
-2hbh,2007-05-01,2006-06-14
-2hb7,2006-08-29,2006-06-14
-2hb4,2007-06-26,2006-06-13
-2hbd,1995-02-07,1994-08-31
-8hbl,2023-07-12,2022-10-29
-2hbe,1995-02-07,1994-08-31
-5hbe,2016-02-03,2015-12-31
-8hbm,2023-06-14,2022-10-29
-4hbx,2012-10-31,2012-09-28
-2hbc,1995-02-07,1994-08-31
-8hbt,2023-09-13,2022-10-31
-2hbb,2007-05-29,2006-06-14
-5hbh,2016-02-03,2015-12-31
-4hbn,2013-01-16,2012-09-28
-2hb8,2006-08-29,2006-06-14
-1hbh,1995-04-20,1995-02-22
-6hbn,2019-03-27,2018-08-10
-8hbd,2023-03-22,2022-10-28
-5hbc,2016-01-20,2015-12-31
-2hb5,2006-08-29,2006-06-13
-1hba,1994-01-31,1992-01-07
-8hbk,2023-10-11,2022-10-29
-2hbs,1997-07-23,1997-05-06
-2hbq,2006-06-27,2006-06-14
-8hbe,2023-04-19,2022-10-28
-5hbi,1998-11-11,1998-06-24
-2hbt,2006-06-27,2006-06-14
-3hbj,2009-09-01,2009-05-04
-1hbo,2001-08-16,2001-04-20
-6hbz,2019-08-28,2018-08-13
-4hbf,2012-10-31,2012-09-27
-4hb9,2012-10-17,2012-09-27
-2hbr,2006-06-27,2006-06-14
-4hbh,2013-01-23,2012-09-28
-3hbg,2010-04-14,2009-05-04
-5hbs,2016-03-02,2016-01-02
-1hbg,1992-07-15,1991-02-11
-2hb1,2006-08-29,2006-06-13
-3hbo,2010-05-26,2009-05-04
-7hbi,1998-11-11,1998-06-25
-2hb6,2006-08-08,2006-06-13
-3hbv,2009-06-30,2009-05-05
-4hb3,2013-01-09,2012-09-27
-3hbl,2009-06-30,2009-05-04
-1hb2,2001-11-23,2001-04-11
-4hbp,2013-02-06,2012-09-28
-5hbv,2017-05-03,2016-01-02
-6hbm,2019-05-01,2018-08-10
-1hbu,2001-08-16,2001-04-20
-3hbq,2010-04-14,2009-05-04
-2hbv,2006-09-19,2006-06-14
-1hbv,1995-07-10,1995-03-29
-6hb7,2019-04-17,2018-08-09
-5hbb,2016-07-20,2015-12-31
-5hbj,2016-02-03,2015-12-31
-1hbj,2001-09-25,2001-04-16
-4hb6,2012-10-31,2012-09-27
-3hb1,2009-12-01,2009-05-03
-8hbw,2023-06-21,2022-10-31
-5hbu,2016-04-13,2016-01-02
-4hb8,2012-10-31,2012-09-27
-1hbi,1994-10-15,1994-06-22
-5hbn,2016-10-12,2016-01-01
-8hb2,2024-02-07,2022-10-27
-4hb2,2013-01-09,2012-09-27
-4hbj,2013-01-23,2012-09-28
-3hb4,2009-12-15,2009-05-04
-6hbd,2019-05-01,2018-08-10
-1hb0,2001-08-02,2001-04-10
-3hbu,2009-07-21,2009-05-05
-4hby,2012-10-31,2012-09-28
-2hbf,1995-02-07,1994-08-31
-1hbr,1999-03-26,1998-12-06
-1hbm,2001-08-16,2001-04-20
-2hbx,2006-09-19,2006-06-14
-1hbn,2001-08-16,2001-04-20
-6hbi,1998-11-11,1998-06-25
-4hb4,2013-01-09,2012-09-27
-1hbk,2001-05-15,2001-04-16
-2hbu,2006-06-27,2006-06-14
-2hbl,2006-07-25,2006-06-14
-6hb5,2019-04-17,2018-08-09
-2hbg,1992-07-15,1991-02-11
-2hbk,2006-07-25,2006-06-14
-5hbr,2016-01-27,2016-01-02
-2hb9,2007-05-29,2006-06-14
-3hbn,2009-05-26,2009-05-04
-1hbp,1994-01-31,1993-02-05
-2hbm,2006-07-25,2006-06-14
-4hbw,2012-10-31,2012-09-28
-2hbz,2006-06-27,2006-06-14
-6hb0,2019-05-01,2018-08-09
-6hb6,2019-04-17,2018-08-09
-3hbp,2010-04-14,2009-05-04
-4hbv,2012-10-31,2012-09-28
-5hbm,2016-02-24,2015-12-31
-6hbu,2018-11-07,2018-08-13
-4hbg,2013-10-30,2012-09-27
-1hbt,1995-07-10,1995-04-06
-4hba,2013-07-31,2012-09-27
-3hbt,2010-05-05,2009-05-05
-3hb5,2009-12-15,2009-05-04
-4hbq,2013-01-23,2012-09-28
-3hb3,2009-06-23,2009-05-04
-8hb0,2023-11-01,2022-10-27
-3hbf,2009-09-01,2009-05-04
-3hbz,2009-05-26,2009-05-05
-8hb5,2023-08-09,2022-10-27
-2hba,2007-05-29,2006-06-14
-1hb3,2001-11-23,2001-04-11
-5hbq,2016-08-10,2016-01-02
-4hbm,2012-10-17,2012-09-28
-1hb4,2001-11-23,2001-04-11
-2hb3,2006-08-29,2006-06-13
-3hb2,2009-08-04,2009-05-04
-8hbb,2024-02-07,2022-10-27
-4hbu,2013-04-10,2012-09-28
-3hbb,2009-05-19,2009-05-04
-1hb1,2001-11-23,2001-04-11
-3hbe,2009-08-11,2009-05-04
-5hb4,2016-04-20,2015-12-31
-1hbs,1982-07-29,1982-06-02
-3hb7,2009-07-07,2009-05-04
-6hbs,2019-08-28,2018-08-13
-1hbb,1994-01-31,1992-01-07
-1hb6,2002-03-11,2001-04-12
-4hbi,1998-11-11,1998-06-24
-3hb9,2009-06-30,2009-05-04
-3hb0,2009-12-01,2009-05-03
-8hbf,2023-04-19,2022-10-28
-8cz9,2023-05-31,2022-05-24
-5czc,2016-02-03,2015-07-31
-3czt,2009-04-14,2008-04-30
-6czh,2018-09-19,2018-04-09
-2cz1,2006-01-09,2005-07-09
-3czl,2008-07-15,2008-04-29
-4czh,2014-06-11,2014-04-19
-4czk,2014-06-11,2014-04-19
-6cze,2018-11-21,2018-04-09
-1czf,1999-10-28,1999-09-02
-7czr,2021-03-10,2020-09-09
-2czs,2005-10-18,2005-07-15
-5cz7,2016-03-23,2015-07-31
-6czz,2018-05-23,2018-04-09
-7czq,2021-03-10,2020-09-09
-8cz4,2023-08-30,2022-05-24
-1czq,1999-10-13,1999-09-06
-7czv,2021-03-10,2020-09-09
-8czt,2022-06-22,2022-05-25
-1cz7,1999-11-05,1999-09-01
-6czm,2018-08-15,2018-04-09
-6czk,2018-08-08,2018-04-09
-1czn,1999-12-29,1999-09-03
-6cz7,2018-08-15,2018-04-08
-3czs,2008-06-24,2008-04-29
-1czs,1999-11-26,1999-09-07
-4czr,2014-12-10,2014-04-21
-8czw,2022-06-22,2022-05-25
-8czn,2022-12-07,2022-05-25
-4czl,2014-06-25,2014-04-19
-6czy,2018-05-23,2018-04-09
-6cz4,2018-06-20,2018-04-07
-6cza,2018-08-15,2018-04-08
-3czr,2008-06-17,2008-04-29
-4czw,2014-06-04,2014-04-22
-4czs,2015-04-22,2014-04-22
-1czz,2000-03-08,1999-09-07
-5czi,2015-09-30,2015-07-31
-3czk,2008-07-15,2008-04-29
-5czw,2016-08-03,2015-08-01
-3cz7,2008-09-09,2008-04-28
-7czh,2021-04-07,2020-09-08
-5czz,2015-09-02,2015-08-01
-4cza,2014-12-17,2014-04-16
-8czv,2022-06-22,2022-05-25
-3czf,2009-04-07,2008-04-29
-7czl,2021-01-20,2020-09-09
-6czi,2018-09-19,2018-04-09
-5czd,2016-02-03,2015-07-31
-6cz1,2019-04-10,2018-04-07
-6cz3,2018-06-20,2018-04-07
-1cze,2000-02-28,1999-09-02
-6czb,2018-11-21,2018-04-09
-5czo,2016-08-03,2015-07-31
-7cz5,2020-11-18,2020-09-07
-1czc,2000-02-28,1999-09-02
-5cz4,2016-03-23,2015-07-31
-7cz3,2021-01-13,2020-09-07
-3czh,2008-08-05,2008-04-29
-4cz0,2014-06-11,2014-04-16
-3cz4,2008-11-11,2008-04-28
-6cz5,2018-08-08,2018-04-08
-1czm,1994-04-30,1993-11-28
-1czu,1999-12-29,1999-09-07
-7cze,2020-10-21,2020-09-08
-8czm,2022-12-07,2022-05-25
-6czw,2018-10-31,2018-04-09
-1czr,1999-12-29,1999-09-07
-8czk,2023-01-25,2022-05-24
-2czc,2006-01-13,2005-07-13
-7czm,2021-03-31,2020-09-09
-7czp,2021-03-10,2020-09-09
-2czf,2006-01-13,2005-07-13
-7czu,2021-03-10,2020-09-09
-4czf,2014-06-11,2014-04-19
-5cz5,2016-03-23,2015-07-31
-4czb,2014-12-10,2014-04-16
-1czk,2000-12-29,1999-09-03
-7cza,2020-09-16,2020-09-07
-5czp,2016-10-12,2015-07-31
-5czb,2016-06-15,2015-07-31
-4czn,2014-12-10,2014-04-21
-2cz0,2006-01-09,2005-07-09
-4czp,2014-12-10,2014-04-21
-1czl,1999-12-29,1999-09-03
-4czj,2014-06-11,2014-04-19
-7czt,2021-03-10,2020-09-09
-6czc,2018-11-21,2018-04-09
-3czm,2009-06-02,2008-04-29
-1czh,1999-12-29,1999-09-03
-5czx,2016-06-01,2015-08-01
-4czc,2014-07-30,2014-04-17
-3czd,2008-07-01,2008-04-29
-5cz0,2016-08-10,2015-07-31
-4czo,2014-12-10,2014-04-21
-6cz6,2019-04-17,2018-04-08
-6czn,2019-03-20,2018-04-09
-6cz9,2018-08-15,2018-04-08
-2cz8,2006-09-19,2005-07-11
-5czr,2016-11-02,2015-08-01
-4czq,2014-12-10,2014-04-21
-5cz2,2016-02-17,2015-07-31
-1cz0,1999-11-19,1999-08-31
-3czj,2009-04-07,2008-04-29
-2czr,2006-02-14,2005-07-15
-7czs,2021-03-10,2020-09-09
-6czr,2019-04-10,2018-04-09
-5cza,2016-03-23,2015-07-31
-5cz9,2016-03-23,2015-07-31
-8czz,2023-05-31,2022-05-25
-6czp,2018-04-25,2018-04-09
-5czm,2016-08-10,2015-07-31
-5czy,2015-09-23,2015-08-01
-5czv,2016-06-01,2015-08-01
-3czg,2008-07-15,2008-04-29
-8czx,2022-06-22,2022-05-25
-6czd,2018-10-24,2018-04-09
-7cz4,2020-11-11,2020-09-07
-6czv,2018-09-26,2018-04-09
-4cz9,2014-12-17,2014-04-16
-5czg,2015-08-12,2015-07-31
-8czu,2022-06-22,2022-05-25
-8czl,2023-01-25,2022-05-24
-5czs,2016-08-10,2015-08-01
-4czg,2014-06-11,2014-04-19
-5cz6,2016-03-23,2015-07-31
-7cz2,2021-12-08,2020-09-07
-7czw,2021-03-10,2020-09-09
-8cz7,2023-08-30,2022-05-24
-6czs,2018-08-08,2018-04-09
-3czv,2008-07-29,2008-04-30
-6czq,2018-08-01,2018-04-09
-8cza,2022-08-03,2022-05-24
-8czp,2023-12-13,2022-05-25
-3czn,2008-06-24,2008-04-29
-6czf,2018-10-10,2018-04-09
-7czx,2021-03-10,2020-09-09
-8cz5,2022-10-19,2022-05-24
-4czz,2014-06-11,2014-04-23
-1czj,1996-07-11,1996-01-12
-4cz1,2014-04-30,2014-04-16
-5czh,2015-09-30,2015-07-31
-5czu,2015-11-18,2015-08-01
-6czo,2019-01-23,2018-04-09
-5czt,2016-08-10,2015-08-01
-2cze,2006-01-13,2005-07-13
-2czl,2006-01-13,2005-07-13
-4czm,2014-08-13,2014-04-19
-4czy,2014-06-04,2014-04-22
-7czi,2021-09-08,2020-09-08
-5czn,2016-03-16,2015-07-31
-4cz2,2014-06-04,2014-04-16
-1cza,2000-03-06,1999-09-01
-7czf,2020-10-21,2020-09-08
-2cz7,2006-01-11,2005-07-11
-3czy,2008-09-30,2008-04-30
-3czx,2008-07-01,2008-04-30
-3cz1,2009-04-28,2008-04-27
-2cz6,2006-01-11,2005-07-11
-5cz8,2016-03-23,2015-07-31
-1cz2,2000-09-27,1999-09-01
-1czy,2000-03-08,1999-09-07
-7czy,2021-03-10,2020-09-09
-3cz0,2009-04-28,2008-04-27
-6cz8,2018-08-15,2018-04-08
-1czi,1997-04-01,1997-01-15
-1czo,1999-12-29,1999-09-03
-7czz,2021-03-10,2020-09-09
-6czu,2018-09-26,2018-04-09
-2cz2,2006-01-10,2005-07-10
-3czu,2008-08-12,2008-04-30
-2czi,2006-07-25,2005-07-13
-5czk,2015-10-14,2015-07-31
-6l5v,2020-02-19,2019-10-24
-7l5p,2022-06-29,2020-12-22
-4l54,2013-11-27,2013-06-10
-5l5z,2016-11-09,2016-05-28
-5l5p,2016-11-09,2016-05-28
-6l5t,2020-04-08,2019-10-24
-5l5i,2016-11-09,2016-05-28
-4l52,2013-07-03,2013-06-10
-6l5n,2020-06-17,2019-10-24
-6l57,2020-04-29,2019-10-22
-3l5k,2010-03-09,2009-12-22
-4l5z,2014-03-05,2013-06-11
-3l5c,2010-02-16,2009-12-21
-5l5r,2016-11-09,2016-05-28
-1l5r,2002-12-04,2002-03-07
-3l5m,2010-03-23,2009-12-22
-4l5w,2014-04-30,2013-06-11
-6l5x,2020-02-19,2019-10-24
-5l5b,2016-11-09,2016-05-28
-4l56,2014-12-24,2013-06-10
-7l57,2021-04-14,2020-12-21
-3l54,2010-06-30,2009-12-21
-7l5i,2021-04-21,2020-12-22
-4l5l,2013-09-04,2013-06-11
-1l5s,2002-12-04,2002-03-07
-7l5o,2022-06-29,2020-12-22
-5l55,2016-11-09,2016-05-27
-5l5s,2016-11-09,2016-05-28
-5l5y,2016-11-09,2016-05-28
-5l5a,2016-11-09,2016-05-28
-6l5p,2020-02-19,2019-10-24
-4l53,2013-07-03,2013-06-10
-7l59,2021-12-29,2020-12-21
-1l5v,2002-04-10,2002-03-08
-3l5u,2010-03-09,2009-12-22
-1l5g,2002-04-17,2002-03-06
-5l5d,2016-11-09,2016-05-28
-3l5h,2010-05-19,2009-12-21
-1l5h,2002-04-17,2002-03-06
-7l5m,2021-10-27,2020-12-22
-3l5t,2010-03-09,2009-12-22
-6l5m,2020-06-17,2019-10-24
-1l5q,2002-12-04,2002-03-07
-4l5u,2014-04-30,2013-06-11
-7l5d,2020-12-30,2020-12-21
-7l5c,2022-01-19,2020-12-21
-4l5j,2013-11-06,2013-06-11
-6l5q,2020-02-19,2019-10-24
-1l5f,2002-09-07,2002-03-06
-5l58,2016-12-14,2016-05-28
-5l5q,2016-11-09,2016-05-28
-4l57,2014-02-12,2013-06-10
-6l50,2020-07-15,2019-10-21
-1l5k,2002-09-07,2002-03-07
-4l59,2013-07-10,2013-06-10
-4l5s,2013-08-14,2013-06-11
-5l5h,2016-11-09,2016-05-28
-6l5z,2020-10-28,2019-10-25
-5l5v,2016-11-09,2016-05-28
-3l57,2010-05-19,2009-12-21
-4l5c,2014-06-11,2013-06-10
-1l5l,2002-09-07,2002-03-07
-5l5t,2016-11-09,2016-05-28
-4l5r,2013-07-31,2013-06-11
-1l5m,2002-09-07,2002-03-07
-1l5b,2002-05-22,2002-03-06
-4l5b,2013-09-18,2013-06-10
-6l5o,2020-06-17,2019-10-24
-3l5e,2010-02-16,2009-12-21
-5l57,2016-12-14,2016-05-28
-2l5d,2011-04-20,2010-10-29
-7l5h,2021-12-29,2020-12-22
-1l5o,2002-09-07,2002-03-07
-6l5l,2020-06-17,2019-10-24
-5l59,2016-07-06,2016-05-28
-6l5g,2019-11-06,2019-10-23
-4l58,2013-06-26,2013-06-10
-4l55,2014-01-29,2013-06-10
-6l5r,2020-02-19,2019-10-24
-7l5e,2021-01-27,2020-12-21
-5l5e,2016-11-09,2016-05-28
-6l59,2020-04-29,2019-10-22
-5l5w,2016-11-09,2016-05-28
-2l5e,2011-05-18,2010-10-31
-7l5a,2021-12-29,2020-12-21
-4l50,2013-11-06,2013-06-10
-3l5r,2010-03-09,2009-12-22
-3l5f,2010-02-16,2009-12-21
-6l56,2019-11-13,2019-10-22
-2l5y,2011-01-19,2010-11-09
-4l5a,2014-06-11,2013-06-10
-7l56,2021-04-14,2020-12-21
-6l5s,2020-02-19,2019-10-24
-3l5b,2010-02-16,2009-12-21
-7l5t,2021-12-29,2020-12-22
-3l58,2010-02-16,2009-12-21
-4l5v,2014-04-30,2013-06-11
-6l5y,2020-02-19,2019-10-24
-6l54,2020-04-15,2019-10-22
-7l5s,2021-04-21,2020-12-22
-1l5y,2002-10-23,2002-03-08
-3l5s,2010-03-09,2009-12-22
-6l55,2019-11-06,2019-10-22
-5l5c,2016-07-06,2016-05-28
-2l51,2010-11-03,2010-10-22
-4l51,2013-11-06,2013-06-10
-5l5f,2016-11-09,2016-05-28
-7l5f,2021-07-28,2020-12-22
-3l5d,2010-02-16,2009-12-21
-1l5w,2002-04-10,2002-03-08
-5l54,2016-11-09,2016-05-27
-5l56,2016-07-06,2016-05-28
-4l5o,2013-09-11,2013-06-11
-1l5u,2003-03-25,2002-03-08
-3l59,2010-02-16,2009-12-21
-5l53,2016-08-31,2016-05-27
-5l5x,2016-11-09,2016-05-28
-4l5m,2013-10-30,2013-06-11
-5l5o,2016-11-09,2016-05-28
-3l5n,2010-08-04,2009-12-22
-6l5w,2020-02-19,2019-10-24
-7l50,2021-08-11,2020-12-21
-7l52,2020-12-30,2020-12-21
-3l5l,2010-03-23,2009-12-22
-6l58,2019-11-06,2019-10-22
-7l58,2021-04-14,2020-12-21
-5l5j,2016-11-09,2016-05-28
-2l5u,2011-01-19,2010-11-08
-5l52,2016-11-09,2016-05-27
-3l5p,2010-03-09,2009-12-22
-5l5u,2016-11-09,2016-05-28
-7l5u,2021-02-03,2020-12-22
-3dxy,2009-05-19,2008-07-25
-7dxg,2022-02-02,2021-01-18
-1dxv,1993-10-31,1992-05-06
-2dxu,2007-03-01,2006-08-30
-6dxu,2019-02-27,2018-06-30
-2dxb,2007-08-28,2006-08-25
-7dxb,2022-02-02,2021-01-18
-5dxo,2016-06-15,2015-09-23
-6dx0,2018-09-19,2018-06-28
-6dxg,2018-11-07,2018-06-28
-2dxi,2006-10-31,2006-08-28
-4dxu,2012-03-14,2012-02-28
-5dxe,2016-08-03,2015-09-23
-5dxk,2016-05-04,2015-09-23
-3dx3,2009-07-07,2008-07-23
-5dxq,2016-05-04,2015-09-23
-3dx2,2009-07-07,2008-07-23
-8dx0,2023-03-22,2022-08-02
-7dx0,2021-03-31,2021-01-18
-1dxf,2000-08-25,2000-01-05
-1dxe,2000-08-25,2000-01-03
-4dxj,2013-01-16,2012-02-27
-5dxa,2015-11-25,2015-09-23
-8dx8,2023-05-31,2022-08-02
-4dxt,2012-06-06,2012-02-28
-8dxi,2023-05-31,2022-08-02
-8dxh,2023-05-31,2022-08-02
-5dxt,2016-01-27,2015-09-23
-5dxh,2016-01-27,2015-09-23
-2dx8,2007-05-15,2006-08-24
-8dx2,2023-05-31,2022-08-02
-6dx3,2018-12-19,2018-06-28
-4dxb,2012-08-08,2012-02-27
-1dxq,2000-04-17,2000-01-14
-6dxi,2018-07-11,2018-06-28
-2dxt,2007-03-01,2006-08-30
-1dxr,2001-01-12,2000-01-15
-7dxp,2021-04-14,2021-01-19
-6dxh,2018-07-18,2018-06-28
-5dx6,2016-09-28,2015-09-23
-4dxr,2012-06-06,2012-02-28
-3dxk,2009-07-28,2008-07-24
-2dxr,2006-09-12,2006-08-30
-1dx5,2000-04-10,1999-12-20
-4dxk,2012-04-18,2012-02-27
-3dx4,2009-07-07,2008-07-23
-4dxv,2012-03-14,2012-02-28
-7dx9,2021-03-31,2021-01-18
-1dxi,1994-01-31,1993-09-30
-8dxk,2023-05-31,2022-08-02
-4dx0,2012-05-30,2012-02-27
-2dxn,2007-05-22,2006-08-28
-5dxn,2016-06-15,2015-09-23
-1dxp,2001-01-12,2000-01-13
-5dx0,2015-11-25,2015-09-23
-4dxp,2013-02-27,2012-02-27
-3dx0,2009-07-07,2008-07-23
-3dxj,2008-10-14,2008-07-24
-4dxz,2012-06-20,2012-02-28
-5dxp,2016-05-04,2015-09-23
-1dx8,2000-01-04,1999-12-23
-1dxw,2001-01-12,2000-01-17
-6dxy,2018-09-26,2018-07-01
-4dxs,2012-06-06,2012-02-28
-4dxx,2013-03-27,2012-02-28
-7dx6,2021-03-31,2021-01-18
-2dxv,2007-03-01,2006-08-31
-2dxw,2007-03-01,2006-08-31
-2dxx,2007-03-01,2006-08-31
-2dxp,2007-03-13,2006-08-29
-8dxj,2023-05-31,2022-08-02
-8dxb,2023-05-31,2022-08-02
-5dxg,2016-07-27,2015-09-23
-5dxv,2016-06-08,2015-09-24
-4dx5,2012-05-02,2012-02-27
-7dxd,2022-01-19,2021-01-18
-5dx1,2015-11-25,2015-09-23
-7dxf,2022-02-02,2021-01-18
-5dxm,2016-05-04,2015-09-23
-4dx9,2013-01-09,2012-02-27
-2dxe,2007-02-25,2006-08-25
-6dxw,2018-09-26,2018-07-01
-2dxf,2007-02-25,2006-08-25
-8dxt,2023-01-18,2022-08-03
-8dxu,2023-01-18,2022-08-03
-5dx4,2016-01-13,2015-09-23
-5dxi,2016-06-15,2015-09-23
-3dxt,2009-10-06,2008-07-25
-6dxl,2018-11-07,2018-06-29
-1dxm,2000-07-04,2000-01-10
-4dxw,2012-05-23,2012-02-28
-6dxq,2018-09-26,2018-06-29
-1dxo,2000-04-23,2000-01-12
-1dxd,2000-03-27,2000-01-03
-1dxl,2000-07-20,2000-01-10
-2dxm,2007-12-04,2006-08-28
-5dxy,2016-10-05,2015-09-24
-7dxh,2021-06-30,2021-01-18
-4dxc,2012-08-08,2012-02-27
-8dxs,2022-12-07,2022-08-03
-5dx8,2015-11-25,2015-09-23
-3dxm,2009-07-28,2008-07-24
-7dx4,2021-04-21,2021-01-18
-1dxu,1993-10-31,1992-05-06
-7dxe,2022-02-02,2021-01-18
-3dx1,2009-07-07,2008-07-23
-1dxk,2000-08-25,2000-01-10
-5dx3,2016-07-20,2015-09-23
-4dxg,2012-09-19,2012-02-27
-6dxp,2018-07-25,2018-06-29
-6dxt,2018-08-08,2018-06-29
-3dxg,2009-06-16,2008-07-24
-3dxv,2009-02-17,2008-07-25
-2dxc,2007-08-28,2006-08-25
-3dxs,2009-08-11,2008-07-25
-2dxs,2006-12-26,2006-08-30
-5dxr,2016-05-04,2015-09-23
-7dx8,2021-03-31,2021-01-18
-3dxu,2009-07-28,2008-07-25
-5dxx,2016-10-05,2015-09-24
-5dxj,2015-11-25,2015-09-23
-6dxv,2018-10-10,2018-07-01
-4dxa,2012-05-16,2012-02-27
-5dxb,2016-07-27,2015-09-23
-4dx7,2012-05-02,2012-02-27
-3dxp,2008-08-12,2008-07-24
-6dxs,2018-09-26,2018-06-29
-5dxu,2016-01-27,2015-09-23
-5dx7,2016-10-05,2015-09-23
-4dxd,2012-05-23,2012-02-27
-4dxy,2012-08-15,2012-02-28
-8dxl,2023-05-31,2022-08-02
-7dx3,2021-03-31,2021-01-18
-3dxh,2009-06-16,2008-07-24
-5dx9,2016-06-15,2015-09-23
-5dx5,2016-01-13,2015-09-23
-1dxy,1997-06-16,1996-08-13
-3dxz,2009-05-19,2008-07-25
-1dxc,2000-04-02,2000-01-03
-6dxk,2018-10-03,2018-06-29
-1dxg,1997-11-12,1997-07-04
-4dx2,2012-07-18,2012-02-27
-1dxt,1993-10-31,1992-05-06
-3dx5,2008-09-02,2008-07-23
-4dxi,2013-02-27,2012-02-27
-3dxw,2009-07-28,2008-07-25
-4dxh,2012-04-11,2012-02-27
-8dxg,2023-05-31,2022-08-02
-5dxd,2015-11-04,2015-09-23
-7dx2,2021-03-31,2021-01-18
-7dxl,2021-10-13,2021-01-19
-8dx3,2023-05-31,2022-08-02
-8dxm,2023-05-31,2022-08-02
-8dxe,2023-05-31,2022-08-02
-7dx7,2021-03-31,2021-01-18
-2dxl,2007-05-22,2006-08-28
-7dx1,2021-03-31,2021-01-18
-7dxi,2022-02-02,2021-01-19
-2dxd,2007-02-25,2006-08-25
-7dxa,2021-06-30,2021-01-18
-7dxq,2022-04-27,2021-01-20
-1dx6,2000-01-02,1999-12-21
-7dx5,2021-03-31,2021-01-18
-6dxz,2018-09-26,2018-07-01
-7dxc,2022-02-02,2021-01-18
-2dxy,2006-09-19,2006-09-03
-4dxl,2012-03-07,2012-02-27
-6dxx,2018-09-26,2018-07-01
-6khi,2020-02-12,2019-07-15
-7khx,2021-03-03,2020-10-22
-6kh0,2020-01-29,2019-07-12
-7kh7,2021-07-14,2020-10-20
-3khu,2009-11-17,2009-10-30
-5khd,2016-06-29,2016-06-14
-4kh9,2013-07-03,2013-04-30
-4khq,2013-10-09,2013-05-01
-7khe,2020-12-09,2020-10-21
-7khv,2020-12-02,2020-10-22
-6khz,2020-01-22,2019-07-16
-1kho,2002-06-19,2001-11-30
-8khq,2023-12-06,2023-08-22
-4khr,2013-05-29,2013-05-01
-5khk,2016-09-14,2016-06-14
-3khl,2010-02-16,2009-10-30
-1khh,2001-12-12,2001-11-30
-2kh9,2010-03-09,2009-03-27
-3khe,2010-01-19,2009-10-30
-7khu,2021-08-18,2020-10-22
-6khy,2020-06-03,2019-07-16
-8kht,2024-04-17,2023-08-22
-1kh3,2003-04-22,2001-11-29
-5kh7,2016-07-27,2016-06-14
-1khf,2002-02-27,2001-11-29
-4khu,2013-10-09,2013-05-01
-7kho,2021-02-10,2020-10-21
-7khj,2021-07-07,2020-10-21
-7khl,2021-02-24,2020-10-21
-5kh4,2016-07-20,2016-06-14
-1khv,2002-01-16,2001-12-01
-5khg,2016-09-14,2016-06-14
-6kho,2020-07-15,2019-07-16
-3kh1,2009-11-24,2009-10-29
-1kh2,2002-04-03,2001-11-29
-5khw,2016-11-09,2016-06-16
-7kh3,2021-12-01,2020-10-19
-1khq,2003-09-09,2001-11-30
-8khc,2024-04-17,2023-08-21
-5kh3,2016-07-27,2016-06-14
-8kho,2024-01-24,2023-08-22
-7kh6,2021-10-27,2020-10-20
-3khh,2010-02-16,2009-10-30
-1kh5,2002-03-13,2001-11-29
-3khj,2010-02-02,2009-10-30
-7khb,2020-10-28,2020-10-20
-8khf,2024-05-01,2023-08-21
-1khw,2002-01-16,2001-12-01
-1khn,2002-03-13,2001-11-30
-4kho,2013-05-29,2013-04-30
-3khg,2010-02-16,2009-10-30
-3khr,2010-02-16,2009-10-30
-1khz,2002-10-09,2001-12-01
-4kh7,2013-06-19,2013-04-30
-5kho,2016-10-19,2016-06-15
-7khz,2021-02-10,2020-10-22
-5kh5,2016-07-20,2016-06-14
-1kht,2003-06-03,2001-11-30
-6kh3,2020-01-29,2019-07-12
-4kh1,2013-11-27,2013-04-29
-7khm,2022-02-02,2020-10-21
-5khy,2016-09-14,2016-06-16
-6khd,2019-10-02,2019-07-15
-1khl,2002-03-13,2001-11-30
-4khs,2013-10-09,2013-05-01
-5khx,2016-11-09,2016-06-16
-1kh9,2002-03-13,2001-11-29
-8khn,2024-01-24,2023-08-22
-7khk,2021-07-07,2020-10-21
-1kh8,2003-06-17,2001-11-29
-7khn,2021-02-03,2020-10-21
-7khc,2020-10-28,2020-10-20
-8kh5,2023-10-18,2023-08-21
-8kh2,2024-04-03,2023-08-21
-6khl,2020-07-22,2019-07-16
-7kh9,2021-02-10,2020-10-20
-5khh,2016-09-14,2016-06-14
-6khf,2019-10-02,2019-07-15
-1khr,2002-02-20,2001-11-30
-5khm,2016-09-21,2016-06-15
-4khn,2013-10-09,2013-04-30
-8khu,2023-10-25,2023-08-22
-3kh4,2010-08-11,2009-10-30
-3kh5,2010-04-21,2009-10-30
-6khp,2020-07-15,2019-07-16
-5khi,2016-09-14,2016-06-14
-7khq,2021-02-10,2020-10-21
-7kh4,2021-10-27,2020-10-19
-3khv,2009-12-01,2009-10-30
-3khc,2010-01-12,2009-10-30
-4khy,2013-10-09,2013-05-01
-6kh4,2020-01-29,2019-07-12
-3kh3,2010-08-11,2009-10-30
-8khl,2024-05-15,2023-08-22
-7khi,2020-10-28,2020-10-21
-1khk,2002-03-13,2001-11-30
-6kh5,2020-01-29,2019-07-12
-7khg,2021-07-07,2020-10-21
-3khb,2010-01-12,2009-10-30
-1khj,2002-03-13,2001-11-30
-7kh2,2020-12-16,2020-10-19
-6khj,2020-02-12,2019-07-15
-1khe,2002-02-27,2001-11-29
-7khr,2021-03-17,2020-10-21
-6khh,2020-07-15,2019-07-15
-4kh2,2013-09-18,2013-04-29
-5khp,2017-04-26,2016-06-15
-3khq,2010-08-25,2009-10-30
-1khb,2002-02-27,2001-11-29
-6khe,2019-10-02,2019-07-15
-4kh0,2013-11-27,2013-04-29
-4khm,2013-05-15,2013-04-30
-4kh4,2013-11-06,2013-04-30
-5khj,2016-09-14,2016-06-14
-7kh5,2021-04-28,2020-10-20
-3khm,2009-11-10,2009-10-30
-8khd,2024-04-17,2023-08-21
-4khp,2013-06-05,2013-05-01
-7khy,2021-02-10,2020-10-22
-1khg,2002-02-27,2001-11-29
-5kha,2016-07-27,2016-06-14
-5kh6,2016-09-21,2016-06-14
-6khs,2020-07-15,2019-07-16
-4khz,2013-10-23,2013-05-01
-1kh7,2002-03-27,2001-11-29
-6khm,2020-07-22,2019-07-16
-2khh,2009-05-12,2009-04-06
-1kh4,2002-03-27,2001-11-29
-7khs,2020-12-02,2020-10-21
-4kh5,2013-11-06,2013-04-30
-1khp,2003-09-09,2001-11-30
-4khv,2013-05-15,2013-05-01
-7kh8,2021-05-19,2020-10-20
-3khi,2009-11-10,2009-10-30
-6khu,2020-07-22,2019-07-16
-6khx,2020-02-19,2019-07-16
-6khn,2020-07-15,2019-07-16
-8kh4,2023-10-11,2023-08-21
-6kh1,2020-01-29,2019-07-12
-4khw,2013-10-09,2013-05-01
-7khh,2021-02-24,2020-10-21
-7khd,2021-03-03,2020-10-21
-7khf,2021-03-31,2020-10-21
-4kh6,2013-11-06,2013-04-30
-2b1v,2006-05-09,2005-09-16
-1b1c,1999-11-24,1998-11-19
-8b1t,2022-12-28,2022-09-12
-4b1l,2012-12-12,2012-07-11
-7b1v,2021-03-03,2020-11-25
-7b1c,2022-07-13,2020-11-24
-5b1e,2016-12-14,2015-12-03
-5b1x,2016-05-11,2015-12-21
-2b11,2005-10-25,2005-09-15
-2b1n,2006-10-03,2005-09-16
-6b1m,2018-01-17,2017-09-18
-4b1h,2012-12-19,2012-07-10
-4b1x,2013-07-31,2012-07-12
-3b1r,2011-11-02,2011-07-05
-6b1e,2017-09-27,2017-09-18
-5b1y,2016-06-15,2015-12-22
-8b1f,2023-08-09,2022-09-09
-5b1j,2016-11-23,2015-12-04
-5b15,2016-05-11,2015-11-23
-3b1e,2012-06-27,2011-06-29
-6b1r,2018-09-19,2017-09-18
-4b1e,2012-10-10,2012-07-10
-8b1w,2023-12-27,2022-09-12
-7b1d,2022-07-13,2020-11-24
-4b17,2012-08-15,2012-07-07
-9b1r,2024-05-15,2024-03-13
-6b18,2019-01-16,2017-09-17
-3b1w,2011-11-02,2011-07-15
-8b1n,2022-09-28,2022-09-10
-4b15,2013-06-12,2012-07-06
-2b16,2006-07-18,2005-09-15
-4b1y,2013-07-31,2012-07-12
-8b1j,2023-08-09,2022-09-09
-7b17,2021-02-10,2020-11-23
-8b19,2023-08-09,2022-09-09
-5b13,2016-10-05,2015-11-18
-2b15,2006-07-18,2005-09-15
-3b1f,2011-10-26,2011-07-02
-2b18,2006-02-21,2005-09-15
-4b1d,2012-10-10,2012-07-10
-3b1v,2011-11-02,2011-07-15
-4b1w,2013-07-31,2012-07-12
-4b1j,2012-12-19,2012-07-10
-6b17,2018-02-21,2017-09-17
-3b1n,2011-11-02,2011-07-05
-4b1i,2012-12-19,2012-07-10
-7b1e,2021-04-28,2020-11-24
-4b11,2012-10-17,2012-07-06
-4b1b,2012-08-29,2012-07-09
-8b1u,2022-12-28,2022-09-12
-6b1j,2018-08-01,2017-09-18
-7b10,2021-02-17,2020-11-23
-2b1x,2005-10-04,2005-09-16
-7b1l,2021-12-08,2020-11-25
-1b1b,1999-12-03,1998-11-19
-7b1o,2021-09-29,2020-11-25
-7b1s,2021-07-14,2020-11-25
-1b1y,1998-12-02,1998-11-25
-2b1h,2006-07-04,2005-09-15
-4b16,2013-06-12,2012-07-06
-4b1c,2012-10-10,2012-07-10
-4b12,2012-10-17,2012-07-06
-5b1u,2016-05-11,2015-12-20
-7b1n,2021-12-08,2020-11-25
-7b1t,2022-06-08,2020-11-25
-5b1i,2016-12-07,2015-12-04
-1b16,1999-11-29,1998-11-25
-6b1h,2018-08-01,2017-09-18
-2b13,2006-01-10,2005-09-15
-7b1u,2021-12-08,2020-11-25
-7b14,2021-04-28,2020-11-23
-1b1x,1999-06-24,1998-11-24
-2b1o,2006-09-26,2005-09-16
-8b17,2023-08-09,2022-09-09
-2b1j,2006-09-26,2005-09-15
-2b1p,2006-09-16,2005-09-16
-7b1p,2021-04-28,2020-11-25
-6b1v,2018-03-14,2017-09-19
-5b1a,2016-09-14,2015-12-01
-8b1g,2023-08-09,2022-09-09
-3b1x,2011-11-02,2011-07-15
-6b1b,2019-05-22,2017-09-18
-6b1f,2018-08-01,2017-09-18
-8b1i,2023-08-09,2022-09-09
-6b1o,2017-09-27,2017-09-18
-3b12,2012-06-20,2011-06-19
-8b1d,2023-08-09,2022-09-09
-5b1w,2016-05-11,2015-12-21
-2b10,2005-10-25,2005-09-15
-4b1f,2012-07-18,2012-07-10
-2b1r,2006-09-12,2005-09-16
-5b1k,2016-11-23,2015-12-04
-8b18,2023-08-09,2022-09-09
-6b1l,2018-09-26,2017-09-18
-6b1x,2018-08-01,2017-09-19
-7b15,2021-09-29,2020-11-23
-8b1h,2023-08-09,2022-09-09
-2b1m,2006-10-03,2005-09-16
-3b1b,2011-11-16,2011-06-29
-2b14,2006-07-18,2005-09-15
-8b1e,2023-08-09,2022-09-09
-4b1q,2013-02-06,2012-07-12
-3b1d,2012-06-27,2011-06-29
-6b1c,2018-01-03,2017-09-18
-1b1h,1998-11-18,1998-11-10
-7b1w,2021-12-08,2020-11-25
-3b1u,2011-10-26,2011-07-13
-6b10,2017-12-13,2017-09-15
-3b1p,2011-11-02,2011-07-05
-8b1y,2023-09-20,2022-09-12
-2b12,2005-10-25,2005-09-15
-6b1k,2018-01-03,2017-09-18
-7b1a,2021-01-13,2020-11-24
-4b1v,2012-11-07,2012-07-12
-4b1a,2013-02-06,2012-07-09
-5b1s,2016-12-21,2015-12-17
-6b1d,2018-09-19,2017-09-18
-1b1g,1998-11-25,1998-11-20
-3b1m,2011-08-24,2011-07-05
-6b1u,2018-04-25,2017-09-19
-2b17,2005-10-04,2005-09-15
-5b1f,2016-12-07,2015-12-03
-3b1y,2011-11-02,2011-07-15
-1b14,1999-11-26,1998-11-25
-1b15,1999-11-26,1998-11-25
-7b13,2021-09-29,2020-11-23
-4b1u,2013-07-31,2012-07-12
-2b1z,2006-09-19,2005-09-16
-3b1j,2012-01-11,2011-07-04
-7b1g,2020-12-09,2020-11-24
-7b18,2021-04-28,2020-11-24
-4b10,2012-10-17,2012-07-06
-2b1q,2006-09-12,2005-09-16
-3b1k,2012-01-11,2011-07-04
-2b1g,2006-11-21,2005-09-15
-4b13,2012-10-17,2012-07-06
-1b13,1999-05-27,1998-11-26
-6b1w,2018-08-01,2017-09-19
-4b1r,2013-07-24,2012-07-12
-8b1v,2022-10-19,2022-09-12
-7b1y,2021-03-03,2020-11-25
-8b1b,2023-08-09,2022-09-09
-7b12,2021-12-01,2020-11-23
-8b1a,2023-08-09,2022-09-09
-4b14,2012-10-17,2012-07-06
-6b1z,2017-10-04,2017-09-19
-4b1m,2012-12-12,2012-07-11
-6b11,2018-12-19,2017-09-15
-4b1z,2012-11-07,2012-07-12
-5b16,2016-02-03,2015-11-23
-9b1z,2024-03-27,2024-03-14
-3b1t,2011-10-26,2011-07-13
-5b1g,2016-12-07,2015-12-03
-7b1b,2022-07-13,2020-11-24
-7b1q,2021-04-28,2020-11-25
-3b1q,2011-11-02,2011-07-05
-8b1z,2023-12-27,2022-09-12
-5b1l,2017-02-15,2015-12-08
-8b1s,2023-09-27,2022-09-12
-6b16,2017-10-25,2017-09-16
-1b11,1998-12-02,1998-11-25
-8b1r,2022-12-28,2022-09-12
-8b1k,2023-08-09,2022-09-09
-1b12,1999-12-10,1999-11-24
-7b19,2021-01-13,2020-11-24
-5b1b,2016-09-14,2015-12-01
-8b1c,2023-08-09,2022-09-09
-6b1n,2018-01-17,2017-09-18
-7b16,2020-12-09,2020-11-23
-7b1k,2021-12-08,2020-11-25
-5b1d,2016-12-14,2015-12-03
-4b1t,2012-08-01,2012-07-12
-2b1i,2006-11-21,2005-09-15
-3b1c,2012-06-27,2011-06-29
-6b1y,2018-08-01,2017-09-19
-6b1i,2018-01-17,2017-09-18
-7le7,2022-01-26,2021-01-14
-1le7,2002-08-14,2002-04-09
-7leo,2022-05-04,2021-01-14
-6lel,2021-01-27,2019-11-25
-1lel,2002-11-06,2002-04-10
-5ley,2016-08-17,2016-06-30
-4len,2014-06-18,2013-06-26
-4leh,2013-08-21,2013-06-25
-3lez,2010-02-02,2010-01-15
-4lez,2013-12-25,2013-06-26
-2lel,2012-02-15,2011-06-16
-4le0,2014-07-16,2013-06-25
-7le9,2022-01-26,2021-01-14
-7leb,2022-01-26,2021-01-14
-5le5,2016-08-17,2016-06-29
-7leh,2022-01-26,2021-01-14
-7leg,2022-01-26,2021-01-14
-4leo,2013-07-10,2013-06-26
-4lei,2014-12-10,2013-06-25
-1le6,2002-08-14,2002-04-09
-7le5,2022-01-26,2021-01-14
-7le3,2022-01-26,2021-01-14
-7let,2022-01-19,2021-01-15
-4led,2014-02-19,2013-06-25
-6le9,2020-04-22,2019-11-24
-3lek,2010-12-29,2010-01-15
-3lex,2010-09-29,2010-01-15
-3le8,2010-04-14,2010-01-14
-4le4,2013-09-11,2013-06-25
-1lek,2002-06-26,2002-04-09
-7le1,2022-07-06,2021-01-14
-1lem,1994-01-31,1993-11-17
-3len,2011-01-19,2010-01-15
-4leq,2014-12-24,2013-06-26
-3lem,2010-05-12,2010-01-15
-7le0,2022-07-06,2021-01-14
-7lei,2022-01-26,2021-01-14
-7lee,2022-01-26,2021-01-14
-3lel,2010-05-19,2010-01-15
-3le0,2010-12-29,2010-01-13
-4lep,2013-07-10,2013-06-26
-5leo,2017-07-12,2016-06-30
-4lef,2014-06-25,2013-06-25
-5le1,2017-02-15,2016-06-29
-3le1,2010-12-15,2010-01-14
-5lex,2016-08-17,2016-06-30
-4lej,2014-01-22,2013-06-25
-7lem,2021-07-14,2021-01-14
-3ley,2010-09-29,2010-01-15
-3leg,2010-12-29,2010-01-14
-6le8,2021-05-26,2019-11-24
-1lee,2002-10-09,2002-04-09
-4leb,2014-05-14,2013-06-25
-1lez,2002-07-10,2002-04-10
-7lec,2022-01-26,2021-01-14
-6lez,2020-12-02,2019-11-27
-6leb,2020-11-25,2019-11-25
-4lew,2013-12-25,2013-06-26
-3lei,2010-12-29,2010-01-14
-6lem,2021-01-27,2019-11-25
-4lec,2013-07-17,2013-06-25
-1led,1994-01-31,1992-12-17
-3le7,2010-04-14,2010-01-14
-7le4,2022-01-26,2021-01-14
-7lep,2021-05-12,2021-01-14
-6leu,2020-12-02,2019-11-27
-5lez,2016-08-17,2016-06-30
-7ler,2022-02-23,2021-01-14
-1len,1994-01-31,1993-11-17
-7les,2021-12-22,2021-01-15
-7lez,2021-09-01,2021-01-15
-7leu,2022-01-19,2021-01-15
-7lef,2022-01-26,2021-01-14
-7le6,2022-01-26,2021-01-14
-6le4,2020-10-07,2019-11-24
-7le2,2022-07-06,2021-01-14
-3lea,2010-12-08,2010-01-14
-7leq,2022-01-19,2021-01-14
-1les,1995-12-07,1995-08-23
-5lef,2017-11-15,2016-06-29
-3le6,2010-11-17,2010-01-14
-3leo,2010-10-27,2010-01-15
-7ley,2021-09-01,2021-01-15
-4ley,2013-12-25,2013-06-26
-7lek,2021-07-14,2021-01-14
-7lel,2021-07-14,2021-01-14
-3le9,2010-12-08,2010-01-14
-2leb,2011-11-23,2011-06-15
-7lev,2022-01-19,2021-01-15
-7led,2022-01-26,2021-01-14
-2lex,2012-01-18,2011-06-24
-5lew,2017-10-25,2016-06-30
-3lee,2010-12-08,2010-01-14
-4lev,2013-12-25,2013-06-26
-7le8,2022-01-26,2021-01-14
-1lev,2002-10-16,2002-04-10
-6lev,2020-12-02,2019-11-27
-4lem,2014-05-14,2013-06-26
-1lec,1994-01-31,1992-12-17
-7lej,2021-07-14,2021-01-14
-4lek,2014-02-19,2013-06-25
-6lej,2021-01-27,2019-11-25
-6le7,2021-05-26,2019-11-24
-4lea,2014-02-19,2013-06-25
-1leg,2002-06-19,2002-04-09
-3lev,2010-09-29,2010-01-15
-7lea,2022-01-26,2021-01-14
-4le2,2014-07-16,2013-06-25
-3lec,2010-01-26,2010-01-14
-7len,2021-11-17,2021-01-14
-6ler,2021-03-03,2019-11-26
-6leg,2021-01-27,2019-11-25
-3ler,2010-01-26,2010-01-15
-3lep,2010-12-15,2010-01-15
-2lec,2011-11-23,2011-06-15
-4le6,2013-11-13,2013-06-25
-2leg,2011-10-26,2011-06-15
-4lel,2014-08-06,2013-06-25
-6leh,2020-03-18,2019-11-25
-4zes,2015-05-27,2015-04-20
-6zek,2021-04-28,2020-06-16
-6zej,2020-09-30,2020-06-16
-2zez,2008-03-25,2007-12-18
-6ze7,2021-05-26,2020-06-16
-6zet,2020-10-14,2020-06-16
-1ze1,2005-04-26,2005-04-16
-1ze9,2005-05-03,2005-04-18
-4zef,2016-06-29,2015-04-20
-4zee,2015-05-27,2015-04-20
-2zey,2008-03-04,2007-12-18
-6zev,2020-10-14,2020-06-16
-4zed,2015-08-19,2015-04-20
-4zet,2015-05-27,2015-04-20
-1zeg,1998-07-15,1998-05-01
-7zeb,2022-09-21,2022-03-30
-1zen,1997-07-07,1996-07-08
-7zel,2022-09-28,2022-03-31
-2zep,2008-04-22,2007-12-13
-4zej,2015-05-27,2015-04-20
-7zer,2022-07-13,2022-03-31
-2zew,2008-03-04,2007-12-18
-3zew,2013-12-25,2012-12-07
-3ze2,2013-06-05,2012-12-03
-3zez,2013-01-30,2012-12-10
-5zef,2019-06-26,2018-02-27
-3zeb,2013-02-13,2012-12-04
-4zer,2015-05-20,2015-04-20
-6zeu,2020-10-14,2020-06-16
-6zef,2020-09-30,2020-06-16
-6ze3,2021-05-26,2020-06-16
-7zei,2022-08-03,2022-03-31
-2zeg,2008-04-22,2007-12-12
-2zeb,2008-12-09,2007-12-08
-7zea,2022-08-24,2022-03-30
-1ze8,2005-10-18,2005-04-18
-1zet,2005-07-19,2005-04-19
-4zeb,2015-08-19,2015-04-20
-7zef,2022-11-23,2022-03-31
-2ze6,2008-02-05,2007-12-06
-7zeg,2022-04-13,2022-03-31
-3zec,2013-06-19,2012-12-04
-2zef,2008-04-22,2007-12-12
-5zer,2019-03-06,2018-02-27
-6ze6,2021-05-26,2020-06-16
-6ze8,2020-11-11,2020-06-16
-7zex,2022-05-04,2022-03-31
-7ze8,2022-10-05,2022-03-30
-6zed,2020-07-29,2020-06-16
-2ze7,2008-02-05,2007-12-06
-5ze3,2018-04-11,2018-02-25
-3ze0,2013-06-05,2012-12-03
-6zew,2021-04-14,2020-06-16
-2zet,2008-09-30,2007-12-17
-7zes,2022-09-28,2022-03-31
-3ze8,2013-06-12,2012-12-03
-2ze0,2007-12-18,2007-12-04
-7ze5,2023-04-19,2022-03-30
-4ze3,2016-03-30,2015-04-20
-7zey,2022-04-13,2022-03-31
-1zed,2005-06-28,2005-04-18
-1zef,2005-06-28,2005-04-18
-4zei,2015-08-19,2015-04-20
-6zei,2020-09-30,2020-06-16
-1zeo,2006-04-25,2005-04-19
-3zea,2013-06-12,2012-12-03
-3ze7,2013-06-12,2012-12-03
-3ze9,2013-06-12,2012-12-03
-5zeo,2018-05-09,2018-02-27
-5ze4,2018-07-18,2018-02-26
-1zeb,2005-06-28,2005-04-18
-4zen,2016-06-29,2015-04-20
-1zem,2006-03-28,2005-04-19
-6zep,2021-06-16,2020-06-16
-6zex,2021-04-14,2020-06-16
-5zed,2019-01-02,2018-02-27
-2zee,2008-04-22,2007-12-12
-3zep,2013-12-11,2012-12-06
-7ze7,2022-12-07,2022-03-30
-7ze3,2022-10-05,2022-03-30
-2ze3,2008-08-12,2007-12-05
-5zeh,2019-06-26,2018-02-27
-2ze1,2008-12-09,2007-12-05
-5ze8,2018-04-25,2018-02-27
-6zer,2020-06-24,2020-06-16
-2zeh,2008-04-22,2007-12-12
-6ze5,2021-05-26,2020-06-16
-5zen,2018-08-08,2018-02-27
-4zek,2015-08-19,2015-04-20
-7zej,2022-05-04,2022-03-31
-5zes,2019-03-06,2018-02-27
-1zel,2006-05-02,2005-04-19
-3zed,2013-01-16,2012-12-04
-4ze2,2016-03-30,2015-04-20
-1zea,2006-04-04,2005-04-18
-6zeh,2020-09-30,2020-06-16
-7zen,2022-11-23,2022-03-31
-7zez,2022-04-13,2022-03-31
-7zew,2022-04-13,2022-03-31
-7zee,2022-04-13,2022-03-31
-5ze0,2018-04-25,2018-02-25
-4zex,2015-09-09,2015-04-20
-2zev,2008-12-23,2007-12-17
-4ze9,2015-08-19,2015-04-20
-5zeq,2018-06-20,2018-02-27
-2zen,2008-04-22,2007-12-13
-5ze1,2018-04-25,2018-02-25
-6zel,2020-07-29,2020-06-16
-4ze1,2016-03-30,2015-04-20
-3zet,2013-03-20,2012-12-07
-4ze0,2016-03-30,2015-04-20
-6ze2,2021-05-26,2020-06-16
-6ze9,2020-06-24,2020-06-16
-2zeu,2008-12-23,2007-12-17
-6zea,2020-09-02,2020-06-16
-7zeu,2023-10-11,2022-03-31
-6zec,2021-06-30,2020-06-16
-5ze6,2019-02-27,2018-02-26
-4zel,2016-04-20,2015-04-20
-2zel,2008-04-22,2007-12-13
-3ze3,2013-05-22,2012-12-03
-7zec,2023-04-19,2022-03-30
-2zex,2008-03-04,2007-12-18
-2zec,2008-12-09,2007-12-08
-3zei,2013-08-07,2012-12-05
-6zez,2021-04-14,2020-06-16
-4ze6,2016-05-04,2015-04-20
-6ze1,2021-06-30,2020-06-15
-3zeu,2013-03-20,2012-12-07
-5ze9,2019-02-06,2018-02-27
-4zev,2015-09-09,2015-04-20
-3zev,2014-01-29,2012-12-07
-2zed,2008-04-22,2007-12-12
-2zeo,2008-04-22,2007-12-13
-2ze5,2008-02-05,2007-12-06
-4zep,2016-06-29,2015-04-20
-3ze6,2013-06-12,2012-12-03
-4zea,2016-05-04,2015-04-20
-7ze9,2023-03-15,2022-03-30
-5ze2,2018-04-25,2018-02-25
-4zew,2015-09-09,2015-04-20
-1zei,1999-02-16,1998-07-14
-5zee,2019-06-26,2018-02-27
-4zec,2015-08-19,2015-04-20
-2zej,2008-01-22,2007-12-13
-4zeg,2016-04-27,2015-04-20
-6zeg,2020-09-30,2020-06-16
-6zeq,2021-06-16,2020-06-16
-7zep,2022-09-28,2022-03-31
-6ze4,2021-05-26,2020-06-16
-3ze1,2013-06-05,2012-12-03
-2ze2,2008-02-12,2007-12-05
-7zet,2023-10-11,2022-03-31
-6zee,2020-09-30,2020-06-16
-7zeh,2022-05-25,2022-03-31
-1zes,2005-09-20,2005-04-19
-7ze6,2022-11-23,2022-03-30
-6zey,2021-04-14,2020-06-16
-1zeh,1998-12-09,1998-05-01
-2zem,2008-04-22,2007-12-13
-5zec,2019-01-02,2018-02-27
-3s41,2011-09-14,2011-05-18
-3s4a,2012-06-27,2011-05-19
-7s4g,2022-04-13,2021-09-08
-5s4i,2021-01-13,2020-11-02
-3s4q,2012-02-01,2011-05-20
-5s40,2021-01-13,2020-11-02
-7s4o,2022-09-07,2021-09-09
-6s4r,2020-02-19,2019-06-28
-5s4o,2021-06-30,2020-11-08
-5s41,2021-01-13,2020-11-02
-6s49,2020-07-08,2019-06-27
-6s41,2019-10-02,2019-06-26
-6s4u,2019-11-27,2019-06-28
-5s44,2021-01-13,2020-11-02
-5s4v,2021-06-30,2020-11-08
-6s4f,2021-07-07,2019-06-27
-3s4g,2011-08-03,2011-05-19
-5s4x,2021-06-30,2020-11-08
-1s4m,2004-10-19,2004-01-16
-5s46,2021-01-13,2020-11-02
-7s42,2021-09-22,2021-09-08
-7s4k,2022-03-30,2021-09-09
-7s4l,2022-03-30,2021-09-09
-7s4m,2022-03-30,2021-09-09
-3s4b,2012-06-27,2011-05-19
-3s47,2012-05-23,2011-05-18
-1s4o,2004-05-04,2004-01-16
-7s4e,2022-10-05,2021-09-08
-1s46,2004-03-23,2004-01-15
-8s4s,2024-05-29,2024-02-22
-7s41,2021-09-22,2021-09-08
-1s4p,2004-05-04,2004-01-16
-5s4g,2021-01-13,2020-11-02
-1s4s,2004-04-13,2004-01-17
-7s44,2021-09-22,2021-09-08
-5s4e,2021-01-13,2020-11-02
-8s4g,,2024-02-21
-6s4n,2019-11-27,2019-06-28
-3s44,2012-08-15,2011-05-18
-7s45,2021-09-22,2021-09-08
-3s4l,2011-06-22,2011-05-19
-1s4i,2005-04-26,2004-01-16
-7s40,2022-09-14,2021-09-08
-5s4y,2021-06-30,2020-11-08
-6s4p,2020-02-19,2019-06-28
-5s4b,2021-01-13,2020-11-02
-7s4f,2022-09-21,2021-09-08
-5s4c,2021-01-13,2020-11-02
-5s4w,2021-06-30,2020-11-08
-6s46,2020-07-08,2019-06-26
-5s4u,2021-06-30,2020-11-08
-7s47,2022-11-09,2021-09-08
-5s47,2021-01-13,2020-11-02
-5s4r,2021-06-30,2020-11-08
-3s48,2012-05-23,2011-05-19
-6s4c,2020-02-19,2019-06-27
-6s40,2020-06-17,2019-06-26
-7s4y,2021-10-27,2021-09-09
-1s4r,2004-04-13,2004-01-17
-5s4a,2021-01-13,2020-11-02
-7s4j,2022-03-30,2021-09-09
-6s4d,2020-07-08,2019-06-27
-5s4t,2021-06-30,2020-11-08
-3s4d,2012-06-27,2011-05-19
-3s42,2011-06-01,2011-05-18
-7s4z,2021-10-27,2021-09-09
-7s48,2022-11-09,2021-09-08
-5s45,2021-01-13,2020-11-02
-7s4c,2021-09-29,2021-09-08
-1s4d,2004-11-30,2004-01-16
-7s4b,2021-09-15,2021-09-08
-3s4j,2011-06-29,2011-05-19
-3s4y,2011-06-08,2011-05-20
-7s43,2021-09-22,2021-09-08
-5s4j,2021-01-13,2020-11-02
-7s46,2022-11-09,2021-09-08
-6s4t,2019-11-27,2019-06-28
-1s4b,2004-07-20,2004-01-15
-5s4m,2021-06-30,2020-11-08
-6s48,2020-05-20,2019-06-26
-3s43,2012-03-21,2011-05-18
-5s4k,2021-01-13,2020-11-02
-1s49,2004-04-06,2004-01-15
-5s4s,2021-06-30,2020-11-08
-6s45,2020-07-08,2019-06-26
-5s4f,2021-01-13,2020-11-02
-6s4h,2020-02-19,2019-06-28
-5s4n,2021-06-30,2020-11-08
-5s43,2021-01-13,2020-11-02
-5s49,2021-01-13,2020-11-02
-7s4x,2022-03-02,2021-09-09
-5s4q,2021-06-30,2020-11-08
-6s4e,2021-07-07,2019-06-27
-7s4t,2022-09-21,2021-09-09
-6s4b,2020-12-09,2019-06-27
-1s4e,2004-04-06,2004-01-16
-5s4h,2021-01-13,2020-11-02
-7s4h,2022-03-30,2021-09-08
-1s4a,2004-02-24,2004-01-15
-6s47,2019-07-24,2019-06-26
-1s4c,2005-06-14,2004-01-15
-6s4l,2020-07-15,2019-06-28
-7s4i,2022-03-30,2021-09-09
-6s4k,2020-02-19,2019-06-28
-5s4l,2021-06-30,2020-11-08
-6s43,2019-09-25,2019-06-26
-5s42,2021-01-13,2020-11-02
-7s4s,2021-09-22,2021-09-09
-1s4n,2004-05-04,2004-01-16
-5s48,2021-01-13,2020-11-02
-1s4v,2004-03-16,2004-01-19
-6s4g,2019-07-17,2019-06-27
-6s4a,2021-07-07,2019-06-27
-5s4p,2021-06-30,2020-11-08
-5s4z,2021-06-30,2020-11-08
-7s49,2021-09-29,2021-09-08
-6s4o,2020-02-19,2019-06-28
-3s45,2012-03-21,2011-05-18
-8iiy,2023-11-01,2023-02-24
-2ii3,2006-12-26,2006-09-27
-6iii,2019-10-09,2018-10-06
-3iiy,2009-09-15,2009-08-03
-5iii,2016-08-17,2016-03-01
-1iir,2001-07-18,2001-04-24
-6ii6,2019-08-07,2018-10-03
-1ii9,2001-09-12,2001-04-21
-6ii9,2018-10-24,2018-10-03
-3iiu,2009-11-24,2009-08-03
-8ii1,2023-06-28,2023-02-24
-5ii5,2017-06-14,2016-03-01
-2iim,2006-11-07,2006-09-28
-4iik,2013-06-19,2012-12-20
-8iiz,2023-11-01,2023-02-24
-3iij,2010-10-06,2009-08-02
-2iiq,2007-08-14,2006-09-28
-5ii2,2016-06-29,2016-03-01
-4iig,2013-04-10,2012-12-20
-6iis,2019-04-24,2018-10-07
-2ii1,2006-12-05,2006-09-27
-1iiq,2002-04-12,2001-04-24
-5iis,2016-04-06,2016-03-01
-1ii7,2001-05-30,2001-04-20
-2iii,2007-10-09,2006-09-28
-3ii1,2009-08-25,2009-07-31
-3iif,2009-08-18,2009-07-31
-4iih,2013-04-10,2012-12-20
-6iia,2019-03-27,2018-10-04
-5ii1,2016-06-29,2016-03-01
-6iiw,2019-10-09,2018-10-07
-4iir,2013-08-28,2012-12-20
-2iit,2006-11-28,2006-09-28
-6iiy,2019-10-09,2018-10-08
-2iip,2006-10-10,2006-09-28
-5iin,2016-08-17,2016-03-01
-5iit,2016-04-27,2016-03-01
-3ii9,2009-12-15,2009-07-31
-6ii7,2019-05-01,2018-10-03
-2iie,2007-02-20,2006-09-28
-8iie,2023-06-21,2023-02-24
-6iix,2019-10-09,2018-10-08
-4iiv,2013-01-09,2012-12-20
-4iid,2013-04-10,2012-12-20
-1ii6,2001-07-18,2001-04-20
-1iiu,2002-01-16,2001-04-24
-3ii4,2010-01-26,2009-07-31
-8iin,2023-06-21,2023-02-24
-5iiu,2016-03-23,2016-03-01
-4ii4,2014-08-20,2012-12-19
-3iim,2010-10-06,2009-08-02
-5iik,2016-08-17,2016-03-01
-3iii,2009-08-18,2009-08-01
-3iiv,2010-03-02,2009-08-03
-5iid,2016-06-29,2016-03-01
-5iif,2016-03-09,2016-03-01
-5ii0,2016-05-11,2016-03-01
-3iiq,2009-09-01,2009-08-03
-5iix,2016-03-16,2016-03-01
-3ii5,2009-11-10,2009-07-31
-8ii4,2023-06-28,2023-02-24
-3iit,2010-08-04,2009-08-03
-6iiv,2018-12-19,2018-10-07
-2ii4,2006-12-26,2006-09-27
-6iig,2019-10-09,2018-10-05
-2iic,2007-04-17,2006-09-27
-5iih,2016-03-16,2016-03-01
-1iit,2001-09-19,2001-04-24
-4iiy,2013-12-25,2012-12-20
-6ii1,2018-12-12,2018-10-03
-8iib,2023-06-07,2023-02-24
-2iiv,2006-11-28,2006-09-28
-6iik,2018-12-12,2018-10-06
-2iid,2006-10-31,2006-09-27
-4iif,2013-04-10,2012-12-20
-3iiw,2009-09-15,2009-08-03
-8iip,2023-06-21,2023-02-24
-3iis,2009-11-24,2009-08-03
-6iiu,2018-12-19,2018-10-07
-1ii0,2001-09-12,2001-04-20
-1iid,2001-05-02,2001-04-22
-4iib,2013-04-10,2012-12-20
-3iil,2010-10-06,2009-08-02
-4iin,2013-01-09,2012-12-20
-2ii6,2007-08-14,2006-09-27
-5ii3,2016-12-07,2016-03-01
-5ii4,2017-06-14,2016-03-01
-6iie,2019-02-20,2018-10-04
-3iid,2009-08-18,2009-07-31
-3iix,2009-09-22,2009-08-03
-3ii0,2009-08-11,2009-07-31
-2iib,2007-08-14,2006-09-27
-4iit,2013-11-06,2012-12-20
-4iis,2013-11-27,2012-12-20
-6iih,2019-08-14,2018-10-06
-4iiz,2013-01-30,2012-12-20
-3ii2,2010-03-23,2009-07-31
-4ii8,2013-12-25,2012-12-20
-4ii2,2013-02-13,2012-12-19
-1iig,2001-05-11,2001-04-23
-6iim,2018-12-12,2018-10-07
-4ii0,2013-07-24,2012-12-19
-5iim,2016-09-07,2016-03-01
-3ii3,2010-03-23,2009-07-31
-5iiy,2017-02-08,2016-03-01
-6ii8,2018-10-24,2018-10-03
-5iij,2016-08-17,2016-03-01
-1iim,2001-05-09,2001-04-23
-4ii9,2013-07-03,2012-12-20
-4iix,2013-12-25,2012-12-20
-2iif,2007-02-20,2006-09-28
-8ii2,2023-06-28,2023-02-24
-3iiz,2009-09-22,2009-08-03
-4ii3,2013-02-13,2012-12-19
-6iin,2018-12-19,2018-10-07
-3iie,2009-08-11,2009-07-31
-4iie,2013-04-10,2012-12-20
-8iil,2023-06-21,2023-02-24
-6iil,2018-12-12,2018-10-07
-3iib,2009-08-25,2009-07-31
-4iiu,2013-01-09,2012-12-20
-8ii0,2024-02-28,2023-02-24
-4iij,2013-01-30,2012-12-20
-6iiq,2019-04-24,2018-10-07
-2ii5,2006-12-26,2006-09-27
-5iib,2017-06-14,2016-03-01
-5iia,2017-06-14,2016-03-01
-2iiz,2006-11-14,2006-09-28
-5iio,2016-08-17,2016-03-01
-5iil,2016-08-17,2016-03-01
-1iic,2001-05-02,2001-04-22
-8ii3,2023-06-28,2023-02-24
-8iig,2023-06-21,2023-02-24
-6iid,2019-04-03,2018-10-04
-1ii5,2001-09-19,2001-04-20
-5iic,2017-06-14,2016-03-01
-6iit,2019-04-24,2018-10-07
-8iit,2023-06-21,2023-02-24
-4iic,2013-04-10,2012-12-20
-5iiz,2016-09-21,2016-03-01
-1iiy,2001-10-24,2001-04-24
-1iin,2001-05-09,2001-04-23
-4ii5,2013-01-23,2012-12-19
-8iii,2023-06-21,2023-02-24
-4ii1,2013-02-13,2012-12-19
-4iil,2013-02-27,2012-12-20
-1oim,2003-11-25,2003-06-19
-6oi3,2020-04-01,2019-04-08
-6oia,2019-09-18,2019-04-09
-3oib,2010-09-01,2010-08-18
-4oi1,2014-05-14,2014-01-18
-4oip,2014-05-07,2014-01-20
-3oiv,2010-12-08,2010-08-20
-5oic,2018-02-14,2017-07-18
-3oi8,2010-09-22,2010-08-18
-7oih,2022-08-24,2021-05-11
-7oia,2021-09-15,2021-05-11
-6oic,2020-01-15,2019-04-09
-6oiv,2019-06-05,2019-04-09
-4oin,2014-05-07,2014-01-20
-8oiz,2023-07-19,2023-03-23
-2oiw,2007-02-20,2007-01-11
-5oi3,2018-03-07,2017-07-18
-2oik,2007-01-30,2007-01-11
-6oiw,2019-05-15,2019-04-09
-2oip,2007-07-17,2007-01-11
-1oin,2003-11-25,2003-06-19
-1oio,2003-08-15,2003-06-22
-5oio,2018-02-14,2017-07-19
-5ois,2018-02-14,2017-07-19
-1oiu,2004-07-13,2003-06-26
-7oin,2022-02-16,2021-05-12
-4oiz,2014-07-23,2014-01-20
-8oi6,2023-08-09,2023-03-22
-1oi6,2004-06-03,2003-06-09
-4oiy,2014-07-02,2014-01-20
-2oi6,2007-06-19,2007-01-10
-3oig,2011-01-05,2010-08-19
-7oid,2021-09-15,2021-05-11
-1oih,2004-03-30,2003-06-18
-8oi1,2023-12-27,2023-03-21
-4oir,2014-05-07,2014-01-20
-4oic,2015-01-21,2014-01-19
-1oie,2004-08-05,2003-06-16
-7oic,2021-09-15,2021-05-11
-3oi7,2010-11-17,2010-08-18
-6oir,2019-07-03,2019-04-09
-7oi3,2021-06-23,2021-05-11
-6oi5,2020-01-15,2019-04-08
-5oim,2018-02-14,2017-07-19
-4oia,2014-07-16,2014-01-19
-7oiw,2022-06-01,2021-05-12
-1oif,2003-11-25,2003-06-16
-5oia,2018-03-07,2017-07-18
-1oiz,2004-01-14,2003-06-27
-8oic,2023-08-02,2023-03-22
-7oii,2022-01-19,2021-05-11
-3oiw,2010-12-08,2010-08-20
-8oi7,2023-08-02,2023-03-22
-4oit,2014-07-23,2014-01-20
-4oif,2015-02-04,2014-01-19
-2oig,2007-03-06,2007-01-11
-2oih,2007-03-27,2007-01-11
-4oiq,2014-05-07,2014-01-20
-1oi9,2004-07-13,2003-06-10
-7oik,2022-06-01,2021-05-11
-4oil,2014-08-20,2014-01-19
-7oij,2021-07-14,2021-05-11
-5oiz,2018-05-30,2017-07-20
-2oil,2007-01-23,2007-01-11
-7oi7,2021-09-15,2021-05-11
-1oil,1997-05-15,1996-12-06
-7oiy,2022-02-02,2021-05-12
-5oie,2018-08-08,2017-07-18
-6oim,2019-11-06,2019-04-09
-1oii,2004-03-30,2003-06-18
-1oir,2003-09-04,2003-06-24
-3oif,2011-01-05,2010-08-19
-1oi8,2004-06-10,2003-06-10
-1oi0,2003-08-14,2003-06-04
-6oi9,2019-07-31,2019-04-09
-5oi0,2018-08-08,2017-07-18
-4oio,2014-05-07,2014-01-20
-2oi3,2007-02-20,2007-01-10
-6oil,2019-09-11,2019-04-09
-5oip,2018-02-14,2017-07-19
-1oiv,2004-01-08,2003-06-26
-2oiz,2007-04-24,2007-01-12
-4oi9,2014-07-16,2014-01-19
-8ois,2023-06-14,2023-03-23
-6oib,2020-01-15,2019-04-09
-4oiw,2014-04-02,2014-01-20
-2oin,2007-06-05,2007-01-11
-8oi9,2023-08-02,2023-03-22
-8oif,2023-12-13,2023-03-22
-6oix,2019-05-08,2019-04-09
-8oib,2023-08-02,2023-03-22
-6oiy,2019-05-15,2019-04-09
-4oi2,2014-05-14,2014-01-18
-1oiy,2004-07-13,2003-06-26
-8oia,2023-08-02,2023-03-22
-3oik,2011-07-06,2010-08-19
-2oi0,2007-11-27,2007-01-10
-8oid,2023-08-09,2023-03-22
-7oif,2022-01-19,2021-05-11
-2oiq,2007-03-20,2007-01-11
-7oi6,2021-10-13,2021-05-11
-1oiq,2003-09-04,2003-06-24
-7oi2,2022-03-02,2021-05-11
-8oix,2024-04-10,2023-03-23
-2oif,2007-07-24,2007-01-10
-1oit,2003-09-04,2003-06-24
-4oiv,2015-03-25,2014-01-20
-4oi5,2014-04-02,2014-01-18
-6oiu,2020-09-30,2019-04-09
-8oi8,2023-08-16,2023-03-22
-3oij,2010-12-01,2010-08-19
-7oiz,2021-09-15,2021-05-13
-4oi4,2014-05-14,2014-01-18
-8oin,2023-06-14,2023-03-23
-6oi8,2019-07-31,2019-04-09
-5oiw,2018-08-08,2017-07-19
-3oix,2010-09-08,2010-08-20
-1oiw,2004-01-08,2003-06-26
-6oii,2019-05-08,2019-04-09
-1oip,2004-01-14,2003-06-24
-1oik,2004-03-30,2003-06-18
-7oig,2022-01-19,2021-05-11
-2oi7,2007-06-19,2007-01-10
-4oik,2014-05-07,2014-01-19
-8oiw,2024-01-17,2023-03-23
-8oiq,2023-06-14,2023-03-23
-6oid,2020-05-20,2019-04-09
-4oi6,2014-09-10,2014-01-18
-6oio,2019-07-03,2019-04-09
-6oi7,2019-05-29,2019-04-08
-8oih,2024-01-17,2023-03-22
-6oi2,2020-04-01,2019-04-08
-4oib,2014-07-16,2014-01-19
-4oim,2014-04-23,2014-01-20
-8oiv,2023-08-23,2023-03-23
-1oid,2004-06-10,2003-06-13
-6oi6,2020-01-15,2019-04-08
-4oiu,2014-08-20,2014-01-20
-3oiu,2010-12-08,2010-08-20
-6oik,2019-05-08,2019-04-09
-2oi5,2007-06-19,2007-01-10
-5oiq,2018-02-14,2017-07-19
-8oir,2023-06-14,2023-03-23
-7oix,2022-06-01,2021-05-12
-5oi8,2018-03-07,2017-07-18
-1oix,2005-01-25,2003-06-26
-3ois,2011-08-03,2010-08-19
-6oi1,2020-04-01,2019-04-08
-7oie,2021-09-15,2021-05-11
-6oij,2019-05-08,2019-04-09
-7oil,2021-07-14,2021-05-11
-6oi0,2020-04-01,2019-04-08
-2oi2,2007-05-01,2007-01-10
-7oi8,2021-09-15,2021-05-11
-7oi1,2021-12-15,2021-05-11
-8oio,2024-04-03,2023-03-23
-2oid,2007-03-20,2007-01-10
-5oin,2018-02-14,2017-07-19
-3oih,2010-09-22,2010-08-19
-3oin,2010-12-01,2010-08-19
-8oip,2023-05-24,2023-03-23
-5oi2,2018-03-07,2017-07-18
-5oit,2018-02-14,2017-07-19
-5oik,2017-09-13,2017-07-18
-3oia,2010-11-17,2010-08-18
-8oit,2023-06-14,2023-03-23
-7oim,2022-06-01,2021-05-11
-3oil,2011-07-06,2010-08-19
-7oi9,2021-09-15,2021-05-11
-6oin,2019-07-03,2019-04-09
-2oi9,2007-04-24,2007-01-10
-2oi4,2007-04-10,2007-01-10
-5oi5,2018-03-07,2017-07-18
-6oie,2019-11-20,2019-04-09
-7ois,2021-07-14,2021-05-12
-3oii,2010-12-01,2010-08-19
-6oip,2019-07-03,2019-04-09
-1oij,2004-03-30,2003-06-18
-6oif,2019-07-24,2019-04-09
-7oib,2021-09-15,2021-05-11
-5oiv,2018-08-08,2017-07-19
-3oid,2011-01-05,2010-08-19
-3oim,2011-07-06,2010-08-19
-5oi1,2018-08-08,2017-07-18
-6oiq,2019-07-03,2019-04-09
-4oi0,2014-05-14,2014-01-18
-2oic,2007-03-20,2007-01-10
-5oif,2018-02-14,2017-07-18
-5oir,2018-02-14,2017-07-19
-7oi4,2021-07-14,2021-05-11
-8oie,2023-10-04,2023-03-22
-5oil,2018-02-14,2017-07-19
-5oiu,2018-08-08,2017-07-19
-5l3s,2016-06-08,2016-05-24
-5l3i,2016-06-15,2016-05-06
-4l32,2013-10-30,2013-06-05
-3l3k,2010-03-16,2009-12-17
-1l3s,2003-03-25,2002-03-01
-4l3f,2013-08-28,2013-06-05
-6l35,2021-02-10,2019-10-09
-5l3k,2017-06-07,2016-05-23
-5l3z,2016-10-05,2016-05-24
-5l32,2016-11-09,2016-08-02
-5l3p,2016-07-20,2016-05-24
-1l3u,2003-03-25,2002-03-01
-5l3y,2016-07-20,2016-05-24
-5l3w,2016-06-08,2016-05-24
-3l35,2010-11-03,2009-12-16
-3l3r,2011-01-05,2009-12-17
-3l36,2010-11-03,2009-12-16
-6l3r,2020-10-28,2019-10-15
-3l3m,2010-06-23,2009-12-17
-3l38,2010-04-28,2009-12-16
-6l3m,2019-12-18,2019-10-11
-7l3k,2021-10-27,2020-12-17
-5l3a,2016-04-27,2016-04-06
-4l37,2013-12-04,2013-06-05
-4l3c,2013-12-25,2013-06-05
-6l3t,2020-09-09,2019-10-15
-7l3e,2021-10-27,2020-12-17
-1l3l,2002-07-03,2002-02-27
-5l38,2016-12-14,2016-08-03
-4l3n,2013-07-31,2013-06-06
-7l3u,2021-02-03,2020-12-18
-3l3i,2010-03-16,2009-12-17
-4l3h,2013-09-04,2013-06-05
-3l3x,2010-01-12,2009-12-18
-6l3x,2020-08-26,2019-10-15
-3l30,2010-01-26,2009-12-16
-4l3t,2013-07-03,2013-06-06
-3l3g,2010-03-16,2009-12-16
-7l3f,2021-10-27,2020-12-17
-1l3t,2003-03-25,2002-03-01
-6l39,2020-09-16,2019-10-10
-3l3v,2010-03-31,2009-12-18
-7l34,2021-01-13,2020-12-17
-3l33,2010-09-22,2009-12-16
-1l3o,2002-03-13,2002-02-28
-6l3s,2020-10-28,2019-10-15
-6l36,2020-11-11,2019-10-09
-3l3l,2010-12-22,2009-12-17
-7l3v,2021-10-13,2020-12-18
-5l31,2016-11-09,2016-08-02
-6l3e,2019-10-23,2019-10-10
-4l3q,2013-07-24,2013-06-06
-1l3i,2002-11-27,2002-02-27
-6l3p,2020-10-14,2019-10-14
-7l35,2021-01-13,2020-12-17
-4l3k,2013-10-09,2013-06-06
-7l3l,2021-02-17,2020-12-17
-4l34,2013-10-30,2013-06-05
-7l3d,2021-10-27,2020-12-17
-4l3z,2014-06-11,2013-06-07
-7l3c,2021-10-27,2020-12-17
-4l35,2014-06-11,2013-06-05
-4l36,2013-12-11,2013-06-05
-4l3v,2013-09-18,2013-06-07
-2l31,2011-02-02,2010-08-30
-6l3y,2021-05-19,2019-10-15
-4l3x,2014-06-11,2013-06-07
-6l3u,2020-09-09,2019-10-15
-4l3l,2013-07-24,2013-06-06
-3l3o,2010-08-04,2009-12-17
-5l36,2016-09-07,2016-08-03
-1l3w,2002-04-26,2002-03-01
-4l3g,2013-09-04,2013-06-05
-5l3h,2016-06-15,2016-05-06
-6l38,2020-11-11,2019-10-09
-3l3d,2010-03-16,2009-12-16
-3l3n,2010-04-28,2009-12-17
-1l3f,2002-07-03,2002-02-26
-7l3q,2020-12-30,2020-12-18
-5l3u,2016-12-21,2016-05-24
-7l3p,2020-12-30,2020-12-18
-1l3r,2002-03-20,2002-02-28
-6l3h,2020-04-01,2019-10-11
-5l3q,2016-06-08,2016-05-24
-7l3h,2021-10-27,2020-12-17
-5l3c,2016-05-04,2016-04-06
-2l30,2011-02-02,2010-08-30
-3l3j,2010-03-16,2009-12-17
-7l3b,2021-10-27,2020-12-17
-3l3z,2010-01-12,2009-12-18
-3l31,2010-04-21,2009-12-16
-4l39,2013-10-02,2013-06-05
-5l3g,2016-09-21,2016-04-10
-5l30,2016-09-28,2016-08-02
-5l3v,2016-06-08,2016-05-24
-7l36,2021-10-13,2020-12-17
-7l3i,2021-10-27,2020-12-17
-1l3p,2003-02-28,2002-02-28
-5l3d,2016-05-04,2016-04-06
-5l3f,2016-09-21,2016-04-10
-4l3o,2014-02-19,2013-06-06
-3l3a,2010-04-28,2009-12-16
-7l31,2021-09-08,2020-12-17
-5l3e,2016-09-21,2016-04-10
-1l3e,2002-04-24,2002-02-26
-6l3w,2019-11-13,2019-10-15
-4l31,2013-10-30,2013-06-05
-5l3o,2017-03-01,2016-05-24
-7l3y,2021-02-03,2020-12-18
-7l3n,2021-02-03,2020-12-18
-3l37,2010-11-03,2009-12-16
-3l3q,2010-04-07,2009-12-17
-4l3a,2013-08-28,2013-06-05
-7l3j,2021-10-27,2020-12-17
-4l3y,2014-06-11,2013-06-07
-4l38,2014-07-16,2013-06-05
-5l3b,2016-05-04,2016-04-06
-6l3v,2020-09-09,2019-10-15
-6l3n,2019-12-18,2019-10-11
-4l3j,2013-07-24,2013-06-06
-4l3p,2013-06-19,2013-06-06
-4l33,2013-10-30,2013-06-05
-7l33,2021-08-11,2020-12-17
-6l37,2020-11-11,2019-10-09
-7l3m,2021-10-13,2020-12-18
-6l32,2019-10-23,2019-10-08
-1l3n,2002-05-08,2002-02-28
-1l3j,2002-07-03,2002-02-27
-7l3g,2021-10-27,2020-12-17
-3l3t,2010-09-22,2009-12-17
-1l3v,2003-03-25,2002-03-01
-6l3a,2020-09-16,2019-10-10
-6l3g,2019-12-11,2019-10-10
-7l3o,2020-12-30,2020-12-18
-5l3j,2016-08-31,2016-05-23
-5l3r,2016-06-08,2016-05-24
-8sbi,2023-04-12,2023-04-03
-6sbq,2020-03-25,2019-07-22
-1sb1,2004-06-08,2004-02-09
-7sbx,2022-05-04,2021-09-26
-2sbl,1995-02-27,1993-07-22
-7sb3,2022-05-04,2021-09-23
-6sbg,2020-07-15,2019-07-19
-6sbl,2020-08-26,2019-07-21
-8sb3,2023-04-19,2023-04-02
-3sbh,2012-04-11,2011-06-05
-6sbt,2019-10-30,2019-07-22
-5sbr,2021-09-22,2021-09-14
-3sbx,2011-06-15,2011-06-06
-1sbz,2004-10-26,2004-02-11
-6sb8,2020-12-09,2019-07-19
-1sbi,1995-12-07,1995-09-01
-7sbd,2022-08-10,2021-09-24
-7sb7,2022-03-02,2021-09-24
-6sbk,2020-08-26,2019-07-21
-7sb6,2022-10-05,2021-09-23
-8sb5,2023-04-19,2023-04-02
-8sbg,2023-08-23,2023-04-03
-5sby,2021-09-22,2021-09-14
-3sbe,2012-07-18,2011-06-03
-2sba,1998-12-09,1998-12-03
-1sbg,1994-10-15,1994-05-24
-1sbc,1988-07-16,1988-05-13
-5sbl,2021-09-22,2021-09-14
-6sbd,2020-07-15,2019-07-19
-8sb6,2023-07-26,2023-04-02
-6sbi,2020-03-25,2019-07-21
-7sby,2022-05-04,2021-09-26
-8sbv,2023-04-12,2023-04-04
-7sbu,2022-05-11,2021-09-25
-7sbn,2022-02-02,2021-09-25
-5sbt,2021-09-22,2021-09-14
-3sbr,2011-08-10,2011-06-06
-1sbd,1998-04-22,1995-07-13
-7sbk,2021-11-03,2021-09-25
-1sbw,1999-05-06,1999-04-29
-6sb2,2019-10-16,2019-07-18
-5sbk,2021-09-22,2021-09-14
-1sb3,2004-12-21,2004-02-10
-6sbe,2020-07-15,2019-07-19
-5sba,2021-12-08,2021-07-20
-3sb0,2012-11-07,2011-06-03
-1sbf,1998-04-22,1997-10-21
-3sbd,2012-07-18,2011-06-03
-5sbw,2021-09-22,2021-09-14
-8sbk,2023-12-06,2023-04-03
-7sbw,2022-05-04,2021-09-26
-5sbc,2021-12-08,2021-07-20
-3sb6,2011-09-21,2011-06-03
-7sbh,2022-03-16,2021-09-24
-8sbm,2023-11-08,2023-04-03
-8sbb,2023-04-26,2023-04-03
-3sb5,2011-09-21,2011-06-03
-5sbi,2023-02-15,2021-08-24
-7sbo,2021-11-03,2021-09-25
-7sbv,2022-05-04,2021-09-26
-3sb9,2011-09-21,2011-06-03
-6sbv,2020-06-10,2019-07-22
-7sbj,2021-10-27,2021-09-25
-3sbi,2012-04-11,2011-06-05
-1sbm,2005-06-14,2004-02-10
-8sbr,2023-05-24,2023-04-04
-8sbz,2023-04-12,2023-04-04
-7sbq,2021-11-03,2021-09-25
-6sbc,2020-07-15,2019-07-19
-6sbm,2020-08-26,2019-07-21
-5sbs,2021-09-22,2021-09-14
-8sb0,2023-04-19,2023-04-02
-5sbm,2021-09-22,2021-09-14
-7sbz,2022-10-05,2021-09-26
-8sbj,2023-07-19,2023-04-03
-1sbr,2004-10-05,2004-02-11
-5sbj,2023-02-15,2021-08-24
-6sbj,2020-02-26,2019-07-21
-8sb1,2023-04-19,2023-04-02
-7sbf,2022-04-20,2021-09-24
-5sbd,2021-12-08,2021-07-20
-4sbv,1985-07-17,1985-04-01
-6sbn,2020-02-26,2019-07-22
-5sb0,2022-06-29,2021-06-22
-7sbl,2021-11-10,2021-09-25
-8sbl,2023-12-06,2023-04-03
-5sb4,2022-04-27,2021-07-08
-5sbx,2021-09-22,2021-09-14
-3sbj,2012-01-11,2011-06-05
-5sb5,2022-04-27,2021-07-08
-3sbp,2011-08-10,2011-06-06
-6sbo,2019-11-27,2019-07-22
-6sbu,2020-06-10,2019-07-22
-1sbe,1998-04-22,1995-07-13
-5sbz,2021-09-22,2021-09-14
-3sbq,2011-08-10,2011-06-06
-5sbo,2021-09-22,2021-09-14
-8sbq,2024-04-17,2023-04-04
-3sbk,2011-09-07,2011-06-05
-6sb5,2020-02-05,2019-07-18
-1sbj,2004-11-23,2004-02-10
-8sb2,2023-04-19,2023-04-02
-8sbf,2024-04-17,2023-04-03
-7sb4,2022-05-04,2021-09-23
-5sbg,2023-02-15,2021-08-24
-7sbp,2021-11-03,2021-09-25
-5sbn,2021-09-22,2021-09-14
-7sb5,2022-05-04,2021-09-23
-5sbe,2021-12-08,2021-07-20
-3sb8,2011-09-21,2011-06-03
-7sbc,2021-10-06,2021-09-24
-5sb9,2021-12-08,2021-07-20
-8sb4,2023-04-19,2023-04-02
-5sbp,2021-09-22,2021-09-14
-1sby,2005-02-22,2004-02-11
-5sb2,2022-06-29,2021-06-22
-5sb6,2022-04-27,2021-07-08
-6sbp,2020-07-01,2019-07-22
-3sba,2011-09-21,2011-06-03
-5sb1,2022-06-29,2021-06-22
-6sb9,2020-08-26,2019-07-19
-3sb7,2011-09-21,2011-06-03
-6sbr,2020-03-25,2019-07-22
-7sbg,2022-08-10,2021-09-24
-5sb3,2022-04-27,2021-07-08
-8sby,2023-04-12,2023-04-04
-1sb9,2004-05-25,2004-02-10
-6sbh,2020-04-08,2019-07-20
-5sb8,2021-12-08,2021-07-20
-7sbr,2021-11-03,2021-09-25
-1sbn,1994-01-31,1991-12-20
-6sb3,2020-02-05,2019-07-18
-7sbs,2021-11-03,2021-09-25
-5sbv,2021-09-22,2021-09-14
-8sbc,2023-07-19,2023-04-03
-6sb7,2020-04-15,2019-07-19
-5sb7,2022-04-27,2021-07-08
-1sbh,1995-12-07,1995-09-01
-5sbu,2021-09-22,2021-09-14
-1sb8,2004-05-25,2004-02-10
-5sbq,2021-09-22,2021-09-14
-7sbt,2021-11-10,2021-09-25
-3sbf,2012-06-06,2011-06-04
-7sbm,2022-02-02,2021-09-25
-6sb0,2019-10-16,2019-07-18
-5sbb,2021-12-08,2021-07-20
-1v6d,2004-12-07,2003-11-28
-6v6v,2020-12-23,2019-12-06
-7v6a,2022-05-11,2021-08-20
-5v6i,2017-08-16,2017-03-16
-6v6w,2020-09-23,2019-12-06
-3v6h,2012-04-25,2011-12-19
-7v6x,2022-08-24,2021-08-20
-7v6y,2021-09-22,2021-08-20
-7v6k,2021-12-29,2021-08-20
-1v6i,2004-02-10,2003-12-01
-7v6z,2021-09-22,2021-08-20
-3v64,2012-04-25,2011-12-18
-7v6l,2021-12-29,2021-08-20
-5v68,2017-03-29,2017-03-16
-8v6k,2024-04-17,2023-12-01
-8v6h,2023-12-20,2023-12-01
-5v6q,2017-03-29,2017-03-17
-6v6o,2020-04-22,2019-12-05
-2v6a,2007-07-31,2007-07-14
-8v6l,2024-04-17,2023-12-01
-6v66,2020-04-22,2019-12-04
-6v6k,2020-04-22,2019-12-05
-4v68,2014-07-09,2008-12-11
-1v6q,2004-08-03,2003-12-03
-6v6z,2020-04-29,2019-12-06
-2v63,2007-07-31,2007-07-13
-3v61,2012-02-29,2011-12-18
-2v69,2007-07-31,2007-07-14
-7v6m,2022-02-09,2021-08-20
-6v6q,2020-11-11,2019-12-05
-3v6o,2012-03-14,2011-12-20
-3v6c,2012-12-19,2011-12-19
-6v6y,2020-05-27,2019-12-06
-2v60,2007-10-16,2007-07-12
-2v6k,2008-07-22,2007-07-19
-1v6u,2004-04-27,2003-12-04
-2v61,2007-10-16,2007-07-13
-5v69,2017-05-10,2017-03-16
-2v6o,2008-03-04,2007-07-19
-8v6i,2023-12-20,2023-12-01
-5v64,2017-06-28,2017-03-15
-3v6r,2012-02-01,2011-12-20
-2v6n,2008-07-01,2007-07-19
-7v6p,2021-12-29,2021-08-20
-3v66,2012-12-19,2011-12-18
-7v6j,2021-12-29,2021-08-20
-8v6n,2024-04-17,2023-12-01
-6v6g,2020-04-22,2019-12-05
-2v6f,2007-11-20,2007-07-18
-7v6d,2021-10-13,2021-08-20
-1v6l,2004-02-10,2003-12-01
-7v61,2022-06-22,2021-08-18
-6v63,2020-01-22,2019-12-04
-1v6x,2004-04-27,2003-12-04
-1v6v,2004-04-27,2003-12-04
-2v6g,2007-11-20,2007-07-18
-6v6s,2020-01-01,2019-12-05
-1v6m,2004-02-10,2003-12-02
-1v6o,2004-02-10,2003-12-02
-1v6p,2004-12-21,2003-12-03
-8v6o,2024-04-17,2023-12-01
-3v6k,2012-04-25,2011-12-20
-8v6m,2024-04-17,2023-12-01
-4v6b,2014-07-09,2009-06-19
-5v6u,2017-10-18,2017-03-17
-6v6l,2020-01-15,2019-12-05
-1v6a,2005-02-15,2003-11-28
-5v6m,2018-01-17,2017-03-17
-5v6y,2018-01-31,2017-03-17
-8v6g,2023-12-20,2023-12-01
-5v6f,2018-01-17,2017-03-16
-7v6f,2022-02-23,2021-08-20
-1v6j,2004-02-10,2003-12-01
-7v64,2022-08-24,2021-08-19
-2v64,2007-11-27,2007-07-13
-5v6a,2017-05-10,2017-03-16
-3v62,2012-02-29,2011-12-18
-1v6k,2004-02-10,2003-12-01
-6v65,2020-07-15,2019-12-04
-6v6u,2020-12-23,2019-12-06
-2v62,2007-08-21,2007-07-13
-4v62,2014-07-09,2008-01-17
-3v65,2012-04-25,2011-12-18
-2v6u,2008-07-22,2007-07-20
-5v6z,2018-03-21,2017-03-17
-6v6f,2020-07-15,2019-12-05
-8v6v,2024-03-20,2023-12-03
-5v6k,2018-01-31,2017-03-16
-8v6u,2024-05-29,2023-12-03
-2v67,2007-08-07,2007-07-13
-5v6n,2017-10-18,2017-03-17
-6v61,2019-12-25,2019-12-04
-1v6s,2003-12-23,2003-12-04
-3v6q,2012-02-15,2011-12-20
-8v6j,2023-12-20,2023-12-01
-7v63,2021-12-22,2021-08-19
-3v6s,2012-02-01,2011-12-20
-5v60,2017-07-26,2017-03-15
-5v67,2018-03-28,2017-03-16
-2v68,2007-08-07,2007-07-13
-7v6i,2022-02-09,2021-08-20
-3v6n,2012-01-04,2011-12-20
-6v64,2020-05-13,2019-12-04
-5v62,2017-07-26,2017-03-15
-2v6t,2008-07-22,2007-07-20
-1v6c,2004-12-28,2003-11-28
-6v6m,2020-12-09,2019-12-05
-3v6e,2012-12-19,2011-12-19
-4v69,2014-07-09,2008-12-11
-7v6h,2021-12-29,2021-08-20
-5v6s,2017-06-28,2017-03-17
-7v6g,2022-02-23,2021-08-20
-1v6n,2004-02-10,2003-12-02
-1v6w,2004-04-27,2003-12-04
-5v61,2017-07-26,2017-03-15
-5v6o,2017-10-18,2017-03-17
-1v6g,2004-06-01,2003-11-29
-6v62,2020-01-15,2019-12-04
-2v66,2007-11-27,2007-07-13
-3v6j,2012-04-25,2011-12-19
-6v6x,2020-12-09,2019-12-06
-7v62,2022-06-08,2021-08-19
-7v6c,2022-03-23,2021-08-20
-7v68,2022-05-11,2021-08-20
-1v67,2003-12-09,2003-11-27
-5v6x,2017-10-11,2017-03-17
-5v6v,2017-06-28,2017-03-17
-3v6i,2012-02-22,2011-12-19
-5qhc,2019-03-27,2018-05-15
-8qh4,2024-04-03,2023-09-06
-5qhn,2018-12-19,2018-05-18
-4qht,2014-07-16,2014-05-29
-6qha,2019-02-06,2019-01-16
-3qhr,2011-05-25,2011-01-26
-6qhw,2019-09-25,2019-01-17
-1qh8,1999-11-01,1999-05-11
-2qh0,2007-07-17,2007-06-29
-8qhc,2023-10-11,2023-09-07
-3qhn,2012-02-01,2011-01-26
-1qhi,1999-07-09,1999-05-12
-2qhb,2008-07-15,2007-07-02
-6qh0,2019-07-10,2019-01-14
-7qhh,2022-02-23,2021-12-12
-7qhs,2022-06-15,2021-12-14
-2qh1,2008-02-19,2007-06-29
-1qh1,1999-11-01,1999-05-10
-1qhg,1999-07-13,1999-05-14
-6qhx,2019-09-25,2019-01-17
-5qh9,2019-03-27,2018-05-15
-6qhp,2019-09-25,2019-01-17
-7qhw,2022-10-26,2021-12-14
-5qhf,2019-03-27,2018-05-15
-5qh7,2019-03-27,2018-05-15
-5qhr,2018-12-19,2018-05-18
-4qh4,2015-07-22,2014-05-26
-2qha,2008-05-20,2007-07-01
-5qhm,2018-12-19,2018-05-18
-6qhz,2019-09-25,2019-01-17
-6qhl,2020-05-13,2019-01-16
-1qhj,1999-07-21,1999-05-04
-1qhp,2000-05-31,1999-05-25
-7qhf,2023-09-27,2021-12-12
-6qh9,2019-02-06,2019-01-16
-1qho,2000-05-31,1999-05-25
-4qhi,2014-07-16,2014-05-28
-2qhw,2008-01-08,2007-07-03
-1qhz,2000-06-07,1999-06-02
-1qh6,2000-05-17,1999-05-11
-1qh5,1999-09-24,1999-05-11
-6qhu,2019-09-25,2019-01-17
-7qhv,2022-04-13,2021-12-14
-5qh4,2019-03-27,2018-05-15
-4qh1,2015-03-11,2014-05-26
-5qh0,2019-03-27,2018-05-15
-5qh8,2019-03-27,2018-05-15
-1qhw,1999-09-15,1999-03-26
-7qh9,2023-05-10,2021-12-10
-6qhv,2019-09-25,2019-01-17
-6qht,2019-09-25,2019-01-17
-7qhg,2021-12-22,2021-12-12
-5qhg,2019-03-27,2018-05-15
-6qhj,2019-09-11,2019-01-16
-6qho,2019-05-22,2019-01-17
-5qh5,2019-03-27,2018-05-15
-2qhx,2007-12-25,2007-07-03
-2qhu,2008-02-26,2007-07-02
-3qhw,2011-05-25,2011-01-26
-1qhh,1999-07-13,1999-05-14
-1qhu,1999-10-06,1999-05-27
-7qh8,2022-10-19,2021-12-10
-2qhz,2008-04-22,2007-07-03
-4qhf,2014-07-16,2014-05-28
-7qha,2022-12-21,2021-12-11
-6qhe,2019-11-27,2019-01-16
-5qha,2019-03-27,2018-09-21
-3qhc,2011-08-31,2011-01-25
-6qhg,2019-05-22,2019-01-16
-7qhe,2022-12-21,2021-12-12
-7qh0,2022-10-19,2021-12-10
-7qh1,2022-12-21,2021-12-10
-5qh6,2019-03-27,2018-05-15
-8qh7,2024-04-03,2023-09-06
-5qhz,2019-04-10,2018-05-21
-7qhn,2022-10-19,2021-12-13
-6qh7,2019-09-04,2019-01-15
-1qhx,2000-06-01,1999-05-31
-1qh0,2002-02-27,1999-05-10
-3qh2,2011-05-25,2011-01-25
-2qhs,2008-02-26,2007-07-02
-3qh0,2011-04-13,2011-01-25
-1qh7,2000-05-17,1999-05-11
-4qhp,2014-09-24,2014-05-28
-4qhy,2015-06-03,2014-05-30
-1qhd,2001-04-13,1999-04-29
-3qh1,2012-01-04,2011-01-25
-3qhb,2011-05-25,2011-01-25
-8qh6,2023-12-27,2023-09-06
-1qh4,1999-11-19,1999-05-11
-8qhl,2023-11-22,2023-09-08
-3qhq,2012-02-01,2011-01-26
-5qhj,2018-12-19,2018-05-18
-1qh3,1999-09-24,1999-05-10
-4qhz,2014-07-30,2014-05-30
-7qhz,2022-11-23,2021-12-14
-5qhx,2019-04-10,2018-05-21
-1qhq,2001-03-07,1999-05-25
-2qhn,2008-03-18,2007-07-02
-4qhj,2014-07-16,2014-05-28
-7qhm,2022-05-18,2021-12-13
-5qhl,2018-12-19,2018-05-18
-7qhk,2022-12-21,2021-12-13
-4qh5,2015-03-11,2014-05-26
-5qhi,2018-12-19,2018-05-18
-2qhm,2008-03-18,2007-07-02
-5qhq,2018-12-19,2018-05-18
-5qhh,2019-03-27,2018-05-15
-5qhk,2018-12-19,2018-05-18
-6qhq,2019-09-25,2019-01-17
-3qhx,2011-03-02,2011-01-26
-6qhy,2019-09-25,2019-01-17
-1qhb,2000-07-05,1999-05-11
-3qh8,2011-02-09,2011-01-25
-4qhc,2015-07-22,2014-05-28
-6qhs,2019-09-25,2019-01-17
-7qh2,2022-06-29,2021-12-10
-4qh6,2015-08-05,2014-05-27
-5qhb,2019-03-27,2018-05-15
-7qhb,2022-02-23,2021-12-11
-1qha,1999-11-10,1999-05-11
-2qhf,2008-07-15,2007-07-02
-5qhp,2018-12-19,2018-05-18
-4qhg,2014-07-16,2014-05-28
-4qhv,2015-06-10,2014-05-29
-5qhu,2019-04-10,2018-05-21
-2qh6,2008-03-18,2007-06-29
-5qhe,2019-03-27,2018-05-15
-7qhr,2022-06-08,2021-12-13
-7qh6,2022-03-02,2021-12-10
-1qhy,2000-06-07,1999-06-01
-6qhm,2020-05-13,2019-01-16
-5qh3,2019-03-27,2018-05-15
-8qh3,2024-03-27,2023-09-06
-4qhh,2014-07-16,2014-05-28
-7qho,2022-05-18,2021-12-13
-8qhq,2023-11-08,2023-09-09
-4qh3,2014-07-30,2014-05-26
-5qhv,2019-04-10,2018-05-21
-4qho,2015-06-03,2014-05-28
-5qh1,2019-03-27,2018-05-15
-8qhk,2024-04-03,2023-09-08
-4qhe,2014-11-12,2014-05-28
-7qhp,2022-07-20,2021-12-13
-2qhv,2008-02-26,2007-07-03
-3qho,2012-02-01,2011-01-26
-7qh7,2022-05-18,2021-12-10
-1qhc,1999-08-31,1999-05-12
-5qhs,2018-12-19,2018-05-18
-6qhk,2019-07-17,2019-01-16
-7qhd,2022-12-21,2021-12-12
-5qhw,2019-04-10,2018-05-21
-8qhr,2023-11-08,2023-09-09
-3qhd,2011-02-09,2011-01-25
-6qhb,2019-02-06,2019-01-16
-5qho,2018-12-19,2018-05-18
-6qhr,2019-05-22,2019-01-17
-7qhj,2022-12-21,2021-12-13
-4qhq,2014-06-18,2014-05-28
-3qh5,2012-01-04,2011-01-25
-2qhy,2008-04-22,2007-07-03
-6qhc,2019-02-06,2019-01-16
-2qhc,2008-07-22,2007-07-02
-8qhp,2023-11-29,2023-09-08
-3qhm,2012-02-01,2011-01-26
-1qhs,2000-06-01,1999-05-28
-7qhl,2022-07-06,2021-12-13
-4qh0,2014-11-19,2014-05-26
-8qhe,2023-10-11,2023-09-07
-6qh4,2019-02-27,2019-01-15
-6qh6,2019-09-04,2019-01-15
-5qhy,2019-04-10,2018-05-21
-4qh9,2014-11-12,2014-05-27
-5qh2,2019-03-27,2018-05-15
-1qhr,2000-05-31,1999-05-26
-5qht,2019-04-10,2018-05-21
-3gsg,2009-04-14,2009-03-26
-8gst,2023-02-08,2022-09-07
-3gsh,2009-12-15,2009-03-27
-4gsc,2013-08-28,2012-08-27
-2gsu,2006-08-01,2006-04-26
-8gs8,2023-05-10,2022-09-05
-7gsc,2024-01-24,2024-01-03
-1gsv,2002-02-14,2002-01-08
-3gsr,2009-08-04,2009-03-27
-8gsm,2023-09-13,2022-09-06
-7gs3,2024-02-14,2023-11-14
-5gsp,1998-03-18,1997-12-09
-7gs9,2024-01-24,2024-01-03
-5gs6,2016-10-05,2016-08-14
-3gsq,2009-08-04,2009-03-27
-7gsq,2024-01-24,2024-01-03
-4gsr,2013-02-27,2012-08-28
-4gsl,2012-11-14,2012-08-27
-6gsb,2018-10-03,2018-06-13
-8gsq,2023-06-14,2022-09-06
-6gsp,1998-03-18,1997-12-09
-1gs6,2002-02-14,2002-01-02
-3gsv,2009-08-04,2009-03-27
-1gsn,1998-05-27,1998-02-21
-3gs0,2009-07-28,2009-03-26
-6gsh,2019-01-16,2018-06-14
-2gsm,2006-10-10,2006-04-26
-5gs9,2016-09-28,2016-08-15
-4gsk,2012-11-14,2012-08-27
-8gsu,2023-03-08,2022-09-07
-3gss,1997-11-12,1996-10-29
-2gsi,2006-05-16,2006-04-26
-4gsn,2014-03-12,2012-08-28
-1gsk,2003-05-21,2002-01-08
-6gs0,2018-08-22,2018-06-13
-6gs6,2019-06-26,2018-06-13
-1gs4,2003-01-16,2001-12-27
-7gs1,2024-02-14,2023-11-14
-2gsl,2006-05-09,2006-04-26
-5gso,2017-05-31,2016-08-16
-1gs7,2002-02-14,2002-01-02
-6gsi,2019-01-16,2018-06-14
-1gsx,2002-02-14,2002-01-09
-4gsq,2013-02-27,2012-08-28
-4gs6,2013-01-23,2012-08-27
-7gsu,2024-01-24,2024-01-03
-7gsz,2024-01-24,2024-01-03
-3gso,2009-08-04,2009-03-27
-7gs2,2024-02-14,2023-11-14
-8gsw,2023-03-08,2022-09-07
-2gsa,1998-03-04,1997-02-26
-5gsn,2017-01-18,2016-08-16
-1gsj,2002-05-16,2002-01-07
-7gsi,2024-01-24,2024-01-03
-7gsj,2024-01-24,2024-01-03
-7gsn,2024-01-24,2024-01-03
-2gsh,2006-05-09,2006-04-26
-2gs7,2006-06-20,2006-04-25
-6gsn,2019-06-26,2018-06-14
-6gsv,1996-11-08,1996-01-26
-5gsz,2016-09-28,2016-08-18
-6gs4,2019-01-30,2018-06-13
-4gs8,2013-08-28,2012-08-27
-4gsm,2012-09-26,2012-08-28
-3gsx,2009-08-04,2009-03-27
-7gs7,2024-01-24,2024-01-03
-1gse,1995-09-15,1995-06-09
-6gs2,2018-09-05,2018-06-13
-3gsm,2009-06-30,2009-03-27
-7gsh,2024-01-24,2024-01-03
-5gs8,2017-07-12,2016-08-14
-2gsk,2006-06-13,2006-04-26
-5gsc,2017-08-30,2016-08-15
-4gsy,2012-10-24,2012-08-28
-2gst,1993-10-31,1993-06-07
-8gsj,2023-12-27,2022-09-06
-2gs9,2007-03-13,2006-04-25
-4gs9,2013-04-03,2012-08-27
-4gsx,2012-12-19,2012-08-28
-4gs7,2012-11-07,2012-08-27
-6gsj,2018-07-04,2018-06-14
-6gsy,1996-11-08,1996-01-26
-2gsr,1996-11-08,1996-03-21
-1gsw,2002-02-14,2002-01-09
-3gsu,2009-08-04,2009-03-27
-8gs6,2022-10-26,2022-09-05
-6gsq,2019-07-03,2018-06-15
-4gss,1998-01-28,1997-01-20
-6gsm,2019-07-31,2018-06-14
-5gsr,2017-04-26,2016-08-17
-2gsp,1998-08-12,1997-12-02
-2gsd,2006-05-09,2006-04-26
-4gs4,2012-10-17,2012-08-27
-7gsp,1998-03-18,1997-12-10
-6gsz,2018-11-14,2018-06-15
-1gs3,2003-01-23,2001-12-27
-2gsn,2006-08-01,2006-04-26
-7gsk,2024-01-24,2024-01-03
-7gs5,2024-02-14,2023-11-14
-6gsk,2018-07-04,2018-06-14
-1gsf,1995-09-15,1995-06-09
-5gsd,2017-08-09,2016-08-15
-6gsg,2018-09-19,2018-06-14
-7gsd,2024-01-24,2024-01-03
-5gsu,2017-02-15,2016-08-17
-1gss,1994-01-31,1992-05-28
-7gss,1998-09-16,1997-08-13
-2gsy,2006-07-18,2006-04-27
-4gsu,2013-02-27,2012-08-28
-4gsp,1998-08-12,1997-12-02
-7gs8,2024-01-24,2024-01-03
-3gsy,2009-06-30,2009-03-27
-5gsb,2017-07-12,2016-08-15
-6gs3,2019-06-26,2018-06-13
-5gs4,2017-08-30,2016-08-13
-5gsq,2017-06-28,2016-08-17
-3gs4,2009-07-28,2009-03-26
-8gs1,2023-09-06,2022-09-04
-6gsd,2018-10-17,2018-06-14
-2gsz,2007-03-20,2006-04-27
-5gst,1993-10-31,1993-07-20
-1gsq,1995-06-03,1995-01-09
-4gsf,2013-08-28,2012-08-27
-3gs2,2010-08-25,2009-03-26
-5gsw,2017-05-31,2016-08-17
-8gs2,2022-11-09,2022-09-04
-5gs0,2016-10-12,2016-08-13
-4gsz,2012-09-26,2012-08-28
-3gs7,2009-07-28,2009-03-26
-6gst,1996-11-08,1996-01-26
-1gsp,1998-02-25,1997-11-28
-3gsb,1999-08-17,1998-06-26
-6gss,1998-09-16,1997-08-13
-7gs4,2024-02-14,2023-11-14
-1gs8,2002-02-14,2002-01-02
-5gss,1998-09-16,1997-08-11
-5gsa,2017-02-01,2016-08-15
-2gs6,2006-06-20,2006-04-25
-3gs6,2009-06-30,2009-03-26
-3gsw,2009-08-04,2009-03-27
-1gsi,2002-03-28,2002-01-03
-8gsg,2023-03-15,2022-09-06
-6gsc,2018-10-03,2018-06-13
-4gsv,2012-09-26,2012-08-28
-2gse,2006-05-09,2006-04-26
-1gsu,1998-03-04,1997-09-02
-8gss,1998-09-16,1997-08-14
-1gsz,2003-01-16,2002-01-09
-3gst,1993-10-31,1993-06-07
-7gsf,2024-01-24,2024-01-03
-6gsx,1996-11-08,1996-01-26
-8gsr,2023-02-08,2022-09-07
-5gsm,2017-02-01,2016-08-16
-2gso,2006-08-01,2006-04-26
-2gss,1997-11-12,1996-10-29
-7gsx,2024-01-24,2024-01-03
-1gsy,1997-11-19,1996-10-25
-4gsa,1998-03-04,1997-02-26
-6gsu,1996-11-08,1996-01-26
-6gsw,1996-11-08,1996-01-26
-7gsg,2024-01-24,2024-01-03
-9gss,1998-09-16,1997-08-14
-7gs6,2024-02-14,2023-11-14
-3gsp,1998-08-12,1997-12-02
-2gsw,2006-05-09,2006-04-26
-6gs8,2019-07-31,2018-06-13
-4gs1,2013-09-11,2012-08-27
-1gsa,1996-06-20,1995-06-08
-7gs0,2024-02-14,2023-11-14
-7gse,2024-01-24,2024-01-03
-3gsd,2009-04-07,2009-03-26
-3gsn,2009-08-04,2009-03-27
-6gsl,2018-07-04,2018-06-14
-1gsl,1996-12-23,1996-06-15
-3gsi,2009-04-14,2009-03-27
-2gsq,1996-04-12,1995-04-14
-1gs5,2002-05-16,2001-12-28
-4gst,1993-10-31,1993-07-20
-7w6v,2022-11-09,2021-12-02
-1w62,2006-02-03,2004-08-12
-3w6d,2013-05-15,2013-02-14
-3w6o,2014-02-19,2013-02-17
-7w6c,2022-09-14,2021-12-01
-2w6d,2009-12-22,2008-12-18
-7w6u,2022-06-08,2021-12-02
-4w63,2015-09-09,2014-08-20
-1w6l,2005-10-26,2004-08-19
-6w6l,2020-09-02,2020-03-17
-4w6t,2015-02-18,2014-08-20
-1w61,2006-02-03,2004-08-11
-8w6i,2023-12-20,2023-08-29
-2w62,2009-01-27,2008-12-16
-5w6x,2018-12-19,2017-06-18
-7w6z,2022-09-07,2021-12-02
-2w63,2009-01-27,2008-12-16
-7w6d,2022-02-02,2021-12-01
-5w64,2017-07-26,2017-06-16
-4w6f,2015-02-18,2014-08-20
-2w6c,2009-04-07,2008-12-18
-5w65,2017-08-02,2017-06-16
-8w6j,2023-12-20,2023-08-29
-8w6v,2024-05-22,2023-08-29
-3w6c,2013-05-15,2013-02-14
-2w6t,2009-05-12,2008-12-19
-1w6c,2005-12-08,2004-08-17
-6w6q,2021-03-17,2020-03-17
-5w6t,2017-10-04,2017-06-16
-4w6e,2015-05-13,2014-08-20
-6w6g,2021-03-17,2020-03-16
-5w6d,2017-07-05,2017-06-16
-2w6q,2009-05-19,2008-12-18
-7w6e,2022-02-02,2021-12-01
-6w6n,2020-06-24,2020-03-17
-2w6o,2009-05-19,2008-12-18
-1w6o,2004-10-20,2004-08-20
-5w6e,2018-05-30,2017-06-16
-3w6y,2014-03-05,2013-02-27
-7w6l,2022-09-07,2021-12-01
-1w6u,2004-10-28,2004-08-24
-6w6j,2021-05-26,2020-03-17
-8w6h,2024-04-17,2023-08-28
-2w68,2008-12-30,2008-12-17
-7w6p,2022-09-28,2021-12-02
-5w6o,2018-02-14,2017-06-16
-5w6s,2018-10-24,2017-06-16
-4w6u,2015-02-18,2014-08-20
-1w6i,2006-07-05,2004-08-18
-2w6y,2009-12-22,2008-12-19
-2w67,2009-04-14,2008-12-17
-4w6b,2015-02-18,2014-08-20
-8w6n,2024-04-17,2023-08-29
-3w6x,2013-08-07,2013-02-25
-7w64,2022-11-09,2021-12-01
-3w6w,2013-06-19,2013-02-22
-2w6w,2009-04-28,2008-12-19
-4w6z,2014-09-03,2014-08-21
-6w6i,2021-05-26,2020-03-17
-5w67,2017-08-23,2017-06-16
-7w6j,2022-09-07,2021-12-01
-5w6u,2017-10-04,2017-06-16
-3w6z,2014-01-15,2013-02-27
-6w6w,2020-06-03,2020-03-17
-8w6g,2024-04-17,2023-08-28
-6w6s,2021-03-17,2020-03-17
-1w69,2004-08-26,2004-08-16
-6w6p,2020-10-14,2020-03-17
-8w6x,2023-09-13,2023-08-30
-2w6p,2009-05-19,2008-12-18
-7w66,2022-09-14,2021-12-01
-3w6f,2013-05-15,2013-02-14
-6w6r,2021-03-17,2020-03-17
-6w61,2020-03-25,2020-03-15
-5w6i,2017-10-04,2017-06-16
-2w6v,2009-04-28,2008-12-19
-1w6r,2004-11-25,2004-08-23
-7w6b,2022-06-01,2021-12-01
-1w6k,2004-10-29,2004-08-19
-8w6d,2024-04-17,2023-08-28
-4w65,2014-09-03,2014-08-20
-1w6y,2005-04-14,2004-08-25
-1w6h,2006-07-05,2004-08-18
-2w69,2009-02-03,2008-12-17
-2w6n,2009-05-19,2008-12-18
-2w6x,2009-12-22,2008-12-19
-5w6y,2017-10-11,2017-06-18
-1w6w,2005-10-26,2004-08-24
-7w61,2022-07-27,2021-12-01
-4w66,2014-09-03,2014-08-20
-7w6a,2022-09-07,2021-12-01
-6w6h,2021-05-26,2020-03-16
-4w6q,2015-07-15,2014-08-20
-5w6g,2017-12-20,2017-06-16
-2w66,2009-04-14,2008-12-17
-5w6k,2018-07-18,2017-06-16
-5w6p,2018-10-24,2017-06-16
-3w6p,2014-02-19,2013-02-17
-6w65,2020-10-07,2020-03-16
-5w6h,2018-10-24,2017-06-16
-5w69,2017-08-23,2017-06-16
-6w6d,2020-04-29,2020-03-16
-4w6d,2015-02-18,2014-08-20
-2w6m,2009-05-19,2008-12-18
-6w6y,2020-03-25,2020-03-18
-7w6y,2022-09-07,2021-12-02
-5w66,2017-07-26,2017-06-16
-1w6s,2004-12-21,2004-08-23
-5w6a,2017-08-23,2017-06-16
-5w6z,2018-12-19,2017-06-18
-8w6p,2023-12-20,2023-08-29
-1w6t,2005-08-22,2004-08-24
-5w6r,2017-10-04,2017-06-16
-5w6b,2018-12-12,2017-06-16
-1w6f,2005-02-23,2004-08-17
-1w6j,2004-10-29,2004-08-18
-7w6o,2022-09-14,2021-12-02
-6w6e,2021-05-26,2020-03-16
-2w65,2009-02-24,2008-12-17
-8w6o,2024-04-17,2023-08-29
-1w6m,2004-10-20,2004-08-19
-6w63,2020-03-25,2020-03-16
-3w6a,2014-02-19,2013-02-13
-8w6r,2023-12-20,2023-08-29
-3w68,2013-05-01,2013-02-11
-3w6i,2013-03-13,2013-02-14
-2w6u,2009-05-12,2008-12-19
-7w6x,2022-09-07,2021-12-02
-7w6f,2022-02-02,2021-12-01
-3w69,2013-06-05,2013-02-12
-1w6z,2004-11-10,2004-08-25
-4w67,2015-05-27,2014-08-20
-3w6u,2014-01-15,2013-02-22
-7w6g,2022-02-02,2021-12-01
-7w6m,2022-08-03,2021-12-02
-3w67,2013-05-01,2013-02-11
-7w6w,2022-12-07,2021-12-02
-3w6s,2013-07-17,2013-02-21
-3w6n,2014-02-19,2013-02-17
-7w6q,2022-09-14,2021-12-02
-7w62,2023-01-18,2021-12-01
-8w6c,2024-04-17,2023-08-28
-6w6z,2020-10-07,2020-03-18
-6w6t,2021-03-17,2020-03-17
-7w6i,2022-09-07,2021-12-01
-7w67,2022-09-07,2021-12-01
-3w6h,2013-03-13,2013-02-14
-7w6r,2022-06-08,2021-12-02
-2w6z,2009-05-19,2008-12-19
-1w6g,2005-12-08,2004-08-18
-1w6p,2004-10-20,2004-08-20
-2w6e,2009-10-27,2008-12-18
-7uqn,2023-03-01,2022-04-19
-5uqf,2017-03-01,2017-02-08
-4uqj,2014-08-13,2014-06-24
-3uqd,2012-11-28,2011-11-20
-3uq6,2012-10-31,2011-11-19
-5uqx,2017-10-25,2017-02-08
-5uqy,2017-03-01,2017-02-08
-6uqv,2020-05-13,2019-10-21
-8uqc,2024-01-17,2023-10-23
-3uqf,2012-03-14,2011-11-20
-7uqj,2023-02-01,2022-04-19
-3uqr,2012-11-21,2011-11-21
-7uqu,2023-05-03,2022-04-20
-1uqt,2003-12-12,2003-10-20
-3uqn,2011-12-07,2011-11-21
-7uqk,2023-02-01,2022-04-19
-5uqe,2017-05-24,2017-02-08
-1uqx,2004-04-28,2003-10-22
-3uq2,2012-05-23,2011-11-18
-5uqa,2018-02-21,2017-02-07
-3uqw,2012-11-21,2011-11-21
-7uqz,2023-03-15,2022-04-20
-8uq5,2023-11-15,2023-10-23
-3uqu,2012-11-21,2011-11-21
-5uql,2017-05-10,2017-02-08
-5uqu,2018-02-14,2017-02-08
-8uq3,2023-11-15,2023-10-23
-3uq4,2012-04-04,2011-11-19
-3uqb,2011-11-30,2011-11-19
-4uqp,2014-10-29,2014-06-24
-8uqo,2023-12-06,2023-10-24
-8uq4,2023-11-15,2023-10-23
-5uq8,2018-03-07,2017-02-07
-5uqh,2017-03-01,2017-02-08
-6uqs,2019-10-30,2019-10-21
-4uqr,2014-09-17,2014-06-24
-1uqu,2003-11-13,2003-10-20
-7uqm,2023-03-01,2022-04-19
-8uq2,2023-11-15,2023-10-23
-6uq3,2020-06-10,2019-10-18
-5uq0,2017-02-22,2017-02-05
-6uqg,2019-12-11,2019-10-19
-8uqn,2023-12-06,2023-10-24
-6uq2,2020-06-10,2019-10-18
-6uq0,2020-06-10,2019-10-18
-6uqe,2020-04-22,2019-10-18
-6uqd,2020-08-26,2019-10-18
-5uqd,2017-09-13,2017-02-07
-5uqz,2018-03-07,2017-02-08
-4uql,2014-10-29,2014-06-24
-7uqx,2022-09-28,2022-04-20
-4uq3,2014-09-17,2014-06-19
-6uqy,2020-05-13,2019-10-21
-5uqn,2017-05-10,2017-02-08
-7uq3,2022-12-21,2022-04-19
-4uqd,2015-06-24,2014-06-22
-3uq3,2012-01-18,2011-11-19
-4uqc,2015-06-24,2014-06-22
-7uq2,2023-02-08,2022-04-18
-8uqp,2024-05-29,2023-10-24
-6uqt,2019-10-30,2019-10-21
-4uqg,2014-12-03,2014-06-23
-6uqi,2020-10-28,2019-10-19
-1uqy,2003-12-18,2003-10-23
-7uq9,2023-02-01,2022-04-19
-7uqb,2023-03-15,2022-04-19
-6uqf,2019-12-11,2019-10-19
-8uqm,2024-05-29,2023-10-24
-3uqe,2012-11-21,2011-11-20
-7uqo,2023-03-01,2022-04-19
-4uqk,2014-08-13,2014-06-24
-8uql,2024-05-29,2023-10-24
-6uqq,2020-09-23,2019-10-21
-4uqs,2014-09-17,2014-06-24
-8uq9,2024-01-17,2023-10-23
-3uqa,2011-12-07,2011-11-19
-7uqw,2022-08-10,2022-04-20
-3uqy,2012-03-28,2011-11-21
-5uqw,2017-03-22,2017-02-08
-6uqx,2020-05-13,2019-10-21
-5uqg,2017-03-01,2017-02-08
-7uqi,2023-02-01,2022-04-19
-8uqz,2024-04-03,2023-10-25
-4uqa,2015-06-24,2014-06-22
-7uqa,2023-07-19,2022-04-19
-4uqq,2014-08-13,2014-06-24
-8uq8,2024-01-17,2023-10-23
-3uqo,2012-11-21,2011-11-21
-3uqg,2012-03-14,2011-11-20
-4uqv,2014-07-30,2014-06-25
-3uq8,2012-01-25,2011-11-19
-6uqk,2020-01-15,2019-10-20
-3uqp,2012-11-21,2011-11-21
-3uqv,2012-11-21,2011-11-21
-6uqr,2019-12-04,2019-10-21
-6uq1,2020-06-10,2019-10-18
-5uqm,2017-05-10,2017-02-08
-8uqv,2024-03-27,2023-10-24
-7uqy,2022-09-28,2022-04-20
-8uqa,2024-01-17,2023-10-23
-5uqv,2017-10-25,2017-02-08
-4uq6,2014-08-13,2014-06-20
-6uqo,2020-04-22,2019-10-21
-3uq0,2012-05-23,2011-11-18
-5uq9,2018-08-22,2017-02-07
-5uq6,2017-05-24,2017-02-06
-3uqx,2012-11-21,2011-11-21
-5uqp,2017-02-22,2017-02-08
-6uqw,2020-05-13,2019-10-21
-3uq9,2012-10-31,2011-11-19
-5uqi,2018-02-21,2017-02-08
-6uqc,2020-01-01,2019-10-18
-6uqu,2019-10-30,2019-10-21
-8uqy,2024-04-03,2023-10-25
-5uqt,2017-05-10,2017-02-08
-4uqh,2014-08-20,2014-06-23
-1uqw,2003-10-22,2003-10-22
-5uqr,2018-03-14,2017-02-08
-3uq5,2012-04-04,2011-11-19
-5uqk,2017-05-10,2017-02-08
-6uqn,2019-12-04,2019-10-21
-5uq7,2018-03-07,2017-02-07
-4uqo,2015-01-14,2014-06-24
-8uqb,2024-01-17,2023-10-23
-6uqz,2020-05-13,2019-10-21
-7uq1,2022-05-11,2022-04-18
-1uqz,2003-12-18,2003-10-24
-4uq2,2014-09-17,2014-06-19
-6bkw,2018-11-07,2017-11-09
-7bk3,2021-07-07,2021-01-15
-5bkg,2021-09-08,2021-03-19
-6bkm,2018-02-28,2017-11-09
-6bkg,2018-07-18,2017-11-08
-6bk2,2017-11-29,2017-11-07
-8bkd,2023-01-25,2022-11-09
-7bk1,2021-07-07,2021-01-15
-5bk4,2017-10-25,2017-09-12
-2bko,2006-06-28,2005-02-17
-5bkq,2021-12-15,2021-03-21
-3bkz,2008-04-22,2007-12-09
-1bkw,1998-07-22,1998-07-13
-9bkj,2024-05-22,2024-04-29
-3bki,2008-09-16,2007-12-06
-6bku,2017-11-29,2017-11-09
-6bkx,2018-07-25,2017-11-09
-8bk9,2023-08-09,2022-11-08
-6bkh,2018-11-07,2017-11-08
-3bkn,2008-01-22,2007-12-07
-3bkm,2008-04-15,2007-12-07
-2bkv,2005-03-09,2005-02-21
-9bkz,2024-05-08,2024-04-29
-4bkx,2013-07-03,2013-04-30
-3bk1,2008-01-22,2007-12-05
-4bk3,2013-07-24,2013-04-21
-5bk2,2018-01-17,2017-09-12
-1bkg,1999-07-22,1998-07-07
-3bk7,2007-12-25,2007-12-06
-9bkp,2024-06-05,2024-04-29
-9bkl,2024-06-05,2024-04-29
-5bkc,2019-06-12,2019-06-02
-7bkc,2021-09-29,2021-01-15
-6bkz,2018-07-25,2017-11-09
-7bko,2021-07-07,2021-01-16
-3bkj,2008-04-15,2007-12-06
-2bkw,2005-11-02,2005-02-21
-7bk6,2021-07-07,2021-01-15
-2bkt,2006-04-05,2005-02-18
-6bkc,2018-12-26,2017-11-08
-6bkj,2018-02-07,2017-11-08
-6bk5,2018-03-14,2017-11-07
-5bkb,2019-06-12,2019-06-02
-9bkt,2024-06-05,2024-04-29
-7bkn,2021-07-07,2021-01-16
-4bky,2013-08-21,2013-04-30
-3bkv,2008-01-08,2007-12-07
-6bkt,2018-02-28,2017-11-09
-7bkx,2021-12-22,2021-01-17
-1bk0,1999-01-13,1998-07-14
-3bkk,2008-06-10,2007-12-07
-4bkm,2013-12-25,2013-04-26
-4bk2,2013-07-24,2013-04-21
-7bka,2022-03-02,2021-01-15
-6bky,2018-07-25,2017-11-09
-2bk5,2005-02-14,2005-02-10
-4bkz,2013-08-21,2013-04-30
-1bky,1999-07-22,1998-07-13
-4bk7,2013-11-27,2013-04-22
-7bkg,2021-03-17,2021-01-15
-5bk3,2017-12-13,2017-09-12
-4bk8,2014-04-02,2013-04-22
-6bkk,2018-09-19,2017-11-08
-5bki,2022-09-21,2021-03-19
-8bk4,2023-09-06,2022-11-08
-1bks,1999-03-23,1998-07-10
-2bkh,2005-06-07,2005-02-16
-8bk1,2023-09-20,2022-11-08
-2bks,2006-04-05,2005-02-18
-1bkf,1996-08-01,1995-10-18
-7bk7,2021-07-07,2021-01-15
-1bka,1996-11-08,1996-04-15
-9bkk,2024-05-22,2024-04-29
-7bkv,2022-03-02,2021-01-17
-2bkb,2007-01-03,2005-02-14
-4bkr,2014-05-14,2013-04-29
-3bk5,2008-02-05,2007-12-05
-2bkz,2006-03-08,2005-02-23
-3bk0,2008-11-18,2007-12-05
-2bkn,2006-06-28,2005-02-17
-4bkq,2014-05-14,2013-04-29
-6bk8,2018-02-21,2017-11-07
-6bkl,2018-09-19,2017-11-08
-6bks,2018-02-28,2017-11-09
-6bkr,2018-02-28,2017-11-09
-4bku,2014-04-09,2013-04-29
-6bk0,2017-11-29,2017-11-07
-6bk1,2017-11-29,2017-11-07
-5bke,2019-06-12,2019-06-02
-5bkd,2019-06-12,2019-06-02
-6bkn,2018-02-28,2017-11-09
-3bkq,2008-09-09,2007-12-07
-3bk2,2008-01-22,2007-12-05
-6bka,2018-02-14,2017-11-08
-3bkl,2008-06-10,2007-12-07
-3bk9,2008-09-30,2007-12-06
-2bki,2005-06-07,2005-02-16
-7bkb,2021-09-29,2021-01-15
-8bk0,2022-11-16,2022-11-08
-8bka,2023-08-09,2022-11-08
-7bkd,2021-09-29,2021-01-15
-4bkp,2013-06-12,2013-04-29
-7bky,2022-03-02,2021-01-17
-1bkm,1997-07-07,1997-05-02
-4bkt,2013-11-27,2013-04-29
-8bkz,2023-08-09,2022-11-09
-8bk3,2023-11-22,2022-11-08
-2bkj,1999-09-10,1998-07-23
-6bkq,2018-02-28,2017-11-09
-7bkh,2021-06-09,2021-01-16
-1bkj,1999-01-13,1998-07-08
-6bkb,2018-12-26,2017-11-08
-3bkh,2008-01-08,2007-12-06
-7bk5,2021-07-07,2021-01-15
-1bkx,1998-03-18,1997-07-01
-7bk2,2021-07-07,2021-01-15
-5bkk,2022-09-21,2021-03-19
-8bkf,2023-05-03,2022-11-09
-6bkp,2018-02-28,2017-11-09
-7bkp,2021-11-17,2021-01-16
-1bk6,1999-01-13,1998-07-14
-6bkd,2018-12-26,2017-11-08
-1bk4,1998-07-22,1998-07-14
-4bkj,2013-05-22,2013-04-25
-7bke,2021-09-29,2021-01-15
-7bk4,2021-08-04,2021-01-15
-1bk9,1999-03-02,1998-07-16
-8bkb,2023-08-09,2022-11-08
-6bke,2018-11-07,2017-11-08
-7bku,2022-03-02,2021-01-17
-3bkc,2008-04-15,2007-12-06
-8bkn,2024-01-31,2022-11-09
-7bkq,2021-11-17,2021-01-17
-2bkl,2005-03-09,2005-02-16
-8bk5,2023-09-06,2022-11-08
-5bkf,2021-09-08,2021-03-19
-1bkc,1999-06-22,1998-04-23
-5bk7,2018-09-05,2018-01-27
-7bk9,2022-03-02,2021-01-15
-2bkp,2006-06-28,2005-02-18
-7bkw,2022-03-02,2021-01-17
-5bkl,2021-12-15,2021-03-20
-6bk3,2017-11-29,2017-11-07
-2bka,2005-02-21,2005-02-14
-4bks,2013-11-27,2013-04-29
-3bkt,2008-02-19,2007-12-07
-3bkb,2007-12-25,2007-12-06
-5bkn,2021-12-15,2021-03-20
-2bkk,2005-08-09,2005-02-16
-8bkh,2024-01-31,2022-11-09
-1bk5,1999-01-06,1998-07-14
-5bkj,2022-09-21,2021-03-19
-4bk1,2013-07-24,2013-04-21
-2bkm,2006-11-29,2006-02-08
-2bk9,2005-05-20,2005-02-14
-6bko,2018-02-28,2017-11-09
-2bk3,2005-02-14,2005-02-10
-2bkx,2005-03-09,2005-02-21
-5bk0,2017-12-13,2017-09-12
-2bku,2005-05-04,2005-02-21
-6bkf,2018-07-18,2017-11-08
-6bk7,2017-11-22,2017-11-07
-3bkf,2008-02-19,2007-12-06
-3bk8,2008-08-12,2007-12-06
-1bke,1999-01-13,1998-07-06
-2bk4,2005-02-14,2005-02-10
-6zmx,2020-07-22,2020-07-04
-2zm4,2008-10-14,2008-04-11
-2zmx,2009-04-07,2008-04-21
-4zm5,2016-03-23,2015-05-02
-7zmx,2023-05-10,2022-04-20
-2zmf,2008-04-29,2008-04-17
-6zmk,2020-08-05,2020-07-02
-7zme,2022-11-30,2022-04-19
-6zmt,2020-08-19,2020-07-03
-3zmj,2013-05-22,2013-02-11
-6zmj,2020-08-05,2020-07-02
-7zmj,2022-12-07,2022-04-19
-7zms,2022-07-13,2022-04-19
-4zmz,2016-09-07,2015-05-04
-7zmo,2022-06-22,2022-04-19
-4zmn,2016-09-07,2015-05-04
-3zme,2013-05-08,2013-02-07
-7zmw,2022-11-23,2022-04-19
-7zmn,2022-06-22,2022-04-19
-1zmc,2005-06-28,2005-05-10
-7zm4,2022-09-28,2022-04-19
-4zm3,2015-10-14,2015-05-02
-7zm5,2023-09-13,2022-04-19
-7zm1,2022-09-28,2022-04-19
-1zml,2006-05-09,2005-05-10
-7zmt,2022-06-22,2022-04-19
-7zm2,2022-09-28,2022-04-19
-3zmc,2014-02-26,2013-02-07
-4zma,2015-12-30,2015-05-02
-3zm8,2013-04-17,2013-02-06
-2zm8,2009-04-14,2008-04-14
-7zmf,2022-09-21,2022-04-19
-5zmf,2019-03-20,2018-04-03
-1zmj,2006-05-09,2005-05-10
-7zmp,2022-06-22,2022-04-19
-6zmi,2020-08-19,2020-07-02
-3zm9,2013-02-27,2013-02-06
-4zmo,2016-09-07,2015-05-04
-2zm7,2009-04-07,2008-04-14
-7zmg,2022-11-30,2022-04-19
-3zms,2013-06-12,2013-02-12
-3zmi,2013-05-22,2013-02-11
-7zmy,2023-05-10,2022-04-20
-3zmm,2013-04-17,2013-02-11
-3zmr,2014-01-15,2013-02-12
-1zm6,2005-06-21,2005-05-10
-6zme,2020-08-12,2020-07-02
-6zma,2020-09-02,2020-07-02
-6zmc,2020-09-02,2020-07-02
-1zmx,2005-05-24,2005-05-11
-3zmh,2013-05-22,2013-02-11
-6zmn,2020-08-26,2020-07-03
-5zmw,2019-04-03,2018-04-06
-5zmp,2019-02-06,2018-04-05
-6zmq,2021-05-19,2020-07-03
-4zmv,2016-09-07,2015-05-04
-1zm5,2006-04-25,2005-05-10
-4zml,2016-09-07,2015-05-04
-2zml,2008-07-29,2008-04-19
-3zml,2014-01-22,2013-02-11
-2zmz,2009-05-05,2008-04-21
-6zm6,2021-01-13,2020-07-01
-5zmu,2018-08-08,2018-04-06
-4zmw,2016-09-07,2015-05-04
-8zmu,2024-06-05,2024-05-23
-1zme,1998-09-16,1997-08-06
-4zmy,2016-09-07,2015-05-04
-7zm0,2022-09-14,2022-04-18
-7zmm,2022-06-22,2022-04-19
-7zmk,2023-03-01,2022-04-19
-3zmv,2013-06-12,2013-02-12
-5zm5,2019-02-27,2018-04-01
-5zm4,2018-07-18,2018-04-01
-8zm6,2024-06-05,2024-05-22
-3zmu,2013-06-12,2013-02-12
-3zmg,2013-05-01,2013-02-08
-2zmb,2008-06-24,2008-04-15
-6zm5,2021-01-13,2020-07-01
-3zmd,2013-02-20,2013-02-07
-1zms,2005-07-19,2005-05-10
-5zm7,2019-02-27,2018-04-01
-8zm5,2024-06-05,2024-05-22
-4zmp,2016-09-07,2015-05-04
-5zmm,2018-09-26,2018-04-04
-3zm4,2013-05-22,2013-02-05
-1zm9,2005-05-24,2005-05-10
-4zmj,2015-06-24,2015-05-04
-7zm7,2022-11-30,2022-04-19
-5zmy,2018-08-08,2018-04-06
-7zm8,2022-11-30,2022-04-19
-5zma,2019-06-05,2018-04-02
-4zm4,2015-10-14,2015-05-02
-4zmm,2016-05-04,2015-05-04
-1zmr,2006-05-02,2005-05-10
-6zmy,2020-07-15,2020-07-04
-7zmi,2022-12-28,2022-04-19
-2zmi,2008-09-02,2008-04-19
-6zm7,2020-07-29,2020-07-01
-5zm9,2019-01-02,2018-04-02
-4zmx,2016-09-07,2015-05-04
-4zmq,2016-09-07,2015-05-04
-6zmb,2020-09-02,2020-07-02
-5zml,2019-02-20,2018-04-04
-5zmo,2018-09-26,2018-04-04
-3zmp,2014-01-22,2013-02-12
-5zm3,2018-07-18,2018-04-01
-1zm7,2005-05-17,2005-05-10
-2zmj,2008-09-02,2008-04-19
-4zmi,2015-09-23,2015-05-04
-5zmd,2019-04-10,2018-04-02
-3zm5,2013-07-03,2013-02-05
-2zmd,2008-05-13,2008-04-16
-3zmk,2014-01-22,2013-02-11
-5zms,2018-10-17,2018-04-05
-1zm4,2005-05-24,2005-05-10
-4zme,2015-08-19,2015-05-03
-8zm4,2024-06-05,2024-05-22
-3zm6,2013-07-03,2013-02-05
-6zm0,2021-03-17,2020-07-01
-2zmh,2008-09-02,2008-04-18
-4zmr,2016-04-27,2015-05-04
-3zm7,2013-09-18,2013-02-05
-7zml,2022-06-22,2022-04-19
-3zmz,2013-06-12,2013-02-13
-6zm2,2021-04-21,2020-07-01
-2zmm,2008-10-07,2008-04-19
-7zmv,2022-06-22,2022-04-19
-1zm2,2005-05-24,2005-05-10
-2zmy,2009-05-05,2008-04-21
-1zmt,2005-10-04,2005-05-10
-2zm1,2008-10-14,2008-04-10
-2zm9,2009-04-14,2008-04-14
-4zmf,2015-08-19,2015-05-04
-1zmd,2005-06-28,2005-05-10
-3zmb,2014-02-26,2013-02-07
-4zm1,2016-03-23,2015-05-02
-6zmw,2020-09-23,2020-07-04
-2zm5,2009-04-14,2008-04-11
-6zm9,2021-02-24,2020-07-02
-7zmh,2022-11-30,2022-04-19
-5zmj,2019-04-17,2018-04-04
-5zmi,2019-04-10,2018-04-03
-2zmk,2008-07-29,2008-04-19
-1zm8,2005-06-21,2005-05-10
-7zmb,2022-11-30,2022-04-19
-6zmg,2021-02-24,2020-07-02
-6zmz,2020-09-30,2020-07-05
-4zmt,2016-09-07,2015-05-04
-2zm6,2009-04-14,2008-04-11
-3zmt,2013-06-12,2013-02-12
-4zmh,2016-05-04,2015-05-04
-6zmu,2020-10-21,2020-07-03
-2zma,2009-04-07,2008-04-14
-7zmq,2022-06-22,2022-04-19
-1zmn,2006-05-09,2005-05-10
-4zmc,2015-09-30,2015-05-02
-2zmn,2008-07-29,2008-04-19
-4zm6,2015-12-09,2015-05-02
-6zmp,2020-12-23,2020-07-03
-7zmu,2022-11-23,2022-04-19
-4zms,2016-04-27,2015-05-04
-5zmv,2018-12-12,2018-04-06
-1zmg,2005-12-20,2005-05-10
-4zm9,2016-02-17,2015-05-02
-5zm0,2018-07-25,2018-03-31
-1zm1,2006-05-10,2005-05-10
-3zmq,2014-01-22,2013-02-12
-2zm3,2008-06-10,2008-04-10
-7zmr,2022-06-22,2022-04-19
-3zmo,2013-05-15,2013-02-11
-6zmd,2021-04-14,2020-07-02
-6zmo,2020-08-19,2020-07-03
-5zmq,2018-10-17,2018-04-05
-4zmg,2016-05-04,2015-05-04
-2awy,2006-08-15,2005-09-02
-5aw9,2015-09-02,2015-07-01
-6awq,2017-10-25,2017-09-06
-5awp,2015-09-09,2015-07-08
-1awq,1998-03-18,1997-10-04
-2awx,2006-08-29,2005-09-02
-8aw1,2023-09-06,2022-08-29
-1awi,1998-10-28,1997-10-02
-8awg,2023-09-20,2022-08-29
-2awh,2006-02-14,2005-09-01
-5awm,2015-08-05,2015-07-06
-8aws,2023-05-24,2022-08-30
-8awx,2023-05-24,2022-08-30
-7awm,2021-10-13,2020-11-08
-7awt,2021-09-15,2020-11-09
-4awe,2012-10-31,2012-06-01
-8aw2,2024-03-06,2022-08-29
-6awi,2018-09-12,2017-09-05
-5aw3,2015-09-02,2015-07-01
-6awz,2018-09-12,2017-09-06
-4awy,2012-06-20,2012-06-06
-2awz,2006-01-24,2005-09-02
-1aw3,1998-02-04,1997-10-09
-7aw7,2022-04-13,2020-11-06
-3aw6,2011-03-30,2011-03-11
-5aw4,2015-09-02,2015-07-01
-3awv,2011-06-29,2011-03-26
-7awg,2021-09-29,2020-11-08
-6awf,2017-12-06,2017-09-05
-6awj,2018-09-12,2017-09-05
-3aw5,2011-06-08,2011-03-10
-4aw7,2012-07-25,2012-06-01
-7aw5,2021-07-21,2020-11-06
-7awd,2020-11-25,2020-11-06
-5awv,2015-08-19,2015-07-09
-3aw0,2011-12-14,2011-03-09
-2awl,2006-04-18,2005-09-01
-1aw1,1998-01-28,1997-10-09
-1awr,1998-03-18,1997-10-04
-5aw7,2015-09-02,2015-07-01
-3awu,2011-06-29,2011-03-26
-7aw0,2021-03-03,2020-11-06
-8awf,2023-05-24,2022-08-29
-5awh,2016-07-06,2015-07-03
-7aww,2020-12-02,2020-11-09
-5awq,2015-09-09,2015-07-08
-3awy,2011-06-29,2011-03-26
-2aw2,2005-09-27,2005-08-31
-7awf,2021-04-21,2020-11-07
-4aw5,2012-08-01,2012-05-31
-3awq,2011-06-29,2011-03-25
-5aw2,2015-09-02,2015-07-01
-2aw3,2005-09-13,2005-08-31
-5awc,2016-07-20,2015-07-03
-6awg,2018-09-12,2017-09-05
-2aww,2006-08-29,2005-09-02
-4awi,2013-05-01,2012-06-03
-8awh,2023-05-03,2022-08-29
-8aw9,2023-05-24,2022-08-29
-4awd,2012-07-25,2012-06-01
-4awp,2012-08-29,2012-06-05
-2aw9,2006-08-22,2005-08-31
-1aw6,1998-04-15,1997-10-10
-5awr,2016-07-06,2015-07-08
-3awj,2011-08-31,2011-03-23
-7awx,2021-03-17,2020-11-09
-2awn,2005-12-13,2005-09-01
-6aw7,2018-09-12,2017-09-05
-5awg,2015-11-11,2015-07-03
-4aws,2013-06-26,2012-06-05
-4awb,2013-06-26,2012-06-01
-8awd,2023-05-24,2022-08-29
-7awc,2020-11-25,2020-11-06
-1awb,1998-01-14,1997-10-01
-7awv,2022-02-02,2020-11-09
-4aw0,2012-10-03,2012-05-30
-3awe,2011-05-04,2011-03-19
-7aw4,2021-03-03,2020-11-06
-4awm,2012-08-22,2012-06-04
-7awn,2021-10-13,2020-11-08
-3awp,2011-06-29,2011-03-25
-3awz,2011-06-29,2011-03-26
-8awc,2023-05-24,2022-08-29
-2awm,2006-04-18,2005-09-01
-7awl,2021-10-13,2020-11-08
-4aw8,2013-06-19,2012-06-01
-8awy,2023-05-24,2022-08-30
-6awa,2017-10-04,2017-09-05
-2aw0,1998-01-14,1997-10-08
-8awi,2023-03-01,2022-08-29
-4awf,2012-08-22,2012-06-03
-8awz,2023-03-01,2022-08-30
-1awu,1998-03-18,1997-10-05
-1aws,1998-03-18,1997-10-04
-4awn,2013-01-09,2012-06-04
-5aw0,2015-09-02,2015-07-01
-2awj,2006-04-18,2005-09-01
-7awp,2021-10-13,2020-11-08
-4awo,2012-08-29,2012-06-05
-6aww,2018-09-12,2017-09-06
-4aw9,2013-06-26,2012-06-01
-7awu,2020-12-02,2020-11-09
-6aw4,2018-09-12,2017-09-05
-3awm,2011-06-29,2011-03-25
-6aw5,2018-09-12,2017-09-05
-3aww,2011-06-29,2011-03-26
-5awz,2015-08-26,2015-07-10
-4awu,2013-06-26,2012-06-05
-4aw2,2012-06-20,2012-05-30
-7aw6,2020-12-16,2020-11-06
-4aw1,2012-10-03,2012-05-30
-1aw9,1998-10-28,1997-10-13
-3awn,2011-06-15,2011-03-25
-8awe,2023-05-24,2022-08-29
-5aw1,2015-09-02,2015-07-01
-4awz,2012-06-20,2012-06-06
-1awp,1998-10-28,1997-10-03
-3awx,2011-06-29,2011-03-26
-5awa,2016-07-20,2015-07-03
-7awr,2020-12-02,2020-11-09
-4awh,2012-08-22,2012-06-03
-5aw6,2015-09-02,2015-07-01
-7aw1,2021-03-03,2020-11-06
-6awx,2018-09-12,2017-09-06
-7awq,2021-10-13,2020-11-08
-7awh,2021-09-29,2020-11-08
-8awv,2023-05-24,2022-08-30
-5awu,2016-07-06,2015-07-08
-7aws,2020-12-02,2020-11-09
-4awa,2013-06-26,2012-06-01
-5aw8,2015-09-02,2015-07-01
-4awq,2012-08-29,2012-06-05
-3awh,2012-04-18,2011-03-22
-4awg,2012-08-22,2012-06-03
-8aw7,2022-12-28,2022-08-29
-1awv,1998-03-18,1997-10-05
-4awx,2013-03-06,2012-06-06
-3aw9,2012-02-29,2011-03-15
-7awi,2021-09-29,2020-11-08
-6awr,2018-09-12,2017-09-06
-8aw8,2023-05-24,2022-08-29
-6awh,2018-09-12,2017-09-05
-5awb,2015-09-23,2015-07-03
-6awo,2017-10-25,2017-09-06
-8aw5,2023-09-06,2022-08-29
-1awt,1998-03-18,1997-10-05
-5aws,2016-07-06,2015-07-08
-2aw1,2006-07-04,2005-08-31
-8aww,2023-07-12,2022-08-30
-7aw3,2021-03-03,2020-11-06
-2awo,2005-12-13,2005-09-01
-6awe,2018-09-12,2017-09-05
-4aw6,2012-07-25,2012-05-31
-6awt,2018-09-12,2017-09-06
-7aw2,2021-03-03,2020-11-06
-6awu,2018-09-12,2017-09-06
-8awb,2023-05-24,2022-08-29
-2aw6,2005-12-06,2005-08-31
-5awt,2016-07-06,2015-07-08
-3aws,2011-06-29,2011-03-26
-4awj,2012-11-14,2012-06-04
-6aw9,2018-09-12,2017-09-05
-6awp,2017-10-25,2017-09-06
-1awf,1998-10-28,1997-10-02
-2awk,2006-04-18,2005-09-01
-5aw5,2015-09-02,2015-07-01
-3aw7,2011-03-30,2011-03-11
-5awj,2015-11-18,2015-07-04
-4aw3,2012-09-05,2012-05-30
-8awu,2023-05-24,2022-08-30
-3awt,2011-06-29,2011-03-26
-6awn,2017-10-25,2017-09-06
-6awv,2018-09-12,2017-09-06
-8awr,2024-03-13,2022-08-30
-4awk,2012-08-29,2012-06-04
-5awk,2015-11-18,2015-07-04
-6awy,2018-09-12,2017-09-06
-7awe,2021-06-09,2020-11-06
-8aw0,2023-08-09,2022-08-28
-6aws,2018-09-12,2017-09-06
-3awo,2011-06-15,2011-03-25
-8awk,2024-03-13,2022-08-30
-1aw5,1998-10-21,1997-10-09
-1awh,1998-10-28,1997-10-02
-5awd,2015-09-23,2015-07-03
-3awd,2012-02-01,2011-03-18
-3awi,2011-06-01,2011-03-23
-3aw8,2012-04-11,2011-03-15
-4awt,2013-06-26,2012-06-05
-6aw8,2018-09-12,2017-09-05
-8aw3,2022-11-16,2022-08-29
-5awi,2015-10-21,2015-07-03
-4at1,1990-10-15,1990-04-26
-7atf,2021-03-03,2020-10-30
-8ats,2023-09-20,2022-08-24
-1at3,1998-10-14,1997-08-16
-4at2,2012-08-01,2012-05-03
-1at6,1998-02-25,1997-08-19
-8atv,2023-08-30,2022-08-24
-4atf,2012-07-25,2012-05-06
-7atv,2021-08-04,2020-10-31
-2atq,2006-05-09,2005-08-25
-4atu,2012-09-26,2012-05-09
-8at8,2022-12-28,2022-08-22
-3at5,2011-04-20,2010-12-26
-3aty,2011-05-04,2011-01-26
-4atq,2012-10-10,2012-05-09
-4atb,2012-08-01,2012-05-05
-7at5,2021-08-04,2020-10-29
-8atw,2023-08-30,2022-08-24
-8atr,2023-09-20,2022-08-24
-6ati,2017-09-13,2017-08-29
-8at1,1990-10-15,1989-09-22
-2atf,2005-10-18,2005-08-24
-4aty,2012-08-22,2012-05-11
-3atu,2011-12-28,2011-01-13
-2atv,2005-10-18,2005-08-26
-3at9,2011-10-19,2010-12-28
-7atw,2021-08-11,2020-11-01
-6atk,2017-12-06,2017-08-29
-2at0,2006-08-22,2005-08-24
-8atp,2023-09-20,2022-08-23
-8at0,2024-03-06,2022-08-22
-3att,2011-08-03,2011-01-13
-2atl,2006-01-10,2005-08-25
-7atk,2021-10-06,2020-10-30
-6atb,2018-09-12,2017-08-28
-1at1,1990-10-15,1989-09-22
-3atr,2011-05-04,2011-01-12
-2ats,2006-09-19,2005-08-26
-7atx,2021-08-11,2020-11-01
-6atz,2017-09-20,2017-08-29
-2at9,1999-04-27,1998-12-17
-8att,2023-08-30,2022-08-24
-8ati,2023-08-23,2022-08-23
-4at5,2012-08-22,2012-05-03
-7atn,2021-12-01,2020-10-30
-2atz,2005-10-11,2005-08-26
-6at0,2017-12-06,2017-08-27
-2at1,1990-10-15,1989-09-22
-6ate,2019-02-27,2017-08-28
-3atb,2011-10-19,2010-12-28
-7ate,2021-12-01,2020-10-30
-6att,2018-04-25,2017-08-29
-3at3,2011-11-09,2010-12-23
-4at9,2012-08-01,2012-05-05
-1ats,1993-10-31,1993-08-09
-3atk,2011-08-24,2011-01-05
-7atj,2000-01-14,1999-04-26
-6at1,1990-10-15,1990-04-26
-4atx,2012-09-26,2012-05-10
-2ato,2006-08-29,2005-08-25
-3at8,2011-10-19,2010-12-28
-8aty,2023-07-12,2022-08-24
-1atp,1993-04-15,1993-01-08
-8atb,2023-11-29,2022-08-22
-8atn,2023-09-06,2022-08-23
-4atj,2002-10-02,1999-04-19
-1at5,1998-02-25,1997-08-18
-3atl,2011-08-24,2011-01-05
-2ati,2006-08-25,2005-08-25
-1atn,1992-07-15,1991-03-08
-4at8,2012-08-01,2012-05-05
-3atz,2012-02-01,2011-01-26
-4at3,2012-08-22,2012-05-03
-3atj,1999-04-28,1998-12-16
-3atn,2012-03-07,2011-01-06
-7atd,2021-03-03,2020-10-29
-3atg,2012-01-18,2011-01-04
-8atf,2022-12-14,2022-08-23
-7at8,2020-12-09,2020-10-29
-2atj,1998-01-28,1997-08-19
-3at1,1990-10-15,1989-09-22
-6at3,2018-08-29,2017-08-27
-6ato,2018-09-12,2017-08-29
-3ata,2011-10-19,2010-12-28
-2at3,2006-08-22,2005-08-24
-7ati,2021-02-17,2020-10-30
-8atz,2023-07-12,2022-08-24
-7at4,2021-03-03,2020-10-28
-4atp,2012-10-10,2012-05-09
-8ate,2023-09-06,2022-08-23
-6atj,2000-01-14,1999-04-23
-7ato,2021-08-11,2020-10-30
-7at3,2021-03-03,2020-10-28
-3ato,2012-03-07,2011-01-06
-7at1,1990-10-15,1989-09-22
-2atx,2005-09-13,2005-08-26
-2ata,2006-07-11,2005-08-24
-6atr,2018-09-12,2017-08-29
-6at2,2018-08-29,2017-08-27
-1atl,1995-10-15,1995-05-26
-5at1,1990-10-15,1990-04-26
-3atq,2011-05-04,2011-01-12
-8atl,2023-09-06,2022-08-23
-1atk,1998-02-04,1996-12-19
-8atu,2023-02-15,2022-08-24
-7at9,2021-08-04,2020-10-29
-3ati,2011-08-24,2011-01-05
-8atx,2023-02-15,2022-08-24
-2atc,1982-12-07,1982-03-24
-2at5,2006-08-22,2005-08-24
-7ats,2020-11-25,2020-10-30
-1atr,1993-10-31,1993-08-09
-3atw,2011-12-14,2011-01-20
-3ate,2011-10-19,2010-12-28
-2atp,2005-12-27,2005-08-25
-6atg,2018-09-12,2017-08-29
-8at9,2023-09-20,2022-08-22
-2atk,2006-03-07,2005-08-25
-2at6,2006-08-22,2005-08-24
-4at4,2012-08-22,2012-05-03
-4atl,2013-01-30,2012-05-08
-8atc,1990-10-15,1989-08-25
-7ath,2021-10-06,2020-10-30
-3at6,2011-04-20,2010-12-26
-3atm,2011-08-24,2011-01-05
-3atf,2011-10-19,2010-12-28
-3atd,2011-10-19,2010-12-28
-3ats,2011-08-03,2011-01-13
-7atu,2020-12-23,2020-10-30
-4ate,2012-07-25,2012-05-06
-3atp,2011-10-19,2011-01-07
-1atj,1998-02-04,1997-08-14
-7atp,2021-08-18,2020-10-30
-8atj,2022-11-30,2022-08-23
-3atv,2011-12-28,2011-01-13
-6atf,2017-09-13,2017-08-29
-3at4,2011-11-09,2010-12-23
-7at6,2021-11-24,2020-10-29
-2ath,2006-08-25,2005-08-25
-7atq,2021-03-03,2020-10-30
-9atc,1999-07-26,1998-06-26
-4at0,2012-08-01,2012-05-03
-2ate,2006-08-29,2005-08-24
-7atm,2021-08-11,2020-10-30
-1at9,1998-09-16,1997-08-20
-4att,2013-05-22,2012-05-09
-3ath,2012-01-18,2011-01-05
-8wqm,2024-03-13,2023-10-11
-2wq6,2010-02-23,2009-08-14
-3wqm,2014-02-26,2014-01-28
-2wq8,2010-09-01,2009-08-14
-1wqa,2005-10-04,2004-09-24
-4wq0,2015-10-28,2014-10-21
-6wq7,2020-06-24,2020-04-28
-3wqo,2014-07-09,2014-01-28
-4wqb,2015-02-18,2014-10-21
-4wqu,2015-01-28,2014-10-22
-7wqg,2022-08-31,2022-01-25
-3wqu,2014-10-08,2014-02-01
-6wq8,2020-06-24,2020-04-28
-5wqi,2017-07-26,2016-11-27
-4wq9,2015-02-18,2014-10-21
-7wqr,2023-01-04,2022-01-25
-4wqc,2015-02-18,2014-10-21
-7wqt,2022-05-25,2022-01-26
-1wqn,1998-07-01,1998-02-09
-6wqz,2020-07-08,2020-04-29
-8wqe,2024-04-03,2023-10-11
-5wqu,2017-12-06,2016-11-28
-3wqy,2014-06-18,2014-02-05
-3wqf,2015-01-28,2014-01-25
-1wq3,2005-01-25,2004-09-20
-4wqd,2015-02-18,2014-10-21
-2wqn,2009-12-08,2009-08-24
-2wqq,2009-10-27,2009-08-25
-3wqe,2015-01-28,2014-01-25
-5wq6,2017-02-15,2016-11-23
-4wqa,2015-02-18,2014-10-21
-4wq8,2015-02-18,2014-10-21
-6wqp,2020-11-18,2020-04-29
-7wqk,2023-08-02,2022-01-25
-2wqb,2009-11-03,2009-08-18
-6wqy,2020-11-18,2020-04-29
-2wq5,2010-03-23,2009-08-13
-7wqy,2023-03-01,2022-01-26
-6wqi,2021-04-21,2020-04-28
-6wqx,2021-02-17,2020-04-29
-5wqg,2017-07-26,2016-11-26
-1wqf,2005-02-22,2004-09-28
-7wqb,2023-08-02,2022-01-25
-6wqb,2021-11-10,2020-04-28
-3wqn,2014-02-26,2014-01-28
-5wqf,2017-07-26,2016-11-26
-4wq1,2015-06-10,2014-10-21
-7wqj,2022-08-24,2022-01-25
-2wqf,2010-06-30,2009-08-20
-4wqm,2015-09-09,2014-10-22
-3wqr,2014-11-26,2014-01-31
-6wq1,2021-05-05,2020-04-28
-8wqa,2024-04-03,2023-10-11
-3wqa,2015-03-04,2014-01-24
-1wq1,1998-07-15,1997-07-03
-8wqf,2024-04-03,2023-10-11
-5wq0,2017-03-22,2016-11-22
-3wq6,2014-04-23,2014-01-22
-6wq4,2020-06-24,2020-04-28
-3wqw,2014-05-28,2014-02-03
-1wq4,2005-01-25,2004-09-20
-5wqa,2017-02-22,2016-11-24
-8wq9,2024-04-03,2023-10-11
-4wq2,2015-09-02,2014-10-21
-4wqe,2015-02-18,2014-10-21
-3wq7,2014-07-02,2014-01-23
-3wql,2014-02-19,2014-01-28
-4wqq,2015-04-29,2014-10-22
-4wq7,2015-02-18,2014-10-21
-6wqs,2021-04-21,2020-04-29
-7wq3,2022-04-20,2022-01-24
-6wq5,2020-06-24,2020-04-28
-1wqm,1998-07-01,1998-02-09
-5wqj,2017-09-06,2016-11-27
-6wq3,2020-05-06,2020-04-28
-8wqh,2024-04-03,2023-10-11
-8wqc,2024-04-03,2023-10-11
-4wqt,2015-02-18,2014-10-22
-7wql,2022-08-31,2022-01-25
-7wqq,2023-01-25,2022-01-25
-2wqz,2009-09-08,2009-08-28
-1wqr,1998-07-01,1998-02-09
-6wq9,2020-06-24,2020-04-28
-2wqd,2009-10-13,2009-08-19
-7wqw,2022-10-26,2022-01-26
-2wqp,2009-09-15,2009-08-25
-6wqw,2021-04-28,2020-04-29
-7wq9,2023-08-02,2022-01-25
-3wqv,2014-05-28,2014-02-03
-7wqx,2022-10-26,2022-01-26
-6wqa,2020-11-18,2020-04-28
-2wqo,2009-12-08,2009-08-24
-3wq1,2015-02-25,2014-01-21
-4wqf,2015-01-28,2014-10-21
-5wqk,2017-09-06,2016-11-27
-7wqh,2022-08-24,2022-01-25
-6wqt,2021-04-21,2020-04-29
-3wqt,2014-10-08,2014-02-01
-7wqm,2023-01-04,2022-01-25
-5wqh,2017-07-26,2016-11-26
-5wqc,2017-11-29,2016-11-25
-3wqz,2014-06-18,2014-02-05
-6wq6,2021-04-21,2020-04-28
-5wql,2017-11-22,2016-11-27
-2wqy,2010-08-25,2009-08-27
-3wqs,2014-11-26,2014-01-31
-3wqd,2015-01-28,2014-01-25
-3wqc,2015-01-28,2014-01-25
-3wq0,2015-02-25,2014-01-21
-4wqr,2015-06-10,2014-10-22
-3wqh,2015-07-15,2014-01-27
-3wqj,2014-10-15,2014-01-27
-2wqm,2009-12-08,2009-08-24
-8wqb,2024-04-03,2023-10-11
-2wq4,2010-01-12,2009-08-13
-4wql,2014-11-12,2014-10-22
-5wq2,2017-11-29,2016-11-22
-3wqq,2014-11-26,2014-01-31
-4wq5,2015-01-28,2014-10-21
-3wq4,2014-04-23,2014-01-22
-3wqg,2015-01-28,2014-01-25
-7wq0,2022-04-27,2022-01-24
-4wqj,2015-02-18,2014-10-22
-1wqq,1998-07-01,1998-02-09
-4wqp,2015-01-14,2014-10-22
-2wqt,2010-01-19,2009-08-27
-1wqw,2005-10-04,2004-10-04
-6wqe,2020-07-22,2020-04-28
-2wqe,2009-09-29,2009-08-20
-1wqo,1998-07-01,1998-02-09
-2wqs,2010-02-16,2009-08-27
-4wq4,2015-01-28,2014-10-21
-7wqs,2023-01-04,2022-01-26
-7wqa,2023-03-22,2022-01-25
-1wqv,2005-10-02,2004-10-02
-6wqh,2021-06-09,2020-04-28
-3wq5,2014-04-23,2014-01-22
-4wqs,2015-02-18,2014-10-22
-4wqy,2015-01-28,2014-10-22
-4wq6,2015-02-11,2014-10-21
-3wqp,2015-02-04,2014-01-29
-1wqs,2005-10-04,2004-10-01
-8wqg,2024-04-03,2023-10-11
-7wq4,2022-04-20,2022-01-24
-1wqh,2005-02-22,2004-09-29
-4wq3,2015-09-02,2014-10-21
-5wqp,2017-10-04,2016-11-27
-4wqk,2014-11-12,2014-10-22
-7wqz,2022-10-26,2022-01-26
-3wq9,2015-02-25,2014-01-23
-2wqk,2009-09-29,2009-08-23
-6wqc,2021-11-10,2020-04-28
-2wqr,2010-11-03,2009-08-26
-7wqi,2023-01-25,2022-01-25
-1wqg,2005-02-22,2004-09-29
-3wqb,2015-03-25,2014-01-24
-1wql,2005-03-29,2004-09-30
-1wqp,1998-07-01,1998-02-09
-5wqd,2017-03-08,2016-11-26
-5wqm,2018-07-04,2016-11-27
-6wqv,2020-11-18,2020-04-29
-7wqv,2023-01-25,2022-01-26
-2wq7,2010-02-23,2009-08-14
-5wqo,2017-10-04,2016-11-27
-7wq8,2023-08-02,2022-01-24
-1r1z,2003-12-16,2003-09-25
-1r15,2004-03-09,2003-09-23
-7r1g,2022-07-13,2022-02-02
-1r1o,2003-10-28,2003-09-24
-1r1j,2004-09-28,2003-09-24
-6r1e,2019-03-27,2019-03-14
-3r1s,2012-08-08,2011-03-11
-7r14,2022-03-09,2022-02-02
-7r11,2022-03-09,2022-02-02
-3r1m,2011-10-12,2011-03-10
-5r1r,1998-03-18,1997-09-17
-4r12,2014-09-17,2014-08-03
-7r1h,2023-02-15,2022-02-03
-7r10,2022-03-02,2022-02-02
-2r16,2008-03-25,2007-08-22
-8r1f,2023-12-06,2023-11-01
-6r1j,2019-07-10,2019-03-14
-1r1l,2004-10-05,2003-09-24
-4r1g,2014-08-27,2014-08-05
-4r17,2014-10-15,2014-08-04
-3r1n,2011-05-25,2011-03-11
-6r1b,2019-09-04,2019-03-14
-5r1z,2020-06-03,2020-02-13
-8r1d,2024-03-13,2023-11-01
-1r1k,2003-11-18,2003-09-24
-6r1r,1998-03-18,1997-09-17
-2r1x,2008-12-30,2007-08-23
-3r1b,2011-05-11,2011-03-09
-7r17,2022-03-09,2022-02-02
-6r12,2019-08-07,2019-03-13
-7r1f,2022-12-28,2022-02-02
-2r14,2008-07-01,2007-08-22
-3r10,2011-04-20,2011-03-09
-6r11,2019-08-07,2019-03-13
-2r1w,2008-12-30,2007-08-23
-4r1z,2014-12-31,2014-08-08
-8r1a,2024-01-17,2023-11-01
-6r1w,2019-08-07,2019-03-15
-8r14,2024-02-07,2023-11-01
-8r1n,2024-03-20,2023-11-02
-7r1l,2023-02-15,2022-02-03
-3r1y,2012-08-08,2011-03-11
-7r1i,2023-02-15,2022-02-03
-2r1k,2008-02-12,2007-08-23
-3r11,2011-04-20,2011-03-09
-1r1x,2003-10-07,2003-09-25
-4r18,2014-10-15,2014-08-04
-3r1j,2011-04-06,2011-03-10
-7r13,2022-03-09,2022-02-02
-6r10,2019-08-28,2019-03-13
-6r1c,2019-08-07,2019-03-14
-4r1s,2014-10-01,2014-08-07
-4r1v,2015-03-18,2014-08-07
-1r1q,2004-09-28,2003-09-24
-6r1k,2019-08-07,2019-03-14
-4r1d,2014-12-17,2014-08-05
-2r1b,2008-03-25,2007-08-22
-1r1s,2004-09-28,2003-09-24
-6r1q,2020-04-01,2019-03-14
-4r1p,2015-08-12,2014-08-07
-5r1v,2020-06-03,2020-02-13
-1r16,2004-03-09,2003-09-23
-4r1q,2015-08-12,2014-08-07
-7r1m,2023-02-15,2022-02-03
-2r1r,1998-01-28,1997-07-21
-7r1w,2022-09-28,2022-02-03
-1r1a,1990-07-15,1989-03-15
-1r1p,2004-09-28,2003-09-24
-3r17,2011-05-25,2011-03-09
-2r1m,2008-02-12,2007-08-23
-1r13,2003-11-18,2003-09-23
-4r1e,2014-11-12,2014-08-05
-7r1j,2023-02-15,2022-02-03
-2r1f,2007-09-04,2007-08-22
-4r1l,2014-08-27,2014-08-06
-7r1x,2023-02-15,2022-02-03
-1r1i,2004-09-28,2003-09-24
-6r1m,2020-01-22,2019-03-14
-2r1h,2008-09-02,2007-08-22
-1r1y,2003-10-07,2003-09-25
-6r1d,2019-08-07,2019-03-14
-3r19,2012-02-08,2011-03-09
-7r16,2022-03-09,2022-02-02
-6r1v,2020-01-22,2019-03-15
-3r18,2012-02-08,2011-03-09
-1r1h,2004-09-28,2003-09-24
-4r1y,2015-03-18,2014-08-08
-4r1r,1998-01-28,1997-07-22
-7r1r,1998-03-18,1997-09-17
-6r1a,2019-08-07,2019-03-14
-7r1q,2022-07-13,2022-02-03
-1r14,2003-11-11,2003-09-23
-3r1k,2011-06-01,2011-03-10
-7r1a,2022-03-02,2022-02-02
-6r1n,2020-01-22,2019-03-14
-7r15,2022-03-02,2022-02-02
-2r1y,2008-12-30,2007-08-23
-8r12,2024-02-07,2023-11-01
-7r18,2022-03-09,2022-02-02
-8r1i,2023-12-06,2023-11-02
-6r16,2020-07-15,2019-03-13
-6r1s,2020-02-19,2019-03-14
-7r1n,2023-02-15,2022-02-03
-7r12,2022-03-09,2022-02-02
-7r19,2022-03-09,2022-02-02
-7r1o,2022-05-18,2022-02-03
-6r15,2020-04-01,2019-03-13
-3r1v,2011-10-19,2011-03-11
-8r10,2024-03-20,2023-11-01
-8r1g,2023-12-06,2023-11-01
-6r1h,2019-05-08,2019-03-14
-1r1r,1998-01-28,1997-07-15
-8r1c,2024-03-13,2023-11-01
-6r1g,2019-09-18,2019-03-14
-6r1l,2020-04-01,2019-03-14
-8r1t,2024-03-20,2023-11-02
-6r1o,2020-01-22,2019-03-14
-8r18,2024-03-20,2023-11-01
-7r1v,2022-09-28,2022-02-03
-4r1f,2014-09-24,2014-08-05
-5r1u,2020-06-03,2020-02-13
-1r17,2003-10-28,2003-09-23
-5r1x,2020-06-03,2020-02-13
-2r1l,2008-02-12,2007-08-23
-8r1p,2024-03-20,2023-11-02
-2r11,2007-09-04,2007-08-21
-7r1b,2022-03-09,2022-02-02
-6r1f,2019-04-10,2019-03-14
-8r16,2024-02-07,2023-11-01
-2r1n,2008-02-12,2007-08-23
-5r1y,2020-06-03,2020-02-13
-8r11,2024-02-07,2023-11-01
-6r19,2019-08-07,2019-03-14
-4r1m,2014-08-27,2014-08-06
-6r1p,2020-02-19,2019-03-14
-2r1p,2008-02-12,2007-08-23
-3r1i,2011-03-30,2011-03-10
-6r1x,2019-08-07,2019-03-15
-3r1z,2011-04-20,2011-03-11
-6r13,2019-08-07,2019-03-13
-2r1d,2008-04-01,2007-08-22
-8r1v,2024-03-06,2023-11-02
-3r1q,2012-08-08,2011-03-11
-3r1r,1998-01-28,1997-07-21
-7r1t,2022-06-29,2022-02-03
-1r10,2003-12-09,2003-09-23
-3r16,2011-05-25,2011-03-09
-3r1a,2011-05-11,2011-03-09
-1r1c,2003-09-30,2003-09-23
-5r1t,2020-06-03,2020-02-13
-4r16,2015-10-14,2014-08-04
-6r18,2019-08-07,2019-03-14
-7r1u,2022-06-29,2022-02-03
-7r1p,2022-07-13,2022-02-03
-7r1k,2022-05-25,2022-02-03
-5r1w,2020-06-03,2020-02-13
-6r1u,2019-04-24,2019-03-15
-4r14,2014-10-22,2014-08-04
-1r18,2003-12-09,2003-09-23
-1r1v,2004-05-18,2003-09-25
-3nvu,2010-09-08,2010-07-08
-3nvj,2010-11-03,2010-07-08
-2nvo,2007-03-27,2006-11-13
-1nv6,2003-07-08,2003-02-02
-1nvm,2003-06-17,2003-02-04
-6nvl,2019-07-10,2019-02-05
-3nvx,2010-09-15,2010-07-08
-3nvv,2011-01-19,2010-07-08
-2nvd,2007-04-24,2006-11-12
-3nv2,2010-09-22,2010-07-07
-2nvq,2006-12-12,2006-11-13
-4nvo,2013-12-25,2013-12-05
-3nv1,2010-09-22,2010-07-07
-1nvg,2003-08-26,2003-02-03
-4nvh,2013-12-18,2013-12-05
-1nvb,2003-03-18,2003-02-03
-4nvj,2013-12-25,2013-12-05
-3nv6,2010-11-03,2010-07-08
-6nvp,2019-03-27,2019-02-05
-5nv2,2018-05-30,2017-05-03
-3nvk,2011-07-20,2010-07-08
-4nvr,2013-12-18,2013-12-05
-6nvy,2019-07-03,2019-02-05
-5nv4,2017-07-26,2017-05-03
-2nvc,2007-04-24,2006-11-12
-2nvx,2006-12-19,2006-11-13
-3nvr,2010-09-08,2010-07-08
-1nv7,2003-07-08,2003-02-02
-4nvg,2013-12-18,2013-12-05
-3nvf,2011-03-02,2010-07-08
-4nvq,2014-01-15,2013-12-05
-3nv5,2010-11-03,2010-07-08
-4nv5,2014-02-12,2013-12-04
-1nva,2003-03-18,2003-02-03
-1nvv,2003-04-01,2003-02-04
-1nv8,2003-05-27,2003-02-02
-7nvo,2022-03-02,2021-03-15
-2nva,2007-03-20,2006-11-11
-6nvo,2019-03-27,2019-02-05
-1nvl,2004-05-11,2003-02-04
-3nvy,2011-01-19,2010-07-08
-7nvh,2021-06-16,2021-03-15
-1nv9,2003-05-27,2003-02-02
-1nvt,2003-03-25,2003-02-04
-6nvj,2019-07-10,2019-02-05
-5nv3,2017-07-26,2017-05-03
-7nv1,2021-11-03,2021-03-15
-3nvg,2011-03-02,2010-07-08
-5nvy,2017-09-20,2017-05-04
-6nvf,2020-02-12,2019-02-05
-6nv8,2020-02-12,2019-02-04
-3nve,2011-03-02,2010-07-08
-5nv9,2018-04-04,2017-05-03
-4nv0,2014-03-19,2013-12-04
-4nve,2013-12-18,2013-12-05
-4nv7,2015-01-21,2013-12-05
-1nvj,2003-05-06,2003-02-03
-4nv2,2014-02-12,2013-12-04
-3nvl,2011-07-27,2010-07-08
-4nva,2013-12-18,2013-12-05
-2nv4,2006-11-21,2006-11-10
-4nvi,2013-12-25,2013-12-05
-4nvd,2013-12-18,2013-12-05
-3nv8,2010-07-28,2010-07-08
-5nvh,2018-03-14,2017-05-04
-7nvl,2022-03-02,2021-03-15
-6nva,2019-02-27,2019-02-04
-7nvs,2021-05-05,2021-03-16
-1nv5,2003-07-08,2003-02-02
-7nvq,2021-06-16,2021-03-15
-3nvo,2011-03-23,2010-07-08
-1nvx,2003-04-01,2003-02-04
-6nvi,2019-07-10,2019-02-05
-1nvd,2003-03-18,2003-02-03
-2nvz,2006-12-19,2006-11-14
-1nvk,2003-09-09,2003-02-04
-1nv1,2003-07-08,2003-02-01
-2nvu,2007-01-30,2006-11-13
-3nvc,2011-07-13,2010-07-08
-2nvk,2007-04-24,2006-11-13
-1nvq,2003-04-08,2003-02-04
-6nvh,2019-07-10,2019-02-05
-7nvz,2021-05-05,2021-03-16
-4nvf,2013-12-18,2013-12-05
-3nvw,2011-01-19,2010-07-08
-1nvs,2003-04-08,2003-02-04
-6nv9,2019-10-09,2019-02-04
-4nvl,2013-12-25,2013-12-05
-6nvu,2019-12-11,2019-02-05
-6nvd,2020-02-12,2019-02-05
-4nvb,2013-12-18,2013-12-05
-6nv1,2020-01-15,2019-02-04
-6nv6,2020-03-04,2019-02-04
-5nvc,2018-03-14,2017-05-04
-3nvn,2010-09-15,2010-07-08
-4nvn,2013-12-25,2013-12-05
-7nvp,2022-03-30,2021-03-15
-2nvb,2007-11-13,2006-11-12
-2nvt,2006-12-12,2006-11-13
-4nvk,2013-12-25,2013-12-05
-7nvm,2022-03-02,2021-03-15
-1nv2,2003-07-08,2003-02-01
-5nvi,2017-11-15,2017-05-04
-5nvf,2018-03-14,2017-05-04
-6nvk,2019-07-10,2019-02-05
-5nv8,2017-10-04,2017-05-03
-2nv7,2007-08-21,2006-11-10
-7nvi,2021-06-09,2021-03-15
-5nv7,2018-05-30,2017-05-03
-6nvx,2019-07-03,2019-02-05
-3nv3,2010-09-22,2010-07-07
-7nv0,2021-11-10,2021-03-15
-3nvh,2011-03-02,2010-07-08
-3nv0,2011-07-20,2010-07-07
-1nvw,2003-04-01,2003-02-04
-7nvu,2021-05-05,2021-03-16
-2nv2,2006-12-05,2006-11-10
-3nvs,2010-07-21,2010-07-08
-6nvw,2019-07-03,2019-02-05
-4nv6,2014-02-12,2013-12-04
-1nvr,2003-04-08,2003-02-04
-4nv1,2013-12-25,2013-12-04
-1nvu,2003-04-01,2003-02-04
-3nv4,2010-09-22,2010-07-07
-5nvw,2017-09-20,2017-05-04
-1nv4,2003-07-08,2003-02-02
-3nvt,2010-07-28,2010-07-08
-5nv1,2018-08-15,2017-05-03
-7nvt,2021-05-05,2021-03-16
-1nvf,2003-03-18,2003-02-03
-6nvc,2020-02-12,2019-02-04
-4nvm,2013-12-25,2013-12-05
-1nv3,2003-07-08,2003-02-02
-7nvw,2021-05-05,2021-03-16
-1nve,2003-03-18,2003-02-03
-2nv1,2006-12-05,2006-11-10
-1nv0,2003-07-08,2003-02-01
-4nv3,2013-12-11,2013-12-04
-6nve,2020-02-12,2019-02-05
-3nvz,2011-01-19,2010-07-08
-7nvv,2021-05-05,2021-03-16
-7nv4,2021-06-09,2021-03-15
-3nv9,2011-07-20,2010-07-08
-7nvn,2022-03-02,2021-03-15
-2nv6,2006-11-21,2006-11-10
-7nvx,2021-05-05,2021-03-16
-2nvy,2006-12-26,2006-11-13
-4nvp,2014-03-19,2013-12-05
-3nvq,2010-09-15,2010-07-08
-2nvv,2007-01-30,2006-11-13
-7nvy,2021-05-05,2021-03-16
-5nva,2018-04-04,2017-05-03
-6nv2,2020-05-13,2019-02-04
-6nv7,2019-10-09,2019-02-04
-4nvc,2013-12-18,2013-12-05
-5nv0,2018-05-30,2017-05-03
-5nvz,2017-09-20,2017-05-04
-2nv9,2007-03-20,2006-11-11
-5nve,2018-03-14,2017-05-04
-5nvv,2017-09-20,2017-05-04
-6nvg,2019-07-10,2019-02-05
-3nvd,2010-08-04,2010-07-08
-5nvx,2017-09-20,2017-05-04
-7nvr,2021-05-05,2021-03-15
-16pk,1998-11-25,1998-05-18
-5yxf,2018-12-12,2017-12-05
-1yxu,2005-04-26,2005-02-22
-1yxo,2005-04-05,2005-02-22
-4yxl,2015-09-23,2015-03-23
-6yxu,2020-11-04,2020-05-03
-4yxm,2015-06-03,2015-03-23
-7yxh,2022-04-27,2022-02-16
-6yx7,2021-05-12,2020-04-30
-6yx9,2021-05-12,2020-04-30
-6yxg,2021-05-12,2020-05-01
-5yx4,2018-02-14,2017-12-01
-7yx3,2022-08-10,2022-02-15
-8yxm,2024-06-05,2024-04-02
-2yxc,2008-04-29,2007-04-26
-1yxi,2005-03-15,2005-02-21
-4yxp,2015-06-17,2015-03-23
-7yxe,2022-03-02,2022-02-15
-6yxi,2020-08-19,2020-05-01
-1yxm,2005-03-15,2005-02-22
-4yx9,2015-07-15,2015-03-22
-7yxi,2022-04-27,2022-02-16
-7yxr,2022-12-07,2022-02-16
-4yx6,2016-04-13,2015-03-22
-2yx9,2008-04-08,2007-04-25
-6yx2,2021-01-20,2020-04-30
-6yxy,2020-10-14,2020-05-04
-5yxd,2019-03-13,2017-12-05
-2yx6,2007-10-30,2007-04-24
-7yx4,2022-08-10,2022-02-15
-4yxb,2015-06-03,2015-03-22
-7yxt,2023-03-01,2022-02-16
-7yxp,2022-12-07,2022-02-16
-5yxc,2017-12-20,2017-12-04
-6yxs,2020-08-05,2020-05-03
-6yxm,2021-05-12,2020-05-03
-6yxw,2020-07-08,2020-05-04
-2yxx,2007-10-30,2007-04-27
-2yxj,2007-05-22,2007-04-26
-2yxh,2007-10-30,2007-04-26
-7yx0,2023-05-24,2022-02-15
-2yxu,2008-03-11,2007-04-27
-1yxc,2005-08-02,2005-02-20
-2yxt,2008-03-11,2007-04-27
-4yxw,2015-05-06,2015-03-23
-4yxi,2016-02-03,2015-03-23
-7yxf,2023-03-01,2022-02-16
-6yxb,2021-04-21,2020-04-30
-2yxn,2008-04-29,2007-04-26
-6yx4,2021-04-21,2020-04-30
-4yxs,2015-05-20,2015-03-23
-5yx1,2018-12-05,2017-12-01
-7yx5,2022-08-10,2022-02-15
-4yxr,2015-05-27,2015-03-23
-7yx8,2022-07-20,2022-02-15
-4yx4,2016-02-03,2015-03-22
-5yxw,2018-02-21,2017-12-07
-7yxk,2022-04-27,2022-02-16
-6yxt,2020-08-05,2020-05-03
-1yxv,2005-04-26,2005-02-22
-6yx6,2021-04-21,2020-04-30
-6yxv,2021-02-10,2020-05-04
-7yxl,2022-04-27,2022-02-16
-7yxu,2023-01-25,2022-02-16
-2yxs,2008-05-06,2007-04-27
-7yxz,2022-07-06,2022-02-17
-7yxc,2022-12-07,2022-02-15
-6yxh,2021-05-12,2020-05-01
-5yxj,2019-03-13,2017-12-05
-4yxk,2015-09-23,2015-03-23
-7yxn,2022-12-07,2022-02-16
-6yx3,2021-05-12,2020-04-30
-2yxv,2008-01-01,2007-04-27
-5yx2,2018-01-31,2017-12-01
-6yxc,2021-04-21,2020-04-30
-6yxr,2020-07-01,2020-05-03
-1yxd,2005-08-02,2005-02-20
-6yx5,2020-12-23,2020-04-30
-2yxw,2008-01-01,2007-04-27
-6yxx,2020-10-14,2020-05-04
-1yxh,2005-05-03,2005-02-21
-1yxq,2005-05-17,2005-02-22
-4yxo,2016-02-03,2015-03-23
-7yxo,2022-12-07,2022-02-16
-5yxz,2018-04-18,2017-12-07
-7yx6,2022-02-23,2022-02-15
-6yx8,2021-05-12,2020-04-30
-1yxx,2005-04-26,2005-02-22
-6yxa,2020-09-23,2020-04-30
-4yxh,2015-09-23,2015-03-23
-7yxm,2022-04-06,2022-02-16
-5yxy,2018-06-20,2017-12-07
-5yxb,2019-03-13,2017-12-04
-6yxe,2020-10-14,2020-05-01
-6yx1,2021-01-20,2020-04-30
-6yxf,2021-05-12,2020-05-01
-4yx1,2015-06-03,2015-03-21
-2yx7,2008-04-29,2007-04-24
-4yxu,2016-02-03,2015-03-23
-1yxl,2005-03-08,2005-02-22
-2yxo,2007-11-27,2007-04-26
-6yxz,2021-05-12,2020-05-04
-6yx0,2021-01-20,2020-04-30
-7yxg,2022-04-27,2022-02-16
-4yxj,2015-06-03,2015-03-23
-4yxd,2016-03-02,2015-03-23
-6yxk,2021-05-12,2020-05-03
-1yxt,2005-04-26,2005-02-22
-2yx1,2008-04-22,2007-04-23
-5yxl,2019-03-13,2017-12-05
-7yx1,2022-07-27,2022-02-15
-8yxp,2024-06-05,2024-04-02
-7yxj,2022-04-27,2022-02-16
-7yxd,2022-12-07,2022-02-15
-2yxl,2008-04-29,2007-04-26
-6yxd,2021-05-12,2020-05-01
-1yx1,2005-04-05,2005-02-19
-7yxa,2022-08-10,2022-02-15
-1yxw,2005-03-15,2005-02-22
-2yx4,2008-04-29,2007-04-24
-5yxh,2018-02-28,2017-12-05
-4i2c,2013-07-24,2012-11-21
-1i2a,2003-12-09,2001-02-07
-1i2g,2001-03-07,2001-02-09
-1i27,2001-03-07,2001-02-07
-1i2c,2003-07-01,2001-02-07
-6i2n,2019-01-23,2018-11-01
-2i2s,2007-04-03,2006-08-16
-6i2k,2018-11-28,2018-11-01
-6i2j,2019-01-16,2018-11-01
-1i2e,2001-03-07,2001-02-09
-5i2s,2016-03-02,2016-02-09
-4i2d,2013-07-24,2012-11-21
-8i2b,2024-01-17,2023-01-14
-2i2c,2007-08-07,2006-08-16
-3i2b,2009-07-28,2009-06-29
-3i2k,2010-06-16,2009-06-29
-3i27,2009-09-15,2009-06-29
-8i2n,2024-01-31,2023-01-14
-3i2l,2011-04-27,2009-06-29
-8i2c,2023-04-12,2023-01-14
-3i2g,2010-06-16,2009-06-29
-6i2p,2019-05-22,2018-11-01
-8i2s,2023-12-20,2023-01-15
-5i2b,2016-03-09,2016-02-08
-8i22,2024-01-17,2023-01-13
-4i2i,2013-07-24,2012-11-21
-4i2a,2013-07-24,2012-11-21
-2i2x,2006-11-21,2006-08-17
-4i2u,2013-11-27,2012-11-23
-4i28,2013-07-24,2012-11-21
-6i2h,2019-11-20,2018-11-01
-2i2b,2007-08-07,2006-08-16
-1i2s,2002-03-13,2001-02-12
-4i26,2014-05-21,2012-11-21
-1i2d,2001-07-11,2001-02-07
-5i2e,2016-06-22,2016-02-08
-4i2p,2013-01-16,2012-11-22
-5i2n,2016-03-16,2016-02-09
-4i23,2013-01-16,2012-11-21
-6i2z,2019-10-16,2018-11-02
-5i23,2016-05-04,2016-02-08
-8i2r,2023-06-14,2023-01-15
-5i2z,2016-07-06,2016-02-09
-3i2o,2009-08-25,2009-06-29
-6i29,2019-11-20,2018-11-01
-2i2z,2006-12-12,2006-08-17
-2i2a,2007-08-07,2006-08-16
-1i2f,2001-03-07,2001-02-09
-4i2j,2013-07-24,2012-11-21
-5i2o,2016-12-28,2016-02-09
-5i29,2016-06-08,2016-02-08
-3i2d,2009-09-15,2009-06-29
-8i2j,2023-04-12,2023-01-14
-8i27,2023-04-12,2023-01-14
-3i2i,2010-06-16,2009-06-29
-8i2l,2023-04-12,2023-01-14
-2i2f,2007-08-07,2006-08-16
-3i2h,2010-06-16,2009-06-29
-6i2t,2018-12-19,2018-11-01
-4i27,2013-07-24,2012-11-21
-1i29,2003-07-01,2001-02-07
-6i2u,2019-10-02,2018-11-02
-6i28,2019-02-20,2018-10-31
-6i2s,2019-05-22,2018-11-01
-4i2x,2013-12-18,2012-11-23
-2i2y,2006-12-12,2006-08-17
-6i2c,2019-05-15,2018-11-01
-8i24,2023-10-11,2023-01-13
-5i25,2016-04-06,2016-02-08
-2i2r,2006-10-24,2006-08-16
-6i24,2019-05-29,2018-10-31
-3i28,2009-10-13,2009-06-29
-1i2k,2003-09-02,2001-02-09
-3i25,2010-06-02,2009-06-29
-5i2u,2017-01-18,2016-02-09
-4i24,2013-01-16,2012-11-21
-4i2e,2013-07-24,2012-11-21
-1i2z,2002-02-12,2001-02-12
-6i2y,2018-12-12,2018-11-02
-5i2c,2016-08-10,2016-02-08
-2i2d,2007-08-07,2006-08-16
-5i28,2016-04-13,2016-02-08
-2i29,2007-08-07,2006-08-16
-2i20,2006-10-10,2006-08-15
-4i22,2013-01-16,2012-11-21
-6i22,2019-05-29,2018-10-31
-6i23,2019-05-29,2018-10-31
-5i26,2016-04-13,2016-02-08
-5i2l,2016-12-28,2016-02-09
-3i24,2009-07-21,2009-06-29
-5i2k,2016-03-16,2016-02-09
-8i2u,2023-12-20,2023-01-15
-6i20,2019-05-29,2018-10-31
-5i2q,2016-12-28,2016-02-09
-2i2o,2006-08-29,2006-08-16
-4i2q,2013-01-16,2012-11-22
-1i22,2001-02-28,2001-02-05
-3i2y,2010-06-09,2009-06-30
-6i2r,2019-05-22,2018-11-01
-6i2f,2019-11-20,2018-11-01
-4i2n,2013-11-27,2012-11-22
-1i2w,2002-03-13,2001-02-12
-8i2p,2023-12-20,2023-01-14
-3i26,2009-09-15,2009-06-29
-1i2b,2003-07-01,2001-02-07
-6i2i,2019-08-28,2018-11-01
-2i21,2006-10-10,2006-08-15
-8i23,2023-10-11,2023-01-13
-4i2r,2014-05-21,2012-11-22
-4i2y,2013-07-24,2012-11-23
-6i2q,2019-05-22,2018-11-01
-5i2h,2016-03-02,2016-02-08
-5i2i,2016-10-26,2016-02-08
-8i2m,2023-04-12,2023-01-14
-4i29,2013-07-24,2012-11-21
-6i2g,2019-09-25,2018-11-01
-8i2g,2023-03-29,2023-01-14
-3i2w,2010-03-02,2009-06-29
-4i2z,2013-03-13,2012-11-23
-5i2d,2016-06-22,2016-02-08
-1i2l,2003-09-02,2001-02-09
-3i2t,2009-09-08,2009-06-29
-8i2z,2023-03-29,2023-01-15
-5i24,2016-05-04,2016-02-08
-3i29,2010-06-16,2009-06-29
-6i2b,2019-05-15,2018-11-01
-6i2a,2019-05-15,2018-11-01
-4i2b,2013-07-24,2012-11-21
-6i25,2019-06-19,2018-10-31
-4i2h,2013-07-24,2012-11-21
-3i2f,2010-06-16,2009-06-29
-4i25,2014-05-21,2012-11-21
-5i2m,2016-02-24,2016-02-09
-4i2f,2013-07-24,2012-11-21
-5i2f,2016-06-22,2016-02-08
-5i2r,2016-03-09,2016-02-09
-8i2a,2023-04-12,2023-01-14
-2i22,2007-08-21,2006-08-15
-6i21,2019-05-29,2018-10-31
-1i24,2003-07-01,2001-02-05
-8i29,2023-02-01,2023-01-14
-6i2d,2019-05-15,2018-11-01
-4i2g,2013-07-24,2012-11-21
-5x2q,2017-05-24,2017-02-02
-8x2a,2023-12-27,2023-11-09
-4x2a,2015-09-16,2014-11-26
-4x2p,2015-10-14,2014-11-26
-6x2q,2021-05-26,2020-05-20
-6x24,2020-12-16,2020-05-19
-3x2m,2015-10-14,2014-12-22
-7x2l,2022-12-07,2022-02-25
-6x26,2021-02-03,2020-05-20
-7x24,2022-10-05,2022-02-25
-6x2p,2020-07-01,2020-05-20
-3x27,2015-10-28,2014-12-10
-5x27,2018-02-07,2017-01-31
-7x2c,2022-06-29,2022-02-25
-3x24,2016-01-27,2014-12-10
-5x21,2017-07-05,2017-01-29
-4x27,2015-03-18,2014-11-26
-1x28,2005-06-14,2005-04-21
-7x2h,2023-03-01,2022-02-25
-1x2r,2006-03-07,2005-04-26
-6x2u,2020-07-01,2020-05-21
-2x2e,2010-04-28,2010-01-12
-3x2k,2015-10-07,2014-12-22
-2x21,2010-02-09,2010-01-09
-7x2f,2022-06-15,2022-02-25
-5x2x,2017-04-12,2017-02-02
-6x2m,2020-07-01,2020-05-20
-2x23,2010-03-02,2010-01-10
-5x2s,2017-09-27,2017-02-02
-7x20,2022-10-05,2022-02-25
-3x2u,2015-12-16,2015-01-02
-4x2l,2015-03-04,2014-11-26
-2x2t,2010-05-26,2010-01-15
-3x26,2016-01-27,2014-12-10
-6x2z,2021-03-17,2020-05-21
-6x2y,2020-07-01,2020-05-21
-3x2t,2015-04-01,2015-01-02
-5x2o,2017-05-24,2017-02-02
-4x23,2014-12-10,2014-11-25
-3x2z,2016-02-17,2015-01-07
-2x2r,2011-01-26,2010-01-15
-3x2x,2016-02-17,2015-01-07
-2x2w,2010-05-19,2010-01-18
-2x2n,2010-02-02,2010-01-14
-6x2j,2020-11-18,2020-05-20
-4x21,2015-11-11,2014-11-25
-5x2i,2018-08-08,2017-01-31
-5x22,2017-07-05,2017-01-29
-8x2j,2024-03-06,2023-11-09
-4x2u,2015-02-18,2014-11-27
-4x2g,2015-08-12,2014-11-26
-2x2i,2011-01-19,2010-01-13
-3x22,2015-11-18,2014-12-06
-4x2d,2015-12-23,2014-11-26
-4x20,2015-03-25,2014-11-25
-2x2j,2011-01-19,2010-01-13
-4x2j,2014-12-24,2014-11-26
-5x20,2017-04-05,2017-01-29
-2x20,2010-02-09,2010-01-09
-6x2o,2020-07-01,2020-05-20
-5x2l,2018-01-31,2017-02-01
-3x2l,2015-10-14,2014-12-22
-6x21,2021-05-26,2020-05-19
-7x2y,2022-09-14,2022-02-26
-2x2y,2010-06-23,2010-01-18
-2x2l,2010-02-09,2010-01-13
-6x2s,2020-07-01,2020-05-20
-4x2h,2015-06-17,2014-11-26
-1x2h,2005-08-02,2005-04-23
-3x2v,2015-12-16,2015-01-02
-4x2k,2014-12-24,2014-11-26
-1x2t,2005-10-04,2005-04-26
-1x2b,2006-05-09,2005-04-22
-4x2f,2015-10-28,2014-11-26
-5x24,2017-10-25,2017-01-30
-8x2l,2024-01-24,2023-11-09
-6x2x,2020-07-01,2020-05-21
-6x25,2020-11-25,2020-05-20
-5x2f,2018-02-07,2017-01-31
-2x2v,2010-08-18,2010-01-18
-5x2e,2017-08-30,2017-01-31
-3x2h,2015-10-07,2014-12-22
-5x2n,2017-05-24,2017-02-02
-7x2q,2023-03-01,2022-02-26
-3x2p,2015-10-14,2014-12-22
-7x21,2022-10-05,2022-02-25
-5x2w,2017-04-12,2017-02-02
-2x24,2011-01-26,2010-01-11
-4x2q,2015-12-02,2014-11-26
-4x2t,2015-02-18,2014-11-27
-7x2n,2023-04-05,2022-02-25
-2x2c,2010-03-23,2010-01-12
-3x2s,2015-04-01,2014-12-31
-6x2w,2020-07-01,2020-05-21
-7x23,2022-10-05,2022-02-25
-8x2i,2023-12-13,2023-11-09
-6x2v,2020-07-01,2020-05-21
-4x2i,2015-11-11,2014-11-26
-5x2j,2018-01-31,2017-01-31
-4x2s,2015-02-04,2014-11-26
-2x2u,2010-05-19,2010-01-15
-7x2d,2022-06-15,2022-02-25
-5x28,2018-02-07,2017-01-31
-7x2j,2022-12-21,2022-02-25
-3x2j,2015-10-07,2014-12-22
-5x2m,2017-05-24,2017-02-02
-1x2e,2006-05-09,2005-04-22
-6x2h,2021-05-26,2020-05-20
-3x2e,2015-05-06,2014-12-21
-6x2r,2020-07-01,2020-05-20
-6x2f,2021-02-03,2020-05-20
-7x2e,2022-07-06,2022-02-25
-3x21,2015-05-20,2014-12-06
-5x2t,2017-09-20,2017-02-02
-7x22,2022-10-05,2022-02-25
-6x27,2021-04-14,2020-05-20
-6x2n,2021-02-03,2020-05-20
-3x2y,2016-02-17,2015-01-07
-3x28,2015-12-23,2014-12-12
-5x2p,2017-05-24,2017-02-02
-1x29,2005-06-14,2005-04-21
-3x2w,2015-12-16,2015-01-02
-3x20,2016-01-27,2014-12-03
-5x2a,2018-02-07,2017-01-31
-4x2o,2015-06-17,2014-11-26
-3x25,2016-01-27,2014-12-10
-3x2g,2015-10-07,2014-12-22
-2x2p,2010-03-09,2010-01-15
-5x26,2018-02-07,2017-01-31
-2x2z,2010-03-16,2010-01-18
-3x2f,2015-05-06,2014-12-21
-8x2h,2023-12-13,2023-11-09
-5x2u,2017-09-27,2017-02-02
-4x2b,2015-05-06,2014-11-26
-1x2a,2005-06-14,2005-04-21
-2x2m,2010-02-09,2010-01-13
-4x29,2015-03-18,2014-11-26
-6x28,2021-05-26,2020-05-20
-6x2e,2020-11-04,2020-05-20
-2x2f,2010-04-28,2010-01-13
-5x2b,2018-03-28,2017-01-31
-5x2k,2018-02-21,2017-02-01
-3x2i,2015-10-07,2014-12-22
-4x2z,2015-01-28,2014-11-27
-1x2w,2005-10-04,2005-04-26
-5x2r,2017-09-20,2017-02-02
-5x2h,2017-03-29,2017-01-31
-7x2s,2023-04-05,2022-02-26
-2x28,2010-02-02,2010-01-11
-6x23,2020-11-25,2020-05-19
-2x22,2010-03-02,2010-01-10
-5x2g,2017-03-29,2017-01-31
-4x24,2015-08-19,2014-11-25
-5x2c,2018-02-21,2017-01-31
-3x2q,2015-06-10,2014-12-26
-2x2k,2010-02-09,2010-01-13
-4x28,2015-02-18,2014-11-26
-5x23,2017-10-25,2017-01-30
-5x2z,2017-04-12,2017-02-02
-7x2k,2022-12-21,2022-02-25
-7x2m,2022-12-14,2022-02-25
-2x2b,2010-03-16,2010-01-12
-2x2o,2010-03-09,2010-01-15
-1x27,2006-02-07,2005-04-20
-2x27,2010-12-15,2010-01-11
-7x2x,2023-04-05,2022-02-26
-7yr0,2022-10-19,2022-08-08
-4yrq,2015-08-12,2015-03-15
-4yro,2015-08-12,2015-03-15
-4yrp,2015-08-12,2015-03-15
-8yru,2024-04-17,2024-03-21
-1yrq,2005-04-19,2005-02-04
-4yry,2015-07-08,2015-03-16
-7yr2,2022-10-19,2022-08-08
-7yr8,2023-04-19,2022-08-09
-6yr2,2021-04-28,2020-04-19
-5yrl,2018-08-29,2017-11-09
-7yrb,2023-11-15,2022-08-09
-7yrp,2023-06-21,2022-08-10
-6yrz,2021-04-21,2020-04-20
-6yr1,2021-04-28,2020-04-18
-7yrn,2023-08-16,2022-08-10
-7yrz,2023-08-16,2022-08-11
-4yr3,2015-05-13,2015-03-14
-6yrd,2021-01-13,2020-04-20
-2yri,2008-04-15,2007-04-02
-2yrh,2007-10-02,2007-04-02
-4yrc,2015-08-12,2015-03-15
-5yr7,2018-11-14,2017-11-08
-1yrs,2005-04-12,2005-02-04
-5yrj,2018-08-29,2017-11-09
-4yr7,2016-03-23,2015-03-14
-2yrs,2008-03-11,2007-04-03
-5yrr,2017-11-22,2017-11-09
-4yrt,2015-08-12,2015-03-15
-5yrt,2018-09-19,2017-11-10
-6yr7,2021-11-03,2020-04-19
-2yrg,2007-10-02,2007-04-02
-7yrs,2023-08-16,2022-08-10
-2yr5,2008-04-15,2007-04-02
-1yrk,2005-07-26,2005-02-03
-1yre,2005-02-15,2005-02-03
-2yrk,2007-10-02,2007-04-02
-7yrk,2023-05-10,2022-08-10
-2yr2,2007-10-02,2007-04-02
-4yrm,2015-08-12,2015-03-15
-2yr6,2008-04-15,2007-04-02
-4yrr,2015-08-12,2015-03-15
-2yrr,2008-04-15,2007-04-02
-1yra,2006-02-14,2005-02-03
-1yrh,2005-02-15,2005-02-03
-4yrw,2015-04-29,2015-03-16
-1yrx,2005-06-28,2005-02-05
-7yri,2023-08-16,2022-08-10
-4yr2,2015-05-13,2015-03-14
-4yrv,2015-12-02,2015-03-16
-8yrt,2024-04-17,2024-03-21
-7yr9,2023-09-20,2022-08-09
-8yrv,2024-04-17,2024-03-21
-4yru,2015-04-01,2015-03-15
-2yrd,2007-10-02,2007-04-02
-2yrx,2007-10-09,2007-04-03
-7yrj,2023-08-16,2022-08-10
-6yr9,2021-02-10,2020-04-19
-6yra,2021-04-21,2020-04-20
-4yrd,2015-10-21,2015-03-15
-2yr4,2008-04-15,2007-04-02
-6yr3,2021-04-28,2020-04-19
-4yrj,2015-08-12,2015-03-15
-1yry,2006-01-17,2005-02-05
-6yru,2021-04-21,2020-04-20
-6yrh,2021-05-12,2020-04-20
-6yr5,2021-11-03,2020-04-19
-1yru,2005-09-27,2005-02-04
-5yrm,2018-08-29,2017-11-09
-6yrt,2021-05-12,2020-04-20
-5yr5,2018-11-14,2017-11-08
-6yry,2020-04-29,2020-04-20
-4yr9,2016-02-03,2015-03-14
-5yrv,2018-09-19,2017-11-10
-1yr7,2006-02-14,2005-02-03
-4yrf,2015-08-19,2015-03-15
-7yro,2023-08-16,2022-08-10
-5yri,2018-08-29,2017-11-09
-2yrj,2007-10-02,2007-04-02
-7yrd,2023-08-16,2022-08-09
-1yrb,2006-02-14,2005-02-03
-1yro,2005-03-22,2005-02-04
-6yrc,2021-01-13,2020-04-20
-4yre,2015-08-12,2015-03-15
-6yrv,2021-04-21,2020-04-20
-6yro,2020-08-19,2020-04-20
-4yr1,2015-04-29,2015-03-13
-7yry,2023-06-21,2022-08-11
-1yr5,2006-07-04,2005-02-03
-6yrw,2020-06-03,2020-04-20
-6yr8,2020-07-08,2020-04-19
-2yrt,2008-04-08,2007-04-03
-4yrn,2015-08-12,2015-03-15
-1yr8,2006-02-14,2005-02-03
-4yrk,2015-08-12,2015-03-15
-4yrh,2015-07-01,2015-03-15
-5yrx,2018-05-16,2017-11-10
-6yrb,2020-10-14,2020-04-20
-6yrx,2021-04-21,2020-04-20
-4yrl,2015-08-12,2015-03-15
-1yr9,2006-02-14,2005-02-03
-4yrg,2015-08-12,2015-03-15
-8yrc,2024-04-24,2024-03-21
-1yrd,2005-02-15,2005-02-03
-5yrf,2018-08-29,2017-11-09
-6yrm,2021-05-12,2020-04-20
-1yrc,2005-02-15,2005-02-03
-6yrp,2020-09-30,2020-04-20
-2yrm,2007-10-02,2007-04-02
-1yr3,2005-04-19,2005-02-03
-7yrg,2023-12-13,2022-08-09
-1yrt,2006-01-17,2005-02-04
-5yro,2018-11-21,2017-11-09
-5yrs,2018-03-07,2017-11-10
-6yri,2021-03-31,2020-04-20
-6yrj,2021-01-13,2020-04-20
-6yr4,2021-01-13,2020-04-19
-4yrz,2016-03-23,2015-03-16
-5yr4,2018-11-14,2017-11-08
-2yrc,2007-10-02,2007-04-02
-2yre,2007-10-02,2007-04-02
-5yrg,2018-08-29,2017-11-09
-4yrb,2016-02-03,2015-03-14
-6yrq,2020-10-14,2020-04-20
-4yrs,2015-08-12,2015-03-15
-7yr3,2022-10-19,2022-08-08
-4yri,2015-08-12,2015-03-15
-5yrp,2018-05-09,2017-11-09
-7yr1,2022-10-19,2022-08-08
-4yr0,2015-05-13,2015-03-13
-5yr6,2018-11-14,2017-11-08
-6yr6,2021-11-03,2020-04-19
-4b0j,2012-11-28,2012-07-02
-7b0i,2021-08-04,2020-11-19
-5b05,2016-01-13,2015-10-28
-2b0c,2005-11-22,2005-09-13
-8b0c,2022-12-28,2022-09-07
-8b0g,2023-02-22,2022-09-07
-3b01,2011-11-23,2011-06-03
-7b04,2021-07-14,2020-11-18
-3b0l,2012-02-22,2011-06-10
-9b0k,2024-05-29,2024-03-12
-7b03,2021-06-16,2020-11-18
-8b07,2023-04-05,2022-09-07
-5b0z,2016-01-27,2015-11-14
-6b0i,2018-05-02,2017-09-14
-1b0n,1999-01-13,1998-11-11
-4b0t,2012-09-12,2012-07-04
-7b0z,2021-11-03,2020-11-23
-7b0f,2020-12-30,2020-11-19
-7b08,2020-12-30,2020-11-18
-8b08,2023-05-03,2022-09-07
-3b0x,2012-05-02,2011-06-17
-4b0h,2013-05-15,2012-07-02
-2b0t,2006-01-31,2005-09-14
-6b09,2019-01-09,2017-09-14
-2b0q,2005-09-27,2005-09-14
-3b0u,2011-12-14,2011-06-14
-7b09,2020-12-16,2020-11-19
-1b0p,1999-04-23,1998-11-12
-6b0c,2018-05-02,2017-09-14
-3b0a,2011-12-14,2011-06-07
-8b0f,2023-02-22,2022-09-07
-6b0q,2018-01-03,2017-09-14
-2b00,2006-11-14,2005-09-12
-8b05,2023-05-03,2022-09-07
-1b0e,1998-11-18,1998-11-09
-7b0e,2021-12-01,2020-11-19
-7b0h,2021-01-13,2020-11-19
-2b0z,2005-10-25,2005-09-15
-5b0y,2016-01-27,2015-11-13
-6b0u,2018-01-31,2017-09-15
-5b0w,2016-07-27,2015-11-11
-6b0d,2018-09-19,2017-09-14
-6b0k,2018-03-14,2017-09-14
-6b00,2017-12-13,2017-09-13
-7b05,2020-12-09,2020-11-18
-8b06,2023-05-03,2022-09-07
-6b0v,2018-05-16,2017-09-15
-6b0y,2018-05-16,2017-09-15
-7b00,2021-10-27,2020-11-17
-5b0q,2015-12-02,2015-11-02
-7b02,2021-05-19,2020-11-18
-7b0v,2021-11-03,2020-11-23
-6b0p,2018-01-03,2017-09-14
-8b0t,2022-12-28,2022-09-08
-3b0v,2011-12-14,2011-06-14
-2b06,2006-01-10,2005-09-13
-5b0s,2015-12-02,2015-11-02
-5b0x,2016-03-30,2015-11-13
-8b0b,2022-12-28,2022-09-07
-6b04,2017-12-13,2017-09-13
-8b0w,2023-09-20,2022-09-08
-1b0f,1998-11-09,1998-11-09
-4b0a,2013-07-03,2012-06-29
-2b0p,2006-01-10,2005-09-14
-8b0d,2022-12-28,2022-09-07
-6b0j,2018-03-14,2017-09-14
-1b0d,1998-11-11,1998-11-07
-1b0u,1999-11-17,1998-11-12
-8b04,2023-09-20,2022-09-07
-3b06,2011-11-02,2011-06-03
-1b0l,1999-11-18,1998-11-11
-1b0h,1998-11-11,1998-11-10
-6b06,2017-12-13,2017-09-13
-3b0r,2011-08-10,2011-06-13
-7b0d,2021-12-01,2020-11-19
-8b0x,2022-11-30,2022-09-08
-6b0f,2018-04-04,2017-09-14
-8b0z,2023-09-20,2022-09-08
-6b0b,2017-10-25,2017-09-14
-2b0e,2005-09-27,2005-09-13
-3b0z,2012-06-20,2011-06-17
-4b0p,2012-08-29,2012-07-04
-6b0z,2017-11-08,2017-09-15
-4b0c,2012-11-28,2012-07-01
-3b0o,2012-06-13,2011-06-10
-8b01,2023-03-15,2022-09-06
-8b0v,2024-03-27,2022-09-08
-9b03,2024-05-29,2024-03-11
-3b04,2011-11-02,2011-06-03
-1b05,1998-11-25,1998-11-20
-5b03,2016-03-23,2015-10-27
-5b0h,2016-07-06,2015-10-29
-6b0r,2018-01-03,2017-09-14
-5b0o,2016-03-23,2015-11-02
-2b0m,2005-09-27,2005-09-14
-3b0n,2012-02-22,2011-06-10
-8b0e,2022-12-28,2022-09-07
-1b02,1999-03-29,1998-11-16
-3b0m,2012-02-22,2011-06-10
-1b0b,2000-02-18,1998-11-06
-5b09,2016-01-27,2015-10-28
-2b03,2006-11-14,2005-09-12
-2b0v,2005-09-27,2005-09-14
-4b0q,2013-07-24,2012-07-04
-7b01,2021-04-28,2020-11-18
-3b0q,2011-08-10,2011-06-13
-8b0r,2022-11-16,2022-09-08
-2b0u,2005-10-11,2005-09-14
-3b0j,2012-02-22,2011-06-10
-3b0h,2012-02-22,2011-06-09
-5b07,2016-01-13,2015-10-28
-4b0s,2012-09-12,2012-07-04
-1b0g,1998-11-18,1998-11-09
-3b05,2011-11-02,2011-06-03
-2b0d,2005-09-27,2005-09-13
-7b0j,2020-12-09,2020-11-20
-1b09,1999-12-03,1998-11-18
-1b0i,1999-11-17,1998-11-10
-3b03,2011-11-02,2011-06-03
-2b0o,2005-09-20,2005-09-14
-4b0b,2012-11-28,2012-07-01
-3b0y,2012-05-02,2011-06-17
-8b03,2023-05-03,2022-09-07
-6b07,2017-12-13,2017-09-13
-3b08,2011-12-14,2011-06-07
-2b05,2005-10-11,2005-09-13
-4b00,2012-10-17,2012-06-27
-7b0s,2020-12-09,2020-11-21
-5b0r,2015-12-02,2015-11-02
-7b0t,2021-02-17,2020-11-21
-2b04,2006-11-14,2005-09-12
-7b0y,2021-01-13,2020-11-23
-5b06,2016-01-13,2015-10-28
-3b0k,2012-06-13,2011-06-10
-3b0t,2011-08-10,2011-06-14
-8b00,2023-06-07,2022-09-06
-5b00,2016-03-23,2015-10-27
-8b0p,2023-07-12,2022-09-07
-6b0o,2018-01-03,2017-09-14
-2b0f,2006-09-05,2005-09-13
-1b08,1999-12-01,1998-11-18
-4b0i,2012-11-28,2012-07-02
-1b0r,1999-11-25,1998-11-12
-4b0g,2013-03-13,2012-07-02
-7b0n,2021-03-10,2020-11-20
-7b0g,2020-12-30,2020-11-19
-6b0t,2018-04-18,2017-09-15
-2b08,2006-09-26,2005-09-13
-2b01,2006-11-14,2005-09-12
-4b02,2012-08-01,2012-06-27
-6b03,2018-06-20,2017-09-13
-5b0k,2016-03-23,2015-10-30
-8b0s,2022-12-28,2022-09-08
-3b0w,2011-07-06,2011-06-17
-6b05,2018-06-20,2017-09-13
-7b0a,2020-12-16,2020-11-19
-3b0i,2012-06-13,2011-06-10
-6b0n,2018-05-30,2017-09-14
-3b0g,2012-02-22,2011-06-09
-7b07,2020-12-30,2020-11-18
-4b0o,2012-08-29,2012-07-04
-6b0l,2018-05-02,2017-09-14
-3b0p,2011-12-14,2011-06-12
-7b0b,2021-12-01,2020-11-19
-2b07,2005-12-06,2005-09-13
-4b05,2012-10-17,2012-06-28
-1b07,1999-01-06,1998-11-17
-3b00,2011-11-23,2011-06-03
-1b06,1999-11-18,1998-11-16
-7pgc,2022-08-24,2021-08-13
-3pgj,2010-11-24,2010-11-02
-7pgu,2021-11-17,2021-08-15
-4pg9,2015-01-07,2014-05-01
-6pgf,2019-12-11,2019-06-24
-7pgy,2022-05-11,2021-08-16
-3pgl,2011-03-09,2010-11-02
-6pg3,2019-12-11,2019-06-24
-3pgx,2010-11-24,2010-11-02
-6pgj,2020-05-06,2019-06-24
-5pgz,2017-11-01,2017-02-06
-6pg6,2019-12-11,2019-06-24
-4pgi,2015-02-11,2014-05-02
-6pg2,2020-05-06,2019-06-23
-4pgb,2015-01-07,2014-05-01
-4pgq,2014-10-01,2014-05-02
-4pgf,2014-10-01,2014-05-01
-4pgt,1999-09-01,1999-03-22
-5pgy,2017-11-01,2017-02-06
-3pg3,2011-11-02,2010-10-29
-2pg5,2007-07-24,2007-04-06
-6pgy,2020-07-01,2019-06-25
-1pgp,1995-02-27,1994-07-18
-4pgn,2014-05-28,2014-05-02
-2pgz,2007-07-03,2007-04-10
-6pgi,2019-12-11,2019-06-24
-1pg3,2003-06-03,2003-05-27
-7pg7,2022-08-24,2021-08-13
-1pgo,1995-02-27,1994-07-18
-4pgz,2015-03-18,2014-05-03
-6pgl,2019-12-11,2019-06-24
-6pgs,2020-07-01,2019-06-24
-6pg7,2019-12-11,2019-06-24
-3pgi,2011-10-26,2010-11-02
-7pgj,2022-08-24,2021-08-14
-6pg5,2019-12-11,2019-06-24
-1pgg,1997-01-11,1995-12-02
-6pg9,2019-12-11,2019-06-24
-5pgv,2017-11-01,2017-02-06
-7pg6,2022-08-24,2021-08-13
-1pge,1997-01-11,1995-12-02
-6pgr,2020-04-01,2019-06-24
-1pgt,1997-09-04,1997-02-17
-4pgc,2015-01-07,2014-05-01
-4pgy,2015-05-06,2014-05-03
-6pgp,2019-12-25,2019-06-24
-7pgs,2021-11-17,2021-08-15
-2pgq,2007-07-17,2007-04-10
-1pg6,2003-12-02,2003-05-27
-1pgf,1997-01-11,1995-12-02
-6pgu,2019-10-23,2019-06-24
-1pgq,1995-02-27,1994-07-18
-6pgo,2019-12-25,2019-06-24
-1pg0,2004-02-17,2003-05-27
-4pg2,2014-09-10,2014-05-01
-7pgb,2022-06-08,2021-08-13
-2pgr,2007-04-24,2007-04-10
-1pg2,2004-02-17,2003-05-27
-2pg6,2007-07-24,2007-04-06
-3pgs,2011-05-25,2010-11-02
-5pgw,2017-11-01,2017-02-06
-6pgc,2019-12-11,2019-06-24
-3pg2,2011-03-02,2010-10-29
-4pgw,2014-06-04,2014-05-02
-7pgo,2022-08-24,2021-08-15
-6pge,2019-12-11,2019-06-24
-7pgr,2021-11-17,2021-08-15
-2pgl,2007-04-24,2007-04-09
-3pg0,2011-12-21,2010-10-29
-3pgh,1997-12-24,1996-12-18
-3pgf,2011-03-09,2010-11-01
-2pg7,2007-07-24,2007-04-06
-4pge,2015-01-07,2014-05-01
-7pgi,2022-06-08,2021-08-14
-4pgd,2015-01-07,2014-05-01
-7pga,2022-08-24,2021-08-13
-2pgt,1997-09-04,1997-02-17
-2pga,2008-04-15,2007-04-09
-7pgz,2022-05-11,2021-08-16
-5pgm,1999-02-16,1998-08-19
-6pg4,2019-12-11,2019-06-24
-6pgn,2019-07-24,2019-06-24
-2pg0,2007-05-08,2007-04-06
-6pg8,2019-12-11,2019-06-24
-3pgv,2010-12-15,2010-11-02
-1pg5,2004-06-08,2003-05-27
-4pg7,2015-05-06,2014-05-01
-2pgh,1994-11-30,1994-09-16
-2pgf,2007-04-24,2007-04-09
-1pg8,2004-06-08,2003-05-28
-2pg2,2007-06-05,2007-04-06
-1pgl,2003-11-18,2003-05-28
-6pgk,2019-11-27,2019-06-24
-5pgx,2017-11-01,2017-02-06
-6pgw,2020-12-30,2019-06-24
-7pg1,2022-08-24,2021-08-12
-3pgu,2011-05-25,2010-11-02
-4pgl,2014-10-22,2014-05-02
-6pgq,2020-02-12,2019-06-24
-2pgo,2008-04-22,2007-04-10
-6pgx,2019-08-21,2019-06-25
-7pgx,2022-05-11,2021-08-16
-4pg0,2014-11-26,2014-05-01
-7pgt,2021-11-17,2021-08-15
-2pgv,2007-07-24,2007-04-10
-6pgd,2019-12-11,2019-06-24
-2pg3,2007-04-24,2007-04-06
-5pgu,2017-11-01,2017-02-06
-4pg3,2014-07-16,2014-05-01
-3pgp,2010-12-01,2010-11-02
-2pg8,2008-01-22,2007-04-09
-7pgq,2022-10-26,2021-08-15
-4pgh,2014-07-02,2014-05-02
-2pgj,2007-04-24,2007-04-09
-3pg9,2011-01-26,2010-10-31
-1pg4,2003-06-03,2003-05-27
-3pgq,2010-12-22,2010-11-02
-8pg0,2023-09-27,2023-06-17
-6pgb,2019-12-11,2019-06-24
-3pgy,2010-11-17,2010-11-02
-1pgn,1995-02-27,1994-07-18
-6pgz,2020-07-01,2019-06-25
-6pga,2019-12-11,2019-06-24
-3pgt,1999-09-01,1999-03-22
-4pg1,2014-11-19,2014-05-01
-4pgp,2014-06-18,2014-05-02
-4pgx,2014-09-24,2014-05-03
-6pg1,2020-07-01,2019-06-23
-2pgn,2008-04-22,2007-04-10
-4pgk,2014-12-24,2014-05-02
-3pgb,2011-07-13,2010-11-01
-2pgb,2007-07-17,2007-04-09
-3pgk,1982-09-24,1982-07-15
-1pgu,2003-07-15,2003-05-28
-7yf4,2023-04-12,2022-07-07
-1yfq,2005-01-11,2005-01-03
-2yfi,2011-06-08,2011-04-06
-1yfc,1997-03-12,1996-08-08
-7yfn,2023-03-08,2022-07-08
-1yf4,2005-05-24,2004-12-30
-5yf9,2018-05-16,2017-09-20
-7yfi,2023-03-29,2022-07-08
-1yf3,2005-05-17,2004-12-30
-4yfb,2016-03-02,2015-02-25
-6yf6,2021-04-07,2020-03-26
-6yfg,2020-09-02,2020-03-26
-7yfg,2023-03-29,2022-07-08
-2yfl,2012-05-16,2011-04-06
-4yfi,2015-09-23,2015-02-25
-7yff,2023-04-12,2022-07-08
-4yf5,2015-05-06,2015-02-25
-4yfn,2015-03-11,2015-02-25
-1yfj,2005-05-17,2005-01-02
-6yfe,2020-09-02,2020-03-26
-2yfe,2012-04-11,2011-04-05
-1yfu,2005-05-31,2005-01-04
-5yfd,2018-01-03,2017-09-20
-5yf4,2018-08-15,2017-09-20
-1yff,2005-01-11,2004-12-31
-6yfn,2020-09-02,2020-03-26
-2yfu,2011-05-18,2011-04-08
-2yfy,2011-06-29,2011-04-11
-4yfl,2015-06-03,2015-02-25
-4yfy,2015-03-11,2015-02-25
-1yfw,2005-05-31,2005-01-04
-1yf6,2005-05-17,2004-12-30
-2yf3,2011-07-06,2011-04-01
-7yfq,2024-02-14,2022-07-08
-7yf0,2023-03-29,2022-07-07
-6yfw,2020-04-08,2020-03-26
-6yfx,2020-04-08,2020-03-26
-6yf8,2021-04-07,2020-03-26
-2yfo,2011-09-28,2011-04-07
-5yfu,2018-02-14,2017-09-22
-4yfz,2015-09-30,2015-02-25
-6yfc,2020-09-02,2020-03-26
-7yfk,2023-06-14,2022-07-08
-5yf2,2018-08-01,2017-09-20
-7yf3,2023-04-12,2022-07-07
-6yfy,2020-06-10,2020-03-26
-4yff,2015-09-23,2015-02-25
-7yfp,2023-04-19,2022-07-08
-4yfr,2016-03-02,2015-02-25
-1yfx,2005-05-31,2005-01-04
-2yfd,2011-07-06,2011-04-05
-1yfr,2005-01-25,2005-01-03
-2yfc,2011-07-06,2011-04-05
-4yf1,2015-03-04,2015-02-24
-1yfy,2005-05-31,2005-01-04
-5yfs,2018-02-14,2017-09-22
-2yfn,2011-09-28,2011-04-07
-5yfi,2018-12-05,2017-09-21
-1yf8,2005-03-08,2004-12-31
-5yf0,2018-08-01,2017-09-20
-6yf0,2021-03-10,2020-03-25
-4yfq,2016-03-02,2015-02-25
-2yfs,2011-08-03,2011-04-07
-7yft,2023-05-24,2022-07-09
-1yft,2005-01-25,2005-01-03
-2yfj,2011-06-08,2011-04-06
-2yfx,2011-05-04,2011-04-08
-5yfm,2017-10-25,2017-09-21
-1yfd,2005-02-15,2004-12-31
-6yf1,2021-03-10,2020-03-25
-7yfl,2023-04-12,2022-07-08
-5yfv,2018-02-14,2017-09-22
-5yf1,2018-08-01,2017-09-20
-5yfy,2018-09-26,2017-09-22
-6yfk,2020-09-02,2020-03-26
-7yfd,2023-10-25,2022-07-08
-6yf3,2021-03-10,2020-03-25
-6yfa,2020-09-02,2020-03-26
-7yfh,2023-03-29,2022-07-08
-7yfc,2023-10-25,2022-07-08
-1yf1,2005-08-16,2004-12-29
-2yft,2011-08-03,2011-04-07
-5yfw,2018-02-14,2017-09-22
-5yfb,2018-01-03,2017-09-20
-4yfu,2015-07-22,2015-02-25
-1yfz,2005-05-10,2005-01-04
-2yfz,2011-05-18,2011-04-11
-4yfx,2015-03-11,2015-02-25
-5yfn,2017-10-25,2017-09-21
-4yf6,2015-05-06,2015-02-25
-1yfh,2005-12-13,2004-12-31
-1yfs,2005-01-25,2005-01-03
-6yf2,2021-03-10,2020-03-25
-4yfg,2015-05-06,2015-02-25
-4yft,2016-06-29,2015-02-25
-7yf2,2023-04-12,2022-07-07
-7yfx,2024-01-24,2022-07-09
-5yfz,2018-06-06,2017-09-22
-1yfl,2005-05-17,2005-01-03
-4yf4,2015-05-06,2015-02-25
-2yfa,2012-04-18,2011-04-05
-7yf6,2022-11-02,2022-07-07
-2yfr,2011-08-03,2011-04-07
-7yfr,2023-04-12,2022-07-09
-5yfj,2018-02-14,2017-09-21
-1yfi,2006-01-10,2005-01-02
-4yfk,2015-03-11,2015-02-25
-6yfm,2020-09-02,2020-03-26
-4yfd,2015-05-06,2015-02-25
-7yfe,2023-03-29,2022-07-08
-6yf4,2020-09-02,2020-03-25
-5yfx,2018-02-14,2017-09-22
-7yfy,2024-01-24,2022-07-09
-5yft,2018-02-14,2017-09-22
-4yfp,2016-03-02,2015-02-25
-6yfv,2021-05-05,2020-03-26
-6ajp,2019-05-29,2018-08-28
-4aj9,2013-03-06,2012-02-16
-5ajl,2015-10-07,2015-02-25
-7ajr,2021-02-10,2020-09-29
-8ajl,2023-08-16,2022-07-28
-2ajv,2006-02-14,2005-08-02
-5aj0,2015-05-20,2015-02-19
-2ajy,2006-02-14,2005-08-02
-3ajr,2011-06-15,2010-06-14
-7aja,2021-05-26,2020-09-28
-1ajc,1995-11-14,1995-07-18
-4aj2,2012-03-21,2012-02-15
-3ajq,2010-08-25,2010-06-11
-4ajh,2012-03-21,2012-02-16
-4aj3,2012-10-31,2012-02-15
-5ajv,2015-04-22,2015-02-27
-7ajs,2021-05-26,2020-09-29
-1aj4,1998-05-20,1997-05-14
-4ajo,2012-03-21,2012-02-16
-7ajv,2021-05-26,2020-09-29
-4aj1,2012-03-21,2012-02-15
-1ajq,1997-11-12,1997-05-07
-5ajx,2015-04-22,2015-02-27
-8ajm,2022-11-09,2022-07-28
-1ajg,1997-11-12,1997-05-02
-4ajc,2012-10-31,2012-02-16
-1ajp,1997-11-12,1997-05-07
-4ajn,2012-03-21,2012-02-16
-8ajp,2022-08-31,2022-07-28
-8ajy,2022-11-02,2022-07-28
-8ajt,2023-08-16,2022-07-28
-4aj4,2012-03-21,2012-02-15
-3aj7,2010-08-11,2010-05-26
-3aj9,2011-06-22,2010-05-27
-6aj6,2019-08-28,2018-08-27
-6ajx,2019-06-12,2018-08-28
-1ajo,1998-05-06,1997-05-07
-7ajw,2021-05-26,2020-09-29
-1ajk,1998-05-06,1997-05-06
-1ajx,1997-09-17,1997-05-11
-8aj3,2022-11-23,2022-07-27
-6ajo,2019-05-29,2018-08-28
-2ajh,2006-01-24,2005-08-02
-8aja,2023-08-16,2022-07-27
-3ajz,2011-05-18,2010-06-29
-5aj4,2015-04-22,2015-02-20
-1aj6,1998-05-20,1997-05-15
-3ajn,2011-02-16,2010-06-09
-5ajp,2015-03-11,2015-02-26
-1ajv,1997-08-20,1997-05-11
-7ajk,2020-11-18,2020-09-29
-5aj3,2015-04-22,2015-02-20
-6aja,2019-08-28,2018-08-27
-4ajb,2012-10-31,2012-02-16
-7ajy,2021-05-26,2020-09-29
-1ajd,1995-11-14,1995-08-18
-1ajj,1997-07-07,1997-05-04
-4aji,2012-03-21,2012-02-16
-8ajx,2023-01-18,2022-07-28
-6aj5,2019-08-28,2018-08-27
-7aj0,2021-09-08,2020-09-28
-3aj5,2011-06-01,2010-05-24
-5aj9,2016-03-16,2015-02-20
-2aj7,2005-11-15,2005-08-01
-4ajd,2013-03-06,2012-02-16
-2ajl,2005-11-08,2005-08-02
-1aj8,1997-11-19,1997-05-16
-6ajh,2018-12-26,2018-08-27
-8ajz,2023-08-16,2022-07-29
-7ajo,2021-10-06,2020-09-29
-3ajp,2010-08-25,2010-06-11
-5ajy,2015-04-22,2015-02-27
-5ajz,2015-04-22,2015-02-27
-3ajh,2011-03-16,2010-06-05
-6aji,2018-12-26,2018-08-27
-4ajp,2012-03-21,2012-02-16
-1aj0,1998-05-20,1997-05-14
-6ajj,2018-12-26,2018-08-27
-3aje,2011-04-13,2010-06-01
-1ajs,1997-08-20,1997-05-08
-3aj8,2011-06-22,2010-05-27
-6ajg,2018-12-26,2018-08-27
-4ajg,2013-03-06,2012-02-16
-6aju,2019-09-11,2018-08-28
-4aja,2012-10-31,2012-02-16
-4ajx,2013-01-09,2012-02-20
-3ajw,2011-02-02,2010-06-23
-1aj9,1998-05-20,1997-05-16
-2ajf,2005-09-20,2005-08-01
-5ajw,2015-04-22,2015-02-27
-2aj4,2005-08-30,2005-08-01
-3ajy,2011-05-18,2010-06-29
-8aj4,2022-11-23,2022-07-27
-2aji,2006-01-24,2005-08-02
-5ajc,2016-03-02,2015-02-20
-1ajb,1995-11-14,1995-08-19
-8aj5,2022-11-23,2022-07-27
-2ajz,2006-02-14,2005-08-02
-1ajn,1997-11-12,1997-05-07
-5ajg,2016-03-09,2015-02-24
-5aja,2015-04-22,2015-02-20
-1aj2,1998-05-20,1997-05-14
-5ajm,2015-03-25,2015-02-25
-4ajw,2012-05-16,2012-02-20
-6ajn,2019-01-02,2018-08-28
-4ajf,2013-03-06,2012-02-16
-4ajz,2013-01-09,2012-02-21
-5ajo,2015-03-11,2015-02-26
-7aju,2020-12-30,2020-09-29
-8ajw,2023-08-16,2022-07-28
-6ajd,2018-10-24,2018-08-27
-6ajz,2019-06-12,2018-08-28
-2ajb,2006-02-28,2005-08-01
-5ajr,2015-12-02,2015-02-26
-6ajv,2019-06-12,2018-08-28
-2ajr,2005-10-11,2005-08-02
-7ajz,2021-10-06,2020-09-29
-6ajb,2019-08-28,2018-08-27
-4ajr,2012-10-31,2012-02-17
-5aju,2015-06-03,2015-02-27
-4ajl,2012-03-21,2012-02-16
-5ajn,2015-03-11,2015-02-26
-7aj5,2021-05-26,2020-09-28
-8aj0,2023-08-16,2022-07-27
-3aj3,2011-05-25,2010-05-21
-3ajm,2010-06-30,2010-06-09
-6aje,2019-08-28,2018-08-27
-8ajq,2022-10-05,2022-07-28
-1ajy,1997-09-17,1997-05-12
-3ajg,2011-03-16,2010-06-05
-8aju,2023-08-16,2022-07-28
-4ajs,2012-10-31,2012-02-17
-8aj6,2022-12-14,2022-07-27
-2ajx,2006-02-14,2005-08-02
-6ajy,2019-06-12,2018-08-28
-4ajj,2012-03-21,2012-02-16
-8ajk,2023-03-01,2022-07-28
-5ajb,2016-03-02,2015-02-20
-7ajn,2020-12-02,2020-09-29
-2aj8,2006-02-28,2005-08-01
-6ajc,2019-08-28,2018-08-27
-7aj8,2021-05-26,2020-09-28
-7aj4,2021-05-26,2020-09-28
-7aj7,2021-05-26,2020-09-28
-2ajc,2006-02-28,2005-08-01
-6ajr,2019-05-29,2018-08-28
-6ajw,2019-06-12,2018-08-28
-2ajd,2006-02-28,2005-08-01
-7ajx,2021-10-06,2020-09-29
-8ajs,2023-08-16,2022-07-28
-7ajm,2021-05-26,2020-09-29
-3aj6,2011-06-01,2010-05-24
-6aj8,2019-08-28,2018-08-27
-3ajo,2010-08-25,2010-06-11
-6ajf,2018-12-26,2018-08-27
-4ajm,2013-03-06,2012-02-16
-4aje,2012-03-21,2012-02-16
-8ajj,2023-03-01,2022-07-28
-7ajt,2020-12-30,2020-09-29
-3ajx,2010-11-03,2010-06-24
-8ajv,2023-08-16,2022-07-28
-3aj4,2011-05-25,2010-05-21
-1aj7,1997-11-12,1997-05-15
-7aj2,2021-05-26,2020-09-28
-1ajh,1997-11-12,1997-05-02
-5ajq,2015-03-11,2015-02-26
-4ajk,2012-03-21,2012-02-16
-104m,1998-04-08,1997-12-18
-7s5f,2022-03-16,2021-09-10
-8s54,2024-04-17,2024-02-22
-6s54,2019-11-13,2019-06-30
-8s5m,2024-04-17,2024-02-23
-5s5t,2021-06-30,2020-11-08
-6s5w,2019-12-11,2019-07-02
-5s5h,2021-06-30,2020-11-08
-1s5z,2005-02-01,2004-01-22
-5s5a,2021-06-30,2020-11-08
-1s5f,2004-04-06,2004-01-20
-7s5z,2021-12-01,2021-09-12
-6s5p,2019-08-21,2019-07-02
-6s5h,2020-07-22,2019-07-01
-5s5n,2021-06-30,2020-11-08
-7s5y,2021-12-01,2021-09-12
-8s52,2024-04-17,2024-02-22
-5s5k,2021-06-30,2020-11-08
-1s5b,2004-04-06,2004-01-20
-6s5b,2020-01-08,2019-07-01
-6s5x,2019-12-11,2019-07-02
-6s5d,2020-01-08,2019-07-01
-6s5j,2020-04-08,2019-07-01
-5s5l,2021-06-30,2020-11-08
-3s56,2012-03-21,2011-05-20
-6s5v,2019-11-06,2019-07-02
-7s5v,2021-12-01,2021-09-12
-5s5f,2021-06-30,2020-11-08
-6s5n,2020-01-08,2019-07-02
-3s5y,2012-01-04,2011-05-23
-7s5r,2022-03-09,2021-09-11
-6s5q,2020-04-08,2019-07-02
-3s5e,2011-06-29,2011-05-23
-7s5e,2021-09-22,2021-09-10
-7s5o,2022-03-30,2021-09-11
-8s5k,2024-04-17,2024-02-23
-7s5q,2022-03-09,2021-09-11
-3s53,2012-03-21,2011-05-20
-1s56,2004-06-29,2004-01-20
-5s5y,2021-06-30,2020-11-08
-1s5n,2004-02-10,2004-01-21
-1s5o,2004-02-03,2004-01-21
-5s5j,2021-06-30,2020-11-08
-3s5k,2012-05-23,2011-05-23
-5s5u,2021-06-30,2020-11-08
-5s51,2021-06-30,2020-11-08
-1s5d,2004-04-06,2004-01-20
-3s5f,2011-06-29,2011-05-23
-3s5h,2012-05-23,2011-05-23
-6s5t,2019-07-24,2019-07-02
-1s5j,2004-11-09,2004-01-21
-5s5r,2021-06-30,2020-11-08
-8s5j,2024-04-17,2024-02-23
-5s5v,2021-06-30,2020-11-08
-5s5z,2021-06-30,2020-11-08
-6s51,2020-02-19,2019-06-29
-5s5o,2021-06-30,2020-11-08
-3s57,2012-06-06,2011-05-20
-5s5m,2021-06-30,2020-11-08
-7s5h,2021-11-03,2021-09-10
-3s5n,2011-10-26,2011-05-23
-5s5g,2021-06-30,2020-11-08
-6s58,2020-05-20,2019-06-30
-3s5x,2011-06-15,2011-05-23
-6s55,2019-08-21,2019-06-30
-1s5x,2004-05-04,2004-01-22
-7s51,2022-09-07,2021-09-09
-5s5c,2021-06-30,2020-11-08
-1s51,2004-03-02,2004-01-19
-1s54,2004-03-02,2004-01-19
-3s5o,2011-10-26,2011-05-23
-1s59,2004-11-30,2004-01-20
-8s5n,2024-04-10,2024-02-24
-6s5s,2019-08-21,2019-07-02
-6s53,2019-09-11,2019-06-30
-6s5e,2020-01-08,2019-07-01
-5s5s,2021-06-30,2020-11-08
-6s5r,2019-08-21,2019-07-02
-3s5a,2012-06-06,2011-05-21
-3s5w,2011-07-13,2011-05-23
-5s50,2021-06-30,2020-11-08
-3s55,2011-06-08,2011-05-20
-1s5s,2004-03-16,2004-01-21
-3s5b,2012-01-11,2011-05-23
-1s53,2004-03-02,2004-01-19
-8s5l,2024-04-17,2024-02-23
-6s5o,2020-01-08,2019-07-02
-6s5m,2020-04-08,2019-07-02
-5s58,2021-06-30,2020-11-08
-7s5t,2021-12-01,2021-09-12
-5s56,2021-06-30,2020-11-08
-1s5k,2004-05-18,2004-01-21
-6s52,2020-02-19,2019-06-29
-3s5z,2012-01-04,2011-05-23
-5s5p,2021-06-30,2020-11-08
-5s59,2021-06-30,2020-11-08
-1s50,2005-02-08,2004-01-19
-6s5c,2020-01-08,2019-07-01
-6s5u,2020-04-08,2019-07-02
-7s50,2021-10-27,2021-09-09
-5s5q,2021-06-30,2020-11-08
-6s57,2019-08-21,2019-06-30
-1s5y,2004-05-04,2004-01-22
-8s55,2024-04-17,2024-02-22
-5s5b,2021-06-30,2020-11-08
-7s5p,2022-03-09,2021-09-11
-1s52,2004-03-02,2004-01-19
-5s5w,2021-06-30,2020-11-08
-6s5g,2020-01-08,2019-07-01
-8s5h,2024-04-17,2024-02-23
-1s5h,2004-05-18,2004-01-20
-5s5d,2021-06-30,2020-11-08
-8s51,2024-04-17,2024-02-22
-1s5e,2004-04-06,2004-01-20
-5s52,2021-06-30,2020-11-08
-7s5k,2022-02-02,2021-09-10
-5s54,2021-06-30,2020-11-08
-6s5a,2019-09-25,2019-07-01
-5s5e,2021-06-30,2020-11-08
-3s54,2012-03-21,2011-05-20
-5s5x,2021-06-30,2020-11-08
-6s5k,2019-12-18,2019-07-01
-1s5l,2004-02-24,2004-01-21
-5s5i,2021-06-30,2020-11-08
-7s5x,2021-12-01,2021-09-12
-6s5z,2019-12-11,2019-07-02
-5s53,2021-06-30,2020-11-08
-5s55,2021-06-30,2020-11-08
-7s5g,2021-11-03,2021-09-10
-1s5p,2004-03-23,2004-01-21
-1s5m,2004-02-10,2004-01-21
-1s5g,2004-06-22,2004-01-20
-6s56,2019-08-21,2019-06-30
-3s5u,2011-06-22,2011-05-23
-6s5i,2021-12-01,2019-07-01
-1s5c,2004-04-06,2004-01-20
-7s5c,2022-02-02,2021-09-10
-8s5i,2024-04-17,2024-02-23
-3s5m,2012-05-23,2011-05-23
-6s5f,2020-07-22,2019-07-01
-5s57,2021-06-30,2020-11-08
-4ny9,2014-08-27,2013-12-10
-7nyj,2021-07-07,2021-03-22
-3nyk,2010-10-20,2010-07-15
-1ny2,2003-03-04,2003-02-11
-2nyj,2007-07-03,2006-11-20
-6nyp,2019-05-29,2019-02-11
-3nyx,2010-10-20,2010-07-15
-2nyu,2006-12-05,2006-11-21
-2nym,2006-12-12,2006-11-21
-3nyu,2010-07-28,2010-07-15
-5nyn,2018-02-28,2017-05-11
-4nyz,2014-03-19,2013-12-11
-7nyx,2021-07-07,2021-03-23
-7nyu,2021-08-25,2021-03-23
-2ny3,2007-02-06,2006-11-20
-2nyl,2006-12-12,2006-11-20
-6ny9,2020-01-22,2019-02-11
-6ny7,2019-09-25,2019-02-11
-4nyo,2014-01-01,2013-12-11
-3nyr,2011-03-30,2010-07-15
-1nyy,2003-08-26,2003-02-14
-5nyq,2017-05-24,2017-05-11
-7ny1,2021-11-17,2021-03-19
-6ny6,2019-08-21,2019-02-11
-4nyn,2014-02-12,2013-12-11
-1ny3,2003-10-14,2003-02-11
-5ny7,2018-05-30,2017-05-11
-5ny1,2018-01-17,2017-05-11
-1nyq,2003-10-28,2003-02-13
-2ny2,2007-02-06,2006-11-20
-5nyi,2018-05-30,2017-05-11
-7ny8,2021-07-07,2021-03-21
-1ny0,2003-08-26,2003-02-11
-6nyt,2019-02-20,2019-02-12
-2nyb,2006-12-05,2006-11-20
-4nyx,2014-01-29,2013-12-11
-2ny4,2007-02-06,2006-11-20
-6nyw,2019-03-27,2019-02-12
-6nyo,2019-08-07,2019-02-11
-3ny0,2010-08-25,2010-07-14
-7nyt,2022-03-09,2021-03-23
-3nyn,2010-09-22,2010-07-15
-4nyi,2014-03-12,2013-12-10
-5nye,2018-05-30,2017-05-11
-7ny7,2021-11-24,2021-03-21
-4ny2,2014-08-13,2013-12-10
-5nyp,2017-05-24,2017-05-11
-4nyp,2014-01-01,2013-12-11
-5nyf,2017-05-24,2017-05-11
-3nyt,2010-07-28,2010-07-15
-1ny5,2003-11-11,2003-02-11
-1nyw,2003-06-24,2003-02-14
-6nyb,2019-10-09,2019-02-11
-7ny9,2022-11-02,2021-03-22
-2nyy,2006-12-26,2006-11-21
-3nye,2010-09-15,2010-07-14
-7nyl,2021-12-22,2021-03-23
-3nyb,2010-08-04,2010-07-14
-2nyt,2007-01-09,2006-11-21
-7ny2,2022-11-02,2021-03-19
-3nyf,2010-09-15,2010-07-15
-7nyp,2022-04-13,2021-03-23
-5nyb,2018-06-13,2017-05-11
-4ny5,2014-03-26,2013-12-10
-1nya,2003-08-05,2003-02-12
-6ny8,2020-04-22,2019-02-11
-6nyy,2019-05-22,2019-02-12
-2ny7,2007-02-06,2006-11-20
-3nys,2010-07-28,2010-07-15
-5nyy,2017-06-07,2017-05-12
-4nyr,2014-01-01,2013-12-11
-7nyr,2021-08-25,2021-03-23
-7nyf,2021-06-09,2021-03-22
-3ny3,2010-08-11,2010-07-14
-5nyz,2017-09-20,2017-05-12
-1nyp,2003-07-01,2003-02-13
-3nyj,2011-06-01,2010-07-15
-2nyq,2007-10-30,2006-11-21
-1nyk,2003-06-24,2003-02-12
-4nym,2014-03-12,2013-12-10
-4nyf,2014-06-25,2013-12-10
-7nya,2022-11-02,2021-03-22
-4ny3,2014-07-23,2013-12-10
-6nya,2019-08-07,2019-02-11
-2ny5,2007-02-06,2006-11-20
-7nyy,2021-07-07,2021-03-23
-4ny8,2014-04-16,2013-12-10
-6ny0,2019-05-29,2019-02-10
-4ny4,2014-08-13,2013-12-10
-6nyq,2020-01-22,2019-02-12
-2nyk,2007-05-29,2006-11-20
-7nyd,2021-10-06,2021-03-22
-3ny6,2010-12-29,2010-07-14
-3ny1,2010-08-11,2010-07-14
-3nyo,2010-09-22,2010-07-15
-4nyt,2014-10-29,2013-12-11
-2ny6,2007-02-06,2006-11-20
-7nyw,2021-07-07,2021-03-23
-3ny2,2010-08-11,2010-07-14
-1nyx,2003-07-15,2003-02-14
-4nyj,2014-03-12,2013-12-10
-3nya,2010-08-11,2010-07-14
-4nyv,2014-01-29,2013-12-11
-3nyd,2011-06-29,2010-07-14
-5ny6,2018-01-17,2017-05-11
-3ny8,2010-08-11,2010-07-14
-4nyw,2014-01-29,2013-12-11
-7nys,2022-04-13,2021-03-23
-4ny1,2015-01-07,2013-12-10
-7nyv,2021-08-25,2021-03-23
-1nyt,2003-03-04,2003-02-13
-4ny7,2015-03-04,2013-12-10
-3nyv,2010-07-28,2010-07-15
-4nyu,2014-08-13,2013-12-11
-3nyq,2011-03-30,2010-07-15
-7nyg,2021-06-09,2021-03-22
-2ny0,2007-02-06,2006-11-20
-7nyc,2021-10-06,2021-03-22
-3nyg,2011-11-02,2010-07-15
-7nye,2021-06-09,2021-03-22
-5nyk,2018-02-28,2017-05-11
-2ny1,2007-02-06,2006-11-20
-2nyg,2006-12-12,2006-11-20
-7ny3,2022-03-30,2021-03-20
-5nym,2018-02-28,2017-05-11
-3ny4,2010-11-24,2010-07-14
-5nyh,2018-04-18,2017-05-11
-5ny3,2018-01-17,2017-05-11
-2nyr,2006-12-19,2006-11-21
-3ny9,2010-08-11,2010-07-14
-2nyp,2007-05-22,2006-11-21
-6ny4,2019-05-22,2019-02-11
-2nyd,2007-01-09,2006-11-20
-1ny6,2003-11-11,2003-02-11
-4nyq,2014-01-01,2013-12-11
-1nym,2003-08-26,2003-02-12
-4nye,2014-04-02,2013-12-10
-3ny7,2010-12-01,2010-07-14
-6nyv,2019-03-27,2019-02-12
-4nyy,2014-08-13,2013-12-11
-7nyz,2021-07-07,2021-03-23
-7ny4,2021-06-09,2021-03-20
-6nyh,2019-05-29,2019-02-11
-1nyr,2003-10-28,2003-02-13
-7nyb,2021-09-15,2021-03-22
-5nya,2018-01-17,2017-05-11
-2nya,2006-12-05,2006-11-20
-6nyd,2019-08-07,2019-02-11
-3nyc,2010-09-22,2010-07-14
-5ojg,2017-11-22,2017-07-21
-1ojz,2003-08-28,2003-07-16
-4ojm,2014-04-16,2014-01-21
-5ojk,2017-08-23,2017-07-21
-1oj7,2004-07-08,2003-07-03
-6ojk,2019-11-20,2019-04-11
-7ojo,2022-06-01,2021-05-17
-8oj6,2024-04-03,2023-03-24
-5ojn,2017-11-29,2017-07-22
-1oji,2004-01-07,2003-07-10
-5oj7,2017-11-29,2017-07-20
-1ojp,2003-10-30,2003-07-11
-4oj6,2014-03-26,2014-01-20
-7oj0,2021-09-15,2021-05-13
-7ojk,2021-12-01,2021-05-16
-5oj5,2018-08-08,2017-07-20
-5ojb,2018-01-24,2017-07-21
-1oj4,2003-07-31,2003-06-30
-4ojj,2014-10-08,2014-01-21
-3oju,2010-12-15,2010-08-23
-3oji,2011-08-10,2010-08-23
-8ojd,2024-04-03,2023-03-24
-3ojw,2011-02-23,2010-08-23
-3ojn,2010-12-29,2010-08-23
-3ojf,2010-09-08,2010-08-22
-4ojr,2014-06-11,2014-01-21
-5ojv,2018-08-08,2017-07-24
-6ojz,2019-11-20,2019-04-12
-1ojj,2004-01-07,2003-07-10
-8ojl,2024-04-03,2023-03-24
-7ojh,2021-07-21,2021-05-15
-3ojy,2011-04-13,2010-08-23
-6ojt,2019-07-24,2019-04-12
-6oj1,2019-08-14,2019-04-10
-8oj8,2024-02-21,2023-03-24
-2oj9,2007-05-01,2007-01-12
-3oj6,2010-09-15,2010-08-20
-2ojx,2007-02-13,2007-01-15
-7ojb,2022-03-02,2021-05-14
-3oj4,2010-12-08,2010-08-20
-1oj9,2003-08-15,2003-07-08
-3ojg,2010-10-27,2010-08-22
-3ojl,2011-03-23,2010-08-23
-7ojz,2022-03-02,2021-05-17
-5oju,2018-08-08,2017-07-24
-3ojt,2010-12-29,2010-08-23
-4ojq,2014-03-05,2014-01-21
-4ojo,2014-03-26,2014-01-21
-8ojh,2023-07-19,2023-03-24
-6oj2,2020-06-24,2019-04-10
-7oja,2022-03-02,2021-05-14
-6ojb,2019-08-14,2019-04-11
-4oj8,2014-04-02,2014-01-20
-7ojp,2021-10-13,2021-05-17
-5oj2,2017-08-23,2017-07-20
-3ojs,2010-12-15,2010-08-23
-2ojj,2007-02-06,2007-01-12
-5oje,2018-09-12,2017-07-21
-7oj7,2021-10-13,2021-05-14
-4oj9,2014-08-20,2014-01-20
-1ojt,1997-10-15,1996-09-06
-3ojk,2010-12-29,2010-08-23
-8oj5,2024-02-21,2023-03-23
-8ojt,2023-06-14,2023-03-24
-8ojb,2024-04-03,2023-03-24
-4oj1,2014-02-05,2014-01-20
-8oj7,2024-04-03,2023-03-24
-2oj1,2007-11-27,2007-01-12
-6ojv,2019-06-19,2019-04-12
-4oju,2014-06-18,2014-01-21
-5oj1,2018-05-30,2017-07-20
-5oj0,2018-05-30,2017-07-20
-7ojl,2021-12-01,2021-05-16
-1ojd,2003-08-15,2003-07-08
-3oj3,2010-12-08,2010-08-20
-2ojf,2007-03-20,2007-01-12
-2oji,2007-02-06,2007-01-12
-5ojh,2018-08-08,2017-07-21
-1oj1,2004-07-15,2003-06-28
-6oja,2019-08-07,2019-04-11
-5oj6,2017-08-23,2017-07-20
-4ojf,2015-01-28,2014-01-21
-7ojc,2022-03-02,2021-05-14
-3oj8,2011-07-06,2010-08-20
-4oja,2015-01-28,2014-01-21
-4ojl,2014-03-26,2014-01-21
-3ojp,2011-03-02,2010-08-23
-2oj2,2007-01-30,2007-01-12
-3ojj,2010-12-29,2010-08-23
-6ojp,2019-08-21,2019-04-11
-6ojd,2019-09-11,2019-04-11
-6ojh,2020-02-12,2019-04-11
-1oj6,2003-09-11,2003-07-03
-6oje,2020-10-14,2019-04-11
-8ojk,2023-09-13,2023-03-24
-5ojz,2018-08-29,2017-07-25
-7ojd,2022-03-02,2021-05-14
-7oju,2022-09-28,2021-05-17
-7oj8,2021-07-21,2021-05-14
-1ojn,2003-10-30,2003-07-11
-7ojg,2022-08-03,2021-05-14
-4ojd,2014-05-14,2014-01-21
-7oj1,2022-09-14,2021-05-13
-6ojw,2019-07-24,2019-04-12
-7oj5,2021-06-02,2021-05-13
-8oj0,2024-02-21,2023-03-23
-7ojy,2021-10-06,2021-05-17
-1ojl,2005-05-19,2003-07-10
-2oj5,2007-02-13,2007-01-12
-5ojy,2018-04-11,2017-07-24
-6ojr,2019-07-24,2019-04-12
-4ojt,2014-03-26,2014-01-21
-7ojm,2022-06-01,2021-05-16
-5oja,2018-01-24,2017-07-21
-6ojf,2020-10-14,2019-04-11
-1ojc,2003-08-15,2003-07-08
-6ojl,2019-11-20,2019-04-11
-6ojo,2020-04-15,2019-04-11
-8oja,2024-04-03,2023-03-24
-8oji,2023-09-13,2023-03-24
-5ojo,2017-11-29,2017-07-22
-3oj7,2010-09-08,2010-08-20
-3ojc,2010-09-15,2010-08-21
-8ojo,2023-09-13,2023-03-24
-7ojq,2021-10-13,2021-05-17
-5ojc,2018-01-24,2017-07-21
-3ojo,2011-03-23,2010-08-23
-5ojm,2017-10-04,2017-07-21
-8oju,2023-06-14,2023-03-24
-3oja,2010-09-22,2010-08-20
-4ojp,2014-03-26,2014-01-21
-6oju,2019-06-19,2019-04-12
-1ojo,2003-10-30,2003-07-11
-7ojw,2021-10-13,2021-05-17
-4ojz,2014-01-29,2014-01-21
-6ojs,2019-06-19,2019-04-12
-4ojk,2014-08-06,2014-01-21
-6ojq,2020-04-15,2019-04-12
-1oja,2003-08-15,2003-07-08
-2ojy,2007-05-01,2007-01-15
-4ojc,2014-05-14,2014-01-21
-3ojx,2011-02-23,2010-08-23
-4oj4,2015-02-04,2014-01-20
-1ojm,2003-10-30,2003-07-11
-6ojx,2019-11-20,2019-04-12
-5ojl,2018-05-30,2017-07-21
-7oj6,2021-10-13,2021-05-14
-5ojj,2017-10-04,2017-07-21
-5oj4,2018-08-08,2017-07-20
-3oj1,2011-08-24,2010-08-20
-7ojj,2021-12-01,2021-05-16
-4ojv,2014-12-03,2014-01-21
-4oje,2014-05-14,2014-01-21
-1ojr,2003-09-11,2003-07-15
-7ojx,2022-01-12,2021-05-17
-5oj9,2018-01-24,2017-07-21
-8ojm,2023-09-13,2023-03-24
-2oju,2008-01-22,2007-01-14
-1ojk,2004-01-07,2003-07-10
-4ojx,2014-12-03,2014-01-21
-2ojw,2007-03-13,2007-01-15
-2oj6,2007-02-13,2007-01-12
-2ojv,2007-01-30,2007-01-15
-2ojr,2007-06-12,2007-01-13
-7ojn,2021-12-01,2021-05-16
-4oj5,2014-03-26,2014-01-20
-5oji,2017-11-22,2017-07-21
-7oje,2022-02-02,2021-05-14
-7oji,2021-07-21,2021-05-16
-4ojb,2014-08-20,2014-01-21
-2ojt,2007-04-03,2007-01-14
-2ojg,2007-02-06,2007-01-12
-7ojf,2022-07-27,2021-05-14
-1oj8,2004-07-15,2003-07-07
-8ojc,2024-04-03,2023-03-24
-1g9h,2002-06-26,2000-11-23
-1g9a,2002-11-13,2000-11-22
-6g9i,2018-05-23,2018-04-10
-1g9v,2000-12-06,2000-11-28
-8g9n,2023-04-12,2023-02-21
-4g9a,2013-06-26,2012-07-23
-8g9w,2023-04-19,2023-02-22
-8g9c,2024-01-03,2023-02-21
-8g96,2023-10-04,2023-02-21
-4g9p,2012-09-26,2012-07-24
-1g94,2001-12-12,2000-11-22
-7g9c,2023-07-12,2023-06-22
-3g9i,2009-04-21,2009-02-13
-3g9d,2009-07-14,2009-02-13
-1g99,2000-12-27,2000-11-22
-7g93,2023-07-12,2023-06-22
-1g9j,2003-06-24,2000-11-24
-1g93,2001-05-20,2000-11-22
-1g9w,2001-04-18,2000-11-28
-7g98,2023-07-12,2023-06-22
-2g9y,2006-10-10,2006-03-07
-6g91,2018-05-30,2018-04-10
-8g99,2023-04-12,2023-02-21
-2g9v,2007-01-16,2006-03-07
-1g9g,2003-06-24,2000-11-23
-4g9g,2013-01-16,2012-07-23
-7g9d,2023-07-12,2023-06-22
-8g91,2024-04-17,2023-02-20
-3g9o,2009-04-21,2009-02-13
-1g9u,2001-10-10,2000-11-28
-1g9y,2001-04-02,2000-11-28
-6g9f,2019-05-22,2018-04-10
-4g98,2012-10-31,2012-07-23
-7g9f,2023-07-12,2023-06-22
-2g9a,2006-09-06,2006-03-06
-1g9k,2003-02-14,2000-11-24
-6g9m,2018-05-30,2018-04-11
-3g9p,2009-04-14,2009-02-13
-4g9e,2013-01-16,2012-07-23
-4g9i,2012-10-24,2012-07-24
-3g9m,2009-04-21,2009-02-13
-7g96,2023-07-12,2023-06-22
-6g98,2018-07-04,2018-04-10
-8g9z,2023-04-05,2023-02-22
-2g9u,2007-01-16,2006-03-07
-3g93,2009-05-12,2009-02-12
-7g94,2023-07-12,2023-06-22
-7g9l,2023-07-26,2023-07-03
-7g92,2023-07-12,2023-06-22
-2g9q,2007-01-16,2006-03-07
-6g9h,2018-05-30,2018-04-10
-3g9k,2009-06-16,2009-02-13
-2g94,2006-04-25,2006-03-05
-2g9r,2007-01-16,2006-03-07
-7g9x,2023-07-26,2023-07-03
-4g9r,2012-11-14,2012-07-24
-8g9l,2023-04-12,2023-02-21
-1g9b,2002-11-13,2000-11-22
-7g99,2023-07-12,2023-06-22
-1g9m,2000-12-27,2000-11-24
-7g9h,2023-07-12,2023-06-22
-4g9k,2012-09-05,2012-07-24
-6g9u,2018-07-04,2018-04-11
-3g9n,2009-02-24,2009-02-13
-4g9h,2012-08-15,2012-07-23
-3g9e,2009-06-02,2009-02-13
-2g97,2006-08-01,2006-03-05
-2g9t,2006-08-15,2006-03-07
-7g9u,2023-07-26,2023-07-03
-6g97,2018-05-30,2018-04-10
-7g90,2023-07-12,2023-06-22
-2g96,2006-08-01,2006-03-05
-6g99,2019-02-20,2018-04-10
-1g98,2001-06-01,2000-11-22
-6g9k,2018-05-30,2018-04-11
-4g97,2014-03-12,2012-07-23
-1g9f,2001-06-13,2000-11-23
-7g9n,2023-07-26,2023-07-03
-4g99,2012-10-31,2012-07-23
-6g96,2018-05-16,2018-04-10
-7g9t,2023-07-26,2023-07-03
-4g93,2013-07-24,2012-07-23
-4g90,2012-11-21,2012-07-23
-7g9y,2023-07-26,2023-07-03
-6g94,2018-06-13,2018-04-10
-7g9z,2023-07-26,2023-07-03
-6g9j,2018-05-30,2018-04-10
-7g9p,2023-07-26,2023-07-03
-8g9e,2024-01-03,2023-02-21
-1g9c,2002-11-13,2000-11-22
-3g9j,2009-04-21,2009-02-13
-7g9b,2023-07-12,2023-06-22
-4g9c,2012-11-14,2012-07-23
-4g9b,2012-08-15,2012-07-23
-4g9l,2013-05-29,2012-07-24
-8g9u,2024-03-06,2023-02-22
-8g93,2023-08-09,2023-02-21
-2g99,2006-09-06,2006-03-06
-8g9f,2023-04-12,2023-02-21
-2g9h,2006-07-11,2006-03-06
-3g99,2009-04-21,2009-02-13
-8g97,2023-10-04,2023-02-21
-2g9z,2006-04-04,2006-03-07
-7g97,2023-07-12,2023-06-22
-6g9r,2019-04-24,2018-04-11
-4g9o,2013-03-13,2012-07-24
-2g93,2006-03-21,2006-03-05
-3g97,2009-04-21,2009-02-13
-6g9v,2019-04-24,2018-04-11
-4g9z,2013-04-03,2012-07-24
-7g9q,2023-07-26,2023-07-03
-1g9q,2001-05-02,2000-11-27
-1g9z,2001-04-02,2000-11-28
-8g9y,2023-04-19,2023-02-22
-8g9q,2023-08-16,2023-02-21
-6g9n,2018-05-30,2018-04-11
-8g98,2023-10-04,2023-02-21
-6g9b,2018-05-23,2018-04-10
-7g9j,2023-07-12,2023-06-22
-1g9s,2002-08-28,2000-11-27
-7g9i,2023-07-12,2023-06-22
-6g9w,2019-04-24,2018-04-11
-7g91,2023-07-12,2023-06-22
-8g9d,2024-01-03,2023-02-21
-7g9w,2023-07-26,2023-07-03
-6g9a,2018-05-30,2018-04-10
-6g90,2018-08-22,2018-04-10
-3g9y,2009-03-03,2009-02-15
-6g9x,2019-07-03,2018-04-11
-8g9v,2023-08-09,2023-02-22
-7g9a,2023-07-12,2023-06-22
-6g95,2018-05-23,2018-04-10
-1g97,2001-05-22,2000-11-22
-3g9l,2009-04-28,2009-02-13
-8g9p,2023-08-16,2023-02-21
-7g9o,2023-07-26,2023-07-03
-1g9i,2000-12-06,2000-11-24
-6g9q,2019-04-24,2018-04-11
-7g9e,2023-07-12,2023-06-22
-6g9d,2018-05-30,2018-04-10
-8g90,2024-04-17,2023-02-20
-7g9m,2023-07-26,2023-07-03
-8g9b,2023-04-19,2023-02-21
-8g92,2023-05-24,2023-02-21
-3g90,2009-02-24,2009-02-12
-1g9d,2002-11-13,2000-11-22
-4g95,2014-01-29,2012-07-23
-1g9n,2000-12-27,2000-11-25
-7g9g,2023-07-12,2023-06-22
-7g9s,2023-07-26,2023-07-03
-4g9j,2012-09-19,2012-07-24
-7g9r,2023-07-26,2023-07-03
-6g92,2018-05-30,2018-04-10
-2g9k,2006-03-14,2006-03-06
-3g91,2010-03-09,2009-02-12
-4g9n,2013-06-05,2012-07-24
-1g9t,2002-08-28,2000-11-28
-7g95,2023-07-12,2023-06-22
-7g9v,2023-07-26,2023-07-03
-8g9x,2023-04-19,2023-02-22
-6g9s,2019-05-22,2018-04-11
-2g9x,2006-05-23,2006-03-07
-1g9r,2001-02-14,2000-11-27
-8g9o,2023-04-12,2023-02-21
-6g93,2018-05-30,2018-04-10
-1g9x,2003-02-11,2000-11-28
-7g9k,2023-07-26,2023-07-03
-6zu2,2021-07-28,2020-07-21
-2zut,2008-12-30,2008-10-28
-7zuk,2022-11-02,2022-05-12
-7zuq,2022-10-19,2022-05-13
-4zur,2015-07-29,2015-05-17
-6zuc,2021-08-04,2020-07-22
-4zu6,2015-06-10,2015-05-15
-1zum,2005-06-28,2005-05-31
-2zul,2009-10-27,2008-10-21
-4zuj,2015-05-27,2015-05-16
-4zu0,2015-06-03,2015-05-15
-2zu9,2009-10-27,2008-10-14
-7zup,2022-10-19,2022-05-12
-2zuw,2008-12-30,2008-10-28
-5zue,2018-07-04,2018-05-07
-4zup,2015-07-29,2015-05-17
-7zu6,2023-05-24,2022-05-11
-2zuh,2009-10-20,2008-10-18
-2zu4,2009-01-13,2008-10-12
-4zu4,2015-07-15,2015-05-15
-4zu9,2015-09-23,2015-05-15
-3zuc,2012-01-11,2011-07-18
-6zu9,2020-10-28,2020-07-22
-1zur,2006-10-17,2005-05-31
-7zum,2023-03-22,2022-05-12
-6zul,2020-11-25,2020-07-23
-6zud,2021-06-23,2020-07-22
-2zun,2009-11-03,2008-10-21
-5zua,2019-06-05,2018-05-07
-7zuo,2023-05-24,2022-05-12
-5zu3,2019-05-22,2018-05-06
-4zui,2015-05-27,2015-05-16
-7zus,2022-10-12,2022-05-13
-6zuw,2020-08-26,2020-07-23
-7zuy,2022-10-19,2022-05-13
-3zux,2011-10-12,2011-07-21
-5zu6,2018-06-20,2018-05-07
-4zun,2015-07-29,2015-05-17
-2zu8,2009-10-27,2008-10-14
-2zux,2009-02-03,2008-10-28
-6zub,2021-06-23,2020-07-22
-3zuy,2011-10-12,2011-07-21
-2zus,2008-12-30,2008-10-28
-1zua,2006-11-07,2005-05-30
-6zuf,2021-06-09,2020-07-22
-1zun,2006-01-17,2005-05-31
-3zu8,2012-01-11,2011-07-17
-6zuu,2020-10-07,2020-07-23
-4zum,2015-07-29,2015-05-17
-6zu6,2021-06-23,2020-07-21
-7zuh,2022-11-02,2022-05-12
-1zu8,2005-06-07,2005-05-30
-6zun,2020-08-26,2020-07-23
-3zu5,2012-01-18,2011-07-13
-2zue,2009-08-18,2008-10-16
-7zu2,2023-03-22,2022-05-11
-3zuh,2011-11-09,2011-07-19
-7zuw,2023-02-22,2022-05-13
-5zu2,2019-05-22,2018-05-06
-3zu2,2012-01-18,2011-07-13
-2zui,2009-10-20,2008-10-18
-6zuk,2020-11-25,2020-07-23
-2zuj,2009-10-20,2008-10-18
-4zuh,2016-06-15,2015-05-16
-3zu4,2012-01-18,2011-07-13
-6zux,2020-08-26,2020-07-23
-2zur,2009-06-02,2008-10-28
-5zui,2019-06-19,2018-05-07
-5zub,2019-06-05,2018-05-07
-2zuq,2009-04-14,2008-10-28
-7zul,2022-11-02,2022-05-12
-4zu5,2016-03-30,2015-05-15
-6zu5,2020-11-04,2020-07-21
-4zuu,2016-04-06,2015-05-17
-6zu8,2020-08-05,2020-07-21
-5zu5,2018-06-27,2018-05-07
-3zu6,2011-10-19,2011-07-14
-4zuq,2015-07-29,2015-05-17
-3zuu,2011-10-12,2011-07-20
-3zup,2011-10-19,2011-07-19
-4zuk,2015-08-26,2015-05-16
-4zud,2015-10-07,2015-05-15
-4zul,2015-08-26,2015-05-16
-7zug,2023-05-24,2022-05-12
-7zub,2022-11-23,2022-05-12
-3zuk,2011-08-03,2011-07-19
-1zuw,2005-12-06,2005-06-01
-5zum,2019-06-12,2018-05-08
-4zu1,2015-06-10,2015-05-15
-1zud,2006-01-31,2005-05-30
-4zux,2016-02-24,2015-05-17
-1zuc,2005-07-05,2005-05-30
-6zuo,2021-05-12,2020-07-23
-3zus,2011-12-07,2011-07-19
-4zu7,2015-07-15,2015-05-15
-6zuv,2020-11-11,2020-07-23
-3zu1,2011-08-03,2011-07-13
-5zun,2018-10-17,2018-05-08
-4zuo,2015-07-29,2015-05-17
-1zui,2006-05-31,2005-05-31
-5zur,2018-09-05,2018-05-08
-5zu9,2019-06-05,2018-05-07
-4zu3,2015-11-04,2015-05-15
-2zup,2009-04-14,2008-10-28
-7zux,2023-02-22,2022-05-13
-1zub,2005-08-30,2005-05-30
-6zuq,2021-08-04,2020-07-23
-2zu5,2009-01-13,2008-10-12
-3zud,2011-09-07,2011-07-18
-1zuu,2006-09-12,2005-06-01
-7zui,2022-11-02,2022-05-12
-2zuy,2009-02-03,2008-10-28
-6zus,2021-08-04,2020-07-23
-6zup,2021-07-14,2020-07-23
-3zu3,2012-01-18,2011-07-13
-7zu8,2022-08-10,2022-05-11
-7zuc,2023-05-24,2022-05-12
-3zu0,2011-12-14,2011-07-13
-3zuo,2012-08-01,2011-07-19
-5zuu,2019-05-15,2018-05-08
-2zuu,2008-12-30,2008-10-28
-5zu0,2018-08-22,2018-05-05
-6zum,2020-11-25,2020-07-23
-1zuk,2006-08-15,2005-05-31
-1zuz,2006-11-14,2005-06-01
-6zut,2021-06-23,2020-07-23
-6zua,2021-06-23,2020-07-22
-7zu1,2023-03-22,2022-05-11
-7zun,2022-10-05,2022-05-12
-5zu7,2019-06-05,2018-05-07
-3zun,2012-07-25,2011-07-19
-1zu0,2006-06-06,2005-05-28
-6zu4,2020-11-18,2020-07-21
-3zuw,2011-11-16,2011-07-20
-3zum,2011-11-16,2011-07-19
-7zuu,2022-10-19,2022-05-13
-6zug,2020-08-26,2020-07-22
-1zu1,2005-09-20,2005-05-29
-6zuj,2021-03-03,2020-07-23
-1zuq,2006-05-02,2005-05-31
-3zuq,2011-12-07,2011-07-19
-2zuv,2008-12-30,2008-10-28
-2zuk,2009-02-17,2008-10-18
-2zum,2009-11-03,2008-10-21
-6zuh,2020-08-26,2020-07-22
-2zu3,2009-01-13,2008-10-12
-6zu1,2020-09-16,2020-07-21
-7zuj,2022-11-02,2022-05-12
-6zur,2021-07-14,2020-07-23
-155c,1976-08-20,1976-08-01
-3pei,2010-12-01,2010-10-26
-7pep,2022-08-24,2021-08-11
-4pe0,2014-11-05,2014-04-22
-3pec,2011-10-05,2010-10-25
-1pew,2004-07-13,2003-05-22
-3pej,2010-11-17,2010-10-26
-3peo,2011-10-12,2010-10-27
-4pe6,2014-05-07,2014-04-22
-4peg,2014-08-27,2014-04-23
-3ped,2011-10-05,2010-10-25
-1pez,2003-10-28,2003-05-23
-2pe4,2007-06-12,2007-04-02
-2pe0,2007-06-12,2007-04-01
-1pey,2004-05-18,2003-05-22
-1pe7,2004-06-08,2003-05-21
-2pe1,2007-06-12,2007-04-01
-4pel,2015-07-22,2014-04-24
-8pee,2024-03-20,2023-06-13
-7pe4,2023-02-22,2021-08-09
-6peg,2019-11-27,2019-06-20
-3pe8,2010-12-08,2010-10-25
-7peh,2022-08-24,2021-08-10
-6peu,2019-11-06,2019-06-20
-7peo,2021-12-01,2021-08-11
-6pef,2020-06-24,2019-06-20
-3pe0,2011-02-02,2010-10-25
-2peh,2007-06-26,2007-04-03
-7pem,2022-08-24,2021-08-10
-1pex,1996-12-23,1996-05-24
-2pez,2007-05-29,2007-04-03
-3pe3,2011-01-19,2010-10-25
-6pej,2020-06-24,2019-06-20
-7pe9,2021-09-08,2021-08-09
-4pee,2014-07-09,2014-04-23
-3pey,2011-03-23,2010-10-27
-4pe4,2014-10-15,2014-04-22
-1peq,2004-05-25,2003-05-22
-2pe2,2007-06-19,2007-04-01
-6pec,2020-06-24,2019-06-20
-7pee,2021-10-13,2021-08-09
-4pey,2015-03-18,2014-04-25
-6pev,2019-12-11,2019-06-21
-3pef,2011-12-07,2010-10-26
-4pe3,2014-05-14,2014-04-22
-6pey,2019-09-25,2019-06-21
-1ped,1997-07-07,1995-12-28
-1peg,2003-08-05,2003-05-21
-2pey,2007-05-29,2007-04-03
-6pe6,2020-12-23,2019-06-20
-8ped,2023-07-12,2023-06-13
-4pe7,2014-10-15,2014-04-22
-4pe8,2014-08-27,2014-04-23
-3pe6,2011-03-02,2010-10-25
-6pen,2019-12-04,2019-06-20
-4pe1,2014-10-15,2014-04-22
-4peu,2014-10-01,2014-04-24
-6pek,2019-12-04,2019-06-20
-3pe4,2011-01-19,2010-10-25
-3pel,2010-11-03,2010-10-26
-8pen,2024-04-24,2023-06-14
-3pen,2011-05-04,2010-10-27
-4pef,2014-08-27,2014-04-23
-1pek,1994-01-31,1993-01-19
-1peu,2004-05-25,2003-05-22
-2pem,2007-07-10,2007-04-03
-7pe8,2021-09-08,2021-08-09
-4peh,2014-08-27,2014-04-23
-2ped,2007-10-30,2007-04-02
-3pe2,2011-09-07,2010-10-25
-1pe1,2004-02-03,2003-05-20
-4pet,2014-05-14,2014-04-24
-7pe0,2022-08-24,2021-08-09
-6pe0,2020-02-12,2019-06-19
-2per,2008-03-04,2007-04-03
-6pe3,2020-01-08,2019-06-19
-4pem,2015-07-22,2014-04-24
-3pe1,2011-09-07,2010-10-25
-3pe7,2010-11-03,2010-10-25
-8pe3,2023-10-04,2023-06-13
-8peg,2024-03-06,2023-06-13
-6peq,2019-12-04,2019-06-20
-4pez,2015-03-18,2014-04-25
-1peo,2004-05-25,2003-05-22
-4pe5,2014-06-04,2014-04-22
-3peq,2011-10-12,2010-10-27
-4pe2,2015-01-14,2014-04-22
-6pet,2019-07-17,2019-06-20
-4pev,2014-05-21,2014-04-25
-7pek,2022-08-24,2021-08-10
-4pex,2015-03-18,2014-04-25
-2pel,1996-12-07,1995-08-23
-3peh,2010-11-17,2010-10-26
-2pev,2007-04-17,2007-04-03
-8pe9,2023-06-28,2023-06-13
-6peb,2019-12-04,2019-06-20
-7pef,2022-08-24,2021-08-10
-7pe7,2021-09-15,2021-08-09
-7pe6,2022-02-02,2021-08-09
-7pe5,2022-02-02,2021-08-09
-1pee,2004-06-01,2003-05-21
-4pew,2015-03-18,2014-04-25
-1pe5,2004-06-08,2003-05-21
-3peb,2010-11-03,2010-10-25
-2peb,2007-04-17,2007-04-02
-3pew,2011-03-23,2010-10-27
-7pel,2021-08-25,2021-08-10
-4pes,2015-06-17,2014-04-24
-8pej,2023-10-04,2023-06-14
-7pen,2022-01-19,2021-08-11
-7pes,2022-01-19,2021-08-11
-8pec,2024-02-14,2023-06-13
-2pe7,2008-04-22,2007-04-02
-8peo,2023-08-16,2023-06-14
-3peg,2010-12-08,2010-10-26
-4pei,2014-08-27,2014-04-23
-2pes,2008-04-22,2007-04-03
-3per,2011-06-01,2010-10-27
-1pe6,1993-04-15,1991-05-14
-2pe5,2008-03-18,2007-04-02
-1pe8,2004-06-08,2003-05-21
-3pee,2011-02-16,2010-10-26
-6pe2,2019-10-30,2019-06-19
-6pel,2020-06-24,2019-06-20
-2peg,2007-07-24,2007-04-03
-5t0a,2017-02-01,2016-08-15
-5t0c,2016-10-19,2016-08-15
-3t01,2011-08-03,2011-07-19
-5t0m,2016-10-05,2016-08-16
-3t0b,2012-01-18,2011-07-19
-1t05,2004-05-11,2004-04-07
-5t07,2016-09-07,2016-08-15
-5t05,2017-02-01,2016-08-15
-6t0z,2020-03-04,2019-10-03
-6t0i,2019-11-27,2019-10-03
-8t0y,2024-05-08,2023-06-01
-6t0c,2020-03-04,2019-10-02
-6t0g,2020-10-14,2019-10-03
-8t0t,2024-05-01,2023-06-01
-3t0u,2012-05-02,2011-07-20
-6t08,2020-03-04,2019-10-02
-1t0l,2004-06-15,2004-04-10
-8t09,2023-12-13,2023-05-31
-6t06,2020-03-04,2019-10-02
-6t0v,2020-04-15,2019-10-03
-6t0a,2020-03-04,2019-10-02
-5t09,2017-02-01,2016-08-15
-6t07,2020-03-04,2019-10-02
-5t0w,2017-09-06,2016-08-16
-1t02,2004-08-03,2004-04-07
-7t0v,2022-03-02,2021-11-30
-3t09,2012-01-18,2011-07-19
-5t0p,2017-08-23,2016-08-16
-7t0l,2022-12-07,2021-11-29
-6t0l,2020-10-14,2019-10-03
-6t0d,2020-03-04,2019-10-02
-7t09,2022-11-09,2021-11-29
-7t0y,2022-12-07,2021-11-30
-5t02,2016-09-07,2016-08-15
-5t0g,2016-10-19,2016-08-16
-8t0n,2024-05-01,2023-06-01
-6t0n,2020-04-15,2019-10-03
-6t0o,2020-03-04,2019-10-03
-5t0h,2016-10-19,2016-08-16
-1t0w,2004-09-28,2004-04-13
-7t0r,2022-01-12,2021-11-30
-7t0e,2022-11-09,2021-11-29
-6t0q,2020-02-19,2019-10-03
-5t0b,2017-06-14,2016-08-15
-1t0m,2004-11-23,2004-04-12
-1t09,2004-06-15,2004-04-08
-3t0t,2012-06-06,2011-07-20
-5t0j,2016-10-19,2016-08-16
-3t0o,2012-07-11,2011-07-20
-3t0i,2011-09-07,2011-07-20
-1t0p,2005-03-08,2004-04-12
-1t0n,2004-11-23,2004-04-12
-3t0z,2012-01-25,2011-07-21
-7t0b,2022-11-09,2021-11-29
-3t0d,2012-01-18,2011-07-20
-8t0c,2024-05-08,2023-05-31
-6t0b,2020-04-22,2019-10-02
-3t0l,2012-12-26,2011-07-20
-7t0u,2022-11-09,2021-11-30
-7t0p,2022-06-15,2021-11-30
-5t03,2017-02-01,2016-08-15
-1t0b,2004-08-03,2004-04-08
-3t0x,2012-03-21,2011-07-20
-1t0a,2004-10-26,2004-04-08
-8t0k,2024-05-01,2023-06-01
-7t0t,2022-12-14,2021-11-30
-5t0i,2016-10-19,2016-08-16
-8t0z,2024-03-13,2023-06-01
-5t06,2016-09-07,2016-08-15
-8t06,2023-09-27,2023-05-31
-3t0g,2011-11-30,2011-07-20
-5t0x,2017-02-15,2016-08-16
-6t02,2020-03-04,2019-10-02
-8t04,2023-09-27,2023-05-31
-6t05,2020-03-04,2019-10-02
-3t0a,2012-01-18,2011-07-19
-6t04,2020-03-04,2019-10-02
-5t0n,2016-10-05,2016-08-16
-1t0t,2004-08-24,2004-04-12
-7t0w,2022-07-13,2021-11-30
-7t0a,2022-11-09,2021-11-29
-6t0j,2020-10-14,2019-10-03
-5t08,2017-06-14,2016-08-15
-3t00,2011-08-03,2011-07-19
-7t02,2022-02-23,2021-11-29
-6t01,2020-03-04,2019-10-02
-6t0p,2020-05-13,2019-10-03
-6t0m,2020-05-13,2019-10-03
-7t0z,2022-07-13,2021-11-30
-6t0f,2020-10-14,2019-10-03
-3t03,2012-05-23,2011-07-19
-7t00,2022-03-02,2021-11-29
-3t0k,2012-05-16,2011-07-20
-6t09,2020-03-04,2019-10-02
-7t0s,2022-12-14,2021-11-30
-1t0i,2004-06-22,2004-04-09
-3t02,2011-08-03,2011-07-19
-3t07,2011-10-26,2011-07-19
-5t0e,2017-06-14,2016-08-15
-6t0y,2020-01-29,2019-10-03
-8t0r,2024-05-01,2023-06-01
-5t00,2017-05-24,2016-08-15
-6t0x,2020-03-04,2019-10-03
-6t03,2020-03-04,2019-10-02
-8t07,2023-09-27,2023-05-31
-7t08,2022-11-09,2021-11-29
-3t0c,2011-08-03,2011-07-19
-8t0e,2024-05-08,2023-05-31
-6t0s,2020-04-15,2019-10-03
-1t03,2004-05-11,2004-04-07
-8t05,2023-09-27,2023-05-31
-5t04,2016-12-21,2016-08-15
-3t08,2012-01-18,2011-07-19
-3t0f,2011-11-30,2011-07-20
-1t0f,2004-11-09,2004-04-08
-5t0d,2017-06-14,2016-08-15
-6t0k,2020-10-14,2019-10-03
-1t0k,2004-07-20,2004-04-09
-1t0s,2004-07-27,2004-04-12
-5t0s,2017-06-14,2016-08-16
-1t0r,2004-07-27,2004-04-12
-5t0k,2016-10-05,2016-08-16
-7t0c,2022-11-09,2021-11-29
-8t03,2023-09-27,2023-05-31
-6t0h,2020-10-14,2019-10-03
-6t0e,2019-11-27,2019-10-03
-3t0m,2012-12-26,2011-07-20
-7t0f,2022-04-20,2021-11-29
-1t0o,2004-10-12,2004-04-12
-7t0d,2022-11-09,2021-11-29
-3t0w,2012-03-21,2011-07-20
-7t0q,2022-12-14,2021-11-30
-5t0l,2016-09-28,2016-08-16
-5t0u,2017-05-24,2016-08-16
-5t0r,2017-06-14,2016-08-16
-1t0q,2004-07-27,2004-04-12
-3t0q,2012-04-04,2011-07-20
-6v4s,2020-06-03,2019-11-29
-7v4t,2022-08-17,2021-08-15
-3v4y,2012-10-31,2011-12-15
-7v4r,2022-08-17,2021-08-14
-4v45,2014-07-09,2001-09-13
-6v4l,2020-02-12,2019-11-27
-2v4c,2010-03-31,2008-09-18
-6v44,2020-06-17,2019-11-27
-3v4j,2012-02-01,2011-12-15
-3v4i,2012-01-18,2011-12-15
-2v4o,2008-12-09,2008-09-26
-4v4e,2014-07-09,2004-06-02
-2v43,2007-08-28,2007-06-27
-1v4x,2004-07-06,2003-11-19
-6v49,2020-06-17,2019-11-27
-4v4i,2014-07-09,2007-02-15
-6v4v,2021-06-02,2019-12-02
-6v42,2020-12-02,2019-11-27
-5v49,2017-07-26,2017-03-08
-6v43,2020-12-09,2019-11-27
-6v4k,2020-02-12,2019-11-27
-8v4u,2024-05-15,2023-11-29
-2v4b,2008-01-15,2007-06-28
-2v4r,2009-06-16,2008-09-26
-3v4x,2012-04-25,2011-12-15
-6v4t,2020-04-01,2019-11-30
-5v41,2017-07-05,2017-03-08
-5v42,2017-07-05,2017-03-08
-4v4m,2014-07-09,2011-04-28
-2v40,2007-07-10,2007-06-27
-5v4o,2017-04-26,2017-03-10
-7v41,2022-06-22,2021-08-12
-6v46,2020-06-17,2019-11-27
-5v4d,2017-04-05,2017-03-09
-1v4u,2004-07-06,2003-11-19
-8v4h,2023-12-20,2023-11-29
-7v4x,2023-02-15,2021-08-15
-1v4b,2005-01-18,2003-11-12
-3v4v,2012-01-11,2011-12-15
-7v4v,2022-09-28,2021-08-15
-6v40,2020-01-29,2019-11-27
-7v4e,2022-04-06,2021-08-12
-2v4j,2008-12-02,2008-09-22
-5v4y,2017-09-13,2017-03-11
-4v4c,2014-07-09,2004-06-02
-7v4w,2022-08-17,2021-08-15
-1v4p,2004-11-23,2003-11-14
-3v4s,2013-02-13,2011-12-15
-3v4p,2012-01-11,2011-12-15
-8v4o,2023-12-06,2023-11-29
-6v4x,2020-02-19,2019-12-02
-1v4f,2004-08-03,2003-11-13
-4v46,2014-07-09,2003-03-23
-8v4a,2023-12-13,2023-11-28
-5v4v,2018-03-14,2017-03-10
-5v4a,2017-09-13,2017-03-08
-3v4u,2012-07-25,2011-12-15
-4v41,2014-07-09,2000-06-07
-1v4t,2004-03-30,2003-11-19
-3v45,2012-01-04,2011-12-14
-6v4g,2020-04-22,2019-11-27
-5v4m,2017-05-03,2017-03-10
-8v4j,2023-12-13,2023-11-29
-3v4l,2012-03-14,2011-12-15
-4v44,2014-07-09,2001-09-13
-3v4e,2012-01-11,2011-12-14
-7v4f,2022-02-23,2021-08-13
-6v47,2020-06-17,2019-11-27
-7v44,2022-06-22,2021-08-12
-3v4k,2012-01-25,2011-12-15
-6v4n,2020-10-07,2019-11-28
-2v4q,2009-06-16,2008-09-26
-6v4e,2020-04-22,2019-11-27
-3v4t,2012-03-07,2011-12-15
-7v4y,2022-06-29,2021-08-16
-3v43,2012-06-27,2011-12-14
-2v4m,2008-10-07,2008-09-26
-8v4r,2023-12-06,2023-11-29
-5v4r,2017-04-19,2017-03-10
-5v4x,2017-05-31,2017-03-10
-3v44,2012-02-29,2011-12-14
-8v4g,2023-12-20,2023-11-29
-3v49,2012-09-05,2011-12-14
-4v40,2014-07-09,1994-07-18
-4v4q,2014-07-09,2005-08-30
-7v45,2022-06-22,2021-08-12
-3v4r,2012-07-04,2011-12-15
-5v4n,2017-05-03,2017-03-10
-6v4o,2020-10-07,2019-11-28
-4v4u,2014-07-09,2005-03-03
-2v4y,2008-10-21,2008-09-30
-2v4z,2008-11-04,2008-09-30
-3v4m,2012-06-13,2011-12-15
-2v42,2007-08-28,2007-06-27
-5v4p,2018-03-14,2017-03-10
-7v4p,2022-02-23,2021-08-13
-7v42,2022-06-22,2021-08-12
-3v4b,2011-12-28,2011-12-14
-1v40,2004-11-07,2003-11-07
-7v40,2022-06-22,2021-08-12
-7v43,2022-06-22,2021-08-12
-4v49,2014-07-09,2003-06-13
-3v47,2012-02-29,2011-12-14
-4v4l,2014-07-09,2010-10-04
-6v4c,2020-06-24,2019-11-27
-3v4o,2012-03-14,2011-12-15
-7v4g,2022-03-30,2021-08-13
-2v4v,2009-10-13,2008-09-29
-7v4m,2022-02-23,2021-08-13
-4v4d,2014-07-09,2004-06-02
-1v4y,2004-04-20,2003-11-20
-1v41,2004-12-14,2003-11-08
-3v4f,2012-08-08,2011-12-14
-7v4n,2022-02-23,2021-08-13
-7v4s,2022-03-09,2021-08-14
-6v4p,2020-02-05,2019-11-28
-1v4s,2004-03-30,2003-11-19
-5v40,2017-07-05,2017-03-08
-1v47,2004-04-06,2003-11-11
-3v4a,2012-09-05,2011-12-14
-4v4o,2014-07-09,2004-05-23
-5v4q,2017-04-19,2017-03-10
-5v4w,2017-05-31,2017-03-10
-4v4h,2014-07-09,2006-08-04
-6v48,2020-06-17,2019-11-27
-1v48,2004-08-03,2003-11-11
-5v4e,2017-06-21,2017-03-09
-8v4y,2024-03-20,2023-11-29
-5v48,2018-03-14,2017-03-08
-4v4f,2014-07-09,2003-12-08
-2v4l,2008-10-14,2008-09-25
-1v4w,2004-07-06,2003-11-19
-8v4p,2023-12-06,2023-11-29
-1v45,2004-12-14,2003-11-10
-5v4t,2018-03-14,2017-03-10
-7v46,2022-06-22,2021-08-12
-2v4n,2008-12-09,2008-09-26
-1ws0,2005-09-13,2004-10-29
-7wsz,2022-04-13,2022-02-03
-2ws6,2010-02-09,2009-09-03
-2ws7,2010-02-09,2009-09-03
-4wsx,2015-02-25,2014-10-28
-5wsb,2017-11-15,2016-12-06
-4wsq,2014-11-05,2014-10-28
-5wsv,2017-06-07,2016-12-08
-5wsf,2017-05-31,2016-12-06
-6wsb,2020-05-20,2020-04-30
-3wsd,2014-08-27,2014-03-13
-6wsh,2021-05-05,2020-05-01
-3wsz,2015-02-04,2014-03-30
-7ws3,2022-06-01,2022-01-28
-4wsv,2015-02-25,2014-10-28
-4wss,2015-02-25,2014-10-28
-4wsj,2014-11-05,2014-10-28
-4wsz,2015-05-06,2014-10-29
-6ws4,2021-11-10,2020-04-30
-2wsl,2009-09-15,2009-09-08
-5ws8,2017-11-15,2016-12-06
-4wsb,2014-11-19,2014-10-26
-7wsm,2022-05-18,2022-01-30
-3wsb,2015-04-01,2014-03-05
-5ws2,2017-12-06,2016-12-05
-7ws4,2022-06-01,2022-01-28
-1ws7,2004-11-23,2004-11-02
-7ws5,2022-06-01,2022-01-28
-4wsk,2014-11-12,2014-10-28
-4wsw,2015-02-25,2014-10-28
-3ws1,2015-03-04,2014-02-27
-6wsa,2020-05-20,2020-04-30
-1wsb,2004-11-23,2004-11-05
-4ws1,2015-07-15,2014-10-25
-2wsa,2010-03-23,2009-09-04
-5ws6,2017-03-15,2016-12-05
-1wsf,2005-02-08,2004-11-05
-4ws5,2015-07-15,2014-10-25
-3wsj,2014-10-22,2014-03-14
-5wsz,2017-02-22,2016-12-08
-7wss,2022-06-29,2022-02-01
-2wsd,2010-09-29,2009-09-04
-1wsv,2005-08-16,2004-11-11
-5wsl,2017-10-18,2016-12-07
-1ws3,2005-03-22,2004-10-29
-7wst,2022-11-30,2022-02-01
-4ws8,2015-07-15,2014-10-25
-5ws5,2017-03-15,2016-12-05
-5ws4,2017-11-15,2016-12-05
-2wsy,1999-03-30,1998-02-18
-2ws3,2010-08-25,2009-09-03
-7wse,2022-10-19,2022-01-29
-4ws3,2015-07-15,2014-10-25
-5wsy,2017-05-31,2016-12-08
-5ws9,2017-11-15,2016-12-06
-3ws2,2015-03-04,2014-02-27
-1ws8,2004-11-23,2004-11-02
-4wsu,2015-02-25,2014-10-28
-4ws7,2015-07-15,2014-10-25
-5wsg,2017-01-25,2016-12-07
-5wsc,2017-11-15,2016-12-06
-5ws1,2017-01-25,2016-12-04
-7ws1,2022-06-01,2022-01-28
-4wsr,2015-02-25,2014-10-28
-2wsj,2010-02-09,2009-09-07
-7wsr,2022-11-30,2022-02-01
-4wsg,2015-01-21,2014-10-27
-3wsr,2014-10-22,2014-03-20
-7wsw,2022-11-09,2022-02-02
-2wsf,2009-11-17,2009-09-05
-2wsb,2010-04-28,2009-09-04
-3ws3,2014-03-26,2014-02-28
-1ws1,2005-09-13,2004-10-29
-4wsd,2015-06-10,2014-10-27
-3wsp,2014-11-26,2014-03-20
-6ws5,2020-12-23,2020-04-30
-1ws2,2005-03-22,2004-10-29
-2wsx,2010-09-08,2009-09-10
-2wsv,2010-08-11,2009-09-10
-3wsi,2014-08-27,2014-03-13
-6wsg,2020-11-04,2020-04-30
-8wsm,2023-11-22,2023-10-17
-2wss,2009-11-17,2009-09-09
-3ws6,2014-03-26,2014-02-28
-4wso,2014-11-12,2014-10-28
-7wsg,2022-11-09,2022-01-29
-7ws9,2022-06-01,2022-01-28
-1ws4,2005-03-29,2004-10-31
-3wsh,2014-08-27,2014-03-13
-5wsh,2017-12-20,2016-12-07
-4ws4,2015-07-15,2014-10-25
-4ws0,2015-07-15,2014-10-25
-5wsa,2017-11-15,2016-12-06
-8wsw,2023-11-15,2023-10-17
-5wsk,2018-02-14,2016-12-07
-4wst,2015-02-25,2014-10-28
-3ws5,2015-03-04,2014-02-28
-2wsw,2010-09-08,2009-09-10
-1wse,2005-02-08,2004-11-05
-1wst,2005-10-25,2004-11-10
-7wsc,2023-03-01,2022-01-28
-3ws8,2014-06-04,2014-03-04
-4wsm,2015-06-10,2014-10-28
-3wsa,2015-04-01,2014-03-05
-4wsy,2015-02-11,2014-10-28
-1ws5,2005-03-29,2004-10-31
-1wsw,2004-12-07,2004-11-12
-1wsg,2005-02-08,2004-11-05
-2wsp,2010-01-19,2009-09-08
-6ws1,2020-08-05,2020-04-30
-7ws7,2022-06-01,2022-01-28
-5ws7,2017-01-04,2016-12-05
-6wsl,2020-08-26,2020-05-01
-4ws2,2015-07-15,2014-10-25
-3wst,2014-04-23,2014-03-21
-6ws3,2021-02-03,2020-04-30
-7wsn,2022-05-18,2022-01-30
-3ws7,2015-03-04,2014-03-04
-3wsx,2015-02-04,2014-03-30
-5wse,2017-05-31,2016-12-06
-1wsz,2004-12-07,2004-11-12
-2wse,2009-11-17,2009-09-05
-3wsw,2014-09-10,2014-03-27
-7wsa,2022-06-01,2022-01-28
-7wsk,2022-06-08,2022-01-29
-7wsf,2022-10-19,2022-01-29
-3ws9,2014-06-04,2014-03-04
-3wsy,2015-02-04,2014-03-30
-7wsq,2023-02-08,2022-02-01
-6wsi,2021-03-24,2020-05-01
-7wsh,2022-11-09,2022-01-29
-3wsg,2014-08-27,2014-03-13
-1wss,2005-11-10,2004-11-10
-4ws6,2015-07-15,2014-10-25
-3wsu,2015-05-20,2014-03-26
-1wsd,2004-11-16,2004-11-05
-7wsj,2022-03-02,2022-01-29
-2wsc,2009-11-17,2009-09-04
-6ws6,2020-05-27,2020-04-30
-3wsf,2014-08-27,2014-03-13
-6ws2,2021-11-10,2020-04-30
-7ws0,2022-06-01,2022-01-28
-7wsu,2022-11-30,2022-02-01
-6wsj,2021-04-28,2020-05-01
-5ws0,2017-01-25,2016-12-04
-7wsb,2022-07-06,2022-01-28
-5ws3,2017-12-13,2016-12-05
-3ws4,2015-03-04,2014-02-28
-2wsi,2010-05-26,2009-09-07
-3wse,2014-08-27,2014-03-13
-7ws8,2022-06-01,2022-01-28
-4wsn,2015-12-23,2014-10-28
-3ws0,2015-03-04,2014-02-27
-1wsp,2006-02-14,2004-11-08
-2ydi,2012-04-04,2011-03-21
-6yd6,2021-07-28,2020-03-20
-2yds,2012-03-14,2011-03-24
-7yd7,2023-11-22,2022-07-04
-6yd7,2021-02-17,2020-03-20
-5ydi,2018-03-07,2017-09-13
-6ydv,2020-05-06,2020-03-21
-7yde,2023-05-24,2022-07-04
-4ydp,2016-06-29,2015-02-22
-7ydc,2023-05-24,2022-07-04
-5yd6,2019-03-27,2017-09-11
-7ydq,2023-04-26,2022-07-04
-2ydo,2011-05-18,2011-03-23
-6ydb,2021-03-31,2020-03-20
-1yd5,2005-03-01,2004-12-23
-2yd0,2011-04-13,2011-03-17
-6ydf,2020-09-16,2020-03-20
-2ydk,2012-04-04,2011-03-22
-1ydr,1997-04-01,1996-07-24
-4ydl,2015-06-03,2015-02-22
-4ydj,2015-06-03,2015-02-22
-7ydy,2022-08-24,2022-07-04
-7ydx,2023-04-19,2022-07-04
-7ydl,2023-07-12,2022-07-04
-6ydj,2020-10-28,2020-03-20
-6yd9,2020-12-30,2020-03-20
-5ydm,2018-05-23,2017-09-13
-7yd2,2023-07-19,2022-07-03
-1yd1,2005-03-01,2004-12-23
-2ydv,2011-05-18,2011-03-24
-6yd0,2020-09-30,2020-03-19
-6ydd,2020-09-16,2020-03-20
-4ydk,2015-06-03,2015-02-22
-4ydh,2015-05-13,2015-02-22
-5yd2,2018-10-31,2017-09-10
-2ydd,2012-03-21,2011-03-18
-5ydd,2018-09-19,2017-09-12
-4yd9,2015-10-14,2015-02-21
-4ydq,2015-05-20,2015-02-23
-1yd0,2005-03-01,2004-12-23
-4ydi,2015-06-03,2015-02-22
-7yd6,2023-11-22,2022-07-04
-4yd7,2016-03-02,2015-02-21
-6ydx,2020-07-22,2020-03-21
-2ydw,2011-06-15,2011-03-24
-4yda,2016-02-24,2015-02-21
-4ydd,2016-03-09,2015-02-21
-5yd8,2018-04-18,2017-09-12
-4yd3,2016-03-02,2015-02-20
-5yd3,2018-06-06,2017-09-11
-7ydi,2022-08-24,2022-07-04
-7yd8,2023-11-22,2022-07-04
-6yde,2020-09-16,2020-03-20
-4ydb,2016-02-24,2015-02-21
-7ydb,2023-05-24,2022-07-04
-5ydh,2018-03-07,2017-09-13
-2ydp,2011-07-13,2011-03-24
-7ydz,2023-11-22,2022-07-05
-5ydj,2018-03-07,2017-09-13
-1ydn,2005-07-05,2004-12-24
-5yd5,2018-06-06,2017-09-11
-5ydl,2018-05-23,2017-09-13
-2yde,2011-03-30,2011-03-18
-4yd4,2016-03-02,2015-02-20
-6ydg,2020-09-16,2020-03-20
-2ydj,2012-01-25,2011-03-22
-2ydm,2011-09-14,2011-03-22
-5yd0,2018-03-28,2017-09-09
-6ydy,2021-03-31,2020-03-21
-4ydn,2015-07-15,2015-02-22
-6ydm,2020-10-28,2020-03-20
-6ydz,2021-03-31,2020-03-23
-4yds,2015-11-11,2015-02-23
-4ydx,2015-03-04,2015-02-23
-5ydc,2018-09-19,2017-09-12
-6yd1,2021-07-28,2020-03-20
-6ydk,2020-10-28,2020-03-20
-1ydp,2005-03-08,2004-12-25
-2ydf,2011-04-27,2011-03-18
-6yd2,2021-02-17,2020-03-20
-4ydr,2015-11-11,2015-02-23
-2ydt,2011-07-13,2011-03-24
-1ydc,1995-02-14,1994-12-22
-2ydc,2012-03-28,2011-03-18
-5yd7,2018-09-19,2017-09-11
-4yd0,2015-04-15,2015-02-20
-6ydw,2020-07-15,2020-03-21
-4ydf,2016-02-03,2015-02-22
-2ydu,2011-11-02,2011-03-24
-4yd6,2016-03-02,2015-02-21
-2ydb,2012-03-21,2011-03-18
-5ydb,2017-09-20,2017-09-12
-6yd4,2021-02-17,2020-03-20
-1yda,1995-02-14,1994-12-22
-6ydc,2020-09-16,2020-03-20
-1ydy,2005-01-25,2004-12-27
-1ydz,2005-01-04,2004-12-27
-2ydg,2011-07-20,2011-03-19
-4ydu,2015-03-04,2015-02-23
-1yd2,2005-03-01,2004-12-23
-1ydb,1995-02-14,1994-12-22
-6yd3,2021-02-17,2020-03-20
-2ydq,2012-03-14,2011-03-24
-4ydg,2016-02-03,2015-02-22
-1yd3,2005-03-01,2004-12-23
-7yd9,2023-05-24,2022-07-04
-4yde,2016-07-06,2015-02-22
-4ydm,2015-07-15,2015-02-22
-6ydu,2020-09-30,2020-03-21
-4yd1,2015-08-05,2015-02-20
-1yd4,2005-03-01,2004-12-23
-2yd9,2011-04-13,2011-03-18
-1ydd,1995-02-14,1994-12-22
-1ydf,2005-01-18,2004-12-23
-6ydl,2020-10-28,2020-03-20
-6yd5,2021-07-28,2020-03-20
-1yd9,2005-09-27,2004-12-23
-4ydo,2016-07-06,2015-02-22
-1ydt,1997-04-01,1996-07-24
-2ydr,2012-03-14,2011-03-24
-1yds,1997-04-01,1996-07-24
-7yda,2023-05-24,2022-07-04
-2yd3,2011-04-13,2011-03-17
-7ydd,2023-05-24,2022-07-04
-4yd5,2016-03-02,2015-02-20
-5yd4,2018-06-06,2017-09-11
-6ydp,2020-07-15,2020-03-20
-5ydr,2018-02-21,2017-09-14
-2yd8,2011-04-13,2011-03-18
-2yd1,2011-04-13,2011-03-17
-6ydi,2020-09-30,2020-03-20
-4yd2,2015-08-05,2015-02-20
-1ydk,2005-06-07,2004-12-24
-2ydx,2011-04-27,2011-03-25
-5cox,1997-12-24,1996-12-18
-3coc,2008-04-08,2008-03-27
-1cor,1993-10-31,1993-06-23
-5coi,2016-01-13,2015-07-20
-3co9,2009-02-10,2008-03-27
-4com,2015-01-14,2014-01-29
-7co2,2021-03-10,2020-08-03
-8co5,2024-03-06,2023-02-27
-4cod,2014-02-12,2014-01-28
-7coc,2021-06-30,2020-08-04
-1co4,1999-06-10,1999-06-04
-8con,2024-02-21,2023-02-28
-5co4,2016-07-20,2015-07-19
-4coe,2014-12-10,2014-01-28
-3cok,2008-04-15,2008-03-28
-3cox,1993-10-31,1993-06-14
-6coe,2019-03-20,2018-03-12
-4cow,2015-02-18,2014-01-31
-2co0,2006-07-03,2006-05-25
-8coq,2024-03-06,2023-02-28
-3coz,2008-10-07,2008-03-29
-3co6,2008-09-16,2008-03-27
-4co4,2014-05-28,2014-01-25
-4col,2015-05-06,2014-01-29
-3cot,2008-04-08,2008-03-29
-6co8,2018-07-04,2018-03-12
-5cok,2016-01-13,2015-07-20
-1com,1994-06-22,1994-04-08
-4cof,2014-06-04,2014-01-28
-5co2,2015-08-26,2015-07-19
-4co9,2014-04-02,2014-01-27
-3co8,2008-04-08,2008-03-27
-7cof,2020-12-16,2020-08-04
-4coy,2015-02-18,2014-01-31
-1co0,2003-09-16,1999-05-30
-5cop,2016-01-13,2015-07-20
-4co1,2014-05-28,2014-01-25
-4coj,2015-05-06,2014-01-28
-4co0,2014-05-28,2014-01-25
-3con,2008-04-08,2008-03-28
-5coz,2015-08-05,2015-07-21
-8cot,2023-04-26,2023-02-28
-2cog,2005-08-30,2005-05-17
-6cod,2019-03-20,2018-03-12
-8cow,2024-03-13,2023-03-01
-4co3,2014-05-28,2014-01-25
-8coy,2023-07-19,2023-03-01
-8cog,2024-03-06,2023-02-28
-4coi,2015-01-14,2014-01-28
-7co9,2021-06-30,2020-08-04
-1coy,1993-10-31,1993-06-14
-3cop,2009-03-24,2008-03-28
-4coh,2014-04-02,2014-01-28
-4cok,2014-10-01,2014-01-29
-5co0,2015-11-25,2015-07-18
-6co5,2019-03-20,2018-03-12
-6cog,2019-03-20,2018-03-12
-1coz,1999-10-06,1999-05-29
-3coq,2008-07-01,2008-03-29
-5cob,2016-03-09,2015-07-20
-3co0,2008-10-14,2008-03-26
-8coe,2024-01-03,2023-02-28
-5cof,2016-02-03,2015-07-20
-7com,2020-08-19,2020-08-04
-8cox,2024-03-13,2023-03-01
-5coq,2015-08-05,2015-07-20
-4coo,2014-03-05,2014-01-29
-8coz,2023-07-19,2023-03-01
-1coj,1999-06-14,1999-05-28
-1co9,1999-06-14,1999-06-07
-5co9,2015-08-26,2015-07-20
-3co4,2008-04-08,2008-03-27
-1coh,1990-01-15,1989-01-13
-6coh,2019-03-20,2018-03-12
-4coz,2015-02-18,2014-01-31
-8coh,2024-01-03,2023-02-28
-6coi,2019-03-20,2018-03-12
-4coq,2014-10-15,2014-01-30
-1con,1994-01-31,1993-03-16
-7cow,2021-08-11,2020-08-05
-4co2,2014-05-28,2014-01-25
-1co7,2003-01-07,1999-06-07
-7coh,2021-04-07,2020-08-04
-7coq,2021-08-11,2020-08-05
-5com,2016-02-03,2015-07-20
-7coj,2020-10-14,2020-08-04
-7co8,2021-06-30,2020-08-04
-5coj,2016-03-23,2015-07-20
-1co8,1999-06-14,1999-06-07
-7co3,2021-03-10,2020-08-03
-6cox,1997-12-24,1996-12-18
-5coo,2016-01-13,2015-07-20
-4cog,2014-04-02,2014-01-28
-8coj,2023-04-26,2023-02-28
-5co6,2015-08-26,2015-07-19
-7col,2021-08-04,2020-08-04
-1cow,1996-08-17,1996-05-08
-7co6,2021-06-30,2020-08-04
-1cot,1994-09-30,1994-07-06
-8cop,2024-03-06,2023-02-28
-6com,2018-04-04,2018-03-12
-3coy,2008-10-07,2008-03-29
-8co4,2024-02-21,2023-02-27
-2col,2006-01-24,2005-05-18
-7cov,2020-08-26,2020-08-05
-3cob,2008-06-24,2008-03-27
-7co5,2021-03-10,2020-08-03
-6coc,2019-03-20,2018-03-12
-7coy,2021-03-31,2020-08-05
-3coa,2008-09-16,2008-03-27
-7cou,2021-04-28,2020-08-05
-8cov,2024-01-10,2023-02-28
-2coi,2005-08-30,2005-05-17
-4cob,2014-04-02,2014-01-28
-3cow,2008-10-07,2008-03-29
-5co1,2016-11-02,2015-07-19
-4cou,2015-02-18,2014-01-31
-5coy,2016-04-13,2015-07-20
-7coa,2021-06-30,2020-08-04
-1cob,1993-10-31,1992-02-19
-1co6,1999-06-18,1999-06-05
-3cor,2008-04-08,2008-03-29
-8co0,2023-12-13,2023-02-25
-4cov,2015-02-18,2014-01-31
-7coe,2021-08-04,2020-08-04
-8co7,2024-01-03,2023-02-27
-3cog,2008-05-27,2008-03-28
-6co7,2018-05-16,2018-03-12
-5co8,2016-01-13,2015-07-20
-7cob,2021-06-30,2020-08-04
-8col,2023-08-09,2023-02-28
-2cot,2005-11-18,2005-05-18
-3coh,2009-02-17,2008-03-28
-4cox,1997-12-24,1996-12-18
-2cor,2005-11-18,2005-05-18
-8co3,2023-12-13,2023-02-26
-7con,2021-09-15,2020-08-04
-5coc,2016-03-30,2015-07-20
-2co8,2005-11-17,2005-05-17
-2coj,2005-08-30,2005-05-17
-7cod,2021-06-30,2020-08-04
-3cod,2008-04-08,2008-03-27
-7co7,2021-03-10,2020-08-04
-7coz,2021-01-13,2020-08-05
-5cov,2015-10-28,2015-07-20
-3cos,2008-04-15,2008-03-29
-5cou,2015-10-28,2015-07-20
-6co3,2018-05-02,2018-03-10
-4cot,2014-03-05,2014-01-31
-7cog,2020-12-16,2020-08-04
-3coj,2008-05-27,2008-03-28
-7coi,2020-10-14,2020-08-04
-4cos,2014-03-05,2014-01-30
-7coo,2021-09-15,2020-08-04
-8cou,2024-01-10,2023-02-28
-6co9,2018-03-28,2018-03-12
-5con,2016-01-13,2015-07-20
-6coj,2018-03-28,2018-03-12
-8cod,2024-03-06,2023-02-27
-2con,2005-11-18,2005-05-18
-5cog,2016-02-03,2015-07-20
-4ygf,2015-07-01,2015-02-26
-6ygr,2020-04-08,2020-03-27
-2yg4,2011-05-18,2011-04-11
-2ygj,2012-04-25,2011-04-18
-5yg0,2018-09-26,2017-09-22
-4ygk,2015-03-25,2015-02-26
-1ygu,2005-02-22,2005-01-05
-6ygf,2020-12-23,2020-03-27
-1ygg,2005-06-28,2005-01-04
-4yg0,2015-09-30,2015-02-25
-5yg4,2018-06-06,2017-09-22
-5yg9,2018-02-14,2017-09-22
-6ygd,2020-10-28,2020-03-27
-6ygg,2020-12-23,2020-03-27
-6yg5,2020-08-12,2020-03-27
-2ygt,2012-05-16,2011-04-20
-5ygq,2018-09-26,2017-09-25
-8ygy,2024-03-13,2024-02-27
-5yg5,2018-02-14,2017-09-22
-6yg2,2020-08-12,2020-03-27
-5ygp,2018-10-03,2017-09-25
-2ygn,2011-07-20,2011-04-19
-5ygx,2018-08-08,2017-09-27
-6ygo,2020-04-08,2020-03-27
-6yg3,2020-08-12,2020-03-27
-4yge,2016-04-06,2015-02-26
-4ygn,2015-03-25,2015-02-26
-4ygg,2016-03-02,2015-02-26
-2ygp,2011-07-13,2011-04-19
-5ygi,2018-09-26,2017-09-23
-8ygw,2024-03-13,2024-02-27
-7yg2,2023-03-29,2022-07-09
-5yga,2018-02-14,2017-09-22
-6ygx,2020-04-08,2020-03-27
-6yg4,2020-08-12,2020-03-27
-2yg6,2011-05-18,2011-04-11
-5yge,2017-10-11,2017-09-22
-6ygj,2020-09-16,2020-03-27
-2yge,2011-11-16,2011-04-14
-4ygy,2015-09-16,2015-02-26
-5ygg,2018-09-26,2017-09-22
-4ygl,2015-03-25,2015-02-26
-2ygk,2011-12-14,2011-04-18
-7ygn,2024-01-24,2022-07-11
-1ygr,2005-02-22,2005-01-05
-6ygl,2020-04-08,2020-03-27
-6ygq,2021-04-07,2020-03-27
-1yg5,2005-01-11,2005-01-04
-2yg1,2012-04-25,2011-04-11
-6ygk,2020-04-08,2020-03-27
-5yg1,2018-09-26,2017-09-22
-5ygm,2017-10-25,2017-09-24
-4ygh,2016-03-02,2015-02-26
-7yg6,2024-01-24,2022-07-11
-4ygx,2015-09-16,2015-02-26
-5yg6,2018-02-14,2017-09-22
-6ygc,2020-10-28,2020-03-27
-5yg7,2018-02-14,2017-09-22
-5ygy,2018-05-23,2017-09-27
-1ygk,2005-07-05,2005-01-05
-4ygm,2015-06-10,2015-02-26
-7ygq,2022-12-21,2022-07-12
-4ygd,2016-04-06,2015-02-26
-2ygi,2012-04-25,2011-04-18
-5ygs,2018-10-03,2017-09-26
-2yg3,2011-05-18,2011-04-11
-7ygy,2023-03-15,2022-07-12
-1ygb,2005-01-25,2005-01-04
-4ygz,2016-03-02,2015-02-26
-2yg0,2011-05-18,2011-04-11
-5yg8,2018-02-14,2017-09-22
-4ygi,2016-02-17,2015-02-26
-1ygc,2005-01-18,2005-01-04
-2yg9,2011-04-20,2011-04-11
-2ygl,2011-06-22,2011-04-18
-4ygj,2015-03-25,2015-02-26
-6ygu,2021-05-05,2020-03-27
-2ygg,2011-09-28,2011-04-15
-4ygb,2016-04-06,2015-02-26
-7ygg,2022-10-19,2022-07-11
-7ygv,2023-03-15,2022-07-12
-7ygh,2023-02-15,2022-07-11
-2yg7,2011-05-18,2011-04-11
-4ygr,2015-04-22,2015-02-26
-4yg6,2015-09-30,2015-02-25
-7ygw,2023-03-15,2022-07-12
-7yg3,2023-07-26,2022-07-11
-4ygc,2016-04-06,2015-02-26
-6ygb,2020-10-28,2020-03-27
-6ygm,2020-04-08,2020-03-27
-1yg9,2005-03-22,2005-01-04
-4ygw,2015-07-01,2015-02-26
-6ygs,2020-04-08,2020-03-27
-4yga,2015-08-26,2015-02-26
-6yg7,2020-08-12,2020-03-27
-2yg5,2011-05-18,2011-04-11
-1ygj,2005-07-05,2005-01-05
-2ygm,2011-06-22,2011-04-19
-5yg2,2018-06-06,2017-09-22
-6ygy,2020-04-08,2020-03-28
-7ygl,2023-02-15,2022-07-11
-6yg1,2020-08-12,2020-03-27
-6ygp,2020-04-08,2020-03-27
-6yge,2020-12-23,2020-03-27
-7yg5,2023-11-29,2022-07-11
-4ygo,2015-10-07,2015-02-26
-2ygf,2011-11-16,2011-04-14
-6ygz,2020-04-08,2020-03-28
-1ygp,1996-12-23,1996-05-30
-2yga,2011-11-16,2011-04-12
-5ygf,2018-03-14,2017-09-22
-1yge,1997-07-23,1996-06-04
-2ygo,2011-07-13,2011-04-19
-5yg3,2018-06-06,2017-09-22
-4ygs,2015-04-22,2015-02-26
-1ygf,2005-01-11,2005-01-04
-5ygk,2018-07-25,2017-09-23
-5ygv,2018-04-18,2017-09-27
-6yg6,2020-08-12,2020-03-27
-6ygw,2020-04-08,2020-03-27
-1ygd,2005-01-11,2005-01-04
-6ygv,2020-04-08,2020-03-27
-4yg2,2015-03-18,2015-02-25
-2ygx,2012-02-29,2011-04-22
-7ygi,2023-02-08,2022-07-11
-6p1k,2020-02-26,2019-05-20
-6p13,2019-08-07,2019-05-17
-6p1w,2019-09-04,2019-05-20
-2p1r,2007-10-23,2007-03-06
-2p18,2008-01-15,2007-03-02
-6p1x,2019-07-24,2019-05-20
-1p1k,2003-07-08,2003-04-12
-6p11,2019-07-24,2019-05-17
-7p1f,2021-10-20,2021-07-01
-1p1o,2003-06-10,2003-04-13
-6p1e,2019-09-25,2019-05-19
-6p1d,2019-12-18,2019-05-19
-7p1s,2021-10-20,2021-07-02
-8p1q,2024-05-22,2023-05-12
-2p1h,2007-05-15,2007-03-05
-7p1u,2021-10-20,2021-07-02
-4p1u,2014-07-30,2014-02-27
-2p1p,2007-04-10,2007-03-06
-6p1p,2019-09-04,2019-05-20
-8p10,2023-10-11,2023-05-11
-2p1v,2007-10-09,2007-03-06
-2p1n,2007-04-10,2007-03-06
-3p19,2011-07-20,2010-09-30
-6p1l,2019-12-18,2019-05-20
-7p19,2022-07-13,2021-07-01
-2p1c,2008-03-04,2007-03-04
-2p1d,2007-03-20,2007-03-05
-7p1e,2021-10-20,2021-07-01
-7p11,2021-12-15,2021-07-01
-8p1p,2024-05-22,2023-05-12
-7p1h,2021-11-17,2021-07-01
-1p1w,2003-06-10,2003-04-14
-2p1i,2007-03-27,2007-03-05
-3p1d,2010-11-24,2010-09-30
-8p1s,2024-05-22,2023-05-12
-1p18,2004-05-18,2003-04-11
-8p1x,2023-12-06,2023-05-13
-3p13,2011-05-25,2010-09-29
-6p1g,2019-09-25,2019-05-19
-4p1c,2014-10-01,2014-02-25
-1p1i,2003-07-08,2003-04-12
-3p1o,2011-10-12,2010-09-30
-8p1n,2024-05-22,2023-05-12
-8p16,2024-05-22,2023-05-11
-4p1h,2015-03-04,2014-02-26
-6p1n,2019-09-04,2019-05-20
-7p1o,2021-10-20,2021-07-02
-1p1v,2003-08-26,2003-04-14
-6p1u,2019-09-04,2019-05-20
-7p1v,2021-10-20,2021-07-02
-8p1r,2024-03-27,2023-05-12
-1p19,2004-05-18,2003-04-11
-7p1q,2021-10-20,2021-07-02
-1p11,1993-01-15,1990-10-26
-7p1g,2021-11-17,2021-07-01
-3p1p,2011-10-12,2010-09-30
-1p16,2003-07-15,2003-04-11
-6p1v,2019-09-04,2019-05-20
-3p17,2011-11-02,2010-09-30
-3p1h,2011-10-05,2010-09-30
-3p1m,2010-11-03,2010-09-30
-2p15,2007-05-01,2007-03-02
-7p1l,2021-07-14,2021-07-01
-8p1g,2024-03-20,2023-05-12
-4p19,2014-06-04,2014-02-25
-8p1t,2023-08-30,2023-05-12
-2p16,2007-10-16,2007-03-02
-7p1a,2021-11-17,2021-07-01
-3p11,2011-10-26,2010-09-29
-1p1j,2003-07-08,2003-04-12
-6p1z,2020-05-27,2019-05-20
-3p1r,2011-10-12,2010-09-30
-4p16,2014-05-07,2014-02-25
-7p17,2022-07-13,2021-07-01
-2p17,2007-05-01,2007-03-02
-2p1t,2007-10-09,2007-03-06
-4p1q,2014-07-16,2014-02-27
-3p1v,2010-10-27,2010-09-30
-6p1m,2019-09-04,2019-05-20
-8p1o,2024-01-31,2023-05-12
-8p1d,2023-10-18,2023-05-11
-2p1x,2007-10-02,2007-03-06
-4p1b,2014-10-01,2014-02-25
-4p14,2015-04-15,2014-02-24
-7p1m,2021-12-15,2021-07-02
-6p10,2019-07-24,2019-05-17
-1p12,1993-01-15,1990-10-26
-1p13,2003-08-19,2003-04-11
-3p1q,2011-10-12,2010-09-30
-6p1q,2019-09-04,2019-05-20
-8p1e,2024-05-08,2023-05-11
-2p1q,2007-04-10,2007-03-06
-3p1s,2011-10-12,2010-09-30
-8p1f,2024-05-08,2023-05-12
-3p1g,2010-10-13,2010-09-30
-4p1a,2014-06-04,2014-02-25
-1p1r,2003-07-15,2003-04-13
-2p1e,2008-01-15,2007-03-05
-3p10,2010-11-10,2010-09-29
-1p1n,2003-06-10,2003-04-13
-3p1c,2010-11-24,2010-09-30
-8p1w,2023-08-30,2023-05-12
-8p14,2024-05-22,2023-05-11
-4p1j,2015-03-25,2014-02-26
-6p1h,2019-10-02,2019-05-19
-3p1n,2011-10-12,2010-09-30
-8p11,2024-05-08,2023-05-11
-3p1e,2010-11-24,2010-09-30
-8p18,2024-05-22,2023-05-11
-8p1m,2024-05-22,2023-05-12
-4p1l,2014-03-19,2014-02-26
-4p11,2015-03-18,2014-02-24
-7p1d,2021-10-20,2021-07-01
-8p17,2024-05-22,2023-05-11
-4p1o,2015-04-15,2014-02-27
-1p1u,2003-06-10,2003-04-14
-6p1t,2019-09-04,2019-05-20
-7p1n,2022-06-08,2021-07-02
-1p1z,2003-11-11,2003-04-14
-7p1z,2021-07-21,2021-07-03
-7p1r,2021-10-20,2021-07-02
-1p1q,2003-06-10,2003-04-13
-4p1r,2014-07-23,2014-02-27
-6p12,2019-07-24,2019-05-17
-1p1h,2003-07-08,2003-04-12
-2p1f,2007-04-03,2007-03-05
-8p1v,2023-08-30,2023-05-12
-2p1u,2007-10-09,2007-03-06
-6p1i,2019-07-24,2019-05-19
-4p1g,2015-03-04,2014-02-26
-7p1y,2022-07-13,2021-07-02
-1p17,2004-05-18,2003-04-11
-4p10,2014-08-13,2014-02-21
-8p1c,2023-10-18,2023-05-11
-1p10,1990-04-15,1989-04-24
-4p1w,2014-05-07,2014-02-27
-6p18,2019-06-26,2019-05-19
-6p1r,2019-09-04,2019-05-20
-6p14,2019-07-24,2019-05-17
-4p1v,2014-04-02,2014-02-27
-7p1k,2022-01-26,2021-07-01
-1p1m,2003-04-29,2003-04-12
-1p1c,2003-04-29,2003-04-12
-6p16,2019-09-25,2019-05-19
-2p1o,2007-04-10,2007-03-06
-8p1i,2024-01-17,2023-05-12
-3p1f,2010-12-08,2010-09-30
-1p1b,2003-04-29,2003-04-12
-2p1s,2007-04-17,2007-03-06
-7p1p,2021-12-29,2021-07-02
-7p15,2021-12-08,2021-07-01
-7p18,2021-07-21,2021-07-01
-6p1o,2019-09-04,2019-05-20
-3p1l,2010-12-22,2010-09-30
-4p13,2015-03-18,2014-02-24
-6p19,2019-06-26,2019-05-19
-6p1s,2019-09-04,2019-05-20
-1ohz,2003-11-20,2003-06-04
-5ohz,2018-08-08,2017-07-18
-8ohr,2024-01-10,2023-03-21
-1oh2,2003-05-29,2003-05-21
-7ohs,2021-11-03,2021-05-11
-1oh6,2003-08-08,2003-05-23
-1ohw,2003-10-16,2003-06-03
-6oha,2019-07-24,2019-04-05
-7ohr,2021-11-10,2021-05-11
-2oh8,2007-01-23,2007-01-09
-7ohw,2021-11-03,2021-05-11
-8ohc,2024-04-03,2023-03-21
-8ohq,2024-01-10,2023-03-21
-1oh5,2003-08-08,2003-05-23
-4oh1,2014-02-05,2014-01-16
-5oh8,2018-10-10,2017-07-14
-1ohy,2003-10-16,2003-06-03
-3ohf,2011-04-06,2010-08-17
-2ohf,2007-04-24,2007-01-10
-2oh2,2007-02-27,2007-01-09
-4oho,2014-07-30,2014-01-17
-8oh5,2023-09-13,2023-03-20
-2ohm,2007-03-13,2007-01-10
-6oht,2019-06-19,2019-04-06
-6ohl,2019-06-05,2019-04-05
-8oho,2024-04-03,2023-03-21
-4oh2,2014-10-15,2014-01-16
-3ohs,2011-08-24,2010-08-18
-8ohl,2024-04-03,2023-03-21
-6ohd,2019-11-20,2019-04-05
-4oha,2014-08-20,2014-01-17
-3ohx,2010-09-01,2010-08-18
-7ohk,2022-03-02,2021-05-11
-6ohb,2019-07-24,2019-04-05
-8ohg,2024-04-03,2023-03-21
-2ohk,2007-03-13,2007-01-10
-7oh6,2021-06-09,2021-05-09
-8ohv,2024-01-10,2023-03-21
-5oh4,2018-10-10,2017-07-14
-1ohp,2005-03-31,2003-05-29
-1oho,2005-03-31,2003-05-29
-8ohd,2024-02-21,2023-03-21
-2oht,2007-03-13,2007-01-10
-4ohc,2014-02-05,2014-01-17
-3ohl,2011-06-29,2010-08-17
-5ohf,2017-11-08,2017-07-16
-8ohw,2024-01-10,2023-03-21
-5ohp,2017-09-20,2017-07-17
-1ohs,2005-03-31,2003-05-30
-1ohv,2003-10-16,2003-06-02
-5ohy,2018-08-08,2017-07-18
-6ohk,2019-06-05,2019-04-05
-4ohb,2014-06-25,2014-01-17
-6ohh,2020-04-08,2019-04-05
-5ohs,2018-08-08,2017-07-18
-8ohx,2024-01-10,2023-03-21
-8ohh,2024-04-03,2023-03-21
-2ohl,2007-03-13,2007-01-10
-5ohb,2018-10-10,2017-07-14
-5ohq,2017-09-13,2017-07-17
-7ohy,2021-11-03,2021-05-11
-5oh9,2018-10-10,2017-07-14
-7ohl,2022-03-02,2021-05-11
-5oh7,2018-10-10,2017-07-14
-8oh1,2024-03-27,2023-03-20
-2oh6,2007-03-06,2007-01-09
-7ohn,2022-03-02,2021-05-11
-6ohw,2019-06-05,2019-04-07
-2ohp,2007-05-01,2007-01-10
-6ohg,2020-06-17,2019-04-05
-7oht,2021-11-03,2021-05-11
-5ohn,2017-09-20,2017-07-17
-6ohq,2020-02-19,2019-04-06
-2oh3,2007-01-23,2007-01-09
-4ohy,2014-05-14,2014-01-18
-2ohq,2007-03-13,2007-01-10
-8ohe,2024-04-03,2023-03-21
-5ohi,2018-01-03,2017-07-17
-4ohx,2014-05-14,2014-01-18
-7ohv,2021-11-03,2021-05-11
-6oh4,2019-04-24,2019-04-04
-1ohf,2004-02-26,2003-05-26
-4oh6,2014-08-20,2014-01-17
-6ohc,2019-07-24,2019-04-05
-8ohy,2023-03-29,2023-03-21
-6ohp,2020-02-19,2019-04-06
-1ohe,2003-07-24,2003-05-24
-3oh1,2010-11-17,2010-08-17
-3oho,2011-06-29,2010-08-17
-2ohx,1993-10-31,1993-08-24
-5ohe,2017-11-08,2017-07-16
-4oh4,2014-10-29,2014-01-17
-3ohi,2011-01-19,2010-08-17
-4ohf,2014-02-26,2014-01-17
-1oh8,2003-08-08,2003-05-23
-4ohu,2014-04-30,2014-01-18
-3oh3,2010-11-17,2010-08-17
-7oh7,2021-06-09,2021-05-09
-6ohy,2019-06-05,2019-04-08
-7ohu,2021-11-03,2021-05-11
-1oh7,2003-08-08,2003-05-23
-6ohr,2020-02-19,2019-04-06
-8ohf,2024-04-03,2023-03-21
-8oh0,2024-03-27,2023-03-20
-3ohr,2010-09-15,2010-08-17
-8ohj,2024-04-03,2023-03-21
-2oh9,2007-01-23,2007-01-09
-7ohh,2022-03-02,2021-05-11
-1ohr,1998-12-09,1997-09-27
-6ohu,2019-06-19,2019-04-06
-7ohq,2021-11-03,2021-05-11
-8oha,2023-08-23,2023-03-20
-3oh2,2010-11-17,2010-08-17
-1oh9,2003-07-31,2003-05-23
-2oh4,2007-09-18,2007-01-09
-3oh4,2010-11-17,2010-08-17
-8ohb,2024-04-03,2023-03-21
-8ohz,2023-12-27,2023-03-21
-8ohk,2024-04-03,2023-03-21
-5oh3,2018-10-10,2017-07-14
-3ohb,2010-12-22,2010-08-17
-4ohw,2014-05-14,2014-01-18
-7ohg,2022-06-01,2021-05-11
-2oh0,2007-03-20,2007-01-09
-4oht,2014-12-10,2014-01-18
-5oh2,2018-10-10,2017-07-14
-2ohs,2007-03-13,2007-01-10
-8oh9,2023-09-13,2023-03-20
-2ohh,2007-05-22,2007-01-10
-6oh2,2019-04-24,2019-04-04
-1ohj,1998-04-29,1997-09-17
-1oha,2003-07-31,2003-05-23
-1ohk,1998-05-27,1997-09-17
-8ohu,2024-01-10,2023-03-21
-1oht,2003-07-18,2003-05-31
-1oh0,2003-06-04,2003-05-21
-7oh4,2021-06-09,2021-05-09
-3oht,2011-06-29,2010-08-18
-5oh1,2018-10-10,2017-07-14
-2oh5,2007-03-06,2007-01-09
-1oh4,2004-03-16,2003-05-21
-4ohp,2014-07-30,2014-01-17
-7ohp,2021-11-03,2021-05-11
-2ohr,2007-03-13,2007-01-10
-6oh7,2019-04-17,2019-04-04
-5ohk,2017-09-20,2017-07-17
-7oh5,2021-06-09,2021-05-09
-7ohd,2022-07-13,2021-05-10
-2ohb,2007-01-23,2007-01-09
-4ohk,2014-10-08,2014-01-17
-7oh3,2021-11-03,2021-05-08
-2ohi,2007-05-22,2007-01-10
-2oha,2007-01-23,2007-01-09
-6oh9,2019-07-24,2019-04-05
-6ohj,2019-05-29,2019-04-05
-5ohg,2017-07-26,2017-07-16
-8ohn,2023-08-02,2023-03-21
-8oht,2024-01-10,2023-03-21
-2ohn,2007-03-13,2007-01-10
-6ohe,2020-04-08,2019-04-05
-5ohj,2017-12-13,2017-07-17
-2ohu,2007-03-13,2007-01-10
-4oh5,2014-08-20,2014-01-17
-4ohn,2015-01-21,2014-01-17
-6oh3,2019-04-24,2019-04-04
-7ohx,2021-11-03,2021-05-11
-8oh8,2024-01-17,2023-03-20
-3oha,2010-12-22,2010-08-17
-4ohz,2014-05-14,2014-01-18
-2oh7,2007-03-06,2007-01-09
-4ohm,2014-07-30,2014-01-17
-1oh3,2004-05-27,2003-05-21
-5ohx,2018-01-03,2017-07-18
-2ohj,2007-05-22,2007-01-10
-6ohs,2020-02-19,2019-04-06
-4ohv,2014-05-14,2014-01-18
-3ohe,2010-09-08,2010-08-17
-5oha,2018-10-10,2017-07-14
-5ohh,2018-08-08,2017-07-17
-5oht,2018-08-08,2017-07-18
-3oh0,2010-11-17,2010-08-17
-1ohl,2003-06-02,2003-05-27
-6oh6,2019-04-17,2019-04-04
-3ohh,2011-04-06,2010-08-17
-1ohb,2003-07-31,2003-05-23
-2ohv,2007-09-25,2007-01-10
-5zp1,2018-12-19,2018-04-16
-3zpr,2013-04-03,2013-03-01
-4zpl,2015-10-28,2015-05-08
-6zpu,2020-10-28,2020-07-09
-4zpn,2015-10-28,2015-05-08
-4zpm,2015-10-28,2015-05-08
-2zp7,2009-01-13,2008-06-30
-2zpg,2008-10-21,2008-07-11
-1zp3,2005-08-09,2005-05-16
-3zpi,2014-03-19,2013-02-27
-5zp8,2018-12-19,2018-04-16
-2zpy,2008-08-26,2008-07-31
-1zpv,2005-06-28,2005-05-17
-5zp0,2018-12-19,2018-04-16
-6zp8,2021-05-19,2020-07-08
-4zp3,2016-05-04,2015-05-07
-2zpr,2009-07-28,2008-07-28
-2zps,2009-07-28,2008-07-28
-6zpl,2021-03-17,2020-07-08
-1zpc,2006-04-18,2005-05-16
-1zpa,2005-05-31,2005-05-16
-3zpo,2013-05-29,2013-02-28
-1zpt,2005-08-09,2005-05-17
-4zpw,2015-08-12,2015-05-08
-2zpq,2009-07-28,2008-07-28
-6zph,2020-12-30,2020-07-08
-3zp3,2013-10-02,2013-02-26
-5zp2,2018-12-19,2018-04-16
-5zp3,2018-12-19,2018-04-16
-3zp0,2013-10-02,2013-02-26
-4zpt,2015-10-21,2015-05-08
-7zp2,2022-08-24,2022-04-26
-5zpe,2018-12-19,2018-04-16
-4zpv,2015-10-21,2015-05-08
-7zpd,2023-03-22,2022-04-27
-2zpt,2008-11-18,2008-07-28
-2zpu,2009-04-28,2008-07-29
-3zp7,2014-04-16,2013-02-26
-5zph,2018-12-19,2018-04-16
-5zpd,2018-12-19,2018-04-16
-6zp0,2020-07-22,2020-07-08
-1zpl,2006-05-23,2005-05-17
-6zp9,2021-03-03,2020-07-08
-7zpu,2023-05-10,2022-04-28
-6zpi,2020-12-30,2020-07-08
-2zpa,2009-04-07,2008-07-08
-3zp4,2014-04-16,2013-02-26
-2zpk,2008-12-23,2008-07-16
-6zpo,2020-09-09,2020-07-09
-1zpe,2005-12-06,2005-05-16
-1zp8,2005-06-21,2005-05-16
-1zpz,2006-05-09,2005-05-18
-3zpp,2013-05-29,2013-02-28
-7zps,2023-05-10,2022-04-28
-3zps,2013-11-06,2013-03-01
-3zpz,2013-06-19,2013-03-04
-5zpf,2018-12-19,2018-04-16
-6zp3,2021-05-19,2020-07-08
-7zp7,2022-09-28,2022-04-26
-3zp1,2013-10-02,2013-02-26
-4zp1,2015-11-04,2015-05-07
-2zp6,2008-07-22,2008-06-27
-2zpi,2008-10-21,2008-07-11
-6zpc,2021-03-03,2020-07-08
-3zpu,2013-11-06,2013-03-01
-2zpn,2008-12-09,2008-07-17
-6zpr,2020-12-16,2020-07-09
-1zp9,2005-08-02,2005-05-16
-2zph,2008-10-21,2008-07-11
-3zpy,2013-06-26,2013-03-04
-4zpe,2015-08-05,2015-05-07
-6zp1,2020-07-22,2020-07-08
-5zpb,2018-12-19,2018-04-16
-2zp9,2009-02-03,2008-07-08
-6zpb,2021-03-03,2020-07-08
-5zpq,2018-12-19,2018-04-16
-2zpe,2008-10-21,2008-07-10
-5zp7,2018-12-19,2018-04-16
-5zps,2018-12-19,2018-04-16
-5zpt,2018-12-19,2018-04-16
-1zpk,2006-04-25,2005-05-17
-2zpb,2008-10-21,2008-07-09
-7zpc,2023-02-01,2022-04-27
-1zps,2005-08-30,2005-05-17
-4zpg,2015-08-05,2015-05-07
-6zp2,2020-07-22,2020-07-08
-1zp4,2005-08-09,2005-05-16
-5zp4,2018-12-19,2018-04-16
-6zp4,2020-07-29,2020-07-08
-5zpc,2018-12-19,2018-04-16
-5zpn,2018-12-19,2018-04-16
-3zpc,2013-03-27,2013-02-27
-6zpz,2020-11-11,2020-07-09
-2zp1,2009-02-17,2008-06-22
-5zp5,2018-12-19,2018-04-16
-4zpf,2015-08-05,2015-05-07
-1zp5,2005-12-06,2005-05-16
-4zpi,2015-08-05,2015-05-07
-1zpb,2006-04-18,2005-05-16
-5zpi,2018-12-19,2018-04-16
-4zpq,2015-10-28,2015-05-08
-3zpa,2013-10-02,2013-02-27
-6zp5,2020-07-29,2020-07-08
-6zpd,2020-12-02,2020-07-08
-2zp8,2009-02-03,2008-07-08
-2zp0,2008-07-15,2008-06-20
-6zpm,2020-10-21,2020-07-08
-4zpj,2015-05-20,2015-05-07
-3zpt,2013-11-06,2013-03-01
-2zp3,2008-11-04,2008-06-27
-6zpt,2020-10-28,2020-07-09
-3zp6,2013-10-02,2013-02-26
-2zpf,2008-10-21,2008-07-11
-7zpl,2022-12-28,2022-04-27
-6zpv,2020-11-11,2020-07-09
-5zpm,2018-12-19,2018-04-16
-2zp5,2008-11-04,2008-06-27
-1zpr,1997-07-07,1996-10-15
-6zp6,2021-05-19,2020-07-08
-6zps,2020-11-11,2020-07-09
-5zp9,2018-12-19,2018-04-16
-1zpd,1999-02-02,1998-04-17
-7zpb,2023-02-01,2022-04-27
-4zpo,2015-10-28,2015-05-08
-6zpy,2020-11-11,2020-07-09
-6zp7,2020-07-29,2020-07-08
-5zpo,2018-12-19,2018-04-16
-5zpj,2018-12-19,2018-04-16
-1zp0,2005-07-12,2005-05-16
-5zpu,2019-04-17,2018-04-16
-1zpg,2005-12-06,2005-05-16
-3zpb,2013-10-02,2013-02-27
-2zp4,2008-11-04,2008-06-27
-2zpl,2008-10-21,2008-07-17
-4zpp,2015-10-28,2015-05-08
-7zp9,2023-05-10,2022-04-27
-4zp0,2015-08-19,2015-05-07
-5zpl,2018-12-19,2018-04-16
-3zpg,2013-03-27,2013-02-27
-7zpo,2023-05-10,2022-04-28
-6zpw,2020-11-11,2020-07-09
-4zp5,2016-10-05,2015-05-07
-3zpq,2013-04-03,2013-03-01
-1zpu,2005-10-04,2005-05-17
-6zpq,2020-10-28,2020-07-09
-3zp2,2013-10-02,2013-02-26
-5zpg,2018-12-19,2018-04-16
-7zpq,2023-02-22,2022-04-28
-5zpp,2018-12-19,2018-04-16
-4zph,2015-08-12,2015-05-07
-7zpy,2022-10-26,2022-04-29
-7zpg,2022-09-21,2022-04-27
-5zpa,2018-12-19,2018-04-16
-6zpx,2020-11-11,2020-07-09
-4zps,2015-10-28,2015-05-08
-7zpr,2023-05-10,2022-04-28
-5zpk,2018-12-19,2018-04-16
-5zpr,2018-12-19,2018-04-16
-3zpv,2013-10-30,2013-03-02
-7zpf,2023-05-10,2022-04-27
-5zp6,2018-12-19,2018-04-16
-6zpa,2021-03-03,2020-07-08
-6zpe,2020-10-14,2020-07-08
-8jqw,2024-04-17,2023-06-15
-3jqa,2009-12-08,2009-09-06
-3jqm,2010-06-30,2009-09-07
-1jqw,2001-10-24,2001-08-09
-1jqa,2001-10-03,2001-08-04
-5jqr,2016-12-21,2016-05-05
-6jqq,2020-04-01,2019-04-01
-6jqb,2020-04-01,2019-03-30
-8jqz,2024-04-24,2023-06-15
-8jqf,2024-01-03,2023-06-14
-4jq8,2013-06-19,2013-03-20
-4jqv,2013-06-26,2013-03-20
-3jqg,2009-12-08,2009-09-06
-4jqt,2013-04-17,2013-03-20
-3jq7,2009-12-08,2009-09-06
-4jqe,2014-03-05,2013-03-20
-4jq3,2014-04-02,2013-03-19
-4jql,2013-04-10,2013-03-20
-5jqj,2017-05-10,2016-05-05
-1jqb,2002-11-13,2001-08-05
-2jqr,2008-04-22,2007-06-07
-1jqx,2003-09-09,2001-08-09
-4jqr,2013-04-10,2013-03-20
-1jqv,2003-09-09,2001-08-09
-6jqz,2020-04-08,2019-04-02
-1jqd,2002-08-06,2001-08-06
-8jqo,2023-12-06,2023-06-14
-7jqu,2021-09-08,2020-08-11
-4jqp,2013-04-17,2013-03-20
-3jqd,2009-12-08,2009-09-06
-3jq8,2009-12-08,2009-09-06
-7jqk,2021-07-21,2020-08-11
-3jqb,2009-12-08,2009-09-06
-6jqn,2019-09-11,2019-03-31
-1jq9,2002-11-06,2001-08-04
-8jq5,2024-03-13,2023-06-13
-4jqh,2013-11-20,2013-03-20
-5jqh,2016-07-13,2016-05-05
-4jq6,2013-05-08,2013-03-20
-3jqw,2010-09-29,2009-09-08
-6jq8,2020-04-01,2019-03-29
-7jq0,2020-12-23,2020-08-10
-6jqr,2019-11-20,2019-04-01
-8jqp,2023-12-06,2023-06-14
-1jqi,2002-02-13,2001-08-07
-6jq3,2020-05-06,2019-03-28
-8jq3,2024-03-13,2023-06-13
-6jqm,2019-09-11,2019-03-31
-7jqq,2021-05-19,2020-08-11
-5jq0,2016-10-19,2016-05-04
-6jq2,2020-04-01,2019-03-28
-5jq3,2016-06-29,2016-05-04
-7jqa,2020-08-19,2020-08-10
-3jq3,2010-09-15,2009-09-05
-3jq5,2009-09-29,2009-09-06
-5jqa,2017-10-11,2016-05-04
-3jqr,2010-01-12,2009-09-07
-7jqo,2021-07-21,2020-08-11
-7jqg,2021-03-03,2020-08-10
-2jq6,2008-04-15,2007-05-29
-7jq3,2020-12-23,2020-08-10
-5jq9,2016-08-10,2016-05-04
-4jq0,2014-05-21,2013-03-19
-4jqc,2014-03-26,2013-03-20
-8jq4,2024-03-13,2023-06-13
-6jqh,2020-04-08,2019-03-31
-7jqn,2021-07-21,2020-08-11
-5jqk,2016-08-31,2016-05-05
-4jq9,2014-04-02,2013-03-20
-5jq8,2017-02-08,2016-05-04
-5jqu,2016-09-28,2016-05-05
-4jqa,2014-04-02,2013-03-20
-4jqm,2013-07-31,2013-03-20
-3jqq,2010-01-12,2009-09-07
-7jq5,2020-12-23,2020-08-10
-1jqn,2003-01-14,2001-08-07
-3jqe,2009-12-08,2009-09-06
-7jq1,2020-12-23,2020-08-10
-3jq1,2009-09-22,2009-09-04
-7jq2,2020-12-23,2020-08-10
-1jqh,2002-04-19,2001-08-07
-7jql,2020-08-26,2020-08-11
-5jq5,2017-02-08,2016-05-04
-4jqi,2013-04-17,2013-03-20
-3jq9,2009-12-08,2009-09-06
-4jqo,2013-04-17,2013-03-20
-1jq7,2001-09-12,2001-08-03
-7jqi,2021-09-08,2020-08-11
-5jqv,2016-09-28,2016-05-05
-7jqh,2021-09-08,2020-08-11
-1jq3,2001-11-21,2001-08-03
-4jq1,2014-04-02,2013-03-19
-3jqf,2009-12-08,2009-09-06
-6jqf,2019-12-11,2019-03-31
-6jq0,2019-12-25,2019-03-28
-1jq8,2002-11-06,2001-08-04
-4jqn,2013-07-31,2013-03-20
-5jqg,2016-05-18,2016-05-04
-8jqq,2023-12-06,2023-06-14
-6jqx,2020-04-01,2019-04-01
-3jql,2009-09-29,2009-09-07
-6jq1,2019-08-28,2019-03-28
-6jq9,2020-04-01,2019-03-29
-1jqe,2002-08-06,2001-08-06
-5jq2,2016-10-12,2016-05-04
-7jqw,2021-08-25,2020-08-11
-6jqo,2019-09-11,2019-03-31
-5jqy,2017-05-24,2016-05-05
-1jq5,2001-10-01,2001-08-03
-2jq7,2007-07-03,2007-05-30
-5jq7,2016-06-29,2016-05-04
-7jqs,2021-09-08,2020-08-11
-4jqj,2013-07-31,2013-03-20
-7jqr,2021-09-08,2020-08-11
-4jq2,2014-04-02,2013-03-19
-2jq5,2007-06-26,2007-05-29
-5jqp,2016-09-14,2016-05-05
-7jqm,2020-08-26,2020-08-11
-4jqg,2014-03-12,2013-03-20
-6jqd,2019-08-14,2019-03-30
-6jqw,2020-04-08,2019-04-01
-1jqf,2001-10-17,2001-08-06
-5jq1,2017-06-14,2016-05-04
-6jqc,2019-08-14,2019-03-30
-1jqg,2002-08-07,2001-08-07
-8jq6,2024-03-13,2023-06-13
-3jqc,2009-12-08,2009-09-06
-4jq4,2014-04-02,2013-03-19
-1jqp,2002-10-18,2001-08-08
-3jqp,2010-01-12,2009-09-07
-7jqj,2021-09-08,2020-08-11
-7jqt,2021-09-08,2020-08-11
-6jqe,2019-08-14,2019-03-30
-3jq6,2009-12-08,2009-09-06
-3jqz,2010-04-21,2009-09-08
-1jqy,2002-05-08,2001-08-09
-5jqb,2016-06-29,2016-05-04
-8jqe,2024-01-03,2023-06-14
-4jqk,2013-07-31,2013-03-20
-1jqc,2001-08-22,2001-08-06
-3jqx,2010-09-29,2009-09-08
-7jq4,2020-12-23,2020-08-10
-5jqw,2016-05-18,2016-05-05
-4jq7,2013-06-19,2013-03-20
-5jqt,2016-10-19,2016-05-05
-3p82,2011-03-02,2010-10-13
-1p81,2003-09-09,2003-05-06
-7p8e,2021-10-20,2021-07-21
-4p8l,2014-12-10,2014-03-31
-4p86,2014-12-17,2014-03-30
-1p8l,2003-08-26,2003-05-07
-1p8d,2003-07-08,2003-05-06
-7p84,2021-11-17,2021-07-21
-5p8z,2017-08-30,2016-08-29
-7p8h,2022-03-02,2021-07-22
-6p83,2019-08-28,2019-06-06
-3p8x,2011-08-31,2010-10-15
-2p8s,2007-05-22,2007-03-23
-4p8s,2014-04-09,2014-04-01
-1p8o,2003-06-17,2003-05-07
-3p8j,2011-04-06,2010-10-14
-7p8n,2022-09-14,2021-07-23
-6p8i,2020-06-24,2019-06-07
-8p8j,2023-08-30,2023-06-01
-6p8x,2019-08-28,2019-06-08
-4p8r,2014-06-18,2014-03-31
-2p8z,2007-05-08,2007-03-23
-8p8k,2023-09-20,2023-06-01
-3p86,2011-10-26,2010-10-13
-6p8s,2019-12-25,2019-06-07
-7p8d,2021-10-20,2021-07-21
-6p8m,2019-11-20,2019-06-07
-8p88,2024-01-31,2023-05-31
-7p8l,2022-08-03,2021-07-23
-3p8g,2011-08-03,2010-10-13
-5p8y,2017-08-30,2016-08-29
-6p8c,2020-06-10,2019-06-06
-1p84,2003-07-29,2003-05-06
-1p8r,2003-06-17,2003-05-07
-4p8h,2015-10-28,2014-03-31
-1p8q,2003-06-17,2003-05-07
-2p8l,2007-05-15,2007-03-22
-4p8k,2014-12-10,2014-03-31
-6p8n,2019-11-20,2019-06-07
-3p8i,2011-04-06,2010-10-14
-8p84,2023-10-18,2023-05-31
-2p86,2008-04-01,2007-03-21
-2p8p,2007-05-15,2007-03-22
-6p88,2019-08-28,2019-06-06
-8p8x,2023-08-16,2023-06-03
-3p81,2011-03-02,2010-10-13
-6p8e,2019-12-25,2019-06-07
-2p8m,2007-05-15,2007-03-22
-3p8e,2010-11-10,2010-10-13
-1p8t,2003-05-20,2003-05-07
-7p8s,2022-04-06,2021-07-23
-3p8z,2010-12-08,2010-10-15
-7p8q,2022-06-01,2021-07-23
-7p8f,2021-10-20,2021-07-21
-8p8a,2023-08-30,2023-05-31
-6p8y,2019-08-28,2019-06-08
-7p80,2022-06-29,2021-07-21
-6p8a,2019-08-28,2019-06-06
-2p8c,2007-07-03,2007-03-22
-2p8y,2007-05-08,2007-03-23
-1p8f,2003-05-20,2003-05-07
-8p87,2024-05-01,2023-05-31
-2p8x,2007-05-08,2007-03-23
-4p8n,2014-12-10,2014-03-31
-6p8v,2019-12-25,2019-06-08
-3p84,2011-04-06,2010-10-13
-3p8f,2011-08-10,2010-10-13
-7p8k,2021-08-04,2021-07-23
-7p85,2022-08-03,2021-07-21
-7p8c,2021-10-20,2021-07-21
-5p8x,2017-08-30,2016-08-29
-6p80,2019-12-25,2019-06-06
-4p8e,2015-03-25,2014-03-31
-7p8g,2023-01-25,2021-07-21
-4p8v,2014-12-03,2014-04-01
-4p8w,2014-12-03,2014-04-01
-7p88,2021-10-20,2021-07-21
-6p8z,2019-08-28,2019-06-08
-3p8n,2011-01-26,2010-10-14
-7p87,2021-10-20,2021-07-21
-2p8u,2007-04-03,2007-03-23
-8p8p,2023-06-14,2023-06-02
-1p8h,2003-07-07,2003-05-07
-6p8t,2020-11-18,2019-06-07
-6p8u,2019-12-25,2019-06-08
-3p80,2011-03-02,2010-10-13
-3p85,2010-11-03,2010-10-13
-7p8a,2021-10-20,2021-07-21
-6p89,2019-08-28,2019-06-06
-7p8o,2022-08-03,2021-07-23
-3p8h,2010-11-03,2010-10-13
-7p8b,2021-10-20,2021-07-21
-7p8v,2022-06-29,2021-07-23
-7p8u,2022-04-06,2021-07-23
-6p8q,2019-12-18,2019-06-07
-6p8p,2019-12-25,2019-06-07
-4p8m,2014-12-10,2014-03-31
-4p8c,2014-12-10,2014-03-31
-1p8i,2003-07-08,2003-05-07
-7p8m,2021-11-17,2021-07-23
-8p81,2023-11-22,2023-05-31
-6p8o,2019-12-25,2019-06-07
-4p8b,2014-05-07,2014-03-31
-7p8p,2022-06-01,2021-07-23
-1p8j,2003-07-08,2003-05-07
-6p85,2019-08-28,2019-06-06
-6p86,2019-08-28,2019-06-06
-2p8e,2007-04-03,2007-03-22
-2p8w,2007-05-08,2007-03-23
-1p8m,2003-06-17,2003-05-07
-2p88,2007-07-03,2007-03-22
-6p81,2019-07-10,2019-06-06
-7p8w,2021-08-25,2021-07-23
-4p83,2014-12-17,2014-03-30
-6p8b,2019-08-28,2019-06-06
-8p82,2023-06-14,2023-05-31
-2p8b,2007-07-03,2007-03-22
-6p8k,2020-05-13,2019-06-07
-2p85,2007-04-10,2007-03-21
-6p8d,2020-06-10,2019-06-07
-3p8p,2010-11-10,2010-10-14
-1p8x,2003-10-14,2003-05-08
-3p8b,2011-01-26,2010-10-13
-1p8k,2004-01-20,2003-05-07
-4p8p,2014-12-10,2014-03-31
-4p8x,2014-12-03,2014-04-01
-4p8y,2014-12-10,2014-04-01
-8p8c,2023-07-26,2023-05-31
-1p8s,2003-06-17,2003-05-07
-8p86,2024-05-01,2023-05-31
-1p8n,2003-06-17,2003-05-07
-4p8t,2014-12-10,2014-04-01
-6p8l,2020-05-13,2019-06-07
-2p8o,2007-05-08,2007-03-22
-1p8p,2003-06-17,2003-05-07
-2p83,2007-06-19,2007-03-21
-3p8o,2011-01-26,2010-10-14
-2p8h,2007-08-14,2007-03-22
-3p88,2011-08-31,2010-10-13
-1p8z,2003-10-14,2003-05-08
-6p8j,2019-12-25,2019-06-07
-4p8q,2014-12-03,2014-03-31
-2p80,2007-12-11,2007-03-21
-4p8o,2014-10-29,2014-03-31
-1p80,2003-09-09,2003-05-06
-7p8i,2022-08-03,2021-07-22
-2p8n,2007-11-20,2007-03-22
-1p8v,2003-07-22,2003-05-07
-3p8v,2011-08-17,2010-10-15
-7p8j,2022-08-03,2021-07-22
-1p8u,2003-07-08,2003-05-07
-3p89,2011-08-31,2010-10-13
-6p87,2019-08-28,2019-06-06
-7p81,2022-06-29,2021-07-21
-4p87,2014-09-10,2014-03-30
-7p8x,2022-04-06,2021-07-23
-6p8w,2019-08-28,2019-06-08
-6p84,2019-08-28,2019-06-06
-7p8z,2021-11-17,2021-07-23
-3p8y,2011-08-17,2010-10-15
-5p8w,2016-09-07,2016-08-25
-5w7u,2017-12-27,2017-06-20
-3w7s,2013-04-03,2013-03-06
-3w7z,2013-07-03,2013-03-11
-6w7p,2020-04-29,2020-03-19
-3w70,2014-03-05,2013-02-27
-1w7o,2004-09-29,2004-09-07
-3w7q,2014-03-05,2013-03-02
-3w7n,2014-03-05,2013-03-02
-5w7f,2018-01-03,2017-06-19
-3w7u,2013-04-03,2013-03-06
-5w7p,2018-06-27,2017-06-20
-8w7f,2023-11-29,2023-08-30
-1w7l,2004-09-08,2004-09-06
-1w7c,2006-08-31,2004-09-01
-1w75,2004-11-25,2004-08-29
-7w7e,2022-09-28,2021-12-04
-5w7r,2018-07-04,2017-06-20
-2w7y,2009-03-10,2009-01-06
-8w71,2024-05-22,2023-08-30
-3w7x,2013-07-17,2013-03-08
-4w74,2015-02-18,2014-08-21
-5w7v,2018-03-14,2017-06-20
-7w7u,2022-12-14,2021-12-06
-3w7d,2014-03-05,2013-02-28
-4w7k,2015-03-11,2014-08-22
-5w7m,2018-06-27,2017-06-20
-4w7t,2014-11-26,2014-08-22
-4w7r,2015-03-04,2014-08-22
-3w7k,2014-03-05,2013-02-28
-7w74,2022-02-23,2021-12-03
-1w7h,2005-02-08,2004-09-02
-3w7g,2014-03-05,2013-02-28
-1w76,2004-11-25,2004-08-30
-4w77,2015-02-18,2014-08-21
-3w71,2014-03-05,2013-02-27
-6w72,2020-10-07,2020-03-18
-5w73,2018-01-17,2017-06-19
-4w76,2015-02-18,2014-08-21
-7w77,2022-04-06,2021-12-03
-1w7g,2006-05-24,2004-09-02
-4w7e,2015-02-25,2014-08-21
-3w78,2014-02-12,2013-02-27
-2w73,2009-05-12,2008-12-19
-1w7z,2005-11-01,2004-09-14
-2w71,2009-05-19,2008-12-19
-7w78,2022-06-22,2021-12-04
-8w7s,2023-12-20,2023-08-31
-3w73,2014-03-05,2013-02-27
-3w7m,2014-03-05,2013-03-02
-5w7a,2018-01-03,2017-06-19
-3w7l,2014-03-05,2013-03-02
-3w7f,2013-04-10,2013-02-28
-5w76,2018-04-25,2017-06-19
-5w7n,2017-06-28,2017-06-20
-2w78,2009-05-12,2008-12-20
-5w78,2018-01-03,2017-06-19
-1w7m,2004-09-08,2004-09-06
-4w75,2015-03-04,2014-08-21
-4w78,2014-10-08,2014-08-21
-2w7d,2010-08-18,2008-12-22
-2w7i,2010-08-18,2008-12-22
-2w7m,2010-08-18,2008-12-22
-5w71,2017-07-12,2017-06-19
-6w78,2021-01-20,2020-03-18
-1w78,2005-02-09,2004-08-31
-2w70,2009-05-19,2008-12-19
-5w7o,2017-06-28,2017-06-20
-6w79,2020-08-26,2020-03-18
-2w7p,2009-06-16,2008-12-23
-1w7x,2005-10-25,2004-09-14
-4w7n,2015-03-11,2014-08-22
-4w7o,2015-03-11,2014-08-22
-2w76,2009-05-12,2008-12-20
-7w7j,2022-03-02,2021-12-05
-2w7e,2010-08-18,2008-12-22
-1w7n,2004-09-08,2004-09-06
-5w7q,2018-04-25,2017-06-20
-2w72,2009-04-28,2008-12-19
-8w78,2023-11-29,2023-08-30
-4w7d,2015-03-11,2014-08-21
-6w7c,2021-01-27,2020-03-19
-5w75,2018-04-25,2017-06-19
-7w73,2022-08-03,2021-12-03
-6w7k,2021-03-24,2020-03-19
-3w77,2014-02-12,2013-02-27
-7w7h,2022-09-21,2021-12-04
-7w7o,2023-06-07,2021-12-06
-2w7l,2010-08-18,2008-12-22
-3w7y,2013-07-03,2013-03-11
-1w72,2004-11-09,2004-08-27
-3w7t,2013-04-03,2013-03-06
-8w7h,2024-01-17,2023-08-30
-4w7s,2014-10-29,2014-08-22
-6w7l,2021-03-24,2020-03-19
-4w7f,2015-03-11,2014-08-21
-6w7e,2021-01-27,2020-03-19
-4w7w,2015-10-21,2014-08-22
-1w7i,2005-02-22,2004-09-03
-6w7i,2020-10-07,2020-03-19
-6w7b,2021-01-27,2020-03-19
-4w7l,2015-03-11,2014-08-22
-3w7w,2013-07-17,2013-03-08
-6w7o,2020-11-18,2020-03-19
-2w7x,2009-09-22,2009-01-06
-6w7d,2021-01-27,2020-03-19
-3w74,2014-03-05,2013-02-27
-7w7t,2022-12-14,2021-12-06
-7w7w,2022-12-14,2021-12-06
-5w7k,2018-06-27,2017-06-20
-6w74,2020-11-18,2020-03-18
-2w7h,2010-08-18,2008-12-22
-6w75,2020-03-25,2020-03-18
-7w79,2022-06-22,2021-12-04
-8w7m,2023-12-06,2023-08-30
-6w7g,2020-07-08,2020-03-19
-7w7x,2022-04-27,2021-12-06
-3w7r,2014-03-12,2013-03-06
-2w7o,2009-06-16,2008-12-23
-7w7v,2022-12-14,2021-12-06
-3w72,2014-03-05,2013-02-27
-1w77,2006-02-21,2004-08-30
-3w7c,2014-03-05,2013-02-28
-4w7v,2015-10-21,2014-08-22
-5w7w,2018-05-02,2017-06-21
-4w72,2015-02-18,2014-08-21
-5w7x,2018-05-02,2017-06-21
-8w7d,2023-12-13,2023-08-30
-1w7k,2005-02-09,2004-09-06
-6w7a,2021-02-03,2020-03-18
-7w7f,2022-04-06,2021-12-04
-7w7d,2022-06-22,2021-12-04
-6w70,2020-08-26,2020-03-18
-5w7e,2018-01-03,2017-06-19
-5w7h,2019-01-23,2017-06-19
-5w7y,2018-05-02,2017-06-21
-3w7a,2014-02-12,2013-02-27
-8w75,2023-11-29,2023-08-30
-4w7c,2015-03-04,2014-08-21
-1w73,2004-10-28,2004-08-27
-4w7p,2014-10-15,2014-08-22
-4w7j,2015-03-11,2014-08-22
-3w79,2014-02-12,2013-02-27
-5w7t,2018-06-20,2017-06-20
-5w74,2018-06-20,2017-06-19
-6w7v,2020-10-21,2020-03-19
-3w7h,2014-03-05,2013-02-28
-6w7z,2020-05-20,2020-03-19
-6w73,2021-03-24,2020-03-18
-3w76,2014-03-05,2013-02-27
-1w7q,2005-03-08,2004-09-08
-4w71,2015-05-27,2014-08-21
-1w79,2005-06-28,2004-08-31
-2w7k,2010-08-18,2008-12-22
-6w7j,2021-03-24,2020-03-19
-6w7h,2021-01-13,2020-03-19
-5w7c,2018-01-03,2017-06-19
-6w7f,2020-07-08,2020-03-19
-5w7d,2018-01-03,2017-06-19
-4w7m,2015-03-11,2014-08-22
-2w7f,2010-08-18,2008-12-22
-1w7j,2005-02-22,2004-09-03
-1w7r,2005-03-08,2004-09-08
-2w7g,2010-08-18,2008-12-22
-5w70,2017-07-12,2017-06-19
-5w7b,2018-01-03,2017-06-19
-4w73,2015-02-18,2014-08-21
-3w75,2014-03-05,2013-02-27
-2w7j,2010-08-18,2008-12-22
-3w7o,2014-03-05,2013-03-02
-2w77,2009-05-12,2008-12-20
-3w7j,2014-03-05,2013-02-28
-5w7s,2018-06-27,2017-06-20
-1w7v,2005-09-29,2004-09-13
-7w7g,2022-05-18,2021-12-04
-3w7p,2014-03-05,2013-03-02
-4w7a,2015-02-18,2014-08-21
-7w72,2022-02-16,2021-12-02
-2w7w,2009-02-17,2009-01-06
-1w7a,2004-09-10,2004-08-31
-3w7i,2014-03-05,2013-02-28
-3w7e,2014-03-05,2013-02-28
-7w7y,2022-04-27,2021-12-06
-2iyb,2007-10-16,2006-07-14
-5iyy,2017-04-05,2016-03-24
-2iy2,2007-07-17,2006-07-12
-5iyt,2016-10-05,2016-03-24
-6iyc,2019-01-23,2018-12-14
-6iyh,2019-04-10,2018-12-16
-6iyb,2019-03-13,2018-12-14
-6iym,2019-04-03,2018-12-17
-5iyb,2016-05-18,2016-03-24
-2iyx,2006-10-11,2006-07-22
-5iyw,2017-04-05,2016-03-24
-5iy8,2016-05-18,2016-03-24
-4iy7,2014-01-29,2013-01-28
-8iyu,2024-04-10,2023-04-06
-1iym,2003-07-22,2002-08-30
-8iy7,2024-04-10,2023-04-04
-1iyk,2002-12-30,2002-08-29
-8iy4,2024-04-03,2023-04-03
-6iyv,2019-02-27,2018-12-17
-8iyx,2024-03-20,2023-04-06
-2iyq,2006-10-11,2006-07-21
-5iyz,2016-08-17,2016-03-24
-2iy7,2007-08-21,2006-07-13
-8iye,2024-04-10,2023-04-04
-8iyj,2023-07-05,2023-04-05
-2iya,2007-03-27,2006-07-13
-8iy2,2024-02-07,2023-04-03
-6iyu,2019-05-01,2018-12-17
-5iya,2016-05-18,2016-03-24
-8iyb,2023-10-25,2023-04-04
-2iyl,2007-01-02,2006-07-18
-1iyl,2002-12-30,2002-08-29
-6iyg,2019-12-18,2018-12-15
-2iyn,2006-08-30,2006-07-19
-6iyf,2019-06-19,2018-12-15
-2iyy,2006-10-11,2006-07-22
-2iy8,2007-09-18,2006-07-13
-6iy9,2019-09-11,2018-12-14
-4iyb,2013-11-20,2013-01-28
-2iyu,2006-10-11,2006-07-22
-1iy7,2003-01-28,2002-07-24
-1iyd,2003-05-06,2002-08-07
-8iyh,2024-03-06,2023-04-04
-3iyd,2009-11-10,2009-08-01
-5iyx,2016-04-20,2016-03-24
-6iyk,2019-04-17,2018-12-17
-2iyk,2006-08-30,2006-07-18
-5iy7,2016-05-18,2016-03-24
-6iyl,2019-04-17,2018-12-17
-6iy8,2020-06-10,2018-12-13
-1iyq,2002-12-11,2002-09-04
-1iyx,2003-07-29,2002-09-12
-2iyp,2007-01-23,2006-07-21
-8iyn,2024-04-10,2023-04-05
-8iy0,2024-02-07,2023-04-03
-6iyi,2019-04-10,2018-12-16
-1iyh,2003-04-08,2002-08-26
-8iym,2024-04-10,2023-04-05
-3iyw,2010-11-24,2010-06-18
-6iyx,2019-05-01,2018-12-17
-1iyi,2003-04-08,2002-08-26
-4iy0,2014-03-05,2013-01-28
-8iyo,2024-04-10,2023-04-05
-2iy5,2006-09-06,2006-07-12
-5iyu,2017-04-05,2016-03-24
-1iy8,2003-05-27,2002-07-25
-2iy6,2006-07-24,2006-07-13
-2iyv,2006-10-11,2006-07-22
-2iy4,2007-01-02,2006-07-12
-6iyw,2019-02-27,2018-12-17
-8iyf,2024-04-10,2023-04-04
-5iy0,2016-07-13,2016-03-23
-4iy5,2013-10-09,2013-01-28
-5iyc,2016-05-18,2016-03-24
-5iy6,2016-05-18,2016-03-24
-4iyn,2014-01-22,2013-01-28
-1iyo,2002-12-11,2002-09-04
-1iy1,2002-11-06,2002-07-10
-5iyr,2017-04-05,2016-03-24
-8iyp,2024-04-10,2023-04-05
-1iyp,2002-12-11,2002-09-04
-2iys,2006-10-11,2006-07-21
-4iyg,2014-01-29,2013-01-28
-5iy5,2017-01-11,2016-03-24
-6iy6,2019-09-11,2018-12-13
-5iyv,2016-04-20,2016-03-24
-2iyo,2007-01-23,2006-07-21
-8iys,2023-06-21,2023-04-06
-8iyw,2024-03-06,2023-04-06
-8iy1,2024-02-07,2023-04-03
-1iy0,2002-11-06,2002-07-10
-1iyz,2003-07-15,2002-09-17
-6iy2,2019-04-03,2018-12-12
-8iya,2024-01-03,2023-04-04
-8iyc,2023-10-25,2023-04-04
-2iyi,2006-09-06,2006-07-17
-1iye,2003-05-06,2002-08-07
-2iyf,2007-03-27,2006-07-17
-2iyw,2006-10-18,2006-07-22
-4iym,2013-04-03,2013-01-28
-8iy9,2024-03-06,2023-04-04
-4iyo,2014-01-29,2013-01-29
-1iyb,2003-08-05,2002-08-05
-2iyr,2006-10-11,2006-07-21
-4iyq,2013-02-13,2013-01-29
-6iy1,2019-12-18,2018-12-12
-8iyg,2024-04-10,2023-04-04
-5iyd,2016-05-18,2016-03-24
-5iys,2017-03-29,2016-03-24
-5iyp,2017-04-05,2016-03-24
-8iy8,2023-10-25,2023-04-04
-5iyq,2017-04-05,2016-03-24
-2iyz,2006-10-11,2006-07-22
-6iy3,2019-04-03,2018-12-12
-8iyt,2024-04-10,2023-04-06
-4iy6,2013-10-09,2013-01-28
-1iyn,2003-09-03,2002-09-03
-5iy9,2016-05-18,2016-03-24
-2iyg,2006-09-06,2006-07-17
-7m3i,2021-05-12,2021-03-18
-6m3i,2021-03-03,2020-03-03
-4m3u,2014-02-12,2013-08-06
-7m3y,2021-10-13,2021-03-19
-4m34,2014-03-05,2013-08-06
-6m3y,2020-07-29,2020-03-04
-4m3w,2014-02-12,2013-08-06
-4m38,2014-04-23,2013-08-06
-7m3g,2021-06-30,2021-03-18
-4m3d,2014-06-25,2013-08-06
-4m3m,2014-02-12,2013-08-06
-3m3o,2010-12-01,2010-03-09
-4m30,2013-12-11,2013-08-05
-3m3m,2010-03-16,2010-03-09
-7m3f,2021-06-30,2021-03-18
-3m3e,2010-12-01,2010-03-09
-1m38,2003-01-28,2002-06-27
-3m34,2010-04-28,2010-03-08
-7m30,2021-08-11,2021-03-17
-4m3y,2014-02-12,2013-08-06
-3m3x,2010-10-20,2010-03-10
-7m3q,2021-04-21,2021-03-18
-3m32,2010-09-15,2010-03-08
-3m38,2010-05-12,2010-03-08
-1m34,2003-02-11,2002-06-27
-3m3l,2010-03-23,2010-03-09
-3m3k,2010-03-23,2010-03-09
-7m3z,2021-10-13,2021-03-19
-5m3y,2017-12-20,2016-10-17
-2m3z,2013-02-27,2013-01-28
-5m32,2017-07-05,2016-10-14
-4m3b,2014-06-25,2013-08-06
-6m3x,2020-07-15,2020-03-04
-5m3u,2017-12-20,2016-10-17
-1m3q,2004-02-17,2002-06-28
-5m3e,2016-12-21,2016-10-14
-4m3p,2014-06-18,2013-08-06
-3m35,2010-04-21,2010-03-08
-1m3u,2003-07-22,2002-06-30
-7m31,2021-06-09,2021-03-18
-4m3t,2014-02-12,2013-08-06
-5m36,2017-11-15,2016-10-14
-2m3g,2013-08-21,2013-01-17
-6m32,2020-11-25,2020-03-02
-3m37,2010-04-21,2010-03-08
-5m3k,2017-12-20,2016-10-15
-3m31,2010-11-03,2010-03-08
-5m3w,2017-01-11,2016-10-17
-3m30,2010-09-15,2010-03-08
-5m34,2017-03-01,2016-10-14
-5m35,2017-11-15,2016-10-14
-3m36,2010-04-21,2010-03-08
-3m3q,2010-12-01,2010-03-09
-6m34,2021-02-03,2020-03-02
-6m3b,2020-07-08,2020-03-03
-1m3z,2002-11-29,2002-07-03
-4m37,2014-04-23,2013-08-06
-5m39,2017-09-27,2016-10-14
-1m3d,2003-01-07,2002-06-27
-3m3u,2010-03-23,2010-03-10
-1m3x,2002-08-28,2002-07-01
-3m3d,2011-03-09,2010-03-09
-5m3z,2017-06-28,2016-10-17
-1m35,2003-05-06,2002-06-27
-6m30,2021-02-10,2020-03-02
-4m3x,2014-02-12,2013-08-06
-3m3f,2010-03-23,2010-03-09
-5m3h,2016-12-21,2016-10-14
-7m33,2022-01-05,2021-03-18
-2m30,2013-05-08,2013-01-04
-3m3c,2010-12-01,2010-03-09
-6m38,2021-02-17,2020-03-02
-7m3h,2022-09-21,2021-03-18
-3m3n,2010-07-28,2010-03-09
-7m3t,2021-12-15,2021-03-19
-1m3v,2003-05-13,2002-06-30
-7m3k,2021-04-07,2021-03-18
-6m3v,2020-10-07,2020-03-04
-6m3w,2020-06-03,2020-03-04
-7m3e,2021-06-30,2021-03-18
-6m3z,2021-02-17,2020-03-04
-2m3s,2013-07-24,2013-01-25
-3m3z,2011-01-26,2010-03-10
-4m33,2014-03-05,2013-08-06
-4m3o,2014-07-16,2013-08-06
-4m3h,2014-03-19,2013-08-06
-1m32,2002-11-20,2002-06-26
-3m3a,2010-05-12,2010-03-08
-6m3f,2020-08-12,2020-03-03
-6m35,2020-07-15,2020-03-02
-4m32,2014-03-05,2013-08-06
-1m33,2003-01-21,2002-06-26
-2m33,2013-02-06,2013-01-08
-6m31,2021-02-03,2020-03-02
-5m3s,2016-12-14,2016-10-17
-7m3j,2021-06-30,2021-03-18
-1m36,2004-01-27,2002-06-27
-4m3n,2013-08-28,2013-08-06
-5m37,2017-11-15,2016-10-14
-6m3s,2021-03-10,2020-03-04
-5m3m,2016-11-23,2016-10-15
-5m3b,2017-03-01,2016-10-14
-2m3h,2013-08-07,2013-01-19
-6m39,2020-08-26,2020-03-03
-5m3v,2017-05-10,2016-10-17
-7m3r,2021-12-15,2021-03-18
-4m3q,2013-11-27,2013-08-06
-3m3b,2010-05-12,2010-03-08
-5m3c,2017-12-20,2016-10-14
-6m3t,2020-08-12,2020-03-04
-5m3l,2017-09-13,2016-10-15
-5m3a,2017-09-27,2016-10-14
-1m3w,2003-02-18,2002-07-01
-5m3j,2016-12-21,2016-10-14
-4m3f,2014-06-25,2013-08-06
-7m32,2021-06-09,2021-03-18
-4m3z,2014-02-12,2013-08-06
-4m3r,2014-02-12,2013-08-06
-7m3s,2021-09-22,2021-03-18
-3m3r,2010-05-05,2010-03-09
-3m39,2010-05-12,2010-03-08
-2m32,2013-11-06,2013-01-07
-6m3d,2020-09-16,2020-03-03
-4m3c,2013-09-18,2013-08-06
-4m3e,2014-06-25,2013-08-06
-2m3l,2013-05-15,2013-01-21
-3m3g,2011-02-09,2010-03-09
-4m35,2014-03-05,2013-08-06
-3m3y,2010-05-12,2010-03-10
-4m3g,2014-06-25,2013-08-06
-5m3f,2016-11-23,2016-10-14
-1m3h,2004-04-20,2002-06-27
-4ihp,2014-01-15,2012-12-19
-5ihe,2016-08-31,2016-02-29
-6ihe,2019-02-06,2018-09-29
-4iha,2013-01-23,2012-12-18
-5ihf,2017-03-08,2016-02-29
-3ihj,2009-08-18,2009-07-30
-3iha,2010-01-19,2009-07-29
-2ih4,2007-11-13,2006-09-25
-3ihg,2009-09-29,2009-07-30
-2ihj,2007-05-22,2006-09-26
-8ihs,2023-08-30,2023-02-23
-4ih0,2013-09-04,2012-12-18
-8ihi,2023-08-30,2023-02-22
-5ihh,2016-04-20,2016-02-29
-5ih7,2017-04-05,2016-02-29
-5ih9,2016-06-01,2016-02-29
-8iht,2024-03-20,2023-02-23
-3ihb,2010-01-19,2009-07-29
-6ih7,2019-10-02,2018-09-28
-8ihh,2023-08-30,2023-02-22
-2ihv,2007-09-18,2006-09-27
-5ih5,2016-04-13,2016-02-29
-3ihp,2009-12-29,2009-07-30
-4ihz,2013-07-24,2012-12-19
-1ih0,2001-10-10,2001-04-18
-3iht,2009-08-25,2009-07-30
-6ihu,2019-08-07,2018-10-02
-1ihy,2002-07-31,2001-04-20
-8ihn,2024-03-20,2023-02-23
-2ih5,2007-11-13,2006-09-25
-4ihf,2013-11-13,2012-12-18
-5ih0,2017-04-26,2016-02-28
-2iho,2007-05-22,2006-09-27
-2ihk,2007-05-22,2006-09-26
-4ih6,2013-07-03,2012-12-18
-2ih1,2006-11-21,2006-09-25
-2ihz,2007-05-22,2006-09-27
-8ih7,2024-02-28,2023-02-22
-3ihk,2009-08-25,2009-07-30
-6ihd,2019-02-06,2018-09-29
-5ihk,2017-03-29,2016-02-29
-5ihb,2017-03-29,2016-02-29
-8ihy,2023-12-06,2023-02-24
-2ihq,2006-12-12,2006-09-27
-6ihx,2018-12-12,2018-10-03
-5ihx,2016-04-06,2016-02-29
-2iht,2007-09-18,2006-09-27
-8ihm,2024-03-20,2023-02-23
-4ih7,2013-07-03,2012-12-18
-5ih6,2016-04-13,2016-02-29
-5ihr,2017-04-19,2016-02-29
-4ihb,2013-12-18,2012-12-18
-5ihy,2016-04-27,2016-03-01
-6ihi,2019-10-02,2018-09-30
-6ih6,2019-03-13,2018-09-28
-1ihu,2001-09-12,2001-04-20
-8ihk,2023-08-30,2023-02-22
-1ih8,2001-06-06,2001-04-18
-8ihp,2023-04-12,2023-02-23
-5ihp,2016-03-30,2016-02-29
-4ih8,2014-04-16,2012-12-18
-2ihl,1994-01-31,1993-06-29
-6ihc,2019-04-10,2018-09-29
-5ih1,2017-04-26,2016-02-28
-5ihg,2016-12-07,2016-02-29
-4ihm,2013-12-25,2012-12-19
-6iht,2019-08-07,2018-10-02
-6ihw,2019-08-07,2018-10-02
-2ih3,2006-11-21,2006-09-25
-6ihr,2019-08-07,2018-10-02
-4iho,2013-09-11,2012-12-19
-6ih1,2019-10-02,2018-09-28
-6ihl,2019-08-07,2018-09-30
-4ihh,2013-11-13,2012-12-18
-8ihg,2024-02-28,2023-02-22
-2ih8,2006-11-14,2006-09-26
-6ihk,2019-07-03,2018-09-30
-3ih0,2009-09-08,2009-07-29
-2ih9,2006-11-14,2006-09-26
-4ihj,2013-02-13,2012-12-18
-3ihl,2009-10-13,2009-07-30
-3ihr,2009-08-11,2009-07-30
-4ih3,2014-05-21,2012-12-18
-8ihz,2024-02-28,2023-02-24
-3ihz,2010-06-16,2009-07-31
-1ihx,2002-07-31,2001-04-20
-1ihf,1997-02-12,1996-08-21
-2ihb,2006-11-21,2006-09-26
-1ihj,2001-08-22,2001-04-19
-6ih5,2019-03-13,2018-09-28
-6ih0,2019-01-30,2018-09-27
-4ihg,2013-11-13,2012-12-18
-2ihp,2007-02-13,2006-09-27
-5ih4,2016-04-13,2016-02-29
-3ih5,2009-09-08,2009-07-29
-4ihs,2013-07-10,2012-12-19
-8ihr,2023-08-30,2023-02-23
-6ihs,2019-08-07,2018-10-02
-2ih2,2007-11-13,2006-09-25
-4ihi,2013-12-18,2012-12-18
-8ihj,2023-08-30,2023-02-22
-3ihv,2009-08-11,2009-07-30
-2ihu,2007-11-27,2006-09-27
-5ihn,2017-03-29,2016-02-29
-8iho,2024-01-03,2023-02-23
-6ihv,2019-08-07,2018-10-02
-8ihq,2023-08-30,2023-02-23
-4ihc,2013-01-16,2012-12-18
-5iha,2016-06-01,2016-02-29
-6ih3,2019-03-13,2018-09-28
-8ihw,2023-12-06,2023-02-24
-8ih5,2023-12-06,2023-02-22
-6ihh,2019-10-02,2018-09-30
-5ihj,2016-09-21,2016-02-29
-8ihb,2023-09-13,2023-02-22
-4ih5,2013-07-03,2012-12-18
-4ihl,2013-09-25,2012-12-19
-8ihx,2023-12-06,2023-02-24
-8ihf,2023-08-30,2023-02-22
-2ihx,2007-01-16,2006-09-27
-5ihc,2016-06-01,2016-02-29
-5ih2,2016-06-29,2016-02-28
-1ihi,2001-10-03,2001-04-19
-1ih7,2001-06-13,2001-04-18
-5ih8,2016-06-01,2016-02-29
-2ihm,2006-12-12,2006-09-26
-5ih3,2017-03-29,2016-02-29
-4ihq,2013-03-06,2012-12-19
-8u8k,2024-03-27,2023-09-18
-6u8r,2020-03-25,2019-09-05
-6u8p,2020-06-10,2019-09-05
-6u8a,2019-10-16,2019-09-04
-6u8x,2020-06-10,2019-09-06
-5u8x,2017-05-31,2016-12-15
-3u8i,2012-10-17,2011-10-17
-8u8y,2024-01-31,2023-09-18
-5u82,2017-01-11,2016-12-13
-8u8a,2024-01-31,2023-09-16
-6u8e,2020-03-25,2019-09-04
-1u8c,2004-12-28,2004-08-05
-7u8y,2023-03-15,2022-03-09
-8u8b,2024-01-31,2023-09-16
-8u8o,2024-01-31,2023-09-18
-3u8p,2012-08-29,2011-10-17
-1u8a,2004-10-19,2004-08-05
-1u8l,2004-10-05,2004-08-06
-7u83,2022-05-04,2022-03-07
-3u8t,2012-04-11,2011-10-17
-1u8m,2004-10-05,2004-08-06
-6u8s,2020-03-25,2019-09-05
-1u8g,2004-11-02,2004-08-06
-5u81,2018-03-28,2016-12-13
-1u8v,2004-12-21,2004-08-07
-8u87,2024-05-01,2023-09-16
-1u8z,2004-11-23,2004-08-09
-6u8t,2020-09-09,2019-09-05
-8u8j,2024-03-27,2023-09-18
-5u8v,2017-02-15,2016-12-15
-4u82,2015-02-04,2014-07-31
-3u8u,2011-10-26,2011-10-17
-5u8l,2017-01-25,2016-12-14
-1u88,2005-02-22,2004-08-05
-4u8i,2014-12-03,2014-08-03
-8u8t,2023-11-15,2023-09-18
-8u8m,2024-04-03,2023-09-18
-4u8l,2014-12-03,2014-08-03
-1u8b,2005-10-11,2004-08-05
-4u8v,2014-10-15,2014-08-04
-7u8w,2023-08-16,2022-03-09
-3u8n,2011-12-14,2011-10-17
-4u8o,2014-12-03,2014-08-03
-4u8j,2014-12-03,2014-08-03
-1u8k,2004-10-05,2004-08-06
-3u8b,2012-10-17,2011-10-16
-5u8h,2017-04-26,2016-12-14
-7u8r,2022-07-06,2022-03-09
-3u8e,2011-10-26,2011-10-17
-4u87,2015-08-26,2014-08-01
-8u8s,2023-11-15,2023-09-18
-1u8j,2004-10-05,2004-08-06
-1u86,2005-08-23,2004-08-05
-4u8d,2015-08-26,2014-08-02
-7u8z,2022-11-23,2022-03-09
-6u8q,2020-02-05,2019-09-05
-7u8q,2022-07-06,2022-03-09
-3u8v,2011-11-09,2011-10-17
-5u8p,2017-02-15,2016-12-14
-1u8i,2004-10-05,2004-08-06
-1u8y,2004-11-23,2004-08-09
-1u8o,2004-10-05,2004-08-06
-1u80,2004-11-30,2004-08-04
-1u8x,2004-08-24,2004-08-09
-5u8q,2018-02-28,2016-12-14
-5u8r,2018-02-28,2016-12-14
-4u8h,2014-10-01,2014-08-03
-6u88,2019-10-16,2019-09-04
-4u8z,2015-03-18,2014-08-05
-1u8u,2005-04-05,2004-08-07
-4u8k,2014-12-03,2014-08-03
-1u85,2005-08-23,2004-08-05
-3u8f,2011-11-16,2011-10-17
-5u8u,2017-02-15,2016-12-15
-7u8f,2023-03-08,2022-03-08
-5u8i,2017-04-26,2016-12-14
-4u89,2015-08-26,2014-08-01
-6u8b,2019-12-04,2019-09-04
-7u8g,2022-10-26,2022-03-08
-4u8t,2014-09-10,2014-08-04
-3u8x,2012-01-25,2011-10-17
-5u8o,2017-01-25,2016-12-14
-5u8e,2017-08-30,2016-12-14
-7u82,2022-05-04,2022-03-07
-6u8w,2020-06-10,2019-09-06
-3u8w,2012-08-29,2011-10-17
-5u83,2017-01-11,2016-12-13
-4u8w,2014-11-05,2014-08-05
-7u8v,2023-08-16,2022-03-09
-6u83,2019-09-18,2019-09-04
-3u8l,2011-12-14,2011-10-17
-5u8y,2017-05-31,2016-12-15
-1u81,2004-10-05,2004-08-04
-6u8v,2020-06-10,2019-09-06
-3u8m,2011-12-14,2011-10-17
-1u8f,2005-08-16,2004-08-05
-5u86,2017-08-09,2016-12-13
-3u85,2012-02-15,2011-10-15
-1u87,2005-02-22,2004-08-05
-7u8u,2023-08-16,2022-03-09
-4u80,2014-09-24,2014-07-31
-7u8s,2023-03-22,2022-03-09
-6u8g,2020-08-19,2019-09-05
-8u8w,2023-09-27,2023-09-18
-8u86,2024-05-01,2023-09-15
-4u8m,2014-12-03,2014-08-03
-3u8q,2011-11-16,2011-10-17
-5u8z,2017-05-31,2016-12-15
-5u8f,2017-03-15,2016-12-14
-5u84,2018-03-28,2016-12-13
-3u8d,2012-10-17,2011-10-16
-5u8s,2017-01-25,2016-12-14
-5u89,2017-05-10,2016-12-14
-4u81,2014-09-24,2014-07-31
-7u8d,2022-09-21,2022-03-08
-8u8l,2024-04-03,2023-09-18
-3u81,2012-02-01,2011-10-15
-6u80,2019-12-04,2019-09-04
-4u8u,2015-06-10,2014-08-04
-1u8r,2004-10-05,2004-08-06
-7u80,2022-05-04,2022-03-07
-8u8q,2023-11-15,2023-09-18
-5u8g,2017-04-26,2016-12-14
-8u85,2024-05-01,2023-09-15
-1u8e,2004-08-17,2004-08-05
-3u8o,2012-05-23,2011-10-17
-7u8x,2023-08-16,2022-03-09
-6u8l,2019-12-04,2019-09-05
-8u89,2024-01-10,2023-09-16
-6u8h,2020-08-19,2019-09-05
-7u84,2022-05-04,2022-03-07
-3u8j,2011-12-14,2011-10-17
-6u8m,2020-08-19,2019-09-05
-1u8h,2004-10-05,2004-08-06
-3u88,2012-02-15,2011-10-16
-5u8w,2017-02-15,2016-12-15
-6u8n,2020-03-25,2019-09-05
-3u8g,2011-11-02,2011-10-17
-4u8n,2014-12-03,2014-08-03
-6u87,2020-09-09,2019-09-04
-4u8y,2014-10-15,2014-08-05
-7u81,2022-05-04,2022-03-07
-5u88,2017-01-11,2016-12-14
-5u8t,2017-02-08,2016-12-15
-4u8p,2014-12-03,2014-08-03
-1u8p,2004-10-05,2004-08-06
-1u8n,2004-10-05,2004-08-06
-7u8h,2022-11-09,2022-03-08
-3u8k,2011-12-14,2011-10-17
-6u8i,2020-08-19,2019-09-05
-3u87,2012-05-30,2011-10-16
-3u8r,2012-05-23,2011-10-17
-3u8h,2012-10-17,2011-10-17
-5u8a,2017-03-15,2016-12-14
-1u8q,2004-10-05,2004-08-06
-5u8c,2017-05-17,2016-12-14
-7u8p,2022-07-06,2022-03-09
-6u8o,2019-12-04,2019-09-05
-7u8e,2023-03-15,2022-03-08
-1ee4,2000-03-29,2000-01-30
-4eep,2012-05-16,2012-03-28
-5ee5,2016-07-06,2015-10-22
-5ee4,2015-11-04,2015-10-22
-4eec,2012-07-04,2012-03-28
-5ee9,2016-02-24,2015-10-22
-5ees,2015-11-11,2015-10-23
-6ee8,2018-11-21,2018-08-13
-4eeu,2012-05-16,2012-03-28
-8eeb,2022-12-21,2022-09-06
-5ee7,2016-04-20,2015-10-22
-8ee4,2024-01-03,2022-09-06
-1ee9,2000-12-06,2000-01-31
-7eev,2021-07-28,2021-03-19
-4ee4,2012-07-04,2012-03-28
-1ee6,2001-01-31,2000-01-31
-4eeb,2012-11-14,2012-03-28
-6ee1,2019-08-14,2018-08-12
-5een,2016-07-27,2015-10-23
-3eel,2009-08-18,2008-09-04
-5eec,2016-02-03,2015-10-22
-7ee4,2021-12-22,2021-03-17
-8eej,2023-02-01,2022-09-07
-8eem,2023-02-01,2022-09-07
-3ee2,2008-09-16,2008-09-04
-5eez,2016-05-04,2015-10-23
-5eeo,2015-11-25,2015-10-23
-4eeg,2012-07-04,2012-03-28
-4een,2012-04-18,2012-03-28
-1ee1,2001-06-06,2000-01-28
-5eeq,2016-06-15,2015-10-23
-2eep,2008-02-19,2007-02-16
-6eet,2019-08-21,2018-08-15
-4eek,2012-04-18,2012-03-28
-1eem,2000-08-11,2000-02-01
-6ee6,2018-12-26,2018-08-13
-1eei,2000-02-16,2000-01-31
-4ee3,2012-07-04,2012-03-28
-1een,2001-02-01,2000-02-01
-3ee5,2009-01-06,2008-09-04
-7eew,2022-03-23,2021-03-19
-5eeg,2015-12-23,2015-10-22
-3eed,2008-09-16,2008-09-04
-1eex,2001-02-07,2000-02-04
-5eei,2016-07-27,2015-10-22
-4eeh,2012-06-27,2012-03-28
-3eeb,2008-10-21,2008-09-04
-8ee7,2024-01-03,2022-09-06
-4ee1,2012-07-25,2012-03-28
-8eeh,2023-02-01,2022-09-07
-4eeo,2012-07-04,2012-03-28
-5eeu,2016-05-04,2015-10-23
-4eel,2012-04-18,2012-03-28
-4eey,2012-05-09,2012-03-28
-6eem,2018-09-19,2018-08-14
-6eel,2019-05-22,2018-08-14
-4eeq,2013-04-03,2012-03-28
-4ee5,2012-07-04,2012-03-28
-3eei,2009-09-08,2008-09-04
-6een,2019-08-21,2018-08-15
-5eev,2016-05-04,2015-10-23
-6ee4,2018-12-26,2018-08-13
-7eer,2022-05-25,2021-03-19
-1eez,2003-06-10,2000-02-04
-4eex,2012-09-26,2012-03-28
-4ee0,2012-07-18,2012-03-28
-8eek,2023-02-01,2022-09-07
-1ee3,2002-06-26,2000-01-30
-5eef,2016-07-27,2015-10-22
-6ee2,2018-12-26,2018-08-13
-8eea,2023-12-27,2022-09-06
-1ee0,2001-01-31,2000-01-28
-7eej,2022-03-23,2021-03-18
-4eed,2012-11-14,2012-03-28
-3eec,2009-03-10,2008-09-04
-8ee5,2023-08-30,2022-09-06
-8ee3,2023-09-13,2022-09-06
-1ee2,2000-10-27,2000-01-30
-7eek,2022-03-23,2021-03-18
-4eem,2012-07-04,2012-03-28
-6eec,2018-11-21,2018-08-13
-4eez,2012-09-26,2012-03-28
-6eea,2018-11-28,2018-08-13
-4eev,2013-04-10,2012-03-28
-8eel,2023-02-01,2022-09-07
-6eeg,2018-08-29,2018-08-14
-5ee3,2016-02-24,2015-10-22
-3eej,2009-08-18,2008-09-04
-7eee,2022-03-23,2021-03-18
-4ee2,2012-10-24,2012-03-28
-8eer,2023-09-20,2022-09-07
-2eeo,2008-02-19,2007-02-16
-2eek,2008-02-19,2007-02-15
-3eer,2008-10-21,2008-09-05
-4ees,2012-05-16,2012-03-28
-1ee8,2001-01-31,2000-01-31
-5ee8,2016-01-27,2015-10-22
-1eey,2003-06-10,2000-02-04
-5eeh,2015-12-16,2015-10-22
-8eex,2022-11-16,2022-09-07
-5eem,2016-07-27,2015-10-23
-8eew,2023-06-28,2022-09-07
-7eez,2021-06-30,2021-03-20
-7eeu,2022-06-22,2021-03-19
-4eet,2012-05-16,2012-03-28
-7ee5,2021-12-22,2021-03-17
-5eey,2016-05-04,2015-10-23
-7eeb,2021-07-28,2021-03-18
-6ee3,2018-12-26,2018-08-13
-1eef,2000-02-16,2000-01-31
-4eer,2012-05-16,2012-03-28
-4eea,2012-07-04,2012-03-28
-6eej,2019-08-14,2018-08-14
-3eef,2008-09-16,2008-09-04
-4eef,2012-06-27,2012-03-28
-3ee4,2009-04-07,2008-09-04
-7eeh,2021-05-26,2021-03-18
-2eer,2007-08-21,2007-02-17
-3ee3,2009-06-16,2008-09-04
-5eex,2016-05-04,2015-10-23
-6eev,2018-09-26,2018-08-15
-4eei,2012-04-18,2012-03-28
-8eei,2023-02-01,2022-09-07
-4ee6,2012-11-14,2012-03-28
-4eej,2012-12-26,2012-03-28
-6eew,2018-09-19,2018-08-15
-2eex,2007-09-18,2007-02-19
-8eef,2023-02-01,2022-09-07
-5eet,2016-10-19,2015-10-23
-6eee,2018-12-26,2018-08-13
-1eeo,2001-02-01,2000-02-01
-3eek,2009-08-18,2008-09-04
-6eeo,2018-11-28,2018-08-15
-1eeh,2001-01-17,2000-01-31
-2eeq,2007-08-21,2007-02-16
-6eei,2018-09-19,2018-08-14
-6eeh,2018-11-28,2018-08-14
-8een,2023-02-01,2022-09-07
-8eeg,2023-02-01,2022-09-07
-3eem,2009-08-18,2008-09-04
-6ee7,2019-08-14,2018-08-13
-3eee,2008-11-25,2008-09-04
-8eeo,2023-02-01,2022-09-07
-5eew,2016-05-04,2015-10-23
-3eey,2008-09-16,2008-09-06
-8eey,2022-11-16,2022-09-07
-1eed,1994-01-31,1992-06-15
-6eeb,2019-08-07,2018-08-13
-6eer,2019-01-16,2018-08-15
-1eet,2001-02-07,2000-02-03
-5eek,2016-07-27,2015-10-23
-5eel,2016-06-15,2015-10-23
-8ee6,2022-12-21,2022-09-06
-3eeo,2010-03-02,2008-09-05
-6eep,2018-08-29,2018-08-15
-3ee6,2008-11-25,2008-09-04
-6eed,2018-12-26,2018-08-13
-2ee8,2007-08-21,2007-02-15
-2rlc,2009-02-17,2007-10-18
-7rl2,2021-10-06,2021-07-23
-5rl0,2020-12-02,2020-08-05
-3rl5,2011-08-10,2011-04-19
-4rl7,2015-03-11,2014-10-16
-7rle,2022-08-03,2021-07-23
-4rl3,2015-10-14,2014-10-15
-4rla,1998-05-13,1997-05-07
-5rlm,2020-09-30,2020-09-16
-4rlg,2014-10-29,2014-10-16
-3rl1,2012-02-29,2011-04-19
-6rl6,2020-06-17,2019-05-01
-6rla,2019-08-28,2019-05-01
-7rlf,2021-09-22,2021-07-23
-3rlw,2012-04-25,2011-04-20
-5rla,1998-05-13,1997-05-07
-5rlg,2020-09-30,2020-09-16
-5rly,2020-09-30,2020-09-16
-5rl4,2020-12-02,2020-08-05
-1rlj,2004-07-13,2003-11-25
-5rlb,2020-09-30,2020-09-16
-2rly,2007-11-06,2007-09-03
-6rln,2019-07-03,2019-05-02
-6rl4,2020-06-17,2019-05-01
-7rla,2021-09-22,2021-07-23
-3rlg,2011-08-24,2011-04-19
-3rl4,2011-08-10,2011-04-19
-6rl0,2019-06-26,2019-04-30
-4rl2,2014-11-19,2014-10-15
-3rll,2011-05-04,2011-04-19
-1rlc,1993-10-31,1993-08-04
-5rl3,2020-12-02,2020-08-05
-5rl2,2020-12-02,2020-08-05
-5rll,2020-09-30,2020-09-16
-3rl3,2011-08-10,2011-04-19
-7rlt,2022-01-12,2021-07-26
-1rl9,2004-05-25,2003-11-25
-3rlr,2011-06-08,2011-04-20
-5rli,2020-09-30,2020-09-16
-5rl7,2020-09-30,2020-09-16
-1rl4,2003-12-09,2003-11-24
-5rlh,2020-09-30,2020-09-16
-3rlu,2012-04-25,2011-04-20
-4rls,2014-11-12,2014-10-17
-7rlh,2021-09-22,2021-07-23
-7rl6,2021-09-22,2021-07-23
-5rle,2020-09-30,2020-09-16
-4rl6,2014-11-05,2014-10-15
-4rli,2015-11-04,2014-10-17
-5rl5,2020-12-02,2020-08-05
-4rlh,2015-12-09,2014-10-17
-3rlp,2011-06-08,2011-04-20
-5rlf,2020-09-30,2020-09-16
-7rl1,2021-09-08,2021-07-23
-2rla,1998-05-13,1997-05-07
-6rlv,2020-01-08,2019-05-02
-6rle,2020-01-29,2019-05-02
-4rlu,2015-10-21,2014-10-18
-6rlu,2020-01-08,2019-05-02
-5rlo,2020-09-30,2020-09-16
-7rld,2021-09-22,2021-07-23
-1rlm,2004-12-07,2003-11-26
-1rlb,1996-04-11,1995-02-20
-5rlt,2020-09-30,2020-09-16
-5rl6,2020-09-30,2020-09-16
-5rlc,2020-09-30,2020-09-16
-1rlu,2004-08-31,2003-11-26
-1rla,1997-10-15,1996-08-15
-2rl9,2008-02-12,2007-10-18
-4rl0,2014-11-19,2014-10-14
-6rlc,2021-02-03,2019-05-02
-6rlw,2020-07-22,2019-05-03
-4rlo,2015-01-21,2014-10-17
-6rlz,2020-03-18,2019-05-03
-7rll,2021-08-11,2021-07-25
-3rla,1998-05-13,1997-05-07
-3rl9,2011-05-11,2011-04-19
-3rlm,2011-10-05,2011-04-19
-3rlj,2011-05-04,2011-04-19
-7rl7,2021-09-22,2021-07-23
-5rlv,2020-09-30,2020-09-16
-3rlv,2012-04-25,2011-04-20
-2rlb,2008-02-12,2007-10-18
-2rl5,2008-04-08,2007-10-18
-6rl1,2020-04-15,2019-05-01
-3rly,2012-04-25,2011-04-20
-4rlw,2015-10-21,2014-10-18
-1rlz,2004-07-13,2003-11-26
-4rlf,2015-09-30,2014-10-16
-2rl8,2008-02-12,2007-10-18
-2rl2,2008-03-25,2007-10-18
-7rlk,2022-08-03,2021-07-25
-3rl8,2011-12-14,2011-04-19
-3rlf,2011-08-10,2011-04-19
-5rld,2020-09-30,2020-09-16
-6rlo,2021-05-12,2019-05-02
-6rlg,2019-08-14,2019-05-02
-5rlu,2020-09-30,2020-09-16
-7rl5,2021-11-24,2021-07-23
-5rlp,2020-09-30,2020-09-16
-3rl7,2011-12-14,2011-04-19
-4rlk,2014-12-17,2014-10-17
-6rl9,2020-04-15,2019-05-01
-1rlh,2004-05-04,2003-11-25
-1rlw,1998-02-25,1997-10-28
-5rlj,2020-09-30,2020-09-16
-5rlq,2020-09-30,2020-09-16
-4rlt,2015-10-21,2014-10-18
-3rlb,2011-06-29,2011-04-19
-1rly,2004-05-25,2003-11-26
-4rlp,2015-01-21,2014-10-17
-1rlt,2004-12-07,2003-11-26
-7rl9,2021-09-22,2021-07-23
-5rlw,2020-09-30,2020-09-16
-7rlb,2021-09-22,2021-07-23
-7rlg,2021-09-22,2021-07-23
-5rlz,2020-09-30,2020-09-16
-7rls,2021-11-10,2021-07-26
-5rln,2020-09-30,2020-09-16
-2rl1,2008-03-25,2007-10-18
-4rlq,2015-09-30,2014-10-17
-5rl1,2020-12-02,2020-08-05
-6rlt,2020-01-08,2019-05-02
-5rl9,2020-09-30,2020-09-16
-3rlq,2011-06-08,2011-04-20
-1rl8,2005-04-19,2003-11-25
-6rlp,2022-11-23,2019-05-02
-2rl7,2008-02-12,2007-10-18
-2rli,2007-08-28,2007-07-11
-1rlo,2004-12-07,2003-11-26
-1rl3,2004-07-06,2003-11-24
-7rlr,2021-08-11,2021-07-26
-7rli,2021-09-22,2021-07-23
-1rls,1994-12-20,1994-03-29
-6rly,2020-03-11,2019-05-03
-2rlf,2008-01-29,2007-07-11
-6rl3,2020-06-17,2019-05-01
-5rlr,2020-09-30,2020-09-16
-5rls,2020-09-30,2020-09-16
-7rlj,2021-09-22,2021-07-23
-6rlq,2020-07-15,2019-05-02
-3rlz,2012-04-25,2011-04-20
-3rlh,2011-06-29,2011-04-19
-6rll,2020-06-03,2019-05-02
-4rll,2014-12-17,2014-10-17
-1rli,2004-04-13,2003-11-25
-7rlc,2021-09-22,2021-07-23
-2rld,2007-10-30,2007-10-18
-4rle,2014-12-03,2014-10-16
-5rlk,2020-09-30,2020-09-16
-5rl8,2020-09-30,2020-09-16
-4rlr,2015-04-01,2014-10-17
-7rlu,2022-01-12,2021-07-26
-3rl6,2011-08-17,2011-04-19
-7rl0,2021-11-24,2021-07-22
-6rl2,2020-04-15,2019-05-01
-4rld,2015-10-21,2014-10-16
-3rld,2012-02-08,2011-04-19
-6rl5,2020-03-11,2019-05-01
-1omj,2003-07-15,2003-02-25
-2om2,2007-07-10,2007-01-20
-7om1,2021-12-08,2021-05-21
-8omo,2023-05-24,2023-03-31
-3omk,2011-01-19,2010-08-27
-7omu,2021-06-23,2021-05-24
-4om8,2015-01-28,2014-01-27
-8omx,2023-12-06,2023-03-31
-3ome,2010-09-15,2010-08-26
-8omt,2023-06-07,2023-03-31
-1omr,2003-11-25,2003-02-26
-7oml,2021-10-27,2021-05-24
-2omu,2007-08-28,2007-01-23
-5om2,2018-05-23,2017-07-28
-8omr,2023-12-20,2023-03-31
-1om5,2003-03-11,2003-02-24
-5omi,2018-08-29,2017-07-31
-8omh,2024-04-10,2023-03-31
-7omb,2021-10-13,2021-05-21
-6om6,2021-02-10,2019-04-18
-8omy,2023-12-06,2023-03-31
-8ome,2023-09-27,2023-03-31
-8om9,2023-05-24,2023-03-31
-4omc,2014-04-09,2014-01-27
-7om0,2022-07-13,2021-05-21
-6om2,2019-12-11,2019-04-17
-3omu,2010-10-27,2010-08-27
-2omt,2007-08-28,2007-01-23
-7om4,2022-03-02,2021-05-21
-8omi,2024-01-10,2023-03-31
-5omr,2018-07-04,2017-08-01
-2om6,2008-01-29,2007-01-21
-7omj,2022-03-02,2021-05-24
-3omm,2011-01-19,2010-08-27
-5omy,2017-12-27,2017-08-02
-4om0,2014-09-03,2014-01-25
-2omp,2007-01-30,2007-01-22
-8om8,2023-06-07,2023-03-31
-3om3,2011-02-02,2010-08-26
-4oma,2014-11-26,2014-01-27
-2omy,2007-06-05,2007-01-23
-4omg,2014-06-04,2014-01-27
-6oml,2019-05-15,2019-04-18
-8omd,2023-09-27,2023-03-31
-7omy,2021-06-23,2021-05-24
-8om4,2024-01-10,2023-03-31
-1om0,2003-06-03,2003-02-24
-5omh,2019-03-13,2017-07-31
-7omw,2021-06-23,2021-05-24
-4omf,2014-06-11,2014-01-27
-8om2,2024-01-10,2023-03-31
-7omr,2022-06-01,2021-05-24
-3omp,2011-03-16,2010-08-27
-5omf,2017-12-20,2017-07-31
-4omo,2014-12-10,2014-01-27
-6ome,2019-05-01,2019-04-18
-7omf,2021-08-04,2021-05-21
-5ome,2018-09-05,2017-07-31
-3omy,2011-05-25,2010-08-27
-4omj,2015-04-15,2014-01-27
-4omr,2014-04-02,2014-01-27
-6omv,2019-06-12,2019-04-19
-8omf,2023-09-27,2023-03-31
-3om2,2011-03-23,2010-08-26
-5oml,2019-03-06,2017-08-01
-3omh,2011-06-29,2010-08-26
-6omq,2019-07-24,2019-04-19
-2om9,2007-04-24,2007-01-21
-6omn,2019-05-08,2019-04-19
-3omq,2011-03-16,2010-08-27
-2ome,2007-02-06,2007-01-22
-5omg,2019-03-13,2017-07-31
-3om6,2011-03-23,2010-08-26
-3omf,2010-09-08,2010-08-26
-6omb,2019-07-17,2019-04-18
-3omn,2011-02-02,2010-08-27
-3om4,2011-03-23,2010-08-26
-6om4,2019-05-22,2019-04-18
-5om9,2017-08-09,2017-07-28
-8omq,2023-05-24,2023-03-31
-8om1,2023-08-09,2023-03-31
-2omv,2007-06-05,2007-01-23
-7ome,2022-06-01,2021-05-21
-1om6,2003-07-15,2003-02-25
-2omh,2007-03-27,2007-01-22
-1omv,2003-11-25,2003-02-26
-6omg,2020-04-22,2019-04-18
-2omg,2007-03-27,2007-01-22
-3omi,2011-02-02,2010-08-27
-2omi,2007-03-27,2007-01-22
-7omc,2021-12-08,2021-05-21
-3omc,2010-09-15,2010-08-26
-5omv,2017-12-20,2017-08-01
-4omb,2014-12-10,2014-01-27
-3om7,2011-03-23,2010-08-26
-5omj,2018-01-03,2017-07-31
-8omk,2024-01-10,2023-03-31
-3om9,2010-10-27,2010-08-26
-7om7,2021-07-28,2021-05-21
-3om0,2010-11-03,2010-08-26
-3om1,2010-11-03,2010-08-26
-7omz,2021-06-23,2021-05-24
-1omo,2004-07-06,2003-02-25
-8omc,2024-04-10,2023-03-31
-5om8,2018-05-23,2017-07-28
-1om7,2003-07-15,2003-02-25
-8omm,2023-05-03,2023-03-31
-4om1,2014-09-03,2014-01-25
-2omm,2007-01-30,2007-01-22
-6om8,2019-05-22,2019-04-18
-3oma,2011-02-02,2010-08-26
-4omh,2014-06-04,2014-01-27
-5om1,2018-01-17,2017-07-28
-3omg,2010-09-08,2010-08-26
-7omd,2022-06-01,2021-05-21
-5om3,2018-05-23,2017-07-28
-7om5,2022-03-02,2021-05-21
-2omq,2007-01-30,2007-01-22
-5om7,2018-05-23,2017-07-28
-8om3,2024-01-10,2023-03-31
-2om0,2007-12-04,2007-01-20
-7omx,2021-06-23,2021-05-24
-5oms,2018-07-04,2017-08-01
-3om5,2011-03-23,2010-08-26
-7omp,2022-03-02,2021-05-24
-6omm,2020-02-26,2019-04-19
-3omv,2010-09-15,2010-08-27
-8oma,2023-05-24,2023-03-31
-7omt,2022-05-04,2021-05-24
-5om4,2018-01-17,2017-07-28
-5omk,2018-01-03,2017-07-31
-7oms,2022-02-02,2021-05-24
-1om8,2003-07-15,2003-02-25
-1om4,2003-03-11,2003-02-24
-6omr,2019-07-24,2019-04-19
-5omo,2017-09-06,2017-08-01
-7omg,2021-10-13,2021-05-22
-2om3,2007-10-16,2007-01-20
-6omz,2019-05-08,2019-04-19
-2om1,2007-12-04,2007-01-20
-5omw,2017-11-15,2017-08-02
-7omo,2022-06-01,2021-05-24
-7oma,2021-07-28,2021-05-21
-6omp,2019-07-24,2019-04-19
-6om1,2019-12-11,2019-04-17
-6omu,2019-08-14,2019-04-19
-7omi,2022-02-02,2021-05-24
-5omx,2017-11-15,2017-08-02
-6omk,2019-05-01,2019-04-18
-1om1,2004-02-24,2003-02-24
-7omq,2022-03-02,2021-05-24
-7om6,2021-07-28,2021-05-21
-8omb,2024-04-10,2023-03-31
-6om0,2019-06-19,2019-04-17
-6om7,2019-06-19,2019-04-18
-6omf,2019-08-28,2019-04-18
-6om5,2019-12-04,2019-04-18
-2omd,2008-01-29,2007-01-22
-5omq,2017-12-20,2017-08-01
-8om5,2023-05-24,2023-03-31
-8omz,2024-04-10,2023-03-31
-3omo,2011-03-16,2010-08-27
-8omp,2024-04-10,2023-03-31
-4omw,2014-11-19,2014-01-27
-5omu,2018-07-04,2017-08-01
-3omb,2010-09-08,2010-08-26
-4omd,2014-04-09,2014-01-27
-8om7,2024-04-10,2023-03-31
-6oms,2019-10-09,2019-04-19
-6omo,2019-05-08,2019-04-19
-1omz,2003-04-22,2003-02-26
-2omx,2007-08-28,2007-01-23
-7om2,2021-07-28,2021-05-21
-1omd,1991-07-15,1990-04-19
-4jiq,2013-05-08,2013-03-06
-8ji7,2023-11-15,2023-05-26
-1ji5,2002-06-19,2001-06-29
-8ji2,2023-11-15,2023-05-26
-6jij,2019-04-24,2019-02-21
-8jiz,2024-06-05,2023-05-29
-5jiz,2017-05-03,2016-04-22
-7jih,2022-03-02,2020-07-23
-8ji6,2023-11-15,2023-05-26
-4ji2,2013-11-06,2013-03-05
-4ji7,2013-11-06,2013-03-05
-6jid,2019-06-05,2019-02-20
-2jiv,2008-01-22,2007-07-02
-6ji8,2019-07-17,2019-02-20
-8jia,2023-10-04,2023-05-26
-1jio,2001-10-17,2001-07-02
-1jiw,2001-08-15,2001-07-03
-6jib,2019-06-05,2019-02-20
-2ji7,2007-07-17,2007-02-26
-5jix,2017-05-03,2016-04-22
-4jih,2013-10-23,2013-03-06
-6ji2,2019-11-13,2019-02-20
-4ji9,2013-08-07,2013-03-05
-1jia,1998-06-10,1997-06-09
-5ji6,2016-05-25,2016-04-21
-8ji8,2023-11-01,2023-05-26
-8jik,2024-05-29,2023-05-26
-8jiw,2024-03-27,2023-05-28
-4jij,2014-03-12,2013-03-06
-4ji5,2013-11-06,2013-03-05
-6jiu,2019-07-17,2019-02-23
-5jil,2016-05-11,2016-04-22
-5jin,2016-07-06,2016-04-22
-1jiz,2002-07-03,2001-07-03
-7jiw,2020-08-05,2020-07-23
-2jis,2007-08-28,2007-06-30
-7jiv,2020-08-05,2020-07-23
-5ji2,2016-11-30,2016-04-21
-2ji2,2007-05-01,2007-02-24
-6jig,2020-02-26,2019-02-21
-6ji6,2019-03-20,2019-02-20
-1jim,1994-01-31,1993-03-19
-6jii,2019-07-17,2019-02-21
-2jir,2008-03-18,2007-06-28
-6ji5,2020-02-26,2019-02-20
-5jim,2016-10-05,2016-04-22
-4jin,2013-04-24,2013-03-06
-6ji3,2020-02-26,2019-02-20
-6jio,2019-10-16,2019-02-22
-7ji4,2021-05-26,2020-07-22
-4jip,2013-05-08,2013-03-06
-1ji2,2002-06-05,2001-06-28
-4ji3,2013-11-06,2013-03-05
-6jis,2019-10-16,2019-02-23
-2ji6,2007-07-17,2007-02-26
-6jiq,2019-11-27,2019-02-22
-4jit,2014-12-24,2013-03-07
-2jiy,2007-09-04,2007-07-03
-6jik,2020-09-02,2019-02-22
-2jin,2007-07-10,2007-06-28
-5jic,2016-08-10,2016-04-22
-1jix,2001-08-15,2001-07-03
-6jia,2019-05-15,2019-02-20
-4ji4,2013-11-06,2013-03-05
-2jig,2007-10-30,2007-06-28
-7jij,2021-07-28,2020-07-23
-8jij,2024-05-29,2023-05-26
-7jib,2020-08-26,2020-07-23
-6jip,2019-11-27,2019-02-22
-2jie,2007-07-03,2007-02-28
-8jil,2023-09-06,2023-05-26
-4jix,2013-06-12,2013-03-07
-2ji3,2007-05-01,2007-02-24
-4ji8,2013-11-06,2013-03-05
-5jio,2017-05-10,2016-04-22
-5jih,2017-04-12,2016-04-22
-6jix,2020-01-01,2019-02-23
-2ji5,2007-10-16,2007-02-26
-1jiv,2001-08-15,2001-07-03
-8ji5,2023-11-15,2023-05-26
-6jif,2020-01-01,2019-02-21
-1jip,2001-10-17,2001-07-02
-1jin,2001-10-17,2001-07-02
-7jif,2022-03-02,2020-07-23
-8jiv,2024-03-27,2023-05-28
-1ji3,2002-11-01,2001-06-29
-4jii,2013-10-23,2013-03-06
-7jir,2020-08-05,2020-07-23
-7jix,2021-07-28,2020-07-23
-5jig,2016-11-09,2016-04-22
-1jiu,2001-08-15,2001-07-03
-4jie,2013-10-09,2013-03-05
-5ji3,2016-12-07,2016-04-21
-1jib,2001-07-25,2001-07-02
-2ji8,2007-07-17,2007-02-26
-7jiu,2021-06-30,2020-07-23
-2jib,2007-07-17,2007-02-26
-4jiv,2013-08-14,2013-03-07
-7jii,2022-03-02,2020-07-23
-7jig,2022-03-02,2020-07-23
-1ji0,2002-08-14,2001-06-28
-8jif,2024-01-31,2023-05-26
-4jib,2013-05-01,2013-03-05
-5jif,2016-05-11,2016-04-22
-4jir,2013-10-23,2013-03-06
-8jib,2023-11-29,2023-05-26
-7jid,2020-08-26,2020-07-23
-5jid,2016-10-05,2016-04-22
-6jie,2019-12-11,2019-02-20
-5ji0,2017-04-26,2016-04-21
-1ji9,2001-10-03,2001-07-01
-4jik,2013-04-17,2013-03-06
-5jiy,2016-09-14,2016-04-22
-5jiu,2016-11-09,2016-04-22
-6jim,2019-04-10,2019-02-22
-2jiw,2007-08-07,2007-07-02
-8ji3,2023-11-15,2023-05-26
-7ji0,2020-10-07,2020-07-21
-4jia,2013-08-07,2013-03-05
-5jip,2016-08-10,2016-04-22
-4jiz,2013-04-17,2013-03-07
-1jil,2001-10-26,2001-07-02
-6jit,2020-02-26,2019-02-23
-1ji1,2002-06-05,2001-06-28
-7jit,2020-08-05,2020-07-23
-5ji5,2016-05-04,2016-04-21
-1jir,2001-07-18,2001-07-02
-1jig,2002-06-19,2001-07-02
-5jiq,2016-10-05,2016-04-22
-8ji4,2023-11-15,2023-05-26
-2jif,2007-04-03,2007-02-28
-2jiz,2007-08-21,2007-07-03
-1jij,2001-10-26,2001-07-02
-7ji2,2020-12-23,2020-07-22
-8jim,2023-09-06,2023-05-26
-1jik,2001-10-26,2001-07-02
-6jiy,2019-07-17,2019-02-24
-5jib,2017-03-01,2016-04-22
-5jik,2017-04-12,2016-04-22
-4jiw,2013-08-14,2013-03-07
-2jih,2008-01-15,2007-06-28
-5ji8,2016-06-22,2016-04-22
-8jii,2023-09-06,2023-05-26
-2jid,2008-05-27,2007-02-28
-4ji0,2013-11-06,2013-03-05
-2ji9,2007-07-17,2007-02-26
-4ji1,2013-11-06,2013-03-05
-4jiu,2013-06-12,2013-03-07
-4ji6,2013-11-06,2013-03-05
-5jii,2017-04-12,2016-04-22
-1jii,2001-10-26,2001-07-02
-8jig,2024-05-29,2023-05-26
-6ji0,2019-07-17,2019-02-19
-1jif,2002-02-06,2001-07-02
-6jil,2019-12-18,2019-02-22
-2ji1,2007-05-01,2007-02-24
-1jie,2002-02-06,2001-07-02
-6ji4,2020-02-26,2019-02-20
-7jis,2020-12-30,2020-07-23
-6jiz,2020-02-26,2019-02-24
-4jic,2013-05-08,2013-03-05
-7jik,2021-07-28,2020-07-23
-2jiu,2008-01-22,2007-07-01
-6gvn,2019-04-24,2018-06-21
-8gvy,2023-09-20,2022-09-16
-4gv9,2013-05-01,2012-08-30
-4gvu,2013-02-06,2012-08-31
-5gvv,2017-03-01,2016-09-07
-6gvc,2019-03-27,2018-06-20
-1gvs,2003-02-27,2002-02-27
-8gv7,2022-12-21,2022-09-14
-5gvt,2017-11-22,2016-09-06
-4gv2,2013-06-19,2012-08-30
-1gvh,2002-08-06,2002-02-13
-2gvy,2006-08-15,2006-05-03
-3gvy,2009-12-22,2009-03-31
-3gvk,2010-03-02,2009-03-31
-6gvq,2018-12-26,2018-06-21
-4gvq,2012-10-31,2012-08-31
-5gv7,2017-04-05,2016-09-03
-2gv9,2006-05-16,2006-05-02
-1gvx,2002-07-04,2002-02-27
-3gvb,2009-04-14,2009-03-30
-4gvo,2012-09-12,2012-08-30
-5gvy,2017-09-13,2016-09-07
-8gv8,2023-04-12,2022-09-14
-1gvv,2002-07-04,2002-02-27
-4gvx,2012-10-03,2012-08-31
-5gvc,2017-06-14,2016-09-05
-4gv3,2013-05-01,2012-08-30
-2gv7,2006-06-06,2006-05-02
-2gvz,2006-07-04,2006-05-03
-8gv6,2022-12-21,2022-09-14
-3gv4,2009-04-28,2009-03-30
-8gvi,2022-10-19,2022-09-15
-6gv6,2018-09-19,2018-06-20
-1gvo,2003-02-20,2002-02-22
-4gv6,2013-05-01,2012-08-30
-2gvf,2007-01-23,2006-05-02
-8gvz,2023-09-20,2022-09-16
-2gvh,2006-05-30,2006-05-02
-3gv8,2009-06-02,2009-03-30
-5gvi,2017-09-13,2016-09-05
-3gvi,2009-04-14,2009-03-31
-6gv0,2019-07-03,2018-06-20
-5gvx,2017-09-27,2016-09-07
-5gvk,2017-07-12,2016-09-06
-1gv2,2003-07-03,2002-02-05
-6gvy,2018-08-01,2018-06-21
-3gvf,2009-04-28,2009-03-30
-2gvk,2006-05-16,2006-05-02
-1gvf,2002-06-18,2002-02-11
-6gvg,2019-10-02,2018-06-21
-4gvl,2012-12-26,2012-08-30
-8gvj,2022-11-23,2022-09-15
-8gvh,2023-04-12,2022-09-15
-5gve,2017-06-14,2016-09-05
-4gv0,2013-06-19,2012-08-30
-2gvm,2006-08-15,2006-05-03
-8gvm,2022-10-19,2022-09-15
-2gvn,2007-05-15,2006-05-03
-5gv0,2016-10-12,2016-09-01
-4gv1,2013-02-27,2012-08-30
-6gvt,2018-12-26,2018-06-21
-4gvi,2012-12-19,2012-08-30
-1gvg,2003-02-07,2002-02-12
-1gvk,2002-07-19,2002-02-14
-5gvp,2017-07-12,2016-09-06
-2gve,2006-05-16,2006-05-02
-8gvg,2022-10-19,2022-09-15
-2gvq,2006-05-23,2006-05-03
-4gvj,2013-08-14,2012-08-30
-6gv2,2019-07-03,2018-06-20
-4gvh,2012-12-19,2012-08-30
-2gvg,2006-06-20,2006-05-02
-1gv4,2002-04-26,2002-02-05
-6gvx,2019-05-29,2018-06-21
-1gv0,2002-02-15,2002-02-04
-6gvz,2018-10-17,2018-06-21
-6gvd,2018-08-22,2018-06-20
-2gv8,2006-06-06,2006-05-02
-6gvh,2019-10-02,2018-06-21
-3gv7,2009-06-02,2009-03-30
-6gvu,2018-12-26,2018-06-21
-2gv2,2006-09-05,2006-05-02
-5gvn,2017-07-12,2016-09-06
-4gva,2012-09-12,2012-08-30
-2gv6,2006-06-06,2006-05-02
-2gvd,2006-07-04,2006-05-02
-4gv7,2013-06-19,2012-08-30
-3gve,2009-04-28,2009-03-30
-3gvu,2009-04-21,2009-03-31
-1gvi,2002-06-06,2002-02-14
-4gvm,2013-05-01,2012-08-30
-6gvp,2018-07-11,2018-06-21
-5gv5,2017-09-13,2016-09-02
-1gv5,2003-07-03,2002-02-06
-4gve,2013-05-01,2012-08-30
-2gvv,2006-09-19,2006-05-03
-5gvw,2017-03-01,2016-09-07
-8gvw,2023-05-24,2022-09-16
-8gv5,2022-12-21,2022-09-14
-2gvc,2006-06-06,2006-05-02
-6gvr,2018-07-11,2018-06-21
-1gvc,2002-02-12,2002-02-07
-1gvy,2002-09-05,2002-02-28
-2gvi,2006-06-13,2006-05-02
-5gvh,2017-06-07,2016-09-05
-2gvj,2006-06-20,2006-05-02
-2gvw,2006-09-19,2006-05-03
-5gvm,2017-07-12,2016-09-06
-5gvj,2017-04-26,2016-09-06
-4gv8,2013-09-11,2012-08-30
-3gvh,2009-04-14,2009-03-31
-1gvr,2003-02-27,2002-02-27
-5gv8,2017-04-05,2016-09-03
-5gvd,2017-06-14,2016-09-05
-6gvm,2019-04-24,2018-06-21
-3gvx,2009-04-28,2009-03-31
-8gvd,2023-09-20,2022-09-14
-1gvq,2003-02-20,2002-02-26
-3gv6,2009-04-21,2009-03-30
-1gvu,2002-07-04,2002-02-27
-4gvz,2012-10-03,2012-08-31
-6gvi,2019-10-02,2018-06-21
-8gvx,2023-05-24,2022-09-16
-2gvx,2006-09-19,2006-05-03
-3gvj,2010-03-02,2009-03-31
-5gv4,2017-09-06,2016-09-01
-4gvy,2012-10-03,2012-08-31
-4gv4,2013-06-19,2012-08-30
-6gvs,2018-11-28,2018-06-21
-1gvt,2002-07-04,2002-02-27
-1gve,2002-06-27,2002-02-08
-6gv7,2018-09-19,2018-06-20
-5gv2,2017-09-06,2016-09-01
-2gvu,2006-09-19,2006-05-03
-5gv3,2017-09-06,2016-09-01
-3gv9,2009-04-14,2009-03-30
-6gva,2019-05-01,2018-06-20
-1gv8,2002-02-12,2002-02-07
-6gv4,2018-11-21,2018-06-20
-3gvd,2009-05-12,2009-03-30
-3gvp,2009-06-09,2009-03-31
-6gvw,2019-07-10,2018-06-21
-3gvl,2010-03-02,2009-03-31
-4gvd,2013-03-13,2012-08-30
-4gvf,2012-12-19,2012-08-30
-3gv5,2009-06-02,2009-03-30
-4gvc,2013-03-13,2012-08-30
-6gve,2019-07-03,2018-06-20
-8gvb,2022-10-19,2022-09-14
-8gv3,2023-09-20,2022-09-14
-1gv3,2002-08-08,2002-02-05
-5gvl,2017-07-12,2016-09-06
-4gvs,2012-10-31,2012-08-31
-6gvf,2019-10-02,2018-06-21
-4noi,2013-12-04,2013-11-19
-6nop,2019-04-24,2019-01-16
-2no9,2007-02-13,2006-10-25
-2nof,2006-11-21,2006-10-25
-3noj,2010-09-15,2010-06-25
-5nou,2017-07-12,2017-04-13
-7noz,2022-07-27,2021-02-26
-1noi,1996-08-01,1996-03-12
-5nol,2017-07-19,2017-04-12
-4non,2014-04-02,2013-11-20
-1nod,1999-03-23,1998-03-05
-1noj,1996-07-11,1996-03-12
-4nog,2013-12-04,2013-11-19
-2nox,2006-12-19,2006-10-26
-3not,2012-11-28,2010-06-25
-2noo,2007-01-23,2006-10-26
-1now,2003-04-29,2003-01-16
-6no4,2019-07-17,2019-01-15
-1noo,1996-03-08,1995-12-02
-4no9,2014-02-12,2013-11-19
-1noc,1998-10-14,1997-09-28
-3nod,1999-03-23,1998-03-06
-2no0,2007-07-03,2006-10-24
-1nox,1997-03-12,1996-11-20
-6no0,2019-07-17,2019-01-15
-5not,2017-07-12,2017-04-13
-2noe,2006-11-21,2006-10-25
-6no8,2019-11-27,2019-01-15
-7now,2021-04-07,2021-02-26
-5no1,2017-08-02,2017-04-10
-3nos,2000-02-04,1999-02-03
-6noc,2019-01-30,2019-01-16
-5now,2017-07-12,2017-04-13
-5nor,2017-07-12,2017-04-13
-4no1,2014-02-12,2013-11-19
-2no7,2007-07-03,2006-10-25
-4noe,2015-05-20,2013-11-19
-6non,2019-04-24,2019-01-16
-2nod,1999-03-23,1998-03-05
-1no6,2003-04-08,2003-01-15
-7nox,2021-11-10,2021-02-26
-6no3,2019-07-17,2019-01-15
-6noe,2019-01-30,2019-01-16
-2no3,2007-04-17,2006-10-24
-5no7,2018-01-17,2017-04-11
-4no5,2014-12-24,2013-11-19
-6nos,2019-02-20,2019-01-16
-3nok,2010-11-03,2010-06-25
-7nor,2021-06-30,2021-02-25
-1nop,2003-03-11,2003-01-16
-6nol,2019-04-10,2019-01-16
-2nos,1998-10-14,1997-09-28
-3noa,2011-06-29,2010-06-25
-5noy,2017-07-12,2017-04-13
-3no3,2010-07-28,2010-06-24
-5noo,2017-05-03,2017-04-12
-6no1,2019-07-17,2019-01-15
-6no9,2019-02-27,2019-01-15
-2nob,2006-11-21,2006-10-25
-6nok,2019-08-21,2019-01-16
-2noz,2006-11-21,2006-10-26
-3noi,2011-03-30,2010-06-25
-3no5,2010-08-25,2010-06-24
-5nof,2017-11-29,2017-04-12
-3nou,2012-11-28,2010-06-25
-6noo,2019-04-24,2019-01-16
-6noh,2019-01-30,2019-01-16
-6no5,2019-07-17,2019-01-15
-5noz,2017-07-12,2017-04-13
-5nos,2017-07-12,2017-04-13
-1nos,1998-10-14,1997-09-28
-5nox,2017-07-12,2017-04-13
-4nos,2000-02-04,1999-02-03
-1nou,2003-04-08,2003-01-16
-6nod,2019-01-30,2019-01-16
-5no4,2017-05-31,2017-04-10
-2nol,2006-11-21,2006-10-25
-5nog,2017-07-19,2017-04-12
-5no2,2017-05-24,2017-04-10
-4no7,2014-10-29,2013-11-19
-5no3,2017-05-31,2017-04-10
-7noy,2021-09-22,2021-02-26
-6noj,2019-02-20,2019-01-16
-2nog,2007-09-11,2006-10-25
-2no5,2007-09-25,2006-10-24
-2noi,2006-11-21,2006-10-25
-2nom,2007-02-20,2006-10-25
-4nof,2013-12-04,2013-11-19
-3nox,2010-08-11,2010-06-25
-1no9,2003-08-26,2003-01-16
-3nom,2010-11-03,2010-06-25
-4not,2015-01-21,2013-11-20
-1nom,1996-11-15,1996-04-19
-7nov,2021-06-30,2021-02-26
-4nov,2014-10-08,2013-11-20
-5noj,2017-08-02,2017-04-12
-5nob,2017-11-29,2017-04-11
-3nol,2010-11-03,2010-06-25
-1nok,1996-07-11,1996-03-12
-1noy,1996-10-14,1996-02-16
-2noh,2006-11-21,2006-10-25
-3noz,2010-12-22,2010-06-27
-1no3,2003-06-03,2003-01-15
-6noz,2020-01-22,2019-01-16
-6nor,2019-05-15,2019-01-16
-3no1,2010-07-07,2010-06-24
-6noq,2019-04-10,2019-01-16
-4no8,2014-02-12,2013-11-19
-5noq,2017-07-12,2017-04-13
-6nof,2019-01-30,2019-01-16
-3nop,2012-11-07,2010-06-25
-4no3,2014-12-24,2013-11-19
-4no6,2014-02-12,2013-11-19
-5non,2017-09-27,2017-04-12
-6no7,2019-07-24,2019-01-15
-4nob,2013-12-04,2013-11-19
-5nov,2017-07-12,2017-04-13
-3no4,2010-08-25,2010-06-24
-2noa,2007-02-13,2006-10-25
-2no1,2007-07-03,2006-10-24
-4no2,2014-11-19,2013-11-19
-1no5,2004-03-16,2003-01-15
-4no4,2014-12-03,2013-11-19
-7not,2021-06-30,2021-02-25
-6no2,2019-07-17,2019-01-15
-1nol,1996-03-08,1995-10-17
-2no6,2007-07-03,2006-10-25
-5no9,2017-12-27,2017-04-11
-7nos,2021-06-30,2021-02-25
-6o5k,2019-06-19,2019-03-03
-7o5p,2021-06-09,2021-04-09
-4o52,2014-12-24,2013-12-19
-2o5t,2007-10-16,2006-12-06
-5o5r,2018-06-13,2017-06-02
-3o57,2011-08-03,2010-07-28
-3o5n,2011-06-15,2010-07-28
-1o5r,2004-09-21,2003-10-05
-1o5g,2004-09-21,2003-09-09
-1o5o,2003-10-14,2003-10-03
-3o53,2010-09-22,2010-07-27
-1o5b,2004-09-21,2003-09-09
-5o5z,2018-10-24,2017-06-02
-2o5n,2007-09-25,2006-12-06
-2o5g,2007-12-25,2006-12-05
-7o5c,2021-06-09,2021-04-08
-5o52,2017-09-27,2017-05-31
-7o5w,2022-10-26,2021-04-09
-5o5e,2018-02-28,2017-06-01
-2o5s,2007-10-16,2006-12-06
-4o5f,2014-01-15,2013-12-19
-6o52,2019-06-19,2019-03-01
-7o5i,2022-11-16,2021-04-08
-7o5s,2021-06-09,2021-04-09
-6o5j,2019-06-26,2019-03-03
-1o5c,2004-09-21,2003-09-09
-6o5x,2019-06-19,2019-03-04
-6o5i,2020-01-08,2019-03-03
-3o51,2010-08-18,2010-07-27
-5o5l,2017-11-01,2017-06-02
-6o5r,2019-05-29,2019-03-04
-5o58,2017-10-25,2017-06-01
-7o5f,2021-06-09,2021-04-08
-4o5n,2014-04-16,2013-12-19
-5o5a,2018-06-13,2017-06-01
-2o5k,2007-10-23,2006-12-06
-7o5m,2022-04-20,2021-04-08
-2o5e,2007-04-03,2006-12-05
-7o57,2021-06-09,2021-04-08
-3o5b,2010-10-13,2010-07-28
-3o5x,2010-08-11,2010-07-28
-4o50,2014-12-24,2013-12-19
-2o53,2007-11-06,2006-12-05
-4o51,2014-03-26,2013-12-19
-2o5w,2007-08-28,2006-12-06
-2o59,2007-04-03,2006-12-05
-7o5q,2022-04-20,2021-04-09
-5o5c,2018-02-28,2017-06-01
-6o5c,2019-06-12,2019-03-01
-4o53,2014-12-24,2013-12-19
-6o5o,2020-03-11,2019-03-04
-4o5h,2014-02-19,2013-12-19
-6o5b,2019-05-22,2019-03-01
-5o5f,2018-06-13,2017-06-01
-1o5i,2003-09-30,2003-09-17
-1o5q,2003-11-25,2003-10-04
-6o51,2020-01-15,2019-03-01
-6o5a,2019-06-19,2019-03-01
-6o53,2020-01-15,2019-03-01
-5o5k,2017-11-01,2017-06-02
-5o54,2017-09-27,2017-05-31
-6o58,2019-05-22,2019-03-01
-7o5l,2022-04-20,2021-04-08
-3o5c,2011-08-03,2010-07-28
-6o5w,2019-05-08,2019-03-04
-3o5t,2011-10-05,2010-07-28
-7o50,2021-09-22,2021-04-07
-2o54,2007-04-03,2006-12-05
-7o55,2022-04-06,2021-04-07
-5o5t,2018-06-13,2017-06-02
-7o54,2021-11-10,2021-04-07
-6o5n,2019-07-10,2019-03-04
-7o5r,2022-10-26,2021-04-09
-6o5y,2019-12-04,2019-03-04
-7o5o,2021-06-09,2021-04-09
-1o5a,2004-09-21,2003-09-09
-2o5y,2007-12-18,2006-12-06
-4o5t,2014-06-04,2013-12-20
-5o5m,2018-06-13,2017-06-02
-4o5v,2014-11-05,2013-12-20
-6o5v,2019-05-29,2019-03-04
-7o5g,2021-06-09,2021-04-08
-3o5u,2011-08-17,2010-07-28
-6o5z,2020-09-16,2019-03-04
-4o5i,2014-04-16,2013-12-19
-4o5m,2014-01-01,2013-12-19
-6o5g,2019-08-07,2019-03-02
-4o55,2014-07-02,2013-12-19
-3o5r,2011-06-01,2010-07-28
-3o56,2011-08-03,2010-07-28
-2o52,2006-12-19,2006-12-05
-6o5h,2019-12-04,2019-03-03
-4o5c,2014-07-02,2013-12-19
-5o5p,2017-07-12,2017-06-02
-6o57,2019-06-19,2019-03-01
-4o58,2014-04-16,2013-12-19
-2o5j,2007-07-03,2006-12-06
-3o52,2011-05-11,2010-07-27
-4o5b,2014-07-02,2013-12-19
-1o5k,2003-10-07,2003-09-22
-3o5a,2011-04-06,2010-07-28
-1o5p,2003-10-14,2003-10-04
-2o5a,2006-12-19,2006-12-05
-4o5u,2014-11-05,2013-12-20
-3o55,2011-04-13,2010-07-28
-2o56,2006-12-12,2006-12-05
-5o5d,2018-01-31,2017-06-01
-1o5e,2004-09-21,2003-09-09
-7o5u,2021-06-09,2021-04-09
-5o5w,2017-09-27,2017-06-02
-6o5t,2019-09-25,2019-03-04
-7o5n,2022-04-20,2021-04-09
-3o5w,2011-09-14,2010-07-28
-7o5v,2022-11-16,2021-04-09
-5o59,2018-01-31,2017-06-01
-4o57,2014-12-24,2013-12-19
-5o50,2017-09-27,2017-05-31
-5o5y,2018-10-24,2017-06-02
-1o5m,2003-10-21,2003-09-26
-4o5q,2014-11-05,2013-12-20
-6o5u,2019-09-25,2019-03-04
-7o5x,2021-06-09,2021-04-09
-1o5x,2004-01-13,2003-10-06
-5o5g,2018-01-17,2017-06-01
-1o5f,2004-09-21,2003-09-09
-7o59,2021-06-09,2021-04-08
-5o5h,2018-06-13,2017-06-01
-5o55,2018-06-13,2017-05-31
-2o5c,2007-04-03,2006-12-05
-7o52,2021-07-28,2021-04-07
-4o5o,2014-01-01,2013-12-19
-5o5u,2018-06-13,2017-06-02
-2o5z,2007-12-18,2006-12-06
-6o5m,2019-07-10,2019-03-04
-7o5a,2021-06-09,2021-04-08
-4o5k,2014-07-02,2013-12-19
-7o5d,2021-06-09,2021-04-08
-2o51,2007-01-02,2006-12-05
-5o5j,2017-07-12,2017-06-02
-7o5h,2021-06-16,2021-04-08
-4o54,2014-12-24,2013-12-19
-1o5d,2004-09-21,2003-09-09
-2o5d,2007-02-20,2006-12-05
-4o5e,2014-07-02,2013-12-19
-4o56,2014-12-24,2013-12-19
-5o56,2017-09-27,2017-05-31
-3o50,2010-08-18,2010-07-27
-6o5s,2019-05-29,2019-03-04
-7o58,2022-02-02,2021-04-08
-2o5i,2007-07-03,2006-12-06
-1o51,2003-08-19,2003-08-01
-1o5w,2004-04-20,2003-10-06
-4o59,2014-09-24,2013-12-19
-6o50,2019-06-19,2019-03-01
-6o5e,2019-09-18,2019-03-01
-3o5s,2011-07-13,2010-07-28
-7o5z,2022-02-02,2021-04-09
-4o5g,2014-01-08,2013-12-19
-7o5b,2022-02-02,2021-04-08
-1fp1,2001-03-07,2000-08-29
-4fpg,2012-10-31,2012-06-22
-7fpz,2023-09-20,2022-09-10
-2fp0,2006-10-10,2006-01-15
-6fp0,2019-08-21,2018-02-08
-8fpd,2024-01-17,2023-01-04
-8fp5,2023-05-31,2023-01-04
-3fpf,2009-10-06,2009-01-05
-3fp0,2009-10-13,2009-01-02
-2fpy,2007-01-23,2006-01-17
-2fp4,2006-02-21,2006-01-15
-7fpd,2022-11-02,2022-08-26
-8fpu,2024-01-17,2023-01-05
-7fp8,2022-11-02,2022-08-26
-6fpo,2019-02-27,2018-02-11
-7fp4,2022-11-02,2022-08-26
-5fp6,2015-12-23,2015-11-27
-5fpb,2016-01-27,2015-11-27
-6fpj,2018-12-19,2018-02-09
-8fp0,2023-05-31,2023-01-03
-1fpm,2001-08-31,2000-08-31
-2fpd,2006-02-28,2006-01-16
-5fpp,2016-05-11,2015-12-02
-7fpe,2022-11-02,2022-08-26
-4fpa,2013-07-03,2012-06-21
-5fpl,2016-01-20,2015-12-02
-8fpr,2024-01-17,2023-01-05
-2fpq,2006-03-21,2006-01-16
-3fp4,2009-07-28,2009-01-03
-8fpy,2024-03-06,2023-01-05
-3fp5,2009-11-17,2009-01-04
-5fph,2016-02-10,2015-11-30
-1fp6,2001-01-17,2000-08-30
-1fpe,1995-02-27,1994-12-15
-5fpx,2016-05-04,2015-12-03
-8fpw,2024-06-05,2023-01-05
-6fpf,2019-01-16,2018-02-09
-3fpk,2009-02-03,2009-01-05
-4fpf,2012-10-31,2012-06-22
-7fpy,2023-09-20,2022-09-10
-3fpe,2009-10-06,2009-01-05
-8fpl,2024-02-28,2023-01-04
-3fpu,2010-01-12,2009-01-06
-8fph,2024-02-28,2023-01-04
-4fps,2013-07-24,2012-06-22
-1fpf,1995-02-27,1994-12-15
-5fpi,2016-01-20,2015-11-30
-7fpt,2023-09-20,2022-09-10
-8fpv,2024-03-06,2023-01-05
-5fpz,2016-05-04,2015-12-03
-6fpw,2019-02-27,2018-02-12
-8fp9,2024-02-28,2023-01-04
-3fpa,2009-06-30,2009-01-04
-8fpc,2024-02-28,2023-01-04
-8fpb,2024-01-17,2023-01-04
-3fpo,2009-06-30,2009-01-05
-7fpm,2023-09-20,2022-09-09
-6fpl,2019-03-13,2018-02-11
-1fp0,2001-01-24,2000-08-29
-2fpg,2006-02-21,2006-01-16
-1fpy,2001-04-04,2000-08-31
-5fpn,2015-12-23,2015-12-02
-3fp2,2009-07-28,2009-01-03
-5fp3,2016-01-27,2015-11-27
-6fp4,2018-06-06,2018-02-09
-2fpc,2006-05-23,2006-01-16
-5fpg,2016-12-14,2015-11-30
-7fpv,2023-09-20,2022-09-10
-2fpk,2006-01-31,2006-01-16
-3fps,2009-04-07,2009-01-06
-3fpd,2009-02-17,2009-01-05
-4fpb,2013-07-03,2012-06-21
-3fpy,2009-11-10,2009-01-06
-7fpb,2022-11-02,2022-08-26
-3fpx,2009-01-27,2009-01-06
-5fpt,2015-12-23,2015-12-02
-2fp7,2006-03-07,2006-01-16
-7fpj,2022-11-02,2022-08-26
-4fpv,2012-10-31,2012-06-22
-6fpm,2019-03-13,2018-02-11
-3fpt,2010-01-26,2009-01-06
-7fpl,2023-09-20,2022-09-09
-3fpw,2009-01-20,2009-01-06
-7fpn,2023-09-20,2022-09-09
-2fpt,2007-01-23,2006-01-17
-2fp1,2006-03-28,2006-01-15
-1fph,1994-01-31,1993-04-21
-1fpk,1996-06-20,1995-06-02
-8fpx,2024-06-05,2023-01-05
-7fp1,2022-11-02,2022-08-26
-4fp9,2012-09-12,2012-06-21
-1fp7,2001-08-30,2000-08-30
-7fp9,2022-11-02,2022-08-26
-4fpd,2013-02-27,2012-06-22
-8fpi,2023-06-14,2023-01-04
-4fpl,2012-10-31,2012-06-22
-4fph,2012-10-31,2012-06-22
-5fps,2015-12-23,2015-12-02
-8fpk,2024-02-28,2023-01-04
-7fph,2022-11-02,2022-08-26
-7fpa,2022-11-02,2022-08-26
-4fp4,2012-07-11,2012-06-21
-7fp7,2022-11-02,2022-08-26
-1fpl,1996-06-20,1995-06-02
-6fpu,2019-03-13,2018-02-12
-3fpi,2009-02-03,2009-01-05
-7fpp,2023-09-20,2022-09-09
-5fpv,2016-01-13,2015-12-03
-2fps,2006-09-05,2006-01-17
-6fpc,2018-05-30,2018-02-09
-3fp6,2009-02-17,2009-01-04
-4fpy,2012-10-31,2012-06-23
-7fpw,2023-09-20,2022-09-10
-1fpi,1996-06-20,1995-06-02
-8fpp,2024-01-17,2023-01-05
-8fpj,2023-06-14,2023-01-04
-2fpl,2006-01-31,2006-01-16
-7fpi,2022-11-02,2022-08-26
-4fp2,2012-10-31,2012-06-21
-4fpt,2013-07-03,2012-06-22
-5fp8,2016-01-27,2015-11-27
-2fpu,2006-09-05,2006-01-17
-1fpb,1993-10-31,1992-02-03
-4fpe,2012-10-31,2012-06-22
-8fp1,2023-04-05,2023-01-03
-3fpm,2009-04-07,2009-01-05
-5fpo,2015-12-23,2015-12-02
-5fpr,2015-12-16,2015-12-02
-7fp6,2022-11-02,2022-08-26
-5fpk,2016-03-30,2015-12-01
-1fpd,1995-02-27,1994-12-15
-3fpl,2010-01-19,2009-01-05
-4fp3,2012-10-31,2012-06-21
-6fpi,2018-12-19,2018-02-09
-6fpp,2018-05-09,2018-02-11
-3fpb,2009-04-07,2009-01-05
-1fp8,2003-09-02,2000-08-31
-2fp2,2006-03-28,2006-01-15
-5fpu,2016-01-13,2015-12-03
-7fp2,2022-11-02,2022-08-26
-5fpf,2016-12-14,2015-11-30
-7fpg,2022-11-02,2022-08-26
-8fpz,2024-03-06,2023-01-05
-1fpg,1995-02-27,1994-12-15
-1fp2,2001-03-07,2000-08-29
-2fpx,2006-09-05,2006-01-17
-1fp4,2002-11-20,2000-08-30
-1fpw,2000-10-18,2000-08-31
-4fpk,2012-10-31,2012-06-22
-3fpc,2010-01-19,2009-01-05
-4fpp,2012-09-12,2012-06-22
-4fp8,2012-09-19,2012-06-21
-7fpo,2023-09-20,2022-09-09
-1fpu,2000-09-20,2000-08-31
-1fpr,2001-03-07,2000-08-31
-7fpq,2023-09-20,2022-09-09
-5fp5,2015-12-09,2015-11-27
-4fp1,2013-06-26,2012-06-21
-1fpp,1999-06-08,1998-07-10
-3fpj,2009-10-06,2009-01-05
-3fpv,2009-01-20,2009-01-06
-8fpe,2023-03-15,2023-01-04
-5fp4,2016-01-27,2015-11-27
-6fpx,2018-05-09,2018-02-12
-2fpz,2006-03-07,2006-01-17
-5fp9,2016-01-27,2015-11-27
-4fpj,2012-10-31,2012-06-22
-6fph,2019-08-21,2018-02-09
-6fpd,2018-05-16,2018-02-09
-5fpy,2015-12-23,2015-12-03
-8fp7,2024-01-17,2023-01-04
-6fp1,2019-08-21,2018-02-08
-6fpq,2018-05-09,2018-02-11
-1fpj,1996-06-20,1995-06-02
-8fp6,2024-01-17,2023-01-04
-7fpu,2023-09-20,2022-09-10
-1fpq,2001-03-07,2000-08-31
-8fpm,2024-01-17,2023-01-05
-5fp0,2016-03-02,2015-11-26
-5fpd,2015-12-16,2015-11-28
-7fpx,2023-09-20,2022-09-10
-7fpk,2022-11-02,2022-08-26
-7fpf,2022-11-02,2022-08-26
-6fp3,2018-05-02,2018-02-09
-7fp0,2022-11-02,2022-08-26
-5fpm,2015-12-16,2015-12-02
-8fpn,2024-01-17,2023-01-05
-7fpr,2023-09-20,2022-09-10
-2fpv,2007-01-23,2006-01-17
-6fp5,2019-08-21,2018-02-09
-4fpc,2012-10-31,2012-06-22
-8fp8,2024-01-17,2023-01-04
-7fp5,2022-11-02,2022-08-26
-2fpm,2006-01-31,2006-01-16
-8fp3,2023-04-05,2023-01-03
-6fpy,2019-02-27,2018-02-12
-4fpo,2012-10-31,2012-06-22
-2fpw,2006-09-05,2006-01-17
-8fpf,2023-11-22,2023-01-04
-7fpc,2022-11-02,2022-08-26
-5fpa,2016-01-27,2015-11-27
-3fp7,2009-02-17,2009-01-04
-5fpe,2015-12-23,2015-11-28
-6fp6,2019-01-30,2018-02-09
-2fpb,2006-05-23,2006-01-16
-3fph,2009-10-06,2009-01-05
-5fp7,2016-11-09,2015-11-27
-7fps,2023-09-20,2022-09-10
-2fpr,2006-09-05,2006-01-17
-3fp8,2009-02-17,2009-01-04
-7fp3,2022-11-02,2022-08-26
-3zjy,2013-04-10,2013-01-21
-1zjo,2005-12-13,2005-04-29
-6zj2,2021-02-17,2020-06-27
-5zj8,2019-03-20,2018-03-19
-5zj5,2018-08-08,2018-03-19
-4zjx,2016-06-01,2015-04-29
-4zjk,2015-09-09,2015-04-29
-2zjp,2008-06-17,2008-03-07
-4zju,2015-05-13,2015-04-29
-3zjl,2013-07-03,2013-01-18
-6zjk,2020-09-30,2020-06-29
-5zjv,2018-04-25,2018-03-22
-6zj5,2020-12-09,2020-06-27
-6zji,2021-07-07,2020-06-29
-3zj4,2013-07-10,2013-01-17
-2zjl,2009-01-20,2008-03-07
-6zj1,2020-12-02,2020-06-27
-3zjc,2013-03-13,2013-01-17
-5zj2,2019-03-20,2018-03-18
-4zjr,2015-06-17,2015-04-29
-3zji,2013-06-26,2013-01-18
-1zj8,2005-05-31,2005-04-28
-3zj5,2013-07-10,2013-01-17
-2zjy,2009-03-24,2008-03-11
-6zj9,2020-11-18,2020-06-28
-1zjm,2005-08-16,2005-04-29
-2zj9,2009-03-10,2008-02-29
-3zj8,2014-02-05,2013-01-17
-3zj7,2014-02-05,2013-01-17
-2zja,2009-02-10,2008-02-29
-2zj0,2008-09-16,2008-02-29
-1zji,2005-09-27,2005-04-28
-5zjn,2018-09-19,2018-03-21
-1zjc,2005-06-07,2005-04-28
-3zjo,2013-06-26,2013-01-18
-3zj0,2013-10-16,2013-01-15
-3zjj,2013-06-26,2013-01-18
-6zjr,2020-08-05,2020-06-29
-7zjp,2022-07-13,2022-04-11
-7zj3,2022-11-30,2022-04-08
-1zj7,2006-05-09,2005-04-28
-3zj6,2014-01-29,2013-01-17
-6zjd,2020-09-16,2020-06-28
-4zjq,2016-07-27,2015-04-29
-4zjo,2016-07-27,2015-04-29
-4zjz,2015-09-30,2015-04-29
-6zjg,2021-07-07,2020-06-29
-2zjf,2008-04-01,2008-03-07
-7zjb,2023-04-19,2022-04-10
-6zjz,2020-12-30,2020-06-29
-2zjr,2008-06-17,2008-03-08
-5zji,2018-06-20,2018-03-20
-7zjq,2022-07-13,2022-04-11
-5zjk,2019-03-20,2018-03-20
-5zjz,2019-02-20,2018-03-22
-8zjv,2024-05-29,2024-05-15
-3zjp,2013-06-26,2013-01-18
-6zjl,2020-09-02,2020-06-29
-8zjf,2024-06-05,2024-05-14
-2zjv,2008-04-08,2008-03-10
-6zje,2020-09-16,2020-06-28
-6zjh,2020-11-25,2020-06-29
-2zjo,2009-03-10,2008-03-07
-4zj8,2016-03-09,2015-04-29
-4zj0,2016-05-11,2015-04-28
-1zjn,2005-08-16,2005-04-29
-2zjn,2009-01-20,2008-03-07
-1zjj,2006-04-29,2005-04-29
-6zj0,2020-08-19,2020-06-26
-7zj6,2022-08-17,2022-04-08
-2zj1,2008-09-16,2008-02-29
-5zjd,2019-07-24,2018-03-20
-6zjs,2020-08-05,2020-06-29
-1zjy,2005-06-21,2005-05-02
-5zjw,2019-04-03,2018-03-22
-3zjm,2013-06-26,2013-01-18
-3zjq,2013-06-26,2013-01-18
-6zju,2020-08-05,2020-06-29
-4zjj,2015-06-24,2015-04-29
-2zji,2009-01-20,2008-03-07
-5zj6,2018-06-06,2018-03-19
-3zjt,2013-04-17,2013-01-18
-4zjw,2015-06-17,2015-04-29
-2zjh,2009-01-20,2008-03-07
-1zj1,2005-12-13,2005-04-27
-3zjh,2013-06-26,2013-01-18
-3zjn,2013-06-26,2013-01-18
-6zj3,2020-10-07,2020-06-27
-7zju,2023-09-27,2022-04-12
-6zjc,2020-11-18,2020-06-28
-6zjw,2020-08-05,2020-06-29
-4zjf,2015-05-27,2015-04-29
-4zji,2015-06-24,2015-04-29
-2zjm,2009-01-20,2008-03-07
-6zjt,2020-08-05,2020-06-29
-6zjp,2020-08-05,2020-06-29
-4zjc,2016-03-09,2015-04-29
-4zjp,2015-05-20,2015-04-29
-4zjt,2015-05-13,2015-04-29
-1zj9,2005-05-31,2005-04-28
-2zjk,2009-01-20,2008-03-07
-2zj6,2008-12-02,2008-02-29
-1zjl,2005-12-20,2005-04-29
-2zjj,2009-01-20,2008-03-07
-6zjf,2020-07-29,2020-06-28
-1zj0,2005-12-13,2005-04-27
-5zj9,2018-10-10,2018-03-19
-3zjr,2013-06-26,2013-01-18
-5zjp,2018-12-05,2018-03-21
-7zjm,2023-04-19,2022-04-11
-5zjf,2019-07-24,2018-03-20
-5zjg,2019-01-16,2018-03-20
-2zj7,2008-12-02,2008-02-29
-7zj8,2022-08-17,2022-04-08
-1zjb,2006-10-17,2005-04-28
-1zj6,2005-06-07,2005-04-28
-5zj7,2019-03-20,2018-03-19
-2zjd,2008-06-03,2008-03-05
-4zjb,2016-11-02,2015-04-29
-3zj1,2013-09-11,2013-01-16
-6zjq,2020-08-05,2020-06-29
-7zjx,2022-09-07,2022-04-12
-5zjy,2019-03-20,2018-03-22
-6zjb,2020-09-16,2020-06-28
-2zjz,2009-03-24,2008-03-11
-5zjc,2019-03-20,2018-03-20
-6zjo,2021-07-07,2020-06-29
-1zjz,2005-06-21,2005-05-02
-3zjz,2013-10-02,2013-01-21
-4zjs,2015-05-13,2015-04-29
-1zjw,2005-06-07,2005-05-01
-2zj4,2009-01-13,2008-02-29
-1zj2,2005-12-13,2005-04-27
-2zj3,2009-01-13,2008-02-29
-6zjm,2020-10-14,2020-06-29
-1zj3,2005-12-13,2005-04-28
-7zjw,2022-10-19,2022-04-12
-4zjl,2016-07-27,2015-04-29
-6zja,2020-12-23,2020-06-28
-3zju,2013-04-17,2013-01-18
-5zj1,2019-03-20,2018-03-18
-2zj5,2009-02-10,2008-02-29
-7zj0,2023-02-22,2022-04-08
-1zjp,2005-12-13,2005-04-29
-2zju,2008-04-08,2008-03-10
-6zj6,2020-11-18,2020-06-27
-5zja,2018-10-10,2018-03-19
-1zja,2006-10-17,2005-04-28
-4zj7,2015-06-03,2015-04-29
-3zja,2014-01-29,2013-01-17
-7zjv,2023-09-27,2022-04-12
-7zj7,2022-08-17,2022-04-08
-6zjx,2020-08-05,2020-06-29
-3zjs,2013-06-26,2013-01-18
-3zj2,2013-09-11,2013-01-16
-2zjw,2009-03-17,2008-03-11
-2zjs,2008-10-14,2008-03-08
-5hgz,2016-09-14,2016-01-09
-1hg2,2001-02-12,2000-12-12
-3hgw,2009-06-30,2009-05-14
-4hgr,2013-08-21,2012-10-08
-6hg3,2018-10-24,2018-08-22
-3hg3,2009-11-24,2009-05-13
-4hg3,2013-07-31,2012-10-06
-8hgm,2023-10-25,2022-11-15
-6hgg,2019-05-29,2018-08-23
-3hg9,2009-05-26,2009-05-13
-4hg5,2013-07-31,2012-10-07
-4hgs,2012-11-21,2012-10-08
-6hgx,2019-07-03,2018-08-23
-5hgl,2016-08-10,2016-01-08
-6hgm,2019-05-29,2018-08-23
-6hgt,2019-09-04,2018-08-23
-4hgo,2013-08-21,2012-10-08
-6hgr,2019-07-31,2018-08-23
-5hgi,2016-06-08,2016-01-08
-8hgi,2023-09-27,2022-11-14
-4hgx,2012-10-24,2012-10-09
-1hgj,1994-01-31,1991-11-01
-8hgd,2023-11-22,2022-11-14
-6hgf,2019-05-29,2018-08-23
-8hgo,2023-02-08,2022-11-15
-1hg8,2001-11-10,2000-12-13
-3hg2,2009-11-24,2009-05-13
-4hgg,2013-05-01,2012-10-08
-8hgh,2023-01-11,2022-11-14
-4hgt,2012-11-21,2012-10-08
-5hgp,2016-10-19,2016-01-08
-3hgg,2010-06-30,2009-05-13
-2hgt,1994-01-31,1991-06-03
-1hgi,1994-01-31,1991-11-01
-5hg2,2016-02-24,2016-01-07
-8hg6,2023-04-26,2022-11-13
-8hgg,2023-01-11,2022-11-14
-3hgy,2010-06-30,2009-05-14
-6hgv,2019-07-03,2018-08-23
-5hgv,2016-09-14,2016-01-08
-2hg8,2006-10-24,2006-06-26
-5hgq,2016-10-26,2016-01-08
-2hg3,2007-03-27,2006-06-26
-4hgf,2013-05-01,2012-10-08
-6hg8,2019-09-04,2018-08-22
-8hge,2023-11-22,2022-11-14
-8hgc,2023-08-16,2022-11-14
-1hgb,1994-01-31,1991-10-31
-8hgb,2023-11-22,2022-11-14
-2hgs,1999-06-22,1999-01-04
-6hg1,2018-10-24,2018-08-22
-8hgs,2023-02-15,2022-11-15
-6hgs,2019-07-31,2018-08-23
-2hg0,2006-11-07,2006-06-26
-2hgz,2007-06-05,2006-06-27
-4hgn,2013-08-21,2012-10-08
-5hgr,2016-11-16,2016-01-08
-1hgy,2002-01-15,2000-12-15
-6hgq,2019-07-31,2018-08-23
-2hgw,2006-10-24,2006-06-27
-3hgj,2010-02-23,2009-05-14
-5hgj,2017-04-12,2016-01-08
-6hg5,2018-08-29,2018-08-22
-3hg5,2009-11-24,2009-05-13
-6hgz,2018-11-28,2018-08-23
-1hgw,2002-01-15,2000-12-15
-8hgt,2023-08-16,2022-11-15
-5hga,2016-06-08,2016-01-08
-5hg7,2016-01-27,2016-01-08
-3hgp,2009-07-28,2009-05-14
-8hg5,2023-04-26,2022-11-13
-1hgf,1994-01-31,1991-11-01
-6hgi,2019-05-29,2018-08-23
-8hgl,2023-10-25,2022-11-15
-8hg9,2023-07-26,2022-11-14
-8hgk,2023-09-27,2022-11-14
-3hgs,2009-08-25,2009-05-14
-6hgl,2019-05-29,2018-08-23
-4hg6,2012-12-19,2012-10-07
-3hgm,2010-03-02,2009-05-14
-8hgr,2022-12-14,2022-11-15
-2hgx,2006-10-24,2006-06-27
-1hg3,2001-03-07,2000-12-12
-4hgw,2013-01-09,2012-10-08
-2hgo,2007-02-27,2006-06-27
-4hgp,2013-08-21,2012-10-08
-8hg0,2023-08-30,2022-11-13
-2hg5,2006-09-12,2006-06-26
-2hgh,2006-08-01,2006-06-27
-4hgi,2013-05-01,2012-10-08
-6hgj,2019-05-29,2018-08-23
-6hg6,2019-05-29,2018-08-22
-6hg2,2018-10-24,2018-08-22
-5hg1,2016-03-30,2016-01-07
-1hgd,1994-01-31,1991-11-01
-4hg9,2012-10-17,2012-10-07
-4hg0,2013-02-06,2012-10-05
-6hga,2020-03-18,2018-08-23
-4hgl,2012-11-21,2012-10-08
-3hgr,2009-08-25,2009-05-14
-1hgc,1994-01-31,1991-10-31
-8hg7,2023-11-15,2022-11-14
-4hgh,2013-05-01,2012-10-08
-1hga,1994-01-31,1991-10-31
-5hg5,2016-02-03,2016-01-08
-6hgw,2019-08-07,2018-08-23
-4hge,2012-10-24,2012-10-08
-5hg9,2016-02-03,2016-01-08
-8hgz,2024-03-06,2022-11-16
-4hgd,2013-07-31,2012-10-08
-5hgw,2016-02-03,2016-01-09
-3hgo,2009-08-25,2009-05-14
-5hgg,2016-06-01,2016-01-08
-5hgc,2016-04-06,2016-01-08
-6hgo,2019-11-20,2018-08-23
-1hge,1994-01-31,1991-11-01
-8hg1,2022-12-21,2022-11-13
-4hgz,2013-10-30,2012-10-09
-8hg3,2023-04-26,2022-11-13
-3hgi,2010-01-12,2009-05-14
-5hgt,2016-01-20,2016-01-08
-1hgx,1996-08-17,1996-03-12
-3hgz,2009-12-08,2009-05-14
-1hgh,1994-01-31,1991-11-01
-4hgj,2013-05-01,2012-10-08
-5hg0,2016-01-20,2016-01-07
-2hg9,2007-03-27,2006-06-26
-6hgk,2019-05-29,2018-08-23
-2hg1,2007-06-05,2006-06-26
-6hgb,2018-09-05,2018-08-23
-1hgg,1994-01-31,1991-11-01
-6hg0,2018-08-29,2018-08-22
-8hgp,2023-02-08,2022-11-15
-5hgb,2016-06-08,2016-01-08
-3hg4,2009-11-24,2009-05-13
-5hg8,2016-02-03,2016-01-08
-1hg1,2001-08-07,2000-12-08
-6hgy,2019-06-26,2018-08-23
-4hg7,2013-07-31,2012-10-07
-4hgu,2013-10-09,2012-10-08
-2hgv,2006-08-15,2006-06-27
-4hg4,2013-02-13,2012-10-06
-5hgm,2016-08-10,2016-01-08
-3hgn,2009-07-28,2009-05-14
-3hgx,2009-06-30,2009-05-14
-4hgq,2013-08-21,2012-10-08
-8hgw,2023-03-15,2022-11-15
-4hgc,2013-10-09,2012-10-08
-3gu8,2010-03-09,2009-03-28
-8gui,2023-09-20,2022-09-12
-1guy,2002-02-15,2002-02-04
-1guf,2003-03-13,2002-01-25
-3gu9,2009-06-30,2009-03-28
-6gu4,2018-12-05,2018-06-19
-2gud,2006-08-01,2006-04-29
-3gu6,2010-03-09,2009-03-28
-2guu,2006-05-16,2006-05-01
-2gu5,2006-07-04,2006-04-28
-4gul,2013-05-29,2012-08-29
-1gul,1999-01-27,1998-06-10
-6gu7,2018-12-05,2018-06-19
-5guf,2017-10-11,2016-08-29
-8guj,2023-09-20,2022-09-12
-6guj,2018-11-07,2018-06-19
-2guo,2007-06-12,2006-05-01
-3guz,2010-02-09,2009-03-30
-4gun,2013-09-18,2012-08-29
-6guf,2018-12-05,2018-06-19
-3guw,2009-04-07,2009-03-30
-8guw,2023-05-31,2022-09-13
-4gu0,2013-02-13,2012-08-29
-4guk,2013-12-25,2012-08-29
-5gu3,2017-03-29,2016-08-24
-3guo,2009-08-25,2009-03-30
-4guu,2013-01-16,2012-08-29
-8gu0,2023-07-26,2022-09-09
-4guy,2012-09-19,2012-08-30
-2gum,2006-07-25,2006-05-01
-1gut,2002-02-08,2002-01-28
-6guc,2018-12-05,2018-06-19
-8gur,2023-05-10,2022-09-13
-3gu3,2009-04-07,2009-03-28
-1gus,2002-02-08,2002-01-28
-6gu2,2018-12-05,2018-06-19
-4gut,2013-01-16,2012-08-29
-4gu7,2013-09-11,2012-08-29
-6guz,2019-10-09,2018-06-19
-5gu1,2017-03-29,2016-08-24
-5guw,2017-08-16,2016-08-31
-1guu,2003-06-26,2002-01-30
-2gu4,2006-07-04,2006-04-28
-5gue,2017-06-07,2016-08-28
-8gud,2022-11-23,2022-09-11
-1gub,2003-03-06,2002-01-24
-1gua,1997-01-11,1996-06-18
-4gur,2013-01-16,2012-08-29
-4gus,2013-01-16,2012-08-29
-3gur,2009-10-27,2009-03-30
-5gu0,2017-03-29,2016-08-24
-5gu2,2017-03-29,2016-08-24
-1gud,2003-03-06,2002-01-24
-6guq,2019-07-03,2018-06-19
-1gu8,2002-04-12,2002-01-24
-1gug,2002-02-08,2002-01-25
-1gu2,2003-01-16,2002-01-22
-1gui,2002-09-26,2002-01-27
-4gu4,2012-12-05,2012-08-29
-4guq,2013-08-14,2012-08-29
-4gug,2012-09-12,2012-08-29
-8gua,2022-12-07,2022-09-11
-6guk,2018-12-05,2018-06-19
-4gu3,2012-12-05,2012-08-29
-4guw,2012-09-12,2012-08-30
-4gu1,2013-01-16,2012-08-29
-6gua,2019-05-22,2018-06-19
-5gu8,2017-08-30,2016-08-26
-4gu9,2013-09-04,2012-08-29
-4gua,2012-10-03,2012-08-29
-1gu6,2002-03-08,2002-01-24
-8guv,2023-07-19,2022-09-13
-3guh,2009-04-28,2009-03-30
-5gup,2017-03-29,2016-08-30
-6gue,2018-12-05,2018-06-19
-2gu3,2006-05-30,2006-04-28
-2gui,2007-03-13,2006-04-30
-3gun,2009-08-25,2009-03-30
-3gud,2010-02-02,2009-03-29
-5gug,2017-04-26,2016-08-29
-2gu7,2006-07-04,2006-04-28
-4gup,2012-10-17,2012-08-29
-2gup,2006-05-30,2006-05-01
-8guh,2023-07-19,2022-09-12
-1gun,2002-02-08,2002-01-28
-3gue,2009-08-18,2009-03-29
-3gup,2009-08-25,2009-03-30
-4gui,2012-09-12,2012-08-29
-1gup,1997-11-12,1996-10-23
-6gu0,2019-01-16,2018-06-19
-5guh,2016-10-19,2016-08-29
-1guh,1993-10-31,1993-02-24
-8gut,2023-05-10,2022-09-13
-2guh,2006-05-30,2006-04-30
-3guc,2009-05-26,2009-03-29
-3guk,2009-08-25,2009-03-30
-5gub,2017-07-19,2016-08-26
-4guh,2012-09-12,2012-08-29
-4guv,2013-04-10,2012-08-29
-4gue,2013-01-30,2012-08-29
-8gue,2023-02-15,2022-09-11
-1guz,2002-02-21,2002-02-04
-4gu6,2013-09-04,2012-08-29
-4gu5,2012-09-26,2012-08-29
-3gu5,2010-03-09,2009-03-28
-6guy,2019-10-09,2018-06-19
-2gu2,2006-06-20,2006-04-28
-3gub,2010-03-09,2009-03-29
-8gul,2023-06-21,2022-09-12
-3gus,2009-10-27,2009-03-30
-6gu6,2018-12-05,2018-06-19
-6guh,2018-12-05,2018-06-19
-4guo,2013-11-27,2012-08-29
-2gu8,2007-05-01,2006-04-28
-6gur,2018-08-15,2018-06-19
-8gub,2022-11-23,2022-09-11
-3gum,2009-08-25,2009-03-30
-3gu2,2009-06-30,2009-03-28
-3gu7,2010-03-09,2009-03-28
-8gun,2022-11-09,2022-09-13
-1gue,2002-04-12,2002-01-24
-8gus,2023-05-10,2022-09-13
-1gux,1998-12-02,1997-11-15
-5guv,2017-08-30,2016-08-31
-3gug,2010-02-09,2009-03-30
-4gub,2013-09-25,2012-08-29
-1guq,1997-11-12,1996-10-23
-3gu1,2009-06-30,2009-03-28
-1gu3,2002-09-26,2002-01-22
-6gu3,2018-12-05,2018-06-19
-4guj,2012-09-12,2012-08-29
-8gu6,2023-01-18,2022-09-10
-1gu1,2002-04-12,2002-01-22
-8gu1,2023-07-26,2022-09-09
-8guq,2023-05-10,2022-09-13
-3gul,2009-08-25,2009-03-30
-5gud,2017-06-07,2016-08-28
-5gul,2017-08-30,2016-08-29
-2gu1,2006-07-04,2006-04-28
-2gue,2006-08-01,2006-04-29
-5gux,2017-08-16,2016-08-31
-6gu5,2018-11-07,2018-06-19
-4gux,2013-09-04,2012-08-30
-6gub,2018-12-05,2018-06-19
-6gux,2019-10-09,2018-06-19
-6guu,2019-10-09,2018-06-19
-5gut,2017-09-06,2016-08-31
-5gu4,2016-11-02,2016-08-24
-2guc,2006-08-01,2006-04-29
-2gu6,2006-07-04,2006-04-28
-2guy,2006-08-15,2006-05-02
-3gu4,2010-03-09,2009-03-28
-6u59,2020-01-29,2019-08-27
-7u5z,2023-03-15,2022-03-03
-5u51,2017-08-16,2016-12-06
-1u5v,2004-10-12,2004-07-28
-3u58,2011-12-28,2011-10-11
-1u5k,2004-10-26,2004-07-27
-6u5l,2019-12-25,2019-08-28
-8u5b,2023-09-27,2023-09-12
-5u58,2017-01-04,2016-12-06
-3u50,2011-12-14,2011-10-10
-1u5u,2005-01-11,2004-07-28
-3u57,2011-11-30,2011-10-11
-3u5y,2011-11-30,2011-10-11
-1u54,2004-08-31,2004-07-26
-4u5g,2014-08-13,2014-07-25
-4u5j,2014-09-17,2014-07-25
-3u5n,2012-01-18,2011-10-11
-7u5a,2022-12-21,2022-03-01
-3u5p,2012-01-18,2011-10-11
-7u5y,2022-03-09,2022-03-02
-5u5a,2017-02-22,2016-12-06
-4u5p,2015-02-25,2014-07-25
-5u5i,2017-12-06,2016-12-06
-7u5f,2022-03-09,2022-03-02
-4u51,2014-10-22,2014-07-24
-5u5l,2017-08-23,2016-12-06
-8u5g,2023-12-06,2023-09-12
-7u5m,2022-12-14,2022-03-02
-4u5t,2014-08-06,2014-07-25
-7u59,2023-01-11,2022-03-01
-6u5m,2019-12-04,2019-08-28
-5u5v,2017-02-01,2016-12-07
-3u5l,2011-11-23,2011-10-11
-5u5c,2017-02-22,2016-12-06
-4u5l,2015-05-13,2014-07-25
-1u5s,2005-04-05,2004-07-28
-4u5i,2015-01-14,2014-07-25
-6u5p,2020-03-25,2019-08-28
-3u5s,2012-10-17,2011-10-11
-5u5y,2017-02-01,2016-12-07
-5u5w,2017-02-01,2016-12-07
-4u5d,2014-08-13,2014-07-25
-7u5v,2023-09-27,2022-03-02
-1u5c,2005-06-21,2004-07-27
-7u58,2022-11-02,2022-03-01
-1u5z,2004-10-12,2004-07-28
-8u5m,2024-02-07,2023-09-12
-7u5q,2022-03-09,2022-03-02
-1u55,2004-08-31,2004-07-27
-7u5l,2022-12-14,2022-03-02
-7u5h,2022-12-14,2022-03-02
-1u5j,2004-09-07,2004-07-27
-3u5j,2011-11-23,2011-10-11
-1u5b,2004-11-23,2004-07-27
-5u55,2017-01-04,2016-12-06
-1u56,2004-08-31,2004-07-27
-5u5d,2017-01-04,2016-12-06
-6u5s,2019-12-04,2019-08-28
-4u5e,2014-08-13,2014-07-25
-3u51,2012-02-22,2011-10-10
-3u5o,2012-01-18,2011-10-11
-5u5f,2018-03-14,2016-12-06
-4u56,2014-10-22,2014-07-24
-4u52,2014-10-22,2014-07-24
-6u5a,2019-09-04,2019-08-27
-6u5r,2020-03-25,2019-08-28
-4u5k,2015-01-14,2014-07-25
-4u5v,2015-05-13,2014-07-25
-6u5w,2019-10-16,2019-08-28
-5u5z,2017-02-01,2016-12-07
-4u5s,2015-05-13,2014-07-25
-1u5r,2004-10-12,2004-07-28
-6u5t,2019-10-16,2019-08-28
-1u5a,2005-06-21,2004-07-27
-1u5p,2004-10-19,2004-07-28
-5u5n,2017-12-06,2016-12-06
-4u54,2015-05-13,2014-07-24
-3u52,2011-12-14,2011-10-10
-5u5k,2017-01-11,2016-12-06
-5u56,2017-08-16,2016-12-06
-4u5x,2014-08-20,2014-07-25
-7u5p,2022-06-22,2022-03-02
-5u5q,2017-03-29,2016-12-07
-7u5e,2023-06-14,2022-03-02
-5u5p,2018-03-14,2016-12-07
-5u5u,2017-02-01,2016-12-07
-5u5b,2017-02-22,2016-12-06
-5u52,2017-05-24,2016-12-06
-1u5q,2004-10-12,2004-07-28
-7u5n,2022-12-14,2022-03-02
-4u5o,2015-05-13,2014-07-25
-5u5m,2018-03-14,2016-12-06
-3u54,2012-10-17,2011-10-11
-6u5y,2019-12-04,2019-08-28
-4u5b,2014-08-13,2014-07-25
-6u5n,2020-03-25,2019-08-28
-6u5v,2019-10-16,2019-08-28
-1u59,2004-08-17,2004-07-27
-5u5g,2017-01-04,2016-12-06
-7u55,2022-09-07,2022-03-01
-5u5x,2017-02-01,2016-12-07
-5u53,2017-06-28,2016-12-06
-3u5m,2012-01-18,2011-10-11
-8u5a,2024-01-17,2023-09-12
-5u57,2017-01-04,2016-12-06
-4u5u,2015-05-13,2014-07-25
-7u56,2022-03-09,2022-03-01
-4u50,2014-10-22,2014-07-24
-7u5w,2023-03-15,2022-03-02
-7u5x,2023-03-15,2022-03-02
-4u55,2014-10-22,2014-07-24
-4u5n,2015-05-13,2014-07-25
-4u5c,2014-08-13,2014-07-25
-7u5c,2022-05-18,2022-03-02
-5u5t,2017-01-11,2016-12-07
-3u56,2012-10-31,2011-10-11
-4u5f,2014-08-13,2014-07-24
-4u58,2015-05-13,2014-07-24
-5u5h,2017-01-11,2016-12-06
-3u5k,2011-11-23,2011-10-11
-4u53,2014-10-22,2014-07-24
-8u51,2024-04-24,2023-09-11
-6u5u,2019-10-16,2019-08-28
-1iru,2002-05-22,2001-10-24
-4ir6,2013-01-23,2013-01-14
-8iru,2023-06-21,2023-03-19
-1ir6,2002-05-15,2001-09-11
-1irv,1997-01-11,1996-06-27
-3irh,2009-09-22,2009-08-24
-5ir4,2016-08-10,2016-03-12
-2iry,2007-01-02,2006-10-16
-5iro,2016-08-24,2016-03-14
-1ira,1998-06-17,1998-04-09
-6ir7,2019-04-03,2018-11-12
-5irp,2017-03-29,2016-03-14
-8iro,2024-01-17,2023-03-19
-3irp,2010-09-08,2009-08-24
-4irc,2013-04-10,2013-01-14
-5irl,2016-06-29,2016-03-14
-8ire,2024-01-17,2023-03-17
-8irn,2024-01-17,2023-03-19
-4ir0,2013-01-23,2013-01-14
-8iri,2024-01-17,2023-03-17
-6iro,2019-04-03,2018-11-13
-3irm,2010-07-28,2009-08-24
-4irx,2013-03-20,2013-01-15
-5ir5,2016-08-10,2016-03-12
-6irt,2019-03-27,2018-11-14
-6irs,2019-03-27,2018-11-14
-4irz,2013-09-25,2013-01-15
-3ir9,2009-09-01,2009-08-21
-6ir9,2019-02-20,2018-11-12
-3irs,2009-09-01,2009-08-24
-4ir5,2013-01-23,2013-01-14
-8irf,2024-01-17,2023-03-17
-8irk,2024-03-06,2023-03-18
-1irc,1996-07-11,1995-12-19
-4ird,2013-04-10,2013-01-14
-8irh,2024-01-17,2023-03-17
-3ir4,2009-09-01,2009-08-21
-8ir2,2023-11-15,2023-03-17
-8ir7,2024-01-17,2023-03-17
-8irb,2024-01-17,2023-03-17
-3ir7,2010-01-05,2009-08-21
-4irp,2013-09-25,2013-01-15
-4irr,2014-01-29,2013-01-15
-4irl,2013-08-07,2013-01-15
-6ird,2019-01-23,2018-11-12
-5ire,2016-03-30,2016-03-13
-1ir1,2002-03-13,2001-08-31
-5irf,2016-05-04,2016-03-13
-6irw,2018-12-05,2018-11-14
-3ir6,2010-01-05,2009-08-21
-4irm,2013-02-06,2013-01-15
-4irw,2014-01-29,2013-01-15
-8irv,2023-06-07,2023-03-19
-8ir3,2023-08-09,2023-03-17
-4ira,2014-01-29,2013-01-14
-6ir0,2019-11-13,2018-11-09
-6iry,2018-12-05,2018-11-14
-6irz,2018-12-05,2018-11-15
-3ir0,2010-09-01,2009-08-21
-5irm,2016-06-29,2016-03-14
-8ir8,2024-01-17,2023-03-17
-4iru,2013-07-10,2013-01-15
-1irb,1997-12-24,1997-08-13
-6irl,2020-03-18,2018-11-13
-8irl,2024-01-17,2023-03-19
-4ir7,2013-05-08,2013-01-14
-3irb,2009-09-01,2009-08-21
-5irv,2017-03-15,2016-03-14
-1irw,1997-01-11,1996-06-27
-8irm,2024-01-17,2023-03-19
-4ire,2013-04-24,2013-01-14
-8ir9,2024-01-17,2023-03-17
-8irr,2023-06-21,2023-03-19
-5ir1,2016-10-26,2016-03-11
-1ird,2001-10-17,2001-09-27
-8irc,2024-01-17,2023-03-17
-8ir5,2024-01-17,2023-03-17
-1irj,2002-02-27,2001-10-09
-3ir1,2009-10-13,2009-08-21
-5irn,2016-06-29,2016-03-14
-6ir8,2019-02-20,2018-11-12
-4iro,2013-02-20,2013-01-15
-5irg,2016-05-04,2016-03-13
-6irk,2019-05-22,2018-11-13
-4ir1,2013-04-10,2013-01-14
-8irt,2023-06-07,2023-03-19
-8ir4,2023-11-15,2023-03-17
-3irx,2010-04-07,2009-08-24
-3ir5,2010-01-05,2009-08-21
-3ird,2009-09-22,2009-08-22
-8iry,2024-03-06,2023-03-20
-5irr,2017-04-26,2016-03-14
-8irg,2024-01-17,2023-03-17
-5irb,2017-07-19,2016-03-12
-1ir3,1998-01-07,1997-09-22
-5irq,2017-03-15,2016-03-14
-2irx,2007-01-02,2006-10-16
-3iru,2009-09-01,2009-08-24
-5ira,2016-08-31,2016-03-12
-1irn,1996-04-03,1995-12-13
-3irn,2010-07-28,2009-08-24
-2irz,2006-11-14,2006-10-16
-8ir6,2024-01-17,2023-03-17
-1irx,2002-04-17,2001-10-25
-5ir6,2016-05-04,2016-03-12
-1iri,2002-06-05,2001-10-08
-4ir9,2013-04-17,2013-01-14
-8irs,2023-06-07,2023-03-19
-2irw,2007-01-23,2006-10-16
-3iro,2010-07-28,2009-08-24
-8irz,2024-03-06,2023-03-20
-4ir3,2013-01-23,2013-01-14
-1iro,1996-04-03,1995-12-13
-1ir2,2002-03-20,2001-09-03
-5irw,2016-10-12,2016-03-14
-4irn,2013-11-27,2013-01-15
-3ir2,2010-01-12,2009-08-21
-6irj,2019-05-22,2018-11-13
-5irx,2016-05-25,2016-03-14
-8ira,2024-01-17,2023-03-17
-4irj,2013-08-28,2013-01-14
-8ird,2024-01-17,2023-03-17
-4ir4,2013-01-23,2013-01-14
-1ire,2002-10-01,2001-10-01
-8ir1,2023-08-09,2023-03-17
-2irf,1999-10-08,1999-05-30
-4irk,2013-04-17,2013-01-14
-4irq,2013-09-25,2013-01-15
-5iry,2016-06-22,2016-03-15
-5irz,2016-05-25,2016-03-15
-5irc,2016-08-17,2016-03-12
-5iru,2016-10-12,2016-03-14
-4irs,2013-09-04,2013-01-15
-8irp,2024-01-17,2023-03-19
-3m9e,2010-08-18,2010-03-22
-7m93,2021-12-15,2021-03-30
-3m98,2011-03-02,2010-03-21
-6m90,2019-04-03,2018-08-22
-2m98,2014-01-29,2013-06-04
-3m9n,2010-06-16,2010-03-22
-4m92,2014-03-26,2013-08-14
-3m9o,2010-06-16,2010-03-22
-7m9n,2022-04-20,2021-03-31
-2m9j,2013-06-26,2013-06-10
-4m91,2014-03-26,2013-08-14
-3m9x,2010-08-18,2010-03-22
-4m9q,2013-11-06,2013-08-15
-7m96,2021-12-15,2021-03-30
-5m92,2017-07-12,2016-10-31
-7m90,2021-06-30,2021-03-30
-2m96,2014-06-04,2013-06-03
-5m95,2016-11-30,2016-10-31
-2m9a,2013-07-24,2013-06-05
-7m94,2021-12-15,2021-03-30
-6m9m,2018-10-10,2018-08-23
-6m95,2019-04-17,2018-08-22
-6m91,2019-04-03,2018-08-22
-1m9j,2002-08-14,2002-07-29
-4m99,2013-10-02,2013-08-14
-6m9r,2019-02-06,2018-08-24
-4m9z,2013-10-23,2013-08-15
-7m9x,2022-08-31,2021-03-31
-1m9o,2003-06-03,2002-07-29
-4m9x,2013-10-23,2013-08-15
-4m9u,2013-08-28,2013-08-15
-7m9b,2021-07-28,2021-03-30
-6m92,2019-04-03,2018-08-22
-3m92,2010-05-19,2010-03-19
-6m98,2019-04-03,2018-08-22
-7m9o,2022-04-20,2021-03-31
-3m93,2011-07-20,2010-03-19
-6m9s,2019-02-06,2018-08-24
-5m96,2016-12-14,2016-10-31
-5m9f,2017-12-20,2016-11-01
-6m9h,2018-09-05,2018-08-23
-1m9m,2002-08-07,2002-07-29
-6m9d,2018-10-24,2018-08-23
-7m9k,2022-04-20,2021-03-31
-5m9w,2017-08-16,2016-11-02
-5m99,2017-07-19,2016-11-01
-1m9n,2003-01-07,2002-07-29
-1m9q,2002-08-07,2002-07-29
-7m9q,2022-04-06,2021-03-31
-4m95,2014-03-12,2013-08-14
-5m90,2017-07-12,2016-10-31
-4m9a,2013-11-13,2013-08-14
-6m9a,2018-11-14,2018-08-23
-6m96,2019-03-06,2018-08-22
-3m9m,2010-06-16,2010-03-22
-7m9f,2022-04-06,2021-03-31
-4m9y,2013-10-23,2013-08-15
-6m94,2019-04-03,2018-08-22
-3m9v,2010-04-07,2010-03-22
-4m9b,2013-11-27,2013-08-14
-2m9w,2013-07-10,2013-06-20
-3m9s,2010-05-26,2010-03-22
-3m94,2011-07-20,2010-03-19
-6m9w,2019-07-31,2018-08-24
-5m9n,2016-11-16,2016-11-01
-3m9g,2010-11-03,2010-03-22
-4m9j,2013-10-16,2013-08-14
-7m9u,2022-08-31,2021-03-31
-6m9b,2019-04-17,2018-08-23
-4m94,2014-03-12,2013-08-14
-1m9i,2002-08-07,2002-07-29
-7m9a,2021-07-28,2021-03-30
-5m9z,2017-08-02,2016-11-02
-7m9l,2022-04-06,2021-03-31
-1m9b,2003-03-04,2002-07-28
-7m9c,2021-07-28,2021-03-30
-4m9d,2013-08-28,2013-08-14
-7m9r,2022-04-06,2021-03-31
-6m9l,2019-04-17,2018-08-23
-6m9f,2018-10-24,2018-08-23
-6m99,2018-09-05,2018-08-23
-7m9m,2022-04-20,2021-03-31
-7m95,2021-12-15,2021-03-30
-3m96,2011-02-02,2010-03-20
-4m9v,2013-11-27,2013-08-15
-7m9g,2022-04-27,2021-03-31
-2m9r,2013-09-11,2013-06-19
-6m93,2019-04-03,2018-08-22
-1m9a,2003-03-04,2002-07-28
-3m99,2010-05-05,2010-03-21
-5m9x,2017-12-20,2016-11-02
-1m90,2002-09-06,2002-07-26
-1m99,2003-03-04,2002-07-28
-2m9f,2013-06-26,2013-06-07
-6m97,2019-04-03,2018-08-22
-6m9t,2018-12-05,2018-08-24
-3m9y,2011-04-06,2010-03-23
-1m9p,2003-08-12,2002-07-29
-3m97,2010-07-21,2010-03-20
-4m9w,2013-11-27,2013-08-15
-5m9v,2017-02-22,2016-11-02
-7m9p,2022-04-20,2021-03-31
-7m9w,2022-08-31,2021-03-31
-7m9h,2022-04-27,2021-03-31
-7m9i,2022-04-27,2021-03-31
-2m9s,2013-09-11,2013-06-19
-4m9g,2013-10-16,2013-08-14
-2m9y,2013-11-13,2013-06-24
-7m91,2021-06-30,2021-03-30
-5m91,2017-07-12,2016-10-31
-7m9v,2022-08-31,2021-03-31
-1m9k,2002-08-14,2002-07-29
-1m9s,2002-11-06,2002-07-29
-1m9t,2002-09-11,2002-09-05
-7m98,2021-09-22,2021-03-30
-4m9l,2013-10-16,2013-08-14
-5m93,2016-12-14,2016-10-31
-4m9s,2013-10-23,2013-08-15
-6m9c,2018-10-24,2018-08-23
-7m9z,2022-04-27,2021-03-31
-5m9o,2016-12-07,2016-11-01
-7m99,2021-07-28,2021-03-30
-4m9e,2014-02-12,2013-08-14
-7m9j,2022-04-27,2021-03-31
-1m9h,2003-08-12,2002-07-29
-7m9s,2022-08-31,2021-03-31
-1m9r,2002-08-14,2002-07-29
-7m9t,2022-08-31,2021-03-31
-4m9n,2013-10-16,2013-08-14
-4m9h,2013-10-16,2013-08-14
-3m9f,2010-06-30,2010-03-22
-4m93,2014-04-09,2013-08-14
-3wlv,2014-06-18,2013-11-14
-4wld,2015-04-08,2014-10-07
-3wlj,2015-03-25,2013-11-12
-5wly,2018-04-11,2017-07-28
-5wlw,2017-11-15,2017-07-27
-3wli,2015-03-25,2013-11-12
-2wle,2009-06-30,2009-06-23
-5wls,2018-06-06,2017-07-27
-5wlt,2018-08-01,2017-07-27
-7wly,2022-05-25,2022-01-14
-1wl7,2005-06-21,2004-06-21
-5wlv,2018-08-01,2017-07-27
-2wlq,2010-01-26,2009-06-24
-7wl4,2022-08-10,2022-01-12
-7wlw,2022-06-29,2022-01-13
-6wl4,2020-12-23,2020-04-18
-4wlb,2014-11-12,2014-10-07
-2wlf,2009-06-30,2009-06-23
-7wlk,2022-05-04,2022-01-13
-2wl3,2010-09-01,2009-06-21
-1wlw,2005-06-07,2004-06-30
-7wlp,2022-11-16,2022-01-13
-7wl6,2022-11-23,2022-01-12
-3wl7,2014-09-24,2013-11-08
-6wlz,2020-11-11,2020-04-20
-2wlg,2009-06-30,2009-06-23
-2wl5,2009-11-03,2009-06-22
-4wlk,2015-07-08,2014-10-07
-2wlu,2009-09-15,2009-06-26
-5wlk,2018-01-03,2017-07-27
-3wlq,2015-03-25,2013-11-12
-2wlk,2010-06-09,2009-06-24
-3wlf,2014-07-16,2013-11-09
-3wln,2015-03-25,2013-11-12
-7wld,2022-04-27,2022-01-13
-3wld,2014-01-22,2013-11-08
-4wlv,2015-11-25,2014-10-08
-3wlc,2014-01-22,2013-11-08
-6wlx,2020-06-24,2020-04-20
-5wlf,2017-10-04,2017-07-26
-3wlu,2014-11-05,2013-11-14
-2wl0,2009-12-15,2009-06-19
-6wl3,2020-12-23,2020-04-18
-3wll,2015-03-25,2013-11-12
-3wle,2014-07-16,2013-11-08
-6wl6,2020-08-19,2020-04-18
-4wlx,2015-04-08,2014-10-08
-5wlg,2017-11-15,2017-07-26
-6wlh,2021-03-03,2020-04-20
-1wl6,2005-08-16,2004-06-21
-1wl9,2005-08-16,2004-06-22
-4wlo,2015-11-25,2014-10-07
-3wlk,2015-03-25,2013-11-12
-1wle,2005-09-06,2004-06-25
-1wl4,2005-03-01,2004-06-20
-6wlv,2020-07-15,2020-04-20
-3wlr,2015-03-25,2013-11-12
-6wlb,2020-07-22,2020-04-19
-2wl9,2010-09-01,2009-06-23
-5wlr,2018-08-01,2017-07-27
-1wld,2005-06-07,2004-06-22
-2wlt,2009-11-24,2009-06-25
-7wlz,2022-05-25,2022-01-14
-5wll,2018-01-03,2017-07-27
-8wlo,2024-03-27,2023-09-30
-1wla,1998-01-14,1997-09-24
-7wln,2022-08-10,2022-01-13
-5wli,2017-11-15,2017-07-27
-4wl9,2014-12-17,2014-10-06
-5wle,2017-10-04,2017-07-26
-5wlc,2017-09-27,2017-07-26
-3wlh,2015-03-25,2013-11-12
-5wlo,2017-10-11,2017-07-27
-4wlc,2015-08-26,2014-10-07
-4wl8,2015-10-21,2014-10-06
-3wl3,2014-05-07,2013-11-07
-1wlk,2005-07-19,2004-06-28
-4wlz,2015-11-04,2014-10-08
-7wlf,2023-01-18,2022-01-13
-7wlx,2022-05-18,2022-01-14
-6wle,2021-03-03,2020-04-20
-2wln,2010-06-09,2009-06-24
-3wlp,2015-03-25,2013-11-12
-4wly,2015-04-08,2014-10-08
-4wlj,2014-12-03,2014-10-07
-4wlu,2015-11-25,2014-10-08
-2wlh,2010-06-09,2009-06-24
-4wlw,2015-09-02,2014-10-08
-7wlj,2022-05-04,2022-01-13
-3wlm,2015-03-25,2013-11-12
-3wl2,2014-11-12,2013-11-06
-3wlw,2015-05-27,2013-11-15
-3wl8,2014-09-24,2013-11-08
-5wlu,2018-08-01,2017-07-27
-7wl5,2023-01-18,2022-01-12
-4wlm,2015-09-30,2014-10-07
-4wlt,2015-04-08,2014-10-08
-3wl0,2014-04-09,2013-11-05
-3wlo,2015-03-25,2013-11-12
-1wli,2005-07-19,2004-06-28
-5wlj,2018-01-03,2017-07-27
-2wlz,2010-03-16,2009-06-29
-4wla,2014-12-17,2014-10-06
-1wlj,2004-12-21,2004-06-28
-5wl0,2017-09-06,2017-07-25
-2wll,2010-06-09,2009-06-24
-3wl4,2014-05-07,2013-11-07
-6wl2,2020-12-23,2020-04-18
-8wl7,2023-10-25,2023-09-29
-6wlw,2020-11-11,2020-04-20
-1wlv,2005-07-05,2004-06-29
-5wlq,2017-08-09,2017-07-27
-2wli,2010-06-09,2009-06-24
-6wly,2020-06-24,2020-04-20
-5wlm,2018-01-03,2017-07-27
-7wli,2022-05-04,2022-01-13
-6wlf,2020-06-17,2020-04-20
-7wl0,2022-03-30,2022-01-12
-2wls,2009-09-08,2009-06-25
-7wll,2022-05-04,2022-01-13
-8wlb,2023-10-25,2023-09-29
-5wl1,2017-11-01,2017-07-25
-4wl4,2015-10-14,2014-10-06
-2wly,2010-03-16,2009-06-29
-2wlm,2010-06-09,2009-06-24
-7wlm,2022-11-23,2022-01-13
-2wl4,2009-11-03,2009-06-22
-5wlb,2018-01-03,2017-07-26
-6wlc,2020-04-29,2020-04-19
-2wlo,2010-06-23,2009-06-24
-2wlj,2010-06-09,2009-06-24
-6wlp,2021-03-03,2020-04-20
-3wl1,2014-04-09,2013-11-05
-8wlr,2024-03-27,2023-09-30
-8wl9,2023-10-25,2023-09-29
-3wlx,2014-12-17,2013-11-15
-1v2a,2003-10-28,2003-10-10
-3v2w,2012-02-15,2011-12-12
-5v27,2018-03-07,2017-03-02
-6v29,2020-05-20,2019-11-22
-1v2g,2004-12-14,2003-10-15
-1v2b,2004-05-18,2003-10-14
-2v2w,2007-11-06,2007-06-07
-4v20,2015-01-14,2014-10-05
-5v2k,2017-05-03,2017-03-04
-3v2u,2012-02-08,2011-12-12
-4v2i,2016-01-13,2014-10-10
-4v24,2014-10-15,2014-10-05
-7v25,2021-12-15,2021-08-07
-6v2n,2019-12-25,2019-11-25
-5v2z,2017-08-16,2017-03-06
-7v2j,2022-08-17,2021-08-09
-3v2k,2012-01-18,2011-12-12
-6v2a,2020-05-20,2019-11-22
-4v2y,2014-12-17,2014-10-15
-7v2a,2021-10-20,2021-08-07
-1v2l,2004-06-01,2003-10-17
-1v2q,2004-06-01,2003-10-17
-5v28,2018-03-07,2017-03-02
-1v2s,2004-06-01,2003-10-17
-7v2c,2022-03-02,2021-08-08
-5v24,2017-03-29,2017-03-02
-6v2k,2020-11-25,2019-11-24
-5v2y,2017-08-16,2017-03-06
-3v2z,2012-11-21,2011-12-12
-6v24,2020-05-20,2019-11-22
-7v2o,2022-04-06,2021-08-09
-2v2r,2008-06-24,2007-06-06
-2v25,2007-06-26,2007-06-01
-1v2w,2004-06-01,2003-10-17
-7v23,2022-08-10,2021-08-07
-2v23,2007-12-04,2007-05-31
-5v2g,2017-09-27,2017-03-03
-2v2c,2008-02-19,2007-06-05
-1v2d,2004-07-06,2003-10-15
-2v2z,2007-06-19,2007-06-08
-5v2x,2017-08-16,2017-03-06
-2v2b,2008-01-08,2007-06-04
-4v2g,2014-12-10,2014-10-09
-5v2t,2017-08-16,2017-03-06
-1v2v,2004-06-01,2003-10-17
-5v2l,2017-10-18,2017-03-05
-1v25,2004-07-27,2003-10-07
-6v25,2020-05-20,2019-11-22
-3v2j,2012-12-26,2011-12-12
-4v2v,2014-11-05,2014-10-15
-5v2w,2017-08-23,2017-03-06
-4v23,2015-02-25,2014-10-05
-3v2i,2012-01-11,2011-12-12
-7v2q,2022-04-06,2021-08-09
-2v2v,2007-06-19,2007-06-07
-1v2i,2004-02-03,2003-10-16
-3v2y,2012-02-15,2011-12-12
-7v27,2022-08-10,2021-08-07
-2v2f,2007-12-25,2007-06-05
-1v2j,2004-06-01,2003-10-17
-4v2w,2014-11-26,2014-10-15
-1v26,2004-07-27,2003-10-07
-1v2h,2004-01-13,2003-10-16
-8v2k,2023-12-06,2023-11-22
-7v2l,2022-04-06,2021-08-09
-4v2o,2015-12-09,2014-10-13
-5v21,2017-03-22,2017-03-02
-7v2b,2022-04-06,2021-08-08
-2v2l,2008-06-24,2007-06-06
-2v21,2007-09-11,2007-05-31
-6v2f,2020-07-01,2019-11-22
-7v2h,2022-03-02,2021-08-09
-6v2w,2020-12-02,2019-11-25
-7v2z,2022-08-17,2021-08-10
-6v2m,2019-12-11,2019-11-25
-6v2t,2020-01-08,2019-11-25
-7v29,2022-03-30,2021-08-07
-2v2p,2008-06-24,2007-06-06
-4v25,2014-12-03,2014-10-06
-7v2r,2022-03-02,2021-08-09
-7v2u,2023-02-15,2021-08-09
-4v28,2014-12-24,2014-10-07
-1v2x,2004-05-04,2003-10-17
-1v2f,2004-07-06,2003-10-15
-7v2t,2023-02-15,2021-08-09
-5v2p,2017-07-19,2017-03-06
-7v26,2021-10-20,2021-08-07
-5v2c,2017-08-30,2017-03-03
-2v20,2008-06-24,2007-05-31
-2v29,2008-01-08,2007-06-04
-2v24,2007-07-17,2007-05-31
-1v2r,2004-06-01,2003-10-17
-8v2n,2023-12-06,2023-11-23
-5v2v,2017-08-16,2017-03-06
-4v2a,2014-11-05,2014-10-08
-2v2a,2008-01-08,2007-06-04
-6v2l,2019-12-11,2019-11-25
-2v2s,2008-06-24,2007-06-06
-4v26,2014-12-03,2014-10-06
-4v2x,2015-02-25,2014-10-15
-2v2o,2008-06-24,2007-06-06
-1v2k,2004-06-01,2003-10-17
-5v26,2018-03-07,2017-03-02
-5v2j,2017-05-03,2017-03-04
-6v22,2019-12-25,2019-11-22
-7v2e,2022-03-02,2021-08-08
-8v2t,2023-12-06,2023-11-23
-4v2p,2015-08-26,2014-10-13
-7v2n,2022-04-06,2021-08-09
-2v2m,2008-06-24,2007-06-06
-3v2t,2011-12-28,2011-12-12
-8v2o,2024-05-01,2023-11-23
-2v26,2007-11-20,2007-06-03
-2v2q,2007-06-19,2007-06-06
-2v2j,2008-06-24,2007-06-06
-2v27,2007-06-19,2007-06-03
-7v2p,2022-04-06,2021-08-09
-7v2d,2022-03-02,2021-08-08
-1v2u,2004-06-01,2003-10-17
-4v29,2014-12-17,2014-10-07
-6v2q,2020-05-20,2019-11-25
-2v22,2008-01-29,2007-05-31
-6v2h,2019-12-25,2019-11-22
-8v2z,2024-05-01,2023-11-25
-7v2m,2022-04-06,2021-08-09
-7v2k,2022-03-02,2021-08-09
-5v2a,2017-04-05,2017-03-03
-1v2e,2004-07-06,2003-10-15
-1v2p,2004-06-01,2003-10-17
-2v2x,2007-11-06,2007-06-07
-7v20,2022-08-10,2021-08-07
-3v2v,2012-11-21,2011-12-12
-4v2z,2014-12-17,2014-10-15
-8v2i,,2023-11-22
-4v27,2014-12-24,2014-10-07
-5v2q,2017-07-19,2017-03-06
-8v24,2024-04-24,2023-11-21
-6v2b,2020-05-20,2019-11-22
-6v2u,2020-12-02,2019-11-25
-4v2k,2015-02-18,2014-10-10
-3v2m,2012-12-26,2011-12-12
-1v2n,2004-06-01,2003-10-17
-7v28,2021-12-15,2021-08-07
-1v2t,2004-06-01,2003-10-17
-6v2e,2020-08-05,2019-11-22
-5v2d,2018-03-07,2017-03-03
-3v20,2012-04-25,2011-12-11
-3v2b,2011-12-21,2011-12-12
-6v2r,2019-12-25,2019-11-25
-2v2n,2008-06-24,2007-06-06
-7v2f,2022-03-02,2021-08-09
-6v26,2020-05-20,2019-11-22
-2v2i,2008-06-24,2007-06-06
-2v2h,2008-02-19,2007-06-06
-5v2s,2018-05-16,2017-03-06
-8v2y,2024-03-13,2023-11-24
-1v29,2004-10-09,2003-10-09
-5v22,2017-03-22,2017-03-02
-7v2x,2023-02-15,2021-08-10
-2v2e,2007-12-04,2007-06-05
-1v2o,2004-06-01,2003-10-17
-5v2o,2017-10-04,2017-03-06
-6zlz,2020-08-05,2020-07-01
-1zl1,2005-05-17,2005-05-05
-1zl6,2005-06-28,2005-05-05
-4zlb,2016-03-23,2015-05-01
-1zlr,2006-05-09,2005-05-09
-4zlf,2015-06-10,2015-05-01
-2zlw,2008-06-24,2008-04-10
-7zl3,2023-03-22,2022-04-13
-4zli,2015-06-10,2015-05-01
-4zl4,2015-07-15,2015-05-01
-6zlj,2020-07-29,2020-06-30
-6zl4,2021-01-27,2020-06-30
-5zlj,2018-05-16,2018-03-28
-7zlp,2023-04-26,2022-04-15
-5zln,2018-04-25,2018-03-28
-4zlo,2015-08-05,2015-05-01
-6zlw,2020-07-29,2020-07-01
-1zle,2005-08-16,2005-05-06
-1zlq,2005-08-02,2005-05-09
-1zlt,2006-06-27,2005-05-09
-5zlu,2018-08-01,2018-03-29
-1zl7,2006-04-25,2005-05-05
-3zls,2013-05-22,2013-02-04
-3zli,2013-02-27,2013-01-31
-4zlh,2015-11-11,2015-05-01
-7zlt,2023-05-10,2022-04-15
-5zlp,2018-08-29,2018-03-29
-6zlf,2020-11-25,2020-06-30
-5zla,2018-12-19,2018-03-27
-7zlk,2022-09-21,2022-04-15
-6zl7,2020-07-08,2020-06-30
-6zll,2020-07-29,2020-06-30
-2zlg,2008-08-19,2008-04-09
-2zl4,2008-04-22,2008-04-02
-6zlh,2021-01-27,2020-06-30
-6zld,2020-07-29,2020-06-30
-2zlc,2008-06-24,2008-04-04
-3zlu,2013-03-27,2013-02-04
-4zla,2015-12-23,2015-05-01
-7zl7,2022-08-31,2022-04-14
-1zl2,2006-05-09,2005-05-05
-7zlc,2022-12-28,2022-04-14
-7zlu,2022-06-22,2022-04-15
-7zln,2023-04-26,2022-04-15
-4zlw,2015-09-30,2015-05-01
-5zlt,2018-05-16,2018-03-29
-3zlx,2013-05-22,2013-02-04
-2zl9,2008-06-24,2008-04-04
-6zl6,2020-07-29,2020-06-30
-3zlm,2013-06-19,2013-02-01
-4zlg,2015-06-10,2015-05-01
-3zlv,2013-03-27,2013-02-04
-6zlr,2020-12-23,2020-07-01
-4zl6,2015-09-30,2015-05-01
-4zl5,2015-09-30,2015-05-01
-4zlk,2016-05-04,2015-05-01
-6zlq,2021-07-14,2020-07-01
-7zld,2022-12-28,2022-04-14
-2zl6,2008-07-22,2008-04-02
-3zl6,2014-02-12,2013-01-28
-4zlv,2015-05-20,2015-05-01
-1zl0,2005-06-21,2005-05-04
-6zlp,2021-05-19,2020-06-30
-4zlt,2015-11-18,2015-05-01
-7zle,2022-06-22,2022-04-14
-4zlu,2015-09-16,2015-05-01
-5zlc,2019-05-29,2018-03-27
-7zlj,2023-01-11,2022-04-15
-3zlb,2014-02-12,2013-01-30
-6zln,2020-08-26,2020-06-30
-5zl1,2019-04-10,2018-03-26
-7zls,2023-04-26,2022-04-15
-7zl6,2023-04-26,2022-04-14
-6zlb,2021-05-19,2020-06-30
-3zln,2013-04-24,2013-02-04
-3zl1,2013-07-10,2013-01-27
-7zlo,2023-04-26,2022-04-15
-5zlm,2018-05-16,2018-03-28
-5zl6,2018-11-28,2018-03-27
-7zlm,2023-04-26,2022-04-15
-1zli,2005-07-05,2005-05-06
-4zlz,2015-07-01,2015-05-01
-1zl9,2005-05-17,2005-05-05
-5zlf,2019-03-27,2018-03-27
-7zlz,2023-04-05,2022-04-17
-5zlv,2018-11-07,2018-03-29
-4zly,2015-07-01,2015-05-01
-6zl3,2020-08-19,2020-06-30
-3zlz,2013-04-10,2013-02-04
-6zly,2020-11-25,2020-07-01
-3zlt,2013-03-27,2013-02-04
-6zlx,2021-07-14,2020-07-01
-7zli,2023-01-11,2022-04-15
-3zlq,2013-05-01,2013-02-04
-5zll,2018-05-16,2018-03-28
-6zlk,2020-07-29,2020-06-30
-3zle,2013-08-28,2013-01-30
-7zll,2023-04-26,2022-04-15
-5zle,2018-10-31,2018-03-27
-3zl2,2013-07-10,2013-01-27
-7zlr,2023-04-26,2022-04-15
-3zlo,2013-04-24,2013-02-04
-2zlv,2008-06-24,2008-04-10
-7zlw,2023-08-09,2022-04-15
-2zlt,2008-06-24,2008-04-10
-5zl4,2018-12-19,2018-03-26
-3zly,2013-05-22,2013-02-04
-3zlk,2013-02-20,2013-02-01
-3zlr,2013-04-24,2013-02-04
-4zlp,2015-08-19,2015-05-01
-5zlk,2018-05-16,2018-03-28
-3zll,2013-02-20,2013-02-01
-6zla,2020-07-29,2020-06-30
-7zl1,2022-08-03,2022-04-13
-6zli,2020-08-19,2020-06-30
-2zla,2008-06-24,2008-04-04
-2zlu,2008-06-24,2008-04-10
-7zlg,2023-01-11,2022-04-15
-5zlq,2018-10-10,2018-03-29
-2zl2,2008-04-22,2008-04-02
-7zl8,2023-08-09,2022-04-14
-3zl8,2013-09-11,2013-01-29
-2zl8,2008-08-05,2008-04-03
-6zl5,2020-08-19,2020-06-30
-1zly,2005-08-23,2005-05-09
-2zl7,2008-07-22,2008-04-02
-1zlf,2006-04-25,2005-05-06
-5zlr,2018-05-16,2018-03-29
-7zl5,2023-04-26,2022-04-14
-4zl1,2016-05-04,2015-05-01
-2zlf,2008-08-19,2008-04-09
-2zl5,2008-07-22,2008-04-02
-2zlx,2008-06-24,2008-04-10
-1zlp,2006-01-03,2005-05-08
-1zlh,2005-07-05,2005-05-06
-3zlw,2013-05-22,2013-02-04
-4zls,2015-07-15,2015-05-01
-5zlg,2018-10-31,2018-03-27
-1v9l,2004-12-14,2004-01-26
-7v9p,2022-05-11,2021-08-26
-8v9h,2024-04-03,2023-12-08
-2v9n,2008-01-15,2007-08-24
-3v98,2012-05-02,2011-12-23
-2v9w,2007-10-30,2007-08-27
-2v9c,2007-11-13,2007-08-23
-7v99,2022-03-30,2021-08-24
-6v9u,2020-08-12,2019-12-16
-1v97,2004-06-22,2004-01-21
-5v9t,2017-05-10,2017-03-23
-5v9f,2017-04-12,2017-03-23
-3v9w,2012-07-11,2011-12-28
-3v95,2012-02-22,2011-12-23
-7v9d,2022-09-07,2021-08-24
-4v9i,2014-07-09,2013-04-04
-7v9o,2022-05-11,2021-08-26
-5v91,2017-08-30,2017-03-22
-4v9b,2014-07-09,2012-07-18
-7v9x,2022-08-31,2021-08-27
-1v9p,2004-03-30,2004-01-27
-1v98,2005-02-01,2004-01-21
-2v9v,2007-09-11,2007-08-27
-1v9u,2004-05-04,2004-02-03
-3v92,2012-05-02,2011-12-23
-6v93,2020-08-19,2019-12-13
-4v9f,2014-07-09,2012-11-02
-5v9h,2017-04-12,2017-03-23
-8v9g,2024-04-03,2023-12-08
-4v9h,2014-07-09,2013-03-25
-8v9l,2024-02-07,2023-12-08
-8v9p,2023-12-20,2023-12-08
-2v9o,2008-01-22,2007-08-24
-1v9e,2004-02-10,2004-01-26
-7v9q,2022-05-11,2021-08-26
-4v9k,2014-07-09,2013-04-24
-3v9o,2012-01-25,2011-12-27
-3v9s,2012-07-11,2011-12-28
-1v9q,2005-05-17,2004-01-29
-7v9n,2022-05-11,2021-08-26
-3v9z,2012-07-11,2011-12-28
-5v9p,2017-05-10,2017-03-23
-6v94,2020-08-26,2019-12-13
-6v9s,2020-07-15,2019-12-16
-2v97,2007-11-20,2007-08-22
-1v93,2004-02-03,2004-01-20
-5v9u,2018-02-07,2017-03-23
-6v9l,2020-08-26,2019-12-13
-6v90,2020-04-01,2019-12-12
-3v9k,2012-05-02,2011-12-27
-6v9p,2020-01-29,2019-12-14
-2v9f,2008-01-15,2007-08-23
-4v9m,2014-07-09,2013-04-25
-7v94,2022-04-13,2021-08-24
-3v91,2012-01-25,2011-12-23
-7v9u,2022-08-31,2021-08-26
-6v9f,2020-08-26,2019-12-13
-1v9y,2004-05-25,2004-02-04
-5v9o,2017-08-23,2017-03-23
-6v9e,2021-02-10,2019-12-13
-6v9o,2020-12-16,2019-12-13
-3v9u,2012-07-11,2011-12-28
-4v97,2014-07-09,2012-04-06
-6v9m,2020-08-26,2019-12-13
-5v96,2017-05-10,2017-03-23
-3v9m,2013-02-13,2011-12-27
-1v9n,2005-03-29,2004-01-26
-1v9o,2005-01-11,2004-01-27
-6v98,2020-01-15,2019-12-13
-5v95,2017-04-12,2017-03-23
-3v94,2012-02-22,2011-12-23
-6v9j,2020-08-26,2019-12-13
-1v9h,2004-10-05,2004-01-26
-2v92,2007-09-25,2007-08-20
-7v9b,2022-08-31,2021-08-24
-3v9x,2012-07-11,2011-12-28
-5v97,2017-04-12,2017-03-23
-3v96,2012-03-28,2011-12-23
-5v9l,2017-08-23,2017-03-23
-4v9a,2014-07-09,2012-07-18
-2v9x,2007-11-20,2007-08-28
-2v9j,2007-09-25,2007-08-23
-3v93,2012-02-22,2011-12-23
-8v9q,2024-03-13,2023-12-08
-3v97,2012-02-29,2011-12-23
-6v95,2020-10-28,2019-12-13
-6v9w,2020-05-06,2019-12-16
-2v96,2007-11-20,2007-08-22
-1v9x,2005-02-22,2004-02-04
-4v90,2014-07-09,2014-02-22
-7v97,2022-08-31,2021-08-24
-6v9q,2020-01-29,2019-12-15
-2v9p,2007-10-02,2007-08-24
-2v9e,2008-01-15,2007-08-23
-5v9x,2017-12-06,2017-03-23
-4v9g,2014-07-09,2013-02-21
-8v9j,2024-02-07,2023-12-08
-6v92,2020-01-15,2019-12-13
-1v9i,2004-02-10,2004-01-26
-2v9i,2008-01-15,2007-08-23
-4v9d,2014-07-09,2012-07-31
-6v9n,2020-08-26,2019-12-13
-2v93,2007-11-06,2007-08-21
-2v9q,2007-09-25,2007-08-25
-2v9l,2008-01-15,2007-08-24
-3v9v,2012-02-01,2011-12-28
-1v9t,2004-09-21,2004-02-03
-3v99,2012-05-02,2011-12-23
-2v9m,2008-01-15,2007-08-24
-3v9t,2012-02-01,2011-12-28
-3v9l,2012-05-02,2011-12-27
-4v99,2014-07-09,2012-07-04
-2v9k,2007-10-09,2007-08-23
-4v95,2014-07-09,2012-01-27
-6v9k,2020-06-17,2019-12-13
-4v9j,2014-07-09,2013-04-23
-3v9e,2013-01-23,2011-12-27
-3v9c,2012-02-22,2011-12-26
-1v9z,2004-05-25,2004-02-04
-2v98,2007-11-20,2007-08-22
-1v9a,2005-02-01,2004-01-23
-2v95,2007-09-04,2007-08-21
-6v9c,2020-03-25,2019-12-13
-3v9y,2012-02-01,2011-12-28
-6v9i,2020-04-29,2019-12-13
-3v9b,2012-01-18,2011-12-25
-2v9g,2008-01-22,2007-08-23
-4v9l,2014-07-09,2013-04-24
-4v94,2014-07-09,2012-01-11
-2v91,2008-09-16,2007-08-16
-5v9g,2017-04-12,2017-03-23
-8v9m,2024-05-08,2023-12-08
-8v9k,2024-02-07,2023-12-08
-4v9c,2014-07-09,2012-07-25
-8v9o,2024-05-15,2023-12-08
-5una,2017-03-08,2017-01-30
-8unz,2024-03-06,2023-10-19
-5unb,2017-02-15,2017-01-30
-3unz,2012-01-25,2011-11-16
-7unw,2022-06-22,2022-04-11
-8unn,2024-03-06,2023-10-19
-4unw,2014-07-23,2014-05-31
-7unl,2022-06-01,2022-04-11
-5un8,2017-03-15,2017-01-30
-1unj,2004-12-16,2003-09-10
-8un3,2023-12-20,2023-10-18
-7unc,2022-10-19,2022-04-10
-4unz,2014-07-23,2014-05-31
-6unq,2021-07-07,2019-10-13
-4una,2014-12-17,2014-05-26
-4uns,2015-06-17,2014-05-30
-6unh,2020-02-05,2019-10-11
-4un3,2014-07-23,2014-05-25
-4un8,2014-12-17,2014-05-26
-3uny,2012-02-29,2011-11-16
-6unr,2021-07-07,2019-10-13
-7uny,2022-11-23,2022-04-12
-4un9,2015-01-14,2014-05-26
-6uni,2020-02-05,2019-10-11
-5un1,2018-02-07,2017-01-30
-6unp,2021-07-07,2019-10-13
-7unf,2022-06-15,2022-04-10
-5uns,2017-05-03,2017-01-31
-4un4,2014-07-23,2014-05-25
-7un4,2022-10-05,2022-04-08
-6unj,2020-02-05,2019-10-12
-3unt,2012-11-14,2011-11-16
-4unq,2015-06-24,2014-05-30
-7uni,2023-04-19,2022-04-11
-8unl,2024-03-06,2023-10-19
-5unz,2017-05-03,2017-01-31
-7un2,2023-04-19,2022-04-08
-1ung,2004-11-10,2003-09-10
-7un7,2023-03-29,2022-04-09
-8un4,2023-12-20,2023-10-18
-1un1,2004-03-18,2003-09-03
-8uno,2024-03-06,2023-10-19
-8unq,2024-03-06,2023-10-19
-3unk,2012-01-25,2011-11-15
-5unx,2017-05-03,2017-01-31
-7unp,2023-04-05,2022-04-11
-4uni,2014-10-15,2014-05-28
-8unt,2024-03-06,2023-10-19
-7un1,2022-10-05,2022-04-08
-7und,2022-10-19,2022-04-10
-7unm,2022-06-29,2022-04-11
-6une,2020-02-05,2019-10-11
-5unr,2017-05-03,2017-01-31
-5unj,2017-04-19,2017-01-31
-4und,2015-06-17,2014-05-27
-8un7,2024-05-22,2023-10-18
-5unf,2017-04-05,2017-01-30
-7unz,2022-11-23,2022-04-12
-6un0,2020-07-15,2019-10-10
-3unc,2012-05-09,2011-11-15
-7una,2022-07-27,2022-04-09
-8un0,2024-05-08,2023-10-18
-5und,2017-05-24,2017-01-30
-3unx,2012-06-27,2011-11-16
-6unn,2020-10-14,2019-10-13
-8uny,2024-03-06,2023-10-19
-3und,2011-11-30,2011-11-15
-7unt,2022-06-22,2022-04-11
-3unh,2012-02-29,2011-11-15
-8unx,2024-03-06,2023-10-19
-7unu,2022-06-22,2022-04-11
-3un8,2012-02-29,2011-11-15
-3uni,2012-05-09,2011-11-15
-5un3,2017-02-22,2017-01-30
-3unj,2012-01-25,2011-11-15
-1uns,2003-11-13,2003-09-15
-6uns,2021-07-07,2019-10-13
-1un6,2003-11-20,2003-09-04
-6unc,2020-04-22,2019-10-11
-1unm,2004-09-24,2003-09-11
-3un2,2012-02-29,2011-11-15
-4uno,2014-06-11,2014-05-29
-7unb,2022-08-10,2022-04-10
-5unh,2017-04-05,2017-01-30
-6unm,2020-02-05,2019-10-12
-3unv,2012-02-22,2011-11-16
-4unc,2014-12-17,2014-05-26
-5ung,2017-04-05,2017-01-30
-6unb,2019-10-30,2019-10-11
-5un7,2017-04-12,2017-01-30
-3un9,2012-03-28,2011-11-15
-1unq,2004-09-16,2003-09-12
-8unp,2024-03-06,2023-10-19
-8unu,2024-03-06,2023-10-19
-5un9,2017-03-15,2017-01-30
-6und,2019-11-20,2019-10-11
-5unt,2017-05-03,2017-01-31
-1unf,2004-10-27,2003-09-10
-4unf,2015-06-10,2014-05-28
-3unn,2012-01-25,2011-11-16
-6unk,2020-02-05,2019-10-12
-5unp,2018-05-09,2017-01-31
-5unc,2017-02-22,2017-01-30
-5unu,2017-05-03,2017-01-31
-6unl,2020-02-05,2019-10-12
-6un8,2020-05-06,2019-10-11
-7ung,2022-10-05,2022-04-11
-3ung,2012-03-21,2011-11-15
-3un3,2012-02-29,2011-11-15
-8unr,2024-03-06,2023-10-19
-4un7,2014-12-03,2014-05-26
-4unp,2015-01-14,2014-05-30
-3una,2012-05-09,2011-11-15
-5unv,2017-05-03,2017-01-31
-4unx,2014-07-23,2014-05-31
-3unb,2012-02-29,2011-11-15
-8un5,2023-12-20,2023-10-18
-8unm,2024-03-06,2023-10-19
-3unf,2012-02-29,2011-11-15
-6un2,2020-07-15,2019-10-10
-7unr,2022-06-22,2022-04-11
-1une,1998-05-06,1997-11-05
-7unj,2023-04-19,2022-04-11
-8unw,2024-03-06,2023-10-19
-3unq,2012-11-21,2011-11-16
-4uny,2014-07-23,2014-05-31
-8unh,2023-12-13,2023-10-19
-8unv,2024-03-06,2023-10-19
-4unn,2015-06-17,2014-05-29
-4un5,2014-07-23,2014-05-25
-1uno,2004-09-24,2003-09-11
-7un8,2022-07-27,2022-04-09
-1unl,2004-11-10,2003-09-10
-3uns,2012-11-21,2011-11-16
-3unw,2011-12-07,2011-11-16
-7unq,2022-06-22,2022-04-11
-4unb,2014-12-17,2014-05-26
-8unj,2024-05-08,2023-10-19
-5un2,2018-02-07,2017-01-30
-6unx,2020-02-05,2019-10-13
-3un4,2012-02-29,2011-11-15
-6un1,2019-10-30,2019-10-10
-1unh,2004-11-10,2003-09-10
-4un1,2014-06-11,2014-05-23
-1un9,2003-10-30,2003-09-08
-5uny,2017-05-03,2017-01-31
-1unb,2004-01-09,2003-09-09
-6un3,2019-10-30,2019-10-10
-8uns,2024-03-06,2023-10-19
-3un5,2012-02-29,2011-11-15
-7unv,2022-06-22,2022-04-11
-4unm,2015-06-10,2014-05-29
-8un9,2024-05-01,2023-10-18
-6ung,2020-02-05,2019-10-11
-5unw,2017-05-03,2017-01-31
-7un0,2022-10-05,2022-04-08
-7un9,2022-07-27,2022-04-09
-4unr,2015-06-17,2014-05-30
-3un6,2011-12-07,2011-11-15
-5jlh,2016-06-15,2016-04-27
-4jl8,2014-06-25,2013-03-12
-5jlu,2017-05-03,2016-04-27
-2jlp,2009-03-17,2008-09-14
-1jlb,2001-10-03,2001-07-16
-5jle,2016-11-02,2016-04-27
-4jl4,2014-03-12,2013-03-12
-7jl2,2020-12-09,2020-07-29
-6jll,2019-10-16,2019-03-06
-5jlf,2016-06-15,2016-04-27
-7jly,2021-07-28,2020-07-30
-7jlk,2021-03-31,2020-07-29
-1jlv,2002-07-16,2001-07-16
-5jlp,2017-05-03,2016-04-27
-4jlq,2013-04-03,2013-03-12
-6jli,2019-07-17,2019-03-06
-4jlh,2013-05-01,2013-03-12
-7jlm,2021-08-04,2020-07-29
-5jl6,2017-04-26,2016-04-26
-5jlx,2016-06-22,2016-04-27
-7jl7,2021-01-27,2020-07-29
-5jl7,2017-04-26,2016-04-26
-8jl0,2024-01-24,2023-06-02
-6jl6,2020-03-04,2019-03-04
-7jln,2021-03-31,2020-07-30
-8jlo,2023-11-15,2023-06-02
-4jlb,2014-06-25,2013-03-12
-8jli,2024-05-01,2023-06-02
-7jl1,2020-12-09,2020-07-29
-7jls,2021-06-09,2020-07-30
-4jlw,2013-10-30,2013-03-13
-1jl7,2002-07-16,2001-07-16
-4jlx,2013-06-12,2013-03-13
-2jld,2008-12-09,2008-09-08
-6jlo,2019-10-16,2019-03-06
-4jlm,2014-01-22,2013-03-12
-6jlj,2019-10-16,2019-03-06
-7jlg,2021-06-30,2020-07-29
-2jlu,2008-11-25,2008-09-15
-8jlh,2024-05-01,2023-06-02
-2jll,2009-11-17,2008-09-10
-4jlj,2014-01-22,2013-03-12
-5jlr,2017-05-03,2016-04-27
-2jla,2008-10-21,2008-09-05
-1jld,1997-12-03,1997-05-31
-8jlg,2024-05-01,2023-06-02
-6jln,2019-10-16,2019-03-06
-8jlr,2023-11-15,2023-06-02
-7jl0,2020-12-09,2020-07-29
-1jlg,2001-10-03,2001-07-16
-6jlg,2020-03-11,2019-03-05
-2jlb,2008-11-25,2008-09-07
-4jl5,2014-06-25,2013-03-12
-7jlu,2020-12-02,2020-07-30
-4jlo,2014-06-25,2013-03-12
-2jl1,2008-09-23,2008-09-02
-5jlc,2016-05-25,2016-04-26
-1jlr,2002-01-10,2001-07-16
-1jlm,1997-01-11,1996-04-09
-4jlt,2013-06-26,2013-03-13
-4jl9,2013-06-19,2013-03-12
-6jlr,2020-02-12,2019-03-06
-7jlr,2021-08-04,2020-07-30
-2jle,2009-08-04,2008-09-08
-8jlk,2023-11-15,2023-06-02
-5jlv,2016-06-15,2016-04-27
-8jlq,2023-11-15,2023-06-02
-5jli,2017-03-08,2016-04-27
-2jly,2008-11-25,2008-09-15
-7jll,2021-08-04,2020-07-29
-6jlm,2019-10-16,2019-03-06
-4jlz,2013-06-12,2013-03-13
-6jlh,2020-03-11,2019-03-05
-4jld,2014-06-25,2013-03-12
-7jl8,2021-06-30,2020-07-29
-1jl6,2002-07-16,2001-07-16
-2jln,2008-10-28,2008-09-11
-1jl5,2001-10-10,2001-07-15
-6jlk,2019-10-16,2019-03-06
-5jlj,2016-06-29,2016-04-27
-1jla,2001-10-03,2001-07-16
-2jlg,2008-11-04,2008-09-09
-8jl4,2024-05-22,2023-06-02
-5jl9,2017-04-26,2016-04-26
-8jlp,2023-11-15,2023-06-02
-8jlz,2023-06-28,2023-06-04
-2jlm,2009-01-20,2008-09-10
-1jlf,2001-10-03,2001-07-16
-4jl1,2014-01-22,2013-03-12
-6jls,2019-06-26,2019-03-06
-1jlj,2001-09-21,2001-07-16
-7jl3,2020-12-09,2020-07-29
-7jlj,2021-08-04,2020-07-29
-5jlb,2016-11-02,2016-04-26
-1jlq,2001-08-22,2001-07-16
-7jlv,2020-12-02,2020-07-30
-6jl9,2019-07-10,2019-03-04
-2jls,2008-11-25,2008-09-15
-8jl1,2024-05-22,2023-06-02
-5jlg,2016-08-03,2016-04-27
-4jlp,2014-06-25,2013-03-12
-5jlw,2016-06-22,2016-04-27
-4jlv,2014-02-05,2013-03-13
-4jla,2014-06-25,2013-03-12
-2jl4,2008-09-16,2008-09-04
-8jle,2024-05-01,2023-06-02
-4jl6,2014-06-25,2013-03-12
-1jlc,2001-10-03,2001-07-16
-1jlx,1997-12-03,1997-07-23
-5jla,2016-05-11,2016-04-26
-4jls,2014-12-24,2013-03-12
-4jlk,2013-09-18,2013-03-12
-4jl0,2013-12-11,2013-03-12
-8jlf,2024-05-01,2023-06-02
-1jls,2002-01-16,2001-07-16
-1jlk,2002-03-13,2001-07-16
-1jl8,2001-08-01,2001-07-16
-1jll,2002-01-30,2001-07-16
-5jls,2017-05-03,2016-04-27
-2jlr,2008-11-25,2008-09-15
-6jlp,2019-10-16,2019-03-06
-4jln,2014-01-22,2013-03-12
-6jla,2020-03-04,2019-03-04
-8jlj,2023-11-15,2023-06-02
-6jl4,2020-03-04,2019-03-04
-6jlq,2019-07-10,2019-03-06
-2jlw,2008-11-25,2008-09-15
-8jlc,2024-05-01,2023-06-02
-6jlu,2019-07-31,2019-03-06
-4jlc,2013-06-19,2013-03-12
-2jlx,2008-11-25,2008-09-15
-8jl3,2024-05-22,2023-06-02
-4jll,2013-04-10,2013-03-12
-7jl5,2020-09-09,2020-07-29
-2jlv,2008-11-25,2008-09-15
-6jlv,2020-03-18,2019-03-07
-2jlc,2008-10-21,2008-09-08
-2jlz,2008-11-25,2008-09-15
-6jlf,2019-11-13,2019-03-05
-8jln,2023-11-15,2023-06-02
-4jlg,2013-04-17,2013-03-12
-2jlf,2008-11-04,2008-09-08
-6jl5,2020-03-04,2019-03-04
-4jl2,2014-01-22,2013-03-12
-8jbk,2023-08-09,2023-05-09
-6jbc,2020-01-29,2019-01-25
-2jb8,2008-02-05,2006-12-05
-5jbb,2016-06-01,2016-04-13
-2jba,2007-01-04,2006-12-05
-6jbb,2019-10-30,2019-01-25
-3jb3,2015-08-12,2015-07-06
-4jbz,2013-12-11,2013-02-20
-6jbn,2020-01-29,2019-01-26
-4jb1,2013-07-17,2013-02-19
-6jb8,2019-11-06,2019-01-25
-2jb7,2008-08-05,2006-12-04
-3jbv,2016-01-27,2015-10-16
-1jbd,2001-06-27,2001-06-04
-2jbg,2007-04-03,2006-12-07
-6jbq,2019-05-29,2019-01-26
-4jbi,2013-06-19,2013-02-19
-2jbj,2006-12-18,2006-12-07
-5jbt,2016-11-09,2016-04-13
-4jbp,2013-06-05,2013-02-20
-3jbk,2015-11-04,2015-09-03
-2jbk,2006-12-18,2006-12-07
-2jb4,2007-10-16,2006-12-01
-1jb9,2001-07-04,2001-06-03
-6jbv,2019-06-26,2019-01-26
-6jbk,2020-02-05,2019-01-25
-1jbr,2001-10-26,2001-06-06
-6jby,2020-04-01,2019-01-27
-1jb0,2001-08-01,2001-06-01
-8jb8,2023-12-13,2023-05-08
-4jbn,2013-12-04,2013-02-20
-5jbj,2016-06-01,2016-04-13
-5jbc,2016-06-01,2016-04-13
-3jb7,2015-10-28,2015-08-03
-8jb3,2024-03-06,2023-05-08
-6jbw,2019-12-04,2019-01-26
-6jb3,2019-05-22,2019-01-25
-8jbf,2024-02-28,2023-05-08
-2jbf,2008-02-05,2006-12-06
-3jb0,2015-08-12,2015-07-06
-6jbr,2019-12-04,2019-01-26
-5jbi,2016-08-24,2016-04-13
-5jbx,2016-06-22,2016-04-14
-6jb4,2019-10-30,2019-01-25
-4jb9,2013-05-08,2013-02-19
-8jbl,2023-08-09,2023-05-09
-8jbm,2023-08-09,2023-05-09
-4jby,2013-03-06,2013-02-20
-2jbh,2006-12-20,2006-12-07
-4jb6,2014-03-05,2013-02-19
-1jbw,2001-09-19,2001-06-06
-4jbq,2013-06-05,2013-02-20
-6jbu,2020-01-29,2019-01-26
-2jbs,2007-01-23,2006-12-11
-3jb1,2015-08-12,2015-07-06
-1jbk,2002-06-05,2001-06-05
-4jb0,2013-04-17,2013-02-19
-5jbd,2017-01-18,2016-04-13
-8jbn,2024-02-28,2023-05-09
-2jbw,2007-01-04,2006-12-14
-5jbe,2017-01-18,2016-04-13
-8jbp,2024-05-15,2023-05-09
-2jbu,2007-07-03,2006-12-11
-4jbs,2013-12-11,2013-02-20
-8jbg,2024-02-07,2023-05-08
-2jbt,2007-01-23,2006-12-11
-3jb6,2015-10-28,2015-08-02
-3jb9,2015-09-23,2015-08-09
-1jbu,2001-07-11,2001-06-06
-4jbr,2014-03-19,2013-02-20
-1jbs,2001-10-26,2001-06-06
-3jbb,2015-11-11,2015-08-26
-4jbg,2013-06-19,2013-02-19
-3jbr,2015-12-30,2015-09-29
-8jbr,2024-01-24,2023-05-09
-2jbp,2007-03-20,2006-12-09
-2jb5,2008-01-08,2006-12-03
-2jbz,2007-01-23,2006-12-15
-6jbt,2019-06-19,2019-01-26
-8jb5,2023-12-13,2023-05-08
-8jbi,2024-02-28,2023-05-09
-1jbz,2003-01-07,2001-06-07
-1jbv,2001-09-19,2001-06-06
-8jb1,2023-12-06,2023-05-07
-6jb1,2019-05-22,2019-01-25
-8jba,2023-10-25,2023-05-08
-5jb8,2016-06-01,2016-04-13
-4jbb,2013-03-20,2013-02-19
-8jbz,2023-05-31,2023-05-10
-3jbj,2015-11-04,2015-09-03
-8jbh,2024-02-07,2023-05-08
-6jbj,2019-09-11,2019-01-25
-5jbh,2016-12-07,2016-04-13
-4jbh,2013-06-19,2013-02-19
-2jb6,2008-01-08,2006-12-03
-5jba,2016-06-01,2016-04-13
-1jbt,2001-10-26,2001-06-06
-8jbo,2023-10-11,2023-05-09
-2jb3,2007-01-30,2006-12-01
-1jbq,2001-08-12,2001-06-06
-3jbx,2015-12-09,2015-10-22
-3jbt,2015-11-18,2015-10-15
-6jbs,2020-02-12,2019-01-26
-3jb2,2015-08-12,2015-07-06
-5jb9,2016-06-01,2016-04-13
-4jb3,2013-03-13,2013-02-19
-4jb4,2013-04-10,2013-02-19
-2jbl,2007-03-13,2006-12-08
-5jbg,2016-06-01,2016-04-13
-5jbf,2017-01-18,2016-04-13
-6jba,2019-10-30,2019-01-25
-3jbw,2015-12-09,2015-10-21
-3jbz,2016-11-16,2015-11-03
-1jba,1999-12-10,1999-04-03
-3jbi,2015-11-04,2015-09-02
-5jb3,2016-11-30,2016-04-13
-5jb2,2016-06-01,2016-04-13
-8jbc,2023-12-13,2023-05-08
-6jbe,2019-10-30,2019-01-25
-8jbw,2024-04-03,2023-05-09
-3jby,2015-12-09,2015-10-22
-4jbx,2013-03-06,2013-02-20
-4jbl,2013-12-04,2013-02-19
-2jbo,2007-03-20,2006-12-09
-4jbo,2013-06-05,2013-02-20
-2jb2,2007-01-30,2006-12-01
-4jbv,2014-03-19,2013-02-20
-2jb0,2007-04-03,2006-12-01
-1jbo,2003-03-18,2002-05-02
-6jb0,2019-10-30,2019-01-25
-8jby,2024-02-28,2023-05-10
-8jb0,2023-08-02,2023-05-07
-1jbp,2001-06-27,2001-06-06
-2jby,2007-03-27,2006-12-14
-5jbq,2016-07-13,2016-04-13
-8jbb,2023-12-13,2023-05-08
-1jbc,1997-02-12,1996-08-23
-2jb1,2007-01-30,2006-12-01
-6jbd,2020-01-29,2019-01-25
-4jbe,2013-03-20,2013-02-19
-4jbt,2014-03-05,2013-02-20
-7tiz,2022-05-04,2022-01-14
-3tij,2012-03-07,2011-08-20
-6til,2020-06-24,2019-11-22
-5ti4,2017-08-09,2016-09-30
-8tiu,2023-08-02,2023-07-20
-6tir,2019-12-04,2019-11-22
-3ti0,2011-10-19,2011-08-19
-6ti1,2020-04-29,2019-11-21
-1ti7,2004-06-08,2004-06-02
-6tit,2020-09-02,2019-11-22
-6tip,2020-12-02,2019-11-22
-5tie,2017-04-26,2016-10-02
-7ti7,2022-01-26,2022-01-12
-5ti8,2017-01-11,2016-10-01
-7ti1,2023-01-25,2022-01-12
-3ti5,2011-11-16,2011-08-20
-8ti2,2024-04-03,2023-07-18
-1tip,1998-01-28,1997-05-28
-8tic,2023-12-06,2023-07-19
-6tig,2020-01-22,2019-11-22
-7tiw,2022-05-04,2022-01-14
-3tiz,2012-08-22,2011-08-22
-3tib,2011-11-16,2011-08-20
-5tis,2016-11-23,2016-10-03
-5tio,2017-01-18,2016-10-03
-3tiq,2012-04-18,2011-08-21
-5tid,2017-04-26,2016-10-02
-3tiy,2012-08-22,2011-08-22
-6tin,2020-06-24,2019-11-22
-4tim,1992-10-15,1991-04-11
-5tip,2017-10-18,2016-10-03
-3tis,2012-08-01,2011-08-21
-1tiw,2004-10-26,2004-06-02
-3ti1,2012-08-22,2011-08-19
-6ti9,2020-10-21,2019-11-22
-5tib,2017-02-01,2016-10-01
-3tix,2011-11-16,2011-08-22
-7tiu,2022-05-04,2022-01-14
-5tij,2017-10-18,2016-10-03
-3ti4,2011-11-16,2011-08-20
-5ti1,2017-02-08,2016-09-30
-7tii,2022-03-30,2022-01-13
-8ti6,2024-05-08,2023-07-19
-3ti7,2011-10-19,2011-08-20
-8tix,2023-08-02,2023-07-20
-3tit,2012-08-22,2011-08-21
-7tih,2022-03-30,2022-01-13
-6tij,2020-06-24,2019-11-22
-2tio,1998-09-30,1998-09-23
-6ti8,2020-10-28,2019-11-22
-7tie,2022-03-30,2022-01-13
-3tin,2011-10-26,2011-08-20
-6tis,2021-01-27,2019-11-22
-5ti7,2017-08-09,2016-10-01
-6tid,2020-01-22,2019-11-22
-5tig,2018-02-21,2016-10-02
-5tin,2017-01-18,2016-10-03
-7tin,2022-09-14,2022-01-14
-8tiz,2023-08-02,2023-07-20
-7tix,2022-05-04,2022-01-14
-8tit,2023-08-02,2023-07-20
-3tio,2012-08-01,2011-08-21
-6ti3,2020-04-29,2019-11-21
-5ti0,2017-04-26,2016-09-30
-7tib,2022-02-16,2022-01-13
-1til,2004-06-15,2004-06-02
-6ti4,2020-04-15,2019-11-21
-6tiy,2021-01-27,2019-11-22
-5tii,2016-11-09,2016-10-03
-6tim,1992-10-15,1991-04-23
-5tiu,2017-01-11,2016-10-03
-5tiy,2017-05-31,2016-10-03
-3tia,2011-11-16,2011-08-20
-8tiy,2023-08-02,2023-07-20
-6tiu,2021-01-27,2019-11-22
-6tia,2020-10-28,2019-11-22
-1tiy,2004-06-22,2004-06-02
-8ti7,2024-05-08,2023-07-19
-7ti2,2022-10-12,2022-01-12
-3tif,2012-03-21,2011-08-20
-8tiq,2023-08-02,2023-07-20
-8tip,2023-08-02,2023-07-20
-5ti3,2017-08-09,2016-09-30
-5tiv,2017-05-31,2016-10-03
-3tid,2012-08-22,2011-08-20
-5tir,2017-10-11,2016-10-03
-7ti0,2022-05-18,2022-01-12
-7tic,2022-02-16,2022-01-13
-5tia,2016-10-26,2016-10-01
-8tiw,2023-08-02,2023-07-20
-3ti9,2011-10-19,2011-08-20
-2tir,1993-10-31,1993-01-10
-6tib,2020-06-24,2019-11-22
-8tir,2023-08-02,2023-07-20
-6tiz,2021-01-27,2019-11-22
-8ti0,2024-06-05,2023-07-18
-5tiz,2017-05-31,2016-10-03
-6tic,2020-06-24,2019-11-22
-5ti6,2017-08-09,2016-10-01
-7tid,2022-02-16,2022-01-13
-5ti5,2017-08-09,2016-10-01
-7tia,2022-05-04,2022-01-13
-5tiw,2017-05-31,2016-10-03
-3tii,2011-10-26,2011-08-20
-6tih,2020-06-24,2019-11-22
-8tis,2023-08-02,2023-07-20
-1ti8,2005-06-21,2004-06-02
-7ti8,2022-02-16,2022-01-13
-6tio,2020-06-24,2019-11-22
-6tiw,2020-03-04,2019-11-22
-3tik,2012-07-11,2011-08-20
-6tix,2020-12-02,2019-11-22
-5til,2017-11-01,2016-10-03
-7tiy,2022-05-04,2022-01-14
-3ti8,2011-11-16,2011-08-20
-8ti1,2024-04-03,2023-07-18
-3tiu,2012-08-22,2011-08-22
-5ti2,2017-08-09,2016-09-30
-3tiv,2012-09-05,2011-08-22
-5tix,2017-05-31,2016-10-03
-1tid,2004-06-15,2004-06-02
-7tiv,2022-05-04,2022-01-14
-3tig,2011-10-26,2011-08-20
-8tiv,2023-08-02,2023-07-20
-7tim,1993-10-31,1991-04-23
-5tiq,2017-10-18,2016-10-03
-3tie,2012-08-22,2011-08-20
-1tio,1998-09-23,1998-09-17
-3ti6,2011-11-23,2011-08-20
-3ti3,2011-11-16,2011-08-20
-3tic,2011-11-16,2011-08-20
-5ti9,2016-10-26,2016-10-01
-5tif,2017-04-26,2016-10-02
-6tie,2020-06-24,2019-11-22
-1tiq,2004-07-13,2004-06-02
-8pkw,2023-11-15,2023-06-27
-5pkb,2017-03-15,2017-02-07
-1pkx,2004-02-17,2003-06-06
-5pkr,2017-03-15,2017-02-07
-1pkd,2003-06-24,2003-06-05
-5pks,2017-03-15,2017-02-07
-8pk9,2024-05-01,2023-06-26
-3pkh,2011-04-06,2010-11-11
-4pku,2014-11-12,2014-05-15
-1pkk,2003-09-23,2003-06-05
-7pkg,2021-12-22,2021-08-25
-3pkp,2011-01-12,2010-11-11
-6pk3,2019-10-23,2019-06-28
-1pkf,2003-10-28,2003-06-05
-5pkm,2017-03-15,2017-02-07
-5pkg,2017-03-15,2017-02-07
-7pkh,2021-12-22,2021-08-25
-1pk0,2004-02-10,2003-06-04
-5pk8,2017-03-15,2017-02-07
-7pkd,2021-12-22,2021-08-25
-5pky,2017-03-15,2017-02-07
-5pkq,2017-03-15,2017-02-07
-2pkn,2007-06-19,2007-04-18
-2pku,2007-11-20,2007-04-18
-7pka,2022-09-07,2021-08-25
-6pka,2019-11-06,2019-06-28
-3pkw,2011-01-12,2010-11-12
-5pkj,2017-03-15,2017-02-07
-5pkv,2017-03-15,2017-02-07
-7pkt,2022-06-15,2021-08-26
-1pke,2003-11-25,2003-06-05
-7pkm,2022-09-07,2021-08-25
-6pk7,2019-12-25,2019-06-28
-7pk9,2021-12-22,2021-08-25
-8pku,2023-11-15,2023-06-27
-1pkj,2003-09-23,2003-06-05
-7pks,2021-12-08,2021-08-26
-4pk5,2014-09-03,2014-05-13
-5pk7,2017-03-15,2017-02-07
-4pk3,2014-08-13,2014-05-13
-6pkx,2019-08-28,2019-06-30
-1pkg,2003-08-12,2003-06-05
-5pk2,2017-03-15,2017-02-07
-2pk0,2007-06-12,2007-04-17
-2pkg,2007-05-15,2007-04-17
-4pkg,2014-07-30,2014-05-14
-4pk0,2014-09-10,2014-05-13
-5pk9,2017-03-15,2017-02-07
-7pkx,2021-10-27,2021-08-27
-7pkv,2022-09-07,2021-08-26
-3pkb,2011-04-20,2010-11-11
-1pk6,2003-10-21,2003-06-05
-3pk3,2011-04-06,2010-11-11
-2pks,2008-04-22,2007-04-18
-5pk4,2017-03-15,2017-02-07
-4pkr,2014-11-12,2014-05-15
-5pka,2017-03-15,2017-02-07
-7pkf,2021-12-22,2021-08-25
-3pkj,2011-01-26,2010-11-11
-5pk1,2017-03-15,2017-02-07
-5pkh,2017-03-15,2017-02-07
-2pk4,1993-10-31,1991-07-18
-4pkw,2014-11-12,2014-05-15
-5pk0,2017-03-15,2017-02-07
-5pk3,2017-03-15,2017-02-07
-2pke,2007-05-08,2007-04-17
-4pkm,2015-06-03,2014-05-15
-4pkd,2014-12-31,2014-05-14
-5pk6,2017-03-15,2017-02-07
-6pkg,2020-02-19,2019-06-29
-8pkx,2023-11-15,2023-06-27
-5pkt,2017-03-15,2017-02-07
-5pkd,2017-03-15,2017-02-07
-4pkq,2014-11-12,2014-05-15
-5pk5,2017-03-15,2017-02-07
-5pkc,2017-03-15,2017-02-07
-3pk7,2011-11-16,2010-11-11
-3pkq,2011-01-12,2010-11-11
-6pkh,2020-02-19,2019-06-29
-4pk2,2014-08-13,2014-05-13
-3pkl,2011-04-06,2010-11-11
-1pk7,2003-11-25,2003-06-05
-8pk8,2024-05-01,2023-06-26
-3pkd,2011-04-20,2010-11-11
-6pkz,2020-07-01,2019-06-30
-7pkb,2021-12-22,2021-08-25
-8pkm,2024-05-29,2023-06-27
-5pke,2017-03-15,2017-02-07
-3pkf,2011-04-06,2010-11-11
-8pky,2023-07-05,2023-06-27
-4pkh,2014-07-30,2014-05-14
-1pk9,2003-11-25,2003-06-05
-4pko,2014-08-20,2014-05-15
-1pkn,1995-01-26,1994-03-25
-1pkw,2004-06-22,2003-06-06
-8pka,2024-05-01,2023-06-26
-3pka,2011-04-20,2010-11-11
-5pkf,2017-03-15,2017-02-07
-7pk8,2022-09-07,2021-08-25
-2pkc,1994-01-31,1993-06-04
-1pk8,2004-03-23,2003-06-05
-8pkl,2024-03-06,2023-06-26
-2pk6,2007-05-08,2007-04-17
-6pk4,2019-12-25,2019-06-28
-3pk5,2011-04-06,2010-11-11
-8pkc,2024-05-08,2023-06-26
-6pku,2020-02-19,2019-06-29
-5pkl,2017-03-15,2017-02-07
-3pk8,2011-04-06,2010-11-11
-5pkz,2017-03-15,2017-02-07
-1pk2,1994-01-31,1991-09-16
-8pk3,2024-01-03,2023-06-24
-4pkt,2014-11-12,2014-05-15
-3pkm,2011-03-09,2010-11-11
-6pk6,2019-08-28,2019-06-28
-2pkk,2007-06-19,2007-04-17
-6pkc,2019-12-18,2019-06-29
-7pkk,2022-09-07,2021-08-25
-4pkv,2014-11-12,2014-05-15
-3pkg,2011-04-06,2010-11-11
-2pkl,2007-09-25,2007-04-17
-5pkx,2017-03-15,2017-02-07
-7pk0,2022-09-07,2021-08-25
-5pku,2017-03-15,2017-02-07
-4pkn,2014-08-20,2014-05-15
-7pki,2022-01-19,2021-08-25
-7pk3,2022-09-07,2021-08-25
-2pkt,2007-05-08,2007-04-18
-3pke,2011-04-20,2010-11-11
-7pke,2021-12-22,2021-08-25
-2pkr,2007-06-19,2007-04-18
-3pkc,2011-04-20,2010-11-11
-3pk4,2011-04-06,2010-11-11
-2pkq,2007-06-19,2007-04-18
-2pkm,2007-06-26,2007-04-17
-3pkt,2011-04-06,2010-11-12
-5pkn,2017-03-15,2017-02-07
-4pk6,2014-09-03,2014-05-13
-3pky,2011-02-16,2010-11-12
-3pk6,2011-04-06,2010-11-11
-3pks,2011-04-06,2010-11-12
-5pkw,2017-03-15,2017-02-07
-2pk5,2007-05-08,2007-04-17
-4pkk,2016-05-04,2014-05-14
-6pk2,2020-07-01,2019-06-28
-8pki,2024-02-28,2023-06-26
-3pkx,2011-01-12,2010-11-12
-2pkp,2008-04-22,2007-04-18
-8pk0,2023-12-13,2023-06-23
-6pk0,2020-01-22,2019-06-28
-5pko,2017-03-15,2017-02-07
-4pk4,2015-04-29,2014-05-13
-5pkp,2017-03-15,2017-02-07
-6pki,2020-02-19,2019-06-29
-6pkd,2019-09-11,2019-06-29
-4pkl,2015-11-18,2014-05-15
-2pk3,2008-03-25,2007-04-17
-6pk1,2019-10-23,2019-06-28
-8pkv,2023-11-15,2023-06-27
-3pk0,2010-11-24,2010-11-10
-3pkk,2011-04-06,2010-11-11
-3pku,2011-04-06,2010-11-12
-8pkp,2023-07-19,2023-06-27
-4pks,2014-11-12,2014-05-15
-5pkk,2017-03-15,2017-02-07
-4pki,2014-07-30,2014-05-14
-6pky,2020-02-19,2019-06-30
-1pkv,2004-06-08,2003-06-06
-4pke,2014-10-08,2014-05-14
-5pki,2017-03-15,2017-02-07
-3pk1,2010-12-29,2010-11-11
-6sdm,2020-08-26,2019-07-28
-5sd4,2022-02-09,2021-12-20
-6sdp,2020-08-26,2019-07-29
-5sdr,2022-02-09,2022-01-20
-8sdg,2024-03-13,2023-04-06
-1sdq,2005-07-12,2004-02-13
-7sda,2022-11-09,2021-09-29
-1sd3,2005-02-15,2004-02-12
-3sdk,2012-06-13,2011-06-09
-3sdi,2012-06-13,2011-06-09
-6sdk,2019-10-23,2019-07-28
-3sdv,2011-12-14,2011-06-09
-5sdc,2022-02-09,2022-01-20
-3sdg,2011-12-07,2011-06-09
-8sd6,2024-03-13,2023-04-06
-1sd9,2005-02-15,2004-02-13
-6sdv,2020-03-11,2019-07-29
-5sd1,2022-02-09,2021-12-20
-1sdy,1994-01-31,1991-06-14
-6sdo,2020-08-26,2019-07-29
-3sd9,2011-07-13,2011-06-08
-1sdx,2004-03-02,2004-02-15
-8sda,2023-09-27,2023-04-06
-1sdl,1996-08-01,1996-02-26
-7sd5,2022-04-27,2021-09-29
-6sd7,2020-04-15,2019-07-26
-3sda,2011-10-05,2011-06-08
-6sdi,2020-08-26,2019-07-27
-3sdj,2011-07-13,2011-06-09
-3sd5,2012-01-04,2011-06-08
-1sdw,2004-05-11,2004-02-14
-5sdo,2022-02-09,2022-01-20
-1sdz,2004-04-27,2004-02-15
-6sdl,2020-08-26,2019-07-28
-5sdt,2022-03-16,2022-01-20
-8sdz,2023-10-18,2023-04-07
-5sdp,2022-02-09,2022-01-20
-6sdx,2019-08-21,2019-07-29
-5sd2,2022-02-09,2021-12-20
-8sdk,2023-05-31,2023-04-06
-3sdt,2011-12-14,2011-06-09
-5sd3,2022-02-09,2021-12-20
-3sd0,2011-08-03,2011-06-08
-1sda,1993-10-31,1993-01-13
-6sdn,2020-08-26,2019-07-29
-6sdc,2019-08-14,2019-07-26
-3sdy,2011-07-20,2011-06-09
-5sdg,2022-02-09,2022-01-20
-5sdq,2022-02-09,2022-01-20
-3sdh,1993-10-31,1993-06-23
-5sdb,2022-02-09,2021-12-20
-1sd0,2004-07-27,2004-02-12
-8sdy,2023-10-18,2023-04-07
-6sds,2020-06-10,2019-07-29
-5sdh,2022-02-09,2022-01-20
-1sdn,2005-02-22,2004-02-13
-5sde,2022-02-09,2022-01-20
-3sdr,2011-12-14,2011-06-09
-6sdh,2020-08-26,2019-07-27
-5sdv,2022-10-12,2022-01-21
-3sdn,2011-11-02,2011-06-09
-1sd1,2004-05-18,2004-02-12
-8sdx,2024-06-05,2023-04-07
-7sdr,2021-10-06,2021-09-29
-8sds,2023-08-16,2023-04-07
-8sd1,2024-03-13,2023-04-06
-7sd3,2022-11-09,2021-09-29
-1sd2,2004-05-18,2004-02-12
-5sd6,2022-02-09,2021-12-20
-8sd7,2024-03-13,2023-04-06
-3sdp,1993-04-15,1991-05-06
-1sdm,2004-06-22,2004-02-13
-5sdi,2022-02-09,2022-01-20
-8sd2,2024-06-05,2023-04-06
-8sd4,2024-06-05,2023-04-06
-1sdt,2004-05-25,2004-02-14
-3sd6,2012-06-13,2011-06-08
-1sdv,2004-05-25,2004-02-14
-5sdl,2022-02-09,2022-01-20
-5sd0,2022-02-09,2021-12-20
-8sd8,2024-03-13,2023-04-06
-3sdf,2011-06-29,2011-06-09
-1sdd,2004-06-29,2004-02-13
-1sd8,2005-02-15,2004-02-13
-5sdn,2022-02-09,2022-01-20
-8sdq,2024-06-05,2023-04-07
-5sdd,2022-02-09,2022-01-20
-7sd0,2022-04-20,2021-09-29
-8sdw,2023-06-28,2023-04-07
-3sd7,2011-06-29,2011-06-08
-7sdc,2022-11-09,2021-09-29
-6sdr,2020-03-11,2019-07-29
-5sdk,2022-02-09,2022-01-20
-6sda,2019-09-11,2019-07-26
-8sd3,2023-09-27,2023-04-06
-8sdf,2024-03-13,2023-04-06
-6sdu,2020-07-08,2019-07-29
-5sdy,2022-10-12,2022-01-21
-4sdh,1993-10-31,1993-06-23
-8sdt,2023-08-16,2023-04-07
-1sde,2004-10-12,2004-02-13
-8sdv,2023-08-16,2023-04-07
-6sde,2019-08-14,2019-07-26
-6sd8,2019-09-11,2019-07-26
-7sd9,2022-11-09,2021-09-29
-5sdu,2022-10-12,2022-01-21
-5sda,2022-02-09,2021-12-20
-7sdd,2022-10-19,2021-09-29
-5sdx,2022-10-12,2022-01-21
-8sdb,2023-07-12,2023-04-06
-6sd0,2020-01-15,2019-07-26
-8sdo,2024-06-05,2023-04-07
-5sdf,2022-02-09,2022-01-20
-6sdt,2020-06-10,2019-07-29
-5sdm,2022-02-09,2022-01-20
-3sdc,2011-10-05,2011-06-09
-1sdu,2004-05-25,2004-02-14
-6sdj,2020-04-15,2019-07-27
-5sdz,2022-10-12,2022-01-21
-3sdd,2011-10-05,2011-06-09
-5sd8,2022-02-09,2021-12-20
-1sdk,1996-08-01,1996-02-26
-7sdp,2021-10-13,2021-09-29
-3sdu,2011-12-14,2011-06-09
-8sdr,2023-08-16,2023-04-07
-6sdd,2019-08-14,2019-07-26
-5sdj,2022-02-09,2022-01-20
-8sd9,2024-03-13,2023-04-06
-6sd9,2019-08-14,2019-07-26
-6sdq,2020-08-26,2019-07-29
-5sd7,2022-02-09,2021-12-20
-5sd9,2022-02-09,2021-12-20
-5sd5,2022-02-09,2021-12-20
-8sd0,2024-03-13,2023-04-06
-5sdw,2022-10-12,2022-01-21
-7vve,2022-03-09,2021-11-05
-3vvs,2013-04-03,2012-07-27
-2vvf,2008-09-16,2008-06-06
-6vvu,2020-12-30,2020-02-18
-3vv5,2013-06-26,2012-07-16
-6vve,2020-04-08,2020-02-17
-2vvu,2009-07-07,2008-06-11
-7vv8,2022-05-18,2021-11-04
-5vv6,2017-08-16,2017-05-19
-2vvn,2008-07-01,2008-06-10
-5vvv,2017-09-27,2017-05-20
-3vv1,2013-05-22,2012-07-10
-7vvh,2022-11-09,2021-11-06
-3vvr,2013-04-03,2012-07-27
-3vvy,2013-07-03,2012-07-30
-5vvr,2017-11-22,2017-05-19
-5vvn,2017-08-16,2017-05-19
-5vvc,2017-08-16,2017-05-19
-7vvo,2022-08-03,2021-11-06
-3vvf,2013-06-26,2012-07-21
-7vvi,2022-11-23,2021-11-06
-6vv2,2020-06-03,2020-02-16
-6vvv,2020-10-21,2020-02-18
-2vvb,2009-07-14,2008-06-04
-6vv1,2020-06-03,2020-02-16
-3vv8,2012-10-24,2012-07-17
-2vvq,2008-07-01,2008-06-10
-3vv0,2013-03-27,2012-07-10
-6vv7,2020-07-15,2020-02-17
-3vvp,2013-04-03,2012-07-27
-2vvz,2008-06-24,2008-06-13
-7vvz,2022-08-10,2021-11-09
-5vv9,2017-08-16,2017-05-19
-6vv9,2020-07-15,2020-02-17
-7vv5,2021-12-01,2021-11-04
-8vv3,2024-03-20,2024-01-30
-5vv0,2017-08-16,2017-05-19
-3vv9,2013-03-13,2012-07-17
-3vvh,2013-08-28,2012-07-24
-7vv9,2022-05-18,2021-11-05
-6vvy,2020-10-21,2020-02-18
-5vvs,2017-11-22,2017-05-20
-6vv5,2020-02-26,2020-02-17
-3vv3,2013-08-07,2012-07-14
-3vva,2013-03-13,2012-07-17
-7vvt,2022-03-02,2021-11-08
-2vvm,2008-11-04,2008-06-10
-5vv4,2017-08-23,2017-05-19
-7vv3,2021-12-01,2021-11-04
-7vv0,2021-12-01,2021-11-04
-2vvo,2008-07-01,2008-06-10
-5vvd,2017-08-16,2017-05-19
-2vvd,2008-09-16,2008-06-06
-2vvl,2008-11-04,2008-06-10
-7vvp,2022-08-24,2021-11-07
-7vv4,2021-12-01,2021-11-04
-7vvs,2022-11-09,2021-11-08
-5vv1,2017-08-23,2017-05-19
-7vvc,2022-03-09,2021-11-05
-3vvd,2013-06-26,2012-07-21
-3vv6,2012-10-24,2012-07-17
-3vve,2013-06-26,2012-07-21
-2vvp,2008-07-01,2008-06-10
-7vvu,2022-08-10,2021-11-09
-5vvi,2017-06-21,2017-05-19
-1vvj,2014-08-06,2013-05-24
-7vvw,2022-04-20,2021-11-09
-2vvc,2009-07-07,2008-06-05
-6vvg,2021-02-03,2020-02-17
-2vv7,2008-11-04,2008-06-04
-6vvt,2020-10-21,2020-02-18
-6vvi,2021-02-24,2020-02-18
-7vvy,2022-08-10,2021-11-09
-3vvg,2013-08-28,2012-07-24
-5vv2,2017-08-23,2017-05-19
-2vvs,2008-09-30,2008-06-11
-2vv8,2008-11-04,2008-06-04
-6vv6,2020-07-15,2020-02-17
-7vvd,2022-11-09,2021-11-05
-6vvh,2021-02-24,2020-02-18
-2vve,2008-09-16,2008-06-06
-6vv3,2020-06-03,2020-02-16
-5vvp,2018-10-03,2017-05-19
-5vvu,2017-09-27,2017-05-20
-6vvz,2020-10-21,2020-02-18
-7vvx,2022-04-20,2021-11-09
-6vvx,2020-10-21,2020-02-18
-5vv5,2017-08-16,2017-05-19
-5vvl,2017-08-02,2017-05-19
-7vvg,2022-05-18,2021-11-06
-5vv7,2017-08-16,2017-05-19
-3vv4,2013-01-30,2012-07-14
-3vvc,2013-06-12,2012-07-18
-2vv9,2008-08-05,2008-06-04
-5vvx,2017-09-27,2017-05-21
-7vv6,2021-12-01,2021-11-04
-7vvb,2022-05-18,2021-11-05
-7vva,2022-04-06,2021-11-05
-5vvm,2018-05-23,2017-05-19
-3vv2,2013-03-06,2012-07-12
-5vv3,2017-08-16,2017-05-19
-5vvb,2017-08-16,2017-05-19
-2vvg,2008-07-08,2008-06-08
-5vv8,2017-08-16,2017-05-19
-6vv8,2020-07-15,2020-02-17
-5vvg,2017-08-16,2017-05-19
-6vvb,2020-07-15,2020-02-17
-5vvt,2017-09-27,2017-05-20
-3vvb,2013-06-12,2012-07-18
-7vvr,2022-11-16,2021-11-08
-2vv4,2008-08-19,2008-06-02
-3vvz,2013-07-03,2012-07-30
-6vvs,2020-10-21,2020-02-18
-2vv6,2008-11-04,2008-06-04
-3vv7,2012-10-24,2012-07-17
-3vvk,2013-06-19,2012-07-26
-2vvv,2009-07-07,2008-06-12
-6vv0,2020-06-03,2020-02-16
-5vva,2017-08-16,2017-05-19
-2vva,2009-07-14,2008-06-04
-2vvt,2008-06-24,2008-06-11
-6vvo,2020-02-26,2020-02-18
-5yn3,2018-05-09,2017-10-24
-2ynh,2013-01-09,2012-10-14
-6yny,2020-09-30,2020-04-14
-4yne,2015-06-03,2015-03-09
-5ynu,2018-08-29,2017-10-25
-2yni,2013-01-09,2012-10-15
-1yni,2005-02-15,2005-01-24
-6ynz,2020-09-30,2020-04-14
-5ynh,2018-10-24,2017-10-24
-1ynt,2005-12-27,2005-01-25
-6ynp,2020-07-15,2020-04-14
-1yny,2005-03-01,2005-01-26
-2yn8,2013-10-23,2012-10-13
-7ynp,2023-08-02,2022-07-31
-7ynh,2022-11-16,2022-07-31
-7yn0,2023-08-09,2022-07-29
-6yns,2021-03-17,2020-04-14
-6yn0,2020-11-04,2020-04-10
-2ynn,2012-12-12,2012-10-17
-4ynd,2015-05-20,2015-03-09
-5ynd,2018-10-24,2017-10-24
-5yne,2018-10-24,2017-10-24
-6ynx,2020-09-30,2020-04-14
-1ynj,2005-03-15,2005-01-24
-1ynd,2005-04-05,2005-01-24
-2yna,2013-10-23,2012-10-13
-2yn6,2012-12-12,2012-10-12
-2ync,2014-01-15,2012-10-13
-6ynr,2020-10-14,2020-04-14
-1ynr,2005-05-17,2005-01-25
-2yn4,2013-05-01,2012-10-12
-5yno,2018-12-05,2017-10-24
-2ynm,2013-01-30,2012-10-16
-7yn3,2023-08-02,2022-07-29
-2ynr,2013-01-09,2012-10-18
-5ynt,2018-08-29,2017-10-25
-7ynu,2022-09-21,2022-08-01
-4yn3,2016-03-09,2015-03-09
-1ynh,2005-03-22,2005-01-24
-6ynt,2020-10-14,2020-04-14
-5ynj,2018-12-05,2017-10-24
-4yn2,2015-04-08,2015-03-09
-5ynf,2018-12-05,2017-10-24
-4yn4,2016-03-09,2015-03-09
-6yn4,2021-10-20,2020-04-10
-2yn3,2013-04-03,2012-10-11
-5ynq,2018-12-05,2017-10-25
-5ynz,2018-10-24,2017-10-26
-5ync,2018-10-24,2017-10-24
-7yn2,2023-08-02,2022-07-29
-1yns,2005-05-17,2005-01-25
-5yn7,2018-10-24,2017-10-24
-5yna,2018-10-24,2017-10-24
-5yn6,2018-12-05,2017-10-24
-2yn5,2013-04-03,2012-10-12
-1ynu,2005-05-03,2005-01-25
-4ynl,2015-12-02,2015-03-10
-6yni,2020-07-15,2020-04-13
-4ynu,2015-09-02,2015-03-11
-6ynn,2020-07-15,2020-04-14
-2ynq,2012-12-05,2012-10-17
-6yn7,2021-02-03,2020-04-11
-7ynn,2023-08-02,2022-07-31
-4yn0,2015-04-15,2015-03-08
-2yne,2014-01-15,2012-10-13
-2ynv,2013-07-24,2012-10-18
-2ynd,2014-01-15,2012-10-13
-4ynq,2015-05-27,2015-03-10
-4yn8,2015-08-19,2015-03-09
-4ynb,2015-11-25,2015-03-09
-1ynq,2005-12-06,2005-01-25
-4yn1,2015-04-08,2015-03-09
-6ynv,2020-09-30,2020-04-14
-6yn9,2020-06-24,2020-04-11
-4ynr,2016-02-24,2015-03-10
-7ynw,2022-09-21,2022-08-01
-2yng,2013-01-09,2012-10-14
-6ynk,2020-07-15,2020-04-13
-1yn4,2005-03-01,2005-01-23
-7ynv,2022-09-21,2022-08-01
-6ynl,2020-07-15,2020-04-14
-2ynf,2013-01-09,2012-10-14
-2ynj,2012-12-12,2012-10-15
-5ynw,2018-08-29,2017-10-25
-1ynw,2005-02-15,2005-01-25
-4ynm,2015-09-02,2015-03-10
-5yni,2018-12-05,2017-10-24
-1ynl,2005-08-16,2005-01-24
-1ynp,2005-12-06,2005-01-25
-6yn3,2021-04-21,2020-04-10
-7yni,2023-05-31,2022-07-31
-5ynn,2018-12-05,2017-10-24
-4ync,2016-01-20,2015-03-09
-7ynj,2023-05-31,2022-07-31
-5ynv,2018-08-29,2017-10-25
-6ynu,2021-03-17,2020-04-14
-7yno,2023-08-02,2022-07-31
-5ynm,2018-12-05,2017-10-24
-6ync,2020-10-14,2020-04-13
-6yno,2020-07-15,2020-04-14
-6ynm,2020-07-15,2020-04-14
-6ynq,2020-04-29,2020-04-14
-4ynt,2015-09-02,2015-03-11
-1ynf,2005-02-15,2005-01-24
-4ynk,2016-01-20,2015-03-10
-1ynn,2005-03-15,2005-01-24
-7ynz,2024-03-06,2022-08-01
-7ynx,2023-04-26,2022-08-01
-1yno,2006-01-17,2005-01-24
-4yni,2016-03-23,2015-03-10
-7yne,2022-10-26,2022-07-30
-5yng,2018-06-27,2017-10-24
-1yn8,2006-05-30,2005-01-24
-1ynk,2005-08-16,2005-01-24
-6yna,2020-10-14,2020-04-13
-7ynq,2023-08-02,2022-07-31
-7ynl,2023-08-02,2022-07-31
-5yn5,2018-12-05,2017-10-24
-5ynp,2018-12-05,2017-10-25
-6yn8,2020-06-24,2020-04-11
-6yn2,2021-04-21,2020-04-10
-2ynp,2012-12-12,2012-10-17
-2ynb,2013-10-23,2012-10-13
-2yns,2013-01-09,2012-10-18
-5yn8,2018-12-05,2017-10-24
-2ynt,2013-07-24,2012-10-18
-2ynw,2013-07-24,2012-10-18
-4ynp,2015-09-02,2015-03-10
-7ynf,2023-12-06,2022-07-30
-5ynb,2018-12-05,2017-10-24
-2ynx,2013-08-21,2012-10-19
-6ynb,2020-10-14,2020-04-13
-6ynj,2020-07-15,2020-04-13
-7ynm,2023-08-02,2022-07-31
-5yn2,2018-10-24,2017-10-24
-6sju,2020-05-20,2019-08-13
-6sj4,2020-01-15,2019-08-12
-6sjm,2019-09-18,2019-08-13
-7sj0,2022-11-16,2021-10-15
-6sjv,2019-09-04,2019-08-14
-3sji,2011-08-10,2011-06-21
-5sj8,2022-10-12,2022-02-01
-5sjk,2022-10-12,2022-02-01
-8sjg,2023-07-05,2023-04-18
-5sje,2022-10-12,2022-02-01
-8sjj,2023-09-27,2023-04-18
-1sjm,2004-06-22,2004-03-03
-3sj7,2012-01-25,2011-06-21
-7sj3,2022-11-02,2021-10-15
-8sj0,2024-04-24,2023-04-17
-3sjp,2011-07-13,2011-06-21
-3sj4,2012-07-04,2011-06-20
-7sjd,2022-11-23,2021-10-17
-5sjs,2022-10-12,2022-02-01
-7sji,2022-11-23,2021-10-17
-5sj5,2022-10-12,2022-02-01
-8sj1,2024-04-24,2023-04-17
-6sj9,2019-10-16,2019-08-13
-6sjs,2019-09-25,2019-08-13
-3sj3,2011-06-29,2011-06-20
-6sjd,2020-07-22,2019-08-13
-5sjw,2022-10-12,2022-02-01
-6sjx,2020-02-26,2019-08-14
-5sjq,2022-10-12,2022-02-01
-3sj9,2011-08-10,2011-06-21
-5sjp,2022-10-12,2022-02-01
-3sjg,2011-10-05,2011-06-21
-3sj0,2012-07-04,2011-06-20
-5sjg,2022-10-12,2022-02-01
-6sj8,2019-09-25,2019-08-13
-3sjn,2011-07-06,2011-06-21
-1sjw,2004-04-27,2004-03-04
-7sjg,2022-11-23,2021-10-17
-3sja,2011-07-06,2011-06-21
-7sj9,2022-01-19,2021-10-16
-3sjs,2011-07-06,2011-06-21
-8sj8,2024-04-24,2023-04-17
-8sj7,2023-09-27,2023-04-17
-1sjn,2004-03-09,2004-03-04
-3sju,2011-09-07,2011-06-21
-1sja,2004-06-01,2004-03-03
-7sjj,2022-05-11,2021-10-17
-6sj3,2020-01-15,2019-08-12
-5sjd,2022-10-12,2022-02-01
-6sjw,2020-02-26,2019-08-14
-1sj3,2004-05-18,2004-03-02
-5sjy,2022-10-12,2022-02-01
-3sj6,2011-08-03,2011-06-21
-8sjy,2024-04-24,2023-04-18
-3sjj,2011-10-12,2011-06-21
-7sjr,2021-12-22,2021-10-18
-3sjb,2011-07-06,2011-06-21
-7sjq,2022-06-08,2021-10-18
-8sji,2023-07-05,2023-04-18
-6sj7,2019-12-18,2019-08-12
-3sjo,2011-08-10,2011-06-21
-5sjc,2022-10-12,2022-02-01
-5sjf,2022-10-12,2022-02-01
-5sjx,2022-10-12,2022-02-01
-3sj5,2011-07-20,2011-06-20
-5sj4,2022-10-12,2022-02-01
-6sjr,2019-09-25,2019-08-13
-5sj1,2022-10-12,2022-02-01
-6sj6,2020-04-08,2019-08-12
-3sjx,2011-10-05,2011-06-22
-3sjc,2011-07-06,2011-06-21
-7sjc,2022-11-23,2021-10-17
-7sj7,2022-01-19,2021-10-16
-1sj2,2004-07-20,2004-03-02
-5sj9,2022-10-12,2022-02-01
-6sjy,2020-01-29,2019-08-14
-7sjb,2022-11-23,2021-10-17
-6sjn,2019-09-25,2019-08-13
-7sje,2022-11-23,2021-10-17
-7sjv,2023-01-11,2021-10-19
-5sji,2022-10-12,2022-02-01
-5sj3,2022-10-12,2022-02-01
-6sjj,2020-06-24,2019-08-13
-1sj7,2004-08-24,2004-03-03
-6sjz,2020-03-18,2019-08-14
-3sjt,2011-07-20,2011-06-21
-5sjt,2022-10-12,2022-02-01
-5sjv,2022-10-12,2022-02-01
-3sjk,2011-08-10,2011-06-21
-6sji,2019-09-18,2019-08-13
-7sjw,2023-01-11,2021-10-19
-3sjz,2012-07-04,2011-06-22
-6sjc,2020-01-08,2019-08-13
-5sjn,2022-10-12,2022-02-01
-5sjb,2022-10-12,2022-02-01
-8sjk,2024-04-24,2023-04-18
-7sj6,2022-10-26,2021-10-16
-7sjh,2022-11-23,2021-10-17
-5sjj,2022-10-12,2022-02-01
-8sj9,2024-05-01,2023-04-17
-5sjr,2022-10-12,2022-02-01
-3sjl,2012-05-02,2011-06-21
-3sjf,2011-10-05,2011-06-21
-5sjm,2022-10-12,2022-02-01
-8sjh,2023-07-05,2023-04-18
-5sj0,2022-10-12,2022-02-01
-1sjz,2005-03-08,2004-03-04
-1sjb,2004-06-01,2004-03-03
-3sje,2011-10-05,2011-06-21
-7sja,2022-01-19,2021-10-16
-3sjh,2012-01-25,2011-06-21
-6sjo,2019-09-25,2019-08-13
-5sjz,2022-10-12,2022-02-01
-7sj1,2022-03-30,2021-10-15
-7sjf,2022-11-23,2021-10-17
-5sj7,2022-10-12,2022-02-01
-5sju,2022-10-12,2022-02-01
-5sjo,2022-10-12,2022-02-01
-8sj2,2024-04-24,2023-04-17
-5sj6,2022-10-12,2022-02-01
-7sj2,2022-05-25,2021-10-15
-5sja,2022-10-12,2022-02-01
-7sjk,2022-10-26,2021-10-18
-7sj8,2022-01-19,2021-10-16
-6sj1,2020-01-15,2019-08-12
-3sjq,2012-05-30,2011-06-21
-3sj1,2012-07-04,2011-06-20
-8sjx,2024-04-24,2023-04-18
-7sjt,2023-01-11,2021-10-19
-1sjc,2004-06-01,2004-03-03
-3sjd,2011-07-13,2011-06-21
-7sju,2023-01-11,2021-10-19
-6sj0,2020-01-15,2019-08-12
-3sjv,2012-02-29,2011-06-22
-8sjd,2023-08-02,2023-04-17
-6sj2,2020-01-15,2019-08-12
-5sjl,2022-10-12,2022-02-01
-5sjh,2022-10-12,2022-02-01
-5sj2,2022-10-12,2022-02-01
-6sja,2019-09-04,2019-08-13
-1sjd,2004-06-01,2004-03-03
-1sj0,2004-04-27,2004-03-02
-7a9e,2021-06-16,2020-09-01
-1a9m,1998-06-17,1998-04-08
-3a9l,2010-11-10,2009-10-30
-5a94,2016-01-20,2015-07-17
-7a91,2020-09-16,2020-09-01
-1a9s,1998-07-15,1998-04-10
-3a9m,2010-03-23,2009-10-30
-8a9o,2023-07-12,2022-06-28
-8a9c,2023-07-12,2022-06-28
-8a94,2023-05-03,2022-06-27
-6a9k,2019-07-24,2018-07-13
-4a9i,2012-01-11,2011-11-26
-8a91,2023-07-05,2022-06-27
-6a98,2018-12-19,2018-07-12
-5a98,2015-09-02,2015-07-17
-1a9e,1998-10-21,1998-04-05
-2a9w,2005-10-11,2005-07-12
-6a99,2018-12-19,2018-07-12
-7a9a,2021-03-03,2020-09-01
-3a9j,2009-12-08,2009-10-29
-2a9a,2005-08-02,2005-07-11
-6a9n,2019-07-17,2018-07-14
-3a90,2010-03-09,2009-10-15
-3a9h,2010-09-08,2009-10-26
-3a9k,2009-12-08,2009-10-29
-3a9v,2010-09-08,2009-11-06
-6a93,2019-02-13,2018-07-11
-3a9e,2010-10-06,2009-10-24
-1a9w,1998-06-17,1998-04-11
-7a9j,2021-05-05,2020-09-02
-8a97,2023-07-05,2022-06-27
-1a95,1998-11-11,1998-04-16
-7a9c,2021-06-30,2020-09-01
-5a9p,2015-09-02,2015-07-21
-8a9n,2023-07-12,2022-06-28
-3a9b,2009-11-03,2009-10-22
-2a9i,2005-10-11,2005-07-11
-1a9t,1998-06-17,1998-04-10
-8a9p,2023-07-12,2022-06-29
-8a9q,2023-05-10,2022-06-29
-2a9o,2006-09-26,2005-07-12
-3a96,2010-03-09,2009-10-15
-4a9o,2012-02-08,2011-11-26
-8a9k,2022-10-12,2022-06-28
-4a9j,2012-01-11,2011-11-26
-7a9u,2020-10-21,2020-09-02
-6a92,2018-12-19,2018-07-11
-4a9e,2012-01-11,2011-11-26
-8a92,2022-11-09,2022-06-27
-4a9k,2012-01-11,2011-11-26
-8a9m,2022-10-05,2022-06-28
-4a9y,2012-05-16,2011-11-29
-4a92,2011-12-28,2011-11-23
-5a9s,2016-06-01,2015-07-22
-4a9c,2012-05-30,2011-11-25
-5a99,2015-09-02,2015-07-17
-3a9r,2010-04-07,2009-11-05
-8a9d,2022-07-20,2022-06-28
-2a9d,2005-08-02,2005-07-11
-6a94,2019-02-13,2018-07-11
-3a9i,2009-12-22,2009-10-28
-4a9s,2012-10-10,2011-11-28
-8a9v,2023-01-11,2022-06-29
-3a9w,2010-11-10,2009-11-07
-1a9y,1998-10-21,1998-04-14
-3a9y,2010-03-16,2009-11-09
-7a9i,2021-05-05,2020-09-02
-7a9z,2021-02-17,2020-09-02
-8a9e,2023-07-12,2022-06-28
-1a9z,1998-10-21,1998-04-14
-4a98,2012-10-17,2011-11-24
-7a9h,2022-03-23,2020-09-02
-3a9q,2009-12-08,2009-11-05
-6a96,2018-10-03,2018-07-11
-6a9u,2019-01-16,2018-07-16
-4a9u,2012-10-10,2011-11-28
-4a97,2012-10-17,2011-11-24
-2a9b,2005-08-02,2005-07-11
-2a9p,2006-09-26,2005-07-12
-5a92,2015-12-16,2015-07-17
-3a93,2010-03-09,2009-10-15
-4a99,2012-12-12,2011-11-25
-3a92,2010-03-09,2009-10-15
-3a9g,2010-09-08,2009-10-26
-3a9t,2010-04-07,2009-11-05
-4a9n,2012-02-08,2011-11-26
-8a90,2023-07-12,2022-06-27
-2a97,2005-09-20,2005-07-11
-3a9x,2010-03-16,2009-11-08
-1a9r,1998-07-15,1998-04-10
-6a9f,2018-12-19,2018-07-13
-4a93,2012-03-21,2011-11-23
-4a94,2011-12-28,2011-11-23
-5a9h,2015-09-09,2015-07-21
-4a9x,2012-12-05,2011-11-29
-2a9e,2006-06-20,2005-07-11
-5a93,2015-12-16,2015-07-17
-4a9w,2012-04-25,2011-11-29
-7a92,2020-09-30,2020-09-01
-5a9t,2016-06-01,2015-07-22
-4a9l,2012-01-11,2011-11-26
-1a97,1998-11-11,1998-04-16
-1a9u,1999-04-20,1998-04-10
-7a9d,2020-12-02,2020-09-01
-4a9m,2012-02-08,2011-11-26
-8a9i,2022-08-31,2022-06-28
-1a9c,1999-05-11,1998-04-04
-8a98,2023-10-11,2022-06-28
-2a94,2006-01-10,2005-07-11
-4a9t,2012-10-10,2011-11-28
-5a9z,2015-10-14,2015-07-23
-7a9y,2021-02-17,2020-09-02
-6a95,2018-08-08,2018-07-11
-8a9j,2022-10-12,2022-06-28
-4a9v,2012-12-05,2011-11-28
-8a9z,2022-11-09,2022-06-29
-8a9t,2022-11-09,2022-06-29
-3a91,2010-03-09,2009-10-15
-4a9h,2012-01-11,2011-11-26
-8a99,2023-05-10,2022-06-28
-4a91,2012-01-11,2011-11-22
-5a95,2016-01-20,2015-07-17
-8a9g,2022-12-28,2022-06-28
-5a96,2015-09-02,2015-07-17
-1a96,1998-11-11,1998-04-16
-8a93,2023-04-26,2022-06-27
-3a95,2010-03-09,2009-10-15
-6a90,2018-08-08,2018-07-11
-2a99,2005-08-02,2005-07-11
-3a99,2010-11-03,2009-10-22
-4a9r,2012-10-10,2011-11-28
-6a9a,2019-01-02,2018-07-12
-3a94,2010-03-09,2009-10-15
-5a9u,2016-06-08,2015-07-22
-7a9g,2022-03-23,2020-09-02
-5a9w,2015-08-26,2015-07-23
-2a9g,2005-08-09,2005-07-11
-2a91,2005-07-26,2005-07-11
-1a9b,1998-10-21,1998-04-03
-5a9k,2015-08-26,2015-07-21
-6a9v,2019-01-16,2018-07-16
-8a9s,2022-10-19,2022-06-29
-5a9y,2015-08-26,2015-07-23
-5a9a,2015-09-02,2015-07-17
-2a9n,2005-10-25,2005-07-12
-3a9f,2010-03-02,2009-10-25
-5a9f,2015-12-16,2015-07-21
-6a9o,2019-07-17,2018-07-14
-6a9t,2019-01-16,2018-07-16
-5a9g,2015-08-05,2015-07-21
-2a9r,2006-09-26,2005-07-12
-1a9p,1998-07-15,1998-04-10
-2a98,2005-07-19,2005-07-11
-2a9k,2005-10-11,2005-07-12
-1a9q,1998-07-15,1998-04-10
-6a9c,2019-06-12,2018-07-13
-7a9v,2021-10-06,2020-09-02
-3a9c,2010-11-03,2009-10-22
-3a9z,2010-03-16,2009-11-09
-7a99,2020-11-04,2020-09-01
-2a9z,2006-07-11,2005-07-12
-8a9y,2023-06-07,2022-06-29
-4a95,2012-06-27,2011-11-24
-1a9x,1998-10-21,1998-04-14
-6a91,2018-08-08,2018-07-11
-7a90,2021-10-06,2020-09-01
-8a95,2023-08-16,2022-06-27
-2a9y,2006-07-11,2005-07-12
-2a92,2006-01-10,2005-07-11
-5a9x,2015-08-26,2015-07-23
-1a94,1999-01-13,1998-04-16
-2a9f,2005-08-02,2005-07-11
-2a9c,2005-08-02,2005-07-11
-3a9s,2010-04-07,2009-11-05
-7a94,2020-09-16,2020-09-01
-8uc3,2024-05-15,2023-09-25
-4ucv,2015-10-14,2014-12-04
-1uc0,2003-04-22,2003-04-07
-6uca,2019-10-16,2019-09-15
-4ucz,2015-11-18,2014-12-05
-7uca,2022-03-30,2022-03-16
-1ucq,2003-12-30,2003-04-17
-7ucd,2023-01-25,2022-03-16
-1uc4,2003-07-22,2003-04-08
-5ucm,2017-02-22,2016-12-22
-6uc4,2020-01-01,2019-09-13
-7uck,2022-06-01,2022-03-16
-3ucm,2011-11-23,2011-10-27
-8ucx,2023-10-11,2023-09-27
-6uc1,2019-10-23,2019-09-13
-5uck,2018-04-11,2016-12-22
-5uc3,2017-12-27,2016-12-21
-4ucf,2016-01-20,2014-12-03
-5uch,2018-01-10,2016-12-22
-3uc1,2012-03-28,2011-10-25
-4ucp,2015-05-13,2014-12-04
-7ucl,2022-06-01,2022-03-16
-5ucy,2017-05-10,2016-12-22
-4uc8,2015-08-19,2014-12-03
-1uc9,2003-09-23,2003-04-09
-3ucz,2012-01-04,2011-10-27
-5ucv,2017-01-11,2016-12-22
-3ucp,2012-08-08,2011-10-27
-7uc5,2022-10-12,2022-03-16
-7uc3,2023-03-22,2022-03-15
-5uci,2018-01-03,2016-12-22
-5ucs,2018-04-11,2016-12-22
-4ucd,2015-08-19,2014-12-03
-3uce,2012-11-28,2011-10-26
-3ucn,2011-11-23,2011-10-27
-6uc2,2020-03-25,2019-09-13
-8uce,2024-02-21,2023-09-26
-8uc9,2024-01-10,2023-09-26
-3uco,2011-11-23,2011-10-27
-4uc1,2015-02-04,2014-08-13
-6ucg,2020-03-04,2019-09-16
-6ucw,2020-09-23,2019-09-17
-5ucw,2017-05-17,2016-12-22
-1ucn,2003-09-30,2003-04-16
-8ucw,2023-10-11,2023-09-27
-4uco,2015-10-14,2014-12-04
-7uc9,2022-03-30,2022-03-16
-8uci,2024-02-21,2023-09-26
-5ucj,2018-01-10,2016-12-22
-4uct,2015-10-14,2014-12-04
-6uc3,2020-09-16,2019-09-13
-5ucu,2017-03-01,2016-12-22
-7uce,2022-08-17,2022-03-16
-3ucj,2011-11-23,2011-10-27
-8ucv,2023-10-11,2023-09-27
-6uco,2020-06-24,2019-09-17
-3ucw,2012-08-08,2011-10-27
-7uch,2022-06-01,2022-03-16
-3ucb,2012-03-28,2011-10-26
-6uce,2020-03-18,2019-09-16
-4ucg,2016-01-13,2014-12-03
-5ucn,2018-04-11,2016-12-22
-7ucu,2022-03-30,2022-03-17
-4ucy,2015-11-18,2014-12-05
-4uch,2014-12-24,2014-12-03
-8uc2,2023-10-04,2023-09-25
-4ucw,2015-02-18,2014-12-04
-4uca,2015-08-19,2014-12-03
-8ucg,2024-02-21,2023-09-26
-5ucp,2018-04-11,2016-12-22
-1ucd,2004-05-18,2003-04-10
-5ucd,2017-04-12,2016-12-22
-3ucy,2012-08-08,2011-10-27
-4uc9,2015-08-19,2014-12-03
-4ucm,2015-05-13,2014-12-04
-6ucb,2019-12-04,2019-09-15
-4ucb,2015-08-19,2014-12-03
-6uc0,2020-01-01,2019-09-13
-5uc1,2017-12-27,2016-12-21
-4ucl,2015-11-18,2014-12-03
-4ucs,2015-10-14,2014-12-04
-7uc8,2023-02-15,2022-03-16
-8uch,2024-02-21,2023-09-26
-6ucs,2020-01-01,2019-09-17
-6ucf,2020-03-18,2019-09-16
-4ucc,2015-08-19,2014-12-03
-5uc4,2018-01-17,2016-12-21
-4ucj,2015-11-18,2014-12-03
-4uce,2015-08-19,2014-12-03
-7ucy,2022-08-17,2022-03-17
-8uct,2024-05-08,2023-09-27
-7uc2,2022-09-14,2022-03-15
-3ucd,2012-08-22,2011-10-26
-6ucz,2019-10-16,2019-09-18
-1ucg,2003-04-29,2003-04-14
-4ucx,2015-02-18,2014-12-05
-4ucn,2015-05-13,2014-12-04
-3uck,2011-11-23,2011-10-27
-8uc0,2024-03-27,2023-09-25
-7ucj,2022-06-01,2022-03-16
-4ucr,2015-10-14,2014-12-04
-4ucu,2015-10-14,2014-12-04
-6ucm,2020-01-15,2019-09-16
-6ucn,2020-09-23,2019-09-16
-3uc5,2012-11-07,2011-10-26
-4uc5,2015-11-25,2014-12-03
-1uca,2003-04-29,2003-04-10
-8ucu,2023-10-11,2023-09-27
-1uc5,2003-07-22,2003-04-08
-5ucr,2017-01-11,2016-12-22
-7uc7,2023-02-15,2022-03-16
-3uct,2012-08-08,2011-10-27
-8ucd,2023-11-22,2023-09-26
-4ucq,2015-02-18,2014-12-04
-5uc6,2017-10-11,2016-12-21
-6ucp,2020-06-24,2019-09-17
-5ucz,2018-04-11,2016-12-23
-6ucy,2020-09-23,2019-09-18
-4uci,2015-10-14,2014-12-03
-7uc6,2023-02-15,2022-03-16
-3ucc,2012-08-22,2011-10-26
-7ucf,2022-08-17,2022-03-16
-7ucc,2023-01-25,2022-03-16
-1ucc,2003-04-29,2003-04-10
-4uc0,2014-10-08,2014-08-13
-4uck,2015-11-18,2014-12-03
-5ucq,2017-02-08,2016-12-22
-7ucg,2022-08-17,2022-03-16
-1uc2,2004-05-04,2003-04-08
-7ucw,2023-03-22,2022-03-17
-6ucq,2019-12-25,2019-09-17
-3uc3,2011-12-14,2011-10-25
-7uci,2022-06-01,2022-03-16
-3ucl,2012-04-25,2011-10-27
-1uc3,2003-04-29,2003-04-08
-8ucf,2024-02-21,2023-09-26
-1cwf,1998-07-15,1998-04-30
-4cwx,2014-08-13,2014-04-03
-5cw4,2015-09-16,2015-07-27
-7cwv,2021-09-01,2020-08-31
-8cwk,2023-05-24,2022-05-19
-6cwy,2019-01-16,2018-04-01
-6cwf,2018-08-15,2018-03-30
-6cw8,2018-11-21,2018-03-30
-4cw3,2014-10-29,2014-04-01
-3cwz,2008-11-18,2008-04-23
-6cw3,2018-09-19,2018-03-29
-7cwh,2021-05-26,2020-08-28
-7cwz,2021-09-01,2020-09-01
-6cww,2018-05-16,2018-03-31
-8cwu,2022-07-06,2022-05-19
-6cwr,2018-08-15,2018-03-30
-4cw1,2015-05-06,2014-03-31
-7cwd,2020-12-09,2020-08-27
-2cwu,2006-05-02,2005-06-26
-2cwf,2005-10-04,2005-06-20
-2cwd,2006-09-05,2005-06-20
-4cwp,2014-07-09,2014-04-03
-1cw7,1999-09-01,1999-08-25
-7cwm,2020-12-16,2020-08-29
-4cw5,2014-12-17,2014-04-01
-2cwg,1994-01-31,1993-01-08
-1cw0,1999-12-12,1999-08-25
-8cwe,2022-06-22,2022-05-19
-2cww,2005-10-11,2005-06-27
-8cw0,2022-06-22,2022-05-18
-6cwz,2019-01-16,2018-04-01
-3cwq,2008-05-13,2008-04-22
-8cwh,2022-06-22,2022-05-19
-8cwb,2022-06-22,2022-05-19
-1cwp,1995-05-22,1995-05-22
-4cwa,2014-10-08,2014-04-01
-7cwl,2021-01-27,2020-08-29
-6cwe,2019-04-03,2018-03-30
-8cw6,2022-06-22,2022-05-18
-1cw1,1999-09-01,1999-08-25
-2cw3,2006-07-04,2005-06-16
-2cw2,2006-07-04,2005-06-16
-4cw7,2014-05-28,2014-04-01
-8cwl,2023-03-08,2022-05-19
-6cw7,2019-01-09,2018-03-30
-7cwe,2021-09-08,2020-08-28
-3cwj,2009-04-21,2008-04-21
-1cw2,1999-12-21,1999-08-25
-1cwd,1996-12-07,1995-09-06
-3cwh,2008-08-05,2008-04-21
-4cwm,2014-07-23,2014-04-03
-6cwj,2019-06-12,2018-03-30
-1cw4,1999-09-01,1999-08-25
-8cwd,2022-06-22,2022-05-19
-8cw3,2022-06-22,2022-05-18
-6cw4,2018-10-24,2018-03-29
-6cw0,2018-04-18,2018-03-29
-6cw9,2019-04-03,2018-03-30
-8cwc,2022-06-22,2022-05-19
-5cw1,2015-12-30,2015-07-27
-1cwq,1999-10-20,1999-08-26
-4cwq,2014-07-09,2014-04-03
-1cwj,1998-08-26,1998-05-25
-4cwr,2014-07-09,2014-04-03
-4cww,2014-08-13,2014-04-03
-6cwp,2018-04-18,2018-03-30
-8cw1,2022-06-22,2022-05-18
-5cw2,2016-08-17,2015-07-27
-2cwv,2006-05-02,2005-06-26
-7cwg,2021-09-01,2020-08-28
-8cw8,2022-06-22,2022-05-18
-8cwg,2022-06-22,2022-05-19
-1cwu,1999-09-02,1999-08-26
-6cwh,2018-08-15,2018-03-30
-7cwu,2020-12-16,2020-08-31
-1cwe,1996-12-07,1995-09-06
-8cw7,2022-06-22,2022-05-18
-6cwl,2018-08-15,2018-03-30
-5cwl,2015-12-16,2015-07-28
-6cwu,2018-10-31,2018-03-31
-4cwf,2014-07-09,2014-04-02
-2cwm,2006-01-17,2005-06-22
-6cwa,2019-08-07,2018-03-30
-8cw2,2023-04-12,2022-05-18
-4cwb,2015-01-28,2014-04-02
-2cwt,2006-05-02,2005-06-26
-4cwv,2014-08-13,2014-04-03
-1cw3,1999-08-31,1999-08-25
-8cwp,2022-09-28,2022-05-19
-4cwd,2014-09-17,2014-04-02
-5cwe,2016-08-03,2015-07-28
-5cw3,2015-09-16,2015-07-27
-5cwy,2016-08-03,2015-07-28
-8cwj,2023-05-24,2022-05-19
-3cw8,2008-09-02,2008-04-21
-1cwl,1998-07-15,1998-05-26
-7cwt,2021-06-23,2020-08-31
-3cwy,2008-12-30,2008-04-23
-4cwn,2014-07-09,2014-04-03
-2cw0,2005-09-20,2005-06-15
-4cwz,2014-08-13,2014-04-03
-8cwv,2022-07-06,2022-05-19
-7cwn,2020-12-16,2020-08-29
-5cwa,2015-08-12,2015-07-28
-1cwm,1998-07-15,1998-05-26
-1cwo,1998-08-12,1998-06-05
-7cws,2020-12-16,2020-08-31
-6cwn,2018-08-15,2018-03-30
-8cw5,2022-06-22,2022-05-18
-6cwo,2018-06-27,2018-03-30
-5cw6,2015-09-16,2015-07-27
-1cwi,1998-08-12,1998-05-25
-1cwb,1996-01-29,1995-09-06
-1cwc,1996-01-29,1995-09-06
-6cwb,2019-04-03,2018-03-30
-4cwo,2014-07-09,2014-04-03
-4cw6,2014-10-29,2014-04-01
-5cw8,2016-02-17,2015-07-27
-3cww,2008-11-25,2008-04-23
-6cwq,2018-04-18,2018-03-30
-2cw6,2005-12-06,2005-06-17
-2cwh,2005-10-04,2005-06-20
-3cw9,2008-09-02,2008-04-21
-1cwa,1996-01-29,1995-09-06
-8cwi,2023-05-24,2022-05-19
-4cw2,2014-10-29,2014-04-01
-5cwf,2015-12-16,2015-07-28
-6cw2,2018-09-19,2018-03-29
-8cwo,2023-03-15,2022-05-19
-8cwf,2022-06-22,2022-05-19
-8cwr,2023-05-17,2022-05-19
-5cwx,2016-08-03,2015-07-28
-6cwv,2018-10-24,2018-03-31
-8cw9,2022-08-10,2022-05-18
-4cws,2014-07-09,2014-04-03
-1cw8,1999-09-03,1999-08-26
-5cws,2015-10-14,2015-07-28
-6cwi,2018-08-15,2018-03-30
-3cwd,2008-07-08,2008-04-21
-3cwb,2008-08-12,2008-04-21
-4cwt,2014-07-09,2014-04-03
-4cw0,2014-10-29,2014-03-31
-4cwy,2014-08-13,2014-04-03
-8cwt,2023-05-17,2022-05-19
-5cwr,2016-02-24,2015-07-28
-1cwz,1999-09-03,1999-08-27
-8cww,2023-06-07,2022-05-19
-7cw1,2020-09-16,2020-08-27
-7cw5,2020-10-07,2020-08-27
-3cwk,2008-09-09,2008-04-22
-6cw6,2019-04-03,2018-03-29
-7cwf,2021-09-01,2020-08-28
-7cwa,2021-09-01,2020-08-27
-1cwh,1998-07-15,1998-05-07
-1cwk,1998-07-15,1998-05-26
-3cwe,2008-06-10,2008-04-21
-8psq,2023-12-27,2023-07-13
-8psx,2023-12-27,2023-07-13
-1pst,1994-04-30,1993-12-13
-4psw,2014-07-09,2014-03-08
-5psm,2017-03-29,2017-02-07
-6psx,2019-09-25,2019-07-14
-6ps4,2019-11-13,2019-07-12
-5ps5,2017-03-29,2017-02-07
-7psk,2022-08-03,2021-09-23
-7ps4,2021-12-15,2021-09-22
-2psj,2007-06-05,2007-05-06
-8ps1,2023-11-22,2023-07-13
-6psr,2020-03-25,2019-07-13
-4psg,2015-02-18,2014-03-07
-3psl,2010-12-22,2010-12-01
-2ps1,2008-01-15,2007-05-04
-1ps6,2003-11-04,2003-06-20
-3psr,1999-06-15,1998-09-17
-4ps1,2015-01-21,2014-03-06
-7psa,2022-04-06,2021-09-22
-3psd,2011-05-18,2010-12-01
-5ps9,2017-03-29,2017-02-07
-6psn,2020-03-04,2019-07-12
-5psa,2017-03-29,2017-02-07
-1psh,1994-01-31,1992-07-28
-5psn,2017-03-29,2017-02-07
-3pso,2010-12-15,2010-12-02
-1psa,1994-01-31,1991-10-22
-5ps6,2017-03-29,2017-02-07
-5psc,2017-03-29,2017-02-07
-2psx,2007-09-11,2007-05-07
-6ps7,2019-11-13,2019-07-12
-5pse,2017-03-29,2017-02-07
-3psb,2011-01-19,2010-12-01
-5psr,2017-03-29,2017-02-07
-4ps5,2014-03-19,2014-03-06
-4pse,2014-09-17,2014-03-07
-7ps5,2021-12-15,2021-09-22
-1ps0,2004-06-29,2003-06-20
-5ps7,2017-03-29,2017-02-07
-1pss,1994-04-30,1993-12-13
-1pso,1995-04-20,1995-01-23
-7pse,2022-10-05,2021-09-23
-7psf,2022-10-05,2021-09-23
-8pss,2023-12-27,2023-07-13
-1ps3,2003-12-16,2003-06-20
-8psn,2023-12-27,2023-07-13
-2psw,2007-06-05,2007-05-07
-5psk,2017-03-29,2017-02-07
-7psm,2021-12-29,2021-09-23
-7ps0,2021-12-15,2021-09-22
-6ps0,2019-11-13,2019-07-12
-5psw,2017-03-29,2017-02-07
-2psy,2007-09-11,2007-05-07
-3psn,2010-12-15,2010-12-02
-6psa,2020-02-05,2019-07-12
-5pst,2017-03-29,2017-02-07
-6ps2,2019-11-13,2019-07-12
-5psx,2017-03-29,2017-02-07
-8psp,2023-11-22,2023-07-13
-5pso,2017-03-29,2017-02-07
-5ps0,2017-03-29,2017-02-07
-7psn,2021-12-29,2021-09-23
-5psq,2017-03-29,2017-02-07
-6psw,2020-03-25,2019-07-13
-6ps1,2019-11-13,2019-07-12
-6ps6,2019-11-13,2019-07-12
-8psm,2023-11-22,2023-07-13
-2ps4,2007-12-18,2007-05-04
-4psr,2014-03-19,2014-03-07
-8psg,2023-11-22,2023-07-13
-4ps7,2014-05-14,2014-03-06
-1psc,1997-04-01,1995-04-25
-6psb,2019-11-27,2019-07-12
-5psj,2017-03-29,2017-02-07
-3ps1,2011-01-19,2010-11-30
-7ps1,2021-12-15,2021-09-22
-8psf,2023-11-22,2023-07-13
-1ps9,2003-09-30,2003-06-20
-8psd,2023-11-01,2023-07-13
-5ps1,2017-03-29,2017-02-07
-8psa,2023-11-22,2023-07-13
-6psy,2019-09-25,2019-07-14
-7pso,2022-03-16,2021-09-23
-4psh,2014-07-23,2014-03-07
-6psq,2020-03-25,2019-07-13
-4ps2,2015-03-11,2014-03-06
-2ps7,2007-12-18,2007-05-04
-6psm,2019-09-25,2019-07-12
-8psu,2023-12-27,2023-07-13
-3psq,2011-01-19,2010-12-02
-3psy,2011-12-07,2010-12-02
-2ps9,2007-06-05,2007-05-04
-3ps9,2010-12-22,2010-12-01
-7psp,2022-10-05,2021-09-23
-5psi,2017-03-29,2017-02-07
-2ps2,2007-05-22,2007-05-04
-5psf,2017-03-29,2017-02-07
-4psy,2014-05-14,2014-03-08
-7ps6,2021-12-15,2021-09-22
-2ps8,2007-12-18,2007-05-04
-7ps2,2021-12-15,2021-09-22
-6psd,2020-07-15,2019-07-12
-6psj,2019-11-20,2019-07-12
-4psx,2014-07-09,2014-03-08
-3psx,2011-12-07,2010-12-02
-5psl,2017-03-29,2017-02-07
-5psh,2017-03-29,2017-02-07
-5psd,2017-03-29,2017-02-07
-3ps6,2011-02-09,2010-11-30
-5ps8,2017-03-29,2017-02-07
-8pso,2023-12-27,2023-07-13
-5ps4,2017-03-29,2017-02-07
-3psu,2011-12-07,2010-12-02
-1psz,2000-04-19,1998-10-13
-5ps3,2017-03-29,2017-02-07
-6ps9,2019-11-27,2019-07-12
-7psy,2022-01-12,2021-09-24
-6pss,2020-03-25,2019-07-13
-7psw,2022-07-20,2021-09-24
-8psk,2023-11-22,2023-07-13
-4pso,2014-04-30,2014-03-07
-7psq,2022-10-05,2021-09-23
-4ps8,2014-05-14,2014-03-06
-7psz,2022-08-17,2021-09-24
-2psn,2008-05-20,2007-05-07
-6ps8,2019-11-13,2019-07-12
-6pst,2020-03-25,2019-07-13
-6pso,2019-09-25,2019-07-13
-4psq,2014-07-02,2014-03-07
-4psb,2014-07-23,2014-03-07
-7psc,2023-04-05,2021-09-22
-1ps7,2003-11-04,2003-06-20
-4ps3,2014-05-14,2014-03-06
-5pss,2017-03-29,2017-02-07
-3ps2,2011-01-19,2010-11-30
-7psx,2022-10-05,2021-09-24
-4ps0,2015-01-21,2014-03-06
-1psd,1995-07-31,1995-05-02
-8psj,2023-11-22,2023-07-13
-4psp,2014-03-19,2014-03-07
-5psp,2017-03-29,2017-02-07
-5ps2,2017-03-29,2017-02-07
-8ps9,2023-11-22,2023-07-13
-2ps5,2007-12-18,2007-05-04
-4pss,2014-06-04,2014-03-07
-6psp,2020-07-01,2019-07-13
-5psb,2017-03-29,2017-02-07
-7psj,2022-08-03,2021-09-23
-5psz,2017-03-29,2017-02-07
-7ps9,2022-03-16,2021-09-22
-5psy,2017-03-29,2017-02-07
-7psi,2022-08-03,2021-09-23
-2psv,2007-06-05,2007-05-07
-8psz,2024-01-10,2023-07-13
-6psl,2019-11-27,2019-07-12
-6ps3,2019-11-13,2019-07-12
-8psl,2023-11-22,2023-07-13
-2psr,1999-06-15,1998-09-17
-6psg,2020-01-22,2019-07-12
-2psu,2007-06-05,2007-05-07
-3pse,2011-01-19,2010-12-01
-8ps2,2023-11-22,2023-07-13
-1psj,1996-07-11,1995-05-24
-5psg,2017-03-29,2017-02-07
-6psv,2020-03-25,2019-07-13
-5psv,2017-03-29,2017-02-07
-5psu,2017-03-29,2017-02-07
-6ps5,2019-11-13,2019-07-12
-4pst,2014-06-04,2014-03-07
-6psu,2020-03-25,2019-07-13
-2ps0,2007-06-05,2007-05-04
-3ps3,2011-01-19,2010-11-30
-4psa,2015-03-18,2014-03-07
-5rcr,2020-06-03,2020-03-24
-5rcf,2020-06-03,2020-03-24
-8rcv,2024-05-15,2023-12-07
-1rcs,1996-06-20,1995-05-12
-2rcn,2008-01-29,2007-09-20
-5rce,2020-06-03,2020-03-24
-6rcw,2019-07-24,2019-04-11
-2rc0,2008-03-18,2007-09-19
-2rc9,2008-08-05,2007-09-19
-6rc5,2020-02-19,2019-04-11
-4rc5,2014-12-17,2014-09-14
-1rca,1995-09-15,1994-07-18
-6rcj,2020-05-13,2019-04-11
-6rcb,2020-04-08,2019-04-11
-3rcb,2011-06-08,2011-03-30
-6rcn,2019-10-09,2019-04-11
-4rcp,2014-11-12,2014-09-16
-6rca,2020-05-13,2019-04-11
-2rck,2008-03-04,2007-09-20
-4rcr,1993-10-31,1991-09-09
-4rca,2014-11-19,2014-09-15
-2rc3,2007-10-02,2007-09-19
-6rc6,2020-02-19,2019-04-11
-3rci,2012-03-21,2011-03-31
-5rcb,2020-06-03,2020-03-24
-1rc1,2005-06-14,2003-11-03
-7rcl,2021-09-29,2021-07-07
-5rc1,2020-06-03,2020-03-24
-2rcm,2008-08-19,2007-09-20
-6rc4,2020-02-19,2019-04-11
-4rc7,2014-12-17,2014-09-14
-3rck,2012-03-21,2011-03-31
-3rcj,2011-06-15,2011-03-31
-4rcf,2014-12-24,2014-09-15
-6rcz,2020-02-19,2019-04-12
-3rc1,2011-06-08,2011-03-30
-5rco,2020-06-03,2020-03-24
-4rck,2014-11-26,2014-09-16
-5rcj,2020-06-03,2020-03-24
-4rcg,2015-04-08,2014-09-16
-6rc1,2020-02-19,2019-04-11
-7rck,2022-03-02,2021-07-07
-2rcl,2008-08-19,2007-09-20
-5rc7,2020-06-03,2020-03-24
-1rcf,1995-01-26,1994-10-31
-3rch,2011-10-19,2011-03-31
-4rc4,2015-03-18,2014-09-14
-5rc4,2020-06-03,2020-03-24
-3rc0,2011-05-25,2011-03-30
-1rc4,1997-03-12,1996-11-25
-2rca,2008-08-05,2007-09-19
-3rce,2011-06-15,2011-03-31
-3rcc,2011-09-07,2011-03-30
-7rc3,2022-03-30,2021-07-07
-3rc2,2011-06-08,2011-03-30
-7rc1,2021-09-29,2021-07-07
-7rcx,2022-03-23,2021-07-08
-4rco,2014-10-01,2014-09-16
-7rcg,2022-06-29,2021-07-07
-7rcy,2022-03-23,2021-07-08
-1rc8,2004-02-17,2003-11-03
-7rci,2022-03-02,2021-07-07
-8rcs,2024-03-06,2023-12-07
-4rc6,2014-12-17,2014-09-14
-3rc6,2011-05-04,2011-03-30
-5rc3,2020-06-03,2020-03-24
-1rct,2004-01-20,2003-11-04
-2rc5,2008-03-25,2007-09-19
-2rcw,2008-09-23,2007-09-20
-2rc2,2008-03-18,2007-09-19
-3rc5,2011-05-04,2011-03-30
-6rcf,2020-05-13,2019-04-11
-7rcu,2022-09-14,2021-07-08
-4rcv,2015-03-18,2014-09-17
-3rc9,2011-06-08,2011-03-30
-6rcg,2020-03-25,2019-04-11
-3rc7,2011-06-08,2011-03-30
-5rcd,2020-06-03,2020-03-24
-4rcz,2015-05-27,2014-09-18
-2rcv,2008-02-26,2007-09-20
-8rc0,2024-03-27,2023-12-05
-6rcx,2020-04-15,2019-04-12
-7rce,2022-06-29,2021-07-07
-7rcf,2022-06-29,2021-07-07
-6rc0,2020-02-19,2019-04-11
-1rcq,2004-06-01,2003-11-04
-7rc6,2022-03-30,2021-07-07
-1rcp,1996-06-10,1995-08-23
-6rcm,2020-04-08,2019-04-11
-4rch,2014-10-08,2014-09-16
-2rcc,2007-10-02,2007-09-19
-7rcd,2022-06-29,2021-07-07
-6rc2,2020-02-19,2019-04-11
-1rcj,2004-02-17,2003-11-04
-7rcw,2022-03-23,2021-07-08
-5rcp,2020-06-03,2020-03-24
-5rcn,2020-06-03,2020-03-24
-3rcf,2012-03-21,2011-03-31
-3rcl,2012-03-21,2011-03-31
-3rcm,2011-04-20,2011-03-31
-2rc7,2008-08-05,2007-09-19
-7rc9,2022-05-04,2021-07-07
-4rce,2014-12-24,2014-09-15
-6rcc,2020-11-04,2019-04-11
-8rc1,2024-03-13,2023-12-05
-8rc4,2024-02-07,2023-12-06
-2rc8,2008-08-05,2007-09-19
-3rc8,2011-05-11,2011-03-30
-5rca,2020-06-03,2020-03-24
-7rcv,2021-12-29,2021-07-08
-2rch,2008-08-19,2007-09-20
-1rcn,1994-09-30,1994-05-27
-1rcv,2004-10-26,2003-11-04
-1rcw,2004-05-04,2003-11-04
-2rc6,2008-03-25,2007-09-19
-7rcj,2022-05-18,2021-07-07
-4rcm,2014-11-19,2014-09-16
-7rc5,2022-03-30,2021-07-07
-2rc1,2008-04-01,2007-09-19
-6rc3,2020-02-19,2019-04-11
-6rcr,2019-08-21,2019-04-11
-5rcu,2020-06-03,2020-03-24
-1rcx,1997-06-16,1996-12-06
-5rc5,2020-06-03,2020-03-24
-5rcy,2020-06-03,2020-03-24
-2rcy,2007-10-23,2007-09-20
-2rcb,2008-08-05,2007-09-19
-5rc9,2020-06-03,2020-03-24
-8rcg,2024-05-08,2023-12-06
-6rct,2019-05-01,2019-04-11
-1rco,1997-03-12,1996-10-31
-3rc4,2011-05-04,2011-03-30
-4rc3,2015-03-18,2014-09-14
-4rcy,2015-05-27,2014-09-18
-5rc6,2020-06-03,2020-03-24
-7rc4,2022-03-30,2021-07-07
-7rct,2021-09-01,2021-07-08
-6rch,2020-03-25,2019-04-11
-5rct,2020-06-03,2020-03-24
-1rc5,2004-03-30,2003-11-03
-7rcz,2022-03-23,2021-07-08
-1rcy,1997-05-15,1996-04-10
-5rc2,2020-06-03,2020-03-24
-6rce,2019-07-10,2019-04-11
-7rc2,2022-03-30,2021-07-07
-6rcl,2019-10-09,2019-04-11
-8rcm,2024-03-06,2023-12-06
-4rc2,2015-03-18,2014-09-14
-7rcp,2022-04-20,2021-07-07
-2rc4,2007-11-13,2007-09-19
-2rcr,1993-07-15,1991-02-04
-5rci,2020-06-03,2020-03-24
-7rcm,2021-09-29,2021-07-07
-8rcw,2024-04-10,2023-12-07
-5rcw,2020-06-03,2020-03-24
-8rcl,2024-03-13,2023-12-06
-5rc8,2020-06-03,2020-03-24
-4rcx,2015-09-30,2014-09-17
-7rcc,2022-06-29,2021-07-07
-4rcd,2015-01-21,2014-09-15
-2rct,2007-10-02,2007-09-20
-5rck,2020-06-03,2020-03-24
-6rcy,2020-05-13,2019-04-12
-3rcd,2011-11-23,2011-03-30
-3rc3,2011-05-11,2011-03-30
-3rcy,2011-05-18,2011-03-31
-1rc0,2005-06-14,2003-11-03
-5rcc,2020-06-03,2020-03-24
-8rct,2024-03-06,2023-12-07
-5rc0,2020-06-03,2020-03-24
-4rc8,2014-12-17,2014-09-14
-7rc0,2021-09-29,2021-07-06
-5rcg,2020-06-03,2020-03-24
-2rcx,2007-11-27,2007-09-20
-7jwi,2021-07-07,2020-08-25
-7jwx,2021-08-04,2020-08-26
-7jwf,2020-11-04,2020-08-25
-1jwv,2002-06-05,2001-09-05
-1jwu,2003-07-08,2001-09-05
-6jwu,2020-02-12,2019-04-21
-7jw8,2021-03-10,2020-08-25
-4jwd,2013-11-13,2013-03-27
-7jwq,2021-03-24,2020-08-26
-8jw0,2024-02-28,2023-06-28
-7jwv,2020-12-30,2020-08-26
-5jwy,2016-07-20,2016-05-12
-3jwy,2010-05-05,2009-09-18
-4jwf,2013-10-16,2013-03-27
-1jwg,2002-03-06,2001-09-04
-1jwj,2001-10-31,2001-09-04
-5jwv,2016-09-21,2016-05-12
-4jwl,2013-10-23,2013-03-27
-7jww,2020-12-30,2020-08-26
-3jwp,2009-10-20,2009-09-18
-7jw5,2021-09-01,2020-08-24
-3jwq,2009-10-13,2009-09-18
-4jwm,2013-06-26,2013-03-27
-3jw3,2010-09-15,2009-09-17
-3jwc,2010-09-29,2009-09-18
-4jwe,2013-11-13,2013-03-27
-3jwg,2009-10-20,2009-09-18
-4jws,2013-06-19,2013-03-27
-1jwz,2002-06-05,2001-09-05
-3jwu,2010-05-05,2009-09-18
-8jwm,2024-04-10,2023-06-29
-5jwg,2017-06-14,2016-05-12
-1jw0,2002-09-01,2001-09-01
-4jwq,2013-04-17,2013-03-27
-3jw2,2009-12-08,2009-09-17
-5jw3,2016-08-03,2016-05-11
-3jw5,2010-09-15,2009-09-17
-8jwn,2024-04-10,2023-06-29
-3jw1,2009-10-06,2009-09-17
-3jwe,2010-01-26,2009-09-18
-1jw8,2001-10-10,2001-09-03
-4jwj,2013-10-16,2013-03-27
-5jwd,2017-05-24,2016-05-12
-4jwu,2013-06-19,2013-03-27
-6jwx,2020-02-12,2019-04-21
-4jwt,2013-05-08,2013-03-27
-5jwp,2016-11-23,2016-05-12
-6jwt,2020-02-12,2019-04-21
-5jwa,2017-03-22,2016-05-11
-1jwk,2001-10-31,2001-09-04
-3jwv,2010-05-05,2009-09-18
-4jwy,2013-05-29,2013-03-27
-1jwa,2001-11-21,2001-09-03
-6jwi,2019-12-25,2019-04-20
-2jwo,2007-11-06,2007-10-17
-1jw1,2003-04-29,2001-09-02
-3jwh,2009-10-20,2009-09-18
-4jwx,2013-05-29,2013-03-27
-3jw9,2010-09-08,2009-09-18
-3jwz,2010-05-05,2009-09-18
-7jw9,2021-05-26,2020-08-25
-5jwm,2016-07-06,2016-05-12
-5jwi,2017-06-14,2016-05-12
-1jwn,2001-12-18,2001-09-04
-1jwb,2001-11-21,2001-09-03
-3jwo,2009-12-29,2009-09-18
-1jwl,2001-10-05,2001-09-04
-8jwg,2023-08-30,2023-06-29
-5jw4,2016-08-03,2016-05-11
-8jwz,2023-08-16,2023-06-29
-1jw6,2001-09-26,2001-09-02
-8jwu,2023-12-20,2023-06-29
-5jwu,2016-09-21,2016-05-12
-5jwk,2017-05-17,2016-05-12
-5jwq,2017-03-29,2016-05-12
-3jwd,2009-12-29,2009-09-18
-5jwc,2017-03-22,2016-05-12
-6jwh,2019-12-25,2019-04-20
-8jwj,2023-12-20,2023-06-29
-6jwn,2020-04-22,2019-04-21
-6jwf,2019-11-06,2019-04-20
-1jwy,2001-11-07,2001-09-05
-5jw7,2017-02-15,2016-05-11
-8jwy,2023-08-16,2023-06-29
-3jwa,2010-09-08,2009-09-18
-6jww,2020-02-12,2019-04-21
-4jwc,2013-11-13,2013-03-27
-1jwh,2002-03-04,2001-09-04
-7jws,2020-12-30,2020-08-26
-7jwu,2020-12-30,2020-08-26
-1jw9,2001-11-21,2001-09-03
-4jwr,2013-05-01,2013-03-27
-5jwl,2017-05-17,2016-05-12
-7jwz,2021-03-17,2020-08-26
-4jwi,2013-11-13,2013-03-27
-6jw7,2020-04-15,2019-04-18
-6jwy,2020-02-12,2019-04-21
-7jwp,2021-03-24,2020-08-26
-3jwf,2010-09-29,2009-09-18
-3jwm,2010-09-15,2009-09-18
-7jwy,2020-11-25,2020-08-26
-6jw8,2020-04-15,2019-04-18
-6jwp,2019-12-11,2019-04-21
-3jws,2010-05-05,2009-09-18
-8jwi,2023-08-30,2023-06-29
-5jws,2016-09-21,2016-05-12
-6jwa,2019-07-24,2019-04-19
-3jwt,2010-05-05,2009-09-18
-7jw4,2020-11-04,2020-08-24
-8jwo,2024-04-10,2023-06-29
-5jwo,2017-03-29,2016-05-12
-1jw5,2002-01-30,2001-09-02
-6jwl,2020-04-22,2019-04-21
-6jwm,2020-04-22,2019-04-21
-3jwx,2010-05-05,2009-09-18
-8jwl,2024-04-10,2023-06-29
-6jw9,2020-04-22,2019-04-18
-5jww,2016-09-21,2016-05-12
-7jwk,2020-09-09,2020-08-25
-6jwr,2020-02-12,2019-04-21
-6jws,2020-02-12,2019-04-21
-6jwb,2020-04-22,2019-04-19
-6jwq,2020-02-12,2019-04-21
-3jwr,2009-10-13,2009-09-18
-1jwm,2003-07-08,2001-09-04
-8jwf,2023-08-30,2023-06-29
-1jwt,2002-02-27,2001-09-05
-6jwj,2019-12-25,2019-04-20
-1jwq,2003-11-18,2001-09-05
-8jws,2023-12-20,2023-06-29
-3jw7,2010-08-11,2009-09-18
-3jwk,2010-09-29,2009-09-18
-4jwn,2013-06-26,2013-03-27
-7jwj,2021-07-07,2020-08-25
-7jwe,2021-03-17,2020-08-25
-6jwv,2020-02-12,2019-04-21
-3jww,2010-05-05,2009-09-18
-7jwt,2020-12-30,2020-08-26
-5jw1,2016-10-26,2016-05-11
-6jw6,2020-04-15,2019-04-18
-7jwn,2020-09-09,2020-08-25
-2jw6,2007-12-25,2007-10-08
-1jws,2003-07-08,2001-09-05
-5jwb,2017-03-29,2016-05-12
-7jwl,2021-05-26,2020-08-25
-4jwk,2013-06-05,2013-03-27
-4jwh,2013-10-16,2013-03-27
-3jwb,2010-09-08,2009-09-18
-3jw4,2009-12-22,2009-09-17
-5jwz,2016-06-01,2016-05-12
-6jwz,2020-02-12,2019-04-21
-8jwk,2024-04-10,2023-06-29
-7jw0,2020-10-14,2020-08-24
-4jwp,2013-05-01,2013-03-27
-5l24,2017-04-12,2016-07-31
-4l2y,2014-01-01,2013-06-05
-4l2o,2014-01-29,2013-06-04
-5l2y,2016-09-28,2016-08-02
-3l24,2010-01-26,2009-12-14
-4l28,2013-09-18,2013-06-04
-5l2m,2017-03-08,2016-08-02
-6l2p,2020-01-15,2019-10-05
-4l2f,2013-10-30,2013-06-04
-6l2c,2020-02-12,2019-10-03
-7l2i,2021-09-22,2020-12-17
-7l2v,2021-09-22,2020-12-17
-7l2l,2021-09-22,2020-12-17
-6l2u,2021-03-03,2019-10-07
-4l2b,2014-02-26,2013-06-04
-6l2d,2020-04-01,2019-10-03
-4l2g,2013-10-30,2013-06-04
-7l2p,2021-09-22,2020-12-17
-4l2z,2013-06-19,2013-06-05
-1l2s,2002-07-17,2002-02-24
-7l21,2021-12-22,2020-12-16
-3l2l,2010-04-14,2009-12-15
-3l22,2010-01-12,2009-12-14
-7l2c,2021-02-10,2020-12-16
-3l2p,2010-07-14,2009-12-15
-6l2e,2020-04-01,2019-10-03
-5l2w,2016-08-24,2016-08-02
-2l2s,2010-09-22,2010-08-27
-7l28,2021-06-16,2020-12-16
-7l2x,2021-09-22,2020-12-17
-3l2n,2009-12-29,2009-12-15
-5l22,2017-03-08,2016-07-30
-3l2b,2010-04-21,2009-12-15
-1l2e,2002-05-08,2002-02-20
-5l2i,2016-08-24,2016-08-01
-6l2h,2019-10-16,2019-10-03
-3l2w,2010-02-09,2009-12-15
-6l22,2020-02-26,2019-10-02
-7l2u,2021-09-22,2020-12-17
-1l2k,2002-08-21,2002-02-21
-4l2a,2014-02-26,2013-06-04
-3l23,2010-02-16,2009-12-14
-3l2i,2009-12-29,2009-12-15
-7l2s,2021-09-22,2020-12-17
-1l2c,2002-06-14,2002-02-20
-5l2z,2016-09-28,2016-08-02
-5l2a,2017-04-12,2016-07-31
-6l2j,2019-10-30,2019-10-04
-3l2j,2010-02-02,2009-12-15
-3l2x,2011-01-05,2009-12-15
-5l2v,2017-08-09,2016-08-02
-6l24,2020-02-26,2019-10-02
-6l2q,2020-01-15,2019-10-05
-5l2j,2016-11-16,2016-08-02
-5l27,2017-04-12,2016-07-31
-3l2m,2010-04-14,2009-12-15
-7l2f,2021-03-24,2020-12-16
-1l2i,2002-05-01,2002-02-21
-5l2b,2017-04-12,2016-07-31
-3l28,2010-01-26,2009-12-14
-3l2y,2010-12-08,2009-12-15
-6l21,2020-02-26,2019-10-02
-7l24,2021-03-17,2020-12-16
-3l26,2010-01-26,2009-12-14
-7l26,2021-03-17,2020-12-16
-1l2d,2002-06-14,2002-02-20
-1l2a,2002-07-17,2002-02-20
-5l2l,2016-12-21,2016-08-02
-6l20,2020-02-26,2019-10-02
-4l20,2014-06-04,2013-06-04
-5l2k,2016-11-16,2016-08-02
-7l25,2021-03-17,2020-12-16
-5l20,2017-08-02,2016-07-29
-6l2f,2020-04-01,2019-10-03
-6l2m,2020-08-12,2019-10-05
-4l2n,2015-05-06,2013-06-04
-6l2i,2020-08-12,2019-10-04
-4l27,2013-09-18,2013-06-04
-3l25,2010-01-26,2009-12-14
-7l2o,2021-09-22,2020-12-17
-7l2h,2021-09-22,2020-12-17
-4l2k,2013-10-30,2013-06-04
-7l2r,2021-09-22,2020-12-17
-7l29,2021-06-16,2020-12-16
-4l2d,2014-02-26,2013-06-04
-3l21,2010-12-15,2009-12-14
-4l2l,2014-03-12,2013-06-04
-7l2j,2021-09-22,2020-12-17
-1l2t,2002-07-24,2002-02-24
-5l2t,2016-08-24,2016-08-02
-6l2z,2020-08-12,2019-10-07
-7l2t,2021-09-22,2020-12-17
-3l2u,2010-02-09,2009-12-15
-1l2o,2002-10-30,2002-02-22
-3l2r,2010-02-09,2009-12-15
-7l2m,2021-09-22,2020-12-17
-4l2h,2013-07-24,2013-06-04
-4l2i,2014-01-15,2013-06-04
-4l29,2013-12-25,2013-06-04
-5l2x,2016-11-23,2016-08-02
-7l2n,2021-09-22,2020-12-17
-6l2l,2020-08-12,2019-10-05
-7l2w,2021-09-22,2020-12-17
-3l2v,2010-02-09,2009-12-15
-3l2c,2009-12-29,2009-12-15
-5l2n,2017-03-08,2016-08-02
-4l2x,2014-01-01,2013-06-04
-5l2o,2017-03-08,2016-08-02
-6l25,2020-05-13,2019-10-02
-3l27,2010-01-26,2009-12-14
-1l2b,2002-06-14,2002-02-20
-3l2q,2010-02-09,2009-12-15
-4l2m,2013-06-12,2013-06-04
-7l20,2021-05-12,2020-12-15
-6l23,2021-03-31,2019-10-02
-5l2s,2016-08-24,2016-08-02
-3l2k,2010-05-26,2009-12-15
-7l23,2021-12-22,2020-12-16
-7l27,2021-06-16,2020-12-16
-7l2e,2021-03-24,2020-12-16
-1l2g,2003-12-16,2002-02-21
-4l21,2014-06-04,2013-06-04
-7l2d,2021-03-24,2020-12-16
-7l2y,2021-12-22,2020-12-17
-4l23,2014-01-01,2013-06-04
-5l26,2017-04-12,2016-07-31
-1l2j,2002-05-01,2002-02-21
-4l2c,2014-02-26,2013-06-04
-5l2f,2016-09-28,2016-08-01
-1f9o,2000-08-02,2000-07-11
-8f9c,2023-12-13,2022-11-23
-3f91,2009-08-18,2008-11-13
-7f9z,2021-08-18,2021-07-05
-4f9a,2012-10-31,2012-05-18
-5f9t,2015-12-23,2015-12-10
-1f9u,2001-06-13,2000-07-11
-6f9o,2019-02-27,2017-12-15
-3f9z,2008-11-25,2008-11-14
-5f96,2016-03-09,2015-12-09
-3f9k,2009-01-20,2008-11-14
-4f9v,2012-08-29,2012-05-21
-4f9m,2012-08-08,2012-05-19
-6f9l,2019-01-30,2017-12-14
-2f9w,2006-08-22,2005-12-06
-6f9k,2019-01-30,2017-12-14
-5f9s,2016-12-21,2015-12-10
-5f9k,2016-12-14,2015-12-09
-5f9h,2016-01-13,2015-12-09
-5f9l,2016-12-21,2015-12-09
-7f9a,2022-10-05,2021-07-04
-5f9d,2016-01-20,2015-12-09
-4f94,2013-08-14,2012-05-18
-3f90,2009-11-17,2008-11-13
-7f9o,2021-12-22,2021-07-04
-2f93,2006-03-07,2005-12-05
-5f9b,2016-06-29,2015-12-09
-8f97,2023-12-13,2022-11-23
-4f96,2012-10-17,2012-05-18
-6f98,2019-01-30,2017-12-14
-8f9w,2023-11-01,2022-11-24
-2f9g,2006-11-14,2005-12-05
-7f9q,2022-10-05,2021-07-04
-8f92,2024-05-15,2022-11-23
-1f9t,2001-06-13,2000-07-11
-7f9r,2022-07-06,2021-07-04
-4f97,2012-10-17,2012-05-18
-8f9k,2023-11-22,2022-11-23
-6f94,2019-06-26,2017-12-14
-5f9e,2016-05-11,2015-12-09
-1f9x,2001-07-11,2000-07-11
-2f9m,2006-04-04,2005-12-06
-5f94,2016-02-03,2015-12-09
-5f9n,2016-12-21,2015-12-09
-1f9h,2003-04-15,2000-07-10
-5f9y,2016-11-16,2015-12-10
-3f9d,2009-10-27,2008-11-13
-3f9m,2008-12-02,2008-11-14
-5f9z,2016-11-16,2015-12-10
-1f9p,2003-08-26,2000-07-11
-7f98,2022-10-05,2021-07-04
-3f98,2009-06-23,2008-11-13
-6f95,2018-04-11,2017-12-14
-4f9b,2012-10-31,2012-05-18
-1f90,2001-07-11,2000-07-06
-8f9d,2023-12-13,2022-11-23
-6f9q,2018-12-12,2017-12-15
-6f92,2018-05-02,2017-12-13
-4f9c,2012-10-31,2012-05-18
-3f9p,2009-07-14,2008-11-14
-2f9y,2006-12-12,2005-12-06
-2f9a,2006-07-25,2005-12-05
-5f9w,2016-03-09,2015-12-10
-1f9d,2000-08-02,2000-07-10
-5f90,2016-04-06,2015-12-09
-1f9i,2000-07-21,2000-07-10
-4f9n,2012-06-20,2012-05-19
-2f9r,2006-06-27,2005-12-06
-8f9v,2023-11-01,2022-11-24
-1f9e,2001-07-10,2000-07-10
-5f99,2016-02-03,2015-12-09
-3f92,2008-11-25,2008-11-13
-4f9j,2012-07-25,2012-05-18
-3f9n,2009-01-20,2008-11-14
-2f9k,2006-02-28,2005-12-06
-2f9n,2006-01-31,2005-12-06
-7f9t,2022-10-05,2021-07-04
-7f9c,2022-07-06,2021-07-04
-1f9b,2001-02-10,2000-07-10
-6f9u,2018-03-07,2017-12-15
-4f9u,2012-08-29,2012-05-21
-1f9g,2001-05-16,2000-07-10
-1f92,2001-07-06,2000-07-06
-2f9b,2006-02-28,2005-12-05
-7f97,2023-01-04,2021-07-04
-2f9i,2006-12-05,2005-12-05
-6f91,2018-05-02,2017-12-13
-2f9q,2005-12-20,2005-12-06
-2f98,2006-02-14,2005-12-05
-6f9h,2019-01-30,2017-12-14
-3f9x,2008-11-25,2008-11-14
-5f9a,2016-01-20,2015-12-09
-2f9o,2006-01-31,2005-12-06
-6f97,2018-02-14,2017-12-14
-7f9v,2022-07-06,2021-07-04
-7f9y,2021-08-18,2021-07-05
-1f9c,2001-03-07,2000-07-10
-8f9r,2024-05-29,2022-11-24
-3f9y,2008-11-25,2008-11-14
-3f9l,2009-02-17,2008-11-14
-5f93,2016-01-20,2015-12-09
-5f9o,2016-03-16,2015-12-10
-1f9a,2001-01-10,2000-07-09
-6f9i,2018-09-05,2017-12-14
-8f9e,2023-11-01,2022-11-23
-1f9v,2001-06-13,2000-07-11
-7f99,2022-07-06,2021-07-04
-8f9a,2023-12-13,2022-11-23
-8f9y,2023-01-18,2022-11-24
-7f9d,2022-10-05,2021-07-04
-3f9t,2008-11-25,2008-11-14
-7f9p,2022-10-05,2021-07-04
-8f93,2023-05-31,2022-11-23
-8f9i,2023-11-08,2022-11-23
-2f94,2006-02-28,2005-12-05
-4f9d,2012-07-25,2012-05-18
-6f9t,2018-03-07,2017-12-15
-3f9o,2009-09-01,2008-11-14
-8f9p,2024-05-29,2022-11-24
-1f98,2000-07-21,2000-07-07
-8f9h,2023-11-08,2022-11-23
-2f9p,2006-01-31,2005-12-06
-2f9u,2006-06-06,2005-12-06
-8f9m,2024-05-15,2022-11-23
-5f98,2016-01-13,2015-12-09
-8f91,2023-07-19,2022-11-22
-2f9v,2007-01-09,2005-12-06
-4f9f,2012-10-17,2012-05-18
-3f9r,2009-03-10,2008-11-14
-3f9w,2008-11-25,2008-11-14
-6f90,2018-05-02,2017-12-13
-1f9z,2000-09-20,2000-07-11
-4f9g,2012-07-25,2012-05-18
-5f95,2016-02-03,2015-12-09
-6f96,2019-01-30,2017-12-14
-7f9s,2022-10-05,2021-07-04
-8f96,2023-12-13,2022-11-23
-1f99,2001-07-09,2000-07-09
-8f9q,2024-05-29,2022-11-24
-2f9c,2005-12-20,2005-12-05
-8f9o,2024-05-29,2022-11-24
-4f99,2012-10-31,2012-05-18
-5f97,2016-01-20,2015-12-09
-5f9f,2016-01-13,2015-12-09
-1f9k,2001-07-11,2000-07-11
-3f9c,2009-06-23,2008-11-13
-2f96,2006-02-14,2005-12-05
-4f9w,2013-06-05,2012-05-21
-6f9m,2018-06-27,2017-12-14
-6f9j,2019-01-30,2017-12-14
-8f9b,2023-12-13,2022-11-23
-2f91,2006-04-18,2005-12-05
-8f9j,2023-11-08,2022-11-23
-1f97,2001-01-10,2000-07-07
-4f9l,2012-08-08,2012-05-18
-7f9g,2022-07-06,2021-07-04
-8f9g,2024-05-15,2022-11-23
-1f9w,2001-06-13,2000-07-11
-7f9u,2022-07-06,2021-07-04
-4f9o,2013-06-12,2012-05-19
-4f93,2012-10-17,2012-05-18
-2f95,2006-03-07,2005-12-05
-1f95,2001-02-28,2000-07-07
-2f92,2006-02-28,2005-12-05
-2f99,2006-02-14,2005-12-05
-7f96,2023-01-04,2021-07-04
-8f98,2023-12-13,2022-11-23
-3f97,2009-06-23,2008-11-13
-6f9r,2018-03-07,2017-12-15
-8f9n,2023-11-08,2022-11-24
-6f9v,2018-03-07,2017-12-15
-8f9x,2023-12-06,2022-11-24
-8f9z,2023-01-11,2022-11-25
-5f91,2016-06-22,2015-12-09
-7f9f,2022-07-06,2021-07-04
-4f92,2012-10-17,2012-05-18
-5f9c,2016-04-27,2015-12-09
-8f99,2023-12-13,2022-11-23
-7f9j,2022-07-06,2021-07-04
-7f9b,2022-10-05,2021-07-04
-5f9j,2016-12-21,2015-12-09
-2f9l,2006-04-04,2005-12-06
-4f9y,2013-06-05,2012-05-21
-4gki,2012-09-05,2012-08-11
-8gk9,2023-11-15,2023-03-17
-4gky,2013-06-05,2012-08-13
-2gk1,2006-05-30,2006-03-31
-8gkx,2023-11-15,2023-03-20
-1gkf,2002-01-04,2001-08-13
-4gkm,2013-08-14,2012-08-13
-7gkn,2023-11-08,2023-08-11
-5gky,2016-08-24,2016-07-07
-7gk3,2023-11-08,2023-08-11
-8gkn,2023-09-13,2023-03-20
-7gk7,2023-11-08,2023-08-11
-7gkp,2023-11-08,2023-08-11
-1gkr,2002-07-25,2001-08-20
-5gk8,2017-07-05,2016-07-03
-4gkk,2013-06-05,2012-08-11
-8gk3,2023-07-26,2023-03-16
-1gki,2002-05-16,2001-08-14
-6gk6,2018-08-08,2018-05-18
-7gkm,2023-11-08,2023-08-11
-7gkz,2023-11-08,2023-08-11
-6gku,2019-06-05,2018-05-21
-5gkd,2017-02-08,2016-07-04
-7gko,2023-11-08,2023-08-11
-4gk5,2013-03-13,2012-08-10
-3gk4,2009-06-09,2009-03-09
-7gkw,2023-11-08,2023-08-11
-8gks,2024-03-20,2023-03-20
-3gke,2009-07-21,2009-03-10
-1gkm,2002-04-05,2001-08-16
-3gki,2009-07-14,2009-03-10
-5gkp,2016-11-23,2016-07-05
-3gkl,2009-09-08,2009-03-11
-7gkb,2023-11-08,2023-08-11
-2gks,2007-03-06,2006-04-03
-6gkh,2018-11-21,2018-05-21
-7gk0,2023-11-08,2023-08-11
-3gky,2009-03-24,2009-03-11
-6gkd,2019-06-19,2018-05-18
-4gk4,2013-01-23,2012-08-10
-6gkr,2018-09-26,2018-05-21
-4gkr,2012-10-03,2012-08-13
-4gkb,2012-08-29,2012-08-10
-4gkt,2013-09-04,2012-08-13
-8gk2,2023-11-15,2023-03-16
-7gkl,2023-11-08,2023-08-11
-8gkw,2024-03-20,2023-03-20
-6gkc,2019-01-23,2018-05-18
-3gk2,2009-06-09,2009-03-09
-2gkm,2006-09-19,2006-04-03
-7gk5,2023-11-08,2023-08-11
-8gkz,2024-03-20,2023-03-20
-6gko,2019-06-05,2018-05-21
-3gk9,2009-09-22,2009-03-10
-5gk3,2017-07-05,2016-07-03
-8gkc,2023-05-24,2023-03-17
-6gkl,2019-06-19,2018-05-21
-5gkn,2016-10-26,2016-07-04
-8gk8,2023-08-30,2023-03-17
-3gkh,2009-07-14,2009-03-10
-2gkj,2006-05-16,2006-04-02
-8gkm,2023-12-06,2023-03-20
-3gkj,2009-07-14,2009-03-10
-8gkr,2023-09-20,2023-03-20
-3gkq,2010-03-31,2009-03-11
-6gk9,2019-02-27,2018-05-18
-6gka,2019-01-23,2018-05-18
-7gk8,2023-11-08,2023-08-11
-7gkj,2023-11-08,2023-08-11
-5gkz,2016-08-24,2016-07-07
-5gkr,2017-07-05,2016-07-05
-3gk0,2009-03-17,2009-03-09
-1gkl,2001-12-13,2001-08-15
-3gkz,2009-10-06,2009-03-11
-5gk5,2017-07-05,2016-07-03
-7gke,2023-11-08,2023-08-11
-6gkj,2019-06-19,2018-05-21
-6gke,2019-06-19,2018-05-19
-8gkb,2023-11-15,2023-03-17
-5gke,2016-11-02,2016-07-04
-2gk6,2007-01-09,2006-03-31
-6gkb,2019-01-23,2018-05-18
-2gkl,2007-03-13,2006-04-03
-1gk8,2001-10-24,2001-08-09
-1gkc,2002-05-16,2001-08-10
-3gkt,2009-09-22,2009-03-11
-7gk4,2023-11-08,2023-08-11
-8gkp,2023-11-01,2023-03-20
-5gk9,2017-03-29,2016-07-04
-1gkk,2001-12-13,2001-08-15
-8gkf,2024-03-20,2023-03-18
-1gkp,2002-06-27,2001-08-20
-8gkt,2024-03-20,2023-03-20
-5gk4,2017-07-05,2016-07-03
-4gk8,2013-02-27,2012-08-10
-6gkm,2018-11-21,2018-05-21
-8gko,2023-11-01,2023-03-20
-4gks,2012-09-12,2012-08-13
-5gkq,2017-02-08,2016-07-05
-3gk1,2009-06-09,2009-03-09
-7gk6,2023-11-08,2023-08-11
-6gkf,2018-10-17,2018-05-20
-4gk9,2013-05-08,2012-08-10
-4gkx,2013-06-05,2012-08-13
-7gk1,2023-11-08,2023-08-11
-4gkn,2012-09-12,2012-08-13
-4gk7,2012-08-29,2012-08-10
-2gkp,2006-05-02,2006-04-03
-7gkx,2023-11-08,2023-08-11
-7gka,2023-11-08,2023-08-11
-3gka,2009-03-17,2009-03-10
-4gko,2013-06-26,2012-08-13
-8gk4,2023-05-31,2023-03-17
-6gkv,2018-06-06,2018-05-22
-4gkj,2013-06-05,2012-08-11
-7gks,2023-11-08,2023-08-11
-6gk4,2019-06-19,2018-05-18
-6gkz,2019-01-16,2018-05-22
-7gkh,2023-11-08,2023-08-11
-7gkt,2023-11-08,2023-08-11
-8gka,2023-09-06,2023-03-17
-3gkr,2010-03-23,2009-03-11
-7gkf,2023-11-08,2023-08-11
-7gkc,2023-11-08,2023-08-11
-8gkq,2023-11-01,2023-03-20
-7gku,2023-11-08,2023-08-11
-6gkg,2018-10-17,2018-05-20
-5gkh,2016-11-02,2016-07-04
-7gkd,2023-11-08,2023-08-11
-4gk2,2013-01-23,2012-08-10
-5gkf,2016-11-02,2016-07-04
-7gk9,2023-11-08,2023-08-11
-2gkw,2006-04-11,2006-04-03
-3gkn,2009-06-16,2009-03-11
-1gkb,2001-08-20,2001-08-10
-2gko,2007-05-01,2006-04-03
-5gk7,2017-07-05,2016-07-03
-4gkv,2013-07-10,2012-08-13
-8gku,2024-03-20,2023-03-20
-8gk0,2023-06-07,2023-03-16
-6gk5,2018-08-08,2018-05-18
-5gkg,2016-11-02,2016-07-04
-1gks,1997-01-27,1996-07-16
-7gki,2023-11-08,2023-08-11
-5gkw,2017-07-12,2016-07-07
-8gky,2024-03-20,2023-03-20
-4gkc,2012-12-26,2012-08-10
-5gk1,2017-07-05,2016-07-03
-1gkq,2002-06-27,2001-08-20
-7gk2,2023-11-08,2023-08-11
-8gk7,2024-04-24,2023-03-17
-8gk1,2023-11-15,2023-03-16
-7gky,2023-11-08,2023-08-11
-6gkk,2019-06-19,2018-05-21
-3gkv,2009-05-05,2009-03-11
-5gk6,2017-07-05,2016-07-03
-7gkr,2023-11-08,2023-08-11
-7gkg,2023-11-08,2023-08-11
-6gk0,2019-11-27,2018-05-17
-3gko,2010-02-23,2009-03-11
-4gk3,2013-01-23,2012-08-10
-1gky,1994-01-31,1991-12-23
-7gkk,2023-11-08,2023-08-11
-4gkh,2012-09-05,2012-08-11
-2gke,2006-05-16,2006-04-01
-1gkd,2002-05-16,2001-08-10
-1gkz,2001-10-11,2001-08-22
-7gkv,2023-11-08,2023-08-11
-1gkt,2001-11-20,2001-08-20
-8gk6,2023-12-13,2023-03-17
-1gka,2002-08-08,2001-08-10
-6gky,2018-06-06,2018-05-22
-8gkh,2023-07-05,2023-03-19
-5gki,2016-11-02,2016-07-04
-1gk9,2002-01-04,2001-08-10
-2gk2,2006-09-05,2006-03-31
-7gkq,2023-11-08,2023-08-11
-2gkn,2006-09-19,2006-04-03
-2vtt,2008-08-05,2008-05-15
-6vta,2021-06-02,2020-02-12
-7vtv,2022-11-02,2021-10-31
-3vta,2012-08-08,2012-05-23
-7vtd,2022-04-06,2021-10-29
-3vt0,2012-12-05,2012-05-18
-3vt1,2012-12-05,2012-05-18
-2vt5,2008-07-22,2008-05-09
-7vth,2022-04-06,2021-10-29
-5vtt,2018-05-23,2017-05-18
-1vtn,2011-07-13,1995-01-06
-7vtq,2022-03-09,2021-10-30
-2vts,2008-08-05,2008-05-15
-2vtm,2008-08-05,2008-05-15
-2vtc,2008-09-09,2008-05-14
-6vtv,2020-02-26,2020-02-13
-5vt6,2017-05-24,2017-05-15
-6vtu,2020-12-30,2020-02-13
-6vts,2021-08-25,2020-02-13
-5vt0,2017-11-01,2017-05-15
-7vt8,2022-09-07,2021-10-28
-3vtj,2013-06-05,2012-05-30
-2vt3,2008-09-09,2008-05-08
-7vtj,2022-11-02,2021-10-29
-7vtc,2022-03-30,2021-10-28
-2vtq,2008-08-05,2008-05-15
-7vtl,2022-11-02,2021-10-29
-2vtl,2008-08-05,2008-05-15
-5vtm,2018-05-23,2017-05-17
-6vtx,2021-09-01,2020-02-13
-6vt1,2020-04-08,2020-02-12
-6vte,2020-04-08,2020-02-12
-5vtd,2017-06-21,2017-05-16
-3vt6,2013-05-22,2012-05-19
-6vtt,2020-04-08,2020-02-13
-6vtn,2020-04-22,2020-02-13
-2vt7,2008-07-22,2008-05-09
-5vtr,2017-06-28,2017-05-18
-5vtx,2017-06-28,2017-05-18
-6vt8,2020-04-08,2020-02-12
-7vtp,2022-03-09,2021-10-30
-2vtg,2009-07-14,2008-05-15
-3vtr,2013-01-16,2012-06-02
-8vtj,2024-03-13,2024-01-26
-2vth,2008-08-05,2008-05-15
-3vt5,2013-05-22,2012-05-19
-8vtk,2024-03-13,2024-01-26
-7vtb,2022-06-08,2021-10-28
-2vtr,2008-08-05,2008-05-15
-6vtd,2020-04-08,2020-02-12
-8vts,2024-02-14,2024-01-27
-5vtq,2017-06-28,2017-05-17
-2vtn,2008-08-05,2008-05-15
-5vt4,2017-06-07,2017-05-15
-2vto,2008-08-05,2008-05-15
-3vtb,2013-06-12,2012-05-26
-5vtu,2017-06-28,2017-05-18
-1vtg,2011-07-13,1988-08-18
-7vtw,2022-11-02,2021-10-31
-7vt5,2022-09-07,2021-10-28
-8vtm,2024-03-13,2024-01-26
-7vte,2022-04-06,2021-10-29
-3vt7,2013-05-22,2012-05-19
-3vtd,2013-06-12,2012-05-26
-5vtz,2017-06-28,2017-05-18
-5vt3,2017-05-31,2017-05-15
-2vt6,2008-07-22,2008-05-09
-6vty,2020-04-22,2020-02-13
-6vt9,2020-04-08,2020-02-12
-5vt1,2017-05-24,2017-05-15
-5vtw,2017-06-28,2017-05-18
-1vtm,1994-07-31,1992-03-30
-7vt7,2022-09-07,2021-10-28
-7vti,2022-08-24,2021-10-29
-5vtv,2017-06-28,2017-05-18
-2vtp,2008-08-05,2008-05-15
-7vt2,2022-11-16,2021-10-27
-2vtj,2008-08-05,2008-05-15
-1vtk,1997-10-22,1997-04-01
-5vts,2018-05-23,2017-05-18
-3vtn,2013-02-06,2012-06-01
-2vta,2008-08-05,2008-05-13
-6vtk,2020-03-11,2020-02-12
-6vto,2021-08-25,2020-02-13
-5vt8,2018-05-23,2017-05-15
-6vtb,2020-04-08,2020-02-12
-3vtk,1997-10-22,1997-04-01
-3vt3,2013-05-22,2012-05-19
-5vty,2017-06-28,2017-05-18
-2vtz,2008-10-28,2008-05-19
-3vtf,2012-09-19,2012-05-29
-5vt7,2017-11-15,2017-05-15
-5vta,2018-05-09,2017-05-16
-2vt2,2008-09-09,2008-05-08
-2vtb,2009-06-02,2008-05-13
-7vtz,2022-11-09,2021-11-01
-3vtg,2013-06-05,2012-05-30
-3vt9,2013-05-22,2012-05-19
-2vt0,2008-09-23,2008-05-03
-7vtf,2022-04-06,2021-10-29
-7vtx,2022-11-02,2021-10-31
-2vt4,2008-06-24,2008-05-09
-3vt4,2013-05-22,2012-05-19
-6vtl,2020-03-11,2020-02-12
-3vti,2012-07-04,2012-05-30
-3vte,2012-07-25,2012-05-28
-7vtm,2022-11-02,2021-10-29
-3vth,2012-07-04,2012-05-30
-5vtp,2018-01-24,2017-05-17
-6vtq,2021-08-25,2020-02-13
-6vt2,2020-08-26,2020-02-12
-3vtc,2013-06-12,2012-05-26
-3vt8,2013-05-22,2012-05-19
-6vt6,2020-04-08,2020-02-12
-2vti,2008-08-05,2008-05-15
-6vtj,2020-02-26,2020-02-12
-2vte,2008-11-25,2008-05-14
-8vt7,2024-03-27,2024-01-25
-2vtk,1997-10-22,1997-04-01
-3vto,2013-02-06,2012-06-01
-7vto,2022-11-02,2021-10-30
-7vtg,2022-04-06,2021-10-29
-2vtd,2008-11-25,2008-05-14
-3vt2,2012-12-05,2012-05-18
-7vt6,2022-09-07,2021-10-28
-8vtt,2024-02-14,2024-01-27
-6fjj,2019-02-06,2018-01-22
-4fjp,2012-06-27,2012-06-12
-6fj0,2019-01-30,2018-01-19
-1fj3,2001-04-18,2000-08-07
-6fje,2019-07-24,2018-01-22
-5fjm,2016-04-06,2015-10-11
-6fjs,2018-10-10,2018-01-23
-6fjb,2019-02-06,2018-01-22
-6fja,2018-06-27,2018-01-21
-6fjc,2018-05-16,2018-01-22
-4fjk,2012-12-19,2012-06-11
-7fjw,2022-11-02,2022-08-26
-7fjy,2022-11-02,2022-08-26
-5fj2,2015-10-28,2015-10-06
-1fjq,2001-04-18,2000-08-08
-4fj0,2013-07-03,2012-06-11
-8fjx,2023-09-06,2022-12-20
-4fjg,2012-12-19,2012-06-11
-5fjt,2016-11-23,2015-10-12
-2fj5,2006-01-24,2005-12-31
-3fjq,2009-08-04,2008-12-15
-2fjm,2006-01-17,2006-01-03
-5fjq,2016-02-17,2015-10-12
-1fjm,1996-06-20,1995-12-17
-5fjh,2015-10-21,2015-10-09
-5fjn,2016-04-06,2015-10-11
-1fjt,2001-04-18,2000-08-08
-5fjw,2015-11-11,2015-10-13
-1fj0,2002-01-16,2000-08-07
-4fju,2013-01-16,2012-06-12
-2fj0,2006-05-23,2005-12-30
-6fju,2018-07-25,2018-01-23
-8fjo,2023-03-29,2022-12-20
-3fjz,2009-02-17,2008-12-15
-7fj9,2022-08-10,2021-08-03
-7fjf,2022-07-27,2021-08-03
-7fja,2022-08-10,2021-08-03
-4fjy,2012-10-24,2012-06-12
-3fju,2008-12-30,2008-12-15
-7fjc,2022-08-10,2021-08-03
-5fj8,2015-11-25,2015-10-06
-7fjz,2022-11-02,2022-08-26
-5fj3,2015-10-28,2015-10-06
-5fjo,2016-11-16,2015-10-12
-7fjn,2022-04-27,2021-08-04
-7fju,2022-11-02,2022-08-26
-2fjx,2006-06-27,2006-01-03
-2fjn,2006-01-17,2006-01-03
-6fj5,2018-06-27,2018-01-20
-4fjm,2012-12-19,2012-06-11
-8fjm,2024-02-07,2022-12-20
-1fjs,2000-10-04,2000-08-08
-3fj4,2009-03-31,2008-12-14
-4fjj,2012-12-19,2012-06-11
-5fj6,2015-11-04,2015-10-06
-7fjt,2022-06-15,2021-08-04
-2fjv,2006-06-27,2006-01-03
-5fji,2016-02-10,2015-10-09
-7fjb,2022-08-10,2021-08-03
-2fjw,2006-06-27,2006-01-03
-8fjw,2023-09-06,2022-12-20
-5fjp,2016-11-16,2015-10-12
-5fjj,2016-02-10,2015-10-09
-2fje,2006-03-28,2006-01-02
-6fj3,2018-11-21,2018-01-19
-2fjc,2006-01-10,2006-01-02
-7fjl,2021-12-15,2021-08-04
-7fjg,2022-06-15,2021-08-03
-6fjo,2019-02-06,2018-01-22
-8fjp,2023-03-01,2022-12-20
-5fjx,2015-11-11,2015-10-13
-2fjp,2006-07-04,2006-01-03
-7fje,2022-07-27,2021-08-03
-6fjf,2018-05-30,2018-01-22
-3fj7,2009-03-10,2008-12-14
-1fja,1996-06-10,1995-12-15
-4fj1,2013-07-03,2012-06-11
-7fjs,2022-04-27,2021-08-04
-1fj4,2000-08-23,2000-08-07
-2fja,2006-03-28,2006-01-02
-5fjz,2015-11-11,2015-10-14
-1fju,2001-04-18,2000-08-08
-7fjo,2022-04-13,2021-08-04
-4fj5,2012-12-19,2012-06-11
-7fji,2021-10-27,2021-08-04
-3fj6,2009-06-09,2008-12-14
-5fjk,2015-10-21,2015-10-09
-3fjx,2009-02-17,2008-12-15
-8fjt,2023-09-06,2022-12-20
-6fj4,2018-02-07,2018-01-19
-3fjl,2009-06-09,2008-12-14
-1fjo,2001-04-18,2000-08-08
-7fjj,2021-10-27,2021-08-04
-7fjv,2022-11-02,2022-08-26
-3fjo,2009-06-16,2008-12-15
-6fjw,2019-02-06,2018-01-23
-5fju,2016-11-16,2015-10-13
-2fju,2006-11-21,2006-01-03
-8fjy,2023-09-06,2022-12-20
-1fjw,2001-04-18,2000-08-08
-1fjg,2000-09-25,2000-08-08
-6fjh,2018-09-19,2018-01-22
-7fj8,2022-08-10,2021-08-03
-5fj7,2015-11-04,2015-10-06
-2fj1,2007-01-09,2005-12-30
-4fj4,2012-08-22,2012-06-11
-7fjp,2023-03-08,2021-08-04
-4fj7,2012-12-19,2012-06-11
-4fji,2012-12-19,2012-06-11
-5fjr,2016-11-16,2015-10-12
-8fjz,2023-04-05,2022-12-20
-7fjk,2022-08-10,2021-08-04
-4fjn,2012-12-19,2012-06-11
-4fjl,2012-12-19,2012-06-11
-8fjk,2023-03-22,2022-12-19
-1fj9,2000-10-18,2000-08-07
-5fjs,2016-05-11,2015-10-12
-4fjr,2013-07-03,2012-06-12
-5fj9,2015-11-25,2015-10-06
-2fjs,2006-11-21,2006-01-03
-1fjx,2000-12-15,2000-08-08
-4fjh,2012-12-19,2012-06-11
-6fji,2019-02-06,2018-01-22
-8fjq,2023-11-29,2022-12-20
-8fju,2023-09-06,2022-12-20
-2fj9,2006-10-31,2006-01-02
-1fjv,2001-04-18,2000-08-08
-8fj8,2024-02-07,2022-12-19
-7fjh,2022-06-08,2021-08-04
-1fjr,2001-04-04,2000-08-08
-4fjz,2012-10-24,2012-06-12
-8fj9,2023-05-17,2022-12-19
-5fja,2015-11-25,2015-10-06
-6fjd,2018-05-16,2018-01-22
-6fjt,2019-02-06,2018-01-23
-8fjh,2023-12-06,2022-12-19
-8fjc,2023-05-17,2022-12-19
-3fjt,2009-03-24,2008-12-15
-4fj9,2012-12-19,2012-06-11
-2fj4,2006-01-24,2005-12-31
-1fj6,2000-10-18,2000-08-07
-5fjv,2016-08-10,2015-10-13
-6fj2,2018-01-31,2018-01-19
-8fjb,2023-12-20,2022-12-19
-2fjd,2006-03-28,2006-01-02
-4fjc,2012-07-25,2012-06-11
-4fj8,2012-12-19,2012-06-11
-6fjm,2018-05-30,2018-01-22
-7fjx,2022-11-02,2022-08-26
-4fjx,2012-12-19,2012-06-12
-3fjw,2009-12-15,2008-12-15
-8fjr,2023-11-29,2022-12-20
-4fj2,2013-07-03,2012-06-11
-8fjd,2023-02-08,2022-12-19
-2fjb,2006-03-28,2006-01-02
-8fjn,2024-02-07,2022-12-20
-6fjl,2019-02-06,2018-01-22
-8fjv,2023-09-06,2022-12-20
-8fjl,2023-03-08,2022-12-19
-5fje,2015-11-18,2015-10-07
-6fj1,2019-01-30,2018-01-19
-1fj8,2000-08-23,2000-08-07
-7fjd,2022-07-27,2021-08-03
-6fjz,2019-02-06,2018-01-23
-8fji,2023-12-06,2022-12-19
-6fjg,2019-08-14,2018-01-22
-2nbq,2016-06-01,2016-03-09
-6nbw,2020-01-29,2018-12-10
-7nbb,2022-08-10,2021-01-26
-1nbp,2002-12-18,2002-12-03
-1nbw,2003-01-14,2002-12-04
-7nb1,2021-10-13,2021-01-25
-4nbb,2014-03-26,2013-10-23
-6nb4,2019-02-06,2018-12-06
-6nbp,2018-12-19,2018-12-09
-7nb9,2021-07-21,2021-01-25
-4nbc,2014-03-26,2013-10-23
-3nbs,2010-07-14,2010-06-04
-5nbl,2018-08-22,2017-03-02
-3nbp,2010-08-18,2010-06-03
-4nbu,2013-12-04,2013-10-23
-3nby,2010-10-27,2010-06-04
-6nbb,2019-03-13,2018-12-06
-4nb9,2014-03-26,2013-10-23
-3nb0,2010-10-06,2010-06-02
-3nbd,2011-09-21,2010-06-03
-3nbr,2011-11-23,2010-06-03
-1nb0,2003-03-11,2002-12-01
-1nbo,2003-05-13,2002-12-03
-3nbc,2011-09-21,2010-06-03
-5nb3,2017-09-27,2017-03-01
-4nbh,2014-03-26,2013-10-23
-7nbg,2021-03-03,2021-01-26
-4nb0,2014-02-26,2013-10-22
-5nbw,2017-06-28,2017-03-02
-7nba,2021-10-13,2021-01-25
-1nbi,2003-03-04,2002-12-02
-1nbh,2003-03-04,2002-12-02
-1nb6,2003-03-25,2002-12-02
-7nbj,2021-03-17,2021-01-27
-7nbw,2021-10-06,2021-01-28
-7nb2,2021-10-13,2021-01-25
-6nb3,2019-02-06,2018-12-06
-3nbl,2011-12-14,2010-06-03
-4nb1,2014-02-26,2013-10-22
-1nb7,2003-03-25,2002-12-02
-4nbn,2013-12-18,2013-10-23
-6nbf,2019-04-17,2018-12-07
-3nb9,2010-10-06,2010-06-03
-7nbd,2021-03-03,2021-01-26
-6nbm,2019-01-09,2018-12-07
-6nbr,2019-06-19,2018-12-09
-3nbk,2010-09-15,2010-06-03
-5nb4,2017-09-27,2017-03-01
-5nbn,2018-08-22,2017-03-02
-4nb7,2014-10-29,2013-10-23
-1nbe,1998-10-14,1998-04-25
-3nbe,2011-07-13,2010-06-03
-7nbr,2021-03-03,2021-01-27
-4nbt,2013-12-04,2013-10-23
-1nb3,2003-02-18,2002-12-02
-7nbm,2021-03-17,2021-01-27
-5nbs,2018-03-21,2017-03-02
-7nbq,2021-03-17,2021-01-27
-4nbi,2013-12-18,2013-10-23
-3nbq,2010-10-06,2010-06-03
-5nbx,2018-03-21,2017-03-02
-4nbd,2014-03-26,2013-10-23
-7nbh,2021-03-03,2021-01-26
-4nb8,2014-03-26,2013-10-23
-7nbt,2022-02-23,2021-01-27
-7nb8,2021-10-13,2021-01-25
-1nbc,1997-09-26,1996-09-10
-5nby,2017-04-05,2017-03-02
-6nbi,2019-04-17,2018-12-07
-3nbz,2010-10-27,2010-06-04
-3nbx,2011-01-12,2010-06-04
-7nb3,2021-10-13,2021-01-25
-6nbh,2019-04-17,2018-12-07
-7nb7,2021-10-13,2021-01-25
-3nbt,2010-07-14,2010-06-04
-7nbu,2022-03-02,2021-01-27
-4nbf,2014-03-26,2013-10-23
-6nbl,2019-03-06,2018-12-07
-5nbp,2017-10-25,2017-03-02
-4nb4,2014-03-05,2013-10-22
-4nbl,2014-01-01,2013-10-23
-6nba,2019-06-12,2018-12-06
-1nbm,1998-08-26,1998-04-30
-7nb4,2021-10-13,2021-01-25
-6nb2,2019-01-23,2018-12-06
-6nbo,2018-12-26,2018-12-07
-1nbb,1996-08-17,1996-03-18
-5nba,2017-06-28,2017-03-01
-3nbb,2010-08-25,2010-06-03
-1nb9,2003-03-11,2002-12-02
-6nbj,2023-04-26,2018-12-07
-5nbf,2017-05-24,2017-03-01
-7nbf,2021-03-03,2021-01-26
-4nbe,2014-03-26,2013-10-23
-7nbs,2021-03-03,2021-01-27
-4nba,2014-03-26,2013-10-23
-3nbv,2010-12-22,2010-06-04
-3nbf,2011-03-23,2010-06-03
-7nbc,2021-03-03,2021-01-26
-5nbk,2018-10-03,2017-03-02
-6nb7,2019-02-06,2018-12-06
-4nbk,2014-01-01,2013-10-23
-4nb6,2013-11-27,2013-10-22
-1nbu,2004-01-13,2002-12-03
-7nby,2021-03-03,2021-01-28
-5nbj,2017-05-10,2017-03-02
-5nb6,2017-06-28,2017-03-01
-6nbc,2019-03-13,2018-12-06
-4nbj,2013-12-18,2013-10-23
-2nb9,2016-12-14,2016-02-01
-4nbw,2013-12-04,2013-10-23
-4nbs,2014-10-29,2013-10-23
-6nbt,2019-02-13,2018-12-10
-7nb5,2021-03-03,2021-01-25
-3nba,2010-09-15,2010-06-03
-6nbd,2019-02-13,2018-12-06
-5nbm,2018-08-22,2017-03-02
-3nb8,2010-10-06,2010-06-03
-6nbk,2018-12-19,2018-12-07
-3nb5,2011-04-20,2010-06-02
-6nb1,2019-11-13,2018-12-06
-5nb7,2017-06-28,2017-03-01
-5nbu,2018-03-21,2017-03-02
-1nb5,2003-02-18,2002-12-02
-5nbd,2017-05-03,2017-03-01
-4nbm,2016-10-26,2013-10-23
-6nb6,2019-02-06,2018-12-06
-6nbs,2019-07-31,2018-12-10
-3nbw,2010-12-22,2010-06-04
-5nbc,2018-05-16,2017-03-01
-4nbg,2014-03-26,2013-10-23
-3nbj,2010-08-25,2010-06-03
-6nbe,2020-04-15,2018-12-07
-20gs,1998-12-30,1997-12-16
-10gs,1998-09-16,1997-08-14
-2ejn,2007-04-17,2007-03-19
-3ejp,2009-10-13,2008-09-18
-4ej7,2012-04-18,2012-04-06
-3ej1,2008-10-21,2008-09-17
-2ej6,2007-09-18,2007-03-15
-4ejw,2013-05-08,2012-04-07
-5ejn,2016-02-24,2015-11-02
-3ej6,2009-01-13,2008-09-17
-5eja,2016-06-01,2015-11-01
-8ejx,2023-10-18,2022-09-19
-8ejc,2023-05-24,2022-09-16
-1eja,2001-03-02,2000-03-02
-1eje,2000-10-11,2000-03-02
-3ejh,2009-02-03,2008-09-18
-8ejh,2023-06-07,2022-09-16
-7ej6,2022-04-20,2021-04-01
-4ej8,2013-05-01,2012-04-06
-7ej2,2021-06-09,2021-04-01
-5ej6,2016-06-01,2015-11-01
-5ejk,2016-02-17,2015-11-02
-2ejd,2007-09-18,2007-03-16
-6ej4,2018-08-29,2017-09-20
-1ejh,2000-03-10,2000-03-02
-2ej2,2008-03-18,2007-03-14
-7ejk,2022-04-13,2021-04-02
-7ej8,2022-04-13,2021-04-01
-8ej3,2023-02-01,2022-09-16
-2ejt,2007-09-25,2007-03-20
-1ejl,2000-04-24,2000-03-03
-4ejv,2013-05-08,2012-04-07
-2ejz,2007-09-25,2007-03-22
-6ej9,2018-05-02,2017-09-20
-2ej1,2007-09-18,2007-03-14
-7ejy,2022-04-13,2021-04-03
-8ejf,2023-06-07,2022-09-16
-6ejj,2018-02-07,2017-09-21
-2ejg,2008-03-18,2007-03-16
-6ej0,2018-05-02,2017-09-19
-4eji,2012-06-06,2012-04-06
-8eji,2023-06-07,2022-09-16
-2ejw,2008-02-12,2007-03-21
-5ejx,2016-01-20,2015-11-02
-3ej5,2009-04-07,2008-09-17
-5ej0,2016-03-16,2015-10-30
-7eja,2022-04-13,2021-04-01
-3eje,2008-10-07,2008-09-18
-5ejl,2016-10-19,2015-11-02
-5ej4,2016-06-01,2015-11-01
-7ej4,2021-06-23,2021-04-01
-6ejd,2018-05-02,2017-09-20
-2ejc,2008-03-18,2007-03-16
-7ejx,2022-04-13,2021-04-02
-4ejj,2012-06-06,2012-04-06
-3ejb,2008-10-07,2008-09-18
-4ejf,2012-06-20,2012-04-06
-6ejl,2017-11-08,2017-09-21
-8ejr,2023-09-27,2022-09-18
-6ejp,2018-10-10,2017-09-22
-2ejj,2007-09-18,2007-03-16
-3ej2,2008-09-30,2008-09-17
-7ej9,2021-06-23,2021-04-01
-4ejm,2012-05-02,2012-04-06
-8ej4,2022-12-14,2022-09-16
-7ejj,2022-05-11,2021-04-02
-8ejb,2023-02-15,2022-09-16
-2ejv,2008-03-25,2007-03-20
-4ej0,2013-04-17,2012-04-06
-3ejx,2009-02-17,2008-09-18
-8ej0,2023-08-30,2022-09-16
-5ejh,2016-11-09,2015-11-01
-3eja,2009-10-27,2008-09-18
-2ej4,2008-02-05,2007-03-14
-7ejc,2022-04-06,2021-04-02
-8ejg,2023-06-07,2022-09-16
-8ejm,2022-12-14,2022-09-17
-4ej4,2012-05-16,2012-04-06
-3ejr,2009-10-13,2008-09-18
-1ejr,2000-09-08,2000-03-04
-2ejk,2007-09-18,2007-03-16
-6ejw,2019-02-06,2017-09-23
-3ejl,2010-03-02,2008-09-18
-6eja,2018-05-02,2017-09-20
-7ejt,2021-11-10,2021-04-02
-1ej1,2000-03-15,2000-02-29
-3ejm,2009-08-25,2008-09-18
-7ejz,2022-04-13,2021-04-03
-1ej8,2000-04-05,2000-03-01
-6ej7,2018-05-02,2017-09-20
-7ej1,2021-06-09,2021-04-01
-2ejq,2007-09-25,2007-03-20
-1ej6,2000-07-12,2000-02-29
-1eji,2000-11-03,2000-03-02
-8ejs,2023-09-27,2022-09-18
-1ejx,2003-07-08,2000-03-04
-2ejr,2008-01-01,2007-03-20
-6ejz,2019-02-06,2017-09-24
-1ej2,2001-03-14,2000-02-29
-2ejl,2007-09-18,2007-03-16
-5ejm,2016-11-02,2015-11-02
-6ejk,2018-02-07,2017-09-21
-2ej9,2008-03-18,2007-03-16
-1ejj,2001-03-02,2000-03-02
-2ejy,2008-02-12,2007-03-22
-5ej7,2016-06-01,2015-11-01
-5ej9,2016-06-01,2015-11-01
-1ejw,2003-11-11,2000-03-04
-5ej1,2016-03-30,2015-10-30
-8ejn,2023-08-23,2022-09-17
-4ejy,2013-03-20,2012-04-08
-4ejd,2013-05-01,2012-04-06
-4eje,2013-04-10,2012-04-06
-1ej3,2000-05-31,2000-02-29
-7ejv,2022-04-06,2021-04-02
-8ejd,2023-06-07,2022-09-16
-4ejl,2013-05-01,2012-04-06
-3ejn,2008-09-30,2008-09-18
-6ejc,2018-05-02,2017-09-20
-5ejb,2016-01-06,2015-11-01
-3ejj,2008-12-09,2008-09-18
-7ej3,2022-09-21,2021-04-01
-5ejq,2016-07-06,2015-11-02
-6ej3,2018-04-18,2017-09-20
-7eju,2021-07-07,2021-04-02
-3ejq,2009-10-13,2008-09-18
-1ej0,2000-08-30,2000-02-29
-5ej5,2016-06-01,2015-11-01
-2ej0,2008-03-18,2007-03-14
-4ejn,2012-05-23,2012-04-06
-1ejb,2001-03-02,2000-03-02
-7ejn,2022-01-26,2021-04-02
-7ejp,2021-11-10,2021-04-02
-1eju,2000-09-08,2000-03-04
-7ej5,2021-06-23,2021-04-01
-5ej8,2016-06-01,2015-11-01
-4ejk,2013-05-01,2012-04-06
-5eji,2016-11-09,2015-11-01
-2ejf,2008-03-18,2007-03-16
-7ejr,2021-10-13,2021-04-02
-7eji,2022-05-11,2021-04-02
-5ej2,2015-12-02,2015-10-31
-4ejt,2013-06-05,2012-04-07
-6ej8,2018-05-02,2017-09-20
-5eje,2016-11-09,2015-11-01
-6eje,2018-05-02,2017-09-20
-4ej5,2012-08-15,2012-04-06
-6ej1,2018-05-02,2017-09-19
-7ejh,2022-05-11,2021-04-02
-3ejd,2008-10-07,2008-09-18
-8ejk,2023-05-24,2022-09-17
-7eje,2022-03-16,2021-04-02
-5ejv,2016-04-27,2015-11-02
-1ejn,2000-05-17,2000-04-22
-7ej0,2022-04-13,2021-04-01
-2ej3,2008-03-18,2007-03-14
-1ejs,2000-09-08,2000-03-04
-6ej2,2018-04-18,2017-09-20
-4ejx,2013-04-10,2012-04-07
-6eji,2018-02-07,2017-09-21
-5ejt,2016-01-20,2015-11-02
-4ejg,2012-06-06,2012-04-06
-1ejt,2000-09-08,2000-03-04
-7ejm,2022-01-26,2021-04-02
-3ejt,2009-10-13,2008-09-18
-7ejq,2021-10-13,2021-04-02
-2eju,2007-09-25,2007-03-20
-4ejh,2012-06-06,2012-04-06
-5ejw,2016-03-09,2015-11-02
-3ej8,2008-10-07,2008-09-17
-3ejs,2009-10-13,2008-09-18
-4ej1,2013-04-24,2012-04-06
-8eje,2023-06-07,2022-09-16
-7ej7,2022-04-20,2021-04-01
-1ejv,2000-09-08,2000-03-04
-3ej0,2008-09-30,2008-09-17
-7ejw,2021-12-22,2021-04-02
-7ejl,2022-01-26,2021-04-02
-8ejj,2023-06-07,2022-09-16
-1ej4,2000-03-15,2000-02-28
-4ej2,2012-07-25,2012-04-06
-3eju,2009-10-13,2008-09-18
-4ej6,2012-05-02,2012-04-06
-5ejz,2016-03-09,2015-11-02
-5ejd,2016-10-19,2015-11-01
-3ejw,2008-12-02,2008-09-18
-7k0d,2021-09-22,2020-09-04
-6k0q,2019-12-25,2019-05-07
-1k0w,2003-01-28,2001-09-21
-3k0s,2010-02-16,2009-09-25
-5k0k,2017-01-11,2016-05-17
-6k0m,2019-12-25,2019-05-07
-5k05,2016-09-07,2016-05-17
-2k0j,2009-03-10,2008-02-04
-5k0d,2017-05-24,2016-05-17
-4k0y,2013-05-15,2013-04-04
-2k0e,2008-06-10,2008-02-02
-8k06,2024-05-15,2023-07-07
-5k0h,2016-07-06,2016-05-17
-3k0h,2010-03-02,2009-09-24
-1k0e,2002-02-27,2001-09-19
-1k06,2001-10-03,2001-09-18
-7k00,2020-09-23,2020-09-02
-4k0z,2014-04-09,2013-04-04
-3k0a,2010-03-31,2009-09-24
-5k0j,2016-09-07,2016-05-17
-7k0j,2021-02-24,2020-09-04
-4k0j,2013-10-16,2013-04-04
-3k08,2011-01-12,2009-09-24
-5k0g,2016-09-07,2016-05-17
-2k0g,2009-02-10,2008-02-02
-5k02,2016-11-23,2016-05-17
-7k0h,2021-07-07,2020-09-04
-6k0e,2020-03-18,2019-05-06
-3k02,2010-02-16,2009-09-24
-3k0v,2009-10-13,2009-09-25
-7k0i,2021-02-24,2020-09-04
-1k09,2002-07-10,2001-09-18
-3k06,2011-01-12,2009-09-24
-3k03,2011-01-12,2009-09-24
-1k02,2001-09-26,2001-09-18
-7k0f,2021-01-13,2020-09-04
-1k0c,2001-12-21,2001-09-19
-2k0c,2008-07-01,2008-01-31
-8k07,2024-05-15,2023-07-07
-5k09,2016-09-07,2016-05-17
-7k0u,2021-09-22,2020-09-06
-7k0x,2021-03-24,2020-09-06
-6k05,2019-09-18,2019-05-05
-1k0a,2001-12-21,2001-09-19
-5k08,2016-09-21,2016-05-17
-6k0b,2019-06-19,2019-05-05
-3k0f,2010-03-31,2009-09-24
-5k0m,2017-01-25,2016-05-17
-5k03,2016-09-07,2016-05-17
-7k0t,2021-09-22,2020-09-05
-7k0o,2021-02-24,2020-09-04
-1k07,2003-01-21,2001-09-18
-6k0i,2019-08-07,2019-05-06
-5k0f,2016-09-07,2016-05-17
-5k0b,2016-09-07,2016-05-17
-6k0x,2019-06-05,2019-05-07
-6k02,2019-10-09,2019-05-05
-5k0i,2016-09-14,2016-05-17
-7k0k,2021-02-24,2020-09-04
-1k0l,2002-02-27,2001-09-19
-3k0t,2010-06-16,2009-09-25
-4k0b,2013-05-01,2013-04-03
-3k0c,2010-03-31,2009-09-24
-7k0n,2021-02-24,2020-09-04
-8k05,2024-05-15,2023-07-07
-7k0e,2021-07-07,2020-09-04
-5k0x,2017-02-22,2016-05-17
-7k0v,2021-05-26,2020-09-06
-4k03,2013-06-26,2013-04-03
-2k0a,2008-07-22,2008-01-31
-6k0f,2020-03-18,2019-05-06
-3k0e,2010-03-31,2009-09-24
-1k08,2001-10-03,2001-09-18
-5k0e,2016-09-07,2016-05-17
-7k03,2021-09-22,2020-09-03
-7k0r,2020-12-09,2020-09-04
-7k0p,2021-02-24,2020-09-04
-2k0x,2008-09-16,2008-02-15
-5k0a,2017-11-15,2016-05-17
-4k08,2013-07-17,2013-04-03
-6k0n,2019-12-25,2019-05-07
-3k0k,2010-03-02,2009-09-24
-7k0l,2021-02-24,2020-09-04
-7k05,2021-10-06,2020-09-03
-1k0j,2002-02-27,2001-09-19
-4k0k,2013-06-26,2013-04-04
-5k01,2016-09-07,2016-05-17
-6k0u,2019-12-25,2019-05-07
-6k0w,2019-12-11,2019-05-07
-6k0a,2019-06-19,2019-05-05
-6k04,2019-09-18,2019-05-05
-7k0m,2021-02-24,2020-09-04
-7k07,2021-10-06,2020-09-03
-5k07,2017-05-24,2016-05-17
-1k0z,2003-06-17,2001-09-21
-1k0y,2001-10-03,2001-09-21
-7k0s,2021-09-22,2020-09-05
-7k04,2021-07-28,2020-09-03
-5k00,2017-03-01,2016-05-17
-3k00,2010-02-16,2009-09-24
-5k0w,2016-08-03,2016-05-17
-6k0g,2019-08-07,2019-05-06
-7k0a,2021-03-17,2020-09-03
-4k0w,2013-08-07,2013-04-04
-7k09,2021-03-17,2020-09-03
-4k0o,2013-04-17,2013-04-04
-7k0c,2021-01-20,2020-09-04
-4k0e,2013-10-16,2013-04-03
-5k0t,2016-05-25,2016-05-17
-6k0j,2019-11-20,2019-05-06
-4k0a,2013-06-12,2013-04-03
-6k0h,2019-08-07,2019-05-06
-6k0p,2019-12-25,2019-05-07
-5k0l,2016-09-07,2016-05-17
-1k0v,2001-12-19,2001-09-21
-7k0q,2021-02-24,2020-09-04
-3k0i,2010-10-13,2009-09-24
-1k0b,2001-12-21,2001-09-19
-3k0g,2011-01-12,2009-09-24
-7k0g,2021-07-07,2020-09-04
-4k05,2013-04-17,2013-04-03
-4k0d,2013-06-12,2013-04-03
-7k0z,2021-03-24,2020-09-06
-6k0t,2019-10-30,2019-05-07
-1k0g,2002-02-27,2001-09-19
-6k0v,2019-12-25,2019-05-07
-1k0u,2001-10-17,2001-09-20
-7k01,2021-07-28,2020-09-02
-5k0n,2016-09-07,2016-05-17
-3k04,2011-01-12,2009-09-24
-3k0d,2011-01-12,2009-09-24
-5k0r,2017-06-07,2016-05-17
-3k05,2010-03-02,2009-09-24
-7k0w,2020-12-16,2020-09-06
-2k0f,2008-06-10,2008-02-02
-3k09,2010-03-31,2009-09-24
-4k0s,2014-04-09,2013-04-04
-5k0c,2016-09-07,2016-05-17
-1k03,2001-09-26,2001-09-18
-4k0g,2014-04-09,2013-04-03
-6k0k,2020-05-13,2019-05-07
-6k0s,2019-12-25,2019-05-07
-1k0i,2002-02-27,2001-09-19
-4k0t,2014-04-09,2013-04-04
-1k0n,2001-12-12,2001-09-19
-5k04,2017-04-19,2016-05-17
-5k0s,2016-05-25,2016-05-17
-1k0d,2001-12-21,2001-09-19
-7k0b,2021-09-22,2020-09-04
-7k06,2021-10-06,2020-09-03
-6k0r,2020-05-06,2019-05-07
-1n3q,2002-11-20,2002-10-29
-5n3q,2018-02-28,2017-02-08
-6n3x,2019-09-18,2018-11-16
-5n3k,2018-02-28,2017-02-08
-6n3k,2019-11-20,2018-11-15
-1n31,2003-01-21,2002-10-25
-4n3m,2014-02-05,2013-10-07
-6n30,2019-02-20,2018-11-14
-1n3t,2003-10-14,2002-10-29
-5n3t,2018-02-28,2017-02-08
-3n39,2010-08-18,2010-05-19
-5n3p,2018-02-28,2017-02-08
-3n33,2011-06-08,2010-05-19
-1n3o,2002-11-20,2002-10-29
-6n3n,2019-10-09,2018-11-15
-4n3a,2014-01-01,2013-10-06
-5n3b,2018-02-28,2017-02-08
-5n3n,2018-02-28,2017-02-08
-5n38,2017-04-19,2017-02-08
-3n30,2011-01-12,2010-05-19
-4n3t,2014-04-09,2013-10-07
-7n3l,2022-02-23,2021-06-01
-4n3b,2014-01-01,2013-10-06
-3n3g,2010-07-14,2010-05-20
-1n38,2002-12-25,2002-10-25
-5n3f,2018-02-28,2017-02-08
-5n3r,2018-02-28,2017-02-08
-3n38,2010-08-18,2010-05-19
-5n3o,2018-02-28,2017-02-08
-7n3t,2022-04-20,2021-06-01
-1n3p,2002-11-20,2002-10-29
-5n39,2018-02-28,2017-02-08
-1n3w,2003-08-12,2002-10-29
-6n3d,2019-01-02,2018-11-15
-6n35,2018-11-28,2018-11-14
-5n3e,2018-03-21,2017-02-08
-4n3r,2013-12-11,2013-10-07
-3n3k,2010-06-23,2010-05-20
-2n3b,2015-10-28,2015-05-27
-6n3f,2019-01-02,2018-11-15
-4n3e,2014-02-26,2013-10-07
-6n3y,2019-09-18,2018-11-16
-1n3f,2003-06-03,2002-10-28
-7n3u,2021-09-01,2021-06-02
-4n3p,2013-11-13,2013-10-07
-5n3y,2017-06-21,2017-02-09
-6n3w,2019-09-18,2018-11-16
-4n3c,2014-01-01,2013-10-06
-7n3r,2022-04-13,2021-06-01
-1n3c,2003-03-04,2002-10-25
-7n37,2022-03-23,2021-05-31
-3n31,2010-06-30,2010-05-19
-5n3g,2018-02-28,2017-02-08
-4n3w,2014-01-29,2013-10-07
-6n3e,2019-01-02,2018-11-15
-7n3y,2022-09-28,2021-06-02
-1n3a,2003-03-04,2002-10-25
-1n39,2003-03-04,2002-10-25
-4n3u,2014-04-09,2013-10-07
-5n33,2018-02-28,2017-02-08
-1n3i,2003-09-30,2002-10-28
-1n3n,2003-05-27,2002-10-29
-7n38,2022-03-23,2021-05-31
-6n3z,2019-11-20,2018-11-16
-6n3o,2019-10-09,2018-11-15
-5n3m,2018-02-28,2017-02-08
-5n3v,2017-06-21,2017-02-09
-6n3p,2019-03-13,2018-11-15
-4n32,2013-11-20,2013-10-06
-2n3y,2016-12-14,2015-06-15
-6n3g,2019-11-20,2018-11-15
-3n34,2011-04-06,2010-05-19
-7n3n,2022-09-28,2021-06-01
-5n3a,2018-02-28,2017-02-08
-5n31,2017-06-21,2017-02-08
-3n3z,2011-04-13,2010-05-21
-4n34,2013-11-20,2013-10-06
-6n33,2019-09-18,2018-11-14
-3n3a,2010-08-18,2010-05-19
-1n33,2002-11-29,2002-10-25
-1n3z,2003-08-26,2002-10-30
-4n38,2013-11-27,2013-10-06
-5n3d,2018-02-28,2017-02-08
-4n33,2013-11-20,2013-10-06
-4n3d,2014-08-27,2013-10-07
-4n37,2013-11-20,2013-10-06
-3n36,2011-03-30,2010-05-19
-6n3v,2019-09-18,2018-11-16
-3n3i,2010-06-09,2010-05-20
-3n3j,2011-03-09,2010-05-20
-1n3r,2003-10-14,2002-10-29
-1n3s,2004-03-02,2002-10-29
-5n35,2017-05-17,2017-02-08
-3n3b,2010-08-18,2010-05-19
-5n34,2017-06-21,2017-02-08
-1n3u,2002-11-06,2002-10-29
-1n3e,2003-06-03,2002-10-28
-7n31,2021-07-14,2021-05-31
-1n36,2002-11-29,2002-10-25
-3n3l,2010-08-18,2010-05-20
-4n3v,2013-12-04,2013-10-07
-5n32,2018-02-28,2017-02-08
-5n3c,2018-02-28,2017-02-08
-4n35,2013-11-20,2013-10-06
-6n3l,2019-10-09,2018-11-15
-7n3i,2021-08-04,2021-06-01
-3n3x,2010-06-30,2010-05-20
-3n32,2011-01-12,2010-05-19
-3n3h,2011-03-30,2010-05-20
-7n3m,2022-02-23,2021-06-01
-6n36,2018-11-28,2018-11-14
-5n3h,2018-02-28,2017-02-08
-4n3o,2013-10-16,2013-10-07
-3n37,2010-08-18,2010-05-19
-3n3t,2010-06-16,2010-05-20
-4n39,2014-01-01,2013-10-06
-5n3j,2018-02-28,2017-02-08
-1n35,2002-12-25,2002-10-25
-7n32,2021-09-29,2021-05-31
-5n37,2018-02-28,2017-02-08
-7n30,2021-07-14,2021-05-30
-5n3l,2018-02-28,2017-02-08
-5n3w,2017-03-29,2017-02-09
-5n3s,2018-02-28,2017-02-08
-4n36,2013-11-20,2013-10-06
-3n3u,2010-07-14,2010-05-20
-3n3m,2011-04-06,2010-05-20
-7n3k,2021-10-27,2021-06-01
-1n32,2002-11-29,2002-10-25
-5n3i,2018-02-28,2017-02-08
-7n33,2021-06-09,2021-05-31
-1n34,2002-11-29,2002-10-25
-3n3y,2011-05-25,2010-05-21
-3n35,2011-03-30,2010-05-19
-7n3s,2022-04-13,2021-06-01
-5n36,2018-02-28,2017-02-08
-6n3r,2020-05-20,2018-11-16
-7n3z,2022-09-28,2021-06-02
-3kwd,2010-02-23,2009-12-01
-4kwl,2013-10-23,2013-05-24
-5kwy,2016-08-24,2016-07-19
-1kw1,2002-04-15,2002-01-28
-5kw1,2017-08-23,2016-07-15
-5kwr,2016-08-03,2016-07-18
-3kws,2009-12-22,2009-12-01
-7kwm,2021-02-03,2020-12-01
-2kwi,2010-09-01,2010-04-12
-1kw6,2003-01-28,2002-01-28
-6kwr,2019-12-11,2019-09-08
-1kwr,2003-01-07,2002-01-30
-4kwc,2013-07-24,2013-05-23
-6kwz,2020-01-01,2019-09-09
-6kw1,2020-09-09,2019-09-05
-6kwd,2020-12-30,2019-09-06
-5kw9,2016-10-05,2016-07-15
-5kwk,2016-09-28,2016-07-18
-4kwd,2013-08-14,2013-05-23
-5kwi,2017-03-29,2016-07-18
-2kwn,2010-07-14,2010-04-13
-1kwg,2002-09-18,2002-01-29
-1kwy,2002-07-05,2002-01-30
-5kwv,2016-07-27,2016-07-19
-1kwp,2002-09-18,2002-01-30
-5kwb,2017-06-07,2016-07-17
-7kwp,2021-12-08,2020-12-01
-1kwo,2002-11-20,2002-01-30
-1kww,2002-07-05,2002-01-30
-7kw7,2021-12-08,2020-11-30
-1kwq,2003-01-07,2002-01-30
-4kwk,2013-10-23,2013-05-24
-7kwn,2021-12-08,2020-12-01
-4kwm,2014-06-25,2013-05-24
-6kwk,2020-09-09,2019-09-07
-4kw8,2014-04-09,2013-05-23
-6kw5,2020-09-09,2019-09-06
-4kwn,2013-06-12,2013-05-24
-4kww,2013-10-02,2013-05-24
-1kw8,2003-01-29,2002-01-29
-3kwk,2009-12-15,2009-12-01
-7kw1,2021-06-02,2020-11-29
-2kwk,2010-07-14,2010-04-12
-1kw9,2003-01-29,2002-01-29
-1kwx,2002-07-05,2002-01-30
-3kw5,2010-06-16,2009-11-30
-7kwa,2021-07-14,2020-11-30
-6kwq,2019-12-11,2019-09-08
-1kwt,2002-07-05,2002-01-30
-4kws,2014-05-28,2013-05-24
-6kwh,2021-07-14,2019-09-06
-4kw5,2013-07-10,2013-05-23
-3kwv,2010-11-10,2009-12-01
-5kwn,2017-07-26,2016-07-18
-3kw4,2010-09-15,2009-11-30
-3kw9,2010-03-02,2009-12-01
-1kw0,2003-01-28,2002-01-28
-3kw8,2010-12-08,2009-12-01
-7kwv,2021-12-15,2020-12-02
-5kwf,2017-02-01,2016-07-18
-7kw6,2022-01-19,2020-11-30
-3kwz,2010-03-02,2009-12-02
-2kwo,2010-07-14,2010-04-14
-5kwj,2017-03-29,2016-07-18
-7kwo,2021-03-03,2020-12-01
-6kwl,2020-09-09,2019-09-07
-3kwc,2010-02-23,2009-12-01
-5kwa,2017-06-07,2016-07-17
-3kwe,2010-02-23,2009-12-01
-6kwt,2020-09-09,2019-09-08
-4kwe,2013-07-31,2013-05-23
-3kwo,2010-01-19,2009-12-01
-6kw3,2019-11-13,2019-09-05
-4kw6,2013-07-31,2013-05-23
-2kw4,2010-05-05,2010-03-31
-6kwg,2020-12-30,2019-09-06
-6kwo,2020-09-09,2019-09-07
-6kwf,2020-12-30,2019-09-06
-1kwu,2002-07-05,2002-01-30
-7kw9,2021-10-13,2020-11-30
-7kwe,2021-06-16,2020-11-30
-6kwn,2020-09-09,2019-09-07
-6kw0,2020-09-09,2019-09-05
-2kwq,2010-05-19,2010-04-15
-6kw7,2020-03-25,2019-09-06
-7kwf,2021-12-08,2020-11-30
-3kw2,2010-01-19,2009-11-30
-3kw0,2009-12-15,2009-11-30
-5kwe,2017-01-11,2016-07-18
-7kws,2021-01-13,2020-12-02
-4kwf,2014-04-09,2013-05-24
-6kwa,2020-11-11,2019-09-06
-4kw1,2014-06-25,2013-05-23
-4kwh,2013-07-31,2013-05-24
-6kw6,2020-09-09,2019-09-06
-4kwp,2014-04-09,2013-05-24
-1kwc,2003-01-29,2002-01-29
-4kw9,2014-04-09,2013-05-23
-1kwv,2002-07-05,2002-01-30
-4kwo,2014-12-24,2013-05-24
-4kwg,2014-04-09,2013-05-24
-7kw2,2021-03-24,2020-11-29
-6kwb,2020-11-11,2019-09-06
-5kwh,2017-10-25,2016-07-18
-1kwh,2002-02-13,2002-01-29
-7kwu,2021-03-31,2020-12-02
-6kw4,2019-11-13,2019-09-06
-1kws,2002-06-19,2002-01-30
-1kw3,2003-01-28,2002-01-28
-4kwi,2013-07-31,2013-05-24
-4kw7,2014-05-28,2013-05-23
-1kwm,2002-06-05,2002-01-30
-5kw6,2017-08-23,2016-07-15
-5kws,2016-08-03,2016-07-19
-3kwb,2010-04-07,2009-12-01
-2kwj,2010-07-14,2010-04-12
-3kw1,2010-04-28,2009-11-30
-3kwx,2009-12-29,2009-12-01
-4kwj,2013-10-23,2013-05-24
-3kwj,2010-09-15,2009-12-01
-3kwm,2010-01-05,2009-12-01
-3kw7,2010-03-09,2009-12-01
-1kwj,2002-02-06,2002-01-29
-3kwa,2010-07-14,2009-12-01
-5kww,2017-08-02,2016-07-19
-7kw0,2021-03-24,2020-11-29
-1kwk,2002-10-02,2002-01-29
-1kwz,2002-07-05,2002-01-30
-7kwd,2021-04-14,2020-11-30
-3kwf,2010-01-12,2009-12-01
-5kw2,2018-05-02,2016-07-15
-3kwy,2010-01-19,2009-12-02
-1kwf,2002-03-13,2002-01-29
-4kwu,2013-06-19,2013-05-24
-7b9w,2021-01-20,2020-12-14
-4b9t,2013-04-17,2012-09-06
-6b9u,2017-10-25,2017-10-11
-9b92,2024-05-15,2024-04-01
-8b96,2024-04-03,2022-10-05
-7b9a,2022-01-12,2020-12-14
-6b9s,2017-12-20,2017-10-11
-4b9f,2012-09-12,2012-09-04
-6b9b,2018-07-04,2017-10-10
-4b9e,2013-02-06,2012-09-04
-8b9c,2023-08-09,2022-10-05
-8b98,2024-04-03,2022-10-05
-3b9f,2008-04-22,2007-11-05
-1b9a,1999-02-15,1999-02-10
-3b98,2007-11-20,2007-11-03
-6b9l,2018-10-17,2017-10-10
-8b9g,2023-10-18,2022-10-06
-6b9f,2017-12-06,2017-10-10
-3b9x,2008-04-01,2007-11-07
-8b9h,2023-02-01,2022-10-06
-7b9i,2022-01-12,2020-12-14
-3b9h,2008-11-25,2007-11-05
-8b91,2022-12-28,2022-10-05
-6b9t,2017-12-20,2017-10-11
-3b9a,2008-04-01,2007-11-03
-1b9x,1999-02-23,1999-02-16
-6b96,2017-11-22,2017-10-10
-3b9g,2008-04-22,2007-11-05
-3b9s,2008-09-23,2007-11-06
-4b96,2013-09-18,2012-09-02
-3b9m,2008-05-27,2007-11-05
-2b9l,2006-01-03,2005-10-12
-6b95,2018-06-20,2017-10-10
-3b9t,2007-11-20,2007-11-06
-7b91,2021-08-04,2020-12-13
-4b97,2013-09-11,2012-09-03
-4b9v,2013-04-17,2012-09-06
-1b9o,1999-03-31,1999-02-14
-2b9x,2006-01-31,2005-10-13
-7b9z,2021-03-17,2020-12-15
-8b9s,2023-10-18,2022-10-06
-4b95,2012-10-24,2012-08-31
-2b9e,2005-10-18,2005-10-11
-6b98,2017-11-22,2017-10-10
-7b9p,2022-01-12,2020-12-14
-6b92,2018-04-04,2017-10-09
-7b9q,2022-01-12,2020-12-14
-8b9d,2023-08-09,2022-10-05
-2b99,2005-11-08,2005-10-11
-6b9i,2018-10-10,2017-10-10
-1b99,1999-06-28,1999-02-22
-3b9d,2008-04-01,2007-11-05
-7b9t,2021-07-07,2020-12-14
-7b9e,2020-12-23,2020-12-14
-4b99,2012-09-19,2012-09-03
-1b9t,1999-02-27,1999-02-15
-3b99,2007-11-20,2007-11-03
-7b9b,2021-01-20,2020-12-14
-6b9y,2018-09-05,2017-10-11
-8b92,2022-12-28,2022-10-05
-3b9r,2007-12-18,2007-11-06
-1b9s,1999-02-26,1999-02-15
-7b9u,2022-01-12,2020-12-14
-8b9a,2023-08-09,2022-10-05
-8b94,2022-12-28,2022-10-05
-6b9p,2018-09-26,2017-10-11
-2b9j,2006-01-03,2005-10-11
-6b9j,2017-11-22,2017-10-10
-6b9a,2018-10-17,2017-10-10
-6b94,2018-10-10,2017-10-09
-3b9k,2008-11-11,2007-11-05
-9b91,2024-05-15,2024-04-01
-8b9z,2023-01-18,2022-10-10
-7b9c,2021-08-04,2020-12-14
-4b9h,2013-07-17,2012-09-04
-7b9o,2021-02-10,2020-12-14
-3b9l,2008-05-27,2007-11-05
-7b98,2022-01-12,2020-12-14
-6b9g,2017-12-06,2017-10-10
-8b9q,2023-02-08,2022-10-06
-8b90,2022-12-28,2022-10-05
-8b9p,2023-09-20,2022-10-06
-8b9y,2023-05-31,2022-10-10
-7b95,2022-01-12,2020-12-14
-2b9h,2006-01-03,2005-10-11
-4b9b,2013-03-27,2012-09-03
-7b9j,2021-10-20,2020-12-14
-3b92,2007-12-18,2007-11-02
-7b9l,2021-03-03,2020-12-14
-8b9i,2023-10-18,2022-10-06
-2b9f,2006-01-03,2005-10-11
-4b9y,2012-11-14,2012-09-09
-4b9l,2013-04-17,2012-09-05
-8b99,2023-02-01,2022-10-05
-1b9i,1999-08-13,1999-02-11
-6b9r,2017-12-20,2017-10-11
-4b9m,2013-04-17,2012-09-05
-8b9w,2023-05-31,2022-10-10
-2b9i,2006-01-03,2005-10-11
-9b90,2024-05-15,2024-04-01
-8b9j,2023-10-18,2022-10-06
-3b9o,2008-01-15,2007-11-06
-4b9w,2012-10-17,2012-09-08
-2b9d,2005-10-25,2005-10-11
-7b9r,2021-07-07,2020-12-14
-4b9p,2013-09-11,2012-09-06
-7b97,2022-01-12,2020-12-14
-7b92,2021-08-04,2020-12-14
-7b9y,2021-03-17,2020-12-15
-4b9n,2013-04-17,2012-09-05
-2b9a,2005-10-25,2005-10-11
-1b9h,1999-08-13,1999-02-11
-8b93,2022-12-28,2022-10-05
-3b9j,2007-12-04,2007-11-05
-4b9k,2012-10-24,2012-09-05
-3b9b,2007-12-18,2007-11-04
-1b90,1999-03-15,1999-03-06
-4b9o,2012-11-14,2012-09-06
-3b97,2008-09-16,2007-11-02
-2b96,2006-03-28,2005-10-11
-7b9h,2021-06-30,2020-12-14
-7b9m,2021-07-07,2020-12-14
-1b94,1999-02-26,1999-02-19
-1b9m,2000-03-15,1999-02-12
-4b9c,2013-09-11,2012-09-04
-2b9w,2006-01-31,2005-10-13
-6b9o,2018-09-26,2017-10-11
-1b9z,1999-03-15,1999-03-06
-8b9b,2023-08-09,2022-10-05
-6b99,2018-10-17,2017-10-10
-6b91,2018-04-04,2017-10-09
-8b9u,2023-07-05,2022-10-10
-8b95,2022-12-28,2022-10-05
-2b9y,2006-01-31,2005-10-13
-4b9d,2012-09-19,2012-09-04
-2b97,2006-03-28,2005-10-11
-4b9z,2012-11-14,2012-09-09
-8b9o,2023-07-05,2022-10-06
-1b9n,2000-03-15,1999-02-12
-1b9y,1999-02-23,1999-02-16
-1b9j,1999-02-22,1999-02-11
-7b9n,2022-01-12,2020-12-14
-9b94,2024-05-22,2024-04-01
-2b92,2006-03-07,2005-10-10
-6b97,2017-11-22,2017-10-10
-7b9d,2022-01-12,2020-12-14
-7b94,2021-03-03,2020-12-14
-2b9b,2006-01-24,2005-10-11
-6b9d,2017-12-06,2017-10-10
-7b9x,2022-01-12,2020-12-14
-1b9v,1999-02-27,1999-02-15
-3b96,2008-02-12,2007-11-02
-8b9k,2023-10-18,2022-10-06
-4b9s,2013-04-17,2012-09-06
-8b9e,2023-02-01,2022-10-05
-4b9u,2013-04-17,2012-09-06
-8b9r,2023-02-01,2022-10-06
-7b93,2021-05-26,2020-12-14
-4b98,2013-03-27,2012-09-03
-8b9v,2023-10-25,2022-10-10
-7b9v,2021-03-10,2020-12-14
-3b90,2008-04-29,2007-11-02
-7b99,2022-01-12,2020-12-14
-4b9q,2012-11-14,2012-09-06
-4b92,2013-02-13,2012-08-31
-8b97,2023-02-22,2022-10-05
-8b9t,2023-10-18,2022-10-07
-8b9n,2023-10-18,2022-10-06
-6b9v,2018-10-17,2017-10-11
-6b9e,2017-12-06,2017-10-10
-1lf0,2002-11-06,2002-04-10
-3lfy,2010-07-21,2010-01-19
-7lfw,2021-03-10,2021-01-18
-3lfc,2011-04-20,2010-01-16
-4lfm,2013-11-27,2013-06-27
-7lfu,2021-11-10,2021-01-18
-3lf5,2010-07-14,2010-01-15
-7lf3,2022-05-04,2021-01-15
-7lft,2021-03-10,2021-01-18
-6lfr,2020-12-09,2019-12-03
-7lfl,2021-07-14,2021-01-17
-1lfy,2002-10-12,2002-04-12
-5lfv,2016-12-14,2016-07-04
-4lfb,2014-07-02,2013-06-26
-2lfo,2012-07-11,2011-07-07
-5lf2,2016-07-27,2016-06-30
-5lfe,2017-07-12,2016-07-01
-6lfl,2020-09-02,2019-12-03
-4lfg,2013-07-10,2013-06-26
-1lf5,2002-11-06,2002-04-10
-3lfd,2011-04-20,2010-01-16
-7lfo,2021-05-26,2021-01-18
-1lfa,1996-01-29,1995-09-08
-3lfb,2011-04-20,2010-01-16
-7lff,2022-02-09,2021-01-16
-4lfc,2014-07-02,2013-06-26
-3lf1,2010-04-14,2010-01-15
-3lfi,2010-05-12,2010-01-17
-3lf2,2010-04-14,2010-01-15
-1lfv,2002-10-12,2002-04-12
-5lf1,2016-08-17,2016-06-30
-7lfv,2021-11-10,2021-01-18
-7lfe,2021-02-03,2021-01-16
-6lfz,2020-11-18,2019-12-04
-4lf2,2014-06-25,2013-06-26
-5lf7,2016-08-17,2016-06-30
-5lfc,2017-10-11,2016-07-01
-4lfn,2013-11-27,2013-06-27
-4lfy,2013-07-10,2013-06-27
-5lfo,2017-03-15,2016-07-04
-4lf4,2014-07-02,2013-06-26
-1lf8,2002-06-26,2002-04-10
-5lfk,2017-06-07,2016-07-01
-6lfs,2020-12-09,2019-12-03
-1lfg,1994-01-31,1992-02-05
-3lff,2011-04-20,2010-01-16
-6lfj,2020-03-25,2019-12-03
-6lfe,2020-03-04,2019-12-02
-6lfx,2020-12-09,2019-12-03
-4lf9,2014-07-02,2013-06-26
-1lfk,2002-12-11,2002-04-11
-3lfn,2010-03-02,2010-01-18
-4lfi,2014-03-05,2013-06-27
-5lft,2017-07-12,2016-07-04
-1lf3,2002-10-10,2002-04-10
-3lfz,2010-04-21,2010-01-19
-1lfq,2002-10-12,2002-04-12
-6lfw,2020-12-09,2019-12-03
-3lfa,2011-04-20,2010-01-16
-5lf0,2016-08-17,2016-06-30
-6lfu,2020-12-09,2019-12-03
-5lfa,2017-01-11,2016-06-30
-5lfr,2016-12-14,2016-07-04
-1lf2,2002-10-10,2002-04-10
-6lf2,2020-12-02,2019-11-28
-7lfn,2021-01-27,2021-01-17
-4lfv,2014-03-12,2013-06-27
-7lf9,2021-01-27,2021-01-15
-6lfk,2020-12-09,2019-12-03
-3lf0,2010-07-07,2010-01-15
-3lfl,2010-11-24,2010-01-18
-5lf5,2016-12-14,2016-06-30
-7lfr,2021-11-17,2021-01-18
-7lfk,2021-07-14,2021-01-17
-6lfd,2020-02-26,2019-12-02
-5lf6,2016-08-17,2016-06-30
-4lf5,2014-07-02,2013-06-26
-7lfj,2021-07-14,2021-01-17
-2lff,2011-08-24,2011-06-29
-7lfp,2021-02-03,2021-01-18
-4lf6,2014-07-02,2013-06-26
-5lfu,2016-12-14,2016-07-04
-3lfs,2010-03-02,2010-01-18
-7lf1,2021-09-01,2021-01-15
-7lfq,2021-03-03,2021-01-18
-1lfd,1999-05-04,1998-04-29
-3lfe,2011-04-20,2010-01-16
-7lfm,2021-07-14,2021-01-17
-7lfs,2021-11-17,2021-01-18
-7lfz,2021-02-03,2021-01-19
-7lfx,2021-03-10,2021-01-19
-7lfi,2021-07-14,2021-01-17
-3lfr,2010-01-26,2010-01-18
-6lft,2020-12-09,2019-12-03
-1lfl,2002-10-12,2002-04-11
-1lft,2002-10-12,2002-04-12
-5lf4,2016-08-17,2016-06-30
-5lfg,2017-08-09,2016-07-01
-1lfi,1993-10-31,1992-02-10
-2lf1,2011-12-21,2011-06-28
-4lf1,2014-06-25,2013-06-26
-3lft,2010-02-02,2010-01-18
-1lfm,2002-07-19,2002-04-11
-6lf6,2020-11-18,2019-11-29
-4lfh,2013-10-02,2013-06-26
-4lf7,2014-07-02,2013-06-26
-4lfe,2013-07-10,2013-06-26
-3lfq,2010-03-02,2010-01-18
-4lfl,2013-11-27,2013-06-27
-7lf5,2021-01-27,2021-01-15
-1lfw,2002-10-23,2002-04-12
-3lfm,2010-04-07,2010-01-18
-4lfd,2014-02-12,2013-06-26
-6lfm,2020-09-02,2019-12-03
-1lf9,2003-02-25,2002-04-10
-5lf3,2016-08-17,2016-06-30
-5lfz,2017-08-02,2016-07-05
-4lfa,2014-07-02,2013-06-26
-6lfo,2020-09-02,2019-12-03
-1lfo,1997-06-16,1996-12-09
-4lf8,2014-07-02,2013-06-26
-4lfx,2013-10-02,2013-06-27
-6lf7,2020-01-22,2019-11-30
-6lf4,2020-03-25,2019-11-28
-2lfd,2011-08-24,2011-06-29
-4lfz,2014-08-06,2013-06-27
-7lf2,2021-09-01,2021-01-15
-1lfz,2002-10-12,2002-04-12
-6lfh,2020-07-08,2019-12-02
-7lfy,2021-03-10,2021-01-19
-5lfy,2017-08-23,2016-07-05
-4lfp,2013-10-02,2013-06-27
-6lf3,2019-12-11,2019-11-28
-1uod,2004-09-24,2003-09-16
-8uou,2024-04-03,2023-10-20
-4uov,2014-10-15,2014-06-10
-3uol,2012-01-25,2011-11-16
-4uop,2014-08-27,2014-06-06
-4uoa,2014-07-23,2014-05-31
-7uob,2022-11-30,2022-04-12
-4uoz,2014-10-15,2014-06-11
-5uoo,2017-05-17,2017-02-01
-7uo1,2022-09-28,2022-04-12
-5uof,2017-02-15,2017-01-31
-7uoj,2023-05-03,2022-04-13
-5uox,2017-06-07,2017-02-01
-4uor,2014-08-27,2014-06-09
-3uok,2012-01-25,2011-11-16
-5uov,2017-05-10,2017-02-01
-1uo6,2003-10-14,2003-09-16
-6uoa,2020-06-10,2019-10-14
-6uox,2020-01-15,2019-10-15
-5uoy,2017-04-26,2017-02-01
-8uo9,2024-05-22,2023-10-19
-3uox,2012-02-01,2011-11-17
-1uom,2003-07-03,2003-04-11
-5uop,2017-03-29,2017-02-01
-7uot,2022-11-02,2022-04-13
-3uoy,2012-02-01,2011-11-17
-3uo5,2012-01-25,2011-11-16
-4uoi,2014-08-20,2014-06-04
-8uo0,2024-03-06,2023-10-19
-4uob,2015-06-10,2014-06-02
-8uo3,2024-03-06,2023-10-19
-5uo8,2017-05-03,2017-01-31
-7uoo,2023-03-15,2022-04-13
-7uoq,2022-07-06,2022-04-13
-3uom,2012-02-22,2011-11-16
-4uo4,2014-07-23,2014-05-31
-5uo3,2017-05-03,2017-01-31
-8uoa,2024-05-22,2023-10-19
-5uos,2017-06-07,2017-02-01
-3uon,2012-02-01,2011-11-16
-8uo1,2024-03-06,2023-10-19
-7uos,2023-04-19,2022-04-13
-6uob,2019-12-04,2019-10-14
-3uo0,2012-02-29,2011-11-16
-7uox,2023-03-08,2022-04-14
-4uow,2014-12-17,2014-06-10
-3uov,2012-02-01,2011-11-17
-4uo0,2014-07-23,2014-05-31
-1uof,2004-01-09,2003-09-16
-6uo5,2019-12-04,2019-10-14
-1uou,2004-01-22,2003-09-23
-3uop,2012-11-21,2011-11-17
-7uoi,2023-04-12,2022-04-12
-5uo1,2017-05-03,2017-01-31
-4uox,2014-12-10,2014-06-11
-4uo2,2014-07-23,2014-05-31
-3uoh,2012-01-25,2011-11-16
-1uoc,2003-11-20,2003-09-16
-5uo0,2017-05-03,2017-01-31
-6uo4,2019-12-04,2019-10-14
-6uoh,2020-10-21,2019-10-14
-1uog,2004-01-09,2003-09-17
-3uoz,2012-02-01,2011-11-17
-5uo5,2017-05-03,2017-01-31
-8uo8,2024-05-22,2023-10-19
-7uor,2023-02-22,2022-04-13
-7uog,2023-04-19,2022-04-12
-5uor,2017-06-07,2017-02-01
-1uon,2003-11-13,2003-09-21
-5uo9,2017-05-03,2017-01-31
-8uoz,2024-05-29,2023-10-20
-7uod,2023-04-19,2022-04-12
-5uow,2017-03-22,2017-02-01
-6uom,2020-01-08,2019-10-15
-5uoa,2017-05-03,2017-01-31
-4uog,2014-09-10,2014-06-03
-7uof,2022-08-31,2022-04-12
-8uo2,2024-03-06,2023-10-19
-5uoc,2017-05-03,2017-01-31
-4uo8,2014-07-23,2014-05-31
-3uod,2012-01-25,2011-11-16
-4uoh,2014-09-10,2014-06-03
-1uoq,2003-10-02,2003-09-22
-3uof,2012-11-21,2011-11-16
-4uo9,2014-07-23,2014-05-31
-8uo7,2024-02-14,2023-10-19
-6uoi,2019-12-04,2019-10-15
-4uoy,2014-12-10,2014-06-11
-3uo1,2012-07-25,2011-11-16
-6uok,2020-01-08,2019-10-15
-4uoo,2014-08-27,2014-06-06
-8uob,2024-04-03,2023-10-19
-3uoa,2011-12-21,2011-11-16
-1uoo,2003-10-02,2003-09-22
-7uo3,2022-11-02,2022-04-12
-7uow,2023-04-19,2022-04-14
-4uo5,2014-07-23,2014-05-31
-6uo6,2020-03-04,2019-10-14
-4uoq,2014-10-22,2014-06-09
-7uo9,2022-11-30,2022-04-12
-1uop,2003-10-02,2003-09-22
-7uop,2023-03-29,2022-04-13
-7uoe,2022-11-30,2022-04-12
-1uow,2004-09-16,2003-09-24
-6uo3,2019-12-04,2019-10-14
-5uo2,2017-05-03,2017-01-31
-8uo4,2024-03-06,2023-10-19
-7uov,2022-11-02,2022-04-14
-5uod,2017-05-03,2017-01-31
-4uoe,2014-10-08,2014-06-03
-3uot,2011-12-28,2011-11-17
-6uo2,2019-12-04,2019-10-14
-3uo9,2011-12-07,2011-11-16
-6uog,2020-10-21,2019-10-14
-3uow,2011-12-07,2011-11-17
-7uo8,2022-11-02,2022-04-12
-5uoq,2017-03-29,2017-02-01
-4uo1,2014-07-23,2014-05-31
-4uo3,2014-07-23,2014-05-31
-4uoc,2014-10-15,2014-06-02
-6uo7,2019-12-04,2019-10-14
-4uof,2014-09-10,2014-06-03
-5uob,2017-05-03,2017-01-31
-3uo4,2012-01-25,2011-11-16
-6uol,2020-01-08,2019-10-15
-1uo9,2004-01-08,2003-09-16
-4uo6,2014-07-23,2014-05-31
-6uof,2019-11-06,2019-10-14
-1uov,2004-09-09,2003-09-24
-7uo7,2022-11-30,2022-04-12
-3uoi,2012-12-05,2011-11-16
-3uo8,2011-12-21,2011-11-16
-4uoj,2014-07-09,2014-06-04
-3uoj,2012-01-25,2011-11-16
-1uob,2004-01-09,2003-09-16
-6uoz,2020-04-15,2019-10-16
-6uoc,2019-12-04,2019-10-14
-5uo6,2017-05-03,2017-01-31
-7uo4,2022-11-30,2022-04-12
-6uo8,2020-06-10,2019-10-14
-4uo7,2014-07-23,2014-05-31
-6uo9,2020-06-10,2019-10-14
-7uoy,2023-03-08,2022-04-14
-1uo5,2004-10-13,2003-09-15
-6uo1,2019-11-27,2019-10-14
-3uo6,2012-01-25,2011-11-16
-1uo4,2004-10-13,2003-09-15
-5uo7,2017-05-03,2017-01-31
-1uol,2003-10-16,2003-09-19
-5uo4,2017-05-03,2017-01-31
-7uoa,2022-09-07,2022-04-12
-7uoh,2022-08-17,2022-04-12
-1uoz,2004-11-18,2003-09-26
-3odu,2010-10-27,2010-08-11
-2oda,2007-09-04,2006-12-22
-6odb,2020-04-01,2019-03-26
-5odi,2017-08-30,2017-07-05
-7od3,2022-01-26,2021-04-28
-1od2,2003-04-03,2003-02-12
-1odc,2005-03-23,2003-02-15
-5odo,2017-11-29,2017-07-06
-3odi,2011-02-16,2010-08-11
-8odz,2024-02-07,2023-03-10
-3odd,2010-08-25,2010-08-11
-2od9,2007-02-27,2006-12-21
-4od0,2014-09-24,2014-01-09
-5od3,2018-07-04,2017-07-04
-5odn,2018-08-01,2017-07-06
-6odl,2020-04-01,2019-03-26
-4odt,2015-06-24,2014-01-10
-5od9,2018-12-12,2017-07-05
-3od8,2011-01-12,2010-08-11
-1od7,2003-05-16,2003-02-14
-4odr,2015-01-14,2014-01-10
-5odp,2018-08-01,2017-07-06
-5odc,2017-08-30,2017-07-05
-4odg,2014-01-29,2014-01-10
-3odh,2010-10-06,2010-08-11
-3od0,2011-05-11,2010-08-10
-7odf,2021-07-21,2021-04-29
-4odc,2014-12-24,2014-01-10
-5odg,2017-11-15,2017-07-05
-5od6,2017-11-15,2017-07-04
-7odd,2022-06-01,2021-04-29
-8odu,2023-11-29,2023-03-09
-7odi,2022-06-01,2021-04-29
-1odg,2003-03-13,2003-02-19
-2odb,2007-01-30,2006-12-22
-1odx,1997-04-01,1996-09-16
-2od0,2007-01-23,2006-12-21
-4od3,2014-02-26,2014-01-09
-3odl,2011-02-16,2010-08-11
-7odg,2021-07-07,2021-04-29
-2od1,2007-06-19,2006-12-21
-6odf,2020-04-01,2019-03-26
-2odx,2007-01-09,2006-12-27
-7odz,2021-07-14,2021-04-30
-8odp,2024-03-27,2023-03-09
-6ode,2019-10-09,2019-03-26
-3odf,2010-08-25,2010-08-11
-8odv,2023-11-29,2023-03-09
-5od2,2018-01-31,2017-07-04
-2od2,2007-02-20,2006-12-21
-6od0,2020-03-25,2019-03-25
-5odu,2017-10-04,2017-07-06
-3od3,2011-09-07,2010-08-10
-1odh,2003-04-08,2003-02-19
-8odo,2024-03-27,2023-03-09
-7odh,2021-07-07,2021-04-29
-7od5,2022-04-27,2021-04-28
-1ods,2003-07-10,2003-02-20
-1odz,2003-07-10,2003-03-17
-7od0,2021-08-04,2021-04-28
-7odr,2021-06-23,2021-04-30
-4odf,2014-04-02,2014-01-10
-7ods,2021-06-23,2021-04-30
-1odw,1997-04-01,1996-09-16
-7odj,2022-02-16,2021-04-29
-4odv,2015-06-24,2014-01-10
-3od5,2010-10-27,2010-08-11
-6odd,2019-11-27,2019-03-26
-7odl,2022-01-26,2021-04-29
-1odv,2003-03-18,2003-03-14
-8odw,2023-05-31,2023-03-09
-1odb,2003-06-12,2003-02-15
-4odj,2014-03-05,2014-01-10
-7odu,2022-06-01,2021-04-30
-4odp,2015-01-14,2014-01-10
-2od6,2007-01-23,2006-12-21
-7od9,2022-04-27,2021-04-29
-7odk,2022-02-16,2021-04-29
-4od9,2014-08-13,2014-01-10
-3odg,2010-08-25,2010-08-11
-5odq,2017-08-30,2017-07-06
-6oda,2020-04-01,2019-03-26
-5od1,2018-12-12,2017-07-04
-3oda,2011-01-12,2010-08-11
-4odk,2015-01-14,2014-01-10
-1oda,2003-08-14,2003-02-14
-7odc,1999-10-22,1999-03-03
-4odn,2015-01-14,2014-01-10
-1od5,2003-06-02,2003-02-13
-1ody,1999-02-16,1998-07-13
-4odq,2015-01-14,2014-01-10
-1odn,2003-06-19,2003-02-19
-7ody,2021-09-01,2021-04-30
-3ode,2011-01-12,2010-08-11
-1od1,2003-06-12,2003-02-12
-3od7,2010-09-15,2010-08-11
-2odw,2007-06-19,2006-12-27
-3od4,2011-07-06,2010-08-10
-7odt,2021-06-23,2021-04-30
-4odo,2015-01-14,2014-01-10
-5odr,2017-08-30,2017-07-06
-2od3,2007-04-10,2006-12-21
-3odc,2011-01-12,2010-08-11
-1odo,2004-01-02,2003-02-19
-7odv,2022-02-16,2021-04-30
-5odv,2017-09-27,2017-07-06
-7odx,2021-09-01,2021-04-30
-2odq,2007-02-06,2006-12-25
-1od8,2003-04-08,2003-02-14
-2od7,2007-02-27,2006-12-21
-2ody,2008-01-22,2006-12-27
-7odn,2022-04-06,2021-04-30
-2odd,2007-06-19,2006-12-22
-5ody,2018-05-23,2017-07-07
-1od9,2003-05-16,2003-02-14
-3odb,2010-09-15,2010-08-11
-5odh,2017-08-30,2017-07-05
-4odi,2014-01-22,2014-01-10
-8odq,2023-05-31,2023-03-09
-1od6,2003-03-13,2003-02-13
-6od6,2019-09-25,2019-03-26
-5odj,2017-10-25,2017-07-05
-6odg,2019-10-02,2019-03-26
-7od1,2021-09-15,2021-04-28
-4od7,2014-05-28,2014-01-10
-5odz,2017-10-18,2017-07-07
-1odu,2004-01-15,2003-03-14
-5odx,2018-04-18,2017-07-07
-1odm,2003-06-19,2003-02-19
-7odb,2022-06-01,2021-04-29
-2ode,2007-02-06,2006-12-22
-1odi,2003-02-27,2003-02-19
-6odc,2020-04-01,2019-03-26
-3od2,2010-09-08,2010-08-10
-3od9,2010-12-22,2010-08-11
-1odj,2003-03-04,2003-02-19
-7odm,2022-04-20,2021-04-30
-2odn,2007-06-19,2006-12-24
-1od4,2003-04-03,2003-02-12
-4ode,2014-04-02,2014-01-10
-3odk,2010-10-27,2010-08-11
-6odz,2019-06-12,2019-03-27
-2odp,2007-02-06,2006-12-25
-1od3,2003-03-13,2003-02-12
-4odm,2015-01-14,2014-01-10
-3odq,2010-12-01,2010-08-11
-2odi,2007-03-20,2006-12-22
-4od5,2014-03-19,2014-01-10
-5od7,2018-11-21,2017-07-04
-5ode,2017-11-15,2017-07-05
-5odl,2017-10-25,2017-07-05
-5odt,2018-03-14,2017-07-06
-4dp8,2013-02-13,2012-02-13
-1dp5,2000-05-03,1999-12-23
-6dpg,2018-08-15,2018-06-09
-7dpx,2021-07-28,2020-12-21
-5dp8,2016-03-30,2015-09-12
-4dpe,2013-02-20,2012-02-13
-5dp9,2016-03-30,2015-09-12
-5dp7,2016-03-30,2015-09-12
-2dpk,2006-06-13,2006-05-12
-6dpx,2018-07-04,2018-06-09
-6dp6,2018-08-15,2018-06-09
-4dp0,2013-02-13,2012-02-13
-8dph,2022-08-24,2022-07-15
-1dp9,2000-12-24,1999-12-24
-6dpk,2018-08-15,2018-06-09
-5dpm,2016-09-21,2015-09-13
-7dp2,2021-09-08,2020-12-17
-5dp2,2015-11-18,2015-09-12
-3dpc,2009-06-16,2008-07-07
-1dp6,2000-12-23,1999-12-23
-1dp0,2001-02-21,1999-12-22
-1dpo,1997-07-07,1997-03-31
-3dpp,2009-03-10,2008-07-09
-2dp4,2006-05-16,2006-05-05
-8dpf,2022-08-24,2022-07-15
-6dpp,2018-08-15,2018-06-09
-1dpp,1995-12-07,1995-08-11
-3dpl,2008-09-30,2008-07-08
-5dpx,2017-01-11,2015-09-14
-3dp3,2009-05-05,2008-07-07
-8dpm,2023-07-19,2022-07-15
-6dpo,2018-08-15,2018-06-09
-3dpk,2009-02-17,2008-07-08
-6dpe,2018-08-15,2018-06-09
-3dpo,2009-03-10,2008-07-09
-7dpd,2021-05-19,2020-12-18
-5dpg,2016-01-13,2015-09-12
-3dpf,2009-03-03,2008-07-08
-4dpg,2013-02-13,2012-02-13
-4dpm,2012-12-26,2012-02-13
-8dpl,2023-07-19,2022-07-15
-8dp1,2023-07-19,2022-07-14
-2dpr,2007-04-24,2006-05-13
-6dpq,2018-11-07,2018-06-09
-6dpw,2018-07-04,2018-06-09
-4dpv,1997-04-01,1996-02-01
-5dpa,2016-03-30,2015-09-12
-5dp0,2016-05-04,2015-09-11
-5dph,2016-01-13,2015-09-12
-7dpo,2021-12-22,2020-12-21
-5dp4,2016-03-30,2015-09-12
-4dpp,2012-07-18,2012-02-14
-2dpm,1998-12-23,1998-09-03
-8dpg,2022-08-24,2022-07-15
-4dph,2012-11-14,2012-02-13
-5dp3,2016-03-30,2015-09-12
-7dpw,2021-09-15,2020-12-21
-4dp5,2013-02-13,2012-02-13
-6dp1,2018-08-15,2018-06-09
-1dpf,2000-06-21,1999-12-27
-6dpd,2018-08-15,2018-06-09
-5dpl,2016-08-10,2015-09-12
-7dp1,2021-09-08,2020-12-17
-2dpg,1998-07-15,1998-04-17
-8dpc,2022-12-14,2022-07-15
-2dpi,2006-07-04,2006-05-12
-5dp6,2016-03-30,2015-09-12
-4dp1,2013-02-13,2012-02-13
-1dpj,2000-05-03,1999-12-27
-4dp6,2013-02-13,2012-02-13
-1dp8,2000-12-24,1999-12-24
-8dp7,2022-11-09,2022-07-15
-4dpn,2013-03-06,2012-02-13
-3dp9,2009-03-10,2008-07-07
-5dpn,2015-10-28,2015-09-13
-6dps,2018-09-12,2018-06-09
-8dpo,2023-07-19,2022-07-15
-8dpr,2022-08-24,2022-07-16
-5dpf,2015-10-28,2015-09-12
-6dp2,2018-08-15,2018-06-09
-8dpj,2022-09-14,2022-07-15
-3dp5,2008-09-02,2008-07-07
-1dph,1993-01-15,1992-10-30
-8dpd,2022-08-31,2022-07-15
-7dp3,2021-05-19,2020-12-17
-5dpz,2016-09-28,2015-09-14
-4dp2,2013-02-13,2012-02-13
-7dpm,2021-02-17,2020-12-20
-1dpm,1997-08-20,1996-02-13
-6dpc,2018-08-15,2018-06-09
-7dpi,2022-03-23,2020-12-19
-2dph,2007-05-29,2006-05-11
-2dpq,2007-04-24,2006-05-13
-4dpd,2012-11-14,2012-02-13
-4dp4,2013-02-13,2012-02-13
-4dpl,2013-01-16,2012-02-13
-3dp0,2009-05-05,2008-07-07
-8dpb,2023-03-01,2022-07-15
-2dpp,2007-05-22,2006-05-12
-7dp5,2021-12-22,2020-12-18
-7dpr,2021-10-27,2020-12-21
-7dp8,2021-07-07,2020-12-18
-1dpy,2000-06-28,1999-12-28
-4dpq,2012-07-18,2012-02-14
-5dpv,2016-07-20,2015-09-14
-1dpe,1996-08-17,1995-07-25
-2dpy,2006-12-26,2006-05-18
-7dpk,2022-02-02,2020-12-19
-6dp0,2018-08-15,2018-06-09
-2dp8,2006-05-23,2006-05-08
-8dp2,2022-08-17,2022-07-14
-8dpt,2023-11-29,2022-07-17
-3dp8,2008-09-16,2008-07-07
-7dp0,2021-09-08,2020-12-17
-2dpw,2007-05-22,2006-05-17
-6dpm,2018-08-15,2018-06-09
-6dpa,2018-08-15,2018-06-09
-2dpz,2006-06-06,2006-05-18
-5dp5,2016-03-30,2015-09-12
-8dpu,2023-11-29,2022-07-17
-8dpi,2022-08-24,2022-07-15
-7dpp,2021-05-12,2020-12-21
-6dp7,2018-08-15,2018-06-09
-4dpa,2013-02-13,2012-02-13
-6dpi,2018-08-15,2018-06-09
-7dpj,2021-07-28,2020-12-19
-3dp6,2008-11-25,2008-07-07
-7dpn,2021-12-22,2020-12-20
-7dp4,2021-12-22,2020-12-18
-1dp2,2000-12-13,1999-12-23
-4dpt,2012-07-11,2012-02-14
-3dpg,2008-08-19,2008-07-08
-5dpd,2016-08-10,2015-09-12
-6dpn,2018-08-15,2018-06-09
-2dpx,2006-08-08,2006-05-18
-4dpu,2012-07-11,2012-02-14
-3dpq,2009-03-10,2008-07-09
-6dpl,2018-08-15,2018-06-09
-7dpu,2021-05-12,2020-12-21
-6dpv,2018-07-04,2018-06-09
-3dp2,2009-05-05,2008-07-07
-6dpf,2018-08-15,2018-06-09
-2dpt,2007-01-02,2006-05-14
-4dp7,2013-02-13,2012-02-13
-2dpe,2006-05-30,2006-05-11
-6dpb,2018-08-15,2018-06-09
-6dpy,2018-07-04,2018-06-09
-7dps,2021-10-27,2020-12-21
-4dp3,2012-11-14,2012-02-13
-7dpe,2021-12-22,2020-12-18
-6dpr,2018-11-07,2018-06-09
-4dpb,2013-02-13,2012-02-13
-3dpy,2008-09-30,2008-07-09
-7dpv,2021-05-12,2020-12-21
-6dp3,2018-08-15,2018-06-09
-4dpc,2013-02-13,2012-02-13
-4dpy,2012-07-11,2012-02-14
-3dpr,2009-04-07,2008-07-09
-4dpi,2012-07-11,2012-02-13
-8dpz,2023-08-02,2022-07-18
-8dps,2023-11-29,2022-07-17
-6dp4,2018-08-15,2018-06-09
-1dps,1998-09-16,1998-02-23
-1dp4,2000-07-12,1999-12-23
-4dp9,2013-02-13,2012-02-13
-5dpw,2016-09-28,2015-09-14
-6dph,2018-08-15,2018-06-09
-3dp4,2008-11-25,2008-07-07
-5dpe,2015-10-28,2015-09-12
-4dpw,2012-07-11,2012-02-14
-7dpt,2021-09-15,2020-12-21
-7dph,2021-07-28,2020-12-19
-6dpj,2018-08-15,2018-06-09
-3dp1,2009-05-05,2008-07-07
-6dp5,2018-08-15,2018-06-09
-2dpj,2006-07-04,2006-05-12
-6dpu,2018-07-04,2018-06-09
-4dpr,2013-02-20,2012-02-14
-3dpm,2009-01-13,2008-07-09
-6dpz,2018-07-04,2018-06-09
-3dpd,2008-08-26,2008-07-08
-7dp6,2021-12-22,2020-12-18
-3dpe,2009-03-03,2008-07-08
-8dp5,2023-06-28,2022-07-14
-6dpt,2018-07-04,2018-06-09
-4dpf,2012-07-11,2012-02-13
-6dp8,2018-08-15,2018-06-09
-6dp9,2018-08-15,2018-06-09
-1brj,1995-07-10,1995-03-09
-3bre,2008-04-01,2007-12-21
-3br1,2008-12-23,2007-12-20
-6brj,2018-12-05,2017-11-30
-8brw,2023-08-16,2022-11-24
-5br6,2015-08-12,2015-05-29
-1br8,1998-09-02,1998-08-26
-5bro,2016-05-04,2015-06-01
-4brk,2013-07-17,2013-06-04
-2br3,2006-03-15,2005-05-01
-1br1,1998-09-09,1998-08-26
-5brb,2015-07-29,2015-05-30
-6brx,2018-08-22,2017-12-01
-4br0,2013-07-17,2013-06-03
-5br4,2015-12-23,2015-05-29
-4brc,2013-07-17,2013-06-04
-5brf,2015-06-17,2015-05-30
-3br5,2008-12-23,2007-12-20
-4brs,2013-09-18,2013-06-05
-3br3,2008-12-23,2007-12-20
-8br7,2024-01-31,2022-11-22
-7brs,2021-03-03,2020-03-30
-5brk,2015-07-08,2015-05-31
-6brb,2018-12-05,2017-11-30
-3br9,2008-12-23,2007-12-21
-1brk,1995-07-10,1995-03-09
-4bre,2013-07-17,2013-06-04
-4brj,2014-06-11,2013-06-04
-3brq,2008-01-22,2007-12-21
-6br1,2018-06-27,2017-11-29
-8brc,2023-01-18,2022-11-22
-2brh,2005-05-12,2005-05-05
-2bra,2005-11-01,2005-05-04
-6br4,2017-12-27,2017-11-29
-4brr,2014-06-18,2013-06-05
-5brt,2015-08-19,2015-06-01
-4brf,2013-07-17,2013-06-04
-7bry,2020-08-26,2020-03-30
-8br6,2024-01-31,2022-11-22
-7br4,2021-03-31,2020-03-26
-6bri,2018-02-07,2017-11-30
-7br5,2021-03-10,2020-03-26
-4brn,2013-07-17,2013-06-04
-6brk,2018-02-14,2017-11-30
-8brd,2023-06-14,2022-11-23
-6br5,2018-03-07,2017-11-30
-7br0,2020-12-23,2020-03-26
-7brz,2020-08-26,2020-03-30
-6br7,2018-02-21,2017-11-30
-4brq,2013-07-17,2013-06-05
-2brc,2005-09-29,2005-05-04
-2brm,2005-05-12,2005-05-09
-7brh,2021-03-31,2020-03-29
-2brq,2006-02-07,2005-05-11
-6brl,2018-01-17,2017-11-30
-7brw,2020-08-26,2020-03-30
-5br0,2015-08-12,2015-05-29
-6br2,2018-03-21,2017-11-29
-6brw,2018-08-15,2017-12-01
-2brn,2005-05-12,2005-05-09
-8brp,2023-03-01,2022-11-23
-8brb,2023-04-19,2022-11-22
-2bru,2006-08-29,2005-05-11
-2br1,2005-05-12,2005-04-29
-7brx,2020-08-26,2020-03-30
-3brf,2008-04-01,2007-12-21
-2br9,2005-05-12,2005-05-03
-2brl,2005-06-14,2005-05-06
-7brj,2021-03-31,2020-03-29
-5brn,2015-10-14,2015-05-31
-5brd,2015-06-17,2015-05-30
-2br0,2005-06-23,2005-04-28
-4br5,2013-07-17,2013-06-04
-8br2,2023-05-03,2022-11-22
-4brb,2014-06-18,2013-06-04
-1br4,1998-09-09,1998-08-27
-7brl,2021-03-31,2020-03-29
-7brn,2020-07-08,2020-03-29
-7br3,2020-10-07,2020-03-26
-7bri,2021-03-31,2020-03-29
-2brd,1996-06-10,1995-12-27
-8brx,2023-08-16,2022-11-24
-6bre,2018-01-24,2017-11-30
-2bry,2005-10-26,2005-05-13
-8brt,2023-05-03,2022-11-23
-2bre,2005-09-29,2005-05-04
-1bra,1994-04-30,1992-12-17
-4brg,2013-07-17,2013-06-04
-8bru,2023-08-16,2022-11-24
-7brf,2021-03-31,2020-03-28
-1br2,1998-09-09,1998-08-26
-1brg,1994-06-22,1994-03-30
-3br2,2008-12-23,2007-12-20
-4brx,2013-07-24,2013-06-05
-6bru,2017-12-13,2017-12-01
-5bre,2015-06-17,2015-05-30
-5brh,2015-06-17,2015-05-30
-6brt,2018-11-21,2017-12-01
-7brv,2020-08-26,2020-03-30
-2br4,2006-03-15,2005-05-01
-6br3,2018-03-21,2017-11-29
-4brl,2013-07-17,2013-06-04
-1brr,1998-09-30,1998-07-28
-1brf,1998-09-02,1998-08-24
-3bra,2008-03-11,2007-12-21
-8br9,2023-03-08,2022-11-22
-5brp,2016-03-02,2015-06-01
-5br7,2016-06-01,2015-05-29
-3br0,2008-12-23,2007-12-20
-5brw,2015-06-17,2015-06-01
-7br1,2021-04-07,2020-03-26
-6bra,2018-07-18,2017-11-30
-1br5,1998-09-02,1998-08-26
-2brb,2005-05-12,2005-05-04
-2brp,2006-04-24,2005-05-10
-8brl,2023-05-24,2022-11-23
-4br2,2013-07-17,2013-06-03
-4bra,2013-07-17,2013-06-04
-4brv,2014-06-18,2013-06-05
-5bru,2015-06-24,2015-06-01
-5brj,2016-02-24,2015-05-31
-1brh,1995-07-10,1995-03-09
-4br4,2013-07-17,2013-06-03
-3brw,2008-03-11,2007-12-21
-8brs,2023-05-03,2022-11-23
-5br2,2016-09-14,2015-05-29
-3brb,2008-01-22,2007-12-21
-7brc,2020-08-19,2020-03-27
-2brt,2006-08-29,2005-05-11
-3brp,2009-02-24,2007-12-21
-8bra,2023-04-19,2022-11-22
-8brr,2023-05-03,2022-11-23
-4brh,2013-07-17,2013-06-04
-5brx,2015-06-24,2015-06-01
-6brd,2017-12-13,2017-11-30
-5br3,2015-08-12,2015-05-29
-6brf,2018-06-27,2017-11-30
-1brx,1999-01-27,1998-05-28
-1brn,1994-01-31,1993-11-17
-8bro,2023-02-08,2022-11-23
-2brg,2005-05-12,2005-05-05
-1brp,1994-01-31,1992-07-27
-8brh,2024-06-05,2022-11-23
-3brn,2008-04-01,2007-12-21
-1brw,1999-01-13,1998-08-25
-5bry,2015-09-09,2015-06-01
-1brd,1991-04-15,1990-05-23
-5brm,2015-07-08,2015-05-31
-8brn,2023-08-02,2022-11-23
-6brm,2018-01-31,2017-11-30
-5br1,2015-06-10,2015-05-29
-5br8,2015-11-18,2015-05-29
-7brk,2021-03-31,2020-03-29
-2bri,2005-07-25,2005-05-05
-8brq,2023-05-03,2022-11-23
-6brc,2017-12-13,2017-11-30
-1bru,1999-08-25,1998-08-24
-6bry,2018-06-27,2017-12-01
-3brx,2008-05-06,2007-12-21
-2bro,2005-05-12,2005-05-09
-8brk,2023-05-24,2022-11-23
-8br4,2023-11-01,2022-11-22
-3br6,2008-12-23,2007-12-20
-8br1,2023-09-20,2022-11-22
-4bri,2013-07-17,2013-06-04
-8brv,2023-08-16,2022-11-24
-8br0,2023-09-20,2022-11-22
-7bre,2020-07-22,2020-03-28
-1br6,1998-09-02,1998-08-27
-3brh,2009-02-17,2007-12-21
-6brr,2018-01-31,2017-11-30
-7brp,2020-05-13,2020-03-29
-6brh,2018-02-14,2017-11-30
-4brd,2013-07-17,2013-06-04
-2brk,2005-06-14,2005-05-06
-3brm,2008-05-20,2007-12-21
-4br7,2013-07-17,2013-06-04
-5brq,2016-03-02,2015-06-01
-4br6,2013-12-18,2013-06-04
-6brs,2018-06-20,2017-11-30
-2br5,2006-03-15,2005-05-01
-8br5,2024-01-31,2022-11-22
-7brg,2021-03-31,2020-03-29
-6br6,2018-03-07,2017-11-30
-6brg,2018-02-14,2017-11-30
-5brz,2016-03-02,2015-06-01
-2br6,2005-12-07,2005-05-03
-4br3,2013-06-19,2013-06-03
-5br5,2016-09-14,2015-05-29
-6vwc,2020-10-21,2020-02-19
-6vw4,2020-06-17,2020-02-18
-1vwq,1998-03-18,1997-03-03
-2vwp,2009-01-13,2008-06-26
-5vw1,2017-06-28,2017-05-21
-2vwh,2009-01-13,2008-06-24
-7vw4,2022-11-16,2021-11-09
-2vwn,2009-07-07,2008-06-26
-7vwd,2023-01-18,2021-11-10
-8vwp,2024-05-01,2024-02-02
-1vwd,1998-03-18,1997-03-03
-5vwj,2018-10-03,2017-05-22
-5vw5,2017-08-23,2017-05-21
-7vwz,2022-06-08,2021-11-12
-7vwg,2022-02-09,2021-11-10
-5vwd,2018-10-03,2017-05-21
-1vwm,1998-03-18,1997-03-03
-7vwy,2022-06-08,2021-11-12
-5vwt,2017-05-31,2017-05-22
-2vww,2008-07-08,2008-06-27
-6vwm,2020-06-03,2020-02-20
-2vwz,2008-10-28,2008-06-30
-5vwa,2017-08-23,2017-05-21
-3vw9,2012-12-12,2012-08-10
-2vwb,2008-08-19,2008-06-20
-2vw6,2008-09-09,2008-06-16
-6vwf,2020-08-05,2020-02-19
-3vwq,2013-10-16,2012-08-30
-5vwg,2018-05-23,2017-05-21
-5vw6,2017-08-23,2017-05-21
-6vw0,2020-10-21,2020-02-18
-5vw4,2017-08-23,2017-05-21
-1vwp,1998-03-18,1997-03-03
-7vw1,2022-01-26,2021-11-09
-8vw1,2024-02-14,2024-01-31
-3vw8,2013-08-14,2012-08-08
-2vwl,2009-07-07,2008-06-26
-3vw1,2013-07-03,2012-07-30
-5vwn,2018-04-04,2017-05-22
-5vwr,2017-09-13,2017-05-22
-7vwt,2022-03-23,2021-11-11
-6vwn,2020-06-03,2020-02-20
-1vwj,1998-03-18,1997-03-03
-1vwc,1998-03-18,1997-03-03
-2vwo,2009-07-07,2008-06-26
-3vwe,2013-08-28,2012-08-22
-5vw7,2017-08-23,2017-05-21
-7vwh,2022-02-09,2021-11-10
-6vwr,2021-02-24,2020-02-20
-2vwk,2008-07-22,2008-06-26
-6vwo,2020-10-07,2020-02-20
-3vwr,2013-10-16,2012-08-30
-1vwf,1998-03-18,1997-03-03
-1vwt,1998-03-25,1997-03-20
-7vwb,2023-03-08,2021-11-10
-3vwp,2013-10-16,2012-08-30
-2vw8,2010-07-14,2008-06-17
-1vwi,1998-03-18,1997-03-03
-8vw2,2024-02-14,2024-01-31
-2vw5,2008-09-02,2008-06-16
-1vwn,1998-03-18,1997-03-03
-6vwp,2020-10-07,2020-02-20
-7vwl,2022-04-06,2021-11-11
-1vwb,1998-03-18,1997-03-03
-5vwk,2017-11-08,2017-05-22
-7vwf,2022-02-09,2021-11-10
-6vww,2020-03-04,2020-02-20
-2vwy,2008-10-28,2008-06-30
-6vwg,2020-05-13,2020-02-19
-1vwh,1998-03-18,1997-03-03
-3vw2,2013-07-03,2012-07-30
-5vwi,2017-11-08,2017-05-22
-2vwj,2008-07-22,2008-06-25
-3vwn,2013-10-16,2012-08-30
-2vwv,2008-07-08,2008-06-27
-1vwe,1998-03-18,1997-03-03
-7vw3,2023-03-15,2021-11-09
-7vwp,2022-09-21,2021-11-11
-2vwc,2008-07-01,2008-06-20
-2vwi,2008-07-08,2008-06-25
-3vw7,2012-12-12,2012-08-07
-2vw4,2008-09-09,2008-06-16
-7vw2,2022-01-26,2021-11-09
-7vwe,2022-02-09,2021-11-10
-6vwi,2020-05-13,2020-02-19
-1vwa,1998-03-18,1997-03-03
-3vw0,2013-07-03,2012-07-30
-7vw7,2022-06-22,2021-11-09
-5vwo,2017-08-30,2017-05-22
-6vwq,2021-02-24,2020-02-20
-2vw7,2008-09-09,2008-06-16
-6vw7,2020-04-08,2020-02-18
-6vwl,2020-06-03,2020-02-20
-3vwk,2012-10-03,2012-08-24
-5vwh,2018-10-03,2017-05-21
-1vwg,1998-03-18,1997-03-03
-3vwx,2013-02-27,2012-09-05
-5vwm,2017-06-07,2017-05-22
-3vwj,2012-10-03,2012-08-24
-3vwd,2013-08-28,2012-08-22
-2vw1,2008-06-24,2008-06-13
-2vwq,2009-01-13,2008-06-26
-8vw0,2024-02-14,2024-01-31
-7vw5,2022-02-16,2021-11-09
-6vw1,2020-03-04,2020-02-18
-2vwx,2008-10-28,2008-06-27
-1vwk,1998-03-18,1997-03-03
-1vwl,1998-03-18,1997-03-03
-1vwr,1998-03-18,1997-03-03
-5vws,2017-06-07,2017-05-22
-3vws,2013-02-27,2012-08-31
-5vwu,2017-05-31,2017-05-22
-5vw8,2017-08-23,2017-05-21
-2vwm,2009-07-07,2008-06-26
-7vws,2022-03-23,2021-11-11
-7vwj,2022-04-06,2021-11-10
-5vw2,2017-08-23,2017-05-21
-3vw6,2012-10-31,2012-08-06
-2vwt,2008-09-09,2008-06-26
-2vwg,2009-01-13,2008-06-24
-1vwo,1998-03-18,1997-03-03
-5vwf,2018-10-03,2017-05-21
-5vwq,2017-08-30,2017-05-22
-6vwe,2020-04-01,2020-02-19
-2vwd,2008-10-07,2008-06-20
-6vw8,2020-04-08,2020-02-18
-6vwx,2020-06-24,2020-02-20
-2vwu,2008-07-08,2008-06-27
-5vw9,2017-08-23,2017-05-21
-5vwb,2017-08-23,2017-05-21
-5vw3,2017-08-23,2017-05-21
-1nr5,2003-03-18,2003-01-23
-1nrx,2003-03-18,2003-01-26
-4nrc,2013-12-25,2013-11-26
-6nrh,2019-08-14,2019-01-23
-4nrh,2014-10-15,2013-11-26
-6nr2,2019-02-20,2019-01-22
-3nrr,2010-07-14,2010-06-30
-4nru,2014-10-15,2013-11-27
-5nr3,2018-05-30,2017-04-21
-5nry,2017-05-31,2017-04-25
-7nrj,2022-03-23,2021-03-04
-6nr6,2019-06-19,2019-01-22
-5nri,2018-05-30,2017-04-23
-7nrl,2021-06-16,2021-03-04
-6nrq,2019-02-06,2019-01-24
-5nrn,2018-08-08,2017-04-25
-4nr8,2013-12-25,2013-11-26
-6nrj,2019-08-14,2019-01-23
-2nrv,2007-02-06,2006-11-02
-4nr6,2013-12-18,2013-11-26
-3nrm,2010-08-18,2010-06-30
-7nr2,2021-10-06,2021-03-02
-3nrt,2010-09-15,2010-06-30
-6nrr,2019-02-06,2019-01-24
-6nrz,2019-02-20,2019-01-24
-4nr7,2013-12-18,2013-11-26
-1nr6,2003-08-12,2003-01-23
-7nr8,2021-10-06,2021-03-03
-3nr4,2010-07-14,2010-06-30
-1nrm,2003-02-04,2003-01-25
-7nr7,2021-06-09,2021-03-03
-5nrs,2018-05-30,2017-04-25
-7nrc,2021-05-05,2021-03-03
-6nrf,2019-08-14,2019-01-23
-4nrb,2013-12-25,2013-11-26
-3nrc,2010-11-10,2010-06-30
-5nrh,2018-05-30,2017-04-23
-4nr9,2013-12-25,2013-11-26
-4nr0,2014-11-26,2013-11-26
-3nrb,2010-07-28,2010-06-30
-6nrx,2019-02-06,2019-01-24
-5nru,2017-05-31,2017-04-25
-5nrx,2017-05-31,2017-04-25
-1nrr,1994-05-31,1994-01-18
-4nr4,2013-12-18,2013-11-26
-4nrj,2014-03-12,2013-11-26
-7nro,2021-10-13,2021-03-04
-7nra,2021-10-06,2021-03-03
-5nrd,2017-10-11,2017-04-22
-3nrq,2011-05-18,2010-06-30
-5nrw,2017-08-16,2017-04-25
-5nrk,2018-01-31,2017-04-24
-1nru,2003-02-04,2003-01-25
-5nrr,2018-05-30,2017-04-25
-5nrt,2017-05-31,2017-04-25
-2nr9,2006-11-14,2006-11-01
-4nrs,2014-11-19,2013-11-27
-7nr5,2021-10-06,2021-03-03
-4nrk,2014-03-12,2013-11-26
-3nre,2010-09-15,2010-06-30
-2nrm,2007-05-08,2006-11-02
-1nr0,2003-07-01,2003-01-23
-5nro,2018-01-17,2017-04-25
-7nr3,2021-10-06,2021-03-02
-6nr0,2020-01-22,2019-01-22
-6nrw,2019-02-06,2019-01-24
-3nr9,2010-08-25,2010-06-30
-2nr6,2008-02-19,2006-11-01
-3nri,2010-12-22,2010-06-30
-4nrz,2014-02-05,2013-11-27
-1nrs,1994-05-31,1994-01-18
-5nra,2018-03-28,2017-04-22
-5nrl,2017-05-31,2017-04-24
-3nrj,2010-07-28,2010-06-30
-7nrk,2021-06-16,2021-03-04
-6nro,2019-07-17,2019-01-23
-4nrt,2014-10-15,2013-11-27
-5nr7,2018-03-21,2017-04-22
-7nr4,2021-04-07,2021-03-02
-6nr3,2019-02-20,2019-01-22
-4nre,2014-02-12,2013-11-26
-7nrr,2021-10-06,2021-03-04
-4nrq,2014-03-19,2013-11-27
-1nr8,2003-10-28,2003-01-24
-2nrz,2007-02-06,2006-11-02
-4nr5,2013-12-18,2013-11-26
-5nrb,2017-10-11,2017-04-22
-4nrr,2014-11-19,2013-11-27
-6nr5,2019-07-17,2019-01-22
-6nrg,2019-08-14,2019-01-23
-1nrg,2003-02-11,2003-01-24
-5nre,2017-10-11,2017-04-22
-3nrn,2010-11-03,2010-06-30
-1nrl,2003-08-19,2003-01-25
-3nrz,2010-07-14,2010-07-01
-4nrp,2014-03-19,2013-11-27
-7nrh,2021-06-23,2021-03-03
-5nr2,2018-05-16,2017-04-21
-3nr6,2011-02-02,2010-06-30
-5nrp,2017-09-27,2017-04-25
-7nrw,2021-09-01,2021-03-04
-5nrq,2018-08-08,2017-04-25
-1nrw,2003-07-29,2003-01-25
-7nr1,2022-09-21,2021-03-02
-2nrl,2007-05-08,2006-11-02
-5nrv,2018-06-13,2017-04-25
-5nrm,2018-01-31,2017-04-24
-7nr6,2022-03-23,2021-03-03
-1nr9,2003-07-29,2003-01-24
-4nra,2013-12-25,2013-11-26
-3nr1,2010-09-08,2010-06-30
-6nr7,2020-01-29,2019-01-23
-5nrz,2017-05-31,2017-04-25
-7nrb,2022-01-12,2021-03-03
-5nr8,2018-02-21,2017-04-22
-4nrn,2014-10-15,2013-11-27
-2nrd,1995-12-07,1995-07-03
-7nry,2022-02-09,2021-03-04
-4nrl,2014-03-12,2013-11-26
-4nro,2014-03-19,2013-11-27
-6nri,2019-08-14,2019-01-23
-2nry,2006-12-12,2006-11-02
-2nr4,2006-11-07,2006-11-01
-5nrg,2017-08-09,2017-04-23
-2nru,2006-12-12,2006-11-02
-5nrf,2018-03-28,2017-04-22
-4nr1,2015-01-21,2013-11-26
-1nrj,2003-03-25,2003-01-24
-7nrg,2022-03-23,2021-03-03
-7nr9,2021-10-06,2021-03-03
-3nrv,2010-09-15,2010-06-30
-4ymt,2015-04-22,2015-03-07
-6ymq,2021-02-17,2020-04-09
-5yms,2018-05-02,2017-10-22
-2ym1,2011-06-22,2011-06-06
-7ymv,2023-08-09,2022-07-29
-4ymj,2015-06-03,2015-03-06
-1ymv,1996-04-03,1995-12-14
-4ymg,2015-05-27,2015-03-06
-1ymx,2005-04-26,2005-01-21
-2ymv,2012-11-21,2012-10-10
-6ym9,2021-04-21,2020-04-08
-4yma,2015-08-05,2015-03-06
-2ym2,2011-06-22,2011-06-06
-6ymp,2021-04-21,2020-04-09
-6yms,2021-04-21,2020-04-09
-7ymg,2023-01-18,2022-07-28
-4ymh,2015-05-27,2015-03-06
-2ymd,2012-12-12,2012-10-09
-6ymy,2020-09-09,2020-04-10
-1yms,2005-04-26,2005-01-21
-4ymk,2015-06-24,2015-03-06
-6ymb,2020-08-12,2020-04-08
-4ym0,2015-07-01,2015-03-06
-2ymz,2013-08-28,2012-10-11
-7ym5,2023-08-02,2022-07-27
-6ym5,2021-04-14,2020-04-07
-2ym8,2012-01-11,2011-06-06
-6ymr,2021-04-21,2020-04-09
-7ymj,2023-07-05,2022-07-28
-7ymz,2023-08-09,2022-07-29
-2ymt,2013-07-10,2012-10-10
-6ymo,2021-03-24,2020-04-09
-1ym0,2005-04-19,2005-01-20
-6ymh,2021-04-28,2020-04-08
-6ymd,2020-06-03,2020-04-08
-4ymq,2015-04-22,2015-03-07
-4ym9,2016-06-29,2015-03-06
-7ym1,2023-08-02,2022-07-27
-1ymc,1994-01-31,1993-09-27
-2yme,2012-12-26,2012-10-09
-7ymo,2022-08-31,2022-07-29
-7ym0,2023-01-04,2022-07-27
-2ymk,2012-10-17,2012-10-09
-1ym2,2006-01-17,2005-01-20
-7ymm,2023-08-16,2022-07-28
-4ymx,2015-04-22,2015-03-07
-7ymh,2023-07-05,2022-07-28
-7ymi,2023-08-16,2022-07-28
-6ymx,2020-09-09,2020-04-10
-6yma,2020-08-12,2020-04-08
-5ymr,2019-03-20,2017-10-22
-2yms,2013-10-30,2012-10-10
-6ym2,2021-04-14,2020-04-07
-1ym4,2006-01-17,2005-01-20
-2ym3,2012-01-11,2011-06-06
-1ymb,1994-01-31,1993-09-27
-4ymd,2015-04-08,2015-03-06
-4ymi,2016-03-09,2015-03-06
-4ym2,2015-07-01,2015-03-06
-6ym1,2021-04-14,2020-04-07
-5ymx,2018-10-24,2017-10-22
-6ymz,2021-02-17,2020-04-10
-4ym7,2015-09-09,2015-03-06
-7ymw,2023-08-09,2022-07-29
-4ym1,2015-07-01,2015-03-06
-5ym3,2018-10-24,2017-10-20
-4ymv,2015-04-22,2015-03-07
-4ymw,2015-04-22,2015-03-07
-1yma,1994-01-31,1993-09-27
-1ym3,2005-03-08,2005-01-20
-7ymb,2023-08-02,2022-07-28
-4ymb,2015-08-05,2015-03-06
-2ym7,2012-01-11,2011-06-06
-1ymq,2005-06-28,2005-01-21
-2ym5,2012-01-11,2011-06-06
-2ym6,2012-01-11,2011-06-06
-7ym8,2023-07-05,2022-07-27
-4ymu,2015-04-22,2015-03-07
-4ymm,2016-03-09,2015-03-06
-5ymt,2018-05-02,2017-10-22
-4ym3,2015-07-01,2015-03-06
-1yme,1997-02-12,1996-07-15
-1ym1,2005-04-26,2005-01-20
-8ym2,2024-05-29,2024-03-08
-6ymf,2020-06-03,2020-04-08
-2ymw,2013-10-23,2012-10-10
-2ymy,2013-03-20,2012-10-10
-7ymt,2023-08-09,2022-07-29
-1ymm,2005-05-03,2005-01-21
-5ymw,2018-10-24,2017-10-22
-7ymy,2023-08-09,2022-07-29
-6ym8,2021-04-14,2020-04-07
-5ymv,2018-10-24,2017-10-22
-4ymo,2016-03-09,2015-03-07
-6ym3,2021-04-14,2020-04-07
-4yml,2015-08-26,2015-03-06
-7ymx,2023-08-09,2022-07-29
-7yml,2023-02-22,2022-07-28
-6ym4,2021-04-14,2020-04-07
-6ymw,2020-12-09,2020-04-10
-4ymn,2016-03-09,2015-03-06
-2ym4,2012-01-11,2011-06-06
-4ym8,2015-12-23,2015-03-06
-4ymp,2016-07-20,2015-03-07
-7ymk,2023-05-31,2022-07-28
-2rgx,2007-12-18,2007-10-05
-5rgq,2020-04-15,2020-04-07
-2rgd,2007-12-18,2007-10-03
-1rg9,2004-03-02,2003-11-11
-2rgs,2008-10-07,2007-10-05
-5rgn,2020-04-15,2020-04-07
-3rgz,2011-06-15,2011-04-11
-4rgp,2014-12-24,2014-09-30
-3rg1,2011-08-31,2011-04-07
-6rgu,2020-07-01,2019-04-17
-8rge,2023-12-27,2023-12-13
-5rgb,2020-07-22,2020-03-19
-7rgf,2022-03-16,2021-07-15
-2rga,2007-12-18,2007-10-03
-4rg0,2014-12-24,2014-09-29
-6rgg,2020-07-01,2019-04-16
-6rge,2020-05-13,2019-04-16
-5rg3,2020-04-15,2020-03-18
-4rgv,2015-07-22,2014-09-30
-5rgf,2020-07-22,2020-03-19
-2rge,2007-12-18,2007-10-03
-5rgu,2020-05-27,2020-05-15
-2rgh,2008-01-15,2007-10-01
-5rgg,2020-04-15,2020-04-07
-6rg7,2020-02-19,2019-04-16
-4rgu,2015-03-04,2014-09-30
-6rgy,2020-02-19,2019-04-18
-3rgx,2011-06-15,2011-04-11
-5rgy,2020-05-27,2020-05-15
-5rg1,2020-04-15,2020-03-18
-6rgh,2019-04-24,2019-04-16
-3rgf,2011-08-10,2011-04-08
-5rgh,2020-04-15,2020-04-07
-2rgz,2007-10-23,2007-10-05
-7rgd,2022-01-12,2021-07-15
-5rgc,2020-07-22,2020-03-19
-5rgo,2020-04-15,2020-04-07
-3rgl,2011-06-08,2011-04-08
-2rg5,2008-01-15,2007-10-02
-3rgy,2011-05-04,2011-04-11
-1rgl,1993-01-15,1992-02-19
-1rgc,1994-01-31,1993-05-12
-6rg3,2020-05-13,2019-04-16
-1rg1,2004-03-02,2003-11-10
-2rg9,2008-10-07,2007-10-03
-7rgl,2022-01-12,2021-07-15
-4rg4,2014-10-15,2014-09-29
-6rgb,2020-02-19,2019-04-16
-6rg9,2020-02-19,2019-04-16
-2rgp,2008-08-26,2007-10-04
-1rgz,2004-04-06,2003-11-13
-6rgd,2020-02-19,2019-04-16
-6rgr,2020-07-01,2019-04-17
-6rgz,2020-02-19,2019-04-18
-5rgk,2020-04-15,2020-04-07
-3rgs,2011-05-11,2011-04-08
-1rgt,2004-03-02,2003-11-12
-7rgj,2022-05-25,2021-07-15
-6rgt,2020-05-13,2019-04-17
-2rg8,2008-03-04,2007-10-03
-2rgt,2008-08-12,2007-10-05
-8rgp,2024-04-24,2023-12-14
-1rgu,2004-03-02,2003-11-13
-7rgk,2022-05-25,2021-07-15
-5rge,2020-07-22,2020-03-19
-2rgm,2008-02-12,2007-10-04
-1rgr,2004-05-18,2003-11-12
-6rgm,2020-05-13,2019-04-17
-5rgr,2020-04-15,2020-04-07
-2rg6,2008-01-15,2007-10-02
-6rg2,2020-07-01,2019-04-16
-3rg0,2011-06-01,2011-04-07
-7rgy,2022-07-13,2021-07-15
-7rg7,2021-12-22,2021-07-14
-2rgv,2008-10-14,2007-10-05
-6rgk,2019-07-24,2019-04-16
-3rgk,2011-04-27,2011-04-08
-4rgz,2015-08-12,2014-10-01
-7rgz,2022-07-13,2021-07-16
-5rgw,2020-05-27,2020-05-15
-5rgt,2020-05-27,2020-05-15
-2rgj,2008-05-20,2007-10-03
-5rgl,2020-04-15,2020-04-07
-5rgi,2020-04-15,2020-04-07
-7rgo,2022-05-25,2021-07-15
-2rgi,2008-01-29,2007-10-03
-1rgj,2003-11-25,2003-11-12
-7rgn,2021-07-28,2021-07-15
-6rgx,2019-08-21,2019-04-17
-2rg4,2007-10-23,2007-10-02
-4rg5,2015-07-01,2014-09-29
-7rgi,2022-01-12,2021-07-15
-4rgr,2015-03-04,2014-09-30
-4rgb,2014-10-15,2014-09-29
-3rgv,2011-07-20,2011-04-09
-7rgq,2022-01-12,2021-07-15
-6rg6,2020-02-19,2019-04-16
-6rgs,2019-09-04,2019-04-17
-4rgt,2014-10-08,2014-09-30
-2rgq,2007-10-16,2007-10-04
-7rgx,2022-07-13,2021-07-15
-1rgq,2004-10-19,2003-11-12
-2rgb,2007-12-18,2007-10-03
-1rga,1993-10-31,1993-06-07
-1rg2,2004-03-02,2003-11-11
-6rgw,2020-07-01,2019-04-17
-7rga,2022-05-25,2021-07-14
-1rgy,2004-04-06,2003-11-13
-3rge,2012-02-22,2011-04-08
-6rg1,2020-07-01,2019-04-16
-2rgc,2007-12-18,2007-10-03
-2rgn,2008-01-15,2007-10-04
-8rgs,2023-12-27,2023-12-14
-6rgn,2019-09-18,2019-04-17
-7rgg,2022-05-25,2021-07-15
-5rg2,2020-04-15,2020-03-18
-4rgq,2015-07-22,2014-09-30
-1rg7,1997-03-12,1996-11-27
-4rg3,2014-10-15,2014-09-29
-1rgk,1993-01-15,1992-02-19
-3rgd,2012-04-11,2011-04-08
-4rgg,2014-10-15,2014-09-30
-3rgu,2011-12-28,2011-04-09
-2rg0,2008-09-16,2007-10-02
-1rgn,2004-04-27,2003-11-12
-6rgp,2019-05-01,2019-04-17
-3rgw,2011-10-26,2011-04-10
-4rgs,2015-03-04,2014-09-30
-3rg3,2012-02-22,2011-04-07
-8rgr,2024-04-24,2023-12-14
-1rgi,2004-07-27,2003-11-12
-2rg3,2008-07-01,2007-10-02
-3rga,2012-03-07,2011-04-08
-2rgl,2008-02-12,2007-10-04
-6rgi,2019-07-10,2019-04-16
-4rg8,2015-02-25,2014-09-29
-4rg1,2014-10-15,2014-09-29
-8rgy,2023-12-27,2023-12-14
-4rga,2015-05-20,2014-09-29
-1rge,1996-10-14,1995-06-05
-5rgx,2020-05-27,2020-05-15
-3rg9,2011-06-29,2011-04-08
-3rg4,2012-02-22,2011-04-07
-5rga,2020-07-22,2020-03-19
-3rgp,2011-05-11,2011-04-08
-5rgm,2020-04-15,2020-04-07
-3rgt,2012-04-11,2011-04-09
-7rgb,2021-10-06,2021-07-14
-7rgm,2022-01-12,2021-07-15
-5rgs,2020-04-15,2020-04-07
-6rg4,2020-05-13,2019-04-16
-3rgn,2011-10-26,2011-04-08
-4rgc,2014-10-15,2014-09-29
-2rgo,2008-01-15,2007-10-04
-2rgr,2007-12-25,2007-10-04
-7rg8,2022-03-02,2021-07-14
-5rgz,2020-05-27,2020-05-15
-6rg8,2020-02-19,2019-04-16
-5rgv,2020-05-27,2020-05-15
-6rgc,2020-02-19,2019-04-16
-1rgd,1995-02-14,1995-01-06
-8rgt,2024-04-24,2023-12-14
-2rgu,2007-11-06,2007-10-05
-3rg2,2012-03-07,2011-04-07
-3rgm,2011-10-26,2011-04-08
-3rgg,2011-05-18,2011-04-08
-8rgw,2023-12-27,2023-12-14
-1rgs,1996-12-07,1995-06-21
-6rg5,2020-05-13,2019-04-16
-5rg0,2020-03-25,2020-03-15
-6rga,2020-02-19,2019-04-16
-6rgj,2020-07-01,2019-04-16
-5rgp,2020-04-15,2020-04-07
-5rgj,2020-04-15,2020-04-07
-2rgg,2007-12-18,2007-10-03
-8rgq,2024-04-24,2023-12-14
-3rgb,2011-11-23,2011-04-08
-1rg5,2004-04-27,2003-11-11
-1rgo,2004-03-02,2003-11-12
-5rgd,2020-07-22,2020-03-19
-6rgf,2020-05-13,2019-04-16
-3rgq,2011-07-06,2011-04-08
-6mcj,2019-03-27,2018-08-31
-3mcx,2010-05-19,2010-03-29
-5mcs,2017-04-12,2016-11-10
-7mcy,2021-06-23,2021-04-02
-6mcs,2019-04-24,2018-09-02
-4mcb,2013-09-04,2013-08-21
-5mc5,2017-12-20,2016-11-09
-4mcp,2014-06-18,2013-08-21
-5mc4,2017-12-20,2016-11-09
-1mct,1994-01-31,1992-10-24
-1mc5,2003-03-04,2002-08-05
-3mcv,2010-06-02,2010-03-29
-6mcv,2019-10-16,2018-09-02
-7mcs,2022-02-23,2021-04-02
-6mcd,2020-03-04,2018-08-31
-1mcq,1994-01-31,1993-02-25
-3mcq,2010-05-19,2010-03-29
-6mcq,2019-09-04,2018-09-01
-1mcf,1994-01-31,1993-02-25
-5mc2,2017-12-20,2016-11-09
-5mc3,2017-12-20,2016-11-09
-4mcc,2013-09-04,2013-08-21
-5mco,2017-09-27,2016-11-10
-7mck,2021-06-16,2021-04-02
-7mcf,2021-05-26,2021-04-02
-7mc6,2021-05-05,2021-04-01
-3mcy,2010-06-16,2010-03-29
-5mc8,2017-01-11,2016-11-09
-3mcr,2010-05-12,2010-03-29
-4mcz,2013-12-04,2013-08-22
-7mco,2022-04-27,2021-04-02
-7mcp,2021-06-23,2021-04-02
-7mc5,2021-05-05,2021-04-01
-7mcn,2021-06-23,2021-04-02
-7mc1,2021-04-28,2021-04-01
-3mcm,2010-12-22,2010-03-29
-4mcr,2014-06-18,2013-08-21
-7mct,2021-06-23,2021-04-02
-1mc9,2002-09-11,2002-08-06
-5mc0,2017-12-20,2016-11-09
-4mc6,2014-04-02,2013-08-21
-4mcs,2014-06-18,2013-08-21
-7mce,2021-09-29,2021-04-02
-7mcu,2021-06-23,2021-04-02
-1mcc,1994-01-31,1993-02-25
-3mc5,2011-03-09,2010-03-27
-5mcv,2018-06-13,2016-11-10
-1mcv,2003-02-04,2002-08-06
-6mco,2019-02-27,2018-08-31
-4mcq,2014-06-18,2013-08-21
-4mcy,2013-11-27,2013-08-22
-7mcj,2022-04-13,2021-04-02
-5mc1,2017-12-20,2016-11-09
-1mc1,2002-10-23,2002-08-04
-6mc1,2020-08-19,2018-08-30
-3mco,2010-12-22,2010-03-29
-4mcd,2013-09-25,2013-08-21
-3mct,1999-07-22,1999-01-05
-5mct,2018-06-13,2016-11-10
-7mc2,2021-04-28,2021-04-01
-1mci,1994-01-31,1993-02-25
-2mcm,1993-01-15,1991-05-08
-5mcb,2017-09-20,2016-11-09
-4mc5,2013-10-23,2013-08-21
-7mcq,2021-06-23,2021-04-02
-6mcr,2019-04-24,2018-09-02
-1mcy,1995-12-07,1995-07-19
-1mcz,2003-02-25,2002-08-06
-7mcl,2021-06-23,2021-04-02
-1mcd,1994-01-31,1993-02-25
-1mce,1994-01-31,1993-02-25
-1mcs,1994-01-31,1993-02-25
-7mcb,2021-06-23,2021-04-01
-4mcv,2013-11-20,2013-08-21
-4mcm,2014-08-27,2013-08-21
-1mcx,2003-03-04,2002-08-06
-6mcx,2019-01-23,2018-09-02
-4mch,2013-09-04,2013-08-21
-6mcp,2019-09-04,2018-09-01
-1mc3,2002-11-20,2002-08-05
-7mcr,2022-04-06,2021-04-02
-1mch,1994-01-31,1993-02-25
-4mc1,2014-04-02,2013-08-21
-3mc1,2010-04-07,2010-03-26
-1mcj,1994-01-31,1993-02-25
-5mcw,2018-06-13,2016-11-10
-1mcl,1994-01-31,1993-02-25
-6mcw,2019-07-10,2018-09-02
-4mc2,2014-04-02,2013-08-21
-4mcw,2014-02-19,2013-08-21
-1mck,1994-01-31,1993-02-25
-1mcr,1994-01-31,1993-02-25
-2mcp,1985-01-02,1984-10-15
-6mc9,2019-04-10,2018-08-30
-1mcb,1994-01-31,1993-02-25
-1mcn,1994-01-31,1993-02-25
-5mcp,2017-06-14,2016-11-10
-1mc0,2002-10-02,2002-08-04
-2mc0,2014-12-10,2013-08-12
-4mc3,2014-01-29,2013-08-21
-5mc9,2017-02-08,2016-11-09
-7mca,2021-06-02,2021-04-01
-3mcn,2010-12-22,2010-03-29
-6mcu,2019-10-16,2018-09-02
-7mc9,2021-07-07,2021-04-01
-4mc7,2013-10-23,2013-08-21
-4mca,2014-02-12,2013-08-21
-6mc0,2018-09-12,2018-08-30
-6mck,2019-01-23,2018-08-31
-4mc9,2014-04-02,2013-08-21
-5mcu,2018-06-13,2016-11-10
-7mc3,2021-04-21,2021-04-01
-6otx,2020-04-01,2019-05-03
-6ot8,2020-01-29,2019-05-02
-7otx,2021-12-08,2021-06-10
-4oty,2014-02-26,2014-02-14
-7oth,2021-12-08,2021-06-10
-3ot8,2010-11-10,2010-09-10
-8otn,2023-08-16,2023-04-21
-4otr,2014-05-14,2014-02-14
-4otg,2014-08-27,2014-02-13
-2otl,2007-04-03,2007-02-08
-3otu,2011-03-23,2010-09-13
-6otj,2019-05-15,2019-05-03
-8otm,2023-08-16,2023-04-21
-5ot5,2018-02-28,2017-08-21
-7ot3,2021-07-28,2021-06-09
-6otu,2019-05-15,2019-05-03
-8otb,2023-07-12,2023-04-20
-8ot2,2024-05-01,2023-04-20
-4otu,2014-07-23,2014-02-14
-7ot0,2021-07-28,2021-06-09
-1ot7,2004-03-23,2003-03-21
-1ot5,2003-06-17,2003-03-21
-1otn,2004-03-30,2003-03-21
-3oth,2010-12-15,2010-09-11
-3ot3,2010-11-10,2010-09-10
-6otp,2020-05-06,2019-05-03
-5ot2,2017-11-01,2017-08-19
-3otm,2011-10-26,2010-09-13
-6otg,2019-05-29,2019-05-03
-6oto,2020-05-06,2019-05-03
-1ota,2004-05-11,2003-03-21
-7otv,2022-01-12,2021-06-10
-4otq,2014-05-14,2014-02-14
-7otn,2021-12-08,2021-06-10
-5otz,2018-02-28,2017-08-22
-6ot9,2020-01-29,2019-05-02
-1otw,2004-05-11,2003-03-23
-6oti,2020-05-06,2019-05-03
-2otj,2007-04-03,2007-02-08
-5otg,2018-09-05,2017-08-21
-8oto,2023-05-03,2023-04-21
-5otb,2017-11-08,2017-08-21
-5ots,2018-09-05,2017-08-22
-2otv,2007-02-27,2007-02-09
-4otf,2015-01-28,2014-02-13
-6ote,2019-05-15,2019-05-03
-1ot6,2004-05-11,2003-03-21
-4otv,2014-05-14,2014-02-14
-7ote,2022-06-22,2021-06-10
-1otd,2004-05-11,2003-03-21
-5ote,2018-02-21,2017-08-21
-7ot6,2021-12-08,2021-06-09
-8ot5,2023-08-23,2023-04-20
-2ot4,2008-04-08,2007-02-07
-4oti,2014-08-27,2014-02-13
-5oti,2018-02-28,2017-08-22
-6ot0,2019-06-12,2019-05-02
-1ot2,2003-06-03,2003-03-21
-7otc,2022-05-11,2021-06-10
-1ot1,2003-06-03,2003-03-21
-2ot1,2007-02-27,2007-02-07
-3ot1,2010-09-22,2010-09-10
-6ot4,2020-01-29,2019-05-02
-3otq,2010-10-27,2010-09-13
-8otl,2024-01-24,2023-04-21
-6otr,2019-08-21,2019-05-03
-4ott,2014-07-23,2014-02-14
-6otm,2020-05-06,2019-05-03
-1ot3,2003-05-27,2003-03-21
-2otz,2007-08-07,2007-02-09
-2otf,2007-02-20,2007-02-08
-1otb,2004-05-11,2003-03-21
-4ot8,2014-04-23,2014-02-13
-3ots,2011-03-30,2010-09-13
-5otd,2018-02-28,2017-08-21
-4ot5,2014-05-14,2014-02-13
-1ote,2004-05-11,2003-03-21
-3otg,2010-12-15,2010-09-11
-6oty,2020-04-01,2019-05-03
-7ot1,2021-07-28,2021-06-09
-5otl,2018-02-28,2017-08-22
-3oty,2011-03-30,2010-09-14
-7otf,2021-12-08,2021-06-10
-1ot4,2003-07-08,2003-03-21
-7otk,2021-12-08,2021-06-10
-3otb,2010-11-17,2010-09-11
-6ot5,2019-05-22,2019-05-02
-2ot7,2007-03-13,2007-02-07
-4otj,2015-04-08,2014-02-13
-5ota,2017-12-20,2017-08-21
-6ott,2019-11-06,2019-05-03
-1ot8,2003-10-28,2003-03-21
-7otw,2022-01-12,2021-06-10
-2otu,2007-04-24,2007-02-09
-7otg,2021-12-08,2021-06-10
-5otm,2018-09-05,2017-08-22
-2oth,2007-02-27,2007-02-08
-3otj,2011-01-26,2010-09-12
-3oti,2010-12-15,2010-09-11
-5otq,2018-02-28,2017-08-22
-1oto,2004-03-30,2003-03-21
-7otu,2022-04-20,2021-06-10
-7otj,2021-07-07,2021-06-10
-6otd,2020-01-08,2019-05-03
-4ots,2014-05-14,2014-02-14
-3otf,2010-10-13,2010-09-11
-1oth,1999-10-06,1998-10-06
-1oti,2004-05-11,2003-03-21
-7otz,2021-12-08,2021-06-10
-3otx,2011-06-29,2010-09-14
-4oth,2014-08-27,2014-02-13
-7otm,2022-01-12,2021-06-10
-6otk,2020-05-06,2019-05-03
-5otp,2018-09-05,2017-08-22
-2otc,1998-06-17,1997-06-15
-6ot3,2019-06-19,2019-05-02
-4ot7,2015-02-18,2014-02-13
-2oty,2007-08-07,2007-02-09
-8otp,2024-05-01,2023-04-21
-8otz,2023-11-22,2023-04-21
-8otv,2024-05-01,2023-04-21
-5ot7,2018-02-14,2017-08-21
-7oto,2022-01-12,2021-06-10
-6ot7,2020-01-29,2019-05-02
-4otp,2014-07-02,2014-02-14
-5oto,2018-02-28,2017-08-22
-5ot1,2018-04-18,2017-08-18
-6otw,2020-04-01,2019-05-03
-6otf,2019-06-26,2019-05-03
-2otg,2007-05-29,2007-02-08
-8ot7,2024-04-24,2023-04-20
-1ot9,2004-05-11,2003-03-21
-6otz,2019-07-24,2019-05-03
-7oty,2022-01-12,2021-06-10
-5ot6,2018-02-28,2017-08-21
-5ot8,2017-12-20,2017-08-21
-8ot8,2024-02-28,2023-04-20
-5otj,2018-09-05,2017-08-22
-7ot5,2022-01-19,2021-06-09
-4otl,2014-04-23,2014-02-13
-4ot6,2014-05-14,2014-02-13
-5ot3,2018-09-05,2017-08-19
-1oty,2004-02-17,2003-03-23
-7otp,2022-01-12,2021-06-10
-3otk,2011-09-14,2010-09-13
-3oto,2010-09-29,2010-09-13
-5oty,2018-02-28,2017-08-22
-2otm,2007-02-20,2007-02-08
-6otq,2020-05-06,2019-05-03
-7ota,2021-12-08,2021-06-09
-4ot2,2014-06-04,2014-02-13
-7ot4,2022-06-22,2021-06-09
-5ot9,2017-12-20,2017-08-21
-8otr,2023-05-24,2023-04-21
-2ot9,2007-03-13,2007-02-07
-8ot0,2023-05-10,2023-04-20
-7otd,2021-10-13,2021-06-10
-4ote,2014-03-19,2014-02-13
-2otw,2007-04-24,2007-02-09
-5otc,2017-12-20,2017-08-21
-5otr,2018-02-28,2017-08-22
-5otf,2018-02-21,2017-08-21
-6ot1,2019-08-07,2019-05-02
-7ot2,2021-07-28,2021-06-09
-5oth,2018-02-28,2017-08-22
-4otz,2014-03-05,2014-02-14
-3ot9,2010-12-29,2010-09-10
-5otn,2018-09-05,2017-08-22
-2ot0,2007-02-27,2007-02-07
-3otw,2011-09-14,2010-09-14
-3otz,2011-10-26,2010-09-14
-4upv,2014-10-29,2014-06-18
-3upg,2012-11-28,2011-11-18
-5up7,2017-06-21,2017-02-01
-8upp,2024-04-24,2023-10-23
-4up3,2015-07-01,2014-06-11
-4upe,2014-10-29,2014-06-16
-4up4,2015-01-28,2014-06-12
-3upv,2012-01-25,2011-11-18
-1upv,2004-10-20,2003-10-13
-4up9,2014-10-29,2014-06-14
-7upw,2022-08-10,2022-04-18
-3upo,2012-10-24,2011-11-18
-4upd,2014-09-24,2014-06-16
-8upw,2024-03-06,2023-10-23
-8upo,2024-05-29,2023-10-23
-3upn,2012-10-24,2011-11-18
-4upj,1996-10-14,1996-03-04
-3upq,2012-05-23,2011-11-18
-7upd,2023-03-29,2022-04-14
-5upu,2017-02-22,2017-02-04
-3upy,2012-03-28,2011-11-18
-8upn,2024-04-24,2023-10-23
-6up4,2020-04-15,2019-10-16
-1upp,2003-10-14,2003-10-09
-6upr,2020-09-23,2019-10-18
-5upq,2017-02-22,2017-02-03
-1upc,2003-11-20,2003-09-29
-7upj,1997-04-21,1996-12-05
-3upw,2012-07-11,2011-11-18
-7up1,2023-03-08,2022-04-14
-1upw,2004-10-20,2003-10-13
-6upy,2020-06-10,2019-10-18
-3upb,2011-11-30,2011-11-17
-7upg,2022-09-28,2022-04-15
-6upd,2020-08-26,2019-10-17
-4upl,2015-07-01,2014-06-17
-4upa,2014-10-29,2014-06-14
-4upr,2014-08-20,2014-06-17
-4upn,2014-08-20,2014-06-17
-7up3,2023-03-08,2022-04-14
-5upn,2017-06-28,2017-02-03
-4up0,2014-11-05,2014-06-11
-7up7,2022-07-20,2022-04-14
-1upm,2003-10-14,2003-10-08
-5uph,2017-12-13,2017-02-03
-1ups,2004-11-25,2003-10-10
-3up3,2011-12-14,2011-11-17
-7upr,2022-06-15,2022-04-16
-1upt,2003-10-30,2003-10-12
-3upt,2011-12-14,2011-11-18
-1up7,2004-11-18,2003-09-29
-1upb,2003-11-20,2003-09-29
-3up4,2012-02-01,2011-11-17
-7upi,2022-05-04,2022-04-15
-7upn,2023-01-25,2022-04-16
-5up8,2017-06-21,2017-02-01
-3upr,2012-06-13,2011-11-18
-6upg,2020-04-29,2019-10-17
-5ups,2017-02-22,2017-02-03
-4upm,2014-08-20,2014-06-17
-6upf,2020-07-01,2019-10-17
-6upe,2020-08-26,2019-10-17
-1upu,1999-05-11,1998-04-16
-6upc,2020-08-26,2019-10-17
-7up5,2022-07-06,2022-04-14
-3up7,2012-01-25,2011-11-17
-6upj,1997-04-21,1996-12-10
-6upp,2019-12-18,2019-10-18
-4upp,2014-08-20,2014-06-17
-3upi,2012-01-25,2011-11-18
-1upk,2004-01-22,2003-10-07
-5upz,2017-05-10,2017-02-05
-5upv,2017-02-22,2017-02-04
-1up3,2004-11-18,2003-09-26
-8upq,2024-04-24,2023-10-23
-1up6,2004-08-02,2003-09-29
-6up3,2020-10-28,2019-10-16
-3up9,2012-01-25,2011-11-17
-7up8,2022-07-06,2022-04-14
-7upy,2022-08-10,2022-04-18
-7up9,2023-03-29,2022-04-14
-8ups,2024-03-06,2023-10-23
-7upl,2022-08-10,2022-04-15
-6up5,2020-07-01,2019-10-16
-6upa,2020-09-23,2019-10-17
-6upw,2020-09-30,2019-10-18
-4upi,2015-07-01,2014-06-17
-8upv,2024-03-06,2023-10-23
-5upo,2017-06-28,2017-02-03
-1upa,2003-11-20,2003-09-29
-4upo,2014-08-20,2014-06-17
-6upv,2020-09-30,2019-10-18
-8up3,2024-04-03,2023-10-20
-5upg,2017-03-29,2017-02-02
-3upf,2012-05-02,2011-11-18
-7upx,2022-08-10,2022-04-18
-1up5,2005-03-24,2003-09-27
-3upu,2012-06-20,2011-11-18
-5upm,2017-06-28,2017-02-03
-5up9,2017-09-27,2017-02-01
-1upr,2004-10-20,2003-10-10
-8upf,2024-01-17,2023-10-22
-5upy,2017-04-05,2017-02-04
-4ups,2014-08-20,2014-06-17
-4up5,2014-11-05,2014-06-12
-8up8,2024-04-03,2023-10-21
-5upj,1997-04-21,1996-12-10
-6upx,2020-06-10,2019-10-18
-1up2,2004-11-18,2003-09-26
-3up5,2012-02-01,2011-11-17
-7up2,2023-03-08,2022-04-14
-1up8,2003-09-30,2003-09-29
-7upb,2023-03-29,2022-04-14
-1upd,2004-09-30,2003-09-29
-4upq,2014-08-20,2014-06-17
-3uph,2012-01-25,2011-11-18
-5upk,2017-12-27,2017-02-03
-3up1,2012-02-08,2011-11-17
-6upq,2020-09-23,2019-10-18
-3upm,2012-08-01,2011-11-18
-5up3,2017-06-07,2017-02-01
-3upx,2012-03-14,2011-11-18
-1upf,1999-06-22,1998-06-17
-4uph,2015-07-01,2014-06-17
-2upj,1996-10-14,1996-03-04
-4upt,2014-08-20,2014-06-17
-6upi,2020-04-29,2019-10-17
-8upr,2024-05-29,2023-10-23
-5up0,2017-04-26,2017-02-01
-1upj,1996-10-14,1996-03-04
-3upe,2012-11-21,2011-11-18
-1up0,2004-11-18,2003-09-26
-6upt,2019-11-20,2019-10-18
-3up0,2011-12-14,2011-11-17
-7up4,2022-07-06,2022-04-14
-8upi,2023-11-08,2023-10-22
-4up7,2014-10-29,2014-06-14
-1up9,2004-09-30,2003-09-29
-5upt,2017-02-22,2017-02-03
-7upa,2023-03-29,2022-04-14
-3upz,2012-03-14,2011-11-18
-3upp,2012-10-24,2011-11-18
-3upj,1996-10-14,1996-03-04
-3up2,2012-01-25,2011-11-17
-3upk,2012-03-07,2011-11-18
-6upz,2020-06-10,2019-10-18
-3upl,2012-03-28,2011-11-18
-6up7,2020-02-26,2019-10-16
-5upx,2017-04-05,2017-02-04
-4upu,2014-08-20,2014-06-18
-8up6,2024-04-03,2023-10-21
-7upt,2022-06-15,2022-04-16
-5upf,2017-06-28,2017-02-02
-5upi,2017-06-28,2017-02-03
-5upe,2017-06-28,2017-02-02
-5up2,2017-03-22,2017-02-01
-7up6,2022-08-31,2022-04-14
-6ha5,2018-08-22,2018-08-07
-3ham,2009-07-28,2009-05-02
-3hav,2009-11-17,2009-05-02
-1haw,2001-08-02,2001-04-09
-4ha6,2013-06-05,2012-09-25
-8haf,2022-12-21,2022-10-26
-2hai,2006-09-05,2006-06-12
-4hap,2013-06-12,2012-09-27
-4hat,2013-01-09,2012-09-27
-2has,2006-08-29,2006-06-13
-6ha1,2018-08-29,2018-08-07
-3had,2000-01-12,1998-12-03
-2ham,2006-08-29,2006-06-13
-3haw,2011-04-27,2009-05-02
-1haj,2001-05-25,2001-04-05
-6hak,2019-04-03,2018-08-07
-1haz,2001-08-02,2001-04-10
-6haz,2019-06-12,2018-08-09
-5ha1,2016-03-02,2015-12-29
-3hah,2009-06-16,2009-05-01
-4ha5,2012-10-17,2012-09-25
-4hal,2013-10-30,2012-09-26
-3hao,2009-09-22,2009-05-02
-3har,2009-09-22,2009-05-02
-4han,2013-03-20,2012-09-27
-6hax,2019-06-12,2018-08-09
-5hao,2017-01-04,2015-12-30
-6ha4,2019-02-13,2018-08-07
-1hag,1994-12-20,1994-06-27
-2ha2,2006-07-18,2006-06-12
-2hah,2007-02-13,2006-06-12
-1hao,1996-04-03,1995-10-03
-3hac,2009-07-21,2009-05-01
-1hah,1994-12-20,1994-06-27
-8haq,2023-11-01,2022-10-26
-1hak,1999-02-16,1997-12-10
-6har,2019-02-06,2018-08-08
-6ha3,2019-08-21,2018-08-07
-1hai,1994-12-20,1994-06-27
-5hab,2017-01-04,2015-12-30
-4haj,2012-10-31,2012-09-26
-6hao,2019-08-21,2018-08-08
-6had,2019-08-21,2018-08-07
-6hac,2019-08-28,2018-08-07
-5haq,2016-09-07,2015-12-30
-2hap,1999-11-10,1998-09-17
-4haw,2013-01-09,2012-09-27
-1hac,1997-11-12,1996-03-13
-5han,2017-01-04,2015-12-30
-2ha8,2006-07-11,2006-06-12
-8has,2024-05-01,2022-10-26
-6ham,2019-08-28,2018-08-08
-4hab,2013-04-03,2012-09-26
-3ha6,2009-08-04,2009-05-01
-2hay,2006-07-04,2006-06-13
-6ha6,2019-08-28,2018-08-07
-4hau,2013-01-09,2012-09-27
-6hap,2019-08-28,2018-08-08
-1ha7,2002-03-28,2001-03-29
-6hal,2018-10-17,2018-08-07
-5hat,2017-01-04,2015-12-30
-2ha7,2006-07-18,2006-06-12
-6hae,2019-08-28,2018-08-07
-8haw,2023-01-25,2022-10-26
-6ha8,2018-08-29,2018-08-07
-6ha9,2018-10-03,2018-08-07
-3ha7,2009-05-12,2009-05-01
-4hax,2013-01-09,2012-09-27
-5hae,2016-05-11,2015-12-30
-5hau,2016-04-06,2015-12-30
-2hal,2006-08-08,2006-06-13
-8hap,2023-06-07,2022-10-26
-6hau,2018-11-21,2018-08-08
-5hav,2016-01-13,2015-12-31
-3hai,2009-06-16,2009-05-01
-3has,2009-09-22,2009-05-02
-8ha1,2023-07-26,2022-10-26
-5ha5,2016-02-10,2015-12-30
-2ha4,2006-07-18,2006-06-12
-1ha5,2002-04-03,2001-03-28
-6haq,2018-08-22,2018-08-08
-3ha5,2009-05-12,2009-05-01
-4ha0,2012-11-07,2012-09-25
-1han,1995-11-14,1995-08-30
-4hac,2012-12-12,2012-09-26
-4ha1,2013-09-25,2012-09-25
-4ha4,2012-10-10,2012-09-25
-3ha0,2009-09-08,2009-04-30
-3haf,2010-01-12,2009-05-01
-3hap,2009-09-22,2009-05-02
-6hav,2019-08-28,2018-08-08
-1ha0,1998-10-12,1998-10-08
-4hai,2012-12-26,2012-09-26
-2ha3,2006-07-18,2006-06-12
-5haz,2016-04-20,2015-12-31
-4hay,2013-01-09,2012-09-27
-1hau,2001-08-02,2001-04-09
-3ha3,2009-05-12,2009-05-01
-3hax,2009-06-23,2009-05-03
-4haq,2013-06-12,2012-09-27
-4had,2012-10-10,2012-09-26
-6hay,2019-06-12,2018-08-09
-2haz,2006-10-03,2006-06-13
-5ha7,2016-09-28,2015-12-30
-3han,2009-09-22,2009-05-02
-3ha8,2009-08-04,2009-05-01
-4haf,2013-06-12,2012-09-26
-2har,2006-08-29,2006-06-13
-4ha9,2013-09-04,2012-09-25
-4ha2,2014-07-02,2012-09-25
-4ha3,2012-10-10,2012-09-25
-4hav,2013-01-09,2012-09-27
-3haj,2009-06-16,2009-05-01
-6haw,2019-01-16,2018-08-08
-4ha8,2013-10-30,2012-09-25
-8hau,2024-06-05,2022-10-26
-2ha6,2006-07-18,2006-06-12
-3haz,2010-02-23,2009-05-03
-1hay,2001-08-02,2001-04-10
-8hay,2023-07-26,2022-10-27
-4haz,2013-01-09,2012-09-27
-8har,2023-11-01,2022-10-26
-4hag,2013-06-12,2012-09-26
-8ha0,2022-12-21,2022-10-26
-8hac,2024-05-15,2022-10-26
-3hae,2009-05-19,2009-05-01
-5haw,2016-04-13,2015-12-31
-2haw,2006-11-14,2006-06-13
-6haf,2019-08-21,2018-08-07
-1hab,1997-11-12,1996-03-13
-6hat,2018-11-21,2018-08-08
-2ha5,2006-07-18,2006-06-12
-3hau,2011-04-27,2009-05-02
-2hax,2007-04-24,2006-06-13
-5ha9,2016-03-09,2015-12-30
-1hap,1996-04-03,1995-10-03
-3haq,2009-09-22,2009-05-02
-5haa,2017-01-04,2015-12-30
-6haa,2018-10-03,2018-08-07
-5hap,2016-09-07,2015-12-30
-1ha3,2001-05-15,2001-03-26
-6hai,2018-11-21,2018-08-07
-3hab,2009-07-21,2009-05-01
-5haf,2016-07-27,2015-12-30
-4hak,2013-10-30,2012-09-26
-3hay,2009-06-23,2009-05-03
-1hax,2001-08-02,2001-04-10
-2hae,2006-07-04,2006-06-12
-2ha0,2006-07-18,2006-06-12
-8ha2,2023-07-26,2022-10-26
-5hay,2016-04-20,2015-12-31
-1ha2,2001-06-20,2001-03-23
-1haa,2001-05-25,2001-04-05
-6ha0,2019-06-12,2018-08-06
-6has,2020-01-15,2018-08-08
-2han,2007-05-22,2006-06-13
-3hat,1995-02-27,1994-10-16
-3qn0,2011-12-07,2011-02-07
-3qn8,2012-02-08,2011-02-08
-3qnt,2011-05-11,2011-02-09
-1qns,2000-10-19,1999-10-20
-4qn6,2014-07-30,2014-06-17
-4qn9,2015-06-17,2014-06-17
-8qnz,2023-11-08,2023-09-27
-6qnr,2019-06-19,2019-02-11
-7qnx,2022-01-19,2021-12-23
-4qnw,2014-10-22,2014-06-18
-4qnv,2014-09-17,2014-06-18
-7qnj,2022-10-19,2021-12-20
-3qnr,2011-04-27,2011-02-09
-7qnw,2022-01-19,2021-12-23
-1qnv,2000-10-19,1999-10-21
-7qny,2022-01-19,2021-12-23
-3qnf,2011-02-23,2011-02-08
-7qno,2022-02-09,2021-12-21
-6qnx,2020-01-22,2019-02-12
-1qnj,2000-03-31,1999-10-15
-7qnb,2022-04-13,2021-12-20
-7qnu,2023-04-05,2021-12-22
-7qn4,2022-08-17,2021-12-20
-2qnv,2008-07-29,2007-07-19
-2qnk,2007-08-14,2007-07-18
-4qnh,2014-08-06,2014-06-17
-6qns,2020-02-26,2019-02-12
-7qnz,2023-01-11,2021-12-23
-6qnq,2019-06-19,2019-02-11
-3qn1,2011-03-16,2011-02-07
-4qny,2014-07-09,2014-06-18
-7qn8,2022-04-13,2021-12-20
-6qng,2020-03-04,2019-02-11
-1qny,2000-04-30,1999-10-26
-6qnl,2020-03-04,2019-02-11
-1qnf,1998-01-14,1997-07-04
-3qn9,2011-12-07,2011-02-08
-4qnz,2014-09-24,2014-06-19
-6qn5,2020-02-26,2019-02-09
-2qn6,2007-11-06,2007-07-18
-3qnv,2012-02-15,2011-02-09
-4qnr,2014-08-06,2014-06-18
-6qn2,2020-02-26,2019-02-08
-8qn5,2023-11-15,2023-09-25
-6qn0,2020-02-26,2019-02-08
-6qne,2020-03-04,2019-02-11
-3qnn,2012-02-08,2011-02-08
-3qnl,2012-02-29,2011-02-08
-8qn0,2024-02-14,2023-09-25
-1qnx,2000-10-26,1999-10-25
-4qnu,2014-09-17,2014-06-18
-7qnv,2023-01-18,2021-12-22
-7qng,2022-09-28,2021-12-20
-7qnc,2022-04-13,2021-12-20
-4qnp,2015-02-11,2014-06-18
-3qnu,2011-03-02,2011-02-09
-2qnq,2008-04-15,2007-07-19
-2qny,2008-05-06,2007-07-19
-1qng,2000-10-13,1999-10-14
-7qn0,2022-08-17,2021-12-20
-6qnd,2019-10-02,2019-02-11
-2qnp,2008-04-15,2007-07-19
-7qnh,2022-12-28,2021-12-20
-3qnm,2011-03-30,2011-02-08
-7qn5,2022-04-13,2021-12-20
-2qn9,2008-07-22,2007-07-18
-1qnl,1999-12-23,1999-10-19
-4qna,2015-07-01,2014-06-17
-1qnp,2000-10-19,1999-10-20
-1qni,2000-10-13,1999-10-15
-2qn0,2007-09-11,2007-07-17
-3qns,2011-04-27,2011-02-09
-7qnq,2022-03-09,2021-12-22
-4qn2,2014-07-02,2014-06-17
-2qnw,2007-07-31,2007-07-19
-3qnj,2011-03-23,2011-02-08
-2qn3,2008-07-22,2007-07-17
-6qnc,2019-10-02,2019-02-10
-1qnn,2000-06-21,1999-10-20
-4qn3,2014-07-30,2014-06-17
-2qng,2007-07-31,2007-07-18
-8qnc,2024-05-01,2023-09-26
-3qnz,2012-02-15,2011-02-09
-7qns,2023-01-18,2021-12-22
-1qn1,2000-10-12,1999-10-11
-1qnq,2000-10-19,1999-10-20
-7qn3,2022-08-17,2021-12-20
-4qnj,2015-06-24,2014-06-18
-2qnx,2008-05-06,2007-07-19
-7qn2,2022-08-17,2021-12-20
-8qnr,2024-05-01,2023-09-27
-2qnc,2008-01-29,2007-07-18
-3qn7,2012-02-15,2011-02-08
-7qnr,2023-04-05,2021-12-22
-6qni,2019-10-02,2019-02-11
-7qnd,2022-04-13,2021-12-20
-8qnh,2023-11-22,2023-09-26
-7qna,2022-04-13,2021-12-20
-8qnd,2023-12-20,2023-09-26
-4qn4,2014-07-30,2014-06-17
-2qnb,2008-07-22,2007-07-18
-1qnw,1999-11-23,1999-10-22
-6qn4,2019-08-28,2019-02-08
-2qn7,2008-07-22,2007-07-18
-3qng,2012-01-18,2011-02-08
-3qno,2012-03-14,2011-02-08
-1qnh,2000-10-13,1999-10-14
-2qn2,2008-06-03,2007-07-17
-4qn5,2014-07-30,2014-06-17
-2qnd,2007-11-06,2007-07-18
-4qn1,2014-08-13,2014-06-17
-8qnb,2024-05-01,2023-09-26
-7qn7,2022-04-13,2021-12-20
-4qn0,2015-06-17,2014-06-17
-4qnk,2015-06-24,2014-06-18
-3qna,2011-12-07,2011-02-08
-3qn3,2011-02-23,2011-02-07
-2qnn,2008-04-15,2007-07-19
-4qnn,2015-06-24,2014-06-18
-2qnz,2008-05-06,2007-07-19
-3qnq,2011-04-06,2011-02-08
-1qn2,2000-10-13,1999-10-13
-6qnb,2019-10-02,2019-02-10
-4qne,2014-08-06,2014-06-17
-7qn9,2022-04-13,2021-12-20
-2qno,2008-01-15,2007-07-19
-4qnq,2015-10-28,2014-06-18
-1qno,2000-10-22,1999-10-20
-1qnm,1998-01-07,1997-07-03
-1qn0,2000-10-12,1999-10-11
-7qnf,2022-10-19,2021-12-20
-4qnl,2015-06-24,2014-06-18
-3qnd,2011-06-15,2011-02-08
-7qn6,2022-04-13,2021-12-20
-7qn1,2022-08-17,2021-12-20
-8qn3,2024-01-17,2023-09-25
-2qn8,2008-07-22,2007-07-18
-6qnj,2019-10-02,2019-02-11
-7qnn,2022-12-28,2021-12-21
-3qni,2011-08-10,2011-02-08
-8qng,2023-11-22,2023-09-26
-1qnr,2000-10-19,1999-10-20
-7qnk,2022-07-13,2021-12-21
-6qno,2019-07-10,2019-02-11
-2qnr,2007-07-31,2007-07-19
-4qnb,2014-12-31,2014-06-17
-4qn7,2014-07-30,2014-06-17
-8qni,2023-11-22,2023-09-26
-6qnh,2019-10-02,2019-02-11
-2qnf,2008-01-29,2007-07-18
-6qn6,2020-02-26,2019-02-09
-8qns,2024-05-08,2023-09-27
-3qnw,2011-09-21,2011-02-09
-7qne,2022-04-13,2021-12-20
-1qnu,2000-04-11,1999-10-21
-2qn1,2008-06-03,2007-07-17
-3kji,2010-01-19,2009-11-03
-5kjq,2017-06-21,2016-06-20
-3kjh,2010-01-19,2009-11-03
-6kjf,2019-12-25,2019-07-22
-5kj4,2016-11-23,2016-06-17
-1kjo,2002-12-05,2001-12-05
-1kjf,2002-03-06,2001-12-04
-7kjq,2021-12-01,2020-10-26
-6kji,2019-09-18,2019-07-22
-7kjj,2021-05-19,2020-10-26
-7kjw,2021-03-17,2020-10-26
-7kj4,2020-11-11,2020-10-25
-5kjk,2016-12-07,2016-06-20
-1kjy,2002-05-08,2001-12-05
-3kjf,2010-08-11,2009-11-03
-1kjq,2002-06-28,2001-12-05
-1kjp,2002-12-05,2001-12-05
-4kjd,2013-10-16,2013-05-03
-4kjx,2013-05-22,2013-05-04
-1kji,2002-06-28,2001-12-04
-5kji,2017-04-19,2016-06-20
-7kjd,2020-12-16,2020-10-26
-6kj8,2020-03-11,2019-07-22
-5kjy,2017-06-28,2016-06-20
-5kj6,2016-07-06,2016-06-17
-7kj9,2020-12-16,2020-10-26
-5kjh,2017-04-19,2016-06-20
-3kjr,2009-11-17,2009-11-03
-6kja,2020-03-11,2019-07-22
-6kjd,2019-12-25,2019-07-22
-3kjs,2010-06-09,2009-11-03
-7kje,2020-12-16,2020-10-26
-6kjr,2020-07-29,2019-07-23
-7kjz,2021-04-07,2020-10-26
-7kjf,2020-12-16,2020-10-26
-6kj5,2020-03-25,2019-07-21
-7kjy,2021-03-31,2020-10-26
-5kje,2016-07-06,2016-06-18
-2kje,2009-09-15,2009-05-27
-4kjm,2013-05-29,2013-05-03
-7kj3,2020-11-11,2020-10-25
-6kje,2019-12-25,2019-07-22
-4kjl,2013-08-21,2013-05-03
-4kjg,2013-10-16,2013-05-03
-6kjq,2020-07-29,2019-07-23
-7kjm,2021-11-17,2020-10-26
-6kjb,2020-06-03,2019-07-22
-7kjv,2021-03-17,2020-10-26
-1kjr,2005-04-12,2001-12-05
-7kjx,2021-03-17,2020-10-26
-1kjl,2005-04-12,2001-12-04
-5kjd,2016-08-03,2016-06-18
-5kjl,2016-12-07,2016-06-20
-5kjr,2016-07-20,2016-06-20
-5kj1,2016-07-06,2016-06-17
-1kj8,2002-06-28,2001-12-04
-6kjv,2019-11-13,2019-07-23
-5kj8,2016-10-19,2016-06-17
-4kjz,2013-09-11,2013-05-04
-5kjw,2016-11-02,2016-06-20
-3kj7,2010-02-16,2009-11-03
-3kj4,2010-09-22,2009-11-02
-7kjn,2021-11-17,2020-10-26
-5kj0,2017-08-09,2016-06-17
-7kjs,2021-06-23,2020-10-26
-3kjq,2010-08-11,2009-11-03
-5kj9,2016-07-06,2016-06-18
-5kjz,2017-06-28,2016-06-20
-7kjc,2021-02-03,2020-10-26
-5kjf,2016-07-27,2016-06-18
-6kjl,2019-09-04,2019-07-22
-6kjj,2020-07-29,2019-07-22
-1kjt,2002-04-24,2001-12-05
-4kjy,2013-06-12,2013-05-04
-4kjt,2014-03-26,2013-05-03
-4kjq,2013-08-21,2013-05-03
-6kjm,2020-07-22,2019-07-22
-7kjg,2020-12-16,2020-10-26
-5kj2,2017-09-27,2016-06-17
-1kjz,2002-04-10,2001-12-06
-3kjd,2009-11-17,2009-11-03
-3kj2,2010-02-16,2009-11-02
-1kj9,2002-06-28,2001-12-04
-7kjh,2021-02-03,2020-10-26
-5kja,2016-08-03,2016-06-18
-5kj7,2016-10-19,2016-06-17
-4kju,2013-11-27,2013-05-03
-1kj3,2002-03-27,2001-12-04
-3kjg,2010-01-19,2009-11-03
-1kj4,2002-03-06,2001-12-04
-5kj5,2016-11-09,2016-06-17
-7kja,2021-02-03,2020-10-26
-5kjc,2016-06-29,2016-06-18
-7kj2,2020-11-11,2020-10-25
-5kjx,2017-06-28,2016-06-20
-1kjm,2002-12-18,2001-12-04
-7kjb,2021-02-03,2020-10-26
-5kjn,2016-12-07,2016-06-20
-3kj1,2010-02-16,2009-11-02
-1kj2,2002-03-27,2001-12-04
-1kjg,2002-03-06,2001-12-04
-5kjm,2016-12-07,2016-06-20
-1kj7,2002-03-06,2001-12-04
-1kjj,2002-06-28,2001-12-04
-6kj6,2020-01-01,2019-07-21
-6kju,2019-11-13,2019-07-23
-5kjt,2016-11-02,2016-06-20
-3kjv,2010-03-23,2009-11-03
-3kjm,2010-05-26,2009-11-03
-4kjj,2013-08-21,2013-05-03
-1kjx,2002-03-20,2001-12-05
-7kj8,2020-12-16,2020-10-26
-7kjl,2021-12-01,2020-10-26
-4kjk,2013-08-21,2013-05-03
-1kjv,2002-12-18,2001-12-05
-6kjp,2020-07-29,2019-07-23
-5kjb,2016-08-03,2016-06-18
-7kj5,2020-11-11,2020-10-25
-6kj0,2020-02-26,2019-07-20
-4kjo,2013-05-15,2013-05-03
-4kjv,2013-11-27,2013-05-03
-4kjn,2013-05-15,2013-05-03
-1kj1,2002-02-22,2001-12-04
-3kjn,2010-08-11,2009-11-03
-5kju,2016-11-02,2016-06-20
-6kjz,2020-03-18,2019-07-23
-11bg,1999-11-05,1999-03-11
-11ba,1999-03-26,1999-03-17
-5ibz,2017-08-09,2016-02-22
-1ibz,2001-06-06,2001-03-29
-6ibs,2019-04-24,2018-11-30
-3ibi,2009-09-22,2009-07-16
-4ibr,2013-04-03,2012-12-09
-4ibg,2014-03-19,2012-12-08
-4ibz,2013-08-14,2012-12-09
-4ib5,2013-03-20,2012-12-08
-5ibi,2016-04-06,2016-02-22
-4ib8,2013-06-26,2012-12-08
-1ibl,2001-05-04,2001-03-28
-6ib2,2019-02-27,2018-11-28
-2ibi,2006-10-24,2006-09-11
-2ibj,2007-02-27,2006-09-11
-2iby,2007-04-03,2006-09-12
-6ibt,2019-10-09,2018-11-30
-5ibe,2016-04-06,2016-02-22
-1ibj,2001-04-04,2001-03-28
-8ibw,2023-09-20,2023-02-10
-3ib7,2009-09-29,2009-07-15
-6ibn,2019-07-31,2018-11-30
-3ibd,2010-01-19,2009-07-15
-4ib1,2013-12-11,2012-12-07
-6ibf,2019-12-18,2018-11-29
-6ibk,2019-10-09,2018-11-30
-1ibh,2001-05-09,2001-03-28
-4ib3,2013-12-11,2012-12-07
-4ibw,2013-08-14,2012-12-09
-4iba,2013-06-26,2012-12-08
-5ib4,2017-02-01,2016-02-22
-2ibx,2006-11-28,2006-09-12
-2ibk,2007-09-11,2006-09-11
-3ibn,2009-09-22,2009-07-16
-4ibx,2013-04-03,2012-12-09
-3iba,2010-02-09,2009-07-15
-4ib7,2013-06-26,2012-12-08
-1ibk,2001-05-04,2001-03-28
-8ibu,2023-04-12,2023-02-10
-5ib9,2017-02-22,2016-02-22
-4ibp,2012-12-26,2012-12-09
-3ibr,2009-09-22,2009-07-16
-4ib2,2013-01-16,2012-12-07
-3ibj,2009-10-27,2009-07-16
-3ibu,2009-09-22,2009-07-17
-3ibh,2009-10-13,2009-07-15
-6ibj,2019-11-13,2018-11-30
-5ibb,2016-05-25,2016-02-22
-6ibx,2019-01-23,2018-12-01
-6ibz,2019-01-23,2018-12-01
-4ib9,2013-06-26,2012-12-08
-2ibz,2007-03-20,2006-09-12
-3ibs,2009-08-25,2009-07-16
-5ib7,2016-05-25,2016-02-22
-8ibn,2023-08-02,2023-02-10
-6ibw,2019-02-27,2018-12-01
-4ibd,2014-03-19,2012-12-08
-1ib4,2001-09-19,2001-03-27
-4ibj,2014-03-19,2012-12-08
-5ibr,2016-10-26,2016-02-22
-8ibz,2023-09-20,2023-02-10
-5ibq,2016-04-20,2016-02-22
-1ib6,2001-09-19,2001-03-27
-3ibo,2009-12-08,2009-07-16
-5ibf,2016-04-06,2016-02-22
-8ibo,2023-09-20,2023-02-10
-8ibq,2023-10-04,2023-02-10
-1ib5,2001-05-09,2001-03-27
-4ibi,2014-03-19,2012-12-08
-3ibg,2009-08-25,2009-07-15
-2ibu,2007-04-03,2006-09-12
-2ibm,2006-11-14,2006-09-11
-5ib8,2016-05-25,2016-02-22
-8ibp,2023-09-20,2023-02-10
-4iby,2013-08-14,2012-12-09
-1ibb,2001-05-09,2001-03-28
-6ibo,2019-07-24,2018-11-30
-6ibh,2019-11-13,2018-11-30
-8ibl,2023-03-15,2023-02-10
-6iby,2019-01-23,2018-12-01
-1ibe,1996-12-23,1996-09-25
-1ibf,2001-05-09,2001-03-28
-8iby,2023-09-20,2023-02-10
-5ib3,2017-02-01,2016-02-22
-4ibe,2014-03-19,2012-12-08
-1ibc,1998-02-11,1997-02-12
-8ibi,2023-04-19,2023-02-10
-6ibr,2019-10-09,2018-11-30
-8ibx,2023-09-20,2023-02-10
-6ibi,2019-11-13,2018-11-30
-4ibf,2014-03-19,2012-12-08
-2ib9,2007-04-03,2006-09-11
-2ibt,2007-05-29,2006-09-12
-1ibi,2001-09-05,2001-03-28
-1ib1,2001-05-02,2001-03-26
-2ibd,2006-10-10,2006-09-11
-1ibm,2001-05-04,2001-03-28
-3ibl,2009-09-22,2009-07-16
-1ib0,2001-12-12,2001-03-26
-1ibw,2002-03-13,2001-03-29
-1iby,2001-06-06,2001-03-29
-3ib1,2009-08-11,2009-07-15
-3ibc,2009-09-01,2009-07-15
-5ib5,2017-02-01,2016-02-22
-5iby,2017-03-15,2016-02-22
-8ibk,2023-05-03,2023-02-10
-5ib2,2017-02-01,2016-02-22
-8ib2,2023-04-26,2023-02-09
-2ibp,2007-05-15,2006-09-11
-5ib0,2017-03-15,2016-02-22
-8ibs,2023-06-07,2023-02-10
-4ib4,2013-03-13,2012-12-07
-3ibz,2009-08-18,2009-07-17
-5ibw,2016-08-03,2016-02-22
-4ibk,2014-03-19,2012-12-08
-4ibb,2014-02-26,2012-12-08
-1ibg,1995-05-08,1994-10-25
-4ibu,2013-08-14,2012-12-09
-4ibt,2013-08-14,2012-12-09
-4ib0,2013-12-11,2012-12-07
-3ibv,2009-08-25,2009-07-17
-5ibg,2016-04-06,2016-02-22
-1ibs,2002-02-06,2001-03-29
-6ib7,2019-04-17,2018-11-29
-3ibq,2009-07-28,2009-07-16
-4ibq,2013-08-14,2012-12-09
-6ibb,2019-08-14,2018-11-29
-6ibl,2019-01-09,2018-11-30
-5ibx,2016-03-09,2016-02-22
-2ibn,2006-10-17,2006-09-11
-6ibv,2019-05-15,2018-11-30
-5ibh,2016-04-06,2016-02-22
-1ib7,2001-04-04,2001-03-27
-5ibc,2016-10-26,2016-02-22
-6ib0,2019-02-27,2018-11-28
-5ibd,2016-04-06,2016-02-22
-8ibm,2023-03-15,2023-02-10
-2ibs,2007-05-29,2006-09-12
-4ibm,2013-08-21,2012-12-08
-6ib8,2019-04-17,2018-11-29
-4ibs,2013-08-14,2012-12-09
-5ibj,2016-04-06,2016-02-22
-5ibl,2016-11-09,2016-02-22
-3ibm,2009-07-28,2009-07-16
-3ib0,2009-08-11,2009-07-15
-1ibq,2001-07-04,2001-03-28
-1ibd,2001-05-09,2001-03-28
-2ib8,2007-04-03,2006-09-11
-5ibp,2016-10-26,2016-02-22
-6ibm,2019-10-09,2018-11-30
-3ib9,2010-06-02,2009-07-15
-3ib8,2009-09-29,2009-07-15
-4ibv,2013-08-14,2012-12-09
-2ibw,2007-04-03,2006-09-12
-3ib2,2009-07-28,2009-07-15
-3ib5,2009-08-04,2009-07-15
-5ib1,2017-02-01,2016-02-22
-4ibc,2014-03-19,2012-12-08
-1ibv,2002-03-13,2001-03-29
-1ibr,1999-06-03,1999-05-14
-3ib3,2009-08-11,2009-07-15
-2iba,2007-02-06,2006-09-11
-4ibo,2012-12-26,2012-12-09
-3ibe,2009-09-01,2009-07-15
-8ibt,2023-06-07,2023-02-10
-4ibl,2014-04-16,2012-12-08
-6prm,2019-09-25,2019-07-10
-5prj,2017-03-29,2017-02-07
-6pra,2020-06-17,2019-07-10
-5pri,2017-03-29,2017-02-07
-3pr3,2011-02-09,2010-11-29
-7prl,2022-10-26,2021-09-22
-5prk,2017-03-29,2017-02-07
-7prb,2022-08-03,2021-09-21
-1pr9,2004-02-24,2003-06-20
-1pr0,2003-11-25,2003-06-19
-2prs,2007-06-05,2007-05-04
-7prt,2022-08-03,2021-09-22
-4pr3,2014-04-30,2014-03-05
-7pr9,2022-08-03,2021-09-21
-5prc,1999-04-06,1997-08-01
-5pr7,2017-03-29,2017-02-07
-6prd,2020-06-17,2019-07-10
-4pry,2015-01-21,2014-03-06
-1prw,2003-10-10,2003-06-20
-8prx,2023-08-23,2023-07-12
-2prt,2008-03-04,2007-05-04
-4prq,2014-09-10,2014-03-06
-3pri,2011-02-02,2010-11-29
-6prg,2019-10-02,2019-07-10
-7pr5,2022-03-02,2021-09-20
-1prr,1994-08-31,1994-03-25
-5prs,2017-03-29,2017-02-07
-6pr1,2020-02-26,2019-07-10
-7prg,2022-01-12,2021-09-21
-2prh,2008-05-20,2007-05-04
-4prw,2015-03-11,2014-03-06
-5pr8,2017-03-29,2017-02-07
-4pr7,2014-06-11,2014-03-05
-7pr8,2022-08-03,2021-09-21
-5pro,2017-03-29,2017-02-07
-7pru,2022-08-10,2021-09-22
-6pr3,2020-02-26,2019-07-10
-4prf,2014-10-29,2014-03-05
-6prc,1999-04-06,1997-07-31
-6pr8,2020-06-17,2019-07-10
-3prx,2011-01-19,2010-11-30
-7pr6,2022-08-03,2021-09-20
-5prv,2017-03-29,2017-02-07
-1pro,1996-08-17,1995-07-18
-3pr0,2011-11-16,2010-11-29
-6prb,2020-06-17,2019-07-10
-7pry,2021-12-15,2021-09-22
-3prf,2011-02-02,2010-11-29
-5pr0,2017-03-29,2017-02-07
-2prm,2008-05-20,2007-05-04
-5prf,2017-03-29,2017-02-07
-8prw,2023-11-22,2023-07-12
-4prt,2015-04-08,2014-03-06
-4prl,2014-06-18,2014-03-06
-1pr5,2003-11-25,2003-06-19
-7prr,2022-05-11,2021-09-22
-1pr4,2003-11-25,2003-06-19
-5prx,2017-03-29,2017-02-07
-5prr,2017-03-29,2017-02-07
-4prx,2014-09-24,2014-03-06
-6prx,2020-01-22,2019-07-11
-2prn,1999-01-13,1998-06-12
-2prq,2007-06-12,2007-05-04
-7prc,1999-04-06,1997-08-01
-5prm,2017-03-29,2017-02-07
-7prj,2022-10-05,2021-09-21
-5pre,2017-03-29,2017-02-07
-4pr4,2015-04-08,2014-03-05
-5pr2,2017-03-29,2017-02-07
-5pru,2017-03-29,2017-02-07
-3prn,1998-08-12,1998-06-12
-5pr4,2017-03-29,2017-02-07
-7pr1,2022-08-10,2021-09-20
-5prd,2017-03-29,2017-02-07
-2prj,1998-12-16,1998-12-11
-4pr8,2014-12-24,2014-03-05
-2pr7,2007-05-15,2007-05-03
-3pr2,2011-02-09,2010-11-29
-3pr5,2011-02-23,2010-11-29
-7prp,2021-12-08,2021-09-22
-6prr,2019-11-27,2019-07-11
-6pr4,2020-02-26,2019-07-10
-3prt,2011-11-30,2010-11-30
-7prk,2022-10-05,2021-09-21
-6pr9,2020-06-17,2019-07-10
-7prx,2023-02-08,2021-09-22
-2pr1,2007-05-15,2007-05-03
-7prv,2023-02-08,2021-09-22
-7prm,2022-02-16,2021-09-22
-3prz,2011-02-09,2010-11-30
-6prs,2019-11-27,2019-07-11
-1prh,1995-03-31,1994-03-07
-5pr6,2017-03-29,2017-02-07
-3prc,1998-11-11,1997-07-29
-7pr7,2022-08-03,2021-09-21
-6prt,2019-11-27,2019-07-11
-6pr7,2020-06-17,2019-07-10
-5pra,2017-03-29,2017-02-07
-2pr3,2007-08-14,2007-05-03
-8pr4,2024-03-27,2023-07-12
-2pr0,2008-03-18,2007-05-03
-2pry,2008-01-15,2007-05-04
-3pro,1999-04-27,1998-08-26
-2pr6,2007-08-07,2007-05-03
-3pru,2010-12-15,2010-11-30
-4pri,2014-04-16,2014-03-05
-6pr5,2019-10-09,2019-07-10
-8prv,2023-11-22,2023-07-12
-6pry,2019-12-18,2019-07-12
-7pr4,2022-03-02,2021-09-20
-3prj,2011-06-15,2010-11-29
-6prf,2019-09-18,2019-07-10
-5prg,2017-03-29,2017-02-07
-4prg,1999-05-27,1999-05-07
-1pr2,2003-11-25,2003-06-19
-2pr2,2008-01-15,2007-05-03
-4pr9,2014-12-10,2014-03-05
-4pr6,2014-10-29,2014-03-05
-1pr1,2003-11-25,2003-06-19
-3prs,2011-10-26,2010-11-30
-5prw,2017-03-29,2017-02-07
-6prw,2020-07-22,2019-07-11
-4prj,2014-07-02,2014-03-05
-3pr4,2011-02-23,2010-11-29
-2pre,2008-01-22,2007-05-04
-2prc,1998-11-11,1997-07-29
-7prs,2022-02-02,2021-09-22
-5pr5,2017-03-29,2017-02-07
-6pru,2019-12-18,2019-07-11
-4prv,2014-09-24,2014-03-06
-6pr0,2020-02-26,2019-07-10
-4prr,2015-04-08,2014-03-06
-4prz,2015-01-21,2014-03-06
-5prh,2017-03-29,2017-02-07
-7prw,2023-02-08,2021-09-22
-7pri,2022-10-05,2021-09-21
-2prb,2008-04-08,2007-05-04
-5prl,2017-03-29,2017-02-07
-6pr2,2020-02-26,2019-07-10
-1prs,1994-08-31,1994-03-25
-5prq,2017-03-29,2017-02-07
-5pry,2017-03-29,2017-02-07
-7pr0,2022-02-02,2021-09-20
-5prt,2017-03-29,2017-02-07
-3pr8,2010-12-22,2010-11-29
-3pre,2011-02-09,2010-11-29
-1prc,1989-01-09,1988-02-04
-3prk,1994-01-31,1991-08-07
-7pr3,2022-03-02,2021-09-20
-4pru,2014-11-12,2014-03-06
-2pri,1998-12-14,1998-12-11
-6pr6,2020-06-17,2019-07-10
-6pro,2020-05-20,2019-07-10
-2pr5,2007-08-07,2007-05-03
-7prz,2021-12-15,2021-09-22
-5pr9,2017-03-29,2017-02-07
-7pr2,2022-03-02,2021-09-20
-4pr0,2015-03-18,2014-03-05
-5prp,2017-03-29,2017-02-07
-5prz,2017-03-29,2017-02-07
-1pr6,2003-11-25,2003-06-19
-2prg,1999-07-19,1998-08-14
-5pr1,2017-03-29,2017-02-07
-2prz,2008-01-15,2007-05-04
-2prk,1988-04-16,1987-11-30
-6pre,2019-10-02,2019-07-10
-2prl,2008-05-20,2007-05-04
-6prz,2019-11-13,2019-07-12
-8prk,1998-12-23,1998-09-16
-5prb,2017-03-29,2017-02-07
-4f20,2012-08-08,2012-05-07
-6f25,2018-12-12,2017-11-23
-4f2l,2013-06-26,2012-05-08
-2f2e,2006-03-14,2005-11-16
-7f2m,2021-10-20,2021-06-11
-1f2a,2000-07-26,2000-05-23
-7f2z,2022-04-27,2021-06-15
-5f2b,2016-08-31,2015-12-01
-6f2g,2019-04-24,2017-11-24
-4f2z,2012-10-03,2012-05-08
-3f2r,2008-11-11,2008-10-30
-6f2v,2018-08-01,2017-11-27
-6f2u,2018-04-04,2017-11-27
-5f2r,2016-06-15,2015-12-02
-4f2e,2013-01-30,2012-05-07
-6f2b,2018-11-14,2017-11-24
-4f2b,2012-12-12,2012-05-07
-8f2c,2023-10-11,2022-11-07
-5f2w,2016-01-20,2015-12-02
-7f22,2022-03-23,2021-06-10
-2f2c,2006-06-13,2005-11-16
-2f2o,2006-02-21,2005-11-17
-2f22,2005-12-20,2005-11-15
-7f2y,2022-04-27,2021-06-15
-3f2k,2008-11-25,2008-10-29
-6f28,2018-02-28,2017-11-23
-3f2c,2009-01-20,2008-10-29
-4f2q,2012-05-30,2012-05-08
-4f27,2012-08-08,2012-05-07
-1f2q,2000-06-08,2000-05-28
-5f2u,2016-04-13,2015-12-02
-6f2k,2018-10-03,2017-11-24
-3f28,2009-11-17,2008-10-29
-6f2y,2018-08-01,2017-11-27
-8f2b,2023-08-02,2022-11-07
-4f21,2012-08-29,2012-05-07
-7f2a,2022-06-15,2021-06-10
-7f20,2022-03-23,2021-06-10
-8f29,2024-02-07,2022-11-07
-6f2p,2018-12-05,2017-11-27
-5f2e,2016-01-13,2015-12-01
-2f2h,2006-02-28,2005-11-16
-5f2n,2015-12-30,2015-12-02
-5f25,2016-03-09,2015-12-01
-7f2x,2022-06-22,2021-06-15
-1f2i,2001-09-14,2000-05-25
-6f29,2018-02-28,2017-11-23
-5f2f,2016-05-04,2015-12-01
-1f29,2000-07-26,2000-05-23
-5f20,2016-01-13,2015-12-01
-5f2i,2016-12-07,2015-12-01
-7f29,2022-07-13,2021-06-10
-4f2o,2012-05-23,2012-05-08
-5f2s,2016-01-20,2015-12-02
-5f2g,2016-12-07,2015-12-01
-2f2a,2006-07-18,2005-11-15
-1f25,2000-11-23,2000-05-23
-6f2m,2018-10-03,2017-11-24
-6f2z,2018-12-12,2017-11-27
-3f2p,2009-11-17,2008-10-30
-7f21,2022-03-23,2021-06-10
-5f2c,2016-12-14,2015-12-01
-5f27,2016-02-03,2015-12-01
-8f2s,2023-06-07,2022-11-08
-3f2d,2009-01-20,2008-10-29
-7f2j,2022-03-09,2021-06-11
-6f2t,2018-08-01,2017-11-27
-5f2l,2016-12-07,2015-12-02
-2f2s,2005-11-29,2005-11-17
-4f22,2012-05-16,2012-05-07
-5f2p,2016-03-09,2015-12-02
-5f2o,2015-12-30,2015-12-02
-6f2i,2018-10-03,2017-11-24
-4f2w,2013-05-01,2012-05-08
-2f2g,2005-12-13,2005-11-16
-2f2u,2006-04-25,2005-11-18
-6f22,2018-03-07,2017-11-23
-3f2a,2009-03-10,2008-10-29
-5f2m,2016-12-07,2015-12-02
-7f24,2022-06-15,2021-06-10
-7f2l,2021-10-20,2021-06-11
-1f2c,2000-07-26,2000-05-23
-3f21,2008-12-30,2008-10-28
-7f2r,2021-09-01,2021-06-14
-4f2p,2013-05-01,2012-05-08
-8f28,2023-07-05,2022-11-07
-6f2w,2019-04-24,2017-11-27
-5f2d,2015-12-16,2015-12-01
-7f2w,2022-05-04,2021-06-14
-4f24,2012-08-08,2012-05-07
-1f2o,2001-08-22,2000-05-28
-3f2v,2008-11-18,2008-10-30
-3f2f,2008-11-11,2008-10-29
-6f2j,2018-10-03,2017-11-24
-5f2k,2015-12-30,2015-12-02
-2f2l,2006-04-04,2005-11-17
-6f2s,2018-06-27,2017-11-27
-3f2m,2009-11-10,2008-10-30
-1f2w,2000-06-08,2000-05-30
-1f20,2001-10-10,2000-05-22
-1f24,2000-11-23,2000-05-23
-2f2k,2006-05-16,2005-11-17
-6f2a,2018-11-14,2017-11-24
-5f2v,2015-12-16,2015-12-02
-1f2n,2000-11-01,2000-05-26
-4f2k,2012-06-06,2012-05-08
-4f29,2012-05-16,2012-05-07
-5f2q,2016-12-07,2015-12-02
-8f2x,2024-04-17,2022-11-08
-5f29,2017-02-01,2015-12-01
-7f2i,2022-01-12,2021-06-11
-6f2n,2018-10-03,2017-11-24
-5f2a,2016-10-19,2015-12-01
-5f2t,2016-03-09,2015-12-02
-8f2k,2023-04-05,2022-11-08
-8f2l,2023-03-01,2022-11-08
-6f2h,2018-10-03,2017-11-24
-8f2a,2023-08-02,2022-11-07
-4f2m,2012-08-22,2012-05-08
-7f23,2022-06-15,2021-06-10
-3f2b,2009-01-20,2008-10-29
-6f20,2018-03-07,2017-11-23
-7f2k,2021-10-20,2021-06-11
-1f28,2001-06-06,2000-05-23
-1f22,2000-06-21,2000-05-23
-8f2d,2023-10-11,2022-11-07
-1f26,2000-11-23,2000-05-23
-4f2s,2013-07-24,2012-05-08
-3f23,2008-12-30,2008-10-28
-6f23,2018-03-07,2017-11-23
-6f2l,2018-01-10,2017-11-24
-8f2j,2023-12-13,2022-11-08
-1f2b,2000-07-26,2000-05-23
-1f2e,2000-06-21,2000-05-24
-3f2n,2008-12-02,2008-10-30
-5f23,2015-12-23,2015-12-01
-1f2u,2000-08-02,2000-05-29
-4f2f,2013-01-30,2012-05-07
-1f2p,2001-08-22,2000-05-28
-3f22,2008-12-30,2008-10-28
-1f2d,2000-12-20,2000-05-24
-2f25,2006-11-21,2005-11-15
-5f24,2015-12-23,2015-12-01
-8f22,2023-09-13,2022-11-06
-4f2a,2012-09-05,2012-05-07
-4f2d,2012-05-30,2012-05-07
-4f2j,2013-02-27,2012-05-08
-2f27,2006-11-21,2005-11-15
-2f2p,2006-02-21,2005-11-17
-3f2h,2008-11-11,2008-10-29
-4f23,2012-11-21,2012-05-07
-4f2n,2012-05-16,2012-05-08
-4f2r,2013-07-24,2012-05-08
-7f2o,2021-10-13,2021-06-11
-6f26,2019-03-13,2017-11-23
-2f29,2006-11-21,2005-11-15
-3f29,2008-12-09,2008-10-29
-7f2u,2021-11-03,2021-06-14
-7f2d,2022-01-12,2021-06-10
-2f2t,2005-11-22,2005-11-17
-1f2s,2000-06-05,2000-05-29
-4q5k,2014-05-21,2014-04-17
-7q5h,2022-03-16,2021-11-03
-7q50,2022-03-02,2021-11-02
-5q5f,2018-08-08,2017-05-25
-6q55,2019-11-20,2018-12-07
-8q5f,2023-11-29,2023-08-09
-8q5j,2024-04-03,2023-08-09
-6q58,2019-07-10,2018-12-07
-7q5y,2022-11-16,2021-11-05
-1q5e,2003-10-28,2003-08-06
-5q5o,2018-08-08,2017-05-25
-2q5f,2007-08-07,2007-06-01
-3q5p,2011-06-15,2010-12-29
-4q5j,2014-10-29,2014-04-17
-5q5q,2018-08-08,2017-05-25
-7q56,2022-11-16,2021-11-02
-7q5e,2022-11-23,2021-11-03
-1q5k,2004-08-10,2003-08-08
-6q50,2019-09-25,2018-12-06
-5q5s,2018-08-08,2017-05-25
-5q5x,2018-08-08,2017-05-25
-4q5b,2014-09-10,2014-04-16
-8q5g,2023-11-29,2023-08-09
-7q54,2022-11-16,2021-11-02
-5q5b,2018-08-08,2017-05-25
-7q5x,2022-11-16,2021-11-04
-2q5z,2007-10-09,2007-06-04
-8q5i,2023-09-13,2023-08-09
-2q58,2007-06-12,2007-05-31
-3q5v,2012-01-04,2010-12-29
-5q54,2018-08-08,2017-05-25
-4q5f,2015-04-01,2014-04-16
-8q59,2023-10-25,2023-08-08
-1q5j,2004-01-06,2003-08-07
-5q5p,2018-08-08,2017-05-25
-1q5i,2004-01-06,2003-08-07
-2q5b,2008-06-17,2007-05-31
-4q53,2014-07-16,2014-04-15
-1q5l,2003-11-04,2003-08-08
-8q58,2023-10-25,2023-08-08
-5q5t,2018-08-08,2017-05-25
-3q5i,2011-06-01,2010-12-28
-5q59,2018-08-08,2017-05-25
-6q5e,2019-01-16,2018-12-07
-2q5a,2007-06-26,2007-05-31
-1q5w,2004-03-30,2003-08-11
-4q5o,2014-09-10,2014-04-17
-5q5c,2018-08-08,2017-05-25
-3q5h,2011-11-30,2010-12-28
-7q5o,2022-04-20,2021-11-04
-5q5j,2018-08-08,2017-05-25
-8q5w,2024-05-15,2023-08-09
-2q5k,2007-09-04,2007-06-01
-5q58,2018-08-08,2017-05-25
-2q5l,2007-10-23,2007-06-01
-4q5h,2014-07-02,2014-04-16
-7q5c,2022-11-16,2021-11-03
-1q5p,2003-11-11,2003-08-08
-5q53,2018-08-08,2017-05-25
-5q5e,2018-08-08,2017-05-25
-3q5r,2011-07-20,2010-12-29
-8q5x,2024-05-15,2023-08-09
-5q5v,2018-08-08,2017-05-25
-3q5e,2011-01-19,2010-12-28
-1q5a,2003-10-07,2003-08-06
-2q5s,2007-10-23,2007-06-01
-8q5p,2024-04-24,2023-08-09
-5q5r,2018-08-08,2017-05-25
-8q5u,2024-04-17,2023-08-09
-7q55,2022-11-16,2021-11-02
-7q53,2022-11-16,2021-11-02
-6q5b,2019-03-20,2018-12-07
-2q5g,2008-06-03,2007-06-01
-5q5d,2018-08-08,2017-05-25
-1q5d,2003-10-28,2003-08-06
-7q59,2022-11-16,2021-11-03
-2q5q,2007-10-23,2007-06-01
-2q55,2007-09-04,2007-05-31
-8q5z,2023-09-20,2023-08-10
-5q5u,2018-08-08,2017-05-25
-5q5z,2018-08-08,2017-05-25
-8q5a,2023-10-25,2023-08-08
-1q5h,2003-08-19,2003-08-07
-5q5g,2018-08-08,2017-05-25
-4q5q,2015-04-01,2014-04-17
-2q59,2007-10-23,2007-05-31
-5q51,2018-08-08,2017-05-25
-5q5h,2018-08-08,2017-05-25
-5q56,2018-08-08,2017-05-25
-2q51,2007-06-19,2007-05-31
-4q50,2015-04-15,2014-04-15
-7q57,2022-11-16,2021-11-02
-2q5e,2007-06-19,2007-05-31
-5q50,2018-08-08,2017-05-25
-6q5a,2019-11-20,2018-12-07
-6q52,2019-05-01,2018-12-06
-1q5c,2003-10-07,2003-08-06
-4q5p,2015-04-22,2014-04-17
-4q5r,2015-04-01,2014-04-17
-7q5v,2022-11-16,2021-11-04
-7q5g,2022-02-02,2021-11-03
-6q5m,2019-05-22,2018-12-09
-7q51,2022-03-02,2021-11-02
-5q5i,2018-08-08,2017-05-25
-4q5u,2014-09-03,2014-04-17
-2q5p,2007-10-23,2007-06-01
-4q52,2014-05-07,2014-04-15
-3q5d,2011-01-19,2010-12-28
-8q5v,2024-05-15,2023-08-09
-5q5n,2018-08-08,2017-05-25
-4q51,2014-05-07,2014-04-15
-3q5u,2011-06-29,2010-12-29
-1q5y,2003-09-30,2003-08-11
-8q5e,2023-11-29,2023-08-09
-5q5m,2018-08-08,2017-05-25
-8q50,2024-05-15,2023-08-07
-7q5d,2022-09-14,2021-11-03
-4q5s,2014-07-09,2014-04-17
-5q5l,2018-08-08,2017-05-25
-3q5l,2011-02-23,2010-12-28
-7q5a,2022-04-06,2021-11-03
-2q5j,2007-10-23,2007-06-01
-3q5g,2011-06-29,2010-12-28
-5q5y,2018-08-08,2017-05-25
-8q5k,2024-01-17,2023-08-09
-7q52,2022-06-22,2021-11-02
-7q5i,2022-03-02,2021-11-03
-7q5n,2022-08-24,2021-11-04
-1q5m,2004-05-18,2003-08-08
-6q53,2019-10-16,2018-12-07
-4q57,2014-07-23,2014-04-16
-5q5k,2018-08-08,2017-05-25
-4q56,2015-10-14,2014-04-16
-2q5o,2007-10-23,2007-06-01
-5q5w,2018-08-08,2017-05-25
-4q5m,2015-04-08,2014-04-17
-5q52,2018-08-08,2017-05-25
-6q56,2019-03-27,2018-12-07
-1q55,2003-10-07,2003-08-06
-5q57,2018-08-08,2017-05-25
-1q5o,2003-09-09,2003-08-08
-3q53,2011-12-21,2010-12-26
-2q5y,2008-10-14,2007-06-03
-6q54,2019-04-17,2018-12-07
-3q5s,2011-06-15,2010-12-29
-3q5k,2011-02-23,2010-12-28
-1q5b,2003-10-07,2003-08-06
-7q5f,2022-11-23,2021-11-03
-4q5c,2014-09-03,2014-04-16
-7q5b,2022-01-26,2021-11-03
-4q5v,2014-11-26,2014-04-17
-5q5a,2018-08-08,2017-05-25
-8q57,2023-10-25,2023-08-08
-1q54,2003-08-26,2003-08-06
-3q5j,2011-02-23,2010-12-28
-6q5f,2019-03-20,2018-12-08
-5q55,2018-08-08,2017-05-25
-1q51,2004-01-27,2003-08-05
-4q5t,2014-06-18,2014-04-17
-8q5l,2024-01-17,2023-08-09
-2q54,2007-09-04,2007-05-31
-4q5n,2015-04-01,2014-04-17
-8ams,2023-11-15,2022-08-04
-3amy,2011-10-05,2010-08-25
-3am7,2011-08-17,2010-08-17
-7amx,2021-10-20,2020-10-09
-2amy,2005-08-23,2005-08-10
-4am3,2012-04-18,2012-03-07
-4am2,2012-10-31,2012-03-07
-6amj,2018-01-31,2017-08-09
-7aml,2021-01-13,2020-10-09
-2ama,2006-05-16,2005-08-09
-6amc,2018-05-16,2017-08-09
-2am5,2006-06-27,2005-08-08
-5amd,2015-04-08,2015-03-10
-2amd,2005-09-13,2005-08-09
-1amo,1998-06-17,1997-06-17
-5amq,2015-06-03,2015-03-12
-5amf,2015-03-18,2015-03-10
-6aml,2018-08-08,2017-08-09
-8am1,2023-06-14,2022-08-02
-5amp,2015-09-23,2015-03-11
-2amb,2006-05-16,2005-08-09
-5am4,2015-05-13,2015-03-09
-8am8,2024-02-14,2022-08-03
-5ama,2016-01-13,2015-03-10
-1ams,1994-09-30,1994-07-01
-3am1,2010-12-29,2010-08-11
-1ami,1995-01-26,1994-11-11
-3amt,2011-10-12,2010-08-23
-1amn,1996-04-03,1996-02-13
-2amt,2006-02-28,2005-08-10
-1amy,1995-05-13,1994-03-10
-5amv,2015-09-30,2015-09-02
-4ami,2012-05-23,2012-03-11
-4amk,2012-10-31,2012-03-12
-6amh,2018-05-16,2017-08-09
-1am1,1998-06-24,1997-06-20
-2amm,2006-07-18,2005-08-09
-5amh,2015-07-01,2015-03-10
-3ams,2011-04-13,2010-08-22
-1amt,1988-10-09,1987-12-08
-6amp,2018-07-18,2017-08-10
-4ams,2013-03-20,2012-03-13
-6amz,2017-08-23,2017-08-11
-5amj,2015-07-01,2015-03-10
-5ame,2015-03-18,2015-03-10
-7amh,2021-10-20,2020-10-08
-1amk,1997-12-17,1997-06-17
-7amv,2021-10-06,2020-10-09
-4amq,2013-03-20,2012-03-13
-4amf,2013-03-20,2012-03-09
-6am0,2018-03-21,2017-08-08
-4amw,2013-03-27,2012-03-14
-5amc,2016-01-13,2015-03-10
-7amk,2021-02-03,2020-10-09
-8amt,2023-02-08,2022-08-04
-8am6,2024-02-14,2022-08-02
-8amy,2023-08-23,2022-08-04
-7amp,2022-04-20,2020-10-09
-2amu,2005-08-23,2005-08-10
-5amo,2015-04-29,2015-03-11
-3amj,2011-02-09,2010-08-20
-5amb,2016-01-13,2015-03-10
-5am7,2015-03-18,2015-03-10
-2amq,2005-09-13,2005-08-10
-3ama,2011-08-03,2010-08-18
-6amf,2017-09-06,2017-08-09
-8am7,2023-09-20,2022-08-02
-5am6,2015-03-18,2015-03-10
-1amz,1997-12-24,1997-06-19
-5amn,2016-02-17,2015-03-11
-7amg,2022-04-20,2020-10-08
-5am3,2015-05-13,2015-03-09
-2am1,2006-01-24,2005-08-08
-1am4,1998-07-15,1997-06-22
-5amr,2015-06-03,2015-03-12
-8amq,2023-02-15,2022-08-03
-7am8,2021-02-17,2020-10-08
-3amm,2011-03-16,2010-08-20
-7amc,2021-10-20,2020-10-08
-2am3,2006-06-27,2005-08-08
-3amv,1999-02-26,1999-02-18
-6am9,2018-05-16,2017-08-09
-4amx,2013-03-27,2012-03-14
-3amz,2010-12-01,2010-08-27
-7ams,2022-04-20,2020-10-09
-5amk,2015-07-01,2015-03-10
-6am7,2018-05-16,2017-08-09
-6am3,2019-02-13,2017-08-09
-3amb,2011-08-03,2010-08-18
-1amq,1994-09-30,1994-07-01
-6amb,2017-11-01,2017-08-09
-2amp,2005-09-13,2005-08-10
-5am8,2016-01-13,2015-03-10
-7amd,2020-10-28,2020-10-08
-8amo,2023-02-15,2022-08-03
-3am9,2010-11-03,2010-08-18
-7amq,2022-04-20,2020-10-09
-1amu,1998-07-01,1997-06-18
-5amg,2015-04-08,2015-03-10
-2amf,2005-09-27,2005-08-09
-6ami,2018-05-16,2017-08-09
-6amo,2018-08-15,2017-08-10
-3am6,2011-07-06,2010-08-16
-6amt,2018-08-15,2017-08-11
-4am5,2012-10-31,2012-03-07
-7amj,2020-12-02,2020-10-09
-4amv,2013-04-24,2012-03-14
-8amz,2022-08-24,2022-08-04
-5am1,2015-05-13,2015-03-08
-1ama,1993-10-31,1992-02-05
-3am8,2011-08-24,2010-08-18
-3amf,2011-10-05,2010-08-19
-4amz,2012-05-16,2012-03-14
-6am5,2018-08-08,2017-08-09
-8am9,2023-03-08,2022-08-03
-8am3,2024-02-14,2022-08-02
-2am4,2006-06-27,2005-08-08
-6am8,2018-05-16,2017-08-09
-3amo,2011-11-23,2010-08-20
-7am9,2021-11-03,2020-10-08
-5am5,2015-05-13,2015-03-09
-3amr,2011-04-13,2010-08-22
-5aml,2015-04-08,2015-03-10
-5am9,2016-01-13,2015-03-10
-1am6,1998-06-24,1997-06-24
-4amt,2013-03-20,2012-03-13
-4am4,2012-10-31,2012-03-07
-8am2,2023-06-14,2022-08-02
-2am2,2006-01-24,2005-08-08
-8amd,2023-03-22,2022-08-03
-8am5,2023-08-16,2022-08-02
-3amg,2011-08-17,2010-08-20
-1amh,1997-12-24,1997-06-17
-8amu,2023-02-08,2022-08-04
-3amq,2011-03-16,2010-08-20
-7am0,2021-08-04,2020-10-07
-7am2,2021-04-28,2020-10-07
-8am0,2023-12-13,2022-08-02
-2amx,2005-09-20,2005-08-10
-4aml,2012-04-04,2012-03-12
-2am9,2006-05-16,2005-08-09
-3am5,2011-03-16,2010-08-14
-8amv,2023-02-08,2022-08-04
-3amu,2011-10-19,2010-08-23
-4amb,2012-09-05,2012-03-08
-4am7,2012-12-12,2012-03-07
-2amh,2005-08-16,2005-08-09
-2amc,2005-12-20,2005-08-09
-3am4,2011-03-16,2010-08-14
-4am9,2012-05-30,2012-03-08
-3am3,2011-03-16,2010-08-14
-5am0,2015-05-13,2015-03-08
-4amc,2012-11-07,2012-03-08
-8amp,2023-02-15,2022-08-03
-2amv,1998-10-21,1998-10-13
-7amz,2021-05-26,2020-10-10
-7amr,2022-04-20,2020-10-09
-5ami,2015-07-01,2015-03-10
-1amp,1994-08-31,1994-04-22
-2amo,2006-10-31,2005-08-09
-1am9,1998-07-10,1997-06-25
-2amg,1997-04-01,1996-12-23
-7ama,2022-04-20,2020-10-08
-4amj,2012-05-23,2012-03-12
-8amf,2024-02-21,2022-08-03
-4amy,2012-05-16,2012-03-14
-3amn,2011-03-16,2010-08-20
-5amm,2015-12-09,2015-03-11
-6amu,2018-08-15,2017-08-11
-4am8,2013-03-27,2012-03-08
-5am2,2015-05-13,2015-03-08
-3amp,2011-03-16,2010-08-20
-7am5,2021-02-17,2020-10-08
-1amr,1994-09-30,1994-07-01
-6amg,2017-12-20,2017-08-09
-1amw,1998-06-24,1997-06-19
-2bnq,2005-05-23,2005-03-31
-5bnp,2015-11-18,2015-05-26
-1bnq,1999-06-15,1998-07-30
-1bnl,1998-10-14,1998-07-30
-1bnw,1999-06-15,1998-07-30
-8bn8,2023-09-20,2022-11-13
-5bnl,2015-07-15,2015-05-26
-5bn2,2016-06-29,2015-05-25
-5bnr,2016-05-18,2015-05-26
-5bnm,2016-05-18,2015-05-26
-2bnm,2005-10-05,2005-03-29
-6bn1,2018-03-14,2017-11-15
-7bnc,2022-03-02,2021-01-21
-3bnf,2008-02-26,2007-12-14
-7bno,2021-02-03,2021-01-22
-7bnk,2021-09-08,2021-01-22
-5bnw,2015-08-05,2015-05-26
-2bnj,2005-09-07,2005-03-25
-3bnx,2008-03-25,2007-12-14
-4bnb,2014-05-28,2013-05-13
-6bnq,2018-01-10,2017-11-17
-6bnc,2018-01-31,2017-11-16
-3bnu,2008-01-29,2007-12-14
-5bn9,2016-09-14,2015-05-25
-4bnx,2013-09-18,2013-05-17
-6bns,2017-12-20,2017-11-17
-7bng,2021-02-17,2021-01-22
-4bn6,2014-05-28,2013-05-13
-6bny,2018-09-26,2017-11-17
-1bnt,1999-06-15,1998-07-30
-5bnt,2015-06-10,2015-05-26
-4bn9,2014-05-28,2013-05-13
-7bn8,2022-03-02,2021-01-21
-7bn5,2022-03-02,2021-01-21
-2bnl,2005-11-03,2005-03-28
-4bny,2013-09-18,2013-05-17
-7bnb,2022-03-02,2021-01-21
-8bns,2023-03-22,2022-11-14
-8bn5,2023-11-22,2022-11-12
-3bng,2008-02-26,2007-12-14
-5bnn,2015-11-18,2015-05-26
-4bnp,2014-05-21,2013-05-16
-5bn6,2016-06-08,2015-05-25
-1bn4,1999-05-18,1998-07-31
-6bnz,2018-11-21,2017-11-17
-5bni,2016-05-25,2015-05-26
-4bnu,2013-09-18,2013-05-17
-3bnm,2008-01-29,2007-12-14
-1bn8,1998-08-05,1998-07-31
-3bny,2008-03-25,2007-12-14
-7bn6,2022-07-13,2021-01-21
-8bn2,2023-11-22,2022-11-11
-6bn5,2017-12-13,2017-11-16
-7bnh,2021-02-17,2021-01-22
-3bn3,2008-08-19,2007-12-13
-4bnf,2013-06-05,2013-05-15
-4bn4,2013-06-26,2013-05-13
-2bnp,2005-05-27,2005-03-31
-4bnj,2013-06-05,2013-05-15
-4bng,2013-06-05,2013-05-15
-1bnn,1999-05-18,1998-07-30
-6bnd,2018-01-31,2017-11-16
-2bns,2005-05-27,2005-03-31
-3bnj,2008-02-26,2007-12-14
-8bnv,2023-03-08,2022-11-14
-6bni,2018-02-14,2017-11-16
-7bne,2022-03-02,2021-01-22
-6bnb,2018-05-30,2017-11-16
-6bn9,2018-05-30,2017-11-16
-6bnl,2018-04-04,2017-11-16
-3bn1,2008-03-18,2007-12-13
-5bnq,2015-10-14,2015-05-26
-5bn4,2015-09-16,2015-05-25
-2bn0,2005-06-16,2005-03-17
-2bne,2005-04-25,2005-03-23
-5bne,2016-05-25,2015-05-26
-7bns,2022-03-02,2021-01-22
-2bnf,2005-04-27,2005-03-23
-6bnn,2018-11-21,2017-11-17
-5bn8,2016-09-14,2015-05-25
-6bn2,2018-01-17,2017-11-15
-5bnc,2015-10-21,2015-05-26
-6bnj,2017-12-06,2017-11-16
-7bnu,2022-03-02,2021-01-22
-8bn0,2023-08-16,2022-11-11
-4bnv,2013-09-18,2013-05-17
-8bn6,2023-03-29,2022-11-12
-7bnn,2021-02-03,2021-01-22
-4bn7,2014-05-28,2013-05-13
-7bnm,2021-02-03,2021-01-22
-6bn7,2018-05-30,2017-11-16
-7bnv,2021-11-17,2021-01-22
-4bnm,2013-06-05,2013-05-15
-2bnn,2005-10-05,2005-03-29
-4bnz,2013-09-18,2013-05-17
-1bn3,1999-05-18,1998-07-31
-7bn7,2022-07-13,2021-01-21
-6bn0,2018-08-22,2017-11-15
-6bnr,2018-09-05,2017-11-17
-2bn2,1999-02-16,1998-12-18
-7bni,2021-02-17,2021-01-22
-2bn7,2005-09-29,2005-03-22
-3bnz,2008-12-16,2007-12-15
-8bnw,2023-07-12,2022-11-14
-2bnd,2005-04-27,2005-03-23
-9bnj,2024-05-29,2024-05-02
-7bn1,2022-03-02,2021-01-21
-4bnk,2013-06-05,2013-05-15
-4bnl,2013-06-05,2013-05-15
-1bnz,1998-11-11,1998-07-31
-6bnt,2018-11-21,2017-11-17
-3bne,2008-04-01,2007-12-14
-4bn1,2014-03-26,2013-05-13
-8bnx,2023-03-08,2022-11-14
-7bnr,2021-09-08,2021-01-22
-1bnm,1999-05-18,1998-07-30
-7bnj,2022-03-02,2021-01-22
-4bnt,2013-09-18,2013-05-17
-2bng,2005-08-03,2005-03-24
-3bnb,2008-04-01,2007-12-14
-6bno,2018-01-10,2017-11-17
-7bnd,2022-03-02,2021-01-21
-3bnd,2008-04-01,2007-12-14
-5bnh,2016-05-25,2015-05-26
-6bnp,2018-01-10,2017-11-17
-5bno,2015-11-18,2015-05-26
-7bnl,2022-03-02,2021-01-22
-4bnh,2013-06-05,2013-05-15
-3bnh,2008-02-26,2007-12-14
-7bnf,2022-03-02,2021-01-22
-4bnn,2013-06-05,2013-05-15
-1bn5,1999-07-31,1998-07-31
-5bns,2016-05-18,2015-05-26
-5bny,2015-08-12,2015-05-26
-8bn1,2023-09-20,2022-11-11
-3bnk,2008-10-28,2007-12-14
-2bnz,2006-03-15,2005-04-06
-6bnx,2018-11-21,2017-11-17
-1bnu,1999-06-15,1998-07-30
-4bn2,2014-01-15,2013-05-13
-1bn1,1999-05-18,1998-07-31
-7bn2,2022-03-02,2021-01-21
-2bno,2005-10-05,2005-03-29
-2bn4,2006-01-17,2005-03-18
-6bn8,2018-06-06,2017-11-16
-4bn5,2013-06-26,2013-05-13
-5bnj,2015-10-14,2015-05-26
-2bnr,2005-05-23,2005-03-31
-1bnv,1999-02-16,1998-07-30
-4bn8,2014-05-28,2013-05-13
-6bnf,2018-01-31,2017-11-16
-6bn6,2017-12-20,2017-11-16
-5bn3,2015-09-16,2015-05-25
-5bnk,2015-07-29,2015-05-26
-8bn3,2024-01-10,2022-11-12
-6bnk,2018-04-04,2017-11-16
-4bnr,2013-09-04,2013-05-17
-3bnc,2008-04-01,2007-12-14
-4bni,2013-06-05,2013-05-15
-6de6,2019-05-15,2018-05-11
-1dej,2000-03-01,1999-11-15
-1dek,1997-01-11,1996-01-09
-4del,2013-01-23,2012-01-20
-8de0,2022-09-07,2022-06-19
-8de5,2023-06-21,2022-06-19
-7deq,2021-03-10,2020-11-04
-6de4,2018-05-23,2018-05-11
-5de5,2015-09-23,2015-08-25
-2dek,2006-07-18,2006-02-10
-5deo,2016-08-24,2015-08-25
-8dey,2023-03-08,2022-06-21
-5deg,2015-11-18,2015-08-25
-4den,2012-11-28,2012-01-20
-4de7,2012-06-06,2012-01-20
-8de9,2023-03-08,2022-06-20
-3deq,2008-11-25,2008-06-10
-5dej,2016-08-31,2015-08-25
-6deh,2018-12-19,2018-05-11
-4der,2012-11-21,2012-01-21
-1ded,2000-04-07,1999-11-14
-6deq,2018-09-26,2018-05-12
-2deu,2006-08-15,2006-02-17
-5del,2015-10-07,2015-08-25
-4ded,2012-08-22,2012-01-20
-1de4,2000-01-19,1999-11-12
-6dex,2018-05-23,2018-05-13
-4dei,2012-05-30,2012-01-20
-6deo,2018-09-26,2018-05-12
-4dew,2012-11-21,2012-01-22
-6de5,2018-05-23,2018-05-11
-4de1,2012-03-28,2012-01-19
-5de1,2015-10-07,2015-08-25
-2dew,2006-04-11,2006-02-18
-7deo,2021-03-31,2020-11-04
-2deh,2007-05-01,2006-02-10
-4det,2012-11-21,2012-01-22
-5de2,2015-11-11,2015-08-25
-8de4,2023-07-05,2022-06-19
-4de5,2013-03-06,2012-01-19
-4def,2013-01-23,2012-01-20
-2deg,2007-05-01,2006-02-10
-4de8,2012-04-04,2012-01-20
-8dev,2022-09-14,2022-06-21
-2de6,2006-12-05,2006-02-08
-7den,2021-01-13,2020-11-04
-3dev,2008-08-05,2008-06-10
-6det,2019-03-20,2018-05-13
-5des,2016-03-16,2015-08-25
-2dea,2006-07-25,2006-02-10
-8deu,2022-09-14,2022-06-21
-4deh,2012-05-30,2012-01-20
-3dek,2008-09-02,2008-06-10
-8dek,2022-08-31,2022-06-20
-3de7,2009-06-09,2008-06-08
-5dei,2015-09-16,2015-08-25
-4dem,2012-03-21,2012-01-20
-1det,1996-07-11,1996-02-20
-5deb,2016-03-16,2015-08-25
-1dex,2000-04-26,1999-11-16
-5def,2015-11-18,2015-08-25
-3dej,2008-09-02,2008-06-10
-2de5,2006-12-05,2006-02-08
-7ded,2021-04-21,2020-11-03
-2deq,2006-08-16,2006-02-16
-4deg,2012-05-30,2012-01-20
-6dep,2018-09-26,2018-05-12
-1de7,2000-12-13,1999-11-13
-5dez,2016-09-07,2015-08-26
-7dex,2021-09-15,2020-11-05
-7dem,2021-01-13,2020-11-04
-8deq,2023-06-28,2022-06-21
-3de4,2009-06-09,2008-06-08
-3de2,2009-06-09,2008-06-07
-2dev,2007-05-01,2006-02-17
-6de3,2018-07-04,2018-05-11
-5den,2016-02-17,2015-08-25
-3den,2008-11-25,2008-06-10
-7dea,2021-11-03,2020-11-03
-7de5,2020-11-25,2020-11-02
-7dee,2021-11-03,2020-11-03
-1def,1997-04-21,1996-03-19
-1de5,2000-08-09,1999-11-12
-2dec,2006-08-10,2006-02-10
-5dep,2015-09-16,2015-08-25
-7del,2021-01-13,2020-11-04
-2de4,2006-08-01,2006-02-08
-6def,2018-08-22,2018-05-11
-3deu,2008-06-24,2008-06-10
-6del,2018-09-26,2018-05-12
-3des,2008-11-25,2008-06-10
-8de6,2023-01-25,2022-06-20
-6des,2018-09-26,2018-05-12
-4de2,2012-03-28,2012-01-19
-5ded,2015-10-28,2015-08-25
-4dep,2012-03-21,2012-01-21
-7de9,2021-04-07,2020-11-03
-7dei,2021-03-24,2020-11-04
-1del,1997-01-11,1996-01-09
-3deh,2008-09-02,2008-06-10
-3de0,2009-06-09,2008-06-07
-5deq,2015-10-21,2015-08-25
-5dey,2016-01-27,2015-08-26
-6dec,2018-10-24,2018-05-11
-7deg,2021-08-04,2020-11-04
-5de0,2015-10-21,2015-08-25
-5de9,2015-09-30,2015-08-25
-6de8,2018-05-30,2018-05-11
-7de0,2021-11-10,2020-10-31
-3de6,2009-06-09,2008-06-08
-1deh,1996-03-08,1995-10-14
-2de3,2006-08-01,2006-02-08
-6deb,2018-05-23,2018-05-11
-3de3,2009-06-09,2008-06-08
-5dea,2015-09-23,2015-08-25
-4de0,2012-03-28,2012-01-19
-4de6,2012-03-07,2012-01-19
-2dex,2006-04-11,2006-02-18
-8de2,2022-09-07,2022-06-19
-4de9,2012-04-04,2012-01-20
-6de2,2018-07-04,2018-05-10
-2dey,2006-04-11,2006-02-18
-7de2,2021-07-14,2020-11-01
-3de8,2009-04-21,2008-06-08
-8deb,2023-08-02,2022-06-20
-3def,2008-06-24,2008-06-10
-4dea,2012-08-22,2012-01-20
-3de9,2009-04-21,2008-06-08
-1de9,2000-02-02,1999-11-13
-4des,2012-11-21,2012-01-21
-5dex,2016-09-14,2015-08-26
-5de3,2016-09-14,2015-08-25
-3ded,2008-08-05,2008-06-09
-3dea,2008-11-18,2008-06-09
-7der,2021-03-10,2020-11-04
-2dej,2007-05-01,2006-02-10
-6dew,2019-02-06,2018-05-13
-3der,2008-11-25,2008-06-10
-7dep,2020-12-23,2020-11-04
-2de7,2006-12-05,2006-02-08
-3deo,2008-08-12,2008-06-10
-8de1,2022-09-07,2022-06-19
-8der,2023-06-28,2022-06-21
-5deh,2015-09-02,2015-08-25
-5deu,2015-11-04,2015-08-26
-6der,2018-09-26,2018-05-12
-3dey,2009-09-29,2008-06-10
-7det,2021-03-31,2020-11-05
-2def,1998-03-18,1997-12-15
-3dep,2008-08-12,2008-06-10
-4deb,2012-08-22,2012-01-20
-3dem,2008-07-01,2008-06-10
-3dec,2008-06-17,2008-06-09
-5dew,2016-09-21,2015-08-26
-6de7,2018-06-06,2018-05-11
-2dei,2007-05-01,2006-02-10
-3de1,2009-06-09,2008-06-07
-8de8,2023-03-08,2022-06-20
-4dec,2012-06-06,2012-01-20
-7deb,2021-11-03,2020-11-03
-8de7,2023-03-08,2022-06-20
-8dea,2022-11-02,2022-06-20
-7de7,2021-08-25,2020-11-02
-5det,2015-09-23,2015-08-25
-6de9,2019-05-15,2018-05-11
-1deo,2000-04-26,1999-11-15
-8del,2022-07-06,2022-06-20
-6den,2018-09-26,2018-05-12
-6dem,2018-09-26,2018-05-12
-4dee,2012-08-22,2012-01-20
-2deb,2007-02-10,2006-02-10
-6dek,2018-09-26,2018-05-12
-4deu,2012-11-21,2012-01-22
-4de3,2012-03-28,2012-01-19
-8deo,2023-05-03,2022-06-21
-3de5,2009-06-09,2008-06-08
-3deb,2009-04-07,2008-06-09
-3dei,2008-09-02,2008-06-10
-8de3,2023-07-05,2022-06-19
-8dep,2022-09-21,2022-06-21
-7deu,2021-03-31,2020-11-05
-1de6,2000-08-09,1999-11-13
-8deg,2022-12-14,2022-06-20
-4xpl,2015-03-18,2015-01-17
-2xp4,2011-01-12,2010-08-25
-6xpq,2021-05-19,2020-07-08
-8xpe,2024-01-31,2024-01-03
-7xpo,2023-05-17,2022-05-05
-7xpx,2022-06-01,2022-05-06
-4xp7,2015-01-28,2015-01-16
-4xp9,2015-05-06,2015-01-16
-5xpn,2018-07-11,2017-06-03
-6xpw,2020-11-04,2020-07-09
-6xpp,2020-10-21,2020-07-08
-1xp8,2004-12-21,2004-10-08
-1xpa,1999-07-22,1998-07-06
-5xp3,2017-10-25,2017-05-31
-4xpp,2015-05-20,2015-01-17
-1xp3,2005-10-04,2004-10-08
-4xpg,2015-05-06,2015-01-16
-5xpg,2018-04-18,2017-06-02
-1xpk,2004-11-02,2004-10-08
-2xpy,2010-12-29,2010-08-31
-7xpg,2023-02-08,2022-05-04
-7xpp,2023-05-24,2022-05-05
-6xph,2020-07-22,2020-07-08
-6xp3,2020-11-04,2020-07-07
-7xp0,2023-04-12,2022-05-02
-2xpu,2011-09-07,2010-08-30
-5xpe,2017-10-04,2017-06-01
-8xp5,2024-03-06,2024-01-03
-4xpq,2015-05-20,2015-01-17
-1xpj,2004-10-19,2004-10-08
-4xp6,2015-05-13,2015-01-16
-5xpd,2017-09-13,2017-06-01
-4xpw,2015-04-29,2015-01-18
-2xpw,2011-09-07,2010-08-30
-7xp1,2023-04-12,2022-05-02
-4xp0,2015-08-12,2015-01-16
-6xp1,2020-11-04,2020-07-07
-1xp9,2004-12-07,2004-10-08
-7xpq,2023-05-17,2022-05-05
-4xpx,2015-04-29,2015-01-18
-2xpj,2010-09-15,2010-08-26
-7xpr,2023-03-29,2022-05-05
-7xps,2023-03-29,2022-05-05
-6xp0,2020-11-04,2020-07-07
-2xp9,2011-01-12,2010-08-25
-4xpz,2015-03-04,2015-01-18
-6xpy,2021-05-19,2020-07-09
-2xp0,2010-09-29,2010-08-24
-1xpm,2004-11-02,2004-10-08
-4xp4,2015-05-06,2015-01-16
-8xpt,2024-01-24,2024-01-04
-6xp2,2020-11-04,2020-07-07
-1xph,2005-04-19,2004-10-08
-4xp3,2015-08-12,2015-01-16
-7xpl,2022-10-05,2022-05-04
-1xpz,2005-05-17,2004-10-11
-4xpc,2015-05-27,2015-01-16
-5xpm,2018-06-06,2017-06-03
-1xp6,2004-12-07,2004-10-08
-5xp9,2018-03-07,2017-06-01
-5xpi,2018-04-25,2017-06-02
-6xpd,2020-08-05,2020-07-08
-4xph,2015-05-06,2015-01-17
-7xpy,2022-08-24,2022-05-06
-4xpa,2015-05-20,2015-01-16
-7xpi,2023-06-14,2022-05-04
-6xpa,2021-01-06,2020-07-08
-2xpa,2011-01-12,2010-08-25
-4xpf,2015-05-06,2015-01-16
-5xpl,2018-06-06,2017-06-03
-6xpv,2020-11-04,2020-07-09
-6xpb,2020-11-25,2020-07-08
-2xpz,2010-12-29,2010-08-31
-1xpy,2004-10-26,2004-10-10
-2xpv,2011-09-07,2010-08-30
-6xpn,2020-08-26,2020-07-08
-5xp7,2017-09-06,2017-06-01
-1xpq,2005-04-26,2004-10-09
-6xpx,2021-05-19,2020-07-09
-5xp0,2018-06-20,2017-05-31
-6xp7,2020-11-04,2020-07-08
-5xp6,2018-03-07,2017-06-01
-1xp5,2005-01-04,2004-10-08
-5xp8,2018-04-18,2017-06-01
-1xp0,2004-12-14,2004-10-07
-8xpb,2024-05-29,2024-01-03
-2xp8,2011-01-12,2010-08-25
-8xpc,2024-01-31,2024-01-03
-1xpu,2004-11-02,2004-10-09
-5xpf,2017-10-04,2017-06-01
-5xpo,2018-06-06,2017-06-03
-5xpa,2018-04-18,2017-06-01
-2xpb,2011-01-12,2010-08-25
-6xp9,2020-09-23,2020-07-08
-2xp7,2011-01-12,2010-08-25
-7xpt,2023-03-29,2022-05-05
-7xpu,2023-03-29,2022-05-05
-4xpn,2015-07-01,2015-01-17
-8xpd,2024-01-31,2024-01-03
-6xpu,2020-11-04,2020-07-09
-4xp2,2015-08-12,2015-01-16
-1xpl,2004-11-02,2004-10-08
-1xp1,2004-12-07,2004-10-07
-6xp6,2021-07-28,2020-07-08
-6xpc,2020-11-25,2020-07-08
-7xpv,2023-03-29,2022-05-05
-1xpr,2004-11-02,2004-10-09
-5xpp,2018-06-06,2017-06-03
-5xps,2018-06-06,2017-06-04
-4xpe,2015-05-27,2015-01-16
-8xpv,2024-01-24,2024-01-04
-5xpr,2017-08-16,2017-06-04
-2xp5,2011-01-12,2010-08-25
-4xpj,2015-07-15,2015-01-17
-4xps,2015-05-20,2015-01-17
-4xp1,2015-05-06,2015-01-16
-5xpx,2018-06-20,2017-06-05
-6xpf,2020-08-05,2020-07-08
-4xpt,2015-05-06,2015-01-17
-6xps,2020-11-04,2020-07-08
-8xp8,2024-05-29,2024-01-03
-6xpz,2021-05-19,2020-07-09
-6xpt,2020-11-04,2020-07-09
-6xpm,2020-07-15,2020-07-08
-4xpy,2015-04-29,2015-01-18
-7xp7,2023-02-08,2022-05-03
-2xp6,2011-01-12,2010-08-25
-5xp5,2018-02-07,2017-06-01
-2xph,2010-09-08,2010-08-26
-6xpr,2021-05-19,2020-07-08
-7xp6,2022-10-12,2022-05-03
-4xpb,2015-05-13,2015-01-16
-1xpo,2005-02-08,2004-10-09
-2xp2,2010-09-15,2010-08-24
-2xpc,2011-05-18,2010-08-26
-2xpg,2011-04-27,2010-08-26
-1xpg,2005-03-01,2004-10-08
-6xpe,2020-08-05,2020-07-08
-1xpc,2004-12-07,2004-10-08
-2xp3,2011-01-12,2010-08-25
-4xpd,2016-07-20,2015-01-16
-8xpn,2024-03-06,2024-01-04
-2xpk,2011-03-16,2010-08-26
-4xp5,2015-05-06,2015-01-16
-6xpo,2021-05-19,2020-07-08
-2wrx,2010-02-09,2009-09-02
-1wro,2005-08-30,2004-10-25
-7wra,2022-06-22,2022-01-26
-7wre,2022-06-22,2022-01-26
-7wr5,2023-01-25,2022-01-26
-3wri,2015-03-18,2014-02-25
-3wry,2014-08-13,2014-02-27
-6wr2,2020-11-04,2020-04-29
-3wrs,2015-01-21,2014-02-27
-7wrd,2022-06-22,2022-01-26
-6wrx,2021-04-28,2020-04-30
-1wrv,2005-10-18,2004-10-27
-4wrq,2015-05-06,2014-10-24
-1wrn,2005-08-30,2004-10-25
-6wre,2020-05-13,2020-04-29
-4wrc,2016-02-10,2014-10-23
-6wrk,2020-07-01,2020-04-29
-6wrz,2020-05-13,2020-04-30
-1wrq,2005-08-30,2004-10-25
-5wrr,2017-05-03,2016-12-03
-4wra,2015-06-10,2014-10-23
-6wrn,2020-07-01,2020-04-29
-7wrb,2022-06-22,2022-01-26
-4wrl,2015-08-12,2014-10-24
-7wrf,2022-06-22,2022-01-26
-4wrh,2014-11-05,2014-10-24
-5wr2,2017-08-16,2016-11-29
-3wrq,2015-01-21,2014-02-27
-2wr7,2009-09-29,2009-08-30
-7wrx,2023-02-01,2022-01-27
-5wr7,2017-12-06,2016-11-30
-7wru,2022-11-23,2022-01-27
-3wrj,2015-03-18,2014-02-25
-5wr3,2017-08-16,2016-11-29
-4wr6,2015-06-10,2014-10-23
-2wra,2009-09-29,2009-09-01
-5wr9,2017-12-06,2016-12-01
-8wrh,2023-11-29,2023-10-14
-6wrh,2020-05-06,2020-04-29
-6wrt,2020-07-01,2020-04-30
-4wro,2015-06-10,2014-10-24
-3wr1,2014-03-05,2014-02-09
-6wr4,2020-07-08,2020-04-29
-5wr6,2017-08-16,2016-11-29
-7wr9,2023-02-01,2022-01-26
-3wrm,2015-03-18,2014-02-25
-4wru,2015-07-15,2014-10-25
-4wrs,2015-02-04,2014-10-25
-4wrf,2016-02-10,2014-10-23
-4wrv,2015-07-15,2014-10-25
-3wr7,2015-09-02,2014-02-20
-2wr1,2009-09-29,2009-08-29
-3wr3,2014-04-30,2014-02-13
-2wrs,2010-06-23,2009-09-02
-5wrv,2017-06-21,2016-12-04
-5wrk,2017-12-06,2016-12-02
-3wr5,2015-02-25,2014-02-16
-2wrh,2009-09-29,2009-09-01
-2wrb,2009-09-29,2009-09-01
-6wrv,2021-04-28,2020-04-30
-7wrh,2023-02-01,2022-01-26
-2wr9,2009-09-15,2009-09-01
-7wrp,2022-02-23,2022-01-27
-7wrz,2022-06-22,2022-01-28
-3wrc,2014-04-30,2014-02-21
-6wrm,2020-12-16,2020-04-29
-3wrn,2015-01-21,2014-02-27
-7wrr,2022-12-07,2022-01-27
-8wr4,2024-06-05,2023-10-13
-7wri,2022-06-08,2022-01-26
-4wri,2015-05-27,2014-10-24
-2wre,2009-09-29,2009-09-01
-4wrk,2015-12-23,2014-10-24
-1wrr,2005-03-22,2004-10-27
-7wrc,2022-06-22,2022-01-26
-5wrc,2017-11-29,2016-12-01
-5wrz,2017-01-25,2016-12-04
-8wr2,2024-03-20,2023-10-12
-2wr2,2009-09-29,2009-08-29
-3wr4,2014-04-30,2014-02-13
-6wrr,2020-11-18,2020-04-30
-3wrx,2014-08-13,2014-02-27
-2wrg,2009-09-29,2009-09-01
-4wr3,2015-11-04,2014-10-23
-5wrb,2017-12-20,2016-12-01
-7wr8,2022-06-22,2022-01-26
-3wrg,2014-09-03,2014-02-25
-3wr9,2014-04-30,2014-02-21
-3wrb,2014-04-30,2014-02-21
-7wrt,2022-12-07,2022-01-27
-4wrz,2015-07-15,2014-10-25
-4wr8,2015-03-11,2014-10-23
-5wrn,2016-12-14,2016-12-02
-8wrj,2024-01-24,2023-10-15
-1wrp,1988-04-16,1987-12-01
-3wrh,2015-03-18,2014-02-25
-6wro,2020-11-18,2020-04-29
-6wrf,2020-11-04,2020-04-29
-2wr0,2009-09-29,2009-08-28
-3wro,2015-01-21,2014-02-27
-4wrb,2015-03-11,2014-10-23
-1wra,2005-05-31,2004-10-13
-7wr7,2022-10-26,2022-01-26
-6wrl,2020-12-16,2020-04-29
-7wrg,2022-08-10,2022-01-26
-5wro,2017-04-26,2016-12-02
-1wrl,2006-01-24,2004-10-20
-8wrz,2024-02-28,2023-10-16
-3wrr,2015-01-21,2014-02-27
-2wr8,2009-09-22,2009-08-31
-3wrl,2015-03-18,2014-02-25
-5wra,2017-12-06,2016-12-01
-3wre,2014-09-03,2014-02-25
-7wrq,2022-08-10,2022-01-27
-2wr3,2009-09-29,2009-08-29
-3wrk,2015-03-18,2014-02-25
-2wr4,2009-09-29,2009-08-29
-8wrb,2023-11-08,2023-10-13
-4wrd,2015-07-08,2014-10-23
-5wrm,2017-12-06,2016-12-02
-1wrs,1996-06-20,1995-05-12
-4wr2,2014-11-12,2014-10-22
-4wr9,2016-02-10,2014-10-23
-5wr4,2017-08-16,2016-11-29
-4wr4,2015-08-19,2014-10-23
-4wre,2016-02-10,2014-10-23
-2wrf,2009-09-29,2009-09-01
-7wrk,2022-03-09,2022-01-27
-5wre,2017-02-22,2016-12-01
-3wr2,2015-02-18,2014-02-13
-4wrn,2016-01-27,2014-10-24
-7wry,2022-09-28,2022-01-27
-6wrq,2020-07-01,2020-04-29
-5wr5,2017-08-16,2016-11-29
-7wr3,2023-01-25,2022-01-26
-7wrj,2022-09-28,2022-01-26
-3wra,2014-04-30,2014-02-21
-6wr1,2021-05-05,2020-04-29
-8wrk,2024-01-24,2023-10-15
-4wr7,2015-07-01,2014-10-23
-6wry,2020-11-25,2020-04-30
-6wrw,2021-04-28,2020-04-30
-7wr6,2023-01-25,2022-01-26
-5wrl,2017-12-06,2016-12-02
-1wr5,2004-10-26,2004-10-11
-2wrm,2010-09-22,2009-09-01
-5wry,2017-01-25,2016-12-04
-1wrz,2006-03-21,2004-10-29
-1wrk,2006-01-24,2004-10-20
-4wrg,2014-11-05,2014-10-23
-8wrl,2023-11-29,2023-10-15
-3wrz,2015-03-04,2014-02-27
-4wry,2015-07-15,2014-10-25
-4wrr,2014-11-05,2014-10-24
-5wri,2017-09-13,2016-12-02
-4wr5,2015-08-19,2014-10-23
-5wrt,2017-10-11,2016-12-03
-5wrs,2017-05-03,2016-12-03
-6wr0,2021-05-05,2020-04-29
-3wr8,2014-04-30,2014-02-21
-3wr0,2015-03-11,2014-02-06
-5wrq,2017-01-25,2016-12-03
-8vc5,2023-12-27,2023-12-13
-7vcs,2022-03-02,2021-09-03
-5vcq,2018-04-04,2017-03-31
-5vcm,2018-04-11,2017-03-31
-2vcn,2007-12-04,2007-09-25
-6vce,2020-07-01,2019-12-20
-5vcb,2017-11-01,2017-03-31
-1vcv,2005-08-02,2004-03-15
-7vcv,2022-03-02,2021-09-04
-6vc2,2020-12-23,2019-12-20
-5vcn,2017-04-26,2017-03-31
-2vcx,2008-04-15,2007-09-27
-1vc5,2004-05-18,2004-03-04
-2vcb,2008-03-18,2007-09-19
-6vc3,2020-10-28,2019-12-20
-3vca,2012-02-08,2012-01-03
-5vcp,2017-05-03,2017-03-31
-5vcg,2017-05-31,2017-03-31
-2vcd,2008-09-02,2007-09-20
-2vcc,2008-03-18,2007-09-19
-7vcl,2022-08-03,2021-09-03
-8vcn,2024-03-13,2023-12-14
-1vcz,2005-04-26,2004-03-17
-6vcl,2020-02-05,2019-12-21
-7vc2,2022-09-07,2021-09-01
-5vcx,2017-08-23,2017-04-01
-7vcn,2022-07-13,2021-09-03
-5vck,2018-04-18,2017-03-31
-2vci,2007-12-11,2007-09-24
-2vct,2008-10-28,2007-09-27
-3vc1,2012-04-11,2012-01-03
-6vcp,2020-02-05,2019-12-21
-2vc7,2008-04-15,2007-09-19
-7vc8,2022-09-07,2021-09-01
-5vc5,2017-08-23,2017-03-31
-3vc2,2012-04-11,2012-01-03
-6vcn,2020-02-05,2019-12-21
-1vc8,2005-04-26,2004-03-05
-1vcr,2004-03-30,2004-03-10
-7vc7,2022-02-09,2021-09-01
-6vcy,2020-02-26,2019-12-23
-2vcf,2007-12-04,2007-09-21
-6vch,2020-07-08,2019-12-20
-3vcz,2012-01-25,2012-01-04
-6vco,2020-02-05,2019-12-21
-1vcg,2005-04-19,2004-03-08
-1vcx,2004-08-10,2004-03-17
-5vce,2017-05-31,2017-03-31
-1vct,2005-03-22,2004-03-12
-2vca,2008-03-18,2007-09-19
-1vcl,2004-09-07,2004-03-09
-6vcf,2020-07-08,2019-12-20
-2vcq,2008-04-15,2007-09-26
-5vc4,2017-08-23,2017-03-30
-1vcu,2004-11-02,2004-03-12
-3vcy,2012-04-11,2012-01-04
-5vcy,2017-08-23,2017-04-01
-1vco,2004-08-31,2004-03-10
-6vcx,2020-02-26,2019-12-23
-6vcq,2020-02-05,2019-12-21
-3vc4,2012-03-21,2012-01-03
-2vcm,2008-11-04,2007-09-25
-7vcp,2022-03-09,2021-09-03
-3vcn,2012-01-25,2012-01-04
-5vcv,2017-08-23,2017-04-01
-6vcu,2020-12-16,2019-12-23
-1vcf,2005-04-19,2004-03-08
-5vcw,2017-08-23,2017-04-01
-5vcs,2018-04-11,2017-03-31
-6vc9,2020-11-11,2019-12-20
-7vc5,2022-09-07,2021-09-01
-6vc8,2021-02-10,2019-12-20
-5vco,2017-04-26,2017-03-31
-7vc1,2022-09-07,2021-09-01
-1vc9,2005-04-26,2004-03-05
-5vc0,2017-05-31,2017-03-30
-6vc6,2020-12-23,2019-12-20
-3vcm,2012-05-23,2012-01-04
-5vc6,2017-08-23,2017-03-31
-6vc4,2020-10-28,2019-12-20
-1vce,2005-03-29,2004-03-07
-6vcg,2020-07-08,2019-12-20
-5vcz,2017-08-23,2017-04-01
-7vcu,2022-03-02,2021-09-04
-6vcr,2020-02-05,2019-12-21
-7vcf,2022-11-30,2021-09-02
-2vc0,2007-11-06,2007-09-18
-2vc9,2008-03-18,2007-09-19
-2vcv,2008-10-28,2007-09-27
-2vc5,2008-04-15,2007-09-18
-5vc7,2017-04-26,2017-03-31
-5vcd,2017-05-31,2017-03-31
-2vcw,2008-04-15,2007-09-27
-5vc9,2017-06-28,2017-03-31
-5vcu,2017-05-03,2017-03-31
-1vci,2004-12-14,2004-03-08
-2vch,2007-10-09,2007-09-24
-1vc2,2004-03-16,2004-03-04
-3vc6,2012-02-01,2012-01-03
-6vcv,2020-12-16,2019-12-23
-2vcp,2008-11-04,2007-09-26
-6vcj,2020-10-28,2019-12-21
-3vcr,2012-01-18,2012-01-04
-2vcz,2008-04-15,2007-09-28
-5vc3,2017-08-23,2017-03-30
-6vcw,2020-02-26,2019-12-23
-7vct,2022-03-02,2021-09-04
-7vcx,2022-03-02,2021-09-04
-2vcs,2007-12-04,2007-09-26
-2vco,2008-05-13,2007-09-26
-6vca,2020-11-11,2019-12-20
-7vch,2022-12-14,2021-09-03
-6vcb,2020-07-22,2019-12-20
-3vcl,2012-11-21,2012-01-04
-6vcz,2020-02-26,2019-12-23
-3vcc,2013-01-09,2012-01-03
-5vc1,2017-06-14,2017-03-30
-1vck,2005-03-01,2004-03-09
-1vcj,2004-03-23,2004-03-09
-5vcj,2018-04-04,2017-03-31
-8vc1,2024-01-10,2023-12-13
-8vc8,2024-03-20,2023-12-13
-6vcm,2020-02-05,2019-12-21
-2vcj,2007-12-11,2007-09-24
-2vc1,2007-11-06,2007-09-18
-6vck,2020-02-05,2019-12-21
-2vc2,2008-09-02,2007-09-18
-6vc7,2020-08-26,2019-12-20
-1vc6,2004-05-18,2004-03-04
-2vcg,2008-01-08,2007-09-24
-5vcr,2018-04-11,2017-03-31
-7vcm,2022-07-27,2021-09-03
-6vc1,2020-12-23,2019-12-20
-5vcc,2017-05-31,2017-03-31
-2vck,2008-08-05,2007-09-25
-6vct,2020-12-16,2019-12-23
-7vc3,2022-09-07,2021-09-01
-7vc6,2022-02-09,2021-09-01
-2vce,2007-10-16,2007-09-20
-3vcp,2012-02-08,2012-01-04
-8vcw,2024-01-24,2023-12-14
-3vc3,2012-09-12,2012-01-03
-5vcl,2017-10-25,2017-03-31
-1vcp,1996-12-07,1996-03-04
-1vch,2005-03-22,2004-03-08
-7vc0,2022-04-06,2021-09-01
-5pu0,2017-03-29,2017-02-07
-4pu5,2014-08-06,2014-03-12
-4pun,2014-07-16,2014-03-13
-5puc,2017-03-29,2017-02-07
-3pue,2010-12-22,2010-12-04
-6puj,2020-02-19,2019-07-18
-3pua,2011-01-26,2010-12-03
-2pup,2007-05-22,2007-05-09
-5puo,2017-03-29,2017-02-07
-6puv,2020-07-22,2019-07-18
-2pu4,2008-04-15,2007-05-08
-2pu2,2008-04-15,2007-05-08
-1pu8,2003-10-07,2003-06-24
-2put,2007-09-11,2007-05-09
-7pug,2022-01-19,2021-09-29
-2puc,1998-05-06,1997-10-04
-7pue,2021-12-01,2021-09-29
-7puw,2022-01-12,2021-09-30
-2pul,2007-05-22,2007-05-09
-5pu9,2017-03-29,2017-02-07
-2pu3,2008-03-18,2007-05-08
-5pug,2017-03-29,2017-02-07
-3pug,2011-06-01,2010-12-04
-2pui,2007-05-22,2007-05-09
-5puv,2017-03-29,2017-02-07
-7pu6,2022-07-06,2021-09-28
-5pur,2017-03-29,2017-02-07
-2pub,1998-05-06,1997-10-04
-1pu4,2005-05-03,2003-06-24
-3pu8,2011-01-26,2010-12-03
-1pun,2003-08-26,2003-06-25
-2pug,1998-05-06,1997-10-04
-6pu2,2019-10-09,2019-07-16
-7pur,2021-11-10,2021-09-30
-5puy,2017-03-29,2017-02-07
-1pud,1997-07-07,1996-06-28
-3puy,2011-05-18,2010-12-06
-3pun,2011-08-03,2010-12-06
-6puu,2019-09-25,2019-07-18
-7pux,2022-12-14,2021-10-01
-4pul,2014-07-16,2014-03-13
-6puc,2020-02-19,2019-07-18
-4puc,2014-06-04,2014-03-12
-7puj,2022-03-16,2021-09-30
-5pui,2017-03-29,2017-02-07
-8pum,2024-03-20,2023-07-17
-7puc,2022-04-06,2021-09-29
-7pu9,2022-08-17,2021-09-28
-7pup,2022-10-12,2021-09-30
-2puu,2008-05-20,2007-05-09
-3pui,2011-09-21,2010-12-04
-5puf,2017-03-29,2017-02-07
-1pua,2003-09-23,2003-06-24
-7pu1,2022-03-16,2021-09-28
-5pu8,2017-03-29,2017-02-07
-7puq,2022-04-06,2021-09-30
-6pug,2020-02-19,2019-07-18
-5puj,2017-03-29,2017-02-07
-5pup,2017-03-29,2017-02-07
-6pue,2020-02-19,2019-07-18
-2puz,2007-05-22,2007-05-09
-2pue,1998-05-06,1997-10-04
-8puy,2023-12-13,2023-07-17
-5pu3,2017-03-29,2017-02-07
-3puq,2011-01-26,2010-12-06
-8pur,2023-10-18,2023-07-17
-1pup,1997-02-25,1996-11-01
-7pul,2022-03-16,2021-09-30
-5puw,2017-03-29,2017-02-07
-2pur,2008-05-27,2007-05-09
-4puz,2014-04-23,2014-03-14
-3pu7,2011-12-21,2010-12-03
-2puh,2007-05-22,2007-05-09
-7pu0,2022-01-19,2021-09-28
-5pue,2017-03-29,2017-02-07
-3pu9,2010-12-22,2010-12-03
-6pu8,2020-06-24,2019-07-17
-4put,2014-05-14,2014-03-13
-1pu7,2003-10-07,2003-06-24
-8puq,2023-10-18,2023-07-17
-8pun,2023-08-02,2023-07-17
-6put,2020-02-12,2019-07-18
-2puw,2007-09-11,2007-05-09
-6puq,2020-07-22,2019-07-18
-6puh,2020-02-19,2019-07-18
-4puj,2014-07-16,2014-03-13
-4pua,2014-04-09,2014-03-12
-6puw,2020-02-12,2019-07-18
-3pus,2011-01-26,2010-12-06
-6pu7,2019-12-04,2019-07-17
-5pu2,2017-03-29,2017-02-07
-5puu,2017-03-29,2017-02-07
-4puv,2014-12-24,2014-03-14
-6pu4,2019-08-28,2019-07-17
-4pu6,2014-09-03,2014-03-12
-1pu0,2003-09-09,2003-06-23
-5puq,2017-03-29,2017-02-07
-5pub,2017-03-29,2017-02-07
-3puj,2011-01-19,2010-12-05
-2pun,2007-05-22,2007-05-09
-5pus,2017-03-29,2017-02-07
-1pu9,2003-09-23,2003-06-24
-5pu5,2017-03-29,2017-02-07
-6pu5,2019-08-28,2019-07-17
-1pum,2004-06-25,2003-06-25
-3puk,2011-01-19,2010-12-05
-7puh,2022-01-19,2021-09-30
-5pu4,2017-03-29,2017-02-07
-3puo,2010-12-29,2010-12-06
-6pus,2019-09-25,2019-07-18
-4puo,2014-06-18,2014-03-13
-2puj,2007-05-22,2007-05-09
-1puq,2003-08-26,2003-06-25
-4pu0,2014-06-18,2014-03-11
-4pu9,2014-09-24,2014-03-12
-5pud,2017-03-29,2017-02-07
-6pu6,2020-07-22,2019-07-17
-3puv,2011-08-10,2010-12-06
-5put,2017-03-29,2017-02-07
-7pu8,2022-04-06,2021-09-28
-7puk,2022-03-16,2021-09-30
-6pur,2019-09-25,2019-07-18
-7pui,2022-10-05,2021-09-30
-6pui,2020-02-19,2019-07-18
-2pux,2007-07-10,2007-05-09
-7pus,2022-05-11,2021-09-30
-4puw,2015-04-08,2014-03-14
-6pul,2020-02-19,2019-07-18
-5puz,2017-03-29,2017-02-07
-4pud,2015-03-18,2014-03-13
-7put,2022-04-06,2021-09-30
-6pum,2020-02-19,2019-07-18
-8pux,2023-12-13,2023-07-17
-3pux,2011-08-10,2010-12-06
-6pun,2019-08-21,2019-07-18
-4puu,2015-04-08,2014-03-14
-2puy,2007-08-14,2007-05-09
-3puw,2011-08-10,2010-12-06
-7puu,2022-01-12,2021-09-30
-5pul,2017-03-29,2017-02-07
-1pus,2003-08-26,2003-06-25
-2puf,1998-05-06,1997-10-04
-1puu,2004-06-25,2003-06-25
-4pum,2014-07-16,2014-03-13
-2pud,1998-05-06,1997-10-04
-6pux,2019-07-31,2019-07-18
-6puf,2020-02-19,2019-07-18
-2pum,2007-05-22,2007-05-09
-5pux,2017-03-29,2017-02-07
-4puk,2014-07-16,2014-03-13
-7pub,2022-05-04,2021-09-29
-6puy,2020-02-12,2019-07-18
-7pu5,2022-03-16,2021-09-28
-3puz,2011-05-18,2010-12-06
-2pua,1998-05-06,1997-10-04
-7puf,2022-02-09,2021-09-29
-5pum,2017-03-29,2017-02-07
-5pu6,2017-03-29,2017-02-07
-5pun,2017-03-29,2017-02-07
-4pu2,2014-06-25,2014-03-11
-2pu1,2007-11-20,2007-05-08
-6puk,2020-02-19,2019-07-18
-5pu7,2017-03-29,2017-02-07
-5pua,2017-03-29,2017-02-07
-2pu7,2007-05-22,2007-05-08
-6pu3,2019-08-21,2019-07-16
-5puk,2017-03-29,2017-02-07
-5pu1,2017-03-29,2017-02-07
-3puu,2011-11-16,2010-12-06
-3pul,2010-12-29,2010-12-06
-4pue,2015-03-18,2014-03-13
-6puz,2020-02-12,2019-07-18
-2pu0,2007-11-20,2007-05-08
-2puv,2007-09-11,2007-05-09
-1puj,2003-07-08,2003-06-24
-7puv,2022-01-12,2021-09-30
-7pua,2022-03-02,2021-09-29
-6pu0,2019-09-04,2019-07-16
-3pup,2010-12-22,2010-12-06
-2puo,2007-07-10,2007-05-09
-7pu7,2022-02-23,2021-09-28
-6pub,2019-09-25,2019-07-18
-7puy,2021-12-29,2021-10-01
-6pup,2020-07-29,2019-07-18
-8pu0,2024-04-17,2023-07-16
-2puq,2007-05-22,2007-05-09
-6pud,2020-02-19,2019-07-18
-3pur,2011-01-26,2010-12-06
-4puq,2014-05-14,2014-03-13
-5puh,2017-03-29,2017-02-07
-1iv2,2002-09-11,2002-03-11
-5iv3,2016-08-17,2016-03-18
-8iv4,2023-08-16,2023-03-26
-8ivp,2024-01-24,2023-03-28
-4ivb,2013-05-22,2013-01-22
-4ivr,2013-02-06,2013-01-23
-6iv3,2019-11-13,2018-12-02
-8iva,2023-08-16,2023-03-26
-3iv3,2009-09-22,2009-08-31
-5iv5,2016-05-18,2016-03-19
-3ivv,2009-10-20,2009-09-01
-4ivo,2013-03-06,2013-01-23
-3ivt,2009-09-22,2009-09-01
-5ivg,2016-05-25,2016-03-20
-4ivk,2013-06-19,2013-01-23
-3ivz,2010-09-22,2009-09-02
-5ivi,2016-06-15,2016-03-20
-3ivd,2009-09-29,2009-08-31
-2ivz,2006-08-16,2006-06-23
-8ivm,2023-08-02,2023-03-28
-6iv8,2019-06-19,2018-12-02
-4iv8,2014-02-19,2013-01-22
-6ivm,2019-11-06,2018-12-04
-4ivw,2013-03-27,2013-01-23
-5ivz,2016-10-26,2016-03-21
-6iv9,2019-06-19,2018-12-02
-1ivv,2002-08-07,2002-03-29
-1ivc,1995-03-31,1994-12-12
-6ivj,2019-11-06,2018-12-04
-2ivh,2007-01-02,2006-06-13
-1iv4,2002-09-11,2002-03-11
-1ivq,1993-07-15,1993-03-18
-8iv0,2024-04-24,2023-03-25
-3iv8,2009-09-08,2009-08-31
-8ivs,2023-08-02,2023-03-28
-3ivc,2009-10-13,2009-08-31
-1ivw,2002-08-07,2002-03-29
-2iv3,2006-10-11,2006-06-08
-3ivi,2010-01-05,2009-09-01
-6ivl,2019-11-06,2018-12-04
-4ivf,2013-02-13,2013-01-22
-2ivs,2006-08-14,2006-06-16
-2ivj,2007-04-10,2006-06-13
-3ivb,2009-10-20,2009-08-31
-5ivb,2016-07-27,2016-03-20
-5ivf,2016-07-27,2016-03-20
-5ivj,2016-07-27,2016-03-21
-2ivi,2007-04-10,2006-06-13
-8ivf,2024-02-28,2023-03-27
-2ive,2006-10-17,2006-06-13
-6ive,2019-04-03,2018-12-03
-1ivd,1995-03-31,1994-12-12
-4iv0,2014-02-19,2013-01-22
-6ivo,2019-11-06,2018-12-04
-2iv8,2007-06-12,2006-06-08
-1ivx,2002-08-07,2002-03-29
-3iv9,2009-11-24,2009-08-31
-1ivy,1997-04-21,1996-06-12
-8ivr,2023-06-14,2023-03-28
-1iv3,2002-09-11,2002-03-11
-4iv6,2013-03-20,2013-01-22
-6iv5,2019-02-27,2018-12-02
-4ivt,2013-11-13,2013-01-23
-8iv3,2024-02-07,2023-03-25
-8ivl,2024-02-28,2023-03-28
-6ivr,2019-11-06,2018-12-04
-2ivt,2006-08-14,2006-06-16
-3ivq,2009-10-20,2009-09-01
-2iv0,2007-04-17,2006-06-08
-5ivk,2016-06-22,2016-03-21
-4ivp,2013-02-06,2013-01-23
-3ivh,2010-01-05,2009-09-01
-8iv5,2023-08-16,2023-03-26
-1ivr,1997-07-23,1996-10-11
-2iv7,2006-10-11,2006-06-08
-5ivc,2016-07-27,2016-03-20
-8ivn,2023-08-02,2023-03-28
-4iva,2013-05-22,2013-01-22
-3ivs,2009-09-22,2009-09-01
-3iv6,2009-09-15,2009-08-31
-1ive,1995-03-31,1994-12-12
-3ivg,2009-10-13,2009-09-01
-5iv4,2016-08-17,2016-03-18
-8ive,2023-08-02,2023-03-27
-4ivy,2013-03-27,2013-01-23
-3ivu,2009-09-22,2009-09-01
-2ivp,2007-07-31,2006-06-14
-1ivj,2002-12-11,2002-03-18
-6ivq,2019-11-06,2018-12-04
-4ivs,2013-11-13,2013-01-23
-2ivf,2006-09-14,2006-06-13
-8ivy,2023-08-23,2023-03-29
-6ivk,2019-11-06,2018-12-04
-1ivu,2002-08-07,2002-03-29
-3iv2,2010-03-23,2009-08-31
-3ive,2009-09-29,2009-08-31
-6iv4,2019-11-13,2018-12-02
-1ivs,2003-02-11,2002-03-29
-5ivt,2016-05-18,2016-03-21
-1ivp,1993-07-15,1993-03-18
-4iv4,2013-03-27,2013-01-22
-1ivg,1995-03-31,1994-12-12
-5ivs,2016-05-18,2016-03-21
-6iv7,2019-02-06,2018-12-02
-6ivn,2019-11-06,2018-12-04
-8ivt,2023-08-02,2023-03-28
-5ivr,2016-05-18,2016-03-21
-4ivn,2013-07-17,2013-01-23
-4iv3,2013-04-17,2013-01-22
-1ivf,1995-03-31,1994-12-12
-2iv9,2007-03-13,2006-06-08
-8ivg,2023-06-14,2023-03-27
-5ivq,2016-05-18,2016-03-21
-6iv1,2019-11-13,2018-12-02
-8ivu,2023-10-11,2023-03-28
-8iv8,2023-08-16,2023-03-26
-2ivv,2006-08-14,2006-06-16
-5ivy,2016-07-27,2016-03-21
-3ivx,2009-10-13,2009-09-02
-3ivm,2010-05-05,2009-09-01
-5iv0,2017-01-11,2016-03-18
-6iv2,2019-11-13,2018-12-02
-6ivy,2019-12-04,2018-12-04
-4iv9,2013-04-10,2013-01-22
-6ivp,2019-11-06,2018-12-04
-3ivy,2009-11-03,2009-09-02
-5iv2,2016-10-26,2016-03-18
-5ivv,2016-07-27,2016-03-21
-4ivh,2013-07-31,2013-01-22
-4ivd,2013-05-22,2013-01-22
-2ivd,2006-10-17,2006-06-12
-4ivc,2013-05-22,2013-01-22
-3iva,2009-11-24,2009-08-31
-2ivn,2007-07-31,2006-06-14
-6ivx,2019-03-06,2018-12-04
-3ivk,2010-03-02,2009-09-01
-4ivq,2013-02-06,2013-01-23
-4ivv,2014-01-29,2013-01-23
-8ivh,2024-04-10,2023-03-27
-6iv0,2019-11-13,2018-12-02
-4iv2,2013-03-27,2013-01-22
-4ivg,2014-01-22,2013-01-22
-2ivu,2006-08-10,2006-06-16
-6ivw,2019-11-13,2018-12-04
-1ivo,2002-10-16,2002-03-28
-4ivm,2013-03-06,2013-01-23
-5ive,2016-07-27,2016-03-20
-1ivb,1995-03-31,1994-12-12
-1ivh,1998-05-20,1997-05-15
-7ehn,2021-08-11,2021-03-30
-7eh2,2021-07-14,2021-03-27
-1eh7,2000-04-12,2000-02-18
-4eh1,2012-04-25,2012-04-02
-4ehl,2012-06-06,2012-04-02
-2ehq,2007-05-01,2007-03-07
-6eho,2017-12-06,2017-09-14
-5ehj,2016-05-04,2015-10-28
-1ehi,2000-05-23,2000-02-21
-4ehz,2012-07-04,2012-04-04
-5eht,2016-09-07,2015-10-28
-5eho,2016-11-09,2015-10-28
-2ehb,2007-09-25,2007-03-06
-5ehl,2016-11-09,2015-10-28
-1ehh,2000-04-05,2000-02-21
-4ehe,2013-04-24,2012-04-02
-4eh8,2012-12-05,2012-04-02
-7ehq,2021-07-07,2021-03-30
-7eh5,2021-09-01,2021-03-28
-1eh6,2000-04-12,2000-02-18
-6ehk,2018-02-28,2017-09-13
-3ehb,2008-09-30,2008-09-12
-1ehg,2000-08-21,2000-02-21
-4ehv,2012-12-05,2012-04-04
-1ehb,2000-08-09,2000-02-20
-4ehh,2012-06-06,2012-04-02
-1eh3,2000-03-01,2000-02-18
-1ehj,2000-05-10,2000-02-21
-3eh5,2009-04-21,2008-09-11
-7eh7,2021-11-17,2021-03-28
-8ehi,2023-03-01,2022-09-14
-5ehp,2016-07-06,2015-10-28
-5ehc,2016-09-07,2015-10-28
-7ehf,2021-08-11,2021-03-29
-3eh2,2008-10-21,2008-09-11
-6eh2,2018-10-10,2017-09-12
-4eh5,2012-12-05,2012-04-02
-3eha,2009-04-28,2008-09-11
-3ehg,2009-09-15,2008-09-12
-6ehh,2018-01-10,2017-09-13
-3eh8,2009-01-13,2008-09-11
-6ehu,2018-02-28,2017-09-15
-5ehw,2016-03-09,2015-10-29
-2eh2,2007-09-04,2007-03-02
-8ehq,2023-02-01,2022-09-14
-8ehf,2023-03-01,2022-09-14
-4ehk,2012-06-06,2012-04-02
-4eht,2012-08-08,2012-04-04
-3ehx,2009-05-19,2008-09-15
-3eh3,2009-04-21,2008-09-11
-5ehy,2016-04-20,2015-10-29
-2ehe,2007-09-11,2007-03-06
-2eh5,2007-09-04,2007-03-04
-1ehl,2001-02-21,2000-02-21
-8ehe,2022-12-21,2022-09-14
-7ehi,2021-08-11,2021-03-29
-1ehf,2000-08-21,2000-02-21
-3eht,2008-09-30,2008-09-14
-5eh8,2016-03-09,2015-10-28
-6ehj,2019-03-27,2017-09-13
-8ehz,2023-10-25,2022-09-14
-8eho,2023-12-06,2022-09-14
-6eh3,2018-10-10,2017-09-12
-1ehk,2001-02-22,2000-02-21
-2eha,2007-04-24,2007-03-06
-8eh0,2023-10-04,2022-09-13
-5ehe,2016-11-09,2015-10-28
-5eh9,2016-09-07,2015-10-28
-8ehp,2023-02-22,2022-09-14
-4ehq,2012-11-07,2012-04-03
-2ehd,2008-03-11,2007-03-06
-5ehz,2016-01-20,2015-10-29
-1eh8,2000-04-12,2000-02-18
-3ehs,2008-09-30,2008-09-14
-1ehe,2000-08-21,2000-02-21
-7ehh,2021-08-11,2021-03-29
-3eh1,2008-10-21,2008-09-11
-6ehq,2018-04-18,2017-09-14
-3ehe,2008-10-14,2008-09-12
-4ehd,2012-06-06,2012-04-02
-7ehe,2021-06-30,2021-03-29
-2ehl,2007-09-11,2007-03-07
-3ehn,2009-05-12,2008-09-13
-4ehb,2013-08-07,2012-04-02
-3ehw,2008-09-30,2008-09-15
-2eh4,2007-09-04,2007-03-04
-4eh3,2012-12-05,2012-04-02
-4ehg,2013-04-24,2012-04-02
-8eh1,2023-10-04,2022-09-13
-2ehc,2007-09-11,2007-03-06
-3ehy,2009-05-19,2008-09-15
-6ehf,2018-04-25,2017-09-13
-8ehn,2023-12-06,2022-09-14
-5ehf,2015-12-23,2015-10-28
-4eha,2012-06-06,2012-04-02
-3ehv,2009-03-17,2008-09-15
-5eh0,2016-04-20,2015-10-27
-7eh0,2021-07-14,2021-03-27
-5ehv,2016-03-09,2015-10-29
-7ehu,2021-07-07,2021-03-30
-3eh9,2009-04-28,2008-09-11
-3ehj,2009-09-15,2008-09-12
-4ehu,2012-08-08,2012-04-04
-5eh1,2016-08-17,2015-10-27
-3ehf,2009-09-15,2008-09-12
-2eh3,2007-09-04,2007-03-03
-5ehm,2016-11-09,2015-10-28
-2ehs,2007-09-11,2007-03-08
-7ehz,2021-12-15,2021-03-30
-3eh4,2009-04-21,2008-09-11
-4ehc,2013-06-19,2012-04-02
-2eh9,2008-03-11,2007-03-05
-8ehh,2023-09-20,2022-09-14
-2eh6,2007-09-11,2007-03-05
-5eh2,2016-02-17,2015-10-27
-1eh4,2001-09-19,2000-02-18
-5eh7,2016-03-09,2015-10-28
-8eha,2023-03-01,2022-09-14
-4ehy,2012-08-29,2012-04-04
-5ehx,2016-11-09,2015-10-29
-4eh4,2012-12-05,2012-04-02
-3ehh,2009-09-15,2008-09-12
-7ehx,2022-04-06,2021-03-30
-2ehz,2008-02-19,2007-03-10
-5eh5,2016-03-09,2015-10-28
-4ehm,2012-05-30,2012-04-02
-5ehq,2016-01-20,2015-10-28
-1ehn,2001-02-22,2000-02-22
-8eh9,2023-03-01,2022-09-13
-7ehm,2021-08-11,2021-03-30
-3ehu,2008-09-30,2008-09-14
-2eht,2007-09-11,2007-03-08
-6ehs,2018-04-18,2017-09-15
-4eh9,2012-12-05,2012-04-02
-5ehg,2016-10-26,2015-10-28
-7ehp,2021-07-07,2021-03-30
-7ehj,2021-08-11,2021-03-29
-5ehs,2016-11-09,2015-10-28
-7ehv,2021-08-11,2021-03-30
-4ehr,2012-06-06,2012-04-03
-4ehf,2012-06-06,2012-04-02
-5ehi,2016-10-26,2015-10-28
-7ehw,2022-03-30,2021-03-30
-1ehy,1999-10-16,1998-10-17
-1eh5,2000-04-26,2000-02-18
-7ehl,2021-05-05,2021-03-29
-6eha,2018-10-10,2017-09-12
-7eh8,2021-11-17,2021-03-28
-4eh6,2012-12-05,2012-04-02
-8eh8,2023-03-01,2022-09-13
-7ehy,2022-03-30,2021-03-30
-2eh1,2007-09-04,2007-03-02
-5ehh,2016-04-13,2015-10-28
-1eh2,1999-07-22,1998-07-10
-8ehv,2023-09-20,2022-09-14
-7ehg,2022-03-30,2021-03-29
-7eh1,2021-07-14,2021-03-27
-6ehg,2018-02-14,2017-09-13
-4eh7,2012-12-05,2012-04-02
-2ehu,2007-09-11,2007-03-09
-6ehe,2018-04-25,2017-09-13
-5ehn,2016-01-20,2015-10-28
-5ehr,2016-06-29,2015-10-28
-4eh2,2012-12-05,2012-04-02
-4ehn,2012-06-06,2012-04-02
-7k4b,2020-12-09,2020-09-15
-5k4g,2017-03-29,2016-05-20
-5k4i,2016-07-06,2016-05-20
-7k4x,2020-12-02,2020-09-16
-5k48,2017-06-07,2016-05-20
-4k4f,2013-06-05,2013-04-12
-1k4d,2001-11-14,2001-10-07
-8k47,2023-12-13,2023-07-17
-3k47,2009-10-13,2009-10-05
-7k4h,2021-12-01,2020-09-15
-1k4q,2002-01-30,2001-10-08
-6k41,2020-04-15,2019-05-23
-4k4x,2013-05-22,2013-04-12
-3k4h,2009-11-10,2009-10-05
-3k4q,2010-06-30,2009-10-06
-3k4m,2010-05-12,2009-10-05
-4k4a,2014-07-30,2013-04-12
-6k4c,2020-05-27,2019-05-23
-7k4n,2020-10-07,2020-09-15
-6k4k,2019-07-24,2019-05-24
-3k4z,2010-07-28,2009-10-06
-7k4w,2020-12-02,2020-09-16
-5k4z,2016-10-19,2016-05-22
-2k46,2008-08-12,2008-05-28
-5k47,2016-08-24,2016-05-20
-1k4y,2002-05-01,2001-10-09
-1k4c,2001-11-14,2001-10-07
-1k4m,2002-10-08,2001-10-08
-3k4s,2009-10-20,2009-10-06
-8k4f,2024-05-29,2023-07-18
-6k4j,2020-05-13,2019-05-24
-6k4g,2020-05-27,2019-05-23
-5k4j,2016-07-06,2016-05-20
-6k4z,2019-09-18,2019-05-27
-3k4n,2010-05-12,2009-10-05
-7k4d,2020-12-09,2020-09-15
-7k45,2020-10-07,2020-09-14
-3k4b,2010-02-02,2009-10-05
-5k41,2017-06-21,2016-05-20
-3k4y,2010-05-05,2009-10-06
-7k4g,2021-12-01,2020-09-15
-7k4o,2021-03-17,2020-09-15
-7k4f,2020-12-09,2020-09-15
-7k4a,2020-12-09,2020-09-15
-8k4c,2023-11-22,2023-07-17
-7k4c,2020-12-09,2020-09-15
-1k4h,2002-04-24,2001-10-08
-4k4e,2013-06-05,2013-04-12
-1k4k,2002-10-08,2001-10-08
-1k4v,2002-04-10,2001-10-09
-6k4x,2019-08-07,2019-05-27
-2k4g,2008-09-23,2008-06-07
-3k48,2009-11-24,2009-10-05
-8k41,2024-05-15,2023-07-17
-4k4j,2013-11-13,2013-04-12
-1k4p,2002-03-06,2001-10-08
-5k4u,2017-11-15,2016-05-22
-4k42,2014-10-01,2013-04-11
-5k4y,2018-01-17,2016-05-22
-7k4m,2021-10-13,2020-09-15
-5k4f,2017-08-09,2016-05-20
-6k4r,2019-07-24,2019-05-26
-7k40,2020-09-23,2020-09-14
-4k49,2014-07-30,2013-04-12
-6k42,2020-04-15,2019-05-23
-8k46,2023-12-13,2023-07-17
-4k4c,2014-07-30,2013-04-12
-5k4v,2017-11-15,2016-05-22
-6k4t,2019-08-07,2019-05-27
-1k4t,2002-12-04,2001-10-08
-6k4l,2019-07-24,2019-05-24
-3k43,2009-11-24,2009-10-05
-4k4s,2013-05-22,2013-04-12
-4k4t,2013-05-22,2013-04-12
-6k4h,2020-05-27,2019-05-23
-5k4x,2016-10-19,2016-05-22
-4k4i,2014-07-16,2013-04-12
-3k4o,2010-05-05,2009-10-05
-4k4y,2013-05-29,2013-04-12
-5k44,2017-06-21,2016-05-20
-4k4p,2013-09-18,2013-04-12
-7k4u,2020-12-02,2020-09-16
-3k4l,2010-05-12,2009-10-05
-2k4x,2008-08-19,2008-06-20
-3k42,2009-11-24,2009-10-05
-8k4h,2023-11-22,2023-07-18
-4k4b,2014-07-30,2013-04-12
-7k41,2021-01-13,2020-09-14
-4k41,2014-10-01,2013-04-11
-1k4g,2002-04-24,2001-10-08
-8k4b,2023-10-11,2023-07-17
-6k4e,2019-06-26,2019-05-23
-4k4r,2013-09-18,2013-04-12
-5k42,2017-06-21,2016-05-20
-4k4h,2014-07-16,2013-04-12
-1k4i,2002-03-06,2001-10-08
-4k4u,2013-05-22,2013-04-12
-7k4z,2020-12-02,2020-09-16
-4k46,2014-07-16,2013-04-12
-8k4z,2024-04-17,2023-07-20
-4k4g,2014-07-16,2013-04-12
-2k4d,2009-01-20,2008-06-06
-3k4j,2010-05-12,2009-10-05
-3k4g,2010-07-07,2009-10-05
-7k4j,2021-12-01,2020-09-15
-2k4w,2008-11-18,2008-06-20
-8k45,2023-12-13,2023-07-17
-7k4k,2021-12-01,2020-09-15
-3k4c,2010-02-02,2009-10-05
-5k4p,2016-08-31,2016-05-21
-1k4o,2002-03-06,2001-10-08
-3k45,2009-10-13,2009-10-05
-2k4i,2008-08-12,2008-06-08
-4k4d,2014-07-30,2013-04-12
-5k4l,2016-08-10,2016-05-20
-5k4q,2017-11-15,2016-05-21
-7k43,2020-10-07,2020-09-14
-3k4f,2009-12-15,2009-10-05
-5k4h,2017-03-29,2016-05-20
-3k4i,2009-10-13,2009-10-05
-5k4m,2017-04-26,2016-05-20
-5k45,2017-03-29,2016-05-20
-6k4d,2020-05-27,2019-05-23
-8k4r,2023-11-01,2023-07-20
-6k4m,2021-02-03,2019-05-24
-7k4e,2020-12-09,2020-09-15
-1k4l,2002-03-06,2001-10-08
-4k43,2014-10-01,2013-04-11
-3k4k,2010-05-12,2009-10-05
-3k4v,2010-06-09,2009-10-06
-8k40,2024-05-15,2023-07-17
-3k4p,2010-06-30,2009-10-06
-8k4n,2023-10-25,2023-07-20
-7k44,2021-09-29,2020-09-14
-6k43,2021-02-03,2019-05-23
-4k4o,2014-01-15,2013-04-12
-3k4d,2010-11-17,2009-10-05
-3k41,2009-11-24,2009-10-05
-6k4y,2019-08-07,2019-05-27
-7k4q,2020-12-02,2020-09-16
-4k4q,2013-09-18,2013-04-12
-4k4z,2013-05-22,2013-04-12
-4k45,2013-06-26,2013-04-11
-4k47,2013-09-04,2013-04-12
-5k4w,2018-01-10,2016-05-22
-7k4i,2021-10-06,2020-09-15
-3k4u,2009-11-03,2009-10-06
-8qc8,2023-12-27,2023-08-25
-1qcn,2000-06-07,1999-05-14
-6qcj,2019-12-25,2018-12-28
-7qca,2022-11-30,2021-11-22
-1qcy,2003-09-02,1999-05-12
-6qcx,2019-06-05,2018-12-31
-2qcg,2007-11-06,2007-06-19
-2qcd,2007-11-06,2007-06-19
-1qcf,1999-06-08,1999-05-04
-2qcm,2007-11-06,2007-06-19
-6qck,2020-01-29,2018-12-28
-3qc6,2011-08-10,2011-01-15
-5qcj,2017-12-20,2017-08-04
-8qcl,2023-12-13,2023-08-27
-4qc2,2014-10-22,2014-05-09
-1qc6,1999-05-25,1999-05-17
-1qcj,1999-09-15,1999-05-05
-8qcq,2024-03-20,2023-08-28
-4qc1,2014-05-21,2014-05-09
-8qc3,2023-12-27,2023-08-25
-6qct,2019-06-05,2018-12-30
-5qcy,2020-06-03,2017-12-01
-3qcy,2011-03-09,2011-01-17
-3qce,2011-12-28,2011-01-16
-8qc0,2024-02-21,2023-08-25
-3qcz,2011-02-02,2011-01-17
-4qc3,2014-05-21,2014-05-09
-7qc2,2022-05-04,2021-11-22
-6qcl,2019-04-10,2018-12-28
-5qcg,2017-12-20,2017-08-04
-7qcm,2022-03-16,2021-11-24
-3qch,2011-12-28,2011-01-16
-1qc5,2000-05-17,1999-05-17
-4qce,2015-05-20,2014-05-11
-5qcl,2017-11-08,2017-08-10
-2qc8,2007-07-03,2007-06-19
-3qcq,2011-03-09,2011-01-17
-5qcb,2017-12-20,2017-08-04
-7qcz,2022-07-06,2021-11-25
-6qc9,2019-08-21,2018-12-27
-7qcd,2022-09-21,2021-11-23
-4qcl,2014-11-26,2014-05-12
-4qck,2014-07-30,2014-05-12
-7qcs,2022-04-20,2021-11-25
-7qck,2022-03-16,2021-11-24
-7qcb,2021-12-29,2021-11-23
-5qcr,2020-06-03,2017-12-01
-5qc9,2017-12-20,2017-08-04
-8qcu,2024-05-01,2023-08-28
-3qcx,2011-03-09,2011-01-17
-7qc0,2022-03-23,2021-11-21
-3qcp,2012-05-30,2011-01-17
-8qc4,2023-11-15,2023-08-25
-6qc3,2019-08-21,2018-12-26
-6qcf,2019-08-21,2018-12-27
-1qca,1995-10-15,1995-08-03
-2qcx,2007-10-23,2007-06-19
-4qcd,2015-04-29,2014-05-10
-5qcp,2020-06-03,2017-12-01
-5qcs,2020-06-03,2017-12-01
-2qcl,2007-11-06,2007-06-19
-8qcg,2023-12-06,2023-08-25
-6qce,2019-12-25,2018-12-27
-2qcs,2007-11-06,2007-06-19
-3qc5,2011-08-10,2011-01-15
-3qcw,2011-06-15,2011-01-17
-5qco,2020-06-03,2017-12-01
-5qcn,2017-11-08,2017-08-10
-6qci,2019-05-01,2018-12-28
-1qcp,1999-05-21,1999-05-10
-5qcf,2017-12-20,2017-08-04
-6qcs,2019-06-05,2018-12-30
-7qct,2022-04-20,2021-11-25
-3qcg,2011-12-28,2011-01-16
-2qch,2007-11-06,2007-06-19
-7qcq,2021-12-08,2021-11-25
-3qci,2011-12-28,2011-01-16
-2qc6,2008-02-26,2007-06-19
-1qco,2000-06-07,1999-05-17
-5qc0,2017-12-20,2017-08-04
-4qca,2015-05-13,2014-05-09
-6qc5,2019-08-21,2018-12-26
-1qcw,1999-05-24,1999-05-07
-5qc7,2017-12-20,2017-08-04
-6qc7,2019-08-21,2018-12-27
-6qca,2019-08-21,2018-12-27
-5qc6,2017-12-20,2017-08-04
-3qc0,2011-04-06,2011-01-14
-7qc5,2022-11-30,2021-11-22
-2qca,2007-07-03,2007-06-19
-8qc2,2023-12-27,2023-08-25
-8qcj,2024-03-13,2023-08-27
-4qcf,2015-05-20,2014-05-11
-5qc2,2017-12-20,2017-08-04
-1qci,1999-09-15,1999-05-05
-3qc9,2011-02-16,2011-01-15
-7qch,2022-03-16,2021-11-24
-5qc3,2017-12-20,2017-08-04
-5qc5,2017-12-20,2017-08-04
-5qcv,2020-06-03,2017-12-01
-6qcy,2019-04-24,2018-12-31
-6qc2,2019-08-21,2018-12-26
-8qci,2024-03-06,2023-08-27
-5qcm,2017-11-08,2017-08-10
-5qcc,2017-12-20,2017-08-04
-8qca,2023-11-15,2023-08-25
-2qci,2008-04-22,2007-06-19
-8qc5,2023-12-27,2023-08-25
-5qcq,2020-06-03,2017-12-01
-2qcp,2007-10-02,2007-06-19
-3qcf,2011-12-28,2011-01-16
-5qc4,2017-12-20,2017-08-04
-8qc6,2023-12-27,2023-08-25
-3qc4,2011-04-20,2011-01-15
-5qce,2017-12-20,2017-08-04
-6qc8,2019-08-21,2018-12-27
-8qcf,2024-01-10,2023-08-25
-7qcn,2023-03-08,2021-11-24
-7qc1,2021-12-08,2021-11-22
-2qcn,2007-11-13,2007-06-19
-7qcj,2022-03-16,2021-11-24
-6qc6,2019-08-21,2018-12-27
-7qc8,2022-08-10,2021-11-22
-2qcf,2007-11-06,2007-06-19
-2qcu,2008-04-15,2007-06-19
-4qc6,2014-10-22,2014-05-09
-7qcl,2023-03-08,2021-11-24
-6qcv,2019-06-05,2018-12-31
-6qcb,2020-01-29,2018-12-27
-7qco,2022-04-06,2021-11-24
-4qc4,2015-03-11,2014-05-09
-6qc4,2019-08-21,2018-12-26
-3qcl,2011-12-28,2011-01-16
-3qc3,2011-03-09,2011-01-14
-2qcb,2008-04-29,2007-06-19
-3qcs,2011-03-09,2011-01-17
-5qcu,2020-06-03,2017-12-01
-7qcg,2022-03-23,2021-11-23
-5qcw,2020-06-03,2017-12-01
-5qcx,2020-06-03,2017-12-01
-5qci,2017-12-20,2017-08-04
-5qcd,2017-12-20,2017-08-04
-3qcm,2011-12-28,2011-01-16
-7qce,2022-11-16,2021-11-23
-5qck,2017-11-08,2017-08-10
-3qcu,2011-03-30,2011-01-17
-7qcu,2023-03-08,2021-11-25
-5qch,2017-12-20,2017-08-04
-2qct,2007-11-20,2007-06-19
-5qc8,2017-12-20,2017-08-04
-7qc9,2022-08-10,2021-11-22
-5qc1,2017-12-20,2017-08-04
-7qci,2022-03-16,2021-11-24
-6qcz,2019-04-24,2018-12-31
-5qca,2017-12-20,2017-08-04
-3qck,2011-12-28,2011-01-16
-7qcr,2022-04-20,2021-11-25
-6qcd,2019-12-25,2018-12-27
-4qc0,2014-10-22,2014-05-09
-5qcz,2020-06-03,2017-12-01
-3qcj,2011-12-28,2011-01-16
-6qch,2019-12-25,2018-12-28
-8qcd,2023-12-06,2023-08-25
-5qct,2020-06-03,2017-12-01
-6qcn,2019-12-25,2018-12-29
-7ugh,2022-04-13,2022-03-24
-7ugl,2023-04-12,2022-03-24
-5ugg,2017-05-31,2017-01-08
-3ugy,2011-12-28,2011-11-03
-5ug4,2017-01-25,2017-01-06
-6ugr,2019-12-18,2019-09-26
-1ugx,2003-09-23,2003-06-22
-3ugh,2011-11-30,2011-11-02
-5ugo,2017-07-26,2017-01-09
-3ugg,2011-11-30,2011-11-02
-5ug8,2017-03-22,2017-01-07
-7ugf,2023-04-12,2022-03-24
-5ugp,2017-07-26,2017-01-09
-3ugv,2011-11-23,2011-11-03
-6ug9,2019-12-18,2019-09-26
-3ugz,2011-12-28,2011-11-03
-6ug2,2020-12-02,2019-09-25
-4ug9,2015-06-24,2015-03-22
-4uga,2015-06-24,2015-03-22
-6ugb,2020-12-02,2019-09-26
-4ugu,2015-06-24,2015-03-22
-3ugi,2012-12-12,2011-11-02
-4ug5,2015-06-24,2015-03-22
-7ugj,2023-03-29,2022-03-24
-6ug6,2020-12-02,2019-09-25
-4ugx,2015-06-24,2015-03-22
-3ugq,2012-02-22,2011-11-02
-3ugw,2011-11-16,2011-11-03
-4ugp,2015-06-24,2015-03-22
-4ugn,2015-06-24,2015-03-22
-8ugb,2024-01-17,2023-10-05
-4ugh,2015-06-24,2015-03-22
-1uge,1997-04-01,1996-07-24
-8ugs,2024-01-17,2023-10-06
-5ug2,2017-02-01,2017-01-06
-8ugy,2024-05-01,2023-10-06
-5ugh,2017-05-17,2017-01-08
-3ug2,2012-03-07,2011-11-02
-6uge,2019-10-09,2019-09-26
-7ugo,2022-10-26,2022-03-25
-3ug3,2012-03-07,2011-11-02
-3ug8,2012-08-15,2011-11-02
-8ug3,2023-12-06,2023-10-05
-1ugp,2004-06-17,2003-06-17
-3ug5,2012-03-07,2011-11-02
-1ug9,2003-12-09,2003-06-16
-1ugr,2004-06-17,2003-06-17
-5ugt,2017-02-15,2017-01-10
-7uge,2023-04-12,2022-03-24
-1uga,1997-01-27,1996-07-24
-4ugj,2015-06-24,2015-03-22
-6ug4,2020-08-05,2019-09-25
-3ugc,2012-05-16,2011-11-02
-7ug0,2023-03-29,2022-03-23
-5ug0,2017-05-31,2017-01-06
-8ugq,2023-11-22,2023-10-05
-5ugl,2017-02-22,2017-01-09
-5ugy,2017-01-25,2017-01-10
-7ug3,2022-07-20,2022-03-23
-4ugs,2015-06-24,2015-03-22
-5ugm,2018-01-17,2017-01-09
-6ugz,2019-12-18,2019-09-26
-6ugm,2019-11-20,2019-09-26
-4ugw,2015-06-24,2015-03-22
-5ugk,2017-05-31,2017-01-09
-4ugk,2015-06-24,2015-03-22
-5ugx,2017-02-22,2017-01-10
-5ug9,2017-03-22,2017-01-07
-3ug7,2011-12-07,2011-11-02
-7ugb,2023-03-29,2022-03-24
-4ugl,2015-06-24,2015-03-22
-4ugt,2015-06-24,2015-03-22
-6ugd,2019-10-09,2019-09-26
-5ugs,2017-02-15,2017-01-10
-6ugw,2019-11-13,2019-09-26
-3ugx,2012-02-08,2011-11-03
-4ugb,2015-06-24,2015-03-22
-7ugn,2022-10-26,2022-03-25
-4ug8,2015-06-24,2015-03-22
-6ugx,2019-11-13,2019-09-26
-6ugc,2020-12-02,2019-09-26
-5ugf,2017-06-21,2017-01-08
-6ugk,2021-03-10,2019-09-26
-1ugf,1997-04-01,1996-07-24
-7ugq,2022-11-09,2022-03-25
-3ugl,2012-12-12,2011-11-02
-4ug2,2015-04-08,2015-03-21
-7ugp,2022-11-09,2022-03-25
-3uge,2012-11-07,2011-11-02
-5ug7,2018-02-07,2017-01-07
-5uga,2017-03-22,2017-01-07
-5ugi,2017-11-15,2017-01-08
-6ugv,2019-11-13,2019-09-26
-5ugn,2017-07-26,2017-01-09
-1ugs,2004-06-17,2003-06-17
-7ug1,2023-04-12,2022-03-23
-5ugu,2017-02-15,2017-01-10
-1ugb,1997-01-27,1996-07-24
-6ugp,2019-12-18,2019-09-26
-4ugg,2015-06-24,2015-03-22
-3ug6,2011-12-07,2011-11-02
-6ugf,2019-10-09,2019-09-26
-6ugy,2019-11-13,2019-09-26
-4ugy,2015-06-24,2015-03-22
-4ugz,2015-07-15,2015-03-23
-4ugq,2015-06-24,2015-03-22
-7ug5,2023-04-05,2022-03-23
-6ug8,2019-12-18,2019-09-26
-5ugc,2017-03-22,2017-01-08
-8ugz,2024-04-03,2023-10-06
-3ugj,2012-06-06,2011-11-02
-4ugv,2015-06-24,2015-03-22
-7ug7,2022-05-18,2022-03-24
-4ug6,2015-06-24,2015-03-22
-4ug7,2015-06-24,2015-03-22
-5ugb,2017-03-22,2017-01-07
-3ugs,2011-11-30,2011-11-02
-5ug1,2017-10-25,2017-01-06
-6ugn,2019-12-18,2019-09-26
-4ug0,2015-06-10,2015-03-20
-3ug9,2012-01-25,2011-11-02
-4ugf,2015-06-24,2015-03-22
-7ugv,2023-03-29,2022-03-25
-7ugg,2022-06-08,2022-03-24
-5ugr,2017-02-08,2017-01-09
-3ugt,2012-02-22,2011-11-02
-5ugw,2017-02-08,2017-01-10
-4uge,2015-06-24,2015-03-22
-7ugw,2022-08-17,2022-03-25
-7ug8,2023-04-19,2022-03-24
-3ugr,2012-08-15,2011-11-02
-1ugc,1997-04-01,1996-07-24
-1ugw,2003-09-23,2003-06-22
-5ugv,2018-01-17,2017-01-10
-3ugf,2011-11-30,2011-11-02
-8ug1,2023-12-06,2023-10-05
-1ugy,2003-09-23,2003-06-23
-4ugr,2015-06-24,2015-03-22
-6ug7,2019-12-18,2019-09-26
-6ugq,2019-12-18,2019-09-26
-7ugd,2023-03-29,2022-03-24
-1ugd,1997-01-27,1996-07-24
-4ugc,2015-06-24,2015-03-22
-4ugo,2015-06-24,2015-03-22
-4ug1,2015-11-25,2015-03-20
-6ugo,2019-12-18,2019-09-26
-7ug9,2022-08-31,2022-03-24
-3ug4,2012-03-07,2011-11-02
-7ug6,2022-12-21,2022-03-24
-4ugi,2015-06-24,2015-03-22
-3ugd,2012-12-12,2011-11-02
-5ugd,2017-05-31,2017-01-08
-7ugx,2023-03-29,2022-03-25
-4ugd,2015-06-24,2015-03-22
-6ugl,2020-01-29,2019-09-26
-1ugg,1997-01-27,1996-07-24
-7ugi,2023-04-12,2022-03-24
-1ugu,2004-08-10,2003-06-19
-4ugm,2015-06-24,2015-03-22
-3ifp,2009-11-17,2009-07-24
-1if8,2001-05-02,2001-04-12
-8if1,,2023-02-16
-8ify,2023-08-30,2023-02-20
-8if3,2023-04-05,2023-02-17
-5ifi,2016-03-16,2016-02-26
-5ifo,2016-06-01,2016-02-26
-4ifi,2013-10-30,2012-12-14
-2if8,2006-10-24,2006-09-20
-4ifv,2013-02-06,2012-12-15
-3ifn,2009-11-17,2009-07-24
-1if4,2001-05-02,2001-04-12
-1if9,2001-05-02,2001-04-12
-3ifj,2009-10-06,2009-07-24
-5if0,2016-04-06,2016-02-25
-4ifu,2013-02-27,2012-12-15
-3if9,2009-10-27,2009-07-24
-8ifn,2024-02-28,2023-02-19
-4ife,2013-05-01,2012-12-14
-6ifk,2018-12-12,2018-09-20
-6ifp,2019-09-25,2018-09-20
-6ifq,2019-10-02,2018-09-20
-8ifo,2023-03-29,2023-02-19
-6ift,2019-01-30,2018-09-21
-4if4,2013-05-08,2012-12-14
-8if2,2023-05-17,2023-02-17
-5if4,2017-01-18,2016-02-25
-6if8,2018-10-03,2018-09-18
-2ifg,2007-02-13,2006-09-20
-4ifz,2013-02-27,2012-12-15
-4if7,2013-12-18,2012-12-14
-2if0,2007-05-01,2006-09-19
-5ifc,2017-02-22,2016-02-25
-5if9,2016-03-09,2016-02-25
-4ifc,2013-08-28,2012-12-14
-8if8,2023-05-31,2023-02-17
-6ifi,2019-07-03,2018-09-20
-5if2,2017-02-22,2016-02-25
-4ifw,2013-02-27,2012-12-15
-5ife,2016-10-26,2016-02-25
-3ifx,2010-02-09,2009-07-26
-3ifw,2010-06-16,2009-07-26
-4ifd,2013-02-06,2012-12-14
-3ifu,2009-10-27,2009-07-26
-3ife,2009-08-04,2009-07-24
-3if2,2009-08-04,2009-07-23
-6ifg,2019-09-25,2018-09-20
-8ifs,2023-10-18,2023-02-19
-6if3,2019-04-03,2018-09-18
-2ify,2006-10-24,2006-09-21
-8ifr,2023-10-18,2023-02-19
-6if2,2019-04-03,2018-09-18
-3ifs,2009-08-11,2009-07-24
-3ifc,2010-08-11,2009-07-24
-3if1,2010-06-23,2009-07-23
-5ifs,2016-10-26,2016-02-26
-5ifk,2017-03-01,2016-02-26
-4if2,2013-12-18,2012-12-13
-6ifb,2019-09-25,2018-09-19
-8ift,2023-10-18,2023-02-19
-2ifc,2007-10-02,2006-09-20
-3ifl,2009-11-17,2009-07-24
-1if6,2001-05-02,2001-04-12
-6ifr,2018-12-12,2018-09-21
-3ifk,2009-12-15,2009-07-24
-8ifb,2024-02-14,2023-02-17
-3ifd,2009-08-04,2009-07-24
-3ifz,2010-07-28,2009-07-27
-6ifz,2018-12-12,2018-09-21
-4ify,2013-02-06,2012-12-15
-6ifj,2019-09-25,2018-09-20
-6ify,2018-12-12,2018-09-21
-1ifx,2001-06-06,2001-04-13
-6ifn,2018-12-12,2018-09-20
-5if6,2017-03-01,2016-02-25
-1ifh,1993-10-31,1993-05-06
-3if7,2010-06-30,2009-07-24
-3ifo,2009-11-17,2009-07-24
-4ifb,2013-02-06,2012-12-14
-1if7,2001-05-02,2001-04-12
-1ifu,1998-01-14,1996-07-05
-8ifp,2023-10-18,2023-02-19
-4ifk,2013-09-18,2012-12-14
-5ifu,2016-11-16,2016-02-26
-8ifx,2024-03-20,2023-02-20
-2if5,2006-11-21,2006-09-20
-6ifc,2020-01-29,2018-09-19
-3ifa,2010-08-11,2009-07-24
-4if5,2014-05-28,2012-12-14
-5ify,2016-03-09,2016-02-26
-5ifm,2016-11-09,2016-02-26
-2ifr,2006-10-03,2006-09-21
-3ifv,2009-09-01,2009-07-26
-4ifo,2013-09-18,2012-12-14
-5if5,2017-03-08,2016-02-25
-6ifd,2019-07-03,2018-09-19
-5ifj,2017-03-15,2016-02-26
-8ifq,2023-10-18,2023-02-19
-1if2,2001-08-17,2001-04-12
-8ifu,2024-02-28,2023-02-19
-4if6,2013-10-23,2012-12-14
-4ifn,2013-12-18,2012-12-14
-5ifp,2017-04-19,2016-02-26
-5ifd,2017-02-22,2016-02-25
-6if0,2019-02-27,2018-09-18
-5ifw,2016-10-26,2016-02-26
-1ifs,1998-01-14,1996-07-05
-4ifx,2013-02-27,2012-12-15
-6if5,2019-01-30,2018-09-18
-1if5,2001-05-02,2001-04-12
-6iff,2019-09-25,2018-09-20
-8ife,2024-02-14,2023-02-17
-8ifd,2024-02-14,2023-02-17
-2ifw,2006-10-03,2006-09-21
-4ifp,2013-04-03,2012-12-14
-2if7,2006-10-17,2006-09-20
-5ift,2017-04-19,2016-02-26
-8iff,2023-08-02,2023-02-17
-4ifr,2013-09-18,2012-12-14
-6if7,2019-04-24,2018-09-18
-4ifg,2014-04-16,2012-12-14
-4ifh,2013-12-18,2012-12-14
-5ifb,2017-02-22,2016-02-25
-5if7,2017-02-22,2016-02-25
-8ifc,2024-02-14,2023-02-17
-8if7,2023-07-26,2023-02-17
-8ifk,2024-01-17,2023-02-18
-8ifz,2023-08-30,2023-02-20
-8ifm,2024-01-17,2023-02-18
-8if4,2023-04-05,2023-02-17
-8ifl,2024-01-17,2023-02-18
-2ifa,2006-10-03,2006-09-20
-8ifg,2024-01-03,2023-02-17
-5if8,2017-02-22,2016-02-25
-6ifh,2019-01-16,2018-09-20
-5ifl,2017-03-01,2016-02-26
-7yvk,2023-06-28,2022-08-19
-5yvs,2017-12-27,2017-11-27
-4yv2,2015-09-16,2015-03-19
-4yvf,2015-11-25,2015-03-20
-5yv9,2018-12-05,2017-11-24
-1yvd,2005-07-26,2005-02-15
-1yvz,2005-03-22,2005-02-16
-5yvo,2018-11-28,2017-11-27
-2yvg,2007-10-16,2007-04-12
-2yvl,2008-04-01,2007-04-13
-4yvb,2016-03-23,2015-03-19
-5yvl,2018-11-07,2017-11-26
-4yvv,2015-11-25,2015-03-20
-6yvs,2021-02-10,2020-04-28
-6yvj,2021-05-12,2020-04-28
-6yvo,2022-02-23,2020-04-28
-7yvp,2023-06-28,2022-08-19
-4yv0,2015-09-16,2015-03-19
-4yvk,2015-07-15,2015-03-20
-5yv5,2018-07-18,2017-11-24
-6yv0,2020-05-13,2020-04-27
-6yvw,2020-12-30,2020-04-28
-6yv5,2021-05-12,2020-04-27
-6yv4,2020-05-06,2020-04-27
-7yvi,2023-06-28,2022-08-19
-2yvk,2008-01-22,2007-04-13
-1yvx,2005-03-22,2005-02-16
-7yv1,2023-07-26,2022-08-18
-2yvm,2008-02-26,2007-04-13
-4yvu,2016-03-30,2015-03-20
-5yvp,2018-11-07,2017-11-27
-5yv3,2018-11-07,2017-11-23
-6yvz,2020-12-30,2020-04-29
-2yvy,2007-09-04,2007-04-18
-6yvn,2021-11-17,2020-04-28
-7yvq,2022-10-26,2022-08-19
-1yvu,2005-08-09,2005-02-16
-1yv5,2005-03-01,2005-02-15
-1yvk,2005-02-22,2005-02-15
-4yvi,2015-07-15,2015-03-20
-1yvj,2005-05-24,2005-02-15
-6yv9,2020-07-22,2020-04-28
-4yvj,2015-07-15,2015-03-20
-6yvy,2021-02-10,2020-04-28
-5yvr,2017-12-27,2017-11-27
-4yv1,2015-09-16,2015-03-19
-7yvd,2023-08-30,2022-08-19
-7yva,2023-08-30,2022-08-19
-7yvs,2022-10-26,2022-08-19
-7yvu,2023-07-19,2022-08-19
-7yvc,2023-08-09,2022-08-19
-4yv9,2015-04-08,2015-03-19
-5yvx,2018-03-14,2017-11-27
-5yv2,2018-09-05,2017-11-23
-1yv1,2005-06-21,2005-02-14
-1yve,1997-09-04,1996-10-11
-2yvf,2007-10-16,2007-04-12
-1yvp,2005-06-07,2005-02-16
-4yvp,2015-11-25,2015-03-20
-7yv4,2023-04-19,2022-08-18
-4yvg,2015-07-15,2015-03-20
-1yvq,2006-02-28,2005-02-16
-2yvv,2007-05-01,2007-04-16
-4yv5,2015-10-14,2015-03-19
-2yve,2008-04-15,2007-04-12
-4yvx,2015-11-25,2015-03-20
-6yv3,2021-05-12,2020-04-27
-4yvc,2015-06-10,2015-03-19
-2yvo,2008-02-26,2007-04-13
-6yvi,2021-05-12,2020-04-28
-6yv8,2020-07-22,2020-04-28
-1yv0,2005-04-12,2005-02-14
-1yvt,2006-02-28,2005-02-16
-4yv8,2016-05-04,2015-03-19
-5yvk,2018-11-07,2017-11-26
-7yve,2023-06-28,2022-08-19
-4yvn,2016-03-30,2015-03-20
-6yvp,2020-05-13,2020-04-28
-4yvh,2015-07-15,2015-03-20
-1yv3,2005-03-08,2005-02-14
-4yvz,2015-06-03,2015-03-20
-7yvv,2023-09-06,2022-08-19
-5yvb,2018-12-05,2017-11-24
-6yvt,2020-05-20,2020-04-28
-6yvk,2021-11-17,2020-04-28
-6yvl,2021-11-17,2020-04-28
-8yvw,2024-05-08,2024-03-29
-1yvf,2005-04-19,2005-02-15
-7yvo,2023-06-28,2022-08-19
-2yvp,2008-02-26,2007-04-13
-2yvx,2007-09-04,2007-04-18
-7yvg,2023-06-28,2022-08-19
-5yvt,2018-03-14,2017-11-27
-2yvj,2007-10-23,2007-04-12
-4yve,2015-06-10,2015-03-19
-1yvn,2000-03-23,1999-03-23
-6yv2,2020-05-13,2020-04-27
-1yvl,2005-03-22,2005-02-16
-2yvr,2008-04-15,2007-04-13
-2yvw,2007-10-16,2007-04-16
-5yvc,2018-12-05,2017-11-24
-5yv8,2018-12-05,2017-11-24
-5yve,2018-04-04,2017-11-25
-5yvn,2018-11-28,2017-11-27
-2yv7,2008-02-19,2007-04-10
-5yvz,2018-09-05,2017-11-28
-4yvy,2016-03-30,2015-03-20
-6yve,2020-11-18,2020-04-28
-6yvm,2021-11-17,2020-04-28
-6yvc,2021-05-12,2020-04-28
-6yvf,2020-05-20,2020-04-28
-2yv9,2008-02-19,2007-04-10
-5yv1,2018-09-05,2017-11-23
-5yva,2018-12-05,2017-11-24
-2yvc,2007-04-24,2007-04-11
-1yvg,2005-03-22,2005-02-15
-5yvm,2017-12-27,2017-11-26
-2yv5,2008-04-15,2007-04-09
-6yvx,2020-12-30,2020-04-28
-1yvh,2005-03-08,2005-02-15
-7yvn,2023-06-28,2022-08-19
-7yv8,2023-07-19,2022-08-18
-1yvm,2005-06-07,2005-02-16
-5yv0,2018-11-14,2017-11-23
-4yvd,2015-04-15,2015-03-19
-7yvb,2023-08-09,2022-08-19
-18gs,1999-01-13,1997-12-07
-7t73,2022-09-28,2021-12-14
-1t7q,2004-06-22,2004-05-10
-6t7n,2020-11-18,2019-10-22
-6t73,2020-03-18,2019-10-21
-5t7l,2016-10-12,2016-09-05
-3t7o,2011-08-31,2011-07-30
-5t7t,2017-01-04,2016-09-05
-7t7h,2022-06-15,2021-12-15
-7t7k,2022-06-01,2021-12-15
-8t72,2024-02-14,2023-06-19
-3t7p,2012-08-01,2011-07-30
-3t7t,2011-10-12,2011-07-31
-5t7h,2017-03-22,2016-09-05
-8t7q,2023-10-11,2023-06-21
-7t7z,2022-04-20,2021-12-15
-7t7d,2022-05-18,2021-12-15
-6t7j,2020-11-18,2019-10-22
-5t7d,2017-06-07,2016-09-04
-3t7b,2011-09-14,2011-07-29
-1t7o,2004-06-22,2004-05-10
-6t7v,2020-09-09,2019-10-23
-5t71,2017-09-06,2016-09-02
-3t7z,2012-04-11,2011-07-31
-3t7k,2012-02-15,2011-07-30
-7t75,2022-09-28,2021-12-14
-1t7j,2005-05-10,2004-05-10
-7t79,2022-03-02,2021-12-14
-5t7u,2017-01-04,2016-09-05
-8t7i,2023-11-22,2023-06-20
-7t7o,2022-06-01,2021-12-15
-8t70,2023-08-09,2023-06-19
-1t74,2004-08-31,2004-05-07
-5t74,2017-09-06,2016-09-02
-3t70,2012-08-29,2011-07-29
-3t7m,2011-08-31,2011-07-30
-6t7p,2020-07-08,2019-10-22
-8t74,2024-02-14,2023-06-19
-3t73,2012-08-01,2011-07-29
-3t7c,2011-08-17,2011-07-29
-6t7l,2020-11-18,2019-10-22
-5t77,2016-12-28,2016-09-02
-7t7i,2022-07-06,2021-12-15
-5t7k,2017-01-18,2016-09-05
-8t79,2024-05-08,2023-06-20
-5t7m,2017-09-20,2016-09-05
-3t7e,2011-11-23,2011-07-30
-3t74,2012-08-01,2011-07-29
-3t7q,2012-08-01,2011-07-30
-7t7u,2023-02-15,2021-12-15
-3t7x,2012-08-01,2011-07-31
-5t7e,2017-06-07,2016-09-04
-1t7i,2005-05-10,2004-05-10
-5t7p,2017-08-09,2016-09-05
-5t72,2017-09-06,2016-09-02
-1t7x,2004-12-21,2004-05-11
-3t7s,2011-10-12,2011-07-31
-5t7j,2017-01-18,2016-09-05
-6t70,2020-07-15,2019-10-20
-1t7l,2005-03-01,2004-05-10
-7t7b,2022-08-03,2021-12-14
-6t72,2020-01-15,2019-10-21
-6t7h,2020-09-30,2019-10-22
-1t75,2004-06-22,2004-05-07
-1t7m,2004-08-31,2004-05-10
-5t75,2017-09-06,2016-09-02
-8t7s,2024-05-01,2023-06-21
-5t7v,2017-05-31,2016-09-06
-8t7u,2024-06-05,2023-06-21
-6t7y,2020-03-04,2019-10-23
-7t7l,2022-07-06,2021-12-15
-1t7d,2004-07-13,2004-05-09
-3t7d,2012-08-01,2011-07-29
-3t77,2011-08-24,2011-07-29
-1t76,2004-08-31,2004-05-08
-1t7f,2004-08-31,2004-05-10
-1t7p,1998-02-25,1997-09-24
-8t7a,2023-09-13,2023-06-20
-5t78,2017-01-11,2016-09-02
-7t74,2022-09-28,2021-12-14
-1t7v,2004-12-21,2004-05-11
-7t7m,2022-07-06,2021-12-15
-3t7n,2011-08-31,2011-07-30
-1t7k,2004-10-05,2004-05-10
-7t7a,2022-05-04,2021-12-14
-8t7h,2023-10-11,2023-06-20
-5t70,2017-03-01,2016-09-02
-3t7l,2011-08-31,2011-07-30
-8t73,2024-02-14,2023-06-19
-8t71,2024-02-14,2023-06-19
-3t7a,2011-12-07,2011-07-29
-6t77,2020-11-18,2019-10-21
-1t7w,2004-12-21,2004-05-11
-3t7y,2011-11-16,2011-07-31
-7t7g,2022-05-04,2021-12-15
-3t7r,2011-10-12,2011-07-31
-5t7s,2017-01-04,2016-09-05
-8t7v,2023-12-06,2023-06-21
-6t7f,2020-08-05,2019-10-21
-1t7r,2004-08-31,2004-05-10
-1t7y,2004-12-21,2004-05-11
-5t7f,2016-12-28,2016-09-04
-8t75,2024-02-14,2023-06-19
-1t79,2004-08-31,2004-05-08
-7t7q,2022-02-02,2021-12-15
-5t79,2017-02-15,2016-09-02
-7t76,2022-09-28,2021-12-14
-3t7v,2011-11-30,2011-07-31
-5t7i,2017-01-04,2016-09-05
-7t78,2022-03-02,2021-12-14
-6t71,2020-08-19,2019-10-20
-6t7g,2019-12-25,2019-10-21
-7t7e,2022-05-18,2021-12-15
-5t73,2016-12-28,2016-09-02
-8t78,2024-05-01,2023-06-19
-5t7n,2017-01-11,2016-09-05
-5t7o,2017-09-20,2016-09-05
-6t7q,2020-11-18,2019-10-23
-7t7j,2022-01-12,2021-12-15
-6t75,2020-01-01,2019-10-21
-7t77,2022-09-28,2021-12-14
-8t77,2024-05-01,2023-06-19
-5t7g,2017-10-11,2016-09-04
-3t78,2012-08-08,2011-07-29
-1t71,2004-12-07,2004-05-07
-7t7s,2022-02-02,2021-12-15
-6t7k,2020-11-18,2019-10-22
-3t71,2012-04-18,2011-07-29
-7t7f,2022-05-18,2021-12-15
-6t74,2020-03-18,2019-10-21
-7t72,2022-12-21,2021-12-14
-1t73,2004-08-31,2004-05-07
-1t7t,2004-08-31,2004-05-10
-1t7z,2004-12-21,2004-05-11
-1ele,1995-02-14,1994-10-24
-6elv,2019-03-20,2017-09-29
-6elo,2018-05-30,2017-09-29
-2ely,2007-10-02,2007-03-28
-5elq,2016-09-07,2015-11-05
-7elg,2021-10-13,2021-04-10
-3ell,2009-01-20,2008-09-22
-2elv,2008-04-01,2007-03-27
-4elc,2012-08-15,2012-04-10
-1elq,2000-04-19,2000-03-14
-4el8,2013-03-20,2012-04-10
-5elm,2015-11-18,2015-11-04
-6elr,2018-10-10,2017-09-29
-1el1,2001-03-13,2000-03-13
-8ela,2023-04-05,2022-09-23
-2els,2008-04-01,2007-03-27
-3el1,2009-09-01,2008-09-19
-8elf,2023-05-03,2022-09-23
-3el8,2008-10-28,2008-09-20
-6els,2019-03-20,2017-09-29
-6el9,2018-02-21,2017-09-28
-3el3,2009-09-29,2008-09-19
-3elf,2009-02-10,2008-09-22
-5eln,2016-11-16,2015-11-04
-3ele,2008-10-14,2008-09-22
-2ele,2007-10-02,2007-03-27
-1ela,1994-04-30,1993-12-07
-7elj,2021-04-28,2021-04-11
-8elp,2023-07-05,2022-09-26
-5elg,2016-11-16,2015-11-04
-8el4,2023-10-25,2022-09-23
-8el6,2023-10-25,2022-09-23
-2elp,2008-04-01,2007-03-27
-6el2,2018-10-10,2017-09-27
-2elo,2008-04-01,2007-03-27
-8els,2023-09-06,2022-09-26
-1el5,2000-12-06,2000-03-13
-2el2,2007-10-02,2007-03-26
-6ely,2018-05-02,2017-09-30
-7elw,2021-11-24,2021-04-12
-2eld,2007-10-02,2007-03-27
-7el1,2021-07-28,2021-04-07
-3eld,2008-11-18,2008-09-22
-6eln,2018-05-30,2017-09-29
-1ell,2002-06-26,2000-03-14
-6el6,2018-02-21,2017-09-28
-6elb,2019-02-06,2017-09-28
-6el3,2018-09-05,2017-09-27
-8eli,2023-09-27,2022-09-24
-4elg,2013-02-13,2012-04-10
-4ele,2013-02-13,2012-04-10
-7el4,2021-06-09,2021-04-08
-2el5,2007-10-02,2007-03-26
-1elb,1994-06-22,1993-12-07
-6elf,2019-02-06,2017-09-28
-2elm,2008-04-01,2007-03-27
-4el4,2012-08-15,2012-04-10
-7elt,2022-02-16,2021-04-12
-2elc,2007-10-02,2007-03-27
-3el0,2009-09-01,2008-09-19
-8el9,2023-10-04,2022-09-23
-2elx,2008-04-01,2007-03-27
-7elb,2021-05-05,2021-04-09
-3eln,2008-10-21,2008-09-22
-3el2,2008-10-07,2008-09-19
-3el5,2009-09-01,2008-09-20
-4elv,2013-04-24,2012-04-11
-6elt,2019-03-20,2017-09-29
-2elt,2008-04-01,2007-03-27
-8elw,2023-09-06,2022-09-26
-8elt,2023-09-06,2022-09-26
-4elm,2012-07-25,2012-04-11
-6elk,2017-12-06,2017-09-29
-8elu,2023-09-06,2022-09-26
-8elq,2023-07-05,2022-09-26
-2el9,2008-03-18,2007-03-27
-8elc,2023-06-28,2022-09-23
-2el0,2007-10-02,2007-03-26
-3elh,2009-06-16,2008-09-22
-5elf,2016-03-30,2015-11-04
-5eld,2016-03-30,2015-11-04
-5el4,2016-01-27,2015-11-04
-6ele,2017-11-08,2017-09-28
-5elw,2016-10-05,2015-11-05
-2elq,2008-04-01,2007-03-27
-3elc,2009-08-25,2008-09-22
-1el9,2000-12-06,2000-03-13
-2el6,2007-10-02,2007-03-26
-2eln,2008-04-01,2007-03-27
-4elf,2013-02-13,2012-04-10
-8el2,2023-07-19,2022-09-22
-1ely,1998-05-27,1998-02-10
-8elh,2023-06-14,2022-09-24
-1elv,2001-03-14,2000-03-14
-3elw,2008-11-18,2008-09-23
-3els,2009-02-10,2008-09-23
-5elv,2016-05-04,2015-11-05
-6elp,2018-05-30,2017-09-29
-1eld,1995-02-14,1994-10-24
-8elo,2023-07-05,2022-09-26
-8elr,2023-09-06,2022-09-26
-2elw,2008-04-01,2007-03-27
-5elr,2016-01-13,2015-11-05
-8el0,2023-10-04,2022-09-22
-5elt,2016-01-13,2015-11-05
-1els,1994-07-31,1994-04-05
-7elc,2021-05-05,2021-04-09
-3elu,2008-11-18,2008-09-23
-8elm,2023-09-06,2022-09-26
-5el9,2016-10-05,2015-11-04
-5elk,2015-12-09,2015-11-04
-3el7,2008-10-28,2008-09-20
-1el3,2000-05-10,2000-03-13
-1eli,2000-12-06,2000-03-13
-5ele,2016-03-30,2015-11-04
-4elu,2013-03-27,2012-04-11
-5elh,2015-12-09,2015-11-04
-6el0,2018-12-12,2017-09-27
-6elz,2017-12-27,2017-09-30
-5ely,2016-04-27,2015-11-05
-5els,2016-01-13,2015-11-05
-1elx,1998-05-27,1998-02-10
-8elz,2023-09-06,2022-09-26
-6eli,2018-04-11,2017-09-29
-2elu,2008-04-01,2007-03-27
-2eli,2008-04-01,2007-03-27
-2el4,2007-10-02,2007-03-26
-6elg,2019-02-06,2017-09-28
-3el4,2009-09-01,2008-09-19
-5elz,2016-08-10,2015-11-05
-4el0,2012-07-25,2012-04-10
-5el1,2016-05-04,2015-11-04
-2el3,2007-10-02,2007-03-26
-5elc,2016-03-30,2015-11-04
-8elj,2023-07-19,2022-09-24
-8el3,2023-10-25,2022-09-23
-1elf,1995-07-10,1995-03-13
-8ely,2023-09-06,2022-09-26
-1elg,1995-07-10,1995-03-13
-1elr,2000-04-26,2000-03-14
-6elc,2018-07-11,2017-09-28
-8el5,2023-10-25,2022-09-23
-1elz,1998-05-27,1998-02-10
-1elt,1996-01-01,1995-01-02
-1elu,2000-04-19,2000-03-14
-2elr,2008-04-01,2007-03-27
-3elj,2008-12-30,2008-09-22
-5eli,2016-12-28,2015-11-04
-7ela,2021-05-05,2021-04-09
-4elt,2013-03-27,2012-04-11
-4el9,2012-09-05,2012-04-10
-4elb,2013-02-13,2012-04-10
-8elk,2023-09-06,2022-09-26
-8ell,2023-09-06,2022-09-26
-1elj,2001-01-19,2000-03-13
-5el2,2016-08-31,2015-11-04
-6el5,2018-05-30,2017-09-27
-8elg,2023-06-14,2022-09-24
-3el9,2009-09-01,2008-09-21
-6el4,2018-12-12,2017-09-27
-1el4,2001-03-13,2000-03-13
-4elr,2013-04-17,2012-04-11
-7elh,2021-10-20,2021-04-11
-7elv,2022-04-20,2021-04-12
-8el1,2023-10-25,2022-09-22
-3elz,2009-01-13,2008-09-23
-1el7,2000-12-06,2000-03-13
-1el8,2000-12-06,2000-03-13
-3ely,2008-11-18,2008-09-23
-4el5,2012-07-25,2012-04-10
-3elb,2008-10-21,2008-09-22
-4elh,2013-02-13,2012-04-10
-1elw,2000-04-26,2000-03-14
-2elz,2007-10-02,2007-03-28
-5el6,2016-01-27,2015-11-04
-7el9,2021-05-05,2021-04-09
-5el7,2016-01-27,2015-11-04
-5elx,2016-02-24,2015-11-05
-3ela,2008-11-04,2008-09-21
-2el1,2007-10-02,2007-03-26
-1elc,1994-04-30,1993-12-07
-3elm,2009-07-21,2008-09-22
-5elo,2016-11-16,2015-11-04
-6ela,2018-05-16,2017-09-28
-8elx,2023-09-06,2022-09-26
-5el0,2015-12-02,2015-11-04
-1elm,2002-06-26,2000-03-14
-6el7,2018-02-21,2017-09-28
-8elv,2023-09-06,2022-09-26
-5elb,2016-03-30,2015-11-04
-8ele,2023-02-22,2022-09-23
-5el5,2016-01-27,2015-11-04
-2zti,2008-10-21,2008-10-06
-6ztx,2020-10-07,2020-07-20
-3zte,2011-10-12,2011-07-07
-4zt4,2016-05-04,2015-05-14
-5zth,2018-10-24,2018-05-03
-7ztc,2023-01-11,2022-05-09
-4zt6,2016-05-04,2015-05-14
-5zta,2019-06-12,2018-05-02
-2zt9,2009-02-10,2008-09-27
-7zti,2023-05-24,2022-05-10
-1zt9,2006-05-09,2005-05-26
-6zt9,2021-02-10,2020-07-17
-6ztl,2020-09-16,2020-07-20
-6ztn,2020-09-16,2020-07-20
-2zt7,2009-08-25,2008-09-19
-6ztm,2020-09-16,2020-07-20
-3ztt,2011-12-07,2011-07-12
-4ztz,2015-09-23,2015-05-15
-1ztg,2006-05-27,2005-05-27
-3ztn,2011-08-10,2011-07-12
-5zto,2019-06-12,2018-05-04
-2zt4,2009-02-24,2008-09-18
-5ztl,2018-12-05,2018-05-04
-3zth,2012-07-11,2011-07-08
-3zt6,2011-09-14,2011-07-01
-6ztb,2021-05-05,2020-07-17
-1zth,2005-07-19,2005-05-27
-7ztw,2023-05-24,2022-05-11
-2zt5,2009-08-25,2008-09-19
-2zt6,2009-08-25,2008-09-19
-4ztd,2015-12-16,2015-05-14
-7zt2,2023-06-28,2022-05-09
-5zt1,2018-05-16,2018-05-01
-4ztq,2016-07-20,2015-05-14
-7ztb,2022-11-23,2022-05-09
-3ztm,2011-10-05,2011-07-11
-7zt9,2023-06-28,2022-05-09
-7ztf,2023-03-22,2022-05-10
-7zta,2023-04-12,2022-05-09
-2zth,2009-01-13,2008-10-01
-2zts,2009-03-24,2008-10-08
-3ztd,2012-07-25,2011-07-07
-6zth,2021-06-02,2020-07-20
-7zt0,2023-04-05,2022-05-09
-3ztg,2011-12-07,2011-07-07
-4ztf,2015-10-07,2015-05-14
-3ztz,2011-10-05,2011-07-12
-3zty,2011-10-19,2011-07-12
-4ztl,2015-09-02,2015-05-14
-1zte,2006-05-02,2005-05-26
-3ztv,2011-12-14,2011-07-12
-4zt2,2016-05-04,2015-05-14
-5zt0,2019-03-13,2018-05-01
-3zt0,2012-07-11,2011-07-01
-2zt0,2009-02-24,2008-09-18
-6zti,2021-06-02,2020-07-20
-3zt7,2011-09-14,2011-07-01
-7zt7,2023-06-28,2022-05-09
-4ztm,2015-09-02,2015-05-14
-2ztj,2009-10-13,2008-10-06
-3ztx,2012-02-01,2011-07-12
-4ztv,2016-05-25,2015-05-15
-6ztw,2020-10-07,2020-07-20
-6ztc,2021-07-28,2020-07-17
-6zt3,2021-03-03,2020-07-17
-5ztb,2019-06-12,2018-05-02
-1zt1,2005-10-18,2005-05-26
-2zt1,2009-02-24,2008-09-18
-7ztm,2023-03-22,2022-05-10
-6ztr,2021-05-05,2020-07-20
-7ztl,2023-01-18,2022-05-11
-7ztd,2023-01-11,2022-05-09
-1ztt,2005-08-30,2005-05-27
-2ztw,2009-10-13,2008-10-10
-6ztp,2020-09-16,2020-07-20
-5zty,2019-01-30,2018-05-05
-2ztg,2009-06-30,2008-10-01
-1ztf,2005-07-19,2005-05-26
-2ztu,2009-08-25,2008-10-09
-1zt7,2005-10-18,2005-05-26
-3zt4,2012-07-18,2011-07-01
-1ztc,2005-06-28,2005-05-26
-6zt2,2021-07-28,2020-07-17
-4ztu,2015-09-23,2015-05-15
-4zt5,2016-05-04,2015-05-14
-7ztz,2023-03-22,2022-05-11
-2zt2,2009-02-24,2008-09-18
-7ztk,2023-08-09,2022-05-10
-2ztk,2009-10-13,2008-10-06
-7ztv,2023-03-22,2022-05-11
-6ztu,2021-01-27,2020-07-20
-4ztn,2015-09-02,2015-05-14
-2ztb,2009-01-13,2008-09-29
-1ztj,2006-05-09,2005-05-27
-5zt7,2019-02-27,2018-05-02
-5ztd,2019-05-15,2018-05-02
-7zt8,2023-06-28,2022-05-09
-2zt8,2009-08-25,2008-09-19
-3ztc,2012-07-25,2011-07-06
-2ztl,2009-08-25,2008-10-07
-4zty,2015-12-09,2015-05-15
-4ztr,2016-07-20,2015-05-15
-4zt1,2016-06-01,2015-05-14
-6ztj,2020-09-16,2020-07-20
-7zt5,2023-06-28,2022-05-09
-4zt8,2015-06-03,2015-05-14
-2zt3,2009-02-24,2008-09-18
-4zt3,2016-05-04,2015-05-14
-4zte,2016-06-01,2015-05-14
-7ztn,2023-08-23,2022-05-10
-6ztk,2021-06-02,2020-07-20
-4ztc,2015-07-29,2015-05-14
-6ztv,2020-10-07,2020-07-20
-3zt9,2012-02-22,2011-07-06
-7zt4,2023-06-28,2022-05-09
-3zt3,2012-07-11,2011-07-01
-5ztf,2019-05-22,2018-05-03
-6ztq,2020-10-21,2020-07-20
-1ztq,2006-05-30,2005-05-27
-4zth,2016-06-22,2015-05-14
-4zt7,2016-05-04,2015-05-14
-2ztv,2009-08-25,2008-10-09
-3zt1,2012-07-11,2011-07-01
-1zt5,2005-06-28,2005-05-26
-1ztw,2005-08-30,2005-05-27
-5zt9,2019-06-12,2018-05-02
-4ztj,2015-10-07,2015-05-14
-7ztx,2023-03-22,2022-05-11
-3zt2,2012-07-11,2011-07-01
-5ztk,2018-12-05,2018-05-04
-1ztm,2005-07-19,2005-05-27
-2ztm,2009-08-25,2008-10-07
-1ztu,2005-11-15,2005-05-27
-3zt5,2011-09-14,2011-07-01
-6zto,2020-09-23,2020-07-20
-4ztt,2016-06-15,2015-05-15
-3ztj,2011-08-10,2011-07-08
-1zt2,2005-11-08,2005-05-26
-4zts,2016-07-20,2015-05-15
-1ztl,2006-05-09,2005-05-27
-5ztn,2018-07-18,2018-05-04
-1ztk,2006-05-09,2005-05-27
-4ztx,2015-12-09,2015-05-15
-6zt7,2021-02-10,2020-07-17
-1y8j,2005-06-07,2004-12-13
-4y80,2015-06-17,2015-02-16
-2y8e,2011-07-06,2011-02-04
-7y80,2022-12-14,2022-06-22
-6y8y,2020-12-16,2020-03-06
-6y8b,2020-10-14,2020-03-04
-7y82,2022-12-14,2022-06-22
-5y8o,2018-07-11,2017-08-21
-6y8d,2020-10-14,2020-03-04
-6y8f,2021-03-31,2020-03-04
-4y8s,2015-06-17,2015-02-16
-6y8s,2020-11-18,2020-03-05
-1y8w,2005-01-04,2004-12-13
-5y8a,2017-10-11,2017-08-20
-2y8i,2011-07-20,2011-02-07
-4y8i,2015-06-17,2015-02-16
-7y84,2022-12-14,2022-06-22
-7y83,2022-12-14,2022-06-22
-6y85,2020-03-11,2020-03-03
-4y8v,2016-01-27,2015-02-16
-7y8r,2022-12-07,2022-06-24
-6y8m,2020-03-18,2020-03-05
-6y87,2021-03-31,2020-03-03
-7y8g,2023-04-26,2022-06-23
-5y8h,2018-07-11,2017-08-21
-4y8h,2015-06-17,2015-02-16
-5y8g,2018-07-11,2017-08-21
-7y8m,2023-06-28,2022-06-24
-6y8l,2020-08-12,2020-03-05
-6y8e,2020-10-14,2020-03-04
-5y8j,2018-07-11,2017-08-21
-4y8w,2015-04-15,2015-02-16
-5y8k,2018-07-11,2017-08-21
-2y8l,2011-03-16,2011-02-07
-4y85,2015-05-06,2015-02-16
-1y8h,2005-07-26,2004-12-13
-2y88,2011-03-02,2011-02-03
-5y8l,2018-07-11,2017-08-21
-5y8p,2018-07-11,2017-08-21
-5y8c,2018-06-13,2017-08-21
-1y85,2004-12-21,2004-12-10
-5y80,2018-08-29,2017-08-18
-7y8a,2023-04-12,2022-06-23
-1y83,2004-12-21,2004-12-10
-4y82,2015-06-17,2015-02-16
-7y88,2022-12-21,2022-06-23
-1y8p,2005-05-24,2004-12-13
-7y8y,2023-06-28,2022-06-24
-4y88,2015-10-07,2015-02-16
-2y83,2011-03-30,2011-02-02
-7y8b,2023-06-28,2022-06-23
-4y8m,2015-06-17,2015-02-16
-7y81,2022-12-14,2022-06-22
-2y8b,2011-06-15,2011-02-03
-2y8k,2011-02-16,2011-02-07
-4y8u,2015-06-17,2015-02-16
-7y8d,2023-11-15,2022-06-23
-4y8k,2015-06-17,2015-02-16
-7y8c,2023-06-28,2022-06-23
-2y81,2011-03-16,2011-02-02
-2y85,2011-03-02,2011-02-03
-5y8t,2017-11-29,2017-08-21
-4y87,2015-09-16,2015-02-16
-2y8c,2012-03-07,2011-02-04
-2y8v,2012-02-22,2011-02-10
-6y8c,2020-09-30,2020-03-04
-4y8q,2015-06-17,2015-02-16
-5y8v,2018-04-25,2017-08-21
-4y8l,2015-06-17,2015-02-16
-4y86,2015-09-16,2015-02-16
-1y8y,2005-02-08,2004-12-14
-5y8w,2018-06-13,2017-08-21
-1y8q,2005-01-25,2004-12-13
-1y8n,2005-05-24,2004-12-13
-4y8c,2015-09-16,2015-02-16
-5y8y,2018-06-13,2017-08-21
-1y8k,2005-07-26,2004-12-13
-4y84,2015-06-17,2015-02-16
-5y8z,2018-06-13,2017-08-22
-1y8o,2005-05-24,2004-12-13
-4y8t,2015-06-17,2015-02-16
-1y8i,2005-07-26,2004-12-13
-6y8x,2020-12-16,2020-03-06
-2y8s,2011-08-03,2011-02-10
-5y88,2018-08-01,2017-08-20
-2y8h,2011-02-23,2011-02-07
-2y8u,2012-02-22,2011-02-10
-2y8q,2011-03-16,2011-02-09
-5y8m,2018-07-11,2017-08-21
-7y85,2022-12-14,2022-06-22
-6y8z,2020-12-16,2020-03-06
-4y81,2015-06-17,2015-02-16
-7y8f,2023-04-26,2022-06-23
-6y8o,2020-08-12,2020-03-05
-1y8a,2005-01-25,2004-12-10
-4y8p,2015-06-17,2015-02-16
-5y8x,2018-10-17,2017-08-21
-1y8r,2005-01-25,2004-12-13
-6y82,2020-03-11,2020-03-03
-6y89,2021-03-31,2020-03-04
-6y8a,2020-10-14,2020-03-04
-6y8g,2020-05-20,2020-03-04
-6y8n,2020-08-12,2020-03-05
-4y8n,2015-06-17,2015-02-16
-7y8s,2023-05-24,2022-06-24
-5y84,2018-07-18,2017-08-18
-5y8n,2018-07-11,2017-08-21
-4y8j,2015-06-17,2015-02-16
-2y8r,2011-08-03,2011-02-10
-4y8o,2015-06-17,2015-02-16
-6y80,2020-03-11,2020-03-02
-5y8b,2017-10-11,2017-08-20
-4y8f,2015-07-15,2015-02-16
-2y80,2011-03-16,2011-02-02
-5y86,2018-05-02,2017-08-18
-6y8k,2021-02-03,2020-03-05
-2y8o,2012-02-22,2011-02-08
-6y88,2020-09-23,2020-03-03
-4y8r,2015-06-17,2015-02-16
-6y8p,2021-03-31,2020-03-05
-5y8i,2018-07-11,2017-08-21
-6y81,2020-03-11,2020-03-03
-5y89,2017-10-11,2017-08-20
-4y8x,2015-05-27,2015-02-16
-7y8t,2023-06-28,2022-06-24
-7y8x,2022-10-12,2022-06-24
-4y8d,2015-04-08,2015-02-16
-7y8n,2023-05-03,2022-06-24
-1y8f,2005-04-12,2004-12-12
-4y8y,2015-05-27,2015-02-16
-4y8e,2016-03-02,2015-02-16
-4y8z,2015-05-27,2015-02-16
-4y83,2015-05-06,2015-02-16
-1y8z,2005-08-30,2004-12-14
-1y81,2005-01-25,2004-12-10
-7y8l,2023-06-28,2022-06-24
-7y8o,2023-03-22,2022-06-24
-4y8a,2015-10-07,2015-02-16
-6y8i,2020-06-17,2020-03-05
-2y82,2011-03-16,2011-02-02
-4y8g,2015-06-17,2015-02-16
-6y8h,2020-03-11,2020-03-05
-2y8t,2011-08-03,2011-02-10
-830c,1999-08-06,1998-08-06
-5dn2,2016-07-20,2015-09-09
-4dnc,2012-07-25,2012-02-08
-6dnk,2019-03-13,2018-06-06
-6dnw,2018-10-03,2018-06-08
-8dnk,2022-08-17,2022-07-11
-8dnp,2022-11-16,2022-07-11
-8dn1,2023-02-01,2022-07-10
-4dn8,2012-06-20,2012-02-08
-8dn3,2023-10-11,2022-07-10
-5dn8,2015-10-14,2015-09-09
-7dn6,2020-12-30,2020-12-08
-5dnk,2016-08-10,2015-09-10
-8dnr,2023-07-19,2022-07-11
-7dn3,2021-03-17,2020-12-08
-8dnh,2023-04-12,2022-07-11
-3dn3,2008-11-11,2008-07-01
-7dn4,2021-10-20,2020-12-08
-5dn6,2015-10-28,2015-09-09
-4dnn,2012-09-12,2012-02-08
-3dnz,2009-07-07,2008-07-03
-4dnj,2012-08-15,2012-02-08
-1dna,1998-11-04,1998-06-25
-6dnt,2018-10-03,2018-06-07
-3dni,1994-01-31,1992-08-20
-8dn5,2023-10-11,2022-07-10
-8dny,2023-05-24,2022-07-12
-8dng,2023-07-19,2022-07-11
-5dny,2016-02-24,2015-09-10
-1dnu,2001-12-21,1999-12-16
-5dnr,2016-07-20,2015-09-10
-5dn3,2016-07-20,2015-09-09
-1dnp,1996-08-01,1995-07-03
-3dnt,2009-01-27,2008-07-02
-7dny,2022-06-22,2020-12-11
-2dn1,2006-05-09,2006-04-25
-7dn8,2021-12-15,2020-12-09
-1dnw,2001-12-21,1999-12-16
-6dn8,2019-04-17,2018-06-06
-8dnt,2023-07-19,2022-07-11
-3dn2,2008-11-11,2008-07-01
-4dnz,2012-08-15,2012-02-09
-7dnp,2021-06-23,2020-12-10
-4dnl,2012-02-22,2012-02-08
-4dnm,2012-02-29,2012-02-08
-1dnk,1994-01-31,1992-08-10
-8dn8,2022-09-21,2022-07-10
-8dnu,2022-11-16,2022-07-11
-3dnj,2008-11-18,2008-07-02
-8dnd,2023-08-02,2022-07-11
-2dn3,2006-05-09,2006-04-25
-5dnw,2016-08-17,2015-09-10
-2dnj,1994-01-31,1986-10-21
-8dnx,2023-05-24,2022-07-12
-4dna,2012-03-21,2012-02-08
-5dno,2016-04-06,2015-09-10
-3dnd,2009-06-23,2008-07-02
-7dnz,2022-06-22,2020-12-11
-5dnc,2016-01-13,2015-09-09
-3dng,2009-03-03,2008-07-02
-7dnn,2021-10-20,2020-12-10
-3dne,2009-06-23,2008-07-02
-7dna,2021-01-27,2020-12-09
-8dn2,2023-10-11,2022-07-10
-5dnu,2016-08-17,2015-09-10
-8dnz,2023-05-24,2022-07-12
-6dn6,2019-04-17,2018-06-06
-7dnc,2021-05-05,2020-12-09
-3dn1,2008-11-11,2008-07-01
-2dn2,2006-05-09,2006-04-25
-8dnc,2022-09-21,2022-07-11
-4dn1,2012-03-07,2012-02-08
-1dn2,2000-05-17,1999-12-15
-6dn7,2019-04-17,2018-06-06
-6dnp,2018-09-05,2018-06-07
-4dne,2012-09-26,2012-02-08
-6dnz,2019-06-12,2018-06-08
-7dn1,2022-04-06,2020-12-08
-3dn4,2008-11-11,2008-07-01
-6dnf,2018-07-11,2018-06-06
-6dnl,2018-09-12,2018-06-06
-6dnd,2018-11-14,2018-06-06
-5dn5,2016-02-24,2015-09-09
-4dn5,2012-06-27,2012-02-08
-7dnm,2021-10-20,2020-12-10
-5dnf,2016-04-13,2015-09-10
-4dn2,2012-02-22,2012-02-08
-5dnx,2016-10-05,2015-09-10
-1dnl,2000-01-05,1999-12-16
-5dn1,2015-09-30,2015-09-09
-6dnh,2018-06-27,2018-06-06
-3dn5,2009-04-07,2008-07-01
-3dn8,2008-11-11,2008-07-01
-4dns,2012-12-05,2012-02-08
-7dno,2021-02-10,2020-12-10
-8dn4,2023-10-11,2022-07-10
-6dn5,2019-04-17,2018-06-06
-5dnl,2016-09-28,2015-09-10
-3dnp,2008-07-29,2008-07-02
-6dnj,2018-08-01,2018-06-06
-3dnx,2008-09-02,2008-07-02
-7dnb,2021-01-27,2020-12-09
-2dns,2006-05-09,2006-04-26
-7dn7,2020-12-30,2020-12-09
-8dnn,2023-05-24,2022-07-11
-4dn0,2012-05-23,2012-02-08
-7dnq,2021-12-22,2020-12-10
-1dnc,1998-05-27,1998-02-20
-4dnr,2013-02-13,2012-02-08
-8dn0,2023-06-21,2022-07-10
-3dn6,2008-11-11,2008-07-01
-4dnf,2013-08-07,2012-02-08
-7dn9,2021-12-15,2020-12-09
-6dno,2019-01-23,2018-06-07
-3dn0,2008-11-11,2008-07-01
-6dns,2018-10-03,2018-06-07
-4dno,2013-08-07,2012-02-08
-5dne,2016-01-13,2015-09-10
-7dnr,2021-12-15,2020-12-10
-5dnd,2016-01-13,2015-09-09
-8dne,2022-09-21,2022-07-11
-8dni,2022-08-17,2022-07-11
-7dn0,2021-12-08,2020-12-08
-3dna,2008-11-11,2008-07-01
-5dn9,2016-05-04,2015-09-09
-8dnq,2023-07-19,2022-07-11
-6dna,2018-11-14,2018-06-06
-5dnj,2016-02-24,2015-09-10
-8dnj,2022-08-17,2022-07-11
-6dne,2018-07-18,2018-06-06
-8dnf,2023-04-12,2022-07-11
-6mxy,2019-11-27,2018-10-31
-1mxr,2003-03-25,2002-10-03
-4mxo,2013-12-04,2013-09-26
-6mx0,2018-12-19,2018-10-30
-7mxt,2023-05-10,2021-05-19
-4mxp,2014-03-19,2013-09-26
-3mxy,2011-05-11,2010-05-08
-4mxu,2014-07-30,2013-09-26
-7mx0,2022-05-18,2021-05-17
-3mx5,2010-12-01,2010-05-06
-3mxb,2010-10-06,2010-05-07
-7mx1,2022-03-30,2021-05-17
-1mxg,2003-06-10,2002-10-02
-1mx9,2003-04-08,2002-10-01
-5mxw,2018-04-18,2017-01-25
-4mxa,2013-10-09,2013-09-26
-7mxq,2023-05-10,2021-05-19
-1mxw,2003-06-10,2002-10-03
-5mxy,2018-02-14,2017-01-25
-1mxh,2003-10-14,2002-10-02
-2mx6,2015-12-30,2014-12-15
-4mxr,2013-11-27,2013-09-26
-5mxx,2017-05-24,2017-01-25
-1mx0,2003-01-07,2002-10-01
-5mx8,2017-04-05,2017-01-21
-7mxu,2023-05-10,2021-05-19
-3mxh,2010-08-25,2010-05-07
-5mxv,2017-10-25,2017-01-24
-5mxb,2018-04-18,2017-01-22
-4mxk,2014-02-12,2013-09-26
-4mxy,2013-12-25,2013-09-26
-4mx5,2014-01-15,2013-09-25
-6mx3,2018-12-19,2018-10-30
-3mxt,2010-06-16,2010-05-07
-5mxf,2017-08-09,2017-01-23
-6mxg,2019-07-24,2018-10-30
-5mxj,2017-07-26,2017-01-23
-3mxp,2011-03-23,2010-05-07
-6mxz,2019-11-27,2018-10-31
-6mx5,2018-11-07,2018-10-30
-4mxj,2014-04-02,2013-09-26
-3mxd,2010-11-10,2010-05-07
-5mx4,2017-04-05,2017-01-20
-5mxh,2017-08-09,2017-01-23
-5mx0,2017-03-01,2017-01-20
-3mxa,2010-10-06,2010-05-07
-5mx7,2017-11-29,2017-01-21
-5mxk,2017-05-31,2017-01-23
-7mxy,2021-12-08,2021-05-19
-7mxf,2021-11-17,2021-05-19
-3mx9,2010-10-06,2010-05-07
-3mxf,2010-10-06,2010-05-07
-7mxo,2022-09-28,2021-05-19
-7mx7,2021-11-17,2021-05-18
-7mxv,2023-05-10,2021-05-19
-7mx2,2022-12-14,2021-05-18
-6mxu,2019-05-15,2018-10-31
-2mxp,2015-11-11,2015-01-12
-6mxe,2018-12-19,2018-10-30
-5mxu,2017-07-26,2017-01-24
-4mxq,2015-08-19,2013-09-26
-1mxy,2003-06-10,2002-10-03
-6mx9,2018-12-26,2018-10-30
-6mxb,2019-07-24,2018-10-30
-5mxa,2017-12-20,2017-01-22
-7mx4,2021-11-17,2021-05-18
-5mxq,2018-02-28,2017-01-24
-4mxz,2013-12-04,2013-09-26
-1mxv,2003-06-10,2002-10-03
-1mxd,2003-06-10,2002-10-02
-5mxr,2018-03-14,2017-01-24
-5mxc,2017-12-20,2017-01-22
-6mxs,2019-07-31,2018-10-31
-5mx9,2017-08-09,2017-01-22
-7mxg,2021-11-17,2021-05-19
-7mxh,2021-11-17,2021-05-19
-7mxc,2021-11-17,2021-05-18
-2mxv,2015-01-28,2015-01-16
-7mxk,2021-10-13,2021-05-19
-7mxr,2023-05-10,2021-05-19
-4mxl,2014-02-12,2013-09-26
-5mxe,2017-08-09,2017-01-23
-6mxd,2019-07-24,2018-10-30
-3mxc,2011-05-11,2010-05-07
-1mxa,1996-07-11,1996-01-10
-5mxd,2018-02-14,2017-01-23
-6mx8,2018-12-12,2018-10-30
-5mx2,2017-08-02,2017-01-20
-4mx0,2013-11-20,2013-09-25
-6mxr,2019-07-31,2018-10-31
-4mx1,2014-01-15,2013-09-25
-7mxd,2022-03-30,2021-05-19
-4mx9,2013-10-09,2013-09-26
-3mx6,2010-05-26,2010-05-06
-6mxc,2019-07-24,2018-10-30
-1mx5,2003-04-08,2002-10-01
-7mxa,2021-11-17,2021-05-18
-6mxx,2019-11-27,2018-10-31
-3mx2,2010-12-01,2010-05-06
-1mx3,2002-12-18,2002-10-01
-6mx4,2018-12-19,2018-10-30
-1mxf,2003-10-14,2002-10-02
-5mxo,2017-11-08,2017-01-24
-6mxo,2019-02-13,2018-10-31
-5mx1,2017-03-01,2017-01-20
-7mxs,2023-05-10,2021-05-19
-1mxo,2003-03-04,2002-10-02
-1mx8,2003-07-29,2002-10-01
-1mxc,1996-07-11,1996-01-10
-2mxz,2015-02-11,2015-01-19
-3mx3,2010-07-07,2010-05-06
-1mxl,1999-07-06,1999-04-22
-5mxg,2017-08-09,2017-01-23
-7mxz,2022-06-01,2021-05-19
-7mxj,2021-10-13,2021-05-19
-5mxm,2018-02-14,2017-01-23
-7mxn,2021-11-17,2021-05-19
-1mxu,2003-06-10,2002-10-03
-3mxm,2011-05-18,2010-05-07
-4mxx,2013-12-04,2013-09-26
-7mxi,2021-07-28,2021-05-19
-1mxt,2003-02-25,2002-10-03
-3mx0,2010-06-30,2010-05-06
-3mxw,2010-05-26,2010-05-07
-1mxe,2002-12-04,2002-10-02
-5mx6,2017-04-05,2017-01-21
-7mxx,2023-05-10,2021-05-19
-1mxx,2003-06-10,2002-10-03
-4mxf,2013-12-25,2013-09-26
-1mxb,1996-07-11,1996-01-10
-7mxb,2021-10-13,2021-05-18
-3mxr,2010-11-24,2010-05-07
-4mx2,2014-04-16,2013-09-25
-3mxi,2011-05-18,2010-05-07
-4mx3,2014-01-15,2013-09-25
-3mxe,2010-11-10,2010-05-07
-6mx2,2018-11-14,2018-10-30
-4mxc,2014-10-15,2013-09-26
-1mx1,2003-04-22,2002-10-01
-6mxt,2018-11-14,2018-10-31
-4mx7,2014-10-01,2013-09-25
-4mxe,2015-04-08,2013-09-26
-6mxv,2018-11-21,2018-10-31
-2mxy,2015-02-25,2015-01-19
-3mxs,2010-11-24,2010-05-07
-7mx6,2022-05-18,2021-05-18
-5mxp,2018-07-25,2017-01-24
-3mxg,2011-01-12,2010-05-07
-5mxz,2018-02-14,2017-01-25
-1mxi,2003-02-25,2002-10-02
-7mxp,2022-05-25,2021-05-19
-7mx3,2021-11-24,2021-05-18
-7mxw,2023-05-10,2021-05-19
-1mxz,2003-06-10,2002-10-03
-7mxe,2021-10-27,2021-05-19
-173d,1994-10-15,1994-04-18
-3lpt,2010-05-12,2010-02-05
-7lpp,2021-09-01,2021-02-12
-6lpn,2021-01-13,2020-01-12
-6lpp,2021-01-13,2020-01-12
-1lpg,2003-05-08,2002-05-08
-7lpk,2022-08-10,2021-02-12
-3lpu,2010-05-12,2010-02-06
-7lpy,2022-02-16,2021-02-12
-1lp6,2002-08-07,2002-05-07
-5lpy,2016-08-24,2016-08-15
-7lpz,2022-02-16,2021-02-12
-7lpj,2021-08-04,2021-02-11
-7lpa,2021-07-28,2021-02-11
-1lpc,2004-05-11,2002-05-07
-1lpa,1994-11-01,1994-08-19
-4lpk,2013-11-27,2013-07-16
-6lpf,2020-03-25,2020-01-10
-1lpn,1995-04-20,1995-01-11
-5lpd,2017-07-26,2016-08-12
-6lpe,2021-02-03,2020-01-10
-6lpj,2020-11-25,2020-01-10
-9lpr,1993-01-15,1991-08-05
-5lpr,1993-01-15,1991-08-05
-3lpg,2010-11-17,2010-02-05
-5lpz,2016-08-24,2016-08-15
-5lpl,2017-08-16,2016-08-13
-1lp4,2002-05-29,2002-05-07
-6lpl,2020-11-25,2020-01-11
-4lpg,2014-06-25,2013-07-16
-6lp1,2020-10-07,2020-01-08
-5lpa,2018-01-17,2016-08-12
-3lpn,2011-02-09,2010-02-05
-4lp4,2013-10-16,2013-07-15
-7lp8,2022-02-16,2021-02-11
-7lpt,2022-02-23,2021-02-12
-1lps,1995-02-14,1995-01-05
-3lps,2011-02-16,2010-02-05
-4lp8,2013-11-20,2013-07-15
-4lpy,2014-01-29,2013-07-16
-3lpj,2010-04-14,2010-02-05
-4lp0,2013-11-13,2013-07-14
-5lpq,2017-08-30,2016-08-14
-3lp2,2010-06-09,2010-02-04
-6lpx,2021-01-13,2020-01-12
-5lpg,2016-08-24,2016-08-12
-3lpa,2010-12-08,2010-02-05
-6lpq,2021-01-13,2020-01-12
-7lpf,2022-02-16,2021-02-11
-5lpe,2016-10-05,2016-08-12
-4lph,2014-06-25,2013-07-16
-5lpu,2017-07-05,2016-08-15
-6lpk,2020-11-25,2020-01-10
-4lp1,2014-07-16,2013-07-14
-2lp2,2013-02-20,2012-01-31
-6lpt,2021-01-13,2020-01-12
-7lp6,2022-02-23,2021-02-11
-7lpr,1993-01-15,1991-08-05
-6lpr,1993-01-15,1991-08-05
-6lpv,2021-01-13,2020-01-12
-1lpd,2004-05-11,2002-05-07
-5lpt,2017-08-30,2016-08-14
-3lpo,2010-03-31,2010-02-05
-3lpf,2010-11-17,2010-02-05
-1lp1,2003-03-18,2002-05-07
-7lp7,2022-02-16,2021-02-11
-4lpb,2013-10-30,2013-07-15
-3lp1,2010-06-09,2010-02-04
-4lp9,2014-01-15,2013-07-15
-4lpl,2014-07-16,2013-07-16
-7lpe,2021-07-28,2021-02-11
-5lpp,2017-08-30,2016-08-14
-7lps,2021-06-02,2021-02-12
-4lpc,2015-04-01,2013-07-16
-6lpd,2021-01-13,2020-01-09
-6lp8,2020-09-30,2020-01-09
-1lpf,1994-01-31,1992-10-26
-6lpi,2020-11-18,2020-01-10
-5lpk,2017-08-16,2016-08-13
-7lpu,2022-02-23,2021-02-12
-3lpl,2010-03-02,2010-02-05
-1lph,1996-06-20,1995-04-19
-6lpu,2021-01-13,2020-01-12
-5lpi,2017-01-11,2016-08-13
-5lpj,2017-08-16,2016-08-13
-5lpn,2016-08-24,2016-08-14
-6lps,2021-01-13,2020-01-12
-7lpn,2022-02-23,2021-02-12
-5lpm,2017-08-16,2016-08-13
-3lp5,2010-03-16,2010-02-04
-5lp1,2017-02-01,2016-08-11
-4lps,2013-12-18,2013-07-16
-7lp9,2021-07-28,2021-02-11
-1lpk,2003-05-08,2002-05-08
-1lpv,2002-10-02,2002-05-08
-1lpo,1995-04-20,1995-01-13
-2lpr,1993-01-15,1991-08-05
-3lp7,2010-02-23,2010-02-04
-3lpe,2010-03-09,2010-02-05
-6lp6,2020-09-30,2020-01-09
-7lpx,2021-11-17,2021-02-12
-3lpd,2010-12-08,2010-02-05
-4lp6,2013-10-23,2013-07-15
-5lpb,2016-08-31,2016-08-12
-4lpj,2014-08-06,2013-07-16
-8lpr,1993-01-15,1991-08-05
-4lpi,2014-07-16,2013-07-16
-3lp9,2010-02-23,2010-02-05
-1lpm,1995-04-20,1995-01-06
-7lph,2021-08-04,2021-02-11
-2lp8,2012-04-18,2012-02-03
-4lp7,2013-12-18,2013-07-15
-4lpm,2014-07-16,2013-07-16
-3lpk,2010-04-14,2010-02-05
-7lpo,2021-09-01,2021-02-12
-1lpp,1995-04-20,1995-01-17
-7lpl,2022-02-23,2021-02-12
-7lpd,2021-07-28,2021-02-11
-6lp0,2020-11-18,2020-01-07
-7lpb,2021-07-28,2021-02-11
-3lpc,2010-12-08,2010-02-05
-7lpm,2022-02-23,2021-02-12
-1lpi,1998-06-17,1998-04-15
-3lpi,2010-04-14,2010-02-05
-7lpv,2022-02-23,2021-02-12
-3lpr,1993-01-15,1991-08-05
-5lp6,2016-09-21,2016-08-11
-4lpf,2013-08-28,2013-07-16
-6lpy,2020-07-01,2020-01-12
-5lpo,2017-08-30,2016-08-14
-3lp4,2010-02-23,2010-02-04
-7lpq,2021-09-01,2021-02-12
-3lp3,2010-06-09,2010-02-04
-1lpb,1994-11-01,1994-08-19
-6lp5,2020-04-08,2020-01-08
-6lp7,2020-09-30,2020-01-09
-7lp0,2022-08-10,2021-02-11
-1lpz,2003-05-08,2002-05-08
-3lpb,2010-04-28,2010-02-05
-7lpw,2021-11-17,2021-02-12
-1lp9,2003-11-11,2002-05-07
-3lp0,2010-06-09,2010-02-04
-3lpp,2010-03-31,2010-02-05
-5lps,2017-08-30,2016-08-14
-5lpx,2017-07-05,2016-08-15
-5lpv,2016-08-31,2016-08-15
-4lpn,2014-07-16,2013-07-16
-2lp3,2013-02-20,2012-01-31
diff --git a/src/plinder/data/utils/annotations/static_files/prdcc.chemlib b/src/plinder/data/utils/annotations/static_files/prdcc.chemlib
deleted file mode 100644
index 106762314..000000000
Binary files a/src/plinder/data/utils/annotations/static_files/prdcc.chemlib and /dev/null differ
diff --git a/src/plinder/eval/__init__.py b/src/plinder/eval/__init__.py
index 80a65384e..c65949232 100644
--- a/src/plinder/eval/__init__.py
+++ b/src/plinder/eval/__init__.py
@@ -1,18 +1,7 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
-from textwrap import dedent
+"""Evaluate predictions with OpenStructure and PoseBusters."""
-try:
- import ost # noqa
-except (ImportError, ModuleNotFoundError):
- raise ImportError(
- dedent(
- """\
- plinder.eval requires the OpenStructureToolkit >= 2.8.0 (ost) to be installed.
- Please refer to the documentation for installation instructions and current limitations.
- See details here:
+from plinder.eval.batch import evaluate_predictions
- https://plinder-org.github.io/plinder/contribution/development.html#creating-the-conda-environment
- """
- )
- )
+__all__ = ["evaluate_predictions"]
diff --git a/src/plinder/eval/batch.py b/src/plinder/eval/batch.py
new file mode 100644
index 000000000..05d98a3b6
--- /dev/null
+++ b/src/plinder/eval/batch.py
@@ -0,0 +1,472 @@
+"""Evaluate folders of predictions against PLINDER reference structures."""
+
+from __future__ import annotations
+
+import multiprocessing
+import os
+import sys
+from collections.abc import Mapping, Sequence
+from concurrent.futures import ProcessPoolExecutor, as_completed
+from dataclasses import dataclass, field
+from functools import partial
+from pathlib import Path
+from tempfile import TemporaryDirectory
+from typing import Any, Literal
+from urllib.parse import quote
+
+import pandas as pd
+
+from plinder.core.index.interface import PlinderInterface
+from plinder.core.index.query import query_table
+from plinder.core.index.system import PlinderSystem
+from plinder.core.release import PlinderRelease
+from plinder.core.structure.inputs import (
+ StructureInput,
+ find_structure_files,
+ read_structure_table,
+)
+from plinder.eval.commands import run_openstructure, run_posebusters
+from plinder.eval.inputs import prepare_prediction, reference_ligands
+
+_INTERFACE_METRICS = (
+ "lddt",
+ "ilddt",
+ "qs_global",
+ "qs_best",
+ "dockq",
+ "dockq_ave_full",
+ "dockq_wave_full",
+)
+_LIGAND_COLUMNS = (
+ "ligand_id",
+ "rmsd",
+ "bb_rmsd",
+ "lddt_lp",
+ "rmsd_coverage",
+ "rmsd_model_ligand",
+ "rmsd_unassigned",
+ "lddt_pli",
+ "lddt_pli_coverage",
+ "lddt_pli_model_ligand",
+ "lddt_pli_unassigned",
+)
+
+
+@dataclass(frozen=True)
+class _Reference:
+ kind: str
+ system_id: str
+ receptor: Path
+ ligands: dict[str, Path] = field(default_factory=dict)
+
+
+def _references(
+ name: str, mode: str, release: PlinderRelease, include_all: bool
+) -> tuple[list[_Reference], list[dict[str, str]]]:
+ """Resolve and reconstruct references in the parent, avoiding cache races."""
+ references, failures = [], []
+ column = "entry_pdb_id" if len(name) == 4 and name.isalnum() else "system_id"
+ for kind, table in (
+ ("ligands", "annotation"),
+ ("interfaces", "interface_annotations"),
+ ):
+ if mode not in (kind, "both"):
+ continue
+ try:
+ rows = query_table(
+ table,
+ columns=["system_id"],
+ filters=[(column, "==", name)],
+ release=release,
+ )
+ except Exception as exc:
+ failures.append(
+ {"system_id": name, "error": f"{table}: {type(exc).__name__}: {exc}"}
+ )
+ continue
+ for system_id in sorted(set(rows["system_id"])):
+ try:
+ if kind == "ligands":
+ system = PlinderSystem(system_id=system_id, release=release)
+ reference = _Reference(
+ kind,
+ system_id,
+ Path(system.receptor_cif).resolve(),
+ reference_ligands(system, include_all_ligands=include_all),
+ )
+ else:
+ interface = PlinderInterface(system_id=system_id, release=release)
+ reference = _Reference(
+ kind, system_id, Path(interface.interface_cif).resolve()
+ )
+ references.append(reference)
+ except Exception as exc:
+ failures.append(
+ {"system_id": system_id, "error": f"{type(exc).__name__}: {exc}"}
+ )
+ if not references and not failures:
+ failures.append(
+ {"system_id": name, "error": f"No {mode} references found for {name}"}
+ )
+ return references, failures
+
+
+def _ligand_rows(
+ result: dict[str, Any], reference: _Reference, model_ids: dict[str, str]
+) -> list[dict[str, Any]]:
+ """Keep each reference ligand and each metric's independent assignment."""
+ reference_ids = {
+ str(path.resolve()): ligand_id for ligand_id, path in reference.ligands.items()
+ }
+ if set(result["reference_ligands"]) != set(reference_ids):
+ raise ValueError("OST reference ligands differ from the selected reference")
+ rows = {
+ key: {"ligand_id": value, "status": "success"}
+ for key, value in reference_ids.items()
+ }
+ for metric in ("rmsd", "lddt_pli"):
+ assigned = set()
+ for score in result[metric]["assigned_scores"]:
+ key = score["reference_ligand"]
+ if key in assigned:
+ raise ValueError(f"OST assigned {key} twice for {metric}")
+ assigned.add(key)
+ row = rows[key]
+ row[metric] = score["score"]
+ row[f"{metric}_coverage"] = score["coverage"]
+ row[f"{metric}_model_ligand"] = model_ids[score["model_ligand"]]
+ if metric == "rmsd":
+ row.update({key: score[key] for key in ("bb_rmsd", "lddt_lp")})
+ unassigned = result[metric]["reference_ligand_unassigned_reason"]
+ if assigned & unassigned.keys() or assigned | unassigned.keys() != rows.keys():
+ raise ValueError(f"OST returned incomplete {metric} assignments")
+ for key, reason in unassigned.items():
+ rows[key][f"{metric}_unassigned"] = reason[0]
+ for row in rows.values():
+ if "rmsd" not in row and "lddt_pli" not in row:
+ row["status"] = "unassigned"
+ return list(rows.values())
+
+
+def _worker_threads() -> None:
+ from threadpoolctl import threadpool_limits
+
+ # OST subprocesses inherit these limits; PoseBusters' own pool is disabled.
+ for variable in (
+ "OMP_NUM_THREADS",
+ "OPENBLAS_NUM_THREADS",
+ "MKL_NUM_THREADS",
+ "BLIS_NUM_THREADS",
+ "NUMEXPR_NUM_THREADS",
+ ):
+ os.environ[variable] = "1"
+ # Spawn imports pandas/NumPy before the initializer. Limit their already
+ # loaded BLAS/OpenMP runtimes, not just libraries in future subprocesses.
+ threadpool_limits(limits=1)
+ if "numexpr" in sys.modules:
+ sys.modules["numexpr"].set_num_threads(1)
+
+
+def _evaluate_one(
+ task: tuple[Path | StructureInput, str, list[_Reference]],
+ *,
+ output_dir: Path,
+ posebusters: bool,
+ ligand_smiles: dict[str, str],
+ ligand_ccd_codes: dict[str, str],
+ ligand_chains: tuple[str, ...],
+ ligand_options: tuple[str, ...],
+ interface_options: tuple[str, ...],
+ ost_executable: str,
+) -> dict[str, list[dict[str, Any]]]:
+ source, prediction, references = task
+ model = Path(source.coordinates) if isinstance(source, StructureInput) else source
+ details = output_dir / "details" / prediction
+ results: dict[str, list[dict[str, Any]]] = {
+ key: [] for key in ("ligands", "interfaces", "posebusters", "failures")
+ }
+
+ def failure(stage: str, exc: Exception, system_id: str = "") -> None:
+ results["failures"].append(
+ {
+ "prediction": prediction,
+ "system_id": system_id,
+ "stage": stage,
+ "error": f"{type(exc).__name__}: {exc}",
+ }
+ )
+
+ # Interface comparisons do not depend on ligand chemistry or PoseBusters.
+ for ref in references:
+ if ref.kind != "interfaces":
+ continue
+ row = {"prediction": prediction, "system_id": ref.system_id, "status": "error"}
+ try:
+ native = run_openstructure(
+ model,
+ ref.receptor,
+ details / f"interface-{quote(ref.system_id, safe='._-')}.json",
+ action="compare-structures",
+ options=interface_options,
+ executable=ost_executable,
+ )
+ row.update({key: native[key] for key in _INTERFACE_METRICS})
+ row["status"] = "success"
+ except Exception as exc:
+ failure("interfaces", exc, ref.system_id)
+ results["interfaces"].append(row)
+
+ ligand_refs = [ref for ref in references if ref.kind == "ligands"]
+ if not ligand_refs:
+ return results
+ prepared = None
+ try:
+ prepared = prepare_prediction(
+ source
+ if isinstance(source, StructureInput)
+ else StructureInput.from_path(model),
+ details / "model",
+ ligand_smiles=ligand_smiles,
+ ligand_ccd_codes=ligand_ccd_codes,
+ ligand_chains=ligand_chains,
+ )
+ except Exception as exc:
+ failure("prepare", exc)
+ for ref in ligand_refs:
+ rows = [
+ {"ligand_id": ligand_id, "status": "error"} for ligand_id in ref.ligands
+ ]
+ if prepared is not None:
+ try:
+ native = run_openstructure(
+ prepared.receptor,
+ ref.receptor,
+ details / f"ligands-{quote(ref.system_id, safe='._-')}.json",
+ action="compare-ligand-structures",
+ options=[
+ *ligand_options,
+ "--model-ligands",
+ *map(str, prepared.ligands.values()),
+ "--reference-ligands",
+ *(str(path.resolve()) for path in ref.ligands.values()),
+ ],
+ executable=ost_executable,
+ )
+ rows = _ligand_rows(
+ native,
+ ref,
+ {str(path): key for key, path in prepared.ligands.items()},
+ )
+ except Exception as exc:
+ failure("ligands", exc, ref.system_id)
+ results["ligands"].extend(
+ {"prediction": prediction, "system_id": ref.system_id, **row}
+ for row in rows
+ )
+ if posebusters and prepared is not None and prepared.ligands:
+ try:
+ checks = run_posebusters(
+ list(prepared.ligands.values()),
+ prepared.receptor_molecule,
+ details / "posebusters.csv",
+ )
+ ids = {str(path): key for key, path in prepared.ligands.items()}
+ checks["model_ligand"] = checks["file"].map(ids)
+ if checks["model_ligand"].isna().any() or checks["position"].ne(0).any():
+ raise ValueError("PoseBusters poses differ from the prepared ligands")
+ checks["prediction"] = prediction
+ results["posebusters"] = checks.drop(
+ columns=["file", "molecule"], errors="ignore"
+ ).to_dict("records")
+ except Exception as exc:
+ failure("posebusters", exc)
+ return results
+
+
+def evaluate_predictions(
+ predictions: str | Path | pd.DataFrame,
+ *,
+ output_dir: str | Path,
+ release: PlinderRelease | None = None,
+ mode: Literal["ligands", "interfaces", "both"] = "both",
+ num_workers: int = 1,
+ include_all_ligands: bool = False,
+ posebusters: bool = True,
+ ligand_smiles: Mapping[str, str] | None = None,
+ ligand_ccd_codes: Mapping[str, str] | None = None,
+ ligand_chains: Sequence[str] = (),
+ ligand_options: Sequence[str] = (),
+ interface_options: Sequence[str] = (),
+ ost_executable: str | Path = "ost",
+) -> dict[str, pd.DataFrame]:
+ """Evaluate a CSV/TSV/Parquet input table or reference-ID prediction folders.
+
+ Tables use ``input_id``, ``structure_path``, ``reference_id`` and optional
+ ``ligand_path`` columns. Repeat an input row for multiple ligand SDFs.
+ Relative paths are resolved from the table directory; DataFrames use the
+ working directory. Table ``input_id`` values identify predictions in results.
+
+ A reference ID is a PLINDER system/interface ID, or a four-character PDB ID
+ to compare against all its systems/interfaces. Each mmCIF (also .mmcif or
+ gzip-compressed) is a separate prediction. Interface comparisons also accept
+ PDB files (.pdb or .pdb.gz), passed directly to OST. For ligand evaluation,
+ pair a receptor PDB/mmCIF with ``model.sdf`` or ``model.ligands/*.sdf``; each
+ SDF contains one ligand in the receptor's coordinate frame. An empty ligand
+ folder represents zero predicted poses. Otherwise ligands are extracted
+ from a complete mmCIF. ``mode`` selects ligand or interface evaluation, or
+ both. References come from the selected release.
+
+ ``num_workers`` limits concurrent prediction processes. PoseBusters runs
+ without its own process pool. When calling from a Python script, put the
+ call inside ``if __name__ == '__main__':``.
+
+ Ligand rows correspond to proper reference ligands by default; set
+ ``include_all_ligands`` to include reference ions/artifacts too. Predictions
+ are not filtered by artifact status or receptor proximity. Missing poses
+ remain as unassigned reference rows. Preparation/tool errors retain error
+ rows and are listed separately, not converted to scientific scores.
+
+ CCD/SMILES mappings and ``ligand_chains`` are passed to ``prepare_prediction``
+ for every model. ``ligand_options`` and ``interface_options`` pass additional
+ native OST flags to the respective actions.
+
+ Returns tables keyed by ``ligands``, ``interfaces``, ``posebusters``, and
+ ``failures``; also writes the first three as Parquet and ``failures.tsv``.
+ Ligand metrics keep separate ``rmsd_model_ligand``/``lddt_pli_model_ligand``
+ assignments. Join either to PoseBusters on prediction and model_ligand.
+ PoseBusters covers all candidate predicted ligands, including unmatched ones.
+ Native JSON, CSV, logs and prepared coordinates remain under ``details/``.
+ Every call reruns comparisons and replaces the summary tables; old details
+ are never read as results.
+ """
+ if (
+ isinstance(num_workers, bool)
+ or not isinstance(num_workers, int)
+ or num_workers < 1
+ ):
+ raise ValueError("num_workers must be a positive integer")
+ if mode not in {"ligands", "interfaces", "both"}:
+ raise ValueError("mode must be ligands, interfaces, or both")
+ output_dir = Path(output_dir).resolve()
+ groups: dict[str, list[tuple[Path | StructureInput, str]]] = {}
+ if isinstance(predictions, pd.DataFrame) or Path(predictions).is_file():
+ for input_id, structure in read_structure_table(
+ predictions, require_reference=True
+ ).items():
+ assert structure.reference_id is not None
+ groups.setdefault(structure.reference_id, []).append((structure, input_id))
+ else:
+ root = Path(predictions).resolve()
+ if not root.is_dir():
+ raise NotADirectoryError(root)
+ for folder in sorted(root.iterdir()):
+ if not folder.is_dir() or folder.name.startswith("."):
+ continue
+ groups[folder.name] = [
+ (path, str(path.relative_to(root)))
+ for path in find_structure_files(folder)
+ ]
+ tasks: list[tuple[Path | StructureInput, str, list[_Reference]]] = []
+ collected: dict[str, list[dict[str, Any]]] = {
+ key: [] for key in ("ligands", "interfaces", "posebusters", "failures")
+ }
+ for reference_id, models in groups.items():
+ if not models:
+ continue
+ refs, failures = _references(
+ reference_id, mode, release or PlinderRelease(), include_all_ligands
+ )
+ collected["failures"].extend(
+ {
+ "prediction": prediction,
+ "stage": "reference",
+ **failure,
+ }
+ for _, prediction in models
+ for failure in failures
+ )
+ tasks.extend((model, prediction, refs) for model, prediction in models if refs)
+ if not tasks and not collected["failures"]:
+ raise ValueError(
+ "No mmCIF or PDB predictions found in reference-ID subdirectories"
+ )
+ output_dir.mkdir(parents=True, exist_ok=True)
+ worker = partial(
+ _evaluate_one,
+ output_dir=output_dir,
+ posebusters=posebusters,
+ ligand_smiles=dict(ligand_smiles or {}),
+ ligand_ccd_codes=dict(ligand_ccd_codes or {}),
+ ligand_chains=tuple(ligand_chains),
+ ligand_options=tuple(ligand_options),
+ interface_options=tuple(interface_options),
+ ost_executable=str(ost_executable),
+ )
+ with ProcessPoolExecutor(
+ max_workers=num_workers,
+ mp_context=multiprocessing.get_context("spawn"),
+ initializer=_worker_threads,
+ ) as pool:
+ futures = {pool.submit(worker, task): task for task in tasks}
+ for future in as_completed(futures):
+ try:
+ for key, rows in future.result().items():
+ collected[key].extend(rows)
+ except Exception as exc:
+ _, prediction, refs = futures[future]
+ collected["failures"].append(
+ {
+ "prediction": prediction,
+ "system_id": "",
+ "stage": "worker",
+ "error": f"{type(exc).__name__}: {exc}",
+ }
+ )
+ for ref in refs:
+ for ligand in ref.ligands if ref.kind == "ligands" else [None]:
+ collected[ref.kind].append(
+ {
+ "prediction": prediction,
+ "system_id": ref.system_id,
+ "status": "error",
+ **({"ligand_id": ligand} if ligand is not None else {}),
+ }
+ )
+ schemas = {
+ "ligands": ["prediction", "system_id", "status", *_LIGAND_COLUMNS],
+ "interfaces": ["prediction", "system_id", "status", *_INTERFACE_METRICS],
+ "posebusters": ["prediction", "model_ligand", "position"],
+ "failures": ["prediction", "system_id", "stage", "error"],
+ }
+ tables = {}
+ with TemporaryDirectory(dir=output_dir, prefix=".tables-") as temporary:
+ for key, rows in collected.items():
+ columns = list(
+ dict.fromkeys(
+ [*schemas[key], *(column for row in rows for column in row)]
+ )
+ )
+ frame = pd.DataFrame(rows).reindex(columns=columns)
+ frame = frame.where(frame.notna(), None)
+ order = [
+ column
+ for column in (
+ "prediction",
+ "system_id",
+ "ligand_id",
+ "model_ligand",
+ "stage",
+ )
+ if column in frame
+ ]
+ tables[key] = frame.sort_values(order).reset_index(drop=True)
+ pending = Path(temporary) / (
+ "failures.tsv" if key == "failures" else f"{key}.parquet"
+ )
+ if key == "failures":
+ tables[key].to_csv(pending, sep="\t", index=False)
+ else:
+ tables[key].to_parquet(pending, index=False)
+ for pending in Path(temporary).iterdir():
+ pending.replace(output_dir / pending.name)
+ return tables
diff --git a/src/plinder/eval/cli.py b/src/plinder/eval/cli.py
new file mode 100644
index 000000000..1fbc9004b
--- /dev/null
+++ b/src/plinder/eval/cli.py
@@ -0,0 +1,127 @@
+"""Command-line entry point for folder-based prediction evaluation."""
+
+from __future__ import annotations
+
+import argparse
+import json
+import shlex
+from collections.abc import Sequence
+from pathlib import Path
+
+from plinder.core.release import PlinderRelease
+from plinder.eval.batch import evaluate_predictions
+
+
+def _component_mapping(value: str) -> dict[str, str]:
+ try:
+ mapping = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise argparse.ArgumentTypeError(
+ f"Expected a JSON component mapping: {exc}"
+ ) from exc
+ if not isinstance(mapping, dict) or any(
+ not isinstance(key, str)
+ or not key.strip()
+ or not isinstance(item, str)
+ or not item.strip()
+ for key, item in mapping.items()
+ ):
+ raise argparse.ArgumentTypeError('Use a JSON object such as {"LIG": "ATP"}')
+ return mapping
+
+
+def main(argv: Sequence[str] | None = None) -> int:
+ """Return zero on completion, one for recorded errors, two for invalid input."""
+ parser = argparse.ArgumentParser(
+ description="Evaluate an input table or predictions// folder with OpenStructure and PoseBusters. Tables use input_id, structure_path, reference_id and optional ligand_path. Reference IDs may be PLINDER system/interface IDs or four-character PDB IDs."
+ )
+ parser.add_argument(
+ "predictions",
+ type=Path,
+ help="CSV/TSV/Parquet input table, or a folder with reference-ID subdirectories",
+ )
+ parser.add_argument("--output-dir", type=Path, required=True)
+ parser.add_argument(
+ "--mode", choices=("ligands", "interfaces", "both"), default="both"
+ )
+ parser.add_argument(
+ "--num-workers",
+ type=int,
+ default=1,
+ help="Maximum concurrent prediction processes (default: 1)",
+ )
+ parser.add_argument(
+ "--data-dir",
+ type=Path,
+ help="Local PLINDER release; otherwise use the configured release",
+ )
+ parser.add_argument(
+ "--include-all-ligands",
+ action="store_true",
+ help="Include reference ions/artifacts, not only proper ligands",
+ )
+ parser.add_argument(
+ "--no-posebusters", action="store_true", help="Skip PoseBusters checks"
+ )
+ parser.add_argument(
+ "--ligand-smiles",
+ type=_component_mapping,
+ help='JSON component-to-SMILES mapping, e.g. {"LIG": "CCO"}',
+ )
+ parser.add_argument(
+ "--ligand-ccd-codes",
+ type=_component_mapping,
+ help='JSON component-to-CCD mapping, e.g. {"LIG": "ATP"}',
+ )
+ parser.add_argument(
+ "--ligand-chain",
+ action="append",
+ default=[],
+ help="Also treat this polymer label asym ID as a ligand; repeat for multiple chains",
+ )
+ parser.add_argument(
+ "--ligand-options",
+ type=shlex.split,
+ default=(),
+ help="Additional OST ligand flags as one quoted string; use --ligand-options='--flag value'",
+ )
+ parser.add_argument(
+ "--interface-options",
+ type=shlex.split,
+ default=(),
+ help="Additional OST interface flags as one quoted string; use --interface-options='--flag value'",
+ )
+ parser.add_argument(
+ "--ost-executable",
+ default="ost",
+ help="Path to the OST executable (default: ost)",
+ )
+ args = parser.parse_args(argv)
+ try:
+ tables = evaluate_predictions(
+ args.predictions,
+ output_dir=args.output_dir,
+ release=PlinderRelease(data_dir=args.data_dir)
+ if args.data_dir is not None
+ else None,
+ mode=args.mode,
+ num_workers=args.num_workers,
+ include_all_ligands=args.include_all_ligands,
+ posebusters=not args.no_posebusters,
+ ligand_smiles=args.ligand_smiles,
+ ligand_ccd_codes=args.ligand_ccd_codes,
+ ligand_chains=args.ligand_chain,
+ ligand_options=args.ligand_options,
+ interface_options=args.interface_options,
+ ost_executable=args.ost_executable,
+ )
+ except (OSError, ValueError) as exc:
+ parser.error(str(exc))
+ for name, table in tables.items():
+ print(f"{name}: {len(table)} rows")
+ print(f"Results: {args.output_dir.resolve()}")
+ return int(not tables["failures"].empty)
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/src/plinder/eval/commands.py b/src/plinder/eval/commands.py
new file mode 100644
index 000000000..ea7353daf
--- /dev/null
+++ b/src/plinder/eval/commands.py
@@ -0,0 +1,147 @@
+"""Run OpenStructure and PoseBusters on prepared structures.
+
+Results retain the tools' field names and assignments. Reference selection and
+PLINDER's proper-ligand selection belong to the calling workflow.
+"""
+
+from __future__ import annotations
+
+import json
+import subprocess
+from collections.abc import Iterator, Sequence
+from contextlib import contextmanager
+from pathlib import Path
+from tempfile import TemporaryDirectory
+from typing import TYPE_CHECKING, Any, Literal
+
+import pandas as pd
+
+if TYPE_CHECKING:
+ from rdkit.Chem import Mol
+
+
+@contextmanager
+def _run(command: list[str], output: Path) -> Iterator[Path]:
+ """Keep a tool log and replace results only after successful parsing."""
+ output.parent.mkdir(parents=True, exist_ok=True)
+ log = output.with_suffix(output.suffix + ".log")
+ with TemporaryDirectory(dir=output.parent, prefix=".evaluation-") as temporary:
+ pending = Path(temporary) / output.name
+ with log.open("w") as stream:
+ completed = subprocess.run(
+ [*command, "--output", str(pending)],
+ stdout=stream,
+ stderr=subprocess.STDOUT,
+ check=False,
+ )
+ if completed.returncode or not pending.is_file():
+ raise RuntimeError(
+ f"{command[0]} failed (exit {completed.returncode}); see {log}: "
+ f"{log.read_text()[-2000:]}"
+ )
+ yield pending
+ pending.replace(output)
+
+
+def run_openstructure(
+ model: str | Path,
+ reference: str | Path,
+ output: str | Path,
+ *,
+ action: Literal["compare-structures", "compare-ligand-structures"],
+ options: Sequence[str] = (),
+ executable: str | Path = "ost",
+) -> dict[str, Any]:
+ """Run an OST comparison and return its complete JSON result.
+
+ ``model`` and ``reference`` are coordinate files accepted by OST. Ligand
+ comparisons include lDDT-PLI, binding-site-superposed RMSD, backbone RMSD
+ (``bb_rmsd``) and lDDT-LP. Structure comparisons include lDDT, iLDDT,
+ QS-score and DockQ, including penalties for unmapped reference interfaces.
+ ``options`` passes additional CLI arguments directly
+ to OST, for example ``["--model-ligands", "pose.sdf"]``. Embedded mmCIF
+ ligands use OST's own detection and chemistry rules.
+
+ The JSON file and a sibling ``.log`` file are retained. Failed comparisons
+ raise an error, including when OST reports FAILURE with a zero exit code.
+ Requires the ``ost`` executable from Bioconda's OpenStructure package.
+ """
+ metrics = {
+ "compare-structures": ["--lddt", "--ilddt", "--qs-score", "--dockq"],
+ "compare-ligand-structures": ["--lddt-pli", "--rmsd"],
+ }
+ if action not in metrics:
+ raise ValueError(f"Unsupported OST action: {action}")
+ command = [
+ str(executable),
+ action,
+ "--model",
+ str(Path(model).resolve()),
+ "--reference",
+ str(Path(reference).resolve()),
+ *metrics[action],
+ *options,
+ ]
+ with _run(command, Path(output)) as pending:
+ result = json.loads(pending.read_text())
+ if not isinstance(result, dict) or result.get("status") != "SUCCESS":
+ raise RuntimeError(f"OpenStructure comparison failed: {result}")
+ return result
+
+
+def run_posebusters(
+ ligands: Sequence[str | Path],
+ receptor: Mol,
+ output: str | Path,
+ *,
+ full_report: bool = False,
+) -> pd.DataFrame:
+ """Check SDF poses against a receptor RDKit molecule with residue metadata.
+
+ Create the receptor using ``biotite.interface.rdkit.to_mol(receptor_atoms)``.
+ Its residue names and hetero flags let PoseBusters distinguish receptor,
+ cofactor and water atoms. An SDF round trip loses that distinction.
+ Ligands must have lowercase ``.sdf`` extensions. The returned table and CSV
+ retain PoseBusters' columns, file names and SDF record positions.
+ Requires ``pip install plinder[eval]``.
+
+ Failed plausibility checks are returned as False. A missing/unreadable
+ result or an unloaded receptor raises an error, because intermolecular
+ checks would otherwise be absent.
+ """
+ from posebusters import PoseBusters
+ from rdkit.Chem import Mol
+
+ if not isinstance(receptor, Mol):
+ raise TypeError("receptor must be an RDKit molecule with residue metadata")
+ if receptor.GetNumAtoms() == 0 or any(
+ atom.GetPDBResidueInfo() is None for atom in receptor.GetAtoms()
+ ):
+ raise ValueError("receptor atoms must have residue metadata for PoseBusters")
+ if isinstance(ligands, (str, Path)) or not ligands:
+ raise ValueError("Provide a nonempty list of ligand SDF paths")
+ paths = [Path(path).resolve() for path in ligands]
+ if any(path.suffix != ".sdf" for path in paths):
+ raise ValueError("PoseBusters ligand files must have the .sdf extension")
+ for path in paths:
+ if not path.is_file():
+ raise FileNotFoundError(path)
+ result = (
+ PoseBusters(config="dock", max_workers=0)
+ .bust(mol_pred=paths, mol_cond=receptor, full_report=full_report)
+ .reset_index()
+ )
+ required = {"file", "position", "mol_pred_loaded", "mol_cond_loaded"}
+ if result.empty or not required.issubset(result.columns):
+ raise RuntimeError("PoseBusters returned incomplete results")
+ if set(result["file"].astype(str)) != {str(path) for path in paths}:
+ raise RuntimeError("PoseBusters did not report all requested ligand files")
+ if not result["mol_cond_loaded"].eq(True).all():
+ raise RuntimeError("PoseBusters could not load the receptor")
+ output = Path(output)
+ output.parent.mkdir(parents=True, exist_ok=True)
+ with TemporaryDirectory(dir=output.parent, prefix=".evaluation-") as temporary:
+ pending = Path(temporary) / output.name
+ result.to_csv(pending, index=False)
+ pending.replace(output)
+ return result
diff --git a/src/plinder/eval/docking/__init__.py b/src/plinder/eval/docking/__init__.py
deleted file mode 100644
index 2bc0efc66..000000000
--- a/src/plinder/eval/docking/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
diff --git a/src/plinder/eval/docking/make_plots.py b/src/plinder/eval/docking/make_plots.py
deleted file mode 100644
index 99a003768..000000000
--- a/src/plinder/eval/docking/make_plots.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-from dataclasses import dataclass
-from pathlib import Path
-
-import numpy as np
-import pandas as pd
-import plotly.express as px
-
-from plinder.core.utils.log import setup_logger
-from plinder.eval.docking.stratify_test_set import STRATIFICATION_LABELS
-
-LOG = setup_logger(__name__)
-
-# TODO: need a better way to keep this in sync with stratify_test_set.py SIMILARITY_METRICS
-METRICS_DICT = {
- "pocket_qcov": "POCKET SHARED",
- "pocket_lddt": "POCKET LDDT",
- "protein_lddt_weighted_sum": "PROTEIN LDDT",
- "protein_seqsim_weighted_sum": "PROTEIN SEQSIM",
- "pli_unique_qcov": "PLI SHARED",
- "tanimoto_similarity_max": "LIGAND SIMILARITY",
-}
-
-ANALYSES = {
- "S": "Success Rate",
- "XS": "Excess Success Rate",
- "EF": "Enrichment Factor",
- "delta_RMSD": "Change in mean RMSD",
- "delta_lDDT_PLI": "Change in mean lDDT-PLI",
- "CDF": "Cumulative Leakage Fraction",
-}
-
-
-@dataclass
-class EvaluationResults:
- data: pd.DataFrame
- output_dir: Path
-
- @classmethod
- def from_scores_and_data_files(
- cls, score_file: Path, data_file: Path, output_dir: Path, top_n: int = 10
- ) -> "EvaluationResults":
- # for eval we use aggregate (wave) scores
- # multi ligand systems have them duplicated per each ligand entry
- # drop them to avoid multiple counting when scoring the same pose
- # i.e. keep one aggregate score (wave) per model
- scores_df = pd.read_parquet(score_file).drop_duplicates(["reference", "rank"])
- data_df = pd.read_parquet(data_file)
- merged_df = scores_df[scores_df["reference"].isin(data_df["system_id"])].merge(
- data_df, left_on="reference", right_on="system_id", how="left"
- )
- merged_df["bisy_rmsd_wave"] = merged_df["bisy_rmsd_wave"].fillna(
- np.nanmax(merged_df["bisy_rmsd_wave"])
- )
- merged_df["lddt_pli_wave"] = merged_df["lddt_pli_wave"].fillna(0)
- merged_df["success"] = merged_df["bisy_rmsd_wave"] <= 2
- merged_df["rank"] = merged_df["rank"].astype(int)
- output_dir.mkdir(exist_ok=True)
- merged_df.to_parquet(output_dir / "merged.parquet")
- data = cls(merged_df, output_dir)
- data.write_results_table(True, top_n)
- data.write_results_table(False, top_n)
- data.write_leakage_plots(True, top_n)
- data.write_leakage_plots(False, top_n)
- return data
-
- def write_results_table(
- self, only_passes_quality: bool = True, top_n: int = 10
- ) -> None:
- results = []
- sub_df = self.data[self.data["rank"] <= top_n].reset_index(drop=True)
- output_suffix = ""
- if only_passes_quality:
- sub_df = sub_df[sub_df["passes_quality"]].reset_index(drop=True)
- output_suffix += "_quality"
- if not len(sub_df):
- LOG.warning("No systems passed quality control")
- return
- for label in ["all"] + STRATIFICATION_LABELS:
- if label == "all":
- sub_df_label = sub_df.copy(deep=True)
- else:
- sub_df_label = sub_df[sub_df[label]].reset_index(drop=True)
- if not len(sub_df_label):
- LOG.warning(f"No systems in {label} category at top {top_n}")
- continue
- row = {
- "Subset": label,
- "No. systems": sub_df_label["reference"].nunique(),
- "Top n": top_n,
- }
- sub_df_top_n = sub_df_label.loc[
- sub_df_label[sub_df_label["rank"] <= top_n]
- .groupby("reference")["bisy_rmsd_wave"]
- .idxmin()
- ]
- row["Success Rate (%)"] = (
- 100
- * sub_df_top_n[sub_df_top_n["success"]]["reference"].nunique()
- / sub_df_top_n["reference"].nunique()
- )
- row["Median RMSD"] = np.median(sub_df_top_n["bisy_rmsd_wave"])
- row["Stdev RMSD"] = np.std(sub_df_top_n["bisy_rmsd_wave"])
- row["Mean lDDT-PLI"] = np.median(sub_df_top_n["lddt_pli_wave"])
- row["Stdev lDDT-PLI"] = np.std(sub_df_top_n["lddt_pli_wave"])
- results.append(row)
- result_df = pd.DataFrame(results)
- result_df.to_csv(self.output_dir / f"results{output_suffix}.csv", index=False)
-
- def write_leakage_plots(
- self, only_passes_quality: bool = True, top_n: int = 1
- ) -> None:
- sub_df = self.data[self.data["rank"] <= top_n].reset_index(drop=True)
- output_suffix = f"_topn{top_n}"
- if only_passes_quality:
- sub_df = sub_df[sub_df["passes_quality"]].reset_index(drop=True)
- if not len(sub_df):
- LOG.warning(f"No systems passed quality control at top {top_n}")
- return
- output_suffix += "_quality"
- df_analysis = perf_vs_traindist_all(sub_df)
- for plot_type in ANALYSES:
- plot_leakage_vs_perfomance(
- df_analysis,
- analysis_Y=plot_type,
- output_html_file=self.output_dir / f"{plot_type}{output_suffix}.html",
- )
-
-
-def perf_vs_traindist(
- df: pd.DataFrame,
- metric: str = "pli_qcov",
- bins: np.ndarray = np.linspace(0, 100, 11),
-) -> dict[str, np.ndarray]:
- sr_total = sum(df["success"]) / len(df)
- mean_rmsd_total = sum(df["bisy_rmsd_wave"]) / len(df)
- mean_lddt_pli_total = sum(df["lddt_pli_wave"]) / len(df)
- y: dict[str, list[float]] = {x: [] for x in ANALYSES}
- for dist in bins:
- train_leaked = df[metric] >= 100 - dist
- sr = sum(df[train_leaked]["success"]) / np.max([sum(train_leaked), 1])
- mean_rmsd = sum(df["bisy_rmsd_wave"][train_leaked]) / np.max(
- [sum(train_leaked), 1]
- )
- mean_lddt_pli = sum(df["lddt_pli_wave"][train_leaked]) / np.max(
- [sum(train_leaked), 1]
- )
- fraction_leaked = sum(train_leaked) / len(train_leaked)
- y["S"].append(sr)
- y["XS"].append(sr - sr_total)
- y["EF"].append(sr / sr_total)
- y["delta_RMSD"].append(mean_rmsd - mean_rmsd_total)
- y["delta_lDDT_PLI"].append(mean_lddt_pli_total - mean_lddt_pli)
- y["CDF"].append(fraction_leaked)
- Y = [y]
- trends = {k: np.array([yi[k] for yi in Y]) for k in Y[0].keys()}
- return trends
-
-
-def perf_vs_traindist_all(
- df: pd.DataFrame, xbins: np.ndarray = np.linspace(0, 100, 11)
-) -> pd.DataFrame:
- data = []
- for metric in METRICS_DICT:
- trends = perf_vs_traindist(df, metric=metric, bins=xbins)
- for k, v in trends.items():
- data += [
- {
- "metric": metric,
- "cutoff": x,
- "mean": np.mean(v[:, ix]),
- "err": np.std(v[:, ix]) / np.sqrt(len(v[:, ix])),
- "analysis": k,
- }
- for ix, x in enumerate(xbins)
- ]
- return pd.DataFrame.from_records(data)
-
-
-def plot_leakage_vs_perfomance(
- df_analysis: pd.DataFrame,
- output_html_file: Path,
- analysis_Y: str,
- plot_dimension: tuple[int, int] = (400, 650),
-) -> None:
- xaxis_label = "Distance to Train Set"
-
- symbols = ["circle", "square", "star", "diamond", "hourglass", "pentagon", "cross"]
- colors = ["lightblue", "pink", "lightgreen", "purple", "goldenrod", "red", "blue"]
-
- df_plot = df_analysis[df_analysis.analysis == analysis_Y].reset_index(drop=True)
- df_plot.metric = df_plot.metric.map(METRICS_DICT)
- df_plot = df_plot.rename(
- columns={
- "cutoff": xaxis_label,
- "mean": ANALYSES[analysis_Y],
- "metric": "Metric",
- }
- )
- no_of_colors = len(df_plot.Metric.unique())
-
- fig = px.scatter(
- df_plot,
- x=xaxis_label,
- y=ANALYSES[analysis_Y],
- color="Metric",
- error_y="err",
- color_discrete_sequence=colors[:no_of_colors],
- symbol="Metric",
- symbol_sequence=symbols[:no_of_colors],
- height=plot_dimension[0],
- width=plot_dimension[1],
- )
-
- fig.update_layout(
- {"plot_bgcolor": "rgba(0, 0, 0, 0)"},
- legend=dict(
- traceorder="normal",
- font=dict(size=16, color="black"),
- ),
- font=dict(size=18),
- yaxis=dict(tickfont=dict(size=18)),
- xaxis=dict(tickfont=dict(size=18)),
- legend_title=None,
- )
- fig.update_xaxes(showline=True, linewidth=2, linecolor="black", color="black")
- fig.update_yaxes(showline=True, linewidth=2, linecolor="black", color="black")
- fig.update_traces(
- marker=dict(size=12, line=dict(width=1, color="DarkSlateGrey")),
- selector=dict(mode="markers"),
- )
- fig.write_html(output_html_file)
-
-
-def plot_cmd(args: list[str] | None = None) -> None:
- import argparse
-
- parser = argparse.ArgumentParser(
- description="Write evaluation results for a stratified test set"
- )
- parser.add_argument(
- "--score_file",
- type=Path,
- help="Path to scores file generated by plinder_eval",
- )
- parser.add_argument(
- "--data_file",
- type=Path,
- help="Path to test data file generated by plinder_stratify",
- )
- parser.add_argument(
- "--output_dir",
- type=Path,
- help="Path to output folder where result tables and plots are saved",
- )
- parser.add_argument(
- "--max_top_n",
- type=int,
- default=1,
- help="Maximum rank to use for Top n calculations",
- )
-
- ns, unknown_args = parser.parse_known_args(args=args)
- if len(unknown_args):
- LOG.warning(f"ignoring arguments {unknown_args}")
- Path(ns.output_dir).mkdir(parents=True, exist_ok=True)
- EvaluationResults.from_scores_and_data_files(
- score_file=ns.score_file,
- data_file=ns.data_file,
- output_dir=ns.output_dir,
- top_n=ns.max_top_n,
- )
-
-
-if __name__ == "__main__":
- plot_cmd()
diff --git a/src/plinder/eval/docking/stratify_test_set.py b/src/plinder/eval/docking/stratify_test_set.py
deleted file mode 100644
index 933086b4e..000000000
--- a/src/plinder/eval/docking/stratify_test_set.py
+++ /dev/null
@@ -1,457 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-from dataclasses import dataclass, field
-from pathlib import Path
-
-import numpy as np
-import pandas as pd
-from tqdm import tqdm
-
-import plinder.core.utils.config
-from plinder.core.scores.index import query_index
-from plinder.core.scores.protein import cross_similarity as protein_cross_similarity
-from plinder.core.structure import smallmols_similarity
-from plinder.core.utils.cpl import get_plinder_path
-from plinder.core.utils.log import setup_logger
-
-cfg = plinder.core.get_config()
-
-LOG = setup_logger(__name__)
-
-SIMILARITY_METRICS = (
- # pli
- "pli_unique_qcov",
- # protein
- "protein_seqsim_weighted_sum",
- "protein_fident_weighted_sum",
- "protein_lddt_weighted_sum",
- # pocket
- "pocket_fident_qcov",
- "pocket_lddt_qcov",
- "pocket_lddt",
- "pocket_qcov",
- # ligand
- "tanimoto_similarity_max",
- "mmp_similarity_max",
-)
-
-STRATIFICATION_LABELS = [
- "novel_pocket_pli",
- "novel_ligand",
- "novel_protein",
- "novel_all",
-]
-
-
-def compute_protein_max_similarities(
- left: set[str], right: set[str], metric: str, output_file: Path
-) -> None:
- LOG.info(
- f"compute_protein_max_similarities: Computing max similarities for {metric}"
- )
- protein_cross_similarity(
- query_systems=left,
- target_systems=right,
- metric=metric,
- ).rename(
- columns={"query_system": "system_id", "target_system": "train_system_id"}
- ).to_parquet(output_file, index=False)
- LOG.info(
- f"compute_protein_max_similarities: Done computing max similarities for {metric}"
- )
-
-
-def compute_ligand_ecfp_max_similarities(
- df: pd.DataFrame,
- split_label: str,
- train_label: str,
- test_label: str,
- output_file: Path,
-) -> None:
- if "fp" not in df.columns:
- smiles_fp_dict = {
- smi: smallmols_similarity.mol2morgan_fp(smi)
- for smi in df["ligand_rdkit_canonical_smiles"].drop_duplicates().to_list()
- }
- df["fp"] = df["ligand_rdkit_canonical_smiles"].map(smiles_fp_dict)
-
- df_test = df.loc[df[split_label] == test_label][
- ["system_id", "ligand_rdkit_canonical_smiles", "fp"]
- ].copy()
-
- (
- df_test["tanimoto_similarity_max"],
- argmax_array,
- ) = smallmols_similarity.tanimoto_maxsim_and_argmax(
- df.loc[df[split_label] == train_label, "fp"].to_list(),
- df_test["fp"].to_list(),
- )
- # get most similar smiles in train
- train_smiles = df.loc[
- df[split_label] == train_label, "ligand_rdkit_canonical_smiles"
- ].to_list()
- df_test[f"tanimoto_most_similar_{train_label}_smiles"] = [
- train_smiles[idx] for idx in argmax_array
- ]
-
- df_test.drop("fp", axis=1).groupby(
- ["system_id", "ligand_rdkit_canonical_smiles"]
- ).agg("max").reset_index().to_parquet(output_file, index=False)
-
-
-def compute_ligand_mmp_max_similarities(
- df: pd.DataFrame,
- split_label: str,
- train_label: str,
- test_label: str,
- output_file: Path,
-) -> None:
- mmp_path = get_plinder_path(rel="mmp/plinder_mms.csv.gz")
- mmp_sim_dict: dict[
- str, dict[str, float]
- ] = smallmols_similarity.get_mmp_similarity_dict(mmp_path=mmp_path)
-
- if "inchikey" not in df.columns:
- smi_inchikey_map = {
- smi: smallmols_similarity.smiles2inchikey(smi, remove_stereo=True)
- for smi in df.ligand_rdkit_canonical_smiles.unique()
- }
- df["inchikey"] = df.ligand_rdkit_canonical_smiles.map(smi_inchikey_map)
- df_test = df.loc[df[split_label] == test_label][
- ["system_id", "ligand_rdkit_canonical_smiles", "inchikey"]
- ].copy()
- train_inchikeys = (
- df[df.split == train_label]["inchikey"].drop_duplicates().to_list()
- )
- test_inchikeys = df_test["inchikey"].drop_duplicates().to_list()
- test_train_sims = {}
- for test_ink in test_inchikeys:
- if test_ink in train_inchikeys:
- # by definition 1 if in train set
- max_similarity = 1.0
- max_sim_inchikey = test_ink
- else:
- # get similarity dictionary
- sim_dict_i = mmp_sim_dict.get(test_ink, {})
- if sim_dict_i:
- similarities = [sim_dict_i.get(ink, 0) for ink in train_inchikeys]
- max_similarity = np.max(similarities)
- max_sim_inchikey = train_inchikeys[np.argmax(similarities)]
- else:
- max_similarity = 0.0
-
- # get first SMILES in train set that match most similar inchikey
- if max_similarity > 0:
- most_similar_smiles_in_train = df.loc[
- (df[split_label] == train_label) & (df["inchikey"] == max_sim_inchikey),
- "ligand_rdkit_canonical_smiles",
- ].iloc[0]
- else:
- most_similar_smiles_in_train = None
- # store
- test_train_sims[test_ink] = [max_similarity, most_similar_smiles_in_train]
-
- df_test["mmp_similarity_max"] = df_test["inchikey"].apply(
- lambda x: test_train_sims[x][0]
- )
- df_test[f"mmp_most_similar_{train_label}_smiles"] = df_test["inchikey"].apply(
- lambda x: test_train_sims[x][1]
- )
- # save
- df_test.groupby(["system_id", "ligand_rdkit_canonical_smiles"]).agg(
- "max"
- ).reset_index().to_parquet(output_file, index=False)
-
-
-@dataclass
-class StratifiedTestSet:
- split_df: pd.DataFrame
- output_dir: Path
- split_label: str = "split"
- train_label: str = "train"
- test_label: str = "test"
- similarity_thresholds: dict[str, int] = field(
- default_factory=lambda: dict(
- pli_unique_qcov=50,
- pocket_lddt_qcov=50,
- pocket_lddt=50,
- pocket_qcov=50,
- protein_seqsim_weighted_sum=30,
- protein_lddt_weighted_sum=50,
- tanimoto_similarity_max=30,
- mmp_similarity_max=50,
- )
- )
- similarity_combinations: dict[str, list[str]] = field(
- default_factory=lambda: {
- "novel_pocket_pli": ["pli_unique_qcov", "pocket_qcov", "pocket_lddt_qcov"],
- "novel_protein": [
- "protein_seqsim_weighted_sum",
- "protein_lddt_weighted_sum",
- ],
- "novel_ligand": [
- "tanimoto_similarity_max",
- "mmp_similarity_max",
- ],
- "novel_all": [
- "pli_unique_qcov",
- "pocket_qcov",
- "pocket_lddt",
- "protein_seqsim_weighted_sum",
- "protein_lddt_weighted_sum",
- "tanimoto_similarity_max",
- ],
- }
- )
- max_similarities: pd.DataFrame = field(
- default_factory=lambda: pd.DataFrame( # type: ignore
- columns=["system_id"] + list(SIMILARITY_METRICS)
- )
- )
-
- @classmethod
- def from_split(
- cls,
- split_file: Path,
- output_dir: Path,
- split_label: str = "split",
- train_label: str = "train",
- test_label: str = "test",
- overwrite: bool = False,
- ) -> "StratifiedTestSet":
- if split_file.name.endswith(".csv"):
- split_df = pd.read_csv(split_file)
- else:
- split_df = pd.read_parquet(split_file)
- assert all(x in split_df.columns for x in [split_label, "system_id"])
- split_df = split_df[split_df[split_label].isin([train_label, test_label])][
- [split_label, "system_id"]
- ].reset_index(drop=True)
- data = cls(
- split_df=split_df,
- output_dir=output_dir,
- split_label=split_label,
- train_label=train_label,
- test_label=test_label,
- )
- data.output_dir.mkdir(exist_ok=True)
- data.compute_train_test_max_similarity(overwrite=overwrite)
- data.assign_test_set_quality()
- data.stratify_test_set()
- data.max_similarities.to_parquet(data.output_dir / f"{test_label}_set.parquet")
- return data
-
- def stratify_test_set(self) -> None:
- for label, metric_list in self.similarity_combinations.items():
- self.max_similarities[label] = np.logical_and.reduce(
- [
- self.max_similarities[metric] < self.similarity_thresholds[metric]
- for metric in metric_list
- ]
- )
- LOG.info(
- f'stratify_test_set: Found {self.max_similarities[self.max_similarities[label]]["system_id"].nunique()} systems labelled {label} ({self.max_similarities[self.max_similarities[label] & self.max_similarities["passes_quality"]]["system_id"].nunique()} passing quality)'
- )
- self.max_similarities["not_novel"] = np.logical_and.reduce(
- [~self.max_similarities[label] for label in self.similarity_combinations]
- )
- LOG.info(
- f'stratify_test_set: Found {self.max_similarities[self.max_similarities["not_novel"]]["system_id"].nunique()} systems labelled not_novel ({self.max_similarities[self.max_similarities["not_novel"] & self.max_similarities["passes_quality"]]["system_id"].nunique()} passing quality)'
- )
-
- def get_filename(self, metric: str) -> Path:
- return (
- self.output_dir
- / f"max_similarities__{self.test_label}_vs_{self.train_label}__{metric}.parquet"
- )
-
- def compute_train_test_max_similarity(
- self, overwrite: bool = False
- ) -> pd.DataFrame:
- left, right = (
- set(
- self.split_df[self.split_df[self.split_label] == self.train_label][
- "system_id"
- ]
- ),
- set(
- self.split_df[self.split_df[self.split_label] == self.test_label][
- "system_id"
- ]
- ),
- )
- LOG.info(
- f"compute_train_test_max_similarity: Found {len(left)} train and {len(right)} test systems"
- )
- for metric in tqdm(SIMILARITY_METRICS):
- if overwrite or not (self.get_filename(metric)).exists():
- if metric in ["tanimoto_similarity_max", "mmp_similarity_max"]:
- # avoid repetitive local assignment
- if "df" not in locals():
- df = query_index(
- columns=[
- "system_id",
- "ligand_rdkit_canonical_smiles",
- ],
- filters=[ # type: ignore
- ("system_id", "in", left.union(right)),
- ("ligand_is_ion", "==", False),
- ("ligand_is_artifact", "==", False),
- ],
- splits=["*"],
- ).drop(columns=["split"])
- df = df.merge(self.split_df, on="system_id", how="left")
- if metric == "tanimoto_similarity_max":
- compute_ligand_ecfp_max_similarities(
- df,
- self.split_label,
- self.train_label,
- self.test_label,
- self.get_filename(metric),
- )
- elif metric == "mmp_similarity_max":
- compute_ligand_mmp_max_similarities(
- df,
- self.split_label,
- self.train_label,
- self.test_label,
- self.get_filename(metric),
- )
- else:
- compute_protein_max_similarities(
- left, right, metric, self.get_filename(metric)
- )
-
- per_metric_similarities = []
- for metric in SIMILARITY_METRICS:
- df = pd.read_parquet(self.get_filename(metric))
- df = df.loc[df.groupby("system_id")[metric].idxmax()]
- df = df[df["system_id"].isin(right)].reset_index(drop=True)
- if "train_system_id" in df.columns:
- df = df.drop(columns="train_system_id")
- if "ligand_rdkit_canonical_smiles" in df.columns:
- df = df.drop(columns="ligand_rdkit_canonical_smiles")
- per_metric_similarities.append(df.set_index("system_id"))
- self.max_similarities = pd.concat(
- per_metric_similarities, join="outer", axis=1
- ).reset_index()
- LOG.info(
- f'compute_train_test_max_similarity: Got max similarities for {self.max_similarities["system_id"].nunique()} systems'
- )
- systems_with_similarities = set(self.max_similarities["system_id"])
- extra_rows = []
- for system in right.difference(systems_with_similarities):
- extra_row = {"system_id": system}
- for metric in SIMILARITY_METRICS:
- extra_row[metric] = np.nan
- extra_rows.append(extra_row)
- if len(extra_rows):
- LOG.info(
- f"compute_train_test_max_similarity: Adding nan similarities for {len(extra_rows)} systems"
- )
- self.max_similarities = pd.concat(
- [self.max_similarities, pd.DataFrame(extra_rows)]
- )
- with pd.option_context("future.no_silent_downcasting", True):
- # FutureWarning: Downcasting object dtype arrays on .fillna, .ffill, .bfill is deprecated and will change in a future version.
- self.max_similarities = self.max_similarities.fillna(0)
-
- def assign_test_set_quality(self) -> None:
- df = query_index(
- filters=[
- (
- "system_id",
- "in",
- set(
- self.split_df[
- self.split_df[self.split_label] == self.test_label
- ]["system_id"]
- ),
- )
- ], # type: ignore
- columns=[
- "system_id",
- "system_pass_validation_criteria",
- ],
- splits=["*"],
- ).drop(columns=["split"])
- quality = dict(
- zip(df["system_id"], df["system_pass_validation_criteria"].fillna(False))
- )
- missing_systems = set(
- self.max_similarities[~self.max_similarities["system_id"].isin(quality)][
- "system_id"
- ]
- )
- if len(missing_systems):
- LOG.info(
- f"Discarding {len(missing_systems)} as they are not in the plindex"
- )
- self.max_similarities = self.max_similarities[
- self.max_similarities["system_id"].isin(quality)
- ].reset_index(drop=True)
- self.max_similarities["passes_quality"] = self.max_similarities[
- "system_id"
- ].map(lambda x: quality.get(x, False))
- LOG.info(
- f'assign_test_set_quality: Found {self.max_similarities[self.max_similarities["passes_quality"]]["system_id"].nunique()} '
- f'out of {self.max_similarities["system_id"].nunique()} systems passing quality'
- )
-
-
-def stratify_cmd(args: list[str] | None = None) -> None:
- import argparse
-
- parser = argparse.ArgumentParser(description="Annotate and stratify a test set")
- parser.add_argument(
- "--split_file",
- type=Path,
- help="Path to split file with [system_id, split] as columns",
- )
- parser.add_argument(
- "--output_dir",
- type=Path,
- help="Path to output folder where similarity and stratification data are saved",
- )
- parser.add_argument(
- "--split_label",
- type=str,
- default="split",
- help="split= is used to get split systems",
- )
- parser.add_argument(
- "--train_label",
- type=str,
- default="train",
- help="split= is used to get train systems",
- )
- parser.add_argument(
- "--test_label",
- type=str,
- default="test",
- help="split= is used to get test systems",
- )
- parser.add_argument(
- "--overwrite",
- action="store_true",
- help="Overwrite max similarity files",
- )
-
- ns, unknown_args = parser.parse_known_args(args=args)
- if len(unknown_args):
- LOG.warning(f"ignoring arguments {unknown_args}")
-
- StratifiedTestSet.from_split(
- split_file=Path(ns.split_file),
- output_dir=Path(ns.output_dir),
- split_label=ns.split_label,
- train_label=ns.train_label,
- test_label=ns.test_label,
- overwrite=ns.overwrite,
- )
-
-
-if __name__ == "__main__":
- stratify_cmd()
diff --git a/src/plinder/eval/docking/utils.py b/src/plinder/eval/docking/utils.py
deleted file mode 100644
index b27939997..000000000
--- a/src/plinder/eval/docking/utils.py
+++ /dev/null
@@ -1,506 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-import copy
-from dataclasses import dataclass, field
-from pathlib import Path
-from typing import Any
-
-import numpy as np
-from ost import io, mol
-from ost.mol.alg.ligand_scoring_lddtpli import LDDTPLIScorer
-from ost.mol.alg.ligand_scoring_scrmsd import SCRMSDScorer
-from ost.mol.alg.scoring import Scorer
-from posebusters import PoseBusters
-
-from plinder.core import PlinderSystem
-from plinder.core.utils.log import setup_logger
-
-LOG = setup_logger(__name__)
-
-
-@dataclass
-class LigandScores:
- chain: str
- residue_number: int
- sdf_file: Path
- atom_count: int
- protein_chain_mapping: dict[str, str] | None = None
- scores: dict[str, float | None] = field(default_factory=dict)
- reference_ligand: dict[str, "LigandScores"] = field(default_factory=dict)
- posebusters: dict[str, Any] = field(default_factory=dict)
-
-
-@dataclass
-class ProteinScores:
- chain_mapping: dict[str, str]
- lddt: float
- bb_lddt: float
- per_chain_lddt: dict[str, float] = field(default_factory=dict)
- per_chain_bb_lddt: dict[str, float] = field(default_factory=dict)
- per_chain_coverage: dict[str, float] = field(default_factory=dict)
- score_oligo: bool = False
- oligomer_scores: dict[str, float] = field(default_factory=dict)
-
-
-@dataclass
-class ComplexData:
- name: str
- receptor_file: Path
- ligand_files: list[Path]
- receptor_entity: mol.EntityHandle
- ligand_views: list[mol.EntityHandle]
- num_ligands: int
- num_proteins: int
-
- @classmethod
- def from_plinder_system(cls, system: PlinderSystem) -> "ComplexData":
- ligand_views = []
- ligand_files = []
- for ligand in system.ligand_sdfs:
- ligand_views.append(system.ligand_views[ligand])
- ligand_files.append(Path(system.ligand_sdfs[ligand]))
- return cls(
- name=system.system_id,
- receptor_file=Path(
- system.receptor_pdb
- ), # PoseBusters requires a PDB file, but entity is built from CIF
- ligand_files=ligand_files,
- receptor_entity=system.receptor_entity,
- ligand_views=ligand_views,
- num_ligands=system.num_ligands,
- num_proteins=system.num_proteins,
- )
-
- @classmethod
- def from_files(
- cls, name: str, receptor_file: Path, ligand_files: list[Path]
- ) -> "ComplexData":
- if receptor_file.suffix not in [".cif", ".pdb"]:
- raise ValueError(
- f"receptor_file must be a .cif or .pdb file, got {receptor_file}"
- )
- if receptor_file.suffix == ".cif":
- entity = io.LoadMMCIF(receptor_file.as_posix(), fault_tolerant=True)
- else:
- entity = io.LoadPDB(receptor_file.as_posix(), fault_tolerant=True)
-
- ligand_views = []
- for i, ligand_file in enumerate(ligand_files):
- ligand_entity = io.LoadEntity(str(ligand_file), format="sdf")
-
- # rename ligand chain to have different chain names for each ligand
- # this is necessary for ost to not complain about duplicate chain names
- editor = ligand_entity.EditXCS()
- # default chain name format is 00001_{sdf_mol_name}, but sdf_mol_name is often empty
- resname = list(ligand_entity.residues)[0].name
- if not resname:
- resname = ligand_file.stem
- editor.RenameChain(list(ligand_entity.chains)[0], f"{i+1:05d}_{resname}")
- ligand_entity = ligand_entity.Select("ele != H")
- ligand_views.append(ligand_entity)
-
- return cls(
- name=name,
- receptor_file=receptor_file,
- ligand_files=ligand_files,
- receptor_entity=entity,
- ligand_views=ligand_views,
- num_ligands=len(ligand_files),
- # TODO: this definition needs a fix due to inconsistencies
- num_proteins=sum(
- 1
- for x in entity.chains
- if x.type == mol.CHAINTYPE_POLY_PEPTIDE_L
- # Comment out to avoid counting water molecules as proteins!
- or x.type == mol.CHAINTYPE_UNKNOWN
- ),
- )
-
-
-@dataclass
-class ModelScores:
- reference: ComplexData
- model: ComplexData
- score_protein: bool = False
- score_posebusters: bool = False
- score_posebusters_full_report: bool = False
- posebusters_mapper: str = "bisy_rmsd"
- num_mapped_reference_ligands: int = 0
- num_mapped_model_ligands: int = 0
- ligand_scores: list[LigandScores] | None = None
- num_mapped_reference_proteins: int = 0
- num_mapped_model_proteins: int = 0
- protein_scores: ProteinScores | None = None
-
- @classmethod
- def from_model_files(
- cls,
- model_name: str,
- model_receptor_file: Path,
- model_ligand_files: list[Path],
- reference: PlinderSystem,
- score_protein: bool = False,
- score_posebusters: bool = False,
- score_posebusters_full_report: bool = False,
- ) -> "ModelScores":
- """
- Create a ModelScores object from a model (receptor file and a list of ligand SDF files) and a reference PlinderSystem.
-
- Parameters
- ----------
- model_file : Path
- The path to the model file.
- model_ligand_files : list[Path]
- The list of ligand SDF files OR a path to directory with SDF files.
- reference : PlinderSystem
- The reference system.
- score_protein : bool, default=False
- Whether to score the protein.
- score_posebusters : bool, default=False
- Whether to score posebusters.
- score_posebusters_full_report : bool, default=False
- Whether to score posebusters with the full report.
-
- Returns
- -------
- ModelScores
- The ModelScores object.
- """
- model = ComplexData.from_files(
- model_name, model_receptor_file, model_ligand_files
- )
- model_class = cls(
- reference=ComplexData.from_plinder_system(reference),
- model=model,
- score_protein=score_protein,
- score_posebusters=score_posebusters or score_posebusters_full_report,
- score_posebusters_full_report=score_posebusters_full_report,
- )
- if model_class.score_protein:
- model_class.calculate_protein_scores()
- model_class.calculate_ligand_scores()
- return model_class
-
- @classmethod
- def from_model_and_reference_files(
- cls,
- model_name: str,
- model_receptor_file: Path,
- model_ligand_files: list[Path],
- reference_name: str,
- reference_receptor_file: Path,
- reference_ligand_files: list[Path],
- score_protein: bool = False,
- score_posebusters: bool = False,
- score_posebusters_full_report: bool = False,
- ) -> "ModelScores":
- """
- Create a ModelScores object from both model and reference (receptor file and a list of ligand SDF files both both).
-
- Parameters
- ----------
- model_file : Path
- The path to the model file.
- model_ligand_sdf_files : list[str | Path]
- The list of ligand SDF files.
- reference_name : str
- The name of the reference system.
- reference_receptor_file : Path
- The path to the reference receptor file.
- reference_ligand_files : list[Path]
- The list of reference ligand SDF files.
- score_protein : bool, default=False
- Whether to score the protein.
- score_posebusters : bool, default=False
- Whether to score posebusters.
- score_posebusters_full_report : bool, default=False
- Whether to score posebusters with the full report.
-
- Returns
- -------
- ModelScores
- The ModelScores object.
- """
- model = ComplexData.from_files(
- model_name, model_receptor_file, model_ligand_files
- )
- reference = ComplexData.from_files(
- reference_name, reference_receptor_file, reference_ligand_files
- )
- model_class = cls(
- reference=reference,
- model=model,
- score_protein=score_protein,
- score_posebusters=score_posebusters or score_posebusters_full_report,
- score_posebusters_full_report=score_posebusters_full_report,
- )
- if model_class.score_protein:
- model_class.calculate_protein_scores()
- model_class.calculate_ligand_scores()
- return model_class
-
- def calculate_protein_scores(self, lddt_add_mdl_contacts: bool = False) -> None:
- scorer = Scorer(
- model=self.model.receptor_entity,
- target=self.reference.receptor_entity,
- lddt_add_mdl_contacts=lddt_add_mdl_contacts,
- )
- self.protein_scores = ProteinScores(
- chain_mapping={k: v for k, v in scorer.mapping.alns.keys()},
- lddt=scorer.lddt,
- bb_lddt=scorer.bb_lddt,
- )
- self.num_mapped_reference_proteins = len(scorer.mapping.alns)
- self.num_mapped_proteins = len(scorer.mapping.alns)
- local_lddt = scorer.local_lddt
- self.protein_scores.per_chain_lddt = {}
- bb_local_lddt = scorer.bb_local_lddt
- self.protein_scores.per_chain_bb_lddt = {}
- for reference_chain, model_chain in self.protein_scores.chain_mapping.items():
- reference_chain_length = len(
- self.reference.receptor_entity.FindChain(reference_chain).residues
- )
- self.protein_scores.per_chain_coverage[model_chain] = (
- len(local_lddt[model_chain]) / reference_chain_length
- )
- self.protein_scores.per_chain_lddt[model_chain] = (
- sum(v for v in local_lddt[model_chain].values() if v is not None)
- / reference_chain_length
- )
- self.protein_scores.per_chain_bb_lddt[model_chain] = (
- sum(v for v in bb_local_lddt[model_chain].values() if v is not None)
- / reference_chain_length
- )
- if self.reference.num_proteins > 1 and self.model.num_proteins > 1:
- self.protein_scores.score_oligo = True
- self.protein_scores.oligomer_scores = {
- "qs_global": scorer.qs_global,
- "qs_best": scorer.qs_best,
- "dockq_wave": scorer.dockq_wave,
- "dockq_ave": scorer.dockq_ave,
- # TODO: add more interface scores
- }
-
- def calculate_ligand_scores(self) -> None:
- pb = PoseBusters(config="dock")
-
- scrmsd_scorer = SCRMSDScorer(
- model=self.model.receptor_entity,
- target=self.reference.receptor_entity,
- model_ligands=self.model.ligand_views,
- target_ligands=self.reference.ligand_views,
- substructure_match=True,
- resnum_alignments=False,
- )
- lddt_pli_scorer = LDDTPLIScorer(
- model=self.model.receptor_entity,
- target=self.reference.receptor_entity,
- model_ligands=self.model.ligand_views,
- target_ligands=self.reference.ligand_views,
- substructure_match=True,
- add_mdl_contacts=True,
- resnum_alignments=False,
- )
- self.ligand_scores = []
- scrmsd_aux, lddt_pli_aux = (
- scrmsd_scorer.aux,
- lddt_pli_scorer.aux,
- )
- assigned_model = set()
- assigned_target = set()
- lddt_pli_assignment = {v: k for k, v in lddt_pli_scorer.assignment}
- scrmsd_assignment = {v: k for k, v in scrmsd_scorer.assignment}
- for m, (ligand, sdf_file) in enumerate(
- zip(self.model.ligand_views, self.model.ligand_files)
- ):
- for residue in ligand.residues:
- chain_name = residue.chain.name
- residue_number = residue.number.num
- ligand_class = LigandScores(
- chain_name, residue_number, Path(sdf_file), len(residue.atoms)
- )
- scrmsd_aux_ligand = scrmsd_aux.get(chain_name, {}).get(
- residue_number, {}
- )
- ligand_class.protein_chain_mapping = scrmsd_aux_ligand.get(
- "chain_mapping", None
- )
- for name, aux, score_name, assignment in zip(
- ["bisy_rmsd", "lddt_lp", "lddt_pli"],
- [
- scrmsd_aux_ligand,
- scrmsd_aux_ligand,
- lddt_pli_aux.get(chain_name, {}).get(residue_number, {}),
- ],
- ["rmsd", "lddt_lp", "lddt_pli"],
- [scrmsd_assignment, scrmsd_assignment, lddt_pli_assignment],
- ):
- ligand_class.scores[name] = aux.get(score_name, None)
- if "target_ligand" in aux:
- ligand_class.reference_ligand[name] = LigandScores(
- aux["target_ligand"].chain.name,
- aux["target_ligand"].number.num,
- Path(self.reference.ligand_files[assignment[m]]),
- len(aux["target_ligand"].atoms),
- )
- if (
- self.score_posebusters
- and ligand_class.reference_ligand.get(self.posebusters_mapper, None)
- is not None
- # only score ligands that have been mapped with posebusters_mapper (bisy_rmsd)
- ):
- if self.model.receptor_file.suffix != ".pdb":
- # WARNING posebusters.tools.loading:loading.py:46 Could not load molecule from receptor.cif with error: Unknown file type .cif
- # TODO: perform format conversion from .cif to .pdb ?
- LOG.warning(
- f"PoseBusters may not accept the receptor file ({self.model.receptor_file}) not in PDB format"
- )
- result_dict = pb.bust(
- mol_pred=ligand_class.sdf_file,
- mol_true=ligand_class.reference_ligand[
- self.posebusters_mapper
- ].sdf_file,
- mol_cond=self.model.receptor_file,
- full_report=self.score_posebusters_full_report,
- ).to_dict()
- # the assumption of key is prepended by ost, eg. '00001_1.D' or '00001_6YYO_Q1K_BBB_323'
- key = (
- str(ligand_class.sdf_file),
- "_".join(chain_name.split("_")[1:]),
- )
- try:
- ligand_class.posebusters = {
- k: v[key] for k, v in result_dict.items()
- }
- except KeyError:
- try:
- # posebusters default when no name is present in SDF
- key = (str(ligand_class.sdf_file), "mol_at_pos_0")
- ligand_class.posebusters = {
- k: v[key] for k, v in result_dict.items()
- }
- except KeyError:
- # this should not be the case as it should be handled
- key = (
- str(ligand_class.sdf_file),
- ligand_class.sdf_file.stem,
- )
- ligand_class.posebusters = {
- k: v[key] for k, v in result_dict.items()
- }
- # print(f"key used {key}")
- if ligand_class.protein_chain_mapping is not None:
- assigned_model.add(chain_name)
- assigned_target.add(
- ligand_class.reference_ligand["bisy_rmsd"].chain
- )
- self.ligand_scores.append(ligand_class)
- self.num_mapped_reference_ligands = len(assigned_target)
- self.num_mapped_model_ligands = len(assigned_model)
-
- def get_average_ligand_scores(
- self, score_name: str
- ) -> tuple[float | None, float | None]:
- if self.ligand_scores is None:
- return None, None
- scores = []
- weights = []
- for s in self.ligand_scores:
- score = s.scores.get(score_name)
- if score is not None:
- scores.append(score)
- weights.append(s.atom_count)
- if not len(scores):
- return None, None
- average_score = np.mean(scores)
- weighted_average_score = sum(w * s for w, s in zip(weights, scores)) / sum(
- weights
- )
- return average_score, weighted_average_score
-
- def get_average_posebusters(self) -> dict[str, list[Any]]:
- scores: dict[str, Any] = {}
- weights: list[float] = []
- if self.ligand_scores is None:
- return scores
- for ligand_scores in self.ligand_scores:
- weights.append(ligand_scores.atom_count)
- for key, value in ligand_scores.posebusters.items():
- scores.setdefault(key, [])
- scores[key].append(value)
- avg_scores = {}
- for key, values in scores.items():
- try:
- avg_scores[f"posebusters_{key}"] = np.mean(
- [w * v for w, v in zip(weights, values)]
- ) / np.sum(weights)
- except Exception:
- try:
- if isinstance(values[0], bool):
- avg_scores[f"posebusters_{key}"] = np.mean(
- [float(val) for val in values]
- )
- elif isinstance(values[0], str):
- avg_scores[f"posebusters_{key}"] = ";".join(values)
- except Exception:
- avg_scores[f"posebusters_{key}"] = None
- return avg_scores
-
- def summarize_scores(self) -> dict[str, dict[str, Any]]:
- if self.ligand_scores is None:
- return {}
- scores: dict[str, Any] = dict(
- model=self.model.name,
- reference=self.reference.name,
- num_reference_ligands=self.reference.num_ligands,
- num_model_ligands=self.model.num_ligands,
- num_reference_proteins=self.reference.num_proteins,
- num_model_proteins=self.model.num_proteins,
- fraction_reference_ligands_mapped=self.num_mapped_reference_ligands
- / self.reference.num_ligands,
- fraction_model_ligands_mapped=self.num_mapped_model_ligands
- / self.model.num_ligands,
- )
- if self.score_protein and self.protein_scores is not None:
- scores["lddt"] = self.protein_scores.lddt
- scores["bb_lddt"] = self.protein_scores.bb_lddt
- per_chain_lddt = list(self.protein_scores.per_chain_lddt.values())
- scores["per_chain_lddt_ave"] = np.mean(per_chain_lddt)
- per_chain_bb_lddt = list(self.protein_scores.per_chain_bb_lddt.values())
- scores["per_chain_bb_lddt_ave"] = np.mean(per_chain_bb_lddt)
- if self.protein_scores.score_oligo:
- scores.update(self.protein_scores.oligomer_scores)
- # aggregated shared_scores to add
- score_list = ["lddt_pli", "lddt_lp", "bisy_rmsd"]
- for score_name in score_list:
- (
- scores[f"{score_name}_ave"],
- scores[f"{score_name}_wave"],
- ) = self.get_average_ligand_scores(score_name)
- if self.score_posebusters:
- scores.update(self.get_average_posebusters())
- # individual ligand scores
- per_lig_scores: dict[str, dict[str, Any]] = {}
- for ligand_score in self.ligand_scores:
- per_lig_scores[ligand_score.chain] = copy.deepcopy(scores)
- for score_name in score_list:
- per_lig_scores[ligand_score.chain][score_name] = ligand_score.scores[
- score_name
- ]
- # get best matched reference ligand chain id
- ref_ligand_rmsd = ligand_score.reference_ligand.get("bisy_rmsd", None)
- if ref_ligand_rmsd:
- # remove ost prefix
- per_lig_scores[ligand_score.chain][
- "best_rmsd_matched_reference_chain"
- ] = "_".join(ref_ligand_rmsd.chain.split("_")[1:])
- # get best matched reference ligand chain id
- ref_ligand_pli = ligand_score.reference_ligand.get("lddt_pli", None)
- if ref_ligand_pli:
- # remove ost prefix
- per_lig_scores[ligand_score.chain][
- "best_pli_matched_reference_chain"
- ] = "_".join(ref_ligand_pli.chain.split("_")[1:])
- return per_lig_scores
diff --git a/src/plinder/eval/docking/write_scores.py b/src/plinder/eval/docking/write_scores.py
deleted file mode 100644
index 74c4d06b6..000000000
--- a/src/plinder/eval/docking/write_scores.py
+++ /dev/null
@@ -1,321 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-from __future__ import annotations
-
-import json
-import multiprocessing
-from pathlib import Path
-from typing import Any
-
-import ost
-import pandas as pd
-
-from plinder.core import PlinderSystem
-from plinder.core.utils.log import setup_logger
-from plinder.eval.docking import utils
-
-ost.PushVerbosityLevel(-1)
-LOG = setup_logger(__name__)
-
-
-def evaluate(
- model_system_id: str,
- reference_system_id: str,
- receptor_file: Path | str,
- ligand_file: Path,
- predictions_dir: Path | None = None,
- score_receptor: bool = False,
- posebusters: bool = False,
- posebusters_full: bool = False,
-) -> dict[str, dict[str, Any]]:
- """
- Evaluate a single receptor - ligand pair
-
- Parameters
- ----------
- model_system_id: str
- The ID of the model system (e.g "prediction_0_rank1")
- reference_system_id: str
- The PLINDER systemID of the reference system
- receptor_file: Path
- The path to the receptor CIF/PDB file
- ligand_file: Path
- Path to the ligand sdf file OR directory with .sdf files
- predictions_dir: Path | None
- The path to the directory containing the predictions (used if receptor/ligand files are not provided)
- score_receptor: bool
- Run protein scoring, for flexible docking and cofolding
- posebusters: bool
- Run posebuster scoring
- posebusters_full: bool
- Run posebuster scoring and return full report
- """
- reference_system = PlinderSystem(system_id=reference_system_id)
- receptor_file = Path(receptor_file)
-
- if not receptor_file.exists():
- if predictions_dir is not None and (predictions_dir / receptor_file).exists():
- receptor_file = predictions_dir / receptor_file
- if not receptor_file.exists():
- raise FileNotFoundError(f"Receptor file {receptor_file} could not be found")
-
- ligand_file_paths = []
- if ligand_file.exists():
- if ligand_file.is_dir():
- ligand_file_paths += list(ligand_file.glob("*.sdf"))
- elif ligand_file.suffix == ".sdf":
- ligand_file_paths.append(ligand_file)
- elif ligand_file is not None:
- if predictions_dir is not None and (predictions_dir / ligand_file).exists():
- ligand_file = predictions_dir / ligand_file
- ligand_file_paths.append(ligand_file)
-
- assert ligand_file_paths is not None and all(
- ligand_file.exists() for ligand_file in ligand_file_paths
- ), f"Ligand files {ligand_file_paths} could not be found"
- return utils.ModelScores.from_model_files(
- model_system_id,
- receptor_file,
- ligand_file_paths,
- reference_system,
- score_protein=score_receptor,
- score_posebusters=posebusters,
- score_posebusters_full_report=posebusters_full,
- ).summarize_scores()
-
-
-def write_scores_as_json(
- scorer_input: pd.Series,
- output_file: Path,
- overwrite: bool = False,
- predictions_dir: Path | None = None,
- score_receptor: bool = False,
- posebusters: bool = False,
- posebusters_full: bool = False,
-) -> None:
- """
- Makes score file for a single reference - model pair
-
- Parameters
- ----------
- scorer_input: pd.Series
- row with [id, reference_system_id, receptor_file, ligand_file, rank, confidence] attributes
- output_file: Path
- Path to save score json file
- overwrite: bool
- Skips existing if False
- predictions_dir: Path | None
- Path to predictions directory
- score_receptor: bool
- Run protein scoring, for flexible docking and cofolding
- posebusters: bool
- Run posebuster scoring
- posebusters_full: bool
- Run posebuster scoring and return full report
- """
- try:
- if not overwrite and output_file.exists():
- LOG.warning(f"get_scores: {output_file} exists")
- return
- reference_system = PlinderSystem(system_id=scorer_input.reference_system_id)
- receptor_file = None
- if (
- scorer_input.receptor_file is not None
- and not str(scorer_input.receptor_file) == "nan"
- ):
- receptor_file = Path(scorer_input.receptor_file)
- # single ligand file path or directory
- ligand_file = Path(scorer_input.ligand_file)
-
- if receptor_file is not None and not receptor_file.exists():
- if (
- predictions_dir is not None
- and (predictions_dir / receptor_file).exists()
- ):
- receptor_file = predictions_dir / receptor_file
- else:
- assert reference_system.receptor_cif is not None
- receptor_file = Path(reference_system.receptor_cif)
-
- elif receptor_file is None:
- if score_receptor:
- raise ValueError("Receptor file is None with --score_receptor flag!")
- LOG.warning(
- "No receptor file provided, using reference receptor (RIGID REDOCKING!!)"
- )
- receptor_file = Path(reference_system.receptor_cif)
- elif not receptor_file.exists():
- raise FileNotFoundError(f"Receptor file {receptor_file} could not be found")
-
- assert receptor_file is not None
- assert ligand_file is not None
- scores = evaluate(
- scorer_input.id,
- scorer_input.reference_system_id,
- receptor_file,
- ligand_file,
- predictions_dir,
- score_receptor,
- posebusters,
- posebusters_full,
- )
- output_file.parent.mkdir(exist_ok=True, parents=True)
- with open(output_file, "w") as f:
- json.dump(scores, f)
- except Exception as e:
- LOG.error(f"get_scores: {e}")
- return
-
-
-def score_test_set(
- prediction_file: Path,
- output_dir: Path,
- output_file: Path,
- num_processes: int = 8,
- overwrite: bool = False,
- posebusters: bool = False,
- score_receptor: bool = False,
- posebusters_full: bool = False,
-) -> None:
- """
- Makes score files for a test set
-
- Parameters
- ----------
- prediction_file: Path
- A CSV file with the columns [id, reference_system_id, receptor_file, ligand_file, rank, confidence]
- system_dir: Path
- Path to *extracted* system files of the test set
- output_dir: Path
- Path to save score files, in the form //.json
- output_file: Path
- Path to save all scores
- num_processes: int
- Number of processes to use
- overwrite: bool
- Skips existing files if False
- posebusters: bool
- Run posebuster scoring
- score_receptor: bool
- Run protein scoring, for flexible docking and cofolding
- posebusters_full: bool
- Run posebuster scoring and return full report
- """
- predictions = pd.read_csv(prediction_file)
- predictions["output_file"] = predictions.apply(
- lambda row: output_dir / row["id"] / f"{row['rank']}.json", axis=1
- )
- predictions["exists"] = predictions["output_file"].map(lambda x: x.exists())
- if not overwrite:
- LOG.info(
- f"Skipping {predictions['exists'].sum()} case as score files exists and overwrite=False"
- )
- predictions = predictions[~predictions["exists"]]
- LOG.info(f"Running evaluation on {predictions.shape[0]} cases")
- ctx = multiprocessing.get_context("spawn")
- with ctx.Pool(num_processes) as p:
- p.starmap(
- write_scores_as_json,
- [
- (
- row,
- row.output_file,
- overwrite,
- prediction_file.parent,
- score_receptor,
- posebusters,
- posebusters_full,
- )
- for _, row in predictions.iterrows()
- ],
- )
- scores = []
- for model_dir in output_dir.iterdir():
- for json_file in model_dir.iterdir():
- with open(json_file) as f:
- try:
- s = json.load(f)
- except Exception as e:
- LOG.error(
- f"score_test_set: Error loading scores file {json_file}: {e}"
- )
- for ligand_chain_name, ligand_scores in s.items():
- if isinstance(ligand_scores, dict):
- scores_dict = {
- "chain": ligand_chain_name,
- "rank": json_file.stem,
- }
- scores_dict.update(
- {
- k: v
- for k, v in ligand_scores.items()
- if k != "ligand_scores"
- }
- )
- scores.append(scores_dict)
- pd.DataFrame(scores).to_parquet(output_file, index=False)
-
-
-def evaluate_cmd(args: list[str] | None = None) -> None:
- """
- Evaluate a set of docking/cofolding predictions against a set of reference Plinder systems.
- """
- import argparse
-
- parser = argparse.ArgumentParser(usage=evaluate_cmd.__doc__)
- parser.add_argument(
- "--prediction_file",
- type=Path,
- help="Path to prediction file with [id, reference_system_id, receptor_file, ligand_file, rank, confidence] as columns",
- )
- parser.add_argument(
- "--output_dir",
- type=Path,
- help="Path to output folder where score JSON files are saved",
- )
- parser.add_argument(
- "--num_processes",
- type=int,
- help="Number of processes to use",
- )
- parser.add_argument(
- "--overwrite",
- action="store_true",
- help="Overwrite max similarity files",
- )
- parser.add_argument(
- "--posebusters",
- action="store_true",
- help="Run posebuster scoring",
- )
- parser.add_argument(
- "--score_receptor",
- action="store_true",
- help="Run protein receptor scoring, for flexible docking and cofolding",
- )
- parser.add_argument(
- "--posebusters_full",
- action="store_true",
- help="Run posebuster scoring and return full report",
- )
- ns, unknown_args = parser.parse_known_args(args=args)
- if len(unknown_args):
- LOG.warning(f"ignoring arguments {unknown_args}")
- LOG.info(f"Evaluating {ns.prediction_file} and saving to {ns.output_dir}")
- Path(ns.output_dir).mkdir(parents=True, exist_ok=True)
- Path(ns.output_dir / "scores").mkdir(parents=True, exist_ok=True)
-
- score_test_set(
- prediction_file=ns.prediction_file,
- output_dir=Path(ns.output_dir) / "scores",
- output_file=Path(ns.output_dir) / "scores.parquet",
- num_processes=ns.num_processes,
- overwrite=ns.overwrite,
- posebusters=ns.posebusters,
- score_receptor=ns.score_receptor,
- posebusters_full=ns.posebusters_full,
- )
-
-
-if __name__ == "__main__":
- evaluate_cmd()
diff --git a/src/plinder/eval/inputs.py b/src/plinder/eval/inputs.py
new file mode 100644
index 000000000..85ef6ff7a
--- /dev/null
+++ b/src/plinder/eval/inputs.py
@@ -0,0 +1,236 @@
+"""Prepare coordinate inputs without contact detection or artifact classification."""
+
+from __future__ import annotations
+
+import shutil
+from collections.abc import Mapping, Sequence
+from dataclasses import dataclass
+from pathlib import Path
+from typing import TYPE_CHECKING
+
+import biotite.structure as struc
+import biotite.structure.io.pdbx as pdbx
+import numpy as np
+from biotite.interface.rdkit import to_mol
+from rdkit.Chem import Mol
+
+from plinder.core.structure.inputs import (
+ StructureInput,
+ read_input_structure,
+ read_ligand_sdf,
+)
+from plinder.data.annotations.cif_utils import (
+ check_cif_bond_orders,
+ check_custom_mmcif_fields,
+ enrich_cif_with_ccd_bonds,
+ enrich_cif_with_smiles_bonds,
+ get_structure_with_altloc,
+ read_mmcif_file,
+)
+from plinder.data.annotations.save_utils import save_cif_file, save_ligands
+
+if TYPE_CHECKING:
+ from plinder.core.index.system import PlinderSystem
+
+
+def reference_ligands(
+ reference: PlinderSystem, *, include_all_ligands: bool = False
+) -> dict[str, Path]:
+ """Select reference poses by release ligand ID, proper ligands by default.
+
+ Uses the reference annotation, not a fresh classification of the prediction.
+ A covalent multi-chain ligand remains one complete SDF molecule.
+ """
+ rows = reference.system
+ if not include_all_ligands:
+ rows = rows.loc[rows["ligand_is_proper"].eq(True)]
+ if rows.empty:
+ raise ValueError(f"No selected reference ligands in {reference.system_id}")
+ sdfs = reference.ligand_sdfs
+ return {
+ row.ligand_id: Path(sdfs[row.ligand_instance_chain])
+ for row in rows.itertuples()
+ }
+
+
+@dataclass
+class PreparedPrediction:
+ """Persistent receptor and ligand files, plus a receptor for PoseBusters.
+
+ Ligand keys are supplied SDF filenames or original label asym IDs. Covalently
+ connected mmCIF ligand chains form one molecule, keyed by their first asym ID.
+ """
+
+ receptor: Path
+ ligands: dict[str, Path]
+ receptor_molecule: Mol
+
+
+def _prepare_receptor_and_sdfs(
+ model: Path, output_dir: Path, ligand_sdfs: Sequence[str | Path]
+) -> PreparedPrediction:
+ """Keep supplied poses and load the predicted receptor for PoseBusters."""
+ paths = [Path(path).resolve() for path in ligand_sdfs]
+ if len({path.name for path in paths}) != len(paths):
+ raise ValueError("Supplied ligand SDF filenames must be unique per prediction")
+ for path in paths:
+ read_ligand_sdf(path)
+ atoms, _ = read_input_structure(model)
+ receptor = to_mol(atoms[struc.filter_heavy(atoms)])
+ output_dir.mkdir(parents=True, exist_ok=True)
+ ligands = {}
+ for index, path in enumerate(paths):
+ destination = output_dir / f"ligand_{index:04d}.sdf"
+ if path != destination.resolve():
+ shutil.copyfile(path, destination)
+ ligands[path.name] = destination.resolve()
+ return PreparedPrediction(model.resolve(), ligands, receptor)
+
+
+def prepare_prediction(
+ model: str | Path | StructureInput,
+ output_dir: str | Path,
+ *,
+ ligand_sdfs: Sequence[str | Path] | None = None,
+ ligand_smiles: Mapping[str, str] | None = None,
+ ligand_ccd_codes: Mapping[str, str] | None = None,
+ ligand_chains: Sequence[str] = (),
+) -> PreparedPrediction:
+ """Prepare a receptor with supplied SDFs, or extract poses from a full mmCIF.
+
+ With ``ligand_sdfs``, ``model`` is the predicted receptor (PDB or mmCIF,
+ optionally gzip-compressed). Each SDF contains one ligand in that receptor's
+ coordinate frame and supplies its own chemistry. Result IDs use the SDF
+ filenames. An empty list represents a prediction with zero ligand poses.
+ Chemistry mappings and ``ligand_chains`` apply to complete-mmCIF extraction.
+
+ Complete-mmCIF extraction selects non-water, non-polymer chains as candidate
+ ligands, including distant poses, ions and artifacts. Protein and DNA/RNA
+ polymers remain receptors. ``ligand_chains`` additionally selects polymer
+ chains used as ligands, such as peptides, by their label asym IDs. Without
+ entity metadata, chains containing amino-acid or nucleotide residues are
+ treated as polymers unless explicitly selected as ligands.
+ DNA/RNA inputs need their mmCIF polymer sequence metadata retained.
+
+ CCD/SMILES mappings use component names, e.g. ``{"LIG": "ATP"}``. For
+ SMILES, the heavy-atom order must match the CIF atom order; CCD templates
+ use atom names or graph matching. Unknown chemistry raises an error with
+ the components requiring bond information. This function does not decide
+ which ligands to evaluate: select proper ligands on the reference instead.
+
+ Prepared SDFs and extracted receptors remain in ``output_dir``; supplied
+ receptors use their original paths. The RDKit receptor retains residue
+ metadata for PoseBusters.
+ """
+ if isinstance(model, StructureInput):
+ if ligand_sdfs is not None:
+ raise ValueError("Supply ligand_sdfs in the StructureInput only")
+ ligand_sdfs = model.ligand_sdfs
+ model = model.coordinates
+ model, output_dir = Path(model), Path(output_dir)
+ if ligand_sdfs is not None:
+ return _prepare_receptor_and_sdfs(model, output_dir, ligand_sdfs)
+ if model.name.lower().endswith((".pdb", ".pdb.gz")):
+ raise ValueError(
+ "Ligand preparation requires a complete mmCIF or a receptor with "
+ "ligand SDFs. Supply model.sdf or model.ligands/ beside model.pdb."
+ )
+ cif = read_mmcif_file(model)
+ block: pdbx.CIFBlock = next(iter(cif.values()))
+ check_custom_mmcif_fields(
+ block, source=model, structure_mode="as_is", require_label_ids=True
+ )
+ overlap = set(ligand_smiles or {}) & set(ligand_ccd_codes or {})
+ if overlap:
+ raise ValueError(
+ f"Provide either SMILES or CCD for each component: {sorted(overlap)}"
+ )
+ atoms = get_structure_with_altloc(cif)
+ atoms = atoms[struc.filter_heavy(atoms) & ~struc.filter_solvent(atoms)]
+ chains = set(atoms.chain_id)
+ extra_ligands = set(ligand_chains)
+ if missing := extra_ligands - chains:
+ raise ValueError(f"Ligand chains absent from model: {sorted(missing)}")
+
+ entity_types = {}
+ if "entity" in block and "struct_asym" in block:
+ entity = block["entity"]
+ asym = block["struct_asym"]
+ by_entity = dict(zip(entity["id"].as_array(), entity["type"].as_array()))
+ entity_types = {
+ chain: by_entity.get(entity_id)
+ for chain, entity_id in zip(
+ asym["id"].as_array(), asym["entity_id"].as_array()
+ )
+ }
+ polymer_atoms = struc.filter_amino_acids(atoms) | struc.filter_nucleotides(atoms)
+ receptor_chains = {
+ chain
+ for chain in chains - extra_ligands
+ if entity_types.get(chain) == "polymer"
+ or (
+ entity_types.get(chain) is None
+ and polymer_atoms[atoms.chain_id == chain].any()
+ )
+ }
+ if not receptor_chains:
+ raise ValueError(f"No protein or nucleic-acid receptor chains in {model}")
+ candidates = chains - receptor_chains
+ # The chemistry helpers scan HETATM records. Select by chain membership,
+ # not the input record spelling, so ATOM-labelled ligands are checked too.
+ site = block["atom_site"]
+ site["group_PDB"] = np.where(
+ np.isin(site["label_asym_id"].as_array(str), list(candidates)),
+ "HETATM",
+ site["group_PDB"].as_array(str),
+ )
+ if ligand_ccd_codes:
+ enrich_cif_with_ccd_bonds(cif, dict(ligand_ccd_codes))
+ if ligand_smiles:
+ enrich_cif_with_smiles_bonds(cif, dict(ligand_smiles))
+ check_cif_bond_orders(cif)
+ atoms = get_structure_with_altloc(cif, include_bonds=True)
+ atoms = atoms[struc.filter_heavy(atoms) & ~struc.filter_solvent(atoms)]
+ receptor_atoms = atoms[np.isin(atoms.chain_id, list(receptor_chains))]
+
+ # Join covalently linked ligand chains, never through a receptor or metal.
+ neighbors: dict[str, set[str]] = {chain: set() for chain in candidates}
+ for first, second, bond_type in atoms.bonds.as_array():
+ if bond_type == struc.BondType.COORDINATION:
+ continue
+ a, b = atoms.chain_id[first], atoms.chain_id[second]
+ if a != b and a in candidates and b in candidates:
+ neighbors[a].add(b)
+ neighbors[b].add(a)
+ groups = {}
+ unseen = set(candidates)
+ while unseen:
+ first = min(unseen)
+ group, pending = set(), [first]
+ while pending:
+ chain = pending.pop()
+ if chain not in group:
+ group.add(chain)
+ pending.extend(neighbors[chain] - group)
+ unseen -= group
+ groups[first] = sorted(group)
+
+ output_dir.mkdir(parents=True, exist_ok=True)
+ receptor_path = output_dir / "receptor.cif"
+ save_cif_file(
+ receptor_atoms,
+ "receptor",
+ receptor_path,
+ source_block=block,
+ source_asym_ids={chain: chain for chain in receptor_chains},
+ )
+ # File names do not interpolate user-supplied chain IDs; keys preserve them.
+ names = {chain: f"ligand_{index:04d}" for index, chain in enumerate(groups)}
+ save_ligands(
+ atoms, {names[chain]: group for chain, group in groups.items()}, output_dir
+ )
+ return PreparedPrediction(
+ receptor=receptor_path,
+ ligands={chain: output_dir / f"{name}.sdf" for chain, name in names.items()},
+ receptor_molecule=to_mol(receptor_atoms),
+ )
diff --git a/src/plinder/methods/__init__.py b/src/plinder/methods/__init__.py
deleted file mode 100644
index 2bc0efc66..000000000
--- a/src/plinder/methods/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
diff --git a/tests/conftest.py b/tests/conftest.py
index 97452b67a..9859d6a0b 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,31 +1,27 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
import json
-from io import StringIO
+import os
+import shutil
from pathlib import Path
import pandas as pd
-import pyarrow.dataset as ds
import pytest
test_asset_fp = Path(__file__).absolute().parent / "test_data"
test_output_fp = Path(__file__).absolute().parent / "xx/output"
-# Loads a mock score dataset
-def load_mini_dataset():
- sample_scores_dataset = (
- Path(__file__).parent / "test_data/mini_score_dataset.parquet"
- )
- return ds.dataset(sample_scores_dataset)
-
-
-# Loads a mock sequence similarity dataset
-def load_mini_seq_dataset():
- sample_scores_dataset = (
- Path(__file__).parent / "test_data/mini_score_seq_dataset.parquet"
- )
- return ds.dataset(sample_scores_dataset)
+# TODO: tests/test_data/plinder/mount is a hand-curated slice of a released
+# index, so the static table cannot reflect code changes; it must be regenerated
+# with each release (a release-time CI job from the release artifacts).
+def _write_test_entry_metadata(release_dir: Path) -> None:
+ annotation = pd.read_parquet(release_dir / "index" / "annotation_table.parquet")
+ entry_columns = [column for column in annotation if column.startswith("entry_")]
+ metadata = annotation.loc[:, entry_columns].drop_duplicates()
+ if metadata["entry_pdb_id"].duplicated().any():
+ raise ValueError("test annotation has inconsistent entry metadata")
+ metadata.to_parquet(release_dir / "index" / "entry_metadata.parquet", index=False)
@pytest.fixture(scope="session")
@@ -84,11 +80,6 @@ def cif_assembly_5a7w():
return test_asset_fp / "xx/pdb_00005a7w/5a7w-assembly.cif"
-@pytest.fixture(scope="session")
-def pdb_5a7w_hydrogen():
- return test_asset_fp / "xx/pdb_00005a7w/5a7w_A_hyd.pdb"
-
-
@pytest.fixture(scope="session")
def fingerprint_prop_5a7w():
return test_asset_fp / "xx/pdb_00005a7w/5a7w_interactions.txt"
@@ -100,6 +91,12 @@ def sdf_5a7w_lig():
return test_asset_fp / "xx/pdb_00005a7w/5a7w_A_35M.sdf"
+# To test branched glycans (chain E is a branched NAG-FUC-NAG)
+@pytest.fixture(scope="session")
+def cif_2dty():
+ return test_asset_fp / "xx/pdb_00002dty/pdb_00002dty_xyz-enrich.cif.gz"
+
+
# To test fragmented ligands, carbs
@pytest.fixture(scope="session")
def cif_6fx1():
@@ -154,6 +151,13 @@ def cif_7gl9():
return test_asset_fp / "xx/pdb_00007gl9/pdb_00007gl9_xyz-enrich.cif.gz"
+# To test covalent linkages + 5-char CCD codes
+# (PCSK9 + enlicitide/MK-0616: ligand is presented as chain + covalent/modified residues)
+@pytest.fixture(scope="session")
+def cif_10sb():
+ return test_asset_fp / "xx/pdb_000010sb/pdb_000010sb_xyz-enrich.cif.gz"
+
+
# To test peptide - 9 a.a. with UniProt (maybe ligand?)
@pytest.fixture(scope="session")
def cif_6i41():
@@ -255,21 +259,26 @@ def cif_2y4i_system():
return test_asset_fp / "xx/pdb_00002y4i/pdb_00002y4i_xyz-enrich.cif.gz"
-# To test PLIP - CHK1 inhib 1
+# CHK1 inhib 1
@pytest.fixture(scope="session")
def cif_2gdo():
return test_asset_fp / "xx/pdb_00002gdo/pdb_00002gdo_xyz-enrich.cif.gz"
-# To test PLIP - CHK1 inhib 2
+# CHK1 inhib 2
@pytest.fixture(scope="session")
def cif_4qyf():
return test_asset_fp / "xx/pdb_00004qyf/pdb_00004qyf_xyz-enrich.cif.gz"
@pytest.fixture(scope="session")
-def smiles_sample_csv():
- return test_asset_fp / "smiles_from_nextgen_bonds_data.csv"
+def rcsb_ccd_reference_csv():
+ return test_asset_fp / "rcsb_ccd_smiles_reference.csv"
+
+
+@pytest.fixture(scope="session")
+def resolved_smiles_csv():
+ return test_asset_fp / "resolved_smiles_reference.csv"
@pytest.fixture(scope="session")
@@ -289,143 +298,28 @@ def cif_6ntj():
return test_asset_fp / "xx/pdb_00006ntj/pdb_00006ntj_xyz-enrich.cif.gz"
+# To test nucleic acid receptor detection (issue #61)
@pytest.fixture(scope="session")
-def ecod_mini():
- ecod_str = """
-#ECOD version develop286
-#Domain list version 1.6
-#Grishin lab (http://prodata.swmed.edu/ecod)
-#uid ecod_domain_id manual_rep f_id pdb chain pdb_range \
-seqid_range unp_acc arch_name x_name h_name t_name f_name asm_status ligand
-000000267 e1udzA1 MANUAL_REP 1.1.1.28 1udz A A:203-381 \
-A:4-182 P56690 beta barrels "cradle loop barrel" "RIFT-related" \
-"acid protease" tRNA-synt_1_2nd NOT_DOMAIN_ASSEMBLY NO_LIGANDS_4A
-000023407 e1udzB1 AUTO_NONREP 1.1.1.28 1udz B B:203-381 \
-B:4-182 P56690 beta barrels "cradle loop barrel" "RIFT-related" \
-"acid protease" tRNA-synt_1_2nd NOT_DOMAIN_ASSEMBLY NO_LIGANDS_4A
-"""
- return StringIO(ecod_str)
-
-
-@pytest.fixture(scope="session")
-def mini_panther():
- return test_asset_fp / "panther_classifications_mini.tar.gz"
-
-
-@pytest.fixture(scope="session")
-def mini_component_cif():
- return test_asset_fp / "components.cif"
-
-
-@pytest.fixture(scope="session")
-def mini_component_cif_gz():
- return test_asset_fp / "components.cif.gz"
-
-
-@pytest.fixture(scope="session")
-def mini_components_pqt():
- return test_asset_fp / "components.parquet"
-
-
-@pytest.fixture(scope="session")
-def protein_pdb_block():
- prot = """
-ATOM 878 N ASN A 46 13.513 -6.432 14.070 1.00 2.87 N
-ATOM 879 CA ASN A 46 12.645 -5.347 13.627 1.00 2.87 C
-ATOM 880 C ASN A 46 11.201 -5.794 13.380 1.00 3.19 C
-ATOM 881 O ASN A 46 10.833 -6.925 13.791 1.00 3.41 O
-ATOM 882 CB ASN A 46 13.268 -4.685 12.384 1.00 3.66 C
-ATOM 883 CG ASN A 46 14.641 -4.132 12.661 1.00 4.78 C
-ATOM 884 OD1 ASN A 46 15.591 -4.547 12.028 1.00 7.55 O
-ATOM 885 ND2 ASN A 46 14.723 -3.168 13.614 1.00 6.97 N
-ATOM 886 OXT ASN A 46 10.480 -4.975 12.775 1.00 4.15 O
-ATOM 887 H ASN A 46 13.774 -7.098 13.362 1.00 3.02 H
-ATOM 888 HA ASN A 46 12.636 -4.574 14.444 1.00 3.14 H
-ATOM 889 HB2 ASN A 46 13.320 -5.415 11.571 1.00 4.02 H
-ATOM 890 HB3 ASN A 46 12.646 -3.851 12.072 1.00 4.02 H
-ATOM 891 HD21 ASN A 46 13.933 -2.916 14.039 1.00 7.87 H
-ATOM 892 HD22 ASN A 46 15.661 -2.840 13.786 1.00 7.87 H
- """
- return prot
-
-
-@pytest.fixture(scope="session")
-def ligand_pdb_block():
- lig = """
-HETATM 894 C1 EOH A2001 18.245 -4.085 12.277 0.60 10.06 C
-HETATM 895 C2 EOH A2001 19.159 -2.255 13.149 0.60 24.97 C
-HETATM 896 O EOH A2001 17.933 -5.505 12.774 0.60 13.14 O
-"""
- return lig
-
-
-@pytest.fixture(scope="session")
-def mini_mmp_index():
- return test_asset_fp / "mmp/tiny_mmp_index.csv.gz"
+def cif_8ufz():
+ return test_asset_fp / "xx/pdb_00008ufz/pdb_00008ufz_xyz-enrich.cif.gz"
+# To test multi-ligand system grouping (GPCR with adjacent binding sites)
@pytest.fixture(scope="session")
-def mini_mmp_data_annotation():
- return test_asset_fp / "mmp/mmp_mini_data.tsv"
+def cif_7fee():
+ return test_asset_fp / "xx/pdb_00007fee/pdb_00007fee_xyz-enrich.cif.gz"
+# To test cofactor-only system classification (HEM in hemoglobin)
@pytest.fixture(scope="session")
-def mmp_pocket_fident_data():
- return (
- test_asset_fp
- / "mmp/mmp_test_pocket_fident_weighted_sum__1.0__strong__component.csv"
- )
+def cif_19hc():
+ return test_asset_fp / "xx/pdb_000019hc/pdb_000019hc_xyz-enrich.cif.gz"
+# To test ATP+metal cofactor system grouping (PKA)
@pytest.fixture(scope="session")
-def mini_mmp_cluster_folder():
- return test_asset_fp / "mmp/mini_clusters"
-
-
-@pytest.fixture(scope="session")
-def mmp_protein_fident_data():
- return (
- test_asset_fp
- / "mmp/mmp_test_protein_fident_weighted_sum__0.95__weak__component.csv"
- )
-
-
-@pytest.fixture(scope="session")
-def target_structure_validation_file():
- return test_asset_fp / "mini_structure_checks_report.tsv"
-
-
-@pytest.fixture(scope="session")
-def mini_all_json():
- return test_asset_fp / "mini_all_entries.json"
-
-
-@pytest.fixture(scope="session")
-def mini_system_dir():
- return test_asset_fp / "mini_system_files_new"
-
-
-@pytest.fixture
-def entry_zip():
- return test_asset_fp / "2g.zip"
-
-
-@pytest.fixture
-def raw_ecod_data():
- # TODO: merge with ecod_mini
- return """\
-#/data/ecod/database_versions/v291/ecod.develop291.domains.txt
-#ECOD version develop291
-#Domain list version 1.6
-#Grishin lab (http://prodata.swmed.edu/ecod)
-#uid ecod_domain_id manual_rep t_id pdb chain pdb_range seqid_range unp_acc arch_name x_name h_name t_name f_name asm_status ligand
-000000267 e1udzA1 MANUAL_REP 1.1.1 1udz A A:203-381 A:4-182 P56690 beta barrels "cradle loop barrel" "RIFT-related" "acid protease" F_UNCLASSIFIED NOT_DOMAIN_ASSEMBLY NO_LIGANDS_4A
-000023408 e1ileA4 AUTO_NONREP 1.1.1 1ile A A:203-381 A:203-381 P56690 beta barrels "cradle loop barrel" "RIFT-related" "acid protease" F_UNCLASSIFIED NOT_DOMAIN_ASSEMBLY NO_LIGANDS_4A
-000023411 e1ue0B1 AUTO_NONREP 1.1.1 1ue0 B B:203-381 B:4-182 P56690 beta barrels "cradle loop barrel" "RIFT-related" "acid protease" F_UNCLASSIFIED NOT_DOMAIN_ASSEMBLY NO_LIGANDS_4A
-000158260 e1wk8A1 AUTO_NONREP 1.1.1 1wk8 A A:201-382 A:7-188 P56690 beta barrels "cradle loop barrel" "RIFT-related" "acid protease" F_UNCLASSIFIED NOT_DOMAIN_ASSEMBLY NO_LIGANDS_4A
-001842922 e5fofA1 AUTO_NONREP 1.1.1 5fof A A:258-340,A:363-567 A:29-103,A:126-330 B3L7I1 beta barrels "cradle loop barrel" "RIFT-related" "acid protease" F_UNCLASSIFIED NOT_DOMAIN_ASSEMBLY NO_LIGANDS_4A
-001842923 e5fofB1 AUTO_NONREP 1.1.1 5fof B B:258-340,B:363-567 B:29-103,B:126-330 B3L7I1 beta barrels "cradle loop barrel" "RIFT-related" "acid protease" F_UNCLASSIFIED NOT_DOMAIN_ASSEMBLY NO_LIGANDS_4A
-"""
+def cif_1atp():
+ return test_asset_fp / "xx/pdb_00001atp/pdb_00001atp_xyz-enrich.cif.gz"
@pytest.fixture
@@ -433,67 +327,11 @@ def test_env(tmp_path, monkeypatch):
monkeypatch.setenv("PLINDER_MOUNT", tmp_path.as_posix())
monkeypatch.setenv("PLINDER_BUCKET", "bucket")
monkeypatch.setenv("PLINDER_RELEASE", "test")
- monkeypatch.setenv("PLINDER_ITERATION", "v0")
+ monkeypatch.setenv("PLINDER_RELEASE_NUMBER", "")
from plinder.core.utils import config
config._config._clear()
- return tmp_path / "bucket" / "test" / "v0"
-
-
-@pytest.fixture
-def raw_ecod_path(test_env, raw_ecod_data):
- raw_ecod_path = test_env / "dbs" / "ecod" / "ecod_raw.tsv"
- raw_ecod_path.parent.mkdir(parents=True)
- raw_ecod_path.write_text(raw_ecod_data)
- return raw_ecod_path
-
-
-@pytest.fixture
-def raw_panther_data(mini_panther):
- return mini_panther.read_bytes()
-
-
-@pytest.fixture
-def raw_panther_path(test_env, raw_panther_data):
- raw_panther_path = test_env / "dbs" / "panther" / "panther_raw.tar.gz"
- raw_panther_path.parent.mkdir(parents=True)
- raw_panther_path.write_bytes(raw_panther_data)
- return raw_panther_path
-
-
-@pytest.fixture
-def kinase_uniprotac():
- df = pd.read_parquet(test_asset_fp / "kinase_uniprotac.parquet")
- return df
-
-
-@pytest.fixture
-def kinase_ligand():
- return pd.read_parquet(test_asset_fp / "kinase_ligand_ccd_codes.parquet")
-
-
-@pytest.fixture
-def all_kinase_paths(test_env, kinase_uniprotac, kinase_ligand):
- kinase_info_path = test_env / "dbs" / "kinase" / "kinase_information.parquet"
- kinase_ccd_path = test_env / "dbs" / "kinase" / "kinase_ligand_ccd_codes.parquet"
- kinase_struc_path = test_env / "dbs" / "kinase" / "kinase_structures.parquet"
- kinase_path = test_env / "dbs" / "kinase" / "kinase_uniprotac.parquet"
- kinase_path.parent.mkdir(parents=True)
- kinase_info_path.write_bytes(b"")
- kinase_struc_path.write_bytes(b"")
- kinase_uniprotac.to_parquet(kinase_path, index=False)
- kinase_ligand.to_parquet(kinase_ccd_path, index=False)
- return kinase_path
-
-
-@pytest.fixture
-def components_path(test_env, mini_component_cif, mini_components_pqt):
- components_path = test_env / "dbs" / "components" / "components.cif"
- components_pqt = test_env / "dbs" / "components" / "components.parquet"
- components_path.parent.mkdir(parents=True)
- components_path.write_text(mini_component_cif.read_text())
- components_pqt.write_bytes(mini_components_pqt.read_bytes())
- return components_path
+ return tmp_path / "bucket" / "test"
@pytest.fixture
@@ -505,7 +343,8 @@ def cofactors_path(test_env):
"Coenzyme A": [
{
"cofactors": [
- "01A"
+ "01A",
+ "EKY"
],
"EC": [
"1.1.1.34"
@@ -524,73 +363,83 @@ def cofactors_path(test_env):
"1.4.99.3"
]
}
+ ],
+ "Heme": [
+ {
+ "cofactors": [
+ "HEM",
+ "HEC",
+ "HEB",
+ "HEA"
+ ],
+ "EC": [
+ "1.11.1.5",
+ "1.11.2.2"
+ ]
+ }
+ ],
+ "Adenosine nucleotides": [
+ {
+ "cofactors": [
+ "ATP",
+ "ADP",
+ "AMP"
+ ],
+ "EC": [
+ "2.7.1.1",
+ "2.7.11.1"
+ ]
+ }
]
}"""
cofactors_path.write_text(mini_cofactors)
with cofactors_path.open("r") as f:
cofactors = json.load(f)
- assert len(cofactors) == 2
+ assert len(cofactors) == 4 # CoA, TTQ, Heme (19hc), ATP (1atp)
return cofactors_path
@pytest.fixture
def affinity_path(test_env):
- affinity_path = test_env / "dbs" / "affinity" / "affinity.json"
- affinity_path.parent.mkdir(parents=True)
- affinity = """\
-{
-"pchembl": {
- "4JVM_XDI": 5.3979400087,
- "4JVN_YUG": 7.638272164,
- "4JVO_A5A": 5.7706810755,
- "4JVP_SO4": 1.2732414543,
- "4JVQ_1ML": 6.2006594505,
- "4JVR_1MT": 8.0268721464}
-}"""
- affinity = json.loads(affinity)
- with open(affinity_path, "w") as f:
- json.dump(affinity, f)
- return affinity_path
-
-
-@pytest.fixture
-def ecod_path(test_env, raw_ecod_path):
- # TODO : combine with ecod_mini and raw_ecod_path for consistency of test data
- ecod_path = test_env / "dbs" / "ecod" / "ecod.parquet"
- ecod = pd.read_fwf(
- StringIO(
- """\
- pdb chain domainid domain pdb_from pdb_to
-786775 2y4i C e2y4iC1 Protein kinase 37 277
-786776 2y4i C e2y4iC1 Protein kinase 307 381
-795072 2y4i B e2y4iB1 Protein kinase 653 931"""
- )
+ affinity_dir = test_env / "dbs" / "affinity"
+ affinity_dir.mkdir(parents=True)
+ # Synthetic Ki record linked to the 4JVN receptor sequence in the CIF.
+ target_sequence = (
+ "MNSELDYYEKFEEVHGILMYKDFVKYWDNVEAFQARPDDLVIATYPKSGTTWVSEIVYMIYKEGDVEKCKEDVIFNRIPF"
+ "LECRKENLMNGVKQLDEMNSPRIVKTHLPPELLPASFWEKDCKIIYLCRNAKDVAVSFYYFFLMVAGHPNPGSFPEFVEK"
+ "FMQGQVPYGSWYKHVKSWWEKGKSPRVLFLFYEDLKEDIRKEVIKLIHFLERKPSEELVDRIIHHTSFQEMKNNPSTNYT"
+ "TLPDEIMNQKLSPFMRKGITGDWKNHFTEALNEKFDKHYEQQMKESTLKFRTEI"
)
- ecod.to_parquet(ecod_path, index=False)
- return ecod_path
-
-
-@pytest.fixture
-def panther_path(test_env, raw_panther_path):
- # TODO : combine with raw_panther_path for consistency of test data
- panther_path = test_env / "dbs" / "panther" / "panther.parquet"
- panther = pd.read_fwf(
- StringIO(
- """\
- uniprotac panther panther_class
-3399199 K9UFQ1 PTHR43464:SF101 Chamaesiphon_minutus_CHAP6
-2534477 A0A8I6S536 PTHR15954:SF4 Cimex_lectularius_CIMLE
-514536 A0A3Q1J8D7 PTHR24248:SF25 Anabas_testudineus_ANATE
-5222120 G8BJ17 PTHR23073:SF162 Candida_parapsilosis_CANPC
-16087460 L0FTL5 PTHR13355:SF24 Echinicola_vietnamensis_ECHVK"""
- )
- )
- panther["shard"] = panther["uniprotac"].str[-1]
- for i in range(10):
- panther[panther["shard"] == str(i)].to_parquet(
- panther_path.parent / f"panther_{i}.parquet"
- )
- return panther_path
+ pd.DataFrame(
+ {
+ "pdbid_ligid": ["4JVN_YUG"],
+ "target_sequence": [target_sequence],
+ "endpoint": ["Ki"],
+ "pchembl": [7.638272164],
+ "count": [1],
+ }
+ ).to_parquet(affinity_dir / "candidates.parquet", index=False)
+ pd.DataFrame(
+ {
+ "pdbid_ligid": ["4JVN_YUG"],
+ "pdb_id": ["4JVN"],
+ "ligand_het_id": ["YUG"],
+ "reactant_set_id": ["fixture"],
+ "monomer_id": ["fixture"],
+ "curation_source": ["synthetic test fixture"],
+ "article_doi": [None],
+ "bindingdb_entry_doi": [None],
+ "source_row": [0],
+ "target_sequences": [[target_sequence]],
+ "target_sequence": [target_sequence],
+ "endpoint": ["Ki"],
+ "raw_value": ["23"],
+ "relation": ["="],
+ "value_nm": [23.0],
+ "pchembl": [7.638272164],
+ }
+ ).to_parquet(affinity_dir / "measurements.parquet", index=False)
+ return affinity_dir / "candidates.parquet"
@pytest.fixture
@@ -605,11 +454,7 @@ def seqres_path(test_env):
@pytest.fixture
def mock_alternative_datasets(
test_env,
- ecod_path,
- panther_path,
seqres_path,
- all_kinase_paths,
- components_path,
cofactors_path,
affinity_path,
):
@@ -622,22 +467,21 @@ def inner(pdb_id: str):
@pytest.fixture
-def final_json_7nac():
- return test_asset_fp / "7nac.json"
-
+def read_plinder_mount(monkeypatch, tmp_path):
+ source = test_asset_fp / "plinder" / "mount"
+ adir = tmp_path / "plinder" / "mount"
+ shutil.copytree(source, adir, copy_function=os.symlink)
+ _write_test_entry_metadata(adir)
-@pytest.fixture
-def read_plinder_mount(monkeypatch):
- monkeypatch.setenv("PLINDER_MOUNT", test_asset_fp.as_posix())
+ monkeypatch.setenv("PLINDER_MOUNT", tmp_path.as_posix())
monkeypatch.setenv("PLINDER_RELEASE", "mount")
+ monkeypatch.setenv("PLINDER_RELEASE_NUMBER", "")
monkeypatch.setenv("PLINDER_BUCKET", "plinder")
- monkeypatch.setenv("PLINDER_ITERATION", "")
+ monkeypatch.setenv("PLINDER_OFFLINE", "true")
from plinder.core.utils import config
config._config._clear()
- plinder_mount = test_asset_fp
cfg = config.get_config()
- adir = plinder_mount / "plinder" / "mount"
assert Path(cfg.data.plinder_dir) == adir
for path in adir.rglob("*_done"):
@@ -646,24 +490,6 @@ def read_plinder_mount(monkeypatch):
return adir
-@pytest.fixture
-def read_plinder_eval_mount(monkeypatch):
- monkeypatch.setenv("PLINDER_MOUNT", test_asset_fp.as_posix())
- monkeypatch.setenv("PLINDER_RELEASE", "")
- monkeypatch.setenv("PLINDER_BUCKET", "eval")
- monkeypatch.setenv("PLINDER_ITERATION", "")
- monkeypatch.setenv("PLINDER_OFFLINE", True)
- from plinder.core.utils import config
-
- config._config._clear()
- plinder_mount = test_asset_fp
- cfg = config.get_config()
- adir = plinder_mount / "eval"
- assert Path(cfg.data.plinder_dir) == adir
-
- return adir
-
-
@pytest.fixture
def write_plinder_mount(monkeypatch, tmp_path):
read_plinder_mount = test_asset_fp / "plinder" / "mount"
@@ -671,8 +497,8 @@ def write_plinder_mount(monkeypatch, tmp_path):
write_plinder_mount.mkdir(parents=True)
monkeypatch.setenv("PLINDER_MOUNT", tmp_path.as_posix())
monkeypatch.setenv("PLINDER_RELEASE", "mount")
+ monkeypatch.setenv("PLINDER_RELEASE_NUMBER", "")
monkeypatch.setenv("PLINDER_BUCKET", "plinder")
- monkeypatch.setenv("PLINDER_ITERATION", "")
from plinder.core.utils import config
config._config._clear()
@@ -682,6329 +508,59 @@ def write_plinder_mount(monkeypatch, tmp_path):
write_path = write_plinder_mount / path.relative_to(read_plinder_mount)
write_path.parent.mkdir(exist_ok=True, parents=True)
write_path.write_bytes(path.read_bytes())
+ _write_test_entry_metadata(write_plinder_mount)
return write_plinder_mount
+@pytest.fixture
+def cached_plinder_system(read_plinder_mount, tmp_path):
+ """Build a system using explicit current-release cache locations."""
+ from plinder.core import PlinderSystem
+
+ def build(system_id: str) -> PlinderSystem:
+ source = test_asset_fp / "reconstructed_systems" / system_id
+ reconstruction_dir = tmp_path / "reconstructed_systems" / system_id
+ shutil.copytree(source, reconstruction_dir)
+
+ canonical_ligand_dir = tmp_path / "canonical_ligands" / system_id
+ canonical_ligand_dir.mkdir(parents=True)
+ for ligand_file in (source / "ligand_files").glob("*.sdf"):
+ asym_id = ligand_file.stem.split(".", maxsplit=1)[-1] # asym may hold dots
+ target = canonical_ligand_dir / f"{asym_id}.sdf"
+ if not target.exists():
+ shutil.copyfile(ligand_file, target)
+
+ return PlinderSystem(
+ system_id=system_id,
+ reconstruction_dir=reconstruction_dir,
+ canonical_ligand_dir=canonical_ligand_dir,
+ )
+
+ return build
+
+
@pytest.fixture(autouse=True)
def mock_ccd_lookups(monkeypatch):
+ # Only the code sets are patched; COFACTOR_SMILES / ARTIFACT_SMILES stay None
+ # so classification falls back to code-only matching in tests (the synonym
+ # code->code map was retired โ obsolete codes are never ingested).
+ data = json.loads((test_asset_fp / "ccd_lookups.json").read_text())
+ from plinder.data.annotations.ligand_utils import ccd_components
+
monkeypatch.setattr(
- "plinder.data.utils.annotations.ligand_utils.LIST_OF_CCD_SYNONYMS",
- [
- {"B1F", "B2F"},
- {"OY5", "OY8"},
- {"N1B", "4LA"},
- {"C2H", "ETD"},
- {"FMT", "CBX"},
- {"NFO", "NFB"},
- {"MBR", "B4M"},
- {"PGH", "PGC"},
- {"BXA", "BRM"},
- {"2PL", "PGA"},
- {"CRY", "GOL"},
- {"VKN", "YLL"},
- {"VDW", "0P0", "GTT"},
- {"AKG", "2OG"},
- {"GGL", "GLU"},
- {"FGA", "DGL"},
- {"ACA", "AHA"},
- {"GCG", "TS3"},
- {"HPG", "PDO"},
- {"148", "BTB"},
- {"EDO", "EGL"},
- {"PIG", "PGE"},
- {"P2K", "P6G"},
- {"SEA", "DHL"},
- {"BME", "SEO"},
- {"CS0", "OCY"},
- {"DHN", "AA4"},
- {"ABK", "FKI"},
- {"ASP", "IAS"},
- {"PAS", "PHD", "ASQ"},
- {"SER", "SEG"},
- {"BTC", "FCY", "CYS"},
- {"CAY", "CCS"},
- {"CSO", "CEA"},
- {"CSE", "SEC"},
- {"ICT", "ICI"},
- {"GLR", "KGR"},
- {"GAL", "GLB"},
- {"G4S", "GSA"},
- {"Z4Y", "TWG"},
- {"GS4", "SGC", "GSD"},
- {"SGN", "YJM"},
- {"AGC", "GLC"},
- {"ADG", "TOA"},
- {"NT2", "GU4"},
- {"L1L", "GP1"},
- {"BFP", "FBP"},
- {"I8Z", "I9X"},
- {"HSU", "BDR"},
- {"RDP", "R1P"},
- {"HNP", "H5P"},
- {"DSP", "DAS"},
- {"DMR", "MLT"},
- {"3PG", "MP3"},
- {"PAG", "2PG"},
- {"GPH", "GPO", "0AL"},
- {"R51", "R52"},
- {"PA4", "IDG"},
- {"KPI", "MCL"},
- {"EUG", "H7Y"},
- {"2H3", "CBU", "INS"},
- {"I6P", "IHP", "KGN"},
- {"GUR", "GLL"},
- {"0AU", "IU"},
- {"GCD", "DGC"},
- {"CYL", "ACI", "CMN"},
- {"TZA", "ACZ"},
- {"LC", "0C"},
- {"C", "C25", "C5P"},
- {"0U", "LHU"},
- {"2AU", "U2N"},
- {"U", "U25", "U5P"},
- {"U37", "T31"},
- {"S4U", "4SU"},
- {"PH2", "HHP"},
- {"PCA", "5HP", "PCC"},
- {"HAC", "ALC"},
- {"CHG", "CUC"},
- {"H2U", "DHU"},
- {"DOX", "DIO"},
- {"DXD", "DXN"},
- {"ORP", "D1P"},
- {"C32", "CBR"},
- {"I5C", "C38"},
- {"5IU", "5IT"},
- {"DCM", "DC"},
- {"C7S", "C7R"},
- {"DU", "UMP"},
- {"IGU", "0UH"},
- {"B1P", "AAB"},
- {"MNM", "NOZ"},
- {"NOJ", "DNJ"},
- {"TSO", "TSA", "BAR"},
- {"UYA", "0AZ"},
- {"DFC", "0DC"},
- {"HSZ", "XYP"},
- {"XYB", "BXP"},
- {"DDM", "DMJ"},
- {"FLH", "FOR"},
- {"PVL", "MIE"},
- {"LIN", "AAE"},
- {"3NK", "LL8"},
- {"CHH", "NWB"},
- {"GCM", "GLM", "F3V"},
- {"CNM", "ACM"},
- {"1ZT", "SC2"},
- {"YYR", "RTV"},
- {"SIA", "SI2", "NAN"},
- {"7BN", "7BO"},
- {"16G", "0AT"},
- {"NAG", "HSR"},
- {"1NA", "MAG"},
- {"NGL", "ASG"},
- {"5G0", "OGN"},
- {"TYL", "NNS"},
- {"ACY", "CM", "CBM"},
- {"CKC", "LYM"},
- {"OTB", "BOC"},
- {"BUG", "TBG", "HV5"},
- {"ISB", "ALQ"},
- {"FPG", "F3P"},
- {"UIC", "GRL"},
- {"CLE", "NLW"},
- {"LEP", "0FA"},
- {"YLV", "YM1"},
- {"YKA", "YKD"},
- {"YKY", "YL7"},
- {"YMD", "YMG"},
- {"YMS", "YMV"},
- {"Y8Y", "Y91"},
- {"Y51", "Y71"},
- {"Y7G", "Y4P"},
- {"YLD", "YLJ"},
- {"YKS", "YKV"},
- {"OLE", "1LU"},
- {"XAO", "GCL"},
- {"HMP", "HMI"},
- {"PLH", "HAP"},
- {"PLU", "PLE"},
- {"BAT", "DSX"},
- {"CCK", "ATW"},
- {"IPA", "IOH"},
- {"ISP", "MIP"},
- {"VME", "0AA"},
- {"CPV", "VAS"},
- {"961", "395"},
- {"HIE", "E0G"},
- {"MQ7", "7MQ"},
- {"REA", "3KV"},
- {"RAW", "ECH"},
- {"45H", "45D"},
- {"DRB", "LRB"},
- {"RFB", "RFA"},
- {"5PY", "T36"},
- {"LCH", "LCC"},
- {"DRT", "0DT"},
- {"HDP", "XTR"},
- {"T0N", "T0Q"},
- {"NYM", "T37"},
- {"TMP", "DT", "T"},
- {"THP", "PTP"},
- {"PST", "TS"},
- {"5MU", "RT"},
- {"U18", "F89"},
- {"BJ5", "0UE"},
- {"4JU", "2MH"},
- {"MCB", "ACE", "ACU"},
- {"YI2", "5YI"},
- {"CL1", "CL2"},
- {"CBG", "PNL"},
- {"NBU", "BUT", "SBU"},
- {"NP6", "BA4"},
- {"YMY", "YN1"},
- {"YMM", "YMJ"},
- {"PEI", "LEA"},
- {"CRC", "DKA"},
- {"LAU", "DAO"},
- {"PLM", "FAT"},
- {"3PH", "2SP"},
- {"QEH", "LP3"},
- {"C8E", "OTE"},
- {"OLA", "OLI"},
- {"HQ", "HQO"},
- {"13H", "243"},
- {"LYW", "EJM"},
- {"1ZD", "2NC"},
- {"0AM", "0SP"},
- {"2PI", "RON", "NVA", "BTA"},
- {"EOX", "EOH", "OHE"},
- {"P3G", "6JZ"},
- {"XL1", "SCC"},
- {"ITU", "SEU"},
- {"1NI", "LP2", "LP1"},
- {"ABA", "AB7"},
- {"CHC", "IU6"},
- {"DCI", "MBA"},
- {"0EZ", "PI6"},
- {"INY", "CRP"},
- {"T0M", "EMT"},
- {"NET", "E4N"},
- {"F22", "HXA"},
- {"GXJ", "I0E"},
- {"PYJ", "N2B"},
- {"NC", "NME"},
- {"MLY", "TRG"},
- {"R5A", "R5B"},
- {"3MU", "UR3"},
- {"VSB", "VSE"},
- {"PTC", "AY0"},
- {"M4C", "4OC"},
- {"SAR", "MGY"},
- {"YNM", "N9K"},
- {"A34", "6MC", "6MA", "6MT"},
- {"A35", "A40"},
- {"6OO", "OKQ"},
- {"A2M", "0AV", "A39"},
- {"MMA", "MAM"},
- {"MGA", "MBG"},
- {"G32", "6OG"},
- {"1CR", "0CR"},
- {"3DQ", "9ZT"},
- {"ROL", "4RR", "4SR"},
- {"1IS", "1IR"},
- {"GB", "PPM"},
- {"577", "IIM"},
- {"CYM", "SMC"},
- {"K7J", "0ZO"},
- {"PIA", "AYG"},
- {"CRW", "MDO"},
- {"YKP", "YKM"},
- {"WLD", "WH7"},
- {"PGO", "PGQ"},
- {"HBL", "HBI"},
- {"BH4", "THB", "H4B"},
- {"98", "986"},
- {"PYL", "PYH"},
- {"JRC", "JQL"},
- {"KOL", "MER"},
- {"1GL", "BRI"},
- {"6CT", "T32"},
- {"MEP", "T23"},
- {"AGL", "RV7"},
- {"G6D", "GLW"},
- {"ARE", "5SA"},
- {"DDB", "MDA"},
- {"53P", "5P8", "QB4"},
- {"STO", "STU"},
- {"INH", "8MI"},
- {"DLA", "LAC"},
- {"AMV", "MMR"},
- {"DHO", "DXC"},
- {"HP3", "PGR"},
- {"HPB", "PR0"},
- {"TRB", "TB9"},
- {"RAA", "RAM"},
- {"MFU", "MFA"},
- {"FUL", "AFL"},
- {"SAA", "APG"},
- {"OET", "ETH"},
- {"HGC", "MMC"},
- {"POC", "PC"},
- {"MOT", "COE"},
- {"SOM", "MPS"},
- {"TTH", "GER"},
- {"TBM", "TMB"},
- {"PDL", "PP3"},
- {"PLA", "AMA"},
- {"THQ", "TZP"},
- {"RIC", "RBZ"},
- {"MDI", "N0U"},
- {"MJQ", "6LX"},
- {"RNY", "AQZ"},
- {"267", "263"},
- {"NEV", "NVP", "NIV"},
- {"PYD", "YF1"},
- {"G33", "8MG"},
- {"0SN", "88N"},
- {"7CP", "MB0"},
- {"HIC", "MH1", "NEM"},
- {"HDZ", "TFH"},
- {"QTR", "OXO", "HOH", "DIS", "O", "OX", "MTO"},
- {"FEO", "F2O"},
- {"O2", "OXY"},
- {"2MO", "MM4"},
- {"PI", "IPS"},
- {"S", "H2S"},
- {"BRO", "BR"},
- {"IDS", "2SI"},
- {"BHD", "DOH"},
- {"UEV", "I7P"},
- {"CLO", "CL"},
- {"FLO", "F"},
- {"MH6", "SRI"},
- {"672", "Q72"},
- {"YJC", "424"},
- {"1MA", "MAD"},
- {"IDO", "IOD"},
- {"NH4", "NGN"},
- {"NMO", "NO"},
- {"SUL", "SO4"},
- {"HYD", "OH"},
- {"B51", "WCC"},
- {"ZN", "ZN2"},
- {"FIB", "IBF"},
- {"PGS", "SPG"},
- {"ANE", "ADE"},
- {"PCQ", "NEW"},
- {"EGG", "KDH"},
- {"G1Z", "G1T"},
- {"B7D", "TRU"},
- {"P5P", "PR5"},
- {"9HE", "KS1"},
- {"DHY", "HAA"},
- {"TY3", "DAH"},
- {"LNR", "LT4"},
- {"NAH", "NAD"},
- {"MTY", "EHP"},
- {"PIX", "TF6"},
- {"CSY", "GYS"},
- {"FA", "FOL"},
- {"TYS", "STY"},
- {"YAP", "69X"},
- {"CBP", "345"},
- {"GHP", "DGH", "NTY"},
- {"CR2", "CQR"},
- {"WAK", "WB8"},
- {"KSB", "QHL"},
- {"BPC", "BP", "BAP"},
- {"6AB", "BE2"},
- {"L0H", "L0F"},
- {"BEZ", "BOX"},
- {"FSL", "F9V"},
- {"PPY", "1PY"},
- {"P6S", "BGG"},
- {"CBZ", "BZO"},
- {"PMS", "IOX"},
- {"PHM", "PCS"},
- {"LLA", "LOF", "HFA"},
- {"TPH", "HPH"},
- {"PUK", "FRF"},
- {"0AC", "FOG"},
- {"638", "XV6"},
- {"BIC", "MOL"},
- {"D8W", "3DB"},
- {"PGY", "PG9"},
- {"119", "P4P"},
- {"86Q", "DRG"},
- {"89E", "LIG"},
- {"GPR", "CYP"},
- {"URY", "K0I"},
- {"TRP", "LTR"},
- {"V7F", "V70"},
- {"QNC", "QND"},
- {"0TN", "RKP"},
- {"QX", "QUI"},
- {"AC4", "AMZ"},
- {"D5M", "DA"},
- {"A", "AMP"},
- {"0DG", "DFG"},
- {"LG", "0G"},
- {"DCG", "DGP", "DG"},
- {"DI", "OIP"},
- {"5GP", "G25", "G", "CPG"},
- {"IMP", "I"},
- {"GTO", "GCP"},
- {"GNP", "GTN"},
- ],
- )
- monkeypatch.setattr(
- "plinder.data.utils.annotations.ligand_utils.CCD_SYNONYMS_DICT",
- {
- "B1F": "B1F",
- "B2F": "B1F",
- "OY5": "OY5",
- "OY8": "OY5",
- "4LA": "N1B",
- "N1B": "N1B",
- "C2H": "C2H",
- "ETD": "C2H",
- "CBX": "CBX",
- "FMT": "CBX",
- "NFB": "NFB",
- "NFO": "NFB",
- "B4M": "B4M",
- "MBR": "B4M",
- "PGC": "PGC",
- "PGH": "PGC",
- "BRM": "BRM",
- "BXA": "BRM",
- "2PL": "PGA",
- "PGA": "PGA",
- "CRY": "CRY",
- "GOL": "CRY",
- "VKN": "VKN",
- "YLL": "VKN",
- "0P0": "GTT",
- "GTT": "GTT",
- "VDW": "GTT",
- "2OG": "AKG",
- "AKG": "AKG",
- "GGL": "GGL",
- "GLU": "GGL",
- "DGL": "DGL",
- "FGA": "DGL",
- "ACA": "ACA",
- "AHA": "ACA",
- "GCG": "GCG",
- "TS3": "GCG",
- "HPG": "HPG",
- "PDO": "HPG",
- "148": "BTB",
- "BTB": "BTB",
- "EDO": "EDO",
- "EGL": "EDO",
- "PGE": "PGE",
- "PIG": "PGE",
- "P2K": "P2K",
- "P6G": "P2K",
- "DHL": "DHL",
- "SEA": "DHL",
- "BME": "BME",
- "SEO": "BME",
- "CS0": "CS0",
- "OCY": "CS0",
- "AA4": "AA4",
- "DHN": "AA4",
- "ABK": "ABK",
- "FKI": "ABK",
- "ASP": "ASP",
- "IAS": "ASP",
- "ASQ": "ASQ",
- "PAS": "ASQ",
- "PHD": "ASQ",
- "SEG": "SEG",
- "SER": "SEG",
- "BTC": "BTC",
- "CYS": "BTC",
- "FCY": "BTC",
- "CAY": "CAY",
- "CCS": "CAY",
- "CEA": "CEA",
- "CSO": "CEA",
- "CSE": "CSE",
- "SEC": "CSE",
- "ICI": "ICI",
- "ICT": "ICI",
- "GLR": "GLR",
- "KGR": "GLR",
- "GAL": "GAL",
- "GLB": "GAL",
- "G4S": "G4S",
- "GSA": "G4S",
- "TWG": "TWG",
- "Z4Y": "TWG",
- "GS4": "GS4",
- "GSD": "GS4",
- "SGC": "GS4",
- "SGN": "SGN",
- "YJM": "SGN",
- "AGC": "AGC",
- "GLC": "AGC",
- "ADG": "ADG",
- "TOA": "ADG",
- "GU4": "GU4",
- "NT2": "GU4",
- "GP1": "GP1",
- "L1L": "GP1",
- "BFP": "BFP",
- "FBP": "BFP",
- "I8Z": "I8Z",
- "I9X": "I8Z",
- "BDR": "BDR",
- "HSU": "BDR",
- "R1P": "R1P",
- "RDP": "R1P",
- "H5P": "H5P",
- "HNP": "H5P",
- "DAS": "DAS",
- "DSP": "DAS",
- "DMR": "DMR",
- "MLT": "DMR",
- "3PG": "MP3",
- "MP3": "MP3",
- "2PG": "PAG",
- "PAG": "PAG",
- "0AL": "GPH",
- "GPH": "GPH",
- "GPO": "GPH",
- "R51": "R51",
- "R52": "R51",
- "IDG": "IDG",
- "PA4": "IDG",
- "KPI": "KPI",
- "MCL": "KPI",
- "EUG": "EUG",
- "H7Y": "EUG",
- "2H3": "CBU",
- "CBU": "CBU",
- "INS": "CBU",
- "I6P": "I6P",
- "IHP": "I6P",
- "KGN": "I6P",
- "GLL": "GLL",
- "GUR": "GLL",
- "0AU": "IU",
- "IU": "IU",
- "DGC": "DGC",
- "GCD": "DGC",
- "ACI": "ACI",
- "CMN": "ACI",
- "CYL": "ACI",
- "ACZ": "ACZ",
- "TZA": "ACZ",
- "0C": "LC",
- "LC": "LC",
- "C": "C25",
- "C25": "C25",
- "C5P": "C25",
- "0U": "LHU",
- "LHU": "LHU",
- "2AU": "U2N",
- "U2N": "U2N",
- "U": "U25",
- "U25": "U25",
- "U5P": "U25",
- "T31": "T31",
- "U37": "T31",
- "4SU": "S4U",
- "S4U": "S4U",
- "HHP": "HHP",
- "PH2": "HHP",
- "5HP": "PCA",
- "PCA": "PCA",
- "PCC": "PCA",
- "ALC": "ALC",
- "HAC": "ALC",
- "CHG": "CHG",
- "CUC": "CHG",
- "DHU": "DHU",
- "H2U": "DHU",
- "DIO": "DIO",
- "DOX": "DIO",
- "DXD": "DXD",
- "DXN": "DXD",
- "D1P": "D1P",
- "ORP": "D1P",
- "C32": "C32",
- "CBR": "C32",
- "C38": "C38",
- "I5C": "C38",
- "5IT": "5IT",
- "5IU": "5IT",
- "DC": "DCM",
- "DCM": "DCM",
- "C7R": "C7R",
- "C7S": "C7R",
- "DU": "UMP",
- "UMP": "UMP",
- "0UH": "IGU",
- "IGU": "IGU",
- "AAB": "AAB",
- "B1P": "AAB",
- "MNM": "MNM",
- "NOZ": "MNM",
- "DNJ": "DNJ",
- "NOJ": "DNJ",
- "BAR": "BAR",
- "TSA": "BAR",
- "TSO": "BAR",
- "0AZ": "UYA",
- "UYA": "UYA",
- "0DC": "DFC",
- "DFC": "DFC",
- "HSZ": "HSZ",
- "XYP": "HSZ",
- "BXP": "BXP",
- "XYB": "BXP",
- "DDM": "DDM",
- "DMJ": "DDM",
- "FLH": "FLH",
- "FOR": "FLH",
- "MIE": "MIE",
- "PVL": "MIE",
- "AAE": "AAE",
- "LIN": "AAE",
- "3NK": "LL8",
- "LL8": "LL8",
- "CHH": "CHH",
- "NWB": "CHH",
- "F3V": "F3V",
- "GCM": "F3V",
- "GLM": "F3V",
- "ACM": "ACM",
- "CNM": "ACM",
- "1ZT": "SC2",
- "SC2": "SC2",
- "RTV": "RTV",
- "YYR": "RTV",
- "NAN": "NAN",
- "SI2": "NAN",
- "SIA": "NAN",
- "7BN": "7BN",
- "7BO": "7BN",
- "0AT": "0AT",
- "16G": "0AT",
- "HSR": "HSR",
- "NAG": "HSR",
- "1NA": "MAG",
- "MAG": "MAG",
- "ASG": "ASG",
- "NGL": "ASG",
- "5G0": "OGN",
- "OGN": "OGN",
- "NNS": "NNS",
- "TYL": "NNS",
- "ACY": "ACY",
- "CBM": "ACY",
- "CM": "ACY",
- "CKC": "CKC",
- "LYM": "CKC",
- "BOC": "BOC",
- "OTB": "BOC",
- "BUG": "BUG",
- "HV5": "BUG",
- "TBG": "BUG",
- "ALQ": "ALQ",
- "ISB": "ALQ",
- "F3P": "F3P",
- "FPG": "F3P",
- "GRL": "GRL",
- "UIC": "GRL",
- "CLE": "CLE",
- "NLW": "CLE",
- "0FA": "LEP",
- "LEP": "LEP",
- "YLV": "YLV",
- "YM1": "YLV",
- "YKA": "YKA",
- "YKD": "YKA",
- "YKY": "YKY",
- "YL7": "YKY",
- "YMD": "YMD",
- "YMG": "YMD",
- "YMS": "YMS",
- "YMV": "YMS",
- "Y8Y": "Y8Y",
- "Y91": "Y8Y",
- "Y51": "Y51",
- "Y71": "Y51",
- "Y4P": "Y4P",
- "Y7G": "Y4P",
- "YLD": "YLD",
- "YLJ": "YLD",
- "YKS": "YKS",
- "YKV": "YKS",
- "1LU": "OLE",
- "OLE": "OLE",
- "GCL": "GCL",
- "XAO": "GCL",
- "HMI": "HMI",
- "HMP": "HMI",
- "HAP": "HAP",
- "PLH": "HAP",
- "PLE": "PLE",
- "PLU": "PLE",
- "BAT": "BAT",
- "DSX": "BAT",
- "ATW": "ATW",
- "CCK": "ATW",
- "IOH": "IOH",
- "IPA": "IOH",
- "ISP": "ISP",
- "MIP": "ISP",
- "0AA": "VME",
- "VME": "VME",
- "CPV": "CPV",
- "VAS": "CPV",
- "395": "395",
- "961": "395",
- "E0G": "E0G",
- "HIE": "E0G",
- "7MQ": "MQ7",
- "MQ7": "MQ7",
- "3KV": "REA",
- "REA": "REA",
- "ECH": "ECH",
- "RAW": "ECH",
- "45D": "45D",
- "45H": "45D",
- "DRB": "DRB",
- "LRB": "DRB",
- "RFA": "RFA",
- "RFB": "RFA",
- "5PY": "T36",
- "T36": "T36",
- "LCC": "LCC",
- "LCH": "LCC",
- "0DT": "DRT",
- "DRT": "DRT",
- "HDP": "HDP",
- "XTR": "HDP",
- "T0N": "T0N",
- "T0Q": "T0N",
- "NYM": "NYM",
- "T37": "NYM",
- "DT": "TMP",
- "T": "TMP",
- "TMP": "TMP",
- "PTP": "PTP",
- "THP": "PTP",
- "PST": "PST",
- "TS": "PST",
- "5MU": "RT",
- "RT": "RT",
- "F89": "F89",
- "U18": "F89",
- "0UE": "BJ5",
- "BJ5": "BJ5",
- "2MH": "2MH",
- "4JU": "2MH",
- "ACE": "ACE",
- "ACU": "ACE",
- "MCB": "ACE",
- "5YI": "YI2",
- "YI2": "YI2",
- "CL1": "CL1",
- "CL2": "CL1",
- "CBG": "CBG",
- "PNL": "CBG",
- "BUT": "BUT",
- "NBU": "BUT",
- "SBU": "BUT",
- "BA4": "BA4",
- "NP6": "BA4",
- "YMY": "YMY",
- "YN1": "YMY",
- "YMJ": "YMJ",
- "YMM": "YMJ",
- "LEA": "LEA",
- "PEI": "LEA",
- "CRC": "CRC",
- "DKA": "CRC",
- "DAO": "DAO",
- "LAU": "DAO",
- "FAT": "FAT",
- "PLM": "FAT",
- "2SP": "2SP",
- "3PH": "2SP",
- "LP3": "LP3",
- "QEH": "LP3",
- "C8E": "C8E",
- "OTE": "C8E",
- "OLA": "OLA",
- "OLI": "OLA",
- "HQ": "HQO",
- "HQO": "HQO",
- "13H": "13H",
- "243": "13H",
- "EJM": "EJM",
- "LYW": "EJM",
- "1ZD": "1ZD",
- "2NC": "1ZD",
- "0AM": "0AM",
- "0SP": "0AM",
- "2PI": "BTA",
- "BTA": "BTA",
- "NVA": "BTA",
- "RON": "BTA",
- "EOH": "EOH",
- "EOX": "EOH",
- "OHE": "EOH",
- "6JZ": "P3G",
- "P3G": "P3G",
- "SCC": "SCC",
- "XL1": "SCC",
- "ITU": "ITU",
- "SEU": "ITU",
- "1NI": "LP1",
- "LP1": "LP1",
- "LP2": "LP1",
- "AB7": "AB7",
- "ABA": "AB7",
- "CHC": "CHC",
- "IU6": "CHC",
- "DCI": "DCI",
- "MBA": "DCI",
- "0EZ": "PI6",
- "PI6": "PI6",
- "CRP": "CRP",
- "INY": "CRP",
- "EMT": "EMT",
- "T0M": "EMT",
- "E4N": "E4N",
- "NET": "E4N",
- "F22": "F22",
- "HXA": "F22",
- "GXJ": "GXJ",
- "I0E": "GXJ",
- "N2B": "N2B",
- "PYJ": "N2B",
- "NC": "NME",
- "NME": "NME",
- "MLY": "MLY",
- "TRG": "MLY",
- "R5A": "R5A",
- "R5B": "R5A",
- "3MU": "UR3",
- "UR3": "UR3",
- "VSB": "VSB",
- "VSE": "VSB",
- "AY0": "AY0",
- "PTC": "AY0",
- "4OC": "M4C",
- "M4C": "M4C",
- "MGY": "MGY",
- "SAR": "MGY",
- "N9K": "N9K",
- "YNM": "N9K",
- "6MA": "A34",
- "6MC": "A34",
- "6MT": "A34",
- "A34": "A34",
- "A35": "A35",
- "A40": "A35",
- "6OO": "OKQ",
- "OKQ": "OKQ",
- "0AV": "A2M",
- "A2M": "A2M",
- "A39": "A2M",
- "MAM": "MAM",
- "MMA": "MAM",
- "MBG": "MBG",
- "MGA": "MBG",
- "6OG": "G32",
- "G32": "G32",
- "0CR": "0CR",
- "1CR": "0CR",
- "3DQ": "3DQ",
- "9ZT": "3DQ",
- "4RR": "ROL",
- "4SR": "ROL",
- "ROL": "ROL",
- "1IR": "1IR",
- "1IS": "1IR",
- "GB": "PPM",
- "PPM": "PPM",
- "577": "IIM",
- "IIM": "IIM",
- "CYM": "CYM",
- "SMC": "CYM",
- "0ZO": "K7J",
- "K7J": "K7J",
- "AYG": "AYG",
- "PIA": "AYG",
- "CRW": "CRW",
- "MDO": "CRW",
- "YKM": "YKM",
- "YKP": "YKM",
- "WH7": "WH7",
- "WLD": "WH7",
- "PGO": "PGO",
- "PGQ": "PGO",
- "HBI": "HBI",
- "HBL": "HBI",
- "BH4": "BH4",
- "H4B": "BH4",
- "THB": "BH4",
- "98": "986",
- "986": "986",
- "PYH": "PYH",
- "PYL": "PYH",
- "JQL": "JQL",
- "JRC": "JQL",
- "KOL": "KOL",
- "MER": "KOL",
- "1GL": "BRI",
- "BRI": "BRI",
- "6CT": "T32",
- "T32": "T32",
- "MEP": "MEP",
- "T23": "MEP",
- "AGL": "AGL",
- "RV7": "AGL",
- "G6D": "G6D",
- "GLW": "G6D",
- "5SA": "ARE",
- "ARE": "ARE",
- "DDB": "DDB",
- "MDA": "DDB",
- "53P": "QB4",
- "5P8": "QB4",
- "QB4": "QB4",
- "STO": "STO",
- "STU": "STO",
- "8MI": "INH",
- "INH": "INH",
- "DLA": "DLA",
- "LAC": "DLA",
- "AMV": "AMV",
- "MMR": "AMV",
- "DHO": "DHO",
- "DXC": "DHO",
- "HP3": "HP3",
- "PGR": "HP3",
- "HPB": "HPB",
- "PR0": "HPB",
- "TB9": "TB9",
- "TRB": "TB9",
- "RAA": "RAA",
- "RAM": "RAA",
- "MFA": "MFA",
- "MFU": "MFA",
- "AFL": "AFL",
- "FUL": "AFL",
- "APG": "APG",
- "SAA": "APG",
- "ETH": "ETH",
- "OET": "ETH",
- "HGC": "HGC",
- "MMC": "HGC",
- "PC": "POC",
- "POC": "POC",
- "COE": "COE",
- "MOT": "COE",
- "MPS": "MPS",
- "SOM": "MPS",
- "GER": "GER",
- "TTH": "GER",
- "TBM": "TBM",
- "TMB": "TBM",
- "PDL": "PDL",
- "PP3": "PDL",
- "AMA": "AMA",
- "PLA": "AMA",
- "THQ": "THQ",
- "TZP": "THQ",
- "RBZ": "RBZ",
- "RIC": "RBZ",
- "MDI": "MDI",
- "N0U": "MDI",
- "6LX": "MJQ",
- "MJQ": "MJQ",
- "AQZ": "AQZ",
- "RNY": "AQZ",
- "263": "263",
- "267": "263",
- "NEV": "NEV",
- "NIV": "NEV",
- "NVP": "NEV",
- "PYD": "PYD",
- "YF1": "PYD",
- "8MG": "G33",
- "G33": "G33",
- "0SN": "0SN",
- "88N": "0SN",
- "7CP": "MB0",
- "MB0": "MB0",
- "HIC": "HIC",
- "MH1": "HIC",
- "NEM": "HIC",
- "HDZ": "HDZ",
- "TFH": "HDZ",
- "DIS": "DIS",
- "HOH": "DIS",
- "MTO": "DIS",
- "O": "DIS",
- "OX": "DIS",
- "OXO": "DIS",
- "QTR": "DIS",
- "F2O": "F2O",
- "FEO": "F2O",
- "O2": "OXY",
- "OXY": "OXY",
- "2MO": "MM4",
- "MM4": "MM4",
- "IPS": "IPS",
- "PI": "IPS",
- "H2S": "H2S",
- "S": "H2S",
- "BR": "BRO",
- "BRO": "BRO",
- "2SI": "IDS",
- "IDS": "IDS",
- "BHD": "BHD",
- "DOH": "BHD",
- "I7P": "I7P",
- "UEV": "I7P",
- "CL": "CLO",
- "CLO": "CLO",
- "F": "FLO",
- "FLO": "FLO",
- "MH6": "MH6",
- "SRI": "MH6",
- "672": "Q72",
- "Q72": "Q72",
- "424": "YJC",
- "YJC": "YJC",
- "1MA": "MAD",
- "MAD": "MAD",
- "IDO": "IDO",
- "IOD": "IDO",
- "NGN": "NGN",
- "NH4": "NGN",
- "NMO": "NMO",
- "NO": "NMO",
- "SO4": "SO4",
- "SUL": "SO4",
- "HYD": "HYD",
- "OH": "HYD",
- "B51": "B51",
- "WCC": "B51",
- "ZN": "ZN2",
- "ZN2": "ZN2",
- "FIB": "FIB",
- "IBF": "FIB",
- "PGS": "PGS",
- "SPG": "PGS",
- "ADE": "ADE",
- "ANE": "ADE",
- "NEW": "NEW",
- "PCQ": "NEW",
- "EGG": "EGG",
- "KDH": "EGG",
- "G1T": "G1T",
- "G1Z": "G1T",
- "B7D": "B7D",
- "TRU": "B7D",
- "P5P": "P5P",
- "PR5": "P5P",
- "9HE": "KS1",
- "KS1": "KS1",
- "DHY": "DHY",
- "HAA": "DHY",
- "DAH": "DAH",
- "TY3": "DAH",
- "LNR": "LNR",
- "LT4": "LNR",
- "NAD": "NAD",
- "NAH": "NAD",
- "EHP": "EHP",
- "MTY": "EHP",
- "PIX": "PIX",
- "TF6": "PIX",
- "CSY": "CSY",
- "GYS": "CSY",
- "FA": "FOL",
- "FOL": "FOL",
- "STY": "STY",
- "TYS": "STY",
- "69X": "YAP",
- "YAP": "YAP",
- "345": "CBP",
- "CBP": "CBP",
- "DGH": "DGH",
- "GHP": "DGH",
- "NTY": "DGH",
- "CQR": "CQR",
- "CR2": "CQR",
- "WAK": "WAK",
- "WB8": "WAK",
- "KSB": "KSB",
- "QHL": "KSB",
- "BAP": "BAP",
- "BP": "BAP",
- "BPC": "BAP",
- "6AB": "BE2",
- "BE2": "BE2",
- "L0F": "L0F",
- "L0H": "L0F",
- "BEZ": "BEZ",
- "BOX": "BEZ",
- "F9V": "F9V",
- "FSL": "F9V",
- "1PY": "PPY",
- "PPY": "PPY",
- "BGG": "BGG",
- "P6S": "BGG",
- "BZO": "BZO",
- "CBZ": "BZO",
- "IOX": "IOX",
- "PMS": "IOX",
- "PCS": "PCS",
- "PHM": "PCS",
- "HFA": "HFA",
- "LLA": "HFA",
- "LOF": "HFA",
- "HPH": "HPH",
- "TPH": "HPH",
- "FRF": "FRF",
- "PUK": "FRF",
- "0AC": "FOG",
- "FOG": "FOG",
- "638": "XV6",
- "XV6": "XV6",
- "BIC": "BIC",
- "MOL": "BIC",
- "3DB": "D8W",
- "D8W": "D8W",
- "PG9": "PG9",
- "PGY": "PG9",
- "119": "P4P",
- "P4P": "P4P",
- "86Q": "DRG",
- "DRG": "DRG",
- "89E": "LIG",
- "LIG": "LIG",
- "CYP": "CYP",
- "GPR": "CYP",
- "K0I": "K0I",
- "URY": "K0I",
- "LTR": "LTR",
- "TRP": "LTR",
- "V70": "V70",
- "V7F": "V70",
- "QNC": "QNC",
- "QND": "QNC",
- "0TN": "RKP",
- "RKP": "RKP",
- "QUI": "QUI",
- "QX": "QUI",
- "AC4": "AC4",
- "AMZ": "AC4",
- "D5M": "D5M",
- "DA": "D5M",
- "A": "AMP",
- "AMP": "AMP",
- "0DG": "DFG",
- "DFG": "DFG",
- "0G": "LG",
- "LG": "LG",
- "DCG": "DCG",
- "DG": "DCG",
- "DGP": "DCG",
- "DI": "OIP",
- "OIP": "OIP",
- "5GP": "CPG",
- "CPG": "CPG",
- "G": "CPG",
- "G25": "CPG",
- "I": "IMP",
- "IMP": "IMP",
- "GCP": "GCP",
- "GTO": "GCP",
- "GNP": "GNP",
- "GTN": "GNP",
- },
- )
- monkeypatch.setattr(
- "plinder.data.utils.annotations.ligand_utils.COFACTORS",
- {
- "JM2",
- "PCD",
- "CAA",
- "NCA",
- "HEM",
- "0XU",
- "RGE",
- "NAX",
- "LPB",
- "AMX",
- "TXP",
- "SCO",
- "MQ7",
- "FNS",
- "MQ9",
- "FMN",
- "PLR",
- "CHL",
- "WSD",
- "TD7",
- "TPQ",
- "SDX",
- "GVX",
- "TS5",
- "EB4",
- "ENA",
- "NDE",
- "1CZ",
- "2MD",
- "CYP",
- "1JO",
- "PP9",
- "GS8",
- "TDM",
- "C2F",
- "NPL",
- "UP3",
- "8EL",
- "AMP",
- "4LU",
- "1DG",
- "DCQ",
- "2CP",
- "GBP",
- "NAQ",
- "HDE",
- "62X",
- "NDP",
- "CCH",
- "TD6",
- "SCD",
- "TXD",
- "UU3",
- "M6T",
- "3HC",
- "SFD",
- "NHM",
- "66S",
- "TMP",
- "ODP",
- "3CP",
- "CLA",
- "CL7",
- "1TY",
- "NBD",
- "C",
- "COM",
- "T6F",
- "MSS",
- "1CV",
- "MCN",
- "ASC",
- "SA8",
- "WCA",
- "S1T",
- "GF5",
- "IRF",
- "CPG",
- "MCA",
- "36A",
- "ISW",
- "GIP",
- "TYQ",
- "PMP",
- "CL2",
- "FCG",
- "UTP",
- "1R4",
- "NAP",
- "HDD",
- "FDE",
- "GTX",
- "CDP",
- "CA8",
- "1U0",
- "76K",
- "GGC",
- "AGQ",
- "XP9",
- "FON",
- "ZEM",
- "1YJ",
- "PQN",
- "76J",
- "IBG",
- "UEG",
- "5GP",
- "1VU",
- "3H9",
- "LPM",
- "BCA",
- "VWW",
- "FAS",
- "DPM",
- "3CD",
- "NA0",
- "TTP",
- "6J4",
- "DT",
- "48T",
- "GTS",
- "4LS",
- "TDT",
- "HMG",
- "THG",
- "TDL",
- "6NR",
- "FSH",
- "G27",
- "TGG",
- "THV",
- "BYC",
- "2TP",
- "FA8",
- "EN0",
- "HXC",
- "2NE",
- "T1G",
- "DU",
- "7AP",
- "THM",
- "TZD",
- "N1T",
- "PAU",
- "ADP",
- "DLZ",
- "A3D",
- "COB",
- "ECH",
- "TYY",
- "MTV",
- "7HE",
- "29P",
- "HAS",
- "G",
- "3AA",
- "UMP",
- "BTN",
- "H4B",
- "YNC",
- "CA5",
- "C5P",
- "0ET",
- "CA3",
- "C25",
- "TP8",
- "FOZ",
- "CNC",
- "TC6",
- "DDH",
- "4CA",
- "MNH",
- "U",
- "76L",
- "G25",
- "JM7",
- "FDA",
- "A",
- "07D",
- "P2Q",
- "NHW",
- "COT",
- "4YP",
- "DTB",
- "GSN",
- "COO",
- "ZNH",
- "BPH",
- "NPW",
- "COH",
- "GDS",
- "L9X",
- "DG1",
- "PAD",
- "MNR",
- "GDN",
- "SX0",
- None,
- "NDC",
- "BCL",
- "COW",
- "TXZ",
- "8EF",
- "WWF",
- "MGD",
- "PZP",
- "GRA",
- "HTL",
- "FRE",
- "0HH",
- "FAA",
- "TP7",
- "AT5",
- "BYG",
- "SRM",
- "MDE",
- "EAD",
- "TPU",
- "4CO",
- "P3Q",
- "TRQ",
- "GMP",
- "M43",
- "LEE",
- "CTP",
- "PXL",
- "ABY",
- "SAH",
- "HIF",
- "GTY",
- "TT8",
- "SMM",
- "COF",
- "ZBF",
- "FAM",
- "T",
- "COA",
- "8ID",
- "GSF",
- "76M",
- "DN4",
- "FAD",
- "5AU",
- "0WD",
- "COZ",
- "CRW",
- "76H",
- "SND",
- "FNR",
- "UDP",
- "BHS",
- "6V0",
- "CYC",
- "ATP",
- "BYT",
- "EPY",
- "THF",
- "GSH",
- "MQE",
- "COY",
- "HAX",
- "1JP",
- "37H",
- "NBP",
- "ZID",
- "MFN",
- "SOP",
- "TPP",
- "PDP",
- "PQQ",
- "GPR",
- "GTP",
- "CA6",
- "DHE",
- "SHT",
- "F42",
- "0Y1",
- "MTQ",
- "H2B",
- "6FA",
- "6HE",
- "THB",
- "CP3",
- "SFG",
- "CAJ",
- "DCC",
- "TD9",
- "8PA",
- "NDO",
- "THY",
- "N3T",
- "MH0",
- "FMI",
- "AP0",
- "GBI",
- "UQ1",
- "H4M",
- "LZ6",
- "FCX",
- "NAJ",
- "MDO",
- "FAE",
- "S0N",
- "HBI",
- "SAD",
- "TDK",
- "TDW",
- "18W",
- "BIO",
- "UQ2",
- "1C4",
- "GPS",
- "FED",
- "NHQ",
- "TQQ",
- "XP8",
- "2TY",
- "G9R",
- "ACO",
- "TDP",
- "UAH",
- "U5P",
- "ESG",
- "FAO",
- "7MQ",
- "CND",
- "D7K",
- "8FL",
- "CO6",
- "PUB",
- "HCC",
- "SAE",
- "AHE",
- "4IK",
- "Y7Y",
- "488",
- "TAP",
- "RAW",
- "DCA",
- "BOB",
- "NAI",
- "TXE",
- "HEC",
- "BCR",
- "MYA",
- "HBL",
- "P1H",
- "01A",
- "UQ6",
- "ATA",
- "NHD",
- "B12",
- "FAB",
- "1HA",
- "MCD",
- "TYD",
- "SAM",
- "8JD",
- "PLQ",
- "GTD",
- "UP2",
- "0UM",
- "NOP",
- "GBX",
- "COD",
- "THD",
- "NAH",
- "NAE",
- "CMC",
- "4AB",
- "SCA",
- "8EO",
- "ZOZ",
- "BH4",
- "OXK",
- "MLC",
- "LPA",
- "ICY",
- "GSM",
- "HEA",
- "1CP",
- "1XE",
- "GNB",
- "JM5",
- "XAX",
- "P5F",
- "H4Z",
- "EEM",
- "GDP",
- "PLP",
- "FFO",
- "SH0",
- "PNY",
- "5GY",
- "MQ8",
- "EQ3",
- "CO8",
- "HSC",
- "BSJ",
- "MTE",
- "CIC",
- "SE8",
- "PEB",
- "TPZ",
- "GTB",
- "0AF",
- "0Y2",
- "R1T",
- "MPL",
- "01K",
- "U25",
- "CL0",
- "HQE",
- "RBF",
- "FYN",
- "CMX",
- "THW",
- "HAG",
- "MEF",
- "CL1",
- "PXP",
- "TAD",
- "T5X",
- "N01",
- "1TP",
- "TD8",
- "MMP",
- "K15",
- "NAD",
- "RFL",
- "BTI",
- "BCO",
- "GSO",
- "UQ5",
- "GSB",
- "0HG",
- "3GC",
- "NMX",
- "THH",
- "HEB",
- "PNS",
- "TOQ",
- "F43",
- "8Q1",
- "8Z2",
- "CAO",
- "TPW",
- "BCB",
- "0Y0",
- "LNC",
- },
+ "plinder.data.annotations.ligand_utils.COFACTORS",
+ {ccd_components(code) for code in data["cofactors"]},
)
monkeypatch.setattr(
- "plinder.data.utils.annotations.ligand_utils.ARTIFACTS",
- {
- "OTE",
- "BNG",
- "GYF",
- "MES",
- "HEX",
- "PX2",
- "2OP",
- "UMQ",
- "1PS",
- "SIN",
- "VX",
- "C8E",
- "ETF",
- "GOL",
- "CAC",
- "O4B",
- "MBO",
- "9YU",
- "PC8",
- "OGA",
- "PVO",
- "CN6",
- "PGR",
- "DDR",
- "AGA",
- "33O",
- "B3H",
- "MPD",
- "DTU",
- "P03",
- "CXS",
- "QLB",
- "KDO",
- "3HR",
- "DIO",
- "THE",
- "RG1",
- "F09",
- "HTG",
- "SP5",
- "BOX",
- "CN3",
- "L1P",
- "DOX",
- "MPO",
- "TAM",
- "1PG",
- "543",
- "7PE",
- "FW5",
- "PE5",
- "TAR",
- "LMT",
- "DHJ",
- "PX4",
- "FJO",
- "P25",
- "P33",
- "HT3",
- "Y69",
- "TRD",
- "DMF",
- "DTT",
- "P4G",
- "MRD",
- "PGO",
- "144",
- "PGE",
- "TCN",
- "MYR",
- "MAC",
- "LMU",
- "L3P",
- "P22",
- "TCE",
- "BET",
- "HTO",
- "ETX",
- "BAM",
- "DTD",
- "DAO",
- "TRS",
- "CE1",
- "LUT",
- "TOE",
- "PEG",
- "HP3",
- "1PE",
- "7PH",
- "TLA",
- "PE4",
- "DKA",
- "P2K",
- "PA8",
- "1EM",
- "7I7",
- "P6G",
- "IPH",
- "BE7",
- "QGT",
- "L4P",
- "9JE",
- "DMR",
- "BDN",
- "TMA",
- "I6P",
- "DD9",
- "MC3",
- "XPE",
- "OP2",
- "SOG",
- "PG0",
- "E4N",
- "PD7",
- "DET",
- "NBN",
- "PE7",
- "CIT",
- "HZA",
- "N8E",
- "BEN",
- "32M",
- "LI1",
- "DR6",
- "D12",
- "P4C",
- "LIN",
- "BU1",
- "C10",
- "D22",
- "CRC",
- "2NV",
- "CHT",
- "CXE",
- "XP4",
- "PE8",
- "DDQ",
- "15P",
- "L2P",
- "PTD",
- "148",
- "EAP",
- "12P",
- "NHE",
- "TBU",
- "PIG",
- "MGY",
- "HSH",
- "IHS",
- "LAU",
- "HAI",
- "13P",
- "PG5",
- "DHB",
- "FTT",
- "3V3",
- "SAR",
- "ICI",
- "3PG",
- "PUT",
- "LAC",
- "SGM",
- "NET",
- "D1D",
- "PG6",
- "7PG",
- "2JC",
- "2DP",
- "PQE",
- "LMR",
- "CPS",
- "IOX",
- "HSG",
- "BXC",
- "EPE",
- "02U",
- "MB3",
- "L2C",
- "DTV",
- "BOG",
- "NEX",
- "PE3",
- "PHQ",
- "PE6",
- "CE9",
- "C14",
- "CD4",
- "SRT",
- "GLV",
- "BHG",
- "I3C",
- "DLA",
- "ICT",
- "TAU",
- "RWB",
- "LDA",
- "PGF",
- "7E8",
- "HCA",
- "QJE",
- "7E9",
- "BTB",
- "SPZ",
- "HED",
- "PGQ",
- "P1O",
- "TEA",
- "IMD",
- "MP3",
- "JDJ",
- "HTH",
- "V1J",
- "6JZ",
- "AUC",
- "DEP",
- "M2M",
- "PG8",
- "MBN",
- "CAQ",
- "B4T",
- "HAE",
- "P15",
- "UND",
- "9FO",
- "DMI",
- "XPA",
- "PEP",
- "TFA",
- "HEZ",
- "MLA",
- "DRE",
- "PEX",
- "AKR",
- "XAT",
- "PLC",
- "SPD",
- "MLT",
- "F4R",
- "SPM",
- "BGL",
- "AAE",
- "AE3",
- "P3G",
- "SPJ",
- "CRY",
- "PPI",
- "PEU",
- "MAE",
- "PHB",
- "DPG",
- "B4X",
- "OCT",
- "ETE",
- "BNZ",
- "IHP",
- "PMS",
- "B3P",
- "PQ9",
- "3SY",
- "AE4",
- "CAD",
- "2PE",
- "OES",
- "GVT",
- "K12",
- "PG4",
- "EEE",
- "SQU",
- "D10",
- "BCN",
- "7N5",
- "90A",
- "ME2",
- "KGN",
- "16P",
- "MLI",
- "6PE",
- "P4K",
- "BEZ",
- "PL9",
- "HP6",
- },
+ "plinder.data.annotations.ligand_utils.ARTIFACTS",
+ {ccd_components(code) for code in data["artifacts"]},
)
monkeypatch.setattr(
- "plinder.data.utils.annotations.ligand_utils.KINASE_INHIBITORS",
- {
- "4DF",
- "2NR",
- "36R",
- "XJ0",
- "S4Q",
- "8BQ",
- "79Y",
- "ZOI",
- "EBD",
- "1JI",
- "7AE",
- "07Z",
- "PZ4",
- "0WM",
- "JRQ",
- "YD7",
- "RMF",
- "MZJ",
- "LM4",
- "XZN",
- "3EY",
- "GW7",
- "469",
- "2KD",
- "H52",
- "Z67",
- "C5Z",
- "P30",
- "29Z",
- "Y5D",
- "EK9",
- "YIR",
- "MT3",
- "1UK",
- "74K",
- "A9R",
- "N4D",
- "OJ5",
- "78W",
- "SBC",
- "6UY",
- "AWK",
- "8GR",
- "I2O",
- "AAX",
- "SU2",
- "9XA",
- "1EH",
- "HK0",
- "Q17",
- "30K",
- "I0A",
- "6HH",
- "E5J",
- "T2O",
- "FW3",
- "8E1",
- "5X4",
- "EUX",
- "MMH",
- "L10",
- "47X",
- "SIQ",
- "YEE",
- "UNJ",
- "ZRK",
- "AMP",
- "46C",
- "R5D",
- "86K",
- "HCW",
- "Q1Y",
- "YIX",
- "7GV",
- "BI1",
- "C6F",
- "7DZ",
- "8BS",
- "6NP",
- "C2V",
- "4JZ",
- "AFE",
- "Q9B",
- "4MK",
- "NN5",
- "0HD",
- "X85",
- "SCW",
- "A3K",
- "L09",
- "2QT",
- "FS8",
- "1UJ",
- "SS6",
- "X6G",
- "0VG",
- "B7V",
- "XL5",
- "QX1",
- "8FX",
- "7VT",
- "C85",
- "63N",
- "AVZ",
- "IFC",
- "4UT",
- "6PF",
- "DXM",
- "7ZC",
- "5BN",
- "ZY6",
- "R4V",
- "AP2",
- "UIW",
- "54Z",
- "F8I",
- "OQM",
- "C52",
- "4VD",
- "DBQ",
- "1D1",
- "TV4",
- "NU6",
- "EA7",
- "X6B",
- "KZJ",
- "3UI",
- "R73",
- "6NC",
- "0B0",
- "SQM",
- "VEH",
- "X69",
- "JGG",
- "AFM",
- "4RM",
- "0JJ",
- "6KC",
- "1YZ",
- "5JE",
- "OOU",
- "R1W",
- "3QS",
- "A8H",
- "DO0",
- "8UV",
- "WI2",
- "NBW",
- "X40",
- "CK9",
- "J8S",
- "2HW",
- "85A",
- "QUP",
- "MHR",
- "4CV",
- "EZJ",
- "P01",
- "363",
- "TID",
- "CUR",
- "EHB",
- "S92",
- "OQJ",
- "Y8L",
- "GUB",
- "090",
- "4Z8",
- "28D",
- "5W6",
- "8GU",
- "WB8",
- "NQ2",
- "J9D",
- "I3K",
- "1JC",
- "QH1",
- "EX9",
- "13V",
- "514",
- "UT5",
- "YQ2",
- "4FT",
- "P02",
- "FB8",
- "07J",
- "JSN",
- "SM6",
- "X3V",
- "FOI",
- "6H3",
- "60K",
- "T3C",
- "4ZB",
- "J3H",
- "T1T",
- "HZ6",
- "GCC",
- "MTW",
- "B4U",
- "7HK",
- "3BM",
- "16X",
- "50H",
- "Z3A",
- "LB4",
- "74L",
- "9IS",
- "XPY",
- "C87",
- "ACK",
- "5Y6",
- "3RW",
- "IXQ",
- "1IJ",
- "LIA",
- "VFC",
- "0K0",
- "19A",
- "5JG",
- "HVH",
- "H5R",
- "QXW",
- "E91",
- "37Q",
- "Y3L",
- "YIS",
- "YOR",
- "JOZ",
- "JSW",
- "EVK",
- "3GF",
- "253",
- "DLN",
- "QP7",
- "CX4",
- "B4J",
- "1CK",
- "EDJ",
- "P47",
- "857",
- "KA7",
- "R6R",
- "0F4",
- "EMW",
- "CKG",
- "TJF",
- "RO6",
- "23D",
- "319",
- "FGE",
- "TBK",
- "NU5",
- "547",
- "70I",
- "U0T",
- "ASH",
- "H8H",
- "J3N",
- "J6F",
- "38M",
- "L90",
- "CGI",
- "C75",
- "6RF",
- "8OV",
- "2QV",
- "19K",
- "4W5",
- "Z68",
- "HUH",
- "SVK",
- "6QZ",
- "4VQ",
- "7TH",
- "GYL",
- "31Y",
- "BR2",
- "3Z2",
- "NRA",
- "ON6",
- "K88",
- "AXU",
- "PIT",
- "OWQ",
- "D15",
- "NJD",
- "F4A",
- "C4E",
- "04Z",
- "ZOQ",
- "KSH",
- "OY2",
- "E0X",
- "K0E",
- "5GX",
- "MWF",
- "LZC",
- "770",
- "BNB",
- "24Z",
- "7AV",
- "QI6",
- "P49",
- "4Q2",
- "PY1",
- "AGI",
- "DJX",
- "X6K",
- "LOQ",
- "YY7",
- "MKP",
- "IEA",
- "Q2H",
- "AGY",
- "1LE",
- "G6K",
- "QQ2",
- "BD2",
- "I17",
- "OOM",
- "ACP",
- "R74",
- "NBK",
- "N14",
- "EXX",
- "54G",
- "A6Z",
- "TXV",
- "X01",
- "5ZH",
- "FLZ",
- "3E4",
- "IDZ",
- "P31",
- "8I1",
- "14K",
- "6Z2",
- "E2O",
- "QG5",
- "GEN",
- "SVQ",
- "DW1",
- "Z30",
- "LIE",
- "N9R",
- "2OQ",
- "2WJ",
- "3WN",
- "X7G",
- "VZG",
- "54J",
- "4E3",
- "KR8",
- "QZ8",
- "2M2",
- "FPW",
- "0CK",
- "SM7",
- "DF1",
- "99Z",
- "HVK",
- "HK6",
- "PDR",
- "4T6",
- "CD2",
- "CG4",
- "21Z",
- "6BF",
- "R7D",
- "NL2",
- "FZJ",
- "JZH",
- "3G5",
- "SMH",
- "LY4",
- "T2A",
- "RSW",
- "V3S",
- "92C",
- "R4Y",
- "N53",
- "VGK",
- "3ND",
- "14S",
- "9A6",
- "NQB",
- "0GW",
- "UB6",
- "N0V",
- "26L",
- "5TF",
- "1RJ",
- "027",
- "0MY",
- "HVQ",
- "M0R",
- "X86",
- "KLP",
- "1K2",
- "ZRR",
- "XGK",
- "BA1",
- "X19",
- "5Q4",
- "UOE",
- "7GT",
- "7GJ",
- "06N",
- "VJK",
- "IQ6",
- "A65",
- "SWD",
- "29L",
- "8LN",
- "K0B",
- "CK7",
- "N17",
- "30E",
- "7KF",
- "AAZ",
- "9D8",
- "LWH",
- "FQM",
- "LU2",
- "EQT",
- "NIL",
- "EJP",
- "M97",
- "4ST",
- "C2J",
- "DFZ",
- "I6C",
- "5XV",
- "FH0",
- "9HR",
- "HET",
- "0VN",
- "X21",
- "5SZ",
- "DZC",
- "YY4",
- "RKO",
- "FBY",
- "446",
- "RYU",
- "0OP",
- "ATU",
- "2SC",
- "10Z",
- "5DN",
- "3HK",
- "IPK",
- "622",
- "8IQ",
- "WFE",
- "ZSB",
- "L9M",
- "F4G",
- "MMG",
- "G8E",
- "MP6",
- "ZRT",
- "7G9",
- "NAR",
- "RXZ",
- "877",
- "3QH",
- "P16",
- "IM9",
- "XW3",
- "KDI",
- "V55",
- "H7C",
- "RVH",
- "362",
- "5VC",
- "UZD",
- "K6Y",
- "19R",
- "OZ8",
- "5U4",
- "3YO",
- "BRQ",
- "77V",
- "5YZ",
- "D0A",
- "KWD",
- "SQ4",
- "IE8",
- "FSS",
- "VZ2",
- "BXJ",
- "3P0",
- "BWP",
- "RO9",
- "MJG",
- "A6E",
- "5OE",
- "13K",
- "R9B",
- "GYQ",
- "FER",
- "JTQ",
- "KC0",
- "XZ9",
- "WZZ",
- "SFY",
- "3DL",
- "YXJ",
- "F29",
- "TOV",
- "0SX",
- "Y4O",
- "A27",
- "DZO",
- "IM6",
- "CKJ",
- "O3E",
- "9Y5",
- "7QQ",
- "L0M",
- "7GB",
- "RHZ",
- "3NC",
- "912",
- "6V4",
- "5IE",
- "7M0",
- "P37",
- "DT2",
- "ZRL",
- "HYW",
- "6DC",
- "580",
- "0BG",
- "8FI",
- "04G",
- "E28",
- "KRQ",
- "4B0",
- "FDW",
- "POX",
- "P5J",
- "VGH",
- "7X5",
- "2C3",
- "8DS",
- "W39",
- "GUQ",
- "35F",
- "ZZM",
- "A5Z",
- "HC4",
- "36N",
- "UC8",
- "796",
- "F8H",
- "CKN",
- "4T5",
- "NR9",
- "481",
- "AD5",
- "22T",
- "GD9",
- "8OK",
- "HKK",
- "3DK",
- "B0K",
- "R6H",
- "JLC",
- "4S3",
- "596",
- "UH3",
- "38O",
- "2R4",
- "80U",
- "8OT",
- "M1J",
- "6ID",
- "0XG",
- "KJD",
- "M4G",
- "0SO",
- "URF",
- "JKW",
- "UU6",
- "LDN",
- "SO9",
- "HVE",
- "QWQ",
- "T3U",
- "222",
- "P5V",
- "JVD",
- "LTY",
- "L12",
- "TVT",
- "1TT",
- "L4Y",
- "VP7",
- "31W",
- "8OW",
- "QZ2",
- "ZOV",
- "61Y",
- "628",
- "W2R",
- "59U",
- "614",
- "65C",
- "1HK",
- "8X2",
- "E3Z",
- "QB8",
- "SCE",
- "0C5",
- "LOK",
- "0XH",
- "8CC",
- "L0Q",
- "ITQ",
- "TZX",
- "4SB",
- "390",
- "J2V",
- "QF8",
- "K4W",
- "C98",
- "C96",
- "ZD6",
- "8GS",
- "9XK",
- "R6V",
- "UJ3",
- "H4K",
- "35Z",
- "86E",
- "CJ5",
- "1WY",
- "VIN",
- "IXH",
- "G5D",
- "6CY",
- "4RJ",
- "L91",
- "30T",
- "5Y8",
- "3YV",
- "C7Y",
- "1R9",
- "7EY",
- "A7K",
- "5XH",
- "UCW",
- "0TZ",
- "FU6",
- "7KD",
- "215",
- "SWN",
- "6YD",
- "WXV",
- "LI8",
- "37J",
- "AK7",
- "2BZ",
- "RYA",
- "WFY",
- "0SW",
- "RXE",
- "YAM",
- "9CT",
- "3XL",
- "4O7",
- "9VS",
- "GEZ",
- "OOQ",
- "M92",
- "CCK",
- "VEW",
- "6UK",
- "L7C",
- "XZS",
- "MH7",
- "QS7",
- "YPH",
- "B5E",
- "QFK",
- "6P8",
- "QDW",
- "DTD",
- "5BS",
- "60O",
- "679",
- "UNW",
- "P36",
- "6JV",
- "WYE",
- "38P",
- "ULY",
- "J2M",
- "CK1",
- "3PS",
- "9AJ",
- "96Y",
- "JMZ",
- "0FK",
- "W7W",
- "02Z",
- "VSB",
- "CK3",
- "O43",
- "EBI",
- "9JI",
- "G4E",
- "0Q2",
- "BI9",
- "G0K",
- "5UY",
- "8ET",
- "WY3",
- "V5U",
- "M33",
- "9FS",
- "34I",
- "3Q6",
- "P5W",
- "M19",
- "S5E",
- "7CS",
- "4UQ",
- "N5Q",
- "706",
- "TC0",
- "KEP",
- "QIG",
- "HYK",
- "KHH",
- "JFS",
- "V6E",
- "66X",
- "KJR",
- "5E2",
- "ME3",
- "EVQ",
- "0VF",
- "7XU",
- "25J",
- "MMY",
- "L1K",
- "QMN",
- "K11",
- "S9H",
- "N58",
- "JNZ",
- "QBB",
- "5W9",
- "66L",
- "HJF",
- "932",
- "BVI",
- "3RZ",
- "1J5",
- "467",
- "4FJ",
- "3JZ",
- "0SQ",
- "0C9",
- "N99",
- "71M",
- "XU0",
- "0Y4",
- "B0R",
- "OOS",
- "B6N",
- "O44",
- "W4D",
- "S4W",
- "BXI",
- "464",
- "XAZ",
- "BEN",
- "L3G",
- "6T2",
- "US0",
- "6GE",
- "5DF",
- "IRE",
- "BFF",
- "GHT",
- "0FS",
- "24N",
- "EYI",
- "14I",
- "L64",
- "430",
- "30G",
- "X14",
- "718",
- "90W",
- "WZU",
- "LWX",
- "0C8",
- "FCS",
- "38Z",
- "FZ9",
- "P7B",
- "ZS2",
- "M3A",
- "91E",
- "KEY",
- "W38",
- "O23",
- "DFY",
- "JH8",
- "6H4",
- "GJG",
- "A07",
- "J8A",
- "RNF",
- "LI7",
- "AW5",
- "MQY",
- "C72",
- "L9N",
- "IR2",
- "2HB",
- "KVC",
- "NHU",
- "FTU",
- "L3Z",
- "35W",
- "FLJ",
- "X2L",
- "SYY",
- "0S0",
- "OQS",
- "KE7",
- "64M",
- "X3S",
- "UF8",
- "3U1",
- "FML",
- "AQ4",
- "QO7",
- "HVB",
- "O7I",
- "C74",
- "1HX",
- "CUE",
- "904",
- "FZ8",
- "AWF",
- "751",
- "IQU",
- "P66",
- "IQR",
- "KSS",
- "A5B",
- "DVJ",
- "5BM",
- "1XZ",
- "5ID",
- "1V5",
- "3Q2",
- "B6J",
- "R93",
- "M9T",
- "SWB",
- "35X",
- "3B3",
- "YXD",
- "I4M",
- "NXI",
- "R0X",
- "F67",
- "0SC",
- "JRJ",
- "N13",
- "4VE",
- "SQG",
- "B1E",
- "38W",
- "AT8",
- "C53",
- "PVB",
- "SQ7",
- "CPB",
- "AAV",
- "HKN",
- "8MZ",
- "Q18",
- "SQY",
- "YO4",
- "FE7",
- "0V0",
- "88Z",
- "3C8",
- "OZN",
- "EZV",
- "AZ7",
- "E6Q",
- "R85",
- "ZZP",
- "R28",
- "5Y2",
- "R1L",
- "979",
- "3YX",
- "D6Q",
- "QFO",
- "KIH",
- "8ZT",
- "79T",
- "BHO",
- "LVU",
- "FH3",
- "VSA",
- "7GX",
- "5OQ",
- "G93",
- "Q7H",
- "YK2",
- "855",
- "R1S",
- "8MW",
- "3DW",
- "TJZ",
- "112",
- "8XN",
- "DT1",
- "QU6",
- "437",
- "X66",
- "RP9",
- "DFW",
- "3VE",
- "X8J",
- "LZE",
- "BZ9",
- "7H4",
- "9T6",
- "SQK",
- "N4F",
- "1NP",
- "77A",
- "EZN",
- "ESN",
- "FP3",
- "9KO",
- "0OM",
- "XHM",
- "EQZ",
- "627",
- "SZW",
- "74J",
- "5CV",
- "VY0",
- "2GI",
- "B5S",
- "6XL",
- "EAZ",
- "E6T",
- "T4X",
- "R7O",
- "Q8T",
- "AM5",
- "6SF",
- "FPH",
- "ZOP",
- "609",
- "ZGD",
- "7IH",
- "FAZ",
- "T92",
- "E46",
- "JND",
- "6DA",
- "7HF",
- "1UL",
- "7Z0",
- "3AM",
- "LW3",
- "RPW",
- "4V9",
- "A9W",
- "6BB",
- "R48",
- "AS6",
- "NVX",
- "7GL",
- "R70",
- "H6W",
- "M0Y",
- "3Q4",
- "0FR",
- "SNJ",
- "44X",
- "094",
- "WEJ",
- "F7I",
- "E2F",
- "SRJ",
- "MS9",
- "29A",
- "2X6",
- "2PU",
- "G6T",
- "KEV",
- "KQ7",
- "A4B",
- "S26",
- "AK8",
- "AU8",
- "MW8",
- "T20",
- "3Q3",
- "LHJ",
- "NKJ",
- "RUW",
- "FC8",
- "G4H",
- "3EW",
- "6FB",
- "2RL",
- "SQV",
- "NW1",
- "8XB",
- "D5Q",
- "VNS",
- "QFV",
- "IG3",
- "6CD",
- "WP1",
- "P1E",
- "BW1",
- "OOV",
- "0FN",
- "26Z",
- "ZXH",
- "7X7",
- "PUP",
- "71G",
- "VJZ",
- "K4A",
- "NK0",
- "OV5",
- "J0E",
- "A58",
- "3RC",
- "75H",
- "0TP",
- "CK6",
- "SVH",
- "YT0",
- "X88",
- "RUI",
- "03K",
- "DYQ",
- "55S",
- "GXA",
- "460",
- "AWJ",
- "NTQ",
- "8N2",
- "KHR",
- "OT5",
- "CG5",
- "KJ8",
- "L0C",
- "H2K",
- "VLV",
- "IRD",
- "6T5",
- "3QX",
- "SMY",
- "1BQ",
- "4S2",
- "QMY",
- "IC8",
- "9IK",
- "M0F",
- "YRZ",
- "67U",
- "NM7",
- "XIN",
- "0FY",
- "C9O",
- "0RF",
- "S4E",
- "9I5",
- "6ZK",
- "6HL",
- "KAV",
- "EVR",
- "LAJ",
- "4W1",
- "LCW",
- "0JE",
- "99J",
- "4K7",
- "41B",
- "DF3",
- "2A2",
- "IQ7",
- "G4Y",
- "T7Z",
- "NNN",
- "8E8",
- "8M1",
- "59N",
- "8QK",
- "D6I",
- "Y5G",
- "3R0",
- "3A3",
- "M1O",
- "F8B",
- "BQR",
- "LY2",
- "07R",
- "2W6",
- "3X7",
- "6YE",
- "66K",
- "JSB",
- "LOE",
- "YK1",
- "0WN",
- "0PF",
- "3SC",
- "8OR",
- "F8M",
- "H3E",
- "5XG",
- "504",
- "QKG",
- "304",
- "U0K",
- "4IH",
- "AX7",
- "LCI",
- "Z62",
- "B96",
- "SYP",
- "L20",
- "KES",
- "373",
- "L2V",
- "P79",
- "EVC",
- "91K",
- "734",
- "86H",
- "LI3",
- "E1B",
- "KF4",
- "XIT",
- "X06",
- "1QO",
- "20K",
- "9FV",
- "17V",
- "K9Y",
- "LGX",
- "1J6",
- "01I",
- "4OK",
- "G4N",
- "KLM",
- "3C3",
- "XBJ",
- "G8N",
- "ZZN",
- "45R",
- "746",
- "RXT",
- "18E",
- "T95",
- "LU8",
- "6UM",
- "07C",
- "9K5",
- "B5G",
- "84R",
- "HRA",
- "OOY",
- "C4F",
- "06Z",
- "0SS",
- "FLY",
- "KIN",
- "J4M",
- "ICQ",
- "WKC",
- "WQ6",
- "RJI",
- "KSF",
- "UF4",
- "G92",
- "0X6",
- "LWJ",
- "X03",
- "8PV",
- "A4U",
- "UWZ",
- "E52",
- "OG5",
- "MB9",
- "CT7",
- "XXK",
- "1E8",
- "H5I",
- "T3M",
- "GR9",
- "F3W",
- "DL1",
- "1BU",
- "YM8",
- "PQ5",
- "2I8",
- "919",
- "0FO",
- "RJZ",
- "H99",
- "0LI",
- "X64",
- "6V5",
- "4S1",
- "DTQ",
- "HDU",
- "R3L",
- "9O5",
- "TWH",
- "XM1",
- "LZN",
- "953",
- "AK1",
- "98D",
- "1C7",
- "9Y8",
- "JMM",
- "7KV",
- "90K",
- "CJT",
- "3Q1",
- "P0F",
- "KUY",
- "0F5",
- "OQ8",
- "VX6",
- "1LC",
- "L0F",
- "EMO",
- "SU6",
- "FJI",
- "NKZ",
- "2D2",
- "HHB",
- "324",
- "1O5",
- "K0N",
- "EZQ",
- "ZUQ",
- "QJI",
- "729",
- "5H2",
- "RMX",
- "LB5",
- "Z86",
- "351",
- "3T3",
- "5Z5",
- "889",
- "8ZW",
- "X73",
- "H7U",
- "3NU",
- "L0G",
- "OG8",
- "6BJ",
- "R24",
- "FI4",
- "A",
- "0G1",
- "E63",
- "8BP",
- "J0B",
- "31L",
- "FRV",
- "N8O",
- "VX3",
- "Y3I",
- "STV",
- "JX4",
- "VEK",
- "534",
- "X9F",
- "2K5",
- "G0N",
- "G2G",
- "VXY",
- "5W2",
- "I5S",
- "79C",
- "F92",
- "X07",
- "4DO",
- "AFV",
- "QYE",
- "YOS",
- "1IX",
- "ED8",
- "FP4",
- "NVV",
- "839",
- "0UU",
- "8DW",
- "WAL",
- "9LL",
- "H8K",
- "ZYS",
- "RTX",
- "77C",
- "MUJ",
- "8LY",
- "SVM",
- "FEW",
- "DVO",
- "R0O",
- "GWH",
- "4WG",
- "FAR",
- "BV9",
- "R25",
- "RBQ",
- "40L",
- "8GQ",
- "C5I",
- "7U5",
- "M61",
- "DJ8",
- "W9D",
- "8V4",
- "8PR",
- "QFB",
- "1UO",
- "3U9",
- "3K3",
- "M56",
- "T0L",
- "GK1",
- "7KC",
- "BH9",
- "8N5",
- "ST8",
- "U55",
- "ATP",
- "4T9",
- "BR9",
- "R7S",
- "NKB",
- "FTZ",
- "748",
- "YQY",
- "8DV",
- "3Z4",
- "MR9",
- "ODJ",
- "OFZ",
- "JWY",
- "85V",
- "0XZ",
- "ZZK",
- "WTP",
- "6A6",
- "G7K",
- "1BM",
- "4RV",
- "3S1",
- "20Z",
- "032",
- "584",
- "ZZO",
- "LCB",
- "5JZ",
- "U4W",
- "Z6V",
- "W3N",
- "0C3",
- "Q6W",
- "OS1",
- "HK9",
- "AP9",
- "NF5",
- "PD1",
- "8QB",
- "F8P",
- "5N4",
- "3R1",
- "8UB",
- "HMW",
- "X9I",
- "Q9G",
- "4DK",
- "Y49",
- "OZU",
- "0O7",
- "N61",
- "IDV",
- "6HJ",
- "GQL",
- "I9W",
- "KZQ",
- "DXK",
- "738",
- "QR7",
- "NS9",
- "VGM",
- "N9G",
- "9ZP",
- "Z48",
- "9FC",
- "ZB9",
- "4QX",
- "NRR",
- "O8T",
- "1B4",
- "24R",
- "XEZ",
- "5SF",
- "3Z5",
- "KIM",
- "QDZ",
- "79R",
- "Z92",
- "PXN",
- "LZB",
- "U8P",
- "5JR",
- "7YG",
- "HGW",
- "0WC",
- "Z46",
- "5WF",
- "6G2",
- "N7C",
- "7KW",
- "60B",
- "L7O",
- "QWW",
- "0MX",
- "L7W",
- "5I9",
- "M59",
- "CAQ",
- "J67",
- "6SL",
- "GKB",
- "5QS",
- "TW2",
- "242",
- "634",
- "MRA",
- "9NQ",
- "P48",
- "7CE",
- "9WG",
- "T6Q",
- "8OH",
- "RSI",
- "406",
- "YM3",
- "TFA",
- "UNL",
- "ZQV",
- "W4A",
- "8BM",
- "74Q",
- "9OO",
- "RMM",
- "IIW",
- "O6X",
- "3WH",
- "CQ3",
- "D37",
- "J07",
- "66T",
- "X67",
- "1SB",
- "4DT",
- "BI5",
- "9YY",
- "YA7",
- "80C",
- "ZWE",
- "5HK",
- "A3E",
- "KBM",
- "R09",
- "AQG",
- "8DY",
- "N15",
- "86G",
- "O21",
- "YR7",
- "UM4",
- "E4S",
- "5P6",
- "07S",
- "LZ1",
- "TQA",
- "DZ6",
- "SIX",
- "76Z",
- "74N",
- "ODO",
- "HEW",
- "B4B",
- "HDY",
- "VL1",
- "ZL1",
- "I5R",
- "L7R",
- "1BK",
- "L0N",
- "3TI",
- "L51",
- "RW6",
- "QQC",
- "T75",
- "5NW",
- "7AU",
- "TJW",
- "69Z",
- "KK8",
- "EJS",
- "AU2",
- "4OR",
- "0SJ",
- "2O6",
- "2VT",
- "G7W",
- "2IJ",
- "EDB",
- "6QH",
- "9QK",
- "057",
- "S69",
- "A0X",
- "FXB",
- "517",
- "358",
- "A42",
- "1C8",
- "AX0",
- "OEB",
- "DXH",
- "61E",
- "D0S",
- "862",
- "52P",
- "87B",
- "7MJ",
- "ANP",
- "0WB",
- "5PB",
- "RC8",
- "L1E",
- "4OQ",
- "BIM",
- "VRV",
- "42Q",
- "0ST",
- "495",
- "AQ8",
- "DUK",
- "S3N",
- "RFG",
- "NZ5",
- "EK3",
- "N97",
- "FG9",
- "4CK",
- "ZZG",
- "4RU",
- "F1S",
- "3FV",
- "EJY",
- "0KD",
- "2YK",
- "F82",
- "N0U",
- "287",
- "SL0",
- "FEF",
- "Z0O",
- "AQE",
- "5XJ",
- "OVC",
- "A96",
- "HK4",
- "2VX",
- "10N",
- "8ZQ",
- "KE8",
- "7IK",
- "7TZ",
- "LQQ",
- "H3R",
- "E8V",
- "8ZH",
- "6QY",
- "0YJ",
- "JK1",
- "QIV",
- "X36",
- "76C",
- "GDH",
- "U82",
- "Z6P",
- "F10",
- "RPS",
- "82B",
- "1EL",
- "NB3",
- "XSE",
- "KEX",
- "W3R",
- "A5H",
- "A6W",
- "DFS",
- "1N1",
- "QDE",
- "IHH",
- "AGS",
- "M2B",
- "X9B",
- "L1Z",
- "S4T",
- "7HD",
- "CQ8",
- "X44",
- "1CD",
- "5S8",
- "LBE",
- "H88",
- "ADZ",
- "CDK",
- "6F2",
- "AV9",
- "5QQ",
- "G9B",
- "AFK",
- "GJD",
- "N41",
- "65L",
- "PYZ",
- "OG2",
- "36Q",
- "B9C",
- "R6S",
- "EUN",
- "LVF",
- "0C6",
- "HH5",
- "18K",
- "LZ2",
- "9YV",
- "4P4",
- "74H",
- "YQB",
- "KH8",
- "5H5",
- "SGV",
- "ZIP",
- "A82",
- "Q6K",
- "809",
- "GXK",
- "L1X",
- "BYZ",
- "AJR",
- "V4Z",
- "IC2",
- "X9H",
- "E57",
- "4J7",
- "Q7Z",
- "IB5",
- "EK4",
- "LKG",
- "G4V",
- "AFU",
- "G02",
- "CXS",
- "50Z",
- "5MT",
- "FI3",
- "CT8",
- "EKU",
- "WBT",
- "QFQ",
- "V0G",
- "IZA",
- "RUY",
- "WJV",
- "891",
- "1N6",
- "0CI",
- "9ES",
- "NXP",
- "5Q3",
- "HV2",
- "N7B",
- "0RX",
- "3DV",
- "F0E",
- "HFS",
- "50F",
- "QQ1",
- "63M",
- "OFW",
- "0JK",
- "6GY",
- "39Z",
- "QIH",
- "647",
- "CJM",
- "WGK",
- "3FX",
- "2HK",
- "97B",
- "ZYR",
- "XYW",
- "279",
- "NHJ",
- "U32",
- "SB4",
- "0O8",
- "QAR",
- "SU1",
- "JZO",
- "AUG",
- "D94",
- "41A",
- "H8Z",
- "6V3",
- "1AO",
- "3D3",
- "WPH",
- "C1V",
- "QMV",
- "0K1",
- "1RA",
- "EDH",
- "JHW",
- "NVB",
- "3WR",
- "CVY",
- "CIG",
- "8FY",
- "H7K",
- "I47",
- "R6P",
- "5X1",
- "N78",
- "SN4",
- "S91",
- "6UF",
- "6K4",
- "WNK",
- "29Y",
- "OL2",
- "S9A",
- "EXF",
- "0OO",
- "ZFS",
- "QRR",
- "5Y7",
- "65R",
- "7GI",
- "6AE",
- "4LO",
- "JK3",
- "D4Z",
- "HOW",
- "50D",
- "WQK",
- "OJL",
- "052",
- "BI3",
- "T0X",
- "L6A",
- "RU9",
- "76A",
- "0KF",
- "63E",
- "16W",
- "D42",
- "0OK",
- "F4N",
- "LC0",
- "47W",
- "CK8",
- "900",
- "EK2",
- "ZZL",
- "G8B",
- "KI7",
- "10K",
- "SKI",
- "C0N",
- "4HZ",
- "2TT",
- "G1W",
- "HHW",
- "TZ1",
- "2WK",
- "EGJ",
- "VO7",
- "4Y0",
- "VSF",
- "72B",
- "7G7",
- "MIH",
- "R61",
- "45B",
- "VSY",
- "LHL",
- "A98",
- "WTJ",
- "G0E",
- "OWN",
- "13L",
- "ODH",
- "2WE",
- "306",
- "W47",
- "SW5",
- "RI8",
- "EQW",
- "A1K",
- "CQU",
- "6S1",
- "4QE",
- "K9T",
- "QYK",
- "C07",
- "ZO6",
- "F88",
- "YRA",
- "A28",
- "OD1",
- "9YQ",
- "KSR",
- "6CB",
- "N5U",
- "FGF",
- "4WD",
- "3E8",
- "63A",
- "MS7",
- "IEO",
- "HBM",
- "DFN",
- "X8D",
- "AY4",
- "9YE",
- "B8L",
- "KZL",
- "3Z6",
- "S22",
- "19P",
- "X20",
- "KGZ",
- "VFS",
- "B4W",
- "4VF",
- "46K",
- "8X7",
- "LN4",
- "15T",
- "XV0",
- "7X8",
- "048",
- "GW8",
- "WG1",
- "HOK",
- "3O0",
- "TIY",
- "YTX",
- "LIB",
- "BI4",
- "AK5",
- "SJL",
- "3C9",
- "CWT",
- "CCX",
- "MH4",
- "KHE",
- "MK2",
- "03Z",
- "8IL",
- "934",
- "OD4",
- "TBN",
- "79O",
- "YM7",
- "LZM",
- "633",
- "8EN",
- "3T8",
- "O8Q",
- "KHC",
- "0F9",
- "01P",
- "S8W",
- "VEN",
- "WGF",
- "3O4",
- "R0N",
- "A4N",
- "50Y",
- "TK5",
- "KQK",
- "N3F",
- "EKH",
- "XFE",
- "92P",
- "FHX",
- "1Y6",
- "XK9",
- "HB9",
- "NJV",
- "YFV",
- "9IV",
- "2NQ",
- "V81",
- "FMK",
- "X96",
- "MWL",
- "KF1",
- "9HB",
- "3HN",
- "SC9",
- "SAV",
- "0JH",
- "SCJ",
- "JL2",
- "LS4",
- "T8L",
- "9Z2",
- "04L",
- "6P6",
- "T3E",
- "QD2",
- "LO8",
- "349",
- "R78",
- "DUI",
- "RQ9",
- "422",
- "SLY",
- "LNH",
- "07U",
- "SQP",
- "F87",
- "G4W",
- "KZM",
- "F6J",
- "Q8B",
- "DKG",
- "80E",
- "FZ5",
- "N1A",
- "LZ4",
- "Z20",
- "ML8",
- "3RA",
- "G97",
- "J30",
- "SW7",
- "TO7",
- "3OV",
- "73Q",
- "3OK",
- "BXM",
- "Y7W",
- "537",
- "QM2",
- "DRG",
- "L8I",
- "A5Q",
- "F18",
- "X0A",
- "22Z",
- "6Q1",
- "F46",
- "QL7",
- "34W",
- "6A7",
- "3DX",
- "79D",
- "4K4",
- "6VK",
- "88O",
- "AUH",
- "W8U",
- "A3F",
- "F4C",
- "RVQ",
- "UGX",
- "LPZ",
- "4KT",
- "4MH",
- "AYS",
- "3YT",
- "ESJ",
- "3RT",
- "Q8K",
- "ZLE",
- "EG7",
- "HKQ",
- "1M3",
- "SD5",
- "1PP",
- "HKI",
- "M5W",
- "SWK",
- "21O",
- "207",
- "A9E",
- "U6S",
- "XY3",
- "AAK",
- "JRE",
- "SNB",
- "19Q",
- "8GV",
- "6NB",
- "519",
- "0U0",
- "91X",
- "2C4",
- "WQ2",
- "3DC",
- "9WU",
- "54F",
- "IQY",
- "R2S",
- "1G0",
- "BGE",
- "KZI",
- "AIZ",
- "70T",
- "PP2",
- "BD4",
- "LZ9",
- "IRG",
- "ABQ",
- "2WC",
- "FS9",
- "9Z4",
- "39P",
- "38G",
- "ERZ",
- "G6J",
- "KWP",
- "1DT",
- "0WH",
- "C5W",
- "OL8",
- "YCF",
- "1HW",
- "UES",
- "5E5",
- "FH5",
- "UEX",
- "F3Z",
- "Y3O",
- "N7K",
- "D05",
- "3V0",
- "03P",
- "S4Z",
- "0NT",
- "5WE",
- "LXX",
- "KRL",
- "QRD",
- "LZ3",
- "6PV",
- "SB2",
- "1N3",
- "BI2",
- "SV5",
- "UPX",
- "N6Z",
- "DF2",
- "4DL",
- "38R",
- "62E",
- "C9Z",
- "3UR",
- "3ZC",
- "HQB",
- "LI4",
- "9WS",
- "55E",
- "CJQ",
- "V04",
- "9OF",
- "FJ0",
- "4KA",
- "86L",
- "8KF",
- "ZXP",
- "09H",
- "WEG",
- "8TN",
- "J4B",
- "LJF",
- "73T",
- "QXZ",
- "SCQ",
- "0JL",
- "A6H",
- "ZYQ",
- "6U1",
- "1LT",
- "BYL",
- "LYG",
- "5B4",
- "CK5",
- "P06",
- "7CU",
- "3FF",
- "HMD",
- "SVJ",
- "J27",
- "JWN",
- "OFG",
- "CG9",
- "507",
- "PBU",
- "M4P",
- "YY9",
- "RGY",
- "SU7",
- "JK2",
- "58C",
- "G62",
- "7TW",
- "0XF",
- "42P",
- "N92",
- "400",
- "A9B",
- "F8S",
- "G5X",
- "8DK",
- "VRU",
- "XIP",
- "G6I",
- "3FN",
- "42I",
- "34L",
- "8R7",
- "ZO8",
- "J60",
- "XI2",
- "0WR",
- "S4K",
- "99K",
- "JZY",
- "H96",
- "OFT",
- "W2P",
- "RV6",
- "WJ9",
- "NBS",
- "IH7",
- "EU4",
- "0SY",
- "JZW",
- "YFY",
- "C5N",
- "589",
- "C1I",
- "7XH",
- "21I",
- "C73",
- "2HV",
- "H3N",
- "68R",
- "KWT",
- "XWA",
- "0J9",
- "044",
- "66A",
- "LVD",
- "VZJ",
- "32W",
- "1P5",
- "VVT",
- "CKO",
- "IIM",
- "SMV",
- "TQ1",
- "W19",
- "FCP",
- "3NG",
- "OKZ",
- "50W",
- "FQD",
- "DWT",
- "466",
- "55U",
- "S0L",
- "ABJ",
- "LH0",
- "9XO",
- "G6A",
- "4L6",
- "G54",
- "O4B",
- "P9K",
- "D4Q",
- "84P",
- "N42",
- "LCD",
- "H0K",
- "5W3",
- "5Y4",
- "50E",
- "LKQ",
- "5KW",
- "0NF",
- "ANK",
- "5SC",
- "SVE",
- "KF6",
- "GS3",
- "XA0",
- "0BQ",
- "JBI",
- "A7N",
- "YY3",
- "4QG",
- "O92",
- "H3Q",
- "83P",
- "RW4",
- "O2K",
- "R2E",
- "P7C",
- "8LU",
- "UNE",
- "KWY",
- "HGK",
- "34U",
- "SM9",
- "IWU",
- "K82",
- "RW3",
- "X11",
- "IE0",
- "63K",
- "SSY",
- "63I",
- "75E",
- "E62",
- "KCI",
- "X9G",
- "6T3",
- "F62",
- "292",
- "NYX",
- "FVC",
- "27D",
- "4H5",
- "8QZ",
- "4EF",
- "A06",
- "PDX",
- "WCX",
- "337",
- "50J",
- "LBB",
- "WXQ",
- "VM1",
- "925",
- "HB4",
- "9I8",
- "O4U",
- "AY7",
- "RKW",
- "7AA",
- "LIF",
- "1IM",
- "JYZ",
- "45Q",
- "6Z5",
- "JWE",
- "A53",
- "5O4",
- "PWU",
- "SNV",
- "SQ8",
- "WF7",
- "U0C",
- "2TA",
- "G5T",
- "MDI",
- "09J",
- "ET8",
- "8DJ",
- "LI2",
- "7LV",
- "KSM",
- "AK2",
- "49J",
- "KY9",
- "F0H",
- "5TL",
- "91L",
- "86C",
- "TCE",
- "RQS",
- "K3R",
- "3WA",
- "OQ2",
- "R4S",
- "CQE",
- "RR9",
- "X8E",
- "X3W",
- "1JX",
- "XK3",
- "EKT",
- "A7H",
- "NPZ",
- "EFP",
- "6U7",
- "9YS",
- "8FU",
- "X46",
- "8QH",
- "6TE",
- "G5C",
- "ADP",
- "AM7",
- "IGV",
- "9N8",
- "4HW",
- "3IU",
- "B4K",
- "XTT",
- "3I7",
- "5B1",
- "0T2",
- "1P6",
- "PZW",
- "8R4",
- "PZO",
- "XL8",
- "J88",
- "I6P",
- "VSH",
- "6TP",
- "NZ4",
- "7O3",
- "8N8",
- "AJK",
- "N1Q",
- "5W8",
- "5U3",
- "KXY",
- "PJC",
- "P4N",
- "BYU",
- "50O",
- "PG0",
- "5O7",
- "OKO",
- "ESK",
- "FMY",
- "N96",
- "1K3",
- "05B",
- "P38",
- "107",
- "6XT",
- "12C",
- "JZJ",
- "DJW",
- "5E6",
- "RTJ",
- "C92",
- "DT4",
- "BA0",
- "NM8",
- "PMU",
- "X9P",
- "31X",
- "RSU",
- "VS0",
- "1BR",
- "7L0",
- "A9T",
- "093",
- "P7N",
- "N3X",
- "IV7",
- "AUE",
- "981",
- "FYV",
- "X3R",
- "LTJ",
- "TZ0",
- "B8Z",
- "K1H",
- "HRM",
- "84M",
- "9TO",
- "R6M",
- "3LH",
- "K8K",
- "11K",
- "92J",
- "8NZ",
- "J0P",
- "65U",
- "N1J",
- "3SM",
- "A4Q",
- "VOY",
- "EO5",
- "NJ6",
- "FMD",
- "ZW3",
- "5R1",
- "24V",
- "KK7",
- "08Z",
- "6OJ",
- "P40",
- "UGK",
- "G4K",
- "85S",
- "PFY",
- "BRY",
- "C9R",
- "XXF",
- "IR1",
- "HJ9",
- "1SK",
- "M5V",
- "6ZF",
- "1E0",
- "V62",
- "831",
- "61U",
- "LD5",
- "ZRM",
- "WXH",
- "HBD",
- "F9N",
- "QX2",
- "WZ8",
- "EMU",
- "8CG",
- "54R",
- "B6I",
- "F48",
- "NQ1",
- "19E",
- "HHQ",
- "XTI",
- "8D6",
- "6S3",
- "6SH",
- "80H",
- "1DR",
- "9DB",
- "F8Z",
- "DG7",
- "LO5",
- "AWO",
- "6SN",
- "N5B",
- "N6N",
- "8ST",
- "Q7Q",
- "VK2",
- "YDJ",
- "LXG",
- "Q7M",
- "0WP",
- "IE4",
- "FKY",
- "N9F",
- "LGV",
- "7GS",
- "E2L",
- "S19",
- "6HF",
- "9EM",
- "W40",
- "L87",
- "1RO",
- "RQU",
- "H3K",
- "RLC",
- "3HQ",
- "B97",
- "L0P",
- "P5O",
- "OO7",
- "49B",
- "7GZ",
- "P9J",
- "H9K",
- "GUK",
- "D31",
- "UUF",
- "0JG",
- "LN3",
- "O0H",
- "IXM",
- "J2Y",
- "0K6",
- "DHC",
- "CV4",
- "3KZ",
- "HUL",
- "7X1",
- "MFZ",
- "7X6",
- "AQT",
- "N29",
- "0XP",
- "98A",
- "1QG",
- "WG8",
- "34Y",
- "7PY",
- "1B5",
- "46G",
- "6UJ",
- "KQE",
- "4VC",
- "GX3",
- "X65",
- "GS2",
- "0G3",
- "FMW",
- "C0M",
- "740",
- "B5Z",
- "CQW",
- "A5W",
- "90T",
- "HO8",
- "XUZ",
- "GJ7",
- "LB8",
- "980",
- "3EH",
- "276",
- "7GY",
- "6SD",
- "816",
- "N9J",
- "GDW",
- "7KG",
- "1OB",
- "1RS",
- "D1A",
- "03Q",
- "GOD",
- "ATK",
- "ER8",
- "2VL",
- "96M",
- "KQZ",
- "R7B",
- "T1L",
- "8QT",
- "LZA",
- "DT5",
- "I1P",
- "5O1",
- "JZX",
- "8OU",
- "LSV",
- "F1B",
- "QGY",
- "XKU",
- "IDW",
- "Z87",
- "RK2",
- "7IF",
- "ZTV",
- "1QN",
- "CIY",
- "OBY",
- "AY3",
- "4TW",
- "FLS",
- "KHD",
- "54S",
- "2K2",
- "8ZK",
- "5LK",
- "994",
- "HJK",
- "18Z",
- "Y8H",
- "VVX",
- "IJB",
- "1GK",
- "WPB",
- "JHK",
- "K81",
- "6ZZ",
- "6U2",
- "0S9",
- "D7D",
- "2VU",
- "WPX",
- "DTJ",
- "R6N",
- "N82",
- "1PU",
- "R0T",
- "A03",
- "7IQ",
- "FAV",
- "O97",
- "G41",
- "W9X",
- "EFQ",
- "533",
- "LCQ",
- "31K",
- "GDK",
- "SLQ",
- "3VD",
- "6VM",
- "1NX",
- "X3Y",
- "RNU",
- "R5Y",
- "BRK",
- "QGR",
- "0BY",
- "KFD",
- "VY1",
- "5RC",
- "530",
- "QJZ",
- "HSJ",
- "B6Q",
- "YEX",
- "PFQ",
- "SVD",
- "57N",
- "046",
- "90Z",
- "46A",
- "R7P",
- "JVE",
- "3HJ",
- "TSK",
- "1J4",
- "A5E",
- "4T3",
- "1KP",
- "X7Y",
- "B4Q",
- "477",
- "KKR",
- "TSW",
- "7XR",
- "17G",
- "X87",
- "Z60",
- "HKC",
- "JVT",
- "KA2",
- "74O",
- "KMP",
- "19S",
- "G98",
- "FZO",
- "F97",
- "EYQ",
- "I5G",
- "SJV",
- "0TB",
- "XWW",
- "1J3",
- "AWX",
- "OXW",
- "ZS3",
- "RQL",
- "1BJ",
- "6RG",
- "8XK",
- "M4I",
- "L1W",
- "0YO",
- "N9L",
- "4EL",
- "GYW",
- "6UE",
- "B4V",
- "T12",
- "4CW",
- "X3G",
- "MT4",
- "83H",
- "JPZ",
- "74F",
- "QH9",
- "AEQ",
- "H7R",
- "9JS",
- "B6H",
- "LW4",
- "937",
- "8MQ",
- "LX9",
- "79Q",
- "9QT",
- "0US",
- "F4B",
- "I85",
- "QYW",
- "0WA",
- "199",
- "3VC",
- "KSC",
- "4L7",
- "6XP",
- "799",
- "KZP",
- "MPZ",
- "LUE",
- "O9C",
- "4RK",
- "3QW",
- "0F0",
- "QT9",
- "UIK",
- "0OA",
- "XVI",
- "HVY",
- "V5W",
- "6CP",
- "SR4",
- "Z2M",
- "QY2",
- "FKT",
- "0S8",
- "6K2",
- "K1B",
- "6R0",
- "N3O",
- "6HK",
- "AOW",
- "4GF",
- "JRT",
- "82A",
- "3JB",
- "6YN",
- "3SB",
- "MFP",
- "1AU",
- "E0P",
- "9ZB",
- "456",
- "IQO",
- "VQE",
- "OND",
- "NX0",
- "844",
- "5N3",
- "VBS",
- "5WR",
- "EK6",
- "S03",
- "62K",
- "MFE",
- "LQ5",
- "OLO",
- "4E2",
- "YM5",
- "DKI",
- "L0D",
- "A4T",
- "CG7",
- "WTI",
- "JQW",
- "X2M",
- "UN4",
- "1N9",
- "RJ5",
- "70W",
- "91O",
- "FCQ",
- "EAQ",
- "CK2",
- "IHX",
- "2TR",
- "ELZ",
- "CK4",
- "1FN",
- "8IW",
- "0NR",
- "7AJ",
- "AHK",
- "USF",
- "MI5",
- "KSE",
- "039",
- "7X3",
- "8V7",
- "5PW",
- "LOT",
- "4VZ",
- "SOJ",
- "GVP",
- "37O",
- "6N9",
- "308",
- "E2C",
- "S4R",
- "BPK",
- "QTX",
- "UJC",
- "JVP",
- "ZIG",
- "V5J",
- "2WF",
- "QCT",
- "QC0",
- "JNF",
- "PHU",
- "QFE",
- "EX4",
- "8XE",
- "X9S",
- "55Y",
- "TAK",
- "ITI",
- "VSE",
- "AWR",
- "H1N",
- "F47",
- "5QO",
- "0SE",
- "JGM",
- "IRB",
- "FKN",
- "0VE",
- "B5W",
- "HGQ",
- "YK7",
- "B7W",
- "U73",
- "FE5",
- "G4T",
- "1PF",
- "O17",
- "CHU",
- "0JF",
- "X75",
- "2V1",
- "3UL",
- "ZZQ",
- "48B",
- "U4N",
- "2YE",
- "LTI",
- "NQ5",
- "YB4",
- "MVS",
- "HY7",
- "BWY",
- "N8L",
- "FU9",
- "JYG",
- "RXQ",
- "O1K",
- "TZY",
- "0EI",
- "AVK",
- "04K",
- "583",
- "573",
- "FKB",
- "QBE",
- "T77",
- "4DN",
- "RI9",
- "KJ7",
- "Q7K",
- "M8Z",
- "NKW",
- "N4U",
- "VTA",
- "3K7",
- "HDT",
- "GJJ",
- "FZC",
- "4DQ",
- "3FE",
- "GIG",
- "1VI",
- "NB5",
- "F4J",
- "1M8",
- "X5E",
- "X3K",
- "4TT",
- "4QZ",
- "V5T",
- "HH8",
- "3I6",
- "106",
- "I46",
- "72L",
- "YFS",
- "2IE",
- "F9J",
- "35R",
- "FWU",
- "3Z1",
- "MT8",
- "7XO",
- "UO5",
- "5EZ",
- "A25",
- "PQA",
- "9OL",
- "Q8Q",
- "VY4",
- "992",
- "6K5",
- "971",
- "B90",
- "4VG",
- "4AU",
- "A9U",
- "FPX",
- "Z83",
- "M5D",
- "ULV",
- "UE9",
- "HK1",
- "G7T",
- "571",
- "WT3",
- "5L4",
- "B7B",
- "AM8",
- "GUI",
- "HCK",
- "KEC",
- "9DP",
- "SMR",
- "Z0W",
- "8CD",
- "AWN",
- "G0U",
- "XGQ",
- "0OL",
- "JN5",
- "1PH",
- "EK5",
- "FZP",
- "D1E",
- "7A7",
- "85X",
- "IK1",
- "XIZ",
- "H7X",
- "60E",
- "AQ5",
- "NTW",
- "2NK",
- "4TV",
- "9YZ",
- "U0N",
- "G11",
- "PQ8",
- "UQX",
- "A0T",
- "B2D",
- "DQX",
- "H72",
- "FZF",
- "8RH",
- "BFK",
- "O10",
- "EK0",
- "T28",
- "EWH",
- "M57",
- "OLP",
- "E26",
- "E2U",
- "J87",
- "QIA",
- "YVQ",
- "55F",
- "AK3",
- "8ON",
- "MVG",
- "EE4",
- "6TT",
- "X63",
- "AFW",
- "D6Z",
- "J2I",
- "40M",
- "2JZ",
- "DJK",
- "8ZN",
- "FMM",
- "SJM",
- "A7O",
- "M77",
- "UAU",
- "RYW",
- "37W",
- "EUI",
- "Q8J",
- "R6K",
- "9WX",
- "45K",
- "P3Y",
- "A3W",
- "1UH",
- "1N8",
- "0JA",
- "SJJ",
- "90N",
- "99M",
- "26D",
- "6YL",
- "VQP",
- "X3N",
- "VAR",
- "FQG",
- "42J",
- "C95",
- "S25",
- "LS5",
- "A5K",
- "S59",
- "FJY",
- "54P",
- "LUN",
- "GAB",
- "F7D",
- "X37",
- "I19",
- "7G8",
- "H83",
- "8WH",
- "P7A",
- "WFD",
- "RQ5",
- "5B2",
- "CMG",
- "SV4",
- "Z0B",
- "QS0",
- "Z3R",
- "71N",
- "JU8",
- "RKZ",
- "S93",
- "O06",
- "CVQ",
- "4L5",
- "RCM",
- "2CH",
- "Z85",
- "SR8",
- "T9N",
- "3RF",
- "6K0",
- "L7A",
- "RVU",
- "QYH",
- "4ZH",
- "0RS",
- "YUN",
- "RK5",
- "JWQ",
- "SWM",
- "JRW",
- "0SU",
- "03X",
- "SJ0",
- "DF6",
- "5VS",
- "575",
- "I73",
- "69C",
- "LXS",
- "3WO",
- "H6K",
- "IS4",
- "3T9",
- "2SB",
- "HK7",
- "6SO",
- "NKT",
- "QYB",
- "TXQ",
- "KSA",
- "0SR",
- "8TK",
- "EVL",
- "X59",
- "OAW",
- "S30",
- "2WI",
- "4YW",
- "JWS",
- "OFQ",
- "FQJ",
- "SZL",
- "EAE",
- "WAZ",
- "DFQ",
- "XJ1",
- "4GD",
- "A9K",
- "JUW",
- "XIJ",
- "PM1",
- "U0Q",
- "BYP",
- "O8Z",
- "ALH",
- "LS1",
- "REB",
- "0YH",
- "8GY",
- "D58",
- "P2V",
- "31J",
- "Z31",
- "RWE",
- "VTD",
- "KAO",
- "25Z",
- "8BH",
- "0UN",
- "3P6",
- "L5G",
- "SQZ",
- "BWI",
- "O2H",
- "631",
- "T3X",
- "8O8",
- "4ZQ",
- "8X5",
- "P39",
- "JMB",
- "N6K",
- "B18",
- "WIQ",
- "SCF",
- "09Z",
- "B7S",
- "LS7",
- "FZR",
- "NYI",
- "DXV",
- "AXI",
- "SOV",
- "U9P",
- "3D8",
- "JUP",
- "UNM",
- "GO7",
- "OYB",
- "2HX",
- "E9Z",
- "AGX",
- "MYC",
- "FPZ",
- "56Z",
- "3CI",
- "HK8",
- "5CN",
- "X8I",
- "16K",
- "MK9",
- "0SB",
- "RHT",
- "GS7",
- "PP1",
- "09K",
- "664",
- "60D",
- "6LF",
- "4VB",
- "0J3",
- "KXZ",
- "J9G",
- "MRI",
- "4K0",
- "8ZF",
- "3D9",
- "EM7",
- "GC6",
- "8KQ",
- "9E1",
- "3IF",
- "E94",
- "9IO",
- "ZZF",
- "N8U",
- "ES4",
- "G68",
- "89E",
- "L0I",
- "15G",
- "GVD",
- "KEJ",
- "NIO",
- "08G",
- "0W7",
- "YDA",
- "Y8C",
- "5FI",
- "XU1",
- "Z19",
- "WCJ",
- "LCT",
- "T74",
- "DI1",
- "7FM",
- "L1H",
- "386",
- "76Y",
- "8QW",
- "HHN",
- "T6E",
- "1YG",
- "5BP",
- "B6E",
- "9O2",
- "S5M",
- "SCZ",
- "7KA",
- "98M",
- "7LY",
- "VVQ",
- "7X2",
- "TOJ",
- "STJ",
- "8BV",
- "J19",
- "1F8",
- "ZZY",
- "XIX",
- "2QK",
- "OOD",
- "ERK",
- "LCJ",
- "1C9",
- "KVJ",
- "O9L",
- "MK3",
- "LKB",
- "N7Z",
- "EZR",
- "SUU",
- "Z63",
- "E86",
- "AA0",
- "FRZ",
- "YY5",
- "3D7",
- "0H2",
- "7FC",
- "VWN",
- "ZYW",
- "S4N",
- "3SG",
- "SX8",
- "KBI",
- "EKK",
- "4KK",
- "ELW",
- "06F",
- "51W",
- "3XM",
- "WAK",
- "5QI",
- "BI8",
- "9I2",
- "1FV",
- "7VH",
- "5LS",
- "G4Q",
- "585",
- "43A",
- "OCJ",
- "W5W",
- "1OA",
- "NG2",
- "GD5",
- "HPP",
- "XHS",
- "3RH",
- "6MV",
- "3I3",
- "B4Y",
- "KGL",
- "E71",
- "31V",
- "3RE",
- "71A",
- "EK7",
- "2VV",
- "NHI",
- "B91",
- "7LK",
- "I90",
- "SU9",
- "IHZ",
- "2A8",
- "984",
- "IE6",
- "EMH",
- "J3Y",
- "H80",
- "XQQ",
- "VFB",
- "A17",
- "8FR",
- "ADN",
- "KH5",
- "K0X",
- "W2T",
- "X02",
- "FDH",
- "AU5",
- "F6M",
- "SVT",
- "OHK",
- "ZGY",
- "1H4",
- "330",
- "YMX",
- "RH8",
- "T1Q",
- "9E4",
- "4PV",
- "2K7",
- "VX1",
- "92M",
- "00J",
- "AQZ",
- "Q1A",
- "AOK",
- "YSO",
- "255",
- "9J4",
- "VX2",
- "1KO",
- "5WH",
- "RKK",
- "AK4",
- "9X4",
- "FL4",
- "QQJ",
- "PE5",
- "DVD",
- "2OL",
- "AA2",
- "RF4",
- "X4B",
- "8H0",
- "LID",
- "VJH",
- "L1N",
- "4YK",
- "SM5",
- "BJG",
- "93J",
- "6SC",
- "MM8",
- "DY4",
- "N83",
- "RWN",
- "4EJ",
- "EML",
- "G0Q",
- "HO5",
- "2VW",
- "626",
- "GJA",
- "A3H",
- "6J9",
- "Z8O",
- "QYZ",
- "BX1",
- "793",
- "2WG",
- "XL7",
- "887",
- "AQW",
- "CZ4",
- "P08",
- "43R",
- "8MY",
- "BMI",
- "EZE",
- "K06",
- "G8H",
- "0X5",
- "29X",
- "371",
- "E2X",
- "4HK",
- "A8K",
- "3Z3",
- "X9J",
- "C58",
- "2KC",
- "5T2",
- "J99",
- "99V",
- "AKI",
- "E0M",
- "8GX",
- "Q55",
- "SQE",
- "UOW",
- "X9V",
- "551",
- "HAU",
- "DWF",
- "X6A",
- "STI",
- "RU5",
- "PGJ",
- "BAX",
- "VYN",
- "QAQ",
- "HKJ",
- "36O",
- "H4N",
- "553",
- "33A",
- "56H",
- "4F6",
- "QP1",
- "3NE",
- "ABO",
- "ANW",
- "XU2",
- "C6O",
- "7RO",
- "PQC",
- "0R4",
- "893",
- "9HP",
- "9EJ",
- "FRT",
- "B9K",
- "ZRU",
- "19B",
- "3JA",
- "2I5",
- "B6B",
- "3NL",
- "F8R",
- "95U",
- "QWS",
- "LJE",
- "V0K",
- "4VJ",
- "4ZR",
- "SVG",
- "A0Q",
- "QZW",
- "ROY",
- "1WS",
- "WGZ",
- "1RU",
- "5Y3",
- "QOP",
- "B8I",
- "GO4",
- "LM3",
- "3RL",
- "P17",
- "0T8",
- "HGF",
- "XR1",
- "0SD",
- "C62",
- "24K",
- "Z14",
- "YIQ",
- "GJK",
- "CC9",
- "PDY",
- "UP9",
- "YNZ",
- "RXN",
- "OE8",
- "BMU",
- "LGF",
- "0UV",
- "RKN",
- "JAK",
- "6L4",
- "OBW",
- "3L0",
- "KRE",
- "42C",
- "OVI",
- "ESQ",
- "B6Z",
- "A6X",
- "K47",
- "9JO",
- "MYF",
- "JNK",
- "UCN",
- "R05",
- "EQH",
- "LWG",
- "GG5",
- "824",
- "3OU",
- "HPM",
- "3O7",
- "AG1",
- "CQO",
- "8PT",
- "MBW",
- "LG8",
- "EZB",
- "RJ2",
- "MWU",
- "EXZ",
- "4YX",
- "FXG",
- "T3I",
- "LZ8",
- "I3H",
- "REF",
- "4V8",
- "Q0B",
- "NL4",
- "G96",
- "6TD",
- "07Q",
- "P41",
- "2IX",
- "4UB",
- "BMW",
- "AEE",
- "STL",
- "WVI",
- "9BD",
- "3UO",
- "XHV",
- "MBP",
- "KA4",
- "RQZ",
- "RQE",
- "U3E",
- "2V9",
- "17P",
- "IBI",
- "RTZ",
- "H7O",
- "Q58",
- "LZD",
- "8H1",
- "DQ4",
- "HNZ",
- "90F",
- "G9E",
- "RQQ",
- "D1D",
- "K0Z",
- "L1G",
- "1AM",
- "48K",
- "5B3",
- "DJQ",
- "9NX",
- "P5C",
- "3H8",
- "939",
- "HOT",
- "V0L",
- "I45",
- "QRW",
- "KJB",
- "ADE",
- "X84",
- "E1D",
- "ZYT",
- "N7W",
- "V6B",
- "2P5",
- "IZZ",
- "61K",
- "SKE",
- "SJX",
- "39G",
- "91H",
- "1RQ",
- "OXM",
- "90E",
- "8C5",
- "Y56",
- "IKD",
- "H5K",
- "70S",
- "4ZJ",
- "8MB",
- "7XW",
- "1OO",
- "Q5Z",
- "O1S",
- "YT8",
- "1Q4",
- "67T",
- "L8V",
- "QUF",
- "6GD",
- "GK6",
- "G3B",
- "MFQ",
- "55M",
- "5I1",
- "7YS",
- "KD6",
- "4LY",
- "A3Q",
- "0NV",
- "5P8",
- "RG4",
- "PP0",
- "5BE",
- "65A",
- "SB5",
- "0S7",
- "P3J",
- "VEQ",
- "T2F",
- "1OC",
- "1LB",
- "FNI",
- "1IF",
- "0NU",
- "9ID",
- "PQB",
- "6XK",
- "NKE",
- "960",
- "2OO",
- "4GU",
- "L0E",
- "7UX",
- "DJH",
- "CC3",
- "8MT",
- "ZYU",
- "W49",
- "7QU",
- "RFZ",
- "OU2",
- "N76",
- "N9Z",
- "499",
- "ZC3",
- "O8W",
- "QP4",
- "NZF",
- "V1Y",
- "1IZ",
- "LB7",
- "Z84",
- "AQY",
- "M0Z",
- "KWV",
- "XA4",
- "6XE",
- "B11",
- "TL7",
- "IAQ",
- "INR",
- "KJV",
- "SB0",
- "YIT",
- "9KI",
- "D36",
- "STU",
- "3NV",
- "UNQ",
- "SJS",
- "YDK",
- "Q98",
- "EX6",
- "Z02",
- "47I",
- "3FP",
- "1WU",
- "81C",
- "4ZG",
- "0BX",
- "6ZV",
- "4Z5",
- "OW6",
- "7KU",
- "4SP",
- "W32",
- "R6D",
- "6Z7",
- "PPI",
- "CT9",
- "GK5",
- "LEV",
- "6BE",
- "8Q5",
- "AM6",
- "0ON",
- "2A6",
- "AQ2",
- "FKO",
- "RAJ",
- "L9A",
- "RRC",
- "5JA",
- "50V",
- "IHP",
- "N5R",
- "W3I",
- "P91",
- "MMD",
- "AUW",
- "AWE",
- "S9K",
- "0O9",
- "W9Z",
- "G0H",
- "FYW",
- "SQB",
- "YTP",
- "A0H",
- "R7W",
- "6LQ",
- "XBD",
- "90B",
- "7MY",
- "3WK",
- "O35",
- "KRW",
- "O1V",
- "X62",
- "4RB",
- "A5G",
- "OPW",
- "0G2",
- "2NS",
- "3QY",
- "LS3",
- "X42",
- "0UW",
- "OV0",
- "G95",
- "1QK",
- "2WH",
- "59T",
- "TWK",
- "66P",
- "NRM",
- "320",
- "U8J",
- "T6X",
- "SW8",
- "FZW",
- "PRC",
- "QY8",
- "3QT",
- "JAU",
- "IYZ",
- "SQQ",
- "QQM",
- "IED",
- "3YY",
- "0TA",
- "4KH",
- "BEZ",
- "NY0",
- "PCG",
- "YDI",
- "C94",
- "R39",
- "T4O",
- "ZS4",
- "VRM",
- "GMG",
- "7X4",
- "4DJ",
- "9M3",
- "R6I",
- "ERW",
- "OE5",
- "RUT",
- "V58",
- "OH8",
- "6BZ",
- "Q6E",
- "X43",
- "X9M",
- "QEW",
- "2AN",
- "4WE",
- "3O8",
- "58V",
- "OD2",
- "IER",
- "LZ7",
- "KRK",
- "6K1",
- "GIN",
- "XL9",
- "W3C",
- "6E2",
- "3GU",
- "X5G",
- "0VM",
- "FBL",
- "X35",
- "YIY",
- "3OA",
- "ZAT",
- "4E1",
- "75X",
- "UX2",
- "QCR",
- "RCH",
- "FMJ",
- "DD8",
- "C9U",
- "IGJ",
- "OOO",
- "NZS",
- "X1N",
- "X76",
- "4R0",
- "FCZ",
- "ESW",
- "QUU",
- "GFJ",
- "O1Y",
- "1ST",
- "B10",
- "JWK",
- "0NL",
- "5I4",
- "084",
- "0F2",
- "NZ8",
- "GMW",
- "E3U",
- "3IP",
- "FYH",
- "E7M",
- "KQW",
- "6QX",
- "N4N",
- "81G",
- "9ZS",
- "L66",
- "6JS",
- "H3H",
- "6DP",
- "K3D",
- "E6W",
- "COM",
- "X8G",
- "L0Z",
- "MI1",
- "29B",
- "HJ0",
- "Y3M",
- "0C0",
- "924",
- "QYT",
- "F8E",
- "E78",
- "B98",
- "3Q0",
- "1IW",
- "2AI",
- "22L",
- "3U5",
- "4F2",
- "71L",
- "Z71",
- "34O",
- "LVL",
- "B1L",
- "4LH",
- "U35",
- "XOJ",
- "2V3",
- "3J7",
- "P4G",
- "E8D",
- "GGY",
- "8QE",
- "UWM",
- "FLL",
- "L80",
- "E4V",
- "AJG",
- "OOJ",
- "WAU",
- "YIW",
- "11G",
- "BRW",
- "E5M",
- "O19",
- "0VH",
- "TBS",
- "6UX",
- "HRZ",
- "GK4",
- "ZUO",
- "B7R",
- "YQT",
- "0C4",
- "LKT",
- "529",
- "HGH",
- "35H",
- "041",
- "8KZ",
- "L11",
- "6C3",
- "OSV",
- "E2R",
- "N45",
- "353",
- "XL6",
- "RHH",
- "8C1",
- "AQ6",
- "98G",
- "396",
- "6BU",
- "WBI",
- "EFV",
- "PFO",
- "PDS",
- "M4X",
- "VFA",
- "H91",
- "7XN",
- "3UP",
- "3U6",
- "8RC",
- "25Q",
- "7CP",
- "E75",
- "8XH",
- "R9P",
- "T3B",
- "RKD",
- "ND2",
- "985",
- "KSK",
- "RJ8",
- "UCE",
- "6ZG",
- "KUV",
- "X39",
- "A7X",
- "Q4J",
- "3Q5",
- "BW8",
- "0CE",
- "3XK",
- "710",
- "WHQ",
- "12Z",
- "7G6",
- "KRJ",
- "KWJ",
- "2V2",
- "1QM",
- "R4L",
- "0X2",
- "0UJ",
- "X3A",
- "H7F",
- "HHT",
- "8ZZ",
- "P78",
- "63L",
- "UCM",
- "78L",
- "YM4",
- "GK3",
- "L9S",
- "SLS",
- "63B",
- "UGJ",
- "2K0",
- "Q9J",
- "B4E",
- "27Z",
- "IKC",
- "W3F",
- "SJG",
- "MPY",
- "KSL",
- "IPV",
- "JIN",
- "1J2",
- "PKE",
- "3EL",
- "FAL",
- "9K8",
- "MMW",
- "6QB",
- "VRZ",
- "CQ7",
- "1Q3",
- "B45",
- "8M8",
- "V7Y",
- "I94",
- "608",
- "6R1",
- "BYM",
- "9VV",
- "W4G",
- "CQQ",
- "859",
- "9EO",
- "1FM",
- "7GG",
- "GXH",
- "UUB",
- "RK8",
- "E0S",
- "0BZ",
- "CFK",
- "1SU",
- "DYK",
- "RKQ",
- "8JC",
- "5QM",
- "FAP",
- "D6W",
- "PVT",
- "39I",
- "D23",
- "H82",
- "55J",
- "7KX",
- "HK5",
- "3HT",
- "W2K",
- "BLZ",
- "4US",
- "0J8",
- "IGS",
- "FKL",
- "62M",
- "4YM",
- "S5I",
- "5U6",
- "Y5Y",
- "K8A",
- "741",
- "YPW",
- "NZU",
- "K7S",
- "HB1",
- "MJF",
- "0NH",
- "OSZ",
- "HHL",
- "M5J",
- "GMQ",
- "PY8",
- "MLW",
- "ZHY",
- "H7L",
- "GIK",
- "X72",
- "W3W",
- "42K",
- "1SW",
- "JYM",
- "TMU",
- "L9L",
- "5E1",
- "LZ5",
- "6FD",
- "CWS",
- "I74",
- "KHQ",
- "URW",
- "TL0",
- "5CP",
- "UIM",
- "F76",
- "22K",
- "G5K",
- "IQB",
- "RKH",
- "HK3",
- "LMR",
- "3YR",
- "8MN",
- "V1G",
- "ZXL",
- "GSH",
- "CKK",
- "D5P",
- "O1Z",
- "6UI",
- "MVE",
- "SV8",
- "Y27",
- "XIY",
- "K1E",
- "GV0",
- "64V",
- "FPU",
- "S1Z",
- "OCG",
- "N69",
- "L8Y",
- "H1K",
- "AM9",
- "0VU",
- "5Q2",
- "OWB",
- "J72",
- "KS1",
- "LI9",
- "UWP",
- "VYP",
- "OFI",
- "2Q7",
- "UMN",
- "O98",
- "X4G",
- "085",
- "J82",
- "1B6",
- "VSG",
- "LGW",
- "5W7",
- "P2B",
- "ZSO",
- "03C",
- "A1N",
- "P2X",
- "N7Q",
- "QPP",
- "630",
- "774",
- "PO6",
- "U7E",
- "3KC",
- "F9Z",
- "V84",
- "N20",
- "3K6",
- "ML9",
- "MIX",
- "C70",
- "5T1",
- "MXE",
- "3WJ",
- "RQT",
- "933",
- "2SH",
- "PGF",
- "AN2",
- "DB8",
- "SCX",
- "SQ9",
- "HIZ",
- "SO7",
- "I39",
- "LIC",
- "6TS",
- "325",
- "KX0",
- "LMM",
- "EDD",
- "7LI",
- "4YV",
- "0SV",
- "JNO",
- "CT6",
- "G4J",
- "FSE",
- "R5S",
- "MFR",
- "O22",
- "ZYV",
- "FS7",
- "84X",
- "FLW",
- "VYH",
- "YK4",
- "7GK",
- "SC8",
- "SLV",
- "QNR",
- "54E",
- "18R",
- "MTZ",
- "UKI",
- "8BY",
- "24A",
- "CQ0",
- "76Q",
- "YY6",
- "1QJ",
- "ICV",
- "PKB",
- "O1R",
- "8AM",
- "IIQ",
- "KJQ",
- "YM6",
- "P5K",
- "BDY",
- "F8Y",
- "2QU",
- "4MG",
- "1JV",
- "B5T",
- "O38",
- "CJN",
- "88A",
- "MSQ",
- "0KO",
- "TVW",
- "MYU",
- "VK5",
- "QUE",
- "AM0",
- "4EK",
- "6K7",
- "WAP",
- "M54",
- "4B7",
- "274",
- "3TA",
- "A8Q",
- "KHT",
- "V25",
- "0C7",
- "071",
- "SK8",
- "MP7",
- "5U5",
- "E7N",
- "LRS",
- "M2Z",
- "3RJ",
- "PO5",
- "15V",
- "88C",
- "B43",
- "582",
- "CQ6",
- "6AF",
- "L8D",
- "AZ5",
- "UOH",
- "H6X",
- "PXK",
- "50R",
- "IPW",
- "FZL",
- "79S",
- "92D",
- "5YS",
- "LHZ",
- "YW5",
- "X2K",
- "TKB",
- "QWN",
- "JYO",
- "BX7",
- "13J",
- "V5E",
- "6KD",
- "X6D",
- "685",
- "19Z",
- "N6U",
- "A4W",
- "WYF",
- "SB6",
- "3NW",
- "4QV",
- "E56",
- "Q8W",
- "L7I",
- "HYM",
- "N8S",
- "YXT",
- "404",
- "84S",
- "N66",
- "RHW",
- "68U",
- "LI6",
- "HYZ",
- "05J",
- "3JW",
- "X9Y",
- "N86",
- "E8K",
- "0B9",
- "EU2",
- "B49",
- "M3Y",
- "S7S",
- "AK6",
- "7MP",
- "76P",
- "L2G",
- "6UH",
- "MUH",
- "SX7",
- "6UG",
- "9G5",
- "R34",
- "IDK",
- "R49",
- "LS2",
- "6VL",
- "4C9",
- "5H7",
- "92Q",
- "AUT",
- "DQO",
- "Q6G",
- "T4C",
- "31S",
- "Z04",
- "26K",
- "YSI",
- "NSO",
- "PFP",
- "676",
- "L9G",
- "84U",
- "E47",
- "9NH",
- "A7Q",
- "62O",
- "P4O",
- "8MK",
- "H2E",
- "LOW",
- "QGI",
- "ZXC",
- "QK0",
- },
+ "plinder.data.annotations.ligand_utils.BINDING_AFFINITY",
+ None,
)
-@pytest.fixture(scope="session")
-def system_1a3b():
- return "1a3b__1__1.B__1.D"
-
-
-@pytest.fixture(scope="session")
-def predicted_pose_1a3b():
- return test_asset_fp / "eval/predicted_poses/1a3b__1__1.B__1.D/rank1.sdf"
-
-
-@pytest.fixture(scope="session")
-def predicted_named_pose_1a3b():
- return test_asset_fp / "eval/predicted_poses/1a3b__1__1.B__1.D/rank1_named.sdf"
-
-
-@pytest.fixture(scope="session")
-def system_1ai5():
- return "1ai5__1__1.A_1.B__1.D"
-
-
-@pytest.fixture(scope="session")
-def predicted_pose_1ai5():
- return test_asset_fp / "eval/predicted_poses/1ai5__1__1.A_1.B__1.D/rank1.sdf"
-
-
@pytest.fixture(autouse=True)
def failfast(monkeypatch):
monkeypatch.setattr("plinder.core.utils.io.sleep", lambda x: None)
@@ -7022,13 +578,6 @@ def raise_for_status(self):
monkeypatch.setattr("plinder.data.pipeline.io.requests.get", f)
-@pytest.fixture(scope="session")
-def pdb_atom_array(pdb_5a7w_hydrogen):
- from plinder.core.structure import vendored
-
- return vendored.atom_array_from_pdb_file(pdb_5a7w_hydrogen)
-
-
@pytest.fixture(scope="session")
def cif_atom_array(cif_1qz5_unzipped):
from plinder.core.structure import atoms
@@ -7039,8 +588,3 @@ def cif_atom_array(cif_1qz5_unzipped):
)
print(atom_array)
return atom_array
-
-
-@pytest.fixture(scope="session")
-def split_plot_split_file():
- return test_asset_fp / "split_plot_split.parquet"
diff --git a/tests/core/test_atoms.py b/tests/core/test_atoms.py
index eef26c3f8..e2c5bce42 100644
--- a/tests/core/test_atoms.py
+++ b/tests/core/test_atoms.py
@@ -1,69 +1,94 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
+from zipfile import ZipFile
+
import biotite.structure as struc
import numpy as np
import pytest
-from biotite.structure.atoms import AtomArray
-from plinder.core.index.system import PlinderSystem
-from plinder.core.structure import vendored as atoms
-from plinder.core.structure.atoms import (
- atom_array_from_cif_file,
-)
-from plinder.core.structure.models import BackboneDefinition
-from plinder.core.structure.smallmols_utils import (
- generate_input_conformer,
- params_removeHs,
-)
+from biotite.structure.atoms import AtomArray, AtomArrayStack
from rdkit import Chem
+from plinder.core.structure import atoms
+from plinder.core.structure.smallmols_utils import generate_input_conformer
+from plinder.core.structure.structure import Structure
+
-def test_pdb_loader(pdb_5a7w_hydrogen):
- arr = atoms.atom_array_from_pdb_file(pdb_5a7w_hydrogen)
+def test_cif_loader(cif_1qz5_unzipped):
+ arr = atoms.atom_array_from_cif_file(cif_1qz5_unzipped, use_author_fields=False)
assert isinstance(arr, AtomArray)
- assert arr.shape == (5623,)
+ assert arr.shape == (3256,)
+ assert sorted(set(arr.chain_id)) == ["A", "B", "C", "D", "E"]
-def test_atom_masks(cif_atom_array):
- print(cif_atom_array)
+def test_apply_mask(cif_atom_array):
arr = cif_atom_array.copy()
- mask = atoms.backbone_mask(arr, BackboneDefinition("dockq"))
- assert mask.sum() == 1794
+ mask = arr.atom_name == "CA"
- assert mask.shape == (3256,)
- assert set(arr[mask].atom_name) == set(atoms.DOCKQ_BACKBONE_ATOMS)
+ assert mask.sum() == 360
+ assert atoms.apply_mask(arr, mask).shape == (360,)
+ stacked = atoms.apply_mask(struc.stack([arr, arr]), mask)
+ assert isinstance(stacked, AtomArrayStack)
+ assert stacked.shape == (2, 360)
+ with pytest.raises(TypeError, match="AtomArray or AtomArrayStack"):
+ atoms.apply_mask(mask, mask)
- assert atoms.apply_mask(arr, mask).shape == arr[mask].shape
- assert set(atoms.filter_atoms(arr, calpha_only=True).atom_name) == {"CA"}
+def test_resn2seq():
+ # MSE keeps its methionine letter; SEC and PYL fall back to C and K because
+ # biotite's protein alphabet lacks U and O; non-residues become X.
+ names = ["ALA", "MSE", "SEC", "PYL", "HOH", "GLY", "UNK"]
+ assert atoms.resn2seq(names) == "AMCKXGX"
+ assert atoms.resn2seq([]) == ""
-@pytest.mark.parametrize(
- "backbone_only, calpha_only, expected_mask",
- [
- (True, True, 1794),
- (True, False, 1794),
- (False, True, 360),
- ],
-)
-def test_get_backbone_atom_masks(
- backbone_only, calpha_only, expected_mask, cif_atom_array
-):
- arr = cif_atom_array.copy()
- arr_mask, stack_mask = atoms.get_backbone_atom_masks(
- arr, struc.stack([arr]), backbone_only=backbone_only, calpha_only=calpha_only
+
+def test_align_sequences_maps_matched_residues_only():
+ # Two-residue deletion in the subject: the reference numbering skips 4-5.
+ assert atoms.align_sequences("ACDEFGHIK", "ACDGHIK") == (
+ "ACDGHIK",
+ "ACDGHIK",
+ [1, 2, 3, 6, 7, 8, 9],
+ [1, 2, 3, 4, 5, 6, 7],
+ )
+ # A substitution stays aligned and keeps both numberings.
+ assert atoms.align_sequences("ACDEFGHIK", "ACDQFGHIK") == (
+ "ACDEFGHIK",
+ "ACDQFGHIK",
+ list(range(1, 10)),
+ list(range(1, 10)),
)
- assert arr_mask.shape[0] == 3256
- assert arr_mask.shape == stack_mask.shape
- assert arr_mask.sum() == stack_mask.sum() == expected_mask
+ # Unknown residues are aligned but never reported as matched.
+ assert atoms.align_sequences("ACDEF", "ACXEF") == (
+ "ACEF",
+ "ACEF",
+ [1, 2, 4, 5],
+ [1, 2, 4, 5],
+ )
+ # Caller-provided numbering is passed through.
+ assert atoms.align_sequences("AC", "AC", [7, 8], [30, 31]) == (
+ "AC",
+ "AC",
+ [7, 8],
+ [30, 31],
+ )
+
+def test_residue_index_mapping_mask(cif_atom_array):
+ chain_a = cif_atom_array[cif_atom_array.chain_id == "A"]
+ resolved = atoms.resn2seq(struc.get_residues(chain_a)[1])
+ assert len(resolved) == 359
-def test_resn2seq(cif_atom_array):
- assert atoms.resn2seq(cif_atom_array.res_name[0:5]) == "TTTTT"
- structure, numbering, resn = atoms._get_structure_and_res_info(cif_atom_array)
- assert isinstance(structure, AtomArray)
- assert set(numbering) == set(cif_atom_array.res_id)
- assert atoms.resn2seq(resn[0:2]) == "TT"
+ # A reference with one extra tryptophan: only that position is unresolved.
+ reference = resolved[:10] + "W" + resolved[10:]
+ mask = atoms.get_residue_index_mapping_mask({"A": reference}, cif_atom_array)["A"]
+ assert mask.shape == (360,)
+ assert np.flatnonzero(mask == 0).tolist() == [10]
+
+ # A reference that starts five residues in is fully resolved.
+ mask = atoms.get_residue_index_mapping_mask({"A": resolved[5:]}, cif_atom_array)
+ assert mask["A"].shape == (354,)
+ assert mask["A"].all()
def test_default_sequence_alignment():
@@ -73,61 +98,36 @@ def test_default_sequence_alignment():
[1, 2, 3, 4],
[1, 2, 3, 4],
)
- assert atoms.get_seq_identity("ACDE", "ACDE") == pytest.approx(1.0)
-
-
-def test_get_seq_alignments(read_plinder_mount):
- pdb = PlinderSystem(system_id="19hc__1__1.A_1.B__1.K_1.M_1.N").receptor_pdb
- a = atoms.atom_array_from_pdb_file(pdb)
- b = atoms.atom_array_from_pdb_file(pdb)
- a_numbering, a_resn = struc.get_residues(a)
- b_numbering, b_resn = struc.get_residues(b)
- a_seq = atoms.resn2seq(a_resn).strip("X")
- b_seq = atoms.resn2seq(b_resn).strip("X")
- ident = atoms.get_seq_identity(a_seq, b_seq)
- assert isinstance(ident, float)
- assert ident == pytest.approx(1.0)
-
- alns = atoms.get_seq_alignments(a_seq, b_seq)
- mismatches, matches = atoms.calc_num_mismatches(alns)
- assert mismatches == 0
- assert matches == len(a_seq)
-
- a_seq_aln, b_seq_aln, a_numbering, b_numbering = atoms.align_sequences(a_seq, b_seq)
- assert a_seq_aln == b_seq_aln == a_seq == b_seq
- assert a_numbering == list(range(1, len(a_seq) + 1))
- assert b_numbering == list(range(1, len(b_seq) + 1))
-
-
-def test_buried_sasa(read_plinder_mount):
- pdb = PlinderSystem(system_id="19hc__1__1.A_1.B__1.K_1.M_1.N").receptor_pdb
- arr = atoms.atom_array_from_pdb_file(pdb)
- a = arr[arr.chain_id == "A"]
- b = arr[arr.chain_id == "B"]
- dsasa = atoms.get_buried_sasa(a, b)
- assert isinstance(dsasa, int)
- assert dsasa == 2520
-
-
-def test_atom_array_from_cif_file(cif_1qz5_unzipped):
- arr = atom_array_from_cif_file(cif_1qz5_unzipped)
- assert isinstance(arr, AtomArray)
-def test_params_removeHs():
+def test_write_cif_roundtrip(cif_atom_array, tmp_path):
+ chain_a = cif_atom_array[cif_atom_array.chain_id == "A"]
+ output = tmp_path / "nested" / "chain_a.cif"
+
+ atoms.write_cif(chain_a, output)
+ reread = atoms.atom_array_from_cif_file(output, use_author_fields=False)
+
+ assert output.read_text().startswith("data_chain_a")
+ assert reread.shape == chain_a.shape
+ assert reread.res_name.tolist() == chain_a.res_name.tolist()
+ with pytest.raises(ValueError, match="must end in .cif"):
+ atoms.write_cif(chain_a, tmp_path / "chain_a.pdb")
+
+
+def test_remove_all_hs():
# explicit bond stereo - from PDB: 5j1x
mol = Chem.MolFromSmiles("[H]/N=C(/N)NCCC[C@H](NC(=O)OC(C)(C)C)C(=O)O")
- mol = params_removeHs(mol)
+ mol = Chem.RemoveAllHs(mol, sanitize=False)
assert mol.GetNumAtoms() == mol.GetNumHeavyAtoms()
# hydrogen isotopes - from PDB: 1tuj
mol2 = Chem.MolFromSmiles("[2H]C([2H])(C(=O)[O-])C([2H])([2H])[Si](C)(C)C")
- mol2 = params_removeHs(mol2)
+ mol2 = Chem.RemoveAllHs(mol2, sanitize=False)
assert mol2.GetNumAtoms() == mol2.GetNumHeavyAtoms()
# more strange explicit Hs
mol3 = Chem.MolFromSmiles(
"[H]/N=C(\\N)c1ccc(O)c(C=NCCN=Cc2cc(/C(N)=N\\[H])ccc2O)c1"
)
- mol3 = params_removeHs(mol3)
+ mol3 = Chem.RemoveAllHs(mol3, sanitize=False)
assert mol3.GetNumAtoms() == mol3.GetNumHeavyAtoms()
@@ -153,9 +153,33 @@ def test_generate_input_conformer_hard():
assert sum(abs(mol.GetConformer().GetPositions()[:, 2])) != 0
-def test_structure_with_symmetry_in_ligand(read_plinder_mount):
+def structure_from_fixture_archive(
+ read_plinder_mount, tmp_path, archive_code, system_id, ligand_smiles
+):
+ with ZipFile(read_plinder_mount / "systems" / f"{archive_code}.zip") as archive:
+ receptor = archive.extract(f"{system_id}/receptor.cif", tmp_path)
+ ligand = archive.extract(
+ f"{system_id}/ligand_files/{system_id.split('__')[-1]}.sdf",
+ tmp_path,
+ )
+ ligand_id = system_id.split("__")[-1]
+ return Structure(
+ id=system_id,
+ protein_path=receptor,
+ ligand_sdfs={ligand_id: ligand},
+ ligand_smiles={ligand_id: ligand_smiles},
+ )
+
+
+def test_structure_with_symmetry_in_ligand(read_plinder_mount, tmp_path):
# structure with symmetry in ligand
- holo_struct = PlinderSystem(system_id="4v2y__1__1.A__1.E").holo_structure
+ holo_struct = structure_from_fixture_archive(
+ read_plinder_mount,
+ tmp_path,
+ "v2",
+ "4v2y__1__1.A__1.E",
+ "O=C1CC[C@H](N2C(=O)c3ccccc3C2=O)C(=O)N1",
+ )
tag = holo_struct.ligand_chain_ordered[0]
holo_struct.input_ligand_templates[tag]
holo_struct.ligand_template2resolved_atom_order_stacks[tag]
@@ -167,9 +191,16 @@ def test_structure_with_symmetry_in_ligand(read_plinder_mount):
)
-def test_structure_partially_resolved_ligand(read_plinder_mount):
+def test_structure_partially_resolved_ligand(read_plinder_mount, tmp_path):
# structure with partially resolved ligand that can be matched piecewise
- holo_struct = PlinderSystem(system_id="1ngx__1__1.A_1.B__1.E").holo_structure
+ holo_struct = structure_from_fixture_archive(
+ read_plinder_mount,
+ tmp_path,
+ "ng",
+ "1ngx__1__1.A_1.B__1.E",
+ "COCCO[C@@H](C)CO[C@H](C)CO[C@H](C)COC(C)CO[C@@H](C)CO[C@@H](C)"
+ "CO[C@H](C)CO[C@H](C)COC[C@H](C)N",
+ )
tag = holo_struct.ligand_chain_ordered[0]
holo_struct.input_ligand_templates[tag]
holo_struct.ligand_template2resolved_atom_order_stacks[tag]
diff --git a/tests/core/test_ccd_template.py b/tests/core/test_ccd_template.py
new file mode 100644
index 000000000..ee555a4ba
--- /dev/null
+++ b/tests/core/test_ccd_template.py
@@ -0,0 +1,198 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from __future__ import annotations
+
+import biotite.structure as struc
+import numpy as np
+
+from plinder.core.structure.atoms import atom_array_from_cif_file
+from plinder.core.structure.ccd_template import (
+ UNRESOLVED_ANNOTATION,
+ add_missing_atoms,
+ ccd_component_template,
+)
+from plinder.core.structure.structure import Structure
+
+CIF_6M92 = "xx/pdb_00006m92/pdb_00006m92_xyz-enrich.cif.gz"
+
+
+def _lysine_30(atoms):
+ return atoms[(atoms.chain_id == "A") & (atoms.res_id == 30)]
+
+
+def test_add_missing_atoms_completes_side_chains_with_nan_and_mask(test_dir):
+ atoms = atom_array_from_cif_file(test_dir / CIF_6M92, use_author_fields=False)
+ atoms = atoms[atoms.res_name != "HOH"]
+ before = _lysine_30(atoms)
+ assert before.atom_name.tolist() == ["N", "CA", "C", "O", "CB"]
+
+ completed = add_missing_atoms(atoms)
+
+ after = _lysine_30(completed)
+ assert after.atom_name.tolist() == [
+ "N",
+ "CA",
+ "C",
+ "O",
+ "CB",
+ "CG",
+ "CD",
+ "CE",
+ "NZ",
+ ]
+ assert after.element.tolist()[5:] == ["C", "C", "C", "N"]
+ assert np.isnan(after.coord[5:]).all() and not np.isnan(after.coord[:5]).any()
+ assert (
+ after.get_annotation(UNRESOLVED_ANNOTATION).tolist() == [False] * 5 + [True] * 4
+ )
+ assert after.res_name.tolist() == ["LYS"] * 9 and set(after.chain_id) == {"A"}
+
+ # deposited atoms are untouched, in order, and residues stay contiguous
+ mask = completed.get_annotation(UNRESOLVED_ANNOTATION)
+ kept = completed[~mask]
+ assert kept.atom_name.tolist() == atoms.atom_name.tolist()
+ np.testing.assert_array_equal(kept.coord, atoms.coord)
+ assert struc.get_residue_count(completed) == struc.get_residue_count(atoms)
+ # leaving atoms (OXT) and hydrogens are never added
+ added = completed[mask]
+ assert (
+ "OXT" not in set(added.atom_name)
+ and not np.isin(added.element, ["H", "D"]).any()
+ )
+ # the input is not modified
+ assert UNRESOLVED_ANNOTATION not in atoms.get_annotation_categories()
+
+
+def test_add_missing_atoms_extends_bonds_and_remaps_existing_ones(test_dir):
+ atoms = atom_array_from_cif_file(test_dir / CIF_6M92, use_author_fields=False)
+ atoms = atoms[atoms.res_name != "HOH"]
+ assert atoms.bonds is not None
+
+ completed = add_missing_atoms(atoms)
+
+ assert completed.bonds is not None
+ mask = completed.get_annotation(UNRESOLVED_ANNOTATION)
+ # every deposited bond survives, as a bond between the same two atoms
+ old_pairs = {
+ (
+ atoms.chain_id[i],
+ atoms.res_id[i],
+ atoms.atom_name[i],
+ atoms.chain_id[j],
+ atoms.res_id[j],
+ atoms.atom_name[j],
+ )
+ for i, j, _ in atoms.bonds.as_array()
+ }
+ new_pairs = {
+ (
+ completed.chain_id[i],
+ completed.res_id[i],
+ completed.atom_name[i],
+ completed.chain_id[j],
+ completed.res_id[j],
+ completed.atom_name[j],
+ )
+ for i, j, _ in completed.bonds.as_array()
+ }
+ assert old_pairs <= new_pairs
+ # the completed lysine side chain is chained CB-CG-CD-CE-NZ
+ lysine = _lysine_30(completed)
+ names = lysine.atom_name.tolist()
+ bonded = {frozenset((names[i], names[j])) for i, j, _ in lysine.bonds.as_array()}
+ assert {
+ frozenset(p) for p in [("CB", "CG"), ("CG", "CD"), ("CD", "CE"), ("CE", "NZ")]
+ } <= bonded
+ assert mask.sum() > 0
+
+
+def test_add_missing_atoms_is_conservative():
+ atoms = struc.AtomArray(6)
+ atoms.coord = np.zeros((6, 3))
+ atoms.chain_id = np.array(["A"] * 6)
+ atoms.res_id = np.array([1, 1, 1, 2, 2, 2])
+ atoms.res_name = np.array(["ALA"] * 3 + ["NOTACCD"] * 3)
+ atoms.atom_name = np.array(
+ [
+ "N",
+ "CA",
+ "CX",
+ "C1",
+ "C2",
+ "C3",
+ ]
+ ) # CX is not an ALA atom
+ atoms.element = np.array(["N", "C", "C", "C", "C", "C"])
+ atoms.hetero = np.array([False] * 3 + [True] * 3)
+
+ completed = add_missing_atoms(atoms)
+
+ # off-template naming and unknown components are left exactly as they were
+ assert completed.array_length() == 6
+ assert not completed.get_annotation(UNRESOLVED_ANNOTATION).any()
+ assert ccd_component_template("NOTACCD") is None
+ template = ccd_component_template("ALA")
+ assert (
+ template.heavy == ("N", "CA", "C", "O", "CB", "OXT")
+ and "OXT" in template.leaving
+ )
+
+
+def test_completed_atoms_match_the_wwpdb_unobserved_records(test_dir):
+ from plinder.data.annotations.cif_utils import _iter_category_rows, read_mmcif_file
+
+ block = list(read_mmcif_file(test_dir / CIF_6M92).values())[0]
+ recorded = {
+ (row["label_asym_id"], int(row["label_seq_id"]), row["label_atom_id"])
+ for row in _iter_category_rows(
+ block,
+ "pdbx_unobs_or_zero_occ_atoms",
+ [
+ "polymer_flag",
+ "occupancy_flag",
+ "label_asym_id",
+ "label_seq_id",
+ "label_atom_id",
+ ],
+ )
+ if row["polymer_flag"] == "Y" and row["occupancy_flag"] == "1"
+ }
+ assert len(recorded) == 136
+
+ from plinder.data.annotations.cif_utils import get_label_asym_sequences
+
+ sequences = get_label_asym_sequences(block)
+ structure = Structure(
+ id="6m92",
+ protein_path=test_dir / CIF_6M92,
+ protein_sequence=sequences,
+ complete_missing_atoms=True,
+ )
+ atoms = structure.protein_atom_array
+ mask = atoms.get_annotation(UNRESOLVED_ANNOTATION)
+ completed = {
+ (str(c), int(r), str(n))
+ for c, r, n in zip(
+ atoms.chain_id[mask], atoms.res_id[mask], atoms.atom_name[mask]
+ )
+ }
+
+ # two independent sources agree: wwPDB's records and the CCD-template diff
+ assert completed == recorded
+ per_chain = structure.protein_unresolved_atom_mask
+ assert [int(m.sum()) for m in per_chain] == [
+ len([r for r in recorded if r[0] == chain])
+ for chain in structure.protein_chain_ordered
+ ]
+ assert all(len(m) == len(c) for m, c in zip(per_chain, structure.protein_coords))
+ assert all(
+ coordinates.dtype == atoms.coord.dtype
+ for coordinates in structure.protein_coords + structure.protein_calpha_coords
+ )
+ default = Structure(
+ id="6m92", protein_path=test_dir / CIF_6M92, protein_sequence=sequences
+ )
+ assert not any(m.any() for m in default.protein_unresolved_atom_mask)
+ assert default.protein_atom_array.array_length() == atoms.array_length() - len(
+ recorded
+ )
diff --git a/tests/core/test_core_config.py b/tests/core/test_core_config.py
index 9c493080e..95b046de0 100644
--- a/tests/core/test_core_config.py
+++ b/tests/core/test_core_config.py
@@ -14,6 +14,35 @@ def test_get_config():
assert cfg == {"data": asdict(ocfg), "context": asdict(ccfg)}
+def test_release_identifier_sets_local_and_remote_roots(monkeypatch):
+ monkeypatch.delenv("PLINDER_MIRROR_URL", raising=False)
+ cfg = config.DataConfig(
+ plinder_release="2026-07",
+ plinder_release_number="1",
+ plinder_mount="/cache",
+ plinder_bucket="plinder",
+ )
+
+ assert cfg.plinder_dir == "/cache/plinder/2026-07/1"
+ assert cfg.plinder_remote == "https://cameo3d.org/plinder/PLINDER-2026-07/1"
+
+
+def test_default_release_uses_cameo_without_environment_overrides(monkeypatch):
+ for key in ["PLINDER_RELEASE", "PLINDER_RELEASE_NUMBER", "PLINDER_MIRROR_URL"]:
+ monkeypatch.delenv(key, raising=False)
+ cfg = config.DataConfig(plinder_mount="/cache")
+
+ assert cfg.plinder_dir == "/cache/plinder/2026-09"
+ assert cfg.plinder_remote == "https://cameo3d.org/plinder/PLINDER-2026-09"
+
+
+def test_mirror_override_uses_the_file_server_layout(monkeypatch):
+ monkeypatch.setenv("PLINDER_MIRROR_URL", "https://mirror.example/datasets/")
+ cfg = config.DataConfig(plinder_release="2026-09", plinder_release_number="")
+
+ assert cfg.plinder_remote == "https://mirror.example/datasets/PLINDER-2026-09"
+
+
def test_get_config_passed():
cfg = config.get_config(
config_args=[], config={"data": {"plinder_release": "test"}}, cached=False
diff --git a/tests/core/test_core_scores.py b/tests/core/test_core_scores.py
index 13698dc6e..f960dc06b 100644
--- a/tests/core/test_core_scores.py
+++ b/tests/core/test_core_scores.py
@@ -1,15 +1,161 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
+import pandas as pd
import pytest
-from plinder.core import scores
-from plinder.core.scores.protein import multi_query_protein_similarity
+from plinder.core import PlinderRelease, query_table, scores
+from plinder.core.scores import ligand as ligand_module
-def test_query_index(read_plinder_mount):
- df = scores.query_index(columns=["system_id"], splits=["*"])
+
+def test_custom_scoring_public_api():
+ assert callable(scores.score_custom_cif_files)
+ assert callable(scores.score_custom_sequence_file)
+ assert scores.CustomProteinSearchConfig().max_seqs == 10_000
+
+
+@pytest.fixture
+def similarity_release(tmp_path):
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def"],
+ "chain_asym_id": ["A", "B"],
+ "chain_auth_id": ["A", "B"],
+ "selected_residue_numbers": [[10, 20, 30], [5, 6, 7, 8]],
+ "selected_residue_indices": [[0, 1, 2], [0, 1, 2, 3]],
+ }
+ ).to_parquet(index / "alignment_chain_lookup.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "1abc", "2def", "2def"],
+ "chain_asym_id": ["A", "A", "B", "B"],
+ "residue_label_seq_id": [10, 20, 6, 8],
+ }
+ ).to_parquet(index / "ligand_pocket_residues.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def"],
+ "interface_chain_1": ["1.A", "1.B"],
+ "interface_chain_1_residue_numbers": [[20, 30], [8]],
+ "interface_chain_2": ["1.C", "1.D"],
+ "interface_chain_2_residue_numbers": [[40], [9]],
+ }
+ ).to_parquet(index / "interface_annotation_table.parquet", index=False)
+ exports = tmp_path / "exports"
+ exports.mkdir()
+ pd.DataFrame(
+ {
+ "query_system": ["query", "query"],
+ "query_ligand_id": ["query__1.A", "query__1.B"],
+ "target_system": ["target", "other"],
+ "target_ligand_id": ["target__1.X", "other__1.Y"],
+ "pocket_qcov": [90, 40],
+ "pocket_fident_qcov": [80, 20],
+ "pli_qcov": [70, 10],
+ "sucos_shape": [60, 30],
+ }
+ ).to_parquet(exports / "ligand_similarity_scores.parquet", index=False)
+ pd.DataFrame(
+ {
+ "query_system": ["query_interface", "query_interface"],
+ "target_system": ["target_interface", "other_interface"],
+ "iface1_qcov": [0.9, 0.4],
+ "iface2_qcov": [0.8, 0.3],
+ "similarity": [80, 30],
+ }
+ ).to_parquet(exports / "interface_similarity_scores.parquet", index=False)
+ pd.DataFrame(
+ {
+ "query_half_interface_id": ["query_interface::side=1"],
+ "target_half_interface_id": ["target_interface::side=2"],
+ "similarity": [75],
+ }
+ ).to_parquet(exports / "interface_half_similarity_scores.parquet", index=False)
+ protein_scores = exports / "protein_similarity_scores/alignment_type=foldseek"
+ protein_scores.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query_entry": ["1abc"],
+ "target_entry": ["2def"],
+ "query_chain_mapped": ["A"],
+ "target_chain_mapped": ["B"],
+ "source": ["foldseek"],
+ "qcov": pd.Series([90], dtype="uint8"),
+ "tcov": pd.Series([85], dtype="uint8"),
+ "fident": pd.Series([70], dtype="uint8"),
+ "seqsim": pd.Series([75], dtype="uint8"),
+ "lddt": pd.Series([80], dtype="uint8"),
+ }
+ ).to_parquet(protein_scores / "shard=ab.parquet", index=False)
+ monomer_scores = exports / "monomer_similarity_scores/alignment_type=mmseqs"
+ monomer_scores.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query_entry": ["3ghi"],
+ "target_entry": ["1abc"],
+ "query_chain_mapped": ["C"],
+ "target_chain_mapped": ["A"],
+ "source": ["mmseqs"],
+ "qcov": pd.Series([95], dtype="uint8"),
+ "tcov": pd.Series([75], dtype="uint8"),
+ "fident": pd.Series([65], dtype="uint8"),
+ "seqsim": pd.Series([72], dtype="uint8"),
+ "lddt": pd.Series([pd.NA], dtype="UInt8"),
+ }
+ ).to_parquet(monomer_scores / "part-0.parquet", index=False)
+ alignment_shard = (
+ tmp_path / "alignments/search_db=holo/alignment_type=mmseqs/shard=ab.parquet"
+ )
+ alignment_shard.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query_entry": ["1abc"],
+ "target_entry": ["2def"],
+ "query_chain_mapped": ["A"],
+ "target_chain_mapped": ["B"],
+ "query_selected_residue_positions": [[1, 2, 3]],
+ "target_selected_residue_positions": [[2, 0, 4]],
+ "selected_residue_identity_bits": [b"\x05"],
+ }
+ ).to_parquet(alignment_shard, index=False)
+ cigar_shard = (
+ tmp_path
+ / "alignment_cigars/search_db=holo/alignment_type=mmseqs/shard=ab.parquet"
+ )
+ cigar_shard.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query_entry": ["1abc"],
+ "target_entry": ["2def"],
+ "query_chain_mapped": ["A"],
+ "target_chain_mapped": ["B"],
+ "source": ["mmseqs"],
+ "query_start": [3],
+ "target_start": [5],
+ "cigar": ["2M1I1D1M"],
+ }
+ ).to_parquet(cigar_shard, index=False)
+ ligand_scores = tmp_path / "ligand_scores"
+ ligand_scores.mkdir()
+ pd.DataFrame(
+ {
+ "query_ligand_id": [29, 51],
+ "target_ligand_id": [49918, 36689],
+ "tanimoto_similarity_ecfp4_1024": [95.0, 75.0],
+ }
+ ).to_parquet(ligand_scores / "scores.parquet", index=False)
+ return PlinderRelease(tmp_path)
+
+
+@pytest.mark.usefixtures("read_plinder_mount")
+def test_query_annotation_table():
+ df = query_table("annotation", columns=["system_id"])
assert len(df.index) == 57
+ assert "split" not in df.columns
+@pytest.mark.usefixtures("read_plinder_mount")
@pytest.mark.parametrize(
"system_id, correct_release_date",
[
@@ -18,118 +164,382 @@ def test_query_index(read_plinder_mount):
],
)
def test_entry_release_date(system_id, correct_release_date):
- df = scores.query_index(
- splits=["*"],
+ df = query_table(
+ "annotation",
columns=["entry_release_date"],
filters=[("system_id", "==", system_id)],
)
assert df.iloc[0].entry_release_date == correct_release_date
-def test_query_protein_similarity(read_plinder_mount):
- df = scores.query_protein_similarity(
- search_db="holo",
- filters=[
- ("metric", "==", "pocket_lddt"),
- ("similarity", ">=", 90),
- ],
+def test_query_ligand_similarity_reads_complete_export(similarity_release):
+ result = scores.query_ligand_similarity(
+ columns=["target_system", "pocket_qcov", "pli_qcov", "sucos_shape"],
+ filters=[("query_system", "==", "query"), ("pocket_qcov", ">=", 80)],
+ release=similarity_release,
)
- assert df is not None
- assert len(df.index)
+
+ assert result.to_dict("records") == [
+ {
+ "target_system": "target",
+ "pocket_qcov": 90,
+ "pli_qcov": 70,
+ "sucos_shape": 60,
+ }
+ ]
-def test_query_protein_similarity_empty(read_plinder_mount):
- with pytest.raises(ValueError):
- scores.query_protein_similarity(
+def test_query_protein_similarity_reads_integer_scores(similarity_release):
+ result = scores.query_protein_similarity(
+ columns=["target_entry", "fident", "seqsim", "lddt"],
+ filters=[("query_entry", "==", "1abc")],
+ release=similarity_release,
+ )
+
+ assert result.to_dict("records") == [
+ {"target_entry": "2def", "fident": 70, "seqsim": 75, "lddt": 80}
+ ]
+
+
+def test_query_protein_similarity_can_include_monomer_pairs(similarity_release):
+ result = scores.query_protein_similarity(
+ columns=["query_entry", "target_entry", "fident"],
+ filters=[("target_entry", "==", "1abc")],
+ release=similarity_release,
+ include_monomers=True,
+ )
+
+ assert result.to_dict("records") == [
+ {"query_entry": "3ghi", "target_entry": "1abc", "fident": 65}
+ ]
+
+
+@pytest.mark.parametrize(
+ ("kind", "expected"),
+ [
+ (
+ "pocket",
+ {
+ "overlapping_residues": 1,
+ "identical_overlapping_residues": 1,
+ "query_total_residues": 2,
+ "target_total_residues": 2,
+ "query_overlap_fraction": pytest.approx(1 / 2),
+ "target_overlap_fraction": pytest.approx(1 / 2),
+ },
+ ),
+ (
+ "interface",
+ {
+ "overlapping_residues": 1,
+ "identical_overlapping_residues": 1,
+ "query_total_residues": 2,
+ "target_total_residues": 1,
+ "query_overlap_fraction": pytest.approx(1 / 2),
+ "target_overlap_fraction": pytest.approx(1.0),
+ },
+ ),
+ ],
+)
+def test_query_chain_overlap_counts_selected_residues(
+ similarity_release, kind, expected
+):
+ # Selected residues 10 and 30 align to 6 and 8; residue 20 is in a gap.
+ pd.DataFrame(
+ [
+ {
+ "query_entry": "1abc",
+ "target_entry": "2def",
+ "query_chain_mapped": "A",
+ "target_chain_mapped": "B",
+ "source": "mmseqs",
+ "query_start": 10,
+ "target_start": 6,
+ "cigar": "1M19I1D1M",
+ "selected_residue_identity_bits": b"\x03",
+ }
+ ]
+ ).to_parquet(
+ similarity_release.path(
+ "alignment_cigar_shard",
search_db="holo",
- filters=[],
- )
+ alignment_type="mmseqs",
+ shard="ab",
+ ),
+ index=False,
+ )
+ result = scores.query_chain_overlap(
+ "1abc",
+ "A",
+ "2def",
+ "B",
+ kind=kind,
+ source="mmseqs",
+ release=similarity_release,
+ )
+ assert result.to_dict("records") == [
+ {
+ "query_entry": "1abc",
+ "query_chain": "A",
+ "target_entry": "2def",
+ "target_chain": "B",
+ "source": "mmseqs",
+ "kind": kind,
+ **expected,
+ }
+ ]
-def test_query_protein_similarity_removes_search_db(read_plinder_mount):
- df = scores.query_protein_similarity(
- search_db="holo",
- filters=[
- ("search_db", "==", "holo"),
- ("metric", "==", "pocket_lddt"),
- ("similarity", ">=", 90),
- ],
+
+@pytest.mark.parametrize(
+ ("source", "query_column", "target_column", "expected_query", "expected_target"),
+ [
+ (
+ "mmseqs",
+ "query_seqres_position",
+ "target_seqres_position",
+ [3, 4, 5, None, 6],
+ [5, 6, None, 7, 8],
+ ),
+ (
+ "foldseek",
+ "query_coordinate_index",
+ "target_coordinate_index",
+ [2, 3, 4, None, 5],
+ [4, 5, None, 6, 7],
+ ),
+ ],
+)
+def test_expand_alignment_cigar_uses_backend_coordinate_space(
+ source, query_column, target_column, expected_query, expected_target
+):
+ result = scores.expand_alignment_cigar(
+ "2M1I1D1M",
+ query_start=3,
+ target_start=5,
+ source=source,
)
- assert df is not None
- assert len(df.index)
+ assert result["operation"].tolist() == ["M", "M", "I", "D", "M"]
+ query_values = (
+ result[query_column].astype(object).where(result[query_column].notna(), None)
+ )
+ target_values = (
+ result[target_column].astype(object).where(result[target_column].notna(), None)
+ )
+ assert query_values.tolist() == expected_query
+ assert target_values.tolist() == expected_target
-def test_query_protein_similarity_raises(read_plinder_mount):
- with pytest.raises(ValueError):
- scores.query_protein_similarity(
- search_db="test",
- filters=[
- ("search_db", "==", "holo"),
- ("metric", "==", "pocket_lddt"),
- ("similarity", ">=", 90),
- ],
- )
+def test_map_chain_alignment_reads_optional_cigar_shard(similarity_release):
+ result = scores.map_chain_alignment(
+ "1abc",
+ "A",
+ "2def",
+ "B",
+ source="mmseqs",
+ include_gaps=False,
+ release=similarity_release,
+ )
+
+ assert result[
+ ["query_seqres_position", "target_seqres_position"]
+ ].values.tolist() == [[3, 5], [4, 6], [6, 8]]
-def test_query_protein_cross_similarity(read_plinder_mount):
- df = scores.cross_protein_similarity(
- query_systems=["8t49__1__1.G__1.AB", "6cex__1__1.D__1.M"],
- target_systems=["4r2g__3__1.P__1.AB", "4ln4__1__1.F__1.U"],
- metric="pocket_lddt",
+
+@pytest.mark.parametrize("source", ["foldseek", "mmseqs"])
+def test_cigar_sparse_decoders_agree(similarity_release, source):
+ import duckdb
+
+ from plinder.core.scores.mapping import (
+ cigar_alignment_sql,
+ decode_cigar_residue_positions,
)
- assert len(df.index)
+ path = similarity_release.path(
+ "alignment_cigar_shard", search_db="holo", alignment_type="mmseqs", shard="ab"
+ )
+ frame = pd.read_parquet(path)
+ frame["source"] = source
+ frame["query_start"] = 1 if source == "foldseek" else 10
+ frame["target_start"] = 1 if source == "foldseek" else 5
+ frame["cigar"] = "2M1I1D1M"
+ frame.to_parquet(path, index=False)
+ lookup = similarity_release.path("alignment_chain_lookup")
+ decoded = decode_cigar_residue_positions(frame, chain_lookup=lookup)
+ con = duckdb.connect()
+ sql = con.execute(cigar_alignment_sql(path, lookup)).fetchdf()
+ con.close()
+ for column in [
+ "query_selected_residue_positions",
+ "target_selected_residue_positions",
+ ]:
+ assert sql.iloc[0][column].tolist() == decoded.iloc[0][column]
-def test_query_ligand_similarity(read_plinder_mount):
- df = scores.query_ligand_similarity(
+
+def test_query_interface_similarity_reads_complete_export(similarity_release):
+ result = scores.query_interface_similarity(
+ columns=["target_system", "iface1_qcov", "iface2_qcov", "similarity"],
filters=[
- ("query_ligand_id", "<", "100"),
- ]
+ ("query_system", "==", "query_interface"),
+ ("similarity", ">=", 70),
+ ],
+ release=similarity_release,
)
- assert df is not None
- assert len(df.index)
-
-def test_query_ligand_similarity_empty(read_plinder_mount):
- with pytest.raises(ValueError):
- scores.query_ligand_similarity(filters=[])
+ assert result.to_dict("records") == [
+ {
+ "target_system": "target_interface",
+ "iface1_qcov": pytest.approx(0.9),
+ "iface2_qcov": pytest.approx(0.8),
+ "similarity": 80,
+ }
+ ]
-def test_query_ligand_cross_similarity(read_plinder_mount):
- df = scores.cross_ligand_similarity(
- query_ligands=[29, 51], target_ligands=[49918, 36689]
+def test_query_half_interface_similarity_reads_complete_export(similarity_release):
+ result = scores.query_half_interface_similarity(
+ filters=[("query_half_interface_id", "==", "query_interface::side=1")],
+ release=similarity_release,
)
- assert len(df.index)
+ assert result.to_dict("records") == [
+ {
+ "query_half_interface_id": "query_interface::side=1",
+ "target_half_interface_id": "target_interface::side=2",
+ "similarity": 75,
+ }
+ ]
-def test_query_links(read_plinder_mount):
- system_id = "4dd7__1__1.A__1.B"
- df = scores.query_links(filters=[("reference_system_id", "==", system_id)])
- assert len(df.index)
+
+@pytest.mark.parametrize(
+ "query",
+ [
+ scores.query_protein_similarity,
+ scores.query_ligand_similarity,
+ scores.query_interface_similarity,
+ scores.query_half_interface_similarity,
+ ],
+)
+def test_complete_similarity_queries_require_filters(query, similarity_release):
+ with pytest.raises(ValueError, match="at least one score filter"):
+ query(filters=[], release=similarity_release)
-def test_query_links_columns(read_plinder_mount):
- system_id = "4dd7__1__1.A__1.B"
- df = scores.query_links(
- columns=["reference_system_id"],
- filters=[("reference_system_id", "==", system_id)],
+def test_query_ligand_chemical_similarity(similarity_release):
+ result = scores.query_ligand_chemical_similarity(
+ filters=[("query_ligand_id", "==", 29)],
+ release=similarity_release,
)
- assert len(df.index)
- assert "reference_system_id" in df.columns
- assert "kind" in df.columns
+ assert result["tanimoto_similarity_ecfp4_1024"].tolist() == [95.0]
+
+
+def test_cross_ligand_chemical_similarity(similarity_release, monkeypatch):
+ monkeypatch.setattr(
+ ligand_module,
+ "_map_cross_chemical_similarity",
+ lambda frame, _target_ligands, _metric, _release: frame,
+ )
+ result = scores.cross_ligand_chemical_similarity(
+ query_ligands=["29", "51"],
+ target_ligands=["49918", "36689"],
+ release=similarity_release,
+ )
+
+ assert len(result.index) == 2
+
+
+def test_cross_ligand_chemical_similarity_rejects_non_numeric_ids(
+ similarity_release,
+):
+ with pytest.raises(ValueError, match="ligand IDs must be integers"):
+ scores.cross_ligand_chemical_similarity(
+ query_ligands=["not-an-id"],
+ target_ligands=["49918"],
+ release=similarity_release,
+ )
+
+
+@pytest.mark.parametrize(
+ ("query_ligands", "target_ligands"),
+ [("29", ["49918"]), (["29"], "49918")],
+)
+def test_cross_ligand_chemical_similarity_rejects_scalar_strings(
+ query_ligands,
+ target_ligands,
+):
+ with pytest.raises(TypeError, match="must be provided as a collection"):
+ scores.cross_ligand_chemical_similarity(
+ query_ligands=query_ligands,
+ target_ligands=target_ligands,
+ )
+
+
+def test_cross_ligand_chemical_similarity_maps_nodes_through_annotation(
+ monkeypatch,
+):
+ calls = []
+
+ def fake_query_table(table_name, *, columns, filters, release):
+ calls.append((table_name, columns, filters, release))
+ return pd.DataFrame(
+ {
+ "system_id": ["1aaa__1__1.A__1.X", "2bbb__1__1.B__1.Y"],
+ "ligand_smiles_id": [0, 0],
+ }
+ )
-def test_multi_query_protein_similarity(read_plinder_mount):
- system_id = "8t49__1__1.G__1.AB"
- filter_criteria: dict[str, int] = {
- "protein_fident_qcov_weighted_sum": 0,
- "pocket_lddt": 90,
+ release = PlinderRelease()
+ monkeypatch.setattr(ligand_module, "query_table", fake_query_table)
+ result = ligand_module._map_cross_chemical_similarity(
+ pd.DataFrame(
+ {
+ "query_ligand_id": [0],
+ "target_ligand_id": [1],
+ "tanimoto_similarity_ecfp4_1024": [95.0],
+ }
+ ),
+ target_ligands={1},
+ metric="tanimoto_similarity_ecfp4_1024",
+ release=release,
+ )
+
+ assert set(result["system_id"]) == {
+ "1aaa__1__1.A__1.X",
+ "2bbb__1__1.B__1.Y",
}
- df = multi_query_protein_similarity(
- system_id=system_id,
- search_db="holo",
- filter_criteria=filter_criteria,
- splits=["*"],
- )
- assert len(df.index)
- assert all(k in df.columns for k in filter_criteria)
+ assert calls[0] == (
+ "annotation",
+ ["system_id", "ligand_smiles_id"],
+ [("ligand_smiles_id", "in", {0})],
+ release,
+ )
+
+
+def test_cross_ligand_chemical_similarity_returns_empty_without_annotation(
+ monkeypatch,
+):
+ monkeypatch.setattr(
+ ligand_module,
+ "query_table",
+ lambda *_args, **_kwargs: pytest.fail(
+ "empty similarities must not query annotation"
+ ),
+ )
+
+ result = ligand_module._map_cross_chemical_similarity(
+ pd.DataFrame(
+ columns=[
+ "query_ligand_id",
+ "target_ligand_id",
+ "tanimoto_similarity_ecfp4_1024",
+ ]
+ ),
+ target_ligands={1},
+ metric="tanimoto_similarity_ecfp4_1024",
+ release=None,
+ )
+
+ assert result.empty
+ assert result.columns.tolist() == ["system_id", "tanimoto_similarity_ecfp4_1024"]
diff --git a/tests/core/test_core_system.py b/tests/core/test_core_system.py
index 0743eb974..af405c075 100644
--- a/tests/core/test_core_system.py
+++ b/tests/core/test_core_system.py
@@ -1,62 +1,215 @@
+from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
+from threading import Barrier
import numpy as np
+import pandas as pd
import pytest
+
from plinder.core import index
+from plinder.core.release import PlinderRelease
+@pytest.mark.usefixtures("read_plinder_mount")
@pytest.mark.parametrize(
"system_id",
[
- "19hc__1__1.A_1.B__1.D_1.L_1.Q_1.S_1.U",
- "19hc__1__1.A_1.B__1.E_1.F_1.H_1.J_1.O",
- "19hc__1__1.A_1.B__1.G",
- "19hc__1__1.A_1.B__1.K_1.M_1.N",
- "19hc__1__1.A_1.B__1.R",
- "19hc__1__1.A_1.B__1.V_1.X_1.Y",
- "19hc__1__1.A_1.B__1.W",
+ "1avd__1__1.A__1.C",
"19hc__1__1.A__1.I",
"19hc__1__1.B__1.T",
],
)
-def test_plinder_system(system_id, read_plinder_mount):
+def test_plinder_system(system_id):
index.PlinderSystem(system_id=system_id).system
-@pytest.mark.parametrize(
- "system_id",
- [
- "19hc__1__1.A__1.C",
- "19hc__1__1.B__1.P",
- ],
-)
-def test_plinder_system_fails(system_id, read_plinder_mount):
- with pytest.raises(ValueError):
- index.PlinderSystem(system_id=system_id).system
+def test_plinder_system_uses_explicit_release(cif_2y4i, tmp_path):
+ release_root = tmp_path / "release"
+ index_dir = release_root / "index"
+ index_dir.mkdir(parents=True)
+ system_id = "2y4i__1__1.A__1.B"
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["2y4i"],
+ "system_id": [system_id],
+ "system_biounit_id": ["1"],
+ "system_receptor_type": ["protein"],
+ "system_protein_chains_asym_id": [["1.A"]],
+ "ligand_instance": [1],
+ "ligand_asym_id": ["B"],
+ }
+ ).to_parquet(index_dir / "annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["2y4i"],
+ "entry_release_date": ["2000-01-01"],
+ }
+ ).to_parquet(index_dir / "entry_metadata.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["2y4i"],
+ "chain_asym_id": ["A"],
+ "chain_receptor_type": ["protein"],
+ }
+ ).to_parquet(index_dir / "entry_chains.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["2y4i", "2y4i"],
+ "biounit_id": ["1", "1"],
+ "chain_instance": ["1.A", "1.B"],
+ "chain_asym_id": ["A", "B"],
+ "chain_role": ["receptor", "ligand"],
+ }
+ ).to_parquet(index_dir / "entry_biounit_chains.parquet", index=False)
+
+ release = PlinderRelease(data_dir=release_root)
+ system = index.PlinderSystem(
+ system_id=system_id,
+ release=release,
+ source_mmcif=cif_2y4i,
+ )
+
+ assert system.reconstruction_dir == (
+ release_root / "reconstructed_systems" / system_id
+ )
+ assert system.system["entry_release_date"].tolist() == ["2000-01-01"]
+ assert system.entry["system_id"].tolist() == [system_id]
+ assert system.receptor_chain_types == {"1.A": "protein"}
+ assert system.biounit_chains["chain_instance"].tolist() == ["1.A", "1.B"]
+
+
+def test_plinder_system_receptor_type():
+ system = index.PlinderSystem.__new__(index.PlinderSystem)
+ system.system_id = "1abc__1__1.A_1.N__1.L"
+ system._system = pd.DataFrame(
+ {
+ "system_receptor_type": ["protein+dna"],
+ "system_protein_chains_asym_id": [["1.A", "1.N"]],
+ }
+ )
+ system._entry_chains = pd.DataFrame(
+ {
+ "chain_asym_id": ["A", "N"],
+ "chain_receptor_type": ["protein", "dna"],
+ }
+ )
+
+ assert system.receptor_type == "protein+dna"
+ assert system.receptor_chain_types == {"1.A": "protein", "1.N": "dna"}
+
+
+def test_plinder_system_smiles_uses_published_ligand_smiles():
+ system = index.PlinderSystem.__new__(index.PlinderSystem)
+ system._system = pd.DataFrame(
+ {
+ "ligand_instance": [1],
+ "ligand_asym_id": ["L"],
+ "ligand_smiles": ["CCO"],
+ "ligand_resolved_smiles": ["CC"],
+ }
+ )
+
+ assert system.smiles == {"1.L": "CCO"}
-def test_plinder_system_system_files(read_plinder_mount):
- system_id = "19hc__1__1.A_1.B__1.V_1.X_1.Y"
- s = index.PlinderSystem(system_id=system_id)
- assert len(s.structures) == 9
- assert len(s.ligand_sdfs) == 3
+def test_plinder_system_system_files(cached_plinder_system):
+ system_id = "1avd__1__1.A__1.C"
+ s = cached_plinder_system(system_id)
+ assert len(s.ligand_sdfs) >= 1
assert len(s.system_cif)
assert len(s.receptor_cif)
- assert len(s.receptor_pdb)
assert len(s.sequences)
- assert s.chain_mapping is not None and len(s.chain_mapping)
- assert s.water_mapping is not None and len(s.water_mapping)
assert Path(s.system_cif).is_file()
assert Path(s.receptor_cif).is_file()
- assert Path(s.receptor_pdb).is_file()
assert Path(s.sequences_fasta).is_file()
- assert isinstance(s.chain_mapping, dict)
- assert isinstance(s.water_mapping, dict)
+ assert s.receptor_structure.array_length() > 0
+ assert set(s.ligand_structures) == set(s.ligand_sdfs)
+ assert all(
+ structure.array_length() > 0 for structure in s.ligand_structures.values()
+ )
+
+
+def test_plinder_system_extracts_canonical_ligand_archive(
+ write_plinder_mount, monkeypatch
+):
+ from plinder.core.utils import config
+
+ monkeypatch.setenv("PLINDER_OFFLINE", "true")
+ config._config._clear()
+ archive = write_plinder_mount / "ligand_archives" / "av.parquet"
+ archive.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "pdb_id": ["1avd"],
+ "ligand_asym_id": ["C"],
+ "sdf": [b"canonical ASU ligand"],
+ }
+ ).to_parquet(archive, index=False)
+
+ system = index.PlinderSystem(system_id="1avd__1__1.A__1.C")
+
+ assert system.canonical_ligand_sdfs == {
+ "1.C": (
+ write_plinder_mount / "ligand_archives" / "1avd/ligand_files/C.sdf"
+ ).as_posix()
+ }
+
+
+def test_canonical_ligand_extraction_supports_concurrent_workers(tmp_path, monkeypatch):
+ from plinder.core.index.system import _extract_packed_ligand_sdfs
+
+ archive = tmp_path / "gr.parquet"
+ content = b"canonical ASU ligand"
+ pd.DataFrame(
+ {"pdb_id": ["3grt"], "ligand_asym_id": ["B"], "sdf": [content]}
+ ).to_parquet(archive, index=False)
+ written = Barrier(2)
+ write_bytes = Path.write_bytes
+
+ def write_together(path, data):
+ result = write_bytes(path, data)
+ if path.parent.name == "ligand_files":
+ written.wait(timeout=10)
+ return result
+
+ monkeypatch.setattr(Path, "write_bytes", write_together)
+ with ThreadPoolExecutor(max_workers=2) as pool:
+ futures = [
+ pool.submit(
+ _extract_packed_ligand_sdfs,
+ archive=archive,
+ pdb_id="3grt",
+ asym_ids={"B"},
+ )
+ for _ in range(2)
+ ]
+ folders = [future.result() for future in futures]
+
+ assert folders[0] == folders[1]
+ assert (folders[0] / "B.sdf").read_bytes() == content
+ assert list(folders[0].iterdir()) == [folders[0] / "B.sdf"]
+
+
+def test_canonical_ligand_extraction_cleans_up_failed_writes(tmp_path, monkeypatch):
+ from plinder.core.index.system import _extract_packed_ligand_sdfs
+
+ archive = tmp_path / "gr.parquet"
+ pd.DataFrame(
+ {"pdb_id": ["3grt"], "ligand_asym_id": ["B"], "sdf": [b"ligand"]}
+ ).to_parquet(archive, index=False)
+
+ def fail_replace(*_args):
+ raise OSError("replacement failed")
+
+ monkeypatch.setattr(Path, "replace", fail_replace)
+ with pytest.raises(OSError, match="replacement failed"):
+ _extract_packed_ligand_sdfs(archive=archive, pdb_id="3grt", asym_ids={"B"})
+ assert list((tmp_path / "3grt/ligand_files").iterdir()) == []
-def test_plinder_structure(read_plinder_mount):
+def test_plinder_structure(cached_plinder_system):
system_id = "1avd__1__1.A__1.C"
- s = index.PlinderSystem(system_id=system_id)
+ s = cached_plinder_system(system_id)
holo_struc = s.holo_structure
ligand_mols = holo_struc.ligand_mols
# test the mask order for smiles
diff --git a/tests/core/test_custom_scores.py b/tests/core/test_custom_scores.py
new file mode 100644
index 000000000..fd51d5317
--- /dev/null
+++ b/tests/core/test_custom_scores.py
@@ -0,0 +1,1728 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+import json
+import os
+from collections import Counter
+from dataclasses import replace
+from pathlib import Path
+from types import SimpleNamespace
+
+import numpy as np
+import pandas as pd
+import pytest
+from biotite.structure.io import pdbx
+
+from plinder.core import release
+from plinder.core.scores import custom
+from plinder.core.scores.entries import (
+ ChainView,
+ EntryView,
+ InterfaceView,
+ LigandView,
+ SystemView,
+)
+
+
+def test_custom_chain_similarity_scores_keep_each_alignment(tmp_path):
+ hits = {}
+ for backend, rows in {
+ "mmseqs": [
+ ("1abc", "A", 0.8, 0.5, 0.75, "ACDE", "ACDF"),
+ ("1abc", "A", 0.6, 0.4, 0.5, "AC-E", "ACDE"),
+ ],
+ "foldseek": [("2def", "B", 0.9, 0.8, 0.5, "AAAA", "AATA")],
+ }.items():
+ path = tmp_path / f"{backend}.parquet"
+ frame = pd.DataFrame(
+ [
+ {
+ "sequence_id": "generated-placeholder",
+ "query_id": "model2" if backend == "foldseek" else "model",
+ "query_chain_id": (
+ "model2__A" if backend == "foldseek" else "model__A"
+ ),
+ "structure_id": "model2" if backend == "foldseek" else "model",
+ "query_chain_asym_id": "A",
+ "target_entry": entry,
+ "target_chain_asym_id": chain,
+ "source": backend,
+ "qcov": qcov,
+ "tcov": tcov,
+ "fident": fident,
+ "qaln": qaln,
+ "taln": taln,
+ **({"lddt": 0.7} if backend == "foldseek" else {}),
+ }
+ for entry, chain, qcov, tcov, fident, qaln, taln in rows
+ ]
+ )
+ frame.to_parquet(path, index=False)
+ hits[backend] = path
+
+ manifest = tmp_path / "query_chains.parquet"
+ pd.DataFrame(
+ {
+ "query_id": ["model", "model2"],
+ "sequence_id": ["original-first", "original-second"],
+ }
+ ).to_parquet(manifest, index=False)
+ output = custom.write_custom_chain_similarity_scores(
+ hits,
+ output_path=tmp_path / "chain_scores.parquet",
+ chain_manifest=manifest,
+ )
+ scores = pd.read_parquet(output)
+ assert len(scores) == 3
+ assert scores["qcov"].tolist() == [80, 60, 90]
+ assert scores["fident"].tolist() == [75, 50, 50]
+ assert scores["sequence_id"].tolist() == [
+ "original-first",
+ "original-first",
+ "original-second",
+ ]
+ assert scores["lddt"].isna().tolist() == [True, True, False]
+ assert scores.iloc[2]["lddt"] == 70
+
+ empty = tmp_path / "empty.parquet"
+ pd.DataFrame().to_parquet(empty, index=False)
+ empty_output = custom.write_custom_chain_similarity_scores(
+ {"mmseqs": empty}, output_path=tmp_path / "empty_scores.parquet"
+ )
+ assert pd.read_parquet(empty_output).empty
+
+
+def test_custom_chain_similarity_scores_round_half_up(tmp_path):
+ hits = tmp_path / "hits.parquet"
+ pd.DataFrame(
+ {
+ "query_id": ["model"],
+ "query_chain_id": ["model__A"],
+ "structure_id": ["model"],
+ "query_chain_asym_id": ["A"],
+ "target_entry": ["1abc"],
+ "target_chain_asym_id": ["B"],
+ "source": ["mmseqs"],
+ "qcov": [0.625],
+ "tcov": [0.125],
+ "fident": [0.125],
+ "qaln": ["ACDE"],
+ "taln": ["ACDF"],
+ }
+ ).to_parquet(hits, index=False)
+
+ output = custom.write_custom_chain_similarity_scores(
+ {"mmseqs": hits}, output_path=tmp_path / "scores.parquet"
+ )
+
+ scores = pd.read_parquet(output)
+ assert scores.loc[0, ["qcov", "tcov", "fident"]].tolist() == [63, 13, 13]
+
+
+def _write_database_prefix(prefix: Path, *, indexed: bool = False) -> None:
+ prefix.parent.mkdir(parents=True, exist_ok=True)
+ prefix.with_suffix(".dbtype").write_bytes(b"db")
+ if indexed:
+ Path(f"{prefix}.idx.dbtype").write_bytes(b"index")
+
+
+def _write_search_bundle(root: Path, backend: str) -> None:
+ root.mkdir(parents=True, exist_ok=True)
+ contract = {
+ "identity": 1.0,
+ "coverage": 1.0,
+ "coverage_mode": 0,
+ "compressed_search_target": False,
+ }
+ if backend == "foldseek":
+ manifest = {
+ **contract,
+ "alignment_type": backend,
+ "portable": True,
+ "search_target": "clustered",
+ "conversion_target": "clustered",
+ }
+ _write_database_prefix(root / "clustered", indexed=True)
+ else:
+ manifest = {
+ **contract,
+ "alignment_type": backend,
+ "portable": True,
+ "search_target": "representatives",
+ "conversion_target": root.name,
+ "cluster_alignments": "cluster_alignments",
+ }
+ _write_database_prefix(root / "representatives", indexed=True)
+ _write_database_prefix(root / root.name)
+ _write_database_prefix(root / "cluster_alignments")
+ (root / "exact_cluster.json").write_text(json.dumps(manifest))
+
+
+def _write_index(root: Path) -> None:
+ index = root / "index"
+ index.mkdir(parents=True, exist_ok=True)
+ for filename in [
+ "annotation_table.parquet",
+ "entry_chains.parquet",
+ "interface_annotation_table.parquet",
+ "alignment_chain_lookup.parquet",
+ ]:
+ (index / filename).touch()
+
+
+def test_resolve_custom_scoring_assets_accepts_ingest_layout(tmp_path):
+ _write_index(tmp_path)
+ for backend in custom.SEARCH_BACKENDS:
+ _write_search_bundle(tmp_path / "dbs" / "subdbs" / f"holo_{backend}", backend)
+ archive = tmp_path / "ligand_archives" / "ab.parquet"
+ archive.parent.mkdir()
+ archive.touch()
+
+ assets = custom.resolve_custom_scoring_assets(
+ data_dir=tmp_path,
+ ligand_pdb_ids=["1abc", "2abd__1__1.A__1.L"],
+ )
+
+ assert assets.annotation_table == tmp_path / "index/annotation_table.parquet"
+ assert assets.search_databases["foldseek"].search_target.name == "clustered"
+ assert assets.search_databases["mmseqs"].cluster_alignments is not None
+ assert assets.ligand_archives == {"ab": archive}
+
+
+def test_resolve_custom_scoring_assets_includes_monomer_targets(tmp_path):
+ _write_index(tmp_path)
+ for backend in custom.SEARCH_BACKENDS:
+ _write_search_bundle(tmp_path / "search_databases" / f"holo_{backend}", backend)
+ _write_search_bundle(
+ tmp_path / "search_databases" / f"monomer_{backend}", backend
+ )
+
+ assets = custom.resolve_custom_scoring_assets(
+ data_dir=tmp_path, include_monomers=True
+ )
+ assert set(assets.monomer_search_databases) == set(custom.SEARCH_BACKENDS)
+ assert (
+ assets.monomer_search_databases["mmseqs"].conversion_target.name
+ == "monomer_mmseqs"
+ )
+
+
+def test_resolve_custom_scoring_assets_skips_missing_monomer_targets(tmp_path):
+ _write_index(tmp_path)
+ for backend in custom.SEARCH_BACKENDS:
+ _write_search_bundle(tmp_path / "search_databases" / f"holo_{backend}", backend)
+ _write_search_bundle(tmp_path / "search_databases" / "monomer_mmseqs", "mmseqs")
+
+ assets = custom.resolve_custom_scoring_assets(
+ data_dir=tmp_path, include_monomers=True
+ )
+
+ assert set(assets.search_databases) == set(custom.SEARCH_BACKENDS)
+ assert set(assets.monomer_search_databases) == {"mmseqs"}
+
+
+def test_remote_resolution_requests_only_bounded_assets(tmp_path, monkeypatch):
+ _write_index(tmp_path)
+ for backend in custom.SEARCH_BACKENDS:
+ _write_search_bundle(tmp_path / "search_databases" / f"holo_{backend}", backend)
+ archive = tmp_path / "ligand_archives" / "xy.parquet"
+ archive.parent.mkdir()
+ archive.touch()
+ requested: list[str] = []
+
+ def get_plinder_path(*, rel: str) -> Path:
+ requested.append(rel)
+ return tmp_path / rel
+
+ monkeypatch.setattr(release.cpl, "get_plinder_path", get_plinder_path)
+
+ assets = custom.resolve_custom_scoring_assets(ligand_pdb_ids=["3xyz"])
+
+ assert set(requested) == {
+ "index/annotation_table.parquet",
+ "index/entry_chains.parquet",
+ "index/interface_annotation_table.parquet",
+ "index/alignment_chain_lookup.parquet",
+ "search_databases/holo_foldseek",
+ "search_databases/holo_mmseqs",
+ "search_databases/weekly_delta/holo_foldseek",
+ "search_databases/weekly_delta/holo_mmseqs",
+ "search_databases/shadowed_entries.parquet",
+ "ligand_archives/xy.parquet",
+ }
+ assert assets.ligand_archives == {"xy": archive}
+
+
+def test_resolve_custom_scoring_assets_includes_weekly_search_overlay(tmp_path):
+ _write_index(tmp_path)
+ for backend in custom.SEARCH_BACKENDS:
+ _write_search_bundle(tmp_path / "search_databases" / f"holo_{backend}", backend)
+ overlay = tmp_path / "search_databases/weekly_delta/holo_mmseqs"
+ _write_search_bundle(overlay, "mmseqs")
+ pd.DataFrame({"pdb_id": ["1abc"]}).to_parquet(
+ tmp_path / "search_databases/shadowed_entries.parquet", index=False
+ )
+ assets = custom.resolve_custom_scoring_assets(data_dir=tmp_path)
+
+ assert assets.shadowed_entries == {"1abc"}
+ assert assets.overlay_search_databases["mmseqs"].root == overlay
+
+
+def test_custom_search_replaces_shadowed_base_hits_with_overlay(tmp_path, monkeypatch):
+ from plinder.data.annotations import get_similarity_scores
+
+ base_target = tmp_path / "base/clustered"
+ base_target.parent.mkdir()
+ Path(f"{base_target}.lookup").write_text(
+ "0\tpdb_00001abc_xyz-enrich_A\t0\n1\tpdb_00002def_xyz-enrich_A\t0\n"
+ )
+ base_bundle = custom.SearchDatabaseBundle(
+ backend="foldseek",
+ root=base_target.parent,
+ search_target=base_target,
+ conversion_target=base_target,
+ cluster_alignments=None,
+ manifest={},
+ )
+ overlay_target = tmp_path / "overlay/clustered"
+ overlay_target.parent.mkdir()
+ overlay_bundle = replace(
+ base_bundle,
+ root=overlay_target.parent,
+ search_target=overlay_target,
+ conversion_target=overlay_target,
+ )
+ assets = custom.CustomScoringAssets(
+ annotation_table=tmp_path / "annotation.parquet",
+ entry_chains=tmp_path / "chains.parquet",
+ interface_annotations=tmp_path / "interfaces.parquet",
+ alignment_chain_lookup=tmp_path / "lookup.parquet",
+ search_databases={"foldseek": base_bundle},
+ ligand_archives={},
+ overlay_search_databases={"foldseek": overlay_bundle},
+ shadowed_entries=frozenset({"1abc"}),
+ )
+ calls = []
+
+ def fake_alignment(**kwargs):
+ calls.append(kwargs["alignment_config"].max_seqs)
+
+ def fake_mapping(*, raw_alignment, output_path, exclude_target_entries, **_kwargs):
+ entries = (
+ ["1abc"] if raw_alignment.stem.endswith("overlay") else ["1abc", "2def"]
+ )
+ entries = [entry for entry in entries if entry not in exclude_target_entries]
+ pd.DataFrame({"target_entry": entries}).to_parquet(output_path, index=False)
+
+ monkeypatch.setattr(get_similarity_scores, "run_alignment", fake_alignment)
+ monkeypatch.setattr(custom, "map_custom_alignment_hits", fake_mapping)
+ result = custom.run_custom_protein_searches(
+ query_databases=SimpleNamespace(databases={"foldseek": tmp_path / "query"}),
+ assets=assets,
+ output_dir=tmp_path / "results",
+ scratch_dir=tmp_path / "scratch",
+ config=custom.CustomProteinSearchConfig(max_seqs=10),
+ backends=("foldseek",),
+ )
+
+ assert calls == [11, 10]
+ assert pd.read_parquet(result["foldseek"])["target_entry"].tolist() == [
+ "2def",
+ "1abc",
+ ]
+
+
+def test_ligand_coordinates_are_not_resolved_before_targets_are_known(
+ tmp_path, monkeypatch
+):
+ _write_index(tmp_path)
+ for backend in custom.SEARCH_BACKENDS:
+ _write_search_bundle(tmp_path / "search_databases" / f"holo_{backend}", backend)
+ requested: list[str] = []
+
+ def get_plinder_path(*, rel: str) -> Path:
+ requested.append(rel)
+ return tmp_path / rel
+
+ monkeypatch.setattr(release.cpl, "get_plinder_path", get_plinder_path)
+
+ assets = custom.resolve_custom_scoring_assets()
+
+ assert assets.ligand_archives == {}
+ assert not any(path.startswith("ligand_archives/") for path in requested)
+
+
+def test_search_database_does_not_require_build_manifest(tmp_path):
+ root = tmp_path / "search_databases" / "holo_foldseek"
+ _write_search_bundle(root, "foldseek")
+ (root / "exact_cluster.json").unlink()
+
+ bundle = custom.resolve_search_database("foldseek", data_dir=tmp_path)
+ assert bundle.search_target == root / "clustered"
+
+
+def test_search_database_requires_indexed_target(tmp_path):
+ root = tmp_path / "search_databases" / "holo_foldseek"
+ _write_search_bundle(root, "foldseek")
+ (root / "clustered.idx.dbtype").unlink()
+
+ with pytest.raises(FileNotFoundError, match="indexed"):
+ custom.resolve_search_database("foldseek", data_dir=tmp_path)
+
+
+def test_search_database_rejects_nested_external_link(tmp_path):
+ root = tmp_path / "search_databases" / "holo_foldseek"
+ _write_search_bundle(root, "foldseek")
+ outside = tmp_path / "outside"
+ outside.write_text("external")
+ nested = root / "nested"
+ nested.mkdir()
+ (nested / "external").symlink_to(outside)
+
+ with pytest.raises(ValueError, match="non-portable database link"):
+ custom.resolve_search_database("foldseek", data_dir=tmp_path)
+
+
+def test_search_database_rejects_absolute_internal_link(tmp_path):
+ root = tmp_path / "search_databases" / "holo_foldseek"
+ _write_search_bundle(root, "foldseek")
+ (root / "absolute").symlink_to((root / "clustered.dbtype").resolve())
+
+ with pytest.raises(ValueError, match="non-portable database link"):
+ custom.resolve_search_database("foldseek", data_dir=tmp_path)
+
+
+def test_missing_offline_asset_has_actionable_error(tmp_path, monkeypatch):
+ monkeypatch.setattr(release.cpl, "is_offline", lambda: True)
+
+ with pytest.raises(FileNotFoundError, match="offline cache"):
+ custom.resolve_custom_scoring_assets(data_dir=tmp_path, backends=())
+
+
+def test_write_custom_query_files_uses_protein_label_asym_ids(test_dir, tmp_path):
+ cif = test_dir / "interfaces/cm/pdb_00007cma/pdb_00007cma_xyz-enrich.cif.gz"
+
+ inputs = custom.write_custom_query_files([cif], work_dir=tmp_path)
+ chains = pd.read_parquet(inputs.chain_manifest)
+
+ assert chains["chain_asym_id"].tolist() == ["A", "B"]
+ assert chains["query_id"].tolist() == ["cq00000000", "cq00000001"]
+ assert chains["query_chain_id"].tolist() == [
+ "pdb_00007cma_xyz-enrich__A",
+ "pdb_00007cma_xyz-enrich__B",
+ ]
+ assert chains["sequence_length"].min() >= 12
+ assert set(chains["sequence_source"]) == {"polymer"}
+ assert len(list(inputs.chain_cif_dir.glob("*.cif"))) == 2
+ assert inputs.sequence_fasta.read_text().count(">cq") == 2
+ block = list(
+ pdbx.CIFFile.read(str(inputs.chain_cif_dir / "cq00000000.cif")).values()
+ )[0]
+ assert {
+ "entry",
+ "entity",
+ "entity_poly",
+ "entity_poly_seq",
+ "chem_comp",
+ "struct_asym",
+ "atom_site",
+ }.issubset(block)
+ assert set(block["atom_site"]["label_asym_id"].as_array(str)).issubset(
+ block["struct_asym"]["id"].as_array(str)
+ )
+ assert set(block["atom_site"]["label_entity_id"].as_array(str)).issubset(
+ block["entity"]["id"].as_array(str)
+ )
+ assert set(block["entity_poly_seq"]["mon_id"].as_array(str)).issubset(
+ block["chem_comp"]["id"].as_array(str)
+ )
+
+
+def test_write_custom_sequence_query_files_preserves_fasta_ids(tmp_path):
+ source = tmp_path / "queries.faa"
+ source.write_text(
+ ">sample.with_symbols description\nACDEFGHIKLMNPQ\n"
+ ">second_sample\nRSTVWYACDEFGHI\n"
+ )
+
+ inputs = custom.write_custom_sequence_query_files(
+ source,
+ work_dir=tmp_path / "work",
+ )
+ manifest = pd.read_parquet(inputs.chain_manifest)
+
+ assert manifest["query_id"].tolist() == ["cq00000000", "cq00000001"]
+ assert manifest["structure_id"].tolist() == ["cq00000000", "cq00000001"]
+ assert manifest["sequence_id"].tolist() == [
+ "sample.with_symbols",
+ "second_sample",
+ ]
+ assert manifest["chain_asym_id"].tolist() == ["A", "A"]
+ assert manifest["sequence_source"].tolist() == ["polymer", "polymer"]
+ assert inputs.sequence_fasta.read_text().splitlines()[::2] == [
+ ">cq00000000",
+ ">cq00000001",
+ ]
+ assert not list(inputs.chain_cif_dir.iterdir())
+
+
+def test_write_custom_sequence_query_files_rejects_duplicate_fasta_ids(tmp_path):
+ source = tmp_path / "queries.faa"
+ source.write_text(
+ ">repeated\nACDEFGHIKLMNPQ\n>repeated duplicate\nRSTVWYACDEFGHI\n"
+ )
+
+ with pytest.raises(ValueError, match="repeats identifiers: \\['repeated'\\]"):
+ custom.write_custom_sequence_query_files(
+ source,
+ work_dir=tmp_path / "work",
+ )
+
+
+def test_write_custom_query_files_accepts_coordinate_only_mmcif(test_dir, tmp_path):
+ from plinder.data.annotations.cif_utils import read_mmcif_file
+
+ source = test_dir / "interfaces/cm/pdb_00007cma/pdb_00007cma_xyz-enrich.cif.gz"
+ cif_file = read_mmcif_file(source)
+ block = list(cif_file.values())[0]
+ for category_name in list(block):
+ if category_name != "atom_site":
+ del block[category_name]
+ del block["atom_site"]["pdbx_PDB_model_num"]
+ del block["atom_site"]["pdbx_PDB_ins_code"]
+ coordinate_only = tmp_path / "coordinate_only.cif"
+ cif_file.write(str(coordinate_only))
+
+ inputs = custom.write_custom_query_files(
+ [coordinate_only], work_dir=tmp_path / "work"
+ )
+ chains = pd.read_parquet(inputs.chain_manifest)
+
+ assert chains["chain_asym_id"].tolist() == ["A", "B"]
+ assert set(chains["sequence_source"]) == {"coordinates"}
+ output = pdbx.CIFFile.read(str(inputs.chain_cif_dir / "cq00000000.cif"))
+ output_block = list(output.values())[0]
+ assert set(output_block["entity_poly_seq"]["num"].as_array(int)) == set(
+ range(1, int(chains.loc[0, "sequence_length"]) + 1)
+ )
+ assert np.min(output_block["atom_site"]["label_seq_id"].as_array(int)) == 1
+
+
+def test_write_custom_query_files_reports_missing_coordinate_fields(test_dir, tmp_path):
+ from plinder.data.annotations.cif_utils import read_mmcif_file
+
+ source = test_dir / "interfaces/cm/pdb_00007cma/pdb_00007cma_xyz-enrich.cif.gz"
+ cif_file = read_mmcif_file(source)
+ del list(cif_file.values())[0]["atom_site"]["Cartn_z"]
+ invalid = tmp_path / "missing_z.cif"
+ cif_file.write(str(invalid))
+
+ with pytest.raises(ValueError, match=r"_atom_site\.Cartn_z"):
+ custom.write_custom_query_files([invalid], work_dir=tmp_path / "work")
+
+
+def test_write_pdb_query_files_reports_missing_assembly_fields(test_dir, tmp_path):
+ from plinder.data.annotations.cif_utils import read_mmcif_file
+
+ source = test_dir / "interfaces/cm/pdb_00007cma/pdb_00007cma_xyz-enrich.cif.gz"
+ cif_file = read_mmcif_file(source)
+ block = list(cif_file.values())[0]
+ del block["pdbx_struct_assembly_gen"]
+ invalid = tmp_path / "missing_assembly.cif"
+ cif_file.write(str(invalid))
+
+ with pytest.raises(ValueError, match="_pdbx_struct_assembly_gen"):
+ custom.write_custom_query_files(
+ [invalid],
+ work_dir=tmp_path / "work",
+ structure_mode="pdb",
+ )
+
+
+def test_write_pdb_query_files_deduplicates_assembly_copies(test_dir, tmp_path):
+ cif = test_dir / "interfaces/cm/pdb_00007cm8/pdb_00007cm8_xyz-enrich.cif.gz"
+
+ inputs = custom.write_custom_query_files(
+ [cif],
+ work_dir=tmp_path,
+ structure_mode="pdb",
+ assembly_ids=["1"],
+ )
+ chains = pd.read_parquet(inputs.chain_manifest)
+
+ assert chains["chain_asym_id"].tolist() == ["A"]
+ assert chains["query_id"].tolist() == ["cq00000000"]
+
+
+def test_write_custom_query_files_derives_coordinate_only_sequences(
+ test_dir, tmp_path, monkeypatch
+):
+ cif = test_dir / "interfaces/cm/pdb_00007cma/pdb_00007cma_xyz-enrich.cif.gz"
+ monkeypatch.setattr(custom, "_protein_asym_sequences", lambda _block: {})
+
+ inputs = custom.write_custom_query_files([cif], work_dir=tmp_path)
+ chains = pd.read_parquet(inputs.chain_manifest)
+
+ assert chains["chain_asym_id"].tolist() == ["A", "B"]
+ assert chains["sequence_length"].min() >= 12
+ assert set(chains["sequence_source"]) == {"coordinates"}
+
+
+def test_annotate_custom_cif_files_writes_bonded_ligands(
+ test_dir, tmp_path, monkeypatch
+):
+ import yaml
+ from rdkit import Chem
+
+ from plinder.data.annotations import ligand_utils
+
+ monkeypatch.setattr(ligand_utils, "BINDING_AFFINITY", {})
+
+ cif = test_dir / "custom_cif/boltz_8c3u_input_model_0.cif"
+ config = yaml.safe_load((test_dir / "custom_cif/boltz_8c3u_input.yaml").read_text())
+ smiles = next(
+ sequence["ligand"]["smiles"]
+ for sequence in config["sequences"]
+ if "ligand" in sequence
+ )
+
+ annotations = custom.annotate_custom_cif_files(
+ [cif],
+ work_dir=tmp_path,
+ ligand_smiles_dict={"LIG": smiles},
+ include_interfaces=False,
+ )
+
+ assert set(annotations.entries_by_structure) == {"boltz_8c3u_input_model_0"}
+ assert not pd.read_parquet(annotations.annotation_table).empty
+ assert not pd.read_parquet(annotations.entry_chains).empty
+ ligand_files = sorted(annotations.ligand_sdf_root.rglob("*.sdf"))
+ assert ligand_files
+ molecules = [
+ Chem.MolFromMolFile(str(path), sanitize=False, removeHs=False)
+ for path in ligand_files
+ ]
+ assert all(molecule is not None for molecule in molecules)
+ assert any(
+ bond.GetBondType() != Chem.BondType.SINGLE
+ for molecule in molecules
+ if molecule is not None
+ for bond in molecule.GetBonds()
+ )
+
+
+def test_annotate_custom_cif_files_keeps_interface_only_entries(test_dir, tmp_path):
+ cif = test_dir / "interfaces/cm/pdb_00007cma/pdb_00007cma_xyz-enrich.cif.gz"
+
+ annotations = custom.annotate_custom_cif_files(
+ [cif],
+ work_dir=tmp_path,
+ include_ligands=False,
+ include_interfaces=True,
+ interface_annotate_prodigy=False,
+ )
+ entry = annotations.entries_by_structure["pdb_00007cma_xyz-enrich"]
+
+ assert not entry.systems
+ assert set(entry.interfaces) == {"pdb_00007cma_xyz-enrich__1__1.A--1.B"}
+ assert not pd.read_parquet(annotations.interface_annotations).empty
+
+
+def test_annotate_custom_cif_files_keeps_protein_only_entries(test_dir, tmp_path):
+ cif = test_dir / "interfaces/cm/pdb_00007cma/pdb_00007cma_xyz-enrich.cif.gz"
+
+ annotations = custom.annotate_custom_cif_files(
+ [cif],
+ work_dir=tmp_path,
+ include_ligands=False,
+ include_interfaces=False,
+ )
+ entry = annotations.entries_by_structure["pdb_00007cma_xyz-enrich"]
+
+ assert not entry.systems
+ assert not entry.interfaces
+ assert {"A", "B"} <= set(entry.chains)
+
+
+def test_create_custom_query_databases_records_backend_identifiers(
+ test_dir, tmp_path, monkeypatch
+):
+ cif = test_dir / "interfaces/cm/pdb_00007cma/pdb_00007cma_xyz-enrich.cif.gz"
+ inputs = custom.write_custom_query_files([cif], work_dir=tmp_path)
+ commands: list[list[str]] = []
+
+ monkeypatch.setattr(custom.shutil, "which", lambda backend: f"/bin/{backend}")
+
+ def fake_run(command: list[str]) -> None:
+ commands.append(command)
+ database = Path(command[3])
+ identifiers = (
+ ["cq00000000_A", "cq00000001_A"]
+ if command[0] == "foldseek"
+ else ["cq00000000", "cq00000001"]
+ )
+ database.with_suffix(".lookup").write_text(
+ "".join(
+ f"{index}\t{identifier}\t0\n"
+ for index, identifier in enumerate(identifiers)
+ )
+ )
+
+ monkeypatch.setattr(custom, "_run_command", fake_run)
+ databases = custom.create_custom_query_databases(
+ inputs,
+ work_dir=tmp_path,
+ threads=3,
+ )
+ identifier_map = pd.read_parquet(databases.identifier_map)
+
+ assert [command[:2] for command in commands] == [
+ ["foldseek", "createdb"],
+ ["mmseqs", "createdb"],
+ ]
+ assert commands[0][commands[0].index("--coord-store-mode") + 1] == "2"
+ assert commands[1][commands[1].index("--threads") + 1] == "3"
+ assert len(identifier_map) == 4
+ assert set(identifier_map["query_id"]) == {"cq00000000", "cq00000001"}
+
+
+def test_create_custom_query_databases_only_requires_selected_backend(
+ test_dir, tmp_path, monkeypatch
+):
+ cif = test_dir / "interfaces/cm/pdb_00007cma/pdb_00007cma_xyz-enrich.cif.gz"
+ inputs = custom.write_custom_query_files([cif], work_dir=tmp_path)
+ executable_checks: list[str] = []
+ commands: list[list[str]] = []
+
+ def which(backend: str) -> str:
+ executable_checks.append(backend)
+ return f"/bin/{backend}"
+
+ def fake_run(command: list[str]) -> None:
+ commands.append(command)
+ database = Path(command[3])
+ database.with_suffix(".lookup").write_text(
+ "0\tcq00000000\t0\n1\tcq00000001\t0\n"
+ )
+
+ monkeypatch.setattr(custom.shutil, "which", which)
+ monkeypatch.setattr(custom, "_run_command", fake_run)
+
+ databases = custom.create_custom_query_databases(
+ inputs,
+ work_dir=tmp_path,
+ backends=["mmseqs"],
+ )
+
+ assert executable_checks == ["mmseqs"]
+ assert [command[0] for command in commands] == ["mmseqs"]
+ assert set(databases.databases) == {"mmseqs"}
+
+
+def test_build_mmseqs_target_subset_uses_selected_scoreable_chains(
+ tmp_path, monkeypatch
+):
+ entry_chains = tmp_path / "entry_chains.parquet"
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "1abc", "1abc", "1abc", "2def"],
+ "chain_asym_id": ["A", "B", "C", "L", "A"],
+ "chain_auth_id": ["X", "I", "Z", "L", "Y"],
+ "chain_receptor_type": [
+ "protein",
+ "protein",
+ "protein",
+ "other",
+ "protein",
+ ],
+ "chain_is_holo": [True, False, False, False, True],
+ "chain_sequence": ["ACDE", "FGHI", "KLMN", "X", "PQRS"],
+ }
+ ).to_parquet(entry_chains, index=False)
+ interface_annotations = tmp_path / "interface_annotations.parquet"
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "interface_chain_1": ["1.A"],
+ "interface_chain_2": ["1.B"],
+ }
+ ).to_parquet(interface_annotations, index=False)
+ commands: list[list[str]] = []
+ monkeypatch.setattr(custom.shutil, "which", lambda _name: "/bin/mmseqs")
+ monkeypatch.setattr(custom, "_run_command", commands.append)
+
+ bundle = custom._build_mmseqs_target_subset(
+ entry_chains,
+ interface_annotations,
+ entry_ids=["1abc"],
+ output_dir=tmp_path / "subset",
+ threads=3,
+ )
+
+ assert bundle.backend == "mmseqs"
+ assert bundle.search_target == bundle.conversion_target
+ assert bundle.cluster_alignments is None
+ assert (bundle.root / "targets.fasta").read_text() == (
+ ">1abc_I\nFGHI\n>1abc_X\nACDE\n"
+ )
+ assert commands == [
+ [
+ "mmseqs",
+ "createdb",
+ str(bundle.root / "targets.fasta"),
+ str(bundle.root / "targets"),
+ "--threads",
+ "3",
+ ]
+ ]
+
+
+def test_plinder_entry_subset_rejects_foldseek(tmp_path):
+ with pytest.raises(ValueError, match="requires backends"):
+ custom._resolve_workflow_assets(
+ data_dir=tmp_path,
+ backends=("foldseek",),
+ plinder_entry_ids=("1abc",),
+ work_dir=tmp_path / "work",
+ threads=1,
+ )
+
+
+def test_map_custom_alignment_hits_maps_query_and_target_chains(tmp_path):
+ input_root = tmp_path / "query_inputs"
+ input_root.mkdir()
+ chain_manifest = input_root / "query_chains.parquet"
+ pd.DataFrame(
+ {
+ "query_id": ["cq00000000"],
+ "query_chain_id": ["model__A"],
+ "structure_id": ["model"],
+ "chain_asym_id": ["A"],
+ "sequence_source": ["polymer"],
+ "resolved_residue_numbers": [[1, 2]],
+ }
+ ).to_parquet(chain_manifest, index=False)
+ inputs = custom.CustomQueryInputs(
+ root=input_root,
+ chain_cif_dir=input_root / "chains",
+ sequence_fasta=input_root / "query.fasta",
+ chain_manifest=chain_manifest,
+ )
+ database_root = tmp_path / "query_databases"
+ database_root.mkdir()
+ identifier_map = database_root / "query_identifier_map.parquet"
+ pd.DataFrame(
+ {
+ "backend": ["foldseek"],
+ "backend_query_id": ["cq00000000_A"],
+ "query_id": ["cq00000000"],
+ }
+ ).to_parquet(identifier_map, index=False)
+ databases = custom.CustomQueryDatabases(
+ root=database_root,
+ inputs=inputs,
+ databases={"foldseek": database_root / "foldseek"},
+ identifier_map=identifier_map,
+ )
+ raw = tmp_path / "raw.parquet"
+ pd.DataFrame(
+ {
+ "query": ["cq00000000_A", "cq00000000_A"],
+ "target": [
+ "pdb_00001abc_xyz-enrich.cif.gz_X",
+ "pdb_00002def_xyz-enrich.cif.gz_OLD",
+ ],
+ "qstart": [1, 1],
+ "tstart": [2, 2],
+ "qcov": [0.8, 0.8],
+ "fident": [0.5, 0.5],
+ "qaln": ["AC", "AC"],
+ "taln": ["AC", "AC"],
+ "lddt": [0.7, 0.7],
+ }
+ ).to_parquet(raw, index=False)
+ lookup = tmp_path / "alignment_chain_lookup.parquet"
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "chain_asym_id": ["B"],
+ "chain_auth_id": ["X"],
+ "selected_residue_numbers": [[2, 4]],
+ "selected_residue_indices": [[1, 3]],
+ }
+ ).to_parquet(lookup, index=False)
+ output = tmp_path / "mapped.parquet"
+
+ custom.map_custom_alignment_hits(
+ raw_alignment=raw,
+ backend="foldseek",
+ query_databases=databases,
+ alignment_chain_lookup=lookup,
+ output_path=output,
+ exclude_target_entries={"2def"},
+ )
+ result = pd.read_parquet(output)
+
+ assert len(result) == 1
+ assert result.loc[0, "query_chain_id"] == "model__A"
+ assert result.loc[0, "target_entry"] == "1abc"
+ assert result.loc[0, "target_chain_asym_id"] == "B"
+ assert result.loc[0, "source"] == "foldseek"
+ assert result.loc[0, "query_sequence_source"] == "polymer"
+ assert result.loc[0, "query_resolved_residue_numbers"].tolist() == [1, 2]
+ assert result.loc[0, "target_selected_residue_numbers"].tolist() == [2, 4]
+
+
+def test_custom_search_defaults_keep_coverage_and_disable_identity_filter():
+ config = custom.CustomProteinSearchConfig()
+
+ assert config.max_seqs == 10_000
+ assert config.coverage == 0.0
+ assert config.min_seq_id == 0.0
+ for backend in ("foldseek", "mmseqs", "steam"):
+ assert config.evalue_for(backend) == 0.01
+
+
+def test_custom_search_backend_evalues():
+ config = custom.CustomProteinSearchConfig(
+ foldseek_evalue=0.001, mmseqs_evalue=0.1, steam_evalue=1.0
+ )
+ assert config.evalue_for("foldseek") == 0.001
+ assert config.evalue_for("mmseqs") == 0.1
+ assert config.evalue_for("steam") == 1.0
+ assert custom.CustomProteinSearchConfig(evalue=0.5).evalue_for("steam") == 0.5
+
+
+@pytest.mark.parametrize(
+ "field", ["evalue", "foldseek_evalue", "mmseqs_evalue", "steam_evalue"]
+)
+@pytest.mark.parametrize("value", [-1.0, float("nan")])
+def test_custom_search_rejects_invalid_evalues(field, value):
+ with pytest.raises(ValueError, match="E-values must be nonnegative"):
+ custom.CustomProteinSearchConfig(**{field: value})
+
+
+def test_custom_protein_searches_against_local_release(test_dir, tmp_path):
+ data_dir_value = os.environ.get("PLINDER_CUSTOM_SEARCH_SMOKE_DATA_DIR")
+ if data_dir_value is None:
+ pytest.skip("local V3 search databases were not requested")
+ data_dir = Path(data_dir_value)
+ search_databases: dict[str, custom.SearchDatabaseBundle] = {}
+ for backend in custom.SEARCH_BACKENDS:
+ root = data_dir / "dbs/subdbs" / f"holo_{backend}"
+ manifest = json.loads((root / "exact_cluster.json").read_text())
+ search_databases[backend] = custom.SearchDatabaseBundle(
+ backend=backend,
+ root=root,
+ search_target=root / str(manifest["search_target"]),
+ conversion_target=root / str(manifest["conversion_target"]),
+ cluster_alignments=(
+ root / str(manifest["cluster_alignments"])
+ if backend == "mmseqs"
+ else None
+ ),
+ manifest=manifest,
+ )
+ assets = custom.CustomScoringAssets(
+ annotation_table=data_dir / "index/annotation_table.parquet",
+ entry_chains=data_dir / "index/entry_chains.parquet",
+ interface_annotations=data_dir / "index/interface_annotation_table.parquet",
+ alignment_chain_lookup=data_dir / "index/alignment_chain_lookup.parquet",
+ search_databases=search_databases,
+ ligand_archives={},
+ )
+ cif = test_dir / "interfaces/cm/pdb_00007cma/pdb_00007cma_xyz-enrich.cif.gz"
+ inputs = custom.write_custom_query_files([cif], work_dir=tmp_path)
+ databases = custom.create_custom_query_databases(
+ inputs,
+ work_dir=tmp_path,
+ threads=4,
+ )
+
+ outputs = custom.run_custom_protein_searches(
+ query_databases=databases,
+ assets=assets,
+ output_dir=tmp_path / "hits",
+ scratch_dir=tmp_path / "scratch",
+ config=custom.CustomProteinSearchConfig(max_seqs=100),
+ threads=4,
+ )
+
+ assert set(outputs) == set(custom.SEARCH_BACKENDS)
+ for output in outputs.values():
+ hits = pd.read_parquet(output)
+ assert set(hits["query_chain_asym_id"]) == {"A", "B"}
+ assert "7cma" in set(hits["target_entry"])
+
+
+@pytest.mark.parametrize(
+ ("backend", "query_number", "target_numbers", "target_indices"),
+ [
+ ("foldseek", 10, [20], [1]),
+ ("mmseqs", 2, [2], [1]),
+ ],
+)
+def test_prepare_custom_score_alignments_maps_selected_residues(
+ tmp_path,
+ backend,
+ query_number,
+ target_numbers,
+ target_indices,
+):
+ query_ligand = LigandView(
+ id="model__1__1.L",
+ pdb_id="model",
+ system_id="model__1__1.A__1.L",
+ instance_chain="1.L",
+ asym_id="L",
+ is_proper=True,
+ protein_chains_asym_id=["1.A"],
+ num_pocket_residues=1,
+ num_interactions=0,
+ num_unique_interactions=0,
+ pocket_residue_number_to_index={"1.A": {query_number: 1}},
+ )
+ query_system = SystemView(
+ id=query_ligand.system_id,
+ pdb_id="model",
+ system_type="holo",
+ protein_chains_asym_id=["1.A"],
+ proper_num_pocket_residues=1,
+ proper_num_interactions=0,
+ proper_num_unique_interactions=0,
+ pocket_residue_number_to_index={"1.A": {query_number: 1}},
+ ligands={"1.L": query_ligand},
+ )
+ query_entry = EntryView(
+ pdb_id="model",
+ chains={"A": ChainView(asym_id="A", auth_id="A", length=2)},
+ systems={query_system.id: query_system},
+ author_to_asym={"A": "A"},
+ )
+ hit_path = tmp_path / f"{backend}_hits.parquet"
+ row = {
+ "structure_id": "model",
+ "query_chain_asym_id": "A",
+ "target_entry": "1abc",
+ "target_chain_asym_id": "B",
+ "target_selected_residue_numbers": target_numbers,
+ "target_selected_residue_indices": target_indices,
+ "qstart": 1,
+ "tstart": 1,
+ "qcov": 1.0,
+ "fident": 1.0,
+ "cigar": "2M",
+ "qaln": "AC",
+ "taln": "AC",
+ }
+ if backend == "foldseek":
+ row["lddt"] = 0.9
+ else:
+ row["query_sequence_source"] = "polymer"
+ row["query_resolved_residue_numbers"] = [1, 2]
+ pd.DataFrame([row]).to_parquet(hit_path, index=False)
+
+ outputs = custom.prepare_custom_score_alignments(
+ {backend: hit_path},
+ entries_by_structure={"model": query_entry},
+ output_dir=tmp_path / "score_alignments",
+ )
+ result = pd.read_parquet(outputs[backend])
+
+ assert result.loc[0, "query_entry"] == "model"
+ assert result.loc[0, "query_chain_mapped"] == "A"
+ assert result.loc[0, "target_chain_mapped"] == "B"
+ assert result.loc[0, "query_selected_residue_numbers"].tolist() == [query_number]
+ assert result.loc[0, "target_selected_residue_numbers"].tolist() == [
+ target_numbers[0]
+ ]
+ assert result.loc[0, "selected_residue_identity_bits"] == b"\x01"
+ assert result.loc[0, "seqsim"] == pytest.approx(1.0)
+
+
+@pytest.mark.parametrize(
+ ("backend", "target_numbers", "target_indices", "custom_number"),
+ [
+ ("foldseek", [20], [1], 200),
+ ("mmseqs", [2], [1], 2),
+ ],
+)
+def test_prepare_custom_protein_score_alignments_reverses_direction(
+ tmp_path,
+ backend,
+ target_numbers,
+ target_indices,
+ custom_number,
+):
+ query_entry = EntryView(
+ pdb_id="model",
+ chains={"A": ChainView(asym_id="A", auth_id="A", length=2)},
+ systems={},
+ author_to_asym={"A": "A"},
+ )
+ hit_path = tmp_path / f"{backend}_hits.parquet"
+ row = {
+ "structure_id": "model",
+ "query_chain_asym_id": "A",
+ "query_sequence_source": "polymer",
+ "query_resolved_residue_numbers": [100, 200],
+ "target_entry": "1abc",
+ "target_chain_asym_id": "B",
+ "target_selected_residue_numbers": target_numbers,
+ "target_selected_residue_indices": target_indices,
+ "qstart": 1,
+ "tstart": 1,
+ "qcov": 0.5,
+ "tcov": 0.75,
+ "fident": 1.0,
+ "qaln": "AC",
+ "taln": "AC",
+ }
+ if backend == "foldseek":
+ row["lddt"] = 0.9
+ pd.DataFrame([row]).to_parquet(hit_path, index=False)
+
+ outputs = custom.prepare_custom_protein_score_alignments(
+ {backend: hit_path},
+ entries_by_structure={"model": query_entry},
+ output_dir=tmp_path / "protein_score_alignments",
+ )
+ result = pd.read_parquet(outputs[backend])
+
+ assert result.loc[0, "query_entry"] == "1abc"
+ assert result.loc[0, "target_entry"] == "model"
+ assert result.loc[0, "query_chain_mapped"] == "B"
+ assert result.loc[0, "target_chain_mapped"] == "A"
+ assert result.loc[0, "qcov"] == pytest.approx(0.75)
+ assert result.loc[0, "tcov"] == pytest.approx(0.5)
+ assert result.loc[0, "query_selected_residue_numbers"].tolist() == [
+ target_numbers[0]
+ ]
+ assert result.loc[0, "target_selected_residue_numbers"].tolist() == [custom_number]
+ assert result.loc[0, "selected_residue_identity_bits"] == b"\x01"
+ assert result.loc[0, "fident_qcov"] == pytest.approx(0.75)
+ assert "cigar" not in result
+
+
+def test_prepare_custom_score_alignments_maps_coordinate_fasta_positions(tmp_path):
+ query_ligand = LigandView(
+ id="model__1__1.L",
+ pdb_id="model",
+ system_id="model__1__1.A__1.L",
+ instance_chain="1.L",
+ asym_id="L",
+ is_proper=True,
+ protein_chains_asym_id=["1.A"],
+ num_pocket_residues=1,
+ num_interactions=0,
+ num_unique_interactions=0,
+ pocket_residue_number_to_index={"1.A": {40: 2}},
+ )
+ query_system = SystemView(
+ id=query_ligand.system_id,
+ pdb_id="model",
+ system_type="holo",
+ protein_chains_asym_id=["1.A"],
+ proper_num_pocket_residues=1,
+ proper_num_interactions=0,
+ proper_num_unique_interactions=0,
+ pocket_residue_number_to_index={"1.A": {40: 2}},
+ ligands={"1.L": query_ligand},
+ )
+ query_entry = EntryView(
+ pdb_id="model",
+ chains={"A": ChainView(asym_id="A", auth_id="A", length=3)},
+ systems={query_system.id: query_system},
+ author_to_asym={"A": "A"},
+ )
+ hit_path = tmp_path / "mmseqs_hits.parquet"
+ pd.DataFrame(
+ [
+ {
+ "structure_id": "model",
+ "query_chain_asym_id": "A",
+ "query_sequence_source": "coordinates",
+ "query_resolved_residue_numbers": [10, 20, 40],
+ "target_entry": "1abc",
+ "target_chain_asym_id": "B",
+ "target_selected_residue_numbers": [3],
+ "target_selected_residue_indices": [2],
+ "qstart": 1,
+ "tstart": 1,
+ "qcov": 1.0,
+ "fident": 1.0,
+ "qaln": "ACD",
+ "taln": "ACD",
+ }
+ ]
+ ).to_parquet(hit_path, index=False)
+
+ outputs = custom.prepare_custom_score_alignments(
+ {"mmseqs": hit_path},
+ entries_by_structure={"model": query_entry},
+ output_dir=tmp_path / "score_alignments",
+ )
+ result = pd.read_parquet(outputs["mmseqs"])
+
+ assert result.loc[0, "query_selected_residue_numbers"].tolist() == [40]
+ assert result.loc[0, "target_selected_residue_numbers"].tolist() == [3]
+ assert result.loc[0, "selected_residue_identity_bits"] == b"\x01"
+
+
+def _scoring_entry(
+ *,
+ pdb_id: str,
+ chain_id: str,
+ ligand_id: str,
+ ligand_chain: str,
+ pocket_number: int,
+ interaction: bool = False,
+) -> EntryView:
+ system_id = f"{pdb_id}__1__1.{chain_id}__1.{ligand_chain}"
+ ligand = LigandView(
+ id=ligand_id,
+ pdb_id=pdb_id,
+ system_id=system_id,
+ instance_chain=f"1.{ligand_chain}",
+ asym_id=ligand_chain,
+ is_proper=True,
+ protein_chains_asym_id=[f"1.{chain_id}"],
+ num_pocket_residues=1,
+ num_interactions=int(interaction),
+ num_unique_interactions=int(interaction),
+ pocket_residue_number_to_index={f"1.{chain_id}": {pocket_number: 1}},
+ interactions_counter=(
+ {f"1.{chain_id}": {pocket_number: Counter({"hydrogen_bond": 1})}}
+ if interaction
+ else {}
+ ),
+ )
+ system = SystemView(
+ id=system_id,
+ pdb_id=pdb_id,
+ system_type="holo",
+ protein_chains_asym_id=[f"1.{chain_id}"],
+ proper_num_pocket_residues=1,
+ proper_num_interactions=0,
+ proper_num_unique_interactions=0,
+ pocket_residue_number_to_index={f"1.{chain_id}": {pocket_number: 1}},
+ ligands={ligand.instance_chain: ligand},
+ )
+ return EntryView(
+ pdb_id=pdb_id,
+ chains={chain_id: ChainView(asym_id=chain_id, auth_id=chain_id, length=2)},
+ systems={system_id: system},
+ author_to_asym={chain_id: chain_id},
+ )
+
+
+def _custom_annotations(tmp_path, entry):
+ root = tmp_path / "custom_annotations"
+ ligand_root = root / "ligands"
+ ligand_root.mkdir(parents=True)
+ return custom.CustomStructureAnnotations(
+ root=root,
+ ligand_sdf_root=ligand_root,
+ annotation_table=root / "annotation.parquet",
+ entry_chains=root / "chains.parquet",
+ interface_annotations=root / "interfaces.parquet",
+ entries_by_structure={"model": entry},
+ )
+
+
+def _custom_assets(tmp_path):
+ return custom.CustomScoringAssets(
+ annotation_table=tmp_path / "release_annotation.parquet",
+ entry_chains=tmp_path / "release_chains.parquet",
+ interface_annotations=tmp_path / "release_interfaces.parquet",
+ alignment_chain_lookup=tmp_path / "release_lookup.parquet",
+ search_databases={},
+ ligand_archives={},
+ )
+
+
+def test_calculate_custom_similarity_scores_reuses_release_metrics(
+ tmp_path, monkeypatch
+):
+ query = _scoring_entry(
+ pdb_id="model",
+ chain_id="A",
+ ligand_id="model__1__1.L",
+ ligand_chain="L",
+ pocket_number=2,
+ )
+ target = _scoring_entry(
+ pdb_id="1abc",
+ chain_id="B",
+ ligand_id="1abc__1__1.Z",
+ ligand_chain="Z",
+ pocket_number=20,
+ )
+ monkeypatch.setattr(
+ custom,
+ "_load_release_entry_views",
+ lambda _assets, *, pdb_ids: {"1abc": target},
+ )
+ alignment = tmp_path / "foldseek.parquet"
+ pd.DataFrame(
+ [
+ {
+ "query_entry": "model",
+ "target_entry": "1abc",
+ "query_chain_mapped": "A",
+ "target_chain_mapped": "B",
+ "source": "foldseek",
+ "qcov": 1.0,
+ "fident": 1.0,
+ "seqsim": 1.0,
+ "lddt": 0.9,
+ "query_selected_residue_numbers": [2],
+ "target_selected_residue_numbers": [20],
+ "selected_residue_identity_bits": b"\x01",
+ }
+ ]
+ ).to_parquet(alignment, index=False)
+
+ scores = custom.calculate_custom_similarity_scores(
+ {"foldseek": alignment},
+ annotations=_custom_annotations(tmp_path, query),
+ assets=_custom_assets(tmp_path),
+ work_dir=tmp_path / "score_work",
+ include_shape=False,
+ )
+
+ pocket = scores.loc[scores["metric"] == "pocket_qcov"]
+ assert len(pocket) == 1
+ assert pocket.iloc[0]["similarity"] == 100
+ assert pocket.iloc[0]["query_ligand_id"] == "model__1__1.L"
+ assert pocket.iloc[0]["target_ligand_id"] == "1abc__1__1.Z"
+ assert scores["metric"].str.startswith("protein_").any()
+
+
+@pytest.mark.parametrize(
+ ("custom_chain", "target_system"),
+ [("A", "model_A"), ("1.A", "model_1.A")],
+)
+def test_calculate_custom_protein_scores_uses_plinder_pocket(
+ tmp_path, monkeypatch, custom_chain, target_system
+):
+ plinder_entry = _scoring_entry(
+ pdb_id="1abc",
+ chain_id="B",
+ ligand_id="1abc__1__1.Z",
+ ligand_chain="Z",
+ pocket_number=20,
+ interaction=True,
+ )
+ monkeypatch.setattr(
+ custom,
+ "_load_release_entry_views",
+ lambda _assets, *, pdb_ids: {"1abc": plinder_entry},
+ )
+ alignment = tmp_path / "reverse_foldseek.parquet"
+ pd.DataFrame(
+ [
+ {
+ "query_entry": "1abc",
+ "target_entry": "model",
+ "query_chain_mapped": "B",
+ "target_chain_mapped": custom_chain,
+ "source": "foldseek",
+ "qcov": 1.0,
+ "fident": 1.0,
+ "seqsim": 1.0,
+ "lddt": 0.9,
+ "query_selected_residue_numbers": [20],
+ "target_selected_residue_numbers": [-1],
+ "selected_residue_identity_bits": b"\x01",
+ }
+ ]
+ ).to_parquet(alignment, index=False)
+
+ scores = custom.calculate_custom_protein_similarity_scores(
+ {"foldseek": alignment},
+ assets=_custom_assets(tmp_path),
+ work_dir=tmp_path / "protein_score_work",
+ custom_chain_ids={target_system},
+ )
+
+ pocket = scores.loc[scores["metric"].astype(str) == "pocket_fident"]
+ assert len(pocket) == 1
+ assert pocket.iloc[0]["similarity"] == 100
+ assert pocket.iloc[0]["query_system"] == "1abc__1__1.B__1.Z"
+ assert pocket.iloc[0]["query_ligand_id"] == "1abc__1__1.Z"
+ assert pocket.iloc[0]["target_system"] == target_system
+ assert pd.isna(pocket.iloc[0]["target_ligand_id"])
+ pli = scores.loc[scores["metric"].astype(str) == "pli_fident"]
+ assert len(pli) == 1
+ assert pli.iloc[0]["similarity"] == 100
+
+
+def test_calculate_custom_protein_scores_reads_alignments_once(tmp_path, monkeypatch):
+ from plinder.data.annotations import get_similarity_scores
+
+ release_entries = {
+ pdb_id: _scoring_entry(
+ pdb_id=pdb_id,
+ chain_id="B",
+ ligand_id=f"{pdb_id}__1__1.Z",
+ ligand_chain="Z",
+ pocket_number=20,
+ )
+ for pdb_id in ["1abc", "2def"]
+ }
+ monkeypatch.setattr(
+ custom,
+ "_load_release_entry_views",
+ lambda _assets, *, pdb_ids: {
+ pdb_id: release_entries[pdb_id] for pdb_id in pdb_ids
+ },
+ )
+ alignment = tmp_path / "reverse_foldseek.parquet"
+ pd.DataFrame(
+ [
+ {
+ "query_entry": pdb_id,
+ "target_entry": "model_with_underscore",
+ "query_chain_mapped": "B",
+ "target_chain_mapped": "A",
+ "source": "foldseek",
+ "qcov": 1.0,
+ "fident": 1.0,
+ "seqsim": 1.0,
+ "lddt": 0.9,
+ "query_selected_residue_numbers": [20],
+ "target_selected_residue_numbers": [-1],
+ "selected_residue_identity_bits": b"\x01",
+ }
+ for pdb_id in release_entries
+ ]
+ ).to_parquet(alignment, index=False)
+ original_load = get_similarity_scores.Scorer.load_alignments
+ load_calls = []
+
+ def counted_load(self, *args, **kwargs):
+ load_calls.append((args, kwargs))
+ return original_load(self, *args, **kwargs)
+
+ monkeypatch.setattr(
+ get_similarity_scores.Scorer,
+ "load_alignments",
+ counted_load,
+ )
+
+ scores = custom.calculate_custom_protein_similarity_scores(
+ {"foldseek": alignment},
+ assets=_custom_assets(tmp_path),
+ work_dir=tmp_path / "protein_score_work",
+ custom_chain_ids={"model_with_underscore_A"},
+ )
+
+ assert len(load_calls) == 1
+ assert set(scores["query_system"]) == {
+ "1abc__1__1.B__1.Z",
+ "2def__1__1.B__1.Z",
+ }
+ assert set(scores["target_system"]) == {"model_with_underscore_A"}
+
+
+def test_write_custom_aligned_pocket_residues(tmp_path, monkeypatch):
+ plinder_entry = _scoring_entry(
+ pdb_id="1abc",
+ chain_id="B",
+ ligand_id="1abc__1__1.Z",
+ ligand_chain="Z",
+ pocket_number=20,
+ )
+ system = next(iter(plinder_entry.systems.values()))
+ ligand = next(iter(system.ligands.values()))
+ plinder_entry.chains["C"] = ChainView(asym_id="C", auth_id="C", length=2)
+ plinder_entry.author_to_asym["C"] = "C"
+ system.protein_chains_asym_id.append("1.C")
+ system.pocket_residue_number_to_index["1.C"] = {30: 1}
+ ligand.protein_chains_asym_id.append("1.C")
+ ligand.pocket_residue_number_to_index["1.C"] = {30: 1}
+ monkeypatch.setattr(
+ custom,
+ "_load_release_entry_views",
+ lambda _assets, *, pdb_ids: {"1abc": plinder_entry},
+ )
+ foldseek_alignment = tmp_path / "reverse_foldseek.parquet"
+ pd.DataFrame(
+ [
+ {
+ "query_entry": "1abc",
+ "target_entry": "model_with_underscore",
+ "query_chain_mapped": "B",
+ "target_chain_mapped": "A",
+ "source": "foldseek",
+ "query_selected_residue_numbers": [20],
+ "target_selected_residue_numbers": [42],
+ "selected_residue_identity_bits": b"\x01",
+ },
+ {
+ "query_entry": "1abc",
+ "target_entry": "model_with_underscore",
+ "query_chain_mapped": "C",
+ "target_chain_mapped": "A",
+ "source": "foldseek",
+ "query_selected_residue_numbers": [30],
+ "target_selected_residue_numbers": [43],
+ "selected_residue_identity_bits": b"\x00",
+ },
+ ]
+ ).to_parquet(foldseek_alignment, index=False)
+ mmseqs_alignment = tmp_path / "reverse_mmseqs.parquet"
+ pd.DataFrame(
+ [
+ {
+ "query_entry": "1abc",
+ "target_entry": "model_with_underscore",
+ "query_chain_mapped": "B",
+ "target_chain_mapped": "A",
+ "source": "mmseqs",
+ "query_selected_residue_numbers": [20],
+ "target_selected_residue_numbers": [142],
+ "selected_residue_identity_bits": b"\x00",
+ }
+ ]
+ ).to_parquet(mmseqs_alignment, index=False)
+ protein_scores = tmp_path / "protein_scores.parquet"
+ pd.DataFrame(
+ [
+ {
+ "query_system": "1abc__1__1.B__1.Z",
+ "query_ligand_id": "1abc__1__1.Z",
+ "target_system": "model_with_underscore_A",
+ "protein_mapping": "1.B:0.A",
+ "source": "foldseek",
+ "metric": "pocket_fident",
+ }
+ ]
+ ).to_parquet(protein_scores, index=False)
+
+ output = custom.write_custom_aligned_pocket_residues(
+ {"foldseek": foldseek_alignment, "mmseqs": mmseqs_alignment},
+ protein_scores=protein_scores,
+ assets=_custom_assets(tmp_path),
+ output_path=tmp_path / "aligned_pocket_residues.parquet",
+ )
+ result = pd.read_parquet(output)
+
+ assert result.to_dict("records") == [
+ {
+ "plinder_system_id": "1abc__1__1.B__1.Z",
+ "plinder_ligand_id": "1abc__1__1.Z",
+ "plinder_entry_id": "1abc",
+ "plinder_chain_instance": "1.B",
+ "plinder_chain_asym_id": "B",
+ "plinder_residue_number": 20,
+ "custom_structure_id": "model_with_underscore",
+ "custom_chain_asym_id": "A",
+ "custom_residue_number": 42,
+ "residue_identical": True,
+ "source": "foldseek",
+ }
+ ]
+
+
+def test_write_custom_sequence_link_tables_adds_ligand_chemistry(tmp_path):
+ manifest = tmp_path / "query_chains.parquet"
+ pd.DataFrame(
+ {
+ "structure_id": ["cq00000000", "cq00000001"],
+ "chain_asym_id": ["A", "A"],
+ "sequence_id": ["sample-1", "sample-2"],
+ "sequence_length": [120, 80],
+ }
+ ).to_parquet(manifest, index=False)
+ protein_scores = tmp_path / "protein_scores.parquet"
+ pd.DataFrame(
+ [
+ {
+ "query_system": "1abc__1__1.B__1.Z",
+ "query_ligand_id": "1abc__1__1.Z",
+ "target_system": "cq00000000_A",
+ "protein_mapping": "1.B:0.A",
+ "protein_mapper": "mmseqs",
+ "source": "mmseqs",
+ "metric": "pocket_fident",
+ "similarity": 75,
+ },
+ {
+ "query_system": "1abc__1__1.B__1.Z",
+ "query_ligand_id": "1abc__1__1.Z",
+ "target_system": "cq00000000_A",
+ "protein_mapping": "1.B:0.A",
+ "protein_mapper": "mmseqs",
+ "source": "mmseqs",
+ "metric": "pli_fident",
+ "similarity": 50,
+ },
+ ]
+ ).to_parquet(protein_scores, index=False)
+ annotation = tmp_path / "annotation.parquet"
+ pd.DataFrame(
+ [
+ {
+ "system_id": "1abc__1__1.B__1.Z",
+ "ligand_id": "1abc__1__1.Z",
+ "ligand_ccd_code": "ATP",
+ "ligand_unique_ccd_code": "ATP",
+ "ligand_smiles": None,
+ },
+ {
+ "system_id": "1abc__1__1.B__1.Z",
+ "ligand_id": "9zzz__1__1.Z",
+ "ligand_ccd_code": "LIG",
+ "ligand_unique_ccd_code": "LIG",
+ "ligand_smiles": "CC",
+ },
+ {
+ "system_id": "1abc__1__1.B__1.Z",
+ "ligand_id": "9zzz__1__1.Z",
+ "ligand_ccd_code": "LIG",
+ "ligand_unique_ccd_code": "LIG",
+ "ligand_smiles": "CCC",
+ },
+ ]
+ ).to_parquet(annotation, index=False)
+
+ links, best = custom.write_custom_sequence_link_tables(
+ protein_scores=protein_scores,
+ chain_manifest=manifest,
+ annotation_table=annotation,
+ output_path=tmp_path / "sequence_links.parquet",
+ best_output_path=tmp_path / "best_sequence_links.parquet",
+ )
+
+ link_rows = pd.read_parquet(links)
+ assert link_rows.loc[0, "sequence_id"] == "sample-1"
+ assert link_rows.loc[0, "plinder_pdb_id"] == "1abc"
+ assert link_rows.loc[0, "plinder_ligand_ccd_code"] == "ATP"
+ assert link_rows.loc[0, "pocket_fident"] == 75
+ assert link_rows.loc[0, "pli_fident"] == 50
+ assert pd.isna(link_rows.loc[0, "plinder_ligand_smiles"])
+ best_rows = pd.read_parquet(best)
+ assert best_rows["sequence_id"].tolist() == ["sample-1", "sample-2"]
+ assert pd.isna(best_rows.loc[1, "plinder_system_id"])
+
+ missing_annotation = tmp_path / "missing_annotation.parquet"
+ missing_chemistry = pd.read_parquet(annotation)
+ missing_chemistry["system_id"] = "9zzz__1__1.B__1.Z"
+ missing_chemistry.to_parquet(missing_annotation, index=False)
+ with pytest.raises(ValueError, match="no row for scored PLINDER ligands"):
+ custom.write_custom_sequence_link_tables(
+ protein_scores=protein_scores,
+ chain_manifest=manifest,
+ annotation_table=missing_annotation,
+ output_path=tmp_path / "missing_sequence_links.parquet",
+ best_output_path=tmp_path / "missing_best_sequence_links.parquet",
+ )
+
+
+def test_add_sequence_ids_to_aligned_pocket_residues(tmp_path):
+ manifest = tmp_path / "query_chains.parquet"
+ pd.DataFrame(
+ {
+ "structure_id": ["cq00000000"],
+ "sequence_id": ["original.sample"],
+ }
+ ).to_parquet(manifest, index=False)
+ residues = tmp_path / "aligned_pocket_residues.parquet"
+ pd.DataFrame(
+ {
+ "custom_structure_id": ["cq00000000"],
+ "custom_residue_number": [42],
+ }
+ ).to_parquet(residues, index=False)
+
+ custom.add_sequence_ids_to_aligned_pocket_residues(
+ residues,
+ chain_manifest=manifest,
+ )
+
+ result = pd.read_parquet(residues)
+ assert result.to_dict("records") == [
+ {
+ "sequence_id": "original.sample",
+ "custom_structure_id": "cq00000000",
+ "custom_residue_number": 42,
+ }
+ ]
+
+
+def test_calculate_custom_interface_scores_uses_compact_maps(tmp_path, monkeypatch):
+ query_interface = InterfaceView(
+ id="model__1__1.A_1.C",
+ pdb_id="model",
+ biounit_id="1",
+ chain_1="1.A",
+ chain_2="1.C",
+ chain_1_residue_number_to_index={2: 1},
+ chain_2_residue_number_to_index={3: 2},
+ num_contact_residue_pairs=1,
+ )
+ target_interface = InterfaceView(
+ id="1abc__1__1.B_1.D",
+ pdb_id="1abc",
+ biounit_id="1",
+ chain_1="1.B",
+ chain_2="1.D",
+ chain_1_residue_number_to_index={20: 1},
+ chain_2_residue_number_to_index={30: 2},
+ num_contact_residue_pairs=1,
+ )
+ query = EntryView(
+ pdb_id="model",
+ chains={
+ chain: ChainView(asym_id=chain, auth_id=chain, length=3)
+ for chain in ["A", "C"]
+ },
+ systems={},
+ author_to_asym={"A": "A", "C": "C"},
+ interfaces={query_interface.id: query_interface},
+ )
+ target = EntryView(
+ pdb_id="1abc",
+ chains={
+ chain: ChainView(asym_id=chain, auth_id=chain, length=3)
+ for chain in ["B", "D"]
+ },
+ systems={},
+ author_to_asym={"B": "B", "D": "D"},
+ interfaces={target_interface.id: target_interface},
+ )
+ monkeypatch.setattr(
+ custom,
+ "_load_release_entry_views",
+ lambda _assets, *, pdb_ids: {"1abc": target},
+ )
+ alignment = tmp_path / "interface_foldseek.parquet"
+ pd.DataFrame(
+ [
+ {
+ "query_entry": "model",
+ "target_entry": "1abc",
+ "query_chain_mapped": query_chain,
+ "target_chain_mapped": target_chain,
+ "source": "foldseek",
+ "query_selected_residue_numbers": [query_number],
+ "target_selected_residue_numbers": [target_number],
+ }
+ for query_chain, target_chain, query_number, target_number in [
+ ("A", "B", 2, 20),
+ ("C", "D", 3, 30),
+ ]
+ ]
+ ).to_parquet(alignment, index=False)
+
+ scores = custom.calculate_custom_interface_similarity_scores(
+ {"foldseek": alignment},
+ annotations=_custom_annotations(tmp_path, query),
+ assets=_custom_assets(tmp_path),
+ )
+
+ assert len(scores) == 1
+ assert scores.loc[0, "similarity"] == 100
+ assert scores.loc[0, "query_system"] == query_interface.id
+ assert scores.loc[0, "target_system"] == target_interface.id
diff --git a/tests/core/test_data_loader.py b/tests/core/test_data_loader.py
index 9f2d7ad54..9a57f4079 100644
--- a/tests/core/test_data_loader.py
+++ b/tests/core/test_data_loader.py
@@ -1,7 +1,28 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
-def test_data_loader(read_plinder_mount):
+def test_data_loader(cached_plinder_system):
from plinder.core.loader import PlinderDataset
+ from plinder.core.loader.dataset import get_torch_loader
- ds = PlinderDataset(split="removed", use_alternate_structures=False)
- assert len(ds[0])
+ system = cached_plinder_system("19hc__1__1.B__1.T")
+ ds = PlinderDataset(
+ filters=[("system_id", "==", "19hc__1__1.B__1.T")],
+ system_factory=lambda _system_id: system,
+ )
+ assert len(ds) == 1
+ item = ds[0]
+ assert set(item) == {
+ "system_id",
+ "holo_structure",
+ "features_and_coords",
+ "path",
+ }
+
+ batch = next(iter(get_torch_loader(ds, batch_size=1, num_workers=0)))
+ assert set(batch) == {
+ "system_ids",
+ "holo_structures",
+ "features_and_coords",
+ "paths",
+ }
+ assert batch["system_ids"] == ["19hc__1__1.B__1.T"]
diff --git a/tests/core/test_dataclass.py b/tests/core/test_dataclass.py
index e35590e9d..24e792d33 100644
--- a/tests/core/test_dataclass.py
+++ b/tests/core/test_dataclass.py
@@ -4,20 +4,16 @@
)
-def test_stringify_dataclass(read_plinder_mount):
- from plinder.core import PlinderSystem
-
- system_id = "19hc__1__1.A_1.B__1.V_1.X_1.Y"
- system = PlinderSystem(system_id=system_id)
+def test_stringify_dataclass(cached_plinder_system):
+ system_id = "1avd__1__1.A__1.C"
+ system = cached_plinder_system(system_id)
struct = system.holo_structure
assert isinstance(stringify_dataclass(struct), str)
-def test_markdown_repr(read_plinder_mount):
- from plinder.core import PlinderSystem
-
- system_id = "19hc__1__1.A_1.B__1.V_1.X_1.Y"
- system = PlinderSystem(system_id=system_id)
+def test_markdown_repr(cached_plinder_system):
+ system_id = "1avd__1__1.A__1.C"
+ system = cached_plinder_system(system_id)
struct = system.holo_structure
markdown = atom_array_summary_markdown_repr(struct.protein_atom_array)
assert isinstance(markdown, str)
diff --git a/tests/core/test_files.py b/tests/core/test_files.py
new file mode 100644
index 000000000..7f4d82974
--- /dev/null
+++ b/tests/core/test_files.py
@@ -0,0 +1,73 @@
+import hashlib
+import json
+import os
+from errno import EXDEV
+from pathlib import Path
+
+import pytest
+
+from plinder.core.utils.files import (
+ file_sha256,
+ link_or_copy_file,
+ read_json_cache,
+ write_json_atomic,
+)
+
+
+def test_file_sha256_streams_multiple_chunks(tmp_path):
+ content = b"plinder" * 400_000
+ path = tmp_path / "source"
+ path.write_bytes(content)
+ assert file_sha256(path) == hashlib.sha256(content).hexdigest()
+
+
+@pytest.mark.parametrize("content", [None, "broken", "[]", "null", '"text"'])
+def test_unusable_json_cache_is_a_miss(tmp_path, content):
+ path = tmp_path / "marker.json"
+ if content is not None:
+ path.write_text(content)
+ assert read_json_cache(path) is None
+
+
+def test_write_json_atomic_replaces_marker(tmp_path):
+ path = tmp_path / "nested" / "marker.json"
+ write_json_atomic(path, {"state": "pending"})
+ write_json_atomic(path, {"state": "complete"})
+ assert read_json_cache(path) == {"state": "complete"}
+ assert list(path.parent.iterdir()) == [path]
+
+
+def test_failed_json_install_preserves_marker(tmp_path, monkeypatch):
+ path = tmp_path / "marker.json"
+ write_json_atomic(path, {"state": "complete"})
+
+ def fail_replace(self, target):
+ raise OSError("install failed")
+
+ monkeypatch.setattr(Path, "replace", fail_replace)
+ with pytest.raises(OSError, match="install failed"):
+ write_json_atomic(path, {"state": "pending"})
+ assert json.loads(path.read_text()) == {"state": "complete"}
+ assert list(tmp_path.iterdir()) == [path]
+
+
+def test_link_or_copy_file_copies_across_filesystems(tmp_path, monkeypatch):
+ source, target = tmp_path / "source", tmp_path / "target"
+ source.write_bytes(b"immutable archive")
+
+ def cross_device(*args):
+ raise OSError(EXDEV, "cross-device link")
+
+ monkeypatch.setattr(os, "link", cross_device)
+ link_or_copy_file(source, target)
+ assert target.read_bytes() == source.read_bytes()
+ assert target.stat().st_ino != source.stat().st_ino
+
+
+def test_link_or_copy_file_does_not_overwrite_existing_file(tmp_path):
+ source, target = tmp_path / "source", tmp_path / "target"
+ source.write_bytes(b"new")
+ target.write_bytes(b"old")
+ with pytest.raises(FileExistsError):
+ link_or_copy_file(source, target)
+ assert target.read_bytes() == b"old"
diff --git a/tests/core/test_gcs.py b/tests/core/test_gcs.py
deleted file mode 100644
index a029eb194..000000000
--- a/tests/core/test_gcs.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# Copyright (c) 2024, Plinder Development Team
-# Distributed under the terms of the Apache License 2.0
-import os
-
-import pytest
-from omegaconf import DictConfig
-from plinder.core.utils import gcs
-
-
-class _Blob:
- def __init__(self, name):
- self.name = name
-
- def download_as_bytes(self):
- return b"test"
-
- def download_to_filename(self, local_path):
- pass
-
-
-class _Bucket:
- def __init__(self, name):
- self.name = name
-
- def blob(self, name):
- return _Blob(name)
-
- def list_blobs(self, prefix):
- return []
-
-
-CONF = DictConfig(
- {
- "data": {
- "plinder_bucket": "plinder",
- }
- }
-)
-
-
-@pytest.fixture
-def mock_buckets(monkeypatch):
- monkeypatch.setattr(
- "plinder.core.utils.gcs.BUCKETS",
- {
- "plinder": _Bucket("plinder"),
- "plinder-test": _Bucket("plinder-test"),
- },
- )
-
-
-def test_download_as_str(mock_buckets):
- assert gcs.download_as_str(gcs_path="gs://plinder/test", cfg=CONF) == "test"
-
-
-def test_download_to_file(mock_buckets, tmp_path):
- gcs.download_to_file(
- gcs_path="gs://plinder/test",
- local_path=(tmp_path / "afile.txt").as_posix(),
- cfg=CONF,
- )
-
-
-def test_download_many(mock_buckets, tmp_path):
- gcs_paths = [
- "gs://plinder/afile.txt",
- "gs://plinder/bfile.txt",
- ]
- local_paths = [
- (tmp_path / "afile.txt").as_posix(),
- (tmp_path / "bfile.txt").as_posix(),
- ]
- gcs.download_many(gcs_paths=gcs_paths, local_paths=local_paths, cfg=CONF)
-
-
-def test_list_dir(mock_buckets):
- assert isinstance(gcs.list_dir(gcs_path="gs://plinder/test", cfg=CONF), list)
-
-
-def test_real_download():
- gcs.download_as_str(
- gcs_path="gs://plinder/2024-04/v1/README.md", cfg=CONF
- ).startswith("plinder-data")
-
-
-def test_real_list_dir():
- assert len(gcs.list_dir(gcs_path="gs://plinder/2024-04/v1/", cfg=CONF))
-
-
-def test_real_download_many(tmp_path):
- gcs_paths = [
- "gs://plinder/2024-04/v1/README.md",
- "gs://plinder/2024-04/v1/README.md",
- ]
- local_paths = [
- (tmp_path / "afile.txt").as_posix(),
- (tmp_path / "bfile.txt").as_posix(),
- ]
- for path in local_paths:
- assert not os.path.exists(path)
- gcs.download_many(gcs_paths=gcs_paths, local_paths=local_paths, cfg=CONF)
- for path in local_paths:
- assert os.path.exists(path)
-
-
-def test_default_behavior():
- assert gcs.download_as_str(gcs_path="gs://plinder/2024-04/v1/README.md").startswith(
- "plinder-data"
- )
diff --git a/tests/core/test_r2.py b/tests/core/test_http.py
similarity index 52%
rename from tests/core/test_r2.py
rename to tests/core/test_http.py
index 8d8ba4288..9320c22a3 100644
--- a/tests/core/test_r2.py
+++ b/tests/core/test_http.py
@@ -1,7 +1,4 @@
-import base64
-import gzip
-import hashlib
-import json
+import os
from functools import partial
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
from pathlib import Path
@@ -9,16 +6,16 @@
from types import SimpleNamespace
import pytest
+
from plinder.core.utils import cpl
-from plinder.core.utils import r2 as dataset
+from plinder.core.utils import http as dataset
@pytest.fixture
def mirror(tmp_path, monkeypatch):
origin = tmp_path / "origin"
- release = origin / "2024-06/v2"
+ release = origin / "PLINDER-2026-09"
release.mkdir(parents=True)
- records = []
for key, data in [
("systems/ab.zip", b"archive"),
("scores/a.parquet", b"one"),
@@ -27,39 +24,44 @@ def mirror(tmp_path, monkeypatch):
path = release / key
path.parent.mkdir(exist_ok=True)
path.write_bytes(data)
- records.append(
- {
- "key": key,
- "size": len(data),
- "md5": base64.b64encode(hashlib.md5(data).digest()).decode(),
- }
- )
- (release / "manifest.jsonl.gz").write_bytes(
- gzip.compress(("\n".join(map(json.dumps, records))).encode())
- )
+ os.utime(path, (1700000000, 1700000000))
+ requests = []
+
+ class Handler(SimpleHTTPRequestHandler):
+ def log_message(self, *args):
+ pass
+
+ def do_HEAD(self):
+ requests.append(("HEAD", self.path))
+ super().do_HEAD()
+
+ def do_GET(self):
+ requests.append(("GET", self.path))
+ super().do_GET()
+
server = ThreadingHTTPServer(
- ("127.0.0.1", 0), partial(SimpleHTTPRequestHandler, directory=str(origin))
+ ("127.0.0.1", 0), partial(Handler, directory=str(origin))
)
thread = Thread(target=server.serve_forever, daemon=True)
thread.start()
cfg = SimpleNamespace(
data=SimpleNamespace(
plinder_bucket="plinder",
- plinder_release="2024-06",
- plinder_iteration="v2",
+ plinder_release="2026-09",
+ plinder_release_number="",
plinder_dir=str(tmp_path / "cache"),
- plinder_remote=f"http://127.0.0.1:{server.server_port}/2024-06/v2",
+ plinder_remote=f"http://127.0.0.1:{server.server_port}/PLINDER-2026-09",
force_update=False,
)
)
monkeypatch.setattr(cpl, "get_config", lambda: cfg)
monkeypatch.delenv("PLINDER_OFFLINE", raising=False)
- cpl.manifest.cache_clear()
+ cfg.requests = requests
+ monkeypatch.delenv("PLINDER_OFFLINE_MODE", raising=False)
yield cfg, release
server.shutdown()
server.server_close()
thread.join()
- cpl.manifest.cache_clear()
def test_directory_download_and_truncated_cache_repair(mirror):
@@ -72,21 +74,28 @@ def test_directory_download_and_truncated_cache_repair(mirror):
assert not (Path(cfg.data.plinder_dir) / "systems/ab.zip").exists()
-def test_archive_listing_without_download(mirror):
+def test_directory_download_prunes_parquet_files_the_release_dropped(mirror):
cfg, _ = mirror
- root = cpl.get_plinder_path(rel="systems", download=False)
- paths = cpl.list_zip_paths("systems")
- assert paths == [root / "ab.zip"]
- assert not paths[0].exists()
- assert cpl.get_plinder_paths(paths=paths) == paths
- assert paths[0].read_bytes() == b"archive"
+ cache = Path(cfg.data.plinder_dir)
+ stale = cache / "scores/old.parquet"
+ stale.parent.mkdir(parents=True)
+ stale.write_bytes(b"stale")
+ (cache / "scores/notes.txt").write_text("kept")
+ elsewhere = cache / "other/x.parquet"
+ elsewhere.parent.mkdir()
+ elsewhere.write_bytes(b"kept")
+
+ path = cpl.get_plinder_path(rel="scores")
+
+ assert sorted(p.name for p in path.glob("*.parquet")) == ["a.parquet", "b.parquet"]
+ assert (path / "notes.txt").read_text() == "kept"
+ assert elsewhere.read_bytes() == b"kept"
def test_small_batch_failure_propagates(mirror):
- cfg, origin = mirror
- (origin / "systems/ab.zip").write_bytes(b"corrupt")
- with pytest.raises(ValueError, match="checksum"):
- cpl.get_plinder_path(rel="systems/ab.zip")
+ cfg, _ = mirror
+ with pytest.raises(FileNotFoundError):
+ cpl.download_paths(paths=[Path(cfg.data.plinder_dir) / "systems/missing.zip"])
assert not (Path(cfg.data.plinder_dir) / "systems/ab.zip").exists()
@@ -94,7 +103,6 @@ def test_offline_does_not_access_network(mirror, monkeypatch):
monkeypatch.setenv("PLINDER_OFFLINE", "true")
monkeypatch.setattr(cpl, "_get_client", lambda: pytest.fail("network"))
assert isinstance(cpl.get_plinder_path(rel="missing"), Path)
- assert cpl.list_zip_paths("systems") == []
@pytest.mark.parametrize(
@@ -105,10 +113,13 @@ def test_path_traversal_rejected(mirror, rel):
cpl.get_plinder_path(rel=rel)
-def test_unsupported_release_rejected(mirror):
+@pytest.mark.parametrize(
+ "release", [("2024-06", "v2"), ("2026-09", "1"), ("2026-9", ""), ("2026-13", "")]
+)
+def test_unsupported_release_rejected(mirror, release):
cfg, _ = mirror
- cfg.data.plinder_iteration = "v1"
- with pytest.raises(ValueError, match="2024-06/v2"):
+ cfg.data.plinder_release, cfg.data.plinder_release_number = release
+ with pytest.raises(ValueError, match="YYYY-MM"):
cpl.get_plinder_path(rel="systems")
@@ -117,53 +128,50 @@ def test_missing_file_fails(mirror):
cpl.get_plinder_path(rel="missing")
-def test_archive_extraction_and_repair(mirror):
- from zipfile import ZipFile
-
- from plinder.core.utils import unpack
-
- cfg, origin = mirror
- cfg.data.systems = "systems"
- cfg.context = SimpleNamespace(system_ids=[], pdb_ids=[], two_char_codes=["ab"])
- archive = origin / "systems/ab.zip"
- with ZipFile(archive, "w") as stream:
- stream.writestr("example/protein.cif", "structure")
- payload = archive.read_bytes()
- record = {
- "key": "systems/ab.zip",
- "size": len(payload),
- "md5": base64.b64encode(hashlib.md5(payload).digest()).decode(),
- }
- (origin / "manifest.jsonl.gz").write_bytes(
- gzip.compress(json.dumps(record).encode())
- )
- unpack.get_zips_to_unpack(kind="systems", cfg=cfg)
- root = Path(cfg.data.plinder_dir) / "systems"
- assert (root / "example/protein.cif").read_text() == "structure"
- assert (root / "ab_done").exists()
- (root / "ab.zip").write_bytes(b"broken")
- cpl.download_paths(paths=[root / "ab.zip"])
- assert not (root / "ab_done").exists()
-
-
-def test_cached_same_size_edit_requires_force_update(mirror, monkeypatch):
+def test_same_size_local_edit_preserving_mtime_requires_force_update(mirror):
cfg, _ = mirror
path = cpl.get_plinder_path(rel="scores/a.parquet")
path.write_bytes(b"bad")
+ os.utime(path, (1700000000, 1700000000))
assert cpl.get_plinder_path(rel="scores/a.parquet").read_bytes() == b"bad"
cfg.data.force_update = True
assert cpl.get_plinder_path(rel="scores/a.parquet").read_bytes() == b"one"
-def test_failed_checksum_preserves_existing_cache(mirror):
+def test_same_size_server_hotfix_is_fetched_without_force_update(mirror):
cfg, origin = mirror
path = cpl.get_plinder_path(rel="scores/a.parquet")
- (origin / "scores/a.parquet").write_bytes(b"bad")
- cfg.data.force_update = True
- with pytest.raises(ValueError, match="checksum"):
- cpl.get_plinder_path(rel="scores/a.parquet")
- assert path.read_bytes() == b"one"
- assert list(path.parent.iterdir()) == [path]
+ source = origin / "scores/a.parquet"
+ source.write_bytes(b"new")
+ os.utime(source, (1700000010, 1700000010))
+
+ assert not cfg.data.force_update
+ assert cpl.get_plinder_path(rel="scores/a.parquet").read_bytes() == b"new"
+ assert path.stat().st_mtime == source.stat().st_mtime
+
+
+def test_directory_listing_refreshes_added_and_removed_files(mirror):
+ _, origin = mirror
+ path = cpl.get_plinder_path(rel="scores")
+ (origin / "scores/a.parquet").unlink()
+ (origin / "scores/c.parquet").write_bytes(b"new")
+
+ assert cpl.get_plinder_path(rel="scores") == path
+ assert sorted(p.name for p in path.glob("*.parquet")) == ["b.parquet", "c.parquet"]
+
+
+def test_encoded_nested_paths_and_empty_directory(mirror):
+ _, origin = mirror
+ shard = origin / "alignments" / "alignment_type=mmseqs" / "shard=a b%.parquet"
+ shard.parent.mkdir(parents=True)
+ shard.write_bytes(b"data")
+ (origin / "empty").mkdir()
+
+ assert (
+ cpl.get_plinder_path(rel="alignments")
+ / shard.relative_to(origin / "alignments")
+ ).read_bytes() == b"data"
+ assert cpl.get_plinder_path(rel="empty").is_dir()
def test_native_cloudpath_listing_and_download(mirror, tmp_path):
@@ -193,19 +201,15 @@ def test_cache_symlink_escape_is_rejected(mirror, tmp_path):
assert not (outside / "a.parquet").exists()
-def test_force_update_fetches_manifest_once(mirror, monkeypatch):
+def test_force_update_fetches_metadata_once_per_file(mirror):
cfg, _ = mirror
- actual = dataset.manifest.__wrapped__
- calls = []
-
- def tracked(remote):
- calls.append(remote)
- return actual(remote)
-
- monkeypatch.setattr(dataset, "manifest", tracked)
cfg.data.force_update = True
cpl.get_plinder_path(rel="scores")
- assert len(calls) == 1
+ for name in ["a", "b"]:
+ assert (
+ cfg.requests.count(("HEAD", f"/PLINDER-2026-09/scores/{name}.parquet")) == 1
+ )
+ assert all("manifest" not in url for _, url in cfg.requests)
def test_cached_file_is_not_read_or_transferred(mirror, monkeypatch):
@@ -229,12 +233,6 @@ def test_interrupted_native_transfer_restarts(tmp_path, monkeypatch):
from http.server import BaseHTTPRequestHandler
payload = b"abcdef" * 500000
- row = {
- "key": "archive.zip",
- "size": len(payload),
- "md5": base64.b64encode(hashlib.md5(payload).digest()).decode(),
- }
- listing = gzip.compress(json.dumps(row).encode())
requests = []
class Handler(BaseHTTPRequestHandler):
@@ -243,23 +241,20 @@ def log_message(self, *args):
def do_HEAD(self):
self.send_response(200)
+ self.send_header("Content-Length", str(len(payload)))
self.end_headers()
def do_GET(self):
- if self.path.endswith("manifest.jsonl.gz"):
- data = listing
- else:
- requests.append(self.headers.get("Range"))
- data = payload
+ requests.append(self.headers.get("Range"))
self.send_response(200)
- self.send_header("Content-Length", str(len(data)))
+ self.send_header("Content-Length", str(len(payload)))
self.end_headers()
- if data is payload and len(requests) == 1:
- self.wfile.write(data[:1500000])
+ if len(requests) == 1:
+ self.wfile.write(payload[:1500000])
self.wfile.flush()
self.connection.shutdown(socket.SHUT_WR)
else:
- self.wfile.write(data)
+ self.wfile.write(payload)
server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
thread = Thread(target=server.serve_forever, daemon=True)
@@ -276,48 +271,28 @@ def do_GET(self):
server.server_close()
-def test_full_download_includes_database_metadata(tmp_path, monkeypatch):
- from dataclasses import asdict
-
- from omegaconf import DictConfig
- from plinder.core.index import utils
- from plinder.core.utils.config import DataConfig
-
- cfg = SimpleNamespace(
- data=DictConfig(asdict(DataConfig(plinder_mount=str(tmp_path))))
- )
- requested = []
-
- def download(*, rel, **kwargs):
- requested.append(rel)
- return tmp_path / rel
-
- monkeypatch.setattr(utils, "get_config", lambda **kwargs: cfg)
- monkeypatch.setattr(cpl, "get_plinder_path", download)
- monkeypatch.setattr(utils, "get_zips_to_unpack", lambda **kwargs: {})
- utils.download_plinder_cmd(["--yes"])
- assert "dbs" in requested
-
-
-@pytest.mark.parametrize("resource", ["manifest", "object"])
@pytest.mark.parametrize(
- "failure", ["503", "stall_headers", "stall_body", "exhausted", "404", "malformed"]
+ "resource,failure",
+ [
+ (resource, failure)
+ for resource in ["metadata", "listing", "object"]
+ for failure in [
+ "503",
+ "stall_headers",
+ "stall_body",
+ "exhausted",
+ "404",
+ "truncated",
+ ]
+ if resource != "metadata" or failure not in {"stall_body", "truncated"}
+ ],
)
def test_download_recovery(tmp_path, monkeypatch, resource, failure):
from http.server import BaseHTTPRequestHandler
from threading import Event
- from urllib.error import HTTPError
payload = b"dataset"
- listing = gzip.compress(
- json.dumps(
- {
- "key": "data",
- "size": len(payload),
- "md5": base64.b64encode(hashlib.md5(payload).digest()).decode(),
- }
- ).encode()
- )
+ listing = b'Index of /data'
release_stall = Event()
requests = []
original_timeout = dataset._TimeoutHandler.http_request
@@ -335,31 +310,40 @@ class Handler(BaseHTTPRequestHandler):
def log_message(self, *args):
pass
- def do_HEAD(self):
- self.send_error(503) # Bootstrap must use GET, not hide this as missing.
-
- def do_GET(self):
- is_manifest = self.path.endswith("manifest.jsonl.gz")
- selected = is_manifest == (resource == "manifest")
+ def respond(self, head=False):
+ is_listing = self.path == "/"
+ selected = (
+ head
+ if resource == "metadata"
+ else not head and is_listing == (resource == "listing")
+ )
if selected:
requests.append(self.path)
- fail = selected and (len(requests) == 1 or failure in {"404", "exhausted"})
+ fail = selected and (
+ len(requests) == 1 or failure in {"404", "exhausted", "truncated"}
+ )
if fail and failure in {"503", "404", "exhausted"}:
self.send_error(503 if failure == "exhausted" else int(failure))
return
if fail and failure == "stall_headers":
release_stall.wait(5)
return
- data = listing if is_manifest else payload
- if fail and failure == "malformed":
- data = b"invalid" # Same length as the object: checksum must reject it.
+ data = listing if is_listing else payload
self.send_response(200)
self.send_header("Content-Length", str(len(data)))
self.end_headers()
+ if head:
+ return
if fail and failure == "stall_body":
release_stall.wait(5)
return
- self.wfile.write(data)
+ self.wfile.write(data[:-1] if fail and failure == "truncated" else data)
+
+ def do_HEAD(self):
+ self.respond(head=True)
+
+ def do_GET(self):
+ self.respond()
server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
thread = Thread(target=server.serve_forever, daemon=True)
@@ -369,17 +353,20 @@ def do_GET(self):
def download():
client = dataset.ReleaseClient(f"http://127.0.0.1:{server.server_port}")
+ if resource == "listing":
+ list(client.path().iterdir())
client.path("data").download_to(destination)
try:
- if failure in {"404", "malformed", "exhausted"}:
- error = (
- (ValueError, gzip.BadGzipFile) if failure == "malformed" else HTTPError
- )
+ if failure in {"404", "exhausted", "truncated"}:
+ from cloudpathlib.exceptions import CloudPathNotExistsError
+
+ error = (OSError, dataset.HTTPException, CloudPathNotExistsError)
with pytest.raises(error):
download()
- assert len(requests) == (3 if failure == "exhausted" else 1)
+ assert len(requests) == (1 if failure == "404" else 3)
assert destination.read_bytes() == b"existing"
+ assert list(tmp_path.iterdir()) == [destination]
else:
download()
assert len(requests) == 2
@@ -389,4 +376,57 @@ def download():
server.shutdown()
server.server_close()
thread.join()
- dataset.manifest.cache_clear()
+
+
+def test_listing_ignores_navigation_and_escaping_links(mirror, monkeypatch):
+ cfg, _ = mirror
+ client = cpl._get_client()
+ original_open = client.opener.open
+
+ def open_index(request):
+ response = original_open(request)
+ if request.full_url.endswith("/scores/"):
+ from io import BytesIO
+
+ response.read = BytesIO(
+ b"Index of /scores/"
+ b'parentsort'
+ b'external'
+ b'absoluteescape'
+ b'encoded escape'
+ b'ab'
+ ).read
+ return response
+
+ monkeypatch.setattr(client.opener, "open", open_index)
+ assert {p.name for p in client.path("scores").iterdir()} == {
+ "a.parquet",
+ "b.parquet",
+ }
+ assert all(
+ "escape" not in url and "example.com" not in url for _, url in cfg.requests
+ )
+
+
+def test_invalid_listing_preserves_cached_parquet(mirror, monkeypatch):
+ cfg, _ = mirror
+ path = cpl.get_plinder_path(rel="scores")
+ monkeypatch.setattr(dataset._DirectoryIndex, "handle_data", lambda *args: None)
+ with pytest.raises(ValueError, match="directory index"):
+ cpl.get_plinder_path(rel="scores")
+ assert (path / "a.parquet").read_bytes() == b"one"
+ assert (path / "b.parquet").read_bytes() == b"two"
+
+
+def test_empty_directory_cannot_prune_through_a_cache_symlink(mirror, tmp_path):
+ cfg, origin = mirror
+ (origin / "empty").mkdir()
+ root = Path(cfg.data.plinder_dir)
+ root.mkdir()
+ outside = tmp_path / "outside"
+ outside.mkdir()
+ (outside / "kept.parquet").write_bytes(b"kept")
+ (root / "empty").symlink_to(outside, target_is_directory=True)
+ with pytest.raises(ValueError):
+ cpl.get_plinder_path(rel="empty")
+ assert (outside / "kept.parquet").read_bytes() == b"kept"
diff --git a/tests/core/test_index_utils.py b/tests/core/test_index_utils.py
index 2bf46b64f..6de0e399c 100644
--- a/tests/core/test_index_utils.py
+++ b/tests/core/test_index_utils.py
@@ -4,6 +4,7 @@
from pathlib import Path
import pytest
+
from plinder.core.index import utils
@@ -22,7 +23,6 @@ def mock_path(*, rel: str = "", download: bool = False, force_progress: bool = F
@pytest.fixture
def mock_cpl(read_plinder_mount, monkeypatch):
- # patch cpl at core.utils not core.index.utils because of unpack
monkeypatch.setattr(
"plinder.core.utils.cpl.get_plinder_path",
mock_path,
@@ -31,22 +31,11 @@ def mock_cpl(read_plinder_mount, monkeypatch):
"plinder.core.utils.cpl.download_paths",
lambda **kws: None,
)
+ yield
+ from plinder.core.utils import config
-def test_get_plindex(mock_cpl):
- df = utils.get_plindex()
- assert len(df.index) == 57
- assert "pli_unique_qcov__50__strong__component" in df.columns
-
-
-def test_get_manifest(mock_cpl):
- df = utils.get_manifest()
- assert len(df.index) == 57
-
-
-def test_load_entries(mock_cpl):
- blob = utils.load_entries(two_char_codes=["9h"])
- assert len(blob) == 1
+ config._config._clear()
@pytest.mark.parametrize(
@@ -54,9 +43,130 @@ def test_load_entries(mock_cpl):
[
[],
["--release", "2024-04"],
- ["--iteration", "v1"],
- ["--release", "2024-06", "--iteration", "v2"],
+ ["--release-number", "2"],
+ ["--release", "2026-07", "--release-number", "2"],
],
)
def test_download_cmd(args, mock_cpl):
utils.download_plinder_cmd(args=args + ["-y"])
+
+
+def test_download_cmd_forwards_release_identity(mock_cpl, monkeypatch):
+ calls = []
+ original_get_config = utils.get_config
+
+ def track_config(**kwargs):
+ calls.append(kwargs.get("config"))
+ return original_get_config(**kwargs)
+
+ monkeypatch.setattr(utils, "get_config", track_config)
+
+ utils.download_plinder_cmd(
+ args=["--release", "2026-07", "--release-number", "2", "-y"]
+ )
+
+ assert calls == [
+ {
+ "data": {
+ "plinder_release": "2026-07",
+ "plinder_release_number": "2",
+ }
+ }
+ ]
+
+
+def test_download_cmd_does_not_fetch_source_mmcif_cache(mock_cpl, monkeypatch):
+ from plinder.core.utils import cpl
+
+ requested = []
+
+ def track_path(**kwargs):
+ requested.append(kwargs.get("rel", ""))
+ return mock_path(**kwargs)
+
+ monkeypatch.setattr(cpl, "get_plinder_path", track_path)
+
+ utils.download_plinder_cmd(args=["-y"])
+
+ assert "index/annotation_table.parquet" in requested
+ assert "index/linked_apo_structures.parquet" in requested
+ assert "index/interface_apo_structures.parquet" in requested
+ assert not any(path.startswith("source_mmcifs") for path in requested)
+
+
+def test_default_download_includes_covers_but_not_complete_scores(
+ mock_cpl, monkeypatch
+):
+ from plinder.core.utils import cpl
+
+ requested = []
+
+ def track_path(**kwargs):
+ requested.append(kwargs.get("rel", ""))
+ return mock_path(**kwargs)
+
+ monkeypatch.setattr(cpl, "get_plinder_path", track_path)
+ monkeypatch.setattr("builtins.input", lambda prompt: "n")
+
+ utils.download_plinder_cmd(args=[])
+
+ assert "ligand_sampling" in requested
+ assert "interface_sampling" in requested
+ assert "index/ligand_clusters.parquet" in requested
+ assert "index/interface_clusters.parquet" in requested
+ assert "protein_clusters/sequence.parquet" in requested
+ assert "protein_clusters/structure.parquet" in requested
+ assert "exports/ligand_similarity_scores.parquet" not in requested
+ assert "exports/interface_similarity_scores.parquet" not in requested
+ assert "exports/interface_half_similarity_scores.parquet" not in requested
+ assert "ligand_clusters" not in requested
+ assert "interface_clusters" not in requested
+
+
+def test_download_uses_only_release_artifacts(mock_cpl, monkeypatch):
+ from plinder.core.utils import cpl
+
+ requested = []
+
+ def track_path(**kwargs):
+ requested.append(kwargs.get("rel", ""))
+ return mock_path(**kwargs)
+
+ monkeypatch.setattr(cpl, "get_plinder_path", track_path)
+
+ utils.download_plinder_cmd(args=["-y"])
+
+ assert "alignment_cigars" in requested
+ assert "search_databases" in requested
+ assert not any(path == "scores" or path.startswith("scores/") for path in requested)
+ assert "entries" not in requested
+ assert "systems" not in requested
+ assert "links" not in requested
+ assert "linked_structures" not in requested
+ assert set(requested) <= {
+ path for path in utils.RELEASE_PATHS.values() if "{" not in path
+ }
+
+
+def test_download_can_skip_large_artifact_groups(mock_cpl, monkeypatch):
+ from plinder.core.utils import cpl
+
+ requested = []
+
+ def track_path(**kwargs):
+ requested.append(kwargs.get("rel", ""))
+ return mock_path(**kwargs)
+
+ monkeypatch.setattr(cpl, "get_plinder_path", track_path)
+ monkeypatch.setattr("builtins.input", lambda prompt: "n")
+
+ utils.download_plinder_cmd(args=[])
+
+ large_paths = {
+ utils.RELEASE_PATHS[artifact_name]
+ for _, artifact_names, large_download in utils._DOWNLOAD_GROUPS
+ if large_download
+ for artifact_name in artifact_names
+ }
+ assert requested
+ assert large_paths.isdisjoint(requested)
diff --git a/tests/core/test_interface.py b/tests/core/test_interface.py
new file mode 100644
index 000000000..963faa250
--- /dev/null
+++ b/tests/core/test_interface.py
@@ -0,0 +1,130 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from __future__ import annotations
+
+import pandas as pd
+import pytest
+from biotite.structure.io import pdbx
+
+from plinder.core import PlinderInterface, PlinderRelease
+from plinder.data.annotations.cif_utils import read_mmcif_file
+
+
+@pytest.fixture
+def interface_release(tmp_path) -> PlinderRelease:
+ index = tmp_path / "index"
+ index.mkdir()
+ system_id = "2y4i__1__1.A--1.B"
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["2y4i"],
+ "system_id": [system_id],
+ "system_biounit_id": ["1"],
+ "interface_chain_1": ["1.A"],
+ "interface_chain_2": ["1.B"],
+ "interface_chain_1_residue_numbers": [[22, 23]],
+ "interface_chain_1_residue_indices": [[0, 1]],
+ "interface_chain_2_residue_numbers": [[39]],
+ "interface_chain_2_residue_indices": [[0]],
+ "interface_num_contact_residue_pairs": [2],
+ }
+ ).to_parquet(index / "interface_annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["2y4i", "2y4i"],
+ "chain_asym_id": ["A", "B"],
+ "chain_sequence": ["AC", "DEF"],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ return PlinderRelease(data_dir=tmp_path)
+
+
+def test_interface_loads_annotation_sequences_and_residue_views(
+ interface_release, cif_2y4i, tmp_path
+):
+ interface = PlinderInterface(
+ system_id="2y4i__1__1.A--1.B",
+ release=interface_release,
+ source_mmcif=cif_2y4i,
+ reconstruction_dir=tmp_path / "reconstructed",
+ )
+
+ assert interface.entry_pdb_id == "2y4i"
+ assert interface.biounit_id == "1"
+ assert interface.chains == ("1.A", "1.B")
+ assert interface.sequences == {"1.A": "AC", "1.B": "DEF"}
+ assert set(interface.chain_structures) == {"1.A", "1.B"}
+ assert all(len(atoms) > 0 for atoms in interface.chain_structures.values())
+ assert set(interface.interface_residue_masks) == {"1.A", "1.B"}
+ assert len(interface.interface_structure) > 0
+ assert set(interface.interface_structure.chain_id) == {"1.A", "1.B"}
+
+ output = interface.reconstruct()
+ assert output == tmp_path / "reconstructed" / "interface.cif"
+ cif_file = read_mmcif_file(output)
+ block = cif_file[interface.system_id]
+ assert {
+ "entry",
+ "entity",
+ "entity_poly",
+ "entity_poly_seq",
+ "chem_comp",
+ "struct_asym",
+ "atom_site",
+ }.issubset(block)
+ atoms = pdbx.get_structure(
+ cif_file,
+ model=1,
+ use_author_fields=False,
+ include_bonds=True,
+ )
+ assert len(set(atoms.chain_id.astype(str))) == 2
+ assert set(block["atom_site"]["label_asym_id"].as_array(str)).issubset(
+ block["struct_asym"]["id"].as_array(str)
+ )
+ assert set(block["atom_site"]["label_entity_id"].as_array(str)).issubset(
+ block["entity"]["id"].as_array(str)
+ )
+ assert interface.interface_cif == output
+ with pytest.raises(FileExistsError, match="Refusing to overwrite"):
+ interface.reconstruct()
+
+
+def test_interface_uses_explicit_release_for_default_reconstruction_dir(
+ interface_release, cif_2y4i
+):
+ interface = PlinderInterface(
+ system_id="2y4i__1__1.A--1.B",
+ release=interface_release,
+ source_mmcif=cif_2y4i,
+ )
+
+ assert interface.reconstruction_dir == (
+ interface_release.data_dir / "reconstructed_interfaces" / "2y4i__1__1.A--1.B"
+ )
+
+
+def test_interface_rejects_source_with_different_residue_numbering(
+ interface_release, cif_2y4i, tmp_path
+):
+ interface = PlinderInterface(
+ system_id="2y4i__1__1.A--1.B",
+ release=interface_release,
+ source_mmcif=cif_2y4i,
+ reconstruction_dir=tmp_path / "reconstructed",
+ )
+ annotation = interface.annotation.copy()
+ annotation["interface_chain_1_residue_numbers"] = [999, 23]
+ interface._annotation = annotation
+
+ with pytest.raises(ValueError, match="do not match the release annotation"):
+ _ = interface.interface_residue_masks
+
+
+def test_interface_reports_an_unknown_id(interface_release):
+ interface = PlinderInterface(
+ system_id="2y4i__1__1.A--1.Z",
+ release=interface_release,
+ )
+ with pytest.raises(ValueError, match="is not in the release"):
+ _ = interface.annotation
diff --git a/tests/core/test_linked_apo_system.py b/tests/core/test_linked_apo_system.py
new file mode 100644
index 000000000..b9be69f1b
--- /dev/null
+++ b/tests/core/test_linked_apo_system.py
@@ -0,0 +1,125 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from __future__ import annotations
+
+import biotite.structure as struc
+import numpy as np
+import pandas as pd
+import pytest
+from biotite.structure.io import pdbx
+
+from plinder.core import PlinderSystem
+from plinder.core.release import PlinderRelease
+from plinder.data.annotations.cif_utils import read_mmcif_file
+
+
+def test_reconstruct_linked_apo_writes_the_scored_assembly_chain(
+ cif_2y4i, tmp_path, monkeypatch
+):
+ links_path = tmp_path / "index" / "linked_apo_structures.parquet"
+ links_path.parent.mkdir()
+ pd.DataFrame(
+ {
+ "reference_system_id": ["1abc__1__1.A__1.Z"],
+ "linked_structure_id": ["2y4i_B"],
+ "source_entry_id": ["2y4i"],
+ "source_chain_asym_id": ["B"],
+ "source_biounit_id": ["1"],
+ "source_chain_instance": ["1.B"],
+ "rank": [1],
+ }
+ ).to_parquet(links_path, index=False)
+
+ def fetch(_release, name, **parameters):
+ assert name == "linked_apo_structures"
+ assert not parameters
+ return links_path
+
+ monkeypatch.setattr(PlinderRelease, "fetch", fetch)
+ system = PlinderSystem(
+ system_id="1abc__1__1.A__1.Z",
+ reconstruction_dir=tmp_path / "reconstructed",
+ )
+ assert system.linked_apo_structures["linked_structure_id"].tolist() == ["2y4i_B"]
+
+ output = system.reconstruct_linked_apo(source_mmcif=cif_2y4i)
+ assert output == tmp_path / "reconstructed" / "linked_apo" / "2y4i_B.cif"
+ cif_file = read_mmcif_file(output)
+ block = cif_file["2y4i_B"]
+ assert {
+ "entry",
+ "entity",
+ "entity_poly",
+ "entity_poly_seq",
+ "chem_comp",
+ "struct_asym",
+ "atom_site",
+ }.issubset(block)
+ atoms = pdbx.get_structure(
+ cif_file,
+ model=1,
+ use_author_fields=False,
+ include_bonds=True,
+ )
+ assert len(np.unique(atoms.chain_id)) == 1
+ assert set(block["atom_site"]["label_asym_id"].as_array(str)).issubset(
+ block["struct_asym"]["id"].as_array(str)
+ )
+ assert set(block["atom_site"]["label_entity_id"].as_array(str)).issubset(
+ block["entity"]["id"].as_array(str)
+ )
+
+ with pytest.raises(FileExistsError, match="Refusing to overwrite"):
+ system.reconstruct_linked_apo(source_mmcif=cif_2y4i)
+
+ reference = atoms.copy()
+ reference.chain_id[:] = "1.A"
+ reference.coord += np.array([12.0, -7.0, 3.0])
+ system.__dict__["receptor_structure"] = reference
+ superposed = system.superpose_linked_apo(source_mmcif=cif_2y4i)
+ superposed_atoms = pdbx.get_structure(
+ read_mmcif_file(superposed),
+ model=1,
+ use_author_fields=False,
+ include_bonds=True,
+ )
+ reference_ca = reference[
+ struc.filter_amino_acids(reference) & (reference.atom_name == "CA")
+ ]
+ superposed_ca = superposed_atoms[
+ struc.filter_amino_acids(superposed_atoms)
+ & (superposed_atoms.atom_name == "CA")
+ ]
+ assert struc.rmsd(reference_ca, superposed_ca) < 1e-3
+
+ second_chain = reference.copy()
+ second_chain.chain_id[:] = "1.C"
+ system.__dict__["receptor_structure"] = struc.concatenate([reference, second_chain])
+ with pytest.raises(ValueError, match="reference_chain is required"):
+ system.superpose_linked_apo(
+ source_mmcif=cif_2y4i,
+ output_cif=tmp_path / "ambiguous.cif",
+ )
+
+
+def test_reconstruct_linked_apo_reports_when_a_system_has_no_link(
+ tmp_path, monkeypatch
+):
+ links_path = tmp_path / "linked_apo_structures.parquet"
+ pd.DataFrame(
+ {
+ "reference_system_id": pd.Series(dtype="string"),
+ "linked_structure_id": pd.Series(dtype="string"),
+ "source_entry_id": pd.Series(dtype="string"),
+ "source_chain_asym_id": pd.Series(dtype="string"),
+ "source_biounit_id": pd.Series(dtype="string"),
+ "source_chain_instance": pd.Series(dtype="string"),
+ "rank": pd.Series(dtype="int16"),
+ }
+ ).to_parquet(links_path, index=False)
+ monkeypatch.setattr(PlinderRelease, "fetch", lambda *_args, **_kwargs: links_path)
+
+ system = PlinderSystem(system_id="1abc__1__1.A__1.Z")
+ assert system.linked_apo_structures.empty
+ with pytest.raises(ValueError, match="No linked apo structure"):
+ system.reconstruct_linked_apo()
diff --git a/tests/core/test_reconstruct_scores.py b/tests/core/test_reconstruct_scores.py
new file mode 100644
index 000000000..c2ad3a6c4
--- /dev/null
+++ b/tests/core/test_reconstruct_scores.py
@@ -0,0 +1,124 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from pathlib import Path
+
+import pandas as pd
+import pytest
+
+from plinder.core import release
+from plinder.core.scores import reconstruct
+from plinder.core.scores.entries import LigandView
+
+
+def test_prefetch_resolves_only_requested_alignment_shards(tmp_path, monkeypatch):
+ requested: list[str] = []
+
+ def get_plinder_path(*, rel: str) -> Path:
+ requested.append(rel)
+ path = tmp_path / rel
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.touch()
+ return path
+
+ monkeypatch.setattr(release.cpl, "get_plinder_path", get_plinder_path)
+
+ paths = reconstruct.prefetch_similarity_alignments(
+ [
+ "1abc__1__1.A__1.L",
+ "2abd__1__1.B__1.M",
+ "3xyz__1__1.C__1.N",
+ ]
+ )
+
+ assert requested == [
+ "alignment_cigars/search_db=holo/alignment_type=foldseek/shard=ab.parquet",
+ "alignment_cigars/search_db=holo/alignment_type=mmseqs/shard=ab.parquet",
+ "alignment_cigars/search_db=holo/alignment_type=foldseek/shard=xy.parquet",
+ "alignment_cigars/search_db=holo/alignment_type=mmseqs/shard=xy.parquet",
+ ]
+ assert paths["1abc"] == paths["2abd"]
+ assert paths["1abc"] != paths["3xyz"]
+ assert all("scores" not in path for path in requested)
+
+
+def test_prefetch_requires_requested_shard_in_offline_cache(tmp_path, monkeypatch):
+ monkeypatch.setattr(release.cpl, "is_offline", lambda: True)
+
+ with pytest.raises(FileNotFoundError, match="offline cache"):
+ reconstruct.prefetch_similarity_alignments(
+ ["1abc__1__1.A__1.L"], data_dir=tmp_path
+ )
+
+
+def test_prefetch_accepts_one_available_alignment_backend(tmp_path):
+ foldseek = (
+ tmp_path
+ / "alignment_cigars/search_db=holo/alignment_type=foldseek/shard=ab.parquet"
+ )
+ foldseek.parent.mkdir(parents=True)
+ foldseek.touch()
+
+ paths = reconstruct.prefetch_similarity_alignments(
+ ["1abc__1__1.A__1.L"], data_dir=tmp_path
+ )
+
+ assert paths == {"1abc": {"foldseek": foldseek}}
+
+
+def test_prefetch_fetches_protein_score_shards_when_requested(tmp_path, monkeypatch):
+ requested: list[str] = []
+
+ def get_plinder_path(*, rel: str) -> Path:
+ requested.append(rel)
+ path = tmp_path / rel
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.touch()
+ return path
+
+ monkeypatch.setattr(release.cpl, "get_plinder_path", get_plinder_path)
+
+ reconstruct.prefetch_similarity_alignments(
+ ["1abc__1__1.A__1.L"], include_protein_scores=True
+ )
+
+ assert requested == [
+ "alignment_cigars/search_db=holo/alignment_type=foldseek/shard=ab.parquet",
+ "exports/protein_similarity_scores/alignment_type=foldseek/shard=ab.parquet",
+ "alignment_cigars/search_db=holo/alignment_type=mmseqs/shard=ab.parquet",
+ "exports/protein_similarity_scores/alignment_type=mmseqs/shard=ab.parquet",
+ ]
+
+
+def test_canonical_ligand_resolver_materializes_only_requested_member(tmp_path):
+ archive = tmp_path / "ligand_archives" / "ab.parquet"
+ archive.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "pdb_id": ["1abc", "2abc"],
+ "ligand_asym_id": ["L", "M"],
+ "sdf": [b"requested", b"other"],
+ }
+ ).to_parquet(archive, index=False)
+
+ ligand = LigandView(
+ id="1abc__1__1.A__1.L__1.L",
+ pdb_id="1abc",
+ system_id="1abc__1__1.A__1.L",
+ instance_chain="1.L",
+ asym_id="L",
+ is_proper=True,
+ protein_chains_asym_id=["1.A"],
+ num_pocket_residues=1,
+ num_interactions=1,
+ num_unique_interactions=1,
+ )
+ resolver = reconstruct._canonical_ligand_resolver(
+ release_root=tmp_path,
+ data_dir=tmp_path,
+ )
+
+ extracted = resolver(ligand)
+
+ assert extracted == tmp_path / "ligand_archives/1abc/ligand_files/L.sdf"
+ assert extracted.read_text() == "requested"
+ assert not (tmp_path / "ligand_archives/2abc").exists()
diff --git a/tests/core/test_release.py b/tests/core/test_release.py
new file mode 100644
index 000000000..1ea45effc
--- /dev/null
+++ b/tests/core/test_release.py
@@ -0,0 +1,113 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from pathlib import Path
+
+import pytest
+
+from plinder.core.release import RELEASE_PATHS, RELEASE_TABLES, PlinderRelease
+
+
+def test_release_paths_are_relative_and_unique():
+ paths = list(RELEASE_PATHS.values())
+ assert len(paths) == len(set(paths))
+ for path in paths:
+ assert not Path(path).is_absolute()
+ assert ".." not in Path(path).parts
+
+
+def test_release_tables_have_artifact_row_description_and_key():
+ assert RELEASE_TABLES["annotation"]["row_description"] == "ligand"
+ assert RELEASE_TABLES["annotation"]["primary_key"] == ("ligand_id",)
+ for table in RELEASE_TABLES.values():
+ assert table["artifact"] in RELEASE_PATHS
+ assert table["row_description"]
+ assert table["primary_key"]
+
+
+def test_ligand_mmp_pairs_are_a_release_table():
+ assert RELEASE_PATHS["ligand_mmp_pairs"] == "index/ligand_mmp_pairs.parquet"
+ assert RELEASE_TABLES["ligand_mmp_pairs"]["primary_key"] == (
+ "ligand_smiles_id_1",
+ "ligand_smiles_id_2",
+ "transformation",
+ "shared_core_smiles",
+ )
+
+
+def test_system_validation_is_a_release_table():
+ assert RELEASE_PATHS["system_validation"] == "index/system_validation.parquet"
+ assert RELEASE_TABLES["system_validation"]["primary_key"] == ("system_id",)
+
+
+def test_path_does_not_require_artifact_to_exist(tmp_path):
+ release = PlinderRelease(tmp_path)
+ assert release.path("annotation_table") == (
+ tmp_path / "index" / "annotation_table.parquet"
+ )
+
+
+def test_parameterized_artifact_path(tmp_path):
+ release = PlinderRelease(tmp_path)
+ assert release.path(
+ "alignment_cigar_shard",
+ search_db="holo",
+ alignment_type="foldseek",
+ shard="ab",
+ ) == (
+ tmp_path
+ / "alignment_cigars"
+ / "search_db=holo"
+ / "alignment_type=foldseek"
+ / "shard=ab.parquet"
+ )
+
+
+@pytest.mark.parametrize(
+ "parameters",
+ [
+ {},
+ {"search_db": "holo", "alignment_type": "foldseek"},
+ {
+ "search_db": "../holo",
+ "alignment_type": "foldseek",
+ "shard": "ab",
+ },
+ ],
+)
+def test_parameterized_artifact_rejects_missing_or_unsafe_values(tmp_path, parameters):
+ with pytest.raises(ValueError):
+ PlinderRelease(tmp_path).path("alignment_cigar_shard", **parameters)
+
+
+def test_fetch_checks_explicit_local_artifact(tmp_path):
+ annotation = tmp_path / "index" / "annotation_table.parquet"
+ annotation.parent.mkdir()
+ annotation.touch()
+ release = PlinderRelease(tmp_path)
+ assert release.fetch("annotation_table") == annotation
+
+ with pytest.raises(FileNotFoundError, match="entry_chains"):
+ release.fetch("entry_chains")
+
+
+def test_fetch_accepts_directory(tmp_path):
+ ligand_scores = tmp_path / "ligand_scores"
+ ligand_scores.mkdir()
+ assert PlinderRelease(tmp_path).fetch("ligand_scores") == ligand_scores
+
+
+def test_unknown_artifact_and_table_fail_clearly(tmp_path):
+ release = PlinderRelease(tmp_path)
+ with pytest.raises(KeyError, match="unknown release artifact"):
+ release.path("systems")
+ with pytest.raises(KeyError, match="unknown release artifact"):
+ release.path("splits")
+ with pytest.raises(KeyError, match="unknown release table"):
+ release.table("systems")
+
+
+def test_external_source_mmcif_cache_is_not_a_release_artifact(tmp_path):
+ with pytest.raises(KeyError, match="unknown release artifact"):
+ PlinderRelease(tmp_path).path(
+ "source_mmcif", shard="ab", filename="1abc_v1-0.cif.gz"
+ )
diff --git a/tests/core/test_score_mapping.py b/tests/core/test_score_mapping.py
new file mode 100644
index 000000000..a0cd19c85
--- /dev/null
+++ b/tests/core/test_score_mapping.py
@@ -0,0 +1,46 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from pathlib import Path
+
+import pandas as pd
+
+from plinder.core.scores.mapping import (
+ expand_residue_positions,
+ pack_residue_identities,
+ unpack_residue_identities,
+)
+
+
+def test_residue_identity_bitset_roundtrip() -> None:
+ values = [True, False, True, True, False, False, True, False, True]
+
+ packed = pack_residue_identities(values)
+
+ assert packed == bytes([0b01001101, 0b00000001])
+ assert unpack_residue_identities(packed, len(values)) == values
+
+
+def test_expand_chain_relative_residue_positions(tmp_path: Path) -> None:
+ lookup = tmp_path / "alignment_chain_lookup.parquet"
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def"],
+ "chain_asym_id": ["A", "B"],
+ "selected_residue_numbers": [[10, 30], [101, 205]],
+ }
+ ).to_parquet(lookup, index=False)
+ compact = pd.DataFrame(
+ {
+ "query_entry": ["1abc"],
+ "target_entry": ["2def"],
+ "query_chain_mapped": ["A"],
+ "target_chain_mapped": ["B"],
+ "query_selected_residue_positions": [[2, 1]],
+ "target_selected_residue_positions": [[0, 2]],
+ }
+ )
+
+ expanded = expand_residue_positions(compact, chain_lookup=lookup)
+
+ assert expanded.loc[0, "query_selected_residue_numbers"] == [30, 10]
+ assert expanded.loc[0, "target_selected_residue_numbers"] == [-1, 205]
diff --git a/tests/core/test_smallmols_utils.py b/tests/core/test_smallmols_utils.py
index 89bcc8682..e9ddc311c 100644
--- a/tests/core/test_smallmols_utils.py
+++ b/tests/core/test_smallmols_utils.py
@@ -1,5 +1,7 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
+import numpy as np
+import pandas as pd
import pytest
from rdkit import Chem
@@ -7,72 +9,519 @@
@pytest.mark.parametrize(
["smiles", "num_problems"],
[
- ["CC(=O)OCCN(C)(C)C", 0], # AtomValenceException
- ["c1ccnc1", 0], # KekulizeException
+ # positive controls: peppr repairs the issue, so no problems remain
+ ["CC(=O)OCCN(C)(C)C", 0], # AtomValenceException, fixed via onium charge
+ ["c1ccnc1", 0], # KekulizeException, fixed by adding [nH]
+ # negative controls: peppr TOLERATES main-group over-valence (does not
+ # raise) but cannot neutralize it, so one residual problem is still found
+ ["[B]12[B]3[B]4[B]1[B]5[B]6[B]2[B]3[B]45C6", 1], # boron cage: over-valent B
+ ["[Be](C)(C)(C)C", 1], # over-valent beryllium centre, no 2-centre-bond fix
],
)
def test_valence_issue_handling(smiles, num_problems):
- from plinder.core.structure.smallmols_utils import fix_valency_issues
+ # TODO(peppr): use the vendored sanitize the pipeline uses (boron/main-group
+ # over-valence fixes not yet in a released peppr). Revert to
+ # `from peppr import sanitize as peppr_sanitize` once upstream.
+ from plinder.core.utils.sanitize import sanitize as peppr_sanitize
mol = Chem.MolFromSmiles(smiles, sanitize=False)
- mol = fix_valency_issues(mol)
+ peppr_sanitize(mol)
problems = Chem.DetectChemistryProblems(mol)
assert len(problems) == num_problems
@pytest.mark.parametrize(
- ["smiles", "num_charged_atoms"],
+ "smiles",
[
- ["CC(=O)OCCN(C)(C)C", 0],
- ["[O-]C(=[O])CC[NH+](C)(C)", 0],
- ["[O-]C(=[OH+])CC[NH+](C)(C)", 0],
- ["OC(=[O])CC[N+](C)(C)(C)", 1],
- ["[O-]C(=[O])CC[N+](C)(C)(C)", 2],
- ["[O-]C(=[O])C.C[N+](C)(C)(C)", 2],
+ "[B]12[B]3[B]4[B]1[B]5[B]6[B]2[B]3[B]45C6", # boron cage
+ "[Be](C)(C)(C)C", # over-valent beryllium
],
)
-def test_uncharge_mol(smiles, num_charged_atoms):
- from plinder.core.structure.smallmols_utils import uncharge_mol
+def test_mol_from_smiles_tolerates_overvalence(smiles):
+ """mol_from_smiles keeps over-valent main-group SMILES that strict rejects.
- mol = Chem.MolFromSmiles(smiles, sanitize=False)
- mol = uncharge_mol(mol)
- assert (
- sum([at.GetFormalCharge() != 0 for at in mol.GetAtoms()]) == num_charged_atoms
- )
+ Strict ``Chem.MolFromSmiles`` returns None for these, which would silently
+ drop the ligand from descriptors/fingerprints; the tolerant helper keeps it.
+ """
+ from plinder.core.utils.sanitize import mol_from_smiles
+
+ assert Chem.MolFromSmiles(smiles) is None # strict rejects
+ assert mol_from_smiles(smiles) is not None # tolerant keeps
+
+
+@pytest.mark.parametrize(
+ ["smiles", "expected_stereo"],
+ [
+ ["O=C(O)/C=C/C(=O)O", Chem.BondStereo.STEREOE], # fumarate (trans, E)
+ ["O=C(O)/C=C\\C(=O)O", Chem.BondStereo.STEREOZ], # maleate (cis, Z)
+ ],
+)
+def test_mol_from_smiles_perceives_double_bond_ez(smiles, expected_stereo):
+ """mol_from_smiles perceives double-bond E/Z, matching Chem.MolFromSmiles.
+
+ The sanitize=False parse skips RDKit's assignStereochemistry finalization, so
+ the helper re-runs it โ otherwise fumarate and maleate collapse to one
+ identity (their C=C would be Unspecified).
+ """
+ from plinder.core.utils.sanitize import mol_from_smiles
+
+ # the stereogenic C=C (there are also carbonyls, which stay STEREONONE)
+ ez = [
+ b.GetStereo()
+ for b in mol_from_smiles(smiles).GetBonds()
+ if b.GetBondType() == Chem.BondType.DOUBLE
+ and b.GetStereo() != Chem.BondStereo.STEREONONE
+ ]
+ assert ez == [expected_stereo]
@pytest.mark.parametrize(
- ["smiles", "inchikey", "remove_stereo"],
+ ["s1", "s2"],
[
- ["CC/C=C/Cl", "DUDKKPVINWLFBI-ONEGZZNKSA-N", False],
- ["CC/C=C\\Cl", "DUDKKPVINWLFBI-ARJAWSKDSA-N", False],
- ["CC/C=C/Cl", "DUDKKPVINWLFBI-UHFFFAOYSA-N", True],
- ["CC/C=C\\Cl", "DUDKKPVINWLFBI-UHFFFAOYSA-N", True],
- ["CCC=CCl", "DUDKKPVINWLFBI-UHFFFAOYSA-N", False],
- ["CCC=CCl", "DUDKKPVINWLFBI-UHFFFAOYSA-N", True],
- ["C[C@@](F)(Cl)CBr", "REKDFINPOZVXJS-VKHMYHEASA-N", False],
- ["C[C@](F)(Cl)CBr", "REKDFINPOZVXJS-GSVOUGTGSA-N", False],
- ["C[C@](F)(Cl)CBr", "REKDFINPOZVXJS-UHFFFAOYSA-N", True],
- ["C[C@@](F)(Cl)CBr", "REKDFINPOZVXJS-UHFFFAOYSA-N", True],
- ["CC(F)(Cl)CBr", "REKDFINPOZVXJS-UHFFFAOYSA-N", True],
+ # E/Z isomers
+ ["CC/C=C/Cl", "CC/C=C\\Cl"],
+ # R/S enantiomers
+ ["C[C@](F)(Cl)CBr", "C[C@@](F)(Cl)CBr"],
],
)
-def test_inchikey(smiles, inchikey, remove_stereo):
- from plinder.core.structure.smallmols_similarity import smiles2inchikey
+def test_smiles2nonstereo(s1, s2):
+ # uncharge / InChIKey were retired: ligand identity is now a stereo-stripped
+ # RDKit canonical SMILES (robust where InChIKey fails on organometallics).
+ from plinder.core.structure.smallmols_similarity import smiles2nonstereo
+
+ out = smiles2nonstereo(s1)
+ # a valid canonical SMILES with no stereo markers
+ assert out and "@" not in out and "/" not in out and "\\" not in out
+ # stereoisomers collapse to one identity
+ assert smiles2nonstereo(s1) == smiles2nonstereo(s2)
- assert inchikey == smiles2inchikey(smiles, remove_stereo=remove_stereo)
+
+def test_load_ligands_from_index_uses_proper_holo_ligand_rows():
+ from plinder.data.annotations.get_similarity_scores import (
+ load_ligands_from_index,
+ )
+
+ annotation = pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "1abc", "2def"],
+ "system_id": ["1abc__1__A", "1abc__1__A", "2def__1__B"],
+ "system_type": ["holo", "holo", "apo"],
+ "ligand_is_proper": [True, False, True],
+ "ligand_smiles": ["CCO", "CCO", "CCN"],
+ "ligand_unique_ccd_code": ["LIG", "LIG", "OTH"],
+ "ligand_id": ["1abc__1__A__1.C", "1abc__1__A__1.C", "2def__1__B__1.D"],
+ "ligand_asym_id": ["C", "C", "D"],
+ }
+ )
+
+ ligands = load_ligands_from_index(annotation=annotation)
+
+ assert ligands["ligand_id"].tolist() == ["1abc__1__A__1.C"]
+ assert ligands["pdb_id"].tolist() == ["1abc"]
+ assert ligands["ligand_ccd_code"].tolist() == ["LIG"]
+ assert "inchikeys" not in ligands.columns
+
+
+def test_compare_stereo_to_template():
+ """Test compare_stereo_to_template: match, mismatch, achiral."""
+ import biotite.structure as struc
+ import biotite.structure.info as bt_info
+ from biotite.interface import rdkit as rdkit_interface
+ from biotite.structure import filter_heavy
+
+ from plinder.core.structure.smallmols_utils import compare_stereo_to_template
+
+ # TODO(peppr): use the vendored sanitize the pipeline uses (boron/main-group
+ # over-valence fixes not yet in a released peppr). Revert to
+ # `from peppr import sanitize as peppr_sanitize` once upstream.
+ from plinder.core.utils.sanitize import sanitize as peppr_sanitize
+
+ # Build a CCD mol with stereo (NAG โ chiral sugar)
+ ref = bt_info.residue("NAG")
+ ref_heavy = ref[filter_heavy(ref)]
+ ref_heavy.bonds = struc.connect_via_residue_names(ref_heavy)
+ template = rdkit_interface.to_mol(ref_heavy)
+ peppr_sanitize(template)
+
+ # Resolved mol = same as template (exact match). No manual chiral-tag
+ # assignment: compare_stereo_to_template perceives the template's stereo
+ # itself (from its coords) and reads only the resolved mol's coordinates.
+ resolved = rdkit_interface.to_mol(ref_heavy)
+ peppr_sanitize(resolved)
+ assert compare_stereo_to_template(resolved, template) is True
+
+ # Invert the 3D geometry (improper reflection through the x=0 plane) โ
+ # enantiomer โ mismatch. compare_stereo_to_template judges stereo from
+ # coordinates, so flipping a chiral *tag* without moving atoms would be a
+ # no-op; the geometry is the source of truth, so we must move atoms.
+ from rdkit.Geometry import Point3D
+
+ flipped = Chem.Mol(resolved)
+ conf = flipped.GetConformer()
+ for i in range(flipped.GetNumAtoms()):
+ p = conf.GetAtomPosition(i)
+ conf.SetAtomPosition(i, Point3D(-p.x, p.y, p.z))
+ assert compare_stereo_to_template(flipped, template) is False
+
+ # Achiral mol (DMS โ no stereocenters)
+ ref_dms = bt_info.residue("DMS")
+ ref_dms_heavy = ref_dms[filter_heavy(ref_dms)]
+ ref_dms_heavy.bonds = struc.connect_via_residue_names(ref_dms_heavy)
+ dms_mol = rdkit_interface.to_mol(ref_dms_heavy)
+ peppr_sanitize(dms_mol)
+ dms_template = rdkit_interface.to_mol(ref_dms_heavy)
+ peppr_sanitize(dms_template)
+ assert (
+ compare_stereo_to_template(dms_mol, dms_template) is True
+ ) # achiral = no conflict
+
+
+def test_compare_stereo_to_template_ez():
+ """compare_stereo_to_template detects cis/trans (E/Z) double-bond mismatches."""
+ from rdkit.Chem import AllChem
+
+ from plinder.core.structure.smallmols_utils import compare_stereo_to_template
+
+ names = ["C1", "C2", "C3", "CL"]
+
+ def _mol(smiles, embed):
+ # stamp PDB names positionally so template and resolved map to each other
+ m = Chem.RemoveHs(Chem.MolFromSmiles(smiles), sanitize=False)
+ for atom, nm in zip(m.GetAtoms(), names):
+ info = Chem.AtomPDBResidueInfo()
+ info.SetName(nm)
+ info.SetResidueName("LIG")
+ info.SetResidueNumber(1)
+ atom.SetMonomerInfo(info)
+ if embed:
+ mh = Chem.AddHs(m)
+ AllChem.EmbedMolecule(mh, randomSeed=1)
+ m = Chem.RemoveHs(mh)
+ return m
+
+ trans_template = _mol("C/C=C/Cl", embed=False) # SMILES tags, no conformer
+ match = compare_stereo_to_template(_mol("C/C=C/Cl", embed=True), trans_template)
+ flip = compare_stereo_to_template(_mol("C/C=C\\Cl", embed=True), trans_template)
+ assert match is True # same E/Z geometry
+ assert flip is False # inverted (cis vs trans) -> mismatch
+
+
+def test_sequences_match_core():
+ """Test sequence matching for binding affinity validation."""
+ from plinder.data.annotations.protein_utils import sequences_match_core
+
+ assert sequences_match_core("ABCDEFGH", "ABCDEFGH") is True
+ assert sequences_match_core("MHHHHHABCDEFGH", "ABCDEFGH") is True
+ assert sequences_match_core("ABCDEFGHLEVLFQ", "ABCDEFGH") is True
+ assert sequences_match_core("ABXDEFGH", "ABCDEFGH") is False
+ assert sequences_match_core("BCDEFG", "ABCDEFGH") is True
+ assert sequences_match_core("", "ABCDEFGH") is False
+ assert sequences_match_core("AB", "ABCDEFGHIJKLMNOP") is False
def test_matched_templates():
from plinder.core.structure.smallmols_utils import (
- get_matched_template_v2,
+ get_matched_template,
mol_assigned_bond_orders_by_template,
)
mol1 = Chem.MolFromSmiles("FC(Cl)(Br)C.CNCC1CCCCC1.CCC(OC)O")
template = Chem.MolFromSmiles("F[C@@](Br)(Cl)CCCNCc1cc(C(=O)N/C=C/C(OC)=O)ccc1")
- matched_template = get_matched_template_v2(template, mol1)
+ matched_template = get_matched_template(template, mol1)
fixed_mol = mol_assigned_bond_orders_by_template(matched_template, mol1)
fixed_mol_SMILES = Chem.CanonSmiles(Chem.MolToSmiles(fixed_mol))
assert fixed_mol_SMILES.count("=") >= 2
assert fixed_mol_SMILES == "C=CC(=O)OC.CC(F)(Cl)Br.CNCc1ccccc1"
+
+
+def test_mhfp6_fingerprint_is_deterministic_and_sized():
+ from plinder.core.structure.smallmols_similarity import (
+ MHFP6_N_PERMUTATIONS,
+ mol2mhfp6,
+ )
+
+ fp_a = mol2mhfp6("c1ccccc1O")
+ fp_b = mol2mhfp6("c1ccccc1O")
+ assert fp_a.shape == (MHFP6_N_PERMUTATIONS,)
+ assert str(fp_a.dtype) == "uint32"
+ # a fixed permutation seed makes the MinHash vector reproducible
+ assert (fp_a == fp_b).all()
+ with pytest.raises(ValueError):
+ mol2mhfp6("not a molecule")
+
+
+def test_mhfp6_handles_conjugated_alkene_stereo():
+ from plinder.core.structure.smallmols_similarity import (
+ MHFP6_N_PERMUTATIONS,
+ mol2mhfp6,
+ )
+
+ smiles = (
+ "C#CCCCCC(=O)O[C@H]1CC(=O)N(C)c2cc(cc(OC)c2Cl)"
+ "C/C(C)=C/C=C/[C@@H](OC)C2=NC(=O)O[C@@H](C2)[C@@H](C)[C@@H]2O[C@@]12C"
+ )
+ assert mol2mhfp6(smiles).shape == (MHFP6_N_PERMUTATIONS,)
+
+
+def test_mhfp6_bulk_jaccard_counts_matching_minima():
+ import numpy as np
+
+ from plinder.core.structure.smallmols_similarity import (
+ MHFP6_N_PERMUTATIONS,
+ mhfp6_bulk_jaccard,
+ mol2mhfp6,
+ )
+
+ # self-similarity is exact; a distinct molecule scores strictly below 1
+ query = mol2mhfp6("c1ccccc1O")
+ other = mol2mhfp6("c1ccccc1N")
+ similarities = mhfp6_bulk_jaccard(query, np.stack([query, other]))
+ assert similarities[0] == 1.0
+ assert 0.0 <= similarities[1] < 1.0
+
+ # the estimate is by definition the fraction of permutations whose minima
+ # agree: break a controlled 1/4 of the positions and expect exactly 0.75.
+ # (RDKit's MHFPEncoder.Distance is not used here โ the C++ argument type it
+ # accepts is registered differently across RDKit versions.)
+ base = np.arange(MHFP6_N_PERMUTATIONS, dtype=np.uint32)
+ changed = base.copy()
+ changed[: MHFP6_N_PERMUTATIONS // 4] = np.uint32(2**32 - 1)
+ assert mhfp6_bulk_jaccard(base, np.stack([changed]))[0] == 0.75
+
+
+def test_is_chemical_cluster_metric_covers_ecfp4_and_mhfp6():
+ from plinder.core.scores.metrics import (
+ CHEMICAL_CLUSTER_METRICS,
+ is_chemical_cluster_metric,
+ )
+
+ assert set(CHEMICAL_CLUSTER_METRICS) == {
+ "tanimoto_similarity_ecfp4_1024",
+ "jaccard_similarity_mhfp6_2048",
+ }
+ assert is_chemical_cluster_metric("jaccard_similarity_mhfp6_2048")
+ assert is_chemical_cluster_metric("tanimoto_similarity_ecfp4_1024")
+ assert not is_chemical_cluster_metric("pocket_qcov")
+
+
+def test_ecfp4_vs_mhfp6_on_sequence_isomer_edge_cases():
+ """ECFP4 and MHFP6 both handle monomer-order isomers the same way.
+
+ Peptides and nucleic acids are built with RDKit's sequence->mol conversion.
+ Two edge cases are probed: a genuine single-monomer change (should stay
+ similar) versus a sequence permutation of the *same* monomers (a distinct
+ molecule that a local-substructure fingerprint struggles to tell apart).
+ """
+ import numpy as np
+ from rdkit import DataStructs
+
+ from plinder.core.structure.smallmols_similarity import (
+ mhfp6_bulk_jaccard,
+ mol2mhfp6,
+ mol2morgan_fp,
+ )
+
+ def ecfp4(m1, m2):
+ return DataStructs.TanimotoSimilarity(
+ mol2morgan_fp(m1, radius=2, nbits=1024),
+ mol2morgan_fp(m2, radius=2, nbits=1024),
+ )
+
+ def mhfp6(m1, m2):
+ return float(mhfp6_bulk_jaccard(mol2mhfp6(m1), np.stack([mol2mhfp6(m2)]))[0])
+
+ # ---- peptides (flavor=0: L-amino-acid chain) ----
+ gya = Chem.MolFromSequence("GYA", flavor=0) # Gly-Tyr-Ala
+ gfa = Chem.MolFromSequence("GFA", flavor=0) # Gly-Phe-Ala (Tyr->Phe: one -OH)
+ agf = Chem.MolFromSequence("AGF", flavor=0) # same residues, permuted order
+ assert all(m is not None for m in (gya, gfa, agf))
+ # GFA and AGF are genuinely different molecules, not the same input twice
+ assert Chem.MolToSmiles(gfa) != Chem.MolToSmiles(agf)
+
+ # the single-residue change (GYA/GFA) is more similar than the permutation
+ # (GFA/AGF) under BOTH fingerprints, by a clear margin
+ ecfp_margin = ecfp4(gya, gfa) - ecfp4(gfa, agf)
+ mhfp_margin = mhfp6(gya, gfa) - mhfp6(gfa, agf)
+ assert ecfp4(gya, gfa) > ecfp4(gfa, agf)
+ assert mhfp6(gya, gfa) > mhfp6(gfa, agf)
+ assert ecfp_margin > 0.1 and mhfp_margin > 0.1
+ # MHFP6 does not separate this edge case better: the margins are comparable
+ assert abs(mhfp_margin - ecfp_margin) < 0.05
+
+ # ---- nucleic acids (flavor=6: DNA) ----
+ gac = Chem.MolFromSequence("GAC", flavor=6)
+ ggc = Chem.MolFromSequence("GGC", flavor=6) # A->G: single-base change
+ acg = Chem.MolFromSequence("ACG", flavor=6) # same bases, permuted order
+ assert all(m is not None for m in (gac, ggc, acg))
+ # distinct molecules with identical base composition
+ assert Chem.MolToSmiles(gac) != Chem.MolToSmiles(acg)
+
+ # bases sit ~10+ bonds apart along the backbone, far beyond ECFP4 radius 2
+ # and MHFP6 radius 3, so neither fingerprint can see base ORDER: a pure
+ # permutation collides at ~1.0 for BOTH, and even scores at least as high as
+ # a real single-base substitution. MHFP6 does not fix this blind spot.
+ assert ecfp4(gac, acg) > 0.99
+ assert mhfp6(gac, acg) > 0.99
+ assert ecfp4(gac, acg) >= ecfp4(gac, ggc)
+ assert mhfp6(gac, acg) >= mhfp6(gac, ggc)
+
+
+def test_ligand_atom_features_are_hand_checkable_vocabulary_indices():
+ from plinder.core.structure.smallmols_utils import (
+ LIGAND_ATOM_FEATURE_NAMES,
+ ligand_atom_features,
+ )
+
+ benzene = ligand_atom_features(Chem.MolFromSmiles("c1ccccc1"))
+
+ assert benzene.shape == (6, len(LIGAND_ATOM_FEATURE_NAMES))
+ assert benzene.dtype == np.int64
+ # Aromatic carbon: Z=6 -> 5, unspecified chirality, degree 3, charge 0 -> 5,
+ # one implicit H, one H, no radicals, SP2 -> 1, aromatic, in one ring, and
+ # only the six-membered ring flag set.
+ assert benzene.tolist() == [[5, 0, 3, 5, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0]] * 6
+
+ alanine = ligand_atom_features(Chem.MolFromSmiles("C[C@H](N)C(=O)O"))
+ assert alanine.tolist() == [
+ [5, 0, 4, 5, 3, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0], # methyl carbon
+ [5, 2, 4, 5, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0], # CCW alpha carbon
+ [6, 0, 3, 5, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0], # amine nitrogen
+ [5, 0, 3, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], # carbonyl carbon
+ [7, 0, 1, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], # carbonyl oxygen
+ [7, 0, 2, 5, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], # hydroxyl oxygen
+ ]
+
+ cyclopropane = ligand_atom_features(Chem.MolFromSmiles("C1CC1"))
+ assert (
+ cyclopropane.tolist() == [[5, 0, 4, 5, 2, 2, 0, 2, 0, 1, 1, 0, 0, 0, 0, 0]] * 3
+ )
+
+ # Hexafluorophosphate: P is Z=15 -> 14, degree 6, charge -1 -> 4, SP3D2 -> 4.
+ phosphorus = ligand_atom_features(Chem.MolFromSmiles("F[P-](F)(F)(F)(F)F"))[1]
+ assert phosphorus.tolist() == [14, 0, 6, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0]
+
+
+def test_ligand_atom_features_bucket_out_of_vocabulary_values():
+ from plinder.core.structure.smallmols_utils import ligand_atom_features
+
+ # A dummy atom has Z=0 and no hybridization: both land in the "other"
+ # bucket after the 118 elements and the five hybridizations.
+ dummy = ligand_atom_features(Chem.MolFromSmiles("*C"))[0]
+ assert dummy.tolist() == [118, 0, 1, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0]
+
+ ammonium = ligand_atom_features(Chem.MolFromSmiles("[NH4+]"))
+ assert ammonium.tolist() == [[6, 0, 4, 6, 0, 4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0]]
+
+ # Chiral tags outside the tetrahedral pair collapse onto CHI_OTHER.
+ exotic = Chem.MolFromSmiles("C[C@H](N)C(=O)O")
+ exotic.GetAtomWithIdx(1).SetChiralTag(Chem.ChiralType.CHI_TETRAHEDRAL)
+ assert ligand_atom_features(exotic)[1, 1] == 3
+
+ assert ligand_atom_features(Chem.Mol()).shape == (0, 16)
+
+
+def test_rascal_parity_match_carries_the_mapping_behind_the_score():
+ from plinder.core.structure.smallmols_similarity import (
+ rascal_parity_match,
+ rascal_parity_score,
+ )
+
+ serine, cysteine = (
+ Chem.MolFromSmiles("N[C@@H](CO)C(=O)O"),
+ Chem.MolFromSmiles("N[C@@H](CS)C(=O)O"),
+ )
+ same = rascal_parity_match(serine, serine)
+ assert same.atoms == {i: i for i in range(serine.GetNumAtoms())}
+ assert same.bonds == serine.GetNumBonds() and same.opposed == 0
+ match = rascal_parity_match(serine, cysteine)
+ assert set(match.atoms) == {0, 1, 2, 4, 5, 6} # everything but the O/S
+ assert match.score(serine, cysteine) == rascal_parity_score(serine, cysteine)
+ assert rascal_parity_match(serine, Chem.MolFromSmiles("CCCCCCCC")).atoms == {}
+ assert match.alternatives == ()
+ # all equally good fragments: distinct, injective, never bigger than the scored one
+ ring = rascal_parity_match(
+ Chem.MolFromSmiles("c1ccccc1"), Chem.MolFromSmiles("Cc1ccccc1"), all_best=True
+ )
+ assert len(ring.alternatives) == 11 and len(ring.atoms) == 6
+ fragments = [ring.atoms, *ring.alternatives]
+ assert len({tuple(sorted(f.items())) for f in fragments}) == len(fragments)
+ assert all(len(set(f.values())) == len(f) <= 6 for f in fragments)
+ assert fragments == sorted(fragments, key=lambda f: (-len(f), sorted(f.items())))
+ # the scored fragment is the best over every MCES of maximal size, not the first
+ chain, branched = (
+ Chem.MolFromSmiles("CCCCCCC(=O)O"),
+ Chem.MolFromSmiles("CC(C)CCCCC(=O)O"),
+ )
+ every = rascal_parity_match(chain, branched, all_best=True)
+ best = rascal_parity_match(chain, branched)
+ assert len(best.atoms) == max(len(f) for f in (every.atoms, *every.alternatives))
+ assert best.bonds == every.bonds and best.alternatives == ()
+
+
+def test_rascal_parity_coverage_is_directional():
+ from plinder.core.structure.smallmols_similarity import (
+ rascal_parity_coverage,
+ rascal_parity_match,
+ rascal_parity_score,
+ )
+
+ small, large = Chem.MolFromSmiles("CCO"), Chem.MolFromSmiles("CCOCCCCCC")
+ # the small molecule is fully inside the large one: symmetric score is low
+ inside, outside = rascal_parity_coverage(small, large, target=0.0)
+ assert inside == 1.0 and outside < 0.5
+ assert rascal_parity_coverage(large, small, target=0.0) == (outside, inside)
+ assert rascal_parity_score(small, large, target=0.0) < 0.5
+ # identical molecules are covered both ways; unrelated ones not at all
+ assert rascal_parity_coverage(small, small) == (1.0, 1.0)
+ assert rascal_parity_coverage(small, Chem.MolFromSmiles("BrBr")) == (0.0, 0.0)
+ # the coverage of each side never falls below the symmetric score
+ match = rascal_parity_match(small, large, target=0.0)
+ assert min(match.coverage(small, large)) >= match.score(small, large)
+
+
+def test_rascal_parity_score_sees_order_stereo_and_size():
+ from rdkit import Chem
+
+ from plinder.core.structure.smallmols_similarity import rascal_parity_score
+
+ peptide = Chem.MolFromSequence
+ score = rascal_parity_score
+ assert score(peptide("ACDEF"), peptide("ACDEF")) == 1.0
+ substitution = score(peptide("ACDEF"), peptide("ACDKF"))
+ shuffled = score(peptide("ACDEF"), peptide("DFACE"))
+ unrelated = score(peptide("ACDEF"), peptide("GHIKL"))
+ assert substitution > shuffled and substitution > unrelated
+ # an internal deletion splits the largest fragment; a terminal one does not
+ assert score(peptide("ACDEF"), peptide("ACDF")) < score(
+ peptide("ACDEF"), peptide("ACDE")
+ )
+ # stereo: lactose vs cellobiose differ at one centre, glucose vs galactose likewise
+ lactose = Chem.MolFromSmiles(
+ "OC[C@H]1O[C@@H](O[C@H]2[C@H](O)[C@@H](O)[C@H](O)O[C@@H]2CO)[C@H](O)[C@@H](O)[C@H]1O"
+ )
+ cellobiose = Chem.MolFromSmiles(
+ "OC[C@H]1O[C@@H](O[C@H]2[C@H](O)[C@@H](O)[C@H](O)O[C@@H]2CO)[C@H](O)[C@@H](O)[C@@H]1O"
+ )
+ glucose = Chem.MolFromSmiles("OC[C@H]1O[C@H](O)[C@H](O)[C@@H](O)[C@@H]1O")
+ galactose = Chem.MolFromSmiles("OC[C@H]1O[C@@H](O)[C@H](O)[C@@H](O)[C@H]1O")
+ assert score(lactose, lactose) == 1.0
+ assert 0.9 < score(lactose, cellobiose) < 1.0
+ assert 0.8 < score(glucose, galactose) < 1.0
+ assert score(lactose, cellobiose, stereo=False) == 1.0
+ # handedness is compared through the mapping, not by CIP label: L-serine and
+ # L-cysteine have opposite CIP labels (S vs R) but the same arrangement
+ l_serine, l_cysteine = (
+ Chem.MolFromSmiles("N[C@@H](CO)C(=O)O"),
+ Chem.MolFromSmiles("N[C@@H](CS)C(=O)O"),
+ )
+ d_serine = Chem.MolFromSmiles("N[C@H](CO)C(=O)O")
+ assert score(l_serine, l_cysteine) == score(l_serine, l_cysteine, stereo=False)
+ assert score(l_serine, d_serine) < score(l_serine, l_serine) == 1.0
+ # a swapped connecting atom keeps the bonds of both rings but splits the largest fragment
+ ether, methane = (
+ Chem.MolFromSmiles("c1ccccc1Oc1ccccc1"),
+ Chem.MolFromSmiles("c1ccccc1Cc1ccccc1"),
+ )
+ assert 0.4 < score(ether, methane) < 0.9
+ # below the pruning target nothing is searched
+ assert score(Chem.MolFromSmiles("CCO"), peptide("ACDEF")) == 0.0
diff --git a/tests/core/test_source_mmcif.py b/tests/core/test_source_mmcif.py
new file mode 100644
index 000000000..973423b63
--- /dev/null
+++ b/tests/core/test_source_mmcif.py
@@ -0,0 +1,418 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from __future__ import annotations
+
+from pathlib import Path
+
+import pandas as pd
+import pytest
+
+from plinder.core import PlinderRelease, PlinderSystem
+from plinder.core.utils import config
+from plinder.core.utils import io as core_io
+from plinder.core.utils.cpl import is_offline
+
+
+class _Response:
+ def __init__(self, content: bytes, status_code: int = 200) -> None:
+ self.content = content
+ self.status_code = status_code
+
+ def raise_for_status(self) -> None:
+ if self.status_code >= 400:
+ raise RuntimeError(f"HTTP {self.status_code}")
+
+ def iter_content(self, chunk_size: int):
+ yield from (
+ self.content[offset : offset + chunk_size]
+ for offset in range(0, len(self.content), chunk_size)
+ )
+
+
+@pytest.fixture
+def release_cache(tmp_path, monkeypatch):
+ monkeypatch.setenv("PLINDER_MOUNT", tmp_path.as_posix())
+ monkeypatch.setenv("PLINDER_BUCKET", "plinder")
+ monkeypatch.setenv("PLINDER_RELEASE", "test")
+ monkeypatch.setenv("PLINDER_RELEASE_NUMBER", "")
+ monkeypatch.delenv("PLINDER_OFFLINE", raising=False)
+ monkeypatch.delenv("PLINDER_OFFLINE_MODE", raising=False)
+ config._config._clear()
+ yield Path(config.get_config().data.plinder_dir)
+ config._config._clear()
+
+
+@pytest.fixture
+def source_manifest(release_cache):
+ path = release_cache / "index" / "entry_sources.parquet"
+ path.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["2y4i", "9zzz"],
+ "source_mmcif_major_revision": [1, 1],
+ "source_mmcif_minor_revision": [5, 0],
+ }
+ ).to_parquet(path, index=False)
+ return path
+
+
+def test_source_mmcif_download_cache_and_system_resolution(
+ release_cache, source_manifest, cif_2y4i, monkeypatch
+):
+ calls = []
+
+ def get(url, *, stream, timeout):
+ calls.append((url, stream, timeout))
+ return _Response(cif_2y4i.read_bytes())
+
+ monkeypatch.setattr(core_io.requests, "get", get)
+
+ path = core_io.get_pdb_mmcif("2Y4I", manifest_path=source_manifest)
+ expected = release_cache / "source_mmcifs" / "y4" / "2y4i_v1-5.cif.gz"
+ assert path == expected
+ assert path.is_file()
+ assert calls == [
+ (
+ "https://files-versioned.wwpdb.org/pdb_versioned/data/entries/"
+ "y4/pdb_00002y4i/pdb_00002y4i_xyz_v1-5.cif.gz",
+ True,
+ (10, 120),
+ )
+ ]
+
+ # A system ID resolves to the same valid cache entry without another request.
+ assert (
+ core_io.get_pdb_mmcif(
+ "2y4i__1__1.B__1.E_1.F",
+ manifest_path=source_manifest,
+ )
+ == expected
+ )
+ assert len(calls) == 1
+
+ manifest_requests = []
+
+ def fetch_release_artifact(_release, name, **parameters):
+ manifest_requests.append((name, parameters))
+ return source_manifest
+
+ monkeypatch.setattr(
+ core_io.PlinderRelease,
+ "fetch",
+ fetch_release_artifact,
+ )
+ assert (
+ PlinderSystem(system_id="2y4i__1__1.B__1.E_1.F").source_mmcif_path == expected
+ )
+ assert manifest_requests == [("entry_sources", {})]
+ assert len(calls) == 1
+
+
+@pytest.mark.usefixtures("release_cache")
+def test_system_source_mmcif_uses_explicit_release_cache(
+ cif_2y4i, tmp_path, monkeypatch
+):
+ release_root = tmp_path / "release"
+ manifest = release_root / "index" / "entry_sources.parquet"
+ manifest.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["2y4i"],
+ "source_mmcif_major_revision": [1],
+ "source_mmcif_minor_revision": [5],
+ }
+ ).to_parquet(manifest, index=False)
+ monkeypatch.setattr(
+ core_io.requests,
+ "get",
+ lambda *_args, **_kwargs: _Response(cif_2y4i.read_bytes()),
+ )
+
+ system = PlinderSystem(
+ system_id="2y4i__1__1.B__1.E_1.F",
+ release=PlinderRelease(data_dir=release_root),
+ )
+
+ assert system.source_mmcif_path == (
+ release_root / "source_mmcifs" / "y4" / "2y4i_v1-5.cif.gz"
+ )
+
+
+def test_source_mmcif_offline_mode_requires_valid_cache(
+ release_cache, source_manifest, cif_2y4i, monkeypatch
+):
+ monkeypatch.setenv("PLINDER_OFFLINE_MODE", "true")
+ assert is_offline()
+ expected = core_io.pdb_mmcif_cache_path(
+ "2y4i",
+ manifest_path=source_manifest,
+ )
+
+ with pytest.raises(FileNotFoundError, match="online node first") as exc:
+ core_io.get_pdb_mmcif("2y4i", manifest_path=source_manifest)
+ assert str(expected) in str(exc.value)
+ assert not expected.parent.exists()
+
+ expected.parent.mkdir(parents=True)
+ expected.write_bytes(cif_2y4i.read_bytes())
+ monkeypatch.setattr(
+ core_io.requests,
+ "get",
+ lambda *args, **kwargs: pytest.fail("offline mode attempted a request"),
+ )
+ assert (
+ core_io.get_pdb_mmcif(
+ "2y4i",
+ force_update=True,
+ manifest_path=source_manifest,
+ )
+ == expected
+ )
+
+
+def test_source_mmcif_replaces_corrupt_online_cache(
+ release_cache, source_manifest, cif_2y4i, monkeypatch
+):
+ expected = core_io.pdb_mmcif_cache_path(
+ "2y4i",
+ manifest_path=source_manifest,
+ )
+ expected.parent.mkdir(parents=True)
+ expected.write_bytes(b"not a gzip file")
+ monkeypatch.setattr(
+ core_io.requests,
+ "get",
+ lambda *args, **kwargs: _Response(cif_2y4i.read_bytes()),
+ )
+
+ assert core_io.get_pdb_mmcif("2y4i", manifest_path=source_manifest) == expected
+ core_io._validate_gzipped_mmcif(expected, expected_revision=(1, 5))
+ assert not list(expected.parent.glob("*.tmp"))
+
+
+def test_source_mmcif_reports_missing_versioned_entry(
+ release_cache, source_manifest, monkeypatch
+):
+ calls = []
+
+ def get(*args, **kwargs):
+ calls.append(args[0])
+ return _Response(b"", status_code=404)
+
+ monkeypatch.setattr(
+ core_io.requests,
+ "get",
+ get,
+ )
+ monkeypatch.setattr(
+ core_io,
+ "sleep",
+ lambda seconds: pytest.fail("404 response was retried"),
+ )
+
+ with pytest.raises(FileNotFoundError, match="revision 1.0"):
+ core_io.get_pdb_mmcif("9zzz", manifest_path=source_manifest)
+ assert len(calls) == 1
+ assert not core_io.pdb_mmcif_cache_path(
+ "9zzz",
+ manifest_path=source_manifest,
+ ).exists()
+
+
+def test_download_pdb_mmcifs_deduplicates_system_ids(
+ release_cache, source_manifest, cif_2y4i, monkeypatch
+):
+ calls = []
+
+ def get(url, *, stream, timeout):
+ calls.append(url)
+ return _Response(cif_2y4i.read_bytes())
+
+ monkeypatch.setattr(core_io.requests, "get", get)
+ paths = core_io.download_pdb_mmcifs(
+ ["2y4i", "2y4i__1__1.B__1.E_1.F"],
+ manifest_path=source_manifest,
+ )
+
+ assert set(paths) == {"2y4i"}
+ assert paths["2y4i"].is_file()
+ assert calls == [
+ "https://files-versioned.wwpdb.org/pdb_versioned/data/entries/"
+ "y4/pdb_00002y4i/pdb_00002y4i_xyz_v1-5.cif.gz"
+ ]
+
+ with pytest.raises(ValueError, match="max_workers"):
+ core_io.download_pdb_mmcifs(
+ ["2y4i"],
+ max_workers=0,
+ manifest_path=source_manifest,
+ )
+
+
+def test_source_mmcif_retries_transient_http_status(
+ release_cache, source_manifest, cif_2y4i, monkeypatch
+):
+ responses = [
+ _Response(b"temporarily unavailable", status_code=503),
+ _Response(cif_2y4i.read_bytes()),
+ ]
+ waits = []
+ monkeypatch.setattr(
+ core_io.requests,
+ "get",
+ lambda *args, **kwargs: responses.pop(0),
+ )
+ monkeypatch.setattr(core_io, "sleep", waits.append)
+
+ path = core_io.get_pdb_mmcif("2y4i", manifest_path=source_manifest)
+
+ assert path.is_file()
+ assert responses == []
+ assert waits == [1]
+
+
+def test_batch_source_download_retries_timeout(
+ release_cache, source_manifest, cif_2y4i, monkeypatch
+):
+ calls = 0
+ waits = []
+
+ def get(*args, **kwargs):
+ nonlocal calls
+ calls += 1
+ if calls == 1:
+ raise core_io.requests.exceptions.Timeout("temporary timeout")
+ return _Response(cif_2y4i.read_bytes())
+
+ monkeypatch.setattr(core_io.requests, "get", get)
+ monkeypatch.setattr(core_io, "sleep", waits.append)
+
+ paths = core_io.download_pdb_mmcifs(
+ ["2y4i"],
+ manifest_path=source_manifest,
+ )
+
+ assert paths["2y4i"].is_file()
+ assert calls == 2
+ assert waits == [1]
+
+
+def test_source_mmcif_transient_retries_are_bounded(
+ release_cache, source_manifest, monkeypatch
+):
+ calls = 0
+ waits = []
+
+ def get(*args, **kwargs):
+ nonlocal calls
+ calls += 1
+ return _Response(b"temporarily unavailable", status_code=503)
+
+ monkeypatch.setattr(core_io.requests, "get", get)
+ monkeypatch.setattr(core_io, "sleep", waits.append)
+
+ with pytest.raises(RuntimeError, match="HTTP 503"):
+ core_io.get_pdb_mmcif("2y4i", manifest_path=source_manifest)
+
+ assert calls == core_io.SOURCE_MMCIF_DOWNLOAD_ATTEMPTS == 3
+ assert waits == [1, 2]
+
+
+def test_parser_failure_replaces_cache_online(
+ release_cache, source_manifest, cif_2y4i, monkeypatch
+):
+ expected = core_io.pdb_mmcif_cache_path(
+ "2y4i",
+ manifest_path=source_manifest,
+ )
+ expected.parent.mkdir(parents=True)
+ expected.write_bytes(cif_2y4i.read_bytes())
+ original_read = core_io.CIFFile.read
+ read_calls = 0
+
+ def read(handle):
+ nonlocal read_calls
+ read_calls += 1
+ if read_calls == 1:
+ raise core_io.DeserializationError("malformed cached CIF")
+ return original_read(handle)
+
+ monkeypatch.setattr(core_io.CIFFile, "read", read)
+ monkeypatch.setattr(
+ core_io.requests,
+ "get",
+ lambda *args, **kwargs: _Response(cif_2y4i.read_bytes()),
+ )
+
+ assert core_io.get_pdb_mmcif("2y4i", manifest_path=source_manifest) == expected
+ assert read_calls == 2
+ assert not list(expected.parent.glob("*.tmp"))
+
+
+def test_parser_failure_is_missing_cache_offline(
+ release_cache, source_manifest, cif_2y4i, monkeypatch
+):
+ expected = core_io.pdb_mmcif_cache_path(
+ "2y4i",
+ manifest_path=source_manifest,
+ )
+ expected.parent.mkdir(parents=True)
+ expected.write_bytes(cif_2y4i.read_bytes())
+ monkeypatch.setenv("PLINDER_OFFLINE", "true")
+
+ def read(handle):
+ raise core_io.DeserializationError("malformed cached CIF")
+
+ monkeypatch.setattr(core_io.CIFFile, "read", read)
+ monkeypatch.setattr(
+ core_io.requests,
+ "get",
+ lambda *args, **kwargs: pytest.fail("offline mode attempted a request"),
+ )
+
+ with pytest.raises(FileNotFoundError, match="online node first"):
+ core_io.get_pdb_mmcif("2y4i", manifest_path=source_manifest)
+
+
+def test_source_manifest_pins_revision(source_manifest):
+ assert core_io.get_pdb_revision(
+ "PDB_00002Y4I__1__1.B__1.E_1.F",
+ manifest_path=source_manifest,
+ ) == (1, 5)
+ with pytest.raises(KeyError, match="missing"):
+ core_io.get_pdb_revision("1abc", manifest_path=source_manifest)
+ assert core_io._get_pdb_revisions(
+ ["2y4i", "9zzz"],
+ manifest_path=source_manifest,
+ ) == {"2y4i": (1, 5), "9zzz": (1, 0)}
+
+
+@pytest.mark.parametrize(
+ "value, expected",
+ [("true", True), ("1", True), ("false", False), ("0", False), ("", False)],
+)
+def test_offline_mode_alias_parsing(monkeypatch, value, expected):
+ monkeypatch.delenv("PLINDER_OFFLINE", raising=False)
+ monkeypatch.setenv("PLINDER_OFFLINE_MODE", value)
+ assert is_offline() is expected
+
+
+def test_source_mmcif_rejects_wrong_version(release_cache, cif_2y4i, monkeypatch):
+ monkeypatch.setattr(
+ core_io.requests,
+ "get",
+ lambda *args, **kwargs: _Response(cif_2y4i.read_bytes()),
+ )
+
+ with pytest.raises(ValueError, match="revision mismatch"):
+ core_io.get_pdb_mmcif("2y4i", revision=(2, 0))
+ assert not core_io.pdb_mmcif_cache_path(
+ "2y4i",
+ revision=(2, 0),
+ ).exists()
+
+
+@pytest.mark.parametrize("value", ["", "../../etc/passwd", "not-a-pdb"])
+def test_source_mmcif_rejects_invalid_ids(value):
+ with pytest.raises(ValueError, match="invalid PDB ID"):
+ core_io.pdb_mmcif_cache_path(value, revision=(1, 0))
diff --git a/tests/core/test_split_plot.py b/tests/core/test_split_plot.py
deleted file mode 100644
index ed4af5512..000000000
--- a/tests/core/test_split_plot.py
+++ /dev/null
@@ -1,25 +0,0 @@
-def test_split_plot(write_plinder_mount, split_plot_split_file, tmp_path):
- from plinder.core.split.plot import SplitPropertiesPlotter
-
- output_dir = tmp_path / "split_plots"
- output_dir.mkdir(exist_ok=True)
-
- plotter = SplitPropertiesPlotter.from_files(
- data_dir=write_plinder_mount,
- split_file=split_plot_split_file,
- output_dir=output_dir,
- # stratified_train_test_file=write_plinder_mount / "strat" / "train_vs_test_data" / "test_set.parquet",
- # stratified_train_val_file=write_plinder_mount / "strat" / "train_vs_val_data" / "val_set.parquet",
- stratified_val_test_file=write_plinder_mount
- / "strat"
- / "val_vs_test_data"
- / "test_set.parquet",
- make_plots=False,
- )
- try:
- plotter.plot_all()
- except Exception as e:
- print(e)
- pass
-
- assert len(list(output_dir.rglob("*"))) > 0
diff --git a/tests/core/test_structure_inputs.py b/tests/core/test_structure_inputs.py
new file mode 100644
index 000000000..c4d0d8198
--- /dev/null
+++ b/tests/core/test_structure_inputs.py
@@ -0,0 +1,302 @@
+"""The shared table keeps each structure associated with its own ligand poses."""
+
+import gzip
+import importlib
+
+import numpy as np
+import pandas as pd
+import pytest
+from rdkit import Chem
+
+from plinder.core.structure.inputs import (
+ StructureInput,
+ read_structure_table,
+ write_search_structure,
+)
+
+
+@pytest.mark.parametrize("suffix", [".csv", ".tsv", ".parquet"])
+def test_table_groups_ligands_and_resolves_relative_paths(tmp_path, suffix):
+ frame = pd.DataFrame(
+ {
+ "input_id": ["one", "one", "two"],
+ "structure_path": ["one.pdb", "one.pdb", "two.cif"],
+ "ligand_path": ["a.sdf", "b.sdf", ""],
+ "reference_id": ["1avd", "1avd", "2e31"],
+ }
+ )
+ path = tmp_path / f"inputs{suffix}"
+ if suffix == ".parquet":
+ frame.to_parquet(path)
+ else:
+ frame.to_csv(path, sep="\t" if suffix == ".tsv" else ",", index=False)
+ inputs = read_structure_table(path, require_reference=True)
+ assert inputs["one"].coordinates == tmp_path / "one.pdb"
+ assert inputs["one"].ligand_sdfs == (tmp_path / "a.sdf", tmp_path / "b.sdf")
+ assert inputs["one"].reference_id == "1avd"
+ assert inputs["two"].ligand_sdfs is None
+
+
+@pytest.mark.parametrize(
+ "field,values,error",
+ [
+ ("input_id", ["../escape", "one"], "Invalid input_id"),
+ ("structure_path", ["a.cif", "b.cif"], "Conflicting structure_path"),
+ ("reference_id", ["1avd", "2e31"], "Conflicting reference_id"),
+ ("ligand_path", ["a.sdf", "a.sdf"], "Repeated ligand"),
+ ],
+)
+def test_table_rejects_ambiguous_inputs(field, values, error):
+ frame = pd.DataFrame(
+ {
+ "input_id": ["one", "one"],
+ "structure_path": ["a.cif", "a.cif"],
+ "reference_id": ["1avd", "1avd"],
+ "ligand_path": ["a.sdf", "b.sdf"],
+ }
+ )
+ frame[field] = values
+ with pytest.raises(ValueError, match=error):
+ read_structure_table(frame)
+
+
+def test_reference_column_required_only_for_evaluation():
+ frame = pd.DataFrame({"input_id": ["one"], "structure_path": ["one.cif"]})
+ assert read_structure_table(frame)["one"].reference_id is None
+ with pytest.raises(ValueError, match="reference_id"):
+ read_structure_table(frame, require_reference=True)
+
+
+def test_search_cif_preserves_separate_ligand_chemistry(test_dir, tmp_path):
+ from plinder.data.annotations.cif_utils import (
+ atoms_to_rdkit_mol,
+ check_cif_bond_orders,
+ check_custom_mmcif_fields,
+ get_structure_with_altloc,
+ read_mmcif_file,
+ )
+
+ root = test_dir / "reconstructed_systems/1avd__1__1.A__1.C"
+ ligand_path = root / "ligand_files/1.C.sdf"
+ second = tmp_path / "other.sdf"
+ molecule = Chem.MolFromSmiles("C[NH3+]")
+ conf = Chem.Conformer(2)
+ conf.SetAtomPosition(0, (100, 0, 0))
+ conf.SetAtomPosition(1, (101.4, 0, 0))
+ molecule.AddConformer(conf)
+ with Chem.SDWriter(str(second)) as writer:
+ writer.write(molecule)
+ structure = StructureInput(root / "receptor.cif", [ligand_path, second])
+ output = write_search_structure(
+ structure, tmp_path / "query.cif", include_ligands=True
+ )
+ cif = read_mmcif_file(output)
+ check_custom_mmcif_fields(
+ cif.block, source=output, structure_mode="as_is", require_label_ids=True
+ )
+ check_cif_bond_orders(cif)
+ atoms = get_structure_with_altloc(cif, include_bonds=True)
+ assert set(atoms.chain_id) == {"1.A", "L0001", "L0002"}
+ for chain, source in [("L0001", ligand_path), ("L0002", second)]:
+ expected = next(Chem.SDMolSupplier(str(source)))
+ selected = atoms[atoms.chain_id == chain]
+ actual = atoms_to_rdkit_mol(selected)
+ assert Chem.MolToSmiles(Chem.RemoveHs(actual)) == Chem.MolToSmiles(
+ Chem.RemoveHs(expected)
+ )
+ np.testing.assert_allclose(
+ selected.coord, expected.GetConformer().GetPositions(), atol=1e-3
+ )
+ mapping = pd.read_csv(output.with_suffix(".ligands.tsv"), sep="\t")
+ assert mapping["ligand_path"].tolist() == [
+ str(ligand_path.resolve()),
+ str(second.resolve()),
+ ]
+
+
+@pytest.mark.parametrize(
+ "smiles",
+ ["[B]12[B]3[B]4[B]1[B]5[B]6[B]2[B]3[B]45C6", "[Be](C)(C)(C)C"],
+ ids=["boron-cage", "beryllium"],
+)
+def test_search_accepts_supported_overvalent_sdfs(test_dir, tmp_path, smiles):
+ from biotite.interface.rdkit import from_mol
+
+ from plinder.core.utils.sanitize import sanitize
+ from plinder.data.annotations.cif_utils import (
+ get_structure_with_altloc,
+ read_mmcif_file,
+ )
+
+ molecule = Chem.MolFromSmiles(smiles, sanitize=False)
+ sanitize(molecule)
+ # These are supported by PLINDER but still rejected by strict RDKit checks.
+ with pytest.raises(Chem.AtomValenceException):
+ Chem.SanitizeMol(Chem.Mol(molecule))
+ coordinates = np.arange(molecule.GetNumAtoms() * 3).reshape(-1, 3).astype(float)
+ conformer = Chem.Conformer(molecule.GetNumAtoms())
+ for index, position in enumerate(coordinates):
+ conformer.SetAtomPosition(index, position)
+ molecule.AddConformer(conformer)
+ sdf = tmp_path / "pose.sdf"
+ with Chem.SDWriter(str(sdf)) as writer:
+ writer.write(molecule)
+ original = sdf.read_bytes()
+ receptor = test_dir / "reconstructed_systems/1avd__1__1.A__1.C/receptor.cif"
+ output = write_search_structure(
+ StructureInput(receptor, [sdf]), tmp_path / "query.cif", include_ligands=True
+ )
+ atoms = get_structure_with_altloc(read_mmcif_file(output), include_bonds=True)
+ ligand = atoms[atoms.chain_id == "L0001"]
+ expected = from_mol(molecule, conformer_id=0, add_hydrogen=False)
+ np.testing.assert_allclose(ligand.coord, coordinates, atol=1e-3)
+ np.testing.assert_array_equal(ligand.element, expected.element)
+ np.testing.assert_array_equal(ligand.charge, expected.charge)
+ np.testing.assert_array_equal(ligand.bonds.as_array(), expected.bonds.as_array())
+ assert sdf.read_bytes() == original
+
+
+def test_search_rejects_unrepairable_ligand_valence(test_dir, tmp_path):
+ molecule = Chem.MolFromSmiles("C(C)(C)(C)(C)C", sanitize=False)
+ molecule.UpdatePropertyCache(strict=False)
+ conformer = Chem.Conformer(molecule.GetNumAtoms())
+ for index in range(molecule.GetNumAtoms()):
+ conformer.SetAtomPosition(index, (float(index), 0.0, 0.0))
+ molecule.AddConformer(conformer)
+ sdf = tmp_path / "invalid.sdf"
+ with Chem.SDWriter(str(sdf)) as writer:
+ writer.write(molecule)
+ receptor = test_dir / "reconstructed_systems/1avd__1__1.A__1.C/receptor.cif"
+ with pytest.raises(Chem.AtomValenceException):
+ write_search_structure(
+ StructureInput(receptor, [sdf]),
+ tmp_path / "query.cif",
+ include_ligands=True,
+ )
+
+
+@pytest.mark.parametrize("suffix", [".pdb", ".PDB.gz"])
+@pytest.mark.parametrize("include_ligands", [False, True])
+def test_pdb_search_sequences_exclude_nonpolymers(
+ test_dir, tmp_path, suffix, include_ligands
+):
+ import biotite.structure as struc
+ from biotite.structure.io import pdb
+
+ from plinder.core.scores.custom import write_custom_query_files
+ from plinder.data.annotations.cif_utils import (
+ get_structure_with_altloc,
+ read_mmcif_file,
+ )
+
+ # Waters/ions share author chains with proteins; MSE is also HETATM.
+ atoms = struc.AtomArray(9)
+ atoms.chain_id = np.array(["A"] * 6 + ["B"] * 3)
+ atoms.res_name = np.array(
+ ["ALA", "HOH", "MSE", "ZN", "GLY", "HOH", "SER", "CL", "THR"]
+ )
+ atoms.res_id = np.array([10, 501, 10, 502, 20, 503, 40, 601, 45])
+ atoms.ins_code[2] = "A"
+ atoms.hetero = np.array([False, True, True, True, False, True, False, True, False])
+ atoms.atom_name = np.array(["CA", "O", "CA", "ZN", "CA", "O", "CA", "CL", "CA"])
+ atoms.element = np.array(["C", "O", "C", "Zn", "C", "O", "C", "Cl", "C"])
+ atoms.coord = np.arange(27, dtype=float).reshape(9, 3)
+ source = tmp_path / f"receptor{suffix}"
+ pdb_file = pdb.PDBFile()
+ pdb_file.set_structure(atoms)
+ with (
+ gzip.open(source, "wt") if suffix.endswith(".gz") else source.open("w")
+ ) as stream:
+ pdb_file.write(stream)
+ original = source.read_bytes()
+ sdf = test_dir / "reconstructed_systems/1avd__1__1.A__1.C/ligand_files/1.C.sdf"
+ output = write_search_structure(
+ StructureInput(source, [sdf] if include_ligands else None),
+ tmp_path / "query.cif",
+ include_ligands=include_ligands,
+ )
+ cif = read_mmcif_file(output)
+ converted = get_structure_with_altloc(cif, include_bonds=True)
+ protein = converted[np.isin(converted.chain_id, ["A", "B"])]
+ assert protein.res_name.tolist() == ["ALA", "MSE", "GLY", "SER", "THR"]
+ assert protein.chain_id.tolist() == ["A", "A", "A", "B", "B"]
+ assert protein.res_id.tolist() == [1, 2, 3, 1, 2]
+ assert protein.ins_code.tolist() == ["", "A", "", "", ""]
+ np.testing.assert_allclose(protein.coord, atoms.coord[[0, 2, 4, 6, 8]])
+ sites = cif.block["atom_site"]
+ selected = np.isin(sites["label_asym_id"].as_array(str), ["A", "B"])
+ assert sites["auth_seq_id"].as_array(int)[selected].tolist() == [10, 10, 20, 40, 45]
+ assert cif.block["entity_poly_seq"]["mon_id"].as_array(str).tolist() == [
+ "ALA",
+ "MSE",
+ "GLY",
+ "SER",
+ "THR",
+ ]
+ assert ("L0001" in converted.chain_id) == include_ligands
+ queries = write_custom_query_files(
+ [output], work_dir=tmp_path / "search", min_chain_length=1
+ )
+ manifest = pd.read_parquet(queries.chain_manifest).set_index("chain_asym_id")
+ assert set(manifest.index) == {"A", "B"}
+ assert manifest.loc["A", "sequence_length"] == 3
+ assert manifest.loc["B", "sequence"] == "ST"
+ assert list(manifest.loc["A", "resolved_residue_numbers"]) == [1, 2, 3]
+ assert list(manifest.loc["B", "resolved_residue_numbers"]) == [1, 2]
+ assert source.read_bytes() == original
+
+
+def test_search_dispatches_fasta_folder_and_table(test_dir, tmp_path, monkeypatch):
+ module = importlib.import_module("plinder.core.scores.search")
+ calls = []
+ monkeypatch.setattr(
+ module,
+ "score_custom_sequence_file",
+ lambda source, **kw: calls.append((source, kw)),
+ )
+ monkeypatch.setattr(
+ module,
+ "score_custom_cif_files",
+ lambda sources, **kw: calls.append((sources, kw)),
+ )
+ module.search(tmp_path / "query.fasta", output_dir=tmp_path / "fasta_search")
+ assert calls[-1][1]["backends"] == ("mmseqs",)
+ folder = tmp_path / "models"
+ folder.mkdir()
+ original = test_dir / "reconstructed_systems/1avd__1__1.A__1.C/receptor.cif"
+ (folder / "one.cif").write_bytes(original.read_bytes())
+ module.search(folder, output_dir=tmp_path / "folder_search")
+ assert calls[-1][1]["include_ligands"] is False
+ table = pd.DataFrame({"input_id": ["custom_id"], "structure_path": [str(original)]})
+ module.search(table, output_dir=tmp_path / "table_search", mode="ligands")
+ assert calls[-1][0][0].name == "custom_id.cif"
+ assert calls[-1][1]["include_ligands"] is True
+ with pytest.raises(ValueError, match="input table"):
+ module.search(folder, output_dir=tmp_path / "bad", mode="ligands")
+ with pytest.raises(ValueError, match="FASTA inputs"):
+ module.search(
+ tmp_path / "query.fa", output_dir=tmp_path / "bad", mode="interfaces"
+ )
+
+
+def test_search_annotation_keeps_dotted_chain_ids(test_dir, tmp_path, monkeypatch):
+ from plinder.core.scores.custom import annotate_custom_cif_files
+ from plinder.data.annotations import ligand_utils
+
+ monkeypatch.setattr(ligand_utils, "BINDING_AFFINITY", {})
+ root = test_dir / "reconstructed_systems/1avd__1__1.A__1.C"
+ source = StructureInput(root / "receptor.cif", [root / "ligand_files/1.C.sdf"])
+ cif = write_search_structure(source, tmp_path / "paired.cif", include_ligands=True)
+ annotations = annotate_custom_cif_files(
+ [cif], work_dir=tmp_path / "annotated", include_interfaces=False
+ )
+ entry = annotations.entries_by_structure["paired"]
+ rows = pd.read_parquet(annotations.annotation_table)
+ assert not rows.empty
+ assert "1.A" in entry.chains
+ assert entry.chains["1.A"].holo
+ assert all(
+ "1.1.A" in system.pocket_residue_number_to_index
+ for system in entry.systems.values()
+ )
+ assert not pd.read_parquet(annotations.entry_chains).empty
diff --git a/tests/core/test_superimpose.py b/tests/core/test_superimpose.py
index 7757ebb6f..35b3b1d44 100644
--- a/tests/core/test_superimpose.py
+++ b/tests/core/test_superimpose.py
@@ -1,32 +1,38 @@
-from plinder.core.index import PlinderSystem
+from zipfile import ZipFile
+
+from biotite.sequence.io.fasta import FastaFile
+
from plinder.core.structure.structure import Structure
-def test_superimpose_chain(read_plinder_mount):
+def test_superimpose_chain(read_plinder_mount, tmp_path):
"""
Check if :func:`superimpose_chain()` can handle different scenarios.
In all cases the superimposed structure should have the original number of atoms
and a low RMSD to the fixed structure.
"""
- # TODO: review if this test is still relevant
- pass
- system_id_1 = "19hc__1__1.A_1.B__1.G"
- system_id_2 = "19hc__1__1.A_1.B__1.V_1.X_1.Y"
- # system_dir_1 = read_plinder_mount / "systems" / system_id_1
- # system_dir_2 = read_plinder_mount / "systems" / system_id_2
+ system_id_1 = "1avd__1__1.A_2.A__1.D"
+ system_id_2 = "1avd__1__1.A_2.A__2.D"
chain_id_1 = "1.A"
- # chain_id_2 = "1.A"
- struct1 = PlinderSystem(system_id=system_id_1).holo_structure
- struct2 = PlinderSystem(system_id=system_id_2).holo_structure
+ with ZipFile(read_plinder_mount / "systems" / "av.zip") as archive:
+ receptor_1 = archive.extract(f"{system_id_1}/receptor.cif", tmp_path)
+ receptor_2 = archive.extract(f"{system_id_2}/receptor.cif", tmp_path)
+ sequences_1 = archive.extract(f"{system_id_1}/sequences.fasta", tmp_path)
+ sequences_2 = archive.extract(f"{system_id_2}/sequences.fasta", tmp_path)
+ struct1 = Structure(
+ id=system_id_1,
+ protein_path=receptor_1,
+ protein_sequence=dict(FastaFile.read_iter(sequences_1)),
+ )
+ struct2 = Structure(
+ id=system_id_2,
+ protein_path=receptor_2,
+ protein_sequence=dict(FastaFile.read_iter(sequences_2)),
+ )
chain_1_array = struct1.protein_atom_array[
struct1.protein_atom_array.chain_id == chain_id_1
]
- # # TODO: test assertions here
- # chain_2_array = struct2.protein_atom_array[
- # struct2.protein_atom_array.chain_id == chain_id_2
- # ]
-
super_chain_1, raw_rmsd, refined_rmsd = struct1.superimpose(struct2)
assert isinstance(super_chain_1, Structure)
super_chain_1_array = super_chain_1.protein_atom_array[
diff --git a/tests/core/test_table_query.py b/tests/core/test_table_query.py
new file mode 100644
index 000000000..5e10dacba
--- /dev/null
+++ b/tests/core/test_table_query.py
@@ -0,0 +1,624 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from __future__ import annotations
+
+from pathlib import Path
+
+import numpy as np
+import pandas as pd
+import pytest
+
+from plinder.core import PlinderRelease, query_table
+
+
+def _write_table(
+ release: PlinderRelease,
+ artifact: str,
+ data: dict[str, list[object]],
+) -> None:
+ path = release.path(artifact)
+ path.parent.mkdir(parents=True, exist_ok=True)
+ pd.DataFrame(data).to_parquet(path, index=False)
+
+
+@pytest.fixture
+def local_release(tmp_path: Path) -> PlinderRelease:
+ release = PlinderRelease(tmp_path)
+ _write_table(
+ release,
+ "annotation_table",
+ {
+ "ligand_id": ["1abc__1__1.L", "2def__1__1.M", "3ghi__1__1.N"],
+ "system_id": [
+ "1abc__1__1.A__1.L",
+ "2def__1__1.B__1.M",
+ "3ghi__1__1.C__1.N",
+ ],
+ "entry_pdb_id": ["1abc", "2def", "3ghi"],
+ "ligand_ccd_code": ["ATP", "ADP", "NA"],
+ "entry_resolution": [99.0, 99.0, 99.0],
+ "entry_release_date": ["1900-01-01"] * 3,
+ },
+ )
+ _write_table(
+ release,
+ "ligand_affinity",
+ {
+ "ligand_id": ["1abc__1__1.L", "2def__1__1.M", "3ghi__1__1.N"],
+ "ligand_binding_affinity": [None, 8.0, None],
+ "ligand_binding_affinity_endpoint": [None, "Kd", None],
+ "ligand_binding_affinity_measurement_count": [None, 1, None],
+ "system_has_binding_affinity": [False, True, False],
+ },
+ )
+ _write_table(
+ release,
+ "system_validation",
+ {
+ "system_id": [
+ "1abc__1__1.A__1.L",
+ "2def__1__1.B__1.M",
+ "3ghi__1__1.C__1.N",
+ ],
+ "system_pocket_validation_average_rscc": [0.95, 0.8, None],
+ },
+ )
+ _write_table(
+ release,
+ "interface_annotations",
+ {
+ "system_id": ["1abc__1__1.A--1.B", "2def__1__1.X--1.Y"],
+ "entry_pdb_id": ["1abc", "2def"],
+ },
+ )
+ _write_table(
+ release,
+ "interface_clusters",
+ {
+ "system_id": ["1abc__1__1.A--1.B", "2def__1__1.X--1.Y"],
+ "interface_qcov__50__directed_set_cover": ["interface_a", "interface_b"],
+ },
+ )
+ _write_table(
+ release,
+ "entry_metadata",
+ {
+ "entry_pdb_id": ["1abc", "2def", "3ghi"],
+ "entry_resolution": [1.5, 2.5, None],
+ "entry_release_date": ["2020-01-01", "2021-01-01", "2022-01-01"],
+ },
+ )
+ _write_table(
+ release,
+ "ligand_pocket_membership",
+ {
+ "ligand_id": ["1abc__1__1.L", "2def__1__1.M"],
+ "system_id": ["1abc__1__1.A__1.L", "2def__1__1.B__1.M"],
+ "pocket_cluster": ["cluster_a", "cluster_b"],
+ },
+ )
+ _write_table(
+ release,
+ "ligand_clusters",
+ {
+ "ligand_id": ["1abc__1__1.L", "2def__1__1.M", "3ghi__1__1.N"],
+ "pocket_qcov__50__ligand__directed_set_cover": [
+ "cover_a",
+ "cover_a",
+ "cover_b",
+ ],
+ },
+ )
+ _write_table(
+ release,
+ "linked_apo_structures",
+ {
+ "reference_system_id": ["1abc__1__1.A__1.L"],
+ "linked_structure_id": ["2def_B"],
+ "source_entry_id": ["2def"],
+ "rank": [1],
+ },
+ )
+ _write_table(
+ release,
+ "ligand_mmp_pairs",
+ {
+ "ligand_smiles_id_1": [0],
+ "ligand_smiles_id_2": [1],
+ "transformation": ["*O>>*N"],
+ "shared_core_smiles": ["*C"],
+ "ligand_1_shared_core_fraction": [1 / 3],
+ },
+ )
+ return release
+
+
+def test_requested_cluster_column_is_joined_automatically(
+ local_release: PlinderRelease,
+) -> None:
+ cluster_column = "pocket_qcov__50__ligand__directed_set_cover"
+ result = query_table(
+ "annotation",
+ columns=["ligand_id", cluster_column],
+ filters=[(cluster_column, "==", "cover_b")],
+ release=local_release,
+ )
+
+ assert result.to_dict("records") == [
+ {
+ "ligand_id": "3ghi__1__1.N",
+ cluster_column: "cover_b",
+ }
+ ]
+
+
+@pytest.fixture
+def protein_cluster_release(tmp_path: Path) -> PlinderRelease:
+ release = PlinderRelease(tmp_path)
+ keys = {
+ "entry_pdb_id": ["1abc", "1abc", "2def", "3ghi"],
+ "chain_asym_id": ["A", "B_2", "1.A", "D"],
+ }
+ _write_table(
+ release,
+ "entry_chains",
+ {
+ **keys,
+ "chain_sequence": ["AAAA", "BBBB", None, "ATGC"],
+ "chain_receptor_type": ["protein", "protein", "protein", "dna"],
+ },
+ )
+ for kind in ("sequence", "structure"):
+ _write_table(
+ release,
+ f"protein_{kind}_clusters",
+ {
+ "entry_pdb_id": keys["entry_pdb_id"][:3],
+ "chain_asym_id": keys["chain_asym_id"][:3],
+ "representative_entry_pdb_id": ["1abc", "1abc", None],
+ "representative_chain_asym_id": ["A", "B_2", None],
+ "is_representative": [True, True, None],
+ "status": [
+ "clustered",
+ "clustered",
+ "missing_sequence"
+ if kind == "sequence"
+ else "insufficient_coordinates",
+ ],
+ },
+ )
+ _write_table(release, "alignment_chain_lookup", keys)
+ assembly_keys = {name: values + [values[0]] for name, values in keys.items()}
+ _write_table(
+ release,
+ "entry_biounit_chains",
+ {**assembly_keys, "chain_instance": ["1.A", "1.B_2", "1.1.A", "1.D", "2.A"]},
+ )
+ _write_table(
+ release,
+ "ligand_pocket_residues",
+ {**assembly_keys, "residue_label_seq_id": [10, 20, 30, 40, 50]},
+ )
+ return release
+
+
+@pytest.mark.parametrize("kind", ["sequence", "structure"])
+def test_protein_cluster_representatives_join_sequences(protein_cluster_release, kind):
+ result = query_table(
+ f"protein_{kind}_clusters",
+ columns=["entry_pdb_id", "chain_asym_id", "chain_sequence"],
+ filters=[("is_representative", "==", True)],
+ release=protein_cluster_release,
+ ).sort_values("chain_asym_id")
+ assert result.to_dict("records") == [
+ {"entry_pdb_id": "1abc", "chain_asym_id": "A", "chain_sequence": "AAAA"},
+ {"entry_pdb_id": "1abc", "chain_asym_id": "B_2", "chain_sequence": "BBBB"},
+ ]
+
+
+@pytest.mark.parametrize("kind", ["sequence", "structure"])
+@pytest.mark.parametrize(
+ "base",
+ [
+ "entry_chains",
+ "entry_biounit_chains",
+ "alignment_chain_lookup",
+ "ligand_pocket_residues",
+ ],
+)
+def test_protein_cluster_joins_preserve_chain_rows(protein_cluster_release, kind, base):
+ result = query_table(
+ base,
+ columns=[
+ "entry_pdb_id",
+ "chain_asym_id",
+ "representative_chain_asym_id",
+ "status",
+ ],
+ joins=[f"protein_{kind}_clusters"],
+ release=protein_cluster_release,
+ )
+ assert len(result) == (
+ 5 if base in {"entry_biounit_chains", "ligand_pocket_residues"} else 4
+ )
+ assert set(
+ result.loc[result.chain_asym_id == "A", "representative_chain_asym_id"]
+ ) == {"A"}
+ assert (
+ result.loc[result.chain_asym_id == "B_2", "representative_chain_asym_id"].item()
+ == "B_2"
+ )
+ assert result.loc[result.entry_pdb_id == "3ghi", "status"].isna().all()
+ assert result.loc[result.entry_pdb_id == "2def", "status"].item() == (
+ "missing_sequence" if kind == "sequence" else "insufficient_coordinates"
+ )
+
+
+def test_chain_query_requires_choice_between_protein_cluster_tables(
+ protein_cluster_release,
+):
+ with pytest.raises(ValueError, match="multiple related tables"):
+ query_table(
+ "entry_chains",
+ columns=["is_representative"],
+ release=protein_cluster_release,
+ )
+
+
+def test_requested_interface_cluster_column_is_joined_automatically(
+ local_release: PlinderRelease,
+) -> None:
+ cluster_column = "interface_qcov__50__directed_set_cover"
+ result = query_table(
+ "interface_annotations",
+ columns=["system_id", cluster_column],
+ filters=[(cluster_column, "==", "interface_b")],
+ release=local_release,
+ )
+
+ assert result.to_dict("records") == [
+ {
+ "system_id": "2def__1__1.X--1.Y",
+ cluster_column: "interface_b",
+ }
+ ]
+
+
+def test_query_table_infers_related_tables_without_changing_ligand_rows(
+ local_release: PlinderRelease,
+) -> None:
+ result = query_table(
+ "annotation",
+ columns=[
+ "ligand_id",
+ "entry_resolution",
+ "entry_release_date",
+ "pocket_cluster",
+ ],
+ filters=[
+ ("entry_resolution", "<=", 2.0),
+ [
+ ("pocket_cluster", "==", "cluster_a"),
+ ("ligand_id", "==", "not a ligand"),
+ ],
+ ],
+ release=local_release,
+ )
+
+ assert result.to_dict("records") == [
+ {
+ "ligand_id": "1abc__1__1.L",
+ "entry_resolution": 1.5,
+ "entry_release_date": "2020-01-01",
+ "pocket_cluster": "cluster_a",
+ }
+ ]
+
+
+def test_requested_entry_metadata_is_joined_automatically(
+ local_release: PlinderRelease,
+) -> None:
+ result = query_table(
+ "annotation",
+ columns=["ligand_id", "entry_resolution"],
+ release=local_release,
+ )
+
+ assert result["entry_resolution"].tolist()[:2] == [1.5, 2.5]
+ assert pd.isna(result["entry_resolution"].iloc[2])
+
+
+def test_requested_system_validation_is_joined_automatically(
+ local_release: PlinderRelease,
+) -> None:
+ result = query_table(
+ "annotation",
+ columns=["ligand_id", "system_pocket_validation_average_rscc"],
+ filters=[("system_pocket_validation_average_rscc", ">=", 0.9)],
+ release=local_release,
+ )
+
+ assert result.to_dict("records") == [
+ {
+ "ligand_id": "1abc__1__1.L",
+ "system_pocket_validation_average_rscc": 0.95,
+ }
+ ]
+
+
+def test_pocket_membership_can_join_system_validation_directly(
+ local_release: PlinderRelease,
+) -> None:
+ result = query_table(
+ "ligand_pocket_membership",
+ columns=["ligand_id", "system_pocket_validation_average_rscc"],
+ filters=[("system_pocket_validation_average_rscc", ">=", 0.9)],
+ joins=["annotation"],
+ release=local_release,
+ )
+
+ assert result.to_dict("records") == [
+ {
+ "ligand_id": "1abc__1__1.L",
+ "system_pocket_validation_average_rscc": 0.95,
+ }
+ ]
+
+
+def test_sparse_sidecar_does_not_erase_base_identifiers(
+ local_release: PlinderRelease,
+) -> None:
+ result = query_table(
+ "annotation",
+ columns=["ligand_id", "system_id", "pocket_cluster"],
+ filters=[("system_id", "==", "3ghi__1__1.C__1.N")],
+ release=local_release,
+ )
+
+ assert result.to_dict("records") == [
+ {
+ "ligand_id": "3ghi__1__1.N",
+ "system_id": "3ghi__1__1.C__1.N",
+ "pocket_cluster": None,
+ }
+ ]
+
+
+def test_annotation_release_dates_come_from_entry_metadata(
+ local_release: PlinderRelease,
+) -> None:
+ result = query_table(
+ "annotation",
+ columns=["ligand_id", "entry_release_date"],
+ filters=[("entry_release_date", ">=", "2022-01-01")],
+ release=local_release,
+ )
+
+ assert result.to_dict("records") == [
+ {
+ "ligand_id": "3ghi__1__1.N",
+ "entry_release_date": "2022-01-01",
+ }
+ ]
+
+
+def test_annotation_adds_entry_metadata_only_when_requested(
+ local_release: PlinderRelease,
+) -> None:
+ result = query_table("annotation", release=local_release)
+
+ assert "entry_release_date" not in result.columns
+ assert "entry_resolution" not in result.columns
+ requested = query_table(
+ "annotation",
+ columns=["ligand_id", "entry_resolution"],
+ release=local_release,
+ )
+ assert requested["entry_resolution"].tolist()[:2] == [1.5, 2.5]
+ assert pd.isna(requested["entry_resolution"].iloc[2])
+
+
+def test_annotation_binding_affinity_columns_join_from_sidecar(
+ local_release: PlinderRelease,
+) -> None:
+ default = query_table("annotation", release=local_release)
+ assert "ligand_binding_affinity" not in default.columns
+ result = query_table(
+ "annotation",
+ columns=["ligand_id", "ligand_binding_affinity"],
+ filters=[("system_has_binding_affinity", "==", True)],
+ release=local_release,
+ )
+ assert result["ligand_id"].tolist() == ["2def__1__1.M"]
+ assert result["ligand_binding_affinity"].tolist() == [8.0]
+
+ joined = query_table(
+ "ligand_pocket_membership",
+ columns=["ligand_id", "ligand_binding_affinity_endpoint"],
+ release=local_release,
+ )
+ endpoints = joined["ligand_binding_affinity_endpoint"]
+ assert endpoints.isna().tolist() == [True, False]
+ assert endpoints.iloc[1] == "Kd"
+
+
+def test_query_table_uses_bound_filter_parameters(
+ local_release: PlinderRelease,
+) -> None:
+ result = query_table(
+ "annotation",
+ columns=["ligand_id"],
+ filters=[("ligand_id", "==", "1abc__1__1.L' OR true --")],
+ release=local_release,
+ )
+
+ assert result.empty
+
+
+def test_query_table_accepts_numpy_filter_values(
+ local_release: PlinderRelease,
+) -> None:
+ scalar = query_table(
+ "ligand_mmp_pairs",
+ columns=["ligand_smiles_id_1"],
+ filters=[("ligand_smiles_id_1", "==", np.int32(0))],
+ release=local_release,
+ )
+ members = query_table(
+ "ligand_mmp_pairs",
+ columns=["ligand_smiles_id_1"],
+ filters=[("ligand_smiles_id_1", "in", np.array([0, 30], dtype=np.int32))],
+ release=local_release,
+ )
+
+ assert scalar["ligand_smiles_id_1"].tolist() == [0]
+ assert members["ligand_smiles_id_1"].tolist() == [0]
+
+
+def test_query_linked_apo_with_source_entry_metadata(
+ local_release: PlinderRelease,
+) -> None:
+ result = query_table(
+ "linked_apo_structures",
+ columns=["linked_structure_id", "entry_resolution"],
+ release=local_release,
+ )
+
+ assert result.to_dict("records") == [
+ {"linked_structure_id": "2def_B", "entry_resolution": 2.5}
+ ]
+
+
+def test_query_ligand_mmp_pairs(local_release: PlinderRelease) -> None:
+ result = query_table(
+ "ligand_mmp_pairs",
+ columns=[
+ "ligand_smiles_id_1",
+ "ligand_smiles_id_2",
+ "ligand_1_shared_core_fraction",
+ ],
+ filters=[("ligand_1_shared_core_fraction", ">=", 0.3)],
+ release=local_release,
+ )
+
+ assert result.to_dict("records") == [
+ {
+ "ligand_smiles_id_1": 0,
+ "ligand_smiles_id_2": 1,
+ "ligand_1_shared_core_fraction": pytest.approx(1 / 3),
+ }
+ ]
+
+
+@pytest.mark.parametrize("include_identifiers", [False, True])
+def test_residue_queries_join_annotation_and_membership(
+ local_release: PlinderRelease, include_identifiers: bool
+) -> None:
+ _write_table(
+ local_release,
+ "ligand_pocket_residues",
+ {
+ "ligand_id": ["1abc__1__1.L"],
+ "system_id": ["1abc__1__1.A__1.L"],
+ "entry_pdb_id": ["1abc"],
+ "residue_label_seq_id": [10],
+ },
+ )
+ expected = {
+ "ligand_id": "1abc__1__1.L",
+ "ligand_ccd_code": "ATP",
+ "pocket_cluster": "cluster_a",
+ }
+ if include_identifiers:
+ expected.update(system_id="1abc__1__1.A__1.L", entry_pdb_id="1abc")
+
+ result = query_table(
+ "ligand_pocket_residues",
+ columns=list(expected),
+ release=local_release,
+ )
+ assert result.to_dict("records") == [expected]
+
+
+def test_query_table_rejects_unregistered_related_tables(
+ local_release: PlinderRelease,
+) -> None:
+ with pytest.raises(ValueError, match="available related tables"):
+ query_table(
+ "entry_metadata",
+ joins=["annotation"],
+ release=local_release,
+ )
+
+
+def test_query_table_rejects_unavailable_columns(
+ local_release: PlinderRelease,
+) -> None:
+ with pytest.raises(ValueError, match="columns .* are unavailable"):
+ query_table(
+ "annotation",
+ columns=["not_a_column"],
+ release=local_release,
+ )
+
+
+def test_query_table_requires_a_choice_for_ambiguous_related_columns(
+ tmp_path: Path,
+) -> None:
+ release = PlinderRelease(tmp_path)
+ _write_table(
+ release,
+ "annotation_table",
+ {"ligand_id": ["1abc__1__1.L"], "entry_pdb_id": ["1abc"]},
+ )
+ _write_table(
+ release,
+ "entry_metadata",
+ {
+ "entry_pdb_id": ["1abc"],
+ "metadata_only": [3],
+ "shared_value": [1],
+ },
+ )
+ _write_table(
+ release,
+ "entry_sources",
+ {"entry_pdb_id": ["1abc"], "shared_value": [2], "source_only": [4]},
+ )
+
+ with pytest.raises(ValueError, match="available from multiple related tables"):
+ query_table(
+ "annotation",
+ columns=["ligand_id", "shared_value"],
+ release=release,
+ )
+
+ inferred = query_table(
+ "annotation",
+ columns=["ligand_id", "shared_value", "metadata_only"],
+ release=release,
+ )
+ assert inferred.to_dict("records") == [
+ {
+ "ligand_id": "1abc__1__1.L",
+ "shared_value": 1,
+ "metadata_only": 3,
+ }
+ ]
+
+ selected = query_table(
+ "annotation",
+ columns=["ligand_id", "shared_value"],
+ joins=["entry_metadata"],
+ release=release,
+ )
+ assert selected.to_dict("records") == [
+ {"ligand_id": "1abc__1__1.L", "shared_value": 1}
+ ]
+
+ with pytest.raises(ValueError, match="joined column 'shared_value'"):
+ query_table(
+ "annotation",
+ columns=["ligand_id", "metadata_only", "source_only"],
+ release=release,
+ )
diff --git a/tests/core/test_transforms.py b/tests/core/test_transforms.py
index 2095259d2..64a82a032 100644
--- a/tests/core/test_transforms.py
+++ b/tests/core/test_transforms.py
@@ -1,5 +1,5 @@
import pytest
-from plinder.core import PlinderSystem
+
from plinder.core.loader.transforms import (
SelectAtomTypes,
StructureTransform,
@@ -7,8 +7,8 @@
from plinder.core.utils import constants as pc
-def test_transform_abc(read_plinder_mount):
- s = PlinderSystem(system_id="19hc__1__1.A_1.B__1.V_1.X_1.Y").holo_structure
+def test_transform_abc(cached_plinder_system):
+ s = cached_plinder_system("1avd__1__1.A__1.C").holo_structure
with pytest.raises(NotImplementedError):
StructureTransform().transform(s)
@@ -16,17 +16,17 @@ def test_transform_abc(read_plinder_mount):
@pytest.mark.parametrize(
"system_id, atom_types",
[
- ("19hc__1__1.A_1.B__1.V_1.X_1.Y", ["CA"]),
- ("19hc__1__1.A_1.B__1.V_1.X_1.Y", ["CA", "N", "C", "O"]),
- ("19hc__1__1.A_1.B__1.V_1.X_1.Y", ["foo"]),
+ ("1avd__1__1.A__1.C", ["CA"]),
+ ("1avd__1__1.A__1.C", ["CA", "N", "C", "O"]),
+ ("1avd__1__1.A__1.C", ["foo"]),
],
)
def test_select_atom_types_structure_transform(
- read_plinder_mount, system_id, atom_types
+ cached_plinder_system, system_id, atom_types
):
valid_atom_names = set(pc.ALL_ATOMS)
expected_atom_names = set(atom_types).intersection(valid_atom_names)
- s = PlinderSystem(system_id=system_id).holo_structure
+ s = cached_plinder_system(system_id).holo_structure
t = SelectAtomTypes(atom_types=atom_types)
assert len(s.protein_unique_atom_names) > len(expected_atom_names)
s = t.transform(s)
diff --git a/tests/data/annotations/test_affinity.py b/tests/data/annotations/test_affinity.py
new file mode 100644
index 000000000..45ee582cc
--- /dev/null
+++ b/tests/data/annotations/test_affinity.py
@@ -0,0 +1,193 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+
+from pathlib import Path
+
+import pandas as pd
+import pytest
+
+from plinder.data.annotations.affinity import (
+ build_ligand_affinity_table,
+ matched_affinity,
+ publish_affinity_tables,
+)
+
+
+def test_matched_affinity_selects_one_target() -> None:
+ candidates = [
+ {"target_sequence": "ACDEFG", "endpoint": "Ki", "pchembl": 9.0, "count": 1},
+ {"target_sequence": "ACDEFA", "endpoint": "Ki", "pchembl": 6.0, "count": 1},
+ ]
+ assert matched_affinity(candidates, {"1.A": "ACDEFG"}) == (9.0, "Ki", 1)
+ assert matched_affinity(candidates, {"1.A": "ACDEFA"}) == (6.0, "Ki", 1)
+
+
+def test_matched_affinity_rejects_missing_or_ambiguous_targets() -> None:
+ candidates = [
+ {"target_sequence": "ACDEFG", "endpoint": "Ki", "pchembl": 9.0, "count": 1},
+ {"target_sequence": "ACDEFA", "endpoint": "Ki", "pchembl": 6.0, "count": 1},
+ ]
+ assert matched_affinity(candidates, {}) is None
+ assert matched_affinity(candidates, {"1.A": "TTTTTT"}) is None
+ assert matched_affinity(candidates, {"1.A": "ACDEFG", "1.B": "ACDEFA"}) is None
+
+
+def test_build_ligand_affinity_table_matches_receptor_sequences(tmp_path: Path) -> None:
+ index_dir = tmp_path / "index"
+ affinity_dir = tmp_path / "dbs" / "affinity"
+ index_dir.mkdir()
+ affinity_dir.mkdir(parents=True)
+ annotation_path = index_dir / "annotation_table.parquet"
+ chains_path = index_dir / "entry_chains.parquet"
+ candidates_path = affinity_dir / "candidates.parquet"
+ pd.DataFrame(
+ {
+ "ligand_id": ["lig1", "lig2", "lig3"],
+ "system_id": ["sys1", "sys1", "sys2"],
+ "entry_pdb_id": ["1abc", "1abc", "2def"],
+ "ligand_ccd_code": ["LIG", "ATP", "LIG"],
+ "ligand_protein_chains_asym_id": [["1.A"], ["1.A"], ["1.B"]],
+ }
+ ).to_parquet(annotation_path, index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def"],
+ "chain_asym_id": ["A", "B"],
+ "chain_sequence": ["ACDEFG", "HIJKLM"],
+ }
+ ).to_parquet(chains_path, index=False)
+ pd.DataFrame(
+ {
+ "pdbid_ligid": ["1ABC_LIG", "2DEF_LIG"],
+ "target_sequence": ["ACDEFG", "ACDEFG"],
+ "endpoint": ["Ki", "Ki"],
+ "pchembl": [8.0, 9.0],
+ "count": [2, 1],
+ }
+ ).to_parquet(candidates_path, index=False)
+
+ result = build_ligand_affinity_table(
+ annotation_path, chains_path, candidates_path
+ ).set_index("ligand_id")
+
+ assert result.loc["lig1", "ligand_binding_affinity"] == pytest.approx(8.0)
+ assert result.loc["lig1", "ligand_binding_affinity_endpoint"] == "Ki"
+ assert result.loc["lig1", "ligand_binding_affinity_measurement_count"] == 2
+ assert pd.isna(result.loc["lig2", "ligand_binding_affinity"])
+ assert bool(result.loc["lig2", "system_has_binding_affinity"])
+ assert pd.isna(result.loc["lig3", "ligand_binding_affinity"])
+ assert not bool(result.loc["lig3", "system_has_binding_affinity"])
+
+ pd.DataFrame({"source_row": [7]}).to_parquet(
+ affinity_dir / "measurements.parquet", index=False
+ )
+ publish_affinity_tables(tmp_path)
+ published = pd.read_parquet(index_dir / "ligand_affinity.parquet")
+ assert published["ligand_binding_affinity"].notna().sum() == 1
+ assert pd.read_parquet(index_dir / "bindingdb_measurements.parquet")[
+ "source_row"
+ ].tolist() == [7]
+
+
+def test_build_ligand_affinity_table_keeps_empty_schema(tmp_path: Path) -> None:
+ annotation_path = tmp_path / "annotation.parquet"
+ chains_path = tmp_path / "chains.parquet"
+ candidates_path = tmp_path / "candidates.parquet"
+ pd.DataFrame(
+ columns=[
+ "ligand_id",
+ "system_id",
+ "entry_pdb_id",
+ "ligand_ccd_code",
+ "ligand_protein_chains_asym_id",
+ ]
+ ).to_parquet(annotation_path)
+ pd.DataFrame(
+ columns=["entry_pdb_id", "chain_asym_id", "chain_sequence"]
+ ).to_parquet(chains_path)
+ pd.DataFrame(
+ columns=["pdbid_ligid", "target_sequence", "endpoint", "pchembl", "count"]
+ ).to_parquet(candidates_path)
+
+ result = build_ligand_affinity_table(annotation_path, chains_path, candidates_path)
+
+ assert result.empty
+ assert str(result["ligand_binding_affinity"].dtype) == "float64"
+ assert str(result["ligand_binding_affinity_measurement_count"].dtype) == "Int64"
+ assert str(result["system_has_binding_affinity"].dtype) == "bool"
+
+
+def test_updated_affinity_matches_full_rebuild(tmp_path: Path) -> None:
+ base = tmp_path / "base"
+ updated = tmp_path / "updated"
+ for root in (base, updated):
+ (root / "index").mkdir(parents=True)
+ affinity_dir = base / "dbs" / "affinity"
+ affinity_dir.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "pdbid_ligid": ["1ABC_LIG", "2DEF_LIG", "3GHI_LIG"],
+ "target_sequence": ["ACDEFG", "HIJKLM", "NPQRST"],
+ "endpoint": ["Ki", "Ki", "Kd"],
+ "pchembl": [8.0, 9.0, 7.0],
+ "count": [1, 1, 1],
+ }
+ ).to_parquet(affinity_dir / "candidates.parquet", index=False)
+ pd.DataFrame({"source_row": [7]}).to_parquet(
+ affinity_dir / "measurements.parquet", index=False
+ )
+
+ def write_index(root: Path, entries: list[tuple[str, str, str]]) -> None:
+ pd.DataFrame(
+ {
+ "ligand_id": [ligand for _, ligand, _ in entries],
+ "system_id": [f"{pdb_id}__1" for pdb_id, _, _ in entries],
+ "entry_pdb_id": [pdb_id for pdb_id, _, _ in entries],
+ "ligand_ccd_code": ["LIG"] * len(entries),
+ "ligand_protein_chains_asym_id": [["1.A"]] * len(entries),
+ }
+ ).to_parquet(root / "index/annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": [pdb_id for pdb_id, _, _ in entries],
+ "chain_asym_id": ["A"] * len(entries),
+ "chain_sequence": [sequence for _, _, sequence in entries],
+ }
+ ).to_parquet(root / "index/entry_chains.parquet", index=False)
+
+ write_index(
+ base,
+ [
+ ("1abc", "old1", "ACDEFG"),
+ ("2def", "old2", "HIJKLM"),
+ ("4jkl", "old4", "AAAAAA"),
+ ],
+ )
+ publish_affinity_tables(base)
+ write_index(
+ updated,
+ [
+ ("1abc", "old1", "ACDEFG"),
+ ("2def", "new2", "HIJKLM"),
+ ("3ghi", "new3", "NPQRST"),
+ ],
+ )
+ publish_affinity_tables(
+ updated,
+ affinity_dir=affinity_dir,
+ base_dir=base,
+ changed_pdb_ids=["2def", "3ghi"],
+ removed_pdb_ids=["2def", "4jkl"],
+ )
+
+ expected = build_ligand_affinity_table(
+ updated / "index/annotation_table.parquet",
+ updated / "index/entry_chains.parquet",
+ affinity_dir / "candidates.parquet",
+ )
+ pd.testing.assert_frame_equal(
+ pd.read_parquet(updated / "index/ligand_affinity.parquet"), expected
+ )
+ assert pd.read_parquet(updated / "index/bindingdb_measurements.parquet")[
+ "source_row"
+ ].tolist() == [7]
diff --git a/tests/data/pipeline/test_collate.py b/tests/data/pipeline/test_collate.py
new file mode 100644
index 000000000..1599a3206
--- /dev/null
+++ b/tests/data/pipeline/test_collate.py
@@ -0,0 +1,1513 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+
+from __future__ import annotations
+
+import gzip
+import json
+from pathlib import Path
+from shutil import copy2, copytree
+
+import pandas as pd
+import pyarrow as pa
+import pyarrow.parquet as pq
+import pytest
+
+from plinder.data.annotations.affinity import publish_affinity_tables
+from plinder.data.annotations.interface_utils import (
+ INTERFACE_ANNOTATION_SCHEMA,
+ MIN_INTERFACE_RESIDUES_METADATA_KEY,
+)
+from plinder.data.pipeline import collate as collate_module
+from plinder.data.pipeline import update_entries, updates
+from plinder.data.pipeline.collate import (
+ COLLATION_VERSION,
+ collate_shard,
+ finalize_collation,
+ finalize_collation_plan,
+ finalize_repair_marker,
+ inventory_collation_codes,
+ plan_collation,
+ planned_code_batch,
+ planned_inventory_code_batch,
+ repair_collation,
+ run_collation,
+ start_collation_plan,
+)
+
+
+def test_merge_parquet_shards_combines_small_row_groups(tmp_path: Path) -> None:
+ schema = pa.schema([("id", pa.int32()), ("tags", pa.list_(pa.string()))])
+ shards = []
+ for index in range(20):
+ path = tmp_path / f"shard-{index}.parquet"
+ pq.write_table(pa.table({"id": pa.array([index], type=pa.int32())}), path)
+ shards.append(path)
+
+ output = tmp_path / "merged.parquet"
+ collate_module._merge_parquet_shards(shards, output, schema, row_group_size=10)
+ metadata = pq.read_metadata(output)
+ assert metadata.num_rows == 20
+ assert metadata.num_row_groups == 2
+ table = pq.read_table(output)
+ assert table.schema.equals(schema)
+ assert table["id"].to_pylist() == list(range(20))
+ assert table["tags"].null_count == 20
+
+
+def _write_entry(
+ data_dir: Path,
+ pdb_id: str,
+ *,
+ ligand_rows: list[dict[str, object]],
+ comparability: dict[str, bool],
+ ph: float | None = None,
+) -> None:
+ code = pdb_id[1:3]
+ raw_root = data_dir / "raw_entries" / code
+ raw_root.mkdir(parents=True, exist_ok=True)
+ system_id = f"{pdb_id}__1__1.A__1.L"
+ annotation_rows = []
+ for ligand in ligand_rows:
+ row: dict[str, object] = {
+ "entry_pdb_id": pdb_id,
+ "entry_pH": ph,
+ "system_biounit_id": "1",
+ "system_id": system_id,
+ "system_id_no_biounit": f"{pdb_id}__1.A__1.L",
+ "system_id_legacy": f"{pdb_id}__1__1.A__1.L",
+ "system_type": "holo",
+ "system_protein_chains_length": [100, 200],
+ "system_ligand_chains": ["1.L"],
+ "system_ligand_chains_asym_id": ["1.L"],
+ "system_ligand_validation_average_rsr": 0.1,
+ "system_pocket_validation_average_rsr": 0.2,
+ "ligand_id": ligand["ligand_id"],
+ "ligand_id_legacy": ligand["ligand_id"],
+ "ligand_ccd_code": ligand["ccd"],
+ "ligand_protein_chains_asym_id": ["1.A"],
+ "ligand_smiles": "C",
+ "ligand_rdkit_canonical_smiles": "C",
+ "ligand_unique_ccd_code": ligand["ccd"],
+ "ligand_is_proper": ligand["proper"],
+ "ligand_is_lipinski": ligand["proper"],
+ "ligand_is_cofactor": ligand.get("cofactor", False),
+ "ligand_is_fragment": False,
+ "ligand_is_monosaccharide": False,
+ "ligand_is_oligosaccharide": False,
+ "ligand_is_mononucleotide": False,
+ "ligand_is_oligonucleotide": False,
+ "ligand_is_monopeptide": False,
+ "ligand_is_oligopeptide": False,
+ "ligand_is_artifact": ligand.get("artifact", False),
+ "ligand_is_other": False,
+ "ligand_is_covalent": False,
+ "ligand_is_invalid": False,
+ "ligand_is_ion": ligand.get("ion", False),
+ "system_pocket_ECOD": "retired",
+ "system_pocket_kinase_name": "retired",
+ }
+ for prefix in (
+ "system_protein_chains_",
+ "system_ligand_chains_",
+ "ligand_protein_chains_",
+ "ligand_neighboring_ligand_chains_",
+ "ligand_interacting_ligand_chains_",
+ ):
+ row[f"{prefix}auth_id"] = ["A"]
+ row[f"{prefix}entity_id"] = ["1"]
+ row[f"{prefix}num_unresolved_residues"] = [0]
+ row[f"{prefix}validation_average_rsr"] = [0.1]
+ if f"{prefix}length" not in row:
+ row[f"{prefix}length"] = [100]
+ annotation_rows.append(row)
+ pd.DataFrame(annotation_rows).to_parquet(
+ raw_root / f"{pdb_id}.parquet", index=False
+ )
+
+ entry_dir = raw_root / pdb_id
+ entry_dir.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": [pdb_id, pdb_id],
+ "chain_asym_id": ["A", "B"],
+ "chain_auth_id": ["A", "B"],
+ "chain_entity_id": ["1", "2"],
+ "chain_type": ["polypeptide(L)", "polypeptide(L)"],
+ "chain_receptor_type": ["protein", "protein"],
+ "chain_sequence": ["A" * 300, "A" * 200],
+ "chain_sequence_noncanonical": ["A" * 300, "A" * 200],
+ "chain_modified_residues": [[], []],
+ "chain_length": [300, 200],
+ "chain_num_unresolved_residues": [0, 0],
+ "chain_is_holo": [True, True],
+ "chain_is_ligand_like": [False, False],
+ "chain_uniprot_ids": [["P12345"], ["Q12345"]],
+ }
+ ).to_parquet(entry_dir / "entry_chains.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": [pdb_id, pdb_id],
+ "biounit_id": ["1", "1"],
+ "chain_instance": ["1.A", "1.B"],
+ "chain_asym_id": ["A", "B"],
+ "chain_role": ["receptor", "receptor"],
+ "chain_num_contacting_ions": [0, 0],
+ "chain_num_contacting_artifacts": [0, 0],
+ "chain_num_contacting_other_ligands": [0, 0],
+ "chain_num_contacting_proteins": [1, 1],
+ }
+ ).to_parquet(entry_dir / "entry_biounit_chains.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": [pdb_id],
+ "source_mmcif_major_revision": [1],
+ "source_mmcif_minor_revision": [0],
+ }
+ ).to_parquet(entry_dir / "entry_source.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": [pdb_id],
+ "entry_pH": [ph],
+ "entry_pH_min": [ph],
+ "entry_pH_max": [ph],
+ "entry_has_ligand_of_interest": [None],
+ }
+ ).to_parquet(entry_dir / "entry_metadata.parquet", index=False)
+ interface_row = dict.fromkeys(INTERFACE_ANNOTATION_SCHEMA.names)
+ interface_row.update(
+ {
+ "entry_pdb_id": pdb_id,
+ "system_id": f"{pdb_id}__1__1.A--1.B",
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.A",
+ "interface_chain_2": "1.B",
+ "interface_chain_1_residue_numbers": [1, 2, 3, 4, 5, 6, 7],
+ "interface_chain_1_residue_indices": [0, 1, 2, 3, 4, 5, 6],
+ "interface_chain_2_residue_numbers": [11, 12, 13, 14, 15, 16, 17],
+ "interface_chain_2_residue_indices": [0, 1, 2, 3, 4, 5, 6],
+ "interface_num_contact_residue_pairs": 7,
+ "prodigy_is_annotated": False,
+ }
+ )
+ pq.write_table(
+ pa.Table.from_pylist([interface_row], schema=INTERFACE_ANNOTATION_SCHEMA),
+ entry_dir / "interfaces.parquet",
+ )
+ _set_interface_threshold(entry_dir / "interfaces.parquet", 7)
+
+ proper = [row for row in ligand_rows if row["proper"]]
+ ligand_table = pd.DataFrame(
+ {
+ "pdb_id": [pdb_id for _ in proper],
+ "system_id": [system_id for _ in proper],
+ "ligand_rdkit_canonical_smiles": ["C" for _ in proper],
+ "ligand_ccd_code": [str(row["ccd"]) for row in proper],
+ "ligand_id": [str(row["ligand_id"]) for row in proper],
+ "ligand_asym_id": ["L" for _ in proper],
+ "ligand_is_shape_comparable": [
+ comparability[str(row["ligand_id"])] for row in proper
+ ],
+ }
+ )
+ ligand_root = data_dir / "ligands"
+ ligand_root.mkdir(exist_ok=True)
+ ligand_table.to_parquet(ligand_root / f"{pdb_id}.parquet", index=False)
+
+
+def _write_release(data_dir: Path) -> None:
+ _write_entry(
+ data_dir,
+ "1abc",
+ ligand_rows=[
+ {
+ "ligand_id": "1abc__1__1.L",
+ "ccd": "ATP",
+ "proper": True,
+ "cofactor": True,
+ },
+ {
+ "ligand_id": "1abc__1__1.Z",
+ "ccd": "ZN",
+ "proper": False,
+ "ion": True,
+ },
+ ],
+ comparability={"1abc__1__1.L": True},
+ )
+ _write_entry(
+ data_dir,
+ "2def",
+ ligand_rows=[{"ligand_id": "2def__1__1.L", "ccd": "LIG", "proper": True}],
+ comparability={"2def__1__1.L": False},
+ ph=7.4,
+ )
+
+
+@pytest.fixture
+def entry_update_case(tmp_path, monkeypatch):
+ base = tmp_path / "base"
+ _write_release(base)
+ _write_entry(
+ base,
+ "3ghi",
+ ligand_rows=[{"ligand_id": "3ghi__1__1.L", "ccd": "ATP", "proper": True}],
+ comparability={"3ghi__1__1.L": True},
+ )
+ run_collation(base, memory_limit="1GB")
+ for relative in update_entries.REQUIRED_REFERENCE_FILES:
+ path = base / relative
+ path.parent.mkdir(parents=True, exist_ok=True)
+ if path.suffix == ".parquet":
+ columns = (
+ ["pdbid_ligid", "target_sequence", "endpoint", "pchembl", "count"]
+ if path.name == "candidates.parquet"
+ else ["source_row", "pdb_id", "ligand_het_id", "endpoint"]
+ )
+ pd.DataFrame(columns=columns).to_parquet(path, index=False)
+ else:
+ path.write_text("{}")
+ publish_affinity_tables(base)
+ root = tmp_path / "nextgen"
+ (root / "holdings").mkdir(parents=True)
+ revisions = {"1abc": (2, 0), "3ghi": (1, 0), "4jkl": (1, 0)}
+ for name, values in {
+ "current_file_holdings": {key: {"mmcif": [key]} for key in revisions},
+ "released_structures_last_modified_dates": {
+ key: "2026-07-01" for key in revisions
+ },
+ }.items():
+ with gzip.open(root / f"holdings/{name}.json.gz", "wt") as handle:
+ json.dump(values, handle)
+ monkeypatch.setattr(
+ updates,
+ "_read_revision",
+ lambda path: revisions[path.parent.name.removeprefix("pdb_0000")],
+ )
+ obsolete = tmp_path / "obsolete.dat"
+ obsolete.write_text("OBSLTE 01-JUL-26 2DEF 4JKL\n")
+ plan_dir = tmp_path / "plan"
+ updates.plan_update(
+ base, nextgen_root=root, obsolete_path=obsolete, output_dir=plan_dir
+ )
+ calls = []
+
+ def ingest(**kwargs):
+ calls.append(kwargs["pdb_ids"])
+ destination = kwargs["output_root"]
+ for pdb_id in kwargs["pdb_ids"]:
+ entry = destination / "raw_entries" / pdb_id[1:3] / pdb_id
+ if entry.exists():
+ continue
+ _write_entry(
+ destination,
+ pdb_id,
+ ligand_rows=[
+ {"ligand_id": f"{pdb_id}__1__1.L", "ccd": "ADP", "proper": True}
+ ],
+ comparability={f"{pdb_id}__1__1.L": True},
+ )
+ pd.DataFrame(
+ {
+ "entry_pdb_id": [pdb_id],
+ "source_mmcif_major_revision": [revisions[pdb_id][0]],
+ "source_mmcif_minor_revision": [revisions[pdb_id][1]],
+ }
+ ).to_parquet(entry / "entry_source.parquet", index=False)
+ chains = pd.read_parquet(entry / "entry_chains.parquet")
+ chains["chain_sequence"] = chains.chain_length.map(
+ lambda length: "C" * length
+ )
+ chains["chain_sequence_noncanonical"] = chains.chain_sequence
+ chains.to_parquet(entry / "entry_chains.parquet", index=False)
+ (entry / "ligand_files").mkdir()
+ (entry / "ligand_files/L.sdf").write_text("new ligand pose")
+ return destination / "metrics.json", False
+
+ monkeypatch.setattr(update_entries, "ingest_pdb_batch", ingest)
+ args = {
+ "plan_dir": plan_dir,
+ "output_dir": tmp_path / "updated",
+ "validation_root": tmp_path,
+ "annotation_cfg": {},
+ "entry_cfg": {},
+ "interface_cfg": {"min_interface_residues": 7, "annotate_prodigy": False},
+ "threads": 1,
+ "memory_limit": "1GB",
+ }
+ return base, args, calls
+
+
+def _index_bytes(root):
+ return {
+ path.name: path.read_bytes()
+ for path in (root / "index").glob("*")
+ if path.is_file()
+ }
+
+
+def test_weekly_update_rejects_plan_for_other_base_revision(
+ entry_update_case, monkeypatch
+):
+ _, args, _ = entry_update_case
+ plan, entries = updates.load_update_plan(args["plan_dir"])
+ entries.loc[entries.pdb_id.eq("1abc"), "previous_minor_revision"] = 99
+ monkeypatch.setattr(update_entries, "load_update_plan", lambda _: (plan, entries))
+
+ with pytest.raises(ValueError, match="base entry revisions"):
+ update_entries.apply_entry_update(**args)
+
+
+def test_weekly_entry_update_matches_full_collation(entry_update_case, tmp_path):
+ base, args, calls = entry_update_case
+ before = _index_bytes(base)
+ report = update_entries.apply_entry_update(**args)
+ assert report["status"] == "requires_downstream_repair"
+ assert report["ingested_pdb_ids"] == ["1abc", "4jkl"]
+ assert report["obsolete_pdb_ids"] == ["2def"]
+ assert calls == [["1abc", "4jkl"]]
+ assert _index_bytes(base) == before
+ output = args["output_dir"]
+ assert not (output / "scores").exists()
+ assert not (output / "ligand_sampling").exists()
+ assert (output / ".incoming/raw_entries/ab/1abc/ligand_files/L.sdf").is_file()
+ full = tmp_path / "full"
+ copytree(output / ".incoming/raw_entries", full / "raw_entries")
+ copytree(output / ".incoming/ligands", full / "ligands")
+ copytree(base / "raw_entries/gh", full / "raw_entries/gh")
+ copy2(base / "ligands/3ghi.parquet", full / "ligands/3ghi.parquet")
+ run_collation(full, memory_limit="1GB")
+ for filename, _ in update_entries.ENTRY_TABLES.values():
+ pd.testing.assert_frame_equal(
+ pd.read_parquet(output / "index" / filename),
+ pd.read_parquet(full / "index" / filename),
+ )
+ assert update_entries.apply_entry_update(**args) == report
+ assert calls == [["1abc", "4jkl"]]
+ assert (
+ json.loads((output / "index/collation.json").read_text())["status"]
+ == "requires_downstream_repair"
+ )
+ assert json.loads((output / "index/collation.json").read_text())["mode"] == (
+ "targeted_repair"
+ )
+ marker = json.loads((output / "index/collation.json").read_text())
+ assert marker["ligand_contacts_computed"] is True
+ assert marker["protein_contacts_computed"] is True
+ assert report["ligand_contacts_computed"] is True
+ assert report["protein_contacts_computed"] is True
+
+
+@pytest.mark.parametrize("with_interfaces", [True, False])
+def test_weekly_update_without_incoming_ligands(
+ entry_update_case, tmp_path, monkeypatch, with_interfaces
+):
+ base, args, _ = entry_update_case
+ before = _index_bytes(base)
+
+ def ingest(**kwargs):
+ root = kwargs["output_root"]
+ for pdb_id in kwargs["pdb_ids"]:
+ directory = root / "raw_entries" / pdb_id[1:3] / pdb_id
+ if directory.exists():
+ continue
+ writer = (
+ _write_interface_only_entry
+ if with_interfaces
+ else _write_sidecar_only_entry
+ )
+ writer(root, pdb_id)
+ source = pd.read_parquet(directory / "entry_source.parquet")
+ source["source_mmcif_major_revision"] = 2 if pdb_id == "1abc" else 1
+ source.to_parquet(directory / "entry_source.parquet", index=False)
+ chains = pd.read_parquet(directory / "entry_chains.parquet")
+ chains["chain_is_holo"] = False
+ chains.to_parquet(directory / "entry_chains.parquet", index=False)
+ return root / "metrics.json", False
+
+ monkeypatch.setattr(update_entries, "ingest_pdb_batch", ingest)
+ report = update_entries.apply_entry_update(**args)
+ output = args["output_dir"]
+ assert report["status"] == "requires_downstream_repair"
+ assert _index_bytes(base) == before
+ for name in ("annotation", "system_validation"):
+ filename = update_entries.ENTRY_TABLES[name][0]
+ incoming = output / ".incoming/index" / filename
+ assert pq.ParquetFile(incoming).metadata.num_rows == 0
+ assert pq.read_schema(incoming).equals(
+ pq.read_schema(base / "index" / filename)
+ )
+ assert set(
+ pd.read_parquet(output / "index/annotation_table.parquet").entry_pdb_id
+ ) == {"3ghi"}
+
+ full = tmp_path / "full"
+ copytree(base / "raw_entries/gh", full / "raw_entries/gh")
+ (full / "ligands").mkdir()
+ copy2(base / "ligands/3ghi.parquet", full / "ligands/3ghi.parquet")
+ ingest(output_root=full, pdb_ids=["1abc", "4jkl"])
+ run_collation(full, memory_limit="1GB")
+ for filename, _ in update_entries.ENTRY_TABLES.values():
+ pd.testing.assert_frame_equal(
+ pd.read_parquet(output / "index" / filename),
+ pd.read_parquet(full / "index" / filename),
+ )
+ assert update_entries.apply_entry_update(**args) == report
+
+
+def test_collation_keeps_unknown_ligand_interest_boolean(tmp_path):
+ _write_release(tmp_path)
+ run_collation(tmp_path, memory_limit="1GB")
+ table = pq.read_table(tmp_path / "index/entry_metadata.parquet")
+ flag = table["entry_has_ligand_of_interest"]
+ assert flag.type == pa.bool_()
+ assert flag.null_count == table.num_rows == 2
+
+
+def test_weekly_removal_only_needs_no_raw_entries(entry_update_case, tmp_path):
+ base, args, calls = entry_update_case
+ original_plan = json.loads((args["plan_dir"] / "plan.json").read_text())
+ plan_dir = tmp_path / "removal-plan"
+ updates.plan_update(
+ base,
+ output_dir=plan_dir,
+ nextgen_root=Path(original_plan["nextgen_root"]),
+ obsolete_path=Path(original_plan["inputs"]["obsolete"]["path"]),
+ pdb_ids=["2def"],
+ )
+ args["plan_dir"] = plan_dir
+ # Obsolete removals operate on the existing tables, not the old raw files.
+ from shutil import rmtree
+
+ rmtree(base / "raw_entries")
+ report = update_entries.apply_entry_update(**args)
+ assert report["ingested_pdb_ids"] == []
+ assert calls == []
+ for filename, _ in update_entries.ENTRY_TABLES.values():
+ frame = pd.read_parquet(args["output_dir"] / "index" / filename)
+ ids = (
+ frame.entry_pdb_id
+ if "entry_pdb_id" in frame
+ else frame.system_id.str.split("__").str[0]
+ )
+ assert set(ids) == {"1abc", "3ghi"}
+
+
+def test_weekly_update_failure_and_resume_preserve_base(entry_update_case, monkeypatch):
+ base, args, calls = entry_update_case
+ before = _index_bytes(base)
+ original = collate_module._validate_final_tables
+
+ def fail_staging(paths, **kwargs):
+ if paths["annotation"].parent.name == ".entry_tables":
+ raise ValueError("injected validation failure")
+ return original(paths, **kwargs)
+
+ monkeypatch.setattr(collate_module, "_validate_final_tables", fail_staging)
+ with pytest.raises(ValueError, match="injected"):
+ update_entries.apply_entry_update(**args)
+ assert _index_bytes(base) == before
+ assert not (args["output_dir"] / "index").exists()
+ monkeypatch.setattr(collate_module, "_validate_final_tables", original)
+ report = update_entries.apply_entry_update(**args)
+ assert report["status"] == "requires_downstream_repair"
+ assert _index_bytes(base) == before
+
+
+@pytest.mark.parametrize(
+ "change", ["base", "report", "settings", "unowned", "threshold"]
+)
+def test_weekly_update_rejects_changed_inputs(entry_update_case, change):
+ base, args, _ = entry_update_case
+ if change == "base":
+ path = base / "index/entry_sources.parquet"
+ frame = pd.read_parquet(path)
+ frame["source_mmcif_minor_revision"] = 9
+ frame.to_parquet(path, index=False)
+ elif change == "report":
+ path = args["plan_dir"] / "entries.parquet"
+ frame = pd.read_parquet(path)
+ frame["action"] = "obsolete"
+ frame.to_parquet(path, index=False)
+ elif change == "settings":
+ update_entries.apply_entry_update(**args)
+ args["annotation_cfg"] = {"min_polymer_size": 30}
+ elif change == "threshold":
+ args["interface_cfg"] = {"min_interface_residues": 8}
+ else:
+ args["output_dir"].mkdir()
+ (args["output_dir"] / "user-file.txt").write_text("keep")
+ before = _index_bytes(base)
+ with pytest.raises(ValueError):
+ update_entries.apply_entry_update(**args)
+ assert _index_bytes(base) == before
+
+
+def test_weekly_update_rejects_wrong_processed_revision(entry_update_case, monkeypatch):
+ base, args, _ = entry_update_case
+ original = update_entries.ingest_pdb_batch
+
+ def wrong_revision(**kwargs):
+ result = original(**kwargs)
+ path = kwargs["output_root"] / "raw_entries/ab/1abc/entry_source.parquet"
+ frame = pd.read_parquet(path)
+ frame["source_mmcif_major_revision"] = 3
+ frame.to_parquet(path, index=False)
+ return result
+
+ monkeypatch.setattr(update_entries, "ingest_pdb_batch", wrong_revision)
+ before = _index_bytes(base)
+ with pytest.raises(ValueError, match="revisions differ"):
+ update_entries.apply_entry_update(**args)
+ assert before == _index_bytes(base)
+ assert not (args["output_dir"] / "index").exists()
+
+
+def test_weekly_update_install_failure_can_resume(entry_update_case, monkeypatch):
+ base, args, _ = entry_update_case
+ before = _index_bytes(base)
+ replace = Path.replace
+
+ def fail_metadata(path, target):
+ if (
+ path.parent.name == ".entry_tables"
+ and path.name == "entry_metadata.parquet"
+ ):
+ raise OSError("injected installation failure")
+ return replace(path, target)
+
+ monkeypatch.setattr(Path, "replace", fail_metadata)
+ with pytest.raises(OSError, match="injected"):
+ update_entries.apply_entry_update(**args)
+ assert before == _index_bytes(base)
+ assert not (args["output_dir"] / "index/annotation_table.parquet").exists()
+ assert not (args["output_dir"] / "index/collation.json").exists()
+ monkeypatch.setattr(Path, "replace", replace)
+ assert (
+ update_entries.apply_entry_update(**args)["status"]
+ == "requires_downstream_repair"
+ )
+ assert before == _index_bytes(base)
+
+
+def test_weekly_update_entry_failure_keeps_workspace_resumable(
+ entry_update_case, monkeypatch
+):
+ base, args, _ = entry_update_case
+ original = update_entries.ingest_pdb_batch
+ before = _index_bytes(base)
+
+ def failed(**kwargs):
+ path, _ = original(**kwargs)
+ return path, True
+
+ monkeypatch.setattr(update_entries, "ingest_pdb_batch", failed)
+ with pytest.raises(RuntimeError, match="entry update failed"):
+ update_entries.apply_entry_update(**args)
+ assert before == _index_bytes(base)
+ assert not (args["output_dir"] / "index").exists()
+ monkeypatch.setattr(update_entries, "ingest_pdb_batch", original)
+ assert (
+ update_entries.apply_entry_update(**args)["status"]
+ == "requires_downstream_repair"
+ )
+
+
+def test_weekly_update_does_not_reuse_missing_marker(entry_update_case):
+ _, args, _ = entry_update_case
+ update_entries.apply_entry_update(**args)
+ (args["output_dir"] / "index/collation.json").unlink()
+ with pytest.raises(FileNotFoundError):
+ update_entries.apply_entry_update(**args)
+
+
+def test_weekly_update_preserves_nested_residue_lists(entry_update_case, monkeypatch):
+ base, args, _ = entry_update_case
+ path = base / "index/annotation_table.parquet"
+ frame = pd.read_parquet(path)
+ frame["ligand_residue_numbers"] = [[3, 4] for _ in range(len(frame))]
+ frame["ligand_instance_chains"] = [["1.L"] for _ in range(len(frame))]
+ frame.to_parquet(path, index=False)
+ original = update_entries.ingest_pdb_batch
+
+ def new_chains(**kwargs):
+ result = original(**kwargs)
+ for pdb_id in kwargs["pdb_ids"]:
+ path = (
+ kwargs["output_root"]
+ / "raw_entries"
+ / pdb_id[1:3]
+ / f"{pdb_id}.parquet"
+ )
+ rows = pd.read_parquet(path)
+ rows["ligand__members"] = [{"2.NEW": [5, 6]} for _ in range(len(rows))]
+ rows["ligand_residue_numbers"] = [[5, 6] for _ in range(len(rows))]
+ rows["ligand_instance_chains"] = [["2.NEW"] for _ in range(len(rows))]
+ rows.to_parquet(path, index=False)
+ return result
+
+ monkeypatch.setattr(update_entries, "ingest_pdb_batch", new_chains)
+ before = _index_bytes(base)
+ update_entries.apply_entry_update(**args)
+ rows = pd.read_parquet(args["output_dir"] / "index/annotation_table.parquet")
+ assert "ligand__members" not in rows
+ for row in rows.itertuples(index=False, name=None):
+ mapping = dict(zip(rows.columns, row))
+ if mapping["entry_pdb_id"] == "3ghi":
+ assert list(mapping["ligand_residue_numbers"]) == [3, 4]
+ assert list(mapping["ligand_instance_chains"]) == ["1.L"]
+ else:
+ assert list(mapping["ligand_residue_numbers"]) == [5, 6]
+ assert list(mapping["ligand_instance_chains"]) == ["2.NEW"]
+ assert _index_bytes(base) == before
+
+
+def test_collation_preserves_failure_diagnostics(tmp_path):
+ from plinder.core import PlinderRelease, query_table
+
+ for pdb_id, failures in [("1abc", []), ("2abd", ["2"]), ("3def", [])]:
+ _write_entry(
+ tmp_path,
+ pdb_id,
+ ligand_rows=[
+ {"ligand_id": f"{pdb_id}__1__1.L", "ccd": "ATP", "proper": True}
+ ],
+ comparability={f"{pdb_id}__1__1.L": True},
+ )
+ raw_root = tmp_path / "raw_entries" / pdb_id[1:3]
+ metadata_path = raw_root / pdb_id / "entry_metadata.parquet"
+ metadata = pd.read_parquet(metadata_path)
+ metadata["entry_failed_assembly_ids"] = [failures]
+ metadata.to_parquet(metadata_path, index=False)
+ annotation_path = raw_root / f"{pdb_id}.parquet"
+ annotation = pd.read_parquet(annotation_path)
+ annotation["ligand_failed_interaction_types"] = [
+ ["water_bridge"] if failures else []
+ ]
+ annotation.to_parquet(annotation_path, index=False)
+
+ run_collation(tmp_path, threads=1, memory_limit="1GB")
+ result = query_table(
+ "annotation",
+ columns=[
+ "entry_pdb_id",
+ "entry_failed_assembly_ids",
+ "ligand_failed_interaction_types",
+ ],
+ release=PlinderRelease(data_dir=tmp_path),
+ ).set_index("entry_pdb_id")
+ assert list(result.loc["1abc", "entry_failed_assembly_ids"]) == []
+ assert list(result.loc["1abc", "ligand_failed_interaction_types"]) == []
+ assert list(result.loc["2abd", "entry_failed_assembly_ids"]) == ["2"]
+ assert list(result.loc["2abd", "ligand_failed_interaction_types"]) == [
+ "water_bridge"
+ ]
+ assert list(result.loc["3def", "entry_failed_assembly_ids"]) == []
+ assert list(result.loc["3def", "ligand_failed_interaction_types"]) == []
+ assert (
+ "entry_failed_assembly_ids"
+ not in pq.read_schema(tmp_path / "index/annotation_table.parquet").names
+ )
+
+
+def test_collation_types_empty_failed_assembly_ids_as_strings(tmp_path):
+ _write_release(tmp_path)
+ for pdb_id in ("1abc", "2def"):
+ path = (
+ tmp_path / "raw_entries" / pdb_id[1:3] / pdb_id / "entry_metadata.parquet"
+ )
+ metadata = pd.read_parquet(path)
+ metadata["entry_failed_assembly_ids"] = [[]]
+ metadata.to_parquet(path, index=False)
+
+ run_collation(tmp_path, memory_limit="1GB")
+
+ schema = pq.read_schema(tmp_path / "index/entry_metadata.parquet")
+ assert schema.field("entry_failed_assembly_ids").type == pa.list_(pa.string())
+
+
+def _write_interface_only_entry(data_dir: Path, pdb_id: str = "3ghi") -> None:
+ _write_entry(
+ data_dir,
+ pdb_id,
+ ligand_rows=[],
+ comparability={},
+ )
+ (data_dir / "raw_entries" / pdb_id[1:3] / f"{pdb_id}.parquet").unlink()
+ (data_dir / "ligands" / f"{pdb_id}.parquet").unlink()
+ metrics = data_dir / "metrics" / pdb_id[1:3] / f"ingest-one-{pdb_id}.json"
+ metrics.parent.mkdir(parents=True, exist_ok=True)
+ metrics.write_text(
+ json.dumps(
+ {
+ "status": "complete",
+ "mode": "all",
+ "counts": {"annotation_rows": 0, "interface_rows": 1},
+ "outputs": {
+ "entry_directory": str(
+ data_dir / "raw_entries" / pdb_id[1:3] / pdb_id
+ ),
+ "entry_parquet": None,
+ "ligand_parquet": None,
+ },
+ }
+ )
+ )
+
+
+def _write_sidecar_only_entry(data_dir: Path, pdb_id: str = "4jkl") -> None:
+ _write_interface_only_entry(data_dir, pdb_id)
+ interface_path = (
+ data_dir / "raw_entries" / pdb_id[1:3] / pdb_id / "interfaces.parquet"
+ )
+ pq.write_table(
+ pa.Table.from_pylist([], schema=INTERFACE_ANNOTATION_SCHEMA), interface_path
+ )
+ _set_interface_threshold(interface_path, 7)
+ metrics = data_dir / "metrics" / pdb_id[1:3] / f"ingest-one-{pdb_id}.json"
+ payload = json.loads(metrics.read_text())
+ payload["counts"]["interface_rows"] = 0
+ metrics.write_text(json.dumps(payload))
+
+
+def _set_interface_threshold(path: Path, threshold: int) -> None:
+ table = pq.read_table(path)
+ metadata = dict(table.schema.metadata or {})
+ metadata[MIN_INTERFACE_RESIDUES_METADATA_KEY] = str(threshold).encode()
+ pq.write_table(table.replace_schema_metadata(metadata), path)
+
+
+def test_plan_shards_and_finalize_release_contract(tmp_path: Path) -> None:
+ _write_release(tmp_path)
+
+ plan = plan_collation(tmp_path)
+ assert plan["entry_count"] == 2
+ assert plan["codes"] == ["ab", "de"]
+ assert planned_code_batch(tmp_path, batch_index=0, batch_size=1) == ["ab"]
+ assert planned_code_batch(tmp_path, batch_index=1, batch_size=1) == ["de"]
+ assert planned_code_batch(tmp_path, batch_index=2, batch_size=1) == []
+
+ first = collate_shard(tmp_path, "ab", memory_limit="1GB")
+ cached = collate_shard(tmp_path, "ab", memory_limit="1GB")
+ collate_shard(tmp_path, "de", memory_limit="1GB")
+ report = finalize_collation(tmp_path, threads=2, memory_limit="1GB")
+
+ assert first == cached
+ assert report["row_counts"] == {
+ "annotation": 3,
+ "system_validation": 2,
+ "entry_chains": 4,
+ "entry_biounit_chains": 4,
+ "entry_metadata": 2,
+ "interfaces": 2,
+ "entry_sources": 2,
+ }
+ assert report["interface_count"] == 2
+ annotation = pd.read_parquet(tmp_path / "index/annotation_table.parquet")
+ assert [column for column in annotation.columns if column.startswith("entry_")] == [
+ "entry_pdb_id"
+ ]
+ assert not {
+ column
+ for column in annotation.columns
+ if any(marker in column.casefold() for marker in ("ecod", "kinase"))
+ }
+ retired_annotation_columns = {
+ "system_id_no_biounit",
+ "system_ligand_chains",
+ "ligand_rdkit_canonical_smiles",
+ "ligand__members",
+ "system_pass_criteria",
+ }
+ assert retired_annotation_columns.isdisjoint(annotation.columns)
+ assert "ligand_smiles" in annotation.columns
+ assert not any(
+ column.startswith(
+ (
+ "system_ligand_validation_",
+ "system_pocket_validation_",
+ )
+ )
+ for column in annotation.columns
+ )
+ for prefix in (
+ "system_protein_chains_",
+ "system_ligand_chains_",
+ "ligand_protein_chains_",
+ "ligand_neighboring_ligand_chains_",
+ "ligand_interacting_ligand_chains_",
+ ):
+ for suffix in (
+ "auth_id",
+ "entity_id",
+ "length",
+ "num_unresolved_residues",
+ ):
+ assert f"{prefix}{suffix}" not in annotation.columns
+ assert not any("_chains_validation_" in column for column in annotation.columns)
+ first_entry = annotation[annotation["entry_pdb_id"] == "1abc"]
+ assert first_entry["biounit_num_ligands"].tolist() == [2, 2]
+ assert first_entry["biounit_num_unique_ccd_codes"].tolist() == [2, 2]
+ assert first_entry["biounit_num_proper_ligands"].tolist() == [1, 1]
+ assert first_entry["system_protein_chains_total_length"].tolist() == [300, 300]
+ assert first_entry["system_unique_ccd_codes"].tolist() == ["ATP-ZN", "ATP-ZN"]
+ assert first_entry["system_proper_unique_ccd_codes"].tolist() == ["ATP", "ATP"]
+ assert first_entry["system_ligand_has_cofactor"].all()
+ assert first_entry["system_ligand_has_ion"].all()
+ assert first_entry.set_index("ligand_id")[
+ "ligand_is_shape_comparable"
+ ].to_dict() == {
+ "1abc__1__1.L": True,
+ "1abc__1__1.Z": False,
+ }
+ metadata = pd.read_parquet(tmp_path / "index/entry_metadata.parquet")
+ assert metadata.set_index("entry_pdb_id").loc["2def", "entry_pH"] == 7.4
+ system_validation = pd.read_parquet(
+ tmp_path / "index/system_validation.parquet"
+ ).set_index("system_id")
+ assert system_validation.loc[
+ "1abc__1__1.A__1.L", "system_ligand_validation_average_rsr"
+ ] == pytest.approx(0.1)
+ assert system_validation.loc[
+ "1abc__1__1.A__1.L", "system_pocket_validation_average_rsr"
+ ] == pytest.approx(0.2)
+ marker = json.loads((tmp_path / "index/collation.json").read_text())
+ assert marker["status"] == "complete"
+ assert marker["interface_min_residues"] == 7
+
+
+def test_collate_shard_does_not_reuse_older_format(tmp_path: Path) -> None:
+ _write_release(tmp_path)
+ plan_collation(tmp_path)
+ collate_shard(tmp_path, "ab", memory_limit="1GB")
+ paths = collate_module._shard_paths(tmp_path, "ab")
+ stale = pd.read_parquet(paths["entry_biounit_chains"]).drop(
+ columns=[
+ "chain_num_contacting_ions",
+ "chain_num_contacting_artifacts",
+ "chain_num_contacting_other_ligands",
+ "chain_num_contacting_proteins",
+ ]
+ )
+ stale.to_parquet(paths["entry_biounit_chains"], index=False)
+ metrics = json.loads(paths["metrics"].read_text())
+ metrics["version"] = COLLATION_VERSION - 1
+ paths["metrics"].write_text(json.dumps(metrics))
+
+ refreshed = collate_shard(tmp_path, "ab", memory_limit="1GB")
+
+ assert refreshed["version"] == COLLATION_VERSION
+ assert {
+ "chain_num_contacting_ions",
+ "chain_num_contacting_artifacts",
+ "chain_num_contacting_other_ligands",
+ "chain_num_contacting_proteins",
+ }.issubset(pq.read_schema(paths["entry_biounit_chains"]).names)
+
+
+def test_collation_rejects_unknown_biounit_contact_counts(tmp_path: Path) -> None:
+ _write_release(tmp_path)
+ path = tmp_path / "raw_entries/ab/1abc/entry_biounit_chains.parquet"
+ frame = pd.read_parquet(path)
+ frame.loc[0, "chain_num_contacting_ions"] = None
+ frame.to_parquet(path, index=False)
+
+ with pytest.raises(
+ ValueError,
+ match="invalid biological-assembly contact counts",
+ ):
+ run_collation(tmp_path, memory_limit="1GB")
+
+
+@pytest.mark.parametrize(
+ ("omitted", "ligand_computed", "protein_computed"),
+ [
+ (["chain_num_contacting_proteins"], True, False),
+ (
+ [
+ "chain_num_contacting_ions",
+ "chain_num_contacting_artifacts",
+ "chain_num_contacting_other_ligands",
+ ],
+ False,
+ True,
+ ),
+ ],
+)
+def test_collation_accepts_consistent_split_ingest_contact_schema(
+ tmp_path: Path,
+ omitted: list[str],
+ ligand_computed: bool,
+ protein_computed: bool,
+) -> None:
+ _write_release(tmp_path)
+ for pdb_id in ("1abc", "2def"):
+ path = (
+ tmp_path
+ / "raw_entries"
+ / pdb_id[1:3]
+ / pdb_id
+ / "entry_biounit_chains.parquet"
+ )
+ pd.read_parquet(path).drop(columns=omitted).to_parquet(path, index=False)
+
+ report = run_collation(tmp_path, memory_limit="1GB")
+ table = pd.read_parquet(tmp_path / "index/entry_biounit_chains.parquet")
+
+ assert report["ligand_contacts_computed"] is ligand_computed
+ assert report["protein_contacts_computed"] is protein_computed
+ assert table[omitted].isna().all().all()
+
+
+def test_distributed_plan_requires_and_merges_every_code_inventory(
+ tmp_path: Path,
+) -> None:
+ _write_release(tmp_path)
+
+ build = start_collation_plan(tmp_path)
+ assert build["code_count"] == 2
+ assert planned_inventory_code_batch(tmp_path, batch_index=0, batch_size=1) == ["ab"]
+ assert planned_inventory_code_batch(tmp_path, batch_index=1, batch_size=1) == ["de"]
+
+ inventory_collation_codes(tmp_path, ["ab"], threads=2)
+ with pytest.raises(FileNotFoundError, match="incomplete for code de"):
+ finalize_collation_plan(tmp_path)
+
+ inventory_collation_codes(tmp_path, ["de"], threads=2)
+ plan = finalize_collation_plan(tmp_path)
+
+ assert plan["entry_count"] == 2
+ assert plan["code_entry_counts"] == {"ab": 1, "de": 1}
+ assert pq.read_table(plan["manifest"]).column("pdb_id").to_pylist() == [
+ "1abc",
+ "2def",
+ ]
+
+
+def test_interface_only_collation_preserves_installed_ligand_annotation(
+ tmp_path: Path,
+) -> None:
+ _write_release(tmp_path)
+ run_collation(tmp_path, memory_limit="1GB")
+ annotation_path = tmp_path / "index/annotation_table.parquet"
+ annotation = pd.read_parquet(annotation_path)
+ annotation["release_only"] = "preserve"
+ annotation.to_parquet(annotation_path, index=False)
+ annotation_bytes = annotation_path.read_bytes()
+ system_validation_path = tmp_path / "index/system_validation.parquet"
+ system_validation_bytes = system_validation_path.read_bytes()
+ build = start_collation_plan(
+ tmp_path,
+ include_ligand_annotations=False,
+ )
+ inventory_collation_codes(tmp_path, build["codes"], threads=2)
+ plan = finalize_collation_plan(tmp_path)
+ for code in plan["codes"]:
+ collate_shard(tmp_path, code, memory_limit="1GB")
+ report = finalize_collation(tmp_path, memory_limit="1GB")
+
+ assert report["include_ligand_annotations"] is False
+ assert annotation_path.read_bytes() == annotation_bytes
+ assert system_validation_path.read_bytes() == system_validation_bytes
+ assert report["interface_count"] == 2
+
+
+def test_collation_retains_entries_with_only_protein_interfaces(
+ tmp_path: Path,
+) -> None:
+ _write_release(tmp_path)
+ _write_interface_only_entry(tmp_path)
+
+ report = run_collation(tmp_path, memory_limit="1GB")
+
+ assert report["entry_count"] == 3
+ assert report["interface_count"] == 3
+ annotation = pd.read_parquet(tmp_path / "index/annotation_table.parquet")
+ assert "3ghi" not in set(annotation["entry_pdb_id"])
+ metadata = pd.read_parquet(tmp_path / "index/entry_metadata.parquet")
+ assert set(metadata["entry_pdb_id"]) == {"1abc", "2def", "3ghi"}
+ interfaces = pd.read_parquet(tmp_path / "index/interface_annotation_table.parquet")
+ assert "3ghi__1__1.A--1.B" in set(interfaces["system_id"])
+
+
+@pytest.mark.parametrize("mode", ["all", "ligands"])
+def test_collation_retains_entries_with_only_chain_sidecars(
+ tmp_path: Path, mode: str
+) -> None:
+ _write_release(tmp_path)
+ _write_sidecar_only_entry(tmp_path)
+ marker = tmp_path / "metrics/jk/ingest-one-4jkl.json"
+ payload = json.loads(marker.read_text())
+ payload["mode"] = mode
+ if mode == "ligands":
+ payload["status"] = "skipped_no_ligands"
+ payload["counts"]["entry_chain_rows"] = 2
+ marker.write_text(json.dumps(payload))
+
+ report = run_collation(tmp_path, memory_limit="1GB")
+
+ assert report["entry_count"] == 3
+ assert report["interface_count"] == 2
+ annotation = pd.read_parquet(tmp_path / "index/annotation_table.parquet")
+ assert "4jkl" not in set(annotation["entry_pdb_id"])
+ metadata = pd.read_parquet(tmp_path / "index/entry_metadata.parquet")
+ assert set(metadata["entry_pdb_id"]) == {"1abc", "2def", "4jkl"}
+ chains = pd.read_parquet(tmp_path / "index/entry_chains.parquet")
+ assert "4jkl" in set(chains["entry_pdb_id"])
+
+ # Targeted repairs must accept the same sidecar-only entries as a full build.
+ repaired = repair_collation(tmp_path, ["4jkl"], memory_limit="1GB")
+ assert repaired["status"] == "requires_downstream_repair"
+ pd.testing.assert_frame_equal(
+ pd.read_parquet(tmp_path / "index/entry_chains.parquet"), chains
+ )
+
+
+def test_collation_rejects_interface_sidecars_from_failed_ingest(
+ tmp_path: Path,
+) -> None:
+ _write_release(tmp_path)
+ _write_interface_only_entry(tmp_path)
+ metrics = tmp_path / "metrics/gh/ingest-one-3ghi.json"
+ metrics.write_text(json.dumps({"status": "failed"}))
+
+ with pytest.raises(ValueError, match="no successful ingest marker"):
+ plan_collation(tmp_path)
+
+
+def test_collation_validates_custom_interface_residue_minimum(
+ tmp_path: Path,
+) -> None:
+ _write_release(tmp_path)
+ for pdb_id in ("1abc", "2def"):
+ path = tmp_path / "raw_entries" / pdb_id[1:3] / pdb_id / "interfaces.parquet"
+ frame = pd.read_parquet(path)
+ frame["interface_chain_1_residue_numbers"] = [[1]]
+ frame["interface_chain_1_residue_indices"] = [[0]]
+ frame["interface_chain_2_residue_numbers"] = [[11]]
+ frame["interface_chain_2_residue_indices"] = [[0]]
+ frame.to_parquet(path, index=False)
+ _set_interface_threshold(path, 1)
+
+ report = run_collation(tmp_path, memory_limit="1GB")
+
+ assert report["interface_min_residues"] == 1
+
+
+def test_collation_rejects_interface_below_frozen_residue_minimum(
+ tmp_path: Path,
+) -> None:
+ _write_release(tmp_path)
+ path = tmp_path / "raw_entries/ab/1abc/interfaces.parquet"
+ frame = pd.read_parquet(path)
+ for column in (
+ "interface_chain_1_residue_numbers",
+ "interface_chain_1_residue_indices",
+ "interface_chain_2_residue_numbers",
+ "interface_chain_2_residue_indices",
+ ):
+ frame[column] = frame[column].map(lambda values: values[:6])
+ frame.to_parquet(path, index=False)
+ _set_interface_threshold(path, 7)
+
+ with pytest.raises(ValueError, match="invalid protein interfaces"):
+ run_collation(tmp_path, memory_limit="1GB")
+
+
+def test_collation_rejects_mixed_interface_thresholds(tmp_path: Path) -> None:
+ _write_release(tmp_path)
+ _set_interface_threshold(
+ tmp_path / "raw_entries/de/2def/interfaces.parquet",
+ 9,
+ )
+
+ with pytest.raises(ValueError, match="mixed interface.min_interface_residues"):
+ plan_collation(tmp_path)
+
+
+def test_collation_rejects_interface_table_without_threshold(tmp_path: Path) -> None:
+ _write_release(tmp_path)
+ path = tmp_path / "raw_entries/de/2def/interfaces.parquet"
+ table = pq.read_table(path)
+ pq.write_table(table.replace_schema_metadata(None), path)
+
+ with pytest.raises(ValueError, match="does not record its minimum residue count"):
+ plan_collation(tmp_path)
+
+
+def test_targeted_repair_preserves_unaffected_release_only_columns(
+ tmp_path: Path,
+) -> None:
+ _write_release(tmp_path)
+ run_collation(tmp_path, memory_limit="1GB")
+ installed = pd.read_parquet(tmp_path / "index/annotation_table.parquet")
+ installed["release_only"] = installed["entry_pdb_id"].map(
+ {
+ "1abc": "old",
+ "2def": "keep",
+ }
+ )
+ installed.to_parquet(tmp_path / "index/annotation_table.parquet", index=False)
+ chain_path = tmp_path / "index/entry_chains.parquet"
+ before_chain_stat = chain_path.stat()
+
+ metadata_path = tmp_path / "raw_entries/ab/1abc/entry_metadata.parquet"
+ metadata = pd.read_parquet(metadata_path)
+ metadata["entry_pH"] = 6.5
+ metadata.to_parquet(metadata_path, index=False)
+
+ report = repair_collation(tmp_path, ["1ABC", "1abc"], threads=2, memory_limit="1GB")
+
+ assert report["mode"] == "targeted_repair"
+ assert report["status"] == "requires_downstream_repair"
+ assert report["repaired_entry_count"] == 1
+ repaired = pd.read_parquet(tmp_path / "index/annotation_table.parquet")
+ assert "entry_pH" not in repaired.columns
+ assert (
+ repaired.loc[repaired["entry_pdb_id"].eq("1abc"), "release_only"].isna().all()
+ )
+ assert (
+ repaired.loc[repaired["entry_pdb_id"].eq("2def"), "release_only"]
+ .eq("keep")
+ .all()
+ )
+ repaired_metadata = pd.read_parquet(tmp_path / "index/entry_metadata.parquet")
+ assert repaired_metadata.set_index("entry_pdb_id").loc["1abc", "entry_pH"] == 6.5
+ repaired_chains = pd.read_parquet(tmp_path / "index/entry_chains.parquet")
+ lengths = (
+ repaired_chains[repaired_chains["chain_asym_id"].eq("A")]
+ .set_index("entry_pdb_id")["chain_length"]
+ .to_dict()
+ )
+ assert lengths == {"1abc": 300, "2def": 300}
+ after_chain_stat = chain_path.stat()
+ assert (
+ after_chain_stat.st_ino,
+ after_chain_stat.st_size,
+ after_chain_stat.st_mtime_ns,
+ ) == (
+ before_chain_stat.st_ino,
+ before_chain_stat.st_size,
+ before_chain_stat.st_mtime_ns,
+ )
+
+ finalized_report = finalize_repair_marker(tmp_path)
+ assert finalized_report is not None
+ assert finalized_report["status"] == "complete"
+ assert finalized_report["downstream_repair_complete"] is True
+
+
+def test_targeted_repair_updates_chain_annotations(tmp_path: Path) -> None:
+ _write_release(tmp_path)
+ run_collation(tmp_path, memory_limit="1GB")
+ path = tmp_path / "index/entry_chains.parquet"
+ installed = pd.read_parquet(path)
+ installed["release_only"] = "keep"
+ installed.to_parquet(path, index=False)
+ replacement_path = tmp_path / "raw_entries/ab/1abc/entry_chains.parquet"
+ replacement = pd.read_parquet(replacement_path)
+ replacement.loc[0, "chain_sequence_noncanonical"] = "(MSE)" + "A" * 299
+ replacement.at[0, "chain_modified_residues"] = ["1:MSE:A:1"]
+ replacement.to_parquet(replacement_path, index=False)
+ metadata_path = tmp_path / "raw_entries/ab/1abc/entry_metadata.parquet"
+ metadata = pd.read_parquet(metadata_path)
+ metadata["entry_pH_min"] = 6.0
+ metadata["entry_pH_max"] = 7.0
+ metadata["entry_has_ligand_of_interest"] = True
+ metadata.to_parquet(metadata_path, index=False)
+ ligand_path = tmp_path / "raw_entries/ab/1abc.parquet"
+ ligands = pd.read_parquet(ligand_path)
+ ligands["ligand_contact_area"] = 42.0
+ ligands["ligand_unresolved_atoms"] = [["5:LIG:L:5:C1"] for _ in range(len(ligands))]
+ ligands.to_parquet(ligand_path, index=False)
+
+ report = repair_collation(tmp_path, ["1abc"], memory_limit="1GB")
+
+ assert report["status"] == "requires_downstream_repair"
+ repaired_metadata = pd.read_parquet(tmp_path / "index/entry_metadata.parquet")
+ metadata_columns = ["entry_pH_min", "entry_pH_max", "entry_has_ligand_of_interest"]
+ assert repaired_metadata.loc[
+ repaired_metadata.entry_pdb_id.eq("1abc"), metadata_columns
+ ].to_dict("records") == metadata[metadata_columns].to_dict("records")
+ repaired_ligands = pd.read_parquet(tmp_path / "index/annotation_table.parquet")
+ columns_to_check = ["ligand_contact_area", "ligand_unresolved_atoms"]
+ pd.testing.assert_frame_equal(
+ repaired_ligands.loc[
+ repaired_ligands.entry_pdb_id.eq("1abc"), columns_to_check
+ ].reset_index(drop=True),
+ ligands[columns_to_check].reset_index(drop=True),
+ )
+ repaired = pd.read_parquet(path)
+ selected = repaired.loc[repaired.entry_pdb_id.eq("1abc"), replacement.columns]
+ pd.testing.assert_frame_equal(selected.reset_index(drop=True), replacement)
+ untouched = repaired.loc[repaired.entry_pdb_id.eq("2def"), installed.columns]
+ pd.testing.assert_frame_equal(
+ untouched.reset_index(drop=True),
+ installed.loc[installed.entry_pdb_id.eq("2def")].reset_index(drop=True),
+ )
+
+
+@pytest.mark.parametrize(
+ ("column", "value"),
+ [
+ ("chain_length", 301),
+ ("chain_sequence", "G" * 300),
+ ("chain_asym_id", "C"),
+ ("chain_auth_id", "Z"),
+ ("chain_is_ligand_like", True),
+ ],
+)
+def test_targeted_repair_rejects_chain_metadata_changes(
+ tmp_path: Path, column: str, value: object
+) -> None:
+ _write_release(tmp_path)
+ run_collation(tmp_path, memory_limit="1GB")
+ chains = pd.read_parquet(tmp_path / "raw_entries/ab/1abc/entry_chains.parquet")
+ chains[column] = value
+ chains.to_parquet(
+ tmp_path / "raw_entries/ab/1abc/entry_chains.parquet", index=False
+ )
+
+ installed_paths = list((tmp_path / "index").glob("*.parquet")) + [
+ tmp_path / "index/collation.json"
+ ]
+ before = {path: path.read_bytes() for path in installed_paths}
+ with pytest.raises(ValueError, match="changed entry_chains"):
+ repair_collation(tmp_path, ["1abc"], memory_limit="1GB")
+ assert {path: path.read_bytes() for path in installed_paths} == before
+
+
+@pytest.mark.parametrize(
+ ("filename", "column", "value", "table"),
+ [
+ ("entry_source.parquet", "source_mmcif_minor_revision", 99, "entry_sources"),
+ (
+ "entry_biounit_chains.parquet",
+ "chain_instance",
+ "2.A",
+ "entry_biounit_chains",
+ ),
+ ],
+)
+def test_metadata_repair_preserves_release_when_scoring_sources_change(
+ tmp_path: Path, filename: str, column: str, value: object, table: str
+) -> None:
+ _write_release(tmp_path)
+ run_collation(tmp_path, memory_limit="1GB")
+ entry_dir = tmp_path / "raw_entries/ab/1abc"
+ chain_path = entry_dir / "entry_chains.parquet"
+ chains = pd.read_parquet(chain_path)
+ chains["chain_sequence_noncanonical"] = "(MSE)AA"
+ chains.to_parquet(chain_path, index=False)
+ source = entry_dir / filename
+ frame = pd.read_parquet(source)
+ frame.loc[0, column] = value
+ frame.to_parquet(source, index=False)
+ paths = list((tmp_path / "index").glob("*.parquet")) + [
+ tmp_path / "index/collation.json"
+ ]
+ before = {path: path.read_bytes() for path in paths}
+ with pytest.raises(ValueError, match=f"changed {table}"):
+ repair_collation(tmp_path, ["1abc"], memory_limit="1GB")
+ assert {path: path.read_bytes() for path in paths} == before
+
+
+def test_shard_rejects_inputs_changed_after_plan(tmp_path: Path) -> None:
+ _write_release(tmp_path)
+ plan_collation(tmp_path)
+ annotation = tmp_path / "raw_entries/ab/1abc.parquet"
+ frame = pd.read_parquet(annotation)
+ frame["ligand_unique_ccd_code"] = "CHANGED"
+ frame.to_parquet(annotation, index=False)
+
+ with pytest.raises(RuntimeError, match="changed after planning"):
+ collate_shard(tmp_path, "ab", memory_limit="1GB")
+
+
+def test_shard_rejects_optional_ligand_outputs_appearing_after_plan(
+ tmp_path: Path,
+) -> None:
+ _write_release(tmp_path)
+ _write_interface_only_entry(tmp_path)
+ plan_collation(tmp_path)
+ pd.DataFrame({"entry_pdb_id": ["3ghi"]}).to_parquet(
+ tmp_path / "raw_entries/gh/3ghi.parquet", index=False
+ )
+ pd.DataFrame({"ligand_id": ["3ghi__1__1.L"]}).to_parquet(
+ tmp_path / "ligands/3ghi.parquet", index=False
+ )
+
+ with pytest.raises(RuntimeError, match="appeared after planning"):
+ collate_shard(tmp_path, "gh", memory_limit="1GB")
+
+
+def test_finalize_uses_frozen_shards_after_raw_inputs_change(tmp_path: Path) -> None:
+ _write_release(tmp_path)
+ plan_collation(tmp_path)
+ collate_shard(tmp_path, "ab", memory_limit="1GB")
+ collate_shard(tmp_path, "de", memory_limit="1GB")
+ annotation = tmp_path / "raw_entries/ab/1abc.parquet"
+ frame = pd.read_parquet(annotation)
+ frame["ligand_unique_ccd_code"] = "CHANGED"
+ frame.to_parquet(annotation, index=False)
+
+ report = finalize_collation(tmp_path, threads=2, memory_limit="1GB")
+
+ assert report["status"] == "complete"
+ installed = pd.read_parquet(tmp_path / "index/annotation_table.parquet")
+ assert "CHANGED" not in set(installed["ligand_unique_ccd_code"])
+
+
+def test_final_install_fails_closed_on_partial_replacement(
+ tmp_path: Path, monkeypatch
+) -> None:
+ names = (
+ "annotation",
+ "system_validation",
+ "entry_chains",
+ "entry_biounit_chains",
+ "entry_metadata",
+ "interfaces",
+ "entry_sources",
+ )
+ temporary_paths = {name: tmp_path / f"new-{name}" for name in names}
+ final_paths = {name: tmp_path / f"final-{name}" for name in names}
+ marker = tmp_path / "collation.json"
+ for path in temporary_paths.values():
+ path.write_text("new")
+ for path in final_paths.values():
+ path.write_text("old")
+ marker.write_text('{"status": "complete"}')
+ real_replace = Path.replace
+
+ def fail_on_second_sidecar(path: Path, target: Path) -> Path:
+ if target == final_paths["entry_biounit_chains"]:
+ raise OSError("simulated replacement failure")
+ return real_replace(path, target)
+
+ monkeypatch.setattr(Path, "replace", fail_on_second_sidecar)
+
+ with pytest.raises(OSError, match="simulated replacement failure"):
+ collate_module._install_final_tables_fail_closed(
+ temporary_paths, final_paths, marker
+ )
+
+ assert not marker.exists()
+ assert not final_paths["annotation"].exists()
+ assert not final_paths["system_validation"].exists()
+
+
+def test_plan_rejects_partial_materialized_entries(tmp_path: Path) -> None:
+ _write_release(tmp_path)
+ (tmp_path / "ligands/1abc.parquet").unlink()
+
+ with pytest.raises(FileNotFoundError, match="incomplete entry 1abc"):
+ plan_collation(tmp_path)
+
+
+def test_plan_rejects_empty_release(tmp_path: Path) -> None:
+ (tmp_path / "raw_entries").mkdir()
+
+ with pytest.raises(ValueError, match="no entries found"):
+ plan_collation(tmp_path)
+
+
+def test_plan_supports_bounded_parallel_inventory(tmp_path: Path) -> None:
+ _write_release(tmp_path)
+
+ plan = plan_collation(tmp_path, threads=2)
+
+ assert plan["entry_count"] == 2
+ with pytest.raises(ValueError, match="planning threads must be positive"):
+ plan_collation(tmp_path, threads=0)
+
+
+def test_shard_cli_selects_codes_from_pdb_manifest(tmp_path: Path) -> None:
+ from plinder.data.pipeline.collate import build_parser
+
+ manifest = tmp_path / "affected.txt"
+ manifest.write_text("1abc\n2abd\n3xyz\n")
+ args = build_parser().parse_args(
+ [
+ "shard",
+ str(tmp_path),
+ "--pdb-manifest",
+ str(manifest),
+ ]
+ )
+
+ assert args.pdb_manifest == manifest
+
+
+def test_final_validation_rejects_all_ion_or_artifact_systems(
+ tmp_path: Path,
+) -> None:
+ _write_entry(
+ tmp_path,
+ "1abc",
+ ligand_rows=[
+ {
+ "ligand_id": "1abc__1__1.I",
+ "ccd": "ZN",
+ "proper": True,
+ "ion": True,
+ }
+ ],
+ comparability={"1abc__1__1.I": False},
+ )
+
+ with pytest.raises(ValueError, match="all_ion_or_artifact_systems=1"):
+ run_collation(tmp_path, threads=1, memory_limit="1GB")
+
+
+@pytest.mark.parametrize(
+ ("length", "unresolved", "error_key"),
+ [
+ (0, 0, "nonpositive_lengths"),
+ (300, -1, "negative_unresolved"),
+ (300, 301, "unresolved_exceeds_length"),
+ ],
+)
+def test_final_validation_rejects_invalid_chain_sequence_metadata(
+ tmp_path: Path,
+ length: int,
+ unresolved: int,
+ error_key: str,
+) -> None:
+ _write_release(tmp_path)
+ chain_path = tmp_path / "raw_entries/ab/1abc/entry_chains.parquet"
+ chains = pd.read_parquet(chain_path)
+ chains.loc[0, "chain_length"] = length
+ chains.loc[0, "chain_num_unresolved_residues"] = unresolved
+ chains.to_parquet(chain_path, index=False)
+
+ with pytest.raises(ValueError, match=error_key):
+ run_collation(tmp_path, threads=1, memory_limit="1GB")
+
+
+def test_final_validation_rejects_missing_chain_sequence(tmp_path: Path) -> None:
+ _write_release(tmp_path)
+ chain_path = tmp_path / "raw_entries/ab/1abc/entry_chains.parquet"
+ chains = pd.read_parquet(chain_path)
+ chains.loc[0, "chain_sequence"] = ""
+ chains.to_parquet(chain_path, index=False)
+
+ with pytest.raises(ValueError, match="missing_sequences"):
+ run_collation(tmp_path, threads=1, memory_limit="1GB")
+
+
+def test_final_validation_rejects_ligands_from_another_biounit(
+ tmp_path: Path,
+) -> None:
+ _write_release(tmp_path)
+ annotation_path = tmp_path / "raw_entries/ab/1abc.parquet"
+ annotation = pd.read_parquet(annotation_path)
+ annotation.loc[0, "ligand_id"] = "1abc__2__1.L"
+ annotation.to_parquet(annotation_path, index=False)
+ ligand_path = tmp_path / "ligands/1abc.parquet"
+ ligands = pd.read_parquet(ligand_path)
+ ligands.loc[ligands["ligand_id"].eq("1abc__1__1.L"), "ligand_id"] = "1abc__2__1.L"
+ ligands.to_parquet(ligand_path, index=False)
+
+ with pytest.raises(ValueError, match="mismatched_biounits=1"):
+ run_collation(tmp_path, threads=1, memory_limit="1GB")
diff --git a/tests/data/pipeline/test_config.py b/tests/data/pipeline/test_config.py
index 90065f1b8..71bc9180e 100644
--- a/tests/data/pipeline/test_config.py
+++ b/tests/data/pipeline/test_config.py
@@ -1,10 +1,12 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
import unittest.mock
+from dataclasses import asdict
from textwrap import dedent
import pytest
from omegaconf import OmegaConf
+
from plinder.data.pipeline import config
@@ -24,6 +26,28 @@ def test_foldseek_config(value, raises):
config.FoldseekConfig(alignment_type=value)
+def test_search_defaults_retain_ten_thousand_hits() -> None:
+ assert config.FoldseekConfig().max_seqs == 10_000
+ assert config.FoldseekConfig().min_seq_id == 0.2
+ assert config.MMSeqsConfig().max_seqs == 10_000
+ assert config.MMSeqsConfig().min_seq_id == 0.2
+
+
+@pytest.mark.parametrize("config_type", [config.FoldseekConfig, config.MMSeqsConfig])
+def test_search_hit_limit_must_be_positive(config_type) -> None:
+ with pytest.raises(ValueError, match="max_seqs must be positive"):
+ config_type(max_seqs=0)
+
+
+@pytest.mark.parametrize("config_type", [config.FoldseekConfig, config.MMSeqsConfig])
+@pytest.mark.parametrize("min_seq_id", [-0.1, 1.1])
+def test_search_minimum_sequence_identity_must_be_a_fraction(
+ config_type, min_seq_id
+) -> None:
+ with pytest.raises(ValueError, match="min_seq_id must be in"):
+ config_type(min_seq_id=min_seq_id)
+
+
def test_flow_config():
dc = config._config.DataConfig()
cfg = OmegaConf.structured(config._config.DataConfig())
@@ -33,9 +57,122 @@ def test_flow_config():
def test_default_config():
cfg = config.get_config(cached=False)
assert cfg.data.plinder_release is not None
+ assert cfg.scorer.minimum_threshold == 0.3
+ assert cfg.scorer.max_alignment_rows_per_query == 5_000_000
+ assert cfg.scorer.max_query_protein_chains == 30
+ assert cfg.scorer.max_query_proper_ligand_chains == 30
+ assert list(cfg.flow.cluster_thresholds) == [30, 50, 70, 90, 100]
+ assert cfg.flow.component_reduction_metric_workers == 4
+ assert cfg.interface.contact_radius == 10.0
+ assert cfg.interface.min_chain_length == 12
+ assert cfg.interface.min_interface_residues == 7
+
+
+def test_ingest_annotation_defaults_have_one_owner():
+ assert asdict(config.AnnotationConfig()) == {
+ "neighboring_residue_threshold": 6.0,
+ "neighboring_ligand_threshold": 4.0,
+ "min_polymer_size": 12,
+ "min_shared_pocket_members": 3,
+ }
+ assert asdict(config.EntryConfig()) == {
+ "interaction_search_threshold": 10.0,
+ "tessellation_atom_limit": 2_000_000,
+ "data_dir": None,
+ "save_folder": None,
+ }
+
+
+@pytest.mark.parametrize("source", ["yaml", "cli"])
+@pytest.mark.parametrize(
+ ("include_ligands", "include_interfaces"),
+ [(True, True), (True, False), (False, True)],
+)
+def test_annotation_overrides_reach_entry_reader(
+ tmp_path, source, include_ligands, include_interfaces
+):
+ from plinder.data.get_system_annotations import GetPlinderAnnotation
+
+ thresholds = {
+ "neighboring_residue_threshold": 7.0,
+ "neighboring_ligand_threshold": 5.0,
+ "min_polymer_size": 15,
+ "min_shared_pocket_members": 4,
+ }
+ if source == "yaml":
+ contents = "annotation:\n" + "".join(
+ f" {name}: {value}\n" for name, value in thresholds.items()
+ )
+ contents += "entry:\n interaction_search_threshold: 11.0\n"
+ cfg = config.get_config(config_contents=contents, config_args=[], cached=False)
+ else:
+ args = [f"annotation.{name}={value}" for name, value in thresholds.items()]
+ args.append("entry.interaction_search_threshold=11.0")
+ cfg = config.get_config(config_args=args, cached=False)
+
+ annotator = GetPlinderAnnotation(
+ tmp_path / "source.cif",
+ tmp_path / "validation.xml.gz",
+ entry_cfg=dict(cfg.entry),
+ **dict(cfg.annotation),
+ )
+ options = annotator._entry_options(
+ include_ligands=include_ligands, include_interfaces=include_interfaces
+ )
+ assert {name: options[name] for name in thresholds} == thresholds
+ assert options["interaction_search_threshold"] == 11.0
+ assert options["include_ligands"] is include_ligands
+ assert options["include_interfaces"] is include_interfaces
-def test_get_config_metaflow(tmp_path):
+@pytest.mark.parametrize("name", list(asdict(config.AnnotationConfig())))
+@pytest.mark.parametrize("source", ["yaml", "cli", "argv"])
+def test_shared_thresholds_are_rejected_in_entry_section(name, source, monkeypatch):
+ with pytest.raises(TypeError, match=name):
+ if source == "yaml":
+ config.get_config(
+ config_contents=f"entry:\n {name}: 5\n", config_args=[], cached=False
+ )
+ elif source == "cli":
+ config.get_config(config_args=[f"entry.{name}=5"], cached=False)
+ else:
+ monkeypatch.setattr("sys.argv", ["ingest", f"entry.{name}=5"])
+ config.get_config(cached=False)
+
+
+@pytest.mark.parametrize(
+ "kwargs",
+ [
+ {"contact_radius": 0},
+ {"min_chain_length": 0},
+ {"min_interface_residues": 0},
+ ],
+)
+def test_interface_config_limits_must_be_positive(kwargs) -> None:
+ with pytest.raises(ValueError, match="interface"):
+ config.InterfaceConfig(**kwargs)
+
+
+def test_component_reduction_metric_workers_must_be_positive() -> None:
+ with pytest.raises(ValueError, match="component_reduction_metric_workers"):
+ config.FlowConfig(component_reduction_metric_workers=0)
+
+
+@pytest.mark.parametrize("metric", ["shape", "color", "sucos_shape"])
+def test_raw_3d_ligand_diagnostics_cannot_be_clustered(metric) -> None:
+ with pytest.raises(ValueError, match="sucos_shape_pocket_qcov"):
+ config.get_config(
+ cached=False,
+ config={"flow": {"cluster_metrics": [metric]}},
+ )
+
+
+def test_alignment_mapping_row_budget_must_be_positive() -> None:
+ with pytest.raises(ValueError, match="max_alignment_rows_per_query"):
+ config.ScorerConfig(max_alignment_rows_per_query=0)
+
+
+def test_get_config_merges_file_and_contents(tmp_path):
file = tmp_path / "conf.yaml"
file.write_text(
dedent(
@@ -79,3 +216,11 @@ def test_get_config_cli():
with unittest.mock.patch("sys.argv", test_args):
cfg = config.get_config(cached=False)
assert cfg.flow.download_rcsb_files_batch_size == 4
+
+
+@pytest.mark.parametrize("backend", ["foldseek", "mmseqs"])
+def test_get_config_ignores_search_backend_argument(backend):
+ test_args = ["score", "search", "--alignment-type", backend, "foldseek.max_seqs=42"]
+ with unittest.mock.patch("sys.argv", test_args):
+ cfg = config.get_config(cached=False)
+ assert cfg.foldseek.max_seqs == 42
diff --git a/tests/data/pipeline/test_end_to_end.py b/tests/data/pipeline/test_end_to_end.py
index cb641a3f6..21f9a5d87 100644
--- a/tests/data/pipeline/test_end_to_end.py
+++ b/tests/data/pipeline/test_end_to_end.py
@@ -1,12 +1,23 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
-from plinder.data.pipeline import config, pipeline, tasks
+from plinder.data.pipeline import config, io, pipeline, tasks
-def test_end_to_end(mock_alternative_datasets):
+def test_end_to_end(mock_alternative_datasets, monkeypatch):
mock_alternative_datasets("4jvm") # different from 19hc
- stages = ",".join(tasks.STAGES[: tasks.STAGES.index("collate_partitions")])
+ # refresh_bundled_ccd re-syncs biotite's bundled CCD from wwPDB via
+ # setup_ccd (a heavy online download); the shipped bt_info snapshot is
+ # already usable, so stub it out for the offline end-to-end run.
+ monkeypatch.setattr(io, "refresh_bundled_ccd", lambda **kwargs: None)
+
+ # make_ccd_ligand_dbs builds the ~50k-component CCD universe once per CCD
+ # release, not per ingest; tests/data/test_ccd_ligand_dbs.py covers it.
+ stages = ",".join(
+ stage
+ for stage in tasks.STAGES[: tasks.STAGES.index("collate_partitions")]
+ if stage != "make_ccd_ligand_dbs"
+ )
import sys
print(stages, file=sys.stderr, flush=True)
diff --git a/tests/data/pipeline/test_ingest.py b/tests/data/pipeline/test_ingest.py
new file mode 100644
index 000000000..b5e319a02
--- /dev/null
+++ b/tests/data/pipeline/test_ingest.py
@@ -0,0 +1,1450 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+
+import json
+from pathlib import Path
+from types import SimpleNamespace
+
+import pandas as pd
+import pyarrow as pa
+import pyarrow.parquet as pq
+import pytest
+
+from plinder.data.annotations.interface_utils import (
+ INTERFACE_ANNOTATION_SCHEMA,
+ MIN_INTERFACE_RESIDUES_METADATA_KEY,
+)
+from plinder.data.pipeline import ingest
+from plinder.data.pipeline.ingest import (
+ REQUIRED_REFERENCE_FILES,
+ EntryInput,
+ balance_entries,
+ build_parser,
+ check_reference_data,
+ completed_entry_metrics,
+ completed_interface_metrics,
+ discover_entries,
+ ingest_one_pdb,
+ ingest_pdb_batch,
+ load_manifest,
+ manifest_slice,
+ normalize_pdb_id,
+ resolve_entry_paths,
+ resolve_source_roots,
+ write_manifest,
+)
+
+_LIGAND_ANNOTATIONS = {
+ "ligand_contact_area": [None],
+ "ligand_contact_area_chains": [[]],
+ "ligand_contact_area_values": [[]],
+ "ligand_unresolved_atoms": [[]],
+ "ligand_pocket_unresolved_atoms": [[]],
+ "ligand_is_subject_of_investigation": [None],
+}
+
+
+def _write_fake_sidecars(
+ entry_dir: Path,
+ pdb_id: str,
+ *,
+ interfaces: list[dict[str, object]] | None = None,
+) -> None:
+ pd.DataFrame(
+ {
+ "entry_pdb_id": [pdb_id],
+ "chain_receptor_type": ["protein"],
+ "chain_is_ligand_like": [False],
+ "chain_sequence_noncanonical": ["A(MSE)G"],
+ "chain_modified_residues": [["A_2_MSE"]],
+ }
+ ).to_parquet(entry_dir / "entry_chains.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": [pdb_id],
+ "biounit_id": ["1"],
+ "chain_instance": ["1.A"],
+ "chain_asym_id": ["A"],
+ "chain_role": ["receptor"],
+ "chain_num_contacting_ions": [0],
+ "chain_num_contacting_artifacts": [0],
+ "chain_num_contacting_other_ligands": [0],
+ "chain_num_contacting_proteins": [0],
+ }
+ ).to_parquet(entry_dir / "entry_biounit_chains.parquet", index=False)
+ pd.DataFrame({"entry_pdb_id": [pdb_id]}).to_parquet(
+ entry_dir / "entry_source.parquet", index=False
+ )
+ pd.DataFrame(
+ {
+ "entry_pdb_id": [pdb_id],
+ "entry_pH_min": [None],
+ "entry_pH_max": [None],
+ "entry_has_ligand_of_interest": [None],
+ }
+ ).to_parquet(entry_dir / "entry_metadata.parquet", index=False)
+ interface_columns = [
+ *INTERFACE_ANNOTATION_SCHEMA.names,
+ ]
+ normalized_interfaces = []
+ for interface in interfaces or []:
+ normalized = dict.fromkeys(interface_columns)
+ normalized.update(interface)
+ normalized["prodigy_is_annotated"] = bool(normalized["prodigy_is_annotated"])
+ normalized_interfaces.append(normalized)
+ interface_path = entry_dir / "interfaces.parquet"
+ table = pa.Table.from_pylist(
+ normalized_interfaces,
+ schema=INTERFACE_ANNOTATION_SCHEMA,
+ )
+ pq.write_table(table, interface_path)
+ table = pq.read_table(interface_path)
+ metadata = dict(table.schema.metadata or {})
+ metadata[MIN_INTERFACE_RESIDUES_METADATA_KEY] = b"7"
+ pq.write_table(table.replace_schema_metadata(metadata), interface_path)
+
+
+def test_empty_annotation_writes_shared_sidecars(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ from plinder.data import get_system_annotations as annotation_module
+
+ validation_calls: list[tuple[Path, Path]] = []
+ entry = SimpleNamespace(
+ pdb_id="8grn",
+ systems={},
+ interfaces=[],
+ set_validation=lambda validation, cif: validation_calls.append(
+ (
+ validation,
+ cif,
+ )
+ ),
+ metadata_to_df=lambda: pd.DataFrame({"entry_pdb_id": ["8grn"]}),
+ )
+ monkeypatch.setattr(
+ annotation_module.Entry,
+ "from_cif_file",
+ lambda *_args, **_kwargs: entry,
+ )
+ annotator = annotation_module.GetPlinderAnnotation(
+ tmp_path / "8grn.cif",
+ tmp_path / "8grn_validation.xml.gz",
+ save_folder=tmp_path / "raw_entries",
+ )
+ writes: list[tuple[Path, int, bool]] = []
+ monkeypatch.setattr(
+ annotator,
+ "_write_shared_sidecars",
+ lambda path, table, *, replace_interfaces: writes.append(
+ (
+ path,
+ table.num_rows,
+ replace_interfaces,
+ )
+ ),
+ )
+
+ assert annotator.annotate() is None
+ assert validation_calls == [
+ (tmp_path / "8grn_validation.xml.gz", tmp_path / "8grn.cif")
+ ]
+ assert writes == [(tmp_path / "raw_entries/8grn", 0, True)]
+
+
+def test_resolve_entry_paths_uses_managed_archive_layout(tmp_path: Path) -> None:
+ cif_file, validation_file = resolve_entry_paths(
+ "8GRN",
+ cif_root=tmp_path / "nextgen",
+ validation_root=tmp_path / "validation",
+ )
+
+ assert cif_file == (
+ tmp_path / "nextgen" / "gr" / "pdb_00008grn" / "pdb_00008grn_xyz-enrich.cif.gz"
+ )
+ assert validation_file == (
+ tmp_path / "validation" / "gr" / "8grn" / "8grn_validation.xml.gz"
+ )
+
+
+def test_source_roots_prefer_config_then_environment_then_local_defaults(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ monkeypatch.setenv("PLINDER_PDB_NEXTGEN_ROOT", str(tmp_path / "env-cif"))
+ monkeypatch.setenv("PLINDER_VALIDATION_ROOT", str(tmp_path / "env-validation"))
+
+ assert resolve_source_roots(data_dir=tmp_path) == (
+ (tmp_path / "env-cif").resolve(),
+ (tmp_path / "env-validation").resolve(),
+ )
+ assert resolve_source_roots(
+ data_dir=tmp_path,
+ cif_root="configured-cif",
+ validation_root="configured-validation",
+ ) == (
+ (tmp_path / "configured-cif").resolve(),
+ (tmp_path / "configured-validation").resolve(),
+ )
+
+ monkeypatch.delenv("PLINDER_PDB_NEXTGEN_ROOT")
+ monkeypatch.delenv("PLINDER_VALIDATION_ROOT")
+ assert resolve_source_roots(data_dir=tmp_path) == (
+ (tmp_path / "ingest").resolve(),
+ (tmp_path / "reports").resolve(),
+ )
+
+ monkeypatch.setenv("HOME", str(tmp_path / "home"))
+ assert resolve_source_roots(
+ data_dir=tmp_path,
+ cif_root="~/nextgen",
+ validation_root="~/validation",
+ ) == (
+ (tmp_path / "home/nextgen").resolve(),
+ (tmp_path / "home/validation").resolve(),
+ )
+
+
+@pytest.mark.parametrize("value", ["", "8gr", "abcd", "8grn-extra"])
+def test_normalize_pdb_id_rejects_invalid_ids(value: str) -> None:
+ with pytest.raises(ValueError, match="invalid four-character PDB ID"):
+ normalize_pdb_id(value)
+
+
+def test_reference_data_check_reports_every_missing_file(tmp_path: Path) -> None:
+ with pytest.raises(FileNotFoundError) as exc_info:
+ check_reference_data(tmp_path)
+
+ message = str(exc_info.value)
+ assert "cofactors.json" in message
+ assert "candidates.parquet" in message
+ assert "measurements.parquet" in message
+
+
+def test_ingest_one_pdb_writes_entry_outputs_and_metrics(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ from dataclasses import asdict
+ from inspect import signature
+
+ from plinder.data.annotations.aggregate_annotations import Entry, System
+
+ output_root = tmp_path / "output"
+ cif_root = tmp_path / "nextgen"
+ validation_root = tmp_path / "validation"
+ cif_file, validation_file = resolve_entry_paths(
+ "8grn",
+ cif_root=cif_root,
+ validation_root=validation_root,
+ )
+ for path in (cif_file, validation_file):
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.touch()
+ for relative in REQUIRED_REFERENCE_FILES:
+ path = output_root / relative
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_text("{}")
+
+ class FakeAnnotation:
+ def __init__(
+ self,
+ cif_path: Path,
+ validation_path: Path,
+ *,
+ save_folder: Path,
+ data_dir: Path,
+ ) -> None:
+ assert cif_path == cif_file
+ assert validation_path == validation_file
+ assert data_dir == output_root.resolve()
+ self.save_folder = save_folder
+
+ def annotate(self) -> pd.DataFrame:
+ ligand_dir = self.save_folder / "8grn" / "ligand_files"
+ ligand_dir.mkdir(parents=True)
+ (ligand_dir / "1.C.sdf").touch()
+ _write_fake_sidecars(ligand_dir.parent, "8grn")
+ return pd.DataFrame(
+ {
+ "system_id": ["8grn__1__1.A__1.C"],
+ "ligand_id": ["8grn__1.C"],
+ "system_receptor_type": ["protein"],
+ **_LIGAND_ANNOTATIONS,
+ }
+ )
+
+ def fake_save_ligand_batch(
+ *, data_dir: Path, annotation: pd.DataFrame, output_path: Path
+ ) -> None:
+ assert data_dir == output_root.resolve()
+ assert len(annotation) == 1
+ annotation[["ligand_id"]].assign(ligand_is_shape_comparable=True).to_parquet(
+ output_path, index=False
+ )
+
+ monkeypatch.setattr(ingest, "_get_annotation_class", lambda: FakeAnnotation)
+ monkeypatch.setattr(ingest, "_save_ligand_batch", fake_save_ligand_batch)
+
+ metrics_path = ingest_one_pdb(
+ pdb_id="8GRN",
+ output_root=output_root,
+ cif_root=cif_root,
+ validation_root=validation_root,
+ )
+
+ metrics = json.loads(metrics_path.read_text())
+ assert metrics["validation_settings"] == {
+ "residue_thresholds": signature(Entry.set_validation)
+ .parameters["thresholds"]
+ .default.model_dump(),
+ "quality_criteria": asdict(
+ signature(System.format).parameters["criteria"].default
+ ),
+ }
+ assert (
+ metrics_path
+ == output_root.resolve() / "metrics" / "gr" / "ingest-one-8grn.json"
+ )
+ assert metrics["status"] == "complete"
+ assert metrics["counts"] == {
+ "annotation_rows": 1,
+ "interface_rows": 0,
+ "systems": 1,
+ "ligand_ids": 1,
+ "canonical_ligand_sdfs": 1,
+ }
+ assert [stage["stage"] for stage in metrics["timings"]] == [
+ "annotate_entry",
+ "write_entry_parquet",
+ "write_ligand_parquet",
+ ]
+ assert all(stage["status"] == "complete" for stage in metrics["timings"])
+ assert (output_root / "raw_entries" / "gr" / "8grn.parquet").is_file()
+ assert (output_root / "ligands" / "8grn.parquet").is_file()
+
+
+def test_ingest_one_pdb_retains_sidecars_for_entries_without_systems(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ output_root = tmp_path / "output"
+ cif_root = tmp_path / "nextgen"
+ validation_root = tmp_path / "validation"
+ cif_file, validation_file = resolve_entry_paths(
+ "8grn",
+ cif_root=cif_root,
+ validation_root=validation_root,
+ )
+ for path in (cif_file, validation_file):
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.touch()
+ for relative in REQUIRED_REFERENCE_FILES:
+ path = output_root / relative
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_text("{}")
+
+ class EmptyAnnotation:
+ def __init__(self, *_args, save_folder: Path, **_kwargs) -> None:
+ self.save_folder = save_folder
+
+ def annotate(self) -> None:
+ entry_dir = self.save_folder / "8grn"
+ stale_dir = entry_dir / "ligand_files"
+ stale_dir.mkdir(parents=True)
+ (stale_dir / "A.sdf").touch()
+ _write_fake_sidecars(entry_dir, "8grn")
+ return None
+
+ monkeypatch.setattr(ingest, "_get_annotation_class", lambda: EmptyAnnotation)
+ entry_parquet = output_root / "raw_entries" / "gr" / "8grn.parquet"
+ ligand_parquet = output_root / "ligands" / "8grn.parquet"
+ for path in (entry_parquet, ligand_parquet):
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.touch()
+
+ metrics_path = ingest_one_pdb(
+ pdb_id="8grn",
+ output_root=output_root,
+ cif_root=cif_root,
+ validation_root=validation_root,
+ force=True,
+ )
+
+ metrics = json.loads(metrics_path.read_text())
+ assert metrics["status"] == "complete"
+ assert metrics["counts"] == {
+ "annotation_rows": 0,
+ "interface_rows": 0,
+ "systems": 0,
+ "ligand_ids": 0,
+ "canonical_ligand_sdfs": 0,
+ }
+ assert [stage["stage"] for stage in metrics["timings"]] == ["annotate_entry"]
+ assert metrics["outputs"] == {
+ "entry_parquet": None,
+ "entry_directory": str(output_root / "raw_entries" / "gr" / "8grn"),
+ "ligand_parquet": None,
+ }
+ assert not entry_parquet.exists()
+ assert not ligand_parquet.exists()
+ entry_dir = output_root / "raw_entries" / "gr" / "8grn"
+ assert entry_dir.is_dir()
+ assert not (entry_dir / "ligand_files").exists()
+ assert (entry_dir / "entry_chains.parquet").is_file()
+ assert (entry_dir / "entry_biounit_chains.parquet").is_file()
+ assert completed_entry_metrics(output_root, "8grn") == metrics_path
+
+
+def test_ingest_one_pdb_materializes_interface_only_entries(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ output_root = tmp_path / "output"
+ cif_root = tmp_path / "nextgen"
+ validation_root = tmp_path / "validation"
+ cif_file, _ = resolve_entry_paths(
+ "8grn", cif_root=cif_root, validation_root=validation_root
+ )
+ cif_file.parent.mkdir(parents=True)
+ cif_file.touch()
+
+ class InterfaceOnlyAnnotation:
+ def __init__(self, *_args, save_folder: Path, **_kwargs) -> None:
+ self.save_folder = save_folder
+
+ def annotate(self) -> pd.DataFrame:
+ entry_dir = self.save_folder / "8grn"
+ entry_dir.mkdir(parents=True)
+ _write_fake_sidecars(
+ entry_dir,
+ "8grn",
+ interfaces=[
+ {
+ "entry_pdb_id": "8grn",
+ "system_id": "8grn__1__1.A--1.B",
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.A",
+ "interface_chain_2": "1.B",
+ "interface_chain_1_residue_numbers": [1, 2, 3],
+ "interface_chain_1_residue_indices": [0, 1, 2],
+ "interface_chain_2_residue_numbers": [4, 5, 6],
+ "interface_chain_2_residue_indices": [0, 1, 2],
+ "interface_num_contact_residue_pairs": 3,
+ }
+ ],
+ )
+ return pd.DataFrame()
+
+ monkeypatch.setattr(
+ ingest, "_get_annotation_class", lambda: InterfaceOnlyAnnotation
+ )
+ metrics_path = ingest_one_pdb(
+ pdb_id="8grn",
+ output_root=output_root,
+ cif_root=cif_root,
+ validation_root=validation_root,
+ check_references=False,
+ )
+
+ metrics = json.loads(metrics_path.read_text())
+ assert metrics["status"] == "complete"
+ assert metrics["counts"] == {
+ "annotation_rows": 0,
+ "interface_rows": 1,
+ "systems": 0,
+ "ligand_ids": 0,
+ "canonical_ligand_sdfs": 0,
+ }
+ assert metrics["outputs"]["entry_parquet"] is None
+ assert metrics["outputs"]["ligand_parquet"] is None
+ assert (output_root / "raw_entries/gr/8grn/interfaces.parquet").is_file()
+ assert completed_entry_metrics(output_root, "8grn") == metrics_path
+
+
+def test_interface_mode_preserves_every_ligand_asset(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ output_root = tmp_path / "output"
+ cif_root = tmp_path / "nextgen"
+ validation_root = tmp_path / "validation"
+ cif_file, _ = resolve_entry_paths(
+ "8grn", cif_root=cif_root, validation_root=validation_root
+ )
+ cif_file.parent.mkdir(parents=True)
+ cif_file.touch()
+
+ entry_parquet = output_root / "raw_entries/gr/8grn.parquet"
+ ligand_parquet = output_root / "ligands/8grn.parquet"
+ entry_dir = output_root / "raw_entries/gr/8grn"
+ entry_dir.mkdir(parents=True)
+ ligand_parquet.parent.mkdir(parents=True)
+ pd.DataFrame({"system_id": ["8grn__1__1.A__1.C"]}).to_parquet(
+ entry_parquet, index=False
+ )
+ pd.DataFrame({"ligand_id": ["8grn__1.C"]}).to_parquet(ligand_parquet, index=False)
+ _write_fake_sidecars(entry_dir, "8grn")
+ ligand_sdf = entry_dir / "ligand_files/1.C.sdf"
+ ligand_sdf.parent.mkdir()
+ ligand_sdf.write_text("canonical ligand")
+ full_metrics = output_root / "metrics/gr/ingest-one-8grn.json"
+ full_metrics.parent.mkdir(parents=True)
+ full_metrics.write_text('{"status":"original-full-ingest"}\n')
+ preserved_paths = [
+ entry_parquet,
+ ligand_parquet,
+ ligand_sdf,
+ full_metrics,
+ entry_dir / "entry_chains.parquet",
+ entry_dir / "entry_biounit_chains.parquet",
+ entry_dir / "entry_metadata.parquet",
+ entry_dir / "entry_source.parquet",
+ ]
+ before = {path: path.read_bytes() for path in preserved_paths}
+
+ class InterfaceAnnotation:
+ def __init__(self, *_args: object, save_folder: Path, **_kwargs: object):
+ self.save_folder = save_folder
+
+ def annotate_interfaces(self) -> pa.Table:
+ interface = dict.fromkeys(INTERFACE_ANNOTATION_SCHEMA.names)
+ interface.update(
+ {
+ "entry_pdb_id": "8grn",
+ "system_id": "8grn__1__1.A--1.B",
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.A",
+ "interface_chain_2": "1.B",
+ "interface_chain_1_residue_numbers": list(range(1, 8)),
+ "interface_chain_1_residue_indices": list(range(7)),
+ "interface_chain_2_residue_numbers": list(range(11, 18)),
+ "interface_chain_2_residue_indices": list(range(7)),
+ "interface_num_contact_residue_pairs": 8,
+ "prodigy_is_annotated": True,
+ "prodigy_label": "BIO",
+ "prodigy_probability_bio": 0.9,
+ "prodigy_link_density": 0.2,
+ "prodigy_intermolecular_contacts": 8,
+ "prodigy_charged_charged_contacts": 1,
+ "prodigy_charged_polar_contacts": 1,
+ "prodigy_charged_apolar_contacts": 2,
+ "prodigy_polar_polar_contacts": 0,
+ "prodigy_apolar_polar_contacts": 1,
+ "prodigy_apolar_apolar_contacts": 3,
+ }
+ )
+ schema = INTERFACE_ANNOTATION_SCHEMA.with_metadata(
+ {MIN_INTERFACE_RESIDUES_METADATA_KEY: b"7"}
+ )
+ table = pa.Table.from_pylist([interface], schema=schema)
+ pq.write_table(
+ table,
+ self.save_folder / "8grn/interfaces.parquet",
+ )
+ return table
+
+ monkeypatch.setattr(ingest, "_get_annotation_class", lambda: InterfaceAnnotation)
+ metrics_path = ingest_one_pdb(
+ pdb_id="8grn",
+ output_root=output_root,
+ cif_root=cif_root,
+ validation_root=validation_root,
+ mode="interfaces",
+ )
+
+ assert {path: path.read_bytes() for path in preserved_paths} == before
+ assert metrics_path.name == "ingest-interfaces-8grn.json"
+ metrics = json.loads(metrics_path.read_text())
+ assert metrics["status"] == "complete"
+ assert metrics["counts"] == {
+ "interface_rows": 1,
+ "prodigy_annotated_rows": 1,
+ "preserved_ligand_annotation_rows": 1,
+ }
+ assert completed_interface_metrics(output_root, "8grn") == metrics_path
+ assert pq.read_table(entry_dir / "interfaces.parquet").column(
+ "prodigy_label"
+ ).to_pylist() == ["BIO"]
+
+
+def test_ligand_mode_skips_interfaces_and_preserves_interface_assets(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ output_root = tmp_path / "output"
+ cif_root = tmp_path / "nextgen"
+ validation_root = tmp_path / "validation"
+ cif_file, _ = resolve_entry_paths(
+ "8grn", cif_root=cif_root, validation_root=validation_root
+ )
+ cif_file.parent.mkdir(parents=True)
+ cif_file.touch()
+ entry_dir = output_root / "raw_entries/gr/8grn"
+ entry_dir.mkdir(parents=True)
+ _write_fake_sidecars(
+ entry_dir,
+ "8grn",
+ interfaces=[
+ {
+ "entry_pdb_id": "8grn",
+ "system_id": "8grn__1__1.A--1.B",
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.A",
+ "interface_chain_2": "1.B",
+ "interface_chain_1_residue_numbers": list(range(1, 8)),
+ "interface_chain_1_residue_indices": list(range(7)),
+ "interface_chain_2_residue_numbers": list(range(11, 18)),
+ "interface_chain_2_residue_indices": list(range(7)),
+ "interface_num_contact_residue_pairs": 8,
+ "prodigy_is_annotated": True,
+ "prodigy_label": "BIO",
+ "prodigy_probability_bio": 0.9,
+ "prodigy_link_density": 0.2,
+ "prodigy_intermolecular_contacts": 8,
+ "prodigy_charged_charged_contacts": 1,
+ "prodigy_charged_polar_contacts": 1,
+ "prodigy_charged_apolar_contacts": 2,
+ "prodigy_polar_polar_contacts": 0,
+ "prodigy_apolar_polar_contacts": 1,
+ "prodigy_apolar_apolar_contacts": 3,
+ }
+ ],
+ )
+ preserved_paths = list(entry_dir.glob("*.parquet"))
+ before = {path: path.read_bytes() for path in preserved_paths}
+
+ class LigandAnnotation:
+ def __init__(self, *_args: object, save_folder: Path, **_kwargs: object):
+ self.save_folder = save_folder
+
+ def annotate(self, *, include_interfaces: bool) -> pd.DataFrame:
+ assert not include_interfaces
+ ligand_dir = self.save_folder / "8grn/ligand_files"
+ ligand_dir.mkdir()
+ (ligand_dir / "1.C.sdf").write_text("canonical ligand")
+ return pd.DataFrame(
+ {
+ "system_id": ["8grn__1__1.A__1.C"],
+ "ligand_id": ["8grn__1.C"],
+ "system_receptor_type": ["protein"],
+ **_LIGAND_ANNOTATIONS,
+ }
+ )
+
+ def save_ligands(
+ *, data_dir: Path, annotation: pd.DataFrame, output_path: Path
+ ) -> None:
+ del data_dir, annotation
+ pd.DataFrame(
+ {
+ "ligand_id": ["8grn__1.C"],
+ "ligand_is_shape_comparable": [True],
+ }
+ ).to_parquet(output_path, index=False)
+
+ monkeypatch.setattr(ingest, "_get_annotation_class", lambda: LigandAnnotation)
+ monkeypatch.setattr(ingest, "_save_ligand_batch", save_ligands)
+ metrics_path = ingest_one_pdb(
+ pdb_id="8grn",
+ output_root=output_root,
+ cif_root=cif_root,
+ validation_root=validation_root,
+ check_references=False,
+ mode="ligands",
+ )
+
+ assert {path: path.read_bytes() for path in preserved_paths} == before
+ metrics = json.loads(metrics_path.read_text())
+ assert metrics["mode"] == "ligands"
+ assert metrics["counts"]["interface_rows"] == 1
+ assert metrics["counts"]["interface_rows_generated"] == 0
+ assert (
+ completed_entry_metrics(output_root, "8grn", expected_ingest_mode="ligands")
+ == metrics_path
+ )
+
+
+def test_interface_mode_resumes_zero_interface_entries(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ output_root = tmp_path / "output"
+ cif_root = tmp_path / "nextgen"
+ validation_root = tmp_path / "validation"
+ cif_file, _ = resolve_entry_paths(
+ "8grn", cif_root=cif_root, validation_root=validation_root
+ )
+ cif_file.parent.mkdir(parents=True)
+ cif_file.touch()
+ calls = 0
+
+ class EmptyInterfaceAnnotation:
+ def __init__(self, *_args: object, **kwargs: object):
+ save_folder = kwargs["save_folder"]
+ assert isinstance(save_folder, Path)
+ self.entry_dir = save_folder / "8grn"
+
+ def annotate_interfaces(self) -> pa.Table:
+ nonlocal calls
+ calls += 1
+ if self.entry_dir.exists():
+ biounit_path = self.entry_dir / "entry_biounit_chains.parquet"
+ biounits = pd.read_parquet(biounit_path)
+ biounits["chain_num_contacting_proteins"] = 0
+ biounits.to_parquet(biounit_path, index=False)
+ return pa.Table.from_pylist(
+ [],
+ schema=INTERFACE_ANNOTATION_SCHEMA.with_metadata(
+ {MIN_INTERFACE_RESIDUES_METADATA_KEY: b"7"}
+ ),
+ )
+
+ monkeypatch.setattr(
+ ingest, "_get_annotation_class", lambda: EmptyInterfaceAnnotation
+ )
+ metrics_path = ingest_one_pdb(
+ pdb_id="8grn",
+ output_root=output_root,
+ cif_root=cif_root,
+ validation_root=validation_root,
+ mode="interfaces",
+ )
+ assert json.loads(metrics_path.read_text())["status"] == "skipped_no_interfaces"
+ assert not (output_root / "raw_entries/gr/8grn").exists()
+
+ batch_metrics, had_failures = ingest_pdb_batch(
+ pdb_ids=["8grn"],
+ output_root=output_root,
+ cif_root=cif_root,
+ validation_root=validation_root,
+ mode="interfaces",
+ )
+ assert not had_failures
+ assert json.loads(batch_metrics.read_text())["entries"][0]["status"] == (
+ "skipped_complete"
+ )
+ assert calls == 1
+
+ entry_dir = output_root / "raw_entries/gr/8grn"
+ entry_dir.mkdir(parents=True)
+ _write_fake_sidecars(entry_dir, "8grn")
+ biounit_path = entry_dir / "entry_biounit_chains.parquet"
+ biounits = pd.read_parquet(biounit_path).drop(
+ columns="chain_num_contacting_proteins"
+ )
+ biounits.to_parquet(biounit_path, index=False)
+ ligand_metrics_path = ingest.entry_metrics_path(output_root, "8grn")
+ ligand_metrics_path.parent.mkdir(parents=True, exist_ok=True)
+ ligand_metrics_path.write_text(
+ json.dumps(
+ {
+ "status": "skipped_no_ligands",
+ "mode": "ligands",
+ "counts": {"entry_chain_rows": 1},
+ "outputs": {"entry_directory": str(entry_dir)},
+ }
+ )
+ )
+ preserved = {
+ path.name: path.read_bytes()
+ for path in entry_dir.iterdir()
+ if path.name != "entry_biounit_chains.parquet"
+ }
+ assert completed_interface_metrics(output_root, "8grn") is None
+
+ refreshed_metrics = ingest_one_pdb(
+ pdb_id="8grn",
+ output_root=output_root,
+ cif_root=cif_root,
+ validation_root=validation_root,
+ mode="interfaces",
+ )
+
+ assert entry_dir.is_dir()
+ assert {
+ path.name: path.read_bytes()
+ for path in entry_dir.iterdir()
+ if path.name != "entry_biounit_chains.parquet"
+ } == preserved
+ refreshed_biounits = pd.read_parquet(biounit_path)
+ assert refreshed_biounits["chain_num_contacting_proteins"].eq(0).all()
+ assert (
+ refreshed_biounits[
+ [
+ "chain_num_contacting_ions",
+ "chain_num_contacting_artifacts",
+ "chain_num_contacting_other_ligands",
+ ]
+ ]
+ .eq(0)
+ .all()
+ .all()
+ )
+ assert json.loads(refreshed_metrics.read_text())["status"] == "complete"
+ assert completed_interface_metrics(output_root, "8grn") == refreshed_metrics
+ assert calls == 2
+
+
+def test_ingest_one_pdb_retries_partial_outputs_without_force(
+ tmp_path: Path,
+ monkeypatch: pytest.MonkeyPatch,
+) -> None:
+ output_root = tmp_path / "output"
+ cif_root = tmp_path / "nextgen"
+ validation_root = tmp_path / "validation"
+ cif_file, _ = resolve_entry_paths(
+ "8grn",
+ cif_root=cif_root,
+ validation_root=validation_root,
+ )
+ cif_file.parent.mkdir(parents=True)
+ cif_file.touch()
+
+ raw_entry_root = output_root / "raw_entries" / "gr"
+ entry_parquet = raw_entry_root / "8grn.parquet"
+ entry_directory = raw_entry_root / "8grn"
+ stale_file = entry_directory / "stale.txt"
+ stale_file.parent.mkdir(parents=True)
+ stale_file.write_text("partial")
+ entry_parquet.write_text("partial")
+ metrics_path = output_root / "metrics" / "ingest-one-8grn.json"
+ metrics_path.parent.mkdir(parents=True)
+ metrics_path.write_text('{"status": "failed"}')
+ annotation_calls = 0
+
+ class FakeAnnotation:
+ def __init__(self, *_args, save_folder: Path, **_kwargs) -> None:
+ assert not stale_file.exists()
+ self.save_folder = save_folder
+
+ def annotate(self) -> pd.DataFrame:
+ nonlocal annotation_calls
+ annotation_calls += 1
+ ligand_dir = self.save_folder / "8grn" / "ligand_files"
+ ligand_dir.mkdir(parents=True)
+ (ligand_dir / "C.sdf").touch()
+ _write_fake_sidecars(ligand_dir.parent, "8grn")
+ return pd.DataFrame(
+ {
+ "system_id": ["8grn__1__1.A__1.C"],
+ "ligand_id": ["8grn__1.C"],
+ "system_receptor_type": ["protein"],
+ **_LIGAND_ANNOTATIONS,
+ }
+ )
+
+ def fake_save_ligand_batch(
+ *, data_dir: Path, annotation: pd.DataFrame, output_path: Path
+ ) -> None:
+ annotation[["ligand_id"]].assign(ligand_is_shape_comparable=True).to_parquet(
+ output_path, index=False
+ )
+
+ monkeypatch.setattr(ingest, "_get_annotation_class", lambda: FakeAnnotation)
+ monkeypatch.setattr(ingest, "_save_ligand_batch", fake_save_ligand_batch)
+
+ result = ingest_one_pdb(
+ pdb_id="8grn",
+ output_root=output_root,
+ cif_root=cif_root,
+ validation_root=validation_root,
+ check_references=False,
+ )
+
+ assert json.loads(result.read_text())["status"] == "complete"
+ assert annotation_calls == 1
+ assert entry_parquet.is_file()
+ assert (output_root / "ligands" / "8grn.parquet").is_file()
+ with pytest.raises(FileExistsError, match="pass --force"):
+ ingest_one_pdb(
+ pdb_id="8grn",
+ output_root=output_root,
+ cif_root=cif_root,
+ validation_root=validation_root,
+ check_references=False,
+ )
+ assert annotation_calls == 1
+
+
+def test_shared_ingest_cli_has_manifest_and_batch_commands() -> None:
+ parser = build_parser()
+
+ manifest_args = parser.parse_args(["manifest", "cif", "validation", "manifest.txt"])
+ batch_args = parser.parse_args(
+ [
+ "batch",
+ "manifest.txt",
+ "output",
+ "--batch-size",
+ "10",
+ "--cif-root",
+ "cif",
+ "--validation-root",
+ "validation",
+ ]
+ )
+
+ assert manifest_args.command == "manifest"
+ assert manifest_args.output_path == Path("manifest.txt")
+ assert batch_args.command == "batch"
+ assert batch_args.batch_size == 10
+ assert batch_args.interface_min_residues is None
+ assert batch_args.mode == "all"
+ ligand_only = parser.parse_args(
+ [
+ "batch",
+ "manifest.txt",
+ "output",
+ "--batch-size",
+ "10",
+ "--cif-root",
+ "cif",
+ "--validation-root",
+ "validation",
+ "--mode",
+ "ligands",
+ ]
+ )
+ assert ligand_only.mode == "ligands"
+ configured = parser.parse_args(
+ [
+ "batch",
+ "manifest.txt",
+ "output",
+ "--batch-size",
+ "10",
+ "--cif-root",
+ "cif",
+ "--validation-root",
+ "validation",
+ "--interface-min-residues",
+ "9",
+ "--mode",
+ "interfaces",
+ ]
+ )
+ assert configured.interface_min_residues == 9
+ assert configured.mode == "interfaces"
+
+
+def test_load_manifest_and_select_slice(tmp_path: Path) -> None:
+ manifest = tmp_path / "pdb_ids.txt"
+ manifest.write_text("# current release\n1abc\n\n2DEF\n3ghi\n")
+
+ pdb_ids = load_manifest(manifest)
+
+ assert pdb_ids == ["1abc", "2def", "3ghi"]
+ assert manifest_slice(pdb_ids, batch_index=1, batch_size=2) == ["3ghi"]
+
+
+def test_load_manifest_rejects_duplicates(tmp_path: Path) -> None:
+ manifest = tmp_path / "pdb_ids.txt"
+ manifest.write_text("1abc\n1ABC\n")
+
+ with pytest.raises(ValueError, match="duplicate PDB IDs"):
+ load_manifest(manifest)
+
+
+def test_batch_continues_after_failure_and_resumes_completed_entries(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ output_root = tmp_path / "output"
+ calls: list[str] = []
+
+ def fake_ingest_one_pdb(*, pdb_id: str, **_: object) -> Path:
+ calls.append(pdb_id)
+ if pdb_id == "2def":
+ raise ValueError("bad entry")
+ entry_path = output_root / "raw_entries" / pdb_id[1:3] / f"{pdb_id}.parquet"
+ entry_directory = entry_path.with_suffix("")
+ ligand_path = output_root / "ligands" / f"{pdb_id}.parquet"
+ metrics_path = (
+ output_root / "metrics" / pdb_id[1:3] / f"ingest-one-{pdb_id}.json"
+ )
+ for path in (entry_path, ligand_path, metrics_path):
+ path.parent.mkdir(parents=True, exist_ok=True)
+ entry_directory.mkdir()
+ pd.DataFrame(
+ {"system_receptor_type": ["protein"], **_LIGAND_ANNOTATIONS}
+ ).to_parquet(entry_path, index=False)
+ _write_fake_sidecars(entry_directory, pdb_id)
+ pd.DataFrame(
+ {
+ "ligand_id": [f"{pdb_id}__1.L"],
+ "ligand_is_shape_comparable": [True],
+ }
+ ).to_parquet(ligand_path, index=False)
+ metrics_path.write_text(
+ json.dumps(
+ {
+ "status": "complete",
+ "mode": "all",
+ "interface_annotate_prodigy": True,
+ "counts": {"annotation_rows": 1, "interface_rows": 0},
+ "outputs": {
+ "entry_parquet": str(entry_path),
+ "entry_directory": str(entry_directory),
+ "ligand_parquet": str(ligand_path),
+ },
+ }
+ )
+ )
+ return metrics_path
+
+ monkeypatch.setattr(ingest, "ingest_one_pdb", fake_ingest_one_pdb)
+
+ metrics_path, had_failures = ingest_pdb_batch(
+ pdb_ids=["1abc", "2def", "3ghi"],
+ output_root=output_root,
+ cif_root=tmp_path / "cif",
+ validation_root=tmp_path / "validation",
+ job_id="123",
+ batch_index=4,
+ )
+
+ assert had_failures
+ metrics = json.loads(metrics_path.read_text())
+ assert metrics["status"] == "completed_with_failures"
+ assert [entry["status"] for entry in metrics["entries"]] == [
+ "complete",
+ "failed",
+ "complete",
+ ]
+ assert calls == ["1abc", "2def", "3ghi"]
+
+ calls.clear()
+ _, had_failures = ingest_pdb_batch(
+ pdb_ids=["1abc", "2def", "3ghi"],
+ output_root=output_root,
+ cif_root=tmp_path / "cif",
+ validation_root=tmp_path / "validation",
+ job_id="124",
+ batch_index=4,
+ )
+
+ assert had_failures
+ assert calls == ["2def"]
+ assert completed_entry_metrics(output_root, "1abc") is not None
+ (output_root / "raw_entries/ab/1abc/entry_chains.parquet").unlink()
+ assert completed_entry_metrics(output_root, "1abc") is None
+
+
+def test_batch_resumes_entries_with_only_chain_sidecars(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ output_root = tmp_path / "output"
+ entry_dir = output_root / "raw_entries/ab/1abc"
+ entry_dir.mkdir(parents=True)
+ _write_fake_sidecars(entry_dir, "1abc")
+ entry_metrics = output_root / "metrics" / "ab" / "ingest-one-1abc.json"
+ entry_metrics.parent.mkdir(parents=True)
+ entry_metrics.write_text(
+ json.dumps(
+ {
+ "status": "complete",
+ "mode": "all",
+ "outputs": {"entry_directory": str(entry_dir)},
+ "interface_annotate_prodigy": True,
+ "counts": {"annotation_rows": 0, "interface_rows": 0},
+ "interface_min_residues": 7,
+ }
+ )
+ )
+
+ def unexpected_ingest(**_kwargs: object) -> Path:
+ pytest.fail("a completed no-system entry must not be ingested again")
+
+ monkeypatch.setattr(ingest, "ingest_one_pdb", unexpected_ingest)
+
+ metrics_path, had_failures = ingest_pdb_batch(
+ pdb_ids=["1abc"],
+ output_root=output_root,
+ cif_root=tmp_path / "cif",
+ validation_root=tmp_path / "validation",
+ )
+
+ assert not had_failures
+ metrics = json.loads(metrics_path.read_text())
+ assert metrics["entries"][0]["status"] == "skipped_complete"
+ assert (
+ completed_entry_metrics(
+ output_root,
+ "1abc",
+ expected_interface_min_residues=9,
+ )
+ is None
+ )
+
+
+def test_completed_entry_metrics_invalidates_interface_cutoff_changes(
+ tmp_path: Path,
+) -> None:
+ output_root = tmp_path / "output"
+ entry_path = output_root / "raw_entries/ab/1abc.parquet"
+ entry_directory = entry_path.with_suffix("")
+ ligand_path = output_root / "ligands/1abc.parquet"
+ metrics_path = output_root / "metrics/ab/ingest-one-1abc.json"
+ entry_directory.mkdir(parents=True)
+ ligand_path.parent.mkdir(parents=True)
+ metrics_path.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {"system_receptor_type": ["protein"], **_LIGAND_ANNOTATIONS}
+ ).to_parquet(entry_path, index=False)
+ _write_fake_sidecars(entry_directory, "1abc")
+ pd.DataFrame(
+ {
+ "ligand_id": ["1abc__1.L"],
+ "ligand_is_shape_comparable": [True],
+ }
+ ).to_parquet(ligand_path, index=False)
+ metrics_path.write_text(
+ json.dumps(
+ {
+ "status": "complete",
+ "mode": "all",
+ "interface_annotate_prodigy": True,
+ "counts": {"annotation_rows": 1, "interface_rows": 0},
+ "outputs": {"entry_directory": str(entry_directory)},
+ }
+ )
+ )
+
+ assert (
+ completed_entry_metrics(
+ output_root,
+ "1abc",
+ expected_interface_min_residues=7,
+ )
+ == metrics_path
+ )
+
+ biounit_path = entry_directory / "entry_biounit_chains.parquet"
+ biounits = pd.read_parquet(biounit_path)
+ biounits.loc[0, "chain_num_contacting_ions"] = None
+ biounits.to_parquet(biounit_path, index=False)
+ assert completed_entry_metrics(output_root, "1abc") is None
+ _write_fake_sidecars(entry_directory, "1abc")
+
+ biounits = pd.read_parquet(biounit_path)
+ biounits.loc[0, "chain_num_contacting_proteins"] = None
+ biounits.to_parquet(biounit_path, index=False)
+ assert completed_entry_metrics(output_root, "1abc") is None
+ _write_fake_sidecars(entry_directory, "1abc")
+
+ assert (
+ completed_entry_metrics(
+ output_root,
+ "1abc",
+ expected_interface_min_residues=9,
+ )
+ is None
+ )
+
+ interface_path = entry_directory / "interfaces.parquet"
+ interface_table = pq.read_table(interface_path)
+ pq.write_table(interface_table.replace_schema_metadata(None), interface_path)
+ assert completed_entry_metrics(output_root, "1abc") is None
+
+
+@pytest.mark.parametrize("mode", ["all", "ligands", "interfaces"])
+@pytest.mark.parametrize("empty", [False, True])
+@pytest.mark.parametrize(
+ ("filename", "missing_column"),
+ [
+ ("entry_chains.parquet", "chain_sequence_noncanonical"),
+ ("entry_chains.parquet", "chain_modified_residues"),
+ ("entry_metadata.parquet", "entry_pH_min"),
+ ("entry_metadata.parquet", "entry_pH_max"),
+ ("entry_metadata.parquet", "entry_has_ligand_of_interest"),
+ ],
+)
+def test_resume_requires_shared_annotations(
+ tmp_path: Path, mode: str, empty: bool, filename: str, missing_column: str
+) -> None:
+ entry_dir = tmp_path / "raw_entries/ab/1abc"
+ entry_dir.mkdir(parents=True)
+ _write_fake_sidecars(entry_dir, "1abc")
+ table_path = entry_dir / filename
+ frame = pd.read_parquet(table_path)
+ if empty:
+ frame = frame.iloc[:0]
+ frame.to_parquet(table_path, index=False)
+ if mode == "interfaces":
+ marker = ingest.interface_metrics_path(tmp_path, "1abc")
+ status = "complete"
+ else:
+ marker = ingest.entry_metrics_path(tmp_path, "1abc")
+ status = "skipped_no_ligands" if mode == "ligands" else "complete"
+ marker.parent.mkdir(parents=True, exist_ok=True)
+ marker.write_text(
+ json.dumps(
+ {
+ "status": status,
+ "mode": mode,
+ "interface_min_residues": 7,
+ "counts": {
+ "annotation_rows": 0,
+ "interface_rows": 0,
+ "entry_chain_rows": 0 if empty else 1,
+ },
+ "outputs": {"entry_directory": str(entry_dir)},
+ }
+ )
+ )
+
+ def completed():
+ if mode == "interfaces":
+ return completed_interface_metrics(tmp_path, "1abc")
+ return completed_entry_metrics(tmp_path, "1abc", expected_ingest_mode=mode)
+
+ assert completed() == marker
+ frame.drop(columns=missing_column).to_parquet(table_path, index=False)
+ assert completed() is None
+ frame.to_parquet(table_path, index=False)
+ assert completed() == marker
+
+
+def test_interface_resume_requires_protein_contact_counts(tmp_path: Path) -> None:
+ entry_dir = tmp_path / "raw_entries/ab/1abc"
+ entry_dir.mkdir(parents=True)
+ _write_fake_sidecars(entry_dir, "1abc")
+ marker = ingest.interface_metrics_path(tmp_path, "1abc")
+ marker.parent.mkdir(parents=True)
+ marker.write_text(
+ json.dumps(
+ {
+ "status": "complete",
+ "mode": "interfaces",
+ "interface_min_residues": 7,
+ "counts": {"interface_rows": 0},
+ "outputs": {"entry_directory": str(entry_dir)},
+ }
+ )
+ )
+ biounit_path = entry_dir / "entry_biounit_chains.parquet"
+
+ assert completed_interface_metrics(tmp_path, "1abc") == marker
+ biounits = pd.read_parquet(biounit_path)
+ biounits.drop(columns="chain_num_contacting_proteins").to_parquet(
+ biounit_path, index=False
+ )
+ assert completed_interface_metrics(tmp_path, "1abc") is None
+ biounits["chain_num_contacting_proteins"] = None
+ biounits.to_parquet(biounit_path, index=False)
+ assert completed_interface_metrics(tmp_path, "1abc") is None
+
+
+@pytest.mark.parametrize("mode", ["all", "ligands"])
+@pytest.mark.parametrize("missing_column", list(_LIGAND_ANNOTATIONS))
+def test_resume_requires_ligand_annotations(
+ tmp_path: Path, mode: str, missing_column: str
+) -> None:
+ entry_path = tmp_path / "raw_entries/ab/1abc.parquet"
+ entry_dir = entry_path.with_suffix("")
+ entry_dir.mkdir(parents=True)
+ _write_fake_sidecars(entry_dir, "1abc")
+ annotation = pd.DataFrame(
+ {"system_receptor_type": ["protein"], **_LIGAND_ANNOTATIONS}
+ )
+ annotation.to_parquet(entry_path, index=False)
+ ligand_path = tmp_path / "ligands/1abc.parquet"
+ ligand_path.parent.mkdir()
+ pd.DataFrame(
+ {"ligand_id": ["1abc__1.L"], "ligand_is_shape_comparable": [True]}
+ ).to_parquet(ligand_path, index=False)
+ marker = ingest.entry_metrics_path(tmp_path, "1abc")
+ marker.parent.mkdir(parents=True)
+ marker.write_text(
+ json.dumps(
+ {
+ "status": "complete",
+ "mode": mode,
+ "counts": {"annotation_rows": 1, "interface_rows": 0},
+ "outputs": {"entry_directory": str(entry_dir)},
+ }
+ )
+ )
+ assert (
+ completed_entry_metrics(tmp_path, "1abc", expected_ingest_mode=mode) == marker
+ )
+ annotation.drop(columns=missing_column).to_parquet(entry_path, index=False)
+ assert completed_entry_metrics(tmp_path, "1abc", expected_ingest_mode=mode) is None
+ annotation.to_parquet(entry_path, index=False)
+ assert (
+ completed_entry_metrics(tmp_path, "1abc", expected_ingest_mode=mode) == marker
+ )
+
+
+def test_ligand_skip_requires_chain_extraction(tmp_path: Path) -> None:
+ entry_dir = tmp_path / "raw_entries/ab/1abc"
+ entry_dir.mkdir(parents=True)
+ _write_fake_sidecars(entry_dir, "1abc")
+ marker = ingest.entry_metrics_path(tmp_path, "1abc")
+ marker.parent.mkdir(parents=True)
+ payload = {
+ "status": "skipped_no_ligands",
+ "mode": "ligands",
+ "outputs": {"entry_directory": str(entry_dir)},
+ }
+ marker.write_text(json.dumps(payload))
+ assert completed_entry_metrics(tmp_path, "1abc") is None
+ payload["counts"] = {"entry_chain_rows": 1}
+ marker.write_text(json.dumps(payload))
+ assert completed_entry_metrics(tmp_path, "1abc") == marker
+
+
+def test_ligand_skip_requires_recorded_biounit_contacts(tmp_path: Path) -> None:
+ output_root = tmp_path / "output"
+ entry_directory = output_root / "raw_entries/ab/1abc"
+ entry_directory.mkdir(parents=True)
+ _write_fake_sidecars(entry_directory, "1abc")
+ biounit_path = entry_directory / "entry_biounit_chains.parquet"
+ contact_columns = [
+ "chain_num_contacting_ions",
+ "chain_num_contacting_artifacts",
+ "chain_num_contacting_other_ligands",
+ ]
+ pd.read_parquet(biounit_path).drop(columns=contact_columns).to_parquet(
+ biounit_path, index=False
+ )
+ metrics_path = output_root / "metrics/ab/ingest-one-1abc.json"
+ metrics_path.parent.mkdir(parents=True)
+ metrics_path.write_text(
+ json.dumps(
+ {
+ "status": "skipped_no_ligands",
+ "mode": "ligands",
+ "counts": {"entry_chain_rows": 1},
+ "outputs": {"entry_directory": str(entry_directory)},
+ }
+ )
+ )
+
+ assert (
+ completed_entry_metrics(
+ output_root,
+ "1abc",
+ expected_ingest_mode="ligands",
+ )
+ is None
+ )
+
+ _write_fake_sidecars(entry_directory, "1abc")
+ biounits = pd.read_parquet(biounit_path)
+ biounits.loc[0, "chain_num_contacting_other_ligands"] = None
+ biounits.to_parquet(biounit_path, index=False)
+ assert (
+ completed_entry_metrics(
+ output_root,
+ "1abc",
+ expected_ingest_mode="ligands",
+ )
+ is None
+ )
+
+ _write_fake_sidecars(entry_directory, "1abc")
+ assert (
+ completed_entry_metrics(
+ output_root,
+ "1abc",
+ expected_ingest_mode="ligands",
+ )
+ == metrics_path
+ )
+
+ assert completed_entry_metrics(output_root, "1abc") == metrics_path
+ assert (
+ completed_entry_metrics(output_root, "1abc", expected_ingest_mode="all") is None
+ )
+
+ pd.DataFrame(
+ columns=[
+ "entry_pdb_id",
+ "biounit_id",
+ "chain_instance",
+ "chain_asym_id",
+ "chain_role",
+ *contact_columns,
+ ]
+ ).to_parquet(biounit_path, index=False)
+ assert (
+ completed_entry_metrics(
+ output_root,
+ "1abc",
+ expected_ingest_mode="ligands",
+ )
+ == metrics_path
+ )
+
+
+def test_discover_entries_tracks_optional_validation(tmp_path: Path) -> None:
+ cif_root = tmp_path / "cif"
+ validation_root = tmp_path / "validation"
+ for pdb_id, content in (("1abc", b"one"), ("2def", b"second")):
+ cif_path = (
+ cif_root
+ / pdb_id[1:3]
+ / f"pdb_0000{pdb_id}"
+ / f"pdb_0000{pdb_id}_xyz-enrich.cif.gz"
+ )
+ cif_path.parent.mkdir(parents=True)
+ cif_path.write_bytes(content)
+ validation_path = validation_root / "ab" / "1abc" / "1abc_validation.xml.gz"
+ validation_path.parent.mkdir(parents=True)
+ validation_path.touch()
+
+ entries = discover_entries(cif_root, validation_root)
+
+ assert entries == [
+ EntryInput("1abc", 3, True),
+ EntryInput("2def", 6, False),
+ ]
+
+ unchecked = discover_entries(
+ cif_root,
+ validation_root,
+ check_validation=False,
+ )
+ assert [entry.validation_exists for entry in unchecked] == [None, None]
+
+
+def test_balanced_manifest_has_fixed_slices_and_summary(tmp_path: Path) -> None:
+ entries = [
+ EntryInput(f"{index}abc", size, True)
+ for index, size in enumerate((100, 90, 80, 20, 10), start=1)
+ ]
+
+ batches = balance_entries(entries, batch_size=2)
+
+ assert [len(batch) for batch in batches] == [2, 2, 1]
+ totals = [sum(entry.cif_size for entry in batch) for batch in batches]
+
+ manifest = tmp_path / "pdb_ids.txt"
+ summary = write_manifest(
+ entries=entries,
+ output_path=manifest,
+ batch_size=2,
+ )
+ assert len(manifest.read_text().splitlines()) == len(entries)
+ assert summary["batch_count"] == 3
+ assert summary["maximum_batch_cif_bytes"] == max(totals)
+ assert summary["cif_size_percentiles"]["maximum"] == 100
+ assert summary["largest_entries"][0]["cif_size"] == 100
+ assert manifest.with_suffix(".txt.json").is_file()
+ inventory = manifest.with_suffix(".txt.entries.tsv")
+ assert inventory.is_file()
+ assert inventory.read_text().splitlines()[0] == (
+ "pdb_id\tcif_size\tvalidation_exists"
+ )
+
+ manifest_ids = manifest.read_text().splitlines()
+ assert [manifest_ids[index : index + 2] for index in range(0, len(entries), 2)] == [
+ [entry.pdb_id for entry in batch] for batch in batches
+ ]
+
+
+def test_balance_entries_distributes_large_inputs_across_full_batches() -> None:
+ entries = [
+ EntryInput(f"{index}abc", size, True)
+ for index, size in enumerate((100, 90, 80, 20, 10, 5), start=1)
+ ]
+
+ batches = balance_entries(entries, batch_size=2)
+ totals = [sum(entry.cif_size for entry in batch) for batch in batches]
+
+ assert [len(batch) for batch in batches] == [2, 2, 2]
+ assert max(totals) - min(totals) <= 15
diff --git a/tests/data/pipeline/test_io.py b/tests/data/pipeline/test_io.py
index 49ee5e12a..e3022c5bc 100644
--- a/tests/data/pipeline/test_io.py
+++ b/tests/data/pipeline/test_io.py
@@ -1,7 +1,7 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
-import pandas as pd
import pytest
+
from plinder.core.utils import io as core_io
from plinder.data.pipeline import io
@@ -55,59 +55,6 @@ def test_download_cofactors_cached(tmp_path):
assert "test" in obj
-def test_download_ecod_data_fetch(tmp_path, raw_ecod_data, monkeypatch):
- monkeypatch.setattr(
- "plinder.data.pipeline.io.requests.get", lambda _: _resp(text=raw_ecod_data)
- )
- ecod_path = io.download_ecod_data(data_dir=tmp_path)
- assert len(pd.read_parquet(ecod_path).index)
-
-
-def test_download_ecod_data_cached(test_env, raw_ecod_path):
- ecod_path = io.download_ecod_data(data_dir=test_env)
- assert len(pd.read_parquet(ecod_path).index)
-
-
-def test_ecod(test_env, raw_ecod_path):
- ecod_path = io.download_ecod_data(data_dir=test_env)
- df = pd.read_parquet(ecod_path)
- reference = "acid protease"
- assert (
- df.loc[df["domainid"] == "e1udzA1", "domain"].values[0].strip()
- == reference.strip()
- )
- assert (
- df.loc[(df["pdb"] == "1udz") & (df["chain"] == "A"), "domain"].values[0]
- == reference.strip()
- )
-
-
-def test_download_panther_data_fetch(tmp_path, monkeypatch, raw_panther_data):
- monkeypatch.setattr(
- "plinder.data.pipeline.io.requests.get",
- lambda _: _resp(content=raw_panther_data),
- )
- panther_path = io.download_panther_data(data_dir=tmp_path)
- assert panther_path.is_file()
- assert len(pd.read_parquet(panther_path).index)
-
-
-def test_download_panther_data_cached(test_env, raw_panther_path):
- panther_path = io.download_panther_data(data_dir=test_env)
- assert len(pd.read_parquet(panther_path).index)
-
-
-def test_panther(test_env, raw_panther_path):
- panther_path = io.download_panther_data(data_dir=test_env)
- df = pd.read_parquet(panther_path)
- reference = "E5R0L8"
- assert df.loc[df["uniprotac"] == reference, "panther"].values[0] == "NOHIT"
- assert (
- df.loc[df["uniprotac"] == reference, "panther_class"].values[0]
- == "Arthroderma_gypseum_ARTGP"
- )
-
-
def test_download_seqres_data_fetch(tmp_path, monkeypatch):
monkeypatch.setattr(
"plinder.data.pipeline.io.requests.get", lambda _: _resp(content=b"foo")
@@ -125,66 +72,6 @@ def test_download_seqres_data_cached(tmp_path):
assert raw_seqres_path.read_text() == "foo"
-def test_download_kinase_data_fetch(tmp_path, monkeypatch):
- resp = _resp(
- body=[
- [
- {
- "name": "foo",
- "HGNC": "foo",
- "family": "foo",
- "group": "foo",
- "kinase_class": "foo",
- "full_name": "foo",
- "uniprot": "foo",
- "kinase_ID": "2",
- }
- ],
- [{"kinase_ID": "2"}],
- [
- {
- "pdb": "foob",
- "chain": "A",
- "structure_ID": "1",
- "kinase_ID": "2",
- "missing_atoms": "5",
- "missing_residues": "6",
- "rmsd1": "1.00",
- "rmsd2": "2.00",
- "resolution": "3.0",
- "quality_score": "9.2",
- "Grich_distance": "1.0",
- "Grich_rotation": "5.6",
- "Grich_angle": "23.4",
- }
- ],
- ]
- )
- monkeypatch.setattr("plinder.data.pipeline.io.requests.get", lambda *_, **__: resp)
- kinase_path = io.download_kinase_data(data_dir=tmp_path)
- assert kinase_path.is_file()
-
-
-def test_kinase(test_env, all_kinase_paths):
- kinase_path = io.download_kinase_data(data_dir=test_env)
- df = pd.read_parquet(kinase_path)
- assert df.loc[df["pdbid_chainid"] == "3mvh_A", "kinase"].values[0] == "AKT1"
- assert df.loc[df["pdbid_chainid"] == "3mvh_A", "uniprot"].values[0] == "P31749"
-
-
-def test_kinase_ligand(test_env, all_kinase_paths):
- kinase_path = io.download_kinase_data(data_dir=test_env)
- df = pd.read_parquet(kinase_path.parent / "kinase_ligand_ccd_codes.parquet")
- assert (
- df.loc[df["PDB-code"] == "IHZ", "SMILES"].values[0]
- == "FC(F)(F)c1cc(NC(=O)c2cc(Nc3cncc(c3)C(=O)N)c(cc2)C)ccc1"
- )
- assert (
- df.loc[df["PDB-code"] == "IHZ", "InChIKey"].values[0]
- == "SAAYRHKJHDIDPH-UHFFFAOYSA-N"
- )
-
-
@pytest.mark.parametrize(
"kind, server, port",
[
@@ -220,38 +107,15 @@ def list_directories(command, **kwargs):
assert f"--port={port}" in commands[0]
-def test_downloads_components_cif_fetch(tmp_path, monkeypatch, mini_component_cif_gz):
- monkeypatch.setattr(
- "plinder.data.pipeline.io.requests.get",
- lambda _: _resp(content=mini_component_cif_gz.read_bytes()),
- )
- components_path = io.download_components_cif(data_dir=tmp_path)
- assert components_path.is_file()
- assert (components_path.parent / "components.parquet").is_file()
- assert len(pd.read_parquet(components_path.parent / "components.parquet").index)
-
-
-def test_download_components_cif_cached(
- tmp_path, mini_component_cif, mini_components_pqt
-):
- components_path = tmp_path / "dbs" / "components" / "components.cif"
- components_pqt = tmp_path / "dbs" / "components" / "components.parquet"
- components_path.parent.mkdir(parents=True)
- components_path.write_bytes(mini_component_cif.read_bytes())
- components_pqt.write_bytes(mini_components_pqt.read_bytes())
- components_path = io.download_components_cif(data_dir=tmp_path)
- assert components_path.is_file()
- assert components_pqt.is_file()
- assert len(pd.read_parquet(components_path.parent / "components.parquet").index)
-
-
-def test_ccd(test_env, mock_alternative_datasets):
- mock_alternative_datasets("test")
- reference = "C[C@H]1[C@H]([C@H]([C@@H]([C@@H](O1)OC)O)O)O"
- path = io.download_components_cif(data_dir=test_env)
- df = pd.read_parquet(path.parent / "components.parquet")
- canonical_smile = df[df["binder_id"] == "MFU"].squeeze()["canonical_smiles"]
- assert canonical_smile == reference
+def test_refresh_bundled_ccd_fails_loudly(monkeypatch):
+ # bt_info is the sole CCD source; a failed sync must NOT be swallowed (else the
+ # pipeline would silently ship a stale bundle), so setup_ccd errors propagate.
+ def boom() -> None:
+ raise RuntimeError("read-only site-packages")
+
+ monkeypatch.setattr("biotite.setup_ccd.main", boom)
+ with pytest.raises(RuntimeError):
+ io.refresh_bundled_ccd(data_dir=None)
def test_download_uniprot_fasta_data_fetch(tmp_path, monkeypatch):
diff --git a/tests/data/pipeline/test_pipeline.py b/tests/data/pipeline/test_pipeline.py
index 71c82e8c4..bd0619e81 100644
--- a/tests/data/pipeline/test_pipeline.py
+++ b/tests/data/pipeline/test_pipeline.py
@@ -1,7 +1,12 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
-from plinder.data.pipeline import pipeline
+from pathlib import Path
+
+import pandas as pd
+import pytest
+
+from plinder.data.pipeline import config, pipeline
def test_pipeline_noop(tmp_path):
@@ -17,3 +22,98 @@ def test_pipeline_noop(tmp_path):
config_file=conf.as_posix(), config_args=[], cached=False
)
pipe.run()
+
+
+def test_pipeline_clusters_whole_and_half_interfaces():
+ cfg = config.get_config(cached=False)
+ pipe = pipeline.IngestPipeline(conf=cfg)
+
+ assert ("interface", ["interface_qcov", "interface_side_qcov"]) in (
+ pipe._cluster_entities()
+ )
+
+
+def test_make_dbs_creates_the_requested_protein_search_plans(
+ tmp_path, monkeypatch
+) -> None:
+ from plinder.data.pipeline import score, tasks
+
+ cfg = config.get_config(cached=False)
+ cfg.scorer.sub_databases = ["holo", "apo"]
+ pipe = pipeline.IngestPipeline(conf=cfg)
+ pipe.plinder_dir = tmp_path
+ calls = []
+ monkeypatch.setattr(
+ pipe,
+ "_entry_source_roots",
+ lambda: (tmp_path / "cif", tmp_path / "validation"),
+ )
+ monkeypatch.setattr(
+ score,
+ "plan_protein_scoring",
+ lambda *_args, **_kwargs: calls.append("holo"),
+ )
+ monkeypatch.setattr(
+ score,
+ "plan_linked_apo_scoring",
+ lambda *_args, **_kwargs: calls.append("apo"),
+ )
+ monkeypatch.setattr(
+ score,
+ "make_foldseek_input_manifest",
+ lambda _data_dir, cif_root: cif_root,
+ )
+ monkeypatch.setattr(tasks, "make_dbs", lambda **_kwargs: None)
+
+ pipeline.IngestPipeline.make_dbs.__wrapped__(pipe)
+
+ assert calls == ["holo", "apo"]
+
+
+@pytest.mark.parametrize("mode", ["enabled", "metric_removed", "stage_skipped"])
+def test_segmented_ligand_ingest_runs_mhfp6_unless_disabled(tmp_path, mode):
+ from plinder.data.annotations import get_similarity_scores as scoring
+
+ config_path = (
+ Path(__file__).resolve().parents[3]
+ / "scripts/slurm/configs/ingest/make_entries_ligands.yaml"
+ )
+ if not config_path.is_file():
+ pytest.skip("ingest configs are not installed in wheel-only test layouts")
+ pipe = pipeline.IngestPipeline(config_file=str(config_path), cached=False)
+ pipe.plinder_dir = tmp_path
+ if mode == "metric_removed":
+ pipe.cfg.flow.cluster_metrics = [
+ metric
+ for metric in pipe.cfg.flow.cluster_metrics
+ if metric != scoring.MHFP6_METRIC
+ ]
+ elif mode == "stage_skipped":
+ pipe.cfg.flow.skip_specific_stages = ["make_mhfp6_scores"]
+ else:
+ fingerprints = tmp_path / "fingerprints"
+ fingerprints.mkdir()
+ scoring.write_mhfp6_fingerprints(
+ pd.DataFrame(
+ {
+ "ligand_smiles_id": [0, 1],
+ "ligand_rdkit_canonical_smiles": ["CCO", "c1ccccc1"],
+ }
+ ),
+ fingerprints,
+ )
+
+ chunks = pipe.scatter_make_mhfp6_scores()
+ for chunk in chunks:
+ pipe.make_mhfp6_scores(chunk)
+ outputs = list((tmp_path / scoring.MHFP6_SCORES_DIR).glob("*.parquet"))
+ if mode != "enabled":
+ assert chunks == [[]]
+ assert outputs == []
+ return
+ assert chunks == [[0, 1]]
+ assert len(outputs) == 1
+ scores = pd.read_parquet(outputs[0])
+ self_scores = scores[scores["query_ligand_id"] == scores["target_ligand_id"]]
+ assert set(self_scores["query_ligand_id"]) == {0, 1}
+ assert self_scores[scoring.MHFP6_METRIC].tolist() == [100.0, 100.0]
diff --git a/tests/data/pipeline/test_public_release.py b/tests/data/pipeline/test_public_release.py
new file mode 100644
index 000000000..e44080f7d
--- /dev/null
+++ b/tests/data/pipeline/test_public_release.py
@@ -0,0 +1,145 @@
+from pathlib import Path
+
+import pytest
+
+from plinder.core.release import RELEASE_PATHS
+from plinder.data.pipeline.public_release import (
+ _FILE_ARTIFACTS,
+ _PARQUET_DIRECTORIES,
+ _SAMPLING_DIRECTORIES,
+ _SEARCH_DATABASES,
+ prepare_public_release,
+)
+
+
+def _working_release(root: Path) -> None:
+ for name in _FILE_ARTIFACTS:
+ path = root / RELEASE_PATHS[name]
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_bytes(b"table")
+ for name in _PARQUET_DIRECTORIES:
+ path = root / RELEASE_PATHS.get(name, name) / "part.parquet"
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_bytes(b"scores")
+ (path.parent / "local.json").write_text("/scicore/private/path")
+ for name in _SAMPLING_DIRECTORIES:
+ directory = root / RELEASE_PATHS.get(name, name)
+ cover = directory / "directed_set_cover/metric=pocket_qcov/threshold=50.parquet"
+ cover.parent.mkdir(parents=True, exist_ok=True)
+ cover.write_bytes(b"cover")
+ cache = directory / "directed_set_cover/reductions/part.parquet"
+ cache.parent.mkdir(parents=True, exist_ok=True)
+ cache.write_bytes(b"cache")
+ for name in _SEARCH_DATABASES:
+ folder = root / "search_databases" / name
+ folder.mkdir(parents=True)
+ (folder / "db").write_bytes(b"database")
+ (folder / "alias").symlink_to("db")
+ (folder / "local.json").write_text("/scicore/private/path")
+ (root / "search_databases" / "holo_steam").mkdir()
+ (root / "search_databases" / "holo_steam" / "db").write_bytes(b"tea")
+ (root / "scores").mkdir()
+ (root / "scores" / "temporary.parquet").write_bytes(b"work")
+
+
+def test_public_release_contains_only_reader_artifacts(tmp_path: Path) -> None:
+ working = tmp_path / "working"
+ public = tmp_path / "public"
+ _working_release(working)
+
+ count = prepare_public_release(working, public)
+
+ assert count > len(_FILE_ARTIFACTS)
+ assert (public / RELEASE_PATHS["annotation_table"]).read_bytes() == b"table"
+ assert (public / "search_databases/holo_foldseek/alias").read_bytes() == b"database"
+ assert (public / "search_databases/holo_foldseek/alias").is_symlink()
+ assert (public / "search_databases/holo_foldseek/db").stat().st_ino == (
+ working / "search_databases/holo_foldseek/db"
+ ).stat().st_ino
+ assert not list(public.rglob("*.json"))
+ assert not (public / "search_databases/holo_steam").exists()
+ assert not (public / "scores").exists()
+ for name in _SAMPLING_DIRECTORIES:
+ directory = public / RELEASE_PATHS.get(name, name)
+ assert (
+ directory / "directed_set_cover/metric=pocket_qcov/threshold=50.parquet"
+ ).read_bytes() == b"cover"
+ assert not (directory / "directed_set_cover/reductions").exists()
+
+
+def test_public_release_allows_an_empty_monomer_universe(tmp_path: Path) -> None:
+ working = tmp_path / "working"
+ _working_release(working)
+ for name in ("monomer_mmseqs", "monomer_foldseek"):
+ for path in sorted((working / "search_databases" / name).iterdir()):
+ path.unlink()
+ (working / "search_databases" / name).rmdir()
+ monomer_scores = working / RELEASE_PATHS["monomer_similarity_scores"]
+ for path in monomer_scores.iterdir():
+ path.unlink()
+ monomer_scores.rmdir()
+
+ prepare_public_release(working, tmp_path / "public")
+
+ assert (tmp_path / "public/search_databases/holo_mmseqs/db").is_file()
+ assert not (tmp_path / "public/search_databases/monomer_mmseqs").exists()
+
+
+def test_public_release_replacement_drops_old_files(tmp_path: Path) -> None:
+ working = tmp_path / "working"
+ public = tmp_path / "public"
+ _working_release(working)
+ prepare_public_release(working, public)
+ (public / "stale.parquet").write_bytes(b"old")
+
+ with pytest.raises(FileExistsError):
+ prepare_public_release(working, public)
+ prepare_public_release(working, public, replace=True, copy=True)
+
+ assert not (public / "stale.parquet").exists()
+ assert (public / "search_databases/holo_foldseek/db").stat().st_ino != (
+ working / "search_databases/holo_foldseek/db"
+ ).stat().st_ino
+
+
+def test_missing_public_file_does_not_replace_release(tmp_path: Path) -> None:
+ working = tmp_path / "working"
+ public = tmp_path / "public"
+ _working_release(working)
+ prepare_public_release(working, public)
+ (working / RELEASE_PATHS["annotation_table"]).unlink()
+
+ with pytest.raises(FileNotFoundError, match="annotation_table.parquet"):
+ prepare_public_release(working, public, replace=True)
+
+ assert (public / RELEASE_PATHS["annotation_table"]).is_file()
+
+
+def test_public_release_rejects_external_database_links(tmp_path: Path) -> None:
+ working = tmp_path / "working"
+ public = tmp_path / "public"
+ _working_release(working)
+ alias = working / "search_databases/holo_foldseek/alias"
+ alias.unlink()
+ alias.symlink_to("../../scores/temporary.parquet")
+
+ with pytest.raises(ValueError, match="link leaves the public release"):
+ prepare_public_release(working, public)
+
+ assert not public.exists()
+
+
+def test_public_release_rejects_absolute_internal_database_links(
+ tmp_path: Path,
+) -> None:
+ working = tmp_path / "working"
+ public = tmp_path / "public"
+ _working_release(working)
+ alias = working / "search_databases/holo_foldseek/alias"
+ alias.unlink()
+ alias.symlink_to(working / "search_databases/holo_foldseek/db")
+
+ with pytest.raises(ValueError, match="absolute link"):
+ prepare_public_release(working, public, copy=True)
+
+ assert not public.exists()
diff --git a/tests/data/pipeline/test_scoring_inputs.py b/tests/data/pipeline/test_scoring_inputs.py
new file mode 100644
index 000000000..258879e1e
--- /dev/null
+++ b/tests/data/pipeline/test_scoring_inputs.py
@@ -0,0 +1,182 @@
+import json
+import sys
+from shutil import copytree
+
+import pyarrow as pa
+import pyarrow.parquet as pq
+import pytest
+
+from plinder.core.utils.files import file_sha256
+from plinder.data.annotations.interface_utils import INTERFACE_ANNOTATION_SCHEMA
+from plinder.data.pipeline import collate, score, tasks
+
+
+def _write_inputs(root, *, revised=False, ligands=True, interfaces=True):
+ index = root / "index"
+ index.mkdir(parents=True, exist_ok=True)
+ schema = pa.schema(
+ [
+ ("entry_pdb_id", pa.string()),
+ ("system_id", pa.string()),
+ ("system_type", pa.string()),
+ ("ligand_id", pa.string()),
+ ("ligand_asym_id", pa.string()),
+ ("ligand_is_proper", pa.bool_()),
+ ("ligand_is_shape_comparable", pa.bool_()),
+ ("ligand_protein_chains_asym_id", pa.list_(pa.string())),
+ ("ligand_neighboring_residues", pa.list_(pa.string())),
+ ("ligand_interacting_residues", pa.list_(pa.string())),
+ ("ligand_interactions", pa.list_(pa.string())),
+ ]
+ )
+ asym, residue = ("M", 20) if revised else ("L", 10)
+ pocket = f"1.A_{residue}_{residue - 1}_{residue + 100}"
+ rows = (
+ [
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": f"1abc__1__1.A__1.{asym}",
+ "system_type": "holo",
+ "ligand_id": f"1abc__1__1.{asym}",
+ "ligand_asym_id": asym,
+ "ligand_is_proper": True,
+ "ligand_is_shape_comparable": True,
+ "ligand_protein_chains_asym_id": ["1.A"],
+ "ligand_neighboring_residues": [pocket],
+ "ligand_interacting_residues": [pocket],
+ "ligand_interactions": [f"1.A_{residue}_hydrogen_bonds"],
+ }
+ ]
+ if ligands
+ else []
+ )
+ pq.write_table(
+ pa.Table.from_pylist(rows, schema=schema), index / "annotation_table.parquet"
+ )
+ other = "3ghi" if revised else "2def"
+ pq.write_table(
+ pa.table(
+ {
+ "entry_pdb_id": ["1abc", other, other],
+ "chain_asym_id": ["A", "A", "B"],
+ "chain_auth_id": ["X", "Y", "Z"],
+ "chain_receptor_type": ["protein"] * 3,
+ }
+ ),
+ index / "entry_chains.parquet",
+ )
+ rows = (
+ [
+ {
+ "entry_pdb_id": other,
+ "system_id": f"{other}__1__1.A--1.B",
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.A",
+ "interface_chain_2": "1.B",
+ "interface_chain_1_residue_numbers": [30],
+ "interface_chain_1_residue_indices": [29],
+ "interface_chain_2_residue_numbers": [40],
+ "interface_chain_2_residue_indices": [39],
+ "interface_num_contact_residue_pairs": 1,
+ }
+ ]
+ if interfaces
+ else []
+ )
+ pq.write_table(
+ pa.Table.from_pylist(rows, schema=INTERFACE_ANNOTATION_SCHEMA),
+ index / "interface_annotation_table.parquet",
+ )
+
+
+@pytest.mark.parametrize(
+ "ligands,interfaces", [(True, True), (False, True), (True, False), (False, False)]
+)
+def test_prepare_scoring_inputs_refreshes_and_resumes(
+ tmp_path, monkeypatch, capsys, ligands, interfaces
+):
+ workspace = tmp_path / "updated"
+ _write_inputs(workspace)
+ marker = workspace / "index/collation.json"
+ marker.write_text(json.dumps({"status": collate.REPAIR_REQUIRED_STATUS}))
+ monkeypatch.setattr(
+ sys,
+ "argv",
+ [
+ "score",
+ "prepare-scoring-inputs",
+ str(workspace),
+ "--threads",
+ "2",
+ "--memory-limit",
+ "1GB",
+ ],
+ )
+ configurations = []
+ configure = collate._configure_duckdb
+
+ def record_configuration(connection, **kwargs):
+ configure(connection, **kwargs)
+ configurations.append(kwargs)
+
+ monkeypatch.setattr(collate, "_configure_duckdb", record_configuration)
+ score.main()
+ assert len(configurations) == 3
+ assert all(c["threads"] == 2 and c["memory_limit"] == "1GB" for c in configurations)
+ assert json.loads(capsys.readouterr().out)["status"] == "complete"
+
+ # Replace a ligand, remove an entry and add an interface-only entry.
+ _write_inputs(workspace, revised=True, ligands=ligands, interfaces=interfaces)
+ fresh = tmp_path / "fresh"
+ copytree(workspace / "index", fresh / "index")
+ for path in (fresh / "index").glob("*.parquet"):
+ if path.name not in {
+ "annotation_table.parquet",
+ "entry_chains.parquet",
+ "interface_annotation_table.parquet",
+ }:
+ path.unlink()
+ inputs = [
+ workspace / "index" / name
+ for name in (
+ "annotation_table.parquet",
+ "entry_chains.parquet",
+ "interface_annotation_table.parquet",
+ "collation.json",
+ )
+ ]
+ before = {p: file_sha256(p) for p in inputs}
+ score.main()
+ tasks.make_alignment_chain_lookup(
+ data_dir=fresh,
+ scratch_dir=None,
+ threads=1,
+ memory_limit="1GB",
+ force_update=True,
+ )
+ outputs = [
+ tasks.ALIGNMENT_CHAIN_LOOKUP_RELATIVE,
+ tasks.LIGAND_POCKET_REPRESENTATIVES_RELATIVE,
+ tasks.LIGAND_POCKET_MEMBERSHIP_RELATIVE,
+ tasks.LIGAND_POCKET_RESIDUES_RELATIVE,
+ tasks.INTERFACE_REPRESENTATIVES_RELATIVE,
+ tasks.INTERFACE_HALF_REPRESENTATIVES_RELATIVE,
+ tasks.INTERFACE_MEMBERSHIP_RELATIVE,
+ ]
+ for relative in outputs:
+ assert pq.read_table(workspace / relative).equals(
+ pq.read_table(fresh / relative)
+ )
+ lookup = pq.read_table(
+ workspace / tasks.ALIGNMENT_CHAIN_LOOKUP_RELATIVE
+ ).to_pylist()
+ assert {row["entry_pdb_id"] for row in lookup} == {"1abc", "3ghi"}
+ assert lookup[0]["selected_residue_numbers"] == ([20] if ligands else [])
+ assert lookup[1]["selected_residue_numbers"] == ([30] if interfaces else [])
+ mtimes = {p: (workspace / p).stat().st_mtime_ns for p in outputs}
+ score.main()
+ assert mtimes == {p: (workspace / p).stat().st_mtime_ns for p in outputs}
+ (workspace / tasks.LIGAND_POCKET_RESIDUES_RELATIVE).unlink()
+ score.main()
+ assert tasks._completed_alignment_chain_lookup(workspace) is not None
+ assert before == {p: file_sha256(p) for p in inputs}
diff --git a/tests/data/pipeline/test_tasks.py b/tests/data/pipeline/test_tasks.py
index 1f1ff387e..9c471d27a 100644
--- a/tests/data/pipeline/test_tasks.py
+++ b/tests/data/pipeline/test_tasks.py
@@ -1,7 +1,1103 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
+import json
+import os
+from pathlib import Path
+from shutil import copyfile
+from types import SimpleNamespace
+
+import pandas as pd
+import pyarrow as pa
+import pyarrow.parquet as pq
import pytest
+
+from plinder.core.scores.mapping import pack_residue_identities
+from plinder.core.utils import schemas
+from plinder.core.utils.files import write_json_atomic
+from plinder.data.annotations.get_similarity_scores import (
+ SCORE_METRICS_METADATA_KEY,
+ SCORE_THRESHOLDS_METADATA_KEY,
+ score_metrics_metadata,
+ score_thresholds_metadata,
+)
+from plinder.data.annotations.interface_utils import INTERFACE_ANNOTATION_SCHEMA
from plinder.data.pipeline import io, tasks
+from plinder.data.pipeline.config import LigandConfig
+
+
+def test_ccd_builder_forwards_parity_selection(tmp_path, monkeypatch):
+ calls = []
+ monkeypatch.setattr(
+ tasks.ccd_ligand_dbs,
+ "make_ccd_ligand_dbs",
+ lambda **kwargs: calls.append(kwargs),
+ )
+ match = tmp_path / "ccd_dbs/ligand_ccd_match.parquet"
+ monkeypatch.setattr(
+ tasks.ccd_ligand_dbs, "make_ligand_ccd_match", lambda **_kwargs: match
+ )
+
+ assert (
+ tasks.make_ccd_ligand_dbs(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ build_parity_scores=True,
+ )
+ == match
+ )
+ assert calls[0]["build_parity_scores"] is True
+
+
+def test_foldseek_manifest_signature_reads_references_in_parallel(
+ tmp_path: Path,
+) -> None:
+ first = tmp_path / "first.cif"
+ second = tmp_path / "second.cif"
+ first.write_text("first")
+ second.write_text("second")
+ manifest = tmp_path / "coordinates.tsv"
+ manifest.write_text(f"{first}\tfirst\n{second}\tsecond\n")
+
+ serial = tasks._foldseek_manifest_signature(manifest, threads=1)
+ assert serial == tasks._foldseek_manifest_signature(manifest, threads=4)
+ assert serial["referenced_cif_count"] == 2
+
+ first.write_text("changed")
+ assert serial != tasks._foldseek_manifest_signature(manifest, threads=4)
+
+
+def _write_selected_residue_lookup(data_dir: Path, rows: list[dict]) -> Path:
+ path = data_dir / tasks.ALIGNMENT_CHAIN_LOOKUP_RELATIVE
+ path.parent.mkdir(exist_ok=True, parents=True)
+ for row in rows:
+ row.setdefault(
+ "selected_residue_indices",
+ list(range(len(row["selected_residue_numbers"]))),
+ )
+ pd.DataFrame(rows).to_parquet(path, index=False)
+ return path
+
+
+def _write_ligand_pair_scores(
+ data_dir: Path, pdb_id: str, candidates: list[dict]
+) -> Path:
+ output = (
+ data_dir
+ / "scores"
+ / "ligand_pair_scores"
+ / "search_db=holo"
+ / f"shard={pdb_id[1:3]}"
+ / f"{pdb_id}.parquet"
+ )
+ output.parent.mkdir(exist_ok=True, parents=True)
+ rows = []
+ for candidate in candidates:
+ rows.append(
+ {
+ key: candidate[key]
+ for key in [
+ "query_system",
+ "query_ligand_id",
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_system",
+ "target_ligand_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ }
+ | {
+ "pocket_qcov": round(float(candidate["pocket_qcov"]) * 100),
+ "pocket_fident_qcov": 0,
+ "pli_qcov": 0,
+ }
+ )
+ pq.write_table(
+ pa.Table.from_pylist(rows, schema=schemas.LIGAND_PAIR_SCORE_SCHEMA),
+ output,
+ )
+ return output
+
+
+def _write_alignment_chain_lookup(data_dir: Path) -> None:
+ index = data_dir / "index"
+ index.mkdir(exist_ok=True, parents=True)
+ annotation = index / "annotation_table.parquet"
+ if not annotation.is_file():
+ schema = pa.schema(
+ [
+ ("entry_pdb_id", pa.string()),
+ ("system_id", pa.string()),
+ ("system_type", pa.string()),
+ ("ligand_id", pa.string()),
+ ("ligand_asym_id", pa.string()),
+ ("ligand_is_proper", pa.bool_()),
+ ("ligand_is_shape_comparable", pa.bool_()),
+ ("ligand_protein_chains_asym_id", pa.list_(pa.string())),
+ ("ligand_neighboring_residues", pa.list_(pa.string())),
+ ("ligand_interacting_residues", pa.list_(pa.string())),
+ ("ligand_interactions", pa.list_(pa.string())),
+ ]
+ )
+ pq.write_table(pa.Table.from_pylist([], schema=schema), annotation)
+ interface = index / "interface_annotation_table.parquet"
+ if not interface.is_file():
+ _write_empty_interface_index(index)
+ chains = index / "entry_chains.parquet"
+ if not chains.is_file():
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "chain_asym_id": ["A"],
+ "chain_auth_id": ["A"],
+ "chain_receptor_type": ["protein"],
+ }
+ ).to_parquet(chains, index=False)
+ scratch = data_dir / "normalized-input-scratch"
+ tasks.make_ligand_pocket_representatives(
+ data_dir=data_dir,
+ scratch_dir=scratch,
+ threads=1,
+ force_update=True,
+ )
+ tasks.make_interface_representatives(
+ data_dir=data_dir,
+ scratch_dir=scratch,
+ threads=1,
+ force_update=True,
+ )
+ lookup = data_dir / tasks.ALIGNMENT_CHAIN_LOOKUP_RELATIVE
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "chain_asym_id": ["A"],
+ "chain_auth_id": ["A"],
+ "selected_residue_numbers": [[10]],
+ "selected_residue_indices": [[9]],
+ }
+ ).to_parquet(lookup, index=False)
+ tasks._write_alignment_chain_lookup_manifest(data_dir)
+
+
+def _write_empty_interface_index(index: Path) -> None:
+ pq.write_table(
+ pa.Table.from_pylist([], schema=INTERFACE_ANNOTATION_SCHEMA),
+ index / "interface_annotation_table.parquet",
+ )
+
+
+def test_make_ligand_pocket_representatives_collapses_assembly_copies(
+ tmp_path,
+):
+ from plinder.data.pipeline.score import (
+ LIGAND_POCKET_SCORE_WORK_RELATIVE,
+ SCORE_WORK_RELATIVE,
+ plan_ligand_pocket_scoring,
+ )
+
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "1abc"],
+ "chain_asym_id": ["A", "N"],
+ "chain_auth_id": ["X", "Y"],
+ "chain_receptor_type": ["protein", "dna"],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"] * 3,
+ "system_id": ["system-1", "system-2", "system-3"],
+ "system_type": ["holo"] * 3,
+ "ligand_id": ["ligand-1", "ligand-2", "ligand-3"],
+ "ligand_asym_id": ["L"] * 3,
+ "ligand_is_proper": [True] * 3,
+ "ligand_is_shape_comparable": [True] * 3,
+ "ligand_protein_chains_asym_id": [
+ ["1.A", "1.N"],
+ ["2.A", "2.N"],
+ ["1.A"],
+ ],
+ "system_protein_chains_asym_id": [
+ ["1.A", "1.N"],
+ ["2.A", "2.N"],
+ ["1.A"],
+ ],
+ "ligand_neighboring_residues": [
+ ["1.A_10_0_110_A", "1.N_20_0_220_."],
+ ["2.A_10_0_110_A", "2.N_20_0_220_."],
+ ["1.A_11_1_11", "1.A_13_3_213_."],
+ ],
+ "ligand_interacting_residues": [
+ ["1.A_10_0_110_A", "1.N_20_0_220_."],
+ ["2.A_10_0_110_A", "2.N_20_0_220_."],
+ ["1.A_11_1_11", "1.A_12_2_212_."],
+ ],
+ "ligand_interactions": [
+ ["1.A_10_hbond", "1.N_20_hbond"],
+ ["2.A_10_hbond", "2.N_20_hbond"],
+ ["1.A_11_hydrophobic", "1.A_12_water_bridge"],
+ ],
+ }
+ ).to_parquet(index / "annotation_table.parquet", index=False)
+
+ report = tasks.make_ligand_pocket_representatives(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ )
+ assert report["ligand_count"] == 3
+ assert report["representative_ligand_count"] == 2
+ assert report["pocket_residue_count"] == 4
+ representatives = pd.read_parquet(
+ tmp_path / tasks.LIGAND_POCKET_REPRESENTATIVES_RELATIVE
+ ).set_index("representative_ligand_id")
+ assert representatives.loc["ligand-1", "receptor_chain_asym_ids"] == ["A"]
+ assert representatives.loc["ligand-1", "receptor_set_id"] == "ligand-1"
+ assert representatives.loc["ligand-1", "pocket_residues"] == ["A_10_0_110_A"]
+ assert representatives.loc["ligand-1", "interactions"] == ["A_10_hbond"]
+ membership = pd.read_parquet(
+ tmp_path / tasks.LIGAND_POCKET_MEMBERSHIP_RELATIVE
+ ).set_index("ligand_id")
+ assert membership.loc["ligand-2", "representative_ligand_id"] == "ligand-1"
+ assert membership.loc["ligand-3", "representative_ligand_id"] == "ligand-3"
+ residues = pd.read_parquet(
+ tmp_path / tasks.LIGAND_POCKET_RESIDUES_RELATIVE
+ ).sort_values(["ligand_id", "residue_label_seq_id"])
+ assert residues.to_dict("records") == [
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": "system-1",
+ "ligand_id": "ligand-1",
+ "chain_instance": "1.A",
+ "chain_asym_id": "A",
+ "chain_auth_id": "X",
+ "residue_label_seq_id": 10,
+ "residue_index": 0,
+ "residue_auth_seq_id": "110",
+ "residue_insertion_code": "A",
+ "is_pli": True,
+ },
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": "system-2",
+ "ligand_id": "ligand-2",
+ "chain_instance": "2.A",
+ "chain_asym_id": "A",
+ "chain_auth_id": "X",
+ "residue_label_seq_id": 10,
+ "residue_index": 0,
+ "residue_auth_seq_id": "110",
+ "residue_insertion_code": "A",
+ "is_pli": True,
+ },
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": "system-3",
+ "ligand_id": "ligand-3",
+ "chain_instance": "1.A",
+ "chain_asym_id": "A",
+ "chain_auth_id": "X",
+ "residue_label_seq_id": 11,
+ "residue_index": 1,
+ "residue_auth_seq_id": "11",
+ "residue_insertion_code": ".",
+ "is_pli": True,
+ },
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": "system-3",
+ "ligand_id": "ligand-3",
+ "chain_instance": "1.A",
+ "chain_asym_id": "A",
+ "chain_auth_id": "X",
+ "residue_label_seq_id": 13,
+ "residue_index": 3,
+ "residue_auth_seq_id": "213",
+ "residue_insertion_code": ".",
+ "is_pli": False,
+ },
+ ]
+ assert report["residue_selection"] == tasks.LIGAND_POCKET_RESIDUE_SELECTION
+ manifest_path = tmp_path / tasks.LIGAND_POCKET_REPRESENTATIVES_MANIFEST_RELATIVE
+ manifest = json.loads(manifest_path.read_text())
+ stale_manifest = dict(manifest)
+ stale_manifest.pop("residue_selection")
+ manifest_path.write_text(json.dumps(stale_manifest))
+ assert tasks._completed_ligand_pocket_representatives(tmp_path) is None
+ manifest_path.write_text(json.dumps(manifest))
+ assert (
+ tasks.make_ligand_pocket_representatives(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ )
+ == report
+ )
+ active_work = tmp_path / SCORE_WORK_RELATIVE
+ active_work.parent.mkdir(parents=True, exist_ok=True)
+ pd.DataFrame({"pdb_id": ["1abc"]}).to_parquet(active_work, index=False)
+ score_plan = plan_ligand_pocket_scoring(
+ tmp_path,
+ scratch_dir=tmp_path / "score-plan-scratch",
+ threads=1,
+ memory_limit="1GB",
+ max_query_protein_chains=1,
+ max_query_proper_ligand_chains=1,
+ )
+ assert score_plan["query_ligand_count"] == 3
+ assert score_plan["query_representative_ligand_count"] == 2
+ query_work = pd.read_parquet(tmp_path / LIGAND_POCKET_SCORE_WORK_RELATIVE)
+ assert set(query_work["ligand_id"]) == {"ligand-1", "ligand-2", "ligand-3"}
+
+
+def test_pocket_chain_assignment_is_lexicographically_optimal():
+ from plinder.core.scores.metrics import maximum_weight_bipartite_assignment
+
+ pocket_coverage = {
+ ("A", "X"): 0,
+ ("A", "Y"): 1,
+ ("B", "X"): 1,
+ ("B", "Y"): 0,
+ }
+ protein_similarity = {
+ ("A", "X"): 1.0,
+ ("A", "Y"): 0.1,
+ ("B", "X"): 0.1,
+ ("B", "Y"): 1.0,
+ }
+ assert maximum_weight_bipartite_assignment(
+ ["A", "B"],
+ ["X", "Y"],
+ pocket_coverage,
+ secondary_weights=protein_similarity,
+ ) == [("A", "Y"), ("B", "X")]
+ assert maximum_weight_bipartite_assignment(
+ ["A", "B"],
+ ["X", "Y"],
+ {pair: 1 for pair in pocket_coverage},
+ secondary_weights=protein_similarity,
+ ) == [("A", "X"), ("B", "Y")]
+
+
+def test_ligand_pocket_qcov_uses_pocket_optimal_receptor_mapping(tmp_path):
+ from plinder.data.pipeline.score import (
+ SCORE_WORK_RELATIVE,
+ materialize_ligand_3d_pair_candidates,
+ score_ligand_pocket_qcov_representatives,
+ score_ligand_pocket_qcov_shards,
+ )
+
+ representatives = pa.Table.from_pylist(
+ [
+ {
+ "representative_ligand_id": "query-ligand",
+ "representative_system_id": "query-system",
+ "entry_pdb_id": "1abc",
+ "ligand_asym_id": "L",
+ "ligand_is_shape_comparable": True,
+ "receptor_set_id": "query-receptors",
+ "receptor_chain_asym_ids": ["A", "B"],
+ "pocket_residues": ["A_1_0_1", "B_2_1_2"],
+ "interactions": [],
+ },
+ {
+ "representative_ligand_id": "target-ligand",
+ "representative_system_id": "target-system",
+ "entry_pdb_id": "2def",
+ "ligand_asym_id": "M",
+ "ligand_is_shape_comparable": True,
+ "receptor_set_id": "target-receptors",
+ "receptor_chain_asym_ids": ["X", "Y"],
+ "pocket_residues": ["X_10_0_10", "Y_20_1_20"],
+ "interactions": [],
+ },
+ ],
+ schema=schemas.LIGAND_POCKET_REPRESENTATIVE_SCHEMA,
+ )
+ representative_path = tmp_path / tasks.LIGAND_POCKET_REPRESENTATIVES_RELATIVE
+ representative_path.parent.mkdir(parents=True)
+ pq.write_table(representatives, representative_path)
+ work_path = tmp_path / SCORE_WORK_RELATIVE
+ work_path.parent.mkdir(parents=True)
+ pd.DataFrame({"pdb_id": ["1abc"]}).to_parquet(work_path, index=False)
+ _write_selected_residue_lookup(
+ tmp_path,
+ [
+ {
+ "entry_pdb_id": entry,
+ "chain_asym_id": chain,
+ "selected_residue_numbers": residues,
+ }
+ for entry, chain, residues in [
+ ("1abc", "A", [1]),
+ ("1abc", "B", [2]),
+ ("2def", "X", [10, 99]),
+ ("2def", "Y", [20, 99]),
+ ]
+ ],
+ )
+
+ alignment_path = tasks._alignment_release_path(
+ data_dir=tmp_path,
+ search_db="holo",
+ alignment_type="foldseek",
+ shard="ab",
+ )
+ alignment_path.parent.mkdir(parents=True)
+ rows = [
+ {
+ "query_entry": "1abc",
+ "target_entry": "2def",
+ "query_chain_mapped": "A",
+ "target_chain_mapped": "X",
+ "source": "foldseek",
+ "qcov": 1.0,
+ "fident": 1.0,
+ "seqsim": 1.0,
+ "query_selected_residue_positions": [1],
+ "target_selected_residue_positions": [2],
+ "selected_residue_identity_bits": bytes([1]),
+ # A missing whole-chain tie-break must not discard valid pocket
+ # coverage or abort a production shard.
+ "lddt": None,
+ },
+ {
+ "query_entry": "1abc",
+ "target_entry": "2def",
+ "query_chain_mapped": "B",
+ "target_chain_mapped": "Y",
+ "source": "foldseek",
+ "qcov": 1.0,
+ "fident": 1.0,
+ "seqsim": 1.0,
+ "query_selected_residue_positions": [1],
+ "target_selected_residue_positions": [2],
+ "selected_residue_identity_bits": bytes([1]),
+ "lddt": 0.9,
+ },
+ {
+ "query_entry": "1abc",
+ "target_entry": "2def",
+ "query_chain_mapped": "A",
+ "target_chain_mapped": "Y",
+ "source": "foldseek",
+ "qcov": 1.0,
+ "fident": 1.0,
+ "seqsim": 1.0,
+ "query_selected_residue_positions": [1],
+ "target_selected_residue_positions": [1],
+ "selected_residue_identity_bits": bytes([1]),
+ "lddt": 0.2,
+ },
+ {
+ "query_entry": "1abc",
+ "target_entry": "2def",
+ "query_chain_mapped": "B",
+ "target_chain_mapped": "X",
+ "source": "foldseek",
+ "qcov": 1.0,
+ "fident": 1.0,
+ "seqsim": 1.0,
+ "query_selected_residue_positions": [1],
+ "target_selected_residue_positions": [1],
+ "selected_residue_identity_bits": bytes([1]),
+ "lddt": 0.1,
+ },
+ ]
+ for row in rows:
+ row.update(
+ query_start=1,
+ target_start=row["target_selected_residue_positions"][0],
+ cigar="1M",
+ tcov=1.0,
+ )
+ pq.write_table(
+ pa.Table.from_pylist(
+ rows,
+ schema=schemas.release_alignment_mapping_schema(alignment_type="foldseek"),
+ ),
+ alignment_path,
+ )
+ mmseqs_alignment_path = tasks._alignment_release_path(
+ data_dir=tmp_path,
+ search_db="holo",
+ alignment_type="mmseqs",
+ shard="ab",
+ )
+ mmseqs_alignment_path.parent.mkdir(parents=True)
+ mmseqs_rows = [
+ {
+ "query_entry": "1abc",
+ "target_entry": "2def",
+ "query_chain_mapped": "A",
+ "target_chain_mapped": "X",
+ "source": "mmseqs",
+ "qcov": 1.0,
+ "fident": 0.95,
+ "seqsim": 0.95,
+ "query_selected_residue_positions": [1],
+ "target_selected_residue_positions": [1],
+ "selected_residue_identity_bits": bytes([1]),
+ },
+ {
+ "query_entry": "1abc",
+ "target_entry": "2def",
+ "query_chain_mapped": "B",
+ "target_chain_mapped": "Y",
+ "source": "mmseqs",
+ "qcov": 1.0,
+ "fident": 0.9,
+ "seqsim": 0.9,
+ "query_selected_residue_positions": [1],
+ "target_selected_residue_positions": [2],
+ "selected_residue_identity_bits": bytes([1]),
+ },
+ ]
+ mmseqs_rows[0].update(query_start=1, target_start=10, cigar="1M", tcov=1.0)
+ mmseqs_rows[1].update(query_start=2, target_start=99, cigar="1M", tcov=1.0)
+ pq.write_table(
+ pa.Table.from_pylist(
+ mmseqs_rows,
+ schema=schemas.release_alignment_mapping_schema(alignment_type="mmseqs"),
+ ),
+ mmseqs_alignment_path,
+ )
+
+ output = tmp_path / "pocket-qcov.parquet"
+ report = score_ligand_pocket_qcov_representatives(
+ tmp_path,
+ shard="ab",
+ output=output,
+ scratch_dir=tmp_path / "score-scratch",
+ query_representative_ligand_ids={"query-ligand"},
+ threads=1,
+ memory_limit="1GB",
+ )
+ assert report["row_count"] == 1
+ scores = pd.read_parquet(output)
+ assert scores.loc[0, "query_ligand_id"] == "query-ligand"
+ assert scores.loc[0, "target_ligand_id"] == "target-ligand"
+ assert scores.loc[0, "protein_mapping"] == "A:Y;B:X"
+ assert scores.loc[0, "protein_mapper"] == "foldseek"
+ assert scores.loc[0, "source"] == "foldseek"
+ assert scores.loc[0, "pocket_qcov"] == pytest.approx(1.0)
+
+ representative_manifest = (
+ tmp_path / tasks.LIGAND_POCKET_REPRESENTATIVES_MANIFEST_RELATIVE
+ )
+ representative_manifest.parent.mkdir(parents=True, exist_ok=True)
+ representative_manifest.write_text('{"status": "complete"}\n')
+ from plinder.data.pipeline.score import (
+ LIGAND_POCKET_SCORE_PLAN_RELATIVE,
+ LIGAND_POCKET_SCORE_WORK_RELATIVE,
+ )
+
+ query_work = pa.Table.from_pylist(
+ [
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": "query-system",
+ "ligand_id": "query-ligand",
+ "representative_system_id": "query-system",
+ "representative_ligand_id": "query-ligand",
+ "shard": "ab",
+ }
+ ],
+ schema=schemas.LIGAND_POCKET_SCORE_QUERY_SCHEMA,
+ )
+ pq.write_table(query_work, tmp_path / LIGAND_POCKET_SCORE_WORK_RELATIVE)
+ (tmp_path / LIGAND_POCKET_SCORE_PLAN_RELATIVE).write_text(
+ '{"status": "complete"}\n'
+ )
+ result = score_ligand_pocket_qcov_shards(
+ tmp_path,
+ shards=["ab"],
+ scratch_dir=tmp_path / "shard-scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+ assert result["shard_count"] == 1
+ assert result["shards"][0]["status"] == "complete"
+ full_candidate = {
+ "query_system": "query-system",
+ "query_ligand_id": "query-ligand",
+ "query_entry": "1abc",
+ "query_ligand_asym_id": "L",
+ "target_system": "target-system",
+ "target_ligand_id": "target-ligand",
+ "target_entry": "2def",
+ "target_ligand_asym_id": "M",
+ "protein_mapping": "A:Y;B:X",
+ "protein_mapper": "foldseek",
+ "pocket_qcov": 1.0,
+ }
+ full_candidate_path = (
+ tmp_path / "scores/ligand_3d_candidate_shards/shard=ab.parquet"
+ )
+ full_candidate_path.parent.mkdir(parents=True, exist_ok=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [full_candidate], schema=schemas.LIGAND_3D_CANDIDATE_SCHEMA
+ ),
+ full_candidate_path,
+ )
+ full_candidate_stat = full_candidate_path.stat()
+ full_candidate_path.with_suffix(".json").write_text(
+ json.dumps(
+ {
+ "shard": "ab",
+ "inputs": [],
+ "output": {
+ "path": str(full_candidate_path.resolve()),
+ "size": full_candidate_stat.st_size,
+ "mtime_ns": full_candidate_stat.st_mtime_ns,
+ "rows": 1,
+ },
+ "pair_output": {},
+ }
+ )
+ )
+ candidate_report = materialize_ligand_3d_pair_candidates(
+ tmp_path,
+ shards=["ab"],
+ scratch_dir=tmp_path / "candidate-scratch",
+ threads=1,
+ memory_limit="1GB",
+ force_update=True,
+ )
+ assert candidate_report["row_count"] == 1
+ candidates = pq.read_table(
+ tmp_path / "scores/ligand_3d_pair_candidate_shards/shard=ab.parquet"
+ ).to_pylist()
+ assert candidates == [
+ {
+ "query_entry": "1abc",
+ "query_ligand_asym_id": "L",
+ "target_entry": "2def",
+ "target_ligand_asym_id": "M",
+ "pocket_qcov": pytest.approx(1.0),
+ }
+ ]
+ cached = score_ligand_pocket_qcov_shards(
+ tmp_path,
+ shards=["ab"],
+ scratch_dir=tmp_path / "shard-scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+ assert cached["shards"][0]["status"] == "cached"
+
+
+def _write_alignment_mapping_manifest(
+ data_dir: Path,
+ shard: str,
+ *,
+ search_db: str = "holo",
+ skipped_queries: dict[str, dict[str, object]] | None = None,
+) -> None:
+ if tasks._completed_alignment_chain_lookup(data_dir) is None:
+ _write_alignment_chain_lookup(data_dir)
+ inputs = tasks._alignment_input_signatures(
+ data_dir=data_dir,
+ search_db=search_db,
+ shard=shard,
+ )
+ outputs = {}
+ protein_score_outputs = {}
+ for alignment_type, signatures in inputs.items():
+ output = tasks._alignment_release_path(
+ data_dir=data_dir,
+ search_db=search_db,
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ if not signatures:
+ outputs[alignment_type] = None
+ if search_db == "holo":
+ protein_score_outputs[alignment_type] = None
+ continue
+ stat = output.stat()
+ outputs[alignment_type] = {
+ "name": output.name,
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ }
+ if search_db == "holo":
+ frame = pd.read_parquet(output)
+ rows = [
+ {
+ "query_entry": str(row.query_entry),
+ "target_entry": str(row.target_entry),
+ "query_chain_mapped": str(row.query_chain_mapped),
+ "target_chain_mapped": str(row.target_chain_mapped),
+ "source": str(row.source),
+ "qcov": round(float(row.qcov) * 100),
+ "tcov": round(float(row.tcov) * 100),
+ "fident": round(float(row.fident) * 100),
+ "seqsim": round(float(row.seqsim) * 100),
+ "lddt": (
+ round(float(row.lddt) * 100)
+ if alignment_type == "foldseek"
+ else None
+ ),
+ }
+ for row in frame.itertuples(index=False)
+ ]
+ protein_scores = tasks._protein_similarity_score_path(
+ data_dir=data_dir,
+ alignment_type=alignment_type,
+ shard=shard,
+ )
+ protein_scores.parent.mkdir(parents=True, exist_ok=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ rows,
+ schema=schemas.PROTEIN_SIMILARITY_EXPORT_SCHEMA,
+ ),
+ protein_scores,
+ )
+ score_stat = protein_scores.stat()
+ protein_score_outputs[alignment_type] = {
+ "name": protein_scores.name,
+ "size": score_stat.st_size,
+ "mtime_ns": score_stat.st_mtime_ns,
+ }
+ manifest = tasks._alignment_mapping_manifest_path(
+ data_dir=data_dir,
+ search_db=search_db,
+ shard=shard,
+ )
+ manifest.parent.mkdir(exist_ok=True, parents=True)
+ manifest.write_text(
+ json.dumps(
+ {
+ "search_db": search_db,
+ "shard": shard,
+ "alignment_chain_lookup": tasks._completed_alignment_chain_lookup(
+ data_dir
+ ),
+ "inputs": inputs,
+ "outputs": outputs,
+ "protein_score_outputs": protein_score_outputs,
+ "skipped_queries": skipped_queries or {},
+ }
+ )
+ )
+
+
+def test_make_batch_scores_threads_node_scratch_to_score_writer(tmp_path, monkeypatch):
+ calls = []
+
+ class FakeScorer:
+ shape_score_threads = 1
+
+ def get_score_df(self, *args, **kwargs):
+ calls.append((args, kwargs))
+
+ fake_scorer = FakeScorer()
+ monkeypatch.setattr(
+ tasks.utils,
+ "get_scorer",
+ lambda **_kwargs: (fake_scorer, ["1abc"], tmp_path / "batch"),
+ )
+ scratch = tmp_path / "node-scratch"
+
+ tasks.make_batch_scores(
+ data_dir=tmp_path,
+ pdb_ids=["1abc"],
+ scorer_cfg=SimpleNamespace(sub_databases=["holo"]),
+ force_update=False,
+ scratch_dir=scratch,
+ threads=3,
+ )
+
+ assert fake_scorer.shape_score_threads == 3
+ assert calls == [
+ (
+ (tmp_path, "1abc"),
+ {
+ "search_db": "holo",
+ "overwrite": False,
+ "map_alignments": False,
+ "scratch_dir": scratch,
+ "source_to_aln_file": {
+ "holo_foldseek": tmp_path
+ / "alignment_cigars/search_db=holo/alignment_type=foldseek/shard=ab.parquet",
+ "holo_mmseqs": tmp_path
+ / "alignment_cigars/search_db=holo/alignment_type=mmseqs/shard=ab.parquet",
+ },
+ "defer_ligand_3d": True,
+ },
+ )
+ ]
+
+
+def test_make_batch_scores_reads_each_apo_alignment_shard_once(
+ tmp_path, monkeypatch
+) -> None:
+ load_calls = []
+ score_calls = []
+
+ class FakeScorer:
+ shape_score_threads = 1
+ entries = {}
+
+ def load_alignments(self, **kwargs):
+ load_calls.append(kwargs)
+ return pd.DataFrame(
+ {"qcov": [1.0, 1.0]},
+ index=pd.MultiIndex.from_tuples(
+ [
+ ("1abc", "3xyz", "A", "X", "foldseek"),
+ ("2abc", "4xyz", "A", "Y", "foldseek"),
+ ],
+ names=[
+ "query_entry",
+ "target_entry",
+ "query_chain_mapped",
+ "target_chain_mapped",
+ "source",
+ ],
+ ),
+ )
+
+ def get_score_df(self, *args, **kwargs):
+ score_calls.append((args, kwargs))
+
+ fake_scorer = FakeScorer()
+ monkeypatch.setattr(
+ tasks.utils,
+ "get_scorer",
+ lambda **_kwargs: (fake_scorer, ["1abc", "2abc"], tmp_path / "batch"),
+ )
+ monkeypatch.setattr(
+ "plinder.core.scores.entries.load_entry_views",
+ lambda *, pdb_ids, data_dir, include_interfaces: (
+ {pdb_id: object() for pdb_id in pdb_ids}
+ if include_interfaces is False
+ else pytest.fail("linked-apo scoring must not load interface annotations")
+ ),
+ )
+
+ tasks.make_batch_scores(
+ data_dir=tmp_path,
+ pdb_ids=["1abc", "2abc"],
+ scorer_cfg=SimpleNamespace(sub_databases=["apo"]),
+ force_update=False,
+ scratch_dir=tmp_path / "scratch",
+ threads=2,
+ )
+
+ assert len(load_calls) == 1
+ assert load_calls[0]["query_entry_ids"] == {"1abc", "2abc"}
+ assert [call[0][1] for call in score_calls] == ["1abc", "2abc"]
+ assert all(len(call[1]["query_entry_alignments"]) == 1 for call in score_calls)
+ assert all(
+ set(call[1]["score_metrics"])
+ == {
+ "pocket_fident",
+ "protein_fident_weighted_sum",
+ "protein_fident_qcov_weighted_sum",
+ "protein_lddt_weighted_sum",
+ }
+ for call in score_calls
+ )
+
+
+def test_make_batch_scores_keeps_all_pred_metrics(tmp_path, monkeypatch) -> None:
+ score_calls = []
+
+ class FakeScorer:
+ shape_score_threads = 1
+ entries = {}
+
+ def load_alignments(self, **_kwargs):
+ return pd.DataFrame()
+
+ def get_score_df(self, *args, **kwargs):
+ score_calls.append((args, kwargs))
+
+ monkeypatch.setattr(
+ tasks.utils,
+ "get_scorer",
+ lambda **_kwargs: (FakeScorer(), ["1abc"], tmp_path / "batch"),
+ )
+ monkeypatch.setattr(
+ "plinder.core.scores.entries.load_entry_views",
+ lambda *, pdb_ids, data_dir, include_interfaces: {
+ pdb_id: object() for pdb_id in pdb_ids
+ },
+ )
+
+ tasks.make_batch_scores(
+ data_dir=tmp_path,
+ pdb_ids=["1abc"],
+ scorer_cfg=SimpleNamespace(sub_databases=["pred"]),
+ force_update=False,
+ scratch_dir=tmp_path / "scratch",
+ )
+
+ assert len(score_calls) == 1
+ assert score_calls[0][1]["score_metrics"] is None
+
+
+def test_make_entries_uses_shared_v3_batch(tmp_path, monkeypatch):
+ calls = []
+
+ def capture(**kwargs):
+ calls.append(kwargs)
+ metrics_path = tmp_path / "metrics" / "batch.json"
+ metrics_path.parent.mkdir(parents=True)
+ metrics_path.write_text(
+ json.dumps(
+ {
+ "entries": [
+ {"pdb_id": "1abc", "status": "complete"},
+ {"pdb_id": "2def", "status": "failed"},
+ ]
+ }
+ )
+ )
+ return metrics_path, True
+
+ monkeypatch.setattr(tasks, "ingest_pdb_batch", capture)
+ failed = tasks.make_entries(
+ data_dir=tmp_path,
+ pdb_ids=["1ABC", "2def"],
+ cif_root=tmp_path / "nextgen",
+ validation_root=tmp_path / "validation",
+ force_update=False,
+ annotation_cfg={"min_polymer_size": 10},
+ entry_cfg={"interaction_search_threshold": 8},
+ interface_cfg={"contact_radius": 9},
+ ingest_mode="interfaces",
+ cpu=1,
+ )
+
+ assert failed == ["2def"]
+ assert calls[0]["pdb_ids"] == ["1abc", "2def"]
+ assert calls[0]["cif_root"] == tmp_path / "nextgen"
+ assert calls[0]["validation_root"] == tmp_path / "validation"
+ assert calls[0]["annotation_cfg"] == {"min_polymer_size": 10}
+ assert calls[0]["entry_cfg"] == {"interaction_search_threshold": 8}
+ assert calls[0]["interface_cfg"] == {"contact_radius": 9}
+ assert calls[0]["mode"] == "interfaces"
+
+
+def test_scatter_make_entries_discovers_configured_source_root(tmp_path):
+ cif_root = tmp_path / "external-nextgen"
+ cif_path = cif_root / "ab" / "pdb_00001abc" / "pdb_00001abc_xyz-enrich.cif.gz"
+ cif_path.parent.mkdir(parents=True)
+ cif_path.write_bytes(b"1234")
+
+ chunks = tasks.scatter_make_entries(
+ data_dir=tmp_path / "release",
+ cif_root=cif_root,
+ validation_root=tmp_path / "external-validation",
+ batch_size=10,
+ two_char_codes=[],
+ pdb_ids=["1ABC"],
+ force_update=False,
+ discovery_threads=1,
+ )
+
+ assert chunks == [["1abc"]]
+
+
+def test_scatter_make_entries_pdb_ids_override_two_char_codes(tmp_path):
+ cif_root = tmp_path / "external-nextgen"
+ for pdb_id in ("1abc", "2def"):
+ cif_path = (
+ cif_root
+ / pdb_id[1:3]
+ / f"pdb_0000{pdb_id}"
+ / f"pdb_0000{pdb_id}_xyz-enrich.cif.gz"
+ )
+ cif_path.parent.mkdir(parents=True)
+ cif_path.touch()
+
+ chunks = tasks.scatter_make_entries(
+ data_dir=tmp_path / "release",
+ cif_root=cif_root,
+ validation_root=tmp_path / "external-validation",
+ batch_size=10,
+ two_char_codes=["ab"],
+ pdb_ids=["2def"],
+ force_update=False,
+ discovery_threads=1,
+ )
+
+ assert chunks == [["2def"]]
+
+
+def test_entry_collation_tasks_use_shared_core(tmp_path, monkeypatch):
+ shard_calls = []
+ finalize_calls = []
+ monkeypatch.setattr(
+ tasks.collate,
+ "plan_collation",
+ lambda data_dir, **_kwargs: {"codes": ["aa", "ab", "ac"]},
+ )
+ monkeypatch.setattr(
+ tasks.collate,
+ "collate_shard",
+ lambda *args, **kwargs: shard_calls.append((args, kwargs)),
+ )
+ monkeypatch.setattr(
+ tasks.collate,
+ "finalize_collation",
+ lambda *args, **kwargs: finalize_calls.append((args, kwargs)) or {"ok": True},
+ )
+
+ chunks = tasks.scatter_collate_entries(data_dir=tmp_path, batch_size=2)
+ tasks.collate_entries(
+ data_dir=tmp_path,
+ two_char_codes=chunks[0],
+ cpu=2,
+ memory_limit="7GB",
+ )
+ result = tasks.finalize_entry_collation(
+ data_dir=tmp_path,
+ cpu=4,
+ memory_limit="32GB",
+ )
+
+ assert chunks == [["aa", "ab"], ["ac"]]
+ assert [args[1] for args, _ in shard_calls] == ["aa", "ab"]
+ assert all(kwargs["threads"] == 2 for _, kwargs in shard_calls)
+ assert result == {"ok": True}
+ assert finalize_calls[0][1]["threads"] == 4
+
+
+def test_archive_scatter_pdb_ids_override_two_char_codes(tmp_path):
+ for code in ("ab", "de"):
+ (tmp_path / "raw_entries" / code).mkdir(parents=True)
+ (tmp_path / "raw_entries" / "de" / "2def.parquet").touch()
+
+ chunks = tasks.scatter_make_canonical_ligand_archives(
+ data_dir=tmp_path,
+ batch_size=1,
+ two_char_codes=["ab"],
+ pdb_ids=["2DEF"],
+ )
+
+ assert chunks == [["de"]]
+
+
+def test_archive_scatter_drops_explicit_empty_raw_shards(tmp_path):
+ (tmp_path / "raw_entries" / "de").mkdir(parents=True)
+
+ chunks = tasks.scatter_make_canonical_ligand_archives(
+ data_dir=tmp_path,
+ batch_size=1,
+ two_char_codes=["de"],
+ pdb_ids=[],
+ )
+
+ assert chunks == []
@pytest.mark.parametrize(
@@ -30,3 +1126,6311 @@ def test_download_rcsb_files(tmp_path):
io.rsync_rcsb = lambda *args, **kws: None
tasks.download_rcsb_files(data_dir=tmp_path, two_char_codes=["aa"])
io.rsync_rcsb = _orig_rsync_rcsb
+
+
+def test_alternative_downloads_use_only_approved_sources(tmp_path, monkeypatch):
+ calls = []
+ approved = {
+ "download_cofactors",
+ "download_seqres_data",
+ "refresh_bundled_ccd",
+ "download_affinity_data",
+ }
+
+ for name in approved:
+ monkeypatch.setattr(io, name, lambda *, _name=name, **_: calls.append(_name))
+
+ tasks.download_alternative_datasets(
+ data_dir=tmp_path,
+ threads=1,
+ force_update=False,
+ )
+
+ assert set(calls) == approved
+ assert not hasattr(io, "download_ecod_data")
+ assert not hasattr(io, "download_panther_data")
+ assert not hasattr(io, "download_kinase_data")
+
+
+def test_scoring_finalization_stage_order_and_partitions():
+ assert tasks.STAGES.index("collate_entries") < tasks.STAGES.index("make_dbs")
+ assert tasks.STAGES.index("make_canonical_ligand_archives") < tasks.STAGES.index(
+ "finalize_ligand_archives"
+ )
+ assert tasks.STAGES.index("finalize_ligand_archives") < tasks.STAGES.index(
+ "compute_ligand_fingerprints"
+ )
+ assert tasks.STAGES.index("make_ligand_scores") < tasks.STAGES.index(
+ "annotate_ligand_similarity"
+ )
+ assert tasks.STAGES.index("annotate_ligand_similarity") < tasks.STAGES.index(
+ "make_ligand_mmp_pairs"
+ )
+ assert tasks.STAGES.index("make_ligand_mmp_pairs") < tasks.STAGES.index(
+ "make_ccd_ligand_dbs"
+ )
+ assert tasks.STAGES.index("make_ccd_ligand_dbs") < tasks.STAGES.index(
+ "make_sub_dbs"
+ )
+ assert tasks.STAGES.index("map_batch_alignments") < tasks.STAGES.index(
+ "collate_alignments"
+ )
+ assert tasks.STAGES.index("collate_alignments") < tasks.STAGES.index(
+ "finalize_alignments"
+ )
+ assert tasks.STAGES.index("finalize_alignments") < tasks.STAGES.index(
+ "plan_score_batches"
+ )
+ assert tasks.STAGES.index("plan_score_batches") < tasks.STAGES.index(
+ "plan_interface_scores"
+ )
+ assert tasks.STAGES.index("plan_interface_scores") < tasks.STAGES.index(
+ "make_interface_scores"
+ )
+ assert tasks.STAGES.index("make_interface_scores") < tasks.STAGES.index(
+ "finalize_interface_scores"
+ )
+ assert tasks.STAGES.index("finalize_interface_scores") < tasks.STAGES.index(
+ "make_batch_scores"
+ )
+ assert tasks.STAGES.index("make_batch_scores") < tasks.STAGES.index(
+ "collate_ligand_3d_candidates"
+ )
+ assert tasks.STAGES.index("collate_ligand_3d_candidates") < tasks.STAGES.index(
+ "plan_ligand_3d_scores"
+ )
+ assert tasks.STAGES.index("plan_ligand_3d_scores") < tasks.STAGES.index(
+ "make_ligand_3d_scores"
+ )
+ assert tasks.STAGES.index("make_ligand_3d_scores") < tasks.STAGES.index(
+ "collate_ligand_3d_scores"
+ )
+ assert tasks.STAGES.index("collate_ligand_3d_scores") < tasks.STAGES.index(
+ "merge_ligand_3d_scores"
+ )
+ assert tasks.STAGES.index("merge_ligand_3d_scores") < tasks.STAGES.index(
+ "finalize_scores"
+ )
+ assert tasks.STAGES.index("finalize_scores") < tasks.STAGES.index(
+ "export_ligand_similarity_scores"
+ )
+ assert tasks.STAGES.index("export_ligand_similarity_scores") < tasks.STAGES.index(
+ "finalize_ligand_similarity_scores"
+ )
+ assert tasks.STAGES.index("finalize_ligand_similarity_scores") < (
+ tasks.STAGES.index("collate_partitions")
+ )
+ assert tasks.STAGES.index("collate_partitions") < tasks.STAGES.index(
+ "make_linked_apo_structures"
+ )
+ assert tasks.STAGES.index("make_linked_apo_structures") < tasks.STAGES.index(
+ "plan_clusters"
+ )
+ assert tasks.STAGES.index("plan_clusters") < tasks.STAGES.index(
+ "make_symmetric_edge_fragments"
+ )
+ assert tasks.STAGES.index("make_symmetric_edge_fragments") < tasks.STAGES.index(
+ "make_symmetric_edge_shards"
+ )
+ assert tasks.STAGES.index("make_symmetric_edge_shards") < tasks.STAGES.index(
+ "make_component_reductions"
+ )
+ assert tasks.STAGES.index("make_component_reductions") < tasks.STAGES.index(
+ "merge_component_reductions"
+ )
+ assert tasks.STAGES.index("merge_component_reductions") < tasks.STAGES.index(
+ "make_set_covers"
+ )
+ assert tasks.STAGES.index("make_set_covers") < tasks.STAGES.index(
+ "make_directed_set_covers"
+ )
+ assert tasks.STAGES.index("make_directed_set_covers") < tasks.STAGES.index(
+ "summarize_clusters"
+ )
+ assert tasks.STAGES.index("summarize_clusters") < tasks.STAGES.index(
+ "finalize_index"
+ )
+ assert tasks.STAGES[-1] == "finalize_index"
+ partitions = tasks.scatter_collate_partitions()
+ assert len(partitions) == 38
+ assert ["0"] in partitions
+ assert ["z"] in partitions
+ assert ["apo"] in partitions
+ assert ["pred"] in partitions
+
+
+def test_make_linked_apo_structures_publishes_compact_index(tmp_path):
+ index = tmp_path / "index"
+ score_dir = tmp_path / "scores/search_db=apo"
+ index.mkdir()
+ score_dir.mkdir(parents=True)
+ system_id = "1abc__1__1.A__1.L"
+ pd.DataFrame(
+ {
+ "system_id": [system_id, "2def__1__1.A__1.I"],
+ "ligand_id": ["1.L", "2def__1__1.I"],
+ "ligand_is_proper": [True, False],
+ "entry_pdb_id": ["1abc", "2def"],
+ "system_biounit_id": ["1", "1"],
+ "ligand_is_ion": [False, False],
+ "ligand_is_artifact": [False, False],
+ "ligand_neighboring_residues": [[], ["1.A_10_0_10"]],
+ "ligand_protein_chains_asym_id": [["1.A"], []],
+ }
+ ).to_parquet(index / "annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["2def"],
+ "chain_asym_id": ["A"],
+ "chain_auth_id": ["R"],
+ "chain_entity_id": ["1"],
+ "chain_receptor_type": ["protein"],
+ "chain_is_holo": [False],
+ "chain_is_ligand_like": [False],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["2def", "2def", "2def"],
+ "biounit_id": ["1", "1", "2"],
+ "chain_instance": ["1.A", "1.I", "1.A"],
+ "chain_asym_id": ["A", "I", "A"],
+ "chain_role": ["receptor", "ligand", "receptor"],
+ "chain_num_contacting_ions": [0, 0, 0],
+ "chain_num_contacting_artifacts": [0, 0, 0],
+ "chain_num_contacting_other_ligands": [1, 0, 0],
+ }
+ ).to_parquet(index / "entry_biounit_chains.parquet", index=False)
+ pd.DataFrame({"entry_pdb_id": ["2def"], "entry_resolution": [1.8]}).to_parquet(
+ index / "entry_metadata.parquet", index=False
+ )
+ _write_empty_interface_index(index)
+ (index / "collation.json").write_text(
+ json.dumps(
+ {"ligand_contacts_computed": True, "protein_contacts_computed": True}
+ )
+ )
+ score_rows = [
+ {
+ "query_system": system_id,
+ "query_ligand_id": "1.L",
+ "target_system": "2def_A",
+ "metric": metric,
+ "similarity": 100,
+ }
+ for metric in [
+ "pocket_fident",
+ "protein_fident_weighted_sum",
+ "protein_fident_qcov_weighted_sum",
+ "protein_lddt_weighted_sum",
+ ]
+ ]
+ pd.DataFrame(score_rows).to_parquet(score_dir / "apo.parquet", index=False)
+
+ output = tasks.make_linked_apo_structures(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+
+ assert output == index / "linked_apo_structures.parquet"
+ links = pd.read_parquet(output)
+ assert links["reference_system_id"].tolist() == [system_id]
+ assert links["linked_structure_id"].tolist() == ["2def_A"]
+ assert links["source_biounit_id"].tolist() == ["2"]
+ candidates = pd.read_parquet(tmp_path / "manifests/apo_candidates.parquet")
+ assert candidates["source_num_contacting_other_ligands"].tolist() == [0]
+
+
+def test_make_linked_apo_structures_uses_completed_interface_apo_queries(
+ tmp_path, monkeypatch
+):
+ from plinder.data.pipeline.score import INTERFACE_APO_QUERY_MANIFEST_RELATIVE
+
+ index = tmp_path / "index"
+ index.mkdir()
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {
+ "entry_pdb_id": "1abc",
+ "ligand_is_proper": True,
+ "ligand_protein_chains_asym_id": ["1.A"],
+ }
+ ],
+ schema=pa.schema(
+ [
+ ("entry_pdb_id", pa.string()),
+ ("ligand_is_proper", pa.bool_()),
+ ("ligand_protein_chains_asym_id", pa.list_(pa.string())),
+ ]
+ ),
+ ),
+ index / "annotation_table.parquet",
+ )
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "1abc", "2def"],
+ "chain_asym_id": ["A", "B", "X"],
+ "chain_auth_id": ["A", "B", "R"],
+ "chain_entity_id": ["1", "2", "1"],
+ "chain_receptor_type": ["protein", "protein", "protein"],
+ "chain_is_ligand_like": [False, False, False],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["2def"],
+ "biounit_id": ["1"],
+ "chain_instance": ["1.X"],
+ "chain_asym_id": ["X"],
+ "chain_role": ["receptor"],
+ "chain_num_contacting_proteins": pd.Series([0], dtype="Int64"),
+ "chain_num_contacting_ions": pd.Series([pd.NA], dtype="Int64"),
+ "chain_num_contacting_artifacts": pd.Series([pd.NA], dtype="Int64"),
+ "chain_num_contacting_other_ligands": pd.Series([pd.NA], dtype="Int64"),
+ }
+ ).to_parquet(index / "entry_biounit_chains.parquet", index=False)
+ pd.DataFrame(
+ {"entry_pdb_id": ["1abc", "2def"], "entry_resolution": [2.0, 1.8]}
+ ).to_parquet(index / "entry_metadata.parquet", index=False)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": "1abc__1__1.A--1.B",
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.A",
+ "interface_chain_2": "1.B",
+ },
+ {
+ "entry_pdb_id": "3ghi",
+ "system_id": "3ghi__1__1.C--1.D",
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.C",
+ "interface_chain_2": "1.D",
+ },
+ ],
+ schema=INTERFACE_ANNOTATION_SCHEMA,
+ ),
+ index / "interface_annotation_table.parquet",
+ )
+ (index / "collation.json").write_text(
+ json.dumps(
+ {"ligand_contacts_computed": False, "protein_contacts_computed": True}
+ )
+ )
+ pq.write_table(
+ pa.Table.from_pylist(
+ [{"reference_system_id": "existing-ligand-link"}],
+ schema=schemas.STRUCTURE_LINK_SCHEMA,
+ ),
+ index / "linked_apo_structures.parquet",
+ )
+ alignment_dir = (
+ tmp_path / "alignment_cigars/search_db=interface_apo/alignment_type=mmseqs"
+ )
+ alignment_dir.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query_entry": ["1abc"],
+ "target_entry": ["2def"],
+ "query_chain_mapped": ["A"],
+ "target_chain_mapped": ["X"],
+ "qcov": [1.0],
+ "tcov": [1.0],
+ "fident": [1.0],
+ }
+ ).to_parquet(alignment_dir / "shard=ab.parquet", index=False)
+ query_manifest = tmp_path / INTERFACE_APO_QUERY_MANIFEST_RELATIVE
+ query_manifest.parent.mkdir(parents=True, exist_ok=True)
+ pd.DataFrame(
+ {
+ "pdb_id": ["1abc", "1abc"],
+ "shard": ["ab", "ab"],
+ "chain_asym_id": ["A", "B"],
+ "chain_auth_id": ["A", "B"],
+ }
+ ).to_parquet(query_manifest, index=False)
+ mapping_manifest = tasks._alignment_mapping_manifest_path(
+ data_dir=tmp_path,
+ search_db="interface_apo",
+ shard="ab",
+ )
+ mapping_manifest.parent.mkdir(parents=True, exist_ok=True)
+ mapping = {
+ "inputs": {"foldseek": [], "mmseqs": [{"name": "1abc.parquet"}]},
+ "skipped_queries": {},
+ }
+ mapping_manifest.write_text(json.dumps(mapping))
+ monkeypatch.setattr(tasks, "alignment_mapping_shard_is_current", lambda **_: True)
+
+ output = tasks.make_linked_apo_structures(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+
+ assert pq.read_schema(output) == schemas.STRUCTURE_LINK_SCHEMA
+ assert pd.read_parquet(output)["reference_system_id"].tolist() == [
+ "existing-ligand-link"
+ ]
+ interface_links = pd.read_parquet(index / "interface_apo_structures.parquet")
+ assert interface_links["reference_side"].tolist() == [1]
+ assert interface_links["linked_structure_id"].tolist() == ["2def_X"]
+ assert pd.isna(interface_links["source_num_contacting_ions"].iloc[0])
+
+ mapping["inputs"]["mmseqs"] = []
+ mapping_manifest.write_text(json.dumps(mapping))
+ with pytest.raises(ValueError, match="interface apo queries were not mapped.*1abc"):
+ tasks.make_linked_apo_structures(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+
+ mapping["inputs"]["mmseqs"] = [{"name": "1abc.parquet"}]
+ mapping["skipped_queries"] = {"1abc": {"reason": "mapping row budget"}}
+ mapping_manifest.write_text(json.dumps(mapping))
+ with pytest.raises(ValueError, match="interface apo queries were not mapped.*1abc"):
+ tasks.make_linked_apo_structures(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+
+
+def test_directed_set_cover_scatter_skips_only_complete_outputs(tmp_path):
+ work = tasks.scatter_make_directed_set_covers(
+ data_dir=tmp_path,
+ metrics=["pocket_qcov"],
+ thresholds=[100, 50],
+ stop_on_cluster=0,
+ skip_existing=True,
+ )
+ assert work == [[("pocket_qcov", 100), ("pocket_qcov", 50)]]
+
+ output = (
+ tmp_path
+ / "ligand_sampling/directed_set_cover/metric=pocket_qcov"
+ / "threshold=100.parquet"
+ )
+ output.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "ligand_id": ["l1"],
+ "centroid_ligand_id": ["l1"],
+ "similarity_to_centroid": [100.0],
+ "label": ["c0"],
+ "metric": ["pocket_qcov"],
+ "threshold": [100],
+ "directed": [True],
+ }
+ ).to_parquet(output, index=False)
+ work = tasks.scatter_make_directed_set_covers(
+ data_dir=tmp_path,
+ metrics=["pocket_qcov"],
+ thresholds=[100, 50],
+ stop_on_cluster=0,
+ skip_existing=True,
+ )
+ assert work == [[("pocket_qcov", 100), ("pocket_qcov", 50)]]
+
+ complete = pd.DataFrame(
+ {
+ "ligand_id": ["l1"],
+ "centroid_ligand_id": ["l1"],
+ "similarity_to_centroid": [100.0],
+ "coverage_count": pd.Series([1], dtype="Int32"),
+ "coverage_fraction": pd.Series([1.0], dtype="Float32"),
+ "representative_selection_order": pd.Series([0], dtype="Int32"),
+ "representative_selection_threshold": pd.Series([100], dtype="Int16"),
+ "representative_marginal_gain": pd.Series([1], dtype="Int32"),
+ "assignment_threshold": pd.Series([100], dtype="Int16"),
+ "label": ["c0"],
+ "metric": ["pocket_qcov"],
+ "threshold": [100],
+ "directed": [True],
+ }
+ )
+ complete.to_parquet(output, index=False)
+ complete.assign(threshold=50).to_parquet(
+ output.with_name("threshold=50.parquet"),
+ index=False,
+ )
+ assert tasks.scatter_make_directed_set_covers(
+ data_dir=tmp_path,
+ metrics=["pocket_qcov"],
+ thresholds=[100, 50],
+ stop_on_cluster=0,
+ skip_existing=True,
+ ) == [[]]
+
+
+def test_ligand_score_threshold_must_cover_frequency_clustering() -> None:
+ with pytest.raises(ValueError, match="must not exceed"):
+ LigandConfig(minimum_similarity=95)
+
+
+def test_scatter_protein_scoring_uses_v3_chain_index(tmp_path) -> None:
+ index_dir = tmp_path / "index"
+ index_dir.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def", "3ghi", "4jkl", "5mno", "5mno"],
+ "chain_asym_id": ["A", "N", "A", "A", "X", "Y"],
+ "chain_receptor_type": [
+ "protein",
+ "dna",
+ "protein",
+ "protein",
+ "protein",
+ "protein",
+ ],
+ "chain_is_holo": [True, True, True, False, False, False],
+ }
+ ).to_parquet(index_dir / "entry_chains.parquet", index=False)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {
+ "entry_pdb_id": "5mno",
+ "system_id": "5mno__1__1.X--1.Y",
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.X",
+ "interface_chain_2": "1.Y",
+ "interface_chain_1_residue_numbers": [1, 2, 3],
+ "interface_chain_1_residue_indices": [0, 1, 2],
+ "interface_chain_2_residue_numbers": [4, 5, 6],
+ "interface_chain_2_residue_indices": [3, 4, 5],
+ "interface_num_contact_residue_pairs": 3,
+ }
+ ],
+ schema=INTERFACE_ANNOTATION_SCHEMA,
+ ),
+ index_dir / "interface_annotation_table.parquet",
+ )
+ tasks.make_interface_representatives(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ )
+
+ assert tasks.scatter_protein_scoring(
+ data_dir=tmp_path,
+ batch_size=1,
+ two_char_codes=[],
+ pdb_ids=[],
+ ) == [["1abc"], ["3ghi"], ["5mno"]]
+ assert tasks.scatter_protein_scoring(
+ data_dir=tmp_path,
+ batch_size=10,
+ two_char_codes=["ab"],
+ pdb_ids=["3GHI"],
+ ) == [["3ghi"]]
+ from plinder.data.pipeline.score import plan_protein_scoring
+
+ plan = plan_protein_scoring(tmp_path)
+ assert plan["query_count"] == 3
+ assert plan["protein_chain_count"] == 4
+ assert "interface_annotation" in plan
+ assert "interface_half_annotation" in plan
+
+
+def test_protein_plan_refreshes_recollated_interface_representatives(tmp_path):
+ from plinder.data.pipeline.score import _load_plan, plan_protein_scoring
+
+ _write_alignment_chain_lookup(tmp_path)
+ chain_path = tmp_path / "index/entry_chains.parquet"
+ pd.read_parquet(chain_path).assign(chain_is_holo=True).to_parquet(
+ chain_path, index=False
+ )
+ interface_path = tmp_path / "index/interface_annotation_table.parquet"
+ # Collation writes the table again even when its interface rows are unchanged.
+ pq.write_table(pq.read_table(interface_path), interface_path)
+ assert tasks._completed_interface_representatives(tmp_path) is None
+
+ plan = plan_protein_scoring(tmp_path)
+ # The later database/mapping stage must reuse the representatives in the plan.
+ tasks.make_interface_representatives(
+ data_dir=tmp_path, scratch_dir=tmp_path / "scratch", threads=1
+ )
+ assert _load_plan(tmp_path, recheck_source=True) == plan
+
+
+def test_linked_apo_queries_include_ligand_receptors_and_interface_chains(
+ tmp_path,
+) -> None:
+ from plinder.data.pipeline.score import (
+ INTERFACE_APO_QUERY_MANIFEST_RELATIVE,
+ LINKED_APO_QUERY_MANIFEST_RELATIVE,
+ _query_batch,
+ plan_linked_apo_scoring,
+ )
+
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def", "3ghi"],
+ "ligand_is_proper": [True, False, True],
+ "ligand_protein_chains_asym_id": [["1.A"], ["1.A"], ["1.N"]],
+ }
+ ).to_parquet(index / "annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "1abc", "2def", "3ghi"],
+ "chain_asym_id": ["A", "B", "A", "N"],
+ "chain_auth_id": ["R", "I", "A", "N"],
+ "chain_receptor_type": ["protein", "protein", "protein", "dna"],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ pd.DataFrame({"entry_pdb_id": [], "chain_asym_id": []}).to_parquet(
+ index / "entry_biounit_chains.parquet", index=False
+ )
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": "1abc__1__1.A--1.B",
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.A",
+ "interface_chain_2": "1.B",
+ }
+ ],
+ schema=INTERFACE_ANNOTATION_SCHEMA,
+ ),
+ index / "interface_annotation_table.parquet",
+ )
+
+ queries = tasks._linked_apo_query_chains(tmp_path)
+ assert queries.to_dict("records") == [
+ {
+ "entry_pdb_id": "1abc",
+ "chain_asym_id": "A",
+ "chain_auth_id": "R",
+ },
+ {
+ "entry_pdb_id": "1abc",
+ "chain_asym_id": "B",
+ "chain_auth_id": "I",
+ },
+ ]
+ assert tasks.scatter_protein_scoring(
+ data_dir=tmp_path,
+ batch_size=10,
+ two_char_codes=[],
+ pdb_ids=[],
+ search_dbs=["apo"],
+ ) == [["1abc"]]
+
+ report = plan_linked_apo_scoring(tmp_path, max_seqs=123)
+ assert report["query_count"] == 1
+ assert report["ligand_protein_chain_count"] == 1
+ assert report["interface_protein_chain_count"] == 2
+ assert report["max_seqs"] == 123
+ manifest = pd.read_parquet(tmp_path / LINKED_APO_QUERY_MANIFEST_RELATIVE)
+ assert manifest.to_dict("records") == [
+ {
+ "pdb_id": "1abc",
+ "shard": "ab",
+ "chain_asym_id": "A",
+ "chain_auth_id": "R",
+ },
+ ]
+ interface_manifest = pd.read_parquet(
+ tmp_path / INTERFACE_APO_QUERY_MANIFEST_RELATIVE
+ )
+ assert interface_manifest.to_dict("records") == [
+ {
+ "pdb_id": "1abc",
+ "shard": "ab",
+ "chain_asym_id": "A",
+ "chain_auth_id": "R",
+ },
+ {
+ "pdb_id": "1abc",
+ "shard": "ab",
+ "chain_asym_id": "B",
+ "chain_auth_id": "I",
+ },
+ ]
+ assert _query_batch(tmp_path, 0, 10, search_db="apo") == ["1abc"]
+
+
+def test_apo_query_auth_ids_accepts_an_empty_query_manifest(tmp_path) -> None:
+ from plinder.data.pipeline.score import INTERFACE_APO_QUERY_MANIFEST_RELATIVE
+
+ manifest = tmp_path / INTERFACE_APO_QUERY_MANIFEST_RELATIVE
+ manifest.parent.mkdir(parents=True)
+ pd.DataFrame(columns=["pdb_id", "chain_auth_id"]).to_parquet(manifest, index=False)
+
+ assert (
+ tasks._apo_query_auth_ids(tmp_path, ["1abc"], search_db="interface_apo") == {}
+ )
+
+
+def test_interface_apo_target_selection_skips_empty_interface_table(tmp_path) -> None:
+ index = tmp_path / "index"
+ index.mkdir()
+ _write_empty_interface_index(index)
+
+ assert tasks._interface_apo_scoring_chains(tmp_path).empty
+
+
+def test_search_bundle_includes_weekly_overlay(tmp_path, monkeypatch) -> None:
+ from plinder.data.pipeline import score
+
+ base = tmp_path / "dbs/subdbs/holo_mmseqs"
+ base.mkdir(parents=True)
+ monomer = tmp_path / "dbs/subdbs/monomer_mmseqs"
+ monomer.mkdir(parents=True)
+ (monomer / "exact_cluster.json").write_text("{}")
+ overlay = tmp_path / "dbs/weekly_delta/subdbs/holo_mmseqs"
+ overlay.mkdir(parents=True)
+ (overlay / "exact_cluster.json").write_text("{}")
+ shadowed = tmp_path / "manifests/weekly_shadowed_entries.parquet"
+ shadowed.parent.mkdir()
+ pd.DataFrame({"pdb_id": ["1abc"]}).to_parquet(shadowed, index=False)
+ sources = []
+
+ def publish_bundle(*, source_root, target_root, aln_type):
+ sources.append(source_root)
+ target_root.mkdir(parents=True)
+ return {"alignment_type": aln_type}
+
+ monkeypatch.setattr(
+ score.databases, "publish_search_database_bundle", publish_bundle
+ )
+
+ score.publish_search_database_bundles(tmp_path, alignment_types=["mmseqs"])
+
+ assert sources == [base, monomer, overlay]
+ assert not (tmp_path / "search_databases/manifest.json").exists()
+ assert (tmp_path / "search_databases/monomer_mmseqs").is_dir()
+ assert (tmp_path / "search_databases/weekly_delta/holo_mmseqs").is_dir()
+ assert pd.read_parquet(tmp_path / "search_databases/shadowed_entries.parquet")[
+ "pdb_id"
+ ].tolist() == ["1abc"]
+
+
+def test_protein_scoring_plan_and_alignment_finalization(tmp_path, monkeypatch) -> None:
+ from plinder.core.scores.custom import resolve_search_database
+ from plinder.data.pipeline.score import (
+ _scoring_config_from_plan,
+ finalize_alignment_artifacts,
+ make_foldseek_input_manifest,
+ plan_protein_scoring,
+ )
+
+ index_dir = tmp_path / "index"
+ index_dir.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "1abc", "2def"],
+ "chain_asym_id": ["A", "B", "N"],
+ "chain_auth_id": ["A", "B", "N"],
+ "chain_receptor_type": [
+ "protein",
+ "protein",
+ "dna",
+ ],
+ "chain_is_holo": [True, False, True],
+ }
+ ).to_parquet(index_dir / "entry_chains.parquet", index=False)
+ plan = plan_protein_scoring(tmp_path)
+
+ assert plan["query_count"] == 1
+ assert plan["protein_chain_count"] == 1
+ assert plan["max_seqs"] == 10_000
+ pre_score_config = _scoring_config_from_plan(tmp_path, plan)
+ assert pre_score_config.scorer.max_query_protein_chains == 30
+ assert pre_score_config.scorer.max_query_proper_ligand_chains == 30
+ foldseek_inputs = make_foldseek_input_manifest(tmp_path, Path("/nextgen"))
+ assert foldseek_inputs.read_text().splitlines() == [
+ "/nextgen/ab/pdb_00001abc/pdb_00001abc_xyz-enrich.cif.gz"
+ ]
+ for alignment_type in ["foldseek", "mmseqs"]:
+ backend = tmp_path / "dbs/subdbs" / f"holo_{alignment_type}"
+ backend.mkdir(parents=True)
+ source_index = backend / f"holo_{alignment_type}.index"
+ source_index.write_text("0\t0\t1\n")
+ source_identifier = (
+ "pdb_00001abc_xyz-enrich_A" if alignment_type == "foldseek" else "1abc_A"
+ )
+ (backend / f"holo_{alignment_type}.lookup").write_text(
+ f"0\t{source_identifier}\t0\n"
+ )
+ search_target = (
+ "clustered" if alignment_type == "foldseek" else "representatives"
+ )
+ conversion_target = (
+ "clustered" if alignment_type == "foldseek" else f"holo_{alignment_type}"
+ )
+ for database in {search_target, conversion_target}:
+ (backend / f"{database}.dbtype").touch()
+ (backend / f"{search_target}.idx.dbtype").touch()
+ if alignment_type == "mmseqs":
+ (backend / "cluster_alignments.dbtype").touch()
+ (backend / "exact_cluster.json").write_text(
+ json.dumps(
+ {
+ "alignment_type": alignment_type,
+ "identity": 1.0,
+ "coverage": 1.0,
+ "coverage_mode": 0,
+ "portable": True,
+ "compressed_search_target": False,
+ "source_index": {
+ "name": source_index.name,
+ "size": source_index.stat().st_size,
+ "mtime_ns": source_index.stat().st_mtime_ns,
+ },
+ "search_target": search_target,
+ "conversion_target": conversion_target,
+ **(
+ {"cluster_alignments": "cluster_alignments"}
+ if alignment_type == "mmseqs"
+ else {}
+ ),
+ }
+ )
+ )
+ output = backend / "aln"
+ output.mkdir()
+ (output / "1abc.parquet").touch()
+ (output / "4qp3.tmp.parquet").touch()
+ # Raw search output is not part of the published database bundle and
+ # must not be traversed by its portability check.
+ external = tmp_path / f"{alignment_type}_raw_alignment"
+ external.touch()
+ (output / "external-link").symlink_to(external)
+ release = (
+ tmp_path
+ / "alignment_cigars/search_db=holo"
+ / f"alignment_type={alignment_type}"
+ )
+ release.mkdir(parents=True)
+ columns = {
+ "query_entry": ["1abc"],
+ "target_entry": ["1abc"],
+ "query_chain_mapped": ["A"],
+ "target_chain_mapped": ["A"],
+ "source": [alignment_type],
+ "query_start": [1],
+ "target_start": [1],
+ "cigar": ["1M"],
+ "selected_residue_identity_bits": [bytes([1])],
+ "qcov": [1.0],
+ "tcov": [1.0],
+ "fident": [1.0],
+ "seqsim": [1.0],
+ }
+ if alignment_type == "foldseek":
+ columns["lddt"] = [1.0]
+ pd.DataFrame(columns).to_parquet(release / "shard=ab.parquet", index=False)
+ _write_alignment_mapping_manifest(tmp_path, "ab")
+ with monkeypatch.context() as patch:
+ patch.setattr(
+ tasks,
+ "_alignment_input_signatures",
+ lambda **_kwargs: pytest.fail("finalization rescanned raw alignments"),
+ )
+ patch.setattr(
+ tasks,
+ "alignment_mapping_shard_is_current",
+ lambda **_kwargs: pytest.fail("finalization used the per-shard validator"),
+ )
+ report = finalize_alignment_artifacts(tmp_path)
+ assert report["status"] == "complete"
+ assert report["artifact_counts"]["foldseek_release_shards"] == 1
+ assert report["target_clustering"]["expand_to_chain_level"] is True
+ assert report["skipped_queries"] == {}
+ assert (tmp_path / "alignments/manifest.json").is_file()
+ assert not (tmp_path / "search_databases/manifest.json").exists()
+ assert (tmp_path / "search_databases/holo_foldseek/clustered.dbtype").is_file()
+ assert (
+ tmp_path / "search_databases/holo_mmseqs/cluster_alignments.dbtype"
+ ).is_file()
+ assert not (tmp_path / "search_databases/holo_foldseek/aln").exists()
+ for alignment_type in ["foldseek", "mmseqs"]:
+ bundle = resolve_search_database(alignment_type, data_dir=tmp_path)
+ assert bundle.root == (tmp_path / "search_databases" / f"holo_{alignment_type}")
+
+ skipped = {
+ "1abc": {
+ "reason": "raw_alignment_row_budget_exceeded",
+ "maximum_rows": 1,
+ "total_rows": 2,
+ "rows_by_alignment_type": {"foldseek": 1, "mmseqs": 1},
+ }
+ }
+ for alignment_type in ["foldseek", "mmseqs"]:
+ release = tasks._alignment_release_path(
+ data_dir=tmp_path,
+ search_db="holo",
+ alignment_type=alignment_type,
+ shard="ab",
+ )
+ pq.write_table(
+ pa.Table.from_pylist(
+ [],
+ schema=schemas.release_alignment_mapping_schema(
+ alignment_type=alignment_type
+ ),
+ ),
+ release,
+ )
+ _write_alignment_mapping_manifest(tmp_path, "ab", skipped_queries=skipped)
+
+ with monkeypatch.context() as patch:
+ patch.setattr(
+ tasks,
+ "_alignment_input_signatures",
+ lambda **_kwargs: pytest.fail("finalization rescanned raw alignments"),
+ )
+ skipped_report = finalize_alignment_artifacts(tmp_path)
+ assert skipped_report["skipped_queries"] == skipped
+ assert skipped_report["artifact_counts"]["foldseek_skipped_queries"] == 1
+ assert skipped_report["artifact_counts"]["mmseqs_skipped_queries"] == 1
+
+
+def test_protein_scoring_plan_groups_queries_by_two_character_shard(tmp_path):
+ from plinder.data.pipeline.score import (
+ MANIFEST_RELATIVE,
+ plan_protein_scoring,
+ )
+
+ index_dir = tmp_path / "index"
+ index_dir.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1zzz", "2aaa", "3aab"],
+ "chain_asym_id": ["A", "A", "A"],
+ "chain_receptor_type": ["protein"] * 3,
+ "chain_is_holo": [True] * 3,
+ }
+ ).to_parquet(index_dir / "entry_chains.parquet", index=False)
+
+ plan_protein_scoring(tmp_path)
+
+ manifest = pd.read_parquet(tmp_path / MANIFEST_RELATIVE)
+ assert manifest["pdb_id"].tolist() == ["2aaa", "3aab", "1zzz"]
+ assert manifest["shard"].tolist() == ["aa", "aa", "zz"]
+
+
+def test_score_work_plan_balances_expensive_queries_into_fixed_batches(tmp_path):
+ from plinder.data.pipeline.score import (
+ PLAN_RELATIVE,
+ SCORE_WORK_RELATIVE,
+ _score_batch,
+ plan_protein_scoring,
+ plan_score_batches,
+ )
+
+ pdb_ids = ["1aaa", "2aab", "3aac", "4aad", "5aae"]
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": pdb_ids,
+ "chain_asym_id": ["A"] * len(pdb_ids),
+ "chain_receptor_type": ["protein"] * len(pdb_ids),
+ "chain_is_holo": [True] * len(pdb_ids),
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ annotation_rows = [
+ {
+ "entry_pdb_id": pdb_id,
+ "system_id": f"{pdb_id}__1",
+ "ligand_id": f"{pdb_id}__1__1.{ligand_asym_id}",
+ "ligand_asym_id": ligand_asym_id,
+ "ligand_is_proper": True,
+ "ligand_is_shape_comparable": True,
+ "system_type": "holo",
+ "system_protein_chains_asym_id": ["1.A"],
+ "system_num_protein_chains": 1,
+ "system_num_ligand_chains": 6 if pdb_id == "5aae" else 1,
+ }
+ for pdb_id, ligand_asym_id in zip(pdb_ids, ["L", "M", "N", "O", "P"])
+ ]
+ annotation_rows.extend(
+ {
+ **annotation_rows[-1],
+ "ligand_id": f"5aae__1__1.{ligand_asym_id}",
+ "ligand_asym_id": ligand_asym_id,
+ }
+ for ligand_asym_id in ["Q", "R", "S", "T", "U"]
+ )
+ pd.DataFrame(annotation_rows).to_parquet(
+ index / "annotation_table.parquet", index=False
+ )
+ plan_protein_scoring(tmp_path)
+ chain_path = index / "entry_chains.parquet"
+ chains = pd.read_parquet(chain_path)
+ chains["repair_note"] = "patched after search"
+ chains.to_parquet(chain_path, index=False)
+ release = (
+ tmp_path
+ / "alignment_cigars/search_db=holo/alignment_type=foldseek/shard=aa.parquet"
+ )
+ release.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query_entry": ["1aaa"] * 10 + ["2aab"] * 8 + ["3aac"] + ["4aad"],
+ "target_entry": ["4aad"] * 20,
+ }
+ ).to_parquet(release, index=False)
+
+ with pytest.raises(ValueError, match="entry chain index changed"):
+ plan_score_batches(
+ tmp_path,
+ batch_size=2,
+ threads=1,
+ scratch_dir=tmp_path / "scratch",
+ max_query_protein_chains=5,
+ max_query_proper_ligand_chains=5,
+ )
+
+ report = plan_score_batches(
+ tmp_path,
+ batch_size=2,
+ threads=1,
+ scratch_dir=tmp_path / "scratch",
+ max_query_protein_chains=5,
+ max_query_proper_ligand_chains=5,
+ reuse_mapped_alignments=True,
+ )
+
+ assert report["batch_count"] == 2
+ assert json.loads((tmp_path / PLAN_RELATIVE).read_text())[
+ "score_reused_mapped_alignments"
+ ]
+ work = pd.read_parquet(tmp_path / SCORE_WORK_RELATIVE)
+ assert set(work["pdb_id"]) == set(pdb_ids[:4])
+ assert work.groupby("score_batch_index").size().tolist() == [2, 2]
+ assert work.groupby("score_batch_index")["shard"].nunique().max() == 1
+ batches = work.set_index("pdb_id")["score_batch_index"]
+ assert batches["1aaa"] != batches["2aab"]
+ assert sorted(
+ _score_batch(tmp_path, 0, 2) + _score_batch(tmp_path, 1, 2)
+ ) == sorted(pdb_ids[:4])
+
+
+def test_score_work_plan_ignores_nonproper_ligands_in_query_cap(tmp_path) -> None:
+ from plinder.data.pipeline.score import (
+ SCORE_WORK_RELATIVE,
+ plan_protein_scoring,
+ plan_score_batches,
+ )
+
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"] * 6,
+ "chain_asym_id": list("ABCDEF"),
+ "chain_receptor_type": ["protein", "dna", "dna", "rna", "rna", "rna"],
+ "chain_is_holo": [True] * 6,
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"] * 6,
+ "system_id": ["1abc__1"] * 6,
+ "ligand_id": [f"1abc__1__1.{value}" for value in "LMNOPQ"],
+ "ligand_asym_id": list("LMNOPQ"),
+ "ligand_is_proper": [True, False, False, False, False, False],
+ "ligand_is_shape_comparable": [True] * 6,
+ "system_type": ["holo"] * 6,
+ "system_protein_chains_asym_id": [[f"1.{chain}" for chain in "ABCDEF"]] * 6,
+ "system_num_protein_chains": [6] * 6,
+ "system_num_ligand_chains": [6] * 6,
+ }
+ ).to_parquet(index / "annotation_table.parquet", index=False)
+ plan_protein_scoring(tmp_path)
+ release = (
+ tmp_path
+ / "alignment_cigars/search_db=holo/alignment_type=foldseek/shard=ab.parquet"
+ )
+ release.parent.mkdir(parents=True)
+ pd.DataFrame({"query_entry": ["1abc"], "target_entry": ["1abc"]}).to_parquet(
+ release, index=False
+ )
+
+ plan_score_batches(
+ tmp_path,
+ batch_size=1,
+ threads=1,
+ scratch_dir=tmp_path / "scratch",
+ max_query_protein_chains=5,
+ max_query_proper_ligand_chains=5,
+ )
+
+ assert pd.read_parquet(tmp_path / SCORE_WORK_RELATIVE)["pdb_id"].tolist() == [
+ "1abc"
+ ]
+
+
+def test_score_work_plan_keeps_over_cap_holo_systems_as_targets(tmp_path) -> None:
+ from plinder.data.pipeline.score import (
+ SCORE_WORK_RELATIVE,
+ plan_protein_scoring,
+ plan_score_batches,
+ )
+
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def"],
+ "chain_asym_id": ["A", "A"],
+ "chain_receptor_type": ["protein", "protein"],
+ "chain_is_holo": [True, True],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ rows = [
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": "1abc__1",
+ "ligand_id": "1abc__1__1.L",
+ "ligand_asym_id": "L",
+ "ligand_is_proper": True,
+ "ligand_is_shape_comparable": True,
+ "system_type": "holo",
+ "system_protein_chains_asym_id": ["1.A"],
+ "system_num_protein_chains": 1,
+ "system_num_ligand_chains": 1,
+ }
+ ]
+ rows.extend(
+ {
+ **rows[0],
+ "entry_pdb_id": "2def",
+ "system_id": "2def__1",
+ "ligand_id": f"2def__1__1.{asym_id}",
+ "ligand_asym_id": asym_id,
+ "system_num_ligand_chains": 6,
+ }
+ for asym_id in "LMNOPQ"
+ )
+ pd.DataFrame(rows).to_parquet(index / "annotation_table.parquet", index=False)
+ plan_protein_scoring(tmp_path)
+ release = (
+ tmp_path
+ / "alignment_cigars/search_db=holo/alignment_type=foldseek/shard=ab.parquet"
+ )
+ release.parent.mkdir(parents=True)
+ pd.DataFrame({"query_entry": ["1abc"], "target_entry": ["2def"]}).to_parquet(
+ release, index=False
+ )
+
+ plan_score_batches(
+ tmp_path,
+ batch_size=1,
+ threads=1,
+ scratch_dir=tmp_path / "scratch",
+ max_query_protein_chains=5,
+ max_query_proper_ligand_chains=5,
+ )
+
+ work = pd.read_parquet(tmp_path / SCORE_WORK_RELATIVE).set_index("pdb_id")
+ assert work.index.tolist() == ["1abc"]
+ assert work.loc["1abc", "ligand_pair_work"] == 6
+ assert work.loc["1abc", "canonical_3d_work"] == 6
+
+
+def test_score_manifest_batch_supports_single_pdb_retries(tmp_path) -> None:
+ from plinder.data.pipeline.score import _score_manifest_batch
+
+ manifest = tmp_path / "retry.parquet"
+ pd.DataFrame({"pdb_id": ["1abc", "2def", "3ghi"]}).to_parquet(manifest, index=False)
+
+ assert _score_manifest_batch(tmp_path, manifest, 0, 1) == ["1abc"]
+ assert _score_manifest_batch(tmp_path, manifest, 1, 1) == ["2def"]
+ assert _score_manifest_batch(tmp_path, manifest, 1, 2) == ["3ghi"]
+
+ pd.DataFrame(
+ {
+ "pdb_id": ["1abc", "2def", "3ghi"],
+ "retry_batch_index": [1, 0, 1],
+ }
+ ).to_parquet(manifest, index=False)
+ assert _score_manifest_batch(tmp_path, manifest, 0, 2) == ["2def"]
+ assert _score_manifest_batch(tmp_path, manifest, 1, 2) == ["1abc", "3ghi"]
+
+
+def test_repair_batch_assignment_balances_a_remainder() -> None:
+ from plinder.data.pipeline.score import _assign_repair_batches
+
+ records = [
+ {"pdb_id": f"query-{index:03}", "estimated_work": 1} for index in range(101)
+ ]
+
+ batch_count = _assign_repair_batches(
+ records,
+ batch_size=100,
+ index_offset=7,
+ )
+
+ counts = pd.Series(
+ [record["repair_batch_index"] for record in records]
+ ).value_counts()
+ assert batch_count == 2
+ assert set(counts.index) == {7, 8}
+ assert sorted(counts.tolist()) == [50, 51]
+
+
+def test_score_repair_plans_full_and_target_only_queries(
+ tmp_path: Path,
+) -> None:
+ from plinder.data.pipeline.score import (
+ MANIFEST_RELATIVE,
+ PLAN_RELATIVE,
+ SCORE_WORK_RELATIVE,
+ _score_repair_batch,
+ _source_signature,
+ plan_score_repair,
+ )
+
+ query_manifest = tmp_path / MANIFEST_RELATIVE
+ query_manifest.parent.mkdir(parents=True)
+ pd.DataFrame({"pdb_id": ["1abc", "2def", "3ghi", "4jkl"]}).to_parquet(
+ query_manifest, index=False
+ )
+ (tmp_path / PLAN_RELATIVE).write_text(
+ json.dumps(
+ {
+ "manifest": _source_signature(query_manifest),
+ "score_max_query_protein_chains": 5,
+ "score_max_query_proper_ligand_chains": 5,
+ }
+ )
+ )
+ work = tmp_path / SCORE_WORK_RELATIVE
+ pd.DataFrame(
+ {
+ "pdb_id": ["1abc", "2def", "3ghi"],
+ "estimated_work": [10, 20, 30],
+ }
+ ).to_parquet(work, index=False)
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def", "3ghi"],
+ "system_id": ["1abc__1", "2def__1", "3ghi__1"],
+ "ligand_id": ["1abc__1__1.L", "2def__1__1.L", "3ghi__1__1.L"],
+ "system_type": ["holo", "holo", "holo"],
+ "system_protein_chains_asym_id": [["1.A"], ["1.A"], ["1.A"]],
+ "ligand_is_proper": [True, True, True],
+ }
+ ).to_parquet(index / "annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def", "3ghi"],
+ "chain_asym_id": ["A", "A", "A"],
+ "chain_receptor_type": ["protein", "protein", "protein"],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ alignment = (
+ tmp_path
+ / "alignment_cigars/search_db=holo/alignment_type=foldseek/shard=ab.parquet"
+ )
+ alignment.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query_entry": ["1abc", "1abc", "1abc", "3ghi", "9zzz"],
+ "target_entry": ["2def", "2def", "4jkl", "8nop", "2def"],
+ }
+ ).to_parquet(alignment, index=False)
+ target_score = tmp_path / "dbs/subdbs/search_db=holo/1abc.parquet"
+ target_score.parent.mkdir(parents=True)
+ target_score.touch()
+ target_candidates = (
+ tmp_path / "scores/ligand_3d_candidates/search_db=holo/shard=ab/1abc.parquet"
+ )
+ target_ligand_pair_scores = (
+ tmp_path / "scores/ligand_pair_scores/search_db=holo/shard=ab/1abc.parquet"
+ )
+ target_candidates.parent.mkdir(parents=True)
+ target_ligand_pair_scores.parent.mkdir(parents=True)
+ target_candidates.touch()
+ target_ligand_pair_scores.touch()
+ packed_candidates = tmp_path / "scores/ligand_3d_candidate_shards/shard=jk.parquet"
+ packed_candidates.parent.mkdir(parents=True)
+ pd.DataFrame({"query_entry": ["4jkl"]}).to_parquet(packed_candidates, index=False)
+ affected = tmp_path / "affected.txt"
+ affected.write_text("2def\n4jkl\n")
+ additional_full = tmp_path / "additional_full.txt"
+ additional_full.write_text("3ghi\n9zzz\n")
+
+ report = plan_score_repair(
+ tmp_path,
+ affected_manifest=affected,
+ additional_full_query_manifest=additional_full,
+ batch_size=2,
+ )
+
+ assert report["full_query_count"] == 2
+ assert report["cache_missing_full_query_count"] == 0
+ assert report["additional_full_query_count"] == 1
+ assert report["ignored_additional_full_query_count"] == 1
+ assert report["dropped_query_count"] == 1
+ assert report["target_only_query_count"] == 1
+ assert report["batch_count"] == 2
+ assert report["full_query_batch_count"] == 1
+ assert report["target_query_batch_count"] == 1
+ repairs = [
+ *_score_repair_batch(
+ tmp_path / "manifests/score_repair.parquet",
+ batch_index=0,
+ batch_size=2,
+ ),
+ *_score_repair_batch(
+ tmp_path / "manifests/score_repair.parquet",
+ batch_index=1,
+ batch_size=2,
+ ),
+ ]
+ repair_by_query = {str(repair["pdb_id"]): repair for repair in repairs}
+ assert repair_by_query["2def"]["repair_mode"] == "full"
+ assert repair_by_query["3ghi"]["repair_mode"] == "full"
+ assert repair_by_query["4jkl"]["repair_mode"] == "drop"
+ assert list(repair_by_query["1abc"]["target_pdb_ids"]) == ["2def", "4jkl"]
+
+
+def test_score_repair_promotes_target_query_when_cache_is_missing(
+ tmp_path: Path,
+) -> None:
+ from plinder.data.pipeline.score import (
+ MANIFEST_RELATIVE,
+ PLAN_RELATIVE,
+ _source_signature,
+ plan_score_repair,
+ )
+
+ query_manifest = tmp_path / MANIFEST_RELATIVE
+ query_manifest.parent.mkdir(parents=True)
+ pd.DataFrame({"pdb_id": ["1abc", "2def"]}).to_parquet(query_manifest, index=False)
+ pd.DataFrame({"pdb_id": ["1abc", "2def"], "estimated_work": [1, 1]}).to_parquet(
+ tmp_path / "manifests/protein_scoring_work.parquet", index=False
+ )
+ (tmp_path / PLAN_RELATIVE).write_text(
+ json.dumps(
+ {
+ "manifest": _source_signature(query_manifest),
+ "score_max_query_protein_chains": 5,
+ "score_max_query_proper_ligand_chains": 5,
+ }
+ )
+ )
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def"],
+ "system_id": ["1abc__1", "2def__1"],
+ "ligand_id": ["1abc__1__1.L", "2def__1__1.L"],
+ "system_type": ["holo", "holo"],
+ "system_protein_chains_asym_id": [["1.A"], ["1.A"]],
+ "ligand_is_proper": [True, True],
+ }
+ ).to_parquet(index / "annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def"],
+ "chain_asym_id": ["A", "A"],
+ "chain_receptor_type": ["protein", "protein"],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ alignment = (
+ tmp_path
+ / "alignment_cigars/search_db=holo/alignment_type=foldseek/shard=ab.parquet"
+ )
+ alignment.parent.mkdir(parents=True)
+ pd.DataFrame({"query_entry": ["1abc"], "target_entry": ["2def"]}).to_parquet(
+ alignment, index=False
+ )
+ affected = tmp_path / "affected.txt"
+ affected.write_text("2def\n")
+
+ report = plan_score_repair(tmp_path, affected_manifest=affected)
+
+ assert report["full_query_count"] == 2
+ assert report["cache_missing_full_query_count"] == 1
+ assert report["target_only_query_count"] == 0
+ plan = pd.read_parquet(tmp_path / "manifests/score_repair.parquet")
+ assert set(plan["pdb_id"]) == {"1abc", "2def"}
+ assert set(plan["repair_mode"]) == {"full"}
+
+
+def test_score_repair_keeps_query_when_affected_hit_disappears(tmp_path: Path) -> None:
+ from plinder.data.pipeline.score import (
+ MANIFEST_RELATIVE,
+ PLAN_RELATIVE,
+ _source_signature,
+ plan_score_repair,
+ )
+
+ query_manifest = tmp_path / MANIFEST_RELATIVE
+ query_manifest.parent.mkdir(parents=True)
+ pd.DataFrame({"pdb_id": ["1abc", "2def"]}).to_parquet(query_manifest, index=False)
+ (tmp_path / PLAN_RELATIVE).write_text(
+ json.dumps(
+ {
+ "manifest": _source_signature(query_manifest),
+ "score_max_query_protein_chains": 5,
+ "score_max_query_proper_ligand_chains": 5,
+ }
+ )
+ )
+ pd.DataFrame({"pdb_id": ["1abc", "2def"], "estimated_work": [1, 1]}).to_parquet(
+ tmp_path / "manifests/protein_scoring_work.parquet", index=False
+ )
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def"],
+ "system_id": ["1abc__1", "2def__1"],
+ "ligand_id": ["1abc__1__1.L", "2def__1__1.L"],
+ "system_type": ["holo", "holo"],
+ "system_protein_chains_asym_id": [["1.A"], ["1.A"]],
+ "ligand_is_proper": [True, True],
+ }
+ ).to_parquet(index / "annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def"],
+ "chain_asym_id": ["A", "A"],
+ "chain_receptor_type": ["protein", "protein"],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ alignment = (
+ tmp_path
+ / "alignment_cigars/search_db=holo/alignment_type=foldseek/shard=ab.parquet"
+ )
+ alignment.parent.mkdir(parents=True)
+ pd.DataFrame({"query_entry": ["1abc"], "target_entry": ["3ghi"]}).to_parquet(
+ alignment, index=False
+ )
+ for path in (
+ tmp_path / "dbs/subdbs/search_db=holo/1abc.parquet",
+ tmp_path / "scores/ligand_3d_candidates/search_db=holo/shard=ab/1abc.parquet",
+ tmp_path / "scores/ligand_pair_scores/search_db=holo/shard=ab/1abc.parquet",
+ ):
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.touch()
+ affected = tmp_path / "affected.txt"
+ affected.write_text("2def\n")
+ old_queries = tmp_path / "old-queries.txt"
+ old_queries.write_text("1abc\n")
+
+ report = plan_score_repair(
+ tmp_path,
+ affected_manifest=affected,
+ additional_target_query_manifest=old_queries,
+ )
+
+ assert report["target_only_query_count"] == 1
+ plan = pd.read_parquet(tmp_path / "manifests/score_repair.parquet")
+ row = plan.set_index("pdb_id").loc["1abc"]
+ assert row["repair_mode"] == "targets"
+ assert list(row["target_pdb_ids"]) == ["2def"]
+
+
+def test_bounded_score_repair_reverses_only_existing_target_candidates(
+ tmp_path: Path,
+) -> None:
+ from plinder.data.pipeline.score import (
+ BOUNDED_SCORE_REPAIR_RELATIVE,
+ DROPPED_QUERY_RELATIVE,
+ plan_bounded_score_repair,
+ published_scoring_query_ids,
+ )
+
+ dropped = tmp_path / DROPPED_QUERY_RELATIVE
+ dropped.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "pdb_id": ["2def", "3ghi", "4jkl"],
+ "stage": ["derived_scoring", "mapping", "derived_scoring"],
+ }
+ ).to_parquet(dropped, index=False)
+ work = tmp_path / "manifests/protein_scoring_work.parquet"
+ pd.DataFrame({"pdb_id": ["1abc", "2def", "5mno"]}).to_parquet(work, index=False)
+ candidate_dir = tmp_path / "scores/ligand_3d_candidate_shards"
+ candidate_dir.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query_entry": ["1abc", "5mno", "1abc", "5mno"],
+ "target_entry": ["2def", "2def", "4jkl", "3ghi"],
+ "query_system": ["1abc_s1", "5mno_s1", "1abc_s2", "5mno_s2"],
+ "query_ligand_id": ["1abc_l1", "5mno_l1", "1abc_l2", "5mno_l2"],
+ "target_system": ["2def_s1", "2def_s2", "4jkl_s1", "3ghi_s1"],
+ "target_ligand_id": ["2def_l1", "2def_l2", "4jkl_l1", "3ghi_l1"],
+ "pocket_qcov": [0.5, 0.8, 0.0, 0.7],
+ }
+ ).to_parquet(candidate_dir / "shard=ab.parquet", index=False)
+
+ requested = tmp_path / "bounded.txt"
+ requested.write_text("2def\n4jkl\n")
+ report = plan_bounded_score_repair(
+ tmp_path, pdb_manifest=requested, batch_size=1, threads=1
+ )
+
+ assert report["requested_query_count"] == 2
+ assert report["planned_query_count"] == 1
+ assert report["queries_without_incoming_candidates"] == ["4jkl"]
+ plan = pd.read_parquet(tmp_path / BOUNDED_SCORE_REPAIR_RELATIVE)
+ assert plan.loc[0, "pdb_id"] == "2def"
+ assert plan.loc[0, "repair_mode"] == "bounded"
+ assert list(plan.loc[0, "target_pdb_ids"]) == ["1abc", "5mno"]
+ assert list(plan.loc[0, "query_system_ids"]) == ["2def_s1", "2def_s2"]
+ assert list(plan.loc[0, "query_ligand_ids"]) == ["2def_l1", "2def_l2"]
+ assert list(plan.loc[0, "target_system_ids"]) == ["1abc_s1", "5mno_s1"]
+ assert list(plan.loc[0, "target_ligand_ids"]) == ["1abc_l1", "5mno_l1"]
+ assert published_scoring_query_ids(tmp_path) == {"1abc", "5mno"}
+ score = tmp_path / "dbs/subdbs/search_db=holo/2def.parquet"
+ candidate = (
+ tmp_path / "scores/ligand_3d_candidates/search_db=holo/shard=de/2def.parquet"
+ )
+ ligand_pair_scores = (
+ tmp_path / "scores/ligand_pair_scores/search_db=holo/shard=de/2def.parquet"
+ )
+ score.parent.mkdir(parents=True)
+ candidate.parent.mkdir(parents=True)
+ ligand_pair_scores.parent.mkdir(parents=True)
+ score.touch()
+ candidate.touch()
+ ligand_pair_scores.touch()
+ assert published_scoring_query_ids(tmp_path) == {"1abc", "2def", "5mno"}
+ invalid = tmp_path / "invalid-bounded.txt"
+ invalid.write_text("3ghi\n")
+ with pytest.raises(ValueError, match="derived-scoring query drops"):
+ plan_bounded_score_repair(
+ tmp_path, pdb_manifest=invalid, batch_size=1, threads=1
+ )
+
+
+def test_repair_batch_scores_uses_full_and_target_only_paths(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ calls: list[tuple[str, str, object]] = []
+
+ class FakeScorer:
+ shape_score_threads = 0
+
+ def get_score_df(self, _data_dir, pdb_id, **kwargs):
+ calls.append(("full", pdb_id, kwargs["defer_ligand_3d"]))
+
+ def repair_score_df_targets(
+ self,
+ _data_dir,
+ pdb_id,
+ *,
+ affected_target_entries,
+ allow_missing=False,
+ **_kwargs,
+ ):
+ calls.append(
+ (
+ "bounded" if allow_missing else "targets",
+ pdb_id,
+ affected_target_entries,
+ )
+ )
+
+ monkeypatch.setattr(
+ tasks.utils,
+ "get_scorer",
+ lambda **_kwargs: (FakeScorer(), ["1abc", "2def"], tmp_path / "db"),
+ )
+
+ tasks.repair_batch_scores(
+ data_dir=tmp_path,
+ repairs=[
+ {
+ "pdb_id": "1abc",
+ "repair_mode": "targets",
+ "target_pdb_ids": ["2def"],
+ },
+ {
+ "pdb_id": "3ghi",
+ "repair_mode": "bounded",
+ "target_pdb_ids": ["1abc"],
+ "query_system_ids": ["3ghi_s1"],
+ "query_ligand_ids": ["3ghi_l1"],
+ "target_system_ids": ["1abc_s1"],
+ "target_ligand_ids": ["1abc_l1"],
+ },
+ {"pdb_id": "2def", "repair_mode": "full", "target_pdb_ids": []},
+ ],
+ scorer_cfg=SimpleNamespace(sub_databases=["holo"]),
+ scratch_dir=tmp_path / "scratch",
+ threads=2,
+ )
+
+ assert calls == [
+ ("targets", "1abc", {"2def"}),
+ ("bounded", "3ghi", {"1abc"}),
+ ("full", "2def", True),
+ ]
+
+
+def test_repair_batch_scores_drops_queries_that_are_no_longer_eligible(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ score = tmp_path / "dbs/subdbs/search_db=holo/1abc.parquet"
+ candidate = (
+ tmp_path / "scores/ligand_3d_candidates/search_db=holo/shard=ab/1abc.parquet"
+ )
+ ligand_pair_scores = (
+ tmp_path / "scores/ligand_pair_scores/search_db=holo/shard=ab/1abc.parquet"
+ )
+ score.parent.mkdir(parents=True)
+ candidate.parent.mkdir(parents=True)
+ ligand_pair_scores.parent.mkdir(parents=True)
+ score.touch()
+ candidate.touch()
+ ligand_pair_scores.touch()
+
+ monkeypatch.setattr(
+ tasks.utils,
+ "get_scorer",
+ lambda **_kwargs: pytest.fail("drop-only repair must not create a scorer"),
+ )
+
+ tasks.repair_batch_scores(
+ data_dir=tmp_path,
+ repairs=[{"pdb_id": "1abc", "repair_mode": "drop", "target_pdb_ids": []}],
+ scorer_cfg=SimpleNamespace(sub_databases=["holo"]),
+ scratch_dir=tmp_path / "scratch",
+ )
+
+ assert not score.exists()
+ assert not candidate.exists()
+ assert not ligand_pair_scores.exists()
+
+
+def test_repair_target_remainders_drops_stalled_query_and_resumes_followers(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ from plinder.data.pipeline import score as score_pipeline
+
+ repair_manifest = tmp_path / "repair.parquet"
+ pd.DataFrame(
+ {
+ "pdb_id": ["1abc", "2def", "3ghi"],
+ "repair_mode": ["targets", "targets", "targets"],
+ "target_pdb_ids": [["9xyz"], ["9xyz"], ["9xyz"]],
+ "repair_batch_index": [0, 0, 0],
+ }
+ ).to_parquet(repair_manifest, index=False)
+ score, candidate, ligand_pair_scores = score_pipeline._score_repair_query_paths(
+ tmp_path, "1abc"
+ )
+ score.parent.mkdir(parents=True)
+ candidate.parent.mkdir(parents=True)
+ ligand_pair_scores.parent.mkdir(parents=True)
+ score.touch()
+ candidate.touch()
+ ligand_pair_scores.touch()
+ completed_ns = repair_manifest.stat().st_mtime_ns + 1_000_000_000
+ os.utime(score, ns=(completed_ns, completed_ns))
+ os.utime(candidate, ns=(completed_ns, completed_ns))
+ os.utime(ligand_pair_scores, ns=(completed_ns, completed_ns))
+ captured: list[dict[str, object]] = []
+
+ def fake_repair_batch_scores(**kwargs) -> None:
+ captured.extend(kwargs["repairs"])
+
+ monkeypatch.setattr(tasks, "repair_batch_scores", fake_repair_batch_scores)
+
+ report = score_pipeline.repair_target_score_remainders(
+ tmp_path,
+ repair_manifest=repair_manifest,
+ batch_index=0,
+ batch_size=3,
+ scorer_cfg=SimpleNamespace(),
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ )
+
+ assert report["dropped_query"] == "2def"
+ assert report["resumed_query_count"] == 1
+ assert [repair["pdb_id"] for repair in captured] == ["3ghi"]
+ marker_dir = score_pipeline._score_repair_marker_dir(tmp_path, repair_manifest)
+ marker = json.loads((marker_dir / "2def.json").read_text())
+ assert marker["pdb_id"] == "2def"
+ (marker_dir / "concurrent.tmp.json").write_text("{")
+
+ second_report = score_pipeline.repair_target_score_remainders(
+ tmp_path,
+ repair_manifest=repair_manifest,
+ batch_index=0,
+ batch_size=3,
+ scorer_cfg=SimpleNamespace(),
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ )
+
+ assert second_report["dropped_query"] == "3ghi"
+ assert second_report["resumed_query_count"] == 0
+ assert score_pipeline._score_repair_marked_targets(tmp_path, repair_manifest) == {
+ "2def",
+ "3ghi",
+ }
+
+
+def test_repair_target_remainders_removes_planned_drops_without_marking_them(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ from plinder.data.pipeline import score as score_pipeline
+
+ repair_manifest = tmp_path / "repair.parquet"
+ pd.DataFrame(
+ {
+ "pdb_id": ["1abc", "2def"],
+ "repair_mode": ["drop", "targets"],
+ "target_pdb_ids": [[], ["9xyz"]],
+ "repair_batch_index": [0, 0],
+ }
+ ).to_parquet(repair_manifest, index=False)
+ for pdb_id in ["1abc", "2def"]:
+ score, candidate, ligand_pair_scores = score_pipeline._score_repair_query_paths(
+ tmp_path, pdb_id
+ )
+ score.parent.mkdir(parents=True, exist_ok=True)
+ candidate.parent.mkdir(parents=True, exist_ok=True)
+ ligand_pair_scores.parent.mkdir(parents=True, exist_ok=True)
+ score.touch()
+ candidate.touch()
+ ligand_pair_scores.touch()
+ completed_ns = repair_manifest.stat().st_mtime_ns + 1_000_000_000
+ for path in score_pipeline._score_repair_query_paths(tmp_path, "2def"):
+ os.utime(path, ns=(completed_ns, completed_ns))
+
+ monkeypatch.setattr(
+ tasks,
+ "repair_batch_scores",
+ lambda **_kwargs: pytest.fail("no target repair should be needed"),
+ )
+
+ report = score_pipeline.repair_target_score_remainders(
+ tmp_path,
+ repair_manifest=repair_manifest,
+ batch_index=0,
+ batch_size=2,
+ scorer_cfg=SimpleNamespace(),
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ )
+
+ assert report["dropped_query"] is None
+ assert report["resumed_query_count"] == 0
+ assert not any(
+ path.exists()
+ for path in score_pipeline._score_repair_query_paths(tmp_path, "1abc")
+ )
+ assert not score_pipeline._score_repair_marker_dir(
+ tmp_path, repair_manifest
+ ).exists()
+
+
+def test_finalize_score_repair_records_marked_targets_and_incomplete_full_queries(
+ tmp_path: Path,
+) -> None:
+ from plinder.data.pipeline import score as score_pipeline
+
+ repair_manifest = tmp_path / "repair.parquet"
+ pd.DataFrame(
+ {
+ "pdb_id": ["1abc", "2def", "3ghi"],
+ "repair_mode": ["targets", "targets", "full"],
+ }
+ ).to_parquet(repair_manifest, index=False)
+ (
+ current_score,
+ current_candidate,
+ current_ligand_pair_scores,
+ ) = score_pipeline._score_repair_query_paths(tmp_path, "1abc")
+ current_score.parent.mkdir(parents=True)
+ current_candidate.parent.mkdir(parents=True)
+ current_ligand_pair_scores.parent.mkdir(parents=True)
+ current_score.touch()
+ current_candidate.touch()
+ current_ligand_pair_scores.touch()
+ completed_ns = repair_manifest.stat().st_mtime_ns + 1_000_000_000
+ os.utime(current_score, ns=(completed_ns, completed_ns))
+ os.utime(current_candidate, ns=(completed_ns, completed_ns))
+ os.utime(current_ligand_pair_scores, ns=(completed_ns, completed_ns))
+ marker_dir = score_pipeline._score_repair_marker_dir(tmp_path, repair_manifest)
+ marker = marker_dir / "2def.json"
+ marker.parent.mkdir(parents=True)
+ marker.write_text(
+ json.dumps(
+ {
+ "pdb_id": "2def",
+ "repair_run_id": score_pipeline._score_repair_run_id(repair_manifest),
+ "repair_batch_index": 4,
+ "repair_mode": "targets",
+ "reason": "resource_limit",
+ }
+ )
+ )
+ existing = tmp_path / score_pipeline.DROPPED_QUERY_RELATIVE
+ existing.parent.mkdir(parents=True, exist_ok=True)
+ pd.DataFrame(
+ {
+ "pdb_id": ["4jkl"],
+ "stage": ["derived_scoring"],
+ "reason": ["resource_limit"],
+ "details": ["{}"],
+ }
+ ).to_parquet(existing, index=False)
+ plan = tmp_path / score_pipeline.PLAN_RELATIVE
+ plan.write_text("{}")
+
+ report = score_pipeline.finalize_score_repair_queries(
+ tmp_path,
+ repair_manifest=repair_manifest,
+ max_new_drops=2,
+ )
+
+ assert report["new_target_query_drops"] == 1
+ assert report["new_full_query_drops"] == 1
+ dropped = pd.read_parquet(tmp_path / score_pipeline.DROPPED_QUERY_RELATIVE)
+ assert set(dropped["pdb_id"].astype(str)) == {"2def", "3ghi", "4jkl"}
+
+
+def test_score_repair_scores_only_new_canonical_ligand_pairs(
+ tmp_path: Path,
+) -> None:
+ from plinder.data.pipeline.score import (
+ SCORE_REPAIR_LIGAND_3D_RELATIVE,
+ merge_score_repair_ligand_3d,
+ plan_score_repair_ligand_3d,
+ )
+
+ repair_manifest = tmp_path / "repair.parquet"
+ pd.DataFrame({"pdb_id": ["1abc"], "shard": ["ab"]}).to_parquet(
+ repair_manifest, index=False
+ )
+ candidate = tmp_path / "scores/ligand_3d_pair_candidate_shards/shard=ab.parquet"
+ candidate.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query_entry": ["1abc", "1abc"],
+ "query_ligand_asym_id": ["B", "B"],
+ "target_entry": ["2def", "3ghi"],
+ "target_ligand_asym_id": ["Y", "Z"],
+ "pocket_qcov": [0.5, 0.7],
+ }
+ ).to_parquet(candidate, index=False)
+ cached = tmp_path / "scores/ligand_3d_by_query/ab.parquet"
+ cached.parent.mkdir(parents=True)
+ cached_row = {
+ "query_entry": "1abc",
+ "query_ligand_asym_id": "B",
+ "target_entry": "2def",
+ "target_ligand_asym_id": "Y",
+ "shape": 0.5,
+ "color": 0.4,
+ "sucos_shape": 0.3,
+ }
+ pd.DataFrame([cached_row]).to_parquet(
+ cached, index=False, schema=schemas.LIGAND_3D_SCORE_SCHEMA
+ )
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def", "3ghi"],
+ "ligand_asym_id": ["B", "Y", "Z"],
+ "ligand_num_heavy_atoms": [10, 20, 30],
+ "ligand_is_proper": [True, True, True],
+ "ligand_is_shape_comparable": [True, True, True],
+ "system_type": ["holo", "holo", "holo"],
+ }
+ ).to_parquet(index / "annotation_table.parquet", index=False)
+
+ report = plan_score_repair_ligand_3d(
+ tmp_path,
+ repair_manifest=repair_manifest,
+ batch_size=10,
+ threads=1,
+ scratch_dir=tmp_path / "plan-scratch",
+ memory_limit="1GB",
+ )
+
+ assert report["pair_count"] == 1
+ work = pd.read_parquet(tmp_path / SCORE_REPAIR_LIGAND_3D_RELATIVE)
+ assert work[["query_entry", "target_entry"]].to_dict("records") == [
+ {"query_entry": "1abc", "target_entry": "3ghi"}
+ ]
+ repaired = work[
+ [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ ].copy()
+ repaired["shape"] = 0.8
+ repaired["color"] = 0.7
+ repaired["sucos_shape"] = 0.6
+ repair_score = tmp_path / "scores/ligand_3d_pair_repairs/0.parquet"
+ repair_score.parent.mkdir()
+ repaired.to_parquet(
+ repair_score, index=False, schema=schemas.LIGAND_3D_SCORE_SCHEMA
+ )
+
+ merge_score_repair_ligand_3d(
+ tmp_path,
+ shards=["ab"],
+ scratch_dir=tmp_path / "merge-scratch",
+ threads=1,
+ )
+
+ merged = pd.read_parquet(cached)
+ assert set(merged["target_entry"]) == {"2def", "3ghi"}
+ merged_mtime = cached.stat().st_mtime_ns
+ merge_score_repair_ligand_3d(
+ tmp_path,
+ shards=["ab"],
+ scratch_dir=tmp_path / "merge-scratch",
+ threads=1,
+ )
+ assert cached.stat().st_mtime_ns == merged_mtime
+
+
+def test_dropped_queries_combine_mapping_and_scoring_stages(tmp_path) -> None:
+ from plinder.data.pipeline.score import (
+ DROPPED_QUERY_RELATIVE,
+ MANIFEST_RELATIVE,
+ PLAN_RELATIVE,
+ SCORE_WORK_RELATIVE,
+ _score_batch,
+ _source_signature,
+ active_scoring_query_ids,
+ record_dropped_queries,
+ )
+
+ query_ids = ["1abc", "2def", "3ghi", "4jkl"]
+ query_manifest = tmp_path / MANIFEST_RELATIVE
+ query_manifest.parent.mkdir(parents=True)
+ pd.DataFrame({"pdb_id": query_ids}).to_parquet(query_manifest, index=False)
+ score_work = tmp_path / SCORE_WORK_RELATIVE
+ pd.DataFrame(
+ {
+ "pdb_id": query_ids,
+ "score_batch_index": [0, 0, 0, 0],
+ "estimated_work": [4.0, 3.0, 2.0, 1.0],
+ }
+ ).to_parquet(score_work, index=False)
+ (tmp_path / PLAN_RELATIVE).write_text(
+ json.dumps(
+ {
+ "manifest": _source_signature(query_manifest),
+ "score_work": _source_signature(score_work),
+ "score_batch_size": 4,
+ }
+ )
+ )
+ alignment_manifest = tmp_path / "alignments" / "manifest.json"
+ alignment_manifest.parent.mkdir()
+ alignment_manifest.write_text(
+ json.dumps(
+ {
+ "skipped_queries": {
+ "1abc": {
+ "reason": "raw_alignment_row_budget_exceeded",
+ "total_rows": 6_000_000,
+ }
+ }
+ }
+ )
+ )
+ score_drops = tmp_path / "score-drops.parquet"
+ pd.DataFrame({"pdb_id": ["2def", "3ghi"]}).to_parquet(score_drops, index=False)
+
+ report = record_dropped_queries(
+ tmp_path,
+ score_query_manifest=score_drops,
+ )
+
+ assert report["alignment_mapping"] == 1
+ assert report["derived_scoring"] == 2
+ assert report["total"] == 3
+ dropped = pd.read_parquet(tmp_path / DROPPED_QUERY_RELATIVE)
+ assert dropped[["pdb_id", "stage"]].to_dict("records") == [
+ {"pdb_id": "1abc", "stage": "alignment_mapping"},
+ {"pdb_id": "2def", "stage": "derived_scoring"},
+ {"pdb_id": "3ghi", "stage": "derived_scoring"},
+ ]
+ assert active_scoring_query_ids(tmp_path) == {"4jkl"}
+ assert _score_batch(tmp_path, 0, 4) == ["4jkl"]
+
+
+@pytest.mark.parametrize(
+ "mapping_id,score_id,invalid",
+ [("2def", None, False), ("9zzz", None, True), (None, "2def", True)],
+)
+def test_dropped_queries_validate_each_stage_against_its_plan(
+ tmp_path, mapping_id, score_id, invalid
+) -> None:
+ from plinder.data.pipeline.score import (
+ DROPPED_QUERY_RELATIVE,
+ MANIFEST_RELATIVE,
+ PLAN_RELATIVE,
+ SCORE_WORK_RELATIVE,
+ _source_signature,
+ record_dropped_queries,
+ )
+
+ query_manifest = tmp_path / MANIFEST_RELATIVE
+ query_manifest.parent.mkdir(parents=True)
+ pd.DataFrame({"pdb_id": ["1abc", "2def"]}).to_parquet(query_manifest, index=False)
+ pd.DataFrame({"pdb_id": ["1abc"]}).to_parquet(
+ tmp_path / SCORE_WORK_RELATIVE, index=False
+ )
+ write_json_atomic(
+ tmp_path / PLAN_RELATIVE, {"manifest": _source_signature(query_manifest)}
+ )
+ alignment_manifest = tmp_path / "alignments/manifest.json"
+ write_json_atomic(
+ alignment_manifest,
+ {
+ "skipped_queries": (
+ {mapping_id: {"reason": "raw_alignment_row_budget_exceeded"}}
+ if mapping_id
+ else {}
+ )
+ },
+ )
+ score_drops = tmp_path / "score-drops.parquet"
+ pd.DataFrame(
+ {"pdb_id": pd.Series([score_id] if score_id else [], dtype="str")}
+ ).to_parquet(score_drops, index=False)
+
+ if invalid:
+ with pytest.raises(ValueError, match="dropped queries are absent"):
+ record_dropped_queries(tmp_path, score_query_manifest=score_drops)
+ assert not (tmp_path / DROPPED_QUERY_RELATIVE).exists()
+ else:
+ report = record_dropped_queries(tmp_path, score_query_manifest=score_drops)
+ assert report["alignment_mapping"] == 1
+ assert report["derived_scoring"] == 0
+ assert pd.read_parquet(tmp_path / DROPPED_QUERY_RELATIVE)[
+ ["pdb_id", "stage"]
+ ].to_dict("records") == [{"pdb_id": "2def", "stage": "alignment_mapping"}]
+
+
+def test_ligand_3d_retries_require_and_reassemble_every_retry(tmp_path) -> None:
+ from plinder.data.pipeline.score import (
+ LIGAND_3D_RETRY_WORK_RELATIVE,
+ LIGAND_3D_WORK_RELATIVE,
+ MANIFEST_RELATIVE,
+ PLAN_RELATIVE,
+ _source_signature,
+ finalize_ligand_3d_retries,
+ plan_ligand_3d_retries,
+ )
+
+ query_manifest = tmp_path / MANIFEST_RELATIVE
+ query_manifest.parent.mkdir(parents=True)
+ pd.DataFrame({"pdb_id": ["1abc"]}).to_parquet(query_manifest, index=False)
+ pair_rows = pd.DataFrame(
+ {
+ "query_entry": ["1abc", "1abc", "1abc"],
+ "query_ligand_asym_id": ["A", "A", "A"],
+ "target_entry": ["2def", "3ghi", "4jkl"],
+ "target_ligand_asym_id": ["B", "C", "D"],
+ "estimated_work": [3, 2, 1],
+ "ligand_3d_batch_index": [0, 1, 1],
+ }
+ )
+ work_path = tmp_path / LIGAND_3D_WORK_RELATIVE
+ pair_rows.to_parquet(work_path, index=False)
+ (tmp_path / PLAN_RELATIVE).write_text(
+ json.dumps(
+ {
+ "manifest": _source_signature(query_manifest),
+ "ligand_3d_plan_complete": True,
+ "ligand_3d_batch_count": 2,
+ "ligand_3d_work": _source_signature(work_path),
+ }
+ )
+ )
+ canonical = tmp_path / "scores" / "ligand_3d_pairs"
+ canonical.mkdir(parents=True)
+ completed = pair_rows.iloc[[0]][
+ [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ ].copy()
+ completed["shape"] = 0.5
+ completed["color"] = 0.4
+ completed["sucos_shape"] = 0.3
+ completed.to_parquet(
+ canonical / "0.parquet",
+ schema=schemas.LIGAND_3D_SCORE_SCHEMA,
+ index=False,
+ )
+
+ report = plan_ligand_3d_retries(tmp_path, batch_size=1)
+ assert report["missing_original_batch_count"] == 1
+ assert report["retry_batch_count"] == 2
+ retry_work = pd.read_parquet(tmp_path / LIGAND_3D_RETRY_WORK_RELATIVE)
+ first_retry = retry_work[retry_work["retry_batch_index"].eq(0)]
+ scored = first_retry[
+ [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ ].copy()
+ scored["shape"] = 0.8
+ scored["color"] = 0.7
+ scored["sucos_shape"] = 0.6
+ retry_dir = tmp_path / "scores" / "ligand_3d_pair_retries"
+ retry_dir.mkdir()
+ scored.to_parquet(
+ retry_dir / "0.parquet",
+ schema=schemas.LIGAND_3D_SCORE_SCHEMA,
+ index=False,
+ )
+
+ with pytest.raises(ValueError, match="retries remain incomplete"):
+ finalize_ligand_3d_retries(tmp_path)
+
+ second_retry = retry_work[retry_work["retry_batch_index"].eq(1)]
+ second_scored = second_retry[
+ [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ ].copy()
+ second_scored["shape"] = 0.2
+ second_scored["color"] = 0.1
+ second_scored["sucos_shape"] = 0.1
+ second_scored.to_parquet(
+ retry_dir / "1.parquet",
+ schema=schemas.LIGAND_3D_SCORE_SCHEMA,
+ index=False,
+ )
+
+ finalized = finalize_ligand_3d_retries(tmp_path)
+ assert finalized["completed_retry_batch_count"] == 2
+ combined = pd.read_parquet(canonical / "1.parquet")
+ assert len(combined) == 2
+ assert combined["shape"].notna().sum() == 2
+
+
+def test_ligand_3d_plan_deduplicates_positive_pocket_candidates(tmp_path) -> None:
+ from plinder.data.pipeline.score import (
+ LIGAND_3D_WORK_RELATIVE,
+ LIGAND_POCKET_QCOV_REPRESENTATIVE_ROOT_RELATIVE,
+ SCORE_WORK_RELATIVE,
+ _ligand_3d_batch,
+ materialize_ligand_3d_pair_candidates,
+ plan_ligand_3d_batches,
+ plan_protein_scoring,
+ )
+
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def", "3ghi"],
+ "chain_asym_id": ["A", "A", "A"],
+ "chain_receptor_type": ["protein"] * 3,
+ "chain_is_holo": [True, True, False],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def", "3ghi"],
+ "ligand_asym_id": ["B", "Y", "Z"],
+ "ligand_num_heavy_atoms": [10, 20, 30],
+ "ligand_is_proper": [True] * 3,
+ "ligand_is_shape_comparable": [True] * 3,
+ "system_type": ["holo"] * 3,
+ }
+ ).to_parquet(index / "annotation_table.parquet", index=False)
+ plan_protein_scoring(tmp_path)
+ pd.DataFrame(
+ {
+ "pdb_id": ["1abc", "2def"],
+ "score_batch_index": [0, 0],
+ "estimated_work": [1.0, 1.0],
+ }
+ ).to_parquet(tmp_path / SCORE_WORK_RELATIVE, index=False)
+
+ candidate_dir = tmp_path / "scores/ligand_3d_candidates/search_db=holo/shard=ab"
+ candidate_dir.mkdir(parents=True)
+ repeated = {
+ "query_system": "1abc_system",
+ "query_ligand_id": "1abc__1__1.B",
+ "query_entry": "1abc",
+ "query_ligand_asym_id": "B",
+ "target_system": "2def_system",
+ "target_ligand_id": "2def__1__1.Y",
+ "target_entry": "2def",
+ "target_ligand_asym_id": "Y",
+ "protein_mapping": "1.A:1.X",
+ "protein_mapper": "foldseek",
+ "pocket_qcov": 0.5,
+ }
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ repeated,
+ {**repeated, "query_system": "1abc_other", "pocket_qcov": 0.75},
+ {
+ **repeated,
+ "target_system": "3ghi_system",
+ "target_ligand_id": "3ghi__1__1.Z",
+ "target_entry": "3ghi",
+ "target_ligand_asym_id": "Z",
+ "pocket_qcov": 0.29,
+ },
+ ],
+ schema=schemas.LIGAND_3D_CANDIDATE_SCHEMA,
+ ),
+ candidate_dir / "1abc.parquet",
+ )
+ _write_ligand_pair_scores(
+ tmp_path,
+ "1abc",
+ pd.read_parquet(candidate_dir / "1abc.parquet").to_dict("records"),
+ )
+ target_candidate_dir = candidate_dir.parent / "shard=de"
+ target_candidate_dir.mkdir()
+ pq.write_table(
+ pa.Table.from_pylist([], schema=schemas.LIGAND_3D_CANDIDATE_SCHEMA),
+ target_candidate_dir / "2def.parquet",
+ )
+ _write_ligand_pair_scores(tmp_path, "2def", [])
+ tasks.collate_ligand_3d_candidates(
+ data_dir=tmp_path,
+ shards=["ab", "de"],
+ scratch_dir=tmp_path / "candidate-scratch",
+ threads=1,
+ )
+ compact = pd.read_parquet(
+ tmp_path / "scores/ligand_3d_pair_candidate_shards/shard=ab.parquet"
+ )
+ assert len(compact) == 2
+ assert compact.loc[
+ compact["target_entry"] == "2def", "pocket_qcov"
+ ].item() == pytest.approx(0.75)
+ representatives = [
+ {
+ "representative_ligand_id": ligand_id,
+ "representative_system_id": system_id,
+ "entry_pdb_id": entry_id,
+ "ligand_asym_id": asym_id,
+ "ligand_is_shape_comparable": True,
+ "receptor_set_id": f"{entry_id}-receptor",
+ "receptor_chain_asym_ids": ["A"],
+ "pocket_residues": ["A_1_0_1"],
+ "interactions": [],
+ }
+ for ligand_id, system_id, entry_id, asym_id in [
+ ("1abc__1__1.B", "1abc_system", "1abc", "B"),
+ ("2def__1__1.Y", "2def_system", "2def", "Y"),
+ ("3ghi__1__1.Z", "3ghi_system", "3ghi", "Z"),
+ ]
+ ]
+ representative_path = tmp_path / tasks.LIGAND_POCKET_REPRESENTATIVES_RELATIVE
+ representative_path.parent.mkdir(parents=True, exist_ok=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ representatives,
+ schema=schemas.LIGAND_POCKET_REPRESENTATIVE_SCHEMA,
+ ),
+ representative_path,
+ )
+ normalized_score = (
+ tmp_path / LIGAND_POCKET_QCOV_REPRESENTATIVE_ROOT_RELATIVE / "shard=ab.parquet"
+ )
+ normalized_score.parent.mkdir(parents=True, exist_ok=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {
+ "query_system": "1abc_system",
+ "query_ligand_id": "1abc__1__1.B",
+ "target_system": target_system,
+ "target_ligand_id": target_ligand,
+ "protein_mapping": "A:A",
+ "protein_mapper": "foldseek",
+ "source": "foldseek",
+ "pocket_qcov": pocket_qcov,
+ }
+ for target_system, target_ligand, pocket_qcov in [
+ ("2def_system", "2def__1__1.Y", 0.8),
+ ("3ghi_system", "3ghi__1__1.Z", 0.4),
+ ]
+ ],
+ schema=schemas.LIGAND_POCKET_QCOV_REPRESENTATIVE_SCHEMA,
+ ),
+ normalized_score,
+ )
+ materialize_ligand_3d_pair_candidates(
+ tmp_path,
+ shards=["ab"],
+ scratch_dir=tmp_path / "normalized-candidate-scratch",
+ threads=1,
+ memory_limit="1GB",
+ force_update=True,
+ )
+ pair_candidate = (
+ tmp_path / "scores/ligand_3d_pair_candidate_shards/shard=ab.parquet"
+ )
+ pair_stat = pair_candidate.stat()
+ candidate_manifest = json.loads(
+ pair_candidate.parent.parent.joinpath(
+ "ligand_3d_candidate_shards/shard=ab.json"
+ ).read_text()
+ )
+ assert candidate_manifest["pair_output"] == {
+ "path": str(pair_candidate.resolve()),
+ "size": pair_stat.st_size,
+ "mtime_ns": pair_stat.st_mtime_ns,
+ "rows": 2,
+ }
+ # Packed candidate shards are self-contained planning inputs. The
+ # per-query score files may be archived or unavailable after collation.
+ (candidate_dir / "1abc.parquet").unlink()
+ (target_candidate_dir / "2def.parquet").unlink()
+
+ report = plan_ligand_3d_batches(
+ tmp_path,
+ batch_size=2,
+ threads=1,
+ scratch_dir=tmp_path / "scratch",
+ )
+
+ assert report["pair_count"] == 2
+ assert report["batch_count"] == 1
+ work = pd.read_parquet(tmp_path / LIGAND_3D_WORK_RELATIVE)
+ assert not work.duplicated(
+ [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ ).any()
+ assert set(work["estimated_work"]) == {200, 300}
+ assert set(work["target_entry"]) == {"2def", "3ghi"}
+ assert len(_ligand_3d_batch(tmp_path, 0, 2)) == 2
+
+
+def test_candidate_repair_patches_packed_shard_without_other_query_caches(
+ tmp_path: Path,
+) -> None:
+ def candidate(query_entry: str, target_entry: str, pocket_qcov: float) -> dict:
+ return {
+ "query_system": f"{query_entry}__1",
+ "query_ligand_id": f"{query_entry}__1__1.L",
+ "query_entry": query_entry,
+ "query_ligand_asym_id": "L",
+ "target_system": f"{target_entry}__1",
+ "target_ligand_id": f"{target_entry}__1__1.X",
+ "target_entry": target_entry,
+ "target_ligand_asym_id": "X",
+ "protein_mapping": "1.A:1.B",
+ "protein_mapper": "foldseek",
+ "pocket_qcov": pocket_qcov,
+ }
+
+ packed = tmp_path / "scores/ligand_3d_candidate_shards/shard=ab.parquet"
+ packed.parent.mkdir(parents=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [candidate("1abc", "2old", 0.4), candidate("9abc", "8keep", 0.6)],
+ schema=schemas.LIGAND_3D_CANDIDATE_SCHEMA,
+ ),
+ packed,
+ )
+ packed_ligand_pairs = tmp_path / "scores/ligand_pair_score_shards/shard=ab.parquet"
+ packed_ligand_pairs.parent.mkdir(parents=True)
+ packed_candidates = pd.read_parquet(packed).to_dict("records")
+ temporary_pair_path = _write_ligand_pair_scores(tmp_path, "1abc", packed_candidates)
+ copyfile(temporary_pair_path, packed_ligand_pairs)
+ replacement = (
+ tmp_path / "scores/ligand_3d_candidates/search_db=holo/shard=ab/1abc.parquet"
+ )
+ replacement.parent.mkdir(parents=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [candidate("1abc", "2new", 0.8)],
+ schema=schemas.LIGAND_3D_CANDIDATE_SCHEMA,
+ ),
+ replacement,
+ )
+ _write_ligand_pair_scores(
+ tmp_path,
+ "1abc",
+ pd.read_parquet(replacement).to_dict("records"),
+ )
+
+ tasks.collate_ligand_3d_candidates(
+ data_dir=tmp_path,
+ shards=["ab"],
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ replacement_query_ids={"1abc"},
+ source_query_ids={"1abc"},
+ )
+
+ repaired = pd.read_parquet(packed)
+ assert set(zip(repaired["query_entry"], repaired["target_entry"])) == {
+ ("1abc", "2new"),
+ ("9abc", "8keep"),
+ }
+ repaired_ligand_pairs = pd.read_parquet(packed_ligand_pairs)
+ assert set(
+ zip(
+ repaired_ligand_pairs["query_entry"],
+ repaired_ligand_pairs["target_entry"],
+ )
+ ) == {
+ ("1abc", "2new"),
+ ("9abc", "8keep"),
+ }
+ pairs = pd.read_parquet(
+ tmp_path / "scores/ligand_3d_pair_candidate_shards/shard=ab.parquet"
+ )
+ assert set(zip(pairs["query_entry"], pairs["target_entry"])) == {
+ ("1abc", "2new"),
+ ("9abc", "8keep"),
+ }
+ packed_mtime = packed.stat().st_mtime_ns
+ pair_mtime = packed_ligand_pairs.stat().st_mtime_ns
+ tasks.collate_ligand_3d_candidates(
+ data_dir=tmp_path,
+ shards=["ab"],
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ replacement_query_ids={"1abc"},
+ source_query_ids={"1abc"},
+ )
+ assert packed.stat().st_mtime_ns == packed_mtime
+ assert packed_ligand_pairs.stat().st_mtime_ns == pair_mtime
+
+
+def test_make_ligand_3d_scores_writes_and_reuses_complete_batch(
+ tmp_path, monkeypatch
+) -> None:
+ pairs = pd.DataFrame(
+ {
+ "query_entry": ["1abc"],
+ "query_ligand_asym_id": ["B"],
+ "target_entry": ["2def"],
+ "target_ligand_asym_id": ["Y"],
+ }
+ )
+ calls = 0
+
+ class FakeScorer:
+ shape_score_threads = 1
+
+ def score_canonical_ligand_pairs(self, _data_dir, observed_pairs):
+ nonlocal calls
+ calls += 1
+ result = observed_pairs.copy()
+ result["shape"] = 0.8
+ result["color"] = 0.6
+ result["sucos_shape"] = 0.7
+ return result
+
+ monkeypatch.setattr(
+ tasks.utils,
+ "get_scorer",
+ lambda **_kwargs: (FakeScorer(), [], tmp_path / "unused"),
+ )
+ kwargs = {
+ "data_dir": tmp_path,
+ "pairs": pairs,
+ "batch_index": 3,
+ "scorer_cfg": SimpleNamespace(),
+ "force_update": False,
+ "scratch_dir": tmp_path / "scratch",
+ "threads": 2,
+ }
+
+ output = tasks.make_ligand_3d_scores(**kwargs)
+ assert tasks.make_ligand_3d_scores(**kwargs) == output
+ assert calls == 1
+ assert pd.read_parquet(output)["sucos_shape"].item() == pytest.approx(0.7)
+
+
+def test_collate_ligand_3d_scores_repartitions_balanced_batches(tmp_path) -> None:
+ from plinder.data.pipeline.score import (
+ LIGAND_3D_WORK_RELATIVE,
+ SCORE_WORK_RELATIVE,
+ )
+
+ work = pd.DataFrame(
+ {
+ "query_entry": ["1abc", "2abc"],
+ "query_ligand_asym_id": ["B", "C"],
+ "target_entry": ["3def", "4ghi"],
+ "target_ligand_asym_id": ["Y", "Z"],
+ "estimated_work": [10, 20],
+ "ligand_3d_batch_index": [0, 1],
+ }
+ )
+ work_path = tmp_path / LIGAND_3D_WORK_RELATIVE
+ work_path.parent.mkdir(parents=True)
+ work.to_parquet(work_path, index=False)
+ pd.DataFrame({"pdb_id": ["1abc", "2abc"]}).to_parquet(
+ tmp_path / SCORE_WORK_RELATIVE, index=False
+ )
+ pair_dir = tmp_path / "scores/ligand_3d_pairs"
+ pair_dir.mkdir(parents=True)
+ for row in work.itertuples(index=False):
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {
+ "query_entry": row.query_entry,
+ "query_ligand_asym_id": row.query_ligand_asym_id,
+ "target_entry": row.target_entry,
+ "target_ligand_asym_id": row.target_ligand_asym_id,
+ "shape": 0.8,
+ "color": 0.6,
+ "sucos_shape": 0.7,
+ }
+ ],
+ schema=schemas.LIGAND_3D_SCORE_SCHEMA,
+ ),
+ pair_dir / f"{row.ligand_3d_batch_index}.parquet",
+ )
+
+ outputs = tasks.collate_ligand_3d_scores(
+ data_dir=tmp_path,
+ shards=["ab"],
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ )
+
+ assert outputs == [tmp_path / "scores/ligand_3d_by_query/ab.parquet"]
+ observed = pd.read_parquet(outputs[0])
+ assert observed["query_entry"].tolist() == ["1abc", "2abc"]
+ assert observed["shape"].tolist() == [0.8, 0.8]
+
+
+def test_ligand_3d_score_shard_with_no_pairs_is_ready(tmp_path) -> None:
+ from plinder.data.pipeline.score import (
+ LIGAND_3D_WORK_RELATIVE,
+ SCORE_WORK_RELATIVE,
+ )
+
+ work_path = tmp_path / LIGAND_3D_WORK_RELATIVE
+ work_path.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query_entry": pd.Series(dtype="str"),
+ "query_ligand_asym_id": pd.Series(dtype="str"),
+ "target_entry": pd.Series(dtype="str"),
+ "target_ligand_asym_id": pd.Series(dtype="str"),
+ "ligand_3d_batch_index": pd.Series(dtype="int64"),
+ }
+ ).to_parquet(work_path, index=False)
+ pd.DataFrame({"pdb_id": ["1abc"]}).to_parquet(
+ tmp_path / SCORE_WORK_RELATIVE, index=False
+ )
+
+ assert tasks._ligand_3d_query_shard_is_ready(data_dir=tmp_path, shard="ab")
+ outputs = tasks.collate_ligand_3d_scores(
+ data_dir=tmp_path,
+ shards=["ab"],
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ )
+
+ assert outputs == [tmp_path / "scores/ligand_3d_by_query/ab.parquet"]
+ assert pq.read_schema(outputs[0]).equals(schemas.LIGAND_3D_SCORE_SCHEMA)
+ assert pq.ParquetFile(outputs[0]).metadata.num_rows == 0
+
+
+@pytest.mark.parametrize("has_pairs", [True, False])
+def test_finalize_ligand_3d_scores_validates_pair_and_packed_shards(
+ tmp_path, monkeypatch, has_pairs
+) -> None:
+ from plinder.data.pipeline.score import (
+ SCORE_WORK_RELATIVE,
+ finalize_ligand_3d_artifacts,
+ plan_ligand_3d_batches,
+ plan_protein_scoring,
+ )
+
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def"],
+ "chain_asym_id": ["A", "A"],
+ "chain_receptor_type": ["protein", "protein"],
+ "chain_is_holo": [True, False],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def"],
+ "ligand_asym_id": ["B", "Y"],
+ "ligand_num_heavy_atoms": [10, 20],
+ "ligand_is_proper": [True, True],
+ "ligand_is_shape_comparable": [has_pairs, has_pairs],
+ "system_type": ["holo", "holo"],
+ }
+ ).to_parquet(index / "annotation_table.parquet", index=False)
+ plan_protein_scoring(tmp_path)
+ pd.DataFrame(
+ {
+ "pdb_id": ["1abc"],
+ "score_batch_index": [0],
+ "estimated_work": [1.0],
+ }
+ ).to_parquet(tmp_path / SCORE_WORK_RELATIVE, index=False)
+ candidate_dir = tmp_path / "scores/ligand_3d_candidates/search_db=holo/shard=ab"
+ candidate_dir.mkdir(parents=True)
+ candidate = {
+ "query_system": "1abc_system",
+ "query_ligand_id": "1abc__1__1.B",
+ "query_entry": "1abc",
+ "query_ligand_asym_id": "B",
+ "target_system": "2def_system",
+ "target_ligand_id": "2def__1__1.Y",
+ "target_entry": "2def",
+ "target_ligand_asym_id": "Y",
+ "protein_mapping": "1.A:1.X",
+ "protein_mapper": "foldseek",
+ "pocket_qcov": 0.5,
+ }
+ candidates = [candidate] if has_pairs else []
+ pq.write_table(
+ pa.Table.from_pylist(candidates, schema=schemas.LIGAND_3D_CANDIDATE_SCHEMA),
+ candidate_dir / "1abc.parquet",
+ )
+ _write_ligand_pair_scores(tmp_path, "1abc", candidates)
+ tasks.collate_ligand_3d_candidates(
+ data_dir=tmp_path,
+ shards=["ab"],
+ scratch_dir=tmp_path / "candidate-scratch",
+ threads=1,
+ )
+ plan_ligand_3d_batches(
+ tmp_path,
+ batch_size=10,
+ threads=1,
+ scratch_dir=tmp_path / "plan-scratch",
+ )
+ pair_dir = tmp_path / "scores/ligand_3d_pairs"
+ pair_dir.mkdir(parents=True)
+ pair = {
+ key: candidate[key]
+ for key in [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ }
+ pair.update({"shape": 0.8, "color": 0.6, "sucos_shape": 0.7})
+ if has_pairs:
+ pq.write_table(
+ pa.Table.from_pylist([pair], schema=schemas.LIGAND_3D_SCORE_SCHEMA),
+ pair_dir / "0.parquet",
+ )
+ final_score = tmp_path / "scores/search_db=holo/ab.parquet"
+ final_score.parent.mkdir(parents=True)
+ pd.DataFrame(columns=schemas.PROTEIN_SIMILARITY_SCHEMA.names).to_parquet(
+ final_score,
+ index=False,
+ schema=schemas.PROTEIN_SIMILARITY_SCHEMA,
+ )
+
+ report = finalize_ligand_3d_artifacts(tmp_path)
+
+ assert report == {
+ "status": "complete",
+ "canonical_pair_count": int(has_pairs),
+ "pair_batch_count": int(has_pairs),
+ "query_shard_count": 1,
+ "query_count": 1,
+ "ligand_pair_score_shard_count": 1,
+ "ligand_pair_score_rows": int(has_pairs),
+ }
+ assert (tmp_path / "scores/ligand_3d_pair_validation.json").is_file()
+
+ import duckdb
+
+ monkeypatch.setattr(
+ duckdb,
+ "connect",
+ lambda: pytest.fail("signature-matched pair validation was not reused"),
+ )
+ assert finalize_ligand_3d_artifacts(tmp_path) == report
+
+ ligand_pair_score = tmp_path / "scores/ligand_pair_score_shards/shard=ab.parquet"
+ ligand_pair_score.unlink()
+ with pytest.raises(FileNotFoundError, match="ligand_pair_score_shards"):
+ finalize_ligand_3d_artifacts(tmp_path)
+
+
+def test_finalize_score_repair_accepts_refreshed_candidate_shards(tmp_path) -> None:
+ from plinder.data.pipeline.score import finalize_score_repair_artifacts
+
+ repair_manifest = tmp_path / "manifests/repair.parquet"
+ repair_manifest.parent.mkdir(parents=True)
+ pd.DataFrame({"pdb_id": ["1abc"], "shard": ["ab"]}).to_parquet(
+ repair_manifest, index=False
+ )
+ candidate = {
+ "query_system": "1abc_system",
+ "query_ligand_id": "1abc__1__1.B",
+ "query_entry": "1abc",
+ "query_ligand_asym_id": "B",
+ "target_system": "2def_system",
+ "target_ligand_id": "2def__1__1.Y",
+ "target_entry": "2def",
+ "target_ligand_asym_id": "Y",
+ "protein_mapping": "1.A:1.X",
+ "protein_mapper": "foldseek",
+ "pocket_qcov": 0.5,
+ }
+ candidate_path = tmp_path / "scores/ligand_3d_candidate_shards/shard=ab.parquet"
+ candidate_path.parent.mkdir(parents=True)
+ pq.write_table(
+ pa.Table.from_pylist([candidate], schema=schemas.LIGAND_3D_CANDIDATE_SCHEMA),
+ candidate_path,
+ )
+ ligand_pair_score_path = (
+ tmp_path / "scores/ligand_pair_score_shards/shard=ab.parquet"
+ )
+ ligand_pair_score_path.parent.mkdir(parents=True)
+ ligand_pair_score = {
+ key: candidate[key]
+ for key in [
+ "query_system",
+ "query_ligand_id",
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_system",
+ "target_ligand_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ } | {"pocket_qcov": 50, "pocket_fident_qcov": 40, "pli_qcov": 30}
+ pq.write_table(
+ pa.Table.from_pylist(
+ [ligand_pair_score], schema=schemas.LIGAND_PAIR_SCORE_SCHEMA
+ ),
+ ligand_pair_score_path,
+ )
+ pair_candidate_path = (
+ tmp_path / "scores/ligand_3d_pair_candidate_shards/shard=ab.parquet"
+ )
+ pair_candidate_path.parent.mkdir(parents=True)
+ pair_candidate = {
+ key: candidate[key]
+ for key in [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ "pocket_qcov",
+ ]
+ }
+ pq.write_table(
+ pa.Table.from_pylist(
+ [pair_candidate], schema=schemas.LIGAND_3D_PAIR_CANDIDATE_SCHEMA
+ ),
+ pair_candidate_path,
+ )
+ candidate_stat = candidate_path.stat()
+ ligand_pair_score_stat = ligand_pair_score_path.stat()
+ pair_candidate_stat = pair_candidate_path.stat()
+ candidate_path.with_suffix(".json").write_text(
+ json.dumps(
+ {
+ "shard": "ab",
+ "inputs": [],
+ "output": {
+ "path": str(candidate_path.resolve()),
+ "size": candidate_stat.st_size,
+ "mtime_ns": candidate_stat.st_mtime_ns,
+ "rows": 1,
+ },
+ "pair_output": {
+ "path": str(pair_candidate_path.resolve()),
+ "size": pair_candidate_stat.st_size,
+ "mtime_ns": pair_candidate_stat.st_mtime_ns,
+ "rows": 1,
+ },
+ "ligand_pair_output": {
+ "path": str(ligand_pair_score_path.resolve()),
+ "size": ligand_pair_score_stat.st_size,
+ "mtime_ns": ligand_pair_score_stat.st_mtime_ns,
+ "rows": 1,
+ },
+ }
+ )
+ )
+
+ pair_path = tmp_path / "scores/ligand_3d_by_query/ab.parquet"
+ pair_path.parent.mkdir(parents=True)
+ pair = {
+ key: candidate[key]
+ for key in [
+ "query_entry",
+ "query_ligand_asym_id",
+ "target_entry",
+ "target_ligand_asym_id",
+ ]
+ }
+ pair.update({"shape": 0.8, "color": 0.6, "sucos_shape": 0.7})
+ pq.write_table(
+ pa.Table.from_pylist([pair], schema=schemas.LIGAND_3D_SCORE_SCHEMA),
+ pair_path,
+ )
+ score_path = tmp_path / "scores/search_db=holo/ab.parquet"
+ score_path.parent.mkdir(parents=True)
+ pd.DataFrame(columns=schemas.PROTEIN_SIMILARITY_SCHEMA.names).to_parquet(
+ score_path,
+ index=False,
+ schema=schemas.PROTEIN_SIMILARITY_SCHEMA,
+ )
+
+ report = finalize_score_repair_artifacts(
+ tmp_path,
+ repair_manifest=repair_manifest,
+ )
+
+ assert report["status"] == "complete"
+ assert report["shard_count"] == 1
+ assert report["candidate_rows"] == 1
+ assert report["ligand_pair_score_rows"] == 1
+ assert report["pair_rows"] == 1
+ assert (tmp_path / "scores/score_repair_manifest.json").is_file()
+
+ score_mtime_ns = score_path.stat().st_mtime_ns
+ os.utime(
+ pair_path,
+ ns=(score_mtime_ns + 1_000_000_000, score_mtime_ns + 1_000_000_000),
+ )
+ with pytest.raises(ValueError, match="predates its current inputs"):
+ finalize_score_repair_artifacts(
+ tmp_path,
+ repair_manifest=repair_manifest,
+ )
+ score_path.unlink()
+ compact_report = finalize_score_repair_artifacts(
+ tmp_path,
+ repair_manifest=repair_manifest,
+ require_packed_scores=False,
+ )
+ assert compact_report["score_rows"] == 0
+
+
+def test_merge_ligand_3d_scores_uses_full_precision_pocket_coverage(tmp_path) -> None:
+ from plinder.data.pipeline.score import (
+ LIGAND_3D_WORK_RELATIVE,
+ SCORE_WORK_RELATIVE,
+ )
+
+ score_path = tmp_path / "dbs/subdbs/search_db=holo/1abc.parquet"
+ score_path.parent.mkdir(parents=True)
+ base = pd.DataFrame(
+ [
+ {
+ "query_system": "1abc_system",
+ "query_ligand_id": "1abc__1__1.B",
+ "target_system": "2def_system",
+ "target_ligand_id": "2def__1__1.Y",
+ "protein_mapping": "1.A:1.X",
+ "mapping": "1.A:1.X",
+ "protein_mapper": "foldseek",
+ "source": "foldseek",
+ "metric": "pocket_qcov",
+ "similarity": 67,
+ }
+ ]
+ )
+ base.to_parquet(
+ score_path,
+ index=False,
+ schema=schemas.PROTEIN_SIMILARITY_SCHEMA.with_metadata(
+ {b"plinder.ligand_3d": b"deferred"}
+ ),
+ )
+ candidate_path = tmp_path / "scores/ligand_3d_candidate_shards/shard=ab.parquet"
+ candidate_path.parent.mkdir(parents=True)
+ candidate = {
+ "query_system": "1abc_system",
+ "query_ligand_id": "1abc__1__1.B",
+ "query_entry": "1abc",
+ "query_ligand_asym_id": "B",
+ "target_system": "2def_system",
+ "target_ligand_id": "2def__1__1.Y",
+ "target_entry": "2def",
+ "target_ligand_asym_id": "Y",
+ "protein_mapping": "1.A:1.X",
+ "protein_mapper": "foldseek",
+ "pocket_qcov": 2 / 3,
+ }
+ pq.write_table(
+ pa.Table.from_pylist([candidate], schema=schemas.LIGAND_3D_CANDIDATE_SCHEMA),
+ candidate_path,
+ )
+ pair_path = tmp_path / "scores/ligand_3d_by_query/ab.parquet"
+ pair_path.parent.mkdir(parents=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {
+ "query_entry": "1abc",
+ "query_ligand_asym_id": "B",
+ "target_entry": "2def",
+ "target_ligand_asym_id": "Y",
+ "shape": 0.8,
+ "color": 0.6,
+ "sucos_shape": 0.46,
+ }
+ ],
+ schema=schemas.LIGAND_3D_SCORE_SCHEMA,
+ ),
+ pair_path,
+ )
+ work = pd.DataFrame(
+ {
+ "query_entry": ["1abc"],
+ "query_ligand_asym_id": ["B"],
+ "target_entry": ["2def"],
+ "target_ligand_asym_id": ["Y"],
+ "estimated_work": [200],
+ "ligand_3d_batch_index": [0],
+ }
+ )
+ work_path = tmp_path / LIGAND_3D_WORK_RELATIVE
+ work_path.parent.mkdir(exist_ok=True, parents=True)
+ work.to_parquet(work_path, index=False)
+ pd.DataFrame({"pdb_id": ["1abc"]}).to_parquet(
+ tmp_path / SCORE_WORK_RELATIVE, index=False
+ )
+ pair_batch_dir = tmp_path / "scores/ligand_3d_pairs"
+ pair_batch_dir.mkdir(parents=True)
+ copyfile(pair_path, pair_batch_dir / "0.parquet")
+
+ tasks.merge_ligand_3d_scores(
+ data_dir=tmp_path,
+ shards=["ab"],
+ scorer_cfg=SimpleNamespace(minimum_threshold=0.3, minimum_thresholds={}),
+ force_update=False,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ )
+
+ merged_path = tmp_path / "scores/search_db=holo/ab.parquet"
+ merged = pd.read_parquet(merged_path).set_index("metric")
+ assert merged["similarity"].to_dict() == {
+ "shape": 80,
+ "pocket_qcov": 67,
+ "color": 60,
+ "sucos_shape": 46,
+ "sucos_shape_pocket_qcov": 31,
+ }
+ assert pd.read_parquet(score_path)["metric"].tolist() == ["pocket_qcov"]
+
+
+def test_score_repair_patches_packed_shard_without_other_query_caches(
+ tmp_path: Path,
+) -> None:
+ def candidate(query_entry: str, target_entry: str, pocket_qcov: float) -> dict:
+ return {
+ "query_system": f"{query_entry}__1",
+ "query_ligand_id": f"{query_entry}__1__1.L",
+ "query_entry": query_entry,
+ "query_ligand_asym_id": "L",
+ "target_system": f"{target_entry}__1",
+ "target_ligand_id": f"{target_entry}__1__1.X",
+ "target_entry": target_entry,
+ "target_ligand_asym_id": "X",
+ "protein_mapping": "1.A:1.B",
+ "protein_mapper": "foldseek",
+ "pocket_qcov": pocket_qcov,
+ }
+
+ candidate_path = tmp_path / "scores/ligand_3d_candidate_shards/shard=ab.parquet"
+ candidate_path.parent.mkdir(parents=True)
+ candidates = [candidate("1abc", "2new", 0.75), candidate("9abc", "8keep", 0.6)]
+ pq.write_table(
+ pa.Table.from_pylist(candidates, schema=schemas.LIGAND_3D_CANDIDATE_SCHEMA),
+ candidate_path,
+ )
+ pair_path = tmp_path / "scores/ligand_3d_by_query/ab.parquet"
+ pair_path.parent.mkdir(parents=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {
+ "query_entry": row["query_entry"],
+ "query_ligand_asym_id": "L",
+ "target_entry": row["target_entry"],
+ "target_ligand_asym_id": "X",
+ "shape": 0.8,
+ "color": 0.6,
+ "sucos_shape": 0.5,
+ }
+ for row in candidates
+ ],
+ schema=schemas.LIGAND_3D_SCORE_SCHEMA,
+ ),
+ pair_path,
+ )
+
+ def score(query_entry: str, metric: str, similarity: int) -> dict:
+ return {
+ "query_system": f"{query_entry}__1",
+ "query_ligand_id": f"{query_entry}__1__1.L",
+ "target_system": "2new__1",
+ "target_ligand_id": "2new__1__1.X",
+ "protein_mapping": "1.A:1.B",
+ "mapping": "1.A:1.B",
+ "protein_mapper": "foldseek",
+ "source": "foldseek",
+ "metric": metric,
+ "similarity": similarity,
+ }
+
+ replacement = tmp_path / "dbs/subdbs/search_db=holo/1abc.parquet"
+ replacement.parent.mkdir(parents=True)
+ pd.DataFrame([score("1abc", "pocket_qcov", 88)]).to_parquet(
+ replacement, index=False, schema=schemas.PROTEIN_SIMILARITY_SCHEMA
+ )
+ packed = tmp_path / "scores/search_db=holo/ab.parquet"
+ packed.parent.mkdir(parents=True)
+ pd.DataFrame(
+ [
+ score("1abc", "pocket_qcov", 11),
+ score("1abc", "shape", 12),
+ score("9abc", "pocket_qcov", 55),
+ score("9abc", "color", 42),
+ score("9abc", "protein_fident_weighted_sum", 91),
+ ]
+ ).to_parquet(packed, index=False, schema=schemas.PROTEIN_SIMILARITY_SCHEMA)
+ work = tmp_path / "manifests/protein_scoring_work.parquet"
+ work.parent.mkdir(parents=True)
+ pd.DataFrame({"pdb_id": ["1abc", "9abc"]}).to_parquet(work, index=False)
+
+ tasks.merge_ligand_3d_scores(
+ data_dir=tmp_path,
+ shards=["ab"],
+ scorer_cfg=SimpleNamespace(minimum_threshold=0.3, minimum_thresholds={}),
+ force_update=True,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ reuse_cached_pairs=True,
+ replacement_query_ids={"1abc"},
+ )
+
+ repaired = pd.read_parquet(packed)
+ preserved = repaired[repaired["query_system"].eq("9abc__1")]
+ assert dict(zip(preserved["metric"], preserved["similarity"])) == {
+ "pocket_qcov": 55,
+ "color": 42,
+ }
+ replacement_rows = repaired[repaired["query_system"].eq("1abc__1")]
+ replacement_scores = dict(
+ zip(replacement_rows["metric"], replacement_rows["similarity"])
+ )
+ assert replacement_scores["pocket_qcov"] == 88
+ assert replacement_scores["shape"] == 80
+ assert 11 not in replacement_rows["similarity"].tolist()
+
+
+def test_merge_ligand_3d_scores_fails_when_query_shard_is_not_ready(
+ tmp_path, monkeypatch
+) -> None:
+ score_work = tmp_path / "manifests" / "protein_scoring_work.parquet"
+ score_work.parent.mkdir(parents=True)
+ pd.DataFrame({"pdb_id": ["1abc"]}).to_parquet(score_work, index=False)
+ monkeypatch.setattr(
+ tasks,
+ "_ligand_3d_query_shard_is_ready",
+ lambda **_kwargs: False,
+ )
+
+ with pytest.raises(RuntimeError, match="retry this merge task"):
+ tasks.merge_ligand_3d_scores(
+ data_dir=tmp_path,
+ shards=["ab"],
+ scorer_cfg=SimpleNamespace(
+ minimum_threshold=0.3,
+ minimum_thresholds={},
+ ),
+ force_update=False,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ )
+
+
+def test_protein_scoring_finalizer_rejects_changed_chain_index(tmp_path) -> None:
+ from plinder.data.pipeline.score import (
+ finalize_alignment_artifacts,
+ plan_protein_scoring,
+ )
+
+ index_dir = tmp_path / "index"
+ index_dir.mkdir()
+ chain_path = index_dir / "entry_chains.parquet"
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "chain_asym_id": ["A"],
+ "chain_receptor_type": ["protein"],
+ "chain_is_holo": [True],
+ }
+ ).to_parquet(chain_path, index=False)
+ plan_protein_scoring(tmp_path)
+ chain_path.write_bytes(chain_path.read_bytes() + b"changed")
+
+ with pytest.raises(ValueError, match="entry chain index changed"):
+ finalize_alignment_artifacts(tmp_path)
+
+
+def test_v3_source_roots_are_configurable() -> None:
+ from plinder.data.pipeline.config import get_config
+
+ cfg = get_config(
+ config={
+ "source": {
+ "pdb_nextgen_root": "/archives/nextgen",
+ "validation_root": "/archives/validation",
+ "discovery_threads": 3,
+ }
+ },
+ cached=False,
+ )
+
+ assert cfg.source.pdb_nextgen_root == "/archives/nextgen"
+ assert cfg.source.validation_root == "/archives/validation"
+ assert cfg.source.discovery_threads == 3
+
+
+def test_make_dbs_uses_configured_source_files(tmp_path, monkeypatch) -> None:
+ cif_root = tmp_path / "nextgen"
+ cif_root.mkdir()
+ seqres_path = tmp_path / "pdb_seqres.txt.gz"
+ seqres_path.touch()
+ create_calls = []
+ index_calls = []
+ monkeypatch.setattr(
+ tasks.databases,
+ "create_db",
+ lambda source, output, kind, threads: create_calls.append(
+ (
+ source,
+ output,
+ kind,
+ threads,
+ )
+ ),
+ )
+ monkeypatch.setattr(
+ tasks.databases,
+ "create_db_index",
+ lambda output, kind, tmp_dir, threads: index_calls.append(
+ (
+ output,
+ kind,
+ tmp_dir,
+ threads,
+ )
+ ),
+ )
+
+ tasks.make_dbs(
+ data_dir=tmp_path,
+ sub_databases=["holo"],
+ cpu=3,
+ cif_root=cif_root,
+ seqres_path=seqres_path,
+ )
+
+ assert create_calls == [
+ (cif_root, tmp_path / "dbs/foldseek", "foldseek", 3),
+ (seqres_path, tmp_path / "dbs/mmseqs", "mmseqs", 3),
+ ]
+ assert index_calls == [
+ (
+ tmp_path / "dbs/foldseek",
+ "foldseek",
+ tmp_path / "scratch/databases/foldseek",
+ 3,
+ ),
+ (
+ tmp_path / "dbs/mmseqs",
+ "mmseqs",
+ tmp_path / "scratch/databases/mmseqs",
+ 3,
+ ),
+ ]
+
+
+def test_make_dbs_records_file_source_before_reusing_completed_output(
+ tmp_path, monkeypatch
+) -> None:
+ cif_root = tmp_path / "nextgen"
+ cif_root.mkdir()
+ seqres_path = tmp_path / "pdb_seqres.txt.gz"
+ seqres_path.touch()
+ monkeypatch.setattr(
+ tasks.databases,
+ "created_database_is_complete",
+ lambda *_args: True,
+ )
+ create_calls = []
+ monkeypatch.setattr(
+ tasks.databases,
+ "create_db",
+ lambda source, output, kind, threads: create_calls.append(
+ (source, output, kind, threads)
+ ),
+ )
+
+ kwargs = dict(
+ data_dir=tmp_path,
+ sub_databases=["holo"],
+ cpu=2,
+ cif_root=cif_root,
+ seqres_path=seqres_path,
+ index=False,
+ )
+ tasks.make_dbs(**kwargs)
+ tasks.make_dbs(**kwargs)
+
+ assert create_calls == [
+ (seqres_path, tmp_path / "dbs/mmseqs", "mmseqs", 2),
+ ]
+
+
+def test_make_dbs_rebuilds_only_the_changed_file_input(tmp_path, monkeypatch) -> None:
+ cif_dir = tmp_path / "nextgen"
+ cif_dir.mkdir()
+ first_cif = cif_dir / "1abc.cif.gz"
+ second_cif = cif_dir / "2def.cif.gz"
+ first_cif.write_text("first")
+ second_cif.write_text("second")
+ cif_manifest = tmp_path / "foldseek-inputs.tsv"
+ cif_manifest.write_text(f"{first_cif}\n")
+ seqres_path = tmp_path / "pdb_seqres.txt.gz"
+ seqres_path.touch()
+ create_calls = []
+ monkeypatch.setattr(
+ tasks.databases,
+ "created_database_is_complete",
+ lambda *_args: True,
+ )
+ monkeypatch.setattr(
+ tasks.databases,
+ "create_db",
+ lambda source, output, kind, threads: create_calls.append(
+ (
+ source,
+ output,
+ kind,
+ threads,
+ )
+ ),
+ )
+
+ kwargs = {
+ "data_dir": tmp_path,
+ "sub_databases": ["holo"],
+ "cpu": 2,
+ "cif_root": cif_manifest,
+ "seqres_path": seqres_path,
+ "index": False,
+ }
+ tasks.make_dbs(**kwargs)
+ tasks.make_dbs(**kwargs)
+ first_cif.write_text("revised coordinates")
+ tasks.make_dbs(**kwargs)
+ cif_manifest.write_text(f"{first_cif}\n{second_cif}\n")
+ tasks.make_dbs(**kwargs)
+
+ assert create_calls == [
+ (cif_manifest, tmp_path / "dbs/foldseek", "foldseek", 2),
+ (seqres_path, tmp_path / "dbs/mmseqs", "mmseqs", 2),
+ (cif_manifest, tmp_path / "dbs/foldseek", "foldseek", 2),
+ (cif_manifest, tmp_path / "dbs/foldseek", "foldseek", 2),
+ ]
+
+
+def test_make_dbs_hashes_direct_foldseek_coordinate_files(
+ tmp_path, monkeypatch
+) -> None:
+ cif_path = tmp_path / "1abc.cif.gz"
+ cif_path.write_bytes(b"initial coordinates")
+ seqres_path = tmp_path / "pdb_seqres.txt.gz"
+ seqres_path.touch()
+ create_calls = []
+ monkeypatch.setattr(
+ tasks.databases,
+ "created_database_is_complete",
+ lambda *_args: True,
+ )
+ monkeypatch.setattr(
+ tasks.databases,
+ "create_db",
+ lambda source, output, kind, threads: create_calls.append(
+ (source, output, kind, threads)
+ ),
+ )
+
+ kwargs = {
+ "data_dir": tmp_path,
+ "sub_databases": ["holo"],
+ "cpu": 2,
+ "cif_root": cif_path,
+ "seqres_path": seqres_path,
+ "index": False,
+ }
+ tasks.make_dbs(**kwargs)
+ tasks.make_dbs(**kwargs)
+ cif_path.write_bytes(b"revised coordinates")
+ tasks.make_dbs(**kwargs)
+
+ assert create_calls == [
+ (cif_path, tmp_path / "dbs/foldseek", "foldseek", 2),
+ (seqres_path, tmp_path / "dbs/mmseqs", "mmseqs", 2),
+ (cif_path, tmp_path / "dbs/foldseek", "foldseek", 2),
+ ]
+
+
+def test_get_scorer_uses_configured_search_limits(tmp_path) -> None:
+ from plinder.data.pipeline import utils
+ from plinder.data.pipeline.config import get_config
+
+ cfg = get_config(
+ config={
+ "foldseek": {"max_seqs": 12_345},
+ "mmseqs": {"max_seqs": 6_789},
+ "scorer": {"sub_databases": "holo"},
+ },
+ cached=False,
+ )
+ scorer, _, batch_db_dir = utils.get_scorer(
+ data_dir=tmp_path,
+ pdb_ids=[],
+ scorer_cfg=cfg.scorer,
+ load_entries=False,
+ foldseek_cfg=cfg.foldseek,
+ mmseqs_cfg=cfg.mmseqs,
+ scratch_dir=tmp_path / "scratch",
+ )
+
+ assert scorer.get_config("holo", "foldseek").max_seqs == 12_345
+ assert scorer.get_config("holo", "mmseqs").max_seqs == 6_789
+ assert scorer.get_config("holo", "foldseek").min_seq_id == 0.2
+ assert scorer.get_config("holo", "mmseqs").min_seq_id == 0.2
+ assert scorer.get_config("apo", "foldseek").min_seq_id == 0.9
+ assert scorer.get_config("pred", "mmseqs").min_seq_id == 0.9
+ assert scorer.get_config("apo", "foldseek").coverage == 0.8
+ assert scorer.get_config("pred", "mmseqs").coverage == 0.9
+ assert batch_db_dir.parent == tmp_path / "scratch"
+ assert batch_db_dir.is_dir()
+ assert not (tmp_path / "dbs/subdbs/batch_dbs").exists()
+
+ from plinder.data.pipeline.score import _scoring_config
+
+ v3_scoring = _scoring_config(tmp_path, 10_000)
+ assert v3_scoring.foldseek.min_seq_id == 0.0
+ assert v3_scoring.mmseqs.min_seq_id == 0.0
+ apo_scoring = _scoring_config(
+ tmp_path,
+ 10_000,
+ sub_databases=["apo"],
+ )
+ assert apo_scoring.scorer.sub_databases == ["apo"]
+ assert apo_scoring.scorer.minimum_thresholds == {
+ "protein_lddt_weighted_sum": pytest.approx(0.2)
+ }
+
+
+def test_run_batch_searches_skips_completed_backend_queries(
+ tmp_path, monkeypatch
+) -> None:
+ completed = tmp_path / "dbs/subdbs/holo_foldseek/aln/1abc.parquet"
+ completed.parent.mkdir(parents=True)
+ completed.touch()
+ calls = []
+
+ class FakeScorer:
+ def run_alignments(self, **kwargs):
+ calls.append(kwargs)
+ alignment_type = kwargs["alignment_types"][0]
+ output = tmp_path / f"dbs/subdbs/holo_{alignment_type}/aln"
+ output.mkdir(parents=True, exist_ok=True)
+ for pdb_id in kwargs["entry_ids"]:
+ (output / f"{pdb_id}.parquet").touch()
+
+ def fake_get_scorer(*, pdb_ids, **_kwargs):
+ scratch = tmp_path / "scratch" / "-".join(pdb_ids)
+ scratch.mkdir(parents=True)
+ return FakeScorer(), pdb_ids, scratch
+
+ monkeypatch.setattr(tasks.utils, "get_scorer", fake_get_scorer)
+ monkeypatch.setattr(
+ tasks.databases,
+ "database_identifiers",
+ lambda _path: pytest.fail("query eligibility must not use target IDs"),
+ )
+ cfg = SimpleNamespace(sub_databases=["holo"])
+
+ tasks.run_batch_searches(
+ data_dir=tmp_path,
+ pdb_ids=["1abc", "2def"],
+ scorer_cfg=cfg,
+ foldseek_cfg=SimpleNamespace(),
+ mmseqs_cfg=SimpleNamespace(),
+ cpu=4,
+ scratch_dir=tmp_path / "node-scratch",
+ alignment_types=["foldseek", "mmseqs"],
+ )
+
+ assert [call["entry_ids"] for call in calls] == [
+ ["2def"],
+ ["1abc", "2def"],
+ ]
+ assert [call["alignment_types"] for call in calls] == [
+ ["foldseek"],
+ ["mmseqs"],
+ ]
+
+
+def test_run_batch_searches_uses_compact_linked_apo_query_chains(
+ tmp_path, monkeypatch
+) -> None:
+ calls = []
+ scorer_calls = []
+ selected_query_chains = {"apo": {"R"}, "interface_apo": {"S"}}
+ selections = {}
+ for search_db in selected_query_chains:
+ selection = tmp_path / f"dbs/subdbs/{search_db}_mmseqs/selection.json"
+ selection.parent.mkdir(parents=True)
+ selection.write_text(
+ json.dumps(
+ {
+ "identifier_sha256": f"{search_db}-1",
+ "target_database": {"sha256": f"{search_db}-content-1"},
+ }
+ )
+ )
+ selections[search_db] = selection
+
+ class FakeScorer:
+ def run_alignments(self, **kwargs):
+ calls.append(kwargs)
+ output = tmp_path / f"dbs/subdbs/{kwargs['search_db']}_mmseqs/aln"
+ output.mkdir(parents=True, exist_ok=True)
+ for pdb_id in kwargs["entry_ids"]:
+ table = pa.table({}).replace_schema_metadata(
+ kwargs["output_metadata_by_entry"][pdb_id]
+ )
+ pq.write_table(table, output / f"{pdb_id}.parquet")
+
+ def fake_get_scorer(**kwargs):
+ scorer_calls.append(kwargs)
+ scratch = tmp_path / "scratch" / "batch"
+ scratch.mkdir(parents=True, exist_ok=True)
+ return FakeScorer(), kwargs["pdb_ids"], scratch
+
+ monkeypatch.setattr(
+ tasks,
+ "_apo_query_auth_ids",
+ lambda _data_dir, _pdb_ids, *, search_db: {
+ "1abc": set(selected_query_chains[search_db])
+ },
+ )
+ monkeypatch.setattr(tasks.utils, "get_scorer", fake_get_scorer)
+ mmseqs_cfg = SimpleNamespace(
+ evalue=0.01,
+ sensitivity=11.0,
+ max_seqs=10_000,
+ )
+
+ tasks.run_batch_searches(
+ data_dir=tmp_path,
+ pdb_ids=["1abc", "2def"],
+ scorer_cfg=SimpleNamespace(sub_databases=["apo"]),
+ foldseek_cfg=SimpleNamespace(),
+ mmseqs_cfg=mmseqs_cfg,
+ cpu=4,
+ scratch_dir=tmp_path / "node-scratch",
+ alignment_types=["mmseqs"],
+ )
+
+ assert [call["load_entries"] for call in scorer_calls] == [False, False]
+ assert [call["pdb_ids"] for call in scorer_calls] == [["1abc"], ["1abc"]]
+ assert [call["search_db"] for call in calls] == ["apo", "interface_apo"]
+ assert [call["query_chain_auth_ids"] for call in calls] == [
+ {"1abc": {"R"}},
+ {"1abc": {"S"}},
+ ]
+
+ # An unchanged apo search is reused.
+ tasks.run_batch_searches(
+ data_dir=tmp_path,
+ pdb_ids=["1abc"],
+ scorer_cfg=SimpleNamespace(sub_databases=["apo"]),
+ foldseek_cfg=SimpleNamespace(),
+ mmseqs_cfg=mmseqs_cfg,
+ cpu=4,
+ scratch_dir=tmp_path / "node-scratch",
+ alignment_types=["mmseqs"],
+ )
+ assert len(calls) == 2
+
+ # Moving the same selected target database does not invalidate searches.
+ selections["apo"].write_text(
+ json.dumps(
+ {
+ "identifier_sha256": "apo-1",
+ "target_database": {"sha256": "apo-content-1"},
+ "source_lookup": {
+ "path": "/another/release/full.lookup",
+ "size": 123,
+ "mtime_ns": 456,
+ },
+ }
+ )
+ )
+ tasks.run_batch_searches(
+ data_dir=tmp_path,
+ pdb_ids=["1abc"],
+ scorer_cfg=SimpleNamespace(sub_databases=["apo"]),
+ foldseek_cfg=SimpleNamespace(),
+ mmseqs_cfg=mmseqs_cfg,
+ cpu=4,
+ scratch_dir=tmp_path / "node-scratch",
+ alignment_types=["mmseqs"],
+ )
+ assert len(calls) == 2
+
+ # A changed backend search setting invalidates both MMseqs result caches.
+ mmseqs_cfg.max_seqs = 20_000
+ tasks.run_batch_searches(
+ data_dir=tmp_path,
+ pdb_ids=["1abc"],
+ scorer_cfg=SimpleNamespace(sub_databases=["apo"]),
+ foldseek_cfg=SimpleNamespace(),
+ mmseqs_cfg=mmseqs_cfg,
+ cpu=4,
+ scratch_dir=tmp_path / "node-scratch",
+ alignment_types=["mmseqs"],
+ )
+ assert len(calls) == 4
+
+ # Changed target content invalidates the result even when IDs are unchanged.
+ selections["apo"].write_text(
+ json.dumps(
+ {
+ "identifier_sha256": "apo-1",
+ "target_database": {"sha256": "apo-content-2"},
+ }
+ )
+ )
+ tasks.run_batch_searches(
+ data_dir=tmp_path,
+ pdb_ids=["1abc"],
+ scorer_cfg=SimpleNamespace(sub_databases=["apo"]),
+ foldseek_cfg=SimpleNamespace(),
+ mmseqs_cfg=mmseqs_cfg,
+ cpu=4,
+ scratch_dir=tmp_path / "node-scratch",
+ alignment_types=["mmseqs"],
+ )
+ assert len(calls) == 5
+
+ # Expanding either side of the search invalidates the cached result.
+ selected_query_chains["apo"].add("T")
+ tasks.run_batch_searches(
+ data_dir=tmp_path,
+ pdb_ids=["1abc"],
+ scorer_cfg=SimpleNamespace(sub_databases=["apo"]),
+ foldseek_cfg=SimpleNamespace(),
+ mmseqs_cfg=mmseqs_cfg,
+ cpu=4,
+ scratch_dir=tmp_path / "node-scratch",
+ alignment_types=["mmseqs"],
+ )
+ selections["apo"].write_text(
+ json.dumps(
+ {
+ "identifier_sha256": "apo-2",
+ "target_database": {"sha256": "apo-content-2"},
+ }
+ )
+ )
+ tasks.run_batch_searches(
+ data_dir=tmp_path,
+ pdb_ids=["1abc"],
+ scorer_cfg=SimpleNamespace(sub_databases=["apo"]),
+ foldseek_cfg=SimpleNamespace(),
+ mmseqs_cfg=mmseqs_cfg,
+ cpu=4,
+ scratch_dir=tmp_path / "node-scratch",
+ alignment_types=["mmseqs"],
+ )
+ assert len(calls) == 7
+
+ # Forced repair bypasses malformed cache metadata and replaces the output.
+ pq.write_table(pa.table({}), tmp_path / "dbs/subdbs/apo_mmseqs/aln/1abc.parquet")
+ tasks.run_batch_searches(
+ data_dir=tmp_path,
+ pdb_ids=["1abc"],
+ scorer_cfg=SimpleNamespace(sub_databases=["apo"]),
+ foldseek_cfg=SimpleNamespace(),
+ mmseqs_cfg=mmseqs_cfg,
+ cpu=4,
+ scratch_dir=tmp_path / "node-scratch",
+ alignment_types=["mmseqs"],
+ search_databases=["apo"],
+ force_update=True,
+ )
+ assert len(calls) == 8
+
+
+def test_run_batch_searches_rejects_missing_eligible_output(tmp_path, monkeypatch):
+ class FakeScorer:
+ def run_alignments(self, **_kwargs):
+ return None
+
+ scratch = tmp_path / "scratch"
+ scratch.mkdir()
+ monkeypatch.setattr(
+ tasks.utils,
+ "get_scorer",
+ lambda **_kwargs: (FakeScorer(), ["1abc"], scratch),
+ )
+ monkeypatch.setattr(
+ tasks.databases,
+ "database_identifiers",
+ lambda _path: {"1abc_A"},
+ )
+
+ with pytest.raises(RuntimeError, match="no output.*1 query"):
+ tasks.run_batch_searches(
+ data_dir=tmp_path,
+ pdb_ids=["1abc"],
+ scorer_cfg=SimpleNamespace(sub_databases=["holo"]),
+ foldseek_cfg=SimpleNamespace(),
+ mmseqs_cfg=SimpleNamespace(),
+ cpu=1,
+ scratch_dir=tmp_path / "node-scratch",
+ alignment_types=["mmseqs"],
+ )
+
+
+@pytest.mark.parametrize("alignment_type", ["foldseek", "mmseqs"])
+def test_alignment_release_shard_preserves_typed_schema_when_all_hits_are_empty(
+ tmp_path, alignment_type
+) -> None:
+ schema = schemas.mapped_alignment_schema(alignment_type=alignment_type)
+ source = tmp_path / "mapped" / "1abc.parquet"
+ source.parent.mkdir()
+ pq.write_table(pa.Table.from_pylist([], schema=schema), source)
+ target = tmp_path / f"shard-{alignment_type}.parquet"
+
+ tasks._write_alignment_release_shard(
+ sources=[source],
+ target=target,
+ alignment_type=alignment_type,
+ temp_dir=tmp_path / "scratch" / alignment_type,
+ threads=1,
+ memory_limit="1GB",
+ )
+
+ assert pq.ParquetFile(target).metadata.num_rows == 0
+ assert pq.read_schema(target).equals(
+ schemas.release_alignment_mapping_schema(alignment_type=alignment_type)
+ )
+
+
+def test_alignment_release_shard_unifies_empty_and_populated_list_types(
+ tmp_path,
+) -> None:
+ columns = {
+ "query_entry": ["1abc"],
+ "target_entry": ["2def"],
+ "query_chain_mapped": ["A"],
+ "target_chain_mapped": ["B"],
+ "source": ["foldseek"],
+ "qstart": [1],
+ "tstart": [1],
+ "cigar": ["1M"],
+ "qcov": [1.0],
+ "tcov": [1.0],
+ "fident": [1.0],
+ "seqsim": [1.0],
+ "query_selected_residue_numbers": [[]],
+ "target_selected_residue_numbers": [[]],
+ "query_selected_residue_positions": [[]],
+ "target_selected_residue_positions": [[]],
+ "selected_residue_identity_bits": [b""],
+ "lddt": [1.0],
+ }
+ empty_lists = tmp_path / "mapped" / "1abc.parquet"
+ populated_lists = tmp_path / "mapped" / "2abc.parquet"
+ empty_lists.parent.mkdir()
+ pd.DataFrame(columns).to_parquet(empty_lists, index=False)
+ populated = dict(columns)
+ populated["query_entry"] = ["2abc"]
+ populated["query_selected_residue_numbers"] = [[1]]
+ populated["target_selected_residue_numbers"] = [[2]]
+ populated["query_selected_residue_positions"] = [[1]]
+ populated["target_selected_residue_positions"] = [[1]]
+ populated["selected_residue_identity_bits"] = [bytes([1])]
+ pd.DataFrame(populated).to_parquet(populated_lists, index=False)
+ target = tmp_path / "foldseek.parquet"
+ protein_scores = tmp_path / "protein_scores.parquet"
+
+ tasks._write_alignment_release_shard(
+ sources=[empty_lists, populated_lists],
+ target=target,
+ alignment_type="foldseek",
+ temp_dir=tmp_path / "scratch",
+ threads=1,
+ memory_limit="1GB",
+ protein_scores_target=protein_scores,
+ )
+
+ from plinder.core.scores.mapping import decode_cigar_residue_positions
+
+ result = decode_cigar_residue_positions(
+ pd.read_parquet(target),
+ chain_lookup=_write_selected_residue_lookup(
+ tmp_path,
+ [
+ {
+ "entry_pdb_id": "1abc",
+ "chain_asym_id": "A",
+ "selected_residue_numbers": [],
+ "selected_residue_indices": [],
+ },
+ {
+ "entry_pdb_id": "2abc",
+ "chain_asym_id": "A",
+ "selected_residue_numbers": [1],
+ "selected_residue_indices": [0],
+ },
+ {
+ "entry_pdb_id": "2def",
+ "chain_asym_id": "B",
+ "selected_residue_numbers": [2],
+ "selected_residue_indices": [0],
+ },
+ ],
+ ),
+ )
+ assert result["query_entry"].tolist() == ["1abc", "2abc"]
+ assert list(result.loc[0, "query_selected_residue_positions"]) == []
+ assert list(result.loc[1, "query_selected_residue_positions"]) == [1]
+ assert list(result.loc[1, "target_selected_residue_positions"]) == [1]
+ score_result = pd.read_parquet(protein_scores)
+ assert pq.read_schema(protein_scores).equals(
+ schemas.PROTEIN_SIMILARITY_EXPORT_SCHEMA
+ )
+ assert score_result[["qcov", "tcov", "fident", "seqsim", "lddt"]].to_dict(
+ "records"
+ ) == [
+ {"qcov": 100, "tcov": 100, "fident": 100, "seqsim": 100, "lddt": 100},
+ {"qcov": 100, "tcov": 100, "fident": 100, "seqsim": 100, "lddt": 100},
+ ]
+
+
+def test_ligand_score_threshold_must_cover_requested_chemical_clusters() -> None:
+ from plinder.data.pipeline.config import get_config
+
+ with pytest.raises(ValueError, match=r"clustering threshold \(30\)"):
+ get_config(
+ config={"ligand": {"minimum_similarity": 60}},
+ cached=False,
+ )
+
+
+def test_derived_score_threshold_must_cover_requested_clusters() -> None:
+ from plinder.data.pipeline.config import get_config
+
+ with pytest.raises(ValueError, match=r"clustering threshold \(30\)"):
+ get_config(
+ config={"scorer": {"minimum_threshold": 0.31}},
+ cached=False,
+ )
+
+
+def test_collate_alignments_writes_query_addressable_shards(tmp_path):
+ columns = {
+ "query_entry": ["1abc", "2abd", "3xyz"],
+ "target_entry": ["9zzz", "8yyy", "7xxx"],
+ "query_chain_mapped": ["A", "B", "C"],
+ "target_chain_mapped": ["D", "E", "F"],
+ "source": ["foldseek"] * 3,
+ "qcov": [1.0, 0.9, 0.8],
+ "tcov": [1.0, 0.9, 0.8],
+ "fident": [1.0, 0.9, 0.8],
+ "seqsim": [1.0, 0.9, 0.8],
+ "qstart": [1, 1, 1],
+ "tstart": [1, 1, 1],
+ "cigar": ["1M", "1M", "1M"],
+ "query_selected_residue_numbers": [[1], [2], [3]],
+ "target_selected_residue_numbers": [[11], [12], [13]],
+ "query_selected_residue_positions": [[1], [1], [1]],
+ "target_selected_residue_positions": [[1], [1], [1]],
+ "selected_residue_identity_bits": [bytes([1])] * 3,
+ "lddt": [1.0, 0.9, 0.8],
+ }
+ mapped_dir = tmp_path / "dbs/subdbs/holo_foldseek/mapped_aln"
+ mapped_dir.mkdir(parents=True)
+ for index, pdb_id in enumerate(columns["query_entry"]):
+ pd.DataFrame(
+ {column: [values[index]] for column, values in columns.items()}
+ ).to_parquet(mapped_dir / f"{pdb_id}.parquet", index=False)
+ # An interrupted atomic install must not become a query or shard.
+ pd.DataFrame(
+ {column: [values[0]] for column, values in columns.items()}
+ ).to_parquet(mapped_dir / "4qp3.tmp.parquet", index=False)
+ assert tasks.scatter_collate_alignments(data_dir=tmp_path) == [["ab"], ["xy"]]
+ tasks.collate_alignments(data_dir=tmp_path, partition=["ab"])
+
+ shard = pd.read_parquet(
+ tmp_path
+ / "alignment_cigars/search_db=holo/alignment_type=foldseek/shard=ab.parquet"
+ )
+ assert shard["query_entry"].tolist() == ["1abc", "2abd"]
+ assert "3xyz" not in set(shard["query_entry"])
+ assert set(shard.columns) == set(
+ schemas.release_alignment_mapping_schema(
+ alignment_type="foldseek", include_scores=False
+ ).names
+ )
+ assert schemas.release_alignment_mapping_schema_is_current(
+ set(shard.columns), alignment_type="foldseek", include_scores=False
+ )
+ assert not schemas.release_alignment_mapping_schema_is_current(
+ set(shard.columns), alignment_type="foldseek"
+ )
+ assert shard["cigar"].tolist() == ["1M", "1M"]
+ assert "query_selected_residue_positions" not in shard
+
+
+def test_empty_alignment_scatter_has_noop_branch(tmp_path):
+ assert tasks.scatter_collate_alignments(data_dir=tmp_path) == [[]]
+ tasks.collate_alignments(data_dir=tmp_path, partition=[])
+
+
+def test_mapping_scatter_requires_current_shard_manifest(tmp_path):
+ raw_dir = tmp_path / "dbs/subdbs/holo_foldseek/aln"
+ raw_dir.mkdir(parents=True)
+ pd.DataFrame({"query": ["1abc_A"]}).to_parquet(
+ raw_dir / "1abc.parquet", index=False
+ )
+
+ assert tasks.scatter_missing_alignment_mappings(
+ data_dir=tmp_path, batch_size=10
+ ) == [["ab"]]
+
+ current_columns = {
+ "query_entry": ["1abc"],
+ "target_entry": ["1abc"],
+ "query_chain_mapped": ["A"],
+ "target_chain_mapped": ["A"],
+ "source": ["foldseek"],
+ "qcov": [1.0],
+ "tcov": [1.0],
+ "fident": [1.0],
+ "seqsim": [1.0],
+ "query_start": [1],
+ "target_start": [1],
+ "cigar": ["1M"],
+ "selected_residue_identity_bits": [bytes([1])],
+ "lddt": [1.0],
+ }
+ release = tasks._alignment_release_path(
+ data_dir=tmp_path,
+ search_db="holo",
+ alignment_type="foldseek",
+ shard="ab",
+ )
+ release.parent.mkdir(parents=True)
+ pd.DataFrame(current_columns).to_parquet(release, index=False)
+ _write_alignment_mapping_manifest(tmp_path, "ab")
+ assert tasks.scatter_missing_alignment_mappings(
+ data_dir=tmp_path, batch_size=10
+ ) == [[]]
+
+
+def test_missing_score_scatter_includes_mapped_apo_queries(tmp_path) -> None:
+ scorer_cfg = SimpleNamespace(
+ minimum_threshold=0.3,
+ minimum_thresholds={"protein_lddt_weighted_sum": 0.2},
+ )
+ raw = tmp_path / "dbs/subdbs/apo_foldseek/aln/1abc.parquet"
+ raw.parent.mkdir(parents=True)
+ pd.DataFrame({"query": ["1abc_A"]}).to_parquet(raw, index=False)
+ release = tasks._alignment_release_path(
+ data_dir=tmp_path,
+ search_db="apo",
+ alignment_type="foldseek",
+ shard="ab",
+ )
+ release.parent.mkdir(parents=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [],
+ schema=schemas.release_alignment_mapping_schema(alignment_type="foldseek"),
+ ),
+ release,
+ )
+ _write_alignment_mapping_manifest(
+ tmp_path,
+ "ab",
+ search_db="apo",
+ )
+
+ assert tasks.scatter_missing_scores(
+ data_dir=tmp_path,
+ batch_size=10,
+ scorer_cfg=scorer_cfg,
+ search_dbs=["apo"],
+ ) == [["1abc"]]
+
+ score = tmp_path / "dbs/subdbs/search_db=apo/1abc.parquet"
+ score.parent.mkdir(parents=True)
+ score.touch()
+ assert tasks.scatter_missing_scores(
+ data_dir=tmp_path,
+ batch_size=10,
+ scorer_cfg=scorer_cfg,
+ search_dbs=["apo"],
+ ) == [["1abc"]]
+
+ pq.write_table(
+ pa.Table.from_batches([], schema=schemas.PROTEIN_SIMILARITY_SCHEMA),
+ score,
+ )
+ assert tasks.scatter_missing_scores(
+ data_dir=tmp_path,
+ batch_size=10,
+ scorer_cfg=scorer_cfg,
+ search_dbs=["apo"],
+ ) == [["1abc"]]
+
+ current_schema = schemas.PROTEIN_SIMILARITY_SCHEMA.with_metadata(
+ {
+ b"plinder.ligand_3d": b"complete",
+ SCORE_THRESHOLDS_METADATA_KEY: score_thresholds_metadata(
+ scorer_cfg.minimum_threshold,
+ scorer_cfg.minimum_thresholds,
+ ),
+ SCORE_METRICS_METADATA_KEY: score_metrics_metadata(
+ {
+ "pocket_fident",
+ "protein_fident_weighted_sum",
+ "protein_fident_qcov_weighted_sum",
+ "protein_lddt_weighted_sum",
+ }
+ ),
+ }
+ )
+ pq.write_table(pa.Table.from_batches([], schema=current_schema), score)
+ assert tasks.scatter_missing_scores(
+ data_dir=tmp_path,
+ batch_size=10,
+ scorer_cfg=scorer_cfg,
+ search_dbs=["apo"],
+ ) == [[]]
+
+
+def test_replace_release_alignment_queries_keeps_unaffected_rows(tmp_path):
+ old = tmp_path / "release.parquet"
+ new = tmp_path / "new.parquet"
+ pd.DataFrame(
+ {"query_entry": ["1abc", "2abc", "3abc"], "target_entry": ["old"] * 3}
+ ).to_parquet(old, index=False)
+ pd.DataFrame({"query_entry": ["2abc"], "target_entry": ["new"]}).to_parquet(
+ new, index=False
+ )
+
+ tasks._replace_release_alignment_queries(
+ old=old,
+ new=new,
+ replacements={"2abc", "3abc"},
+ scratch_dir=tmp_path / "scratch",
+ )
+
+ actual = pd.read_parquet(old).sort_values("query_entry").reset_index(drop=True)
+ expected = pd.DataFrame(
+ {"query_entry": ["1abc", "2abc"], "target_entry": ["old", "new"]}
+ )
+ pd.testing.assert_frame_equal(actual, expected)
+
+
+def test_replace_release_alignment_queries_only_changes_selected_targets(tmp_path):
+ old = tmp_path / "release.parquet"
+ new = tmp_path / "new.parquet"
+ pd.DataFrame(
+ {
+ "query_entry": ["1abc", "1abc", "2abc"],
+ "target_entry": ["3abc", "4abc", "3abc"],
+ "score": [1, 2, 3],
+ }
+ ).to_parquet(old, index=False)
+ pd.DataFrame(
+ {"query_entry": ["1abc"], "target_entry": ["3abc"], "score": [9.0]}
+ ).to_parquet(new, index=False)
+
+ tasks._replace_release_alignment_queries(
+ old=old,
+ new=new,
+ replacements={"1abc"},
+ replacement_target_ids={"3abc"},
+ scratch_dir=tmp_path / "scratch",
+ )
+
+ actual = pd.read_parquet(old).sort_values(
+ ["query_entry", "target_entry"], ignore_index=True
+ )
+ expected = pd.DataFrame(
+ {
+ "query_entry": ["1abc", "1abc", "2abc"],
+ "target_entry": ["3abc", "4abc", "3abc"],
+ "score": [9, 2, 3],
+ }
+ )
+ pd.testing.assert_frame_equal(actual, expected)
+
+
+@pytest.mark.parametrize("search_db", ["holo", "apo"])
+def test_map_batch_alignments_publishes_atomic_shard(tmp_path, monkeypatch, search_db):
+ raw_dir = tmp_path / f"dbs/subdbs/{search_db}_foldseek/aln"
+ raw_dir.mkdir(parents=True)
+ pd.DataFrame({"query": ["1abc_A"], "target_pdb_id": ["1abc"]}).to_parquet(
+ raw_dir / "1abc.parquet", index=False
+ )
+ _write_alignment_chain_lookup(tmp_path)
+ calls = []
+ identity = [1.0]
+
+ class FakeScorer:
+ entries = {}
+
+ def map_alignment_files(self, *_args, **kwargs):
+ calls.append(kwargs)
+ output = (
+ kwargs["mapped_db_dir"]
+ / f"{search_db}_foldseek/mapped_aln/1abc.parquet"
+ )
+ output.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query_entry": ["1abc"],
+ "target_entry": ["1abc"],
+ "query_chain_mapped": ["A"],
+ "target_chain_mapped": ["A"],
+ "source": ["foldseek"],
+ "qcov": [1.0],
+ "tcov": [1.0],
+ "fident": identity,
+ "seqsim": [1.0],
+ "qstart": [1],
+ "tstart": [1],
+ "cigar": ["1M"],
+ "query_selected_residue_numbers": [[10]],
+ "target_selected_residue_numbers": [[10]],
+ "query_selected_residue_positions": [[1]],
+ "target_selected_residue_positions": [[1]],
+ "selected_residue_identity_bits": [bytes([1])],
+ "lddt": [1.0],
+ }
+ ).to_parquet(output, index=False)
+ return [output]
+
+ monkeypatch.setattr(
+ tasks.utils,
+ "get_scorer",
+ lambda **_kwargs: (FakeScorer(), ["1abc"], tmp_path / "unused"),
+ )
+ scratch = tmp_path / "scratch"
+ tasks.map_batch_alignments(
+ data_dir=tmp_path,
+ shards=["ab"],
+ scorer_cfg=SimpleNamespace(
+ sub_databases=[search_db],
+ ),
+ force_update=False,
+ scratch_dir=scratch,
+ search_db=search_db,
+ )
+
+ release = tasks._alignment_release_path(
+ data_dir=tmp_path,
+ search_db=search_db,
+ alignment_type="foldseek",
+ shard="ab",
+ )
+ assert pd.read_parquet(release)["query_entry"].tolist() == ["1abc"]
+ cigar = tasks._alignment_release_path(
+ data_dir=tmp_path,
+ search_db=search_db,
+ alignment_type="foldseek",
+ shard="ab",
+ )
+ row = pd.read_parquet(cigar).iloc[0].to_dict()
+ assert row["cigar"] == "1M"
+ assert row["selected_residue_identity_bits"] == b"\x01"
+ if search_db == "holo":
+ score_path = tasks._protein_similarity_score_path(
+ data_dir=tmp_path, alignment_type="foldseek", shard="ab"
+ )
+ assert pd.read_parquet(score_path)["fident"].tolist() == [100]
+ else:
+ assert row["fident"] == 1.0
+ assert tasks.alignment_mapping_shard_is_current(
+ data_dir=tmp_path,
+ search_db=search_db,
+ shard="ab",
+ )
+ assert not (tmp_path / f"dbs/subdbs/{search_db}_foldseek/mapped_aln").exists()
+ assert not any(scratch.iterdir())
+
+ tasks.map_batch_alignments(
+ data_dir=tmp_path,
+ shards=["ab"],
+ scorer_cfg=SimpleNamespace(
+ sub_databases=[search_db],
+ ),
+ force_update=False,
+ scratch_dir=scratch,
+ search_db=search_db,
+ )
+ assert len(calls) == 1
+
+ identity[0] = 0.5
+ tasks.map_batch_alignments(
+ data_dir=tmp_path,
+ shards=["ab"],
+ scorer_cfg=SimpleNamespace(sub_databases=[search_db]),
+ force_update=True,
+ scratch_dir=scratch,
+ search_db=search_db,
+ replacement_query_ids={"1abc"},
+ )
+ if search_db == "holo":
+ assert pd.read_parquet(score_path)["fident"].tolist() == [50]
+ else:
+ assert pd.read_parquet(cigar)["fident"].tolist() == [0.5]
+ (raw_dir / "1abc.parquet").unlink()
+ assert not tasks.alignment_mapping_shard_is_current(
+ data_dir=tmp_path, search_db=search_db, shard="ab"
+ )
+ assert tasks.alignment_mapping_shard_is_current(
+ data_dir=tmp_path,
+ search_db=search_db,
+ shard="ab",
+ require_raw_inputs=False,
+ )
+
+
+def test_map_batch_alignments_records_and_skips_oversized_queries(
+ tmp_path, monkeypatch
+) -> None:
+ raw_dir = tmp_path / "dbs/subdbs/holo_foldseek/aln"
+ raw_dir.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query": ["1abc_A", "1abc_A"],
+ "target_pdb_id": ["1abc", "1abc"],
+ }
+ ).to_parquet(raw_dir / "1abc.parquet", index=False)
+ _write_alignment_chain_lookup(tmp_path)
+
+ class FakeScorer:
+ entries = {}
+
+ def map_alignment_files(self, *_args, **_kwargs):
+ raise AssertionError("oversized query must not be mapped")
+
+ monkeypatch.setattr(
+ tasks.utils,
+ "get_scorer",
+ lambda **_kwargs: (FakeScorer(), [], tmp_path / "unused"),
+ )
+
+ tasks.map_batch_alignments(
+ data_dir=tmp_path,
+ shards=["ab"],
+ scorer_cfg=SimpleNamespace(
+ sub_databases=["holo"], max_alignment_rows_per_query=1
+ ),
+ force_update=True,
+ scratch_dir=tmp_path / "scratch",
+ )
+
+ manifest = json.loads(
+ tasks._alignment_mapping_manifest_path(
+ data_dir=tmp_path, shard="ab"
+ ).read_text()
+ )
+ assert manifest["skipped_queries"] == {
+ "1abc": {
+ "reason": "raw_alignment_row_budget_exceeded",
+ "maximum_rows": 1,
+ "total_rows": 2,
+ "rows_by_alignment_type": {"foldseek": 2},
+ }
+ }
+ release = tasks._alignment_release_path(
+ data_dir=tmp_path,
+ search_db="holo",
+ alignment_type="foldseek",
+ shard="ab",
+ )
+ assert pd.read_parquet(release).empty
+ assert tasks.alignment_mapping_shard_is_current(data_dir=tmp_path, shard="ab")
+
+
+def test_alignment_chain_lookup_compacts_mapping_inputs(tmp_path) -> None:
+ from plinder.core.scores.entries import load_alignment_entry_views
+
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "1abc"],
+ "system_id": [
+ "1abc__1__1.A__1.L",
+ "1abc__1__1.A__1.M",
+ ],
+ "system_type": ["holo", "holo"],
+ "ligand_id": ["1abc__1__1.L", "1abc__1__1.M"],
+ "ligand_asym_id": ["L", "M"],
+ "ligand_is_proper": [True, False],
+ "ligand_is_shape_comparable": [True, False],
+ "ligand_protein_chains_asym_id": [["1.A"], ["1.A"]],
+ "ligand_neighboring_residues": [
+ ["1.A_10_9_10", "1.A_11_10_11"],
+ ["1.A_99_98_99"],
+ ],
+ "ligand_interacting_residues": [
+ ["1.A_10_9_10", "1.A_11_10_11"],
+ ["1.A_99_98_99"],
+ ],
+ "ligand_interactions": [["1.A_contact"], []],
+ }
+ ).to_parquet(index / "annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "1abc", "1abc"],
+ "chain_asym_id": ["A", "B", "C"],
+ "chain_auth_id": ["X", "Y", "Z"],
+ "chain_receptor_type": ["protein", "dna", "protein"],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": "1abc__1__1.A--1.C",
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.A",
+ "interface_chain_2": "1.C",
+ "interface_chain_1_residue_numbers": [11, 12],
+ "interface_chain_1_residue_indices": [10, 11],
+ "interface_chain_2_residue_numbers": [20, 21],
+ "interface_chain_2_residue_indices": [19, 20],
+ "interface_num_contact_residue_pairs": 3,
+ }
+ ],
+ schema=INTERFACE_ANNOTATION_SCHEMA,
+ ),
+ index / "interface_annotation_table.parquet",
+ )
+
+ lookup = tasks.make_alignment_chain_lookup(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ )
+
+ frame = pd.read_parquet(lookup)
+ assert frame["chain_asym_id"].tolist() == ["A", "C"]
+ assert frame.loc[0, "selected_residue_numbers"].tolist() == [10, 11, 12]
+ assert frame.loc[0, "selected_residue_indices"].tolist() == [9, 10, 11]
+ assert frame.loc[1, "selected_residue_numbers"].tolist() == [20, 21]
+ assert frame.loc[1, "selected_residue_indices"].tolist() == [19, 20]
+ assert tasks._completed_alignment_chain_lookup(tmp_path) is not None
+ manifest = tmp_path / tasks.ALIGNMENT_CHAIN_LOOKUP_MANIFEST_RELATIVE
+ assert manifest.is_file()
+ views = load_alignment_entry_views(lookup_path=lookup, pdb_ids=["1abc"])
+ assert views["1abc"].author_to_asym == {"X": "A", "Z": "C"}
+ assert views["1abc"].selected_index_to_number_per_chain == {
+ "A": {9: 10, 10: 11, 11: 12},
+ "C": {19: 20, 20: 21},
+ }
+
+ interface_path = index / "interface_annotation_table.parquet"
+ interface_table = pq.read_table(interface_path)
+ contact_count_index = interface_table.schema.get_field_index(
+ "interface_num_contact_residue_pairs"
+ )
+ interface_table = interface_table.set_column(
+ contact_count_index,
+ "interface_num_contact_residue_pairs",
+ pa.array([4], type=pa.int64()),
+ )
+ pq.write_table(
+ interface_table,
+ interface_path,
+ )
+ assert tasks._completed_alignment_chain_lookup(tmp_path) is None
+ tasks.make_alignment_chain_lookup(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch-refresh",
+ threads=1,
+ force_update=True,
+ )
+
+ annotation = index / "annotation_table.parquet"
+ annotation_frame = pd.read_parquet(annotation)
+ annotation_frame.loc[0, "ligand_is_proper"] = False
+ annotation_frame.to_parquet(annotation, index=False)
+ assert tasks._completed_alignment_chain_lookup(tmp_path) is None
+
+
+@pytest.mark.parametrize("change", ["system_rows", "chain_annotations"])
+def test_alignment_chain_lookup_keeps_identity_when_metadata_changes(
+ tmp_path: Path,
+ change: str,
+) -> None:
+ index = tmp_path / "index"
+ index.mkdir()
+ annotation = index / "annotation_table.parquet"
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "system_id": ["1abc__1__1.A__1.B"],
+ "system_type": ["holo"],
+ "ligand_id": ["1abc__1__1.B"],
+ "ligand_asym_id": ["B"],
+ "ligand_is_proper": [True],
+ "ligand_is_shape_comparable": [True],
+ "ligand_protein_chains_asym_id": [["1.A"]],
+ "ligand_neighboring_residues": [["1.A_10_9_10"]],
+ "ligand_interacting_residues": [["1.A_10_9_10"]],
+ "ligand_interactions": [["1.A_contact"]],
+ }
+ ).to_parquet(annotation, index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "chain_asym_id": ["A"],
+ "chain_auth_id": ["X"],
+ "chain_receptor_type": ["protein"],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ _write_empty_interface_index(index)
+ lookup = tasks.make_alignment_chain_lookup(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch-1",
+ threads=1,
+ )
+ original_stat = lookup.stat()
+ if change == "system_rows":
+ frame = pd.read_parquet(annotation)
+ frame["system_id"] = "1abc__2__1.A__1.B"
+ frame.to_parquet(annotation, index=False)
+ else:
+ chain_path = index / "entry_chains.parquet"
+ frame = pd.read_parquet(chain_path)
+ frame["chain_sequence_noncanonical"] = "(MSE)AA"
+ frame["chain_modified_residues"] = [["1:MSE:A:1"]]
+ frame.to_parquet(chain_path, index=False)
+
+ tasks.make_alignment_chain_lookup(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch-2",
+ threads=1,
+ force_update=change == "system_rows",
+ )
+
+ refreshed_stat = lookup.stat()
+ assert (refreshed_stat.st_size, refreshed_stat.st_mtime_ns) == (
+ original_stat.st_size,
+ original_stat.st_mtime_ns,
+ )
+ assert tasks._completed_alignment_chain_lookup(tmp_path) is not None
+
+
+def test_alignment_chain_lookup_replaces_an_unexpected_schema(tmp_path: Path) -> None:
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "system_id": ["1abc__1__1.A__1.B"],
+ "system_type": ["holo"],
+ "ligand_id": ["1abc__1__1.B"],
+ "ligand_asym_id": ["B"],
+ "ligand_is_proper": [True],
+ "ligand_is_shape_comparable": [True],
+ "ligand_protein_chains_asym_id": [["1.A"]],
+ "ligand_neighboring_residues": [["1.A_10_9_10"]],
+ "ligand_interacting_residues": [["1.A_10_9_10"]],
+ "ligand_interactions": [["1.A_contact"]],
+ }
+ ).to_parquet(index / "annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "chain_asym_id": ["A"],
+ "chain_auth_id": ["X"],
+ "chain_receptor_type": ["protein"],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ _write_empty_interface_index(index)
+ lookup = tasks.make_alignment_chain_lookup(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch-1",
+ threads=1,
+ )
+ unexpected = pd.read_parquet(lookup)
+ unexpected["extra"] = "unexpected"
+ unexpected.to_parquet(lookup, index=False)
+
+ tasks.make_alignment_chain_lookup(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch-2",
+ threads=1,
+ force_update=True,
+ )
+
+ assert pq.read_schema(lookup).names == [
+ "entry_pdb_id",
+ "chain_asym_id",
+ "chain_auth_id",
+ "selected_residue_numbers",
+ "selected_residue_indices",
+ ]
+ assert tasks._completed_alignment_chain_lookup(tmp_path) is not None
+
+
+def test_finalize_index_preserves_current_alignment_lookup(
+ tmp_path, monkeypatch
+) -> None:
+ _write_alignment_chain_lookup(tmp_path)
+ annotation = tmp_path / "index" / "annotation_table.parquet"
+ interface = tmp_path / "index" / "interface_annotation_table.parquet"
+
+ def enrich_index(
+ *,
+ data_dir: Path,
+ weekly_ligand_clusters: Path | None,
+ weekly_interface_clusters: Path | None,
+ ) -> None:
+ assert weekly_ligand_clusters is None
+ assert weekly_interface_clusters is None
+ frame = pd.read_parquet(data_dir / "index" / "annotation_table.parquet")
+ frame["example_cluster"] = "c0"
+ frame.to_parquet(data_dir / "index" / "annotation_table.parquet", index=False)
+ interface_frame = pd.read_parquet(
+ data_dir / "index" / "interface_annotation_table.parquet"
+ )
+ interface_frame["example_interface_cluster"] = "c0"
+ interface_frame.to_parquet(
+ data_dir / "index" / "interface_annotation_table.parquet", index=False
+ )
+
+ monkeypatch.setattr(tasks.utils, "finalize_index", enrich_index)
+ tasks.finalize_index(data_dir=tmp_path)
+
+ assert "example_cluster" in pd.read_parquet(annotation).columns
+ assert "example_interface_cluster" in pd.read_parquet(interface).columns
+ assert tasks._completed_alignment_chain_lookup(tmp_path) is not None
+
+
+def test_interface_cluster_columns_are_written_to_sidecar(tmp_path, monkeypatch):
+ from plinder.data.pipeline import utils
+
+ interfaces = pd.DataFrame(
+ {
+ "system_id": ["1abc__1__1.A--1.B", "2def__1__1.X--1.Y"],
+ "entry_pdb_id": ["1abc", "2def"],
+ }
+ )
+ index_dir = tmp_path / "index"
+ index_dir.mkdir()
+ representative = interfaces.loc[0, "system_id"]
+ side_nodes = [f"{representative}::side={side}" for side in (1, 2)]
+ pd.DataFrame({"representative_system_id": [representative]}).to_parquet(
+ index_dir / "interface_representatives.parquet", index=False
+ )
+ pd.DataFrame({"half_interface_id": side_nodes}).to_parquet(
+ index_dir / "interface_half_representatives.parquet", index=False
+ )
+ pd.DataFrame(
+ {
+ "system_id": interfaces["system_id"],
+ "representative_system_id": [representative, representative],
+ "side_1_half_interface_id": [side_nodes[0], side_nodes[0]],
+ "side_2_half_interface_id": [side_nodes[1], side_nodes[1]],
+ }
+ ).to_parquet(index_dir / "interface_membership.parquet", index=False)
+ artifact_rows = pd.DataFrame(
+ {
+ "system_id": [representative],
+ "label": ["c0"],
+ "metric": ["interface_qcov"],
+ "directed": [True],
+ "threshold": [50],
+ }
+ )
+ cover = (
+ tmp_path
+ / "interface_sampling/directed_set_cover"
+ / "metric=interface_qcov/threshold=50.parquet"
+ )
+ cover.parent.mkdir(parents=True)
+ artifact_rows.assign(
+ centroid_system_id=[representative],
+ similarity_to_centroid=100.0,
+ ).to_parquet(cover, index=False)
+ side_cover = (
+ tmp_path
+ / "interface_sampling/directed_set_cover"
+ / "metric=interface_side_qcov/threshold=50.parquet"
+ )
+ side_cover.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "system_id": side_nodes,
+ "label": ["c0", "c2"],
+ "metric": ["interface_side_qcov"] * 2,
+ "directed": [True] * 2,
+ "threshold": [50] * 2,
+ "centroid_system_id": side_nodes,
+ "similarity_to_centroid": [100.0] * 2,
+ }
+ ).to_parquet(side_cover, index=False)
+ for metric, nodes, labels in (
+ ("interface_qcov", [representative], ["r0"]),
+ ("interface_side_qcov", side_nodes, ["r1", "r1"]),
+ ):
+ component_file = (
+ tmp_path
+ / "interface_clusters/reductions"
+ / f"metric={metric}/labels/directed=false/threshold=50.parquet"
+ )
+ component_file.parent.mkdir(parents=True)
+ pd.DataFrame({"system_id": nodes, "label": labels}).to_parquet(
+ component_file, index=False
+ )
+
+ result = utils.build_interface_cluster_table(index=interfaces, data_dir=tmp_path)
+
+ assert result["interface_qcov__50__directed_set_cover"].tolist() == [
+ "c0",
+ "c0",
+ ]
+ assert result["interface_side_qcov__50__chain_1_directed_set_cover"].tolist() == [
+ "c0",
+ "c0",
+ ]
+ assert result["interface_side_qcov__50__chain_2_directed_set_cover"].tolist() == [
+ "c2",
+ "c2",
+ ]
+ assert result["interface_side_qcov__50__chain_1_reciprocal_component"].tolist() == [
+ "r1",
+ "r1",
+ ]
+ assert result["interface_side_qcov__50__chain_2_reciprocal_component"].tolist() == [
+ "r1",
+ "r1",
+ ]
+
+ pd.DataFrame(
+ {"system_id": ["ligand-system"], "ligand_id": ["ligand-1"]}
+ ).to_parquet(
+ index_dir / "annotation_table.parquet",
+ index=False,
+ )
+ interfaces.to_parquet(
+ index_dir / "interface_annotation_table.parquet",
+ index=False,
+ )
+ monkeypatch.setattr(
+ utils,
+ "add_ligand_3d_score_ability_column",
+ lambda *, index, data_dir: index,
+ )
+ monkeypatch.setattr(
+ utils,
+ "add_ligand_similarity_columns",
+ lambda *, index, data_dir: index,
+ )
+ monkeypatch.setattr(
+ utils,
+ "build_ligand_cluster_table",
+ lambda *, index, data_dir: index,
+ )
+
+ utils.finalize_index(data_dir=tmp_path)
+
+ finalized_interfaces = pd.read_parquet(
+ index_dir / "interface_annotation_table.parquet"
+ )
+ finalized_clusters = pd.read_parquet(index_dir / "interface_clusters.parquet")
+ assert "interface_qcov__50__directed_set_cover" not in finalized_interfaces
+ assert finalized_clusters["interface_qcov__50__directed_set_cover"].tolist() == [
+ "c0",
+ "c0",
+ ]
+
+ original_replace = Path.replace
+
+ def fail_interface_install(source: Path, target: Path) -> Path:
+ if source.name == "interface_annotation_table.tmp.parquet":
+ raise OSError("simulated interface-index install failure")
+ return original_replace(source, target)
+
+ monkeypatch.setattr(Path, "replace", fail_interface_install)
+ with pytest.raises(OSError, match="simulated interface-index install failure"):
+ utils.finalize_index(data_dir=tmp_path)
+ assert not (index_dir / "annotation_table.parquet").exists()
+
+
+def test_nonempty_interface_annotation_requires_cluster_artifacts(tmp_path):
+ from plinder.data.pipeline.utils import build_interface_cluster_table
+
+ with pytest.raises(FileNotFoundError, match="no published interface clusters"):
+ build_interface_cluster_table(
+ index=pd.DataFrame({"system_id": ["1abc__1__1.A--1.B"]}),
+ data_dir=tmp_path,
+ )
+
+
+def test_component_reduction_scatter_reads_each_physical_source_once(
+ tmp_path, monkeypatch
+):
+ score_a = tmp_path / "scores-a.parquet"
+ score_b = tmp_path / "scores-b.parquet"
+ ligand = tmp_path / "ligands.parquet"
+
+ def sources(*, data_dir, metric, entity_type="ligand"):
+ del data_dir
+ assert entity_type == "ligand"
+ if metric == "tanimoto_similarity_ecfp4_1024":
+ return [ligand]
+ return [score_a, score_b]
+
+ monkeypatch.setattr(tasks.clusters, "component_score_sources", sources)
+
+ assert tasks.scatter_component_reduction_sources(
+ data_dir=tmp_path,
+ metrics=[
+ "protein_lddt_max",
+ "sucos_shape_pocket_qcov",
+ "tanimoto_similarity_ecfp4_1024",
+ ],
+ batch_size=2,
+ ) == [[str(ligand), str(score_a)], [str(score_b)]]
+
+
+def test_score_partition_collation_stages_atomically_from_scratch(tmp_path):
+ source = tmp_path / "dbs" / "subdbs" / "search_db=holo"
+ source.mkdir(parents=True)
+ pd.DataFrame({"query_system": ["a"], "similarity": [30]}).to_parquet(
+ source / "abc1.parquet", index=False
+ )
+ pd.DataFrame({"query_system": ["b"], "similarity": [50]}).to_parquet(
+ source / "def1.parquet", index=False
+ )
+
+ tasks.collate_partitions(
+ data_dir=tmp_path,
+ partition=["1"],
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ )
+
+ output = pd.read_parquet(tmp_path / "scores" / "search_db=holo" / "1.parquet")
+ assert output.sort_values("query_system").to_dict("records") == [
+ {"query_system": "a", "similarity": 30, "search_db": "holo"},
+ {"query_system": "b", "similarity": 50, "search_db": "holo"},
+ ]
+ assert not (tmp_path / "scores" / "search_db=holo" / "1.parquet.tmp").exists()
+
+
+def test_component_reduction_task_copies_generic_source_once(tmp_path, monkeypatch):
+ source = (
+ tmp_path
+ / "ligand_clusters/symmetric_edges"
+ / "metric=sucos_shape_pocket_qcov"
+ / "bucket=000.parquet"
+ )
+ source.parent.mkdir(parents=True)
+ source.write_bytes(b"scores")
+ scratch = tmp_path / "scratch"
+ calls = []
+
+ monkeypatch.setattr(
+ tasks.clusters,
+ "component_node_universe",
+ lambda **kwargs: (["l1", "l2"], {"s1", "s2"}),
+ )
+ monkeypatch.setattr(
+ tasks.clusters,
+ "score_component_reduction_is_complete",
+ lambda **kwargs: False,
+ )
+ monkeypatch.setattr(
+ tasks.clusters,
+ "directed_cover_component_reduction_is_complete",
+ lambda **kwargs: False,
+ )
+
+ def record_reciprocal_reduction(**kwargs):
+ assert kwargs["read_path"].read_bytes() == b"scores"
+ calls.append(("reciprocal", kwargs["metric"]))
+ return {"outputs": []}
+
+ monkeypatch.setattr(
+ tasks.clusters,
+ "make_score_component_reduction",
+ record_reciprocal_reduction,
+ )
+
+ def record_cover_reduction(**kwargs):
+ assert kwargs["read_path"].read_bytes() == b"scores"
+ calls.append(("directed_cover", kwargs["metric"]))
+ return {"outputs": []}
+
+ monkeypatch.setattr(
+ tasks.clusters,
+ "make_directed_cover_component_reduction",
+ record_cover_reduction,
+ )
+
+ tasks.make_component_reductions(
+ data_dir=tmp_path,
+ source_paths=[str(source)],
+ metrics=["protein_lddt_max", "sucos_shape_pocket_qcov"],
+ thresholds=[30, 50, 70, 90, 100],
+ scratch_dir=scratch,
+ force_update=False,
+ )
+
+ assert calls == [
+ ("reciprocal", "sucos_shape_pocket_qcov"),
+ ("directed_cover", "sucos_shape_pocket_qcov"),
+ ]
+ assert list(scratch.iterdir()) == []
+
+
+def test_component_reduction_metric_workers_must_be_positive(tmp_path):
+ with pytest.raises(ValueError, match="metric workers must be positive"):
+ tasks.make_component_reductions(
+ data_dir=tmp_path,
+ source_paths=["unused.parquet"],
+ metrics=["pocket_qcov"],
+ thresholds=[30],
+ scratch_dir=tmp_path / "scratch",
+ force_update=False,
+ metric_workers=0,
+ )
+
+
+def test_clustering_plan_counts_set_covers_per_chemical_metric(tmp_path, monkeypatch):
+ from plinder.core.scores.metrics import CHEMICAL_CLUSTER_METRICS
+ from plinder.data.pipeline.score import plan_clustering
+
+ monkeypatch.setattr(
+ "plinder.data.pipeline.score.clusters.prepare_component_node_universe",
+ lambda data_dir, **kwargs: {"status": "complete"},
+ )
+ monkeypatch.setattr(
+ "plinder.data.pipeline.score.clusters.prepare_symmetric_edge_plan",
+ lambda **kwargs: {"batches": [{}], "plan_hash": "test-plan"},
+ )
+ universe_manifest = (
+ tmp_path / "ligand_clusters" / "reductions" / "node_universe.json"
+ )
+ universe_manifest.parent.mkdir(parents=True)
+ universe_manifest.write_text(json.dumps({"universe_hash": "test-universe"}))
+
+ plan = plan_clustering(
+ tmp_path,
+ metrics=["pocket_qcov", *CHEMICAL_CLUSTER_METRICS],
+ thresholds=[30, 100],
+ source_batch_size=2,
+ cover_batch_size=3,
+ symmetric_bucket_count=4,
+ )
+
+ # ECFP4 and MHFP6 each get one reciprocal set cover per threshold, while the
+ # single score metric gets one shared directed-cover task.
+ assert len(CHEMICAL_CLUSTER_METRICS) == 2
+ assert plan["set_cover_task_count"] == 4
+ assert plan["set_cover_batch_count"] == 2
+ assert plan["directed_cover_task_count"] == 1
+
+
+def test_clustering_plan_matches_slurm_array_bounds(tmp_path, monkeypatch):
+ from plinder.data.pipeline.score import (
+ _cluster_parameters,
+ _cover_batch,
+ _directed_cover_batch,
+ plan_clustering,
+ )
+
+ monkeypatch.setattr(
+ "plinder.data.pipeline.score.clusters.prepare_component_node_universe",
+ lambda data_dir, **kwargs: {"status": "complete"},
+ )
+ monkeypatch.setattr(
+ "plinder.data.pipeline.score.clusters.prepare_symmetric_edge_plan",
+ lambda **kwargs: {"batches": [{}, {}, {}], "plan_hash": "test-plan"},
+ )
+ universe_manifest = (
+ tmp_path / "ligand_clusters" / "reductions" / "node_universe.json"
+ )
+ universe_manifest.parent.mkdir(parents=True)
+ universe_manifest.write_text(json.dumps({"universe_hash": "test-universe"}))
+
+ plan = plan_clustering(
+ tmp_path,
+ metrics=["pocket_qcov", "tanimoto_similarity_ecfp4_1024"],
+ thresholds=[30, 100],
+ source_batch_size=2,
+ cover_batch_size=3,
+ symmetric_bucket_count=4,
+ )
+
+ assert plan["symmetric_fragment_batch_count"] == 3
+ assert plan["symmetric_edge_shard_count"] == 8
+ assert plan["component_reduction_batch_count"] == 8
+ assert plan["set_cover_task_count"] == 2
+ assert plan["set_cover_batch_count"] == 1
+ assert plan["directed_cover_batch_count"] == 1
+ assert _cover_batch(
+ metrics=["tanimoto_similarity_ecfp4_1024"],
+ thresholds=plan["thresholds"],
+ batch_index=0,
+ batch_size=3,
+ ) == [
+ ("tanimoto_similarity_ecfp4_1024", 100),
+ ("tanimoto_similarity_ecfp4_1024", 30),
+ ]
+ assert _directed_cover_batch(
+ metrics=["pocket_qcov"],
+ thresholds=plan["thresholds"],
+ batch_index=0,
+ batch_size=3,
+ ) == [("pocket_qcov", 100), ("pocket_qcov", 30)]
+ assert _cluster_parameters(
+ metrics=None,
+ thresholds=None,
+ entity_type="interface",
+ ) == (
+ ["interface_qcov", "interface_side_qcov"],
+ [100, 90, 70, 50, 30],
+ )
+
+
+def test_interface_cluster_plan_enforces_collated_ingest_threshold(tmp_path):
+ from plinder.data.pipeline.score import plan_clustering
+
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "system_id": ["1abc__1__1.A--1.B"],
+ "interface_chain_1_residue_numbers": [[1, 2, 3, 4, 5, 6]],
+ "interface_chain_2_residue_numbers": [[1, 2, 3, 4, 5, 6, 7]],
+ }
+ ).to_parquet(index / "interface_annotation_table.parquet", index=False)
+ (index / "collation.json").write_text(
+ json.dumps({"status": "complete", "interface_min_residues": 7})
+ )
+
+ with pytest.raises(ValueError, match="below the frozen minimum of 7"):
+ plan_clustering(tmp_path, entity_type="interface")
+
+
+def test_ligand_similarity_export_retains_complete_factor_scores(tmp_path):
+ from plinder.data.pipeline.score import (
+ MANIFEST_RELATIVE,
+ PLAN_RELATIVE,
+ SCORE_WORK_RELATIVE,
+ _source_signature,
+ export_ligand_similarity_scores_batch,
+ finalize_ligand_similarity_scores,
+ )
+
+ manifest = tmp_path / MANIFEST_RELATIVE
+ manifest.parent.mkdir(parents=True)
+ pd.DataFrame({"pdb_id": ["1abc", "2def"], "shard": ["ab", "de"]}).to_parquet(
+ manifest, index=False
+ )
+ score_work = tmp_path / SCORE_WORK_RELATIVE
+ pd.DataFrame({"pdb_id": ["1abc", "2def"]}).to_parquet(score_work, index=False)
+ (tmp_path / PLAN_RELATIVE).write_text(
+ json.dumps({"manifest": _source_signature(manifest)})
+ )
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def", "3ghi", "4jkl"],
+ "system_id": [
+ "1abc_system",
+ "2def_system",
+ "3ghi_system",
+ "4jkl_system",
+ ],
+ "ligand_id": [
+ "1abc__1__1.B",
+ "2def__1__1.Y",
+ "3ghi__1__1.Z",
+ "4jkl__1__1.W",
+ ],
+ "system_type": ["holo"] * 4,
+ "ligand_is_proper": [True, True, True, False],
+ "ligand_is_shape_comparable": [True, True, False, True],
+ }
+ ).to_parquet(index / "annotation_table.parquet", index=False)
+
+ rows = [
+ ("ab", "1abc", "B", "2def", "Y", 20, 15, 12, 0.5),
+ ("de", "2def", "Y", "1abc", "B", 80, 70, 60, 0.5),
+ ]
+ for (
+ shard,
+ query,
+ query_asym,
+ target,
+ target_asym,
+ qcov,
+ fident_qcov,
+ pli_qcov,
+ sucos,
+ ) in rows:
+ pair_score = {
+ "query_system": f"{query}_system",
+ "query_ligand_id": f"{query}__1__1.{query_asym}",
+ "query_entry": query,
+ "query_ligand_asym_id": query_asym,
+ "target_system": f"{target}_system",
+ "target_ligand_id": f"{target}__1__1.{target_asym}",
+ "target_entry": target,
+ "target_ligand_asym_id": target_asym,
+ "pocket_qcov": qcov,
+ "pocket_fident_qcov": fident_qcov,
+ "pli_qcov": pli_qcov,
+ }
+ pair_score_path = (
+ tmp_path / "scores" / "ligand_pair_score_shards" / f"shard={shard}.parquet"
+ )
+ pair_score_path.parent.mkdir(parents=True, exist_ok=True)
+ pq.write_table(
+ pa.Table.from_pylist([pair_score], schema=schemas.LIGAND_PAIR_SCORE_SCHEMA),
+ pair_score_path,
+ )
+ pair_path = tmp_path / "scores" / "ligand_3d_by_query" / f"{shard}.parquet"
+ pair_path.parent.mkdir(parents=True, exist_ok=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {
+ "query_entry": query,
+ "query_ligand_asym_id": query_asym,
+ "target_entry": target,
+ "target_ligand_asym_id": target_asym,
+ "shape": 0.6,
+ "color": 0.4,
+ "sucos_shape": sucos,
+ }
+ ],
+ schema=schemas.LIGAND_3D_SCORE_SCHEMA,
+ ),
+ pair_path,
+ )
+
+ shard_dir = tmp_path / "release-shards"
+ for batch_index in range(2):
+ export_ligand_similarity_scores_batch(
+ tmp_path,
+ output_dir=shard_dir,
+ batch_index=batch_index,
+ batch_size=1,
+ scratch_dir=tmp_path / "scratch" / str(batch_index),
+ threads=1,
+ memory_limit="1GB",
+ )
+ output = tmp_path / "exports" / "ligand_similarity_scores.parquet"
+ report = finalize_ligand_similarity_scores(
+ tmp_path,
+ source_dir=shard_dir,
+ output=output,
+ scratch_dir=tmp_path / "finalize-scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+
+ exported = pd.read_parquet(output)
+ assert sorted(exported["pocket_qcov"].tolist()) == [20, 80, 100, 100, 100]
+ assert sorted(exported["pocket_fident_qcov"].tolist()) == [
+ 15,
+ 70,
+ 100,
+ 100,
+ 100,
+ ]
+ assert sorted(exported["pli_qcov"].tolist()) == [12, 60, 100, 100, 100]
+ self_rows = exported[
+ exported["query_system"].eq(exported["target_system"])
+ & exported["query_ligand_id"].eq(exported["target_ligand_id"])
+ ]
+ assert sorted(self_rows["query_ligand_id"].tolist()) == [
+ "1abc__1__1.B",
+ "2def__1__1.Y",
+ "3ghi__1__1.Z",
+ ]
+ non_3d_self = self_rows[self_rows["query_ligand_id"].eq("3ghi__1__1.Z")]
+ assert non_3d_self["sucos_shape"].isna().all()
+ assert non_3d_self[["shape", "color"]].isna().all().all()
+ assert sorted(exported["shape"].dropna().tolist()) == [60, 60, 100, 100]
+ assert sorted(exported["color"].dropna().tolist()) == [40, 40, 100, 100]
+ assert report["row_count"] == 5
+ assert (
+ finalize_ligand_similarity_scores(
+ tmp_path,
+ source_dir=shard_dir,
+ output=output,
+ scratch_dir=tmp_path / "finalize-scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+ == report
+ )
+ cached = shard_dir / "ab.parquet"
+ cached_stat = cached.stat()
+ cached_manifest = cached.with_suffix(".json")
+ saved = json.loads(cached_manifest.read_text())
+ saved["inputs"]["pairs"]["path"] = "/previous-release/pairs.parquet"
+ saved["inputs"]["shape"]["path"] = "/previous-release/shape.parquet"
+ saved["output"]["path"] = "/previous-release/ab.parquet"
+ cached_manifest.write_text(json.dumps(saved))
+ export_ligand_similarity_scores_batch(
+ tmp_path,
+ output_dir=shard_dir,
+ shards=["ab"],
+ scratch_dir=tmp_path / "scratch" / "reuse",
+ threads=1,
+ memory_limit="1GB",
+ )
+ assert cached.stat().st_mtime_ns == cached_stat.st_mtime_ns
+ assert json.loads(cached_manifest.read_text())["output"]["path"] == str(
+ cached.resolve()
+ )
+
+
+@pytest.mark.parametrize("target_buckets", [1, 3])
+def test_interface_score_shards_retain_side_coverages_and_compact_export(
+ tmp_path, target_buckets
+):
+ from plinder.data.pipeline.score import (
+ INTERFACE_HALF_SIMILARITY_EXPORT_RELATIVE,
+ INTERFACE_SIMILARITY_EXPORT_RELATIVE,
+ _interface_score_repair_task_batches,
+ _interface_score_shard_batch,
+ _source_signature,
+ finalize_interface_half_similarity_scores,
+ finalize_interface_score_repair,
+ finalize_interface_similarity_scores,
+ plan_interface_score_repair,
+ plan_interface_scoring,
+ plan_protein_scoring,
+ score_interface_qcov_repair_batch,
+ score_interface_qcov_shards,
+ )
+
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": [
+ "1abc",
+ "1abc",
+ "1abc",
+ "2def",
+ "2def",
+ "3ghi",
+ "3ghi",
+ ],
+ "chain_asym_id": ["A", "B", "C", "X", "Y", "C", "D"],
+ "chain_receptor_type": ["protein"] * 7,
+ "chain_is_holo": [True, True, True, True, True, False, False],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ query_id = "1abc__1__1.A--1.B"
+ shared_half_id = "1abc__1__1.A--1.C"
+ target_id = "2def__1__1.X--1.Y"
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": query_id,
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.A",
+ "interface_chain_2": "1.B",
+ "interface_chain_1_residue_numbers": [1, 2, 3, 4],
+ "interface_chain_1_residue_indices": [0, 1, 2, 3],
+ "interface_chain_2_residue_numbers": [5, 6],
+ "interface_chain_2_residue_indices": [4, 5],
+ "interface_num_contact_residue_pairs": 4,
+ },
+ {
+ "entry_pdb_id": "2def",
+ "system_id": target_id,
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.X",
+ "interface_chain_2": "1.Y",
+ "interface_chain_1_residue_numbers": [10, 20],
+ "interface_chain_1_residue_indices": [9, 19],
+ "interface_chain_2_residue_numbers": [30, 40, 50],
+ "interface_chain_2_residue_indices": [29, 39, 49],
+ "interface_num_contact_residue_pairs": 4,
+ },
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": shared_half_id,
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.A",
+ "interface_chain_2": "1.C",
+ "interface_chain_1_residue_numbers": [1, 2, 3, 4],
+ "interface_chain_1_residue_indices": [0, 1, 2, 3],
+ "interface_chain_2_residue_numbers": [7, 8],
+ "interface_chain_2_residue_indices": [6, 7],
+ "interface_num_contact_residue_pairs": 4,
+ },
+ {
+ "entry_pdb_id": "3ghi",
+ "system_id": "3ghi__1__1.C--1.D",
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.C",
+ "interface_chain_2": "1.D",
+ "interface_chain_1_residue_numbers": [1, 2, 3],
+ "interface_chain_1_residue_indices": [0, 1, 2],
+ "interface_chain_2_residue_numbers": [4, 5, 6],
+ "interface_chain_2_residue_indices": [3, 4, 5],
+ "interface_num_contact_residue_pairs": 3,
+ },
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": "1abc__2__1.A--2.B",
+ "system_biounit_id": "2",
+ "interface_chain_1": "1.A",
+ "interface_chain_2": "2.B",
+ "interface_chain_1_residue_numbers": [1, 2, 3, 4],
+ "interface_chain_1_residue_indices": [0, 1, 2, 3],
+ "interface_chain_2_residue_numbers": [5, 6],
+ "interface_chain_2_residue_indices": [4, 5],
+ "interface_num_contact_residue_pairs": 4,
+ },
+ ],
+ schema=INTERFACE_ANNOTATION_SCHEMA,
+ ),
+ index / "interface_annotation_table.parquet",
+ )
+ plan_protein_scoring(tmp_path)
+ _write_selected_residue_lookup(
+ tmp_path,
+ [
+ {
+ "entry_pdb_id": "1abc",
+ "chain_asym_id": "A",
+ "selected_residue_numbers": [1, 2, 3, 4],
+ },
+ {
+ "entry_pdb_id": "1abc",
+ "chain_asym_id": "B",
+ "selected_residue_numbers": [5, 6],
+ },
+ {
+ "entry_pdb_id": "1abc",
+ "chain_asym_id": "C",
+ "selected_residue_numbers": [7, 8],
+ },
+ {
+ "entry_pdb_id": "2def",
+ "chain_asym_id": "X",
+ "selected_residue_numbers": [10, 20],
+ },
+ {
+ "entry_pdb_id": "2def",
+ "chain_asym_id": "Y",
+ "selected_residue_numbers": [30, 40, 50],
+ },
+ {
+ "entry_pdb_id": "3ghi",
+ "chain_asym_id": "C",
+ "selected_residue_numbers": [1, 2, 3],
+ },
+ {
+ "entry_pdb_id": "3ghi",
+ "chain_asym_id": "D",
+ "selected_residue_numbers": [4, 5, 6],
+ },
+ ],
+ )
+
+ mapped_rows = {
+ "ab": {
+ "foldseek": [
+ ("2def", "A", "Y", [1, 2, 3, 4], [30, 40, 50, -1]),
+ ("2def", "B", "X", [5, 6], [10, 20]),
+ ("1abc", "A", "A", [1, 2, 3, 4], [1, 2, 3, 4]),
+ ("1abc", "B", "C", [5, 6], [7, 8]),
+ ("1abc", "C", "B", [7, 8], [5, 6]),
+ ],
+ "mmseqs": [
+ ("2def", "A", "X", [1, 2, 3, 4], [10, -1, -1, -1]),
+ ("2def", "B", "Y", [5, 6], [30, 40]),
+ ],
+ },
+ "de": {
+ "foldseek": [
+ ("1abc", "X", "A", [10, 20], [1, -1]),
+ ("1abc", "Y", "B", [30, 40, 50], [5, -1, -1]),
+ ]
+ },
+ "gh": {"foldseek": []},
+ }
+ lookup = pd.read_parquet(tmp_path / tasks.ALIGNMENT_CHAIN_LOOKUP_RELATIVE)
+ ordered_numbers = {
+ (str(row.entry_pdb_id), str(row.chain_asym_id)): list(
+ row.selected_residue_numbers
+ )
+ for row in lookup.itertuples(index=False)
+ }
+ for shard, backends in mapped_rows.items():
+ for backend, values in backends.items():
+ query_entry = {"ab": "1abc", "de": "2def", "gh": "3ghi"}[shard]
+ rows = [
+ {
+ "query_entry": query_entry,
+ "target_entry": target_entry,
+ "query_chain_mapped": query_chain,
+ "target_chain_mapped": target_chain,
+ "source": backend,
+ "qcov": 1.0,
+ "tcov": 1.0,
+ "fident": 1.0,
+ "seqsim": 1.0,
+ "query_selected_residue_positions": [
+ ordered_numbers[(query_entry, query_chain)].index(residue) + 1
+ for residue in query_residues
+ ],
+ "target_selected_residue_positions": [
+ 0
+ if residue < 0
+ else ordered_numbers[(target_entry, target_chain)].index(
+ residue
+ )
+ + 1
+ for residue in target_residues
+ ],
+ "selected_residue_identity_bits": pack_residue_identities(
+ [True] * len(query_residues)
+ ),
+ **({"lddt": 1.0} if backend == "foldseek" else {}),
+ }
+ for (
+ target_entry,
+ query_chain,
+ target_chain,
+ query_residues,
+ target_residues,
+ ) in values
+ ]
+ for row in rows:
+ qnumbers = ordered_numbers[(query_entry, row["query_chain_mapped"])]
+ tnumbers = ordered_numbers[
+ (row["target_entry"], row["target_chain_mapped"])
+ ]
+ if backend == "foldseek":
+ qnumbers = list(range(1, len(qnumbers) + 1))
+ tnumbers = list(range(1, len(tnumbers) + 1))
+ qpairs = [
+ qnumbers[i - 1] for i in row["query_selected_residue_positions"]
+ ]
+ tpairs = [
+ tnumbers[i - 1] if i else max(tnumbers) + k + 1
+ for k, i in enumerate(row["target_selected_residue_positions"])
+ ]
+ qcursor, tcursor = qpairs[0], tpairs[0]
+ operations = []
+ for qnumber, tnumber in zip(qpairs, tpairs):
+ if qnumber > qcursor:
+ operations.append(f"{qnumber - qcursor}I")
+ if tnumber > tcursor:
+ operations.append(f"{tnumber - tcursor}D")
+ operations.append("1M")
+ qcursor, tcursor = qnumber + 1, tnumber + 1
+ row.update(
+ query_start=qpairs[0],
+ target_start=tpairs[0],
+ cigar="".join(operations),
+ )
+ path = tasks._alignment_release_path(
+ data_dir=tmp_path,
+ search_db="holo",
+ alignment_type=backend,
+ shard=shard,
+ )
+ path.parent.mkdir(parents=True, exist_ok=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ rows,
+ schema=schemas.release_alignment_mapping_schema(
+ alignment_type=backend
+ ),
+ ),
+ path,
+ )
+ mapping_manifest = tasks._alignment_mapping_manifest_path(
+ data_dir=tmp_path,
+ shard=shard,
+ )
+ mapping_manifest.parent.mkdir(parents=True, exist_ok=True)
+ mapping_manifest.write_text("{}\n")
+ alignment_manifest = tmp_path / "alignments" / "manifest.json"
+ alignment_manifest.write_text(
+ json.dumps({"status": "complete", "skipped_queries": {}}) + "\n"
+ )
+
+ plan = plan_interface_scoring(tmp_path, batch_size=1)
+ assert plan["query_interface_count"] == 5
+ assert plan["query_representative_interface_count"] == 4
+ assert plan["target_interface_count"] == 5
+ assert plan["target_representative_interface_count"] == 4
+ membership = pd.read_parquet(
+ tmp_path / "index" / "interface_membership.parquet"
+ ).set_index("system_id")
+ assert membership.loc["1abc__2__1.A--2.B", "representative_system_id"] == query_id
+ assert _interface_score_shard_batch(tmp_path, batch_index=0, batch_size=1) == ["ab"]
+ assert _interface_score_shard_batch(tmp_path, batch_index=1, batch_size=1) == ["de"]
+ assert _interface_score_shard_batch(tmp_path, batch_index=2, batch_size=1) == ["gh"]
+
+ for batch_index in range(3):
+ score_interface_qcov_shards(
+ tmp_path,
+ shards=_interface_score_shard_batch(
+ tmp_path,
+ batch_index=batch_index,
+ batch_size=1,
+ ),
+ scratch_dir=tmp_path / "scratch" / str(batch_index),
+ threads=1,
+ memory_limit="1GB",
+ assignment_target_bucket_count=target_buckets,
+ )
+
+ forward_all = pd.read_parquet(tmp_path / "interface_scores" / "shard=ab.parquet")
+ forward = forward_all[forward_all["metric"].eq("interface_qcov")].reset_index(
+ drop=True
+ )
+ assert len(forward) == 3
+ cross_entry = forward[
+ forward["query_system"].eq(query_id) & forward["target_system"].eq(target_id)
+ ].iloc[0]
+ assert cross_entry["mapping"] == "1.A:1.Y;1.B:1.X"
+ assert cross_entry["source"] == "foldseek"
+ assert cross_entry["iface1_qcov"] == pytest.approx(0.75)
+ assert cross_entry["iface2_qcov"] == pytest.approx(1.0)
+ assert cross_entry["similarity"] == 75
+ shared_half_pairs = forward[
+ forward["query_system"].isin([query_id, shared_half_id])
+ & forward["target_system"].isin([query_id, shared_half_id])
+ ]
+ assert set(
+ shared_half_pairs[
+ ["query_system", "target_system", "iface1_qcov", "iface2_qcov"]
+ ].itertuples(index=False, name=None)
+ ) == {
+ (query_id, shared_half_id, 1.0, 1.0),
+ (shared_half_id, query_id, 1.0, 1.0),
+ }
+ side_scores = forward_all[
+ forward_all["metric"].eq("interface_side_qcov")
+ ].sort_values(["query_system", "target_system"])
+ target_side_scores = side_scores[
+ side_scores["target_system"].str.startswith(target_id)
+ ]
+ assert target_side_scores[["query_system", "target_system", "similarity"]].to_dict(
+ "records"
+ ) == [
+ {
+ "query_system": f"{query_id}::side=1",
+ "target_system": f"{target_id}::side=2",
+ "similarity": 75,
+ },
+ {
+ "query_system": f"{query_id}::side=2",
+ "target_system": f"{target_id}::side=1",
+ "similarity": 100,
+ },
+ {
+ "query_system": f"{query_id}::side=2",
+ "target_system": f"{target_id}::side=2",
+ "similarity": 100,
+ },
+ ]
+ assert side_scores["similarity"].min() >= 30
+ assert side_scores["iface1_qcov"].isna().all()
+ assert side_scores["iface2_qcov"].isna().all()
+ reverse_all = pd.read_parquet(tmp_path / "interface_scores" / "shard=de.parquet")
+ reverse = reverse_all[reverse_all["metric"].eq("interface_qcov")].reset_index(
+ drop=True
+ )
+ assert reverse.loc[0, "iface1_qcov"] == pytest.approx(0.5)
+ assert reverse.loc[0, "iface2_qcov"] == pytest.approx(1 / 3)
+ assert reverse.loc[0, "similarity"] == 17
+ empty = tmp_path / "interface_scores" / "shard=gh.parquet"
+ assert pq.ParquetFile(empty).metadata.num_rows == 0
+ assert pq.read_schema(empty).equals(schemas.INTERFACE_SCORE_SHARD_SCHEMA)
+
+ report = finalize_interface_similarity_scores(
+ tmp_path,
+ scratch_dir=tmp_path / "finalize-scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+ release = pd.read_parquet(tmp_path / INTERFACE_SIMILARITY_EXPORT_RELATIVE)
+ assert release.columns.tolist() == [
+ "query_system",
+ "target_system",
+ "iface1_qcov",
+ "iface2_qcov",
+ "similarity",
+ ]
+ assert sorted(release["similarity"].tolist()) == [17, 75, 100, 100]
+ assert report["row_count"] == 4
+ assert report["ordering"] == "query_target_similarity"
+ assert release.equals(
+ release.sort_values(
+ ["query_system", "target_system", "similarity"],
+ ignore_index=True,
+ )
+ )
+ half_release = pd.read_parquet(tmp_path / INTERFACE_HALF_SIMILARITY_EXPORT_RELATIVE)
+ assert half_release.columns.tolist() == [
+ "query_half_interface_id",
+ "target_half_interface_id",
+ "similarity",
+ ]
+ all_side_scores = pd.concat([forward_all, reverse_all], ignore_index=True)
+ all_side_scores = all_side_scores[
+ all_side_scores["metric"].eq("interface_side_qcov")
+ ]
+ assert len(half_release) == len(all_side_scores)
+ assert half_release.equals(
+ half_release.sort_values(
+ ["query_half_interface_id", "target_half_interface_id", "similarity"],
+ ignore_index=True,
+ )
+ )
+ assert report["half_row_count"] == len(all_side_scores)
+ assert set(half_release.itertuples(index=False, name=None)) == set(
+ all_side_scores[["query_system", "target_system", "similarity"]].itertuples(
+ index=False, name=None
+ )
+ )
+ previous_manifest = alignment_manifest.read_bytes()
+ previous_stat = alignment_manifest.stat()
+ alignment_manifest.write_text("alignment representation changed\n")
+ half_path = tmp_path / INTERFACE_HALF_SIMILARITY_EXPORT_RELATIVE
+ half_path.unlink()
+ half_path.with_suffix(".parquet.json").unlink()
+ cached_half = finalize_interface_half_similarity_scores(
+ tmp_path,
+ scratch_dir=tmp_path / "cached-half-scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+ assert cached_half["row_count"] == len(all_side_scores)
+ alignment_manifest.write_bytes(previous_manifest)
+ os.utime(
+ alignment_manifest,
+ ns=(previous_stat.st_atime_ns, previous_stat.st_mtime_ns),
+ )
+
+ expected_repaired = pd.read_parquet(
+ tmp_path / "interface_scores" / "shard=ab.parquet"
+ ).sort_values(["metric", "query_system", "target_system"], ignore_index=True)
+ (tmp_path / "interface_scores" / "shard=ab.parquet").unlink()
+ (tmp_path / "interface_scores" / "shard=ab.json").unlink()
+ repair_plan = plan_interface_score_repair(tmp_path, batch_size=1)
+ assert repair_plan["shard_count"] == 1
+ assert repair_plan["entry_count"] == 1
+ assert repair_plan["batch_count"] == 1
+ assert _interface_score_repair_task_batches(
+ tmp_path, task_index=0, batches_per_task=5
+ ) == [0]
+ assert (
+ _interface_score_repair_task_batches(tmp_path, task_index=1, batches_per_task=5)
+ == []
+ )
+ score_interface_qcov_repair_batch(
+ tmp_path,
+ batch_index=0,
+ batch_size=1,
+ scratch_dir=tmp_path / "repair-score-scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+ repair_report = finalize_interface_score_repair(
+ tmp_path,
+ scratch_dir=tmp_path / "repair-finalize-scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+ observed_repaired = pd.read_parquet(
+ tmp_path / "interface_scores" / "shard=ab.parquet"
+ ).sort_values(["metric", "query_system", "target_system"], ignore_index=True)
+ pd.testing.assert_frame_equal(observed_repaired, expected_repaired)
+ assert repair_report["row_count"] == len(expected_repaired)
+
+ # A selected-query repair updates only that query and retains unrelated
+ # rows already stored in the same physical shard.
+ score_path = tmp_path / "interface_scores" / "shard=ab.parquet"
+ stored = pq.read_table(score_path)
+ sentinel = stored.slice(0, 1)
+ query_index = sentinel.schema.get_field_index("query_system")
+ sentinel = sentinel.set_column(
+ query_index,
+ "query_system",
+ pa.array(["4abc__1__1.Q--1.R"]),
+ )
+ pq.write_table(pa.concat_tables([stored, sentinel]), score_path)
+ score_manifest_path = score_path.with_suffix(".json")
+ score_manifest = json.loads(score_manifest_path.read_text())
+ score_manifest["output"] = _source_signature(score_path)
+ score_manifest["rows"] = len(expected_repaired) + 1
+ score_manifest_path.write_text(json.dumps(score_manifest) + "\n")
+
+ query_manifest = tmp_path / "repair-queries.txt"
+ query_manifest.write_text("1abc\n")
+ targeted_plan = plan_interface_score_repair(
+ tmp_path,
+ batch_size=1,
+ query_manifest=query_manifest,
+ )
+ assert targeted_plan["repair_mode"] == "selected_queries"
+ assert targeted_plan["entry_count"] == 1
+ assert targeted_plan["query_manifest"] == _source_signature(query_manifest)
+ score_interface_qcov_repair_batch(
+ tmp_path,
+ batch_index=0,
+ batch_size=1,
+ scratch_dir=tmp_path / "targeted-repair-score-scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+ targeted_report = finalize_interface_score_repair(
+ tmp_path,
+ scratch_dir=tmp_path / "targeted-repair-finalize-scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+ targeted = pd.read_parquet(score_path)
+ assert targeted["query_system"].eq("4abc__1__1.Q--1.R").sum() == 1
+ assert targeted_report["row_count"] == len(expected_repaired) + 1
+
+ alignment_manifest.write_text(
+ json.dumps(
+ {
+ "status": "complete",
+ "skipped_queries": {"2def": {"reason": "mapping row budget"}},
+ }
+ )
+ + "\n"
+ )
+ dropped_plan = plan_interface_scoring(tmp_path, batch_size=1)
+ assert dropped_plan["query_interface_count"] == 4
+ assert dropped_plan["query_representative_interface_count"] == 3
+ assert dropped_plan["target_interface_count"] == 5
+ assert dropped_plan["target_representative_interface_count"] == 4
+ assert pd.read_parquet(tmp_path / "manifests/interface_scoring_work.parquet")[
+ "shard"
+ ].tolist() == ["ab", "gh"]
+ assert not (tmp_path / "interface_scores" / "shard=de.parquet").exists()
+ assert not (tmp_path / "interface_scores" / "shard=de.json").exists()
+ assert (tmp_path / "interface_scores" / "shard=ab.parquet").is_file()
+
+
+def test_interface_score_cli_exposes_plan_array_and_finalizer(tmp_path):
+ from plinder.data.pipeline.score import _parser
+
+ planned = _parser().parse_args(
+ [
+ "plan-interface-scores",
+ str(tmp_path),
+ "--batch-size",
+ "3",
+ ]
+ )
+ assert planned.batch_size == 3
+ shard = _parser().parse_args(
+ [
+ "score-interface-shards",
+ str(tmp_path),
+ "--batch-index",
+ "2",
+ "--batch-size",
+ "3",
+ "--scratch-dir",
+ str(tmp_path / "scratch"),
+ "--memory-limit",
+ "12GB",
+ ]
+ )
+ assert shard.batch_index == 2
+ assert shard.memory_limit == "12GB"
+ repair_plan = _parser().parse_args(
+ [
+ "plan-interface-score-repair",
+ str(tmp_path),
+ "--batch-size",
+ "25",
+ "--query-manifest",
+ str(tmp_path / "queries.txt"),
+ ]
+ )
+ assert repair_plan.batch_size == 25
+ assert repair_plan.query_manifest == tmp_path / "queries.txt"
+ repair_batch = _parser().parse_args(
+ [
+ "score-interface-repair-batches",
+ str(tmp_path),
+ "--batch-index",
+ "4",
+ "--batch-size",
+ "25",
+ "--scratch-dir",
+ str(tmp_path / "scratch"),
+ "--repair-batches-per-task",
+ "5",
+ ]
+ )
+ assert repair_batch.batch_index == 4
+ assert repair_batch.repair_batches_per_task == 5
+ repair_finalizer = _parser().parse_args(
+ [
+ "finalize-interface-score-repair",
+ str(tmp_path),
+ "--scratch-dir",
+ str(tmp_path / "scratch"),
+ ]
+ )
+ assert repair_finalizer.threads == 8
+ finalized = _parser().parse_args(
+ [
+ "finalize-interface-scores",
+ str(tmp_path),
+ "--scratch-dir",
+ str(tmp_path / "scratch"),
+ "--output",
+ str(tmp_path / "release.parquet"),
+ ]
+ )
+ assert finalized.output == tmp_path / "release.parquet"
+ half_finalized = _parser().parse_args(
+ [
+ "finalize-interface-half-scores",
+ str(tmp_path),
+ "--scratch-dir",
+ str(tmp_path / "scratch"),
+ ]
+ )
+ assert half_finalized.command == "finalize-interface-half-scores"
+ ligand_plan = _parser().parse_args(
+ [
+ "plan-ligand-pocket-scores",
+ str(tmp_path),
+ "--scratch-dir",
+ str(tmp_path / "scratch"),
+ "--max-query-protein-chains",
+ "5",
+ "--max-query-proper-ligand-chains",
+ "7",
+ ]
+ )
+ assert ligand_plan.max_query_protein_chains == 5
+ assert ligand_plan.max_query_proper_ligand_chains == 7
+ ligand_shard = _parser().parse_args(
+ [
+ "score-ligand-pocket-shards",
+ str(tmp_path),
+ "--batch-index",
+ "2",
+ "--batch-size",
+ "3",
+ "--scratch-dir",
+ str(tmp_path / "scratch"),
+ "--memory-limit",
+ "12GB",
+ "--shard",
+ "qv",
+ ]
+ )
+ assert ligand_shard.batch_index == 2
+ assert ligand_shard.memory_limit == "12GB"
+ assert ligand_shard.shards == ["qv"]
+ interface_clusters = _parser().parse_args(
+ [
+ "plan-clusters",
+ str(tmp_path),
+ "--entity-type",
+ "interface",
+ ]
+ )
+ assert interface_clusters.entity_type == "interface"
+
+
+def test_clustering_statistics_validate_published_cover_artifacts(tmp_path):
+ from plinder.data.pipeline.score import summarize_clustering_artifacts
+
+ metric = "pocket_qcov"
+ for threshold, labels in [(100, ["c0", "c1"]), (50, ["c0", "c0"])]:
+ directed_cover = (
+ tmp_path
+ / "ligand_sampling"
+ / "directed_set_cover"
+ / f"metric={metric}"
+ / f"threshold={threshold}.parquet"
+ )
+ directed_cover.parent.mkdir(parents=True, exist_ok=True)
+ pd.DataFrame(
+ {
+ "ligand_id": ["l1", "l2"],
+ "centroid_ligand_id": ["l1", "l2"]
+ if threshold == 100
+ else ["l1", "l1"],
+ "similarity_to_centroid": [100.0, 100.0],
+ "label": labels,
+ "metric": [metric, metric],
+ "threshold": [threshold, threshold],
+ "directed": [True, True],
+ }
+ ).to_parquet(directed_cover, index=False)
+
+ report = summarize_clustering_artifacts(
+ tmp_path,
+ metrics=[metric],
+ thresholds=[100, 50],
+ )
+
+ assert report["status"] == "complete"
+ assert report["artifact_count"] == 2
+ assert report["issues"] == []
+ assert (tmp_path / "ligand_clusters" / "stats.json").is_file()
+ stats = pd.read_parquet(tmp_path / "ligand_clusters" / "stats.parquet")
+ directed = stats[stats["cluster"].eq("directed_set_cover")].set_index("threshold")
+ assert directed.loc[100, "cluster_count"] == 2
+ assert directed.loc[50, "cluster_count"] == 1
+
+ cover_50 = (
+ tmp_path
+ / "ligand_sampling"
+ / "directed_set_cover"
+ / f"metric={metric}"
+ / "threshold=50.parquet"
+ )
+ pd.DataFrame(
+ {
+ "ligand_id": ["l1", "l1"],
+ "centroid_ligand_id": ["l1", "l1"],
+ "label": ["c0", "c0"],
+ "metric": [metric, metric],
+ "threshold": [50, 50],
+ "directed": [True, True],
+ }
+ ).to_parquet(cover_50, index=False)
+ with pytest.raises(ValueError, match="invalid clustering artifacts"):
+ summarize_clustering_artifacts(
+ tmp_path,
+ metrics=[metric],
+ thresholds=[100, 50],
+ )
+ invalid_report = json.loads(
+ (tmp_path / "ligand_clusters" / "stats.json").read_text()
+ )
+ assert invalid_report["status"] == "invalid"
+ assert any("duplicate node IDs" in issue for issue in invalid_report["issues"])
+
+ pd.DataFrame(
+ {
+ "ligand_id": ["l1", "l2"],
+ "centroid_ligand_id": ["l2", "l1"],
+ "label": ["c0", "c0"],
+ }
+ ).to_parquet(cover_50, index=False)
+ with pytest.raises(ValueError, match="exactly one representative row"):
+ summarize_clustering_artifacts(tmp_path, metrics=[metric], thresholds=[100, 50])
+
+
+def test_v3_score_slurm_exposes_exact_clustering_stages():
+ repository = Path(__file__).resolve().parents[3]
+ script_path = repository / "scripts" / "slurm" / "score_v3.sbatch"
+ if not script_path.is_file():
+ pytest.skip("Slurm assets are not installed in wheel-only test layouts")
+ script = script_path.read_text()
+
+ assert "plan-interface-scores)" in script
+ assert "score-interface-shards" in script
+ assert "finalize-interface-scores)" in script
+ assert "PLINDER_INTERFACE_SCORE_OUTPUT" in script
+ assert "plan-ligand-pocket-scores)" in script
+ assert "score-ligand-pocket-shards" in script
+ assert "plan-bounded-score-repair)" in script
+ assert "plan-clusters)" in script
+ assert "symmetric-edge-fragments|symmetric-edge-shards" in script
+ assert "component-reductions|set-covers|directed-covers)" in script
+ assert (
+ "finalize-alignments|finalize-ligands|finalize-scores|"
+ "finalize-ligand-3d-retries|finalize-index|merge-components|cluster-stats)"
+ in script
+ )
+ assert "PLINDER_CLUSTER_METRICS" in script
+ assert "PLINDER_CLUSTER_THRESHOLDS" in script
+ assert "PLINDER_CLUSTER_ENTITY_TYPE" in script
+ assert "SEARCH_DB=${PLINDER_SEARCH_DB:-holo}" in script
+ assert 'ARGS+=(--search-db "${SEARCH_DB}")' in script
+
+
+def test_v3_score_cli_accepts_apo_search_database(tmp_path):
+ from plinder.data.pipeline.score import _parser
+
+ build = _parser().parse_args(
+ [
+ "make-sub-dbs",
+ str(tmp_path),
+ "--scratch-dir",
+ str(tmp_path / "scratch"),
+ "--search-db",
+ "holo",
+ "--search-db",
+ "apo",
+ ]
+ )
+ assert build.search_dbs == ["holo", "apo"]
+
+ for command in ["search", "map", "score", "score-pdbs"]:
+ arguments = [
+ command,
+ str(tmp_path),
+ "--batch-index",
+ "0",
+ "--batch-size",
+ "1",
+ "--scratch-dir",
+ str(tmp_path / "scratch"),
+ "--search-db",
+ "apo",
+ ]
+ if command == "search":
+ arguments.extend(["--alignment-type", "mmseqs"])
+ if command == "score-pdbs":
+ arguments.extend(["--pdb-manifest", str(tmp_path / "queries.parquet")])
+ parsed = _parser().parse_args(arguments)
+ assert parsed.search_db == "apo"
+
+
+def test_v3_collation_slurm_uses_local_scratch_and_long_qos_for_global_steps():
+ repository = Path(__file__).resolve().parents[3]
+ script_path = repository / "scripts" / "slurm" / "collate_v3_shards.sbatch"
+ readme_path = repository / "scripts" / "slurm" / "README.md"
+ if not script_path.is_file() or not readme_path.is_file():
+ pytest.skip("Slurm assets are not installed in wheel-only test layouts")
+
+ script = script_path.read_text()
+ documentation = readme_path.read_text()
+
+ assert "${SLURM_TMPDIR:-/scratch/${USER}/plinder-collate-" in script
+ assert (
+ 'sbatch \\\n --output="${OUTPUT_ROOT}/logs/collate-plan-start-%j.out"'
+ ) in documentation
+ assert (
+ "sbatch \\\n --array=0-LAST_PLAN_BATCH_INDEX "
+ "--cpus-per-task=4 --mem=8G \\\n "
+ '--output="${OUTPUT_ROOT}/logs/collate-plan-%A-%a.out"'
+ ) in documentation
+ assert (
+ "sbatch \\\n --qos=6hours \\\n --cpus-per-task=4 --mem=48G"
+ ) in documentation
+
+
+def test_ingest_configs_use_current_schema_and_stages():
+ from plinder.data.pipeline.config import get_config
+
+ repository = Path(__file__).resolve().parents[3]
+ config_dir = repository / "scripts" / "slurm" / "configs" / "ingest"
+ if not config_dir.is_dir():
+ pytest.skip("ingest configs are not installed in wheel-only test layouts")
+ ingest_configs = list(config_dir.glob("*.yaml"))
+ assert ingest_configs
+
+ for path in ingest_configs:
+ cfg = get_config(config_file=path.as_posix(), cached=False)
+ assert set(cfg.flow.run_specific_stages) <= set(tasks.STAGES)
+ assert cfg.data.plinder_release == "2026-07"
+ assert cfg.data.plinder_release_number == "1"
+ if path.name == "make_protein_scores.yaml":
+ assert cfg.scorer.sub_databases == ["holo", "apo"]
+ assert cfg.flow.make_dbs_cpu == 32
+ assert cfg.flow.make_sub_dbs_cpu == 32
+ assert cfg.flow.make_scorers_cpu == 32
+ assert cfg.flow.protein_clustering_cpu == 32
+ assert cfg.scorer.minimum_thresholds[
+ "protein_lddt_weighted_sum"
+ ] == pytest.approx(0.2)
+ assert "collate_alignments" in cfg.flow.run_specific_stages
+ assert "finalize_alignments" in cfg.flow.run_specific_stages
+ assert "plan_score_batches" in cfg.flow.run_specific_stages
+ assert "plan_interface_scores" in cfg.flow.run_specific_stages
+ assert "make_interface_scores" in cfg.flow.run_specific_stages
+ assert "finalize_interface_scores" in cfg.flow.run_specific_stages
+ assert "export_ligand_similarity_scores" in cfg.flow.run_specific_stages
+ assert "finalize_ligand_similarity_scores" in cfg.flow.run_specific_stages
+ assert "map_batch_alignments" in cfg.flow.run_specific_stages
+ assert cfg.flow.map_batch_alignments_batch_size == 1
+ assert cfg.flow.make_interface_scores_batch_size == 1
+ assert cfg.foldseek.min_seq_id == 0.0
+ assert cfg.mmseqs.min_seq_id == 0.0
+ assert tasks.STAGES.index("map_batch_alignments") < tasks.STAGES.index(
+ "make_batch_scores"
+ )
+ if path.name == "make_components.yaml":
+ assert "collate_partitions" in cfg.flow.run_specific_stages
+ assert "make_linked_apo_structures" in cfg.flow.run_specific_stages
+ assert "plan_clusters" in cfg.flow.run_specific_stages
+ assert "make_symmetric_edge_fragments" in cfg.flow.run_specific_stages
+ assert "make_symmetric_edge_shards" in cfg.flow.run_specific_stages
+ assert "make_component_reductions" in cfg.flow.run_specific_stages
+ assert "merge_component_reductions" in cfg.flow.run_specific_stages
+ assert "make_set_covers" in cfg.flow.run_specific_stages
+ assert "make_directed_set_covers" in cfg.flow.run_specific_stages
+ assert "summarize_clusters" in cfg.flow.run_specific_stages
+ assert "finalize_index" in cfg.flow.run_specific_stages
+ if path.name == "make_entries_ligands.yaml":
+ assert "collate_entries" in cfg.flow.run_specific_stages
+ assert "finalize_ligand_archives" in cfg.flow.run_specific_stages
+ assert "compute_ligand_fingerprints" in cfg.flow.run_specific_stages
+ assert "make_ligand_scores" in cfg.flow.run_specific_stages
+ assert "make_mhfp6_scores" in cfg.flow.run_specific_stages
+ assert "annotate_ligand_similarity" in cfg.flow.run_specific_stages
+ assert "make_ligand_mmp_pairs" in cfg.flow.run_specific_stages
+ assert "make_ccd_ligand_dbs" in cfg.flow.run_specific_stages
+ assert "make_ligands" not in cfg.flow.run_specific_stages
+
+
+def test_make_canonical_ligand_archives_only_archives_asu_sdfs(tmp_path):
+ from plinder.data.pipeline.score import finalize_ligand_archives
+
+ (tmp_path / "raw_entries" / "cd").mkdir(parents=True)
+ canonical = tmp_path / "raw_entries" / "ab" / "1abc" / "ligand_files"
+ canonical.mkdir(parents=True)
+ (canonical / "A.sdf").write_text("canonical")
+ (canonical.parent.parent / "1abc.parquet").touch()
+ rotated = tmp_path / "raw_entries" / "ab" / "1abc__1__1.B__1.A" / "ligand_files"
+ rotated.mkdir(parents=True)
+ (rotated / "1.A.sdf").write_text("rotated")
+
+ assert tasks.scatter_make_canonical_ligand_archives(
+ data_dir=tmp_path,
+ two_char_codes=[],
+ pdb_ids=[],
+ batch_size=4,
+ ) == [["ab"]]
+ tasks.make_canonical_ligand_archives(data_dir=tmp_path, two_char_codes=["ab"])
+
+ archive = tmp_path / "ligand_archives" / "ab.parquet"
+ packed = pd.read_parquet(archive)
+ assert packed[["pdb_id", "ligand_asym_id"]].to_dict("records") == [
+ {"pdb_id": "1abc", "ligand_asym_id": "A"}
+ ]
+ assert packed["sdf"].tolist() == [b"canonical"]
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame({"entry_pdb_id": ["1abc"], "ligand_asym_id": ["A"]}).to_parquet(
+ index / "annotation_table.parquet", index=False
+ )
+ report = finalize_ligand_archives(tmp_path)
+ assert report == {
+ "status": "complete",
+ "shard_count": 1,
+ "ligand_count": 1,
+ "compressed_bytes": archive.stat().st_size,
+ }
+
+
+def test_finalize_ligand_archives_removes_stale_empty_archives(tmp_path):
+ from plinder.data.pipeline.score import finalize_ligand_archives
+
+ (tmp_path / "raw_entries" / "ab").mkdir(parents=True)
+ archive_dir = tmp_path / "ligand_archives"
+ archive_dir.mkdir()
+ stale = archive_dir / "ab.parquet"
+ pd.DataFrame(
+ {
+ "pdb_id": pd.Series(dtype="string"),
+ "ligand_asym_id": pd.Series(dtype="string"),
+ "sdf": pd.Series(dtype="object"),
+ }
+ ).to_parquet(stale, index=False)
+
+ report = finalize_ligand_archives(tmp_path)
+
+ assert report == {
+ "status": "complete",
+ "shard_count": 0,
+ "ligand_count": 0,
+ "compressed_bytes": 0,
+ }
+ assert not stale.exists()
+
+
+def test_finalize_ligand_archives_rejects_nonempty_extra_archives(tmp_path):
+ from plinder.data.pipeline.score import finalize_ligand_archives
+
+ (tmp_path / "raw_entries" / "ab").mkdir(parents=True)
+ archive_dir = tmp_path / "ligand_archives"
+ archive_dir.mkdir()
+ pd.DataFrame(
+ {
+ "pdb_id": ["1abc"],
+ "ligand_asym_id": ["A"],
+ "sdf": [b"ligand"],
+ }
+ ).to_parquet(archive_dir / "ab.parquet", index=False)
+
+ with pytest.raises(ValueError, match=r"extra=\['ab'\]"):
+ finalize_ligand_archives(tmp_path)
+
+
+def test_make_sub_dbs_loads_entry_chain_index(tmp_path, monkeypatch):
+ from plinder.core.scores import entries as entry_views
+
+ index_dir = tmp_path / "index"
+ index_dir.mkdir()
+ (tmp_path / "dbs").mkdir()
+ pd.DataFrame({"entry_pdb_id": ["1abc"]}).to_parquet(
+ index_dir / "annotation_table.parquet",
+ index=False,
+ )
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "chain_asym_id": ["A"],
+ }
+ ).to_parquet(index_dir / "entry_chains.parquet", index=False)
+
+ sentinel = {"1abc": object()}
+
+ def fake_entry_views(annotation, *, entry_chains):
+ assert annotation["entry_pdb_id"].tolist() == ["1abc"]
+ assert entry_chains["chain_asym_id"].tolist() == ["A"]
+ return sentinel
+
+ observed = {}
+ lookup_calls = []
+ monkeypatch.setattr(entry_views, "entry_views_from_df", fake_entry_views)
+ monkeypatch.setattr(
+ tasks,
+ "_interface_apo_scoring_chains",
+ lambda _data_dir: pd.DataFrame(
+ columns=["entry_pdb_id", "chain_asym_id", "chain_auth_id"]
+ ),
+ )
+ monkeypatch.setattr(tasks.utils, "get_db_sources", lambda **kwargs: {})
+ monkeypatch.setattr(
+ tasks.databases,
+ "make_sub_dbs",
+ lambda db_dir, db_sources, entries, **kwargs: observed.update(
+ entries=entries,
+ kwargs=kwargs,
+ ),
+ )
+ monkeypatch.setattr(
+ tasks,
+ "make_alignment_chain_lookup",
+ lambda **kwargs: lookup_calls.append(kwargs),
+ )
+
+ tasks.make_sub_dbs(data_dir=tmp_path, sub_databases=["holo", "apo", "pred"])
+
+ assert observed["entries"] is sentinel
+ assert observed["kwargs"] == {
+ "identifiers_by_database": {
+ "interface_apo_foldseek": set(),
+ "interface_apo_mmseqs": set(),
+ },
+ "tmp_dir": None,
+ "threads": 1,
+ }
+ assert lookup_calls == [{"data_dir": tmp_path, "scratch_dir": None, "threads": 1}]
+
+
+def test_monomer_scoring_chains_excludes_holo_and_ligand_like_chains(
+ tmp_path, monkeypatch
+):
+ index = tmp_path / "index"
+ index.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"] * 4,
+ "chain_asym_id": ["A", "B", "C", "D"],
+ "chain_auth_id": ["A", "B", "C", "D"],
+ "chain_receptor_type": ["protein", "protein", "protein", "dna"],
+ "chain_is_ligand_like": [False, False, True, False],
+ }
+ ).to_parquet(index / "entry_chains.parquet", index=False)
+ monkeypatch.setattr(
+ tasks,
+ "_protein_scoring_chains",
+ lambda _data_dir: pd.DataFrame(
+ {"entry_pdb_id": ["1abc"], "chain_asym_id": ["A"]}
+ ),
+ )
+
+ result = tasks._monomer_scoring_chains(tmp_path)
+ assert result["chain_asym_id"].tolist() == ["B"]
+
+
+def test_make_holo_sub_dbs_selects_protein_receptor_and_interface_chains(
+ tmp_path, monkeypatch
+):
+ index_dir = tmp_path / "index"
+ index_dir.mkdir()
+ (tmp_path / "dbs").mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "1abc", "2def"],
+ "chain_asym_id": ["A", "B", "N"],
+ "chain_auth_id": ["X", "Y", "Z"],
+ "chain_receptor_type": ["protein", "protein", "dna"],
+ "chain_is_holo": [True, False, True],
+ }
+ ).to_parquet(index_dir / "entry_chains.parquet", index=False)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": "1abc__1__1.A--1.B",
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.A",
+ "interface_chain_2": "1.B",
+ "interface_chain_1_residue_numbers": [1, 2, 3],
+ "interface_chain_1_residue_indices": [0, 1, 2],
+ "interface_chain_2_residue_numbers": [4, 5, 6],
+ "interface_chain_2_residue_indices": [3, 4, 5],
+ "interface_num_contact_residue_pairs": 3,
+ }
+ ],
+ schema=INTERFACE_ANNOTATION_SCHEMA,
+ ),
+ index_dir / "interface_annotation_table.parquet",
+ )
+
+ observed = {}
+ lookup_calls = []
+ monkeypatch.setattr(tasks.utils, "get_db_sources", lambda **kwargs: {})
+ monkeypatch.setattr(
+ tasks.databases,
+ "make_sub_dbs",
+ lambda db_dir, db_sources, entries, **kwargs: observed.update(
+ entries=entries,
+ kwargs=kwargs,
+ ),
+ )
+ monkeypatch.setattr(
+ tasks,
+ "make_alignment_chain_lookup",
+ lambda **kwargs: lookup_calls.append(kwargs),
+ )
+
+ tasks.make_sub_dbs(data_dir=tmp_path, sub_databases=["holo"])
+
+ assert observed["entries"] is None
+ assert observed["kwargs"]["identifiers_by_database"] == {
+ "holo_foldseek": {
+ "pdb_00001abc_xyz-enrich_X",
+ "pdb_00001abc_xyz-enrich_Y",
+ },
+ "holo_mmseqs": {"1abc_X", "1abc_Y"},
+ }
+ assert lookup_calls == [{"data_dir": tmp_path, "scratch_dir": None, "threads": 1}]
+
+
+def test_make_holo_apo_sub_dbs_selects_apo_chains_from_chain_index(
+ tmp_path, monkeypatch
+):
+ index_dir = tmp_path / "index"
+ index_dir.mkdir()
+ (tmp_path / "dbs").mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"] * 6,
+ "chain_asym_id": ["A", "B", "C", "N", "P", "Q"],
+ "chain_auth_id": ["X", "Y", "Z", "N", "P", "Q"],
+ "chain_entity_id": ["1", "2", "1", "3", "5", "6"],
+ "chain_receptor_type": [
+ "protein",
+ "protein",
+ "protein",
+ "dna",
+ "protein",
+ "protein",
+ ],
+ "chain_is_holo": [True, False, False, False, False, False],
+ "chain_is_ligand_like": [False, False, False, False, True, False],
+ }
+ ).to_parquet(index_dir / "entry_chains.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "1abc", "1abc"],
+ "biounit_id": ["1", "1", "1"],
+ "chain_instance": ["1.B", "1.P", "1.Q"],
+ "chain_asym_id": ["B", "P", "Q"],
+ "chain_role": ["receptor", "ligand", "receptor"],
+ "chain_num_contacting_proteins": [0, 0, 1],
+ "chain_num_contacting_ions": [0, 0, 0],
+ "chain_num_contacting_artifacts": [0, 0, 0],
+ "chain_num_contacting_other_ligands": [0, 0, 0],
+ }
+ ).to_parquet(index_dir / "entry_biounit_chains.parquet", index=False)
+ pd.DataFrame({"entry_pdb_id": ["1abc"], "entry_resolution": [2.0]}).to_parquet(
+ index_dir / "entry_metadata.parquet", index=False
+ )
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "ligand_is_proper": [True],
+ "ligand_protein_chains_asym_id": [["1.A"]],
+ }
+ ).to_parquet(index_dir / "annotation_table.parquet", index=False)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {
+ "entry_pdb_id": "1abc",
+ "system_id": "1abc__1__1.A--1.Q",
+ "system_biounit_id": "1",
+ "interface_chain_1": "1.A",
+ "interface_chain_2": "1.Q",
+ "interface_chain_1_residue_numbers": [1, 2, 3],
+ "interface_chain_1_residue_indices": [0, 1, 2],
+ "interface_chain_2_residue_numbers": [4, 5, 6],
+ "interface_chain_2_residue_indices": [3, 4, 5],
+ "interface_num_contact_residue_pairs": 3,
+ }
+ ],
+ schema=INTERFACE_ANNOTATION_SCHEMA,
+ ),
+ index_dir / "interface_annotation_table.parquet",
+ )
+
+ observed = {}
+ monkeypatch.setattr(tasks.utils, "get_db_sources", lambda **kwargs: {})
+ monkeypatch.setattr(
+ tasks.databases,
+ "make_sub_dbs",
+ lambda db_dir, db_sources, entries, **kwargs: observed.update(
+ entries=entries,
+ kwargs=kwargs,
+ ),
+ )
+ monkeypatch.setattr(tasks, "make_alignment_chain_lookup", lambda **kwargs: None)
+
+ tasks.make_sub_dbs(data_dir=tmp_path, sub_databases=["holo", "apo"])
+
+ assert observed["entries"] is None
+ assert observed["kwargs"]["identifiers_by_database"] == {
+ "holo_foldseek": {
+ "pdb_00001abc_xyz-enrich_Q",
+ "pdb_00001abc_xyz-enrich_X",
+ },
+ "holo_mmseqs": {"1abc_Q", "1abc_X"},
+ "apo_foldseek": {
+ "pdb_00001abc_xyz-enrich_Q",
+ "pdb_00001abc_xyz-enrich_Y",
+ },
+ "apo_mmseqs": {"1abc_Q", "1abc_Y"},
+ "interface_apo_foldseek": {"pdb_00001abc_xyz-enrich_Y"},
+ "interface_apo_mmseqs": {"1abc_Y"},
+ }
+
+
+def test_make_apo_sub_db_builds_alignment_chain_lookup(tmp_path, monkeypatch):
+ (tmp_path / "dbs").mkdir()
+ apo_chains = pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "chain_asym_id": ["A"],
+ "chain_auth_id": ["X"],
+ }
+ )
+ lookup_calls = []
+ monkeypatch.setattr(tasks, "_apo_scoring_chains", lambda _data_dir: apo_chains)
+ monkeypatch.setattr(
+ tasks, "_interface_apo_scoring_chains", lambda _data_dir: apo_chains.iloc[:0]
+ )
+ monkeypatch.setattr(tasks.utils, "get_db_sources", lambda **kwargs: {})
+ monkeypatch.setattr(tasks.databases, "make_sub_dbs", lambda *args, **kwargs: None)
+ monkeypatch.setattr(
+ tasks,
+ "make_alignment_chain_lookup",
+ lambda **kwargs: lookup_calls.append(kwargs),
+ )
+
+ tasks.make_sub_dbs(data_dir=tmp_path, sub_databases=["apo"])
+
+ assert lookup_calls == [{"data_dir": tmp_path, "scratch_dir": None, "threads": 1}]
diff --git a/tests/data/pipeline/test_transform.py b/tests/data/pipeline/test_transform.py
index 9783308be..e14e1a9dd 100644
--- a/tests/data/pipeline/test_transform.py
+++ b/tests/data/pipeline/test_transform.py
@@ -1,41 +1,183 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
+
+from pathlib import Path
+
+import pandas as pd
import pytest
-from plinder.data.pipeline import transform
-
-
-@pytest.mark.parametrize(
- "pdb_range",
- [
- "SM:9-163",
- "SM:9--163",
- "SM:-9--163",
- "SM:9-163L",
- "B:-3-715",
- "A:-4-131",
- "B:-1-75",
- "B:-4-1927",
- ],
+
+from plinder.data.pipeline.io import download_affinity_data
+from plinder.data.pipeline.transform import (
+ strict_bindingdb_candidates,
+ transform_bindingdb_measurements,
)
-def test_parse_pdb_range(pdb_range):
- assert len(transform.parse_pdb_range(pdb_range)) == 3
-
-
-def test_transform_ecod_data(tmp_path):
- ecod_path = tmp_path / "ecod_raw.tsv"
- sample = """\
-#/data/ecod/database_versions/v291/ecod.develop291.domains.txt
-#ECOD version develop291
-#Domain list version 1.6
-#Grishin lab (http://prodata.swmed.edu/ecod)
-#uid ecod_domain_id manual_rep t_id pdb chain pdb_range seqid_range unp_acc arch_name x_name h_name t_name f_name asm_status ligand
-000000267 e1udzA1 MANUAL_REP 1.1.1 1udz A A:203-381 A:4-182 P56690 beta barrels "cradle loop barrel" "RIFT-related" "acid protease" F_UNCLASSIFIED NOT_DOMAIN_ASSEMBLY NO_LIGANDS_4A
-000023408 e1ileA4 AUTO_NONREP 1.1.1 1ile A A:203-381 A:203-381 P56690 beta barrels "cradle loop barrel" "RIFT-related" "acid protease" F_UNCLASSIFIED NOT_DOMAIN_ASSEMBLY NO_LIGANDS_4A
-000023411 e1ue0B1 AUTO_NONREP 1.1.1 1ue0 B B:203-381 B:4-182 P56690 beta barrels "cradle loop barrel" "RIFT-related" "acid protease" F_UNCLASSIFIED NOT_DOMAIN_ASSEMBLY NO_LIGANDS_4A
-000158260 e1wk8A1 AUTO_NONREP 1.1.1 1wk8 A A:201-382 A:7-188 P56690 beta barrels "cradle loop barrel" "RIFT-related" "acid protease" F_UNCLASSIFIED NOT_DOMAIN_ASSEMBLY NO_LIGANDS_4A
-001842922 e5fofA1 AUTO_NONREP 1.1.1 5fof A A:258-340,A:363-567 A:29-103,A:126-330 B3L7I1 beta barrels "cradle loop barrel" "RIFT-related" "acid protease" F_UNCLASSIFIED NOT_DOMAIN_ASSEMBLY NO_LIGANDS_4A
-001842923 e5fofB1 AUTO_NONREP 1.1.1 5fof B B:258-340,B:363-567 B:29-103,B:126-330 B3L7I1 beta barrels "cradle loop barrel" "RIFT-related" "acid protease" F_UNCLASSIFIED NOT_DOMAIN_ASSEMBLY NO_LIGANDS_4A
-"""
- ecod_path.write_text(sample)
- df = transform.transform_ecod_data(raw_ecod_path=ecod_path)
- assert len(df.index) == 8
+
+
+def test_bindingdb_transform_aggregates_across_chunks(tmp_path: Path) -> None:
+ raw_path = tmp_path / "BindingDB_All.tsv"
+ pd.DataFrame(
+ {
+ "Ligand HET ID in PDB": ["LIG", "LIG", "ATP", None],
+ "PDB ID(s) for Ligand-Target Complex": [
+ "1abc",
+ "1abc",
+ "2def, 3ghi",
+ None,
+ ],
+ "Ki (nM)": [10.0, 100.0, 1.0, 5.0],
+ "Kd (nM)": [None, None, None, None],
+ "EC50 (nM)": [None, None, None, None],
+ "BindingDB Target Chain Sequence 1": [
+ "AAAA",
+ "AAAA",
+ "BBBB",
+ "CCCC",
+ ],
+ }
+ ).to_csv(raw_path, sep="\t", index=False)
+
+ records = transform_bindingdb_measurements(raw_affinity_path=raw_path, chunksize=1)
+ result = strict_bindingdb_candidates(records).set_index("pdbid_ligid")
+
+ assert set(result.index) == {"1ABC_LIG", "2DEF_ATP", "3GHI_ATP"}
+ assert result.loc["1ABC_LIG", "pchembl"] == pytest.approx(7.5)
+ assert result.loc["1ABC_LIG", "target_sequence"] == "AAAA"
+ assert result.loc["1ABC_LIG", "count"] == 2
+ assert result.loc["2DEF_ATP", "pchembl"] == pytest.approx(9.0)
+
+
+def test_bindingdb_transform_preserves_numeric_identifiers_as_strings(
+ tmp_path: Path,
+) -> None:
+ raw_path = tmp_path / "BindingDB_numeric_ids.tsv"
+ pd.DataFrame(
+ {
+ "Ligand HET ID in PDB": [123],
+ "PDB ID(s) for Ligand-Target Complex": [1234],
+ "Ki (nM)": [10.0],
+ "Kd (nM)": [None],
+ "EC50 (nM)": [None],
+ "BindingDB Target Chain Sequence 1": ["AAAA"],
+ }
+ ).to_csv(raw_path, sep="\t", index=False)
+
+ records = transform_bindingdb_measurements(raw_affinity_path=raw_path)
+ result = strict_bindingdb_candidates(records)
+
+ assert result["pdbid_ligid"].tolist() == ["1234_123"]
+ assert result["pchembl"].tolist() == pytest.approx([8.0])
+
+
+# Regression cases contributed by Jacob Casey in
+# https://github.com/plinder-org/plinder/issues/94#issuecomment-5784851981
+def test_bindingdb_measurements_keep_target_associations(tmp_path: Path) -> None:
+ base = {
+ "Ligand HET ID in PDB": "LIG",
+ "PDB ID(s) for Ligand-Target Complex": "1abc",
+ "Ki (nM)": None,
+ "Kd (nM)": None,
+ }
+ rows = [
+ {**base, "Ki (nM)": "1", "BindingDB Target Chain Sequence 1": "ACDEFG"},
+ {**base, "Ki (nM)": "1000", "BindingDB Target Chain Sequence 1": "ACDEFA"},
+ ]
+ raw_path = tmp_path / "BindingDB_All.tsv"
+ for order in (rows, list(reversed(rows))):
+ pd.DataFrame(order).to_csv(raw_path, sep="\t", index=False)
+ records = transform_bindingdb_measurements(
+ raw_affinity_path=raw_path, chunksize=1
+ )
+ assert len(records) == 2
+ candidates = strict_bindingdb_candidates(records).set_index("target_sequence")
+ assert candidates.loc["ACDEFG", "pchembl"] == pytest.approx(9.0)
+ assert candidates.loc["ACDEFA", "pchembl"] == pytest.approx(6.0)
+
+
+def test_bindingdb_measurements_keep_bounds_and_endpoints(tmp_path: Path) -> None:
+ raw_path = tmp_path / "BindingDB_All.tsv"
+ pd.DataFrame(
+ [
+ {
+ "Ligand HET ID in PDB": "LIG",
+ "PDB ID(s) for Ligand-Target Complex": "1abc",
+ "BindingDB Target Chain Sequence 1": "ACDEFG",
+ "Ki (nM)": ">100",
+ "Kd (nM)": None,
+ },
+ {
+ "Ligand HET ID in PDB": "LIG",
+ "PDB ID(s) for Ligand-Target Complex": "2def",
+ "BindingDB Target Chain Sequence 1": "ACDEFG",
+ "Ki (nM)": "1",
+ "Kd (nM)": "1000",
+ },
+ ]
+ ).to_csv(raw_path, sep="\t", index=False)
+ records = transform_bindingdb_measurements(raw_affinity_path=raw_path)
+
+ assert len(records) == 3
+ bound = records.loc[records["pdbid_ligid"].eq("1ABC_LIG")].iloc[0]
+ assert bound["endpoint"] == "Ki"
+ assert bound["relation"] == "<"
+ assert bound["pchembl"] == pytest.approx(7.0)
+ assert set(records.loc[records["pdbid_ligid"].eq("2DEF_LIG"), "endpoint"]) == {
+ "Ki",
+ "Kd",
+ }
+ assert strict_bindingdb_candidates(records).empty
+
+
+def test_bindingdb_multichain_target_is_not_a_scalar(tmp_path: Path) -> None:
+ raw_path = tmp_path / "BindingDB_All.tsv"
+ pd.DataFrame(
+ [
+ {
+ "BindingDB Reactant_set_id": "123",
+ "BindingDB MonomerID": "456",
+ "Curation/DataSource": "ChEMBL",
+ "Article DOI": "10.1000/example",
+ "BindingDB Entry DOI": "10.7270/example",
+ "Ligand HET ID in PDB": "LIG",
+ "PDB ID(s) for Ligand-Target Complex": "1abc",
+ "BindingDB Target Chain Sequence 1": "ACDEFG",
+ "BindingDB Target Chain Sequence 2": "HIJKLM",
+ "Ki (nM)": "10",
+ "Kd (nM)": None,
+ }
+ ]
+ ).to_csv(raw_path, sep="\t", index=False)
+ records = transform_bindingdb_measurements(raw_affinity_path=raw_path)
+
+ assert records.loc[0, "reactant_set_id"] == "123"
+ assert records.loc[0, "monomer_id"] == "456"
+ assert records.loc[0, "curation_source"] == "ChEMBL"
+ assert records.loc[0, "article_doi"] == "10.1000/example"
+ assert records.loc[0, "bindingdb_entry_doi"] == "10.7270/example"
+ assert records.loc[0, "target_sequences"] == ["ACDEFG", "HIJKLM"]
+ assert pd.isna(records.loc[0, "target_sequence"])
+ assert strict_bindingdb_candidates(records).empty
+
+
+def test_affinity_cache_keeps_records_and_target_candidates(tmp_path: Path) -> None:
+ affinity_dir = tmp_path / "dbs" / "affinity"
+ affinity_dir.mkdir(parents=True)
+ raw_path = affinity_dir / "BindingDB_All.tsv"
+ pd.DataFrame(
+ {
+ "Ligand HET ID in PDB": ["LIG", "LIG"],
+ "PDB ID(s) for Ligand-Target Complex": ["1abc", "1abc"],
+ "BindingDB Target Chain Sequence 1": ["ACDEFG", "HIJKLM"],
+ "Ki (nM)": ["10", "100"],
+ "Kd (nM)": [None, None],
+ }
+ ).to_csv(raw_path, sep="\t", index=False)
+
+ candidates = download_affinity_data(data_dir=tmp_path)
+
+ assert {row["target_sequence"] for row in candidates["1ABC_LIG"]} == {
+ "ACDEFG",
+ "HIJKLM",
+ }
+ assert len(pd.read_parquet(affinity_dir / "measurements.parquet")) == 2
+ assert len(pd.read_parquet(affinity_dir / "candidates.parquet")) == 2
+ assert not (affinity_dir / "affinity.json").exists()
diff --git a/tests/data/pipeline/test_update_archives.py b/tests/data/pipeline/test_update_archives.py
new file mode 100644
index 000000000..e4ad1ff1f
--- /dev/null
+++ b/tests/data/pipeline/test_update_archives.py
@@ -0,0 +1,221 @@
+import json
+from pathlib import Path
+from shutil import rmtree
+
+import pyarrow as pa
+import pyarrow.parquet as pq
+import pytest
+
+from plinder.core.utils.files import file_sha256, write_json_atomic
+from plinder.data.pipeline import collate, tasks, update_archives
+from plinder.data.pipeline.score import finalize_ligand_archives
+from plinder.data.pipeline.update_entries import _file_stats, _prepared_entry_outputs
+
+
+def _write_poses(root, poses):
+ for pdb_id, asym, sdf in poses:
+ entry = root / "raw_entries" / pdb_id[1:3] / pdb_id
+ (entry / "ligand_files").mkdir(parents=True, exist_ok=True)
+ (entry.parent / f"{pdb_id}.parquet").touch()
+ (entry / "ligand_files" / f"{asym}.sdf").write_bytes(sdf)
+
+
+def _write_tables(root, poses):
+ for name, path in collate.entry_table_paths(root).items():
+ path.parent.mkdir(parents=True, exist_ok=True)
+ table = pa.table({"entry_pdb_id": [pdb_id for pdb_id, _, _ in poses]})
+ if name == "annotation":
+ table = table.append_column(
+ "ligand_asym_id",
+ pa.array([asym for _, asym, _ in poses], type=pa.string()),
+ )
+ pq.write_table(table, path)
+ (root / "index/ligand_affinity.parquet").touch()
+ (root / "index/bindingdb_measurements.parquet").touch()
+ write_json_atomic(root / "index/collation.json", {"status": "complete"})
+
+
+@pytest.fixture(params=[True, False], ids=["with_poses", "ligand_free"])
+def archive_update_case(tmp_path, request):
+ base, workspace = tmp_path / "base", tmp_path / "updated"
+ original = [
+ (pdb_id, "L", f"old {pdb_id}".encode())
+ for pdb_id in ("1abc", "2abd", "3def", "4ghi")
+ ]
+ _write_tables(base, original)
+ _write_poses(base, original)
+ tasks.make_canonical_ligand_archives(
+ data_dir=base, two_char_codes=["ab", "de", "gh"]
+ )
+ finalize_ligand_archives(base)
+ added = (
+ [("1abc", "M", b"revised pose"), ("5jkl", "N", b"added pose")]
+ if request.param
+ else []
+ )
+ expected = [row for row in original if row[0] in {"2abd", "4ghi"}] + added
+ _write_tables(workspace, expected)
+ _write_poses(workspace / ".incoming", added)
+ prepared = _prepared_entry_outputs(workspace)
+ write_json_atomic(
+ workspace / "entry_update.json",
+ {
+ "status": collate.REPAIR_REQUIRED_STATUS,
+ "base_release": str(base),
+ "inputs": {"base_tables": _file_stats(collate.entry_table_paths(base))},
+ "outputs": _file_stats(prepared),
+ "ingested_pdb_ids": ["1abc", "5jkl"],
+ "obsolete_pdb_ids": ["3def"],
+ },
+ )
+ # Incremental archive updates must work without the old per-entry files.
+ rmtree(base / "raw_entries")
+ return base, workspace, expected
+
+
+def _archive_bytes(root):
+ return {
+ path.name: path.read_bytes() for path in (root / "ligand_archives").iterdir()
+ }
+
+
+def test_archive_update_matches_full_repack_and_reuses_unchanged_shards(
+ archive_update_case, tmp_path
+):
+ base, workspace, expected = archive_update_case
+ before = _archive_bytes(base)
+ report = update_archives.update_ligand_archives(workspace, memory_limit="1GB")
+ assert report["status"] == "complete"
+ assert report["updated_pdb_ids"] == ["1abc", "3def", "5jkl"]
+ assert report["ligand_count"] == len(expected)
+ assert _archive_bytes(base) == before
+ assert not (workspace / "ligand_archives/de.parquet").exists()
+ assert (workspace / "ligand_archives/gh.parquet").stat().st_ino == (
+ base / "ligand_archives/gh.parquet"
+ ).stat().st_ino
+ assert (workspace / "ligand_archives/ab.parquet").stat().st_ino != (
+ base / "ligand_archives/ab.parquet"
+ ).stat().st_ino
+ full = tmp_path / "full"
+ _write_poses(full, expected)
+ tasks.make_canonical_ligand_archives(
+ data_dir=full, two_char_codes=sorted({row[0][1:3] for row in expected})
+ )
+ for path in (full / "ligand_archives").glob("*.parquet"):
+ actual = pq.read_table(workspace / "ligand_archives" / path.name)
+ assert actual.to_pylist() == pq.read_table(path).to_pylist()
+ assert (
+ update_archives.update_ligand_archives(workspace, memory_limit="1GB") == report
+ )
+ assert _archive_bytes(base) == before
+ assert (
+ json.loads((workspace / "entry_update.json").read_text())["status"]
+ == collate.REPAIR_REQUIRED_STATUS
+ )
+
+
+def test_failed_archive_install_preserves_previous_output_and_can_retry(
+ archive_update_case, monkeypatch
+):
+ base, workspace, _ = archive_update_case
+ update_archives.update_ligand_archives(workspace, memory_limit="1GB")
+ before, base_before = _archive_bytes(workspace), _archive_bytes(base)
+ rename = Path.rename
+
+ def fail_install(path, target):
+ if path.name == ".ligand_archives.pending":
+ raise OSError("install failed")
+ return rename(path, target)
+
+ with monkeypatch.context() as patch:
+ patch.setattr(Path, "rename", fail_install)
+ with pytest.raises(OSError, match="install failed"):
+ update_archives.update_ligand_archives(workspace, memory_limit="1GB")
+ assert _archive_bytes(workspace) == before
+ assert _archive_bytes(base) == base_before
+ update_archives.update_ligand_archives(workspace, memory_limit="1GB")
+
+
+def test_archive_update_recovers_interrupted_directory_swap(archive_update_case):
+ _, workspace, _ = archive_update_case
+ first = update_archives.update_ligand_archives(workspace, memory_limit="1GB")
+ (workspace / "ligand_archives").rename(workspace / ".ligand_archives.previous")
+ assert (
+ update_archives.update_ligand_archives(workspace, memory_limit="1GB") == first
+ )
+ assert not (workspace / ".ligand_archives.previous").exists()
+
+
+def test_missing_new_pose_leaves_previous_archives_untouched(archive_update_case):
+ base, workspace, expected = archive_update_case
+ if not any(row[0] == "1abc" for row in expected):
+ return
+ update_archives.update_ligand_archives(workspace, memory_limit="1GB")
+ before, base_before = _archive_bytes(workspace), _archive_bytes(base)
+ (workspace / ".incoming/raw_entries/ab/1abc/ligand_files/M.sdf").unlink()
+ with pytest.raises(ValueError, match="missing_index_ligands=1"):
+ update_archives.update_ligand_archives(workspace, memory_limit="1GB")
+ assert _archive_bytes(workspace) == before
+ assert _archive_bytes(base) == base_before
+
+
+def test_archive_update_rejects_changed_entry_tables(archive_update_case):
+ _, workspace, _ = archive_update_case
+ path = workspace / "index/entry_metadata.parquet"
+ path.write_bytes(b"changed")
+ with pytest.raises(ValueError, match="entry tables changed"):
+ update_archives.update_ligand_archives(workspace)
+
+
+def test_archive_update_rejects_incomplete_base_archives(archive_update_case):
+ base, workspace, _ = archive_update_case
+ (base / "ligand_archives/ab.parquet").unlink()
+ with pytest.raises(ValueError, match="completion manifest"):
+ update_archives.update_ligand_archives(workspace)
+
+
+def test_archive_update_detects_input_changes_during_build(
+ archive_update_case, monkeypatch
+):
+ _, workspace, _ = archive_update_case
+ update_archives.update_ligand_archives(workspace, memory_limit="1GB")
+ before = _archive_bytes(workspace)
+ validate = update_archives.finalize_ligand_archives
+
+ def change_inputs(*args, **kwargs):
+ result = validate(*args, **kwargs)
+ write_json_atomic(workspace / "index/collation.json", {"status": "changed"})
+ return result
+
+ monkeypatch.setattr(update_archives, "finalize_ligand_archives", change_inputs)
+ with pytest.raises(RuntimeError, match="inputs changed"):
+ update_archives.update_ligand_archives(workspace, memory_limit="1GB")
+ assert _archive_bytes(workspace) == before
+
+
+def test_archive_update_can_remove_every_ligand(archive_update_case):
+ base, workspace, _ = archive_update_case
+ rmtree(workspace / ".incoming", ignore_errors=True)
+ annotation = workspace / "index/annotation_table.parquet"
+ pq.write_table(
+ pa.table(
+ {
+ "entry_pdb_id": pa.array([], type=pa.string()),
+ "ligand_asym_id": pa.array([], type=pa.string()),
+ }
+ ),
+ annotation,
+ )
+ marker = workspace / "entry_update.json"
+ report = json.loads(marker.read_text())
+ report["ingested_pdb_ids"] = []
+ report["obsolete_pdb_ids"] = ["1abc", "2abd", "3def", "4ghi"]
+ report["outputs"] = _file_stats(_prepared_entry_outputs(workspace))
+ write_json_atomic(marker, report)
+ before = file_sha256(base / "ligand_archives/manifest.json")
+ archives = update_archives.update_ligand_archives(workspace, memory_limit="1GB")
+ assert archives["shard_count"] == archives["ligand_count"] == 0
+ assert list((workspace / "ligand_archives").iterdir()) == [
+ workspace / "ligand_archives/manifest.json"
+ ]
+ assert file_sha256(base / "ligand_archives/manifest.json") == before
diff --git a/tests/data/pipeline/test_update_release.py b/tests/data/pipeline/test_update_release.py
new file mode 100644
index 000000000..ccdbee122
--- /dev/null
+++ b/tests/data/pipeline/test_update_release.py
@@ -0,0 +1,1570 @@
+import gzip
+import json
+import os
+import threading
+from types import SimpleNamespace
+
+import pandas as pd
+import pyarrow as pa
+import pyarrow.parquet as pq
+import pytest
+from omegaconf import OmegaConf
+from rdkit import DataStructs
+
+from plinder.core.structure.smallmols_similarity import mol2morgan_fp
+from plinder.core.utils import schemas
+from plinder.core.utils.files import file_sha256, write_json_atomic
+from plinder.data.annotations import get_similarity_scores
+from plinder.data.pipeline import update_entries, update_release
+from plinder.data.pipeline.config import FoldseekConfig, MMSeqsConfig
+
+
+def _fingerprint(smiles: str) -> bytes:
+ return DataStructs.BitVectToBinaryText(
+ mol2morgan_fp(
+ smiles,
+ radius=get_similarity_scores.ECFP4_RADIUS,
+ nbits=get_similarity_scores.ECFP4_NBITS,
+ )
+ )
+
+
+def test_weekly_table_merge_counts_written_rows(tmp_path, monkeypatch):
+ monkeypatch.setattr(
+ update_entries,
+ "ENTRY_TABLES",
+ {
+ "entry_metadata": ("entry_metadata.parquet", "entry_pdb_id"),
+ "entry_sources": ("entry_sources.parquet", "entry_pdb_id"),
+ },
+ )
+ base = tmp_path / "base/index"
+ incoming = tmp_path / "incoming/index"
+ base.mkdir(parents=True)
+ incoming.mkdir(parents=True)
+ for name in ("entry_metadata", "entry_sources"):
+ pd.DataFrame({"entry_pdb_id": ["1abc", "2def"], "value": [1, 2]}).to_parquet(
+ base / f"{name}.parquet"
+ )
+ pd.DataFrame({"entry_pdb_id": ["1abc"], "value": [3]}).to_parquet(
+ incoming / f"{name}.parquet"
+ )
+ stage = tmp_path / "stage"
+
+ counts = update_entries._combine_tables(
+ base.parent,
+ incoming.parent,
+ stage,
+ ["1abc"],
+ threads=2,
+ memory_limit="1GB",
+ scratch_dir=tmp_path / "scratch",
+ )
+
+ assert counts == {"entry_metadata": 2, "entry_sources": 2}
+ for name in counts:
+ assert pd.read_parquet(stage / f"{name}.parquet").to_dict("records") == [
+ {"entry_pdb_id": "1abc", "value": 3},
+ {"entry_pdb_id": "2def", "value": 2},
+ ]
+
+
+def test_chemical_update_keeps_old_pairs_and_adds_both_directions(tmp_path):
+ fingerprints = tmp_path / "fingerprints"
+ fingerprints.mkdir()
+ fingerprint_path = fingerprints / "ligands_per_smiles.parquet"
+ get_similarity_scores.write_ecfp4_fingerprint_table(
+ pd.DataFrame(
+ {
+ "ligand_smiles_id": [0, 1],
+ "ligand_rdkit_canonical_smiles": ["CCO", "CCC"],
+ "fingerprint": [_fingerprint("CCO"), _fingerprint("CCC")],
+ }
+ ),
+ fingerprint_path,
+ )
+ source = tmp_path / "base-score.parquet"
+ get_similarity_scores.ligand_scores(
+ ligand_ids=[0, 1],
+ data_dir=tmp_path,
+ output_path=source,
+ minimum_similarity=0,
+ )
+ scores = tmp_path / "ligand_scores"
+ scores.mkdir()
+ os.link(source, scores / "base.parquet")
+ prior_manifest = get_similarity_scores.ligand_score_manifest_payload(
+ fingerprint_path=fingerprint_path,
+ fingerprint_col="fingerprint",
+ metric="tanimoto_similarity_ecfp4_1024",
+ minimum_similarity=0,
+ number_id_col="ligand_smiles_id",
+ )
+ write_json_atomic(
+ scores / get_similarity_scores.LIGAND_SCORE_MANIFEST,
+ prior_manifest,
+ )
+ source_hash = file_sha256(source)
+ get_similarity_scores.write_ecfp4_fingerprint_table(
+ pd.DataFrame(
+ {
+ "ligand_smiles_id": [0, 2],
+ "ligand_rdkit_canonical_smiles": ["CCO", "c1ccccc1"],
+ "fingerprint": [_fingerprint("CCO"), _fingerprint("c1ccccc1")],
+ }
+ ),
+ fingerprint_path,
+ )
+ current_manifest = get_similarity_scores.ligand_score_manifest_payload(
+ fingerprint_path=fingerprint_path,
+ fingerprint_col="fingerprint",
+ metric="tanimoto_similarity_ecfp4_1024",
+ minimum_similarity=0,
+ number_id_col="ligand_smiles_id",
+ )
+
+ report = update_release._refresh_chemical_score_shards(
+ data_dir=tmp_path,
+ directory="ligand_scores",
+ metric="tanimoto_similarity_ecfp4_1024",
+ batch_size=10,
+ number_id_col="ligand_smiles_id",
+ minimum_similarity=0,
+ scratch_dir=tmp_path / "scratch",
+ prior_ligands=pd.DataFrame(
+ {
+ "ligand_smiles_id": [0, 1],
+ "ligand_rdkit_canonical_smiles": ["CCO", "CCC"],
+ "fingerprint": [_fingerprint("CCO"), _fingerprint("CCC")],
+ }
+ ),
+ prior_manifest=prior_manifest,
+ current_manifest=current_manifest,
+ )
+
+ result = pd.read_parquet(scores).sort_values(
+ ["query_ligand_id", "target_ligand_id"], ignore_index=True
+ )
+ assert result[["query_ligand_id", "target_ligand_id"]].to_records(
+ index=False
+ ).tolist() == [(0, 0), (0, 2), (2, 0), (2, 2)]
+ assert report["new_query_scores"] == 1
+ assert report["removed_ligands"] == 1
+ assert file_sha256(source) == source_hash
+ assert json.loads((scores / "_manifest.json").read_text())["metric"] == (
+ "tanimoto_similarity_ecfp4_1024"
+ )
+
+ resumed = update_release._refresh_chemical_score_shards(
+ data_dir=tmp_path,
+ directory="ligand_scores",
+ metric="tanimoto_similarity_ecfp4_1024",
+ batch_size=10,
+ number_id_col="ligand_smiles_id",
+ minimum_similarity=0,
+ scratch_dir=tmp_path / "scratch",
+ prior_ligands=pd.DataFrame(
+ {
+ "ligand_smiles_id": [0, 2],
+ "ligand_rdkit_canonical_smiles": ["CCO", "c1ccccc1"],
+ "fingerprint": [_fingerprint("CCO"), _fingerprint("c1ccccc1")],
+ }
+ ),
+ prior_manifest=current_manifest,
+ current_manifest=current_manifest,
+ )
+ assert resumed["new_query_scores"] == 0
+ assert (
+ pd.read_parquet(scores)
+ .sort_values(["query_ligand_id", "target_ligand_id"], ignore_index=True)
+ .equals(result)
+ )
+
+ (scores / get_similarity_scores.LIGAND_SCORE_MANIFEST).unlink()
+ rebuilt = update_release._refresh_chemical_score_shards(
+ data_dir=tmp_path,
+ directory="ligand_scores",
+ metric="tanimoto_similarity_ecfp4_1024",
+ batch_size=10,
+ number_id_col="ligand_smiles_id",
+ minimum_similarity=0,
+ scratch_dir=tmp_path / "scratch",
+ prior_ligands=pd.DataFrame(
+ {
+ "ligand_smiles_id": [0, 2],
+ "ligand_rdkit_canonical_smiles": ["CCO", "c1ccccc1"],
+ "fingerprint": [_fingerprint("CCO"), _fingerprint("c1ccccc1")],
+ }
+ ),
+ prior_manifest=current_manifest,
+ current_manifest=current_manifest,
+ )
+ assert rebuilt["new_query_scores"] == 2
+ assert (
+ pd.read_parquet(scores)
+ .sort_values(["query_ligand_id", "target_ligand_id"], ignore_index=True)
+ .equals(result)
+ )
+
+
+def test_chemical_update_rescores_changed_fingerprint(tmp_path):
+ fingerprints = tmp_path / "fingerprints"
+ fingerprints.mkdir()
+ fingerprint_path = fingerprints / "ligands_per_smiles.parquet"
+ prior_ligands = pd.DataFrame(
+ {
+ "ligand_smiles_id": [0],
+ "ligand_rdkit_canonical_smiles": ["CCO"],
+ "fingerprint": [_fingerprint("CCC")],
+ }
+ )
+ get_similarity_scores.write_ecfp4_fingerprint_table(prior_ligands, fingerprint_path)
+ scores = tmp_path / "ligand_scores"
+ scores.mkdir()
+ get_similarity_scores.ligand_scores(
+ ligand_ids=[0],
+ data_dir=tmp_path,
+ output_path=scores / "base.parquet",
+ minimum_similarity=0,
+ )
+ prior_manifest = get_similarity_scores.ligand_score_manifest_payload(
+ fingerprint_path=fingerprint_path,
+ fingerprint_col="fingerprint",
+ metric="tanimoto_similarity_ecfp4_1024",
+ minimum_similarity=0,
+ number_id_col="ligand_smiles_id",
+ )
+ write_json_atomic(
+ scores / get_similarity_scores.LIGAND_SCORE_MANIFEST,
+ prior_manifest,
+ )
+ get_similarity_scores.write_ecfp4_fingerprint_table(
+ pd.DataFrame(
+ {
+ "ligand_smiles_id": [0],
+ "ligand_rdkit_canonical_smiles": ["CCO"],
+ "fingerprint": [_fingerprint("CCO")],
+ }
+ ),
+ fingerprint_path,
+ )
+ current_manifest = get_similarity_scores.ligand_score_manifest_payload(
+ fingerprint_path=fingerprint_path,
+ fingerprint_col="fingerprint",
+ metric="tanimoto_similarity_ecfp4_1024",
+ minimum_similarity=0,
+ number_id_col="ligand_smiles_id",
+ )
+
+ report = update_release._refresh_chemical_score_shards(
+ data_dir=tmp_path,
+ directory="ligand_scores",
+ metric="tanimoto_similarity_ecfp4_1024",
+ batch_size=10,
+ number_id_col="ligand_smiles_id",
+ minimum_similarity=0,
+ scratch_dir=tmp_path / "scratch",
+ prior_ligands=prior_ligands,
+ prior_manifest=prior_manifest,
+ current_manifest=current_manifest,
+ )
+
+ assert report["new_query_scores"] == 1
+ assert pd.read_parquet(scores)[["query_ligand_id", "target_ligand_id"]].to_records(
+ index=False
+ ).tolist() == [(0, 0)]
+
+
+def test_remove_affected_shape_scores(tmp_path):
+ cache = tmp_path / "scores/ligand_3d_by_query/ab.parquet"
+ cache.parent.mkdir(parents=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {
+ "query_entry": "1abc",
+ "query_ligand_asym_id": "L",
+ "target_entry": "2def",
+ "target_ligand_asym_id": "M",
+ "shape": 0.5,
+ "color": 0.4,
+ "sucos_shape": 0.45,
+ },
+ {
+ "query_entry": "2def",
+ "query_ligand_asym_id": "M",
+ "target_entry": "1abc",
+ "target_ligand_asym_id": "L",
+ "shape": 0.5,
+ "color": 0.4,
+ "sucos_shape": 0.45,
+ },
+ {
+ "query_entry": "2def",
+ "query_ligand_asym_id": "M",
+ "target_entry": "3ghi",
+ "target_ligand_asym_id": "N",
+ "shape": 0.6,
+ "color": 0.5,
+ "sucos_shape": 0.55,
+ },
+ ],
+ schema=schemas.LIGAND_3D_SCORE_SCHEMA,
+ ),
+ cache,
+ )
+ other_cache = cache.with_name("cd.parquet")
+ pq.write_table(pq.read_table(cache), other_cache)
+
+ removed = update_release._remove_affected_shape_scores(
+ tmp_path,
+ shards=["ab", "cd"],
+ affected={"1abc"},
+ scratch_dir=tmp_path / "scratch",
+ threads=2,
+ )
+
+ assert removed == 4
+ for path in (cache, other_cache):
+ assert pd.read_parquet(path)[["query_entry", "target_entry"]].to_dict(
+ "records"
+ ) == [{"query_entry": "2def", "target_entry": "3ghi"}]
+
+
+def test_shape_repair_uses_changed_ligand_archives(tmp_path):
+ base = tmp_path / "base"
+ updated = tmp_path / "updated"
+ for root, changed_sdf in ((base, b"old"), (updated, b"new")):
+ archive = root / "ligand_archives/qz.parquet"
+ archive.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "pdb_id": ["1qz5", "2qz6"],
+ "ligand_asym_id": ["B", "B"],
+ "sdf": [b"same", changed_sdf],
+ "pharmacophore_features": [None, None],
+ }
+ ).to_parquet(archive, index=False)
+
+ assert update_release._changed_ligand_archive_entries(
+ base, updated, {"1qz5", "2qz6", "3qz7"}
+ ) == {"2qz6"}
+
+
+def test_weekly_metadata_only_revision_reuses_scoring_inputs(tmp_path):
+ source = tmp_path / "pdb_00001abc/pdb_00001abc_xyz-enrich.cif.gz"
+ source.parent.mkdir()
+ source.write_bytes(gzip.compress(b"coordinates", mtime=1))
+ roots = [tmp_path / "base", tmp_path / "updated"]
+ for root in roots:
+ (root / "index").mkdir(parents=True)
+ (root / "manifests").mkdir()
+ (root / "manifests/foldseek_createdb_inputs.tsv").write_text(f"{source}\n")
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "chain_asym_id": ["A"],
+ "chain_auth_id": ["A"],
+ "chain_type": ["polypeptide(L)"],
+ "chain_receptor_type": ["protein"],
+ "chain_sequence": ["ACD"],
+ "chain_sequence_noncanonical": ["ACD"],
+ "chain_is_holo": [True],
+ "chain_is_ligand_like": [False],
+ }
+ ).to_parquet(root / "index/entry_chains.parquet")
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "biounit_id": ["1"],
+ "chain_instance": ["1.A"],
+ "chain_asym_id": ["A"],
+ "chain_role": ["receptor"],
+ "chain_num_contacting_ions": [0],
+ "chain_num_contacting_artifacts": [0],
+ "chain_num_contacting_other_ligands": [1],
+ "chain_num_contacting_proteins": [0],
+ }
+ ).to_parquet(root / "index/entry_biounit_chains.parquet")
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "ligand_id": ["1abc__1__L"],
+ "system_id": ["1abc__1__A__L"],
+ "ligand_smiles": ["CCO"],
+ "ligand_is_proper": [True],
+ "ligand_neighboring_residues": [["A_1"]],
+ "ligand_interactions": [[]],
+ }
+ ).to_parquet(root / "index/annotation_table.parquet")
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "system_id": ["1abc__1__A__B"],
+ "interface_chain_1_residue_numbers": [[1]],
+ "interface_chain_2_residue_numbers": [[2]],
+ }
+ ).to_parquet(root / "index/interface_annotation_table.parquet")
+
+ base, updated = roots
+ assert update_release._entries_with_interfaces(base, updated, {"1abc"}) == {"1abc"}
+ assert not update_release._entries_with_interfaces(base, updated, {"2def"})
+ assert update_release._unchanged_scoring_entries(base, updated, {"1abc"}) == {
+ "1abc"
+ }
+ recompressed = tmp_path / "other/pdb_00001abc/pdb_00001abc_xyz-enrich.cif.gz"
+ recompressed.parent.mkdir(parents=True)
+ recompressed.write_bytes(gzip.compress(b"coordinates", mtime=2))
+ (updated / "manifests/foldseek_createdb_inputs.tsv").write_text(f"{recompressed}\n")
+ assert source.read_bytes() != recompressed.read_bytes()
+ assert update_release._unchanged_scoring_entries(base, updated, {"1abc"}) == {
+ "1abc"
+ }
+ recompressed.write_bytes(gzip.compress(b"different coordinates", mtime=2))
+ assert not update_release._unchanged_scoring_entries(base, updated, {"1abc"})
+ recompressed.write_bytes(gzip.compress(b"coordinates", mtime=2))
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "chain_asym_id": ["A"],
+ "chain_auth_id": ["A"],
+ "chain_type": ["polypeptide(L)"],
+ "chain_receptor_type": ["protein"],
+ "chain_sequence": ["ACE"],
+ "chain_sequence_noncanonical": ["ACE"],
+ "chain_is_holo": [True],
+ "chain_is_ligand_like": [False],
+ }
+ ).to_parquet(updated / "index/entry_chains.parquet")
+ assert not update_release._unchanged_scoring_entries(base, updated, {"1abc"})
+
+
+def test_weekly_reused_foldseek_manifest_uses_current_snapshot(tmp_path):
+ old = (
+ tmp_path
+ / "old/data/entries/divided/ab/pdb_00001abc/pdb_00001abc_xyz-enrich.cif.gz"
+ )
+ current_root = tmp_path / "current"
+ current = current_root / old.relative_to(tmp_path / "old")
+ old.parent.mkdir(parents=True)
+ current.parent.mkdir(parents=True)
+ old.write_bytes(gzip.compress(b"same cif", mtime=1))
+ current.write_bytes(gzip.compress(b"same cif", mtime=2))
+ data_dir = tmp_path / "release"
+ (data_dir / "manifests").mkdir(parents=True)
+ manifest = data_dir / "manifests/foldseek_createdb_inputs.tsv"
+ manifest.write_text(f"{old}\n")
+
+ update_release._refresh_foldseek_source_manifest(
+ data_dir, nextgen_root=current_root, affected={"1abc"}
+ )
+
+ assert manifest.read_text() == f"{current}\n"
+
+
+def test_holo_repair_discards_interrupted_shape_batches(tmp_path, monkeypatch):
+ partial = tmp_path / "scores/ligand_3d_pair_repairs/0.parquet"
+ partial.parent.mkdir(parents=True)
+ partial.write_text("partial")
+ monkeypatch.setattr(
+ update_release.score,
+ "plan_score_batches",
+ lambda *_args, **_kwargs: None,
+ )
+
+ def no_active_queries(*args, **kwargs):
+ raise ValueError("no active score queries are affected by the repair")
+
+ monkeypatch.setattr(update_release.score, "plan_score_repair", no_active_queries)
+
+ report = update_release.repair_holo_scores(
+ tmp_path,
+ base_data_dir=tmp_path / "base",
+ affected={"1abc"},
+ full_alignment_queries=set(),
+ targeted_alignment_queries=set(),
+ scorer_cfg=OmegaConf.create(
+ {
+ "max_query_protein_chains": 40,
+ "max_query_proper_ligand_chains": 20,
+ }
+ ),
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ memory_limit="1GB",
+ score_batch_size=10,
+ ligand_batch_size=10,
+ )
+
+ assert report == {"status": "complete", "query_count": 0, "pair_count": 0}
+ assert not partial.parent.exists()
+
+
+def test_weekly_score_repair_runs_independent_batches(tmp_path):
+ for pdb_id in ("1abc", "2def"):
+ score_file = tmp_path / "dbs/subdbs/search_db=holo" / f"{pdb_id}.parquet"
+ score_file.parent.mkdir(parents=True, exist_ok=True)
+ score_file.touch()
+
+ update_release._repair_score_batches(
+ tmp_path,
+ pd.DataFrame(
+ {
+ "repair_batch_index": [0, 1],
+ "pdb_id": ["1abc", "2def"],
+ "repair_mode": ["drop", "drop"],
+ }
+ ),
+ OmegaConf.create({"sub_databases": ["holo"]}),
+ tmp_path / "scratch",
+ threads=8,
+ )
+
+ assert not list((tmp_path / "dbs/subdbs/search_db=holo").glob("*.parquet"))
+
+
+def test_completed_weekly_query_repair_survives_a_resume(tmp_path):
+ manifests = tmp_path / "manifests"
+ affected = update_release._write_pdb_manifest(
+ manifests / "weekly_affected_entries.parquet", {"1abc"}
+ )
+ full = update_release._write_pdb_manifest(
+ manifests / "weekly_full_score_queries.parquet", {"1abc"}
+ )
+ target = update_release._write_pdb_manifest(
+ manifests / "weekly_target_score_queries.parquet", {"2def"}
+ )
+ repair = manifests / "score_repair.parquet"
+ pd.DataFrame({"pdb_id": ["1abc"]}).to_parquet(repair, index=False)
+ plan = {
+ "affected_manifest": update_release.score._source_signature(affected),
+ "additional_full_query_manifest": update_release.score._source_signature(full),
+ "additional_target_query_manifest": update_release.score._source_signature(
+ target
+ ),
+ "output": update_release.score._source_signature(repair),
+ }
+ write_json_atomic(repair.with_suffix(".json"), plan)
+ write_json_atomic(
+ manifests / "score_repair_incomplete_queries.json", {"status": "complete"}
+ )
+
+ old_mtime = target.stat().st_mtime_ns
+ update_release._write_pdb_manifest(target, {"2def"})
+ assert target.stat().st_mtime_ns == old_mtime
+ assert (
+ update_release._completed_holo_query_repair(
+ tmp_path,
+ affected_manifest=affected,
+ full_manifest=full,
+ target_manifest=target,
+ )
+ == plan
+ )
+
+ update_release._write_pdb_manifest(target, {"3ghi"})
+ assert (
+ update_release._completed_holo_query_repair(
+ tmp_path,
+ affected_manifest=affected,
+ full_manifest=full,
+ target_manifest=target,
+ )
+ is None
+ )
+
+
+def test_weekly_alignment_shards_can_map_concurrently(tmp_path, monkeypatch):
+ barrier = threading.Barrier(2)
+ observed = set()
+
+ def map_shard(*, shards, **_kwargs):
+ observed.update(shards)
+ barrier.wait(timeout=10)
+
+ monkeypatch.setattr(update_release.tasks, "map_batch_alignments", map_shard)
+ update_release._refresh_alignment_shards(
+ tmp_path,
+ search_db="holo",
+ shards={"ab", "cd"},
+ replacement_query_ids=set(),
+ scorer_cfg=OmegaConf.create({"sub_databases": ["holo"]}),
+ scratch_dir=tmp_path / "scratch",
+ threads=2,
+ )
+
+ assert observed == {"ab", "cd"}
+
+
+def test_weekly_candidate_shards_can_pack_concurrently(tmp_path, monkeypatch):
+ barrier = threading.Barrier(2)
+ observed = {}
+
+ def collate(*, shards, scratch_dir, threads, **_kwargs):
+ observed[shards[0]] = (scratch_dir, threads)
+ barrier.wait(timeout=10)
+
+ monkeypatch.setattr(update_release.tasks, "collate_ligand_3d_candidates", collate)
+ update_release._collate_repaired_candidate_shards(
+ tmp_path,
+ ["ab", "cd"],
+ tmp_path / "scratch",
+ threads=8,
+ )
+
+ assert observed == {
+ "ab": (tmp_path / "scratch/ab", 4),
+ "cd": (tmp_path / "scratch/cd", 4),
+ }
+
+
+def test_weekly_target_repair_restores_only_needed_query_caches(tmp_path):
+ base = tmp_path / "base"
+ workspace = tmp_path / "workspace"
+ old_score = base / "dbs/subdbs/search_db=holo/1abc.parquet"
+ old_score.parent.mkdir(parents=True)
+ pd.DataFrame({"query_system": ["1abc__1"]}).to_parquet(old_score, index=False)
+ for folder, schema in (
+ ("ligand_3d_candidate_shards", schemas.LIGAND_3D_CANDIDATE_SCHEMA),
+ ("ligand_pair_score_shards", schemas.LIGAND_PAIR_SCORE_SCHEMA),
+ ):
+ packed = base / "scores" / folder / "shard=ab.parquet"
+ packed.parent.mkdir(parents=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {"query_entry": "1abc", "target_entry": "2def"},
+ {"query_entry": "2abc", "target_entry": "3ghi"},
+ ],
+ schema=schema,
+ ),
+ packed,
+ )
+
+ update_release._restore_score_query_caches(
+ base_data_dir=base,
+ data_dir=workspace,
+ query_ids={"1abc", "2abc"},
+ )
+
+ assert pd.read_parquet(workspace / "dbs/subdbs/search_db=holo/1abc.parquet")[
+ "query_system"
+ ].tolist() == ["1abc__1"]
+ for folder in ("ligand_3d_candidates", "ligand_pair_scores"):
+ query_file = (
+ workspace / "scores" / folder / "search_db=holo/shard=ab/1abc.parquet"
+ )
+ assert pd.read_parquet(query_file)["query_entry"].tolist() == ["1abc"]
+ assert not (
+ workspace / "scores" / folder / "search_db=holo/shard=ab/2abc.parquet"
+ ).exists()
+
+
+def test_weekly_target_repair_splits_interleaved_packed_rows_once(tmp_path):
+ base = tmp_path / "base"
+ workspace = tmp_path / "workspace"
+ score_root = base / "dbs/subdbs/search_db=holo"
+ score_root.mkdir(parents=True)
+ for pdb_id in ("1abc", "2abc", "3abc"):
+ pd.DataFrame({"query_system": [f"{pdb_id}__1"]}).to_parquet(
+ score_root / f"{pdb_id}.parquet", index=False
+ )
+ for folder, schema in (
+ ("ligand_3d_candidate_shards", schemas.LIGAND_3D_CANDIDATE_SCHEMA),
+ ("ligand_pair_score_shards", schemas.LIGAND_PAIR_SCORE_SCHEMA),
+ ):
+ packed = base / "scores" / folder / "shard=ab.parquet"
+ packed.parent.mkdir(parents=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [
+ {"query_entry": "2abc", "target_entry": "4def"},
+ {"query_entry": "1abc", "target_entry": "5def"},
+ {"query_entry": "2abc", "target_entry": "6def"},
+ ],
+ schema=schema,
+ ),
+ packed,
+ )
+
+ update_release._restore_score_query_caches(
+ base_data_dir=base,
+ data_dir=workspace,
+ query_ids={"1abc", "2abc", "3abc"},
+ )
+
+ for folder in ("ligand_3d_candidates", "ligand_pair_scores"):
+ cache = workspace / "scores" / folder / "search_db=holo/shard=ab"
+ assert pd.read_parquet(cache / "1abc.parquet")["target_entry"].tolist() == [
+ "5def"
+ ]
+ assert pd.read_parquet(cache / "2abc.parquet")["target_entry"].tolist() == [
+ "4def",
+ "6def",
+ ]
+ assert pd.read_parquet(cache / "3abc.parquet").empty
+
+
+def test_ligand_score_export_removes_stale_shards(tmp_path, monkeypatch):
+ shard_dir = tmp_path / "exports" / "ligand_similarity_scores"
+ shard_dir.mkdir(parents=True)
+ for suffix in ("parquet", "json"):
+ (shard_dir / f"stale.{suffix}").write_text("stale")
+
+ monkeypatch.setattr(
+ update_release.score,
+ "published_scoring_query_ids",
+ lambda _data_dir: ["1abc"],
+ )
+
+ def export(*args, **kwargs):
+ del args
+ assert kwargs["shards"] == ["ab"]
+ assert not (shard_dir / "stale.parquet").exists()
+ assert not (shard_dir / "stale.json").exists()
+
+ monkeypatch.setattr(
+ update_release.score,
+ "export_ligand_similarity_scores_batch",
+ export,
+ )
+ monkeypatch.setattr(
+ update_release.score,
+ "finalize_ligand_similarity_scores",
+ lambda *args, **kwargs: {"status": "complete"},
+ )
+
+ assert update_release.refresh_ligand_score_export(
+ tmp_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ memory_limit="1GB",
+ ) == {"status": "complete"}
+
+
+def test_weekly_stage_report_is_strictly_ordered(tmp_path):
+ path = tmp_path / "weekly_update.json"
+ report = {"status": "running", "inputs": {"plan": "x"}, "completed_stages": []}
+ update_release._finish_stage(
+ path, report, "entries_and_archives", {"status": "complete"}
+ )
+ loaded = update_release._read_weekly_report(path, inputs={"plan": "x"})
+ assert loaded is not None
+ assert loaded["completed_stages"] == ["entries_and_archives"]
+
+
+def test_base_reuse_skips_transient_staging_trees(tmp_path):
+ base = tmp_path / "base"
+ workspace = tmp_path / "workspace"
+ durable = base / "index" / "annotation_table.parquet"
+ stale = base / "index" / ".staging" / "old" / "entries.parquet"
+ temporary = base / "index" / "annotation_table.parquet.tmp"
+ installing = base / "dbs" / ".foldseek.installing" / "foldseek"
+ partial_shape = base / "scores/ligand_3d_pair_repairs/0.parquet"
+ old_shape_batch = base / "scores/ligand_3d_pairs/0.parquet"
+ old_raw_alignment = base / "dbs/subdbs/holo_mmseqs/aln/1abc.parquet"
+ old_holo_score = base / "dbs/subdbs/search_db=holo/1abc.parquet"
+ old_apo_score = base / "dbs/subdbs/search_db=apo/1abc.parquet"
+ for path in (
+ durable,
+ stale,
+ temporary,
+ installing,
+ partial_shape,
+ old_shape_batch,
+ old_raw_alignment,
+ old_holo_score,
+ old_apo_score,
+ ):
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_text(path.name)
+
+ update_release._reuse_base_artifacts(base, workspace)
+
+ assert (workspace / "index" / durable.name).read_text() == durable.name
+ assert not (workspace / "index" / ".staging").exists()
+ assert not (workspace / "index" / temporary.name).exists()
+ assert not (workspace / "dbs" / ".foldseek.installing").exists()
+ assert not (workspace / "scores/ligand_3d_pair_repairs").exists()
+ assert not (workspace / "scores/ligand_3d_pairs").exists()
+ assert not (workspace / "dbs/subdbs/holo_mmseqs/aln").exists()
+ assert not (workspace / "dbs/subdbs/search_db=holo").exists()
+ assert not (workspace / "dbs/subdbs/search_db=apo").exists()
+
+
+def test_weekly_apo_scores_replace_only_changed_queries(tmp_path):
+ scores = tmp_path / "scores/search_db=apo/apo.parquet"
+ scores.parent.mkdir(parents=True)
+ source_dir = tmp_path / "dbs/subdbs/search_db=apo"
+ source_dir.mkdir(parents=True)
+
+ def row(query: str, similarity: int) -> dict[str, object]:
+ return {
+ "query_system": f"{query}__1__1.A__1.B",
+ "query_ligand_id": f"{query}__1__1.B",
+ "target_system": "9xyz__1__1.A__1.B",
+ "target_ligand_id": "9xyz__1__1.B",
+ "protein_mapping": "1.A:1.A",
+ "mapping": "1.B:1.B",
+ "protein_mapper": "mmseqs",
+ "source": "mmseqs",
+ "metric": "pocket_fident",
+ "similarity": similarity,
+ }
+
+ pd.DataFrame([row("1abc", 40), row("2def", 80)]).assign(search_db="apo").to_parquet(
+ scores, index=False
+ )
+ pd.DataFrame([row("1abc", 90)]).to_parquet(source_dir / "1abc.parquet", index=False)
+ update_release._merge_apo_scores(
+ tmp_path,
+ output=scores,
+ new_queries=["1abc"],
+ replaced_queries={"1abc", "3ghi"},
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ memory_limit="1GB",
+ )
+ result = pq.ParquetFile(scores).read().to_pandas().sort_values("query_system")
+ assert result["query_system"].tolist() == [
+ "1abc__1__1.A__1.B",
+ "2def__1__1.A__1.B",
+ ]
+ assert result["similarity"].tolist() == [90, 80]
+ assert result["search_db"].tolist() == ["apo", "apo"]
+
+
+def test_weekly_chemistry_reuses_unchanged_ligands(tmp_path):
+ base = tmp_path / "base"
+ updated = tmp_path / "updated"
+ rows = pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc", "2def"],
+ "ligand_id": ["1abc__1__1.B", "2def__1__1.B"],
+ "ligand_smiles": ["CCO", "CCN"],
+ "ligand_is_proper": [True, True],
+ "system_type": ["holo", "holo"],
+ }
+ )
+ for root in (base, updated):
+ (root / "index").mkdir(parents=True)
+ rows.to_parquet(root / "index/annotation_table.parquet", index=False)
+
+ assert update_release._ligand_chemistry_unchanged(base, updated, {"1abc"})
+ changed = rows.copy()
+ changed.loc[0, "ligand_smiles"] = "CCC"
+ changed.to_parquet(updated / "index/annotation_table.parquet", index=False)
+ assert not update_release._ligand_chemistry_unchanged(base, updated, {"1abc"})
+
+
+def test_old_target_discovery_reads_retained_cigars(tmp_path):
+ cigar = (
+ tmp_path
+ / "alignment_cigars/search_db=holo/alignment_type=mmseqs/shard=ab.parquet"
+ )
+ cigar.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query_entry": ["1abc", "2abc", "3abc"],
+ "target_entry": ["9xyz", "8xyz", "9xyz"],
+ }
+ ).to_parquet(cigar, index=False)
+ foldseek = (
+ tmp_path
+ / "alignment_cigars/search_db=holo/alignment_type=foldseek/shard=cd.parquet"
+ )
+ foldseek.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query_entry": ["1abc", "4abc", None],
+ "target_entry": ["9xyz", "9xyz", "9xyz"],
+ }
+ ).to_parquet(foldseek, index=False)
+
+ assert update_release._queries_with_old_target_hits(
+ tmp_path, search_db="holo", affected={"9xyz"}
+ ) == {"1abc", "3abc", "4abc"}
+
+
+def test_changed_target_probe_searches_in_reverse_once_per_backend(
+ tmp_path, monkeypatch
+):
+ for backend in ("mmseqs", "foldseek"):
+ marker = tmp_path / "changed" / f"holo_{backend}" / "exact_cluster.json"
+ marker.parent.mkdir(parents=True)
+ marker.write_text("{}")
+ scorer = SimpleNamespace(
+ source_to_full_db_file={
+ "holo_mmseqs": tmp_path / "full_mmseqs",
+ "holo_foldseek": tmp_path / "full_foldseek",
+ },
+ get_config=lambda _db, backend: (
+ MMSeqsConfig() if backend == "mmseqs" else FoldseekConfig()
+ ),
+ )
+ monkeypatch.setattr(
+ update_release.utils,
+ "get_scorer",
+ lambda **_kwargs: (scorer, [], tmp_path / "probe"),
+ )
+ monkeypatch.setattr(
+ update_release.databases,
+ "exact_search_database_paths",
+ lambda *_args: (tmp_path / "changed_target", tmp_path / "unused", None),
+ )
+ calls = []
+
+ def run_alignment(**kwargs):
+ calls.append(kwargs["aln_type"])
+ assert kwargs["query_ids_only"]
+ assert kwargs["id_column"] == "target"
+ assert kwargs["query_db"] == tmp_path / "changed_target"
+ assert kwargs["target_db"] == tmp_path / f"full_{kwargs['aln_type']}"
+ assert kwargs["search_target_db"] == kwargs["target_db"]
+ assert kwargs["alignment_config"].evalue == 2.0
+ assert kwargs["alignment_config"].max_seqs == 2_000_000
+ return (
+ {"1abc_A", "9xyz_X"}
+ if kwargs["aln_type"] == "mmseqs"
+ else {"pdb_00002def_xyz-enrich_B"}
+ )
+
+ monkeypatch.setattr(
+ update_release.get_similarity_scores, "run_alignment", run_alignment
+ )
+ hits = update_release._search_changed_targets(
+ tmp_path,
+ search_db="holo",
+ query_ids=["1abc", "2def"],
+ target_database_dir=tmp_path / "changed",
+ scorer_cfg=OmegaConf.create({}),
+ foldseek_cfg=OmegaConf.create({}),
+ mmseqs_cfg=OmegaConf.create({}),
+ scratch_dir=tmp_path / "scratch",
+ threads=2,
+ )
+
+ assert calls == ["mmseqs", "foldseek"]
+ assert hits == {"1abc", "2def"}
+
+
+def test_alignment_query_only_mode_skips_residue_output(tmp_path, monkeypatch):
+ monkeypatch.setattr(
+ get_similarity_scores,
+ "_alignment_search_command",
+ lambda **_kwargs: ["mmseqs", "search"],
+ )
+
+ def check_call(command, **_kwargs):
+ if command[1] == "convertalis":
+ assert command[command.index("--format-output") + 1] == "query"
+ (tmp_path / "hits.tsv").write_text("query\n1abc_A\n1abc_A\n2def_B\n")
+
+ monkeypatch.setattr(get_similarity_scores.subprocess, "check_call", check_call)
+ identifiers = get_similarity_scores.run_alignment(
+ aln_type="mmseqs",
+ query_db=tmp_path / "query",
+ target_db=tmp_path / "target",
+ search_target_db=tmp_path / "target",
+ search_db=tmp_path / "search",
+ aln_file=tmp_path / "hits.tsv",
+ alignment_config=MMSeqsConfig(),
+ tmp_dir=tmp_path / "tmp",
+ remove_tmp=False,
+ query_ids_only=True,
+ )
+
+ assert identifiers == {"1abc_A", "2def_B"}
+ assert not (tmp_path / "hits.parquet").exists()
+
+
+def test_alignment_target_only_mode_returns_target_ids(tmp_path, monkeypatch):
+ def search_command(**kwargs):
+ assert kwargs["expand_exact_clusters"] is False
+ return ["foldseek", "search"]
+
+ monkeypatch.setattr(
+ get_similarity_scores,
+ "_alignment_search_command",
+ search_command,
+ )
+
+ def check_call(command, **_kwargs):
+ if command[1] == "convertalis":
+ assert command[command.index("--format-output") + 1] == "target"
+ (tmp_path / "hits.tsv").write_text("target\n1abc_A\n1abc_A\n2def_B\n")
+
+ monkeypatch.setattr(get_similarity_scores.subprocess, "check_call", check_call)
+ identifiers = get_similarity_scores.run_alignment(
+ aln_type="foldseek",
+ query_db=tmp_path / "query",
+ target_db=tmp_path / "target",
+ search_target_db=tmp_path / "target",
+ search_db=tmp_path / "search",
+ aln_file=tmp_path / "hits.tsv",
+ alignment_config=FoldseekConfig(),
+ tmp_dir=tmp_path / "tmp",
+ query_ids_only=True,
+ id_column="target",
+ )
+
+ assert identifiers == {"1abc_A", "2def_B"}
+
+
+def test_alignment_repair_queries_are_saved_before_restart(tmp_path, monkeypatch):
+ state_path = tmp_path / "weekly_update.json"
+ report = {
+ "status": "running",
+ "inputs": {"plan": "x"},
+ "completed_stages": ["entries_and_archives", "search_inputs"],
+ }
+ planned = {"holo": {"1abc", "2def"}, "pred": {"1abc"}}
+ calls: list[str] = []
+
+ def plan(*_args, search_db, **_kwargs):
+ calls.append(search_db)
+ return planned[search_db]
+
+ monkeypatch.setattr(update_release, "_plan_alignment_repairs", plan)
+ result = update_release._load_or_plan_alignment_repairs(
+ tmp_path,
+ search_databases=["holo", "pred"],
+ affected={"1abc"},
+ scorer_cfg=OmegaConf.create({}),
+ foldseek_cfg=OmegaConf.create({}),
+ mmseqs_cfg=OmegaConf.create({}),
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ batch_size=10,
+ state_path=state_path,
+ report=report,
+ )
+
+ assert result == planned
+ assert calls == ["holo", "pred"]
+ saved = json.loads(state_path.read_text())
+ assert saved["alignment_repair_queries"] == {
+ "holo": ["1abc", "2def"],
+ "pred": ["1abc"],
+ }
+
+ monkeypatch.setattr(
+ update_release,
+ "_plan_alignment_repairs",
+ lambda *_args, **_kwargs: (_ for _ in ()).throw(
+ AssertionError("restart must use the saved repair queries")
+ ),
+ )
+ assert (
+ update_release._load_or_plan_alignment_repairs(
+ tmp_path,
+ search_databases=["holo", "pred"],
+ affected=set(),
+ scorer_cfg=OmegaConf.create({}),
+ foldseek_cfg=OmegaConf.create({}),
+ mmseqs_cfg=OmegaConf.create({}),
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ batch_size=10,
+ state_path=state_path,
+ report=saved,
+ )
+ == planned
+ )
+
+
+def test_unchanged_alignment_rebase_accepts_public_mapping_schema(
+ tmp_path,
+ monkeypatch,
+):
+ inputs = {"foldseek": [{"name": "1abc.parquet"}], "mmseqs": []}
+ output = update_release.tasks._alignment_release_path(
+ data_dir=tmp_path,
+ search_db="holo",
+ alignment_type="foldseek",
+ shard="ab",
+ )
+ output.parent.mkdir(parents=True)
+ pq.write_table(
+ pa.Table.from_pylist(
+ [],
+ schema=schemas.release_alignment_mapping_schema(alignment_type="foldseek"),
+ ),
+ output,
+ )
+ stat = output.stat()
+ manifest = tmp_path / "alignments/manifests/shard=ab.json"
+ manifest.parent.mkdir(parents=True)
+ write_json_atomic(
+ manifest,
+ {
+ "inputs": inputs,
+ "outputs": {
+ "foldseek": {
+ "name": output.name,
+ "size": stat.st_size,
+ "mtime_ns": stat.st_mtime_ns,
+ },
+ "mmseqs": None,
+ },
+ },
+ )
+ lookup = {"name": "alignment_chain_lookup.parquet"}
+ monkeypatch.setattr(
+ update_release.tasks,
+ "_completed_alignment_chain_lookup",
+ lambda _data_dir: lookup,
+ )
+ monkeypatch.setattr(
+ update_release.tasks,
+ "_alignment_input_signatures",
+ lambda **_kwargs: inputs,
+ )
+
+ update_release._rebase_unchanged_alignment_manifests(
+ tmp_path,
+ search_db="holo",
+ repaired_shards=set(),
+ )
+
+ assert json.loads(manifest.read_text())["alignment_chain_lookup"] == lookup
+
+
+def test_pred_alignment_repairs_only_changed_queries(tmp_path, monkeypatch):
+ manifest = tmp_path / update_release.score.MANIFEST_RELATIVE
+ manifest.parent.mkdir(parents=True)
+ pd.DataFrame({"pdb_id": ["1abc", "2def"]}).to_parquet(manifest, index=False)
+
+ def unexpected(*_args, **_kwargs):
+ raise AssertionError("pred targets do not change with a PDB update")
+
+ monkeypatch.setattr(update_release, "_queries_with_old_target_hits", unexpected)
+ monkeypatch.setattr(update_release, "_changed_target_database", unexpected)
+ monkeypatch.setattr(update_release, "_search_changed_targets", unexpected)
+
+ assert update_release._plan_alignment_repairs(
+ tmp_path,
+ search_db="pred",
+ affected={"1abc", "9xyz"},
+ scorer_cfg=OmegaConf.create({}),
+ foldseek_cfg=OmegaConf.create({}),
+ mmseqs_cfg=OmegaConf.create({}),
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ ) == {"1abc"}
+
+
+def test_changed_target_database_reuses_weekly_subdb(tmp_path, monkeypatch):
+ monkeypatch.setattr(
+ update_release,
+ "_scoring_chains",
+ lambda *_args: pd.DataFrame(
+ {
+ "entry_pdb_id": ["1abc"],
+ "chain_asym_id": ["A"],
+ "chain_auth_id": ["A"],
+ }
+ ),
+ )
+ subdb = tmp_path / "dbs/weekly_delta/subdbs"
+ exact = subdb / "holo_mmseqs/exact_cluster.json"
+ exact.parent.mkdir(parents=True)
+ exact.write_text("{}")
+
+ assert (
+ update_release._changed_target_database(
+ tmp_path,
+ search_db="holo",
+ affected={"1abc"},
+ )
+ == subdb
+ )
+
+
+def test_targeted_weekly_repair_replaces_cumulative_delta_targets(
+ tmp_path, monkeypatch
+):
+ manifest = tmp_path / update_release.score.MANIFEST_RELATIVE
+ manifest.parent.mkdir(parents=True)
+ pd.DataFrame({"pdb_id": ["1abc", "2def"]}).to_parquet(manifest, index=False)
+ shadowed = tmp_path / "manifests/weekly_shadowed_entries.parquet"
+ shadowed.parent.mkdir(parents=True, exist_ok=True)
+ pd.DataFrame({"pdb_id": ["2def", "3ghi"]}).to_parquet(shadowed, index=False)
+ target_dir = tmp_path / "changed"
+ marker = target_dir / "holo_mmseqs/exact_cluster.json"
+ marker.parent.mkdir(parents=True)
+ marker.write_text("{}")
+ monkeypatch.setattr(
+ update_release, "_changed_target_database", lambda *_args, **_kwargs: target_dir
+ )
+ monkeypatch.setattr(update_release.tasks, "run_batch_searches", lambda **_kw: None)
+ monkeypatch.setattr(
+ update_release, "_rebase_unchanged_alignment_manifests", lambda *_a, **_kw: None
+ )
+ replacements = []
+ monkeypatch.setattr(
+ update_release,
+ "_refresh_alignment_shards",
+ lambda *_args, **kwargs: replacements.append(kwargs),
+ )
+
+ update_release.repair_alignments(
+ tmp_path,
+ search_db="holo",
+ affected={"2def"},
+ full_queries=set(),
+ targeted_queries={"1abc"},
+ scorer_cfg=OmegaConf.create({}),
+ foldseek_cfg=OmegaConf.create({}),
+ mmseqs_cfg=OmegaConf.create({}),
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ batch_size=10,
+ )
+
+ assert len(replacements) == 1
+ assert replacements[0]["replacement_query_ids"] == {"1abc"}
+ assert replacements[0]["replacement_target_ids"] == {"2def", "3ghi"}
+
+
+def test_weekly_ccd_refresh_preserves_parity_from_manifest(tmp_path, monkeypatch):
+ fingerprint_path = tmp_path / "fingerprints/ligands_per_smiles.parquet"
+ fingerprint_path.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "ligand_smiles_id": [1],
+ "ligand_rdkit_canonical_smiles": ["CCO"],
+ "fingerprint": [b"fingerprint"],
+ }
+ ).to_parquet(fingerprint_path, index=False)
+ ccd_manifest = tmp_path / "ccd_dbs/ccd_dbs.manifest.json"
+ ccd_manifest.parent.mkdir()
+ ccd_manifest.write_text('{"build_parity_scores": true}')
+ monkeypatch.setattr(
+ update_release.get_similarity_scores,
+ "ligand_score_manifest_payload",
+ lambda **_kwargs: {},
+ )
+ monkeypatch.setattr(
+ update_release.tasks, "compute_ligand_fingerprints", lambda **_kwargs: None
+ )
+ monkeypatch.setattr(
+ update_release, "_refresh_chemical_score_shards", lambda **_kwargs: {}
+ )
+ monkeypatch.setattr(
+ update_release.tasks, "annotate_ligand_similarity", lambda **_kwargs: None
+ )
+ monkeypatch.setattr(
+ update_release.tasks, "make_ligand_mmp_pairs", lambda **_kwargs: tmp_path
+ )
+ ccd_calls = []
+ monkeypatch.setattr(
+ update_release.tasks,
+ "make_ccd_ligand_dbs",
+ lambda **kwargs: ccd_calls.append(kwargs) or tmp_path / "ccd_dbs",
+ )
+ cfg = OmegaConf.create(
+ {
+ "ligand": {
+ "number_id_col": "ligand_smiles_id",
+ "minimum_similarity": 30.0,
+ "cofactor_similarity_threshold": 90.0,
+ },
+ "flow": {
+ "cluster_metrics": [],
+ "make_ligands_batch_size": 10,
+ "skip_specific_stages": [],
+ },
+ }
+ )
+
+ update_release.refresh_ligand_chemistry(
+ tmp_path, cfg=cfg, scratch_dir=tmp_path / "scratch", threads=1
+ )
+
+ assert ccd_calls[0]["build_parity_scores"] is True
+
+
+@pytest.mark.parametrize("resume", [False, True])
+def test_metadata_only_update_finishes_without_alignment_repairs(
+ tmp_path, monkeypatch, resume
+):
+ plan_dir = tmp_path / "plan"
+ plan_dir.mkdir()
+ base = tmp_path / "base"
+ base.mkdir()
+ plan = {"data_dir": str(base), "nextgen_root": str(tmp_path / "nextgen")}
+ write_json_atomic(plan_dir / "plan.json", plan)
+ entries = pd.DataFrame({"pdb_id": ["1abc"], "action": ["revised"]})
+ entries.to_parquet(plan_dir / "entries.parquet", index=False)
+ config_path = tmp_path / "config.yaml"
+ config_path.write_text("{}")
+ validation_root = tmp_path / "validation"
+ validation_root.mkdir()
+ workspace = tmp_path / "workspace"
+ (workspace / "index").mkdir(parents=True)
+ state_path = workspace / "weekly_update.json"
+ report = {
+ "status": "running",
+ "inputs": update_release._weekly_inputs(plan_dir, config_path, validation_root),
+ "base_release": str(base),
+ "affected_pdb_ids": ["1abc"],
+ "completed_stages": (
+ list(update_release._STAGES[:-1]) if resume else ["entries_and_archives"]
+ ),
+ }
+ if resume:
+ report.update(
+ search_inputs={"reused_base": True},
+ alignments={"full_queries": {"holo": []}},
+ scores={"reused_base": True},
+ ligand_chemistry={"reused_base": True},
+ cluster_assignments={
+ "ligand": str(workspace / "index/ligand_clusters.parquet"),
+ "interface": str(workspace / "index/interface_clusters.parquet"),
+ },
+ )
+ write_json_atomic(state_path, report)
+ monkeypatch.setattr(
+ update_release,
+ "_load_configuration",
+ lambda _path: OmegaConf.create({"scorer": {"sub_databases": ["holo"]}}),
+ )
+ monkeypatch.setattr(
+ update_release, "load_update_plan", lambda _path: (plan, entries)
+ )
+ monkeypatch.setattr(
+ update_release, "_unchanged_scoring_entries", lambda *_args: {"1abc"}
+ )
+ monkeypatch.setattr(
+ update_release,
+ "_refresh_foldseek_source_manifest",
+ lambda *_args, **_kwargs: None,
+ )
+ monkeypatch.setattr(
+ update_release, "_rebase_reused_scoring_artifacts", lambda *_args: None
+ )
+ monkeypatch.setattr(
+ update_release,
+ "_load_or_plan_alignment_repairs",
+ lambda *_args, **_kwargs: pytest.fail("metadata-only updates reuse alignments"),
+ )
+ finalizations = []
+
+ def finalize_index(*, data_dir, **_kwargs):
+ finalizations.append(data_dir)
+ write_json_atomic(data_dir / "index/collation.json", {"status": "complete"})
+
+ monkeypatch.setattr(update_release.tasks, "finalize_index", finalize_index)
+ kwargs = {
+ "validation_root": validation_root,
+ "config_path": config_path,
+ "scratch_dir": tmp_path / "scratch",
+ "threads": 1,
+ }
+
+ result = update_release.apply_release_update(plan_dir, workspace, **kwargs)
+
+ assert result["status"] == "complete"
+ assert result["alignment_repair_queries"] == {"holo": []}
+ assert result["completed_stages"] == list(update_release._STAGES)
+ assert json.loads(state_path.read_text())["alignment_repair_queries"] == {
+ "holo": []
+ }
+ assert update_release.apply_release_update(plan_dir, workspace, **kwargs) == result
+ assert finalizations == [workspace]
+
+
+def test_release_update_runs_only_configured_search_databases(tmp_path, monkeypatch):
+ plan_dir = tmp_path / "plan"
+ plan_dir.mkdir()
+ (plan_dir / "plan.json").write_text("{}")
+ entries = pd.DataFrame({"pdb_id": ["1abc"], "action": ["revised"]})
+ entries.to_parquet(plan_dir / "entries.parquet", index=False)
+ config_path = tmp_path / "config.yaml"
+ config_path.write_text("{}")
+ validation_root = tmp_path / "validation"
+ validation_root.mkdir()
+ base = tmp_path / "base"
+ base.mkdir()
+ (base / "index").mkdir()
+ pd.DataFrame({"entry_pdb_id": ["2def"]}).to_parquet(
+ base / "index/interface_annotation_table.parquet", index=False
+ )
+ workspace = tmp_path / "workspace"
+ (workspace / "index").mkdir(parents=True)
+ state_path = workspace / "weekly_update.json"
+ write_json_atomic(
+ state_path,
+ {
+ "status": "running",
+ "inputs": update_release._weekly_inputs(
+ plan_dir, config_path, validation_root
+ ),
+ "base_release": str(base),
+ "affected_pdb_ids": ["1abc"],
+ "completed_stages": ["entries_and_archives"],
+ },
+ )
+ cfg = OmegaConf.create(
+ {
+ "scorer": {
+ "sub_databases": ["holo", "pred"],
+ "max_query_protein_chains": 30,
+ "max_query_proper_ligand_chains": 30,
+ },
+ "foldseek": {"max_seqs": 100},
+ "mmseqs": {},
+ "flow": {
+ "protein_sequence_cluster_identity": 0.4,
+ "protein_structure_cluster_lddt": 0.7,
+ "protein_cluster_coverage": 0.8,
+ "make_batch_scores_batch_size": 10,
+ "make_ligand_3d_scores_batch_size": 10,
+ },
+ }
+ )
+ calls: dict[str, list] = {
+ "overlay": [],
+ "plan": [],
+ "alignments": [],
+ "scores": [],
+ "interface_repair_queries": [],
+ }
+
+ monkeypatch.setattr(update_release, "_load_configuration", lambda _path: cfg)
+ monkeypatch.setattr(
+ update_release,
+ "load_update_plan",
+ lambda _path: (
+ {"data_dir": str(base), "nextgen_root": str(tmp_path / "nextgen")},
+ entries,
+ ),
+ )
+ monkeypatch.setattr(
+ update_release.tasks,
+ "make_alignment_chain_lookup",
+ lambda **_kwargs: tmp_path / "lookup.parquet",
+ )
+ monkeypatch.setattr(
+ update_release.score, "plan_protein_scoring", lambda *_args, **_kwargs: {}
+ )
+ monkeypatch.setattr(
+ update_release.score,
+ "make_foldseek_input_manifest",
+ lambda *_args, **_kwargs: tmp_path / "foldseek.tsv",
+ )
+ monkeypatch.setattr(
+ update_release.score,
+ "make_mmseqs_input_fasta",
+ lambda *_args, **_kwargs: tmp_path / "mmseqs.fasta",
+ )
+ monkeypatch.setattr(
+ update_release,
+ "extend_protein_clusters",
+ lambda **kwargs: tmp_path / f"{kwargs['backend']}.parquet",
+ )
+ monkeypatch.setattr(
+ update_release,
+ "_prepare_weekly_search_overlay",
+ lambda **kwargs: calls["overlay"].append(kwargs["search_databases"])
+ or {"1abc"},
+ )
+ monkeypatch.setattr(
+ update_release.score,
+ "plan_linked_apo_scoring",
+ lambda *_args, **_kwargs: (_ for _ in ()).throw(
+ AssertionError("apo is not configured")
+ ),
+ )
+
+ def plan_alignments(*_args, search_db, **_kwargs):
+ calls["plan"].append(search_db)
+ return {"1abc", "2def"} if search_db == "holo" else {"1abc"}
+
+ def repair_alignments(*_args, search_db, full_queries, **_kwargs):
+ calls["alignments"].append(search_db)
+ return full_queries
+
+ monkeypatch.setattr(update_release, "_plan_alignment_repairs", plan_alignments)
+ monkeypatch.setattr(update_release, "repair_alignments", repair_alignments)
+ monkeypatch.setattr(
+ update_release.score,
+ "finalize_alignment_artifacts",
+ lambda *_args, **_kwargs: {"status": "complete"},
+ )
+ monkeypatch.setattr(
+ update_release,
+ "repair_holo_scores",
+ lambda *_args, **_kwargs: calls["scores"].append("holo") or {},
+ )
+ monkeypatch.setattr(
+ update_release,
+ "repair_interface_scores",
+ lambda *_args, **kwargs: calls["scores"].append("interface")
+ or calls["interface_repair_queries"].append(kwargs["full_alignment_queries"])
+ or {},
+ )
+ monkeypatch.setattr(
+ update_release,
+ "_isolated_ligand_score_export",
+ lambda *_args, **_kwargs: {},
+ )
+ monkeypatch.setattr(
+ update_release,
+ "repair_apo_scores",
+ lambda *_args, **_kwargs: (_ for _ in ()).throw(
+ AssertionError("apo is not configured")
+ ),
+ )
+
+ def repair_non_holo(*_args, search_db, **_kwargs):
+ calls["scores"].append(search_db)
+ return {}
+
+ monkeypatch.setattr(update_release, "repair_non_holo_scores", repair_non_holo)
+ monkeypatch.setattr(
+ update_release, "_ligand_chemistry_unchanged", lambda *_args: False
+ )
+ monkeypatch.setattr(
+ update_release,
+ "refresh_ligand_chemistry",
+ lambda *_args, **_kwargs: {},
+ )
+ monkeypatch.setattr(
+ update_release,
+ "extend_ligand_clusters",
+ lambda **_kwargs: pd.DataFrame({"ligand_id": ["1abc__1__1.X"]}),
+ )
+ monkeypatch.setattr(
+ update_release,
+ "extend_interface_clusters",
+ lambda **_kwargs: pd.DataFrame({"system_id": []}),
+ )
+
+ def finalize_index(*, data_dir, **_kwargs):
+ write_json_atomic(data_dir / "index" / "collation.json", {"status": "complete"})
+
+ monkeypatch.setattr(update_release.tasks, "finalize_index", finalize_index)
+
+ result = update_release.apply_release_update(
+ plan_dir,
+ workspace,
+ validation_root=validation_root,
+ config_path=config_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ )
+
+ assert calls == {
+ "overlay": [["holo"]],
+ "plan": ["holo", "pred"],
+ "alignments": ["holo", "pred"],
+ "scores": ["holo", "interface", "pred"],
+ "interface_repair_queries": [{"1abc", "2def"}],
+ }
+ assert result["alignments"]["full_queries"] == {
+ "holo": ["1abc"],
+ "pred": ["1abc"],
+ }
+ assert set(result["scores"]) == {"ligand", "interface", "ligand_export", "pred"}
diff --git a/tests/data/pipeline/test_updates.py b/tests/data/pipeline/test_updates.py
new file mode 100644
index 000000000..66968bfd7
--- /dev/null
+++ b/tests/data/pipeline/test_updates.py
@@ -0,0 +1,350 @@
+# Copyright (c) 2026, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+
+import gzip
+import json
+import sys
+
+import pandas as pd
+import pytest
+
+from plinder.data.pipeline import updates
+from plinder.data.pipeline.ingest import load_manifest
+
+
+def _json_gz(path, value):
+ path.parent.mkdir(parents=True, exist_ok=True)
+ with gzip.open(path, "wt") as handle:
+ json.dump(value, handle)
+
+
+def _cif(root, pdb_id, revision):
+ path = (
+ root
+ / "data/entries/divided"
+ / pdb_id[1:3]
+ / f"pdb_0000{pdb_id}"
+ / f"pdb_0000{pdb_id}_xyz-enrich.cif.gz"
+ )
+ path.parent.mkdir(parents=True, exist_ok=True)
+ with gzip.open(path, "wt") as handle:
+ handle.write(
+ f"data_{pdb_id}\nloop_\n"
+ "_pdbx_audit_revision_history.ordinal\n"
+ "_pdbx_audit_revision_history.data_content_type\n"
+ "_pdbx_audit_revision_history.major_revision\n"
+ "_pdbx_audit_revision_history.minor_revision\n"
+ f"1 'Structure model' {revision[0]} {revision[1]}\n"
+ "2 'Structure factors' 99 99\n#\n"
+ )
+ return path
+
+
+def _sources(rows):
+ return pd.DataFrame(rows, columns=["entry_pdb_id", *updates.REVISION_COLUMNS])
+
+
+@pytest.fixture
+def inputs(tmp_path):
+ release = tmp_path / "release"
+ (release / "index").mkdir(parents=True)
+ _sources(
+ [
+ ("1abc", 1, 0),
+ ("2abc", 1, 0),
+ ("3abc", 1, 0),
+ ("4abc", 1, 0),
+ ]
+ ).to_parquet(release / "index/entry_sources.parquet", index=False)
+ root = tmp_path / "nextgen"
+ revisions = {"1abc": (1, 0), "2abc": (1, 1), "3abc": (2, 0), "5abc": (1, 0)}
+ _json_gz(
+ root / "holdings/current_file_holdings.json.gz",
+ {
+ f"pdb_0000{key}": {"mmcif": [f"/pdb_nextgen/{key}.cif.gz"]}
+ for key in revisions
+ },
+ )
+ _json_gz(
+ root / "holdings/released_structures_last_modified_dates.json.gz",
+ {f"pdb_0000{key}": "2026-06-01T00:00:00+00:00" for key in revisions},
+ )
+ for key, revision in revisions.items():
+ _cif(root, key, revision)
+ obsolete = tmp_path / "obsolete.dat"
+ obsolete.write_text(
+ " LIST OF OBSOLETE COORDINATE ENTRIES AND SUCCESSORS\n"
+ "OBSLTE 01-JUN-26 4ABC 5ABC\n"
+ )
+ return {"data_dir": release, "nextgen_root": root, "obsolete_path": obsolete}
+
+
+def _bytes(root):
+ return {
+ str(path.relative_to(root)): path.read_bytes()
+ for path in root.rglob("*")
+ if path.is_file()
+ }
+
+
+def test_plan_classifies_entries_and_both_search_directions(inputs, tmp_path):
+ before = _bytes(inputs["data_dir"])
+ output = tmp_path / "plan"
+ plan = updates.plan_update(**inputs, output_dir=output, threads=2)
+ assert plan["status"] == "ready"
+ assert plan["counts"] == {"added": 1, "revised": 2, "obsolete": 1, "unchanged": 1}
+ assert load_manifest(output / "ingest.txt") == ["2abc", "3abc", "5abc"]
+ assert load_manifest(output / "remove.txt") == ["4abc"]
+ assert load_manifest(output / "invalidate.txt") == ["2abc", "3abc", "4abc"]
+ assert load_manifest(output / "active.txt") == ["1abc", "2abc", "3abc", "5abc"]
+ assert load_manifest(output / "unchanged.txt") == ["1abc"]
+ pairs = set()
+ for work in plan["work"]["searches"]:
+ pairs.update(
+ (q, t)
+ for q in load_manifest(output / work["queries"])
+ for t in load_manifest(output / work["targets"])
+ )
+ active = set(load_manifest(output / "active.txt"))
+ changed = set(load_manifest(output / "ingest.txt"))
+ assert pairs == {
+ (q, t) for q in active for t in active if q in changed or t in changed
+ }
+ report = pd.read_parquet(output / "entries.parquet").set_index("pdb_id")
+ assert list(report.loc["4abc", "replacement_pdb_ids"]) == ["5abc"]
+ assert pd.read_csv(output / "entries.tsv", sep="\t").shape[0] == 5
+ assert json.loads((output / "plan.json").read_text()) == plan
+ assert before == _bytes(inputs["data_dir"])
+
+
+def test_plan_refreshes_unchanged_entry_without_new_revision(inputs, tmp_path):
+ output = tmp_path / "refresh_plan"
+ plan = updates.plan_update(
+ **inputs,
+ output_dir=output,
+ pdb_ids=["1abc"],
+ refresh_pdb_ids=["1ABC"],
+ )
+ assert plan["status"] == "ready"
+ assert plan["refresh_pdb_ids"] == ["1abc"]
+ assert load_manifest(output / "ingest.txt") == ["1abc"]
+ assert load_manifest(output / "invalidate.txt") == ["1abc"]
+ row = pd.read_parquet(output / "entries.parquet").iloc[0]
+ assert row.action == "revised"
+ assert row.reason == "annotation refresh"
+ assert row.previous_major_revision == row.current_major_revision == 1
+ assert row.previous_minor_revision == row.current_minor_revision == 0
+
+
+def test_obsolete_preserves_multiple_successors_and_withdrawals(tmp_path):
+ path = tmp_path / "obsolete.dat"
+ path.write_text(
+ " LIST OF OBSOLETE COORDINATE ENTRIES AND SUCCESSORS\n"
+ "OBSLTE 01-JUN-26 1ABC 2ABC 3ABC\n"
+ "OBSLTE 01-JUN-26 1ABC 4ABC\n"
+ "OBSLTE 01-JUN-26 5ABC\n"
+ )
+ assert updates.read_obsolete(path) == {
+ "1abc": ["2abc", "3abc", "4abc"],
+ "5abc": [],
+ }
+
+
+@pytest.mark.parametrize("line", ["OBSLTE", "OBSLTE 01-JUN-26", "OBSLTE 01-JUN-26 BAD"])
+def test_malformed_obsolete_record_fails(tmp_path, line):
+ path = tmp_path / "obsolete.dat"
+ path.write_text(line)
+ with pytest.raises(ValueError):
+ updates.read_obsolete(path)
+
+
+@pytest.mark.parametrize(
+ "problem", ["absent", "conflict", "older", "missing_cif", "missing_revision"]
+)
+def test_source_problems_block_plan_without_removal_lists(inputs, tmp_path, problem):
+ if problem == "absent":
+ inputs["obsolete_path"].write_text("")
+ elif problem == "conflict":
+ with inputs["obsolete_path"].open("a") as handle:
+ handle.write("OBSLTE 01-JUN-26 1ABC\n")
+ elif problem == "older":
+ _cif(inputs["nextgen_root"], "1abc", (0, 9))
+ elif problem == "missing_cif":
+ _cif(inputs["nextgen_root"], "1abc", (1, 0)).unlink()
+ else:
+ path = _cif(inputs["nextgen_root"], "1abc", (1, 0))
+ with gzip.open(path, "wt") as handle:
+ handle.write("data_1abc\n_entry.id 1abc\n")
+ output = tmp_path / "blocked"
+ plan = updates.plan_update(**inputs, output_dir=output)
+ assert plan["status"] == "blocked"
+ assert plan["counts"]["blocked"] == 1
+ assert not list(output.glob("*.txt"))
+ assert (
+ pd.read_parquet(output / "entries.parquet")
+ .query("action == 'blocked'")
+ .reason.str.len()
+ .gt(0)
+ .all()
+ )
+
+
+def test_null_release_revision_blocks(inputs, tmp_path):
+ path = inputs["data_dir"] / "index/entry_sources.parquet"
+ sources = pd.read_parquet(path)
+ sources.loc[0, updates.REVISION_COLUMNS[0]] = None
+ sources.to_parquet(path, index=False)
+ plan = updates.plan_update(**inputs, output_dir=tmp_path / "plan")
+ assert plan["status"] == "blocked"
+
+
+def test_snapshot_cache_reuses_only_unchanged_successful_reads(
+ inputs, tmp_path, monkeypatch
+):
+ root = inputs["nextgen_root"]
+ snapshot = updates.read_snapshot(root)
+ cache = tmp_path / "snapshot.parquet"
+ snapshot.loc[snapshot.entry_pdb_id == "2abc", "error"] = "previous read failed"
+ snapshot.loc[snapshot.entry_pdb_id == "3abc", "last_modified"] = "older timestamp"
+ snapshot.to_parquet(cache, index=False)
+ original = updates._read_revision
+ calls = []
+
+ def read(path):
+ calls.append(path.parent.name)
+ return original(path)
+
+ monkeypatch.setattr(updates, "_read_revision", read)
+ new = updates.read_snapshot(root, previous_snapshot=cache, threads=1)
+ assert calls == ["pdb_00002abc", "pdb_00003abc"]
+ assert new.error.isna().all()
+
+
+def test_inventory_cache_does_not_mark_unapplied_changes_complete(inputs, tmp_path):
+ first = tmp_path / "first"
+ plan = updates.plan_update(**inputs, output_dir=first)
+ second = tmp_path / "second"
+ repeated = updates.plan_update(
+ **inputs, output_dir=second, previous_snapshot=first / "snapshot.parquet"
+ )
+ assert repeated == plan
+ pd.testing.assert_frame_equal(
+ pd.read_parquet(first / "entries.parquet"),
+ pd.read_parquet(second / "entries.parquet"),
+ )
+
+
+def test_no_changes_after_release_matches_snapshot(inputs, tmp_path):
+ snapshot = updates.read_snapshot(inputs["nextgen_root"])
+ snapshot[["entry_pdb_id", *updates.REVISION_COLUMNS]].to_parquet(
+ inputs["data_dir"] / "index/entry_sources.parquet",
+ index=False,
+ )
+ plan = updates.plan_update(**inputs, output_dir=tmp_path / "plan")
+ assert plan["status"] == "no_changes"
+ assert plan["counts"] == {"unchanged": 4}
+ assert plan["work"]["refresh"] == []
+ assert load_manifest(tmp_path / "plan/ingest.txt") == []
+
+
+def test_removal_only_plan(inputs, tmp_path):
+ plan = updates.plan_update(**inputs, output_dir=tmp_path / "plan", pdb_ids=["4ABC"])
+ assert plan["status"] == "ready"
+ assert plan["scope"] == ["4abc"]
+ assert plan["counts"] == {"obsolete": 1}
+ assert load_manifest(tmp_path / "plan/ingest.txt") == []
+ assert load_manifest(tmp_path / "plan/remove.txt") == ["4abc"]
+
+
+def test_duplicate_source_ids_are_rejected(inputs, tmp_path):
+ path = inputs["data_dir"] / "index/entry_sources.parquet"
+ sources = pd.read_parquet(path)
+ pd.concat([sources, sources.iloc[:1]]).to_parquet(path, index=False)
+ with pytest.raises(ValueError, match="duplicate"):
+ updates.plan_update(**inputs, output_dir=tmp_path / "plan")
+ assert not (tmp_path / "plan").exists()
+
+
+def test_plan_pins_resolved_snapshot_root(inputs, tmp_path):
+ alias = tmp_path / "latest"
+ alias.symlink_to(inputs["nextgen_root"], target_is_directory=True)
+ inputs["nextgen_root"] = alias
+ plan = updates.plan_update(**inputs, output_dir=tmp_path / "plan")
+ assert plan["nextgen_root"] == str(alias.resolve())
+ assert str(alias) not in plan["inputs"]["holdings"]["path"]
+
+
+def test_do_not_overwrite_release_or_existing_plan(inputs, tmp_path):
+ with pytest.raises(ValueError, match="outside"):
+ updates.plan_update(**inputs, output_dir=inputs["data_dir"] / "plan")
+ output = tmp_path / "plan"
+ updates.plan_update(**inputs, output_dir=output)
+ before = _bytes(output)
+ with pytest.raises(FileExistsError):
+ updates.plan_update(**inputs, output_dir=output)
+ assert before == _bytes(output)
+
+
+def test_cli_blocked_exit_and_report(inputs, tmp_path, monkeypatch, capsys):
+ inputs["obsolete_path"].write_text("")
+ monkeypatch.setattr(
+ sys,
+ "argv",
+ [
+ "updates",
+ str(inputs["data_dir"]),
+ str(tmp_path / "plan"),
+ "--nextgen-root",
+ str(inputs["nextgen_root"]),
+ "--obsolete",
+ str(inputs["obsolete_path"]),
+ "--threads",
+ "1",
+ ],
+ )
+ with pytest.raises(SystemExit) as exc:
+ updates.main()
+ assert exc.value.code == 1
+ assert json.loads(capsys.readouterr().out)["status"] == "blocked"
+
+
+def test_changed_catalogue_during_read_does_not_write_plan(
+ inputs, tmp_path, monkeypatch
+):
+ original = updates.read_snapshot
+
+ def read(*args, **kwargs):
+ frame = original(*args, **kwargs)
+ inputs["obsolete_path"].write_text("")
+ return frame
+
+ monkeypatch.setattr(updates, "read_snapshot", read)
+ with pytest.raises(RuntimeError, match="catalogues changed"):
+ updates.plan_update(**inputs, output_dir=tmp_path / "plan")
+ assert not (tmp_path / "plan").exists()
+
+
+def test_missing_timestamp_always_reads_revision(inputs, tmp_path, monkeypatch):
+ root = inputs["nextgen_root"]
+ cached = updates.read_snapshot(root)
+ path = tmp_path / "cache.parquet"
+ cached.to_parquet(path, index=False)
+ _json_gz(root / "holdings/released_structures_last_modified_dates.json.gz", {})
+ original = updates._read_revision
+ calls = []
+
+ def read(path):
+ calls.append(path)
+ return original(path)
+
+ monkeypatch.setattr(updates, "_read_revision", read)
+ snapshot = updates.read_snapshot(root, previous_snapshot=path)
+ assert len(calls) == 4
+ assert snapshot.last_modified.isna().all()
+
+
+def test_empty_scope_is_not_interpreted_as_all_entries(inputs, tmp_path):
+ plan = updates.plan_update(**inputs, output_dir=tmp_path / "empty", pdb_ids=[])
+ assert plan["status"] == "no_changes"
+ assert plan["counts"] == {}
+ assert pd.read_parquet(tmp_path / "empty/entries.parquet").empty
diff --git a/tests/data/pipeline/test_utils.py b/tests/data/pipeline/test_utils.py
index ee0978c69..f7eee928d 100644
--- a/tests/data/pipeline/test_utils.py
+++ b/tests/data/pipeline/test_utils.py
@@ -1,19 +1,24 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
+from types import SimpleNamespace
+
+import pandas as pd
import pytest
+
+from plinder.core.scores.metrics import CHEMICAL_CLUSTER_SUMMARY_COLUMNS
from plinder.data.pipeline import utils
-_ENTRY = """
-{{
- "pdb_id": "{pdb_id}",
- "release_date": "2002-11-29",
- "oligomeric_state": "monomeric",
- "determination_method": "X-RAY DIFFRACTION",
- "keywords": "MEMBRANE PROTEIN",
- "pH": "8",
- "resolution": 2.7
-}}
-""".format
+
+def _write_component_labels(tmp_path, metric, threshold, nodes, labels=None):
+ path = (
+ tmp_path
+ / "ligand_clusters/reductions"
+ / f"metric={metric}/labels/directed=false/threshold={threshold}.parquet"
+ )
+ path.parent.mkdir(parents=True, exist_ok=True)
+ pd.DataFrame(
+ {"ligand_id": nodes, "label": labels or [f"c{i}" for i in range(len(nodes))]}
+ ).to_parquet(path, index=False)
@pytest.mark.parametrize(
@@ -31,55 +36,17 @@ def test_should_run_stage(funcname, run, skip, expect):
assert utils.should_run_stage(funcname, run, skip) == expect
-@pytest.mark.parametrize(
- "expect",
- [
- (False),
- (True),
- ],
-)
-def test_entry_exists(expect, tmp_path):
- path = tmp_path / "aa" / "aaaa.json"
- path.parent.mkdir(parents=True)
- if expect:
- path.write_text("")
- assert (
- utils.entry_exists(
- entry_dir=tmp_path,
- pdb_id="aaaa",
+def test_skipped_scatter_keeps_foreach_join_reachable() -> None:
+ class Pipeline:
+ cfg = SimpleNamespace(
+ flow=SimpleNamespace(run_specific_stages=["other"], skip_specific_stages=[])
)
- == expect
- )
+ @utils.ingest_flow_control
+ def scatter_example(self):
+ raise AssertionError("skipped scatter must not execute")
-def test_load_entries(tmp_path):
- a = tmp_path / "raw_entries" / "aa" / "aaaa.json"
- b = tmp_path / "raw_entries" / "bb" / "bbbb.json"
- a.parent.mkdir(parents=True)
- b.parent.mkdir(parents=True)
- a.write_text(_ENTRY(pdb_id="aaaa"))
- b.write_text(_ENTRY(pdb_id="bbbb"))
- ret = utils.load_entries(
- data_dir=tmp_path,
- pdb_ids=["aaaa", "bbbb"],
- )
- assert len(ret) == 2
-
-
-@pytest.mark.parametrize(
- "kwargs, expect",
- [
- ({}, 2),
- ({"two_char_codes": ["2g"]}, 2),
- ({"pdb_ids": ["22gs"]}, 1),
- ],
-)
-def test_load_entries_from_zips(kwargs, expect, tmp_path, entry_zip):
- zip_dir = tmp_path / "entries"
- zip_dir.mkdir(parents=True)
- (zip_dir / entry_zip.name).write_bytes(entry_zip.read_bytes())
- entries = utils.load_entries_from_zips(data_dir=tmp_path, **kwargs)
- assert len(entries) == expect
+ assert Pipeline().scatter_example() == [[]]
@pytest.mark.parametrize(
@@ -93,35 +60,389 @@ def test_hash_contents(contents):
utils.hash_contents(contents)
+def test_comparability_merge_reuses_complete_collated_column(tmp_path):
+ index = pd.DataFrame(
+ {
+ "ligand_id": ["1aaa__1__1.X", "1aaa__1__1.Y", None],
+ "system_type": ["holo", "holo", "apo"],
+ "ligand_is_proper": [True, False, False],
+ "ligand_is_shape_comparable": [True, True, None],
+ }
+ )
+
+ result = utils.add_ligand_3d_score_ability_column(
+ index=index,
+ data_dir=tmp_path,
+ )
+
+ assert result["ligand_is_shape_comparable"].tolist() == [True, False, False]
+ assert str(result["ligand_is_shape_comparable"].dtype) == "boolean"
+
+
+def test_finalize_index_writes_local_clusters_to_sidecar(tmp_path):
+ index_dir = tmp_path / "index"
+ directed_cover_file = (
+ tmp_path
+ / "ligand_sampling/directed_set_cover/metric=pli_qcov"
+ / "threshold=100.parquet"
+ )
+ tanimoto_cover_file = (
+ tmp_path
+ / "ligand_sampling/set_cover/metric=tanimoto_similarity_ecfp4_1024"
+ / "threshold=90.parquet"
+ )
+ index_dir.mkdir(parents=True)
+ directed_cover_file.parent.mkdir(parents=True)
+ tanimoto_cover_file.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1aaa", "1aaa"],
+ "system_id": ["1aaa__1__1.A__1.X", "1aaa__2__1.A__1.X"],
+ "system_id_no_biounit": ["1aaa__1.A__1.X", "1aaa__1.A__1.X"],
+ "system_biounit_id": ["1", "2"],
+ "system_type": ["holo", "holo"],
+ "ligand_id": ["1aaa__1__1.X", "1aaa__2__1.X"],
+ "ligand_is_proper": [True, False],
+ "ligand_smiles": ["CCO", "CCO"],
+ "ligand_neighboring_residues": [["1.A:10", "1.A:11"], None],
+ "ligand__members": [{"1.X": [1]}, {"2.X": [1]}],
+ "system_pass_criteria": [None, None],
+ "ligand_tanimoto_ecfp4_1024_90_cluster": ["legacy", "legacy"],
+ "ligand_tanimoto_ecfp4_1024_90_cluster_num_pdb_ids": [1, 1],
+ }
+ ).to_parquet(index_dir / "annotation_table.parquet", index=False)
+ fingerprint_dir = tmp_path / "fingerprints"
+ fingerprint_dir.mkdir()
+ pd.DataFrame(
+ {
+ "ligand_rdkit_canonical_smiles": ["CCO"],
+ "ligand_smiles_id": [0],
+ "ligand_is_cofactor_like": [False],
+ }
+ ).to_parquet(fingerprint_dir / "ligand_similarity_annotations.parquet", index=False)
+ ligand_dir = tmp_path / "ligands"
+ ligand_dir.mkdir()
+ pd.DataFrame(
+ {
+ "ligand_id": ["1aaa__1__1.X"],
+ "ligand_is_shape_comparable": [True],
+ }
+ ).to_parquet(ligand_dir / "part.parquet", index=False)
+ pd.DataFrame(
+ {
+ "ligand_id": ["1aaa__1__1.X"],
+ "centroid_ligand_id": ["1aaa__1__1.X"],
+ "similarity_to_centroid": [100.0],
+ "coverage_count": [1],
+ "coverage_fraction": [1.0],
+ "label": ["d0"],
+ "metric": ["pli_qcov"],
+ "threshold": [100],
+ "directed": [True],
+ }
+ ).to_parquet(directed_cover_file, index=False)
+ pd.DataFrame(
+ {
+ "ligand_id": ["1aaa__1__1.X"],
+ "centroid_ligand_id": ["1aaa__1__1.X"],
+ "label": ["t0"],
+ "metric": ["tanimoto_similarity_ecfp4_1024"],
+ "cluster": ["set_cover"],
+ "threshold": [90],
+ "directed": [False],
+ }
+ ).to_parquet(tanimoto_cover_file, index=False)
+ _write_component_labels(tmp_path, "tanimoto_similarity_ecfp4_1024", 90, ["0"])
+ _write_component_labels(tmp_path, "pli_qcov", 100, ["1aaa__1__1.X"])
+ arrow_finalized = utils.finalize_index(data_dir=tmp_path)
+ assert isinstance(
+ arrow_finalized["ligand_neighboring_residues"].dtype, pd.ArrowDtype
+ )
+ assert arrow_finalized["ligand_neighboring_residues"].iloc[0] == [
+ "1.A:10",
+ "1.A:11",
+ ]
+ assert pd.isna(arrow_finalized["ligand_neighboring_residues"].iloc[1])
+ finalized = pd.read_parquet(index_dir / "annotation_table.parquet")
+ assert "ligand__members" not in finalized
+ assert "system_pass_criteria" not in finalized
+ clusters = pd.read_parquet(index_dir / "ligand_clusters.parquet")
+ directed_labels = clusters["pli_qcov__100__ligand__directed_set_cover"]
+ assert directed_labels.iloc[0] == "d0"
+ assert pd.isna(directed_labels.iloc[1])
+ centroid_flags = clusters["pli_qcov__100__ligand__directed_set_cover__is_centroid"]
+ assert bool(centroid_flags.iloc[0])
+ assert pd.isna(centroid_flags.iloc[1])
+ coverage_counts = clusters[
+ "pli_qcov__100__ligand__directed_set_cover__coverage_count"
+ ]
+ coverage_fractions = clusters[
+ "pli_qcov__100__ligand__directed_set_cover__coverage_fraction"
+ ]
+ assert coverage_counts.iloc[0] == 1
+ assert coverage_fractions.iloc[0] == pytest.approx(1.0)
+ assert pd.isna(coverage_counts.iloc[1])
+ assert pd.isna(coverage_fractions.iloc[1])
+ tanimoto_column = "tanimoto_similarity_ecfp4_1024__90__ligand__set_cover"
+ assert clusters[tanimoto_column].tolist()[0] == "t0"
+ assert pd.isna(clusters[tanimoto_column].iloc[1])
+ assert bool(clusters[f"{tanimoto_column}__is_centroid"].iloc[0])
+ assert clusters["ligand_tanimoto_ecfp4_1024_90_cluster"].iloc[0] == "t0"
+ assert pd.isna(clusters["ligand_tanimoto_ecfp4_1024_90_cluster"].iloc[1])
+ assert clusters["ligand_tanimoto_ecfp4_1024_90_cluster_num_pdb_ids"].iloc[0] == 1
+ assert finalized.loc[0, "ligand_smiles_id"] == 0
+ assert pd.isna(finalized.loc[1, "ligand_smiles_id"])
+ assert finalized["ligand_is_shape_comparable"].tolist() == [True, False]
+ assert "uniqueness" not in finalized.columns
+ assert not any("set_cover" in column for column in finalized)
+ assert "ligand_tanimoto_ecfp4_1024_90_cluster" not in finalized
+
+
+def test_finalize_index_preserves_annotation_when_staging_fails(tmp_path, monkeypatch):
+ index_dir = tmp_path / "index"
+ index_dir.mkdir(parents=True)
+ index_path = index_dir / "annotation_table.parquet"
+ original = pd.DataFrame(
+ {
+ "entry_pdb_id": ["1aaa"],
+ "system_id": ["1aaa__1__1.A__1.X"],
+ "system_type": ["holo"],
+ "ligand_id": ["1aaa__1__1.X"],
+ "ligand_is_proper": [False],
+ "ligand_smiles": [None],
+ "ligand_is_shape_comparable": [False],
+ }
+ )
+ original.to_parquet(index_path, index=False)
+ fingerprint_dir = tmp_path / "fingerprints"
+ fingerprint_dir.mkdir()
+ pd.DataFrame(
+ {
+ "ligand_rdkit_canonical_smiles": pd.Series(dtype="string"),
+ "ligand_smiles_id": pd.Series(dtype="Int32"),
+ "ligand_is_cofactor_like": pd.Series(dtype="boolean"),
+ }
+ ).to_parquet(
+ fingerprint_dir / "ligand_similarity_annotations.parquet",
+ index=False,
+ )
+
+ original_to_parquet = pd.DataFrame.to_parquet
+
+ def fail_cluster_staging(frame, path, *args, **kwargs):
+ if path.name == "ligand_clusters.tmp.parquet":
+ raise OSError("staging failed")
+ return original_to_parquet(frame, path, *args, **kwargs)
+
+ monkeypatch.setattr(pd.DataFrame, "to_parquet", fail_cluster_staging)
+
+ with pytest.raises(OSError, match="staging failed"):
+ utils.finalize_index(data_dir=tmp_path)
+
+ pd.testing.assert_frame_equal(pd.read_parquet(index_path), original)
+ assert not (index_dir / "annotation_table.tmp.parquet").exists()
+
+
+def test_finalize_index_uses_weekly_cluster_assignments(tmp_path, monkeypatch):
+ index_dir = tmp_path / "index"
+ index_dir.mkdir()
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1aaa"],
+ "system_id": ["1aaa__1__1.A__1.X"],
+ "system_type": ["holo"],
+ "ligand_id": ["1aaa__1__1.X"],
+ "ligand_is_proper": [False],
+ "ligand_smiles": [None],
+ "ligand_is_shape_comparable": [False],
+ }
+ ).to_parquet(index_dir / "annotation_table.parquet", index=False)
+ fingerprints = tmp_path / "fingerprints"
+ fingerprints.mkdir()
+ pd.DataFrame(
+ {
+ "ligand_rdkit_canonical_smiles": pd.Series(dtype="string"),
+ "ligand_smiles_id": pd.Series(dtype="Int32"),
+ }
+ ).to_parquet(fingerprints / "ligand_similarity_annotations.parquet", index=False)
+ assignment = tmp_path / "weekly.parquet"
+ pd.DataFrame(
+ {
+ "ligand_id": ["1aaa__1__1.X"],
+ "pocket_qcov__50__ligand__directed_set_cover": ["fixed"],
+ }
+ ).to_parquet(assignment, index=False)
+ monkeypatch.setattr(
+ utils,
+ "build_ligand_cluster_table",
+ lambda **_kwargs: (_ for _ in ()).throw(AssertionError("full cover rebuilt")),
+ )
+
+ utils.finalize_index(data_dir=tmp_path, weekly_ligand_clusters=assignment)
+
+ clusters = pd.read_parquet(index_dir / "ligand_clusters.parquet")
+ assert clusters["pocket_qcov__50__ligand__directed_set_cover"].tolist() == ["fixed"]
+
+
+def test_cluster_index_rejects_non_tanimoto_set_cover(tmp_path):
+ cover_file = (
+ tmp_path / "ligand_sampling/set_cover/metric=pli_qcov" / "threshold=100.parquet"
+ )
+ cover_file.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "ligand_id": ["1aaa__1__1.X"],
+ "centroid_ligand_id": ["1aaa__1__1.X"],
+ "label": ["c0"],
+ }
+ ).to_parquet(cover_file, index=False)
+ index = pd.DataFrame(
+ {
+ "ligand_id": ["1aaa__1__1.X"],
+ "system_type": ["holo"],
+ "ligand_is_proper": [True],
+ "ligand_smiles_id": [0],
+ }
+ )
+
+ with pytest.raises(ValueError, match="invalid ligand set-cover modes"):
+ utils.build_ligand_cluster_table(index=index, data_dir=tmp_path)
+
+
@pytest.mark.parametrize(
- "two_char_codes, expect",
- [
- (["aa", "bb"], 2),
- (["aa"], 1),
- ([], 2),
- (None, 2),
- ],
+ "metric, column", sorted(CHEMICAL_CLUSTER_SUMMARY_COLUMNS.items())
)
-def test_get_local_contents(two_char_codes, expect, tmp_path):
- a = tmp_path / "aa" / "aaaa" / "aaaa.json"
- b = tmp_path / "bb" / "bbbb" / "bbbb.json"
- a.parent.mkdir(parents=True)
- b.parent.mkdir(parents=True)
- a.write_text(_ENTRY(pdb_id="aaaa"))
- b.write_text(_ENTRY(pdb_id="bbbb"))
- contents = utils.get_local_contents(
- data_dir=tmp_path,
- two_char_codes=two_char_codes,
+def test_chemical_90_set_cover_counts_distinct_pdb_ids(tmp_path, metric, column):
+ cover_file = (
+ tmp_path / f"ligand_sampling/set_cover/metric={metric}" / "threshold=90.parquet"
+ )
+ cover_file.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "ligand_id": ["l1", "l2", "l3"],
+ "centroid_ligand_id": ["l1", "l1", "l3"],
+ "label": ["c0", "c0", "c1"],
+ }
+ ).to_parquet(cover_file, index=False)
+ index = pd.DataFrame(
+ {
+ "entry_pdb_id": ["1aaa", "2bbb", "1aaa"],
+ "ligand_id": ["l1", "l2", "l3"],
+ "system_type": ["holo", "holo", "holo"],
+ "ligand_is_proper": [True, True, True],
+ "ligand_smiles_id": [0, 1, 2],
+ }
)
- assert len(contents) == expect
+ _write_component_labels(tmp_path, metric, 90, ["0", "1", "2"])
+ result = utils.build_ligand_cluster_table(index=index, data_dir=tmp_path)
+
+ assert result[column].tolist() == [
+ "c0",
+ "c0",
+ "c1",
+ ]
+ assert result[f"{column}_num_pdb_ids"].tolist() == [
+ 2,
+ 2,
+ 1,
+ ]
+
+
+def test_cluster_index_marks_only_directed_cover_centroids(tmp_path):
+ cover_file = (
+ tmp_path
+ / "ligand_sampling/directed_set_cover/metric=pli_qcov"
+ / "threshold=50.parquet"
+ )
+ cover_file.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "ligand_id": ["l1", "l2"],
+ "label": ["d0", "d0"],
+ "centroid_ligand_id": ["l2", "l2"],
+ "coverage_count": [1, 2],
+ "coverage_fraction": [0.5, 1.0],
+ }
+ ).to_parquet(cover_file, index=False)
+ index = pd.DataFrame(
+ {
+ "ligand_id": ["l1", "l2", "not-eligible"],
+ "system_type": ["holo", "holo", "apo"],
+ "ligand_is_proper": [True, True, False],
+ "ligand_smiles_id": [0, 1, pd.NA],
+ }
+ )
+ _write_component_labels(tmp_path, "pli_qcov", 50, ["l1", "l2"], ["c0", "c0"])
+
+ result = utils.build_ligand_cluster_table(index=index, data_dir=tmp_path)
+
+ label_column = "pli_qcov__50__ligand__directed_set_cover"
+ centroid_column = f"{label_column}__is_centroid"
+ assert result[label_column].tolist()[:2] == ["d0", "d0"]
+ assert result[centroid_column].tolist()[:2] == [False, True]
+ assert pd.isna(result.loc[2, centroid_column])
+ assert str(result[centroid_column].dtype) == "boolean"
+ count_column = f"{label_column}__coverage_count"
+ fraction_column = f"{label_column}__coverage_fraction"
+ assert result[count_column].tolist()[:2] == [1, 2]
+ assert result[fraction_column].tolist()[:2] == [0.5, 1.0]
+ assert pd.isna(result.loc[2, count_column])
+ assert pd.isna(result.loc[2, fraction_column])
+ assert str(result[count_column].dtype) == "Int32"
+ assert str(result[fraction_column].dtype) == "Float32"
+
+
+def test_ligand_similarity_rejects_stale_proper_smiles_universe(tmp_path):
+ fingerprint_dir = tmp_path / "fingerprints"
+ fingerprint_dir.mkdir()
+ pd.DataFrame(
+ {
+ "ligand_rdkit_canonical_smiles": ["CC"],
+ "ligand_smiles_id": [0],
+ }
+ ).to_parquet(
+ fingerprint_dir / "ligand_similarity_annotations.parquet",
+ index=False,
+ )
+ index = pd.DataFrame(
+ {
+ "system_type": ["holo", "holo"],
+ "ligand_is_proper": [True, True],
+ "ligand_smiles": ["CC", "CCC"],
+ }
+ )
+
+ with pytest.raises(ValueError, match="proper holo SMILES universe"):
+ utils.add_ligand_similarity_columns(index=index, data_dir=tmp_path)
+
+
+def test_ligand_similarity_reuses_matching_artifact_after_targeted_repair(
+ tmp_path,
+):
+ fingerprint_dir = tmp_path / "fingerprints"
+ index_dir = tmp_path / "index"
+ fingerprint_dir.mkdir()
+ index_dir.mkdir()
+ pd.DataFrame(
+ {
+ "ligand_rdkit_canonical_smiles": ["CC"],
+ "ligand_smiles_id": [0],
+ }
+ ).to_parquet(
+ fingerprint_dir / "ligand_similarity_annotations.parquet",
+ index=False,
+ )
+ (index_dir / "collation.json").write_text(
+ '{"status": "requires_downstream_repair"}'
+ )
+ index = pd.DataFrame(
+ {
+ "system_type": ["holo"],
+ "ligand_is_proper": [True],
+ "ligand_smiles": ["CC"],
+ }
+ )
-def test_get_local_contents_pdb_ids(tmp_path):
- a = tmp_path / "aa" / "pdb_0000aaaa" / "aaaa.json"
- b = tmp_path / "bb" / "pdb_0000bbbb" / "bbbb.json"
- a.parent.mkdir(parents=True)
- b.parent.mkdir(parents=True)
- a.write_text(_ENTRY(pdb_id="aaaa"))
- b.write_text(_ENTRY(pdb_id="bbbb"))
- contents = utils.get_local_contents(data_dir=tmp_path, as_four_char_ids=True)
- assert contents == ["aaaa", "bbbb"]
+ result = utils.add_ligand_similarity_columns(index=index, data_dir=tmp_path)
+ assert result["ligand_smiles_id"].tolist() == [0]
diff --git a/tests/data/pipeline/test_weekly_clusters.py b/tests/data/pipeline/test_weekly_clusters.py
new file mode 100644
index 000000000..3f695b02d
--- /dev/null
+++ b/tests/data/pipeline/test_weekly_clusters.py
@@ -0,0 +1,185 @@
+from pathlib import Path
+
+import pandas as pd
+
+from plinder.data.pipeline.weekly_clusters import (
+ _best_representatives,
+ extend_interface_clusters,
+ extend_ligand_clusters,
+)
+
+
+def test_weekly_assignment_keeps_qualifying_previous_representative():
+ scores = pd.DataFrame(
+ {
+ "query_node": ["new", "new"],
+ "target_node": ["first", "second"],
+ "similarity": [99, 91],
+ }
+ )
+ representatives = pd.DataFrame(
+ {"centroid": ["first", "second"], "label": ["a", "b"]}
+ )
+ result = _best_representatives(
+ scores,
+ representatives,
+ threshold=90,
+ directed=True,
+ previous_labels=pd.Series({"new": "b"}),
+ )
+ assert result.iloc[0]["label"] == "b"
+
+
+def test_weekly_ligands_join_existing_representatives(tmp_path: Path):
+ base = tmp_path / "base"
+ updated = tmp_path / "updated"
+ (base / "index").mkdir(parents=True)
+ (updated / "index").mkdir(parents=True)
+ (updated / "exports/ligand_similarity_scores").mkdir(parents=True)
+ (updated / "ligand_scores").mkdir()
+ (updated / "mhfp6_scores").mkdir()
+ (updated / "fingerprints").mkdir()
+ direct_column = "pocket_qcov__90__ligand__directed_set_cover"
+ direct_component = "pocket_qcov__90__ligand__reciprocal_component"
+ shape_column = "sucos_shape_pocket_qcov__90__ligand__directed_set_cover"
+ chemical_column = "tanimoto_similarity_ecfp4_1024__90__ligand__set_cover"
+ chemical_component = (
+ "tanimoto_similarity_ecfp4_1024__90__ligand__reciprocal_component"
+ )
+ summary = "ligand_tanimoto_ecfp4_1024_90_cluster"
+ pd.DataFrame(
+ {
+ "ligand_id": ["1aaa__1__1.X", "2bbb__1__1.X"],
+ direct_column: ["c0", "c1"],
+ direct_component: ["r0", "r1"],
+ f"{direct_column}__is_centroid": [True, True],
+ f"{direct_column}__coverage_count": [2, 1],
+ f"{direct_column}__coverage_fraction": [1.0, 1.0],
+ shape_column: ["c0", "c1"],
+ f"{shape_column}__is_centroid": [True, True],
+ chemical_column: ["t0", "t1"],
+ chemical_component: ["u0", "u1"],
+ f"{chemical_column}__is_centroid": [True, True],
+ summary: ["t0", "t1"],
+ f"{summary}_num_pdb_ids": [1, 1],
+ }
+ ).to_parquet(base / "index/ligand_clusters.parquet", index=False)
+ pd.DataFrame(
+ {
+ "entry_pdb_id": ["1aaa", "2bbb", "3ccc"],
+ "ligand_id": ["1aaa__1__1.X", "2bbb__1__1.X", "3ccc__1__1.X"],
+ "ligand_smiles": ["C", "CC", "CCC"],
+ "ligand_is_proper": [True, True, True],
+ "system_type": ["holo", "holo", "holo"],
+ }
+ ).to_parquet(updated / "index/annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "ligand_rdkit_canonical_smiles": ["C", "CC", "CCC"],
+ "ligand_smiles_id": [0, 1, 2],
+ }
+ ).to_parquet(
+ updated / "fingerprints/ligand_similarity_annotations.parquet", index=False
+ )
+ pd.DataFrame(
+ {
+ "query_ligand_id": ["3ccc__1__1.X"],
+ "target_ligand_id": ["1aaa__1__1.X"],
+ "pocket_qcov": pd.Series([100], dtype="int8"),
+ "pli_qcov": [70],
+ "sucos_shape": pd.Series([100], dtype="int8"),
+ }
+ ).to_parquet(updated / "exports/ligand_similarity_scores/cc.parquet", index=False)
+ pd.DataFrame(
+ {
+ "query_ligand_id": [2],
+ "target_ligand_id": [0],
+ "tanimoto_similarity_ecfp4_1024": [96.0],
+ }
+ ).to_parquet(updated / "ligand_scores/added.parquet", index=False)
+
+ result = extend_ligand_clusters(
+ base=base, data_dir=updated, affected={"3ccc"}
+ ).set_index("ligand_id")
+
+ assert result.at["3ccc__1__1.X", direct_column] == "c0"
+ assert result.at["3ccc__1__1.X", shape_column] == "c0"
+ assert result.at["3ccc__1__1.X", chemical_column] == "t0"
+ assert pd.isna(result.at["3ccc__1__1.X", direct_component])
+ assert pd.isna(result.at["3ccc__1__1.X", chemical_component])
+ assert result.at["1aaa__1__1.X", direct_component] == "r0"
+ assert not result.at["3ccc__1__1.X", f"{direct_column}__is_centroid"]
+ assert pd.isna(result.at["3ccc__1__1.X", f"{direct_column}__coverage_count"])
+ assert result.at["1aaa__1__1.X", f"{summary}_num_pdb_ids"] == 2
+
+
+def test_weekly_interfaces_join_existing_whole_and_side_covers(tmp_path: Path):
+ base = tmp_path / "base"
+ updated = tmp_path / "updated"
+ (base / "index").mkdir(parents=True)
+ (updated / "index").mkdir(parents=True)
+ (updated / "interface_scores").mkdir()
+ whole = "interface_qcov__90__directed_set_cover"
+ whole_component = "interface_qcov__90__reciprocal_component"
+ side = "interface_side_qcov__90__chain_1_directed_set_cover"
+ side_component = "interface_side_qcov__90__chain_1_reciprocal_component"
+ side_two = "interface_side_qcov__90__chain_2_directed_set_cover"
+ old = "1aaa__1__1.A--1.B"
+ new = "2bbb__1__1.A--1.B"
+ pd.DataFrame(
+ {
+ "system_id": [old],
+ whole: ["c0"],
+ whole_component: ["r0"],
+ side: ["s0"],
+ side_component: ["u0"],
+ side_two: ["s1"],
+ }
+ ).to_parquet(base / "index/interface_clusters.parquet", index=False)
+ pd.DataFrame(
+ {"entry_pdb_id": ["1aaa", "2bbb"], "system_id": [old, new]}
+ ).to_parquet(updated / "index/interface_annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "system_id": [old, new],
+ "representative_system_id": [old, new],
+ "side_1_half_interface_id": [f"{old}::side=1", f"{new}::side=1"],
+ "side_2_half_interface_id": [f"{old}::side=2", f"{new}::side=2"],
+ }
+ ).to_parquet(updated / "index/interface_membership.parquet", index=False)
+ for metric, nodes, labels in (
+ ("interface_qcov", [old], ["c0"]),
+ (
+ "interface_side_qcov",
+ [f"{old}::side=1", f"{old}::side=2"],
+ ["s0", "s1"],
+ ),
+ ):
+ directory = base / f"interface_sampling/directed_set_cover/metric={metric}"
+ directory.mkdir(parents=True)
+ pd.DataFrame(
+ {"system_id": nodes, "centroid_system_id": nodes, "label": labels}
+ ).to_parquet(directory / "threshold=90.parquet", index=False)
+ pd.DataFrame(
+ {
+ "query_system": [new, f"{new}::side=1", f"{new}::side=2"],
+ "target_system": [old, f"{old}::side=1", f"{old}::side=2"],
+ "metric": [
+ "interface_qcov",
+ "interface_side_qcov",
+ "interface_side_qcov",
+ ],
+ "similarity": [95, 92, 93],
+ }
+ ).to_parquet(updated / "interface_scores/shard=bb.parquet", index=False)
+
+ result = extend_interface_clusters(
+ base=base, data_dir=updated, affected={"2bbb"}
+ ).set_index("system_id")
+
+ assert result.at[new, whole] == "c0"
+ assert result.at[new, side] == "s0"
+ assert result.at[new, side_two] == "s1"
+ assert pd.isna(result.at[new, whole_component])
+ assert pd.isna(result.at[new, side_component])
+ assert result.at[old, whole_component] == "r0"
diff --git a/tests/data/test_ccd_ligand_dbs.py b/tests/data/test_ccd_ligand_dbs.py
new file mode 100644
index 000000000..0db75d00c
--- /dev/null
+++ b/tests/data/test_ccd_ligand_dbs.py
@@ -0,0 +1,1148 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+"""Tests for the CCD-anchored ligand relationship databases.
+
+Everything here runs against the real bundled CCD; no synthetic component ids.
+"""
+
+import gzip
+import json
+import shutil
+from collections import Counter
+from pathlib import Path
+
+import numpy as np
+import pandas as pd
+import pytest
+from biotite.structure.io.pdbx import CIFFile, get_structure
+
+from plinder.core.structure.smallmols_similarity import smiles2nonstereo
+from plinder.data.annotations.ccd_ligand_dbs import (
+ LOG,
+ CcdParityTable,
+ ResidueGraph,
+ _ccd_chem_comp_table,
+ _ccd_heavy_atoms,
+ _ccd_mmp_inputs,
+ _ccd_named_mol,
+ _ccd_smiles,
+ build_ccd_ecfp_db,
+ build_ccd_parity_scores,
+ build_ccd_tanimoto_scores,
+ build_ligand_ccd_match,
+ ccd_code_residue_graph,
+ ccd_code_sequence,
+ ccd_component_table,
+ ccd_dbs_dir,
+ ccd_fingerprint_path,
+ ccd_node_similarity,
+ ccd_parity_path,
+ ccd_universe_signature,
+ component_sequence_identity,
+ composite_parity,
+ composite_similarity,
+ ligand_features,
+ ligand_parity,
+ ligand_similarity,
+ make_ccd_ligand_dbs,
+ make_ligand_ccd_match,
+ match_composite_by_sequence,
+ query_ccd_mmp_pairs,
+ query_ccd_parity,
+ query_ccd_tanimoto,
+ residue_graph_features,
+ residue_graph_from_atoms,
+)
+
+needs_mmpdb = pytest.mark.skipif(
+ shutil.which("mmpdb") is None, reason="mmpdb executable not installed"
+)
+LIMIT = 1500
+
+
+def test_ccd_mmp_inputs_exclude_unsupported_chemistry() -> None:
+ components = pd.DataFrame(
+ {
+ "ccd_id": ["ETH", "MET", "SAL", "BAD"],
+ "ligand_smiles_id": [0, 1, 2, 3],
+ "ligand_rdkit_canonical_smiles": [
+ "CCO",
+ "N->[Cu+2]<-N",
+ "CCO.[Na+]",
+ "C1CC",
+ ],
+ }
+ )
+ included, excluded = _ccd_mmp_inputs(components)
+ assert included["ccd_id"].tolist() == ["ETH"]
+ assert dict(zip(excluded["ccd_id"], excluded["reason"])) == {
+ "MET": "metal_dative_bonds",
+ "SAL": "disconnected_components",
+ "BAD": "unsupported_by_mmpdb_smiles_parser",
+ }
+
+
+@pytest.fixture(scope="module")
+def components() -> pd.DataFrame:
+ return ccd_component_table(limit=LIMIT)
+
+
+def test_chem_comp_table_pins_the_biotite_bundle_contract():
+ """Fails loudly if a bundle change removes a column this module needs."""
+ table = _ccd_chem_comp_table()
+ assert len(table) > 40_000
+ # Exactly the columns this module consumes - nothing fetched and unused.
+ assert set(table.columns) == {"id", "type", "pdbx_release_status"}
+ assert {"REL", "OBS"} <= set(table["pdbx_release_status"])
+
+
+def test_component_table_filters_and_numbers_nodes(components):
+ released = set(
+ _ccd_chem_comp_table()
+ .loc[lambda df: df["pdbx_release_status"] == "REL", "id"]
+ .astype(str)
+ )
+ assert set(components["ccd_id"]) <= released
+ assert not {"UNL", "UNX", "DUM"} & set(components["ccd_id"])
+ # is_excluded_mol enforces the >=5 heavy-atom floor; no invented cap.
+ assert components["num_heavy_atoms"].min() >= 5
+ assert all(value == value.lower() for value in components["ccd_type"])
+ # 0-based and contiguous: ligand_scores indexes the fingerprint list by node
+ # id and rejects any other numbering.
+ assert components["ligand_smiles_id"].tolist() == list(range(len(components)))
+
+
+def test_universe_signature_is_deterministic_and_content_sensitive(components):
+ baseline = ccd_universe_signature(components)
+ assert baseline == ccd_universe_signature(components.copy())
+ changed = components.copy()
+ changed.loc[0, "ligand_rdkit_canonical_smiles"] = "CCO"
+ assert ccd_universe_signature(changed) != baseline
+
+
+def test_non_druglike_components_are_dropped(components):
+ """Named real components, so this checks the wiring, not is_excluded_mol itself."""
+ broad = ccd_component_table(limit=LIMIT, exclude_non_druglike=False)
+ dropped = set(broad["ccd_id"]) - set(components["ccd_id"])
+ # 06C = CI (1 carbon), 03S = CS(=O)(=O)O (1 carbon)
+ assert {"06C", "03S"} <= dropped
+ assert "001" in set(components["ccd_id"])
+
+
+def test_polymer_linking_exclusion_is_opt_in(components):
+ ligand_only = ccd_component_table(limit=LIMIT, exclude_polymer_linking=True)
+ assert len(ligand_only) < len(components)
+ assert not ligand_only["ccd_type"].str.contains("linking").any()
+ assert components["ccd_type"].str.contains("linking").any()
+
+
+def _match_all(ligands: pd.DataFrame, components: pd.DataFrame) -> pd.DataFrame:
+ return build_ligand_ccd_match(ligands, components).set_index("ligand_id")
+
+
+def test_match_by_code_then_by_chemistry_against_the_real_universe(components):
+ known, other = components["ccd_id"].iloc[0], components["ccd_id"].iloc[1]
+ smiles = dict(
+ zip(components["ccd_id"], components["ligand_rdkit_canonical_smiles"])
+ )
+ nodes = dict(zip(components["ccd_id"], components["ligand_smiles_id"]))
+ ligands = pd.DataFrame(
+ {
+ "ligand_id": ["by_code", "by_chemistry", "composite", "ion", "novel"],
+ "ligand_ccd_code": [known, "ZZZZZ", f"{known}-{other}", "NA", "ZZZZZ"],
+ "ligand_smiles": [smiles[known], smiles[known], "CC", "[Na+]", "CCOCC"],
+ }
+ )
+ matches = _match_all(ligands, components)
+ assert matches.loc["by_code", "match_kind"] == "exact"
+ assert matches.loc["by_code", "ccd_node_ids"] == [nodes[known]]
+ # an unknown code with a component's chemistry is that component
+ assert matches.loc["by_chemistry", "match_kind"] == "exact"
+ assert known in matches.loc["by_chemistry", "matched_ccd_ids"]
+ # a composite is not its parts: annotated with them, matched as a molecule
+ assert matches.loc["composite", "match_kind"] == "novel"
+ assert matches.loc["composite", "component_ccd_ids"] == [known, other]
+ assert matches.loc["composite", "ccd_node_ids"] == []
+ # sodium is a released CCD component the universe filters out, not novel
+ assert "NA" not in set(components["ccd_id"])
+ assert matches.loc["ion", "match_kind"] == "excluded"
+ assert matches.loc["novel", "match_kind"] == "novel"
+
+
+def test_one_molecule_matches_however_it_was_deposited():
+ """Lactose as one code (LAT) or as its linked sugars (GAL-BGC).
+
+ Chemistry matching uses the stereo-aware canonical SMILES, the dataset's own
+ ligand key, so cellobiose and maltose (same graph, other stereo) stay apart
+ and a ligand without stereo matches nothing rather than all three.
+ """
+ from rdkit import Chem
+
+ codes = ["LAT", "CBI", "MAL", "GAL", "BGC"]
+ components = pd.DataFrame({"ccd_id": codes})
+ components["ligand_rdkit_canonical_smiles"] = [_ccd_smiles(c) for c in codes]
+ components["ligand_smiles_id"] = range(len(codes))
+ stereo_free = components["ligand_rdkit_canonical_smiles"].map(smiles2nonstereo)
+ assert len(set(stereo_free.iloc[:3])) == 1, "three stereoisomers of one graph"
+ assert components["ligand_rdkit_canonical_smiles"].iloc[:3].is_unique
+ # the composite's whole-molecule SMILES, written from a different atom order
+ lactose = Chem.MolFromSmiles(_ccd_smiles("LAT"))
+ reordered = Chem.MolToSmiles(
+ Chem.RenumberAtoms(lactose, list(reversed(range(lactose.GetNumAtoms())))),
+ canonical=False,
+ )
+ assert reordered != _ccd_smiles("LAT")
+ ligands = pd.DataFrame(
+ {
+ "ligand_id": ["one_code", "two_codes", "two_codes_no_stereo", "galactose"],
+ "ligand_ccd_code": ["LAT", "GAL-BGC", "GAL-BGC", "GAL"],
+ "ligand_smiles": [
+ _ccd_smiles("LAT"),
+ reordered,
+ stereo_free.iloc[0],
+ _ccd_smiles("GAL"),
+ ],
+ }
+ )
+ matches = _match_all(ligands, components)
+ assert matches.loc["two_codes", "match_kind"] == "exact"
+ assert matches.loc["two_codes", "matched_ccd_ids"] == ["LAT"]
+ assert matches.loc["two_codes", "component_ccd_ids"] == ["GAL", "BGC"]
+ # no stereo means a different molecule as far as identity goes
+ assert matches.loc["two_codes_no_stereo", "match_kind"] == "novel"
+ assert matches.loc["one_code", "matched_ccd_ids"] == ["LAT"]
+ # a code match is never overridden by chemistry
+ assert matches.loc["galactose", "matched_ccd_ids"] == ["GAL"]
+
+
+def test_make_ligand_ccd_match_joins_the_collated_annotation_table(
+ tmp_path, components
+):
+ with pytest.raises(FileNotFoundError):
+ make_ligand_ccd_match(data_dir=tmp_path)
+
+ known = components["ccd_id"].iloc[0]
+ (tmp_path / "index").mkdir()
+ pd.DataFrame(
+ {
+ "ligand_id": ["a__1__1.A", "a__1__1.A", "b__1__1.B"],
+ "ligand_ccd_code": [known, known, "ZZZZZ"],
+ "ligand_smiles": ["C", "C", "CCOCC"],
+ }
+ ).to_parquet(tmp_path / "index" / "annotation_table.parquet", index=False)
+ ccd_dbs_dir(tmp_path).mkdir()
+ components.to_parquet(ccd_dbs_dir(tmp_path) / "ccd_components.parquet", index=False)
+
+ output = make_ligand_ccd_match(data_dir=tmp_path)
+
+ assert output == ccd_dbs_dir(tmp_path) / "ligand_ccd_match.parquet"
+ matches = pd.read_parquet(output).set_index("ligand_id")
+ assert matches["match_kind"].to_dict() == {
+ "a__1__1.A": "exact",
+ "b__1__1.B": "novel",
+ }
+
+
+@pytest.mark.parametrize(
+ "query, target, expected",
+ [
+ ("SER-GLY-ALA", "SER-GLY-ALA", 1.0),
+ ("DA-DT-DG", "DA-DC-DG", pytest.approx(2 / 3)),
+ # Order matters - a sequence match, not a set intersection.
+ ("NAG-BMA", "BMA-NAG", 0.5),
+ ("SER-GLY", "TRP-PHE", 0.0),
+ ("SER-GLY", "SER-GLY-ALA-LYS", 0.5),
+ ("", "ATP", 0.0),
+ ("ATP", "ATP", 1.0),
+ ],
+ ids=[
+ "identical",
+ "one-substitution",
+ "order-matters",
+ "disjoint",
+ "prefix-normalised-by-longer",
+ "empty-query",
+ "single-component",
+ ],
+)
+def test_component_sequence_identity(query, target, expected):
+ """Each case pins a distinct property; the comparison is class-agnostic."""
+ assert (
+ component_sequence_identity(ccd_code_sequence(query), ccd_code_sequence(target))
+ == expected
+ )
+
+
+def test_match_composite_by_sequence_ranks_and_thresholds():
+ """Stereoisomeric sugars that achiral ECFP4 cannot separate, resolved by code."""
+ references = {"same": "NAG-NAG-BMA", "one_off": "NAG-NAG-MAN", "other": "DA-DT-DG"}
+ matches = match_composite_by_sequence("NAG-NAG-BMA", references, min_identity=0.6)
+ assert [name for name, _ in matches] == ["same", "one_off"]
+ assert matches[0][1] == 1.0
+
+
+@needs_mmpdb
+def test_tanimoto_scores_match_native_edge_schema(tmp_path, components):
+ """The CCD table drives the *native* scorer unchanged."""
+ build_ccd_ecfp_db(components, ccd_fingerprint_path(tmp_path))
+ scores_dir = build_ccd_tanimoto_scores(
+ components, tmp_path, minimum_similarity=30.0, batch_size=750
+ )
+ shards = sorted(scores_dir.glob("*.parquet"))
+ assert len(shards) > 1
+ edges = pd.concat([pd.read_parquet(shard) for shard in shards])
+ assert list(edges.columns) == [
+ "query_ligand_id",
+ "target_ligand_id",
+ "tanimoto_similarity_ecfp4_1024",
+ ]
+ nodes = set(components["ligand_smiles_id"])
+ assert set(edges["query_ligand_id"]) <= nodes
+ assert set(edges["target_ligand_id"]) <= nodes
+ self_edges = edges[edges["query_ligand_id"] == edges["target_ligand_id"]]
+ assert (self_edges["tanimoto_similarity_ecfp4_1024"] == 100.0).all()
+ assert edges["tanimoto_similarity_ecfp4_1024"].min() >= 30.0
+
+
+def test_parity_scores_every_tanimoto_edge_once(tmp_path):
+ """The ECFP4 edges are the prefilter; each unordered pair is scored once."""
+ small = ccd_component_table(limit=300)
+ build_ccd_ecfp_db(small, ccd_fingerprint_path(tmp_path))
+ scores_dir = build_ccd_tanimoto_scores(small, tmp_path, batch_size=100)
+ edges = pd.concat(
+ [pd.read_parquet(shard) for shard in scores_dir.glob("*.parquet")]
+ )
+ unordered = edges[edges["query_ligand_id"] < edges["target_ligand_id"]]
+ parity = pd.read_parquet(
+ build_ccd_parity_scores(small, tmp_path, threads=2, batch_size=50)
+ )
+ assert list(parity.columns) == [
+ "ligand_smiles_id_1",
+ "ligand_smiles_id_2",
+ "tanimoto_similarity_ecfp4_1024",
+ "parity_similarity",
+ "parity_coverage_1",
+ "parity_coverage_2",
+ "fragment_atoms_1",
+ "fragment_atoms_2",
+ ]
+ assert len(parity) == len(unordered) > 0
+ # the stored fragment is in CCD atom names, one name per mapped atom on each side
+ codes = small.set_index("ligand_smiles_id")["ccd_id"]
+ scored = parity[parity["parity_similarity"] > 0]
+ assert len(scored) > 0
+ for row in scored.head(20).itertuples(index=False):
+ assert len(row.fragment_atoms_1) == len(row.fragment_atoms_2) > 0
+ for one, other in zip(row.fragment_atoms_1, row.fragment_atoms_2):
+ assert len(one) == len(other) > 0
+ assert set(one) <= set(_ccd_heavy_atoms(codes[row.ligand_smiles_id_1])[0])
+ assert set(other) <= set(_ccd_heavy_atoms(codes[row.ligand_smiles_id_2])[0])
+ assert (parity["ligand_smiles_id_1"] < parity["ligand_smiles_id_2"]).all()
+ assert not parity.duplicated(["ligand_smiles_id_1", "ligand_smiles_id_2"]).any()
+ assert parity["parity_similarity"].between(0.0, 100.0).all()
+ # each side's coverage is a fraction of that molecule, never below the union score
+ for side in ("parity_coverage_1", "parity_coverage_2"):
+ assert parity[side].between(0.0, 100.0).all()
+ assert (parity[side] >= parity["parity_similarity"] - 1e-9).all()
+ # the graph score orders neighbours differently from the fingerprint
+ assert (
+ parity["parity_similarity"].corr(parity["tanimoto_similarity_ecfp4_1024"])
+ < 0.95
+ )
+
+
+def test_parity_scores_write_multiple_batches(tmp_path):
+ components = ccd_component_table(limit=3)
+ ids = sorted(components["ligand_smiles_id"])
+ scores_dir = ccd_dbs_dir(tmp_path) / "ligand_scores"
+ scores_dir.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "query_ligand_id": [ids[0], ids[0], ids[1]],
+ "target_ligand_id": [ids[1], ids[2], ids[2]],
+ "tanimoto_similarity_ecfp4_1024": [80.0, 70.0, 60.0],
+ }
+ ).to_parquet(scores_dir / "ccd_scores_0000.parquet", index=False)
+
+ path = build_ccd_parity_scores(components, tmp_path, threads=1, batch_size=1)
+ table = pd.read_parquet(path)
+ assert len(table) == 3
+ assert list(table["tanimoto_similarity_ecfp4_1024"]) == [80.0, 70.0, 60.0]
+ assert list(table.columns[-2:]) == ["fragment_atoms_1", "fragment_atoms_2"]
+
+
+@pytest.fixture(scope="module")
+def ccd_dbs(tmp_path_factory) -> Path:
+ if shutil.which("mmpdb") is None:
+ pytest.skip("mmpdb executable not installed")
+ data_dir = tmp_path_factory.mktemp("ccd_dbs")
+ make_ccd_ligand_dbs(
+ data_dir=data_dir,
+ scratch_dir=data_dir / "scratch",
+ threads=2,
+ limit=400,
+ build_tanimoto_scores=False,
+ )
+ return data_dir
+
+
+@needs_mmpdb
+def test_fragment_dictionary_reproduces_every_mmpdb_pair(ccd_dbs):
+ pairs = pd.read_parquet(ccd_dbs / "ccd_dbs" / "ccd_mmp_pairs.parquet")
+ assert not pairs.empty
+ queried = pairs.drop_duplicates("ligand_smiles_id_1").head(12)
+ found = query_ccd_mmp_pairs(
+ dict(
+ zip(queried["ligand_smiles_id_1"].astype(str), queried["ligand_smiles_1"])
+ ),
+ ccd_dbs,
+ )
+ expected = pairs[pairs["ligand_smiles_id_1"].isin(queried["ligand_smiles_id_1"])]
+ for pair in expected.itertuples(index=False):
+ hits = found[
+ (found["query_id"] == str(pair.ligand_smiles_id_1))
+ & (found["ligand_smiles_id"] == pair.ligand_smiles_id_2)
+ & (found["shared_core_smiles"] == pair.shared_core_smiles)
+ ]
+ # mmpdb writes the pair in canonical order; ours reads query >> component
+ reversed_smirks = ">>".join(reversed(pair.transformation.split(">>")))
+ assert {pair.transformation, reversed_smirks} & set(hits["transformation"]), (
+ pair
+ )
+ # a component never pairs with itself
+ assert not (found["query_id"].astype(int) == found["ligand_smiles_id"]).any()
+
+
+@needs_mmpdb
+def test_novel_molecule_pairs_against_the_universe(ccd_dbs):
+ components = pd.read_parquet(ccd_dbs / "ccd_dbs" / "ccd_components.parquet")
+ # diphenyl ether is not one of the first 400 components
+ assert "c1ccc(Oc2ccccc2)cc1" not in set(components["ligand_rdkit_canonical_smiles"])
+ novel = query_ccd_mmp_pairs({"dpe": "c1ccccc1Oc1ccccc1"}, ccd_dbs)
+ assert not novel.empty
+ assert list(novel.columns) == [
+ "query_id",
+ "query_smiles",
+ "ligand_smiles_id",
+ "transformation",
+ "shared_core_smiles",
+ "num_cuts",
+ "shared_core_num_heavy_atoms",
+ "ccd_id",
+ "ligand_smiles",
+ ]
+ assert set(novel["ligand_smiles_id"]) <= set(components["ligand_smiles_id"])
+ assert novel["ccd_id"].notna().all()
+ assert (novel["transformation"].str.count(">>") == 1).all()
+ # an unparsable query is skipped, not fatal
+ assert query_ccd_mmp_pairs({"bad": "C1CC"}, ccd_dbs).empty
+
+
+@needs_mmpdb
+def test_novel_molecule_tanimoto_neighbours_use_the_native_measure(ccd_dbs):
+ components = pd.read_parquet(ccd_dbs / "ccd_dbs" / "ccd_components.parquet")
+ own = components.iloc[7]
+ hits = query_ccd_tanimoto(
+ {"self": own["ligand_rdkit_canonical_smiles"], "dpe": "c1ccccc1Oc1ccccc1"},
+ ccd_dbs,
+ minimum_similarity=30.0,
+ )
+ assert list(hits.columns) == [
+ "query_id",
+ "query_smiles",
+ "ligand_smiles_id",
+ "tanimoto_similarity_ecfp4_1024",
+ "ccd_id",
+ ]
+ best = hits[hits["query_id"] == "self"].iloc[0]
+ assert best["ccd_id"] == own["ccd_id"]
+ assert best["tanimoto_similarity_ecfp4_1024"] == 100.0
+ assert (hits["tanimoto_similarity_ecfp4_1024"] >= 30.0).all()
+ assert set(hits["ligand_smiles_id"]) <= set(components["ligand_smiles_id"])
+ assert hits["ccd_id"].notna().all()
+
+
+@needs_mmpdb
+def test_novel_molecule_parity_extends_the_precompiled_table(ccd_dbs):
+ """Ligands that only exist at dataset time are scored the same way, later."""
+ components = pd.read_parquet(ccd_dbs / "ccd_dbs" / "ccd_components.parquet")
+ own = components.iloc[7]
+ hits = query_ccd_parity(
+ {"self": own["ligand_rdkit_canonical_smiles"], "dpe": "c1ccccc1Oc1ccccc1"},
+ ccd_dbs,
+ threads=2,
+ )
+ assert list(hits.columns) == [
+ "query_id",
+ "query_smiles",
+ "ligand_smiles_id",
+ "tanimoto_similarity_ecfp4_1024",
+ "ccd_id",
+ "parity_similarity",
+ "parity_coverage_1",
+ "parity_coverage_2",
+ ]
+ best = hits[hits["query_id"] == "self"].iloc[0]
+ assert best["ccd_id"] == own["ccd_id"]
+ assert best["parity_similarity"] == 100.0
+ assert best["parity_coverage_1"] == best["parity_coverage_2"] == 100.0
+ assert (hits["tanimoto_similarity_ecfp4_1024"] >= 30.0).all()
+ assert hits["parity_similarity"].between(0.0, 100.0).all()
+ dpe = hits[hits["query_id"] == "dpe"]["parity_similarity"]
+ assert dpe.is_monotonic_decreasing and len(dpe) > 0
+
+
+@needs_mmpdb
+def test_make_ccd_ligand_dbs_builds_artifacts_and_caches(tmp_path):
+ output_dir = make_ccd_ligand_dbs(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=2,
+ limit=250,
+ build_tanimoto_scores=False,
+ )
+ paths = [
+ output_dir / "ccd_components.parquet",
+ output_dir / "fingerprints" / "ligands_per_smiles.parquet",
+ output_dir / "ccd_mmp_pairs.parquet",
+ output_dir / "ccd_mmp_fragments.parquet",
+ output_dir / "ccd_mmp_exclusions.tsv",
+ output_dir / "ccd_dbs.manifest.json",
+ ]
+ for path in paths:
+ assert path.is_file(), path
+
+ components = pd.read_parquet(paths[0])
+ ecfp = pd.read_parquet(paths[1])
+ mmp = pd.read_parquet(paths[2])
+ assert set(ecfp["ligand_smiles_id"]) == set(components["ligand_smiles_id"])
+ assert "fingerprint" in ecfp.columns
+ nodes = set(components["ligand_smiles_id"])
+ assert set(mmp["ligand_smiles_id_1"]) <= nodes
+ assert set(mmp["ligand_smiles_id_2"]) <= nodes
+
+ before = {path.name: path.stat().st_mtime_ns for path in paths}
+ make_ccd_ligand_dbs(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=2,
+ limit=250,
+ build_tanimoto_scores=False,
+ )
+ assert {path.name: path.stat().st_mtime_ns for path in paths} == before
+
+
+@needs_mmpdb
+def test_ccd_score_cache_tracks_similarity_cutoff(tmp_path):
+ def build(cutoff, *, scores=True):
+ return make_ccd_ligand_dbs(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=2,
+ limit=12,
+ minimum_similarity=cutoff,
+ build_tanimoto_scores=scores,
+ build_parity_scores=scores,
+ )
+
+ def read_scores(output_dir):
+ edges = pd.concat(
+ [
+ pd.read_parquet(path)
+ for path in sorted((output_dir / "ligand_scores").glob("*.parquet"))
+ ],
+ ignore_index=True,
+ )
+ parity_pairs = pd.read_parquet(
+ ccd_parity_path(tmp_path),
+ columns=[
+ "ligand_smiles_id_1",
+ "ligand_smiles_id_2",
+ "tanimoto_similarity_ecfp4_1024",
+ ],
+ )
+ return edges, parity_pairs
+
+ output_dir = build(0.0)
+ all_edges, all_parity = read_scores(output_dir)
+ similarity = "tanimoto_similarity_ecfp4_1024"
+ assert all_parity[similarity].lt(100.0).any()
+
+ # A score-free run must not certify the older score files at a new cutoff.
+ build(100.0, scores=False)
+ build(100.0)
+ high_edges, high_parity = read_scores(output_dir)
+ for actual, original in [(high_edges, all_edges), (high_parity, all_parity)]:
+ pd.testing.assert_frame_equal(
+ actual,
+ original.loc[original[similarity].ge(100.0)].reset_index(drop=True),
+ )
+
+ build(0.0)
+ low_edges, low_parity = read_scores(output_dir)
+ pd.testing.assert_frame_equal(low_edges, all_edges)
+ pd.testing.assert_frame_equal(low_parity, all_parity)
+ manifest = json.loads((output_dir / "ccd_dbs.manifest.json").read_text())
+ assert manifest["minimum_similarity"] == 0.0
+ assert manifest["build_tanimoto_scores"] is True
+ assert manifest["build_parity_scores"] is True
+
+ paths = list((output_dir / "ligand_scores").glob("*.parquet")) + [
+ ccd_parity_path(tmp_path)
+ ]
+ modified = {path: path.stat().st_mtime_ns for path in paths}
+ build(0.0)
+ assert {path: path.stat().st_mtime_ns for path in paths} == modified
+
+
+@needs_mmpdb
+def test_default_ccd_build_defers_parity(tmp_path):
+ output_dir = make_ccd_ligand_dbs(
+ data_dir=tmp_path,
+ scratch_dir=tmp_path / "scratch",
+ threads=2,
+ limit=12,
+ )
+ assert list((output_dir / "ligand_scores").glob("ccd_scores_*.parquet"))
+ assert not ccd_parity_path(tmp_path).exists()
+ manifest = json.loads((output_dir / "ccd_dbs.manifest.json").read_text())
+ assert manifest["build_parity_scores"] is False
+
+
+@needs_mmpdb
+def test_tanimoto_rebuild_does_not_leave_stale_shards(tmp_path):
+ """A smaller rebuild must not leave edges referencing dead node ids."""
+ big = ccd_component_table(limit=300)
+ build_ccd_ecfp_db(big, ccd_fingerprint_path(tmp_path))
+ build_ccd_tanimoto_scores(big, tmp_path, batch_size=100)
+
+ small = ccd_component_table(limit=120)
+ build_ccd_ecfp_db(small, ccd_fingerprint_path(tmp_path))
+ scores_dir = build_ccd_tanimoto_scores(small, tmp_path, batch_size=100)
+
+ edges = pd.concat(
+ [pd.read_parquet(shard) for shard in scores_dir.glob("*.parquet")]
+ )
+ assert edges["query_ligand_id"].max() < len(small)
+
+
+@pytest.fixture(scope="module")
+def atoms_2dty(cif_2dty):
+ """2dty as deposited: chains E and F each carry a branched NAG-FUC-NAG."""
+ with gzip.open(cif_2dty, "rt") as handle:
+ return get_structure(
+ CIFFile.read(handle), model=1, include_bonds=True, altloc="first"
+ )
+
+
+def glycan(atoms, *chains):
+ return atoms[
+ np.isin(atoms.chain_id, list(chains)) & np.isin(atoms.res_name, ["NAG", "FUC"])
+ ]
+
+
+def test_residue_graph_roots_at_the_reducing_end(atoms_2dty):
+ graph = residue_graph_from_atoms(glycan(atoms_2dty, "E"))
+ assert graph.labels == ("NAG", "FUC", "NAG")
+ # The core NAG carries both the fucose and the second NAG: branched, not a
+ # chain, and the only residue donating no anomeric carbon.
+ assert graph.adjacency == (frozenset({1, 2}), frozenset({0}), frozenset({0}))
+ assert graph.roots == (0,)
+ assert graph.is_tree and graph.is_connected
+
+
+def test_connectivity_separates_what_the_ccd_code_cannot(atoms_2dty):
+ """The deposited glycan is branched; its own code string reads as linear."""
+ deposited = residue_graph_from_atoms(glycan(atoms_2dty, "E"))
+ code = "-".join(deposited.labels)
+
+ assert (
+ component_sequence_identity(ccd_code_sequence(code), ccd_code_sequence(code))
+ == 1.0
+ ), "sequence identity cannot see the branch"
+ assert composite_similarity(
+ deposited, ccd_code_residue_graph(code)
+ ) == pytest.approx(4 / 9)
+ assert composite_similarity(deposited, deposited) == 1.0
+
+
+def test_composite_similarity_is_independent_of_residue_order(atoms_2dty):
+ """Relabelling the traversal must not move the score; a code string would."""
+ graph = residue_graph_from_atoms(glycan(atoms_2dty, "E"))
+ order = [2, 0, 1]
+ position = {old: new for new, old in enumerate(order)}
+ shuffled = ResidueGraph(
+ tuple(graph.labels[old] for old in order),
+ tuple(frozenset(position[n] for n in graph.adjacency[old]) for old in order),
+ tuple(position[root] for root in graph.roots),
+ )
+ assert shuffled.labels != graph.labels
+ assert composite_similarity(graph, shuffled) == 1.0
+
+
+def test_residue_graph_records_present_atoms_and_link_atoms(atoms_2dty):
+ """Linked residues have lost their leaving oxygen; each linkage names its atoms."""
+ graph = residue_graph_from_atoms(glycan(atoms_2dty, "E"))
+ assert [len(names) for names in graph.atoms] == [14, 10, 14]
+ assert all("O1" not in names for names in graph.atoms)
+ # fucose alpha1-3 and the second NAG beta1-4, both donating their anomeric C1
+ assert graph.links == ((0, 1, "O3", "C1"), (0, 2, "O4", "C1"))
+
+
+@pytest.fixture(scope="module")
+def sugar_table() -> CcdParityTable:
+ return CcdParityTable.compute(["NAG", "FUC", "GLC", "BMA"], threads=2)
+
+
+def test_parity_table_is_symmetric_and_identity_aware(sugar_table):
+ forward, backward = (
+ sugar_table.mapping("GLC", "NAG"),
+ sugar_table.mapping("NAG", "GLC"),
+ )
+ assert forward and backward == {q: p for p, q in forward.items()}
+ assert (
+ sugar_table.similarity("GLC", "NAG") == sugar_table.similarity("NAG", "GLC") > 0
+ )
+ assert sugar_table.similarity("NAG", "NAG") == 1.0
+ assert sugar_table.mapping("NAG", "NAG") == {
+ n: n for n in _ccd_heavy_atoms("NAG")[0]
+ }
+ assert sugar_table.mappings("GLC", "NAG")[0] == forward
+ # alternatives are stored for residue pairs; the scored fragment leads
+ alternatives = CcdParityTable.compute(["FUC", "VAL"]).mappings("FUC", "VAL")
+ assert len(alternatives) > 1
+ assert len({tuple(sorted(m.items())) for m in alternatives}) == len(alternatives)
+ assert all(len(m) <= len(alternatives[0]) for m in alternatives)
+ assert (
+ sugar_table.similarity("NAG", "XYZ") == 0.0
+ and sugar_table.mapping("NAG", "XYZ") == {}
+ )
+
+
+def test_parity_table_resolves_direction_from_one_stored_pair(sugar_table):
+ # glucose sits inside its N-acetyl derivative: covered as query, not as target
+ inside, outside = (
+ sugar_table.coverage("GLC", "NAG"),
+ sugar_table.coverage("NAG", "GLC"),
+ )
+ assert inside > outside > 0
+ assert sugar_table.coverage("NAG", "NAG") == 1.0
+ assert sugar_table.coverage("NAG", "XYZ") == 0.0
+ directed = sugar_table.directed()
+ assert len(directed) == 2 * len(sugar_table._coverage)
+ row = directed.set_index(["query_ccd_id", "target_ccd_id"])
+ assert row.loc[("GLC", "NAG"), "parity_coverage"] == inside
+ assert row.loc[("NAG", "GLC"), "parity_coverage"] == outside
+ # the symmetric score is the same in both directions
+ assert (
+ row.loc[("GLC", "NAG"), "parity_similarity"]
+ == row.loc[("NAG", "GLC"), "parity_similarity"]
+ == sugar_table.similarity("GLC", "NAG")
+ )
+ # a table from before the coverage columns still loads but cannot answer
+ legacy = CcdParityTable(
+ pd.DataFrame(
+ {
+ "ccd_id_1": ["GLC"],
+ "ccd_id_2": ["NAG"],
+ "parity_similarity": [50.0],
+ "fragment_atoms_1": [[["C1"]]],
+ "fragment_atoms_2": [[["C1"]]],
+ }
+ )
+ )
+ assert legacy.similarity("GLC", "NAG") == 0.5
+ with pytest.raises(ValueError, match="rebuild"):
+ legacy.coverage("GLC", "NAG")
+
+
+def test_composite_parity_reassembles_the_whole_molecule_score(atoms_2dty, sugar_table):
+ """Fragments joined through matched linkages give the exact atom-level score."""
+ from plinder.core.structure.smallmols_similarity import rascal_parity_score
+ from plinder.data.annotations.cif_utils import atoms_to_rdkit_mol
+
+ chain_e, chain_f = glycan(atoms_2dty, "E"), glycan(atoms_2dty, "F")
+ core = chain_e[chain_e.res_name != "FUC"] # NAG-NAG, the fucose branch removed
+ graphs = [residue_graph_from_atoms(a) for a in (chain_e, chain_f, core)]
+ mols = [atoms_to_rdkit_mol(a) for a in (chain_e, chain_f, core)]
+ exact = lambda i, j: rascal_parity_score(mols[i], mols[j], stereo=False) # noqa: E731
+ assert composite_parity(graphs[0], graphs[1], sugar_table) == exact(0, 1) == 1.0
+ assert composite_parity(graphs[0], graphs[2], sugar_table) == pytest.approx(
+ exact(0, 2)
+ )
+ assert composite_parity(graphs[2], graphs[0], sugar_table) == pytest.approx(
+ exact(0, 2)
+ )
+ assert 0.7 < exact(0, 2) < 0.75
+
+
+def test_composite_parity_scores_mono_against_composite(atoms_2dty, sugar_table):
+ """A one-residue graph is the mono case; the score tracks the unpruned engine."""
+ from plinder.core.structure.smallmols_similarity import rascal_parity_score
+ from plinder.data.annotations.cif_utils import atoms_to_rdkit_mol
+
+ chain_e = glycan(atoms_2dty, "E")
+ graph, whole = residue_graph_from_atoms(chain_e), atoms_to_rdkit_mol(chain_e)
+ free = lambda code: ResidueGraph((code,), (frozenset(),), (0,)) # noqa: E731
+ for code in ("NAG", "FUC", "GLC"):
+ assembled = composite_parity(free(code), graph, sugar_table)
+ exact = rascal_parity_score(
+ _ccd_named_mol(code), whole, target=0.0, stereo=False
+ )
+ assert composite_parity(graph, free(code), sugar_table) == assembled
+ # the engine may also carry the mono's leaving oxygen onto the linkage
+ assert 0 < assembled <= exact + 1e-9
+ assert assembled == pytest.approx(exact, abs=0.05)
+ assert composite_parity(free("NAG"), graph, sugar_table) > composite_parity(
+ free("GLC"), graph, sugar_table
+ )
+
+
+def _linked_chain(codes, *, donor="C1", acceptors=None, leaving="O1"):
+ """CCD residues linked donor(i) -> acceptor(i+1), each donor's leaving atom dropped."""
+ import biotite.structure as struc
+
+ from plinder.data.annotations.cif_utils import _get_ccd_atomarray
+
+ units = []
+ for index, code in enumerate(codes):
+ unit = _get_ccd_atomarray(code)
+ unit = unit[struc.filter_heavy(unit)]
+ if index < len(codes) - 1:
+ unit = unit[unit.atom_name != leaving]
+ unit.res_id[:] = index + 1
+ unit.chain_id[:] = "A"
+ units.append(unit)
+ atoms = struc.concatenate(units)
+ offsets = np.cumsum([0] + [len(unit) for unit in units[:-1]])
+ for index, acceptor in enumerate(acceptors or ["O4"] * (len(codes) - 1)):
+ first = offsets[index] + int(np.where(units[index].atom_name == donor)[0][0])
+ second = offsets[index + 1] + int(
+ np.where(units[index + 1].atom_name == acceptor)[0][0]
+ )
+ atoms.bonds.add_bond(first, second, struc.BondType.SINGLE)
+ return atoms
+
+
+def test_a_mono_spanning_several_residues_goes_through_the_whole_molecule_engine():
+ """Chitotriose (CTO, one code) against NAG-NAG-NAG built from CCD residues.
+
+ The table holds one fragment of CTO per NAG unit, but residues align
+ one-to-one, so the assembly credits a single unit. The routed score runs
+ the engine on the whole molecules and recovers the identity.
+ """
+ from plinder.core.structure.smallmols_similarity import rascal_parity_score
+ from plinder.data.annotations.cif_utils import atoms_to_rdkit_mol
+
+ chain = _linked_chain(["NAG", "NAG", "NAG"])
+ graph = residue_graph_from_atoms(chain)
+ assert graph.links == ((0, 1, "C1", "O4"), (1, 2, "C1", "O4"))
+ assert [len(names) for names in graph.atoms] == [14, 14, 15]
+ whole = atoms_to_rdkit_mol(chain, assign_stereo=False)
+ cto = _ccd_named_mol("CTO")
+ assert (whole.GetNumAtoms(), whole.GetNumBonds()) == (
+ cto.GetNumAtoms(),
+ cto.GetNumBonds(),
+ )
+ table = CcdParityTable.compute(["NAG", "CTO"])
+ assert len(table.mappings("CTO", "NAG")) == 3 # one fragment per unit
+ free = ResidueGraph(("CTO",), (frozenset(),), (0,))
+ assembled = composite_parity(free, graph, table)
+ assert 0.15 < assembled < 0.25 # one unit of three, on each side's union
+ exact = rascal_parity_score(cto, whole, stereo=False)
+ assert exact == 1.0
+ assert ligand_parity(free, graph, table, cto, whole) == exact
+ assert ligand_parity(graph, free, table, whole, cto) == exact
+ # two composites still assemble
+ assert ligand_parity(graph, graph, table, whole, whole) == composite_parity(
+ graph, graph, table
+ )
+
+
+def test_a_linkage_isomer_scores_high_but_not_identical():
+ """NAG-NAG-NAG with the last linkage beta1-6 against the beta1-4 chain and CTO.
+
+ The mono table maps NAG onto NAG as the identity, which cannot carry a
+ linkage that lands on another oxygen; rewiring the acceptor keeps the chain
+ connected at the cost of the two displaced hydroxyl bonds. The engine does
+ one better by swapping C4 with C6 along with their oxygens, losing a single
+ ring bond, so the assembly sits just below it.
+ """
+ from plinder.core.structure.smallmols_similarity import (
+ parity_similarity,
+ rascal_parity_score,
+ )
+ from plinder.data.annotations.cif_utils import atoms_to_rdkit_mol
+
+ regular = _linked_chain(["NAG", "NAG", "NAG"])
+ isomer = _linked_chain(["NAG", "NAG", "NAG"], acceptors=["O4", "O6"])
+ graphs = [residue_graph_from_atoms(a) for a in (regular, isomer)]
+ mols = [atoms_to_rdkit_mol(a, assign_stereo=False) for a in (regular, isomer)]
+ assert graphs[1].links == ((0, 1, "C1", "O4"), (1, 2, "C1", "O6"))
+ table = CcdParityTable.compute(["NAG", "CTO"])
+ # all 43 atoms stay one fragment; the engine matches 44 of 45 bonds, the
+ # rewired assembly 43 (two hydroxyl bonds displaced, one linkage gained)
+ exact = rascal_parity_score(mols[0], mols[1], stereo=False)
+ assert exact == pytest.approx(parity_similarity(43, 44, 86, 90))
+ assembled = composite_parity(graphs[0], graphs[1], table)
+ assert assembled == pytest.approx(parity_similarity(43, 43, 86, 90))
+ assert composite_parity(graphs[1], graphs[0], table) == assembled
+ assert 0.95 < assembled < exact < 1.0
+ free = ResidueGraph(("CTO",), (frozenset(),), (0,))
+ cto = _ccd_named_mol("CTO")
+ assert ligand_parity(free, graphs[0], table, cto, mols[0]) == 1.0
+ assert ligand_parity(free, graphs[1], table, cto, mols[1]) == pytest.approx(exact)
+
+
+def test_residue_graph_requires_a_bond_graph(atoms_2dty):
+ unbonded = glycan(atoms_2dty, "E").copy()
+ unbonded.bonds = None
+ with pytest.raises(ValueError, match="requires bonded atoms"):
+ residue_graph_from_atoms(unbonded)
+
+
+def test_disconnected_residues_are_flagged_not_scored_silently(atoms_2dty, monkeypatch):
+ """Two chains' glycans share no bond; that must not pass as one composite."""
+ warnings: list[str] = []
+ monkeypatch.setattr(LOG, "warning", lambda msg, *a: warnings.append(msg % a))
+ graph = residue_graph_from_atoms(glycan(atoms_2dty, "E", "F"))
+ assert not graph.is_connected
+ assert not graph.is_tree
+ assert any("disconnected" in message for message in warnings)
+
+
+def build_peptide(sequence: str, *, cyclic: bool):
+ """Residue graph and whole-molecule SMILES of an RDKit-built peptide."""
+ import io
+
+ import biotite.structure.io.pdb as pdb
+ from rdkit import Chem
+ from rdkit.Chem import rdDistGeom
+
+ mol = Chem.RWMol(Chem.MolFromSequence(sequence))
+ named = lambda atom, name: atom.GetPDBResidueInfo().GetName().strip() == name # noqa: E731
+ if cyclic:
+ n_term = next(
+ a.GetIdx()
+ for a in mol.GetAtoms()
+ if a.GetPDBResidueInfo().GetResidueNumber() == 1 and named(a, "N")
+ )
+ c_term = next(
+ a.GetIdx()
+ for a in mol.GetAtoms()
+ if a.GetPDBResidueInfo().GetResidueNumber() == len(sequence)
+ and named(a, "C")
+ )
+ for idx in sorted(
+ (a.GetIdx() for a in mol.GetAtoms() if named(a, "OXT")), reverse=True
+ ):
+ mol.RemoveAtom(idx)
+ mol.AddBond(n_term, c_term, Chem.BondType.SINGLE)
+ peptide = mol.GetMol()
+ Chem.SanitizeMol(peptide)
+ peptide = Chem.AddHs(peptide)
+ rdDistGeom.EmbedMolecule(peptide, randomSeed=0xF00D)
+ block = Chem.MolToPDBBlock(Chem.RemoveHs(peptide))
+ stripped = Chem.RemoveHs(peptide)
+ atoms = pdb.PDBFile.read(io.StringIO(block)).get_structure(
+ model=1, include_bonds=True
+ )
+ return residue_graph_from_atoms(atoms), Chem.MolToSmiles(stripped)
+
+
+def peptide_graph(sequence: str, *, cyclic: bool):
+ """Just the residue graph, for tests that do not need the molecule."""
+ return build_peptide(sequence, cyclic=cyclic)[0]
+
+
+@pytest.fixture(scope="module")
+def cyclic_peptide():
+ """Head-to-tail cyclo(Ala-Gly-Ser-Phe-Leu)."""
+ return peptide_graph("AGSFL", cyclic=True)
+
+
+def rotated(graph, shift):
+ """Same macrocycle, residue numbering rotated by *shift*."""
+ size = len(graph.labels)
+ position = {old: (old + shift) % size for old in range(size)}
+ order = sorted(range(size), key=lambda old: position[old])
+ return ResidueGraph(
+ tuple(graph.labels[old] for old in order),
+ tuple(frozenset(position[x] for x in graph.adjacency[old]) for old in order),
+ tuple(sorted(position[root] for root in graph.roots)),
+ tuple(frozenset(position[x] for x in graph.donors[old]) for old in order),
+ )
+
+
+def test_macrocycle_has_no_terminus_to_root_at(cyclic_peptide):
+ assert cyclic_peptide.labels == ("ALA", "GLY", "SER", "PHE", "LEU")
+ assert [len(bonded) for bonded in cyclic_peptide.adjacency] == [2] * 5
+ assert cyclic_peptide.is_connected and not cyclic_peptide.is_tree
+ # Every residue donates its carbonyl and accepts at its nitrogen, so none is
+ # a terminus and all are candidate roots.
+ assert cyclic_peptide.roots == (0, 1, 2, 3, 4)
+
+
+@pytest.mark.parametrize("shift", [0, 1, 2, 3, 4])
+def test_macrocycle_score_is_invariant_to_rotation(cyclic_peptide, shift):
+ """Rotating where the ring is numbered must not move the score."""
+ assert composite_similarity(cyclic_peptide, rotated(cyclic_peptide, shift)) == 1.0
+
+
+def test_macrocycle_is_distinguished_from_the_real_linear_peptide(cyclic_peptide):
+ """A ring and the open chain of the same residues are different molecules.
+
+ The spanning tree drops the ring-closing edge, so this separation rests
+ entirely on the two termini having one linkage where the ring has two.
+ """
+ linear = peptide_graph("AGSFL", cyclic=False)
+ assert linear.labels == cyclic_peptide.labels
+ assert [len(bonded) for bonded in linear.adjacency] == [1, 2, 2, 2, 1]
+ # Three internal residues match fully (degree 2 both); the two termini
+ # carry degree 1 against the ring's 2, weighted (1+1)/(1+2).
+ assert composite_similarity(cyclic_peptide, linear) == pytest.approx(13 / 15)
+
+
+@pytest.mark.parametrize(
+ "sequence, note",
+ [("AGSLF", "last two residues swapped"), ("ASGFL", "middle two swapped")],
+)
+def test_scrambled_macrocycle_matches_partially(cyclic_peptide, sequence, note):
+ """A different ring order over the same residues is neither same nor unrelated."""
+ assert sequence not in {"AGSFL"[shift:] + "AGSFL"[:shift] for shift in range(5)}, (
+ "the scramble must not be a rotation"
+ )
+ scrambled = peptide_graph(sequence, cyclic=True)
+ assert sorted(scrambled.labels) == sorted(cyclic_peptide.labels)
+ assert 0.0 < composite_similarity(cyclic_peptide, scrambled) < 1.0
+
+
+def test_ccd_node_similarity_grades_conservative_substitutions():
+ """Residue chemistry, not string equality: Tyr is Phe plus a hydroxyl."""
+ assert ccd_node_similarity("TYR", "TYR") == 1.0
+ assert (
+ ccd_node_similarity("TYR", "PHE")
+ > ccd_node_similarity("TYR", "TRP")
+ > ccd_node_similarity("TYR", "ALA")
+ )
+ # An underivable component must not invent similarity.
+ assert ccd_node_similarity("TYR", "ZZZZZ") == 0.0
+
+
+def test_graded_kernel_ranks_substitutions_within_the_same_topology():
+ """A-X-B vs A-Y-B: identical topology, so the node kernel decides."""
+ reference = peptide_graph("AYG", cyclic=False)
+ scores = {
+ substitution: composite_similarity(
+ reference,
+ peptide_graph(f"A{substitution}G", cyclic=False),
+ node_similarity=ccd_node_similarity,
+ )
+ for substitution in ("Y", "F", "W", "A")
+ }
+ assert scores["Y"] == 1.0
+ assert scores["F"] > scores["W"] > scores["A"]
+ # Exact matching cannot see any of this: all three are one mismatch of three.
+ assert all(
+ composite_similarity(reference, peptide_graph(f"A{s}G", cyclic=False))
+ == pytest.approx(1 / 3 * 2)
+ for s in ("F", "W", "A")
+ )
+
+
+def test_single_residue_ligand_still_scores_against_a_composite(cyclic_peptide):
+ """A free residue must not be unmatchable against composites containing it.
+
+ The linkage weighting compares degrees, and a free residue has degree 0. An
+ unsmoothed ratio makes that pair impossible rather than merely poor, zeroing
+ every mono-vs-multi comparison - worse than the whole-molecule fingerprint
+ this is meant to improve on.
+ """
+ free = lambda code: ResidueGraph((code,), (frozenset(),), (0,)) # noqa: E731
+
+ present = composite_similarity(free("PHE"), cyclic_peptide)
+ absent = composite_similarity(free("TRP"), cyclic_peptide)
+ assert present > 0.0
+ # PHE is one of the five ring residues; TRP is not.
+ assert present > absent
+ # Scaled by how much of the composite one residue can account for.
+ assert present == pytest.approx(1 / 3 / 5)
+ assert composite_similarity(free("PHE"), free("PHE")) == 1.0
+
+
+def test_residue_features_are_invariant_to_numbering_but_see_topology(cyclic_peptide):
+ """Relabelling must not change features; a different ring order must."""
+ assert residue_graph_features(cyclic_peptide) == residue_graph_features(
+ rotated(cyclic_peptide, 3)
+ )
+ assert residue_graph_features(cyclic_peptide) != residue_graph_features(
+ peptide_graph("AGSLF", cyclic=True)
+ )
+
+
+@pytest.mark.parametrize(
+ "single, parts",
+ [("LAT", ("GAL", "BGC")), ("SUC", ("GLC", "FRU"))],
+ ids=["lactose", "sucrose"],
+)
+def test_same_molecule_survives_a_different_decomposition(single, parts):
+ """One CCD code or several linked ones can denote the same molecule.
+
+ Heavy atoms confirm the identity: a glycosidic bond loses one oxygen, so
+ the single code carries the components' atoms minus one.
+ """
+ from rdkit import Chem
+
+ heavy = lambda code: Chem.MolFromSmiles(_ccd_smiles(code)).GetNumHeavyAtoms() # noqa: E731
+ assert heavy(single) == sum(heavy(part) for part in parts) - 1
+
+ smiles = _ccd_smiles(single)
+ as_one = ResidueGraph((single,), (frozenset(),), (0,))
+ as_several = ccd_code_residue_graph("-".join(parts))
+
+ # Residue labels share nothing across the regrouping.
+ assert composite_similarity(as_one, as_several) == 0.0
+ # Sharing one feature space does not privilege either decomposition.
+ combined = ligand_similarity(
+ ligand_features(smiles, as_one), ligand_features(smiles, as_several)
+ )
+ assert combined > 0.7
+
+
+def test_ligand_similarity_separates_what_fingerprints_alone_cannot(cyclic_peptide):
+ """The scramble ECFP4 cannot see, still separated once residues count."""
+ features = lambda seq: ligand_features( # noqa: E731
+ *reversed(build_peptide(seq, cyclic=True))
+ )
+ reference, identical, scrambled = (
+ features("AGSFL"),
+ features("AGSFL"),
+ features("AGSLF"),
+ )
+
+ assert ligand_similarity(reference, identical) == 1.0
+ assert ligand_similarity(reference, scrambled) < 1.0
+ assert ligand_similarity(reference, Counter()) == 0.0
+
+
+def test_residue_counts_separate_a_repeat_from_its_unit():
+ """Presence-only features cannot see multiplicity; counted ones can.
+
+ A pentapeptide and a head-to-tail decapeptide of the same residues have the
+ identical set of circular environments and the identical set of residue
+ labels, so every presence-only comparison scores them 1.000.
+ """
+ short_graph, short_smiles = build_peptide("AGSFL", cyclic=True)
+ long_graph, long_smiles = build_peptide("AGSFLAGSFL", cyclic=True)
+ assert len(long_graph.labels) == 2 * len(short_graph.labels)
+
+ short, long = (
+ ligand_features(short_smiles, short_graph),
+ ligand_features(long_smiles, long_graph),
+ )
+ # Same feature *keys* either way - only the counts differ.
+ assert set(short) == set(long)
+ assert ligand_similarity(short, long) < 1.0
+
+ presence_only = Counter(dict.fromkeys(short, 1)), Counter(dict.fromkeys(long, 1))
+ assert ligand_similarity(*presence_only) == 1.0
diff --git a/tests/data/test_chain_modifications.py b/tests/data/test_chain_modifications.py
new file mode 100644
index 000000000..a2f49d73a
--- /dev/null
+++ b/tests/data/test_chain_modifications.py
@@ -0,0 +1,48 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from __future__ import annotations
+
+import pyarrow as pa
+
+from plinder.data.annotations.aggregate_annotations import Entry
+from plinder.data.annotations.cif_utils import read_mmcif_file
+from plinder.data.annotations.protein_utils import get_modified_residues
+from plinder.data.pipeline.collate import ENTRY_CHAIN_SCHEMA
+
+CIF_6M92 = "xx/pdb_00006m92/pdb_00006m92_xyz-enrich.cif.gz"
+
+
+def test_modified_residues_come_from_seqres_with_deposited_parent(test_dir):
+ block = list(read_mmcif_file(test_dir / CIF_6M92).values())[0]
+
+ assert get_modified_residues(block) == {"C": ["33:SEP:C:18>SER (modified residue)"]}
+
+
+def test_modified_residues_fall_back_to_the_ccd_parent(test_dir):
+ block = list(read_mmcif_file(test_dir / CIF_6M92).values())[0]
+ assert "pdbx_struct_mod_residue" in block
+ del block["pdbx_struct_mod_residue"]
+
+ assert get_modified_residues(block) == {"C": ["33:SEP:C:18>SER"]}
+
+
+def test_entry_chain_table_carries_modifications_and_noncanonical_sequence(test_dir):
+ entry = Entry.from_cif_file(test_dir / CIF_6M92, include_interfaces=False)
+
+ assert entry.chains["C"].modified_residues == ["33:SEP:C:18>SER (modified residue)"]
+ assert entry.chains["A"].modified_residues == []
+ assert entry.chain_to_seqres["C"][17] == "S"
+ assert "(SEP)" in entry.chain_to_seqres_noncanonical["C"]
+ assert "(" not in entry.chain_to_seqres_noncanonical["A"]
+
+ frame = entry.chains_to_df()
+ table = pa.Table.from_pandas(frame, schema=ENTRY_CHAIN_SCHEMA, preserve_index=False)
+ rows = {row["chain_asym_id"]: row for row in table.to_pylist()}
+ assert rows["C"]["chain_modified_residues"] == [
+ "33:SEP:C:18>SER (modified residue)"
+ ]
+ assert (
+ rows["C"]["chain_sequence_noncanonical"]
+ == entry.chain_to_seqres_noncanonical["C"]
+ )
+ assert rows["A"]["chain_modified_residues"] == []
diff --git a/tests/data/test_clusters.py b/tests/data/test_clusters.py
index 5892462be..71d8c0276 100644
--- a/tests/data/test_clusters.py
+++ b/tests/data/test_clusters.py
@@ -1,11 +1,1963 @@
-def test_make_components_and_communities(write_plinder_mount):
- from plinder.data.clusters import make_components_and_communities
+import json
+from os import utime
+from pathlib import Path
- i = len(list((write_plinder_mount / "clusters").rglob("*")))
- make_components_and_communities(
- data_dir=write_plinder_mount,
- metric="pocket_lddt",
+import networkit as nk
+import numpy as np
+import pandas as pd
+import pytest
+
+
+def test_slurm_zero_memory_does_not_limit_duckdb(monkeypatch):
+ from plinder.data.clusters import _set_slurm_memory_limit
+
+ calls = []
+
+ class Connection:
+ def execute(self, query, values):
+ calls.append((query, values))
+
+ monkeypatch.setenv("SLURM_MEM_PER_NODE", "0")
+ _set_slurm_memory_limit(Connection(), 3)
+ assert calls == []
+
+ monkeypatch.setenv("SLURM_MEM_PER_NODE", "1000")
+ _set_slurm_memory_limit(Connection(), 4)
+ assert calls == [("SET memory_limit = ?", ["800MB"])]
+
+
+def _component_partition(labels: pd.DataFrame) -> set[frozenset[str]]:
+ return {
+ frozenset(group["ligand_id"].astype(str))
+ for _, group in labels.groupby("label")
+ }
+
+
+def _write_interface_cluster_universe(
+ index_dir: Path, interface_ids: list[str]
+) -> None:
+ """Write identity representative metadata for focused cluster tests."""
+ pd.DataFrame({"representative_system_id": interface_ids}).to_parquet(
+ index_dir / "interface_representatives.parquet", index=False
+ )
+ half_ids = [
+ f"{system_id}::side={side}" for system_id in interface_ids for side in (1, 2)
+ ]
+ pd.DataFrame({"half_interface_id": half_ids}).to_parquet(
+ index_dir / "interface_half_representatives.parquet", index=False
+ )
+ pd.DataFrame(
+ {
+ "system_id": interface_ids,
+ "representative_system_id": interface_ids,
+ "side_1_half_interface_id": [
+ f"{system_id}::side=1" for system_id in interface_ids
+ ],
+ "side_2_half_interface_id": [
+ f"{system_id}::side=2" for system_id in interface_ids
+ ],
+ }
+ ).to_parquet(index_dir / "interface_membership.parquet", index=False)
+
+
+def test_exact_threshold_components_preserve_bridge_edges_across_shards():
+ from plinder.data.clusters import (
+ count_crossing_component_edges,
+ make_exact_threshold_components,
+ )
+
+ # A is a deliberately bad representative for the 100% component {A, B}:
+ # A-C is below 70, but B-C is a qualifying bridge that must not be lost.
+ shards = [
+ pd.DataFrame(
+ {
+ "query_node": ["A", "A", "D"],
+ "target_node": ["B", "C", "E"],
+ "similarity": [100, 60, 95],
+ }
+ ),
+ pd.DataFrame(
+ {
+ "query_node": ["B", "C", "E"],
+ "target_node": ["C", "D", "F"],
+ "similarity": [70, 50, 30],
+ }
+ ),
+ ]
+ labels = make_exact_threshold_components(
+ edge_batches=shards,
+ all_nodes=["A", "B", "C", "D", "E", "F", "G"],
+ thresholds=[30, 50, 70, 90, 100],
+ forest_fan_in=2,
+ )
+
+ assert _component_partition(labels[100]) == {
+ frozenset({"A", "B"}),
+ frozenset({"C"}),
+ frozenset({"D"}),
+ frozenset({"E"}),
+ frozenset({"F"}),
+ frozenset({"G"}),
+ }
+ assert frozenset({"A", "B", "C"}) in _component_partition(labels[70])
+ assert frozenset({"A", "B", "C", "D", "E"}) in _component_partition(labels[50])
+ assert _component_partition(labels[30]) == {
+ frozenset({"A", "B", "C", "D", "E", "F"}),
+ frozenset({"G"}),
+ }
+ assert count_crossing_component_edges(
+ edge_batches=shards,
+ labels_by_threshold=labels,
+ ) == {100: 0, 90: 0, 70: 0, 50: 0, 30: 0}
+
+
+def test_exact_threshold_components_match_full_graph_and_are_order_independent():
+ from plinder.data.clusters import make_exact_threshold_components
+
+ shards = [
+ pd.DataFrame(
+ {
+ "query_node": ["A", "B", "C", "D"],
+ "target_node": ["B", "C", "A", "E"],
+ "similarity": [95, 70, 50, 30],
+ }
+ ),
+ pd.DataFrame(
+ {
+ "query_node": ["E", "F", "G", "A"],
+ "target_node": ["F", "G", "D", "A"],
+ "similarity": [100, 50, 29, 100],
+ }
+ ),
+ ]
+ nodes = list("ABCDEFGH")
+ thresholds = [100, 90, 70, 50, 30]
+ forward = make_exact_threshold_components(
+ edge_batches=shards,
+ all_nodes=nodes,
+ thresholds=thresholds,
+ forest_fan_in=2,
+ )
+ reverse = make_exact_threshold_components(
+ edge_batches=reversed(shards),
+ all_nodes=reversed(nodes),
+ thresholds=reversed(thresholds),
+ forest_fan_in=2,
+ )
+
+ for threshold in thresholds:
+ qualifying = pd.concat(shards, ignore_index=True)
+ qualifying = qualifying[qualifying["similarity"] >= threshold]
+ expected = {frozenset({node}) for node in nodes}
+ if not qualifying.empty:
+ # A tiny independent union implementation is clearer than relying on
+ # the production forest reducer to construct the expected partition.
+ groups = {node: {node} for node in nodes}
+ for edge in qualifying.itertuples(index=False):
+ merged = groups[str(edge.query_node)] | groups[str(edge.target_node)]
+ for node in merged:
+ groups[node] = merged
+ expected = {frozenset(group) for group in groups.values()}
+ assert _component_partition(forward[threshold]) == expected
+ assert forward[threshold].equals(reverse[threshold])
+
+
+def test_crossing_component_edge_validation_detects_split():
+ from plinder.data.clusters import count_crossing_component_edges
+
+ edges = pd.DataFrame(
+ {
+ "query_node": ["A", "B"],
+ "target_node": ["B", "C"],
+ "similarity": [80, 40],
+ }
+ )
+ labels = {
+ 50: pd.DataFrame({"ligand_id": ["A", "B", "C"], "label": ["c0", "c1", "c2"]}),
+ 30: pd.DataFrame({"ligand_id": ["A", "B", "C"], "label": ["c0", "c0", "c1"]}),
+ }
+
+ assert count_crossing_component_edges(
+ edge_batches=[edges],
+ labels_by_threshold=labels,
+ ) == {50: 1, 30: 1}
+
+
+def test_exact_strong_components_preserve_cross_shard_directional_cycle():
+ from plinder.data.clusters import make_exact_threshold_components
+
+ shards = [
+ pd.DataFrame(
+ {
+ "query_node": ["A", "D"],
+ "target_node": ["B", "A"],
+ "similarity": [90, 90],
+ }
+ ),
+ pd.DataFrame(
+ {
+ "query_node": ["B"],
+ "target_node": ["C"],
+ "similarity": [70],
+ }
+ ),
+ pd.DataFrame(
+ {
+ "query_node": ["C"],
+ "target_node": ["A"],
+ "similarity": [50],
+ }
+ ),
+ ]
+ labels = make_exact_threshold_components(
+ edge_batches=shards,
+ all_nodes=["A", "B", "C", "D"],
+ thresholds=[50, 70, 90],
+ forest_fan_in=2,
+ directed=True,
+ )
+
+ assert _component_partition(labels[90]) == {
+ frozenset({"A"}),
+ frozenset({"B"}),
+ frozenset({"C"}),
+ frozenset({"D"}),
+ }
+ assert _component_partition(labels[70]) == _component_partition(labels[90])
+ assert _component_partition(labels[50]) == {
+ frozenset({"A", "B", "C"}),
+ frozenset({"D"}),
+ }
+
+
+def test_weak_and_strong_components_share_one_input_scan():
+ from plinder.data.clusters import (
+ make_exact_weak_and_strong_threshold_components,
+ )
+
+ iterations = 0
+
+ def batches():
+ nonlocal iterations
+ iterations += 1
+ if iterations > 1:
+ raise AssertionError("edge batches were scanned more than once")
+ yield pd.DataFrame(
+ {
+ "query_node": ["A", "B"],
+ "target_node": ["B", "A"],
+ "similarity": [70, 50],
+ }
+ )
+
+ labels = make_exact_weak_and_strong_threshold_components(
+ edge_batches=batches(),
+ all_nodes=["A", "B", "C"],
+ thresholds=[50, 70],
+ forest_fan_in=2,
+ )
+
+ assert iterations == 1
+ assert frozenset({"A", "B"}) in _component_partition(labels[False][70])
+ assert _component_partition(labels[True][70]) == {
+ frozenset({"A"}),
+ frozenset({"B"}),
+ frozenset({"C"}),
+ }
+ assert frozenset({"A", "B"}) in _component_partition(labels[True][50])
+
+
+def test_component_reduction_shards_are_resumable_and_merge_exactly(tmp_path):
+ from plinder.data.clusters import (
+ make_exact_threshold_components,
+ merge_component_reduction_shards,
+ write_component_reduction_shard,
+ )
+
+ nodes = list("ABCDE")
+ thresholds = [50, 70, 100]
+ shards = [
+ pd.DataFrame(
+ {
+ "query_node": ["A", "B", "C"],
+ "target_node": ["B", "C", "A"],
+ "similarity": [100, 70, 50],
+ }
+ ),
+ pd.DataFrame(
+ {
+ "query_node": ["D", "E", "C"],
+ "target_node": ["E", "D", "D"],
+ "similarity": [70, 50, 50],
+ }
+ ),
+ ]
+ reduction_dirs = []
+ for shard_index, shard in enumerate(shards):
+ source = tmp_path / f"source-{shard_index}.parquet"
+ shard.to_parquet(source, index=False)
+ reduction_dir = tmp_path / "reductions" / str(shard_index)
+ write_component_reduction_shard(
+ edge_batches=[shard],
+ all_nodes=nodes,
+ thresholds=thresholds,
+ source_path=source,
+ output_dir=reduction_dir,
+ forest_fan_in=2,
+ )
+ reduction_dirs.append(reduction_dir)
+
+ merged = merge_component_reduction_shards(
+ reduction_dirs=reduction_dirs,
+ all_nodes=nodes,
+ thresholds=thresholds,
+ forest_fan_in=2,
+ parquet_batch_size=2,
+ )
+ direct = make_exact_threshold_components(
+ edge_batches=shards,
+ all_nodes=nodes,
+ thresholds=thresholds,
+ forest_fan_in=2,
+ )
+ for threshold in thresholds:
+ assert merged[False][threshold].equals(direct[threshold])
+
+ def should_not_be_read():
+ raise AssertionError("completed reduction unexpectedly rescanned its source")
+ yield pd.DataFrame()
+
+ cached = write_component_reduction_shard(
+ edge_batches=should_not_be_read(),
+ all_nodes=nodes,
+ thresholds=thresholds,
+ source_path=tmp_path / "source-0.parquet",
+ output_dir=reduction_dirs[0],
+ forest_fan_in=2,
+ )
+ assert cached["status"] == "complete"
+
+
+def test_component_score_batches_read_reciprocal_minimum_edges(tmp_path):
+ from plinder.data.clusters import iter_component_score_batches
+
+ source = tmp_path / "symmetric.parquet"
+ pd.DataFrame(
+ {
+ "query_node": ["l1", "l2"],
+ "target_node": ["l2", "l3"],
+ "similarity": [70.0, 95.0],
+ }
+ ).to_parquet(source, index=False)
+
+ result = pd.concat(
+ iter_component_score_batches(
+ source_path=source,
+ metric="sucos_shape_pocket_qcov",
+ batch_size=1,
+ ),
+ ignore_index=True,
+ )
+
+ assert result.to_dict("records") == [
+ {"query_node": "l1", "target_node": "l2", "similarity": 70.0},
+ {"query_node": "l2", "target_node": "l3", "similarity": 95.0},
+ ]
+
+
+@pytest.mark.parametrize("compact", [False, True])
+def test_symmetric_edge_shards_take_minimum_of_directional_maxima(tmp_path, compact):
+ from plinder.data.clusters import (
+ make_directed_cover_component_reduction,
+ make_directed_set_cover,
+ merge_directed_cover_component_reductions,
+ prepare_symmetric_edge_plan,
+ write_symmetric_edge_fragment_batch,
+ write_symmetric_edge_shard,
+ )
+
+ metric = "sucos_shape_pocket_qcov"
+ index_dir = tmp_path / "index"
+ score_dir = (
+ tmp_path / "exports" / "ligand_similarity_scores"
+ if compact
+ else tmp_path / "scores" / "search_db=holo"
+ )
+ index_dir.mkdir(parents=True)
+ score_dir.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "system_id": ["s1", "s2", "s3", "s4"],
+ "ligand_id": ["l1", "l2", "l3", "l4"],
+ "system_type": ["holo"] * 4,
+ "ligand_is_proper": [True] * 4,
+ "system_proper_num_pocket_residues": [200, 20, 200, 20],
+ "system_proper_num_interactions": [1, 10, 1, 10],
+ "system_proper_ligand_max_molecular_weight": [100, 300, 100, 300],
+ "system_pass_validation_criteria": [True, False, True, False],
+ }
+ ).to_parquet(index_dir / "annotation_table.parquet", index=False)
+ scores = pd.DataFrame(
+ {
+ "query_system": ["s1", "s1", "s2", "s1", "s4"],
+ "query_ligand_id": ["l1", "l1", "l2", "l1", "l4"],
+ "target_system": ["s2", "s2", "s1", "s3", "s3"],
+ "target_ligand_id": ["l2", "l2", "l1", "l3", "l3"],
+ "metric": [metric] * 5,
+ "similarity": [80, 75, 60, 90, 85],
+ }
+ )
+ if compact:
+ scores = scores.drop(columns="metric").rename(
+ columns={"similarity": "sucos_shape"}
+ )
+ scores["pocket_qcov"] = 100
+ scores.to_parquet(score_dir / "part.parquet", index=False)
+ plan = prepare_symmetric_edge_plan(
+ data_dir=tmp_path,
+ metrics=[metric],
+ source_batch_size=1,
+ bucket_count=1,
+ )
+ write_symmetric_edge_fragment_batch(
+ data_dir=tmp_path,
+ batch=plan["batches"][0],
+ scratch_dir=tmp_path / "scratch-fragments",
+ threads=1,
+ )
+ result = write_symmetric_edge_shard(
+ data_dir=tmp_path,
+ metric=metric,
+ bucket=0,
+ scratch_dir=tmp_path / "scratch-shard",
+ threads=1,
+ )
+
+ assert result["rows"] == 3
+ edges = pd.read_parquet(
+ tmp_path
+ / "ligand_clusters/symmetric_edges"
+ / f"metric={metric}/bucket=000.parquet"
+ ).set_index(["query_node", "target_node"])
+ assert edges.loc[("l1", "l2"), "forward_similarity"] == pytest.approx(80.0)
+ assert edges.loc[("l1", "l2"), "reverse_similarity"] == pytest.approx(60.0)
+ assert edges.loc[("l1", "l2"), "similarity"] == pytest.approx(60.0)
+ assert edges.loc[("l1", "l2"), "maximum_similarity"] == pytest.approx(80.0)
+ assert edges.loc[("l1", "l3"), "forward_similarity"] == pytest.approx(90.0)
+ assert pd.isna(edges.loc[("l1", "l3"), "reverse_similarity"])
+ assert pd.isna(edges.loc[("l1", "l3"), "similarity"])
+ assert edges.loc[("l1", "l3"), "maximum_similarity"] == pytest.approx(90.0)
+ assert edges.loc[("l3", "l4"), "reverse_similarity"] == pytest.approx(85.0)
+ assert pd.isna(edges.loc[("l3", "l4"), "forward_similarity"])
+ assert pd.isna(edges.loc[("l3", "l4"), "similarity"])
+
+ edge_path = (
+ tmp_path
+ / "ligand_clusters/symmetric_edges"
+ / f"metric={metric}/bucket=000.parquet"
+ )
+ make_directed_cover_component_reduction(
+ data_dir=tmp_path,
+ metric=metric,
+ thresholds=[90],
+ source_path=edge_path,
+ )
+ merge_directed_cover_component_reductions(
+ data_dir=tmp_path,
+ metric=metric,
+ thresholds=[90],
+ )
+ cover_path = make_directed_set_cover(
+ data_dir=tmp_path,
+ metric=metric,
threshold=50,
+ scratch_dir=tmp_path / "scratch-cover",
+ threads=1,
+ )
+ cover = pd.read_parquet(cover_path).set_index("ligand_id")
+ assert cover.loc["l1", "centroid_ligand_id"] == "l1"
+ assert cover.loc["l1", "similarity_to_centroid"] == pytest.approx(100.0)
+ assert cover.loc["l1", "coverage_count"] == 2
+ assert cover.loc["l1", "coverage_fraction"] == pytest.approx(0.5)
+ assert cover.loc["l2", "centroid_ligand_id"] == "l1"
+ assert cover.loc["l3", "centroid_ligand_id"] == "l3"
+ assert cover.loc["l3", "coverage_count"] == 3
+ assert cover.loc["l3", "coverage_fraction"] == pytest.approx(0.75)
+ assert cover.loc["l4", "centroid_ligand_id"] == "l3"
+ assert cover.loc["l4", "similarity_to_centroid"] == pytest.approx(85.0)
+ assert (
+ cover.loc["l3", "representative_selection_order"]
+ < cover.loc["l1", "representative_selection_order"]
+ )
+
+ relaxed_cover_path = make_directed_set_cover(
+ data_dir=tmp_path,
+ metric=metric,
+ threshold=90,
+ scratch_dir=tmp_path / "scratch-relaxed-cover",
+ threads=1,
+ )
+ relaxed_cover = pd.read_parquet(relaxed_cover_path).set_index("ligand_id")
+ assert relaxed_cover.loc["l4", "centroid_ligand_id"] == "l3"
+ assert relaxed_cover.loc["l4", "similarity_to_centroid"] == pytest.approx(85.0)
+ assert relaxed_cover.loc["l4", "assignment_threshold"] == 50
+ assert relaxed_cover.loc["l3", "representative_selection_threshold"] == 90
+ assert relaxed_cover.loc["l1", "representative_selection_threshold"] == 50
+
+
+def test_interface_clusters_use_directed_cover_pipeline(tmp_path):
+ from plinder.data.clusters import (
+ make_directed_cover_component_reduction,
+ make_directed_set_covers,
+ merge_directed_cover_component_reductions,
+ prepare_component_node_universe,
+ prepare_symmetric_edge_plan,
+ write_symmetric_edge_fragment_batch,
+ write_symmetric_edge_shard,
+ )
+
+ metric = "interface_qcov"
+ interfaces = ["i1", "i2", "i3", "i4"]
+ index_dir = tmp_path / "index"
+ score_dir = tmp_path / "interface_scores"
+ index_dir.mkdir()
+ score_dir.mkdir()
+ pd.DataFrame({"system_id": interfaces}).to_parquet(
+ index_dir / "interface_annotation_table.parquet",
+ index=False,
+ )
+ _write_interface_cluster_universe(index_dir, interfaces)
+ pd.DataFrame(
+ {
+ "query_system": ["i1", "i2", "i1", "i4"],
+ "target_system": ["i2", "i1", "i3", "i3"],
+ "metric": [metric] * 4,
+ "similarity": [80, 60, 90, 85],
+ }
+ ).to_parquet(score_dir / "shard=ab.parquet", index=False)
+
+ prepare_component_node_universe(tmp_path, entity_type="interface")
+ plan = prepare_symmetric_edge_plan(
+ data_dir=tmp_path,
+ metrics=[metric],
+ source_batch_size=1,
+ bucket_count=1,
+ entity_type="interface",
+ )
+ write_symmetric_edge_fragment_batch(
+ data_dir=tmp_path,
+ batch=plan["batches"][0],
+ scratch_dir=tmp_path / "scratch-fragments",
+ threads=1,
+ entity_type="interface",
+ )
+ write_symmetric_edge_shard(
+ data_dir=tmp_path,
+ metric=metric,
+ bucket=0,
+ scratch_dir=tmp_path / "scratch-shard",
+ threads=1,
+ entity_type="interface",
+ )
+ edge_path = (
+ tmp_path
+ / "interface_clusters/symmetric_edges"
+ / f"metric={metric}/bucket=000.parquet"
+ )
+ edges = pd.read_parquet(edge_path).set_index(["query_node", "target_node"])
+ assert edges.loc[("i1", "i2"), "similarity"] == pytest.approx(60.0)
+ assert pd.isna(edges.loc[("i1", "i3"), "similarity"])
+ assert edges.loc[("i1", "i3"), "maximum_similarity"] == pytest.approx(90.0)
+
+ make_directed_cover_component_reduction(
+ data_dir=tmp_path,
+ metric=metric,
+ thresholds=[30, 50],
+ source_path=edge_path,
+ entity_type="interface",
+ )
+ merge_directed_cover_component_reductions(
+ data_dir=tmp_path,
+ metric=metric,
+ thresholds=[30, 50],
+ entity_type="interface",
+ )
+ cover_paths = make_directed_set_covers(
+ data_dir=tmp_path,
+ metric=metric,
+ thresholds=[90, 50, 30],
+ scratch_dir=tmp_path / "scratch-cover",
+ threads=3,
+ entity_type="interface",
+ )
+
+ assert [path.name for path in cover_paths] == [
+ "threshold=90.parquet",
+ "threshold=50.parquet",
+ "threshold=30.parquet",
+ ]
+ cover = pd.read_parquet(cover_paths[1]).set_index("system_id")
+ assert cover.loc["i1", "centroid_system_id"] == "i1"
+ assert cover.loc["i2", "centroid_system_id"] == "i1"
+ assert cover.loc["i2", "similarity_to_centroid"] == pytest.approx(60.0)
+ assert cover.loc["i4", "centroid_system_id"] == "i3"
+
+ from plinder.data.pipeline.score import summarize_clustering_artifacts
+
+ summary = summarize_clustering_artifacts(
+ tmp_path,
+ metrics=[metric],
+ thresholds=[90, 50, 30],
+ entity_type="interface",
+ )
+ assert summary["entity_type"] == "interface"
+ assert summary["artifact_count"] == 3
+
+
+def test_interface_node_universe_contains_only_scoring_representatives(tmp_path):
+ from plinder.data.clusters import (
+ component_node_universe,
+ prepare_component_node_universe,
+ )
+
+ index_dir = tmp_path / "index"
+ index_dir.mkdir()
+ pd.DataFrame({"system_id": ["i1", "i2"]}).to_parquet(
+ index_dir / "interface_annotation_table.parquet", index=False
+ )
+ pd.DataFrame({"representative_system_id": ["i1"]}).to_parquet(
+ index_dir / "interface_representatives.parquet", index=False
+ )
+ half_ids = ["i1::side=1", "i1::side=2"]
+ pd.DataFrame({"half_interface_id": half_ids}).to_parquet(
+ index_dir / "interface_half_representatives.parquet", index=False
+ )
+ pd.DataFrame(
+ {
+ "system_id": ["i1", "i2"],
+ "representative_system_id": ["i1", "i1"],
+ "side_1_half_interface_id": [half_ids[0], half_ids[0]],
+ "side_2_half_interface_id": [half_ids[1], half_ids[1]],
+ }
+ ).to_parquet(index_dir / "interface_membership.parquet", index=False)
+
+ report = prepare_component_node_universe(tmp_path, entity_type="interface")
+
+ assert report["interface_count"] == 1
+ assert report["interface_side_count"] == 2
+ assert component_node_universe(
+ data_dir=tmp_path,
+ metric="interface_qcov",
+ entity_type="interface",
+ )[0] == ["i1"]
+ assert (
+ component_node_universe(
+ data_dir=tmp_path,
+ metric="interface_side_qcov",
+ entity_type="interface",
+ )[0]
+ == half_ids
+ )
+
+
+def test_interface_side_clusters_use_independent_side_nodes(tmp_path):
+ from plinder.data.clusters import (
+ component_node_universe,
+ prepare_component_node_universe,
+ prepare_symmetric_edge_plan,
+ write_symmetric_edge_fragment_batch,
+ write_symmetric_edge_shard,
+ )
+
+ index_dir = tmp_path / "index"
+ score_dir = tmp_path / "interface_scores"
+ index_dir.mkdir()
+ score_dir.mkdir()
+ pd.DataFrame({"system_id": ["i1", "i2"]}).to_parquet(
+ index_dir / "interface_annotation_table.parquet",
+ index=False,
+ )
+ _write_interface_cluster_universe(index_dir, ["i1", "i2"])
+ pd.DataFrame(
+ {
+ "query_system": ["i1::side=1", "i2::side=2"],
+ "target_system": ["i2::side=2", "i1::side=1"],
+ "metric": ["interface_side_qcov"] * 2,
+ "similarity": [80, 60],
+ }
+ ).to_parquet(score_dir / "shard=ab.parquet", index=False)
+
+ prepare_component_node_universe(tmp_path, entity_type="interface")
+ nodes, _ = component_node_universe(
+ data_dir=tmp_path,
+ metric="interface_side_qcov",
+ entity_type="interface",
+ )
+ assert nodes == [
+ "i1::side=1",
+ "i1::side=2",
+ "i2::side=1",
+ "i2::side=2",
+ ]
+ plan = prepare_symmetric_edge_plan(
+ data_dir=tmp_path,
+ metrics=["interface_side_qcov"],
+ source_batch_size=1,
+ bucket_count=1,
+ entity_type="interface",
+ )
+ write_symmetric_edge_fragment_batch(
+ data_dir=tmp_path,
+ batch=plan["batches"][0],
+ scratch_dir=tmp_path / "scratch-fragments",
+ threads=1,
+ entity_type="interface",
+ )
+ write_symmetric_edge_shard(
+ data_dir=tmp_path,
+ metric="interface_side_qcov",
+ bucket=0,
+ scratch_dir=tmp_path / "scratch-shard",
+ threads=1,
+ entity_type="interface",
+ )
+ edges = pd.read_parquet(
+ tmp_path
+ / "interface_clusters/symmetric_edges/metric=interface_side_qcov"
+ / "bucket=000.parquet"
+ ).set_index(["query_node", "target_node"])
+ assert edges.loc[("i1::side=1", "i2::side=2"), "similarity"] == pytest.approx(60.0)
+
+
+def test_interface_clusters_prefer_compact_similarity_tables(tmp_path):
+ from plinder.data.clusters import (
+ prepare_component_node_universe,
+ prepare_symmetric_edge_plan,
+ write_symmetric_edge_fragment_batch,
+ write_symmetric_edge_shard,
+ )
+
+ index_dir = tmp_path / "index"
+ index_dir.mkdir()
+ pd.DataFrame({"system_id": ["i1", "i2"]}).to_parquet(
+ index_dir / "interface_annotation_table.parquet", index=False
+ )
+ _write_interface_cluster_universe(index_dir, ["i1", "i2"])
+ raw_dir = tmp_path / "interface_scores"
+ raw_dir.mkdir()
+ pd.DataFrame(
+ {
+ "query_system": ["i1"],
+ "target_system": ["i2"],
+ "metric": ["interface_qcov"],
+ "similarity": [5],
+ }
+ ).to_parquet(raw_dir / "shard=ab.parquet", index=False)
+ exports = tmp_path / "exports"
+ exports.mkdir()
+ pd.DataFrame(
+ {
+ "query_system": ["i1", "i1", "i2"],
+ "target_system": ["i2", "i2", "i1"],
+ "similarity": [80, 75, 60],
+ }
+ ).to_parquet(exports / "interface_similarity_scores.parquet", index=False)
+ pd.DataFrame(
+ {
+ "query_half_interface_id": ["i1::side=1", "i2::side=2"],
+ "target_half_interface_id": ["i2::side=2", "i1::side=1"],
+ "similarity": [90, 70],
+ }
+ ).to_parquet(exports / "interface_half_similarity_scores.parquet", index=False)
+
+ prepare_component_node_universe(tmp_path, entity_type="interface")
+ plan = prepare_symmetric_edge_plan(
+ data_dir=tmp_path,
+ metrics=["interface_qcov", "interface_side_qcov"],
+ source_batch_size=1,
+ bucket_count=1,
+ entity_type="interface",
+ )
+ assert {batch["kind"] for batch in plan["batches"]} == {
+ "interface_export_interface_qcov",
+ "interface_export_interface_side_qcov",
+ }
+ for batch in plan["batches"]:
+ write_symmetric_edge_fragment_batch(
+ data_dir=tmp_path,
+ batch=batch,
+ scratch_dir=tmp_path / "scratch-fragments" / batch["key"],
+ threads=1,
+ entity_type="interface",
+ )
+ for metric, pair, expected in (
+ ("interface_qcov", ("i1", "i2"), 60.0),
+ ("interface_side_qcov", ("i1::side=1", "i2::side=2"), 70.0),
+ ):
+ write_symmetric_edge_shard(
+ data_dir=tmp_path,
+ metric=metric,
+ bucket=0,
+ scratch_dir=tmp_path / "scratch-shards" / metric,
+ threads=1,
+ entity_type="interface",
+ )
+ edges = pd.read_parquet(
+ tmp_path
+ / "interface_clusters/symmetric_edges"
+ / f"metric={metric}/bucket=000.parquet"
+ ).set_index(["query_node", "target_node"])
+ assert edges.loc[pair, "similarity"] == pytest.approx(expected)
+ if metric == "interface_qcov":
+ assert edges.loc[pair, "forward_similarity"] == pytest.approx(80.0)
+
+
+def test_empty_interface_universe_publishes_typed_empty_cover(tmp_path):
+ from plinder.data.clusters import (
+ make_directed_cover_component_reduction,
+ make_directed_set_cover,
+ merge_directed_cover_component_reductions,
+ prepare_component_node_universe,
+ prepare_symmetric_edge_plan,
+ write_symmetric_edge_shard,
+ )
+
+ index_dir = tmp_path / "index"
+ index_dir.mkdir()
+ pd.DataFrame({"system_id": pd.Series(dtype="string")}).to_parquet(
+ index_dir / "interface_annotation_table.parquet",
+ index=False,
+ )
+ _write_interface_cluster_universe(index_dir, [])
+ prepare_component_node_universe(tmp_path, entity_type="interface")
+ plan = prepare_symmetric_edge_plan(
+ data_dir=tmp_path,
+ metrics=["interface_qcov"],
+ bucket_count=1,
+ entity_type="interface",
+ )
+ assert plan["batches"] == []
+ write_symmetric_edge_shard(
+ data_dir=tmp_path,
+ metric="interface_qcov",
+ bucket=0,
+ scratch_dir=tmp_path / "scratch-shard",
+ entity_type="interface",
+ )
+ edge_path = (
+ tmp_path
+ / "interface_clusters/symmetric_edges/metric=interface_qcov"
+ / "bucket=000.parquet"
+ )
+ make_directed_cover_component_reduction(
+ data_dir=tmp_path,
+ metric="interface_qcov",
+ thresholds=[50],
+ source_path=edge_path,
+ entity_type="interface",
+ )
+ merge_directed_cover_component_reductions(
+ data_dir=tmp_path,
+ metric="interface_qcov",
+ thresholds=[50],
+ entity_type="interface",
+ )
+ cover = make_directed_set_cover(
+ data_dir=tmp_path,
+ metric="interface_qcov",
+ threshold=50,
+ entity_type="interface",
+ )
+
+ frame = pd.read_parquet(cover)
+ assert frame.empty
+ assert "system_id" in frame.columns
+
+ from plinder.data.pipeline.score import summarize_clustering_artifacts
+
+ summary = summarize_clustering_artifacts(
+ tmp_path,
+ metrics=["interface_qcov"],
+ thresholds=[50],
+ entity_type="interface",
+ )
+ assert summary["status"] == "complete"
+ assert summary["artifact_count"] == 1
+
+
+def test_interface_cluster_plan_requires_scores_for_nonempty_universe(tmp_path):
+ from plinder.data.clusters import (
+ prepare_component_node_universe,
+ prepare_symmetric_edge_plan,
+ )
+
+ index_dir = tmp_path / "index"
+ index_dir.mkdir()
+ pd.DataFrame({"system_id": ["i1"]}).to_parquet(
+ index_dir / "interface_annotation_table.parquet",
+ index=False,
+ )
+ _write_interface_cluster_universe(index_dir, ["i1"])
+ prepare_component_node_universe(tmp_path, entity_type="interface")
+
+ with pytest.raises(
+ FileNotFoundError,
+ match="no raw interface score sources found",
+ ):
+ prepare_symmetric_edge_plan(
+ data_dir=tmp_path,
+ metrics=["interface_qcov"],
+ entity_type="interface",
+ )
+
+
+def test_symmetric_edge_fragment_validation_can_be_scoped_to_one_bucket(tmp_path):
+ from plinder.data.clusters import _completed_symmetric_fragment_batch
+
+ batch = {"key": "batch-key", "kind": "score"}
+ plan = {"plan_hash": "plan-hash"}
+ output_dir = (
+ tmp_path
+ / "ligand_clusters"
+ / "symmetric_edges"
+ / "fragments"
+ / "batch=batch-key"
+ )
+ selected = output_dir / "metric=pocket_qcov/bucket=0/data.parquet"
+ unrelated = output_dir / "metric=pli_qcov/bucket=1/data.parquet"
+ selected.parent.mkdir(parents=True)
+ unrelated.parent.mkdir(parents=True)
+ selected.write_bytes(b"selected")
+ unrelated.write_bytes(b"unrelated")
+ manifest = {
+ "version": 1,
+ "plan_hash": plan["plan_hash"],
+ "batch": batch,
+ "outputs": [
+ {
+ "path": selected.relative_to(output_dir).as_posix(),
+ "size": selected.stat().st_size,
+ },
+ {
+ "path": unrelated.relative_to(output_dir).as_posix(),
+ "size": unrelated.stat().st_size,
+ },
+ ],
+ }
+ (output_dir / "manifest.json").write_text(json.dumps(manifest))
+ unrelated.unlink()
+
+ assert (
+ _completed_symmetric_fragment_batch(
+ data_dir=tmp_path,
+ plan=plan,
+ batch=batch,
+ output_prefix="metric=pocket_qcov/bucket=0/",
+ )
+ == manifest
+ )
+ assert (
+ _completed_symmetric_fragment_batch(
+ data_dir=tmp_path,
+ plan=plan,
+ batch=batch,
+ )
+ is None
+ )
+
+
+def test_greedy_set_cover_assigns_members_to_the_best_representative():
+ from plinder.data.clusters import _greedy_set_cover
+
+ nodes = ["l1", "l2", "l3", "l4"]
+ graph = nk.Graph(len(nodes), weighted=True, directed=False)
+ graph.addEdges(
+ (
+ np.asarray([0.7, 0.9, 0.75]),
+ (
+ np.asarray([0, 1, 2], dtype=np.uint),
+ np.asarray([1, 2, 3], dtype=np.uint),
+ ),
+ )
+ )
+
+ assert _greedy_set_cover(graph, nodes) == [
+ ("l2", ["l1", "l2"]),
+ ("l3", ["l3", "l4"]),
+ ]
+
+
+def test_greedy_set_cover_selects_the_largest_residual_gain():
+ from plinder.data.clusters import _greedy_set_cover
+
+ nodes = ["broad-other", "preferred-1", "preferred-2"]
+ graph = nk.Graph(len(nodes), weighted=True, directed=False)
+ graph.addEdges(
+ (
+ np.asarray([0.9, 0.9]),
+ (
+ np.asarray([0, 0], dtype=np.uint),
+ np.asarray([1, 2], dtype=np.uint),
+ ),
+ )
+ )
+
+ groups = _greedy_set_cover(graph, nodes)
+
+ assert groups == [("broad-other", nodes)]
+
+
+def test_directed_cover_uses_query_to_centroid_scores_and_reassigns():
+ from plinder.data.clusters import _greedy_directed_centroid_cover
+
+ nodes = ["a", "b", "c", "d"]
+ graph = nk.Graph(len(nodes), weighted=True, directed=True)
+ graph.addEdges(
+ (
+ np.asarray([0.8, 0.6, 0.9]),
+ (
+ np.asarray([0, 2, 2], dtype=np.uint),
+ np.asarray([1, 1, 3], dtype=np.uint),
+ ),
+ )
+ )
+
+ assignments = _greedy_directed_centroid_cover(graph, nodes)
+
+ assert assignments == [
+ ("a", "b", pytest.approx(80.0), 1, pytest.approx(0.25)),
+ ("b", "b", 100.0, 3, pytest.approx(0.75)),
+ ("c", "d", pytest.approx(90.0), 1, pytest.approx(0.25)),
+ ("d", "d", 100.0, 2, pytest.approx(0.5)),
+ ]
+
+
+@pytest.mark.parametrize("primary_threshold", [30, 50, 90, 100])
+def test_indexed_cover_components_preserve_assignments(primary_threshold, tmp_path):
+ from plinder.data.clusters import (
+ _build_outgoing_edge_index,
+ _greedy_indexed_directed_set_cover,
+ _IncomingEdgeIndex,
+ )
+
+ # Two disconnected components and an isolate, with interleaved node IDs.
+ # Strict edges exhaust their gain before the relaxed pass covers all nodes.
+ nodes = ["a", "b", "c", "d", "e", "f", "g"]
+ incoming = [[], [], [(0, 95), (4, 55)], [(1, 90), (5, 60)], [], [], []]
+ index = _IncomingEdgeIndex(
+ offsets=np.asarray([0, 0, 0, 2, 4, 4, 4, 4], dtype=np.int64),
+ queries=np.asarray(
+ [q for edges in incoming for q, _ in edges], dtype=np.uint32
+ ),
+ similarities=np.asarray(
+ [s for edges in incoming for _, s in edges], dtype=np.uint8
+ ),
+ )
+ fallback = min(primary_threshold, 50)
+
+ def gains(threshold):
+ return np.asarray(
+ [1 + sum(s >= threshold for _, s in edges) for edges in incoming]
+ )
+
+ kwargs = dict(
+ primary_threshold=primary_threshold,
+ fallback_threshold=fallback,
+ primary_gains=gains(primary_threshold),
+ fallback_gains=gains(fallback),
+ outgoing_index=_build_outgoing_edge_index(
+ index,
+ target_index_path=tmp_path / "targets.bin",
+ similarity_index_path=tmp_path / "scores.bin",
+ ),
+ )
+ global_result = _greedy_indexed_directed_set_cover(index, nodes, **kwargs)
+ component_result = _greedy_indexed_directed_set_cover(
+ index, nodes, components=np.asarray([0, 1, 0, 1, 0, 1, 2]), **kwargs
+ )
+ for expected, actual in zip(global_result[1:], component_result[1:]):
+ np.testing.assert_array_equal(actual, expected)
+ assert sorted(
+ (s.representative, s.threshold, s.marginal_gain) for s in component_result[0]
+ ) == sorted(
+ (s.representative, s.threshold, s.marginal_gain) for s in global_result[0]
+ )
+
+
+def test_indexed_cover_preserves_selected_centroids_in_perfect_ties(tmp_path):
+ from plinder.data.clusters import (
+ _build_outgoing_edge_index,
+ _greedy_indexed_directed_set_cover,
+ _IncomingEdgeIndex,
+ )
+
+ index = _IncomingEdgeIndex(
+ offsets=np.asarray([0, 3, 4, 4, 4, 4], dtype=np.int64),
+ queries=np.asarray([1, 2, 3, 4], dtype=np.uint32),
+ similarities=np.asarray([100, 100, 100, 100], dtype=np.uint8),
+ )
+ selections, representatives, similarities, _ = _greedy_indexed_directed_set_cover(
+ index,
+ ["a", "b", "c", "d", "e"],
+ primary_threshold=100,
+ fallback_threshold=50,
+ primary_gains=np.asarray([4, 2, 1, 1, 1]),
+ fallback_gains=np.asarray([4, 2, 1, 1, 1]),
+ components=np.zeros(5, dtype=np.uint32),
+ outgoing_index=_build_outgoing_edge_index(
+ index,
+ target_index_path=tmp_path / "targets.bin",
+ similarity_index_path=tmp_path / "scores.bin",
+ ),
+ )
+ assert [selection.representative for selection in selections] == [0, 1]
+ np.testing.assert_array_equal(representatives, [0, 1, 0, 0, 1])
+ np.testing.assert_array_equal(similarities, [100, 100, 100, 100, 100])
+
+
+@pytest.mark.parametrize("threshold", [30, 50, 70, 90, 100])
+def test_incremental_cover_matches_reference_without_candidate_rescans(
+ threshold, tmp_path, monkeypatch
+):
+ from plinder.data.clusters import (
+ _build_outgoing_edge_index,
+ _greedy_directed_set_cover,
+ _greedy_indexed_directed_set_cover,
+ _IncomingEdgeIndex,
+ )
+
+ rng = np.random.default_rng(42)
+ size = 60
+ nodes = [f"{i:03d}" for i in range(size)]
+ incoming = [[] for _ in nodes]
+ graph = nk.Graph(size, weighted=True, directed=True)
+ for target in range(size):
+ for query in rng.choice(size, size=20, replace=False):
+ if query != target:
+ score = int(rng.integers(30, 101))
+ incoming[target].append((query, score))
+ graph.addEdge(int(query), target, score / 100)
+ index = _IncomingEdgeIndex(
+ offsets=np.r_[0, np.cumsum([len(edges) for edges in incoming])],
+ queries=np.asarray(
+ [q for edges in incoming for q, _ in edges], dtype=np.uint32
+ ),
+ similarities=np.asarray(
+ [s for edges in incoming for _, s in edges], dtype=np.uint8
+ ),
+ )
+ outgoing = _build_outgoing_edge_index(
+ index,
+ target_index_path=tmp_path / "targets.bin",
+ similarity_index_path=tmp_path / "scores.bin",
+ )
+ calls = 0
+ original = _IncomingEdgeIndex.incoming
+
+ def counted(self, *args):
+ nonlocal calls
+ calls += 1
+ return original(self, *args)
+
+ monkeypatch.setattr(_IncomingEdgeIndex, "incoming", counted)
+ fallback = min(threshold, 50)
+
+ def gains(t):
+ return np.asarray([1 + sum(s >= t for _, s in edges) for edges in incoming])
+
+ primary_gains = gains(threshold)
+ actual = _greedy_indexed_directed_set_cover(
+ index,
+ nodes,
+ primary_threshold=threshold,
+ fallback_threshold=fallback,
+ primary_gains=primary_gains,
+ fallback_gains=gains(fallback),
+ outgoing_index=outgoing,
+ )
+ expected, _ = _greedy_directed_set_cover(
+ graph, nodes, primary_threshold=threshold, fallback_threshold=fallback
+ )
+ assert actual[0] == expected
+ assert calls <= 2 * len(expected)
+ np.testing.assert_array_equal(primary_gains, gains(threshold))
+
+
+def test_directed_cover_falls_back_to_relaxed_edges_when_strict_gain_ends():
+ from plinder.data.clusters import _greedy_directed_set_cover
+
+ nodes = ["q1", "q2", "r1", "r2"]
+ graph = nk.Graph(len(nodes), weighted=True, directed=True)
+ graph.addEdges(
+ (
+ np.asarray([0.9, 0.55]),
+ (
+ np.asarray([0, 1], dtype=np.uint),
+ np.asarray([2, 3], dtype=np.uint),
+ ),
+ )
+ )
+ candidate_mask = np.asarray([False, False, True, True])
+ target_mask = np.asarray([True, True, False, False])
+
+ selections, assignments = _greedy_directed_set_cover(
+ graph,
+ nodes,
+ primary_threshold=90,
+ fallback_threshold=50,
+ candidate_mask=candidate_mask,
+ target_mask=target_mask,
+ )
+
+ assert [
+ (nodes[item.representative], item.threshold, item.marginal_gain)
+ for item in selections
+ ] == [("r1", 90, 1), ("r2", 50, 1)]
+ assert [
+ (
+ nodes[item.query],
+ nodes[item.representative],
+ item.similarity,
+ item.threshold,
+ )
+ for item in assignments
+ ] == [
+ ("q1", "r1", pytest.approx(90.0), 90),
+ ("q2", "r2", pytest.approx(55.0), 50),
+ ]
+
+
+def test_directed_cover_uses_stable_ids_for_ties_and_self_for_isolates():
+ from plinder.data.clusters import _greedy_directed_set_cover
+
+ nodes = ["query", "lower-quality", "higher-quality", "isolated"]
+ graph = nk.Graph(len(nodes), weighted=True, directed=True)
+ graph.addEdges(
+ (
+ np.asarray([0.8, 0.8]),
+ (
+ np.asarray([0, 0], dtype=np.uint),
+ np.asarray([1, 2], dtype=np.uint),
+ ),
+ )
+ )
+
+ selections, assignments = _greedy_directed_set_cover(
+ graph,
+ nodes,
+ primary_threshold=70,
+ fallback_threshold=50,
+ candidate_mask=np.asarray([False, True, True, False]),
+ target_mask=np.asarray([True, False, False, True]),
+ )
+
+ assert [(nodes[item.representative], item.threshold) for item in selections] == [
+ ("higher-quality", 70),
+ ("isolated", None),
+ ]
+ assert [
+ (nodes[item.query], nodes[item.representative]) for item in assignments
+ ] == [("query", "higher-quality"), ("isolated", "isolated")]
+
+
+def test_directed_cover_selects_the_largest_residual_gain():
+ from plinder.data.clusters import _greedy_directed_set_cover
+
+ nodes = ["q1", "q2", "q3", "preferred", "broad-other"]
+ graph = nk.Graph(len(nodes), weighted=True, directed=True)
+ graph.addEdges(
+ (
+ np.asarray([0.9, 0.9, 0.9, 0.9]),
+ (
+ np.asarray([0, 0, 1, 2], dtype=np.uint),
+ np.asarray([3, 4, 4, 4], dtype=np.uint),
+ ),
+ )
+ )
+
+ selections, assignments = _greedy_directed_set_cover(
+ graph,
+ nodes,
+ primary_threshold=90,
+ fallback_threshold=50,
+ candidate_mask=np.asarray([False, False, False, True, True]),
+ target_mask=np.asarray([True, True, True, False, False]),
+ )
+
+ assert [nodes[item.representative] for item in selections] == ["broad-other"]
+ assert {nodes[item.query] for item in assignments} == {"q1", "q2", "q3"}
+
+
+def test_symmetric_plan_checks_only_sources_for_the_requested_metric(tmp_path):
+ from plinder.data.clusters import (
+ load_symmetric_edge_plan,
+ prepare_symmetric_edge_plan,
+ )
+
+ score_dir = tmp_path / "scores/search_db=holo"
+ chemical_dir = tmp_path / "ligand_scores"
+ score_dir.mkdir(parents=True)
+ chemical_dir.mkdir()
+ score_source = score_dir / "scores.parquet"
+ chemical_source = chemical_dir / "chemical.parquet"
+ score_source.write_text("score")
+ chemical_source.write_text("chemical")
+ prepare_symmetric_edge_plan(
+ data_dir=tmp_path,
+ metrics=[
+ "sucos_shape_pocket_qcov",
+ "tanimoto_similarity_ecfp4_1024",
+ ],
+ source_batch_size=1,
+ bucket_count=1,
+ )
+ chemical_source.unlink()
+
+ plan = load_symmetric_edge_plan(
+ tmp_path,
+ metrics=["sucos_shape_pocket_qcov"],
+ )
+ assert plan["metrics"] == [
+ "sucos_shape_pocket_qcov",
+ "tanimoto_similarity_ecfp4_1024",
+ ]
+ with pytest.raises(ValueError, match="raw score source changed"):
+ load_symmetric_edge_plan(
+ tmp_path,
+ metrics=["tanimoto_similarity_ecfp4_1024"],
+ )
+
+
+def test_set_cover_stream_rejects_edges_crossing_components(tmp_path):
+ from plinder.data.clusters import (
+ make_set_cover,
+ prepare_symmetric_edge_plan,
+ write_symmetric_edge_fragment_batch,
+ write_symmetric_edge_shard,
+ )
+
+ metric = "tanimoto_similarity_ecfp4_1024"
+ index_dir = tmp_path / "index"
+ score_dir = tmp_path / "ligand_scores"
+ fingerprint_dir = tmp_path / "fingerprints"
+ component_dir = (
+ tmp_path
+ / "ligand_clusters"
+ / "reductions"
+ / f"metric={metric}"
+ / "labels"
+ / "directed=false"
+ )
+ index_dir.mkdir(parents=True)
+ score_dir.mkdir()
+ fingerprint_dir.mkdir()
+ component_dir.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "system_id": ["s1", "s2"],
+ "ligand_id": ["l1", "l2"],
+ "system_type": ["holo", "holo"],
+ "ligand_is_proper": [True, True],
+ "ligand_smiles": ["CC", "CCC"],
+ }
+ ).to_parquet(index_dir / "annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "ligand_smiles_id": [0, 1],
+ "ligand_rdkit_canonical_smiles": ["CC", "CCC"],
+ }
+ ).to_parquet(fingerprint_dir / "ligands_per_smiles.parquet", index=False)
+ pd.DataFrame(
+ {
+ "query_ligand_id": [0],
+ "target_ligand_id": [1],
+ metric: [80.0],
+ }
+ ).to_parquet(score_dir / "part.parquet", index=False)
+ plan = prepare_symmetric_edge_plan(
+ data_dir=tmp_path,
+ metrics=[metric],
+ source_batch_size=1,
+ bucket_count=1,
+ )
+ write_symmetric_edge_fragment_batch(
+ data_dir=tmp_path,
+ batch=plan["batches"][0],
+ scratch_dir=tmp_path / "scratch-fragments",
+ threads=1,
+ )
+ write_symmetric_edge_shard(
+ data_dir=tmp_path,
+ metric=metric,
+ bucket=0,
+ scratch_dir=tmp_path / "scratch-shard",
+ threads=1,
+ )
+ pd.DataFrame(
+ {
+ "ligand_id": ["0", "1"],
+ "label": ["component0", "component1"],
+ }
+ ).to_parquet(component_dir / "threshold=50.parquet", index=False)
+
+ with pytest.raises(ValueError, match="crossing edges"):
+ make_set_cover(
+ data_dir=tmp_path,
+ metric=metric,
+ threshold=50,
+ scratch_dir=tmp_path / "scratch",
+ threads=1,
+ )
+
+
+def test_ligand_covers_are_merged_without_system_projection(tmp_path):
+ from plinder.data.pipeline.utils import finalize_index
+
+ index_dir = tmp_path / "index"
+ score_dir = tmp_path / "scores" / "search_db=holo"
+ index_dir.mkdir(parents=True)
+ score_dir.mkdir(parents=True)
+
+ system_a = "1aaa__1__1.A__1.X_1.Y"
+ system_b = "2bbb__1__1.B__1.Z"
+ system_c = "3ccc__1__1.C__1.W"
+ system_d = "4ddd__1__1.D__1.V"
+ ligand_a1 = "1aaa__1__1.X"
+ ligand_a2 = "1aaa__1__1.Y"
+ ligand_b = "2bbb__1__1.Z"
+ ligand_c = "3ccc__1__1.W"
+ ligand_d = "4ddd__1__1.V"
+ annotation = pd.DataFrame(
+ {
+ "system_id": [system_a, system_a, system_b, system_c, system_d],
+ "system_id_no_biounit": [
+ "1aaa__1.A",
+ "1aaa__1.A",
+ "2bbb__1.B",
+ "3ccc__1.C",
+ "4ddd__1.D",
+ ],
+ "system_biounit_id": ["1"] * 5,
+ "ligand_id": [ligand_a1, ligand_a2, ligand_b, ligand_c, ligand_d],
+ "ligand_smiles": [
+ "CC",
+ "CCC",
+ "CCCC",
+ "CCCCC",
+ "CCCCCC",
+ ],
+ "system_type": ["holo"] * 5,
+ "system_num_protein_chains": [1] * 5,
+ "system_num_ligand_chains": [2, 2, 1, 1, 1],
+ "ligand_is_proper": [True, True, True, True, False],
+ }
+ )
+ annotation.to_parquet(index_dir / "annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "query_system": [system_a, system_b, system_a, system_a, system_d],
+ "query_ligand_id": [
+ ligand_a1,
+ ligand_b,
+ ligand_a2,
+ ligand_a2,
+ ligand_d,
+ ],
+ "target_system": [system_b, system_a, system_c, system_d, system_a],
+ "target_ligand_id": [
+ ligand_b,
+ ligand_a1,
+ ligand_c,
+ ligand_d,
+ ligand_a2,
+ ],
+ "metric": ["sucos_shape_pocket_qcov"] * 5,
+ "similarity": [80, 80, 40, 90, 90],
+ }
+ ).to_parquet(score_dir / "scores.parquet", index=False)
+ fingerprint_dir = tmp_path / "fingerprints"
+ fingerprint_dir.mkdir()
+ proper_annotation = annotation[annotation["ligand_is_proper"]]
+ pd.DataFrame(
+ {
+ "ligand_rdkit_canonical_smiles": proper_annotation["ligand_smiles"],
+ "ligand_smiles_id": range(len(proper_annotation)),
+ }
+ ).to_parquet(fingerprint_dir / "ligand_similarity_annotations.parquet", index=False)
+ ligand_dir = tmp_path / "ligands"
+ ligand_dir.mkdir()
+ pd.DataFrame(
+ {
+ "ligand_id": annotation["ligand_id"],
+ "ligand_is_shape_comparable": [True, True, False, True, False],
+ }
+ ).to_parquet(ligand_dir / "part.parquet", index=False)
+
+ directed_cover = (
+ tmp_path
+ / "ligand_sampling/directed_set_cover"
+ / "metric=sucos_shape_pocket_qcov/threshold=50.parquet"
+ )
+ directed_cover.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "ligand_id": [ligand_a1, ligand_a2, ligand_b, ligand_c],
+ "label": ["d0", "d1", "d0", "d2"],
+ "centroid_ligand_id": [
+ ligand_a1,
+ ligand_a2,
+ ligand_a1,
+ ligand_c,
+ ],
+ "coverage_count": [2, 1, 2, 1],
+ "coverage_fraction": [0.5, 0.25, 0.5, 0.25],
+ }
+ ).to_parquet(directed_cover, index=False)
+
+ component_path = (
+ tmp_path
+ / "ligand_clusters/reductions/metric=sucos_shape_pocket_qcov"
+ / "labels/directed=false/threshold=50.parquet"
+ )
+ component_path.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "ligand_id": [ligand_a1, ligand_a2, ligand_b, ligand_c],
+ "label": ["c0", "c1", "c0", "c2"],
+ }
+ ).to_parquet(component_path, index=False)
+
+ finalized = finalize_index(data_dir=tmp_path)
+ cluster_table = pd.read_parquet(index_dir / "ligand_clusters.parquet")
+ ligand_column = "sucos_shape_pocket_qcov__50__ligand__directed_set_cover"
+ assert "sucos_shape_pocket_qcov__50__directed_set_cover" not in finalized
+ assert ligand_column not in finalized
+ finalized_labels = cluster_table.set_index("ligand_id")[ligand_column]
+ assert finalized_labels[ligand_a1] == finalized_labels[ligand_b]
+ assert finalized_labels[ligand_a2] != finalized_labels[ligand_a1]
+ assert pd.isna(finalized_labels[ligand_d])
+ component_column = "sucos_shape_pocket_qcov__50__ligand__reciprocal_component"
+ components = cluster_table.set_index("ligand_id")[component_column]
+ assert components[ligand_a1] == components[ligand_b]
+ assert components[ligand_a2] != components[ligand_a1]
+ assert pd.isna(components[ligand_d])
+ centroid_column = f"{ligand_column}__is_centroid"
+ finalized_centroids = cluster_table.set_index("ligand_id")[centroid_column]
+ assert bool(finalized_centroids[ligand_a1])
+ assert not bool(finalized_centroids[ligand_b])
+ assert not bool(
+ finalized.set_index("ligand_id").loc[ligand_b, "ligand_is_shape_comparable"]
+ )
+
+
+def test_finalize_index_rejects_stale_ligand_cover_universe(tmp_path):
+ from plinder.data.pipeline.utils import finalize_index
+
+ index_dir = tmp_path / "index"
+ ligand_dir = tmp_path / "ligands"
+ fingerprint_dir = tmp_path / "fingerprints"
+ index_dir.mkdir(parents=True)
+ ligand_dir.mkdir()
+ fingerprint_dir.mkdir()
+ pd.DataFrame(
+ {
+ "system_id": ["s1", "s2"],
+ "system_id_no_biounit": ["s1", "s2"],
+ "system_type": ["holo", "holo"],
+ "ligand_id": ["l1", "l2"],
+ "ligand_is_proper": [True, True],
+ "ligand_smiles": ["CC", "CCC"],
+ }
+ ).to_parquet(index_dir / "annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "ligand_id": ["l1", "l2"],
+ "ligand_is_shape_comparable": [True, True],
+ }
+ ).to_parquet(ligand_dir / "part.parquet", index=False)
+ pd.DataFrame(
+ {
+ "ligand_rdkit_canonical_smiles": ["CC", "CCC"],
+ "ligand_smiles_id": [0, 1],
+ }
+ ).to_parquet(
+ fingerprint_dir / "ligand_similarity_annotations.parquet",
+ index=False,
+ )
+ directed_cover = (
+ tmp_path
+ / "ligand_sampling/directed_set_cover"
+ / "metric=sucos_shape_pocket_qcov/threshold=30.parquet"
+ )
+ directed_cover.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "ligand_id": ["l1"],
+ "centroid_ligand_id": ["l1"],
+ "label": ["d0"],
+ "coverage_count": [1],
+ "coverage_fraction": [1.0],
+ }
+ ).to_parquet(
+ directed_cover,
+ index=False,
+ )
+
+ with pytest.raises(ValueError, match="current eligible ligand universe"):
+ finalize_index(data_dir=tmp_path)
+
+
+def test_finalize_index_rejects_clusters_from_before_targeted_repair(tmp_path):
+ from plinder.data.pipeline.utils import finalize_index
+
+ index_dir = tmp_path / "index"
+ ligand_dir = tmp_path / "ligands"
+ fingerprint_dir = tmp_path / "fingerprints"
+ index_dir.mkdir(parents=True)
+ ligand_dir.mkdir()
+ fingerprint_dir.mkdir()
+ pd.DataFrame(
+ {
+ "system_id": ["s1"],
+ "system_id_no_biounit": ["s1"],
+ "system_type": ["holo"],
+ "ligand_id": ["l1"],
+ "ligand_is_proper": [True],
+ "ligand_smiles": ["CC"],
+ }
+ ).to_parquet(index_dir / "annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "ligand_id": ["l1"],
+ "ligand_is_shape_comparable": [True],
+ }
+ ).to_parquet(ligand_dir / "part.parquet", index=False)
+ directed_cover = (
+ tmp_path
+ / "ligand_sampling/directed_set_cover"
+ / "metric=sucos_shape_pocket_qcov/threshold=30.parquet"
+ )
+ directed_cover.parent.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "ligand_id": ["l1"],
+ "centroid_ligand_id": ["l1"],
+ "label": ["d0"],
+ }
+ ).to_parquet(
+ directed_cover,
+ index=False,
+ )
+ (index_dir / "collation.json").write_text(
+ '{"status": "requires_downstream_repair"}'
+ )
+ fingerprint_path = fingerprint_dir / "ligand_similarity_annotations.parquet"
+ pd.DataFrame(
+ {
+ "ligand_rdkit_canonical_smiles": ["CC"],
+ "ligand_smiles_id": [0],
+ }
+ ).to_parquet(fingerprint_path, index=False)
+ marker_mtime_ns = (index_dir / "collation.json").stat().st_mtime_ns
+ utime(
+ fingerprint_path,
+ ns=(marker_mtime_ns + 1_000_000_000,) * 2,
+ )
+
+ with pytest.raises(ValueError, match="cluster artifact predates"):
+ finalize_index(data_dir=tmp_path)
+
+
+def test_default_cluster_metrics_use_only_pocket_weighted_shape():
+ from plinder.core.scores.metrics import (
+ LIGAND_CLUSTER_METRICS,
+ LIGAND_SCORE_NAMES,
+ is_ligand_level_metric,
+ )
+ from plinder.data.pipeline.config import METRICS
+
+ assert "shape" in LIGAND_SCORE_NAMES
+ assert "color" in LIGAND_SCORE_NAMES
+ assert "sucos_shape_pocket_qcov" in METRICS
+ assert "tanimoto_similarity_ecfp4_1024" in METRICS
+ assert "shape" not in METRICS
+ assert "color" not in METRICS
+ assert "pocket_fident" not in METRICS
+ assert "pocket_fident_qcov" not in METRICS
+ assert "pli_unique_qcov" not in LIGAND_SCORE_NAMES
+ assert "pli_unique_qcov" not in METRICS
+ assert set(LIGAND_CLUSTER_METRICS) == {
+ "pocket_qcov",
+ "pli_qcov",
+ "sucos_shape_pocket_qcov",
+ }
+ assert "shape_tanimoto" not in METRICS
+ assert "sucos_shape" not in METRICS
+ assert not any(metric.startswith("protein_lddt") for metric in METRICS)
+ assert not any(metric.startswith("protein_") for metric in METRICS)
+ assert all(is_ligand_level_metric(metric) for metric in METRICS)
+
+
+def test_component_node_universe_keeps_large_holo_targets_in_prepared_cache(
+ tmp_path, monkeypatch
+):
+ from plinder.data import clusters
+
+ index_dir = tmp_path / "index"
+ index_dir.mkdir()
+ pd.DataFrame(
+ {
+ "system_id": ["s1", "s2", "s3"],
+ "ligand_id": ["l1", "l2", "l3"],
+ "system_type": ["holo", "holo", "holo"],
+ "system_num_protein_chains": [1, 6, 1],
+ "system_num_ligand_chains": [1, 1, 1],
+ "ligand_is_proper": [True, True, False],
+ }
+ ).to_parquet(index_dir / "annotation_table.parquet", index=False)
+
+ report = clusters.prepare_component_node_universe(tmp_path)
+ assert report["ligand_count"] == 2
+ assert report["system_count"] == 2
+ monkeypatch.setattr(
+ clusters,
+ "_eligible_annotation",
+ lambda data_dir: pytest.fail("prepared node universe was not reused"),
+ )
+ nodes, systems = clusters.component_node_universe(
+ data_dir=tmp_path,
+ metric="pocket_qcov",
+ )
+ assert nodes == ["l1", "l2"]
+ assert systems == {"s1", "s2"}
+
+
+def test_tanimoto_set_cover_expands_unique_smiles_to_ligands(tmp_path):
+ from plinder.data.clusters import (
+ make_score_component_reduction,
+ make_set_cover,
+ merge_score_component_reductions,
+ prepare_symmetric_edge_plan,
+ write_symmetric_edge_fragment_batch,
+ write_symmetric_edge_shard,
+ )
+
+ index_dir = tmp_path / "index"
+ fingerprint_dir = tmp_path / "fingerprints"
+ score_dir = tmp_path / "ligand_scores"
+ index_dir.mkdir()
+ fingerprint_dir.mkdir()
+ score_dir.mkdir()
+
+ system_a = "1aaa__1__1.A__1.X_1.Y"
+ system_b = "2bbb__1__1.B__1.Z"
+ system_c = "3ccc__1__1.C__1.W"
+ pd.DataFrame(
+ {
+ "system_id": [system_a, system_a, system_b, system_c],
+ "ligand_id": [
+ "1aaa__1__1.X",
+ "1aaa__1__1.Y",
+ "2bbb__1__1.Z",
+ "3ccc__1__1.W",
+ ],
+ "ligand_molecular_weight": [100.0, 200.0, 150.0, 100.0],
+ "ligand_smiles": ["CC", "CCC", "CCCC", "CC"],
+ "ligand_is_proper": [True] * 4,
+ "ligand_is_ion": [False] * 4,
+ "ligand_is_artifact": [False] * 4,
+ }
+ ).to_parquet(index_dir / "annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "ligand_smiles_id": [0, 1, 2],
+ "ligand_rdkit_canonical_smiles": ["CC", "CCC", "CCCC"],
+ }
+ ).to_parquet(fingerprint_dir / "ligands_per_smiles.parquet", index=False)
+ pd.DataFrame(
+ {
+ "query_ligand_id": [0, 0, 1, 2, 2],
+ "target_ligand_id": [0, 2, 1, 0, 2],
+ "tanimoto_similarity_ecfp4_1024": [100.0, 95.0, 100.0, 95.0, 100.0],
+ }
+ ).to_parquet(score_dir / "part.parquet", index=False)
+
+ metric = "tanimoto_similarity_ecfp4_1024"
+ plan = prepare_symmetric_edge_plan(
+ data_dir=tmp_path,
+ metrics=[metric],
+ source_batch_size=1,
+ bucket_count=1,
+ )
+ write_symmetric_edge_fragment_batch(
+ data_dir=tmp_path,
+ batch=plan["batches"][0],
+ scratch_dir=tmp_path / "scratch-fragments",
+ threads=1,
+ )
+ write_symmetric_edge_shard(
+ data_dir=tmp_path,
+ metric=metric,
+ bucket=0,
+ scratch_dir=tmp_path / "scratch-shard",
+ threads=1,
+ )
+ edge_path = (
+ tmp_path
+ / "ligand_clusters/symmetric_edges"
+ / f"metric={metric}/bucket=000.parquet"
+ )
+ make_score_component_reduction(
+ data_dir=tmp_path,
+ metric=metric,
+ thresholds=[90],
+ source_path=edge_path,
+ )
+ merge_score_component_reductions(
+ data_dir=tmp_path,
+ metric=metric,
+ thresholds=[90],
+ )
+ output = make_set_cover(
+ data_dir=tmp_path,
+ metric=metric,
+ threshold=90,
+ scratch_dir=tmp_path / "scratch-cover",
+ threads=1,
+ )
+ cover = pd.read_parquet(output).set_index("ligand_id")
+ labels = cover["label"]
+ assert labels["1aaa__1__1.X"] == labels["2bbb__1__1.Z"]
+ assert labels["3ccc__1__1.W"] == labels["2bbb__1__1.Z"]
+ assert labels["1aaa__1__1.Y"] != labels["2bbb__1__1.Z"]
+ assert cover.loc["1aaa__1__1.X", "centroid_ligand_id"] == "1aaa__1__1.X"
+ assert cover.loc["2bbb__1__1.Z", "centroid_ligand_id"] == "1aaa__1__1.X"
+ assert set(cover["cluster"]) == {"set_cover"}
+ assert not (tmp_path / "ligand_clusters/cluster=components").exists()
+ assert not (tmp_path / "ligand_clusters/cluster=communities").exists()
+ assert not (fingerprint_dir / "ligands_per_system.parquet").exists()
+
+
+@pytest.mark.parametrize("metric", ["shape", "color", "sucos_shape"])
+def test_gated_shape_diagnostics_cannot_be_clustered(tmp_path, metric):
+ from plinder.data.pipeline.score import _cluster_parameters
+
+ with pytest.raises(ValueError, match="sucos_shape_pocket_qcov"):
+ _cluster_parameters(metrics=[metric], thresholds=[50])
+
+
+def test_v3_rejects_scores_without_ligand_identifiers(tmp_path):
+ from plinder.data.clusters import iter_component_score_batches
+
+ index_dir = tmp_path / "index"
+ score_dir = tmp_path / "scores" / "search_db=holo"
+ index_dir.mkdir(parents=True)
+ score_dir.mkdir(parents=True)
+ pd.DataFrame(
+ {
+ "system_id": ["1aaa__1__1.A__1.X"],
+ "ligand_id": ["1aaa__1__1.X"],
+ "system_type": ["holo"],
+ "system_num_protein_chains": [1],
+ "system_num_ligand_chains": [1],
+ "ligand_is_proper": [True],
+ }
+ ).to_parquet(index_dir / "annotation_table.parquet", index=False)
+ pd.DataFrame(
+ {
+ "query_system": ["1aaa__1__1.A__1.X"],
+ "target_system": ["1aaa__1__1.A__1.X"],
+ "metric": ["protein_lddt_weighted_sum"],
+ "similarity": [100],
+ }
+ ).to_parquet(score_dir / "scores.parquet", index=False)
+
+ with pytest.raises(ValueError, match="missing"):
+ list(
+ iter_component_score_batches(
+ source_path=score_dir / "scores.parquet",
+ metric="pocket_qcov",
+ eligible_systems={"1aaa__1__1.A__1.X"},
+ )
+ )
+
+
+def test_two_chemical_metrics_get_separate_per_metric_source_groups(tmp_path):
+ from plinder.data.clusters import (
+ _raw_component_score_sources,
+ prepare_symmetric_edge_plan,
+ write_symmetric_edge_fragment_batch,
+ write_symmetric_edge_shard,
+ )
+
+ ecfp4 = "tanimoto_similarity_ecfp4_1024"
+ mhfp6 = "jaccard_similarity_mhfp6_2048"
+ # each chemical metric aggregates its own directed-edge shards
+ (tmp_path / "fingerprints").mkdir()
+ pd.DataFrame({"ligand_smiles_id": [0, 1, 2]}).to_parquet(
+ tmp_path / "fingerprints" / "ligands_per_smiles.parquet", index=False
+ )
+ (tmp_path / "ligand_scores").mkdir()
+ pd.DataFrame(
+ {
+ "query_ligand_id": [0, 1],
+ "target_ligand_id": [1, 2],
+ ecfp4: [90.0, 40.0],
+ }
+ ).to_parquet(tmp_path / "ligand_scores" / "part.parquet", index=False)
+ (tmp_path / "mhfp6_scores").mkdir()
+ pd.DataFrame(
+ {
+ "query_ligand_id": [0, 0, 1],
+ "target_ligand_id": [1, 2, 2],
+ mhfp6: [80.0, 40.0, 35.0],
+ }
+ ).to_parquet(tmp_path / "mhfp6_scores" / "part.parquet", index=False)
+
+ # the source dirs are resolved per metric, not shared
+ assert _raw_component_score_sources(data_dir=tmp_path, metric=ecfp4) == [
+ tmp_path / "ligand_scores" / "part.parquet"
+ ]
+ assert _raw_component_score_sources(data_dir=tmp_path, metric=mhfp6) == [
+ tmp_path / "mhfp6_scores" / "part.parquet"
+ ]
+
+ plan = prepare_symmetric_edge_plan(
+ data_dir=tmp_path,
+ metrics=[ecfp4, mhfp6],
+ source_batch_size=10,
+ bucket_count=1,
+ )
+ chemical_batches = [b for b in plan["batches"] if b["kind"] == "chemical"]
+ # one single-metric group per chemical metric, each with its own source
+ assert {tuple(b["metrics"]) for b in chemical_batches} == {(ecfp4,), (mhfp6,)}
+ sources_by_metric = {
+ b["metrics"][0]: {Path(s["path"]).parent.name for s in b["sources"]}
+ for b in chemical_batches
+ }
+ assert sources_by_metric == {ecfp4: {"ligand_scores"}, mhfp6: {"mhfp6_scores"}}
+
+ # the MHFP6 chemical branch symmetrizes into per-metric shards end to end
+ mhfp6_batch = next(b for b in chemical_batches if b["metrics"][0] == mhfp6)
+ write_symmetric_edge_fragment_batch(
+ data_dir=tmp_path,
+ batch=mhfp6_batch,
+ scratch_dir=tmp_path / "scratch-fragments",
+ threads=1,
+ )
+ write_symmetric_edge_shard(
+ data_dir=tmp_path,
+ metric=mhfp6,
+ bucket=0,
+ scratch_dir=tmp_path / "scratch-shard",
+ threads=1,
)
- j = len(list((write_plinder_mount / "clusters").rglob("*")))
- assert i < j
+ edges = pd.read_parquet(
+ tmp_path
+ / "ligand_clusters/symmetric_edges"
+ / f"metric={mhfp6}/bucket=000.parquet"
+ ).set_index(["query_node", "target_node"])
+ # chemical similarity is symmetric: forward == reverse == the stored value
+ assert edges.loc[("0", "1"), "similarity"] == pytest.approx(80.0)
+ assert edges.loc[("0", "2"), "similarity"] == pytest.approx(40.0)
+ assert edges.loc[("1", "2"), "similarity"] == pytest.approx(35.0)
diff --git a/tests/data/test_contact_areas.py b/tests/data/test_contact_areas.py
new file mode 100644
index 000000000..88ce8375e
--- /dev/null
+++ b/tests/data/test_contact_areas.py
@@ -0,0 +1,270 @@
+# Copyright (c) 2024, Plinder Development Team
+# Distributed under the terms of the Apache License 2.0
+from __future__ import annotations
+
+import numpy as np
+import pytest
+
+from plinder.data.annotations.aggregate_annotations import Entry
+from plinder.data.annotations.cif_utils import build_biounit, read_mmcif_file
+from plinder.data.annotations.contact_areas import (
+ chain_pair_contact_areas,
+ partner_contact_areas,
+ tessellation_atom_mask,
+)
+from plinder.data.annotations.interface_utils import (
+ INTERFACE_ANNOTATION_SCHEMA,
+ protein_interfaces_to_table,
+)
+
+CIF_1QZ5 = "xx/pdb_00001qz5/pdb_00001qz5_xyz-enrich.cif.gz"
+CIF_7CMA = "interfaces/cm/pdb_00007cma/pdb_00007cma_xyz-enrich.cif.gz"
+
+
+def _water_chains(atoms) -> set[str]:
+ return {
+ str(chain_id)
+ for chain_id in np.unique(atoms.chain_id)
+ if np.all(atoms.res_name[atoms.chain_id == chain_id] == "HOH")
+ }
+
+
+def test_chain_pair_contact_areas_match_reference_and_exclude_solvent(test_dir):
+ from voronotalt import biotite_interface # noqa: F401 registers from_biotite_atoms
+ from voronotalt import voronotalt_python as vlt
+
+ biounit = build_biounit(read_mmcif_file(test_dir / CIF_1QZ5), "1")
+ water_chains = _water_chains(biounit)
+ assert water_chains, "fixture must carry a water chain to prove its exclusion"
+ assert not tessellation_atom_mask(biounit)[
+ np.isin(biounit.chain_id, sorted(water_chains))
+ ].any()
+
+ areas = chain_pair_contact_areas(biounit)
+
+ assert areas
+ assert all(chain_a < chain_b for chain_a, chain_b in areas)
+ assert all(area > 0 for area in areas.values())
+ assert not any(water_chains & set(pair) for pair in areas)
+ # Voronota-LT's own biotite shim (waters and hydrogens dropped, default probe)
+ # is the reference for the vectorised ball construction.
+ reference = vlt.MolecularRadicalTessellation.from_biotite_atoms(biounit)
+ expected = {
+ tuple(sorted((summary.ID1_chain, summary.ID2_chain))): summary.area
+ for summary in reference.inter_chain_contact_summaries
+ }
+ assert areas.keys() == expected.keys()
+ for pair, area in areas.items():
+ assert area == pytest.approx(expected[pair], rel=1e-9)
+
+
+def _three_chain_toy(distance_ab: float, occluder: bool):
+ """Two carbon atoms in chains A and B ``distance_ab`` apart on the x axis,
+ optionally with a chain-C carbon at their midpoint; no ins_code annotation."""
+ import biotite.structure as struc
+
+ count = 3 if occluder else 2
+ atoms = struc.AtomArray(count)
+ atoms.coord = np.zeros((count, 3))
+ atoms.coord[1, 0] = distance_ab
+ if occluder:
+ atoms.coord[2, 0] = distance_ab / 2.0
+ atoms.chain_id = np.array(["A", "B", "C"][:count])
+ atoms.res_id = np.arange(1, count + 1)
+ atoms.res_name = np.array(["ALA"] * count)
+ atoms.atom_name = np.array(["CA"] * count)
+ atoms.element = np.array(["C"] * count)
+ atoms.hetero = np.zeros(count, dtype=bool)
+ if "ins_code" in atoms.get_annotation_categories():
+ atoms.del_annotation("ins_code")
+ return atoms
+
+
+def test_chain_pair_contact_areas_follow_contact_geometry():
+ # Two carbons 4 ร apart overlap once each is grown by the 1.4 ร probe.
+ touching = chain_pair_contact_areas(_three_chain_toy(4.0, occluder=False))
+ assert list(touching) == [("A", "B")]
+ assert touching[("A", "B")] > 0
+
+ # Beyond the summed probe-expanded radii there is no contact at all.
+ assert chain_pair_contact_areas(_three_chain_toy(12.0, occluder=False)) == {}
+
+ # A third chain sitting between them takes over part of the shared plane.
+ occluded = chain_pair_contact_areas(_three_chain_toy(4.0, occluder=True))
+ assert occluded.get(("A", "B"), 0.0) < touching[("A", "B")]
+ assert occluded[("A", "C")] > 0 and occluded[("B", "C")] > 0
+ assert all(chain_a < chain_b for chain_a, chain_b in occluded)
+
+ # Hydrogens are ignored, so adding one changes nothing.
+ with_h = _three_chain_toy(4.0, occluder=True)
+ hydrogen = with_h[2:3].copy()
+ hydrogen.element = np.array(["H"])
+ hydrogen.atom_name = np.array(["HA"])
+ hydrogen.coord = hydrogen.coord + 0.7
+ assert chain_pair_contact_areas(with_h + hydrogen) == pytest.approx(occluded)
+
+
+def test_partner_contact_areas_sums_over_member_chains_and_skips_internal_pairs():
+ pair_areas = {
+ ("1.A", "1.C"): 10.0,
+ ("1.C", "1.D"): 5.0, # internal to the two-chain ligand
+ ("1.A", "1.D"): 2.5,
+ ("1.B", "1.C"): 1.0,
+ ("1.A", "1.B"): 7.0, # receptor-receptor, not a partner pair
+ }
+
+ assert partner_contact_areas(pair_areas, {"1.C", "1.D"}) == {
+ "1.A": 12.5,
+ "1.B": 1.0,
+ }
+ assert partner_contact_areas(pair_areas, {"1.Z"}) == {}
+
+
+@pytest.mark.usefixtures("mock_alternative_datasets")
+def test_ligand_contact_area_counts_receptor_chains_only(test_dir):
+ """ATP in 1qz5 touches the receptor chain and a calcium ion: both are reported
+ as partners, but only the receptor counts towards ``contact_area``."""
+ entry = Entry.from_cif_file(test_dir / CIF_1QZ5, include_interfaces=False)
+
+ assert entry.failed_contact_area_biounit_ids == []
+ [atp] = [
+ ligand
+ for system in entry.systems.values()
+ for ligand in system.ligands
+ if ligand.ccd_code == "ATP"
+ ]
+ partners = atp.chain_contact_areas
+ ion_partners = [c for c in partners if c.split(".")[-1] in entry.ligand_like_chains]
+ receptor_partners = [c for c in partners if c not in ion_partners]
+ assert ion_partners and receptor_partners
+ assert all(area > 0 for area in partners.values())
+ assert atp.contact_area == pytest.approx(
+ sum(partners[chain_id] for chain_id in receptor_partners)
+ )
+ assert atp.contact_area > 100.0
+ assert atp.contact_area < sum(partners.values())
+
+ row = atp.format(entry.chains)
+ assert row["ligand_contact_area"] == atp.contact_area
+ assert row["ligand_contact_area_chains"] == sorted(partners)
+ assert row["ligand_contact_area_values"] == [partners[c] for c in sorted(partners)]
+
+
+def test_protein_interface_reports_its_contact_area(test_dir):
+ entry = Entry.from_custom_cif_file(
+ pdb_id="custom_7cma",
+ cif_file=test_dir / CIF_7CMA,
+ structure_mode="as_is",
+ include_ligands=False,
+ include_interfaces=True,
+ interface_annotate_prodigy=False,
+ )
+ [interface] = entry.interfaces
+
+ assert interface.system_id == "custom_7cma__1__1.A--1.B"
+ assert interface.contact_area is not None and interface.contact_area > 100.0
+ assert interface.to_row()["interface_contact_area"] == interface.contact_area
+ table = protein_interfaces_to_table(entry.interfaces)
+ assert table.schema.equals(INTERFACE_ANNOTATION_SCHEMA, check_metadata=False)
+ assert table.column("interface_contact_area").to_pylist() == [
+ interface.contact_area
+ ]
+
+
+def test_no_retained_interface_skips_tessellation(test_dir, monkeypatch):
+ from plinder.data.annotations import aggregate_annotations
+
+ def explode(_atoms):
+ raise AssertionError("no retained interface needs contact areas")
+
+ monkeypatch.setattr(aggregate_annotations, "chain_pair_contact_areas", explode)
+ entry = Entry.from_custom_cif_file(
+ pdb_id="custom_7cma",
+ cif_file=test_dir / CIF_7CMA,
+ structure_mode="as_is",
+ include_ligands=False,
+ include_interfaces=True,
+ interface_min_residues=1000,
+ interface_annotate_prodigy=False,
+ )
+
+ assert entry.interfaces == []
+ assert entry.failed_contact_area_biounit_ids == []
+ assert entry.biounit_protein_contact_counts
+
+
+@pytest.mark.usefixtures("mock_alternative_datasets")
+def test_no_neighboring_ligand_pocket_skips_tessellation(test_dir, monkeypatch):
+ from plinder.data.annotations import aggregate_annotations
+
+ def explode(_atoms):
+ raise AssertionError("no neighboring-residue pocket needs contact areas")
+
+ monkeypatch.setattr(aggregate_annotations, "chain_pair_contact_areas", explode)
+ entry = Entry.from_cif_file(
+ test_dir / CIF_1QZ5,
+ include_interfaces=False,
+ neighboring_residue_threshold=0.1,
+ )
+
+ assert entry.failed_contact_area_biounit_ids == []
+
+
+@pytest.mark.usefixtures("mock_alternative_datasets")
+def test_contact_area_size_guard_records_the_skipped_assembly(test_dir):
+ entry = Entry.from_cif_file(
+ test_dir / CIF_1QZ5, include_interfaces=False, tessellation_atom_limit=10
+ )
+
+ assert entry.failed_contact_area_biounit_ids == ["1"]
+ ligands = [ligand for system in entry.systems.values() for ligand in system.ligands]
+ assert ligands
+ for ligand in ligands:
+ assert ligand.contact_area is None
+ assert ligand.chain_contact_areas == {}
+ row = ligand.format(entry.chains)
+ assert row["ligand_contact_area"] is None
+ assert row["ligand_contact_area_chains"] == []
+ assert row["ligand_contact_area_values"] == []
+
+
+def test_failed_tessellation_records_the_assembly_and_leaves_areas_null(
+ test_dir, monkeypatch
+):
+ from plinder.data.annotations import aggregate_annotations
+
+ def explode(_atoms):
+ raise RuntimeError("voronota exploded")
+
+ monkeypatch.setattr(aggregate_annotations, "chain_pair_contact_areas", explode)
+ entry = Entry.from_custom_cif_file(
+ pdb_id="custom_7cma",
+ cif_file=test_dir / CIF_7CMA,
+ structure_mode="as_is",
+ include_ligands=False,
+ include_interfaces=True,
+ interface_annotate_prodigy=False,
+ )
+
+ assert entry.failed_contact_area_biounit_ids == ["1"]
+ [interface] = entry.interfaces
+ assert interface.contact_area is None
+ assert interface.to_row()["interface_contact_area"] is None
+
+
+def test_protein_only_ingest_never_tessellates(test_dir, monkeypatch):
+ from plinder.data.annotations import aggregate_annotations
+
+ def explode(_atoms):
+ raise AssertionError("tessellation must not run without consumers")
+
+ monkeypatch.setattr(aggregate_annotations, "chain_pair_contact_areas", explode)
+ entry = Entry.from_cif_file(
+ test_dir / CIF_1QZ5,
+ include_ligands=False,
+ include_interfaces=False,
+ protein_only=True,
+ )
+
+ assert entry.chains
+ assert entry.failed_contact_area_biounit_ids == []
diff --git a/tests/data/test_databases.py b/tests/data/test_databases.py
new file mode 100644
index 000000000..7d3ce9546
--- /dev/null
+++ b/tests/data/test_databases.py
@@ -0,0 +1,350 @@
+import json
+import os
+
+from plinder.data import databases
+
+
+def test_make_db_limits_external_tool_threads(tmp_path, monkeypatch):
+ commands: list[list[str]] = []
+ monkeypatch.setattr(databases, "run", commands.append)
+
+ databases.make_db(
+ input_dir=tmp_path / "input",
+ output_dir=tmp_path / "output",
+ db="foldseek",
+ threads=3,
+ )
+
+ assert len(commands) == 2
+ for command in commands:
+ index = command.index("--threads")
+ assert command[index + 1] == "3"
+ foldseek_createdb = commands[0]
+ assert foldseek_createdb[foldseek_createdb.index("--coord-store-mode") + 1] == "2"
+
+
+def _touch_database(database, *, foldseek=False):
+ database.parent.mkdir(exist_ok=True, parents=True)
+ database.with_suffix(".dbtype").touch()
+ database.with_suffix(".index").touch()
+ if foldseek:
+ database.parent.joinpath(f"{database.name}_ss.dbtype").touch()
+ database.parent.joinpath(f"{database.name}_ca.dbtype").touch()
+
+
+def test_exact_foldseek_target_uses_native_cluster_search_db(tmp_path, monkeypatch):
+ full = tmp_path / "subdbs" / "holo_foldseek" / "holo_foldseek"
+ _touch_database(full, foldseek=True)
+ commands: list[list[str]] = []
+
+ def fake_run(command, **_kwargs):
+ commands.append(command)
+ if command[1] == "linclust":
+ _touch_database(full.parent / "exact_clusters")
+ elif command[1] == "createclusearchdb":
+ _touch_database(full.parent / "clustered", foldseek=True)
+ elif command[1] == "createindex":
+ (full.parent / "clustered.idx.dbtype").touch()
+
+ monkeypatch.setattr(databases, "run", fake_run)
+
+ report = databases.make_exact_search_db(
+ full_db=full,
+ aln_type="foldseek",
+ tmp_dir=tmp_path / "scratch",
+ threads=4,
+ )
+
+ assert [command[1] for command in commands] == [
+ "linclust",
+ "createclusearchdb",
+ "createindex",
+ ]
+ linclust = commands[0]
+ assert linclust[linclust.index("--min-seq-id") + 1] == "1.0"
+ assert linclust[linclust.index("-c") + 1] == "1.0"
+ cluster_db = commands[1]
+ assert cluster_db[cluster_db.index("--compressed") + 1] == "0"
+ assert report["search_target"] == "clustered"
+ assert report["conversion_target"] == "clustered"
+ assert report["source_index"]["name"] == "holo_foldseek.index"
+ assert report["portable"] is True
+ assert report["compressed_search_target"] is False
+
+
+def test_exact_mmseqs_target_stores_expansion_alignments(tmp_path, monkeypatch):
+ full = tmp_path / "subdbs" / "holo_mmseqs" / "holo_mmseqs"
+ _touch_database(full)
+ commands: list[list[str]] = []
+
+ def fake_run(command, **_kwargs):
+ commands.append(command)
+ output_by_command = {
+ "linclust": "exact_clusters",
+ "createsubdb": "representatives",
+ "align": "cluster_alignments",
+ }
+ if command[1] in output_by_command:
+ _touch_database(full.parent / output_by_command[command[1]])
+ elif command[1] == "createindex":
+ (full.parent / "representatives.idx.dbtype").touch()
+
+ monkeypatch.setattr(databases, "run", fake_run)
+
+ report = databases.make_exact_search_db(
+ full_db=full,
+ aln_type="mmseqs",
+ tmp_dir=tmp_path / "scratch",
+ threads=2,
+ )
+
+ assert [command[1] for command in commands] == [
+ "linclust",
+ "createsubdb",
+ "align",
+ "createindex",
+ ]
+ cluster_align = commands[2]
+ assert "-a" in cluster_align
+ assert "--min-seq-id" not in cluster_align
+ assert "-c" not in cluster_align
+ assert cluster_align[cluster_align.index("--add-self-matches") + 1] == "1"
+ createsubdb = commands[1]
+ assert createsubdb[createsubdb.index("--subdb-mode") + 1] == "0"
+ assert report["cluster_alignments"] == "cluster_alignments"
+
+
+def test_portable_foldseek_subdb_copies_each_database(tmp_path, monkeypatch):
+ full = tmp_path / "full" / "foldseek"
+ full.parent.mkdir()
+ full.with_suffix(".lookup").write_text("0 1abc_A 0\n")
+ output = tmp_path / "selected"
+ output.mkdir()
+ commands: list[list[str]] = []
+ monkeypatch.setattr(databases, "run", commands.append)
+
+ missing = databases.make_sub_db(
+ {"1abc_A"},
+ full,
+ output,
+ "foldseek",
+ portable=True,
+ )
+
+ assert missing == []
+ assert len(commands) == 1
+ assert all(
+ command[command.index("--subdb-mode") + 1] == "0" for command in commands
+ )
+
+
+def test_make_sub_db_selects_only_first_model_per_chain(tmp_path, monkeypatch):
+ full = tmp_path / "full" / "foldseek"
+ full.parent.mkdir()
+ full.with_suffix(".lookup").write_text(
+ "0 pdb_00001abc_xyz-enrich_A 0\n"
+ "1 pdb_00001abc_xyz-enrich_A 1\n"
+ "2 pdb_00001abc_xyz-enrich_B 1\n"
+ )
+ output = tmp_path / "selected"
+ output.mkdir()
+ monkeypatch.setattr(databases, "run", lambda *_args, **_kwargs: None)
+
+ missing = databases.make_sub_db(
+ {
+ "pdb_00001abc_xyz-enrich_A",
+ "pdb_00001abc_xyz-enrich_B",
+ },
+ full,
+ output,
+ "foldseek",
+ portable=True,
+ )
+
+ assert missing == []
+ assert (output / "ids.tsv").read_text() == (
+ "0 pdb_00001abc_xyz-enrich_A 0\n2 pdb_00001abc_xyz-enrich_B 1\n"
+ )
+
+
+def test_database_link_normalization_makes_directory_self_contained(tmp_path):
+ root = tmp_path / "database"
+ root.mkdir()
+ internal_target = root / "member"
+ internal_target.write_text("member")
+ external_target = tmp_path / "parent-header"
+ external_target.write_text("header")
+ internal_link = root / "internal-link"
+ internal_link.symlink_to(internal_target)
+ external_link = root / "external-link"
+ external_link.symlink_to(external_target)
+
+ report = databases._make_database_directory_portable(root)
+
+ assert report == {"external_links_copied": 1, "internal_links_relativized": 1}
+ assert internal_link.is_symlink()
+ assert not internal_link.readlink().is_absolute()
+ assert external_link.is_file() and not external_link.is_symlink()
+ assert external_link.read_text() == "header"
+ assert not databases._has_external_database_links(root)
+
+
+def test_database_link_checks_skip_runtime_alignment_trees(tmp_path):
+ root = tmp_path / "database"
+ runtime = root / "aln"
+ runtime.mkdir(parents=True)
+ external_target = tmp_path / "completed-alignment.parquet"
+ external_target.write_text("alignment")
+ runtime_link = runtime / "1abc.parquet"
+ runtime_link.symlink_to(external_target)
+
+ report = databases._make_database_directory_portable(root)
+
+ assert report == {"external_links_copied": 0, "internal_links_relativized": 0}
+ assert runtime_link.is_symlink()
+ assert not databases._has_external_database_links(root)
+
+
+def test_database_identifiers_follow_selected_index_keys(tmp_path):
+ database = tmp_path / "selected"
+ database.with_suffix(".lookup").write_text(
+ "0\t1abc_A\t0\n1\t2def_B\t0\n2\t3ghi_C\t0\n"
+ )
+ database.with_suffix(".index").write_text("0\t0\t10\n2\t10\t20\n")
+
+ assert databases.database_identifiers(database) == {"1abc_A", "3ghi_C"}
+
+
+def test_install_database_directory_replaces_partial_shared_output(tmp_path):
+ source = tmp_path / "scratch" / "foldseek"
+ source.mkdir(parents=True)
+ (source / "foldseek.dbtype").write_text("complete")
+ source_payload = tmp_path / "scratch" / "payload"
+ source_payload.write_text("portable")
+ (source / "external-link").symlink_to(source_payload)
+ target = tmp_path / "shared" / "foldseek"
+ target.mkdir(parents=True)
+ (target / "partial").write_text("stale")
+
+ databases.install_database_directory(source, target)
+
+ assert (target / "foldseek.dbtype").read_text() == "complete"
+ assert (target / "external-link").read_text() == "portable"
+ assert not (target / "external-link").is_symlink()
+ assert not (target / "partial").exists()
+ assert not (target.parent / ".foldseek.installing").exists()
+ assert not (target.parent / ".foldseek.previous").exists()
+
+
+def test_install_database_directory_preserves_generated_results(tmp_path):
+ source = tmp_path / "scratch" / "foldseek"
+ source.mkdir(parents=True)
+ (source / "foldseek.dbtype").write_text("new database")
+ target = tmp_path / "shared" / "foldseek"
+ alignments = target / "aln"
+ alignments.mkdir(parents=True)
+ (alignments / "1abc.parquet").write_text("completed search")
+ (target / "foldseek.dbtype").write_text("old database")
+
+ databases.install_database_directory(
+ source,
+ target,
+ preserve_directories=("aln", "mapped_aln"),
+ )
+
+ assert (target / "foldseek.dbtype").read_text() == "new database"
+ assert (target / "aln" / "1abc.parquet").read_text() == "completed search"
+ assert not (target.parent / ".foldseek.previous").exists()
+
+
+def test_make_sub_dbs_builds_complete_backend_in_scratch(tmp_path, monkeypatch):
+ full_db = tmp_path / "full" / "foldseek"
+ full_db.parent.mkdir()
+ full_db.with_suffix(".lookup").write_text("0 pdb_00001abc_xyz-enrich_A 0\n")
+ db_dir = tmp_path / "shared" / "subdbs"
+ db_dir.mkdir(parents=True)
+ original_missing = tmp_path / "original-missing.json"
+ original_missing.write_text('{"old": true}\n')
+ os.link(original_missing, db_dir / "missing.json")
+ scratch = tmp_path / "scratch"
+ build_paths = []
+
+ def fake_make_sub_db(_ids, _full_db, subdb, _aln_type, *, portable):
+ build_paths.append(subdb)
+ assert portable is True
+ database = subdb / subdb.name
+ _touch_database(database, foldseek=True)
+ return []
+
+ def fake_make_exact_search_db(*, full_db, **_kwargs):
+ (full_db.parent / "exact_cluster.json").write_text("{}")
+ return {"status": "complete"}
+
+ monkeypatch.setattr(databases, "make_sub_db", fake_make_sub_db)
+ monkeypatch.setattr(databases, "make_exact_search_db", fake_make_exact_search_db)
+ monkeypatch.setattr(
+ databases, "_completed_exact_search_manifest", lambda *_args: None
+ )
+
+ databases.make_sub_dbs(
+ db_dir,
+ {"holo_foldseek": full_db},
+ identifiers_by_database={"holo_foldseek": {"pdb_00001abc_xyz-enrich_A"}},
+ tmp_dir=scratch,
+ threads=4,
+ )
+
+ assert build_paths == [scratch / "holo_foldseek/build/holo_foldseek"]
+ target = db_dir / "holo_foldseek"
+ assert (target / "holo_foldseek.dbtype").is_file()
+ assert (target / "selection.json").is_file()
+ selection = json.loads((target / "selection.json").read_text())
+ assert selection["target_database"]["file_count"] == 4
+ assert selection["target_database"]["size"] == 0
+ assert len(selection["target_database"]["sha256"]) == 64
+ assert (target / "exact_cluster.json").is_file()
+ assert original_missing.read_text() == '{"old": true}\n'
+ assert not os.path.samefile(original_missing, db_dir / "missing.json")
+
+
+def test_make_sub_dbs_retires_monomer_db_when_selection_becomes_empty(
+ tmp_path, monkeypatch
+):
+ full_db = tmp_path / "full" / "mmseqs"
+ full_db.parent.mkdir()
+ full_db.with_suffix(".lookup").write_text("0 1abc_A 0\n")
+ db_dir = tmp_path / "subdbs"
+ db_dir.mkdir()
+ clustered: list[str] = []
+
+ def fake_make_sub_db(ids, _full_db, subdb, _aln_type, *, portable):
+ database = subdb / subdb.name
+ _touch_database(database)
+ database.with_suffix(".index").write_text("".join(f"{i}\t0\t1\n" for i in ids))
+ return []
+
+ def fake_make_exact_search_db(*, full_db, **_kwargs):
+ clustered.append(full_db.name)
+ (full_db.parent / "exact_cluster.json").write_text("{}")
+ return {"status": "complete"}
+
+ monkeypatch.setattr(databases, "make_sub_db", fake_make_sub_db)
+ monkeypatch.setattr(databases, "make_exact_search_db", fake_make_exact_search_db)
+ monkeypatch.setattr(
+ databases, "_completed_exact_search_manifest", lambda *_args: None
+ )
+ target = db_dir / "monomer_mmseqs"
+ for identifiers in ({"1abc_A"}, set()):
+ databases.make_sub_dbs(
+ db_dir,
+ {"monomer_mmseqs": full_db},
+ identifiers_by_database={"monomer_mmseqs": identifiers},
+ tmp_dir=tmp_path / "scratch",
+ )
+ if identifiers:
+ assert (target / "exact_cluster.json").is_file()
+
+ assert clustered == ["monomer_mmseqs"]
+ assert not (target / "exact_cluster.json").exists()
+ assert not (target / "selection.json").exists()
+ assert not list(target.glob("monomer_mmseqs*"))
diff --git a/tests/data/test_docs.py b/tests/data/test_docs.py
index bba582f8f..e0c018bc0 100644
--- a/tests/data/test_docs.py
+++ b/tests/data/test_docs.py
@@ -1,14 +1,633 @@
# Copyright (c) 2024, Plinder Development Team
# Distributed under the terms of the Apache License 2.0
+import pytest
+
from plinder.data import docs
-def test_make_column_descriptions(read_plinder_mount):
- from plinder.core.scores import query_index
+def _import_tablegen(monkeypatch):
+ import importlib
+ import sys
+ from pathlib import Path
+ from types import ModuleType
+
+ itables = ModuleType("itables")
+ itables.to_html_datatable = lambda frame, **_: frame.to_html(
+ index=False, escape=False
+ )
+ monkeypatch.setitem(sys.modules, "itables", itables)
+ monkeypatch.delitem(sys.modules, "tablegen", raising=False)
+ repository = Path(__file__).resolve().parents[2]
+ monkeypatch.syspath_prepend(str(repository / "docs"))
+ return importlib.import_module("tablegen")
+
+
+def test_tablegen_renders_checked_in_table_descriptions(tmp_path, monkeypatch):
+ tablegen = _import_tablegen(monkeypatch)
+
+ description_dir = tmp_path / "column_descriptions"
+ table_dir = description_dir / "tables"
+ table_dir.mkdir(parents=True)
+ (table_dir / "alpha.tsv").write_text(
+ "Name\tType\tDescription\n"
+ "entry\tlist\tApply & keep metadata\n",
+ encoding="utf-8",
+ )
+ (table_dir / "beta.tsv").write_text(
+ "Name\tType\tDescription\nscore\tdouble\tSimilarity score\n",
+ encoding="utf-8",
+ )
+ output_path = tmp_path / "table.html"
+
+ tablegen.generate_table(description_dir, output_path)
+
+ html = output_path.read_text(encoding="utf-8")
+ assert '' in html
+ assert '' in html
+ assert "
alpha
" in html
+ assert "
beta
" in html
+ assert "" not in html
+ assert ">entry<id><" in html
+ assert ">list<element: string><" in html
+ assert "Apply <operation> & keep metadata" in html
+ assert ">score<" in html
+ assert "Similarity score" in html
+ assert html.count("